summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS18
-rw-r--r--Makefile3
-rw-r--r--Makefile.inc115
-rw-r--r--ObsoleteFiles.inc31
-rw-r--r--UPDATING23
-rw-r--r--bin/cp/utils.c4
-rw-r--r--bin/ed/Makefile1
-rw-r--r--bin/ed/main.c7
-rw-r--r--bin/ln/ln.c88
-rw-r--r--bin/ln/symlink.735
-rw-r--r--bin/ls/cmp.c64
-rw-r--r--bin/pax/Makefile3
-rw-r--r--bin/pax/cpio.1304
-rw-r--r--bin/pax/getoldopt.c17
-rw-r--r--bin/pax/tar.1310
-rw-r--r--bin/ps/extern.h1
-rw-r--r--bin/ps/keyword.c1
-rw-r--r--bin/ps/print.c16
-rw-r--r--bin/ps/ps.126
-rw-r--r--bin/pwait/pwait.12
-rw-r--r--bin/rcp/rcp.c8
-rw-r--r--bin/setfacl/file.c16
-rw-r--r--bin/setfacl/mask.c16
-rw-r--r--bin/setfacl/merge.c16
-rw-r--r--bin/setfacl/remove.c16
-rw-r--r--bin/setfacl/setfacl.116
-rw-r--r--bin/setfacl/setfacl.c16
-rw-r--r--bin/setfacl/setfacl.h16
-rw-r--r--bin/setfacl/util.c16
-rw-r--r--bin/sh/arith.y4
-rw-r--r--bin/sh/arith_lex.l26
-rw-r--r--bin/sh/cd.c27
-rw-r--r--bin/sh/cd.h2
-rw-r--r--bin/sh/eval.c158
-rw-r--r--bin/sh/exec.c24
-rw-r--r--bin/sh/exec.h4
-rw-r--r--bin/sh/expand.c10
-rw-r--r--bin/sh/main.c5
-rw-r--r--bin/sh/mksyntax.c1
-rw-r--r--bin/sh/options.c5
-rw-r--r--bin/sh/parser.c605
-rw-r--r--bin/sh/sh.133
-rw-r--r--bin/test/test.c6
-rw-r--r--cddl/Makefile.inc1
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs.8998
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c79
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h5
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c62
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool.8205
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h1
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c35
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h3
-rw-r--r--cddl/lib/drti/Makefile5
-rw-r--r--cddl/lib/libavl/Makefile1
-rw-r--r--cddl/lib/libctf/Makefile11
-rw-r--r--cddl/lib/libdtrace/Makefile10
-rw-r--r--cddl/lib/libnvpair/Makefile1
-rw-r--r--cddl/lib/libumem/Makefile1
-rw-r--r--cddl/lib/libuutil/Makefile1
-rw-r--r--cddl/lib/libzfs/Makefile1
-rw-r--r--cddl/lib/libzpool/Makefile1
-rw-r--r--cddl/sbin/zfs/Makefile1
-rw-r--r--cddl/sbin/zpool/Makefile1
-rw-r--r--cddl/usr.bin/ctfconvert/Makefile15
-rw-r--r--cddl/usr.bin/ctfdump/Makefile12
-rw-r--r--cddl/usr.bin/ctfmerge/Makefile16
-rw-r--r--cddl/usr.bin/sgsmsg/Makefile11
-rw-r--r--cddl/usr.bin/zinject/Makefile1
-rw-r--r--cddl/usr.bin/ztest/Makefile1
-rw-r--r--cddl/usr.sbin/dtrace/Makefile10
-rw-r--r--cddl/usr.sbin/lockstat/Makefile13
-rw-r--r--cddl/usr.sbin/zdb/Makefile4
-rw-r--r--contrib/bind9/CHANGES421
-rw-r--r--contrib/bind9/COPYRIGHT4
-rw-r--r--contrib/bind9/FAQ18
-rw-r--r--contrib/bind9/FAQ.xml35
-rw-r--r--contrib/bind9/NSEC3-NOTES4
-rw-r--r--contrib/bind9/README23
-rw-r--r--contrib/bind9/bin/check/named-checkconf.84
-rw-r--r--contrib/bind9/bin/check/named-checkconf.html4
-rw-r--r--contrib/bind9/bin/check/named-checkzone.88
-rw-r--r--contrib/bind9/bin/check/named-checkzone.c8
-rw-r--r--contrib/bind9/bin/check/named-checkzone.docbook4
-rw-r--r--contrib/bind9/bin/check/named-checkzone.html18
-rw-r--r--contrib/bind9/bin/dig/dig.14
-rw-r--r--contrib/bind9/bin/dig/dig.html4
-rw-r--r--contrib/bind9/bin/dig/dighost.c24
-rw-r--r--contrib/bind9/bin/dig/host.14
-rw-r--r--contrib/bind9/bin/dig/host.c5
-rw-r--r--contrib/bind9/bin/dig/host.html4
-rw-r--r--contrib/bind9/bin/dig/nslookup.14
-rw-r--r--contrib/bind9/bin/dig/nslookup.c3
-rw-r--r--contrib/bind9/bin/dig/nslookup.html4
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.c18
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.820
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c7
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook21
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html32
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.820
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.c22
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.docbook31
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.html43
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.825
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.c915
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.docbook33
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.html45
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.c4
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.h6
-rw-r--r--contrib/bind9/bin/named/control.c12
-rw-r--r--contrib/bind9/bin/named/include/named/server.h5
-rw-r--r--contrib/bind9/bin/named/lwresd.84
-rw-r--r--contrib/bind9/bin/named/lwresd.html4
-rw-r--r--contrib/bind9/bin/named/named.822
-rw-r--r--contrib/bind9/bin/named/named.conf.54
-rw-r--r--contrib/bind9/bin/named/named.conf.html4
-rw-r--r--contrib/bind9/bin/named/named.docbook17
-rw-r--r--contrib/bind9/bin/named/named.html28
-rw-r--r--contrib/bind9/bin/named/query.c53
-rw-r--r--contrib/bind9/bin/named/server.c54
-rw-r--r--contrib/bind9/bin/named/statschannel.c400
-rw-r--r--contrib/bind9/bin/named/update.c25
-rw-r--r--contrib/bind9/bin/nsupdate/nsupdate.14
-rw-r--r--contrib/bind9/bin/nsupdate/nsupdate.html4
-rw-r--r--contrib/bind9/bin/rndc/rndc-confgen.84
-rw-r--r--contrib/bind9/bin/rndc/rndc-confgen.html4
-rw-r--r--contrib/bind9/bin/rndc/rndc.84
-rw-r--r--contrib/bind9/bin/rndc/rndc.conf.54
-rw-r--r--contrib/bind9/bin/rndc/rndc.conf.html4
-rw-r--r--contrib/bind9/bin/rndc/rndc.html4
-rw-r--r--contrib/bind9/config.h.in28
-rw-r--r--contrib/bind9/configure.in134
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM-book.xml144
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch01.html54
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch02.html26
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch03.html30
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch04.html152
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch05.html10
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch06.html224
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch07.html18
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch08.html22
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch09.html184
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.ch10.html6
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.html152
-rw-r--r--contrib/bind9/doc/arm/Bv9ARM.pdf12986
-rw-r--r--contrib/bind9/doc/arm/man.dig.html24
-rw-r--r--contrib/bind9/doc/arm/man.dnssec-dsfromkey.html20
-rw-r--r--contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html32
-rw-r--r--contrib/bind9/doc/arm/man.dnssec-keygen.html43
-rw-r--r--contrib/bind9/doc/arm/man.dnssec-signzone.html47
-rw-r--r--contrib/bind9/doc/arm/man.host.html14
-rw-r--r--contrib/bind9/doc/arm/man.named-checkconf.html16
-rw-r--r--contrib/bind9/doc/arm/man.named-checkzone.html20
-rw-r--r--contrib/bind9/doc/arm/man.named.html28
-rw-r--r--contrib/bind9/doc/arm/man.nsupdate.html18
-rw-r--r--contrib/bind9/doc/arm/man.rndc-confgen.html16
-rw-r--r--contrib/bind9/doc/arm/man.rndc.conf.html16
-rw-r--r--contrib/bind9/doc/arm/man.rndc.html16
-rw-r--r--contrib/bind9/doc/misc/Makefile.in16
-rw-r--r--contrib/bind9/lib/dns/api4
-rw-r--r--contrib/bind9/lib/dns/db.c6
-rw-r--r--contrib/bind9/lib/dns/dispatch.c28
-rw-r--r--contrib/bind9/lib/dns/dnssec.c69
-rw-r--r--contrib/bind9/lib/dns/dst_api.c53
-rw-r--r--contrib/bind9/lib/dns/dst_internal.h12
-rw-r--r--contrib/bind9/lib/dns/dst_parse.c18
-rw-r--r--contrib/bind9/lib/dns/include/dns/db.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/dnssec.h8
-rw-r--r--contrib/bind9/lib/dns/include/dns/journal.h11
-rw-r--r--contrib/bind9/lib/dns/include/dns/keyvalues.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/name.h8
-rw-r--r--contrib/bind9/lib/dns/include/dns/ncache.h4
-rw-r--r--contrib/bind9/lib/dns/include/dns/nsec3.h4
-rw-r--r--contrib/bind9/lib/dns/include/dns/rbt.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdataset.h20
-rw-r--r--contrib/bind9/lib/dns/include/dns/resolver.h46
-rw-r--r--contrib/bind9/lib/dns/include/dns/result.h8
-rw-r--r--contrib/bind9/lib/dns/include/dns/types.h2
-rw-r--r--contrib/bind9/lib/dns/include/dns/validator.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/zone.h20
-rw-r--r--contrib/bind9/lib/dns/include/dst/dst.h6
-rw-r--r--contrib/bind9/lib/dns/journal.c99
-rw-r--r--contrib/bind9/lib/dns/masterdump.c2
-rw-r--r--contrib/bind9/lib/dns/message.c4
-rw-r--r--contrib/bind9/lib/dns/ncache.c6
-rw-r--r--contrib/bind9/lib/dns/nsec3.c25
-rw-r--r--contrib/bind9/lib/dns/opensslrsa_link.c504
-rw-r--r--contrib/bind9/lib/dns/rbt.c35
-rw-r--r--contrib/bind9/lib/dns/rbtdb.c163
-rw-r--r--contrib/bind9/lib/dns/rcode.c6
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c3
-rw-r--r--contrib/bind9/lib/dns/rdatalist.c6
-rw-r--r--contrib/bind9/lib/dns/rdataset.c25
-rw-r--r--contrib/bind9/lib/dns/rdataslab.c6
-rw-r--r--contrib/bind9/lib/dns/resolver.c461
-rw-r--r--contrib/bind9/lib/dns/result.c7
-rw-r--r--contrib/bind9/lib/dns/sdb.c10
-rw-r--r--contrib/bind9/lib/dns/sdlz.c10
-rw-r--r--contrib/bind9/lib/dns/spnego.c18
-rw-r--r--contrib/bind9/lib/dns/validator.c160
-rw-r--r--contrib/bind9/lib/dns/view.c14
-rw-r--r--contrib/bind9/lib/dns/zone.c211
-rw-r--r--contrib/bind9/lib/isc/api4
-rw-r--r--contrib/bind9/lib/isc/base32.c4
-rw-r--r--contrib/bind9/lib/isc/base64.c8
-rw-r--r--contrib/bind9/lib/isc/heap.c14
-rw-r--r--contrib/bind9/lib/isc/httpd.c45
-rw-r--r--contrib/bind9/lib/isc/ia64/include/isc/atomic.h2
-rw-r--r--contrib/bind9/lib/isc/include/isc/entropy.h14
-rw-r--r--contrib/bind9/lib/isc/include/isc/netscope.h6
-rw-r--r--contrib/bind9/lib/isc/include/isc/portset.h4
-rw-r--r--contrib/bind9/lib/isc/include/isc/sha2.h10
-rw-r--r--contrib/bind9/lib/isc/include/isc/util.h14
-rw-r--r--contrib/bind9/lib/isc/inet_ntop.c11
-rw-r--r--contrib/bind9/lib/isc/powerpc/include/isc/atomic.h53
-rw-r--r--contrib/bind9/lib/isc/random.c27
-rw-r--r--contrib/bind9/lib/isc/sha2.c27
-rw-r--r--contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c6
-rw-r--r--contrib/bind9/lib/isc/unix/socket.c31
-rw-r--r--contrib/bind9/lib/isccc/api2
-rw-r--r--contrib/bind9/lib/isccfg/aclconf.c23
-rw-r--r--contrib/bind9/lib/isccfg/api2
-rw-r--r--contrib/bind9/lib/isccfg/include/isccfg/namedconf.h6
-rw-r--r--contrib/bind9/lib/lwres/api2
-rw-r--r--contrib/bind9/lib/lwres/context.c15
-rw-r--r--contrib/bind9/lib/lwres/getipnode.c100
-rw-r--r--contrib/bind9/lib/lwres/man/lwres.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_buffer.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_buffer.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_config.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_config.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_context.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_context.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gabn.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gabn.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gai_strerror.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gai_strerror.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getaddrinfo.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gethostent.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gethostent.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getipnode.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getipnode.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getnameinfo.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getnameinfo.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gnba.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_gnba.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_hstrerror.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_hstrerror.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_inetntop.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_inetntop.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_noop.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_noop.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_packet.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_packet.html4
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_resutil.34
-rw-r--r--contrib/bind9/lib/lwres/man/lwres_resutil.html4
-rw-r--r--contrib/bind9/version6
-rwxr-xr-xcontrib/binutils/bfd/config.bfd4
-rw-r--r--contrib/bsnmp/gensnmpdef/gensnmpdef.c2
-rw-r--r--contrib/bsnmp/gensnmptree/gensnmptree.12
-rw-r--r--contrib/bsnmp/snmpd/config.c2
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.33
-rw-r--r--contrib/com_err/compile_et.12
-rw-r--r--contrib/cpio/ABOUT-NLS1101
-rw-r--r--contrib/cpio/AUTHORS6
-rw-r--r--contrib/cpio/COPYING340
-rw-r--r--contrib/cpio/ChangeLog1781
-rw-r--r--contrib/cpio/FREEBSD-upgrade29
-rw-r--r--contrib/cpio/INSTALL234
-rw-r--r--contrib/cpio/NEWS155
-rw-r--r--contrib/cpio/README71
-rw-r--r--contrib/cpio/THANKS20
-rw-r--r--contrib/cpio/TODO159
-rw-r--r--contrib/cpio/doc/cpio.141
-rw-r--r--contrib/cpio/doc/cpio.texi602
-rw-r--r--contrib/cpio/doc/version.texi4
-rw-r--r--contrib/cpio/lib/alloca_.h54
-rw-r--r--contrib/cpio/lib/argp-ba.c25
-rw-r--r--contrib/cpio/lib/argp-eexst.c31
-rw-r--r--contrib/cpio/lib/argp-fmtstream.c435
-rw-r--r--contrib/cpio/lib/argp-fmtstream.h301
-rw-r--r--contrib/cpio/lib/argp-fs-xinl.c43
-rw-r--r--contrib/cpio/lib/argp-help.c1954
-rw-r--r--contrib/cpio/lib/argp-namefrob.h158
-rw-r--r--contrib/cpio/lib/argp-parse.c953
-rw-r--r--contrib/cpio/lib/argp-pin.c28
-rw-r--r--contrib/cpio/lib/argp-pv.c24
-rw-r--r--contrib/cpio/lib/argp-pvh.c31
-rw-r--r--contrib/cpio/lib/argp-xinl.c43
-rw-r--r--contrib/cpio/lib/argp.h624
-rw-r--r--contrib/cpio/lib/basename.c129
-rw-r--r--contrib/cpio/lib/dirname.c85
-rw-r--r--contrib/cpio/lib/dirname.h70
-rw-r--r--contrib/cpio/lib/error.c338
-rw-r--r--contrib/cpio/lib/error.h66
-rw-r--r--contrib/cpio/lib/exitfail.c26
-rw-r--r--contrib/cpio/lib/exitfail.h20
-rw-r--r--contrib/cpio/lib/fatal.c27
-rw-r--r--contrib/cpio/lib/full-write.c81
-rw-r--r--contrib/cpio/lib/full-write.h35
-rw-r--r--contrib/cpio/lib/getopt.c1191
-rw-r--r--contrib/cpio/lib/getopt1.c171
-rw-r--r--contrib/cpio/lib/getopt_.h226
-rw-r--r--contrib/cpio/lib/getopt_int.h131
-rw-r--r--contrib/cpio/lib/gettext.h270
-rw-r--r--contrib/cpio/lib/hash.c1048
-rw-r--r--contrib/cpio/lib/hash.h88
-rw-r--r--contrib/cpio/lib/intprops.h78
-rw-r--r--contrib/cpio/lib/inttostr.c51
-rw-r--r--contrib/cpio/lib/inttostr.h30
-rw-r--r--contrib/cpio/lib/mempcpy.c29
-rw-r--r--contrib/cpio/lib/paxerror.c365
-rw-r--r--contrib/cpio/lib/paxexit.c28
-rw-r--r--contrib/cpio/lib/paxlib.h115
-rw-r--r--contrib/cpio/lib/paxnames.c156
-rw-r--r--contrib/cpio/lib/quote.c41
-rw-r--r--contrib/cpio/lib/quote.h22
-rw-r--r--contrib/cpio/lib/quotearg.c697
-rw-r--r--contrib/cpio/lib/quotearg.h140
-rw-r--r--contrib/cpio/lib/rmt-command.h4
-rw-r--r--contrib/cpio/lib/rmt.h99
-rw-r--r--contrib/cpio/lib/rtapelib.c740
-rw-r--r--contrib/cpio/lib/safe-read.c78
-rw-r--r--contrib/cpio/lib/safe-read.h35
-rw-r--r--contrib/cpio/lib/safe-write.c19
-rw-r--r--contrib/cpio/lib/safe-write.h25
-rw-r--r--contrib/cpio/lib/savedir.c137
-rw-r--r--contrib/cpio/lib/savedir.h27
-rw-r--r--contrib/cpio/lib/strchrnul.c32
-rw-r--r--contrib/cpio/lib/stripslash.c45
-rw-r--r--contrib/cpio/lib/strndup.c37
-rw-r--r--contrib/cpio/lib/strnlen.c31
-rw-r--r--contrib/cpio/lib/system-ioctl.h55
-rw-r--r--contrib/cpio/lib/system.h475
-rw-r--r--contrib/cpio/lib/umaxtostr.c3
-rw-r--r--contrib/cpio/lib/unlocked-io.h137
-rw-r--r--contrib/cpio/lib/utimens.c189
-rw-r--r--contrib/cpio/lib/utimens.h3
-rw-r--r--contrib/cpio/lib/xalloc-die.c42
-rw-r--r--contrib/cpio/lib/xalloc.h271
-rw-r--r--contrib/cpio/lib/xmalloc.c123
-rw-r--r--contrib/cpio/lib/xstrndup.c37
-rw-r--r--contrib/cpio/lib/xstrndup.h24
-rw-r--r--contrib/cpio/src/copyin.c1644
-rw-r--r--contrib/cpio/src/copyout.c1010
-rw-r--r--contrib/cpio/src/copypass.c443
-rw-r--r--contrib/cpio/src/cpio.h72
-rw-r--r--contrib/cpio/src/cpiohdr.h106
-rw-r--r--contrib/cpio/src/defer.c43
-rw-r--r--contrib/cpio/src/defer.h26
-rw-r--r--contrib/cpio/src/dstring.c103
-rw-r--r--contrib/cpio/src/dstring.h50
-rw-r--r--contrib/cpio/src/extern.h221
-rw-r--r--contrib/cpio/src/filemode.c243
-rw-r--r--contrib/cpio/src/filetypes.h85
-rw-r--r--contrib/cpio/src/global.c201
-rw-r--r--contrib/cpio/src/idcache.c207
-rw-r--r--contrib/cpio/src/main.c804
-rw-r--r--contrib/cpio/src/makepath.c267
-rw-r--r--contrib/cpio/src/safe-stat.h1
-rw-r--r--contrib/cpio/src/tar.c494
-rw-r--r--contrib/cpio/src/tar.h112
-rw-r--r--contrib/cpio/src/tarhdr.h63
-rw-r--r--contrib/cpio/src/userspec.c261
-rw-r--r--contrib/cpio/src/util.c1344
-rw-r--r--contrib/gcc/config/mips/freebsd.h66
-rw-r--r--contrib/ipfilter/ipsend/sbpf.c1
-rw-r--r--contrib/netcat/FREEBSD-upgrade27
-rw-r--r--contrib/netcat/FREEBSD-vendor2
-rw-r--r--contrib/netcat/nc.127
-rw-r--r--contrib/netcat/netcat.c56
-rw-r--r--contrib/openpam/include/security/pam_appl.h3
-rw-r--r--contrib/top/utils.c4
-rw-r--r--contrib/top/utils.h2
-rw-r--r--contrib/tzdata/africa40
-rw-r--r--contrib/tzdata/antarctica65
-rw-r--r--contrib/tzdata/asia119
-rw-r--r--contrib/tzdata/australasia93
-rw-r--r--contrib/tzdata/europe12
-rw-r--r--contrib/tzdata/southamerica45
-rw-r--r--contrib/tzdata/zone.tab9
-rw-r--r--crypto/openssh/ChangeLog979
-rw-r--r--crypto/openssh/INSTALL6
-rw-r--r--crypto/openssh/PROTOCOL37
-rw-r--r--crypto/openssh/PROTOCOL.agent24
-rw-r--r--crypto/openssh/PROTOCOL.certkeys193
-rw-r--r--crypto/openssh/PROTOCOL.mux196
-rw-r--r--crypto/openssh/README4
-rw-r--r--crypto/openssh/README.smartcard93
-rw-r--r--crypto/openssh/addrmatch.c78
-rw-r--r--crypto/openssh/auth-krb5.c13
-rw-r--r--crypto/openssh/auth-options.c169
-rw-r--r--crypto/openssh/auth-options.h4
-rw-r--r--crypto/openssh/auth-rh-rsa.c5
-rw-r--r--crypto/openssh/auth-rhosts.c10
-rw-r--r--crypto/openssh/auth-rsa.c5
-rw-r--r--crypto/openssh/auth.c98
-rw-r--r--crypto/openssh/auth.h6
-rw-r--r--crypto/openssh/auth2-hostbased.c5
-rw-r--r--crypto/openssh/auth2-pubkey.c88
-rw-r--r--crypto/openssh/authfd.c30
-rw-r--r--crypto/openssh/authfd.h3
-rw-r--r--crypto/openssh/authfile.c83
-rw-r--r--crypto/openssh/authfile.h3
-rw-r--r--crypto/openssh/bufaux.c28
-rw-r--r--crypto/openssh/buffer.c8
-rw-r--r--crypto/openssh/buffer.h9
-rw-r--r--crypto/openssh/canohost.c20
-rw-r--r--crypto/openssh/channels.c279
-rw-r--r--crypto/openssh/channels.h23
-rw-r--r--crypto/openssh/clientloop.c75
-rw-r--r--crypto/openssh/clientloop.h12
-rwxr-xr-xcrypto/openssh/config.guess238
-rw-r--r--crypto/openssh/config.h37
-rw-r--r--crypto/openssh/config.h.in50
-rw-r--r--crypto/openssh/defines.h10
-rw-r--r--crypto/openssh/dh.c4
-rw-r--r--crypto/openssh/dns.c8
-rw-r--r--crypto/openssh/dns.h6
-rw-r--r--crypto/openssh/hostfile.c101
-rw-r--r--crypto/openssh/hostfile.h7
-rw-r--r--crypto/openssh/kex.c13
-rw-r--r--crypto/openssh/kex.h7
-rw-r--r--crypto/openssh/kexdhs.c19
-rw-r--r--crypto/openssh/kexgexs.c20
-rw-r--r--crypto/openssh/key.c613
-rw-r--r--crypto/openssh/key.h32
-rw-r--r--crypto/openssh/loginrec.c4
-rw-r--r--crypto/openssh/match.h4
-rw-r--r--crypto/openssh/misc.c29
-rw-r--r--crypto/openssh/misc.h3
-rw-r--r--crypto/openssh/monitor.c20
-rw-r--r--crypto/openssh/monitor_fdpass.c23
-rw-r--r--crypto/openssh/monitor_wrap.c19
-rw-r--r--crypto/openssh/mux.c1851
-rw-r--r--crypto/openssh/myproposal.h6
-rw-r--r--crypto/openssh/nchan.c21
-rw-r--r--crypto/openssh/openbsd-compat/bsd-cygwin_util.c9
-rw-r--r--crypto/openssh/openbsd-compat/openbsd-compat.h10
-rw-r--r--crypto/openssh/openbsd-compat/openssl-compat.c3
-rw-r--r--crypto/openssh/openbsd-compat/port-aix.c25
-rw-r--r--crypto/openssh/openbsd-compat/port-aix.h6
-rw-r--r--crypto/openssh/openbsd-compat/port-linux.c98
-rw-r--r--crypto/openssh/openbsd-compat/port-linux.h8
-rw-r--r--crypto/openssh/openbsd-compat/pwcache.c114
-rw-r--r--crypto/openssh/openbsd-compat/readpassphrase.c78
-rw-r--r--crypto/openssh/pathnames.h7
-rw-r--r--crypto/openssh/pkcs11.h1357
-rw-r--r--crypto/openssh/platform.c24
-rw-r--r--crypto/openssh/platform.h7
-rw-r--r--crypto/openssh/readconf.c18
-rw-r--r--crypto/openssh/readconf.h4
-rw-r--r--crypto/openssh/roaming.h8
-rw-r--r--crypto/openssh/roaming_client.c280
-rw-r--r--crypto/openssh/roaming_common.c57
-rw-r--r--crypto/openssh/roaming_serv.c31
-rw-r--r--crypto/openssh/scard-opensc.c532
-rw-r--r--crypto/openssh/scard.c571
-rw-r--r--crypto/openssh/scp.16
-rw-r--r--crypto/openssh/scp.c21
-rw-r--r--crypto/openssh/servconf.c56
-rw-r--r--crypto/openssh/servconf.h8
-rw-r--r--crypto/openssh/session.c106
-rw-r--r--crypto/openssh/sftp-client.c301
-rw-r--r--crypto/openssh/sftp-client.h21
-rw-r--r--crypto/openssh/sftp-common.c31
-rw-r--r--crypto/openssh/sftp-common.h4
-rw-r--r--crypto/openssh/sftp-server.825
-rw-r--r--crypto/openssh/sftp-server.c119
-rw-r--r--crypto/openssh/sftp.193
-rw-r--r--crypto/openssh/sftp.c858
-rw-r--r--crypto/openssh/ssh-add.132
-rw-r--r--crypto/openssh/ssh-add.c54
-rw-r--r--crypto/openssh/ssh-agent.122
-rw-r--r--crypto/openssh/ssh-agent.c158
-rw-r--r--crypto/openssh/ssh-dss.c10
-rw-r--r--crypto/openssh/ssh-keygen.1210
-rw-r--r--crypto/openssh/ssh-keygen.c636
-rw-r--r--crypto/openssh/ssh-keyscan.14
-rw-r--r--crypto/openssh/ssh-keyscan.c2
-rw-r--r--crypto/openssh/ssh-keysign.c4
-rw-r--r--crypto/openssh/ssh-pkcs11-client.c238
-rw-r--r--crypto/openssh/ssh-pkcs11-helper.025
-rw-r--r--crypto/openssh/ssh-pkcs11-helper.843
-rw-r--r--crypto/openssh/ssh-pkcs11-helper.c372
-rw-r--r--crypto/openssh/ssh-pkcs11.c564
-rw-r--r--crypto/openssh/ssh-pkcs11.h20
-rw-r--r--crypto/openssh/ssh-rand-helper.c9
-rw-r--r--crypto/openssh/ssh-rsa.c10
-rw-r--r--crypto/openssh/ssh.169
-rw-r--r--crypto/openssh/ssh.c174
-rw-r--r--crypto/openssh/ssh2.h12
-rw-r--r--crypto/openssh/ssh_config5
-rw-r--r--crypto/openssh/ssh_config.542
-rw-r--r--crypto/openssh/ssh_namespace.h28
-rw-r--r--crypto/openssh/sshconnect.c106
-rw-r--r--crypto/openssh/sshconnect2.c65
-rw-r--r--crypto/openssh/sshd.877
-rw-r--r--crypto/openssh/sshd.c145
-rw-r--r--crypto/openssh/sshd_config10
-rw-r--r--crypto/openssh/sshd_config.547
-rw-r--r--crypto/openssh/sshpty.h6
-rw-r--r--crypto/openssh/sshtty.c23
-rw-r--r--crypto/openssh/version.h6
-rw-r--r--crypto/openssl/CHANGES202
-rwxr-xr-xcrypto/openssl/Configure84
-rw-r--r--crypto/openssl/FAQ2
-rw-r--r--crypto/openssl/Makefile84
-rw-r--r--crypto/openssl/Makefile.org82
-rw-r--r--crypto/openssl/NEWS21
-rw-r--r--crypto/openssl/README27
-rw-r--r--crypto/openssl/apps/CA.sh121
-rw-r--r--crypto/openssl/apps/Makefile71
-rw-r--r--crypto/openssl/apps/apps.c2
-rw-r--r--crypto/openssl/apps/ca.c69
-rw-r--r--crypto/openssl/apps/dsa.c2
-rw-r--r--crypto/openssl/apps/dsaparam.c6
-rw-r--r--crypto/openssl/apps/enc.c7
-rw-r--r--crypto/openssl/apps/gendsa.c6
-rw-r--r--crypto/openssl/apps/genpkey.c440
-rw-r--r--crypto/openssl/apps/genrsa.c8
-rw-r--r--crypto/openssl/apps/openssl.c10
-rw-r--r--crypto/openssl/apps/pkcs12.c6
-rw-r--r--crypto/openssl/apps/pkey.c284
-rw-r--r--crypto/openssl/apps/pkeyparam.c201
-rw-r--r--crypto/openssl/apps/pkeyutl.c570
-rw-r--r--crypto/openssl/apps/req.c12
-rw-r--r--crypto/openssl/apps/s_apps.h3
-rw-r--r--crypto/openssl/apps/s_cb.c105
-rw-r--r--crypto/openssl/apps/s_client.c43
-rw-r--r--crypto/openssl/apps/s_server.c56
-rw-r--r--crypto/openssl/apps/s_socket.c6
-rw-r--r--crypto/openssl/apps/speed.c32
-rw-r--r--crypto/openssl/apps/ts.c1144
-rw-r--r--crypto/openssl/apps/tsget195
-rw-r--r--crypto/openssl/apps/x509.c1
-rwxr-xr-xcrypto/openssl/config14
-rw-r--r--crypto/openssl/crypto/aes/aes_cfb.c1
-rw-r--r--crypto/openssl/crypto/aes/aes_x86core.c1063
-rwxr-xr-xcrypto/openssl/crypto/aes/asm/aes-armv4.pl1030
-rwxr-xr-xcrypto/openssl/crypto/aes/asm/aes-ppc.pl1176
-rwxr-xr-xcrypto/openssl/crypto/aes/asm/aes-s390x.pl1333
-rwxr-xr-xcrypto/openssl/crypto/aes/asm/aes-sparcv9.pl1181
-rwxr-xr-xcrypto/openssl/crypto/aes/asm/aes-x86_64.pl2
-rw-r--r--crypto/openssl/crypto/asn1/a_mbstr.c2
-rw-r--r--crypto/openssl/crypto/asn1/a_object.c11
-rw-r--r--crypto/openssl/crypto/asn1/ameth_lib.c446
-rw-r--r--crypto/openssl/crypto/asn1/asn1.h7
-rw-r--r--crypto/openssl/crypto/asn1/asn1_err.c1
-rw-r--r--crypto/openssl/crypto/asn1/asn1_gen.c9
-rw-r--r--crypto/openssl/crypto/asn1/asn1_locl.h134
-rw-r--r--crypto/openssl/crypto/asn1/asn1_par.c2
-rw-r--r--crypto/openssl/crypto/asn1/bio_asn1.c495
-rw-r--r--crypto/openssl/crypto/asn1/bio_ndef.c246
-rw-r--r--crypto/openssl/crypto/asn1/t_x509.c17
-rw-r--r--crypto/openssl/crypto/asn1/x_nx509.c72
-rw-r--r--crypto/openssl/crypto/bio/bio.h9
-rw-r--r--crypto/openssl/crypto/bio/bss_dgram.c243
-rw-r--r--crypto/openssl/crypto/bio/bss_file.c15
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/alpha-mont.pl317
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/armv4-mont.pl200
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/mips3-mont.pl327
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/ppc-mont.pl323
-rw-r--r--crypto/openssl/crypto/bn/asm/ppc.pl2
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/ppc64-mont.pl918
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/s390x-mont.pl225
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/s390x.S678
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/sparcv9-mont.pl606
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/sparcv9a-mont.pl882
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/via-mont.pl242
-rwxr-xr-xcrypto/openssl/crypto/bn/asm/x86-mont.pl591
-rw-r--r--crypto/openssl/crypto/bn/asm/x86_64-gcc.c19
-rw-r--r--crypto/openssl/crypto/bn/bn_div.c15
-rw-r--r--crypto/openssl/crypto/bn/bn_exp.c3
-rw-r--r--crypto/openssl/crypto/bn/bn_gf2m.c3
-rw-r--r--crypto/openssl/crypto/bn/bn_mul.c10
-rw-r--r--crypto/openssl/crypto/bn/bntest.c2
-rw-r--r--crypto/openssl/crypto/camellia/Makefile7
-rwxr-xr-xcrypto/openssl/crypto/camellia/asm/cmll-x86.pl1138
-rwxr-xr-xcrypto/openssl/crypto/camellia/asm/cmll-x86_64.pl1080
-rw-r--r--crypto/openssl/crypto/cast/c_cfb64.c3
-rw-r--r--crypto/openssl/crypto/cast/c_ecb.c3
-rw-r--r--crypto/openssl/crypto/cast/c_enc.c13
-rw-r--r--crypto/openssl/crypto/cast/c_ofb64.c3
-rw-r--r--crypto/openssl/crypto/cast/cast.h12
-rw-r--r--crypto/openssl/crypto/cms/cms_ess.c4
-rw-r--r--crypto/openssl/crypto/cms/cms_lib.c6
-rw-r--r--crypto/openssl/crypto/comp/c_zlib.c17
-rw-r--r--crypto/openssl/crypto/cryptlib.c2
-rw-r--r--crypto/openssl/crypto/dsa/Makefile5
-rw-r--r--crypto/openssl/crypto/dsa/dsa_asn1.c2
-rw-r--r--crypto/openssl/crypto/dsa/dsa_lib.c2
-rw-r--r--crypto/openssl/crypto/dso/dso_dlfcn.c28
-rw-r--r--crypto/openssl/crypto/ec/ec2_smpl.c10
-rw-r--r--crypto/openssl/crypto/ecdsa/Makefile9
-rw-r--r--crypto/openssl/crypto/ecdsa/ecs_ossl.c54
-rw-r--r--crypto/openssl/crypto/ecdsa/ecs_sign.c2
-rw-r--r--crypto/openssl/crypto/engine/Makefile16
-rw-r--r--crypto/openssl/crypto/engine/eng_all.c2
-rw-r--r--crypto/openssl/crypto/engine/eng_cnf.c17
-rw-r--r--crypto/openssl/crypto/engine/eng_cryptodev.c56
-rw-r--r--crypto/openssl/crypto/engine/eng_ctrl.c8
-rw-r--r--crypto/openssl/crypto/engine/eng_err.c3
-rw-r--r--crypto/openssl/crypto/engine/eng_table.c3
-rw-r--r--crypto/openssl/crypto/engine/engine.h3
-rw-r--r--crypto/openssl/crypto/err/Makefile35
-rw-r--r--crypto/openssl/crypto/err/err_all.c2
-rw-r--r--crypto/openssl/crypto/evp/c_allc.c2
-rw-r--r--crypto/openssl/crypto/evp/c_alld.c3
-rw-r--r--crypto/openssl/crypto/evp/digest.c24
-rw-r--r--crypto/openssl/crypto/evp/evp_lib.c6
-rw-r--r--crypto/openssl/crypto/evp/evp_locl.h6
-rw-r--r--crypto/openssl/crypto/evp/names.c2
-rw-r--r--crypto/openssl/crypto/lhash/lhash.c58
-rw-r--r--crypto/openssl/crypto/md32_common.h8
-rwxr-xr-xcrypto/openssl/crypto/md5/asm/md5-x86_64.pl4
-rw-r--r--crypto/openssl/crypto/o_init.c7
-rw-r--r--crypto/openssl/crypto/o_str.c4
-rw-r--r--crypto/openssl/crypto/objects/obj_dat.c11
-rw-r--r--crypto/openssl/crypto/objects/obj_dat.h253
-rw-r--r--crypto/openssl/crypto/objects/obj_mac.h141
-rw-r--r--crypto/openssl/crypto/objects/obj_mac.num34
-rw-r--r--crypto/openssl/crypto/objects/objects.txt44
-rw-r--r--crypto/openssl/crypto/ocsp/ocsp_prn.c5
-rw-r--r--crypto/openssl/crypto/opensslv.h6
-rw-r--r--crypto/openssl/crypto/pem/pem_seal.c2
-rwxr-xr-xcrypto/openssl/crypto/perlasm/x86_64-xlate.pl2
-rw-r--r--crypto/openssl/crypto/pkcs12/p12_attr.c6
-rw-r--r--crypto/openssl/crypto/pkcs12/p12_key.c6
-rw-r--r--crypto/openssl/crypto/pkcs12/p12_utl.c6
-rw-r--r--crypto/openssl/crypto/pkcs12/pkcs12.h7
-rw-r--r--crypto/openssl/crypto/pkcs7/pk7_mime.c662
-rwxr-xr-xcrypto/openssl/crypto/ppccpuid.pl94
-rw-r--r--crypto/openssl/crypto/rand/rand_win.c71
-rw-r--r--crypto/openssl/crypto/rand/randfile.c17
-rw-r--r--crypto/openssl/crypto/rsa/rsa.h1
-rw-r--r--crypto/openssl/crypto/rsa/rsa_eay.c1
-rw-r--r--crypto/openssl/crypto/rsa/rsa_eng.c13
-rw-r--r--crypto/openssl/crypto/rsa/rsa_oaep.c14
-rw-r--r--crypto/openssl/crypto/rsa/rsa_pss.c2
-rw-r--r--crypto/openssl/crypto/rsa/rsa_sign.c10
-rw-r--r--crypto/openssl/crypto/s390xcpuid.S90
-rw-r--r--crypto/openssl/crypto/sha/sha512.c9
-rw-r--r--crypto/openssl/crypto/sparcv9cap.c154
-rw-r--r--crypto/openssl/crypto/stack/safestack.h44
-rw-r--r--crypto/openssl/crypto/symhacks.h20
-rw-r--r--crypto/openssl/crypto/ui/ui_openssl.c11
-rw-r--r--crypto/openssl/crypto/x509/by_dir.c5
-rw-r--r--crypto/openssl/crypto/x509/x509.h1
-rw-r--r--crypto/openssl/crypto/x509/x509_lu.c66
-rw-r--r--crypto/openssl/crypto/x509/x509_vfy.c14
-rw-r--r--crypto/openssl/crypto/x509/x509_vfy.h3
-rw-r--r--crypto/openssl/crypto/x509/x509_vpm.c6
-rw-r--r--crypto/openssl/crypto/x509v3/pcy_tree.c2
-rw-r--r--crypto/openssl/crypto/x509v3/v3_alt.c3
-rw-r--r--crypto/openssl/crypto/x509v3/v3_ocsp.c20
-rw-r--r--crypto/openssl/demos/x509/mkcert.c2
-rw-r--r--crypto/openssl/demos/x509/mkreq.c2
-rw-r--r--crypto/openssl/doc/apps/enc.pod10
-rw-r--r--crypto/openssl/doc/apps/verify.pod17
-rw-r--r--crypto/openssl/doc/crypto/ASN1_generate_nconf.pod2
-rw-r--r--crypto/openssl/doc/crypto/EVP_DigestInit.pod6
-rw-r--r--crypto/openssl/doc/crypto/PKCS12_parse.pod31
-rw-r--r--crypto/openssl/doc/crypto/bn_internal.pod28
-rw-r--r--crypto/openssl/doc/crypto/d2i_X509.pod12
-rw-r--r--crypto/openssl/doc/crypto/d2i_X509_CRL.pod4
-rw-r--r--crypto/openssl/doc/crypto/d2i_X509_REQ.pod4
-rw-r--r--crypto/openssl/doc/crypto/hmac.pod2
-rw-r--r--crypto/openssl/doc/crypto/pem.pod2
-rw-r--r--crypto/openssl/doc/ssl/SSL_CIPHER_get_name.pod2
-rw-r--r--crypto/openssl/doc/ssl/SSL_CTX_set_options.pod120
-rw-r--r--crypto/openssl/engines/Makefile17
-rw-r--r--crypto/openssl/engines/alpha.opt (renamed from crypto/openssl/engines/axp.opt)0
-rw-r--r--crypto/openssl/engines/e_capi.c54
-rw-r--r--crypto/openssl/engines/e_capi_err.c1
-rw-r--r--crypto/openssl/engines/e_capi_err.h1
-rw-r--r--crypto/openssl/engines/e_chil.c11
-rw-r--r--crypto/openssl/engines/e_ubsec.c4
-rw-r--r--crypto/openssl/engines/ia64.opt1
-rw-r--r--crypto/openssl/fips/Makefile14
-rw-r--r--crypto/openssl/fips/aes/fips_aesavs.c8
-rw-r--r--crypto/openssl/fips/des/fips_desmovs.c31
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_key.c2
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_sign.c2
-rw-r--r--crypto/openssl/fips/dsa/fips_dsatest.c2
-rw-r--r--crypto/openssl/fips/dsa/fips_dssvs.c25
-rw-r--r--crypto/openssl/fips/fips_locl.h1
-rw-r--r--crypto/openssl/fips/fips_test_suite.c79
-rw-r--r--crypto/openssl/fips/fips_utl.h16
-rwxr-xr-xcrypto/openssl/fips/fipsalgtest.pl55
-rwxr-xr-xcrypto/openssl/fips/fipsld12
-rw-r--r--crypto/openssl/fips/hmac/fips_hmac.c4
-rw-r--r--crypto/openssl/fips/hmac/fips_hmac_selftest.c2
-rw-r--r--crypto/openssl/fips/rand/fips_rand.c4
-rw-r--r--crypto/openssl/fips/rand/fips_rngvs.c4
-rw-r--r--crypto/openssl/fips/rsa/fips_rsagtest.c2
-rw-r--r--crypto/openssl/fips/rsa/fips_rsastest.c2
-rw-r--r--crypto/openssl/fips/rsa/fips_rsavtest.c3
-rw-r--r--crypto/openssl/fips/sha/Makefile6
-rw-r--r--crypto/openssl/fips/sha/fips_sha1_selftest.c2
-rw-r--r--crypto/openssl/openssl.spec6
-rw-r--r--crypto/openssl/ssl/Makefile25
-rw-r--r--crypto/openssl/ssl/d1_both.c242
-rw-r--r--crypto/openssl/ssl/d1_clnt.c104
-rw-r--r--crypto/openssl/ssl/d1_enc.c2
-rw-r--r--crypto/openssl/ssl/d1_lib.c199
-rw-r--r--crypto/openssl/ssl/d1_pkt.c225
-rw-r--r--crypto/openssl/ssl/d1_srvr.c228
-rw-r--r--crypto/openssl/ssl/dtls1.h52
-rw-r--r--crypto/openssl/ssl/kssl.c8
-rw-r--r--crypto/openssl/ssl/s23_clnt.c5
-rw-r--r--crypto/openssl/ssl/s23_srvr.c9
-rw-r--r--crypto/openssl/ssl/s2_srvr.c2
-rw-r--r--crypto/openssl/ssl/s3_both.c127
-rw-r--r--crypto/openssl/ssl/s3_clnt.c59
-rw-r--r--crypto/openssl/ssl/s3_lib.c20
-rw-r--r--crypto/openssl/ssl/s3_pkt.c70
-rw-r--r--crypto/openssl/ssl/s3_srvr.c91
-rw-r--r--crypto/openssl/ssl/ssl.h49
-rw-r--r--crypto/openssl/ssl/ssl3.h9
-rw-r--r--crypto/openssl/ssl/ssl_algs.c3
-rw-r--r--crypto/openssl/ssl/ssl_asn1.c65
-rw-r--r--crypto/openssl/ssl/ssl_cert.c7
-rw-r--r--crypto/openssl/ssl/ssl_ciph.c3
-rw-r--r--crypto/openssl/ssl/ssl_err.c16
-rw-r--r--crypto/openssl/ssl/ssl_lib.c60
-rw-r--r--crypto/openssl/ssl/ssl_locl.h27
-rw-r--r--crypto/openssl/ssl/ssl_rsa.c2
-rw-r--r--crypto/openssl/ssl/ssl_sess.c7
-rw-r--r--crypto/openssl/ssl/ssl_stat.c11
-rw-r--r--crypto/openssl/ssl/ssl_txt.c8
-rw-r--r--crypto/openssl/ssl/t1_enc.c6
-rw-r--r--crypto/openssl/ssl/t1_lib.c156
-rw-r--r--crypto/openssl/ssl/t1_reneg.c292
-rw-r--r--crypto/openssl/ssl/tls1.h7
-rw-r--r--crypto/openssl/test/Makefile10
-rwxr-xr-xcrypto/openssl/test/cms-test.pl5
-rwxr-xr-xcrypto/openssl/util/domd2
-rwxr-xr-xcrypto/openssl/util/libeay.num31
-rwxr-xr-xcrypto/openssl/util/mk1mf.pl5
-rwxr-xr-xcrypto/openssl/util/mkdef.pl23
-rw-r--r--crypto/openssl/util/mkerr.pl4
-rw-r--r--crypto/openssl/util/pl/Mingw32.pl1
-rw-r--r--crypto/openssl/util/pl/VC-32.pl23
-rwxr-xr-xcrypto/openssl/util/pod2man.pl2
-rwxr-xr-xcrypto/openssl/util/shlib_wrap.sh2
-rw-r--r--etc/Makefile5
-rw-r--r--etc/defaults/periodic.conf2
-rw-r--r--etc/defaults/rc.conf18
-rw-r--r--etc/devd.conf14
-rw-r--r--etc/devd/uath.conf156
-rw-r--r--etc/inetd.conf4
-rw-r--r--etc/mtree/BSD.include.dist4
-rw-r--r--etc/mtree/BSD.usr.dist2
-rw-r--r--etc/network.subr199
-rwxr-xr-xetc/rc.d/Makefile4
-rwxr-xr-xetc/rc.d/ip6addrctl2
-rwxr-xr-xetc/rc.d/jail15
-rwxr-xr-xetc/rc.d/netif9
-rwxr-xr-xetc/rc.d/netoptions7
-rwxr-xr-xetc/rc.d/routing32
-rwxr-xr-xetc/rc.d/tmp4
-rwxr-xr-xetc/rc.d/ubthidhci40
-rw-r--r--etc/rc.firewall19
-rw-r--r--etc/rc.subr11
-rw-r--r--etc/termcap.small160
-rw-r--r--games/fortune/Notes16
-rw-r--r--games/fortune/datfiles/fortunes2193
-rw-r--r--games/fortune/datfiles/fortunes-o.real358
-rw-r--r--games/fortune/datfiles/fortunes.sp.ok47
-rw-r--r--games/fortune/datfiles/limerick22
-rw-r--r--games/fortune/datfiles/startrek5
-rw-r--r--games/fortune/datfiles/zippy12
-rw-r--r--games/pom/pom.61
-rw-r--r--gnu/usr.bin/Makefile5
-rwxr-xr-xgnu/usr.bin/binutils/ld/elf32btsmipn32_fbsd.sh2
-rwxr-xr-xgnu/usr.bin/binutils/ld/elf32ltsmipn32_fbsd.sh2
-rw-r--r--gnu/usr.bin/cc/Makefile.inc4
-rw-r--r--gnu/usr.bin/cpio/Makefile79
-rw-r--r--gnu/usr.bin/cpio/config.h1001
-rw-r--r--gnu/usr.bin/cpio/doc/Makefile15
-rw-r--r--gnu/usr.bin/diff/context.c.diff2
-rw-r--r--gnu/usr.bin/diff/diff.c.diff18
-rw-r--r--gnu/usr.bin/dtc/Makefile2
-rw-r--r--gnu/usr.bin/gdb/Makefile3
-rw-r--r--gnu/usr.bin/gdb/Makefile.inc2
-rw-r--r--gnu/usr.bin/gdb/arch/arm/nm-fbsd.h2
-rw-r--r--gnu/usr.bin/gdb/gdbserver/Makefile17
-rw-r--r--gnu/usr.bin/gdb/gdbserver/fbsd-powerpc-low.c (renamed from gnu/usr.bin/gdb/gdbserver/fbsd-ppc-low.c)0
-rw-r--r--gnu/usr.bin/gdb/gdbserver/reg-amd64.c (renamed from gnu/usr.bin/gdb/gdbserver/reg-x86-64.c)0
-rw-r--r--gnu/usr.bin/gdb/gdbserver/reg-powerpc.c (renamed from gnu/usr.bin/gdb/gdbserver/reg-ppc.c)0
-rw-r--r--gnu/usr.bin/gdb/kgdb/kgdb.12
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_ia64.c7
-rw-r--r--include/Makefile4
-rw-r--r--include/dlfcn.h3
-rw-r--r--include/inttypes.h15
-rw-r--r--include/netdb.h1
-rw-r--r--include/nsswitch.h1
-rw-r--r--include/regexp.h66
-rw-r--r--include/stdlib.h2
-rw-r--r--include/utmp.h2
-rw-r--r--lib/Makefile102
-rw-r--r--lib/bind/config.h6
-rw-r--r--lib/csu/Makefile.inc2
-rw-r--r--lib/csu/amd64/crt1.c3
-rw-r--r--lib/csu/arm/Makefile5
-rw-r--r--lib/csu/arm/crt1.c3
-rw-r--r--lib/csu/i386-elf/Makefile2
-rw-r--r--lib/csu/ia64/Makefile3
-rw-r--r--lib/csu/mips/Makefile5
-rw-r--r--lib/csu/mips/crt1.c7
-rw-r--r--lib/csu/mips/crti.S51
-rw-r--r--lib/csu/mips/crtn.S29
-rw-r--r--lib/csu/powerpc/Makefile3
-rw-r--r--lib/csu/powerpc/crt1.c5
-rw-r--r--lib/csu/sparc64/crt1.c5
-rw-r--r--lib/libalias/Makefile.inc3
-rw-r--r--lib/libalias/libalias/Makefile1
-rw-r--r--lib/libarchive/test/Makefile1
-rw-r--r--lib/libbsnmp/Makefile.inc4
-rw-r--r--lib/libbsnmp/libbsnmp/Makefile5
-rw-r--r--lib/libc/arm/gen/makecontext.c7
-rw-r--r--lib/libc/arm/string/bzero.S7
-rw-r--r--lib/libc/arm/string/memcpy_arm.S7
-rw-r--r--lib/libc/arm/string/memmove.S7
-rw-r--r--lib/libc/compat-43/sigpause.21
-rw-r--r--lib/libc/db/hash/hash.c2
-rw-r--r--lib/libc/db/hash/hash.h2
-rw-r--r--lib/libc/db/man/hash.32
-rw-r--r--lib/libc/gen/__getosreldate.c2
-rw-r--r--lib/libc/gen/_spinlock_stub.c14
-rw-r--r--lib/libc/gen/_thread_init.c2
-rw-r--r--lib/libc/gen/check_utility_compat.32
-rw-r--r--lib/libc/gen/confstr.31
-rw-r--r--lib/libc/gen/daemon.c4
-rw-r--r--lib/libc/gen/dladdr.32
-rw-r--r--lib/libc/gen/dlfcn.c4
-rw-r--r--lib/libc/gen/dlinfo.32
-rw-r--r--lib/libc/gen/dllockinit.32
-rw-r--r--lib/libc/gen/dlopen.34
-rw-r--r--lib/libc/gen/fmtcheck.39
-rw-r--r--lib/libc/gen/fnmatch.c16
-rw-r--r--lib/libc/gen/frexp.32
-rw-r--r--lib/libc/gen/ftok.32
-rw-r--r--lib/libc/gen/getcwd.314
-rw-r--r--lib/libc/gen/getutxent.32
-rw-r--r--lib/libc/gen/opendir.c4
-rw-r--r--lib/libc/gen/setproctitle.32
-rw-r--r--lib/libc/gen/stringlist.39
-rw-r--r--lib/libc/gen/sysconf.34
-rw-r--r--lib/libc/gen/sysctl.327
-rw-r--r--lib/libc/include/reentrant.h7
-rw-r--r--lib/libc/locale/isalnum.31
-rw-r--r--lib/libc/locale/isalpha.31
-rw-r--r--lib/libc/net/getservent.c306
-rw-r--r--lib/libc/net/nsdispatch.33
-rw-r--r--lib/libc/posix1e/acl_add_flag_np.316
-rw-r--r--lib/libc/posix1e/acl_clear_flags_np.316
-rw-r--r--lib/libc/posix1e/acl_delete_flag_np.316
-rw-r--r--lib/libc/posix1e/acl_get_brand_np.316
-rw-r--r--lib/libc/posix1e/acl_get_entry_type_np.316
-rw-r--r--lib/libc/posix1e/acl_get_flag_np.316
-rw-r--r--lib/libc/posix1e/acl_get_flagset_np.316
-rw-r--r--lib/libc/posix1e/acl_set_entry_type_np.316
-rw-r--r--lib/libc/posix1e/acl_set_flagset_np.316
-rw-r--r--lib/libc/posix1e/acl_strip.c16
-rw-r--r--lib/libc/posix1e/acl_to_text_nfs4.c11
-rw-r--r--lib/libc/posix1e/mac_prepare.32
-rw-r--r--lib/libc/powerpc/gen/fpgetmask.c7
-rw-r--r--lib/libc/powerpc/gen/fpgetround.c7
-rw-r--r--lib/libc/powerpc/gen/fpgetsticky.c7
-rw-r--r--lib/libc/powerpc/gen/fpsetmask.c7
-rw-r--r--lib/libc/powerpc/gen/fpsetround.c7
-rw-r--r--lib/libc/rpc/Symbol.map4
-rw-r--r--lib/libc/rpc/clnt_simple.c22
-rw-r--r--lib/libc/rpc/getnetconfig.c29
-rw-r--r--lib/libc/rpc/key_call.c20
-rw-r--r--lib/libc/rpc/mt_misc.c27
-rw-r--r--lib/libc/rpc/mt_misc.h1
-rw-r--r--lib/libc/rpc/rpc_generic.c28
-rw-r--r--lib/libc/rpc/rpc_soc.c15
-rw-r--r--lib/libc/softfloat/softfloat-specialize4
-rw-r--r--lib/libc/sparc64/fpu/fpu.c53
-rw-r--r--lib/libc/sparc64/fpu/fpu_div.c16
-rw-r--r--lib/libc/sparc64/fpu/fpu_emu.h2
-rw-r--r--lib/libc/sparc64/fpu/fpu_explode.c27
-rw-r--r--lib/libc/sparc64/fpu/fpu_extern.h14
-rw-r--r--lib/libc/sparc64/fpu/fpu_implode.c34
-rw-r--r--lib/libc/stdio/findfp.c5
-rw-r--r--lib/libc/stdio/local.h8
-rw-r--r--lib/libc/stdio/printf.36
-rw-r--r--lib/libc/stdio/snprintf.c5
-rw-r--r--lib/libc/stdio/vasprintf.c12
-rw-r--r--lib/libc/stdio/vdprintf.c4
-rw-r--r--lib/libc/stdio/vfprintf.c2
-rw-r--r--lib/libc/stdio/vsnprintf.c5
-rw-r--r--lib/libc/stdio/vsprintf.c5
-rw-r--r--lib/libc/stdio/vsscanf.c7
-rw-r--r--lib/libc/stdio/vswprintf.c5
-rw-r--r--lib/libc/stdio/vswscanf.c7
-rw-r--r--lib/libc/stdio/xprintf.c3
-rw-r--r--lib/libc/stdlib/hcreate.32
-rw-r--r--lib/libc/stdlib/ptsname.32
-rw-r--r--lib/libc/stdlib/reallocf.c9
-rw-r--r--lib/libc/stdlib/realpath.329
-rw-r--r--lib/libc/stdlib/realpath.c48
-rw-r--r--lib/libc/string/strlen.c70
-rw-r--r--lib/libc/sys/mlockall.27
-rw-r--r--lib/libc/sys/mmap.27
-rw-r--r--lib/libc/sys/ntp_adjtime.27
-rw-r--r--lib/libc/sys/open.212
-rw-r--r--lib/libc/sys/sigaction.221
-rw-r--r--lib/libc/sys/stat.230
-rw-r--r--lib/libc/sys/unlink.24
-rw-r--r--lib/libc/sys/utrace.27
-rw-r--r--lib/libcam/cam.32
-rw-r--r--lib/libcam/cam_cdbparse.32
-rw-r--r--lib/libcompat/4.1/ascftime.c3
-rw-r--r--lib/libcompat/4.1/cftime.32
-rw-r--r--lib/libcompat/4.1/cftime.c3
-rw-r--r--lib/libcompat/4.1/ftime.c3
-rw-r--r--lib/libcompat/4.1/getpw.c13
-rw-r--r--lib/libcompat/4.3/cfree.c1
-rw-r--r--lib/libcompat/4.3/re_comp.313
-rw-r--r--lib/libcompat/4.3/re_comp.c (renamed from lib/libcompat/4.3/regex.c)62
-rw-r--r--lib/libcompat/4.4/cuserid.32
-rw-r--r--lib/libcompat/Makefile26
-rw-r--r--lib/libcompat/regexp/COPYRIGHT22
-rw-r--r--lib/libcompat/regexp/README84
-rw-r--r--lib/libcompat/regexp/regerror.c18
-rw-r--r--lib/libcompat/regexp/regexp.3319
-rw-r--r--lib/libcompat/regexp/regexp.c1337
-rw-r--r--lib/libcompat/regexp/regmagic.h5
-rw-r--r--lib/libcompat/regexp/regsub.c85
-rw-r--r--lib/libedit/editline.32
-rw-r--r--lib/libedit/editrc.52
-rw-r--r--lib/libelf/elf.32
-rw-r--r--lib/libelf/elf_begin.32
-rw-r--r--lib/libelf/elf_cntl.32
-rw-r--r--lib/libelf/elf_end.32
-rw-r--r--lib/libelf/elf_errmsg.32
-rw-r--r--lib/libelf/elf_fill.32
-rw-r--r--lib/libelf/elf_flagdata.32
-rw-r--r--lib/libelf/elf_getarhdr.32
-rw-r--r--lib/libelf/elf_getarsym.32
-rw-r--r--lib/libelf/elf_getbase.32
-rw-r--r--lib/libelf/elf_getdata.32
-rw-r--r--lib/libelf/elf_getident.32
-rw-r--r--lib/libelf/elf_getphnum.32
-rw-r--r--lib/libelf/elf_getscn.32
-rw-r--r--lib/libelf/elf_getshnum.32
-rw-r--r--lib/libelf/elf_getshstrndx.32
-rw-r--r--lib/libelf/elf_hash.32
-rw-r--r--lib/libelf/elf_kind.32
-rw-r--r--lib/libelf/elf_memory.32
-rw-r--r--lib/libelf/elf_next.32
-rw-r--r--lib/libelf/elf_rand.32
-rw-r--r--lib/libelf/elf_rawfile.32
-rw-r--r--lib/libelf/elf_strptr.32
-rw-r--r--lib/libelf/elf_update.32
-rw-r--r--lib/libelf/elf_version.32
-rw-r--r--lib/libelf/gelf.32
-rw-r--r--lib/libelf/gelf_checksum.32
-rw-r--r--lib/libelf/gelf_fsize.32
-rw-r--r--lib/libelf/gelf_getcap.32
-rw-r--r--lib/libelf/gelf_getclass.32
-rw-r--r--lib/libelf/gelf_getdyn.32
-rw-r--r--lib/libelf/gelf_getehdr.32
-rw-r--r--lib/libelf/gelf_getmove.32
-rw-r--r--lib/libelf/gelf_getphdr.32
-rw-r--r--lib/libelf/gelf_getrel.32
-rw-r--r--lib/libelf/gelf_getrela.32
-rw-r--r--lib/libelf/gelf_getshdr.32
-rw-r--r--lib/libelf/gelf_getsym.32
-rw-r--r--lib/libelf/gelf_getsyminfo.32
-rw-r--r--lib/libelf/gelf_getsymshndx.32
-rw-r--r--lib/libelf/gelf_newehdr.32
-rw-r--r--lib/libelf/gelf_newphdr.32
-rw-r--r--lib/libelf/gelf_update_ehdr.32
-rw-r--r--lib/libelf/gelf_xlatetof.32
-rw-r--r--lib/libgssapi/gss_accept_sec_context.32
-rw-r--r--lib/libgssapi/gss_acquire_cred.32
-rw-r--r--lib/libgssapi/gss_add_cred.32
-rw-r--r--lib/libgssapi/gss_add_oid_set_member.32
-rw-r--r--lib/libgssapi/gss_canonicalize_name.32
-rw-r--r--lib/libgssapi/gss_compare_name.32
-rw-r--r--lib/libgssapi/gss_context_time.32
-rw-r--r--lib/libgssapi/gss_create_empty_oid_set.32
-rw-r--r--lib/libgssapi/gss_delete_sec_context.32
-rw-r--r--lib/libgssapi/gss_display_name.32
-rw-r--r--lib/libgssapi/gss_display_status.32
-rw-r--r--lib/libgssapi/gss_duplicate_name.32
-rw-r--r--lib/libgssapi/gss_export_name.32
-rw-r--r--lib/libgssapi/gss_export_sec_context.32
-rw-r--r--lib/libgssapi/gss_get_mic.32
-rw-r--r--lib/libgssapi/gss_import_name.32
-rw-r--r--lib/libgssapi/gss_import_sec_context.32
-rw-r--r--lib/libgssapi/gss_indicate_mechs.32
-rw-r--r--lib/libgssapi/gss_init_sec_context.34
-rw-r--r--lib/libgssapi/gss_inquire_context.32
-rw-r--r--lib/libgssapi/gss_inquire_cred.32
-rw-r--r--lib/libgssapi/gss_inquire_cred_by_mech.32
-rw-r--r--lib/libgssapi/gss_inquire_mechs_for_name.32
-rw-r--r--lib/libgssapi/gss_inquire_names_for_mech.32
-rw-r--r--lib/libgssapi/gss_process_context_token.32
-rw-r--r--lib/libgssapi/gss_release_buffer.32
-rw-r--r--lib/libgssapi/gss_release_cred.32
-rw-r--r--lib/libgssapi/gss_release_name.32
-rw-r--r--lib/libgssapi/gss_release_oid_set.32
-rw-r--r--lib/libgssapi/gss_test_oid_set_member.32
-rw-r--r--lib/libgssapi/gss_unwrap.33
-rw-r--r--lib/libgssapi/gss_verify_mic.32
-rw-r--r--lib/libgssapi/gss_wrap.32
-rw-r--r--lib/libgssapi/gss_wrap_size_limit.32
-rw-r--r--lib/libkvm/kvm.38
-rw-r--r--lib/libkvm/kvm_getpcpu.32
-rw-r--r--lib/libmemstat/libmemstat.32
-rw-r--r--lib/libpam/Makefile.inc2
-rw-r--r--lib/libpam/modules/Makefile.inc1
-rw-r--r--lib/libpam/modules/pam_krb5/Makefile2
-rw-r--r--lib/libpam/modules/pam_ssh/pam_ssh.c3
-rw-r--r--lib/libpkg/Makefile47
-rw-r--r--lib/libpkg/deps.c (renamed from usr.sbin/pkg_install/lib/deps.c)2
-rw-r--r--lib/libpkg/exec.c (renamed from usr.sbin/pkg_install/lib/exec.c)2
-rw-r--r--lib/libpkg/file.c (renamed from usr.sbin/pkg_install/lib/file.c)33
-rw-r--r--lib/libpkg/global.c (renamed from usr.sbin/pkg_install/lib/global.c)2
-rw-r--r--lib/libpkg/match.c (renamed from usr.sbin/pkg_install/lib/match.c)6
-rw-r--r--lib/libpkg/msg.c (renamed from usr.sbin/pkg_install/lib/msg.c)9
-rw-r--r--lib/libpkg/pen.c (renamed from usr.sbin/pkg_install/lib/pen.c)21
-rw-r--r--lib/libpkg/pkg.h (renamed from usr.sbin/pkg_install/lib/lib.h)30
-rw-r--r--lib/libpkg/pkgwrap.c90
-rw-r--r--lib/libpkg/plist.c (renamed from usr.sbin/pkg_install/lib/plist.c)4
-rw-r--r--lib/libpkg/str.c (renamed from usr.sbin/pkg_install/lib/str.c)2
-rw-r--r--lib/libpkg/url.c (renamed from usr.sbin/pkg_install/lib/url.c)6
-rw-r--r--lib/libpkg/version.c (renamed from usr.sbin/pkg_install/lib/version.c)12
-rw-r--r--lib/libpmc/Makefile5
-rw-r--r--lib/libpmc/libpmc.c248
-rw-r--r--lib/libpmc/pmc.32
-rw-r--r--lib/libpmc/pmc.atom.32
-rw-r--r--lib/libpmc/pmc.core.32
-rw-r--r--lib/libpmc/pmc.core2.32
-rw-r--r--lib/libpmc/pmc.corei7.31581
-rw-r--r--lib/libpmc/pmc.corei7uc.3880
-rw-r--r--lib/libpmc/pmc.iaf.32
-rw-r--r--lib/libpmc/pmc.k7.32
-rw-r--r--lib/libpmc/pmc.k8.32
-rw-r--r--lib/libpmc/pmc.mips.3410
-rw-r--r--lib/libpmc/pmc.p4.32
-rw-r--r--lib/libpmc/pmc.p5.32
-rw-r--r--lib/libpmc/pmc.p6.32
-rw-r--r--lib/libpmc/pmc.tsc.32
-rw-r--r--lib/libpmc/pmc.ucf.3115
-rw-r--r--lib/libpmc/pmc.westmere.31329
-rw-r--r--lib/libpmc/pmc.westmereuc.31083
-rw-r--r--lib/libpmc/pmc.xscale.3121
-rw-r--r--lib/libpmc/pmc_allocate.32
-rw-r--r--lib/libpmc/pmc_attach.32
-rw-r--r--lib/libpmc/pmc_capabilities.32
-rw-r--r--lib/libpmc/pmc_configure_logfile.32
-rw-r--r--lib/libpmc/pmc_disable.32
-rw-r--r--lib/libpmc/pmc_event_names_of_class.32
-rw-r--r--lib/libpmc/pmc_get_driver_stats.32
-rw-r--r--lib/libpmc/pmc_get_msr.32
-rw-r--r--lib/libpmc/pmc_init.32
-rw-r--r--lib/libpmc/pmc_name_of_capability.32
-rw-r--r--lib/libpmc/pmc_read.32
-rw-r--r--lib/libpmc/pmc_set.32
-rw-r--r--lib/libpmc/pmc_start.32
-rw-r--r--lib/libpmc/pmclog.32
-rw-r--r--lib/librpcsec_gss/rpcsec_gss.31
-rw-r--r--lib/libsm/Makefile1
-rw-r--r--lib/libstand/assert.c8
-rw-r--r--lib/libstand/bzipfs.c8
-rw-r--r--lib/libstand/gzipfs.c8
-rw-r--r--lib/libthr/libthr.32
-rw-r--r--lib/libufs/Makefile7
-rw-r--r--lib/libufs/cgroup.c140
-rw-r--r--lib/libufs/inode.c16
-rw-r--r--lib/libufs/libufs.h16
-rw-r--r--lib/libufs/sblock.c50
-rw-r--r--lib/libufs/type.c5
-rw-r--r--lib/libugidfw/bsde_get_rule.32
-rw-r--r--lib/libugidfw/bsde_get_rule_count.32
-rw-r--r--lib/libugidfw/bsde_parse_rule.32
-rw-r--r--lib/libugidfw/bsde_rule_to_string.32
-rw-r--r--lib/libugidfw/libugidfw.32
-rw-r--r--lib/libulog/ulog_login.32
-rw-r--r--lib/libulog/utempter_add_record.32
-rw-r--r--lib/libusbhid/data.c31
-rw-r--r--lib/libusbhid/descr.c22
-rw-r--r--lib/libusbhid/parse.c536
-rw-r--r--lib/libusbhid/usage.c1
-rw-r--r--lib/libusbhid/usbhid.h63
-rw-r--r--lib/libusbhid/usbvar.h4
-rw-r--r--lib/libutil/_secure_path.32
-rw-r--r--lib/libutil/auth.32
-rw-r--r--lib/libutil/hexdump.32
-rw-r--r--lib/libutil/humanize_number.37
-rw-r--r--lib/libutil/kinfo_getfile.32
-rw-r--r--lib/libutil/kinfo_getvmmap.32
-rw-r--r--lib/libutil/kld.32
-rw-r--r--lib/libutil/login_auth.32
-rw-r--r--lib/libutil/login_cap.32
-rw-r--r--lib/libutil/login_class.32
-rw-r--r--lib/libutil/login_ok.32
-rw-r--r--lib/libutil/login_times.32
-rw-r--r--lib/libutil/login_tty.32
-rw-r--r--lib/libutil/property.32
-rw-r--r--lib/libutil/pty.32
-rw-r--r--lib/libutil/realhostname.32
-rw-r--r--lib/libutil/realhostname_sa.32
-rw-r--r--lib/libutil/trimdomain.32
-rw-r--r--lib/libutil/uucplock.32
-rw-r--r--lib/libz/ChangeLog355
-rw-r--r--lib/libz/FAQ261
-rw-r--r--lib/libz/Makefile46
-rw-r--r--lib/libz/README86
-rw-r--r--lib/libz/Symbol.map96
-rw-r--r--lib/libz/Versions.def11
-rw-r--r--lib/libz/adler32.c38
-rw-r--r--lib/libz/compress.c5
-rw-r--r--lib/libz/contrib/README.contrib77
-rw-r--r--lib/libz/contrib/asm686/README.68651
-rw-r--r--lib/libz/contrib/asm686/match.S343
-rw-r--r--lib/libz/contrib/gcc_gvmat64/gvmat64.S574
-rw-r--r--lib/libz/crc32.c35
-rw-r--r--lib/libz/deflate.c268
-rw-r--r--lib/libz/deflate.h35
-rw-r--r--lib/libz/doc/algorithm.txt (renamed from lib/libz/algorithm.txt)2
-rw-r--r--lib/libz/doc/rfc1950.txt619
-rw-r--r--lib/libz/doc/rfc1951.txt955
-rw-r--r--lib/libz/doc/rfc1952.txt675
-rw-r--r--lib/libz/doc/txtvsbin.txt107
-rw-r--r--lib/libz/example.c4
-rw-r--r--lib/libz/gzclose.c25
-rw-r--r--lib/libz/gzguts.h132
-rw-r--r--lib/libz/gzio.c1027
-rw-r--r--lib/libz/gzlib.c540
-rw-r--r--lib/libz/gzread.c656
-rw-r--r--lib/libz/gzwrite.c532
-rw-r--r--lib/libz/infback.c93
-rw-r--r--lib/libz/inffast.c80
-rw-r--r--lib/libz/inffast.h4
-rw-r--r--lib/libz/inflate.c282
-rw-r--r--lib/libz/inflate.h31
-rw-r--r--lib/libz/inftrees.c63
-rw-r--r--lib/libz/inftrees.h27
-rw-r--r--lib/libz/minigzip.c140
-rw-r--r--lib/libz/trees.c93
-rw-r--r--lib/libz/trees.h4
-rw-r--r--lib/libz/uncompr.c4
-rw-r--r--lib/libz/zconf.h199
-rw-r--r--lib/libz/zlib.366
-rw-r--r--lib/libz/zlib.h1162
-rw-r--r--lib/libz/zutil.c32
-rw-r--r--lib/libz/zutil.h63
-rw-r--r--lib/msun/man/cimag.32
-rw-r--r--libexec/fingerd/fingerd.823
-rw-r--r--libexec/fingerd/fingerd.c36
-rw-r--r--libexec/ftpd/popen.c3
-rw-r--r--libexec/rtld-elf/mips/reloc.c287
-rw-r--r--libexec/rtld-elf/mips/rtld_start.S181
-rw-r--r--libexec/rtld-elf/rtld.c2
-rw-r--r--libexec/tftpd/tftpd.82
-rw-r--r--release/Makefile4
-rw-r--r--release/Makefile.inc.docports2
-rw-r--r--release/powerpc/boot_crunch.conf5
-rw-r--r--sbin/ddb/Makefile2
-rw-r--r--sbin/devd/devd.conf.556
-rw-r--r--sbin/dumpfs/dumpfs.c4
-rw-r--r--sbin/fsck_ffs/Makefile3
-rw-r--r--sbin/fsck_ffs/fsck.h10
-rw-r--r--sbin/fsck_ffs/gjournal.c293
-rw-r--r--sbin/fsck_ffs/main.c27
-rw-r--r--sbin/fsck_ffs/pass5.c1
-rw-r--r--sbin/fsck_ffs/suj.c2634
-rw-r--r--sbin/fsdb/fsdb.c11
-rw-r--r--sbin/fsdb/fsdbutil.c26
-rw-r--r--sbin/geom/class/Makefile1
-rw-r--r--sbin/geom/class/cache/gcache.816
-rw-r--r--sbin/geom/class/mountver/gmountver.816
-rw-r--r--sbin/geom/class/multipath/geom_multipath.c104
-rw-r--r--sbin/geom/class/part/geom_part.c102
-rw-r--r--sbin/geom/class/part/gpart.838
-rw-r--r--sbin/geom/class/sched/Makefile18
-rw-r--r--sbin/geom/class/sched/geom_sched.c124
-rw-r--r--sbin/geom/class/sched/gsched.8163
-rw-r--r--sbin/geom/misc/subr.c2
-rw-r--r--sbin/gvinum/gvinum.c26
-rw-r--r--sbin/hastctl/Makefile10
-rw-r--r--sbin/hastd/Makefile11
-rw-r--r--sbin/hastd/hast_proto.c8
-rw-r--r--sbin/hastd/hastd.c1
-rw-r--r--sbin/hastd/pjdlog.c2
-rw-r--r--sbin/hastd/primary.c78
-rw-r--r--sbin/ifconfig/ifconfig.c25
-rw-r--r--sbin/ifconfig/ifieee80211.c1
-rw-r--r--sbin/ipf/ipftest/Makefile3
-rw-r--r--sbin/ipfw/altq.c1
-rw-r--r--sbin/ipfw/dummynet.c965
-rw-r--r--sbin/ipfw/ipfw.8252
-rw-r--r--sbin/ipfw/ipfw2.c423
-rw-r--r--sbin/ipfw/ipfw2.h32
-rw-r--r--sbin/ipfw/main.c162
-rw-r--r--sbin/iscontrol/iscsi.conf.52
-rw-r--r--sbin/mca/mca.c36
-rw-r--r--sbin/mount/mount.c6
-rw-r--r--sbin/newfs/Makefile4
-rw-r--r--sbin/newfs/newfs.84
-rw-r--r--sbin/newfs/newfs.c55
-rw-r--r--sbin/nos-tun/Makefile2
-rw-r--r--sbin/nos-tun/nos-tun.c27
-rw-r--r--sbin/ping6/ping6.88
-rw-r--r--sbin/ping6/ping6.c14
-rw-r--r--sbin/quotacheck/quotacheck.82
-rw-r--r--sbin/setkey/setkey.82
-rw-r--r--sbin/spppcontrol/spppcontrol.82
-rw-r--r--sbin/sysctl/sysctl.c1
-rw-r--r--sbin/tunefs/Makefile2
-rw-r--r--sbin/tunefs/tunefs.89
-rw-r--r--sbin/tunefs/tunefs.c567
-rw-r--r--secure/lib/libcrypto/Makefile.inc7
-rw-r--r--secure/lib/libcrypto/Makefile.man66
-rw-r--r--secure/lib/libcrypto/man/ASN1_OBJECT_new.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_STRING_length.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_STRING_new.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_STRING_print_ex.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_generate_nconf.34
-rw-r--r--secure/lib/libcrypto/man/BIO_ctrl.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_base64.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_buffer.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_cipher.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_md.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_null.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_ssl.32
-rw-r--r--secure/lib/libcrypto/man/BIO_find_type.32
-rw-r--r--secure/lib/libcrypto/man/BIO_new.32
-rw-r--r--secure/lib/libcrypto/man/BIO_push.32
-rw-r--r--secure/lib/libcrypto/man/BIO_read.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_accept.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_bio.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_connect.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_fd.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_file.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_mem.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_null.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_socket.32
-rw-r--r--secure/lib/libcrypto/man/BIO_set_callback.32
-rw-r--r--secure/lib/libcrypto/man/BIO_should_retry.32
-rw-r--r--secure/lib/libcrypto/man/BN_BLINDING_new.32
-rw-r--r--secure/lib/libcrypto/man/BN_CTX_new.32
-rw-r--r--secure/lib/libcrypto/man/BN_CTX_start.32
-rw-r--r--secure/lib/libcrypto/man/BN_add.32
-rw-r--r--secure/lib/libcrypto/man/BN_add_word.32
-rw-r--r--secure/lib/libcrypto/man/BN_bn2bin.32
-rw-r--r--secure/lib/libcrypto/man/BN_cmp.32
-rw-r--r--secure/lib/libcrypto/man/BN_copy.32
-rw-r--r--secure/lib/libcrypto/man/BN_generate_prime.32
-rw-r--r--secure/lib/libcrypto/man/BN_mod_inverse.32
-rw-r--r--secure/lib/libcrypto/man/BN_mod_mul_montgomery.32
-rw-r--r--secure/lib/libcrypto/man/BN_mod_mul_reciprocal.32
-rw-r--r--secure/lib/libcrypto/man/BN_new.32
-rw-r--r--secure/lib/libcrypto/man/BN_num_bytes.32
-rw-r--r--secure/lib/libcrypto/man/BN_rand.32
-rw-r--r--secure/lib/libcrypto/man/BN_set_bit.32
-rw-r--r--secure/lib/libcrypto/man/BN_swap.32
-rw-r--r--secure/lib/libcrypto/man/BN_zero.32
-rw-r--r--secure/lib/libcrypto/man/CONF_modules_free.32
-rw-r--r--secure/lib/libcrypto/man/CONF_modules_load_file.32
-rw-r--r--secure/lib/libcrypto/man/CRYPTO_set_ex_data.32
-rw-r--r--secure/lib/libcrypto/man/DH_generate_key.32
-rw-r--r--secure/lib/libcrypto/man/DH_generate_parameters.32
-rw-r--r--secure/lib/libcrypto/man/DH_get_ex_new_index.32
-rw-r--r--secure/lib/libcrypto/man/DH_new.32
-rw-r--r--secure/lib/libcrypto/man/DH_set_method.32
-rw-r--r--secure/lib/libcrypto/man/DH_size.32
-rw-r--r--secure/lib/libcrypto/man/DSA_SIG_new.32
-rw-r--r--secure/lib/libcrypto/man/DSA_do_sign.32
-rw-r--r--secure/lib/libcrypto/man/DSA_dup_DH.32
-rw-r--r--secure/lib/libcrypto/man/DSA_generate_key.32
-rw-r--r--secure/lib/libcrypto/man/DSA_generate_parameters.32
-rw-r--r--secure/lib/libcrypto/man/DSA_get_ex_new_index.32
-rw-r--r--secure/lib/libcrypto/man/DSA_new.32
-rw-r--r--secure/lib/libcrypto/man/DSA_set_method.32
-rw-r--r--secure/lib/libcrypto/man/DSA_sign.32
-rw-r--r--secure/lib/libcrypto/man/DSA_size.32
-rw-r--r--secure/lib/libcrypto/man/ERR_GET_LIB.32
-rw-r--r--secure/lib/libcrypto/man/ERR_clear_error.32
-rw-r--r--secure/lib/libcrypto/man/ERR_error_string.32
-rw-r--r--secure/lib/libcrypto/man/ERR_get_error.32
-rw-r--r--secure/lib/libcrypto/man/ERR_load_crypto_strings.32
-rw-r--r--secure/lib/libcrypto/man/ERR_load_strings.32
-rw-r--r--secure/lib/libcrypto/man/ERR_print_errors.32
-rw-r--r--secure/lib/libcrypto/man/ERR_put_error.32
-rw-r--r--secure/lib/libcrypto/man/ERR_remove_state.32
-rw-r--r--secure/lib/libcrypto/man/ERR_set_mark.32
-rw-r--r--secure/lib/libcrypto/man/EVP_BytesToKey.32
-rw-r--r--secure/lib/libcrypto/man/EVP_DigestInit.38
-rw-r--r--secure/lib/libcrypto/man/EVP_EncryptInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_OpenInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_PKEY_new.32
-rw-r--r--secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.32
-rw-r--r--secure/lib/libcrypto/man/EVP_SealInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_SignInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_VerifyInit.32
-rw-r--r--secure/lib/libcrypto/man/OBJ_nid2obj.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_Applink.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_config.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_ia32cap.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.32
-rw-r--r--secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.32
-rw-r--r--secure/lib/libcrypto/man/PKCS12_create.32
-rw-r--r--secure/lib/libcrypto/man/PKCS12_parse.332
-rw-r--r--secure/lib/libcrypto/man/PKCS7_decrypt.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_encrypt.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_sign.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_verify.32
-rw-r--r--secure/lib/libcrypto/man/RAND_add.32
-rw-r--r--secure/lib/libcrypto/man/RAND_bytes.32
-rw-r--r--secure/lib/libcrypto/man/RAND_cleanup.32
-rw-r--r--secure/lib/libcrypto/man/RAND_egd.32
-rw-r--r--secure/lib/libcrypto/man/RAND_load_file.32
-rw-r--r--secure/lib/libcrypto/man/RAND_set_rand_method.32
-rw-r--r--secure/lib/libcrypto/man/RSA_blinding_on.32
-rw-r--r--secure/lib/libcrypto/man/RSA_check_key.32
-rw-r--r--secure/lib/libcrypto/man/RSA_generate_key.32
-rw-r--r--secure/lib/libcrypto/man/RSA_get_ex_new_index.32
-rw-r--r--secure/lib/libcrypto/man/RSA_new.32
-rw-r--r--secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.32
-rw-r--r--secure/lib/libcrypto/man/RSA_print.32
-rw-r--r--secure/lib/libcrypto/man/RSA_private_encrypt.32
-rw-r--r--secure/lib/libcrypto/man/RSA_public_encrypt.32
-rw-r--r--secure/lib/libcrypto/man/RSA_set_method.32
-rw-r--r--secure/lib/libcrypto/man/RSA_sign.32
-rw-r--r--secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.32
-rw-r--r--secure/lib/libcrypto/man/RSA_size.32
-rw-r--r--secure/lib/libcrypto/man/SMIME_read_PKCS7.32
-rw-r--r--secure/lib/libcrypto/man/SMIME_write_PKCS7.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_print_ex.32
-rw-r--r--secure/lib/libcrypto/man/X509_new.32
-rw-r--r--secure/lib/libcrypto/man/bio.32
-rw-r--r--secure/lib/libcrypto/man/blowfish.32
-rw-r--r--secure/lib/libcrypto/man/bn.32
-rw-r--r--secure/lib/libcrypto/man/bn_internal.333
-rw-r--r--secure/lib/libcrypto/man/buffer.32
-rw-r--r--secure/lib/libcrypto/man/crypto.32
-rw-r--r--secure/lib/libcrypto/man/d2i_ASN1_OBJECT.32
-rw-r--r--secure/lib/libcrypto/man/d2i_DHparams.32
-rw-r--r--secure/lib/libcrypto/man/d2i_DSAPublicKey.32
-rw-r--r--secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.32
-rw-r--r--secure/lib/libcrypto/man/d2i_RSAPublicKey.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509.314
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_ALGOR.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_CRL.36
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_NAME.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_REQ.36
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_SIG.32
-rw-r--r--secure/lib/libcrypto/man/des.32
-rw-r--r--secure/lib/libcrypto/man/dh.32
-rw-r--r--secure/lib/libcrypto/man/dsa.32
-rw-r--r--secure/lib/libcrypto/man/ecdsa.32
-rw-r--r--secure/lib/libcrypto/man/engine.32
-rw-r--r--secure/lib/libcrypto/man/err.32
-rw-r--r--secure/lib/libcrypto/man/evp.32
-rw-r--r--secure/lib/libcrypto/man/hmac.34
-rw-r--r--secure/lib/libcrypto/man/lh_stats.32
-rw-r--r--secure/lib/libcrypto/man/lhash.32
-rw-r--r--secure/lib/libcrypto/man/md5.32
-rw-r--r--secure/lib/libcrypto/man/mdc2.32
-rw-r--r--secure/lib/libcrypto/man/pem.34
-rw-r--r--secure/lib/libcrypto/man/rand.32
-rw-r--r--secure/lib/libcrypto/man/rc4.32
-rw-r--r--secure/lib/libcrypto/man/ripemd.32
-rw-r--r--secure/lib/libcrypto/man/rsa.32
-rw-r--r--secure/lib/libcrypto/man/sha.32
-rw-r--r--secure/lib/libcrypto/man/threads.32
-rw-r--r--secure/lib/libcrypto/man/ui.32
-rw-r--r--secure/lib/libcrypto/man/ui_compat.32
-rw-r--r--secure/lib/libcrypto/man/x509.32
-rw-r--r--secure/lib/libssh/Makefile5
-rw-r--r--secure/lib/libssl/Makefile2
-rw-r--r--secure/lib/libssl/Makefile.man3
-rw-r--r--secure/lib/libssl/man/SSL_CIPHER_get_name.34
-rw-r--r--secure/lib/libssl/man/SSL_COMP_add_compression_method.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_add_session.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_ctrl.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_flush_sessions.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_free.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_get_ex_new_index.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_get_verify_mode.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_load_verify_locations.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_new.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sess_number.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sessions.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_cert_store.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_cipher_list.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_client_CA_list.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_generate_session_id.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_info_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_max_cert_list.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_mode.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_msg_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_options.3120
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_session_id_context.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_ssl_version.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_timeout.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_verify.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_use_certificate.32
-rw-r--r--secure/lib/libssl/man/SSL_SESSION_free.32
-rw-r--r--secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.32
-rw-r--r--secure/lib/libssl/man/SSL_SESSION_get_time.32
-rw-r--r--secure/lib/libssl/man/SSL_accept.32
-rw-r--r--secure/lib/libssl/man/SSL_alert_type_string.32
-rw-r--r--secure/lib/libssl/man/SSL_clear.32
-rw-r--r--secure/lib/libssl/man/SSL_connect.32
-rw-r--r--secure/lib/libssl/man/SSL_do_handshake.32
-rw-r--r--secure/lib/libssl/man/SSL_free.32
-rw-r--r--secure/lib/libssl/man/SSL_get_SSL_CTX.32
-rw-r--r--secure/lib/libssl/man/SSL_get_ciphers.32
-rw-r--r--secure/lib/libssl/man/SSL_get_client_CA_list.32
-rw-r--r--secure/lib/libssl/man/SSL_get_current_cipher.32
-rw-r--r--secure/lib/libssl/man/SSL_get_default_timeout.32
-rw-r--r--secure/lib/libssl/man/SSL_get_error.32
-rw-r--r--secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.32
-rw-r--r--secure/lib/libssl/man/SSL_get_ex_new_index.32
-rw-r--r--secure/lib/libssl/man/SSL_get_fd.32
-rw-r--r--secure/lib/libssl/man/SSL_get_peer_cert_chain.32
-rw-r--r--secure/lib/libssl/man/SSL_get_peer_certificate.32
-rw-r--r--secure/lib/libssl/man/SSL_get_rbio.32
-rw-r--r--secure/lib/libssl/man/SSL_get_session.32
-rw-r--r--secure/lib/libssl/man/SSL_get_verify_result.32
-rw-r--r--secure/lib/libssl/man/SSL_get_version.32
-rw-r--r--secure/lib/libssl/man/SSL_library_init.32
-rw-r--r--secure/lib/libssl/man/SSL_load_client_CA_file.32
-rw-r--r--secure/lib/libssl/man/SSL_new.32
-rw-r--r--secure/lib/libssl/man/SSL_pending.32
-rw-r--r--secure/lib/libssl/man/SSL_read.32
-rw-r--r--secure/lib/libssl/man/SSL_rstate_string.32
-rw-r--r--secure/lib/libssl/man/SSL_session_reused.32
-rw-r--r--secure/lib/libssl/man/SSL_set_bio.32
-rw-r--r--secure/lib/libssl/man/SSL_set_connect_state.32
-rw-r--r--secure/lib/libssl/man/SSL_set_fd.32
-rw-r--r--secure/lib/libssl/man/SSL_set_session.32
-rw-r--r--secure/lib/libssl/man/SSL_set_shutdown.32
-rw-r--r--secure/lib/libssl/man/SSL_set_verify_result.32
-rw-r--r--secure/lib/libssl/man/SSL_shutdown.32
-rw-r--r--secure/lib/libssl/man/SSL_state_string.32
-rw-r--r--secure/lib/libssl/man/SSL_want.32
-rw-r--r--secure/lib/libssl/man/SSL_write.32
-rw-r--r--secure/lib/libssl/man/d2i_SSL_SESSION.32
-rw-r--r--secure/lib/libssl/man/ssl.32
-rw-r--r--secure/libexec/Makefile2
-rw-r--r--secure/libexec/ssh-pkcs11-helper/Makefile16
-rw-r--r--secure/usr.bin/openssl/man/CA.pl.12
-rw-r--r--secure/usr.bin/openssl/man/asn1parse.12
-rw-r--r--secure/usr.bin/openssl/man/ca.12
-rw-r--r--secure/usr.bin/openssl/man/ciphers.12
-rw-r--r--secure/usr.bin/openssl/man/crl.12
-rw-r--r--secure/usr.bin/openssl/man/crl2pkcs7.12
-rw-r--r--secure/usr.bin/openssl/man/dgst.12
-rw-r--r--secure/usr.bin/openssl/man/dhparam.12
-rw-r--r--secure/usr.bin/openssl/man/dsa.12
-rw-r--r--secure/usr.bin/openssl/man/dsaparam.12
-rw-r--r--secure/usr.bin/openssl/man/ec.12
-rw-r--r--secure/usr.bin/openssl/man/ecparam.12
-rw-r--r--secure/usr.bin/openssl/man/enc.112
-rw-r--r--secure/usr.bin/openssl/man/errstr.12
-rw-r--r--secure/usr.bin/openssl/man/gendsa.12
-rw-r--r--secure/usr.bin/openssl/man/genrsa.12
-rw-r--r--secure/usr.bin/openssl/man/nseq.12
-rw-r--r--secure/usr.bin/openssl/man/ocsp.12
-rw-r--r--secure/usr.bin/openssl/man/openssl.12
-rw-r--r--secure/usr.bin/openssl/man/passwd.12
-rw-r--r--secure/usr.bin/openssl/man/pkcs12.12
-rw-r--r--secure/usr.bin/openssl/man/pkcs7.12
-rw-r--r--secure/usr.bin/openssl/man/pkcs8.12
-rw-r--r--secure/usr.bin/openssl/man/rand.12
-rw-r--r--secure/usr.bin/openssl/man/req.12
-rw-r--r--secure/usr.bin/openssl/man/rsa.12
-rw-r--r--secure/usr.bin/openssl/man/rsautl.12
-rw-r--r--secure/usr.bin/openssl/man/s_client.12
-rw-r--r--secure/usr.bin/openssl/man/s_server.12
-rw-r--r--secure/usr.bin/openssl/man/s_time.12
-rw-r--r--secure/usr.bin/openssl/man/sess_id.12
-rw-r--r--secure/usr.bin/openssl/man/smime.12
-rw-r--r--secure/usr.bin/openssl/man/speed.12
-rw-r--r--secure/usr.bin/openssl/man/spkac.12
-rw-r--r--secure/usr.bin/openssl/man/verify.118
-rw-r--r--secure/usr.bin/openssl/man/version.12
-rw-r--r--secure/usr.bin/openssl/man/x509.12
-rw-r--r--secure/usr.bin/openssl/man/x509v3_config.12
-rw-r--r--secure/usr.bin/ssh/Makefile2
-rw-r--r--secure/usr.sbin/sshd/Makefile2
-rw-r--r--share/dict/web21
-rw-r--r--share/examples/Makefile2
-rw-r--r--share/examples/autofs/driver/Makefile6
-rw-r--r--share/examples/indent/indent.pro46
-rw-r--r--share/man/man1/builtin.116
-rw-r--r--share/man/man3/pthread_affinity_np.36
-rw-r--r--share/man/man3/sysexits.32
-rw-r--r--share/man/man3/tgmath.32
-rw-r--r--share/man/man4/Makefile1
-rw-r--r--share/man/man4/acpi.49
-rw-r--r--share/man/man4/acpi_wmi.42
-rw-r--r--share/man/man4/ada.41
-rw-r--r--share/man/man4/ahci.44
-rw-r--r--share/man/man4/altq.45
-rw-r--r--share/man/man4/amdtemp.41
-rw-r--r--share/man/man4/ata.423
-rw-r--r--share/man/man4/ath.411
-rw-r--r--share/man/man4/audit.42
-rw-r--r--share/man/man4/auditpipe.42
-rw-r--r--share/man/man4/cd.42
-rw-r--r--share/man/man4/ch.41
-rw-r--r--share/man/man4/coda.42
-rw-r--r--share/man/man4/cxgb.42
-rw-r--r--share/man/man4/da.41
-rw-r--r--share/man/man4/ddb.42
-rw-r--r--share/man/man4/ehci.47
-rw-r--r--share/man/man4/gbde.42
-rw-r--r--share/man/man4/gem.47
-rw-r--r--share/man/man4/geom.42
-rw-r--r--share/man/man4/geom_fox.42
-rw-r--r--share/man/man4/geom_linux_lvm.42
-rw-r--r--share/man/man4/geom_uzip.42
-rw-r--r--share/man/man4/gre.47
-rw-r--r--share/man/man4/hme.47
-rw-r--r--share/man/man4/ipw.42
-rw-r--r--share/man/man4/iscsi_initiator.44
-rw-r--r--share/man/man4/iwi.42
-rw-r--r--share/man/man4/iwn.42
-rw-r--r--share/man/man4/kbdmux.42
-rw-r--r--share/man/man4/ktr.410
-rw-r--r--share/man/man4/lp.42
-rw-r--r--share/man/man4/mac.42
-rw-r--r--share/man/man4/mac_biba.42
-rw-r--r--share/man/man4/mac_bsdextended.42
-rw-r--r--share/man/man4/mac_ifoff.42
-rw-r--r--share/man/man4/mac_lomac.42
-rw-r--r--share/man/man4/mac_mls.42
-rw-r--r--share/man/man4/mac_none.42
-rw-r--r--share/man/man4/mac_partition.42
-rw-r--r--share/man/man4/mac_seeotheruids.42
-rw-r--r--share/man/man4/mac_stub.42
-rw-r--r--share/man/man4/mac_test.42
-rw-r--r--share/man/man4/man4.sparc64/sbus.47
-rw-r--r--share/man/man4/miibus.45
-rw-r--r--share/man/man4/ndis.46
-rw-r--r--share/man/man4/netintro.49
-rw-r--r--share/man/man4/ng_netflow.42
-rw-r--r--share/man/man4/ohci.421
-rw-r--r--share/man/man4/orm.42
-rw-r--r--share/man/man4/pass.41
-rw-r--r--share/man/man4/pt.42
-rw-r--r--share/man/man4/ral.42
-rw-r--r--share/man/man4/rp.42
-rw-r--r--share/man/man4/rum.42
-rw-r--r--share/man/man4/run.42
-rw-r--r--share/man/man4/sa.44
-rw-r--r--share/man/man4/sched_4bsd.42
-rw-r--r--share/man/man4/sched_ule.42
-rw-r--r--share/man/man4/scsi.479
-rw-r--r--share/man/man4/sge.4120
-rw-r--r--share/man/man4/si.42
-rw-r--r--share/man/man4/siis.44
-rw-r--r--share/man/man4/snd_uaudio.47
-rw-r--r--share/man/man4/splash.412
-rw-r--r--share/man/man4/stge.47
-rw-r--r--share/man/man4/sysmouse.481
-rw-r--r--share/man/man4/tap.42
-rw-r--r--share/man/man4/textdump.42
-rw-r--r--share/man/man4/uart.41
-rw-r--r--share/man/man4/ubsa.47
-rw-r--r--share/man/man4/ucom.47
-rw-r--r--share/man/man4/udbp.421
-rw-r--r--share/man/man4/ufm.418
-rw-r--r--share/man/man4/uftdi.47
-rw-r--r--share/man/man4/ugen.47
-rw-r--r--share/man/man4/uhci.421
-rw-r--r--share/man/man4/uhid.47
-rw-r--r--share/man/man4/uhso.42
-rw-r--r--share/man/man4/ukbd.421
-rw-r--r--share/man/man4/ulpt.47
-rw-r--r--share/man/man4/umass.421
-rw-r--r--share/man/man4/umodem.47
-rw-r--r--share/man/man4/ums.421
-rw-r--r--share/man/man4/upgt.42
-rw-r--r--share/man/man4/uplcom.47
-rw-r--r--share/man/man4/ural.42
-rw-r--r--share/man/man4/urio.428
-rw-r--r--share/man/man4/usb.428
-rw-r--r--share/man/man4/uvisor.47
-rw-r--r--share/man/man4/uvscom.47
-rw-r--r--share/man/man4/vkbd.42
-rw-r--r--share/man/man4/vlan.43
-rw-r--r--share/man/man4/wpi.42
-rw-r--r--share/man/man5/ar.52
-rw-r--r--share/man/man5/core.548
-rw-r--r--share/man/man5/nsswitch.conf.54
-rw-r--r--share/man/man5/rc.conf.5196
-rw-r--r--share/man/man5/services.516
-rw-r--r--share/man/man5/src.conf.59
-rw-r--r--share/man/man7/build.725
-rw-r--r--share/man/man7/clocks.72
-rw-r--r--share/man/man7/maclabel.72
-rw-r--r--share/man/man8/picobsd.82
-rw-r--r--share/man/man8/rescue.82
-rw-r--r--share/man/man9/CTASSERT.92
-rw-r--r--share/man/man9/DELAY.92
-rw-r--r--share/man/man9/KASSERT.92
-rw-r--r--share/man/man9/VFS.92
-rw-r--r--share/man/man9/VFS_CHECKEXP.92
-rw-r--r--share/man/man9/VFS_FHTOVP.92
-rw-r--r--share/man/man9/VFS_MOUNT.92
-rw-r--r--share/man/man9/VFS_QUOTACTL.92
-rw-r--r--share/man/man9/VFS_ROOT.92
-rw-r--r--share/man/man9/VFS_STATFS.92
-rw-r--r--share/man/man9/VFS_SYNC.92
-rw-r--r--share/man/man9/VFS_UNMOUNT.92
-rw-r--r--share/man/man9/VFS_VGET.92
-rw-r--r--share/man/man9/VOP_ACCESS.92
-rw-r--r--share/man/man9/VOP_ACLCHECK.92
-rw-r--r--share/man/man9/VOP_ADVLOCK.92
-rw-r--r--share/man/man9/VOP_ATTRIB.92
-rw-r--r--share/man/man9/VOP_BWRITE.92
-rw-r--r--share/man/man9/VOP_CREATE.92
-rw-r--r--share/man/man9/VOP_FSYNC.92
-rw-r--r--share/man/man9/VOP_GETACL.92
-rw-r--r--share/man/man9/VOP_GETEXTATTR.92
-rw-r--r--share/man/man9/VOP_GETPAGES.92
-rw-r--r--share/man/man9/VOP_GETVOBJECT.92
-rw-r--r--share/man/man9/VOP_INACTIVE.92
-rw-r--r--share/man/man9/VOP_IOCTL.92
-rw-r--r--share/man/man9/VOP_LINK.92
-rw-r--r--share/man/man9/VOP_LISTEXTATTR.92
-rw-r--r--share/man/man9/VOP_LOCK.92
-rw-r--r--share/man/man9/VOP_LOOKUP.92
-rw-r--r--share/man/man9/VOP_OPENCLOSE.92
-rw-r--r--share/man/man9/VOP_PATHCONF.92
-rw-r--r--share/man/man9/VOP_PRINT.92
-rw-r--r--share/man/man9/VOP_RDWR.92
-rw-r--r--share/man/man9/VOP_READDIR.92
-rw-r--r--share/man/man9/VOP_READLINK.92
-rw-r--r--share/man/man9/VOP_REALLOCBLKS.92
-rw-r--r--share/man/man9/VOP_REMOVE.92
-rw-r--r--share/man/man9/VOP_RENAME.92
-rw-r--r--share/man/man9/VOP_REVOKE.92
-rw-r--r--share/man/man9/VOP_SETACL.92
-rw-r--r--share/man/man9/VOP_SETEXTATTR.92
-rw-r--r--share/man/man9/VOP_STRATEGY.92
-rw-r--r--share/man/man9/VOP_VPTOCNP.92
-rw-r--r--share/man/man9/VOP_VPTOFH.92
-rw-r--r--share/man/man9/accept_filter.92
-rw-r--r--share/man/man9/accf_data.92
-rw-r--r--share/man/man9/accf_dns.92
-rw-r--r--share/man/man9/accf_http.92
-rw-r--r--share/man/man9/acl.92
-rw-r--r--share/man/man9/alq.9339
-rw-r--r--share/man/man9/atomic.92
-rw-r--r--share/man/man9/cr_cansee.92
-rw-r--r--share/man/man9/cr_seeothergids.92
-rw-r--r--share/man/man9/cr_seeotheruids.92
-rw-r--r--share/man/man9/devfs_set_cdevpriv.92
-rw-r--r--share/man/man9/devtoname.92
-rw-r--r--share/man/man9/driver.98
-rw-r--r--share/man/man9/extattr.92
-rw-r--r--share/man/man9/fail.95
-rw-r--r--share/man/man9/firmware.92
-rw-r--r--share/man/man9/hexdump.92
-rw-r--r--share/man/man9/ieee80211.919
-rw-r--r--share/man/man9/ieee80211_crypto.93
-rw-r--r--share/man/man9/ieee80211_node.94
-rw-r--r--share/man/man9/ieee80211_output.94
-rw-r--r--share/man/man9/ieee80211_scan.94
-rw-r--r--share/man/man9/ifnet.92
-rw-r--r--share/man/man9/kernacc.97
-rw-r--r--share/man/man9/make_dev.92
-rw-r--r--share/man/man9/malloc.97
-rw-r--r--share/man/man9/mi_switch.97
-rw-r--r--share/man/man9/namei.92
-rw-r--r--share/man/man9/p_candebug.92
-rw-r--r--share/man/man9/p_cansee.92
-rw-r--r--share/man/man9/pfind.92
-rw-r--r--share/man/man9/pgfind.92
-rw-r--r--share/man/man9/physio.97
-rw-r--r--share/man/man9/prison_check.92
-rw-r--r--share/man/man9/psignal.97
-rw-r--r--share/man/man9/random.92
-rw-r--r--share/man/man9/rijndael.92
-rw-r--r--share/man/man9/rtalloc.92
-rw-r--r--share/man/man9/rtentry.92
-rw-r--r--share/man/man9/sleep.92
-rw-r--r--share/man/man9/spl.92
-rw-r--r--share/man/man9/stack.92
-rw-r--r--share/man/man9/timeout.97
-rw-r--r--share/man/man9/uio.96
-rw-r--r--share/man/man9/usbdi.92
-rw-r--r--share/man/man9/vaccess.92
-rw-r--r--share/man/man9/vaccess_acl_nfs4.92
-rw-r--r--share/man/man9/vaccess_acl_posix1e.92
-rw-r--r--share/man/man9/vcount.92
-rw-r--r--share/man/man9/vfs_mount.93
-rw-r--r--share/man/man9/vget.92
-rw-r--r--share/man/man9/vm_map_entry_resize_free.92
-rw-r--r--share/man/man9/vnode.92
-rw-r--r--share/man/man9/vput.92
-rw-r--r--share/man/man9/vref.92
-rw-r--r--share/man/man9/vrefcnt.92
-rw-r--r--share/man/man9/vrele.92
-rw-r--r--share/man/man9/vslock.97
-rw-r--r--share/misc/bsd-family-tree17
-rw-r--r--share/misc/committers-ports.dot16
-rw-r--r--share/misc/committers-src.dot8
-rw-r--r--share/misc/pci_vendors2072
-rw-r--r--share/mk/bsd.cpu.mk2
-rw-r--r--share/mk/bsd.lib.mk53
-rw-r--r--share/mk/bsd.libnames.mk1
-rw-r--r--share/mk/bsd.own.mk1
-rw-r--r--share/mk/bsd.port.mk5
-rw-r--r--share/mk/bsd.prog.mk13
-rw-r--r--share/mk/sys.mk82
-rw-r--r--sys/amd64/acpica/acpi_machdep.c2
-rw-r--r--sys/amd64/amd64/apic_vector.S12
-rw-r--r--sys/amd64/amd64/bpf_jit_machdep.c35
-rw-r--r--sys/amd64/amd64/bpf_jit_machdep.h6
-rw-r--r--sys/amd64/amd64/db_trace.c2
-rw-r--r--sys/amd64/amd64/exception.S31
-rw-r--r--sys/amd64/amd64/identcpu.c4
-rw-r--r--sys/amd64/amd64/local_apic.c81
-rw-r--r--sys/amd64/amd64/machdep.c25
-rw-r--r--sys/amd64/amd64/mca.c87
-rw-r--r--sys/amd64/amd64/pmap.c320
-rw-r--r--sys/amd64/amd64/trap.c10
-rw-r--r--sys/amd64/amd64/vm_machdep.c4
-rw-r--r--sys/amd64/conf/GENERIC5
-rw-r--r--sys/amd64/conf/NOTES4
-rw-r--r--sys/amd64/conf/XENHVM3
-rw-r--r--sys/amd64/ia32/ia32_signal.c25
-rw-r--r--sys/amd64/include/_inttypes.h7
-rw-r--r--sys/amd64/include/apicvar.h7
-rw-r--r--sys/amd64/include/elf.h1
-rw-r--r--sys/amd64/include/mca.h5
-rw-r--r--sys/amd64/include/md_var.h5
-rw-r--r--sys/amd64/include/pmc_mdep.h11
-rw-r--r--sys/amd64/include/proc.h3
-rw-r--r--sys/amd64/include/reg.h11
-rw-r--r--sys/amd64/include/specialreg.h57
-rw-r--r--sys/amd64/linux32/linux.h18
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c18
-rw-r--r--sys/arm/arm/busdma_machdep.c3
-rw-r--r--sys/arm/arm/identcpu.c2
-rw-r--r--sys/arm/arm/machdep.c6
-rw-r--r--sys/arm/arm/pmap.c22
-rw-r--r--sys/arm/arm/vm_machdep.c8
-rw-r--r--sys/arm/conf/BWCT.hints2
-rw-r--r--sys/arm/conf/DB-78XXX1
-rw-r--r--sys/arm/conf/DB-88F5XXX1
-rw-r--r--sys/arm/conf/DB-88F6XXX1
-rw-r--r--sys/arm/conf/HL2001
-rw-r--r--sys/arm/conf/KB920X3
-rw-r--r--sys/arm/conf/LN2410SBC88
-rw-r--r--sys/arm/conf/SHEEVAPLUG1
-rw-r--r--sys/arm/include/bus.h2
-rw-r--r--sys/arm/include/proc.h2
-rw-r--r--sys/arm/mv/common.c2
-rw-r--r--sys/arm/mv/kirkwood/kirkwood.c4
-rw-r--r--sys/arm/mv/mv_sata.c5
-rw-r--r--sys/arm/s3c2xx0/board_ln2410sbc.c (renamed from sys/ia64/include/nexusvar.h)28
-rw-r--r--sys/arm/s3c2xx0/files.s3c2xx013
-rw-r--r--sys/arm/s3c2xx0/s3c2410reg.h96
-rw-r--r--sys/arm/s3c2xx0/s3c2410var.h49
-rw-r--r--sys/arm/s3c2xx0/s3c2440reg.h109
-rw-r--r--sys/arm/s3c2xx0/s3c24x0.c648
-rw-r--r--sys/arm/s3c2xx0/s3c24x0_clk.c287
-rw-r--r--sys/arm/s3c2xx0/s3c24x0_machdep.c467
-rw-r--r--sys/arm/s3c2xx0/s3c24x0reg.h672
-rw-r--r--sys/arm/s3c2xx0/s3c24x0var.h51
-rw-r--r--sys/arm/s3c2xx0/s3c2xx0_space.c252
-rw-r--r--sys/arm/s3c2xx0/s3c2xx0board.h (renamed from sys/mips/include/segments.h)30
-rw-r--r--sys/arm/s3c2xx0/s3c2xx0reg.h139
-rw-r--r--sys/arm/s3c2xx0/s3c2xx0var.h89
-rw-r--r--sys/arm/s3c2xx0/std.ln2410sbc10
-rw-r--r--sys/arm/s3c2xx0/std.s3c24106
-rw-r--r--sys/arm/s3c2xx0/uart_bus_s3c2410.c59
-rw-r--r--sys/arm/s3c2xx0/uart_cpu_s3c2410.c78
-rw-r--r--sys/arm/s3c2xx0/uart_dev_s3c2410.c383
-rw-r--r--sys/arm/s3c2xx0/uart_dev_s3c2410.h88
-rw-r--r--sys/arm/xscale/ixp425/cambria_fled.c2
-rw-r--r--sys/boot/arm/at91/boot2/bwct_board.c8
-rw-r--r--sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c2
-rw-r--r--sys/boot/forth/loader.conf1
-rw-r--r--sys/boot/i386/boot2/boot2.c2
-rw-r--r--sys/boot/i386/efi/Makefile69
-rw-r--r--sys/boot/i386/efi/autoload.c (renamed from crypto/openssh/scard.h)26
-rw-r--r--sys/boot/i386/efi/bootinfo.c297
-rw-r--r--sys/boot/i386/efi/conf.c77
-rw-r--r--sys/boot/i386/efi/devicename.c169
-rw-r--r--sys/boot/i386/efi/efimd.c139
-rw-r--r--sys/boot/i386/efi/elf32_freebsd.c87
-rw-r--r--sys/boot/i386/efi/exec.c59
-rw-r--r--sys/boot/i386/efi/i386_copy.c59
-rw-r--r--sys/boot/i386/efi/ldscript.amd6475
-rw-r--r--sys/boot/i386/efi/ldscript.i38672
-rw-r--r--sys/boot/i386/efi/main.c371
-rw-r--r--sys/boot/i386/efi/reloc.c103
-rw-r--r--sys/boot/i386/efi/start.S (renamed from sys/mips/include/psl.h)66
-rw-r--r--sys/boot/i386/efi/version7
-rw-r--r--sys/boot/i386/gptboot/gptboot.c2
-rw-r--r--sys/boot/i386/zfsboot/zfsboot.c2
-rw-r--r--sys/cam/ata/ata_da.c4
-rw-r--r--sys/cam/ata/ata_xpt.c29
-rw-r--r--sys/cam/cam_xpt.c7
-rw-r--r--sys/cam/scsi/scsi_all.h2
-rw-r--r--sys/cam/scsi/scsi_cd.c9
-rw-r--r--sys/cam/scsi/scsi_da.c5
-rw-r--r--sys/cam/scsi/scsi_sg.c2
-rw-r--r--sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c17
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c507
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c28
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c30
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c13
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c11
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c10
-rw-r--r--sys/cddl/dev/cyclic/amd64/cyclic_machdep.c133
-rw-r--r--sys/cddl/dev/cyclic/i386/cyclic_machdep.c6
-rw-r--r--sys/compat/freebsd32/freebsd32.h122
-rw-r--r--sys/compat/freebsd32/freebsd32_ipc.h8
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c864
-rw-r--r--sys/compat/freebsd32/freebsd32_proto.h254
-rw-r--r--sys/compat/freebsd32/freebsd32_syscall.h25
-rw-r--r--sys/compat/freebsd32/freebsd32_syscalls.c50
-rw-r--r--sys/compat/freebsd32/freebsd32_sysent.c84
-rw-r--r--sys/compat/freebsd32/freebsd32_util.h21
-rw-r--r--sys/compat/freebsd32/syscalls.master180
-rw-r--r--sys/compat/ia32/ia32_reg.h23
-rw-r--r--sys/compat/ia32/ia32_signal.h5
-rw-r--r--sys/compat/ia32/ia32_sysvec.c124
-rw-r--r--sys/compat/linprocfs/linprocfs.c76
-rw-r--r--sys/compat/linux/linux_file.c8
-rw-r--r--sys/compat/linux/linux_ioctl.c4
-rw-r--r--sys/compat/linux/linux_stats.c27
-rw-r--r--sys/compat/svr4/svr4_stat.c18
-rw-r--r--sys/compat/x86bios/x86bios.c152
-rw-r--r--sys/conf/NOTES18
-rw-r--r--sys/conf/files28
-rw-r--r--sys/conf/files.amd6425
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/conf/files.ia6420
-rw-r--r--sys/conf/files.mips4
-rw-r--r--sys/conf/files.pc981
-rw-r--r--sys/conf/files.sparc647
-rw-r--r--sys/conf/files.sun4v4
-rw-r--r--sys/conf/kern.mk8
-rw-r--r--sys/conf/kern.post.mk16
-rw-r--r--sys/conf/kern.pre.mk12
-rw-r--r--sys/conf/kmod.mk13
-rw-r--r--sys/conf/ldscript.mips.octeon1.3210
-rw-r--r--sys/conf/ldscript.mips.octeon1.6415
-rw-r--r--sys/conf/ldscript.mips.octeon1.n323
-rw-r--r--sys/conf/options1
-rw-r--r--sys/conf/options.amd642
-rw-r--r--sys/conf/options.i3861
-rw-r--r--sys/conf/options.ia642
-rw-r--r--sys/contrib/dev/acpica/changes.txt128
-rw-r--r--sys/contrib/dev/acpica/common/dmextern.c11
-rw-r--r--sys/contrib/dev/acpica/common/dmtable.c3
-rw-r--r--sys/contrib/dev/acpica/common/dmtbdump.c14
-rw-r--r--sys/contrib/dev/acpica/common/dmtbinfo.c25
-rw-r--r--sys/contrib/dev/acpica/compiler/aslanalyze.c289
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.h26
-rw-r--r--sys/contrib/dev/acpica/compiler/aslglobal.h1
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmain.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmap.c317
-rw-r--r--sys/contrib/dev/acpica/compiler/aslpredef.c799
-rw-r--r--sys/contrib/dev/acpica/compiler/aslstubs.c11
-rw-r--r--sys/contrib/dev/acpica/compiler/asltypes.h17
-rw-r--r--sys/contrib/dev/acpica/debugger/dbdisply.c59
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dsfield.c2
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dsmethod.c2
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dsmthdat.c10
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dsobject.c14
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dsopcode.c12
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dswexec.c6
-rw-r--r--sys/contrib/dev/acpica/dispatcher/dswstate.c10
-rw-r--r--sys/contrib/dev/acpica/events/evevent.c2
-rw-r--r--sys/contrib/dev/acpica/events/evgpe.c291
-rw-r--r--sys/contrib/dev/acpica/events/evgpeblk.c200
-rw-r--r--sys/contrib/dev/acpica/events/evmisc.c2
-rw-r--r--sys/contrib/dev/acpica/events/evxface.c6
-rw-r--r--sys/contrib/dev/acpica/events/evxfevnt.c282
-rw-r--r--sys/contrib/dev/acpica/executer/exconvrt.c4
-rw-r--r--sys/contrib/dev/acpica/executer/excreate.c4
-rw-r--r--sys/contrib/dev/acpica/executer/exdebug.c350
-rw-r--r--sys/contrib/dev/acpica/executer/exfield.c2
-rw-r--r--sys/contrib/dev/acpica/executer/exfldio.c16
-rw-r--r--sys/contrib/dev/acpica/executer/exmisc.c8
-rw-r--r--sys/contrib/dev/acpica/executer/exmutex.c51
-rw-r--r--sys/contrib/dev/acpica/executer/exnames.c4
-rw-r--r--sys/contrib/dev/acpica/executer/exoparg1.c16
-rw-r--r--sys/contrib/dev/acpica/executer/exoparg2.c37
-rw-r--r--sys/contrib/dev/acpica/executer/exoparg3.c4
-rw-r--r--sys/contrib/dev/acpica/executer/exoparg6.c4
-rw-r--r--sys/contrib/dev/acpica/executer/exprep.c4
-rw-r--r--sys/contrib/dev/acpica/executer/exregion.c17
-rw-r--r--sys/contrib/dev/acpica/executer/exresnte.c4
-rw-r--r--sys/contrib/dev/acpica/executer/exresolv.c8
-rw-r--r--sys/contrib/dev/acpica/executer/exresop.c8
-rw-r--r--sys/contrib/dev/acpica/executer/exstore.c223
-rw-r--r--sys/contrib/dev/acpica/executer/exsystem.c2
-rw-r--r--sys/contrib/dev/acpica/hardware/hwregs.c6
-rw-r--r--sys/contrib/dev/acpica/hardware/hwsleep.c17
-rw-r--r--sys/contrib/dev/acpica/hardware/hwvalid.c2
-rw-r--r--sys/contrib/dev/acpica/include/acdisasm.h1
-rw-r--r--sys/contrib/dev/acpica/include/acevents.h20
-rw-r--r--sys/contrib/dev/acpica/include/acexcep.h2
-rw-r--r--sys/contrib/dev/acpica/include/acglobal.h18
-rw-r--r--sys/contrib/dev/acpica/include/acinterp.h10
-rw-r--r--sys/contrib/dev/acpica/include/aclocal.h3
-rw-r--r--sys/contrib/dev/acpica/include/acoutput.h2
-rw-r--r--sys/contrib/dev/acpica/include/acpixf.h16
-rw-r--r--sys/contrib/dev/acpica/include/actables.h8
-rw-r--r--sys/contrib/dev/acpica/include/actbl2.h30
-rw-r--r--sys/contrib/dev/acpica/include/actypes.h51
-rw-r--r--sys/contrib/dev/acpica/include/platform/acfreebsd.h30
-rw-r--r--sys/contrib/dev/acpica/namespace/nsaccess.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nsdump.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nsnames.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nssearch.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nsutils.c4
-rw-r--r--sys/contrib/dev/acpica/parser/psargs.c4
-rw-r--r--sys/contrib/dev/acpica/parser/psloop.c3
-rw-r--r--sys/contrib/dev/acpica/parser/psxface.c5
-rw-r--r--sys/contrib/dev/acpica/resources/rscreate.c14
-rw-r--r--sys/contrib/dev/acpica/resources/rslist.c6
-rw-r--r--sys/contrib/dev/acpica/resources/rsmisc.c4
-rw-r--r--sys/contrib/dev/acpica/tables/tbfadt.c16
-rw-r--r--sys/contrib/dev/acpica/tables/tbutils.c86
-rw-r--r--sys/contrib/dev/acpica/tables/tbxface.c62
-rw-r--r--sys/contrib/dev/acpica/tables/tbxfroot.c6
-rw-r--r--sys/contrib/dev/acpica/utilities/utalloc.c2
-rw-r--r--sys/contrib/dev/acpica/utilities/utdelete.c4
-rw-r--r--sys/contrib/dev/acpica/utilities/uteval.c2
-rw-r--r--sys/contrib/dev/acpica/utilities/utglobal.c1
-rw-r--r--sys/contrib/dev/acpica/utilities/utmisc.c6
-rw-r--r--sys/contrib/dev/acpica/utilities/utmutex.c4
-rw-r--r--sys/contrib/dev/acpica/utilities/utobject.c8
-rw-r--r--sys/contrib/dev/acpica/utilities/uttrack.c4
-rw-r--r--sys/contrib/dev/iwn/LICENSE60
-rw-r--r--sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu8112
-rw-r--r--sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu8152
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h1
-rw-r--r--sys/contrib/x86emu/x86emu.c348
-rw-r--r--sys/ddb/db_sym.c6
-rw-r--r--sys/dev/aac/aac.c142
-rw-r--r--sys/dev/aac/aac_cam.c4
-rw-r--r--sys/dev/aac/aac_debug.c72
-rw-r--r--sys/dev/aac/aac_disk.c2
-rw-r--r--sys/dev/aac/aac_pci.c8
-rw-r--r--sys/dev/aac/aac_tables.h70
-rw-r--r--sys/dev/aac/aacreg.h104
-rw-r--r--sys/dev/aac/aacvar.h20
-rw-r--r--sys/dev/acpica/acpi.c76
-rw-r--r--sys/dev/acpica/acpi_button.c1
-rw-r--r--sys/dev/acpica/acpi_ec.c12
-rw-r--r--sys/dev/acpica/acpi_lid.c1
-rw-r--r--sys/dev/acpica/acpi_video.c4
-rw-r--r--sys/dev/acpica/acpivar.h1
-rw-r--r--sys/dev/age/if_age.c28
-rw-r--r--sys/dev/agp/agp_i810.c28
-rw-r--r--sys/dev/ahci/ahci.c21
-rw-r--r--sys/dev/alc/if_alc.c44
-rw-r--r--sys/dev/ale/if_ale.c19
-rw-r--r--sys/dev/ata/ata-all.h2
-rw-r--r--sys/dev/ata/ata-queue.c2
-rw-r--r--sys/dev/ata/ata-raid.c32
-rw-r--r--sys/dev/ata/chipsets/ata-acerlabs.c5
-rw-r--r--sys/dev/ath/ath_hal/ah_debug.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_decode.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_devid.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v1.c2
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v1.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v3.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_internal.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_soc.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_power.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_recv.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210desc.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210phy.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210reg.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5k_0007.ini2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_power.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_recv.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211desc.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211phy.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211reg.h2
-rwxr-xr-xsys/dev/ath/ath_hal/ar5211/boss.ini2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212.ini2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_eeprom.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212desc.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212phy.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5311reg.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_misc.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_power.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312phy.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312reg.h2
-rw-r--r--[-rwxr-xr-x]sys/dev/ath/ath_hal/ar5416/ar9160.ini0
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar9285_attach.c4
-rw-r--r--sys/dev/ath/if_ath.c10
-rw-r--r--sys/dev/bce/if_bce.c4597
-rw-r--r--sys/dev/bce/if_bcefw.h2
-rw-r--r--sys/dev/bce/if_bcereg.h1753
-rw-r--r--sys/dev/bge/if_bge.c74
-rw-r--r--sys/dev/bktr/ioctl_bt848.h14
-rw-r--r--sys/dev/bktr/ioctl_meteor.h26
-rw-r--r--sys/dev/bwi/if_bwi.c44
-rw-r--r--sys/dev/bwi/if_bwivar.h7
-rw-r--r--sys/dev/bwn/if_bwn.c823
-rw-r--r--sys/dev/bwn/if_bwnvar.h25
-rw-r--r--sys/dev/ciss/ciss.c13
-rw-r--r--sys/dev/ciss/cissvar.h3
-rw-r--r--sys/dev/cxgb/common/cxgb_ael1002.c807
-rw-r--r--sys/dev/cxgb/common/cxgb_common.h1
-rw-r--r--sys/dev/cxgb/common/cxgb_t3_hw.c4
-rw-r--r--sys/dev/cxgb/cxgb_adapter.h6
-rw-r--r--sys/dev/cxgb/cxgb_main.c97
-rw-r--r--sys/dev/cxgb/cxgb_sge.c139
-rw-r--r--sys/dev/drm/ati_pcigart.c11
-rw-r--r--sys/dev/drm/drmP.h56
-rw-r--r--sys/dev/drm/drm_bufs.c39
-rw-r--r--sys/dev/drm/drm_context.c2
-rw-r--r--sys/dev/drm/drm_drv.c7
-rw-r--r--sys/dev/drm/drm_hashtab.c3
-rw-r--r--sys/dev/drm/drm_memory.c2
-rw-r--r--sys/dev/drm/drm_mm.c3
-rw-r--r--sys/dev/drm/drm_pciids.h4
-rw-r--r--sys/dev/drm/drm_scatter.c118
-rw-r--r--sys/dev/drm/drm_sman.c10
-rw-r--r--sys/dev/drm/drm_sysctl.c10
-rw-r--r--sys/dev/drm/drm_vm.c43
-rw-r--r--sys/dev/drm/i915_dma.c14
-rw-r--r--sys/dev/drm/i915_drv.h10
-rw-r--r--sys/dev/drm/i915_reg.h4
-rw-r--r--sys/dev/drm/mach64_dma.c8
-rw-r--r--sys/dev/drm/mga_dma.c22
-rw-r--r--sys/dev/drm/mga_warp.c4
-rw-r--r--sys/dev/drm/r128_cce.c24
-rw-r--r--sys/dev/drm/r128_state.c4
-rw-r--r--sys/dev/drm/r600_blit.c17
-rw-r--r--sys/dev/drm/r600_cp.c57
-rw-r--r--sys/dev/drm/radeon_cp.c51
-rw-r--r--sys/dev/drm/radeon_cs.c2
-rw-r--r--sys/dev/drm/radeon_state.c8
-rw-r--r--sys/dev/drm/savage_bci.c28
-rw-r--r--sys/dev/drm/via_dma.c13
-rw-r--r--sys/dev/drm/via_map.c2
-rw-r--r--sys/dev/drm/via_mm.c2
-rw-r--r--sys/dev/e1000/e1000_80003es2lan.c4
-rw-r--r--sys/dev/e1000/e1000_82571.c22
-rw-r--r--sys/dev/e1000/e1000_82575.c28
-rw-r--r--sys/dev/e1000/e1000_82575.h5
-rw-r--r--sys/dev/e1000/e1000_defines.h15
-rw-r--r--sys/dev/e1000/e1000_hw.h2
-rw-r--r--sys/dev/e1000/e1000_ich8lan.c49
-rw-r--r--sys/dev/e1000/e1000_ich8lan.h4
-rw-r--r--sys/dev/e1000/e1000_mac.c19
-rw-r--r--sys/dev/e1000/e1000_manage.c25
-rw-r--r--sys/dev/e1000/e1000_phy.c21
-rw-r--r--sys/dev/e1000/e1000_regs.h14
-rw-r--r--sys/dev/e1000/if_em.c3189
-rw-r--r--sys/dev/e1000/if_em.h235
-rw-r--r--sys/dev/e1000/if_igb.c573
-rw-r--r--sys/dev/e1000/if_igb.h21
-rw-r--r--sys/dev/e1000/if_lem.c4552
-rw-r--r--sys/dev/e1000/if_lem.h481
-rw-r--r--sys/dev/fb/vesa.c143
-rw-r--r--sys/dev/fb/vga.c24
-rw-r--r--sys/dev/firewire/sbp.c2
-rw-r--r--sys/dev/fxp/if_fxp.c106
-rw-r--r--sys/dev/hme/if_hme_sbus.c7
-rw-r--r--sys/dev/hme/if_hmereg.h7
-rw-r--r--sys/dev/hme/if_hmevar.h7
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c1047
-rw-r--r--sys/dev/hwpmc/hwpmc_core.h15
-rw-r--r--sys/dev/hwpmc/hwpmc_intel.c41
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c46
-rw-r--r--sys/dev/hwpmc/hwpmc_mips.c75
-rw-r--r--sys/dev/hwpmc/hwpmc_mips24k.c570
-rw-r--r--sys/dev/hwpmc/hwpmc_mips24k.h61
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c8
-rw-r--r--sys/dev/hwpmc/hwpmc_uncore.c1121
-rw-r--r--sys/dev/hwpmc/hwpmc_uncore.h120
-rw-r--r--sys/dev/hwpmc/pmc_events.h2202
-rw-r--r--sys/dev/ipw/if_ipw.c55
-rw-r--r--sys/dev/ipw/if_ipwvar.h11
-rw-r--r--sys/dev/isp/isp.c221
-rw-r--r--sys/dev/isp/isp_freebsd.c37
-rw-r--r--sys/dev/isp/isp_freebsd.h15
-rw-r--r--sys/dev/isp/isp_library.c4
-rw-r--r--sys/dev/isp/isp_pci.c6
-rw-r--r--sys/dev/isp/isp_sbus.c2
-rw-r--r--sys/dev/isp/ispvar.h10
-rw-r--r--sys/dev/ispfw/ispfw.c15
-rw-r--r--sys/dev/iwn/if_iwn.c572
-rw-r--r--sys/dev/iwn/if_iwnreg.h36
-rw-r--r--sys/dev/iwn/if_iwnvar.h6
-rw-r--r--sys/dev/ixgbe/LICENSE2
-rw-r--r--sys/dev/ixgbe/ixgbe.c1530
-rw-r--r--sys/dev/ixgbe/ixgbe.h172
-rw-r--r--sys/dev/ixgbe/ixgbe_82598.c84
-rw-r--r--sys/dev/ixgbe/ixgbe_82599.c158
-rw-r--r--sys/dev/ixgbe/ixgbe_api.c17
-rw-r--r--sys/dev/ixgbe/ixgbe_api.h4
-rw-r--r--sys/dev/ixgbe/ixgbe_common.c157
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.c132
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.h10
-rw-r--r--sys/dev/ixgbe/ixgbe_type.h80
-rw-r--r--sys/dev/le/am79900var.h7
-rw-r--r--sys/dev/le/am7990var.h7
-rw-r--r--sys/dev/le/if_le_ledma.c7
-rw-r--r--sys/dev/le/lancevar.h7
-rw-r--r--sys/dev/malo/if_malo.c4
-rw-r--r--sys/dev/mfi/mfi_cam.c1
-rw-r--r--sys/dev/mfi/mfi_pci.c1
-rw-r--r--sys/dev/mii/bmtphyreg.h7
-rw-r--r--sys/dev/mii/brgphy.c163
-rw-r--r--sys/dev/mii/brgphyreg.h55
-rw-r--r--sys/dev/mii/e1000phy.c1
-rw-r--r--sys/dev/mii/icsphyreg.h7
-rw-r--r--sys/dev/mii/lxtphyreg.h7
-rw-r--r--sys/dev/mii/mii.c24
-rw-r--r--sys/dev/mii/mii_physubr.c7
-rw-r--r--sys/dev/mii/miidevs9
-rw-r--r--sys/dev/mii/miivar.h7
-rw-r--r--sys/dev/mii/nsphyreg.h7
-rw-r--r--sys/dev/mii/nsphyterreg.h7
-rw-r--r--sys/dev/mii/qsphyreg.h7
-rw-r--r--sys/dev/mii/truephy.c6
-rw-r--r--sys/dev/mii/ukphy_subr.c7
-rw-r--r--sys/dev/mpt/mpt_cam.c4
-rw-r--r--sys/dev/msk/if_msk.c323
-rw-r--r--sys/dev/msk/if_mskreg.h1
-rw-r--r--sys/dev/mxge/if_mxge.c123
-rw-r--r--sys/dev/mxge/if_mxge_var.h8
-rw-r--r--sys/dev/nfe/if_nfe.c13
-rw-r--r--sys/dev/ofw/ofw_standard.c54
-rw-r--r--sys/dev/pci/vga_pci.c3
-rw-r--r--sys/dev/ppc/ppc_pci.c1
-rw-r--r--sys/dev/ral/rt2560.c56
-rw-r--r--sys/dev/ral/rt2560var.h7
-rw-r--r--sys/dev/ral/rt2661.c49
-rw-r--r--sys/dev/ral/rt2661var.h7
-rw-r--r--sys/dev/re/if_re.c14
-rw-r--r--sys/dev/sge/if_sge.c1748
-rw-r--r--sys/dev/sge/if_sgereg.h350
-rw-r--r--sys/dev/siba/siba.c2
-rw-r--r--sys/dev/siba/siba_bwn.c81
-rw-r--r--sys/dev/siba/siba_cc.c2
-rw-r--r--sys/dev/siba/siba_core.c714
-rw-r--r--sys/dev/siba/siba_pcib.c2
-rw-r--r--sys/dev/siba/sibavar.h246
-rw-r--r--sys/dev/siis/siis.c14
-rw-r--r--sys/dev/sis/if_sis.c15
-rw-r--r--sys/dev/sound/pci/envy24.c2
-rw-r--r--sys/dev/sound/pci/envy24.h2
-rw-r--r--sys/dev/sound/pci/envy24ht.c2
-rw-r--r--sys/dev/sound/pci/envy24ht.h2
-rw-r--r--sys/dev/sound/pci/es137x.c4
-rw-r--r--sys/dev/sound/pci/es137x.h12
-rw-r--r--sys/dev/sound/pci/hda/hdac.c16
-rw-r--r--sys/dev/sound/pci/spicds.c2
-rw-r--r--sys/dev/sound/pci/spicds.h2
-rw-r--r--sys/dev/sound/pcm/dsp.c1
-rw-r--r--sys/dev/sound/usb/uaudio.c22
-rw-r--r--sys/dev/syscons/logo/beastie.c358
-rw-r--r--sys/dev/syscons/logo/logo.c1183
-rw-r--r--sys/dev/syscons/logo/logo_saver.c4
-rw-r--r--sys/dev/syscons/scvgarndr.c10
-rw-r--r--sys/dev/syscons/scvidctl.c4
-rw-r--r--sys/dev/syscons/syscons.c4
-rw-r--r--sys/dev/uart/uart.h1
-rw-r--r--sys/dev/uart/uart_cpu_sparc64.c11
-rw-r--r--sys/dev/ubsec/ubsec.c4
-rw-r--r--sys/dev/usb/controller/ehci.c38
-rw-r--r--sys/dev/usb/controller/ehci.h7
-rw-r--r--sys/dev/usb/controller/ehci_pci.c9
-rw-r--r--sys/dev/usb/controller/ehcireg.h7
-rw-r--r--sys/dev/usb/controller/ohci.h7
-rw-r--r--sys/dev/usb/controller/ohci_pci.c9
-rw-r--r--sys/dev/usb/controller/ohci_s3c24x0.c219
-rw-r--r--sys/dev/usb/controller/ohcireg.h7
-rw-r--r--sys/dev/usb/controller/uhci.c34
-rw-r--r--sys/dev/usb/controller/uhci.h7
-rw-r--r--sys/dev/usb/controller/uhci_pci.c7
-rw-r--r--sys/dev/usb/controller/uhcireg.h7
-rw-r--r--sys/dev/usb/controller/usb_controller.c6
-rw-r--r--sys/dev/usb/controller/uss820dci.c10
-rw-r--r--sys/dev/usb/input/atp.c12
-rw-r--r--sys/dev/usb/input/uhid.c9
-rw-r--r--sys/dev/usb/input/ukbd.c47
-rw-r--r--sys/dev/usb/input/ums.c13
-rw-r--r--sys/dev/usb/misc/udbp.c2
-rw-r--r--sys/dev/usb/net/if_aue.c2
-rw-r--r--sys/dev/usb/net/if_axe.c2
-rw-r--r--sys/dev/usb/net/if_cdce.c2
-rw-r--r--sys/dev/usb/net/if_cue.c2
-rw-r--r--sys/dev/usb/net/if_kue.c2
-rw-r--r--sys/dev/usb/net/if_rue.c2
-rw-r--r--sys/dev/usb/net/if_udav.c2
-rw-r--r--sys/dev/usb/quirk/usb_quirk.c4
-rw-r--r--sys/dev/usb/serial/u3g.c3
-rw-r--r--sys/dev/usb/serial/ubsa.c5
-rw-r--r--sys/dev/usb/serial/ubser.c2
-rw-r--r--sys/dev/usb/serial/uchcom.c2
-rw-r--r--sys/dev/usb/serial/uftdi.c13
-rw-r--r--sys/dev/usb/serial/ugensa.c7
-rw-r--r--sys/dev/usb/serial/uipaq.c7
-rw-r--r--sys/dev/usb/serial/ulpt.c9
-rw-r--r--sys/dev/usb/serial/umodem.c2
-rw-r--r--sys/dev/usb/serial/umoscom.c2
-rw-r--r--sys/dev/usb/serial/uplcom.c2
-rw-r--r--sys/dev/usb/serial/usb_serial.c2
-rw-r--r--sys/dev/usb/serial/uslcom.c2
-rw-r--r--sys/dev/usb/serial/uvisor.c17
-rw-r--r--sys/dev/usb/serial/uvscom.c2
-rw-r--r--sys/dev/usb/storage/umass.c8
-rw-r--r--sys/dev/usb/storage/urio.c2
-rw-r--r--sys/dev/usb/storage/ustorage_fs.c2
-rw-r--r--sys/dev/usb/template/usb_template.c54
-rw-r--r--sys/dev/usb/template/usb_template.h5
-rw-r--r--sys/dev/usb/template/usb_template_mtp.c2
-rw-r--r--sys/dev/usb/usb_cdc.h7
-rw-r--r--sys/dev/usb/usb_compat_linux.c5
-rw-r--r--sys/dev/usb/usb_debug.h2
-rw-r--r--sys/dev/usb/usb_dev.c10
-rw-r--r--sys/dev/usb/usb_device.c187
-rw-r--r--sys/dev/usb/usb_device.h19
-rw-r--r--sys/dev/usb/usb_freebsd.h4
-rw-r--r--sys/dev/usb/usb_generic.c43
-rw-r--r--sys/dev/usb/usb_hid.c7
-rw-r--r--sys/dev/usb/usb_hub.c2
-rw-r--r--sys/dev/usb/usb_request.c24
-rw-r--r--sys/dev/usb/usb_transfer.c50
-rw-r--r--sys/dev/usb/usb_transfer.h2
-rw-r--r--sys/dev/usb/usbdevs74
-rw-r--r--sys/dev/usb/wlan/if_rum.c78
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h11
-rw-r--r--sys/dev/usb/wlan/if_run.c675
-rw-r--r--sys/dev/usb/wlan/if_runreg.h127
-rw-r--r--sys/dev/usb/wlan/if_runvar.h32
-rw-r--r--sys/dev/usb/wlan/if_ural.c77
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h11
-rw-r--r--sys/dev/usb/wlan/if_zyd.c52
-rw-r--r--sys/dev/usb/wlan/if_zydreg.h7
-rw-r--r--sys/dev/wpi/if_wpi.c45
-rw-r--r--sys/dev/wpi/if_wpivar.h7
-rw-r--r--sys/dev/xen/netback/netback.c2
-rw-r--r--sys/fs/coda/cnode.h5
-rw-r--r--sys/fs/coda/coda.h132
-rw-r--r--sys/fs/coda/coda_subr.c2
-rw-r--r--sys/fs/coda/coda_subr.h2
-rw-r--r--sys/fs/coda/coda_venus.c60
-rw-r--r--sys/fs/coda/coda_venus.h65
-rw-r--r--sys/fs/coda/coda_vfsops.c12
-rw-r--r--sys/fs/coda/coda_vfsops.h2
-rw-r--r--sys/fs/coda/coda_vnops.c8
-rw-r--r--sys/fs/deadfs/dead_vnops.c10
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c29
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c9
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c6
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c2
-rw-r--r--sys/fs/nfs/nfs_commonport.c26
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c13
-rw-r--r--sys/fs/nfs/nfs_var.h7
-rw-r--r--sys/fs/nfs/nfsclstate.h2
-rw-r--r--sys/fs/nfs/nfsport.h11
-rw-r--r--sys/fs/nfs/nfsrvstate.h15
-rw-r--r--sys/fs/nfsclient/nfs.h6
-rw-r--r--sys/fs/nfsclient/nfs_clbio.c31
-rw-r--r--sys/fs/nfsclient/nfs_clnfsiod.c6
-rw-r--r--sys/fs/nfsclient/nfs_clnode.c2
-rw-r--r--sys/fs/nfsclient/nfs_clport.c2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c50
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c108
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c6
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c40
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c50
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c30
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c766
-rw-r--r--sys/fs/nwfs/nwfs.h8
-rw-r--r--sys/fs/nwfs/nwfs_io.c8
-rw-r--r--sys/fs/nwfs/nwfs_ioctl.c8
-rw-r--r--sys/fs/nwfs/nwfs_mount.h8
-rw-r--r--sys/fs/nwfs/nwfs_node.c6
-rw-r--r--sys/fs/nwfs/nwfs_node.h6
-rw-r--r--sys/fs/nwfs/nwfs_subr.c6
-rw-r--r--sys/fs/nwfs/nwfs_subr.h8
-rw-r--r--sys/fs/nwfs/nwfs_vfsops.c6
-rw-r--r--sys/fs/nwfs/nwfs_vnops.c6
-rw-r--r--sys/fs/procfs/procfs_dbregs.c7
-rw-r--r--sys/fs/procfs/procfs_fpregs.c7
-rw-r--r--sys/fs/procfs/procfs_ioctl.c6
-rw-r--r--sys/fs/procfs/procfs_map.c8
-rw-r--r--sys/fs/procfs/procfs_regs.c7
-rw-r--r--sys/fs/pseudofs/pseudofs_vnops.c2
-rw-r--r--sys/fs/smbfs/smbfs.h8
-rw-r--r--sys/fs/smbfs/smbfs_io.c8
-rw-r--r--sys/fs/smbfs/smbfs_node.c6
-rw-r--r--sys/fs/smbfs/smbfs_node.h8
-rw-r--r--sys/fs/smbfs/smbfs_smb.c6
-rw-r--r--sys/fs/smbfs/smbfs_subr.c8
-rw-r--r--sys/fs/smbfs/smbfs_subr.h8
-rw-r--r--sys/fs/smbfs/smbfs_vfsops.c8
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c6
-rw-r--r--sys/geom/eli/g_eli.c5
-rw-r--r--sys/geom/gate/g_gate.c30
-rw-r--r--sys/geom/geom_dump.c28
-rw-r--r--sys/geom/geom_io.c9
-rw-r--r--sys/geom/geom_subr.c20
-rw-r--r--sys/geom/geom_vfs.c7
-rw-r--r--sys/geom/multipath/g_multipath.c201
-rw-r--r--sys/geom/part/g_part.c109
-rw-r--r--sys/geom/part/g_part_apm.c16
-rw-r--r--sys/geom/part/g_part_bsd.c16
-rw-r--r--sys/geom/part/g_part_gpt.c16
-rw-r--r--sys/geom/part/g_part_if.m14
-rw-r--r--sys/geom/part/g_part_mbr.c28
-rw-r--r--sys/geom/part/g_part_pc98.c28
-rw-r--r--sys/geom/part/g_part_vtoc8.c23
-rw-r--r--sys/geom/sched/README162
-rw-r--r--sys/geom/sched/g_sched.c1895
-rw-r--r--sys/geom/sched/g_sched.h138
-rw-r--r--sys/geom/sched/gs_rr.c686
-rw-r--r--sys/geom/sched/gs_scheduler.h237
-rw-r--r--sys/geom/sched/subr_disk.c209
-rw-r--r--sys/geom/vinum/geom_vinum.c15
-rw-r--r--sys/i386/acpica/acpi_machdep.c2
-rw-r--r--sys/i386/conf/GENERIC3
-rw-r--r--sys/i386/conf/NOTES9
-rw-r--r--sys/i386/conf/XBOX1
-rw-r--r--sys/i386/conf/XEN1
-rw-r--r--sys/i386/i386/apic_vector.s13
-rw-r--r--sys/i386/i386/bpf_jit_machdep.c35
-rw-r--r--sys/i386/i386/bpf_jit_machdep.h6
-rw-r--r--sys/i386/i386/identcpu.c6
-rw-r--r--sys/i386/i386/local_apic.c90
-rw-r--r--sys/i386/i386/machdep.c22
-rw-r--r--sys/i386/i386/mca.c87
-rw-r--r--sys/i386/i386/mp_machdep.c1
-rw-r--r--sys/i386/i386/mpboot.s7
-rw-r--r--sys/i386/i386/pmap.c386
-rw-r--r--sys/i386/i386/trap.c8
-rw-r--r--sys/i386/ibcs2/ibcs2_stat.c6
-rw-r--r--sys/i386/include/_inttypes.h7
-rw-r--r--sys/i386/include/apicvar.h7
-rw-r--r--sys/i386/include/bootinfo.h7
-rw-r--r--sys/i386/include/mca.h5
-rw-r--r--sys/i386/include/md_var.h1
-rw-r--r--sys/i386/include/pmc_mdep.h11
-rw-r--r--sys/i386/include/proc.h2
-rw-r--r--sys/i386/include/specialreg.h57
-rw-r--r--sys/i386/linux/linux.h18
-rw-r--r--sys/i386/linux/linux_sysvec.c9
-rw-r--r--sys/i386/xen/mp_machdep.c1
-rw-r--r--sys/i386/xen/pmap.c32
-rw-r--r--sys/ia64/conf/GENERIC61
-rw-r--r--sys/ia64/conf/NOTES4
-rw-r--r--sys/ia64/ia32/ia32_signal.c4
-rw-r--r--sys/ia64/ia64/autoconf.c19
-rw-r--r--sys/ia64/ia64/clock.c112
-rw-r--r--sys/ia64/ia64/db_machdep.c7
-rw-r--r--sys/ia64/ia64/exception.S6
-rw-r--r--sys/ia64/ia64/genassym.c4
-rw-r--r--sys/ia64/ia64/highfp.c4
-rw-r--r--sys/ia64/ia64/interrupt.c417
-rw-r--r--sys/ia64/ia64/locore.S11
-rw-r--r--sys/ia64/ia64/machdep.c54
-rw-r--r--sys/ia64/ia64/mca.c135
-rw-r--r--sys/ia64/ia64/mp_machdep.c144
-rw-r--r--sys/ia64/ia64/nexus.c106
-rw-r--r--sys/ia64/ia64/pmap.c112
-rw-r--r--sys/ia64/ia64/sal.c65
-rw-r--r--sys/ia64/ia64/sapic.c21
-rw-r--r--sys/ia64/ia64/trap.c6
-rw-r--r--sys/ia64/ia64/vm_machdep.c4
-rw-r--r--sys/ia64/include/_inttypes.h7
-rw-r--r--sys/ia64/include/acpica_machdep.h4
-rw-r--r--sys/ia64/include/clock.h8
-rw-r--r--sys/ia64/include/cpufunc.h9
-rw-r--r--sys/ia64/include/elf.h1
-rw-r--r--sys/ia64/include/frame.h2
-rw-r--r--sys/ia64/include/intr.h26
-rw-r--r--sys/ia64/include/intrcnt.h6
-rw-r--r--sys/ia64/include/mca.h3
-rw-r--r--sys/ia64/include/pal.h51
-rw-r--r--sys/ia64/include/pcb.h2
-rw-r--r--sys/ia64/include/pcpu.h12
-rw-r--r--sys/ia64/include/proc.h3
-rw-r--r--sys/ia64/include/reg.h9
-rw-r--r--sys/ia64/include/smp.h32
-rw-r--r--sys/ia64/pci/pci_cfgreg.c11
-rw-r--r--sys/kern/imgact_elf.c35
-rw-r--r--sys/kern/init_main.c22
-rw-r--r--sys/kern/kern_alq.c674
-rw-r--r--sys/kern/kern_clock.c33
-rw-r--r--sys/kern/kern_descrip.c4
-rw-r--r--sys/kern/kern_event.c10
-rw-r--r--sys/kern/kern_exec.c12
-rw-r--r--sys/kern/kern_jail.c8
-rw-r--r--sys/kern/kern_ktr.c69
-rw-r--r--sys/kern/kern_module.c2
-rw-r--r--sys/kern/kern_proc.c137
-rw-r--r--sys/kern/kern_resource.c10
-rw-r--r--sys/kern/kern_rwlock.c4
-rw-r--r--sys/kern/kern_shutdown.c23
-rw-r--r--sys/kern/kern_sig.c1
-rw-r--r--sys/kern/kern_syscalls.c30
-rw-r--r--sys/kern/kern_thr.c2
-rw-r--r--sys/kern/kern_umtx.c6
-rw-r--r--sys/kern/ksched.c27
-rw-r--r--sys/kern/subr_bus.c15
-rw-r--r--sys/kern/subr_eventhandler.c71
-rw-r--r--sys/kern/subr_firmware.c2
-rw-r--r--sys/kern/subr_param.c2
-rw-r--r--sys/kern/sys_generic.c34
-rw-r--r--sys/kern/sys_pipe.c6
-rw-r--r--sys/kern/sys_process.c30
-rw-r--r--sys/kern/sysv_ipc.c66
-rw-r--r--sys/kern/sysv_msg.c220
-rw-r--r--sys/kern/sysv_sem.c236
-rw-r--r--sys/kern/sysv_shm.c295
-rw-r--r--sys/kern/tty_pts.c15
-rw-r--r--sys/kern/uipc_mqueue.c373
-rw-r--r--sys/kern/uipc_sem.c193
-rw-r--r--sys/kern/uipc_shm.c8
-rw-r--r--sys/kern/uipc_socket.c6
-rw-r--r--sys/kern/uipc_syscalls.c28
-rw-r--r--sys/kern/vfs_aio.c94
-rw-r--r--sys/kern/vfs_bio.c30
-rw-r--r--sys/kern/vfs_cache.c4
-rw-r--r--sys/kern/vfs_default.c16
-rw-r--r--sys/kern/vfs_lookup.c20
-rw-r--r--sys/kern/vfs_subr.c34
-rw-r--r--sys/kern/vfs_syscalls.c58
-rw-r--r--sys/kern/vfs_vnops.c17
-rw-r--r--sys/libkern/iconv.c8
-rw-r--r--sys/libkern/iconv_converter_if.m8
-rw-r--r--sys/libkern/iconv_xlat.c10
-rw-r--r--sys/libkern/strcasecmp.c2
-rw-r--r--sys/mips/atheros/if_arge.c2
-rw-r--r--sys/mips/cavium/asm_octeon.S216
-rw-r--r--sys/mips/cavium/dev/rgmii/octeon_fau.c83
-rw-r--r--sys/mips/cavium/dev/rgmii/octeon_fau.h5
-rw-r--r--sys/mips/cavium/dev/rgmii/octeon_rgmx.c300
-rw-r--r--sys/mips/cavium/files.octeon14
-rw-r--r--sys/mips/cavium/octeon_ebt3000_cf.c127
-rw-r--r--sys/mips/cavium/octeon_machdep.c221
-rw-r--r--sys/mips/cavium/octeon_mp.c102
-rw-r--r--sys/mips/cavium/octeon_pcmap_regs.h570
-rw-r--r--sys/mips/conf/AR71XX9
-rw-r--r--sys/mips/conf/OCTEON12
-rw-r--r--sys/mips/conf/OCTEON1-322
-rw-r--r--sys/mips/conf/SENTRY51
-rw-r--r--sys/mips/conf/SWARM6
-rw-r--r--sys/mips/conf/XLR1
-rw-r--r--sys/mips/include/_inttypes.h101
-rw-r--r--sys/mips/include/_limits.h8
-rw-r--r--sys/mips/include/archtype.h49
-rw-r--r--sys/mips/include/asm.h84
-rw-r--r--sys/mips/include/bus.h2
-rw-r--r--sys/mips/include/clock.h8
-rw-r--r--sys/mips/include/cpu.h39
-rw-r--r--sys/mips/include/cpufunc.h157
-rw-r--r--sys/mips/include/cpuinfo.h48
-rw-r--r--sys/mips/include/cpuregs.h46
-rw-r--r--sys/mips/include/db_machdep.h2
-rw-r--r--sys/mips/include/defs.h256
-rw-r--r--sys/mips/include/kdb.h2
-rw-r--r--sys/mips/include/param.h56
-rw-r--r--sys/mips/include/pcb.h2
-rw-r--r--sys/mips/include/pmap.h36
-rw-r--r--sys/mips/include/pmc_mdep.h20
-rw-r--r--sys/mips/include/proc.h9
-rw-r--r--sys/mips/include/profile.h8
-rw-r--r--sys/mips/include/pte.h4
-rw-r--r--sys/mips/include/queue.h171
-rw-r--r--sys/mips/include/regnum.h4
-rw-r--r--sys/mips/include/rm7000.h95
-rw-r--r--sys/mips/include/sf_buf.h15
-rw-r--r--sys/mips/include/smp.h4
-rw-r--r--sys/mips/include/trap.h23
-rw-r--r--sys/mips/include/vmparam.h39
-rw-r--r--sys/mips/malta/gt_pci.c4
-rw-r--r--sys/mips/malta/gtreg.h7
-rw-r--r--sys/mips/mips/autoconf.c1
-rw-r--r--sys/mips/mips/busdma_machdep.c44
-rw-r--r--sys/mips/mips/copystr.S171
-rw-r--r--sys/mips/mips/cpu.c2
-rw-r--r--sys/mips/mips/db_trace.c21
-rw-r--r--sys/mips/mips/exception.S676
-rw-r--r--sys/mips/mips/fp.S10
-rw-r--r--sys/mips/mips/genassym.c12
-rw-r--r--sys/mips/mips/locore.S26
-rw-r--r--sys/mips/mips/machdep.c28
-rw-r--r--sys/mips/mips/mem.c204
-rw-r--r--sys/mips/mips/mp_machdep.c21
-rw-r--r--sys/mips/mips/mpboot.S21
-rw-r--r--sys/mips/mips/nexus.c10
-rw-r--r--sys/mips/mips/pm_machdep.c8
-rw-r--r--sys/mips/mips/pmap.c789
-rw-r--r--sys/mips/mips/psraccess.S117
-rw-r--r--sys/mips/mips/support.S778
-rw-r--r--sys/mips/mips/swtch.S139
-rw-r--r--sys/mips/mips/tick.c75
-rw-r--r--sys/mips/mips/tlb.S8
-rw-r--r--sys/mips/mips/trap.c346
-rw-r--r--sys/mips/mips/uio_machdep.c34
-rw-r--r--sys/mips/mips/vm_machdep.c149
-rw-r--r--sys/mips/rmi/clock.c12
-rw-r--r--[-rwxr-xr-x]sys/mips/rmi/debug.h0
-rw-r--r--[-rwxr-xr-x]sys/mips/rmi/dev/sec/desc.h0
-rw-r--r--sys/mips/rmi/ehcireg.h7
-rw-r--r--sys/mips/rmi/ehcivar.h7
-rw-r--r--[-rwxr-xr-x]sys/mips/rmi/msgring.h0
-rw-r--r--[-rwxr-xr-x]sys/mips/rmi/shared_structs.h0
-rw-r--r--[-rwxr-xr-x]sys/mips/rmi/shared_structs_func.h0
-rw-r--r--[-rwxr-xr-x]sys/mips/rmi/shared_structs_offsets.h0
-rw-r--r--sys/mips/rmi/xls_ehci.c7
-rw-r--r--sys/mips/sibyte/sb_asm.S50
-rw-r--r--sys/mips/sibyte/sb_machdep.c48
-rw-r--r--sys/mips/sibyte/sb_scd.c20
-rw-r--r--sys/mips/sibyte/sb_scd.h1
-rw-r--r--sys/modules/Makefile32
-rw-r--r--sys/modules/acpi/acpi/Makefile22
-rw-r--r--sys/modules/alq/Makefile9
-rw-r--r--sys/modules/ath/Makefile2
-rw-r--r--sys/modules/cyclic/Makefile2
-rw-r--r--sys/modules/dummynet/Makefile3
-rw-r--r--sys/modules/em/Makefile18
-rw-r--r--sys/modules/geom/Makefile1
-rw-r--r--sys/modules/geom/geom_sched/Makefile5
-rw-r--r--sys/modules/geom/geom_sched/Makefile.inc9
-rw-r--r--sys/modules/geom/geom_sched/gs_sched/Makefile6
-rw-r--r--sys/modules/geom/geom_sched/gsched_rr/Makefile9
-rw-r--r--sys/modules/hwpmc/Makefile4
-rw-r--r--sys/modules/iwnfw/iwn6000/Makefile2
-rw-r--r--sys/modules/ixgbe/Makefile2
-rw-r--r--sys/modules/linux/Makefile2
-rw-r--r--sys/modules/procfs/Makefile2
-rw-r--r--sys/modules/sge/Makefile8
-rw-r--r--sys/modules/syscons/Makefile2
-rw-r--r--sys/modules/syscons/beastie/Makefile10
-rw-r--r--sys/modules/uart/Makefile2
-rw-r--r--sys/modules/wlan/Makefile5
-rw-r--r--sys/modules/zfs/Makefile4
-rw-r--r--sys/net/bpf.c187
-rw-r--r--sys/net/bpfdesc.h1
-rw-r--r--sys/net/flowtable.c983
-rw-r--r--sys/net/flowtable.h35
-rw-r--r--sys/net/if.c19
-rw-r--r--sys/net/if.h1
-rw-r--r--sys/net/if_bridge.c9
-rw-r--r--sys/net/if_clone.c23
-rw-r--r--sys/net/if_epair.c91
-rw-r--r--sys/net/if_ethersubr.c11
-rw-r--r--sys/net/if_lagg.c4
-rw-r--r--sys/net/if_llatbl.c145
-rw-r--r--sys/net/if_llatbl.h2
-rw-r--r--sys/net/if_media.h2
-rw-r--r--sys/net/if_tap.c4
-rw-r--r--sys/net/if_tun.c2
-rw-r--r--sys/net/if_var.h2
-rw-r--r--sys/net/if_vlan.c4
-rw-r--r--sys/net/radix.c20
-rw-r--r--sys/net/radix.h1
-rw-r--r--sys/net/radix_mpath.c3
-rw-r--r--sys/net/route.c38
-rw-r--r--sys/net/route.h3
-rw-r--r--sys/net/rtsock.c102
-rw-r--r--sys/net/vnet.c48
-rw-r--r--sys/net/vnet.h39
-rw-r--r--sys/net80211/ieee80211.c4
-rw-r--r--sys/net80211/ieee80211_adhoc.c8
-rw-r--r--sys/net80211/ieee80211_amrr.c149
-rw-r--r--sys/net80211/ieee80211_amrr.h40
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c9
-rw-r--r--sys/net80211/ieee80211_crypto_tkip.c9
-rw-r--r--sys/net80211/ieee80211_freebsd.h23
-rw-r--r--sys/net80211/ieee80211_hostap.c8
-rw-r--r--sys/net80211/ieee80211_ht.c100
-rw-r--r--sys/net80211/ieee80211_input.c15
-rw-r--r--sys/net80211/ieee80211_ioctl.c166
-rw-r--r--sys/net80211/ieee80211_mesh.c13
-rw-r--r--sys/net80211/ieee80211_node.c2
-rw-r--r--sys/net80211/ieee80211_node.h3
-rw-r--r--sys/net80211/ieee80211_proto.c2
-rw-r--r--sys/net80211/ieee80211_ratectl.c66
-rw-r--r--sys/net80211/ieee80211_ratectl.h129
-rw-r--r--sys/net80211/ieee80211_rssadapt.c136
-rw-r--r--sys/net80211/ieee80211_rssadapt.h32
-rw-r--r--sys/net80211/ieee80211_scan_sta.c46
-rw-r--r--sys/net80211/ieee80211_sta.c9
-rw-r--r--sys/net80211/ieee80211_tdma.c2
-rw-r--r--sys/net80211/ieee80211_var.h22
-rw-r--r--sys/netgraph/netflow/ng_netflow.c9
-rw-r--r--sys/netgraph/ng_deflate.c9
-rw-r--r--sys/netgraph/ng_ksocket.c14
-rw-r--r--sys/netgraph/ng_l2tp.c46
-rw-r--r--sys/netgraph/ng_mppc.c6
-rw-r--r--sys/netgraph/ng_pipe.c2
-rw-r--r--sys/netgraph/ng_pipe.h2
-rw-r--r--sys/netgraph/ng_ppp.c23
-rw-r--r--sys/netgraph/ng_pptpgre.c22
-rw-r--r--sys/netgraph/ng_socket.c21
-rw-r--r--sys/netgraph/ng_socketvar.h1
-rw-r--r--sys/netgraph/ng_tcpmss.c19
-rw-r--r--sys/netinet/if_ether.c18
-rw-r--r--sys/netinet/in.c14
-rw-r--r--sys/netinet/in.h1
-rw-r--r--sys/netinet/in_mcast.c26
-rw-r--r--sys/netinet/in_pcb.c41
-rw-r--r--sys/netinet/in_pcb.h6
-rw-r--r--sys/netinet/ip_divert.c49
-rw-r--r--sys/netinet/ip_dummynet.h505
-rw-r--r--sys/netinet/ip_fw.h27
-rw-r--r--sys/netinet/ip_input.c20
-rw-r--r--sys/netinet/ip_ipsec.c2
-rw-r--r--sys/netinet/ip_output.c32
-rw-r--r--sys/netinet/ipfw/dn_heap.c550
-rw-r--r--sys/netinet/ipfw/dn_heap.h191
-rw-r--r--sys/netinet/ipfw/dn_sched.h189
-rw-r--r--sys/netinet/ipfw/dn_sched_fifo.c120
-rw-r--r--sys/netinet/ipfw/dn_sched_prio.c229
-rw-r--r--sys/netinet/ipfw/dn_sched_qfq.c864
-rw-r--r--sys/netinet/ipfw/dn_sched_rr.c307
-rw-r--r--sys/netinet/ipfw/dn_sched_wf2q.c373
-rw-r--r--sys/netinet/ipfw/dummynet.txt860
-rw-r--r--sys/netinet/ipfw/ip_dn_glue.c845
-rw-r--r--sys/netinet/ipfw/ip_dn_io.c801
-rw-r--r--sys/netinet/ipfw/ip_dn_private.h406
-rw-r--r--sys/netinet/ipfw/ip_dummynet.c3867
-rw-r--r--sys/netinet/ipfw/ip_fw2.c89
-rw-r--r--sys/netinet/ipfw/ip_fw_dynamic.c16
-rw-r--r--sys/netinet/ipfw/ip_fw_log.c4
-rw-r--r--sys/netinet/ipfw/ip_fw_pfil.c16
-rw-r--r--sys/netinet/ipfw/ip_fw_private.h31
-rw-r--r--sys/netinet/ipfw/ip_fw_sockopt.c394
-rw-r--r--sys/netinet/ipfw/ip_fw_table.c9
-rw-r--r--sys/netinet/ipfw/test/Makefile51
-rw-r--r--sys/netinet/ipfw/test/dn_test.h175
-rw-r--r--sys/netinet/ipfw/test/main.c636
-rw-r--r--sys/netinet/ipfw/test/mylist.h49
-rw-r--r--sys/netinet/ipfw/test/test_dn_heap.c162
-rw-r--r--sys/netinet/ipfw/test/test_dn_sched.c89
-rw-r--r--sys/netinet/raw_ip.c35
-rw-r--r--sys/netinet/sctp_asconf.c12
-rw-r--r--sys/netinet/sctp_constants.h15
-rw-r--r--sys/netinet/sctp_crc32.c4
-rw-r--r--sys/netinet/sctp_crc32.h2
-rw-r--r--sys/netinet/sctp_indata.c1167
-rw-r--r--sys/netinet/sctp_indata.h4
-rw-r--r--sys/netinet/sctp_input.c44
-rw-r--r--sys/netinet/sctp_output.c626
-rw-r--r--sys/netinet/sctp_output.h3
-rw-r--r--sys/netinet/sctp_pcb.c129
-rw-r--r--sys/netinet/sctp_pcb.h6
-rw-r--r--sys/netinet/sctp_structs.h3
-rw-r--r--sys/netinet/sctp_sysctl.c160
-rw-r--r--sys/netinet/sctp_uio.h6
-rw-r--r--sys/netinet/sctp_usrreq.c4
-rw-r--r--sys/netinet/sctp_var.h6
-rw-r--r--sys/netinet/sctputil.c132
-rw-r--r--sys/netinet/sctputil.h6
-rw-r--r--sys/netinet/tcp_input.c10
-rw-r--r--sys/netinet/tcp_output.c2
-rw-r--r--sys/netinet/tcp_reass.c9
-rw-r--r--sys/netinet/tcp_subr.c62
-rw-r--r--sys/netinet/tcp_timer.c43
-rw-r--r--sys/netinet/tcp_timewait.c2
-rw-r--r--sys/netinet/tcp_usrreq.c12
-rw-r--r--sys/netinet/tcp_var.h3
-rw-r--r--sys/netinet/udp_usrreq.c60
-rw-r--r--sys/netinet6/in6.c6
-rw-r--r--sys/netinet6/ip6_output.c19
-rw-r--r--sys/netinet6/mld6.c6
-rw-r--r--sys/netinet6/nd6.c3
-rw-r--r--sys/netinet6/sctp6_usrreq.c2
-rw-r--r--sys/netipsec/ipsec.c2
-rw-r--r--sys/netipsec/key.c22
-rw-r--r--sys/netncp/ncp_conn.c8
-rw-r--r--sys/netncp/ncp_conn.h8
-rw-r--r--sys/netncp/ncp_file.h8
-rw-r--r--sys/netncp/ncp_lib.h6
-rw-r--r--sys/netncp/ncp_login.c6
-rw-r--r--sys/netncp/ncp_ncp.c6
-rw-r--r--sys/netncp/ncp_ncp.h8
-rw-r--r--sys/netncp/ncp_nls.c8
-rw-r--r--sys/netncp/ncp_nls.h8
-rw-r--r--sys/netncp/ncp_rcfile.h8
-rw-r--r--sys/netncp/ncp_rq.c6
-rw-r--r--sys/netncp/ncp_rq.h6
-rw-r--r--sys/netncp/ncp_sock.c6
-rw-r--r--sys/netncp/ncp_sock.h8
-rw-r--r--sys/netncp/ncp_subr.c6
-rw-r--r--sys/netncp/ncp_subr.h8
-rw-r--r--sys/netncp/ncp_user.h8
-rw-r--r--sys/netsmb/netbios.h6
-rw-r--r--sys/netsmb/smb.h6
-rw-r--r--sys/netsmb/smb_conn.c6
-rw-r--r--sys/netsmb/smb_conn.h6
-rw-r--r--sys/netsmb/smb_dev.c6
-rw-r--r--sys/netsmb/smb_dev.h6
-rw-r--r--sys/netsmb/smb_iod.c6
-rw-r--r--sys/netsmb/smb_rq.c8
-rw-r--r--sys/netsmb/smb_rq.h8
-rw-r--r--sys/netsmb/smb_smb.c6
-rw-r--r--sys/netsmb/smb_subr.c6
-rw-r--r--sys/netsmb/smb_subr.h8
-rw-r--r--sys/netsmb/smb_tran.h8
-rw-r--r--sys/netsmb/smb_trantcp.c6
-rw-r--r--sys/netsmb/smb_trantcp.h8
-rw-r--r--sys/netsmb/smb_usr.c6
-rw-r--r--sys/nfsserver/nfs_srvsubs.c3
-rw-r--r--sys/pc98/cbus/clock.c13
-rw-r--r--sys/pc98/conf/GENERIC2
-rw-r--r--sys/pc98/pc98/machdep.c10
-rw-r--r--sys/pci/if_rlreg.h7
-rw-r--r--sys/powerpc/aim/interrupt.c6
-rw-r--r--sys/powerpc/aim/machdep.c4
-rw-r--r--sys/powerpc/aim/mmu_oea.c11
-rw-r--r--sys/powerpc/aim/mmu_oea64.c85
-rw-r--r--sys/powerpc/aim/nexus.c60
-rw-r--r--sys/powerpc/aim/ofw_machdep.c8
-rw-r--r--sys/powerpc/aim/ofwmagic.S7
-rw-r--r--sys/powerpc/booke/interrupt.c10
-rw-r--r--sys/powerpc/booke/machdep.c20
-rw-r--r--sys/powerpc/booke/pmap.c29
-rw-r--r--sys/powerpc/booke/trap_subr.S1
-rw-r--r--sys/powerpc/conf/GENERIC2
-rw-r--r--sys/powerpc/conf/MPC85XX1
-rw-r--r--sys/powerpc/fpu/fpu_extern.h7
-rw-r--r--sys/powerpc/include/_inttypes.h7
-rw-r--r--sys/powerpc/include/intr.h7
-rw-r--r--sys/powerpc/include/proc.h2
-rw-r--r--sys/powerpc/include/spr.h7
-rw-r--r--sys/powerpc/mpc85xx/ocpbus.c15
-rw-r--r--sys/powerpc/mpc85xx/ocpbus.h2
-rw-r--r--sys/powerpc/mpc85xx/pci_ocp.c15
-rw-r--r--sys/powerpc/ofw/ofw_real.c52
-rw-r--r--sys/powerpc/ofw/ofw_syscons.c4
-rw-r--r--sys/powerpc/powermac/cuda.c65
-rw-r--r--sys/powerpc/powermac/cudavar.h1
-rw-r--r--sys/powerpc/powermac/pmu.c59
-rw-r--r--sys/powerpc/powermac/smu.c321
-rw-r--r--sys/powerpc/powermac/uninorth.c15
-rw-r--r--sys/powerpc/powerpc/cpu.c7
-rw-r--r--sys/powerpc/powerpc/mmu_if.m14
-rw-r--r--sys/powerpc/powerpc/pmap_dispatch.c8
-rw-r--r--sys/rpc/svc.c2
-rw-r--r--sys/sparc64/conf/GENERIC5
-rw-r--r--sys/sparc64/conf/NOTES1
-rw-r--r--sys/sparc64/fhc/fhc.c4
-rw-r--r--sys/sparc64/include/_inttypes.h7
-rw-r--r--sys/sparc64/include/dcr.h8
-rw-r--r--sys/sparc64/include/lsu.h22
-rw-r--r--sys/sparc64/include/ofw_machdep.h1
-rw-r--r--sys/sparc64/include/proc.h2
-rw-r--r--sys/sparc64/include/tlb.h38
-rw-r--r--sys/sparc64/include/tte.h63
-rw-r--r--sys/sparc64/include/ver.h9
-rw-r--r--sys/sparc64/include/wstate.h35
-rw-r--r--sys/sparc64/isa/isa.c3
-rw-r--r--sys/sparc64/pci/apb.c24
-rw-r--r--sys/sparc64/pci/psycho.c16
-rw-r--r--sys/sparc64/pci/sbbc.c1074
-rw-r--r--sys/sparc64/pci/schizo.c59
-rw-r--r--sys/sparc64/pci/schizovar.h5
-rw-r--r--sys/sparc64/sbus/lsi64854reg.h7
-rw-r--r--sys/sparc64/sbus/lsi64854var.h7
-rw-r--r--sys/sparc64/sbus/ofw_sbus.h7
-rw-r--r--sys/sparc64/sbus/sbus.c6
-rw-r--r--sys/sparc64/sparc64/cheetah.c114
-rw-r--r--sys/sparc64/sparc64/exception.S52
-rw-r--r--sys/sparc64/sparc64/genassym.c2
-rw-r--r--sys/sparc64/sparc64/locore.S22
-rw-r--r--sys/sparc64/sparc64/machdep.c25
-rw-r--r--sys/sparc64/sparc64/mp_locore.S10
-rw-r--r--sys/sparc64/sparc64/mp_machdep.c16
-rw-r--r--sys/sparc64/sparc64/nexus.c2
-rw-r--r--sys/sparc64/sparc64/ofw_machdep.c28
-rw-r--r--sys/sparc64/sparc64/pmap.c69
-rw-r--r--sys/sparc64/sparc64/support.S25
-rw-r--r--sys/sparc64/sparc64/swtch.S2
-rw-r--r--sys/sparc64/sparc64/trap.c61
-rw-r--r--sys/sun4v/conf/GENERIC2
-rw-r--r--sys/sun4v/include/_inttypes.h7
-rw-r--r--sys/sun4v/include/ofw_machdep.h1
-rw-r--r--sys/sun4v/include/proc.h2
-rw-r--r--sys/sun4v/sun4v/machdep.c6
-rw-r--r--sys/sun4v/sun4v/pmap.c11
-rw-r--r--sys/sys/_timespec.h26
-rw-r--r--sys/sys/alq.h63
-rw-r--r--sys/sys/buf.h3
-rw-r--r--sys/sys/clock.h7
-rw-r--r--sys/sys/dtrace_bsd.h2
-rw-r--r--sys/sys/eventhandler.h16
-rw-r--r--sys/sys/iconv.h8
-rw-r--r--sys/sys/imgact.h3
-rw-r--r--sys/sys/ioccom.h5
-rw-r--r--sys/sys/mchain.h6
-rw-r--r--sys/sys/mount.h4
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pcpu.h62
-rw-r--r--sys/sys/pioctl.h2
-rw-r--r--sys/sys/pmc.h23
-rw-r--r--sys/sys/proc.h3
-rw-r--r--sys/sys/ptrace.h3
-rw-r--r--sys/sys/stat.h71
-rw-r--r--sys/sys/sysent.h29
-rw-r--r--sys/sys/systm.h5
-rw-r--r--sys/sys/thr.h4
-rw-r--r--sys/sys/timeb.h4
-rw-r--r--sys/sys/timespec.h15
-rw-r--r--sys/sys/user.h27
-rw-r--r--sys/sys/vnode.h2
-rw-r--r--sys/sys/vtoc.h2
-rw-r--r--sys/teken/teken.c2
-rw-r--r--sys/ufs/ffs/ffs_alloc.c252
-rw-r--r--sys/ufs/ffs/ffs_balloc.c13
-rw-r--r--sys/ufs/ffs/ffs_extern.h24
-rw-r--r--sys/ufs/ffs/ffs_inode.c132
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c66
-rw-r--r--sys/ufs/ffs/ffs_softdep.c7289
-rw-r--r--sys/ufs/ffs/ffs_subr.c130
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c69
-rw-r--r--sys/ufs/ffs/ffs_vnops.c1
-rw-r--r--sys/ufs/ffs/fs.h135
-rw-r--r--sys/ufs/ffs/softdep.h446
-rw-r--r--sys/ufs/ufs/dinode.h9
-rw-r--r--sys/ufs/ufs/inode.h3
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c2
-rw-r--r--sys/ufs/ufs/ufs_extern.h24
-rw-r--r--sys/ufs/ufs/ufs_lookup.c192
-rw-r--r--sys/ufs/ufs/ufs_vnops.c583
-rw-r--r--sys/ufs/ufs/ufsmount.h9
-rw-r--r--sys/vm/memguard.c2
-rw-r--r--sys/vm/memguard.h2
-rw-r--r--sys/vm/pmap.h4
-rw-r--r--sys/vm/swap_pager.c6
-rw-r--r--sys/vm/uma_int.h22
-rw-r--r--sys/vm/vm_contig.c115
-rw-r--r--sys/vm/vm_extern.h7
-rw-r--r--sys/vm/vm_fault.c21
-rw-r--r--sys/vm/vm_glue.c63
-rw-r--r--sys/vm/vm_kern.c29
-rw-r--r--sys/vm/vm_map.c40
-rw-r--r--sys/vm/vm_map.h5
-rw-r--r--sys/vm/vm_mmap.c7
-rw-r--r--sys/vm/vm_object.c15
-rw-r--r--sys/vm/vm_page.c1
-rw-r--r--sys/vm/vm_pageout.c9
-rw-r--r--sys/x86/isa/clock.c29
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc6
-rw-r--r--tools/build/options/WITH_GNU_CPIO6
-rw-r--r--tools/regression/aio/aiotest/aiotest.c3
-rw-r--r--tools/regression/bin/sh/builtins/command10.014
-rw-r--r--tools/regression/bin/sh/builtins/command11.014
-rw-r--r--tools/regression/bin/sh/builtins/command8.045
-rw-r--r--tools/regression/bin/sh/builtins/command9.014
-rw-r--r--tools/regression/bin/sh/builtins/var-assign2.055
-rw-r--r--tools/regression/bin/sh/errors/assignment-error1.030
-rw-r--r--tools/regression/bin/sh/errors/redirection-error3.054
-rw-r--r--tools/regression/bin/sh/errors/redirection-error4.07
-rw-r--r--tools/regression/bin/sh/errors/redirection-error5.05
-rw-r--r--tools/regression/bin/sh/errors/redirection-error6.012
-rw-r--r--tools/regression/bin/sh/expansion/arith4.020
-rw-r--r--tools/regression/bin/sh/expansion/arith5.017
-rw-r--r--tools/regression/bin/sh/expansion/assign1.037
-rw-r--r--tools/regression/bin/sh/expansion/cmdsubst2.043
-rw-r--r--tools/regression/bin/sh/expansion/plus-minus1.081
-rw-r--r--tools/regression/bin/sh/expansion/plus-minus2.04
-rw-r--r--tools/regression/bin/sh/expansion/plus-minus3.044
-rw-r--r--tools/regression/bin/sh/expansion/tilde1.056
-rw-r--r--tools/regression/bin/sh/expansion/tilde2.090
-rw-r--r--tools/regression/bin/sh/expansion/trim1.085
-rw-r--r--tools/regression/bin/sh/expansion/trim2.055
-rw-r--r--tools/regression/bin/sh/expansion/trim3.046
-rw-r--r--tools/regression/bin/sh/parameters/pwd1.011
-rw-r--r--tools/regression/bin/sh/parameters/pwd2.024
-rw-r--r--tools/regression/bin/sh/parser/heredoc1.085
-rw-r--r--tools/regression/bin/sh/parser/heredoc2.044
-rw-r--r--tools/regression/bpf/bpf_filter/tests/test0083.h2
-rw-r--r--tools/regression/kqueue/Makefile2
-rw-r--r--tools/regression/lib/libc/gen/Makefile2
-rw-r--r--tools/regression/lib/libc/gen/test-fnmatch.c336
-rw-r--r--tools/regression/lib/libc/resolv/resolv.c7
-rw-r--r--tools/regression/mqueue/mqtest1/mqtest1.c7
-rw-r--r--tools/regression/mqueue/mqtest2/mqtest2.c9
-rw-r--r--tools/regression/mqueue/mqtest3/mqtest3.c11
-rw-r--r--tools/regression/mqueue/mqtest4/mqtest4.c13
-rw-r--r--tools/regression/mqueue/mqtest5/mqtest5.c14
-rw-r--r--tools/regression/posixsem/posixsem.c12
-rw-r--r--tools/regression/posixsem2/semtest.c3
-rw-r--r--tools/regression/priv/Makefile2
-rw-r--r--tools/regression/sockets/unix_gc/Makefile2
-rw-r--r--tools/regression/sockets/unix_sorflush/Makefile2
-rw-r--r--tools/regression/sysvmsg/msgtest.c7
-rw-r--r--tools/regression/sysvsem/semtest.c7
-rw-r--r--tools/regression/sysvshm/shmtest.c7
-rw-r--r--tools/regression/tmpfs/Makefile2
-rw-r--r--tools/regression/tmpfs/h_funcs.subr7
-rw-r--r--tools/regression/tmpfs/h_tools.c7
-rw-r--r--tools/regression/tmpfs/t_create7
-rw-r--r--tools/regression/tmpfs/t_dots7
-rw-r--r--tools/regression/tmpfs/t_exec7
-rw-r--r--tools/regression/tmpfs/t_link7
-rw-r--r--tools/regression/tmpfs/t_mkdir7
-rw-r--r--tools/regression/tmpfs/t_mount7
-rw-r--r--tools/regression/tmpfs/t_pipes7
-rw-r--r--tools/regression/tmpfs/t_read_write7
-rw-r--r--tools/regression/tmpfs/t_readdir7
-rw-r--r--tools/regression/tmpfs/t_remove7
-rw-r--r--tools/regression/tmpfs/t_rename7
-rw-r--r--tools/regression/tmpfs/t_rmdir7
-rw-r--r--tools/regression/tmpfs/t_setattr7
-rw-r--r--tools/regression/tmpfs/t_sizes7
-rw-r--r--tools/regression/tmpfs/t_sockets7
-rw-r--r--tools/regression/tmpfs/t_statvfs7
-rw-r--r--tools/regression/tmpfs/t_symlink7
-rw-r--r--tools/regression/tmpfs/t_times7
-rw-r--r--tools/regression/tmpfs/t_trail_slash7
-rw-r--r--tools/regression/tmpfs/t_truncate7
-rw-r--r--tools/regression/tmpfs/t_vnd7
-rw-r--r--tools/regression/tmpfs/t_vnode_leak7
-rw-r--r--tools/regression/usr.bin/Makefile3
-rw-r--r--tools/regression/usr.bin/apply/Makefile4
-rw-r--r--tools/regression/usr.bin/apply/regress.00.in1
-rw-r--r--tools/regression/usr.bin/apply/regress.00.out1
-rw-r--r--tools/regression/usr.bin/apply/regress.01.out1
-rw-r--r--tools/regression/usr.bin/apply/regress.01.sh15
-rw-r--r--tools/regression/usr.bin/apply/regress.sh10
-rw-r--r--tools/regression/usr.bin/apply/regress.t6
-rw-r--r--tools/regression/usr.bin/ncal/Makefile4
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200901-jd-nhl.out17
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200901-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200902-jd-nhl.out18
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200902-md-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200903-jd-nhl.out17
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200903-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200904-jd-nhl.out18
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200904-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200905-jd-nhl.out17
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200905-md-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200906-jd-nhl.out18
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200906-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200907-jd-nhl.out17
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200907-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200908-jd-nhl.out18
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200908-md-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200909-jd-nhl.out17
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200909-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200910-jd-nhl.out18
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200910-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200911-jd-nhl.out17
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200911-md-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200912-jd-nhl.out19
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-3m200912-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2008-jd-nhl.out54
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2008-md-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2009-jd-nhl.out54
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2009-md-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2010-jd-nhl.out54
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2010-md-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2011-jd-nhl.out54
-rw-r--r--tools/regression/usr.bin/ncal/regress.b-y2011-md-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-3A-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-3AB-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-3B-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-3gy-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-3y-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-mgm-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-yA-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-yAB-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-yB-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-ygm-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.f-ym-nhl.out1
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200901-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200901-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200902-jd-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200902-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200903-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200903-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200904-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200904-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200905-jd-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200905-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200906-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200906-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200907-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200907-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200908-jd-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200908-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200909-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200909-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200910-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200910-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200911-jd-nhl.out9
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200911-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200912-jd-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-3m200912-md-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2008-jd-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2008-md-nhl.out27
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2009-jd-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2009-md-nhl.out27
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2010-jd-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2010-md-nhl.out27
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2011-jd-nhl.out36
-rw-r--r--tools/regression/usr.bin/ncal/regress.r-y2011-md-nhl.out27
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-3-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-A-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-AB-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-B-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-gmgy-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-m-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-b-mgy-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-3-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-A-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-AB-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-B-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-gmgy-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-m-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.s-r-mgy-nhl.out8
-rw-r--r--tools/regression/usr.bin/ncal/regress.sh82
-rw-r--r--tools/regression/usr.bin/ncal/regress.t6
-rw-r--r--tools/test/README1
-rw-r--r--tools/test/testfloat/README.txt50
-rw-r--r--tools/test/testfloat/fail.c46
-rw-r--r--tools/test/testfloat/fail.h29
-rw-r--r--tools/test/testfloat/random.c63
-rw-r--r--tools/test/testfloat/random.h32
-rw-r--r--tools/test/testfloat/slowfloat-32.c1183
-rw-r--r--tools/test/testfloat/slowfloat-64.c2109
-rw-r--r--tools/test/testfloat/slowfloat.c35
-rw-r--r--tools/test/testfloat/slowfloat.h167
-rw-r--r--tools/test/testfloat/sparc64/Makefile105
-rw-r--r--tools/test/testfloat/sparc64/fpu_emul.S186
-rw-r--r--tools/test/testfloat/sparc64/fpu_reg.h63
-rw-r--r--tools/test/testfloat/sparc64/fpu_util.c706
-rw-r--r--tools/test/testfloat/sparc64/libc_private.h30
-rw-r--r--tools/test/testfloat/sparc64/milieu.h56
-rw-r--r--tools/test/testfloat/sparc64/namespace.h30
-rw-r--r--tools/test/testfloat/sparc64/softfloat.h267
-rw-r--r--tools/test/testfloat/sparc64/sparc64.h93
-rw-r--r--tools/test/testfloat/sparc64/systflags.c73
-rw-r--r--tools/test/testfloat/sparc64/systfloat.S1120
-rw-r--r--tools/test/testfloat/sparc64/systfloat.h216
-rw-r--r--tools/test/testfloat/sparc64/systmodes.c54
-rw-r--r--tools/test/testfloat/sparc64/un-namespace.h30
-rw-r--r--tools/test/testfloat/systemBugs.txt323
-rw-r--r--tools/test/testfloat/systflags.h33
-rw-r--r--tools/test/testfloat/systfloat.c553
-rw-r--r--tools/test/testfloat/systmodes.h42
-rw-r--r--tools/test/testfloat/testCases.c3682
-rw-r--r--tools/test/testfloat/testCases.h69
-rw-r--r--tools/test/testfloat/testFunction.c1149
-rw-r--r--tools/test/testfloat/testFunction.h135
-rw-r--r--tools/test/testfloat/testLoops.c2713
-rw-r--r--tools/test/testfloat/testLoops.h143
-rw-r--r--tools/test/testfloat/testfloat-history.txt57
-rw-r--r--tools/test/testfloat/testfloat-source.txt444
-rw-r--r--tools/test/testfloat/testfloat.c299
-rw-r--r--tools/test/testfloat/testfloat.txt771
-rw-r--r--tools/test/testfloat/testsoftfloat.c1044
-rw-r--r--tools/test/testfloat/writeHex.c183
-rw-r--r--tools/test/testfloat/writeHex.h42
-rw-r--r--tools/tools/ath/common/dumpregs_5416.c1
-rw-r--r--tools/tools/nanobsd/Files/root/updatep12
-rw-r--r--tools/tools/nanobsd/Files/root/updatep22
-rw-r--r--tools/tools/nanobsd/gateworks/common17
-rw-r--r--tools/tools/nanobsd/nanobsd.sh12
-rw-r--r--tools/tools/netrate/http/Makefile2
-rw-r--r--tools/tools/netrate/httpd/Makefile2
-rw-r--r--tools/tools/netrate/juggle/Makefile5
-rw-r--r--tools/tools/netrate/tcpconnect/Makefile2
-rw-r--r--tools/tools/netrate/tcpp/Makefile2
-rw-r--r--tools/tools/netrate/tcpp/tcpp_client.c47
-rw-r--r--tools/tools/netrate/tcpp/tcpp_server.c5
-rw-r--r--tools/tools/netrate/tcpreceive/Makefile2
-rw-r--r--tools/tools/umastat/Makefile3
-rw-r--r--usr.bin/alias/Makefile3
-rw-r--r--usr.bin/apply/Makefile2
-rw-r--r--usr.bin/apply/apply.c67
-rw-r--r--usr.bin/ar/ar.12
-rw-r--r--usr.bin/biff/biff.14
-rw-r--r--usr.bin/c89/c89.12
-rw-r--r--usr.bin/c99/c99.12
-rw-r--r--usr.bin/calendar/Makefile6
-rw-r--r--usr.bin/calendar/calendar.186
-rw-r--r--usr.bin/calendar/calendar.c110
-rw-r--r--usr.bin/calendar/calendar.h182
-rw-r--r--usr.bin/calendar/calendars/calendar.australia74
-rw-r--r--usr.bin/calendar/calendars/calendar.dutch90
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd3
-rw-r--r--usr.bin/calendar/dates.c452
-rw-r--r--usr.bin/calendar/day.c416
-rw-r--r--usr.bin/calendar/events.c126
-rw-r--r--usr.bin/calendar/io.c372
-rw-r--r--usr.bin/calendar/locale.c164
-rw-r--r--usr.bin/calendar/ostern.c46
-rw-r--r--usr.bin/calendar/parsedata.c1009
-rw-r--r--usr.bin/calendar/paskha.c43
-rw-r--r--usr.bin/calendar/pathnames.h6
-rw-r--r--usr.bin/calendar/pom.c276
-rw-r--r--usr.bin/calendar/sunpos.c448
-rw-r--r--usr.bin/chpass/Makefile2
-rw-r--r--usr.bin/column/column.12
-rw-r--r--usr.bin/comm/comm.12
-rw-r--r--usr.bin/comm/comm.c178
-rw-r--r--usr.bin/compress/compress.c4
-rw-r--r--usr.bin/cpio/Makefile2
-rw-r--r--usr.bin/csup/Makefile46
-rw-r--r--usr.bin/csup/auth.c2
-rw-r--r--usr.bin/csup/cpasswd.14
-rw-r--r--usr.bin/csup/csup.12
-rw-r--r--usr.bin/enigma/enigma.12
-rw-r--r--usr.bin/find/find.110
-rw-r--r--usr.bin/getent/getent.c14
-rw-r--r--usr.bin/gzip/gzip.111
-rw-r--r--usr.bin/gzip/gzip.c43
-rw-r--r--usr.bin/gzip/unbzip2.c2
-rw-r--r--usr.bin/hexdump/od.12
-rw-r--r--usr.bin/indent/args.c1
-rw-r--r--usr.bin/indent/indent.14
-rw-r--r--usr.bin/indent/indent.c2
-rw-r--r--usr.bin/indent/indent_globs.h2
-rw-r--r--usr.bin/indent/lexi.c13
-rw-r--r--usr.bin/kdump/kdump.c32
-rw-r--r--usr.bin/killall/killall.12
-rw-r--r--usr.bin/locale/Makefile6
-rw-r--r--usr.bin/lockf/lockf.12
-rw-r--r--usr.bin/mail/util.c2
-rw-r--r--usr.bin/make/main.c2
-rw-r--r--usr.bin/minigzip/Makefile9
-rw-r--r--usr.bin/ncal/Makefile1
-rw-r--r--usr.bin/ncal/ncal.172
-rw-r--r--usr.bin/ncal/ncal.c731
-rw-r--r--usr.bin/netstat/netgraph.c6
-rw-r--r--usr.bin/perror/perror.12
-rw-r--r--usr.bin/procstat/Makefile1
-rw-r--r--usr.bin/procstat/procstat.161
-rw-r--r--usr.bin/procstat/procstat.c26
-rw-r--r--usr.bin/procstat/procstat.h4
-rw-r--r--usr.bin/procstat/procstat_sigs.c139
-rw-r--r--usr.bin/script/script.c1
-rw-r--r--usr.bin/sed/main.c3
-rw-r--r--usr.bin/sed/sed.18
-rw-r--r--usr.bin/sockstat/sockstat.c2
-rw-r--r--usr.bin/stat/stat.17
-rw-r--r--usr.bin/stat/stat.c29
-rw-r--r--usr.bin/tar/bsdtar.135
-rw-r--r--usr.bin/tar/bsdtar.c3
-rw-r--r--usr.bin/tar/bsdtar_platform.h4
-rw-r--r--usr.bin/tar/matching.c53
-rw-r--r--usr.bin/tar/subst.c3
-rw-r--r--usr.bin/tar/tree.h36
-rw-r--r--usr.bin/tar/write.c14
-rw-r--r--usr.bin/touch/touch.c12
-rw-r--r--usr.bin/truncate/Makefile2
-rw-r--r--usr.bin/truncate/truncate.c67
-rw-r--r--usr.bin/truss/amd64-fbsd.c2
-rw-r--r--usr.bin/truss/amd64-fbsd32.c2
-rw-r--r--usr.bin/truss/amd64-linux32.c2
-rw-r--r--usr.bin/truss/extern.h2
-rw-r--r--usr.bin/truss/i386-fbsd.c2
-rw-r--r--usr.bin/truss/i386-linux.c2
-rw-r--r--usr.bin/truss/ia64-fbsd.c2
-rw-r--r--usr.bin/truss/main.c2
-rw-r--r--usr.bin/truss/mips-fbsd.c2
-rw-r--r--usr.bin/truss/powerpc-fbsd.c4
-rw-r--r--usr.bin/truss/setup.c2
-rw-r--r--usr.bin/truss/sparc64-fbsd.c2
-rw-r--r--usr.bin/truss/syscalls.c2
-rw-r--r--usr.bin/truss/truss.h2
-rw-r--r--usr.bin/unifdef/unifdef.128
-rw-r--r--usr.bin/unifdef/unifdef.c83
-rw-r--r--usr.bin/unifdef/unifdefall.sh21
-rw-r--r--usr.bin/uniq/uniq.c193
-rw-r--r--usr.bin/wtmpcvt/wtmpcvt.12
-rw-r--r--usr.bin/xlint/lint1/decl.c8
-rw-r--r--usr.bin/xlint/lint1/lint1.h4
-rw-r--r--usr.bin/xlint/lint1/mem1.c2
-rw-r--r--usr.bin/xlint/lint1/scan.l2
-rw-r--r--usr.sbin/Makefile3
-rw-r--r--usr.sbin/ac/ac.c3
-rw-r--r--usr.sbin/acpi/acpidb/Makefile10
-rw-r--r--usr.sbin/acpi/iasl/Makefile6
-rw-r--r--usr.sbin/asf/asf.82
-rw-r--r--usr.sbin/bluetooth/bthidd/Makefile1
-rw-r--r--usr.sbin/bsnmpd/modules/Makefile.inc3
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt151
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/Makefile1
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c577
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def47
-rw-r--r--usr.sbin/burncd/burncd.82
-rw-r--r--usr.sbin/config/config.h2
-rw-r--r--usr.sbin/config/config.y10
-rw-r--r--usr.sbin/config/configvers.h2
-rw-r--r--usr.sbin/config/lang.l3
-rw-r--r--usr.sbin/config/main.c20
-rw-r--r--usr.sbin/config/mkmakefile.c4
-rw-r--r--usr.sbin/config/mkoptions.c37
-rw-r--r--usr.sbin/ctm/ctm/ctm.12
-rw-r--r--usr.sbin/ctm/ctm/ctm.52
-rw-r--r--usr.sbin/devinfo/devinfo.82
-rw-r--r--usr.sbin/fdformat/fdformat.12
-rw-r--r--usr.sbin/fdread/fdread.12
-rw-r--r--usr.sbin/fdwrite/fdwrite.12
-rw-r--r--usr.sbin/fifolog/fifolog_create/fifolog.12
-rw-r--r--usr.sbin/flowctl/flowctl.82
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.82
-rw-r--r--usr.sbin/fwcontrol/Makefile2
-rw-r--r--usr.sbin/jail/jail.86
-rw-r--r--usr.sbin/jls/jls.c2
-rw-r--r--usr.sbin/lastlogin/lastlogin.82
-rw-r--r--usr.sbin/lastlogin/lastlogin.c29
-rw-r--r--usr.sbin/mailwrapper/mailwrapper.83
-rw-r--r--usr.sbin/mailwrapper/mailwrapper.c8
-rw-r--r--usr.sbin/makefs/ffs/ffs_bswap.c2
-rw-r--r--usr.sbin/mergemaster/mergemaster.815
-rwxr-xr-xusr.sbin/mergemaster/mergemaster.sh14
-rw-r--r--usr.sbin/mount_nwfs/Makefile1
-rw-r--r--usr.sbin/mount_nwfs/mount_nwfs.c20
-rw-r--r--usr.sbin/mtest/mtest.82
-rw-r--r--usr.sbin/mtree/compare.c6
-rw-r--r--usr.sbin/mtree/create.c4
-rw-r--r--usr.sbin/mtree/mtree.87
-rw-r--r--usr.sbin/periodic/periodic.82
-rw-r--r--usr.sbin/pkg_install/Makefile4
-rw-r--r--usr.sbin/pkg_install/Makefile.inc13
-rw-r--r--usr.sbin/pkg_install/add/Makefile7
-rw-r--r--usr.sbin/pkg_install/add/extract.c2
-rw-r--r--usr.sbin/pkg_install/add/futil.c4
-rw-r--r--usr.sbin/pkg_install/add/main.c4
-rw-r--r--usr.sbin/pkg_install/add/perform.c26
-rw-r--r--usr.sbin/pkg_install/create/Makefile6
-rw-r--r--usr.sbin/pkg_install/create/main.c4
-rw-r--r--usr.sbin/pkg_install/create/perform.c2
-rw-r--r--usr.sbin/pkg_install/create/pl.c2
-rw-r--r--usr.sbin/pkg_install/delete/Makefile5
-rw-r--r--usr.sbin/pkg_install/delete/main.c4
-rw-r--r--usr.sbin/pkg_install/delete/perform.c22
-rw-r--r--usr.sbin/pkg_install/info/Makefile6
-rw-r--r--usr.sbin/pkg_install/info/info.h39
-rw-r--r--usr.sbin/pkg_install/info/main.c14
-rw-r--r--usr.sbin/pkg_install/info/perform.c2
-rw-r--r--usr.sbin/pkg_install/info/show.c2
-rw-r--r--usr.sbin/pkg_install/lib/Makefile11
-rw-r--r--usr.sbin/pkg_install/lib/pkgwrap.c89
-rw-r--r--usr.sbin/pkg_install/updating/Makefile5
-rw-r--r--usr.sbin/pkg_install/updating/main.c4
-rw-r--r--usr.sbin/pkg_install/updating/pkg_updating.19
-rw-r--r--usr.sbin/pkg_install/version/Makefile5
-rw-r--r--usr.sbin/pkg_install/version/main.c4
-rw-r--r--usr.sbin/pkg_install/version/perform.c33
-rw-r--r--usr.sbin/pmcannotate/pmcannotate.83
-rw-r--r--usr.sbin/pmccontrol/pmccontrol.82
-rw-r--r--usr.sbin/pmcstat/pmcpl_callgraph.c5
-rw-r--r--usr.sbin/pmcstat/pmcpl_calltree.c33
-rw-r--r--usr.sbin/pmcstat/pmcpl_gprof.c2
-rw-r--r--usr.sbin/pmcstat/pmcstat.82
-rw-r--r--usr.sbin/pmcstat/pmcstat.c3
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.c65
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.h2
-rw-r--r--usr.sbin/powerd/powerd.82
-rw-r--r--usr.sbin/ppp/arp.c2
-rw-r--r--usr.sbin/pppctl/pppctl.82
-rw-r--r--usr.sbin/sade/disks.c7
-rw-r--r--usr.sbin/sade/menus.c23
-rw-r--r--usr.sbin/services_mkdb/Makefile10
-rw-r--r--usr.sbin/services_mkdb/services_mkdb.897
-rw-r--r--usr.sbin/services_mkdb/services_mkdb.c429
-rw-r--r--usr.sbin/services_mkdb/uniq.c159
-rw-r--r--usr.sbin/setfmac/setfsmac.82
-rw-r--r--usr.sbin/setpmac/setpmac.82
-rw-r--r--usr.sbin/sysinstall/devices.c1
-rw-r--r--usr.sbin/sysinstall/disks.c7
-rw-r--r--usr.sbin/sysinstall/menus.c40
-rw-r--r--usr.sbin/sysinstall/sysinstall.82
-rw-r--r--usr.sbin/sysinstall/tcpip.c2
-rw-r--r--usr.sbin/uhsoctl/Makefile2
-rw-r--r--usr.sbin/uhsoctl/uhsoctl.18
-rw-r--r--usr.sbin/vidcontrol/vidcontrol.c37
-rw-r--r--usr.sbin/wpa/wpa_supplicant/driver_freebsd.c13
-rw-r--r--usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.524
-rw-r--r--usr.sbin/zic/Makefile1
3323 files changed, 159263 insertions, 109670 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 316d226..3d4ff92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -36,8 +36,6 @@ pci bus imp,jhb Pre-commit review requested.
cdboot jhb Pre-commit review requested.
pxeboot jhb Pre-commit review requested.
witness jhb Pre-commit review requested.
-twe aradford@amcc.com Pre-commit review requested
-twa aradford@amcc.com Pre-commit review requested
CAM gibbs,
ken Pre-commit review requested. send to scsi@freebsd.org
devstat(9) ken Pre-commit review requested.
@@ -59,15 +57,12 @@ libfetch des Advance notification requested.
fetch des Advance notification requested.
libpam des Pre-commit review requested.
openssh des Pre-commit review requested.
-pseudofs des Advance notification requested.
-procfs des Advance notification requested.
-linprocfs des Advance notification requested.
+pseudofs des Pre-commit review requested.
+procfs des Pre-commit review requested.
+linprocfs des Pre-commit review requested.
lpr gad Pre-commit review requested, particularly for
lpd/recvjob.c and lpd/printjob.c.
newsyslog(8) gad Heads-up appreciated. I'm going thru the PR's for it.
-pkill gad Heads-up appreciated.
-ps gad I am working on a number of changes to this. Would
- like advance notice of major changes planned to it.
cvs peter Heads-up appreciated, try not to break it.
nvi peter Try not to break it.
libz peter Try not to break it.
@@ -76,9 +71,6 @@ share/mk ru This is a vital component of the build system, so I
offer a pre-commit review for anything non-trivial.
ipfw ipfw Pre-commit review preferred. send to ipfw@freebsd.org
drm rnoland Just keep me informed of changes, try not to break it.
-libufs jmallett Willing to handle problems, help with work.
-fdc(4) joerg Just keep me informed of changes, try not to break it.
-sppp(4) joerg Just keep me informed of changes, try not to break it.
unifdef(1) fanf Pre-commit review requested.
ntp roberto Pre-commit review requested.
inetd dwmalone Recommends pre-commit review.
@@ -131,6 +123,9 @@ usr.sbin/zic edwin Heads-up appreciated, since this code is
maintained by a third party source.
lib/libc/stdtime edwin Heads-up appreciated, since parts of this code
is maintained by a third party source.
+sysinstall randi Please contact about any major changes so that
+ they can be co-ordinated.
+sbin/routed bms Pre-commit review; notify vendor at rhyolite.com
Following are the entries from the Makefiles, and a few other sources.
Please remove stale entries from both their origin, and this file.
@@ -144,4 +139,3 @@ $ cd /usr/src; find */* -type f|xargs egrep 'MAINTAINER[ <tab>]*='
sys/modules/3dfx/Makefile:MAINTAINER= cokane@FreeBSD.org
sys/modules/urio/Makefile:MAINTAINER= Iwasa Kazmi <kzmi@ca2.so-net.ne.jp>
tools/tools/sysdoc/Makefile:MAINTAINER= trhodes@FreeBSD.org
-usr.sbin/zic/Makefile:MAINTAINER= wollman@FreeBSD.org
diff --git a/Makefile b/Makefile
index bd26716..ce53124 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@
# reinstallkernel - Reinstall the kernel and the kernel-modules.
# reinstallkernel.debug
# kernel - buildkernel + installkernel.
+# kernel-toolchain - Builds the subset of world necessary to build a kernel
# doxygen - Build API documentation of the kernel, needs doxygen.
# update - Convenient way to update your source tree (cvs).
# check-old - List obsolete directories/files/libraries.
@@ -310,6 +311,7 @@ universe_${target}:
"check _.${target}.buildworld for details" | ${MAKEFAIL}))
@echo ">> ${target} buildworld completed on `LC_ALL=C date`"
.endif
+.if !defined(MAKE_JUST_WORLDS)
.if exists(${.CURDIR}/sys/${target}/conf/NOTES)
@(cd ${.CURDIR}/sys/${target}/conf && env __MAKE_CONF=/dev/null \
${MAKE} LINT > ${.CURDIR}/_.${target}.makeLINT 2>&1 || \
@@ -318,6 +320,7 @@ universe_${target}:
.endif
@cd ${.CURDIR} && ${MAKE} ${.MAKEFLAGS} TARGET=${target} \
universe_kernels
+.endif
@echo ">> ${target} completed on `LC_ALL=C date`"
.endfor
universe_kernels: universe_kernconfs
diff --git a/Makefile.inc1 b/Makefile.inc1
index fe163ab..df4604a 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -15,6 +15,7 @@
# -DNO_CTF do not run the DTrace CTF conversion tools on built objects
# LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list
# TARGET="machine" to crossbuild world for a different machine type
+# TARGET_ARCH= may be required when a TARGET supports multiple endians
#
# The intended user-driven targets are:
@@ -258,7 +259,7 @@ WMAKEENV= ${CROSSENV} \
VERSION="${VERSION}" \
INSTALL="sh ${.CURDIR}/tools/install.sh" \
PATH=${TMPPATH}
-.if ${MK_CDDL} == "no" || defined(NO_CTF)
+.if ${MK_CDDL} == "no"
WMAKEENV+= NO_CTF=1
.endif
WMAKE= ${WMAKEENV} ${MAKE} -f Makefile.inc1 DESTDIR=${WORLDTMP}
@@ -283,6 +284,7 @@ LIB32WMAKEENV= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \
VERSION="${VERSION}" \
MACHINE=i386 \
MACHINE_ARCH=i386 \
+ MACHINE_CPU="i686 mmx sse sse2" \
INSTALL="sh ${.CURDIR}/tools/install.sh" \
PATH=${TMPPATH} \
CC="${CC} ${LIB32FLAGS}" \
@@ -778,7 +780,7 @@ buildkernel:
@echo "--------------------------------------------------------------"
cd ${KRNLOBJDIR}/${_kernel}; \
MAKESRCPATH=${KERNSRCDIR}/dev/aic7xxx/aicasm \
- ${MAKE} SSP_CFLAGS= -DNO_CPU_CFLAGS -DNO_CTF \
+ ${MAKE} SSP_CFLAGS= -DNO_CPU_CFLAGS \
-f ${KERNSRCDIR}/dev/aic7xxx/aicasm/Makefile
# XXX - Gratuitously builds aicasm in the ``makeoptions NO_MODULES'' case.
.if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists(${KERNSRCDIR}/modules)
@@ -1109,7 +1111,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libheimntlm} \
${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \
${_kerberos5_lib_libroken} \
lib/libbz2 lib/libcom_err lib/libcrypt \
- lib/libexpat \
+ lib/libexpat lib/libfetch \
${_lib_libgssapi} ${_lib_libipx} \
lib/libkiconv lib/libkvm lib/libmd \
lib/ncurses/ncurses lib/ncurses/ncursesw \
@@ -1136,6 +1138,7 @@ _cddl_lib= cddl/lib
_secure_lib_libcrypto= secure/lib/libcrypto
_secure_lib_libssl= secure/lib/libssl
lib/libradius__L secure/lib/libssl__L: secure/lib/libcrypto__L
+lib/libfetch__L: secure/lib/libcrypto__L secure/lib/libssl__L lib/libmd__L
.if ${MK_OPENSSH} != "no"
_secure_lib_libssh= secure/lib/libssh
secure/lib/libssh__L: lib/libz__L secure/lib/libcrypto__L lib/libcrypt__L
@@ -1171,7 +1174,7 @@ _lib_libypclnt= lib/libypclnt
.endif
.if ${MK_OPENSSL} == "no"
-lib/libradius__L: lib/libmd__L
+lib/libfetch__L lib/libradius__L: lib/libmd__L
.endif
.for _lib in ${_prereq_libs}
@@ -1259,7 +1262,7 @@ delete-old-files:
@echo ">>> Removing old files (only deletes safe to delete libs)"
# Ask for every old file if the user really wants to remove it.
# It's annoying, but better safe than sorry.
- @for file in ${OLD_FILES}; do \
+ @for file in ${OLD_FILES} ${OLD_FILES:Musr/share/*.gz:R}; do \
if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \
chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \
rm ${RM_I} "${DESTDIR}/$${file}"; \
@@ -1279,7 +1282,7 @@ delete-old-files:
check-old-files:
@echo ">>> Checking for old files"
- @for file in ${OLD_FILES}; do \
+ @for file in ${OLD_FILES} ${OLD_FILES:Musr/share/*.gz:R}; do \
if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \
echo "${DESTDIR}/$${file}"; \
fi; \
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index ff811b7..2d4624d 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -14,6 +14,37 @@
# The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
#
+# 20100416: [mips] removed <machine/psl.h>
+.if ${TARGET_ARCH} == "mips"
+OLD_FILES+=usr/include/machine/psl.h
+.endif
+# 20100415: [mips] removed unused headers
+.if ${TARGET_ARCH} == "mips"
+OLD_FILES+=usr/include/machine/archtype.h
+OLD_FILES+=usr/include/machine/segments.h
+OLD_FILES+=usr/include/machine/rm7000.h
+OLD_FILES+=usr/include/machine/defs.h
+OLD_FILES+=usr/include/machine/queue.h
+.endif
+# 20100326: [ia64] removed <machine/nexusvar.h>
+.if ${TARGET_ARCH} == "ia64"
+OLD_FILES+=usr/include/machine/nexusvar.h
+.endif
+# 20100326: gcpio removal
+OLD_FILES+=usr/bin/gcpio
+OLD_FILES+=usr/share/info/cpio.info.gz
+OLD_FILES+=usr/share/man/man1/gcpio.1.gz
+# 20100322: libz update
+OLD_LIBS+=lib/libz.so.5
+.if ${TARGET_ARCH} == "amd64"
+OLD_LIBS+=usr/lib32/libz.so.5
+.endif
+# 20100314: removal of regexp.h
+OLD_FILES+=usr/include/regexp.h
+OLD_FILES+=usr/share/man/man3/regexp.3.gz
+OLD_FILES+=usr/share/man/man3/regsub.3.gz
+# 20100303: actual removal of utmp.h
+OLD_FILES+=usr/include/utmp.h
# 20100227: [ia64] removed <machine/sapicreg.h> and <machine/sapicvar.h>
.if ${TARGET_ARCH} == "ia64"
OLD_FILES+=usr/include/machine/sapicreg.h
diff --git a/UPDATING b/UPDATING
index fe27b4f..553e961 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,22 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
machines to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
+20100402:
+ WITH_CTF can now be specified in src.conf (not recommended, there
+ are some problems with static executables), make.conf (would also
+ affect ports which do not use GNU make and do not override the
+ compile targets) or in the kernel config (via "makeoptions
+ WITH_CTF=yes").
+ When WITH_CTF was specified there before this was silently ignored,
+ so make sure that WITH_CTF is not used in places which could lead
+ to unwanted behavior.
+
+20100311:
+ The kernel option COMPAT_IA32 has been replaced with COMPAT_FREEBSD32
+ to allow 32-bit compatibility on non-x86 platforms. All kernel
+ configurations on amd64 and ia64 platforms using these options must
+ be modified accordingly.
+
20100113:
The utmp user accounting database has been replaced with utmpx,
the user accounting interface standardized by POSIX.
@@ -497,7 +513,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
20090313:
The k8temp(4) driver has been renamed to amdtemp(4) since
- support for K10 and K11 CPU families was added.
+ support for Family 10 and Family 11 CPU families was added.
20090309:
IGMPv3 and Source-Specific Multicast (SSM) have been merged
@@ -983,7 +999,7 @@ COMMON ITEMS:
mergemaster -p [5]
make installworld
make delete-old
- mergemaster [4]
+ mergemaster -i [4]
<reboot>
@@ -1054,7 +1070,8 @@ COMMON ITEMS:
system. Attempting to do it by hand is not recommended and those
that pursue this avenue should read this file carefully, as well
as the archives of freebsd-current and freebsd-hackers mailing lists
- for potential gotchas.
+ for potential gotchas. The -U option is also useful to consider.
+ See mergemaster(8) for more information.
[5] Usually this step is a noop. However, from time to time
you may need to do this if you get unknown user in the following
diff --git a/bin/cp/utils.c b/bin/cp/utils.c
index b075eac..d729bd5 100644
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -323,8 +323,8 @@ setfile(struct stat *fs, int fd)
fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX |
S_IRWXU | S_IRWXG | S_IRWXO;
- TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atim);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtim);
if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) {
warn("%sutimes: %s", islink ? "l" : "", to.p_path);
rval = 1;
diff --git a/bin/ed/Makefile b/bin/ed/Makefile
index 32e2dfa..5a7e37d 100644
--- a/bin/ed/Makefile
+++ b/bin/ed/Makefile
@@ -4,7 +4,6 @@
PROG= ed
SRCS= buf.c cbc.c glbl.c io.c main.c re.c sub.c undo.c
-WARNS?= 2
LINKS= ${BINDIR}/ed ${BINDIR}/red
MLINKS= ed.1 red.1
diff --git a/bin/ed/main.c b/bin/ed/main.c
index 2273c95..fad1866 100644
--- a/bin/ed/main.c
+++ b/bin/ed/main.c
@@ -103,15 +103,10 @@ const char usage[] = "usage: %s [-] [-sx] [-p string] [file]\n";
/* ed: line editor */
int
-main(int argc, char *argv[])
+main(volatile int argc, char ** volatile argv)
{
int c, n;
long status = 0;
-#if __GNUC__
- /* Avoid longjmp clobbering */
- (void) &argc;
- (void) &argv;
-#endif
(void)setlocale(LC_ALL, "");
diff --git a/bin/ln/ln.c b/bin/ln/ln.c
index e946646..fc3afc1 100644
--- a/bin/ln/ln.c
+++ b/bin/ln/ln.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -172,6 +173,52 @@ main(int argc, char *argv[])
exit(exitval);
}
+/*
+ * Two pathnames refer to the same directory entry if the directories match
+ * and the final components' names match.
+ */
+static int
+samedirent(const char *path1, const char *path2)
+{
+ const char *file1, *file2;
+ char pathbuf[PATH_MAX];
+ struct stat sb1, sb2;
+
+ if (strcmp(path1, path2) == 0)
+ return 1;
+ file1 = strrchr(path1, '/');
+ if (file1 != NULL)
+ file1++;
+ else
+ file1 = path1;
+ file2 = strrchr(path2, '/');
+ if (file2 != NULL)
+ file2++;
+ else
+ file2 = path2;
+ if (strcmp(file1, file2) != 0)
+ return 0;
+ if (file1 - path1 >= PATH_MAX || file2 - path2 >= PATH_MAX)
+ return 0;
+ if (file1 == path1)
+ memcpy(pathbuf, ".", 2);
+ else {
+ memcpy(pathbuf, path1, file1 - path1);
+ pathbuf[file1 - path1] = '\0';
+ }
+ if (stat(pathbuf, &sb1) != 0)
+ return 0;
+ if (file2 == path2)
+ memcpy(pathbuf, ".", 2);
+ else {
+ memcpy(pathbuf, path2, file2 - path2);
+ pathbuf[file2 - path2] = '\0';
+ }
+ if (stat(pathbuf, &sb2) != 0)
+ return 0;
+ return sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino;
+}
+
int
linkit(const char *source, const char *target, int isdir)
{
@@ -180,6 +227,7 @@ linkit(const char *source, const char *target, int isdir)
int ch, exists, first;
char path[PATH_MAX];
char wbuf[PATH_MAX];
+ char bbuf[PATH_MAX];
if (!sflag) {
/* If source doesn't exist, quit now. */
@@ -202,11 +250,9 @@ linkit(const char *source, const char *target, int isdir)
if (isdir ||
(lstat(target, &sb) == 0 && S_ISDIR(sb.st_mode)) ||
(!hflag && stat(target, &sb) == 0 && S_ISDIR(sb.st_mode))) {
- if ((p = strrchr(source, '/')) == NULL)
- p = source;
- else
- ++p;
- if (snprintf(path, sizeof(path), "%s/%s", target, p) >=
+ if (strlcpy(bbuf, source, sizeof(bbuf)) >= sizeof(bbuf) ||
+ (p = basename(bbuf)) == NULL ||
+ snprintf(path, sizeof(path), "%s/%s", target, p) >=
(ssize_t)sizeof(path)) {
errno = ENAMETOOLONG;
warn("%s", source);
@@ -215,7 +261,6 @@ linkit(const char *source, const char *target, int isdir)
target = path;
}
- exists = !lstat(target, &sb);
/*
* If the link source doesn't exist, and a symbolic link was
* requested, and -w was specified, give a warning.
@@ -231,19 +276,30 @@ linkit(const char *source, const char *target, int isdir)
* absolute path of the source, by appending `source'
* to the parent directory of the target.
*/
- p = strrchr(target, '/');
- if (p != NULL)
- p++;
- else
- p = target;
- (void)snprintf(wbuf, sizeof(wbuf), "%.*s%s",
- (int)(p - target), target, source);
- if (stat(wbuf, &sb) != 0)
- warn("warning: %s", source);
+ strlcpy(bbuf, target, sizeof(bbuf));
+ p = dirname(bbuf);
+ if (p != NULL) {
+ (void)snprintf(wbuf, sizeof(wbuf), "%s/%s",
+ p, source);
+ if (stat(wbuf, &sb) != 0)
+ warn("warning: %s", source);
+ }
+ }
+ }
+
+ /*
+ * If the file exists, first check it is not the same directory entry.
+ */
+ exists = !lstat(target, &sb);
+ if (exists) {
+ if (!sflag && samedirent(source, target)) {
+ warnx("%s and %s are the same directory entry",
+ source, target);
+ return (1);
}
}
/*
- * If the file exists, then unlink it forcibly if -f was specified
+ * Then unlink it forcibly if -f was specified
* and interactively if -i was specified.
*/
if (fflag && exists) {
diff --git a/bin/ln/symlink.7 b/bin/ln/symlink.7
index d2e8cbb..8c09f28 100644
--- a/bin/ln/symlink.7
+++ b/bin/ln/symlink.7
@@ -29,7 +29,7 @@
.\" @(#)symlink.7 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd March 31, 1994
+.Dd April 25, 2010
.Dt SYMLINK 7
.Os
.Sh NAME
@@ -103,19 +103,23 @@ the system call
would return a file descriptor to the file
.Dq afile .
.Pp
-There are nine system calls that do not follow links, and which operate
+There are thirteen system calls that do not follow links, and which operate
on the symbolic link itself.
They are:
.Xr lchflags 2 ,
.Xr lchmod 2 ,
.Xr lchown 2 ,
+.Xr lpathconf 2 ,
.Xr lstat 2 ,
.Xr lutimes 2 ,
.Xr readlink 2 ,
+.Xr readlinkat 2 ,
.Xr rename 2 ,
+.Xr renameat 2 ,
.Xr rmdir 2 ,
+.Xr unlink 2 ,
and
-.Xr unlink 2 .
+.Xr unlinkat 2 .
Because
.Xr remove 3
is an alias for
@@ -123,9 +127,30 @@ is an alias for
it also does not follow symbolic links.
When
.Xr rmdir 2
+or
+.Xr unlinkat 2
+with the
+.Dv AT_REMOVEDIR
+flag
is applied to a symbolic link, it fails with the error
.Er ENOTDIR .
.Pp
+The
+.Xr linkat 2
+system call does not follow symbolic links
+unless given the
+.Dv AT_SYMLINK_FOLLOW
+flag.
+.Pp
+The following system calls follow symbolic links
+unless given the
+.Dv AT_SYMLINK_NOFOLLOW
+flag:
+.Xr fchmodat 2 ,
+.Xr fchownat 2
+and
+.Xr fstatat 2 .
+.Pp
The owner and group of an existing symbolic link can be changed by
means of the
.Xr lchown 2
@@ -138,8 +163,8 @@ an existing symbolic link can be changed by means of the
and
.Xr lutimes 2
system calls, respectively.
-Of these, only the flags are used by the system;
-the access permissions and ownership are ignored.
+Of these, only the flags and ownership are used by the system;
+the access permissions are ignored.
.Pp
The
.Bx 4.4
diff --git a/bin/ls/cmp.c b/bin/ls/cmp.c
index badd108..84fb038 100644
--- a/bin/ls/cmp.c
+++ b/bin/ls/cmp.c
@@ -66,17 +66,17 @@ int
modcmp(const FTSENT *a, const FTSENT *b)
{
- if (b->fts_statp->st_mtimespec.tv_sec >
- a->fts_statp->st_mtimespec.tv_sec)
+ if (b->fts_statp->st_mtim.tv_sec >
+ a->fts_statp->st_mtim.tv_sec)
return (1);
- if (b->fts_statp->st_mtimespec.tv_sec <
- a->fts_statp->st_mtimespec.tv_sec)
+ if (b->fts_statp->st_mtim.tv_sec <
+ a->fts_statp->st_mtim.tv_sec)
return (-1);
- if (b->fts_statp->st_mtimespec.tv_nsec >
- a->fts_statp->st_mtimespec.tv_nsec)
+ if (b->fts_statp->st_mtim.tv_nsec >
+ a->fts_statp->st_mtim.tv_nsec)
return (1);
- if (b->fts_statp->st_mtimespec.tv_nsec <
- a->fts_statp->st_mtimespec.tv_nsec)
+ if (b->fts_statp->st_mtim.tv_nsec <
+ a->fts_statp->st_mtim.tv_nsec)
return (-1);
return (strcoll(a->fts_name, b->fts_name));
}
@@ -92,17 +92,17 @@ int
acccmp(const FTSENT *a, const FTSENT *b)
{
- if (b->fts_statp->st_atimespec.tv_sec >
- a->fts_statp->st_atimespec.tv_sec)
+ if (b->fts_statp->st_atim.tv_sec >
+ a->fts_statp->st_atim.tv_sec)
return (1);
- if (b->fts_statp->st_atimespec.tv_sec <
- a->fts_statp->st_atimespec.tv_sec)
+ if (b->fts_statp->st_atim.tv_sec <
+ a->fts_statp->st_atim.tv_sec)
return (-1);
- if (b->fts_statp->st_atimespec.tv_nsec >
- a->fts_statp->st_atimespec.tv_nsec)
+ if (b->fts_statp->st_atim.tv_nsec >
+ a->fts_statp->st_atim.tv_nsec)
return (1);
- if (b->fts_statp->st_atimespec.tv_nsec <
- a->fts_statp->st_atimespec.tv_nsec)
+ if (b->fts_statp->st_atim.tv_nsec <
+ a->fts_statp->st_atim.tv_nsec)
return (-1);
return (strcoll(a->fts_name, b->fts_name));
}
@@ -118,17 +118,17 @@ int
birthcmp(const FTSENT *a, const FTSENT *b)
{
- if (b->fts_statp->st_birthtimespec.tv_sec >
- a->fts_statp->st_birthtimespec.tv_sec)
+ if (b->fts_statp->st_birthtim.tv_sec >
+ a->fts_statp->st_birthtim.tv_sec)
return (1);
- if (b->fts_statp->st_birthtimespec.tv_sec <
- a->fts_statp->st_birthtimespec.tv_sec)
+ if (b->fts_statp->st_birthtim.tv_sec <
+ a->fts_statp->st_birthtim.tv_sec)
return (-1);
- if (b->fts_statp->st_birthtimespec.tv_nsec >
- a->fts_statp->st_birthtimespec.tv_nsec)
+ if (b->fts_statp->st_birthtim.tv_nsec >
+ a->fts_statp->st_birthtim.tv_nsec)
return (1);
- if (b->fts_statp->st_birthtimespec.tv_nsec <
- a->fts_statp->st_birthtimespec.tv_nsec)
+ if (b->fts_statp->st_birthtim.tv_nsec <
+ a->fts_statp->st_birthtim.tv_nsec)
return (-1);
return (strcoll(a->fts_name, b->fts_name));
}
@@ -144,17 +144,17 @@ int
statcmp(const FTSENT *a, const FTSENT *b)
{
- if (b->fts_statp->st_ctimespec.tv_sec >
- a->fts_statp->st_ctimespec.tv_sec)
+ if (b->fts_statp->st_ctim.tv_sec >
+ a->fts_statp->st_ctim.tv_sec)
return (1);
- if (b->fts_statp->st_ctimespec.tv_sec <
- a->fts_statp->st_ctimespec.tv_sec)
+ if (b->fts_statp->st_ctim.tv_sec <
+ a->fts_statp->st_ctim.tv_sec)
return (-1);
- if (b->fts_statp->st_ctimespec.tv_nsec >
- a->fts_statp->st_ctimespec.tv_nsec)
+ if (b->fts_statp->st_ctim.tv_nsec >
+ a->fts_statp->st_ctim.tv_nsec)
return (1);
- if (b->fts_statp->st_ctimespec.tv_nsec <
- a->fts_statp->st_ctimespec.tv_nsec)
+ if (b->fts_statp->st_ctim.tv_nsec <
+ a->fts_statp->st_ctim.tv_nsec)
return (-1);
return (strcoll(a->fts_name, b->fts_name));
}
diff --git a/bin/pax/Makefile b/bin/pax/Makefile
index f142bfc..9e8d4e1 100644
--- a/bin/pax/Makefile
+++ b/bin/pax/Makefile
@@ -29,8 +29,5 @@ PROG= pax
SRCS= ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c \
gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c \
tables.c tar.c tty_subs.c
-#XXX NOTYET
-#MAN= pax.1 tar.1 cpio.1
-#LINKS= ${BINDIR}/pax ${BINDIR}/tar ${BINDIR}/pax ${BINDIR}/cpio
.include <bsd.prog.mk>
diff --git a/bin/pax/cpio.1 b/bin/pax/cpio.1
deleted file mode 100644
index 7ff1881..0000000
--- a/bin/pax/cpio.1
+++ /dev/null
@@ -1,304 +0,0 @@
-.\"-
-.\" Copyright (c) 1997 SigmaSoft, Th. Lockert
-.\" 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.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by SigmaSoft, Th. Lockert.
-.\" 4. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-.\"
-.\" $OpenBSD: cpio.1,v 1.16 2001/05/01 17:58:01 aaron Exp $
-.\" $FreeBSD$
-.\"
-.Dd February 16, 1997
-.Dt CPIO 1
-.Os
-.Sh NAME
-.Nm cpio
-.Nd copy file archives in and out
-.Sh SYNOPSIS
-.Nm
-.Fl o
-.Op Fl aABcLvzZ
-.Op Fl C Ar bytes
-.Op Fl F Ar archive
-.Op Fl H Ar format
-.Op Fl O Ar archive
-.No < Ar name-list
-.Op No > Ar archive
-.Nm
-.Fl i
-.Op Fl bBcdfmrsStuvzZ6
-.Op Fl C Ar bytes
-.Op Fl E Ar file
-.Op Fl F Ar archive
-.Op Fl H Ar format
-.Op Fl I Ar archive
-.Op Ar pattern ...
-.Op No < Ar archive
-.Nm
-.Fl p
-.Op Fl adlLmuv
-.Ar destination-directory
-.No < Ar name-list
-.Sh DESCRIPTION
-The
-.Nm
-command copies files to and from a
-.Nm
-archive.
-.Pp
-The options are as follows:
-.Bl -tag -width indent
-.It Fl o
-Create an archive.
-Reads the list of files to store in the
-archive from standard input, and writes the archive on standard
-output.
-.Bl -tag -width indent
-.It Fl a
-Reset the access times on files that have been copied to the
-archive.
-.It Fl A
-Append to the specified archive.
-.It Fl B
-Set block size of output to 5120 bytes.
-.It Fl c
-Use
-.Tn ASCII
-format for
-.Nm
-header for portability.
-.It Fl C Ar bytes
-Set the block size of output to
-.Ar bytes .
-.It Fl F Ar archive
-.It Fl O Ar archive
-Use the specified file name as the archive to write to.
-.It Fl H Ar format
-Write the archive in the specified format.
-Recognized formats are:
-.Pp
-.Bl -tag -width sv4cpio -compact
-.It Cm bcpio
-Old binary
-.Nm
-format.
-.It Cm cpio
-Old octal character
-.Nm
-format.
-.It Cm sv4cpio
-.Tn SVR4
-hex
-.Nm
-format.
-.It Cm tar
-Old tar format.
-.It Cm ustar
-.Tn POSIX
-ustar format.
-.El
-.It Fl L
-Follow symbolic links.
-.It Fl v
-Be verbose about operations.
-List filenames as they are written to the archive.
-.It Fl z
-Compress archive using
-.Xr gzip 1
-format.
-.It Fl Z
-Compress archive using
-.Xr compress 1
-format.
-.El
-.It Fl i
-Restore files from an archive.
-Reads the archive file from
-standard input and extracts files matching the
-.Ar patterns
-that were specified on the command line.
-.Bl -tag -width indent
-.It Fl b
-Do byte and word swapping after reading in data from the
-archive, for restoring archives created on systems with
-a different byte order.
-.It Fl B
-Set the block size of the archive being read to 5120 bytes.
-.It Fl c
-Expect the archive headers to be in
-.Tn ASCII
-format.
-.It Fl C Ar bytes
-Read archive written with a block size of
-.Ar bytes .
-.It Fl d
-Create any intermediate directories as needed during
-restore.
-.It Fl E Ar file
-Read list of file name patterns to extract or list from
-.Ar file .
-.It Fl f
-Restore all files except those matching the
-.Ar patterns
-given on the command line.
-.It Fl F Ar archive , Fl I Ar archive
-Use the specified file as the input for the archive.
-.It Fl H Ar format
-Read an archive of the specified format.
-Recognized formats are:
-.Pp
-.Bl -tag -width sv4cpio -compact
-.It Cm bcpio
-Old binary
-.Nm
-format.
-.It Cm cpio
-Old octal character
-.Nm
-format.
-.It Cm sv4cpio
-.Tn SVR4
-hex
-.Nm
-format.
-.It Cm tar
-Old tar format.
-.It Cm ustar
-.Tn POSIX
-ustar format.
-.El
-.It Fl m
-Restore modification times on files.
-.It Fl r
-Rename restored files interactively.
-.It Fl s
-Swap bytes after reading data from the archive.
-.It Fl S
-Swap words after reading data from the archive.
-.It Fl t
-Only list the contents of the archive, no files or
-directories will be created.
-.It Fl u
-Overwrite files even when the file in the archive is
-older than the one that will be overwritten.
-.It Fl v
-Be verbose about operations.
-List filenames as they are copied in from the archive.
-.It Fl z
-Uncompress archive using
-.Xr gzip 1
-format.
-.It Fl Z
-Uncompress archive using
-.Xr compress 1
-format.
-.It Fl 6
-Process old-style
-.Nm
-format archives.
-.El
-.It Fl p
-Copy files from one location to another in a single pass.
-The list of files to copy are read from standard input and
-written out to a directory relative to the specified
-.Ar directory
-argument.
-.Bl -tag -width indent
-.It Fl a
-Reset the access times on files that have been copied.
-.It Fl d
-Create any intermediate directories as needed to write
-the files at the new location.
-.It Fl l
-When possible, link files rather than creating an
-extra copy.
-.It Fl L
-Follow symbolic links.
-.It Fl m
-Restore modification times on files.
-.It Fl u
-Overwrite files even when the original file being copied is
-older than the one that will be overwritten.
-.It Fl v
-Be verbose about operations.
-List filenames as they are copied.
-.El
-.El
-.Sh ENVIRONMENT
-.Bl -tag -width TMPDIR
-.It Ev TMPDIR
-Path in which to store temporary files.
-.El
-.Sh EXIT STATUS
-The
-.Nm
-utility will exit with one of the following values:
-.Bl -tag -width 2n
-.It 0
-All files were processed successfully.
-.It 1
-An error occurred.
-.El
-.Pp
-Whenever
-.Nm
-cannot create a file or a link when extracting an archive or cannot
-find a file while writing an archive, or cannot preserve the user
-ID, group ID, file mode, or access and modification times when the
-.Fl p
-option is specified, a diagnostic message is written to standard
-error and a non-zero exit value will be returned, but processing
-will continue.
-In the case where
-.Nm
-cannot create a link to a file,
-.Nm
-will not create a second copy of the file.
-.Pp
-If the extraction of a file from an archive is prematurely terminated
-by a signal or error,
-.Nm
-may have only partially extracted the file the user wanted.
-Additionally, the file modes of extracted files and directories may
-have incorrect file bits, and the modification and access times may
-be wrong.
-.Pp
-If the creation of an archive is prematurely terminated by a signal
-or error,
-.Nm
-may have only partially created the archive which may violate the
-specific archive format specification.
-.Sh SEE ALSO
-.Xr pax 1 ,
-.Xr tar 1
-.Sh AUTHORS
-.An Keith Muller
-at the University of California, San Diego.
-.Sh BUGS
-The
-.Fl s
-and
-.Fl S
-options are currently not implemented.
diff --git a/bin/pax/getoldopt.c b/bin/pax/getoldopt.c
index 1c9f63c..2871721 100644
--- a/bin/pax/getoldopt.c
+++ b/bin/pax/getoldopt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getoldopt.c,v 1.4 2000/01/22 20:24:51 deraadt Exp $ */
+/* $OpenBSD: getoldopt.c,v 1.9 2009/10/27 23:59:22 deraadt Exp $ */
/* $NetBSD: getoldopt.c,v 1.3 1995/03/21 09:07:28 cgd Exp $ */
/*-
@@ -7,7 +7,7 @@
* otherwise, it uses the old rules used by tar, dump, and ps.
*
* Written 25 August 1985 by John Gilmore (ihnp4!hoptoad!gnu) and placed
- * in the Pubic Domain for your edification and enjoyment.
+ * in the Public Domain for your edification and enjoyment.
*/
#include <sys/cdefs.h>
@@ -33,7 +33,8 @@ getoldopt(int argc, char **argv, const char *optstring)
optarg = NULL;
if (key == NULL) { /* First time */
- if (argc < 2) return EOF;
+ if (argc < 2)
+ return (-1);
key = argv[1];
if (*key == '-')
use_getopt++;
@@ -42,18 +43,18 @@ getoldopt(int argc, char **argv, const char *optstring)
}
if (use_getopt)
- return getopt(argc, argv, optstring);
+ return (getopt(argc, argv, optstring));
c = *key++;
if (c == '\0') {
key--;
- return EOF;
+ return (-1);
}
place = strchr(optstring, c);
if (place == NULL || c == ':') {
fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
- return('?');
+ return ('?');
}
place++;
@@ -64,9 +65,9 @@ getoldopt(int argc, char **argv, const char *optstring)
} else {
fprintf(stderr, "%s: %c argument missing\n",
argv[0], c);
- return('?');
+ return ('?');
}
}
- return(c);
+ return (c);
}
diff --git a/bin/pax/tar.1 b/bin/pax/tar.1
deleted file mode 100644
index ff66ccb..0000000
--- a/bin/pax/tar.1
+++ /dev/null
@@ -1,310 +0,0 @@
-.\"-
-.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
-.\" 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.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by SigmaSoft, Th. Lockert.
-.\" 4. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-.\"
-.\" $OpenBSD: tar.1,v 1.33 2001/05/01 17:58:01 aaron Exp $
-.\" $FreeBSD$
-.\"
-.Dd February 7, 2001
-.Dt TAR 1
-.Os
-.Sh NAME
-.Nm tar
-.Nd tape archiver
-.Sh SYNOPSIS
-.Nm
-.Sm off
-.Op Fl
-.Brq Cm crtux
-.Op Cm befhjmopqsvwyzHLOPXZ014578
-.Sm on
-.Op Ar blocksize
-.Op Ar archive
-.Op Ar replstr
-.\" XXX how to do this right?
-.Op Fl C Ar directory
-.Op Fl I Ar file
-.Op Ar
-.Sh DESCRIPTION
-The
-.Nm
-command creates, adds files to, or extracts files from an
-archive file in
-.Nm
-format.
-A
-.Nm
-archive is often stored on a magnetic tape, but can be
-stored equally well on a floppy, CD-ROM, or in a regular disk file.
-.Pp
-One of the following flags must be present:
-.Bl -tag -width indent
-.It Fl c
-Create new archive, or overwrite an existing archive,
-adding the specified files to it.
-.It Fl r
-Append the named new files to existing archive.
-Note that this will only work on media on which an end-of-file mark
-can be overwritten.
-.It Fl t
-List contents of archive.
-If any files are named on the
-command line, only those files will be listed.
-.It Fl u
-Alias for
-.Fl r .
-.It Fl x
-Extract files from archive.
-If any files are named on the
-command line, only those files will be extracted from the
-archive.
-If more than one copy of a file exists in the
-archive, later copies will overwrite earlier copies during
-extraction.
-The file mode and modification time are preserved
-if possible.
-The file mode is subject to modification by the
-.Xr umask 2 .
-.El
-.Pp
-In addition to the flags mentioned above, any of the following
-flags may be used:
-.Bl -tag -width indent
-.It Fl b Ar "blocking factor"
-Set blocking factor to use for the archive, with 512 byte blocks.
-The default is 20, the maximum is 126.
-Archives with a blocking factor larger 63 violate the
-.Tn POSIX
-standard and will not be portable to all systems.
-.It Fl e
-Stop after first error.
-.It Fl f Ar archive
-Filename where the archive is stored.
-Defaults to
-.Pa /dev/sa0 .
-.It Fl h
-Follow symbolic links as if they were normal files
-or directories.
-.It Fl j
-Compress archives using
-.Xr bzip2 1 .
-.It Fl m
-Do not preserve modification time.
-.It Fl O
-Write old-style
-.Pq non- Ns Tn POSIX
-archives.
-.It Fl o
-Do not write directory information that the older (V7) style
-.Nm
-is unable to decode.
-This implies the
-.Fl O
-flag.
-.It Fl p
-Preserve user and group ID as well as file mode regardless of
-the current
-.Xr umask 2 .
-The setuid and setgid bits are only preserved if the user is
-the superuser.
-Only meaningful in conjunction with the
-.Fl x
-flag.
-.It Fl q
-Select the first archive member that matches each
-.Ar pattern
-operand.
-No more than one archive member is matched for each
-.Ar pattern .
-When members of type directory are matched, the file hierarchy rooted at that
-directory is also matched.
-.It Fl s Ar replstr
-Modify the file or archive member names specified by the
-.Ar pattern
-or
-.Ar file
-operands according to the substitution expression
-.Ar replstr ,
-using the syntax of the
-.Xr ed 1
-utility regular expressions.
-The format of these regular expressions are:
-.Dl /old/new/[gp]
-As in
-.Xr ed 1 ,
-.Cm old
-is a basic regular expression and
-.Cm new
-can contain an ampersand
-.Pq Ql & ,
-.Li \e Ns Ar n
-(where
-.Ar n
-is a digit) back-references,
-or subexpression matching.
-The
-.Cm old
-string may also contain newline characters.
-Any non-null character can be used as a delimiter
-.Ql ( /
-is shown here).
-Multiple
-.Fl s
-expressions can be specified.
-The expressions are applied in the order they are specified on the
-command line, terminating with the first successful substitution.
-The optional trailing
-.Cm g
-continues to apply the substitution expression to the pathname substring
-which starts with the first character following the end of the last successful
-substitution.
-The first unsuccessful substitution stops the operation of the
-.Cm g
-option.
-The optional trailing
-.Cm p
-will cause the final result of a successful substitution to be written to
-standard error
-in the following format:
-.Pp
-.Dl <original pathname> >> <new pathname>
-.Pp
-File or archive member names that substitute to the empty string
-are not selected and will be skipped.
-.It Fl v
-Verbose operation mode.
-.It Fl w
-Interactively rename files.
-This option causes
-.Nm
-to prompt the user for the filename to use when storing or
-extracting files in an archive.
-.It Fl y
-Compress archives using
-.Xr bzip2 1 .
-.It Fl z
-Compress archive using
-.Xr gzip 1 .
-.It Fl C Ar directory
-This is a positional argument which sets the working directory for the
-following files.
-When extracting, files will be extracted into
-the specified directory; when creating, the specified files will be matched
-from the directory.
-.It Fl H
-Follow symlinks given on command line only.
-.It Fl L
-Follow all symlinks.
-.It Fl P
-Do not strip leading slashes
-.Pq Ql /
-from pathnames.
-The default is to strip leading slashes.
-.It Fl I Ar file
-This is a positional argument which reads the names of files to
-archive or extract from the given file, one per line.
-.It Fl X
-Do not cross mount points in the file system.
-.It Fl Z
-Compress archive using
-.Xr compress 1 .
-.El
-.Pp
-The options
-.Op Fl 014578
-can be used to select one of the compiled-in backup devices,
-.Pa /dev/rst Ns Ar N .
-.Sh ENVIRONMENT
-.Bl -tag -width TMPDIR
-.It Ev TMPDIR
-Path in which to store temporary files.
-.It Ev TAPE
-Default tape device to use instead of
-.Pa /dev/sa0 .
-.El
-.Sh FILES
-.Bl -tag -width "/dev/sa0"
-.It Pa /dev/sa0
-default archive name
-.El
-.Sh EXIT STATUS
-The
-.Nm
-utility will exit with one of the following values:
-.Bl -tag -width 2n
-.It 0
-All files were processed successfully.
-.It 1
-An error occurred.
-.El
-.Pp
-Whenever
-.Nm
-cannot create a file or a link when extracting an archive or cannot
-find a file while writing an archive, or cannot preserve the user
-ID, group ID, file mode, or access and modification times when the
-.Fl p
-option is specified, a diagnostic message is written to standard
-error and a non-zero exit value will be returned, but processing
-will continue.
-In the case where
-.Nm
-cannot create a link to a file,
-.Nm
-will not create a second copy of the file.
-.Pp
-If the extraction of a file from an archive is prematurely terminated
-by a signal or error,
-.Nm
-may have only partially extracted the file the user wanted.
-Additionally, the file modes of extracted files and directories may
-have incorrect file bits, and the modification and access times may
-be wrong.
-.Pp
-If the creation of an archive is prematurely terminated by a signal
-or error,
-.Nm
-may have only partially created the archive which may violate the
-specific archive format specification.
-.Sh COMPATIBILITY
-The
-.Fl L
-flag is not portable to other versions of
-.Nm
-where it may have a different meaning.
-.Sh SEE ALSO
-.Xr cpio 1 ,
-.Xr pax 1
-.Sh HISTORY
-A
-.Nm
-command first appeared in
-.At v7 .
-.Sh AUTHORS
-.An Keith Muller
-at the University of California, San Diego.
diff --git a/bin/ps/extern.h b/bin/ps/extern.h
index c441278..45d76a6 100644
--- a/bin/ps/extern.h
+++ b/bin/ps/extern.h
@@ -48,6 +48,7 @@ void command(KINFO *, VARENT *);
void cputime(KINFO *, VARENT *);
int donlist(void);
void elapsed(KINFO *, VARENT *);
+void elapseds(KINFO *, VARENT *);
void emulname(KINFO *, VARENT *);
VARENT *find_varentry(VAR *);
const char *fmt_argv(char **, char *, size_t);
diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c
index 4524d99..237b579 100644
--- a/bin/ps/keyword.c
+++ b/bin/ps/keyword.c
@@ -89,6 +89,7 @@ static VAR var[] = {
{"emul", "EMUL", NULL, LJUST, emulname, NULL, EMULLEN, 0, CHAR,
NULL, 0},
{"etime", "ELAPSED", NULL, USER, elapsed, NULL, 12, 0, CHAR, NULL, 0},
+ {"etimes", "ELAPSED", NULL, USER, elapseds, NULL, 12, 0, CHAR, NULL, 0},
{"f", "F", NULL, 0, kvar, NULL, 7, KOFF(ki_flag), INT, "x", 0},
{"flags", "", "f", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"ignored", "", "sigignore", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
diff --git a/bin/ps/print.c b/bin/ps/print.c
index aa4f98f..cc33cdd 100644
--- a/bin/ps/print.c
+++ b/bin/ps/print.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <nlist.h>
#include <pwd.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -618,6 +619,21 @@ elapsed(KINFO *k, VARENT *ve)
(void)printf("%*s", v->width, obuff);
}
+void
+elapseds(KINFO *k, VARENT *ve)
+{
+ VAR *v;
+ time_t val;
+
+ v = ve->var;
+ if (!k->ki_valid) {
+ (void)printf("%-*s", v->width, "-");
+ return;
+ }
+ val = now - k->ki_p->ki_start.tv_sec;
+ (void)printf("%*jd", v->width, (intmax_t)val);
+}
+
double
getpcpu(const KINFO *k)
{
diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
index 46a371c..22373bd 100644
--- a/bin/ps/ps.1
+++ b/bin/ps/ps.1
@@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd July 9, 2009
+.Dd April 13, 2010
.Dt PS 1
.Os
.Sh NAME
@@ -284,11 +284,10 @@ The percentage of real memory used by this process.
The flags associated with the process as in
the include file
.In sys/proc.h :
-.Bl -column P_STOPPED_SINGLE 0x4000000
+.Bl -column P_SINGLE_BOUNDARY 0x40000000
.It Dv "P_ADVLOCK" Ta No "0x00001 Process may hold a POSIX advisory lock"
.It Dv "P_CONTROLT" Ta No "0x00002 Has a controlling terminal"
.It Dv "P_KTHREAD" Ta No "0x00004 Kernel thread"
-.It Dv "P_NOLOAD" Ta No "0x00008 Ignore during load avg calculations"
.It Dv "P_PPWAIT" Ta No "0x00010 Parent is waiting for child to exec/exit"
.It Dv "P_PROFIL" Ta No "0x00020 Has started profiling"
.It Dv "P_STOPPROF" Ta No "0x00040 Has thread in requesting to stop prof"
@@ -299,14 +298,21 @@ the include file
.It Dv "P_WAITED" Ta No "0x01000 Someone is waiting for us"
.It Dv "P_WEXIT" Ta No "0x02000 Working on exiting"
.It Dv "P_EXEC" Ta No "0x04000 Process called exec"
+.It Dv "P_WKILLED" Ta No "0x08000 Killed, shall go to kernel/user boundary ASAP"
.It Dv "P_CONTINUED" Ta No "0x10000 Proc has continued from a stopped state"
.It Dv "P_STOPPED_SIG" Ta No "0x20000 Stopped due to SIGSTOP/SIGTSTP"
.It Dv "P_STOPPED_TRACE" Ta No "0x40000 Stopped because of tracing"
.It Dv "P_STOPPED_SINGLE" Ta No "0x80000 Only one thread can continue"
.It Dv "P_PROTECTED" Ta No "0x100000 Do not kill on memory overcommit"
.It Dv "P_SIGEVENT" Ta No "0x200000 Process pending signals changed"
+.It Dv "P_SINGLE_BOUNDARY" Ta No "0x400000 Threads should suspend at user boundary"
+.It Dv "P_HWPMC" Ta No "0x800000 Process is using HWPMCs"
.It Dv "P_JAILED" Ta No "0x1000000 Process is in jail"
.It Dv "P_INEXEC" Ta No "0x4000000 Process is in execve()"
+.It Dv "P_STATCHILD" Ta No "0x8000000 Child process stopped or exited"
+.It Dv "P_INMEM" Ta No "0x10000000 Loaded into memory"
+.It Dv "P_SWAPPINGOUT" Ta No "0x20000000 Process is being swapped out"
+.It Dv "P_SWAPPINGIN" Ta No "0x40000000 Process is being swapped in"
.El
.It Cm label
The MAC label of the process.
@@ -474,7 +480,12 @@ command and arguments
.It Cm cpu
short-term CPU usage factor (for scheduling)
.It Cm etime
-elapsed running time
+elapsed running time, format
+.Op days- Ns
+.Op hours: Ns
+minutes:seconds.
+.It Cm etimes
+elapsed running time, in decimal integer seconds
.It Cm flags
the process flags, in hexadecimal (alias
.Cm f )
@@ -615,6 +626,13 @@ wait channel (as a symbolic name)
.It Cm xstat
exit or stop status (valid only for stopped or zombie process)
.El
+.Pp
+Note that the
+.Cm pending
+column displays bitmask of signals pending in the process queue when
+.Fl H
+option is not specified, otherwise the per-thread queue of pending signals
+is shown.
.Sh ENVIRONMENT
The following environment variables affect the execution of
.Nm :
diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1
index 132d83c..f36090d 100644
--- a/bin/pwait/pwait.1
+++ b/bin/pwait/pwait.1
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd November 1, 2009
-.Os
.Dt PWAIT 1
+.Os
.Sh NAME
.Nm pwait
.Nd wait for processes to terminate
diff --git a/bin/rcp/rcp.c b/bin/rcp/rcp.c
index 0a9b7ba..2c27b63 100644
--- a/bin/rcp/rcp.c
+++ b/bin/rcp/rcp.c
@@ -390,8 +390,8 @@ syserr: run_err("%s: %s", name, strerror(errno));
* versions expecting microseconds.
*/
(void)snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
- (long)stb.st_mtimespec.tv_sec,
- (long)stb.st_atimespec.tv_sec);
+ (long)stb.st_mtim.tv_sec,
+ (long)stb.st_atim.tv_sec);
(void)write(rem, buf, strlen(buf));
if (response() < 0)
goto next;
@@ -454,8 +454,8 @@ rsource(char *name, struct stat *statp)
last++;
if (pflag) {
(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
- (long)statp->st_mtimespec.tv_sec,
- (long)statp->st_atimespec.tv_sec);
+ (long)statp->st_mtim.tv_sec,
+ (long)statp->st_atim.tv_sec);
(void)write(rem, path, strlen(path));
if (response() < 0) {
closedir(dirp);
diff --git a/bin/setfacl/file.c b/bin/setfacl/file.c
index 5996d55..c44f398 100644
--- a/bin/setfacl/file.c
+++ b/bin/setfacl/file.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/bin/setfacl/mask.c b/bin/setfacl/mask.c
index 5478302..05007a1 100644
--- a/bin/setfacl/mask.c
+++ b/bin/setfacl/mask.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/bin/setfacl/merge.c b/bin/setfacl/merge.c
index 0a42eec..9d8e67a 100644
--- a/bin/setfacl/merge.c
+++ b/bin/setfacl/merge.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/bin/setfacl/remove.c b/bin/setfacl/remove.c
index e6feef9..35c735e 100644
--- a/bin/setfacl/remove.c
+++ b/bin/setfacl/remove.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/bin/setfacl/setfacl.1 b/bin/setfacl/setfacl.1
index f527bbb..5f6ee14 100644
--- a/bin/setfacl/setfacl.1
+++ b/bin/setfacl/setfacl.1
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/bin/setfacl/setfacl.c b/bin/setfacl/setfacl.c
index 2835ba8..42f4731 100644
--- a/bin/setfacl/setfacl.c
+++ b/bin/setfacl/setfacl.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/bin/setfacl/setfacl.h b/bin/setfacl/setfacl.h
index 290ac5b..84fdd92 100644
--- a/bin/setfacl/setfacl.h
+++ b/bin/setfacl/setfacl.h
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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$
*/
diff --git a/bin/setfacl/util.c b/bin/setfacl/util.c
index a7fb6a6..60f5b24 100644
--- a/bin/setfacl/util.c
+++ b/bin/setfacl/util.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/bin/sh/arith.y b/bin/sh/arith.y
index 5db1633..28046ba 100644
--- a/bin/sh/arith.y
+++ b/bin/sh/arith.y
@@ -287,7 +287,9 @@ arith_t
arith(const char *s)
{
arith_t result;
+ struct stackmark smark;
+ setstackmark(&smark);
arith_buf = arith_startbuf = s;
INTOFF;
@@ -295,6 +297,8 @@ arith(const char *s)
arith_lex_reset(); /* Reprime lex. */
INTON;
+ popstackmark(&smark);
+
return result;
}
diff --git a/bin/sh/arith_lex.l b/bin/sh/arith_lex.l
index f0d9cb3..aede40f 100644
--- a/bin/sh/arith_lex.l
+++ b/bin/sh/arith_lex.l
@@ -51,13 +51,6 @@ __FBSDID("$FreeBSD$");
int yylex(void);
-struct varname
-{
- struct varname *next;
- char name[1];
-};
-static struct varname *varnames;
-
#undef YY_INPUT
#define YY_INPUT(buf,result,max) \
result = (*buf = *arith_buf++) ? 1 : YY_NULL;
@@ -87,14 +80,11 @@ static struct varname *varnames;
* If variable doesn't exist, we should initialize
* it to zero.
*/
- struct varname *temp;
+ char *temp;
if (lookupvar(yytext) == NULL)
setvarsafe(yytext, "0", 0);
- temp = ckmalloc(sizeof(struct varname) +
- strlen(yytext));
- temp->next = varnames;
- varnames = temp;
- yylval.s_value = strcpy(temp->name, yytext);
+ temp = stalloc(strlen(yytext) + 1);
+ yylval.s_value = strcpy(temp, yytext);
return ARITH_VAR;
}
@@ -140,15 +130,5 @@ static struct varname *varnames;
void
arith_lex_reset(void)
{
- struct varname *name, *next;
-
YY_NEW_FILE;
-
- name = varnames;
- while (name != NULL) {
- next = name->next;
- ckfree(name);
- name = next;
- }
- varnames = NULL;
}
diff --git a/bin/sh/cd.c b/bin/sh/cd.c
index 40801ba..aee06e8 100644
--- a/bin/sh/cd.c
+++ b/bin/sh/cd.c
@@ -70,6 +70,7 @@ STATIC int docd(char *, int, int);
STATIC char *getcomponent(void);
STATIC char *findcwd(char *);
STATIC void updatepwd(char *);
+STATIC char *getpwd(void);
STATIC char *getpwd2(void);
STATIC char *curdir = NULL; /* current working directory */
@@ -351,7 +352,7 @@ pwdcmd(int argc, char **argv)
/*
* Get the current directory and cache the result in curdir.
*/
-char *
+STATIC char *
getpwd(void)
{
char *p;
@@ -374,7 +375,6 @@ getpwd(void)
STATIC char *
getpwd2(void)
{
- struct stat stdot, stpwd;
char *pwd;
int i;
@@ -387,12 +387,29 @@ getpwd2(void)
break;
}
- pwd = getenv("PWD");
+ return NULL;
+}
+
+/*
+ * Initialize PWD in a new shell.
+ * If the shell is interactive, we need to warn if this fails.
+ */
+void
+pwd_init(int warn)
+{
+ char *pwd;
+ struct stat stdot, stpwd;
+
+ pwd = lookupvar("PWD");
if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
- return pwd;
+ if (curdir)
+ ckfree(curdir);
+ curdir = savestr(pwd);
}
- return NULL;
+ if (getpwd() == NULL && warn)
+ out2fmt_flush("sh: cannot determine working directory\n");
+ setvar("PWD", curdir, VEXPORT);
}
diff --git a/bin/sh/cd.h b/bin/sh/cd.h
index 0a2d489..f88ce26 100644
--- a/bin/sh/cd.h
+++ b/bin/sh/cd.h
@@ -29,6 +29,6 @@
* $FreeBSD$
*/
-char *getpwd(void);
+void pwd_init(int);
int cdcmd (int, char **);
int pwdcmd(int, char **);
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 30e05b8..e93fb14 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -91,6 +91,7 @@ STATIC void evalloop(union node *, int);
STATIC void evalfor(union node *, int);
STATIC void evalcase(union node *, int);
STATIC void evalsubshell(union node *, int);
+STATIC void evalredir(union node *, int);
STATIC void expredir(union node *);
STATIC void evalpipe(union node *);
STATIC void evalcommand(union node *, int, struct backcmd *);
@@ -221,10 +222,7 @@ evaltree(union node *n, int flags)
evaltree(n->nbinary.ch2, flags);
break;
case NREDIR:
- expredir(n->nredir.redirect);
- redirect(n->nredir.redirect, REDIR_PUSH);
- evaltree(n->nredir.n, flags);
- popredir();
+ evalredir(n, flags);
break;
case NSUBSHELL:
evalsubshell(n, flags);
@@ -415,6 +413,46 @@ evalsubshell(union node *n, int flags)
}
+/*
+ * Evaluate a redirected compound command.
+ */
+
+STATIC void
+evalredir(union node *n, int flags)
+{
+ struct jmploc jmploc;
+ struct jmploc *savehandler;
+ volatile int in_redirect = 1;
+
+ expredir(n->nredir.redirect);
+ savehandler = handler;
+ if (setjmp(jmploc.loc)) {
+ int e;
+
+ handler = savehandler;
+ e = exception;
+ if (e == EXERROR || e == EXEXEC) {
+ popredir();
+ if (in_redirect) {
+ exitstatus = 2;
+ return;
+ }
+ }
+ longjmp(handler->loc, 1);
+ } else {
+ INTOFF;
+ handler = &jmploc;
+ redirect(n->nredir.redirect, REDIR_PUSH);
+ in_redirect = 0;
+ INTON;
+ evaltree(n->nredir.n, flags);
+ }
+ INTOFF;
+ handler = savehandler;
+ popredir();
+ INTON;
+}
+
/*
* Compute the names of the files in a redirection list.
@@ -597,6 +635,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
char *lastarg;
int realstatus;
int do_clearcmdentry;
+ char *path = pathval();
/* First expand the arguments. */
TRACE(("evalcommand(%p, %d) called\n", (void *)cmd, flags));
@@ -679,10 +718,10 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
/* Variable assignment(s) without command */
cmdentry.cmdtype = CMDBUILTIN;
cmdentry.u.index = BLTINCMD;
- cmdentry.special = 1;
+ cmdentry.special = 0;
} else {
static const char PATH[] = "PATH=";
- char *path = pathval();
+ int cmd_flags = 0, bltinonly = 0;
/*
* Modify the command lookup path, if a PATH= assignment
@@ -713,24 +752,68 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
do_clearcmdentry = 1;
}
- find_command(argv[0], &cmdentry, 0, path);
- /* implement the bltin builtin here */
- if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) {
- for (;;) {
- argv++;
- if (--argc == 0)
- break;
- if ((cmdentry.u.index = find_builtin(*argv,
- &cmdentry.special)) < 0) {
+ for (;;) {
+ if (bltinonly) {
+ cmdentry.u.index = find_builtin(*argv, &cmdentry.special);
+ if (cmdentry.u.index < 0) {
cmdentry.u.index = BLTINCMD;
argv--;
argc++;
break;
}
- if (cmdentry.u.index != BLTINCMD)
+ } else
+ find_command(argv[0], &cmdentry, cmd_flags, path);
+ /* implement the bltin and command builtins here */
+ if (cmdentry.cmdtype != CMDBUILTIN)
+ break;
+ if (cmdentry.u.index == BLTINCMD) {
+ if (argc == 1)
break;
- }
+ argv++;
+ argc--;
+ bltinonly = 1;
+ } else if (cmdentry.u.index == COMMANDCMD) {
+ if (argc == 1)
+ break;
+ if (!strcmp(argv[1], "-p")) {
+ if (argc == 2)
+ break;
+ if (argv[2][0] == '-') {
+ if (strcmp(argv[2], "--"))
+ break;
+ if (argc == 3)
+ break;
+ argv += 3;
+ argc -= 3;
+ } else {
+ argv += 2;
+ argc -= 2;
+ }
+ path = _PATH_STDPATH;
+ clearcmdentry(0);
+ do_clearcmdentry = 1;
+ } else if (!strcmp(argv[1], "--")) {
+ if (argc == 2)
+ break;
+ argv += 2;
+ argc -= 2;
+ } else if (argv[1][0] == '-')
+ break;
+ else {
+ argv++;
+ argc--;
+ }
+ cmd_flags |= DO_NOFUNC;
+ bltinonly = 0;
+ } else
+ break;
}
+ /*
+ * Special builtins lose their special properties when
+ * called via 'command'.
+ */
+ if (cmd_flags & DO_NOFUNC)
+ cmdentry.special = 0;
}
/* Fork off a child process if necessary. */
@@ -741,9 +824,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
&& (cmdentry.cmdtype != CMDBUILTIN
|| cmdentry.u.index == CDCMD
|| cmdentry.u.index == DOTCMD
- || cmdentry.u.index == EVALCMD))
- || (cmdentry.cmdtype == CMDBUILTIN &&
- cmdentry.u.index == COMMANDCMD)) {
+ || cmdentry.u.index == EVALCMD))) {
jp = makejob(cmd, 1);
mode = cmd->ncmd.backgnd;
if (flags & EV_BACKCMD) {
@@ -770,7 +851,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
#ifdef DEBUG
trputs("Shell function: "); trargs(argv);
#endif
- redirect(cmd->ncmd.redirect, REDIR_PUSH);
saveparam = shellparam;
shellparam.malloc = 0;
shellparam.reset = 1;
@@ -788,6 +868,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
else {
freeparam(&shellparam);
shellparam = saveparam;
+ if (exception == EXERROR || exception == EXEXEC)
+ popredir();
}
unreffunc(cmdentry.u.func);
poplocalvars();
@@ -798,6 +880,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
}
handler = &jmploc;
funcnest++;
+ redirect(cmd->ncmd.redirect, REDIR_PUSH);
INTON;
for (sp = varlist.list ; sp ; sp = sp->next)
mklocal(sp->text);
@@ -846,6 +929,12 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
}
handler = &jmploc;
redirect(cmd->ncmd.redirect, mode);
+ /*
+ * If there is no command word, redirection errors should
+ * not be fatal but assignment errors should.
+ */
+ if (argc == 0 && !(flags & EV_BACKCMD))
+ cmdentry.special = 1;
if (cmdentry.special)
listsetvar(cmdenviron);
commandname = argv[0];
@@ -871,6 +960,9 @@ cmddone:
backcmd->nleft = memout.nextc - memout.buf;
memout.buf = NULL;
}
+ if (cmdentry.u.index != EXECCMD &&
+ (e == -1 || e == EXERROR || e == EXEXEC))
+ popredir();
if (e != -1) {
if ((e != EXERROR && e != EXEXEC)
|| cmdentry.special)
@@ -879,8 +971,6 @@ cmddone:
if (flags != EV_BACKCMD)
FORCEINTON;
}
- if (cmdentry.u.index != EXECCMD)
- popredir();
} else {
#ifdef DEBUG
trputs("normal command: "); trargs(argv);
@@ -889,7 +979,7 @@ cmddone:
for (sp = varlist.list ; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
envp = environment();
- shellexec(argv, envp, pathval(), cmdentry.u.index);
+ shellexec(argv, envp, path, cmdentry.u.index);
/*NOTREACHED*/
}
goto out;
@@ -996,15 +1086,11 @@ int
commandcmd(int argc, char **argv)
{
static char stdpath[] = _PATH_STDPATH;
- struct jmploc loc, *old;
- struct strlist *sp;
char *path;
int ch;
int cmd = -1;
- for (sp = cmdenviron; sp ; sp = sp->next)
- setvareq(sp->text, VEXPORT|VSTACK);
- path = pathval();
+ path = bltinlookup("PATH", 1);
optind = optreset = 1;
opterr = 0;
@@ -1032,22 +1118,14 @@ commandcmd(int argc, char **argv)
error("wrong number of arguments");
return typecmd_impl(2, argv - 1, cmd, path);
}
- if (argc != 0) {
- old = handler;
- handler = &loc;
- if (setjmp(handler->loc) == 0)
- shellexec(argv, environment(), path, 0);
- handler = old;
- if (exception == EXEXEC)
- exit(exerrno);
- exraise(exception);
- }
+ if (argc != 0)
+ error("commandcmd() called while it should not be");
/*
* Do nothing successfully if no command was specified;
* ksh also does this.
*/
- exit(0);
+ return 0;
}
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index a28ab03..7c15f79 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -248,7 +248,7 @@ hashcmd(int argc __unused, char **argv __unused)
&& (cmdp->cmdtype == CMDNORMAL
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
delete_cmd_entry();
- find_command(name, &entry, 1, pathval());
+ find_command(name, &entry, DO_ERR, pathval());
if (verbose) {
if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */
cmdp = cmdlookup(name, 0);
@@ -310,10 +310,10 @@ printentry(struct tblentry *cmdp, int verbose)
*/
void
-find_command(const char *name, struct cmdentry *entry, int printerr,
+find_command(const char *name, struct cmdentry *entry, int act,
const char *path)
{
- struct tblentry *cmdp;
+ struct tblentry *cmdp, loc_cmd;
int idx;
int prev;
char *fullname;
@@ -330,13 +330,19 @@ find_command(const char *name, struct cmdentry *entry, int printerr,
}
/* If name is in the table, and not invalidated by cd, we're done */
- if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0)
- goto success;
+ if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
+ if (cmdp->cmdtype == CMDFUNCTION && act & DO_NOFUNC)
+ cmdp = NULL;
+ else
+ goto success;
+ }
/* If %builtin not in path, check for builtin next */
if (builtinloc < 0 && (i = find_builtin(name, &spec)) >= 0) {
INTOFF;
cmdp = cmdlookup(name, 1);
+ if (cmdp->cmdtype == CMDFUNCTION)
+ cmdp = &loc_cmd;
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
cmdp->special = spec;
@@ -365,6 +371,8 @@ loop:
goto loop;
INTOFF;
cmdp = cmdlookup(name, 1);
+ if (cmdp->cmdtype == CMDFUNCTION)
+ cmdp = &loc_cmd;
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
cmdp->special = spec;
@@ -414,6 +422,8 @@ loop:
TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
INTOFF;
cmdp = cmdlookup(name, 1);
+ if (cmdp->cmdtype == CMDFUNCTION)
+ cmdp = &loc_cmd;
cmdp->cmdtype = CMDNORMAL;
cmdp->param.index = idx;
INTON;
@@ -421,9 +431,9 @@ loop:
}
/* We failed. If there was an entry for this command, delete it */
- if (cmdp)
+ if (cmdp && cmdp->cmdtype != CMDFUNCTION)
delete_cmd_entry();
- if (printerr) {
+ if (act & DO_ERR) {
if (e == ENOENT || e == ENOTDIR)
outfmt(out2, "%s: not found\n", name);
else
diff --git a/bin/sh/exec.h b/bin/sh/exec.h
index 32bf131..45330a1 100644
--- a/bin/sh/exec.h
+++ b/bin/sh/exec.h
@@ -57,6 +57,10 @@ struct cmdentry {
};
+/* action to find_command() */
+#define DO_ERR 0x01 /* prints errors */
+#define DO_NOFUNC 0x02 /* don't return shell functions, for command */
+
extern const char *pathopt; /* set by padvance */
extern int exerrno; /* last exec error */
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 876cde1..7d98737 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -273,7 +273,6 @@ exptilde(char *p, int flag)
switch(c) {
case CTLESC: /* This means CTL* are always considered quoted. */
case CTLVAR:
- case CTLENDVAR:
case CTLBACKQ:
case CTLBACKQ | CTLQUOTE:
case CTLARI:
@@ -285,6 +284,7 @@ exptilde(char *p, int flag)
goto done;
break;
case '/':
+ case CTLENDVAR:
goto done;
}
p++;
@@ -360,7 +360,7 @@ removerecordregions(int endoff)
void
expari(int flag)
{
- char *p, *start;
+ char *p, *q, *start;
arith_t result;
int begoff;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
@@ -398,7 +398,9 @@ expari(int flag)
removerecordregions(begoff);
if (quotes)
rmescapes(p+2);
+ q = grabstackstr(expdest);
result = arith(p+2);
+ ungrabstackstr(q, expdest);
fmtstr(p, DIGITS(result), ARITH_FORMAT_STR, result);
while (*p++)
;
@@ -506,7 +508,9 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
int amount;
herefd = -1;
- argstr(p, 0);
+ argstr(p, (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX ||
+ subtype == VSTRIMRIGHT || subtype == VSTRIMRIGHTMAX ?
+ EXP_CASE : 0) | EXP_TILDE);
STACKSTRNUL(expdest);
herefd = saveherefd;
argbackq = saveargbackq;
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 50a8813..ecbb12d 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -153,10 +153,7 @@ main(int argc, char *argv[])
init();
setstackmark(&smark);
procargs(argc, argv);
- if (getpwd() == NULL && iflag)
- out2fmt_flush("sh: cannot determine working directory\n");
- if (getpwd() != NULL)
- setvar ("PWD", getpwd(), VEXPORT);
+ pwd_init(iflag);
if (iflag)
chkmail(1);
if (argv[0] && argv[0][0] == '-') {
diff --git a/bin/sh/mksyntax.c b/bin/sh/mksyntax.c
index 28a018b..7a38ad1 100644
--- a/bin/sh/mksyntax.c
+++ b/bin/sh/mksyntax.c
@@ -232,7 +232,6 @@ main(int argc __unused, char **argv __unused)
add("\n", "CNL");
add("\\", "CBACK");
add("`", "CBQUOTE");
- add("'", "CSQUOTE");
add("\"", "CDQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
diff --git a/bin/sh/options.c b/bin/sh/options.c
index bde96aa..3baeccc 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -93,8 +93,11 @@ procargs(int argc, char **argv)
options(1);
if (*argptr == NULL && minusc == NULL)
sflag = 1;
- if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
+ if (iflag != 0 && sflag == 1 && isatty(0) && isatty(1)) {
iflag = 1;
+ if (Eflag == 2)
+ Eflag = 1;
+ }
if (mflag == 2)
mflag = iflag;
for (i = 0; i < NOPTS; i++)
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index d8903c9..29ccd83 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -79,6 +79,10 @@ struct heredoc {
int striptabs; /* if set, strip leading tabs */
};
+struct parser_temp {
+ struct parser_temp *next;
+ void *data;
+};
STATIC struct heredoc *heredoclist; /* list of here documents to read */
@@ -94,6 +98,7 @@ STATIC struct heredoc *heredoc;
STATIC int quoteflag; /* set if (part of) last token was quoted */
STATIC int startlinno; /* line # where last token started */
STATIC int funclinno; /* line # where the current function started */
+STATIC struct parser_temp *parser_temp;
/* XXX When 'noaliases' is set to one, no alias expansion takes place. */
static int noaliases = 0;
@@ -117,6 +122,73 @@ STATIC void synerror(const char *);
STATIC void setprompt(int);
+STATIC void *
+parser_temp_alloc(size_t len)
+{
+ struct parser_temp *t;
+
+ INTOFF;
+ t = ckmalloc(sizeof(*t));
+ t->data = NULL;
+ t->next = parser_temp;
+ parser_temp = t;
+ t->data = ckmalloc(len);
+ INTON;
+ return t->data;
+}
+
+
+STATIC void *
+parser_temp_realloc(void *ptr, size_t len)
+{
+ struct parser_temp *t;
+
+ INTOFF;
+ t = parser_temp;
+ if (ptr != t->data)
+ error("bug: parser_temp_realloc misused");
+ t->data = ckrealloc(t->data, len);
+ INTON;
+ return t->data;
+}
+
+
+STATIC void
+parser_temp_free_upto(void *ptr)
+{
+ struct parser_temp *t;
+ int done = 0;
+
+ INTOFF;
+ while (parser_temp != NULL && !done) {
+ t = parser_temp;
+ parser_temp = t->next;
+ done = t->data == ptr;
+ ckfree(t->data);
+ ckfree(t);
+ }
+ INTON;
+ if (!done)
+ error("bug: parser_temp_free_upto misused");
+}
+
+
+STATIC void
+parser_temp_free_all(void)
+{
+ struct parser_temp *t;
+
+ INTOFF;
+ while (parser_temp != NULL) {
+ t = parser_temp;
+ parser_temp = t->next;
+ ckfree(t->data);
+ ckfree(t);
+ }
+ INTON;
+}
+
+
/*
* Read and parse a command. Returns NEOF on end of file. (NULL is a
* valid parse tree indicating a blank line.)
@@ -127,6 +199,11 @@ parsecmd(int interact)
{
int t;
+ /* This assumes the parser is not re-entered,
+ * which could happen if we add command substitution on PS1/PS2.
+ */
+ parser_temp_free_all();
+
tokpushback = 0;
doprompt = interact;
if (doprompt)
@@ -863,6 +940,179 @@ breakloop:
}
+#define MAXNEST_STATIC 8
+struct tokenstate
+{
+ const char *syntax; /* *SYNTAX */
+ int parenlevel; /* levels of parentheses in arithmetic */
+ enum tokenstate_category
+ {
+ TSTATE_TOP,
+ TSTATE_VAR_OLD, /* ${var+-=?}, inherits dquotes */
+ TSTATE_VAR_NEW, /* other ${var...}, own dquote state */
+ TSTATE_ARITH
+ } category;
+};
+
+
+/*
+ * Called to parse command substitutions.
+ */
+
+STATIC char *
+parsebackq(char *out, struct nodelist **pbqlist,
+ int oldstyle, int dblquote, int quoted)
+{
+ struct nodelist **nlpp;
+ union node *n;
+ char *volatile str;
+ struct jmploc jmploc;
+ struct jmploc *const savehandler = handler;
+ int savelen;
+ int saveprompt;
+ const int bq_startlinno = plinno;
+ char *volatile ostr = NULL;
+ struct parsefile *const savetopfile = getcurrentfile();
+
+ str = NULL;
+ if (setjmp(jmploc.loc)) {
+ popfilesupto(savetopfile);
+ if (str)
+ ckfree(str);
+ if (ostr)
+ ckfree(ostr);
+ handler = savehandler;
+ if (exception == EXERROR) {
+ startlinno = bq_startlinno;
+ synerror("Error in command substitution");
+ }
+ longjmp(handler->loc, 1);
+ }
+ INTOFF;
+ savelen = out - stackblock();
+ if (savelen > 0) {
+ str = ckmalloc(savelen);
+ memcpy(str, stackblock(), savelen);
+ }
+ handler = &jmploc;
+ INTON;
+ if (oldstyle) {
+ /* We must read until the closing backquote, giving special
+ treatment to some slashes, and then push the string and
+ reread it as input, interpreting it normally. */
+ char *oout;
+ int c;
+ int olen;
+
+
+ STARTSTACKSTR(oout);
+ for (;;) {
+ if (needprompt) {
+ setprompt(2);
+ needprompt = 0;
+ }
+ switch (c = pgetc()) {
+ case '`':
+ goto done;
+
+ case '\\':
+ if ((c = pgetc()) == '\n') {
+ plinno++;
+ if (doprompt)
+ setprompt(2);
+ else
+ setprompt(0);
+ /*
+ * If eating a newline, avoid putting
+ * the newline into the new character
+ * stream (via the STPUTC after the
+ * switch).
+ */
+ continue;
+ }
+ if (c != '\\' && c != '`' && c != '$'
+ && (!dblquote || c != '"'))
+ STPUTC('\\', oout);
+ break;
+
+ case '\n':
+ plinno++;
+ needprompt = doprompt;
+ break;
+
+ case PEOF:
+ startlinno = plinno;
+ synerror("EOF in backquote substitution");
+ break;
+
+ default:
+ break;
+ }
+ STPUTC(c, oout);
+ }
+done:
+ STPUTC('\0', oout);
+ olen = oout - stackblock();
+ INTOFF;
+ ostr = ckmalloc(olen);
+ memcpy(ostr, stackblock(), olen);
+ setinputstring(ostr, 1);
+ INTON;
+ }
+ nlpp = pbqlist;
+ while (*nlpp)
+ nlpp = &(*nlpp)->next;
+ *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
+ (*nlpp)->next = NULL;
+
+ if (oldstyle) {
+ saveprompt = doprompt;
+ doprompt = 0;
+ }
+
+ n = list(0);
+
+ if (oldstyle)
+ doprompt = saveprompt;
+ else {
+ if (readtoken() != TRP)
+ synexpect(TRP);
+ }
+
+ (*nlpp)->n = n;
+ if (oldstyle) {
+ /*
+ * Start reading from old file again, ignoring any pushed back
+ * tokens left from the backquote parsing
+ */
+ popfile();
+ tokpushback = 0;
+ }
+ while (stackblocksize() <= savelen)
+ growstackblock();
+ STARTSTACKSTR(out);
+ if (str) {
+ memcpy(out, str, savelen);
+ STADJUST(savelen, out);
+ INTOFF;
+ ckfree(str);
+ str = NULL;
+ INTON;
+ }
+ if (ostr) {
+ INTOFF;
+ ckfree(ostr);
+ ostr = NULL;
+ INTON;
+ }
+ handler = savehandler;
+ if (quoted)
+ USTPUTC(CTLBACKQ | CTLQUOTE, out);
+ else
+ USTPUTC(CTLBACKQ, out);
+ return out;
+}
+
/*
* If eofmark is NULL, read a word or a redirection symbol. If eofmark
@@ -879,12 +1129,10 @@ breakloop:
#define CHECKEND() {goto checkend; checkend_return:;}
#define PARSEREDIR() {goto parseredir; parseredir_return:;}
#define PARSESUB() {goto parsesub; parsesub_return:;}
-#define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
-#define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
#define PARSEARITH() {goto parsearith; parsearith_return:;}
STATIC int
-readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
+readtoken1(int firstc, char const *initialsyntax, char *eofmark, int striptabs)
{
int c = firstc;
char *out;
@@ -892,23 +1140,21 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
char line[EOFMARKLEN + 1];
struct nodelist *bqlist;
int quotef;
- int dblquote;
- int varnest; /* levels of variables expansion */
- int arinest; /* levels of arithmetic expansion */
- int parenlevel; /* levels of parens in arithmetic */
- int oldstyle;
- char const *prevsyntax; /* syntax before arithmetic */
+ int newvarnest;
+ int level;
int synentry;
+ struct tokenstate state_static[MAXNEST_STATIC];
+ int maxnest = MAXNEST_STATIC;
+ struct tokenstate *state = state_static;
startlinno = plinno;
- dblquote = 0;
- if (syntax == DQSYNTAX)
- dblquote = 1;
quotef = 0;
bqlist = NULL;
- varnest = 0;
- arinest = 0;
- parenlevel = 0;
+ newvarnest = 0;
+ level = 0;
+ state[level].syntax = initialsyntax;
+ state[level].parenlevel = 0;
+ state[level].category = TSTATE_TOP;
STARTSTACKSTR(out);
loop: { /* for each line, until end of word */
@@ -916,11 +1162,11 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
for (;;) { /* until end of line or end of word */
CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
- synentry = syntax[c];
+ synentry = state[level].syntax[c];
switch(synentry) {
case CNL: /* '\n' */
- if (syntax == BASESYNTAX)
+ if (state[level].syntax == BASESYNTAX)
goto endword; /* exit outer loop */
USTPUTC(c, out);
plinno++;
@@ -934,7 +1180,7 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
USTPUTC(c, out);
break;
case CCTL:
- if (eofmark == NULL || dblquote)
+ if (eofmark == NULL || initialsyntax != SQSYNTAX)
USTPUTC(CTLESC, out);
USTPUTC(c, out);
break;
@@ -950,41 +1196,37 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
else
setprompt(0);
} else {
- if (dblquote && c != '\\' &&
- c != '`' && c != '$' &&
- (c != '"' || eofmark != NULL))
+ if (state[level].syntax == DQSYNTAX &&
+ c != '\\' && c != '`' && c != '$' &&
+ (c != '"' || (eofmark != NULL &&
+ newvarnest == 0)) &&
+ (c != '}' || state[level].category != TSTATE_VAR_OLD))
USTPUTC('\\', out);
if (SQSYNTAX[c] == CCTL)
USTPUTC(CTLESC, out);
- else if (eofmark == NULL)
+ else if (eofmark == NULL ||
+ newvarnest > 0)
USTPUTC(CTLQUOTEMARK, out);
USTPUTC(c, out);
quotef++;
}
break;
case CSQUOTE:
- if (eofmark == NULL)
- USTPUTC(CTLQUOTEMARK, out);
- syntax = SQSYNTAX;
+ USTPUTC(CTLQUOTEMARK, out);
+ state[level].syntax = SQSYNTAX;
break;
case CDQUOTE:
- if (eofmark == NULL)
- USTPUTC(CTLQUOTEMARK, out);
- syntax = DQSYNTAX;
- dblquote = 1;
+ USTPUTC(CTLQUOTEMARK, out);
+ state[level].syntax = DQSYNTAX;
break;
case CENDQUOTE:
- if (eofmark != NULL && arinest == 0 &&
- varnest == 0) {
+ if (eofmark != NULL && newvarnest == 0)
USTPUTC(c, out);
- } else {
- if (arinest) {
- syntax = ARISYNTAX;
- dblquote = 0;
- } else if (eofmark == NULL) {
- syntax = BASESYNTAX;
- dblquote = 0;
- }
+ else {
+ if (state[level].category == TSTATE_ARITH)
+ state[level].syntax = ARISYNTAX;
+ else
+ state[level].syntax = BASESYNTAX;
quotef++;
}
break;
@@ -992,30 +1234,33 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
PARSESUB(); /* parse substitution */
break;
case CENDVAR: /* '}' */
- if (varnest > 0) {
- varnest--;
+ if (level > 0 &&
+ (state[level].category == TSTATE_VAR_OLD ||
+ state[level].category == TSTATE_VAR_NEW)) {
+ if (state[level].category == TSTATE_VAR_OLD)
+ state[level - 1].syntax = state[level].syntax;
+ else
+ newvarnest--;
+ level--;
USTPUTC(CTLENDVAR, out);
} else {
USTPUTC(c, out);
}
break;
case CLP: /* '(' in arithmetic */
- parenlevel++;
+ state[level].parenlevel++;
USTPUTC(c, out);
break;
case CRP: /* ')' in arithmetic */
- if (parenlevel > 0) {
+ if (state[level].parenlevel > 0) {
USTPUTC(c, out);
- --parenlevel;
+ --state[level].parenlevel;
} else {
if (pgetc() == ')') {
- if (--arinest == 0) {
+ if (level > 0 &&
+ state[level].category == TSTATE_ARITH) {
+ level--;
USTPUTC(CTLENDARI, out);
- syntax = prevsyntax;
- if (syntax == DQSYNTAX)
- dblquote = 1;
- else
- dblquote = 0;
} else
USTPUTC(')', out);
} else {
@@ -1029,12 +1274,15 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
}
break;
case CBQUOTE: /* '`' */
- PARSEBACKQOLD();
+ out = parsebackq(out, &bqlist, 1,
+ state[level].syntax == DQSYNTAX &&
+ (eofmark == NULL || newvarnest > 0),
+ state[level].syntax == DQSYNTAX || state[level].syntax == ARISYNTAX);
break;
case CEOF:
goto endword; /* exit outer loop */
default:
- if (varnest == 0)
+ if (level == 0)
goto endword; /* exit outer loop */
USTPUTC(c, out);
}
@@ -1042,14 +1290,17 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
}
}
endword:
- if (syntax == ARISYNTAX)
+ if (state[level].syntax == ARISYNTAX)
synerror("Missing '))'");
- if (syntax != BASESYNTAX && eofmark == NULL)
+ if (state[level].syntax != BASESYNTAX && eofmark == NULL)
synerror("Unterminated quoted string");
- if (varnest != 0) {
+ if (state[level].category == TSTATE_VAR_OLD ||
+ state[level].category == TSTATE_VAR_NEW) {
startlinno = plinno;
synerror("Missing '}'");
}
+ if (state != state_static)
+ parser_temp_free_upto(state);
USTPUTC('\0', out);
len = out - stackblock();
out = stackblock();
@@ -1072,7 +1323,6 @@ endword:
/* end of readtoken routine */
-
/*
* Check to see whether we are at the end of the here document. When this
* is called, c is set to the first character of the next input line. If
@@ -1189,7 +1439,11 @@ parsesub: {
PARSEARITH();
} else {
pungetc();
- PARSEBACKQNEW();
+ out = parsebackq(out, &bqlist, 0,
+ state[level].syntax == DQSYNTAX &&
+ (eofmark == NULL || newvarnest > 0),
+ state[level].syntax == DQSYNTAX ||
+ state[level].syntax == ARISYNTAX);
}
} else {
USTPUTC(CTLVAR, out);
@@ -1244,6 +1498,8 @@ parsesub: {
subtype = VSERROR;
if (c == '}')
pungetc();
+ else if (c == '\n' || c == PEOF)
+ synerror("Unexpected end of line in substitution");
else
USTPUTC(c, out);
} else {
@@ -1260,6 +1516,8 @@ parsesub: {
default:
p = strchr(types, c);
if (p == NULL) {
+ if (c == '\n' || c == PEOF)
+ synerror("Unexpected end of line in substitution");
if (flags == VSNUL)
STPUTC(':', out);
STPUTC(c, out);
@@ -1285,197 +1543,74 @@ parsesub: {
pungetc();
}
STPUTC('=', out);
- if (subtype != VSLENGTH && (dblquote || arinest))
+ if (subtype != VSLENGTH && (state[level].syntax == DQSYNTAX ||
+ state[level].syntax == ARISYNTAX))
flags |= VSQUOTE;
*(stackblock() + typeloc) = subtype | flags;
- if (subtype != VSNORMAL)
- varnest++;
- }
- goto parsesub_return;
-}
-
-
-/*
- * Called to parse command substitutions. Newstyle is set if the command
- * is enclosed inside $(...); nlpp is a pointer to the head of the linked
- * list of commands (passed by reference), and savelen is the number of
- * characters on the top of the stack which must be preserved.
- */
-
-parsebackq: {
- struct nodelist **nlpp;
- union node *n;
- char *volatile str;
- struct jmploc jmploc;
- struct jmploc *const savehandler = handler;
- int savelen;
- int saveprompt;
- const int bq_startlinno = plinno;
- char *volatile ostr = NULL;
- struct parsefile *const savetopfile = getcurrentfile();
-
- str = NULL;
- if (setjmp(jmploc.loc)) {
- popfilesupto(savetopfile);
- if (str)
- ckfree(str);
- if (ostr)
- ckfree(ostr);
- handler = savehandler;
- if (exception == EXERROR) {
- startlinno = bq_startlinno;
- synerror("Error in command substitution");
- }
- longjmp(handler->loc, 1);
- }
- INTOFF;
- savelen = out - stackblock();
- if (savelen > 0) {
- str = ckmalloc(savelen);
- memcpy(str, stackblock(), savelen);
- }
- handler = &jmploc;
- INTON;
- if (oldstyle) {
- /* We must read until the closing backquote, giving special
- treatment to some slashes, and then push the string and
- reread it as input, interpreting it normally. */
- char *oout;
- int c;
- int olen;
-
-
- STARTSTACKSTR(oout);
- for (;;) {
- if (needprompt) {
- setprompt(2);
- needprompt = 0;
+ if (subtype != VSNORMAL) {
+ if (level + 1 >= maxnest) {
+ maxnest *= 2;
+ if (state == state_static) {
+ state = parser_temp_alloc(
+ maxnest * sizeof(*state));
+ memcpy(state, state_static,
+ MAXNEST_STATIC * sizeof(*state));
+ } else
+ state = parser_temp_realloc(state,
+ maxnest * sizeof(*state));
}
- switch (c = pgetc()) {
- case '`':
- goto done;
-
- case '\\':
- if ((c = pgetc()) == '\n') {
- plinno++;
- if (doprompt)
- setprompt(2);
- else
- setprompt(0);
- /*
- * If eating a newline, avoid putting
- * the newline into the new character
- * stream (via the STPUTC after the
- * switch).
- */
- continue;
- }
- if (c != '\\' && c != '`' && c != '$'
- && (!dblquote || c != '"'))
- STPUTC('\\', oout);
- break;
-
- case '\n':
- plinno++;
- needprompt = doprompt;
- break;
-
- case PEOF:
- startlinno = plinno;
- synerror("EOF in backquote substitution");
- break;
-
- default:
- break;
+ level++;
+ state[level].parenlevel = 0;
+ if (subtype == VSMINUS || subtype == VSPLUS ||
+ subtype == VSQUESTION || subtype == VSASSIGN) {
+ /*
+ * For operators that were in the Bourne shell,
+ * inherit the double-quote state.
+ */
+ state[level].syntax = state[level - 1].syntax;
+ state[level].category = TSTATE_VAR_OLD;
+ } else {
+ /*
+ * The other operators take a pattern,
+ * so go to BASESYNTAX.
+ * Also, ' and " are now special, even
+ * in here documents.
+ */
+ state[level].syntax = BASESYNTAX;
+ state[level].category = TSTATE_VAR_NEW;
+ newvarnest++;
}
- STPUTC(c, oout);
- }
-done:
- STPUTC('\0', oout);
- olen = oout - stackblock();
- INTOFF;
- ostr = ckmalloc(olen);
- memcpy(ostr, stackblock(), olen);
- setinputstring(ostr, 1);
- INTON;
- }
- nlpp = &bqlist;
- while (*nlpp)
- nlpp = &(*nlpp)->next;
- *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
- (*nlpp)->next = NULL;
-
- if (oldstyle) {
- saveprompt = doprompt;
- doprompt = 0;
- }
-
- n = list(0);
-
- if (oldstyle)
- doprompt = saveprompt;
- else {
- if (readtoken() != TRP)
- synexpect(TRP);
- }
-
- (*nlpp)->n = n;
- if (oldstyle) {
- /*
- * Start reading from old file again, ignoring any pushed back
- * tokens left from the backquote parsing
- */
- popfile();
- tokpushback = 0;
- }
- while (stackblocksize() <= savelen)
- growstackblock();
- STARTSTACKSTR(out);
- if (str) {
- memcpy(out, str, savelen);
- STADJUST(savelen, out);
- INTOFF;
- ckfree(str);
- str = NULL;
- INTON;
- }
- if (ostr) {
- INTOFF;
- ckfree(ostr);
- ostr = NULL;
- INTON;
+ }
}
- handler = savehandler;
- if (arinest || dblquote)
- USTPUTC(CTLBACKQ | CTLQUOTE, out);
- else
- USTPUTC(CTLBACKQ, out);
- if (oldstyle)
- goto parsebackq_oldreturn;
- else
- goto parsebackq_newreturn;
+ goto parsesub_return;
}
+
/*
* Parse an arithmetic expansion (indicate start of one and set state)
*/
parsearith: {
- if (++arinest == 1) {
- prevsyntax = syntax;
- syntax = ARISYNTAX;
- USTPUTC(CTLARI, out);
- if (dblquote)
- USTPUTC('"',out);
- else
- USTPUTC(' ',out);
- } else {
- /*
- * we collapse embedded arithmetic expansion to
- * parenthesis, which should be equivalent
- */
- USTPUTC('(', out);
+ if (level + 1 >= maxnest) {
+ maxnest *= 2;
+ if (state == state_static) {
+ state = parser_temp_alloc(
+ maxnest * sizeof(*state));
+ memcpy(state, state_static,
+ MAXNEST_STATIC * sizeof(*state));
+ } else
+ state = parser_temp_realloc(state,
+ maxnest * sizeof(*state));
}
+ level++;
+ state[level].syntax = ARISYNTAX;
+ state[level].parenlevel = 0;
+ state[level].category = TSTATE_ARITH;
+ USTPUTC(CTLARI, out);
+ if (state[level - 1].syntax == DQSYNTAX)
+ USTPUTC('"',out);
+ else
+ USTPUTC(' ',out);
goto parsearith_return;
}
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 8ec1195..1f74992 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd December 31, 2009
+.Dd April 5, 2010
.Dt SH 1
.Os
.Sh NAME
@@ -210,7 +210,8 @@ Enable the built-in
.Xr emacs 1
command line editor (disables the
.Fl V
-option if it has been set).
+option if it has been set;
+set automatically when interactive on terminals).
.It Fl e Li errexit
Exit immediately if any untested command fails in non-interactive mode.
The exit status of a command is considered to be
@@ -1178,10 +1179,20 @@ consists of all characters until the matching
.Ql } .
Any
.Ql }
-escaped by a backslash or within a quoted string, and characters in
+escaped by a backslash or within a single-quoted string, and characters in
embedded arithmetic expansions, command substitutions, and variable
expansions, are not examined in determining the matching
.Ql } .
+Except for the variants with
+.Ql + ,
+.Ql - ,
+.Ql =
+or
+.Ql ?\& ,
+any
+.Ql }
+within a double-quoted string is also not examined in determining the matching
+.Ql } .
.Pp
The simplest form for parameter expansion is:
.Pp
@@ -1265,6 +1276,14 @@ is substituted.
In the parameter expansions shown previously, use of the colon in the
format results in a test for a parameter that is unset or null; omission
of the colon results in a test for a parameter that is only unset.
+.Pp
+The
+.Ar word
+inherits the type of quoting
+(unquoted, double-quoted or here-document)
+from the surroundings,
+with the exception that a backslash that quotes a closing brace is removed
+during quote removal.
.Bl -tag -width indent
.It Li ${# Ns Ar parameter Ns Li }
String Length.
@@ -1571,10 +1590,12 @@ built-in command.
.It Ic command Oo Fl p Oc Op Ar utility Op Ar argument ...
.It Ic command Oo Fl v | V Oc Op Ar utility
The first form of invocation executes the specified
+.Ar utility ,
+ignoring shell functions in the search.
+If
.Ar utility
-as a simple command (see the
-.Sx Simple Commands
-section).
+is a special builtin,
+it is executed as if it were a regular builtin.
.Pp
If the
.Fl p
diff --git a/bin/test/test.c b/bin/test/test.c
index d7d1eec..e2062d1 100644
--- a/bin/test/test.c
+++ b/bin/test/test.c
@@ -572,12 +572,12 @@ newerf (const char *f1, const char *f2)
if (stat(f1, &b1) != 0 || stat(f2, &b2) != 0)
return 0;
- if (b1.st_mtimespec.tv_sec > b2.st_mtimespec.tv_sec)
+ if (b1.st_mtim.tv_sec > b2.st_mtim.tv_sec)
return 1;
- if (b1.st_mtimespec.tv_sec < b2.st_mtimespec.tv_sec)
+ if (b1.st_mtim.tv_sec < b2.st_mtim.tv_sec)
return 0;
- return (b1.st_mtimespec.tv_nsec > b2.st_mtimespec.tv_nsec);
+ return (b1.st_mtim.tv_nsec > b2.st_mtim.tv_nsec);
}
static int
diff --git a/cddl/Makefile.inc b/cddl/Makefile.inc
index 4161c27..d3a4914 100644
--- a/cddl/Makefile.inc
+++ b/cddl/Makefile.inc
@@ -7,4 +7,5 @@ IGNORE_PRAGMA= YES
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
+WARNS?= 6
CSTD?= gnu89
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
index 39445ea..9cda0e5 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -1,24 +1,9 @@
'\" te
-.\" CDDL HEADER START
-.\"
-.\" The contents of this file are subject to the terms of the
-.\" Common Development and Distribution License (the "License").
-.\" You may not use this file except in compliance with the License.
-.\"
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-.\" or http://www.opensolaris.org/os/licensing.
-.\" See the License for the specific language governing permissions
-.\" and limitations under the License.
-.\"
-.\" When distributing Covered Code, include this CDDL HEADER in each
-.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-.\" If applicable, add the following below this CDDL HEADER, with the
-.\" fields enclosed by brackets "[]" replaced with your own identifying
-.\" information: Portions Copyright [yyyy] [name of copyright owner]
-.\"
-.\" CDDL HEADER END
-.\" Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
-.TH zfs 1M "8 Apr 2008" "SunOS 5.11" "System Administration Commands"
+.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
+.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
+.TH zfs 1M "14 Feb 2009" "SunOS 5.11" "System Administration Commands"
.SH NAME
zfs \- configures ZFS file systems
.SH SYNOPSIS
@@ -44,7 +29,8 @@ zfs \- configures ZFS file systems
.LP
.nf
-\fBzfs\fR \fBsnapshot\fR [\fB-r\fR] \fIfilesystem@snapname\fR|\fIvolume@snapname\fR
+\fBzfs\fR \fBsnapshot\fR [\fB-r\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR]...
+ \fIfilesystem@snapname\fR|\fIvolume@snapname\fR
.fi
.LP
@@ -54,7 +40,7 @@ zfs \- configures ZFS file systems
.LP
.nf
-\fBzfs\fR \fBclone\fR [\fB-p\fR] \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR
+\fBzfs\fR \fBclone\fR [\fB-p\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR] ... \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR
.fi
.LP
@@ -65,7 +51,7 @@ zfs \- configures ZFS file systems
.LP
.nf
\fBzfs\fR \fBrename\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
- \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
+ \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
.fi
.LP
@@ -81,23 +67,23 @@ zfs \- configures ZFS file systems
.LP
.nf
\fBzfs\fR \fBlist\fR [\fB-rH\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fB-t\fR \fItype\fR[,...]]
- [\fB-s\fR \fIproperty\fR] ... [\fB-S\fR \fIproperty\fR ... [\fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR] ...
+ [\fB-s\fR \fIproperty\fR] ... [\fB-S\fR \fIproperty\fR] ... [\fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR] ...
.fi
.LP
.nf
-\fBzfs\fR \fBset\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR ...
+\fBzfs\fR \fBset\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR|snapshot ...
.fi
.LP
.nf
\fBzfs\fR \fBget\fR [\fB-rHp\fR] [\fB-o\fR \fIfield\fR[,...]] [\fB-s\fR \fIsource\fR[,...]] "\fIall\fR" | \fIproperty\fR[,...]
- \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...
+ \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...
.fi
.LP
.nf
-\fBzfs\fR \fBinherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume\fR ...
+\fBzfs\fR \fBinherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume|snapshot\fR ...
.fi
.LP
@@ -132,12 +118,12 @@ zfs \- configures ZFS file systems
.LP
.nf
-\fBzfs\fR \fBunshare\fR \fB-a\fR \fIfilesystem\fR|\fImountpoint\fR
+\fBzfs\fR \fBunshare\fR \fB-a\fR \fIfilesystem\fR|\fImountpoint\fR
.fi
.LP
.nf
-\fBzfs\fR \fBsend\fR [\fB-vR\fR] [\fB-\fR[\fB-iI\fR] \fIsnapshot\fR] \fIsnapshot\fR
+\fBzfs\fR \fBsend\fR [\fB-vR\fR] [\fB-\fR[\fBiI\fR] \fIsnapshot\fR] \fIsnapshot\fR
.fi
.LP
@@ -153,7 +139,7 @@ zfs \- configures ZFS file systems
.LP
.nf
\fBzfs\fR \fBallow\fR [\fB-ldug\fR] "\fIeveryone\fR"|\fIuser\fR|\fIgroup\fR[,...] \fIperm\fR|\fI@setname\fR[,...]
- \fIfilesystem\fR|\fIvolume\fR
+ \fIfilesystem\fR|\fIvolume\fR
.fi
.LP
@@ -174,7 +160,7 @@ zfs \- configures ZFS file systems
.LP
.nf
\fBzfs\fR \fBunallow\fR [\fB-rldug\fR] "\fIeveryone\fR"|\fIuser\fR|\fIgroup\fR[,...] [\fIperm\fR|@\fIsetname\fR[,... ]]
- \fIfilesystem\fR|\fIvolume\fR
+ \fIfilesystem\fR|\fIvolume\fR
.fi
.LP
@@ -192,20 +178,10 @@ zfs \- configures ZFS file systems
\fBzfs\fR \fBunallow\fR [\fB-r\fR] \fB-s\fR @setname [\fIperm\fR|@\fIsetname\fR[,... ]] \fIfilesystem\fR|\fIvolume\fR
.fi
-.LP
-.nf
-\fBzfs\fR \fBjail\fR \fBjailid\fR \fB\fIfilesystem\fR\fR
-.fi
-.LP
-.nf
-\fBzfs\fR \fBunjail\fR \fBjailid\fR \fB\fIfilesystem\fR\fR
-.fi
-
.SH DESCRIPTION
.sp
.LP
-The \fBzfs\fR command configures \fBZFS\fR datasets within a \fBZFS\fR storage pool, as described in \fBzpool\fR(1M). A
-dataset is identified by a unique path within the \fBZFS\fR namespace. For example:
+The \fBzfs\fR command configures \fBZFS\fR datasets within a \fBZFS\fR storage pool, as described in \fBzpool\fR(1M). A dataset is identified by a unique path within the \fBZFS\fR namespace. For example:
.sp
.in +2
.nf
@@ -226,9 +202,9 @@ A dataset can be one of the following:
.na
\fB\fIfile system\fR\fR
.ad
-.RS 15n
-.rt
-A standard \fBPOSIX\fR file system. \fBZFS\fR file systems can be mounted within the standard file system namespace and behave like any other file system.
+.sp .6
+.RS 4n
+A \fBZFS\fR dataset of type "filesystem" that can be mounted within the standard system namespace and behaves like other file systems. While \fBZFS\fR file systems are designed to be \fBPOSIX\fR compliant, known issues exist that prevent compliance in some cases. Applications that depend on standards conformance might fail due to nonstandard behavior when checking file system free space.
.RE
.sp
@@ -237,8 +213,8 @@ A standard \fBPOSIX\fR file system. \fBZFS\fR file systems can be mounted within
.na
\fB\fIvolume\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
A logical volume exported as a raw or block device. This type of dataset should only be used under special circumstances. File systems are typically used in most environments. Volumes cannot be used in a non-global zone.
.RE
@@ -248,8 +224,8 @@ A logical volume exported as a raw or block device. This type of dataset should
.na
\fB\fIsnapshot\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
A read-only version of a file system or volume at a given point in time. It is specified as \fIfilesystem@name\fR or \fIvolume@name\fR.
.RE
@@ -272,20 +248,17 @@ A snapshot is a read-only copy of a file system or volume. Snapshots can be crea
Snapshots can have arbitrary names. Snapshots of volumes can be cloned or rolled back, but cannot be accessed independently.
.sp
.LP
-File system snapshots can be accessed under the ".zfs/snapshot" directory in the root of the file system. Snapshots are automatically mounted on demand and may be unmounted at regular intervals. The visibility of the ".zfs" directory can be controlled by the "snapdir"
-property.
+File system snapshots can be accessed under the ".zfs/snapshot" directory in the root of the file system. Snapshots are automatically mounted on demand and may be unmounted at regular intervals. The visibility of the ".zfs" directory can be controlled by the "snapdir" property.
.SS "Clones"
.sp
.LP
A clone is a writable volume or file system whose initial contents are the same as another dataset. As with snapshots, creating a clone is nearly instantaneous, and initially consumes no additional space.
.sp
.LP
-Clones can only be created from a snapshot. When a snapshot is cloned, it creates an implicit dependency between the parent and child. Even though the clone is created somewhere else in the dataset hierarchy, the original snapshot cannot be destroyed as long as a clone exists. The "origin"
-property exposes this dependency, and the \fBdestroy\fR command lists any such dependencies, if they exist.
+Clones can only be created from a snapshot. When a snapshot is cloned, it creates an implicit dependency between the parent and child. Even though the clone is created somewhere else in the dataset hierarchy, the original snapshot cannot be destroyed as long as a clone exists. The "origin" property exposes this dependency, and the \fBdestroy\fR command lists any such dependencies, if they exist.
.sp
.LP
-The clone parent-child dependency relationship can be reversed by using the "\fBpromote\fR" subcommand. This causes the "origin" file system to become a clone of the specified file system, which makes it possible to destroy the file system that the clone
-was created from.
+The clone parent-child dependency relationship can be reversed by using the "\fBpromote\fR" subcommand. This causes the "origin" file system to become a clone of the specified file system, which makes it possible to destroy the file system that the clone was created from.
.SS "Mount Points"
.sp
.LP
@@ -301,8 +274,7 @@ A file system can also have a mount point set in the "mountpoint" property. This
A file system mountpoint property of "none" prevents the file system from being mounted.
.sp
.LP
-If needed, \fBZFS\fR file systems can also be managed with traditional tools (\fBmount\fR, \fBumount\fR, \fB/etc/vfstab\fR). If a file system's mount point is set to "legacy", \fBZFS\fR makes no attempt to manage
-the file system, and the administrator is responsible for mounting and unmounting the file system.
+If needed, \fBZFS\fR file systems can also be managed with traditional tools (\fBmount\fR, \fBumount\fR, \fB/etc/vfstab\fR). If a file system's mount point is set to "legacy", \fBZFS\fR makes no attempt to manage the file system, and the administrator is responsible for mounting and unmounting the file system.
.SS "Zones"
.sp
.LP
@@ -312,8 +284,7 @@ A \fBZFS\fR file system can be added to a non-global zone by using zonecfg's "\f
The physical properties of an added file system are controlled by the global administrator. However, the zone administrator can create, modify, or destroy files within the added file system, depending on how the file system is mounted.
.sp
.LP
-A dataset can also be delegated to a non-global zone by using zonecfg's "\fBadd dataset\fR" subcommand. You cannot delegate a dataset to one zone and the children of the same dataset to another zone. The zone administrator can change properties of the dataset or
-any of its children. However, the "quota" property is controlled by the global administrator.
+A dataset can also be delegated to a non-global zone by using zonecfg's "\fBadd dataset\fR" subcommand. You cannot delegate a dataset to one zone and the children of the same dataset to another zone. The zone administrator can change properties of the dataset or any of its children. However, the "quota" property is controlled by the global administrator.
.sp
.LP
A \fBZFS\fR volume can be added as a device to a non-global zone by using zonecfg's "\fBadd device\fR" subcommand. However, its physical properties can only be modified by the global administrator.
@@ -329,15 +300,13 @@ The global administrator can forcibly clear the "zoned" property, though this sh
.SS "Native Properties"
.sp
.LP
-Properties are divided into two types, native properties and user defined properties. Native properties either export internal statistics or control \fBZFS\fR behavior. In addition, native properties are either editable or read-only. User properties have no effect on \fBZFS\fR behavior,
-but you can use them to annotate datasets in a way that is meaningful in your environment. For more information about user properties, see the "User Properties" section.
+Properties are divided into two types, native properties and user defined properties. Native properties either export internal statistics or control \fBZFS\fR behavior. In addition, native properties are either editable or read-only. User properties have no effect on \fBZFS\fR behavior, but you can use them to annotate datasets in a way that is meaningful in your environment. For more information about user properties, see the "User Properties" section.
.sp
.LP
-Every dataset has a set of properties that export statistics about the dataset as well as control various behavior. Properties are inherited from the parent unless overridden by the child. Snapshot properties can not be edited; they always inherit their inheritable properties. Properties
-that are not applicable to snapshots are not displayed.
+Every dataset has a set of properties that export statistics about the dataset as well as control various behavior. Properties are inherited from the parent unless overridden by the child. Some properties only apply to certain types of datasets (file systems, volumes or snapshots).
.sp
.LP
-The values of numeric properties can be specified using the following human-readable suffixes (for example, "k", "KB", "M", "Gb", etc, up to Z for zettabyte). The following are all valid (and equal) specifications:
+The values of numeric properties can be specified using human-readable suffixes (for example, "k", "KB", "M", "Gb", etc, up to Z for zettabyte). The following are all valid (and equal) specifications:
.sp
.in +2
.nf
@@ -360,8 +329,7 @@ The following native properties consist of read-only statistics about the datase
.ad
.sp .6
.RS 4n
-The amount of space available to the dataset and all its children, assuming that there is no other activity in the pool. Because space is shared within a pool, availability can be limited by any number of factors, including physical pool size, quotas, reservations, or other datasets
-within the pool.
+The amount of space available to the dataset and all its children, assuming that there is no other activity in the pool. Because space is shared within a pool, availability can be limited by any number of factors, including physical pool size, quotas, reservations, or other datasets within the pool.
.sp
This property can also be referred to by its shortened column name, "avail".
.RE
@@ -418,8 +386,7 @@ For cloned file systems or volumes, the snapshot from which the clone was create
.ad
.sp .6
.RS 4n
-The amount of data that is accessible by this dataset, which may or may not be shared with other datasets in the pool. When a snapshot or clone is created, it initially references the same amount of space as the file system or snapshot it was created from, since its contents are
-identical.
+The amount of data that is accessible by this dataset, which may or may not be shared with other datasets in the pool. When a snapshot or clone is created, it initially references the same amount of space as the file system or snapshot it was created from, since its contents are identical.
.sp
This property can also be referred to by its shortened column name, "refer".
.RE
@@ -432,7 +399,7 @@ This property can also be referred to by its shortened column name, "refer".
.ad
.sp .6
.RS 4n
-The type of dataset: "filesystem", "volume", "snapshot", or "clone".
+The type of dataset: "filesystem", "volume", or "snapshot".
.RE
.sp
@@ -443,11 +410,9 @@ The type of dataset: "filesystem", "volume", "snapshot", or "clone".
.ad
.sp .6
.RS 4n
-The amount of space consumed by this dataset and all its descendents. This is the value that is checked against this dataset's quota and reservation. The space used does not include this dataset's reservation, but does take into account the reservations of any descendent datasets.
-The amount of space that a dataset consumes from its parent, as well as the amount of space that are freed if this dataset is recursively destroyed, is the greater of its space used and its reservation.
+The amount of space consumed by this dataset and all its descendents. This is the value that is checked against this dataset's quota and reservation. The space used does not include this dataset's reservation, but does take into account the reservations of any descendent datasets. The amount of space that a dataset consumes from its parent, as well as the amount of space that are freed if this dataset is recursively destroyed, is the greater of its space used and its reservation.
.sp
-When snapshots (see the "Snapshots" section) are created, their space is initially shared between the snapshot and the file system, and possibly with previous snapshots. As the file system changes, space that was previously shared becomes unique to the snapshot, and counted in
-the snapshot's space used. Additionally, deleting snapshots can increase the amount of space unique to (and used by) other snapshots.
+When snapshots (see the "Snapshots" section) are created, their space is initially shared between the snapshot and the file system, and possibly with previous snapshots. As the file system changes, space that was previously shared becomes unique to the snapshot, and counted in the snapshot's space used. Additionally, deleting snapshots can increase the amount of space unique to (and used by) other snapshots.
.sp
The amount of space used, available, or referenced does not take into account pending changes. Pending changes are generally accounted for within a few seconds. Committing a change to a disk using \fBfsync\fR(3c) or \fBO_SYNC\fR does not necessarily guarantee that the space usage information is updated immediately.
.RE
@@ -456,12 +421,66 @@ The amount of space used, available, or referenced does not take into account pe
.ne 2
.mk
.na
+\fBusedby*\fR
+.ad
+.sp .6
+.RS 4n
+The \fBusedby*\fR snapshots decompose the "used" properties into the various reasons that space is used. Specifically, \fBused\fR = \fBusedbychildren\fR + \fBusedbydataset\fR + \fBusedbyrefreservation\fR +, \fBusedbysnapshots\fR. These properties are only available for datasets created on zpool "version 13" pools.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fBusedbychildren\fR
+.ad
+.sp .6
+.RS 4n
+The amount of space used by children of this dataset, which would be freed if all the dataset's children were destroyed.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fBusedbydataset\fR
+.ad
+.sp .6
+.RS 4n
+The amount of space used by this dataset itself, which would be freed if the dataset were destroyed (after first removing any \fBrefreservation\fR and destroying any necessary snapshots or descendents).
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fBusedbyrefreservation\fR
+.ad
+.sp .6
+.RS 4n
+The amount of space used by a \fBrefreservation\fR set on this dataset, which would be freed if the \fBrefreservation\fR was removed.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fBusedbysnapshots\fR
+.ad
+.sp .6
+.RS 4n
+The amount of space consumed by snapshots of this dataset. In particular, it is the amount of space that would be freed if all of this dataset's snapshots were destroyed. Note that this is not simply the sum of the snapshots' "used" properties because space can be shared by multiple snapshots
+.RE
+
+.sp
+.ne 2
+.mk
+.na
\fBvolblocksize=\fIblocksize\fR\fR
.ad
.sp .6
.RS 4n
-For volumes, specifies the block size of the volume. The \fBblocksize\fR cannot be changed once the volume has been written, so it should be set at volume creation time. The default \fBblocksize\fR for volumes is 8 Kbytes. Any power of 2 from 512 bytes
-to 128 Kbytes is valid.
+For volumes, specifies the block size of the volume. The \fBblocksize\fR cannot be changed once the volume has been written, so it should be set at volume creation time. The default \fBblocksize\fR for volumes is 8 Kbytes. Any power of 2 from 512 bytes to 128 Kbytes is valid.
.sp
This property can also be referred to by its shortened column name, "volblock".
.RE
@@ -473,15 +492,13 @@ The following native properties can be used to change the behavior of a \fBZFS\f
.ne 2
.mk
.na
-\fBaclinherit=\fBdiscard\fR | \fBnoallow\fR | \fBrestricted\fR | \fBpassthrough\fR\fR
+\fBaclinherit=\fBdiscard\fR | \fBnoallow\fR | \fBrestricted\fR | \fBpassthrough\fR | \fBpassthrough-x\fR\fR
.ad
.sp .6
.RS 4n
-Controls how \fBACL\fR entries are inherited when files and directories are created. A file system with an "aclinherit" property of "\fBdiscard\fR" does not inherit any \fBACL\fR entries. A file system with an "aclinherit"
-property value of "\fBnoallow\fR" only inherits inheritable \fBACL\fR entries that specify "deny" permissions. The property value "\fBrestricted\fR" (the default) removes the "\fBwrite_acl\fR" and "\fBwrite_owner\fR" permissions when the \fBACL\fR entry is inherited. A file system with an "aclinherit" property value of "\fBpassthrough\fR" inherits all inheritable \fBACL\fR entries without any modifications made to the \fBACL\fR entries when they are inherited.
+Controls how \fBACL\fR entries are inherited when files and directories are created. A file system with an "aclinherit" property of "\fBdiscard\fR" does not inherit any \fBACL\fR entries. A file system with an "aclinherit" property value of "\fBnoallow\fR" only inherits inheritable \fBACL\fR entries that specify "deny" permissions. The property value "\fBrestricted\fR" (the default) removes the "\fBwrite_acl\fR" and "\fBwrite_owner\fR" permissions when the \fBACL\fR entry is inherited. A file system with an "aclinherit" property value of "\fBpassthrough\fR" inherits all inheritable \fBACL\fR entries without any modifications made to the \fBACL\fR entries when they are inherited. A file system with an "aclinherit" property value of "\fBpassthrough-x\fR" has the same meaning as "\fBpassthrough\fR", except that the \fBowner@\fR, \fBgroup@\fR, and \fBeveryone@\fR \fBACE\fRs inherit the execute permission only if the file creation mode also requests the execute bit.
.sp
-When the property value is set to "\fBpassthrough\fR," files are created with a mode determined by the inheritable \fBACE\fRs. If no inheritable \fBACE\fRs exist that affect the mode, then the mode is set in accordance to the requested mode
-from the application.
+When the property value is set to "\fBpassthrough\fR," files are created with a mode determined by the inheritable \fBACE\fRs. If no inheritable \fBACE\fRs exist that affect the mode, then the mode is set in accordance to the requested mode from the application.
.RE
.sp
@@ -492,9 +509,7 @@ from the application.
.ad
.sp .6
.RS 4n
-Controls how an \fBACL\fR is modified during \fBchmod\fR(2). A file system with an "aclmode" property of "\fBdiscard\fR"
-deletes all \fBACL\fR entries that do not represent the mode of the file. An "aclmode" property of "\fBgroupmask\fR" (the default) reduces user or group permissions. The permissions are reduced, such that they are no greater than the group permission
-bits, unless it is a user entry that has the same \fBUID\fR as the owner of the file or directory. In this case, the \fBACL\fR permissions are reduced so that they are no greater than owner permission bits. A file system with an "aclmode" property of "\fBpassthrough\fR" indicates that no changes are made to the \fBACL\fR other than generating the necessary \fBACL\fR entries to represent the new mode of the file or directory.
+Controls how an \fBACL\fR is modified during \fBchmod\fR(2). A file system with an "aclmode" property of "\fBdiscard\fR" deletes all \fBACL\fR entries that do not represent the mode of the file. An "aclmode" property of "\fBgroupmask\fR" (the default) reduces user or group permissions. The permissions are reduced, such that they are no greater than the group permission bits, unless it is a user entry that has the same \fBUID\fR as the owner of the file or directory. In this case, the \fBACL\fR permissions are reduced so that they are no greater than owner permission bits. A file system with an "aclmode" property of "\fBpassthrough\fR" indicates that no changes are made to the \fBACL\fR other than generating the necessary \fBACL\fR entries to represent the new mode of the file or directory.
.RE
.sp
@@ -505,8 +520,7 @@ bits, unless it is a user entry that has the same \fBUID\fR as the owner of the
.ad
.sp .6
.RS 4n
-Controls whether the access time for files is updated when they are read. Turning this property off avoids producing write traffic when reading files and can result in significant performance gains, though it might confuse mailers and other similar utilities. The default value
-is "on".
+Controls whether the access time for files is updated when they are read. Turning this property off avoids producing write traffic when reading files and can result in significant performance gains, though it might confuse mailers and other similar utilities. The default value is "on".
.RE
.sp
@@ -517,12 +531,9 @@ is "on".
.ad
.sp .6
.RS 4n
-If this property is set to "\fBoff\fR", the file system cannot be mounted, and is ignored by "\fBzfs mount -a\fR". Setting this property to "\fBoff\fR" is similar to setting the "mountpoint"
-property to "\fBnone\fR", except that the dataset still has a normal "mountpoint" property, which can be inherited. Setting this property to "\fBoff\fR" allows datasets to be used solely as a mechanism to inherit properties. One example
-of setting canmount=\fBoff\fR is to have two datasets with the same mountpoint, so that the children of both datasets appear in the same directory, but might have different inherited characteristics.
+If this property is set to "\fBoff\fR", the file system cannot be mounted, and is ignored by "\fBzfs mount -a\fR". Setting this property to "\fBoff\fR" is similar to setting the "mountpoint" property to "\fBnone\fR", except that the dataset still has a normal "mountpoint" property, which can be inherited. Setting this property to "\fBoff\fR" allows datasets to be used solely as a mechanism to inherit properties. One example of setting canmount=\fBoff\fR is to have two datasets with the same mountpoint, so that the children of both datasets appear in the same directory, but might have different inherited characteristics.
.sp
-When the "\fBnoauto\fR" option is set, a dataset can only be mounted and unmounted explicitly. The dataset is not mounted automatically when the dataset is created or imported, nor is it mounted by the "\fBzfs mount -a\fR" command or unmounted
-by the "\fBzfs unmount -a\fR" command.
+When the "\fBnoauto\fR" option is set, a dataset can only be mounted and unmounted explicitly. The dataset is not mounted automatically when the dataset is created or imported, nor is it mounted by the "\fBzfs mount -a\fR" command or unmounted by the "\fBzfs unmount -a\fR" command.
.sp
This property is not inherited.
.RE
@@ -535,8 +546,7 @@ This property is not inherited.
.ad
.sp .6
.RS 4n
-Controls the checksum used to verify data integrity. The default value is "on", which automatically selects an appropriate algorithm (currently, \fIfletcher4\fR, but this may change in future releases). The value "off" disables integrity
-checking on user data. Disabling checksums is NOT a recommended practice.
+Controls the checksum used to verify data integrity. The default value is "on", which automatically selects an appropriate algorithm (currently, \fIfletcher2\fR, but this may change in future releases). The value "off" disables integrity checking on user data. Disabling checksums is NOT a recommended practice.
.RE
.sp
@@ -547,9 +557,7 @@ checking on user data. Disabling checksums is NOT a recommended practice.
.ad
.sp .6
.RS 4n
-Controls the compression algorithm used for this dataset. The "lzjb" compression algorithm is optimized for performance while providing decent data compression. Setting compression to "on" uses the "lzjb" compression algorithm. The "gzip"
-compression algorithm uses the same compression as the \fBgzip\fR(1) command. You can specify the "gzip" level by using the value "gzip-\fIN\fR" where \fIN\fR is
-an integer from 1 (fastest) to 9 (best compression ratio). Currently, "gzip" is equivalent to "gzip-6" (which is also the default for \fBgzip\fR(1)).
+Controls the compression algorithm used for this dataset. The "lzjb" compression algorithm is optimized for performance while providing decent data compression. Setting compression to "on" uses the "lzjb" compression algorithm. The "gzip" compression algorithm uses the same compression as the \fBgzip\fR(1) command. You can specify the "gzip" level by using the value "gzip-\fIN\fR" where \fIN\fR is an integer from 1 (fastest) to 9 (best compression ratio). Currently, "gzip" is equivalent to "gzip-6" (which is also the default for \fBgzip\fR(1)).
.sp
This property can also be referred to by its shortened column name "compress".
.RE
@@ -562,8 +570,7 @@ This property can also be referred to by its shortened column name "compress".
.ad
.sp .6
.RS 4n
-Controls the number of copies of data stored for this dataset. These copies are in addition to any redundancy provided by the pool, for example, mirroring or raid-z. The copies are stored on different disks, if possible. The space used by multiple copies is charged to the associated
-file and dataset, changing the "used" property and counting against quotas and reservations.
+Controls the number of copies of data stored for this dataset. These copies are in addition to any redundancy provided by the pool, for example, mirroring or raid-z. The copies are stored on different disks, if possible. The space used by multiple copies is charged to the associated file and dataset, changing the "used" property and counting against quotas and reservations.
.sp
Changing this property only affects newly-written data. Therefore, set this property at file system creation time by using the "\fB-o\fR copies=" option.
.RE
@@ -600,8 +607,7 @@ Controls whether processes can be executed from within this file system. The def
.RS 4n
Controls the mount point used for this file system. See the "Mount Points" section for more information on how this property is used.
.sp
-When the mountpoint property is changed for a file system, the file system and any children that inherit the mount point are unmounted. If the new value is "legacy", then they remain unmounted. Otherwise, they are automatically remounted in the new location if the property was
-previously "legacy" or "none", or if they were mounted before the property was changed. In addition, any shared file systems are unshared and shared in the new location.
+When the mountpoint property is changed for a file system, the file system and any children that inherit the mount point are unmounted. If the new value is "legacy", then they remain unmounted. Otherwise, they are automatically remounted in the new location if the property was previously "legacy" or "none", or if they were mounted before the property was changed. In addition, any shared file systems are unshared and shared in the new location.
.RE
.sp
@@ -612,7 +618,18 @@ previously "legacy" or "none", or if they were mounted before the property was c
.ad
.sp .6
.RS 4n
-Controls whether the file system should be mounted with "\fBnbmand\fR" (Non Blocking mandatory locks). This is used for \fBCIFS\fR clients. Changes to this property only take effect when the file system is umounted and remounted. See \fBmount\fR(1M) for more information on "\fBnbmand\fR" mounts.
+Controls whether the file system should be mounted with "\fBnbmand\fR" (Non Blocking mandatory locks). This is used for \fBCIFS\fR clients. Changes to this property only take effect when the file system is umounted and remounted. See \fBmount\fR(1M) for more information on "\fBnbmand\fR" mounts.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fBprimarycache=\fIall\fR | \fInone\fR | \fImetadata\fR\fR
+.ad
+.sp .6
+.RS 4n
+Controls what is cached in the primary cache (ARC). If this property is set to "all", then both user data and metadata is cached. If this property is set to "none", then neither user data nor metadata is cached. If this property is set to "metadata", then only metadata is cached. The default value is "all".
.RE
.sp
@@ -623,8 +640,7 @@ Controls whether the file system should be mounted with "\fBnbmand\fR" (Non Bloc
.ad
.sp .6
.RS 4n
-Limits the amount of space a dataset and its descendents can consume. This property enforces a hard limit on the amount of space used. This includes all space consumed by descendents, including file systems and snapshots. Setting a quota on a descendent of a dataset that already
-has a quota does not override the ancestor's quota, but rather imposes an additional limit.
+Limits the amount of space a dataset and its descendents can consume. This property enforces a hard limit on the amount of space used. This includes all space consumed by descendents, including file systems and snapshots. Setting a quota on a descendent of a dataset that already has a quota does not override the ancestor's quota, but rather imposes an additional limit.
.sp
Quotas cannot be set on volumes, as the "volsize" property acts as an implicit quota.
.RE
@@ -650,11 +666,9 @@ This property can also be referred to by its shortened column name, "rdonly".
.ad
.sp .6
.RS 4n
-Specifies a suggested block size for files in the file system. This property is designed solely for use with database workloads that access files in fixed-size records. \fBZFS\fR automatically tunes block sizes according to internal algorithms optimized for typical
-access patterns.
+Specifies a suggested block size for files in the file system. This property is designed solely for use with database workloads that access files in fixed-size records. \fBZFS\fR automatically tunes block sizes according to internal algorithms optimized for typical access patterns.
.sp
-For databases that create very large files but access them in small random chunks, these algorithms may be suboptimal. Specifying a "recordsize" greater than or equal to the record size of the database can result in significant performance gains. Use of this property for general
-purpose file systems is strongly discouraged, and may adversely affect performance.
+For databases that create very large files but access them in small random chunks, these algorithms may be suboptimal. Specifying a "recordsize" greater than or equal to the record size of the database can result in significant performance gains. Use of this property for general purpose file systems is strongly discouraged, and may adversely affect performance.
.sp
The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes.
.sp
@@ -682,8 +696,7 @@ Limits the amount of space a dataset can consume. This property enforces a hard
.ad
.sp .6
.RS 4n
-The minimum amount of space guaranteed to a dataset, not including its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by \fBrefreservation\fR. The \fBrefreservation\fR reservation
-is accounted for in the parent datasets' space used, and counts against the parent datasets' quotas and reservations.
+The minimum amount of space guaranteed to a dataset, not including its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by \fBrefreservation\fR. The \fBrefreservation\fR reservation is accounted for in the parent datasets' space used, and counts against the parent datasets' quotas and reservations.
.sp
If \fBrefreservation\fR is set, a snapshot is only allowed if there is enough free pool space outside of this reservation to accommodate the current number of "referenced" bytes in the dataset.
.sp
@@ -698,8 +711,7 @@ This property can also be referred to by its shortened column name, "refreserv".
.ad
.sp .6
.RS 4n
-The minimum amount of space guaranteed to a dataset and its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by its reservation. Reservations are accounted for in the parent datasets' space
-used, and count against the parent datasets' quotas and reservations.
+The minimum amount of space guaranteed to a dataset and its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by its reservation. Reservations are accounted for in the parent datasets' space used, and count against the parent datasets' quotas and reservations.
.sp
This property can also be referred to by its shortened column name, "reserv".
.RE
@@ -708,6 +720,17 @@ This property can also be referred to by its shortened column name, "reserv".
.ne 2
.mk
.na
+\fBsecondarycache=\fIall\fR | \fInone\fR | \fImetadata\fR\fR
+.ad
+.sp .6
+.RS 4n
+Controls what is cached in the secondary cache (L2ARC). If this property is set to "all", then both user data and metadata is cached. If this property is set to "none", then neither user data nor metadata is cached. If this property is set to "metadata", then only metadata is cached. The default value is "all".
+.RE
+
+.sp
+.ne 2
+.mk
+.na
\fBsetuid=\fIon\fR | \fIoff\fR\fR
.ad
.sp .6
@@ -723,8 +746,7 @@ Controls whether the set-\fBUID\fR bit is respected for the file system. The def
.ad
.sp .6
.RS 4n
-Like the "sharenfs" property, "shareiscsi" indicates whether a \fBZFS\fR volume is exported as an \fBiSCSI\fR target. The acceptable values for this property are "on", "off", and "type=disk".
-The default value is "off". In the future, other target types might be supported. For example, "tape".
+Like the "sharenfs" property, "shareiscsi" indicates whether a \fBZFS\fR volume is exported as an \fBiSCSI\fR target. The acceptable values for this property are "on", "off", and "type=disk". The default value is "off". In the future, other target types might be supported. For example, "tape".
.sp
You might want to set "shareiscsi=on" for a file system so that all \fBZFS\fR volumes within the file system are shared by default. Setting this property on a file system has no direct effect, however.
.RE
@@ -737,15 +759,13 @@ You might want to set "shareiscsi=on" for a file system so that all \fBZFS\fR vo
.ad
.sp .6
.RS 4n
-Controls whether the file system is shared by using the Solaris \fBCIFS\fR service, and what options are to be used. A file system with the "\fBsharesmb\fR" property set to "off" is managed through traditional tools such as \fBsharemgr\fR(1M). Otherwise, the file system is automatically shared and unshared with the "zfs share" and "zfs unshare" commands. If the property is set to "on",
-the \fBsharemgr\fR(1M) command is invoked with no options. Otherwise, the \fBsharemgr\fR(1M) command is invoked with options equivalent to the contents of this property.
+Controls whether the file system is shared by using the Solaris \fBCIFS\fR service, and what options are to be used. A file system with the "\fBsharesmb\fR" property set to "off" is managed through traditional tools such as \fBsharemgr\fR(1M). Otherwise, the file system is automatically shared and unshared with the \fBzfs share\fR and \fBzfs unshare\fR commands. If the property is set to \fBon\fR, the \fBsharemgr\fR(1M) command is invoked with no options. Otherwise, the \fBsharemgr\fR(1M) command is invoked with options equivalent to the contents of this property.
+.sp
+Because \fBSMB\fR shares requires a resource name, a unique resource name is constructed from the dataset name. The constructed name is a copy of the dataset name except that the characters in the dataset name, which would be illegal in the resource name, are replaced with underscore (\fB_\fR) characters. A pseudo property "name" is also supported that allows you to replace the data set name with a specified name. The specified name is then used to replace the prefix dataset in the case of inheritance. For example, if the dataset \fBdata/home/john\fR is set to \fBname=john\fR, then \fBdata/home/john\fR has a resource name of \fBjohn\fR. If a child dataset of \fBdata/home/john/backups\fR, it has a resource name of \fBjohn_backups\fR.
.sp
-Because \fBSMB\fR shares requires a resource name, a unique resource name is constructed from the dataset name. The constructed name is a copy of the dataset name except that the characters in the dataset name, which would be illegal in the resource name, are replaced with underscore
-(_) characters. A pseudo property "name" is also supported that allows you to replace the data set name with a specified name. The specified name is then used to replace the prefix dataset in the case of inheritance. For example, if the dataset "\fBdata/home/john\fR"
-is set to "name=john", then "\fBdata/home/john\fR" has a resource name of "john". If a child dataset of "\fBdata/home/john/backups\fR", it has a resource name of "john_backups".
+When SMB shares are created, the SMB share name appears as an entry in the \fB\&.zfs/shares\fR directory. You can use the \fBls\fR or \fBchmod\fR command to display the share-level ACLs on the entries in this directory.
.sp
-When the "sharesmb" property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously set to "off", or if they were shared before the property was changed. If the new property
-is set to "off", the file systems are unshared.
+When the \fBsharesmb\fR property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously set to \fBoff\fR, or if they were shared before the property was changed. If the new property is set to \fBoff\fR, the file systems are unshared.
.RE
.sp
@@ -756,11 +776,9 @@ is set to "off", the file systems are unshared.
.ad
.sp .6
.RS 4n
-Controls whether the file system is shared via \fBNFS\fR, and what options are used. A file system with a"\fBsharenfs\fR" property of "off" is managed through traditional tools such as \fBshare\fR(1M), \fBunshare\fR(1M), and \fBdfstab\fR(4). Otherwise, the file system is automatically shared and unshared with the "\fBzfs share\fR" and "\fBzfs unshare\fR" commands. If the property is set to "on",
-the \fBshare\fR(1M) command is invoked with no options. Otherwise, the \fBshare\fR(1M) command is invoked with options equivalent to the contents of this property.
+Controls whether the file system is shared via \fBNFS\fR, and what options are used. A file system with a"\fBsharenfs\fR" property of "off" is managed through traditional tools such as \fBshare\fR(1M), \fBunshare\fR(1M), and \fBdfstab\fR(4). Otherwise, the file system is automatically shared and unshared with the "\fBzfs share\fR" and "\fBzfs unshare\fR" commands. If the property is set to "on", the \fBshare\fR(1M) command is invoked with no options. Otherwise, the \fBshare\fR(1M) command is invoked with options equivalent to the contents of this property.
.sp
-When the "sharenfs" property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously "off", or if they were shared before the property was changed. If the new property is "off",
-the file systems are unshared.
+When the "sharenfs" property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously "off", or if they were shared before the property was changed. If the new property is "off", the file systems are unshared.
.RE
.sp
@@ -793,14 +811,11 @@ The on-disk version of this file system, which is independent of the pool versio
.ad
.sp .6
.RS 4n
-For volumes, specifies the logical size of the volume. By default, creating a volume establishes a reservation of equal size. For storage pools with a version number of 9 or higher, a \fBrefreservation\fR is set instead. Any changes to \fBvolsize\fR are
-reflected in an equivalent change to the reservation (or \fBrefreservation\fR). The \fBvolsize\fR can only be set to a multiple of \fBvolblocksize\fR, and cannot be zero.
+For volumes, specifies the logical size of the volume. By default, creating a volume establishes a reservation of equal size. For storage pools with a version number of 9 or higher, a \fBrefreservation\fR is set instead. Any changes to \fBvolsize\fR are reflected in an equivalent change to the reservation (or \fBrefreservation\fR). The \fBvolsize\fR can only be set to a multiple of \fBvolblocksize\fR, and cannot be zero.
.sp
-The reservation is kept equal to the volume's logical size to prevent unexpected behavior for consumers. Without the reservation, the volume could run out of space, resulting in undefined behavior or data corruption, depending on how the volume is used. These effects can also occur when
-the volume size is changed while it is in use (particularly when shrinking the size). Extreme care should be used when adjusting the volume size.
+The reservation is kept equal to the volume's logical size to prevent unexpected behavior for consumers. Without the reservation, the volume could run out of space, resulting in undefined behavior or data corruption, depending on how the volume is used. These effects can also occur when the volume size is changed while it is in use (particularly when shrinking the size). Extreme care should be used when adjusting the volume size.
.sp
-Though not recommended, a "sparse volume" (also known as "thin provisioning") can be created by specifying the \fB-s\fR option to the "\fBzfs create -V\fR" command, or by changing the reservation after the volume has been created.
-A "sparse volume" is a volume where the reservation is less then the volume size. Consequently, writes to a sparse volume can fail with \fBENOSPC\fR when the pool is low on space. For a sparse volume, changes to \fBvolsize\fR are not reflected in the reservation.
+Though not recommended, a "sparse volume" (also known as "thin provisioning") can be created by specifying the \fB-s\fR option to the "\fBzfs create -V\fR" command, or by changing the reservation after the volume has been created. A "sparse volume" is a volume where the reservation is less then the volume size. Consequently, writes to a sparse volume can fail with \fBENOSPC\fR when the pool is low on space. For a sparse volume, changes to \fBvolsize\fR are not reflected in the reservation.
.RE
.sp
@@ -838,8 +853,7 @@ Controls whether the dataset is managed from a non-global zone. See the "Zones"
.sp
.LP
-The following three properties cannot be changed after the file system is created, and therefore, should be set when the file system is created. If the properties are not set with the "\fBzfs create\fR" command, these properties are inherited from the parent dataset.
-If the parent dataset lacks these properties due to having been created prior to these features being supported, the new file system will have the default values for these properties.
+The following three properties cannot be changed after the file system is created, and therefore, should be set when the file system is created. If the properties are not set with the "\fBzfs create\fR" or "\fBzpool create\fR" commands, these properties are inherited from the parent dataset. If the parent dataset lacks these properties due to having been created prior to these features being supported, the new file system will have the default values for these properties.
.sp
.ne 2
.mk
@@ -848,11 +862,9 @@ If the parent dataset lacks these properties due to having been created prior to
.ad
.sp .6
.RS 4n
-Indicates whether the file name matching algorithm used by the file system should be case-sensitive, case-insensitive, or allow a combination of both styles of matching. The default value for the "\fBcasesensitivity\fR" property is "\fBsensitive\fR."
-Traditionally, UNIX and POSIX file systems have case-sensitive file names.
+Indicates whether the file name matching algorithm used by the file system should be case-sensitive, case-insensitive, or allow a combination of both styles of matching. The default value for the "\fBcasesensitivity\fR" property is "\fBsensitive\fR." Traditionally, UNIX and POSIX file systems have case-sensitive file names.
.sp
-The "\fBmixed\fR" value for the "\fBcasesensitivity\fR" property indicates that the file system can support requests for both case-sensitive and case-insensitive matching behavior. Currently, case-insensitive matching behavior on a file system
-that supports mixed behavior is limited to the Solaris CIFS server product. For more information about the "mixed" value behavior, see the \fIZFS Administration Guide\fR.
+The "\fBmixed\fR" value for the "\fBcasesensitivity\fR" property indicates that the file system can support requests for both case-sensitive and case-insensitive matching behavior. Currently, case-insensitive matching behavior on a file system that supports mixed behavior is limited to the Solaris CIFS server product. For more information about the "mixed" value behavior, see the \fIZFS Administration Guide\fR.
.RE
.sp
@@ -863,20 +875,7 @@ that supports mixed behavior is limited to the Solaris CIFS server product. For
.ad
.sp .6
.RS 4n
-Indicates whether the file system should perform a \fBunicode\fR normalization of file names whenever two file names are compared, and which normalization algorithm should be used. File names are always stored unmodified, names are normalized as part of any comparison
-process. If this property is set to a legal value other than "\fBnone\fR," and the "\fButf8only\fR" property was left unspecified, the "\fButf8only\fR" property is automatically set to "\fBon\fR."
-The default value of the "\fBnormalization\fR" property is "\fBnone\fR." This property cannot be changed after the file system is created.
-.RE
-
-.sp
-.ne 2
-.mk
-.na
-\fBjailed =\fIon\fR | \fIoff\fR\fR
-.ad
-.sp .6
-.RS 4n
-Controls whether the dataset is managed from within a jail. The default value is "off".
+Indicates whether the file system should perform a \fBunicode\fR normalization of file names whenever two file names are compared, and which normalization algorithm should be used. File names are always stored unmodified, names are normalized as part of any comparison process. If this property is set to a legal value other than "\fBnone\fR," and the "\fButf8only\fR" property was left unspecified, the "\fButf8only\fR" property is automatically set to "\fBon\fR." The default value of the "\fBnormalization\fR" property is "\fBnone\fR." This property cannot be changed after the file system is created.
.RE
.sp
@@ -887,63 +886,52 @@ Controls whether the dataset is managed from within a jail. The default value is
.ad
.sp .6
.RS 4n
-Indicates whether the file system should reject file names that include characters that are not present in the \fBUTF-8\fR character code set. If this property is explicitly set to "\fBoff\fR," the normalization property must either not be
-explicitly set or be set to "\fBnone\fR." The default value for the "\fButf8only\fR" property is "off." This property cannot be changed after the file system is created.
+Indicates whether the file system should reject file names that include characters that are not present in the \fBUTF-8\fR character code set. If this property is explicitly set to "\fBoff\fR," the normalization property must either not be explicitly set or be set to "\fBnone\fR." The default value for the "\fButf8only\fR" property is "off." This property cannot be changed after the file system is created.
.RE
.sp
.LP
-The "\fBcasesensitivity\fR," "\fBnormalization\fR," and "\fButf8only\fR" properties are also new permissions that can be assigned to non-privileged users by using the \fBZFS\fR delegated administration
-feature.
+The "\fBcasesensitivity\fR," "\fBnormalization\fR," and "\fButf8only\fR" properties are also new permissions that can be assigned to non-privileged users by using the \fBZFS\fR delegated administration feature.
.SS "Temporary Mount Point Properties"
.sp
.LP
-When a file system is mounted, either through \fBmount\fR(1M) for legacy mounts or the "\fBzfs mount\fR" command for normal file systems,
-its mount options are set according to its properties. The correlation between properties and mount options is as follows:
+When a file system is mounted, either through \fBmount\fR(1M) for legacy mounts or the "\fBzfs mount\fR" command for normal file systems, its mount options are set according to its properties. The correlation between properties and mount options is as follows:
.sp
.in +2
.nf
PROPERTY MOUNT OPTION
- devices devices/nodevices
- exec exec/noexec
- readonly ro/rw
- setuid setuid/nosetuid
- xattr xattr/noxattr
+ devices devices/nodevices
+ exec exec/noexec
+ readonly ro/rw
+ setuid setuid/nosetuid
+ xattr xattr/noxattr
.fi
.in -2
.sp
.sp
.LP
-In addition, these options can be set on a per-mount basis using the \fB-o\fR option, without affecting the property that is stored on disk. The values specified on the command line override the values stored in the dataset. The \fB-nosuid\fR option is an alias for "nodevices,nosetuid".
-These properties are reported as "temporary" by the "\fBzfs get\fR" command. If the properties are changed while the dataset is mounted, the new setting overrides any temporary settings.
+In addition, these options can be set on a per-mount basis using the \fB-o\fR option, without affecting the property that is stored on disk. The values specified on the command line override the values stored in the dataset. The \fB-nosuid\fR option is an alias for "nodevices,nosetuid". These properties are reported as "temporary" by the "\fBzfs get\fR" command. If the properties are changed while the dataset is mounted, the new setting overrides any temporary settings.
.SS "User Properties"
.sp
.LP
-In addition to the standard native properties, \fBZFS\fR supports arbitrary user properties. User properties have no effect on \fBZFS\fR behavior, but applications or administrators can use them to annotate datasets.
-.sp
-.LP
-User property names must contain a colon (":") character, to distinguish them from native properties. They might contain lowercase letters, numbers, and the following punctuation characters: colon (":"), dash ("-"), period ("."), and underscore
-("_"). The expected convention is that the property name is divided into two portions such as "\fImodule\fR:\fIproperty\fR", but this namespace is not enforced by \fBZFS\fR. User property names can be at most 256 characters,
-and cannot begin with a dash ("-").
+In addition to the standard native properties, \fBZFS\fR supports arbitrary user properties. User properties have no effect on \fBZFS\fR behavior, but applications or administrators can use them to annotate datasets (file systems, volumes, and snapshots).
.sp
.LP
-When making programmatic use of user properties, it is strongly suggested to use a reversed \fBDNS\fR domain name for the \fImodule\fR component of property names to reduce the chance that two independently-developed packages use the same property name for
-different purposes. Property names beginning with "com.sun." are reserved for use by Sun Microsystems.
+User property names must contain a colon (":") character to distinguish them from native properties. They may contain lowercase letters, numbers, and the following punctuation characters: colon (":"), dash ("-"), period ("."), and underscore ("_"). The expected convention is that the property name is divided into two portions such as "\fImodule\fR:\fIproperty\fR", but this namespace is not enforced by \fBZFS\fR. User property names can be at most 256 characters, and cannot begin with a dash ("-").
.sp
.LP
-The values of user properties are arbitrary strings, are always inherited, and are never validated. All of the commands that operate on properties ("zfs list", "zfs get", "zfs set", etc.) can be used to manipulate both native properties and user properties.
-Use the "\fBzfs inherit\fR" command to clear a user property . If the property is not defined in any parent dataset, it is removed entirely. Property values are limited to 1024 characters.
-.SS "Volumes as Swap or Dump Devices"
+When making programmatic use of user properties, it is strongly suggested to use a reversed \fBDNS\fR domain name for the \fImodule\fR component of property names to reduce the chance that two independently-developed packages use the same property name for different purposes. Property names beginning with "com.sun." are reserved for use by Sun Microsystems.
.sp
.LP
-To set up a swap area, create a \fBZFS\fR volume of a specific size and then enable swap on that device. For more information, see the EXAMPLES section.
+The values of user properties are arbitrary strings, are always inherited, and are never validated. All of the commands that operate on properties ("zfs list", "zfs get", "zfs set", etc.) can be used to manipulate both native properties and user properties. Use the "\fBzfs inherit\fR" command to clear a user property . If the property is not defined in any parent dataset, it is removed entirely. Property values are limited to 1024 characters.
+.SS "ZFS Volumes as Swap or Dump Devices"
.sp
.LP
-Do not swap to a file on a \fBZFS\fR file system. A \fBZFS\fR swap file configuration is not supported.
+During an initial installation or a live upgrade from a \fBUFS\fR file system, a swap device and dump device are created on \fBZFS\fR volumes in the \fBZFS\fR root pool. By default, the swap area size is based on 1/2 the size of physical memory up to 2 Gbytes. The size of the dump device depends on the kernel's requirements at installation time. Separate \fBZFS\fR volumes must be used for the swap area and dump devices. Do not swap to a file on a \fBZFS\fR file system. A \fBZFS\fR swap file configuration is not supported.
.sp
.LP
-Using a \fBZFS\fR volume as a dump device is not supported.
+If you need to change your swap area or dump device after the system is installed or upgraded, use the \fBswap\fR(1M) and \fBdumpadm\fR(1M) commands. If you need to change the size of your swap area or dump device, see the \fISolaris ZFS Administration Guide\fR.
.SH SUBCOMMANDS
.sp
.LP
@@ -974,10 +962,9 @@ Creates a new \fBZFS\fR file system. The file system is automatically mounted ac
.na
\fB\fB-p\fR\fR
.ad
-.RS 21n
-.rt
-Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If
-the target filesystem already exists, the operation completes successfully.
+.sp .6
+.RS 4n
+Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If the target filesystem already exists, the operation completes successfully.
.RE
.sp
@@ -986,10 +973,9 @@ the target filesystem already exists, the operation completes successfully.
.na
\fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
.ad
-.RS 21n
-.rt
-Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An
-error results if the same property is specified in multiple \fB-o\fR options.
+.sp .6
+.RS 4n
+Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An error results if the same property is specified in multiple \fB-o\fR options.
.RE
.RE
@@ -1002,8 +988,7 @@ error results if the same property is specified in multiple \fB-o\fR options.
.ad
.sp .6
.RS 4n
-Creates a volume of the given size. The volume is exported as a block device in \fB/dev/zvol/{dsk,rdsk}/\fIpath\fR\fR, where \fIpath\fR is the name of the volume in the \fBZFS\fR namespace. The size represents
-the logical size as exported by the device. By default, a reservation of equal size is created.
+Creates a volume of the given size. The volume is exported as a block device in \fB/dev/zvol/{dsk,rdsk}/\fIpath\fR\fR, where \fIpath\fR is the name of the volume in the \fBZFS\fR namespace. The size represents the logical size as exported by the device. By default, a reservation of equal size is created.
.sp
\fIsize\fR is automatically rounded up to the nearest 128 Kbytes to ensure that the volume has an integral number of blocks regardless of \fIblocksize\fR.
.sp
@@ -1012,10 +997,9 @@ the logical size as exported by the device. By default, a reservation of equal s
.na
\fB\fB-p\fR\fR
.ad
-.RS 21n
-.rt
-Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If
-the target filesystem already exists, the operation completes successfully.
+.sp .6
+.RS 4n
+Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If the target filesystem already exists, the operation completes successfully.
.RE
.sp
@@ -1024,8 +1008,8 @@ the target filesystem already exists, the operation completes successfully.
.na
\fB\fB-s\fR\fR
.ad
-.RS 21n
-.rt
+.sp .6
+.RS 4n
Creates a sparse volume with no reservation. See "volsize" in the Native Properties section for more information about sparse volumes.
.RE
@@ -1035,10 +1019,9 @@ Creates a sparse volume with no reservation. See "volsize" in the Native Propert
.na
\fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
.ad
-.RS 21n
-.rt
-Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An
-error results if the same property is specified in multiple \fB-o\fR options.
+.sp .6
+.RS 4n
+Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An error results if the same property is specified in multiple \fB-o\fR options.
.RE
.sp
@@ -1047,10 +1030,9 @@ error results if the same property is specified in multiple \fB-o\fR options.
.na
\fB\fB-b\fR \fIblocksize\fR\fR
.ad
-.RS 21n
-.rt
-Equivalent to "\fB\fR\fB-o\fR \fBvolblocksize=\fIblocksize\fR\fR". If this option is specified in conjunction with "\fB\fR\fB-o\fR \fBvolblocksize\fR", the resulting
-behavior is undefined.
+.sp .6
+.RS 4n
+Equivalent to "\fB\fR\fB-o\fR \fBvolblocksize=\fIblocksize\fR\fR". If this option is specified in conjunction with "\fB\fR\fB-o\fR \fBvolblocksize\fR", the resulting behavior is undefined.
.RE
.RE
@@ -1070,8 +1052,8 @@ Destroys the given dataset. By default, the command unshares any file systems th
.na
\fB\fB-r\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively destroy all children. If a snapshot is specified, destroy all snapshots with this name in descendent file systems.
.RE
@@ -1081,8 +1063,8 @@ Recursively destroy all children. If a snapshot is specified, destroy all snapsh
.na
\fB\fB-R\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively destroy all dependents, including cloned file systems outside the target hierarchy. If a snapshot is specified, destroy all snapshots with this name in descendent file systems.
.RE
@@ -1092,8 +1074,8 @@ Recursively destroy all dependents, including cloned file systems outside the ta
.na
\fB\fB-f\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Force an unmount of any file systems using the "\fBunmount -f\fR" command. This option has no effect on non-file systems or unmounted file systems.
.RE
@@ -1104,7 +1086,7 @@ Extreme care should be taken when applying either the \fB-r\fR or the \fB-f\fR o
.ne 2
.mk
.na
-\fB\fBzfs snapshot\fR [\fB-r\fR] \fIfilesystem@snapname\fR|\fIvolume@snapname\fR\fR
+\fB\fBzfs snapshot\fR [\fB-r\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR] ... \fIfilesystem@snapname\fR|\fIvolume@snapname\fR\fR
.ad
.sp .6
.RS 4n
@@ -1115,11 +1097,22 @@ Creates a snapshot with the given name. See the "Snapshots" section for details.
.na
\fB\fB-r\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively create snapshots of all descendent datasets. Snapshots are taken atomically, so that all recursive snapshots correspond to the same moment in time.
.RE
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
+.ad
+.sp .6
+.RS 4n
+Sets the specified property; see "\fBzfs create\fR" for details.
+.RE
+
.RE
.sp
@@ -1130,16 +1123,15 @@ Recursively create snapshots of all descendent datasets. Snapshots are taken ato
.ad
.sp .6
.RS 4n
-Roll back the given dataset to a previous snapshot. When a dataset is rolled back, all data that has changed since the snapshot is discarded, and the dataset reverts to the state at the time of the snapshot. By default, the command refuses to roll back to a snapshot other than
-the most recent one. In order to do so, all intermediate snapshots must be destroyed by specifying the \fB-r\fR option.
+Roll back the given dataset to a previous snapshot. When a dataset is rolled back, all data that has changed since the snapshot is discarded, and the dataset reverts to the state at the time of the snapshot. By default, the command refuses to roll back to a snapshot other than the most recent one. In order to do so, all intermediate snapshots must be destroyed by specifying the \fB-r\fR option.
.sp
.ne 2
.mk
.na
\fB\fB-r\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively destroy any snapshots more recent than the one specified.
.RE
@@ -1149,8 +1141,8 @@ Recursively destroy any snapshots more recent than the one specified.
.na
\fB\fB-R\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively destroy any more recent snapshots, as well as any clones of those snapshots.
.RE
@@ -1160,8 +1152,8 @@ Recursively destroy any more recent snapshots, as well as any clones of those sn
.na
\fB\fB-f\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Used with the \fB-R\fR option to force an unmount of any clone file systems that are to be destroyed.
.RE
@@ -1171,7 +1163,7 @@ Used with the \fB-R\fR option to force an unmount of any clone file systems that
.ne 2
.mk
.na
-\fB\fBzfs clone\fR [\fB-p\fR] \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR\fR
+\fB\fBzfs clone\fR [\fB-p\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR] ... \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR\fR
.ad
.sp .6
.RS 4n
@@ -1182,11 +1174,22 @@ Creates a clone of the given snapshot. See the "Clones" section for details. The
.na
\fB\fB-p\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. If the target filesystem or volume already exists, the operation completes successfully.
.RE
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
+.ad
+.sp .6
+.RS 4n
+Sets the specified property; see "\fBzfs create\fR" for details.
+.RE
+
.RE
.sp
@@ -1197,11 +1200,9 @@ Creates all the non-existing parent datasets. Datasets created in this manner ar
.ad
.sp .6
.RS 4n
-Promotes a clone file system to no longer be dependent on its "origin" snapshot. This makes it possible to destroy the file system that the clone was created from. The clone parent-child dependency relationship is reversed, so that the "origin" file system
-becomes a clone of the specified file system.
+Promotes a clone file system to no longer be dependent on its "origin" snapshot. This makes it possible to destroy the file system that the clone was created from. The clone parent-child dependency relationship is reversed, so that the "origin" file system becomes a clone of the specified file system.
.sp
-The snapshot that was cloned, and any snapshots previous to this snapshot, are now owned by the promoted clone. The space they use moves from the "origin" file system to the promoted clone, so enough space must be available to accommodate these snapshots. No new space is consumed
-by this operation, but the space accounting is adjusted. The promoted clone must not have any conflicting snapshot names of its own. The "\fBrename\fR" subcommand can be used to rename any conflicting snapshots.
+The snapshot that was cloned, and any snapshots previous to this snapshot, are now owned by the promoted clone. The space they use moves from the "origin" file system to the promoted clone, so enough space must be available to accommodate these snapshots. No new space is consumed by this operation, but the space accounting is adjusted. The promoted clone must not have any conflicting snapshot names of its own. The "\fBrename\fR" subcommand can be used to rename any conflicting snapshots.
.RE
.sp
@@ -1216,21 +1217,19 @@ by this operation, but the space accounting is adjusted. The promoted clone must
.ad
.br
.na
-\fB\fBzfs
-rename\fR [\fB-p\fR] \fIfilesystem\fR|\fIvolume\fR \fIfilesystem\fR|\fIvolume\fR\fR
+\fB\fBzfs rename\fR [\fB-p\fR] \fIfilesystem\fR|\fIvolume\fR \fIfilesystem\fR|\fIvolume\fR\fR
.ad
.sp .6
.RS 4n
-Renames the given dataset. The new target can be located anywhere in the \fBZFS\fR hierarchy, with the exception of snapshots. Snapshots can only be renamed within the parent file system or volume. When renaming a snapshot, the parent file system of the snapshot does
-not need to be specified as part of the second argument. Renamed file systems can inherit new mount points, in which case they are unmounted and remounted at the new mount point.
+Renames the given dataset. The new target can be located anywhere in the \fBZFS\fR hierarchy, with the exception of snapshots. Snapshots can only be renamed within the parent file system or volume. When renaming a snapshot, the parent file system of the snapshot does not need to be specified as part of the second argument. Renamed file systems can inherit new mount points, in which case they are unmounted and remounted at the new mount point.
.sp
.ne 2
.mk
.na
\fB\fB-p\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent.
.RE
@@ -1259,7 +1258,7 @@ Recursively rename the snapshots of all descendent datasets. Snapshots are the o
.ad
.sp .6
.RS 4n
-Lists the property information for the given datasets in tabular form. If specified, you can list property information by the absolute pathname or the relative pathname. By default, all datasets are displayed and contain the following fields:
+Lists the property information for the given datasets in tabular form. If specified, you can list property information by the absolute pathname or the relative pathname. By default, all file systems and volumes are displayed. Snapshots are displayed if the "listsnaps" property is "on" (the default is "off") . The following fields are displayed:
.sp
.in +2
.nf
@@ -1274,8 +1273,8 @@ name,used,available,referenced,mountpoint
.na
\fB\fB-H\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
Used for scripting mode. Do not print headers and separate fields by a single tab instead of arbitrary whitespace.
.RE
@@ -1285,8 +1284,8 @@ Used for scripting mode. Do not print headers and separate fields by a single ta
.na
\fB\fB-r\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
Recursively display any children of the dataset on the command line.
.RE
@@ -1296,9 +1295,33 @@ Recursively display any children of the dataset on the command line.
.na
\fB\fB-o\fR \fIproperty\fR\fR
.ad
-.RS 15n
-.rt
-A comma-separated list of properties to display. The property must be one of the properties described in the "Native Properties" section, or the special value "name" to display the dataset name.
+.sp .6
+.RS 4n
+A comma-separated list of properties to display. The property must be:
+.RS +4
+.TP
+.ie t \(bu
+.el o
+one of the properties described in the "Native Properties" section.
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+a user property.
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+the value "name" to display the dataset name.
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+the value "space" to display space usage properties on file systems and volumes. This is a shortcut for "\fB-o name,avail,used,usedsnap,usedds, usedrefreserv,usedchild -t filesystem,volume\fR".
+.RE
.RE
.sp
@@ -1307,10 +1330,9 @@ A comma-separated list of properties to display. The property must be one of the
.na
\fB\fB-s\fR \fIproperty\fR\fR
.ad
-.RS 15n
-.rt
-A property to use for sorting the output by column in ascending order based on the value of the property. The property must be one of the properties described in the "Properties" section, or the special value "name" to sort by the dataset name. Multiple
-properties can be specified at one time using multiple \fB-s\fR property options. Multiple \fB-s\fR options are evaluated from left to right in decreasing order of importance.
+.sp .6
+.RS 4n
+A property to use for sorting the output by column in ascending order based on the value of the property. The property must be one of the properties described in the "Properties" section, or the special value "name" to sort by the dataset name. Multiple properties can be specified at one time using multiple \fB-s\fR property options. Multiple \fB-s\fR options are evaluated from left to right in decreasing order of importance.
.sp
The following is a list of sorting criteria:
.RS +4
@@ -1345,8 +1367,8 @@ If no sorting options are specified the existing behavior of "\fBzfs list\fR" is
.na
\fB\fB-S\fR \fIproperty\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
Same as the \fB-s\fR option, but sorts by property in descending order.
.RE
@@ -1356,9 +1378,9 @@ Same as the \fB-s\fR option, but sorts by property in descending order.
.na
\fB\fB-t\fR \fItype\fR\fR
.ad
-.RS 15n
-.rt
-A comma-separated list of types to display, where "type" is one of "filesystem", "snapshot" or "volume". For example, specifying "\fB-t snapshot\fR" displays only snapshots.
+.sp .6
+.RS 4n
+A comma-separated list of types to display, where "type" is one of "filesystem", "snapshot" , "volume" or "all". For example, specifying "\fB-t snapshot\fR" displays only snapshots.
.RE
.RE
@@ -1367,12 +1389,11 @@ A comma-separated list of types to display, where "type" is one of "filesystem",
.ne 2
.mk
.na
-\fB\fBzfs set\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR ...\fR
+\fB\fBzfs set\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...\fR
.ad
.sp .6
.RS 4n
-Sets the property to the given value for each dataset. Only some properties can be edited. See the "Properties" section for more information on what properties can be set and acceptable values. Numeric values can be specified as exact values, or in a human-readable
-form with a suffix of "B", "K", "M", "G", "T", "P", "E", "Z" (for bytes, Kbytes, Mbytes, gigabytes, terabytes, petabytes, exabytes, or zettabytes, respectively). Properties cannot be set on snapshots.
+Sets the property to the given value for each dataset. Only some properties can be edited. See the "Properties" section for more information on what properties can be set and acceptable values. Numeric values can be specified as exact values, or in a human-readable form with a suffix of "B", "K", "M", "G", "T", "P", "E", "Z" (for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or zettabytes, respectively). Properties cannot be set on snapshots.
.RE
.sp
@@ -1388,25 +1409,25 @@ Displays properties for the given datasets. If no datasets are specified, then t
.in +2
.nf
name Dataset name
- property Property name
- value Property value
- source Property source. Can either be local, default,
- temporary, inherited, or none (-).
+ property Property name
+ value Property value
+ source Property source. Can either be local, default,
+ temporary, inherited, or none (-).
.fi
.in -2
.sp
All columns are displayed by default, though this can be controlled by using the \fB-o\fR option. This command takes a comma-separated list of properties as described in the "Native Properties" and "User Properties" sections.
.sp
-The special value "all" can be used to display all properties for the given dataset.
+The special value "all" can be used to display all properties that apply to the given dataset's type (filesystem, volume or snapshot).
.sp
.ne 2
.mk
.na
\fB\fB-r\fR\fR
.ad
-.RS 13n
-.rt
+.sp .6
+.RS 4n
Recursively display properties for any children.
.RE
@@ -1416,8 +1437,8 @@ Recursively display properties for any children.
.na
\fB\fB-H\fR\fR
.ad
-.RS 13n
-.rt
+.sp .6
+.RS 4n
Display output in a form more easily parsed by scripts. Any headers are omitted, and fields are explicitly separated by a single tab instead of an arbitrary amount of space.
.RE
@@ -1427,8 +1448,8 @@ Display output in a form more easily parsed by scripts. Any headers are omitted,
.na
\fB\fB-o\fR \fIfield\fR\fR
.ad
-.RS 13n
-.rt
+.sp .6
+.RS 4n
A comma-separated list of columns to display. "name,property,value,source" is the default value.
.RE
@@ -1438,8 +1459,8 @@ A comma-separated list of columns to display. "name,property,value,source" is th
.na
\fB\fB-s\fR \fIsource\fR\fR
.ad
-.RS 13n
-.rt
+.sp .6
+.RS 4n
A comma-separated list of sources to display. Those properties coming from a source other than those in this list are ignored. Each source must be one of the following: "local,default,inherited,temporary,none". The default value is all sources.
.RE
@@ -1449,8 +1470,8 @@ A comma-separated list of sources to display. Those properties coming from a sou
.na
\fB\fB-p\fR\fR
.ad
-.RS 13n
-.rt
+.sp .6
+.RS 4n
Display numbers in parsable (exact) values.
.RE
@@ -1460,7 +1481,7 @@ Display numbers in parsable (exact) values.
.ne 2
.mk
.na
-\fB\fBzfs inherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume\fR ...\fR
+\fB\fBzfs inherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...\fR
.ad
.sp .6
.RS 4n
@@ -1471,8 +1492,8 @@ Clears the specified property, causing it to be inherited from an ancestor. If n
.na
\fB\fB-r\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively inherit the given property for all children.
.RE
@@ -1497,8 +1518,7 @@ Displays a list of file systems that are not the most recent version.
.ad
.sp .6
.RS 4n
-Upgrades file systems to a new on-disk version. Once this is done, the file systems will no longer be accessible on systems running older versions of the software. "\fBzfs send\fR" streams generated from new snapshots of these file systems can not be accessed
-on systems running older versions of the software.
+Upgrades file systems to a new on-disk version. Once this is done, the file systems will no longer be accessible on systems running older versions of the software. "\fBzfs send\fR" streams generated from new snapshots of these file systems can not be accessed on systems running older versions of the software.
.sp
The file system version is independent of the pool version (see \fBzpool\fR(1M) for information on the "\fBzpool upgrade\fR" command).
.sp
@@ -1509,8 +1529,8 @@ The file system version does not have to be upgraded when the pool version is up
.na
\fB\fB-a\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Upgrade all file systems on all imported pools.
.RE
@@ -1520,8 +1540,8 @@ Upgrade all file systems on all imported pools.
.na
\fB\fIfilesystem\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Upgrade the specified file system.
.RE
@@ -1531,8 +1551,8 @@ Upgrade the specified file system.
.na
\fB\fB-r\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Upgrade the specified file system and all descendent file systems
.RE
@@ -1542,10 +1562,9 @@ Upgrade the specified file system and all descendent file systems
.na
\fB\fB-V\fR \fIversion\fR\fR
.ad
-.RS 14n
-.rt
-Upgrade to the specified \fIversion\fR. If the \fB-V\fR flag is not specified, this command upgrades to the most recent version. This option can only be used to increase the version number, and only up to the most recent version supported by this
-software.
+.sp .6
+.RS 4n
+Upgrade to the specified \fIversion\fR. If the \fB-V\fR flag is not specified, this command upgrades to the most recent version. This option can only be used to increase the version number, and only up to the most recent version supported by this software.
.RE
.RE
@@ -1576,8 +1595,8 @@ Mounts \fBZFS\fR file systems. Invoked automatically as part of the boot process
.na
\fB\fB-o\fR \fIoptions\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
An optional comma-separated list of mount options to use temporarily for the duration of the mount. See the "Temporary Mount Point Properties" section for details.
.RE
@@ -1587,8 +1606,8 @@ An optional comma-separated list of mount options to use temporarily for the dur
.na
\fB\fB-O\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Perform an overlay mount. See \fBmount\fR(1M) for more information.
.RE
@@ -1598,8 +1617,8 @@ Perform an overlay mount. See \fBmount\fR(1M) for more information.
.na
\fB\fB-v\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Report mount progress.
.RE
@@ -1609,8 +1628,8 @@ Report mount progress.
.na
\fB\fB-a\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Mount all available \fBZFS\fR file systems. Invoked automatically as part of the boot process.
.RE
@@ -1620,8 +1639,8 @@ Mount all available \fBZFS\fR file systems. Invoked automatically as part of the
.na
\fB\fIfilesystem\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Mount the specified filesystem.
.RE
@@ -1642,8 +1661,8 @@ Unmounts currently mounted \fBZFS\fR file systems. Invoked automatically as part
.na
\fB\fB-f\fR\fR
.ad
-.RS 25n
-.rt
+.sp .6
+.RS 4n
Forcefully unmount the file system, even if it is currently in use.
.RE
@@ -1653,8 +1672,8 @@ Forcefully unmount the file system, even if it is currently in use.
.na
\fB\fB-a\fR\fR
.ad
-.RS 25n
-.rt
+.sp .6
+.RS 4n
Unmount all available \fBZFS\fR file systems. Invoked automatically as part of the boot process.
.RE
@@ -1664,8 +1683,8 @@ Unmount all available \fBZFS\fR file systems. Invoked automatically as part of t
.na
\fB\fIfilesystem\fR|\fImountpoint\fR\fR
.ad
-.RS 25n
-.rt
+.sp .6
+.RS 4n
Unmount the specified filesystem. The command can also be given a path to a \fBZFS\fR file system mount point on the system.
.RE
@@ -1686,8 +1705,8 @@ Shares available \fBZFS\fR file systems.
.na
\fB\fB-a\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Share all available \fBZFS\fR file systems. Invoked automatically as part of the boot process.
.RE
@@ -1697,8 +1716,8 @@ Share all available \fBZFS\fR file systems. Invoked automatically as part of the
.na
\fB\fIfilesystem\fR\fR
.ad
-.RS 14n
-.rt
+.sp .6
+.RS 4n
Share the specified filesystem according to the "sharenfs" and "sharesmb" properties. File systems are shared when the "sharenfs" or "sharesmb" property is set.
.RE
@@ -1719,8 +1738,8 @@ Unshares currently shared \fBZFS\fR file systems. This is invoked automatically
.na
\fB\fB-a\fR\fR
.ad
-.RS 25n
-.rt
+.sp .6
+.RS 4n
Unshare all available \fBZFS\fR file systems. Invoked automatically as part of the boot process.
.RE
@@ -1730,8 +1749,8 @@ Unshare all available \fBZFS\fR file systems. Invoked automatically as part of t
.na
\fB\fIfilesystem\fR|\fImountpoint\fR\fR
.ad
-.RS 25n
-.rt
+.sp .6
+.RS 4n
Unshare the specified filesystem. The command can also be given a path to a \fBZFS\fR file system shared on the system.
.RE
@@ -1741,7 +1760,7 @@ Unshare the specified filesystem. The command can also be given a path to a \fBZ
.ne 2
.mk
.na
-\fB\fBzfs send\fR [\fB-vR\fR] [\fB-\fR[\fB-iI\fR] \fIsnapshot\fR] \fIsnapshot\fR\fR
+\fB\fBzfs send\fR [\fB-vR\fR] [\fB-\fR[\fBiI\fR] \fIsnapshot\fR] \fIsnapshot\fR\fR
.ad
.sp .6
.RS 4n
@@ -1752,10 +1771,9 @@ Creates a stream representation of the second \fIsnapshot\fR, which is written t
.na
\fB\fB-i\fR \fIsnapshot\fR\fR
.ad
-.RS 15n
-.rt
-Generate an incremental stream from the first \fIsnapshot\fR to the second \fIsnapshot\fR. The incremental source (the first \fIsnapshot\fR) can be specified as the last component of the snapshot name (for example,
-the part after the "@"), and it is assumed to be from the same file system as the second \fIsnapshot\fR.
+.sp .6
+.RS 4n
+Generate an incremental stream from the first \fIsnapshot\fR to the second \fIsnapshot\fR. The incremental source (the first \fIsnapshot\fR) can be specified as the last component of the snapshot name (for example, the part after the "@"), and it is assumed to be from the same file system as the second \fIsnapshot\fR.
.sp
If the destination is a clone, the source may be the origin snapshot, which must be fully specified (for example, "pool/fs@origin", not just "@origin").
.RE
@@ -1766,10 +1784,9 @@ If the destination is a clone, the source may be the origin snapshot, which must
.na
\fB\fB-I\fR \fIsnapshot\fR\fR
.ad
-.RS 15n
-.rt
-Generate a stream package that sends all intermediary snapshots from the first snapshot to the second snapshot. For example, "\fB-I @a fs@d\fR" is similar to "\fB-i @a fs@b; -i @b fs@c; -i @c fs@d\fR". The incremental source snapshot
-may be specified as with the \fB-i\fR option.
+.sp .6
+.RS 4n
+Generate a stream package that sends all intermediary snapshots from the first snapshot to the second snapshot. For example, "\fB-I @a fs@d\fR" is similar to "\fB-i @a fs@b; -i @b fs@c; -i @c fs@d\fR". The incremental source snapshot may be specified as with the \fB-i\fR option.
.RE
.sp
@@ -1778,8 +1795,8 @@ may be specified as with the \fB-i\fR option.
.na
\fB\fB-R\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
Generate a replication stream package, which will replicate the specified filesystem, and all descendant file systems, up to the named snapshot. When received, all properties, snapshots, descendent file systems, and clones are preserved.
.sp
If the \fB-i\fR or \fB-I\fR flags are used in conjunction with the \fB-R\fR flag, an incremental replication stream is generated. The current values of properties, and current snapshot and file system names are set when the stream is received. If the \fB-F\fR flag is specified when this stream is recieved, snapshots and file systems that do not exist on the sending side are destroyed.
@@ -1791,8 +1808,8 @@ If the \fB-i\fR or \fB-I\fR flags are used in conjunction with the \fB-R\fR flag
.na
\fB\fB-v\fR\fR
.ad
-.RS 15n
-.rt
+.sp .6
+.RS 4n
Print verbose information about the stream package generated.
.RE
@@ -1811,24 +1828,21 @@ The format of the stream is evolving. No backwards compatibility is guaranteed.
.ad
.sp .6
.RS 4n
-Creates a snapshot whose contents are as specified in the stream provided on standard input. If a full stream is received, then a new file system is created as well. Streams are created using the "\fBzfs send\fR" subcommand, which by default creates a full
-stream. "\fBzfs recv\fR" can be used as an alias for "\fBzfs receive\fR".
+Creates a snapshot whose contents are as specified in the stream provided on standard input. If a full stream is received, then a new file system is created as well. Streams are created using the "\fBzfs send\fR" subcommand, which by default creates a full stream. "\fBzfs recv\fR" can be used as an alias for "\fBzfs receive\fR".
.sp
-If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's source. For \fBzvols\fR, the destination device link is destroyed and re-created, which means the \fBzvol\fR cannot
-be accessed during the \fBreceive\fR operation.
+If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's source. For \fBzvols\fR, the destination device link is destroyed and re-created, which means the \fBzvol\fR cannot be accessed during the \fBreceive\fR operation.
.sp
The name of the snapshot (and file system, if a full stream is received) that this subcommand creates depends on the argument type and the \fB-d\fR option.
.sp
-If the argument is a snapshot name, the specified \fIsnapshot\fR is created. If the argument is a file system or volume name, a snapshot with the same name as the sent snapshot is created within the specified \fIfilesystem\fR or \fIvolume\fR.
-If the \fB-d\fR option is specified, the snapshot name is determined by appending the sent snapshot's name to the specified \fIfilesystem\fR. If the \fB-d\fR option is specified, any required file systems within the specified one are created.
+If the argument is a snapshot name, the specified \fIsnapshot\fR is created. If the argument is a file system or volume name, a snapshot with the same name as the sent snapshot is created within the specified \fIfilesystem\fR or \fIvolume\fR. If the \fB-d\fR option is specified, the snapshot name is determined by appending the sent snapshot's name to the specified \fIfilesystem\fR. If the \fB-d\fR option is specified, any required file systems within the specified one are created.
.sp
.ne 2
.mk
.na
\fB\fB-d\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Use the name of the sent snapshot to determine the name of the new snapshot as described in the paragraph above.
.RE
@@ -1838,8 +1852,8 @@ Use the name of the sent snapshot to determine the name of the new snapshot as d
.na
\fB\fB-v\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Print verbose information about the stream and the time required to perform the receive operation.
.RE
@@ -1849,8 +1863,8 @@ Print verbose information about the stream and the time required to perform the
.na
\fB\fB-n\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Do not actually receive the stream. This can be useful in conjunction with the \fB-v\fR option to verify the name the receive operation would use.
.RE
@@ -1860,10 +1874,9 @@ Do not actually receive the stream. This can be useful in conjunction with the \
.na
\fB\fB-F\fR\fR
.ad
-.RS 6n
-.rt
-Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by "z\fBfs send -R -[iI]\fR"), destroy snapshots and file systems that do
-not exist on the sending side.
+.sp .6
+.RS 4n
+Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by "z\fBfs send -R -[iI]\fR"), destroy snapshots and file systems that do not exist on the sending side.
.RE
.RE
@@ -1889,8 +1902,7 @@ Delegates \fBZFS\fR administration permission for the file systems to non-privil
.ad
.sp .6
.RS 4n
-Specifies to whom the permissions are delegated. Multiple entities can be specified as a comma-separated list. If neither of the \fB-ug\fR options are specified, then the argument is interpreted preferentially as the keyword "everyone", then as a user name,
-and lastly as a group name. To specify a user or group named "everyone", use the \fB-u\fR or \fB-g\fR options. To specify a group with the same name as a user, use the \fB-g\fR options.
+Specifies to whom the permissions are delegated. Multiple entities can be specified as a comma-separated list. If neither of the \fB-ug\fR options are specified, then the argument is interpreted preferentially as the keyword "everyone", then as a user name, and lastly as a group name. To specify a user or group named "everyone", use the \fB-u\fR or \fB-g\fR options. To specify a group with the same name as a user, use the \fB-g\fR options.
.RE
.sp
@@ -1901,8 +1913,7 @@ and lastly as a group name. To specify a user or group named "everyone", use the
.ad
.sp .6
.RS 4n
-Specifies that the permissions be delegated to "everyone." Multiple permissions may be specified as a comma-separated list. Permission names are the same as \fBZFS\fR subcommand and property names. See the property list below. Property set names, which
-begin with an "at sign" ("@") , may be specified. See the \fB-s\fR form below for details.
+Specifies that the permissions be delegated to "everyone." Multiple permissions may be specified as a comma-separated list. Permission names are the same as \fBZFS\fR subcommand and property names. See the property list below. Property set names, which begin with an "at sign" ("@") , may be specified. See the \fB-s\fR form below for details.
.RE
.sp
@@ -1913,8 +1924,7 @@ begin with an "at sign" ("@") , may be specified. See the \fB-s\fR form below fo
.ad
.sp .6
.RS 4n
-Specifies where the permissions are delegated. If neither of the \fB-ld\fR options are specified, or both are, then the permissions are allowed for the file system or volume, and all of its descendents. If only the \fB-l\fR option is used, then is allowed "locally"
-only for the specified file system. If only the \fB-d\fR option is used, then is allowed only for the descendent file systems.
+Specifies where the permissions are delegated. If neither of the \fB-ld\fR options are specified, or both are, then the permissions are allowed for the file system or volume, and all of its descendents. If only the \fB-l\fR option is used, then is allowed "locally" only for the specified file system. If only the \fB-d\fR option is used, then is allowed only for the descendent file systems.
.RE
.RE
@@ -1927,49 +1937,51 @@ Permissions are generally the ability to use a \fBZFS\fR subcommand or change a
.nf
NAME TYPE NOTES
allow subcommand Must also have the permission
- that is being allowed.
+ that is being allowed.
clone subcommand Must also have the 'create' ability
- and the 'mount' ability in the origin
- file system.
+ and the 'mount' ability in the origin
+ file system.
create subcommand Must also have the 'mount' ability.
destroy subcommand Must also have the 'mount' ability.
mount subcommand Allows mount, unmount, and
- create/remove zvol device links.
+ create/remove zvol device links.
promote subcommand Must also have the 'mount' ability and
- 'promote' ability in the origin file system.
+ 'promote' ability in the origin file system.
receive subcommand Must also have the 'mount' ability and
- the 'create' ability.
+ the 'create' ability.
rename subcommand Must also have the 'mount' ability and
- the 'create' ability in the new parent.
+ the 'create' ability in the new parent.
rollback subcommand Must also have the 'mount' ability.
snapshot subcommand Must also have the 'mount' ability.
share subcommand Allows share and unshare.
send subcommand
-
-
-aclinherit property
-aclmode property
-atime property
-canmount property
-checksum property
-compression property
-copies property
-devices property
-exec property
-mountpoint property
-quota property
-readonly property
-recordsize property
-reservation property
-setuid property
-shareiscsi property
-sharenfs property
-snapdir property
-version property
-volsize property
-xattr property
-zoned property
-userprop other Allows changing any user property.
+
+
+aclinherit property
+aclmode property
+atime property
+canmount property
+checksum property
+compression property
+copies property
+devices property
+exec property
+mountpoint property
+primarycache property
+quota property
+readonly property
+recordsize property
+reservation property
+secondarycache property
+setuid property
+shareiscsi property
+sharenfs property
+snapdir property
+version property
+volsize property
+xattr property
+zoned property
+userprop other Allows changing any user property.
.fi
.in -2
.sp
@@ -1993,8 +2005,7 @@ Sets "create time" permissions. These permissions are granted (locally) to the c
.ad
.sp .6
.RS 4n
-Defines or adds permissions to a permission set. The set can be used by other \fBzfs allow\fR commands for the specified file system and its descendents. Sets are evaluated dynamically, so changes to a set are immediately reflected. Permission sets follow the same
-naming restrictions as ZFS file systems, but the name must begin with an "at sign" ("@"), and can be no more than 64 characters long.
+Defines or adds permissions to a permission set. The set can be used by other \fBzfs allow\fR commands for the specified file system and its descendents. Sets are evaluated dynamically, so changes to a set are immediately reflected. Permission sets follow the same naming restrictions as ZFS file systems, but the name must begin with an "at sign" ("@"), and can be no more than 64 characters long.
.RE
.sp
@@ -2017,17 +2028,15 @@ naming restrictions as ZFS file systems, but the name must begin with an "at sig
.ad
.sp .6
.RS 4n
-Removes permissions that were granted with the "\fBzfs allow\fR" command. No permissions are explicitly denied, so other permissions granted are still in effect. For example, if the permission is granted by an ancestor. If no permissions are specified,
-then all permissions for the specified \fIuser\fR, \fIgroup\fR, or \fIeveryone\fR are removed. Specifying "everyone" (or using the \fB-e\fR option) only removes the permissions that were granted to "everyone",
-not all permissions for every user and group. See the "\fBzfs allow\fR" command for a description of the \fB-ldugec\fR options.
+Removes permissions that were granted with the "\fBzfs allow\fR" command. No permissions are explicitly denied, so other permissions granted are still in effect. For example, if the permission is granted by an ancestor. If no permissions are specified, then all permissions for the specified \fIuser\fR, \fIgroup\fR, or \fIeveryone\fR are removed. Specifying "everyone" (or using the \fB-e\fR option) only removes the permissions that were granted to "everyone", not all permissions for every user and group. See the "\fBzfs allow\fR" command for a description of the \fB-ldugec\fR options.
.sp
.ne 2
.mk
.na
\fB\fB-r\fR\fR
.ad
-.RS 6n
-.rt
+.sp .6
+.RS 4n
Recursively remove the permissions from this file system and all descendents.
.RE
@@ -2048,36 +2057,12 @@ Recursively remove the permissions from this file system and all descendents.
Removes permissions from a permission set. If no permissions are specified, then all permissions are removed, thus removing the set entirely.
.RE
-.sp
-.ne 2
-.mk
-.na
-\fB\fBzfs jail\fR \fIjailid\fR \fIfilesystem\fR\fR
-.ad
-.sp .6
-.RS 4n
-Attaches the given file system to the given jail. From now on this file system tree can be managed from within a jail if the "\fBjailed\fR" property has been set.
-To use this functionality, sysctl \fBsecurity.jail.enforce_statfs\fR should be set to 0 and sysctl \fBsecurity.jail.mount_allowed\fR should be set to 1.
-.RE
-
-.sp
-.ne 2
-.mk
-.na
-\fB\fBzfs unjail\fR \fIjailid\fR \fIfilesystem\fR\fR
-.ad
-.sp .6
-.RS 4n
-Detaches the given file system from the given jail.
-.RE
-
.SH EXAMPLES
.LP
\fBExample 1 \fRCreating a ZFS File System Hierarchy
.sp
.LP
-The following commands create a file system named "\fBpool/home\fR" and a file system named "\fBpool/home/bob\fR". The mount point "\fB/export/home\fR" is set for the parent file system, and automatically inherited
-by the child file system.
+The following commands create a file system named "\fBpool/home\fR" and a file system named "\fBpool/home/bob\fR". The mount point "\fB/export/home\fR" is set for the parent file system, and automatically inherited by the child file system.
.sp
.in +2
@@ -2107,8 +2092,7 @@ The following command creates a snapshot named "yesterday". This snapshot is mou
\fBExample 3 \fRTaking and destroying multiple snapshots
.sp
.LP
-The following command creates snapshots named "\fByesterday\fR" of "\fBpool/home\fR" and all of its descendent file systems. Each snapshot is mounted on demand in the ".zfs/snapshot" directory at the root of its file system. The
-second command destroys the newly created snapshots.
+The following command creates snapshots named "\fByesterday\fR" of "\fBpool/home\fR" and all of its descendent file systems. Each snapshot is mounted on demand in the ".zfs/snapshot" directory at the root of its file system. The second command destroys the newly created snapshots.
.sp
.in +2
@@ -2138,7 +2122,7 @@ The following commands turn compression off for all file systems under "\fBpool/
\fBExample 5 \fRListing ZFS Datasets
.sp
.LP
-The following command lists all active file systems and volumes in the system.
+The following command lists all active file systems and volumes in the system. Snapshots are displayed if the "listsnaps" property is "on" (the default is "off") . See \fBzpool\fR(1M) for more information on pool properties.
.sp
.in +2
@@ -2146,12 +2130,11 @@ The following command lists all active file systems and volumes in the system.
\fB# zfs list\fR
- NAME USED AVAIL REFER MOUNTPOINT
- pool 450K 457G 18K /pool
- pool/home 315K 457G 21K /export/home
- pool/home/anne 18K 457G 18K /export/home/anne
- pool/home/bob 276K 457G 276K /export/home/bob
- pool/home/bob@yesterday 0 - 276K -
+ NAME USED AVAIL REFER MOUNTPOINT
+ pool 450K 457G 18K /pool
+ pool/home 315K 457G 21K /export/home
+ pool/home/anne 18K 457G 18K /export/home/anne
+ pool/home/bob 276K 457G 276K /export/home/bob
.fi
.in -2
.sp
@@ -2182,42 +2165,52 @@ The following command lists all properties for "\fBpool/home/bob\fR".
\fB# zfs get all pool/home/bob\fR
- NAME PROPERTY VALUE SOURCE
- pool/home/bob type filesystem -
- pool/home/bob creation Thu Jul 12 14:44 2007 -
- pool/home/bob used 276K -
- pool/home/bob available 50.0G -
- pool/home/bob referenced 276K -
- pool/home/bob compressratio 1.00x -
- pool/home/bob mounted yes -
- pool/home/bob quota 50G local
- pool/home/bob reservation none default
- pool/home/bob recordsize 128K default
- pool/home/bob mountpoint /export/home/bob inherited from
- pool/home
- pool/home/bob checksum on default
- pool/home/bob compression off default
- pool/home/bob atime on default
- pool/home/bob devices on default
- pool/home/bob exec on default
- pool/home/bob setuid on default
- pool/home/bob readonly off default
- pool/home/bob zoned off default
- pool/home/bob snapdir hidden default
- pool/home/bob aclmode groupmask default
- pool/home/bob aclinherit restricted default
- pool/home/bob canmount on default
- pool/home/bob nbmand off default
- pool/home/bob shareiscsi off default
- pool/home/bob sharesmb off default
- pool/home/bob sharenfs off default
- pool/home/bob xattr on default
- pool/home/bob refquota 10M local
- pool/home/bob refreservation none default
- pool/home/bob copies 1 default
- pool/home/bob version 1 -
-
-
+NAME PROPERTY VALUE SOURCE
+pool/home/bob type filesystem -
+pool/home/bob creation Thu Jul 12 14:44 2007 -
+pool/home/bob used 276K -
+pool/home/bob available 50.0G -
+pool/home/bob referenced 276K -
+pool/home/bob compressratio 1.00x -
+pool/home/bob mounted yes -
+pool/home/bob quota 50G local
+pool/home/bob reservation none default
+pool/home/bob recordsize 128K default
+pool/home/bob mountpoint /export/home/bob inherited
+ from
+ pool/home
+pool/home/bob sharenfs off default
+pool/home/bob checksum on default
+pool/home/bob compression off default
+pool/home/bob atime on default
+pool/home/bob devices on default
+pool/home/bob exec on default
+pool/home/bob setuid on default
+pool/home/bob readonly off default
+pool/home/bob zoned off default
+pool/home/bob snapdir hidden default
+pool/home/bob aclmode groupmask default
+pool/home/bob aclinherit restricted default
+pool/home/bob canmount on default
+pool/home/bob shareiscsi off default
+pool/home/bob xattr on default
+pool/home/bob copies 1 default
+pool/home/bob version 1 -
+pool/home/bob utf8only off -
+pool/home/bob normalization none -
+pool/home/bob casesensitivity sensitive -
+pool/home/bob vscan off default
+pool/home/bob nbmand off default
+pool/home/bob sharesmb off default
+pool/home/bob refquota 10M local
+pool/home/bob refreservation none default
+pool/home/bob primarycache all default
+pool/home/bob secondarycache a default
+pool/home/bob usedbysnapshots 0 -
+pool/home/bob usedbydataset 18K -
+pool/home/bob usedbychildren 0 -
+pool/home/bob usedbyrefreservation 0 -
+
.fi
.in -2
.sp
@@ -2244,9 +2237,9 @@ The following command lists all properties with local settings for "\fBpool/home
.nf
\fB# zfs get -r -s local -o name,property,value all pool/home/bob\fR
- NAME PROPERTY VALUE
- pool compression on
- pool/home checksum off
+ NAME PROPERTY VALUE
+ pool compression on
+ pool/home checksum off
.fi
.in -2
.sp
@@ -2289,15 +2282,15 @@ The following commands illustrate how to test out changes to a file system, and
.in +2
.nf
\fB# zfs create pool/project/production\fR
- populate /pool/project/production with data
+ populate /pool/project/production with data
\fB# zfs snapshot pool/project/production@today
# zfs clone pool/project/production@today pool/project/beta\fR
- make changes to /pool/project/beta and test them
+ make changes to /pool/project/beta and test them
\fB# zfs promote pool/project/beta
# zfs rename pool/project/production pool/project/legacy
# zfs rename pool/project/beta pool/project/production\fR
- once the legacy version is no longer needed, it can be
- destroyed
+ once the legacy version is no longer needed, it can be
+ destroyed
\fB# zfs destroy pool/project/legacy\fR
.fi
.in -2
@@ -2321,16 +2314,15 @@ The following command causes "\fBpool/home/bob\fR" and "\fBpool/home/anne\fR" to
\fBExample 12 \fRRemotely Replicating ZFS Data
.sp
.LP
-The following commands send a full stream and then an incremental stream to a remote machine, restoring them into "\fBpoolB/received/fs\fR@a" and "\fBpoolB/received/fs@b\fR", respectively. "\fBpoolB\fR" must contain
-the file system "\fBpoolB/received\fR", and must not initially contain "\fBpoolB/received/fs\fR".
+The following commands send a full stream and then an incremental stream to a remote machine, restoring them into "\fBpoolB/received/fs\fR@a" and "\fBpoolB/received/fs@b\fR", respectively. "\fBpoolB\fR" must contain the file system "\fBpoolB/received\fR", and must not initially contain "\fBpoolB/received/fs\fR".
.sp
.in +2
.nf
# zfs send pool/fs@a | \e
- ssh host zfs receive poolB/received/fs@a
+ ssh host zfs receive poolB/received/fs@a
# zfs send -i a pool/fs@b | ssh host \e
- zfs receive poolB/received/fs
+ zfs receive poolB/received/fs
.fi
.in -2
.sp
@@ -2339,35 +2331,19 @@ the file system "\fBpoolB/received\fR", and must not initially contain "\fBpoolB
\fBExample 13 \fRUsing the zfs receive -d Option
.sp
.LP
-The following command sends a full stream of "\fBpoolA/fsA/fsB@snap\fR" to a remote machine, receiving it into "\fBpoolB/received/fsA/fsB@snap\fR". The "\fBfsA/fsB@snap\fR" portion of the received snapshot's name
-is determined from the name of the sent snapshot. "\fBpoolB\fR" must contain the file system "\fBpoolB/received\fR". If "\fBpoolB/received/fsA\fR" does not exist, it is be created as an empty file system.
+The following command sends a full stream of "\fBpoolA/fsA/fsB@snap\fR" to a remote machine, receiving it into "\fBpoolB/received/fsA/fsB@snap\fR". The "\fBfsA/fsB@snap\fR" portion of the received snapshot's name is determined from the name of the sent snapshot. "\fBpoolB\fR" must contain the file system "\fBpoolB/received\fR". If "\fBpoolB/received/fsA\fR" does not exist, it is be created as an empty file system.
.sp
.in +2
.nf
\fB# zfs send poolA/fsA/fsB@snap | \e
- ssh host zfs receive -d poolB/received\fR
+ ssh host zfs receive -d poolB/received\fR
.fi
.in -2
.sp
.LP
-\fBExample 14 \fRCreating a ZFS volume as a Swap Device
-.sp
-.LP
-The following example shows how to create a 5-Gbyte ZFS volume and then add the volume as a swap device.
-
-.sp
-.in +2
-.nf
-\fB# zfs create -V 5gb tank/vol
-# swap -a /dev/zvol/dsk/tank/vol\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 15 \fRSetting User Properties
+\fBExample 14 \fRSetting User Properties
.sp
.LP
The following example sets the user defined "com.example:department" property for a dataset.
@@ -2381,7 +2357,7 @@ The following example sets the user defined "com.example:department" property fo
.sp
.LP
-\fBExample 16 \fRCreating a ZFS Volume as a iSCSI Target Device
+\fBExample 15 \fRCreating a ZFS Volume as a iSCSI Target Device
.sp
.LP
The following example shows how to create a \fBZFS\fR volume as an \fBiSCSI\fR target.
@@ -2390,12 +2366,12 @@ The following example shows how to create a \fBZFS\fR volume as an \fBiSCSI\fR t
.in +2
.nf
\fB# zfs create -V 2g pool/volumes/vol1
-# zfs set shareiscsi=on pool/volumes/vol1
-# iscsitadm list target\fR
-Target: pool/volumes/vol1
-iSCSI Name:
-iqn.1986-03.com.sun:02:7b4b02a6-3277-eb1b-e686-a24762c52a8c
-Connections: 0
+ # zfs set shareiscsi=on pool/volumes/vol1
+ # iscsitadm list target\fR
+ Target: pool/volumes/vol1
+ iSCSI Name:
+ iqn.1986-03.com.sun:02:7b4b02a6-3277-eb1b-e686-a24762c52a8c
+ Connections: 0
.fi
.in -2
.sp
@@ -2404,7 +2380,7 @@ Connections: 0
.LP
After the \fBiSCSI\fR target is created, set up the \fBiSCSI\fR initiator. For more information about the Solaris \fBiSCSI\fR initiator, see the Solaris Administration Guide: Devices and File Systems.
.LP
-\fBExample 17 \fRPerforming a Rolling Snapshot
+\fBExample 16 \fRPerforming a Rolling Snapshot
.sp
.LP
The following example shows how to maintain a history of snapshots with a consistent naming scheme. To keep a week's worth of snapshots, the user destroys the oldest snapshot, renames the remaining snapshots, and then creates a new snapshot, as follows:
@@ -2424,7 +2400,7 @@ The following example shows how to maintain a history of snapshots with a consis
.sp
.LP
-\fBExample 18 \fRSetting sharenfs Property Options on a ZFS File System
+\fBExample 17 \fRSetting sharenfs Property Options on a ZFS File System
.sp
.LP
The following commands show how to set "sharenfs" property options to enable \fBrw\fR access for a set of \fBIP\fR addresses and to enable root access for system \fBneo\fR on the \fBtank/home\fR file system.
@@ -2433,7 +2409,7 @@ The following commands show how to set "sharenfs" property options to enable \fB
.in +2
.nf
\fB# zfs set sharenfs='rw=@123.123.0.0/16,root=neo' tank/home\fR
-
+
.fi
.in -2
.sp
@@ -2443,7 +2419,7 @@ The following commands show how to set "sharenfs" property options to enable \fB
If you are using \fBDNS\fR for host name resolution, specify the fully qualified hostname.
.LP
-\fBExample 19 \fRDelegating ZFS Administration Permissions on a ZFS Dataset
+\fBExample 18 \fRDelegating ZFS Administration Permissions on a ZFS Dataset
.sp
.LP
The following example shows how to set permissions so that user "\fBcindys\fR" can create, destroy, mount and take snapshots on \fBtank/cindys\fR. The permissions on \fBtank/cindys\fR are also displayed.
@@ -2455,9 +2431,9 @@ The following example shows how to set permissions so that user "\fBcindys\fR" c
# zfs allow tank/cindys\fR
-------------------------------------------------------------
Local+Descendent permissions on (tank/cindys)
- user cindys create,destroy,mount,snapshot
+ user cindys create,destroy,mount,snapshot
-------------------------------------------------------------
-
+
.fi
.in -2
.sp
@@ -2474,7 +2450,7 @@ Because the \fBtank/cindys\fR mount point permission is set to 755 by default, u
.sp
.LP
-\fBExample 20 \fRDelegating Create Time Permissions on a ZFS Dataset
+\fBExample 19 \fRDelegating Create Time Permissions on a ZFS Dataset
.sp
.LP
The following example shows how to grant anyone in the group \fBstaff\fR to create file systems in \fBtank/users\fR. This syntax also allows staff members to destroy their own file systems, but not destroy anyone else's file system. The permissions on \fBtank/users\fR are also displayed.
@@ -2487,16 +2463,16 @@ The following example shows how to grant anyone in the group \fBstaff\fR to crea
# zfs allow tank/users\fR
-------------------------------------------------------------
Create time permissions on (tank/users)
- create,destroy
+ create,destroy
Local+Descendent permissions on (tank/users)
- group staff create,mount
+ group staff create,mount
-------------------------------------------------------------
.fi
.in -2
.sp
.LP
-\fBExample 21 \fRDefining and Granting a Permission Set on a ZFS Dataset
+\fBExample 20 \fRDefining and Granting a Permission Set on a ZFS Dataset
.sp
.LP
The following example shows how to define and grant a permission set on the \fBtank/users\fR file system. The permissions on \fBtank/users\fR are also displayed.
@@ -2509,18 +2485,18 @@ The following example shows how to define and grant a permission set on the \fBt
# zfs allow tank/users
-------------------------------------------------------------
Permission sets on (tank/users)
- @pset create,destroy,mount,snapshot
+ @pset create,destroy,mount,snapshot
Create time permissions on (tank/users)
- create,destroy
+ create,destroy
Local+Descendent permissions on (tank/users)
- group staff @pset,create,mount
+ group staff @pset,create,mount
-------------------------------------------------------------\fR
.fi
.in -2
.sp
.LP
-\fBExample 22 \fRDelegating Property Permissions on a ZFS Dataset
+\fBExample 21 \fRDelegating Property Permissions on a ZFS Dataset
.sp
.LP
The following example shows to grant the ability to set quotas and reservations on the \fBusers/home\fR file system. The permissions on \fBusers/home\fR are also displayed.
@@ -2532,7 +2508,7 @@ The following example shows to grant the ability to set quotas and reservations
# zfs allow users/home\fR
-------------------------------------------------------------
Local+Descendent permissions on (users/home)
- user cindys quota,reservation
+ user cindys quota,reservation
-------------------------------------------------------------
cindys% zfs set quota=10G users/home/marks
cindys% zfs get quota users/home/marks
@@ -2543,7 +2519,7 @@ users/home/marks quota 10G local
.sp
.LP
-\fBExample 23 \fRRemoving ZFS Delegated Permissions on a ZFS Dataset
+\fBExample 22 \fRRemoving ZFS Delegated Permissions on a ZFS Dataset
.sp
.LP
The following example shows how to remove the snapshot permission from the \fBstaff\fR group on the \fBtank/users\fR file system. The permissions on \fBtank/users\fR are also displayed.
@@ -2555,11 +2531,11 @@ The following example shows how to remove the snapshot permission from the \fBst
# zfs allow tank/users\fR
-------------------------------------------------------------
Permission sets on (tank/users)
- @pset create,destroy,mount,snapshot
+ @pset create,destroy,mount,snapshot
Create time permissions on (tank/users)
- create,destroy
+ create,destroy
Local+Descendent permissions on (tank/users)
- group staff @pset,create,mount
+ group staff @pset,create,mount
-------------------------------------------------------------
.fi
.in -2
@@ -2575,8 +2551,8 @@ The following exit values are returned:
.na
\fB\fB0\fR\fR
.ad
-.RS 5n
-.rt
+.sp .6
+.RS 4n
Successful completion.
.RE
@@ -2586,8 +2562,8 @@ Successful completion.
.na
\fB\fB1\fR\fR
.ad
-.RS 5n
-.rt
+.sp .6
+.RS 4n
An error occurred.
.RE
@@ -2597,8 +2573,8 @@ An error occurred.
.na
\fB\fB2\fR\fR
.ad
-.RS 5n
-.rt
+.sp .6
+.RS 4n
Invalid command line options were specified.
.RE
@@ -2627,4 +2603,4 @@ Interface StabilityCommitted
\fBgzip\fR(1), \fBssh\fR(1), \fBmount\fR(1M), \fBshare\fR(1M), \fBsharemgr\fR(1M), \fBunshare\fR(1M), \fBzonecfg\fR(1M), \fBzpool\fR(1M), \fBchmod\fR(2), \fBstat\fR(2), \fBfsync\fR(3c), \fBdfstab\fR(4), \fBattributes\fR(5)
.sp
.LP
-For information about using the \fBZFS\fR web-based management tool and other \fBZFS\fR features, see the \fIZFS Administration Guide\fR.
+For information about using the \fBZFS\fR web-based management tool and other \fBZFS\fR features, see the \fISolaris ZFS Administration Guide\fR.
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
index a22370a..ca5c2b2 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -53,11 +53,14 @@ typedef struct zfs_node {
} zfs_node_t;
typedef struct callback_data {
- uu_avl_t *cb_avl;
- int cb_flags;
- zfs_type_t cb_types;
- zfs_sort_column_t *cb_sortcol;
- zprop_list_t **cb_proplist;
+ uu_avl_t *cb_avl;
+ int cb_flags;
+ zfs_type_t cb_types;
+ zfs_sort_column_t *cb_sortcol;
+ zprop_list_t **cb_proplist;
+ int cb_depth_limit;
+ int cb_depth;
+ uint8_t cb_props_table[ZFS_NUM_PROPS];
} callback_data_t;
uu_avl_pool_t *avl_pool;
@@ -98,10 +101,17 @@ zfs_callback(zfs_handle_t *zhp, void *data)
uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
&idx) == NULL) {
- if (cb->cb_proplist &&
- zfs_expand_proplist(zhp, cb->cb_proplist) != 0) {
- free(node);
- return (-1);
+ if (cb->cb_proplist) {
+ if ((*cb->cb_proplist) &&
+ !(*cb->cb_proplist)->pl_all)
+ zfs_prune_proplist(zhp,
+ cb->cb_props_table);
+
+ if (zfs_expand_proplist(zhp, cb->cb_proplist)
+ != 0) {
+ free(node);
+ return (-1);
+ }
}
uu_avl_insert(cb->cb_avl, node, idx);
dontclose = 1;
@@ -113,11 +123,15 @@ zfs_callback(zfs_handle_t *zhp, void *data)
/*
* Recurse if necessary.
*/
- if (cb->cb_flags & ZFS_ITER_RECURSE) {
+ if (cb->cb_flags & ZFS_ITER_RECURSE &&
+ ((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
+ cb->cb_depth < cb->cb_depth_limit)) {
+ cb->cb_depth++;
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
(void) zfs_iter_snapshots(zhp, zfs_callback, data);
+ cb->cb_depth--;
}
if (!dontclose)
@@ -325,10 +339,10 @@ zfs_sort(const void *larg, const void *rarg, void *data)
int
zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
- zfs_sort_column_t *sortcol, zprop_list_t **proplist,
+ zfs_sort_column_t *sortcol, zprop_list_t **proplist, int limit,
zfs_iter_f callback, void *data)
{
- callback_data_t cb;
+ callback_data_t cb = {0};
int ret = 0;
zfs_node_t *node;
uu_avl_walk_t *walk;
@@ -346,6 +360,45 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
cb.cb_flags = flags;
cb.cb_proplist = proplist;
cb.cb_types = types;
+ cb.cb_depth_limit = limit;
+ /*
+ * If cb_proplist is provided then in the zfs_handles created we
+ * retain only those properties listed in cb_proplist and sortcol.
+ * The rest are pruned. So, the caller should make sure that no other
+ * properties other than those listed in cb_proplist/sortcol are
+ * accessed.
+ *
+ * If cb_proplist is NULL then we retain all the properties. We
+ * always retain the zoned property, which some other properties
+ * need (userquota & friends), and the createtxg property, which
+ * we need to sort snapshots.
+ */
+ if (cb.cb_proplist && *cb.cb_proplist) {
+ zprop_list_t *p = *cb.cb_proplist;
+
+ while (p) {
+ if (p->pl_prop >= ZFS_PROP_TYPE &&
+ p->pl_prop < ZFS_NUM_PROPS) {
+ cb.cb_props_table[p->pl_prop] = B_TRUE;
+ }
+ p = p->pl_next;
+ }
+
+ while (sortcol) {
+ if (sortcol->sc_prop >= ZFS_PROP_TYPE &&
+ sortcol->sc_prop < ZFS_NUM_PROPS) {
+ cb.cb_props_table[sortcol->sc_prop] = B_TRUE;
+ }
+ sortcol = sortcol->sc_next;
+ }
+
+ cb.cb_props_table[ZFS_PROP_ZONED] = B_TRUE;
+ cb.cb_props_table[ZFS_PROP_CREATETXG] = B_TRUE;
+ } else {
+ (void) memset(cb.cb_props_table, B_TRUE,
+ sizeof (cb.cb_props_table));
+ }
+
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
(void) fprintf(stderr,
gettext("internal error: out of memory\n"));
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
index 76a1108..a029077 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,9 +41,10 @@ typedef struct zfs_sort_column {
#define ZFS_ITER_RECURSE (1 << 0)
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
+#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
int zfs_for_each(int, char **, int options, zfs_type_t,
- zfs_sort_column_t *, zprop_list_t **, zfs_iter_f, void *);
+ zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
void zfs_free_sort_columns(zfs_sort_column_t *);
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index d6bc6e1..79428f7 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -190,8 +190,8 @@ get_usage(zfs_help_t idx)
return (gettext("\tdestroy [-rRf] "
"<filesystem|volume|snapshot>\n"));
case HELP_GET:
- return (gettext("\tget [-rHp] [-o field[,...]] "
- "[-s source[,...]]\n"
+ return (gettext("\tget [-rHp] [-d max] "
+ "[-o field[,...]] [-s source[,...]]\n"
"\t <\"all\" | property[,...]> "
"[filesystem|volume|snapshot] ...\n"));
case HELP_INHERIT:
@@ -205,8 +205,8 @@ get_usage(zfs_help_t idx)
case HELP_UNJAIL:
return (gettext("\tunjail <jailid> <filesystem>\n"));
case HELP_LIST:
- return (gettext("\tlist [-rH] [-o property[,...]] "
- "[-t type[,...]] [-s property] ...\n"
+ return (gettext("\tlist [-rH][-d max] "
+ "[-o property[,...]] [-t type[,...]] [-s property] ...\n"
"\t [-S property] ... "
"[filesystem|volume|snapshot] ...\n"));
case HELP_MOUNT:
@@ -432,6 +432,27 @@ parseprop(nvlist_t *props)
}
+static int
+parse_depth(char *opt, int *flags)
+{
+ char *tmp;
+ int depth;
+
+ depth = (int)strtol(opt, &tmp, 0);
+ if (*tmp) {
+ (void) fprintf(stderr,
+ gettext("%s is not an integer\n"), optarg);
+ usage(B_FALSE);
+ }
+ if (depth < 0) {
+ (void) fprintf(stderr,
+ gettext("Depth can not be negative.\n"));
+ usage(B_FALSE);
+ }
+ *flags |= (ZFS_ITER_DEPTH_LIMIT|ZFS_ITER_RECURSE);
+ return (depth);
+}
+
/*
* zfs clone [-p] [-o prop=value] ... <snap> <fs | vol>
*
@@ -1119,6 +1140,7 @@ zfs_do_get(int argc, char **argv)
int i, c, flags = 0;
char *value, *fields;
int ret;
+ int limit = 0;
zprop_list_t fake_name = { 0 };
/*
@@ -1132,11 +1154,14 @@ zfs_do_get(int argc, char **argv)
cb.cb_type = ZFS_TYPE_DATASET;
/* check options */
- while ((c = getopt(argc, argv, ":o:s:rHp")) != -1) {
+ while ((c = getopt(argc, argv, ":d:o:s:rHp")) != -1) {
switch (c) {
case 'p':
cb.cb_literal = B_TRUE;
break;
+ case 'd':
+ limit = parse_depth(optarg, &flags);
+ break;
case 'r':
flags |= ZFS_ITER_RECURSE;
break;
@@ -1267,7 +1292,7 @@ zfs_do_get(int argc, char **argv)
/* run for each object */
ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET, NULL,
- &cb.cb_proplist, get_callback, &cb);
+ &cb.cb_proplist, limit, get_callback, &cb);
if (cb.cb_proplist == &fake_name)
zprop_free_list(fake_name.pl_next);
@@ -1380,10 +1405,10 @@ zfs_do_inherit(int argc, char **argv)
if (flags & ZFS_ITER_RECURSE) {
ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET,
- NULL, NULL, inherit_recurse_cb, propname);
+ NULL, NULL, 0, inherit_recurse_cb, propname);
} else {
ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET,
- NULL, NULL, inherit_cb, propname);
+ NULL, NULL, 0, inherit_cb, propname);
}
return (ret);
@@ -1578,7 +1603,7 @@ zfs_do_upgrade(int argc, char **argv)
if (cb.cb_version == 0)
cb.cb_version = ZPL_VERSION;
ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_FILESYSTEM,
- NULL, NULL, upgrade_set_callback, &cb);
+ NULL, NULL, 0, upgrade_set_callback, &cb);
(void) printf(gettext("%llu filesystems upgraded\n"),
cb.cb_numupgraded);
if (cb.cb_numsamegraded) {
@@ -1596,14 +1621,14 @@ zfs_do_upgrade(int argc, char **argv)
flags |= ZFS_ITER_RECURSE;
ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
- NULL, NULL, upgrade_list_callback, &cb);
+ NULL, NULL, 0, upgrade_list_callback, &cb);
found = cb.cb_foundone;
cb.cb_foundone = B_FALSE;
cb.cb_newer = B_TRUE;
ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
- NULL, NULL, upgrade_list_callback, &cb);
+ NULL, NULL, 0, upgrade_list_callback, &cb);
if (!cb.cb_foundone && !found) {
(void) printf(gettext("All filesystems are "
@@ -1615,11 +1640,12 @@ zfs_do_upgrade(int argc, char **argv)
}
/*
- * list [-rH] [-o property[,property]...] [-t type[,type]...]
+ * list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...]
* [-s property [-s property]...] [-S property [-S property]...]
* <dataset> ...
*
* -r Recurse over all children
+ * -d Limit recursion by depth.
* -H Scripted mode; elide headers and separate columns by tabs
* -o Control which fields to display.
* -t Control which object types to display.
@@ -1769,16 +1795,20 @@ zfs_do_list(int argc, char **argv)
char *fields = NULL;
list_cbdata_t cb = { 0 };
char *value;
+ int limit = 0;
int ret;
zfs_sort_column_t *sortcol = NULL;
int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS;
/* check options */
- while ((c = getopt(argc, argv, ":o:rt:Hs:S:")) != -1) {
+ while ((c = getopt(argc, argv, ":d:o:rt:Hs:S:")) != -1) {
switch (c) {
case 'o':
fields = optarg;
break;
+ case 'd':
+ limit = parse_depth(optarg, &flags);
+ break;
case 'r':
flags |= ZFS_ITER_RECURSE;
break;
@@ -1869,7 +1899,7 @@ zfs_do_list(int argc, char **argv)
cb.cb_first = B_TRUE;
ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
- list_callback, &cb);
+ limit, list_callback, &cb);
zprop_free_list(cb.cb_proplist);
zfs_free_sort_columns(sortcol);
@@ -2252,7 +2282,7 @@ zfs_do_set(int argc, char **argv)
}
ret = zfs_for_each(argc - 2, argv + 2, NULL,
- ZFS_TYPE_DATASET, NULL, NULL, set_callback, &cb);
+ ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, &cb);
return (ret);
}
@@ -2886,7 +2916,7 @@ zfs_do_unallow(int argc, char **argv)
flags |= ZFS_ITER_RECURSE;
error = zfs_for_each(argc, argv, flags,
ZFS_TYPE_FILESYSTEM|ZFS_TYPE_VOLUME, NULL,
- NULL, unallow_callback, (void *)zperms);
+ NULL, 0, unallow_callback, (void *)zperms);
if (zperms)
nvlist_free(zperms);
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
index a7967d7..b6c97c1 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
@@ -1,24 +1,9 @@
'\" te
-.\" CDDL HEADER START
-.\"
-.\" The contents of this file are subject to the terms of the
-.\" Common Development and Distribution License (the "License").
-.\" You may not use this file except in compliance with the License.
-.\"
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-.\" or http://www.opensolaris.org/os/licensing.
-.\" See the License for the specific language governing permissions
-.\" and limitations under the License.
-.\"
-.\" When distributing Covered Code, include this CDDL HEADER in each
-.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-.\" If applicable, add the following below this CDDL HEADER, with the
-.\" fields enclosed by brackets "[]" replaced with your own identifying
-.\" information: Portions Copyright [yyyy] [name of copyright owner]
-.\"
-.\" CDDL HEADER END
.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved.
-.TH zpool 1M "13 Nov 2007" "SunOS 5.11" "System Administration Commands"
+.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
+.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
+.TH zpool 1M "5 Mar 2009" "SunOS 5.11" "System Administration Commands"
.SH NAME
zpool \- configures ZFS storage pools
.SH SYNOPSIS
@@ -29,8 +14,8 @@ zpool \- configures ZFS storage pools
.LP
.nf
-\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR]
- \fIpool\fR \fIvdev\fR ...
+\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR]
+ ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR \fIvdev\fR ...
.fi
.LP
@@ -106,13 +91,13 @@ zpool \- configures ZFS storage pools
.LP
.nf
\fBzpool import\fR [\fB-o \fImntopts\fR\fR] [\fB-p\fR \fIproperty=value\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
- [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR
+ [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR
.fi
.LP
.nf
\fBzpool import\fR [\fB-o \fImntopts\fR\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
- [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR |\fIid\fR [\fInewpool\fR]
+ [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR |\fIid\fR [\fInewpool\fR]
.fi
.LP
@@ -169,8 +154,7 @@ A "virtual device" describes a single device or a collection of devices organize
.ad
.RS 10n
.rt
-A block device, typically located under "/dev/dsk". \fBZFS\fR can use individual slices or partitions, though the recommended mode of operation is to use whole disks. A disk can be specified by a full path, or it can be a shorthand name (the relative portion
-of the path under "/dev/dsk"). A whole disk can be specified by omitting the slice or partition designation. For example, "c0t0d0" is equivalent to "/dev/dsk/c0t0d0s2". When given a whole disk, \fBZFS\fR automatically labels the disk, if necessary.
+A block device, typically located under "/dev/dsk". \fBZFS\fR can use individual slices or partitions, though the recommended mode of operation is to use whole disks. A disk can be specified by a full path, or it can be a shorthand name (the relative portion of the path under "/dev/dsk"). A whole disk can be specified by omitting the slice or partition designation. For example, "c0t0d0" is equivalent to "/dev/dsk/c0t0d0s2". When given a whole disk, \fBZFS\fR automatically labels the disk, if necessary.
.RE
.sp
@@ -192,8 +176,7 @@ A regular file. The use of files as a backing store is strongly discouraged. It
.ad
.RS 10n
.rt
-A mirror of two or more devices. Data is replicated in an identical fashion across all components of a mirror. A mirror with \fIN\fR disks of size \fIX\fR can hold \fIX\fR bytes and can withstand (\fIN-1\fR)
-devices failing before data integrity is compromised.
+A mirror of two or more devices. Data is replicated in an identical fashion across all components of a mirror. A mirror with \fIN\fR disks of size \fIX\fR can hold \fIX\fR bytes and can withstand (\fIN-1\fR) devices failing before data integrity is compromised.
.RE
.sp
@@ -214,11 +197,9 @@ devices failing before data integrity is compromised.
.rt
A variation on \fBRAID-5\fR that allows for better distribution of parity and eliminates the "\fBRAID-5\fR write hole" (in which data and parity become inconsistent after a power loss). Data and parity is striped across all disks within a \fBraidz\fR group.
.sp
-A \fBraidz\fR group can have either single- or double-parity, meaning that the \fBraidz\fR group can sustain one or two failures respectively without losing any data. The \fBraidz1\fR \fBvdev\fR type specifies a single-parity \fBraidz\fR group
-and the \fBraidz2\fR \fBvdev\fR type specifies a double-parity \fBraidz\fR group. The \fBraidz\fR \fBvdev\fR type is an alias for \fBraidz1\fR.
+A \fBraidz\fR group can have either single- or double-parity, meaning that the \fBraidz\fR group can sustain one or two failures respectively without losing any data. The \fBraidz1\fR \fBvdev\fR type specifies a single-parity \fBraidz\fR group and the \fBraidz2\fR \fBvdev\fR type specifies a double-parity \fBraidz\fR group. The \fBraidz\fR \fBvdev\fR type is an alias for \fBraidz1\fR.
.sp
-A \fBraidz\fR group with \fIN\fR disks of size \fIX\fR with \fIP\fR parity disks can hold approximately (\fIN-P\fR)*\fIX\fR bytes and can withstand \fIP\fR device(s)
-failing before data integrity is compromised. The minimum number of devices in a \fBraidz\fR group is one more than the number of parity disks. The recommended number is between 3 and 9 to help increase performance.
+A \fBraidz\fR group with \fIN\fR disks of size \fIX\fR with \fIP\fR parity disks can hold approximately (\fIN-P\fR)*\fIX\fR bytes and can withstand \fIP\fR device(s) failing before data integrity is compromised. The minimum number of devices in a \fBraidz\fR group is one more than the number of parity disks. The recommended number is between 3 and 9 to help increase performance.
.RE
.sp
@@ -240,8 +221,7 @@ A special pseudo-\fBvdev\fR which keeps track of available hot spares for a pool
.ad
.RS 10n
.rt
-A separate intent log device. If more than one log device is specified, then writes are load-balanced between devices. Log devices can be mirrored. However, \fBraidz\fR and \fBraidz2\fR are not supported for the intent log. For more information, see the "Intent
-Log" section.
+A separate intent log device. If more than one log device is specified, then writes are load-balanced between devices. Log devices can be mirrored. However, \fBraidz\fR and \fBraidz2\fR are not supported for the intent log. For more information, see the "Intent Log" section.
.RE
.sp
@@ -260,8 +240,7 @@ A device used to cache storage pool data. A cache device cannot be mirrored or p
Virtual devices cannot be nested, so a mirror or \fBraidz\fR virtual device can only contain files or disks. Mirrors of mirrors (or other combinations) are not allowed.
.sp
.LP
-A pool can have any number of virtual devices at the top of the configuration (known as "root vdevs"). Data is dynamically distributed across all top-level devices to balance data among devices. As new virtual devices are added, \fBZFS\fR automatically places data
-on the newly available devices.
+A pool can have any number of virtual devices at the top of the configuration (known as "root vdevs"). Data is dynamically distributed across all top-level devices to balance data among devices. As new virtual devices are added, \fBZFS\fR automatically places data on the newly available devices.
.sp
.LP
Virtual devices are specified one at a time on the command line, separated by whitespace. The keywords "mirror" and "raidz" are used to distinguish where a group ends and another begins. For example, the following creates two root vdevs, each a mirror of two disks:
@@ -279,12 +258,10 @@ Virtual devices are specified one at a time on the command line, separated by wh
\fBZFS\fR supports a rich set of mechanisms for handling device failure and data corruption. All metadata and data is checksummed, and \fBZFS\fR automatically repairs bad data from a good copy when corruption is detected.
.sp
.LP
-In order to take advantage of these features, a pool must make use of some form of redundancy, using either mirrored or \fBraidz\fR groups. While \fBZFS\fR supports running in a non-redundant configuration, where each root vdev is simply a disk or file, this is
-strongly discouraged. A single case of bit corruption can render some or all of your data unavailable.
+In order to take advantage of these features, a pool must make use of some form of redundancy, using either mirrored or \fBraidz\fR groups. While \fBZFS\fR supports running in a non-redundant configuration, where each root vdev is simply a disk or file, this is strongly discouraged. A single case of bit corruption can render some or all of your data unavailable.
.sp
.LP
-A pool's health status is described by one of three states: online, degraded, or faulted. An online pool has all devices operating normally. A degraded pool is one in which one or more devices have failed, but the data is still available due to a redundant configuration. A faulted pool has
-corrupted metadata, or one or more faulted devices, and insufficient replicas to continue functioning.
+A pool's health status is described by one of three states: online, degraded, or faulted. An online pool has all devices operating normally. A degraded pool is one in which one or more devices have failed, but the data is still available due to a redundant configuration. A faulted pool has corrupted metadata, or one or more faulted devices, and insufficient replicas to continue functioning.
.sp
.LP
The health of the top-level vdev, such as mirror or \fBraidz\fR device, is potentially impacted by the state of its associated vdevs, or component devices. A top-level vdev or component device is in one of the following states:
@@ -399,8 +376,10 @@ If a device is removed and later re-attached to the system, \fBZFS\fR attempts t
.sp
.LP
-Spares can be shared across multiple pools, and can be added with the "\fBzpool add\fR" command and removed with the "\fBzpool remove\fR" command. Once a spare replacement is initiated, a new "spare" \fBvdev\fR is
-created within the configuration that will remain there until the original device is replaced. At this point, the hot spare becomes available again if another device fails.
+Spares can be shared across multiple pools, and can be added with the "\fBzpool add\fR" command and removed with the "\fBzpool remove\fR" command. Once a spare replacement is initiated, a new "spare" \fBvdev\fR is created within the configuration that will remain there until the original device is replaced. At this point, the hot spare becomes available again if another device fails.
+.sp
+.LP
+If a pool has a shared spare that is currently being used, the pool can not be exported since other pools may use this shared spare, which may lead to potential data corruption.
.sp
.LP
An in-progress spare replacement can be cancelled by detaching the hot spare. If the original faulted device is detached, then the hot spare assumes its place in the configuration, and is removed from the spare list of all active pools.
@@ -410,9 +389,7 @@ Spares cannot replace log devices.
.SS "Intent Log"
.sp
.LP
-The \fBZFS\fR Intent Log (\fBZIL\fR) satisfies \fBPOSIX\fR requirements for synchronous transactions. For instance, databases often require their transactions to be on stable storage devices when returning from a system call. \fBNFS\fR and
-other applications can also use \fBfsync\fR() to ensure data stability. By default, the intent log is allocated from blocks within the main pool. However, it might be possible to get better performance using separate intent log devices such as \fBNVRAM\fR or a dedicated
-disk. For example:
+The \fBZFS\fR Intent Log (\fBZIL\fR) satisfies \fBPOSIX\fR requirements for synchronous transactions. For instance, databases often require their transactions to be on stable storage devices when returning from a system call. \fBNFS\fR and other applications can also use \fBfsync\fR() to ensure data stability. By default, the intent log is allocated from blocks within the main pool. However, it might be possible to get better performance using separate intent log devices such as \fBNVRAM\fR or a dedicated disk. For example:
.sp
.in +2
.nf
@@ -430,8 +407,7 @@ Log devices can be added, replaced, attached, detached, and imported and exporte
.SS "Cache Devices"
.sp
.LP
-Devices can be added to a storage pool as "cache devices." These devices provide an additional layer of caching between main memory and disk. For read-heavy workloads, where the working set size is much larger than what can be cached in main memory, using cache devices allow
-much more of this working set to be served from low latency media. Using cache devices provides the greatest performance improvement for random read-workloads of mostly static content.
+Devices can be added to a storage pool as "cache devices." These devices provide an additional layer of caching between main memory and disk. For read-heavy workloads, where the working set size is much larger than what can be cached in main memory, using cache devices allow much more of this working set to be served from low latency media. Using cache devices provides the greatest performance improvement for random read-workloads of mostly static content.
.sp
.LP
To create a pool with cache devices, specify a "cache" \fBvdev\fR with any number of devices. For example:
@@ -521,8 +497,7 @@ Amount of storage space used within the pool.
.sp
.LP
-These space usage properties report actual physical space available to the storage pool. The physical space can be different from the total amount of space that any contained datasets can actually use. The amount of space used in a \fBraidz\fR configuration depends on the characteristics
-of the data being written. In addition, \fBZFS\fR reserves some space for internal accounting that the \fBzfs\fR(1M) command takes into account, but the \fBzpool\fR command does not. For non-full pools of a reasonable size, these effects should be invisible. For small pools, or pools that are close to being completely full, these discrepancies may become more noticeable.
+These space usage properties report actual physical space available to the storage pool. The physical space can be different from the total amount of space that any contained datasets can actually use. The amount of space used in a \fBraidz\fR configuration depends on the characteristics of the data being written. In addition, \fBZFS\fR reserves some space for internal accounting that the \fBzfs\fR(1M) command takes into account, but the \fBzpool\fR command does not. For non-full pools of a reasonable size, these effects should be invisible. For small pools, or pools that are close to being completely full, these discrepancies may become more noticeable.
.sp
.LP
The following property can be set at creation time and import time:
@@ -534,8 +509,7 @@ The following property can be set at creation time and import time:
.ad
.sp .6
.RS 4n
-Alternate root directory. If set, this directory is prepended to any mount points within the pool. This can be used when examining an unknown pool where the mount points cannot be trusted, or in an alternate boot environment, where the typical paths are not valid. \fBaltroot\fR is
-not a persistent property. It is valid only while the system is up. Setting \fBaltroot\fR defaults to using \fBcachefile\fR=none, though this may be overridden using an explicit setting.
+Alternate root directory. If set, this directory is prepended to any mount points within the pool. This can be used when examining an unknown pool where the mount points cannot be trusted, or in an alternate boot environment, where the typical paths are not valid. \fBaltroot\fR is not a persistent property. It is valid only while the system is up. Setting \fBaltroot\fR defaults to using \fBcachefile\fR=none, though this may be overridden using an explicit setting.
.RE
.sp
@@ -549,8 +523,7 @@ The following properties can be set at creation time and import time, and later
.ad
.sp .6
.RS 4n
-Controls automatic device replacement. If set to "\fBoff\fR", device replacement must be initiated by the administrator by using the "\fBzpool replace\fR" command. If set to "\fBon\fR", any new device, found
-in the same physical location as a device that previously belonged to the pool, is automatically formatted and replaced. The default behavior is "\fBoff\fR". This property can also be referred to by its shortened column name, "replace".
+Controls automatic device replacement. If set to "\fBoff\fR", device replacement must be initiated by the administrator by using the "\fBzpool replace\fR" command. If set to "\fBon\fR", any new device, found in the same physical location as a device that previously belonged to the pool, is automatically formatted and replaced. The default behavior is "\fBoff\fR". This property can also be referred to by its shortened column name, "replace".
.RE
.sp
@@ -572,9 +545,7 @@ Identifies the default bootable dataset for the root pool. This property is expe
.ad
.sp .6
.RS 4n
-Controls the location of where the pool configuration is cached. Discovering all pools on system startup requires a cached copy of the configuration data that is stored on the root file system. All pools in this cache are automatically imported when the system boots. Some environments,
-such as install and clustering, need to cache this information in a different location so that pools are not automatically imported. Setting this property caches the pool configuration in a different location that can later be imported with "\fBzpool import -c\fR". Setting
-it to the special value "\fBnone\fR" creates a temporary pool that is never cached, and the special value \fB\&''\fR (empty string) uses the default location.
+Controls the location of where the pool configuration is cached. Discovering all pools on system startup requires a cached copy of the configuration data that is stored on the root file system. All pools in this cache are automatically imported when the system boots. Some environments, such as install and clustering, need to cache this information in a different location so that pools are not automatically imported. Setting this property caches the pool configuration in a different location that can later be imported with "\fBzpool import -c\fR". Setting it to the special value "\fBnone\fR" creates a temporary pool that is never cached, and the special value \fB\&''\fR (empty string) uses the default location.
.sp
Multiple pools can share the same cache file. Because the kernel destroys and recreates this file when pools are added and removed, care should be taken when attempting to access this file. When the last pool using a \fBcachefile\fR is exported or destroyed, the file is removed.
.RE
@@ -587,8 +558,7 @@ Multiple pools can share the same cache file. Because the kernel destroys and re
.ad
.sp .6
.RS 4n
-Controls whether a non-privileged user is granted access based on the dataset permissions defined on the dataset. See \fBzfs\fR(1M) for more information
-on \fBZFS\fR delegated administration.
+Controls whether a non-privileged user is granted access based on the dataset permissions defined on the dataset. See \fBzfs\fR(1M) for more information on \fBZFS\fR delegated administration.
.RE
.sp
@@ -639,12 +609,22 @@ Prints out a message to the console and generates a system crash dump.
.ne 2
.mk
.na
+\fB\fBlistsnaps\fR=on | off\fR
+.ad
+.sp .6
+.RS 4n
+Controls whether information about snapshots associated with this pool is output when "\fBzfs list\fR" is run without the \fB-t\fR option. The default value is "off".
+.RE
+
+.sp
+.ne 2
+.mk
+.na
\fB\fBversion\fR=\fIversion\fR\fR
.ad
.sp .6
.RS 4n
-The current on-disk version of the pool. This can be increased, but never decreased. The preferred method of updating pools is with the "\fBzpool upgrade\fR" command, though this property can be used when a specific version is needed for backwards compatibility.
-This property can be any number between 1 and the current version reported by "\fBzpool upgrade -v\fR". The special value "\fBcurrent\fR" is an alias for the latest supported version.
+The current on-disk version of the pool. This can be increased, but never decreased. The preferred method of updating pools is with the "\fBzpool upgrade\fR" command, though this property can be used when a specific version is needed for backwards compatibility. This property can be any number between 1 and the current version reported by "\fBzpool upgrade -v\fR".
.RE
.SS "Subcommands"
@@ -669,18 +649,15 @@ Displays a help message.
.ne 2
.mk
.na
-\fB\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR \fIvdev\fR ...\fR
+\fB\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR \fIvdev\fR ...\fR
.ad
.sp .6
.RS 4n
-Creates a new storage pool containing the virtual devices specified on the command line. The pool name must begin with a letter, and can only contain alphanumeric characters as well as underscore ("_"), dash ("-"), and period ("."). The pool
-names "mirror", "raidz", "spare" and "log" are reserved, as are names beginning with the pattern "c[0-9]". The \fBvdev\fR specification is described in the "Virtual Devices" section.
+Creates a new storage pool containing the virtual devices specified on the command line. The pool name must begin with a letter, and can only contain alphanumeric characters as well as underscore ("_"), dash ("-"), and period ("."). The pool names "mirror", "raidz", "spare" and "log" are reserved, as are names beginning with the pattern "c[0-9]". The \fBvdev\fR specification is described in the "Virtual Devices" section.
.sp
-The command verifies that each device specified is accessible and not currently in use by another subsystem. There are some uses, such as being currently mounted, or specified as the dedicated dump device, that prevents a device from ever being used by \fBZFS\fR. Other uses,
-such as having a preexisting \fBUFS\fR file system, can be overridden with the \fB-f\fR option.
+The command verifies that each device specified is accessible and not currently in use by another subsystem. There are some uses, such as being currently mounted, or specified as the dedicated dump device, that prevents a device from ever being used by \fBZFS\fR. Other uses, such as having a preexisting \fBUFS\fR file system, can be overridden with the \fB-f\fR option.
.sp
-The command also checks that the replication strategy for the pool is consistent. An attempt to combine redundant and non-redundant storage in a single pool, or to mix disks and files, results in an error unless \fB-f\fR is specified. The use of differently sized devices within
-a single \fBraidz\fR or mirror group is also flagged as an error unless \fB-f\fR is specified.
+The command also checks that the replication strategy for the pool is consistent. An attempt to combine redundant and non-redundant storage in a single pool, or to mix disks and files, results in an error unless \fB-f\fR is specified. The use of differently sized devices within a single \fBraidz\fR or mirror group is also flagged as an error unless \fB-f\fR is specified.
.sp
Unless the \fB-R\fR option is specified, the default mount point is "/\fIpool\fR". The mount point must not exist or must be empty, or else the root dataset cannot be mounted. This can be overridden with the \fB-m\fR option.
.sp
@@ -720,6 +697,21 @@ Sets the given pool properties. See the "Properties" section for a list of valid
.ne 2
.mk
.na
+\fB\fB-O\fR \fIfile-system-property=value\fR\fR
+.ad
+.br
+.na
+\fB[\fB-O\fR \fIfile-system-property=value\fR] ...\fR
+.ad
+.sp .6
+.RS 4n
+Sets the given file system properties in the root file system of the pool. See the "Properties" section of \fBzfs\fR(1M) for a list of valid properties that can be set.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
\fB\fB-R\fR \fIroot\fR\fR
.ad
.sp .6
@@ -770,8 +762,7 @@ Forces any active datasets contained within the pool to be unmounted.
.ad
.sp .6
.RS 4n
-Adds the specified virtual devices to the given pool. The \fIvdev\fR specification is described in the "Virtual Devices" section. The behavior of the \fB-f\fR option, and the device checks performed are described in the "zpool create"
-subcommand.
+Adds the specified virtual devices to the given pool. The \fIvdev\fR specification is described in the "Virtual Devices" section. The behavior of the \fB-f\fR option, and the device checks performed are described in the "zpool create" subcommand.
.sp
.ne 2
.mk
@@ -805,8 +796,7 @@ Do not add a disk that is currently configured as a quorum device to a zpool. Af
.ad
.sp .6
.RS 4n
-Removes the specified device from the pool. This command currently only supports removing hot spares and cache devices. Devices that are part of a mirrored configuration can be removed using the "\fBzpool detach\fR" command. Non-redundant and \fBraidz\fR devices
-cannot be removed from a pool.
+Removes the specified device from the pool. This command currently only supports removing hot spares and cache devices. Devices that are part of a mirrored configuration can be removed using the "\fBzpool detach\fR" command. Non-redundant and \fBraidz\fR devices cannot be removed from a pool.
.RE
.sp
@@ -850,8 +840,7 @@ Comma-separated list of properties to display. See the "Properties" section for
.ad
.sp .6
.RS 4n
-Displays \fBI/O\fR statistics for the given pools. When given an interval, the statistics are printed every \fIinterval\fR seconds until \fBCtrl-C\fR is pressed. If no \fIpools\fR are specified, statistics for
-every pool in the system is shown. If \fIcount\fR is specified, the command exits after \fIcount\fR reports are printed.
+Displays \fBI/O\fR statistics for the given pools. When given an interval, the statistics are printed every \fIinterval\fR seconds until \fBCtrl-C\fR is pressed. If no \fIpools\fR are specified, statistics for every pool in the system is shown. If \fIcount\fR is specified, the command exits after \fIcount\fR reports are printed.
.sp
.ne 2
.mk
@@ -956,8 +945,7 @@ Clears device errors in a pool. If no arguments are specified, all device errors
.ad
.sp .6
.RS 4n
-Attaches \fInew_device\fR to an existing \fBzpool\fR device. The existing device cannot be part of a \fBraidz\fR configuration. If \fIdevice\fR is not currently part of a mirrored configuration, \fIdevice\fR automatically
-transforms into a two-way mirror of \fIdevice\fR and \fInew_device\fR. If \fIdevice\fR is part of a two-way mirror, attaching \fInew_device\fR creates a three-way mirror, and so on. In either case, \fInew_device\fR begins to resilver immediately.
+Attaches \fInew_device\fR to an existing \fBzpool\fR device. The existing device cannot be part of a \fBraidz\fR configuration. If \fIdevice\fR is not currently part of a mirrored configuration, \fIdevice\fR automatically transforms into a two-way mirror of \fIdevice\fR and \fInew_device\fR. If \fIdevice\fR is part of a two-way mirror, attaching \fInew_device\fR creates a three-way mirror, and so on. In either case, \fInew_device\fR begins to resilver immediately.
.sp
.ne 2
.mk
@@ -994,8 +982,7 @@ Replaces \fIold_device\fR with \fInew_device\fR. This is equivalent to attaching
.sp
The size of \fInew_device\fR must be greater than or equal to the minimum size of all the devices in a mirror or \fBraidz\fR configuration.
.sp
-\fInew_device\fR is required if the pool is not redundant. If \fInew_device\fR is not specified, it defaults to \fIold_device\fR. This form of replacement is useful after an existing disk has failed and has been physically replaced.
-In this case, the new disk may have the same \fB/dev/dsk\fR path as the old device, even though it is actually a different disk. \fBZFS\fR recognizes this.
+\fInew_device\fR is required if the pool is not redundant. If \fInew_device\fR is not specified, it defaults to \fIold_device\fR. This form of replacement is useful after an existing disk has failed and has been physically replaced. In this case, the new disk may have the same \fB/dev/dsk\fR path as the old device, even though it is actually a different disk. \fBZFS\fR recognizes this.
.sp
.ne 2
.mk
@@ -1017,11 +1004,9 @@ Forces use of \fInew_device\fR, even if its appears to be in use. Not all device
.ad
.sp .6
.RS 4n
-Begins a scrub. The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror or \fBraidz\fR) devices, \fBZFS\fR automatically repairs any damage discovered during the scrub. The "\fBzpool
-status\fR" command reports the progress of the scrub and summarizes the results of the scrub upon completion.
+Begins a scrub. The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror or \fBraidz\fR) devices, \fBZFS\fR automatically repairs any damage discovered during the scrub. The "\fBzpool status\fR" command reports the progress of the scrub and summarizes the results of the scrub upon completion.
.sp
-Scrubbing and resilvering are very similar operations. The difference is that resilvering only examines data that \fBZFS\fR knows to be out of date (for example, when attaching a new device to a mirror or replacing an existing device), whereas scrubbing examines all data to
-discover silent errors due to hardware faults or disk failure.
+Scrubbing and resilvering are very similar operations. The difference is that resilvering only examines data that \fBZFS\fR knows to be out of date (for example, when attaching a new device to a mirror or replacing an existing device), whereas scrubbing examines all data to discover silent errors due to hardware faults or disk failure.
.sp
Because scrubbing and resilvering are \fBI/O\fR-intensive operations, \fBZFS\fR only allows one at a time. If a scrub is already in progress, the "\fBzpool scrub\fR" command terminates it and starts a new scrub. If a resilver is in progress, \fBZFS\fR does not allow a scrub to be started until the resilver completes.
.sp
@@ -1045,8 +1030,7 @@ Stop scrubbing.
.ad
.sp .6
.RS 4n
-Lists pools available to import. If the \fB-d\fR option is not specified, this command searches for devices in "/dev/dsk". The \fB-d\fR option can be specified multiple times, and all directories are searched. If the device appears to be part of
-an exported pool, this command displays a summary of the pool with the name of the pool, a numeric identifier, as well as the \fIvdev\fR layout and current health of the device for each device or file. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR" command, are not listed unless the \fB-D\fR option is specified.
+Lists pools available to import. If the \fB-d\fR option is not specified, this command searches for devices in "/dev/dsk". The \fB-d\fR option can be specified multiple times, and all directories are searched. If the device appears to be part of an exported pool, this command displays a summary of the pool with the name of the pool, a numeric identifier, as well as the \fIvdev\fR layout and current health of the device for each device or file. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR" command, are not listed unless the \fB-D\fR option is specified.
.sp
The numeric identifier is unique, and can be used instead of the pool name when multiple exported pools of the same name are available.
.sp
@@ -1088,13 +1072,11 @@ Lists destroyed pools only.
.ne 2
.mk
.na
-\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
-[\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR\fR
+\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR\fR
.ad
.sp .6
.RS 4n
-Imports all pools found in the search directories. Identical to the previous command, except that all pools with a sufficient number of devices available are imported. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR"
-command, will not be imported unless the \fB-D\fR option is specified.
+Imports all pools found in the search directories. Identical to the previous command, except that all pools with a sufficient number of devices available are imported. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR" command, will not be imported unless the \fB-D\fR option is specified.
.sp
.ne 2
.mk
@@ -1103,8 +1085,7 @@ command, will not be imported unless the \fB-D\fR option is specified.
.ad
.RS 21n
.rt
-Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount
-options.
+Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount options.
.RE
.sp
@@ -1190,15 +1171,13 @@ Sets the "\fBcachefile\fR" property to "\fBnone\fR" and the "\fIaltroot\fR" prop
.ne 2
.mk
.na
-\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
-[\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR | \fIid\fR [\fInewpool\fR]\fR
+\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR | \fIid\fR [\fInewpool\fR]\fR
.ad
.sp .6
.RS 4n
Imports a specific pool. A pool can be identified by its name or the numeric identifier. If \fInewpool\fR is specified, the pool is imported using the name \fInewpool\fR. Otherwise, it is imported with the same name as its exported name.
.sp
-If a device is removed from a system without running "\fBzpool export\fR" first, the device appears as potentially active. It cannot be determined if this was a failed export, or whether the device is really in use from another host. To import a pool in this state,
-the \fB-f\fR option is required.
+If a device is removed from a system without running "\fBzpool export\fR" first, the device appears as potentially active. It cannot be determined if this was a failed export, or whether the device is really in use from another host. To import a pool in this state, the \fB-f\fR option is required.
.sp
.ne 2
.mk
@@ -1207,8 +1186,7 @@ the \fB-f\fR option is required.
.ad
.sp .6
.RS 4n
-Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount
-options.
+Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount options.
.RE
.sp
@@ -1289,7 +1267,7 @@ Sets the "\fBcachefile\fR" property to "\fBnone\fR" and the "\fIaltroot\fR" prop
.RS 4n
Exports the given pools from the system. All devices are marked as exported, but are still considered in use by other subsystems. The devices can be moved between systems (even those of different endianness) and imported as long as a sufficient number of devices are present.
.sp
-Before exporting the pool, all datasets within the pool are unmounted.
+Before exporting the pool, all datasets within the pool are unmounted. A pool can not be exported if it has a shared spare that is currently being used.
.sp
For pools to be portable, you must give the \fBzpool\fR command whole disks, not just slices, so that \fBZFS\fR can label the disks with portable \fBEFI\fR labels. Otherwise, disk drivers on platforms of different endianness will not recognize the disks.
.sp
@@ -1301,6 +1279,8 @@ For pools to be portable, you must give the \fBzpool\fR command whole disks, not
.RS 6n
.rt
Forcefully unmount all datasets, using the "\fBunmount -f\fR" command.
+.sp
+This command will forcefully export the pool even if it has a shared spare that is currently being used. This may lead to potential data corruption.
.RE
.RE
@@ -1313,8 +1293,7 @@ Forcefully unmount all datasets, using the "\fBunmount -f\fR" command.
.ad
.sp .6
.RS 4n
-Displays all pools formatted using a different \fBZFS\fR on-disk version. Older versions can continue to be used, but some features may not be available. These pools can be upgraded using "\fBzpool upgrade -a\fR". Pools that are formatted with
-a more recent version are also displayed, although these pools will be inaccessible on the system.
+Displays all pools formatted using a different \fBZFS\fR on-disk version. Older versions can continue to be used, but some features may not be available. These pools can be upgraded using "\fBzpool upgrade -a\fR". Pools that are formatted with a more recent version are also displayed, although these pools will be inaccessible on the system.
.RE
.sp
@@ -1407,9 +1386,9 @@ Retrieves the given list of properties (or all properties if "\fBall\fR" is used
.in +2
.nf
name Name of storage pool
- property Property name
- value Property value
- source Property source, either 'default' or 'local'.
+ property Property name
+ value Property value
+ source Property source, either 'default' or 'local'.
.fi
.in -2
.sp
@@ -1421,7 +1400,7 @@ See the "Properties" section for more information on the available pool properti
.ne 2
.mk
.na
-\fB\fBzpool set\fR \fIproperty\fR=\fIvalue\fR \fIpool\fR \fR
+\fB\fBzpool set\fR \fIproperty\fR=\fIvalue\fR \fIpool\fR\fR
.ad
.sp .6
.RS 4n
@@ -1513,10 +1492,10 @@ The results from this command are similar to the following:
.in +2
.nf
\fB# zpool list\fR
- NAME SIZE USED AVAIL CAP HEALTH ALTROOT
- pool 67.5G 2.92M 67.5G 0% ONLINE -
- tank 67.5G 2.92M 67.5G 0% ONLINE -
- zion - - - 0% FAULTED -
+ NAME SIZE USED AVAIL CAP HEALTH ALTROOT
+ pool 67.5G 2.92M 67.5G 0% ONLINE -
+ tank 67.5G 2.92M 67.5G 0% ONLINE -
+ zion - - - 0% FAULTED -
.fi
.in -2
.sp
@@ -1563,16 +1542,16 @@ The results from this command are similar to the following:
.in +2
.nf
\fB# zpool import\fR
- pool: tank
- id: 15451357997522795478
-state: ONLINE
+ pool: tank
+ id: 15451357997522795478
+ state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
- tank ONLINE
- mirror ONLINE
- c1t2d0 ONLINE
- c1t3d0 ONLINE
+ tank ONLINE
+ mirror ONLINE
+ c1t2d0 ONLINE
+ c1t3d0 ONLINE
\fB# zpool import tank\fR
.fi
@@ -1642,7 +1621,7 @@ The following command creates a ZFS storage pool consisting of two, two-way mirr
.in +2
.nf
\fB# zpool create pool mirror c0d0 c1d0 mirror c2d0 c3d0 log mirror \e
- c4d0 c5d0\fR
+ c4d0 c5d0\fR
.fi
.in -2
.sp
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 9a13bbb..a959494 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -369,6 +369,7 @@ typedef struct zprop_list {
} zprop_list_t;
extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **);
+extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *);
#define ZFS_MOUNTPOINT_NONE "none"
#define ZFS_MOUNTPOINT_LEGACY "legacy"
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index f3b132f..eb0a1fe 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2045,6 +2045,8 @@ getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
} else {
+ verify(!zhp->zfs_props_table ||
+ zhp->zfs_props_table[prop] == B_TRUE);
value = zfs_prop_default_numeric(prop);
*source = "";
}
@@ -2064,6 +2066,8 @@ getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
} else {
+ verify(!zhp->zfs_props_table ||
+ zhp->zfs_props_table[prop] == B_TRUE);
if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
value = "";
*source = "";
@@ -4267,6 +4271,35 @@ zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
return (error);
}
+void
+zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
+{
+ nvpair_t *curr;
+
+ /*
+ * Keep a reference to the props-table against which we prune the
+ * properties.
+ */
+ zhp->zfs_props_table = props;
+
+ curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
+
+ while (curr) {
+ zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
+ nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
+
+ /*
+ * We leave user:props in the nvlist, so there will be
+ * some ZPROP_INVAL. To be extra safe, don't prune
+ * those.
+ */
+ if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
+ (void) nvlist_remove(zhp->zfs_props,
+ nvpair_name(curr), nvpair_type(curr));
+ curr = next;
+ }
+}
+
/*
* Attach/detach the given filesystem to/from the given jail.
*/
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
index afe71f3..c0e47e9 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,6 +77,7 @@ struct zfs_handle {
nvlist_t *zfs_user_props;
boolean_t zfs_mntcheck;
char *zfs_mntopts;
+ uint8_t *zfs_props_table;
};
/*
diff --git a/cddl/lib/drti/Makefile b/cddl/lib/drti/Makefile
index 4be57a5..ffd161c 100644
--- a/cddl/lib/drti/Makefile
+++ b/cddl/lib/drti/Makefile
@@ -1,8 +1,6 @@
# $FreeBSD$
-.include "../../Makefile.inc"
-
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/common
SRCS= drti.c
FILES= ${SRCS:R:S/$/.o/g}
@@ -10,7 +8,6 @@ FILESOWN= ${LIBOWN}
FILESGRP= ${LIBGRP}
FILESMODE= ${LIBMODE}
FILESDIR= ${LIBDIR}/dtrace
-WARNS?= 6
CLEANFILES= ${FILES}
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
diff --git a/cddl/lib/libavl/Makefile b/cddl/lib/libavl/Makefile
index 8cbaff1..f4db92f 100644
--- a/cddl/lib/libavl/Makefile
+++ b/cddl/lib/libavl/Makefile
@@ -4,6 +4,7 @@
LIB= avl
SRCS= avl.c
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
diff --git a/cddl/lib/libctf/Makefile b/cddl/lib/libctf/Makefile
index 6309ee4..5829111 100644
--- a/cddl/lib/libctf/Makefile
+++ b/cddl/lib/libctf/Makefile
@@ -1,10 +1,10 @@
# $FreeBSD$
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/common/ctf
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libctf/common
+.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/ctf
LIB= ctf
-SHLIB_MAJOR= 2
-
SRCS= ctf_create.c \
ctf_decl.c \
ctf_error.c \
@@ -17,10 +17,7 @@ SRCS= ctf_create.c \
ctf_types.c \
ctf_util.c
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/common/ctf
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/lib/libctf/common
-.PATH: ${OPENSOLARIS_SYS_DISTDIR}/common/ctf
-
+WARNS?= 0
CFLAGS+= -DCTF_OLD_VERSIONS
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile
index 071d950..7e500c7 100644
--- a/cddl/lib/libdtrace/Makefile
+++ b/cddl/lib/libdtrace/Makefile
@@ -1,12 +1,9 @@
# $FreeBSD$
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/common
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libgen/common
LIB= dtrace
-SHLIB_MAJOR= 2
-
-WARNS= 1
-
SRCS= dt_aggregate.c \
dt_as.c \
dt_buf.c \
@@ -51,8 +48,7 @@ DSRCS= errno.d \
signal.d \
unistd.d
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/lib/libgen/common
+WARNS?= 1
CFLAGS+= -I${.OBJDIR} \
-I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
diff --git a/cddl/lib/libnvpair/Makefile b/cddl/lib/libnvpair/Makefile
index 7bf5001..da0c7f3 100644
--- a/cddl/lib/libnvpair/Makefile
+++ b/cddl/lib/libnvpair/Makefile
@@ -10,6 +10,7 @@ SRCS= libnvpair.c \
nvpair_alloc_fixed.c \
nvpair.c
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
diff --git a/cddl/lib/libumem/Makefile b/cddl/lib/libumem/Makefile
index 6b6881e..0ce73f8 100644
--- a/cddl/lib/libumem/Makefile
+++ b/cddl/lib/libumem/Makefile
@@ -4,6 +4,7 @@
LIB= umem
SRCS= umem.c
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
.include <bsd.lib.mk>
diff --git a/cddl/lib/libuutil/Makefile b/cddl/lib/libuutil/Makefile
index 309ffd0..7521747 100644
--- a/cddl/lib/libuutil/Makefile
+++ b/cddl/lib/libuutil/Makefile
@@ -15,6 +15,7 @@ SRCS= avl.c \
uu_pname.c \
uu_strtoint.c
+WARNS?= 0
CFLAGS+= -DNATIVE_BUILD
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
diff --git a/cddl/lib/libzfs/Makefile b/cddl/lib/libzfs/Makefile
index 30c516b..3023a1de 100644
--- a/cddl/lib/libzfs/Makefile
+++ b/cddl/lib/libzfs/Makefile
@@ -32,6 +32,7 @@ SRCS+= zfs_deleg.c \
libzfs_sendrecv.c \
libzfs_status.c
+WARNS?= 0
CFLAGS+= -DZFS_NO_ACL
CFLAGS+= -I${.CURDIR}/../../../sbin/mount
CFLAGS+= -I${.CURDIR}/../../../cddl/lib/libumem
diff --git a/cddl/lib/libzpool/Makefile b/cddl/lib/libzpool/Makefile
index fec99d9..045e13d 100644
--- a/cddl/lib/libzpool/Makefile
+++ b/cddl/lib/libzpool/Makefile
@@ -33,6 +33,7 @@ SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} \
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \
${UNICODE_SRCS}
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
diff --git a/cddl/sbin/zfs/Makefile b/cddl/sbin/zfs/Makefile
index 4a9274e..591ef06 100644
--- a/cddl/sbin/zfs/Makefile
+++ b/cddl/sbin/zfs/Makefile
@@ -6,6 +6,7 @@ PROG= zfs
MAN= zfs.8
SRCS= zfs_main.c zfs_iter.c
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
diff --git a/cddl/sbin/zpool/Makefile b/cddl/sbin/zpool/Makefile
index 4b24dfb..06fd238 100644
--- a/cddl/sbin/zpool/Makefile
+++ b/cddl/sbin/zpool/Makefile
@@ -7,6 +7,7 @@ PROG= zpool
MAN= zpool.8
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c zfs_comutil.c
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
diff --git a/cddl/usr.bin/ctfconvert/Makefile b/cddl/usr.bin/ctfconvert/Makefile
index aea32c7..08be1f0 100644
--- a/cddl/usr.bin/ctfconvert/Makefile
+++ b/cddl/usr.bin/ctfconvert/Makefile
@@ -1,13 +1,12 @@
# $FreeBSD$
-.include <bsd.own.mk>
-
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/tools/ctf/common
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/tools/ctf/cvt
DEBUG_FLAGS= -g
PROG= ctfconvert
-
+NO_MAN=
SRCS= alist.c \
ctf.c \
ctfconvert.c \
@@ -29,8 +28,6 @@ SRCS= alist.c \
traverse.c \
util.c
-WARNS?= 6
-
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/compat/opensolaris/include \
-I${OPENSOLARIS_USR_DISTDIR} \
@@ -43,10 +40,4 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
DPADD= ${LIBCTF} ${LIBDWARF} ${LIBELF} ${LIBZ} ${LIBPTHREAD}
LDADD= -lctf -ldwarf -lelf -lz -lpthread
-.PATH: ${.CURDIR}
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/common
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/cvt
-
-MK_MAN= no
-
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/ctfdump/Makefile b/cddl/usr.bin/ctfdump/Makefile
index 700b070..9b713c2 100644
--- a/cddl/usr.bin/ctfdump/Makefile
+++ b/cddl/usr.bin/ctfdump/Makefile
@@ -1,15 +1,14 @@
# $FreeBSD$
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/tools/ctf/common
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/tools/ctf/dump
PROG= ctfdump
-
+NO_MAN=
SRCS= dump.c \
symbol.c \
utils.c
-WARNS?= 6
-
CFLAGS+= -I${OPENSOLARIS_USR_DISTDIR} \
-I${OPENSOLARIS_SYS_DISTDIR} \
-I${OPENSOLARIS_USR_DISTDIR}/head \
@@ -22,9 +21,4 @@ CFLAGS+= -I${OPENSOLARIS_USR_DISTDIR} \
DPADD= ${LIBPTHREAD} ${LIBELF} ${LIBZ}
LDADD= -lpthread -lelf -lz
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/common
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/dump
-
-NO_MAN=
-
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/ctfmerge/Makefile b/cddl/usr.bin/ctfmerge/Makefile
index 7c96d36..ef3b4bf 100644
--- a/cddl/usr.bin/ctfmerge/Makefile
+++ b/cddl/usr.bin/ctfmerge/Makefile
@@ -1,13 +1,10 @@
# $FreeBSD$
-.include <bsd.own.mk>
-
-.include "../../Makefile.inc"
-
-WARNS= 1
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/tools/ctf/common
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/tools/ctf/cvt
PROG= ctfmerge
-
+NO_MAN=
SRCS= alist.c \
barrier.c \
ctf.c \
@@ -26,7 +23,7 @@ SRCS= alist.c \
traverse.c \
util.c
-WARNS?= 6
+WARNS?= 1
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/compat/opensolaris/include \
@@ -40,9 +37,4 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
DPADD= ${LIBCTF} ${LIBDWARF} ${LIBELF} ${LIBZ} ${LIBPTHREAD}
LDADD= -lctf -ldwarf -lelf -lz -lpthread
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/common
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/cvt
-
-MK_MAN= no
-
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/sgsmsg/Makefile b/cddl/usr.bin/sgsmsg/Makefile
index 5414414..8d1f70f 100644
--- a/cddl/usr.bin/sgsmsg/Makefile
+++ b/cddl/usr.bin/sgsmsg/Makefile
@@ -1,20 +1,17 @@
# $FreeBSD$
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/sgs/tools/common
+.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/avl
# This program is required as a bootstrap tool for 'make buildworld'
PROG= sgsmsg
-
+NO_MAN=
SRCS= avl.c sgsmsg.c string_table.c findprime.c
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/compat/opensolaris/include \
-I${OPENSOLARIS_USR_DISTDIR}/cmd/sgs/include \
-I${OPENSOLARIS_SYS_DISTDIR}/uts/common
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/cmd/sgs/tools/common
-.PATH: ${OPENSOLARIS_SYS_DISTDIR}/common/avl
-
-NO_MAN=
-
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/zinject/Makefile b/cddl/usr.bin/zinject/Makefile
index 82505a8..dc6de45 100644
--- a/cddl/usr.bin/zinject/Makefile
+++ b/cddl/usr.bin/zinject/Makefile
@@ -6,6 +6,7 @@ PROG= zinject
SRCS= zinject.c translate.c
NO_MAN=
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile
index 67ade45ad..8bb69b1 100644
--- a/cddl/usr.bin/ztest/Makefile
+++ b/cddl/usr.bin/ztest/Makefile
@@ -5,6 +5,7 @@
PROG= ztest
NO_MAN=
+WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
diff --git a/cddl/usr.sbin/dtrace/Makefile b/cddl/usr.sbin/dtrace/Makefile
index 56e8815..b8c668b 100644
--- a/cddl/usr.sbin/dtrace/Makefile
+++ b/cddl/usr.sbin/dtrace/Makefile
@@ -1,14 +1,12 @@
# $FreeBSD$
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/dtrace
PROG= dtrace
-
-BINDIR?= /usr/sbin
-
SRCS= dtrace.c
+BINDIR?= /usr/sbin
-WARNS= 1
+WARNS?= 1
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/compat/opensolaris/include \
@@ -18,8 +16,6 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${OPENSOLARIS_SYS_DISTDIR}/uts/common \
-I${OPENSOLARIS_SYS_DISTDIR}/compat
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/cmd/dtrace
-
# Optional debugging stuff...
#CFLAGS+= -DNEED_ERRLOC
#YFLAGS+= -d
diff --git a/cddl/usr.sbin/lockstat/Makefile b/cddl/usr.sbin/lockstat/Makefile
index 4fbddef..6cf7009 100644
--- a/cddl/usr.sbin/lockstat/Makefile
+++ b/cddl/usr.sbin/lockstat/Makefile
@@ -1,14 +1,13 @@
# $FreeBSD$
-.include "../../Makefile.inc"
+.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/lockstat
PROG= lockstat
-
-BINDIR?= /usr/sbin
-
+NO_MAN=
SRCS= lockstat.c sym.c
+BINDIR?= /usr/sbin
-WARNS= 1
+WARNS?= 1
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/compat/opensolaris/include \
@@ -19,8 +18,6 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
-I${OPENSOLARIS_SYS_DISTDIR}/compat \
-I${.CURDIR}/../../../sys
-.PATH: ${OPENSOLARIS_USR_DISTDIR}/cmd/lockstat
-
CFLAGS+= -DNEED_ERRLOC -g
#YFLAGS+= -d
@@ -28,6 +25,4 @@ CFLAGS+= -DNEED_ERRLOC -g
DPADD= ${LIBPTHREAD} ${LIBDTRACE} ${LIBY} ${LIBL} ${LIBPROC} ${LIBCTF} ${LIBELF} ${LIBZ} ${LIBRT}
LDADD= -lpthread -ldtrace -ly -ll -lproc -lctf -lelf -lz -lrt
-NO_MAN=
-
.include <bsd.prog.mk>
diff --git a/cddl/usr.sbin/zdb/Makefile b/cddl/usr.sbin/zdb/Makefile
index 35ad2a1..b98038e 100644
--- a/cddl/usr.sbin/zdb/Makefile
+++ b/cddl/usr.sbin/zdb/Makefile
@@ -6,6 +6,9 @@ PROG= zdb
MAN= zdb.8
SRCS= zdb.c zdb_il.c
+WARNS?= 0
+CSTD= c99
+
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
@@ -23,6 +26,5 @@ DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
${LIBUUTIL} ${LIBZ} ${LIBZFS} ${LIBZPOOL}
LDADD= -lavl -lgeom -lm -lnvpair -lpthread -lumem -luutil -lz -lzfs -lzpool
-CSTD= c99
.include <bsd.prog.mk>
diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES
index 0e9c9a6..d14fdd6 100644
--- a/contrib/bind9/CHANGES
+++ b/contrib/bind9/CHANGES
@@ -1,4 +1,30 @@
- --- 9.6.1-P3 released ---
+ --- 9.6.2-P1 released ---
+
+2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619]
+
+ --- 9.6.2 released ---
+
+2850. [bug] If isc_heap_insert() failed due to memory shortage
+ the heap would have corrupted entries. [RT #20951]
+
+2849. [bug] Don't treat errors from the xml2 library as fatal.
+ [RT #20945]
+
+2846. [bug] EOF on unix domain sockets was not being handled
+ correctly. [RT #20731]
+
+2844. [doc] notify-delay default in ARM was wrong. It should have
+ been five (5) seconds.
+
+ --- 9.6.2rc1 released ---
+
+2838. [func] Backport support for SHA-2 DNSSEC algorithms,
+ RSASHA256 and RSASHA512, from BIND 9.7. (This
+ incorporates changes 2726 and 2738 from that
+ release branch.) [RT #20871]
+
+2837. [port] Prevent Linux spurious warnings about fwrite().
+ [RT #20812]
2831. [security] Do not attempt to validate or cache
out-of-bailiwick data returned with a secure
@@ -10,21 +36,286 @@
2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712]
- --- 9.6.1-P2 released ---
+2825. [bug] Changing the setting of OPTOUT in a NSEC3 chain that
+ was in the process of being created was not properly
+ recorded in the zone. [RT #20786]
+
+2823. [bug] rbtdb.c:getsigningtime() was missing locks. [RT #20781]
+
+2819. [cleanup] Removed unnecessary DNS_POINTER_MAXHOPS define
+ [RT #20771]
+
+2818. [cleanup] rndc could return an incorrect error code
+ when a zone was not found. [RT #20767]
+
+2815. [bug] Exclusively lock the task when freezing a zone.
+ [RT #19838]
+
+2814. [func] Provide a definitive error message when a master
+ zone is not loaded. [RT #20757]
+
+ --- 9.6.2b1 released ---
+
+2797. [bug] Don't decrement the dispatch manager's maxbuffers.
+ [RT #20613]
+
+2790. [bug] Handle DS queries to stub zones. [RT #20440]
+
+2789. [bug] Fixed an INSIST in dispatch.c [RT #20576]
+
+2786. [bug] Additional could be promoted to answer. [RT #20663]
+
+2784. [bug] TC was not always being set when required glue was
+ dropped. [RT #20655]
+
+2783. [func] Return minimal responses to EDNS/UDP queries with a UDP
+ buffer size of 512 or less. [RT #20654]
+
+2782. [port] win32: use getaddrinfo() for hostname lookups.
+ [RT #20650]
+
+2777. [contrib] DLZ MYSQL auto reconnect support discovery was wrong.
2772. [security] When validating, track whether pending data was from
the additional section or not and only return it if
validates as secure. [RT #20438]
- --- 9.6.1-P1 released ---
+2765. [bug] Skip masters for which the TSIG key cannot be found.
+ [RT #20595]
+
+2760. [cleanup] Corrected named-compilezone usage summary. [RT #20533]
+
+2759. [doc] Add information about .jbk/.jnw files to
+ the ARM. [RT #20303]
+
+2758. [bug] win32: Added a workaround for a windows 2008 bug
+ that could cause the UDP client handler to shut
+ down. [RT #19176]
+
+2757. [bug] dig: assertion failure could occur in connect
+ timeout. [RT #20599]
+
+2755. [doc] Clarify documentation of keyset- files in
+ dnssec-signzone man page. [RT #19810]
+
+2754. [bug] Secure-to-insecure transitions failed when zone
+ was signed with NSEC3. [RT #20587]
+
+2750. [bug] dig: assertion failure could occur when a server
+ didn't have an address. [RT #20579]
+
+2749. [bug] ixfr-from-differences generated a non-minimal ixfr
+ for NSEC3 signed zones. [RT #20452]
+
+2747. [bug] Journal roll forwards failed to set the re-signing
+ time of RRSIGs correctly. [RT #20541]
+
+2743. [bug] RRSIG could be incorrectly set in the NSEC3 record
+ for a insecure delegation.
+
+2729. [func] When constructing a CNAME from a DNAME use the DNAME
+ TTL. [RT #20451]
+
+2723. [bug] isc_base32_totext(), isc_base32hex_totext(), and
+ isc_base64_totext(), didn't always mark regions of
+ memory as fully consumed after conversion. [RT #20445]
+
+2722. [bug] Ensure that the memory associated with the name of
+ a node in a rbt tree is not altered during the life
+ of the node. [RT #20431]
+
+2721. [port] Have dst__entropy_status() prime the random number
+ generator. [RT #20369]
+
+2718. [bug] The space calculations in opensslrsa_todns() were
+ incorrect. [RT #20394]
+
+2716. [bug] nslookup debug mode didn't return the ttl. [RT #20414]
+
+2715. [bug] Require OpenSSL support to be explicitly disabled.
+ [RT #20288]
+
+2714. [port] aix/powerpc: 'asm("ics");' needs non standard assembler
+ flags.
+
+2713. [bug] powerpc: atomic operations missing asm("ics") /
+ __isync() calls.
+
+2706. [bug] Loading a zone with a very large NSEC3 salt could
+ trigger an assert. [RT #20368]
+
+2705. [bug] Reconcile the XML stats version number with a later
+ BIND9 release, by adding a "name" attribute to
+ "cache" elements and increasing the version number
+ to 2.2. (This is a minor version change, but may
+ affect XML parsers if they assume the cache element
+ doesn't take an attribute.)
+
+2704. [bug] Serial of dynamic and stub zones could be inconsistent
+ with their SOA serial. [RT #19387]
+
+2701. [doc] Correction to ARM: hmac-md5 is no longer the only
+ supported TSIG key algorithm. [RT #18046]
+
+2700. [doc] The match-mapped-addresses option is discouraged.
+ [RT #12252]
+
+2699. [bug] Missing lock in rbtdb.c. [RT #20037]
+
+2697. [port] win32: ensure that S_IFMT, S_IFDIR, S_IFCHR and
+ S_IFREG are defined after including <isc/stat.h>.
+ [RT #20309]
+
+2696. [bug] named failed to successfully process some valid
+ acl constructs. [RT #20308]
+
+2692. [port] win32: 32/64 bit cleanups. [RT #20335]
+
+2690. [bug] win32: fix isc_thread_key_getspecific() prototype.
+ [RT #20315]
+
+2689. [bug] Correctly handle snprintf result. [RT #20306]
+
+2688. [bug] Use INTERFACE_F_POINTTOPOINT, not IFF_POINTOPOINT,
+ to decide to fetch the destination address. [RT #20305]
+
+2686. [bug] dnssec-signzone should clean the old NSEC chain when
+ signing with NSEC3 and vice versa. [RT #20301]
+
+2683. [bug] dnssec-signzone should clean out old NSEC3 chains when
+ the NSEC3 parameters used to sign the zone change.
+ [RT #20246]
+
+2681. [bug] IPSECKEY RR of gateway type 3 was not correctly
+ decoded. [RT #20269]
+
+2678. [func] Treat DS queries as if "minimal-response yes;"
+ was set. [RT #20258]
+
+2672. [bug] Don't enable searching in 'host' when doing reverse
+ lookups. [RT #20218]
+
+2670. [bug] Unexpected connect failures failed to log enough
+ information to be useful. [RT #20205]
+
+2663. [func] win32: allow named to run as a service using
+ "NT AUTHORITY\LocalService" as the account. [RT #19977]
+
+2662. [bug] lwres_getipnodebyname() and lwres_getipnodebyaddr()
+ returned a misleading error code when lwresd was
+ down. [RT #20028]
+
+2661. [bug] Check whether socket fd exceeds FD_SETSIZE when
+ creating lwres context. [RT #20029]
+
+2659. [doc] Clarify dnssec-keygen doc: key name must match zone
+ name for DNSSEC keys. [RT #19938]
+
+2656. [func] win32: add a "tools only" check box to the installer
+ which causes it to only install dig, host, nslookup,
+ nsupdate and relevant DLLs. [RT #19998]
+
+2655. [doc] Document that key-directory does not affect
+ rndc.key. [RT #20155]
+
+2653. [bug] Treat ENGINE_load_private_key() failures as key
+ not found rather than out of memory. [RT #18033]
+
+2649. [bug] Set the domain for forward only zones. [RT #19944]
+
+2648. [port] win32: isc_time_seconds() was broken. [RT #19900]
+
+2647. [bug] Remove unnecessary SOA updates when a new KSK is
+ added. [RT #19913]
+
+2646. [bug] Incorrect cleanup on error in socket.c. [RT #19987]
+
+2645. [port] "gcc -m32" didn't work on amd64 and x86_64 platforms
+ which default to 64 bits. [RT #19927]
+
+2643. [bug] Stub zones interacted badly with NSEC3 support.
+ [RT #19777]
+
+2642. [bug] nsupdate could dump core on solaris when reading
+ improperly formatted key files. [RT #20015]
2640. [security] A specially crafted update packet will cause named
to exit. [RT #20000]
+2639. [bug] Silence compiler warnings in gssapi code. [RT #19954]
+
+2637. [func] Rationalize dnssec-signzone's signwithkey() calling.
+ [RT #19959]
+
+2635. [bug] isc_inet_ntop() incorrectly handled 0.0/16 addresses.
+ [RT #19716]
+
+2633. [bug] Handle 15 bit rand() functions. [RT #19783]
+
+2632. [func] util/kit.sh: warn if documentation appears to be out of
+ date. [RT #19922]
+
+2625. [bug] Missing UNLOCK in rbtdb.c. [RT #19865]
+
+2623. [bug] Named started seaches for DS non-optimally. [RT #19915]
+
+2621. [doc] Made copyright boilterplate consistent. [RT #19833]
+
+2920. [bug] Delay thawing the zone until the reload of it has
+ completed successfully. [RT #19750]
+
+2618. [bug] The sdb and sdlz db_interator_seek() methods could
+ loop infinitely. [RT #19847]
+
+2617. [bug] ifconfig.sh failed to emit an error message when
+ run from the wrong location. [RT #19375]
+
+2616. [bug] 'host' used the nameservers from resolv.conf even
+ when a explicit nameserver was specified. [RT #19852]
+
+2615. [bug] "__attribute__((unused))" was in the wrong place
+ for ia64 gcc builds. [RT #19854]
+
+2614. [port] win32: 'named -v' should automatically be executed
+ in the foreground. [RT #19844]
+
+2613. [bug] Option argument validation was missing for
+ dnssec-dsfromkey. [RT #19828]
+
+2610. [port] sunos: Change #2363 was not complete. [RT #19796]
+
+2608. [func] Perform post signing verification checks in
+ dnssec-signzone. These can be disabled with -P.
+
+ The post sign verification test ensures that for each
+ algorithm in use there is at least one non revoked
+ self signed KSK key. That all revoked KSK keys are
+ self signed. That all records in the zone are signed
+ by the algorithm. [RT #19653]
+
+2601. [doc] Mention file creation mode mask in the
+ named manual page.
+
+2593. [bug] Improve a corner source of SERVFAILs [RT #19632]
+
+2589. [bug] dns_db_unregister() failed to clear '*dbimp'.
+ [RT #19626]
+
+2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
+ Requires MySQL 5.0.19 or later. [RT #19084]
+
+2580. [bug] UpdateRej statistics counter could be incremented twice
+ for one rejection. [RT #19476]
+
+2533. [doc] ARM: document @ (at-sign). [RT #17144]
+
+2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent
+ function. [RT #18582]
+
--- 9.6.1 released ---
2607. [bug] named could incorrectly delete NSEC3 records for
- empty nodes when processing a update request.
+ empty nodes when processing a update request.
[RT #19749]
2606. [bug] "delegation-only" was not being accepted in
@@ -78,7 +369,7 @@
date to the version string, -DNO_VERSION_DATE.
2582. [bug] Don't emit warning log message when we attempt to
- remove non-existant journal. [RT #19516]
+ remove non-existent journal. [RT #19516]
2579. [bug] DNSSEC lookaside validation failed to handle unknown
algorithms. [RT #19479]
@@ -136,7 +427,7 @@
2556. [port] Solaris: mkdir(2) on tmpfs filesystems does not do the
error checks in the correct order resulting in the
wrong error code sometimes being returned. [RT #19249]
-
+
2554. [bug] Validation of uppercase queries from NSEC3 zones could
fail. [RT #19297]
@@ -185,7 +476,7 @@
2536. [cleanup] Silence some warnings when -Werror=format-security is
specified. [RT #19083]
-2535. [bug] dig +showsearh and +trace interacted badly. [RT #19091]
+2535. [bug] dig +showsearch and +trace interacted badly. [RT #19091]
2532. [bug] dig: check the question section of the response to
see if it matches the asked question. [RT #18495]
@@ -198,8 +489,8 @@
2529. [cleanup] Upgrade libtool to silence complaints from recent
version of autoconf. [RT #18657]
-2528. [cleanup] Silence spurious configure warning about
- --datarootdir [RT #19096]
+2528. [cleanup] Silence spurious configure warning about
+ --datarootdir [RT #19096]
2527. [bug] named could reuse cache on reload with
enabling/disabling validation. [RT #19119]
@@ -222,7 +513,7 @@
preceded in resolv.conf. [RT #19081]
2517. [bug] dig +trace with -4 or -6 failed when it chose a
- nameserver address of the excluded address.
+ nameserver address of the excluded address type.
[RT #18843]
2516. [bug] glue sort for responses was performed even when not
@@ -235,7 +526,7 @@
2511. [cleanup] dns_rdata_tofmttext() add const to linebreak.
[RT #18885]
-2506. [port] solaris: Check at configure time if
+2506. [port] solaris: Check at configure time if
hack_shutup_pthreadonceinit is needed. [RT #19037]
2505. [port] Treat amd64 similarly to x86_64 when determining
@@ -258,7 +549,7 @@
2515. [port] win32: build dnssec-dsfromkey and dnssec-keyfromlabel.
[RT #19063]
-2513 [bug] Fix windows cli build. [RT #19062]
+2513. [bug] Fix windows cli build. [RT #19062]
2510. [bug] "dig +sigchase" could trigger REQUIRE failures.
[RT #19033]
@@ -343,7 +634,7 @@
2478. [bug] 'addresses' could be used uninitialized in
configure_forward(). [RT #18800]
-
+
2477. [bug] dig: the global option to print the command line is
+cmd not print_cmd. Update the output to reflect
this. [RT #17008]
@@ -359,7 +650,7 @@
2473. [port] linux: raise the limit on open files to the possible
maximum value before spawning threads; 'files'
- specified in named.conf doesn't seem to work with
+ specified in named.conf doesn't seem to work with
threads as expected. [RT #18784]
2472. [port] linux: check the number of available cpu's before
@@ -388,7 +679,7 @@
2464. [port] linux: check that a capability is present before
trying to set it. [RT #18135]
-2463. [port] linux: POSIX doesn't include the IPv6 Advanced Socket
+2463. [port] linux: POSIX doesn't include the IPv6 Advanced Socket
API and glibc hides parts of the IPv6 Advanced Socket
API as a result. This is stupid as it breaks how the
two halves (Basic and Advanced) of the IPv6 Socket API
@@ -418,7 +709,7 @@
2456. [bug] In ACLs, ::/0 and 0.0.0.0/0 would both match any
address, regardless of family. They now correctly
distinguish IPv4 from IPv6. [RT #18559]
-
+
2455. [bug] Stop metadata being transferred via axfr/ixfr.
[RT #18639]
@@ -458,7 +749,7 @@
2442. [bug] A lock could be destroyed twice. [RT# 18626]
-2441. [bug] isc_radix_insert() could copy radix tree nodes
+2441. [bug] isc_radix_insert() could copy radix tree nodes
incompletely. [RT #18573]
2440. [bug] named-checkconf used an incorrect test to determine
@@ -515,7 +806,7 @@
implementation. Allow the use of kqueue,
epoll and /dev/poll to be selected at compile
time. [RT #18277]
-
+
2423. [security] Randomize server selection on queries, so as to
make forgery a little more difficult. Instead of
always preferring the server with the lowest RTT,
@@ -583,9 +874,9 @@
2406. [placeholder]
-2405. [cleanup] The default value for dnssec-validation was changed to
- "yes" in 9.5.0-P1 and all subsequent releases; this
- was inadvertently omitted from CHANGES at the time.
+2405. [cleanup] The default value for dnssec-validation was changed to
+ "yes" in 9.5.0-P1 and all subsequent releases; this
+ was inadvertently omitted from CHANGES at the time.
2404. [port] hpux: files unlimited support.
@@ -661,7 +952,7 @@
2380. [bug] dns_view_find() was not returning NXDOMAIN/NXRRSET
proofs which, in turn, caused validation failures
for insecure zones immediately below a secure zone
- the server was authoritative for. [RT #18112]
+ the server was authoritative for. [RT #18112]
2379. [contrib] queryperf/gen-data-queryperf.py: removed redundant
TLDs and supported RRs with TTLs [RT #17972]
@@ -709,7 +1000,7 @@
2363. [port] sunos: pre-set "lt_cv_sys_max_cmd_len=4096;".
[RT #17513]
-2362. [cleanup] Make "rrset-order fixed" a compile-time option.
+2362. [cleanup] Make "rrset-order fixed" a compile-time option.
settable by "./configure --enable-fixed-rrset".
Disabled by default. [RT #17977]
@@ -792,12 +1083,12 @@
interfaces if there are not listen-on-v6 clauses in
named.conf. [RT #17581]
-2335. [port] sunos: libbind and *printf() support for long long.
+2335. [port] sunos: libbind and *printf() support for long long.
[RT #17513]
2334. [bug] Bad REQUIRES in fromstruct_in_naptr(), off by one
bug in fromstruct_txt(). [RT #17609]
-
+
2333. [bug] Fix off by one error in isc_time_nowplusinterval().
[RT #17608]
@@ -842,7 +1133,7 @@
2320. [func] Make statistics counters thread-safe for platforms
that support certain atomic operations. [RT #17466]
-2319. [bug] Silence Coverity warnings in
+2319. [bug] Silence Coverity warnings in
lib/dns/rdata/in_1/apl_42.c. [RT #17469]
2318. [port] sunos fixes for libbind. [RT #17514]
@@ -894,7 +1185,7 @@
2301. [bug] Remove resource leak and fix error messages in
bin/tests/system/lwresd/lwtest.c. [RT #17474]
-2300. [bug] Fixed failure to close open file in
+2300. [bug] Fixed failure to close open file in
bin/tests/names/t_names.c. [RT #17473]
2299. [bug] Remove unnecessary NULL check in
@@ -1017,7 +1308,7 @@
2261. [bug] Fix memory leak with "any" and "none" ACLs [RT #17272]
2260. [bug] Reported wrong clients-per-query when increasing the
- value. [RT #17236]
+ value. [RT #17236]
2259. [placeholder]
@@ -1039,10 +1330,10 @@
intermediate values as timer->idle was reset by
isc_timer_touch(). [RT #17243]
-2253. [func] "max-cache-size" defaults to 32M.
+2253. [func] "max-cache-size" defaults to 32M.
"max-acache-size" defaults to 16M.
-2252. [bug] Fixed errors in sortlist code [RT #17216]
+2252. [bug] Fixed errors in sortlist code [RT #17216]
2251. [placeholder]
@@ -1050,11 +1341,11 @@
memory statistics file should be written or not.
Additionally named's -m option will cause the
statistics file to be written. [RT #17113]
-
-2249. [bug] Only set Authentic Data bit if client requested
- DNSSEC, per RFC 3655 [RT #17175]
-2248. [cleanup] Fix several errors reported by Coverity. [RT #17160]
+2249. [bug] Only set Authentic Data bit if client requested
+ DNSSEC, per RFC 3655 [RT #17175]
+
+2248. [cleanup] Fix several errors reported by Coverity. [RT #17160]
2247. [doc] Sort doc/misc/options. [RT #17067]
@@ -1095,11 +1386,11 @@
2235. [bug] <isc/atomic.h> was not being installed. [RT #17135]
-2234. [port] Correct some compiler warnings on SCO OSr5 [RT #17134]
-
-2233. [func] Add support for O(1) ACL processing, based on
- radix tree code originally written by Kevin
- Brintnall. [RT #16288]
+2234. [port] Correct some compiler warnings on SCO OSr5 [RT #17134]
+
+2233. [func] Add support for O(1) ACL processing, based on
+ radix tree code originally written by Kevin
+ Brintnall. [RT #16288]
2232. [bug] dns_adb_findaddrinfo() could fail and return
ISC_R_SUCCESS. [RT #17137]
@@ -1120,7 +1411,7 @@
2226. [placeholder]
2225. [bug] More support for systems with no IPv4 addresses.
- [RT #17111]
+ [RT #17111]
2224. [bug] Defer journal compaction if a xfrin is in progress.
[RT #17119]
@@ -1128,7 +1419,7 @@
2223. [bug] Make a new journal when compacting. [RT #17119]
2222. [func] named-checkconf now checks server key references.
- [RT #17097]
+ [RT #17097]
2221. [bug] Set the event result code to reflect the actual
record turned to caller when a cache update is
@@ -1137,7 +1428,7 @@
2220. [bug] win32: Address a race condition in final shutdown of
the Windows socket code. [RT #17028]
-
+
2219. [bug] Apply zone consistency checks to additions, not
removals, when updating. [RT #17049]
@@ -1147,7 +1438,7 @@
2217. [func] Adjust update log levels. [RT #17092]
2216. [cleanup] Fix a number of errors reported by Coverity.
- [RT #17094]
+ [RT #17094]
2215. [bug] Bad REQUIRE check isc_hmacsha1_verify(). [RT #17094]
@@ -1193,7 +1484,7 @@
localhost;) is used.
[RT #16987]
-
+
2205. [bug] libbind: change #2119 broke thread support. [RT #16982]
2204. [bug] "rndc flushanme name unknown-view" caused named
@@ -1332,7 +1623,7 @@
allow-query-on, allow-recursion-on and
allow-query-cache-on. [RT #16291]
-2164. [bug] The code to determine how named-checkzone /
+2164. [bug] The code to determine how named-checkzone /
named-compilezone was called failed under windows.
[RT #16764]
@@ -1539,14 +1830,14 @@
2095. [port] libbind: alway prototype inet_cidr_ntop_ipv6() and
net_cidr_ntop_ipv6(). [RT #16388]
-
+
2094. [contrib] Update named-bootconf. [RT# 16404]
2093. [bug] named-checkzone -s was broken.
2092. [bug] win32: dig, host, nslookup. Use registry config
if resolv.conf does not exist or no nameservers
- listed. [RT #15877]
+ listed. [RT #15877]
2091. [port] dighost.c: race condition on cleanup. [RT #16417]
@@ -1950,7 +2241,7 @@
1964. [func] Separate out MX and SRV to CNAME checks. [RT #15723]
-1963. [port] Tru64 4.0E doesn't support send() and recv().
+1963. [port] Tru64 4.0E doesn't support send() and recv().
[RT #15586]
1962. [bug] Named failed to clear old update-policy when it
@@ -1993,7 +2284,7 @@
1951. [security] Drop queries from particular well known ports.
Don't return FORMERR to queries from particular
well known ports. [RT #15636]
-
+
1950. [port] Solaris 2.5.1 and earlier cannot bind() then connect()
a TCP socket. This prevents the source address being
set for TCP connections. [RT #15628]
@@ -2015,7 +2306,7 @@
1945. [cleanup] dnssec-keygen: RSA (RSAMD5) is no longer recommended.
To generate a RSAMD5 key you must explicitly request
RSAMD5. [RT #13780]
-
+
1944. [cleanup] isc_hash_create() does not need a read/write lock.
[RT #15522]
@@ -2127,7 +2418,7 @@
[RT #15034]
1905. [bug] Strings returned from cfg_obj_asstring() should be
- treated as read-only. The prototype for
+ treated as read-only. The prototype for
cfg_obj_asstring() has been updated to reflect this.
[RT #15256]
@@ -2259,10 +2550,10 @@
1863. [bug] rrset-order "fixed" error messages not complete.
1862. [func] Add additional zone data constancy checks.
- named-checkzone has extended checking of NS, MX and
+ named-checkzone has extended checking of NS, MX and
SRV record and the hosts they reference.
named has extended post zone load checks.
- New zone options: check-mx and integrity-check.
+ New zone options: check-mx and integrity-check.
[RT #4940]
1861. [bug] dig could trigger a INSIST on certain malformed
@@ -2305,9 +2596,9 @@
1848. [bug] Improve SMF integration. [RT #13238]
1847. [bug] isc_ondestroy_init() is called too late in
- dns_rbtdb_create()/dns_rbtdb64_create().
+ dns_rbtdb_create()/dns_rbtdb64_create().
[RT #13661]
-
+
1846. [contrib] query-loc-0.3.0 from Stephane Bortzmeyer
<bortzmeyer@nic.fr>.
@@ -2599,7 +2890,7 @@
[RT #12866]
1748. [func] dig now returns the byte count for axfr/ixfr.
-
+
1747. [bug] BIND 8 compatibility: named/named-checkconf failed
to parse "host-statistics-max" in named.conf.
@@ -2617,7 +2908,7 @@
requested number of worker threads then destruction
of the manager would trigger an INSIST() failure.
[RT #12790]
-
+
1742. [bug] Deleting all records at a node then adding a
previously existing record, in a single UPDATE
transaction, failed to leave / regenerate the
@@ -2628,7 +2919,7 @@
1740. [bug] Replace rbt's hash algorithm as it performed badly
with certain zones. [RT #12729]
-
+
NOTE: a hash context now needs to be established
via isc_hash_create() if the application was not
already doing this.
@@ -2643,7 +2934,7 @@
1736. [bug] dst_key_fromnamedfile() could fail to read a
public key. [RT #12687]
-
+
1735. [bug] 'dig +sigtrace' could die with a REQUIRE failure.
[RE #12688]
@@ -2820,7 +3111,7 @@
1675. [bug] named would sometimes add extra NSEC records to
the authority section.
-
+
1674. [port] linux: increase buffer size used to scan
/proc/net/if_inet6.
@@ -2894,7 +3185,7 @@
1648. [func] Update dnssec-lookaside named.conf syntax to support
multiple dnssec-lookaside namespaces (not yet
- implemented).
+ implemented).
1647. [bug] It was possible trigger a INSIST when chasing a DS
record that required walking back over a empty node.
@@ -2924,7 +3215,7 @@
1638. [bug] "ixfr-from-differences" could generate a REQUIRE
failure if the journal open failed. [RT #11347]
-
+
1637. [bug] Node reference leak on error in addnoqname().
1636. [bug] The dump done callback could get ISC_R_SUCCESS even if
@@ -3018,21 +3309,21 @@
1607. [bug] dig, host and nslookup were still using random()
to generate query ids. [RT# 11013]
-1606. [bug] DLV insecurity proof was failing.
+1606. [bug] DLV insecurity proof was failing.
1605. [func] New dns_db_find() option DNS_DBFIND_COVERINGNSEC.
1604. [bug] A xfrout_ctx_create() failure would result in
xfrout_ctx_destroy() being called with a
partially initialized structure.
-
+
1603. [bug] nsupdate: set interactive based on isatty().
[RT# 10929]
1602. [bug] Logging to a file failed unless a size was specified.
[RT# 10925]
-1601. [bug] Silence spurious warning 'both "recursion no;" and
+1601. [bug] Silence spurious warning 'both "recursion no;" and
"allow-recursion" active' warning from view "_bind".
[RT# 10920]
diff --git a/contrib/bind9/COPYRIGHT b/contrib/bind9/COPYRIGHT
index 620ee98..d95930b 100644
--- a/contrib/bind9/COPYRIGHT
+++ b/contrib/bind9/COPYRIGHT
@@ -1,4 +1,4 @@
-Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
Copyright (C) 1996-2003 Internet Software Consortium.
Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
-$Id: COPYRIGHT,v 1.14.176.1 2009/01/05 23:47:22 tbox Exp $
+$Id: COPYRIGHT,v 1.14.176.2 2010/01/07 23:47:36 tbox Exp $
Portions Copyright (C) 1996-2001 Nominum, Inc.
diff --git a/contrib/bind9/FAQ b/contrib/bind9/FAQ
index b256ed8..9e3469c 100644
--- a/contrib/bind9/FAQ
+++ b/contrib/bind9/FAQ
@@ -1,6 +1,6 @@
Frequently Asked Questions about BIND 9
-Copyright © 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+Copyright © 2004-2010 Internet Systems Consortium, Inc. ("ISC")
Copyright © 2000-2003 Internet Software Consortium.
@@ -784,6 +784,22 @@ A: Red Hat Security Enhanced Linux (SELinux) policy security protections :
See these man-pages for more information : selinux(8), named_selinux
(8), chcon(1), setsebool(8)
+Q: I'm running BIND on Ubuntu -
+
+ Why can't named update slave zone database files?
+
+ Why can't named create DDNS journal files or update the master zones
+ from journals?
+
+ Why can't named create custom log files?
+
+A: Ubuntu uses AppArmor <http://en.wikipedia.org/wiki/AppArmor> in
+ addition to normal file system permissions to protect the system.
+
+ Adjust the paths to use those specified in /etc/apparmor.d/
+ usr.sbin.named or adjust /etc/apparmor.d/usr.sbin.named to allow named
+ to write at the location specified in named.conf.
+
Q: Listening on individual IPv6 interfaces does not work.
A: This is usually due to "/proc/net/if_inet6" not being available in the
diff --git a/contrib/bind9/FAQ.xml b/contrib/bind9/FAQ.xml
index 65e8efc..1d87642 100644
--- a/contrib/bind9/FAQ.xml
+++ b/contrib/bind9/FAQ.xml
@@ -1,7 +1,7 @@
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: FAQ.xml,v 1.46.56.4.12.1 2009/12/31 23:17:56 tbox Exp $ -->
+<!-- $Id: FAQ.xml,v 1.46.56.9 2010/01/20 23:47:43 tbox Exp $ -->
<article class="faq">
<title>Frequently Asked Questions about BIND 9</title>
@@ -29,6 +29,7 @@
<year>2007</year>
<year>2008</year>
<year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -1385,6 +1386,36 @@ named_cache_t: for files modifiable by named - $ROOTDIR/var/{tmp,named/{slaves,d
<qandaentry>
<question>
<para>
+ I'm running BIND on Ubuntu -
+ </para>
+ <para>
+ Why can't named update slave zone database files?
+ </para>
+ <para>
+ Why can't named create DDNS journal files or update
+ the master zones from journals?
+ </para>
+ <para>
+ Why can't named create custom log files?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Ubuntu uses AppArmor <ulink url="http://en.wikipedia.org/wiki/AppArmor">
+ &lt;http://en.wikipedia.org/wiki/AppArmor&gt;</ulink> in
+ addition to normal file system permissions to protect the system.
+ </para>
+ <para>
+ Adjust the paths to use those specified in /etc/apparmor.d/usr.sbin.named
+ or adjust /etc/apparmor.d/usr.sbin.named to allow named to write at the
+ location specified in named.conf.
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>
Listening on individual IPv6 interfaces does not work.
</para>
</question>
diff --git a/contrib/bind9/NSEC3-NOTES b/contrib/bind9/NSEC3-NOTES
index d23b20e..3f8d8f9 100644
--- a/contrib/bind9/NSEC3-NOTES
+++ b/contrib/bind9/NSEC3-NOTES
@@ -35,7 +35,7 @@ will not be completely signed until named has had time to walk the
zone and generate the NSEC and RRSIG records. Initially the NSEC
record at the zone apex will have the OPT bit set. When the NSEC
chain is complete the OPT bit will be cleared. Additionally when
-the zone is fully signed the private type (default TYPE65535) records
+the zone is fully signed the private type (default TYPE65534) records
will have a non zero value for the final octet.
The private type record has 5 octets.
@@ -45,7 +45,7 @@ The private type record has 5 octets.
complete flag (octet 5)
If you wish to go straight to a secure zone using NSEC3 you should
-also add a NSECPARAM record to the update request with the flags
+also add a NSEC3PARAM record to the update request with the flags
field set to indicate whether the NSEC3 chain will have the OPTOUT
bit set or not.
diff --git a/contrib/bind9/README b/contrib/bind9/README
index d151988..902d9ed 100644
--- a/contrib/bind9/README
+++ b/contrib/bind9/README
@@ -42,6 +42,29 @@ BIND 9
Stichting NLnet - NLnet Foundation
Nominum, Inc.
+BIND 9.6.2
+
+ BIND 9.6.2 is a maintenance release, fixing bugs in 9.6.1.
+ It also introduces support for the SHA-2 DNSSEC algorithms,
+ RSASHA256 and RSASHA512.
+
+ Known issues in this release:
+
+ - A validating resolver that has been incorrectly configured with
+ an invalid trust anchor will be unable to resolve names covered
+ by that trust anchor. In all current versions of BIND 9, such a
+ resolver will also generate significant unnecessary DNS traffic
+ while trying to validate. The latter problem will be addressed
+ in future BIND 9 releases. In the meantime, to avoid these
+ problems, exercise caution when configuring "trusted-keys":
+ make sure all keys are correct and current when you add them,
+ and update your configuration in a timely manner when keys
+ roll over.
+
+BIND 9.6.1
+
+ BIND 9.6.1 is a maintenance release, fixing bugs in 9.6.0.
+
BIND 9.6.0
BIND 9.6.0 includes a number of changes from BIND 9.5 and earlier
diff --git a/contrib/bind9/bin/check/named-checkconf.8 b/contrib/bind9/bin/check/named-checkconf.8
index 852b133..072d1cf 100644
--- a/contrib/bind9/bin/check/named-checkconf.8
+++ b/contrib/bind9/bin/check/named-checkconf.8
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2002 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named-checkconf.8,v 1.30 2007/06/20 02:27:32 marka Exp $
+.\" $Id: named-checkconf.8,v 1.30.334.1 2009/07/11 01:55:20 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/check/named-checkconf.html b/contrib/bind9/bin/check/named-checkconf.html
index 34bec80..8fd1e6d 100644
--- a/contrib/bind9/bin/check/named-checkconf.html
+++ b/contrib/bind9/bin/check/named-checkconf.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkconf.html,v 1.30 2007/06/20 02:27:32 marka Exp $ -->
+<!-- $Id: named-checkconf.html,v 1.30.334.1 2009/07/11 01:55:20 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/check/named-checkzone.8 b/contrib/bind9/bin/check/named-checkzone.8
index 5520da3..dfc409e 100644
--- a/contrib/bind9/bin/check/named-checkzone.8
+++ b/contrib/bind9/bin/check/named-checkzone.8
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2002 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named-checkzone.8,v 1.42.334.1 2009/01/23 01:53:33 tbox Exp $
+.\" $Id: named-checkzone.8,v 1.42.334.3 2009/11/11 01:56:22 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,9 +33,9 @@
named\-checkzone, named\-compilezone \- zone file validity checking or converting tool
.SH "SYNOPSIS"
.HP 16
-\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename}
+\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename}
.HP 18
-\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename}
+\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename}
.SH "DESCRIPTION"
.PP
\fBnamed\-checkzone\fR
diff --git a/contrib/bind9/bin/check/named-checkzone.c b/contrib/bind9/bin/check/named-checkzone.c
index 83b3bbe..0b49b51 100644
--- a/contrib/bind9/bin/check/named-checkzone.c
+++ b/contrib/bind9/bin/check/named-checkzone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkzone.c,v 1.51.34.3 2009/05/29 02:17:43 marka Exp $ */
+/* $Id: named-checkzone.c,v 1.51.34.4 2009/11/10 20:01:41 each Exp $ */
/*! \file */
@@ -73,14 +73,16 @@ static enum { progmode_check, progmode_compile } progmode;
static void
usage(void) {
fprintf(stderr,
- "usage: %s [-djqvD] [-c class] [-o output] "
+ "usage: %s [-djqvD] [-c class] "
"[-f inputformat] [-F outputformat] "
"[-t directory] [-w directory] [-k (ignore|warn|fail)] "
"[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
"[-i (full|full-sibling|local|local-sibling|none)] "
"[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
"[-W (ignore|warn)] "
- "zonename filename\n", prog_name);
+ "%s zonename filename\n",
+ prog_name,
+ progmode == progmode_check ? "[-o filename]" : "{-o filename}");
exit(1);
}
diff --git a/contrib/bind9/bin/check/named-checkzone.docbook b/contrib/bind9/bin/check/named-checkzone.docbook
index d863447..4abb07f 100644
--- a/contrib/bind9/bin/check/named-checkzone.docbook
+++ b/contrib/bind9/bin/check/named-checkzone.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkzone.docbook,v 1.34.334.2 2009/01/22 23:47:04 tbox Exp $ -->
+<!-- $Id: named-checkzone.docbook,v 1.34.334.3 2009/11/10 20:01:41 each Exp $ -->
<refentry id="man.named-checkzone">
<refentryinfo>
<date>June 13, 2000</date>
@@ -69,7 +69,6 @@
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-M <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
- <arg><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
<arg><option>-s <replaceable class="parameter">style</replaceable></option></arg>
<arg><option>-S <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
@@ -99,6 +98,7 @@
<arg><option>-w <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-D</option></arg>
<arg><option>-W <replaceable class="parameter">mode</replaceable></option></arg>
+ <arg choice="req"><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
<arg choice="req">zonename</arg>
<arg choice="req">filename</arg>
</cmdsynopsis>
diff --git a/contrib/bind9/bin/check/named-checkzone.html b/contrib/bind9/bin/check/named-checkzone.html
index 71dc445..68a6331 100644
--- a/contrib/bind9/bin/check/named-checkzone.html
+++ b/contrib/bind9/bin/check/named-checkzone.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkzone.html,v 1.42.334.1 2009/01/23 01:53:33 tbox Exp $ -->
+<!-- $Id: named-checkzone.html,v 1.42.334.3 2009/11/11 01:56:22 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,11 +29,11 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
-<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {<code class="option">-o <em class="replaceable"><code>filename</code></em></code>} {zonename} {filename}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543672"></a><h2>DESCRIPTION</h2>
+<a name="id2543674"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkzone</strong></span>
checks the syntax and integrity of a zone file. It performs the
same checks as <span><strong class="command">named</strong></span> does when loading a
@@ -53,7 +53,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543707"></a><h2>OPTIONS</h2>
+<a name="id2543709"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-d</span></dt>
<dd><p>
@@ -239,14 +239,14 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544328"></a><h2>RETURN VALUES</h2>
+<a name="id2544330"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkzone</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544340"></a><h2>SEE ALSO</h2>
+<a name="id2544342"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<em class="citetitle">RFC 1035</em>,
@@ -254,7 +254,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544373"></a><h2>AUTHOR</h2>
+<a name="id2544375"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dig/dig.1 b/contrib/bind9/bin/dig/dig.1
index f7f4370..c8704a1 100644
--- a/contrib/bind9/bin/dig/dig.1
+++ b/contrib/bind9/bin/dig/dig.1
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dig.1,v 1.50.44.2 2009/02/03 01:52:10 tbox Exp $
+.\" $Id: dig.1,v 1.50.44.3 2009/07/11 01:55:20 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/dig/dig.html b/contrib/bind9/bin/dig/dig.html
index 11b55cc..3fd3e75 100644
--- a/contrib/bind9/bin/dig/dig.html
+++ b/contrib/bind9/bin/dig/dig.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dig.html,v 1.45.44.2 2009/02/03 01:52:10 tbox Exp $ -->
+<!-- $Id: dig.html,v 1.45.44.3 2009/07/11 01:55:20 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/dig/dighost.c b/contrib/bind9/bin/dig/dighost.c
index 73264e6..d730c0e 100644
--- a/contrib/bind9/bin/dig/dighost.c
+++ b/contrib/bind9/bin/dig/dighost.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dighost.c,v 1.311.70.8 2009/02/25 02:39:21 marka Exp $ */
+/* $Id: dighost.c,v 1.311.70.11 2009/11/10 17:27:13 each Exp $ */
/*! \file
* \note
@@ -1048,7 +1048,9 @@ setup_system(void) {
debug("ndots is %d.", ndots);
}
- copy_server_list(lwconf, &server_list);
+ /* If user doesn't specify server use nameservers from resolv.conf. */
+ if (ISC_LIST_EMPTY(server_list))
+ copy_server_list(lwconf, &server_list);
/* If we don't find a nameserver fall back to localhost */
if (ISC_LIST_EMPTY(server_list)) {
@@ -2397,11 +2399,9 @@ connect_timeout(isc_task_t *task, isc_event_t *event) {
if (!l->tcp_mode)
send_udp(ISC_LIST_NEXT(cq, link));
else {
- isc_socket_cancel(query->sock, NULL,
- ISC_SOCKCANCEL_ALL);
- isc_socket_detach(&query->sock);
- sockcount--;
- debug("sockcount=%d", sockcount);
+ if (query->sock != NULL)
+ isc_socket_cancel(query->sock, NULL,
+ ISC_SOCKCANCEL_ALL);
send_tcp_connect(ISC_LIST_NEXT(cq, link));
}
UNLOCK_LOOKUP;
@@ -2604,12 +2604,10 @@ connect_done(isc_task_t *task, isc_event_t *event) {
if (sevent->result == ISC_R_CANCELED) {
debug("in cancel handler");
- if (query->sock != NULL) {
- isc_socket_detach(&query->sock);
- sockcount--;
- INSIST(sockcount >= 0);
- debug("sockcount=%d", sockcount);
- }
+ isc_socket_detach(&query->sock);
+ INSIST(sockcount > 0);
+ sockcount--;
+ debug("sockcount=%d", sockcount);
query->waiting_connect = ISC_FALSE;
isc_event_free(&event);
l = query->lookup;
diff --git a/contrib/bind9/bin/dig/host.1 b/contrib/bind9/bin/dig/host.1
index eebdad8..c538ae3 100644
--- a/contrib/bind9/bin/dig/host.1
+++ b/contrib/bind9/bin/dig/host.1
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2002 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: host.1,v 1.29.114.1 2009/01/23 01:53:33 tbox Exp $
+.\" $Id: host.1,v 1.29.114.2 2009/07/11 01:55:20 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/dig/host.c b/contrib/bind9/bin/dig/host.c
index 9f30206..8cd5b3d 100644
--- a/contrib/bind9/bin/dig/host.c
+++ b/contrib/bind9/bin/dig/host.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: host.c,v 1.116.216.2 2009/05/06 23:47:18 tbox Exp $ */
+/* $Id: host.c,v 1.116.216.3 2009/09/08 23:28:20 marka Exp $ */
/*! \file */
@@ -839,11 +839,10 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
} else {
strncpy(lookup->textname, hostname, sizeof(lookup->textname));
lookup->textname[sizeof(lookup->textname)-1]=0;
+ usesearch = ISC_TRUE;
}
lookup->new_search = ISC_TRUE;
ISC_LIST_APPEND(lookup_list, lookup, link);
-
- usesearch = ISC_TRUE;
}
int
diff --git a/contrib/bind9/bin/dig/host.html b/contrib/bind9/bin/dig/host.html
index f210731..3928c93 100644
--- a/contrib/bind9/bin/dig/host.html
+++ b/contrib/bind9/bin/dig/host.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: host.html,v 1.28.114.1 2009/01/23 01:53:33 tbox Exp $ -->
+<!-- $Id: host.html,v 1.28.114.2 2009/07/11 01:55:20 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/dig/nslookup.1 b/contrib/bind9/bin/dig/nslookup.1
index 2d19534..68b419a 100644
--- a/contrib/bind9/bin/dig/nslookup.1
+++ b/contrib/bind9/bin/dig/nslookup.1
@@ -1,6 +1,6 @@
.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: nslookup.1,v 1.14 2007/05/16 06:12:01 marka Exp $
+.\" $Id: nslookup.1,v 1.14.354.1 2009/07/11 01:55:20 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/dig/nslookup.c b/contrib/bind9/bin/dig/nslookup.c
index 5679626..000f54e 100644
--- a/contrib/bind9/bin/dig/nslookup.c
+++ b/contrib/bind9/bin/dig/nslookup.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nslookup.c,v 1.117.334.4 2009/05/06 11:41:57 fdupont Exp $ */
+/* $Id: nslookup.c,v 1.117.334.5 2009/10/20 01:11:22 marka Exp $ */
#include <config.h>
@@ -373,6 +373,7 @@ detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
printrdata(&rdata);
}
dns_rdata_reset(&rdata);
+ printf("\tttl = %u\n", rdataset->ttl);
loopresult = dns_rdataset_next(rdataset);
}
}
diff --git a/contrib/bind9/bin/dig/nslookup.html b/contrib/bind9/bin/dig/nslookup.html
index 0f38176..3984a16 100644
--- a/contrib/bind9/bin/dig/nslookup.html
+++ b/contrib/bind9/bin/dig/nslookup.html
@@ -1,7 +1,7 @@
<!--
- Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nslookup.html,v 1.21 2007/05/16 06:12:01 marka Exp $ -->
+<!-- $Id: nslookup.html,v 1.21.354.1 2009/07/11 01:55:20 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
index 653aa3e..8bd4aa5 100644
--- a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-dsfromkey.c,v 1.2.14.3 2009/03/02 02:54:15 marka Exp $ */
+/* $Id: dnssec-dsfromkey.c,v 1.2.14.6 2010/01/11 23:47:22 tbox Exp $ */
/*! \file */
@@ -78,10 +78,18 @@ loadkeys(char *dirname, char *setname)
isc_buffer_init(&buf, filename, sizeof(filename));
if (dirname != NULL) {
+ if (isc_buffer_availablelength(&buf) < strlen(dirname))
+ fatal("directory name '%s' too long", dirname);
isc_buffer_putstr(&buf, dirname);
- if (dirname[strlen(dirname) - 1] != '/')
+ if (dirname[strlen(dirname) - 1] != '/') {
+ if (isc_buffer_availablelength(&buf) < 1)
+ fatal("directory name '%s' too long", dirname);
isc_buffer_putstr(&buf, "/");
+ }
}
+
+ if (isc_buffer_availablelength(&buf) < strlen("keyset-"))
+ fatal("directory name '%s' too long", dirname);
isc_buffer_putstr(&buf, "keyset-");
result = dns_name_tofilenametext(name, ISC_FALSE, &buf);
check_result(result, "dns_name_tofilenametext()");
@@ -210,12 +218,12 @@ emitds(unsigned int dtype, dns_rdata_t *rdata)
putchar(' ');
isc_buffer_usedregion(&classb, &r);
- fwrite(r.base, 1, r.length, stdout);
+ isc_util_fwrite(r.base, 1, r.length, stdout);
printf(" DS ");
isc_buffer_usedregion(&textb, &r);
- fwrite(r.base, 1, r.length, stdout);
+ isc_util_fwrite(r.base, 1, r.length, stdout);
putchar('\n');
}
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
index 6222058..03f13e9 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
@@ -1,6 +1,6 @@
-.\" Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keyfromlabel.8,v 1.6 2008/11/08 01:11:47 tbox Exp $
+.\" $Id: dnssec-keyfromlabel.8,v 1.6.14.3 2010/01/16 01:55:32 tbox Exp $
.\"
.hy 0
.ad l
@@ -43,7 +43,13 @@ gets keys with the given label from a crypto hardware and builds key files for D
.RS 4
Selects the cryptographic algorithm. The value of
\fBalgorithm\fR
-must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or DH (Diffie Hellman). These values are case insensitive.
+.sp
+If no algorithm is specified, then RSASHA1 will be used by default, unless the
+\fB\-3\fR
+option is specified, in which case NSEC3RSASHA1 will be used instead. (If
+\fB\-3\fR
+is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended.
.sp
@@ -138,12 +144,10 @@ file contains algorithm specific fields. For obvious security reasons, this file
\fBdnssec\-keygen\fR(8),
\fBdnssec\-signzone\fR(8),
BIND 9 Administrator Reference Manual,
-RFC 2539,
-RFC 2845,
-RFC 4033.
+RFC 4034.
.SH "AUTHOR"
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2008 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
index e7587c3..78bfda3 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keyfromlabel.c,v 1.4 2008/09/24 02:46:21 marka Exp $ */
+/* $Id: dnssec-keyfromlabel.c,v 1.4.50.2 2010/01/15 23:47:31 tbox Exp $ */
/*! \file */
@@ -48,7 +48,8 @@ const char *program = "dnssec-keyfromlabel";
int verbose;
static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |"
- " NSEC3DSA | NSEC3RSASHA1";
+ " NSEC3DSA | NSEC3RSASHA1 |"
+ " RSASHA256 | RSASHA512";
static void
usage(void) {
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
index 2bcf0a4..f2ab152 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.docbook,v 1.6 2008/11/07 13:54:11 jreed Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.docbook,v 1.6.14.2 2010/01/15 23:47:31 tbox Exp $ -->
<refentry id="man.dnssec-keyfromlabel">
<refentryinfo>
<date>February 8, 2008</date>
@@ -37,6 +37,7 @@
<docinfo>
<copyright>
<year>2008</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -75,11 +76,19 @@
<listitem>
<para>
Selects the cryptographic algorithm. The value of
- <option>algorithm</option> must be one of RSAMD5 (RSA)
- or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ <option>algorithm</option> must be one of RSAMD5,
+ RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
+ RSASHA512 or DH (Diffie Hellman).
These values are case insensitive.
</para>
<para>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <option>-3</option> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <option>-3</option> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </para>
+ <para>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended.
</para>
@@ -246,9 +255,7 @@
<refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 9 Administrator Reference Manual</citetitle>,
- <citetitle>RFC 2539</citetitle>,
- <citetitle>RFC 2845</citetitle>,
- <citetitle>RFC 4033</citetitle>.
+ <citetitle>RFC 4034</citetitle>.
</para>
</refsect1>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
index cbea64b..1aafccd 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
@@ -1,7 +1,7 @@
<!--
- - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.html,v 1.5 2008/10/15 01:11:35 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.html,v 1.5.44.3 2010/01/16 01:55:32 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -31,7 +31,7 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543413"></a><h2>DESCRIPTION</h2>
+<a name="id2543416"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
@@ -39,17 +39,25 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543425"></a><h2>OPTIONS</h2>
+<a name="id2543428"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5 (RSA)
- or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5,
+ RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
+ RSASHA512 or DH (Diffie Hellman).
These values are case insensitive.
</p>
<p>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <code class="option">-3</code> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <code class="option">-3</code> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </p>
+<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended.
</p>
@@ -112,7 +120,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543619"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2543632"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -153,17 +161,15 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543691"></a><h2>SEE ALSO</h2>
+<a name="id2543704"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
- <em class="citetitle">RFC 2539</em>,
- <em class="citetitle">RFC 2845</em>,
- <em class="citetitle">RFC 4033</em>.
+ <em class="citetitle">RFC 4034</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543731"></a><h2>AUTHOR</h2>
+<a name="id2543737"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.8 b/contrib/bind9/bin/dnssec/dnssec-keygen.8
index 13db3d9..485ea6e 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.8
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.8
@@ -1,7 +1,7 @@
-.\" Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004, 2005, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keygen.8,v 1.40 2008/10/15 01:11:35 tbox Exp $
+.\" $Id: dnssec-keygen.8,v 1.40.44.4 2010/01/16 01:55:32 tbox Exp $
.\"
.hy 0
.ad l
@@ -38,13 +38,17 @@ dnssec\-keygen \- DNSSEC key generation tool
.PP
\fBdnssec\-keygen\fR
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845.
+.PP
+The
+\fBname\fR
+of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated.
.SH "OPTIONS"
.PP
\-a \fIalgorithm\fR
.RS 4
-Selects the cryptographic algorithm. The value of
+Selects the cryptographic algorithm. For DNSSEC keys, the value of
\fBalgorithm\fR
-must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC\-MD5. These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory.
.sp
@@ -53,7 +57,7 @@ Note 2: HMAC\-MD5 and DH automatically set the \-k flag.
.PP
\-b \fIkeysize\fR
.RS 4
-Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC\-MD5 keys must be between 1 and 512 bits.
+Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits.
.RE
.PP
\-n \fInametype\fR
@@ -189,12 +193,12 @@ and
BIND 9 Administrator Reference Manual,
RFC 2539,
RFC 2845,
-RFC 4033.
+RFC 4034.
.SH "AUTHOR"
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004, 2005, 2007\-2010 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000\-2003 Internet Software Consortium.
.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.c b/contrib/bind9/bin/dnssec/dnssec-keygen.c
index 614d388..2b9a863 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.c
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keygen.c,v 1.81 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: dnssec-keygen.c,v 1.81.48.2 2010/01/15 23:47:31 tbox Exp $ */
/*! \file */
@@ -62,8 +62,8 @@
const char *program = "dnssec-keygen";
int verbose;
-static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | NSEC3DSA |"
- " NSEC3RSASHA1 | HMAC-MD5 |"
+static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | RSASHA256 |"
+ " RSASHA512 | NSEC3DSA | NSEC3RSASHA1 | HMAC-MD5 |"
" HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |"
" HMAC-SHA384 | HMAC-SHA512";
@@ -84,6 +84,8 @@ usage(void) {
fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA);
fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA);
fprintf(stderr, " NSEC3RSASHA1:\t\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA);
fprintf(stderr, " DH:\t\t[128..4096]\n");
fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n");
fprintf(stderr, " NSEC3DSA:\t\t[512..1024] and divisible by 64\n");
@@ -307,9 +309,14 @@ main(int argc, char **argv) {
case DNS_KEYALG_RSAMD5:
case DNS_KEYALG_RSASHA1:
case DNS_KEYALG_NSEC3RSASHA1:
+ case DNS_KEYALG_RSASHA256:
if (size != 0 && (size < 512 || size > MAX_RSA))
fatal("RSA key size %d out of range", size);
break;
+ case DNS_KEYALG_RSASHA512:
+ if (size != 0 && (size < 1024 || size > MAX_RSA))
+ fatal("RSA key size %d out of range", size);
+ break;
case DNS_KEYALG_DH:
if (size != 0 && (size < 128 || size > 4096))
fatal("DH key size %d out of range", size);
@@ -376,7 +383,8 @@ main(int argc, char **argv) {
}
if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 ||
- alg == DNS_KEYALG_NSEC3RSASHA1) && rsa_exp != 0)
+ alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 ||
+ alg == DNS_KEYALG_RSASHA512) && rsa_exp != 0)
fatal("specified RSA exponent for a non-RSA key");
if (alg != DNS_KEYALG_DH && generator != 0)
@@ -440,12 +448,16 @@ main(int argc, char **argv) {
switch(alg) {
case DNS_KEYALG_RSAMD5:
case DNS_KEYALG_RSASHA1:
+ case DNS_KEYALG_NSEC3RSASHA1:
+ case DNS_KEYALG_RSASHA256:
+ case DNS_KEYALG_RSASHA512:
param = rsa_exp;
break;
case DNS_KEYALG_DH:
param = generator;
break;
case DNS_KEYALG_DSA:
+ case DNS_KEYALG_NSEC3DSA:
case DST_ALG_HMACMD5:
case DST_ALG_HMACSHA1:
case DST_ALG_HMACSHA224:
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
index c267a1b..92ef9b9 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004, 2005, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.docbook,v 1.22 2008/10/14 14:32:50 jreed Exp $ -->
+<!-- $Id: dnssec-keygen.docbook,v 1.22.44.4 2010/01/15 23:47:33 tbox Exp $ -->
<refentry id="man.dnssec-keygen">
<refentryinfo>
<date>June 30, 2000</date>
@@ -41,6 +41,8 @@
<year>2005</year>
<year>2007</year>
<year>2008</year>
+ <year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -80,6 +82,11 @@
and RFC 4034. It can also generate keys for use with
TSIG (Transaction Signatures), as defined in RFC 2845.
</para>
+ <para>
+ The <option>name</option> of the key is specified on the command
+ line. For DNSSEC keys, this must match the name of the zone for
+ which the key is being generated.
+ </para>
</refsect1>
<refsect1>
@@ -90,10 +97,13 @@
<term>-a <replaceable class="parameter">algorithm</replaceable></term>
<listitem>
<para>
- Selects the cryptographic algorithm. The value of
- <option>algorithm</option> must be one of RSAMD5 (RSA) or RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5.
- These values are case insensitive.
+ Selects the cryptographic algorithm. For DNSSEC keys, the value
+ of <option>algorithm</option> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
+ For TSIG/TKEY, the value must
+ be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
+ HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
+ case insensitive.
</para>
<para>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
@@ -111,11 +121,10 @@
<listitem>
<para>
Specifies the number of bits in the key. The choice of key
- size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be
- between
- 512 and 2048 bits. Diffie Hellman keys must be between
+ size depends on the algorithm used. RSA keys must be
+ between 512 and 2048 bits. Diffie Hellman keys must be between
128 and 4096 bits. DSA keys must be between 512 and 1024
- bits and an exact multiple of 64. HMAC-MD5 keys must be
+ bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
</para>
</listitem>
@@ -343,7 +352,7 @@
<citetitle>BIND 9 Administrator Reference Manual</citetitle>,
<citetitle>RFC 2539</citetitle>,
<citetitle>RFC 2845</citetitle>,
- <citetitle>RFC 4033</citetitle>.
+ <citetitle>RFC 4034</citetitle>.
</para>
</refsect1>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.html b/contrib/bind9/bin/dnssec/dnssec-keygen.html
index 696ef88..fccec6f 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.html
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004, 2005, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.html,v 1.32 2008/10/15 01:11:35 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.html,v 1.32.44.4 2010/01/16 01:55:32 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -32,23 +32,31 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-b <em class="replaceable"><code>keysize</code></em>} {-n <em class="replaceable"><code>nametype</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k</code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543477"></a><h2>DESCRIPTION</h2>
+<a name="id2543483"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keygen</strong></span>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
TSIG (Transaction Signatures), as defined in RFC 2845.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. For DNSSEC keys, this must match the name of the zone for
+ which the key is being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543489"></a><h2>OPTIONS</h2>
+<a name="id2543501"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
- Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5 (RSA) or RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5.
- These values are case insensitive.
+ Selects the cryptographic algorithm. For DNSSEC keys, the value
+ of <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
+ For TSIG/TKEY, the value must
+ be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
+ HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
+ case insensitive.
</p>
<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
@@ -62,11 +70,10 @@
<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt>
<dd><p>
Specifies the number of bits in the key. The choice of key
- size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be
- between
- 512 and 2048 bits. Diffie Hellman keys must be between
+ size depends on the algorithm used. RSA keys must be
+ between 512 and 2048 bits. Diffie Hellman keys must be between
128 and 4096 bits. DSA keys must be between 512 and 1024
- bits and an exact multiple of 64. HMAC-MD5 keys must be
+ bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
</p></dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
@@ -148,7 +155,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543824"></a><h2>GENERATED KEYS</h2>
+<a name="id2543836"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -194,7 +201,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543906"></a><h2>EXAMPLE</h2>
+<a name="id2543918"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -215,16 +222,16 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543949"></a><h2>SEE ALSO</h2>
+<a name="id2544030"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
<em class="citetitle">RFC 2845</em>,
- <em class="citetitle">RFC 4033</em>.
+ <em class="citetitle">RFC 4034</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544049"></a><h2>AUTHOR</h2>
+<a name="id2544061"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.8 b/contrib/bind9/bin/dnssec/dnssec-signzone.8
index 1e77927..7b21fb6 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.8
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.8
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-signzone.8,v 1.47.44.4.8.1 2009/12/31 23:17:46 tbox Exp $
+.\" $Id: dnssec-signzone.8,v 1.47.44.8 2009/11/07 01:56:11 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,13 +33,15 @@
dnssec\-signzone \- DNSSEC zone signing tool
.SH "SYNOPSIS"
.HP 16
-\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
+\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
.SH "DESCRIPTION"
.PP
\fBdnssec\-signzone\fR
-signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a
-\fIkeyset\fR
-file for each child zone.
+signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. It also generates a
+\fIkeyset\-\fR
+file containing the key\-signing keys for the zone, and if signing a zone which contains delegations, it can optionally generate DS records for the child zones from their
+\fIkeyset\-\fR
+files.
.SH "OPTIONS"
.PP
\-a
@@ -73,7 +75,9 @@ as the directory
.PP
\-g
.RS 4
-Generate DS records for child zones from keyset files. Existing DS records will be removed.
+If the zone contains any delegations, and there are
+\fIkeyset\-\fR
+files for any of the child zones, then DS records for the child zones will be generated from the keys in those files. Existing DS records will be removed.
.RE
.PP
\-s \fIstart\-time\fR
@@ -186,6 +190,13 @@ The format of the output file containing the signed zone. Possible formats are
Use pseudo\-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited.
.RE
.PP
+\-P
+.RS 4
+Disable post sign verification tests.
+.sp
+The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests.
+.RE
+.PP
\-r \fIrandomdev\fR
.RS 4
Specifies the source of randomness. If the operating system does not provide a
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.c b/contrib/bind9/bin/dnssec/dnssec-signzone.c
index 2ef2e10..eec6110 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.c
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.209.12.8 2009/06/08 22:23:06 each Exp $ */
+/* $Id: dnssec-signzone.c,v 1.209.12.18 2009/11/03 23:47:45 tbox Exp $ */
/*! \file */
@@ -51,6 +51,7 @@
#include <isc/os.h>
#include <isc/print.h>
#include <isc/random.h>
+#include <isc/rwlock.h>
#include <isc/serial.h>
#include <isc/stdio.h>
#include <isc/stdlib.h>
@@ -106,6 +107,8 @@ struct signer_key_struct {
isc_boolean_t issigningkey;
isc_boolean_t isdsk;
isc_boolean_t isksk;
+ isc_boolean_t wasused;
+ isc_boolean_t commandline;
unsigned int position;
ISC_LINK(signer_key_t) link;
};
@@ -127,6 +130,7 @@ struct signer_event {
static ISC_LIST(signer_key_t) keylist;
static unsigned int keycount = 0;
+isc_rwlock_t keylist_lock;
static isc_stdtime_t starttime = 0, endtime = 0, now;
static int cycle = -1;
static int jitter = 0;
@@ -164,6 +168,7 @@ static dns_master_style_t *dsstyle = NULL;
static unsigned int serialformat = SOA_SERIAL_KEEP;
static unsigned int hash_length = 0;
static isc_boolean_t unknownalg = ISC_FALSE;
+static isc_boolean_t disable_zone_check = ISC_FALSE;
#define INCSTAT(counter) \
if (printstats) { \
@@ -175,8 +180,9 @@ static isc_boolean_t unknownalg = ISC_FALSE;
static void
sign(isc_task_t *task, isc_event_t *event);
-static isc_boolean_t
-nsec3only(dns_dbnode_t *node);
+#define check_dns_dbiterator_current(result) \
+ check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \
+ "dns_dbiterator_current()")
static void
dumpnode(dns_name_t *name, dns_dbnode_t *node) {
@@ -206,21 +212,37 @@ newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) {
key->isksk = ISC_FALSE;
key->isdsk = ISC_TRUE;
}
+ key->wasused = ISC_FALSE;
+ key->commandline = ISC_FALSE;
key->position = keycount++;
ISC_LINK_INIT(key, link);
return (key);
}
+/*%
+ * Sign the given RRset with given key, and add the signature record to the
+ * given tuple.
+ */
+
static void
-signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata,
- dst_key_t *key, isc_buffer_t *b)
+signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
+ dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
{
isc_result_t result;
isc_stdtime_t jendtime;
+ char keystr[KEY_FORMATSIZE];
+ dns_rdata_t trdata = DNS_RDATA_INIT;
+ unsigned char array[BUFSIZE];
+ isc_buffer_t b;
+ dns_difftuple_t *tuple;
+
+ key_format(key, keystr, sizeof(keystr));
+ vbprintf(1, "\t%s %s\n", logmsg, keystr);
jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
+ isc_buffer_init(&b, array, sizeof(array));
result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime,
- mctx, b, rdata);
+ mctx, &b, &trdata);
isc_entropy_stopcallbacksources(ectx);
if (result != ISC_R_SUCCESS) {
char keystr[KEY_FORMATSIZE];
@@ -232,7 +254,7 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata,
if (tryverify) {
result = dns_dnssec_verify(name, rdataset, key,
- ISC_TRUE, mctx, rdata);
+ ISC_TRUE, mctx, &trdata);
if (result == ISC_R_SUCCESS) {
vbprintf(3, "\tsignature verified\n");
INCSTAT(nverified);
@@ -241,6 +263,12 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata,
INCSTAT(nverifyfailed);
}
}
+
+ tuple = NULL;
+ result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, &trdata,
+ &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(add, &tuple);
}
static inline isc_boolean_t
@@ -255,13 +283,11 @@ iszonekey(signer_key_t *key) {
}
/*%
- * Finds the key that generated a RRSIG, if possible. First look at the keys
- * that we've loaded already, and then see if there's a key on disk.
+ * Find the key if it is in our list. If it is, return it, otherwise null.
+ * No locking is performed here, this must be done by the caller.
*/
static signer_key_t *
-keythatsigned(dns_rdata_rrsig_t *rrsig) {
- isc_result_t result;
- dst_key_t *pubkey = NULL, *privkey = NULL;
+keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
signer_key_t *key;
key = ISC_LIST_HEAD(keylist);
@@ -269,15 +295,50 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
if (rrsig->keyid == dst_key_id(key->key) &&
rrsig->algorithm == dst_key_alg(key->key) &&
dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
- return key;
+ return (key);
key = ISC_LIST_NEXT(key, link);
}
+ return (NULL);
+}
+
+/*%
+ * Finds the key that generated a RRSIG, if possible. First look at the keys
+ * that we've loaded already, and then see if there's a key on disk.
+ */
+static signer_key_t *
+keythatsigned(dns_rdata_rrsig_t *rrsig) {
+ isc_result_t result;
+ dst_key_t *pubkey = NULL, *privkey = NULL;
+ signer_key_t *key;
+
+ isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
+ key = keythatsigned_unlocked(rrsig);
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read);
+ if (key != NULL)
+ return (key);
+
+ /*
+ * We did not find the key in our list. Get a write lock now, since
+ * we may be modifying the bits. We could do the tryupgrade() dance,
+ * but instead just get a write lock and check once again to see if
+ * it is on our list. It's possible someone else may have added it
+ * after all.
+ */
+ isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
+
+ key = keythatsigned_unlocked(rrsig);
+ if (key != NULL) {
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
+ return (key);
+ }
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm, DST_TYPE_PUBLIC,
NULL, mctx, &pubkey);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (NULL);
+ }
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm,
@@ -289,6 +350,8 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
} else
key = newkeystruct(pubkey, ISC_FALSE);
ISC_LIST_APPEND(keylist, key, link);
+
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (key);
}
@@ -438,6 +501,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
keep = ISC_TRUE;
wassignedby[key->position] = ISC_TRUE;
nowsignedby[key->position] = ISC_TRUE;
+ key->wasused = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
@@ -453,6 +517,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
keep = ISC_TRUE;
wassignedby[key->position] = ISC_TRUE;
nowsignedby[key->position] = ISC_TRUE;
+ key->wasused = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
@@ -499,24 +564,12 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
}
if (resign) {
- isc_buffer_t b;
- dns_rdata_t trdata = DNS_RDATA_INIT;
- unsigned char array[BUFSIZE];
- char keystr[KEY_FORMATSIZE];
-
INSIST(!keep);
- key_format(key->key, keystr, sizeof(keystr));
- vbprintf(1, "\tresigning with dnskey %s\n", keystr);
- isc_buffer_init(&b, array, sizeof(array));
- signwithkey(name, set, &trdata, key->key, &b);
+ signwithkey(name, set, key->key, ttl, add,
+ "resigning with dnskey");
nowsignedby[key->position] = ISC_TRUE;
- tuple = NULL;
- result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
- name, ttl, &trdata,
- &tuple);
- check_result(result, "dns_difftuple_create");
- dns_diff_append(add, &tuple);
+ key->wasused = ISC_TRUE;
}
dns_rdata_reset(&sigrdata);
@@ -534,11 +587,6 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- isc_buffer_t b;
- dns_rdata_t trdata;
- unsigned char array[BUFSIZE];
- char keystr[KEY_FORMATSIZE];
-
if (nowsignedby[key->position])
continue;
@@ -550,16 +598,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
dns_name_equal(name, gorigin))))
continue;
- key_format(key->key, keystr, sizeof(keystr));
- vbprintf(1, "\tsigning with dnskey %s\n", keystr);
- dns_rdata_init(&trdata);
- isc_buffer_init(&b, array, sizeof(array));
- signwithkey(name, set, &trdata, key->key, &b);
- tuple = NULL;
- result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
- ttl, &trdata, &tuple);
- check_result(result, "dns_difftuple_create");
- dns_diff_append(add, &tuple);
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ key->wasused = ISC_TRUE;
}
isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t));
@@ -787,8 +828,8 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
return (DNS_R_BADDB);
}
dns_rdataset_init(&keyset);
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
- &keyset, NULL);
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0,
+ 0, &keyset, NULL);
if (result != ISC_R_SUCCESS) {
dns_db_detachnode(db, &node);
dns_db_detach(&db);
@@ -1021,6 +1062,20 @@ active_node(dns_dbnode_t *node) {
type = rdataset.type;
covers = rdataset.covers;
dns_rdataset_disassociate(&rdataset);
+ /*
+ * Delete the NSEC chain if we are signing with
+ * NSEC3.
+ */
+ if (nsec_datatype == dns_rdatatype_nsec3 &&
+ (type == dns_rdatatype_nsec ||
+ covers == dns_rdatatype_nsec)) {
+ result = dns_db_deleterdataset(gdb, node,
+ gversion, type,
+ covers);
+ check_result(result,
+ "dns_db_deleterdataset(nsec/rrsig)");
+ continue;
+ }
if (type != dns_rdatatype_rrsig)
continue;
found = ISC_FALSE;
@@ -1050,32 +1105,6 @@ active_node(dns_dbnode_t *node) {
fatal("rdataset iteration failed: %s",
isc_result_totext(result));
dns_rdatasetiter_destroy(&rdsiter2);
-
-#if 0
- /*
- * Delete all NSEC records and RRSIG(NSEC) if we are in
- * NSEC3 mode and vica versa.
- */
- for (result = dns_rdatasetiter_first(rdsiter2);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(rdsiter2)) {
- dns_rdatasetiter_current(rdsiter, &rdataset);
- type = rdataset.type;
- covers = rdataset.covers;
- if (type == dns_rdatatype_rrsig)
- type = covers;
- dns_rdataset_disassociate(&rdataset);
- if (type == nsec_datatype ||
- (type != dns_rdatatype_nsec &&
- type != dns_rdatatype_nsec3))
- continue;
- if (covers != 0)
- type = dns_rdatatype_rrsig;
- result = dns_db_deleterdataset(gdb, node, gversion,
- type, covers);
- check_result(result, "dns_db_deleterdataset()");
- }
-#endif
}
dns_rdatasetiter_destroy(&rdsiter);
@@ -1198,7 +1227,7 @@ cleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
dns_rdataset_t set;
isc_result_t result, dresult;
- if (outputformat != dns_masterformat_text)
+ if (outputformat != dns_masterformat_text || !disable_zone_check)
return;
dns_rdataset_init(&set);
@@ -1248,6 +1277,424 @@ postsign(void) {
dns_dbiterator_destroy(&gdbiter);
}
+static isc_boolean_t
+goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
+ dns_rdataset_t *rdataset)
+{
+ dns_rdata_dnskey_t key;
+ dns_rdata_rrsig_t sig;
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+
+ dns_rdata_tostruct(sigrdata, &sig, NULL);
+
+ for (result = dns_rdataset_first(keyrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(keyrdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_current(keyrdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &key, NULL);
+ result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ if (sig.algorithm != key.algorithm ||
+ sig.keyid != dst_key_id(dstkey) ||
+ !dns_name_equal(&sig.signer, gorigin)) {
+ dst_key_free(&dstkey);
+ continue;
+ }
+ result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
+ mctx, sigrdata);
+ dst_key_free(&dstkey);
+ if (result == ISC_R_SUCCESS)
+ return(ISC_TRUE);
+ }
+ return (ISC_FALSE);
+}
+
+static void
+verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
+ dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
+ unsigned char *bad_algorithms)
+{
+ unsigned char set_algorithms[256];
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char algbuf[80];
+ char typebuf[80];
+ dns_rdataset_t sigrdataset;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ isc_result_t result;
+ int i;
+
+ dns_rdataset_init(&sigrdataset);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &sigrdataset);
+ if (sigrdataset.type == dns_rdatatype_rrsig &&
+ sigrdataset.covers == rdataset->type)
+ break;
+ dns_rdataset_disassociate(&sigrdataset);
+ }
+ if (result != ISC_R_SUCCESS) {
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ type_format(rdataset->type, typebuf, sizeof(typebuf));
+ fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf);
+ for (i = 0; i < 256; i++)
+ if (ksk_algorithms[i] != 0)
+ bad_algorithms[i] = 1;
+ return;
+ }
+
+ memset(set_algorithms, 0, sizeof(set_algorithms));
+ for (result = dns_rdataset_first(&sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&sigrdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_rrsig_t sig;
+
+ dns_rdataset_current(&sigrdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &sig, NULL);
+ if ((set_algorithms[sig.algorithm] != 0) ||
+ (ksk_algorithms[sig.algorithm] == 0))
+ continue;
+ if (goodsig(&rdata, name, keyrdataset, rdataset))
+ set_algorithms[sig.algorithm] = 1;
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) {
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ type_format(rdataset->type, typebuf, sizeof(typebuf));
+ for (i = 0; i < 256; i++)
+ if ((ksk_algorithms[i] != 0) &&
+ (set_algorithms[i] == 0)) {
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s signature for "
+ "%s %s\n", algbuf, namebuf, typebuf);
+ bad_algorithms[i] = 1;
+ }
+ }
+ dns_rdataset_disassociate(&sigrdataset);
+}
+
+static void
+verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
+ dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
+ unsigned char *bad_algorithms)
+{
+ dns_rdataset_t rdataset;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ isc_result_t result;
+
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ result = dns_rdatasetiter_first(rdsiter);
+ dns_rdataset_init(&rdataset);
+ while (result == ISC_R_SUCCESS) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ if (rdataset.type != dns_rdatatype_rrsig &&
+ rdataset.type != dns_rdatatype_dnskey &&
+ (!delegation || rdataset.type == dns_rdatatype_ds ||
+ rdataset.type == dns_rdatatype_nsec)) {
+ verifyset(&rdataset, name, node, keyrdataset,
+ ksk_algorithms, bad_algorithms);
+ }
+ dns_rdataset_disassociate(&rdataset);
+ result = dns_rdatasetiter_next(rdsiter);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("rdataset iteration failed: %s",
+ isc_result_totext(result));
+ dns_rdatasetiter_destroy(&rdsiter);
+}
+
+/*%
+ * Verify that certain things are sane:
+ *
+ * The apex has a DNSKEY record with at least one KSK and at least
+ * one ZSK.
+ *
+ * The DNSKEY record was signed with at least one of the KSKs in this
+ * set.
+ *
+ * The rest of the zone was signed with at least one of the ZSKs
+ * present in the DNSKEY RRSET.
+ */
+static void
+verifyzone(void) {
+ char algbuf[80];
+ dns_dbiterator_t *dbiter = NULL;
+ dns_dbnode_t *node = NULL, *nextnode = NULL;
+ dns_fixedname_t fname, fnextname, fzonecut;
+ dns_name_t *name, *nextname, *zonecut;
+ dns_rdata_dnskey_t dnskey;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t rdataset;
+ dns_rdataset_t sigrdataset;
+ int i;
+ isc_boolean_t done = ISC_FALSE;
+ isc_boolean_t first = ISC_TRUE;
+ isc_boolean_t goodksk = ISC_FALSE;
+ isc_boolean_t goodzsk = ISC_FALSE;
+ isc_result_t result;
+ unsigned char revoked[256];
+ unsigned char standby[256];
+ unsigned char ksk_algorithms[256];
+ unsigned char zsk_algorithms[256];
+ unsigned char bad_algorithms[256];
+#ifdef ALLOW_KSKLESS_ZONES
+ isc_boolean_t allzsksigned = ISC_TRUE;
+ unsigned char self_algorithms[256];
+#endif
+
+ if (disable_zone_check)
+ return;
+
+ result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to find the zone's origin: %s",
+ isc_result_totext(result));
+
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&sigrdataset);
+ result = dns_db_findrdataset(gdb, node, gversion,
+ dns_rdatatype_dnskey,
+ 0, 0, &rdataset, &sigrdataset);
+ dns_db_detachnode(gdb, &node);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot find DNSKEY rrset\n");
+
+ if (!dns_rdataset_isassociated(&sigrdataset))
+ fatal("cannot find DNSKEY RRSIGs\n");
+
+ memset(revoked, 0, sizeof(revoked));
+ memset(standby, 0, sizeof(revoked));
+ memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
+ memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
+ memset(bad_algorithms, 0, sizeof(bad_algorithms));
+#ifdef ALLOW_KSKLESS_ZONES
+ memset(self_algorithms, 0, sizeof(self_algorithms));
+#endif
+
+ /*
+ * Check that the DNSKEY RR has at least one self signing KSK and
+ * one ZSK per algorithm in it.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
+ check_result(result, "dns_rdata_tostruct");
+
+ if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
+ ;
+ else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
+ !dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
+ &sigrdataset, ISC_FALSE,
+ mctx)) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char buffer[1024];
+ isc_buffer_t buf;
+
+ dns_name_format(gorigin, namebuf,
+ sizeof(namebuf));
+ isc_buffer_init(&buf, buffer, sizeof(buffer));
+ result = dns_rdata_totext(&rdata, NULL, &buf);
+ check_result(result, "dns_rdata_totext");
+ fatal("revoked KSK is not self signed:\n"
+ "%s DNSKEY %.*s", namebuf,
+ (int)isc_buffer_usedlength(&buf), buffer);
+ }
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
+ revoked[dnskey.algorithm] != 255)
+ revoked[dnskey.algorithm]++;
+ } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
+ if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
+ &sigrdataset, ISC_FALSE, mctx)) {
+ if (ksk_algorithms[dnskey.algorithm] != 255)
+ ksk_algorithms[dnskey.algorithm]++;
+ goodksk = ISC_TRUE;
+ } else {
+ if (standby[dnskey.algorithm] != 255)
+ standby[dnskey.algorithm]++;
+ }
+ } else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
+ &sigrdataset, ISC_FALSE,
+ mctx)) {
+#ifdef ALLOW_KSKLESS_ZONES
+ if (self_algorithms[dnskey.algorithm] != 255)
+ self_algorithms[dnskey.algorithm]++;
+#endif
+ if (zsk_algorithms[dnskey.algorithm] != 255)
+ zsk_algorithms[dnskey.algorithm]++;
+ goodzsk = ISC_TRUE;
+ } else {
+ if (zsk_algorithms[dnskey.algorithm] != 255)
+ zsk_algorithms[dnskey.algorithm]++;
+#ifdef ALLOW_KSKLESS_ZONES
+ allzsksigned = ISC_FALSE;
+#endif
+ }
+ dns_rdata_freestruct(&dnskey);
+ dns_rdata_reset(&rdata);
+ }
+ dns_rdataset_disassociate(&sigrdataset);
+
+ if (!goodksk) {
+#ifdef ALLOW_KSKLESS_ZONES
+ if (!goodzsk)
+ fatal("no self signing keys found");
+ fprintf(stderr, "No self signing KSK found. Using self signed "
+ "ZSK's for active algorithm list.\n");
+ memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
+ if (!allzsksigned)
+ fprintf(stderr, "warning: not all ZSK's are self "
+ "signed.\n");
+#else
+ fatal("no self signed KSK's found");
+#endif
+ }
+
+ fprintf(stderr, "Verifying the zone using the following algorithms:");
+ for (i = 0; i < 256; i++) {
+ if (ksk_algorithms[i] != 0) {
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, " %s", algbuf);
+ }
+ }
+ fprintf(stderr, ".\n");
+
+ for (i = 0; i < 256; i++) {
+ /*
+ * The counts should both be zero or both be non-zero.
+ * Mark the algorithm as bad if this is not met.
+ */
+ if ((ksk_algorithms[i] != 0) == (zsk_algorithms[i] != 0))
+ continue;
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s for algorithm %s\n",
+ (ksk_algorithms[i] != 0) ? "ZSK" : "self signing KSK",
+ algbuf);
+ bad_algorithms[i] = 1;
+ }
+
+ /*
+ * Check that all the other records were signed by keys that are
+ * present in the DNSKEY RRSET.
+ */
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_fixedname_init(&fnextname);
+ nextname = dns_fixedname_name(&fnextname);
+ dns_fixedname_init(&fzonecut);
+ zonecut = NULL;
+
+ result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ result = dns_dbiterator_first(dbiter);
+ check_result(result, "dns_dbiterator_first()");
+
+ while (!done) {
+ isc_boolean_t isdelegation = ISC_FALSE;
+
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ if (delegation(name, node, NULL)) {
+ zonecut = dns_fixedname_name(&fzonecut);
+ dns_name_copy(name, zonecut, NULL);
+ isdelegation = ISC_TRUE;
+ }
+ verifynode(name, node, isdelegation, &rdataset,
+ ksk_algorithms, bad_algorithms);
+ result = dns_dbiterator_next(dbiter);
+ nextnode = NULL;
+ while (result == ISC_R_SUCCESS) {
+ result = dns_dbiterator_current(dbiter, &nextnode,
+ nextname);
+ check_dns_dbiterator_current(result);
+ if (!dns_name_issubdomain(nextname, gorigin) ||
+ (zonecut != NULL &&
+ dns_name_issubdomain(nextname, zonecut)))
+ {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ dns_db_detachnode(gdb, &nextnode);
+ break;
+ }
+ if (result == ISC_R_NOMORE) {
+ done = ISC_TRUE;
+ } else if (result != ISC_R_SUCCESS)
+ fatal("iterating through the database failed: %s",
+ isc_result_totext(result));
+ dns_db_detachnode(gdb, &node);
+ }
+
+ dns_dbiterator_destroy(&dbiter);
+
+ result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter) ) {
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ verifynode(name, node, ISC_FALSE, &rdataset,
+ ksk_algorithms, bad_algorithms);
+ dns_db_detachnode(gdb, &node);
+ }
+ dns_dbiterator_destroy(&dbiter);
+
+ dns_rdataset_disassociate(&rdataset);
+
+ /*
+ * If we made it this far, we have what we consider a properly signed
+ * zone. Set the good flag.
+ */
+ for (i = 0; i < 256; i++) {
+ if (bad_algorithms[i] != 0) {
+ if (first)
+ fprintf(stderr, "The zone is not fully signed "
+ "for the following algorithms:");
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, " %s", algbuf);
+ first = ISC_FALSE;
+ }
+ }
+ if (!first) {
+ fprintf(stderr, ".\n");
+ fatal("DNSSEC completeness test failed.");
+ }
+
+ if (goodksk) {
+ /*
+ * Print the success summary.
+ */
+ fprintf(stderr, "Zone signing complete:\n");
+ for (i = 0; i < 256; i++) {
+ if ((zsk_algorithms[i] != 0) ||
+ (ksk_algorithms[i] != 0) ||
+ (revoked[i] != 0) || (standby[i] != 0)) {
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Algorithm: %s: ZSKs: %u, "
+ "KSKs: %u active, %u revoked, %u "
+ "stand-by\n", algbuf,
+ zsk_algorithms[i], ksk_algorithms[i],
+ revoked[i], standby[i]);
+ }
+ }
+ }
+}
+
/*%
* Sign the apex of the zone.
* Note the origin may not be the first node if there are out of zone
@@ -1265,7 +1712,7 @@ signapex(void) {
result = dns_dbiterator_seek(gdbiter, gorigin);
check_result(result, "dns_dbiterator_seek()");
result = dns_dbiterator_current(gdbiter, &node, name);
- check_result(result, "dns_dbiterator_current()");
+ check_dns_dbiterator_current(result);
signname(node, name);
dumpnode(name, node);
cleannode(gdb, gversion, node);
@@ -1317,9 +1764,7 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
found = ISC_FALSE;
while (!found) {
result = dns_dbiterator_current(gdbiter, &node, name);
- if (result != ISC_R_SUCCESS)
- fatal("failure iterating database: %s",
- isc_result_totext(result));
+ check_dns_dbiterator_current(result);
/*
* The origin was handled by signapex().
*/
@@ -1487,7 +1932,7 @@ add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
}
/*%
- * Generate NSEC records for the zone.
+ * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records.
*/
static void
nsecify(void) {
@@ -1495,10 +1940,14 @@ nsecify(void) {
dns_dbnode_t *node = NULL, *nextnode = NULL;
dns_fixedname_t fname, fnextname, fzonecut;
dns_name_t *name, *nextname, *zonecut;
+ dns_rdataset_t rdataset;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ dns_rdatatype_t type, covers;
isc_boolean_t done = ISC_FALSE;
isc_result_t result;
isc_uint32_t nsttl = 0;
+ dns_rdataset_init(&rdataset);
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
dns_fixedname_init(&fnextname);
@@ -1506,14 +1955,70 @@ nsecify(void) {
dns_fixedname_init(&fzonecut);
zonecut = NULL;
+ /*
+ * Remove any NSEC3 chains.
+ */
+ result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter)) {
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ type = rdataset.type;
+ covers = rdataset.covers;
+ dns_rdataset_disassociate(&rdataset);
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ type, covers);
+ check_result(result,
+ "dns_db_deleterdataset(nsec3param/rrsig)");
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ dns_db_detachnode(gdb, &node);
+ }
+ dns_dbiterator_destroy(&dbiter);
+
result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
check_result(result, "dns_db_createiterator()");
result = dns_dbiterator_first(dbiter);
check_result(result, "dns_dbiterator_first()");
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ /*
+ * Delete any NSEC3PARAM records at the apex.
+ */
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ type = rdataset.type;
+ covers = rdataset.covers;
+ dns_rdataset_disassociate(&rdataset);
+ if (type == dns_rdatatype_nsec3param ||
+ covers == dns_rdatatype_nsec3param) {
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ type, covers);
+ check_result(result,
+ "dns_db_deleterdataset(nsec3param/rrsig)");
+ continue;
+ }
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ dns_db_detachnode(gdb, &node);
+
while (!done) {
- dns_dbiterator_current(dbiter, &node, name);
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
if (delegation(name, node, &nsttl)) {
zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(name, zonecut, NULL);
@@ -1526,8 +2031,7 @@ nsecify(void) {
isc_boolean_t active = ISC_FALSE;
result = dns_dbiterator_current(dbiter, &nextnode,
nextname);
- if (result != ISC_R_SUCCESS)
- break;
+ check_dns_dbiterator_current(result);
active = active_node(nextnode);
if (!active) {
dns_db_detachnode(gdb, &nextnode);
@@ -1560,37 +2064,6 @@ nsecify(void) {
dns_dbiterator_destroy(&dbiter);
}
-/*%
- * Does this node only contain NSEC3 records or RRSIG records or is empty.
- */
-static isc_boolean_t
-nsec3only(dns_dbnode_t *node) {
- dns_rdatasetiter_t *rdsiter = NULL;
- isc_result_t result;
- dns_rdataset_t rdataset;
- isc_boolean_t answer = ISC_TRUE;
-
- dns_rdataset_init(&rdataset);
- result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
- check_result(result, "dns_db_allrdatasets()");
- result = dns_rdatasetiter_first(rdsiter);
- while (result == ISC_R_SUCCESS) {
- dns_rdatasetiter_current(rdsiter, &rdataset);
- if (rdataset.type != dns_rdatatype_nsec3 &&
- rdataset.type != dns_rdatatype_rrsig) {
- answer = ISC_FALSE;
- result = ISC_R_NOMORE;
- } else
- result = dns_rdatasetiter_next(rdsiter);
- dns_rdataset_disassociate(&rdataset);
- }
- if (result != ISC_R_NOMORE)
- fatal("rdataset iteration failed: %s",
- isc_result_totext(result));
- dns_rdatasetiter_destroy(&rdsiter);
- return (answer);
-}
-
static void
addnsec3param(const unsigned char *salt, size_t salt_length,
unsigned int iterations)
@@ -1631,6 +2104,16 @@ addnsec3param(const unsigned char *salt, size_t salt_length,
result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node);
check_result(result, "dns_db_find(gorigin)");
+
+ /*
+ * Delete any current NSEC3PARAM records.
+ */
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ dns_rdatatype_nsec3param, 0);
+ if (result == DNS_R_UNCHANGED)
+ result = ISC_R_SUCCESS;
+ check_result(result, "dddnsec3param: dns_db_deleterdataset()");
+
result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset,
DNS_DBADD_MERGE, NULL);
if (result == DNS_R_UNCHANGED)
@@ -1719,6 +2202,7 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
isc_buffer_t target;
isc_result_t result;
unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
+ isc_boolean_t exists;
/*
* Get the first label.
@@ -1740,8 +2224,7 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
hash[isc_buffer_usedlength(&target)] = 0;
- if (hashlist_exists(hashlist, hash))
- return;
+ exists = hashlist_exists(hashlist, hash);
/*
* Verify that the NSEC3 parameters match the current ones
@@ -1756,20 +2239,21 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
return;
/*
- * Delete any matching NSEC3 records which have parameters that
- * match the NSEC3 chain we are building.
+ * Delete any NSEC3 records which are not part of the current
+ * NSEC3 chain.
*/
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
dns_rdata_init(&rdata);
dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &nsec3, NULL);
- if (nsec3.hash == hashalg &&
+ result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ check_result(result, "dns_rdata_tostruct");
+ if (exists && nsec3.hash == hashalg &&
nsec3.iterations == iterations &&
nsec3.salt_length == salt_length &&
!memcmp(nsec3.salt, salt, salt_length))
- break;
+ continue;
rdatalist.rdclass = rdata.rdclass;
rdatalist.type = rdata.type;
rdatalist.covers = 0;
@@ -1783,7 +2267,7 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
result = dns_db_subtractrdataset(gdb, node, gversion,
&delrdataset, 0, NULL);
dns_rdataset_disassociate(&delrdataset);
- if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
+ if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET)
check_result(result, "dns_db_subtractrdataset(NSEC3)");
delete_rrsigs = ISC_TRUE;
}
@@ -1814,13 +2298,17 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
dns_dbnode_t *node = NULL, *nextnode = NULL;
dns_fixedname_t fname, fnextname, fzonecut;
dns_name_t *name, *nextname, *zonecut;
+ dns_rdataset_t rdataset;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ dns_rdatatype_t type, covers;
+ int order;
+ isc_boolean_t active;
isc_boolean_t done = ISC_FALSE;
isc_result_t result;
- isc_boolean_t active;
isc_uint32_t nsttl = 0;
unsigned int count, nlabels;
- int order;
+ dns_rdataset_init(&rdataset);
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
dns_fixedname_init(&fnextname);
@@ -1837,15 +2325,41 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
result = dns_dbiterator_first(dbiter);
check_result(result, "dns_dbiterator_first()");
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ /*
+ * Delete any NSEC records at the apex.
+ */
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ type = rdataset.type;
+ covers = rdataset.covers;
+ dns_rdataset_disassociate(&rdataset);
+ if (type == dns_rdatatype_nsec ||
+ covers == dns_rdatatype_nsec) {
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ type, covers);
+ check_result(result,
+ "dns_db_deleterdataset(nsec3param/rrsig)");
+ continue;
+ }
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ dns_db_detachnode(gdb, &node);
+
while (!done) {
- dns_dbiterator_current(dbiter, &node, name);
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
result = dns_dbiterator_next(dbiter);
nextnode = NULL;
while (result == ISC_R_SUCCESS) {
result = dns_dbiterator_current(dbiter, &nextnode,
nextname);
- if (result != ISC_R_SUCCESS)
- break;
+ check_dns_dbiterator_current(result);
active = active_node(nextnode);
if (!active) {
dns_db_detachnode(gdb, &nextnode);
@@ -1927,6 +2441,26 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
addnsec3param(salt, salt_length, iterations);
+ /*
+ * Clean out NSEC3 records which don't match this chain.
+ */
+ result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter)) {
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ nsec3clean(name, node, hashalg, iterations, salt, salt_length,
+ hashlist);
+ dns_db_detachnode(gdb, &node);
+ }
+ dns_dbiterator_destroy(&dbiter);
+
+ /*
+ * Generate / complete the new chain.
+ */
result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
check_result(result, "dns_db_createiterator()");
@@ -1934,25 +2468,16 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
check_result(result, "dns_dbiterator_first()");
while (!done) {
- dns_dbiterator_current(dbiter, &node, name);
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
result = dns_dbiterator_next(dbiter);
nextnode = NULL;
while (result == ISC_R_SUCCESS) {
result = dns_dbiterator_current(dbiter, &nextnode,
nextname);
- if (result != ISC_R_SUCCESS)
- break;
- /*
- * Cleanout NSEC3 RRsets which don't exist in the
- * hash table.
- */
- nsec3clean(nextname, nextnode, hashalg, iterations,
- salt, salt_length, hashlist);
- /*
- * Skip NSEC3 only nodes when looking for the next
- * node in the zone. Also skips now empty nodes.
- */
- if (nsec3only(nextnode)) {
+ check_dns_dbiterator_current(result);
+ active = active_node(nextnode);
+ if (!active) {
dns_db_detachnode(gdb, &nextnode);
result = dns_dbiterator_next(dbiter);
continue;
@@ -2098,7 +2623,8 @@ loadzonepubkeys(dns_db_t *db) {
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, currentversion,
- dns_rdatatype_dnskey, 0, 0, &rdataset, NULL);
+ dns_rdatatype_dnskey, 0, 0, &rdataset,
+ NULL);
if (result != ISC_R_SUCCESS)
fatal("failed to find keys at the zone apex: %s",
isc_result_totext(result));
@@ -2134,7 +2660,7 @@ warnifallksk(dns_db_t *db) {
dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
- dns_rdata_key_t key;
+ dns_rdata_dnskey_t dnskey;
isc_boolean_t have_non_ksk = ISC_FALSE;
dns_db_currentversion(db, &currentversion);
@@ -2146,7 +2672,8 @@ warnifallksk(dns_db_t *db) {
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, currentversion,
- dns_rdatatype_dnskey, 0, 0, &rdataset, NULL);
+ dns_rdatatype_dnskey, 0, 0, &rdataset,
+ NULL);
if (result != ISC_R_SUCCESS)
fatal("failed to find keys at the zone apex: %s",
isc_result_totext(result));
@@ -2155,21 +2682,27 @@ warnifallksk(dns_db_t *db) {
while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &key, NULL);
+ result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
check_result(result, "dns_rdata_tostruct");
- if ((key.flags & DNS_KEYFLAG_KSK) == 0) {
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
have_non_ksk = ISC_TRUE;
result = ISC_R_NOMORE;
} else
result = dns_rdataset_next(&rdataset);
+ dns_rdata_freestruct(&dnskey);
}
dns_rdataset_disassociate(&rdataset);
dns_db_detachnode(db, &node);
dns_db_closeversion(db, &currentversion, ISC_FALSE);
- if (!have_non_ksk && !ignoreksk)
- fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.\n",
- program);
+ if (!have_non_ksk && !ignoreksk) {
+ if (disable_zone_check)
+ fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
+ "Supply non-KSK dnskey or use '-z'.\n",
+ program);
+ else
+ fatal("No non-KSK dnskey found. "
+ "Supply non-KSK dnskey or use '-z'.");
+ }
}
static void
@@ -2343,7 +2876,8 @@ usage(void) {
fprintf(stderr, "\t-g:\t");
fprintf(stderr, "generate DS records from keyset files\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
- fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
+ fprintf(stderr, "\t\tRRSIG start time - absolute|offset "
+ "(now - 1 hour)\n");
fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
"(now + 30 days)\n");
@@ -2351,7 +2885,8 @@ usage(void) {
fprintf(stderr, "\t\tcycle interval - resign "
"if < interval from end ( (end-start)/4 )\n");
fprintf(stderr, "\t-j jitter:\n");
- fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n");
+ fprintf(stderr, "\t\trandomize signature end time up to jitter "
+ "seconds\n");
fprintf(stderr, "\t-v debuglevel (0)\n");
fprintf(stderr, "\t-o origin:\n");
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
@@ -2370,6 +2905,8 @@ usage(void) {
fprintf(stderr, "verify generated signatures\n");
fprintf(stderr, "\t-p:\t");
fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
+ fprintf(stderr, "\t-P:\t");
+ fprintf(stderr, "disable post-sign verification\n");
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
@@ -2448,7 +2985,7 @@ main(int argc, char *argv[]) {
unsigned char saltbuf[255];
hashlist_t hashlist;
-#define CMDLINE_FLAGS "3:aAc:d:e:f:ghH:i:I:j:k:l:m:n:N:o:O:pr:s:StUv:z"
+#define CMDLINE_FLAGS "3:aAc:d:e:f:FghH:i:I:j:k:l:m:n:N:o:O:pPr:s:StUv:z"
/*
* Process memory debugging argument first.
@@ -2535,19 +3072,19 @@ main(int argc, char *argv[]) {
generateds = ISC_TRUE;
break;
- case '?':
- if (isc_commandline_option != '?')
- fprintf(stderr, "%s: invalid argument -%c\n",
- program, isc_commandline_option);
+ case 'H':
+ iterations = strtoul(isc_commandline_argument,
+ &endp, 0);
+ if (*endp != '\0')
+ fatal("iterations must be numeric");
+ if (iterations > 0xffffU)
+ fatal("iterations too big");
+ break;
+
case 'h':
usage();
break;
- default:
- fprintf(stderr, "%s: unhandled option -%c\n",
- program, isc_commandline_option);
- exit(1);
-
case 'i':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
@@ -2567,8 +3104,13 @@ main(int argc, char *argv[]) {
fatal("jitter must be numeric and positive");
break;
+ case 'k':
+ if (ndskeys == MAXDSKEYS)
+ fatal("too many key-signing keys specified");
+ dskeyfile[ndskeys++] = isc_commandline_argument;
+ break;
+
case 'l':
- dns_fixedname_init(&dlv_fixed);
len = strlen(isc_commandline_argument);
isc_buffer_init(&b, isc_commandline_argument, len);
isc_buffer_add(&b, len);
@@ -2580,12 +3122,6 @@ main(int argc, char *argv[]) {
check_result(result, "dns_name_fromtext(dlv)");
break;
- case 'k':
- if (ndskeys == MAXDSKEYS)
- fatal("too many key-signing keys specified");
- dskeyfile[ndskeys++] = isc_commandline_argument;
- break;
-
case 'm':
break;
@@ -2600,15 +3136,6 @@ main(int argc, char *argv[]) {
serialformatstr = isc_commandline_argument;
break;
- case 'H':
- iterations = strtoul(isc_commandline_argument,
- &endp, 0);
- if (*endp != '\0')
- fatal("iterations must be numeric");
- if (iterations > 0xffffU)
- fatal("iterations too big");
- break;
-
case 'o':
origin = isc_commandline_argument;
break;
@@ -2621,6 +3148,10 @@ main(int argc, char *argv[]) {
pseudorandom = ISC_TRUE;
break;
+ case 'P':
+ disable_zone_check = ISC_TRUE;
+ break;
+
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
@@ -2653,6 +3184,21 @@ main(int argc, char *argv[]) {
case 'z':
ignoreksk = ISC_TRUE;
break;
+
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ usage();
+ break;
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
}
}
@@ -2743,7 +3289,8 @@ main(int argc, char *argv[]) {
else if (strcasecmp(serialformatstr, "unixtime") == 0)
serialformat = SOA_SERIAL_UNIXTIME;
else
- fatal("unknown soa serial format: %s\n", serialformatstr);
+ fatal("unknown soa serial format: %s\n",
+ serialformatstr);
}
result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
@@ -2769,7 +3316,12 @@ main(int argc, char *argv[]) {
"NSEC only DNSKEY");
}
+ /*
+ * We need to do this early on, as we start messing with the list
+ * of keys rather early.
+ */
ISC_LIST_INIT(keylist);
+ isc_rwlock_init(&keylist_lock, 0, 0);
if (argc == 0) {
loadzonekeys(gdb);
@@ -2806,6 +3358,7 @@ main(int argc, char *argv[]) {
}
if (key == NULL) {
key = newkeystruct(newkey, ISC_TRUE);
+ key->commandline = ISC_TRUE;
ISC_LIST_APPEND(keylist, key, link);
} else
dst_key_free(&newkey);
@@ -2856,8 +3409,11 @@ main(int argc, char *argv[]) {
}
if (ISC_LIST_EMPTY(keylist)) {
- fprintf(stderr, "%s: warning: No keys specified or found\n",
- program);
+ if (disable_zone_check)
+ fprintf(stderr, "%s: warning: No keys specified "
+ "or found\n", program);
+ else
+ fatal("No signing keys specified or found.");
nokeys = ISC_TRUE;
}
@@ -2972,6 +3528,7 @@ main(int argc, char *argv[]) {
isc_taskmgr_destroy(&taskmgr);
isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
postsign();
+ verifyzone();
if (outputformat != dns_masterformat_text) {
result = dns_master_dumptostream2(mctx, gdb, gversion,
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
index 7ed320a..f204fcd 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.31.44.6 2009/06/09 01:47:19 each Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.31.44.8 2009/11/06 21:36:22 each Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
<date>June 08, 2009</date>
@@ -73,6 +73,7 @@
<arg><option>-o <replaceable class="parameter">origin</replaceable></option></arg>
<arg><option>-O <replaceable class="parameter">output-format</replaceable></option></arg>
<arg><option>-p</option></arg>
+ <arg><option>-P</option></arg>
<arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
<arg><option>-s <replaceable class="parameter">start-time</replaceable></option></arg>
<arg><option>-t</option></arg>
@@ -91,10 +92,10 @@
<para><command>dnssec-signzone</command>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. The security status of delegations from the signed zone
- (that is, whether the child zones are secure or not) is
- determined by the presence or absence of a
- <filename>keyset</filename> file for each child zone.
+ zone. It also generates a <filename>keyset-</filename> file containing
+ the key-signing keys for the zone, and if signing a zone which
+ contains delegations, it can optionally generate DS records for
+ the child zones from their <filename>keyset-</filename> files.
</para>
</refsect1>
@@ -154,8 +155,10 @@
<term>-g</term>
<listitem>
<para>
- Generate DS records for child zones from keyset files.
- Existing DS records will be removed.
+ If the zone contains any delegations, and there are
+ <filename>keyset-</filename> files for any of the child zones,
+ then DS records for the child zones will be generated from the
+ keys in those files. Existing DS records will be removed.
</para>
</listitem>
</varlistentry>
@@ -360,6 +363,22 @@
</varlistentry>
<varlistentry>
+ <term>-P</term>
+ <listitem>
+ <para>
+ Disable post sign verification tests.
+ </para>
+ <para>
+ The post sign verification test ensures that for each algorithm
+ in use there is at least one non revoked self signed KSK key,
+ that all revoked KSK keys are self signed, and that all records
+ in the zone are signed by the algorithm.
+ This option skips these tests.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-r <replaceable class="parameter">randomdev</replaceable></term>
<listitem>
<para>
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.html b/contrib/bind9/bin/dnssec/dnssec-signzone.html
index 652d5c4..e7c534f 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.html
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.html,v 1.33.44.4.8.1 2009/12/31 23:17:46 tbox Exp $ -->
+<!-- $Id: dnssec-signzone.html,v 1.33.44.8 2009/11/07 01:56:11 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,21 +29,21 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543554"></a><h2>DESCRIPTION</h2>
+<a name="id2543558"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-signzone</strong></span>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. The security status of delegations from the signed zone
- (that is, whether the child zones are secure or not) is
- determined by the presence or absence of a
- <code class="filename">keyset</code> file for each child zone.
+ zone. It also generates a <code class="filename">keyset-</code> file containing
+ the key-signing keys for the zone, and if signing a zone which
+ contains delegations, it can optionally generate DS records for
+ the child zones from their <code class="filename">keyset-</code> files.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543569"></a><h2>OPTIONS</h2>
+<a name="id2543576"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -70,8 +70,10 @@
</p></dd>
<dt><span class="term">-g</span></dt>
<dd><p>
- Generate DS records for child zones from keyset files.
- Existing DS records will be removed.
+ If the zone contains any delegations, and there are
+ <code class="filename">keyset-</code> files for any of the child zones,
+ then DS records for the child zones will be generated from the
+ keys in those files. Existing DS records will be removed.
</p></dd>
<dt><span class="term">-s <em class="replaceable"><code>start-time</code></em></span></dt>
<dd><p>
@@ -202,6 +204,19 @@
may be useful when signing large zones or when the entropy
source is limited.
</p></dd>
+<dt><span class="term">-P</span></dt>
+<dd>
+<p>
+ Disable post sign verification tests.
+ </p>
+<p>
+ The post sign verification test ensures that for each algorithm
+ in use there is at least one non revoked self signed KSK key,
+ that all revoked KSK keys are self signed, and that all records
+ in the zone are signed by the algorithm.
+ This option skips these tests.
+ </p>
+</dd>
<dt><span class="term">-r <em class="replaceable"><code>randomdev</code></em></span></dt>
<dd><p>
Specifies the source of randomness. If the operating
@@ -258,7 +273,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544407"></a><h2>EXAMPLE</h2>
+<a name="id2544503"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
@@ -287,7 +302,7 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2544458"></a><h2>KNOWN BUGS</h2>
+<a name="id2544554"></a><h2>KNOWN BUGS</h2>
<p>
<span><strong class="command">dnssec-signzone</strong></span> was designed so that it could
sign a zone partially, using only a subset of the DNSSEC keys
@@ -312,14 +327,14 @@ db.example.com.signed
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544484"></a><h2>SEE ALSO</h2>
+<a name="id2544716"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 4033</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544645"></a><h2>AUTHOR</h2>
+<a name="id2544741"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssectool.c b/contrib/bind9/bin/dnssec/dnssectool.c
index b89d769..3a6b7f0 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.c
+++ b/contrib/bind9/bin/dnssec/dnssectool.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.c,v 1.45.334.4 2009/06/08 23:47:00 tbox Exp $ */
+/* $Id: dnssectool.c,v 1.45.334.5 2009/06/22 05:05:00 marka Exp $ */
/*! \file */
@@ -65,7 +65,7 @@ void
fatal(const char *format, ...) {
va_list args;
- fprintf(stderr, "%s: ", program);
+ fprintf(stderr, "%s: fatal: ", program);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
diff --git a/contrib/bind9/bin/dnssec/dnssectool.h b/contrib/bind9/bin/dnssec/dnssectool.h
index ee476f4..43b7375 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.h
+++ b/contrib/bind9/bin/dnssec/dnssectool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.h,v 1.22 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: dnssectool.h,v 1.22.48.2 2009/09/04 23:46:58 tbox Exp $ */
#ifndef DNSSECTOOL_H
#define DNSSECTOOL_H 1
@@ -45,7 +45,7 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size);
void
alg_format(const dns_secalg_t alg, char *cp, unsigned int size);
-#define ALG_FORMATSIZE 10
+#define ALG_FORMATSIZE 20
void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size);
diff --git a/contrib/bind9/bin/named/control.c b/contrib/bind9/bin/named/control.c
index 8bd8f6c..ac1ec42 100644
--- a/contrib/bind9/bin/named/control.c
+++ b/contrib/bind9/bin/named/control.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: control.c,v 1.33 2007/09/13 04:45:18 each Exp $ */
+/* $Id: control.c,v 1.33.266.2 2009/07/11 23:47:17 tbox Exp $ */
/*! \file */
@@ -56,7 +56,7 @@ command_compare(const char *text, const char *command) {
/*%
* This function is called to process the incoming command
- * when a control channel message is received.
+ * when a control channel message is received.
*/
isc_result_t
ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
@@ -170,10 +170,12 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
} else if (command_compare(command, NS_COMMAND_TSIGDELETE)) {
result = ns_server_tsigdelete(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_FREEZE)) {
- result = ns_server_freeze(ns_g_server, ISC_TRUE, command);
+ result = ns_server_freeze(ns_g_server, ISC_TRUE, command,
+ text);
} else if (command_compare(command, NS_COMMAND_UNFREEZE) ||
command_compare(command, NS_COMMAND_THAW)) {
- result = ns_server_freeze(ns_g_server, ISC_FALSE, command);
+ result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
+ text);
} else if (command_compare(command, NS_COMMAND_RECURSING)) {
result = ns_server_dumprecursing(ns_g_server);
} else if (command_compare(command, NS_COMMAND_TIMERPOKE)) {
diff --git a/contrib/bind9/bin/named/include/named/server.h b/contrib/bind9/bin/named/include/named/server.h
index 43eccc4..1a3f746 100644
--- a/contrib/bind9/bin/named/include/named/server.h
+++ b/contrib/bind9/bin/named/include/named/server.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.h,v 1.93.120.2 2009/01/29 23:47:44 tbox Exp $ */
+/* $Id: server.h,v 1.93.120.3 2009/07/11 04:23:53 marka Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
@@ -276,7 +276,8 @@ ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text);
* Enable or disable updates for a zone.
*/
isc_result_t
-ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args);
+ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
+ isc_buffer_t *text);
/*%
* Dump the current recursive queries.
diff --git a/contrib/bind9/bin/named/lwresd.8 b/contrib/bind9/bin/named/lwresd.8
index c0862aa..56d272b 100644
--- a/contrib/bind9/bin/named/lwresd.8
+++ b/contrib/bind9/bin/named/lwresd.8
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwresd.8,v 1.29.14.1 2009/01/23 01:53:33 tbox Exp $
+.\" $Id: lwresd.8,v 1.29.14.2 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/named/lwresd.html b/contrib/bind9/bin/named/lwresd.html
index 4c2b059..728acc8 100644
--- a/contrib/bind9/bin/named/lwresd.html
+++ b/contrib/bind9/bin/named/lwresd.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwresd.html,v 1.25.14.1 2009/01/23 01:53:33 tbox Exp $ -->
+<!-- $Id: lwresd.html,v 1.25.14.2 2009/07/11 01:55:21 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/named/named.8 b/contrib/bind9/bin/named/named.8
index 3408403..2874272 100644
--- a/contrib/bind9/bin/named/named.8
+++ b/contrib/bind9/bin/named/named.8
@@ -1,7 +1,7 @@
-.\" Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named.8,v 1.38 2008/11/07 01:11:19 tbox Exp $
+.\" $Id: named.8,v 1.38.14.2 2009/12/03 05:06:38 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: named
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: June 30, 2000
+.\" Date: May 21, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "NAMED" "8" "June 30, 2000" "BIND9" "BIND9"
+.TH "NAMED" "8" "May 21, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -224,6 +224,16 @@ The
\fBnamed\fR
configuration file is too complex to describe in detail here. A complete description is provided in the
BIND 9 Administrator Reference Manual.
+.PP
+\fBnamed\fR
+inherits the
+\fBumask\fR
+(file creation mode mask) from the parent process. If files created by
+\fBnamed\fR, such as journal files, need to have custom permissions, the
+\fBumask\fR
+should be set explicitly in the script used to start the
+\fBnamed\fR
+process.
.SH "FILES"
.PP
\fI/etc/named.conf\fR
@@ -250,7 +260,7 @@ BIND 9 Administrator Reference Manual.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004\-2008 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000, 2001, 2003 Internet Software Consortium.
.br
diff --git a/contrib/bind9/bin/named/named.conf.5 b/contrib/bind9/bin/named/named.conf.5
index 039c795..3206f5d 100644
--- a/contrib/bind9/bin/named/named.conf.5
+++ b/contrib/bind9/bin/named/named.conf.5
@@ -1,6 +1,6 @@
.\" Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named.conf.5,v 1.36 2008/09/25 04:45:04 tbox Exp $
+.\" $Id: named.conf.5,v 1.36.48.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/named/named.conf.html b/contrib/bind9/bin/named/named.conf.html
index 7bbbd0a..190f0c1 100644
--- a/contrib/bind9/bin/named/named.conf.html
+++ b/contrib/bind9/bin/named/named.conf.html
@@ -1,7 +1,7 @@
<!--
- Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.conf.html,v 1.45 2008/09/25 04:45:04 tbox Exp $ -->
+<!-- $Id: named.conf.html,v 1.45.48.1 2009/07/11 01:55:21 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/named/named.docbook b/contrib/bind9/bin/named/named.docbook
index f47eae1..246c4f5 100644
--- a/contrib/bind9/bin/named/named.docbook
+++ b/contrib/bind9/bin/named/named.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.docbook,v 1.23 2008/11/06 05:30:24 marka Exp $ -->
+<!-- $Id: named.docbook,v 1.23.14.2 2009/12/03 04:49:32 tbox Exp $ -->
<refentry id="man.named">
<refentryinfo>
- <date>June 30, 2000</date>
+ <date>May 21, 2009</date>
</refentryinfo>
<refmeta>
@@ -42,6 +42,7 @@
<year>2006</year>
<year>2007</year>
<year>2008</year>
+ <year>2009</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -374,6 +375,16 @@
in the
<citetitle>BIND 9 Administrator Reference Manual</citetitle>.
</para>
+
+ <para>
+ <command>named</command> inherits the <function>umask</function>
+ (file creation mode mask) from the parent process. If files
+ created by <command>named</command>, such as journal files,
+ need to have custom permissions, the <function>umask</function>
+ should be set explicitly in the script used to start the
+ <command>named</command> process.
+ </para>
+
</refsect1>
<refsect1>
diff --git a/contrib/bind9/bin/named/named.html b/contrib/bind9/bin/named/named.html
index 23c9a7c..3522475 100644
--- a/contrib/bind9/bin/named/named.html
+++ b/contrib/bind9/bin/named/named.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.html,v 1.30 2008/11/07 01:11:19 tbox Exp $ -->
+<!-- $Id: named.html,v 1.30.14.2 2009/12/03 05:06:38 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -32,7 +32,7 @@
<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543468"></a><h2>DESCRIPTION</h2>
+<a name="id2543472"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named</strong></span>
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -47,7 +47,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543493"></a><h2>OPTIONS</h2>
+<a name="id2543496"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-4</span></dt>
<dd><p>
@@ -220,7 +220,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543928"></a><h2>SIGNALS</h2>
+<a name="id2543931"></a><h2>SIGNALS</h2>
<p>
In routine operation, signals should not be used to control
the nameserver; <span><strong class="command">rndc</strong></span> should be used
@@ -241,16 +241,24 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543976"></a><h2>CONFIGURATION</h2>
+<a name="id2543979"></a><h2>CONFIGURATION</h2>
<p>
The <span><strong class="command">named</strong></span> configuration file is too complex
to describe in detail here. A complete description is provided
in the
<em class="citetitle">BIND 9 Administrator Reference Manual</em>.
</p>
+<p>
+ <span><strong class="command">named</strong></span> inherits the <code class="function">umask</code>
+ (file creation mode mask) from the parent process. If files
+ created by <span><strong class="command">named</strong></span>, such as journal files,
+ need to have custom permissions, the <code class="function">umask</code>
+ should be set explicitly in the script used to start the
+ <span><strong class="command">named</strong></span> process.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543993"></a><h2>FILES</h2>
+<a name="id2544016"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt>
<dd><p>
@@ -263,7 +271,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544033"></a><h2>SEE ALSO</h2>
+<a name="id2544123"></a><h2>SEE ALSO</h2>
<p><em class="citetitle">RFC 1033</em>,
<em class="citetitle">RFC 1034</em>,
<em class="citetitle">RFC 1035</em>,
@@ -276,7 +284,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544171"></a><h2>AUTHOR</h2>
+<a name="id2544194"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c
index a56d2e6..cef6d7f 100644
--- a/contrib/bind9/bin/named/query.c
+++ b/contrib/bind9/bin/named/query.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.313.20.7.12.4 2009/12/31 22:53:03 each Exp $ */
+/* $Id: query.c,v 1.313.20.16 2009/12/30 08:34:29 jinmei Exp $ */
/*! \file */
@@ -2244,7 +2244,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
static inline isc_result_t
query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
- dns_trust_t trust, dns_name_t **anamep, dns_rdatatype_t type)
+ dns_rdataset_t *dname, dns_name_t **anamep,
+ dns_rdatatype_t type)
{
dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist;
@@ -2280,7 +2281,7 @@ query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
rdatalist->type = type;
rdatalist->covers = 0;
rdatalist->rdclass = client->message->rdclass;
- rdatalist->ttl = 0;
+ rdatalist->ttl = dname->ttl;
dns_name_toregion(tname, &r);
rdata->data = r.base;
@@ -2292,7 +2293,7 @@ query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
== ISC_R_SUCCESS);
- rdataset->trust = trust;
+ rdataset->trust = dname->trust;
query_addrrset(client, anamep, &rdataset, NULL, NULL,
DNS_SECTION_ANSWER);
@@ -2735,7 +2736,7 @@ query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node,
return;
addnsec3:
- if (dns_db_iscache(db))
+ if (!dns_db_iszone(db))
goto cleanup;
/*
* Add the NSEC3 which proves the DS does not exist.
@@ -3317,6 +3318,14 @@ do { \
line = __LINE__; \
} while (0)
+#define RECURSE_ERROR(r) \
+do { \
+ if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \
+ QUERY_ERROR(r); \
+ else \
+ QUERY_ERROR(DNS_R_SERVFAIL); \
+} while (0)
+
/*
* Extract a network address from the RDATA of an A or AAAA
* record.
@@ -3604,7 +3613,7 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
dns_name_t *found)
{
unsigned char salt[256];
- size_t salt_length = sizeof(salt);
+ size_t salt_length;
isc_uint16_t iterations;
isc_result_t result;
unsigned int dboptions;
@@ -3999,14 +4008,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
if (result == ISC_R_SUCCESS)
client->query.attributes |=
NS_QUERYATTR_RECURSING;
- else if (result == DNS_R_DUPLICATE ||
- result == DNS_R_DROP) {
- /* Duplicate query. */
- QUERY_ERROR(result);
- } else {
- /* Unable to recurse. */
- QUERY_ERROR(DNS_R_SERVFAIL);
- }
+ else
+ RECURSE_ERROR(result);
goto cleanup;
} else {
/* Unable to give root server referral. */
@@ -4185,11 +4188,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
if (result == ISC_R_SUCCESS)
client->query.attributes |=
NS_QUERYATTR_RECURSING;
- else if (result == DNS_R_DUPLICATE ||
- result == DNS_R_DROP)
- QUERY_ERROR(result);
else
- QUERY_ERROR(DNS_R_SERVFAIL);
+ RECURSE_ERROR(result);
} else {
dns_fixedname_t fixed;
@@ -4603,7 +4603,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
dns_name_init(tname, NULL);
(void)query_addcnamelike(client, client->query.qname, fname,
- trdataset->trust, &tname,
+ trdataset, &tname,
dns_rdatatype_cname);
if (tname != NULL)
dns_message_puttempname(client->message, &tname);
@@ -4729,7 +4729,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
client->query.attributes |=
NS_QUERYATTR_RECURSING;
else
- QUERY_ERROR(DNS_R_SERVFAIL); }
+ RECURSE_ERROR(result);
+ }
goto addauth;
}
/*
@@ -5123,9 +5124,17 @@ ns_query_start(ns_client_t *client) {
}
/*
- * Turn on minimal response for DNSKEY queries.
+ * Turn on minimal response for DNSKEY and DS queries.
+ */
+ if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds)
+ client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
+ NS_QUERYATTR_NOADDITIONAL);
+
+ /*
+ * Turn on minimal responses for EDNS/UDP bufsize 512 queries.
*/
- if (qtype == dns_rdatatype_dnskey)
+ if (client->opt != NULL && client->udpsize <= 512U &&
+ (client->attributes & NS_CLIENTATTR_TCP) == 0)
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL);
diff --git a/contrib/bind9/bin/named/server.c b/contrib/bind9/bin/named/server.c
index e685e18..6608fdf 100644
--- a/contrib/bind9/bin/named/server.c
+++ b/contrib/bind9/bin/named/server.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.520.12.7 2009/01/30 03:53:38 marka Exp $ */
+/* $Id: server.c,v 1.520.12.11.8.2 2010/02/25 10:57:11 tbox Exp $ */
/*! \file */
@@ -2826,7 +2826,7 @@ set_limit(const cfg_obj_t **maps, const char *configname,
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
result == ISC_R_SUCCESS ?
ISC_LOG_DEBUG(3) : ISC_LOG_WARNING,
- "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s",
+ "set maximum %s to %" ISC_PRINT_QUADFORMAT "u: %s",
description, value, isc_result_totext(result));
}
@@ -4337,6 +4337,8 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
/* Partial match? */
if (result != ISC_R_SUCCESS && *zonep != NULL)
dns_zone_detach(zonep);
+ if (result == DNS_R_PARTIALMATCH)
+ result = ISC_R_NOTFOUND;
fail1:
return (result);
}
@@ -4724,6 +4726,8 @@ dumpdone(void *arg, isc_result_t result) {
}
if (dctx->cache != NULL) {
dns_adb_dump(dctx->view->view->adb, dctx->fp);
+ dns_resolver_printbadcache(dctx->view->view->resolver,
+ dctx->fp);
dns_db_detach(&dctx->cache);
}
if (dctx->dumpzones) {
@@ -5401,7 +5405,9 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
* Act on a "freeze" or "thaw" command from the command channel.
*/
isc_result_t
-ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
+ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
+ isc_buffer_t *text)
+{
isc_result_t result, tresult;
dns_zone_t *zone = NULL;
dns_zonetype_t type;
@@ -5411,6 +5417,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
char *journal;
const char *vname, *sep;
isc_boolean_t frozen;
+ const char *msg = NULL;
result = zone_from_args(server, args, &zone);
if (result != ISC_R_SUCCESS)
@@ -5441,27 +5448,52 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
return (ISC_R_NOTFOUND);
}
+ result = isc_task_beginexclusive(server->task);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
frozen = dns_zone_getupdatedisabled(zone);
if (freeze) {
- if (frozen)
+ if (frozen) {
+ msg = "WARNING: The zone was already frozen.\n"
+ "Someone else may be editing it or "
+ "it may still be re-loading.";
result = DNS_R_FROZEN;
- if (result == ISC_R_SUCCESS)
+ }
+ if (result == ISC_R_SUCCESS) {
result = dns_zone_flush(zone);
+ if (result != ISC_R_SUCCESS)
+ msg = "Flushing the zone updates to "
+ "disk failed.";
+ }
if (result == ISC_R_SUCCESS) {
journal = dns_zone_getjournal(zone);
if (journal != NULL)
(void)isc_file_remove(journal);
}
+ if (result == ISC_R_SUCCESS)
+ dns_zone_setupdatedisabled(zone, freeze);
} else {
if (frozen) {
- result = dns_zone_load(zone);
- if (result == DNS_R_CONTINUE ||
- result == DNS_R_UPTODATE)
+ result = dns_zone_loadandthaw(zone);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ case DNS_R_UPTODATE:
+ msg = "The zone reload and thaw was "
+ "successful.";
result = ISC_R_SUCCESS;
+ break;
+ case DNS_R_CONTINUE:
+ msg = "A zone reload and thaw was started.\n"
+ "Check the logs to see the result.";
+ result = ISC_R_SUCCESS;
+ break;
+ }
}
}
- if (result == ISC_R_SUCCESS)
- dns_zone_setupdatedisabled(zone, freeze);
+ isc_task_endexclusive(server->task);
+
+ if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text))
+ isc_buffer_putmem(text, (const unsigned char *)msg,
+ strlen(msg) + 1);
view = dns_zone_getview(zone);
if (strcmp(view->name, "_bind") == 0 ||
diff --git a/contrib/bind9/bin/named/statschannel.c b/contrib/bind9/bin/named/statschannel.c
index 81f40bb..4773ec6 100644
--- a/contrib/bind9/bin/named/statschannel.c
+++ b/contrib/bind9/bin/named/statschannel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.c,v 1.14.64.6 2009/02/17 03:43:07 marka Exp $ */
+/* $Id: statschannel.c,v 1.14.64.11 2010/02/04 23:47:46 tbox Exp $ */
/*! \file */
@@ -70,6 +70,7 @@ stats_dumparg {
int ncounters; /* used for general statistics */
int *counterindices; /* used for general statistics */
isc_uint64_t *countervalues; /* used for general statistics */
+ isc_result_t result;
} stats_dumparg_t;
static isc_once_t once = ISC_ONCE_INIT;
@@ -95,6 +96,8 @@ static const char *sockstats_xmldesc[isc_sockstatscounter_max];
#define sockstats_xmldesc NULL
#endif /* HAVE_LIBXML2 */
+#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
+
/*%
* Mapping arrays to represent statistics counters in the order of our
* preference, regardless of the order of counter indices. For example,
@@ -129,11 +132,11 @@ init_desc(void) {
int i;
/* Initialize name server statistics */
- memset((void *)nsstats_desc, 0,
- dns_nsstatscounter_max * sizeof(nsstats_desc[0]));
+ for (i = 0; i < dns_nsstatscounter_max; i++)
+ nsstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
- memset((void *)nsstats_xmldesc, 0,
- dns_nsstatscounter_max * sizeof(nsstats_xmldesc[0]));
+ for (i = 0; i < dns_nsstatscounter_max; i++)
+ nsstats_xmldesc[i] = NULL;
#endif
#define SET_NSSTATDESC(counterid, desc, xmldesc) \
@@ -197,11 +200,11 @@ init_desc(void) {
INSIST(i == dns_nsstatscounter_max);
/* Initialize resolver statistics */
- memset((void *)resstats_desc, 0,
- dns_resstatscounter_max * sizeof(resstats_desc[0]));
+ for (i = 0; i < dns_resstatscounter_max; i++)
+ resstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
- memset((void *)resstats_xmldesc, 0,
- dns_resstatscounter_max * sizeof(resstats_xmldesc[0]));
+ for (i = 0; i < dns_resstatscounter_max; i++)
+ resstats_xmldesc[i] = NULL;
#endif
#define SET_RESSTATDESC(counterid, desc, xmldesc) \
@@ -267,11 +270,11 @@ init_desc(void) {
INSIST(i == dns_resstatscounter_max);
/* Initialize zone statistics */
- memset((void *)zonestats_desc, 0,
- dns_zonestatscounter_max * sizeof(zonestats_desc[0]));
+ for (i = 0; i < dns_zonestatscounter_max; i++)
+ zonestats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
- memset((void *)zonestats_xmldesc, 0,
- dns_zonestatscounter_max * sizeof(zonestats_xmldesc[0]));
+ for (i = 0; i < dns_zonestatscounter_max; i++)
+ zonestats_xmldesc[i] = NULL;
#endif
#define SET_ZONESTATDESC(counterid, desc, xmldesc) \
@@ -299,11 +302,11 @@ init_desc(void) {
INSIST(i == dns_zonestatscounter_max);
/* Initialize socket statistics */
- memset((void *)sockstats_desc, 0,
- isc_sockstatscounter_max * sizeof(sockstats_desc[0]));
+ for (i = 0; i < isc_sockstatscounter_max; i++)
+ sockstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
- memset((void *)sockstats_xmldesc, 0,
- isc_sockstatscounter_max * sizeof(sockstats_xmldesc[0]));
+ for (i = 0; i < isc_sockstatscounter_max; i++)
+ sockstats_xmldesc[i] = NULL;
#endif
#define SET_SOCKSTATDESC(counterid, desc, xmldesc) \
@@ -437,7 +440,7 @@ generalstat_dump(isc_statscounter_t counter, isc_uint64_t val, void *arg) {
dumparg->countervalues[counter] = val;
}
-static void
+static isc_result_t
dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
const char *category, const char **desc, int ncounters,
int *indices, isc_uint64_t *values, int options)
@@ -448,6 +451,7 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
FILE *fp;
#ifdef HAVE_LIBXML2
xmlTextWriterPtr writer;
+ int xmlrc;
#endif
#ifndef HAVE_LIBXML2
@@ -480,31 +484,41 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
writer = arg;
if (category != NULL) {
- xmlTextWriterStartElement(writer,
- ISC_XMLCHAR
- category);
- xmlTextWriterStartElement(writer,
- ISC_XMLCHAR "name");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR
- desc[index]);
- xmlTextWriterEndElement(writer); /* name */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR
- "counter");
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ category));
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ "name"));
+ TRY0(xmlTextWriterWriteString(writer,
+ ISC_XMLCHAR
+ desc[index]));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
+
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ "counter"));
} else {
- xmlTextWriterStartElement(writer, ISC_XMLCHAR
- desc[index]);
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ desc[index]));
}
- xmlTextWriterWriteFormatString(writer,
- "%" ISC_PRINT_QUADFORMAT
- "u", value);
- xmlTextWriterEndElement(writer); /* counter */
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%"
+ ISC_PRINT_QUADFORMAT
+ "u", value));
+ TRY0(xmlTextWriterEndElement(writer)); /* counter */
if (category != NULL)
- xmlTextWriterEndElement(writer); /* category */
+ TRY0(xmlTextWriterEndElement(writer)); /* category */
#endif
break;
}
}
+ return (ISC_R_SUCCESS);
+#ifdef HAVE_LIBXML2
+ error:
+ return (ISC_R_FAILURE);
+#endif
}
static void
@@ -515,6 +529,7 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
FILE *fp;
#ifdef HAVE_LIBXML2
xmlTextWriterPtr writer;
+ int xmlrc;
#endif
if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE)
@@ -534,22 +549,28 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
#ifdef HAVE_LIBXML2
writer = dumparg->arg;
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype"));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr);
- xmlTextWriterEndElement(writer); /* name */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
- xmlTextWriterWriteFormatString(writer,
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
"%" ISC_PRINT_QUADFORMAT "u",
- val);
- xmlTextWriterEndElement(writer); /* counter */
+ val));
+ TRY0(xmlTextWriterEndElement(writer)); /* counter */
- xmlTextWriterEndElement(writer); /* rdtype */
+ TRY0(xmlTextWriterEndElement(writer)); /* rdtype */
#endif
break;
}
+ return;
+#ifdef HAVE_LIBXML2
+ error:
+ dumparg->result = ISC_R_FAILURE;
+ return;
+#endif
}
static void
@@ -561,6 +582,7 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
isc_boolean_t nxrrset = ISC_FALSE;
#ifdef HAVE_LIBXML2
xmlTextWriterPtr writer;
+ int xmlrc;
#endif
if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN)
@@ -589,22 +611,28 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
#ifdef HAVE_LIBXML2
writer = dumparg->arg;
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset");
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteFormatString(writer, "%s%s",
- nxrrset ? "!" : "", typestr);
- xmlTextWriterEndElement(writer); /* name */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset"));
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%s%s",
+ nxrrset ? "!" : "", typestr));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
- xmlTextWriterWriteFormatString(writer,
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
"%" ISC_PRINT_QUADFORMAT "u",
- val);
- xmlTextWriterEndElement(writer); /* counter */
+ val));
+ TRY0(xmlTextWriterEndElement(writer)); /* counter */
- xmlTextWriterEndElement(writer); /* rrset */
+ TRY0(xmlTextWriterEndElement(writer)); /* rrset */
#endif
break;
}
+ return;
+#ifdef HAVE_LIBXML2
+ error:
+ dumparg->result = ISC_R_FAILURE;
+#endif
+
}
static void
@@ -615,6 +643,7 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
stats_dumparg_t *dumparg = arg;
#ifdef HAVE_LIBXML2
xmlTextWriterPtr writer;
+ int xmlrc;
#endif
isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
@@ -630,30 +659,35 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
#ifdef HAVE_LIBXML2
writer = dumparg->arg;
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode"));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf);
- xmlTextWriterEndElement(writer); /* name */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
- xmlTextWriterWriteFormatString(writer,
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
"%" ISC_PRINT_QUADFORMAT "u",
- val);
- xmlTextWriterEndElement(writer); /* counter */
+ val));
+ TRY0(xmlTextWriterEndElement(writer)); /* counter */
- xmlTextWriterEndElement(writer); /* opcode */
+ TRY0(xmlTextWriterEndElement(writer)); /* opcode */
#endif
break;
}
+ return;
+
+#ifdef HAVE_LIBXML2
+ error:
+ dumparg->result = ISC_R_FAILURE;
+ return;
+#endif
}
#ifdef HAVE_LIBXML2
/* XXXMLG below here sucks. */
-#define TRY(a) do { result = (a); INSIST(result == ISC_R_SUCCESS); } while(0);
-#define TRY0(a) do { xmlrc = (a); INSIST(xmlrc >= 0); } while(0);
static isc_result_t
zone_xmlrender(dns_zone_t *zone, void *arg) {
@@ -663,47 +697,55 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
xmlTextWriterPtr writer = arg;
isc_stats_t *zonestats;
isc_uint64_t nsstat_values[dns_nsstatscounter_max];
+ int xmlrc;
+ isc_result_t result;
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"));
dns_zone_name(zone, buf, sizeof(buf));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
+ TRY0(xmlTextWriterEndElement(writer));
rdclass = dns_zone_getclass(zone);
dns_rdataclass_format(rdclass, buf, sizeof(buf));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
+ TRY0(xmlTextWriterEndElement(writer));
- serial = dns_zone_getserial(zone);
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial");
- xmlTextWriterWriteFormatString(writer, "%u", serial);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"));
+ if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS)
+ TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial));
+ else
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
+ TRY0(xmlTextWriterEndElement(writer));
zonestats = dns_zone_getrequeststats(zone);
if (zonestats != NULL) {
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters");
- dump_counters(zonestats, statsformat_xml, writer, NULL,
- nsstats_xmldesc, dns_nsstatscounter_max,
- nsstats_index, nsstat_values,
- ISC_STATSDUMP_VERBOSE);
- xmlTextWriterEndElement(writer); /* counters */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ result = dump_counters(zonestats, statsformat_xml, writer, NULL,
+ nsstats_xmldesc, dns_nsstatscounter_max,
+ nsstats_index, nsstat_values,
+ ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* counters */
}
- xmlTextWriterEndElement(writer); /* zone */
+ TRY0(xmlTextWriterEndElement(writer)); /* zone */
return (ISC_R_SUCCESS);
+ error:
+ return (ISC_R_FAILURE);
}
-static void
+static isc_result_t
generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"];
isc_time_t now;
- xmlTextWriterPtr writer;
- xmlDocPtr doc;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
int xmlrc;
dns_view_t *view;
stats_dumparg_t dumparg;
@@ -712,12 +754,15 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
isc_uint64_t resstat_values[dns_resstatscounter_max];
isc_uint64_t zonestat_values[dns_zonestatscounter_max];
isc_uint64_t sockstat_values[isc_sockstatscounter_max];
+ isc_result_t result;
isc_time_now(&now);
isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
isc_time_formatISO8601(&now, nowstr, sizeof nowstr);
writer = xmlNewTextWriterDoc(&doc, 0);
+ if (writer == NULL)
+ goto error;
TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL));
TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet",
ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\""));
@@ -728,7 +773,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "bind"));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
- ISC_XMLCHAR "2.0"));
+ ISC_XMLCHAR "2.2"));
/* Set common fields for statistics dump */
dumparg.type = statsformat_xml;
@@ -741,39 +786,55 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
view = ISC_LIST_HEAD(server->viewlist);
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views"));
while (view != NULL) {
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "view");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name));
+ TRY0(xmlTextWriterEndElement(writer));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones");
- dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender,
- writer);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones"));
+ result = dns_zt_apply(view->zonetable, ISC_TRUE, zone_xmlrender,
+ writer);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer));
if (view->resquerystats != NULL) {
+ dumparg.result = ISC_R_SUCCESS;
dns_rdatatypestats_dump(view->resquerystats,
rdtypestat_dump, &dumparg, 0);
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
}
if (view->resstats != NULL) {
- dump_counters(view->resstats, statsformat_xml, writer,
- "resstat", resstats_xmldesc,
- dns_resstatscounter_max, resstats_index,
- resstat_values, ISC_STATSDUMP_VERBOSE);
+ result = dump_counters(view->resstats, statsformat_xml,
+ writer, "resstat",
+ resstats_xmldesc,
+ dns_resstatscounter_max,
+ resstats_index, resstat_values,
+ ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
}
cachestats = dns_db_getrrsetstats(view->cachedb);
if (cachestats != NULL) {
- xmlTextWriterStartElement(writer,
- ISC_XMLCHAR "cache");
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "cache"));
+ TRY0(xmlTextWriterWriteAttribute(writer,
+ ISC_XMLCHAR "name",
+ ISC_XMLCHAR
+ view->name));
+ dumparg.result = ISC_R_SUCCESS;
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
&dumparg, 0);
- xmlTextWriterEndElement(writer); /* cache */
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* cache */
}
- xmlTextWriterEndElement(writer); /* view */
+ TRY0(xmlTextWriterEndElement(writer)); /* view */
view = ISC_LIST_NEXT(view, link);
}
@@ -788,44 +849,63 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
TRY0(xmlTextWriterEndElement(writer)); /* taskmgr */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server"));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime);
- xmlTextWriterEndElement(writer);
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime));
+ TRY0(xmlTextWriterEndElement(writer));
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr));
+ TRY0(xmlTextWriterEndElement(writer));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests"));
+ dumparg.result = ISC_R_SUCCESS;
dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg,
0);
- xmlTextWriterEndElement(writer); /* requests */
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* requests */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in"));
+ dumparg.result = ISC_R_SUCCESS;
dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
&dumparg, 0);
- xmlTextWriterEndElement(writer); /* queries-in */
-
- dump_counters(server->nsstats, statsformat_xml, writer,
- "nsstat", nsstats_xmldesc, dns_nsstatscounter_max,
- nsstats_index, nsstat_values, ISC_STATSDUMP_VERBOSE);
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* queries-in */
+
+ result = dump_counters(server->nsstats, statsformat_xml, writer,
+ "nsstat", nsstats_xmldesc,
+ dns_nsstatscounter_max,
+ nsstats_index, nsstat_values,
+ ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
- dump_counters(server->zonestats, statsformat_xml, writer, "zonestat",
- zonestats_xmldesc, dns_zonestatscounter_max,
- zonestats_index, zonestat_values, ISC_STATSDUMP_VERBOSE);
+ result = dump_counters(server->zonestats, statsformat_xml, writer,
+ "zonestat", zonestats_xmldesc,
+ dns_zonestatscounter_max, zonestats_index,
+ zonestat_values, ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
/*
* Most of the common resolver statistics entries are 0, so we don't
* use the verbose dump here.
*/
- dump_counters(server->resolverstats, statsformat_xml, writer, "resstat",
- resstats_xmldesc, dns_resstatscounter_max, resstats_index,
- resstat_values, 0);
+ result = dump_counters(server->resolverstats, statsformat_xml, writer,
+ "resstat", resstats_xmldesc,
+ dns_resstatscounter_max, resstats_index,
+ resstat_values, 0);
+ if (result != ISC_R_SUCCESS)
+ goto error;
- dump_counters(server->sockstats, statsformat_xml, writer, "sockstat",
- sockstats_xmldesc, isc_sockstatscounter_max,
- sockstats_index, sockstat_values, ISC_STATSDUMP_VERBOSE);
+ result = dump_counters(server->sockstats, statsformat_xml, writer,
+ "sockstat", sockstats_xmldesc,
+ isc_sockstatscounter_max, sockstats_index,
+ sockstat_values, ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
- xmlTextWriterEndElement(writer); /* server */
+ TRY0(xmlTextWriterEndElement(writer)); /* server */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
isc_mem_renderxml(writer);
@@ -841,6 +921,14 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 1);
xmlFreeDoc(doc);
+ return (ISC_R_SUCCESS);
+
+ error:
+ if (writer != NULL)
+ xmlFreeTextWriter(writer);
+ if (doc != NULL)
+ xmlFreeDoc(doc);
+ return (ISC_R_FAILURE);
}
static void
@@ -859,21 +947,24 @@ render_index(const char *url, const char *querystring, void *arg,
unsigned char *msg;
int msglen;
ns_server_t *server = arg;
+ isc_result_t result;
UNUSED(url);
UNUSED(querystring);
- generatexml(server, &msglen, &msg);
+ result = generatexml(server, &msglen, &msg);
- *retcode = 200;
- *retmsg = "OK";
- *mimetype = "text/xml";
- isc_buffer_reinit(b, msg, msglen);
- isc_buffer_add(b, msglen);
- *freecb = wrap_xmlfree;
- *freecb_args = NULL;
+ if (result == ISC_R_SUCCESS) {
+ *retcode = 200;
+ *retmsg = "OK";
+ *mimetype = "text/xml";
+ isc_buffer_reinit(b, msg, msglen);
+ isc_buffer_add(b, msglen);
+ *freecb = wrap_xmlfree;
+ *freecb_args = NULL;
+ }
- return (ISC_R_SUCCESS);
+ return (result);
}
#endif /* HAVE_LIBXML2 */
@@ -1274,20 +1365,20 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
}
fprintf(fp, "++ Name Server Statistics ++\n");
- dump_counters(server->nsstats, statsformat_file, fp, NULL,
- nsstats_desc, dns_nsstatscounter_max, nsstats_index,
- nsstat_values, 0);
+ (void) dump_counters(server->nsstats, statsformat_file, fp, NULL,
+ nsstats_desc, dns_nsstatscounter_max,
+ nsstats_index, nsstat_values, 0);
fprintf(fp, "++ Zone Maintenance Statistics ++\n");
- dump_counters(server->zonestats, statsformat_file, fp, NULL,
- zonestats_desc, dns_zonestatscounter_max,
- zonestats_index, zonestat_values, 0);
+ (void) dump_counters(server->zonestats, statsformat_file, fp, NULL,
+ zonestats_desc, dns_zonestatscounter_max,
+ zonestats_index, zonestat_values, 0);
fprintf(fp, "++ Resolver Statistics ++\n");
fprintf(fp, "[Common]\n");
- dump_counters(server->resolverstats, statsformat_file, fp, NULL,
- resstats_desc, dns_resstatscounter_max, resstats_index,
- resstat_values, 0);
+ (void) dump_counters(server->resolverstats, statsformat_file, fp, NULL,
+ resstats_desc, dns_resstatscounter_max,
+ resstats_index, resstat_values, 0);
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
@@ -1297,9 +1388,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
fprintf(fp, "[View: default]\n");
else
fprintf(fp, "[View: %s]\n", view->name);
- dump_counters(view->resstats, statsformat_file, fp, NULL,
- resstats_desc, dns_resstatscounter_max,
- resstats_index, resstat_values, 0);
+ (void) dump_counters(view->resstats, statsformat_file, fp, NULL,
+ resstats_desc, dns_resstatscounter_max,
+ resstats_index, resstat_values, 0);
}
fprintf(fp, "++ Cache DB RRsets ++\n");
@@ -1320,9 +1411,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
}
fprintf(fp, "++ Socket I/O Statistics ++\n");
- dump_counters(server->sockstats, statsformat_file, fp, NULL,
- sockstats_desc, isc_sockstatscounter_max, sockstats_index,
- sockstat_values, 0);
+ (void) dump_counters(server->sockstats, statsformat_file, fp, NULL,
+ sockstats_desc, isc_sockstatscounter_max,
+ sockstats_index, sockstat_values, 0);
fprintf(fp, "++ Per Zone Query Statistics ++\n");
zone = NULL;
@@ -1343,9 +1434,10 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
fprintf(fp, " (view: %s)", view->name);
fprintf(fp, "]\n");
- dump_counters(zonestats, statsformat_file, fp, NULL,
- nsstats_desc, dns_nsstatscounter_max,
- nsstats_index, nsstat_values, 0);
+ (void) dump_counters(zonestats, statsformat_file, fp,
+ NULL, nsstats_desc,
+ dns_nsstatscounter_max,
+ nsstats_index, nsstat_values, 0);
}
}
diff --git a/contrib/bind9/bin/named/update.c b/contrib/bind9/bin/named/update.c
index b0a556d..74a192a 100644
--- a/contrib/bind9/bin/named/update.c
+++ b/contrib/bind9/bin/named/update.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update.c,v 1.151.12.5.12.1 2009/07/28 14:18:08 marka Exp $ */
+/* $Id: update.c,v 1.151.12.9 2009/12/30 04:02:56 marka Exp $ */
#include <config.h>
@@ -3031,7 +3031,7 @@ check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
} else {
CHECK(get_iterations(db, ver, &iterations));
CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max));
- if (iterations > max) {
+ if (max != 0 && iterations > max) {
flag = ISC_TRUE;
update_log(client, zone, ISC_LOG_WARNING,
"too many NSEC3 iterations (%u) for "
@@ -3157,6 +3157,24 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
&newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
+
+ /*
+ * Remove any existing CREATE request to add an
+ * otherwise indentical chain with a reversed
+ * OPTOUT state.
+ */
+ buf[1] ^= DNS_NSEC3FLAG_OPTOUT;
+ CHECK(rr_exists(db, ver, name, &rdata, &flag));
+
+ if (flag) {
+ CHECK(dns_difftuple_create(diff->mctx,
+ DNS_DIFFOP_DEL,
+ name, tuple->ttl,
+ &rdata,
+ &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, diff));
+ }
+
/*
* Remove the temporary add record.
*/
@@ -4140,9 +4158,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
goto common;
failure:
- if (result == DNS_R_REFUSED)
- inc_stats(zone, dns_nsstatscounter_updaterej);
-
/*
* The reason for failure should have been logged at this point.
*/
diff --git a/contrib/bind9/bin/nsupdate/nsupdate.1 b/contrib/bind9/bin/nsupdate/nsupdate.1
index b0688a3..83fd7d7 100644
--- a/contrib/bind9/bin/nsupdate/nsupdate.1
+++ b/contrib/bind9/bin/nsupdate/nsupdate.1
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: nsupdate.1,v 1.3.48.2 2009/03/10 01:54:11 tbox Exp $
+.\" $Id: nsupdate.1,v 1.3.48.3 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/nsupdate/nsupdate.html b/contrib/bind9/bin/nsupdate/nsupdate.html
index dab7f90..9f45171 100644
--- a/contrib/bind9/bin/nsupdate/nsupdate.html
+++ b/contrib/bind9/bin/nsupdate/nsupdate.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nsupdate.html,v 1.40.48.2 2009/03/10 01:54:11 tbox Exp $ -->
+<!-- $Id: nsupdate.html,v 1.40.48.3 2009/07/11 01:55:21 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/rndc/rndc-confgen.8 b/contrib/bind9/bin/rndc/rndc-confgen.8
index 440870a..d37c00a 100644
--- a/contrib/bind9/bin/rndc/rndc-confgen.8
+++ b/contrib/bind9/bin/rndc/rndc-confgen.8
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2001, 2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc-confgen.8,v 1.20 2007/01/30 00:24:59 marka Exp $
+.\" $Id: rndc-confgen.8,v 1.20.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/rndc/rndc-confgen.html b/contrib/bind9/bin/rndc/rndc-confgen.html
index 4be87af..41debdc 100644
--- a/contrib/bind9/bin/rndc/rndc-confgen.html
+++ b/contrib/bind9/bin/rndc/rndc-confgen.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2001, 2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc-confgen.html,v 1.25 2007/01/30 00:24:59 marka Exp $ -->
+<!-- $Id: rndc-confgen.html,v 1.25.418.1 2009/07/11 01:55:21 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/rndc/rndc.8 b/contrib/bind9/bin/rndc/rndc.8
index 7f0dea1..8ab0df2 100644
--- a/contrib/bind9/bin/rndc/rndc.8
+++ b/contrib/bind9/bin/rndc/rndc.8
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc.8,v 1.42 2007/12/14 22:37:22 marka Exp $
+.\" $Id: rndc.8,v 1.42.214.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/rndc/rndc.conf.5 b/contrib/bind9/bin/rndc/rndc.conf.5
index 9e9bad4..edb3a36 100644
--- a/contrib/bind9/bin/rndc/rndc.conf.5
+++ b/contrib/bind9/bin/rndc/rndc.conf.5
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc.conf.5,v 1.38 2007/05/09 13:35:57 marka Exp $
+.\" $Id: rndc.conf.5,v 1.38.366.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/bin/rndc/rndc.conf.html b/contrib/bind9/bin/rndc/rndc.conf.html
index 144cd1c..6fbaaa2 100644
--- a/contrib/bind9/bin/rndc/rndc.conf.html
+++ b/contrib/bind9/bin/rndc/rndc.conf.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc.conf.html,v 1.29 2007/05/09 13:35:57 marka Exp $ -->
+<!-- $Id: rndc.conf.html,v 1.29.366.1 2009/07/11 01:55:21 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/bin/rndc/rndc.html b/contrib/bind9/bin/rndc/rndc.html
index a8d11c4..52c862a 100644
--- a/contrib/bind9/bin/rndc/rndc.html
+++ b/contrib/bind9/bin/rndc/rndc.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc.html,v 1.31 2007/12/14 22:37:22 marka Exp $ -->
+<!-- $Id: rndc.html,v 1.31.214.1 2009/07/11 01:55:21 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/config.h.in b/contrib/bind9/config.h.in
index 97b13c4..28ace46 100644
--- a/contrib/bind9/config.h.in
+++ b/contrib/bind9/config.h.in
@@ -16,7 +16,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.h.in,v 1.106.40.6 2009/03/13 05:35:43 marka Exp $ */
+/* $Id: config.h.in,v 1.106.40.11 2010/01/15 19:38:52 each Exp $ */
/*! \file */
@@ -144,6 +144,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define if threads need PTHREAD_SCOPE_SYSTEM */
#undef NEED_PTHREAD_SCOPE_SYSTEM
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
/* Define if recvmsg() does not meet all of the BSD socket API specifications.
*/
#undef BROKEN_RECVMSG
@@ -163,6 +166,12 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the `EVP_sha256' function. */
+#undef HAVE_EVP_SHA256
+
+/* Define to 1 if you have the `EVP_sha512' function. */
+#undef HAVE_EVP_SHA512
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
@@ -293,6 +302,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@@ -314,11 +326,15 @@ int sigwait(const unsigned int *set, int *sig);
#undef WITH_IDN
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
-#if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-#elif ! defined __LITTLE_ENDIAN__
-# undef WORDS_BIGENDIAN
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
#endif
/* Define to empty if `const' does not conform to ANSI C. */
diff --git a/contrib/bind9/configure.in b/contrib/bind9/configure.in
index 6ebdfdd..76e1eb3 100644
--- a/contrib/bind9/configure.in
+++ b/contrib/bind9/configure.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
-AC_REVISION($Revision: 1.457.26.9 $)
+AC_REVISION($Revision: 1.457.26.16 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
@@ -28,6 +28,18 @@ AC_CONFIG_HEADER(config.h)
AC_CANONICAL_HOST
AC_PROG_MAKE_SET
+
+#
+# GNU libtool support
+#
+case $build_os in
+sunos*)
+ # Just set the maximum command line length for sunos as it otherwise
+ # takes a exceptionally long time to work it out. Required for libtool.
+ lt_cv_sys_max_cmd_len=4096;
+ ;;
+esac
+
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_LN_S
@@ -466,7 +478,7 @@ AC_C_BIGENDIAN
OPENSSL_WARNING=
AC_MSG_CHECKING(for OpenSSL library)
AC_ARG_WITH(openssl,
-[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path].
+[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path].
(Required for DNSSEC)],
use_openssl="$withval", use_openssl="auto")
@@ -491,7 +503,9 @@ case "$use_openssl" in
auto)
DST_OPENSSL_INC=""
USE_OPENSSL=""
- AC_MSG_RESULT(not found)
+ AC_MSG_ERROR(
+[OpenSSL was not found in any of $openssldirs; use --with-openssl=/path
+If you don't want OpenSSL, use --without-openssl])
;;
*)
if test "$use_openssl" = "yes"
@@ -630,8 +644,10 @@ esac
else
AC_MSG_RESULT(no)
fi
+ AC_CHECK_FUNCS(EVP_sha256 EVP_sha512)
CFLAGS="$saved_cflags"
LIBS="$saved_libs"
+
;;
esac
@@ -652,7 +668,7 @@ DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
AC_MSG_CHECKING(for PKCS11 support)
AC_ARG_WITH(pkcs11,
-[ --with-pkcs11 Build with PKCS11 support],
+[ --with-pkcs11 Build with PKCS11 support],
use_pkcs11="yes", use_pkcs11="no")
case "$use_pkcs11" in
@@ -670,7 +686,7 @@ AC_SUBST(USE_PKCS11)
AC_MSG_CHECKING(for GSSAPI library)
AC_ARG_WITH(gssapi,
-[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
+[ --with-gssapi=PATH Specify path for system-supplied GSSAPI],
use_gssapi="$withval", use_gssapi="no")
gssapidirs="/usr/local /usr/pkg /usr/kerberos /usr"
@@ -824,7 +840,7 @@ AC_SUBST(DNS_CRYPTO_LIBS)
#
AC_MSG_CHECKING(for random device)
AC_ARG_WITH(randomdev,
-[ --with-randomdev=PATH Specify path for random device],
+[ --with-randomdev=PATH Specify path for random device],
use_randomdev="$withval", use_randomdev="unspec")
case "$use_randomdev" in
@@ -997,7 +1013,7 @@ AC_SUBST(ISC_THREAD_DIR)
#
AC_MSG_CHECKING(for libxml2 library)
AC_ARG_WITH(libxml2,
-[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]],
+[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]],
use_libxml2="$withval", use_libxml2="auto")
case "$use_libxml2" in
@@ -1191,7 +1207,7 @@ esac
#
AC_MSG_CHECKING(whether to use purify)
AC_ARG_WITH(purify,
- [ --with-purify[=PATH] use Rational purify],
+ [ --with-purify[=PATH] use Rational purify],
use_purify="$withval", use_purify="no")
case "$use_purify" in
@@ -1228,19 +1244,9 @@ esac
AC_SUBST(PURIFY)
-#
-# GNU libtool support
-#
-case $build_os in
-sunos*)
- # Just set the maximum command line length for sunos as it otherwise
- # takes a exceptionally long time to work it out. Required for libtool.
- lt_cv_sys_max_cmd_len=4096;
- ;;
-esac
AC_ARG_WITH(libtool,
- [ --with-libtool use GNU libtool (following indented options supported)],
+ [ --with-libtool use GNU libtool],
use_libtool="$withval", use_libtool="no")
case $use_libtool in
@@ -1299,7 +1305,7 @@ AC_SUBST(LIBTOOL_IN_MAIN)
# IPv6
#
AC_ARG_ENABLE(ipv6,
- [ --enable-ipv6 use IPv6 [default=autodetect]])
+ [ --enable-ipv6 use IPv6 [default=autodetect]])
case "$enable_ipv6" in
yes|''|autodetect)
@@ -1330,7 +1336,7 @@ AC_TRY_COMPILE([
#
AC_MSG_CHECKING(for Kame IPv6 support)
AC_ARG_WITH(kame,
- [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]],
+ [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]],
use_kame="$withval", use_kame="no")
case "$use_kame" in
@@ -1780,7 +1786,7 @@ AC_SUBST(ISC_LWRES_GETADDRINFOPROTO)
AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO)
AC_ARG_ENABLE(getifaddrs,
-[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
+[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
want_getifaddrs="$enableval", want_getifaddrs="yes")
#
@@ -1902,7 +1908,7 @@ AC_SUBST(ISC_EXTRA_SRCS)
# Use our own SPNEGO implementation?
#
AC_ARG_ENABLE(isc-spnego,
- [ --disable-isc-spnego use SPNEGO from GSSAPI library])
+ [ --disable-isc-spnego use SPNEGO from GSSAPI library])
if test -n "$USE_GSSAPI"
then
@@ -1967,7 +1973,7 @@ AC_SUBST(LWRES_PLATFORM_QUADFORMAT)
# Note it is very recommended to *not* disable chroot(),
# this is only because chroot() was made obsolete by Posix.
AC_ARG_ENABLE(chroot,
- [ --disable-chroot disable chroot])
+ [ --disable-chroot disable chroot])
case "$enable_chroot" in
yes|'')
AC_CHECK_FUNCS(chroot)
@@ -1976,7 +1982,7 @@ case "$enable_chroot" in
;;
esac
AC_ARG_ENABLE(linux-caps,
- [ --disable-linux-caps disable linux capabilities])
+ [ --disable-linux-caps disable linux capabilities])
case "$enable_linux_caps" in
yes|'')
AC_CHECK_HEADERS(linux/capability.h sys/capability.h)
@@ -2215,13 +2221,43 @@ AC_CHECK_FUNCS(nanosleep)
# Machine architecture dependent features
#
AC_ARG_ENABLE(atomic,
- [ --enable-atomic enable machine specific atomic operations
- [[default=autodetect]]],
+ [ --enable-atomic enable machine specific atomic operations
+ [[default=autodetect]]],
enable_atomic="$enableval",
enable_atomic="autodetect")
case "$enable_atomic" in
yes|''|autodetect)
- use_atomic=yes
+ case "$host" in
+ powerpc-ibm-aix*)
+ if test "X$GCC" = "Xyes"; then
+ AC_MSG_CHECKING([if asm("isc"); works])
+ AC_TRY_COMPILE(,[
+ main() { asm("ics"); exit(0); }
+ ],
+ [AC_MSG_RESULT(yes)
+ use_atomic=yes],
+ [
+ saved_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS -Wa,-many"
+ AC_TRY_RUN([
+ main() { asm("ics"); exit(0); }
+ ],
+ [AC_MSG_RESULT([yes, required -Wa,-many])
+ use_atomic=yes],
+ [AC_MSG_RESULT([no, use_atomic disabled])
+ CFLAGS="$saved_cflags"
+ use_atomic=no],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ CFLAGS="$saved_cflags"
+ use_atomic=yes])
+ ]
+ )
+ fi
+ ;;
+ *)
+ use_atomic=yes
+ ;;
+ esac
;;
no)
use_atomic=no
@@ -2248,8 +2284,16 @@ main() {
[arch=x86_32])
;;
x86_64-*|amd64-*)
- have_xaddq=yes
- arch=x86_64
+AC_TRY_RUN([
+main() {
+ exit((sizeof(void *) == 8) ? 0 : 1);
+}
+],
+ [arch=x86_64
+ have_xaddq=yes],
+ [arch=x86_32],
+ [arch=x86_64
+ have_xaddq=yes])
;;
alpha*-*)
arch=alpha
@@ -2354,9 +2398,9 @@ else
fi
if test "$have_xaddq" = "yes"; then
- ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
+ ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
else
- ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
+ ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
fi
AC_SUBST(ISC_PLATFORM_HAVEXADD)
@@ -2376,14 +2420,14 @@ AC_SUBST(ISC_ARCH_DIR)
# Activate "rrset-order fixed" or not?
#
AC_ARG_ENABLE(fixed-rrset,
- [ --enable-fixed-rrset enable fixed rrset ordering
- [[default=no]]],
+ [ --enable-fixed-rrset enable fixed rrset ordering
+ [[default=no]]],
enable_fixed="$enableval",
enable_fixed="no")
case "$enable_fixed" in
yes)
AC_DEFINE(DNS_RDATASET_FIXED, 1,
- [Define to enable "rrset-order fixed" syntax.])
+ [Define to enable "rrset-order fixed" syntax.])
;;
no)
;;
@@ -2503,7 +2547,7 @@ AC_SUBST($1)
#
AC_MSG_CHECKING(for Docbook-XSL path)
AC_ARG_WITH(docbook-xsl,
-[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets],
+[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets],
docbook_path="$withval", docbook_path="auto")
case "$docbook_path" in
auto)
@@ -2571,7 +2615,7 @@ AC_SUBST(XSLT_DB2LATEX_ADMONITIONS)
# IDN support
#
AC_ARG_WITH(idn,
- [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]],
+ [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]],
use_idn="$withval", use_idn="no")
case "$use_idn" in
yes)
@@ -2591,7 +2635,7 @@ esac
iconvinc=
iconvlib=
AC_ARG_WITH(libiconv,
- [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]],
+ [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]],
use_libiconv="$withval", use_libiconv="no")
case "$use_libiconv" in
yes)
@@ -2610,7 +2654,7 @@ no)
esac
AC_ARG_WITH(iconv,
- [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]],
+ [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]],
iconvlib="$withval")
case "$iconvlib" in
no)
@@ -2622,7 +2666,7 @@ yes)
esac
AC_ARG_WITH(idnlib,
- [ --with-idnlib=ARG specify libidnkit],
+ [ --with-idnlib=ARG specify libidnkit],
idnlib="$withval", idnlib="no")
if test "$idnlib" = yes; then
AC_MSG_ERROR([You must specify ARG for --with-idnlib.])
@@ -2678,7 +2722,7 @@ AC_SUBST_FILE(BIND9_MAKE_RULES)
BIND9_MAKE_RULES=$BIND9_TOP_BUILDDIR/make/rules
. $srcdir/version
-BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}"
+BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}${PATCHVER:+.}${PATCHVER}${RELEASETYPE}${RELEASEVER}"
AC_SUBST(BIND9_VERSION)
if test -z "$ac_configure_args"; then
@@ -2964,6 +3008,12 @@ AC_CONFIG_FILES([
AC_OUTPUT
+if test "X$USE_OPENSSL" = "X"; then
+cat << \EOF
+BIND is being built without OpenSSL. This means it will not have DNSSEC support.
+EOF
+fi
+
if test "X$OPENSSL_WARNING" != "X"; then
cat << \EOF
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
diff --git a/contrib/bind9/doc/arm/Bv9ARM-book.xml b/contrib/bind9/doc/arm/Bv9ARM-book.xml
index 0875e57..29331d9 100644
--- a/contrib/bind9/doc/arm/Bv9ARM-book.xml
+++ b/contrib/bind9/doc/arm/Bv9ARM-book.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $Id: Bv9ARM-book.xml,v 1.380.14.15 2009/06/02 05:56:27 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.380.14.24.2.1 2010/02/25 05:39:32 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@@ -30,6 +30,7 @@
<year>2007</year>
<year>2008</year>
<year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -1679,6 +1680,11 @@ controls {
each dynamic update, because that would be too slow when a large
zone is updated frequently. Instead, the dump is delayed by
up to 15 minutes, allowing additional updates to take place.
+ During the dump process, transient files will be created
+ with the extensions <filename>.jnw</filename> and
+ <filename>.jbk</filename>; under ordinary circumstances, these
+ will be removed when the dump is complete, and can be safely
+ ignored.
</para>
<para>
@@ -2053,17 +2059,16 @@ nameserver 172.16.72.4
<sect3>
<title>Automatic Generation</title>
<para>
- The following command will generate a 128-bit (16 byte) HMAC-MD5
+ The following command will generate a 128-bit (16 byte) HMAC-SHA256
key as described above. Longer keys are better, but shorter keys
- are easier to read. Note that the maximum key length is 512 bits;
- keys longer than that will be digested with MD5 to produce a
- 128-bit key.
+ are easier to read. Note that the maximum key length is the digest
+ length, here 256 bits.
</para>
<para>
- <userinput>dnssec-keygen -a hmac-md5 -b 128 -n HOST host1-host2.</userinput>
+ <userinput>dnssec-keygen -a hmac-sha256 -b 128 -n HOST host1-host2.</userinput>
</para>
<para>
- The key is in the file <filename>Khost1-host2.+157+00000.private</filename>.
+ The key is in the file <filename>Khost1-host2.+163+00000.private</filename>.
Nothing directly uses this file, but the base-64 encoded string
following "<literal>Key:</literal>"
can be extracted from the file and used as a shared secret:
@@ -2105,18 +2110,16 @@ nameserver 172.16.72.4
<programlisting>
key host1-host2. {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "La/E5CjG9O+os1jq0a2jdA==";
};
</programlisting>
<para>
- The algorithm, <literal>hmac-md5</literal>, is the only one supported by <acronym>BIND</acronym>.
The secret is the one generated above. Since this is a secret, it
- is recommended that either <filename>named.conf</filename> be non-world
- readable, or the key directive be added to a non-world readable
- file that is included by
- <filename>named.conf</filename>.
+ is recommended that either <filename>named.conf</filename> be
+ non-world readable, or the key directive be added to a non-world
+ readable file that is included by <filename>named.conf</filename>.
</para>
<para>
At this point, the key is recognized. This means that if the
@@ -2445,14 +2448,17 @@ allow-update { key host1-host2. ;};
To enable <command>named</command> to respond appropriately
to DNS requests from DNSSEC aware clients,
<command>dnssec-enable</command> must be set to yes.
+ (This is the default setting.)
</para>
<para>
To enable <command>named</command> to validate answers from
- other servers both <command>dnssec-enable</command> and
- <command>dnssec-validation</command> must be set and some
- <command>trusted-keys</command> must be configured
- into <filename>named.conf</filename>.
+ other servers, the <command>dnssec-enable</command> and
+ <command>dnssec-validation</command> options must both be
+ set to yes (the default setting in <acronym>BIND</acronym> 9.5
+ and later), and at least one trust anchor must be configured
+ with a <command>trusted-keys</command> statement in
+ <filename>named.conf</filename>.
</para>
<para>
@@ -2531,6 +2537,41 @@ options {
the root key is not valid.
</note>
+ <para>
+ When DNSSEC validation is enabled and properly configured,
+ the resolver will reject any answers from signed, secure zones
+ which fail to validate, and will return SERVFAIL to the client.
+ </para>
+
+ <para>
+ Responses may fail to validate for any of several reasons,
+ including missing, expired, or invalid signatures, a key which
+ does not match the DS RRset in the parent zone, or an insecure
+ response from a zone which, according to its parent, should have
+ been secure.
+ </para>
+
+ <note>
+ <para>
+ When the validator receives a response from an unsigned zone
+ that has a signed parent, it must confirm with the parent
+ that the zone was intentionally left unsigned. It does
+ this by verifying, via signed and validated NSEC/NSEC3 records,
+ that the parent zone contains no DS records for the child.
+ </para>
+ <para>
+ If the validator <emphasis>can</emphasis> prove that the zone
+ is insecure, then the response is accepted. However, if it
+ cannot, then it must assume an insecure response to be a
+ forgery; it rejects the response and logs an error.
+ </para>
+ <para>
+ The logged error reads "insecurity proof failed" and
+ "got insecure response; parent indicates it should be secure".
+ (Prior to BIND 9.7, the logged error was "not insecure".
+ This referred to the zone, not the response.)
+ </para>
+ </note>
</sect2>
</sect1>
@@ -2539,10 +2580,9 @@ options {
<para>
<acronym>BIND</acronym> 9 fully supports all currently
- defined forms of IPv6
- name to address and address to name lookups. It will also use
- IPv6 addresses to make queries when running on an IPv6 capable
- system.
+ defined forms of IPv6 name to address and address to name
+ lookups. It will also use IPv6 addresses to make queries when
+ running on an IPv6 capable system.
</para>
<para>
@@ -4324,8 +4364,7 @@ category notify { null; };
<para>
Lame servers. These are misconfigurations
in remote servers, discovered by BIND 9 when trying to
- query
- those servers during resolution.
+ query those servers during resolution.
</para>
</entry>
</row>
@@ -4785,7 +4824,7 @@ category notify { null; };
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
<optional> use-queryport-pool <replaceable>yes_or_no</replaceable>; </optional>
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
- <optional> queryport-pool-interval <replaceable>number</replaceable>; </optional>
+ <optional> queryport-pool-updateinterval <replaceable>number</replaceable>; </optional>
<optional> max-transfer-time-in <replaceable>number</replaceable>; </optional>
<optional> max-transfer-time-out <replaceable>number</replaceable>; </optional>
<optional> max-transfer-idle-in <replaceable>number</replaceable>; </optional>
@@ -4826,7 +4865,7 @@ category notify { null; };
<optional> lame-ttl <replaceable>number</replaceable>; </optional>
<optional> max-ncache-ttl <replaceable>number</replaceable>; </optional>
<optional> max-cache-ttl <replaceable>number</replaceable>; </optional>
- <optional> sig-validity-interval <replaceable>number</replaceable> ; </optional>
+ <optional> sig-validity-interval <replaceable>number</replaceable> <optional><replaceable>number</replaceable></optional> ; </optional>
<optional> sig-signing-nodes <replaceable>number</replaceable> ; </optional>
<optional> sig-signing-signatures <replaceable>number</replaceable> ; </optional>
<optional> sig-signing-type <replaceable>number</replaceable> ; </optional>
@@ -4909,11 +4948,12 @@ category notify { null; };
<listitem>
<para>
When performing dynamic update of secure zones, the
- directory where the public and private key files should be
- found,
- if different than the current working directory. The
- directory specified
- must be an absolute path.
+ directory where the public and private DNSSEC key files
+ should be found, if different than the current working
+ directory. The directory specified must be an absolute
+ path. (Note that this option has no effect on the paths
+ for files containing non-DNSSEC keys such as the
+ <filename>rndc.key</filename>.
</para>
</listitem>
</varlistentry>
@@ -5874,13 +5914,15 @@ options {
If <userinput>yes</userinput>, then an
IPv4-mapped IPv6 address will match any address match
list entries that match the corresponding IPv4 address.
- Enabling this option is sometimes useful on IPv6-enabled
- Linux
- systems, to work around a kernel quirk that causes IPv4
- TCP connections such as zone transfers to be accepted
- on an IPv6 socket using mapped addresses, causing
- address match lists designed for IPv4 to fail to match.
- The use of this option for any other purpose is discouraged.
+ </para>
+ <para>
+ This option was introduced to work around a kernel quirk
+ in some operating systems that causes IPv4 TCP
+ connections, such as zone transfers, to be accepted on an
+ IPv6 socket using mapped addresses. This caused address
+ match lists designed for IPv4 to fail to match. However,
+ <command>named</command> now solves this problem
+ internally. The use of this option is discouraged.
</para>
</listitem>
</varlistentry>
@@ -7663,6 +7705,13 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<literal>1800</literal> (30 minutes).
</para>
+ <para>
+ Lame-ttl also controls the amount of time DNSSEC
+ validation failures are cached. There is a minimum
+ of 30 seconds applied to bad cache entries if the
+ lame-ttl is set to less than 30 seconds.
+ </para>
+
</listitem>
</varlistentry>
@@ -7919,7 +7968,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<listitem>
<para>
The delay, in seconds, between sending sets of notify
- messages for a zone. The default is zero.
+ messages for a zone. The default is five (5) seconds.
</para>
</listitem>
</varlistentry>
@@ -8271,7 +8320,7 @@ XXX: end of RFC1918 addresses #defined out -->
<optional> query-source-v6 <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
<optional> use-queryport-pool <replaceable>yes_or_no</replaceable>; </optional>
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
- <optional> queryport-pool-interval <replaceable>number</replaceable>; </optional>
+ <optional> queryport-pool-updateinterval <replaceable>number</replaceable>; </optional>
};
</programlisting>
@@ -8751,7 +8800,7 @@ view "external" {
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> zone-statistics <replaceable>yes_or_no</replaceable> ; </optional>
- <optional> sig-validity-interval <replaceable>number</replaceable> ; </optional>
+ <optional> sig-validity-interval <replaceable>number</replaceable> <optional><replaceable>number</replaceable></optional> ; </optional>
<optional> sig-signing-nodes <replaceable>number</replaceable> ; </optional>
<optional> sig-signing-signatures <replaceable>number</replaceable> ; </optional>
<optional> sig-signing-type <replaceable>number</replaceable> ; </optional>
@@ -11206,6 +11255,16 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
and <command>$TTL.</command>
</para>
<sect3>
+ <title>The <command>@</command> (at-sign)</title>
+ <para>
+ When used in the label (or name) field, the asperand or
+ at-sign (@) symbol represents the current origin.
+ At the start of the zone file, it is the
+ &lt;<varname>zone_name</varname>&gt; (followed by
+ trailing dot).
+ </para>
+ </sect3>
+ <sect3>
<title>The <command>$ORIGIN</command> Directive</title>
<para>
Syntax: <command>$ORIGIN</command>
@@ -11216,7 +11275,8 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
sets the domain name that will be appended to any
unqualified records. When a zone is first read in there
is an implicit <command>$ORIGIN</command>
- &lt;<varname>zone-name</varname>&gt;<command>.</command>
+ &lt;<varname>zone_name</varname>&gt;<command>.</command>
+ (followed by trailing dot).
The current <command>$ORIGIN</command> is appended to
the domain specified in the <command>$ORIGIN</command>
argument if it is not absolute.
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch01.html b/contrib/bind9/doc/arm/Bv9ARM.ch01.html
index 320a867..ea561e6 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch01.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch01.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch01.html,v 1.43.48.2 2009/04/03 01:52:22 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch01.html,v 1.43.48.4 2010/01/24 01:55:26 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,17 +45,17 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2563409">Scope of Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564388">Organization of This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564528">Conventions Used in This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564641">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2563412">Scope of Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564391">Organization of This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564531">Conventions Used in This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564712">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564662">DNS Fundamentals</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564696">Domains and Domain Names</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567170">Zones</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567246">Authoritative Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567419">Caching Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567549">Name Servers in Multiple Roles</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564733">DNS Fundamentals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564768">Domains and Domain Names</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567173">Zones</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567250">Authoritative Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567422">Caching Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567553">Name Servers in Multiple Roles</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -71,7 +71,7 @@
</p>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2563409"></a>Scope of Document</h2></div></div></div>
+<a name="id2563412"></a>Scope of Document</h2></div></div></div>
<p>
The Berkeley Internet Name Domain
(<acronym class="acronym">BIND</acronym>) implements a
@@ -87,7 +87,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564388"></a>Organization of This Document</h2></div></div></div>
+<a name="id2564391"></a>Organization of This Document</h2></div></div></div>
<p>
In this document, <span class="emphasis"><em>Chapter 1</em></span> introduces
the basic <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym> concepts. <span class="emphasis"><em>Chapter 2</em></span>
@@ -116,7 +116,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564528"></a>Conventions Used in This Document</h2></div></div></div>
+<a name="id2564531"></a>Conventions Used in This Document</h2></div></div></div>
<p>
In this document, we use the following general typographic
conventions:
@@ -243,7 +243,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564641"></a>The Domain Name System (<acronym class="acronym">DNS</acronym>)</h2></div></div></div>
+<a name="id2564712"></a>The Domain Name System (<acronym class="acronym">DNS</acronym>)</h2></div></div></div>
<p>
The purpose of this document is to explain the installation
and upkeep of the <acronym class="acronym">BIND</acronym> (Berkeley Internet
@@ -253,7 +253,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2564662"></a>DNS Fundamentals</h3></div></div></div>
+<a name="id2564733"></a>DNS Fundamentals</h3></div></div></div>
<p>
The Domain Name System (DNS) is a hierarchical, distributed
database. It stores information for mapping Internet host names to
@@ -275,7 +275,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2564696"></a>Domains and Domain Names</h3></div></div></div>
+<a name="id2564768"></a>Domains and Domain Names</h3></div></div></div>
<p>
The data stored in the DNS is identified by <span class="emphasis"><em>domain names</em></span> that are organized as a tree according to
organizational or administrative boundaries. Each node of the tree,
@@ -321,7 +321,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567170"></a>Zones</h3></div></div></div>
+<a name="id2567173"></a>Zones</h3></div></div></div>
<p>
To properly operate a name server, it is important to understand
the difference between a <span class="emphasis"><em>zone</em></span>
@@ -374,7 +374,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567246"></a>Authoritative Name Servers</h3></div></div></div>
+<a name="id2567250"></a>Authoritative Name Servers</h3></div></div></div>
<p>
Each zone is served by at least
one <span class="emphasis"><em>authoritative name server</em></span>,
@@ -391,7 +391,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567270"></a>The Primary Master</h4></div></div></div>
+<a name="id2567273"></a>The Primary Master</h4></div></div></div>
<p>
The authoritative server where the master copy of the zone
data is maintained is called the
@@ -411,7 +411,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567300"></a>Slave Servers</h4></div></div></div>
+<a name="id2567303"></a>Slave Servers</h4></div></div></div>
<p>
The other authoritative servers, the <span class="emphasis"><em>slave</em></span>
servers (also known as <span class="emphasis"><em>secondary</em></span> servers)
@@ -427,7 +427,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567389"></a>Stealth Servers</h4></div></div></div>
+<a name="id2567393"></a>Stealth Servers</h4></div></div></div>
<p>
Usually all of the zone's authoritative servers are listed in
NS records in the parent zone. These NS records constitute
@@ -462,7 +462,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567419"></a>Caching Name Servers</h3></div></div></div>
+<a name="id2567422"></a>Caching Name Servers</h3></div></div></div>
<p>
The resolver libraries provided by most operating systems are
<span class="emphasis"><em>stub resolvers</em></span>, meaning that they are not
@@ -489,7 +489,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567523"></a>Forwarding</h4></div></div></div>
+<a name="id2567526"></a>Forwarding</h4></div></div></div>
<p>
Even a caching name server does not necessarily perform
the complete recursive lookup itself. Instead, it can
@@ -516,7 +516,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567549"></a>Name Servers in Multiple Roles</h3></div></div></div>
+<a name="id2567553"></a>Name Servers in Multiple Roles</h3></div></div></div>
<p>
The <acronym class="acronym">BIND</acronym> name server can
simultaneously act as
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch02.html b/contrib/bind9/doc/arm/Bv9ARM.ch02.html
index 831e7a1..b279c67 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch02.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch02.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch02.html,v 1.38.56.1 2009/01/08 01:50:59 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch02.html,v 1.38.56.3 2010/01/24 01:55:25 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,16 +45,16 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567584">Hardware requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567610">CPU Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567623">Memory Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567854">Name Server Intensive Environment Issues</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567865">Supported Operating Systems</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567587">Hardware requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567613">CPU Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567626">Memory Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567721">Name Server Intensive Environment Issues</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567732">Supported Operating Systems</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567584"></a>Hardware requirements</h2></div></div></div>
+<a name="id2567587"></a>Hardware requirements</h2></div></div></div>
<p>
<acronym class="acronym">DNS</acronym> hardware requirements have
traditionally been quite modest.
@@ -73,7 +73,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567610"></a>CPU Requirements</h2></div></div></div>
+<a name="id2567613"></a>CPU Requirements</h2></div></div></div>
<p>
CPU requirements for <acronym class="acronym">BIND</acronym> 9 range from
i486-class machines
@@ -84,7 +84,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567623"></a>Memory Requirements</h2></div></div></div>
+<a name="id2567626"></a>Memory Requirements</h2></div></div></div>
<p>
The memory of the server has to be large enough to fit the
cache and zones loaded off disk. The <span><strong class="command">max-cache-size</strong></span>
@@ -107,7 +107,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567854"></a>Name Server Intensive Environment Issues</h2></div></div></div>
+<a name="id2567721"></a>Name Server Intensive Environment Issues</h2></div></div></div>
<p>
For name server intensive environments, there are two alternative
configurations that may be used. The first is where clients and
@@ -124,7 +124,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567865"></a>Supported Operating Systems</h2></div></div></div>
+<a name="id2567732"></a>Supported Operating Systems</h2></div></div></div>
<p>
ISC <acronym class="acronym">BIND</acronym> 9 compiles and runs on a large
number
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch03.html b/contrib/bind9/doc/arm/Bv9ARM.ch03.html
index 9964823..59d7e73 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch03.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch03.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch03.html,v 1.71.48.2 2009/04/03 01:52:21 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch03.html,v 1.71.48.4 2010/01/24 01:55:25 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,14 +47,14 @@
<dl>
<dt><span class="sect1"><a href="Bv9ARM.ch03.html#sample_configuration">Sample Configurations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567897">A Caching-only Name Server</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567913">An Authoritative-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567764">A Caching-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567780">An Authoritative-only Name Server</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568004">Load Balancing</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568358">Name Server Operations</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568007">Load Balancing</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568361">Name Server Operations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568363">Tools for Use With the Name Server Daemon</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570071">Signals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568366">Tools for Use With the Name Server Daemon</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570006">Signals</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -68,7 +68,7 @@
<a name="sample_configuration"></a>Sample Configurations</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567897"></a>A Caching-only Name Server</h3></div></div></div>
+<a name="id2567764"></a>A Caching-only Name Server</h3></div></div></div>
<p>
The following sample configuration is appropriate for a caching-only
name server for use by clients internal to a corporation. All
@@ -95,7 +95,7 @@ zone "0.0.127.in-addr.arpa" {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567913"></a>An Authoritative-only Name Server</h3></div></div></div>
+<a name="id2567780"></a>An Authoritative-only Name Server</h3></div></div></div>
<p>
This sample configuration is for an authoritative-only server
that is the master server for "<code class="filename">example.com</code>"
@@ -137,7 +137,7 @@ zone "eng.example.com" {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2568004"></a>Load Balancing</h2></div></div></div>
+<a name="id2568007"></a>Load Balancing</h2></div></div></div>
<p>
A primitive form of load balancing can be achieved in
the <acronym class="acronym">DNS</acronym> by using multiple records
@@ -280,10 +280,10 @@ zone "eng.example.com" {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2568358"></a>Name Server Operations</h2></div></div></div>
+<a name="id2568361"></a>Name Server Operations</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2568363"></a>Tools for Use With the Name Server Daemon</h3></div></div></div>
+<a name="id2568366"></a>Tools for Use With the Name Server Daemon</h3></div></div></div>
<p>
This section describes several indispensable diagnostic,
administrative and monitoring tools available to the system
@@ -749,7 +749,7 @@ controls {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2570071"></a>Signals</h3></div></div></div>
+<a name="id2570006"></a>Signals</h3></div></div></div>
<p>
Certain UNIX signals cause the name server to take specific
actions, as described in the following table. These signals can
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch04.html b/contrib/bind9/doc/arm/Bv9ARM.ch04.html
index 123098e..2be5791 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch04.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch04.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch04.html,v 1.87.48.2 2009/04/03 01:52:21 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch04.html,v 1.87.48.6 2010/01/24 01:55:26 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -49,29 +49,29 @@
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#dynamic_update">Dynamic Update</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#journal">The journal file</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#incremental_zone_transfers">Incremental Zone Transfers (IXFR)</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2564066">Split DNS</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564084">Example split DNS setup</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2570492">Split DNS</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2570510">Example split DNS setup</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#tsig">TSIG</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571141">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571214">Copying the Shared Secret to Both Machines</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571225">Informing the Servers of the Key's Existence</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571268">Instructing the Server to Use the Key</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571325">TSIG Key Based Access Control</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571510">Errors</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571082">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571156">Copying the Shared Secret to Both Machines</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571166">Informing the Servers of the Key's Existence</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571203">Instructing the Server to Use the Key</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571260">TSIG Key Based Access Control</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571445">Errors</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571524">TKEY</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571709">SIG(0)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571459">TKEY</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571576">SIG(0)</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#DNSSEC">DNSSEC</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571778">Generating Keys</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571925">Signing the Zone</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572006">Configuring Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571644">Generating Keys</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571792">Signing the Zone</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571873">Configuring Servers</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572220">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572110">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572282">Address Lookups Using AAAA Records</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572304">Address to Name Lookups Using Nibble Format</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572172">Address Lookups Using AAAA Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572194">Address to Name Lookups Using Nibble Format</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -149,6 +149,11 @@
each dynamic update, because that would be too slow when a large
zone is updated frequently. Instead, the dump is delayed by
up to 15 minutes, allowing additional updates to take place.
+ During the dump process, transient files will be created
+ with the extensions <code class="filename">.jnw</code> and
+ <code class="filename">.jbk</code>; under ordinary circumstances, these
+ will be removed when the dump is complete, and can be safely
+ ignored.
</p>
<p>
When a server is restarted after a shutdown or crash, it will replay
@@ -210,7 +215,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564066"></a>Split DNS</h2></div></div></div>
+<a name="id2570492"></a>Split DNS</h2></div></div></div>
<p>
Setting up different views, or visibility, of the DNS space to
internal and external resolvers is usually referred to as a
@@ -240,7 +245,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2564084"></a>Example split DNS setup</h3></div></div></div>
+<a name="id2570510"></a>Example split DNS setup</h3></div></div></div>
<p>
Let's say a company named <span class="emphasis"><em>Example, Inc.</em></span>
(<code class="literal">example.com</code>)
@@ -486,7 +491,7 @@ nameserver 172.16.72.4
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571141"></a>Generate Shared Keys for Each Pair of Hosts</h3></div></div></div>
+<a name="id2571082"></a>Generate Shared Keys for Each Pair of Hosts</h3></div></div></div>
<p>
A shared secret is generated to be shared between <span class="emphasis"><em>host1</em></span> and <span class="emphasis"><em>host2</em></span>.
An arbitrary key name is chosen: "host1-host2.". The key name must
@@ -494,19 +499,18 @@ nameserver 172.16.72.4
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2571158"></a>Automatic Generation</h4></div></div></div>
+<a name="id2571099"></a>Automatic Generation</h4></div></div></div>
<p>
- The following command will generate a 128-bit (16 byte) HMAC-MD5
+ The following command will generate a 128-bit (16 byte) HMAC-SHA256
key as described above. Longer keys are better, but shorter keys
- are easier to read. Note that the maximum key length is 512 bits;
- keys longer than that will be digested with MD5 to produce a
- 128-bit key.
+ are easier to read. Note that the maximum key length is the digest
+ length, here 256 bits.
</p>
<p>
- <strong class="userinput"><code>dnssec-keygen -a hmac-md5 -b 128 -n HOST host1-host2.</code></strong>
+ <strong class="userinput"><code>dnssec-keygen -a hmac-sha256 -b 128 -n HOST host1-host2.</code></strong>
</p>
<p>
- The key is in the file <code class="filename">Khost1-host2.+157+00000.private</code>.
+ The key is in the file <code class="filename">Khost1-host2.+163+00000.private</code>.
Nothing directly uses this file, but the base-64 encoded string
following "<code class="literal">Key:</code>"
can be extracted from the file and used as a shared secret:
@@ -519,7 +523,7 @@ nameserver 172.16.72.4
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2571196"></a>Manual Generation</h4></div></div></div>
+<a name="id2571138"></a>Manual Generation</h4></div></div></div>
<p>
The shared secret is simply a random sequence of bits, encoded
in base-64. Most ASCII strings are valid base-64 strings (assuming
@@ -534,7 +538,7 @@ nameserver 172.16.72.4
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571214"></a>Copying the Shared Secret to Both Machines</h3></div></div></div>
+<a name="id2571156"></a>Copying the Shared Secret to Both Machines</h3></div></div></div>
<p>
This is beyond the scope of DNS. A secure transport mechanism
should be used. This could be secure FTP, ssh, telephone, etc.
@@ -542,7 +546,7 @@ nameserver 172.16.72.4
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571225"></a>Informing the Servers of the Key's Existence</h3></div></div></div>
+<a name="id2571166"></a>Informing the Servers of the Key's Existence</h3></div></div></div>
<p>
Imagine <span class="emphasis"><em>host1</em></span> and <span class="emphasis"><em>host 2</em></span>
are
@@ -550,17 +554,15 @@ nameserver 172.16.72.4
</p>
<pre class="programlisting">
key host1-host2. {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "La/E5CjG9O+os1jq0a2jdA==";
};
</pre>
<p>
- The algorithm, <code class="literal">hmac-md5</code>, is the only one supported by <acronym class="acronym">BIND</acronym>.
The secret is the one generated above. Since this is a secret, it
- is recommended that either <code class="filename">named.conf</code> be non-world
- readable, or the key directive be added to a non-world readable
- file that is included by
- <code class="filename">named.conf</code>.
+ is recommended that either <code class="filename">named.conf</code> be
+ non-world readable, or the key directive be added to a non-world
+ readable file that is included by <code class="filename">named.conf</code>.
</p>
<p>
At this point, the key is recognized. This means that if the
@@ -571,7 +573,7 @@ key host1-host2. {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571268"></a>Instructing the Server to Use the Key</h3></div></div></div>
+<a name="id2571203"></a>Instructing the Server to Use the Key</h3></div></div></div>
<p>
Since keys are shared between two hosts only, the server must
be told when keys are to be used. The following is added to the <code class="filename">named.conf</code> file
@@ -603,7 +605,7 @@ server 10.1.2.3 {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571325"></a>TSIG Key Based Access Control</h3></div></div></div>
+<a name="id2571260"></a>TSIG Key Based Access Control</h3></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> allows IP addresses and ranges
to be specified in ACL
@@ -631,7 +633,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571510"></a>Errors</h3></div></div></div>
+<a name="id2571445"></a>Errors</h3></div></div></div>
<p>
The processing of TSIG signed messages can result in
several errors. If a signed message is sent to a non-TSIG aware
@@ -657,7 +659,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2571524"></a>TKEY</h2></div></div></div>
+<a name="id2571459"></a>TKEY</h2></div></div></div>
<p><span><strong class="command">TKEY</strong></span>
is a mechanism for automatically generating a shared secret
between two hosts. There are several "modes" of
@@ -693,7 +695,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2571709"></a>SIG(0)</h2></div></div></div>
+<a name="id2571576"></a>SIG(0)</h2></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> 9 partially supports DNSSEC SIG(0)
transaction signatures as specified in RFC 2535 and RFC 2931.
@@ -754,7 +756,7 @@ allow-update { key host1-host2. ;};
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571778"></a>Generating Keys</h3></div></div></div>
+<a name="id2571644"></a>Generating Keys</h3></div></div></div>
<p>
The <span><strong class="command">dnssec-keygen</strong></span> program is used to
generate keys.
@@ -810,7 +812,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571925"></a>Signing the Zone</h3></div></div></div>
+<a name="id2571792"></a>Signing the Zone</h3></div></div></div>
<p>
The <span><strong class="command">dnssec-signzone</strong></span> program is used
to sign a zone.
@@ -852,18 +854,21 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572006"></a>Configuring Servers</h3></div></div></div>
+<a name="id2571873"></a>Configuring Servers</h3></div></div></div>
<p>
To enable <span><strong class="command">named</strong></span> to respond appropriately
to DNS requests from DNSSEC aware clients,
<span><strong class="command">dnssec-enable</strong></span> must be set to yes.
+ (This is the default setting.)
</p>
<p>
To enable <span><strong class="command">named</strong></span> to validate answers from
- other servers both <span><strong class="command">dnssec-enable</strong></span> and
- <span><strong class="command">dnssec-validation</strong></span> must be set and some
- <span><strong class="command">trusted-keys</strong></span> must be configured
- into <code class="filename">named.conf</code>.
+ other servers, the <span><strong class="command">dnssec-enable</strong></span> and
+ <span><strong class="command">dnssec-validation</strong></span> options must both be
+ set to yes (the default setting in <acronym class="acronym">BIND</acronym> 9.5
+ and later), and at least one trust anchor must be configured
+ with a <span><strong class="command">trusted-keys</strong></span> statement in
+ <code class="filename">named.conf</code>.
</p>
<p>
<span><strong class="command">trusted-keys</strong></span> are copies of DNSKEY RRs
@@ -936,17 +941,50 @@ options {
None of the keys listed in this example are valid. In particular,
the root key is not valid.
</div>
+<p>
+ When DNSSEC validation is enabled and properly configured,
+ the resolver will reject any answers from signed, secure zones
+ which fail to validate, and will return SERVFAIL to the client.
+ </p>
+<p>
+ Responses may fail to validate for any of several reasons,
+ including missing, expired, or invalid signatures, a key which
+ does not match the DS RRset in the parent zone, or an insecure
+ response from a zone which, according to its parent, should have
+ been secure.
+ </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>
+<p>
+ When the validator receives a response from an unsigned zone
+ that has a signed parent, it must confirm with the parent
+ that the zone was intentionally left unsigned. It does
+ this by verifying, via signed and validated NSEC/NSEC3 records,
+ that the parent zone contains no DS records for the child.
+ </p>
+<p>
+ If the validator <span class="emphasis"><em>can</em></span> prove that the zone
+ is insecure, then the response is accepted. However, if it
+ cannot, then it must assume an insecure response to be a
+ forgery; it rejects the response and logs an error.
+ </p>
+<p>
+ The logged error reads "insecurity proof failed" and
+ "got insecure response; parent indicates it should be secure".
+ (Prior to BIND 9.7, the logged error was "not insecure".
+ This referred to the zone, not the response.)
+ </p>
+</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2572220"></a>IPv6 Support in <acronym class="acronym">BIND</acronym> 9</h2></div></div></div>
+<a name="id2572110"></a>IPv6 Support in <acronym class="acronym">BIND</acronym> 9</h2></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> 9 fully supports all currently
- defined forms of IPv6
- name to address and address to name lookups. It will also use
- IPv6 addresses to make queries when running on an IPv6 capable
- system.
+ defined forms of IPv6 name to address and address to name
+ lookups. It will also use IPv6 addresses to make queries when
+ running on an IPv6 capable system.
</p>
<p>
For forward lookups, <acronym class="acronym">BIND</acronym> 9 supports
@@ -979,7 +1017,7 @@ options {
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572282"></a>Address Lookups Using AAAA Records</h3></div></div></div>
+<a name="id2572172"></a>Address Lookups Using AAAA Records</h3></div></div></div>
<p>
The IPv6 AAAA record is a parallel to the IPv4 A record,
and, unlike the deprecated A6 record, specifies the entire
@@ -998,7 +1036,7 @@ host 3600 IN AAAA 2001:db8::1
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572304"></a>Address to Name Lookups Using Nibble Format</h3></div></div></div>
+<a name="id2572194"></a>Address to Name Lookups Using Nibble Format</h3></div></div></div>
<p>
When looking up an address in nibble format, the address
components are simply reversed, just as in IPv4, and
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch05.html b/contrib/bind9/doc/arm/Bv9ARM.ch05.html
index addc97a..e84781f 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch05.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch05.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch05.html,v 1.71.48.2 2009/04/03 01:52:21 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch05.html,v 1.71.48.6 2010/01/24 01:55:26 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,13 +45,13 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572337">The Lightweight Resolver Library</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572227">The Lightweight Resolver Library</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch05.html#lwresd">Running a Resolver Daemon</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2572337"></a>The Lightweight Resolver Library</h2></div></div></div>
+<a name="id2572227"></a>The Lightweight Resolver Library</h2></div></div></div>
<p>
Traditionally applications have been linked with a stub resolver
library that sends recursive DNS queries to a local caching name
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch06.html b/contrib/bind9/doc/arm/Bv9ARM.ch06.html
index 46fd0dd..9e0667e 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch06.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch06.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch06.html,v 1.201.14.9 2009/06/03 01:54:40 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch06.html,v 1.201.14.18.2.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -48,55 +48,55 @@
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#configuration_file_elements">Configuration File Elements</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#address_match_lists">Address Match Lists</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573716">Comment Syntax</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573606">Comment Syntax</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#Configuration_File_Grammar">Configuration File Grammar</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574346"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574305"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#acl"><span><strong class="command">acl</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574536"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574494"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#controls_statement_definition_and_usage"><span><strong class="command">controls</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574965"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574982"><span><strong class="command">include</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574923"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574940"><span><strong class="command">include</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575005"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575029"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575120"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575245"><span><strong class="command">logging</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574964"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574987"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575078"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575204"><span><strong class="command">logging</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577306"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577448"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577512"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577556"><span><strong class="command">masters</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577401"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577475"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577539"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577582"><span><strong class="command">masters</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577571"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577597"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#options"><span><strong class="command">options</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_grammar"><span><strong class="command">server</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_definition_and_usage"><span><strong class="command">server</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#statschannels"><span><strong class="command">statistics-channels</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586902"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586877"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586988"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587040"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586964"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587083"><span><strong class="command">trusted-keys</strong></span> Statement Definition
and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#view_statement_grammar"><span><strong class="command">view</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587122"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587165"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zone_statement_grammar"><span><strong class="command">zone</strong></span>
Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588659"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588638"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2591138">Zone File</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2591117">Zone File</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#types_of_resource_records_and_when_to_use_them">Types of Resource Records and When to Use Them</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593300">Discussion of MX Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593348">Discussion of MX Records</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#Setting_TTLs">Setting TTLs</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593915">Inverse Mapping in IPv4</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594042">Other Zone File Directives</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594368"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593895">Inverse Mapping in IPv4</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594090">Other Zone File Directives</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594500"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zonefile_format">Additional File Formats</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#statistics">BIND9 Statistics</a></span></dt>
@@ -461,7 +461,7 @@
<a name="address_match_lists"></a>Address Match Lists</h3></div></div></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573414"></a>Syntax</h4></div></div></div>
+<a name="id2573372"></a>Syntax</h4></div></div></div>
<pre class="programlisting"><code class="varname">address_match_list</code> = address_match_list_element ;
[<span class="optional"> address_match_list_element; ... </span>]
<code class="varname">address_match_list_element</code> = [<span class="optional"> ! </span>] (ip_address [<span class="optional">/length</span>] |
@@ -470,7 +470,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573442"></a>Definition and Usage</h4></div></div></div>
+<a name="id2573468"></a>Definition and Usage</h4></div></div></div>
<p>
Address match lists are primarily used to determine access
control for various server operations. They are also used in
@@ -554,7 +554,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2573716"></a>Comment Syntax</h3></div></div></div>
+<a name="id2573606"></a>Comment Syntax</h3></div></div></div>
<p>
The <acronym class="acronym">BIND</acronym> 9 comment syntax allows for
comments to appear
@@ -564,7 +564,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573731"></a>Syntax</h4></div></div></div>
+<a name="id2573621"></a>Syntax</h4></div></div></div>
<p>
</p>
<pre class="programlisting">/* This is a <acronym class="acronym">BIND</acronym> comment as in C */</pre>
@@ -579,7 +579,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573761"></a>Definition and Usage</h4></div></div></div>
+<a name="id2573651"></a>Definition and Usage</h4></div></div></div>
<p>
Comments may appear anywhere that whitespace may appear in
a <acronym class="acronym">BIND</acronym> configuration file.
@@ -820,7 +820,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574346"></a><span><strong class="command">acl</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574305"></a><span><strong class="command">acl</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">acl</strong></span> acl-name {
address_match_list
};
@@ -902,7 +902,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574536"></a><span><strong class="command">controls</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574494"></a><span><strong class="command">controls</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">controls</strong></span> {
[ inet ( ip_addr | * ) [ port ip_port ] allow { <em class="replaceable"><code> address_match_list </code></em> }
keys { <em class="replaceable"><code>key_list</code></em> }; ]
@@ -1024,12 +1024,12 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574965"></a><span><strong class="command">include</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574923"></a><span><strong class="command">include</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">include</strong></span> <em class="replaceable"><code>filename</code></em>;</pre>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574982"></a><span><strong class="command">include</strong></span> Statement Definition and
+<a name="id2574940"></a><span><strong class="command">include</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">include</strong></span> statement inserts the
@@ -1044,7 +1044,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575005"></a><span><strong class="command">key</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574964"></a><span><strong class="command">key</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">key</strong></span> <em class="replaceable"><code>key_id</code></em> {
algorithm <em class="replaceable"><code>string</code></em>;
secret <em class="replaceable"><code>string</code></em>;
@@ -1053,7 +1053,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575029"></a><span><strong class="command">key</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2574987"></a><span><strong class="command">key</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">key</strong></span> statement defines a shared
secret key for use with TSIG (see <a href="Bv9ARM.ch04.html#tsig" title="TSIG">the section called &#8220;TSIG&#8221;</a>)
@@ -1100,7 +1100,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575120"></a><span><strong class="command">logging</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575078"></a><span><strong class="command">logging</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">logging</strong></span> {
[ <span><strong class="command">channel</strong></span> <em class="replaceable"><code>channel_name</code></em> {
( <span><strong class="command">file</strong></span> <em class="replaceable"><code>path_name</code></em>
@@ -1124,7 +1124,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575245"></a><span><strong class="command">logging</strong></span> Statement Definition and
+<a name="id2575204"></a><span><strong class="command">logging</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">logging</strong></span> statement configures a
@@ -1158,7 +1158,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2575298"></a>The <span><strong class="command">channel</strong></span> Phrase</h4></div></div></div>
+<a name="id2575256"></a>The <span><strong class="command">channel</strong></span> Phrase</h4></div></div></div>
<p>
All log output goes to one or more <span class="emphasis"><em>channels</em></span>;
you can make as many of them as you want.
@@ -1666,8 +1666,7 @@ category notify { null; };
<p>
Lame servers. These are misconfigurations
in remote servers, discovered by BIND 9 when trying to
- query
- those servers during resolution.
+ query those servers during resolution.
</p>
</td>
</tr>
@@ -1724,7 +1723,7 @@ category notify { null; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2576793"></a>The <span><strong class="command">query-errors</strong></span> Category</h4></div></div></div>
+<a name="id2576820"></a>The <span><strong class="command">query-errors</strong></span> Category</h4></div></div></div>
<p>
The <span><strong class="command">query-errors</strong></span> category is
specifically intended for debugging purposes: To identify
@@ -1944,7 +1943,7 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577306"></a><span><strong class="command">lwres</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577401"></a><span><strong class="command">lwres</strong></span> Statement Grammar</h3></div></div></div>
<p>
This is the grammar of the <span><strong class="command">lwres</strong></span>
statement in the <code class="filename">named.conf</code> file:
@@ -1959,7 +1958,7 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577448"></a><span><strong class="command">lwres</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2577475"></a><span><strong class="command">lwres</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">lwres</strong></span> statement configures the
name
@@ -2010,14 +2009,14 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577512"></a><span><strong class="command">masters</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577539"></a><span><strong class="command">masters</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting">
<span><strong class="command">masters</strong></span> <em class="replaceable"><code>name</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> | <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] };
</pre>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577556"></a><span><strong class="command">masters</strong></span> Statement Definition and
+<a name="id2577582"></a><span><strong class="command">masters</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p><span><strong class="command">masters</strong></span>
lists allow for a common set of masters to be easily used by
@@ -2026,7 +2025,7 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577571"></a><span><strong class="command">options</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577597"></a><span><strong class="command">options</strong></span> Statement Grammar</h3></div></div></div>
<p>
This is the grammar of the <span><strong class="command">options</strong></span>
statement in the <code class="filename">named.conf</code> file:
@@ -2115,7 +2114,7 @@ category notify { null; };
[<span class="optional"> port ( <em class="replaceable"><code>ip_port</code></em> | <em class="replaceable"><code>*</code></em> ) </span>] ) ; </span>]
[<span class="optional"> use-queryport-pool <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> queryport-pool-ports <em class="replaceable"><code>number</code></em>; </span>]
- [<span class="optional"> queryport-pool-interval <em class="replaceable"><code>number</code></em>; </span>]
+ [<span class="optional"> queryport-pool-updateinterval <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-transfer-time-in <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-transfer-time-out <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-transfer-idle-in <em class="replaceable"><code>number</code></em>; </span>]
@@ -2156,7 +2155,7 @@ category notify { null; };
[<span class="optional"> lame-ttl <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-ncache-ttl <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-cache-ttl <em class="replaceable"><code>number</code></em>; </span>]
- [<span class="optional"> sig-validity-interval <em class="replaceable"><code>number</code></em> ; </span>]
+ [<span class="optional"> sig-validity-interval <em class="replaceable"><code>number</code></em> [<span class="optional"><em class="replaceable"><code>number</code></em></span>] ; </span>]
[<span class="optional"> sig-signing-nodes <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> sig-signing-signatures <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> sig-signing-type <em class="replaceable"><code>number</code></em> ; </span>]
@@ -2228,11 +2227,12 @@ category notify { null; };
<dt><span class="term"><span><strong class="command">key-directory</strong></span></span></dt>
<dd><p>
When performing dynamic update of secure zones, the
- directory where the public and private key files should be
- found,
- if different than the current working directory. The
- directory specified
- must be an absolute path.
+ directory where the public and private DNSSEC key files
+ should be found, if different than the current working
+ directory. The directory specified must be an absolute
+ path. (Note that this option has no effect on the paths
+ for files containing non-DNSSEC keys such as the
+ <code class="filename">rndc.key</code>.
</p></dd>
<dt><span class="term"><span><strong class="command">named-xfer</strong></span></span></dt>
<dd><p>
@@ -2990,18 +2990,22 @@ options {
</p>
</dd>
<dt><span class="term"><span><strong class="command">match-mapped-addresses</strong></span></span></dt>
-<dd><p>
+<dd>
+<p>
If <strong class="userinput"><code>yes</code></strong>, then an
IPv4-mapped IPv6 address will match any address match
list entries that match the corresponding IPv4 address.
- Enabling this option is sometimes useful on IPv6-enabled
- Linux
- systems, to work around a kernel quirk that causes IPv4
- TCP connections such as zone transfers to be accepted
- on an IPv6 socket using mapped addresses, causing
- address match lists designed for IPv4 to fail to match.
- The use of this option for any other purpose is discouraged.
- </p></dd>
+ </p>
+<p>
+ This option was introduced to work around a kernel quirk
+ in some operating systems that causes IPv4 TCP
+ connections, such as zone transfers, to be accepted on an
+ IPv6 socket using mapped addresses. This caused address
+ match lists designed for IPv4 to fail to match. However,
+ <span><strong class="command">named</strong></span> now solves this problem
+ internally. The use of this option is discouraged.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">ixfr-from-differences</strong></span></span></dt>
<dd>
<p>
@@ -3181,7 +3185,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2581747"></a>Forwarding</h4></div></div></div>
+<a name="id2581856"></a>Forwarding</h4></div></div></div>
<p>
The forwarding facility can be used to create a large site-wide
cache on a few servers, reducing traffic over links to external
@@ -3225,7 +3229,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2581874"></a>Dual-stack Servers</h4></div></div></div>
+<a name="id2581914"></a>Dual-stack Servers</h4></div></div></div>
<p>
Dual-stack servers are used as servers of last resort to work
around
@@ -3422,7 +3426,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2582379"></a>Interfaces</h4></div></div></div>
+<a name="id2582420"></a>Interfaces</h4></div></div></div>
<p>
The interfaces and ports that the server will answer queries
from may be specified using the <span><strong class="command">listen-on</strong></span> option. <span><strong class="command">listen-on</strong></span> takes
@@ -3874,7 +3878,7 @@ avoid-v6-udp-ports {};
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2583582"></a>UDP Port Lists</h4></div></div></div>
+<a name="id2583691"></a>UDP Port Lists</h4></div></div></div>
<p>
<span><strong class="command">use-v4-udp-ports</strong></span>,
<span><strong class="command">avoid-v4-udp-ports</strong></span>,
@@ -3916,7 +3920,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2583642"></a>Operating System Resource Limits</h4></div></div></div>
+<a name="id2583751"></a>Operating System Resource Limits</h4></div></div></div>
<p>
The server's usage of many system resources can be limited.
Scaled values are allowed when specifying resource limits. For
@@ -4078,7 +4082,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2584065"></a>Periodic Task Intervals</h4></div></div></div>
+<a name="id2584173"></a>Periodic Task Intervals</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">cleaning-interval</strong></span></span></dt>
<dd><p>
@@ -4393,14 +4397,22 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<a name="tuning"></a>Tuning</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">lame-ttl</strong></span></span></dt>
-<dd><p>
+<dd>
+<p>
Sets the number of seconds to cache a
lame server indication. 0 disables caching. (This is
<span class="bold"><strong>NOT</strong></span> recommended.)
The default is <code class="literal">600</code> (10 minutes) and the
maximum value is
<code class="literal">1800</code> (30 minutes).
- </p></dd>
+ </p>
+<p>
+ Lame-ttl also controls the amount of time DNSSEC
+ validation failures are cached. There is a minimum
+ of 30 seconds applied to bad cache entries if the
+ lame-ttl is set to less than 30 seconds.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">max-ncache-ttl</strong></span></span></dt>
<dd><p>
To reduce network traffic and increase performance,
@@ -4602,7 +4614,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<dt><span class="term"><span><strong class="command">notify-delay</strong></span></span></dt>
<dd><p>
The delay, in seconds, between sending sets of notify
- messages for a zone. The default is zero.
+ messages for a zone. The default is five (5) seconds.
</p></dd>
</dl></div>
</div>
@@ -4872,7 +4884,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
[<span class="optional"> query-source-v6 [<span class="optional"> address ( <em class="replaceable"><code>ip_addr</code></em> | <em class="replaceable"><code>*</code></em> ) </span>] [<span class="optional"> port ( <em class="replaceable"><code>ip_port</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]; </span>]
[<span class="optional"> use-queryport-pool <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> queryport-pool-ports <em class="replaceable"><code>number</code></em>; </span>]
- [<span class="optional"> queryport-pool-interval <em class="replaceable"><code>number</code></em>; </span>]
+ [<span class="optional"> queryport-pool-updateinterval <em class="replaceable"><code>number</code></em>; </span>]
};
</pre>
</div>
@@ -5056,7 +5068,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2586902"></a><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<a name="id2586877"></a><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">statistics-channels</strong></span> statement
@@ -5107,7 +5119,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2586988"></a><span><strong class="command">trusted-keys</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2586964"></a><span><strong class="command">trusted-keys</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">trusted-keys</strong></span> {
<em class="replaceable"><code>string</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ;
[<span class="optional"> <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ; [<span class="optional">...</span>]</span>]
@@ -5116,7 +5128,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587040"></a><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<a name="id2587083"></a><span><strong class="command">trusted-keys</strong></span> Statement Definition
and Usage</h3></div></div></div>
<p>
The <span><strong class="command">trusted-keys</strong></span> statement defines
@@ -5162,7 +5174,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587122"></a><span><strong class="command">view</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2587165"></a><span><strong class="command">view</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">view</strong></span> statement is a powerful
feature
@@ -5315,7 +5327,7 @@ view "external" {
[<span class="optional"> notify-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> notify-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> zone-statistics <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
- [<span class="optional"> sig-validity-interval <em class="replaceable"><code>number</code></em> ; </span>]
+ [<span class="optional"> sig-validity-interval <em class="replaceable"><code>number</code></em> [<span class="optional"><em class="replaceable"><code>number</code></em></span>] ; </span>]
[<span class="optional"> sig-signing-nodes <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> sig-signing-signatures <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> sig-signing-type <em class="replaceable"><code>number</code></em> ; </span>]
@@ -5428,10 +5440,10 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2588659"></a><span><strong class="command">zone</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2588638"></a><span><strong class="command">zone</strong></span> Statement Definition and Usage</h3></div></div></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2588666"></a>Zone Types</h4></div></div></div>
+<a name="id2588646"></a>Zone Types</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -5642,7 +5654,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2589094"></a>Class</h4></div></div></div>
+<a name="id2589005"></a>Class</h4></div></div></div>
<p>
The zone's name may optionally be followed by a class. If
a class is not specified, class <code class="literal">IN</code> (for <code class="varname">Internet</code>),
@@ -5664,7 +5676,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2589127"></a>Zone Options</h4></div></div></div>
+<a name="id2589038"></a>Zone Options</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">allow-notify</strong></span></span></dt>
<dd><p>
@@ -6243,7 +6255,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2591138"></a>Zone File</h2></div></div></div>
+<a name="id2591117"></a>Zone File</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="types_of_resource_records_and_when_to_use_them"></a>Types of Resource Records and When to Use Them</h3></div></div></div>
@@ -6256,7 +6268,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2591156"></a>Resource Records</h4></div></div></div>
+<a name="id2591204"></a>Resource Records</h4></div></div></div>
<p>
A domain name identifies a node. Each node has a set of
resource information, which may be empty. The set of resource
@@ -6993,7 +7005,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2592779"></a>Textual expression of RRs</h4></div></div></div>
+<a name="id2592759"></a>Textual expression of RRs</h4></div></div></div>
<p>
RRs are represented in binary form in the packets of the DNS
protocol, and are usually represented in highly encoded form
@@ -7196,7 +7208,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2593300"></a>Discussion of MX Records</h3></div></div></div>
+<a name="id2593348"></a>Discussion of MX Records</h3></div></div></div>
<p>
As described above, domain servers store information as a
series of resource records, each of which contains a particular
@@ -7452,7 +7464,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2593915"></a>Inverse Mapping in IPv4</h3></div></div></div>
+<a name="id2593895"></a>Inverse Mapping in IPv4</h3></div></div></div>
<p>
Reverse name resolution (that is, translation from IP address
to name) is achieved by means of the <span class="emphasis"><em>in-addr.arpa</em></span> domain
@@ -7513,7 +7525,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2594042"></a>Other Zone File Directives</h3></div></div></div>
+<a name="id2594090"></a>Other Zone File Directives</h3></div></div></div>
<p>
The Master File Format was initially defined in RFC 1035 and
has subsequently been extended. While the Master File Format
@@ -7528,7 +7540,18 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594201"></a>The <span><strong class="command">$ORIGIN</strong></span> Directive</h4></div></div></div>
+<a name="id2594113"></a>The <span><strong class="command">@</strong></span> (at-sign)</h4></div></div></div>
+<p>
+ When used in the label (or name) field, the asperand or
+ at-sign (@) symbol represents the current origin.
+ At the start of the zone file, it is the
+ &lt;<code class="varname">zone_name</code>&gt; (followed by
+ trailing dot).
+ </p>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2594129"></a>The <span><strong class="command">$ORIGIN</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$ORIGIN</strong></span>
<em class="replaceable"><code>domain-name</code></em>
@@ -7538,7 +7561,8 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
sets the domain name that will be appended to any
unqualified records. When a zone is first read in there
is an implicit <span><strong class="command">$ORIGIN</strong></span>
- &lt;<code class="varname">zone-name</code>&gt;<span><strong class="command">.</strong></span>
+ &lt;<code class="varname">zone_name</code>&gt;<span><strong class="command">.</strong></span>
+ (followed by trailing dot).
The current <span><strong class="command">$ORIGIN</strong></span> is appended to
the domain specified in the <span><strong class="command">$ORIGIN</strong></span>
argument if it is not absolute.
@@ -7556,7 +7580,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594262"></a>The <span><strong class="command">$INCLUDE</strong></span> Directive</h4></div></div></div>
+<a name="id2594326"></a>The <span><strong class="command">$INCLUDE</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$INCLUDE</strong></span>
<em class="replaceable"><code>filename</code></em>
@@ -7592,7 +7616,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594331"></a>The <span><strong class="command">$TTL</strong></span> Directive</h4></div></div></div>
+<a name="id2594395"></a>The <span><strong class="command">$TTL</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$TTL</strong></span>
<em class="replaceable"><code>default-ttl</code></em>
@@ -7611,7 +7635,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2594368"></a><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</h3></div></div></div>
+<a name="id2594500"></a><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</h3></div></div></div>
<p>
Syntax: <span><strong class="command">$GENERATE</strong></span>
<em class="replaceable"><code>range</code></em>
@@ -8002,7 +8026,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2595364"></a>Name Server Statistics Counters</h4></div></div></div>
+<a name="id2595428"></a>Name Server Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -8559,7 +8583,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2596905"></a>Zone Maintenance Statistics Counters</h4></div></div></div>
+<a name="id2596901"></a>Zone Maintenance Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -8713,7 +8737,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2597288"></a>Resolver Statistics Counters</h4></div></div></div>
+<a name="id2597284"></a>Resolver Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -9089,7 +9113,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2598307"></a>Socket I/O Statistics Counters</h4></div></div></div>
+<a name="id2598302"></a>Socket I/O Statistics Counters</h4></div></div></div>
<p>
Socket I/O statistics counters are defined per socket
types, which are
@@ -9244,7 +9268,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2598817"></a>Compatibility with <span class="emphasis"><em>BIND</em></span> 8 Counters</h4></div></div></div>
+<a name="id2598812"></a>Compatibility with <span class="emphasis"><em>BIND</em></span> 8 Counters</h4></div></div></div>
<p>
Most statistics counters that were available
in <span><strong class="command">BIND</strong></span> 8 are also supported in
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch07.html b/contrib/bind9/doc/arm/Bv9ARM.ch07.html
index ca12cb3..91994f3 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch07.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch07.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch07.html,v 1.178.14.6 2009/06/03 01:54:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch07.html,v 1.178.14.13.2.1 2010/02/25 12:16:47 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -46,10 +46,10 @@
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#Access_Control_Lists">Access Control Lists</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2598990"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2599054"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599072">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599268">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599136">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599264">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#dynamic_update_security">Dynamic Update Security</a></span></dt>
</dl>
@@ -119,7 +119,7 @@ zone "example.com" {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2598990"></a><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span>
+<a name="id2599054"></a><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span>
</h2></div></div></div>
<p>
On UNIX servers, it is possible to run <acronym class="acronym">BIND</acronym>
@@ -145,7 +145,7 @@ zone "example.com" {
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2599072"></a>The <span><strong class="command">chroot</strong></span> Environment</h3></div></div></div>
+<a name="id2599136"></a>The <span><strong class="command">chroot</strong></span> Environment</h3></div></div></div>
<p>
In order for a <span><strong class="command">chroot</strong></span> environment
to
@@ -173,7 +173,7 @@ zone "example.com" {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2599268"></a>Using the <span><strong class="command">setuid</strong></span> Function</h3></div></div></div>
+<a name="id2599264"></a>Using the <span><strong class="command">setuid</strong></span> Function</h3></div></div></div>
<p>
Prior to running the <span><strong class="command">named</strong></span> daemon,
use
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch08.html b/contrib/bind9/doc/arm/Bv9ARM.ch08.html
index 5e547eb..3e7c8c3 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch08.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch08.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch08.html,v 1.178.14.6 2009/06/03 01:54:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch08.html,v 1.178.14.13.2.1 2010/02/25 12:16:47 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,18 +45,18 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599348">Common Problems</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2599353">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599365">Incrementing and Changing the Serial Number</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599382">Where Can I Get Help?</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599344">Common Problems</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2599349">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599361">Incrementing and Changing the Serial Number</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599378">Where Can I Get Help?</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599348"></a>Common Problems</h2></div></div></div>
+<a name="id2599344"></a>Common Problems</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2599353"></a>It's not working; how can I figure out what's wrong?</h3></div></div></div>
+<a name="id2599349"></a>It's not working; how can I figure out what's wrong?</h3></div></div></div>
<p>
The best solution to solving installation and
configuration issues is to take preventative measures by setting
@@ -68,7 +68,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599365"></a>Incrementing and Changing the Serial Number</h2></div></div></div>
+<a name="id2599361"></a>Incrementing and Changing the Serial Number</h2></div></div></div>
<p>
Zone serial numbers are just numbers &#8212; they aren't
date related. A lot of people set them to a number that
@@ -95,7 +95,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599382"></a>Where Can I Get Help?</h2></div></div></div>
+<a name="id2599378"></a>Where Can I Get Help?</h2></div></div></div>
<p>
The Internet Systems Consortium
(<acronym class="acronym">ISC</acronym>) offers a wide range
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch09.html b/contrib/bind9/doc/arm/Bv9ARM.ch09.html
index 87134e0..6b6af6a 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch09.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch09.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch09.html,v 1.180.16.6 2009/06/03 01:54:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch09.html,v 1.180.16.14.2.1 2010/02/25 12:16:47 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,21 +45,21 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599444">Acknowledgments</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599508">Acknowledgments</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#historical_dns_information">A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599684">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599748">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#ipv6addresses">IPv6 addresses (AAAA)</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bibliography">Bibliography (and Suggested Reading)</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#rfcs">Request for Comments (RFCs)</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#internet_drafts">Internet Drafts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2602896">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2603028">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
</dl></dd>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599444"></a>Acknowledgments</h2></div></div></div>
+<a name="id2599508"></a>Acknowledgments</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="historical_dns_information"></a>A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym>
@@ -162,7 +162,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599684"></a>General <acronym class="acronym">DNS</acronym> Reference Information</h2></div></div></div>
+<a name="id2599748"></a>General <acronym class="acronym">DNS</acronym> Reference Information</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="ipv6addresses"></a>IPv6 addresses (AAAA)</h3></div></div></div>
@@ -250,17 +250,17 @@
</p>
<div class="bibliography">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2599872"></a>Bibliography</h4></div></div></div>
+<a name="id2599936"></a>Bibliography</h4></div></div></div>
<div class="bibliodiv">
<h3 class="title">Standards</h3>
<div class="biblioentry">
-<a name="id2599882"></a><p>[<abbr class="abbrev">RFC974</abbr>] <span class="author"><span class="firstname">C.</span> <span class="surname">Partridge</span>. </span><span class="title"><i>Mail Routing and the Domain System</i>. </span><span class="pubdate">January 1986. </span></p>
+<a name="id2599946"></a><p>[<abbr class="abbrev">RFC974</abbr>] <span class="author"><span class="firstname">C.</span> <span class="surname">Partridge</span>. </span><span class="title"><i>Mail Routing and the Domain System</i>. </span><span class="pubdate">January 1986. </span></p>
</div>
<div class="biblioentry">
-<a name="id2599906"></a><p>[<abbr class="abbrev">RFC1034</abbr>] <span class="author"><span class="firstname">P.V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Concepts and Facilities</i>. </span><span class="pubdate">November 1987. </span></p>
+<a name="id2599970"></a><p>[<abbr class="abbrev">RFC1034</abbr>] <span class="author"><span class="firstname">P.V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Concepts and Facilities</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
<div class="biblioentry">
-<a name="id2599929"></a><p>[<abbr class="abbrev">RFC1035</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Implementation and
+<a name="id2599993"></a><p>[<abbr class="abbrev">RFC1035</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Implementation and
Specification</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
</div>
@@ -268,42 +268,42 @@
<h3 class="title">
<a name="proposed_standards"></a>Proposed Standards</h3>
<div class="biblioentry">
-<a name="id2599965"></a><p>[<abbr class="abbrev">RFC2181</abbr>] <span class="author"><span class="firstname">R., R. Bush</span> <span class="surname">Elz</span>. </span><span class="title"><i>Clarifications to the <acronym class="acronym">DNS</acronym>
+<a name="id2600029"></a><p>[<abbr class="abbrev">RFC2181</abbr>] <span class="author"><span class="firstname">R., R. Bush</span> <span class="surname">Elz</span>. </span><span class="title"><i>Clarifications to the <acronym class="acronym">DNS</acronym>
Specification</i>. </span><span class="pubdate">July 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2599992"></a><p>[<abbr class="abbrev">RFC2308</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Andrews</span>. </span><span class="title"><i>Negative Caching of <acronym class="acronym">DNS</acronym>
+<a name="id2600056"></a><p>[<abbr class="abbrev">RFC2308</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Andrews</span>. </span><span class="title"><i>Negative Caching of <acronym class="acronym">DNS</acronym>
Queries</i>. </span><span class="pubdate">March 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600018"></a><p>[<abbr class="abbrev">RFC1995</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Ohta</span>. </span><span class="title"><i>Incremental Zone Transfer in <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2600082"></a><p>[<abbr class="abbrev">RFC1995</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Ohta</span>. </span><span class="title"><i>Incremental Zone Transfer in <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600042"></a><p>[<abbr class="abbrev">RFC1996</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A Mechanism for Prompt Notification of Zone Changes</i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2600106"></a><p>[<abbr class="abbrev">RFC1996</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A Mechanism for Prompt Notification of Zone Changes</i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600066"></a><p>[<abbr class="abbrev">RFC2136</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">Y.</span> <span class="surname">Rekhter</span>, and <span class="firstname">J.</span> <span class="surname">Bound</span>. </span><span class="title"><i>Dynamic Updates in the Domain Name System</i>. </span><span class="pubdate">April 1997. </span></p>
+<a name="id2600130"></a><p>[<abbr class="abbrev">RFC2136</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">Y.</span> <span class="surname">Rekhter</span>, and <span class="firstname">J.</span> <span class="surname">Bound</span>. </span><span class="title"><i>Dynamic Updates in the Domain Name System</i>. </span><span class="pubdate">April 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600121"></a><p>[<abbr class="abbrev">RFC2671</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Extension Mechanisms for DNS (EDNS0)</i>. </span><span class="pubdate">August 1997. </span></p>
+<a name="id2600185"></a><p>[<abbr class="abbrev">RFC2671</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Extension Mechanisms for DNS (EDNS0)</i>. </span><span class="pubdate">August 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600148"></a><p>[<abbr class="abbrev">RFC2672</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Non-Terminal DNS Name Redirection</i>. </span><span class="pubdate">August 1999. </span></p>
+<a name="id2600212"></a><p>[<abbr class="abbrev">RFC2672</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Non-Terminal DNS Name Redirection</i>. </span><span class="pubdate">August 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600174"></a><p>[<abbr class="abbrev">RFC2845</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>, <span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, and <span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secret Key Transaction Authentication for <acronym class="acronym">DNS</acronym> (TSIG)</i>. </span><span class="pubdate">May 2000. </span></p>
+<a name="id2600238"></a><p>[<abbr class="abbrev">RFC2845</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>, <span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, and <span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secret Key Transaction Authentication for <acronym class="acronym">DNS</acronym> (TSIG)</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600236"></a><p>[<abbr class="abbrev">RFC2930</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secret Key Establishment for DNS (TKEY RR)</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2600300"></a><p>[<abbr class="abbrev">RFC2930</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secret Key Establishment for DNS (TKEY RR)</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600266"></a><p>[<abbr class="abbrev">RFC2931</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DNS Request and Transaction Signatures (SIG(0)s)</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2600330"></a><p>[<abbr class="abbrev">RFC2931</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DNS Request and Transaction Signatures (SIG(0)s)</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600296"></a><p>[<abbr class="abbrev">RFC3007</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secure Domain Name System (DNS) Dynamic Update</i>. </span><span class="pubdate">November 2000. </span></p>
+<a name="id2600360"></a><p>[<abbr class="abbrev">RFC3007</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secure Domain Name System (DNS) Dynamic Update</i>. </span><span class="pubdate">November 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600323"></a><p>[<abbr class="abbrev">RFC3645</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Kwan</span>, <span class="firstname">P.</span> <span class="surname">Garg</span>, <span class="firstname">J.</span> <span class="surname">Gilroy</span>, <span class="firstname">L.</span> <span class="surname">Esibov</span>, <span class="firstname">J.</span> <span class="surname">Westhead</span>, and <span class="firstname">R.</span> <span class="surname">Hall</span>. </span><span class="title"><i>Generic Security Service Algorithm for Secret
+<a name="id2600387"></a><p>[<abbr class="abbrev">RFC3645</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Kwan</span>, <span class="firstname">P.</span> <span class="surname">Garg</span>, <span class="firstname">J.</span> <span class="surname">Gilroy</span>, <span class="firstname">L.</span> <span class="surname">Esibov</span>, <span class="firstname">J.</span> <span class="surname">Westhead</span>, and <span class="firstname">R.</span> <span class="surname">Hall</span>. </span><span class="title"><i>Generic Security Service Algorithm for Secret
Key Transaction Authentication for DNS
(GSS-TSIG)</i>. </span><span class="pubdate">October 2003. </span></p>
</div>
@@ -312,19 +312,19 @@
<h3 class="title">
<acronym class="acronym">DNS</acronym> Security Proposed Standards</h3>
<div class="biblioentry">
-<a name="id2600405"></a><p>[<abbr class="abbrev">RFC3225</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Conrad</span>. </span><span class="title"><i>Indicating Resolver Support of DNSSEC</i>. </span><span class="pubdate">December 2001. </span></p>
+<a name="id2600469"></a><p>[<abbr class="abbrev">RFC3225</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Conrad</span>. </span><span class="title"><i>Indicating Resolver Support of DNSSEC</i>. </span><span class="pubdate">December 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600432"></a><p>[<abbr class="abbrev">RFC3833</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Atkins</span> and <span class="firstname">R.</span> <span class="surname">Austein</span>. </span><span class="title"><i>Threat Analysis of the Domain Name System (DNS)</i>. </span><span class="pubdate">August 2004. </span></p>
+<a name="id2600496"></a><p>[<abbr class="abbrev">RFC3833</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Atkins</span> and <span class="firstname">R.</span> <span class="surname">Austein</span>. </span><span class="title"><i>Threat Analysis of the Domain Name System (DNS)</i>. </span><span class="pubdate">August 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600468"></a><p>[<abbr class="abbrev">RFC4033</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>DNS Security Introduction and Requirements</i>. </span><span class="pubdate">March 2005. </span></p>
+<a name="id2600532"></a><p>[<abbr class="abbrev">RFC4033</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>DNS Security Introduction and Requirements</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600533"></a><p>[<abbr class="abbrev">RFC4034</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Resource Records for the DNS Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
+<a name="id2600597"></a><p>[<abbr class="abbrev">RFC4034</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Resource Records for the DNS Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600598"></a><p>[<abbr class="abbrev">RFC4035</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Protocol Modifications for the DNS
+<a name="id2600662"></a><p>[<abbr class="abbrev">RFC4035</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Protocol Modifications for the DNS
Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
</div>
@@ -332,146 +332,146 @@
<h3 class="title">Other Important RFCs About <acronym class="acronym">DNS</acronym>
Implementation</h3>
<div class="biblioentry">
-<a name="id2600672"></a><p>[<abbr class="abbrev">RFC1535</abbr>] <span class="author"><span class="firstname">E.</span> <span class="surname">Gavron</span>. </span><span class="title"><i>A Security Problem and Proposed Correction With Widely
+<a name="id2600736"></a><p>[<abbr class="abbrev">RFC1535</abbr>] <span class="author"><span class="firstname">E.</span> <span class="surname">Gavron</span>. </span><span class="title"><i>A Security Problem and Proposed Correction With Widely
Deployed <acronym class="acronym">DNS</acronym> Software.</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600697"></a><p>[<abbr class="abbrev">RFC1536</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Kumar</span>, <span class="firstname">J.</span> <span class="surname">Postel</span>, <span class="firstname">C.</span> <span class="surname">Neuman</span>, <span class="firstname">P.</span> <span class="surname">Danzig</span>, and <span class="firstname">S.</span> <span class="surname">Miller</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Implementation
+<a name="id2600761"></a><p>[<abbr class="abbrev">RFC1536</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Kumar</span>, <span class="firstname">J.</span> <span class="surname">Postel</span>, <span class="firstname">C.</span> <span class="surname">Neuman</span>, <span class="firstname">P.</span> <span class="surname">Danzig</span>, and <span class="firstname">S.</span> <span class="surname">Miller</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Implementation
Errors and Suggested Fixes</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600765"></a><p>[<abbr class="abbrev">RFC1982</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Elz</span> and <span class="firstname">R.</span> <span class="surname">Bush</span>. </span><span class="title"><i>Serial Number Arithmetic</i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2600829"></a><p>[<abbr class="abbrev">RFC1982</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Elz</span> and <span class="firstname">R.</span> <span class="surname">Bush</span>. </span><span class="title"><i>Serial Number Arithmetic</i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600801"></a><p>[<abbr class="abbrev">RFC4074</abbr>] <span class="authorgroup"><span class="firstname">Y.</span> <span class="surname">Morishita</span> and <span class="firstname">T.</span> <span class="surname">Jinmei</span>. </span><span class="title"><i>Common Misbehaviour Against <acronym class="acronym">DNS</acronym>
+<a name="id2600865"></a><p>[<abbr class="abbrev">RFC4074</abbr>] <span class="authorgroup"><span class="firstname">Y.</span> <span class="surname">Morishita</span> and <span class="firstname">T.</span> <span class="surname">Jinmei</span>. </span><span class="title"><i>Common Misbehaviour Against <acronym class="acronym">DNS</acronym>
Queries for IPv6 Addresses</i>. </span><span class="pubdate">May 2005. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Resource Record Types</h3>
<div class="biblioentry">
-<a name="id2600846"></a><p>[<abbr class="abbrev">RFC1183</abbr>] <span class="authorgroup"><span class="firstname">C.F.</span> <span class="surname">Everhart</span>, <span class="firstname">L. A.</span> <span class="surname">Mamakos</span>, <span class="firstname">R.</span> <span class="surname">Ullmann</span>, and <span class="firstname">P.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>New <acronym class="acronym">DNS</acronym> RR Definitions</i>. </span><span class="pubdate">October 1990. </span></p>
+<a name="id2600910"></a><p>[<abbr class="abbrev">RFC1183</abbr>] <span class="authorgroup"><span class="firstname">C.F.</span> <span class="surname">Everhart</span>, <span class="firstname">L. A.</span> <span class="surname">Mamakos</span>, <span class="firstname">R.</span> <span class="surname">Ullmann</span>, and <span class="firstname">P.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>New <acronym class="acronym">DNS</acronym> RR Definitions</i>. </span><span class="pubdate">October 1990. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600904"></a><p>[<abbr class="abbrev">RFC1706</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">R.</span> <span class="surname">Colella</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> NSAP Resource Records</i>. </span><span class="pubdate">October 1994. </span></p>
+<a name="id2600968"></a><p>[<abbr class="abbrev">RFC1706</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">R.</span> <span class="surname">Colella</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> NSAP Resource Records</i>. </span><span class="pubdate">October 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600941"></a><p>[<abbr class="abbrev">RFC2168</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Daniel</span> and <span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="title"><i>Resolution of Uniform Resource Identifiers using
+<a name="id2601005"></a><p>[<abbr class="abbrev">RFC2168</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Daniel</span> and <span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="title"><i>Resolution of Uniform Resource Identifiers using
the Domain Name System</i>. </span><span class="pubdate">June 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600977"></a><p>[<abbr class="abbrev">RFC1876</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Davis</span>, <span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">T.</span>, and <span class="firstname">I.</span> <span class="surname">Dickinson</span>. </span><span class="title"><i>A Means for Expressing Location Information in the
+<a name="id2601041"></a><p>[<abbr class="abbrev">RFC1876</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Davis</span>, <span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">T.</span>, and <span class="firstname">I.</span> <span class="surname">Dickinson</span>. </span><span class="title"><i>A Means for Expressing Location Information in the
Domain
Name System</i>. </span><span class="pubdate">January 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601031"></a><p>[<abbr class="abbrev">RFC2052</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A <acronym class="acronym">DNS</acronym> RR for Specifying the
+<a name="id2601095"></a><p>[<abbr class="abbrev">RFC2052</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A <acronym class="acronym">DNS</acronym> RR for Specifying the
Location of
Services.</i>. </span><span class="pubdate">October 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601069"></a><p>[<abbr class="abbrev">RFC2163</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Allocchio</span>. </span><span class="title"><i>Using the Internet <acronym class="acronym">DNS</acronym> to
+<a name="id2601133"></a><p>[<abbr class="abbrev">RFC2163</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Allocchio</span>. </span><span class="title"><i>Using the Internet <acronym class="acronym">DNS</acronym> to
Distribute MIXER
Conformant Global Address Mapping</i>. </span><span class="pubdate">January 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601095"></a><p>[<abbr class="abbrev">RFC2230</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Atkinson</span>. </span><span class="title"><i>Key Exchange Delegation Record for the <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">October 1997. </span></p>
+<a name="id2601159"></a><p>[<abbr class="abbrev">RFC2230</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Atkinson</span>. </span><span class="title"><i>Key Exchange Delegation Record for the <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">October 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601121"></a><p>[<abbr class="abbrev">RFC2536</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DSA KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2601185"></a><p>[<abbr class="abbrev">RFC2536</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DSA KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601147"></a><p>[<abbr class="abbrev">RFC2537</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2601211"></a><p>[<abbr class="abbrev">RFC2537</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601174"></a><p>[<abbr class="abbrev">RFC2538</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Storing Certificates in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2601238"></a><p>[<abbr class="abbrev">RFC2538</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Storing Certificates in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601213"></a><p>[<abbr class="abbrev">RFC2539</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Storage of Diffie-Hellman Keys in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2601277"></a><p>[<abbr class="abbrev">RFC2539</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Storage of Diffie-Hellman Keys in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601243"></a><p>[<abbr class="abbrev">RFC2540</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Detached Domain Name System (DNS) Information</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2601307"></a><p>[<abbr class="abbrev">RFC2540</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Detached Domain Name System (DNS) Information</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601273"></a><p>[<abbr class="abbrev">RFC2782</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span>. </span><span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="author"><span class="firstname">L.</span> <span class="surname">Esibov</span>. </span><span class="title"><i>A DNS RR for specifying the location of services (DNS SRV)</i>. </span><span class="pubdate">February 2000. </span></p>
+<a name="id2601337"></a><p>[<abbr class="abbrev">RFC2782</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span>. </span><span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="author"><span class="firstname">L.</span> <span class="surname">Esibov</span>. </span><span class="title"><i>A DNS RR for specifying the location of services (DNS SRV)</i>. </span><span class="pubdate">February 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601316"></a><p>[<abbr class="abbrev">RFC2915</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="author"><span class="firstname">R.</span> <span class="surname">Daniel</span>. </span><span class="title"><i>The Naming Authority Pointer (NAPTR) DNS Resource Record</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2601380"></a><p>[<abbr class="abbrev">RFC2915</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="author"><span class="firstname">R.</span> <span class="surname">Daniel</span>. </span><span class="title"><i>The Naming Authority Pointer (NAPTR) DNS Resource Record</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601349"></a><p>[<abbr class="abbrev">RFC3110</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</i>. </span><span class="pubdate">May 2001. </span></p>
+<a name="id2601413"></a><p>[<abbr class="abbrev">RFC3110</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</i>. </span><span class="pubdate">May 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601376"></a><p>[<abbr class="abbrev">RFC3123</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Koch</span>. </span><span class="title"><i>A DNS RR Type for Lists of Address Prefixes (APL RR)</i>. </span><span class="pubdate">June 2001. </span></p>
+<a name="id2601440"></a><p>[<abbr class="abbrev">RFC3123</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Koch</span>. </span><span class="title"><i>A DNS RR Type for Lists of Address Prefixes (APL RR)</i>. </span><span class="pubdate">June 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601399"></a><p>[<abbr class="abbrev">RFC3596</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">C.</span> <span class="surname">Huitema</span>, <span class="firstname">V.</span> <span class="surname">Ksinant</span>, and <span class="firstname">M.</span> <span class="surname">Souissi</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Extensions to support IP
+<a name="id2601463"></a><p>[<abbr class="abbrev">RFC3596</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">C.</span> <span class="surname">Huitema</span>, <span class="firstname">V.</span> <span class="surname">Ksinant</span>, and <span class="firstname">M.</span> <span class="surname">Souissi</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Extensions to support IP
version 6</i>. </span><span class="pubdate">October 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601457"></a><p>[<abbr class="abbrev">RFC3597</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gustafsson</span>. </span><span class="title"><i>Handling of Unknown DNS Resource Record (RR) Types</i>. </span><span class="pubdate">September 2003. </span></p>
+<a name="id2601589"></a><p>[<abbr class="abbrev">RFC3597</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gustafsson</span>. </span><span class="title"><i>Handling of Unknown DNS Resource Record (RR) Types</i>. </span><span class="pubdate">September 2003. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">
<acronym class="acronym">DNS</acronym> and the Internet</h3>
<div class="biblioentry">
-<a name="id2601489"></a><p>[<abbr class="abbrev">RFC1101</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Network Names
+<a name="id2601621"></a><p>[<abbr class="abbrev">RFC1101</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Network Names
and Other Types</i>. </span><span class="pubdate">April 1989. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601582"></a><p>[<abbr class="abbrev">RFC1123</abbr>] <span class="author"><span class="surname">Braden</span>. </span><span class="title"><i>Requirements for Internet Hosts - Application and
+<a name="id2601646"></a><p>[<abbr class="abbrev">RFC1123</abbr>] <span class="author"><span class="surname">Braden</span>. </span><span class="title"><i>Requirements for Internet Hosts - Application and
Support</i>. </span><span class="pubdate">October 1989. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601605"></a><p>[<abbr class="abbrev">RFC1591</abbr>] <span class="author"><span class="firstname">J.</span> <span class="surname">Postel</span>. </span><span class="title"><i>Domain Name System Structure and Delegation</i>. </span><span class="pubdate">March 1994. </span></p>
+<a name="id2601669"></a><p>[<abbr class="abbrev">RFC1591</abbr>] <span class="author"><span class="firstname">J.</span> <span class="surname">Postel</span>. </span><span class="title"><i>Domain Name System Structure and Delegation</i>. </span><span class="pubdate">March 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601628"></a><p>[<abbr class="abbrev">RFC2317</abbr>] <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Eidnes</span>, <span class="firstname">G.</span> <span class="surname">de Groot</span>, and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Classless IN-ADDR.ARPA Delegation</i>. </span><span class="pubdate">March 1998. </span></p>
+<a name="id2601692"></a><p>[<abbr class="abbrev">RFC2317</abbr>] <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Eidnes</span>, <span class="firstname">G.</span> <span class="surname">de Groot</span>, and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Classless IN-ADDR.ARPA Delegation</i>. </span><span class="pubdate">March 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601674"></a><p>[<abbr class="abbrev">RFC2826</abbr>] <span class="authorgroup"><span class="surname">Internet Architecture Board</span>. </span><span class="title"><i>IAB Technical Comment on the Unique DNS Root</i>. </span><span class="pubdate">May 2000. </span></p>
+<a name="id2601738"></a><p>[<abbr class="abbrev">RFC2826</abbr>] <span class="authorgroup"><span class="surname">Internet Architecture Board</span>. </span><span class="title"><i>IAB Technical Comment on the Unique DNS Root</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601698"></a><p>[<abbr class="abbrev">RFC2929</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, <span class="firstname">E.</span> <span class="surname">Brunner-Williams</span>, and <span class="firstname">B.</span> <span class="surname">Manning</span>. </span><span class="title"><i>Domain Name System (DNS) IANA Considerations</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2601762"></a><p>[<abbr class="abbrev">RFC2929</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, <span class="firstname">E.</span> <span class="surname">Brunner-Williams</span>, and <span class="firstname">B.</span> <span class="surname">Manning</span>. </span><span class="title"><i>Domain Name System (DNS) IANA Considerations</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">
<acronym class="acronym">DNS</acronym> Operations</h3>
<div class="biblioentry">
-<a name="id2601755"></a><p>[<abbr class="abbrev">RFC1033</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Lottor</span>. </span><span class="title"><i>Domain administrators operations guide.</i>. </span><span class="pubdate">November 1987. </span></p>
+<a name="id2601819"></a><p>[<abbr class="abbrev">RFC1033</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Lottor</span>. </span><span class="title"><i>Domain administrators operations guide.</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601779"></a><p>[<abbr class="abbrev">RFC1537</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Beertema</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Data File
+<a name="id2601843"></a><p>[<abbr class="abbrev">RFC1537</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Beertema</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Data File
Configuration Errors</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601805"></a><p>[<abbr class="abbrev">RFC1912</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Barr</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Operational and
+<a name="id2601869"></a><p>[<abbr class="abbrev">RFC1912</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Barr</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Operational and
Configuration Errors</i>. </span><span class="pubdate">February 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601832"></a><p>[<abbr class="abbrev">RFC2010</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Operational Criteria for Root Name Servers.</i>. </span><span class="pubdate">October 1996. </span></p>
+<a name="id2601896"></a><p>[<abbr class="abbrev">RFC2010</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Operational Criteria for Root Name Servers.</i>. </span><span class="pubdate">October 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601868"></a><p>[<abbr class="abbrev">RFC2219</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Hamilton</span> and <span class="firstname">R.</span> <span class="surname">Wright</span>. </span><span class="title"><i>Use of <acronym class="acronym">DNS</acronym> Aliases for
+<a name="id2601932"></a><p>[<abbr class="abbrev">RFC2219</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Hamilton</span> and <span class="firstname">R.</span> <span class="surname">Wright</span>. </span><span class="title"><i>Use of <acronym class="acronym">DNS</acronym> Aliases for
Network Services.</i>. </span><span class="pubdate">October 1997. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Internationalized Domain Names</h3>
<div class="biblioentry">
-<a name="id2601914"></a><p>[<abbr class="abbrev">RFC2825</abbr>] <span class="authorgroup"><span class="surname">IAB</span> and <span class="firstname">R.</span> <span class="surname">Daigle</span>. </span><span class="title"><i>A Tangled Web: Issues of I18N, Domain Names,
+<a name="id2601978"></a><p>[<abbr class="abbrev">RFC2825</abbr>] <span class="authorgroup"><span class="surname">IAB</span> and <span class="firstname">R.</span> <span class="surname">Daigle</span>. </span><span class="title"><i>A Tangled Web: Issues of I18N, Domain Names,
and the Other Internet protocols</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601946"></a><p>[<abbr class="abbrev">RFC3490</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Faltstrom</span>, <span class="firstname">P.</span> <span class="surname">Hoffman</span>, and <span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Internationalizing Domain Names in Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
+<a name="id2602010"></a><p>[<abbr class="abbrev">RFC3490</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Faltstrom</span>, <span class="firstname">P.</span> <span class="surname">Hoffman</span>, and <span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Internationalizing Domain Names in Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601992"></a><p>[<abbr class="abbrev">RFC3491</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Hoffman</span> and <span class="firstname">M.</span> <span class="surname">Blanchet</span>. </span><span class="title"><i>Nameprep: A Stringprep Profile for Internationalized Domain Names</i>. </span><span class="pubdate">March 2003. </span></p>
+<a name="id2602124"></a><p>[<abbr class="abbrev">RFC3491</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Hoffman</span> and <span class="firstname">M.</span> <span class="surname">Blanchet</span>. </span><span class="title"><i>Nameprep: A Stringprep Profile for Internationalized Domain Names</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602027"></a><p>[<abbr class="abbrev">RFC3492</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Punycode: A Bootstring encoding of Unicode
+<a name="id2602160"></a><p>[<abbr class="abbrev">RFC3492</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Punycode: A Bootstring encoding of Unicode
for Internationalized Domain Names in
Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
@@ -487,47 +487,47 @@
</p>
</div>
<div class="biblioentry">
-<a name="id2602072"></a><p>[<abbr class="abbrev">RFC1464</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Rosenbaum</span>. </span><span class="title"><i>Using the Domain Name System To Store Arbitrary String
+<a name="id2602204"></a><p>[<abbr class="abbrev">RFC1464</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Rosenbaum</span>. </span><span class="title"><i>Using the Domain Name System To Store Arbitrary String
Attributes</i>. </span><span class="pubdate">May 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602094"></a><p>[<abbr class="abbrev">RFC1713</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Romao</span>. </span><span class="title"><i>Tools for <acronym class="acronym">DNS</acronym> Debugging</i>. </span><span class="pubdate">November 1994. </span></p>
+<a name="id2602227"></a><p>[<abbr class="abbrev">RFC1713</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Romao</span>. </span><span class="title"><i>Tools for <acronym class="acronym">DNS</acronym> Debugging</i>. </span><span class="pubdate">November 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602120"></a><p>[<abbr class="abbrev">RFC1794</abbr>] <span class="author"><span class="firstname">T.</span> <span class="surname">Brisco</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Support for Load
+<a name="id2602252"></a><p>[<abbr class="abbrev">RFC1794</abbr>] <span class="author"><span class="firstname">T.</span> <span class="surname">Brisco</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Support for Load
Balancing</i>. </span><span class="pubdate">April 1995. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602146"></a><p>[<abbr class="abbrev">RFC2240</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Legal Basis for Domain Name Allocation</i>. </span><span class="pubdate">November 1997. </span></p>
+<a name="id2602278"></a><p>[<abbr class="abbrev">RFC2240</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Legal Basis for Domain Name Allocation</i>. </span><span class="pubdate">November 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602169"></a><p>[<abbr class="abbrev">RFC2345</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>, <span class="firstname">T.</span> <span class="surname">Wolf</span>, and <span class="firstname">G.</span> <span class="surname">Oglesby</span>. </span><span class="title"><i>Domain Names and Company Name Retrieval</i>. </span><span class="pubdate">May 1998. </span></p>
+<a name="id2602301"></a><p>[<abbr class="abbrev">RFC2345</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>, <span class="firstname">T.</span> <span class="surname">Wolf</span>, and <span class="firstname">G.</span> <span class="surname">Oglesby</span>. </span><span class="title"><i>Domain Names and Company Name Retrieval</i>. </span><span class="pubdate">May 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602215"></a><p>[<abbr class="abbrev">RFC2352</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Convention For Using Legal Names as Domain Names</i>. </span><span class="pubdate">May 1998. </span></p>
+<a name="id2602347"></a><p>[<abbr class="abbrev">RFC2352</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Convention For Using Legal Names as Domain Names</i>. </span><span class="pubdate">May 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602238"></a><p>[<abbr class="abbrev">RFC3071</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>. </span><span class="title"><i>Reflections on the DNS, RFC 1591, and Categories of Domains</i>. </span><span class="pubdate">February 2001. </span></p>
+<a name="id2602371"></a><p>[<abbr class="abbrev">RFC3071</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>. </span><span class="title"><i>Reflections on the DNS, RFC 1591, and Categories of Domains</i>. </span><span class="pubdate">February 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602265"></a><p>[<abbr class="abbrev">RFC3258</abbr>] <span class="authorgroup"><span class="firstname">T.</span> <span class="surname">Hardie</span>. </span><span class="title"><i>Distributing Authoritative Name Servers via
+<a name="id2602397"></a><p>[<abbr class="abbrev">RFC3258</abbr>] <span class="authorgroup"><span class="firstname">T.</span> <span class="surname">Hardie</span>. </span><span class="title"><i>Distributing Authoritative Name Servers via
Shared Unicast Addresses</i>. </span><span class="pubdate">April 2002. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602291"></a><p>[<abbr class="abbrev">RFC3901</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Durand</span> and <span class="firstname">J.</span> <span class="surname">Ihren</span>. </span><span class="title"><i>DNS IPv6 Transport Operational Guidelines</i>. </span><span class="pubdate">September 2004. </span></p>
+<a name="id2602423"></a><p>[<abbr class="abbrev">RFC3901</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Durand</span> and <span class="firstname">J.</span> <span class="surname">Ihren</span>. </span><span class="title"><i>DNS IPv6 Transport Operational Guidelines</i>. </span><span class="pubdate">September 2004. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Obsolete and Unimplemented Experimental RFC</h3>
<div class="biblioentry">
-<a name="id2602334"></a><p>[<abbr class="abbrev">RFC1712</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Farrell</span>, <span class="firstname">M.</span> <span class="surname">Schulze</span>, <span class="firstname">S.</span> <span class="surname">Pleitner</span>, and <span class="firstname">D.</span> <span class="surname">Baldoni</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Geographical
+<a name="id2602467"></a><p>[<abbr class="abbrev">RFC1712</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Farrell</span>, <span class="firstname">M.</span> <span class="surname">Schulze</span>, <span class="firstname">S.</span> <span class="surname">Pleitner</span>, and <span class="firstname">D.</span> <span class="surname">Baldoni</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Geographical
Location</i>. </span><span class="pubdate">November 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602392"></a><p>[<abbr class="abbrev">RFC2673</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Binary Labels in the Domain Name System</i>. </span><span class="pubdate">August 1999. </span></p>
+<a name="id2602524"></a><p>[<abbr class="abbrev">RFC2673</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Binary Labels in the Domain Name System</i>. </span><span class="pubdate">August 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602419"></a><p>[<abbr class="abbrev">RFC2874</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span> and <span class="firstname">C.</span> <span class="surname">Huitema</span>. </span><span class="title"><i>DNS Extensions to Support IPv6 Address Aggregation
+<a name="id2602551"></a><p>[<abbr class="abbrev">RFC2874</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span> and <span class="firstname">C.</span> <span class="surname">Huitema</span>. </span><span class="title"><i>DNS Extensions to Support IPv6 Address Aggregation
and Renumbering</i>. </span><span class="pubdate">July 2000. </span></p>
</div>
</div>
@@ -541,39 +541,39 @@
</p>
</div>
<div class="biblioentry">
-<a name="id2602467"></a><p>[<abbr class="abbrev">RFC2065</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">C.</span> <span class="surname">Kaufman</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">January 1997. </span></p>
+<a name="id2602667"></a><p>[<abbr class="abbrev">RFC2065</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">C.</span> <span class="surname">Kaufman</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">January 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602506"></a><p>[<abbr class="abbrev">RFC2137</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secure Domain Name System Dynamic Update</i>. </span><span class="pubdate">April 1997. </span></p>
+<a name="id2602707"></a><p>[<abbr class="abbrev">RFC2137</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secure Domain Name System Dynamic Update</i>. </span><span class="pubdate">April 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602533"></a><p>[<abbr class="abbrev">RFC2535</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2602733"></a><p>[<abbr class="abbrev">RFC2535</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602563"></a><p>[<abbr class="abbrev">RFC3008</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Domain Name System Security (DNSSEC)
+<a name="id2602763"></a><p>[<abbr class="abbrev">RFC3008</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Domain Name System Security (DNSSEC)
Signing Authority</i>. </span><span class="pubdate">November 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602588"></a><p>[<abbr class="abbrev">RFC3090</abbr>] <span class="authorgroup"><span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>DNS Security Extension Clarification on Zone Status</i>. </span><span class="pubdate">March 2001. </span></p>
+<a name="id2602789"></a><p>[<abbr class="abbrev">RFC3090</abbr>] <span class="authorgroup"><span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>DNS Security Extension Clarification on Zone Status</i>. </span><span class="pubdate">March 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602683"></a><p>[<abbr class="abbrev">RFC3445</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Massey</span> and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Limiting the Scope of the KEY Resource Record (RR)</i>. </span><span class="pubdate">December 2002. </span></p>
+<a name="id2602816"></a><p>[<abbr class="abbrev">RFC3445</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Massey</span> and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Limiting the Scope of the KEY Resource Record (RR)</i>. </span><span class="pubdate">December 2002. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602720"></a><p>[<abbr class="abbrev">RFC3655</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Redefinition of DNS Authenticated Data (AD) bit</i>. </span><span class="pubdate">November 2003. </span></p>
+<a name="id2602852"></a><p>[<abbr class="abbrev">RFC3655</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Redefinition of DNS Authenticated Data (AD) bit</i>. </span><span class="pubdate">November 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602756"></a><p>[<abbr class="abbrev">RFC3658</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Delegation Signer (DS) Resource Record (RR)</i>. </span><span class="pubdate">December 2003. </span></p>
+<a name="id2602888"></a><p>[<abbr class="abbrev">RFC3658</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Delegation Signer (DS) Resource Record (RR)</i>. </span><span class="pubdate">December 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602782"></a><p>[<abbr class="abbrev">RFC3755</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Weiler</span>. </span><span class="title"><i>Legacy Resolver Compatibility for Delegation Signer (DS)</i>. </span><span class="pubdate">May 2004. </span></p>
+<a name="id2602915"></a><p>[<abbr class="abbrev">RFC3755</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Weiler</span>. </span><span class="title"><i>Legacy Resolver Compatibility for Delegation Signer (DS)</i>. </span><span class="pubdate">May 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602809"></a><p>[<abbr class="abbrev">RFC3757</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Kolkman</span>, <span class="firstname">J.</span> <span class="surname">Schlyter</span>, and <span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>Domain Name System KEY (DNSKEY) Resource Record
+<a name="id2602941"></a><p>[<abbr class="abbrev">RFC3757</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Kolkman</span>, <span class="firstname">J.</span> <span class="surname">Schlyter</span>, and <span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>Domain Name System KEY (DNSKEY) Resource Record
(RR) Secure Entry Point (SEP) Flag</i>. </span><span class="pubdate">April 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602854"></a><p>[<abbr class="abbrev">RFC3845</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Schlyter</span>. </span><span class="title"><i>DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format</i>. </span><span class="pubdate">August 2004. </span></p>
+<a name="id2602986"></a><p>[<abbr class="abbrev">RFC3845</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Schlyter</span>. </span><span class="title"><i>DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format</i>. </span><span class="pubdate">August 2004. </span></p>
</div>
</div>
</div>
@@ -594,14 +594,14 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2602896"></a>Other Documents About <acronym class="acronym">BIND</acronym>
+<a name="id2603028"></a>Other Documents About <acronym class="acronym">BIND</acronym>
</h3></div></div></div>
<p></p>
<div class="bibliography">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2602905"></a>Bibliography</h4></div></div></div>
+<a name="id2603037"></a>Bibliography</h4></div></div></div>
<div class="biblioentry">
-<a name="id2602907"></a><p><span class="authorgroup"><span class="firstname">Paul</span> <span class="surname">Albitz</span> and <span class="firstname">Cricket</span> <span class="surname">Liu</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></i>. </span><span class="copyright">Copyright © 1998 Sebastopol, CA: O'Reilly and Associates. </span></p>
+<a name="id2603040"></a><p><span class="authorgroup"><span class="firstname">Paul</span> <span class="surname">Albitz</span> and <span class="firstname">Cricket</span> <span class="surname">Liu</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></i>. </span><span class="copyright">Copyright © 1998 Sebastopol, CA: O'Reilly and Associates. </span></p>
</div>
</div>
</div>
diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch10.html b/contrib/bind9/doc/arm/Bv9ARM.ch10.html
index 5fbeb3d..452717c 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.ch10.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.ch10.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch10.html,v 1.11.14.1 2009/01/08 01:51:00 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch10.html,v 1.11.14.3 2010/01/24 01:55:26 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/doc/arm/Bv9ARM.html b/contrib/bind9/doc/arm/Bv9ARM.html
index ffb7b62..2f127c6 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.html
+++ b/contrib/bind9/doc/arm/Bv9ARM.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.html,v 1.193.14.6 2009/06/03 01:54:40 tbox Exp $ -->
+<!-- $Id: Bv9ARM.html,v 1.193.14.14.2.1 2010/02/25 12:16:48 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -41,7 +41,7 @@
<div>
<div><h1 class="title">
<a name="id2563174"></a>BIND 9 Administrator Reference Manual</h1></div>
-<div><p class="copyright">Copyright © 2004-2009 Internet Systems Consortium, Inc. ("ISC")</p></div>
+<div><p class="copyright">Copyright © 2004-2010 Internet Systems Consortium, Inc. ("ISC")</p></div>
<div><p class="copyright">Copyright © 2000-2003 Internet Software Consortium.</p></div>
</div>
<hr>
@@ -51,39 +51,39 @@
<dl>
<dt><span class="chapter"><a href="Bv9ARM.ch01.html">1. Introduction</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2563409">Scope of Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564388">Organization of This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564528">Conventions Used in This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564641">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2563412">Scope of Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564391">Organization of This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564531">Conventions Used in This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564712">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564662">DNS Fundamentals</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564696">Domains and Domain Names</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567170">Zones</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567246">Authoritative Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567419">Caching Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567549">Name Servers in Multiple Roles</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564733">DNS Fundamentals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564768">Domains and Domain Names</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567173">Zones</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567250">Authoritative Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567422">Caching Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567553">Name Servers in Multiple Roles</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch02.html">2. <acronym class="acronym">BIND</acronym> Resource Requirements</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567584">Hardware requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567610">CPU Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567623">Memory Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567854">Name Server Intensive Environment Issues</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567865">Supported Operating Systems</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567587">Hardware requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567613">CPU Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567626">Memory Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567721">Name Server Intensive Environment Issues</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567732">Supported Operating Systems</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch03.html">3. Name Server Configuration</a></span></dt>
<dd><dl>
<dt><span class="sect1"><a href="Bv9ARM.ch03.html#sample_configuration">Sample Configurations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567897">A Caching-only Name Server</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567913">An Authoritative-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567764">A Caching-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567780">An Authoritative-only Name Server</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568004">Load Balancing</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568358">Name Server Operations</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568007">Load Balancing</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568361">Name Server Operations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568363">Tools for Use With the Name Server Daemon</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570071">Signals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568366">Tools for Use With the Name Server Daemon</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570006">Signals</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch04.html">4. Advanced DNS Features</a></span></dt>
@@ -92,34 +92,34 @@
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#dynamic_update">Dynamic Update</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#journal">The journal file</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#incremental_zone_transfers">Incremental Zone Transfers (IXFR)</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2564066">Split DNS</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564084">Example split DNS setup</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2570492">Split DNS</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2570510">Example split DNS setup</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#tsig">TSIG</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571141">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571214">Copying the Shared Secret to Both Machines</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571225">Informing the Servers of the Key's Existence</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571268">Instructing the Server to Use the Key</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571325">TSIG Key Based Access Control</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571510">Errors</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571082">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571156">Copying the Shared Secret to Both Machines</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571166">Informing the Servers of the Key's Existence</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571203">Instructing the Server to Use the Key</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571260">TSIG Key Based Access Control</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571445">Errors</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571524">TKEY</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571709">SIG(0)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571459">TKEY</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571576">SIG(0)</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#DNSSEC">DNSSEC</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571778">Generating Keys</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571925">Signing the Zone</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572006">Configuring Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571644">Generating Keys</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571792">Signing the Zone</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571873">Configuring Servers</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572220">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572110">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572282">Address Lookups Using AAAA Records</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572304">Address to Name Lookups Using Nibble Format</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572172">Address Lookups Using AAAA Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572194">Address to Name Lookups Using Nibble Format</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch05.html">5. The <acronym class="acronym">BIND</acronym> 9 Lightweight Resolver</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572337">The Lightweight Resolver Library</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572227">The Lightweight Resolver Library</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch05.html#lwresd">Running a Resolver Daemon</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch06.html">6. <acronym class="acronym">BIND</acronym> 9 Configuration Reference</a></span></dt>
@@ -127,55 +127,55 @@
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#configuration_file_elements">Configuration File Elements</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#address_match_lists">Address Match Lists</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573716">Comment Syntax</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573606">Comment Syntax</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#Configuration_File_Grammar">Configuration File Grammar</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574346"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574305"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#acl"><span><strong class="command">acl</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574536"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574494"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#controls_statement_definition_and_usage"><span><strong class="command">controls</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574965"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574982"><span><strong class="command">include</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574923"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574940"><span><strong class="command">include</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575005"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575029"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575120"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575245"><span><strong class="command">logging</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574964"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574987"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575078"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575204"><span><strong class="command">logging</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577306"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577448"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577512"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577556"><span><strong class="command">masters</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577401"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577475"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577539"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577582"><span><strong class="command">masters</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577571"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577597"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#options"><span><strong class="command">options</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_grammar"><span><strong class="command">server</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_definition_and_usage"><span><strong class="command">server</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#statschannels"><span><strong class="command">statistics-channels</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586902"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586877"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586988"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587040"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586964"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587083"><span><strong class="command">trusted-keys</strong></span> Statement Definition
and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#view_statement_grammar"><span><strong class="command">view</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587122"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587165"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zone_statement_grammar"><span><strong class="command">zone</strong></span>
Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588659"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588638"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2591138">Zone File</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2591117">Zone File</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#types_of_resource_records_and_when_to_use_them">Types of Resource Records and When to Use Them</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593300">Discussion of MX Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593348">Discussion of MX Records</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#Setting_TTLs">Setting TTLs</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593915">Inverse Mapping in IPv4</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594042">Other Zone File Directives</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594368"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593895">Inverse Mapping in IPv4</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594090">Other Zone File Directives</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594500"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zonefile_format">Additional File Formats</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#statistics">BIND9 Statistics</a></span></dt>
@@ -184,31 +184,31 @@
<dt><span class="chapter"><a href="Bv9ARM.ch07.html">7. <acronym class="acronym">BIND</acronym> 9 Security Considerations</a></span></dt>
<dd><dl>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#Access_Control_Lists">Access Control Lists</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2598990"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2599054"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599072">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599268">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599136">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599264">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#dynamic_update_security">Dynamic Update Security</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch08.html">8. Troubleshooting</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599348">Common Problems</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2599353">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599365">Incrementing and Changing the Serial Number</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599382">Where Can I Get Help?</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599344">Common Problems</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2599349">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599361">Incrementing and Changing the Serial Number</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599378">Where Can I Get Help?</a></span></dt>
</dl></dd>
<dt><span class="appendix"><a href="Bv9ARM.ch09.html">A. Appendices</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599444">Acknowledgments</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599508">Acknowledgments</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#historical_dns_information">A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599684">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599748">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#ipv6addresses">IPv6 addresses (AAAA)</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bibliography">Bibliography (and Suggested Reading)</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#rfcs">Request for Comments (RFCs)</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#internet_drafts">Internet Drafts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2602896">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2603028">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="reference"><a href="Bv9ARM.ch10.html">I. Manual pages</a></span></dt>
diff --git a/contrib/bind9/doc/arm/Bv9ARM.pdf b/contrib/bind9/doc/arm/Bv9ARM.pdf
index fbb664f..87f3462 100644
--- a/contrib/bind9/doc/arm/Bv9ARM.pdf
+++ b/contrib/bind9/doc/arm/Bv9ARM.pdf
@@ -765,323 +765,329 @@ endobj
<< /S /GoTo /D (subsubsection.6.3.5.1) >>
endobj
516 0 obj
-(6.3.5.1 The \044ORIGIN Directive)
+(6.3.5.1 The @ \(at-sign\))
endobj
517 0 obj
<< /S /GoTo /D (subsubsection.6.3.5.2) >>
endobj
520 0 obj
-(6.3.5.2 The \044INCLUDE Directive)
+(6.3.5.2 The \044ORIGIN Directive)
endobj
521 0 obj
<< /S /GoTo /D (subsubsection.6.3.5.3) >>
endobj
524 0 obj
-(6.3.5.3 The \044TTL Directive)
+(6.3.5.3 The \044INCLUDE Directive)
endobj
525 0 obj
-<< /S /GoTo /D (subsection.6.3.6) >>
+<< /S /GoTo /D (subsubsection.6.3.5.4) >>
endobj
528 0 obj
-(6.3.6 BIND Master File Extension: the \044GENERATE Directive)
+(6.3.5.4 The \044TTL Directive)
endobj
529 0 obj
-<< /S /GoTo /D (subsection.6.3.7) >>
+<< /S /GoTo /D (subsection.6.3.6) >>
endobj
532 0 obj
-(6.3.7 Additional File Formats)
+(6.3.6 BIND Master File Extension: the \044GENERATE Directive)
endobj
533 0 obj
-<< /S /GoTo /D (section.6.4) >>
+<< /S /GoTo /D (subsection.6.3.7) >>
endobj
536 0 obj
-(6.4 BIND9 Statistics)
+(6.3.7 Additional File Formats)
endobj
537 0 obj
-<< /S /GoTo /D (subsubsection.6.4.0.1) >>
+<< /S /GoTo /D (section.6.4) >>
endobj
540 0 obj
-(6.4.0.1 The Statistics File)
+(6.4 BIND9 Statistics)
endobj
541 0 obj
-<< /S /GoTo /D (subsection.6.4.1) >>
+<< /S /GoTo /D (subsubsection.6.4.0.1) >>
endobj
544 0 obj
-(6.4.1 Statistics Counters)
+(6.4.0.1 The Statistics File)
endobj
545 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.1) >>
+<< /S /GoTo /D (subsection.6.4.1) >>
endobj
548 0 obj
-(6.4.1.1 Name Server Statistics Counters)
+(6.4.1 Statistics Counters)
endobj
549 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.2) >>
+<< /S /GoTo /D (subsubsection.6.4.1.1) >>
endobj
552 0 obj
-(6.4.1.2 Zone Maintenance Statistics Counters)
+(6.4.1.1 Name Server Statistics Counters)
endobj
553 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.3) >>
+<< /S /GoTo /D (subsubsection.6.4.1.2) >>
endobj
556 0 obj
-(6.4.1.3 Resolver Statistics Counters)
+(6.4.1.2 Zone Maintenance Statistics Counters)
endobj
557 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.4) >>
+<< /S /GoTo /D (subsubsection.6.4.1.3) >>
endobj
560 0 obj
-(6.4.1.4 Socket I/O Statistics Counters)
+(6.4.1.3 Resolver Statistics Counters)
endobj
561 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.5) >>
+<< /S /GoTo /D (subsubsection.6.4.1.4) >>
endobj
564 0 obj
-(6.4.1.5 Compatibility with BIND 8 Counters)
+(6.4.1.4 Socket I/O Statistics Counters)
endobj
565 0 obj
-<< /S /GoTo /D (chapter.7) >>
+<< /S /GoTo /D (subsubsection.6.4.1.5) >>
endobj
568 0 obj
-(7 BIND 9 Security Considerations)
+(6.4.1.5 Compatibility with BIND 8 Counters)
endobj
569 0 obj
-<< /S /GoTo /D (section.7.1) >>
+<< /S /GoTo /D (chapter.7) >>
endobj
572 0 obj
-(7.1 Access Control Lists)
+(7 BIND 9 Security Considerations)
endobj
573 0 obj
-<< /S /GoTo /D (section.7.2) >>
+<< /S /GoTo /D (section.7.1) >>
endobj
576 0 obj
-(7.2 Chroot and Setuid)
+(7.1 Access Control Lists)
endobj
577 0 obj
-<< /S /GoTo /D (subsection.7.2.1) >>
+<< /S /GoTo /D (section.7.2) >>
endobj
580 0 obj
-(7.2.1 The chroot Environment)
+(7.2 Chroot and Setuid)
endobj
581 0 obj
-<< /S /GoTo /D (subsection.7.2.2) >>
+<< /S /GoTo /D (subsection.7.2.1) >>
endobj
584 0 obj
-(7.2.2 Using the setuid Function)
+(7.2.1 The chroot Environment)
endobj
585 0 obj
-<< /S /GoTo /D (section.7.3) >>
+<< /S /GoTo /D (subsection.7.2.2) >>
endobj
588 0 obj
-(7.3 Dynamic Update Security)
+(7.2.2 Using the setuid Function)
endobj
589 0 obj
-<< /S /GoTo /D (chapter.8) >>
+<< /S /GoTo /D (section.7.3) >>
endobj
592 0 obj
-(8 Troubleshooting)
+(7.3 Dynamic Update Security)
endobj
593 0 obj
-<< /S /GoTo /D (section.8.1) >>
+<< /S /GoTo /D (chapter.8) >>
endobj
596 0 obj
-(8.1 Common Problems)
+(8 Troubleshooting)
endobj
597 0 obj
-<< /S /GoTo /D (subsection.8.1.1) >>
+<< /S /GoTo /D (section.8.1) >>
endobj
600 0 obj
-(8.1.1 It's not working; how can I figure out what's wrong?)
+(8.1 Common Problems)
endobj
601 0 obj
-<< /S /GoTo /D (section.8.2) >>
+<< /S /GoTo /D (subsection.8.1.1) >>
endobj
604 0 obj
-(8.2 Incrementing and Changing the Serial Number)
+(8.1.1 It's not working; how can I figure out what's wrong?)
endobj
605 0 obj
-<< /S /GoTo /D (section.8.3) >>
+<< /S /GoTo /D (section.8.2) >>
endobj
608 0 obj
-(8.3 Where Can I Get Help?)
+(8.2 Incrementing and Changing the Serial Number)
endobj
609 0 obj
-<< /S /GoTo /D (appendix.A) >>
+<< /S /GoTo /D (section.8.3) >>
endobj
612 0 obj
-(A Appendices)
+(8.3 Where Can I Get Help?)
endobj
613 0 obj
-<< /S /GoTo /D (section.A.1) >>
+<< /S /GoTo /D (appendix.A) >>
endobj
616 0 obj
-(A.1 Acknowledgments)
+(A Appendices)
endobj
617 0 obj
-<< /S /GoTo /D (subsection.A.1.1) >>
+<< /S /GoTo /D (section.A.1) >>
endobj
620 0 obj
-(A.1.1 A Brief History of the DNS and BIND)
+(A.1 Acknowledgments)
endobj
621 0 obj
-<< /S /GoTo /D (section.A.2) >>
+<< /S /GoTo /D (subsection.A.1.1) >>
endobj
624 0 obj
-(A.2 General DNS Reference Information)
+(A.1.1 A Brief History of the DNS and BIND)
endobj
625 0 obj
-<< /S /GoTo /D (subsection.A.2.1) >>
+<< /S /GoTo /D (section.A.2) >>
endobj
628 0 obj
-(A.2.1 IPv6 addresses \(AAAA\))
+(A.2 General DNS Reference Information)
endobj
629 0 obj
-<< /S /GoTo /D (section.A.3) >>
+<< /S /GoTo /D (subsection.A.2.1) >>
endobj
632 0 obj
-(A.3 Bibliography \(and Suggested Reading\))
+(A.2.1 IPv6 addresses \(AAAA\))
endobj
633 0 obj
-<< /S /GoTo /D (subsection.A.3.1) >>
+<< /S /GoTo /D (section.A.3) >>
endobj
636 0 obj
-(A.3.1 Request for Comments \(RFCs\))
+(A.3 Bibliography \(and Suggested Reading\))
endobj
637 0 obj
-<< /S /GoTo /D (subsection.A.3.2) >>
+<< /S /GoTo /D (subsection.A.3.1) >>
endobj
640 0 obj
-(A.3.2 Internet Drafts)
+(A.3.1 Request for Comments \(RFCs\))
endobj
641 0 obj
-<< /S /GoTo /D (subsection.A.3.3) >>
+<< /S /GoTo /D (subsection.A.3.2) >>
endobj
644 0 obj
-(A.3.3 Other Documents About BIND)
+(A.3.2 Internet Drafts)
endobj
645 0 obj
-<< /S /GoTo /D (appendix.B) >>
+<< /S /GoTo /D (subsection.A.3.3) >>
endobj
648 0 obj
-(B Manual pages)
+(A.3.3 Other Documents About BIND)
endobj
649 0 obj
-<< /S /GoTo /D (section.B.1) >>
+<< /S /GoTo /D (appendix.B) >>
endobj
652 0 obj
-(B.1 dig)
+(B Manual pages)
endobj
653 0 obj
-<< /S /GoTo /D (section.B.2) >>
+<< /S /GoTo /D (section.B.1) >>
endobj
656 0 obj
-(B.2 host)
+(B.1 dig)
endobj
657 0 obj
-<< /S /GoTo /D (section.B.3) >>
+<< /S /GoTo /D (section.B.2) >>
endobj
660 0 obj
-(B.3 dnssec-dsfromkey)
+(B.2 host)
endobj
661 0 obj
-<< /S /GoTo /D (section.B.4) >>
+<< /S /GoTo /D (section.B.3) >>
endobj
664 0 obj
-(B.4 dnssec-keyfromlabel)
+(B.3 dnssec-dsfromkey)
endobj
665 0 obj
-<< /S /GoTo /D (section.B.5) >>
+<< /S /GoTo /D (section.B.4) >>
endobj
668 0 obj
-(B.5 dnssec-keygen)
+(B.4 dnssec-keyfromlabel)
endobj
669 0 obj
-<< /S /GoTo /D (section.B.6) >>
+<< /S /GoTo /D (section.B.5) >>
endobj
672 0 obj
-(B.6 dnssec-signzone)
+(B.5 dnssec-keygen)
endobj
673 0 obj
-<< /S /GoTo /D (section.B.7) >>
+<< /S /GoTo /D (section.B.6) >>
endobj
676 0 obj
-(B.7 named-checkconf)
+(B.6 dnssec-signzone)
endobj
677 0 obj
-<< /S /GoTo /D (section.B.8) >>
+<< /S /GoTo /D (section.B.7) >>
endobj
680 0 obj
-(B.8 named-checkzone)
+(B.7 named-checkconf)
endobj
681 0 obj
-<< /S /GoTo /D (section.B.9) >>
+<< /S /GoTo /D (section.B.8) >>
endobj
684 0 obj
-(B.9 named)
+(B.8 named-checkzone)
endobj
685 0 obj
-<< /S /GoTo /D (section.B.10) >>
+<< /S /GoTo /D (section.B.9) >>
endobj
688 0 obj
-(B.10 nsupdate)
+(B.9 named)
endobj
689 0 obj
-<< /S /GoTo /D (section.B.11) >>
+<< /S /GoTo /D (section.B.10) >>
endobj
692 0 obj
-(B.11 rndc)
+(B.10 nsupdate)
endobj
693 0 obj
-<< /S /GoTo /D (section.B.12) >>
+<< /S /GoTo /D (section.B.11) >>
endobj
696 0 obj
-(B.12 rndc.conf)
+(B.11 rndc)
endobj
697 0 obj
-<< /S /GoTo /D (section.B.13) >>
+<< /S /GoTo /D (section.B.12) >>
endobj
700 0 obj
-(B.13 rndc-confgen)
+(B.12 rndc.conf)
endobj
701 0 obj
-<< /S /GoTo /D [702 0 R /FitH ] >>
+<< /S /GoTo /D (section.B.13) >>
+endobj
+704 0 obj
+(B.13 rndc-confgen)
endobj
-705 0 obj <<
+705 0 obj
+<< /S /GoTo /D [706 0 R /FitH ] >>
+endobj
+709 0 obj <<
/Length 236
/Filter /FlateDecode
>>
stream
xÚÁJA †ïó9¶‡M'™d2s´T¥‚Beoâai·Rp·t­ïïÔÕ*êArÉÿ‘ü /A}È–ՓºsžŠvíèƒ ¨B)þP+!ÃlQ¡bJÕÂwìNì1úÈP©)&>áóÚÍ®˜€-A½bEM¦pæêÍÃd¾¼[L+V?ÉcºØt»~÷ršã~[÷í¶Ú~ÝNë a¤(±ø˘’å÷9·MÿÚ<Ÿ
endobj
-702 0 obj <<
+706 0 obj <<
/Type /Page
-/Contents 705 0 R
-/Resources 704 0 R
+/Contents 709 0 R
+/Resources 708 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 711 0 R
+/Parent 715 0 R
>> endobj
-703 0 obj <<
+707 0 obj <<
/Type /XObject
/Subtype /Form
/FormType 1
/PTEX.FileName (./isc-logo.pdf)
/PTEX.PageNumber 1
-/PTEX.InfoDict 712 0 R
+/PTEX.InfoDict 716 0 R
/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000]
/BBox [0.00000000 0.00000000 255.00000000 149.00000000]
/Resources <<
/ProcSet [ /PDF /Text ]
/ColorSpace <<
-/R15 713 0 R
-/R9 714 0 R
-/R11 715 0 R
-/R13 716 0 R
+/R15 717 0 R
+/R9 718 0 R
+/R11 719 0 R
+/R13 720 0 R
>>/ExtGState <<
-/R17 717 0 R
-/R8 718 0 R
->>/Font << /R19 719 0 R >>
+/R17 721 0 R
+/R8 722 0 R
+>>/Font << /R19 723 0 R >>
>>
-/Length 720 0 R
+/Length 724 0 R
/Filter /FlateDecode
>>
stream
@@ -1097,7 +1103,7 @@ xœu˜;“d9…ýû+®Ùe´R©— lG`XËkz#†10gwÙ~6ßÉ[53}+ˆ}tI%åóäÉT½ßs*{Ö?·¿××í'¿ûŸ?
FÑÞIca­Ç0Ú) ¹A¿+ÇÀº ¸|-Tuùa>‚s:½¯•~K“ÒÞV׋„OÒAŠI… ɪÁr2Q“°Ø¨Á>.z
ÏÆ狼eÇNdæÌdï"gK2cëÉ—GoOá8GëÏϦ:B Àht[
endobj
-712 0 obj
+716 0 obj
<<
/Producer (AFPL Ghostscript 8.51)
/CreationDate (D:20050606145621)
@@ -1107,46 +1113,46 @@ endobj
/Author (Douglas E. Appelt)
>>
endobj
-713 0 obj
-[/Separation/PANTONE#201805#20C/DeviceCMYK 721 0 R]
+717 0 obj
+[/Separation/PANTONE#201805#20C/DeviceCMYK 725 0 R]
endobj
-714 0 obj
-[/Separation/PANTONE#207506#20C/DeviceCMYK 722 0 R]
+718 0 obj
+[/Separation/PANTONE#207506#20C/DeviceCMYK 726 0 R]
endobj
-715 0 obj
-[/Separation/PANTONE#20301#20C/DeviceCMYK 723 0 R]
+719 0 obj
+[/Separation/PANTONE#20301#20C/DeviceCMYK 727 0 R]
endobj
-716 0 obj
-[/Separation/PANTONE#20871#20C/DeviceCMYK 724 0 R]
+720 0 obj
+[/Separation/PANTONE#20871#20C/DeviceCMYK 728 0 R]
endobj
-717 0 obj
+721 0 obj
<<
/Type /ExtGState
/SA true
>>
endobj
-718 0 obj
+722 0 obj
<<
/Type /ExtGState
/OPM 1
>>
endobj
-719 0 obj
+723 0 obj
<<
/BaseFont /NVXWCK#2BTrajanPro-Bold
-/FontDescriptor 725 0 R
+/FontDescriptor 729 0 R
/Type /Font
/FirstChar 67
/LastChar 136
/Widths [ 800 0 0 0 0 0 452 0 0 0 0 0 0 0 0 0 582 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 841 633 576 686 590 540 923 827 407 760]
-/Encoding 726 0 R
+/Encoding 730 0 R
/Subtype /Type1
>>
endobj
-720 0 obj
+724 0 obj
2362
endobj
-721 0 obj
+725 0 obj
<<
/Filter /FlateDecode
/FunctionType 4
@@ -1157,7 +1163,7 @@ endobj
stream
xœ«N)-P0PÈ-ÍQH­HÎP
endobj
-722 0 obj
+726 0 obj
<<
/Filter /FlateDecode
/FunctionType 4
@@ -1168,7 +1174,7 @@ endobj
stream
xœ«N)-P0PÈ-ÍQH­HÎP
endobj
-723 0 obj
+727 0 obj
<<
/Filter /FlateDecode
/FunctionType 4
@@ -1179,7 +1185,7 @@ endobj
stream
xœ«N)-P0TÈ-ÍQH­HÎP
endobj
-724 0 obj
+728 0 obj
<<
/Filter /FlateDecode
/FunctionType 4
@@ -1190,7 +1196,7 @@ endobj
stream
xœ«N)-P0Ð365³TÈ-ÍQH­HÎP€Š™X ‹™›#Ä ô -,ŒÀüZ
endobj
-725 0 obj
+729 0 obj
<<
/Type /FontDescriptor
/FontName /NVXWCK#2BTrajanPro-Bold
@@ -1203,17 +1209,17 @@ endobj
/StemV 138
/MissingWidth 500
/CharSet (/Msmall/C/Ysmall/Nsmall/Osmall/Esmall/Rsmall/S/Ssmall/I/Tsmall/Ismall/Usmall)
-/FontFile3 727 0 R
+/FontFile3 731 0 R
>>
endobj
-726 0 obj
+730 0 obj
<<
/Type /Encoding
/BaseEncoding /WinAnsiEncoding
/Differences [ 127/Nsmall/Tsmall/Esmall/Rsmall/Ysmall/Ssmall/Msmall/Osmall/Ismall/Usmall]
>>
endobj
-727 0 obj
+731 0 obj
<<
/Filter /FlateDecode
/Subtype /Type1C
@@ -1236,40 +1242,41 @@ x¸ \3§gA34–ITž-‹R8õ-ǵÛö2ªWuÉ~Á!"(0Š*FÂ͢ùĨ¸SˆˆoÊQPˆ0¦šåiFäݸVN^_!Ô‚–b
ȼLçÇ<;— *X³«¥×ÛGâ_Y1ETïƒ4ˆÒ-U…_>´üØ¢æ}õï÷v¼ §ádù#¹rÛŸå¥@ÔÁ\5l…hð<8Ús·
»O·Øèv61Bá5*È<6ÞÍ,‡bh‘˜¶ž\Î]Çé#¹#ØÔÍ1Oúñ°Ï¤5oÂ]цÆß4}h˜î0$å,6ü¼”A,¯?/å;Rôcy6Ò½UJ¿§Y½X^é¶ÙÉŸ‡‹º–2¸K|o½Ø”/Ȩ/ƒ( Â2Ð#žNMKðrˆ rœÛf9ËyZ¸Ú}$«Ö õ–©)  h`iÎGàAç÷´€H+Šˆ…Õ&*áX$žèìVŽhª”—›¾÷‡A1Ý£¤œÏ0‰÷—Hi éƒw~I(Áö2;à]¸L ™x4[¡OÜ,¾®ÆûÂQQ°”FdQ“ƒ¢¬„%\î¢Åâ:Ó;ÈÑ”ÌEb1ž’¡ˆÿ§=$¸¥?Iš¿CÐõ3¾C=VÐ'>·¯ôÌÒ+Ü~8 ç#;úÁ_£×á*qň+ô 8®‚ãÆpêŒ_YR”¾d%a ç¡H\eÄõãDf£Ñ¨­ŽR[kφG¸ù/WT®ò•A5”H¥ÛVoo8hnû)¼ÞÃDn…ñëqÌzfåhý&þcQbµXÇß‚çLŽúõ;{²Ðñðué¿ÊÛÙ†-©[SÄ-Û¼ÔyubÜñhüm´œ4^Ë™ ääšLÿQ‹¡endstream
endobj
-706 0 obj <<
-/D [702 0 R /XYZ 85.0394 794.5015 null]
+710 0 obj <<
+/D [706 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-707 0 obj <<
-/D [702 0 R /XYZ 85.0394 769.5949 null]
+711 0 obj <<
+/D [706 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-704 0 obj <<
-/Font << /F21 710 0 R >>
-/XObject << /Im1 703 0 R >>
+708 0 obj <<
+/Font << /F21 714 0 R >>
+/XObject << /Im1 707 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-730 0 obj <<
+734 0 obj <<
/Length 1001
/Filter /FlateDecode
>>
stream
-xÚµVM“¢:Ýû+XjU“É_Y҈ʂ8]S3³°»©jÅ'8]ýïß…$"êëÍÔ+¹IŽ÷žsr Ãh¦…,N¹fs™˜˜Úz7ÀÚ ìMDb°¦cĸÓnþ3øùk
-¹¿z{kuîÀ!57áR Ô.òªmh\Ì3X#ÖFœQ»…d3_¶Y<ÉžFœÝD®©Iü=ûc1kn®›*D3±Õ¢'‚1D¡Ì%Ø CÈ*‰e/7Ÿ‚l&¢ÄŸºÉX\Ixæ2Ò—”5îÇšÍÅ;ä#/\ŽƒhzU<˜/Â@i¹Ç$žˆqî'Þ 6F¶1tƒ0È~tBvâ†c+v¤e7 ²ÈOS¤8ˆ1’|ýï>ä„g#å×£¤îc(ãIœ¨ª²|ºð½À ”ljïµÕÓ6ºY‚mŒLÎyßO/ŽRÿÛˆAR™Ó»Ó³×õ{»O3·)”¥1hKԦ˰]=»?Iâ¹Ô§Ï +Œà¹xuÆËÔWòDúö ú| )ÁìôAñð¡‘“¾í®½,ˆ£þé‚ì,q{6Eþ4 ¦~äùýJq›¹}Xˆ:„ô\4d2b6Ž—éeM™ÙM‚ôìE¼ÌúTâ+Ú@-ò/(wWã|WÁ ÞÑ6—>z&.üšgîvz&ŸÝš›7‰úc&j¾’î~Œ©zý1¦«jºa#æ8ôþ›ˆ:ðƲٙTû^½!}N™Eï0ÿŸûh~endstream
+xÚµV]“¢8}÷Wð¨UM:|å‘FT¦ÀéÚš™[±›ªV\Åéê¿’€¨Û/[[>ä$9Þ{îÉ @4 ?¢™²8åšÍ dbbjëÝ
+ ¹ÝX¢x¿À8Aí%%A½±!QŒ‡‘NM\C³ƒVí:ä-$X `_åÇ}^‰YúyªòÝIL¼r*UqÞ=(îtF0È4ñ/J õꦤV=ð³ÖOÂ(2-ËÃ47¿4¿eë—ô[÷ ³áÔmÞEý7ûéÿi?î,%¤dwÝ-·ÕÇê8"Î0¿¶]ûíM)v4›2Ði9_Ú§Èú%ûÖ=ÓASÒŬËYäÇ]q:å^hªJ1žO¹¬g öŽ!C9ß•›bÛ[Yí7åQàMqªŽÅ˹’5Vo…l¨ÓMý[õ§ÕþS€Ãùx(Orû£¨ÞR¼z¥<K?·¹äA‚úà A”Aoè
+KÔé¥Ë°Ym­Ÿ$ñ\§Éµ$ŒàÁxuÀËÔWµ‰ðÍôõ@G‚ÓéƒÒáC'}Ï]5zYGý£…²³ÄíyùÓ0˜ú‘ç÷3ÅMäZ+|P‡ô[4c2b6Ô/ÓË”2°›ikE¼ÌúJâ+Õ ,ò/w×¢½§àOïXë‹Ï雸ð蜹ÛÕ3ùêÊܾJä—3QýÁt÷»LåûÏßeºÊ¦6bŽCï¿Š¨ƒ·Y+ªy±Þ‡&§Ì¢w”ÿ¾Èjæendstream
endobj
-729 0 obj <<
+733 0 obj <<
/Type /Page
-/Contents 730 0 R
-/Resources 728 0 R
+/Contents 734 0 R
+/Resources 732 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 711 0 R
+/Parent 715 0 R
>> endobj
-731 0 obj <<
-/D [729 0 R /XYZ 56.6929 794.5015 null]
+735 0 obj <<
+/D [733 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-728 0 obj <<
-/Font << /F23 734 0 R /F14 737 0 R >>
+732 0 obj <<
+/Font << /F23 738 0 R /F14 741 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-740 0 obj <<
+744 0 obj <<
/Length 2891
/Filter /FlateDecode
>>
@@ -1289,1334 +1296,1337 @@ W±ïëå*¯úoÞæ®x­]Δܫ!$j2È¢
M…­æ:h¾nêãô¨ýèá·oðÐkƒh—#öùlk…lMfR,`5("qP,Þ„b‰Ðø˜Ž~]í»=Ãמ,Åzž%húg°º
ÁîGÓäm2ƒÅREŽ7XD‚ ˆ \@pÁ,tûµDÀ'/œÕ½ÊýØø@Á_™'Hûd !E–•B*Åéö®ÒŒ‘@aaëêdz¿µÍ:ê°uõÕ¶HA‰©”!;2¬3ÁX$1Ò5–$LCK¢[ÎÂéÌù›ödŽ÷ÇršgľڀŠL% Ù¤a½ Ò"AP‡…r=|Ê?SRxÐRèWywqqvê:ûñÌ7ƒÊ'*SƒVZâï<Ž`¨ðwæ2ciìÈÛÕ÷ Ε[~©‘&Å3çë™SÿÀóøóp%ðö?ž­®Bendstream
endobj
-739 0 obj <<
+743 0 obj <<
/Type /Page
-/Contents 740 0 R
-/Resources 738 0 R
+/Contents 744 0 R
+/Resources 742 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 711 0 R
-/Annots [ 743 0 R 744 0 R 745 0 R 746 0 R 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R ]
+/Parent 715 0 R
+/Annots [ 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R 793 0 R 794 0 R 795 0 R 796 0 R ]
>> endobj
-743 0 obj <<
+747 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 688.709 539.579 697.2967]
/Subtype /Link
/A << /S /GoTo /D (chapter.1) >>
>> endobj
-744 0 obj <<
+748 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 676.5858 539.579 685.4425]
/Subtype /Link
/A << /S /GoTo /D (section.1.1) >>
>> endobj
-745 0 obj <<
+749 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 664.4876 539.579 673.3442]
/Subtype /Link
/A << /S /GoTo /D (section.1.2) >>
>> endobj
-746 0 obj <<
+750 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 652.3894 539.579 661.246]
/Subtype /Link
/A << /S /GoTo /D (section.1.3) >>
>> endobj
-747 0 obj <<
+751 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 640.1914 539.579 649.1477]
/Subtype /Link
/A << /S /GoTo /D (section.1.4) >>
>> endobj
-748 0 obj <<
+752 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 628.0932 539.579 637.0495]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.1) >>
>> endobj
-749 0 obj <<
+753 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 615.995 539.579 624.9512]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.2) >>
>> endobj
-750 0 obj <<
+754 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 603.8967 539.579 612.853]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.3) >>
>> endobj
-751 0 obj <<
+755 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 591.7985 539.579 600.7547]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.4) >>
>> endobj
-752 0 obj <<
+756 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 579.7002 539.579 588.6565]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.4.1) >>
>> endobj
-753 0 obj <<
+757 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 567.6019 539.579 576.5582]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.4.2) >>
>> endobj
-754 0 obj <<
+758 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 555.5037 539.579 564.46]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.4.3) >>
>> endobj
-755 0 obj <<
+759 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 543.4055 539.579 552.5112]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.5) >>
>> endobj
-756 0 obj <<
+760 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 531.3072 539.579 540.413]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.5.1) >>
>> endobj
-757 0 obj <<
+761 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 519.209 539.579 528.3147]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.6) >>
>> endobj
-758 0 obj <<
+762 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 496.7003 539.579 505.4125]
/Subtype /Link
/A << /S /GoTo /D (chapter.2) >>
>> endobj
-759 0 obj <<
+763 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 484.5772 539.579 493.5832]
/Subtype /Link
/A << /S /GoTo /D (section.2.1) >>
>> endobj
-760 0 obj <<
+764 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 472.4789 539.579 481.485]
/Subtype /Link
/A << /S /GoTo /D (section.2.2) >>
>> endobj
-761 0 obj <<
+765 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 460.3806 539.579 469.3867]
/Subtype /Link
/A << /S /GoTo /D (section.2.3) >>
>> endobj
-762 0 obj <<
+766 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 448.2824 539.579 457.2885]
/Subtype /Link
/A << /S /GoTo /D (section.2.4) >>
>> endobj
-763 0 obj <<
+767 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 436.1841 539.579 445.1902]
/Subtype /Link
/A << /S /GoTo /D (section.2.5) >>
>> endobj
-764 0 obj <<
+768 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 413.4314 539.579 422.288]
/Subtype /Link
/A << /S /GoTo /D (chapter.3) >>
>> endobj
-765 0 obj <<
+769 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 401.353 539.579 410.4588]
/Subtype /Link
/A << /S /GoTo /D (section.3.1) >>
>> endobj
-766 0 obj <<
+770 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 389.2548 539.579 398.3605]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.1.1) >>
>> endobj
-767 0 obj <<
+771 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 377.1565 539.579 386.2623]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.1.2) >>
>> endobj
-768 0 obj <<
+772 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 365.1579 539.579 374.164]
/Subtype /Link
/A << /S /GoTo /D (section.3.2) >>
>> endobj
-769 0 obj <<
+773 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 353.0597 539.579 362.0658]
/Subtype /Link
/A << /S /GoTo /D (section.3.3) >>
>> endobj
-770 0 obj <<
+774 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 340.9614 539.579 349.9675]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.3.1) >>
>> endobj
-771 0 obj <<
+775 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 328.7635 539.579 337.8693]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.3.3.1.1) >>
>> endobj
-772 0 obj <<
+776 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 316.6653 539.579 325.771]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.3.3.1.2) >>
>> endobj
-773 0 obj <<
+777 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 304.567 539.579 313.6728]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.3.2) >>
>> endobj
-774 0 obj <<
+778 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 281.9139 539.579 290.7706]
/Subtype /Link
/A << /S /GoTo /D (chapter.4) >>
>> endobj
-775 0 obj <<
+779 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 269.8356 539.579 278.9413]
/Subtype /Link
/A << /S /GoTo /D (section.4.1) >>
>> endobj
-776 0 obj <<
+780 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 257.7373 539.579 266.8431]
/Subtype /Link
/A << /S /GoTo /D (section.4.2) >>
>> endobj
-777 0 obj <<
+781 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 245.6391 539.579 254.7448]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.2.1) >>
>> endobj
-778 0 obj <<
+782 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 233.5408 539.579 242.4971]
/Subtype /Link
/A << /S /GoTo /D (section.4.3) >>
>> endobj
-779 0 obj <<
+783 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 221.4426 539.579 230.3988]
/Subtype /Link
/A << /S /GoTo /D (section.4.4) >>
>> endobj
-780 0 obj <<
+784 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 209.3443 539.579 218.3006]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.4.1) >>
>> endobj
-781 0 obj <<
+785 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 197.2461 539.579 206.2023]
/Subtype /Link
/A << /S /GoTo /D (section.4.5) >>
>> endobj
-782 0 obj <<
+786 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 185.1478 539.579 194.1041]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.1) >>
>> endobj
-783 0 obj <<
+787 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 173.0496 539.579 182.0058]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.4.5.1.1) >>
>> endobj
-784 0 obj <<
+788 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 161.051 539.579 170.0571]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.4.5.1.2) >>
>> endobj
-785 0 obj <<
+789 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 148.9527 539.579 157.9588]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.2) >>
>> endobj
-786 0 obj <<
+790 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 136.8545 539.579 145.8606]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.3) >>
>> endobj
-787 0 obj <<
+791 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 124.7562 539.579 133.7623]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.4) >>
>> endobj
-788 0 obj <<
+792 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 112.5583 539.579 121.5146]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.5) >>
>> endobj
-789 0 obj <<
+793 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 100.4601 539.579 109.4163]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.6) >>
>> endobj
-790 0 obj <<
+794 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 88.3618 539.579 97.3181]
/Subtype /Link
/A << /S /GoTo /D (section.4.6) >>
>> endobj
-791 0 obj <<
+795 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 76.2636 539.579 85.2199]
/Subtype /Link
/A << /S /GoTo /D (section.4.7) >>
>> endobj
-792 0 obj <<
+796 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 64.1653 539.579 73.1216]
/Subtype /Link
/A << /S /GoTo /D (section.4.8) >>
>> endobj
-741 0 obj <<
-/D [739 0 R /XYZ 85.0394 794.5015 null]
+745 0 obj <<
+/D [743 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-742 0 obj <<
-/D [739 0 R /XYZ 85.0394 711.9273 null]
+746 0 obj <<
+/D [743 0 R /XYZ 85.0394 711.9273 null]
>> endobj
-738 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R >>
+742 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-795 0 obj <<
-/Length 3159
+799 0 obj <<
+/Length 3161
/Filter /FlateDecode
>>
stream
-xÚí[wÛ¸Çßý)ôh?Åýò˜ûɶM²±÷¥Û}`dÆÖ‰$z%9©ûé Š8´À‘ÐÆili÷ìÚ‰9œñüÂ`@d#êÿe#¥‰vÜŒ“DQ¦F“ù ]ùŸ½9aí1ãpÐõüâä/¯…9â4×£‹Ï#©ájs2K¨µltqùûé‹÷ï.^½»8?ûãâ—“Wñ¬Ð3£¢>åŸ'¿ÿAG—>€_N(ΪÑ7ÿJ˜s|4?‘J%…3;9?ù5žütcšüM%\hžøU¸
-0ÄHba¤$âÀHÙòžs%–ºSÝŽ¹[Cm×Áëiµä|.—åbRg.œ|ïñ`ã- Z°áŒÓa™ÚòšüL1KŒiWuo“©y= s‹W³r^.Ö~¢˜9Ô~eÒìO0Ä>YP2Œ“D/¨÷0i¥š©UÀe¸Qù{±ž\‡¢¼ªQц{Ú{¨„tf£ 1T \‚£’ˆCõθ&R09Räí`Ùà"êõ»Åºø×ÙX8u\ZÝ”˜Ê\P !JO*”T(¸÷ˉ¶‚Px Ê˲®C‹iW…ŠÅeè{‹«zuþg˜éÿˆUö˜¥l€!Æ
-0ÄPra¨$âÀPA½wÃ…²D3g:XŽuå¿%¤2`ˆ¥Â@IÄ‚zï@‘š(Û57”c]Ùf d)›`ˆ1
- ߯¿}³,æó¢^=2âØÞÞÃ%d4`ˆáÃpIÄá‚zÓΉâ2T–º®x÷÷l#ÖRéÔG“Y{LoR„3nÛcÎןì¦1‘.Ãí±Ž9Ïæ b<AM…æ)Æê=ðä—NDœøCà´»”YÇžÞ0Ô¦6›šÎƒ‡1³† æº%F:K¤Ž'b'2“j±^V³U‚áe‚uOrB'æ8—hˆÀÓÓ¡'‚î=ðcýÜ—»®‚Éãg)´â—ANB.³9†'P+1¼­1Æ ê=pbd½;b¢vb2]Lf·—eŠMŒc»&;–ñƒš'‡ gÃÓÙaì
-ΈýîÃ4T4O+®¡¸8sôtY,VŸ7“
-eØ‹˜¸l,€!†F oBIÅazï° ŽÊzµÄ6XüöòCCŇøÚö‰<J‡‹.sÙ\
-(ËðÂe" ÌuGWDš~KÁT,7ôô¶}·>Øg'åò™M
-0ÄPéé5ü@¥T,¨÷Ž&ˆ”÷:ÝÐòüv:[ÃëpV _™.>o^_wHü»ZÔkáƸG¹s&f![c`ˆiÜËòðšd*LcÔ{§1eD2ݓؤ$~5¿Yßu¯V«/nüDKPÛ‚´9Ê ³Ãô‡
- oˆI©¹Žâ[G„•¢'¾mÄvy¹ÙäTÌÂUîI÷‰~QL®7uÂiýtdÙÈ•Ø!2÷r=¼Äœ‘u^PeˆP|Âw?ΡÎõŒè÷Rsó”'
-ƒo¼jý«Î{ß”yÝÕvØÛ®0×Ὂšû@øìó,¼§Ðs¶ùÌwK0CßÜÒi…¼+k+‚-Dâ»~ÇÜyi“/,ñÿ1â”âÿû«…»7 ËúÖ";°=‹[J\ýÖ.á篢½s¹%fsˆü?ìÑTÿendstream
+xÚí[wÛ¸Çßý)ôh?Åýò˜ûɶM²±÷¥Û}`dÆÖ‰$z%9©ûé Š8´À‘ÐÆili÷ìÚ‰9œñüÂ`@d#êÿe#¥‰vÜŒ“DQ¦F“ù ]ùŸ½9aí1ãpÐõüâä/¯…9â4×£‹Ï#©ájs2K¨µltqùûé‹÷ï.^½»8?ûãâ—“Wñ¬Ð3£¢>åŸ'¿ÿAG—>€_N(ΪÑ7ÿJ˜s|4?‘J%…3;9?ù5žütcšüM%\hžøU¸
+
+0Ä@Ra $âÀ@A½w HM”íšʱ®l3²”Í
+©Í¦¦³Ã ÂaÌl!ƒ¹Äpωa2n'2³êêªÞI–(TÆyNíZÏQò vÆg£ 1v „<‰80zPï&ýáNwKô¡øÙc¢óÿÙeõÝîËlN€!Æ Ô
+ã$Æ ê=^e’”N¤Ô×#m»myM}W-ìwr],ejÕÏrR)Ý÷ázY¬< ZðÚՄôfà 1x |’ÓˆƒõáÎÃb@;UŸ ?\UËÔLGR¢­¹¤ö *TLo.<Ч'Ÿäƒð¤â@àÁ½wðK˜”°FÕ·§î ÏŸ·åòn\.—Õ2µø§,q҆ſ4/´Ô r2™Í 0Ä8JÉáýu©80NPïíLÆ÷ê„1êÓî«š³oË2Å÷ó˜8¨ Mƒ¹Ò|}<¦;%`ˆ¡åÄPJÄ¡„z()I¨e¼C‰?J»gÄ’¹'T¥BZ³‘†2P69¼ +† ê= #9¡Ò©™ÝW4çÅj]&kRÝGI§wöáú°f9!ÇÙü
endobj
-794 0 obj <<
+798 0 obj <<
/Type /Page
-/Contents 795 0 R
-/Resources 793 0 R
+/Contents 799 0 R
+/Resources 797 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 711 0 R
-/Annots [ 800 0 R 801 0 R 802 0 R 803 0 R 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R ]
+/Parent 715 0 R
+/Annots [ 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R 857 0 R 858 0 R 859 0 R 860 0 R ]
>> endobj
-800 0 obj <<
+804 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 758.4766 511.2325 767.4329]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.8.1) >>
>> endobj
-801 0 obj <<
+805 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 746.445 511.2325 755.4012]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.8.2) >>
>> endobj
-802 0 obj <<
+806 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 734.5129 511.2325 743.3696]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.8.3) >>
>> endobj
-803 0 obj <<
+807 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 722.3816 511.2325 731.3379]
/Subtype /Link
/A << /S /GoTo /D (section.4.9) >>
>> endobj
-804 0 obj <<
+808 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 710.3499 511.2325 719.3062]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.9.1) >>
>> endobj
-805 0 obj <<
+809 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 698.3182 511.2325 707.2745]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.9.2) >>
>> endobj
-806 0 obj <<
+810 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 675.998 511.2325 684.7301]
+/Rect [499.2773 675.998 511.2325 684.8547]
/Subtype /Link
/A << /S /GoTo /D (chapter.5) >>
>> endobj
-807 0 obj <<
+811 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 663.9862 511.2325 672.9425]
+/Rect [499.2773 663.9862 511.2325 673.0919]
/Subtype /Link
/A << /S /GoTo /D (section.5.1) >>
>> endobj
-808 0 obj <<
+812 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 651.9545 511.2325 660.9108]
+/Rect [499.2773 651.9545 511.2325 661.0603]
/Subtype /Link
/A << /S /GoTo /D (section.5.2) >>
>> endobj
-809 0 obj <<
+813 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 629.6343 511.2325 638.4909]
+/Rect [499.2773 629.6343 511.2325 638.3664]
/Subtype /Link
/A << /S /GoTo /D (chapter.6) >>
>> endobj
-810 0 obj <<
+814 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 617.6225 511.2325 626.7282]
+/Rect [499.2773 617.6225 511.2325 626.5788]
/Subtype /Link
/A << /S /GoTo /D (section.6.1) >>
>> endobj
-811 0 obj <<
+815 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 605.5908 511.2325 614.5471]
+/Rect [499.2773 605.5908 511.2325 614.6966]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.1.1) >>
>> endobj
-812 0 obj <<
+816 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 593.5591 511.2325 602.5154]
+/Rect [499.2773 593.5591 511.2325 602.6649]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.1.1) >>
>> endobj
-813 0 obj <<
+817 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 581.5275 511.2325 590.4837]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.1.2) >>
>> endobj
-814 0 obj <<
+818 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 569.4958 511.2325 578.4521]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.1.2) >>
>> endobj
-815 0 obj <<
+819 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 557.4641 511.2325 566.4204]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.2.1) >>
>> endobj
-816 0 obj <<
+820 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 545.4324 511.2325 554.5382]
+/Rect [499.2773 545.4324 511.2325 554.3887]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.2.2) >>
>> endobj
-817 0 obj <<
+821 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 533.4007 511.2325 542.5065]
+/Rect [499.2773 533.4007 511.2325 542.357]
/Subtype /Link
/A << /S /GoTo /D (section.6.2) >>
>> endobj
-818 0 obj <<
+822 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 521.3691 511.2325 530.3254]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.1) >>
>> endobj
-819 0 obj <<
+823 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 509.3374 511.2325 518.2937]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.2) >>
>> endobj
-820 0 obj <<
+824 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 497.3057 511.2325 506.262]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.3) >>
>> endobj
-821 0 obj <<
+825 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 485.274 511.2325 494.2303]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.4) >>
>> endobj
-822 0 obj <<
+826 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 473.2424 511.2325 482.1986]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.5) >>
>> endobj
-823 0 obj <<
+827 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 461.2107 511.2325 470.167]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.6) >>
>> endobj
-824 0 obj <<
+828 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 449.179 511.2325 458.1353]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.7) >>
>> endobj
-825 0 obj <<
+829 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 437.1473 511.2325 446.1036]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.8) >>
>> endobj
-826 0 obj <<
+830 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 425.1157 511.2325 434.0719]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.9) >>
>> endobj
-827 0 obj <<
+831 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 413.084 511.2325 422.0403]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.10) >>
>> endobj
-828 0 obj <<
+832 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 401.0523 511.2325 410.0086]
+/Rect [499.2773 401.0523 511.2325 410.158]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.10.1) >>
>> endobj
-829 0 obj <<
+833 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 389.0206 511.2325 398.1264]
+/Rect [499.2773 389.1203 511.2325 398.1264]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.10.2) >>
>> endobj
-830 0 obj <<
+834 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 377.0886 511.2325 386.0947]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.10.3) >>
>> endobj
-831 0 obj <<
+835 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 365.0569 511.2325 374.063]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.11) >>
>> endobj
-832 0 obj <<
+836 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 352.9256 511.2325 362.0313]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.12) >>
>> endobj
-833 0 obj <<
+837 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 340.8939 511.2325 349.9997]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.13) >>
>> endobj
-834 0 obj <<
+838 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 328.8622 511.2325 337.968]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.14) >>
>> endobj
-835 0 obj <<
+839 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 316.8305 511.2325 325.9363]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.15) >>
>> endobj
-836 0 obj <<
+840 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 304.7989 511.2325 313.9046]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.16) >>
>> endobj
-837 0 obj <<
+841 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 292.7672 511.2325 301.873]
+/Rect [499.2773 292.7672 511.2325 301.7235]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.1) >>
>> endobj
-838 0 obj <<
+842 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 280.7355 511.2325 289.6918]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.2) >>
>> endobj
-839 0 obj <<
+843 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 268.7038 511.2325 277.6601]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.3) >>
>> endobj
-840 0 obj <<
+844 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 256.6722 511.2325 265.6285]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.4) >>
>> endobj
-841 0 obj <<
+845 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 244.6405 511.2325 253.5968]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.5) >>
>> endobj
-842 0 obj <<
+846 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 232.6088 511.2325 241.5651]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.6) >>
>> endobj
-843 0 obj <<
+847 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 220.5771 511.2325 229.5334]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.7) >>
>> endobj
-844 0 obj <<
+848 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 208.5455 511.2325 217.5017]
+/Rect [499.2773 208.5455 511.2325 217.6512]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.8) >>
>> endobj
-845 0 obj <<
+849 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 196.5138 511.2325 205.4701]
+/Rect [499.2773 196.5138 511.2325 205.6195]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.9) >>
>> endobj
-846 0 obj <<
+850 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 184.4821 511.2325 193.4384]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.10) >>
>> endobj
-847 0 obj <<
+851 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 172.4504 511.2325 181.5562]
+/Rect [499.2773 172.4504 511.2325 181.4067]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.11) >>
>> endobj
-848 0 obj <<
+852 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 160.4187 511.2325 169.5245]
+/Rect [499.2773 160.4187 511.2325 169.375]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.12) >>
>> endobj
-849 0 obj <<
+853 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 148.3871 511.2325 157.3433]
+/Rect [499.2773 148.3871 511.2325 157.4928]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.13) >>
>> endobj
-850 0 obj <<
+854 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 136.3554 511.2325 145.3117]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.14) >>
>> endobj
-851 0 obj <<
+855 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 124.3237 511.2325 133.4295]
+/Rect [499.2773 124.3237 511.2325 133.28]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.15) >>
>> endobj
-852 0 obj <<
+856 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 112.292 511.2325 121.2483]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.16) >>
>> endobj
-853 0 obj <<
+857 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 100.2604 511.2325 109.2166]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.17) >>
>> endobj
-854 0 obj <<
+858 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 88.2287 511.2325 97.185]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.18) >>
>> endobj
-855 0 obj <<
+859 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 76.197 511.2325 85.1533]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.17) >>
>> endobj
-856 0 obj <<
+860 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 64.1653 511.2325 73.1216]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.18) >>
>> endobj
-796 0 obj <<
-/D [794 0 R /XYZ 56.6929 794.5015 null]
+800 0 obj <<
+/D [798 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-793 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R >>
+797 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-859 0 obj <<
-/Length 3451
+863 0 obj <<
+/Length 3456
/Filter /FlateDecode
>>
stream
-xÚíKSGÇï|
-ŽX8P®gWÕîa’qXH 8¼±¶£™tˆéÁó
-³† P" D ¨÷ˆ¢®¼á- Wƒ™CBPþ5!ñÅ9Ù„‹Oh6.ÀÃ
-¦U?.‰80\Pïg`[ÁEÜ­'ï®›¶£A‡¿”‘ ›Ï\6Àã*£‹~.q`\ Þ#ŽÍ]—p![.?׃q5ìz×#×Ùh¿?¹ª†UÓêH¥ž¬ì>1Ù²CLv˜xmúeOÄÉŽzwk„Ø.˜¹JíUw…€Ñ•Jðººj&Ï•ýê[GÝ…õ2d3 1Ơ̦ž%Æê=Ž{('ªP²¦ÿÊ8]é¶6¬M>¶_OËÙd1ÝefgXúŸ 'ËŒfw4?]–Ýg>ñCß)¾,Çn¨£Å㛤 ÉÖbzÃŒcz'âÀôF½‡¦DYJ¤EÔ{©¸Ø,­ì9ö,BÂrq€†+‚ 8¤â@pÀ½G´!’2ˆïpp€ï”¿Ïƒ«–†ò÷ë% ål&/BY8]ŽeŠ§Ú„<eS
- FôSˆ£
-w[&ýbÜ7ïNߟ$í¤vÍ çÝu+HíîYÅžêžµÐl\€!†  Ã%† ê=âB±ÔB\x.Ç'?üxx”Úº¦-D/\<½ºâS™
-0Ä@Ra $âÀ@A½P¤Ä]Ï("×óMí(ˆ‘¶ý0ÓòÖy )Î"
-9¾vÒ~¨®ªùçVÛÛj~ÙNø»ÒÔ®“HýQêå¤Sb>R&™5XÄcëöáS– 0Ä€€’Øþ“Œ©80 Ö¼³ÄKiœðD*Ù.Ô7“GteÑO”ÃÅ4Pq0©gÕ¨œÚ£½yó·vÜ/_À`=âõû.óÕ¿7ÞËÓš×ÔTŠp× Í»³‚ËŽl3•²?–³PëùrêsÒ͹ýàÊäòwòe^%ÿ©ó Ï~ê€!öÔAA1Šq`4¡ÞMÍÉ,K=M©W[¸¡¶e’uåóàr:™ÌEVHB]?½»¬Ù ˜Î·D(-üÑr¾¨F©[×9”¦»ì™oòÿ_ˆõ¢f 1b!4¶¿L*ŒXÔ{˜òLNM@6nÝO.!)æ¸4ž¹a/¾n¬Ø<-íeGõM»x4©Û3Ì¢ϧ örå3ŸÍ0ĸ‚Êb\%âÀ¸B½G®¨C‰"påwÿ8 ›óÒ«”ºpw`¾ôÍzË%š†µó׋zØž†—ú94¶½Pù´gC 1¨ ¬T‰80¨Pï¾yuåÌUé™ògÙzO/Æî­VÅË4u˜Ó\` !ÌŠf0©8`Ö½§FA¼h´ÜT—ƒ ó]ÆØÎt²øpUÎ.]óÕ”£Þìt7¸ïP\Œt`X¶±Ü ËÄ]—É'G)Ò½„É„AÎÁd<ög2Þ·í³ËɸÄKù2¦É”Ú$g?HÁ {Œ¢€1k`à ~C3Î¥ ‚w¯F1ÝRÏrËýüoÝø¸žtS‰·“é'÷0ý£ý¿ËÉmûÍpà÷à·_šW×\´G»:=Yø;\Âmo»ãÅ?]ùfæµ±!'ÙJCLk˜sLíD˜Þ¨÷P)š®»T^pÞÕŠãzØ*ÖtàC.Ò=¸Ô+ý:¿
-XùJ'‹ñ‡fAö tÞCš²
-Êž
->YÙ(
-#u‹„týtÓ¦Üo§ð›"qüþ¦èžúÑÈ¿tÿŠç×£Ûwÿ¸¯¬Yµ×Ïx“·—Ñç1`ˆauB1I‚a‚ºDÄU1O‰h È«êÃU5¹˜®/?G0B+q¶¸¸(›—ïûÂ2¹Q^ËŒàü™”Ÿ¹l.€!ÆTå"Æê>–. cÝ™Éýöå]Mù8-[8í[å]ëáwCŒ»þª‡åôõÁ¬%ÂþÄ;^1Ÿ²l"€!F”%"Fê>Á¸½éHï”fWí‡ù‡ÓÁdžkùËå>Ðø¬fC 1h jŒö/µ¤Á AÝhšvFuç%÷Ûwû4Ì€×nN† P;ö?„yßv0¢Ø3)>U¹
-„‚5ß©Ù­‰¤-€¯šæ@ì¼ÔáÕo׃‹Ô”Ovg»iÂÇç"^žšîY½g›‰þÃÜñ^ØŸ¹ã0ù²UEoWi^-›QawFÕÅ“ª‘_Á1½NýNܧ,š!P#k=„5ÂÂrÜã–$÷§7ÿe,<~îïFÆ¿nÙ¼¬ÆôýÁ.A­‹œ6‰Is¯æƒ*dKîò"ùû\,Œendstream
+xÚí[SÜFÇßùó°U tú&u÷îÃ.슱Hek“<ŒgäAeF"sx?ý¶Fêî3Lë ½‰âªƒŽÎ™óÿéô]°µØ@g„
+#ÊH’Q– FÓ:˜ØŸ½ÙaÝ5ûî¢}xÕ«‹o^ 50Ää<\|÷Ò„jÍãŸvß^Ÿ^œïýrñÝÎñ…¿)t̨hîøëÎO¿ÐÁØúÿn‡at6¸µÿ „ÃÓ™ ’I!Üw®vÎwþåo~º2}Lh’i®"Ÿ„ ðIçDe£Ë É…ýYóQr­ãæƒØ˸\0¢5•ÖGsÙ|1\”óE9šï.‡UU\Í;±ž,™iÓÙœ[›bZT‹½}žÑÝ7³át:œííK®vÉÞ~Féþ%¹ß•w$θ&9§,dqC“ÙdÐ~qUrvûÐpS¥Íû7©Tl#§z,ŒÔ{`D*’e”{F8ý39*~¦”W墬«ö;ÃjÜ~ñÃ|8)¬(æ‘èeÁe+™`ˆ±
+B*ÙÐFAˆß
+“† P" H ¨÷
+bLAU1¦"q`L¡ÞS4#†ÈO`ê/ïÎNÞœœFÈ’Êv­8ï®[+S{ûæõïƒô MÆb¸@Á0\"q`¸ Þ=.Òb¯ç
+
+4D@Y“
+%
+î=€¢Q2ƒ ÈPìh*¶»$'ZšHÔÃ,õ<X‡Ø§8 `ˆ%ÔýË~±80€Pï¾C,sCò\0PÞuˆ_œ¹Ó|áúÆ¡G|üÛ¢¨šY›¿ÙÞ0£»‹(nLåÔÌíŒüË›ãÓ㳃fÖï"VrA(2^þ'Íýô‚àR• 0Ä@€R` DâÀ@@½2e X
+¸+ÿa½¬l¤Y¦æ™W^J\2“1†'P, ”H)¨÷P3¨!<ã
+¨í&£Îëѧ¢;žtòÍ»m¢çòòþRÛå#Ym`ˆ© ómúCÆâÀÔF½µsJ —Pí¬Sû°ž^[i?”Wåâs«ím¹¸l'|„Yë *;f îxþjÒ)2©ˆð‡Ýô,â±õ
+{p)Kb@@I0 "q`@lxg‘ {½P¼;WÙ̬Í"ºy‚b´œy*ëj^Ž‹Ù°=nÒ›7wkÀýò 6#Þ¼ï*_ýûàí°<mxM¥ˆæ|–¡]žVÙf.å`4*æ¾V‹ÕÔgÝ͹}oËäêgòeb%ý©s O~ê€!öÔAA1Š"q`4¡Þ=MLNµ£)öº;à6L²®|^Îêz)²BjÇcÝeÍûÈt¾!"SÂ;.Ër»•¶½}©»ËžùÁ‘ÿ‡X'j2±À#Bcú÷`ÅâÀˆE½û‰A9a<Ùp$º„”1Ë¥vÌzñµcŦö¶—W7íâQ]µçâE.žOAìåÊe>™+`ˆq•Å¸ŠÄq…z÷\ÙbiI‘+·Ãü‡¹ßð_¥T¹½s¥oÞ[Ö(QÔ¯¿^V£ö R=‡Æ¶*ŸöT¨ !Õš¬T±8¨pï®yåJ5ßëÞ7ãÏGöžˆ Ý[•å/sÕq`\N“†0P3 ˜H0Þc£ že¤{Ÿ•îÆ@{Œ±ÝY½üpUÌ/mëÕT£Þä´ö÷è„Ë‘aˆÉô/ö…[aI¸ã/úÌHAïÞ—¢ý
+°C €B`D¢@ Øð›êÉ3"x»¼õªiÄîÛaåß(x=œ ó=í}g{ÂåÈ\ˆ‡QìõÞî^ ð¿½qŸÝ.ÞüŸ1ÿ„ü¾_~¥eó6Ý÷[º56b*Íïòmìvk/‘ÿ§07endstream
endobj
-858 0 obj <<
+862 0 obj <<
/Type /Page
-/Contents 859 0 R
-/Resources 857 0 R
+/Contents 863 0 R
+/Resources 861 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 711 0 R
-/Annots [ 861 0 R 862 0 R 863 0 R 864 0 R 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 896 0 R 897 0 R 898 0 R 899 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R ]
+/Parent 715 0 R
+/Annots [ 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 897 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R 919 0 R 920 0 R 921 0 R 922 0 R ]
>> endobj
-861 0 obj <<
+865 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 758.4766 539.579 767.4329]
+/Rect [527.6238 758.5763 539.579 767.5824]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.19) >>
>> endobj
-862 0 obj <<
+866 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 746.3946 539.579 755.3509]
+/Rect [527.6238 746.4943 539.579 755.3509]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.20) >>
>> endobj
-863 0 obj <<
+867 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 734.3125 539.579 743.2688]
+/Rect [527.6238 734.4122 539.579 743.2688]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.21) >>
>> endobj
-864 0 obj <<
+868 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 722.2305 539.579 731.1868]
+/Rect [527.6238 722.3302 539.579 731.1868]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.22) >>
>> endobj
-865 0 obj <<
+869 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 710.1484 539.579 719.1047]
+/Rect [527.6238 710.2481 539.579 719.1047]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.23) >>
>> endobj
-866 0 obj <<
+870 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 698.1661 539.579 707.1721]
+/Rect [527.6238 698.0664 539.579 707.0227]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.24) >>
>> endobj
-867 0 obj <<
+871 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 686.084 539.579 694.9406]
+/Rect [527.6238 686.084 539.579 695.0901]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.25) >>
>> endobj
-868 0 obj <<
+872 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 674.002 539.579 683.008]
+/Rect [527.6238 673.9023 539.579 682.8586]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.26) >>
>> endobj
-869 0 obj <<
+873 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 661.9199 539.579 670.926]
+/Rect [527.6238 661.8203 539.579 670.7765]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.26.1) >>
>> endobj
-870 0 obj <<
+874 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 649.7382 539.579 658.6945]
+/Rect [527.6238 649.8379 539.579 658.6945]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.26.2) >>
>> endobj
-871 0 obj <<
+875 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 637.6562 539.579 646.6124]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.26.3) >>
>> endobj
-872 0 obj <<
+876 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 625.5741 539.579 634.5304]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.26.4) >>
>> endobj
-873 0 obj <<
+877 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 613.4921 539.579 622.4483]
/Subtype /Link
/A << /S /GoTo /D (section.6.3) >>
>> endobj
-874 0 obj <<
+878 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 601.41 539.579 610.3663]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.1) >>
>> endobj
-875 0 obj <<
+879 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 589.328 539.579 598.2842]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.1.1) >>
>> endobj
-876 0 obj <<
+880 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 577.2459 539.579 586.2022]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.1.2) >>
>> endobj
-877 0 obj <<
+881 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 565.1639 539.579 574.1201]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.2) >>
>> endobj
-878 0 obj <<
+882 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 553.0818 539.579 562.1876]
+/Rect [527.6238 553.0818 539.579 562.0381]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.3) >>
>> endobj
-879 0 obj <<
+883 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 540.9998 539.579 550.1055]
+/Rect [527.6238 540.9998 539.579 549.956]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.4) >>
>> endobj
-880 0 obj <<
+884 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 528.9177 539.579 537.874]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.5) >>
>> endobj
-881 0 obj <<
+885 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 516.8357 539.579 525.792]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.1) >>
>> endobj
-882 0 obj <<
+886 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 504.7536 539.579 513.7099]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.2) >>
>> endobj
-883 0 obj <<
+887 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 492.6716 539.579 501.6279]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.3) >>
>> endobj
-884 0 obj <<
+888 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 480.5895 539.579 489.5458]
/Subtype /Link
-/A << /S /GoTo /D (subsection.6.3.6) >>
+/A << /S /GoTo /D (subsubsection.6.3.5.4) >>
>> endobj
-885 0 obj <<
+889 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 468.5075 539.579 477.4638]
/Subtype /Link
-/A << /S /GoTo /D (subsection.6.3.7) >>
+/A << /S /GoTo /D (subsection.6.3.6) >>
>> endobj
-886 0 obj <<
+890 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 456.4254 539.579 465.3817]
/Subtype /Link
-/A << /S /GoTo /D (section.6.4) >>
+/A << /S /GoTo /D (subsection.6.3.7) >>
>> endobj
-887 0 obj <<
+891 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 444.3434 539.579 453.2997]
/Subtype /Link
-/A << /S /GoTo /D (subsubsection.6.4.0.1) >>
+/A << /S /GoTo /D (section.6.4) >>
>> endobj
-888 0 obj <<
+892 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 432.2613 539.579 441.2176]
/Subtype /Link
-/A << /S /GoTo /D (subsection.6.4.1) >>
+/A << /S /GoTo /D (subsubsection.6.4.0.1) >>
>> endobj
-889 0 obj <<
+893 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 420.1793 539.579 429.1356]
/Subtype /Link
-/A << /S /GoTo /D (subsubsection.6.4.1.1) >>
+/A << /S /GoTo /D (subsection.6.4.1) >>
>> endobj
-890 0 obj <<
+894 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 408.0972 539.579 417.0535]
/Subtype /Link
+/A << /S /GoTo /D (subsubsection.6.4.1.1) >>
+>> endobj
+895 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [527.6238 396.0152 539.579 405.1209]
+/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.2) >>
>> endobj
-891 0 obj <<
+896 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 396.0152 539.579 404.9715]
+/Rect [527.6238 383.9331 539.579 392.8894]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.3) >>
>> endobj
-892 0 obj <<
+897 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 383.9331 539.579 392.8894]
+/Rect [527.6238 371.8511 539.579 380.8074]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.4) >>
>> endobj
-896 0 obj <<
+901 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 371.8511 539.579 380.9568]
+/Rect [527.6238 359.769 539.579 368.7253]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.5) >>
>> endobj
-897 0 obj <<
+902 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 349.279 539.579 358.0111]
+/Rect [527.6238 337.1969 539.579 345.9291]
/Subtype /Link
/A << /S /GoTo /D (chapter.7) >>
>> endobj
-898 0 obj <<
+903 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 337.2168 539.579 346.1731]
+/Rect [527.6238 325.1348 539.579 334.091]
/Subtype /Link
/A << /S /GoTo /D (section.7.1) >>
>> endobj
-899 0 obj <<
+904 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 325.1348 539.579 334.2405]
+/Rect [527.6238 313.0527 539.579 322.009]
/Subtype /Link
/A << /S /GoTo /D (section.7.2) >>
>> endobj
-900 0 obj <<
+905 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 313.0527 539.579 322.1585]
+/Rect [527.6238 300.9707 539.579 309.9269]
/Subtype /Link
/A << /S /GoTo /D (subsection.7.2.1) >>
>> endobj
-901 0 obj <<
+906 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 300.9707 539.579 310.0764]
+/Rect [527.6238 288.8886 539.579 297.8449]
/Subtype /Link
/A << /S /GoTo /D (subsection.7.2.2) >>
>> endobj
-902 0 obj <<
+907 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 288.8886 539.579 297.9944]
+/Rect [527.6238 276.8066 539.579 285.7628]
/Subtype /Link
/A << /S /GoTo /D (section.7.3) >>
>> endobj
-903 0 obj <<
+908 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 266.3165 539.579 275.0487]
+/Rect [527.6238 254.2345 539.579 262.9666]
/Subtype /Link
/A << /S /GoTo /D (chapter.8) >>
>> endobj
-904 0 obj <<
+909 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 254.2544 539.579 263.2106]
+/Rect [527.6238 242.1723 539.579 251.1286]
/Subtype /Link
/A << /S /GoTo /D (section.8.1) >>
>> endobj
-905 0 obj <<
+910 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 242.1723 539.579 251.1286]
+/Rect [527.6238 230.0903 539.579 239.0465]
/Subtype /Link
/A << /S /GoTo /D (subsection.8.1.1) >>
>> endobj
-906 0 obj <<
+911 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 230.0903 539.579 239.0465]
+/Rect [527.6238 218.0082 539.579 226.9645]
/Subtype /Link
/A << /S /GoTo /D (section.8.2) >>
>> endobj
-907 0 obj <<
+912 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 218.0082 539.579 226.9645]
+/Rect [527.6238 205.9262 539.579 214.8824]
/Subtype /Link
/A << /S /GoTo /D (section.8.3) >>
>> endobj
-908 0 obj <<
+913 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 195.4361 539.579 204.1683]
+/Rect [522.6425 183.3541 539.579 192.2107]
/Subtype /Link
/A << /S /GoTo /D (appendix.A) >>
>> endobj
-909 0 obj <<
+914 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 183.3739 539.579 192.3302]
+/Rect [522.6425 171.2919 539.579 180.3976]
/Subtype /Link
/A << /S /GoTo /D (section.A.1) >>
>> endobj
-910 0 obj <<
+915 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 171.2919 539.579 180.2482]
+/Rect [522.6425 159.2098 539.579 168.3156]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.1.1) >>
>> endobj
-911 0 obj <<
+916 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 159.2098 539.579 168.3156]
+/Rect [522.6425 147.1278 539.579 156.2335]
/Subtype /Link
/A << /S /GoTo /D (section.A.2) >>
>> endobj
-912 0 obj <<
+917 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 147.1278 539.579 156.2335]
+/Rect [522.6425 135.0457 539.579 144.1515]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.2.1) >>
>> endobj
-913 0 obj <<
+918 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 135.0457 539.579 144.1515]
+/Rect [522.6425 122.9637 539.579 132.0694]
/Subtype /Link
/A << /S /GoTo /D (section.A.3) >>
>> endobj
-914 0 obj <<
+919 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 122.9637 539.579 132.0694]
+/Rect [522.6425 110.8816 539.579 119.9874]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.3.1) >>
>> endobj
-915 0 obj <<
+920 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 110.8816 539.579 119.9874]
+/Rect [522.6425 98.7996 539.579 107.9053]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.3.2) >>
>> endobj
-916 0 obj <<
+921 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 98.7996 539.579 107.9053]
+/Rect [522.6425 86.7175 539.579 95.8233]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.3.3) >>
>> endobj
-917 0 obj <<
+922 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 76.2275 539.579 85.0841]
+/Rect [522.6425 64.1455 539.579 73.0021]
/Subtype /Link
/A << /S /GoTo /D (appendix.B) >>
>> endobj
-918 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 64.1653 539.579 73.2711]
-/Subtype /Link
-/A << /S /GoTo /D (section.B.1) >>
->> endobj
-860 0 obj <<
-/D [858 0 R /XYZ 85.0394 794.5015 null]
+864 0 obj <<
+/D [862 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-857 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R >>
+861 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-921 0 obj <<
-/Length 844
+925 0 obj <<
+/Length 881
/Filter /FlateDecode
>>
stream
-xÚíÙOOÛ0
-¤áBˆ~F™D(Fäð‰‘ÔÌ
-ð#µÇ(à‰Žn¾5ÓÊq?Ú`'®î`;(²ƒ« ûíd¡ìÃ';B2kŒëìè—vÍ*¬¯Òã÷Ú‘4Åõ¬ Ršp=t¿¦L"”&rø¤ €9
-¤ áRØ~H™D(Häð’ñž9mTÉî ­n–M]Íïšùý|½ºVF‹QÐk¥5*‚öjzå!ÑÃ'AÎ2Ï!nåÜ îR¤ÇkÐëÅ5,R‚p AôßVç¡‘Ã'AV3¯LÜy$(ÜD{=îÿßÿŸj0X
-¤„áƒPýÂ2‰PÂÈá“0#™÷<nÜ€‡Em‰m~ý¨ožšö™“y½'¯X€Á¼P Å DÿMT.Š9|â¥ãRǽÀŽ×㪞‡3pãsÌÿî-Vd°7HyÃÙÿ83—å>ySœqÇãîo÷ìÙÔVæAµC´ZŠl{+¿m¹×«vÃi»–£Ñ£:Œ•ìR±Ä[&Ê!9|r(\À§ãæäóu¯j±mŸiIã5â²F…)T¸¬ ‰{µL"¨ÒëÃJ{ѾšT¹7ˆá˜×Z¼ý}åókUe™tNä§+gÞJ_JÍÚ¾ÚÉšÞ©vPæÿ
+xÚíÙOOÛ0
+NB ÄÏ~ñû)µ(yøRf¼ð¥õŠiºœ.
+^Îù¯´mªØ¨Â­Ž'ÅÑ©´¥gÞSNnK¥5zÓ™cÜ9('³ËÑ—oç““óÉÅøjrVœLR¯xdà²éòWqyÅËYHà¬àLz§Ë?áÎÀ{Q.
+¥%ÓJÊøŸÇâ¢øž:Dg7¡Ù+΄4"s)B¢K±ÀŒ4!9íÃA8Õ\É1ƒqå¥ÍîçáÀ‹Wšóácó¡¼?Xg¯¬(dùP†T½â>ÍËíÁTîWáÀýrï÷ßÔ¸ÝCýä¡´‘Ã'mÊ2c-´ÚÄVÛÝjýæÅÜ>Ÿ[,Hon(↠ º¹e¡¸‘Ã'nR3+À·Üd{s[®×õ´š­oŸÆàF«ÅCýw\IçMof'º7#H1Â…PÝŒ2‰PŒÈá#!™5ƵŒÔ£€':z¼¾©Ç•ã~°ÓÃNœÝÞvP eW@wÛÉ$BÙ!‡Ov
+¤á‚è^Vç¡‘Ã'AF2ïyÜy$(,¢½öÿ¿ÿO5è- RÂpA˜na™D(aäðI˜ŒK7nÀä6ÄÖ¿ήŸë晓x}$¯X€Þ¼P Å ±ˆÊ$Bñ"‡O¼gÜñ¸·ØòzZΦáÜðóӽŊôö†)o¸â ‰%W&Ê9|ò&¡ãîoû4õèTj+ó š!šF E¶YÊoZîôj y|aÛ–ƒÑƒ:Œ•êíR±ÄÂ-“å>9ÃÀòôÎP¾Ü÷ªÛæ™–9Üã‹*N{oT(B…Ë
+’X«eÙC•^VWÚqf¥¹÷Õá˜×Þÿvüå%¾²L:'ò—+B6ÞJ_JÍB_Û½O÷µÆV(÷ÿŽžA·endstream
endobj
-920 0 obj <<
+924 0 obj <<
/Type /Page
-/Contents 921 0 R
-/Resources 919 0 R
+/Contents 925 0 R
+/Resources 923 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 711 0 R
-/Annots [ 923 0 R 924 0 R 925 0 R 926 0 R 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 936 0 R 937 0 R ]
+/Parent 715 0 R
+/Annots [ 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 933 0 R 934 0 R 935 0 R 936 0 R 937 0 R 941 0 R 942 0 R ]
>> endobj
-923 0 obj <<
+927 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [494.296 758.4766 511.2325 767.5824]
/Subtype /Link
-/A << /S /GoTo /D (section.B.2) >>
+/A << /S /GoTo /D (section.B.1) >>
>> endobj
-924 0 obj <<
+928 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [494.296 746.6211 511.2325 755.6272]
/Subtype /Link
+/A << /S /GoTo /D (section.B.2) >>
+>> endobj
+929 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 734.666 511.2325 743.672]
+/Subtype /Link
/A << /S /GoTo /D (section.B.3) >>
>> endobj
-925 0 obj <<
+930 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 734.5663 511.2325 743.672]
+/Rect [494.296 722.6111 511.2325 731.7169]
/Subtype /Link
/A << /S /GoTo /D (section.B.4) >>
>> endobj
-926 0 obj <<
+931 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 722.6111 511.2325 731.7169]
+/Rect [494.296 710.7556 511.2325 719.7617]
/Subtype /Link
/A << /S /GoTo /D (section.B.5) >>
>> endobj
-927 0 obj <<
+932 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 710.7556 511.2325 719.7617]
+/Rect [494.296 698.7008 511.2325 707.8065]
/Subtype /Link
/A << /S /GoTo /D (section.B.6) >>
>> endobj
-928 0 obj <<
+933 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 698.8005 511.2325 707.8065]
+/Rect [494.296 686.7456 511.2325 695.8514]
/Subtype /Link
/A << /S /GoTo /D (section.B.7) >>
>> endobj
-929 0 obj <<
+934 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 686.8453 511.2325 695.8514]
+/Rect [494.296 674.8901 511.2325 683.8962]
/Subtype /Link
/A << /S /GoTo /D (section.B.8) >>
>> endobj
-930 0 obj <<
+935 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 674.8901 511.2325 683.8962]
+/Rect [494.296 662.8353 511.2325 671.941]
/Subtype /Link
/A << /S /GoTo /D (section.B.9) >>
>> endobj
-931 0 obj <<
+936 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 662.935 511.2325 671.941]
+/Rect [494.296 650.8801 511.2325 659.9859]
/Subtype /Link
/A << /S /GoTo /D (section.B.10) >>
>> endobj
-932 0 obj <<
+937 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 650.8801 511.2325 659.9859]
+/Rect [494.296 638.925 511.2325 648.0307]
/Subtype /Link
/A << /S /GoTo /D (section.B.11) >>
>> endobj
-936 0 obj <<
+941 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 638.925 511.2325 648.0307]
+/Rect [494.296 626.9698 511.2325 636.0755]
/Subtype /Link
/A << /S /GoTo /D (section.B.12) >>
>> endobj
-937 0 obj <<
+942 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 626.9698 511.2325 636.0755]
+/Rect [494.296 615.0146 511.2325 624.1204]
/Subtype /Link
/A << /S /GoTo /D (section.B.13) >>
>> endobj
-922 0 obj <<
-/D [920 0 R /XYZ 56.6929 794.5015 null]
+926 0 obj <<
+/D [924 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-919 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R >>
+923 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-940 0 obj <<
+945 0 obj <<
/Length 2175
/Filter /FlateDecode
>>
@@ -2632,51 +2642,51 @@ xÚÝYÝoã6÷_áGXëø%‘ìãî¶ÅÅî’¢½>(c kK®>’ºý 9C[ŠåÍö6ÀE€ˆ¤†äpæ7¿Ê|Éà/M–2iÕR
(ÁÝîx‰kàXÛòä¾)Óò³B£:Ò96&'ȉj\@4@a&
²MáÓŽ‚Ëx¿õŸC ®•’p¹gbçN"ùéß?¾AÉmÓõ#IàµPÏ|>Ø‘¢wI>Ü‚éž_»'‚€k÷ÓWT¾^Gôè”_g¸¢Ÿ[Ì3‡è‘徫~÷›ý>Ue¿½ÞWÓ÷/ÞèèWäB¡Êò—ÀËeʤˆëÏiX¥9ï0|?£^Ÿ+¯Ì,~ÆÊ
endobj
-939 0 obj <<
+944 0 obj <<
/Type /Page
-/Contents 940 0 R
-/Resources 938 0 R
+/Contents 945 0 R
+/Resources 943 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 951 0 R
+/Parent 956 0 R
>> endobj
-941 0 obj <<
-/D [939 0 R /XYZ 85.0394 794.5015 null]
+946 0 obj <<
+/D [944 0 R /XYZ 85.0394 794.5015 null]
>> endobj
6 0 obj <<
-/D [939 0 R /XYZ 85.0394 769.5949 null]
+/D [944 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-942 0 obj <<
-/D [939 0 R /XYZ 85.0394 582.8476 null]
+947 0 obj <<
+/D [944 0 R /XYZ 85.0394 582.8476 null]
>> endobj
10 0 obj <<
-/D [939 0 R /XYZ 85.0394 512.9824 null]
+/D [944 0 R /XYZ 85.0394 512.9824 null]
>> endobj
-943 0 obj <<
-/D [939 0 R /XYZ 85.0394 474.7837 null]
+948 0 obj <<
+/D [944 0 R /XYZ 85.0394 474.7837 null]
>> endobj
14 0 obj <<
-/D [939 0 R /XYZ 85.0394 399.5462 null]
+/D [944 0 R /XYZ 85.0394 399.5462 null]
>> endobj
-944 0 obj <<
-/D [939 0 R /XYZ 85.0394 363.8828 null]
+949 0 obj <<
+/D [944 0 R /XYZ 85.0394 363.8828 null]
>> endobj
18 0 obj <<
-/D [939 0 R /XYZ 85.0394 223.0066 null]
+/D [944 0 R /XYZ 85.0394 223.0066 null]
>> endobj
-945 0 obj <<
-/D [939 0 R /XYZ 85.0394 190.9009 null]
+950 0 obj <<
+/D [944 0 R /XYZ 85.0394 190.9009 null]
>> endobj
-946 0 obj <<
-/D [939 0 R /XYZ 85.0394 170.4169 null]
+951 0 obj <<
+/D [944 0 R /XYZ 85.0394 170.4169 null]
>> endobj
-947 0 obj <<
-/D [939 0 R /XYZ 85.0394 158.4617 null]
+952 0 obj <<
+/D [944 0 R /XYZ 85.0394 158.4617 null]
>> endobj
-938 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F48 950 0 R >>
+943 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-954 0 obj <<
+959 0 obj <<
/Length 3187
/Filter /FlateDecode
>>
@@ -2703,66 +2713,66 @@ W¹‡Ñ;ÓÙS×Q3„;W4{¼kÝÔØc7>JØÇái [¨åÃ~5gë@
½þ`J9ÿdÑÆÇVþ¢Ì!ûȨÀÌBÖ?e‘úñcΗ`ùX¹žŸš¦-zXæç-@fØ:\a½ã¶Gî7žÛù¨ß•=Éȧv)½»@2wl(kz+0h´zx6éqŸSS> u»žQ¶àðI¼þ˜CÍ-í‚f¡œoMoqÓâ›äÚµ|Éï…2VDÓWÜãÒ|ññþkÿ=êø_bP*˜4Õ/øÃ[Df@
ž!þêóy©òendstream
endobj
-953 0 obj <<
+958 0 obj <<
/Type /Page
-/Contents 954 0 R
-/Resources 952 0 R
+/Contents 959 0 R
+/Resources 957 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 951 0 R
-/Annots [ 961 0 R 962 0 R ]
+/Parent 956 0 R
+/Annots [ 966 0 R 967 0 R ]
>> endobj
-961 0 obj <<
+966 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [272.8897 207.1951 329.1084 219.2548]
/Subtype /Link
/A << /S /GoTo /D (types_of_resource_records_and_when_to_use_them) >>
>> endobj
-962 0 obj <<
+967 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [190.6691 179.6723 249.6573 189.0819]
/Subtype /Link
/A << /S /GoTo /D (rfcs) >>
>> endobj
-955 0 obj <<
-/D [953 0 R /XYZ 56.6929 794.5015 null]
+960 0 obj <<
+/D [958 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-956 0 obj <<
-/D [953 0 R /XYZ 56.6929 756.8229 null]
+961 0 obj <<
+/D [958 0 R /XYZ 56.6929 756.8229 null]
>> endobj
-957 0 obj <<
-/D [953 0 R /XYZ 56.6929 744.8677 null]
+962 0 obj <<
+/D [958 0 R /XYZ 56.6929 744.8677 null]
>> endobj
22 0 obj <<
-/D [953 0 R /XYZ 56.6929 651.295 null]
+/D [958 0 R /XYZ 56.6929 651.295 null]
>> endobj
-958 0 obj <<
-/D [953 0 R /XYZ 56.6929 612.4036 null]
+963 0 obj <<
+/D [958 0 R /XYZ 56.6929 612.4036 null]
>> endobj
26 0 obj <<
-/D [953 0 R /XYZ 56.6929 555.4285 null]
+/D [958 0 R /XYZ 56.6929 555.4285 null]
>> endobj
-959 0 obj <<
-/D [953 0 R /XYZ 56.6929 530.6703 null]
+964 0 obj <<
+/D [958 0 R /XYZ 56.6929 530.6703 null]
>> endobj
30 0 obj <<
-/D [953 0 R /XYZ 56.6929 416.0112 null]
+/D [958 0 R /XYZ 56.6929 416.0112 null]
>> endobj
-960 0 obj <<
-/D [953 0 R /XYZ 56.6929 391.253 null]
+965 0 obj <<
+/D [958 0 R /XYZ 56.6929 391.253 null]
>> endobj
34 0 obj <<
-/D [953 0 R /XYZ 56.6929 164.815 null]
+/D [958 0 R /XYZ 56.6929 164.815 null]
>> endobj
-963 0 obj <<
-/D [953 0 R /XYZ 56.6929 137.4068 null]
+968 0 obj <<
+/D [958 0 R /XYZ 56.6929 137.4068 null]
>> endobj
-952 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >>
+957 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-968 0 obj <<
+973 0 obj <<
/Length 3415
/Filter /FlateDecode
>>
@@ -2781,60 +2791,60 @@ J$”š.º\.³/ËA*™… _ÕÏ5ŠAç ãîøˆ›ÔoÉÛéÌ‚ÖþoâFð 6ñ—·'\d"`X¦Ûµ¯Dí”»@/HhBg©3¡½¡&+J
?6`³<sö Ôq¿qÁâK Nÿ¢@C+žsê^ÎÌo.Þ÷³Å"ÏÅE}”0Õó©áÅœ¬ݦ5F;Ž
—%^G¦ð8Ê‹`øûÕ%çÿ^_'kendstream
endobj
-967 0 obj <<
+972 0 obj <<
/Type /Page
-/Contents 968 0 R
-/Resources 966 0 R
+/Contents 973 0 R
+/Resources 971 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 951 0 R
-/Annots [ 971 0 R 972 0 R ]
+/Parent 956 0 R
+/Annots [ 976 0 R 977 0 R ]
>> endobj
-971 0 obj <<
+976 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [519.8432 463.1122 539.579 475.1718]
/Subtype /Link
/A << /S /GoTo /D (diagnostic_tools) >>
>> endobj
-972 0 obj <<
+977 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [84.0431 451.8246 133.308 463.2167]
/Subtype /Link
/A << /S /GoTo /D (diagnostic_tools) >>
>> endobj
-969 0 obj <<
-/D [967 0 R /XYZ 85.0394 794.5015 null]
+974 0 obj <<
+/D [972 0 R /XYZ 85.0394 794.5015 null]
>> endobj
38 0 obj <<
-/D [967 0 R /XYZ 85.0394 570.5252 null]
+/D [972 0 R /XYZ 85.0394 570.5252 null]
>> endobj
-970 0 obj <<
-/D [967 0 R /XYZ 85.0394 541.3751 null]
+975 0 obj <<
+/D [972 0 R /XYZ 85.0394 541.3751 null]
>> endobj
42 0 obj <<
-/D [967 0 R /XYZ 85.0394 434.1868 null]
+/D [972 0 R /XYZ 85.0394 434.1868 null]
>> endobj
-973 0 obj <<
-/D [967 0 R /XYZ 85.0394 406.5769 null]
+978 0 obj <<
+/D [972 0 R /XYZ 85.0394 406.5769 null]
>> endobj
46 0 obj <<
-/D [967 0 R /XYZ 85.0394 301.1559 null]
+/D [972 0 R /XYZ 85.0394 301.1559 null]
>> endobj
-974 0 obj <<
-/D [967 0 R /XYZ 85.0394 276.6843 null]
+979 0 obj <<
+/D [972 0 R /XYZ 85.0394 276.6843 null]
>> endobj
50 0 obj <<
-/D [967 0 R /XYZ 85.0394 200.1512 null]
+/D [972 0 R /XYZ 85.0394 200.1512 null]
>> endobj
-975 0 obj <<
-/D [967 0 R /XYZ 85.0394 175.6796 null]
+980 0 obj <<
+/D [972 0 R /XYZ 85.0394 175.6796 null]
>> endobj
-966 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >>
+971 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-979 0 obj <<
+984 0 obj <<
/Length 2458
/Filter /FlateDecode
>>
@@ -2847,39 +2857,39 @@ Yþýî×ßÂU üù. TžÅ«LÂ@ä¹\5wQ¬‚8RÊCê»ç»Œg«n뢤DH•ÈQIµ$ª8K(ªwp9®‹®ý†òe8j[
K³ËZ! U¢|õ },ä-T\Èiù)¶†—™M¬)¢Ût‡KBaŒÂ´˜ŸS7`\&Ö^±¡‰&&Ú¡Ù’å^_ˆ¼=¢ µŽ¸Š©/@ð$.˜Á²n 0ãf—«{/Qc‡çöùŽ±Éñ¡ÚÖ=¯tñÍX>Ëî)z /{0„öG1Y C*5÷Hò|ÅjAÀùеa0ÂXë–KƯ,†•p=†”Fä9‰ñléÜî|uÚ$1Sû52Ñ”*?õVù8ijÞC@üû 3ß‚ü¹=á¬zÛ”SsÀÖ'¨‹«ƒNøÒÕæOwíi¸þáñé=|ë5ë~ÒÅÀªƒtk¨€ƒ6¼Ý ]´Né!)½=Á˜*5$ÐyúÿPŠrla±Ö¯æj§›íb5% îÖfÏX.]äü©pšwzc 4vÖ׳Ü]Õ°»“™2_$¡OæÖ#ç’_åpÚÐØ°ö4uîëÜzû.—H38Bn«‚'äô°…ïúýuoõÖV1J¹–cݽŒñ=Ãm}„R/"$•§Ž4÷•>‚tùª[«_Ð@âIŠý[†a{ÓШk/O \¯\iܽŒ‹µyîbm^`8O_Š­j˜=:9M®<uH&)!Íf¹² E ¤òïFÜÙ Ív¤Yžú*Ï]‚ÍŽb7KFY!ëö4¹é>a±¬z Ù\˜"T‘2»Œ·SCNE˜"¿ÄTz[Õ•=L A05h1„u”»œdkM9C€/¥x$ue¿
…3¸U£©UPk\‘;cpËÜÓ…à8~*”©DGÊR
endobj
-978 0 obj <<
+983 0 obj <<
/Type /Page
-/Contents 979 0 R
-/Resources 977 0 R
+/Contents 984 0 R
+/Resources 982 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 951 0 R
+/Parent 956 0 R
>> endobj
-980 0 obj <<
-/D [978 0 R /XYZ 56.6929 794.5015 null]
+985 0 obj <<
+/D [983 0 R /XYZ 56.6929 794.5015 null]
>> endobj
54 0 obj <<
-/D [978 0 R /XYZ 56.6929 717.7272 null]
+/D [983 0 R /XYZ 56.6929 717.7272 null]
>> endobj
-981 0 obj <<
-/D [978 0 R /XYZ 56.6929 690.4227 null]
+986 0 obj <<
+/D [983 0 R /XYZ 56.6929 690.4227 null]
>> endobj
58 0 obj <<
-/D [978 0 R /XYZ 56.6929 550.0786 null]
+/D [983 0 R /XYZ 56.6929 550.0786 null]
>> endobj
-982 0 obj <<
-/D [978 0 R /XYZ 56.6929 525.2967 null]
+987 0 obj <<
+/D [983 0 R /XYZ 56.6929 525.2967 null]
>> endobj
62 0 obj <<
-/D [978 0 R /XYZ 56.6929 393.0502 null]
+/D [983 0 R /XYZ 56.6929 393.0502 null]
>> endobj
-983 0 obj <<
-/D [978 0 R /XYZ 56.6929 363.1913 null]
+988 0 obj <<
+/D [983 0 R /XYZ 56.6929 363.1913 null]
>> endobj
-977 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R >>
+982 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-986 0 obj <<
+991 0 obj <<
/Length 2095
/Filter /FlateDecode
>>
@@ -2897,66 +2907,66 @@ DŽ49œvDü¹„šný~¹ æÒû/å¢õ>ÉÃP©_¬MËZç¹—ù
Õmíš™Q‘‚z
â~ó ¯ fÙ"‡èâ9Lt¨ž¹£j¡ mK(ÈÏbµ
endobj
-985 0 obj <<
+990 0 obj <<
/Type /Page
-/Contents 986 0 R
-/Resources 984 0 R
+/Contents 991 0 R
+/Resources 989 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 951 0 R
-/Annots [ 992 0 R 993 0 R ]
+/Parent 956 0 R
+/Annots [ 997 0 R 998 0 R ]
>> endobj
-992 0 obj <<
+997 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [519.8432 268.1131 539.579 280.1727]
/Subtype /Link
/A << /S /GoTo /D (acache) >>
>> endobj
-993 0 obj <<
+998 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [84.0431 256.1579 143.5361 268.2175]
/Subtype /Link
/A << /S /GoTo /D (acache) >>
>> endobj
-987 0 obj <<
-/D [985 0 R /XYZ 85.0394 794.5015 null]
+992 0 obj <<
+/D [990 0 R /XYZ 85.0394 794.5015 null]
>> endobj
66 0 obj <<
-/D [985 0 R /XYZ 85.0394 769.5949 null]
+/D [990 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-988 0 obj <<
-/D [985 0 R /XYZ 85.0394 574.3444 null]
+993 0 obj <<
+/D [990 0 R /XYZ 85.0394 574.3444 null]
>> endobj
70 0 obj <<
-/D [985 0 R /XYZ 85.0394 574.3444 null]
+/D [990 0 R /XYZ 85.0394 574.3444 null]
>> endobj
-989 0 obj <<
-/D [985 0 R /XYZ 85.0394 540.5052 null]
+994 0 obj <<
+/D [990 0 R /XYZ 85.0394 540.5052 null]
>> endobj
74 0 obj <<
-/D [985 0 R /XYZ 85.0394 447.7637 null]
+/D [990 0 R /XYZ 85.0394 447.7637 null]
>> endobj
-990 0 obj <<
-/D [985 0 R /XYZ 85.0394 410.3389 null]
+995 0 obj <<
+/D [990 0 R /XYZ 85.0394 410.3389 null]
>> endobj
78 0 obj <<
-/D [985 0 R /XYZ 85.0394 348.7624 null]
+/D [990 0 R /XYZ 85.0394 348.7624 null]
>> endobj
-991 0 obj <<
-/D [985 0 R /XYZ 85.0394 311.223 null]
+996 0 obj <<
+/D [990 0 R /XYZ 85.0394 311.223 null]
>> endobj
82 0 obj <<
-/D [985 0 R /XYZ 85.0394 189.9853 null]
+/D [990 0 R /XYZ 85.0394 189.9853 null]
>> endobj
-994 0 obj <<
-/D [985 0 R /XYZ 85.0394 156.0037 null]
+999 0 obj <<
+/D [990 0 R /XYZ 85.0394 156.0037 null]
>> endobj
-984 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R >>
+989 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-998 0 obj <<
+1003 0 obj <<
/Length 605
/Filter /FlateDecode
>>
@@ -2965,27 +2975,27 @@ xÚ¥TËr›0ÝóZŠ™¢êŒ´Ìƒ¤îŒÇài;iŽQ¦QIó÷HÄ$qW†A÷utî‘.`óÀgh&©‘ Ç„ƒÝÞÃàÁÄ.
4‹$
ó}å*!²á ]ÖÑUA«ƒlÛ*kyÓÚ Ë54<ªàmgvd¦gíTúä,¥ì¢}Tã?9_¸ûÿcZ8^¾Klue…zR…]fù •Úµº~±®Û´î0lÒqÐÝPµS#HÓÖù]ךÃ@ÿ;ÆQ?+G†Ä¼îPÿ{$ÿ©0BLz˜¶éTÐH PGª—œÐÌÇÙýHý/š@endstream
endobj
-997 0 obj <<
+1002 0 obj <<
/Type /Page
-/Contents 998 0 R
-/Resources 996 0 R
+/Contents 1003 0 R
+/Resources 1001 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 951 0 R
+/Parent 956 0 R
>> endobj
-999 0 obj <<
-/D [997 0 R /XYZ 56.6929 794.5015 null]
+1004 0 obj <<
+/D [1002 0 R /XYZ 56.6929 794.5015 null]
>> endobj
86 0 obj <<
-/D [997 0 R /XYZ 56.6929 769.5949 null]
+/D [1002 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1000 0 obj <<
-/D [997 0 R /XYZ 56.6929 744.7247 null]
+1005 0 obj <<
+/D [1002 0 R /XYZ 56.6929 744.7247 null]
>> endobj
-996 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R >>
+1001 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1003 0 obj <<
+1008 0 obj <<
/Length 1215
/Filter /FlateDecode
>>
@@ -3000,45 +3010,45 @@ NT2æ ž®öv‰¿W™ü¼ç<™!Ž„¦$çðVDBT¹
.Sø«ê¹”ý¿X'¶o|uÃ=-Lî…wà våã;d̛˪š¨!=ZŸÜOŸl_¯|É•o»
ω¤¶j'ÇÆÌ9‚4ŒýàF%Œ}ÌÄgcê®)ÓëŸÂKÆ ®Ô,u°7tÌ)Mþ:~ø~=}Ü„O‘û4÷ùDâ‹ ~û\w¼ )x™C6.&Þz›¾¤îÝý ?»˜endstream
endobj
-1002 0 obj <<
+1007 0 obj <<
/Type /Page
-/Contents 1003 0 R
-/Resources 1001 0 R
+/Contents 1008 0 R
+/Resources 1006 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1009 0 R
+/Parent 1014 0 R
>> endobj
-1004 0 obj <<
-/D [1002 0 R /XYZ 85.0394 794.5015 null]
+1009 0 obj <<
+/D [1007 0 R /XYZ 85.0394 794.5015 null]
>> endobj
90 0 obj <<
-/D [1002 0 R /XYZ 85.0394 769.5949 null]
+/D [1007 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1005 0 obj <<
-/D [1002 0 R /XYZ 85.0394 575.896 null]
+1010 0 obj <<
+/D [1007 0 R /XYZ 85.0394 575.896 null]
>> endobj
94 0 obj <<
-/D [1002 0 R /XYZ 85.0394 529.2011 null]
+/D [1007 0 R /XYZ 85.0394 529.2011 null]
>> endobj
-1006 0 obj <<
-/D [1002 0 R /XYZ 85.0394 492.9468 null]
+1011 0 obj <<
+/D [1007 0 R /XYZ 85.0394 492.9468 null]
>> endobj
98 0 obj <<
-/D [1002 0 R /XYZ 85.0394 492.9468 null]
+/D [1007 0 R /XYZ 85.0394 492.9468 null]
>> endobj
-1007 0 obj <<
-/D [1002 0 R /XYZ 85.0394 466.0581 null]
+1012 0 obj <<
+/D [1007 0 R /XYZ 85.0394 466.0581 null]
>> endobj
102 0 obj <<
-/D [1002 0 R /XYZ 85.0394 237.1121 null]
+/D [1007 0 R /XYZ 85.0394 237.1121 null]
>> endobj
-1008 0 obj <<
-/D [1002 0 R /XYZ 85.0394 206.4074 null]
+1013 0 obj <<
+/D [1007 0 R /XYZ 85.0394 206.4074 null]
>> endobj
-1001 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1006 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1012 0 obj <<
+1017 0 obj <<
/Length 1860
/Filter /FlateDecode
>>
@@ -3054,53 +3064,53 @@ g:+Â`ón™é‚W­|_Ë*UiXMtÕ 
n9ê®ÐB©ªWúQEBŽ| ÌNuë`:ôkn‹}8ÔXÅÇtªëmý÷­¯ý=^¤8æñ Ç̃€×á<ÊÃ>%Åê+'Йú>êçòE@Û߈¶¿4E¢þhh!V²ŠúO@º¬bºMæ1áwÿ$‰%7BܲÌê½>ìsëD7c¸¦1êÿ0§‘ÌÁ¬‡^˜yö·èl™ê.$ ˆßf’È:®Ò¹ïXÀŽ2³—à‰+YÔÑ\÷¦
=n ˆi¬¢<UZžiÝ(]ÜY$Ë
endobj
-1011 0 obj <<
+1016 0 obj <<
/Type /Page
-/Contents 1012 0 R
-/Resources 1010 0 R
+/Contents 1017 0 R
+/Resources 1015 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1009 0 R
-/Annots [ 1017 0 R ]
+/Parent 1014 0 R
+/Annots [ 1022 0 R ]
>> endobj
-1017 0 obj <<
+1022 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [55.6967 190.8043 126.3509 202.8639]
/Subtype /Link
/A << /S /GoTo /D (rrset_ordering) >>
>> endobj
-1013 0 obj <<
-/D [1011 0 R /XYZ 56.6929 794.5015 null]
+1018 0 obj <<
+/D [1016 0 R /XYZ 56.6929 794.5015 null]
>> endobj
106 0 obj <<
-/D [1011 0 R /XYZ 56.6929 480.2651 null]
+/D [1016 0 R /XYZ 56.6929 480.2651 null]
>> endobj
-1014 0 obj <<
-/D [1011 0 R /XYZ 56.6929 441.7923 null]
+1019 0 obj <<
+/D [1016 0 R /XYZ 56.6929 441.7923 null]
>> endobj
-1015 0 obj <<
-/D [1011 0 R /XYZ 56.6929 373.7178 null]
+1020 0 obj <<
+/D [1016 0 R /XYZ 56.6929 373.7178 null]
>> endobj
-1016 0 obj <<
-/D [1011 0 R /XYZ 56.6929 361.7627 null]
+1021 0 obj <<
+/D [1016 0 R /XYZ 56.6929 361.7627 null]
>> endobj
110 0 obj <<
-/D [1011 0 R /XYZ 56.6929 167.4388 null]
+/D [1016 0 R /XYZ 56.6929 167.4388 null]
>> endobj
-1018 0 obj <<
-/D [1011 0 R /XYZ 56.6929 126.8733 null]
+1023 0 obj <<
+/D [1016 0 R /XYZ 56.6929 126.8733 null]
>> endobj
114 0 obj <<
-/D [1011 0 R /XYZ 56.6929 126.8733 null]
+/D [1016 0 R /XYZ 56.6929 126.8733 null]
>> endobj
-1019 0 obj <<
-/D [1011 0 R /XYZ 56.6929 98.4089 null]
+1024 0 obj <<
+/D [1016 0 R /XYZ 56.6929 98.4089 null]
>> endobj
-1010 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >>
+1015 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1023 0 obj <<
+1028 0 obj <<
/Length 2720
/Filter /FlateDecode
>>
@@ -3123,33 +3133,33 @@ NåãSÅ)#Ɉ–"0ú4Â(%y–)Oà¼'iöf„ç,KuT
Z,¼-
?°ú4`ƒ‚À•°qâI[„4Ú´áb+Þ³œÆsì–Ä»ÀËíé Ü”ΞuU9œ¹¼Ešé0ô›-Rbÿ³hD wsÏþ¦ÇÿëWZóq'T£çYPÊ*ÏÒ¡æñ?NUÿ£^mšendstream
endobj
-1022 0 obj <<
+1027 0 obj <<
/Type /Page
-/Contents 1023 0 R
-/Resources 1021 0 R
+/Contents 1028 0 R
+/Resources 1026 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1009 0 R
+/Parent 1014 0 R
>> endobj
-1024 0 obj <<
-/D [1022 0 R /XYZ 85.0394 794.5015 null]
+1029 0 obj <<
+/D [1027 0 R /XYZ 85.0394 794.5015 null]
>> endobj
118 0 obj <<
-/D [1022 0 R /XYZ 85.0394 769.5949 null]
+/D [1027 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-976 0 obj <<
-/D [1022 0 R /XYZ 85.0394 749.3395 null]
+981 0 obj <<
+/D [1027 0 R /XYZ 85.0394 749.3395 null]
>> endobj
122 0 obj <<
-/D [1022 0 R /XYZ 85.0394 221.8894 null]
+/D [1027 0 R /XYZ 85.0394 221.8894 null]
>> endobj
-1028 0 obj <<
-/D [1022 0 R /XYZ 85.0394 197.4323 null]
+1033 0 obj <<
+/D [1027 0 R /XYZ 85.0394 197.4323 null]
>> endobj
-1021 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >>
+1026 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1031 0 obj <<
+1036 0 obj <<
/Length 3424
/Filter /FlateDecode
>>
@@ -3172,21 +3182,21 @@ xÚå[Ý“Û¶¿¿BoáÍX>H€lŸœÄN™Ú‰ïÒ´ãø'RwŒ)R©;Ë“?¾»øâ·äI:ÓN:÷@
.ø¡i±"ƒ|çÌ´£²D9»W>kè:•Æâ•öÿ°³§ô9R¬Ø»dða¹}õ3~!Îð1€Ùæî•ÅÈU€øRŠÞ-?²=¡¿G¤°·ÔàÙçLS%ý¡/,gûbo“7ÍÒ¿2€áÿÌXõÏ/þð¿9tÿýïâxéjPaŽ
˜X¡p*LNŸz¢F$Ÿýßð3*endstream
endobj
-1030 0 obj <<
+1035 0 obj <<
/Type /Page
-/Contents 1031 0 R
-/Resources 1029 0 R
+/Contents 1036 0 R
+/Resources 1034 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1009 0 R
+/Parent 1014 0 R
>> endobj
-1032 0 obj <<
-/D [1030 0 R /XYZ 56.6929 794.5015 null]
+1037 0 obj <<
+/D [1035 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1029 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F53 1027 0 R /F14 737 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F55 1035 0 R >>
+1034 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F53 1032 0 R /F14 741 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1038 0 obj <<
+1043 0 obj <<
/Length 3965
/Filter /FlateDecode
>>
@@ -3212,29 +3222,29 @@ wßÉ°PÒQÆR~éH2Æ"GbW‹¥Ä`‡y®!~žÆMçÜåÀ<0ôä`M¤ìç—šü¼«¬ˆ‰p—ïe´îð»úè‡RGì-¢ôŒŒ¿
›e4?sžÜZjø ‰€Â¦‡ àÊ€'Ât´YØ8(‰5¶ºn´Ÿg¾ª wL™+x^9Pk{:ê¸wcÔb+âgj|‰ö`_ÒM¤ÒU|`°ic¢Ÿ#á«È÷&‘ü.‹
¹Û ñê’,Ïgò8Ü<n~HÝìZ‘­Ÿg‰Îh¥)ˆ‡
endobj
-1037 0 obj <<
+1042 0 obj <<
/Type /Page
-/Contents 1038 0 R
-/Resources 1036 0 R
+/Contents 1043 0 R
+/Resources 1041 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1009 0 R
-/Annots [ 1040 0 R ]
+/Parent 1014 0 R
+/Annots [ 1045 0 R ]
>> endobj
-1040 0 obj <<
+1045 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [120.1376 318.9001 176.3563 328.1154]
/Subtype /Link
/A << /S /GoTo /D (controls_statement_definition_and_usage) >>
>> endobj
-1039 0 obj <<
-/D [1037 0 R /XYZ 85.0394 794.5015 null]
+1044 0 obj <<
+/D [1042 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1036 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F41 935 0 R /F55 1035 0 R >>
+1041 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F41 940 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1044 0 obj <<
+1049 0 obj <<
/Length 1676
/Filter /FlateDecode
>>
@@ -3249,33 +3259,33 @@ xÚÝXmoÛ6þî_!û`ÃQ$×Oi¦îдKœlmW Š¤ØBõâYr³`èßQ$eÙ–Û  ¶að‰Òñîx÷ÜsgÃx<D¡¢Ê
¹#„@Ë1!ƒìTÛ•mÕLæªÔpßÔ8ÔBZ»Ï\Ðüp—ç6ºàS[êë¥eˆHh"
•êƒi¸ 8”5!lK-ñX*+k°¨’ìö~ÀšVU”?$ì!E4 hÔtmuAë" M5À1óG„à°›äéća¦ïl^FƒhÓ C('骉²6Þd|u>ýÅÜÕv?,h×gá¹'ˆë”ZÔuJýº2;šè£{»LãL06ë(nç»ïœ| gu¼ÊnÌ]¹Ü±¶Õ"µú›<EC x¶Hk›©ÞzP¼qo»Þ°®»Ö;̇Pt…üQ3Ú
endobj
-1043 0 obj <<
+1048 0 obj <<
/Type /Page
-/Contents 1044 0 R
-/Resources 1042 0 R
+/Contents 1049 0 R
+/Resources 1047 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1009 0 R
+/Parent 1014 0 R
>> endobj
-1045 0 obj <<
-/D [1043 0 R /XYZ 56.6929 794.5015 null]
+1050 0 obj <<
+/D [1048 0 R /XYZ 56.6929 794.5015 null]
>> endobj
126 0 obj <<
-/D [1043 0 R /XYZ 56.6929 424.8255 null]
+/D [1048 0 R /XYZ 56.6929 424.8255 null]
>> endobj
-1046 0 obj <<
-/D [1043 0 R /XYZ 56.6929 397.5211 null]
+1051 0 obj <<
+/D [1048 0 R /XYZ 56.6929 397.5211 null]
>> endobj
-1047 0 obj <<
-/D [1043 0 R /XYZ 56.6929 368.0037 null]
+1052 0 obj <<
+/D [1048 0 R /XYZ 56.6929 368.0037 null]
>> endobj
-1048 0 obj <<
-/D [1043 0 R /XYZ 56.6929 356.0485 null]
+1053 0 obj <<
+/D [1048 0 R /XYZ 56.6929 356.0485 null]
>> endobj
-1042 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F21 710 0 R >>
+1047 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1052 0 obj <<
+1057 0 obj <<
/Length 2367
/Filter /FlateDecode
>>
@@ -3299,29 +3309,29 @@ GùZöšJ
±ÌÐ.‰`—\?ô³æûîàhT¼
DäÏÎ4W(þpu˜endstream
endobj
-1051 0 obj <<
+1056 0 obj <<
/Type /Page
-/Contents 1052 0 R
-/Resources 1050 0 R
+/Contents 1057 0 R
+/Resources 1055 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1066 0 R
-/Annots [ 1056 0 R 1057 0 R ]
+/Parent 1071 0 R
+/Annots [ 1061 0 R 1062 0 R ]
>> endobj
-1049 0 obj <<
+1054 0 obj <<
/Type /XObject
/Subtype /Form
/FormType 1
/PTEX.FileName (/usr/local/share/db2latex/xsl/figures/note.pdf)
/PTEX.PageNumber 1
-/PTEX.InfoDict 1067 0 R
+/PTEX.InfoDict 1072 0 R
/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000]
/BBox [0.00000000 0.00000000 27.00000000 27.00000000]
/Resources <<
/ProcSet [ /PDF ]
/ExtGState <<
-/R4 1068 0 R
+/R4 1073 0 R
>>>>
-/Length 1069 0 R
+/Length 1074 0 R
/Filter /FlateDecode
>>
stream
@@ -3334,12 +3344,12 @@ qª„Ñ«ò^ÿï>‹«>÷— .13×…Óƒ!¶3¢SËAÕ”ih¥Å¨Š^…(€<Îm䦽ªšÛÆlLÊâ³ò7Ù
n*Œ1½÷¨¾x¥Æˆpîâ‹&XîÃœ§³±è\íD¤ßä0}#XŒûž˜‹¸À>#^V°¡|2Îi‰9ÊÎr)`˜¢Xh¡Ò& „hb—H°Œe"Ãê
þrÓGçX5¾ûû8‡´ÕªOª«t–Ô³$Ây°‰—BÒ›ÀÄ5©/¨vp÷o`kA“ôr ±ñœÓ4N.4Žæ
endobj
-1067 0 obj
+1072 0 obj
<<
/Producer (AFPL Ghostscript 6.50)
>>
endobj
-1068 0 obj
+1073 0 obj
<<
/Type /ExtGState
/Name /R4
@@ -3349,287 +3359,298 @@ endobj
/SA true
>>
endobj
-1069 0 obj
+1074 0 obj
1049
endobj
-1056 0 obj <<
+1061 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [470.3398 477.3512 539.579 489.4108]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1057 0 obj <<
+1062 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [316.7164 465.396 385.3363 477.4557]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1053 0 obj <<
-/D [1051 0 R /XYZ 85.0394 794.5015 null]
+1058 0 obj <<
+/D [1056 0 R /XYZ 85.0394 794.5015 null]
>> endobj
130 0 obj <<
-/D [1051 0 R /XYZ 85.0394 769.5949 null]
+/D [1056 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1054 0 obj <<
-/D [1051 0 R /XYZ 85.0394 580.0302 null]
+1059 0 obj <<
+/D [1056 0 R /XYZ 85.0394 580.0302 null]
>> endobj
134 0 obj <<
-/D [1051 0 R /XYZ 85.0394 580.0302 null]
+/D [1056 0 R /XYZ 85.0394 580.0302 null]
>> endobj
-1055 0 obj <<
-/D [1051 0 R /XYZ 85.0394 539.9341 null]
+1060 0 obj <<
+/D [1056 0 R /XYZ 85.0394 539.9341 null]
>> endobj
138 0 obj <<
-/D [1051 0 R /XYZ 85.0394 315.9171 null]
+/D [1056 0 R /XYZ 85.0394 315.9171 null]
>> endobj
-1064 0 obj <<
-/D [1051 0 R /XYZ 85.0394 282.0038 null]
+1069 0 obj <<
+/D [1056 0 R /XYZ 85.0394 282.0038 null]
>> endobj
142 0 obj <<
-/D [1051 0 R /XYZ 85.0394 146.7217 null]
+/D [1056 0 R /XYZ 85.0394 146.7217 null]
>> endobj
-1065 0 obj <<
-/D [1051 0 R /XYZ 85.0394 117.3479 null]
+1070 0 obj <<
+/D [1056 0 R /XYZ 85.0394 117.3479 null]
>> endobj
-1050 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F41 935 0 R >>
-/XObject << /Im2 1049 0 R >>
+1055 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F41 940 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1074 0 obj <<
-/Length 3348
-/Filter /FlateDecode
->>
-stream
-xÚ¥Z[w£F~÷¯Ð[ð9#4Mþ93öÆ9‰3k{/'—‡6 ‹ …k4¿~«ºªHÌæaè{W×å«‹®ø W2ñ“,ÊV*‹}„r•ï®‚Õ+Ìýý*ä5k·h=]õÝóÕ·wB­2?K¢dõ¼™œ•úAš†«çâW/ö… 'ÞýÃûÇÛŸnž¯UìÝüx½ŽdàýòóÃ-µžožînŸ¨û[ ƒûÿÜ=Â7¼^ GÞûïo>>ß>Ò|̧Þ|ø×u†ÞÍÃûÛ4õáϸ»½Á»žÿùxûtýûóW·Ï㣦/úóê×߃Uïÿá*ðE–ÊÕ:fY´Ú]ÅRø2ÂÔWOWÿœÌÚ­‹Œ ?I´ÀÉH,qRf~"`
-9ù¼-áY‰òLÙ½•µU]SKצ¥V›çÚTm£ëúÈ«ºªçÍÈ×ߢ(.†Ý¿Ä_œéÝùy»Û×e?öš¾lzÃgoÎûB÷eA/mc‡S¯gZ*·ÑN €ë0ô3)#ûªß‚ ªKf,$<±ÂåYä¹oÓöÔ(èhœÚíÊ¢‚Kíë²ÐÓ›Þ²æJoyý±Ñ»*§ùô(ˆ¼—2׃áÃú­æ íPtà‹›l[j˜º=ðªmÙPK/½¦ÖÝu˜z¯x@”9~@˾¾'vAgc—À_x ª±O4Þ7¦/uG"ffG©‡B›ŸW”µ>ºó^ŽîúZ!À7”ôÝUÍЗƞ*@aàUUóJsº(ªÞ*Íü]dÅD¶!³²ÇâW*©µ¯u2tSÌ•”ößįH¿à“œ”†èÒ#6˜^wÌšd”©Û(=³ú¢=ðimGëòN›­}P
-0B
-‡cG.º‘'`d›'Ï O0ú:hàN_ÒqõhKµeH–°˜3åíZ+æÌékܧþÄ
-'9™¬â,ò#&ÉMv¯+j<N²·qýzºá2{»<¹öëGzÈܵC„ …$Ð:“ {Ÿz0rå…ùýœè0ˆý8€¼;N!Ñ “åDs\µž.»$õò´‰¯ãW!8À™«£€^ı§óÞJܶ éÃø¹7æ\~wÿð¦2ú˜aÑuÏÛHÚز*Œ k°É16!ýršC‹¸Ñ@ÐdŒîŽØ•¬Ç4î oabQ‘7bÚƒN ¶š%BH9Þ4©/Le P--1¸¤Éë¡àŽÃil;*aûb<ŒóP/q
-cKüž|*,rÀû°Á†‹ótÞB¢qà€/²Q¦ÖAÛ\*ôÚw3SFXûÔ¼£Ô)8Ü;ÑŒçœ\a•Í11køè;Ç[xFÇß-U×îË@¸!(ÓƒáÍ`C;„© ”À8‚ä ƒ$çÈ ‚„ˆ[XÅìƒ`˜QløL 68µ·*pé.E šÄέWŸ){Zoºv·.àè
-äd5Çwí×óŽ™-G€ú¥zjÒy¤fŒ6ïhÆ”%5Hpmiò®ÚŸÎ±ŽW,T€õAš9ÉtXÌ1ýÚjÊ¥ˆ¤ô¥ÌœˆòšóË¿¼E*"·˜÷q åòxøa(¶šðCŽÅ˜œèKgç±Q̱ÑȤ?Tÿ2Üy*{Ö%@ L×ð{²+8Ìkqø­*(ˆÕV¸vÌT/Ü9f9‚ù"¸èb¶¸‹ ³·µÁEü‚•”Ø
-‡TT”ŸûëÐg”«‰´5EFv+C˜¸ a´ žB ƒ1‡»Â#ü©,øíÈ&œJ 9`{$ÇXX¼ÌØ8öS¥£´ûaÏAýóÉýÙ»Nëà5TÒŠ™VmÚÆ0y M½ê¦úâlF]ítÓÏ_FÈTVŒ¹¦ 3L>²)ôS€§³J€KÍÿg™çg ñJ`Ùyg RSúiŽœ L§e8j R6êÀ.ÕýqÑ|׎™
-%8LVì ” *Œ
-& âN‰°Mó|®8Ø‹iK…mØš79K(H~ꊊéØiA-j’~+¬üâ–Œv(9•8ÎV¼Ó´;)Ê
-##¸bV¶XÝom|‚—ñ×–¬p5qfz*xŽ°ØžØ_
-AîO†–H6ÉDžÅS0P—ú“¡¦cZDß-“b ËЯ¿Uš:%„$|ÃÒ 0UÄ„Ìň¸â³Æ_*ø'" “ÇÃmI [F¿½¿&p^:ÿ'³€d†UCÜHµ*{œtUhÌ_H3GZßØÚŽQÄ6[æ?ÌïJˆ`PªByß·´V §Êƒ-9ßQCÀJÀ.]ŒVæ<¤gXÇ‘Š öao’õÅ®$ÃN©7ê¢í¸j)l€°˜’BálÑþ°B §ã\YNcʾpAÛ@8ÎF}ûßBÑ#,&Æ,¨’qÔP¡‹V !¨ër) SÔÈ·-…ÅŠÓ\øn@ÓÇ!/4Ù¦Ok÷üª½º=¾Æ€@J4Õž†Ð{1Mú"–õf~àÅÏ,¯¡7„7ŒmW‹¨xÓ°ê` :"£HæÈs„Œ"™ £„Œ.¢NƇ 6V»@Ý⎺.j¶äCßþ:DCÕ‚`V -cÝ«FgÃ/å¶jŠ¯þÞדߠRÅ8hSwD§0 SÆ:vô*²øàä
-^0d~œ,Ĉ5ˆF(,Ú|ÀÈ­]¼ÇýÆ|BÎI„@„qHð°ž7o¬*žQ¶A4ûÍä…õa0îWWÍvb6C«—~ÙiÔ àÙüw—ñ×:WŽŸˆSNœ“ѽÆFxBùi˜
-ú!G‡·½\@_x¥ [¾5&~(Š7,ûol
-©mø¯(¡Ÿ¡AAÉM@rgJ'Ï¢«P
-ó§ñº«¾¸Ë8‹W‰=öÃO¿PÚ¾
+1079 0 obj <<
+/Length 3492
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Év¤Fò®¯ÐÍè½.H’„™“Ü’ÆígË=’fy^(n
+Ê@©ºúë'¶d©Böa^È%2222ö,ÿÒƒŸ©#7J‚äÒ$¡«=__fÛ ïòæþqá ÌÊ­¦Pß>]¼¿Sæ2q“(ˆ.ŸÖ\±ëűù”ÿâ„®r¯
+Öë›_ù¾ï\߸½á©›{Áqw{{=ýëáöñê·§ï/nŸ†CMî{
+OôÇÅ/¿y—9œÿû ÏUI¬/Ðñ\?I‚ËíE¨•«C¥ìHuñxñÏád––.2Ò÷Ü@EÁ'µÄI¸‘‚)ääÓ¦€cEÆéŠöµh¹}(«Š[iÕ5Üj²,íʦN«ê(PmÙËbäë¯Aæûí¿Ì_œé-þ¬Ùzu_Ô}'¸×'Àû]žöEίMMÃ±Ó -¥]HSpÀˆ•ï»‰ÖêWÏ ª.3TŽX"x8ö[7=7rFSÛm‘—°).ñtÝ;`®H³Àët[fÜa"ßyó\dé¾dý&• ;Êá³lntUs¨MQs+]:M•¶W~ì¼ ‚ ±ü€¾#» ³&àâ=ðƒbì2ë®/Ò(T(Ìb/mŽ//ªôhñ=í&ü¥K€¯¯ù»-ë}_t„UÀÀ©Êú…çÒ</{šù¹X‹™ìŽ©`´ðM?]ÆÙUiVéʹٷ‚4¶„›ðØÙÑ™›¬è˜àr›Ö] ,`
+4•Îæþ^h¦ƒ+ 5»à´Îú‰kŒŠ„ÏŸÊMÐÒ0Ðß[¾röuβë; ,/ë´=²ˆe% eûmקuF7‡Ò§´ò+ J‚Ah™?Û敤b"²¾p•ƒ¯c¢gVçe<&§5ɨ§Åpè7hO0´]ºfm„vùRóIŠÜD)v/Ñ´æ?LN Aƒàæ †X¬µNÝŠ²D¤åpå­ô®Ûìû¼9ÂF&³6í6$]@NÏsV’"Á "{ä‘íüÞì[”ê°ò
+x ®Îšv×´i_ØžŠÉ‚=
+‚‰Á€aòOzjþ¶ãqgv)0 rº©E`| ËŽylÃú §Î†áNdñäØJ|Œ¾ìSàN_0:…r´ #è`SbHY5ζ¡kN¬¼fl ¡?ñlà‡ †ð熇ûMÃ"š¦f§iœ³ GéGLƒWáùlõ”'Õ€0¶{Ùháˆ1·b<JРiÐæëäbr‹ÓegUÉꎀ³bN ìL{ƒ©£<µÜ]ùÖt·u.»u}³[0âaà*å%ÖÒ³m¸^˜¹¨~ijÄÆ96{nlÒW$/
+#[ö ñô¡c§S†¹!-®÷$¾¨,醴 kÖÍèÝvðºù~‡xˆ±Õ´Ÿÿ¶?ÖÎMÙ¥ÏÕâ=”
+•sÜAÂp«:Ä fçáz–Àº§
+ÙX-¨×56ð„Ž¾U*tvE‹ÀvCq–Ãë=…**´F¦&¦ÆÑH^‹‘”‰ Å—ˆKDÄè@0,VÖ‚“Œ NíHÎÝ¥
+c×x¡0Ê/œ=­Öm³]å€:@T û‚CHP´ ËNÔ*ŒÜ0ð‚9OºbÈ%‰g±+D:LÇÅÝ|ã&`Cçñ*äòq¨ƒEÆÊ–Õa¬­u2ƺV`nfYÔF†•Ð
+¡û¾ØîzîPhˆE8Ò€ÅÆ¡7Ù¡ìy¶”~ñeW•Y‰…1êç–æ ±î‰$Ç·ÍÛyÇL—°és³ï¹ÉøXÌÄڼ㙮(¸Á²€°E—µånÄCN *°õ^œØ›i±Â×õ+’”ó+ÒÚÕ:±W”U’_þå.ÚÀåy6º”*Ê9zå¹¾¯­´v=Ø 9c"p> /Q˜œÆF¡ÄFp'ýXeÿ“p'f·Uô"K`%0]Ãï¨#tq˜×âðkY¨Âr%‡Çºò¹„=‡,G _”]¨Alt;ª()Úà,XÁ‰­²–
+ƒŠâKå;ÃŒ±5‘¦âȈ–Êwß±M\0^G‘’Ú¹PÂ]å°ý ¹VüþN%NEèÀ&3–±
+ý0#ä#›|7ótR °©ùŸ–y~"oÖ%·D™ÒÏsìl`¢³R†£D¡¨»ü„@Gð][*Œ’0Ùˆƒ0Šh0BÈ…|%±B„mž¼êÄÆÀÌPL[zí€õXšq)ÉOUò vËš›,ߟpIJ»ŠŒžÞ8Ζ²²k¶2’ÏF±àFÌ°¡rp¿¡ø7“/•¬š93Å
+Þ@"ìmOì.… GE‹´¨d¤Oâ)¨ŠôsÇM2Æ Äß-•I±#@è×_Ë”;„$²ÃÒ PU´ ‰âKŠ¥ly7„VyDN%5luéëëñ­ûç•fŸ³\N¨
+ ¹VEè´­@c~Bž92|Mµ?ã*5á?Ìo ˆ`ðV•q¾k¨­6@ŽK2Ù£‚€•Àª4ÏÅZu§Ñ ƒG¬&¶{“¬/´%9¶òȽA©c«¥°
+5\$û¡è¿¡,
+Ÿ»@Eº:«µÚ[(ü*WùÆöâjÜŒý):í­ôˆÏg’7©=› ΰ3yYD ®äÒzbµ‰W’ä%dÿ¸
+›è$ŒNÓžá2Í ›Ü‘§r3<±ŠÊàˆS6±Ÿæ%6ÃŽøã'©Amu›l©Á߉S1˜?m1ˆOÛò«ÝL²xÚ›æ´ýé(íâ_kªZÞ ›ÿ÷?xÆÿ9…ÆUq,—Ç»a H„(äxàQnÿêsNúÿ
endobj
-1073 0 obj <<
+1078 0 obj <<
/Type /Page
-/Contents 1074 0 R
-/Resources 1072 0 R
+/Contents 1079 0 R
+/Resources 1077 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1066 0 R
-/Annots [ 1077 0 R 1078 0 R ]
+/Parent 1071 0 R
+/Annots [ 1082 0 R 1083 0 R ]
>> endobj
-1077 0 obj <<
+1082 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [464.1993 488.466 511.2325 500.5257]
+/Rect [464.1993 469.2511 511.2325 481.3107]
/Subtype /Link
/A << /S /GoTo /D (proposed_standards) >>
>> endobj
-1078 0 obj <<
+1083 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [55.6967 477.5271 105.4 488.5705]
+/Rect [55.6967 458.3121 105.4 469.3555]
/Subtype /Link
/A << /S /GoTo /D (proposed_standards) >>
>> endobj
-1075 0 obj <<
-/D [1073 0 R /XYZ 56.6929 794.5015 null]
+1080 0 obj <<
+/D [1078 0 R /XYZ 56.6929 794.5015 null]
>> endobj
146 0 obj <<
-/D [1073 0 R /XYZ 56.6929 556.0057 null]
+/D [1078 0 R /XYZ 56.6929 535.4755 null]
>> endobj
-1076 0 obj <<
-/D [1073 0 R /XYZ 56.6929 521.4772 null]
+1081 0 obj <<
+/D [1078 0 R /XYZ 56.6929 501.7295 null]
>> endobj
150 0 obj <<
-/D [1073 0 R /XYZ 56.6929 361.9951 null]
+/D [1078 0 R /XYZ 56.6929 345.0948 null]
>> endobj
-1079 0 obj <<
-/D [1073 0 R /XYZ 56.6929 325.2573 null]
+1084 0 obj <<
+/D [1078 0 R /XYZ 56.6929 309.1395 null]
>> endobj
154 0 obj <<
-/D [1073 0 R /XYZ 56.6929 133.2872 null]
+/D [1078 0 R /XYZ 56.6929 120.0167 null]
>> endobj
-1080 0 obj <<
-/D [1073 0 R /XYZ 56.6929 104.8892 null]
+1085 0 obj <<
+/D [1078 0 R /XYZ 56.6929 92.4013 null]
>> endobj
-1072 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >>
+1077 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F55 1040 0 R /F48 955 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1084 0 obj <<
-/Length 3001
+1089 0 obj <<
+/Length 3046
/Filter /FlateDecode
>>
stream
-xÚå]sÛÆñ]¿‚o¡2æå>CòäÆJãLâ&±Úfšd¦ ›¨)€! Ñj§ÿ½»·wÀI©™>u<2îc±··ß» ˜qø'fÖ0®2=K3Í f¶º»â³÷°÷Ç+áahCýáö곯T:ËX–Èdvû.Âe·VÌn×?Ï¿üúå÷·7?^/¤ásÍ®&áó—¯þr-„˜¿|óåÍ+Úzõæ- ¾ºyyêù퟼aµ±ð^xóí÷ß¾¾íßøõö›«›ÛŽÒø6‚+$ó·«Ÿå³5\ê›+ÎTfÍì
-¶û7Á’T8_9äUÛ
-GźØÔ{áÁ2Üxº-›_ß” *£4^°Ös^8”H!.7EKK÷;ÿîÁ#…†–p\Aý oíQ Ym³ùŸªb„Ìã‡ÑÒoÕþHϤ<Ÿlǘ¤Ùün8HÎmã`à‰XØëïi§Ùå«Þ4ujŽûÝ«5Œö©ÅM¢—–ª¢eÞ´eíGB¶J ʺ)WF§0ùEJ½s õÇGœ /KÞÔ!+Ø*¯üR¾ýàG5=—5šŽIÍP›Ê€Ê³íEЭ‘²½úîo“ªEfi¶3/aœØ NX^zàU]ý¹|O—_ÓªÓGx¾«÷bËšäáýßî‹}Y8å´N±k;ò ZDL™©$ .´)ÛB°ŽìckKl"=ø‹ Œ mãÝ~¬ˆYþ>Ì)©PJ Š ,q¥àài…Í:œ ’#— ?Ëc>È'a!Gqi™ŽhpÐq5(ÚMz Ç"™‚8ähR "‹=Î:´8!]Âùl9ïU´E
-î·ÚÞ¯Ëê½ÇïbЇ½ð™Ð1J5màŽË†»Hé’Ö)qâx¶Iw(N•Eñ ÑGÚ.•u绸|¿Ü–+”݉N¤#.¸ZqByÁý
-Û9S§¼¦$K2¡/él’rñ,G–Wð¯¸\Ó0Åd}H¶þÜo×tq®²ö0Í=%0bž7ýeÝ2Ÿ–ˆ¿+Ÿvú7½óE]
-Ž“v¢N‘ Rëu‰ÆŒ¬:3äA7&ãP¢?Á¦ãVʳw”œñä¹&!WÆ&E×h6dHHº¯0quW¬Jrv|þÝO´x$w\tÙ=…¨£²ê($¸ºÔ©¸¹õªËšÑ=£ÚüýÓO‚ré)åÒó] aŠ|8¼C1B_®#_»Þ—C´2Á]`𘪢X»¸„¯«üÞE
-õ’Šc"DŒdñbTnbBÂëê8¿¨i@Têuï÷b3TyúBá9¨7…
-/ª}µX ϶N‡ø¯=™Ÿ4!µ¤§·¨a)šwŽÙ‘àsȳÏ'ŒŽGûåškŸ:šÀfØ,ÕÊ£ys½H8aƧàô š:Èû§ºq‹€tpÝ7¨`J_—Ó¨x¤v–v~•Ä‹#—±8ƒÙäÛw~Í?AÓ]È¥YYuÃB—6Á¬¯ß•Iz >-‚‰ïàÐgEîÅbRC]>ijù‡ÊÝŠgd?]ãˆÛÞ~pÑß©ÛÎùo—.´MÈÑc[gØÂÔ ë@ qQKG¾DØûíµ˜?º²Ë¼uß­·úB‰gÇ$r8GÓŒÍÏñiØXñ
-<‘šGPÎÁž0ÓQ ÏU®QÓ%>d•£öxw½{¤yÒò~è2«<;pcVÅM]Ü },åûXèj›Cähpç‘ž]²7ÄØçî2 í3XîËŸÿ¹Õ(,xbSz(œô…‘Ç
-|_æ«]ûôß;N]W—¼hs²½*!DÚŒSº¨0¾‰Wk7ªéé;•0Ú]», …JXÌQ¹;Í–RÅlØ®·ïPS„ ¡wlÂŽ5´ƒ2N<ää+ á`ÊvE±kqOä?³‰
-I!ñNDÅ/e¤ó=mEû$…÷
-Ĩ ìSgyT©¸¦y32ËÛ>xßUP‡2Çm‹U[>xHäÍÈõÄ&œí®ûøUÀ ‚Ãv
-“7 `©gŒN¡wbAÎÇü&ePÁ†¬¶ÿL„N|&‚š
-ä•Pn»ÎK0‚:#Á
+xÚå]“Û¶ñý~…Þ¢ËD>LžÜøÒ8»I|m3M2SJ¢-Ö:Ry'_;ýïÝÅ HQÒ]3}êxÎÅb±ß»”˜qø'fF3®òd–å Ó\èÙêîŠÏÞÃÚ¯„ƒYx E õ‡Û«Ï¿VÙ,gy*ÓÙí»—aÜ1»]ÿ<ÿê›ßßÞüx½šÏv½Ð)Ÿ¿xù—k!ÄüÅ›¯n^ÒÒË7oiðõÍ‹ë,™ßþùǘ&Ñöùo¿ÿîÕm¿ã×Ûo¯nn¥ñmWHæoW?ÿÊgk¸Ô·Wœ©ÜèÙ^8y.gwW‰VL'Jù™íÕÛ«ÂhÕnâŽV†i#³ öH5ųTÁ²§ÙÓe~‘2iZ—8¤É¶\uUSÓKóŽž=ê²;4ûŸÑ[·):U­{(ªm±Ü– ñ€nbw¿ÜV+†1æ|¶˳DZ
+o>w»m ©ÄÌ_Õ~Ïàn©`i–hØ‹[EÝJæóŠf^Õ]¹¯‹-M¯¶U`6|.K%ªã•ýµ0ó²m¶¤ücÛ4mWw¥ÃWÔëx;B¯6EýÞ!½Æàf OõB–kM÷=TÝ
+:Ü)VÓMjP
+@ź‹PÜ ¦áÎÀÓmÕnÜü¦jQ¥v€¹žë°áP!…8Ý–MÝïÜÞƒC
++-M!á8ƒúãwíQ ÙÄäó?Õå™Ã£¥[jÜ žI18>™ÀxÉòù/\óª¦b œ" k{õ=­´»bUÂA¯VÍq=lm`´w°H-.µ8µôP5­,‹Öy˜DB¶Jʺ©VwFÐ C>jg'šÖKM\Ö"+تpN¬+¶†iÙ ¹YoLj‡ÚTyTCoWÕ#e{ùúo#Õ"bÈ,õÀÖàÍI_Œ'L/ðª©á\¾¿§Ë¯iÖê#<ß5û±eM
+¿ÿ·ûr_•V9M‚N§Üuƒ•€€<(èïAÁ”™JSïBÛª+ d{\£XjRéÀ?›À¸H´`\c`"‰€Yþ>Ì™PJKŠ ,q¥àài…ÉÎE’‘#—†²Å|OÂ>BŽâJdJ:’€³BÇYÔ h5í5‹d
+bôP­A“Z
+»ûèül"Áûj µòüRH
+’D\â ¤WþÀ%xÙš¥IPb¼&ó²Wpœ4C`ë *µ^WhÌhÁ*˜¡¯¨§ãŠé'Ø”bÜHyöŽ’3ž>פ äÊؤèí† Iw&ÎîÊUEÎŽÏ_ÿD“GrÇI›ÝSH€:Z+£Æ9BmëR«jàæÖ«5£{Fµùû§ŸxåJ¦”+™ïSäÃaňÄûò$òå°ê|9D+í݆‡©.˵K¸­\÷6Ê
+NO¯©ƒ¼ª·ðH×}ƒ
+¦”vu9ÊGagiçfI¼8²‹5˜M±}çæÜ4݆\z«ê€ÑO„´ Þúú]é´êÓ"xqº¬Èn,×S&hó!žÏ?ÔöV<'û #nzûÁIw§°œòß.“’£Ç¶Î°!…©Aè@ qQKG®DØ•ûíµ˜?Ú.·Í¼“¾[5nõùÏOuŽ ¦›ŸåÓ°±âx"5 ¬ƒ=a¦£ž­¨-í²ÊQ?\ïiž´¼Bæo”Ã`n̨¸©‹‹¾¥\ ]m{ˆ ®<Ò3${CŒ}î.sß>ƒé¾ qùŸÂ‚#f1%Oá¤/Œ<–çû²X}íÓ|œ0º©/yÑöd{UB(ˆ´_é¢B»rL¤N­í¨¡§ëTÂhwm³€ *a1Gåš-¥ŠÙ °¡·oQS„ö¡·l Ç ´ÏãÄg
+H8˜2¡(¶-î‰ü'g&U>)$Þ‰¨ø¥Œ”c¾—˜cÑ>Iá1j»ÔÃZU*¶iގ̲ĶÞwåUã¡*üq[üðóà ‘7[ ×e š0Ý]wY«‹_%ÜÀ;l«0Eë ò–zÆèz'æå|Ì¡3¬ÏjûÏDˆáÄg"¨ ýðɨ»C?Ó«ÏÐÁQzÔ30þ¶õÅ© –e Ù³Ÿ5c(ûÝŠ‚¨L€¡Q.ªD6>sí<M²ó§¨ãcG™;Œ“txìw9Ò¥)mä>áä9ê‘O”$J3ru¹ÌW™ÑO(»’gÖ$p»tX柠Ì%3J賌¡NK0@]”àÙS{ ;)ÁÁ±ÿK ^è BâižQA?¥Í(óa›ñ´ 3¨Deš\duFê² Ï r|ì´ ãcŸ.È#ýÊò´ìNóJ§Ì £<Ï«ê ¯<Ôe^;5âÕøØi^ÅÇÞôm¥Qùè?þõŸ‡Ñ€²4Íã| #”ý4ï÷@OÓaÚóMŸ%Ÿäÿ©¼íI¡EJÇBH</£ꌌ<Ôe;5’ÑøØiÅÇþ†.Y.óì‚#¨3ôP—%xîÔH‚ãc§%{ÙÊ@¢M]>IŠZ2Èð²'I1}vTù/¥9œ˜ó<Ÿîäàjùe õs²$êçÀK(6°¢q_]qžÒúÌ73l
+~'sd_èc\Ñgbe8ÓÚ¤ã*;O£
+~Èø­ÁD0cJ‹Õ–Z~>¶ôú/×ÌÀ8SÿóÏeò¥›ÌqÒ0OþûK¯S¾%8@ïƒê½k,,ª]»xß,6å¾<Ž2¡f‡àÇ©RL3ü!å„TàÏ)üïþ½fﶨN9‘¤(É ºMGÞBiTøaç1éÿÆv–endstream
endobj
-1083 0 obj <<
+1088 0 obj <<
/Type /Page
-/Contents 1084 0 R
-/Resources 1082 0 R
+/Contents 1089 0 R
+/Resources 1087 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1066 0 R
-/Annots [ 1086 0 R ]
+/Parent 1071 0 R
+/Annots [ 1091 0 R ]
>> endobj
-1086 0 obj <<
+1091 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [417.8476 181.7231 466.5943 193.7827]
+/Rect [417.8476 169.1947 466.5943 181.2543]
/Subtype /Link
/A << /S /GoTo /D (sample_configuration) >>
>> endobj
-1085 0 obj <<
-/D [1083 0 R /XYZ 85.0394 794.5015 null]
+1090 0 obj <<
+/D [1088 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1082 0 obj <<
-/Font << /F37 799 0 R /F39 895 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R >>
+1087 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F14 741 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1089 0 obj <<
-/Length 853
+1094 0 obj <<
+/Length 828
/Filter /FlateDecode
>>
stream
-xÚÕWMsÚ0½ûWxr‚ƒ…¾üÕœhBÚf:™4¸½$9¸F$Ì›X& íô¿W²°‘ƒ€PÒÎt˜Y^½]½}+VȆâƒl×^ˆCÛ)p!rídjAûN¼û`¡¥S9ºÕûÈêßAèaÏŽÆV
-ùLšó'ÀŽäÏ[Bì½eK¸]—q¶Ð]»PïØ8ž§Ûš?Óe„¸@Þ WØðxðEeuG£> A€›;HKôØ
+xÚÕW]o›0}çW >%f}ÊÚt[5U]ÃöÒö·D ÅôkÓþûl4&mš©Ò)1æúÜësÏu®‘ åÙžü‡vRàAäÙÉÜ‚öµ|÷ÉBK§6rÚV#Ë="‚ÐǾ]µ°€Œ!;šž( `(à`rúõK4t°‡'“¡ƒõØààóè4ŸéùÚttøcˆŒNƇ­%jp4 :ˆ¾Ÿ'ÃËèØGM¤íÝ HT˜·Öù%´§rSÇ$džý  @aˆí¹E=<JH=“Zë[Øz[-5²ƒ ÀÄÇz(jÑà ð¡„
+¼ø“Š
+ˆø­x
+.Êb–”ú©' ¢ßwÁ“»BH7úWþÖëob ø-³Eû²U'SÍþ’Tj{bVrøc•äó½•ÔîÉÔ\J¦ÎP…¥|Ôn;þ˧EgYæ³xoî®´¿¡€Ú¥Ñ(Œµ3:Íkóº&¤‹".g÷:pPYÚ,ì:he(OïÊ&³J‘+̲S‡<ç˜hW™ö
+ÏXsÝUasô*àm5"Òøžo'‘jÉK
+îz8Fz´àºò@Èò›l¤¶_]½gß™UjÌ&¥ÿ¼”»0½Ý1¿õÔÀîåòbM€û
+ Wô^êeNÞ-%î‘lÅV]štEd³Geg«lÆMW¤zOuŠ/=q“‹²:¾»=ªîžô8ɳ ñõí¬Ó>s'©‘…µD@Óåeg''@íI³ØøæHéÀ;:#­àò…2„ŠÞÐânÑb÷–Ðt{ P-¿¡×‡Íw¾Y¬.U4
endobj
-1088 0 obj <<
+1093 0 obj <<
/Type /Page
-/Contents 1089 0 R
-/Resources 1087 0 R
+/Contents 1094 0 R
+/Resources 1092 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1066 0 R
+/Parent 1071 0 R
>> endobj
-1090 0 obj <<
-/D [1088 0 R /XYZ 56.6929 794.5015 null]
+1095 0 obj <<
+/D [1093 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1087 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >>
+1092 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1093 0 obj <<
-/Length 1946
+1098 0 obj <<
+/Length 1945
/Filter /FlateDecode
>>
stream
-xÚ¥ÙrÛÈñ_ÁòYeŒ0ƒ{ý¤µd[›¬ãXL^Ö[®!0$Q‹ƒÆ!™IåßÓ=Ý Ú7¥*ÍLOOß(—.üÉe×Küe”ø"pe°LË…»ÜÃÝÛ…dg@rÆX?nWo¼h™ˆ$Tár³ÑŠ…Çr¹É~Y½~wýasûqí¨À]ùbí¡»º¾ùçZJ¹º~ÿúö†®nÞßÓæÍíõ:òW›|¼EˆT ¾ øåæþîíú×ÍO‹ÛÍY¾±ÒõP¸/‹_~u—¨òÓÂ^ËG8¸B&‰Z– ?ðDà{Þ
-6WWhLÛ5yÚÑiDP§©i[´íH)’ P# “öM›×ÕwóWþ³ü/Dgø
-!¦`9Ÿ“GÀß(O$èb„þ«®XÍmÞ)ÌW] #Òº|qVHzcKµƒ÷…~à­%…,®öÝéÈx¥nÁ¯æÛåÝåɳ«k+Ë«9É]£«vgšïµÿÈVêOØJÍÚê0€µÙéß^ßÕŸLÙN×UÝLóy w?ŸuÛ}.õik¦šÏÆòŸ3åZòê äì%µ'…ù¡Å¹«¨hØ„<É}5?Gˆ YR`‘j7C8Œ…ò}ɸŸÜÀ­¢m¾ôùƒ.LÕT¬ñµ6ÐnH¡Å?Ìæ@U‚º7èYž­ÑMz »|“¦d’J—¦5ÍÃ`e)!CÿÕœŸG÷¾ºÏ“Ké Ï»"
--VÒ¼;±˜ ýñîý í]7gÇÌ´i“o‘§'ƒUzÐÕ~8 vÅÀ±·uõÉuÕ¾o41F B
-FÐüòÑÅÈAw3,4iLÚCÓ&#èc7Y¾C8¦-^WLog.†{9Yy•}F~§ÁÑ>ªm×£DÙÑš5Ý]ÞL¬ €ß̉é*£Mß>Þæû©{ö˜wÚ‘“É!eXÉñP¢
-eS ´™¶&ÐÖÐÚ·f×tKn`v‚:–§ŒqÌtgЮ·º&ùýD‡³SÇ$ô7”’Á]øäP÷EÆÂÕUG!Ïb<?ñÙÌbÎü(¹G( J(Sž_‚—úŽÀwö>`Föf"^æ-¯UÛÛÇ‚’æß`Š0ð&!@ætìê}£e^òÖ>ÉîP¥3‚lO´’ÿpgeðØé†Õë¦ÉkîVœÈŠ3t˜Qû–žðbü  öÔ²‘¾m-~ b•DŒÈRRå™#§öT´‡\Óf~|@6IbÅdßf8Ë@Dž8cZÎŒ!®}ÿLæ4CÆÑ>gâ'ƒ7Ö“s1,òŠ«l}ì83ñÀcJ^]Ð T?Í´ w³††QD(é,!â9MCºQÈ8â2 ò‚
-ÌKÔÂKàÔUÃd $ÏoMeé(ÎýA7†Õû˹üï•nuÊåüƒÎ›©&ï`Æjç§ ’Æ<TAÎ{ž9«/ φæ–P|Ïâ1šÍYX±à ÚS2[Ó=S‘^2ö¹J„繃Óq"”3Ò*_$nò4z¦”ð9ŒG„Ô!Ÿ(NÎÞÑ
-^Ebêf›C“Áš‡Gô¯ÝàÀ7Õ?ú¦ú¦rSª+a~žÄä'¥|«ŽcexÆ ¥j3Œ–nˆîʾí88Í“¡¡=# ½}[}y´b&fqšŒ Æ¢ècç(»î»º„&œ:þ$þý€!BìøYãf2JE8<æ8‹án‰g8iZ¤Š°8pä”!í·§Î £g²z÷óõkç盀Nd3$ÒÒ:Œ‘ÌSoëÛÉÂhõ×ƽنÊC6ˆa Äj70ê*xc§mš_âç^Ýæ
-M>1:C‰õ¾î¹³S©:nJý5/ûò̃6ðEµ·n憥 R±Ày‡ßˆ*Q$ÔLC-ÈKúüE¦»a´NE\–Ã,Ô ç2,’ðq=c³>å—š–‹c9Èq@ãèôãiP§™¬j¡â8ðâ…>®Më¡Ô©SfC·üé¥b0ú»¿ÝoøÁ(÷žû%Î þ|6ó»™{®×ÿ÷¯t—Ÿ%ýút¬Î?ÀMòËsCjÎ,ÚCyO%?ÿœ÷­èÿ¢ „êendstream
+xÚ­ksÛ6ò»~…&Ÿ¤™&
+ÆÿÅ\N<M.¿»gÆ—ÜcÒ „ …ÏŠä¤>´z¨vìËýKôeèDÌ|SIldŸ‚U¿*ZšCU·ú«}—¥š°meOuÛfåž6Ý‘ÖÍžBÌ?•Ø(
+îˆ8Z!Cæ
+)ûÉ€q;¼Ñ¥®M¦£:÷UkkÞCûßõ&ݨĶów*«§–ÜÂŒÕ<1e@L"îÙPóRzP³êü
+x„bb“Î~ÿyÂ<) ñ³Æ̸J7Îbí‡|ö¤Ä‡‘\Dxœ68rò€àí©Õ4zâîöŸ×/ûÛkáÛcã6pÂC~8Iâ#
+Ãdj%l«=ûmð
+F@l±Ä¨!è< ¢x˜‡1CúÒ¾-pbfî¯ÜÖªÉz* iÇ•bÂùÁêmÕZâ–fSYT¡>gEW 2€ïª=¹e`kC mT—/PšÁ4cóˆn>·y¢{Uqg<j)²Ç‹¦AOiÙ@Gp@)ˆ'}ü8ŠÖC¡êÞ°4[ûu$"‹°7nºßØ;£òxê'9H^ümæ4wh©ùçºóï“^Oi$†_â&% Ý€ÞO«ºDÈK͇ßõ¾Tý²è†Ÿendstream
endobj
-1092 0 obj <<
+1097 0 obj <<
/Type /Page
-/Contents 1093 0 R
-/Resources 1091 0 R
+/Contents 1098 0 R
+/Resources 1096 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1066 0 R
+/Parent 1071 0 R
>> endobj
-1094 0 obj <<
-/D [1092 0 R /XYZ 85.0394 794.5015 null]
+1099 0 obj <<
+/D [1097 0 R /XYZ 85.0394 794.5015 null]
>> endobj
158 0 obj <<
-/D [1092 0 R /XYZ 85.0394 427.2881 null]
+/D [1097 0 R /XYZ 85.0394 418.0047 null]
>> endobj
-1095 0 obj <<
-/D [1092 0 R /XYZ 85.0394 390.6298 null]
+1100 0 obj <<
+/D [1097 0 R /XYZ 85.0394 382.2497 null]
>> endobj
162 0 obj <<
-/D [1092 0 R /XYZ 85.0394 229.0656 null]
+/D [1097 0 R /XYZ 85.0394 223.9723 null]
>> endobj
-1096 0 obj <<
-/D [1092 0 R /XYZ 85.0394 200.0179 null]
+1101 0 obj <<
+/D [1097 0 R /XYZ 85.0394 195.8278 null]
>> endobj
166 0 obj <<
-/D [1092 0 R /XYZ 85.0394 151.3455 null]
+/D [1097 0 R /XYZ 85.0394 149.2124 null]
>> endobj
-1097 0 obj <<
-/D [1092 0 R /XYZ 85.0394 127.291 null]
+1102 0 obj <<
+/D [1097 0 R /XYZ 85.0394 126.0612 null]
>> endobj
-1091 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R /F48 950 0 R >>
+1096 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1100 0 obj <<
-/Length 2314
+1105 0 obj <<
+/Length 2253
/Filter /FlateDecode
>>
stream
-xÚ¥ÛrÛ6öÝ_¡éK¨‰…àB`3}p'uw“ÍÖê¾4} $JbÊ‹"RvÝNÿ}p
-KÍý>_öŽžµ‘A[ã õ"½^Ì8o,,ˆÇŽòÎ~-SÛEé˜,–8ï¿04ciJ˜àqL‘˜‚ùxÆf HùŸù‹Kùúó»ì_ÏÛŽ}þBsþyuñöéÇÜÑ?ó ¹JN¸Nbßp'‹‰Á5õCyyùž–±7Ž%–I’‚ßNf"‡£©>ŒðéŒ/DïóæWˆî]Ñû¼/Û&,3.µ·D&Ò1I"„ûÆ!ôzYïŒÃÀZŽŸ=˜ˆ1!sìË,Þ"m׸º(û|ˆÇCw€u
-PĬ„ºvD’ª&ÀåHQ!;¬e¢`¶AÛ(VÄ#xÐEÕµšŒ”¦“4ú½ioz¯‚1Þs |÷SìZ¿Å°rØlæÌ'"É”õ ºF“˜*øhœzm÷ˆÝ†XV¹]Ûá…›}^[Zü:v-±Þ"`â,9x–‚1–í*ïó£GúãDrŸ²^¤]Ñ9âëvwçƒ÷økСóökИӖ¡¾¯ZctR;ò’d¢Ç]×اJÐN•]ÜµÆ a o†ÅnÙî
-\3& _(<n^àØÐÁ[¤><eÚ«»]»ïq¥.À„›²«ím{¨VîV\Óf¬-K=i2Z:¸Äà . ˜óÛùÇ)TQѹŒÝÖŽú¢*vÛ¶)ì¼è—_WðªV5WͺÝ×åûtM˜! w!3=›J$N/ÿ(»Þ„¸ÇtUçÐ$ÂA¾; @±ó
-ÚÈ4õÁ*_@DW÷*CHâZ5 5@[6½I®v‚mìA¥Í‘2õ
-ß4åŸ&_ H66_Iç í!¤cή݊Åê"›[„ÈÜ̪®Ë7îD¹iPJ)ºËˆtM¥~8…c²4Æ’Kàêr}‡c´ è òÞ&V†¡„»Z —Œ#è­Ãr ¯¦Rt×hå+Ò#<ÕAÓÝÇbÙÔãÅAõ!÷O­´bŸÎ¡"=€µŸHèc{ÿ¥+&öGs¸ 2Ti2;åGf£ÆIo.Šþ¶(œô·-tʱ§M<Emƒñ 'å­JëC×#þ…ÝíÛÊÞp»uèOÔ·ŽüºÊ ê±ù6¨‚§§wûôqÿ•‚qY"þ×T}¨XbD¤,{¬Xb!TvÌe†ûµÜÕGϘ5âcÕ÷ðfáHða™Æ-ÓœèÕÍ9Á"EÄŒ$Rfãìîô¯kwü+E
-sÎÓ9 %ÎË¿ÃurÝñþØù¦™½’§`¥ù.-ìÖÎJµÀH¬»óf[¶Œ€jŽkÝï;»o_k¬"K\XÈû© àVmaO4mP`p}nÞ`5oìuÇÀ¼Aè¤û
+xÚ¥ÛvÛ6òÝ_¡Ó—P'!‚ ÁKsúà:Nêî&›­Õ}iú@I”Ä”"‘²ëÝÓß
+÷õì·ßùd GùùŒ3•¥zr ÎD–ÉÉö,ÒŠéH)©Î®Ïþé öVÍÖQΤŠåˆR¤SŠÎX¬` •2Ûp,ÐÃÅ Ê¿"(kšwã3ç²*ðȯßE¢G8SLŠåAŠÛ4m'Bü_²—"V/9þc»}y“wvÿ@0‘j¦¸vÀ‘ÁǦ۔õšx/ËýT¤A±è*+æ¡-Z' ™$|5 çÁüÐ
+"N¤,âà>þ`a Zþ{þúR_|yŸýãeÓŠ/_y.¿,ÏøaäØ|Hcæäï«ù½jÉdªœÆ¾§ˆ‹ 4žTõ}}yý>¬1f95–i–@ÜNBAÀñÄ'Áä4 Á‡¼>ä‘{_ÔÅ>ïʦ×™Ô­=•©d(’Š{"Ѻ „—Û €åôÙƒ‹2Û¾Àã-ÑfEÐyÙµC2ê‡ÀMB
+Œêv×ì;‚l páºl·væ9TKÇ•`èÆXhEâEÓÁÂáůÇlÄßÍ>M¡‹
+^ÙÌØnì¨+ªb·iêÂ΋nñ¸i”7²¦¹ªWÍ~;bœbC¡ £¤þ*T¦S Š¤éåŸeÛ™÷”®¶ù,IxPïŽx*¤ÈE€énÆŠzÄxœi‹… æ>%‘1¥Õ£DRÊ1z1ƒNÔU®c
+Â\áݯ%]`*üXQOš•Òu
+´¯ÁuIµÀ¶ç
+ô¨½ë32‘§ƒò„£í£ÌäKÇ¥Ûä­
+€u¹º£1y AÞÙz„Õ :Ÿ«ÕcH2†Ä¥Ãb¯¦ÁrlÐøÅ=O$G2´ŠjÝžR±ÇÄñüžˆ`ù±ºÓ?·A‰|„Fî
+Ì÷ \œÝmQÔ4én`¦¶»M_MÖçSN?©÷*omGôçvµk*ËávãÈ? R×8Qèëhcf›Q<¿*ÚƒÓ˽ ²Xý¯ÐÕæýX!˜JDöT!˜NR‡e[«ò´ºúäføØ,ÝçœBâQ²ßÝÈ'»§:ÁñNËÔhmW‘`±ÖÙ°":ûcÝuÛ©íÂOëè Þü5^«å³kõ‡ã…1É,K™€—æwšÛ¥ÕjA™›jóÔKö: #²lGÛï[»n_ë¬*‹]ZÌ“Ò†x˦°;ê¦#,p¸.7Wq€æµew,ûæêŽ{3Œáó,]3ï†÷β¼™j åñ­iô6z5æ]‹TªžnU$]« z]šCS‘A ø"“øŠ•ØGXÎiJÂ~=­Õ”‰æÁŽ^D-EG3 xÜ–UE£¹]ö¥Í¬šö;q@í®XØ:B^¨ ÿI¹~´ %Á¥8|Þ%Êi
+A€Î=ZÓö+X;LpÇJÍÝÉO0œ_ô1íÁocXîÌhp8èìÁ¦™¹¡÷û{Éõ8é Ù…^´£)Õ„ãMU÷Ã
+NoÒÉÝo.÷Eÿ/Í’ÕYendstream
endobj
-1099 0 obj <<
+1104 0 obj <<
/Type /Page
-/Contents 1100 0 R
-/Resources 1098 0 R
+/Contents 1105 0 R
+/Resources 1103 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1066 0 R
+/Parent 1071 0 R
>> endobj
-1101 0 obj <<
-/D [1099 0 R /XYZ 56.6929 794.5015 null]
+1106 0 obj <<
+/D [1104 0 R /XYZ 56.6929 794.5015 null]
>> endobj
170 0 obj <<
-/D [1099 0 R /XYZ 56.6929 691.7741 null]
+/D [1104 0 R /XYZ 56.6929 691.7741 null]
>> endobj
-1102 0 obj <<
-/D [1099 0 R /XYZ 56.6929 668.7722 null]
+1107 0 obj <<
+/D [1104 0 R /XYZ 56.6929 668.7722 null]
>> endobj
174 0 obj <<
-/D [1099 0 R /XYZ 56.6929 579.8329 null]
+/D [1104 0 R /XYZ 56.6929 579.8329 null]
>> endobj
-1103 0 obj <<
-/D [1099 0 R /XYZ 56.6929 549.1878 null]
+1108 0 obj <<
+/D [1104 0 R /XYZ 56.6929 549.1878 null]
>> endobj
178 0 obj <<
-/D [1099 0 R /XYZ 56.6929 502.9124 null]
+/D [1104 0 R /XYZ 56.6929 502.9124 null]
>> endobj
-1104 0 obj <<
-/D [1099 0 R /XYZ 56.6929 474.9173 null]
+1109 0 obj <<
+/D [1104 0 R /XYZ 56.6929 474.9173 null]
>> endobj
182 0 obj <<
-/D [1099 0 R /XYZ 56.6929 277.7919 null]
+/D [1104 0 R /XYZ 56.6929 277.7919 null]
>> endobj
-1105 0 obj <<
-/D [1099 0 R /XYZ 56.6929 249.7968 null]
+1110 0 obj <<
+/D [1104 0 R /XYZ 56.6929 249.7968 null]
>> endobj
-1098 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F39 895 0 R >>
+1103 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1108 0 obj <<
+1113 0 obj <<
/Length 3203
/Filter /FlateDecode
>>
@@ -3646,53 +3667,53 @@ gUBœQgâsd‘Ï€1à±8Š‰I‘c±7fq4(&öOX<ìX ¹Idy.Tîe
Ê-;1ØxÈkÊCN.—²ƒÂ9W‰;hYq  c>ú ÒŸe.èÓ
ÐÐf_zÝG}Åq¯¯¯0!3ÃJ÷9ßH´15ü„ý
endobj
-1107 0 obj <<
+1112 0 obj <<
/Type /Page
-/Contents 1108 0 R
-/Resources 1106 0 R
+/Contents 1113 0 R
+/Resources 1111 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1115 0 R
-/Annots [ 1111 0 R ]
+/Parent 1120 0 R
+/Annots [ 1116 0 R ]
>> endobj
-1111 0 obj <<
+1116 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [418.3461 611.3335 487.0181 623.3932]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-1109 0 obj <<
-/D [1107 0 R /XYZ 85.0394 794.5015 null]
+1114 0 obj <<
+/D [1112 0 R /XYZ 85.0394 794.5015 null]
>> endobj
186 0 obj <<
-/D [1107 0 R /XYZ 85.0394 769.5949 null]
+/D [1112 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1110 0 obj <<
-/D [1107 0 R /XYZ 85.0394 749.4437 null]
+1115 0 obj <<
+/D [1112 0 R /XYZ 85.0394 749.4437 null]
>> endobj
190 0 obj <<
-/D [1107 0 R /XYZ 85.0394 597.4103 null]
+/D [1112 0 R /XYZ 85.0394 597.4103 null]
>> endobj
-1112 0 obj <<
-/D [1107 0 R /XYZ 85.0394 573.0707 null]
+1117 0 obj <<
+/D [1112 0 R /XYZ 85.0394 573.0707 null]
>> endobj
194 0 obj <<
-/D [1107 0 R /XYZ 85.0394 410.9267 null]
+/D [1112 0 R /XYZ 85.0394 410.9267 null]
>> endobj
-1113 0 obj <<
-/D [1107 0 R /XYZ 85.0394 378.8211 null]
+1118 0 obj <<
+/D [1112 0 R /XYZ 85.0394 378.8211 null]
>> endobj
198 0 obj <<
-/D [1107 0 R /XYZ 85.0394 204.765 null]
+/D [1112 0 R /XYZ 85.0394 204.765 null]
>> endobj
-1114 0 obj <<
-/D [1107 0 R /XYZ 85.0394 171.4256 null]
+1119 0 obj <<
+/D [1112 0 R /XYZ 85.0394 171.4256 null]
>> endobj
-1106 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F14 737 0 R /F41 935 0 R >>
+1111 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F14 741 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1119 0 obj <<
+1124 0 obj <<
/Length 3252
/Filter /FlateDecode
>>
@@ -3713,133 +3734,185 @@ RËâV²³´¡†AˆdÀßÀÕöXÑ…¡}É­©T%Jhõ™Co’¼°ùèÔw´Ê±Ã.%™!ƒû_Þ½ó÷n§ÒzÈÀ!Õ0âìo|ZÛ
UˆÄuV¼¼Ô)e ç/> –|}Ä[¾¸»¿‡CÔMT4ÃðF‹Ó üIT¸ ;?ðËPñVUè‚èô7 øpiKìOD“"VØØŒ66ð8uRÈ(L0”lÙuÇ]‰¥¶â§s$ôuJAï¡þœ .ºj2˜dàJU>¨¡“Ï•ÝPK'ºÈO1ta  øŠ#~Õ Ä9ÖsåÖåqÛ³ºÊp0ºÈe©ó['‚|ËÅežÿ~(!ˆA§Ò`xË0zDúÜMç8kO&.βºóhB×íÄe
+â~Ú;Ä(>õw¥üÎÄŸoDÌvþç¿úœþÝ’QÖ¦§ñŒ“< ÂI˜)Üvš_pþtÉú
endobj
-1118 0 obj <<
+1123 0 obj <<
/Type /Page
-/Contents 1119 0 R
-/Resources 1117 0 R
+/Contents 1124 0 R
+/Resources 1122 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1115 0 R
+/Parent 1120 0 R
>> endobj
-1120 0 obj <<
-/D [1118 0 R /XYZ 56.6929 794.5015 null]
+1125 0 obj <<
+/D [1123 0 R /XYZ 56.6929 794.5015 null]
>> endobj
202 0 obj <<
-/D [1118 0 R /XYZ 56.6929 769.5949 null]
+/D [1123 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1121 0 obj <<
-/D [1118 0 R /XYZ 56.6929 748.4014 null]
+1126 0 obj <<
+/D [1123 0 R /XYZ 56.6929 748.4014 null]
>> endobj
206 0 obj <<
-/D [1118 0 R /XYZ 56.6929 549.4516 null]
+/D [1123 0 R /XYZ 56.6929 549.4516 null]
>> endobj
-1122 0 obj <<
-/D [1118 0 R /XYZ 56.6929 521.7105 null]
+1127 0 obj <<
+/D [1123 0 R /XYZ 56.6929 521.7105 null]
>> endobj
210 0 obj <<
-/D [1118 0 R /XYZ 56.6929 231.5025 null]
+/D [1123 0 R /XYZ 56.6929 231.5025 null]
>> endobj
-1123 0 obj <<
-/D [1118 0 R /XYZ 56.6929 201.1114 null]
+1128 0 obj <<
+/D [1123 0 R /XYZ 56.6929 201.1114 null]
>> endobj
-1117 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F48 950 0 R >>
+1122 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1126 0 obj <<
-/Length 2922
+1131 0 obj <<
+/Length 3056
/Filter /FlateDecode
>>
stream
-xÚµYI“«8¾×¯¨x—qMua$±FǼ=ï;^»ç€6‹ x˜ÿ>Z€²ë1óº£c„”Je~¹
-ƒWÿÀ«"r<R…WY8‘â«á¿ð¯6^k¾€”æ##úx¤ªj/åïH~U9U‚Ò«¶}à¥p¼¢€WÍü­TkUFZcòöE¾$po¢Ä—*õù
-›PÈü0ÿ'Íuú@ŠÊ!I@Ï&÷OqjÀMnî/½Y1µ#Èœªâ¼ô8RÀÿ
-Pþ°=Xb%3¡_5 éÌ’3²Ì’º NN…yÂøñP#DêŒéÁ8ØÃÂ%s²(HFæ0‡mÑÁ*'㺕’rj|àŠÆ)
-ŠP©BK:ž§(Ñ‘çØØØ
-à8%*Šòݧ$©59%fþc%£ÓKVÈëgrÃ/¦eù™l4Ùà§uu©/ÚŒuàÔJq<ÎÌPÈË« yÉÉ•Åã<J;ïfæ{ÌqYª1¿±ÌQÈ;Jž©[¤”i-|*žY~*rpþÏz6ŽTé«g“CL+6"wóìé‡ÏD‰î¦ú{XÃè™8qÜ&34N>.6\î‚ôÜ'Ygçî c•ªíé´qg­üBžj>ƒJ*[0CÚ≠LØNÎîöÆ&I¯ª'iŠI ÀÑy¡n¦liwŠ—XÛFSÛâ9³d Ÿ'ŒÜ§ÛsJ•†1Y5C6EÄÈ*ÙCdÖWÈ“ïÁ2\È_AÎ=ä3S²LO'³¾¶ jV¶ÌPz¨ûRɶXo a$\ˆÜر(
-x—é’Hn„$§r²€ØÂßéB&ÏÃÂ$$9“°íZ¬ü‰ôò ¶§|æË™Â"'B=;ö7îã E™ ÐÓã[u°.Ñ¢‚Ú¶ó^[š|4_ÞV~¸Iä¸ÑØv‘áM6M]»L;ר¹¿váú$µåѽsbG㻺ÌÓúñ
-ÖU÷¸p¤s+Œ1Ê¥Q©è×QߘÀ+ßÚŒçÂÂZW¥°Q_¾Gü¸/‰Ý£í¢X땉?rë5 À‰¼ôåâ‡Vª»µ§£|^—ïÍõÌl4‹Û{g}?ż7;${×¼8³)E¥µ:ÝÙfSäCÍè+‡ËÒÛñ w‰Âú÷¹¿k A°{ûê)0ëζe¿&·ÎÛ˪U®Z6ƒZ‘gx‘t;0´…Ûå>T¶×ßË»Ív=ëžÝHkEPlöä©6žÝ«q_ Û,ųƒ›6kÅ AKm%:ݵT;~¿ú•ùzy×ÖÜ«”Aψìe¹Ûo4Ír¡Šîéü]8vj7óäZ­Óþ´B-aÙ¯“÷««C¦bОÎ~9¼-&JuQvæ}xŠTœÖ4ÇkmÑÕ]yV}“”C0ÔƼZáÿ‘ùû§Ñþo‘Æ”î̹Y†ÍÍ @*íËø¢eñYMÈ‘OÓk>*õúdTá íg~>Sá”Ûöpv¨Ž:hÚ÷‹qšýÊË ”ñqŒÇã
-W¸ÄÂ/içóèÝí9M-4¨.ƽYûÞ:ó5ºÛö -.MÚ¯CÉà‹ žÄ÷Õq“œ Ç·Ç5¥v~y$Wê7Ë–žbÚœ¡ØÕ‡æ”/2ómØ–ªö(¾¼¯ÖæÝ[õõv§¹ú‚y »mçn®oc¸Y£Ým\$„Ыò^MÖ‡AÜ¿­º­ÖÊšœÙÉ£ë®=^úæÑvšÇ÷3n›¼TX°ïàj¯:ŽÕÚÛÀMâéöµ7jÂóR«—'Aoù^GšõŠ”[U«ãTÖu±'ªóón:Š×–U¯Ín‹Ut­­x]oOÎN½^t¾§ÝóƱ,­3󥆳¿ß’Á
-=îæ8î¿ýÝ‚°«#TôçŸÓ_þ+æóß',Røù/ËSûJ>»ãKB& ù«äù6?Šþ¢Ó, endstream
+xÚµYI“«8¾×¯¨è˸¦º0’X£cÞž÷¯Ý}À€›Å¼NÌ-@Ùõ˜yýbbÂD*•ÊåËT
+ƒWÿÀ«"r<R…WY8‘â«á¿ð¯6žk¾€”ç#cúxäªj/åoH~U9U‚Ò«¶}¥p¼¢€WÍü½TkUFZcòöE¾$po¢Ä—*õù
+PEáuJº³Mµ·?µÎKCË5|´ðˆ¨w|ùýOþÕÄÆt^x©ŠøzÁ/<T¾ú/‚ˆ8Q@(£x/Ó—q.ða–.-òŠˆNT \àŠÜ"ªœ„ ¢n1ƒ8¶ŒØµƒ{XÄ ¼ =,“eNUïEø/®çaÿ(rI÷âÑPJ¡y2¬tŠ=öÖ-¶’”˜d ”Ì8§ýÁóгâ'¹7 tÏ»= 3½ó—…8%ͱâl_ªˆÅ6:Å–IÌÁnI-ø
+ˆ$?2&‹&O3Æ[ƒlc=ažDªÌ!QQŸ]ùévœ6Ô}d€auzœÀ~Œnlx]âTÊ~YF¼Ì¥º‚×|›-Vò‰âe–Ï$ÎKžçKµ0 °Oq3µ¢³ùËØnˆ}Läho*,% Â*êÏÊ7ˆ âp1©£ÝgÐú"! ¤\I*ô!P„
+8¨Bðý.áä…bÆMŠc‘HNP}–˜êKhTrŠ,dÅ%<|°´ð ‚ñ­|©X)nO,܃nÒ2‡i$ð„BR
+ê¹(q²$¡GPsXÏm‘p•“å\®@Ù¨âÆB’¤çìú±Ò2òŠT{ìà’¸gÈ–ÑØÇÆ“IÌ[rœ.RèS=`èèI&=Á)/VºØÏ–¤L$NQœ0>Ï öŒL@õÄgD·CÚ‘~p\ƒÁ>3ç õ†£“µPÔòÌpD„JÚa:õy.qgÁ{>AEù‹ØÀIêC Àš#,üûƒŸ’©/ÙM^?ÏübZ–ŸéF‹~ZW—B^M3‰Zà“ˆúòø ƒÂ—S>¯×¹±xœº€&uËC±ð= Ym5¿œ
+÷¸än0’‹:
+q;œ°òØ*ƒ½fõIJ¨fûãËœÖ4A)¥íÙ‰è•óîG}ê~ˆ§$¦W¦'©L[Ü{æ!RƒC6»±ŠNß¼(n©Ìv)/(x”Þ4EûƒÂN"}"Ƹž2¤†â3sâË[’Òh—r0©ô쌺a=Ò ã÷ÚKz 3Ý‹S³+§ôY
+‚HÚC²†vG¹ŧ'zz¹úzYÇ`?na}ös$„D¤ëû'Ú ,ÕÍýôÖá»±•1)““*“=[ñ7&âF¦pÊL/xnr˧iErøúýåðx¼Kg·¼˜+èrÈí ¿ ¸3ù®lHø®÷Oº ãö˜ÇWzˆ°Ÿx2—é”H®Ï¤¢r²€ØÄßéDº‡‰IH*&ÛµØá'Ò›*XžÊ} —3‹ENÄýÔ3¬á~a’¡(³zzüR¬„K´èƒ ¶í¼×–&Í—·•n9n4¶]dx“MS×.ÓÎ5jî¯E¸>ImytïœØÖ²ÌÉ<==\ÝPí«0«{³Òò–]³!ÜWíÃÄÑ«ÝàlÔàLõ×ÎÞœL0Ãr«bî–Òóû^p_¡" ßopyöÞbX©k£ûô¬Zº¿Sæ@µš»jOŸ'«ó¾ìâºrØ­lgû.m^ä÷ö¦~/ÊùþkA¥6Q€\ÿ&T«º<›”7V½u;ˆîB[.¦®´ôÃNoÓT§ÆÑ=™ïÖÞy9Aý"ËÞl6Ÿlö– Ú£ÎÔ5ý.ZßjžçËiw³³Ê‚8힌–\fâÎÚö“£$ÙÝÐïÞ %º*ÛÙÜ’Oªº¸k=ì£w­;×Õx ùocUž¾÷º3í06ŽPžÈ •ç¢3_§F»ÈêÁñbÜ…Ý긮ÃíØ´¯£®Õ¼_›TM×µn½þà¾l¢_~Ë¿[±ðþ4Èá#L ´)ähq$ƒð” ¢Ïj÷·8çºè‘É^²o‚¯©ä‹æO%”Ç$?{ÁºêþÛéÛ
+3DL3¤riT*úuÔ7&ðÊ·6ã¹°°ÖU)lÔ—ï?îKbwãh»hÖzeâœÆzÍÔp"/}¹Ñ¢•êníÆé(Ÿ×å{s=3ÍÁâöÞYßO1ïÍÉÅÞ5/Îl
+DQim„Nw¶Ùc¨}åpYz;¾á.QXÿ6÷w­¡ vo_2fÝÙ¶ì×äÖy{YµÊU ÂfP+B†¹A·s
+S—|K¢_ü6ŸGïnÏijÁ y@­p1îÍÚ÷nÔ™¯ÑݶohqhÒ~J_ð$¾¯Ž›äl8¾=®)µ{7ÜõË ¹R¿Y¶ôԧ͊]}hNù¢0߆m©jâËûjmÞ½U_owš[¡/˜·°Ûvîæú6†›Õ8ÚÝÆEJ½*ïÕd}ÄýÛªÛj­¬É™í<ºîÚã¥oía§y|?ã°ÉK…Öâ\íUÇQ£Z{ø In_{£&</µzyô–ïu¤¡Y¯È¹ÕYµ:Ne]{¢:?念xÝiYõÚì¶XEçÑÚŠ×õöäìÔëEû‹pÚ=oËÒ:3_j8ûû- àt JãÉ^ٕݶânrØFó_¿e’Y2 ô“]úU.o…Šþ~BÍýYÄçùò?ÿ5õùonÆ¢ÀÏžZTò7¾dJÑ$‘¿jžÿ‡õ½êÿsÍvFendstream
endobj
-1125 0 obj <<
+1130 0 obj <<
/Type /Page
-/Contents 1126 0 R
-/Resources 1124 0 R
+/Contents 1131 0 R
+/Resources 1129 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1115 0 R
+/Parent 1120 0 R
>> endobj
-1127 0 obj <<
-/D [1125 0 R /XYZ 85.0394 794.5015 null]
+1132 0 obj <<
+/D [1130 0 R /XYZ 85.0394 794.5015 null]
>> endobj
214 0 obj <<
-/D [1125 0 R /XYZ 85.0394 717.5894 null]
+/D [1130 0 R /XYZ 85.0394 717.5894 null]
>> endobj
-1128 0 obj <<
-/D [1125 0 R /XYZ 85.0394 690.1986 null]
+1133 0 obj <<
+/D [1130 0 R /XYZ 85.0394 690.1986 null]
>> endobj
-1124 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1129 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1131 0 obj <<
-/Length 2380
-/Filter /FlateDecode
->>
-stream
-xÚ¥YKsã6¾ûWð°ªÊBð"H:'gÆ“8•õxmMöÉ¡1w(RCRÖz«ö¿o7¤(šv¶jì*£4~|hÐ"àð+‚È0“Ê4ˆSÍ".¢`½=ãÁ˜ûùLxžeÏ´sý´:û჊ƒ”¥Fš`µÉJO¬ò?BÍR¶
-âæ"XÀûƒ'…ˆS:S]A`È8 ë ¶IØ=ú¯ ÉC‹ž[š*‹¶³9ÍUÏ^´4bŠ‡ÿζ»ÒÒTÖxIO …XJGáuE㻬Y,5»b½/†<Ÿ(ÑÔuGC#u¼^«
-8fz´éÄÚ€S“4 ÆAð}q…¥ë˜Ëßõ§¡ª5ð ¡*¡™ÒFŽ3Šc
--˜Q:Ò¶¨ºe%OCÅDÚbÅqøÑmêöG·€M[RjÙû¨”&¼O¨(©–(ª¬y&¾2{°¥s‡3‹ˆ9‹ãDÌg°”Ç|…_«úPIXa¼Ô®íˆAìÀ
-A,äàsB…‡}G£#`ŠèÐzÄ2Uó<ÒNÀc­ß{]cAÕY‚¦h
-MQ¸s&ƒÅˆÇ3ɇèìê.þ=«œf»]Y¬]ßÒÅâ`b#û°ÏkêV®b_—ÚÎÃqot Ž“dp"±ûömé'¶”¾öÜ›¼—î®ã™cw·o*<[êîNl-!¦;v‹ µ_
-7&C‚€Û‰¥†@ )Âï¹ûn
-wƒyvæmß(FÕ„JóT؃ïm<è>ÚoÉ=n‰jq¬QÖ`_gçÓµ¯TAç~­µÓŠ[Eƒ‰L<Ê=ži²ùâŸ7w£WïÀ¿/èßicà›ÊE ÜÃuVô5Õ%“L¼xðÖ~Å¿x{\¡ÅKi¨óØ'ÆïJw²8uG„G‡ÏÂ×ë—`Qª`AùßèF¢Î§öxóQiÔÞ{pÏ×î X z¬¨‹zç2DH5^4¹Di̽°ðE >צ®Ëlp/¶#ÙxáIÎJuÅ…‹2Oí«²øjO„èéUCªš7äµ;».0l;—GC¤CÑXŒÃy6ŒOŸG¾AË÷Uø©
-ˆ¬‚“ÎÒøœrò‰’²$¡4ýÛÇ»ëŸñÓ~eñ«€=›;ÂcÝB†ÆXðÃVšÓ‡/ìöá€cÀ".ò‡äâB¼¨‚üÂÊG)í[)òß²¨–dœÙÂMN@zòäÁ¡¢¥…„t0Ð[g»µpMäî“›
-¯7^5t\ç.<7SQK„S£Ýš£ˆ^GfˆŠ×/†qˆ€[èò::-vÞ¿÷ºÇo aàÍ>Ô)ø¹) ‰I˜ö 2±/.âF'~QÖN°vt¦yxJ2ŲÇ3àƒœÃ‡þÅyCO‡7ãƤþ#'!þ_BÆ?݃UqzD:QØÙï¨ÍüäIòà@á'*¿'ÒC}¤àùáì1»«¸«Î÷³>_±Ó$ÏDŠ÷ÜI5á¿ö.ª¸vv÷ŠÌ=ô!ļ"xß½t½†rZ¸¯p㺛Í,‚HHDÏØë ƒ±Oº ‹pt8³?ð¾ì¼Eµ«# StìÙ 9µØ¦.Ëú0øâPïK¿fý„¯b*r¹f1“"÷ôÕƒ©1Ľæ_a”²C¾¼@Í™JxèØ[çm`2‹#Õ'›‡o2耵_EQÎNöÀrh…ëIvâÉ)Ä
-Æßú…ìK` ¡5¯£ïíê=ÀÉHlŠåsÇ!¹õ|ÑÁ8øî/¿ ê˜)¬’f«xÝaõ¢z¥œ³’š÷ÿ‡x©úÿ
+1136 0 obj <<
+/Length 2753
+/Filter /FlateDecode
+>>
+stream
+xÚµ]sÛ¸ñÝ¿BÔŒÅàƒÉÉ“/¶{¾i×ö¥—{ EÈbC‘
+IY§Ìô¿w LgÚÉ]2c,‹Å~cñƒÿ|«Pe"›%YƌdzåæŒÍžaîogÜÒ,ѧúéñìݵLfY˜)¡f+W²4å³Çâ·
+³pXps÷IÍ"fÁïwwïç2  qsKãO7·—eóçŠÉàÃÏwW÷„,«‹ËOsÎypqûáÊ.¸¼} àúêbžDÁã¯÷Wóß9»z4ñµåL¢_Ï~ûÍ
+Pú—3Ê,g{ø`!Ï21ÛœE± ãHJ‡©ÎÎþ90ôfÍÒIëq
+©Ä„ù"î™3˜åRÍ’8 •ÒØ/ CÔXAÂ,Ž…Au×éåB×ùS¥ç ÅXpÐÝûï¾äUYä}ÙÔ'ä‹( SÁ·ŠüöŸ÷oO%iÈWÿ“õ¸³,Ž¦­‚&À4bâm^´Ž/ ºǬÆUŒ‡±àÑ`d0ä`ŽÕL‰P& ¼R™’“‘oQWC™…±¯w„± ¹¡øFã®JW§–ž, Œ,L²ÄÄÕì댇,Ê2IDltm`ïn6bvÙ€F3O)Çxás6JA8‘ùT°¿@Ö6:55†H² Yá˜ýÚ"¾Ì 4þ9t4U•]¯ š-kG^v„ÑsÉ‚?òͶÒ4•·–ÓË\Ä$¦Œâà¦&ü6o狈}¹ÜU
+#8ÎÖ˜â?õÇ¡Ê@^¨¾.§qAA îÿZk4±H±à=\} ØÏmü6„‘ÊCAym
+6ù
+râà‹>àì`Ñ¥£È¤©AmòÞÍ’í
+•„MUuõûgj54ÊTúgž©2!Röœ©>ç·ÏTìð Á~õ•.ve4FyobæZ½Ô¥Á› ‘ƒfbSX¹jMˆJÜ0îjªƒ4ÿmÎã€q³aÞ´Î}®‘­SÙ ±Jq,%,—$霳`×™/åÊ>JŽS†b_ökš5Z"Š89dnY Ó£¨H°Ç/§Êº‡•p2åUu ùJ¯,ƒ]=Y…H#l)¤
+nPíx¨7±r àž\Ó
+ʸ<A¸‹MŸÄ¦IG{1®d(¸6—†DãçOCÁ¤%Ù¶ÍÜñÕn3£¼¿­§0WÔ‹ð¡rk2#t ®¨Ö*?Ep] …Yo{mÕ^¤<Œ8Ô­£ ùÙˆ¶Çè6ýª‹×zB[¹²cO#( G—´²xÓc¢àWÞu»m]sGéT¢†vù54>¹54XŸ>c tx?Peï¢{ªî$
+#Œ&Ç9Ú÷†RA3û™ÅìU€~¨i‰ý„‹èé!8‹!&¤‹JD9ák"D…>pŸW
+M§±EB‹ó¸v—œVÓ[焾9ñøP6uìÕè°
+Z<F0|u'XO{Ž{ž£[%4/ãS†Mš¶[™íð1£±@~Jw¤|_(ÿ)Ã Ï‰Ç J¸cÙÄRnZÓ”—*JN6ð8í•7å^D
+SLJÀ8ÈñÕE³Ð}ièÍ eƒoͽ¦ÒŸ–&¸“Áb¬Çu«³é´TðzaS"È·Û
+{GkbÀP,&VÂ…}ÑÐ'µY
+c˜)ì-,)4ØîQž]b&8~GõÛ l_ PFUl„¨bL݃™G“!@…Û°¥ŠBT¿§ªæi¹Ì °1ï÷*×J@¨´/¥ÞÛ¯ÕÉ‹îàÿB”eôúìÖ¾Ñ oÖú´ß–1 £43hP%ô®ÐÆÒTûlߨî½_ êÅHþú7Sž¨ûd¥k¥.Bè[_uþ,UP¹FÖ¯~¥h¾»ÿ)'ó å[ÏšP¡#)'·cÃóáÿ;^¢$”i*§%‡zŽ’ËA*]¤¯dw?ÖNÿ_ëÞÍ&endstream
endobj
-1130 0 obj <<
+1135 0 obj <<
/Type /Page
-/Contents 1131 0 R
-/Resources 1129 0 R
+/Contents 1136 0 R
+/Resources 1134 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1115 0 R
-/Annots [ 1134 0 R ]
+/Parent 1120 0 R
+/Annots [ 1142 0 R ]
>> endobj
-1134 0 obj <<
+1142 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [349.4919 384.4828 408.4801 395.2672]
+/Rect [349.4919 62.7905 408.4801 73.5749]
/Subtype /Link
/A << /S /GoTo /D (ipv6addresses) >>
>> endobj
-1132 0 obj <<
-/D [1130 0 R /XYZ 56.6929 794.5015 null]
+1137 0 obj <<
+/D [1135 0 R /XYZ 56.6929 794.5015 null]
>> endobj
218 0 obj <<
-/D [1130 0 R /XYZ 56.6929 594.1106 null]
+/D [1135 0 R /XYZ 56.6929 285.3652 null]
>> endobj
-1133 0 obj <<
-/D [1130 0 R /XYZ 56.6929 562.6395 null]
+1141 0 obj <<
+/D [1135 0 R /XYZ 56.6929 250.4165 null]
+>> endobj
+1134 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F62 1065 0 R /F65 1140 0 R /F21 714 0 R /F39 900 0 R >>
+/XObject << /Im2 1054 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1146 0 obj <<
+/Length 1018
+/Filter /FlateDecode
+>>
+stream
+xÚ¥VK“ÓH ¾ûWø°»
+÷öÓÜØP[!›ñ°àà;Äà×ÆÉ üûU·ÚÆ™1Ãû ~I-}ú¤jæRø™+BE"Ý(‘DQ¦Ü»Ú¡îgØ{ã0{&ÓS/SçÏ×"r’„<tÓýÄVLh37Í?x¯þZnÓÕθ¢ž$~ Bê-¯ÞûŒ1o¹yµºÂ­«Í5^¯–~$½ôf·‚ÆB*@/±šëíûÏ]ßl·ïv¾ˆ¼Ö”/×k3ñ?¥oU:F2–Q¡ÃøÏùð‰º9ýÖ¡D$±r`B KîÖŽT‚()Ä°R9×Î?£ÁÉ®QCO‰˜¨˜G3ðqæ2F¥ø~*!¡àÂà§Cg€¥
+žœµð|c
+‰”ŠÌ˜ x(`hÿ¼RrùÇä–ä ™™qr‘ÊÇ´`„>÷CùÅp“R÷ßpÚ~·éN§€"Jäq3Ÿ{@uë'ÅÌ[‚Žýà·_.?u2""ŽùGÉ{ACó$œ2Ùzò®Ÿ8O]ÿ¬ÊƒXendstream
+endobj
+1145 0 obj <<
+/Type /Page
+/Contents 1146 0 R
+/Resources 1144 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1120 0 R
+>> endobj
+1147 0 obj <<
+/D [1145 0 R /XYZ 85.0394 794.5015 null]
>> endobj
222 0 obj <<
-/D [1130 0 R /XYZ 56.6929 370.2937 null]
+/D [1145 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1135 0 obj <<
-/D [1130 0 R /XYZ 56.6929 341.714 null]
+1148 0 obj <<
+/D [1145 0 R /XYZ 85.0394 749.4437 null]
>> endobj
226 0 obj <<
-/D [1130 0 R /XYZ 56.6929 214.6004 null]
+/D [1145 0 R /XYZ 85.0394 622.33 null]
>> endobj
-1136 0 obj <<
-/D [1130 0 R /XYZ 56.6929 186.0207 null]
+1149 0 obj <<
+/D [1145 0 R /XYZ 85.0394 593.7503 null]
>> endobj
-1129 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F62 1060 0 R /F21 710 0 R /F39 895 0 R >>
-/XObject << /Im2 1049 0 R >>
+1144 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1140 0 obj <<
+1152 0 obj <<
+/Length 69
+/Filter /FlateDecode
+>>
+stream
+xÚ3T0
+endobj
+1151 0 obj <<
+/Type /Page
+/Contents 1152 0 R
+/Resources 1150 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1120 0 R
+>> endobj
+1153 0 obj <<
+/D [1151 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1150 0 obj <<
+/ProcSet [ /PDF ]
+>> endobj
+1156 0 obj <<
/Length 1913
/Filter /FlateDecode
>>
@@ -3851,61 +3924,61 @@ M&PÄqíèÙi7jÓŽ4¾§YyŸ"A¦͠ì‚d,"û©ì±‰kkÒ;¥)ÏR^Š:”&JÓ×9*—“²,Jן©IW؃È!6Š
q¿–D"mX• ‘¹ÈjmËúÿ@CH®2#¶¦È²&RØš8"u£
:åô³¡&Ä«»Û†ý5é˜âB€û}Ye¡ødÉ °]B楖x¬†Í@”üizT(þ¶Úxe訳vTn3o-òÁa^¨ª1ü8Háã=ô6³¶µ{Ó‘¡š»hW”P·Šj‰v¢æwЮ„Z[Š´»ƒhM 5ƒ© º¡s?‡+ì
ïp,'èñ+)jä‘jåQúk ©ï¯‘ÙYºÝÕ¡Eâ¦Á§âÛð´â·I-§Ñ;ÀÍÍ$b®»Ö¬Ý‰ÜQµ㩺›{JýÐà4;,ÿ‰f`¨º ‡W$‚7€Úù«1[Ë/¥nÆÏX «Eš Q S£»»·ž;šWïP{“øÄDN)ój=u”ö¬ÊùßC;»òÕ]Û Ñ_;Œ`ÝÄF
-q…7ÉGb†N0bèKNôJ… $ȳÈBÏ"g¥O Øêåýµ G’^—=Ys{}ñJE½Ó6l`‘“TÈ‹«Ã}%­JüŠÆ‹ŸêIÙmS:_Óß Р*çóýÃì(š´ªŠúºWy÷ËÓü-1~!EŠß×¾6F‘íE†>5.NF¸áb¼¹]mþpùv¹ÿÐÆ}endstream
+q…7ÉGb†N0bèKNôJ… $ȳÈBÏ"g¥O Øêåýµ G’^—=Ys{}ñJE½Ó6l`‘“TÈ‹«Ã}%­JüŠÆ‹ŸêIÙmS:_Óß Р*çóýÃì(š´ªŠúºWy÷ËÓü-1~!EŠß×¾6F‘íE†>5.NF¸áb‚Ý®6¸|»ÜÿÏ“vendstream
endobj
-1139 0 obj <<
+1155 0 obj <<
/Type /Page
-/Contents 1140 0 R
-/Resources 1138 0 R
+/Contents 1156 0 R
+/Resources 1154 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1115 0 R
+/Parent 1161 0 R
>> endobj
-1141 0 obj <<
-/D [1139 0 R /XYZ 85.0394 794.5015 null]
+1157 0 obj <<
+/D [1155 0 R /XYZ 85.0394 794.5015 null]
>> endobj
230 0 obj <<
-/D [1139 0 R /XYZ 85.0394 769.5949 null]
+/D [1155 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1142 0 obj <<
-/D [1139 0 R /XYZ 85.0394 576.7004 null]
+1158 0 obj <<
+/D [1155 0 R /XYZ 85.0394 576.7004 null]
>> endobj
234 0 obj <<
-/D [1139 0 R /XYZ 85.0394 576.7004 null]
+/D [1155 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-1143 0 obj <<
-/D [1139 0 R /XYZ 85.0394 544.8207 null]
+1159 0 obj <<
+/D [1155 0 R /XYZ 85.0394 544.8207 null]
>> endobj
238 0 obj <<
-/D [1139 0 R /XYZ 85.0394 403.9445 null]
+/D [1155 0 R /XYZ 85.0394 403.9445 null]
>> endobj
-1144 0 obj <<
-/D [1139 0 R /XYZ 85.0394 368.2811 null]
+1160 0 obj <<
+/D [1155 0 R /XYZ 85.0394 368.2811 null]
>> endobj
-1138 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1154 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1147 0 obj <<
+1164 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1146 0 obj <<
+1163 0 obj <<
/Type /Page
-/Contents 1147 0 R
-/Resources 1145 0 R
+/Contents 1164 0 R
+/Resources 1162 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1115 0 R
+/Parent 1161 0 R
>> endobj
-1148 0 obj <<
-/D [1146 0 R /XYZ 56.6929 794.5015 null]
+1165 0 obj <<
+/D [1163 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1145 0 obj <<
+1162 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1151 0 obj <<
+1168 0 obj <<
/Length 3113
/Filter /FlateDecode
>>
@@ -3924,49 +3997,49 @@ h4:‰[q=`¼Âµ®•úë3ö¼pÃåÀ Ô^VØiÝÌW»E…ŠiÎ|3‘]8~½ÑXQÎDzLe=HF}Ü7Pƒˆq6F™‰î
'öuð8Z¿›· CHU™îá|éAæshQ‰P¼××ãÞÍcoY~®°ç¦åú¡~ÚÕý }À£/­ê-uÊüo<»ÓŽþ­w]D÷På¢à¢î;N-xœZ¼L¤v³¡»ÙÖ%¾4©h<,z¾¥™äut¼×
Ÿ6ô’fŽ&û@d !{A¹I1ùO!&Ó
²>Ÿ2˜ÄáÎG9ü)¿²ÁrÔ™½ã7àã~€ª;'è¼UðB4²nÃÑ2–'ÁN;ú3Þ*ü?ÚªŠª•YZêð€rõ\¾ÄE^í…
-¶ÍÍ^f"|-Ô—0zp™=Ÿ?¬†3©­ÒŠI®åÍØ^fSi Ó¿ŒËX9\+ÒGêý:ƒÑZ0)-Ø ºÈÙ"{Kšž‡ã$¾6Ï_Ôr i;ur-;<IߣJËý~ÌÑóendstream
+¶ÍÍ^f"|-Ô—0zp™=Ÿ?¬†3©­ÒŠI®åÍØ^fSi Ó¿ŒËX9\+ÒGêý:ƒÑZ0)-Ø ºÈÙ"{Kšž‡ã$¾6Ï_Ôr i;¥NXHOÒ÷¨Òrÿ$Ñõendstream
endobj
-1150 0 obj <<
+1167 0 obj <<
/Type /Page
-/Contents 1151 0 R
-/Resources 1149 0 R
+/Contents 1168 0 R
+/Resources 1166 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
-/Annots [ 1157 0 R ]
+/Parent 1161 0 R
+/Annots [ 1174 0 R ]
>> endobj
-1157 0 obj <<
+1174 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [356.2946 363.7923 412.5133 376.6291]
/Subtype /Link
/A << /S /GoTo /D (address_match_lists) >>
>> endobj
-1152 0 obj <<
-/D [1150 0 R /XYZ 85.0394 794.5015 null]
+1169 0 obj <<
+/D [1167 0 R /XYZ 85.0394 794.5015 null]
>> endobj
242 0 obj <<
-/D [1150 0 R /XYZ 85.0394 769.5949 null]
+/D [1167 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1153 0 obj <<
-/D [1150 0 R /XYZ 85.0394 576.7004 null]
+1170 0 obj <<
+/D [1167 0 R /XYZ 85.0394 576.7004 null]
>> endobj
246 0 obj <<
-/D [1150 0 R /XYZ 85.0394 479.565 null]
+/D [1167 0 R /XYZ 85.0394 479.565 null]
>> endobj
-1154 0 obj <<
-/D [1150 0 R /XYZ 85.0394 441.8891 null]
+1171 0 obj <<
+/D [1167 0 R /XYZ 85.0394 441.8891 null]
>> endobj
-1155 0 obj <<
-/D [1150 0 R /XYZ 85.0394 424.9629 null]
+1172 0 obj <<
+/D [1167 0 R /XYZ 85.0394 424.9629 null]
>> endobj
-1156 0 obj <<
-/D [1150 0 R /XYZ 85.0394 413.0077 null]
+1173 0 obj <<
+/D [1167 0 R /XYZ 85.0394 413.0077 null]
>> endobj
-1149 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1166 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1162 0 obj <<
+1178 0 obj <<
/Length 4061
/Filter /FlateDecode
>>
@@ -3989,35 +4062,35 @@ KeøQ½‘†Ê©>ßÒ3ÅK—€FÀ–È—l7¦yÁc›£·Ü ·—´¢ Ä–RŠé"$š|Ø%Cj·x²ÇÀ˜Ë ÚzáÀMg^Ê
“@ÄŠçB”‡bW°ÖÌJ©”ÔCq]šù#!¦öŽ„`Üôo]¬ Û˳ÄKú%¾]˨ޖ9…Õ“]|Ìßlšnê.ÛµtlÔFUÝÕ‹T
S÷£sÈÀÈX÷Œ–2w»(æ0 
žèͶKê-‰?˜^À¡E×°NžÄô;,)ÒJ”¯0¬•;ªå ëÉ3½&„–˺/ÐñÐè›»ç“_A½Îì±ê%”ÔTÚêÏk]ß­ëËAt•Û…e›(Cµ|LÌœÜnè?cX/J•–±È
-jLŒ˜æxqºñ¿IýÅã=þ\%öúoõ꾈CþuèÃcUJ‡w7žæU¿ú£äí'ÛÒagÐ;ð-JZœòEð½™3
+jLŒ˜æxqºñ¿IýÅã=þ\%öúoõ꾈CþuèÃcUJ‡w7žæU¿ú£äí'ÛÒagÐ;ð-JZœòEȽ™3
endobj
-1161 0 obj <<
+1177 0 obj <<
/Type /Page
-/Contents 1162 0 R
-/Resources 1160 0 R
+/Contents 1178 0 R
+/Resources 1176 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1161 0 R
>> endobj
-1163 0 obj <<
-/D [1161 0 R /XYZ 56.6929 794.5015 null]
+1179 0 obj <<
+/D [1177 0 R /XYZ 56.6929 794.5015 null]
>> endobj
250 0 obj <<
-/D [1161 0 R /XYZ 56.6929 165.9801 null]
+/D [1177 0 R /XYZ 56.6929 165.9801 null]
>> endobj
-1159 0 obj <<
-/D [1161 0 R /XYZ 56.6929 136.242 null]
+1175 0 obj <<
+/D [1177 0 R /XYZ 56.6929 136.242 null]
>> endobj
254 0 obj <<
-/D [1161 0 R /XYZ 56.6929 136.242 null]
+/D [1177 0 R /XYZ 56.6929 136.242 null]
>> endobj
-1164 0 obj <<
-/D [1161 0 R /XYZ 56.6929 106.2766 null]
+1180 0 obj <<
+/D [1177 0 R /XYZ 56.6929 106.2766 null]
>> endobj
-1160 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R >>
+1176 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1167 0 obj <<
+1183 0 obj <<
/Length 3096
/Filter /FlateDecode
>>
@@ -4030,41 +4103,41 @@ e$EßùödÕš>h¸£O+Ðã6#E€Èû ­Œ…ÍpøÑ‹ý2/²UƈLã‘[ßQæºß¾zY c[GŒÖ ‹|Qoá—Ö~QÐBmHÚGð
ËY_¯ÉÌ›H×v™ÝçUäº`×vgá…­uw/Æ23z4›ëÆ2¯s7ìW&€º+-/½TK F­(
µbAm¨$FýþºÍcÏ‚P—àU¶ð_™xV(àM÷èê`¸Xw
›1¸ÜC¯.‰}~©­mÖtãá>}?î
-0{× ª»ŸŽb¯>´æøµ*P·›Ú_ýF‰s‘ïAt$§WÇ)?®ÃMPÐH§5<Ùqnë ÖT7DtùÌ}—CuB_}Û¥»¥€nºÛƒnwã
+0{× ª»ŸŽb¯>´æøµ*P·›Ú_ýF‰s‘ïAt$§WÇ)?®ÃMPÐH§5<Ùqnë ÖT7DtùÌ}—CuB_}Û¥»¥€nºÛƒnwã
endobj
-1166 0 obj <<
+1182 0 obj <<
/Type /Page
-/Contents 1167 0 R
-/Resources 1165 0 R
+/Contents 1183 0 R
+/Resources 1181 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1161 0 R
>> endobj
-1168 0 obj <<
-/D [1166 0 R /XYZ 85.0394 794.5015 null]
+1184 0 obj <<
+/D [1182 0 R /XYZ 85.0394 794.5015 null]
>> endobj
258 0 obj <<
-/D [1166 0 R /XYZ 85.0394 731.767 null]
+/D [1182 0 R /XYZ 85.0394 731.767 null]
>> endobj
-1169 0 obj <<
-/D [1166 0 R /XYZ 85.0394 703.7216 null]
+1185 0 obj <<
+/D [1182 0 R /XYZ 85.0394 703.7216 null]
>> endobj
262 0 obj <<
-/D [1166 0 R /XYZ 85.0394 229.6467 null]
+/D [1182 0 R /XYZ 85.0394 229.6467 null]
>> endobj
-1170 0 obj <<
-/D [1166 0 R /XYZ 85.0394 201.8883 null]
+1186 0 obj <<
+/D [1182 0 R /XYZ 85.0394 201.8883 null]
>> endobj
266 0 obj <<
-/D [1166 0 R /XYZ 85.0394 144.1965 null]
+/D [1182 0 R /XYZ 85.0394 144.1965 null]
>> endobj
-1171 0 obj <<
-/D [1166 0 R /XYZ 85.0394 118.9605 null]
+1187 0 obj <<
+/D [1182 0 R /XYZ 85.0394 118.9605 null]
>> endobj
-1165 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R /F14 737 0 R /F39 895 0 R >>
+1181 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R /F14 741 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1175 0 obj <<
+1191 0 obj <<
/Length 2474
/Filter /FlateDecode
>>
@@ -4081,16 +4154,17 @@ xÚ½koã6ò{~…~8{»fH‘Ô£ý´»MÒ·Û^6ÅáÐ8ÅæÚBeÉ•äMÓ_3R¢åÑ&Wˆø‡óž±˜qø3³8‹²Y’)
Øð²¢zAËÒ@«–x£D3ži
(åuc&ad#ÊÝ8 2DZo3QŠp-øÁ8‘ȶ^1°é¢M#ð
ãyÒUà SÉSûã°ˆx6õË5Ÿ=Üžú;ùP"*pOi…í–€eIÊT
-H¤fˆ 9"ÕÎ’ÿAÝA¤ÿC9 endstream
+H¤fˆ 9"ã;%ÿƒºƒ
+HÿC‘ Ÿendstream
endobj
-1174 0 obj <<
+1190 0 obj <<
/Type /Page
-/Contents 1175 0 R
-/Resources 1173 0 R
+/Contents 1191 0 R
+/Resources 1189 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1161 0 R
>> endobj
-1172 0 obj <<
+1188 0 obj <<
/Type /XObject
/Subtype /Form
/FormType 1
@@ -4110,33 +4184,33 @@ xÚm”In1 EOPw¨u€$ÅIg0²Êľÿ6¤¤êV5 oʯÅésÀóή¯ƒÖ×O²Î Ž¢‘ÿ¨#h8Çùø:„5?ù
6\>RgÈbÏWÖ¹j[†›
WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åŽ°Š­r²ÂÙÄLûˆ T¥Í¡誋ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream
endobj
-1176 0 obj <<
-/D [1174 0 R /XYZ 56.6929 794.5015 null]
+1192 0 obj <<
+/D [1190 0 R /XYZ 56.6929 794.5015 null]
>> endobj
270 0 obj <<
-/D [1174 0 R /XYZ 56.6929 769.5949 null]
+/D [1190 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1177 0 obj <<
-/D [1174 0 R /XYZ 56.6929 749.9737 null]
+1193 0 obj <<
+/D [1190 0 R /XYZ 56.6929 749.9737 null]
>> endobj
274 0 obj <<
-/D [1174 0 R /XYZ 56.6929 282.0726 null]
+/D [1190 0 R /XYZ 56.6929 282.0726 null]
>> endobj
-1178 0 obj <<
-/D [1174 0 R /XYZ 56.6929 250.2286 null]
+1194 0 obj <<
+/D [1190 0 R /XYZ 56.6929 250.2286 null]
>> endobj
-1179 0 obj <<
-/D [1174 0 R /XYZ 56.6929 191.4593 null]
+1195 0 obj <<
+/D [1190 0 R /XYZ 56.6929 191.4593 null]
>> endobj
-1180 0 obj <<
-/D [1174 0 R /XYZ 56.6929 179.5041 null]
+1196 0 obj <<
+/D [1190 0 R /XYZ 56.6929 179.5041 null]
>> endobj
-1173 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R >>
-/XObject << /Im3 1172 0 R >>
+1189 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F62 1065 0 R >>
+/XObject << /Im3 1188 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1183 0 obj <<
+1199 0 obj <<
/Length 2134
/Filter /FlateDecode
>>
@@ -4148,47 +4222,47 @@ xÚÍYMsã6½ûWè¶òVˆàƒˆääx<§fœÄvN“©)Z¢$f(Ò+RV¼»ùïÛ$ʦ,;ÖTmù  4¯×´pøƒ4a\Ùx
TiJ¶ŒÁo Ž¡1ÿðb‚¥óeãuÜxIÈÙc¯ŠvÖÇãLÊ,_'ú !hãnr¬’Ð:Ú¨ð‚õdFàÇ$¢™¯fÄìóï±t¶Ãªö÷ÇB°ñÀ-°ÅŠH¬vZ;ñ: ±„·(˜â:eY¯òq/ÞxܤI³0sº.:©GÕͲ(Û¨¨¾{øÀ 3cŒ„, ùH‰ç½FPÕkc^úõ­
vðƒ’/¦HÕÔN!¥àUPÌhésiuß4V}OÂ#ôxí³Òß—YÝôVÕÈ ýwy-…PLkÿ*˜ÅXÂ+µ3H)7ßU?ïz´ª~fc…Ù«á5f«;®öa¦°–žïŒ²OÿÜŒ‚ìŠ7ÚÈáù/w1‰è %‘ö¢MÆ ÝË
|Jq‚s ÊÈ5}ßqg:W(â.BnüÎè»âUí˜Ì % M×$¬ê–·Dî \Š±_‘ÑÏÊ‘hh´0è×sØf^T½—)¤d앺‡þO’”yJ¦í¬¡¾ b”£¨éƒZ[AïH—žW4Ö,û‘d%FY“Óû%È0 \r]•ìvu´ž»uC6µÃ¼›ðÖ'ØMoû6_Ë›oHö‡#AÄؾô±^‰Å©LU×Ö%æô½†fî¾µÝëðº+¶¹µ/)sO,Á<‘ þˆÁ NŸYæJöµ•Ò;ÅOø–H¡ŠN즦S¾rŸýé“ÿ ;v&žŒl´lê¹@·.ÑGšW¬¥2v/»ýìÂËuþK*„b‰‰12«Ä©ø§"¥$ý´Úïr[/ÚµîM瓯A‘ƒ#!9ï«6ià/bÍ!†¶Žä¾'5ø¿{P”ú]
-c˜á©Þ¾‹PaŒm-ã½(.«âOÒ ê jA£VµœßäÎzU…fW<]ÔËÛÇâhŸiâ˃´¯tïûï«JXLáýððÁ^ZùÜÿÌnþm .Viºã«ÑúÚy£Ðr•<ÊR*eI*MéÿUÜU?endstream
+c˜á©Þ¾‹PaŒm-ã½(.«âOÒ ê jA£VµœßäÎzU…fW<]ÔËÛÇâhŸiâ˃´¯tïûï«JXLáýððÁ^ZùÜÿÌnþm .Viºã«ÑúÚy£Ðree)•²$•¦ÇôÿV4UAendstream
endobj
-1182 0 obj <<
+1198 0 obj <<
/Type /Page
-/Contents 1183 0 R
-/Resources 1181 0 R
+/Contents 1199 0 R
+/Resources 1197 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1206 0 R
>> endobj
-1184 0 obj <<
-/D [1182 0 R /XYZ 85.0394 794.5015 null]
+1200 0 obj <<
+/D [1198 0 R /XYZ 85.0394 794.5015 null]
>> endobj
278 0 obj <<
-/D [1182 0 R /XYZ 85.0394 585.0446 null]
+/D [1198 0 R /XYZ 85.0394 585.0446 null]
>> endobj
-1185 0 obj <<
-/D [1182 0 R /XYZ 85.0394 560.705 null]
+1201 0 obj <<
+/D [1198 0 R /XYZ 85.0394 560.705 null]
>> endobj
282 0 obj <<
-/D [1182 0 R /XYZ 85.0394 491.9365 null]
+/D [1198 0 R /XYZ 85.0394 491.9365 null]
>> endobj
-1186 0 obj <<
-/D [1182 0 R /XYZ 85.0394 461.8226 null]
+1202 0 obj <<
+/D [1198 0 R /XYZ 85.0394 461.8226 null]
>> endobj
-1187 0 obj <<
-/D [1182 0 R /XYZ 85.0394 384.4846 null]
+1203 0 obj <<
+/D [1198 0 R /XYZ 85.0394 384.4846 null]
>> endobj
-1188 0 obj <<
-/D [1182 0 R /XYZ 85.0394 372.5294 null]
+1204 0 obj <<
+/D [1198 0 R /XYZ 85.0394 372.5294 null]
>> endobj
286 0 obj <<
-/D [1182 0 R /XYZ 85.0394 206.4979 null]
+/D [1198 0 R /XYZ 85.0394 206.4979 null]
>> endobj
-1189 0 obj <<
-/D [1182 0 R /XYZ 85.0394 171.8379 null]
+1205 0 obj <<
+/D [1198 0 R /XYZ 85.0394 171.8379 null]
>> endobj
-1181 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1197 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1192 0 obj <<
+1209 0 obj <<
/Length 4496
/Filter /FlateDecode
>>
@@ -4214,56 +4288,56 @@ mtÈf;Ku…ÜÖê °q
¤ kOþÕ%A\uÓìj´>?ä8b‘8)ŸÁÉÿ×ã <ásä £ %Æ$*“瓱^}ð.CFó/ó¸]NªèÐY '£ïº&’»G«±ÎÅâ(œ3¢üFÎÓurpóëXh·üÄÔ^¤–ÏaÇàÑ3v¬YÞTkt
ÐÖÏ® ˜é$5±HN‘³É^6
»§tŸÀÄëjä`¦ä£L=tç’JÖɹ[¾?4C¸Â[ô«CÉ[·P«Ïüac~595_È3fù¡ ¶ÖVxá
-]`‚ëYÚ‘aˆéÍ)ö¤Ã‚íw‡æ«w9øø‡n0²Nð-·3õÄCh– ý{ØÌ
+]`‚ëYÚ‘aˆéÍ)ö¤Ã‚íw‡æ«w9øø‡n0²Nð-·3õÄCh– ý{ØÌ
endobj
-1191 0 obj <<
+1208 0 obj <<
/Type /Page
-/Contents 1192 0 R
-/Resources 1190 0 R
+/Contents 1209 0 R
+/Resources 1207 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
-/Annots [ 1194 0 R 1195 0 R ]
+/Parent 1206 0 R
+/Annots [ 1211 0 R 1212 0 R ]
>> endobj
-1194 0 obj <<
+1211 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [55.6967 480.2482 256.3816 492.3078]
/Subtype /Link
/A << /S /GoTo /D (rndc) >>
>> endobj
-1195 0 obj <<
+1212 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [268.5158 480.2482 332.4306 492.3078]
/Subtype /Link
/A << /S /GoTo /D (admin_tools) >>
>> endobj
-1193 0 obj <<
-/D [1191 0 R /XYZ 56.6929 794.5015 null]
+1210 0 obj <<
+/D [1208 0 R /XYZ 56.6929 794.5015 null]
>> endobj
290 0 obj <<
-/D [1191 0 R /XYZ 56.6929 769.5949 null]
+/D [1208 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1041 0 obj <<
-/D [1191 0 R /XYZ 56.6929 749.0409 null]
+1046 0 obj <<
+/D [1208 0 R /XYZ 56.6929 749.0409 null]
>> endobj
294 0 obj <<
-/D [1191 0 R /XYZ 56.6929 209.5509 null]
+/D [1208 0 R /XYZ 56.6929 209.5509 null]
>> endobj
-1196 0 obj <<
-/D [1191 0 R /XYZ 56.6929 183.9497 null]
+1213 0 obj <<
+/D [1208 0 R /XYZ 56.6929 183.9497 null]
>> endobj
298 0 obj <<
-/D [1191 0 R /XYZ 56.6929 147.0778 null]
+/D [1208 0 R /XYZ 56.6929 147.0778 null]
>> endobj
-1197 0 obj <<
-/D [1191 0 R /XYZ 56.6929 116.7981 null]
+1214 0 obj <<
+/D [1208 0 R /XYZ 56.6929 116.7981 null]
>> endobj
-1190 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F14 737 0 R >>
+1207 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F14 741 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1201 0 obj <<
+1218 0 obj <<
/Length 2349
/Filter /FlateDecode
>>
@@ -4277,69 +4351,69 @@ xÚµ]sÛ8îÝ¿ÂÊLÅòC¥ÉS·›ô²w›½K½OÝNG‘[³¶äµäd|·ûß$HY²ä:½Î’ €
J[¨åÅ%RÉ )Σ b±ÁÑ·òÅe|–˜üVb"™ä ì=îÒRç''ä€*’'ô$ãgéùHèŠ5F²}Ê/¨É0¬ô-ÆDsNƒÅUJ!n@XÁ<¾Ò„fe K¸jœ!ž8m·¤a´€i÷¸‹
ù1üÔBÄNh[1¢„Ï Ao¼Íg¢V ïXܽPد8 Y‚Å$†„9’ÀCwÄòôÂÁqÀ`^2eIw,>¡6úL¦ÃJ&²³ŒZñZS6h)Ø…Ú]ƒ[wI~ïbÜVÚ3°u©ž°wÐò {´Éñ<o¡Ó óuÙfÖè0Žp áQ,<"ÊHÎô‚@PÆ¢´ë¥®´®—KgÎÿK' Û>‘cŒ)ÈVM›®/í'ÄèZ½ÁL×zܾ“ÂNRDz*×}›µ+Ü=Ñycýs!³h 48:Òòþjà?ñ³¯Ö妴—àpBŸ§ÔÑoÊë/\g8)—;µ94 Ê>üå)ËË5<ƒSmB¿«-ôn7Åן^¾õú(ÇuŸ6-ˆ6IX{8**‡!ÄÓõ@Ipj=TÛK¶«:Cð§×°Sû)s¶ 3YÊê©l+ôãÞr\¹>êr€z€ë/ó¾ˆ}º—iCó€³:qÚˆ—­ª¯/ß=R*îՔؘR[zw¸DeÚ¢þzÏC¹ýè’'²~›¯‡|=¸¬³ë„ïäÞPÀ­Ãþ­Îè+Bàÿ±%N…òïŽç`ò}â"emq¡zÍ9¬¹Ì,vÇ…)xL;Î@ÏÙ®ÔÆ&ÍÀä#«ÚNn[Œ‹f€Ýrá
oƒ‹wh¦\é¨"“HejäfªÙ'S9‰O}¼‹é›"R%'ÿhlW» k[óþ5u^‚Ü ö
-ê}»Ý·¸¶Ñíª.š7Xkã›Ì­tÙö‚½2Ñkfdã‰Cy1U–»˜\Áºk ÚÕÎÌ·ùlŠà ,Ù±+pb®®òt­  e¥„JŸ1w.9QŒ@¡˜x•v’.)1 €^ëÜÙíª~AÀ\~½w9D¾mj7ÀÌÔ(±1–ìÓŒcŒž¡ rî?!‰ù·n¢ÍF;ßûî?ÿ˜B5&’äLû]ÐjµTy¦Œ’„:å¼û÷pÌúâØ\5endstream
+ê}»Ý·¸¶Ñíª.š7Xkã›Ì­tÙö‚½2Ñkfdã‰Cy1U–»˜\Áºk ÚÕÎÌ·ùlŠà ,Ù±+pb®®òt­  e¥„JŸ1w.9QŒ@¡˜x•v’.)1 €^ëÜÙíª~AÀ\~½w9D¾mj7ÀÌÔ(±1–ìÓŒcŒž¡ rî?!‰ù·n¢ÍF;ßûî?ÿ˜B5&’äLû]ÐjµTy¦Œ’DzÊy÷ïá˜õÿã0\7endstream
endobj
-1200 0 obj <<
+1217 0 obj <<
/Type /Page
-/Contents 1201 0 R
-/Resources 1199 0 R
+/Contents 1218 0 R
+/Resources 1216 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1210 0 R
-/Annots [ 1205 0 R 1206 0 R 1207 0 R ]
+/Parent 1206 0 R
+/Annots [ 1222 0 R 1223 0 R 1224 0 R ]
>> endobj
-1205 0 obj <<
+1222 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [406.6264 617.3695 456.8481 629.4292]
/Subtype /Link
/A << /S /GoTo /D (tsig) >>
>> endobj
-1206 0 obj <<
+1223 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [140.5805 606.0819 196.7992 617.474]
/Subtype /Link
/A << /S /GoTo /D (controls_statement_definition_and_usage) >>
>> endobj
-1207 0 obj <<
+1224 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [103.6195 562.6731 159.8382 574.7328]
/Subtype /Link
/A << /S /GoTo /D (controls_statement_definition_and_usage) >>
>> endobj
-1202 0 obj <<
-/D [1200 0 R /XYZ 85.0394 794.5015 null]
+1219 0 obj <<
+/D [1217 0 R /XYZ 85.0394 794.5015 null]
>> endobj
302 0 obj <<
-/D [1200 0 R /XYZ 85.0394 769.5949 null]
+/D [1217 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1203 0 obj <<
-/D [1200 0 R /XYZ 85.0394 749.0225 null]
+1220 0 obj <<
+/D [1217 0 R /XYZ 85.0394 749.0225 null]
>> endobj
306 0 obj <<
-/D [1200 0 R /XYZ 85.0394 668.2594 null]
+/D [1217 0 R /XYZ 85.0394 668.2594 null]
>> endobj
-1204 0 obj <<
-/D [1200 0 R /XYZ 85.0394 636.8261 null]
+1221 0 obj <<
+/D [1217 0 R /XYZ 85.0394 636.8261 null]
>> endobj
310 0 obj <<
-/D [1200 0 R /XYZ 85.0394 425.0299 null]
+/D [1217 0 R /XYZ 85.0394 425.0299 null]
>> endobj
-1208 0 obj <<
-/D [1200 0 R /XYZ 85.0394 396.4061 null]
+1225 0 obj <<
+/D [1217 0 R /XYZ 85.0394 396.4061 null]
>> endobj
314 0 obj <<
-/D [1200 0 R /XYZ 85.0394 136.3155 null]
+/D [1217 0 R /XYZ 85.0394 136.3155 null]
>> endobj
-1209 0 obj <<
-/D [1200 0 R /XYZ 85.0394 104.8822 null]
+1226 0 obj <<
+/D [1217 0 R /XYZ 85.0394 104.8822 null]
>> endobj
-1199 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F41 935 0 R /F23 734 0 R /F53 1027 0 R >>
+1216 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F41 940 0 R /F23 738 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1213 0 obj <<
+1229 0 obj <<
/Length 3704
/Filter /FlateDecode
>>
@@ -4360,29 +4434,29 @@ B+Áä úÁ\³RÉñ¥
\Þ‡ÔsÌ=’K1­ûÝ9>ÇâR$u»,êP-AM,ñ¿ãÑc<ò3Ñ£>žä3K&zL^Íú–ÕÙ|$1*£J/ i.Âþvé?–Hbìõ%êôÓ%ª„»oOo'|½ºÃn×î¹× f\ýËØ Æ+0ªÀp¹ ˜¶¢Ôì[êñŸÞl@¸Òùº}*¾gþ„Ü|‡= b¯j&o|W$ü]_àsã¾ãRq
aÖœ’þÖ2MÅÉn2¾ÜÐ3|ñêP¤ZMŽ-Ûfj¿â7bb‚3‡`¼£²õ ÐÀWû ÓâCI ‚
×$qdAlÇ·c”6|‚q†Å¿côqJ@Þ‰âõe(UÇXç¯ ×PRq‰È{4näÊŸ,NZ=5èÎQ=4\Rr¿kp¦Î/ìûH¡ü7îš7øÕ”þ«O•žÛý#«g]=³@¤ÂWÅ&
-¿ë=~ͯÝ[G€ÿ^ ;j£i/_Ûay"Á’¸/lïžüQ'ÌÑWHÚ)õøsL=ôpèrÛ$Qžfê´á³/ª‡ î.sÒx¢¢«QŸ@àŒèk\¶±´ÁèРߨMS×,Yú“+Û¹Q³ïß#so‰27l\áŒP~ÖeÑñÐV¸ÊUÉ
+¿ë=~ͯÝ[G€ÿ^ ;j£i/_Ûay"Á’¸/lïžüQ'ÌÑWHÚ)õøsL=ôpèrÛ$Qžfê´á³/ª‡ î.sÒx¢¢«QŸ@àŒèk\¶±´ÁèРߨMS×,Yú“+Û¹Q³ïß#so‰27l\áŒP~ÖeÑñÐV¸ÊUÉ
endobj
-1212 0 obj <<
+1228 0 obj <<
/Type /Page
-/Contents 1213 0 R
-/Resources 1211 0 R
+/Contents 1229 0 R
+/Resources 1227 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1210 0 R
+/Parent 1206 0 R
>> endobj
-1214 0 obj <<
-/D [1212 0 R /XYZ 56.6929 794.5015 null]
+1230 0 obj <<
+/D [1228 0 R /XYZ 56.6929 794.5015 null]
>> endobj
318 0 obj <<
-/D [1212 0 R /XYZ 56.6929 607.7662 null]
+/D [1228 0 R /XYZ 56.6929 607.7662 null]
>> endobj
-1215 0 obj <<
-/D [1212 0 R /XYZ 56.6929 584.6557 null]
+1231 0 obj <<
+/D [1228 0 R /XYZ 56.6929 584.6557 null]
>> endobj
-1211 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F39 895 0 R >>
+1227 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1218 0 obj <<
+1234 0 obj <<
/Length 2891
/Filter /FlateDecode
>>
@@ -4401,31 +4475,31 @@ n÷B1ºÉ<±%ô)ðs—bÈ
ÁD˜×žtÔ³IÀy9®<þ!€sŸáe`_þ=;»Ø#WÁn_5E4MIã"ýstˆ¨Ðûž «ý >k̼Â0RΔ1H™4nVB%,Uv®šÎÙ´Ý1BM’2‘ÚF}·Ô:aZò³ˆBàñÛ*&W/c^ïÍ  …¨NÍb¼ÍõÜ3`jNÓÞ{h“·:~ôÓduÔv¦žbÕ^#Ä(H7ï VCÍ„ƒLLJKfÅøž@r8{î˜É
n1•ß¼K§Æ‹†§Ìà â +‡„œâôÖ@Óᾧ•£°ãc´ýHð¾¥Î’gê]©2¦d¢g<>Sðò1ûkwXãôžˆü8¿uE-LDBK´í£¯”ßzÜL StÏ]ÔÙ*ä¶^¹jæõ!?ö4ê cŽÜÒ/u©”
V³”WSâEi²{íÞÑ»ºªÊäÑÜ‚I(;ÏL=ö|;>ý¸ =5.±…ûNÅ*þ4Y›¸ht¤EQÕ
-=áŸË˹àÇÕÓ×ùtÄ×vÿt>íè­:0tŸyØú©¬éñ˜nõz'_&: ÊW±2sTÛú‚á—®®ÖgÔ‡zfJ€{,+W/Co]³“Þ,×o<M»Ó+ê2jºgE2•fŠQ;Bµá|QMžëÊf¸¨Æ)cŠ§Œ§z&J| Ü2ä2½0Çþ Æß^~^ø{rìÏ
+=áŸË˹àÇÕÓ×ùtÄ×vÿt>íè­:0tŸyØú©¬éñ˜nõz'_&: ÊW±2sTÛú‚á—®®ÖgÔ‡zfJ€{,+W/Co]³“Þ,×o<M»Ó+ê2jºgE2•fŠQ;Bµá|QMžëÊf¸¨Æ)cŠ§Œ§z&J| Ü2ä2½0Çþ Æß^~^ø{rìÏ
endobj
-1217 0 obj <<
+1233 0 obj <<
/Type /Page
-/Contents 1218 0 R
-/Resources 1216 0 R
+/Contents 1234 0 R
+/Resources 1232 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1210 0 R
-/Annots [ 1220 0 R ]
+/Parent 1206 0 R
+/Annots [ 1236 0 R ]
>> endobj
-1220 0 obj <<
+1236 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [173.6261 333.9221 242.2981 343.3317]
/Subtype /Link
/A << /S /GoTo /D (the_category_phrase) >>
>> endobj
-1219 0 obj <<
-/D [1217 0 R /XYZ 85.0394 794.5015 null]
+1235 0 obj <<
+/D [1233 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1216 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >>
+1232 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1224 0 obj <<
+1240 0 obj <<
/Length 2569
/Filter /FlateDecode
>>
@@ -4442,35 +4516,35 @@ X­ ƒKpp”&BIsp®•&Â:i"<!Xçh{$ª@9¾AŠC>VGŽ½.ó¼|èüÃéÈwí¤³®žÄ¢äoÜÆþ®ØŠt¤©1
¼äñò‹¼èèyïÛåÁZru(O<?Ñ>hÙ¡Ûqüþä.µäaÈ| ËPØCF3ûLÉP=S#Ä‹dà|Í”§õI3ðÕ]¢ê·¦iC[Â>M ´tƆ¬®&+£²Æ½!Îú:7ѹl‚žžÚme³M[YãD ¶óSÝ„ÖÅTù>4œ@F,àÐEüujCêQ¹Hìÿ’nÇÓ–åpøŒ%À­â˜Ó32½Dä/³›ø’n—ðV¹|þÁ´ܼTºkÛwÚÀe*HC OêÚh Ý!Є•ñå”iôí˨³¶qg˜€´[k÷¶M³–sB¹©}&Ž•|SårŤ˜§•ë̳½æ*i’»é>r¬Ü]Öö¥t±\²
:0M‘)](ƒŽ¸Ý„¥8-€6uUÐc.®Ü¦ÝÆp|Ô¿µ?êf”4þ, }di’v ?°tBÍù}+5»½œ¤Ûñ´š½I<£eîÑg*Vmiùœš/ööÝÿ>ɤ¸ÒEæ€&ßw9õ÷V×M}B¬=¿_'‚c©òo)UD(Ô3)2V jMúBãRɳB}{œsŽ¿R쓪îÚ¥NàV)x,>-ÞãßJ¼ÿ‡Øy,âO#ñª‰Ð£´SéºÌï»'û§ÅûîãO‹¥„‚”¬vµ(æ×øÝ7š×mºÅezF4W`_[þ½¦µ¼,¿´ûšÖ÷”&Ó –·®öt*ÅF7_=$Í3jÇŠI—:µ?
r¦[~Jçi~‚( ¨ù°ìJN~†öfÏF±—~ôîÿ# ˆ˜¯Ô WZµHA
-i¡ÈïÑ'y÷uÜb Xÿ/LN+8endstream
+i¡Èñ蓼û:n±¬ÿL¦+:endstream
endobj
-1223 0 obj <<
+1239 0 obj <<
/Type /Page
-/Contents 1224 0 R
-/Resources 1222 0 R
+/Contents 1240 0 R
+/Resources 1238 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1210 0 R
+/Parent 1206 0 R
>> endobj
-1225 0 obj <<
-/D [1223 0 R /XYZ 56.6929 794.5015 null]
+1241 0 obj <<
+/D [1239 0 R /XYZ 56.6929 794.5015 null]
>> endobj
322 0 obj <<
-/D [1223 0 R /XYZ 56.6929 556.3324 null]
+/D [1239 0 R /XYZ 56.6929 556.3324 null]
>> endobj
-1221 0 obj <<
-/D [1223 0 R /XYZ 56.6929 531.5504 null]
+1237 0 obj <<
+/D [1239 0 R /XYZ 56.6929 531.5504 null]
>> endobj
-1226 0 obj <<
-/D [1223 0 R /XYZ 56.6929 214.5791 null]
+1242 0 obj <<
+/D [1239 0 R /XYZ 56.6929 214.5791 null]
>> endobj
-1227 0 obj <<
-/D [1223 0 R /XYZ 56.6929 202.6239 null]
+1243 0 obj <<
+/D [1239 0 R /XYZ 56.6929 202.6239 null]
>> endobj
-1222 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R >>
+1238 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1230 0 obj <<
+1246 0 obj <<
/Length 2985
/Filter /FlateDecode
>>
@@ -4483,23 +4557,23 @@ e6M2“x&Xâc,»¿]ˆOüñIšÄLfjb2'Œ'“ùâˆM íݧ>ÓÐiÚïõööèoçÒL²8ÓBOnï{¼Ò˜¥)ŸÜ¿D§?ù
Þ¹WT´wö_KE!žŸåýiÄAåBÄàÜFUTdâjŠ—ÁgL Âéã†ÍGŸL÷ôé , úu¤@íèŸëÝ`_»¸Še•—Ô×Å=ž(ÖvÐîxŸE]¹°€ýœ]……474` ¾ê¾óóC•cåë6ƒQ©w¬ªïÐ3e™í”öÎR¢ÎóS$
"ÇE :‹•~SP9Cщ¾i€jtïn0…ÍPgÿ
e‡Ó=X„ó.©Ða¹=:}„j‡íihƒ%²eã£Ó楹Ÿ>#Æ;ˆ´hꨒ¶ 2Lç\‚¢½q©3²«RR:Ç |ÊÃy^#™GÝQ“×f)A‹A”H"ä Û6’î[KÑ){&{©TÁLõ„˜¡Ûðµ5Ø_Tu¨%U‡ê êóá‹Šò1½”£Î¨›
-™òm4uOyU@Â7=¬»ná9…2£Ä„ÜP÷à m£Ùý ‘~ìõp4¾õq¯ã}Ìòe8h ­¶?žû5žc˜Ùû5Þÿ7*,„ë _¦‰†nøŒ~Å÷ɯù„à±É
+™òm4uOyU@Â7=¬»ná9…2£Ä„ÜP÷à m£Ùý ‘~ìõp4¾õq¯ã}Ìòe8h ­¶?žû5žc˜Ùû5Þÿ7*,„ë _¦‰†nøŒ~Å÷ɯù„à±É
endobj
-1229 0 obj <<
+1245 0 obj <<
/Type /Page
-/Contents 1230 0 R
-/Resources 1228 0 R
+/Contents 1246 0 R
+/Resources 1244 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1210 0 R
+/Parent 1248 0 R
>> endobj
-1231 0 obj <<
-/D [1229 0 R /XYZ 85.0394 794.5015 null]
+1247 0 obj <<
+/D [1245 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1228 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1244 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1234 0 obj <<
+1251 0 obj <<
/Length 3540
/Filter /FlateDecode
>>
@@ -4521,41 +4595,41 @@ KvF:3+ )_ÞĆ½™Jój¡‡½¼& Ãé¯/QòÅÕO”›Û±ø‹•Ù¼»ª(ª @Ð,‰Ck¢Ç„þ"LžÎ"0OÄŒÃñ—H„<
U!˜I¡ª½
¥«„ÅBF0~¹dUû+ÞBoÝ8íªmèŠð+÷[pÇ E¾Ìw‚Ÿ=Wx8ο ó‘[7äF_,ÜI\÷"'[­tSm½à€E"dI†þ]ô {ùj@îþ.P‚@°/(fAÄ„ §Â½Ýy
ûWK‘÷jɾ©„<I?ôj)Üzµó^NC›Ôõ{ÁWf¶Uc+Ð[¤Ðµü1*rÂ"ÿõ&滆‘{P‚ƒ3îéÈUh.˜öœW“Ú~¯¶.£éµ!|[µ¥T©ïí£0üÚò1«YãA3¦ÌK=ó¯_]\]ÛÜî¥U­/èž
-é%¯'ÁùȼÜáÀè]öçjXý5ü×4¬: «q Cö/%½=£Ê6aïפy9ÜØ”yD©ºbRâ ‡(õæoZwúUýð¥rϲÕ
+é%¯'ÁùȼÜáÀè]öçjXý5ü×4¬: «q Cö/%½=£Ê6aïפy9ÜØ”yD©ºbRâ ‡(õæoZwúUýð¥rϲÕ
endobj
-1233 0 obj <<
+1250 0 obj <<
/Type /Page
-/Contents 1234 0 R
-/Resources 1232 0 R
+/Contents 1251 0 R
+/Resources 1249 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1210 0 R
+/Parent 1248 0 R
>> endobj
-1235 0 obj <<
-/D [1233 0 R /XYZ 56.6929 794.5015 null]
+1252 0 obj <<
+/D [1250 0 R /XYZ 56.6929 794.5015 null]
>> endobj
326 0 obj <<
-/D [1233 0 R /XYZ 56.6929 769.5949 null]
+/D [1250 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1236 0 obj <<
-/D [1233 0 R /XYZ 56.6929 749.9737 null]
+1253 0 obj <<
+/D [1250 0 R /XYZ 56.6929 749.9737 null]
>> endobj
-1237 0 obj <<
-/D [1233 0 R /XYZ 56.6929 433.0023 null]
+1254 0 obj <<
+/D [1250 0 R /XYZ 56.6929 433.0023 null]
>> endobj
-1238 0 obj <<
-/D [1233 0 R /XYZ 56.6929 421.0471 null]
+1255 0 obj <<
+/D [1250 0 R /XYZ 56.6929 421.0471 null]
>> endobj
330 0 obj <<
-/D [1233 0 R /XYZ 56.6929 173.1316 null]
+/D [1250 0 R /XYZ 56.6929 173.1316 null]
>> endobj
-1239 0 obj <<
-/D [1233 0 R /XYZ 56.6929 148.792 null]
+1256 0 obj <<
+/D [1250 0 R /XYZ 56.6929 148.792 null]
>> endobj
-1232 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1249 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1242 0 obj <<
+1259 0 obj <<
/Length 1976
/Filter /FlateDecode
>>
@@ -4571,62 +4645,62 @@ ab¸€,…aTOî) WC>èZ7½~Ö¿…¡hÌ`Ú†8ySñkŸ¯´³$÷|C"b"ã‰5t½Ö£;;!ž±4Q/Êý—ªÀ"“ÂIõ;×
¤v€À7>sz
»ÂöNFçûm49Žÿ}CÔj_³½væó†dtGƒ´­ÎD<tfµr¦Êo˜µ€®²Äc[ç]±žiÉ™PjfÖ
•Ú ð lójä[تÌæqÆ2èŒãݹç}¦Ý¶09/Fñn[ø ‡âCg;‹Jf d‹÷û'@F†Yp>ïn{4¥vQæô ©öÚLÆ (ülëÆ›nk1ÒXó°°/›nJ?ãlÞÆéXåƒytr¶«‰4nbo|Ûö
-%ܧ½)ÛaöP‘°,ÍøLÖ#¾ˆ¢iÁOŽGo<KTü]–_©wzßUq8ÖÚŠG8·JS€ÑÞÅdÇðks¯q#UâU$ΦÞÖ LÅA³­ïí®:
+%ܧ½)ÛaöP‘°,ÍøLÖ#¾ˆ¢iÁOŽGo<KTü]–_©wzßUq8ÖÚŠG8·JS€ÑÞÅdÇðks¯q#UâU$ΦÞÖ LÅA³­ïí®:
endobj
-1241 0 obj <<
+1258 0 obj <<
/Type /Page
-/Contents 1242 0 R
-/Resources 1240 0 R
+/Contents 1259 0 R
+/Resources 1257 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1250 0 R
-/Annots [ 1245 0 R 1246 0 R ]
+/Parent 1248 0 R
+/Annots [ 1262 0 R 1263 0 R ]
>> endobj
-1245 0 obj <<
+1262 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [519.8432 682.6714 539.579 694.731]
/Subtype /Link
/A << /S /GoTo /D (lwresd) >>
>> endobj
-1246 0 obj <<
+1263 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [84.0431 670.7162 117.8035 682.7759]
/Subtype /Link
/A << /S /GoTo /D (lwresd) >>
>> endobj
-1243 0 obj <<
-/D [1241 0 R /XYZ 85.0394 794.5015 null]
+1260 0 obj <<
+/D [1258 0 R /XYZ 85.0394 794.5015 null]
>> endobj
334 0 obj <<
-/D [1241 0 R /XYZ 85.0394 731.9325 null]
+/D [1258 0 R /XYZ 85.0394 731.9325 null]
>> endobj
-1244 0 obj <<
-/D [1241 0 R /XYZ 85.0394 701.4683 null]
+1261 0 obj <<
+/D [1258 0 R /XYZ 85.0394 701.4683 null]
>> endobj
338 0 obj <<
-/D [1241 0 R /XYZ 85.0394 475.6865 null]
+/D [1258 0 R /XYZ 85.0394 475.6865 null]
>> endobj
-1247 0 obj <<
-/D [1241 0 R /XYZ 85.0394 450.9966 null]
+1264 0 obj <<
+/D [1258 0 R /XYZ 85.0394 450.9966 null]
>> endobj
342 0 obj <<
-/D [1241 0 R /XYZ 85.0394 393.3855 null]
+/D [1258 0 R /XYZ 85.0394 393.3855 null]
>> endobj
-1248 0 obj <<
-/D [1241 0 R /XYZ 85.0394 362.9213 null]
+1265 0 obj <<
+/D [1258 0 R /XYZ 85.0394 362.9213 null]
>> endobj
346 0 obj <<
-/D [1241 0 R /XYZ 85.0394 329.3761 null]
+/D [1258 0 R /XYZ 85.0394 329.3761 null]
>> endobj
-1249 0 obj <<
-/D [1241 0 R /XYZ 85.0394 301.8169 null]
+1266 0 obj <<
+/D [1258 0 R /XYZ 85.0394 301.8169 null]
>> endobj
-1240 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >>
+1257 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1253 0 obj <<
+1269 0 obj <<
/Length 1168
/Filter /FlateDecode
>>
@@ -4634,120 +4708,122 @@ stream
xÚ½XÛnã6}÷WèÑ.@V÷ ö)›:iÝlëzŸÒÀ %*&B‰Z’rìnößKYK‰ÝJŽ$J<3çpf8¦¡éêÏкh^`CG7-LFºö Þ]ŒêPÚ_}œ~¾²<-€kºÚ<naùP÷}C›Gwcšp¢ôñå—Û«›ë¯³‹‰gç7_n'ÀtôñÕÍoÓòîzvñùóÅl ß1Æ—¿^ü>ŸÎÊWn…ññæö—r$(/G@gÓ«élz{9ÜÏ?¦ó†K›¯¡[‘o£»{]‹íO#ZïhOêA‡F˜Z2² :¶eÕ#tôçè°õv7õ ~†MË5h-}ºº‚òœ
CœIU3ÂqtBucü ñh¿¼å]‘%ÅŒ ²ùÊèŒy;ßËKdÙEQ¥ã]ƸlÆ‹‡ûò©2!¬íí.?úè“«2¥j]ø¨äæëÆ£¶¾ïÀL ŶÞa´×¥\­EQ¹þîyW£tàúq/d®U( À ¬’m#MWpG%M¸ÂJ•VõÝó;–Æ‘ºø·üì!
†´RˆÐÎ
-z¶eïPê´ª­Mk ׃–gÚõßSlo1¯{a :žmT¶c¶½í¶nÏ•'¦38ÜÙV¢öRÂò íÛöpoŽZ,Nñßé â› ÷'©¶Zß7›s@Ójšž¯È)Ê©‚‚m¿ò¼>U|íú?ÌÕÌendstream
+z¶eïPê´ª­Mk ׃–gÚõßSlo1¯{a :žmT¶c¶½í¶nÏ•'¦38ÜÙV¢öRÂò íÛöpoŽZ,Nñßé â› ÷'©¶Zß7›s@Ójšž¯È)Ê©‚‚í¾ò¼>U|íú?Í-Ìendstream
endobj
-1252 0 obj <<
+1268 0 obj <<
/Type /Page
-/Contents 1253 0 R
-/Resources 1251 0 R
+/Contents 1269 0 R
+/Resources 1267 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1250 0 R
+/Parent 1248 0 R
>> endobj
-1254 0 obj <<
-/D [1252 0 R /XYZ 56.6929 794.5015 null]
+1270 0 obj <<
+/D [1268 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1251 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >>
+1267 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1257 0 obj <<
-/Length 1152
+1273 0 obj <<
+/Length 1164
/Filter /FlateDecode
>>
stream
-xÚµXÛrÛ6}×WðÑê P\^&OŽ+»Î4N«ªOªFÆ"r¢4ý÷‚I¤EY$DƒÜƒ³g±‹°…̶<õmËõmÈfV¸!ëÞ¼»áê°ûÔ¿z;ý|M]ˇ¾Ck¶ªayy¶fÑüâê×Ëßg“é†.8ÌAooï~)GüòçêÃÝõíÍ_Ó˱k_Ìn?Ü•ÃÓÉõd:¹»šŒö6ö¤B8ap}ûÛ¤|º™^¾9/fïF“ÙÞ—º¿ÑÜ‘Ï£ùY‘qûÝAê{ÌúbþAû>±Ö#›QÈlJw#ñèÏÑ{ÀÚÛ´M?F=È<â¶h㚀˜è9[.ó¡C -œƒÐE*•.ŸþF •O"]†¿ç¾Z>®º6eÄOÕ+è3†­Ú …KëÅ»x³ÏM¶}hSß1O
-©Sû¼áj 2¹Q!ÎS–u¾Î2ˆ"Õ ì»8&§“#Â%#JŠÌÛ6FÃIJOÍm·‹õ½bBdħ;&¸Î$w—gY'%¨ mÏfýCw>D?jõ¿z6Å
-ÊÉ€Tʸßòl)Õ2‘ ,ÔªrÓäO•äÉfý‘«vò „H4WAÜe|ZI¶â
-h±æè<~BnôKhˆ(îFã D' Wt˜‚0<é “3F~™ª~âÌÃÊÄ#ï>}ƒ¸™\q¹,
-4ï9Í^ð¾äsÕb‘ižä
-²äC‚k•µ…ëYi Á»Èy%ºÄ…ØöÈÉ=ò¤¼}6ÊDj±Ú‚ˆÇÁvWªB™DY ¥öÄ©:¥ãBêû”`ìeiãRHmß?Ïò|Ò2ð’û’¢ý?- ×àI<;Ç$ˆ3 J¤ràß=«ƒ«çØÎØ@ à ñu¥@,ïA&¾ñýÑ?&®‰Ù`æùÓ2KyØA(M{qlÙYî(ÐAOû†+ïš‚þ“g:?½„}ó É}·ÁþJäÚ#f« äCŒÚôG"̆ú e*ÍòkfKuT[š¦)|XæXµ¨ož#c’âðí‹ ”ʸRE»Þ¬B+FŽƒ<öíÓÔ<dèiYâÀœ6´rèI |jÜö٦‹{`‚/"¡·­K¡{V‰¼Ýy‘ȨٳBɽQÝ¡ð)(½Mù >k‘
+xÚµXMsÛ6½ëWðhu(>’˜œWviœVUOªFÆ"r¢4ýï?$‘e‘t<>˜¹oßb ` ™?ly "ÊmËå6d3+XuoÞÝŒpõ Ø}ê_½~¾¦®Å!wˆcÍV5,"ÏÃÖ,œ_\ýzùûl2ÂÐ…Ç€9èâííÝ/å/ÿ]}¸»¾½ùkz9ví‹Ù퇻rx:¹žL'wW“1ÀÃÆžT' ®o›”O7ÓË÷ï/§ãÅìÝh2ÛûR÷#š;òy4_ +4n¿!H¹Ç¬/悘sb­G6£Ù”îF¢ÑŸ£?ö€µ·…i›~ŒzyÄmÐÆ51%Ðs¶\Æ¡C -œƒÐEš(]>ý*Ÿdº< Ï}µ06|\ 0tmÊ
+ˆŸªW3†­Ú …KëÅ»x³ÏM¶9´)wÌSBêÔ>o„Ú‚,Ù¨@€Gç)Ë:_g釡jæ.$Ž Å)ÂäˆpÉÈ„’"ó¶Ñ0±ìSsÛíb}¯˜átÇ×™äîŠ,ë¤u¡íÙ¬è·èG­òãWÏ& XA9&ITŽoE¶LÔ2NX¨Uå¦=ÈŸ*ÉãÍú£PíäˆMúZÈX õèG=±ÖþW •g+¡€–kd|?‘lôKhÈ0êFã D' Wt‚ ’"î“9F~šÚ|̃Êä£è>}ƒ¸™\úQ¹82Ë¡çü5{)ú’ÏU‹d¦EœlD_ÑwA[%jíå~ `>ø"ö¨
+w¼­Æ% wa[M—K “^žîm¬­½mj|{‹¼S©Ü¼*ÉÔ>®Ï.‡”¸mõ™AîºN{mœŠlUq­5²ÜÏpžM¶Ã¦jŸ j£J…„º¼}Ë4è%k íd%ˆC‚k•µ…ëYi Á»Èy%ºÄ…ØöÈÉò¤¼}¶Ë8Ñrµ¡ˆüí®TIf-”Ú§Bè”6Ž ©KìS‚±—¥K!µ9?Ïò|Ò2ð’s Iq8®þ“xvŽ‰e (‘Ê÷¬®žc;`!l´ÿul,äוQr2ùM èþ1qÍ{0ÏŸ–Y*‚ ‚Ä´Ç–å6ý¡ßÓ¾áÁJF»¦ ÿä™öƒO/aDÂe|º·¸ öÂWú£ð5Ø#f+?CŒÚôG2Ȇú “41˯™-Õmiš¦àa™w`Õ¢^¼yŽŒIŠÃ·/‚R*$*ÜõfZ1räù³oŸ¦æ!COËùæ´¡õCOøÁÃPã¶Í6]Þ|J½m]
+•PåE÷“yeº/²$NÂf?%ÿïëê…OAém*ñY˨$é}˜Ê›¼`÷ØäS•<Ê°£ÓQ΂2=ÐZ«¼P
+øÈRÿ¨eêìD!žX™
endobj
-1256 0 obj <<
+1272 0 obj <<
/Type /Page
-/Contents 1257 0 R
-/Resources 1255 0 R
+/Contents 1273 0 R
+/Resources 1271 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1250 0 R
+/Parent 1248 0 R
>> endobj
-1258 0 obj <<
-/D [1256 0 R /XYZ 85.0394 794.5015 null]
+1274 0 obj <<
+/D [1272 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1255 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >>
+1271 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1261 0 obj <<
-/Length 2305
+1277 0 obj <<
+/Length 2423
/Filter /FlateDecode
>>
stream
-xÚ¥]sÛ¸ñÝ¿Bo¥gB„
-¹ˆeÀB‡‹l{æ-Ö°öúŒ[·'rÇT¿Üž=åÇ Éd$¢ÅíjÄ+a^’ðÅmþΉ˜`çÀÁs^¾¹~uõú›‹ó8pn¯Þ\Ÿ»"ôœWWÿ¼$èõÍÅï¿_Üœ»< ¹óòïÿº½¼¡¥ÈòøåêúWÂHz<ÀôæòÕåÍåõËËó·¿]ÞgŸ—{>äóÙ»Þ"‡cÿvæ1_&áâ^<Æ¥‹íYú, |¿Ç”goÏþ=0­š­³öã~$f ð‘E°ŠCÉ"_øÆ€ïÎÝÈóœmQ¹ÒÍÞÕÅV®ê¶KÕü‚ðÀ ÕåœÉ0éןe±«MP±ûˆ/ó{øxOšç….ê*-ÝUSoÝ´ÓZÙ«öcÝ|¬ê“åóÊÒl£žÊ¬I«xäêK‘Y&»To>VioN‡F5Z¸mñÍnCèc»SÙ¸Fgw›îv*wáj[Õìÿ4j¥š˜¬ËÎjóÞ =‚.èñ§}ƒ¿ âúÍõå°…Ÿpv•W­Ûå»ÑÑ)žN Æ'nmêZƒ×JµN1ܺ*÷´Òëõ5+»Ü²ýŸåN-‹ÖFï_½”SÝü¹S;¬×Oµ¼hÓe©Ü´\×M¡7[ë\À´¨&š$/&‡:F[Ýÿ:%k(@U…*üÀ ø “¬TiUTk·¨´j¾¤åüžþ|Âde¡*ݺ;Õ¸Æ7§–³ûÉûTNGÇjÁ«\¼ªHçCîiõUÿÙ¤w˜T'óSÛÞ»-X¸W⇪mÏêJ§™>mÿŒøou¥Ú›ÙÀ?p$<B?Vi¿©¦v«ÚmëÔÕº|ªBGlNm!®ð™ä^0å Ù‹Ï_ ¾Ð+r–Á0ñ¦˜Õ;,Y-M)ouªÕ¢^Uï=OT¦Á´éZYQþhb
-p‹)/qN„fÏé'ÂÔ
-Õ˜êáB5P¡ÔOjï>X¬8YKï‰f¤OŠ•°úSñÿÙ˜Ôæp׃yFM*Xžtò=¤G‘Ñb·ËSSv
-ÂÌ’»êªŒ>½z?Þ
-9ÑÄT.=*ÒÆÂø–Q ê38ºˆš3‚ú°Ÿš³mME¿º"—ÌÔaÄÀÙ[‚HÈçNµÐÁÉiº0LøS§™ë·%VÀž×oߺ·o¯^Ú”®³ºÄÛ”ÎËC .íf{…ä?T³¤2^·´Òc¤+]…¹5\û’%}@4Ý:Éc“Í|O(ìõÇ<è,Gj`}nŠ*+vær Ö̸BR9˜‘ÙPå³Ï]Ñ·J¤ÒâÛ­÷Oî`í ¿¥ÓIÝñ½TøM©,÷Èä£çJgÏ?5Ë'.ç
-*\˜ £¤‰Ø¹î%¸~õ—€F¶À×mf
-Cˆu3 qþßê½Õ3™|…HX¾›Wíó™Óô_YìMÙX™Ù¤÷OÇ,ö’¾£`sšÄ¹=—©I3hÓ~²ØŽ®O} ?›)®A¢0îk«©êá7¢?ÞaH˶žp_gý.£þ˜4S`¼á ÓOÿfuøA›G’ˆùJ%bðXL¬Rx® º_¤í[÷Uÿ?ž<G1endstream
+xÚ¥]s›HòÝ¿Bo‡«afø¬<y'ç½[çÎÖÖ=$©‚‘DƒåvÿûuO$ì•û¦§§»§¿±™ ÿlæNóxÆžã»ÌŸ¥›3w¶‚µ÷gÌÐØ‘=¤úe~öúg±<˜Í—^‘ãF›Í³Vàpç8¸Ö凛w×�8=k~ýáæÜæ¾k½»þçAïo/~ûíâöÜf‘Ϭ˿_ük~uKKáñËõÍ[ÂÄôx„éíÕ»«Û«›Ë«óÏó_Ï®æýY†çe®Àƒ|;ûøÙepì_Ï\GÄ‘?{€×aqÌg›3ÏŽï ÑaŠ³»³÷ «zë¤ý˜ëpð zl`ÀÈuX…~ì‚ mÀçvàºÖ&/íZªzg«|# W¶›…¬ ~CÏx`j3æľÏG,’ï?Ëb[ÕŠ |û_¦÷°áž$Ër•WeRØ˺ÚØI«Ö´²“Í—ªþRV'Ë?ä•&éZ¾”Y”ðÈä}ž&ÛD­¿”IgN‡FÕZØMþÃlCèK³•é3\£Òµ½I¶[™ÙpÈZ6lvŠj¹”u LVEk´ùäú.AôøüÁßqóáæªßÂN8»ÌÊÆn³íàèO'ã ·ÖU¥Àk…\% vU;ZéôúžmfØþÏp§yc¢÷ÏNÊ©nþÖÊzWT«—ÆZ–7É¢vR¬ª:Wëq.`’—#M{’7£C¢îž’5 ²Džq6Á$-dRæåÊÎK%ëû¤xß“ŸO˜´Èe©{+k[ûæÔrvœ¼/åtp¬̱ÌÁÅ˪†tÞçž’ßÕuò€Iu2?¹ÙªÝ€…;%žU•h{Z•*IÕiû'Äÿ¨JÙ<?l&Ï‘ð=¯Òþue—•ÝT‰­TñR…ØœÚBl.œ˜¹Þ˜'d,¾~ÇÙ¬G/Q°ÏœÈóú ˆ0Õ¸À¬ÚbÉjhJ¹S‰’ˆ>z}+?¹./uƒ# 4(~o’•4¢Ä`b
+DýEiHKM’ES­2´8]bÉCsbtÈë8JIQjüÉ ×Ý`êäAáQ 0ù*KB% =é,ð½ïˆ*ZQ:ÚŸËÓGŠ™1Rt‘ƒ @;5a º›ªQiÓ€ñÌBÕªmk–èPM÷â»ÒY9”8£ÑA'@ãeNÝ–9÷0¸xr“cÔl9¸E——°;'B“ç×5
+–[ÙÒ#Oi±Ýf‰.;
+b§hä{Žû±!(BRtF³”2“ÙTëÑ[c—m™Ò—Ê\í†bkÑæ4}£”ÑÙgv8½8°\'Ú`Þ|,% ¢˜ÀÓ)1 z"%:*=6`ï[5M²Íí´†S—*‡àazø`âØóŸÖ£§šPdÔ 4”‘&z¾`±K=M[ßR*ÊbG·' Ñ,ƒ Úï§YFÃ¦í Œ©‘KªÛb¨Ö!DB¾µ²‡œ¹Ì^b\Jõm—™†ÉaÏû»;{~wýžÐ& T•V^†ãغÜ÷¨Âl67^@þCÖ jÄUCk>=ºRk`&Öpí>É ú~ƒhú °×)>4ÙD«ËMAÇ©Ø‹Õðñ£s^¦ùV
+:Ük©Ò×_ë…]H%‹©‚
+Ëc^߈쀇ÖM'’ »C4°¾vh=‚iB¬›¾ÝwC¨Oœ{FÏhôÑ&r¼ÐFlV6¯§Ú©ù(e>,h+;æ›òñIÂРݨ«Æ(XŸ&²æç1·*Ò Å´ˆ|'^0ê.†_MW/r?ìj«®êào]¼;ž•0(Š¦h¤rû&cüím¢À¸ý¹Ÿþ‰oÿû'6(âÓ•Š‡à±˜¥ð\^t\¤ÍoǪÿ­!–5endstream
endobj
-1260 0 obj <<
+1276 0 obj <<
/Type /Page
-/Contents 1261 0 R
-/Resources 1259 0 R
+/Contents 1277 0 R
+/Resources 1275 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1250 0 R
+/Parent 1248 0 R
>> endobj
-1262 0 obj <<
-/D [1260 0 R /XYZ 56.6929 794.5015 null]
+1278 0 obj <<
+/D [1276 0 R /XYZ 56.6929 794.5015 null]
>> endobj
350 0 obj <<
-/D [1260 0 R /XYZ 56.6929 418.3076 null]
+/D [1276 0 R /XYZ 56.6929 418.3076 null]
>> endobj
-1263 0 obj <<
-/D [1260 0 R /XYZ 56.6929 386.0953 null]
+1279 0 obj <<
+/D [1276 0 R /XYZ 56.6929 386.0953 null]
>> endobj
-1259 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F48 950 0 R >>
+1275 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1266 0 obj <<
-/Length 3835
+1282 0 obj <<
+/Length 3842
/Filter /FlateDecode
>>
stream
-xÚµZÝsÛ¸÷_á·ÊÓˆ!
-ÒÆÕr„´6MtÄJ*§e)Æ´l¹PËÝ×òeZ4›¼ª‡+‘
-„—þ¨G²-ÓˆlåÉQ%Âg«òjªt:á ˜v¾Ý^‰IYeA„®á§å®óMÙR³Yâ3™äë5ÚU¾»éÄ~ ËcÖDz.wyGÉä¹êV¸â’””°a «33üûí¿™Ë_ŽL!“Œ™ðÏUi—€ŸÀž¥I„QZA¦µ4Ü‹uUÖØeOhªßöeÛµHÑôé`N‰"¦¯L) Â$¶Lå÷Å*¯Ë7`Óa<©XÞ&¡F³#qŽP7ÌÒnËEµ|¡n£r¤e[9½~ØâYÒXñt~%„@½ÈLLî–DÞÒ
-ãrãæq¼!Xn¥
-bÂÖ-£èY7yÁ;Äv?_W þ .˜¸«žHu@eUAkiTšr«Ò
-è(¶)ø
-(5ªBOžˆoûjG!l gdÉìÃPý/óŠ[™dbï–¼Sl¯p÷°wŽÅƒe-¿¯ò}Û™ªU%|$—ØÐaìÄ–!À{ˆ Þ¦®÷,iê¨( "<æãØŸ·ü«ƒ¨“Qd‘ïY¬ÐAE$‡ªù 3ÚWeVQÖÿQŠ¡PeTs›–»¢G=„™Í Ã’]b®üj‹;ƒe$a µ-b\†
-a7ÈÔðh ÍÈZWëh[äö §4×
-ÂH&úó˜]!jØaÈ—+*…p±½fcX”*ü€nrnŠ›ÐŸ¸!V<Èìç›–ØQÅ]³%òº|*×ü¹ù©NËÙ3åX_P²²÷8 ?B ìÉäø!ˆÌ­Mm}s+¿/Öû‚÷}&°IPÂÖ…‚øñ@å?`Uò‚;×ò;¸âѱÁœ{7yQö{¼X
+xÚµZ_sÛ6÷§ðÛÉsC
+@_ÌsëzH*bkÝvÓkÓ6óêkÝõÖ0‘±Û?†Êgëú÷Š ÃMoà=¿J™Er¡ÁÏ€!5¢çÈ^2Ê1Ó¹kîGœ‡CNÄ} L¨ü Ùm9Gˆcã°MF:ë8»?:²L»˜‡+ÇP,br0—¿´{j°Ð˾«›'Nö÷÷óÅýí‡oèµ_Õµž‹]]<¬ù‹Í [L)«_ãX6UÎÆ©Ž£<Ó¯¤ìëtÊö\‡Y¡Çû¬²(N“ó¢Ó„èaÆ–Q e(Ûfl Ñõº~D¢ªùwÕz½±öìB1²ì;Œ;Hz`Jï¾vÞ‚˜Þ‘æò3QÃÐ…½”ÇeΉÛòPôîœ4ÚÔܸ
+!tS¶U:Js˜Û0^€Ö[½1ÖØÌ¿´»ß½³” –}»óÞºFñ[.ƒ‰Q²ÂM§òœãh
+¤•Ç8éu:O£4ɲó^rö:Ïe¡B±\UsÒÖ‘ßÁ¦§ƒ/&ÏqMˆx˜m*ãl(áC“{ZàeÕðÑoRÛ¬{sݲÖÚÞE¿3ÚK¡PzE{×í9.Æ÷›íIåå‘I_‘í˜&dU—D&‘#á ‡‡¶E¿rp)=†K<¿xUHÄUt£Ê¢/ŠÎ}Ö2À¢Z
+¬-­%JW5ü}W?5źóÝ yjLJ/Òè™ÍYMC¸Â$3´Û:Àfè—"™ÝÓ‘²N fˆD™†:"[¬ ÊÝÉÊ[
+èN‡PÌËÑó!4à:B—ÅQÕr¿ÃÚñT Mt9&=?Ï51…A<€bZ©Ñ(Ýj¦[ÍV ÏþJ̇·Yíü@ëCÆ…6CÔAÿç=¨ïêÊw=µ‚c==ÐkÓ¯_ˆÄõ)ˆHÙRlÄcI3´‡ÚµÙ·u›Íx“Ÿ'Юˆ¡€NR—‚0×oÔô)¡ÎÂSÂÿÒ5hpnNUêÏO6¤©ÈdòùN¶ç²8èU$‰'<1lÜÙ)x®‰9 Ï‹R€ì©N‚2]œ„Þ,FˆÙD‘àó´=Ñcà,¶[Hgw˜Ñ~ÑÒ“«.`W]SÉO[uë¾›N\s<'KâQÀ#{T)Mb
+& ¤® ßk®ø !üvˆTlЯ¨ë€TRuÂAÓ"CK<5À÷*Ë|>hHKSãƒì Â
+v©öqäp‡@vÈeÕ-wõC%F+5 ‹JJ0¶”®C©s÷tIOízþyøÁ±í‹ó¿‡×mã. “ŠÑ£ÚV@Çb0£#ò\¯Ìãx´ó¡#N#€mœ×™Ðá¸,Hkéîk-°2Ò&=/ÕsMˆU£³T£ ÐÈåhaf?_ÿôfñî'z±³ ýýæ‚«$ qˆaG¬öp Il»UýlS’,n£O›ÒS¯ïîéSFÙ}»l×,kWø3ã%â5@ŒÎøøb:²ü ›dlÝf¦æ%%ýI^6k·ÎÀÌÌÑðºƒÒ/–:=߃cŸ÷§çx)Ngƒ·TX7bð—™ë%}bŸ½z""`‚ÆÍÓ®+_‚°a:u§¶‡k—ê—íf³oê%I»\?
+ÑR‡3,Ò$nƃÕ=·»zSìê5“›ª*ݨ|µo7èþæÃ>øÌŒn£Û-ÞÝ€1ÛKX!gÝ~¹BçóèèiïKl Ü©é
+\;ºe„€7x½/ûmi-Û„¨”­˜ù?PuèŽ:g§²œ[X¹Kýù”AÛì‹\Â¥CÉ×l`б "ÂÁ z÷+öí˪¶‹…,È
+Î"°½ÂÝÃÞ,!kõuUì»ÞÖ®*ヹ̅†ìig®ÞClÌð–u½gI“PG%Y”àÙ0ÊÀþ¼á_#L@%‰C^¼{d±BGy’ŒªäƒÎh_e’;m$ùðÇ*–BÕ~’Såm[þêõç.'Œ w‰¹nôkŠ ‘Å‘Ö®”ñ¤õÅﶂƒfeÓÑ#
+=]ý‹Š)åù$rNžË"]õXívU9BK<Ê1âBs^¾çš˜À0 èÈ%†3 Cm9v™Ü_ùªÙ Â7½ýË–/‚ÑÂßý¤DÎÞÂ6f º3-wÁ¬fÕO¯JG ÎlpÐõD^ Dúщ<Ì¥(KŽ§v£\ÈÐŒœuu!€v@áŽ{*{à  ÛBd«¸t_œªË‡Äá vÖGg£t‡ ¤-[oèøîãÝ ªç´™ ¨Ù“ü53 ¸Î˜™ã²>߶=xüºz²~6·—´ccËL¤³ÌœŸ…皘ÆÀØŒ‚0’‹á<WˆvXò‹2Î!¶7l ËjC…ÐmÎ5¸ É[b̓,~¸îˆUÜ·["¯«çjÍŸÛŸðtœ= Ç
+ü‚’•»ÍÉ øjdO6ÇAdáljš[õu¹Þ—¼ßè3‘O‚RI·×÷Tþ£Ö øs0|©¾‚+<pï¦(«aƒ—  ›/Õá‡wØóÂg^“|Bê„–Ç2™šÝ3v:Lr¿T9t\ŽÁr$¢-Â"´"ìí¨£ WP[ÅYƲ·D>Þt‡—2:¤8L$*ø¨Cڹà çÛ‡2¹û×õÇßÞÞ„.ôðö¹.]:á8òîîí7'ÂCYwËö¹d!—Ò|¢é–¸YGøcí Ÿ„¼/ú7á‡ÌðQÆœpn,šÌ37)Ta’g®„
+#³‰©ÿîÑbendstream
endobj
-1265 0 obj <<
+1281 0 obj <<
/Type /Page
-/Contents 1266 0 R
-/Resources 1264 0 R
+/Contents 1282 0 R
+/Resources 1280 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1250 0 R
-/Annots [ 1268 0 R ]
+/Parent 1285 0 R
+/Annots [ 1284 0 R ]
>> endobj
-1268 0 obj <<
+1284 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [250.9056 343.4991 314.5963 352.9087]
+/Rect [250.9056 335.8063 314.5963 345.2159]
/Subtype /Link
/A << /S /GoTo /D (statsfile) >>
>> endobj
-1267 0 obj <<
-/D [1265 0 R /XYZ 85.0394 794.5015 null]
+1283 0 obj <<
+/D [1281 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1264 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1280 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1272 0 obj <<
+1289 0 obj <<
/Length 3458
/Filter /FlateDecode
>>
@@ -4758,67 +4834,69 @@ xÚ¥]sÛ6òÝ¿Âs/•g" Aœ>¹±“K¯qîlçz¶´YœP¤*Rv|7÷ßo»€@‰R’¹ñŒ ,‹Åb±_<ð'ÏÓ,ÊŠ¸8
o ]‘T&
H™”ØóH­«Í]ÙçÌÛEÿÌä^ˆVÁ ³äœ³1û‘É.|éýÀˆÔðUHëäÔõh€Ž5´øÂ=°NÜs‡eíA70>m›©ù\õ‡I*šÛBæÁc01¬ƒØz‰rÁ50,Á®Ù[a&OÎØ@ÅC»CM(¨Ý-5MÃ5WöeWòqx¶fÕR­QBòR~r‹3uƒ-=HZˆj#ü„Œ‡*Åï•'µ|­÷êá~(„JwOn¶m6ÀÖj•µêƒÔ`± —:­!Öq}ðXÖ™fª®¯f‡%10‚™*ŠÓË{¬‘õª'Q–€D ü‚O¾*ù)òƒ'k ºo¶ïŽ›Kž‚A‡=ÿBíE!0øð2F
é"s1À@S&7ÄÏ+wum
-)­¸}\ö4àæãû1~Å¢pÑç@|ôX5pçqCˆ<£á 런Ţ7Ž]Ùr›W–ü‚#›~,¯1Œ3ëí#±ÂDŠ/+1 [–/¿µ"Ä>ŒYt[Î’)>´Î` ×|¤{–ÌÃ(¾ÇHÐ
+)­¸}\ö4àæãû1~Å¢pÑç@|ôX5pçqCˆ<£á 런Ţ7Ž]Ùr›W–ü‚#›~,¯1Œ3ëí#±ÂDŠ/+1 [–/¿µ"Ä>ŒYt[Î’)>´Î` ×|¤{–ÌÃ(¾ÇHÐ
endobj
-1271 0 obj <<
+1288 0 obj <<
/Type /Page
-/Contents 1272 0 R
-/Resources 1270 0 R
+/Contents 1289 0 R
+/Resources 1287 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1250 0 R
+/Parent 1285 0 R
>> endobj
-1273 0 obj <<
-/D [1271 0 R /XYZ 56.6929 794.5015 null]
+1290 0 obj <<
+/D [1288 0 R /XYZ 56.6929 794.5015 null]
>> endobj
354 0 obj <<
-/D [1271 0 R /XYZ 56.6929 333.8409 null]
+/D [1288 0 R /XYZ 56.6929 333.8409 null]
>> endobj
-1070 0 obj <<
-/D [1271 0 R /XYZ 56.6929 308.7186 null]
+1075 0 obj <<
+/D [1288 0 R /XYZ 56.6929 308.7186 null]
>> endobj
-1270 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F48 950 0 R >>
+1287 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1276 0 obj <<
+1293 0 obj <<
/Length 3312
/Filter /FlateDecode
>>
stream
-xÚÍ]sã¶ñÝ¿Bo•fŽ ñE—‹}u¦çkg:i’Z¢,6©ˆ”}î¯ï.° A‰’®éÍôÆãá
-\»‹ýØ$?6Ñ*N„‘“ÌÈX%LM曫dòïÞ_1‰<Rb}ûpõÍÈ&&6)O'Ë`.'Z³ÉÃâ—黿¾ýûÃõý,â*™¦ñ,Ri2ýööî;7bÜãÝÇ»›Û÷?Ý¿erúpûñÎ ß_ß\ß_ß½»žEL+ßsšáÄ7·»vÐûû·>¼½ŸýöðýÕõCÇKÈ/K2òÇÕ/¿%“°ýýU £Õä~$13†O6WR‰XI!üÈúêÇ«º ƒ·öÓ1ù)¡c¥y6"@.²`™N2eâTÀ+àír ­¦íªpÀ¿ëŠ ²qÏÜ=6yÓ»éÍ,’Ìà‡ÕÁM±{ö˜/åzíG«…ƒê};˜ùîãÃíÍÏÞ͘ž싆pÚšpý<ý2ëü¹hp @c±QŠ[¦~MT²(–ù~ÝÈ`SS™LV–#e¦ÍªÞ¯‘ØêvW>=Yjñ‡
-Yl×½ñ”“à mÈJž9>X·¯0Rïܳi÷ýWoTd€ƒ9½"ì ÐNºæÌ«i>pÃOûuN_ýʹì)Ûo ¿vÏEÞˆA¸ ân‚hL—´æŠ49ͦ`Þ»²hÜ¿êjýê m±[Ö»ûDôBœÚ±‘-ãŒÇ~Ð>¬Š|×>y•x®g°âã­Ó2N¯ ŧmIÔºuJZ/_,J² \½vOôhh´Ý)ú^>TúPÓ×ÖĤݸ)+ë]¸ UžÐ(@£ sUÏhvôÕ=÷ ôÍÔ¡6gYÌSyÙ2 è,|™„&‹»ÍA¹nØ9n€7 UùSѼ]—†Ð®î”<ygF¤C¹mó¦¿3fk*æB±
-eÒÑ%YO {ºÜ«l;0ÿÒùoxYòYŸƒ©Sb‡@
-<Æ+|+¥½JíàSü옑#ÎyÈ3Ç4â˜' á#Òp‚;±±Ç,×vF'£“w†‰?œ¹!4nnBbÞaÔcnQ÷Ñ€éÀðÞPÜñNy \¥b­¡Ï(‰Œ…ÙPIpÚíŠ2‹²É×E/ÖÞNÉààP¬ñaâÇ8p“6IÁŸ•ú‰ÌÄš)3LýþÜWž 螤À}—À\ú­NuLEiÂÀMfüDbÉuÌ3˜'M ÿ4Ây³¤M6p€ô6õÂ&mR—´H˜pŠ¡&Àb™ÈŽ°z—î xäXppð!ÿ›TPþ’AfÐið4˜Fœ¨@ÎlLÎÊpÈàuJÞtÄ
-lD¹Î
-, äkV/¨Æ™NÕ%)ì™`€‹*vÎJ¾fA2Ä—ñZ³Ì\ˆê'öYî+ äk¶H•d–^ôÿ‚Ç:¥ª²é?/¶³†ô¥äÖ·²þ 3Y (JÀIZÐS;ê­ üƒë‹¤'¨™>ßZ“¸´Ô¿©Û®ËÒg)}öÖ†‡Y{Ø ¦œx‰HËbÞží‚p(‘  öNyر^ÀÖê,Óa×bÐËñ(Í —ÖÀ›9Ñ»%¤(Ä:Ö\ßí°lc ÿ½ˆJ,9ŽÒ6&tÌR“_¼ÃY}˜ ³Tl¸ú-óQ³XË©ÆÒÃHØ-+ylTn©è‡·E…å½hÊÍ~·n«|O±êǦ^vßaø»»à˜´íë–ÞÞþðÓõý RÙŸgŒ1Ø€=jj¨@1Zâ ^ª
-×ßÁ:¦ö5L0Ÿë¨‘uuzo“4fI’^ØÛ
-¹ÑÙµ;¬‘Å[+liÈ ®î:½<Õýb3ÇÑaS3N`˜ía@í)µð=Œ€A¨Ž’Y$TøBa÷Þ~3Ï÷Õ XƒZoYЫÓÔXÒÓ¼m‹Í¶ »MÚ­H½¦4‹µ0Cp´p£©`jê½æƒÑymŸØÀAìCãsQ.ª¿¼r}G€¨áм®šv7ÓÓýœ´Þx
-oó]ÞÒ°Û—QëØ}e^ó}»ŠªO‹z“—cÁ•A‚}p 2N6ObÉ;»;w çcén9ç Y¦SlLXP!u²:Õ"“Rù^r ñ­È'’CÁJqÁñ‡X§²Ã²û^7mÔ´§5m9?6J f¤Syž€k„‚¡QÂV¤Y6$Áf@ŠÑѦŠùT —þR€ü½(¶äv³iÀƒEZÚSKüôÙ%¿
-̦i,2¡‡$ÐŽ™ Ÿ°‹&õ±
-†JzE® íP¬®ånàè”ýZ,Ê_Œêð}'Eubp˜ïîÞ~¸vÆU’äXM…:vlp\8ê8Ÿ>—µëê¹a«QÜßå‚×täx[ ì,§9¬ t)¼¯CT/ù`¡|ý’¿6~Ž]éÊ0|STËšzJÍÁª=KÉ!/zºï2ÇǺ] Ó1­a(¸y‡Ú5m¯ ÙrNÑj‹—ÏšøÔÍ[¡b¼.;¢EÉäâ×çÞÊí¯,C‰(´>q/B$¸É<Q(iŽÎZüõÝcÒÿ±.ÿÞendstream
+xÚÍ]sã¶ñÝ¿Âo•gŽ $ðx¹ØWgz¾Æq¦“&y %Êb#‘ŠHÙçþúîb(QÒ5½™Þx<\K`w±ß€¸LàO\'ʦ—¹Mc}9]]$—Oðîý…`œÈ#E!Ö·ßܨüÒÆ6“ÙåÃ<˜Ëĉ1âòaöËäÝ_ßþýáúþ*’:™dñU¤³dòííÝw4béñîãÝÍíûŸîß^åéäáöã ß_ß\ß_ß½»¾Š„Ѿ—<ÑnnÿvMÐûû·>¼½¿úíáû‹ë‡ž—_‘(dä‹_~K.gÀö÷I¬¬Ñ—/ð#‰…µòru‘jëT)?²¼øñâ‡~Âà­ûtL~Z™X™Pª@€"8Í.smãLÁ+àíü*RFOºEIÀ¿›š¡ª¥gAUÑvåf‡ôæ*J…Åë½)Úróì1_ªåÒÖ3‚šm7˜ùîãÃíÍÏo®„™”lË–qº†qý<»e–ÅsÙâ€"!b«µtLýšèdV΋í²PÀ¦fi2yX8Ž´´‹f»Db`«»Mõôä¨Ånn
+
+Ð˱¹b¥óÔã,Û&::_jc©ÓœqcÇ}$-¬’RÈc«¤éíMf’
+s\»IFG?î ¹!4nn*żÃêÿÆÜ¢þ£Óá½á¸ãò@¸ZÇÆXË+žP’4VJåC%Áiÿµm9Ê̪¶x\–}¼XwvH‡b÷?!›D‰Ë |PñY©ŸÊml„¶ÃÔïÏ}å ‚îQ
+è»æbÐoÅpª¨g*Ên2—GKib™Ã<Yù§UäÍf6¹ÀÒ[53—´¥ú´¤U")R„štKä*?ÀÚ¹´p_À#ÇJ‚ƒ9øߤ‚òOd½AAƒiĉä,Æ䬭„ ÞdìMG @@ý!¼þï¥Ã·KHŸ_Q÷ ,†3DFÅSÊ/ ìk„¹ÄfæœüLgF¥N:¯TCì *©|—ÒõÚ ?V@Æ—•Öµjiˆö &g¤•™8—FΆQ®“ (ùšÕ ªqa2}N`{®Ä™ଊ2Ç€’¯Y` I%Ô9A¼6"·g¢ú}–û
+ùš-RB%™ggý¿’±É¸jàlúÏ‹í¤a})¹íZYÿIØ< %à¤-è©ôÖ”
+v†ûÄ‚Ãûb×LpÀÁÉШ!UÝQƒQò›q†!Öqƒé±¨FKÔ¶]DØtm£¦ŽÚŶ›5/õ>%B³L¥=MJ5BË €ÙH@ó:ÓQŠ[b
+rÑbUöç:ð¢üTu-½šmKc +«g:ç€w?Þ¾¸¾ÿð†˜IzÕðL³†WÀ0b9U·@_näP1Šú•Ã&w`÷86UW¶û‡\÷5ÒóÇ.©Pi_7ŸØ“}÷ LœÙT첬‘¢œY8pUbâ4ÍÏ8åë„Žy,ס+€‹å,š.«²î’>‘±Å„à$=Öf¡‚ìJ Ià3¸<ë=3Â/VWbRƒ‹bMê\ÏÇWëe¹¢]¿øK2h„0z§ '8?çSÝô~a‘×ýÏ-3y¸² š¤{)TñÓòîQß}×u
+¯‹MÑñ0í˨u¤Ø}^‹m·ˆêO³fUTcÁU@‚½w 2N¶LâTövwê@ÎÇÒÍ|*A³"L§Ä˜° Bêeu¬E–¦Ú÷’+ˆoe1;j”
+î,UgˆuÜ({,·ïMÛEmyZÛUÓC£LÁŒL–ž& Ç¡`h”°YžIpAtt©°>ˆÒ_¿—åšÝ®à#`1 xpHswj‰Ÿ>Sò 2;,‰ÄîC Oås"€ÝaB1å#ò(•q"E¾wfRu ööw¾X¸ 7Pä
+)DeØßUE¡;Å”bC?
+zt›¢nAÀo÷¤.>wZ"EjO#%©
+awÂKªÜ-HÊqfHõ©SbX8*é G%|áØÒ83¨\´ð“Y4ìïVT»ŠPÑÍ”2~r6†žfY>¹~ˆS}¥Á¬ð·«v•ÊŠî,JWÅkjø†×þ­*¾ÈRÔÓrx_jw{‹6ýÌÙre 8ìA%:ý5‡€zÑŸ'œ0»
+ò0Ò‰XY©OÐcP0`6Ëb•+3$wÌý<€)BØÌÇ*ªø»z€ ¡8]·šnà1HÎ~ç/V÷ø¾“¢{1æ»»·®ÉX JJ%VS¡ŽœTD”“窡® ;’þ. PÓQâm1°³‚çp6Чxð¼OP¿ƒ…ŠåKñÚú96•aø¦¬ç ÷”Ú½Uw,%û¼˜É¶Ï›n1LÇüµR„¡à–=jß´™½‚d«)G«5^>kãc7o•Žñºìˆ%—g¸>÷VîîÊ2”ˆÊ˜#÷"T1@ÚÜ…âÐâà¬Å_ß=$ý?¯ûÿ×endstream
endobj
-1275 0 obj <<
+1292 0 obj <<
/Type /Page
-/Contents 1276 0 R
-/Resources 1274 0 R
+/Contents 1293 0 R
+/Resources 1291 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1280 0 R
+/Parent 1285 0 R
>> endobj
-1277 0 obj <<
-/D [1275 0 R /XYZ 85.0394 794.5015 null]
+1294 0 obj <<
+/D [1292 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1278 0 obj <<
-/D [1275 0 R /XYZ 85.0394 625.316 null]
+1295 0 obj <<
+/D [1292 0 R /XYZ 85.0394 625.316 null]
>> endobj
-1279 0 obj <<
-/D [1275 0 R /XYZ 85.0394 613.3608 null]
+1296 0 obj <<
+/D [1292 0 R /XYZ 85.0394 613.3608 null]
>> endobj
-1274 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F39 895 0 R >>
+1291 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1283 0 obj <<
+1299 0 obj <<
/Length 3798
/Filter /FlateDecode
>>
@@ -4843,1011 +4921,1010 @@ tc .¦>ÆÍã:}Í¢­£ø]zX\‰e­î´,¢Ó–Éü²¡Ÿ«ÝjICÒjéœÇ\äèÒ·/ôŠÞ —›Ýv>¹Ç“¿Ëeà(ž 
ÐìËë:ß–s©î' 1¿%õŸ2ÅdŸª Í"DBÓÛè1û‹ð'¶<ÆûZ Ô‚ Û=«I ŒP'Øc;®kJ2Ã!ÿ9®k¨#º¡¨ìo¦uC= ÐÇ©·Päûº¦™õÖÕ¥ÿ÷èÚpC]olÖ5ë
)6Û"k9UGY½¨7Y>þ±¡L! JÅq6Z¨ >zJ§43’›>#¡ Å>€ñs&ÃÏ8t¸…™Ð*€‘£‡/àù”}-ÂŒ×_Í÷•+N†Ë©†^ól»-éò_‹þ-¼caú›”šXè^¼†àÇyû3¢ ƒÐ,+Œö0õ#欉Nø¥
%óô =ï*ì“ã(p £Cç/,µ_yþë©ßLA–leçüãv–q?oÃÌ!6¬aʶåìkµ°¿“®þMûðj«±l†M†uñ¼*ד?çëuûrüñl±|/–ƒ 4Õo,ÖU¸g‡~ª¯ Íâ¡ ãmOþ/ÿŒÿ´eÊ9y8i§Td
-åcø8
-p&±÷4fýÿK€ä?endstream
+åcä8
+p&±÷4fýÿKØäAendstream
endobj
-1282 0 obj <<
+1298 0 obj <<
/Type /Page
-/Contents 1283 0 R
-/Resources 1281 0 R
+/Contents 1299 0 R
+/Resources 1297 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1280 0 R
-/Annots [ 1285 0 R 1286 0 R 1287 0 R 1288 0 R 1289 0 R 1290 0 R ]
+/Parent 1285 0 R
+/Annots [ 1301 0 R 1302 0 R 1303 0 R 1304 0 R 1305 0 R 1306 0 R ]
>> endobj
-1285 0 obj <<
+1301 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [154.2681 743.8714 203.5396 755.9311]
/Subtype /Link
/A << /S /GoTo /D (notify) >>
>> endobj
-1286 0 obj <<
+1302 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [80.6033 237.2629 144.294 246.4782]
/Subtype /Link
/A << /S /GoTo /D (statsfile) >>
>> endobj
-1287 0 obj <<
+1303 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [265.4578 191.3384 326.6578 203.3981]
/Subtype /Link
/A << /S /GoTo /D (server_statement_definition_and_usage) >>
>> endobj
-1288 0 obj <<
+1304 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [367.5441 191.3384 416.2908 203.3981]
/Subtype /Link
/A << /S /GoTo /D (incremental_zone_transfers) >>
>> endobj
-1289 0 obj <<
+1305 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [280.9692 160.0192 342.1692 172.0789]
/Subtype /Link
/A << /S /GoTo /D (server_statement_definition_and_usage) >>
>> endobj
-1290 0 obj <<
+1306 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [277.6219 128.7 338.8219 140.7596]
/Subtype /Link
/A << /S /GoTo /D (server_statement_definition_and_usage) >>
>> endobj
-1284 0 obj <<
-/D [1282 0 R /XYZ 56.6929 794.5015 null]
+1300 0 obj <<
+/D [1298 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1281 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F62 1060 0 R /F39 895 0 R /F14 737 0 R >>
-/XObject << /Im2 1049 0 R >>
+1297 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F62 1065 0 R /F39 900 0 R /F14 741 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1294 0 obj <<
-/Length 3853
-/Filter /FlateDecode
->>
-stream
-xÚ¥Ërã6òî¯ðm媈!
-ækYá… oßýã†[?|¼þé§ëWÜþxqsÎ2=¯Š äÏ‹ßþˆ/·pì/âȹ½|„N©¢Ð—‡‹ÄšÈ&ÆxH}ñéâŸaÁÉ(M]â_bóÈê$½\r¢s³Ìå8Š-pm%*Š3£—µZâ²ÇB.—ÛmÕWmSÖëÝ©=¬Ë¡ßÃŒ8Ú”›½;g‹Î³(Ö±¾œîýŒÂ€µ@¢™¨ űJç4Þî]ç®Ö@ûª="Ew6mÓŸ®T¾jk˜U¿´;·/ªö$“vü-ùÂÛSÕ—}õ@º!­F+ÖòÆ;=8X$Ññêqïl)X¦{t§ª¹ç?è¸ÎcU›=7'#yd[ö%ð8Iͪ=[=^íÚºnÃêoÞ_ÿtã÷ݱ±'’õä{ÆÀÛì˪颀Âc Æú•60J¯îÚ~Ï-â |{á¯Rþ¼$æ:ît®ì×ÿöm’O.Neq¤MŒŽ»=?i~»
-°œßcó…Á¢[·+‡º˜’½á°Ü`ÂËO ©„¼;G\bl¼¢V¦íX02>¬åž élÎÀ©0¬uRÐý0C‘Æ’µ.·Íïq¬ï‡°!ŽW 0†ÆéPbñÁ3}s62•iÎŒ„@ž
-ÖcÕ¹ zô=²<T|W
-¢8[y8’¼ëôb‡Ð­"ŠUÄfÙ}k¯ÔJf£ËÃïOÿâ¯Hvë×Úù­öm׋mŸÆ Ú˜(Ë‹Lìö®m#!*Ú€Â?·óy¥©É_('ÁÅ]ˆ¸ïsZöÁ㉠X ¡5öÌ´i,КDE®ÙÆñJÅü=”UHo\¿@º2
-âÔÔÓŽ»ýzÕ´§CY×ÄíØ‚®T¤¦cÀüTD?r-ø|ñêþØßaO´êœõÜjæ½êŒ~aŽM£ÌBl93+ËgƒµâñZDU ß3ÙTø>ººF6@‚ˆ ÏMûØÌ=É(¸Šáí„"ƒú$Ë3 ¦í¹Q…922* IŒØ3|r}¦‰írf(ˆÑ©ƒ –Wf¡p¦#“s˜M»$ I¤HXe[uèu:Þ@l¬>šãlà¦>¸ŽaÁ¾!… ¹p‚N­«feÄ™­€±¢)¹bCžF©^`Û–1^©Ä„qÔqÇûë%Ûããmc&ñ tÆxÐ ½kHR°GdccèÂ8~çÁ6Ø%·æ³ãøIô¢–½(By¢™a–Y=TîqãNÎ~Ý÷îpìñ„Ú²Q×)®Ø»Cz.*N¢Ì˜×…ÂDyìËc…ò.«—àHeãÛT»'×…] ééÉm†SÇ,²¸)ä€Üû\oyS³qK¾u€!›0 ºoÚ ÌÑ£™—…ãöX±VبÛ{ˆ?,O Ç
-Ð9€õ+ïÝbâñé5n$y”«ÔgË 'Dºú…ÛPY¤RåÍc¹h²æØXO56ñZ fY¢%¶žŒÌvë©ñ˱^&¢— ȬšœT¤6*²|ÎFÖW“"ëÚÏÃuÈB˜†ò‚P–lqÄŠƒˆÉ9 €1.B çH©×_,[€QLMzJ© U²úÐ &RÐ’#$bLSSxý%¥ZRCŽ]DÒ(L#íi¼ó<”öIÍ ¿%B–ÄèûÝà–¬g¶ägØñ4åA<J QIøOþ§Y Q¨yŽŠçãëh)³dMtk¥w`ìç=ÚƒÌ=8?¡éè¾p‹Î+6Oê¶K<GÛVÑäd¼Ž'áö‚)Çš!æ/†-Ãñ± 1ùÐ;w:•5EO
-Ÿ}tÇ–½J.‰WáÓx€„jÏì÷Œðñæí/Ÿn¾Ά&î}^–‹ÚBã’-kžf¹ÜÃAÌLÇ…ÍïÇ´0ðž¬ÒÔÞÉÆñÏa´¶jµ§3‹òÌa¬õI°“ѳڳx!a²Ø~¥
-<Åz¹
-°8³è7ûõ¡<Ýv) PÁ©ò¬ÖÇQš'Åët¬Bæ鈅4âš%ïvKÕE,.¦¯Ö!(ŒÎÆœÓä”ZgÍÙØlõîÃC"çä
-öú–i&94Øg^ˆrd‹5Û‹uG½‹ÏVÇátlý:çÕ\åsêM;œ qؾhñ@Š"È¿bñ¦X/[¼€…›W_ØͳSÜV;ì€8pÏ Ÿ‚g¯“°è™™* (‰õœž_ƒ3ŸY>] /6_{VI
-’(z8±™Ø°T!*`Ý–QX*!"¤qÜÇHŽïÖÊÍH‡ÔZ–`ÕÁÁI 𪗅 Aì`å‰Ö ¯Ž#NúS_5sw<Rò
-@îÐRÞmðÎÝpðžãù>‰·/\ÚHÒ‚Þ
-ƒ«PôƒJª kÐ/éºQÒ;l½Ã—4ׯt¸`-…Ê
-ïèîplOå©ò%'T± A.:²„M§ì[ÿH'ú@E(¾W)0=ãµ/gõÑB2=×õ¯ gž¹È#ȳ}¹X*ÄE&Ae·°Ÿµ‘Õ6 >¤Ï6&2EšN\þB¥Bùçv‘ ÁCé8<
-‘E.2ÿÌQ±}öÒŸMêÃЩ݃«¥-¿}Á¦„ëωZãc¢†ÞüòÿgÆfQži!Ú_¾ˆs“iò]²ØdžE”©pC/ó[G…Ný†þ©nÎnå©M¾Æn;}cðoþcIàˆY Õ$•Rh ŠWïúyI´eöÈ©Eä4/FÒ*V‘
-_¤§X/GÒ‹˜»Vë‘u³À91Qšçù뻬…íçOry”f±šï/Å 0<¡”jùé„c ù]´žÚqöòã Åg8Ö¾Ggéfrœª¦!s vn|â;ËðjG‚ÚÊ»-¾é$j®綉r_ ¾7{°Õô‹B-WHð‡“6Mþ‹Éø,¿`}"£ÂCV[·Ë¶'³úì9
-Èä*X–ÉSQ–y–gÞždøwªJ?a8Ü_ ÝÎÇŒÛt¿¸0¿!š<V¬XÌØfg¯ ô»ççÓ ˜ÄðööÊ“<ñÜ 'ÞíËN4óÖWôDû‚ž.Ô°ÀÒƽú¼(G`”襟 ÈÍb‡%þŽ¿ÝM²Èäù ¿Ø41¤x`ò=QH¸Uç”[w Þhôÿ
+1310 0 obj <<
+/Length 3850
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Ërã6òî¯ðm媈!‚£3ñ$ÞÚLfgœÊV%9Pdq‡"‘´â|ýö )ÓN¥Ö>h4€F£ßPtÂt™ Ôy|æq`ÂÈ\—‡«ðúƾ»ŠgíÖS¬o®¾~¯Óë<È•\?ì&keA˜eÑõÃö—Õ»ïo?>Ü}ºY+®’àfm’põÍý‡o’óçÝÞß÷Ó§Û›4^=ÜÿøÁŸîÞß}ºûðîîfe&‚ùJVxeÂûûÝqë»O·?üpûéæ·‡^Ý=ø³LÏ…òûÕ/¿…×[8ö?¯Â@癹>C' ¢<Wׇ«ØèÀÄZ;H}õùêß~ÁÉ(M]â_l²À¨8¹^r–Æj™ËaàÚ:à Q©ö\VÑ—r¹Øn«¾j›¢^ïNía] ýþ+fÄåPY”{{É•¥A¨Bu=Ýû…kD=!Qå*Ã(™Óø°·½Yí«öˆuÜ)Û¦?ÝDÙª­ Wý^Ð6v_<UíI&íø[4ò…3¶§ª/úê‰t BŒŽ¢ 7FÑÆ==YX$Váê¼· ¶"X¦;ÛSÕ<òÀïtlç°ªrÏM ÀÊÏHÙ}<Ž½j/VW»¶®Û³_ý݇Ûîܾ["6tD²ž|Ëxc徨š.ðX90ÓÒÏ´¾ŽÔjÓö{n[àÛ {£hÂ^€Ä[ËÎö‚Ýâò_¿³É½Ei(â}ãnÏÀBš_n„ò— ί¡ ù¾`Ñ­ÝCÝ,’½á¬Ü`ÂÉÏ ©„¼%&16ÞQ+Óv,ÖrÍy¨t~ÉSYX«8§ëa~"ÿl+Ln›_ÃP=~C¯` Ó¡ÄÒƒgúêbd*8 ;ÒœŒ„@ž
+.E'Éê¶îZ”Nð…ÅS[mY4w… J$Ûb4ôwpÜY“»ËÔ\¸³È Œˆ¼¬;Z"€Ã‘¿ÎÖâp{´'/¸dÏ_&
+Žm×U  ¶mÓÉ]Õ 2”7Ó ×à4—/ªkë'Ñ·óžvÆV;Ô[ÑJ¬sÕY¯zô=²<U|W
+ÿÒÎgy$:|¡œw!nà¾/iAÚ‡'&`­• T2ó+ûU©xÖ8ȳ(–ñÐI®¢¿‡¢ª=éíHtajâhÇ]ˆ~µjÚÓ¡¨kâvèAW*RÓ1`~*¢¹• |¾pu ìï°'ZuÉzn5u^uF¿0Ç$Aj ´œéâòÙ`­p¼ÑÅ(f†ï…
+bT¢Æ FA€å•Y$œª@gÀfEÓ.IB¨òFÙVzŽ7[«q&ÂÅ8k¸©/#®e˜·oHaC.œ SëªXq`f+`@¬hBn†Ø%!/°m˯TbÂ8Hê¸ãüõÜöÄù,ÞÖzBg 5’ÑÛ†D{D76†Îãwlƒa²k><‰£D7jØ"”'êyäágéÕSeÏ“wrøÛ¾·‡cGT†­ºJ8r%ÀÞüÐK¡ˆÂ8Hµ~[*0 óæ\¡ÀËêxRÙðhËj÷,òº° 45=Ùr8uñÁ"‹›B˜ÂÅÏË‚˜[òµÌKÙ„ÕcÓzd>ˆ"eȼô"ÕLj¹ÂFÝ>
+Dbqj8X€ÎÌ_ñh…éó[܈³ ‹—,'œêªWn#Jƒ(‰œ},J'kŽÕTec§†Ð`–ÅJ‚ëÉÈl·^·+f,Š ‚̺ÉYEb‚<½ÐDVX ëÚ/ÃuÈ@œ†ò‚P–lqÈŠƒˆÉI €10B 'I‰S`,[€ULtzJ¹ U²úÐ è'RÔì³#$bLŽSxý%¥ZRC^DÒ(NCíiÀó2–vYÍ ¿eB†ÄèúÝ°,aœÛ’§a×Óñ)žÈH
+/Èc`2¾]žb½^öXœ[ôå~}(ŽG»]cRTp²<+ö†ad`vߤÃc-2OH $ŠØÌ(¹ß-Ô!L0aüfub\«iÖÉ¡¹†ŒÝ|ï?>ÅrNäHešË!ÀåH9³Ç-ô̰褺âT¤O)È(/ÓW°vNÈCçP0Ž’}(i¹ð¾ªàèx%šwºÂ‘hV!ÀÊÕзCÉ›{­<·§/ŒÎâÎÙ9ŽüùbO­âVŒ-¥FãK}´µÅªDÑË`ìLÅAˆp,Õ]¬Òð‰Ñ"?¼ûèlvÓp …’ˆ<;B¦¿cdN„ÈOœÀkî$áÈÅóQ'3ÊÒ©l†ÐvæB´È ¶º¶ü‚™LÏ]©§jÊûH®– ÏxIT{‹3ã·0ãCo¹=+zÙÃ1+™‚1ÝcÓòÕè!çæŽO!Wüæ1¡5…ŒïÛ³}â¸ò«%o’§Akd£ Þ.z ‡7/EP<„æ«j^à]p71îfÖƒHQœEº:
+1!Ëìªncé–…{Œ!(Ûá©ÉöU“ª xOó4Û¤N±^7© ^ýÁq{ÝmµÃˆŸ?ó²F°S¬Âômr<Ö=3[Å¡šÓó³f¦Uåèìõ_½ÜĹöi½Í˜TÂP}ö
+Y U)ÒØ3÷1T¤;B(Åy#Ò¡
+.a\N(αºÉ±xHF@‡XÔ…Å˵v˹žOIµ×ùˆÆZf!ã:rä=!eQ—C]ôÎP~õƒ>³#_bÌA{IÖ̤†uôYs,åì™ eÝ>>ò›š”cW"Œ ±ñÿ ŠÍÕ1è¸;Á¶„’±q^e\!ÆÒæÑÊe!ld}ºœCÕ÷Žr„ðÝBºÒ±Ÿ´ÅAöA‘èxbÑ-G›Î¨]ˆÄ¼@7‰Eþ F(‹þe{/Wõ‚¦&‚ÖI·åïF†Ùáàç;°¼}_•ŒFÏRLiÿ<‡:ål-j†pfo@šÖKŒ8W[ÊPCMO9øeᄆ¼Ñ¡¼Ô‡z<[!~Q¯Þ}üIVhr°‡–2ChC$Ð !kaŸØ®žÄINAb(û^'£ëÜKEì‡+6¼âa‡’âàHùVâ(Ç<ֶ犃ѣªÐ‹ l‹¦çÁÉ“ªQãÖse¦m©V0C⚧'I/+%"ÑY°1¸íf_Wýi9ÜcÅ™ì4frDØT )ÝÄqEAÄ_o¸ ÒE—ÂÞñÕÝ[8É,=¦ßm,Gå gRò.â22ÿVoÇöTœ*WÕB+É
+r]“%l:eߺ‡À1öp÷ꢎK^»ŠY,X󇿿Œ.\sžÉ»ÔHŠÐy*Ál·°Ÿ1Q&ñJ¤/Ö:Ðy’L|þB1b•ºœ‹}äBô*ôOd’óÔ=¥§TÏŸýš ” ¡SCtZK[~^ƒÍ1Q¸ j–
+zóËÿÛŒMƒ,UB´»|÷ØküËô¾`±» ó ü ½Îoä*qºçÀ9»£ KLüWì6Óg ÷»‚±èpÄŒ‰ªž“û¾ŸGÎ-³GN-* ¿Òy5”†“*é·#é Òë´C"ŽÁ–ÕzäÛ,lŽudYöæÖéåÞó¿,HÒ0šm.É3˜_hJ”ü0#3 ùÕ ´žÛqöòÓŽˆp¬]ÒÍžû"2¯ð{ç-Üø€ÍSHùº” ¶ò*ŒFqtñqa•òãîrVš~9ñbõ•i’¿W~Y°;Žü+Öki$þÖÀ¨‹·. “+li*ïPiêXž:K’âKß©*Ü„á°!¾@»#ŽÉ¶é~qa®ãš¼„¬#°•¡_vØ5Ò¯B^žOÅ` ýÃÞŒ³Ø°Nî:œÚÝeÖ+zç5tá÷w`cCÈŒÞ|»a`”àµß·jHõ¢"…~‰ÿû·¯ãƒã4ÐY¦–UR‡Ý±wD!áF_Rn@Þ ø¡ÒÿªZÁªendstream
endobj
-1293 0 obj <<
+1309 0 obj <<
/Type /Page
-/Contents 1294 0 R
-/Resources 1292 0 R
+/Contents 1310 0 R
+/Resources 1308 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1280 0 R
+/Parent 1285 0 R
>> endobj
-1295 0 obj <<
-/D [1293 0 R /XYZ 85.0394 794.5015 null]
+1311 0 obj <<
+/D [1309 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1292 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R >>
+1308 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1298 0 obj <<
+1314 0 obj <<
/Length 3366
/Filter /FlateDecode
>>
stream
-xÚÅZÝsÛ6÷_áGy&B‰/|t§çN㤶{×™¶ŒDٜȤ*RqÜ¿þv± Š” )¹væâ™\,°‹ÅûJž'ð'Ïm*Ò\åçYn„M¤=Ÿ=%çÐ÷Ùdži`š¹¾¿?ûî­ÎÎs‘§*=¿_ ær"qNžßÏ›¤B‰ ˜!™¼~óöú‡_n//23¹¿~s1U6™¼½þéŠZ?Ü^¾{wy{1•ÎÊÉë]~¸¿º¥®”çøþúæ Qrz˜ôöêíÕíÕÍë«‹?î<»ºï×2\¯L4.äϳßþHÎç°ìÏ¡sgÏŸá%2ÏÕùÓ™±ZX£u ,ÏîÎ~î'ôú¡1ûë„U&=Ÿj#È[YŠLJ`Êl.R­toe%cV\håyݶålZÖÅÇe¹»f©á29ßsEäë|©¬pV«±W$yªœš¼¹¹»»zMív³Z5ëŽ^ªUÛYTF˜l’ø‰êâ©œ3ÛP¬NDž܈ à`’tòK½,Û–%•,¥kh¸qƒá©Ö暇¿”mD„ÌD®Uñ*¢«:ËO)ª…K”a®åcñ¹d ~V ~²Æó&pÔM‡SP”
-B<~d–‹ é&‹rÖUŸKX³–߆`•Cx1ÿ€Ó £€;ŽßÓaø¦ÁÖ³Y¹ê¦å—Uµ¦Í!FªÌ¹£:ôLûJŒV›J¡R€íP‹K/wTN¼htÐɤ­ê¢Û­%¦çDz¦ÞÏåºZ¼TõulÁ/w"`!TûÍÃÞ~óð%ºyBˆ4MÒ±g«›Ø2C6'we×yÅÝcÕR«YÑyôT†ÛïJ@>ˆ°,½+ŽV0s–$ú´g7ήϛe]®9ê Ä’iVËâ…Þ‹®+fŸÚÃÔRhÈN€pÀu… üsS®_–Íîà<©uùqÁ)"x´G‰©IÔXòݪœ€`ý&AXuå^tN:4{ zûØl–sêðni]±îÊy?KÌÍ*N1OäéÓ. .ÃOŒØÕB\/b®Ö “¦zCCîL âµíýŒG#(‹Qœ–
-ÌfŸiÎÑ)ålömt°6mñ€ðÎÀ“6øLMÞÂûØÎ(lSËeD‘ éGH«þjjŸ¸gá0eƒˆÔ*m
-Œâ&Uª' oN /ˇbI´Ç¦íø€c÷HB€y¹ž‚O÷€''kÃËÀÚÀwûö5‘aŸxd͌ܥ'NIÊ“?5ój:>–ŠÍŠánªhhH ؉˜5ÛdÇ»ïÖ=P7ã->«Õ’œGfÈßfš½šçÚ»9 ׈Ô=/_Q×%ü#
-y] ½û• UvI˜R¤NN®;â⪠nÕЬ†ñjø­*,ü¶ÊlP›Ä§ÖNnßÐÕþwI$àáys÷Šwï/¹õîWnÐ&bßí…µ“ÓËþz´³~=~Œ_ÊR\Ï…œÐ’ðÝ羧µŠøé÷xÃgöDñG†© ÓCƒ7›hjUõ¼Âìe˜‹Ž;“g-†¡Öiy‚eÓ|Ú¬XÂbĽ¡¯ÙÑ%‚uæÇ‚·žsºVq~w}3½|óæV\Þ~¸È•‡š'HwIþ¤s×õÍ=ú¥ƒ •Ñ)ä¹'ò©Óát*0mÏÛÓ—½:"‡3 Åæ1©g_긊0àû@‘¡Ø×(×®%„ÕÁÓ!Äç9D€–źåÍqÑOÄä‚×øu>çŒÆã_æánB#€æ \÷·%ãTÙ&"ß^j~u¨iïýR)>B¦Ýnv¶jÚ¶êËÎÏÅrS2º‚ODnH'Lgr(çÈÀÀ„"O!vÙLÿ!.Xk‘*s¢ör†lϵÅìsµœÏŠõþÝ‹J…¢ñ¨øÀ?2¾H#ùT(m¶7Ð4*”f eÆ`‡&ÅvhÔM=¥â·x ðz¶Î91 Nš”%.ŽçrÔä"sP¸ŽÕÏ ìŠ®0Ž=ûÃ6D²åsñ¾¿å×ÀB>8tFàÝ«ºÇݦw芗ÏM ”å>(©pÆ¡1\1QžŠnöHÕªW jÕª{|"è˜1ˆ™hCÎ?Ç„-Á«#X—iðZô—“¸´<ßCÐéÓæ~†’¶^^¤¡Jg"ÍÔñ;K#r£óq
-SE½±ò¼Ç
-4=V°og¯¡k„•b*‘J»“hÑ}JÛnØ©ô@·¦>||áˆ@Z¨Oßב㸶Ƿª»òv÷eÿüByžØãòSDþøü&B¹TøP®Á¶U :\gÈxšbN4Dµ¶Zz¯zK]þÜÃ3@û„p×ØK
-äa-…ö> úüVyÿ =h±Eßlºi³è§ÉÓD–°icbp"¥ÞgN½D?ë¾ÓpþË•8 ü$˜¶J"'xM£’ÈÞa'¯ºÃrø±\6ÏDíš3.ˆÀ‹ƒÖÖ(‰z¶FÁ£xØæNäRçcØé6Ùú#‘¿“„’
-ãäW8ù“¦ Z™©üë°gí¹†ÉütæË“½ÏªJ˜–pT~ÏQ`ìZ3a²ÜŒ5ˆ^¸çª$¤‹ï¿33Úf£kw8ü
-\Û kן¢ê¸üÀ‘Á”+p
+xÚÅZÝsÛ6÷_áGy&B‰/|t§çN㤶{×™¶ŒDٜȤ*RqÜ¿þv± Š” )¹væâ™\,°‹ÅûRž'ð'Ïm*Ò\åçYn„M¤=Ÿ=%çÐ÷Ùdži`š¹¾¿?ûî­ÎÎs‘§*=¿_ ær"qNžßÏ›¤B‰ ˜!™¼~óöú‡_n//23¹¿~s1U6™¼½þéŠZ?Ü^¾{wy{1•ÎÊÉë]~¸¿º¥®”çøþúæ Qrú90éíÕÛ«Û«›×WÜÿxvu߯e¸^™h\ÈŸg¿ý‘œÏaÙ?ž%BçΞ?ÃC"dž«ó§3cµ°Fë@YžÝýÜO8èõCcö3Ö «L
+–ÔB¥RÇ­,E&%0eF
+eÕ[Yɘ•Zy^·m9›–uñqYî®YªD¸L†ÄÄ÷\ùz _*+œÕj¬ÀIž*§&onîî®^S»Ý¬Vͺ£‡ªFÕvÖ#•&»&~¢ºx*çÌ6«‘ç
+=WD‡ÑrÉyë) ­uÖCÛ­üsÕ :ý
+°ì¢ÚfrrÓtedJ
+þ¹)×/ËæaWpž‰Ôºü¸àÀ<Ú£D‰3‘ä»U9
+ÌfŸiÎÑ)åœöm”1oÚâá&m
+<𙚼… ö±%PÞ¦–!ˈ"’\ýÕÔ>}ÏÂaÊ!©U,Ú8Å“ .kQTËXð³Âärj˜;®º‚Ó–gµ]B‹%fò¢Ôýƒš?ë:&<²Qͽ¢nŸËuËàK¡:ÎíŽOƒ}Ò<#¿ÅàáhŸØ$Zc*(ÿ\ÈÆ׌Ә+÷e|pZ0ÜÍOG°ÔÜúGÈ”šut+r•y6tç0iÎ5ÁÂÏ"Š= ÊNØÄM6þªTOÞš@^–Å’hMÛñùÆï þ„øò$ò<
+îGNƆ‡±ïöík"Ã6ñÈš¹KOœ’,”'jæÕt|*[£Ý8RÑ4Р±j22ÉŽoß­} vÆ› .~V«%¹ŽÌ·Í4û 4ϵwr@ Ž© ú½|E]—ð(äsôîW"0PÙ!aB‘:9¹îˆ‹+/¸UC³Æ«á7>¨<2TðÚ*³A9lŸY;¹}C×_øß%‘|x‡ß›»WÔ¸{É­w¿rƒöûn/¬ü›ö×£õëñcüzT–âz.ä„–„Ï>ó=­UÄK¸Ç[>³'šˆÏ˜62JM˜¼qØDÛP«ªçæ.óÀ\tÜ~yÖb(*–'X6ͧ͊%,F¼álÑzš]"Pg~,zë9'kgw×7ÓË7onÅå퇋\y¨yò‡t—ä:w]ßÜ£W:˜Ne ÷s4rN§z®í‘{ú²WHäÂYÈyŽ
+LÁãB€û]F’_£d´€”VŸLGÇø!À´,Ö-h†Œ‹~"&ôsýçsÎjü)y¸¥ÐÃ( 9 ×ý½É8]¶‰È·×›_.AÚ{¿TŠ‘P‰i·›¡­š¶­úÒós±Ü”Œ±àØ#ÑR
+ÓßžÊ;2A00¡ŸˆÄTˆ_6ÓÿC˜‹ÁVgNäRGí€é0hÓ³ÏÕr>+Öû÷/*ªÆc²Ͼ쑽´„íÒP8
+
+-Á‹#XiðXô”¸´<ß–BÐé“æ~†’¶þ
+4=V°og¯¡k„•`*‘J»“hÑ}BÛnØôƒ L}øàJ˜0w'^i ¹ŽÝÀµ=»UÝ•°»/û‡ŠóÄ—˜"òÇÇ7Ê¥z¬À‡r ¶õ¨JÐÕz<CÆÓs¢!¨µÕÒ³xÕ[êòç~„°?@w½plGɸ
+ôl‚Fñ°Å×lRçû¹rH_‚?"ùI(Ø e=㊱?.Ð>dG# C±ϧßN¯¤0N~…“?ùr
+¢5ÞŸÈä‡\‡=kÏ5Ìä§3_žì½ZUÂä°„£ò{®ˆcך “åf¬Aôº=V%!QŒxÿ™ÑÐ6]ºÃùã¯
+À”6î[ »(‡JC*ͤ€ •é
+†m#tîã
+ˆŒ«¾›p…"ïáÊÊݼýÿ+(&re³¸pÁUàà
+Ê\Lø÷Þã8!¥Ž‹ï¹"òÇïq´HÄ‹‘ÿ¡]7édE !&e}†“‚öõñ=´BªnzÿÄ°Oæ dŸQfŠ  nw˜£AG§PÊI÷-µÅá„Âüê‰o"†\Gv2pù|­\7Óº™¶M1íºå~B¯„5VW çŠh0ÞË ÂIšUཔ!í6PÜ@éçw¨Å¦{ÄZ²À/S„¯ú'¹û– IþŒâ7 ï/‰Þˆz*9d{ä ïï"ŠO§dxµ
+@š‡6ü¾c§‡™§ðèÁ&«œ¿ÖAzØd<ØNi¤ZÑÏE*ûöЗ;ÐÒ÷=ýVà糓'ýÇ?û+Ýí'Ì/RÝYTæ {‡IX)TÜš}Ä&BéTETÿ/±—@endstream
endobj
-1297 0 obj <<
+1313 0 obj <<
/Type /Page
-/Contents 1298 0 R
-/Resources 1296 0 R
+/Contents 1314 0 R
+/Resources 1312 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1280 0 R
+/Parent 1285 0 R
>> endobj
-1299 0 obj <<
-/D [1297 0 R /XYZ 56.6929 794.5015 null]
+1315 0 obj <<
+/D [1313 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1296 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R >>
+1312 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1302 0 obj <<
+1318 0 obj <<
/Length 3178
/Filter /FlateDecode
>>
stream
-xÚ¥ZÝsÛ8Ï_á·Ufj­ø¥Çn›ö²½íöœtnvv÷A¶e[YÊZrr¹¿þ
-“,ÉðÏ]Qƒîe®EÛ¢.yWÖ[ ª(èv /w·Ÿ["nšªjž‰†r¢~ÿö‘.ö¦¿à_Ç¢íx­fÀß«#ñùßM]¼Ã!X• :fó8
-ÁˆÀŒ…3c¤•š¤ÊLðåî vtðG©|KĦ¦Ös}üz÷åæ7b\,x°¡v]tÅa_Ö —7·l©÷P¼ÐP»kŽÕšˆK^ùØku뱋‘V}¡=R4<Ë=í¤Ìé *­ÜÖ )iÍ€•½òà3?}ÄAÝtDõâbÁK.›nG½ç’zq×ë©9vL%(9¤ÞýŽwX›üXñ. +œkdñÎ(#)á¸xÊ—Â1 lR‡™V)ó„g~ÏΕD:Ô—üôä=®W<ÐqY;:¼Ì»ÕãüPlE»;s@ø 
-7>q&@ᶠ_ò:à îŽç]¹ÚQ—‚Œq×å=ж  “aÍCÙg?1?¡¾AUcv«ìáòyÝ>ûåkn;žhmø"‚Cöþg²×¼ÏuÁ=ꉜv}†ÜR„&Ùë{®‰ xa ¤‹ƒ­)p«LÍcWZÇÍDàitÁ@Ùy 6°9V4b:s€„ð
-Ç}©§¹Ç’®¡Q×f—¶æƒöÖèaQ†Fèt”ù mCS@p³“5p³ÔÖãP£ü\Ѧæ@E7ÀLY¸¤Æ\æ…ãû£=5Pm ”Œ™(Vê$óžQ=¹óºý2ûÞî°¥/®0 wfçbxÌî îàv—ãát”ØÃ!…ÓEéÔÌü-µhJØSµ'N2#ŸK·ÿÈ.ÁþÃL¥.4L[ä8š@Z€6šÂ5hŠÅµ‡²ŸåXWxÿöBÁãC‘¢©öoÔYˆuІ öôc+^f[EíBg‹7µ¾àç«f¿÷5tEŠƒ&bE¸o™faœ
-•P†™÷ù ­Î¯Å)GAh{D°yËv.ƒP2Œ´v? X¹'ÞHL¨g‚€À
-ý„B)¥š–Ø>¡qo&9½
-íxô»=µü¯¾Ë¿Øÿú4tOûžÌõîDZàêR
+xÚ¥ZÝsÛ8Ï_á·Ufj­ø¥Çn›ö²½íöœtnvv÷A¶e[YÊZrr¹¿þ
+¹Áº·ºeƒhAÝ“1â¤ÚwáI»œ·Yót‹fØÙåOÅ‚®KÒÇ
+ùdä«UѶԷ2È”½·5µèP“:–ÇŽžKëh~JTMó@½ã#ñX5•Öo€Šjâ]òúå9'WA]iÉØ3&àjVðxFSW/´(ÜøÄu
+·ù’×~lpwì<ïÊÕŽºdŒ».ﶥX
+—önÚù+5'©S
+Ç}¥§¹ÇŠ®¡Q×f—¶æƒöÖè]Q†Fèt”ø kCS@X³sµ¹JR[ŽCŒòsu D›™Ý
+— )Ö>ÔÄV|–c]áýÛ EŠ¦Ú¿Qg!ÖA1üÙÓ-x™mYµ š-ÞÔú‚Ÿ¯šýÞ—Ð)z˜áv
+¼ešáO ¯–§Ïõ„:´“T æöùÙYD0
+Ñf!ðÙA(žR¡$ÎÜñ} ŠsÞP(YÄq2s‘ÄÐó{"9íð/ŒÐ¼0&üº`÷£ÆuQin½ ‘°&³ÇÇ_ˆ3÷F¯Ký
endobj
-1301 0 obj <<
+1317 0 obj <<
/Type /Page
-/Contents 1302 0 R
-/Resources 1300 0 R
+/Contents 1318 0 R
+/Resources 1316 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1280 0 R
-/Annots [ 1305 0 R 1308 0 R ]
+/Parent 1325 0 R
+/Annots [ 1321 0 R 1324 0 R ]
>> endobj
-1305 0 obj <<
+1321 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [367.5469 435.097 428.747 446.9972]
+/Rect [367.5469 410.6007 428.747 422.5009]
/Subtype /Link
/A << /S /GoTo /D (zone_statement_grammar) >>
>> endobj
-1308 0 obj <<
+1324 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [483.4431 226.9165 539.579 238.9762]
+/Rect [483.4431 196.7586 539.579 208.8182]
/Subtype /Link
/A << /S /GoTo /D (address_match_lists) >>
>> endobj
-1303 0 obj <<
-/D [1301 0 R /XYZ 85.0394 794.5015 null]
+1319 0 obj <<
+/D [1317 0 R /XYZ 85.0394 794.5015 null]
>> endobj
358 0 obj <<
-/D [1301 0 R /XYZ 85.0394 671.5763 null]
+/D [1317 0 R /XYZ 85.0394 649.9934 null]
>> endobj
-1304 0 obj <<
-/D [1301 0 R /XYZ 85.0394 644.6731 null]
+1320 0 obj <<
+/D [1317 0 R /XYZ 85.0394 622.3077 null]
>> endobj
362 0 obj <<
-/D [1301 0 R /XYZ 85.0394 417.7762 null]
+/D [1317 0 R /XYZ 85.0394 392.0307 null]
>> endobj
-1306 0 obj <<
-/D [1301 0 R /XYZ 85.0394 393.3438 null]
+1322 0 obj <<
+/D [1317 0 R /XYZ 85.0394 366.8157 null]
>> endobj
366 0 obj <<
-/D [1301 0 R /XYZ 85.0394 274.0842 null]
+/D [1317 0 R /XYZ 85.0394 245.2415 null]
>> endobj
-1307 0 obj <<
-/D [1301 0 R /XYZ 85.0394 249.8112 null]
+1323 0 obj <<
+/D [1317 0 R /XYZ 85.0394 220.1859 null]
>> endobj
-1300 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1316 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1312 0 obj <<
-/Length 3041
-/Filter /FlateDecode
->>
-stream
-xÚÕZKsã6¾ûWè¹j„à ¢æ4Éx§6NÖã=%9Ðm³F"QÇ»µÿ}»Ñ
-“vOõöÓW =ŒÅ@×Ç#ê…ÝÉ#HÁ@£…‹qb“£fBô¦¦ÑmA›P+"”¡‚Þ‡j)P ÿl2±8Ä:'yb‚cÞ›¢Ú¡ñ¤ˆ+èº0\æMÔ'
-þÖŸ‹í¶\ Áãmœ…X%-T?À$]%žçkì朵cÕ Mogqy´Ž€èÙôÍ«â.߯#_?„aÁ‡-ô xíûch$º˜buLsŸý
- 4Paú•)~âð¡nv‘šSdˆ¨6ÂB)
-3H¼/vñmÕ<Û8ï.Ì«7ôƒ°YlˆŒÂ@wƒ¡6`
-O™*b@wN qkÄqêÈ fÁvØVFRhÅASÄ(XMh!ì• ”ÙËý¶)§Ã½àx?ZŽ\ Gå]»n¨SÀB°òö©l&óx¿2ÎÚbbi}€áê5Kã@Í÷Õ=øpY(c êp­‡UW·o`0`÷ZX ~Õ¦ê ðÒš0(ÃdÛb H!W*á9Ë’+( ¦7å\û‹á–ѸÖ÷ŒÞ
-aù6m"õWnø”ñŒ3•¤‡jª¬æ-ÌòŠžÑO¦å¥ôéÜ`A“ÊXLh¡!
-J9Ä0*~0S”3é¥z!õ¸N„¢Ä5Š¦Zè›…—Ùi-Z® 5ñÈBÔumz [îÚzš…ÔŠðÃVÞR+ïîËÏ‘ÚP„ä.á+JR@N¡HzK5¼¤š ^j.ªÕ2fœ¶Ã#ûÓ…Å©5Yõ|P“½™@§„vÂ6Fçµd™k})¯VS`÷hXGlOIãÌk›ü(\•…Öî4\û\ÇáÚr‰Áæ»Óæ´-ׄæY1nÌH…aæ´mӌÔ9aØeN|h3§¥z ÿbçK#b {úI]·Š3Ãûû‡D(㫦ØBoƒWˆ€ekÍtZE›kÕã ¤¿*¡ñL»Am(¢›¸˜Lr,bœ¹üX¾†ÊW/Fë¥Z”²R(JçN'P(&„âòµ Jí“KSµcÆù¨
-¡+wIçx¯v,éè@!;L$œu2鵬$~4:™^‡þHKñ‚¿ö¸Nøk⚀ØTrÑàd"Ó§uh¹&”»ŽyïÝP‹¡ËÊ6¹(Ù&¤Ž’ ¾ É%¼‹÷\H»«tÉ]±´Õ<äd¤BSŽòI¨AâÄ |JÔ1œ^›OFš|i¯ŸNZ‚ãZ¯Íi8ô¹ŽÃ¡åêà°\å»Ãž»X¥ÿÉÕ[®‰åÕèjÉgÎ ×UÝ…'äü»‘ÚÆîðb72…3
-¢îò]˘®ÞI„W·9CK·A‡‡(€ nyq«Ž¾Š³.ބƸÐápò²jÏá] {Mqˆ•Ì0‡©E‚½\¦Ãgz¹½×+×}Ô$þEÂjäÔË]™\É15ÖF*Ét‚úÂÛr½ ƒT:\ôœ¾„ Gvy¹>á»/5„Áw{\'|7q}wê<åÛe|4N`~T§i¹&4Q£;Y—õ·uèÆVµn ÃäÆ0ìÜZ7†òÕ¹1Œ;7ƇàÆ0èùToÚ:ÿýÕCÓ“ÉQøžÇ§@ßnÈá™ ¾“eðò¡Ž¬‘' ªé”p!:„7½¼Úɯ?è¬i!QêTËÿ ŠBÎc †ÿžª}sÐìÆ9oH|²)*T@G•¥HÄ*ª£yx{GŸ€â]tžeBš¡qÒö)ÈhHÆeN:##å±Ø‚¤ ,ïýüæÜËyM<E•ß®#_»´v}Âä7Äœî,'ì䡃2rXN‚ïï¨zŽ¦…–-Yö틦 W_‚ð{÷L_›ŸÎ×{º‡‹õc¼b{È« Õñj‚C”úsGìðÆ3mŽiB®dÖ¶Åþáö¦¤‚a Êî_Á(,5÷`ÏgzXÖ{üTõHéhµ_¦‹<–Q5Ô1X!qp²²ZâÙú䀘3ëª)oËu¹{&ŠŽÀÐ"ˆí5Œ—¾¡M!%ÖDkêýzEã(xGRðƒÜhå6qãĶ犪RCäÛÏ\ãï~!^PÈz£Œ_0ɳT‚xüéÒµUÖî ÇC´GZ‘ïöm× º«ƒ
-†QÔ
-”¸ƒ0Ÿó²<ÖM‘ˆ´ÝŽ¹™Jã´Úú¹÷Uó0ê€qJ„TVà»tbxURW½ãê—¿»]¾üÔ/”ãv  „ð#•{¡6Hì‹>ÿa&:úšÊ@Cµj¬êrø#›Äõ‚
-ZrÆõCÚÊ`S÷íýRy&ÁO— =¦ãUBbêâèg»hž+
-ü*¥®Ê[Jl0eßë©ôL²Ýü6ý¶¢åÁ ™ùù÷PÛt1If]øÎÛ¸u³I·)4~*Z,9K×;U<ÆžBQ¼Åº›
-Áà±s:€ÐŠ6uBh_V(u LŒšÞ*µºå}ñ½ê~5c@½)Ò*ÛªEüÅýT››n* ß¿M
+1329 0 obj <<
+/Length 2905
+/Filter /FlateDecode
+>>
+stream
+xÚÍËnãFòî¯Ð-20êôûœ&OÖÁÆÉ:ÞS’-Ñ#b$Ò©qœÅþûVu5)’¢d“2FÅêêêêêz6)fþÄÌXfƒ 343\˜Ùr{Ág`ìÛ ‘h-Ñ¢OõõÝÅ—ï•›¬´³»‡/ϸ÷bv·úyn™d—ÀÏ¿ùáæýõ·ÿ¾}{éôüîú‡›Ë…4|þþúŸW}{ûöûïßÞ^.„7bþÍ?ÞþxwuKC6ñøúúæaýœ`z{õþêöê曫Ë_ï¾»¸ºëöÒ߯à
+7òÛÅÏ¿òÙ
+¶ýÝg*x3{‚ÎDr¶½ÐF1£•j1›‹Ÿ.þÕ1ìÆ©SúÓÒ3«¬È3)€Ç+–U>jÑO/Ëá0³ÚêÓ¼h^ lg Y-¼`&3[X§ANºã•j& ÆH<_ï˜tØ(Å8¢àxoPÁ‘00cµ@:Á™QRs¤øáraÅüþ—ó£ãð–8Š™…ÍáqáÙo3Á¸AMŽ;=h "¾¼ÞÊÙ»
+ö3ëo)ñ]ôÇYÕ3X!ìW«™ † "£ÀÙfS]
+3Zü¶Ïw`|þ¼XfËK
+ê«2¯ßøT4ë
+À‡2GŸÊvÅæ™Ëê©›EÞ@°Œ''5OÕîã5=Œ¥P×·G”Ë3'¹<a‰#óq’iáR¤Øf(™Ð0­®ºÏé·î jEˆÍD¨(÷±B‚7+'ã?@'‹C´I["8æ&ßæeƒÊ“"­ ;Óp™ÕIžhQð[}Êw»b OHã,3ªZ¨zŒK†¨ ï*i\{žâÕzsÎڱ茘¶£é,T$º~HGZ%ƒèéôÍÈVùC¶ß$º"~ Ähd¦v¦O†×Ÿ²–AªKYÖh¨< ø›Ö
+«Á¯ºT¥
+˜m”QòB :ÐœC‰f2M5!Æ@„”þÜúÍ‘
+ e|4N`~Tçé¨&$Q£{XçûÛ:vc«:7°uc
+”mYcí‰áUIUöŽ«_þ6M¶üXŸ.”ãvføAD°ê…Ò ¥^ôÈóИçkÊ ùÛX;äø»š–èüúZrÆ ºš`[õ5ýR…` S±ÎÂÐÑœù€háó“]ÔÏ%ØkM©iØæÙpéέÞÑ-?lñ,óÐ ö–O_8“^Ôü”E¤Å÷ã]ô¡vÞ$Ý9Ó¾©2óz[UÑí¹ƒ„W´¬ì ˜6ó·ð/ÑU cé¯×†N|»¥ ÓÓï^U~öw]‡Þ +Ž]ÅtÁé<¦À$ …5öØz8“
+ õXôÿë(«’endstream
endobj
-1311 0 obj <<
+1328 0 obj <<
/Type /Page
-/Contents 1312 0 R
-/Resources 1310 0 R
+/Contents 1329 0 R
+/Resources 1327 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1280 0 R
-/Annots [ 1314 0 R 1315 0 R ]
+/Parent 1325 0 R
+/Annots [ 1331 0 R 1332 0 R ]
>> endobj
-1314 0 obj <<
+1331 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [184.7318 238.2538 233.4785 249.0382]
+/Rect [184.7318 214.5925 233.4785 225.3769]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_security) >>
>> endobj
-1315 0 obj <<
+1332 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [369.8158 116.018 418.5625 128.0776]
+/Rect [369.8158 92.1907 418.5625 104.2503]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_security) >>
>> endobj
-1313 0 obj <<
-/D [1311 0 R /XYZ 56.6929 794.5015 null]
+1330 0 obj <<
+/D [1328 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1310 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F63 1063 0 R /F62 1060 0 R /F21 710 0 R /F48 950 0 R >>
-/XObject << /Im2 1049 0 R >>
+1327 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F63 1068 0 R /F62 1065 0 R /F21 714 0 R /F48 955 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1319 0 obj <<
-/Length 2727
-/Filter /FlateDecode
->>
-stream
-xÚ­]sÛ6òÝ¿B÷tòL„
-©½™Þ+•Ìoää ̽?RŒ3‹H³.Ö—G¯Ït1ñÂçY>¹¼îÐrB:§&—‹_§ïþyòéòôâx–Y9ÍÅñÌærúÃùÇÄÓãÝÏÏÎßÿëâä¸0ÓËóŸ?øâôìôâôã»Óã™rVÁúŒ)XpvþÓ)Þ_œ|øprqüûåG§—é,Ýó*©ñ _~ý]Npì¤ÐÞÙÉ#¼H¡¼Ï&·GÆjaÖ²>úåès"Ø™ KÇäg¬63ùdf3ád6.d)¤¡Í
-£DîýNÈ™rÄB!—ëuó8Ûnʺ½®6Ã3+ãE–¹I—ðÞöid{ÝÙ^Y#2éuÿ_îªùê7)³ª=ž™ÌN—«ù’†Ë¦Ýh>-7ÇÊM+‚ž«½lz¼Z=0ÖššGñtLë: 6·<¹d¬¶Ú<€@)Ša <m­ÈQeGlˆ7™iï…Ë @)á­ÍFW¤IèB€¢{&u[>Þi4Û†FW=Û$œV5=‘é}U¦…2:cÂA
-÷íªþ7s_F[BoDBCÅ®êYSœ|–p{zDo4˜à}i£…Ó:bnË› øbMOÚ¤Dƒ16ˆ4Î/"©MÏ7*×yŒf º ¶C7E¡•›ä2…/õ‚œ'Þ97žñÌÅY—dp:=þ´q¢È@­EÊ-Ĥ!“d2×ß‘ÉHñ[L:0·Þc2xÀC&h’ ά/ÈFð’’ûƒ1»?‘bð=×tÃs(lfJÈ<è\ÏØb‹æêiÿ:.‹
-ù—˜$ÎEʶRºËŽ´øØgN\ýQÞ¯F iæ ‡‡
-ÍšÀº¼ePòÃ
-p©
-œc5 Þ®K+Ik ’ªéH ¨êA0hrQ¸¡ž7·”Z€0¿v3ǼNtx Ÿú¾/«±È=Ð=veýMÜò»”ƒxe1ȉ¤›–<‘¢ÞÎE°ñϧ ™„B¢­‘àõ+þR0Žg]Šû±Ø²Ð~·ñÁ„!ÓNXë¿'‘â·˜4JXãtŸÉC ƒ…2=w,nò¯Ý»é'” V/6<H‰‹žá¡sQ9›êF4P‹ES±b;ÐÚNÕ&.¹+7\¹²Ê½0™²}GÜ6ó›àvµc›'^R£Á[ Q²hzíû{Íšª nH$aD‚"b†‰]ó†K&×ÜUÀ(™ ¼¶O ®[/K¦SÕÍýæëäÓ9cÞß_Ú 1Yç‚  ñ!œœþ&­L66WûD|n oÞÔ°ú¶%h @/Î@Äïh¬×Ýp¦ßD[“ÁN
-“Ç®á0eŽåH¤--¥`éc¨î² o1§”h1vÊÎE„ý<¿D H$i°©Ã™JrÅC£„djËè$[˜ˆ² О4ù,KH͸AÇ´çUµ,@\«°ÌqqrwÄ–ò
- QõM׎b³£ËcŸM›Ø*¸©ž©HRå4V„[Ùï!?‚MÜoæ¿ ;¡BC3ê` WHûr‘ã×°aY£È‘™½šÎĦ§é4=êT$K
-|0hïC¢“ÜC
-#ßå$û_þ3ÄîŸ"!ç²ñ¯‘ZæÂe¾ˆL¡ì­rn± wY1Âúÿ|0Ãíendstream
+1336 0 obj <<
+/Length 2683
+/Filter /FlateDecode
+>>
+stream
+xÚ­]sÛ6òÝ¿B÷&ÏDA€<¹9;uç’¦®;÷Ðô’hK‰tDÚ®ïæþ{w± ˆ¤(Ç7Íèàb±Ø]ì'(9Ià''6‰rzbœY"³Éb{’Lnaîý‰dœY@šu±~¸>y}¡ÌÄ —§ùäú¦CËŠÄZ9¹^þ>}÷ãÙ§ëó«ÓYš%Ó\œÎ²<™þpùñŸqôx÷óÇ‹Ë÷¿]=½¾üù#¯Î/ίÎ?¾;?I›IXŸ2…# ..ÿuN£÷Wg>œ]þqýÓÉùu”¥+¯L
+òõä÷?’ÉÄþé$ÊÙlò/‰Î¥“í‰Î”È´R²9ùõä—H°3ë—Žé/SVd65#
+LUG2±Î'&s"W0…
+üœ¦ºZÏç›3ùtSÌËMƒPzok|šé|]»§.¨JY7ý±~,Ê*êL[5mÖÕ‚©ÍëvE£³œžEµ<FÆ@KÚ)hWeEøËòŽ&E[._¡æAü™”ÂeYêeiW놎§¾k×uEãǂŦ©iÔ§…‚ÈdzÙÒd QÕ ¸­jB_2ŵ—
+FM½-Ã.»j]ÝÒ˶lšâ¶ í#I¦kd&L–ñFšu±è8å˜?,TA±ÙÔ³vWTÍ (r°½ÔN¤©}~û€4²}Ïš2-ÒÄ©þþ¿Þ•‹õç$IKТN³éãj½XÑpU7­‡‚„3F¸çu‹/hoøäó)׌õŸºâQŽiÝxÔzË“+ÆjÊ›¥?…òT–‰=%é¨ÍÛÔL9'l®íÀ¶:*hB1É1©mF­\07ÍKz6Q9K¬+z"Ó‡<ÊT ©UÊ„½w$g¤d¤¦‹Þ–U‹¾¨e܇‹¢A~4vKµ[/ñÈžáÆX‘f6hŒ<¬ ¢vÔ—×Fš >ùõ¹Äè¡
+˜mñžƲˆž´I£3¯Ò0¿Œˆd6½Ø È|™³˜.˜í0Œ
+g­/Ng‘â¬KÒJ[aR0ëˆF™²…œ4dÒ@õ‘äê;2(~‹I ÎáàÔ{LúxÌutÁYæ ùR 0æð#2 >çŠNs¥ÍTŠ$Ï6×s¶ÄB€™? ò_'dqê5쇸ù ¥ô #ëW¾Gsí9Sàb!„륈õ¹ÃòD{i>@ð[ßmFÝ30r/q¡TX«­X.Åæa¯-ûÓ ‚Ë?‹-pñjÄ‘fÚ-Hà}¾÷ìÌr›ÿ¥Âû–Þþ÷v¬#¬$íáj;Ý£ö ±Y ÍäàíµÌ{´㳂Ҝ
+o>(w˪ànN±i
+cR×—ùz¼æw“ô´³‡|Dà,9T—½þ€û n00¤­;ÑÍW¡/éF=l*b
+¤[Ìà™Mÿ~6g]Š‡É؉Qn¿ñÑŠ!Åë¯Ì}OÅo1©¥È´U}&U œXnYÝ_»gÓ¯(!j%_ìxP›žãap‘9»ÚFp0‹e]²aP8Ð}§
+f–Ü;È®ÜZåNèTf}ïhêÅv•eŸ† ^ÐMƒõ¾@£èÑôÚ÷Š-U¾‘ˆ,ˆEÄ4»á WL®¾+QrAxmž@][¯
+¦SVõý-óuöé’1ïï|,I1œ
+vÑ~=rÐC¼ê^mܲmbsQs™ô¸*ãÝÁ]\³î]š“atj16£Ý Þwj$ŽFN##òþJv÷ÇyØÕ¼¼“pF(­ŽuÈO·üï$ü牸ð¹^"Mùf9·oÞ¼VéÛñ^ÒN¨$‹í„J¸@ µŠ6
+Po–
+Å‹b>TapXŽ}èÑ"Í2ÓÙ™RáCýŇÖL+<·Cò¹ʸg…‚B<OÜ€t/¹©ÔÒ×äCúÐøiì‹Øw¬á«†Ù_ëÁ>Œ# @|H˜)hY(ŽIûvg ò× +dbÓ¾_óGqì¯*ø‘ODÉ$ÐùÛKØÿgCCš³6ÿؤ’\ØÔ™ÀòŸ™!çñÿ ‡¬ÿ¤Eendstream
endobj
-1318 0 obj <<
+1335 0 obj <<
/Type /Page
-/Contents 1319 0 R
-/Resources 1317 0 R
+/Contents 1336 0 R
+/Resources 1334 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1323 0 R
+/Parent 1325 0 R
>> endobj
-1320 0 obj <<
-/D [1318 0 R /XYZ 85.0394 794.5015 null]
+1337 0 obj <<
+/D [1335 0 R /XYZ 85.0394 794.5015 null]
>> endobj
370 0 obj <<
-/D [1318 0 R /XYZ 85.0394 658.768 null]
->> endobj
-1321 0 obj <<
-/D [1318 0 R /XYZ 85.0394 636.4568 null]
+/D [1335 0 R /XYZ 85.0394 625.1831 null]
>> endobj
-374 0 obj <<
-/D [1318 0 R /XYZ 85.0394 119.9909 null]
->> endobj
-1322 0 obj <<
-/D [1318 0 R /XYZ 85.0394 92.5589 null]
+1338 0 obj <<
+/D [1335 0 R /XYZ 85.0394 599.8772 null]
>> endobj
-1317 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R >>
+1334 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1326 0 obj <<
-/Length 3170
+1341 0 obj <<
+/Length 2990
/Filter /FlateDecode
>>
stream
-xÚ­ZßsÛ¸~÷_¡·Ò‡ß›'_⤾é9©ëÌ´sw”DÙœH¤"RvÒNÿ÷îbŠ”)ÅI:™ ©ÅX,v¿ý
-ü¥ÀWˠߟFkØÔóÅb[4ÍÈ°*eÚ ôÊfd¤Œ¥Ú˜ ñç1Ó×&Zö;7<oÚb[6á]ÀVY•Ô[zÂðÔI½.Û¶X¼À_6É©ñ±\-æùö\¸dAjWï©íG1®Á p–S%·°}&.çêúâõë›Ãè€õÂF¹ßgćd™sn<:¦ÝˆÓþO·^;ͤÔb¸÷×ÿqª”&Úî½*P æ2fÜ=‚e&ÅvpÝŠ’bVÐs× æ»pPÍ ¤!§,G÷Øj—†É6õ¶³H°÷D¨@
-ðÌf'cEe©ˆQŒQ‘9ŠŠ,ëE…ÂG4nójQ¯Ias.4Îÿ¨vëYFXúðˆj¡ç†bf:¯«ß9—w;ú½ %÷®ο)ç©Ù%»M«
-‚àb‹i+Ë”±Ã@¿›hyiRäó{ù4?°8H]
-è¢Æ‹¼x¥ Õ~üxÐ-oa7Ãñ±Û:O:€·¾ ‡0”DZËÀ"BS½ÚQ"Äž’Dþ²(Vy¼HBZ.(¶1‡°bîIT¹Æ¥æUÐöø ÏCüí®4xg_’ÑñpÑ¡è<ÌójxWÙäË"‚ÑXÊê
-¨Q;zùù¸ÍxÖ­ƒW%¿áN£»ôyö¨Ï¿Öp
-
-Âœd~0/ðÁO:›b[w% ÒìGêN(8k”>Ì
-M´Ë»†›GFjM¾:‚áµ S-Å#£†6ª, ™Qz3à±ÈÏï+œõî(݇ƒL0 Þö¤ÃŸq$X4q?|ö8Ø3„CuGHײٳCTñ[‡ªôËÐ/§Ç&ßóÝ!òÃÞB ´8]
-oSŒ|öµ¥Öžºˆšj­!\=}k÷¼ûË—ˆZwüÒZÙà©´9ÀL
-ÄQì©5Àhp¼Ñ÷"lƒ¯©‚¥BØ œ™ËŽ|û$•é^çø‡Ï s<û“§Á^âÔìΓéÕ
-|Þ+1pJä •ƒs ä8vëdS&U÷4†˜Ÿ.ØA´%ËsÅýY
-çÀ³¡UGl ‘W¨˜ã"¿„ °ÆQV¼G÷‡'â [ŠÞM“N² w+x’¤ÚfLºÌM( Ä'¦°Á¿“˜îÿžè‡ÓNÖ>2n¼K×þK¨=(à×b7…þ¢cÚÁ Ê0 ÷Ãاu"üÉTÐê™þ?náÒ1endstream
+xÚµZßsã¶~÷_¡·È‹ß${ONâKiœÄufÚIò@IÍ9‰TDÊεÓÿ½»ØEÊ”ÎwiǤ `±Øýöh9ð''Ö%.Wù$ÍMb…´“ÅæBL í› É:³¨4ëk}yñçw:äIܯzce‰È29¹_þ<u‰J.a1ýêûÛw7ßütwu™šéýÍ÷·—3eÅôÝÍß®éí›»«ï¾»º»œÉÌÊéW½úáþúŽšñåÍí×$Ééqbлëw×w×·_]_þzÿíÅõ}·–þz¥Ð¸ß.~þUL–°ìo/D¢óÌNžá‡Hdž«ÉæÂXX£u”¬/þ~ñc7`¯5tõŸ‰ÒN8PÉ1Ú<qZéÎÀ-Bˆé{¿û@‹¼Z.w¾ip‰0î $&3•'&•4ÄÍêr¦¡Cûèé¥ñ»'¿Ãw9]Ö¾©¾h©á}U?éUóLº ¬©OA?Ûû¦-ëê üLí´äAžËõºS@c±K ò(U±ØÑ$¼„¾/4xJ+›ÃZp a¤YSïw ?²àY§>“2É­U¡W³õ‹ò!”o`BçxUÎN ðݥ̦è¿ÐRTKzÙÖ»–tögÙªÞÑK³_<R#Tz0}æl:}XÌÚ¾â¡jr7Èn~xrè¯ÜNƒGÐÒ)£%±ó¶Ø­ñˆ«”/|3{r#îImâÒ4c_Ö[Ü´„¶
+wÖõ†¶—€B˜Ûø£ÚoæžGX…ðˆjÜsK13[ÔÈÞ~/I Æ}ðÃù·åâ=5gÓý–ǪXÀ.ÑÜóVdI®­î!N°‰–—N}ˆƒ"S ‹ƒÔ…²3½d¶¼¬”ìÂøn8}:S€›¢%Éy¶²Š*cp£
+øY(cMÑJ(&S´RŒŠ ÆΧþ÷Åz¿,«j¤º}‚ƒ܈èƨ=âF …<‹–Ou¹ü˜s©ÕùqÜYàáòt8lç.HªÐå(ÌÎù ’L*5(脆QXv[>ùu Fš‰û à‚"z.ýªØ¯Û†~Õ+zŽû p.µR¾®ð;À‘uÌmS32ÞÉbi;ìd½T^ü_¨“éO2dN€âÙ¡ÖÏð·^5HS©\Ãî@™„]ê€o·«×‘uÔ.ËÒ|¤—Mò4uýNoiwdª“ã(8öÄKóŒN ²Öÿ¯uÇTNæP3•©ƒÂ™Jw®òX™ÉOÂ%Ò^‰•(™æCìyý˜l3àŽUÞŒaœëc*RâåÃÒI¦]Œo®"0üâÑ/Þã«›–+ˆÂ—zë7èÂöæª 5QQ«Àɉ͎Ãâ©\€Ó60Qmb¯‡]±Ù"B[Y5<\Ù( ‡xR’´»šýSl|ä—`´l¾àI¸/À+v£_„Ôðâ·~ƒdyZ¬Iv#
+ oÀN&çhxÉK¿L Él¯‚ÓbØ*8¶OE¹.æk?¶M9dhêìÇ·)U™nLáCsÐæ€dQï"ŠÖÕlï6 T:‡`C¨7oq÷R:B=—G8ÎD8o¡ÎÈ|%…*¬ÒQ st.ªŸ«!.AÚõ{‘^/þMæCø*¡ÜÒ›³VÛ·ôþŸ·ÃQãéõc¾<úöaã¶n¯6¸é¦xq%R”îÜ%2M‘j;¼ÏYÖìW¨Šy¼(á8·þ@ò5Õ‚‘"õýb¿+ÛOËÌôŠš ­0%vj¬\þËǶ­¯–<w]Ñó©Ø•õž…Ûb6æAÈIQ*´‘ÓùcøË3‚F+@ƒ5šbZ÷¢Þl| ¦ Qr ºmˆ üL׎c$’Ng†^y¯P •dñ¼$iNZÁa„ÛH´ðÈ)\ØžfÝÔôÈéHÎRâÈc
+z§éxú²ñz/x¾ 3bˆ-Š@»Gï Ò;Î#ñðOœ [“à°ñALÂçîÂm$2—H( [¬-=¤$khôúøÂ|鱜#¶¢„¼ è`ðŠžM½aId4p ëDúß‹Í–™ z!‡¤G„í§Û›`Š+ÆȆ~0+€·ªnéò¹~弬½;gžIY%\:X{E&Ì×>Öû8=Èqúí®|œ 1ˆŠ9Šb"-ØÎe^×tYÎÒEEoHB‘ñ…#ã#žAmP‚ÔÊâX+`~î +,ŸÚML){|®7¡ÈÑ¥ÒÕŽ¿~/€vú–špOQo½ÓT¼R0ú0þ<êV´°[æpG‘oבt
+—g³—›ËÿóÒôÿ¢–lìendstream
endobj
-1325 0 obj <<
+1340 0 obj <<
/Type /Page
-/Contents 1326 0 R
-/Resources 1324 0 R
+/Contents 1341 0 R
+/Resources 1339 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1323 0 R
+/Parent 1325 0 R
>> endobj
-1327 0 obj <<
-/D [1325 0 R /XYZ 56.6929 794.5015 null]
+1342 0 obj <<
+/D [1340 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1324 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R >>
-/XObject << /Im2 1049 0 R >>
+374 0 obj <<
+/D [1340 0 R /XYZ 56.6929 769.5949 null]
+>> endobj
+1343 0 obj <<
+/D [1340 0 R /XYZ 56.6929 748.5275 null]
+>> endobj
+1339 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1330 0 obj <<
-/Length 2839
-/Filter /FlateDecode
->>
-stream
-xÚÝZÝÛ6ß¿Âo•šå·ÈÇ4Ù䶸îæwm´¶¼bKŽ%goû×ß ‡’%¯ì$H€Š
-Ø[W‹©äÉü/oê)ÅNý¬}ʬ²j·Ø};jŸÆ[?™‘ÿ͘–– “~Y©`Ö
-õ5+ 3ôÙø0À ¼4Ÿ‰+=sR™ï Œ°Î›ï!}ÉBÄxɬ֔Ôßç
-Ã0§µ+ÆÂ),K!eqΓÿTeNer>B$aƒò}ÝÃj+.¥p¦Ê­¬MÖYMÄ6_¬³²¨·ñ½(é¹Ûd!§ÙTøL“U¶(¦rf“59 ýL Lá•2-2‰ØÛ¢‰_«¨„R(²o«C«UœPeKÒÒ¬³f,wöt¢7¢ÉH¢|HÔOu“o¡ýP
-ÕR\¤ñU4oM£‹j÷DaR´€åð9µð áš/Äbïb…v @LÑROÊq­ð‚~Ë—ÄÑÎèû!jº}? Êêdú¢
-Ï%
-'wiõeK:®S0t
-N
-öYá†Û\BT.O[Îc~6Ô;àSHND§²E„$r Ç£šv|(ö£Ø¶ôò)Ûò¡dé¢Úì©'Usu¢ñ2šxÊž/£©ÇuM-×(šŠåfMx³
-à(åºY¢C–0Áé¤ \¢k£D—8˜ë¥Ö¯/—=‡-qÄÖÿ ZÒÚ‹‹Ðês‡VÇu>QU‡æ¶ 
-j íÁES:®[†Ø‚º§ƒcîM—„þ=#ñ Ð;ÀÂk?UÉp¤
-ÜÔíªˆSSê¶^b/Ô}«ª(E‰û¿h¶’RÂH÷Hõ¸.@ªå:Ÿ­F!mԃ˦t\#¶ !…W¸é‰1GH)ÞBJq>ÈW\ó”¯à9’¯`bÈW¼ÅÍ ùŠ‹a¾â-¼
-ùŠx—D€Y–B „ü5r–€øIuª/¬Ïu`Wèãó}‘mfùþi¶ÇK¶S`YΤ·æ² ׈ `AŠ’)tU#Þo²Oè5%×Ru)†w`fµ,áp¾‹éã6«›°”èÏ—tÊ…g¸>ZÆN,V4S#é.²¨°<lïãýædf Sê´ÕZ“ÍÎ'x›ùP¦¥M®ñÈÆëCKµÆy÷PHeô íCñNR:º¦Â1:f£¸M§‘V9¥:ù!J+óæ±Ú —û¬\>ËfÍÆ®mæS/t ýpEŠd¼lÁ±Î
- ƒØ$´‰V÷NRŠö§Yàñ=‘õ‰Ì
-Ãê#ÀÈ0Ú!
-<âd:búÿ
+1346 0 obj <<
+/Length 2666
+/Filter /FlateDecode
+>>
+stream
+xÚÝZÝsÛ¸÷_¡·£f">Iâ1—8©ozvêè¦ÓÞÝ-Q'©ˆ”}¾¿¾»X€"eJN›tzÓÉL¸
+7òùâ—ßød Ûþñ‚3eS3y„gÂZ9Ù\h£˜ÑJ…™òâãÅß:½·né˜ÿ:°Œ)nÄ©’Ykô¸Z§¢X¬•=-‹ÖqåÉ°b(êp¼1PÆÈÃñJ5‚Y˜Ãóµœ%Ž51Î<¦ó½F;NËL¬2
+ÎŒ’`¹ã¸™ÎbÍá]ŸÈÔLK@Oª¤óÌäóD0®­UÄÔ£Ý^>pß_määm ;šô6Ïú’ݦbÙì ã‰6í,ž¯óéLKeËå.o¨¨Ùæ‹âWÎe¾¤·EEÏØbÕ—¬4‹ÁíÞ Ÿ÷ùPÌ£§YSïwSÉ£EXÖ7(N˜T:ø®Þ¶EíÕÞŽ} XMê îêvMÔÏo?gV-QÀŽƒ
+³|î*èùRš@³¥ã°ÖÃã*m!ªÏÑV¬^ªÏ€®Œ_q:<ú'üu ùöá1Ä¡äú
+È™mÖæ4õ‡3Å1uV¸!eZ eQ›¢õok¯„R(²oê}åë•_PgKÒÒ®³v,wöt¢7¼ÉH¢|RDóÔ´ù
+dXXªl“ÓL“ïFÒŸ<­¥•~€‰Ë14yå®oæWïþAô4d÷yã;qÈ7#¯Çu^å®úÃÕ·i|åÍ[Óì¢Þ>E˜°¼>§6^!\óå+,ö©"×t›ÀROÊa¯0@¿åKâëú¾óš®?Ž™¾¨Ýs À„Šd
+vîîH»½Amñ$êó¾X|€¡åº$ßû5Îð„-f%^šÜ€¶ÏÆ®7.³DbŽÃë‘6îÒ¡Ý}¨%j“=q—ÓspcĉÇÕ!•g‹µÏ‘ý(“œ3›hjÖ0¾Ž‚Â@½HM(þ=@“
+—)Њ¼òê)áE’ÕŸƒE™‡«‘,66oØrÁa+uŠVѤW'Ÿ¯²}XW4if>n£«½€eÏ!â”Iiâ/uDW\ÏK1’‹†TÞ¹·­¨h*Ñ õ*{Pé¢ê¹.©!]vÔ`ùÙ@Ü¿"±…×LXÄ™Pµ+–tm…ŒoHÇ°v„C$Puy2ø€P×¢ç¨cžL!­Äg©Œþ¾Fw(ÍGÝZ¦Ñ÷‚ÓyÚû1x„?ó­Â"í¦ê D[iÕÐòª®Ñ*°¼¢ï”@¨Ëëšåurº†˜†AíÒš€ðuã¹iÆ2¨SòË (™Jä
+ê"~”ªèگ˺º§K¿öù“(ú\€¥z¢•›¢Ú·¹ŸöhJ©Ò¸%ùnSÌ蜰/éíDåò¸å<ägC½>…äDt*"$‘k¸5tâCqpÅf¿¡ÁCVîó¡d™zµÙSOªæêHãy4‰®‘*}M=®3h
+\£h*–å8šb& \ÇÎZÒq˜2D“€ä’Ê¡-4‰Mbˆ&èøDHXÑé¹u¶×÷‡V
+¨?y¶J2(,/d«>×H®ÓÙjRÐ6A=8oJÇ5bËRø 792æ
+ž#ù
+º|Ŷh­ËW\ óðBÊå+îàå\â³²Ø` äÿ#gAˆKõRoÕc: ¯Àäšø|Wdå “{šíð Û1ªbΤÍYýÓs˜Š “ 4T} >–ÙúKÉÇ x’ LoÁÆzY,ܵܽsæÒËMÖ´.U)Ñ_/é~ O÷áhI µû&‹Mø¤Hº‹Ì+¬ö›;ÿes23†)uh²Uk²9µ~ǼwøÒ2Ž.ñ²ïæ›} ‚±@îúÉÓºO
+ð ƒ÷Sþk¤LéÎùßbA\Ùi¤]Ng‰Ž¾óÒª¼}¬wŸhp—UËÇbÙ®G¿p̧VFè(÷îã(’áG_˜ë¬
endobj
-1329 0 obj <<
+1345 0 obj <<
/Type /Page
-/Contents 1330 0 R
-/Resources 1328 0 R
+/Contents 1346 0 R
+/Resources 1344 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1323 0 R
+/Parent 1325 0 R
>> endobj
-1331 0 obj <<
-/D [1329 0 R /XYZ 85.0394 794.5015 null]
+1347 0 obj <<
+/D [1345 0 R /XYZ 85.0394 794.5015 null]
>> endobj
378 0 obj <<
-/D [1329 0 R /XYZ 85.0394 548.8286 null]
+/D [1345 0 R /XYZ 85.0394 460.4475 null]
>> endobj
-1071 0 obj <<
-/D [1329 0 R /XYZ 85.0394 526.2567 null]
+1076 0 obj <<
+/D [1345 0 R /XYZ 85.0394 437.5053 null]
>> endobj
-1328 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R >>
-/XObject << /Im2 1049 0 R >>
+1344 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1334 0 obj <<
-/Length 3252
-/Filter /FlateDecode
->>
-stream
-xÚµZÝsÛ6÷_¡·“g"_üÀcš8½t®i.uçf®í-Q6§©Š’÷¯¿ßbŠ”(Û™äÆ3ÆX‹Å~Cj"ñ§&I*R§Ý$sV$R%“ùúBNn1÷Ã…
-8³ˆ4ëc}}ñÝ;“Mœp©N'×ËÞZ¹y®&׋ߦ©Ðâ+È雟?¼{ÿïŸ^_fvzýþç—3Èé»÷ÿºbè‡O¯úéõ§Ë™Ê5}óÏׯ¯>ñTÖøþý‡·<â¸9³è§«wWŸ®>¼¹ºüãúÇ‹«ëî,ýó*iè ]üö‡œ,pì/¤0.O&èH¡œÓ“õ…MŒH¬1qduñËÅ¿»{³þÓ1þÙ$‰¶)8™
-°'îï4{]|®Öû5wêýúÆ{
-ožéƒgÅŽÙ‡Èq·ÎŽ #7hQ§§Õá¸åAÁ<°jŠÅPi{SóbÅ`ûˆ°h}V’ Q¼ÒöiêcW kÈøf·C摬ا·ï°FöʉY–dC¼YåD¨AVKi4ƒ
-QUˆ ž
-:«Mx"à&`öUˆPϨkN.T–yN2üF«î{¼Ä_û²ÝµQ ¸-?Ïô„û_ßµæ@VNªÕjhòyÍ%…Ò‚ýuüîàíÐ ì7Ó`ƒ$Qº.²z‘
-Ÿ“B˜>™9óŒö°žÂˆ5”ÂèÉêö4‰Ì…µF=ME‡5BÆ0‰4Â"óÒÁVò ŒÔ‰Â¨wù;Tò`ΩòHPO}÷Ž£ ‹4t0Odoðý6MÏÖ\'KŽ•ˆ>ÇA
-à–;ñ
-C±8Ž,œ\žb':ª÷A™¥Hòì(Àõ>Ï>CéŸYï30Ùõêà3t|«ã±w öSz‡Þ–*xB"ï0 ¦‰4Á—èIé]â)åPV^ÊD¸Ø¤é¹æè#7ƒ
-úaílúëÛ<Bù«a©Î××øi A®w<ˆ(g[1ÙéaO|«q½Å#,V5çùýfÍ¡¼ÝhjÉ(u³ž$*#—kBOwù}Ë=aÚj8vf—¿cç¸ZyB0À(z²xÚ·ûÀ,ÍÏïq€¡\j6/TJÚÝ]*_l\Õ¸Îe1ßü®µ¯šv6v:‰Ä,ÐÁa;X}L”5… xq}çÍ)p$Òz×,6›²ØòhU‡}îÂZõ ­ýÑZ‰J §Ñ ƒ9ÍìÓü‘r\&¬ÔÇaÚd*x`#œ‚¹ˆ,3Ù˜Aâ?×(0¸‡ÊGRaÒiµd„î#_èÀ
-5«¢{RãgzÀ('Ï ˆRÓ³)‘–”ègªÿ}¬'®.bq`²›½$-2ozó}’k„’áÝYa·¤¼&wœeDR¹­ aei¯LH“ƒw`ô)Ž¡–uèì¢1²ªZÿdæ±ê±DYAÓÒ,ÿRoœšøɲ¨Vm zôw²IeÝîí{FüŽofVäÎØñRóQ’ÉÓ¼%¡/wg½¤J¬0ÖfßÄKæT70î Œ]ü✗Ä2)ógœ¤²J(Ï·t’m.í·÷‘½…Ÿp‘Рiv‘ïýÛŠœ>’ÏiöÜYP)Lªàý$%õ”G^j$« Á4è MB†èÝ»õÎÎëVé\"a4ÜÞ„>å±T’“é‚ö®Ù¯.ÃÓkjÎ×Ë¢ ³0Ø z&
-õ'JÓ3b4±HöÍ&D 8e—V³¦ÑÏs@#½h ÁÙóD$“`Ï,妬Ãà~ÓÔ±œ¶¤R·1ˆ ÷ï‹Í¾m‰á~즡ïùT:‹õ‡Œ0±¥l’:[$ÿœø£C‰?ñ‘h3ÏÇ=}ø: û„ôx›ÂÝ°tüçprûÕ¿Ð;ü|I HÓã>…BR›DÒ‰ÀZ|£I~êP%½AÐzÄÿ.:Xendstream
+1350 0 obj <<
+/Length 3385
+/Filter /FlateDecode
+>>
+stream
+xÚ­ZÝoã6Ï_á·s€5+~Iâãv7ÛÛÃu»·MqÀµ}Pl9jK©e'Mÿúû ‡”%YN²haÀâÇÎ÷Œ$g ~rfS‘:åf™3Â&ÒΖۋdv‹¹ï.d€YD EêÛë‹o>èlæ„KU:»^÷öÊE’çrv½úyž
+%.±C2÷ç¿ûéËÛËÌ̯?þðér¡l2ÿðñßWÜúîËÛï¿ûår!s+çïþùöóõÕžJÃß~üôžG?ÎlúåêÃÕ—«Oï®.½þ×ÅÕuw—þ}e¢é"¿_üük2[áÚÿºH„v¹=¢“霚m/ŒÕ­ãÈæâÇ‹ÿtöfýÒIúÉD(ª *Ý#`.…uÎÎ2ëDª1ElÖ¸R¢æû»’.ƒ%²·D¥XBh[îªb³øýPîž»bôÏÈ2¡R4÷ûª©ßà
+d[üQm[îÔ‡í À=DD–P¨Ê°¬-ë=ßG¸¶\6õ
+LUlã›Í`ˆÈ­… I)œµÊ#¹*×Åa³gÆzTðT‰8a­™”é,“Vè\egXÁ@‹>sBN‰r„‘—î6:^Ê\¤/œ`&ï³H*-R#õðôÄå¢
+¨|ž{´>#©‰–ù©hÜG‡¦F(cÌ@0øÀ¶ÜóyÌ~ŒÙÑŽý˜ðìǘ»<ìv—2Ÿ3ïý6„A·fXžIAX8î÷Ó:?Š‘Ön^l6Íc¹â™}ÃÏ›’ŸÍaßî‹zUÕ·zÏEýÄÛꡬyn_mK2(™ Ô¤yÇUÃçÉfÏà›j[…Ý< üd¸5ÍãÖt—$^‚ ß
+Lñ‹n¬ª5Ý$\¨勵o¦|—ÎDîLô^Àc±Á)Ë,ü¦´”4fJ/DžÀA3Ìšö›T
+ WÓ)…`16p§(òõ´Ø9ØË¡3¼Ëü{šŸØX›·–°,÷0ha&èPŽû@Uw !à6[Bz®JLo«:€³rz耞àåª÷Ò’˜’÷xH“ä$êv¨ágù¥÷Q|ÅÛàZdTýµÈ€©÷Ÿ~ä‘mÙ¶Åmõ3Ø|cYöG—l$W¼$’žçVSwRÐ?ào^)Ni£=¹/–¿Ü‹–O¤õLÄtp²F ‰rŠ»’Ù÷–‹ð¼oÚ¶ºÙPD`M˜çG ‘˜”C%k¿Vê™KípNß6IF¯ôzLFxYA½oÐó›Ã> 5õæ‰[íáþ¾ÙíËUði ²r¨E7ä†eÈ°)öpÇ´Nܼ.y²Ýehz‡ÝXhßy a¦qÏ„$†A4â<LçÊ1—‹?0yVjçŒpÂò`S?p‡&wgT];[aò>‰ÿyÆM)ÅùµCbÔ‰V§—t·ü,6-±>Ñ=ªú ¢=ƒu!õ÷ÕÒ5m³Cÿ½´2´j[Þª. @LÏ^ÈíaÁ5#1q{°3KùnŸ‰$K²¾ÉûIa3÷Õ6Õ8);ìž8V¸ ñEƒKïªÕª¬C?< ~܇íK‹6f7O¯ BÝ mw B¦Í"rÈ´K¿îË-Xy6ø@fIq•y>øèC>:¨>qÛEUŸD |±óÙÓ;¨‰ãQ‡4”üÚáù^
+ª¯„q{_úD
+ÍÃ==CœO ÏkÅmY/àg- Mb…7Ï€ôÎÁ“bÒ:gÁk•L7hQ§§ÕñºåQÁ|cÓ«¡Òö¦–>“¢â aÑö¬™<νT èCW jHx$z§µ
+±æäBf©rž“ ÏÃhÕ}·@²ÖîÛ(ü,ÿX"è ü_ùÏ95«ÍfhòyÏ5…Ò‚ýu\7(% U¥S ÖV#Íî"«W©ð9)4
+§V/Haê)ŒPC)Œž¬>-L©\£åóXtPh “H- 2Ÿ!La™ôJCè+ƒ¡4$“£9§Ë"µz²è»wY¤¡›
+ –;ñ
+C±ÇNN.ϱ]Õ{‡ Ì‰°ù¸®ã}† õ`-Õ„Ï\ ¦É.¨—GŸ¡²à3¨º¼g8ö4Â~Jª‘wè)ƒw òlúL¤ f¢G¥ÇÄSŽ
+x¯%"\¬í…Ç„z®8úÈõ
+„æ_e†S’ø®ŠûæXšºE¤?O
+[S_9À•Ð Œ‰o¥¦gS"*±Û,±/°®õ ë"&ûÅkÒ"5ôÎ÷YD:¨ L†¼3Â8˜ì*oÉg¡Tîjÿ‰ÎÒ^™&ïѧ8†ž¬ó
endobj
-1333 0 obj <<
+1349 0 obj <<
/Type /Page
-/Contents 1334 0 R
-/Resources 1332 0 R
+/Contents 1350 0 R
+/Resources 1348 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1323 0 R
+/Parent 1325 0 R
>> endobj
-1335 0 obj <<
-/D [1333 0 R /XYZ 56.6929 794.5015 null]
+1351 0 obj <<
+/D [1349 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1332 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R >>
-/XObject << /Im2 1049 0 R >>
+1348 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F62 1065 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1338 0 obj <<
-/Length 3258
-/Filter /FlateDecode
->>
-stream
-xÚ¥Z_sÛ6÷§Ð[噈Å‚—§4urî´NÎQnÚ>ÐesB‘ªHYu:÷Ýo P¤Ùé$™1A`±X,v» ŠOüç«&35I3•hÆõd±¾`“{{Á=Í,͆T?Ì/¾'ÓI–dF˜É|5àef-ŸÌ—¿MßþûÍÇùÕíåLh65ÉåL6ýáúæGêÉèñöÃÍ»ë÷¿Þ¾¹LÕt~ýᆺo¯Þ]Ý^ݼ½ºœq«9̞Ù ﮾¢ÖûÛ7¿üòæöòùOWó~/Ãýr&q#^üö›,aÛ?]°DfVOöðžeb²¾PZ&ZIzª‹OÿéFÝÔ˜þ”¶‰ÊLfZ$™Ui\Ë,a´6KO47¶×²à1-*Ôr^u³n›×íªØ^r;µÍn»(fæXÜòÄdf2\äD”@EDáÖ$&MåX–75œ@ÊP¦b[ç]A¯½xî åCAn”OË•§zðäMíUÙvÅ’ÚeÛ9Rˆ`6ᜠ—?¯†#é­JWaÚ*/«Ö ^/#Ë(–蔥ž|×3$‚ÃeYbE
-ÞÁy’i-ž;˜:‘,“žoÙ’ù¶E—œØ®7“e‰ÊXö¼ ©Î[QO6õŒàc3‚£7pôÏ
-ÓSE¤Rö¦¬‹ók‹&`­7
-›L
-û&ƒ“ji¸ñuºœ)¡§×+y,‹}ëYº9ža»)åïŒ gp0Ú=”žÙ²X廪ó³º&b!3ðš”AÛ[`ÝDúð`K ìo»/ÝnáèËŽžƒá-º" X’ŠL{FO°óÈZi¢¤
-4¿3ÍVN3zˆÃ–‹f½É»ò®¬Êî Hùy#ÔÀÖÀŸ7ÂÕ3F¨H_]¹z:gv
-¼Åýüò=Õ ës  ­¤}A€#}™Hm¸×ç²
-I¡4+$XÙÑbB%,Í‚h°óÈiòÄÓ)#ÊLj4}€ñÙÇ€Ú£þC€¹Æ¸t¿ÛæÔ‰=UqÑ2’ §SHŒÒìkr\i]Ênã9.ƒD3=ú,/šÇ€—o†cV³ Ü ê¨%ÀÜA¯zÔŸÝ@ª¬‚ 6u*º(8ÁDË?>
-6ýŒÕ@¨+TÀ²4r2<èo³ie† u(¶¾Í²g’wœ¡Ggò¹lMš&Œ«겞êµbÕÁ
-€MU÷ô±ÓµC~j›ºÓ^Õ«CÂéH¨¹á‰Ð{²1ù%›nHc9cŒ’&ä÷’&jý ud¬ZhPhfûªçQÍvËÍ S¬Xê‘bzh³~û‘êÐÞ†Ü$lÊåK<Á–ÔŸ_ËÓIiþ‘”3!³3Å,š»UGò>ÏÝBÊ“±ó\¥äŽW—À+uléi³¢8Wåó £“,cÇU2B›6€ÈüÉAÉášÝCÞQ‹_¤s©
-ôPŠ‹-—€ÀÓA!’†rÏhtë
-ô³á„S?>åë‚D±ð¡„óö~(³d+Ò‘H'€ÒS½ HÀ4‰·e&Ú]ÿ¡Ùå)ùc^Vù]å_ƒ‚q¤/´]m뫦%j—³é»P’åëMUxˆÁÄíh…Uƒ©9¥Ž‘ÄÈ®Ú:¸»OÁv£Ž43
-Ieƒjâø Lm*Í?Ä_`âr3Á8á ìi {6äpxê§dRèCü?wÌPU±ô{³që,š¦%?„ÕÄBoéü:à@—da©ÁtE–Žl„ƊИZP”tø
-„Â0½©+¿²;Š8Œ/Õ^„
-Eùf»‹¼
-Ùóc^í´C‡/Á‰*›î
-ÏÑרˆ˃ë ZSme %ƒ‚IŸ F"(×ýµûò©L*‡!׺ókúÛqh•5è+÷/ ÎØ—‘ÈÕg©L·BÅ.‡ÑéXð&‡pÀ¶¯˜ð%욶êò#\½öÒÝ—÷ùÝSWD‹`ÉTbGÈTûCŒ¥Ò$åýçK:
-G|¡ÚÓR)„=eÛî²c{°^d;»Ú RŽ
+1354 0 obj <<
+/Length 3017
+/Filter /FlateDecode
+>>
+stream
+xÚÅZÝ“›Fß¿BoÇV2ßÀùÉqÖ¾M9kßzýp•ä ´¢Œ@håêþ÷ëžžA !¯SÎÕ%U¦™izzzúã×£å3ÿóY¢#&S5‹SiÆõl±¾b³G˜{{ÅOè™Â!×÷Wß½‘ñ,R#Ììa9•D,Iøì!ÿ9xýWnî¯C¡Y`¢ëP|{÷¤ôxýþîÍíÛO÷¯®c<ܾ¿£áû›77÷7w¯o®Cžhß 'áÂonßÝõöþÕO?½º¿þõáÇ«›‡~/Ãýr&q#¿]ýü+›å°í¯X$ÓDÏöðÂ"ž¦b¶¾RZFZIéGª«Wÿìfí§SöS"‰Œ4ñ 4‹$Óük–•‰µb2½,ƒS‘‘Q2½,‹¾c Ë‘þ‹±¨38Cef¡ëh-ŽÇ+äŒó(…1<_Îud„Šg±Öpè†øMlYÓHÅ-'‹´
+Ä#ÇûëÐðàþÁÍé P)t2‹a¥D
+k›Ùo31•¦’¸´ÝíÑ
+và»Ûµ˜ýÐÀžfÃmyÉáP´Ý—·å¶˜0Ð@2`SVçÛåu( ׂÍŽ^òŸ<¨›Žöe»"ª[DdUWlу:ëÜX·½æ0S·ËkÉœF)m³Û.<GCϹ{ßµEþI3Ö ]5»*wtÑ‘éì†áÆÝ‘Á>@P*…ÝÖ.Ïíò 0ÄÕ‘
+¥±–ÓÙ›E £À'ñ1ºùDòî¹ìÁ÷žÆâ yÍ¢ŸÌY'öffÃEÎ4ñLª ]˜'&2q,Ǻ¼²^àŒb _{õì›õjPtagyP.×ʱ7µ#ª²íŠœè²v9lhÁ’ˆƒwº¸l†í)®ügˬ¬Z§88ÿù2
+ReÌ|¤a¸R\(HʉˆÕ8œ/È”XilÎÄïÊ–ª"äŒ3O'ÿà3ÃãH *—ˆ!×¼Èsç 3ÅÇnGoð迤LÏ5¡ÍÈ‘Rð7•˜±:ŸZtÄg‰$¹Ž]
+&.ÕÒtã& ±E˜Í´-8óTûÖ‰´ß8í¦X”˜Š¬ÃÁl·*°¼Xf»ªs_Aþ:÷¢&f@<¡n&¨áÞ—Øß*TAG_vô¬¨ÙôŠ
+œØÓÈHjÃ=ó\r]Öèt’©`¿*jè jYE£Ãt‡SYž“ßµ-¢žP‰FÖfÓ•MUX»ñýÓè›M³í󾬜àyáª3z‚†Rv
+*Pª¡‚‹ÏÖVv€¸ÁÝû‡Û7ÿ¢Ñ5è‘=-„‰12x°^=ç‹´ÚlŠlK4äe+“À.SeOž,¶O¢
+ªIjûÕ¿°‰UÒ@ ù?ha‚¿ÐÀ*•Dq
+ì¨ðǦÊ\Ëf“lˆHGœH* @Ž§*m;#yS8~jshw› Æ¡Ïq#¾?מÓcG‹+@Šwé= lßKþ|Ú >¼þ@ÁÔ6®“ƒ0¥R—›²á!›ßüŸ›2™Šˆ«äË@Æ1ñóŒ5Õ‰A RVÿÕ$–ñ\ámBö =Òá]ùy*Û
+n£‡(˜pä˜wqœò.Ž/íY4ë)Ì
+¥W$ý]T­‹|ªÃJc<—ëE…»‡l›%ÜÞP9¨ÃñqÜš¥ý;àͽí‘Í6­0/Søï%hOÅÇnÎ
+~éJC‰(bœg¦Â¶§¸M·-ÉíË6¾8³ïê<³~ C6ÑsÑplÛ/Ýñ®ŠÃX%p z%é86èhš§2/r_ê(˜g‹Ï{’O\RŸ$xŸÕ7MÛ–óÊM·%àŠ¾#éáĦoú‹
+í å`¢éH]Óñ~S ñÈäã¡íŠµûۈ·ÛÔŠ¬ËÉ#>éLVäŽïOîÍݬEÛ€f×Y}pü~i Ã~a* @x ]¡R„Çí.²Ê£ç§¬ÚùÏŽ(_°‚WìW…“èz4ÄD
+<Õ×´:Bme AüÕ½ƒJ×ý;õ«B™XK&®5wkº›q Ê앹0çÔ¯,"’Çë>Îb+ž5u1ŒAÇ|4Ñ_ ˆcÇ„/Ù`×´U‹põÚi÷X>fóCw~µ×ƒr៲Là{Öß¡}ó_ÌÿœHÅ‘L1Ý(H½7x§”~¹99Sý¿ÓCendstream
endobj
-1337 0 obj <<
+1353 0 obj <<
/Type /Page
-/Contents 1338 0 R
-/Resources 1336 0 R
+/Contents 1354 0 R
+/Resources 1352 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1323 0 R
-/Annots [ 1341 0 R 1343 0 R ]
+/Parent 1359 0 R
+/Annots [ 1357 0 R ]
>> endobj
-1341 0 obj <<
+1357 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [471.1233 402.3147 539.579 414.3744]
+/Rect [471.1233 313.2012 539.579 325.2608]
/Subtype /Link
/A << /S /GoTo /D (query_address) >>
>> endobj
-1343 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [389.4645 133.6118 438.2112 145.6714]
-/Subtype /Link
-/A << /S /GoTo /D (configuration_file_elements) >>
->> endobj
-1339 0 obj <<
-/D [1337 0 R /XYZ 85.0394 794.5015 null]
+1355 0 obj <<
+/D [1353 0 R /XYZ 85.0394 794.5015 null]
>> endobj
382 0 obj <<
-/D [1337 0 R /XYZ 85.0394 458.5915 null]
+/D [1353 0 R /XYZ 85.0394 371.6561 null]
>> endobj
-1340 0 obj <<
-/D [1337 0 R /XYZ 85.0394 436.0118 null]
+1356 0 obj <<
+/D [1353 0 R /XYZ 85.0394 347.7805 null]
>> endobj
386 0 obj <<
-/D [1337 0 R /XYZ 85.0394 213.7989 null]
+/D [1353 0 R /XYZ 85.0394 119.9702 null]
>> endobj
-1342 0 obj <<
-/D [1337 0 R /XYZ 85.0394 188.7485 null]
+1358 0 obj <<
+/D [1353 0 R /XYZ 85.0394 93.6238 null]
>> endobj
-1336 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F41 935 0 R >>
-/XObject << /Im2 1049 0 R >>
+1352 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R /F41 940 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1346 0 obj <<
-/Length 3419
-/Filter /FlateDecode
->>
-stream
-xÚ¥]sÛ6òÝ¿ÂoGÏT,@
-=õÕÇ«'£~êÒùicc“èNWM’åS–q&% eiåj8åD.rÀÂSÞ}ÑU¹Svsg)\Ҕ䳅ÒÂÂj²0Üj¦œ/|÷ààÄsíŠ/ÕF±kMOp»Å¯ð[dT·kO÷a~çŸÝ!ÐâÑcçàâµJÆu6n[k¦]uÈð·ïôô€”~òÌ
-ùãìCQu<ð[8₶ÝSÂFC¬¯
-å²eü]áÅ÷óDc¬„1JLŠò¾pwOíERÖ¡<hùCOX»¼ð@ß`c Ó 7ô J
->óòÊiaå)“ Å©f¾4(Èóx«ÐŒ
-á ÁŽþ'’2À¾Ày¸d\Ð•î¸ ¾×S)x v¾´ˆkØs—Þ?ÂpÕôîЀGy¢6Xóç±x»àÚ ë5'‚0u~8Ó;¿³J¥!þµ Ú—•jŠu^©¬àNª/[ÏõªnïWK
-&!¨ÕJëËÛ°ö1S1ec-Apg¡ÐWåj ’r’°oݵµëÝß!fMµ=¦ÃEYº}ï/ [͆‡ïŽÄx¯×”Ê!Ž¥Ž²Ýíá:ÖU]õƒ-ÍÀöÞqX„y¨•§8ïõ¹J)+‘Lö¿A_@’κm8 3Øa>Ù‹,# uÁ"µ=6%ÇÆÞÏÒw’¢ž—%câÔf/øÜ)ÖY
-Xç¸<#a^Ø@@ZØÀ© p^ó|tÞ^hdøì56(”Dˆä
-zÂ
-žôš¥ÊÎÍÇÚ=5nÃr¡ì*ŸÖæ„b6ìÔœØ3…G©òØæ2dá°/X’DŹzRuIôÚ•!€8yD„&çà£Ôaw4 3:‚
-ÜÕ:ÖU?åj(ºbXå¸F¦
-²ij…Î
-œxÊJ’ÁÇîDPûSU·ë§ÞuXiS&ÌË¢ÏE} $¶Ôµ\]‘ƒQ‘>+…œ/wdDjI>+wÐRÞãZ”°c*7ö¬¹½q%kA58dŠ"I!áJÕ‰’£é‚Œõ,ì*¦y&Ŭg´=ɱlþBN>A:¯ëÉ_S¹?«ä@dÂåK+HÏ—žçäc3[û.Ôq'µÿtÔp€©èœžj8ô b ðÝ›_¸³m7„ ùPdkÆÙ¬f<–£)ûˆù3|~š+úWDiNI›Q‹PfqéêK…˜DgÃÁ^._úë­,R›U×–ŸÜ²ÏÍåõgaùSãž+©æëûã„Ði¸m-鶱/„îC0Xª}ß:êà
-ß=Mó™
-9èàrLÎ*k6‰ÝÇ-¯ª Uâ48­³µZH¤À}§ZÎ%J&vÉÓ ŸÔä
-ío%`ÀÑà÷EïîŸh€Ê ÀÂŒ(23>ÈÂ4Rp‹-#áë¿ÛP]$ÑÑ+B vÆðOà+æ|º]àë~b@ó]Ñ Í^¬¹û¾–ÏO ;Ǻ¾†£^î}Ð ]Tñnw„Ír&Ãí"Ø6¾èÐ#K’Ç«DàîîG^j¼_SÑ+8_úÇQfˆ&}rO¼O¶²vþX2Ì‹¡ ô?Ž©£r6q2ýI ö†tˆƒ]*Y­CýØtÕ}CEr飌{w`‚h£Å2w—ÿC;ŽS’…_e¨ðs$Ô„ZFØû<Í¡ŒÉ†z"
-nºq] UðŒî¸ß·nìÚA8lx›AH%ô]Ó«“¥"Ÿ¬’ÚøûU&Üô¢ÎíÛ®ê+J>”š½"B¼,Œ'?½¦.° °ûš”0ê“7 ©†¶g:í@%¦ž÷L· f°:ØE$öbJTíë°ÅÊ=R-ÎýdPv•Ûš,_aÜh2êðÒÙž<tƒ9©¹p \ø„ã¥ò©ÿŠøÜꔉñWp  þøbþïÛ¿D„dDY{&[…¨ Â¦üKªx < õ}¾õÿ
+1362 0 obj <<
+/Length 3265
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ZKsã6¾ûWè¹jĈÉÚÓÌÄ3;©d’µµ•C6Š‚lîP¤"Rvœ_Ÿn4@‚%e²år&ºtý øŒÁŸ)é,ÎfI&#ŸšÛ6{„¹7ÜÑ,<Ñ"¤z·¼ùÇ‘̲(Ó±ž-7ÁZiÄҔϖë_æ:Š£[XÍßÿøùçÿ¹{›ÈùòÓŸo±b󟾿£ÖÇû·?üðöþvÁSÅçïÿõö§åÝ=Mi·Æ»OŸ¿¥‘Œg½¿ûpw÷ùýÝí¯Ëïnî–ý^Âýr&p#¿Ýüò+›­aÛßÝ°Hd©š½@‡E<ËâÙöF*))„©nnþÝ/ÌÚW'ϳ(:ž8À˜O Ê"-baðPWå¶ìÌ·/ˆà™D g pAÊý-Oçæ·ƒi»ŽA¨à]ê¶æ ¶Òy³§‘îÉPc›ÿ^n[êäÏyYå«ÊÍåÛæPw‘ã
+k¥Z*'ÀÚlòCÕM*d”¥©§9Ú#þVN?–»ÖKîÈÊל-„„ãÓ t ΣL©Ø.·iìÎ CwÿòdjjÑêÐhÍþÙìÝ´]»|Gš%8›?sôÒڴžÜueã–k6SG X¤Dâ·Ö–˜c±žÌ¸/$ü¯h]Œ–NëÜ¢_q.yªP"N#35p¶2îL1qGqI¦2·:òÑ6tq.Åh4¹œQã>Ðúž~BÈ‘nœ¬‹üL1œ¼Žø±4’¥ z©Isby=ÕNWC"§u
+L”­Ë"Å9M.Iu¨_U5/eýHÝÆjŒU\ Š×ùQ³Ï»ž¨}m;³¥6™mÛ-†7­A´žÃžçYç[ã98Õ†Ñ]¡)LÛ¢V39h<Ý
+M‹ûðö%ƒc “?ÚÍI5ÿ´¡1wáKºt€3»[8ªÖQ5n0»È;÷J¸véx›ßG<=·¯#ü´¢¿AÈM¼Ú³ '}‚4lm ¼²Ô)+%‚"Žº‹ÓN=ï{תLþìVí—¶©ð\´† =ïÁol©óíç‡á­²0ÑÔ.@MÈê]@…Á¢ÈíݹómÔöc{ºDS½RÔns@ìÖbž;šœ/¹£±þB;7A˜¯½÷@rg!©¿"ÇbM Vpµ¯Ô<ã Ü1Av`Cßl¾:¸è’âM=/òš¸˜¡&qÀ–=N Þçeë&=ýȧ«À§ko¯Ðr†¸ºq5¹# z›ÆÑos«&(Ï+Í9#´.]£¾OÜÝks
+éh=œË¤é~)–þúðP¥L¥'<<:nÈ" ÏÕZ¡íC.è¾ôÄ!ud· Φøƒì÷6áò%ƒï)Ù:å ('Qœ¢ˆ³0ム{@ œ³6|g)jëü
+þE¿q/öi x¡>Ä °”pçyí*¹ã‘û(™˜º/„¬iº¬;³¯ÁŸ¼R°|ÂuLÞ-8¶'ß~Ç•Ðõá›Öõ5)¸‘H¥ìŠI…TçMª§òΤü}cw½¨šÇÅ”yqi¥ò²=Õ„# “Ôv$¾"Cˆ”¹ ÇVmS™Îü"V-màNçEav6Wµ½zí¦k‡¹[ÀUA‘&¥¢Ùîà:VeUv=’&€¼Ka 7åC®n $),]öÿÀZ@“Î:í4JUÂ.ôlG)e öPåN¥6‡:(ï”îTwÏë’’WÙ•,0¤º KžêÜ.Õˆ©+x¢ Ž•ˆëKð`,^H{døèÑ;Hb‹ô
+WEÃAërÃךjmÚÎ îóºÍ ŠÂˆ5’¼—;.¹„ÖÊM燮Ù(ÿ'pŸ°eÛ<÷5ð¯ðÞœ%ƒÙ߈»+_ˆë£ˆ¼jj­z‡ä£“z%;ÊS4µ£\åmٞŌ«/i¬.cFHu3z*ÜÌSÓv ™º²…ƒn`°'°!Y”$:½,DO5!Å8¤Š•ò±ŸðxtêñS'óµ-‰Ml‰„´C$¨ƒø^»tž¸7š6H3¯ïKZ0¡,WnÝ/àÊ"ÊÈ?7™F+LÕØ‚Êí®2[XËi¿Æ ÄJEBó+^ ¤ºp£žjœKùâØ €oLa¡‹"ôT2Œ†Y!ÇBL…ë|¸¤0\‡éªËkÓZ¢"«v›pÕï¦ùrص£Ž¿‰zi¹ª4î³ h¢E:†•yÊ+ÃÕÿcÀUwfX™cÂm# á$=Svä"‹ÒŒûÃõ©/T"Ê8“AÍ‘Åów¦È©‹“GÄVp6Jí¥£i÷ Z9MnòrO«² wÕ—\1¬² žöõ€†§cÍ&ŸÂíWV,oâ) N€Ã1£þ—²jV¯Áï  ʼnç¼:ø%644][á)£LŸBÎ;’"µ8;ˆ•bäEé:¡qãÈÊõצ sÍ©‡›rGkH·´Pc%Ai½ŽuOÁ×oõÁážµvÜ&‹3qÙÚCªóÖÞSÙ›*vgíbˆ„AÄ|‘yO5Á}œ–§‘N5f¿ôµÜ þ¯;‡6žõ±ÃH¯ÌÐ^¾ÿÉ 6umú !ë CÝ8Õ‡’4å îƒ'¤¼,=Rꯈ t ‰Qÿ£
+õ€Cžÿ†ºm·.l«dnºðÒUyYÖƬ] Ÿ+CK®ÊGýà–?‚~S7‡G4f)ÉÿKLAI«pȪ
+4zM†y«É0fk›¼0í$žÅQ–%ð+÷TD‰©zÌ}zZAlb¬ÂÃòMýfb] * {ÇqdõÇÉCIɼfænÝc-EŠ~„6.ýG÷çrmˆ€úÍÖ¥<ÆŸ`ð±5¹/úpå‡î±qŸ¼!Cã·ƒq!–ýÞà¾E”5$ú=±‹~ñs& ³oÝ'W?ÕaýTŸ©Â1 ™hïxÏkDðC‘À«¬}¥X{×u¶^ é8q-ùX£xœNù{†A”>À{(“!lʳTgB ža{Xú +ú
endobj
-1345 0 obj <<
+1361 0 obj <<
/Type /Page
-/Contents 1346 0 R
-/Resources 1344 0 R
+/Contents 1362 0 R
+/Resources 1360 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1323 0 R
-/Annots [ 1349 0 R ]
+/Parent 1359 0 R
+/Annots [ 1364 0 R 1366 0 R ]
>> endobj
-1349 0 obj <<
+1364 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [361.118 743.8714 409.8647 755.9311]
+/Subtype /Link
+/A << /S /GoTo /D (configuration_file_elements) >>
+>> endobj
+1366 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [347.1258 451.8816 404.2417 463.9413]
+/Rect [347.1258 350.3535 404.2417 362.4131]
/Subtype /Link
/A << /S /GoTo /D (journal) >>
>> endobj
-1347 0 obj <<
-/D [1345 0 R /XYZ 56.6929 794.5015 null]
+1363 0 obj <<
+/D [1361 0 R /XYZ 56.6929 794.5015 null]
>> endobj
390 0 obj <<
-/D [1345 0 R /XYZ 56.6929 585.2486 null]
+/D [1361 0 R /XYZ 56.6929 484.9636 null]
>> endobj
-1348 0 obj <<
-/D [1345 0 R /XYZ 56.6929 561.0275 null]
+1365 0 obj <<
+/D [1361 0 R /XYZ 56.6929 460.3339 null]
>> endobj
-1344 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R >>
+1360 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1352 0 obj <<
-/Length 2983
+1369 0 obj <<
+/Length 3381
/Filter /FlateDecode
>>
stream
-xÚ­]sÛ6òÝ¿B÷tòLÄà‹$8yrS§çNëä\ß½´}€%Èâ„"‘²£ëÜ¿],@¥t¦7”‹Åb±Xì'd>aðŸè4a²P“¼PIÊx:™¯¯Øäæ~¸âžfˆf1ÕwWo?È|R$E&²Éã2⥦5Ÿ<.~¾ÿÇͧÇÛ‡ë™HÙ4K®giƦßÝÝO˜‚>ï?Þ¸ûá_7×¹š>Þ}¼'ôÃí‡Û‡Ûû÷·×3®Së…çpfÁ‡»Ÿn úááæçŸo®üñêö±?K|^Î$äËÕ¯¿³ÉŽýãKd¡ÓÉ+ X‹BLÖW*•Iª¤ ˜êê—«ö £Y·tL*ÕI*T6™±H¹×2KX
-Z›åŠã½–Ór B-wóͬ*ÛÎÖ³/;»³ÇÇæi‘𜓘÷‰=Õˆ2g ¼PWöz&U1%A&ifnda7Ý
-®/cú@»°K³«:˜zAÀº¬ËõnMëÊ–Ò¯½[Ò¸ <>Ûmm+‚ÛÝfÓl»––" hô®Á2 GäI‘¦Â læs (u>ý1QuvëGB¨…éÌöšë©5‹="hª[9y
-ÐóÙû:R²æ S÷+ tí:Ûb¬’¹Ot¸aAŸÚ
-ÇÎBÉ[¦ä°@·±-]<“Šò? )µPÛ×ʃ‹²7/6m×ÛSKc¼š b/储Jîyâ%ªªy œž<…oߎӅÖP¢A«MFéØÔ£#ÐLóèJÐZÞPDrÕÑ0Hµ]³!ˆvê‹—PnÄ禨gºP±¼øð÷L±wx5T+ŸyJˆ$Sâ1/¦:óz*<vÛÁq±2l/=&³oÑSHqöÏĸ7؃ʨþpp/ŽûVfž<uÕ<?; aú|ù^¤‰,DXgN<RÀg2= rJK_$°C‘@ZÏTäùЬB-›1Œœ…
-åÍà#||úÿÓÛÕ
-l>êç–Ðþ ÑöËÎTø6’r_!±%ʾ ä|Õ4­õ, }j0qö@IïqˆÃœ½'ÔáÙ£_-|]è]Æñ©ˆ{‹%FÁ§%6D`üß‹Ã "¤€—Óc<qhHåòúž¦æ¬ óž¾kmµÄæJõåqºûËÒ"¼Ètç/H)¸å(ò;›÷ûA‘g>[/©GöãTYÜß,¨dš)Y@œ=/¶øÐ90f®›É?0xñEëv gÇSëæ\$Šƒ¿*—ÆL7_H¨X’i&þ†ßPA›”| ¡3ÌÓ[äy’Cì ÷àž«dNU–·E÷¼¸.Ìá7sïa0lñ•Éõý08”[³4çÓ[Zq`H³
-ꈊ֒›à„­‚á k¿•iÛò¹¶^¿TÁ6ÁôÖ5˳Š"=´”û¦žÕöÙ?Æ Ø#_ˆÑϤmhXòÉ´a™«Æ…«üË-¡6M[RKN ‚{÷T®¢/K×–ôŶ`„“Ond9,Û±8áœWj¿؃ÈÛŽpcåçt/EÆ"úU³¥ßZb.ÑÑ¥‡‘Xýu¯Öýš$¥ßÅ[E´Œî-.:Þþ zYô'¼//%öJcoÑ}‹~›¨Cl|Wƒ7çxÅP0å¾"ŠÃþ¼T¶áØÉú&þ¥ f±ðoXžÚ¦¼!Ñ£°Œ i¬‰]•¨‡¸]Æ|S‡~hªÉÈŒC3äŸaÉ ;¨`[çÆÌ< _Ú~ïGö«ÁÒå E ŇɘëDjÁ‡Ya–A&ÿÃZȤÀŸxGçì­~7¦“¿q(ä[¡Þ™ÃÄhÞòì $rrÐßù·û±iò´–ˆÅ;²-}N¦—8×qòð ÎèëŸÄtÝ8Ãw€eÚj¤À¶¿+ ¸È4m& °Ù5ýxKDš&ø(°Ó%Ù€R[%§…R)¶[Ñ4‰ €ýŠ¿)ÒëPbAtTÑcNE•T8ƒ˜NÔÐáãîÞöaMéytÿut¦Êš`ðo½ ¶IÎý}L%åèÏìl,ë/ÿñÁá/3éZ‹ñ>‹c-Š¼—Ê•¿üXöTê$Õ"þÔüendstream
+xÚ­Ërã6òî¯Ðm媃'G'ñdJ&³Ž³{Èæ@KÅŠÔˆ”=Ê×o7ºÁ‡DiR•-W™F£Ñhô €äLÀŸœ¥6:3³$3‘ÒΖÛ1{¾n$Ó,ÑbHõíÓÍ7ïu2Ë¢,Vñìi=à•F"Måìiõûü»Þ}|º¼](+æqt»°±˜ûðá{Âdôùî—ï~øíñî61ó§‡_>úñþýýãý‡ïîo2µÆ+æpaÀû‡Ÿî úáñîçŸïoÿxúñæþ©[Ëp½Rh\Èç›ßÿ³,ûÇé,µ³7hˆHf™šmoŒÕ‘5ZLyóëÍ¿:†ƒ^?tJƦ‘U&ž-´‰ÒxLjYD‚։͢X+ÝiYÉ)-*Ôò6ÿ²XæË[4ÅŸîtÑdìÕóÙüÕ„
+ñe2åPJØ7£ÐX±Ü9ŽÄMû`}´ØMþŠ¦‚W
+ú Qãw ›WÀVW® ¬rÑv»zÏmÝñx­è za^Y8"„*dµË—¸Ó‰°ÓÇ)ÛÜÕMÑ~AR“ò‘¡4óÒ5 µÔÏ õ󷼡ü°ñìè {ïˆ#5×2«šÐÀ%"ÌCE˜œš!ê ê­h7„ÝʶؕAʽ5Kµè¢å‰Avþ;°Û•…yÐhÜ.ÇQ©íÕ!Pˆ.`ZÁn/|Ì$'¾ûð¢ ʈ_¹uR£à©Dt–È9[ÆÆD‰òzJR]N©•4ËÝ¢,šÖU‹Ïw˜HªY$‘]— £ša”Tc¨G, F2pRÍæ$Á$ÍB{]íÚOziOÛ)Ð'àjEÀ¶¨8.°Z©yìÃz”t3XûÊ•³54´Ë¨ÖDJÄú$£.— :LD¨²õö‡-¥ æVÎœ«#"¨‹r'By‰i¡e]µªKîÛÔolóêHÐÓw;ê
+¢DQWM`™³”mòn•¦¤¿á ÇO|X½’’ÜžÀ·¼²’oøBÅÔ[îçÒA*˜jÝÅìyvݸ]ÞPÆØ; |Ik°*KæÿF§àÐ:<¹Xiˆ* ?! S”®jËÉè´Ï‹3e•¡ý/”‰2c}šDP]'ž‹mGRBñ- è}tû¢^Kòȧ[‰’7Ÿ¨ù
+5Œ™UÚûJá·úP®䊰~e²¾8YuÙŽ)ñ‰IPB©©HZú¨’MV€N6
+
+¯óèã%6ʲ~ œž™‚o§é"2©e£äÖÕdÆ´#Ó<Ù¾òWÕê4H5m½#ˆfꊗPn ×MQ/oCÅòÊáï…b'Îð–S­|9æÉ,‚*Ð~%æ ¨®Ä¼@…ËnZX.V†ÍÕ 'tü!:ª )NÞɉèÊlPx¸ÛÝQzž™º¬_èfT¤—Ë÷ êœL…€uaÅ|¬íY3©æ"AôEE<m"«’äÄŸØ
+÷Ëý‘OÛxEBiÛŠQÚFã´ ¼Ö¡ÆmÇZâݸJ*vlÙÏ,)öÌ¥
+ÒXÄWxÑ8¼ #ƬA:ˆá`Œ©Z`·)`ÒF±2ÉLÅ22± ú0°é)!9jeØ
+~zOΟ࿚ߟi˜jiQI¨\Uì³þìó ‚Y¦‰j
+½ kÂx~Õ
+DÁÿŸãׄ4pRŠ39Ò›çù^BìK´
+Wjte¥ª´Ø"ý?âÚЇßØ߉A³Ñ„F_r-l"ç÷þY;Àœ%Ô%%gÁWóAÖ<UÞt/Ø¢TÂ-„é¾k‘ÄFé¸ÞüPW‹Ê½ð…œ’=ò…@ýâßÈ”÷Yl–„äGo}E®D÷ (zÅ ^ *<+*Yý{™?št·
+/˜@ë=s‚$ãñ`ÑLE ïÂ:åÀDöO—š;¡ÃÅ! ‚±Ðoê=½· ¹ –®ù.Fcؾ9ÿ¢$ÏÂV1˜†ã£¿O€¶ø ø^õ:ëVx.15ž—¦Ö8ØoÕM3(æ;ܫѽópÄX0ÃOXDÑïIÆë¥Ò Û^ÖwÃ×.@æ«ßc15/ºØèbX iâʉ_¿‡Uèú°§dƧ˜*œ‰Ž¡¢˜q8ñU,ôé)*ØÖ%†CfÌ‚ËÛ÷áÉ}ɱ~ywé·QÚFøƒ¦‰cŠèêÀ¿ý»©þGeª²4½pÍ£T*K‚P¾ÎЧ’[F6UÉ„èÿýoÒ¸endstream
endobj
-1351 0 obj <<
+1368 0 obj <<
/Type /Page
-/Contents 1352 0 R
-/Resources 1350 0 R
+/Contents 1369 0 R
+/Resources 1367 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
+/Parent 1359 0 R
>> endobj
-1353 0 obj <<
-/D [1351 0 R /XYZ 85.0394 794.5015 null]
+1370 0 obj <<
+/D [1368 0 R /XYZ 85.0394 794.5015 null]
>> endobj
394 0 obj <<
-/D [1351 0 R /XYZ 85.0394 688.9861 null]
+/D [1368 0 R /XYZ 85.0394 590.4054 null]
>> endobj
-1354 0 obj <<
-/D [1351 0 R /XYZ 85.0394 663.3646 null]
+1371 0 obj <<
+/D [1368 0 R /XYZ 85.0394 563.4931 null]
>> endobj
398 0 obj <<
-/D [1351 0 R /XYZ 85.0394 285.7302 null]
+/D [1368 0 R /XYZ 85.0394 179.4044 null]
>> endobj
-1355 0 obj <<
-/D [1351 0 R /XYZ 85.0394 261.2794 null]
+1372 0 obj <<
+/D [1368 0 R /XYZ 85.0394 153.6629 null]
>> endobj
-1350 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F41 935 0 R >>
-/XObject << /Im2 1049 0 R >>
+1367 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F62 1065 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1359 0 obj <<
-/Length 3004
+1375 0 obj <<
+/Length 3134
/Filter /FlateDecode
>>
stream
-xÚµ]oãFî=¿Âo§
-ç¹Ñó|L€9"N%ñfíK
-WnK¤3×þ˜²ÃƒÀ'h­˜°X;îµåþrOýÇj»åu ©Øn?шŽíûšÆ¡1à÷;»ûj¼ª#w:uýZQÓÆê\DõºìJ¼9ˆ“fù^@ÎÌÅð>·Ä—d@uIοٱz‰Øã­Ð~t,›=#žzp8BH†m{årèîÉ3”^_š›…Q`:ÀÒ ‚ÓâþŽmÓuàÐzøe¸áØ¡ãEr>”+¶#@Œúˆ&‹[€áG®µ‡zŠ’#lÌ~Ô"™§¬E@Ðj[õœò
-»%mÂÕfÍpí}sØ®C¸b¿/ê»@†®ƒê„’_J ¶.ë2Ò€ÂÙQKó°¯@Z¯p6,EGëU릲èÐÒ³Â=õ'î¬×Lj[2>²Ó‚逎sêÔ­K”èèrSR[¯x³'ˆ °ìgŽÞ)ˆ»¾kKät_µœb@òÚF…{ŠÐ ÛÒÔÊ=#è¬ñPå/5{ÞNÛ¾Ù³åèÜ“vSõ¯I"ïȾ”k$/É£ÿÜ—Œº ̽ˆ5û1h=[=”í]¶'î~LSV7μmºÍ¢Û’Ú‡rVÑùG›ómʸl69tò¶h=pøz`ºÃ¿ZRA«(ÑÏT­ßêøc½š~<T ˘z®ÂSœI5ÈHªSIp^$_è|1<õ^ŽÈl㉋Eõ84™9€HSíÍ\ï%mœ‚PZØôØÆ)p³hX=ÅÁm¹mÙ5å ¼âw¼;®õcY3òø:gŸ¤’ÒÅ0I–ˆçfXkO„=Æeˆò8ÎÖÆRŠá`¤rWt«û)
-,«¶Ú~9{ŒOШ@Œ:Sé˜È’Y¬R%<¿ë5 §‚XrϦ©cUÉìMM3»Æ[µåªBu^9OO†×Â]´²cÓŠo*'Ü-*γÙyD½†äAÎúZÀ½nÜ3ƒT5òØï&2ZÐ!“Å‚RŸÏº]_ðs^w‚uìt*ïtå±RKl ˜ñ¹ ôS\ÇUZG(,  y Îĺ%vMøX}VVBƒå}žòy£!”ö€»Cëñwm¹Ý¾è°%:ë Zq•IíAÖ•>l«UÕÍ“êXèç퇀t2…r, “Û¿Íã2Dyü6a%6™É†“Oa3H
-0n'Y5uIÂÂ'ºÇ†:%åªè-ÓÌPô‡€h:ö¨_1Éã}µbÔ.ÂÎ-ï$½ÑåO¤EÂHˆÁõ$Úü4øNÞßm39ns-Û;¤ãÏ È›·?P‡ì¹{A[`ÉxÙbú}¬‘Rb Ã<áÒ¤Á©RµRªÂ x¹»`ŒË圻0þëáàÓ. Ìm®2ûiôŸ¢Q§q.ÓtLä)Ô±ÊLÎü¦Øà lCméŒöœñÃ?×ÅTÒi! 0ŽÃvu_®~'éÑ dVI>±QÅ]QÕ¾¤Ð •† áÆ(mPBšpÙ¸Ã×  {¨»Šƒº‚‹¯;ºvÓêõlŒ÷ÞåJs"‚¥å˜p<
-w09|_0Ðmé
-€‡¶ßÛP > ܼ?æäþz.I#áË|ZV’9¥Ðîš?&3ý¦Ûò®ªkJ $©ùh=DêÒ2]NaB—/Iï±-¨áZYˆü‘©ðÆü”:Ê÷õlöw¬³¡h,sÖF'ô18óÌ„|L/ô
-;‘@ŒžéD=•C€“ƒTc¡ÒBàÌ|‚1.C”s9„Šmhz°Ï$,ji¾‘=Æ'ˆD¯ ”Pc"O'FKË ÇxÑIiÎ&`Ÿ¤zVdo ˜Föø-JøøÕi‡31p™2Ð
-ƒ,«gMÆœl=!ö,Ú¶º«]¦Ÿ’•…f ·,¨ƒ“õzˆifdÄ[M-Cˆé;†%
-ŒF@»ª®v‡ÝÜ™#ÆWïOoN[“ŒŒÀœ[oq‰R³–Ÿt6ÍRw‡QÙ bî¿2¼Â‡¢òB¡¨\Jß9Veå¨vH¨°¶£Q¿Ë¹™ð°I ‘ÁàW2êqÆàúTcÆÞ]ÙÍYœðæ-Õ…‡š×]°’<©ãaù¸/2≠µ}EÚÕ©¶¼
-†­à†%ïŒäþwW‚”ëªü³#¸»‚tPÕŒ
-F§ý³ÕIš/‚â|{ß<ÖÔ½|w(‰µ Bi…!¿QÑϽbüD1:PLÔ°†)*á:ìNù
+xÚ­]sÛFîÝ¿B÷tôLDs¿Èåä)MœÔÖißÜCÛZ¢lN$Ò©8žLÿû ,µ¤(;7ÉdœýÂb±
+pÙ8±VÌ®—Fi,ãSÀD¯ß_¾½x÷Ÿ«W§™Ž®/Þ_žÎ¥I¢·¿žSïÝÕ«ß~{uu:Öˆèõϯ~¿>¿¢¥”qütqù†frjŽ ½:{~u~ùúüôïë_Nίû»„÷‰Â‹|:ùóïd¶„kÿr’Ä*·fö
+úî®{¸‰³‹œ½iàF³àRñ<Äì.Vn/up
+2²¹…Âú>ù£¦™<Ø{ˆïÓÎP¥ll5èO¯RSîD[g:Þ‹4`\DÏ©Ñm³íÖ•7º¢sÜ›¶ðRǹ†×±· JGdbÚû¦nÝŒIÒJAÃ7—hüiWn©»)iqÛèx˜uv&7`c*ãà€fç:‹Áì¢qí²¥h4¯®ZgÆÔªÙnªú–V‹ÿß„ÅlK¤3×þ˜²Ãƒ FÑ`ž‰°Xî‘«£>;D\’ÀÐ>ÒˆŽívÛšÆäAr~¿³»«†«:r§Sׯ5m¬NÁû-ˮěƒ8i–ïäL¸7¼ÏÍñ%P]R§óov¨^"¶Æx;´ÝófˈG*c
+bÉ-›¦ŽVu$C°75ÍlopÔÞ—‹
+Õyá<=^ $he‡* ¦ßT*Ž¸[Tg“1ò€z­bp,S¾p/÷Ì Y@<ô» „ŒtÈ Hßs~—áçá†)¿;Æ;ô»@˜÷»òP¯%Hâêðˆ ¿ËPÏQr€-ð»
+2æóÂåÐ(†æž:k6âfõ¤Ä„=ÊûlåiÓ!”ö€›]ëñwm¹^‘Öè°%:j Úr•IóAú•_î×Õ¢ê&ÈIu |ÚŠHŒ…lEiHšéï~¡=Æyˆòð…
+)nf²ýÉG͈°¤`‘ãsDb‰AZ5$ò˜±$÷jC(«¦.IXGàD÷ÐP§¤Œ}fšŠ È•"
+;7¼“ôBF¿“ #c,k c¾½·ª pÛLŽÛ\ËVéø2yõúWêPºƒ=w/h l %/ÛŽ*OcÇ!±”ažqlÇ©R<Èà4ã<D9å4LŒ2î¡Ž;60º¹¯òãhôŸ£1—i:$ò˜FHfræ7E N`+jKgü°çŒvØø¹.&”N a€Ñ¶‹»rñ‘ëŠàñ ¿JòtT3½-ªÚº}½!H»1VÛ+á°ÙïðUèîê®âЮ †Äâ ®]5»z9ŠôÈï¿w…ÒœŽ`'$Gi9$ÂLß tSº0
+ìIø2—dNÉ ´›æóh¦ßtSÞVuMi„$5¬‡H]r¦¢‹1Lèò%é=¶5\1 ‘?0Þ˜¿ ²RGY£žÌa@âŽu6eÎڨ㴾#gž™õ‘é…^áa§#ˆÔ3¨ç2 prpÌdjccìÈ$ã<D9•I¨Øf°Úƒ=‘J@¼¨¥ùqDöŸ!½‚PB ‰<žJ V‡Žñ¢“Ò”3LâDHõMñ½L`ßãRáãW§ÎÄÀidbÈ@+ ²ìÈÿ÷Ú&S¶ž{m[ÝÖ.ßOÉÊB³„[TŽÁI÷1,õEtlÄ[M-Cˆñ;†%þhmªºÚì6SgVŒ_½?½™²‡½ÛÀ”[ oqR³–Ÿtèۣèl1wß^`¡CQ ¡Ð?T.±ïK‹²rT;$T^ÛШßåÜLxب–†È`ðsõ8cp}ª4cï¶ì¦XÞ¼¥êpðÁ8†õäQ5‹È}©ù‘'VÔöuiW­Zó*¶\€XÞ;u¥!H¹.Ë/ÁmÜ=äðÃ¥ØWÜp°œOÙÑ!±‰|i—K 69æš6gRÓS„¦Z¤¬×
endobj
-1358 0 obj <<
+1374 0 obj <<
/Type /Page
-/Contents 1359 0 R
-/Resources 1357 0 R
+/Contents 1375 0 R
+/Resources 1373 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1362 0 R 1363 0 R ]
+/Parent 1359 0 R
+/Annots [ 1378 0 R 1379 0 R ]
>> endobj
-1362 0 obj <<
+1378 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [213.6732 532.1015 286.8984 544.1612]
+/Rect [213.6732 432.1255 286.8984 444.1851]
/Subtype /Link
/A << /S /GoTo /D (rrset_ordering) >>
>> endobj
-1363 0 obj <<
+1379 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [209.702 453.3093 283.4678 465.3689]
+/Rect [209.702 354.4169 283.4678 366.4765]
/Subtype /Link
/A << /S /GoTo /D (topology) >>
>> endobj
-1360 0 obj <<
-/D [1358 0 R /XYZ 56.6929 794.5015 null]
+1376 0 obj <<
+/D [1374 0 R /XYZ 56.6929 794.5015 null]
>> endobj
402 0 obj <<
-/D [1358 0 R /XYZ 56.6929 601.5665 null]
+/D [1374 0 R /XYZ 56.6929 498.9148 null]
>> endobj
-1361 0 obj <<
-/D [1358 0 R /XYZ 56.6929 578.6548 null]
+1377 0 obj <<
+/D [1374 0 R /XYZ 56.6929 477.595 null]
>> endobj
-1357 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R >>
-/XObject << /Im2 1049 0 R >>
+1373 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1366 0 obj <<
-/Length 2639
+1382 0 obj <<
+/Length 2398
/Filter /FlateDecode
>>
stream
-xÚÅ]sÛ¸ñÝ¿B“'¹sBðIÉ“/g§¾¹sZÇN'—Z¢mÎQ¢"Êqt™þ÷îb¤¨Ø©¯ÓñØÁÅbw±ß°˜pø“Ì0®¬ž¤V3Ã…™Ì—G|r ßÞ 3 @³êÇ«£—g*Xf™L®n"\ãY&&W‹Ó7=ùÛÕéåñL>MØñÌ$|úãùÅO4céñæÝÅÙùÛ\ž§zzuþ/OÏN/O/ÞœÏDf¬—Ãgç¿œÒèíåɯ¿ž\¼úùèôªå%æWp…Œ|:úð‘OÀöÏGœ)›™É¼p&¬•“å‘6Š­T˜©ŽÞý½E}uKÇägTÆL&Ój PðŒYmÓIj,K”TN‚ÿ~LLfR1‹$Ï„`Ö}|y°0)³Jfæê®
-fº¼¯¶e뜼zÔî¹h$§Ùb{¿Y9Ïå*ø¾jÜÙá7ï—–ùŽ&®=šû¦¸¹¯hÎÙ.<Aã\ÞÞÇûyg¦ž¦ÂûAçSpñÝÒGŽd]åsGµV@µÛVk¦¼J;åDºŠ}ÿD„ œMøíf'0«Qø#’7œ™TZÛlóm±$·[®‹Í²tÆ
-„tüçÛÒÙ@8>áÙRÙÊÂ ¬ÛÄuÁ2 1¯'r·Ü9xDÚ
-À2IÓ§$l’Ù,ËÆÓµY‹q£$&{ÄI g­»Ý‘¯‹ùˆZHÉ47ÁîJš ù#ÔB?MIXóÊû[¥åi}˜WyÓÐF¦·Q ù~£ª'1-!ùþ4dáJiû|‰Œ³¥“X8áÂî6véFÛ‰ù\–ùH’ù°Ý­‹®Á­‰D= @1Ó‚H‚áñOcºÅøÓR¦,ÑÊ>ƒë¸Ïµ¡úÅ¢^æåjÏÓ€–ZcíŸÇx‹ñÆ•4Ðì1þbŒs˲,µ}λÐ9½d2Ë’Ø7ŒgèêQ=m0!²ÔsÌ… d¸˜¹šÌÛŠ›*ÅÔÑžK´ÒbñÌd>®ã‚Eq“CÔñKšQ÷U]’³?¹ø׸kH¬ºË—yâ ½ÞIë¢ÝË}<H›iËЖ*¦eÒ¾E[òmÚœvFÀ!\ªL$ýˆÝ'7[ï=¹ø¼ão`ac„C œe­üe„l œA†J
-ô…
-ÿH¡0q‰ô²W hZ ‹øìòIt@â´æw{ˆú! °ðéõªËèqUU°½4,ƒê*I 6G¢yž¸ñ`¡"Ⱥ
-ñé(ÅOPYË€æô±ä
-¿$Ö7ùjA­ï8@˽ÍæÛ4¼-šz`h£A$Iõô°Øc~ž'£Nì:…ò…Ê°â°ØÁy%‰yDêÊBZ$Rj ÌwóªœÿϤîË0¿K\߯3]Øý³Zǹ/ }/ «^gÅrXjûšø¡ÜÞ JItûð›®39óncæJ^°&]‡‚UNóí)óz¹.]]©À¬13X¾”«¿W~Þí*!4¯ÊméÂ…âÂWRÿ­z ªmÁä2ßÎïÆzKm¼D§BÊÞÅÔþy´ ´°¹œH©ž§§êwïÿGЉe*eŸAr Ï4®i÷j[ÅßfPR@µ/³ñÚ6Ü(.iF¥íYí{~¾cþê@3R(‚öš/Q?/¤¨}%¤Ü¡Î/èéŠ7:¡¥a8z-?æ)a À/h>Ú‹\ãëÑfEÖìû~£„º\PtÊRÄîî æù}S„žÛ.î~uÕ$® 8:9ØåKÚ6žQHˆÉ÷tñZ!W]ZÙ;i%(‹©ÛP„#lZu]»ÀûdÍ‘Ó£¹¿AjBÇ‘ŠÐ9†<9c\ÈAžœWù®é·ˆ;Þo9×ã: mç¨1½/Ƨ;úØÃpä‘’;G·çöSfm¡v×OnI&h{ƒöZà`½.rGKW_ìF˜kðp®”‡p‚éÀy‚Fm6©Ê¢a‡® …ÑLiý¤6”P![£æÜ™¢ÖÁÓ]rX1pÉÝý,&ç=×Öê¨4|¶ˆ0sÐäÛ.¢ƒ0 ñT„1£d8ˆwà.Äô
-þÊééP0€S  ÌbOõÃäÓD0®­U§ÜÄËó¥œüT?“ˆ¥€w!v,A(‹›t)¶œ0M3XDÐ-Â9(³؃ǼG›¢*rtNø‚aŸ”~àÈ‚Fim»öpÒïkqÆeb[>†%¤ÇÇ’wý‹e '©hk먽Žû-êÂæ”ÍýzŽ« šq)º•cHŠEpl`pÄࢻÀ‹w¿k§×HÞŽÆPƒ#¬ÃÑu@1sVzÌ0²~NW'ÖߎØ)f[ˆ³
-‹ÈÿÚ(‚—m¹,ö p¹ÌÍÎ×Ëðçs´Ã,â½—×¥]êÁ“,ø©Ë‹[Òå3¼Tà ðìö“$›‚çCìçy‰¶o,èÌw$Iú ¥Y–X9Ö»ç“GË¿§þCCçM4öy2yà6"$TÊ0ÀEǘìÝ<´ÿúÀ"âÿžóN»endstream
+xÚÅÛrã¶õÝ_¡Ù'¹Á¸Ø<9[{ãLãmµÎd:›} %Êæ„"‘Z¯Òé¿÷àF‚e«u2† xpn887˜L0ü‘‰3Í'‰æH`"&‹õž<À·÷gÄÃÌÐ,†úîîìâš%´¤rr·Šp)„•"“»å§é»ï/ÿ~w5?ŸQ§Ï„ÄÓïnnÿêf´{¼ûp{}óþ§ùåy§w7nÝôüêúj~uûîê|F” °žz G\ßüíÊÞÏ/üñr~þù«»V–X^‚™ä·³OŸñd bÿp†ÓJLžà#¢5¬Ï¸`HpÆÂLqöñì-Âè«]:¦?ÁŠ&#
+ä$R % î„F’Qf5ø¯ó™ÄxJ4ED*D/(ÿ¶?ź©>A“O¢8 i!è3˜á&/.ÜÇ›k£{T¥›Xi]»á»ÁzKŠ2¤ Èp
+%©"Jwß_ݺѮÎÜ
+BNsƒU$Ó:_çEºu“M埖9ÑcÞªÕàsº\:^êÚMÔÕ¶qxóÒÍ„° §iôÕs1ÏêMUÖYX–•MŸƒßvÙ6Ï<+K¤Z÷ÅsûiyaL=š¡Ó£¹MbLMWé#†™L˽y̳ÅÑW­™éTk_#eŠDÆb˜¯N ‹±rÏV óÒŠÑr1²]0cÔ­X»÷Šº½‡©Ô=&
+ÑþY]Ô£Dý)33uºÎzXAxŽû{AägÄèm)<Á¨¬7¸ÏÜÓØP¶Dî˜öbi{L‹Û
+rYŽé]šB'ñêl 5fœPFÁ)F°ì¤jˆ"­”¯…f-ÆYŒÒ ÙcŽjØkÞ¶[¾É#fA)âX„s—û˜°Ì̱qþÈX¡ŸvIXýÖû[P¥Æ¼ >¹DÜ=BAeI<¡ª§1N¡²5ÃIÍäë50Îb”Vc=æˆ ¼#lÓ5mG4æsY'Èg§™OÍ~“H nHì$
+,¥=#a›ƒd¡:
+câã! 1Ì’±’VÙCê3÷/i±ËZ'½aN)À ØËF 10ÑmråÕ·®š%ˆ ð˜P?¡kuÊáe\l2hõýo«#¸k.åÀ­Ã€ËÊa´BÁÁ„ZBkq$¾r†d <A4¸¼ÏÐWWøT
+…‰µ5§Òy¯à8*8ðÙæ“<Ø$€Äi»›ß ê‡pX4À‚§¿We6–Ñ›UE†Ò0‘’NbÕ¼NÝfc¡"P]ú|:Ê°âøbØ#ÎÙK;ˆaÃÚUi¹t­ÿbE¬÷6›o7Pච¨«u€q„‘$áÓgÔÉó:uj]ÄÓQ†GÕ5¤žQàW;ÕñD¸”q±_ùâOS»¯Ã<•¸Ú•Ë™ÝØÃÍ_úfš){í1¦ÃZÛÅOyó8¨%߇ŸÌlkræýÆÌÖ¼>&˜¢t*V:MG›«‹j½ÉmaÉà\›Ô`™øÅl^úyK•Bl.ó&·ñ‚áaÅK]®š ¬íÁä:mc¼´Óxgí]PíïG ú{ û’ω­êu–Úw¡ôÿ[DjÄ°ö$ችªö ºeXúFƒÉÙ•¯mÃåÅ’#åÚRוïùùŽùÛ#Í<u
+‘Í—¨Ÿª¼¾ v×.7þšÄ9vtéïlfFoLËyNØï›pÉÐÒr®q´ýA¹Ãìû~£Œ»\`°ýZ˜îÞ`‘ÚË×sÛÇݯ®±*“èÊÀÊhF—G»|²mãy%™¡Q’Áä{ºæZ! W]ZÙÛª)˜
+ ©ÛP…#b‚s•¼]à]ŠÍ3‘ºG½[n­ÿ1~#!¡s y²B˜PÙ×iZ<¥ûºß">îwŸ r¶ÇuÚÎQcúP§ûùØÁñã‘‘[?·çSf®œŸÜ’”æì ÚkA‚Í&K-/]}±®mÀþBL
+Â&ß Õ .)ò¬FÇîä¡(7é#Ý3<y1;õ¾¾ûgn*-EôƒCóLÙ.¼rÞ^ì²þÔþ–endstream
endobj
-1365 0 obj <<
+1381 0 obj <<
/Type /Page
-/Contents 1366 0 R
-/Resources 1364 0 R
+/Contents 1382 0 R
+/Resources 1380 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1368 0 R ]
+/Parent 1359 0 R
+/Annots [ 1384 0 R ]
>> endobj
-1368 0 obj <<
+1384 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [353.6787 530.3947 427.332 542.4544]
+/Rect [353.6787 434.7534 427.332 446.813]
/Subtype /Link
/A << /S /GoTo /D (the_sortlist_statement) >>
>> endobj
-1367 0 obj <<
-/D [1365 0 R /XYZ 85.0394 794.5015 null]
+1383 0 obj <<
+/D [1381 0 R /XYZ 85.0394 794.5015 null]
>> endobj
406 0 obj <<
-/D [1365 0 R /XYZ 85.0394 600.9849 null]
+/D [1381 0 R /XYZ 85.0394 505.3435 null]
>> endobj
-1020 0 obj <<
-/D [1365 0 R /XYZ 85.0394 573.3935 null]
+1025 0 obj <<
+/D [1381 0 R /XYZ 85.0394 477.7522 null]
>> endobj
-1369 0 obj <<
-/D [1365 0 R /XYZ 85.0394 447.7048 null]
+1385 0 obj <<
+/D [1381 0 R /XYZ 85.0394 352.0635 null]
>> endobj
-1370 0 obj <<
-/D [1365 0 R /XYZ 85.0394 435.7497 null]
+1386 0 obj <<
+/D [1381 0 R /XYZ 85.0394 340.1083 null]
>> endobj
-1364 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R /F62 1060 0 R /F63 1063 0 R >>
-/XObject << /Im2 1049 0 R >>
+1380 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1373 0 obj <<
-/Length 3269
-/Filter /FlateDecode
->>
-stream
-xÚ½Ërã6òî¯Ðm骃'IϬ³‰g×v¶j+É–`‹5é!){œ¯OÝàC¢äì¦jí›@Ýhô›â ÿ|¡Ó$5Â,2£͸^,·glñsŸÎ8áÄ)c}wöî£Ì&1©Hw£½ò„å9_Ü­~‰ÒD$ç°‹Þ¾þxõé盋óLEwWŸ¯Ïc¡YôñêÇK„>Ý\üôÓÅÍyÌsÍ£÷¿øçÝå N¥´Ç÷W×pÄàãȦ7—/o.¯ß_žÿv÷ÃÙå]–ñy9“î _Ï~ù-VpìÎX"M®/ðÂnŒXlÏ”–‰VR†‘ÍÙíÙ¿ú G³~é¬ü8K„LÅŒ
-î3ÕrªÞ‡âÜ“Aš')ïµÒ[™Ñ®µ+„¼‘óµò9($Œ!Ç­œqÓºÒ»
-’>îŽ@JƤò4ùk†þÔ¨³,2@‘Y§!¤ã` ƒ¡Á0
-¨_w¶)-‘ïh¹­]Sáû-dà ªt¹îÅÕßáÚ{‹;ºC²©ËqœH™G›ºídP¢-Žâ¬Z¼µ«´gnnZ­v'owîÂnA£×·øôÅM<ú㻡 ø{wpH_ðò(…@šˆàÀ PT©7;ï¤'‡Á«zBi.mÛµ3­2ÈtÒ7âþë¸õXÞÎÊ*nêºklŒ1X Ös’t5C{bc•eSâ9rÇE°,3$À¯Ò=QDèK U‹Sݺèòj®ƒÈ¿îJJ#p–Ì4GO7`Ù¶ÛC ã5ªùÕQîÉ…J¤Ú7Âb¹´Oà““?•Ùæy¥I®³œ‰˜ 5"(NÎm ôi¦%±&y« ”¹¯oóù‚´6ƒM3#Žï…ëìE`X1Ý*ÜÅ
-Bt®Ót¬5½!úBBåb¡ OÓ
-ËŒ‘0t
-Y—WŽ;¤SŸÏÁåCB§":¨”sˆ
-P®.h"˸r¤_<aʉH#ØŸuxwµ‹5œh1>mwö‡‚
-yn$ÁJB…­œ¸±¾öZ–oŸ6Š" ån Â'µ
- “äyf¼±W’tfŠå ½áÌz,Ÿá•1Ä«rUv¯±÷þðvàØàv”âÙbLàб¬>&ŽM W^Nù¸}²ËÒ•'>òe!ȲÁ·Á ÷mYŸÂ°\ã-€äbqÒ{*|YÛ
-Q>\ßÞ^¾ÇQ8xUÄç‹]Wo¡†‰ÑAe,JYOÔµ‹Þ*meJ áµhé‰Ú–"Þá¹z­Šm¹Ä—ÝÓ
-6 ….¼î‹^`BË|!M
-†m¼RádóHæuói¬0„^ÂᾘÁ-©.v@ãö¹‘2ÿö7Þü@z¬7x8Üê{Ž PòýöD‘ÉwZŒ‹ ýÃ|9}ýäNQÐb,b(æhˆ)˜Û$7òz·qÙ ã!%u`;VJ7°®_ØÔÕ#B÷ö¡¬¸wÏê+Âg¢é}µóý9q3|ât¯_.½Letõ€³¾@
-üÅsù2½‚¬Pê,$V‡:/¥Äaöž°öˆ#š?Lòw
-Ìa•o8”à=|6ÃÐí©¢ü=<HÚ-h ¡3a•³I_0z<Éä51ᧂ Ã7Z0-Ѽw)*œÊð1l^îÍKÙoØM·š0‹ñékb§ž‡ß_4¤-Ë™Ô|ijÉçkwp­‚÷¹œ«Ü¡3‚B¡óÀ~å³kRzØÙ‡Éè†c§ýÔ” ï¬à™áþNà»ÛÖi£–tFj<xñµQ.z…ßA„­^mÑ´Ô ÓŸÞ²ï2¤)ªð¾Ïàå1CQ'9bª×8TV.¤è{<‚úFÂÕþ •%:
-ïч֑ ^’ ò
-°ß— ä‹!}nA"›UÈè]ý™²¨ jcc‹¶£±ÖB àõ
-&¶` åvÐûZ%ôaàöóŽ ß‘/¨îÃN¡š@‘z}â\@^ÓD¢T£°(t9áÂï7¡)í¶-BÐóÝ¢*ýj¯§ý\4e½£~»Öf¯û¼>ê,Dô£e)ÜLb{£,cÏäz¬pdÑqU¯ìay*!Õ”™8ÍB5ÃÃÔÝÈ„qHg'Lø4îÁ ‚‡ŒŒ=ås
-1™dJ¥o¨Ðë„
-¬}
->uFtæ:¶â4=Ö #“3C0ô§œ zä>%ÐGŒ5%.ëzCß.z]Øë’k¿ï'ö~©÷L"¤;~Ì6 X¾Ïå?z -%Ô°S1Ò%¨Â¥Üû.×…]¤}¾×"ëÿSÃ2ÿ-‰÷*6§aÄ÷ÆÁftž¿QnŽ±ŽkXµ¯aÝë“=ôQP–(%NsÐcÍ°09­ÔPÁi=åaÐ-£0#Rpûå3ª¼Ü|ÀŸøÞ*y^rþÉhôOðNߟ
-OESl-¦Ú<4»@ν­ŸqÊ 9Þ<&õ;L»"ÆgîúñKÚ1Rï7i;ˆÍ˜€w…Çžñ„ç©~CáGX'>`õÍbû
-¤P“CÜáçPn•Ö-¾@Ý¡ÛÜà€øßpÀ‚þFÙ¾ÈÝ/öû½÷v]<—>E“2ò·,ÃWÚ‡àïÑd$~Ñ…¹R‰ßb )tßL^ KQÆx˜M°„rï±ÿÙ‚#ÔŒ uýbÈË‹rãà®)ªö¾1ýÜî|êËéUp.‡G²ÆŒŠ!CL™Ð*‡:@£BÉx‡â
-wˆ÷»ÇÂ÷è½='Ö.0zÿÚ/B` É8\Üí;”„&j7Å3áõÞÜÖ«x®Tu_ZKW7m¨Tº.dÓ}ðÕÊsÈ”™²° FšI‘É€Àk»_QÍè1ëØ_þ±ÖðK6¨­ežùÒ)²<Q9lBLy§ªÝýªëõ?
+1389 0 obj <<
+/Length 3100
+/Filter /FlateDecode
+>>
+stream
+xÚ­ZÝsÜ6÷_±Ú™Já—HñÑMœ{=çÎöÝÌMÛy—v4Ù•6’6Žû×H€úØ·½Ôž±(@ø€Ì ~ù"×™¶Â.ŒUYÎx¾Xm/Øâ ÆÞ_p¢I#Q:¥úþþâÍ;i6³ZèÅýã„W‘±¢à‹ûõωÎD¶,yûáæÝõûß^.Jî¯?Ü,S‘³äÝõOWØz{ù\Þ.S^ä<yû·ËÞ_Ýâ&ß_ßü€=g˜Þ^½»º½ºy{µüõþÇ‹«ûa-Óõr&ýB>_üü+[¬aÙ?^°LÚ"_<à ˸µb±½P¹Ìr%eìÙ\Ü]ük`8 SOíß@ºe’åü‰å"³6W§Å²EZÈL+iÏóÂy xQ3Θ³Wy–çb<^!œgúüùj‘IÃõÂä9œ¹Æó½ñ;(m–kÅ=!gY.h(>,SÍ“{ø+’£ó
+
+_×ËTñ<é?V¶Z·qeçð¥yÄ'Ú¢oÙïà©,Lp¸ZNDpÅ2&´¥íhÛ%Lé\Ÿ6íR°díZš4Õ+W™áJÓœ®/{·uuòÖ#ÅꆺºýnüRÅêùEõ câëR²Ä­ý«—³H9˜¾
+hųMëIabU?i›<xõ^°½vžO¹ßôàŠRñä]Eœ‘àÄüUY#‡OW—ç&N*{¢l¶»jCT}µuÇ
+t;·ª_<s¿
+µG+ ‹BÒÉÚÓ¶…ý;
+S$MO^¡á‡VMí§<í[7R‚bÛ²^ã˦ª?»ìЈ•¶™(l±˜:зù¤÷þ܂Ѥ#®|bÌÝœÙàåüˆkNÎß#ˆs “à€càÌ\Ød_ÓiÌ
+ºBĉK&GÌB‚#Ã)8$âpéÉ\dÖ$—E¨€gkw˜ËÿD
+Hw $²àH`5&ÿ+jwÜ ’Eas`.ó¿¬v§SÎǵ;k©À±˜€dŽaÜ{¬Ì€ow›P4sT¿©¨ìCEdhÙó¥œé~~ÛIØ{m™ü3¥œ× ö%+
+cC=YÁó:˜Áí™ ^Ø×Ál 
+±]õ”†ô²ê_Ò€þðvlÊxéf1p l‘ê„3`ÿ‚ä®Ç¯úùÄ$Ü|&†ÆŒØÛÌ
+þ å¾îèf
+U ;¯jhªj [ßìü*JšŒé Ý9ዸÛìLƒÝm|ôÂx I}³›¥ïøØ<ccÓøÚ·o=¸Ç&ªâ߃ª/ØÆ{[4|hvAbX'2Ã'öåÃK-“ëG ©QÔ/=ì¡Òkˆ
+enb`ulóRæQ8Œ>Õp$ AþFa#F˜
+ž$¢Gø‚gðêRqÿC{Üi?¡#‚a›‰ª:ôE§Ï13±” T" EÃ7š0Oκ„ |ŒÌàÚ>WÃ~Îj¦,JÄgȆ½yB~±h [¢–'6ÑÙ§³v€VÁ‡ØFžÊٹʬàñã­ø=U_ðCÅ8Î:áÔ›Ã04W"€< Nào¾{¶ÞsIk„¾1ǃ—ûä±( /¡¾ ¬^\ÙvT—V|àñõ­Ù˜µW6¯¹¢BÌí»ªÚÇ‘TÝCuGPÅHø¬¬²B ˆ>U‘¥Ð𧋭©ÃÒ¨ÅjßbÝ
+ì@’GXe:a TMØTÛj¨I …âI9vµiVŸ¨"ñÉ=ûàÙ=:.Î
endobj
-1372 0 obj <<
+1388 0 obj <<
/Type /Page
-/Contents 1373 0 R
-/Resources 1371 0 R
+/Contents 1389 0 R
+/Resources 1387 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1376 0 R ]
+/Parent 1359 0 R
+/Annots [ 1392 0 R ]
>> endobj
-1376 0 obj <<
+1392 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [289.8576 392.4739 338.5646 404.5335]
+/Rect [289.8576 239.4581 338.5646 251.5177]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update) >>
>> endobj
-1374 0 obj <<
-/D [1372 0 R /XYZ 56.6929 794.5015 null]
+1390 0 obj <<
+/D [1388 0 R /XYZ 56.6929 794.5015 null]
>> endobj
410 0 obj <<
-/D [1372 0 R /XYZ 56.6929 769.5949 null]
+/D [1388 0 R /XYZ 56.6929 661.3973 null]
>> endobj
-1375 0 obj <<
-/D [1372 0 R /XYZ 56.6929 749.8269 null]
+1391 0 obj <<
+/D [1388 0 R /XYZ 56.6929 635.5371 null]
>> endobj
-1371 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F62 1060 0 R >>
-/XObject << /Im2 1049 0 R >>
+1387 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R /F41 940 0 R /F48 955 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1379 0 obj <<
-/Length 3862
-/Filter /FlateDecode
->>
-stream
-xÚ¥ZYsÛF~ׯÐ#Ue"s`pÔnm•ã؉·6vÖVö%ÉDŒH¬A€!
-¥‰^¶\¦YˆHïä’á2‘»·²éÖCyXwÕv¾µŒóHÉ,~vï@t¾ùDéMŒv•Nvÿl{P,håƒ=öUç¤ý·ß}øL­Ÿ¿û‰wÃ=ŠùÞ雀 GÖÝLÕ0ÅSoýÂ-ýnÚ¦w·ÓÖ³O·÷´à¡Ø|;’«Žút«[=ØÒÝÏõ:Ž#e
-b”"%†ñç‚ c‡M›´a ZÐoZAHØ#ö"aãDRi”¥ <bQç€ÁžÁž W/èg‚H8àMwiÂ#‘°A:…‹0"MÈö¸;•9Ü©NÔ<h!ú¯1")Ÿ#"9rBlŽ Ÿ ƒ“‘&ÏÄÞOë)ñiùñƒ&÷Ép{‘@®»âð*ü6¥=€•
-³ç™T \L°5É¢D€VNØø_§×ƒ,4ˆ5j3®wˆ¿»);ß1¢³g~BCÄ©ÒDMÎB“Çí55>Nè_8Õùºä36˜¤GI1îœ
-¶#ØŽ} yàD ì¹@ùâá²xõ®¢ÛÇuúm)Å&éNGÛ89?¨†ðN§Ð~þ¤iâÒ“«DVŸÕÆ¥¬®k¿®I
-Ú$Q’©d
-c ñ¡iLágj(T‡þÖ6yš†á'&Û-ÅRk
-DÛ­ý…ÿ>ØãÓ+â ÑÅù9—*ðy6ÕŸÓ(H;àž0ê ô"¡·J_TM@ÆU_¹š )/Žc¬Îï$0V¥y*ŸÃlx/fØßÙàƒ$…Îc5”R¸áØQç
- {ˆy‹Æ¶Û˦ɦ¡Q4OÔØ£ 5I¢¡Kª%'F„ozÒPÆùû‚ö¥Qgv~G|õ;ðSsþ>[4°MB€òKk¦£’«È„à®åo–‘Ãb‘bð0ÏJ@›=8
-HÑ6³,àþsH>+±â`›ÃÞúÝ
-¾ìŠR1O¥-j6 ‚/A.ðR£ ›ØVYb‡¶ñP•¬N¾ž4†˜òHããÓáê]”h5ß<»¥ØHÓÕëp_¸»ßñžŠÿ093u˜äÕ_-¾ ÂzBž3§±ÓVîvÎ0„c¶=‚`«Ó&#C×ࢸ㹺}䬲¤ —îÄÔg2¸—}8y(1w; rsn‰}Q5ÛÎŽ34墡‚`ŸH å±í¢S>¤FOÚ³û4šQ²nZ¦unß°XpÂÕ8<Ôè°@ÃÏÕå©0Õžž`š`g1Û™ùDCïè]Ãû?ã_ ÓNµ³À:›r#s `4믈WBÈ ¢Uàÿ¬Œ¥ˆ#Pè‘Œc•‘Œc•:ãÀHÆqª¼ê©l,cìúš–žNP8t×(lrõ‰ž/"­ö‡ÖÕ™ñÓRd,¥‡¤féèƒè¥`
-¦ÓpfLæCùW{j9YQ»#‘AŠ8}ቷl)u$!»{áIøBpLn°g«N^(™;5Vú6t”ÇBMØY€ ¦z‹óÕFiðàŒ~GùØô¾ È’®¨2ª¾ì ËRl©\–‹u ùXчcížæ8Ü‚.ñxá©K,*‘E1(/ïþþÃ’;ÀHc¯¹ ó‡lœî!Hª„Óa  /ò<teQªe:Å®€5y6ú@:ÝàD§Xb\rì2ÊTHÝ÷}9ì¬E uUâ<ã*14|•8OY”¹sß7õà·JɸàÆžÚ÷ÖUBóÌ?š®Ê3pˆw*«®¸«'+‡*½Ô鬸çë‚:ÉVƒ3á8öï»âÑgX6´øY'} ©*óáøŽ>ª?LzáþÁGÀÍd/A ÖÝC†Í €+?Ѧ%昪qÇ‹†~í×C]m\0 =ÿœ!Ì‘Kj¹V‰‰Ò,ŸE5Ï ¡”¹ŠOI¸Í.¤Ø>ª–  m¼üM¸öÜüߟŸ0N#eê«b‘€®ç©gÊyp3ç<|7|Îúÿ
-endstream
+1395 0 obj <<
+/Length 3964
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Z_ã¶ßO±oõg…IýŠ—d/½´¹¤{›E’Ù¢½êÉ’Ï’wÏùôá iÉ–½ ŠÃž‡äg~%oü“·™‰„ÊõmšëÈin—›q»†¶ïn$óÌ=Ó|ÈõõãÍWïTz›Gy'·«ÁXY$²LÞ>–¿Ì¾ùûÛŸïîæ±³$º››D̾~ÿá[ªÉéç›?¼{ÿÝÏoïR={|ÿãª~¸wÿpÿá›û»¹ÌŒ„þ1p¡Ã»÷ÿ¼'껇·?üðöáî·ÇïoîÃZ†ë•BáB>ßüò›¸-aÙß߈H噹}‚ˆdžÇ·›mTd´R¾¦¾ùxó¯0à ÕuÒŸ6YdbÜΕŽ²ƘԲˆ„­ÍS“G‰ŠUÐr,§´ì¹PË]µžÃ_S5ô[ôûíN/3P`ž¥·ÃÎä\‚¨ 2—Qœåø¸µËju€-ˆÍ¬ Ÿþiw'³™ížÚº¤ªf¿YØÑí
+õÌ‹M¼¾kÑõRÕ5×ÙݦNKÅ­ëÐ.m×ÁâGÞÍu
+ýüÞ6–ùªþiÔÔØ"¾ýðñ÷ÿ¹“RÎ"ªy|âN¥]ûº§Bå¶ä«wz¸¡qªÀ]T ÚG±¤ ž±®Ynb‰Î¬šM'•i”Jõš} ¸®Ø—ç:µ¯þ°µg–F s‘\— pMˆ0ZmΙÆcŽ¦•k·ð³ÝUÏd Pxø–À
+T@Ï«K\kÚÈåJÇãE€Iv fp¸Y»ía/:*,Û¦'Ь©¢b¶ÎîžÑ
+ ž¡Hoz×8yùß}‡ë±%ÎÁR³ùbi¶Â)tSgÒÉŠ›P<Ôí»}QIë,:w°A™Ü@&Rh&G!kŒ×@ɱٙIžXR’Dyäœ3wDáOÓ6óãr ‚–ãH¿
+„󤋘¤ÓÜ ~%ˆr]F¥ÀåŽ[ˆ
+LOLp :4¡L°„,´@
+Æ#&­ñtd (öˆH8zA?#DÂ
+¿¾Áá¯ïâ ²)„iÄæ°Çí©ÌaOU‘z„Hx~ )ú‘‰/¶ÈNè‚ä‘°g
+}²édš
+î¤>YÚÛ/ýT.ME9>
+ JèHOD”Æ'KÔ3XYØÍW]v§ Š(“2{Uƒ
+=V ö…ï†ïyômGår_œE;W+ :†SÁ•ÛM/•y;š§liUMÛSE±ÝÒíÕß u|a©2–xOó.±+^¦–*"¥Ò©•º‚\7…¥¨<?IüÙÂež åbMµÔq?€vûaÔ%!…‰²Dç¯ ©0#)iÐ ^ßÝä žnˆPôÏk>­U]±aÊ)šÈÚ>Ûš‹Î ìgf¤È…˜“·?²<u¡1Mž¼îfZš` mƒÓ®÷»‚ÎPž”’§ÿàÔèí†Â;íòÝ5qd†O<&.„@'Òe`§"˜ g)Ë2Î!Rªsˆ ¾à×,C–ˆ˜ÞUeé`V¥œÿÏ(ÏŸR§Ì°·¸ ªkY¥ƒ2:4 ªj–õ¾äÌ>:±?&àöÿ9…@¨k„ß®áÀ¤h{/czæ€Ó‘Щ»Ö…+Ö‘Hƒ.žîªo2ÞåJ&ÇIâpðù Š»#œ\ Îíψ`¢ôbÛ Æ¿¥¹.GéË9C]á#ÁÜoøç½Ýc“í§RÆ \`Á
+@¤àþ@UOøˆÄ†,(4×Êò§K
+OeÂß$lê@ôã Ȧ8e&B¢
+M<s_|²,®ÛŒ _×ÖÏöBòÆéJº‰œ2ãÙûU1øÊã÷L!Y#K2x·ZZŠsdØjVÿT@Š¾™e÷¯E ùIŠg
+At¬cþJDÇ©Ó1V t¬ÓØ›^œ uŒE?@ÓRÿýÖ)
+«íõƒ$gŸ¨ÑkµÙ¶.Ïì˜S‘±”?×;y•Ùù`Æ/z*€ð6Ë_ÿ¬1Åd¥|å«Æ#Ó•™‰°¬¯V‡yiëâpþ>‡[—««S¦ó¹G{©M”Çømä`r:S
endobj
-1378 0 obj <<
+1394 0 obj <<
/Type /Page
-/Contents 1379 0 R
-/Resources 1377 0 R
+/Contents 1395 0 R
+/Resources 1393 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1381 0 R 1386 0 R ]
+/Parent 1401 0 R
+/Annots [ 1397 0 R ]
>> endobj
-1381 0 obj <<
+1397 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [353.2799 540.398 410.176 552.4577]
+/Rect [353.2799 390.6622 410.176 402.7219]
/Subtype /Link
/A << /S /GoTo /D (zonefile_format) >>
>> endobj
-1386 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [84.0431 109.336 144.9365 121.3956]
-/Subtype /Link
-/A << /S /GoTo /D (view_statement_grammar) >>
->> endobj
-1380 0 obj <<
-/D [1378 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-414 0 obj <<
-/D [1378 0 R /XYZ 85.0394 184.8801 null]
->> endobj
-1385 0 obj <<
-/D [1378 0 R /XYZ 85.0394 156.8765 null]
+1396 0 obj <<
+/D [1394 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1377 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F11 1384 0 R >>
+1393 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F11 1400 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1391 0 obj <<
-/Length 2882
+1405 0 obj <<
+/Length 3058
/Filter /FlateDecode
>>
stream
-xÚ½]sã¶ñÝ¿B“—Ê3B| Ó'ßÙN•i|W[ídšä–è3çdR©sÜ_ß],@‚2Dú&ŽÇ`±Ø/
-üÃVæLsH:ÎX"…ì¬,xÈÊ ­ü¥Ø7e]k›ELÅÉÌ'øŠ­Å p•×,fJj9äºz,ÀÜ:íØ›Aë M±‡ Û¬Û õ÷ç<»zßÚÕeNÛü~(ö/Ô­ŽhVùSZ~w­|£-X,e*yæ`÷eµ!ì2Oq[äç²}´\^v–øÀâ*fR¦úêçU€$‡®t¿EØv‘0Ž»Î9ËâX˜¹õ6oš
-è *‘S‚â<‹ Ç'ºý‡ Ohóêe7- È.È.J‰-b¬ÛC¾Ý¾8üæd3þ†/õaO½Îq,D6åààl‰TÄGgœè ‡ûkèÉ‘LÇ©sïg3{'3É"éáîýOü]"4SÑ”¿ó±Nû» ¥³g$\”›WaGÂ2Îõ8w‡à>tyœ¥™r§S™êùò’ÚÖ:_‡}çëÒ#_—â¹+*f]”_ÈÌ
-)½¸LªNf€¯kzT¥¹i&œ„.^™f—¯ »€ìÐöÍßü|ù᧋å h¶ÙÕUC $©%•O³÷V2R &!ìò}[®¡}9ls“ðâóŠŽ”Ž;¡µ³tHÔÑ:p˜Ðé@x¾ÙXIZ
-À.¼X´mSÓÒ²Zo›"¤I,Å‘Ä’$†y’àË_™#H@O šÃ‹ÕQÄ€·ãSUlðê  eÒQâómY}£Y4vI{ÎçNb_z·½û|ý™<ÊP@#ú‘³¥½Cõ¹ªŸ«W+YÇ#…hMqß !ík„½¼mÑáÐÀ?h7\¦'“Ôá°ÄÐ]([
-ß]὆%µµešÍ Š?ʳJì›MAZv EùÅ.Ä- ³é܆ gÉc
-»úLnk³@Ç:"N—vl
-ˆëö9>[6ÆõMjí
-¼z^XÅY"JýkOàS ô8¤ƒ£LÒk¦Ã"
-¼åY™Fly³¸¸¼¼e·Ï31¿8©w"¨ü1®·‡5¢·ÃšÔ{Œi¯÷1Ó°Þ>S™Æ›5‡P h‰ Í=¬ÍÖ¤æcL{Í™†5÷™Š¿${»ö"aRB7®½‡5¢½ÃšÔ~Œi¯ý1Ó°ö>SÁðëŒx»öQÊ"™N(ß#èn‘&UáØk~Ä1¬¸ÇQ@bïÿ¿U‘fL«)øX§-ÐaM™`”igƒWLƒF0ØŸû[~L¦-ê*•é ‹yX#sX“cÚ[ì˜iØb>Sþÿ°X,ãdÂbÖˆÅÖ¤ÅƘö;f¶˜Ïô’]£¶oÓÜ|çúšîchî°&5cÚk~Ì4¬¹Ï4eW_£;äüq¢'â(kDw‡5©ûÓ^÷c¦aÝ}¦ÙWéÎ3ós"–ò±NëÞaMé>Ê´ÓýÓ î¦_§»r:›ˆ'|¬ÝÖ¤îcL{Ý™†u÷™¾;©;#Ų?Öú¹‰«gñ¸Ë7¸ê‹DoŠ¶Å:+L¶ÃmÉ_Êâ™z[ÈÌ·–€É²
+xÚ½ZÝsã¶÷_¡·Ê3J
+#…î³b7$2ri˜´I Õ¯+QÄ°¾¡a…ûùn@ ï±8Š,×6Oª
+wu(p*ã…uYFËD‡Íz—kjéPá0uˆAï9K_høWOyUšŽîØ’ÒÃ`#ÒØñqAÛÁÌwøiãÊ¡k¹Ðûtk¶"õ.²o 犩XFsÞ¤OÃ5cÅ[ih‚“ 9üêЬ¢Œ™ £`f+âÂ7\/ûl»'±YEß*…ÅJjX8!¼åmþ'Ó»»ô!9å5uhÕaÖ˜‰Â‹˜{×h_ß È/B_–ïÅ´ 9õ÷;T,“â•óò>Éu†­¤ŠX(yh3¼šü9àÒVÔ©N:q¸L†læg‘ˆlº%y^¾¬~?¥Ç×ãA³ôÞ]IŠ²¦Fr8䯤‹B ´š²›:{ ©
+nŸÇb©Ù!DßÀöæ5)=°þÂÇ•‰æ †3O…v—P@ɯ¤t—þêy¢ÈŠG¢'}Ó?y¶ÍjêÙyŠ0(cÛr%ÅÂ(VÝðL !ÇÃÇ3žÔt^Á©±Ý#üaö 5¶y–5,kÊ8 9ï3!d<rôÓÊå?y.·ôX!€õôÆóÕŒZÃ3 ÕC ‡° eW«>E5êu§¶Ô& ±½/OùŽÚ”Õ‡ =;K¨a>”pº©AÆ•Y$OéÀ9)BÁ””=lä¼ ±²ñ”ÅŬÞ-¯‡¡#ÓWLÊØ¢ÔæçÍ’ASZ‰ßQ"új!¿—‡£péãA/æ=dhf€°ËEÐh;ˆñø­í(…=É©×,všúÚ:ô<+Á¬#T­ 0”Áòîn³‡WÌÉ£ÉSP<„½¥0z
+Fª.Š€3Ifª¼mZU ¦·‡òÌö€n,O@»JS9€.×x6\hëÊJ»7;eƒ¥TÌhn¸TwvÆÖ{º) ƒ 5B÷jKnòÛ6×;yc”‡Ð0›‡ÐÔveŽåaÄ™±Y|kÐX"FPüÝ4D%ÃiÅ5äS¤d7¡Þ•0WS|áÉoN=¹¡$‰›{ÑñŒÖ_º¯¸KƒdºC4Ã
+Ž“í>+^:ï\;;pî>Ê”1‹UÅVäwóç¡„«„Ôõi*|‹£@xLkk–ߦòŽ‡S¡katЋÍÞ‚ ‡cö”èí€ÓñPêJÆ7 DS[ù‘ÍB"gæ«Ë„"¢¨=ˆj‹R’3pi½v<š‹ÙºZ'|¡&Ü&UMŠ ªó"R‹Ûúçó«å¯^À6Ð…‚ëH­8 šš8Ø["ª·ÇI"Ü÷CGŽd¡Š,¼7ÈF5l,™ç{a×ñÿ ÞA…í?ƒw×ÞY.§Â WÙîMÙ°˜CM>©Ý2 h—ý’
+°ŽvÚ•Q¸\_Ò·¶„ë°m±.êa]„û.-Ü‘mš=S˜”Ðç†VZwŽÔµÞ¿X”Z
+&ÐÍÝúÒ$P99ç=X½—G+Y¯¸ð˜ˆe¯5pËczcà±Yg$ŒÀ-â§âA×—ìîêö_W·C—‹tK<VòH¸ž6Uùû ÅV7!îð÷AlÐB,ŠÜP ¼Ú ŽP¸¸A ¤X¢hP³úqÐEG Üž ¨†o‹KØ3¸„M ÖðMèã QgÔ"v$Ò‚Í·E"âo»„DØj‘Èf¨•ÝœX Çáȇ[—Çûp¤çôiT†¶˜ +C%¦­6SspitÈP¸w"n¶mžÓ”mrªFjÉ †àÝÈ ô¡úCú€A¾ÝÃz'ľ¹ÇÒz뻧7“Š¨æ|E’¾­Æöb „ÁóUOjÏ×Ð÷líî7µûÀyã ¸¡Åþ`
+g‘™£W»SK)áÆBWX…WÖW%MÍŠm~Ú¥£¿@)zKÞ±ÆÉb ¯¿<DÒ[ˆŽ4†‰ÕnQ䀳ã±Hw˜:C4’ø2ÏŠ¯S2õ;%N©ÏùÒZìRVC{ï>Ù~5r‘ ƒèVÎF´NÅ×¢|)ÞÌdŽˆ e~#4 $„4§¶’ºFÀ¡ŽÞ~ðÝ¥LOúR‡ÝL?—ûº¶.\aQÈÊÍ3Íî•éY…·JlëEAY¦Eöl&âÐÞ´°!èXr”ª¾líVlC[Äái®»꺣þÌÔ¸nHM EXƒï Æ‰Ú;¡OÚb¾ñXÿhWƾ­B•ö‚ïTýÈp:’‚ÂÌȳªîÞzªÌ6Ȫ¿ýÊEã*Ž¦Uv¹ô]=§ªâ,#‹~Ô°§4ynƒ“J-Ó[¥Ý78ÊãXu•zl}³º¸¼¼e·_ð)ÿbÔo8»c0qÆo‡kÂoË5ë÷”ÒÖï¾Òa¿]¥.ïö\Ä,ðe0ã¹Ã5á¹åšõ|Jiëy_é°ç®R¡ î â÷{I/#5ç½Ã5á½åšõ~Jië}_é°÷®RÁð/Ä»½‡š’Á^™ù—kÜû†kÎûI¥÷o”zßQ*àvïþÿî(À50‚Ú~&
+×D,×l¦”¶Qè+Ž‚«ÔcîßúK01lp.g"æpMDÌrÍFlJi±¾ÒሹJùÿ#b2bpš‹˜Ã51Ë5±)¥mÄúJ‡#æ*½d×èíû<£ʪiÏ® Ï-׬çSJ[ÏûJ‡=w•Fìê[|ÇW[òß® ß-׬ïSJ[ßûJ‡}w•Æßä{$™
+ãiÏ[žq¿ Ïœ×êŸ{ê=vÔ]|“¿bR̬tË3î¯á™ówB]ãoOÝ ¿Žºßä¯Ä?…„øßܤþôßj¶¡ƒòVFÑHªŠ÷!Æ(ýî½ý5ÈüQç[Óÿ KQo?endstream
endobj
-1390 0 obj <<
+1404 0 obj <<
/Type /Page
-/Contents 1391 0 R
-/Resources 1389 0 R
+/Contents 1405 0 R
+/Resources 1403 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
+/Parent 1401 0 R
+/Annots [ 1408 0 R ]
>> endobj
-1392 0 obj <<
-/D [1390 0 R /XYZ 56.6929 794.5015 null]
+1408 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [55.6967 706.497 116.59 718.5566]
+/Subtype /Link
+/A << /S /GoTo /D (view_statement_grammar) >>
+>> endobj
+1406 0 obj <<
+/D [1404 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+414 0 obj <<
+/D [1404 0 R /XYZ 56.6929 769.5949 null]
+>> endobj
+1407 0 obj <<
+/D [1404 0 R /XYZ 56.6929 752.2918 null]
>> endobj
418 0 obj <<
-/D [1390 0 R /XYZ 56.6929 551.4149 null]
+/D [1404 0 R /XYZ 56.6929 436.1631 null]
>> endobj
-1393 0 obj <<
-/D [1390 0 R /XYZ 56.6929 523.4719 null]
+1409 0 obj <<
+/D [1404 0 R /XYZ 56.6929 408.2731 null]
>> endobj
-1389 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R >>
+1403 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F14 741 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1396 0 obj <<
-/Length 3167
-/Filter /FlateDecode
->>
-stream
-xÚ¥ZKsÛ8¾ûWè¶TUÄ€$Ž™‰3ã©]g×ñÖfæ@SÍZ‰TDÊŽç×o7ºÁ‡LÙÙM¥*Ä£4úù5d¹ðO.r eõ"³:6BšE¹»‹{˜ûùB2Í*­ÆT?Þ^üðQe Û4I·›Ñ^y,ò\.n׿G?ýòþŸ·—7ËUbD”ÆË•IEôãÕõ±ôùéÓõÇ«Ÿÿ}ó~™éèöêÓ5 ß\~¼¼¹¼þér¹’¹‘°>áÎ,øxõ÷Kjý|óþÿx³üóö׋ËÛþ.ãûJ¡ð"_.~ÿS,Öpí_/D¬lnOб´6Yì.´Q±ÑJ…‘íÅç‹õŽfýÒ9ù•Ç&O²&jN€ÆÆ©‚)`UoEÛ–yt,»ãa)óÈÁ3µîðè-u6Íu±s<VÕôí\Öì—2*Jׂ U¦¢Ï ïŠúyºhS”]X^p«-ÊCõ‡IYÛ&žÜ˜¿Ú¹µ[ó ªä±’2¶Æ$þrwŽ´µvûmóìi¡×5ô-Šºv[|`Ú/Gwx¦æ¶)xIñTðØÆsÐìNV#Lñ ⳶"uœ' ¢o1™ÄÖ=o,pûÌ%ÓÉù½h€½¸VL·œ2U2Nt®Ç6ÕËx³°"Î$8c&dllBr¿Æ»²õ™TK$”"6*Î=ŧå*•Ñ-üŸD—§’=µÖR“Å,^|YÈXhkÚþ®ƒ üÀW»dñ¡-F—
-¯Æ;ûK¥ÉÈQd’Åe’f)NhÏò­×u–GGÆi£}qpuG£ f0y=.±ÅæÑf Cä:vð“<úk)MÔÔŽÉÚ‡æ¸]Õºj‹»eæÇ´ÅvK ·ÛwÏDÖÓı^»5Ñ"'ž@q²ç47ãµÐÃpØ3õ¦·@BtäTGû‹ðß`Q`«iº¹-@°É;œÊ`]ÕQøÒÝrù«m·ò¦ÂmG·ÄÐŒ§ßÒÎ €§ªW=•#p½ãV4‰®
-^ÕaÀ+ÌÀÁë·í”~íÜ>ºªSãà\ÏßØœµÍ Þ¦j1v¥ïóNŒƦv±òÂ÷ÅŽ•Žm.Õ„kGó™ZÄ€³¯Rab•fÙäL¢é©PC^+
-†§’B Ôéb¼ï‹Ó{ª™ãÇyNjgÖØéùŸ÷®¬6`PJÙèɧl1C¾©ç½a«Øï]Áó¨rüz•cƒÂ<ØP¹G>z?ž*ÿåIŸC±Á¦Í¿Ð¬u€]m¼i¯”sˆnS ¯Éc1×´œXðF˜-Ýú]ŸŽê“Ä„ûÿÐý°ÅN­"­[¿LQ¬o“"#IþºQŒ©ÎEO5EÙÔ¢Vaã$yëøžjæü‰U'â”Þ*0‘U`À ùa ³Ø`,˜¶CÀ⨨O̧¼Y SƒYà$A+˜ì#žîÍBKÝ›˜’*ý=fñG’èÿûÿÌ@ÐT™}à FT¯˜A ÌÀßy…Q{ë^ØdbHÄúuzª&&¶Ë8ÏM6åâ’Nörð*AäˆÉ8 AZAQì_ìB¾øñ9ÀÍMqÜvƒôy¼ÃBºçyaëA4^ö˜ê¼°{*¼&_i5ý¥° ä)‘¾ÎCO5ÃÄTØTÚ)zÁ*¬ ÖÕcµ>z0ý _höòšä c#ù*<
-Rm»oê–§
-S;‡¥yÕî‰ |±éX¯^™fòØ÷¨×ÓŒXûÒdDÛ¢;}
-èáÒ‡ëÏü8Ð3Ô—ðü
-‘LàŽÁÉoK!¿{XÍ9Isìf 4Î2•[©•÷¥ÖË
+1413 0 obj <<
+/Length 3230
+/Filter /FlateDecode
+>>
+stream
+xÚ¥]sÛ6òÝ¿BÓ—£f" ’¸{J§uçêÜ9¾éCÛŠ¢lÎQ¤"RvÜ_»Ø J”“¹Lf¢åb,û Ë…€r‘éP(/R‡ZH½(vWbñ
+ðz·ï_àLRµMÙ!ùa)³ $|Wö}¾®ù+dÄSU>T—OeÍ 4µMÍËçû=0·§vL·¥¡¢Î;FÝ܆¼«:ÜCå Çzà.¤²’24ZGöˆÌ‚ÒAÕ<–‡ª·+©$ØÚ9íŽÛ}_µMGCÕ–pÊA€åcMKÈÍÈ`{0àØl·/‹ê!"··#m@£b1ÂÑ•ÐÁýÒDïÓ>•‡Cµ™=#-Š9ž>êªë½¥_Wø² ¾!ø¥=PäÍ„–>† Hfm?®@PÞŸò <o³m”Ÿóݾ.ÿŽ§ùþ},=EMe˜*Pl%ÂT€À23++Þm›|~÷Zb¢ë«é™]ã…`>ªñ¯>ŽKtUó@_t ¤ÙlˆÊª% yóP2\àØÑ !œº¼ÁëKǺÇöX3M^M¾A=1:xÌŸx3€5;F8r{Mø›Ñ[œ§tL< pìJЪ$RÁMC˜ý!/úª(髬x
+˜j™ø¼sÖ–žUEÞ1ô\õíòæ… OG`Û1³.í ˆbSú;èó3‘¯ší!ïúÃ2 ŽEî,…û*(,ú Õ Éw%㪆~aéÎÍÙÃEçEÙ¡‰¥*øØž8ö'mA:nzÎP—kÈE•×3L<—>MYn¬jàíÜ…­ÙZ6å¾n_œaZ‰¶ø˜7õ©¾e¡D_Ø´Úœ§äÏ9ã<·æϺ$Fâ„—ÂY"’P鯌g2
+Ññ|<ƒÓgÑR°÷‹kÑ<k1H3N—óEaš&‘öo\€„|AJ’ú­ç2tÌ
+”‡NÒÐÈŒŽtoï9Í‚CIŠi‚}~(›ž°pÅè’‚§e1Š´5 ¶K@‘Ù˜ÑF²à¯¥ Ý%“ Þ ¨¬#^FèÕi0¯k\ä"7ŸŽÍ¦<xÁm œfÚŸ›‘O€Í^èkz
+$D#NâàýpÌÅT
+é`¢¾}›e¢Ð&1‹Õ˜¶~›ßXÅ`R-VQ¦ñx^HˆPè ‰ñHÚσåL<Pá Q^AŽðTB2ŽÃLÆÉÂ_÷l÷jf{?5‘± S£Ítÿ˜ n1d*<Ûpƒ3da k<n•!ŠÔã•ã/Åe
+c$Ä‹^\ª¹Íu?JŸñ¹ŸÒ9/ [Id²×…íS]ö@u¡Ð;¶£X$¯ó0PÍ01¶
+ëMõTmŽ6™€ï¡Ä—£|ELòœ'_Û%hx¯y ‡BÜÎU.APðPŸ@ OŸTÄ5%N«ØMµ™æÓö\ߨöCñ^íJÊîOn
+IƒSOi5ìƒÉ$”Ùr%ÔØo7›
+9ë×Dzè‰Aì­åÅ#Ötç58ä@¬¢ T ªŠ5Ö¨Ãr*Ž!Æñr8XÀr¶zN0³ìZ")@·áhçY 9}¦8kÏíô^"ˆYij˜Œ×·å.2ÔÐ.UÓ—f‹9¡[ ªÚí©¶zâ£ôŽ‚‹î}Ût<™Ø–üèŠ..’q(¤.“›ƒª³()i¶=šlh_Æ v˜,ø<$Œ¡ì@=†ÛÈÄ(>œQðmؤìdsæD×Û~\äîÔˆÌyÍQ,v»ÇöЯŠc?Û†ÂL4J9Ö
+iœojÚ¹et¨uæ»/eôÀïàðëïceÛÚV>Ɖ(‹ãˆ­Œµ„ÚÊ,gŸ
+e:^Žë2ñÁHAOd*îà,ÀÐÔ:“!¬hV
+2Æ7—Êfn+ µ‘ÑW\V¢%Si€í¯.]ZsÃÍ{jƒ¯5wF/» ™}›)^½yÂK’„±ˆÕ«^D†q"ô«^kžÄ­’ÞpϘz–†ópÄìÛ®«ÖCDzå3 ]
+¯Ã !Ðà³ô‰u÷{—ªÔÕ®:1òAoõɽOžsÏz×/®30/ÕHËPc Í—–^±d»ê¯9¹¦
+ŠR¡³@¤£.§S^BÑ~ÌÐ`„%¨\dU}á{W5dŸ±ÿùAº™d$š2&ÂM&›e4“åø$EÒŽ;NN~[jpùýãjöÅüØÏ*h˜¦*ûºR+J­ó… ?—‰‹ÅKQWÅÜ:Y¨áLæg€ߓœ QÔÆ.Ó`ð…Ÿöâ ¯ô\ÖõCó±ÑÎuˆ´.
+β^†5¹ÎÃæ‘'íQ›7¡è#üÜ>ã/þi‰- ’“Øæ+’ö F0Óül½¿vŠ$'Ú ‡ÄÑÞñ8ó@àj[ª5gŽ@ãL»®Ÿ¿ 2¹šË[Ο‡£’Q©ã²ŽÈ¨ £f¥9Ó`»"ÔÐ 3þþ×V YíÆõEQ–¶vÓü°ÓñÆ„{ ŽË¦æ·û˜üÌÈO<¸c7záTéÿg¦Ï$†—Æoþ[ŸñA,•eÑ|ÃJ‰$Ì"H¿˜)Û±1§œtÎúÿ
endobj
-1395 0 obj <<
+1412 0 obj <<
/Type /Page
-/Contents 1396 0 R
-/Resources 1394 0 R
+/Contents 1413 0 R
+/Resources 1411 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
+/Parent 1401 0 R
>> endobj
-1397 0 obj <<
-/D [1395 0 R /XYZ 85.0394 794.5015 null]
+1414 0 obj <<
+/D [1412 0 R /XYZ 85.0394 794.5015 null]
>> endobj
422 0 obj <<
-/D [1395 0 R /XYZ 85.0394 453.4423 null]
+/D [1412 0 R /XYZ 85.0394 349.7668 null]
>> endobj
-995 0 obj <<
-/D [1395 0 R /XYZ 85.0394 426.3513 null]
+1000 0 obj <<
+/D [1412 0 R /XYZ 85.0394 323.7864 null]
>> endobj
-1394 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F21 710 0 R >>
-/XObject << /Im2 1049 0 R >>
+1411 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F62 1065 0 R /F21 714 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1401 0 obj <<
-/Length 2863
+1417 0 obj <<
+/Length 2688
/Filter /FlateDecode
>>
stream
-xÚµ]sã¶ñÝ¿Bo•;‚O˜<]’»«3É¥uœig.ž -Q2'©ˆ”ïœ6ÿ½»X€2}¶{ÓñÅb¿°»Ø…,fþÄÌd,óÒϬ×ÌpafËÝŸm`í홈8‹„´b}}uöåegžùLf³«õ€–cÜ91»Z½ŸgL²s ÀçßüøîÍÅÛŸ/_[=¿ºøñÝùB>sñýk½½|õï.ÏÂ1ÿæo¯þ~õú’–²Hãë‹wßÄÓ碗¯ß¼¾|ýî›×ç×Wß½¾êtê+¸BE~?{Íg+Pû»3Δwfö&œ ïålw¦bF+• Û³ŸÎþѬ†­SöÓÆ1#u6[(Í🶲`V@²Æ³LIÕYYŠ)+',´r¾Ì—·Åb¹-òª¬6‹²j‹Ã]¾=U_d–)cålÈã$Ö„(j Š°’)Jd¹º-ट7 Bq ñ‡r»¥Ñá\¸y±«ïV›oq¨ø<(AТjeÑ| j~“7ÅŠꊾyü~ù3màäÛM}(ÛÛݨÿlá9³Êÿ
-Á¼12ˆY€l÷¸~b_™1ǵK<eØSkÉœi箬ŽmÑ€ãJï£QD6_ëü¸mqbçeCÀŒÓ|¼çbM«MÑÛš
-s‰È~˜J8–y%]Äa].ë„Yƒ`ãÕc˜pÖt—²°pÑrÎ6äóŸZÐ}WTQ¶·‡|·Ë‚ÎR3o£k&Ð+÷¿æ«Õáý—ûC±.?n‹êšþ¬%óxóŽlöž0nêͱ¡á}ÑüZ~Ňӯès=eð¸y¨ïÊU±(?®/ !†4ÅïÇ¢i_Jc$G±ªšÏÙ»8®ö”¨:în’iŸ¡&Ö—‰ÐòªY‡æ³v/ î0ìø 7œFuU,
-
-àIsŽd|Ú˜ýÉü?Äô‚I'í¤ Èc[Æ”.êÓÐŒi{(½”® žM¸Bb8é ×#~½.#f=8šJY¦Ö/f6¶‰r’™ÌèIÚ¤;»—›Jj¸Á¦|/ñœ<ÕÏ1‹y1³±Y4çL{7" v]Ó óž®·'÷×3ÒáxÿG£äW× ‰®ÕzŒÊb²”øó«©B8jË„†`é
- ÷tômñ ç²*Û2ô
-Üc›‚†¡ûQI¦†Ð©er¢,¡iàzþcÊy•Êxìê¦=á¼$27 ©mú:÷m‚JfÚäá»Ú†¼›§;‚6þÔ4­’³AËö°²†ÖÏÛÌÇ3Gû¯Ø²®Öîa ÿµÆ
-ݧÃò˜ÀAS
-ÓzTÈqijûgõ¡’**‰ÈÕ"v Ú5™Ùñ5tbO<D)HWgãó3 @i”ÓGBPÊ"0¬#z;]]YÃŒè곧B®+£R<×ûXõ²ê¹t»X'Àw³­o0,lmhraû[$Aáf‰ý“‚LæOʘ<&Õ|”A'ï—G«JíTºåFOªjæ{Ÿè
-n')3Å´$èÓ.F[ˆ”–6
-`éû´„xA+GÍâÆ –®ûmÒÉaxӮɨƒcÕÜŸ<Q’6û±™¯)Úvq‘¼Ù¤D„°±c›=¢Ì€×gTŒL—ÅÈÌ¢·†íCûÀZòVX­×½ ™ PËîÒzúØ\fx+P/cú†šj"¯i…RÉc­Ë{FXçÃ0I>L?–„/UGÁKŸï­ÿzƒÿN ôIÇ_˜C¶QzØQv?\Áò*.“¥︧—\í GWX~lëô1àÔ|êùšRŒnò Ð€ï+ ÁhxuÛ×u,ˆCC¿oNË!j~=ý$¬Ü¼*‚
-¢QMþï€>û¿<úÑ–)çäôOÍpŸaêSI¨ðÔäþ²-™Êä„èÿ¬O*endstream
+xڵ˒Û6ò>_¡Ûj¶,’ *'Ç{'Û»“qíÁ™rÑ%±B‘
+IÍXÙÍ¿o7 H æḶtÀƒF¿ÑhHÌ8üÄ,NXb¤™i±˜‹x–oÏøl ßÞœ ³ð@‹1Ô×gß½Vzf˜Id2»^p¥Œ§©˜]/?Î&Ù9`àóWïß½¾|óáê幎æ×—ïß/dÌç¯/¾ Þ›«—oß¾¼:_ˆ4óWÿxùÏë‹+ú”8?\¾û‘f 5 ½ºx}quñîÕÅùÍõOg×/c~WÈÈïgoøl lÿtÆ™2i<»ƒgÂ9ÛžE±bq¤”Ÿ©Î~9û×€pôÕ. ÊOp&U"”"$ÀØ°DIeض]Ñ/švY´È ,Q£%QÊD”¦°¢”¸™_oŠó…ɼX‹t¾*òÇzÞ¬h¾ß”Ít›f_-iö³[µ-ë¦Ey¾€±RóMsWÜã™®¬ó‚d5-ºº2©[Öô©÷ddËeÙ—MU4î€ :¨ÃnŒÍž—…Ìı´,•yVU
+͸€ˆ@¶˜åYÜ7YiXªõÑdO=T0-D2KRÍ„2â" Åêa‡ Ž„-Š:û\§» ~,#ñøöT`ÿ1«BÆLñ8šp¹
+HÏ0‘ĉÊ~_p"b&R^p/œG¾eµé} Èé=µãK†îÇF²,VÙ¾röu›UûbXÐu"X*"ãh©›¹‚AO=©gPRªùSzA=¢g5Òs^Y BX”5¸ 0vOå‰f*ÖòqJ¨
+ÝlQ÷mYt¨xˆÁŸ!t,éƒU7´™k¾ú@‹G0YµnÚ²ßl_P°5œi•ši8Â0ª›¥<Š'žì=,•Â¯„“eߘž4pMÎk¦0™pO×\®è«=lð3„";ÁQ,2BS´ãÐfYæåi%ÞÁÑ4§¼;m`ìËó½=í¶Y.Áà¸~ÂfGPج‡²ʾ,œx»ò@t2LËô ¨
+Úâ÷}Ñõß„£XÖ™\»Ø/wí”OòŸ¹;ÆÖoBзYÝ­Š¶{îjZ½€0¸E·ÇI¼ŠP¯©‹
+kÿZÌP«yn/†Ð¡²‚ífî1&Ó7;š©
+¸%:øÕHaíõ°ÞÃ5Œü &q¦r
+]ð…ÄŠ0Šç‡fOeÙQx´#*Ϩ(±2†‰qôDZ…Ø·/jЮË[{Â~³wë?gK·AÖg(¹ÄÀÕ®ým€´/MÐf‹»ïc—ªLØsGÈ­õD»Ú·`wm(sÀ”¡ôïFd¤PûçVý›UÐ¥Rƒ_;ýA-Š$ñPÁ÷8·Åžûz€
endobj
-1400 0 obj <<
+1416 0 obj <<
/Type /Page
-/Contents 1401 0 R
-/Resources 1399 0 R
+/Contents 1417 0 R
+/Resources 1415 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
+/Parent 1401 0 R
>> endobj
-1402 0 obj <<
-/D [1400 0 R /XYZ 56.6929 794.5015 null]
+1418 0 obj <<
+/D [1416 0 R /XYZ 56.6929 794.5015 null]
>> endobj
426 0 obj <<
-/D [1400 0 R /XYZ 56.6929 654.5469 null]
+/D [1416 0 R /XYZ 56.6929 550.5868 null]
>> endobj
-1403 0 obj <<
-/D [1400 0 R /XYZ 56.6929 627.5235 null]
+1419 0 obj <<
+/D [1416 0 R /XYZ 56.6929 523.0374 null]
>> endobj
430 0 obj <<
-/D [1400 0 R /XYZ 56.6929 355.4402 null]
+/D [1416 0 R /XYZ 56.6929 249.7563 null]
>> endobj
-1291 0 obj <<
-/D [1400 0 R /XYZ 56.6929 325.2926 null]
+1307 0 obj <<
+/D [1416 0 R /XYZ 56.6929 219.0826 null]
>> endobj
-1399 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1415 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1406 0 obj <<
-/Length 3514
-/Filter /FlateDecode
->>
-stream
-xÚÅ]sã¶ñÝ¿Brç„â“ 'O—œïêLsI}N?&Édh‘–Ù£HE¤ìSÚü÷îbŠ¤¨“<tô p,û…ÝÄŒÃOÌbøJôÌ&š.Ìl¹¾à³ô½»~Ì" ZôG}y{ñç·ÊΖD2šÝÞ÷pŌDZ˜Ýf?Ì¿úËëïn¯n.ÒðyÄ.&âó/¯ß¿!HB_}ûþíõ»ïo^_Z=¿½þö=o®Þ^Ý\½ÿêêr!b#`¾ôNLx{ý×+j½»yýÍ7¯o.ºýúâê¶ÛK¿‚+ÜÈ/?üÄglûë ÎT›Ù|p&’DÎÖÚ(f´RR^|¸ø[‡°×ë¦NñϨ˜™XÚ J5Å@“°HA2°y¨we›Š’yZ>¥û†ÚOõö#0CEÑüö!'Øf·ÝÔÿ¨ïé¿…^à¬%zk‰X2 Û
-ÿßÖô¿N?º Åó¢õ»¬›¦¸+ón Ÿ-”0 L‚%ÆH‡:+š”†ÆÊqÂ5vŽG±$àúŸoo¨•?浞¨%çwuû@°uÚ´ù–ÚÈ×hÊôÑãƒk¿Xí{w›M½mé£h_A#óûÚcÉ?¥ëÍ¥˜ OQ]y@ Ñ‹X6Ø`“oómCJ_øÿ»Ýjµ§&Q å6mr?À­ŽÀz»½Œç»Më;²´M©å·-Ïœ~à_Æ:jfmLÊz;­k ‹µˆ½´ó¬j&4Bjfu§¤ Þ"žg9ð|]TH¼)fl©ÓÉ¡e½LK‚O¨ýT”% HÛ6_oZ?­¦¿ˆ_½yÿÁÏpGز^¯wU±LÛ¢Z‘–i°ßب¡ ž
-§ÀÒ0hl/S¾®[ÿíIg…6+¸·Yäx~Ÿîʶcðû"˸Ú³fŸO±Oh–h,Š„N¨Œ¹g…$9Ó²3IÒb—mMñk>±”
-8üFUr0gM=q¤]8ý0Išð‘9dd«²¾KKàbþŠ`÷Á#:\æ¯ÆNÐy’dßzgù#ç’ºŸR…ëjÏù„"´ÈÜÙG§ŸøU’­ˆ6e‘7/óÂX/²N?}Ö¾}œ2²ožû~c\Åz·¦àH¹7vìÏ›&]ùÁ½ö¬$ÚØóöÌmgõ^ïUœH ÇCcäÁɼ 8¹Xê‘zt‚•’LTJAç7
-É¥ ²è¬x¿
-Ä£† 锥*¦´Â"ãR£„`Eii ¡„˜à9¥FÉ’8Ž§ ‹ßâ€jˆÃ8,Z)Vuf2J É⃀²÷[9§¡½ÓЧj‡p¨ÄÊŒ¶>f/G¯:?«|’—Pº
-ÿdÀØ¢S—F•I—>ñÐ⃥‚‚ŠùžT”TBŽŠ1šß~¸~÷j,!"£h¦#Á"¥cd unW3jÜôª¶ÝøEÂqÕö/’ñ!¤ÇNTsDMd˜j@ÌQá8 :GÁ—烠Õ}ÊGó6-)ZG°“þSXk‡e=ð\Vòù?<"ëŽðn†+ôÀ{njÕ~vbXÈözE’A°ÂüašƒM2ZÓ`B¹ªÒv×ÕYLWô3^Áà•Wùt0£Ï]Cl0¡Ž
-kî{„»ô»Q'zC©çõzþb»ðõifc1Š¯{Eé¹èóΗVͤôS± &MË©² dŸJ&ñ¹{>ë4ÞÅc4bi‘ÝøÊF›C: µ¯ú"ôú»GM Ÿš8Pä§ôÓ>’e>ô8)9Š|rdè„ ¦'kÏ£"\‡\ž›~.pŸb œêVzèð £ï‡ÜU€'iƒ¾ü1/ƒþã<K š¹KŠ
-úȺ­&ÇSýnO" Ž æžò·Ö0™tOÎ
-Y1Þ•6ÑQîEin¦K#/%ø„×í_?¥áÎäöÙ›d?÷”×…x
-øf^¦o¦»Ó]R&·âŸ\DŒ+!Ÿ™“«ˆÏä®_?kN çÑgÍ Ýå¯}„'wgUw¶vÖ¤BÍÆ•3£¼[ÎsëßP`IÅMéY“Ò·&埯`ÇЋ_bG¹™Š_TävRÐÅ© y€>5<„ñû`@˜Ãœ2 yÂ)tƒ… *{iXÌé€%ÂK»ÎKž—ª‰†:.v—‡zÓ<Ukÿ$ÑÿZó| 3 ×H<×~Ür
-` Ç›Ó^-à4ÕÄ
-½ò¸?ùA.ë /„ädŠ`†?¯ñäç²ÀÄÚuüæ§~P9BJid2ª"í‘16šçX3z)òÛS’åøC–D%¡DßP®8TÝË®ïÝ¥à±>ŽD}úU@ÜݨNQ3e‚Û·ÚN\ óÒßÓ{ÙFå
-b`µ‡­â
+1422 0 obj <<
+/Length 3904
+/Filter /FlateDecode
+>>
+stream
+xÚÅÙrã6òÝ_áGykÄ%.‚¬<M’™¬S›IvÆÙ£’TŠ’(™;©ˆ”=Înþ}»Ñ ðå#yØòƒ€Ðh4ú-.cø—©‰b•éK›éÈÄÂ\.wñåƾº<gî'Íû³>¿¹øó[e/³(Kdry³îáJ£8MÅåÍê‡ÙyýÝÍ›÷WsiâY]ÍMÏ>¿~÷%A2úùâÛwo¯¿úþýë+«g7×ß¾#ðû7oß¼óî‹7Ws‘ë%c8³àíõ_ßPë«÷¯¿ùæõû«Ÿn¾¾xsÎÒ?¯ˆä—‹~Š/Wpì¯/âHe©¹¼‡N‰,“—» mTd´R²½øpñ·€°7ê–NñϨ42©´ ”jŠ&‹CÈÀöWͺ8À±¬šÝ—Û-¶älQd¸鬾+WÅŠçÜUqçWìë¦)Û§l:»^¸)ZÂÓÖÈ# Dô(‘ʱú‘†ÊÏéS+D-ÅS^!¶t–y*Ýp·æßÛ‚¶uT»º-<=‡»ñ!RÕI¸œKEB&ÀKØ?3FºÝËjÉ‹ªÍ·pV-5µ°º¥é̦@wùöÈÍš§ãØ)K„5‘&ãóîŽåóòÓú0Ác£Ä(Óë}[Öa/«n¢ ,ýn¶õ"ß2Ì-m¨³ØÖËŒ†AÇ®8£T$TÓ>gò†ô!§ŸU±ÎÛ6rKb˜j£ÌÆÆM½™>wéTI>É¡øåX4íÙc›(ëdb¹Í<¤SÂÆmqØ•Uáè(¤À 2/Ä ÎG—^ @½Ý•Á –mYmhž;LÊyî6¿+pZšyáI½ˆ9ziÕHJˆmp­:ÎÌk¿Ö•“¼d(Çf¶&mÛñ I³™mÊ»¢"ØP°ÍèL3ÌÛåMKpÔÌ4aÍLXZÝÊöUŸ?0æ¥FëuGÃé­)@-UúìkKs"­€¤ÕqI w•gw¢ ÄŠeZN†á7È0‚ CÇË04K9&)}Ž´&nïë¾E¯¢tÿžq¹bk#Äû†:ímÞÒðŠ‡‰Ó8ï¸ß×í³(,?¶õ.oKÎí ®ÉÔAk‘»õö} ("jÞ #}ëš~ñJ•SꇳõÍ™#9C» ¿é¬*ƒ
+­•ß¾n?ƒ–öæ†ÂõÂ0߯^OH£F˜e^À`ƒS!œ‡Yknëã©L€Üí}þÐPû¾>|DÍIg¸l<€»ãŽSø=cÎSÛ6Ï6çÚ‚§ÉȵICitP¢§5ÎfÙÀNò¹Jþu7àMtJge˧dæ9 UÂD 3#Ǹ*›œ¦¦þö ¬2¹¼ óÐ*È¥FЬEÝÞŒ–k“ì@ÃY_š ')w¼YÍ£Aò S’ÿ³uÍXŠOùn–ŸI+™"2ÀØXwÄO¨J'å=ƒ²8n6lI*6-ËCÞÜÍÐJ-ëÃá*÷-¬ò–mZÌœ‘Áz™ Mµð¶¸XUSâ/uduGï:•H®S Û¹NtwŠPvó±¶É†á„¼m‹Ý¾åe5ýò&vöæËwx…;8–õnw¬Àè9ÇK~
+XÕ–Î)bñ0E.Ü„JŒª*ß« :JUÈøj'§Ãƒ §TC€IÐЩ‘é_¦Ùð2
+0‹hhE‹„êãî*™b„’¬[‚1 úP©q_6·4莥ãî‚ç^qf¬ÙóW-ïÀüQ\‡=ƒ¹‡æLI.ïÖ"I62ÓÍ€7B”lí-¢³ÇÛâÕØvñÊÀ²±ü1Ž% ßSX„CíS6¡ô-Íú£D
+÷¡·%)Ú í·eѼÌ
+Cbí­È.ÿô¨~sž>Òï8óú-ø`\åŽ7¤1+;ŽM“oxroÃaÆ-#¡}ZŸc´žåÞQU­0ëMÓ¡2Æ^I½ ¹TŽSÄp±R’ŠJHžÿ
+*Šƒ$¹fE ÇÒˆ†!Š"t¨¢p&ÁJéÐûŒ–•L‚WJg1è øXÕ÷cQ{¹Dÿ~1e%óÉãÄõCªŒ–O]e™J†^NÅI¤´MO•
+D’4Ò!«€Ì°¡­]f Ûáê>1“8ZÜü±œA9‚p2‹¸‰?SG˜‹LùåVO2 >‹yHwuÐ-!­Å
+IJmF·¡!#>¶4™AžQ9=jbE@G½æ"ôÕ
+èhëzÅð‚sµ ãï iô‰aèÃô}Þ.o}QŒ0 ̨QÌ/ð—pb "ÉÈ€Ì'™žý ©sô0°t¾;X–ëêpêŒMÒj;?n}„ çb±‘3¯—ˆÃEÐnÙt9'á)ßEÐRàýðîÀ.M$ÔaÕàødLÙY\O¦ëXÅ‹_¶™•QœJÕtK®Â‚^Èq ŤX½Â˜LŸ9hša~ñvîmD$ yo}ºŸU ÙZüü”*(©,ð¿ióÖi çÛÈe1DåÎ÷ÔlQŒÒÆ£ÊVWr<¥CƒÍT2íë¤ 4Ë^ ÛrçÊÖÇ_ШŽ»•ØW1®–ÇC"¬¬õÑit|%T +¡ñ ÚÛdÀ\6Ìü`‰¤’|”pVS¯L—LõH*ΰG©8ן{{(ˆƒøÔó¬?»`@¾ô&9x{ÇjsN°$ä“]…'Ð<ß³8OJ™Õ‘ÔAñ¼¢rè&¢8ËÄ3SYa¤ç×ÇâáL½Áĉ×4¤=+âQC|JSU¤;Za“ñS›„`Eii ÃŒl¢“ç<¶É(KÓtú©m0Îû(émKƒV+%º²LTBFiwM«O]9Ó¡ÙtèsDp-©2#Œ™£mJÇfM ?Š¹}˜ñ¤ÆØ"_[£ààˇK?4ú ¯ ¦böÀÏ>ÓÇ™•d0@¿ùpýÕ«ñ­‘@™$—
+Rœ4†|XHƒ‡Í%5Þ÷Þ.ÃüyÁéÛå)^$ãCáIO-øUsBMb"!Ô€˜“çS?é)
+Ƹ˜‚vçÄ=Mfm¾¥˜Áîüs6Ř=°_VƳ0"ëyXÁïLŠßæhiÕ>º Ü¢ßÈŠÜͦp±‚ýa²“M6ÚÓ`Z¹©òöª-&”þ ünŠª8€ ®¨{lˆ ÆW`Ê1!8R
+f=@™uaé<Qvözªþ2|ªsÚrSVy¬mÏÝ<£Î80âôÌ&ÿr,9ÖÚñE(Kl*?¶xðûydȬ›L¾I½ÞBüwÜ@(§c&›C¾ÛAnè:èyý蔫ËÀb™ä Ûm¢Xœ<³"VÈUëû†ÚΈ`cwܶå~ËS'&[
+ØYaåýá.‰Àa”‰ÞTj ×¢Qæ/¶K®*P8›Šlx¥½°bË\äìó¤vž<^µØOE„˜:-§Š7ƒ*™¥O½Ö(°YçñÎï’ ÔQ ŒïÆ7ÚtIÔþe ×ßÝiq‚â@ /é'8eµâ¬qRŠ”pŠdz¯ý"“X•rÈoÄÚgô±égô±ö‰©z¥‡/=Xãƒ
+ˆË~MõR%µF?©¤Æªß¡¤R(š>aèG`¼"™* wb#‘Ø1P˜?ï/8@Nñb úN‚‰ì I „O‰’’N"¡0ë)BN°õË…ø(†Ÿ†<¯f.€•á3° Üù+M$ø.+Ÿ¶»!C`œ¾Lá“ØÈ—[\ã-nrÖâšgZ\×B›@¦×Z0µg®-ÑbC¡²ñŸ¶Qf­ÃWpÓ¿95´ÙY{«`Œ´Ûj2L°”O{©7L6;ko­‰d>\xò’U‡'Ú#JæÁ¼(xBª¡•ñ„Õí?BåþåîíÑ÷d^{ÎêB<|3/“7^v—ž”É£ð‡I+!Ÿ™™«$|VéaU§,Ž“GÕ ò×>³§³*øÖ MÊWn\Q3ñÁ»½?·ü%ŽÑ­¸%=mrSúÚ¤ø#Xð„^ü’:ÊÍTü¢w’’žO­Ï£
endobj
-1405 0 obj <<
+1421 0 obj <<
/Type /Page
-/Contents 1406 0 R
-/Resources 1404 0 R
+/Contents 1422 0 R
+/Resources 1420 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
-/Annots [ 1408 0 R 1409 0 R ]
+/Parent 1401 0 R
+/Annots [ 1424 0 R 1425 0 R ]
>> endobj
-1408 0 obj <<
+1424 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [116.0003 457.8291 166.1092 469.8888]
+/Rect [116.0003 361.0037 166.1092 373.0634]
/Subtype /Link
/A << /S /GoTo /D (tsig) >>
>> endobj
-1409 0 obj <<
+1425 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [399.2874 346.5415 467.9594 358.6011]
+/Rect [399.2874 253.3317 467.9594 265.3913]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1407 0 obj <<
-/D [1405 0 R /XYZ 85.0394 794.5015 null]
+1423 0 obj <<
+/D [1421 0 R /XYZ 85.0394 794.5015 null]
>> endobj
434 0 obj <<
-/D [1405 0 R /XYZ 85.0394 240.6473 null]
->> endobj
-1410 0 obj <<
-/D [1405 0 R /XYZ 85.0394 213.5966 null]
->> endobj
-438 0 obj <<
-/D [1405 0 R /XYZ 85.0394 126.6995 null]
+/D [1421 0 R /XYZ 85.0394 155.2922 null]
>> endobj
-1411 0 obj <<
-/D [1405 0 R /XYZ 85.0394 93.8745 null]
+1426 0 obj <<
+/D [1421 0 R /XYZ 85.0394 130.8971 null]
>> endobj
-1404 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >>
+1420 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1414 0 obj <<
-/Length 2970
+1429 0 obj <<
+/Length 3082
/Filter /FlateDecode
>>
stream
-xÚ­ËrÛ8òî¯Ðmè-‹K
-^¾{ûúâÍï—ÏOe\_¼{{:çI¼¾øç9Bo.ŸÿöÛóËÓ9S ^þòüýõù%.¥DãÅÅÛW8£ñsÑËó×ç—ço_žŸ~ºþõäüº¿Ëð¾,ö"_O>|ŠfK¸ö¯'Q(´Jf·0ˆB¦5ŸmNâD„I,„Ÿ)O®NþÕ¬º­“òcQÈEÊ'ÈÅ”
-OS”4eoZïˆ4>&Ì­ÓÜ2Æûœ:¡ç„5SÝ!6½߶ž çêÆ% €îC÷G@2+5~óõ¬±FzuáQ¨RÜò¼š>KBÅSEÂ*ª¼›(P1NHY]ux”e•kÿv PJ0ipxýò=ŽÛ:û’w—ðÀyUT+Ä14„‰v›g‡G9f™Ç)˜¿×—b{èD¬Ã(Rb&#ê(QOñO€©”šöNóžâ|H]Ï3‘À iÉö'[«8*ga¤%ÝÂùŠ§‹@Â^ÅĽ"ˆpÌRª¿N=ÅGD'2di*Ç"0Ëes„7Tk)B·ë"[“âÃzÅêÀòƒ;qÎGéÀ/Þ‹qlÀϤ9œOkÁçÅ<¹ÇR¸=—ñ½‚å<{ár–jðJI”þ°`{Šó!ÉcÁ‚v„ŠAÐëѬ
-pV5?tíÂ…G\u>ØMÜà×±eöîµù©E<dÒÑÙ³”[JäI§š5®£CÃ]xÊ€(j!1¸¿ë(ž³ýkâ1gèÔwmÞ{ùcuMA%¤¼ß2žRB.FñÓ2µµµ§8’<ÖV&t˜¤LîO~X[ȆÑVK¦~þy*H‘ àœÕ$Ëa ¼¸A™V5~)—È)1|Þ÷ìGEc\x¢%B7Îï
-‘˜Iýãjå ·'‚‹Ê‘Vûƒˆ¯ <Ó|¬qÌÃX¤l¤ø*{LÖ¿íp``â[ŸªX üì“Tï3 ØPÐ$™r×:B˜[Üá¡£n˜)'^&TZhº)ËúvÊzd(eŸ>g¥×µêÅÁË¡‡tÇÖûã<„P!˜¨{ÖÑõ´¢ë² Ä1º°Û¼ÙÞPCídP¹`Å%505÷ó(
-%õ 6 > ¸šƒðä` "…lᇮ§8’œ¸Rc ÷h–Íé0=eœ’#žÆ“=ÅG˜ðúð1“6MYDBÒ½E@R'ÐÂ#3œPAÐÀ˜óÇ4P…1Sz¤¨Î€8å-”agSé,€|…TfÓ'½Ãc mãaCÎ<RVŒñî 6È pLM«7X¶lhÍ•b&à§yÐU–ã"Z*
-*ÌE y‘â6Ùò(íÛ{òhEð\Í’ƒåüK~G×»ßúMc6ÓL$ ö)´mhGvL)Úÿu/f«ævàóå,ZµÛ,òæaxˆÿlJ?ãýÿtÝçC†Ÿ>Q)0ÅûϦ„¹ž«J¡zé…ÌŸ*äW¹Mÿªbÿ°¦"Kû½5«|B¼ôEŸTL˜2º>q1‘Ö5®’©FV,‘Aפƒá«·WWç/nól×ÝŽÐpëξa­'ÖfM±Àr-²íÉÃŒ¬CÅJÌ„„JÆ.áb³š!p9hÖöøóá†ãfí1]{Õ«Þ3q¨Ž¸<PG<qsÔ0î±ãሚ (ϽH}73t:Öõ^Þ‚õòÆ&ƒ¬.—FÁíÚùáã
-;³È]Q!ҾߊDµ¤„gpØ5§*pcKzÀB’(jÙ]ØDÍM7&¹Æ³EðÖféùYbÁ7SËÁæŠ(RÛ6ö„WÞ?÷aIJ1´.¿åTÆ’§dàa
-€âýãüß>WH!YHõX.——mÞ*ÿ^¤?yu'vèNä„ÃŽÊXG#ýp%}%ö©±4H„¦n¸Pƒ*f¿Iˆ¢‰¶×kŠÜõcp$&[÷{[›Š£‰hR9ÿkRpr\´]œ¶©ôÊZJ(ªùÁtö÷S³²ç‰8ýJS¦\ÙH¶Þ¸qLNŒûÀ ¡7q€o4ÈöÉÙ5×ËîDwÎç‚ì/ßÀüÕÖd¹ç§3 VùmY8s±;-#3 T?«‘»ìv÷c{}µÎnUÕ}¨z¿¾ÃG!yæ ´¤}Ø8[,<Ê×nK_.î¶þ8_TFî–á=Ù2–$É>[”-+òÛ?YŠ`2ŒR"õÙê“°°-–$9(²Ò´í§aÅrð® 3ÏÊé+÷¡.Òg‡ñÙõAÜüÏî§É/¨¾¡6ÙŸ 6è ;ZHÌæèÞ,þ]Þ~®›Ï¶Ý<Q-ñaµäă=A*~líóÀëå?÷>ápÏ|RÀÈÿÔ?t
+xÚµ]sÛ6òÝ¿Bo•o,¾HÍSš:©{×4g»7i&CQ´Ä Eª$×wÓÿ~ ì‚_¢ãtÜ=p.‹Å~S|ÁàÇaDF˜ElT2.Òý[láÝ›3N8+´b}w{ö÷×2^˜ÀD"ZÜÞ hé€iÍ·›÷Ë(Á9P`ËW?¿}}õæ—ë—ç±ZÞ^ýüö|%B¶|}õÏK„Þ\¿ü駗×ç+®C¾|õÃËw·—×ø*"ß]½ýg >!z}ùúòúòí«Ëó·?ž]Þvgž—3iòÛÙûl±cÿxÆit¸¸‡ ¸1b±?S¡ B%¥Ÿ)ÎnÎþÕ¼uKgåÇY d$f(ø‚óÀ„¡I04A$…ì$(H…1¶lڤ͛6O›UºKÊ2+<ñ ¼ÈöYÙâðûìWÆD™·yUâLRnø¥I¶™• ì.×Çð:‘4nÛÛGâ$n‚Xí3‡3ÇÍ)a,VÑ` 1*¹Xn²´Hês®—Yƒ3iµßË<MwÉù²?ªEh+|®3|›lƒxëœiØád³ÏK`²NV–·È1 t¨%@^òÀV[Õ$IKÞ>·É2IÓ¬™¼ìOŽã¼¼«ê}Ò‹»º£ F”Éž &«?gµUØÀq‚ç:à!Ý÷í.·Dy4•æe›•zç᱂ÃuËì÷|]dÃ÷@ãx8T5QØ‹6?x”‰ íÔÁÝDÕViU4~W"è;ÞÛ#^ØL¸‡c‹oRœ_u§ròE?€+ʶ€+q¸¬Jýp{û¡NÐ
+“¦ñH*0Î(
+!F()¾&" 8¡ÖóñhÕQ\ Iú`Ós&C¸"ó~gË¡ó§B<`Æ{}ç,¾^1¬Õ\>*B(Žcý׉ £ø„T<Šâ±’ͦ~DÒ[ª5)—÷»<Ý‘æÃû)=1}§ñàOœ÷ÑféÇWï>+œ#ð3BŽçÔpzJ„XC§±zT°BD`/Ž'u
+F)ǹàe‘%¥”ÊÙ„“Ïxâh6ÆÅDÙBwÎë
+8ù$$íòíÎ÷
+á&KuÞ>àM·j]åËø3o<±&­ó5–l¶õz’ôyh¥åB†*`Üeþø®Þ.¸´ç;ôÕ
+û§YÒŽÉ1×t¶~Á.Ùx~ ÿF–øòsRä›Áâ’(JÛöÌ©ûëžÖ£>«Â~CAg×'NáÀ·
+_+~;_ TFî”Á#™òI9")Sþœg÷Ï+CBD´>ºöVÄvË(œ¨Íû´Hšæð\™d%®³J‹8éÊ÷ ÒG‡ñÑuAÜü/©·$¾ û 5ÉžI¬¶¬Ôl…þÍâ?dÍǪþh»ÍO•JN<ؤÊÇ>sÛÑëæ?vNaºf5+`äîÿ;€nÿt3“M³NYžýßžþOP›I­Å|^.lOHK陲œÇâ„sÿ' SÖÿVíÂendstream
endobj
-1413 0 obj <<
+1428 0 obj <<
/Type /Page
-/Contents 1414 0 R
-/Resources 1412 0 R
+/Contents 1429 0 R
+/Resources 1427 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
-/Annots [ 1418 0 R ]
+/Parent 1401 0 R
+/Annots [ 1434 0 R ]
>> endobj
-1418 0 obj <<
+1434 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [432.8521 368.6685 481.8988 380.7281]
+/Rect [432.8521 350.2114 481.8988 362.271]
/Subtype /Link
/A << /S /GoTo /D (DNSSEC) >>
>> endobj
-1415 0 obj <<
-/D [1413 0 R /XYZ 56.6929 794.5015 null]
+1430 0 obj <<
+/D [1428 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+438 0 obj <<
+/D [1428 0 R /XYZ 56.6929 769.5949 null]
+>> endobj
+1431 0 obj <<
+/D [1428 0 R /XYZ 56.6929 749.3407 null]
>> endobj
442 0 obj <<
-/D [1413 0 R /XYZ 56.6929 543.7303 null]
+/D [1428 0 R /XYZ 56.6929 505.5458 null]
>> endobj
-1416 0 obj <<
-/D [1413 0 R /XYZ 56.6929 512.1243 null]
+1432 0 obj <<
+/D [1428 0 R /XYZ 56.6929 477.9188 null]
>> endobj
446 0 obj <<
-/D [1413 0 R /XYZ 56.6929 424.5706 null]
+/D [1428 0 R /XYZ 56.6929 399.4257 null]
>> endobj
-1417 0 obj <<
-/D [1413 0 R /XYZ 56.6929 390.1552 null]
+1433 0 obj <<
+/D [1428 0 R /XYZ 56.6929 368.9893 null]
>> endobj
450 0 obj <<
-/D [1413 0 R /XYZ 56.6929 210.2494 null]
+/D [1428 0 R /XYZ 56.6929 203.5616 null]
>> endobj
-1388 0 obj <<
-/D [1413 0 R /XYZ 56.6929 181.6082 null]
+1410 0 obj <<
+/D [1428 0 R /XYZ 56.6929 178.8995 null]
>> endobj
-1412 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >>
+1427 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1421 0 obj <<
+1437 0 obj <<
/Length 2930
/Filter /FlateDecode
>>
@@ -5861,134 +5938,139 @@ P;°„d’ÆRN»‚7®rWÂô…<*(´kJœ’6f„‚³ÐO7›2ŽÍL³ lÙΰƒY×¹-‹bfyãZAQǬ
Î
|Ž¸¸ô±›t@.9E³Ý••]-ýðåÍæo%ù"¼ü³Ã­²™æÀ´3­±†3ψŒÆdsõ"ð%Q}@°íGzC’“œ"«©±Vª¿Þï«r®úð#ÊLr¨6qW?yèX]pª÷„Ì4ÅÎí(,d
Ü]f$¶Ì¤?º¸ ‰8«ïgK5BðÆr1hÆXÐ[fà-&Q·ojšpÖsD³£™ÊÞÚŠÆ0%ÉÞć=ßeá,Yšèþäyu[®+_R'aõí®:L¥XxâU=Qt±‡(v†OÇÈL† õ‚nj)Y¦E ™(ˆ@Ù³r‡È²¹ßX€7—½@ù”›Š^¾€ôbž¸è}œK… ÇA53°Ÿ¡l*Ên¶7ÐàgYòWr
-èu}Â@|ÌÞJ‰ÐDÏù)lNUŸ) á׼ŷvlÒ›…×Æ,èzR×v÷;ôö'Š\æëD²\FZî;Žû蛡¶úÿôüûÌå0h­C‘š#µ)ØÅ€¼o|±ÿ ½ÿ×KGÐ]FÑa/_Ò’kç|Hµ›æP­ˆæž Iü%Åž7½Õ¶»köŸF©cäóÓ»2Å=¤ÝßËô üñÊ3PøC¡Ðé~Üóվ쇋'¯Ýß–¿ >r"¦ÍYi™/†<\woÛçË”óF ‚¢ãÁá@fN¼ O1ï{pÀ;ܱP~7HûÕ~uûѶòŸª U[70Tã:¨Œ$y-àÖ#£…­^Í1_—Õó¥—+\Ý|óŠ=wÊŸ>ýc~RŽ'ûã0Ǩ÷=ìóQÿaÀ·«Ü€Å]¶÷ž`Ù-ðÎÉqîöö¶lípîÒ G<Ë®ìÚýõ\?ð&™¨öô×ÍŸ?
+èu}Â@|ÌÞJ‰ÐDÏù)lNUŸ) á׼ŷvlÒ›…×Æ,èzR×v÷;ôö'Š\æëD²\FZî;Žû蛡¶úÿôüûÌå0h­C‘š#µ)ØÅ€¼o|±ÿ ½ÿ×KGÐ]FÑa/_Ò’kç|Hµ›æP­ˆæž Iü%Åž7½Õ¶»köŸF©cäóÓ»2Å=¤ÝßËô üñÊ3PøC¡Ðé~Üóվ쇋'¯Ýß–¿ >r"¦ÍYi™/†<\woÛçË”óF ‚¢ãÁá@fN¼ O1ï{pÀ;ܱP~7HûÕ~uûѶòŸª U[70Tã:¨Œ$y-àÖ#£…­^Í1_—Õó¥—+\Ý|óŠ=wÊŸ>ýc~RŽ'ûã0Ǩ÷=ìóQÿaÀ·«Ü€Å]¶÷ž`Ù-ðÎÉqîöö¶lípîÒ G<Ë®ìÚýõ\?ð&™¨öô×ÍŸ?
endobj
-1420 0 obj <<
+1436 0 obj <<
/Type /Page
-/Contents 1421 0 R
-/Resources 1419 0 R
+/Contents 1437 0 R
+/Resources 1435 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
+/Parent 1440 0 R
>> endobj
-1422 0 obj <<
-/D [1420 0 R /XYZ 85.0394 794.5015 null]
+1438 0 obj <<
+/D [1436 0 R /XYZ 85.0394 794.5015 null]
>> endobj
454 0 obj <<
-/D [1420 0 R /XYZ 85.0394 769.5949 null]
+/D [1436 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1423 0 obj <<
-/D [1420 0 R /XYZ 85.0394 749.1193 null]
+1439 0 obj <<
+/D [1436 0 R /XYZ 85.0394 749.1193 null]
>> endobj
-1419 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >>
+1435 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1426 0 obj <<
-/Length 1106
+1443 0 obj <<
+/Length 1112
/Filter /FlateDecode
>>
stream
-xÚÍXÛnã6}÷WèÑ)@®H‰º OÙÔI³èf[¯û”#Ñ»º-IÇqêþ{)QräKÉNÂ0$ ÉÃ3Ù!‡È²õYă^ˆCË]HlD¬(ØÖ\·] PÝ4@»×ÇÉàÃ¥ã[! =ìY“Y +€v kß=ˆá™F°‡_n.¯¯~ŸŸùîprýåæ `b/¯™·«ñùçÏçã3€‚†?Ÿÿ:M“Wc|¼¾ùÉHBóxt<ºG7£³»É§Áh²Ñ¥­/²R‘ïƒÛ;ÛŠµÚŸ6t€XKýaC†ØJ.q q§‘$ƒ¯ƒß6€­ÖjèAû!bÇà 袖C \Ë'!ôìTüûÇR 8!@†„àVã‡KŒ¬x¦'®¯çñÍ`¢ÍjÛöð9Ϙ±ÑWEKY¦jë š¦T¼-Zˆbà ‚WcM3šÖŸ·QB¥¼3U¬±ÃÒÌ5iãjUÔ#R*FA{[³[Óƒ&I¾ßL¬\#cÁ¤œ¦TEÓ„KeäÚ Õó®&ȳS`Ñ>¬4“3&Þ™í¢ˆõj½¨EžðhÛ°¦ejZ¦b‘4‹ !¼ëc ™ƒ,W|¶ Ï‹iÉ»Æ,r¡6òò£ž¡žàöˆ1šfî³5¢}¥#K#øÃ&ö’Šl=£<Yóy– ¦ehk¦·Ó§ãáÐ>Ü’'qDEld+&§¹˜fyg:<Sl.¸Zí
-¼¹ÎÀNëÞ
+xÚÍXÛnã6}÷WèÑ)@®(‰º OÙÔI³èf[¯ûä#Q»º-IÇqêþ{)QräKÉNÂ0$ÅÃ3Ù!‡È0ÕØ…n`†8›a:0…ê» úÐ|Ú_}œ >\ÛžÀÀµ\c·°|hú>2&ÑtèB ^(sxõåîúöæ÷ñå…ç '·_î.€…Íáõí/#ýv3¾üüùr|ÑðêçË_'£±îrkŒ·w?iI ¯€ŽG×£ñèîjt1›|Œ&[]Úú"Ó.ù>˜ÎL#Rj˜Ð|l¬TÄ(,#8؆رíF’ ¾~Û¶z«¡Gí‡LhÙ®uÄ€j0° ƾcx8€®mÙ•ÿþ±ÔÁ
+ÎÂÙXÃi·Æšg$­›Ó0!BÌt㯊µeà4sMZ»„\õˆ”I¹VÐÜÕlª¿ I’¯À÷%åëWË£ˆS!æ)‘áÃ<aBj¹2HõœuÃyv,:„•œd"¦üÙ.‹H­Ö»j8Pä w «{æºgΗI³¸ÂYcˆd¹dñ.<+æ%ï³È¹ÜÊËF=C=Áô„1Šfî³5Â~¥# -øÃÄæŠðl–lØ"Ë9U2´3ÓÛˆéÓépènÅ’($<Ò²5óœÏ³¼3–IºàL®÷
+v˜]©°Ú.d©Cž%ëM̸½´¨q(;AöÆÍŽ!ØSÌÁ=§-i5:æy
+"«ŒI³°‰¿>¾]ÁÈ´
+D4!õ AÃ<‹Dgµk™‘“þU,ï¿Ñõ¡™^{ïé÷5;¡2HH_R
+懪 ÃÀó\£%ÉoźfgCÿ›5Gðè¶iº‡4} m5{M¿BŸH3@Ðò-ï¨1Ë#(ê$«Ž?,§®` ðH©Ý±Ú'ùc³9´Wzª³ÎžX⪦üC†¢&¿õ ¾6Jù$rÉßêåÞ3­¨"99í§*Ñr+ª”trŠ<2‘ª
+8“ÇY*Õ¨ ÓPæMSùPÕU”x¦¼<h—™H™¼
endobj
-1425 0 obj <<
+1442 0 obj <<
/Type /Page
-/Contents 1426 0 R
-/Resources 1424 0 R
+/Contents 1443 0 R
+/Resources 1441 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
+/Parent 1440 0 R
>> endobj
-1427 0 obj <<
-/D [1425 0 R /XYZ 56.6929 794.5015 null]
+1444 0 obj <<
+/D [1442 0 R /XYZ 56.6929 794.5015 null]
>> endobj
458 0 obj <<
-/D [1425 0 R /XYZ 56.6929 720.2271 null]
+/D [1442 0 R /XYZ 56.6929 720.2271 null]
>> endobj
-1309 0 obj <<
-/D [1425 0 R /XYZ 56.6929 692.8842 null]
+1326 0 obj <<
+/D [1442 0 R /XYZ 56.6929 692.8842 null]
>> endobj
-1424 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >>
+1441 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1430 0 obj <<
+1447 0 obj <<
/Length 1141
/Filter /FlateDecode
>>
stream
-xÚÍX[s£6~÷¯à1îŒ$!@³OÙÔÙf§›m]÷ÉÍxˆ„†Û"ygÝÿ^q1/¾@6ӎǃЧs¾óݦ«Òl
-u Íb¤:¢ští^µ}¡ê°ù4¿z?_Kc™ØÔf~ˆºm#mæÍÏ.¹øm6™Ž¦ú™ Ç€šúÙû뛟ËV>.?ß\]øsz1¶Œ³Ùõ盲z:¹šL'7—“1@6Eª?®öt¸ºþuR–>L/>}º˜ŽogG“YíKÓ_¤“Ü‘/£ù­®yÊí#fSíI½è1†µhdP©AȦ&ý1ú½l´]»ø£Ä†ÔÆVjˆt2ƒYšE4 &ƒó10uýÌ Ãä ,SÏ‘øIöäd^ߗߪo</ãB,"Gº‹0²¬ÿç]ù¼ÍéP6„ £7ñ+d÷»àQ<–µ+.I¶ˆ“d¶ÒMAÆ}eÅÃI
-ÒEîYù2O“LÖõùËmùV 0ÐB¸±îd¾J¢b'⢬øK§º
-J¼ö \÷q’qU‡Z#Bô'\¦Íò"IećZúAÈË’Y-Ž†Ž!y–wÏ¥¥ä³uIòg¹Îœ§^®ü,³Ø OµµmyU ‚—Cª´)wO½ÊŽ­I®Ö~ ÙË‹
-‡g¢%Ç7TX‹ˆàÙÏÀ#†…´èígI¼À÷yÆcw£Ô>I]ÀÈ(}´µÏ –êvü©­è©Rq„ñoÛ¸·º5æÃuŸÎy5©Âm Þ–Ñ\¸Çä‘k¼ #Lî"—ÑÏzeŠÌœX¨ð‚ÀSÉħáÃ@ÉR¾IQ“Ða ¡&5”ÍU:àÏi¸A[¥j@>uô
-x<tªN‚»I쉓ݮdDâôÏÖtyW«µIÓ¾rÏ9¥ˆPó³Ë·‰¤F#•Ö²$Ø¢
- Z1
- ŸŠ&
-™e™Z£~›PÇfÒÒ¾|?‰êÔÉâŽà«Ù4ÕüÞTfAlªí`i*Ýc*f*Ö ÄÄb”:¡½hm ½‰­ bD驶¥c‘¥›o£Œ-ˆ wª`)8ØKoŸ¬ª’ò$Ñ›$6öE‡¾*:È"Œ·ò¸ä·ùóÙÉÄʼn§#./IÌŽTëqàŠ¡»u\qïŽ"µ©Î)Åê2xÒaIqv QØÑ¢íÊ2”(×¼¡yáY~|ËW. ex`*¦ÝšÚ?UclšóÚ\4[ù,òsW¥H7t„¨÷~ÅœÓ+WiÕãAíGßuq±o‹{@ƒ<ä÷N~Fklú37ì,y~^>o’*#¯£4ä%÷à!žQ'ÏÆkyF;< ¹¼;D^y£ñeɳÕ»Åh`‚ÍÁy,úööþã;ƒ®û8Ba~‰Öq{¦þÕد¾«Û^dj•¶m\_ÃaÒ¸†#º m̬Q¹ÏÙµ¼¾ÔûÞôh÷Lendstream
+xÚÍX[s£6~÷¯à1îŒ$ Ù§lêl³ÓͶ®ûäf<D¢†Û"ygÝÿ^q1/¾@6ӎǃЧs¾óݦ«ÒuƒššMMHtD4/éÚ½jû0BÕ7`óh~õ~6:¿2lBjaK› ,ꎃ´™??»üåâ·Ùd:˜ègbégï¯o~.khù¸ü|suýáÏéÅØ6ÏfןoÊêéäj2Ü\NÆ
+/à¾J^Ÿ
+„%Kùz$É£>&¡Ã@CMj.(;š«tÀžÓ{¼-ŽR5 Ÿ:z|ºU'Á¼$öÅÉnW2"qûgkº¼«ÕÚ¤i_¹çœRD¨ùÙcÛDã©ÙH¥ul
+ l…mÓ0  ŸŠ&©m[Z£~›PÇfÒÒ¾|? Õ©“Å;ÁW«iªõ½©Ô†ØRÛÁÒT²ÇT2ÌT¬6í¤Ô %èEkíMl¥#BNµõ(µ#ˆlÝz`lCd:¸SKÁÀ^zûdU•”'‰Þ²¡acs_tÈ«¢ƒl&¥Ç­<.ùmþ¼EvRqqâéˆËK3 ¤+ÕzÌ=1t7 Ž+îàÝQ¤ö#Õ9¥X]¯QC@:,)ÎNƒ!
+;úB´]Y†’ƒrÍ–åÇ·|åR†Ça
endobj
-1429 0 obj <<
+1446 0 obj <<
/Type /Page
-/Contents 1430 0 R
-/Resources 1428 0 R
+/Contents 1447 0 R
+/Resources 1445 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1432 0 R
+/Parent 1440 0 R
>> endobj
-1431 0 obj <<
-/D [1429 0 R /XYZ 85.0394 794.5015 null]
+1448 0 obj <<
+/D [1446 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1428 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >>
+1445 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1435 0 obj <<
+1451 0 obj <<
/Length 2154
/Filter /FlateDecode
>>
stream
-xÚÕËrÛFò®¯àÚ2Ƙ^å“ìHŽRk%+3—UT*ŠH@€ €¢¹ñþûvOÏ€ Z²T9¤t@OOOwO¿‡â£
-YÇѨ‡ß¹â©#ý°@0 ‡Íp §ÿõU«šÆL@Þý5ªŠ@BîÇé ªYÑúßeÖ7ÔIÑU½T×” †ƒîÐõIÓ
-Áƒè/2­ˆW‰4íºÑþQónusWÕweõŒ¬úoUj¿i³JO>m<;{fY›M²F?7õöKD^úµž×ºY˜
-ñâ:ó&ü±&m½}­¯c±.Úܧ¦ð´C|!YÊM‚÷.5Þ
- mÊôöÎïweæ4¼™YÓtýÉD÷Ûv»Ò{öÝÓÍøoØÔ÷c[ú¤*}¼À÷{D zD¾Ö#âÀ#z¾{R—·‚:ôUƒÑ,»ÑV@äUŽfÏÏP+ôR—--п(sK˜¬œðk“ÝëNÎnD (–*.{r·’þÝIŸ¦`ç•n§Ü„³(ŠùHèÇÏs¡µ„i¸?å¾èÓ¢çÈ£òé\
-ëó¶¢ïª>å‰W=ä3»‘­ÛEUçبªl6¦&à‚ô
-î6›¶Ž‰îÈ[¯ 챜6#—n"‘“Ò™XÊÀûä^˜H`mPú±&;VYIè¬hª! } ¦ÅvÓˆBͤÖ&»×,âQVJ€‡¼÷[ÂÍô<ƒYå yßÍ¢ö@æÌ.MÀÌôP‹Sž/Aݘ{Ô¼E,¼PÆ4ø’)
-ZC[m6¤ØJ›s~WÈCåÁðmL`6oÖF²a¿'
-|y…"2ݵpeã´w|×bhì.yD¡f \¢Ã¤"b6y» èPuÄ?_~$Þ÷¨V¤Þåܲ%^˜á…å†÷įñIýÙ›Áă{¥»{uM†Òv&ÜšX’ 4™¶;X9F(@"xhºF_UU„òfH/™èqR“”°ºdŠÅì’WV€:
-Âz‰CX6[Èæe3<µ,27üCðl jŠjSX8ŸÓw[­í;bm³ß–A@0yËVò¥+.ÈTqÏ‘Yn _[8%™Ì=öÀèî¯{ (‘àO‹à)˜\ ýç%èï¯þ?ÏîŸ`0`Ãì'º×Ç~Å S 0‘!C^è•X=ú/”û‡¥ê©þ&4Cendstream
+xÚÕ]sÛ6òÝ¿BôMˆ
+i xsêÇAàÍëf“73ZüDA]•Û¯ó¢Ñ-¬8áßÑço ¢}ÎYEb€j4­ÿ¤Ý-VwùlÖXܪnÚ‹Û=1Œ1'Ï|þ÷ ñË\·ì£þÜ]sïØ]Yh{àë÷(|ó‡ÚÀmÇ|ßj7pŸoß„ïßä‹ß6y¥çªñ‹Y©ü¢¢j½œ¨æÙÙcÔË3Z­'Ý=ûGÁºmŠêþ[ì÷.Üé¨ëu3U;«°ç„¯†O2&E'–„22Œþa¶"–%I<êáw®x*äH?,L¡A3èé?Ä}UãǪf wª"ûI6¨j^¶þw™µÇ u
+è¾T׌ EƒîÐõIÓ
+ÁO‚ø/2­HS1hÚµVþQón•¾«›»ª~FVý·®”¯Û¼…ÒSLõƒggÏ,oóI®ÕsSo¿D•ß¨y£ôÂTˆ×™—0á5i›íkõx‹uÙ>5…§â É2n¼w!¨ñV
+È«ÍžŸ¡V¨¥ªZZþ ~ Q(–0y5#àWß«NÎnD „, ¹ìÉaÜJúw'i|šWJN¹)gqœð‘ bÐ=Iž5æBk‰²hÊ}Ñ!§EÏ‘GåÓ¹
+"l¼@»‚Iµj°° ¼È!§Dšy9­]ÑAxZ¯¶Õs"j ,÷AnÐíÙPAž&
+È+h3véÖ);)‰¥ ¼Oî…‰ÖF@¥k²c•W„ÎK]éièK0-¶M
+5_Ú ˜î^³ˆGY”
+=¾)
+mØïÉÄ€_žAa…ÈLw-<´qÚ;¾k1‡4v—<¦P3 .ÑaR1›¢]t¨:âÆŸ/?ï{T+
+2ïrnÙ/ÌðÒrÃ{â×øǤþìÍ`âÁ½€Òݽº&#i;nM,ÉšLÛ¬# N< ]£/„ª*B…ÒËF&zœGÔ$e ¬ne ™b1»äÀ•Õ N€M À7§Og׎!¼íšësÃDæNÍÝ©—:ö"àÔ:^Óz Ufft’±¨¦Ž°¥o=7ÆÃ3à5Ó„îBaÔh½""š
+j¥íòØ~ÂÌ«€q !LÈ '¦rÁØnŠY»À çwU;
+WÃÝÄ
+LdÄz%‰ýÊýCÈRõTÿ?&ŒEendstream
endobj
-1434 0 obj <<
+1450 0 obj <<
/Type /Page
-/Contents 1435 0 R
-/Resources 1433 0 R
+/Contents 1451 0 R
+/Resources 1449 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1432 0 R
+/Parent 1440 0 R
>> endobj
-1436 0 obj <<
-/D [1434 0 R /XYZ 56.6929 794.5015 null]
+1452 0 obj <<
+/D [1450 0 R /XYZ 56.6929 794.5015 null]
>> endobj
462 0 obj <<
-/D [1434 0 R /XYZ 56.6929 373.8367 null]
+/D [1450 0 R /XYZ 56.6929 373.8367 null]
>> endobj
-1437 0 obj <<
-/D [1434 0 R /XYZ 56.6929 343.7228 null]
+1453 0 obj <<
+/D [1450 0 R /XYZ 56.6929 343.7228 null]
>> endobj
466 0 obj <<
-/D [1434 0 R /XYZ 56.6929 343.7228 null]
+/D [1450 0 R /XYZ 56.6929 343.7228 null]
>> endobj
-1438 0 obj <<
-/D [1434 0 R /XYZ 56.6929 319.3114 null]
+1454 0 obj <<
+/D [1450 0 R /XYZ 56.6929 319.3114 null]
>> endobj
-1439 0 obj <<
-/D [1434 0 R /XYZ 56.6929 319.3114 null]
+1455 0 obj <<
+/D [1450 0 R /XYZ 56.6929 319.3114 null]
>> endobj
-1440 0 obj <<
-/D [1434 0 R /XYZ 56.6929 307.3563 null]
+1456 0 obj <<
+/D [1450 0 R /XYZ 56.6929 307.3563 null]
>> endobj
-1433 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >>
+1449 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1443 0 obj <<
+1459 0 obj <<
/Length 3493
/Filter /FlateDecode
>>
@@ -6004,37 +6086,37 @@ Fõy—syô“1Ž§Hz€HÔ!ìà/ôáØâÍtb$ð›®.´'ºÉÈÁš¤ÕˆÃûÓ/”G›r,ªa­ &Âh=m—zjÀg]˹†L
1Õh÷oÖo‹”è« w–¦ÞmPËçj6"¸Z7œ;<IN<
#n‘p*ꜩ=C§¹.=U˜¸Ð
-çF‡Â#ÐÆ™KCbˆnf¼ž¬Ó8W&¼ßQÕ· ÊÖÑTzXPsF6uà•@Ïý±= Y1œ`‡/̘-©Þ«¾ÖlÅ(ugÕ`1$/E+}ëâñ(ÃL™^¶T(Í}/æ‘#¨|`Ͳl«æ­”9·!†Éá/ *iééœÁþwáG †ëàAoh3ùÃÀèÂ×ǻǿɒ?pÇ/lÅq¹s¿$±&ºëŽ 8ÿÅD»,aÇÔgqž²{‘Ì4ÔÑâ Ãò€/Ŷj(®A…Ü·]¹n¹,Ÿäy×âïEvX<¤é2‚|©’\>Çn†o¶ô  +sîsðm [üáÈÔY-É`~-÷¯ƒßnüþ+ÈwŸÇn
+çF‡Â#ÐÆ™KCbˆnf¼ž¬Ó8W&¼ßQÕ· ÊÖÑTzXPsF6uà•@Ïý±= Y1œ`‡/̘-©Þ«¾ÖlÅ(ugÕ`1$/E+}ëâñ(ÃL™^¶T(Í}/æ‘#¨|`Ͳl«æ­”9·!†Éá/ *iééœÁþwáG †ëàAoh3ùÃÀèÂ×ǻǿɒ?pÇ/lÅq¹s¿$±&ºëŽ 8ÿÅD»,aÇÔgqž²{‘Ì4ÔÑâ Ãò€/Ŷj(®A…Ü·]¹n¹,Ÿäy×âïEvX<¤é2‚|©’\>Çn†o¶ô  +sîsðm [üáÈÔY-É`~-÷¯ƒßnüþ+ÈwŸÇn
endobj
-1442 0 obj <<
+1458 0 obj <<
/Type /Page
-/Contents 1443 0 R
-/Resources 1441 0 R
+/Contents 1459 0 R
+/Resources 1457 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1432 0 R
-/Annots [ 1445 0 R ]
+/Parent 1440 0 R
+/Annots [ 1461 0 R ]
>> endobj
-1445 0 obj <<
+1461 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [280.2146 205.1117 375.7455 217.8489]
/Subtype /Link
/A << /S /GoTo /D (root_delegation_only) >>
>> endobj
-1444 0 obj <<
-/D [1442 0 R /XYZ 85.0394 794.5015 null]
+1460 0 obj <<
+/D [1458 0 R /XYZ 85.0394 794.5015 null]
>> endobj
470 0 obj <<
-/D [1442 0 R /XYZ 85.0394 162.5022 null]
+/D [1458 0 R /XYZ 85.0394 162.5022 null]
>> endobj
-1446 0 obj <<
-/D [1442 0 R /XYZ 85.0394 137.1661 null]
+1462 0 obj <<
+/D [1458 0 R /XYZ 85.0394 137.1661 null]
>> endobj
-1441 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R >>
+1457 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1450 0 obj <<
+1466 0 obj <<
/Length 2962
/Filter /FlateDecode
>>
@@ -6049,128 +6131,128 @@ LA—§ÿm¨¡á•B[G?¥
Ó\{½Nã8Ôˆ~šK ­ß„·Is#Ž ÓœD§¯ÇŽe9
PØgö}ˆf9‹Ÿp:”û++l¹Pñè;Ô”!´8å0l}U2ñÍÞ>*B¹¥5ê/N?fup±&H08ÓGw Å~=D—ë¹ô5·÷ôm¡œwÕL–¶¥8ÓeJ•ød¡y^šÞG‹²¥Rn ÓR7eeJN0ÇÝ]<×ÛëÜUõ;§W6¥¾šõ$Œ}qÚDP¿¤Øæ0Ç0Øîân‚|É_žm•´PiJ¿ú/*óÝøÜ\"Q5ÏìÃÌüÑsÓjc€ç§¢ÉëC¶Êë|[ì
ûªœwZt}^pj=†ºh[ur¶¬ó}S,ì5›µÛóÓ}½"•6Q@ã4Pm7 ä殢­Dë¾öîI7êãc=šß ¤=+-Î}/>²ºãöø|Ô¿:èÌ(ãæØǹ_
-&6 ¢NMý»ÿý‘çìeð‹•Í”å0cž4»âò™_0ôO6F&ü·ÿÇ¿ 9ýl†ëßœ=uèr†!Ö(™„Éþ„$4ý—Qëendstream
+&6 ¢NMý»ÿý‘çìeð‹•Í”å0cž4»âò™_0ôO6F&ü·ÿÇ¿ 9ýl†ëßœ=uèr†!Ö(©ÂŒdBšþ?—©ëƒendstream
endobj
-1449 0 obj <<
+1465 0 obj <<
/Type /Page
-/Contents 1450 0 R
-/Resources 1448 0 R
+/Contents 1466 0 R
+/Resources 1464 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1432 0 R
-/Annots [ 1453 0 R 1454 0 R 1455 0 R 1456 0 R 1457 0 R 1458 0 R 1459 0 R 1460 0 R 1461 0 R 1462 0 R 1463 0 R 1464 0 R 1465 0 R 1466 0 R ]
+/Parent 1440 0 R
+/Annots [ 1469 0 R 1470 0 R 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R 1481 0 R 1482 0 R ]
>> endobj
-1453 0 obj <<
+1469 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [284.2769 667.7189 352.9489 679.7785]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1454 0 obj <<
+1470 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [282.0654 636.5559 350.7374 648.6156]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1455 0 obj <<
+1471 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [311.9531 605.393 380.6251 617.4526]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1456 0 obj <<
+1472 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [299.7586 574.23 368.4306 586.2897]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1457 0 obj <<
+1473 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [292.0084 543.0671 360.6804 555.1267]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1458 0 obj <<
+1474 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [330.7921 511.9042 399.4641 523.9638]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-1459 0 obj <<
+1475 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [401.5962 480.7412 470.2682 492.8008]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1460 0 obj <<
+1476 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [257.6971 315.5214 326.3691 327.581]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1461 0 obj <<
+1477 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [310.7975 284.3584 379.4695 296.4181]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1462 0 obj <<
+1478 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [308.6055 253.1955 377.2775 265.2551]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1463 0 obj <<
+1479 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [294.1999 222.0326 362.8719 234.0922]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1464 0 obj <<
+1480 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [303.0862 190.8696 371.7582 202.9292]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1465 0 obj <<
+1481 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [332.9347 159.7067 401.6067 171.7663]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1466 0 obj <<
+1482 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [301.97 128.5437 370.642 140.6034]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1451 0 obj <<
-/D [1449 0 R /XYZ 56.6929 794.5015 null]
+1467 0 obj <<
+/D [1465 0 R /XYZ 56.6929 794.5015 null]
>> endobj
474 0 obj <<
-/D [1449 0 R /XYZ 56.6929 726.6924 null]
+/D [1465 0 R /XYZ 56.6929 726.6924 null]
>> endobj
-1452 0 obj <<
-/D [1449 0 R /XYZ 56.6929 700.1172 null]
+1468 0 obj <<
+/D [1465 0 R /XYZ 56.6929 700.1172 null]
>> endobj
-1448 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R >>
+1464 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1469 0 obj <<
+1485 0 obj <<
/Length 3111
/Filter /FlateDecode
>>
@@ -6182,94 +6264,95 @@ aŠ¹cãKÞL0 ¤R"/Ó†íà•SÍ›ñɆõ\”¥3¢lœæ6èAe…%å ÒÛ€”µ>e.øé m~] +|P´ ë”wÒþpZ~9
ãlˆŠ5$Ñ9v«SÒhëOC«ý‹ý0}®K«ìÛ,M¦N$N´2·.Öز~´%¿$,ù­>Ÿ`«Iì3RºV͸ëÌÝ (¶NÙ#l)]¨-‡H™„]C ØÞþçͲI°¶ãßÚeŠGˆh†Í°âž663´¶"ÁÂJ®ÏÛvXÁÚ¯³Œ3]ŠðÚYhqÞ:]`6…ZÀñ˜WŽþðù !Ô­-»,¢„ ΔÔÈ{—ËíuÀoU¹¸ð4b¬ãÔrÆØÙœßYKf‡R›AØ4F§‹šwœ€ê9N{8n\w݇ê&² D@MhÑë6(…Uå@à>6¹PRíê­9TñëÍõ‡—C;©vp²¾ DÜÍAÕ|Oc†8å 3géi2,rÄÀrŸÂ/*8 &$÷ƒSŠaª/ú•[{HïG’tŽídpª/ûiyàx XCiiV$æ×M»»¼Òû¹„¹Í¢ÄýVÍÌ£«ûRM÷9æ°È!0A(Õ÷Á97† .ö«24í¨Ð%
Ãövè¨6PèÙÊ°Ævwqz»Íü¹—ߤöwHT Ωoþ5z‘:y²¢.³¾Ž‚m)Ñ×›Ó”ú<oÂA:õ(·­žas
û7JæÛhžËdü}ã(³iŠOãˆÁ1¢ ¡Qñ4–ß?à(•©ì)ð×NÁd«±éBÂr5³ça)¥XBº–F¶Ý·yÔêìaX2Tˆ;0Ž¼ÇÄ•¶Ýp§4…蟰¢uP¦y”#³äÙçnž*ùfê
-ÏØÌïî|8æ;Kw‘L’Áƒî%åÄk¨ä~q™ÎápÉ¡e¡Æ.×ÀjxýXºæò¤
+ÏØÌïî|8æ;Kw‘L’Áƒî%åÄk¨ä~q™ÎápÉ¡e¡Æ.×ÀjxýXºæò¤
+5Ô<<««þ?çÅe@endstream
endobj
-1468 0 obj <<
+1484 0 obj <<
/Type /Page
-/Contents 1469 0 R
-/Resources 1467 0 R
+/Contents 1485 0 R
+/Resources 1483 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1432 0 R
-/Annots [ 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R ]
+/Parent 1497 0 R
+/Annots [ 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R ]
>> endobj
-1471 0 obj <<
+1487 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [259.4835 683.3704 328.1555 695.4301]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1472 0 obj <<
+1488 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [172.152 623.0288 267.6829 634.8294]
/Subtype /Link
/A << /S /GoTo /D (root_delegation_only) >>
>> endobj
-1473 0 obj <<
+1489 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [352.4539 369.6354 426.1073 381.695]
/Subtype /Link
/A << /S /GoTo /D (server_resource_limits) >>
>> endobj
-1474 0 obj <<
+1490 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [387.5019 339.3849 456.1739 351.4445]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1475 0 obj <<
+1491 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [381.9629 309.1343 450.6349 321.194]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1476 0 obj <<
+1492 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [398.5803 278.8838 467.2523 290.9435]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1477 0 obj <<
+1493 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [393.0412 248.6333 461.7132 260.693]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1478 0 obj <<
+1494 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [255.0796 218.3828 323.7516 230.4425]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1479 0 obj <<
+1495 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [311.5276 188.1323 385.1809 200.192]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1480 0 obj <<
+1496 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [315.9507 157.8818 384.6227 169.9414]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1470 0 obj <<
-/D [1468 0 R /XYZ 85.0394 794.5015 null]
+1486 0 obj <<
+/D [1484 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1467 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F48 950 0 R /F21 710 0 R /F41 935 0 R >>
+1483 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F48 955 0 R /F21 714 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1483 0 obj <<
+1500 0 obj <<
/Length 2952
/Filter /FlateDecode
>>
@@ -6283,142 +6366,142 @@ aÊ50Hz3¢ ¢Ls÷©²;Ì`¸3%hà°}yxZØ›‡ë?ãzl×ú¾>{idO$"b̉S“éô ‘-CE’wº‚ÿ™i©gÄ7@
Ò´d$<j†Hl-©DÆ8›9o¢.+Ñ£LǦX]»"ñP»$š`Ö¾ Y 5r@çm6姢˜#B2™(A4°Ž'K`‡Ÿ‚Øîõbä ÂÒ¡èA34"[i%J »7Ÿ9€¢JìQ¦ÇªnËíé’öx®÷4Ñ{X„¤µba÷o³FNŒú–e„©‹R£š9–Ž&¤æñ3>Çv¯¯A`«„…Š¥ÇÞ£fˆÄÖÒjƒÌ!ãbæ°eˆJ¨­GEš,@0Ê RLèA¢£oƒà¦÷ZsÔ"ˆJµh¾ÎµüŒÛ±Ýë5—)Ø5K¿G͉¬¥5庘;a€Šs Óݾ¬V‡b{(šçU[ììó?'›;t{8Åؾ1N™’Xò$ŠÓ$‰D¦TàA'X¢`ÍM XÓ‹‹C‡D’lÈ*¡-Oó‹¬Ê2L.â H¼¨I’aîAi‘­¤®˜‚̈Ë,-¬!ê²²<ª›ÒnmŠ³=ÔûզܚH{Šj=õ EXA ”¤ãQ|‚V#!dH¨S
¤ÚV)LòP)æÍäÒF0aôg$snÅ5™,QS
K¯W ÇTâB[–½VÅg×`ˆ1ÚÏqhÑöbÔjoŒÜÇöµ/ àÉÌžªXÁÈ—UáÐ0©ÚSï¬á"h_}îÊ(swž®Æ¾3i#Ä9&a„:ÅÆœ²å;3€bÙ]ùÁݨsˆH¶<îl#¬£ÐjæCiˆ›nžH kOq.pIJÈ×Ï ×\B´öE¯®®Ãƒ}¿)ª²pmgí¸†mr5Ñùc~ ƒÕÉßÆÈ„U_Æ—Ÿ
-ûlÇlãO¶Ñ77ûb h-b[¶ÀÆŽ¾¼ßZ˜•! Ϋ¨ïÂ"¬™?ŽEÓÚ—@¬ÉŸÜÛÒ‘4¿[³œDW3w•òĪ[6n‘*Û~>¬wÇM_nžG&½<þtÿÁÍ*÷L¸«*'æ iÿj4ËÜ
+ûlÇlãO¶Ñ77ûb h-b[¶ÀÆŽ¾¼ßZ˜•! Ϋ¨ïÂ"¬™?ŽEÓÚ—@¬ÉŸÜÛÒ‘4¿[³œDW3w•òĪ[6n‘*Û~>¬wÇM_nžG&½<þtÿÁÍ*÷L¸«*'æ iÿj4ËÜ
endobj
-1482 0 obj <<
+1499 0 obj <<
/Type /Page
-/Contents 1483 0 R
-/Resources 1481 0 R
+/Contents 1500 0 R
+/Resources 1498 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1432 0 R
-/Annots [ 1485 0 R 1486 0 R 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R 1497 0 R 1498 0 R 1499 0 R 1500 0 R ]
+/Parent 1497 0 R
+/Annots [ 1502 0 R 1503 0 R 1504 0 R 1505 0 R 1506 0 R 1507 0 R 1508 0 R 1509 0 R 1510 0 R 1511 0 R 1512 0 R 1513 0 R 1514 0 R 1515 0 R 1516 0 R 1517 0 R ]
>> endobj
-1485 0 obj <<
+1502 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [352.879 737.5325 426.5323 749.5921]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1486 0 obj <<
+1503 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [334.0699 707.2832 407.7232 719.3428]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1487 0 obj <<
+1504 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [373.9 677.0339 447.5533 689.0936]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1488 0 obj <<
+1505 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [319.6839 646.7846 393.3372 658.8443]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1489 0 obj <<
+1506 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [307.1508 616.5353 375.8228 628.595]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1490 0 obj <<
+1507 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [334.8268 586.2861 403.4988 598.3457]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1491 0 obj <<
+1508 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [337.0185 556.0368 405.6905 568.0964]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1492 0 obj <<
+1509 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [364.6945 525.7875 433.3665 537.8471]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1493 0 obj <<
+1510 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [374.6372 495.5382 443.3092 507.5979]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1494 0 obj <<
+1511 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [292.0276 465.2889 360.6996 477.3486]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1495 0 obj <<
+1512 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [319.7036 435.0397 388.3756 447.0993]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1496 0 obj <<
+1513 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [460.1655 404.7904 533.2211 416.85]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1497 0 obj <<
+1514 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [368.9978 374.5411 438.8121 386.6007]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1498 0 obj <<
+1515 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [293.1435 332.3366 354.3435 344.3963]
/Subtype /Link
/A << /S /GoTo /D (options) >>
>> endobj
-1499 0 obj <<
+1516 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [288.6803 302.0873 357.3523 314.147]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1500 0 obj <<
+1517 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [328.5503 271.8381 402.2036 283.8977]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1484 0 obj <<
-/D [1482 0 R /XYZ 56.6929 794.5015 null]
+1501 0 obj <<
+/D [1499 0 R /XYZ 56.6929 794.5015 null]
>> endobj
478 0 obj <<
-/D [1482 0 R /XYZ 56.6929 256.8016 null]
+/D [1499 0 R /XYZ 56.6929 256.8016 null]
>> endobj
-1116 0 obj <<
-/D [1482 0 R /XYZ 56.6929 231.4888 null]
+1121 0 obj <<
+/D [1499 0 R /XYZ 56.6929 231.4888 null]
>> endobj
-1481 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R >>
+1498 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1503 0 obj <<
+1520 0 obj <<
/Length 3016
/Filter /FlateDecode
>>
@@ -6433,30 +6516,30 @@ k·ß¨|óþýñuFŸóœ™ÒÛE^E»)ÁÜÆÅ;‡N‘ÞÒš>v/M±Ý*‘˜ñ¯Ùú6 Ú/+j›¾˜æ«tAŸ¨O,ÛÓE‹!s<\
˜ H&á}Â9Î$Dz¼øšNëIté•Sp¨–):Gñ[Ïc²{ÚÛ?Ú@?(ÒUNGO
ššÅwïšÛ,$hÛÉÛõ31tÏLÑ F¹hà=’QÎÂÛ×t?¾$,,­ö ³eº½+º‘K]Úð àˆu÷áy{‹(RÜû.ê‡ÂÅ@¬)dr.x0Ú¼rú ih¢›(Ýà^4Ù&bÅJŒ¬ Ö¢@tQ Æ Ù”ŠÀÑdF[¡¼;‹•õ=BÂ{ƵÔ?B½ùQR†ykÌwlf쇰,ÑN‚wYkuÈÕØEÐà~u›CÙ§lœÙuÙ”¥PËÖïV–ünl ~7Vú~7¶týn•¸6FÔnÝn¼K‘ªìDÝ5ˆZ6QË&´”ü82‚[ðwGÄDŒL‡‚8ðCóh4[ÆC9Tº¢>ÇÎF?<[<6Éñ$›{ñ¨”k.Þ€ÿ˜ßãJ Y3ßn¨HìvC±ç!¢®‰ˆmÜ.lŠŠí†b{B´/»†lkŒ”Ô”Æz1‚®4wDD&Àh%j× MŒ’{N b^uðä •<:yÀoùÏï‹2&y(W¢kæ‘r÷›p:!úž—:¾³UP6>vÒ°†²?v_@hÎŒñæ(ÅhÔü®b¬Ñ[Åô}]ˆ‚yïÁÓD‚G/än
u›2«6n¬Æ²¬jjÙT„À}‹wßbQ>D cZcQ‘RÌmÉñj÷-a». 𚌟W–`ÞÀºâRÍóF3" £)ØíŠ;áU‡vwЀ™Š—½²!1URõ66mVÐN
-fÔ¸ÝÇ É¸oIOç ÐPÇ€—0Ä(Uû/ ª“»êîwb™ç7’9­È‘þÓà–›„q£Á0 NDzyòK›,GUgë¼úD|ý·ŒÆݦU¶ß2wMÞóÌèÿÔÙTƒ8~ÈÙÁ|‚O&]MÛ{“n“èË|‘®©Ð>°¡†%ÊË pà¶ÉÇìë4[Õ´@SªÉÖ=ŽK—wCá¬ð¨ÿïµtd¦-rb6™ÓÙÆJO@¥³ÿÇq‰~µæöT †O||®"Í3„Å»žÞ”-Vðc+àì£b%aw°h¬`­,ßâ¢Ô„ž!ÔLÄÕ·ãO€µ6ZÌ”îü(¤€[À$7ßC3Ny"
+fÔ¸ÝÇ É¸oIOç ÐPÇ€—0Ä(Uû/ ª“»êîwb™ç7’9­È‘þÓà–›„q£Á0 NDzyòK›,GUgë¼úD|ý·ŒÆݦU¶ß2wMÞóÌèÿÔÙTƒ8~ÈÙÁ|‚O&]MÛ{“n“èË|‘®©Ð>°¡†%ÊË pà¶ÉÇìë4[Õ´@SªÉÖ=ŽK—wCá¬ð¨ÿïµtd¦-rb6™ÓÙÆJO@¥³ÿÇq‰~µæöT †O||®"Í3„Å»žÞ”-Vðc+àì£b%aw°h¬`­,ßâ¢Ô„ž!ÔLÄÕ·ãO€µ6ZÌ”îü(¤€[À$7ßC3Ny"
endobj
-1502 0 obj <<
+1519 0 obj <<
/Type /Page
-/Contents 1503 0 R
-/Resources 1501 0 R
+/Contents 1520 0 R
+/Resources 1518 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1507 0 R
+/Parent 1497 0 R
>> endobj
-1504 0 obj <<
-/D [1502 0 R /XYZ 85.0394 794.5015 null]
+1521 0 obj <<
+/D [1519 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1505 0 obj <<
-/D [1502 0 R /XYZ 85.0394 512.9872 null]
+1522 0 obj <<
+/D [1519 0 R /XYZ 85.0394 512.9872 null]
>> endobj
-1506 0 obj <<
-/D [1502 0 R /XYZ 85.0394 501.0321 null]
+1523 0 obj <<
+/D [1519 0 R /XYZ 85.0394 501.0321 null]
>> endobj
-1501 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F48 950 0 R /F62 1060 0 R >>
-/XObject << /Im2 1049 0 R >>
+1518 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R /F48 955 0 R /F62 1065 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1510 0 obj <<
+1526 0 obj <<
/Length 2779
/Filter /FlateDecode
>>
@@ -6470,69 +6553,69 @@ lP»*Ý+a~vqFdè¿Ii»Å¦º±ÍPE™ºÚ•ÀŽT<1 z¥ƒãÎ Ï=9Яf3²_ú8 JéðÛBz`+¡<Vù
ølZO誻Æ’'9;&kË'ì¤ç¡5îìæÞñJ»Ž×##ÕÛ5g¶dÐp=¢µA~p‹Í±s¢:]}AÁG†F Þƒ€ô-D:Ì¢Y»"&‹»vãSÇhåj[÷ÕºöË®¤× Öv³ªzòXx¥Œ„­ûjUýîQà8·4aç?6pÚ/úýÑÜâþ^ýç³ù®ÃÇ•}¶ØÜxfR'o†¸
¸ézFÖ¸¶öiŒå«¸„—$X1Óäæηw³Q…=ðOÇ KìÃ}ñ¼×þÊÃßpAõ­™P2å)K2½'ÒA©˜^“#‡zXk½/‡O9{ÏvËPý•Ïìú¬’ —1y’¿¬†ë5AvCI|óHɤf¿{˜‡¬ä‚SþISŒK!‡œ2*É|ûÇÁµC¸Ð“Ðå¥Y®ÿW]æ(À|EëìW<{K)ÓŒi©ž±H¸¥”Z0Iá }h‚/SÀ„"ÛÙáiëG£Œ’»a¨%fþ"¹êB1½mÊÃû 1Ä û6쮤bæÅ+çƒ-ÊçuŠ×0B‰Wtš&ÓÄP…ê|2Õ‰NãSԞѱm-]*š4zzSõ4q_Ô[KC†a×Lva*𸭑ÇùÄxŠlB«¹"Eíe±§N³ß˼`¨‘Þ¦Õ¡’Œå’ÍÝVXñ¬¡ÄçÜÈ×À/SèϺĜϿ;¥†{Èg Îje§%E<­«{OtºÎ‚®³ Îˆâ¯¨´»hr ôª¤78ð
ûÎ9ò5Ï›kÛT.þ)ªMñÙµšÒ%ü$´u@®<ÛzS­ŠMå.UàuÛYÏpã){Å‘\›s¬PXZ\¤¡Éƒ*ÚÒ
-B•H¯/¼ßEâ`Ôºáë’näy\·®
+B•H¯/¼ßEâ`Ôºáë’näy\·®
endobj
-1509 0 obj <<
+1525 0 obj <<
/Type /Page
-/Contents 1510 0 R
-/Resources 1508 0 R
+/Contents 1526 0 R
+/Resources 1524 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1507 0 R
-/Annots [ 1514 0 R 1515 0 R ]
+/Parent 1497 0 R
+/Annots [ 1530 0 R 1531 0 R ]
>> endobj
-1514 0 obj <<
+1530 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [312.8189 298.8688 386.4723 310.9284]
/Subtype /Link
/A << /S /GoTo /D (the_sortlist_statement) >>
>> endobj
-1515 0 obj <<
+1531 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [406.3277 298.8688 479.981 310.9284]
/Subtype /Link
/A << /S /GoTo /D (rrset_ordering) >>
>> endobj
-1511 0 obj <<
-/D [1509 0 R /XYZ 56.6929 794.5015 null]
+1527 0 obj <<
+/D [1525 0 R /XYZ 56.6929 794.5015 null]
>> endobj
482 0 obj <<
-/D [1509 0 R /XYZ 56.6929 509.1791 null]
+/D [1525 0 R /XYZ 56.6929 509.1791 null]
>> endobj
-1512 0 obj <<
-/D [1509 0 R /XYZ 56.6929 477.0735 null]
+1528 0 obj <<
+/D [1525 0 R /XYZ 56.6929 477.0735 null]
>> endobj
486 0 obj <<
-/D [1509 0 R /XYZ 56.6929 477.0735 null]
+/D [1525 0 R /XYZ 56.6929 477.0735 null]
>> endobj
-964 0 obj <<
-/D [1509 0 R /XYZ 56.6929 447.2177 null]
+969 0 obj <<
+/D [1525 0 R /XYZ 56.6929 447.2177 null]
>> endobj
490 0 obj <<
-/D [1509 0 R /XYZ 56.6929 390.5598 null]
+/D [1525 0 R /XYZ 56.6929 390.5598 null]
>> endobj
-1513 0 obj <<
-/D [1509 0 R /XYZ 56.6929 368.2486 null]
+1529 0 obj <<
+/D [1525 0 R /XYZ 56.6929 368.2486 null]
>> endobj
-1516 0 obj <<
-/D [1509 0 R /XYZ 56.6929 281.9323 null]
+1532 0 obj <<
+/D [1525 0 R /XYZ 56.6929 281.9323 null]
>> endobj
-1517 0 obj <<
-/D [1509 0 R /XYZ 56.6929 269.9771 null]
+1533 0 obj <<
+/D [1525 0 R /XYZ 56.6929 269.9771 null]
>> endobj
-1518 0 obj <<
-/D [1509 0 R /XYZ 56.6929 89.8526 null]
+1534 0 obj <<
+/D [1525 0 R /XYZ 56.6929 89.8526 null]
>> endobj
-1519 0 obj <<
-/D [1509 0 R /XYZ 56.6929 77.8974 null]
+1535 0 obj <<
+/D [1525 0 R /XYZ 56.6929 77.8974 null]
>> endobj
-1508 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F62 1060 0 R /F53 1027 0 R /F21 710 0 R /F39 895 0 R >>
-/XObject << /Im2 1049 0 R >>
+1524 0 obj <<
+/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F62 1065 0 R /F53 1032 0 R /F21 714 0 R /F39 900 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1522 0 obj <<
+1538 0 obj <<
/Length 2893
/Filter /FlateDecode
>>
@@ -6551,23 +6634,23 @@ aÇg¬‰¾—uó|GVäM>ó)‰Æõýwº¡éùÑ„4>ˆR3Š4x«ë(Ç#©\4ZVOm.Ê*Ÿ†ü‚3H[‚t9øŒµiŽ•çNºQ6
¦JI$áû œÝ$âgÇ$†l"Ÿ’T{;Ý‘³×‡ÞØ¡)z€2„#©êa„¥Cn”C½Þ‘ûÂÝÌ×KœˆîÓé2ˆܦŃ_tŽûªGY´'·Áýu1ÅV“ðô‘®4YèFÇù¨
õ ‘?n›G@¤‰gîæ’XxÑÉ|Û’ûŠ®o°ž!E
M’‡×åÁ(^®a‚÷0Áò©I,€ñd³å]¶Hñ蔾gV¼à½#V^4oÚqq7_RI*z7‰‘®Ï³Y‰ê èýÀ`—Qá]EòúÛUÑ$0”É.²þLšÕgë¤LÃ0£­Õ¯¼«<õ¶M,€dµ#µÙëî›V—Œ']O 3 ?²
-燉ŒŽ.Ž¾Á°¶ 6„»l xÍ°þã%o6( ª;‚LŸIl ÁÛýD·°ÞëŒjó7÷°ýIGÓp‹s ¨g†ýS¯0|Y4ç,–Öá·…ÌÚ'?\ç½NêþÜÏäWÿU
+燉ŒŽ.Ž¾Á°¶ 6„»l xÍ°þã%o6( ª;‚LŸIl ÁÛýD·°ÞëŒjó7÷°ýIGÓp‹s ¨g†ýS¯0|Y4ç,–Öá·…ÌÚ'?\ç½NêþÜÏäWÿU
endobj
-1521 0 obj <<
+1537 0 obj <<
/Type /Page
-/Contents 1522 0 R
-/Resources 1520 0 R
+/Contents 1538 0 R
+/Resources 1536 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1507 0 R
+/Parent 1497 0 R
>> endobj
-1523 0 obj <<
-/D [1521 0 R /XYZ 85.0394 794.5015 null]
+1539 0 obj <<
+/D [1537 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1520 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R >>
+1536 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1526 0 obj <<
+1542 0 obj <<
/Length 3252
/Filter /FlateDecode
>>
@@ -6581,86 +6664,92 @@ xÚÍks£Fò»…¾UY„y
…,‚ ‡ …BÁá)‰Ž·Ï0ëq•æ7±PÌÖî³iM€j¼ð=SBYÑFDzÍAhÚÇ>cÌ3.wÃÂã˜ÂºòƒþppÚ}Õ7ìUe" ¶9bàCH…¼•aÈÍ%j±èj± ”×ö™‡ü@øVW™I‡¾©ËbòHðå2kd¡YtC(D¥A ÝŸ1L‹{mFCÐT¸ žµWû9×!É[f\gGì/¨‘E‚¡Ûa? ½aòÉÍøUDŒkcß"å=hcÞ
½#ÝaŸ¿¤›±Ÿ‘Bø<„ý0#!›R’“±™úd±Ã¨ŸpOi‰6"­Í3{nÁê°ÇéïÛ^ùu @BB6}˜Š\úJÅ‘3@EL˜7ŒVÈCg´|È‹IŽ`dí"­ýBpe¿p„³_§ûE¼Yâr&³aÙí¯£›>ã‰wJm›¦àˆ®"¸YÎçõ¢u¼}_4-„Lör°Cš7ìz„‰ðH^ŸÄ1Ñò1hco¨;Õeç}” Â"<?ù8¡µ¿Æv>ÉV>¶7`ø¶âH÷e_Š'ëû•c68'â­ ›ÿo–;·)bà„¸~o^ô<¹ð ì„p¯ €¨jÛÝm”€L$à¡5&@ßÕeY?`ÎtþþR$™‘„S* Ûá”I™"‹iÜÆ<ñ¹
èÍj;?·S;;ãMý)}•a¯‹¥7É)Q!}ƒ8xkXòŽU™0\2i8²ãåè˜ÑUdæ».¹!eC¨uL&]=`õ¡Ï¼/ÆØ@;ש©'â ¬5á‡+xf)(^´ðhô‹K4Φƒ8½°›Mð¶iÍg-Ø&ºÀ€ÔT@Ì ÝZD i>ÞÁ!h]R¼ÁÝaTH4PíñpÃwôþÙól$‹øvm³`VZ»8Õ…¶«¾Ý1îXaÑ–¹Ç_OAb¿& •ÓÌtJÌÀ’·‘âØ}É aL‰½Ì¨a4*6E'3º˜Ùáe1+ZBc ϼ~°}5íB¾1æ“#hOR;vl—ù¬çv•¢ÚØi’Nrü„$‚j”»cЮ;Ä-«M12¶_N‰ôx>GBœq'ˆ²Åð ÷šºÐD°aÇx¸ÖöÙÅÓ²±K!%2B‚ :źµ»!‚Þ±Û˜¨ëxxgY™[60oŽåñÂ%r—×2«$Ò ³_Ë‘ÃßË*TãoÑÌáì×Sø\­‘f`ê@ Às•XS76"è!×+¼^F8ºÊ^Áµ”˜ƒ®üžåN›Ð
-ñ±;,%ñØÀvŸê_WvnJ0øÕt§m#…å‰=Ò»cr‚îM*·Yb%€'“ˆ¦Ù’n]á5±¡^g{˜NgÒ‘
+ñ±;,%ñØÀvŸê_WvnJ0øÕt§m#…å‰=Ò»cr‚îM*·Yb%€'“ˆ¦Ù’n]á5±¡^g{˜NgÒ‘
endobj
-1525 0 obj <<
+1541 0 obj <<
/Type /Page
-/Contents 1526 0 R
-/Resources 1524 0 R
+/Contents 1542 0 R
+/Resources 1540 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1507 0 R
+/Parent 1497 0 R
>> endobj
-1527 0 obj <<
-/D [1525 0 R /XYZ 56.6929 794.5015 null]
+1543 0 obj <<
+/D [1541 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1528 0 obj <<
-/D [1525 0 R /XYZ 56.6929 337.2163 null]
+1544 0 obj <<
+/D [1541 0 R /XYZ 56.6929 337.2163 null]
>> endobj
-1529 0 obj <<
-/D [1525 0 R /XYZ 56.6929 325.2611 null]
+1545 0 obj <<
+/D [1541 0 R /XYZ 56.6929 325.2611 null]
>> endobj
-1524 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R >>
+1540 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1532 0 obj <<
+1548 0 obj <<
/Length 2932
/Filter /FlateDecode
>>
stream
-xÚÍ]sã¸í=¿ÂÎL¬Šúê[6›\ss—ÝfsÞÞƒlѱº²ä³äxýï  L;rv{—¶;™‰@A
-"­”ÃTgÎþÞ3ôzíÐ!5E* ¢T&z’jHOQÄ
-ºPO Ë…y—TÖøãÎuÝ¿%ýà¿KBµfÖ•MMfÎt÷-,[BÌòõº45rFò,³f9-ëÜq=Ä®w<M·.ëG7°fNE³Ìu¾4m€v
-xî%o?5¥“
-2…Ç šæ ?͆;ÅµÓ DZ†ÒN¹îUb›{FQ¶ÿÂ#Ùª?DÅKo-U²Ÿ„V
-Õ™­Ò‘7õŸ[ ê <𿣟n‰H‡$uH gžNã ‰Rº4<×ÈåÇ^§ÕáÍôªú¯ªîZ"þªÃ$:HCEçC‡À\ÜbU’¡Žddˆ$OkÆ›ó;ö”|!ö*
-'<%–AªùîÚ+&D/èÀãþë@'
-cõ5ïˆÂ ÍdFÞáoHò|ß
-䶴ÙvØŠ´GìñdZv„ª7Ë©-
-UêäÄ)#‰6 AH‹•Êø}Æ×…ïU…X89ÂÓJñ¦{%¥ü''Ãëû­H2ÈžðdP2H2‘}ãÉ kÅÙË'lÛ Y̱¨l_Ž@}ñšÙÇJz]8܉ „‡¾?ðW‚8“_œŠ`w‹rŽRÌ«¬ö5·ö!¥?/æ –(
-RPâDCªâ½§¸×”·e;Û ¼àai£«™5ëâÔ;J$Šwù¥-ÃÉqaÚÙºœÚ3 g\DSÙ>î"žž xLÿØ@}eMç»ÐŸ3]Þ- £¨4¨Š)ØKØWÕZ+‡`õú£é\( òágkSÂZAÙZ[WÎ6öuÁ¶Kc«7Šßí”8\‚:m6h-:.® ` )á^V
-êcljÒše`©dþÊ<åv§h[]Û,Qk:â¢! Þº ÍIö4Ö
-¡u¦?Å—NÅî_Æ©ðG
+xÚÍ]sã¸í=¿ÂÎL¬Šú`ß²Ùäš›»ì6›ëìôödKŽÕ•%Ÿ%Çë_€
+åýýì×ßÂQ«ûñ, ”I£Ña Œ‘£å™ŽTi¥¦:ûpö÷ž¡×k‡©)Ri¥2ГTCzŠL+èB==,
+X,,ϺŒ ²Æ¯w®ëþ-éÿ]ª-f]ÙÔÔhæLwßÒȲ%Ä,[¯Ë"§FÆHžeÖ,§e9.¢ç‚ØõŽ§éÖeýèÖÌ)o–™²Î–E @!EÒ[Yä‘lÉ ÌÖç"3Íœ¿oŠº«v„Û´VôˆE‡ï')õª)ë®X·¶kèÛ€ÂÖ<%)3be"‘“æíÝ+.GxÆá•
+„`÷E‡ÿ Ã4/„_ºMV—âËj]´-)/bDdb®™K-´eNv2ÒS4^ѧ=ØÕAK
+ËeYîl½Ò~Y‡`FN‚ßeÖvÓ
+CiåÂÆ6c 
+|pþš@»/Ù{ ŠT¡ª².,C=ΪnÑlÔ²–õÆ…$†¤-ÞD`¶¶Þ´âi7È;˜¬´~\J£dêG\–ËÖû”segFHŽË'ò¯–Iþ70òþ> à–{2âã8ªñ´x,kf¹-»…GUVFõ€q:ÞÃ3—Ì"kÛÍ<dÀE]dœGA°¥½ä…VrS?”õļ۟ÊfÓº(ð¥%ÐÙê8²7ó®¨],žU›ÜõyÃÁš¨³<›–UÙíl¬´ÜMSUÍÖ÷699
+,WÎlžÕ ìåt: ŸTGÃe ªãÆ‘²Ê/¨µåqKHZ8Ò‰zÀ•Ž¾ÈO®=sqÖ In›=ö!ö¯Ç÷¡D á¾4ŠÂîLR~ËMEÅaÇ2:¼©ü±QNO‰'% q!ðbÐ8d5é5Ñ&
+(Û]ƒ´Ÿi •i™‘†ûb"Tlmrûá6¸~û lÃX¥áøçç“D%Ò/À@
+þë»ëûË ';R¨6"H´JGÞÔn5¨7ðÀÿŽ~R¸]$"VÔ&Î<ÆA¥tix®‘˽>N«Ã›éUõ!^U ܵDüU‡It†Š.·¹:¸ ĪĠŽd˜
+ C iQ<O&e
+(I¾m‡™?´ÃÌÿ*™t‹š([,”Ñ©ð¯ LAøW«ð†ŽÀƒŸ®>?ß>pR ;™ît˜9Á6‹!²áI€Z?‚1O‚þÜ6š×> ÷
+UêäÄ)#‰6 AH‹•2ü>ãëBŒ÷ªB,œái¥xÓ½’Rþ““áõýV$²'<” #Ì7ž ¸¦Ql^>`Û¡01Ç¢²}9õAÆ kÅ>VÒëÂáHd 8ðý׸Äi,˜üâT㸛—s”b^¸Êj_sàpkRúóbj‰¢ %N4¤*Þ{Š{My[¶³ÍÀÛ –6º³fŸzGI‚Dñ.¿´e89΋v¶.§öŒÃÂÑ”ÙÇ]Äӳ騯¬é¢cú3¦Ëú±eÁ(* ªb
+övÆUµÖÊ!X½þh:×J‚|øÙÚ”°VP¶ÖÖ•³}]°í²°ÕÅïvJ.Á6´–
+W°?”p/+
+£Ë’…pO@X`º úØ”XÃà†ª¨] ÖÊ`É’Ÿ¦í`o&á, ðmi _˜¼|ûØÚ>kû6EfDYå ébÕ ›('¶3÷廕õ À¬²rMHb¡lu#SGÞû
+ô’J‚:ÄØq¢t€fX*™¿*ž2»S´­®m–¨5qÑo]Ðæ${k €
+)ö$µ•K„ÚÚhVÚ7Ï`©¸þ\<&rRÒgµ.%d»Þ¡â½spölO’p/ûël©¿s„þ{4‰gܧþ€²«'ÐSÒ¶D›u`îUWäèÓ‰pnêÏ‚×
+F½ÄiÃWMóSFÿXžê1)é:¨ì{!4³G:SܹÓÌ3‚à–•Í>󸆿Že]|a òhvõBóúµÇï{Â!d§–ÈófÈ')CP£›¦”œxG¨lÚ6Õ¦+¨µ,²šŠò@óIÊ„Ð ©#ï%Íq\“øÄ[1¡S"^[ݤváHÅ?Ê
endobj
-1531 0 obj <<
+1547 0 obj <<
/Type /Page
-/Contents 1532 0 R
-/Resources 1530 0 R
+/Contents 1548 0 R
+/Resources 1546 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1507 0 R
+/Parent 1556 0 R
>> endobj
-1533 0 obj <<
-/D [1531 0 R /XYZ 85.0394 794.5015 null]
+1549 0 obj <<
+/D [1547 0 R /XYZ 85.0394 794.5015 null]
>> endobj
494 0 obj <<
-/D [1531 0 R /XYZ 85.0394 729.6823 null]
+/D [1547 0 R /XYZ 85.0394 729.6823 null]
>> endobj
-1534 0 obj <<
-/D [1531 0 R /XYZ 85.0394 704.98 null]
+1550 0 obj <<
+/D [1547 0 R /XYZ 85.0394 704.98 null]
>> endobj
-1535 0 obj <<
-/D [1531 0 R /XYZ 85.0394 519.4358 null]
+1551 0 obj <<
+/D [1547 0 R /XYZ 85.0394 519.4358 null]
>> endobj
-1536 0 obj <<
-/D [1531 0 R /XYZ 85.0394 507.4807 null]
+1552 0 obj <<
+/D [1547 0 R /XYZ 85.0394 507.4807 null]
>> endobj
-1537 0 obj <<
-/D [1531 0 R /XYZ 85.0394 339.3113 null]
+1553 0 obj <<
+/D [1547 0 R /XYZ 85.0394 339.3113 null]
>> endobj
-1538 0 obj <<
-/D [1531 0 R /XYZ 85.0394 327.3562 null]
+1554 0 obj <<
+/D [1547 0 R /XYZ 85.0394 327.3562 null]
>> endobj
498 0 obj <<
-/D [1531 0 R /XYZ 85.0394 227.5589 null]
+/D [1547 0 R /XYZ 85.0394 227.5589 null]
>> endobj
-1539 0 obj <<
-/D [1531 0 R /XYZ 85.0394 200.4217 null]
+1555 0 obj <<
+/D [1547 0 R /XYZ 85.0394 200.4217 null]
>> endobj
-1530 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >>
+1546 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1542 0 obj <<
+1559 0 obj <<
/Length 2721
/Filter /FlateDecode
>>
@@ -6678,425 +6767,431 @@ xÚÍZKsÛ8¾ûWè0ºj„Ń Á¹y2ά¦&vVÑVMm&Z¢-ÖJ¤V¤âdýv£$%ÓN²qjW`£ñjôãk@j"áOMl"’Lg
*ò…©ï©Ò>™ú»´&ñtáoá3E®#óW·á‘Dª‡ÄUq®"¶qÏTƒL$Q5
q‚TÕÚȱÌÒNçÒh<’0σä æä`V¡ê²z¾Êw»>ȱÏ^¿?1Ì Çd2¼¶¸¬Gׇ¶¬+jE·Ý®½÷Ž’d öºÏ«f“3´ôñ{Í^õè%ÃðÕ66à¤ìñ3
ÑžÂ6,mETýHÝ0‘èÀÉF¾ÑœEYMýüi‰|¿ËGäb ˜‚ éj÷åRÊTŒK¢×‹9UŽ¯Ó1«HµŒ.Á!•>\9zU@VŠkžp²ß|4O¡a›¯Šã‘6 IÌé¶5=8M¦aÍGÑ°)ï*Šcy…Îé>ÏO ò4Y¾"ŽMqëy ¿8èh_Þ­[|Ëi
-”IþÍÛ
+”IþÍÛ
endobj
-1541 0 obj <<
+1558 0 obj <<
/Type /Page
-/Contents 1542 0 R
-/Resources 1540 0 R
+/Contents 1559 0 R
+/Resources 1557 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1507 0 R
+/Parent 1556 0 R
>> endobj
-1543 0 obj <<
-/D [1541 0 R /XYZ 56.6929 794.5015 null]
+1560 0 obj <<
+/D [1558 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1544 0 obj <<
-/D [1541 0 R /XYZ 56.6929 703.0246 null]
+1561 0 obj <<
+/D [1558 0 R /XYZ 56.6929 703.0246 null]
>> endobj
-1545 0 obj <<
-/D [1541 0 R /XYZ 56.6929 691.0694 null]
+1562 0 obj <<
+/D [1558 0 R /XYZ 56.6929 691.0694 null]
>> endobj
502 0 obj <<
-/D [1541 0 R /XYZ 56.6929 555.5354 null]
+/D [1558 0 R /XYZ 56.6929 555.5354 null]
>> endobj
-1546 0 obj <<
-/D [1541 0 R /XYZ 56.6929 528.2309 null]
+1563 0 obj <<
+/D [1558 0 R /XYZ 56.6929 528.2309 null]
>> endobj
-1547 0 obj <<
-/D [1541 0 R /XYZ 56.6929 486.7584 null]
+1564 0 obj <<
+/D [1558 0 R /XYZ 56.6929 486.7584 null]
>> endobj
-1548 0 obj <<
-/D [1541 0 R /XYZ 56.6929 474.8032 null]
+1565 0 obj <<
+/D [1558 0 R /XYZ 56.6929 474.8032 null]
>> endobj
506 0 obj <<
-/D [1541 0 R /XYZ 56.6929 306.0886 null]
+/D [1558 0 R /XYZ 56.6929 306.0886 null]
>> endobj
-1549 0 obj <<
-/D [1541 0 R /XYZ 56.6929 276.0992 null]
+1566 0 obj <<
+/D [1558 0 R /XYZ 56.6929 276.0992 null]
>> endobj
-1550 0 obj <<
-/D [1541 0 R /XYZ 56.6929 186.806 null]
+1567 0 obj <<
+/D [1558 0 R /XYZ 56.6929 186.806 null]
>> endobj
-1551 0 obj <<
-/D [1541 0 R /XYZ 56.6929 174.8508 null]
+1568 0 obj <<
+/D [1558 0 R /XYZ 56.6929 174.8508 null]
>> endobj
-1540 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >>
+1557 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1554 0 obj <<
-/Length 2210
+1571 0 obj <<
+/Length 2430
/Filter /FlateDecode
>>
stream
-xÚ½koÛÈñ»…>ôƒD{û$—EQÀçÈ©~\]S\.hiHG¤ìä~}gvv)Ò¦í´IŠ
-ÖÇQþ¿ã)
-SfhòTšB—ÂmßG))h-ãarW½@g=&ýNÛ¢
-BÈ7‰`iüϵÇo´Ž~U•K×#‹ShÂ,Ì’}ê:R~¼pewXÉWì©w8)¡£Æÿ=^Ä2Ť„9ùë'îxâ©ñˆÌÞ/¼ˆIŽh‰üž/bÂdL'Ú~ÿ'±.ågÞÄ>GèP!ý­Ó,ŒÐÚòNΩi‹Â™ G8>pµólB õºÚoV„‰ :®í\ÝT;Vó?jâF^<Ê)%YbQõ?6na£ç­çïÉ ÓÔPq˜ µ6ãk|—Ú#ï:ñE1_à·.¨wA¸* ç~íè5I
-—Ć?áâRY7d·½[í< çôYùgµ»"Ÿ>‰¨|5»ÙU[‚è=&¥÷˜Wæ i¹¼Ùïü#á«Ãƒ~QŽ§_ܺÁúmñÿ#_Ü„„‘"¢ûâöøO%¬Y¦»ï êQwºXœý¸Î‰?îý€w«³öeÁÝäûM3mšÍÿùea¨”€
-L!ãÖ<äÜ( ÅO¦¬ÿ…ŸžÊendstream
+xÚµYÝoÜ8Ï_1÷à:Z}ZòaqØl:éeÑ&{éìö°mœ'1à±SÛ“4÷×%Jþ˜zšöÒCš‘(Š”È)›QøÇfF*9Ó‰$Š25[oèìæ^1ϳL‹!ׯ«£ŸN…ž%$‰y<[]dBa³Õæ}tòÏãßWËËù‚+Åd¾P1~=;‰# ~N.ÎOÏ^ýqy<×2Z]œãðåòty¹<?YÎLHÅA€ð"þº8_"ÓéÙëåüãê·£åªSyh£ÂêûéèýG:Û€u¿Q"£fð%,Iøl{$• J
+FŠ£·GÿêfÝÒ©cêx@-"¨bß´-ã$I”œÞ–Âá bbóY¸Ž‚,O†cQý-Æ@ nDw‹\Ì#‰RÜ^cB‰f°\+Wã5žÛvœ Q±d–‘Q¢ÍÇÅ|³hÿóè‹û
+£iƒD^æmžÖW쟛쥼t÷äfqéåé 
+kE”6wY
+ó¦YA!LcúaÑCŽù„ù\À]gsœç¬ð›–HìÊOPÃåR6¸b/[¯‰
+xîÚK}6F‰‹¡È €rM&ã:¶'QBî¡ÄAKÉTJ%Zpq
+õ‚æOÖ I Ñœéq’ ‰aèäÔ;ù ½ôQiè.[ܽ¯±ºä2ÖÐ@…,â§5CPꌾÙm»B/¿žÎiîæl¸jªb×fdÂ9!Ù‹VÀažct2Òf gø"
+H%X<HGâ‹tŠÆÿ[>U¥£¢àÕãÍ5”Ó²‘Ô`]ûd6‚kBhfb¥ºdälž—Æ•þ_’›õBÛµázüp¸D@áõ%t„5de;
+8ãKHãë» waà«JJóMGÆL`©ßÁÅlíâ þ~èsŠÅ'‹W//DLèå¦Ó6Læ^ø]K,´Ñ8:»žzZ0A¨é@óð5Q8@(óhO ~ˆI˜<©í6%úÀ3´Sv€#ƒ#Èö··“InQðï…4¨Föá5<z v¡f¯l6È›lƒŸJpû¶c÷}:ãí‹Ê¿å„ÖPrQ3.¹¤ 7ãhtW¼@&{˜é2оÞ
+yî³Ús¹éå<eÂà#ŽÞ¦~¿»:wϳ½¥x3¢»àÿÚ+ðFÊàWU¹ÎFbm³)&Šq=6t$옸.BV{é†j·³ª ®õi|'‚p'ßÑX +uÁ ºÐ”š'úÞ
endobj
-1553 0 obj <<
+1570 0 obj <<
/Type /Page
-/Contents 1554 0 R
-/Resources 1552 0 R
+/Contents 1571 0 R
+/Resources 1569 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1560 0 R
+/Parent 1556 0 R
>> endobj
-1555 0 obj <<
-/D [1553 0 R /XYZ 85.0394 794.5015 null]
+1572 0 obj <<
+/D [1570 0 R /XYZ 85.0394 794.5015 null]
>> endobj
510 0 obj <<
-/D [1553 0 R /XYZ 85.0394 663.594 null]
+/D [1570 0 R /XYZ 85.0394 665.3048 null]
>> endobj
-1556 0 obj <<
-/D [1553 0 R /XYZ 85.0394 640.0743 null]
+1573 0 obj <<
+/D [1570 0 R /XYZ 85.0394 642.5175 null]
>> endobj
514 0 obj <<
-/D [1553 0 R /XYZ 85.0394 573.5829 null]
+/D [1570 0 R /XYZ 85.0394 578.7341 null]
>> endobj
-1557 0 obj <<
-/D [1553 0 R /XYZ 85.0394 548.3076 null]
+1574 0 obj <<
+/D [1570 0 R /XYZ 85.0394 552.6769 null]
>> endobj
518 0 obj <<
-/D [1553 0 R /XYZ 85.0394 357.2459 null]
+/D [1570 0 R /XYZ 85.0394 507.9859 null]
>> endobj
-1558 0 obj <<
-/D [1553 0 R /XYZ 85.0394 330.4365 null]
+1575 0 obj <<
+/D [1570 0 R /XYZ 85.0394 484.7183 null]
>> endobj
522 0 obj <<
-/D [1553 0 R /XYZ 85.0394 105.6253 null]
+/D [1570 0 R /XYZ 85.0394 297.8603 null]
>> endobj
-1559 0 obj <<
-/D [1553 0 R /XYZ 85.0394 82.6167 null]
+1576 0 obj <<
+/D [1570 0 R /XYZ 85.0394 271.7833 null]
>> endobj
-1552 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R /F53 1027 0 R /F11 1384 0 R /F41 935 0 R >>
-/XObject << /Im2 1049 0 R >>
+1569 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R /F11 1400 0 R /F41 940 0 R /F53 1032 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1563 0 obj <<
-/Length 3050
-/Filter /FlateDecode
->>
-stream
-xÚÝÉrÛ8öî¯ð!ºÊbAöÍí(O¥Œ­éêšt”HÛ¬¡HµHÅq¾~ÞøÈ➤jªÆ>
-áFª“Û“ô
-¹ˆ¹‡N\øè¤Ò00…tº-:À)‚î¡ N^Üe»ÊŽ.Δ
-Êuá~¥<h¨ÿ®ülGÿˆT´X¼ƒ†ÑÀ]³¥N»[¶ÅŸ»¢¶Ð¶g, ŠUcÚ¼¥ÁDz{ Þ®Î‹?¢ˆ×EnÏ[¼k5RDÁoxtV•£ì± # 4ÜÜ È
-LO1«Õl,Â(Ò®ñ¦zh=·P<L"GÝx"L»Ã»®òÀp\¤5Ÿè8¬4d\i»nUe­ïF< “D§=´ç`\9qwîž6Á­A üæR¾ÃU³^£fy
-\s 61
-Ñòp÷"ôùËA´¸Í¸@Íõ-µ·ó›ßæ7¯Âùï¿~x7(Æ5u_Qsy}ñ«|F~ ;ÆÈùäâç¬"ÿ ¿‰G¨AÎ à#+v
-‡xˆ³Ôàî-}b†ÎÊùµ¶ç#75Æ8Vgk7x··êypƒÓÏ6‹È=C»´‹†*÷š¤‹c&ƒ¶¬ï«Â·(B~»X܃t)jâbaLâò¦ª²­ƒ{_SFg~=­—MÕÒLØÐÃcß&Z{g3e…îéé§9‹ͶÝ0! }J‡?¨¿©²D&$áøÊ$›
-µ‰ë´SV­‡ÀÎ ƒÝ¨×©ÒX¿7êŒv½¢_&‚CkvÝf‡ÚÇ<5;š® òÀ|gáÀd&Ì·›ýÉä8xðr†Ç‘‹³w-†§xGl–Ùêß-„Q´Ò²ÑVõ8v”¯}Ù(sÀÑœÈ4(ÂûÐ 2PÍút©ö c€É#B69 Ë,Rƒ~ùè®3"yT`,nÁ:{"j4Œ³ª²¿
-A{ÒÜ<šøGŸHxФ¤Rî´ë&/ѸCÜKy|(1wôö2S&Õ–Æ&cÞaŒ7þÜÒ/'Hj-Œ)ªÜSæÝuÑŽ{lõ2kQl5&ùpÉ3 ÷LõHUÒ„¶£k仕Á Zà\æa/Ó©ÄÌ Ë—ä©`ñÈFTÅ]G—[PIk"࠲ѼƒUÙþ3Ks `RžLiÌ1‚Í%? )2 SÇ$ÜühAÖúLWÁÅÆ„
- ½;$ãnÁÀøç†{Ï‘EŸ>y §pvÜWî_ "ÒÁc²€(Å—l½©ŠsÏ•b2ÑÛ΃XÉ—b5ãѹ8Ï}& …8‚Á„OZ–spÑ©dzÊòDsXñ€GØŠqÊqkoaxµÛ’h›ÜfŒGûËx°_áàô;¬·¥Ò%LdvAFÓy±*×YEcƼs_ ºÄÌ-eyîÛ^yñ‡‰ËT䔘+`Íݸ) |ÎÊ*[ºb9ê›”ºCù¶wTTVõšÉ(Œy_ZÈ}Ň0J4”–Û+¬º¬²üÑ`Ú±45áÏ#'e§ÆWš •è ŸÖ$€7¡)ÚÃå7œ9pP’†Rô
-óÅk¤ìµÅ£ð0~÷]Ân ºáv› ‰Á
-ô‘0é0ÞÊ,è ãøcð„bé3>3êkPTŸËÿ+G~m…Zô²qÐâÈ‘ÅQÜæ9‡‚9Á°þ¥¾ËI•N*ƒ
-äà}ŪŸÇX÷w
-üY÷[[®^ßaÛˆ ßGãQEÖ^ç/¸j»ã Û”
-9gÇÝ*S =‹›Â?Ä“f'‡ÅAZ èÞG6bÉ›uæT"7“}]íé:q»Ymë¨-לmÍ;2=¬¹/Ž°`„Ü÷Ñk`ÁðYÏÿâñmA‚‘×LÊ 2
-îû¢gßq ÙW"L 9hÿÌ(Iðóe+ê…ß2‚X§‡?á‡?Éíó6}³2a·Žáë˜Â}³§oD¡€dÛnšÓ÷P qNN
-ow}¥§&[ pé=¦ôÅÅ t’53Nœh0Ü'qÒ[´{é_ç§1·­pîÅa=—ï.no'ŠçR츶?'ó|G~Ó¼ô«µáË=iêCÜ/)½@ÙK!•’øÙÍÝçmϯþ<õª÷endstream
+1579 0 obj <<
+/Length 3049
+/Filter /FlateDecode
+>>
+stream
+xÚÝËrÛ8òî¯Ð!ºÊÂàE‚œ›'Q²ÞÊ8YG;5µ™(‘¶YKQ‘Šã|ýv£’’!³™©­Zû
+mtªmh¤…‹5œ÷”Ó|Ÿf«åqVW-£ŸUã´íõKêHÅÓáLº­DpSo
+‚&OzÑNœ`šýsÞvåÖ„ªv8ξteÓVëæÇó©žÅ¨of×3Ð é|ö×iÄÞ)O…9QŒs¥Ýêoêû6p‹X²”Ëç*GXÃ<½bØãB°2&dl¼¢Õyº‘ÌXššl¬f`b¸rêïÜ=n‚Û ‚ø úÿ—¨ÿ£¦ŠgLÁÕ\›c Û·O’™8Qc—q´k­lC¯CÓ “hI*™w%çÔ´å¶*Ý&«¨ÐÒÊv½³eI
+Hž$8hDZ÷LöÉg•ÏJ(3F@šç¢àV9oU§¸
+žM´TL¤"}NX­2Å 7aõ·Ë߃Ûø"Mâøø hX®ëw샚zœ¦*5઎Ù4YjÀMi–
+%Gîÿ©fM| C:¿·ª‘¤dR±ƒ&Ûuc;†\ tkê@8ºjÑúh°x]¾í¦m·Þ¸][j‡ñ ’Ú0´†*ºò îÝ!ÊmÛ.$$x
+Ÿi/´hä/Ðè €×Íð r³¿¬¥<#÷ ­À7N¢Ëº¦Šj3º¤ƒèP
+c½'B© P^df2fà÷ÉJ„¸)Ü ˜Fêo€Ùo9&hRÀ…µÊN
+š2),2d[ÃÁeHÌÐ[yÇÖö|¤ñõCƒŽ5ùÊÞ¬zÝàôS¯-8ùghnÑCA›tÙ`° tÔVÍ]]—X0HpŒN!O}0ŒY\±®ë|ëáÞ5”ÒÙ¯ÇÕb]·ôºxì»Lëàl±¬2==Ã4 ¢ãÃÙ¶Û&´Ïéðƒú›:_Bxac)¯B‹}¡¶ñÊjÌÙÙað£»õ:SC ãwVý “Ó®ôeC˜1´õ®ÛìPûdGëM7¥y`¾sð@`rç»Íálr=9#îí]K„‘Þ›E¾üw qÔ=m…¼l´‚ÿ$ñ”oBé(…ðÀÑœè,*Ù
+æp°Þm«»ÛhÅYŸû¥¼ž@dÆŽgŽãŒì;³¼!uüó+"ÕŒ›TŸLÁʲØÄúÄ‹Â~âøaFÎZ”AíRAÛ©Vå´[Okz6ƒë=4–ø²oAŸi¢ ¬ªÂ,©tÚþÈÂI¦èP€¬Ü ¥çí}¹­:ïÛ\ž±¯਼Dô¯§n_Þ,ý{ÆyíêòèÛÙX쎽¥
+WO/Ãv"¿ìø¯Eäñ_‹îu›~²²Çm'ÃcJÿ3˜u£
+å#ßvû}ÿ´å¤ïn×Wzhrµ
endobj
-1562 0 obj <<
+1578 0 obj <<
/Type /Page
-/Contents 1563 0 R
-/Resources 1561 0 R
+/Contents 1579 0 R
+/Resources 1577 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1560 0 R
+/Parent 1556 0 R
>> endobj
-1564 0 obj <<
-/D [1562 0 R /XYZ 56.6929 794.5015 null]
+1580 0 obj <<
+/D [1578 0 R /XYZ 56.6929 794.5015 null]
>> endobj
526 0 obj <<
-/D [1562 0 R /XYZ 56.6929 713.4234 null]
+/D [1578 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1565 0 obj <<
-/D [1562 0 R /XYZ 56.6929 686.2623 null]
+1581 0 obj <<
+/D [1578 0 R /XYZ 56.6929 751.488 null]
>> endobj
-1566 0 obj <<
-/D [1562 0 R /XYZ 56.6929 478.4096 null]
+530 0 obj <<
+/D [1578 0 R /XYZ 56.6929 670.5492 null]
>> endobj
-1567 0 obj <<
-/D [1562 0 R /XYZ 56.6929 466.4545 null]
+1582 0 obj <<
+/D [1578 0 R /XYZ 56.6929 643.3882 null]
>> endobj
-1561 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R /F41 935 0 R /F14 737 0 R >>
+1583 0 obj <<
+/D [1578 0 R /XYZ 56.6929 435.5355 null]
+>> endobj
+1584 0 obj <<
+/D [1578 0 R /XYZ 56.6929 423.5803 null]
+>> endobj
+1577 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R /F14 741 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1570 0 obj <<
-/Length 3287
+1587 0 obj <<
+/Length 3094
/Filter /FlateDecode
>>
stream
-xÚÝZÝsÛ6÷_¡·“g*_ÁÇ4qz¾™‹[Ç÷r½>Ðls"‘ªHÙuÿúÛÅ(QrÒø!“Ñhˆo,¿],°Ë' ~|bòŒÉRMŠRe9ãùd¾:c“{¨ûùŒû6³Ðh–¶úéæìÇ÷²˜”Y©…žÜÜ%c™ŒÃ'7‹ß¦oÿùæ—›‹ëó™ÈÙTgç³\³éO—ÞQIIŸ·WÞ_þüŸë7ç…šÞ\^} âë‹÷×Þ^œÏÊÒ诒|ß7ØÉ÷üxsùöãùï7ÿ:»¸‰ HÉ™Dêÿ8ûíw6YÀZÿuÆ2Yš|ò–ñ²“Õ™Êe–+)CÉòìãÙ¯qÀ¤ÖucZ.M–QŒpMð çY™çbÀ¶¼Ì´Ò±Mg2+Îgœ16}³XÔ}Ý6Õ’ü¾^ZŸj7«ªïp½0ªLö‚MfBe¥âÊ wٜϤdÓÊE¹¾õßK‰®¯šEµ9çfºðUöÏ~‹cæÎM÷dò°‡X\úÎÛõºÝ
-ãVö¡"J|ÁÏzS¯cDɧÝ< ¢,6"aŠ@DiD ~ûqp2SŠ§ÁÁ2#K½‡7xG_ûçÚžóé¼· ?[Kß[OŽm즊ÕwÄŸ-ÈÓept1„P1Âp9 ·€˜¸D‘.Q”™Tyî©oª•]Ìæíj ÚÅMr¸^˜Dk¡|h»u‘¯ig„rDÃœ·¨KžCÖíK·þ{·×eñ DÔsÊ ˆ-ýº§"ÇTl¾í[àt=¯–€,/*c¬(‡r0Wj ËY}GévåÁ d¢\C:”uk;¯‘Å¡72Sjy„™pH ŽxYUHíÐl'°{ü4"Ì„>íµÉi§ی̤a¥¹Òé¶ -a«xa|+T¬~]¤—!öx2“Ž16
-g‰à@8A‚Þ,z/€!sÛuÄ+ÈAeÝC»].(}ëÊ5i-È{m]¸RŠvŶ¾ž? †!é„õʼ0 ÷8¹õxBÞÆæÌÏšœq›sØŠ¥Ï»fc‚)Á bâ 9Ée>ä¤Gô}U7Û™0&39XÀø¾Yö°òûd<?r¸h‘™Rò— Ð}rßò€1·ív£»Dcû§vó‰2·Ï½/nÉ’sFdÝ*\â±­~ ²öæuoãQ?[صm ýÔ†Œ×zYß73Z¿cZH5ÜÔ•ë$”˜v-}û‡Ê—Ôá‹"©¤3Œ0¿Ú:Ð@
-íG2œ0ê×m×Õ·2¥ö† 6@íŒ EG®?o•?o•?oá Ìó5uÓÕ h´DRððäƒÞò§ëžÀvÏ ÛW YZk2¬µ°Z—d¿B1K¢²ŠŠ¼I A¡a©³a±ã(`@·d9HÑKˆÑL uö5L²ª>Ù-;~cám5ÿ´]ûõÜíèqQÎáÂã¶
-ä+–t»Ñ]yÝІ‘Ö^X±&šÌ ëGë,pέÚu„ƒù®š‡J2ª´CúÆ—9Nj46{?ø*„Ê#§_eB¨3ô´»LAI¯9Æ”¯›ùr»mÝ4ÒjÞn8?{¢U–A]@êÉÆ‹ÇálÎ
-M¢øî28åE&%hYº‹ Éý; ¨«È²kûÇÖvô¾’rL«JÎËI:Ã×ч|j©àÎ`ÌjÂOQN›íêÖÁ´ ŽeõnI{÷á#U6ýú\jŽa±™tlzõËÛ«wøTi®_‘É
-=™íؾLJ'e!ò0ÉDVp%F0ùëÖnj{’é¯ÉÓDGH¦D;HÊBFHbÚðÝAsø¹Œ;¾0á`7€#aýÚ?%÷Ïk{Š¯Ç…oŠ°Fç_²¢Ðãs–•Ì¼
-^, Ë P¾¾1PªW%¥$÷PÂÂH,öÿ7¾Ê:…a›ª™ÛÏGf2á«!óä""2ÓE ©ÈÔ€÷þ€p©‹ø ¢éÖmgcèLØÑ®Ñ)€W!1ڷꎽpw'ðüj¬û~M ¡5ÜVô x¥Ìr!éN|ÎÅÏ…p:ÇkY§éÐBXi•@Xé<(W¬hÜ)‚…Ñ Øº‹þˆ
-‚Y¹C³b¦áƒzaT6þ¦uñz ÿf€¯@ ö%GSèq ø¨Ýpe§ŸKó’
-Óº¯±YNd•£ï¾ÂRršb{°sU ÃÿAt9Ö ¼ucÂÕõm|¨“†|‹ø%é‚Äœv“è ¹­:¸yÎ
-.RÛ|Ì"úYzµ-ü~-uôä©Ò¼tˆ°2cp÷#eÜÎ?Yÿ6{ùãÕgŸ%éT¯e&?J‘h©25‡TYij*¢ÿË ÌK÷0öž÷ˆ^ýãP|½µP¥Sð ÒŒãûT­wµ'™±*Ñ©«EVÍÇ÷+íq¥`¿üÅê úù”·CóþÆÃJâÓé{?ó.MøÎÛå281YðáÈíSCÉu#HïúDpÃ3ï"v]“i*?O¬­¶ýC»Á0½y$}~…
-nr$cÖò™¹ uˆ[!Gú²úèí#¿§I¥"Ïv¡.ÏvlÔFmÐGzŽ¢Îú ö\*;ÂÚjÛÆ#w1†¥î¨XTト „Óì®Ò/>2€ƒn– GCÁ»ôcwmx>˜WΕ?ðÚìè/&i\Éû#qBjâ
-°‚v =àžIb;¡š‘µÇâÀužIá;Õlî'”¸ zßµ>~ ø6îÐ&?kxp&íÓ‡†PºL98ˆb›“óïät ³†,4*Æ­ÌÈbLúW‡Çïx‡ŠÐqÄæ g­'
-‰7Å¡aâãèIÿ?äßGendstream
+xÚÝZKsã6¾ûWè¶rÕˆÁ‹ ytf<Y§²ãÄÖ^6›%Ak(R#Rö(¿>Ýh€eZžÉèšR©Øx5¯1øñQGLfj”d*ŠGóõ=@ÙOÜÕ™øJ“°ÖÓ‹ÞËd”E™z4]¼Òˆ¥)M¿ßþûê×éõÝåDÄl¬£ËI¬ÙøÇ›ï('£ÏÛÛïo~úïÝÕe¢ÆÓ›Û”}wýþúîúÃÛëËI–¥Ú«€ƒk{?ÅF®åýôæíýåÓŸ/®§Ý
+´¡O’Õ&pÿrø.ªÖl;l-ò6wpo·—éx7owÄÇ•”šãh9çã7=PÁlO”ZçÛ  —W¬I¦ú±¨³£²Î‡Übm¢nª“(“"µ#{P™@½àg³-ÖV1"ããÆlA
+ðKQÖU"!E "Qƒßv‰Œ”âÉip°(•™>B‡eÞÐ×|Þ˜K>ž·fáz«é;sR<˜Êló®xIúYÓ€œü †p
+Ù ŒÝ2`^NY.¤… ïÐ0×Æ°Øp0à[¢¬è5Äh¦ž!˜Úø:YçMO–ƒ¾1s–Ï?î6n<˃<6£³sØ€Ù)ÀÒ¢q¦ غÄj( EûA0µ³õ# ï|üù÷w'¶¨s´]ÄD½Ö©›-ñŽö›-Å"¡eê6[ÊmµÂm.¶o Êxi{•F:ÉzÛGÍíþZ¤ÁM´ðo(·¬í:
+¨WÌiÜm~QÑ„‘ÖÎX±¤ ™Æqk hÎŽÚ6„…y™Ï}!UÚ"}ëò¬&5›­c>Çe€2¡ð…U ‚¯,ÔzÚn¦ $ ·9ýŠ”.ªy¹[øºv¨5¯w¬Ÿ-É*3ï.€z2ÝÆãyo6
+ÝA1ÚBQ1ÞAi„¢ýv#‚-âŠXd¡ˆÄ)(ÆB[(ÕØÍO,’àÏÖXÊ>œµb¶‹TëÒZFCþ÷?.’ô ýƇ!…yºÌÄø„œm¾_‡,`!UékFÀ’ˆIw3󶈸CðgšÏv ƒötu.Ï|RúÎBé9¶ñ7ߘÊg`DNZê0\©Û£à¦š¼ŒÈ³©à;$,£<eâ4"E*¢D
+9¯ê§ŠÈçáßEwã„¿}gîfØ6 º]実®4ßµ«z‹¯óüã ïOðª/QþvŘ4§®Ê´Ž´öÏUèþ¯°Úî’®;ÓÐ*âèðÂeo†¸ú+wªƒWSà–a%jŒëàè&å`CXšž´ñN»øt¥hW” **ŽÞ»ø Â:vzŠ«‹{ÀÁ7KžÉ¾áÝ8ÞMíÏ æyã—v—5Gݦ$|y»ñ¶{±ô/i: ³Ìwe;°ðØyÍ"–ÅÝÙ¬ç+u  L¿fÔÐÃSMex¡HTxç(Ýý"Vµ÷‹2¸_<úÇ
+½«OŒN•ßV®¤h<×µo²)sÊãî剤›N÷¬jèí1`HIɇž
+³‘‡ù7?L><ÕƹÙÍ{÷â¥ÂyH³çÎØ=aþ/qÎ=wendstream
endobj
-1569 0 obj <<
+1586 0 obj <<
/Type /Page
-/Contents 1570 0 R
-/Resources 1568 0 R
+/Contents 1587 0 R
+/Resources 1585 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1560 0 R
-/Annots [ 1575 0 R ]
->> endobj
-1575 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [84.0431 62.1828 145.2431 73.5749]
-/Subtype /Link
-/A << /S /GoTo /D (statschannels) >>
+/Parent 1556 0 R
>> endobj
-1571 0 obj <<
-/D [1569 0 R /XYZ 85.0394 794.5015 null]
+1588 0 obj <<
+/D [1586 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-530 0 obj <<
-/D [1569 0 R /XYZ 85.0394 769.5949 null]
+534 0 obj <<
+/D [1586 0 R /XYZ 85.0394 741.6375 null]
>> endobj
-1387 0 obj <<
-/D [1569 0 R /XYZ 85.0394 752.4085 null]
+1402 0 obj <<
+/D [1586 0 R /XYZ 85.0394 717.2979 null]
>> endobj
-534 0 obj <<
-/D [1569 0 R /XYZ 85.0394 542.1781 null]
+538 0 obj <<
+/D [1586 0 R /XYZ 85.0394 507.0674 null]
>> endobj
-1572 0 obj <<
-/D [1569 0 R /XYZ 85.0394 510.0725 null]
+1589 0 obj <<
+/D [1586 0 R /XYZ 85.0394 474.9618 null]
>> endobj
-1573 0 obj <<
-/D [1569 0 R /XYZ 85.0394 447.7453 null]
+1590 0 obj <<
+/D [1586 0 R /XYZ 85.0394 412.6347 null]
>> endobj
-1574 0 obj <<
-/D [1569 0 R /XYZ 85.0394 435.7902 null]
+1591 0 obj <<
+/D [1586 0 R /XYZ 85.0394 400.6795 null]
>> endobj
-1568 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R >>
+1585 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1578 0 obj <<
-/Length 2644
+1594 0 obj <<
+/Length 2603
/Filter /FlateDecode
>>
stream
-xÚÍZKsÛH¾ûWèHU¢Þ~ðÕ³§Ä±3ÎÁIdewj's $Úâ,EjDJŽ÷×/Ðè¦(Y
-åÇT©\e5A4ø€úAÑãð'zAÈB-u/Ò> ¸z“ùïÝÁ»gÂò Ó Íõ~töKõ4Ó¡ {£Û–¬˜ñ8½Ñôw/d>ëƒºþ ûpïfÔ|ïþ]ÝŒ®Îoú­céÿúîËèbH\a«#Ql÷óÏ×—W¿ ­€Ï×D^\^ /®Ï/úŒ>]ŒÚF
-®Pû¿Î~ÿƒ÷¦`ë§3ΔŽƒÞ=<p&´–½ù™(øJ9J~vsöµØzkºîMp&U(÷ &Å>ÔÍB%UƒŒÜι7š¥·:©³ªÎ&=_fyŠÆ‚HÕÉ{é3í ßkº×éšZ·åržØvµ#tºš/¨5Nï²ÂRï³zF­„~ò¬HߺæÓ_¬b[1­dlôxóæÍ~3>4#6,ßyÀu¤ ”´¯áAì7“ÄG3¼b5§KjgþÆÞ"YöEì¥E=K«´²/íoB?
-ì³d-!‚³0´
-ªqÙvóršá€ë(Jاµ)Hئ
-ÞƒãS?¢lÓá»-jà,(Xbk Õ©ÙÈê¦a ÛDõT„·ˆ¶d76Á†¾–Æ—ÖoŽ®p!ý2‹™W»›Pî³HG¢×ûeæ n<T”IÅ´àþDRu!?bÜn–oZ„BÉ@1Š½aú×
-¶GkêJ¤|oøuOM±LµÃaŸ«/ÄîÛdc$TF€¥LR˜ŠSH:Þ5ä™_úF›2 Ê0S±¢vA.Øm0
-&bŤôÄ‘Ù•-WÞC—£¾Æˆ‹=×£‚Ot£ì #F,Œe¤‘`2Ô~)îJù“Cð§‡`¶ô<a4ƒ€E2ê¨ô"ÐL _nôÈÍÂ07›ƒ I»/îdG‘ì(î˜
-´h9v{
-˜Ï•rXuެ̥j7˜_ÝúRiíÒã*7 ÓçönW›¯‰ð§"±·«Ü’‹ê¾¹;ƃÝìBÏyšP{t¡J÷´jsš«š{Ó@Z`ûKß)úHyן/†ÃÏCzhçq+ÁFðï½ãÌÓÄ\§‘gV„Ø°ÚC;ô†CFÄ‘½yܽ޳DóFÐ|v²ãÉcÆE -¸ÕA/ Î-l6W‡ÝÕãïÂÝï—«jë±Úæk}y8æ[Ñô²øü;Ó­ÃŽ G,ˆ•tÖ£–T_ï¨\ÄÓ±½e}¼nGû!|[ªŸîX$a—*:²s°PÚ[dÀ÷ºL,ÂéĹ¹N^îæ`ᙸ·Lz)îh?ö
-YÈcßǼ¼×é”c?Þ|LÕ0Ž[§”mTñ¼×ÇpÇD¯èÎ"ŽÁá¾1¶\-ÕÿŽãçzendstream
+xÚÍZMsÛ8½ûWèHU",>H€˜=%ŽqžDVv§v2J¢mÎJ¤F¤äx~ýv£AŠ²eQ±=[ªT…`£Ñh¼n<4h‰‡¢i¦­´=cCqõ&óÞ»¾'Âë j¥A[ëýèäçÊô,³ZêÞèºe+f<ŽEo4ý-Ð,d}°Àƒ÷—l #\ú& Þᣋ«ÑÅéU`m,ƒÓŸß} IK·’Ä?ýåòüâãס7ðË%‰‡gçgóËÓ³þï£O'g£fíE
+®Ðû?O~û÷¦°ÖO'œ)G½;xáLX+{ó“0R,
+•ª%³“«“/ÁV¯º4Á™TZî@Mª]¨E–i]ˆÚt5_¤SX–ŽƒªÀ§ ªÛ”ß8—3ß.é$CiÛ`|ïG6À
+Y±ïƒënÃb
+ nÓò[h¤ºL•Ôåà…':\¢ÇRi3t«$Ë)pðN|)Ìv4œÑU^9g¡sÌV^ïÚÞa Zî iVÏŽy•Ìè…²ìÊ¥æCXÜ9ÖR0MœfI²dd³d<ó*Þ­Ò=¯ÕÆ”ë묺ï !\¸:õY
+ê·É:%YB‚z…Ú"îÈ2Éò¢"iy[Üå$sG6õøp¡IŒÎ Ö¨¶âK<!ã­1Ðé‰{RÚº £ EYEÃŒß{(ºÃ‚€ÜÞÒhHR©€²l
+Ü“M0hN· qU;³5ög¾e3¦mã2jÇêÑ¥6ÌNô;ðÔì^þ&¥é"æΊǨ÷ÈÍ
+.ŽR1»÷3Ð#“õˆ§’1à·/¸bB<b‘}Dh˜þ¹‚»Ñ:„sŨ0~Ùq  ° ÕCè?;\|&õГ³P:^2Ia+NÀ›àxæ§þÀD±§ Ô#¢An+–ÔÎ)É&À»F®=#{2\m ^†íß.­7Bï—ŒÓB©­pé —þ?…K>3\- ^+\¯Ï?2š:ìWd˜áM´Î¦yÉ»c4l¢²}¿>ûpy…µw{ Ò:dOBÚröµëo€4”Lh!; #f€Ók¤Þ'SÄå_î. ä³Ñ]ååj±(–¶7µàà-›oBÞZÌC®8“¼‹s <1V6GÄèêâãóav£È‹¯‹£xMEÌ`Ig­”‚ÅÊD5>€Ä Ø
+aBÆ…®+ŠI{ ¸RUkPŸhËÕ#4Šá>ÝE Z‚‚ê…_¯—LAy6üúëù°ÍÿyýÇÎe’—×õg§H¢Û×GÌ¡fhv`9®©„øº˜&UJ¹ª¥xAÒ ï‡û<™g_õ:/Ä·åúç®
+Y¤ÃŽŠB(hD¢®(ðC!~p*PÁÕ»¼<„ h‡°Lójt-§Ž:)™æ¶kßK æ´hP¹;Ùr•ãß¡HÌQßbÊÅA=¢•ƒ?‚iËÛ#Þï‚3…]5™ 7â”ÿpîý„ÐfËÍãMP3zû±ä’É8Š7ùyà]á ,7wƒý¶œ;^cÍLW2Z°¯¸nP9ôþú~/°ûqܸøRq=¡ÄŸC2%Ä®Šñ^'ćþ.só÷Ð@ÍËÝ¿8“Š”XÉžŠXè?ðZþŒúœ^«åúÿ
endobj
-1577 0 obj <<
+1593 0 obj <<
/Type /Page
-/Contents 1578 0 R
-/Resources 1576 0 R
+/Contents 1594 0 R
+/Resources 1592 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1560 0 R
->> endobj
-1579 0 obj <<
-/D [1577 0 R /XYZ 56.6929 794.5015 null]
+/Parent 1556 0 R
+/Annots [ 1596 0 R ]
>> endobj
-538 0 obj <<
-/D [1577 0 R /XYZ 56.6929 769.5949 null]
+1596 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [55.6967 732.5838 116.8967 743.9759]
+/Subtype /Link
+/A << /S /GoTo /D (statschannels) >>
>> endobj
-1269 0 obj <<
-/D [1577 0 R /XYZ 56.6929 752.4444 null]
+1595 0 obj <<
+/D [1593 0 R /XYZ 56.6929 794.5015 null]
>> endobj
542 0 obj <<
-/D [1577 0 R /XYZ 56.6929 549.5629 null]
+/D [1593 0 R /XYZ 56.6929 718.3947 null]
>> endobj
-1580 0 obj <<
-/D [1577 0 R /XYZ 56.6929 524.9842 null]
+1286 0 obj <<
+/D [1593 0 R /XYZ 56.6929 695.4159 null]
>> endobj
546 0 obj <<
-/D [1577 0 R /XYZ 56.6929 417.5407 null]
+/D [1593 0 R /XYZ 56.6929 492.5344 null]
>> endobj
-1581 0 obj <<
-/D [1577 0 R /XYZ 56.6929 395.2295 null]
+1597 0 obj <<
+/D [1593 0 R /XYZ 56.6929 467.9557 null]
>> endobj
-1582 0 obj <<
-/D [1577 0 R /XYZ 56.6929 395.2295 null]
+550 0 obj <<
+/D [1593 0 R /XYZ 56.6929 360.5123 null]
>> endobj
-1583 0 obj <<
-/D [1577 0 R /XYZ 56.6929 383.2743 null]
+1598 0 obj <<
+/D [1593 0 R /XYZ 56.6929 338.2011 null]
>> endobj
-1576 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >>
+1599 0 obj <<
+/D [1593 0 R /XYZ 56.6929 338.2011 null]
+>> endobj
+1600 0 obj <<
+/D [1593 0 R /XYZ 56.6929 326.2459 null]
+>> endobj
+1592 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1586 0 obj <<
-/Length 2860
+1603 0 obj <<
+/Length 2927
/Filter /FlateDecode
>>
stream
-xÚÍ[[SÛH~çWøÑTŽ}¿ì[`ÖS3f+µ3ó l4k[F’C˜_¿§/’Û¶Œ0xS.Ôêë鯿sk ÒÃðGzZ Ì ï)ÑÀDôƳÜû
-m?ÐgPwĽ>Üœüã‚©žAFRÙ»¹‹æÒkMz7“ßûÿõþÓÍùèt@îKt:÷? /Ï|ñW—ß~½?U¼3¼ºôÕ£ó‹óÑùåÇóÓ1šÂxÍÆ^ßØAaäõÍðãõéŸ7?Ÿœß4ˆ7I0³Ò?œüþ'îM`¯?Ÿ`ÄŒ½GxÁˆC{³.œ±ºfzr}ò¹™0juCÛ@ã\VTõ#NÈîUý
-V Eʱr®/:0`…CàaƒW‡@It0’ô”0H2ÊÜ!|.žFé]ZÉÔbCX4„h’>Øw^¦E––§Æy¿8%ºŸ–Ëi•N|M6[¤®&™—iaÏÁ’aý›û,L3΋0Ó"ŸOJ+¬6 !¨[¶ÊýqV÷i1ÞUˆk)‚ˆÅîÍ0‰¨`2tçËy2¹™ó;ÿ\xQ¾eù²ô5ßÒ¢Ìòy¹Þ/b)Ú¤”` ÎD/>·/ç a S˜@°×}¦¬Gì` ÖˆÒ.ÂÀŠSæò{Q”iµ_(U|±5–/öyyu>]ÖºÊzäcVÝûÒ<÷ÏIR%¨*žWÄlóÊUZ&¹g+“
-OvÎ"uRr3ýKl¨/Dÿ1_N×<¦eî+ï
-éF•Î“ù8T\W•·†CýXç gBÀ·q¡`¬¦êEe1®a›Šíaû¨Z|@5j6åï¼]i3k÷ë i°?$iðHÚ«ÒõÓì6‡œÒeÚ?ó×]UøikíÎNHIàD¼ÈÛ·1¬õÿ êG¤i§Û
- dÆP°X@JŸÝ=]-«o¼Å¤Ž”àuþ9üÙ Ëlr\[”2Wh7|‘\‡…>E‘DwÁ§
-D¦‘G¡Ø~q¶âBxÿCñN }põ ‘„Ç $…4|RýÁª‚w½z¿¯;!¾ð×a#ÑŽAèÁ´èôÉ„#£¨ˆÜG_… íØ ¢1ˆÃä]øaHÀ3û+õ/£Qú°혭û¸ç48’ëˆÑÓÊ~ZÝå“ ‹Ò5ðöaßÞàEb1xJ Aq—+V‘£_A¼á¾ØERq0-ä´¢ËK…ˆÿ 1|ñö/ë÷#E¥»ËAÄþûOË÷¸×ÉÊ—þ#Ôê_à cµ´˜Ð\=@|aç²pi³}O£‘дé‰þ?¥w¤‹endstream
+xÚÍ[[SãF~çWøQTŽ}¿ìÛd€,©&†l¥6Ƀ°ÅŒ²¶å‘dö×ïé›Ü¶eOŠâ¡[­¾œþÎýȆ?2Ðafø@Ž&b0žàÁGx÷à s†qÒ0õýíÉ?.˜d$•ƒÛûd/°Ödp;ù={ÿ¯wnÏG§C*p&ÑéPHœ}yuæGŒoÞ__]\þðëèÝ©âÙíåõ•_œÎ¯ÞŸŸÑÖód‡°öæÖ.
++on/ßßœþyûãÉùmwô’3Kýç“ßÿă ÜõÇŒ˜Ñbðcè`vÂC‚3G¦'7'¿t&oÝÒ>Ð8×€U€GŒ’=Çú#0º\!M±Ú8uh0à
+ûQ˜¦1í¸@I IJ$eŽ ¿ÔO7Ëñ¸h‹ ¬`É
+¢ P
+ø`?wYÔeÑœ™1Y}JtV4Ëi[LN‡㬜û7¹o¿íýr†çÍcQ[f
+Á"œ‰A*N¯“Oζìp~þ–qÅ‘l($öЄÈ(ñï–í§wó—H¼Ej]â툕xÛæ°_U—mÞ–EJ¤}'¾+Ú_‡Å·ƒW„T½_i ÒBòˆïU•„‡&d7Wù1ážW¯Ã=½Ô±€§ ™½dk˸bðŠ"&ÌÁ–Z!ƒIgÊGÅ}Q×ùô%¶œó ¨íˆ³åÝ›°©Y3ã°háÕ¦ì3è•gÓ“¨×RëÝ—aÀ@Ád˜øí-aÊ×±w%1L ¸ëK¶Œ+vH €Â¿ûFY›NS¿ÔuS´/QMª6UFœjB»ò¼«iÎó†•ÁõBo^ùv’·9ê/WÄlË•´’äÚ^Iäasï¼&p˜+A6%Éîl%Ķë’dG@’ìÐБ=$
+Á>Ó‡œÕˆPÑ9…ˆõÁjüûâTˆìÝåO€„Æà.òrz4×`íáù_þ´çäÇõ¾äx@Š„†Tj?ÐD"¢pç.®G?ƒZ@¤|ÏA{Ž…oØ{¬ ÉÇõ­üh¾Uh¤bì
+Ð"ÕC'4€¹^a㥃År‹²ltñ8ùå…¢’\'ù²ñòÂ|>l;MQ?¸tÔV¾]õ}UÏRY‹„ôˆ‹=f²ÊÍœ¸Í8ö›ÁðÓù$Œ¹Sã ñF ¨b>oçmK­ßù+¥¶Nï±)¶Œùß'¶‰HË? ƒ”/Ù2®è[n`gv 
+$8Gœ¥öl¹˜–ã¼µ¬¦Ld#x‰ÔBBÕ•f ë+7Љ’jûyÛ³…w*vNåÛ•¬†5wËÖw&e3\—šXû!˜¯=IFß_ʦ-çý“­’ìÉ?ùØÓöq¶Óä³Ð»ü6šL‚è6ßõÉ뢪Ûï€8Æ»š5Ù噃Ô6 ¯Û§EáßæV‘ìÛñ4oš06õÇä“'ÿî®pdÛ®ØjØw¾­Ð8iºú“êÓ8åñum¿ŽÅ—RªÀÈIÇÿ%uTÝÌNÉìÞ <>6aÎø:ŸŽªz‰X¿NMVšDKþ¢l\ѯyÌ(XŠl\s@žu‘ñY]- É•-x[ë`
+;ôÀôÛé\‡Š†:»€>èÔšúØ5y¯‹(¾XióÇ1šÍ—³;· #Žqvl¥oö)q:~Ih„÷žFè‰ÜTk¯Ž‚ʨGr=²ƒNl'èÑÚØc¸‘j–wMgÏÛéSßÕ¼’;ØA— ¼2 @(¶>Û‰7·}{sÛ&;ØÕMûN[†Ê³/ÐU];ÆW´,ž‹)Äg>ì^UªéN? i®¤&jæ´„7ÃEÈO½…ê©(wëÖà·XöeÒ”D_<Ë¿ Ÿ{ ÄìÈP“ðjÑzÍç`ºþÀ7…5¾F{ £“¢×å"&ÖT"%¬^­E .²¢°,¿«–í¦¹` üš:8d"†Q—6ø—õÇ¯1Ýüaº`[y·÷Ý‹xJ’]Á°Ñk$mŠ³zY3Æ[»YB
+V)Î$÷;V¿æ<øóPXÃ%]ÿuèW-ŠdP"m
+MŠù•A$ä¾ç!˜Ðv\É1” BuÁ ("‚˜ÂþrÙ‚sÜýçá(új7Š }¯ŒŠ0FŠJWöAÄþIÏ× <8(¤Ïý—šÕ?q–\ÓþÏ"]à‘†ÝËâfÈv”¨‘д›•þgbk"endstream
endobj
-1585 0 obj <<
+1602 0 obj <<
/Type /Page
-/Contents 1586 0 R
-/Resources 1584 0 R
+/Contents 1603 0 R
+/Resources 1601 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1560 0 R
-/Annots [ 1588 0 R ]
+/Parent 1609 0 R
+/Annots [ 1605 0 R ]
>> endobj
-1588 0 obj <<
+1605 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [333.4761 480.8577 413.3061 492.9174]
+/Rect [333.4761 409.1267 413.3061 421.1864]
/Subtype /Link
/A << /S /GoTo /D (clients-per-query) >>
>> endobj
-1587 0 obj <<
-/D [1585 0 R /XYZ 85.0394 794.5015 null]
+1604 0 obj <<
+/D [1602 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-550 0 obj <<
-/D [1585 0 R /XYZ 85.0394 244.5016 null]
+554 0 obj <<
+/D [1602 0 R /XYZ 85.0394 172.7706 null]
>> endobj
-1589 0 obj <<
-/D [1585 0 R /XYZ 85.0394 219.381 null]
+1606 0 obj <<
+/D [1602 0 R /XYZ 85.0394 147.65 null]
>> endobj
-1590 0 obj <<
-/D [1585 0 R /XYZ 85.0394 219.381 null]
+1607 0 obj <<
+/D [1602 0 R /XYZ 85.0394 147.65 null]
>> endobj
-1591 0 obj <<
-/D [1585 0 R /XYZ 85.0394 207.4258 null]
+1608 0 obj <<
+/D [1602 0 R /XYZ 85.0394 135.6948 null]
>> endobj
-1584 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >>
+1601 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1595 0 obj <<
-/Length 3080
-/Filter /FlateDecode
->>
-stream
-xÚÍ[YoãF~÷¯Ð£„:}ØÅY{ÆR‚ì&yàHô˜‰tDÊÎüûT±y´lJ”Ö
- À"›ÝŪ¯ëìn²…ÿl 4ÑŽ»q’(ÊÔ`¶<£ƒÏðìû3Võ×Æa¯ï¦gß^ 3pÄi®Óû€–%ÔZ6˜Îj"É(Ðáw×7n4æŠ'Ó‘‘Ãwøgz=™^ŸOFcç,žÿç݇éå弄¾¥~~{suýýOwÛß|wyuywys~9ú}úÃÙå´ ’QÜÿqöëït0Y8£D8«ÏpC sŽ–gR ¢¤uËâlrö±!<-‡v&)#Œ+1 K¤Rvûký+(¼¶ºdŒ8¥^¾ų# þÀD€HT*ÓLgÁD0¦ˆ´f`”#ZpQNÄ/÷«Éz6‹óá"À% ¼»þ/Kci±ŠÒü>^ù»ÕˆÙaüÇ:΋ܷäH1žÇsòs`ŽH扖շ‰/¤% €¨:Q) uTõ * ÑÆ°Ñ«(YÎ{ ·Ë€ÉcaÙªpŸMàCÍ ›øÿFÕŒ0íˆ0
-— ÑþzÄV|¥†â‘ö¸SiÑÜèßI6û²_¼¿
-":ÀGÙ0Iýoö§IúoÚ
-€ÉI&_ªíÞ¨ê#¢p|¸ ƒîÁÕâ¬ö¡ýç²°ŒïŠ"^>î¨.n&“ËsÚS´HæA"y";ô,žx%)4‡Ú[ö„|¡5¡‚± o¿¼ ÃíG>Z !‡JŠîê[1jCÙSö€Qj”ÛÀð&þ|ŒFº M•“b{Z–èO±oMR,)ƒn€ö¸+ãí‚@¸·áõ·ª1×DAu¾{PÓJoÌÀ~>v—÷zÔ–·£ùjˆr‡­¬ÔC¶AÈ™gÉû<ôâŒúPõqõµÜï™NÓtÚ²9¦”ΰ
-—fñY˜œ#šJ³ z}AMÓÔ+ª.×ÜŸâ4©¢4<W¿ófwy: ªÞ®ŒðN­
-btüWš1´u¥Ôàõpª%«!«·‘Wå¡0vÓáLÏ»Ù6PvЇŽ»Ù6„«:†Cg}U½ÕŸÒäÏ.ª )Ú†P`?Hàäð"[FIꉗxwå1¶‹WÏ娎ºH@¢ldð¦jwÙ¿ 7w˼^y2ýM[7 Èóµ/
-çÆXÔp™Í׋2ëÁ‡ë²öæJ×A ï³Å"{ö[ÝØ^.Q”¼²pŠþT5yá¿:¤†É¶Æmúß—dðK-k7úïîÔ•ã!ßãUÌÏ=בç6 ®ò&+üóh±ð[c.G·á ú<EÉ¢–×…pOM‹Ž]ûr%ÜS¤Á«+[ÿguöòÏYüœ
-ÞE‡iÖœáHªå´j"Úõ$Üu¯WÚšoï 8a»ë¤á¾“'*y3¸»¾Ë¤ƒÞeÌ}¿m¿‹•‚oøU˦uW­ PáË9ú*Ú¢Â`ÞSõ
-Xÿ 2Äb™endstream
+1613 0 obj <<
+/Length 2828
+/Filter /FlateDecode
+>>
+stream
+xÚÍ›YsâH€ßý+x„Ø¥¶îãÑcC¯'fìi`':vfhÛŠáFÂÞþ÷›©ÒQØÁ@GÑÖQ•Êú*+’`
+ÿXGi¢wã$Q”©ÎlyE;_àÞ‡+V´é—úa«Ÿ&Wÿ
+ÓqÄi®;“Ç@–%ÔZÖ™Ìÿèj"I$ÐîOw÷·®×çŠvÇ“ž‘Ýküor7žÜÝŒ{}ç,ïÞüûú·É`ä[é £¿Rt¿y¸Þ}øϨðpï/ÃÁhp3èý5ùùj0©’QÚ»úã/Ú™ÃX¾¢D8«:¯pB sŽw–WR ¢¤å•ÅÕøêc%0¸›wm‚&)#Œ+Ñé K¤Rv÷cý#(<¶8dŒ8¥Þ>µÏ¨# þƒ‰€!Q©L5œÁ˜"ÒšŽQŽhÁE>ã‡ë‡Mö"´A{Àb”4ðlx÷4òÓôpí¾m¢u¥þ$’Œ¼E ºÉ>³Öì´Ñ
+i‰
+`Dô`Ò)$êQºZ¼”S1ΦYœfñ¬˜ˆ›Õ&É¢uúv&4#FÝQÖå¸9(—‚HÍ£ÖØ©Ô‚žq”#ê+y¦0A]å¢ÚBÕ¨,ƒè"‹lôûòójуÉp<¯lA³¸.¸äÝÛ(­ãç,^%ïj"
+ëÄAj>û´á 7ª…ú!„´"Úî²¹ŠX4×Ö§›!çþŽ¡\)­»ãáëücƒ»`hMÔÉwÁ¿=e¯Ê!;'B(Z 7¼!ø;Á„ ê£êãÊ]°J8j%(
+ëÓNpuÏ«$Ъ$Õ¦;c„>LyixiÅ/ ѪæYkzÁ8!îX¦m Oî˜
+¹ÍSÇSŸÊ3Põ‚—83ÄjfZ€rF$„òœÍý§Û‡_¯ïî!b©º#8oZw:‚` Û›$…$“jÕBréD‰#܇ü}ØSª{}÷ ¦²²;Ú‘Ÿ¾A‰½¡ôÆQì}Ò@ÙËE
+  k ÝÒ¢„ñ¡{ø0úu
+^0E…¯yTKô†‚@éì£÷¯qºœf³'0J§ vßnžßu¯“Bx¨ïS•Êfª[¨J¨Ø™ñÅõ¤Ç`…¯7ÉlšEóvž“žCf¶[ö8‘«×øÂ;DÂŒj ìRb4÷ý—é2êõ E÷™·’õ=Ý<ZD_¦XxÇ2Ðò‚YrN8§m+b©vEÞž¡ ÌaŽaÙPG~¬½¦‡—ÕÅäs´~\­—{QJ^0JF ת-1A,$Ð5—ëÏ«uvÃ
+Úû”Ë}¾)÷EWeZeS8[%™þ‹=|½æg õ,Feýe]|…‘ÐÙµTDø®Þ:­k¾ãÕìëañ~DtÀGY7NüßÕs”ÄÉ<©s
+ÛYÄË8ËŸ?/ÿþI)_TÎÑoKBr¹Û¾Â™;Í~äúšC--[ŠКPÁXm_,úâe´ÚdGyÂÌ÷ÙÇ-ÐèrýžP”HëZBˆP’P£|ù°ØDÃò@ÜFÈîxü==jO÷~\Øê|^¬•òåÊ-ýdœ¼¬¾î -¡òŒXX¨¨ÛÊ!9aœš7ˆõшõyÊ_ne.¸&ʸ¤i¥ßñaáåPãÝû³ÆZ+|Á†Ë$TÞ¢¥°ÌΨ|k¸cÕgÄh|Á\)'ZÛ–ÒjOÂËLã÷¼´œ.®³,Z>ªnïÇãÁ§ö2]Äó ˜z!{A*^î²çŽBõ-Z‚>$wDPʶ@>|=áî>*†¡vçbÈq¸Öé{ˆÝ !%²µ0´œ)ÝÃûèË1t[M‘•âõ$/Ò_"5N°¨ ší~SÞ:ÁàNãõCͲ++[Ü,W–H!õÖ æc÷Ùq›G t;› †(wÜÛ’²Ë.„Lp–¬ÍHM¤q>T}\ÏßøL&Ir@uY}¨”Ì°€:,›~Î )¬Ý_Cúb}“Ì‹P\GP.¤þ÷¤G=aàÁ¸ÿ—ÛÓ(åÑK)^ד&‹L!zmÃr‰_ʈBÙæ)XÁPZû&és4‹±Dµ „w³§”¿ëz ržW¤xÿq
+¢ßû%>F8D¢m|, ž›âw–åär’Ùb“B¾TI}2o2@C´¤l÷
+”ÖLÌÁ²æôXJì‡"›ü 6p\5Ûe€
+Ú1Œ>úß»Ñ/ãÅ"N£D,ÜÏTv‡¸9‹÷ªÀäÑTšmèéô+Zš¦ÞPu¾ëþ%q­àÂkñwaÀL¢&O'aBµÑ»ž £Ðêtc,%öC‘ ƈ5±Õªf¨!mtuªn'ã ?ƒ§¿q¥ÝÉSqa1M3Ï•i…ÙÛŽøQ’¿iVtÓ§Õf1ÇcéåÁ5¿ÆŸ‹TGEƒiÚÈW^‡&¾_o«3¹‚w;ßBb?ÙÄÖ¬òúÉy(ùGÓB†\ºÊ(!–@Wð„1în ’e4M
+ÿŠ²À7ùW(*ÿ
+Ügp-øÈÓ”þ¯oûW¼YùW¼ yÙtá¯û7ø­Iñ? ?o2Ò÷sÁ Âf RNJì¾Ý˜§¢Ø$¾Ÿ n Õ±ÕSwEtPviJÛžcWÖ'Ö,u!tø¯Îÿù<gà $ÔD}H”àûrÀ¡ÎrTæ?P°Öï[¾mE;­;e‡þ¬·þ¡3`Öo'ÄÖ|ç¿„ø¾ dy·ãø»IĤ¸–ÊfòÿªË’óendstream
endobj
-1594 0 obj <<
+1612 0 obj <<
/Type /Page
-/Contents 1595 0 R
-/Resources 1593 0 R
+/Contents 1613 0 R
+/Resources 1611 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1560 0 R
->> endobj
-1596 0 obj <<
-/D [1594 0 R /XYZ 56.6929 794.5015 null]
+/Parent 1609 0 R
>> endobj
-554 0 obj <<
-/D [1594 0 R /XYZ 56.6929 698.798 null]
->> endobj
-1597 0 obj <<
-/D [1594 0 R /XYZ 56.6929 673.6774 null]
->> endobj
-1598 0 obj <<
-/D [1594 0 R /XYZ 56.6929 673.6774 null]
->> endobj
-1599 0 obj <<
-/D [1594 0 R /XYZ 56.6929 661.7222 null]
+1614 0 obj <<
+/D [1612 0 R /XYZ 56.6929 794.5015 null]
>> endobj
558 0 obj <<
-/D [1594 0 R /XYZ 56.6929 173.6899 null]
+/D [1612 0 R /XYZ 56.6929 627.067 null]
>> endobj
-1600 0 obj <<
-/D [1594 0 R /XYZ 56.6929 148.5693 null]
+1615 0 obj <<
+/D [1612 0 R /XYZ 56.6929 601.9463 null]
>> endobj
-1601 0 obj <<
-/D [1594 0 R /XYZ 56.6929 92.1409 null]
+1616 0 obj <<
+/D [1612 0 R /XYZ 56.6929 601.9463 null]
>> endobj
-1602 0 obj <<
-/D [1594 0 R /XYZ 56.6929 80.1857 null]
+1617 0 obj <<
+/D [1612 0 R /XYZ 56.6929 589.9912 null]
>> endobj
-1593 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F11 1384 0 R >>
+1611 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1605 0 obj <<
-/Length 2016
+1620 0 obj <<
+/Length 2375
/Filter /FlateDecode
>>
stream
-xÚÍZ[oÛ¸~÷¯Ð£ ±¼_€ÅÚ4ÙÍÛKâv±gYm„ãH^KnпC‘’)[¶šÆ1Š
--K´Yψžf
-ív*x¹Å‘SFp©2˜°xICÀÇœ^˲ʞ¶À¼©²8b”`µ§ÚJ^`[•J Ã%3Š2H0ªÎi”7y±øŸ·Æ±>oŸwÀ¢ñyÛè|þ É]üÈ&“༛1“I…„RgÝý/Ê¢x¦ÉR`‘¥õ¬¨ãG¶D~Ì„³šHRÐÜ™­6j± o—²ð˪6½¼ºo’71˜¼´Y ŒSÙŒ ¨_„xËvÄa›‰ˆÂtÌfðÞvÖ„è5èzU‡¯ Æ_ŒM“†Iãj¶;/Òò¡k¥Á]ÛqøgvwÞ¸›ù$ð&‹š‘©ËÓ¡Ýö»<0—Hµ9|hr&èΙˆàá߸õüþöÃÀš)·u_«ž¤X 1ÒÀ‡'_1ÅQ(û ´Yر@ åy|QP £1 DX!‰<?¨G}Ýá
-÷¼¾øíƒÏnÛ©ºæl(Éç#g0¡íOD·Çößw ÿ¼c|" b
-°S…°êßìÝ#0,‘¦FE17 aA¶^ÐCe{ÉÁô1æœÀ^˜$`kÆC¥ñ°«ßå˼ööyÌk¿ßIºÌÌ¢g/Êô<E#Ah»Áj“ã"X5´‰ÚtK&aáAºÈ›¿••Ð|¡†ÙUužÚ`LI +÷µ¾O<Ýcæ<ÅQ%_ w™ƒý˜CSÅ6l†M¶¤t»Ë.é‰ZV¥Ÿêfµ*ׇJÀrœ3ú¡Æ õ
-¨îËÇ¢“àµÐ$D‘Ý  :2Ý÷»ä®üÒ—ZØÀaXéTÖxeØ
-`ô¦ö›Z·­ÜékâIeÇÀ_­²ÄÊ‹î°¶Ú™ÐîíTk1€7Œ_Az¢8¤:ìU¢¯7ÿ¹µÿwe8àâ¨ðŽj@zhJ"a–Té¾ø¹Ó
-í¨¤öT‰Aåöf¤'ö´ª¼ñ'<ߦKj`Ûfîò°.CªÃºì¨]¾_ÕÕ>0JÂ&÷ÇÄvTr{Ú´
+xÚÍZmoÛ8þž_áP³|ÁhÝd× l’&.p‡Ýý ÈJ#œcy-;Ùþû¾É”-ÛIëäb‘Î3Ï ‡‘†?ÒÓafxOŽ&¢—?œàÞWx÷Ó 4ƒH4H©>ŽOÞŸ3Õ3ÈH*{㻄—FXkÒO~ëþp5>»>Pû„Äý£‹O¾ÇøŸáåÅùè§/×NïG—¾ûúìüìúìbxv:0FSÏaìÍØ
+#oÆ£áÍéã_NÎÆÍÒEÌììÿ<ùíÜ›ÀZ9Áˆ-zOÐÀˆC{'\0$8c±gzrsò¹a˜¼uC»”&˜FBSÕ¡5Jº´& ’Œ2§5»P‚øé€` +¬òÿK¿ÚÑûË°ìe¶,ëe™×A…Õj¶,µ]<ˆ`‰ÜPŽ 'Ü1ìˆ ììC°³í<²s­lqJt¿ðIñ;ÆtVL|s^,‹„ïòÛ¼¨ßÁÌ0í?Ý—ù}›Ÿcª
+ ‘JZõÙ9~ùtÅ;VB „D¢ß±À@ø~tõÈᙼëà+€-3bÍV¾„­ÜÅvÀ‰@Œ)Ý‚ŒÔ »§­bJ%üpÿ´¢ÀG®ò%\峸~™•uq¤HªÂÒ ¨æýOÕCVÎ<ó5¬ŸÍ&R AJËÀáüÓS¶óo â )¥x"ɨöªyá æžW˺œ¾±¼wøé ÃHܘÀœºqѨ&«ia' aƒQÙÍì éx8Š»j:­žÊÙ×ПÝN:Iº$¢ÀÓÁ‡ÃdÿÙ±j0×Qoãÿ\u°¡qÉY úW‡RF Ø(Ç{ËÜÿÔÅÌéfùÙ¦KµyQ-ýûl:õ/×ÎìFGgv4Y9«†8AÒB²6¬ïª…2#ND_ÿ‡.þÊ‹ù²¬f!*%²pV-Eᱜ…±÷áݤ¨óEé†úcŠémsÂâp#5CRÒg…sÆ5RXm„óï'‚×:Ú9?¯ðG´Y šE ¤"V&Yo±&…8fLô¤(Êôo·FrCûŸEn¨ŽÃ^£@e½TÈMܪˆÁfÈaÈìÝ\·XÆ»uÁÁ©l0Šºhûd£ É CÄÙëšê{\s§ƒ_Btêp_È ”¡&ݬãIâxÏ*Ï‹º¾[M§ßNaãéƒçrÌúãû²öÁcýÐ2°˜9dž‡l>Ÿ–ç±¸í©¹seïZÕÚÅ:¶Š„¤ä9Qš3Wä£ÌNX%öú1 ¼.¬€Bk)ÁŠÄ©¦o «sÈ¡e‰Va_€¨M¿ºƒ_‚ÎÜ~f;ÃŽjá¥u€—%jàe‰ÊÀÁÁ˾ý»Â+±Û±àõÜR0ÂÁ HA”yKx §U]¼ lys;d²Ç(Éjµ•¼‚Q„ÕÚãÅ£`fq«ÞÒ(ËÙä;|ÞÇú¼ý½!‡ÅkŸße²TÇ59ªÉ´F˜²˜€Ó†ÄêM7ÿa5›ý År`QäËm­¿³›)‰°‡26¡ ’‚ò·6ÚAƒ ƒYšóKQÛ#aYßǃKGê¶Ód‰2Že3&ì€/ÙãˆÝ6ãpæÄøÐ~%¤BÒ¨7M‡>äö4ù®&w®&ëgŽ‰ó4Û]Îòê¡iåÁ}Ûsøsv÷θ™…p—C’¾ÏÒ¡û}–N˜O£bÆ/\ÆýÝ#ùú¦ªûr†JÕÓ}ýB4ðá‡S¯QÁYûþÄæ÷€:AË!ðuA9œ ùÁ@Ä<õö >èQƒSÉT‚ÓÚvè&](rê6]®¨kWÓ®|úoníCŠ[Û¶¸u¿;pkï´Ù[À6–r/n)lä¬ÑÒÑq›
+1Iš<Þµ:k 7¦Ð»ššþXÇÛWˆ¬œs$„9PE¶doÐë"|)@)ö
+S]ÍçÕÂùÇN¡ Ç9£/j‚Р€ú¾zš5‚bRql£œÝVñ¦ÔêĆ {·ús‘VĶÊc±lv[­Bu­A‹xi°.ãá`W;«aø|^d‹­J[½1¡ÍÏ$0„lMz#¢
endobj
-1604 0 obj <<
+1619 0 obj <<
/Type /Page
-/Contents 1605 0 R
-/Resources 1603 0 R
+/Contents 1620 0 R
+/Resources 1618 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1611 0 R
+/Parent 1609 0 R
>> endobj
-1606 0 obj <<
-/D [1604 0 R /XYZ 85.0394 794.5015 null]
+1621 0 obj <<
+/D [1619 0 R /XYZ 85.0394 794.5015 null]
>> endobj
562 0 obj <<
-/D [1604 0 R /XYZ 85.0394 477.8665 null]
+/D [1619 0 R /XYZ 85.0394 769.5949 null]
+>> endobj
+1622 0 obj <<
+/D [1619 0 R /XYZ 85.0394 752.4444 null]
>> endobj
-1610 0 obj <<
-/D [1604 0 R /XYZ 85.0394 450.2752 null]
+1623 0 obj <<
+/D [1619 0 R /XYZ 85.0394 696.016 null]
>> endobj
-1603 0 obj <<
-/Font << /F37 799 0 R /F39 895 0 R /F11 1384 0 R /F21 710 0 R /F23 734 0 R /F65 1609 0 R >>
+1624 0 obj <<
+/D [1619 0 R /XYZ 85.0394 684.0608 null]
+>> endobj
+566 0 obj <<
+/D [1619 0 R /XYZ 85.0394 401.8966 null]
+>> endobj
+1628 0 obj <<
+/D [1619 0 R /XYZ 85.0394 374.3052 null]
+>> endobj
+1618 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F11 1400 0 R /F39 900 0 R /F67 1627 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1614 0 obj <<
+1631 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1613 0 obj <<
+1630 0 obj <<
/Type /Page
-/Contents 1614 0 R
-/Resources 1612 0 R
+/Contents 1631 0 R
+/Resources 1629 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1611 0 R
+/Parent 1609 0 R
>> endobj
-1615 0 obj <<
-/D [1613 0 R /XYZ 56.6929 794.5015 null]
+1632 0 obj <<
+/D [1630 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1612 0 obj <<
+1629 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1618 0 obj <<
+1635 0 obj <<
/Length 1321
/Filter /FlateDecode
>>
@@ -7106,141 +7201,147 @@ xÚ•WKÛ6¾ï¯0öä"ZEJêž’MÓnEãžšh™¶…•EUlÜ"ÿ½)[¶àÔ0 ‡Ão†ó"Eg¡ùÑYÊIȲx–d1á!å
[#y¿ÒÛ¾­T×Þ#o: ^‹²DjUêüÉß?<ÑŒ¦8ik™O^]Þ+©¡¦j”uæúáÓ·+àæ\c®÷{]ìyZ¿­¨üv­763­6Œ$[„-Sæþ,þ¼8ý×
ljiÐa2>DHìo‘>¢(=›GçëpÌÅ^Ä´obS~¢:’ÈÔŠeÑè—Š™âÑ] c‹ñß%# ãó"7Mß»Øä~
ÿxK<duûÚù&¿2D¢ÌÒf:£lxÝÞFÞAÀ+ì hòŒÆXÀnECo°Ñïq6ˆ ÷!LúªÄ;v¬ ÒX;éÖVJU¨Êß…yªÑy -Øë¢ &Ëne
-ÝÿîÇåðqé?á•h>@§>?½Hp”ÁoÏÑ#4¦;e‰;×6|É^ªûaáŸendstream
+ÝÿîÇåðqé?á•h>@§>?½Hp”ÁoÏÑ#4¦;e‰?×6|É^ªûaZá¡endstream
endobj
-1617 0 obj <<
+1634 0 obj <<
/Type /Page
-/Contents 1618 0 R
-/Resources 1616 0 R
+/Contents 1635 0 R
+/Resources 1633 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1611 0 R
+/Parent 1609 0 R
>> endobj
-1619 0 obj <<
-/D [1617 0 R /XYZ 85.0394 794.5015 null]
+1636 0 obj <<
+/D [1634 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-566 0 obj <<
-/D [1617 0 R /XYZ 85.0394 769.5949 null]
+570 0 obj <<
+/D [1634 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1620 0 obj <<
-/D [1617 0 R /XYZ 85.0394 573.0962 null]
+1637 0 obj <<
+/D [1634 0 R /XYZ 85.0394 573.0962 null]
>> endobj
-570 0 obj <<
-/D [1617 0 R /XYZ 85.0394 573.0962 null]
+574 0 obj <<
+/D [1634 0 R /XYZ 85.0394 573.0962 null]
>> endobj
-1621 0 obj <<
-/D [1617 0 R /XYZ 85.0394 542.127 null]
+1638 0 obj <<
+/D [1634 0 R /XYZ 85.0394 542.127 null]
>> endobj
-1616 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R >>
+1633 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1624 0 obj <<
-/Length 3449
+1641 0 obj <<
+/Length 3450
/Filter /FlateDecode
>>
stream
-xÚ¥ZmoÛFþî_¡o'Å}á[q8ÀMœÖm‘ôwEÛIK¼P¤BRvÕ_3;³+R¢ë
-_¡˜¾\ýú»?ËA¨?\ùžJâ`ö ¾'’DÎvW:P^ •²”êêÓÕ¿ÃÁ¬yuR; „rB= á õ‰*˜B9¼kZºÜ"žôTÖM»Kû²©‰`·Í3 ú†~¿rûæ§n<µ7›¾Èz"›ïÖíSÑ¢o,ÙôÛ‚µ7T²’‹âÄjïöáÓP^ÌÙjFÕ‘'¾àµiþTvM{$öiÿ ½!Äà…
-A&QÍ`&"ˆóê?ÏõjOkÍ"-<éˆôA³ŸgvôãI7ö…Åð £=Üÿ‚/îþØï¿Y.á_/=tYÑö^Ón`¼ÜÖK&-íí–·?-Àˆý9Qâù¾öòº;?¾V`d‘/GçÍ@¥—Äq<mž Çñ• ‚ ƒX“ñóæò„ðüäBÂgïV]î:Rë%7Üö_l2b&´§48Ž±
-¨%óN'ÜFŠÈCí'd[rHðÈ©3«Ð ’È..꧒–×»¢îißüÀ?te½áƒY_•C© ?ôbí‚{f‡oÂÿbjßØ“¡ŸðòÇCaØ1‹Í¦ë#¾„J<íK >*¼$(¿tû"+æLJGæL0ˆç¿I©i·‘%FÂÒ‡E?q boaøÖÍžâ!r‡ð8qu±qÅüfî¦í{Iâ2äžÐ—óÕ•¬³´¦ý¶Eµ§Q¹ãXúÄ—ëŽ]_ìh²+²C[öGzZižJ3'²Éϟ’LÁw=8Jde*Ý•;0òuó9D?oËlËòªhT•»²?En3ÈÓ]º±ã¦¶)å‘g”hŠGÖØ{îÊ®È n@WÆäÛºðEm’ÏãO¢Åü±HûƒËaÚ'Ç€ :Øû€„;‹yGÙ ž›GZÁ^s$m/„t]VFȆÚЯóÈá6yZì,ã”Ù¤ü|¨÷mùTVņ,ÃÜn y¸ËfÂ|%D$¢`ó=Ð’`d¾˜LëO†ã¥ jÒÎ Ð×À •ðçÿ¹N¤Ýa³):Ö.]µ&ßG5v62ÞÌ"ƒÖZNaWuŽÁtðQ
-pžU
+xÚ¥ZmoÛFþî_¡o'Å}á[q8ÀMœÖm‘ôwEÛIK¼P¤BRvÕ_3;³+R¢ë
+¨%óN'ÜFŠÈÃÛ!Oȶäà‘S2«Ð ’È..꧒–×»¢îißüÀ?te½aÁ¬¯Ê¡Ö…z±vÁ=3ŠÃ7á1µoìÉÐOxùã¡Î0ì˜ÅfÓõ_ÂJ<íK >*¼$(¿tû"+F&¥## âùoRjÚmd‰‘ð„tÁaÑODì­" úÙS<Dî'Ž!6£˜ß¬ÓÝ´¢}/I\&‚Üúr¾Úâå#ë,­i¿mQíiTî8–>ñáºc×;šìŠìЖý‘žÖGZ±¯ÒÌ)…¬ÅpbùSÒ)ø®¢DV§Ò¹#_7àCôó¶Ì¶<,«ŠFU¹+ûSä6ƒ<Ý¥;nj›RÙyF€¦8qd=ç®ìŠÜàt¥aL¾­Ø_Ô&ù<P-æEÚ\Ó>9L\@`ïî,æe7xni{PŒHÚ
+麬Œ’ µ¡_ç‘Ãmò´ØYÆ)³IùùPïÛò©¬Š Y†9Ý@óp Ö :Ì„ùJˆH
+TÁæ{ %ÁÈ|1™ÖŸ ÇKÔ¤ ¯*áÏÿsH ºÃfSt|»tÔš|¯±³±qÀðd´Ör
+»ªs ¦ƒ‡ŒÈ7")žŒ¤E}ƒ»÷8X
+
+Ì$v Ä\‚µå…Ap–Ð_²bÀSq%ƒ…–I¬*(§QVÂQ] 1àÈX7&Ì¢§ÁSjʉðBaæ­mÊ£²ÎªC^pj. qû-çÕxWqÇn¼%9”IïzþŽóÜžeä8ÈìU“
+ÌË ý¦ùÿ]¶ßSZŠÎíF $ĸcõúê,ìø\ F—ÎÁ1eh5ÖË–;Q-*H—¡¸' mâ©“Òöe¾ EL¹cà…qxäÒ,k5ŽG[rƒ!užÅa£ÅY¶z¨ù˜
+ â'ÂÊ_OFk"—Oø¢1*BWV/ÜJ ƒWñ±‚JÌ]ŸöCÉ릵ø¦èXÀCÀŽƒð,mS
+[(a„y|ݦmi .FÌb"1Î…Çh·ÏD±ž€À(‰çß7ÏÅ eGÅ÷EžõòŮɯ ;UK>cö*è^€ºK´šõt9‚†ÂæUΘ{g>õ¦;÷‚q±)DØŒ»Ì‹§åŸEÛLAåE‰k´M…°LYµà+ÐÎCL
c  lSàa g¹°1øÇŒßq1ûW
-ïq©Ä:U(&B(nàÁ~Óü#¨&¤<´Ô€Éú6ˆzW+ 앲mZo
-K7ÔÐ!>]Ç%“i®
-þ•ó»‹¾®ôüHFPƒqHˆƒ°õìËLx¾NE‹csד ay¿“³· Üh6¸”e¼r6—‚Ø3pâÐJûÇ°M,cºSÓ¤-…6QˆÂ¦ŽoL’½ˆ£Í ˜ lù csïè¬U.ö %53ŠP3<cµoJ~CFëû»¡fBɧ¶¨P@aë‚™G)5öàt}-!©¡OE¨ñê¼|LªÖ=ÓC[t=*ë ^¹7
-xFGϦ …¶ÌÜø« z-ƒ9¡˜`±a‰u>w¢F}ê0¸uh¬ÏþÑÓ€púÖó÷¼sìRP¨ë“KšßvôÑHÅyNq–{{S*3
--û<í ÛþæÎã« ð[ðJ(n8(®„œç–?RÌÇiÆŸºms¨r¯ùUÐ8(»â¦‰ÚZ€«šš©0ã 'ÀŒS˜ñ—óàT0WWÇ©ݳl‰âºFÏ󆟷TM½›æÖiGU¢øžh[J©ùýÏDHóœ0jÇ/QÑ¥ìJ=ß6T6)¤Å¨˜V—‘änØ¿øUé–jêÕ½°õ⤬…^ÖSç@P™^ <Tü×”Ãÿ ºé¶ñ‹ßÀ
-¸aŽä]Ño›œÁ4(Ð8Ý'Mpt(å‹ÓÍꮡ%vb¬ ÜññÔ'W!T.#S`>±3Z?¼EéØBÉ>>ˆÝ±Š´+M!Ð'Økc Bàü¶ê–xÓ»£¦–Åãèðiq|è‚·1ò¥>lL¦ð¢fT¢<)4|E3 ·|¢6‡mL#ÉtLè ƒ±d`¬'觫Ò'^ê¾ `ÇŠv¤ÀÞŠ?KwD€á3•w\„ ¸º‚tó­M‰Ó‘v)Ôcí”ágÔÔ¦0#pZlms
-ä´ïQ·9M®™Ú¹j0°n¨ih†gÖe`n}Cc‡ñ”û¼¢‡w¤)úØ2ÁŠoÃï›fA€»©† —
+ïq©Ä:U(&B(nàÁ~Óü#¨&¤<´Ô€É.*ôm=ô®V&Ø#eÛ´Þ–n"¨¡C|,ºŽK&Ó\â®ÉK\”Ù6$ê
+HKmB9µ­Ýú¶ì©šêN+КNdðUíišH
+$“¡¤+?¸Ã „À`úP^ \‰øp˜˜¯à_9¿»èëJÏdU1‡„8[Ͼ̄çë$Q´h06g=éÀ–÷;9{ÛÀ‰fƒCYÆ‹!gs(ˆ='Ž­D° ÛÄ2¦35½IÚÂQa…(lÚá(ðƤًX0Ú ‚™À–Ï00÷Ž~ÁZEàbRR3£5Ã3VûfÑ©ä7d´~°¿j&”,µE…Ú
+3X ||È<J©±§ëk I }*"@¿Pçåc
+Tå°î™Ú¢ëY¨¬/xåÞ(à=›.rØ2sã¯
+€èµ æ„b‚ņ%Öù܉õ©ÃàÔ¡±þ=ûGO:8Àé[ÏßóαKA¡®O.5j~ÛuÒG#Mç9ÅYîíL©Ì(´<ìó´/lû›;¯6Ào9À+¡¸á ¸rž[þH=0?¦^|ê¶Í¡Êi¼æWáÆá²+^aš‘x[ pUSs#Õf|á˜q
+3þ2`HsuuœjÑ=À–(®kô<oøyKÕØ»iŽivT)Šï‰¶¥”šßÿL„4Ï £vü]Ê®ÔómCe“"LZ|Š‰aåpiî†ý‹…¬J·TS¯î…­''e-ô²ž:2€ÊôZ Pñ_Sÿƒè¦ÛÄ/~
+ ÔX> ŸÂvœMbg¢êÓ€FBe‚¤¦Å¾©Êì8ÝÂ"÷‰ÖiË8Ö§Š/¹Ô‚JK©©?bð]Mó·ÿHè„ó
endobj
-1623 0 obj <<
+1640 0 obj <<
/Type /Page
-/Contents 1624 0 R
-/Resources 1622 0 R
+/Contents 1641 0 R
+/Resources 1639 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1611 0 R
-/Annots [ 1629 0 R ]
+/Parent 1609 0 R
+/Annots [ 1646 0 R ]
>> endobj
-1629 0 obj <<
+1646 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [63.4454 738.9144 452.088 749.0762]
/Subtype/Link/A<</Type/Action/S/URI/URI(ftp://ftp.auscert.org.au/pub/auscert/advisory/AL-1999.004.dns_dos)>>
>> endobj
-1625 0 obj <<
-/D [1623 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-574 0 obj <<
-/D [1623 0 R /XYZ 56.6929 723.0302 null]
->> endobj
-1630 0 obj <<
-/D [1623 0 R /XYZ 56.6929 689.3491 null]
+1642 0 obj <<
+/D [1640 0 R /XYZ 56.6929 794.5015 null]
>> endobj
578 0 obj <<
-/D [1623 0 R /XYZ 56.6929 552.677 null]
+/D [1640 0 R /XYZ 56.6929 723.0302 null]
>> endobj
-1631 0 obj <<
-/D [1623 0 R /XYZ 56.6929 525.9649 null]
+1647 0 obj <<
+/D [1640 0 R /XYZ 56.6929 689.3491 null]
>> endobj
582 0 obj <<
-/D [1623 0 R /XYZ 56.6929 411.5673 null]
+/D [1640 0 R /XYZ 56.6929 552.677 null]
>> endobj
-1632 0 obj <<
-/D [1623 0 R /XYZ 56.6929 383.9327 null]
+1648 0 obj <<
+/D [1640 0 R /XYZ 56.6929 525.9649 null]
>> endobj
586 0 obj <<
-/D [1623 0 R /XYZ 56.6929 225.6356 null]
+/D [1640 0 R /XYZ 56.6929 411.5673 null]
>> endobj
-1316 0 obj <<
-/D [1623 0 R /XYZ 56.6929 193.4614 null]
+1649 0 obj <<
+/D [1640 0 R /XYZ 56.6929 383.9327 null]
>> endobj
-1622 0 obj <<
-/Font << /F37 799 0 R /F69 1628 0 R /F23 734 0 R /F39 895 0 R /F11 1384 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R /F48 950 0 R /F62 1060 0 R /F63 1063 0 R >>
-/XObject << /Im2 1049 0 R >>
+590 0 obj <<
+/D [1640 0 R /XYZ 56.6929 225.6356 null]
+>> endobj
+1333 0 obj <<
+/D [1640 0 R /XYZ 56.6929 193.4614 null]
+>> endobj
+1639 0 obj <<
+/Font << /F37 803 0 R /F71 1645 0 R /F23 738 0 R /F39 900 0 R /F11 1400 0 R /F41 940 0 R /F21 714 0 R /F53 1032 0 R /F48 955 0 R /F62 1065 0 R /F63 1068 0 R >>
+/XObject << /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1635 0 obj <<
+1652 0 obj <<
/Length 533
/Filter /FlateDecode
>>
stream
-xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v
+xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v
endobj
-1634 0 obj <<
+1651 0 obj <<
/Type /Page
-/Contents 1635 0 R
-/Resources 1633 0 R
+/Contents 1652 0 R
+/Resources 1650 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1611 0 R
+/Parent 1654 0 R
>> endobj
-1636 0 obj <<
-/D [1634 0 R /XYZ 85.0394 794.5015 null]
+1653 0 obj <<
+/D [1651 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1633 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R >>
+1650 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1639 0 obj <<
+1657 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1638 0 obj <<
+1656 0 obj <<
/Type /Page
-/Contents 1639 0 R
-/Resources 1637 0 R
+/Contents 1657 0 R
+/Resources 1655 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1611 0 R
+/Parent 1654 0 R
>> endobj
-1640 0 obj <<
-/D [1638 0 R /XYZ 56.6929 794.5015 null]
+1658 0 obj <<
+/D [1656 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1637 0 obj <<
+1655 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1643 0 obj <<
+1661 0 obj <<
/Length 1964
/Filter /FlateDecode
>>
@@ -7253,133 +7354,132 @@ i ·¥Ý3éÀ–yíˆùðŠ&Â8K<æcø¡›‚hïCû™<»úÐŒ­êhüýÔï Æס\@•‰ó÷w= vV
­è×ØÚ:‰óÎÐÃBYn?z·XdÌqâd¾©Üä¤ÚNí:ørðï»QÕaáƒL·CÕMucVìâªV.Wª4 Û8Hü»Uoy)”@»Zìo+B)ˆ×­©ôD9ƒ©;B.ÊõTyåvÂ)Î6™îZds§¡ÁÓÏMí­µ°r=¶öä&vÓž®é^/yr€¡¶¯ÓP;«y Â1{9B€FãŸà{ËוÂM>p\×-ž‘7>å èWˆÌ¨W
¥Ìrcø-Š¼ûãËü
“¤%œ¡i±Iæ² —â~ÚøÑŸ/¯6³Âv¡ámÒ¥ß;»è½‡CÀê/aïoãã<,EQ^Çsór4 ÝÅpµö;[ÃïVÎy7G)JΑOü©5­¿|hW°hpk·IQ„"é5¶ÏÍŽûª‡]Ù)C™‹_Ú‘Âõ%KÄQXDñ¯oʬ±]ªÜïʽe×SX{üâññ|>‡¼+¾,}w¸ÉÀUßÄx³Q³Ô}\Wù¸·ö߶
-ߣ«ª]qöü´Þíâ³äZÄ^d{‘¡Éep …E\æÞ†Ræ·Þæ÷Í{wÿ¢BŒìendstream
+ߣ«ª]qöü´Þíâ³äZÄ^d{‘¡Éep …E\æÞ†R–·Þæ÷Í{wÿ¢šŒîendstream
endobj
-1642 0 obj <<
+1660 0 obj <<
/Type /Page
-/Contents 1643 0 R
-/Resources 1641 0 R
+/Contents 1661 0 R
+/Resources 1659 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1652 0 R
-/Annots [ 1650 0 R 1651 0 R ]
+/Parent 1654 0 R
+/Annots [ 1668 0 R 1669 0 R ]
>> endobj
-1650 0 obj <<
+1668 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [348.3486 128.9523 463.9152 141.0119]
/Subtype/Link/A<</Type/Action/S/URI/URI(mailto:info@isc.org)>>
>> endobj
-1651 0 obj <<
+1669 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [147.3629 116.9971 364.5484 129.0567]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.isc.org/services/support/)>>
>> endobj
-1644 0 obj <<
-/D [1642 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-590 0 obj <<
-/D [1642 0 R /XYZ 85.0394 769.5949 null]
->> endobj
-1645 0 obj <<
-/D [1642 0 R /XYZ 85.0394 576.7004 null]
+1662 0 obj <<
+/D [1660 0 R /XYZ 85.0394 794.5015 null]
>> endobj
594 0 obj <<
-/D [1642 0 R /XYZ 85.0394 576.7004 null]
+/D [1660 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1646 0 obj <<
-/D [1642 0 R /XYZ 85.0394 548.3785 null]
+1663 0 obj <<
+/D [1660 0 R /XYZ 85.0394 576.7004 null]
>> endobj
598 0 obj <<
-/D [1642 0 R /XYZ 85.0394 548.3785 null]
+/D [1660 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-1647 0 obj <<
-/D [1642 0 R /XYZ 85.0394 518.5228 null]
+1664 0 obj <<
+/D [1660 0 R /XYZ 85.0394 548.3785 null]
>> endobj
602 0 obj <<
-/D [1642 0 R /XYZ 85.0394 460.6968 null]
+/D [1660 0 R /XYZ 85.0394 548.3785 null]
>> endobj
-1648 0 obj <<
-/D [1642 0 R /XYZ 85.0394 425.0333 null]
+1665 0 obj <<
+/D [1660 0 R /XYZ 85.0394 518.5228 null]
>> endobj
606 0 obj <<
-/D [1642 0 R /XYZ 85.0394 260.2468 null]
+/D [1660 0 R /XYZ 85.0394 460.6968 null]
>> endobj
-1649 0 obj <<
-/D [1642 0 R /XYZ 85.0394 224.698 null]
+1666 0 obj <<
+/D [1660 0 R /XYZ 85.0394 425.0333 null]
>> endobj
-1641 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F11 1384 0 R /F41 935 0 R >>
+610 0 obj <<
+/D [1660 0 R /XYZ 85.0394 260.2468 null]
+>> endobj
+1667 0 obj <<
+/D [1660 0 R /XYZ 85.0394 224.698 null]
+>> endobj
+1659 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F11 1400 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1655 0 obj <<
+1672 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1654 0 obj <<
+1671 0 obj <<
/Type /Page
-/Contents 1655 0 R
-/Resources 1653 0 R
+/Contents 1672 0 R
+/Resources 1670 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1652 0 R
+/Parent 1654 0 R
>> endobj
-1656 0 obj <<
-/D [1654 0 R /XYZ 56.6929 794.5015 null]
+1673 0 obj <<
+/D [1671 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1653 0 obj <<
+1670 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1659 0 obj <<
-/Length 2543
+1676 0 obj <<
+/Length 2544
/Filter /FlateDecode
>>
stream
-xÚuYYsÛ8~ϯð[誑ÂûØ7[ÎádìrYÎNÕnö"! k’`ÒŠæ×O7ºyØéTJ@£hôñuƒö.\øç]¤ÑÚ ²ð"ÉÂuäzÑE^½s/°öùÇ<a¬£0`²°ºŠ‚t¥~r±šorýôîÃ'ß»ðÝuûÑÅÓ~<+N’µ¥OÅ«¦‘u¡~]®üÈu®.ÿ÷ô•ÄÂu’&Š¹pD²ã$žKäÒŒÌ^¸ÂØgæ8Z‡A’óÚ»\y® [çϵ>•²8T²îf²Þ:‹¢A6Ö^yƒì$Mú]·JîiøE™N·gšh&vGIƒ›û- D]°èíý \dë,öc>Ӈ˹!ë[vGÝŽ d¼ ~ø~gx©óÃuý\‰)´¶»ôyPu­êQ¬6sñ] UÓø^TLÝžM'+Éó¾mñ
-\Ó±8 ØãràÔòD3h Ä“0D,¤É[µ³:Ýê dÐ9 QÔ€EÒÔ'{)Áúrø®óɪ¢«q—µÑ$”ÄêY_ÝÔ'ÿ=>\f¾sUË"' Á_‘k/ƒ“†®
-¦6pkK­é·ç÷'‘s[w²…-@Ø£åÌ­ßp,XBšÎÞ'h7ü•¿Ù*Œpv
-÷Ãa…|‘¥nl Ø-H±ÈZyá6µ¨€÷ƒ(
-RÜŠ1ÏuL~”6`l ¿‚~ZѨ¢<ÓCƒÚ̓
-’ r”OœBç=Á 1j"«¢ºÑpQɧUäzý"GöÄÙ G,ØÝfS6ä ÐBdz˜€z²Ó„Q™DÏ B0q
-ã”U#7Cã@Q²€.ÿ¾ô
-ÝD‘øñðñ^=:\è±æí
-®o¬ƒñ+ñ'E\2}8Ç’;i %Ò‡ï&ª°Wõ\~jÀaÛÍ{³˜¢GË!zeoA_^†NmÞxš^Xð”Ð;’ù‚Ïr{z8Ø'"Hóȃ…×UØNÑô
+xÚuY[sÛ¸~ï¯È[•™µ««e·Äé%í&“‰Ó³3çô<ÐmóDUQŠëýõ  ¤dµÓé˜Äå¨>ü .ÖÉÒ²ø"ÍâeâÉE^½ó/°öù]À<q-“8Š`2³ºH¢õ2Y‡éÅbºÉõÓ»ŸÂà"ô—«U˜\<퇳Viº “õÅSñ_ïªid]¨_—‹0ñ½«Ëÿ=}%±x™®Ó
+#œ‚Ľ;¬/²Ô »)–X+Ïܦð~EAŠC1øžÉÒŒ­‘áWÐO+U”gš€B`hC»  ŸUM”Ä
+FXЭ‚dƒ\#åS¯ÐyOpBŒšÈª†¨n4\Tòi¹^¿È=õvÂÀ3v·Ù”¹<ƒZˆLPO–`š8I9³€øQ &ŽÀ6 CÆg”ñf±Ñu.{4ÐÈ,0ø$rUªNIƒb¼Ã°:Ý>±‹átûÕé°Ûª)å$
+£ÄÁ¶‘¹µ/!. N…Ùzê°Wâ.pl „ÓÁº°â…!R߸“OG•y—²œ ™®Õ+Å cøˆP¾·ëU é6É–+?£ÂôD˜•ZŒnMG“Ñu Æ »Æ51ŒŒl_àêiìYpɼÔ$LK­¹¿JH\ç d`
+¼
+–a“p¯Gkଯ ëÃá5³îǪÿêÄ- ÜȽ¬Í|µ/^ÄwxÒH‚
+D¤<ÐÎÿ—yÇ‘sU@E…ÎqÌ*Š‘×8P”Ì Ë¿/@f4áRÊ}^º¦ÖÒRº#›Úv°/×ˈÖFtÅŒ‚þ[åSr Òéú@Øèªé)ŽL½"Ÿûæ¢@ù<ñpJµÙ>~æÜpËLtGY­Fgá±[A —(-̃ÅÙ¶Ä ˜Þ°)Ëx™AaíF¼¨‚ÕáPâ¥V)§8·º>@ÌÔ4ûôÜÄP‰BÍÞ(dv P&máªëæßFD3zœ`·“¢ÂEàÛ=ÃBj{ †rh®ÔÐq½ ‘®³«zß&Å(uùJ¸8…B×ò5ø?Š²9Òp#ªf'Ë’•ú&_æ ùM_—¢±J6iðU£ª#E}ïãÏ^5X*‰eÃÏÖJ©>KF\¢P¯SSŒo&Œ>Ï! ·LÝ–è@±¸ˆ¤ægH@Ä9³ZI( Ž:ž()6Sq
+UŸiQc¢õFêƆEiX*×5ÔÏ]OÕ-ãÖXXE p³Í‚¥¢o¹‡šMÔºõÁùˆ4òs®øbðج–×
endobj
-1658 0 obj <<
+1675 0 obj <<
/Type /Page
-/Contents 1659 0 R
-/Resources 1657 0 R
+/Contents 1676 0 R
+/Resources 1674 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1652 0 R
+/Parent 1654 0 R
>> endobj
-1660 0 obj <<
-/D [1658 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-610 0 obj <<
-/D [1658 0 R /XYZ 85.0394 769.5949 null]
->> endobj
-1661 0 obj <<
-/D [1658 0 R /XYZ 85.0394 573.5449 null]
+1677 0 obj <<
+/D [1675 0 R /XYZ 85.0394 794.5015 null]
>> endobj
614 0 obj <<
-/D [1658 0 R /XYZ 85.0394 573.5449 null]
+/D [1675 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1662 0 obj <<
-/D [1658 0 R /XYZ 85.0394 539.0037 null]
+1678 0 obj <<
+/D [1675 0 R /XYZ 85.0394 573.5449 null]
>> endobj
618 0 obj <<
-/D [1658 0 R /XYZ 85.0394 539.0037 null]
+/D [1675 0 R /XYZ 85.0394 573.5449 null]
>> endobj
-1663 0 obj <<
-/D [1658 0 R /XYZ 85.0394 510.2426 null]
+1679 0 obj <<
+/D [1675 0 R /XYZ 85.0394 539.0037 null]
>> endobj
-1657 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R >>
+622 0 obj <<
+/D [1675 0 R /XYZ 85.0394 539.0037 null]
+>> endobj
+1680 0 obj <<
+/D [1675 0 R /XYZ 85.0394 510.2426 null]
+>> endobj
+1674 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1666 0 obj <<
+1683 0 obj <<
/Length 2810
/Filter /FlateDecode
>>
@@ -7391,66 +7491,66 @@ eéÄ&þx~Øk
çÑD”’-
kûèõ¡Þa€<Ž@«£¿ïqäiìØ@:ļΖ"´ZtÀɶ¡?|F
½5ºÂ5æaŸ6|šq˜ÐëA¤S‘ônhaЫg#ˆV˜ilÚqø…Ë·­(„á´ª[Óà2àdƒûÚ“9òŸóv¼LZ•Ï–\'NrÓQT&1À;Þ3Y¶÷j†+~Sm vRM“—ç V¸_hvK%OÆ1e¼»YÞrîMlk‘ă,ómúOm?‹çŸ¸ÙÓ"Ñú„ôÂ@•ÒâwÖÞÊz…±rp3 ûöû\p©z»|à;Ù^Mdûu»¿º¼|yyA8….•.‹ja¬t‰­¾qý`èúÂOàZ…¶þ
-Ä“N"\‹ä´_ùaEŒóŠÈ¶Å>þtâ¾%AlZv&>}ë å/3;ú±ÿîÑíX ·˜ïþðàSÊ#u UßwÈk/ùó‘ÿ8ŽŽø;úÓaò4RÆ)5äé/SyW01bŒ‰®ôÒ=<žÚ ¢¡'ñf ßµ8…¶ˆê½W¶-±O,Ý"x‹õbšé‰oi©í'ç´°OªC—íèýR­Fþ{¤²~¶¡éáÄBßñ}zÒqEðÇ^d7,†;Nè„®©ÚÞ‰T»vêfsÙ¬³ßñÜÈI\yÌÕ‘ïtX§¬ŒqJí-߉œÈ£áÏqz7!Ø$MÓ’3Ðo}ᔃŸ%'äp»Äü?ýì?
+Ä“N"\‹ä´_ùaEŒóŠÈ¶Å>þtâ¾%AlZv&>}ë å/3;ú±ÿîÑíX ·˜ïþðàSÊ#u UßwÈk/ùó‘ÿ8ŽŽø;úÓaò4RÆ)5äé/SyW01bŒ‰®ôÒ=<žÚ ¢¡'ñf ßµ8…¶ˆê½W¶-±O,Ý"x‹õbšé‰oi©í'ç´°OªC—íèýR­Fþ{¤²~¶¡éáÄBßñ}zÒqEðÇ^d7,†;Nè„®©ÚÞ‰T»vêfsÙ¬³ßñÜÈI\yÌÕ‘ïtX§¬ŒqJí-߉œÈ£áÏqz7!Ø$MÓ’3Ðo}ᔃŸ%'äp»Äü?ýì?
endobj
-1665 0 obj <<
+1682 0 obj <<
/Type /Page
-/Contents 1666 0 R
-/Resources 1664 0 R
+/Contents 1683 0 R
+/Resources 1681 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1652 0 R
-/Annots [ 1670 0 R 1671 0 R ]
+/Parent 1654 0 R
+/Annots [ 1687 0 R 1688 0 R ]
>> endobj
-1670 0 obj <<
+1687 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [253.7995 149.3637 417.685 161.4234]
/Subtype/Link/A<</Type/Action/S/URI/URI(ftp://www.isi.edu/in-notes/)>>
>> endobj
-1671 0 obj <<
+1688 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [63.4454 110.455 208.8999 120.6168]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.ietf.org/rfc/)>>
>> endobj
-1667 0 obj <<
-/D [1665 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-622 0 obj <<
-/D [1665 0 R /XYZ 56.6929 662.0717 null]
->> endobj
-1668 0 obj <<
-/D [1665 0 R /XYZ 56.6929 624.1661 null]
+1684 0 obj <<
+/D [1682 0 R /XYZ 56.6929 794.5015 null]
>> endobj
626 0 obj <<
-/D [1665 0 R /XYZ 56.6929 624.1661 null]
+/D [1682 0 R /XYZ 56.6929 662.0717 null]
>> endobj
-1137 0 obj <<
-/D [1665 0 R /XYZ 56.6929 593.0972 null]
+1685 0 obj <<
+/D [1682 0 R /XYZ 56.6929 624.1661 null]
>> endobj
630 0 obj <<
-/D [1665 0 R /XYZ 56.6929 294.2701 null]
+/D [1682 0 R /XYZ 56.6929 624.1661 null]
>> endobj
-1669 0 obj <<
-/D [1665 0 R /XYZ 56.6929 255.4568 null]
+1143 0 obj <<
+/D [1682 0 R /XYZ 56.6929 593.0972 null]
>> endobj
634 0 obj <<
-/D [1665 0 R /XYZ 56.6929 255.4568 null]
+/D [1682 0 R /XYZ 56.6929 294.2701 null]
>> endobj
-965 0 obj <<
-/D [1665 0 R /XYZ 56.6929 226.1045 null]
+1686 0 obj <<
+/D [1682 0 R /XYZ 56.6929 255.4568 null]
>> endobj
-1672 0 obj <<
-/D [1665 0 R /XYZ 56.6929 53.5688 null]
+638 0 obj <<
+/D [1682 0 R /XYZ 56.6929 255.4568 null]
>> endobj
-1673 0 obj <<
-/D [1665 0 R /XYZ 56.6929 53.5688 null]
+970 0 obj <<
+/D [1682 0 R /XYZ 56.6929 226.1045 null]
>> endobj
-1664 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R /F53 1027 0 R /F11 1384 0 R /F41 935 0 R >>
+1689 0 obj <<
+/D [1682 0 R /XYZ 56.6929 53.5688 null]
+>> endobj
+1690 0 obj <<
+/D [1682 0 R /XYZ 56.6929 53.5688 null]
+>> endobj
+1681 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R /F53 1032 0 R /F11 1400 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1676 0 obj <<
+1693 0 obj <<
/Length 2825
/Filter /FlateDecode
>>
@@ -7465,682 +7565,682 @@ xÚµZ]{£6¾Ï¯È¥ý<-’ KÇö¤É4™4v·Ûα›glH ÎLúë÷} 0’;Ûî“‹€tЋÏ{>%ðe
´ ¸ ¤ƒùÈ
’Tï*
µ9Te>#ôá¶6Ø6Ay2¾b$´ÌHÜ)³|Þ‰zA 4lY3ª#Óò`ï§6c¿ŒI0‚¶Æ¾[g;µú,{Ù•oúùFÿÍ+”Ÿë¯’ù Ø.…‚1¦‘•ß‹WñÈÌvìï&}•/\ u˜sê 8˜$Ðk“3©-å¡ZKY\{h½ÐÙ}lÛ6ø´Üïå®+Ö›­ßÁä\²Z*)#ý&ÇÍ:±¦‚ñwù·á£s£˜cû‰†Íçƒb‘÷Ç}ªO]žkÓçÁj%¬¼SƒS5ø´‰3zÝÏÞs–äWœ¹Ïw;sâû}&ÁDÂ(ò[„%ä6-Ô~P‘xN|¸­9ô‡­ÁF^d‡\•<ÛkÒlIdu¾ª2!³ðôtÖÅ:Úsq\û½I$Ø‚?Sÿ[Bn…k¡6ãû>ûòá¶
-ï+ÜF6Þuþ}^=gÛô5Õ Œ@õµ®­Ñ LKç„ }RÛˆÈB
+ï+ÜF6Þuþ}^=gÛô5Õ Œ@õµ®­Ñ LKç„ }RÛˆÈB
endobj
-1675 0 obj <<
+1692 0 obj <<
/Type /Page
-/Contents 1676 0 R
-/Resources 1674 0 R
+/Contents 1693 0 R
+/Resources 1691 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1652 0 R
->> endobj
-1677 0 obj <<
-/D [1675 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-1678 0 obj <<
-/D [1675 0 R /XYZ 85.0394 752.3015 null]
->> endobj
-1679 0 obj <<
-/D [1675 0 R /XYZ 85.0394 752.3015 null]
->> endobj
-1680 0 obj <<
-/D [1675 0 R /XYZ 85.0394 752.3015 null]
->> endobj
-1681 0 obj <<
-/D [1675 0 R /XYZ 85.0394 746.3107 null]
->> endobj
-1682 0 obj <<
-/D [1675 0 R /XYZ 85.0394 731.5461 null]
->> endobj
-1683 0 obj <<
-/D [1675 0 R /XYZ 85.0394 728.1497 null]
->> endobj
-1684 0 obj <<
-/D [1675 0 R /XYZ 85.0394 713.3851 null]
->> endobj
-1685 0 obj <<
-/D [1675 0 R /XYZ 85.0394 709.9887 null]
->> endobj
-1686 0 obj <<
-/D [1675 0 R /XYZ 85.0394 651.9592 null]
->> endobj
-1081 0 obj <<
-/D [1675 0 R /XYZ 85.0394 651.9592 null]
->> endobj
-1687 0 obj <<
-/D [1675 0 R /XYZ 85.0394 651.9592 null]
->> endobj
-1688 0 obj <<
-/D [1675 0 R /XYZ 85.0394 648.8377 null]
->> endobj
-1689 0 obj <<
-/D [1675 0 R /XYZ 85.0394 634.0731 null]
->> endobj
-1690 0 obj <<
-/D [1675 0 R /XYZ 85.0394 630.6767 null]
->> endobj
-1691 0 obj <<
-/D [1675 0 R /XYZ 85.0394 615.9121 null]
->> endobj
-1692 0 obj <<
-/D [1675 0 R /XYZ 85.0394 612.5156 null]
->> endobj
-1693 0 obj <<
-/D [1675 0 R /XYZ 85.0394 585.7959 null]
+/Parent 1750 0 R
>> endobj
1694 0 obj <<
-/D [1675 0 R /XYZ 85.0394 582.3994 null]
+/D [1692 0 R /XYZ 85.0394 794.5015 null]
>> endobj
1695 0 obj <<
-/D [1675 0 R /XYZ 85.0394 567.6349 null]
+/D [1692 0 R /XYZ 85.0394 752.3015 null]
>> endobj
1696 0 obj <<
-/D [1675 0 R /XYZ 85.0394 564.2384 null]
+/D [1692 0 R /XYZ 85.0394 752.3015 null]
>> endobj
1697 0 obj <<
-/D [1675 0 R /XYZ 85.0394 549.5337 null]
+/D [1692 0 R /XYZ 85.0394 752.3015 null]
>> endobj
1698 0 obj <<
-/D [1675 0 R /XYZ 85.0394 546.0774 null]
+/D [1692 0 R /XYZ 85.0394 746.3107 null]
>> endobj
1699 0 obj <<
-/D [1675 0 R /XYZ 85.0394 531.3128 null]
+/D [1692 0 R /XYZ 85.0394 731.5461 null]
>> endobj
1700 0 obj <<
-/D [1675 0 R /XYZ 85.0394 527.9163 null]
+/D [1692 0 R /XYZ 85.0394 728.1497 null]
>> endobj
1701 0 obj <<
-/D [1675 0 R /XYZ 85.0394 513.1518 null]
+/D [1692 0 R /XYZ 85.0394 713.3851 null]
>> endobj
1702 0 obj <<
-/D [1675 0 R /XYZ 85.0394 509.7553 null]
+/D [1692 0 R /XYZ 85.0394 709.9887 null]
>> endobj
1703 0 obj <<
-/D [1675 0 R /XYZ 85.0394 483.0356 null]
+/D [1692 0 R /XYZ 85.0394 651.9592 null]
+>> endobj
+1086 0 obj <<
+/D [1692 0 R /XYZ 85.0394 651.9592 null]
>> endobj
1704 0 obj <<
-/D [1675 0 R /XYZ 85.0394 479.6391 null]
+/D [1692 0 R /XYZ 85.0394 651.9592 null]
>> endobj
1705 0 obj <<
-/D [1675 0 R /XYZ 85.0394 464.8745 null]
+/D [1692 0 R /XYZ 85.0394 648.8377 null]
>> endobj
1706 0 obj <<
-/D [1675 0 R /XYZ 85.0394 461.4781 null]
+/D [1692 0 R /XYZ 85.0394 634.0731 null]
>> endobj
1707 0 obj <<
-/D [1675 0 R /XYZ 85.0394 446.7135 null]
+/D [1692 0 R /XYZ 85.0394 630.6767 null]
>> endobj
1708 0 obj <<
-/D [1675 0 R /XYZ 85.0394 443.3171 null]
+/D [1692 0 R /XYZ 85.0394 615.9121 null]
>> endobj
1709 0 obj <<
-/D [1675 0 R /XYZ 85.0394 428.5525 null]
+/D [1692 0 R /XYZ 85.0394 612.5156 null]
>> endobj
1710 0 obj <<
-/D [1675 0 R /XYZ 85.0394 425.156 null]
+/D [1692 0 R /XYZ 85.0394 585.7959 null]
>> endobj
1711 0 obj <<
-/D [1675 0 R /XYZ 85.0394 355.0758 null]
+/D [1692 0 R /XYZ 85.0394 582.3994 null]
>> endobj
1712 0 obj <<
-/D [1675 0 R /XYZ 85.0394 355.0758 null]
+/D [1692 0 R /XYZ 85.0394 567.6349 null]
>> endobj
1713 0 obj <<
-/D [1675 0 R /XYZ 85.0394 355.0758 null]
+/D [1692 0 R /XYZ 85.0394 564.2384 null]
>> endobj
1714 0 obj <<
-/D [1675 0 R /XYZ 85.0394 352.0499 null]
+/D [1692 0 R /XYZ 85.0394 549.5337 null]
>> endobj
1715 0 obj <<
-/D [1675 0 R /XYZ 85.0394 337.3452 null]
+/D [1692 0 R /XYZ 85.0394 546.0774 null]
>> endobj
1716 0 obj <<
-/D [1675 0 R /XYZ 85.0394 333.8889 null]
+/D [1692 0 R /XYZ 85.0394 531.3128 null]
>> endobj
1717 0 obj <<
-/D [1675 0 R /XYZ 85.0394 309.8192 null]
+/D [1692 0 R /XYZ 85.0394 527.9163 null]
>> endobj
1718 0 obj <<
-/D [1675 0 R /XYZ 85.0394 303.7727 null]
+/D [1692 0 R /XYZ 85.0394 513.1518 null]
>> endobj
1719 0 obj <<
-/D [1675 0 R /XYZ 85.0394 278.3282 null]
+/D [1692 0 R /XYZ 85.0394 509.7553 null]
>> endobj
1720 0 obj <<
-/D [1675 0 R /XYZ 85.0394 273.6565 null]
+/D [1692 0 R /XYZ 85.0394 483.0356 null]
>> endobj
1721 0 obj <<
-/D [1675 0 R /XYZ 85.0394 246.9367 null]
+/D [1692 0 R /XYZ 85.0394 479.6391 null]
>> endobj
1722 0 obj <<
-/D [1675 0 R /XYZ 85.0394 243.5403 null]
+/D [1692 0 R /XYZ 85.0394 464.8745 null]
>> endobj
1723 0 obj <<
-/D [1675 0 R /XYZ 85.0394 173.5556 null]
+/D [1692 0 R /XYZ 85.0394 461.4781 null]
>> endobj
1724 0 obj <<
-/D [1675 0 R /XYZ 85.0394 173.5556 null]
+/D [1692 0 R /XYZ 85.0394 446.7135 null]
>> endobj
1725 0 obj <<
-/D [1675 0 R /XYZ 85.0394 173.5556 null]
+/D [1692 0 R /XYZ 85.0394 443.3171 null]
>> endobj
1726 0 obj <<
-/D [1675 0 R /XYZ 85.0394 170.4341 null]
+/D [1692 0 R /XYZ 85.0394 428.5525 null]
>> endobj
1727 0 obj <<
-/D [1675 0 R /XYZ 85.0394 144.9896 null]
+/D [1692 0 R /XYZ 85.0394 425.156 null]
>> endobj
1728 0 obj <<
-/D [1675 0 R /XYZ 85.0394 140.3179 null]
+/D [1692 0 R /XYZ 85.0394 355.0758 null]
>> endobj
1729 0 obj <<
-/D [1675 0 R /XYZ 85.0394 113.5982 null]
+/D [1692 0 R /XYZ 85.0394 355.0758 null]
>> endobj
1730 0 obj <<
-/D [1675 0 R /XYZ 85.0394 110.2017 null]
+/D [1692 0 R /XYZ 85.0394 355.0758 null]
>> endobj
1731 0 obj <<
-/D [1675 0 R /XYZ 85.0394 95.4372 null]
+/D [1692 0 R /XYZ 85.0394 352.0499 null]
>> endobj
1732 0 obj <<
-/D [1675 0 R /XYZ 85.0394 92.0407 null]
+/D [1692 0 R /XYZ 85.0394 337.3452 null]
>> endobj
-1674 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >>
-/ProcSet [ /PDF /Text ]
+1733 0 obj <<
+/D [1692 0 R /XYZ 85.0394 333.8889 null]
>> endobj
-1735 0 obj <<
-/Length 2889
-/Filter /FlateDecode
->>
-stream
-xÚµšMsÛ8†ïþ:JU1†
-<
-}w„°i5LX[iÂã¶J7„O´{ ·´Xøé«M|§–=w¦í½˜A;ˆ‚ÈÀ öHü¿HiþM|˜øh²÷²ÈX–%òž.w˜C
-†•…‚²Ò`¯·P°IºÚýLíù&?ýã⯲s¬Ø,¯dSšwç]ù?ý
-?â7?Òù1Щsàží’º(
-ü6¡¹$´HÊ*K^˜l¦µ£ïÞ©s±ðûgM,&†af0 †•…˜²2ˆb6iƒXW»Ÿ˜©½ÞÄÜÎ=ØYEXž(E_q@ü¿Ø&ÁFQã‚Z}ƒ¤Æ¯G¨ù
-\'4v¹@`ã£Ø\ÇÄÆ?5ØÄaFÔÊ'­0ÝÐA>Lº¦i5 S[0-»Uºy¢Ý ³¥½©ŠC½KáˆN/ÙAlapød%osk†¼¯fÈCÞ(ò+Å[Œ0$aH;†ü~Îßkºžã)†Â¦^aüâ“4¾:îöG8ÔÊùŴ‰´ÿÄs]8Ç4 #° + leeÀŽ,°mÒì®v?lS›ÃNÄ>ŠsÁÙô©>µœ_³º2#zas,E*[dè ÐéС7[
-id„ý4¦Õ0m¥Ñ¡¥
-°I+ «Ý¿Lí{Ôu]î‹5e×¥ÓøX=ö[½‰®»"ååÑÇ¡®â»ûµðOÞ_3æ}í¬“wÉä¤?ÈúžÛð†hÁSÃú.•®‘Wä‘ÊïlEÕ {…ø¡Ó;G
-ÛðÈ‘·±±06Š ÅØ^-¢¿¶j?½F•t7×ñ90d6BäQ—Â-D‹L^àJj±ªÞ£z‹uõ7®G¶Ëx8›c°ˆ¿¤uæåE\#þò‚tò&™ª1ZP"¦}Ä Ç‘…£4j@KÝΦkì÷£4„ã&]ÉøZ?$üÑ`'¿¿IËJ¦ž"ö:íbo¸ùáé+‡²w7Jcðì··T#ôB^UlŸOj4V`qÅ‘˜a4 Li`^d) Øt`]á^`¦°¨¡†p"üU±¼¬ŸTÂ숚*ü/¯¯Å¡FË;ÑøƒJQ6‡F¿¯2`äø‘±ºÄ›n¸ãþ¹Ø‹|·^ÊÖëc
-¾šÈÖϺ`]Ë4OòJv‰šU N«µƒiqLË2í«ÿ
-ŒÛÏiueK×±ôƒƒæÏBŽãŒÄaÓj˜¹¶jÞLpð0s«tÃüD»—yK[ÏÇ"ß»ø+Vý,/MÓ­ ~‚é;üd'DÄñCK˜ýl~h½u Äë!ÍTò'/Ø‹PˆÇª¦•…’²j(ÙöK«´A©«ÝOÉÔ^³ïÇTìq{–«íPo‘Í#/þéºÐ湚»×,Ý…ô¦¬+#wŸ[<¹ÂùÅ!Ù±r¹
-…º#õ:ÓÊEYi(^ds›´¥«ÝÅÔOï7ÕḭD˜d™7žmôl‘‡ü€ºíÉÿ ã
-.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñ
-endobj
1734 0 obj <<
-/Type /Page
-/Contents 1735 0 R
-/Resources 1733 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1652 0 R
+/D [1692 0 R /XYZ 85.0394 309.8192 null]
+>> endobj
+1735 0 obj <<
+/D [1692 0 R /XYZ 85.0394 303.7727 null]
>> endobj
1736 0 obj <<
-/D [1734 0 R /XYZ 56.6929 794.5015 null]
+/D [1692 0 R /XYZ 85.0394 278.3282 null]
>> endobj
1737 0 obj <<
-/D [1734 0 R /XYZ 56.6929 748.5056 null]
+/D [1692 0 R /XYZ 85.0394 273.6565 null]
>> endobj
1738 0 obj <<
-/D [1734 0 R /XYZ 56.6929 748.5056 null]
+/D [1692 0 R /XYZ 85.0394 246.9367 null]
>> endobj
1739 0 obj <<
-/D [1734 0 R /XYZ 56.6929 748.5056 null]
+/D [1692 0 R /XYZ 85.0394 243.5403 null]
>> endobj
1740 0 obj <<
-/D [1734 0 R /XYZ 56.6929 743.7078 null]
+/D [1692 0 R /XYZ 85.0394 173.5556 null]
>> endobj
1741 0 obj <<
-/D [1734 0 R /XYZ 56.6929 719.6381 null]
+/D [1692 0 R /XYZ 85.0394 173.5556 null]
>> endobj
1742 0 obj <<
-/D [1734 0 R /XYZ 56.6929 711.8197 null]
+/D [1692 0 R /XYZ 85.0394 173.5556 null]
>> endobj
1743 0 obj <<
-/D [1734 0 R /XYZ 56.6929 697.0552 null]
+/D [1692 0 R /XYZ 85.0394 170.4341 null]
>> endobj
1744 0 obj <<
-/D [1734 0 R /XYZ 56.6929 691.8868 null]
+/D [1692 0 R /XYZ 85.0394 144.9896 null]
>> endobj
1745 0 obj <<
-/D [1734 0 R /XYZ 56.6929 665.1671 null]
+/D [1692 0 R /XYZ 85.0394 140.3179 null]
>> endobj
1746 0 obj <<
-/D [1734 0 R /XYZ 56.6929 659.9987 null]
+/D [1692 0 R /XYZ 85.0394 113.5982 null]
>> endobj
1747 0 obj <<
-/D [1734 0 R /XYZ 56.6929 635.929 null]
+/D [1692 0 R /XYZ 85.0394 110.2017 null]
>> endobj
1748 0 obj <<
-/D [1734 0 R /XYZ 56.6929 628.1106 null]
+/D [1692 0 R /XYZ 85.0394 95.4372 null]
>> endobj
1749 0 obj <<
-/D [1734 0 R /XYZ 56.6929 601.3909 null]
+/D [1692 0 R /XYZ 85.0394 92.0407 null]
>> endobj
-1750 0 obj <<
-/D [1734 0 R /XYZ 56.6929 596.2225 null]
->> endobj
-1751 0 obj <<
-/D [1734 0 R /XYZ 56.6929 569.5028 null]
->> endobj
-1752 0 obj <<
-/D [1734 0 R /XYZ 56.6929 564.3344 null]
+1691 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
1753 0 obj <<
-/D [1734 0 R /XYZ 56.6929 549.6297 null]
+/Length 2889
+/Filter /FlateDecode
+>>
+stream
+xÚµšMsÛ8†ïþ:JU1†
+<
+}w„°i5LX[iÂã¶J7„O´{ ·´Xøé«M|§–=w¦í½˜A;ˆ‚ÈÀ öHü¿HiþM|˜øh²÷²ÈX–%òž.w˜C
+†•…‚²Ò`¯·P°IºÚýLíù&?ýã⯲s¬Ø,¯dSšwç]ù?ý
+?â7?Òù1Щsàží’º(
+ü6¡¹$´HÊ*K^˜l¦µ£ïÞ©s±ðûgM,&†af0 †•…˜²2ˆb6iƒXW»Ÿ˜©½ÞÄÜÎ=ØYEXž(E_q@ü¿Ø&ÁFQã‚Z}ƒ¤Æ¯G¨ù
+\'4v¹@`ã£Ø\ÇÄÆ?5ØÄaFÔÊ'­0ÝÐA>Lº¦i5 S[0-»Uºy¢Ý ³¥½©ŠC½KáˆN/ÙAlapød%osk†¼¯fÈCÞ(ò+Å[Œ0$aH;†ü~Îßkºžã)†Â¦^aüâ“4¾:îöG8ÔÊùŴ‰´ÿÄs]8Ç4 #° + leeÀŽ,°mÒì®v?lS›ÃNÄ>ŠsÁÙô©>µœ_³º2#zas,E*[dè ÐéС7[
+id„ý4¦Õ0m¥Ñ¡¥
+°I+ «Ý¿Lí{Ôu]î‹5e×¥ÓøX=ö[½‰®»"ååÑÇ¡®â»ûµðOÞ_3æ}í¬“wÉä¤?ÈúžÛð†hÁSÃú.•®‘Wä‘ÊïlEÕ {…ø¡Ó;G
+ÛðÈ‘·±±06Š ÅØ^-¢¿¶j?½F•t7×ñ90d6BäQ—Â-D‹L^àJj±ªÞ£z‹uõ7®G¶Ëx8›c°ˆ¿¤uæåE\#þò‚tò&™ª1ZP"¦}Ä Ç‘…£4j@KÝΦkì÷£4„ã&]ÉøZ?$üÑ`'¿¿IËJ¦ž"ö:íbo¸ùáé+‡²w7Jcðì··T#ôB^UlŸOj4V`qÅ‘˜a4 Li`^d) Øt`]á^`¦°¨¡†p"üU±¼¬ŸTÂ숚*ü/¯¯Å¡FË;ÑøƒJQ6‡F¿¯2`äø‘±ºÄ›n¸ãþ¹Ø‹|·^ÊÖëc
+¾šÈÖϺ`]Ë4OòJv‰šU N«µƒiqLË2í«ÿ
+ŒÛÏiueK×±ôƒƒæÏBŽãŒÄaÓj˜¹¶jÞLpð0s«tÃüD»—yK[ÏÇ"ß»ø+Vý,/MÓ­ ~‚é;üd'DÄñCK˜ýl~h½u Äë!ÍTò'/Ø‹PˆÇª¦•…’²j(ÙöK«´A©«ÝOÉÔ^³ïÇTìq{–«íPo‘Í#/þéºÐ湚»×,Ý…ô¦¬+#wŸ[<¹ÂùÅ!Ù±r¹
+…º#õ:ÓÊEYi(^ds›´¥«ÝÅÔOï7ÕḭD˜d™7žmôl‘‡ü€ºíÉÿ ã
+.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñ
+endobj
+1752 0 obj <<
+/Type /Page
+/Contents 1753 0 R
+/Resources 1751 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1750 0 R
>> endobj
1754 0 obj <<
-/D [1734 0 R /XYZ 56.6929 544.4015 null]
+/D [1752 0 R /XYZ 56.6929 794.5015 null]
>> endobj
1755 0 obj <<
-/D [1734 0 R /XYZ 56.6929 529.6968 null]
+/D [1752 0 R /XYZ 56.6929 748.5056 null]
>> endobj
1756 0 obj <<
-/D [1734 0 R /XYZ 56.6929 524.4686 null]
+/D [1752 0 R /XYZ 56.6929 748.5056 null]
>> endobj
1757 0 obj <<
-/D [1734 0 R /XYZ 56.6929 500.3989 null]
+/D [1752 0 R /XYZ 56.6929 748.5056 null]
>> endobj
1758 0 obj <<
-/D [1734 0 R /XYZ 56.6929 492.5805 null]
+/D [1752 0 R /XYZ 56.6929 743.7078 null]
>> endobj
1759 0 obj <<
-/D [1734 0 R /XYZ 56.6929 467.136 null]
+/D [1752 0 R /XYZ 56.6929 719.6381 null]
>> endobj
1760 0 obj <<
-/D [1734 0 R /XYZ 56.6929 460.6924 null]
+/D [1752 0 R /XYZ 56.6929 711.8197 null]
>> endobj
1761 0 obj <<
-/D [1734 0 R /XYZ 56.6929 436.6227 null]
+/D [1752 0 R /XYZ 56.6929 697.0552 null]
>> endobj
1762 0 obj <<
-/D [1734 0 R /XYZ 56.6929 428.8043 null]
+/D [1752 0 R /XYZ 56.6929 691.8868 null]
>> endobj
1763 0 obj <<
-/D [1734 0 R /XYZ 56.6929 414.0996 null]
+/D [1752 0 R /XYZ 56.6929 665.1671 null]
>> endobj
1764 0 obj <<
-/D [1734 0 R /XYZ 56.6929 408.8714 null]
+/D [1752 0 R /XYZ 56.6929 659.9987 null]
>> endobj
1765 0 obj <<
-/D [1734 0 R /XYZ 56.6929 382.1516 null]
+/D [1752 0 R /XYZ 56.6929 635.929 null]
>> endobj
1766 0 obj <<
-/D [1734 0 R /XYZ 56.6929 376.9833 null]
+/D [1752 0 R /XYZ 56.6929 628.1106 null]
>> endobj
1767 0 obj <<
-/D [1734 0 R /XYZ 56.6929 350.2636 null]
+/D [1752 0 R /XYZ 56.6929 601.3909 null]
>> endobj
1768 0 obj <<
-/D [1734 0 R /XYZ 56.6929 345.0952 null]
+/D [1752 0 R /XYZ 56.6929 596.2225 null]
>> endobj
1769 0 obj <<
-/D [1734 0 R /XYZ 56.6929 321.0255 null]
+/D [1752 0 R /XYZ 56.6929 569.5028 null]
>> endobj
1770 0 obj <<
-/D [1734 0 R /XYZ 56.6929 313.2071 null]
+/D [1752 0 R /XYZ 56.6929 564.3344 null]
>> endobj
1771 0 obj <<
-/D [1734 0 R /XYZ 56.6929 298.5024 null]
+/D [1752 0 R /XYZ 56.6929 549.6297 null]
>> endobj
1772 0 obj <<
-/D [1734 0 R /XYZ 56.6929 293.2742 null]
+/D [1752 0 R /XYZ 56.6929 544.4015 null]
>> endobj
1773 0 obj <<
-/D [1734 0 R /XYZ 56.6929 267.8297 null]
+/D [1752 0 R /XYZ 56.6929 529.6968 null]
>> endobj
1774 0 obj <<
-/D [1734 0 R /XYZ 56.6929 261.3861 null]
+/D [1752 0 R /XYZ 56.6929 524.4686 null]
>> endobj
1775 0 obj <<
-/D [1734 0 R /XYZ 56.6929 199.468 null]
+/D [1752 0 R /XYZ 56.6929 500.3989 null]
>> endobj
1776 0 obj <<
-/D [1734 0 R /XYZ 56.6929 199.468 null]
+/D [1752 0 R /XYZ 56.6929 492.5805 null]
>> endobj
1777 0 obj <<
-/D [1734 0 R /XYZ 56.6929 199.468 null]
+/D [1752 0 R /XYZ 56.6929 467.136 null]
>> endobj
1778 0 obj <<
-/D [1734 0 R /XYZ 56.6929 191.7053 null]
+/D [1752 0 R /XYZ 56.6929 460.6924 null]
>> endobj
1779 0 obj <<
-/D [1734 0 R /XYZ 56.6929 176.9408 null]
+/D [1752 0 R /XYZ 56.6929 436.6227 null]
>> endobj
1780 0 obj <<
-/D [1734 0 R /XYZ 56.6929 171.7724 null]
+/D [1752 0 R /XYZ 56.6929 428.8043 null]
>> endobj
1781 0 obj <<
-/D [1734 0 R /XYZ 56.6929 157.0677 null]
+/D [1752 0 R /XYZ 56.6929 414.0996 null]
>> endobj
1782 0 obj <<
-/D [1734 0 R /XYZ 56.6929 151.8395 null]
+/D [1752 0 R /XYZ 56.6929 408.8714 null]
>> endobj
1783 0 obj <<
-/D [1734 0 R /XYZ 56.6929 137.1348 null]
+/D [1752 0 R /XYZ 56.6929 382.1516 null]
>> endobj
1784 0 obj <<
-/D [1734 0 R /XYZ 56.6929 131.9066 null]
+/D [1752 0 R /XYZ 56.6929 376.9833 null]
>> endobj
1785 0 obj <<
-/D [1734 0 R /XYZ 56.6929 117.2018 null]
+/D [1752 0 R /XYZ 56.6929 350.2636 null]
>> endobj
1786 0 obj <<
-/D [1734 0 R /XYZ 56.6929 111.9736 null]
+/D [1752 0 R /XYZ 56.6929 345.0952 null]
>> endobj
1787 0 obj <<
-/D [1734 0 R /XYZ 56.6929 97.2091 null]
+/D [1752 0 R /XYZ 56.6929 321.0255 null]
>> endobj
1788 0 obj <<
-/D [1734 0 R /XYZ 56.6929 92.0407 null]
+/D [1752 0 R /XYZ 56.6929 313.2071 null]
>> endobj
-1733 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >>
-/ProcSet [ /PDF /Text ]
+1789 0 obj <<
+/D [1752 0 R /XYZ 56.6929 298.5024 null]
>> endobj
-1791 0 obj <<
-/Length 2542
-/Filter /FlateDecode
->>
-stream
-xÚ¥Z[w£º~ϯð£½Ö˜Jqé›'Og’ÔÎô´kÎy ¶â°ŠÁœ9s~}·Ð‘<=]yH>Øß¾c<Að‡'1õI‚I”E˜N¶‡+4ÙÃÞý–2s%47¥®Ÿ¯þrG¢Iâ%¡Nž_{ÅŠc<yÞ}›.žžn–«Îæ>EÓ…7›S„ÔêÍíf6„o¾¢éõêúóêñ~½xúø/qѯˆ¢ÅÃRœl¾Þßßnžoåéúv±\=܃žýöüéêöY?¶ùjþÌÿ¹úöšìà ?]!$1|‡äá$ñ'‡«€„¨•üjsõw}Cc·½tLU”ÄýhDW>ž`ì%”ú=eÑÄ ‰OZe-6⵬J›¬,jë[ Oq.-#€Œ‘%d8ú·õÝ (Šü6ÄÄyqÏï
-ÔÆCùÎ/¬g8‰#Ϫl Η6äP·!åP¸’Ò*§$r¨Üm(}ˆmQ» ~S¥T¼¶¼eÚ¤âè.Ë™8º)‹_ò÷'ÁƒX¼­ªŽ§œ¦*@™A>O3ì'SÉÇ5cUéÜ{Ü6¥AFB¬d„ †t!T™Rv2´”&#Á¾ 'tGÆö8=ðQ2tHséÅîÏRâcê…qì÷)Y*6ÒÊô;öRÍâé)­~hFB;#¼9EñF )#JJ1â#ŒŒ¸  F†ØFLð3åßTYêLºÇk)u]–Œ(éAz̆UשׁG£Tƒ ÆaŸ‡kÉ×´(²b?`»ç8ÿ˜Q:Í~ϘÅs<>Â_ ©r°$…4I>N$9p ŽÀŠ 䯵Twù:pœEž¥5«L=°æ{Yý»£(Û²qŽÂØ‹ü Ï$ÓC–7Êé4Ik¹ý ÷£*Û¿5‚"Ù+æ>I<J¡®˜¾"¬pU€ÍÒ³?˜3“&7;k@£Ä‹¾P)˜RvÖµ”¦=ö©v'tÇûö8ñ=ð¼yNŸgc``Ÿ·z #P¾¦ì寳9 ü骮O­ÀNk#pÍ
-ÇÄ¡V"l·Jäë‘¢š7&vᨒ׷„°FœEÄmÊm™E]â'B‰™`µ¸÷ÕHëÖ&&s-?¦! }™fðŠÊ S“}„Õ×iya] ½r°.…é$HÙ…kp>
-‘gDDvXýZdüR±(’>¬Ž%PØ×q#êâ,«%7æ-y¨^ôB0WD¡õˈ…§JøŸrö³:û ¸ÊY'ˆŒ¨2”¨‚æËÓF @¨µ> ‡ÐÈ¿P˜R3RRº›‚ÐaF.hÃŒ†Ø32Á¿Ö­uˆ]Vçê(•:_Ýü
-”vйQ`Å­cCÊ¡d%Õi9q¸ŠÚPóÛ¢g\ëss:˪¨ûs™îÔˆ€'+‹¾Ià…1Ì{žy'¤ UVo•ÒÇ*˵Ʃ]ã~ì¡(¾0ê1¥WR]Ï8êX'´¡ñ!¶Eã&øBj–íÕdá:­³3;txª±ÍKQÎŽŽÓ> zløÓô´Eé˜éÛ EðÂñ…v”r¡¤4$pt‘Nhƒˆ!¶…\g„P×
-9±ôIŒ»©Òï¯bF²SÁà´?Õæ!±ò
-endobj
1790 0 obj <<
-/Type /Page
-/Contents 1791 0 R
-/Resources 1789 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1843 0 R
+/D [1752 0 R /XYZ 56.6929 293.2742 null]
+>> endobj
+1791 0 obj <<
+/D [1752 0 R /XYZ 56.6929 267.8297 null]
>> endobj
1792 0 obj <<
-/D [1790 0 R /XYZ 85.0394 794.5015 null]
+/D [1752 0 R /XYZ 56.6929 261.3861 null]
>> endobj
1793 0 obj <<
-/D [1790 0 R /XYZ 85.0394 748.4854 null]
+/D [1752 0 R /XYZ 56.6929 199.468 null]
>> endobj
1794 0 obj <<
-/D [1790 0 R /XYZ 85.0394 748.4854 null]
+/D [1752 0 R /XYZ 56.6929 199.468 null]
>> endobj
1795 0 obj <<
-/D [1790 0 R /XYZ 85.0394 748.4854 null]
+/D [1752 0 R /XYZ 56.6929 199.468 null]
>> endobj
1796 0 obj <<
-/D [1790 0 R /XYZ 85.0394 743.3452 null]
+/D [1752 0 R /XYZ 56.6929 191.7053 null]
>> endobj
1797 0 obj <<
-/D [1790 0 R /XYZ 85.0394 728.6405 null]
+/D [1752 0 R /XYZ 56.6929 176.9408 null]
>> endobj
1798 0 obj <<
-/D [1790 0 R /XYZ 85.0394 723.1655 null]
+/D [1752 0 R /XYZ 56.6929 171.7724 null]
>> endobj
1799 0 obj <<
-/D [1790 0 R /XYZ 85.0394 708.4607 null]
+/D [1752 0 R /XYZ 56.6929 157.0677 null]
>> endobj
1800 0 obj <<
-/D [1790 0 R /XYZ 85.0394 702.9857 null]
+/D [1752 0 R /XYZ 56.6929 151.8395 null]
>> endobj
1801 0 obj <<
-/D [1790 0 R /XYZ 85.0394 688.2211 null]
+/D [1752 0 R /XYZ 56.6929 137.1348 null]
>> endobj
1802 0 obj <<
-/D [1790 0 R /XYZ 85.0394 682.8059 null]
+/D [1752 0 R /XYZ 56.6929 131.9066 null]
>> endobj
1803 0 obj <<
-/D [1790 0 R /XYZ 85.0394 668.0414 null]
+/D [1752 0 R /XYZ 56.6929 117.2018 null]
>> endobj
1804 0 obj <<
-/D [1790 0 R /XYZ 85.0394 662.6262 null]
+/D [1752 0 R /XYZ 56.6929 111.9736 null]
>> endobj
1805 0 obj <<
-/D [1790 0 R /XYZ 85.0394 599.7666 null]
+/D [1752 0 R /XYZ 56.6929 97.2091 null]
>> endobj
1806 0 obj <<
-/D [1790 0 R /XYZ 85.0394 599.7666 null]
->> endobj
-1807 0 obj <<
-/D [1790 0 R /XYZ 85.0394 599.7666 null]
+/D [1752 0 R /XYZ 56.6929 92.0407 null]
>> endobj
-1808 0 obj <<
-/D [1790 0 R /XYZ 85.0394 591.7571 null]
+1751 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
1809 0 obj <<
-/D [1790 0 R /XYZ 85.0394 565.0374 null]
+/Length 2542
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Z[w£º~ϯð£½Ö˜Jqé›'Og’ÔÎô´kÎy ¶â°ŠÁœ9s~}·Ð‘<=]yH>Øß¾c<Að‡'1õI‚I”E˜N¶‡+4ÙÃÞý–2s%47¥®Ÿ¯þrG¢Iâ%¡Nž_{ÅŠc<yÞ}›.žžn–«Îæ>EÓ…7›S„ÔêÍíf6„o¾¢éõêúóêñ~½xúø/qѯˆ¢ÅÃRœl¾Þßßnžoåéúv±\=܃žýöüéêöY?¶ùjþÌÿ¹úöšìà ?]!$1|‡äá$ñ'‡«€„¨•üjsõw}Cc·½tLU”ÄýhDW>ž`ì%”ú=eÑÄ ‰OZe-6⵬J›¬,jë[ Oq.-#€Œ‘%d8ú·õÝ (Šü6ÄÄyqÏï
+ÔÆCùÎ/¬g8‰#Ϫl Η6äP·!åP¸’Ò*§$r¨Üm(}ˆmQ» ~S¥T¼¶¼eÚ¤âè.Ë™8º)‹_ò÷'ÁƒX¼­ªŽ§œ¦*@™A>O3ì'SÉÇ5cUéÜ{Ü6¥AFB¬d„ †t!T™Rv2´”&#Á¾ 'tGÆö8=ðQ2tHséÅîÏRâcê…qì÷)Y*6ÒÊô;öRÍâé)­~hFB;#¼9EñF )#JJ1â#ŒŒ¸  F†ØFLð3åßTYêLºÇk)u]–Œ(éAz̆UשׁG£Tƒ ÆaŸ‡kÉ×´(²b?`»ç8ÿ˜Q:Í~ϘÅs<>Â_ ©r°$…4I>N$9p ŽÀŠ 䯵Twù:pœEž¥5«L=°æ{Yý»£(Û²qŽÂØ‹ü Ï$ÓC–7Êé4Ik¹ý ÷£*Û¿5‚"Ù+æ>I<J¡®˜¾"¬pU€ÍÒ³?˜3“&7;k@£Ä‹¾P)˜RvÖµ”¦=ö©v'tÇûö8ñ=ð¼yNŸgc``Ÿ·z #P¾¦ì寳9 ü骮O­ÀNk#pÍ
+ÇÄ¡V"l·Jäë‘¢š7&vᨒ׷„°FœEÄmÊm™E]â'B‰™`µ¸÷ÕHëÖ&&s-?¦! }™fðŠÊ S“}„Õ×iya] ½r°.…é$HÙ…kp>
+‘gDDvXýZdüR±(’>¬Ž%PØ×q#êâ,«%7æ-y¨^ôB0WD¡õˈ…§JøŸrö³:û ¸ÊY'ˆŒ¨2”¨‚æËÓF @¨µ> ‡ÐÈ¿P˜R3RRº›‚ÐaF.hÃŒ†Ø32Á¿Ö­uˆ]Vçê(•:_Ýü
+”vйQ`Å­cCÊ¡d%Õi9q¸ŠÚPóÛ¢g\ëss:˪¨ûs™îÔˆ€'+‹¾Ià…1Ì{žy'¤ UVo•ÒÇ*˵Ʃ]ã~ì¡(¾0ê1¥WR]Ï8êX'´¡ñ!¶Eã&øBj–íÕdá:­³3;txª±ÍKQÎŽŽÓ> zløÓô´Eé˜éÛ EðÂñ…v”r¡¤4$pt‘Nhƒˆ!¶…\g„P×
+9±ôIŒ»©Òï¯bF²SÁà´?Õæ!±ò
+endobj
+1808 0 obj <<
+/Type /Page
+/Contents 1809 0 R
+/Resources 1807 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1750 0 R
>> endobj
1810 0 obj <<
-/D [1790 0 R /XYZ 85.0394 559.6222 null]
+/D [1808 0 R /XYZ 85.0394 794.5015 null]
>> endobj
1811 0 obj <<
-/D [1790 0 R /XYZ 85.0394 534.1777 null]
+/D [1808 0 R /XYZ 85.0394 748.4854 null]
>> endobj
1812 0 obj <<
-/D [1790 0 R /XYZ 85.0394 527.4872 null]
+/D [1808 0 R /XYZ 85.0394 748.4854 null]
>> endobj
1813 0 obj <<
-/D [1790 0 R /XYZ 85.0394 502.0427 null]
+/D [1808 0 R /XYZ 85.0394 748.4854 null]
>> endobj
1814 0 obj <<
-/D [1790 0 R /XYZ 85.0394 495.3523 null]
+/D [1808 0 R /XYZ 85.0394 743.3452 null]
>> endobj
1815 0 obj <<
-/D [1790 0 R /XYZ 85.0394 420.5376 null]
+/D [1808 0 R /XYZ 85.0394 728.6405 null]
>> endobj
1816 0 obj <<
-/D [1790 0 R /XYZ 85.0394 420.5376 null]
+/D [1808 0 R /XYZ 85.0394 723.1655 null]
>> endobj
1817 0 obj <<
-/D [1790 0 R /XYZ 85.0394 420.5376 null]
+/D [1808 0 R /XYZ 85.0394 708.4607 null]
>> endobj
1818 0 obj <<
-/D [1790 0 R /XYZ 85.0394 412.5281 null]
+/D [1808 0 R /XYZ 85.0394 702.9857 null]
>> endobj
1819 0 obj <<
-/D [1790 0 R /XYZ 85.0394 388.4584 null]
+/D [1808 0 R /XYZ 85.0394 688.2211 null]
>> endobj
1820 0 obj <<
-/D [1790 0 R /XYZ 85.0394 380.3932 null]
+/D [1808 0 R /XYZ 85.0394 682.8059 null]
>> endobj
1821 0 obj <<
-/D [1790 0 R /XYZ 85.0394 365.6884 null]
+/D [1808 0 R /XYZ 85.0394 668.0414 null]
>> endobj
1822 0 obj <<
-/D [1790 0 R /XYZ 85.0394 360.2134 null]
+/D [1808 0 R /XYZ 85.0394 662.6262 null]
>> endobj
1823 0 obj <<
-/D [1790 0 R /XYZ 85.0394 345.4488 null]
+/D [1808 0 R /XYZ 85.0394 599.7666 null]
>> endobj
1824 0 obj <<
-/D [1790 0 R /XYZ 85.0394 340.0336 null]
+/D [1808 0 R /XYZ 85.0394 599.7666 null]
>> endobj
1825 0 obj <<
-/D [1790 0 R /XYZ 85.0394 325.269 null]
+/D [1808 0 R /XYZ 85.0394 599.7666 null]
>> endobj
1826 0 obj <<
-/D [1790 0 R /XYZ 85.0394 319.8539 null]
+/D [1808 0 R /XYZ 85.0394 591.7571 null]
>> endobj
1827 0 obj <<
-/D [1790 0 R /XYZ 85.0394 295.7842 null]
+/D [1808 0 R /XYZ 85.0394 565.0374 null]
>> endobj
1828 0 obj <<
-/D [1790 0 R /XYZ 85.0394 287.7189 null]
+/D [1808 0 R /XYZ 85.0394 559.6222 null]
>> endobj
1829 0 obj <<
-/D [1790 0 R /XYZ 85.0394 272.9543 null]
+/D [1808 0 R /XYZ 85.0394 534.1777 null]
>> endobj
1830 0 obj <<
-/D [1790 0 R /XYZ 85.0394 267.5392 null]
+/D [1808 0 R /XYZ 85.0394 527.4872 null]
>> endobj
1831 0 obj <<
-/D [1790 0 R /XYZ 85.0394 252.7746 null]
+/D [1808 0 R /XYZ 85.0394 502.0427 null]
>> endobj
1832 0 obj <<
-/D [1790 0 R /XYZ 85.0394 247.3594 null]
+/D [1808 0 R /XYZ 85.0394 495.3523 null]
>> endobj
1833 0 obj <<
-/D [1790 0 R /XYZ 85.0394 223.2897 null]
+/D [1808 0 R /XYZ 85.0394 420.5376 null]
>> endobj
1834 0 obj <<
-/D [1790 0 R /XYZ 85.0394 215.2245 null]
+/D [1808 0 R /XYZ 85.0394 420.5376 null]
>> endobj
1835 0 obj <<
-/D [1790 0 R /XYZ 85.0394 149.4956 null]
+/D [1808 0 R /XYZ 85.0394 420.5376 null]
>> endobj
1836 0 obj <<
-/D [1790 0 R /XYZ 85.0394 149.4956 null]
+/D [1808 0 R /XYZ 85.0394 412.5281 null]
>> endobj
1837 0 obj <<
-/D [1790 0 R /XYZ 85.0394 149.4956 null]
+/D [1808 0 R /XYZ 85.0394 388.4584 null]
>> endobj
1838 0 obj <<
-/D [1790 0 R /XYZ 85.0394 144.3554 null]
+/D [1808 0 R /XYZ 85.0394 380.3932 null]
>> endobj
1839 0 obj <<
-/D [1790 0 R /XYZ 85.0394 120.2857 null]
+/D [1808 0 R /XYZ 85.0394 365.6884 null]
>> endobj
1840 0 obj <<
-/D [1790 0 R /XYZ 85.0394 112.2205 null]
+/D [1808 0 R /XYZ 85.0394 360.2134 null]
>> endobj
1841 0 obj <<
-/D [1790 0 R /XYZ 85.0394 97.4559 null]
+/D [1808 0 R /XYZ 85.0394 345.4488 null]
>> endobj
1842 0 obj <<
-/D [1790 0 R /XYZ 85.0394 92.0407 null]
+/D [1808 0 R /XYZ 85.0394 340.0336 null]
>> endobj
-1789 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >>
-/ProcSet [ /PDF /Text ]
+1843 0 obj <<
+/D [1808 0 R /XYZ 85.0394 325.269 null]
+>> endobj
+1844 0 obj <<
+/D [1808 0 R /XYZ 85.0394 319.8539 null]
>> endobj
-1846 0 obj <<
-/Length 2121
-/Filter /FlateDecode
->>
-stream
-xÚ¥YIs㸾ûWèª*B°pÍM¶ÔŽ»=¶cy*™t÷¦`‰eŠÔˆ”»5¿>x J$5•”Äòà}x 6¢ðc#Ï'~Ä£Q¹Ä£Ì%›+:ZÁÜí34“šhbS]¿\ýí“F‰|î^Þ,Y!¡aÈF/˯Δ2 Ô¹¾»¾¿{¼}ž>ýã·ñ„{ÔùF=:}˜agñëíí|ñ27Ýçùtv÷p $l< üˆ:Ó§§ùÃìîß8?URi3z3_Œ¿¿|¾š¿4˶·Æ¨Pkþýêëw:ZÂ?_Q"¢Ðý€%,Šøhsåz‚x®õHvµ¸úg#Кլ¦b”páó[q6bŒDžÇ[Æò"â .´±_Ë"“•\âg c™ìwiu0¦ùtSönV¸Ð Ñ-*\›è±¦RKû
-Z9õ½ï§šç`/VÝPë‘¥›ñ€x<hëž›8ÍÇ—Sç!ÞHÕbÎâPVrƒ£G©™ùÏJæeZäÚL'»c!%Aø°.%û¯Àâ gF k\VYü.Ç g\GìÆ,t–¨'ÎMãÆЉ÷o›87R>Çù>Þ”VØr­hÒÀúà\¤=ê’ê
-›ª‹†ªÃ~4¨úˆÆ™îN8Zº/Û¿h†ý($Š¼ÿƒ_bÝMÖ Q?~H"\ÈK6Õ
-¸÷‹Š{Jð/qYÊŽéZA/‰E©¢
-\§Il‡·îLx‹j
-aÜo汆ÆÙ3¨¢sõd¥Ë*^ÉÛXxùÎR~ȬتýÁŠüˆ9w›m&U¿Øé½cïU¢Àâ,pò¢2ª‹ö6°L@ÎU\¿²q8.€6býN}×I?âL¥°Ž ®üHU®‹}fFµVÕx•øý}_à»*ê¬cIj†\m­17ÂÞÔ©ÏpÐƺû<3ú$)6“.|¶qžjéŒ:¯ü≀Æ2-“,N7:‡ê‰¸jH ññBçç®:s%võrá‹(+$-K¢èp
-uüa„ÄøÉÒ7YÂò°§O+|Ëô'66E^­ /œ÷z‰?Ö)\6;6jVìÙ+†ÎRZ/ÙÉT[?뙉WÃ
-BRSOÄú1£ì ô<(AD]­Xx©°óZìM¬¸¾{˜åºP¬ú\J"VßCÞäN¹Qï3;¡Ô»pý²©Î“ ì‚
-ÓÙ„õç‘A­Ç<r¦¶3´´b¡žq+êÛ–²íC@ …ñç)ÞgÈ4ÍàÂõlj¤8Nš¼ëøýût¯™ çö°KWk\F,an¨þ^¡æ9Á%@?.aÂIàG°O‹îe^×å€ÃúúdQâÚò5.«b[èhAöfúwœyüË3¤™yÂçžÒur¥kª‘)\+’ÎrÙ[tÀaUuàE›cýÿ/eU/aßU„f¿^”6 uÏ–^ÿƒu¾öÿøÈÜendstream
-endobj
1845 0 obj <<
-/Type /Page
-/Contents 1846 0 R
-/Resources 1844 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1843 0 R
+/D [1808 0 R /XYZ 85.0394 295.7842 null]
+>> endobj
+1846 0 obj <<
+/D [1808 0 R /XYZ 85.0394 287.7189 null]
>> endobj
1847 0 obj <<
-/D [1845 0 R /XYZ 56.6929 794.5015 null]
+/D [1808 0 R /XYZ 85.0394 272.9543 null]
>> endobj
1848 0 obj <<
-/D [1845 0 R /XYZ 56.6929 749.4437 null]
+/D [1808 0 R /XYZ 85.0394 267.5392 null]
>> endobj
1849 0 obj <<
-/D [1845 0 R /XYZ 56.6929 749.4437 null]
+/D [1808 0 R /XYZ 85.0394 252.7746 null]
>> endobj
1850 0 obj <<
-/D [1845 0 R /XYZ 56.6929 749.4437 null]
+/D [1808 0 R /XYZ 85.0394 247.3594 null]
>> endobj
1851 0 obj <<
-/D [1845 0 R /XYZ 56.6929 746.6461 null]
+/D [1808 0 R /XYZ 85.0394 223.2897 null]
>> endobj
1852 0 obj <<
-/D [1845 0 R /XYZ 56.6929 722.5763 null]
+/D [1808 0 R /XYZ 85.0394 215.2245 null]
>> endobj
1853 0 obj <<
-/D [1845 0 R /XYZ 56.6929 716.7581 null]
+/D [1808 0 R /XYZ 85.0394 149.4956 null]
>> endobj
1854 0 obj <<
-/D [1845 0 R /XYZ 56.6929 701.9936 null]
+/D [1808 0 R /XYZ 85.0394 149.4956 null]
>> endobj
1855 0 obj <<
-/D [1845 0 R /XYZ 56.6929 698.8254 null]
+/D [1808 0 R /XYZ 85.0394 149.4956 null]
>> endobj
1856 0 obj <<
-/D [1845 0 R /XYZ 56.6929 684.1207 null]
+/D [1808 0 R /XYZ 85.0394 144.3554 null]
>> endobj
1857 0 obj <<
-/D [1845 0 R /XYZ 56.6929 680.8926 null]
+/D [1808 0 R /XYZ 85.0394 120.2857 null]
>> endobj
1858 0 obj <<
-/D [1845 0 R /XYZ 56.6929 656.8229 null]
+/D [1808 0 R /XYZ 85.0394 112.2205 null]
>> endobj
1859 0 obj <<
-/D [1845 0 R /XYZ 56.6929 651.0047 null]
+/D [1808 0 R /XYZ 85.0394 97.4559 null]
>> endobj
1860 0 obj <<
-/D [1845 0 R /XYZ 56.6929 636.3 null]
->> endobj
-1861 0 obj <<
-/D [1845 0 R /XYZ 56.6929 633.072 null]
+/D [1808 0 R /XYZ 85.0394 92.0407 null]
>> endobj
-1862 0 obj <<
-/D [1845 0 R /XYZ 56.6929 609.0023 null]
+1807 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
1863 0 obj <<
-/D [1845 0 R /XYZ 56.6929 603.184 null]
+/Length 2121
+/Filter /FlateDecode
+>>
+stream
+xÚ¥YIs㸾ûWèª*B°pÍM¶ÔŽ»=¶cy*™t÷¦`‰eŠÔˆ”»5¿>x J$5•”Äòà}x 6¢ðc#Ï'~Ä£Q¹Ä£Ì%›+:ZÁÜí34“šhbS]¿\ýí“F‰|î^Þ,Y!¡aÈF/˯Δ2 Ô¹¾»¾¿{¼}ž>ýã·ñ„{ÔùF=:}˜agñëíí|ñ27Ýçùtv÷p $l< üˆ:Ó§§ùÃìîß8?URi3z3_Œ¿¿|¾š¿4˶·Æ¨Pkþýêëw:ZÂ?_Q"¢Ðý€%,Šøhsåz‚x®õHvµ¸úg#Кլ¦b”páó[q6bŒDžÇ[Æò"â .´±_Ë"“•\âg c™ìwiu0¦ùtSönV¸Ð Ñ-*\›è±¦RKû
+Z9õ½ï§šç`/VÝPë‘¥›ñ€x<hëž›8ÍÇ—Sç!ÞHÕbÎâPVrƒ£G©™ùÏJæeZäÚL'»c!%Aø°.%û¯Àâ gF k\VYü.Ç g\GìÆ,t–¨'ÎMãÆЉ÷o›87R>Çù>Þ”VØr­hÒÀúà\¤=ê’ê
+›ª‹†ªÃ~4¨úˆÆ™îN8Zº/Û¿h†ý($Š¼ÿƒ_bÝMÖ Q?~H"\ÈK6Õ
+¸÷‹Š{Jð/qYÊŽéZA/‰E©¢
+\§Il‡·îLx‹j
+aÜo汆ÆÙ3¨¢sõd¥Ë*^ÉÛXxùÎR~ȬتýÁŠüˆ9w›m&U¿Øé½cïU¢Àâ,pò¢2ª‹ö6°L@ÎU\¿²q8.€6býN}×I?âL¥°Ž ®üHU®‹}fFµVÕx•øý}_à»*ê¬cIj†\m­17ÂÞÔ©ÏpÐƺû<3ú$)6“.|¶qžjéŒ:¯ü≀Æ2-“,N7:‡ê‰¸jH ññBçç®:s%võrá‹(+$-K¢èp
+uüa„ÄøÉÒ7YÂò°§O+|Ëô'66E^­ /œ÷z‰?Ö)\6;6jVìÙ+†ÎRZ/ÙÉT[?뙉WÃ
+BRSOÄú1£ì ô<(AD]­Xx©°óZìM¬¸¾{˜åºP¬ú\J"VßCÞäN¹Qï3;¡Ô»pý²©Î“ ì‚
+ÓÙ„õç‘A­Ç<r¦¶3´´b¡žq+êÛ–²íC@ …ñç)ÞgÈ4ÍàÂõlj¤8Nš¼ëøýût¯™ çö°KWk\F,an¨þ^¡æ9Á%@?.aÂIàG°O‹îe^×å€ÃúúdQâÚò5.«b[èhAöfúwœyüË3¤™yÂçžÒur¥kª‘)\+’ÎrÙ[tÀaUuàE›cýÿ/eU/aßU„f¿^”6 õÏ–^ÿƒu¾öÿù Þendstream
+endobj
+1862 0 obj <<
+/Type /Page
+/Contents 1863 0 R
+/Resources 1861 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1750 0 R
>> endobj
1864 0 obj <<
-/D [1845 0 R /XYZ 56.6929 579.1143 null]
+/D [1862 0 R /XYZ 56.6929 794.5015 null]
>> endobj
1865 0 obj <<
-/D [1845 0 R /XYZ 56.6929 573.2961 null]
+/D [1862 0 R /XYZ 56.6929 749.4437 null]
>> endobj
1866 0 obj <<
-/D [1845 0 R /XYZ 56.6929 558.5914 null]
+/D [1862 0 R /XYZ 56.6929 749.4437 null]
>> endobj
1867 0 obj <<
-/D [1845 0 R /XYZ 56.6929 555.3634 null]
+/D [1862 0 R /XYZ 56.6929 749.4437 null]
>> endobj
1868 0 obj <<
-/D [1845 0 R /XYZ 56.6929 540.5988 null]
+/D [1862 0 R /XYZ 56.6929 746.6461 null]
>> endobj
1869 0 obj <<
-/D [1845 0 R /XYZ 56.6929 537.4306 null]
+/D [1862 0 R /XYZ 56.6929 722.5763 null]
>> endobj
1870 0 obj <<
-/D [1845 0 R /XYZ 56.6929 510.7109 null]
+/D [1862 0 R /XYZ 56.6929 716.7581 null]
>> endobj
1871 0 obj <<
-/D [1845 0 R /XYZ 56.6929 507.5427 null]
->> endobj
-638 0 obj <<
-/D [1845 0 R /XYZ 56.6929 477.5928 null]
+/D [1862 0 R /XYZ 56.6929 701.9936 null]
>> endobj
1872 0 obj <<
-/D [1845 0 R /XYZ 56.6929 453.2532 null]
->> endobj
-642 0 obj <<
-/D [1845 0 R /XYZ 56.6929 369.7201 null]
+/D [1862 0 R /XYZ 56.6929 698.8254 null]
>> endobj
1873 0 obj <<
-/D [1845 0 R /XYZ 56.6929 345.3805 null]
+/D [1862 0 R /XYZ 56.6929 684.1207 null]
>> endobj
1874 0 obj <<
-/D [1845 0 R /XYZ 56.6929 310.6805 null]
+/D [1862 0 R /XYZ 56.6929 680.8926 null]
>> endobj
1875 0 obj <<
-/D [1845 0 R /XYZ 56.6929 310.6805 null]
+/D [1862 0 R /XYZ 56.6929 656.8229 null]
>> endobj
1876 0 obj <<
-/D [1845 0 R /XYZ 56.6929 310.6805 null]
+/D [1862 0 R /XYZ 56.6929 651.0047 null]
>> endobj
1877 0 obj <<
-/D [1845 0 R /XYZ 56.6929 310.6805 null]
+/D [1862 0 R /XYZ 56.6929 636.3 null]
>> endobj
-1844 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F14 737 0 R >>
-/ProcSet [ /PDF /Text ]
+1878 0 obj <<
+/D [1862 0 R /XYZ 56.6929 633.072 null]
+>> endobj
+1879 0 obj <<
+/D [1862 0 R /XYZ 56.6929 609.0023 null]
>> endobj
1880 0 obj <<
+/D [1862 0 R /XYZ 56.6929 603.184 null]
+>> endobj
+1881 0 obj <<
+/D [1862 0 R /XYZ 56.6929 579.1143 null]
+>> endobj
+1882 0 obj <<
+/D [1862 0 R /XYZ 56.6929 573.2961 null]
+>> endobj
+1883 0 obj <<
+/D [1862 0 R /XYZ 56.6929 558.5914 null]
+>> endobj
+1884 0 obj <<
+/D [1862 0 R /XYZ 56.6929 555.3634 null]
+>> endobj
+1885 0 obj <<
+/D [1862 0 R /XYZ 56.6929 540.5988 null]
+>> endobj
+1886 0 obj <<
+/D [1862 0 R /XYZ 56.6929 537.4306 null]
+>> endobj
+1887 0 obj <<
+/D [1862 0 R /XYZ 56.6929 510.7109 null]
+>> endobj
+1888 0 obj <<
+/D [1862 0 R /XYZ 56.6929 507.5427 null]
+>> endobj
+642 0 obj <<
+/D [1862 0 R /XYZ 56.6929 477.5928 null]
+>> endobj
+1889 0 obj <<
+/D [1862 0 R /XYZ 56.6929 453.2532 null]
+>> endobj
+646 0 obj <<
+/D [1862 0 R /XYZ 56.6929 369.7201 null]
+>> endobj
+1890 0 obj <<
+/D [1862 0 R /XYZ 56.6929 345.3805 null]
+>> endobj
+1891 0 obj <<
+/D [1862 0 R /XYZ 56.6929 310.6805 null]
+>> endobj
+1892 0 obj <<
+/D [1862 0 R /XYZ 56.6929 310.6805 null]
+>> endobj
+1893 0 obj <<
+/D [1862 0 R /XYZ 56.6929 310.6805 null]
+>> endobj
+1894 0 obj <<
+/D [1862 0 R /XYZ 56.6929 310.6805 null]
+>> endobj
+1861 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F14 741 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1897 0 obj <<
/Length 1945
/Filter /FlateDecode
>>
@@ -8151,45 +8251,45 @@ O3i_Üüá*Ü×ͶXüú€ZÿúÝ&sÎtÎí9´FöÁgDr®¸ßÏW„Ž¼hŒ8öN'?önwhÚž1öp)öU*™NʼnýSˆË±?
! ˆ(ñ7|Ùl‹²†B ù¼¬WÍn[ôeƒ•Ï×»‘Í›Öí€U¦ŽÖ
š~ã\¹ŸåcåˆÜ7ME+€a{·#¤5€×kâ¤Zë>¦=‰ÒwÇnÅÓùmOT8åꈷy‡ŽºŒü™ê°*"ÖKH,£][‡@î7ŽÈEÝ=Ãq‘Zôa›—5ðиßïj·¤å©²=#-DZ q;2.ááȈ3t€Ò-Ae³OM×Ç‚ª–·•²ò˶¬Ë1ïú]Ñ7^x ï;7á l>Tœ .ݲ1Û÷ ö¤äîµÛ4 ŠnùQŒ––auÛÑÒ£[(…_nVô-û°½„ kþ ,d`…â|O
³‰1éï\³\«XûXÌΚeyn@Çœ¥iJÿ¦ê7Í~½™8Jè8•ºvµ2eàÁÀUJÎkŒñª:àÌ›{Iôç²ßmÑl·`ý¤*kGkëýÖÕ}‡Wg$\.qU×צè‰æE¿Ûf ü=ãšR7€ÕB¹»ýB(bŠ%%}r¡h©ëCŽ8†(ÎŽ™JVÎç;C´Gˆ½ »=(½;Ф DïÀxÆØ$õÔ$ä½ ··¨X7$̉ˆnw˜‘ßêùóÆÕ4Âtò²È§9Âêp‘ÉfÚ«Lfc@¤OØð]—O®Fõšÿ³®ÊïŽè®ØU¥˜`úEÑÁiJÙMZ3{{÷ž8ò€ºm!øA÷âxR³šŒ x‰¡¾X—Lj¢7ƒw6ÏdµDãÓ*züÛ}Õ—måN£»GòcX,»nïB”Ÿø…âÀ.7€Á ³áÆN‚lF)A‘ïK¥B1”phµ$Š?(¾°© J׺E‰N¸ y,{*Œ›TCV|i@ÉsïyÍ€^5繬ª XŠ2 —Ô«‚QÕ%jUvä–¨e=á‹Â&¤ˆêk×/^à ª©žb*Ëàá$@º‘¿/šz5!÷¸Ñ‘82ÿ¿(Fd ¿éɵ1&ŒÎH>ÀŽc\|a“ŽIëë ³É®Z_Èll}@ ^ñ}Ûßè!0\E᥮þ#:ötM0!ßmzì)¢¡,<ƒyfÇ–ò}“ÍBà§ðëºÐ Õ;(P;ØZêG¨;ZZºUÖÑ:
-7Ñ[¤ʘÐ×ìbyíòTSþ*¤Ñ›þüïŸ?}øÏkx»Åb¦˜Í¬ü:5¿ßDU)ÇŸªŸ µƒ8Èa€\Ô¢7…r$sÍ´gõȇ½á'®ƒ“¶…ü¹ŒYÍu\¼œcN‘‚³N¦{ß`Bɺ½£/uµ0x÷‘¾ô{ƒo™1§tDm ¦«¢¥I¨í0ê¯ÂõMK`•{rÑè•ý!`zfó%5YH§Î-œ1ñ³¼eL–ÅBç£ëMÓÙ+5´‚çžy1W±»M—ª¢T£ªÊ!Å¢´¼:Ë/ ðw¿F“™C]ôª^®×"‡¤aÉ~\”,†Ïpî‰4êHi0Fë)šP´ƒ4ʧۻ˜@`eè¡¡„*œžõÐÈøîcäw H¨©Ômá/„íàÍ]tì¦}²÷/açïðãó˜áϲ“íÀ’yèÙÑo#\Ó/UÜœ7üÀûò¼ÿйž…endstream
+7Ñ[¤ʘÐ×ìbyíòTSþ*¤Ñ›þüïŸ?}øÏkx»Åb¦˜Í¬ü:5¿ßDU)ÇŸªŸ µƒ8Èa€\Ô¢7…r$sÍ´gõȇ½á'®ƒ“¶…ü¹ŒYÍu\¼œcN‘‚³N¦{ß`Bɺ½£/uµ0x÷‘¾ô{ƒo™1§tDm ¦«¢¥I¨í0ê¯ÂõMK`•{rÑè•ý!`zfó%5YH§Î-œ1ñ³¼eL–ÅBç£ëMÓÙ+5´‚çžy1W±»M—ª¢T£ªÊ!Å¢´¼:Ë/ ðw¿F“™C]ôª^®×"‡¤aÉ~\”,†Ïpî‰4êHi0Fë)šP´ƒ4ʧۻ˜@`eè¡¡„*œžõÐÈøîcäw H¨©Ômá/„íàÍ]tì¦}²÷/açïðãó˜áϲ“íÀ’yèÙÑo#\Ó/U<=?nø÷åyÿÑž‡endstream
endobj
-1879 0 obj <<
+1896 0 obj <<
/Type /Page
-/Contents 1880 0 R
-/Resources 1878 0 R
+/Contents 1897 0 R
+/Resources 1895 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1843 0 R
+/Parent 1750 0 R
>> endobj
-1881 0 obj <<
-/D [1879 0 R /XYZ 85.0394 794.5015 null]
+1898 0 obj <<
+/D [1896 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-646 0 obj <<
-/D [1879 0 R /XYZ 85.0394 769.5949 null]
+650 0 obj <<
+/D [1896 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1882 0 obj <<
-/D [1879 0 R /XYZ 85.0394 573.0107 null]
+1899 0 obj <<
+/D [1896 0 R /XYZ 85.0394 573.0107 null]
>> endobj
-650 0 obj <<
-/D [1879 0 R /XYZ 85.0394 573.0107 null]
+654 0 obj <<
+/D [1896 0 R /XYZ 85.0394 573.0107 null]
>> endobj
-1883 0 obj <<
-/D [1879 0 R /XYZ 85.0394 538.4209 null]
+1900 0 obj <<
+/D [1896 0 R /XYZ 85.0394 538.4209 null]
>> endobj
-1884 0 obj <<
-/D [1879 0 R /XYZ 85.0394 504.6118 null]
+1901 0 obj <<
+/D [1896 0 R /XYZ 85.0394 504.6118 null]
>> endobj
-1885 0 obj <<
-/D [1879 0 R /XYZ 85.0394 432.7569 null]
+1902 0 obj <<
+/D [1896 0 R /XYZ 85.0394 432.7569 null]
>> endobj
-1886 0 obj <<
-/D [1879 0 R /XYZ 85.0394 303.3232 null]
+1903 0 obj <<
+/D [1896 0 R /XYZ 85.0394 303.3232 null]
>> endobj
-1878 0 obj <<
-/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >>
+1895 0 obj <<
+/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1889 0 obj <<
-/Length 3825
+1906 0 obj <<
+/Length 3824
/Filter /FlateDecode
>>
stream
@@ -8208,29 +8308,29 @@ hÁáÊÙmMƒ‰ät¢¬î¦_bií´F‚JÜòzD”1¸<ÇñˆR%`”O‹2î‹R[%<wî­ús¹*VcrÌdd?)F™¦<fYWÍaÓ6
£L¨¸Â›2Ž¤Šà˜ÊjŽŠåû]>ê|“(ÑÆô®³av½Ò»^q¬$C“¡Ç|qYðw)Ð÷þæ Wr–ÇëçbÙ–Ÿ‹ÿx…f&@
Žx»k¹|t’†ó
Giß\_¾AQ?çM@#`£JU¤7ÏøJg]­T;Tˆ8I§r3À-KBnöq\‘¬ºIËlö‹;—­@‰-Úñ¦©‰ÔÙ†¿(êÓeÛ›["’¨Ò£±r™—¨\ë ›ã+‚ òŸ^ŒÕPð«ÔP%z˜¸vé^àŽÿ6u±•øȱÞæËqè"™’ð)ˆYaÆw&®úâ›!=Çoß]¼œ¿{•ŒãX€Yf¡ˆ=Ô‘¥pè'<Q šä‰ZxtüI„³5€\S!ŒÝ ƒ§2'"%Ó.ÔÃD!$`LçS€ˆøO&EÊÕ ó¿Ó,-Â9=ySÌSM}Eµ¬WŸ¼/DûÓÒÖ»áIîŠ
-/ÉpÚQœÀ¬*VË9pcÐ-Zq4õM´ÂRˆû2G„/%þçï¥_ƒk)k'¾ñ‰ $†´™)‡:Dzú-Y}ÊûXȨendstream
+/ÉpÚQœÀ¬*VË9pcÐ-Zq4õM´ÂRˆû2G„/%þçï¥_ƒk)k'¾ñ‰ $†´™)‡:„=ý–‰¿¬>åý¿°Èªendstream
endobj
-1888 0 obj <<
+1905 0 obj <<
/Type /Page
-/Contents 1889 0 R
-/Resources 1887 0 R
+/Contents 1906 0 R
+/Resources 1904 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1843 0 R
+/Parent 1750 0 R
>> endobj
-1890 0 obj <<
-/D [1888 0 R /XYZ 56.6929 794.5015 null]
+1907 0 obj <<
+/D [1905 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1891 0 obj <<
-/D [1888 0 R /XYZ 56.6929 752.1413 null]
+1908 0 obj <<
+/D [1905 0 R /XYZ 56.6929 752.1413 null]
>> endobj
-1892 0 obj <<
-/D [1888 0 R /XYZ 56.6929 501.191 null]
+1909 0 obj <<
+/D [1905 0 R /XYZ 56.6929 501.191 null]
>> endobj
-1887 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F53 1027 0 R /F11 1384 0 R >>
+1904 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F53 1032 0 R /F11 1400 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1895 0 obj <<
+1912 0 obj <<
/Length 3111
/Filter /FlateDecode
>>
@@ -8247,99 +8347,95 @@ DìáX=ÿÀZ¼àrø!öIÑAa2/jªùëï‹<£2ϳšÚ›ŠªžËêÕöͩɬÖ¤%÷K7OÕæ·å¾¬E;-9y zQEó›’Z
“]Erü<@ÊžÔßçÍêý>¯«ÍËÔ©Zê`žÐN4á“"NÜC÷S ¯¿2²³2L‘+ÑDïÐÚ÷•l¯ãÂþåCâÁYÀÚûu¬Ö#f‚Y+žÜŠ¹ñ¼»¯žÀOåäžRqä~øÆžêJMï)'åh²Å(MžUÞÒä‰öqšì©7¡)É„fˆqš±†B3–øÌ¡{+Š ´¢Ø’åë’·‚χ£=¹ä, ~Ñ4N¶Ø<
[ˆéPíµ,C–Ïx£+?gHl!Ûæ@üQÖxä³g/÷\:tÒ;r çy÷öüo¢À4ÊTà…A½²ŽÔ”Y©eëêuiqàÅB½a€“:µ`pá¥àƒ°oÂ-Å-r¡­ë,k÷½Tzèlœ»Î4çIˆƒ]Ænn§¦],/òã7<Ü
q0 9ÿÂêŽFÅà‹à¬j't¢»ïÚHzq(ãžòëÜ^K¤íI¥¡*¬a—Ö}×˪<nÛ4r„k#Hú}_wÓãqüXÇù!¡:ïݮԴ{”Ó¦U¹9N²äYå-KžhgÉžzÈ:êÁ•&ÕiÚfåîš²sJtÂtº¤ä~ÊuèKÔ[¿+uÆuVªãºÇMú4íºsÊ;®jŸp]WýÕ ·HÃ$ÝÍþ`ź"Pª°{µ?êT8…&‘Ôo8µ#uÆ©Vªµ.;ïÔsÊ;NjŸpjW½É‚¥‰G±`x uÞÜSÉ  W×ô‹ÑÍ=ÁQU–6)=ÿá×CÁƒå`ˆ.€¾öùÐMk’zÐË>±™Êª+Þöå™Ïë:çËJ?†S=i}¾”÷ùÔ´ØkxSÎH
-gˆ¯nGªïÜëÃ]51ŸVÍ›%”^ÒM‘1aúô,‹’0ÂÁ%ŠX¿ZñÝ)…"´¨"Ñ“çÉï_0[”ÌwÕæ’ñÕ±;«¤{-ÌM€P°~?Jj*Ê OóÚv1·½]q è\Ž÷f=1Ù¤;Y0®3ߤõì[!ZR¿Ö¡ÐypÖ{ òËí_×_¾.©bŸ–Oø†(3[Áƒñlé‹'«ÝsÔíÒ=ë1^Ô’½…®U¯imGì,æÈTìmŠËJœ—&)ïM%
+gˆ¯nGªïÜëÃ]51ŸVÍ›%”^ÒM‘1aúô,‹’0ÂÁ%ŠX¿ZñÝ)…"´¨"Ñ“çÉï_0[”ÌwÕæ’ñÕ±;«¤{-ÌM€P°~?Jj*Ê OóÚv1·½]q è\Ž÷f=1Ù¤;Y0®3ߤõì[!ZR¿Ö¡ÐypÖ{ òËí_×_¾.©bŸ–Oø†(3[Áƒñlé‹'«ÝsÔíÒ=ë1^Ô’½…®U¯imGì,æÈTìmŠËJœ—&)ïM%
endobj
-1894 0 obj <<
+1911 0 obj <<
/Type /Page
-/Contents 1895 0 R
-/Resources 1893 0 R
+/Contents 1912 0 R
+/Resources 1910 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1843 0 R
+/Parent 1915 0 R
>> endobj
-1896 0 obj <<
-/D [1894 0 R /XYZ 85.0394 794.5015 null]
+1913 0 obj <<
+/D [1911 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1897 0 obj <<
-/D [1894 0 R /XYZ 85.0394 679.319 null]
+1914 0 obj <<
+/D [1911 0 R /XYZ 85.0394 679.319 null]
>> endobj
-1893 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F48 950 0 R /F53 1027 0 R >>
+1910 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F48 955 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1900 0 obj <<
-/Length 2838
+1918 0 obj <<
+/Length 2837
/Filter /FlateDecode
>>
stream
-xÚ¥Z[oܺ~÷¯ØGITÞDQú éAÚS÷ÄA $~W´-D+mVÚίïð*R·=m±¢Èg8óÍ…äâ‚Þe<å)vyÁÒ ál·?\¡Ý#Œýr…-ÍGô&¤zw{õ§¿Ò|W¤'|wûÌ%R$ÞÝV_’w)N¯a”¼ÿøËõÂ3D’·77~{ÿñßðž! „’¿¿ýíóÛ¿™¾›ëÈ~ùðéúîö׫·^˜P`Œ¨’äûÕ—;´«@î_¯PJ ‘ížá¥¸(ÈîpÅ2šfŒR×Ó\}ºú§Ÿ0ÕŸ.)€e"Íã 
-š”“e5á4Ljr†SR0êÕÄÄ’š•RÓ«/mww’ûó©—Ó%c"RFhðÅwO5gOhÀSš2”‘˜ÿ­Òw÷øØÈë7TàdxÒ ’ôr®qR·æ½{ˆpòû{óüŠ2tºÆ"Ñ‹¨»ÖÐW²¯MwØÐÞ׃iÔí„Ý÷³<½\cŒ
-¸±
-= ö|FBƒ Gp>‘¡,¶¢ƒ•Bîù¨
-LÕ¢
-$ä²'û t(¿Ië€õ OÞM…Ë7vé$ƒ!ÃñÚµçjÝ£ïý-aV0bõ-ë‰jÔ« ºÊ(J>f𹆢¡iÌËC×4ÝsÈäAžNeÓÛáÑæ@à™6"ki•Æ¤þ§îÙ â"wLSyBvv¾;²<Z¡‘à¹ìÇLd»0„XE^¯Ô¡Ô°â÷çiNßöûjÝï=•÷ûý¡šy=‚ZÓ œ=Õœu 7È.¬`Þ£×+…q‹Âir<Õí`‚6t«
-2¦e„¶ßùÝz1mˆ0ý ÊØðZlÒŒŽ`Ùµ«åuF ‚¥ͳ8=öÚnÒûíòCÓW°ȘFµœitì{˜N¸˜^£ûV˾¦ÝvÍ“@ï… iHµáIŽjL¤&ööëž´Å>ð¤)ÿO
-kèH+ã¶&Pr”%šº•}¢ü×&{þ¯aÐ)dÝPðeìPmØÃQ9¶œýjŽÙä=æ˜óåq·é˜
-ŸÜ¡éœ\µ_÷¨­Vhu¢0OµŠºê}ÿgušÃT‚ê§|p2%(4e%_«Í(éúú§ô Ö÷4ƉÍËÄ‹{kî®ÝDǽ„ê¥vÛÜ?’2ƒzh\ú*‚(ÏSÆÈ…ÜR­#ÈSy}?Mù"Í趖fÎuRS¨ža ±½5ò¥²ZÒ1Ù«ën]_nëQO\³'´VzW¯×'sÇÜ7N×(ÍS Uþ¶%F¢ CX¢Ñ*ƒ)ïY‹¬[¼ÇÀ:e¾WCîΪBÑæp•‰ß§(sp2î$¼¨ú­—ûñÅìd¨.
-„.dÚjžÊãa,Ó⻎Äé6sO5ç> íà–¶mû÷a:{¨Í¶wÛ€H«.!—Ó`ko1þxÚò|½aÎRŽò )7¤Ú0Œ£ cÏzç» †Ršx›¿§š ÛÊlÊ‹%mÃœm˜³ ‹lÃüI1JF‘õëhZó0c¶d”[ó°Ð<Ìš‡Yó°ètyÛ<¬(fvÝ!Õ†yÕhžªªÕêÊfn®îZòm<Õ\‚Ø> )¥"– 0wæáÎ<<2OîÌÓ@dý>Ú‡qknì×ìS8ûðÐ>ÜÚ‡[ûäÞ>:˜ò"Í©˜TDFÃI¿ë¢u“9¢ÑbM³z8·Åv<››ò]>š ’6Ƹ²mßÈÒ6•<óxó!Z>®Wi˜«0ráâ-¤ÚP‘£2W‡õAþåv¥JÛd몴×å*-b Òøqy_5@(Ë;}Öïæj¥y¸l¯H»¥+Qp•<ËÝÁýí¡€úÄ߆‚tmÕÇAˆ„ 72Y°E<I2óˆ¿ÛZa͵ž—Ó’ ƒâ2€ &±›, {)w*êVãO`woÓ!¶gèµC™=B³^|†”«ãZƒ´Š}Êíܾ%¸ôg¨k¨Å…úçÆ…TRm ÖQÙ ïZösØŽž½Å9pí)ëßy[躛.ÕðÇ0öºM‚:]gŸZÕÐøüþÆ4ÜýPDæÏmLß8$£iq¶‰ô‚dÂÔm?ȲšÈç„þ¢8¦ê¿L¨ó²ƒÍºÈ.òu÷bµ½ø‚­™×wpé·
-‚½9Í’šcŸÏêЧ©¿-:ƒ' T°‚ÆÇ´&Î,?gêÿ7Î<&ÚªNN7ÿu»oÎÕôpQ_Å9¨‡¿ZùãðUÿ–[@Ú9çú¿ÿ”7þåå1YÆɳ>æN(¥ ŒÄÜqPJ(¤Ý¹ìÿnøþ§endstream
+xÚ¥Z[oܺ~÷¯ØGITÞ%èC‚¤9hOÝ-øA^Ѷ­´Yic8¿¾Ã«HÝö´Å>ˆ"GœáÌ7’‹w~xÇE*
+R첂¥a¾Û®ÐîÆ~¹Â–æ#zR½»½úÓ_i¶+ÒB±»}æÊS”çxw[}IÞ¥8½†Pòþã/×oˆàˆ$oon>üöþã¿á# „’¿¿ýíóÛ¿™¾›ëÈ~ùðéúîö׫·^˜P`Œ¨’äûÕ—;´«@î_¯PJ‹œïžá¥¸(ÈîpÅ8M9£Ôõ4WŸ®þé' Fõ§K
+`<O9aTAS‚2²¬&œfQÆpJ
+F½šX¾¤&G¥ÔôêKÛÝäþ|êåtɘä)#4øb‰»§š³'4`)Mâ$æ«ôÝ=>6òú Íq2<éIz9 ×8©ÛGóÞ=D8ùý½y~E®qžèEÔ]kè+Ùצ»
+lhïëÁ4êvÂîûYž^®1Æ €"C,¹}ªûéG¶D3Ý¿(•iäˆg  œ–¨VVɇòÜ ¯“äù©Þ?ÄŠ"9ȲíÕ‡  (Ð+2Î@«úóúÑÒDJÌÒ‚ˆÂÒ´ÝéP6Í‹™·—m¥$Dúø!ͨZ`-{X€*ù=PЫ•)¢ò<t‡r¨÷fV5TÕ}yßÈʬ`–
+"EK}~’­q¥O-5¥f`ùLp+õ«¶ïeyuÌ×%yîÖ×&ƹðjz5œÊ½\˜‰æ)å‚X2c^-bw`ݽy)¦Ì˹—U:ó{ë\"ÏRT |ÛCªuôTÞC•D.H8 ¾MöžjÎâ‚E
+¸Ícþ¥­GqÖÓ‡–Q’i»>€ýëØbT¤˜d|·9MgŒräá8Øi‡Î<¿"DÚÊ "M
+@ãâ]0ƒ±î½±½&Óè‰wç<ÐE0…lõ KžLQ– ¹ìÉ>ÊoÒ:`=È“wÓÜå»t¡Fà8^»ö|B­{ô]£¿%ÌêF¬¡e=Qz•A·QEÉÇÁ >×P44yy蚦{™<ÈÓ©lz;<Ú<ÓÀæ@d-­Ò8ƒÔÿÔ={A\¤ñŽi*OÈîÏÎwG§C+ôï1<—ý˜‰ì`†«£Èë•:”Vüž ‘f$Û~R­û½§ò~¿?T3¯GP«cz³§š³ŽáÙ…lÂ{ôz¥0aCMŽ§ºLІn
+”]H¹!Õ†aÕh{Ö;ßM0”Ò¬ÀÛü=Õ\€Ø6PfSX,ÁhælÃœmXdæOŠQ2Š¬_GóИ‡ó°%ó Ìš‡…æaÖ<Ìš‡E§ËÛæ`E1»°ë©6Ìã¨FóTU­VW6sûu×’m à©æÄöI)Íc ógáÌ#"ódÎ<" DÖï£}˜°öÆ>bÉ>…³í#¬}„µOæí£ƒ©(Ҍ擊hÃh¸ )b]@´n2G4Z¬iVç¶ØŽgsS¾ËGs!ãOÒÆW¶íYÚ¦’go¾"DËÇõ* u
+®’ñÌÜß.äPŸøÛPðƒ®­ú8‘äF&+¶ˆ' 7øû·­Ö\ëy9-é° 0(Žd0‰ÝdYpØK¹SQ—°2
+Óš8³tüÌÕÿoœ'xL:´Uœnþëvßœ«éᢾŠsPÿ~µòÇ;à«þ-·€´sÎõÿ)oüË!Ë cædO$ã)|,œPJ£¹ã ”PH»sÙÿmÅþ endstream
endobj
-1899 0 obj <<
+1917 0 obj <<
/Type /Page
-/Contents 1900 0 R
-/Resources 1898 0 R
+/Contents 1918 0 R
+/Resources 1916 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1843 0 R
+/Parent 1915 0 R
>> endobj
-1901 0 obj <<
-/D [1899 0 R /XYZ 56.6929 794.5015 null]
+1919 0 obj <<
+/D [1917 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1898 0 obj <<
-/Font << /F37 799 0 R /F48 950 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R >>
+1916 0 obj <<
+/Font << /F37 803 0 R /F48 955 0 R /F23 738 0 R /F21 714 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1904 0 obj <<
-/Length 3265
-/Filter /FlateDecode
->>
-stream
-xÚ­]sÛ6òÝ¿B3}¡§‚O~<äÁ©ÝœÛ4Ik§w7m(‰²9¥HU¤œº¿þv±
-9ùýâç_ùl|{Á™ÊR3û ÎD–ÉÙæBÅŒVʯTw?„½·vë”
-%Ys1ëãQPcÒRõH •°T‹#ÚwEw9W*‰ºÇ‚õ~³(v8Ž£fMkÈŸË݆ÇüÉíèzæÛmq)¢|GӲƽúÆô¹<cqª%ðŽäë|SÔ€W™0ÇÂþ1"!×ÊA\OàȘRpHX7ž©®Ïs-Ü–MÝ–+8·H£båγh›jß ±Ïæ2™”E.XfŒ´˜ï­Ü ȨXçûª£ÉS^íÝzÙÒÓIÎBþ¹¬-˜îÛ¤V?x0·¯vB‡aÛå]±)j·ß V‹¾ÈRÍ$è–;ð«¢[¾Úp€'g[O È°X /¯
-zS¨äµƒþ\V--¬‚$WÛDqùhñƒ»²j„¸û´·…ƒU³É˺¥IU¶ß҇ߚHR–ŠÄ«)R\>NÜ•J\ƒ·àb•
-!"d9K¢Ÿ0…@wë©î;ôäÒ)v9ÈOXZ0¶ãf_¯ŠÕ”ØoÉ0¼í¯šÏΦ!àÑÞí®ÝãKð!_¸taç}Aî0üI§¡™sH0ZæûÖÙcN¼uý¾/vÏ‘Û¸p°äVOÙšÀ›l­uÆÖ<”µµbU·¯¿šŒ¨¡9O8@)¥/èßT:$}*Q®­4RoliUµeS»÷ =ƒ
-GûM^ÏIëbà9æGî›èæ«|Q!". Þ`þ†A!‰ \).Nбj¨ØPq¾uG‡¥"_>ÒâðL´†æˆP9M1°aáY Õ* h×ùn`Ù
-¨’KÐ~8ÝIÕÑPSqÍ“óªÓ‡:­:*¨Î¢€Zd ®¡)d¬ W/0 ÆY‹-ìÍ…«
-×-&Ã1y
-ƒ)Ûm•?»E+l@!Ñ¡Ó!+iXuérK3Y±èÅd„Ê+t~ÅÊêóXø"èNÊÖyAHÙUj†:áC©U*›æ.a¸˜\·PŸ¶§¯TÅLÆü…T«uæJ=T¸RÝm±]§áP‰Èô<ñ
-^‚Êjûlm3À®<û—+áĪÀ1Âß¹¥Ûú 7üúü/hŽ‘Qdña÷‡÷S¼Ðkn-=êÝŒªø|µ*;H]‚mcÁÑÔãˆÒKÄ(å?¡*ƒ@“ry^úP§!@EhˇåcÞNd:’%€ã,u4¦>T¨&™©!ù¯-Ù¹„üÂ_š”X¿>Ôy·¦)±y‚}´KÞ¨?®ãÐÒk ½v`SX‰¸Í¶¬¬¡…4Gó뉆°N%Ó™Òƒ“¾Ô–,KÓtº!<_‹†[X9ËÝíÛ¯ÿuuwsZ@è1ªßy}èAÑeõ¡Ûí±é4ÿ­x~ýüéDtªÎ³ Æ< µ",VY<dÂVcØÛ,¬°µ >p©*hŒn4Â?XÓî2öÔ/Ã9ðï6£GÆçÂíÜ·ÆjÅD Tif²ÐLû²oGüc+?Kí©¹´76mE ÓßÝü×·<áZÒLM%͇ÄÖ 8Æ°ó®£ì|À·0Óe!‰…-ÎR‹øÖ6MŒ‹CIµA¨«¯&2ÙD0¡âø¥L6NC¿ÇU™@£jšßˆÈz²¥h&uh)Ú®_OÍü›"&%“™O›ÁYNv«%Sæ
-~pÛ‰‹Èý’<Ž+rTª@$
-P!~uÍÖ6ÓF™L ¹×穨1ù£
-¤´&† Ô´HÑ°»EtQ÷ GX_”Ži¬\4ÁB(KÅQø§ó)®¨ÁµçÏrdק¿÷¡÷5܇ÔùÔ§3¡Y–d^6‹¼Ã¬I`p)"<%N›-r~IM„Ë_¸ýn Ý£mâR ®/sÇý¢8p_•ö‹4¬’‡Áu›¸XŒŸki0@4H@"fþ@@À«ÊÚ¯\ÚcYm½5¬Fl0á¥(å¿åÀh IbV1µÇßÀà ÷IÑ™ø
-‰
-O½ ©¡ð°w_® ™¡ûÆ܆åÜñS‚%>•«½-• DZ¯<Ë…ã˜tÎ5kq¥}3ùƒÆ«¢]îÊ…ûü4bºÐGÅj¾hž
-üm „ wÓ’ÓïlEŽ3{ï¿Ÿ=÷¤«YqÐvÀFî³V„ wƒ¯íÝààp‡‡Hï·,Ɔ¶/ÜsÉÂmÞoÝ>«fÒ_o^MumûŸ3ž·Å‘Ž,«¼=Ö{ºi
-ßלãl›}µfl¹Wõþ”Ö#oz¬W¤wU³ ‹OÈ$¤û¹ >ƒ&Äž/«­Yè_á&Ï™û
->œ¹_¨ØE›­;¬`ÁÕ’Ôß· íðh¼1Û¢Û6Ãl­ŽëÓ· °?Ûí¶¦Q¶¿ïz¸«‚^‘RÀôK;ƒÕý¶rëä…¤UT¡é:ÝoÛMOJø¢§{0#•äò$‹pÜù©_Š)¨ÒÕä‡Bä?þÙá7r2
-?æ˜B± ž³n06¦2™àýÌMÀxendstream
+1922 0 obj <<
+/Length 3268
+/Filter /FlateDecode
+>>
+stream
+xÚ­ZÝsÛ6÷_¡™¾ÐÓ
+Á'?òàÔnÎmš¤µÓ»›¶”DÙœR¤*RNÝ¿þv±
+É3§Z‚ìȾÎ7Q d• “q,¬?^HHƵr×kdL)Ø$¬/T×—9Žn˦nËì[¤Q±rûY´Mµï
+†«Ïæ2™”U.XfŒ´+ß[½ÐQ±Î÷UG§¼Ú»ñ²¥§Óœ¥ü…sY[6ÐÝ·%h­~ðdn^í”Ͷ˻bSÔn¾W¬}•¥šIÀ–Ûð«¢[¾Ú°'{[O)È°X ¯Â¯`íTGVOÀC8V
+_п©tÈú Q®­6RoliÐUµeS»÷ =ƒS{ãXèk^åÊÍ G—öÐ>\Lã
+è6zˆ&‰AšXbŸê4•Ý×Ïuóë‚°²*ëb„Ç8e øÖóüÕX€!Èxœ %ø¸+1îÑ2uzZ6ö¹ji°*+¨eõ‰»WØH¦'`ø€Ïœ ÚEÓº™v§s»UÛ‡èd“;îJaëq¿Éë9¡.™c~侉o¾Ê.ÄÃŒßðRHbC—Ž‡;èX5dlˆAìoÝÖa¨È—48Ü¡9"UN]¼Øˆ±Œp/ˆj•…e×ùN`"ÙÀÚîpõÀê ÓåÓ»dß @Z@.룠‡ [ ÓJ{¸V¶ûÓÎÕ€A§Ü¼€éÕL{ª€éu^VãìBG•ÄçYª1ï£8FA¼“ y_c’¤!i:jtèx”v赯Š?Ü»¶Ø=Ù¼Q»´žÏÍžè
+e⛜w7?^ýôÍe¢£«ÛwŒ†ïýò‡¤
+±™”v¹Û„X>yR+…,°¯Dö$ª½sK«|§]º³bª-͹ê¶Û/úäûÅdÉ% vw:r*®yr:}ªÓÐ T:‹r‘5¸†n ˆX®^ P%8²›Ø›¡W$®[ †cò27R¶Û*vƒVÙЀD¢C§C4VÓ0êÂå–zþ°bÑ»“‘*¯Ðù+‹ç±ðEÀvÊÖyAÙUj†˜ðW©• ó‚”Ð Ü\·Ÿ¶§TÅLÆü…P«OuæH=U8R¸ºÛb9:NÃ!‘éyæjÌ}xœÖ$‰Cö?|´xF²f¸ðïn¾¦öèò”VÛgk‹väÙ¸X ;Ç ~øÎÍ(ÝÔ_¸á×àA}¼Eføx?% ¹6àÖÒ£ÚÍ(‹ÏW«²ƒÐ%Ø6&M=¾Qz…ü'€ 2¸hR.Ï¡Ou*
+÷W×lm1mÉÄ{p}ž{ ³?ºÀKŒH†üÿ¸œK[ÝÏ]Ö(²Ãe/Ž/3á/3jo‹†„ÔÉi:lhîʃ–ÊUÞÙR8˜ìN0ÁÙ+dgvqs„Ù¿‡1µ8iiR&ÿc~ÅyÉ ŒU-Íó_ØL@¢ì…Ô¹Oucž*` ?ëLϲ>¤Î#Þ“©ó€÷m½¬ö+VÖÇ%2ûÝÓ…˜‡\ôöºŸHÚPÛ'©E*|«PãÈ'ãP{A­[)
+ÜÕàÑŸS¥êûOï0+½¿ýøùáÓÍ·7wÞ¼¢Œ™éዧ„$ûÍí{XgQFåf[Ù/¹‹šµý0¾´Pµ&–âÅú‹Èü­Õî·[Hb[âÔRÝ—4\l)l[9ÁP!¥51 ¦Aº-`
+ÙŽ`:"ÂCQÊËÖ‚:\YÅTjK 3ÜEÄgâS(*<õŠ¦‚ÂÃÞ}¹6d†îs†s'O –øT®ö6YT2lǾò"NbÂœ+ÖâHû fòµWE»Ü• ÷ùi.8ÜéB%«ù¢y*ð·1pm¸“–œ~·`3rìÙsøýì¹7 ]Ί¶1rµ"m8|mχó;ü8Dz¿eWlhúÂõ1–,ÜäýÖͳ0“þxójªjÛÿœñ¼-Ž0²¬òö7vwÓ
+ßלãl›}µFl¹‡zÿ ÊaÊ‘7=Fãáî¡jtð ™„t?—Ág@Bìå²hÍBý
+'yÉÜPðyÌýBÅÚhÝ­
+ì–Z ñ}ÛÐ ¿Œ7f›tÛb˜ÍÕÂI}úÖç °Ünseëû®†»*èÞ _ڌ'/$-hBÓqº6ž¶mšž–ðE{Ð#HryRDØîüÔ/ÅdéjòCWä?þÙá7r"
+?æ„BµÌŽE7x7¦2™ýËÀqendstream
endobj
-1903 0 obj <<
+1921 0 obj <<
/Type /Page
-/Contents 1904 0 R
-/Resources 1902 0 R
+/Contents 1922 0 R
+/Resources 1920 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1907 0 R
+/Parent 1915 0 R
>> endobj
-1905 0 obj <<
-/D [1903 0 R /XYZ 85.0394 794.5015 null]
+1923 0 obj <<
+/D [1921 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1906 0 obj <<
-/D [1903 0 R /XYZ 85.0394 179.5067 null]
+1924 0 obj <<
+/D [1921 0 R /XYZ 85.0394 179.5067 null]
>> endobj
-1902 0 obj <<
-/Font << /F37 799 0 R /F48 950 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R /F21 710 0 R >>
+1920 0 obj <<
+/Font << /F37 803 0 R /F48 955 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R /F21 714 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1910 0 obj <<
+1927 0 obj <<
/Length 1912
/Filter /FlateDecode
>>
@@ -8351,47 +8447,47 @@ xÚ¥X[sÛº~ׯÐCgJ͉`Üx;oJlçøLŽãFÊ´Ç4 YœP„BRVÔNÿ{X¦$jt:=
 aWš½
Ná¸Æ~<ö¹$
ÙF¬šDÞ¶¬ÏP- HeˆTËã8¶¹½û„ï»Óº½G¯WªI¯*Uëâ•À _¶iÇ0ˆìŠ¿üû·ÏÜü犀U:d
-nþó{×mEÑÖý¦¿mò"oöçÓ1›ïK½©á|ÑŽ`$Œà1FPQ@å1ðy€‘Ü7—Óð·0šÁ©ìi8å˜îË[ôæ¢yb>N“YQVõb÷úÔŠÒ¡BS˜'l/Ó´HêzðUB,-ÚEÂû…Â'Qà· Xfº9«/Œ~¹¬p»~VƒÏÅ€p.Ù±Ææ¢Æf¿üú!H̨<Ö÷÷‹úvIÞœÕ':}ø ‹‡à­ Â0>N×»´,’—¡]$‘at‚‚ìzëaíbeX <ûnÞ™]™J»£ñS{ûd(M‘ñáÏe<ô ü9h2N2FOLo¿¾Úþ_nê".endstream
+nþó{×mEÑÖý¦¿mò"oöçÓ1›ïK½©á|ÑŽ`$Œà1FPQ@å1ðy€‘Ü7—Óð·0šÁ©ìi8å˜îË[ôæ¢yb>N“YQVõb÷úÔŠÒ¡BS˜'l/Ó´HêzðUB,-ÚEÂû…Â'Qà· Xfº9«/Œ~¹¬p»~VƒÏÅ€p.Ù±Ææ¢Æf¿üú!H̨<Ö÷÷‹úvIÞœÕ':}ø ‹‡à­ Â0>N×»´,’—¡]$‘at‚‚ìzëaíbeX <ûnÞ™]™J»£ñS{ûd(M‘ñáÏe<ô ü9h2N2ÆOLo¿¾Úþ_oB"0endstream
endobj
-1909 0 obj <<
+1926 0 obj <<
/Type /Page
-/Contents 1910 0 R
-/Resources 1908 0 R
+/Contents 1927 0 R
+/Resources 1925 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1907 0 R
+/Parent 1915 0 R
>> endobj
-1911 0 obj <<
-/D [1909 0 R /XYZ 56.6929 794.5015 null]
+1928 0 obj <<
+/D [1926 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1912 0 obj <<
-/D [1909 0 R /XYZ 56.6929 581.7741 null]
+1929 0 obj <<
+/D [1926 0 R /XYZ 56.6929 581.7741 null]
>> endobj
-1913 0 obj <<
-/D [1909 0 R /XYZ 56.6929 460.6765 null]
+1930 0 obj <<
+/D [1926 0 R /XYZ 56.6929 460.6765 null]
>> endobj
-1914 0 obj <<
-/D [1909 0 R /XYZ 56.6929 366.7195 null]
+1931 0 obj <<
+/D [1926 0 R /XYZ 56.6929 366.7195 null]
>> endobj
-1915 0 obj <<
-/D [1909 0 R /XYZ 56.6929 293.4426 null]
+1932 0 obj <<
+/D [1926 0 R /XYZ 56.6929 293.4426 null]
>> endobj
-654 0 obj <<
-/D [1909 0 R /XYZ 56.6929 247.3727 null]
+658 0 obj <<
+/D [1926 0 R /XYZ 56.6929 247.3727 null]
>> endobj
-1916 0 obj <<
-/D [1909 0 R /XYZ 56.6929 211.2315 null]
+1933 0 obj <<
+/D [1926 0 R /XYZ 56.6929 211.2315 null]
>> endobj
-1917 0 obj <<
-/D [1909 0 R /XYZ 56.6929 172.539 null]
+1934 0 obj <<
+/D [1926 0 R /XYZ 56.6929 172.539 null]
>> endobj
-1918 0 obj <<
-/D [1909 0 R /XYZ 56.6929 96.3402 null]
+1935 0 obj <<
+/D [1926 0 R /XYZ 56.6929 96.3402 null]
>> endobj
-1908 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R /F39 895 0 R >>
+1925 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F53 1032 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1921 0 obj <<
+1938 0 obj <<
/Length 4192
/Filter /FlateDecode
>>
@@ -8411,27 +8507,27 @@ VAC‡S»,Q•È/¸vR¤½Yök»)ÀòdäÓA@lžçÇ’Bþ Ô’iȧö$;hš½1 ö¼@) þéñ3a(ªÔãä' "Ñ
OˆøO´çföþþö§ïUA²$‹@d4Š†~¾õÕìáîG†þò‘N€ý£œ¡òÈþОˆ,Ü}²ŠÒvh#)*&[®J
ì`WAŠ3õÕóõ41ÒžþÀ˜¯%Ì7ÏüÌÁ¶óMŒ‚® N“:ç“Ä<d:\ó€Íu6±@1°_µšT‡ÙÅ’›ê“o:æ¤ËHÐŒoi!Ž,«ïttW¨ dÓõ¬á%,¬•, Äß^ÍšºÉ“˜Â\6©ˆçË!^Ï‚,"H¼Àö8=JMÁÕß­èmy2)$B ÷¹¥&ÈóÚ†‰>ÄÅU@¶]¹ç¸SøûUÉôõiôõ<‡LŒB²c™ˆ5ú àlèAA]½Œ‡bá;pôå&œòo6Íëø»¾Þ‰ä ³
ÓqŒ'\ò̵î9'Ýȇÿ’J§YnìÙãdªTèÔ—Xj¨}-½%Ð|¡’®œxãÄM5ghêŽ,Ó†Nì4&Ä„9<¯yšéü)S‰ÉÓxÀö÷3ç,¶?g™<^Ä[T…‰Ã¼žft†ìÏîA¦0D¬Y^|m'NX§gOür N2ÿÆ[q#Q¤-›“«p’ž
-?B£ ‚Ø{Úè€äN-(_í/ËŠéêS¦!$ë¯U~˨dÊôlÃæÉ×Öj‚ fö&4(' úuùRõ ™;‡i¿¦k~ŒðÉgêù.—Ögë¡Y¢Sm¿&%˜E%™µ£"}x•s(`Îß겉Ìss9ÛSâø®*îV¨6+*gS8`‚jÚ<D¸ŽŠ*Œð}Jzîu•o¤²`­‡N¬õÐ"ÂñÐ(é ;„h ¨4Òå~c¼á,DñÚH\CJýÕ¢" =x?~Æ8®ù_§pÿцKÿª¶‡-_às¤áª`‡Q¶žÃô`“뮿€qæ§ÏÍôÔDüm¿ý3‰þW ©.ZÕÿâH¹Eš@8#QÈa ~LzüAÅ)íÿÛ$
-üendstream
+?B£ ‚Ø{Úè€äN-(_í/ËŠéêS¦!$ë¯U~˨dÊôlÃæÉ×Öj‚ fö&4(' úuùRõ ™;‡i¿¦k~ŒðÉgêù.—Ögë¡Y¢Sm¿&%˜E%™µ£"}x•s(`Îß겉Ìss9ÛSâø®*îV¨6+*gS8`‚jÚ<D¸ŽŠ*Œð}Jzîu•o¤²`­‡N¬õÐ"ÂñÐ(é ;„h ¨4Òå~c¼á,DñÚH\CJýÕ¢" =x?~Æ8®ù_§pÿцKÿª¶‡-_às¤áª`‡Q¶žÃô`“뮿€qæ§ÏÍôÔDüm¿ý3‰þW ©.ZÕÿâH¹Eš@8#QÈa)õ˜ôøƒŠSÚÿÛ|
+þendstream
endobj
-1920 0 obj <<
+1937 0 obj <<
/Type /Page
-/Contents 1921 0 R
-/Resources 1919 0 R
+/Contents 1938 0 R
+/Resources 1936 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1907 0 R
+/Parent 1915 0 R
>> endobj
-1922 0 obj <<
-/D [1920 0 R /XYZ 85.0394 794.5015 null]
+1939 0 obj <<
+/D [1937 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1923 0 obj <<
-/D [1920 0 R /XYZ 85.0394 751.6872 null]
+1940 0 obj <<
+/D [1937 0 R /XYZ 85.0394 751.6872 null]
>> endobj
-1919 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R >>
+1936 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1926 0 obj <<
+1943 0 obj <<
/Length 1971
/Filter /FlateDecode
>>
@@ -8444,50 +8540,50 @@ xÚ½XKsÛ8¾ëWè6RÕÁƒ £ËYÍdl¯¥líV&Z„$ÖP¤†¤œñüúm
]uI7¢Ý(ñ¬¢û-ìxM’o}À&à
£áàý&ËÕ«ñÅ.XšˆoÏÄ•ø:­×ã —•kqÒÝðaÿ÷( ÖsC¶ºÎ“ºþþÊHß4˜Ø{ý£’„9ßE!´à°! Å †0JHvëÍ|ùáqñ°ZÜßyüé<ÐtA‚#(0ÇJËcs8¶œŠrË h4¹Q¹Ú:`‰e¶-ZVc š7KË8A×ÝšŽí`­Œ–‘® ÏJO_>>:†O»®£V¯el0ýxûÁXÄ…ÙkÃ8p»Ðó
n1{wïäø¤§6É1oήéew×µ—ß²Ù]®Y¤'åQ—*o€Êgáo$ §u%N«M
-{AÈf†¬ë‰ç$?Úa¹ñ‚>dICß/ÿK<Aîþè–~²î”Åiöéꆺà•XÀÕÚ•@*˜>Ýåð|T‹ý¸kàeXoЕV»E[QIw%†—uâT²®ÇuÖ
+{AÈf†¬ë‰ç$?Úa¹ñ‚>dICß/ÿK<Aîþè–~²î”Åiöéꆺà•XÀÕÚ•@*˜>Ýåð|T‹ý¸kàeXoЕV»E[QIw%†—uâT²®ÇuÖ
endobj
-1925 0 obj <<
+1942 0 obj <<
/Type /Page
-/Contents 1926 0 R
-/Resources 1924 0 R
+/Contents 1943 0 R
+/Resources 1941 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1907 0 R
+/Parent 1915 0 R
>> endobj
-1927 0 obj <<
-/D [1925 0 R /XYZ 56.6929 794.5015 null]
+1944 0 obj <<
+/D [1942 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1928 0 obj <<
-/D [1925 0 R /XYZ 56.6929 684.0716 null]
+1945 0 obj <<
+/D [1942 0 R /XYZ 56.6929 684.0716 null]
>> endobj
-1929 0 obj <<
-/D [1925 0 R /XYZ 56.6929 572.8605 null]
+1946 0 obj <<
+/D [1942 0 R /XYZ 56.6929 572.8605 null]
>> endobj
-1930 0 obj <<
-/D [1925 0 R /XYZ 56.6929 509.4701 null]
+1947 0 obj <<
+/D [1942 0 R /XYZ 56.6929 509.4701 null]
>> endobj
-658 0 obj <<
-/D [1925 0 R /XYZ 56.6929 470.2699 null]
+662 0 obj <<
+/D [1942 0 R /XYZ 56.6929 470.2699 null]
>> endobj
-1931 0 obj <<
-/D [1925 0 R /XYZ 56.6929 433.5878 null]
+1948 0 obj <<
+/D [1942 0 R /XYZ 56.6929 433.5878 null]
>> endobj
-1932 0 obj <<
-/D [1925 0 R /XYZ 56.6929 401.47 null]
+1949 0 obj <<
+/D [1942 0 R /XYZ 56.6929 401.47 null]
>> endobj
-1933 0 obj <<
-/D [1925 0 R /XYZ 56.6929 335.1577 null]
+1950 0 obj <<
+/D [1942 0 R /XYZ 56.6929 335.1577 null]
>> endobj
-1934 0 obj <<
-/D [1925 0 R /XYZ 56.6929 244.1508 null]
+1951 0 obj <<
+/D [1942 0 R /XYZ 56.6929 244.1508 null]
>> endobj
-1935 0 obj <<
-/D [1925 0 R /XYZ 56.6929 168.8052 null]
+1952 0 obj <<
+/D [1942 0 R /XYZ 56.6929 168.8052 null]
>> endobj
-1924 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >>
+1941 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F39 900 0 R /F53 1032 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1938 0 obj <<
+1955 0 obj <<
/Length 1658
/Filter /FlateDecode
>>
@@ -8503,675 +8599,570 @@ a¥Hš~Ä··ã›óË/À
¦×ã)]»Ž‘VÊÀí,1ͨ1<HuÅjÊÔÜÝ?Û뺱Ý.²¦‚ºÌÓ™;hÄÜóÊÇþÐI’$'™ùë
Uزo“Ÿ“É0Tí‘c‡ ™sâS‘Pªý™ÜZèB¯’µöÕ⺟+Ц*Ó0
-O“çj­—ŽÎà{©\­³ÍrgêŽKŸP…!§¶ãŒäÁ¸É[¦{çɽýÒ¯ÓIBù0KV7ÝUh¤ È¸ÜË"ÏNVŸ¯„pûá1ŸmëªE«¦·Øô/Ëü¥_`€"ÌÏ&9Þºúÿ:³û-Š‡ˆ)õÂGÆÜ"âA?Âö¡ ˜Ò…¢aö\Ñ™dendstream
+O“çj­—ŽÎà{©\­³ÍrgêŽKŸP…!§¶ãŒäÁ¸É[¦{çɽýÒ¯ÓIBù0KV7ÝUh¤ È¸ÜË"ÏNVŸ¯„pûá1ŸmëªE«¦·Øô/Ëü¥_`€"ÌÏ&9Þºúÿ:³û-Š‡ˆ)õÂGÆÜ"âA?"ö¡ ˜Ò…¢aö])™fendstream
endobj
-1937 0 obj <<
-/Type /Page
-/Contents 1938 0 R
-/Resources 1936 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1907 0 R
->> endobj
-1939 0 obj <<
-/D [1937 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-1940 0 obj <<
-/D [1937 0 R /XYZ 85.0394 575.4191 null]
->> endobj
-1941 0 obj <<
-/D [1937 0 R /XYZ 85.0394 427.1073 null]
->> endobj
-1942 0 obj <<
-/D [1937 0 R /XYZ 85.0394 329.3834 null]
->> endobj
-1943 0 obj <<
-/D [1937 0 R /XYZ 85.0394 262.8864 null]
->> endobj
-1944 0 obj <<
-/D [1937 0 R /XYZ 85.0394 196.3893 null]
->> endobj
-662 0 obj <<
-/D [1937 0 R /XYZ 85.0394 155.0304 null]
->> endobj
-1945 0 obj <<
-/D [1937 0 R /XYZ 85.0394 117.4002 null]
->> endobj
-1946 0 obj <<
-/D [1937 0 R /XYZ 85.0394 84.3344 null]
->> endobj
-1936 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F55 1035 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >>
-/ProcSet [ /PDF /Text ]
->> endobj
-1949 0 obj <<
-/Length 2406
-/Filter /FlateDecode
->>
-stream
-xÚ¥YÝoÛ8Ï_aà^ fù!RÒ½¥MÚdÛ:¹Úv¯ÛÅ–!²ä³äÙ¿~‡RmÚ^ààRä3CÎ'i6 ðc©ˆJy:ˆÓˆHÊä`¶º ƒ%Ì}¾`3r Qõazñþ“ˆ)IWƒé¢G+!4IØ`:ÿ9ü@"r èðz<™Ü|}¹ùãÓ÷ûo_¯>Ü|½1™$jxõðp3¾¾ûýrÄ%…%°€Òá·«ñ«¯8öp™òáÕç›Éå¯éo7ÓN¸þZ²ÿ]üüEsØÇo”ˆ4‘ƒWø „¥)¬.")ˆŒ„p#åÅäâ?ÁÞ¬Y<F ŠN„³c$•’{G"S¢æH&oU½nŠf+‚‘8Qb J¤d,ÄšÁqs ‘‹ÄŒ)«Gˆ±¢JK5¯š&Ÿžó·Å¦^•Ùc^^Ž¨a”iAß®;LÄ$J¢øêÅY¹¬7Eû´B¨Ï͈Ì-rT†¨Å$<±ä}HHH’()-êçh ÄIµ fVfM ÄS’$qjQ¿pŸ?G‹
-ß&µJÛˆÎé,Ø´08¹½ÒÆ(D<¼ž\½Ãñ1˜°èO&8ŸÀõ-¶šÃu±Ðv® 9ÇÑÛ¼,WY¥ùê:FàÌ; §¶ÍMFцŠâbúÌúþ2ËšÜ9E“WMÑ‚ç·ŒƒIššeãºÕÈ8² •‚6³G´Ïšº§ö¾¤Û>Î ¶6 ÷<këÍBuô0¨ÕºÌWyeévŠ4cëš>©Ž,À=ÍêÕÈß2j(Îóù©mé  ·ÅðÐM(ضõ*k‹YV–o8Ô˜è©{hÉÐ=»`DE¶$ÇÜ?‚*DÄ2:íþ}Ôq÷ïP^•Òwÿ”0.ãý"¥/W*IL•<-—äòüžRˆÔñž`“u>+Œµî™­Øt×8´˜Œú±¹C»ä¢û‡ÉÅå‡/'ÿbÌ…û—b–£_ÓˆR©8£ê„>Êè£
-…cF »R£_7yј)Ñ$=-\‡
-HçGc×Ê}ñ|­¨Äž3tê×*×^¬[ ‡ƒ •Ÿ!CÚfŒ uœVÒÆi˜2§[
-Ò1aqW^ûÕ££¡ÚL…ðc4Í! Œ Ækàúßûñ Žh3À@™ ØR‘Lù‘"njaÀOm9¢‡4!¸û½4ÚŒ\I¨ÛûÉa†´7ãéÝôœÝÉ
-æÇPØ@*b_²»jé§5' —pM/Ç(Cwx—
-:ÍS½--ú){É=6]´põ9ØíncUm…2hÔ¬N±,˜o±HÉÖæx¤¦{7¶±ß~ƒEΚø ‰ ðœ6ƒ>ê¸t(c‹`&U‰P{wjÏÀN•œËbyW5 õsÂ|±&¹)†ìåLw|­ÄÌÖºÏ1öÑ»I¼hå¥]eb{¹‹yHÊ7)­õXØp¯—W¦*‚žÃ-«â¯ HX†Ž˜€<”(ßé¿L¾ì²ø—ÜZ“biÍ>`Ô%¼ài13‘H‘8–g’{uÂDʘÈÓ>Ke¼õ K
-°ì«?f„­Ígù°)*Wtf¶
-}ª7­ínW«lóæS]éT¯Û¢®š½›-ÆååV—Ù®4«¯ <J çÜ•‘»×†e^’6l2•‰ ˜ÇuÃ"BádÏ覇:¡‡2ºy>ª›S,wº9`ÔMŸåçJ¦ÌÝÐo$Ýó{Ä€ÃÚÅ((«<k-;z‚,ÂN‰3'ØG?ÁeNp}¶tí?ÏKדÂíJ×Cé‚¥«'ÞŸ®XjŸ©à’»Æ×(ÉLÙ"TOšŠÈƒ/­¾æ8þ¼+d%³aª:1é™ ?«íê1·WôǼ}ÍÍ[LP WÃò3…¤®NúKi2(µ±”3¸°,²mÙâ‡É‚Ð
-ÝPWrAÁêJ.˜»·ÆÝuÝ4Åci)u˜;
-endobj
-1948 0 obj <<
+1954 0 obj <<
/Type /Page
-/Contents 1949 0 R
-/Resources 1947 0 R
+/Contents 1955 0 R
+/Resources 1953 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1907 0 R
->> endobj
-1950 0 obj <<
-/D [1948 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-1951 0 obj <<
-/D [1948 0 R /XYZ 56.6929 748.122 null]
->> endobj
-1952 0 obj <<
-/D [1948 0 R /XYZ 56.6929 665.5133 null]
->> endobj
-1953 0 obj <<
-/D [1948 0 R /XYZ 56.6929 579.9397 null]
->> endobj
-1947 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F41 935 0 R /F53 1027 0 R /F23 734 0 R /F55 1035 0 R >>
-/ProcSet [ /PDF /Text ]
+/Parent 1964 0 R
>> endobj
1956 0 obj <<
-/Length 2100
-/Filter /FlateDecode
->>
-stream
-xÚ­Y_“Ú8ŸOÁÃ=˜Ú³V²$[~$ÉÌnBr©Û«Ù<x@€kÍa3©ÙO¿­ÆÙº›y°,·ZÝ­î_w 2ÀðO‚#LS6HR†8&|°ØÞáÁ¾}¸#–&tDa—êÝüîç÷4¤(£x0_ux „… ƒùò9}ù2™Ž†ÇÁ;4 9ÆÁ§Ñôë裙û2L£`ôa2†$<"®ÈbŒ§³Ùä>üuòŸ“éðÛü—»É¼«+:ÁTÉôß»çox° ~¹Ãˆ·ÁwxÁˆ¤i4ØÞ1Ng”º™ânv÷¯–aç«^ê3§q%[Dd@J9zÆà)ŠiDµ1@‹ÉÓHé;ŸŒö ›¼ü&
-¤Ú¼dµƒ‰I`Ü#vÚ&ÖåÒÌÐC>ØærE’\€m½D!5 tÄXª•Ao9ú¢ïÍËÓ³Ø^
-çíŠËK¾—9IC.I ʾ‚=Ò—GÉ qìúž<V÷(%pÜ1é÷|#}R¦(‰Zc¢ Šal°!uÒËpÜ‘N½eꑨÊɼëúB Œ×,*—Õ\³ÉËDå?5x‘†0”{í
-j¼¢êðƒ?«ÒnßEEÄ2·;5P9hV*FÔWã&ÿxœ†Æ\,F±€ ìyÊýǯãI›Î¹•ðRuÑmÓ‚[á8vÁ}åÄkDÚœÔêÄp×¼¬ƒ›ê•õN.L±`>kx(–µª_ÔtZu «^^!êòêPÛurq
-xè±Tm<NO•Ø´£?ÚÑγQ
-QƈSg·¯šjá‚Às‚ñé>{Oˆ\sw ±‡2®Ú.å«_ø·Ö2­o2…ü Ë5”·\­åÙxx†T©o*ºîŃßïúgÒ2~½)l!_eñƒîW‘î°Hy‚YŠÆ“ÙýÓã—ùã穧=¹’À=`§ˆGiÔw9ÓbÙfdoJDQ…®gªüÑYºýî*xËìò¥TÅOiÚ5¨yš¼ ÈIÜ®(—'ß Ý1u×Cyðؘ)UâêàrÒ÷2+êªMÓ&€úäÞçPÛo®ÃÂÁ|öøáØ·)V¾\g‹c˜AÁ“5VíºUîz¨§.¶êb§Öe”jŸõÏÎÚz›/DŠ"JèõœÒ!rW›ç)Åi”véƒ÷ÒJDÊ}Ù£×û³ÅQr]´–è\¶^bÐ(!xO¸™, QVfÌvo0XìßvMµÞg»î)aªs)ý‰Ð=|àÁ+Ô$8Ø·jå P@ì”ÆÄŸ+û½F ²µ¨³=ÔÙþÅJ¦[+=X™ Ÿf£Ocn›j( D”Ò¾÷*¯*åUæžVûªÐKg#íj) Ƴ‘¾ÇeÁâ‘ö?ê)GÁƒñƒy*Öã|¥ÜVw7föAÅ6+Ãr·ãçÑ}â»4-'q]š °éÁ]•fG0€†+s$ª-ë¼É_/ß|ª+{Ïà6Fþç_Ž÷]1¨è\ìõ¯’0°4%N(¥1!üTôö7„sÙÿ(Ä7yendstream
-endobj
-1955 0 obj <<
-/Type /Page
-/Contents 1956 0 R
-/Resources 1954 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1966 0 R
+/D [1954 0 R /XYZ 85.0394 794.5015 null]
>> endobj
1957 0 obj <<
-/D [1955 0 R /XYZ 85.0394 794.5015 null]
+/D [1954 0 R /XYZ 85.0394 575.4191 null]
>> endobj
1958 0 obj <<
-/D [1955 0 R /XYZ 85.0394 752.0811 null]
+/D [1954 0 R /XYZ 85.0394 427.1073 null]
>> endobj
1959 0 obj <<
-/D [1955 0 R /XYZ 85.0394 529.0618 null]
+/D [1954 0 R /XYZ 85.0394 329.3834 null]
>> endobj
1960 0 obj <<
-/D [1955 0 R /XYZ 85.0394 453.6936 null]
->> endobj
-666 0 obj <<
-/D [1955 0 R /XYZ 85.0394 414.4777 null]
+/D [1954 0 R /XYZ 85.0394 262.8864 null]
>> endobj
1961 0 obj <<
-/D [1955 0 R /XYZ 85.0394 377.7886 null]
+/D [1954 0 R /XYZ 85.0394 196.3893 null]
+>> endobj
+666 0 obj <<
+/D [1954 0 R /XYZ 85.0394 155.0304 null]
>> endobj
1962 0 obj <<
-/D [1955 0 R /XYZ 85.0394 345.6639 null]
+/D [1954 0 R /XYZ 85.0394 117.4002 null]
>> endobj
1963 0 obj <<
-/D [1955 0 R /XYZ 85.0394 279.329 null]
->> endobj
-1964 0 obj <<
-/D [1955 0 R /XYZ 85.0394 194.9705 null]
+/D [1954 0 R /XYZ 85.0394 84.3344 null]
>> endobj
-1965 0 obj <<
-/D [1955 0 R /XYZ 85.0394 119.6023 null]
->> endobj
-1954 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >>
+1953 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F39 900 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1969 0 obj <<
-/Length 2835
+1967 0 obj <<
+/Length 2624
/Filter /FlateDecode
>>
stream
-xÚ¥Z_sã6ϧð£3³VHJ”ÄÞSº›Ý¤’½Ú¹^ÛÅ–ÍÊ’kÉIÓO J¤-Ë7;;¤È@€Ÿ0øÇ'2b%Ô$QQ —“åöŠM60÷åŠffA3õýâêæs˜LT bOk‡V°4å“Åê÷é÷ ®›~zœÏï>Î~¼ûíËÝãõŒ«TªéíׯwŸþs=’ ŒM¾}üõö'ûz­ÄôöËÝüúÏÅWw‹N,WtÎB-Ó_W¿ÿÉ&+ØÁW,Ãä >XÀ•“íU$Ã@FahGÊ«ùÕ¿;‚άY:¨
-ÎÆb@"tt‘ò@*%'‰TA”ÖÅcÝæ°©DMùw׳0VÓö%kqd]ﱃjú
-#;P\å+8Ÿ³ég#,Îbþðåvï¾ý8ûù“Ä/CÚ^HÎù4°”…X+W+
-¿ß`;Épà¥Æ(Ó‰ÐóöÙ¯ó»_ôf…»sä
- r¸Æט[$Äý?œ°Ÿ÷.§^-‚49v 4ÄSüXfRTM^ & Mѯ¹ Wù:ƒèA1À¤+ÐÒiCom“
-û›lîúº:ëø =})Œû½:ïöd¼~9äõ:ùƒ”ÍxYÂIK¥b !¢Q©,æT*Ïݯ ÃvÅz¨V÷´æD¢Ð榗c´§;¢ËçL»ÂÉe]µYQÕæhtš—úPú%{Í=œ˜6]´±µô ³tú°Æ±ª&¡ -c&tÎqß@e¨OÓ}xôÓH¼âÏ
-.á0d[ó‰Ò(×´ÈR4à[¹%vwûb›cwmä©·¸ø—ÏqXÈPaï­(Kì=Ó×^¬‰^Ý4Ås™ÿK{„:?|+ÂkWHœV˜Zøw†8k¾aœŠEŠ~uÞ|;”1ß—“ #˜J.°´ –®IBÐbIzÄò뾨lNE®ð=é¢9l·Ùž|ÞÖgÝI½Ó‰UsTnÑuqÐoH}²†9½—ýG
-LJ$ä—«ªiòå l¬i €M*™ÚÜéüÙè?Ž¦œ ÌÁ|;{0#üús9æ7x,¿/èP¤ç.›õ>)pX™£±½›-;«;¡T^(€{ÌyÍÆ(nw±øÝíë¶^ÖåÙâwD¬¾ô=–k°ðuƒ[Û¼)z+:™øƒÂ˜)*`õ¤©.<8=€¸rŸ±$Yœ§Šáƒ!|v/fÂyÇÐŒ`àXXº*ÈçYâ‡`!¥ÉžéáLîD3ø0Ñ ÚP7Ì–kPìÚr æžÈ€ kÃ'~uÅ›U€ÄÛF÷\OwGhuy­Ùc™©%©°5]w °KZF[<*ÿ
-?šÃr™CÕº±ÝŠä’õ:¨ûµ(cÁûKYçį·«üõ4£€š%‰’qá:Ô€t¾Ë€ËؗΈeöå“A¥UÌa˜'T†Ù¤nQÚ*7UWKÌIú•€Üõ¹‰&ôg¸Å©Umù˜MO“}¿+Zž ¼ô„`¥\ ëò7 ¬kÔiDiêŸ<
-9p €°0±wú$Ü_‡lÕ˜¡ö _,ss„Ò¾«Þ/ôO=<¥få¨Ç‹¦sïç:³µ°™©v¬‚Ž7BÆÇX:dGÛ%¢tÒ{÷ðO5²gš72ÂóÄÔšåK¶Ï–­ $€C r­&XÒ˜[Èk<)ÜÌ­²–ˆêGÝ>wJ·`¤¨À(²•/ÊxvEÏ8 ›=˜Mf%~`¤=Õ¥þùAòî‰Na5üDrn-¬pÞ9ð^l»b×9G“ïésì2|¼pž–GŸx"Çœs>âÆÄ›æâÃQÓîójÓ¾œÞ˜øh}D¬s"—ÿ«Ü5"Ž\ÁŽBýÍ: ûF&3b/NF?ݸh÷÷žØþÞ3H¥ F6ÝEÉÜ‹>ÁLí.µëóй:Ó
-2å{Ùò°'Ž­ýð%#ƒ©èyq•ëW9Åî°‡2·†Ó¥ZpŸž·¨Y,.</¹¨;±(c)íàÍ÷„C¿)¤údS5.– ˆå½‡€-éŸÎ=±Ü'Fa«¸äñ]IPÑϸ1
+xÚ¥Z]oÛ¸}ϯ0p_ fù!RÒ¾¥MÚdÓ:¹µ Ün·Š­ØBdÉ×’dý9¤$ʲ³À"¤ÈáÌs8<¤ÃFþØH*¢bÂ8 ’29ZlÎèh}ŸÏ˜•™8¡IWêÃüìý'Žb+®FóÇŽ®ˆÐ(b£ùòçø È9h ãËélvõqr{õãÓ·»¯_.>\}9Ÿ0Ej|q5½¼ùßù„K
+C`
+&BDA
+Ãá,±}€ƒº¾CŠSuð_¥uu>’a˜­½ÀvÀZ½N±²ÊžÓBW¹Áø9çøõ¸;gѸܠX‚Åb÷º­K¬¯#±|ÁÒêKŠ%VöY¾l=ÀÊŸ”ò<­¬…r§g1š8Ç=ÌajÆLû'•t–.öÎnƒ~hfïð+©°\¦ÚD‘.ñ3+°üöÉj‚<%íˆbÙë ¨€sa „Ô݉ÚaÖ·‰NªˆÄñÉlØ•rIú06R&M¹¤'»iŠB‚ŽåPÎë:Ç8#<8ô®‘pÏËœÐé¹7Kót¡1Ç9G|é
+"fµK¶ëlM“p¦
+ÊÆs'ûœä{[-‡¶äd Ùi8Á{ÂRƬàf_Õ¨öÁ©/Z;¦ü6»øz)ß!‹Ø
+}@‚ÈìúBNDl|9»Ð5)ÇS€©èvrlj%°“KeÇâ·d»a˜òòKöËìQc]ƒÙl,5¾Nó|bü£Î/d3›¤ÐA/&£z1+»CÌrÚ}‘t·Î"q"YQ¥E•ÕH£;" ‘Üèå £qQê2î,¹iÎ*l®¶é";Çí.õ–(PÌ.ʾdyŽÍ&Pî+³]¡ïá[–éc²Ïk«h_@ʨ°GãjàbRæNŒ‰@ HÈ›¤]në¬,g1±Ppz
+*}dÍüªLn¡¿
+ŽœvÌ 8æçP˜@,Bß³›b ÇOmV4îÀ5µ+ ]á͈ ;eQ'Y‘«Þ(Tªu¹Ï­ô:yN=9Þe V£^s‘ˆ­B[QZ§Œ´¥t\¿¬Ì°ÇepIMõfjs¿ýÖê( ô?T‘8 ƒ®Ôq4Rƒ')t«ÞÛÀI¤¢Ón9¡·¼' ÷¼ˆùnÍRC†ì#‚®øQ ™åºÎñüìJ·öÆÛQ&·w%Ûœ‡ª|H騇¦{=¼0¬jNnUd ºdY.D©Hù˜¸Ý¶§ømj‰Ö,[YØ´ڤ„ÚA<€ŽADÄ„êלÓéH€ˆ“2Y÷M*¸ùÆá&ЀÉnøCFhõLÞï²Â‘ÎIJÐu¹³×€j¿Ù$»WŸL5Ô ¯]Uïóòj¯i¶£fåÀ«‡k\Öl_ÅVi1phÃ$c¹„y<64Ò kûv¤NÄÆI™Ø<Í)“mlLƦkòs
+”)q÷Ü7’öö]bCî‚׸ÂCóа£+ÈÂðœƒ]©ã+ØH™ܾI]»ÏȃÔõ¤s-u=ônºzîÍð‰•Åö9•SpǼš¢K¦Ë’PÝi‘'¾²ñZbûSKd%¨™×jnöÜl@ýYì7:–ºé!­_Ró¦ ÔŠÁVCúáN{/[\Js‚R÷ÇÜ ~˜SJ¡ ê(VG¹ ï΂ ªÛ²ª²‡Üjj˜[
+ß­.™ã.KÃRî 3æ6·=´ÐÃÛ”V-¢ :ø-Æs„+¨ì=ÌÚG"ÎÜÃlkúâûüúãÝô“þ­õ6Mï™m´î‡¦Q´}ÆÃiOïÜXƒ]åP¯º¨WõÊó€´Mº&mŠ|LwVؼ påVL“æe«Ó›ìõãhmßZNêD;/ì/(ºÍ€tsš&ÝW3÷"‘æ}¾;€Ú£pWÜÂipí¡ã`wBëÏÃ9[aÐÿYÍ£­!‰yÄOzåd½òo.œÄ4–ž[³Ã‡²eú°_­Rg¼"Ç~Ë’è༢ÍOEÿúwþö¿‚öRtäy‹‡’À`åœÒóƒ`ÆÙþGÀ¡ï •úendstream
endobj
-1968 0 obj <<
+1966 0 obj <<
/Type /Page
-/Contents 1969 0 R
-/Resources 1967 0 R
+/Contents 1967 0 R
+/Resources 1965 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1966 0 R
+/Parent 1964 0 R
+>> endobj
+1968 0 obj <<
+/D [1966 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1969 0 obj <<
+/D [1966 0 R /XYZ 56.6929 749.0289 null]
>> endobj
1970 0 obj <<
-/D [1968 0 R /XYZ 56.6929 794.5015 null]
+/D [1966 0 R /XYZ 56.6929 675.7286 null]
>> endobj
-1967 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R >>
+1971 0 obj <<
+/D [1966 0 R /XYZ 56.6929 599.4635 null]
+>> endobj
+1965 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F41 940 0 R /F53 1032 0 R /F23 738 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1973 0 obj <<
-/Length 2183
+1974 0 obj <<
+/Length 2139
/Filter /FlateDecode
>>
stream
-xÚ¥YM{Û¸¾ûWèЃüd‰½ÉŽ’x+i¤<Ý6ña‹»©){½¿¾ ( ½­} gï|Sd„៌C˜ÊhË1LØh¹¾À£Gxöþ‚XšÀ]ª«ÅÅßßÑx$‘ä!-:¼ÂBÑ"ý>ž|ù2½½ùå2_¡Ë€a<¾Ì¾M>™½/—2OÞOç—1‰ˆk2ŽÇogóùô:˜ß¼Ÿýçólzy·øùbºhë*O0ÕZý~ñýR8ÃÏQ)Øèn0"R†£õEÄ(b¥n'¿˜_ü³eØyÚ¼êƒQ˜c!‚$cáL"NCÚÀñ~:›~è/¦oÍù?Nÿ=×'ƒ÷iM<‚§($Òàø¯•*,éP…Â8Pk¢´¨*µ ~S/-u—'—(Ž¨%^–ëM®jU±W»åRUÕÃ.Ï_. !ãŸ`_Äã¬ÖW<Þl³¢¶´‰ÙªjØ{4[åƒÙ«WÊl<”ÛµQ!:P˜bXKb•øXÀz“$É›Lÿy”oŠB&í uiØk9@;
-¢P Q>
-Z쬪“"M¶—DŒSs¹«7»‹<^¬²Êl»kRØûTuöãp™ÔYiwÛ“Âf樰
-`‘¬U/T\pˆ‡(:U—ªª–jª³R÷PˆõBu œÞ‡w { *vkµÍ–æ¦ñoµ1—
-·ã²M@vßLòÇr›Õ«u?À·5ÎÜ¡:°£øœÔÀÇbý
-—ÊÝãêLÞÒ¨ø³‡yìŽÖ°ý}49¸ý¾htÆ°eM›®µ™þ2¹ýòi:<,ôL¡{cJ x—D$×°Pf?1—˜‹à¾iU)ŒXó‰Ù5ÊR×ßÂŽ9)ì¤åbÅš]˜èHtÍŠú#Ñ#‚ÉÂ7|À©XÛØhŒ]=ÒÂÊ</ŸM“ "ÅÚ€
-ÏžË]žšý{K¾¾Sé?<:!çH„°w¦ì†Ð 1ׂfãÞ\ »a)›á³Y?¢'{5&ߟnÜi˜©¬‹œ'œ©|G>û±£$zƒ1}rÂñ°¾7Mµ`._áÈ÷'OwGÐÑSòúÉÆíØÛÕ4•è2ÂiŠÜˆ‰t¹ªçŒ=)ŒpPºª³9
-¶Äm-n˜\A¥9îh„Ÿi=(ä=Ì]%ò~ÐÙ`{>µÕròiþy8XCTÙc¡«¹®ÝB—WkB*»l’9¥®nfö‹„´ÓuVdà‘IízÞ¯êAÛKë”·I±ƒšäsÎyð§
-@'Ú:þõݵáÓ¼ôð‹ 8j üev"bÿ;»è˜8=dç70• ‰ˆÄ~òmñáó×aÃÞ@»¾-”Mó—
-Z'Û»^C«Qnël·Þ‹…ÊqWP"h[¥Я‡²€!—¹Šë(œÞmˆg0Lô¨&à\±×ç쨆±Y™¯xf½®©ÛTW—e>\ ç/E¹©²êx”„Ð#’ SǘžIRGwÈ´5½Ã-t”L4ѽgq:eº¸¥òž^׉ïArçVKs2v8‹HÑý˜—'•/é… »œÔrL='Á™ËЯC¯^n_<LY„xغjËT 2UEÔÙÚ×’G1Ô\ó|ðð (ø“q|˜KÍ÷¹à!Ë}ü›‡–ÿc»Zµ«ß<2!ðxÔÆr[$ó¿
-…asœ r¬Ê$€q5Kò~m t œˆ“)¹ÃœðøW¬öÙ‹0£Ž'6çʽÇ=ĉ§mÚÕÖ#ë0¶ÐÔëT=õÄ7f'€WÀ×ɶî‹p PÜ6 -׺]=õ*íøç0Qå¯ÏrÞÙÞKH(fòhNûPÀ"I°C©JòÚû„&¢Çò> Çe­‡R˜6«×4±+]šäfö!!„îú>Å‚\ý;”§Vá¶>þß?wí¿éBV¡Bì¿ó~.m¾ïCb•ÒÇ#§tÛÆNuÿ/<ýøÀendstream
+xÚ¥YÝsÛ6÷_¡‡>ÐÓÅ7ÁGÅVR·‰’³”¹ë¸y )Èâ”"U‘rÆýëoA
+½C×±À8ú4~´s_®SM?Ì×1I•HH2‰£Ûùb1»‰›ýþa6¿þ¶üõj¶ìÅŠN032ýuõð OVpƒ_¯0bÀmò>0"iJ'Û+.œ1?S^-®þÕ3¬v[CªL!¡hÐ%BP*)C¤H2Ê:eÀ-f÷SsßåìÖÞîfïï>‚
+àŽÀ‰ ´Š'°ŒÂyÇâß]9*2 ¢)è
+þ¡³,û±0ÿRÇL€Ü˜Nâ^Û°±­­íy0hÚ¬Zeûk¢¢•©íîЂg1‚£å¦hì´ÿÍ*÷½ÒU[ü1ͳ¶¨+ÏÎÝ Æp•“Ã@Ñv`¶•Úsníï&sOºÒû¬Õ+tÖ—1¸ †¨z; Të>4+ ð2úù“äôP‚9lâÉÛ§öT¯Y’`s9>Ö˜3`C*ÇÄÙÜàµ6«l«ÏªJšçT5¤:¯ªžê¢ªÞ<õ¨ªWÇU5:|>¤)Œ8 Ϩª:lõ¾ÈíGçìzgðâÿvñ8Ü™•Oõ¾h7Ûó
+– N¨
+P½¡`OuYÁo:Pðé±a=(Œ"–(yÑÀ ÷>ÚöX°®ë¶ÃD˜$(€Ð1À
+¥­ëòMO´â,^ªz×@xœZ:ˆM(‹ê
+\_‚bcWΉ‘Ãa‚$QÆpò»D'¬oŒâÇ7h„XŸ¥àð¦ø;ƒ<AŠbOWgY)Gb
+†öeâ=2ô÷^¬‡80£ ².öÍh^fMç)åOüf•öë~´p–
+¢/ÖeöbÌOé9Û É‚r•ñÓEù£¾´uéé%6ýèÏ~´ ”
+$y.»}ÝÖ¹‚€åé9û
+ê:û뛊¨`Âí¨V'k&é™ç&¢»ÖN™²± //ýÈ”YÙÔã—>4'O)‡Æ­ù®GËÅ݇cŸµ¼N±ñæ&Ë9c5DÖºk7ƒÿ¸Œ®‹Ýuñ1S•þ?.'!Фï*œ¡PÄ›±k»%q= lúƒA×gJz,!;a¡»ÛpK^o·ÖðQ•66àÌV—†Eï –×ÿIîŠH3¹=4­em¾9áßÝývX n›‚_Ø|ÛcKÿ‘õ¾oŠ|s¶ov¶xÔý Úø!ìBíù¹ °Å«g
+—®“Ä”Àäí”> òoµwkGÔ%IŸ½Å({#0¿%ïÑ[O‘¤ÉÛ¢õD¯eå夕 ·Ð%´WF­Š9…+åû—][?í³Ý¦k’amðÈ Ð5$†¶w ò.“RÏ‹EÏYyplëu q‚u̸µ‚ÖŽ4+Z'Ã1È?cÈ0í'IMøÁÚþÞ/¦Ÿn…‘Só±øeÚ;fÑíbú“%šÃ¥Øx±›:RØE*¤ã¾NCÜž} 3%1c!SâÞwÿï¿@ŸÕ 2¥hØ)†ºž¥Ä eG^¿©õ«x-û7ZX‰endstream
endobj
-1972 0 obj <<
+1973 0 obj <<
/Type /Page
-/Contents 1973 0 R
-/Resources 1971 0 R
+/Contents 1974 0 R
+/Resources 1972 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1966 0 R
->> endobj
-1974 0 obj <<
-/D [1972 0 R /XYZ 85.0394 794.5015 null]
+/Parent 1964 0 R
>> endobj
1975 0 obj <<
-/D [1972 0 R /XYZ 85.0394 752.3199 null]
+/D [1973 0 R /XYZ 85.0394 794.5015 null]
>> endobj
1976 0 obj <<
-/D [1972 0 R /XYZ 85.0394 504.8188 null]
+/D [1973 0 R /XYZ 85.0394 752.1618 null]
>> endobj
1977 0 obj <<
-/D [1972 0 R /XYZ 85.0394 359.3246 null]
+/D [1973 0 R /XYZ 85.0394 531.002 null]
>> endobj
1978 0 obj <<
-/D [1972 0 R /XYZ 85.0394 298.3625 null]
+/D [1973 0 R /XYZ 85.0394 468.4168 null]
>> endobj
670 0 obj <<
-/D [1972 0 R /XYZ 85.0394 260.8495 null]
+/D [1973 0 R /XYZ 85.0394 429.776 null]
>> endobj
1979 0 obj <<
-/D [1972 0 R /XYZ 85.0394 224.9084 null]
+/D [1973 0 R /XYZ 85.0394 393.3396 null]
>> endobj
1980 0 obj <<
-/D [1972 0 R /XYZ 85.0394 193.5316 null]
+/D [1973 0 R /XYZ 85.0394 361.4675 null]
>> endobj
1981 0 obj <<
-/D [1972 0 R /XYZ 85.0394 129.6476 null]
+/D [1973 0 R /XYZ 85.0394 295.9604 null]
>> endobj
-1971 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R /F48 950 0 R /F39 895 0 R /F53 1027 0 R >>
+1982 0 obj <<
+/D [1973 0 R /XYZ 85.0394 212.4297 null]
+>> endobj
+1983 0 obj <<
+/D [1973 0 R /XYZ 85.0394 107.4752 null]
+>> endobj
+1972 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F14 741 0 R /F39 900 0 R /F53 1032 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1984 0 obj <<
-/Length 3093
+1986 0 obj <<
+/Length 2949
/Filter /FlateDecode
>>
stream
-xÚ¥MwãÆíî_¡#ý±óIrÒ““u7N²Þmì¤M“h‰²ùV"‘ZÇùõŠ¤(i_k8Ä`|c(9ð/g6‰§Ü,u&¶BÚÙbs!f0÷öB2Î< ÍûX_ß_üí:¹Ø%*™Ý¯z{e±È29»_þ}'ñ%ì ¢7·ww×ßÌïnÞÞþçýíõå\f©L£«®oßÜüûr®¬
-X¸%œ6ð³x*×Kævhš“ÜüYE8$ùƒ?
-|J§±RÖúß{ç8ôu§R&³D›8ÂñMBš÷±‚kª éÎó1IŒs2;M2 MìK/aªåäÏ— «Ø–+Ök¾^Ó 8)Ë Ìœ••
-¨…­€6«~.Jî’F{~>4õzçÙW–:ØXCŸö© žÍKÈèª"äþRCzÙãÒÈó§0?-Kè |f€øvIQZƒGµÛ<ÖJÞÿø{÷îÍ|تQn|óí·ïÞÝÝ¡½§ØŸùŽòïÔM+à‡Ò+¢€( @B?B|i¾2ö«0õÓ=pö }Eï|E
-|`ÑO¼@Àš²Q­¡\6Éç©uqº¿Aa‹4Za‰¯‡>êC"Ä^\³ª³FɆ#ž %/ãpÕE&„…Èä³Å¸Ðý–£8‹äjÆyb”W+÷Vž1gŒ9MÒóTÄAÅqhÐ-½îƒ
-Àúwr!m8°âºt`Œð‡r]Ðw]ò¸ô-(œt<ĪG{½?ì3A}ãiTÿÚH>$NTõË·11Äáìdˆ“FÇ*Ù„»º1el/Âáæƒ7×Ð iA3Ëü•qöD6üiýR’ ‡yyùñ H4—3$'s•ÎÄ&ƒöp e±Ê¡…>ÂT*¡HÏôG}¬ã!¬Ãò!l5Ù3'™YïÚç];_•ëà æ]ϹÓìuXü ‹´4–Rª!ƒ¾[Õ2á.=»L„&àY$`¸0E8xA .݈À{ö
-Ò8þ«»
-ZDh£åPçÌın.´gívYùÃî[”ÌqËQYœ@|<c9=¬–°¼å<t_I,\z†d@š 9è¾À I~Ø–UÛ„+v*žê- £Ùm6ùöõÈMÝq…Å7dôáq·)ºÛz⃑‚¼ª”êî‘Î02 2gúv0¥‰ŸðœÒ§µÓÇ:®Ëk§<w¢,¶ÐV&µÓ§yë°&˜8µý)‘ ¹ûWWfäôàï+ŸÊz׬_çÁ?qŠ>á¨äJâ9oš0›3Ì;&F¡¦ë¯‰ƒ‡¢_½%.UÐù'|tï”1rv®³$vd>pôp½:¬¨›q•ÿºX‡¶"ðo9c漘6p¾¢û‚Q×€Ý œ4žlh„wY z¬ª}W¡º®"§}BO ¡l§
-˜}ˆ|g
-å×É”ÜC:ž‘’OÈ7ç
-mŸÂæ ù YÈ°ÒÎb) ®<Å\‡tȵL"˲{÷¡–fú06\hÛ}¡Í¥'ÎQZF ¡¾~6чºiÊ*À oÖpѼ·‚ƒê*Áï£Ý÷ èÓÚâÏŸ.§@jÝý
-æ1¬t+ä)…Ú|èÚØUhÓ#²Í_ŽÑÀV$Sã2>â~ä¯|oëì>Í;Ø󶄚´\¿2œÑ]óoÔ?'dðN=#ŽÈÙa°|…â¾\ÐËþg4vÿ#
+xÚ¥ZKsã6¾ûWè(Wh<>²'gì;Ù±gGšªÍfs $Jf E*"eÇùõÛ(@¢¨Ã–
+íH—!®
+Ã{ŒG‡ÂSMæ¸åÍ'¥$04Ih©†üÈß›âïü˜4zJ.‡iëP=ÄIoK„\Ä>uÓm¾(´ò5ÄrÒ`èTûÍ<ßQ¿^Q;/Z+*lù¸½æczƒã1ÌåN”¡ÊvñR‹Ü_ ±º£®{Ë| ¢eÖ¯íúv‘N|µäL¤ .¹¯ïû†“…¨/¨ÒRó–zd‡„ Çs :7ݼ}ËóŠ îÔ!IƒŽ`aB=<ºYÛ7Y8iLÖ¹ÉòQëlÇEBDàv=š²4BÍäÝæqhµ•Ûmba·A\n[» <Щ
+ô'H ®<T:þÒßiªŒi*N¯m^ÓL]v <†K=åÂé
+ŒR*-»Ìýò9¨0ј,À®ÿy~º§ ÈÿÁCf4ÅA¨ Ðñ$Šœ#
+bä>’(Öšps*OÅ~þjóð ¹I¦Åºê„ F§8Øà.9ë<Ué…ÉE ˆˆEiY÷G\2ŒC##F3€iÇ!I‰LÔ0uª‡<?äB3&>}¨žR„žzâsFÍQ Fº„
+"LênwÅ&§îJÓSoèåoŸ>Ò°P2¥Þ[Q–Ô››WЮ¼X™õê¦)æeþÔHÿ0J|+ƒGUê‰6–`ø>Cœ_©Â@` ?(¾.ê¼øv(-¾/'#
+X_ØÒ‚z¶tE2æ‹“£-¿îŠÊFVÆàƒ ß^4ûÍ&Û¯WG‘z‹áUs”tw±ÇŠÑ!d£ÈÞËÂDJÄF/—UÓä‹ È8HSO"
+p†qörƒ.ê<;”æàöb:¼ÝÕm½¨Ë³éð q‡tø”ºÞtØ#ü¸®¥¦V$Ð8i‹D$é)[Ž&ëðàÆ j“ãNKÁ2³ó«’Á$ó]ÅL8õ œ`fÊ<‰EOûFY(¥ãiS8‚;ö ´}ƒVbÃlI°Mã`îÙt­A¥§CÍÚ¦]‚ÿƒ=W÷ÝóvyÛSú‰”TÔjS0õʼÖ_É*¬Eiö‹EÙìn@Ž¥
+¸â‚;¨9¶(-Ç»Kqèȯ7Ëüõ4Æ€,&ãaâ:Tu¾ìŠ|êüB,³•O¹W½×—¡K¨ŒâKl‰Ú*×yX)ŠRor{ˆVp¡w¸Ã M-k»ÎÚpÚÈ÷k±4¯g= RÊSaÿ˜uc…: â0I|©&"{üè
+‘ÊÖ‚Óƒ^à+{xb*Ì©Ã/šN½çuf³c=Sm÷”.(a,é£ã`mÖ˜îñÿVC{7R×Îhˆî“‚Ih/Ù.[´Ú
+/e^æóýzÝUÎ4UÁ¹?ó@Ô€ÿÀé¡Šìåüßô9ü¡)ŒA—’3±¦ˆU
endobj
-1983 0 obj <<
+1985 0 obj <<
/Type /Page
-/Contents 1984 0 R
-/Resources 1982 0 R
+/Contents 1986 0 R
+/Resources 1984 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1966 0 R
->> endobj
-1985 0 obj <<
-/D [1983 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-1986 0 obj <<
-/D [1983 0 R /XYZ 56.6929 752.112 null]
+/Parent 1964 0 R
>> endobj
1987 0 obj <<
-/D [1983 0 R /XYZ 56.6929 665.106 null]
+/D [1985 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1982 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F55 1035 0 R >>
+1984 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F55 1040 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
1990 0 obj <<
-/Length 2978
+/Length 2192
/Filter /FlateDecode
>>
stream
-xÚ¥ZK“Û6¾Ï¯Ðm9UAGÇv¼N6c¯gRÙÚ8J¤FL$R©ýv£Š HªR[:l|
-)˜J¹?íÚ¬*êSÓ³T6„ õ`¬Ý?Œ¡¥¬Ö4Ù¾€s²ƒñ†Lç
-°HíðªhzÊv%”úØØyªÜ/ŽÀ¢E­^,q  CÃÆ:[oG ÌØl݈Uºó•¢ì23ªÓ~EkCŸ N@4ŽÊÒòºúGKd_}’|<Ég
-Ò‚C'­_¨Ö8SÃÀ*â0
-;Q©œÞ|úeZ³
-2Û4ÕW4ÛCÍhÖ¡ŒfïÆ4‹‰·K™š:[‚Ï(³ÝÒ¦¯caƒ!Ì2Ù¡F¸ì+Y0&QûlšÔ6bIpÿñ56â€X"¢Ó4¶]ŠÔ:ÒZ7Ú%؉ ¨<ÜàSÝ4åjWôghè%;‡™8—‚Ãt°ï6¾ýY|ŽÅR¨-4sgæ SÌš4ùw#«Dbtê‚/ΊáÉ„¦‰%TÊ´ÓºýËY!I•ÈÞ¬§ªüŠ¾ejRjº fÊYÐ(\B5^cu¨evi¨®ÆêPc‚õ–)±HÅW–w¨‘å=7%!±ö×[»Z§sÔy¹:jcžT&‘yš!dž*N .J¨<Á¼àú°iÁu¨I›ñxˆÁe|… áÀ“]”'‘χ~Fõ7$fÚ§¦ËÌ>ÿð†\§Â†Í#ÔK{ÈÖÍŒp#j®ô5áö`3Âu¨©£ãËä¡¢ô
- 5‚']R‚ðy¸/þ¶L]ÒèwÖ72žÜåÉ`B[êõv2RE\„Qþ{6RõQÓ‘ªC™HUç 2êY},Ë겺!$bžµ5›Ÿ„$PÔKå3÷ài Y£aÆäÃŒ
-Þ¾÷8—NùwC]tÉžÓD{9{wå¤lÉŒg*úý0Ñtyl7‡ãkB2å üDÎ믚Ö_‡2úûx-Ó€Šêí‰,ƒ'$ÂØYþh„?O‡Ð çHú Ê„u)„L8%Ž‰«¶¡ALRÛ)ö:ï–Æ]!©ãÒlÛ´#†þsÚq^µ¡¡3iG‚i7¤^¯'·Р7>žuXÛÍ”†
-ˆ4†¤&M‚–xóÁ¢s-Ã-¿™åve·Dq)hHqþÝ&B…ªùÁGÓÎr*g9ȇWgKkZÉ7I÷YÐYdwÈ­ˆgDOÿK"çó+’8ƒfþ#aAÆ"ÿy­
-‡”™>ê]~ÍQi¨…³¬u KÞü«,Ð#“±Çܯ“âËÆ…×Éß Ù©hŸU/.Rwû&]n×W.g,œúGähÑxFÎΈþï+ÿ—%¡LÓ‰ ¹8\ÍS(?ðCÖ»ÿ5]òþ?gvH.endstream
+xÚ¥YM{›H¾ûWè°ùÉÐÛMÓìMv”Ä“XñFʳ³›ä€¶˜A ÈϯßjúCHj„g×>Ð4EUõ[߈Œ0ü“‘dÓ8‰8B 6Z®/ðèž½¿ †&°DA—êjqñ÷wTŒbó^a)Éh‘~Oî·7¿\!Ãã+t0ŒÇ·“Ù×É'½ww‡ãÉûéü2 RD\‘q<~;›Ï§×Áüæýì?ŸgÓË‹Ÿ/¦ §XWy‚©Òê÷‹o?ð(…3ü|%=à F$ŽÃÑú"b±ˆR»S\Ì/þévž¶¯úÀ`T"&CáA#$#BPÌXx
+cDã@­ˆÒ²®³eð[öò註<yŒDD ñ²ZoŠ¬ÉjPCÄãz·\fuý°+Š—KBÈø'Ø—bœ7êŠÇ›m^6†6Ñ[u{z«zÐ{Í*ÓÕv­Uˆ¦Ö11J|,á½I’äM®þ<Jƒ7E!‹Í M¥Ù+9@;
+¢P¢Q>
+ö@V7I™&ÛK"Ç©†¹Ú5›]ŽE /Vy­·í5)Í}š•Mþãp™4yevÝIa Ó }TX
+fȶI“¥¨×wq„(åá@àu¨ZW#Q!XJÚá¥øŽ‰8J€ æ‘8/ÕQŠ=0%Á°Žø¡XeOCŽ"ln1?°LÖY/T\rˆ‡(:U—ª*G5ÕY©{¨NÄz¡: NïC
+ƒ»ƒ†=P•»u¶Í—ú¦õïl£/58nÇeۀ쾙Õ6oVë~€9$îÔ8p‡ê À–jàsR;
+ëA
+Òḇ­mÚ¤`Ì;Ú©»D]„ê‡ô=ô z¡ÝcYÙJ§öšUÒ&ªª©Å}¦
+@¯³N©®gZH‘XÛÇœ±8p…l+áHÞ¨“ƒz“-uõ×tmði­RŽßµ§†ýêþ)¯væuˆç¼þ¢™ˆ­«² NNÁ y½ggUH«Ì¼_VL€¾’“CÀVÉSÖí&ŠnîOLw³É¶ë¼®!û{q¼ªÀH ¡pCû8à£ñ(¶)À’`Ž]zÞ"Œ¹ìfr  ØXwk
+Á÷“~Öö\jQ¿¬×YÓ@u›•ËíËF=õš3¤á MíÊp7;n'×Æ=U!ª³<€ûö-3Ù'{ÊJ›ªÝãêLÞR¨ø³‡~lÖ²ý}4¸ý¾htÆ°em›®´™þ2¹½û4žj¦P½1%¼K¢’ŒXdz?ÑÁep߶ªF¬ùDïje©íoaGŸvÒj ±bÌ.ÌNT$Úf%û#Q#‚ÉÂ7|À©˜klƶ)aUQTϺÉ‘Àb­A…gÏÕ®Hõþ½!_ßeé?<:!çH†°w¦ì†Ð Ñׂvã^_ ³a(Ûá³]?¢'{µ&ߟnìi˜™©Œ‹œ'œ©|G>û±£$zƒ1}rÂñ°¾7mµ`6_áÈ÷'Ow#"èè)yýä ã¶ðv5­ÄL ´á4Å@nÄ$¶¹ªçŒ=)ŒpPºª³9
+vŒ]-vt® ±9îh„Ÿi=(ä=Ìm%ò~àˆLÐ=Ÿšj9ù4ÿ<œŒ!êü±TÕ\Õn©Ê«1!»l$’1³J]ÝÌ̉ØL×y™ƒG&íy¿d™¶]¹4Ny›”;¨I>Ða0眻€?U
+ç†w[â =ªI8—ðúœ•ÂPè•þŠ§×ûçŠÚ¥º¦ªŠáb8)«M×Ç£$„¡\œZ`&|“¤Šî)kz‡[è(™l£{ÏâtÊ´3°£òž^Õ‰oAòî–údìp‰QD÷c^‘Ô¾¤ÆHJas’ã˜z8N’3›¡_‡^½Ú¾x˜²ñйªcš 2ÍÊ4hòµ¯%Ô\,Žy>xx|‡ÅBæRý}.xÈ ÿÃæÁñt«•[ýæ‘ Ç#Ë®Hæ "œE»bën{DzÉÇ|£Í·O6«¾è/ÐÀbÔ `Ä0oq†^"iüuVÐçøuPç_ó”ö¡ÀQFá1Ç٠ǺJWó¤è×–@ʉ<‰j;Ì ÅjŸ½3
+áxb³®Ü ±€ì!O<mãVwnµíuf[ç¶ÐÍTë4{ê‰tÌN ¯‡¡o’mÓë Z!áÚǵq«'À–³UñŠ|§?#@  þt©G XFÄÒ¢T'Eãý5Åê—£££|ŽÐF§0wÖ¯hbVªJ´iNïC6Býèû( rÕ/Ržª…]¥ü¿øÚÝ…üB¥Üñ?üpÚ~釆Ä(¥ŽGH|¬ºû‰ìT÷ÿøxûendstream
endobj
1989 0 obj <<
/Type /Page
/Contents 1990 0 R
/Resources 1988 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1966 0 R
+/Parent 1964 0 R
>> endobj
1991 0 obj <<
/D [1989 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1988 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R /F53 1027 0 R >>
-/ProcSet [ /PDF /Text ]
+1992 0 obj <<
+/D [1989 0 R /XYZ 85.0394 752.3199 null]
>> endobj
-1994 0 obj <<
-/Length 2340
-/Filter /FlateDecode
->>
-stream
-xÚ¥]sÛ6òÝ¿B/RÓ%>J¬¦nÛ9ÓÞ5} %ÊâD"U“râûõ·‹(’¢Ïuô
->Ì.?ÍÞìzšŠ`öv¾˜þuóÛÙü¦¬+<$Jõ÷ÙŸE“èðÛYÄdšÄ“¯ð1ž¦b²;S±d±’ÒC¶g‹³µ;«vë˜1Tœ°X(= ¥b ð7g†s@2qÊ´²5™àc&óXh²p6TTf4—“.±–i„¥ì°4‚ÓËß7y9 ¥Hƒ»¼Ìﳦ(ïè;£áŽNÒt¹É
-‡\ç MšMN“«ë›)O‚«O7ôý9ŠdæHUnW¶Ýž½Ç]ù²²ãªvˆåŠ&«ŠÆ²jzRæh¨IÂ’ØLBÎYÇÂêã(£÷œPFà>í¤(ë|y ‚¬òm~¨Êš8œ;UÃ5SI¤¾sô¬gŽÞc¡Üÿ­ÊL&¶ùu*˜Ö&}žµGaÝuÔ0­Àq{¬o6Î
-ò¦¡†Þ×98F)E]¡]}¿±°Ï\ª±ü÷DŒ¡öÉ2ªî}Dî„ÍM¤Ÿ¶(ý\˃ì¶z€Ðr_ŽÏ«»§)ã<Qý Ðè”±1ÐÞ 
-Krð…zì½Öà€tÌÀ$f4&;F°å"†»A*Ý6,sàÏ6.OZ«¶3
-;du}Ø Û%†A“ûÿt cy M
-»—Ý­ZœH!¿ßMÝÛí”>Ù
-n
-½÷Ï?¸X¨wûm:2?ÒhÆbßf¦“Ç¢a³HùIrÑZOPk#´þ¾ºÚö@ö¢Á
-ÝL`²Ë³²)v6‘ X_¼énÅ t^®œHô.✱¥!p‚=ùÀ­g½îúe¬‹0ß…@Áîë~盬yòyηžÎ‘ ×÷mïúËüã…o‘°åYWÝ÷Q_çl¾Á ™{•~1ŸÓžÙûÅÕw_1zW|¼Š%x‘r™vo[œ©Hz½¾¸<'6©ãÖ+^ô±ÛIèCV²íX?¯lyµ#?&
-IqØ=õ7ŠŒþ÷1òHµþã¿XŽ&)¸2$‰n&f°Y{¡P9.¢ÓWåˆ ©ÅˆìÿÅhØ^endstream
-endobj
1993 0 obj <<
-/Type /Page
-/Contents 1994 0 R
-/Resources 1992 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1966 0 R
+/D [1989 0 R /XYZ 85.0394 504.8188 null]
+>> endobj
+1994 0 obj <<
+/D [1989 0 R /XYZ 85.0394 359.3246 null]
>> endobj
1995 0 obj <<
-/D [1993 0 R /XYZ 56.6929 794.5015 null]
+/D [1989 0 R /XYZ 85.0394 298.3625 null]
+>> endobj
+674 0 obj <<
+/D [1989 0 R /XYZ 85.0394 260.8495 null]
>> endobj
1996 0 obj <<
-/D [1993 0 R /XYZ 56.6929 614.1369 null]
+/D [1989 0 R /XYZ 85.0394 224.9084 null]
>> endobj
1997 0 obj <<
-/D [1993 0 R /XYZ 56.6929 339.2217 null]
+/D [1989 0 R /XYZ 85.0394 193.5316 null]
>> endobj
1998 0 obj <<
-/D [1993 0 R /XYZ 56.6929 150.6999 null]
+/D [1989 0 R /XYZ 85.0394 129.6476 null]
>> endobj
-1999 0 obj <<
-/D [1993 0 R /XYZ 56.6929 84.3474 null]
->> endobj
-1992 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R /F39 895 0 R >>
+1988 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F14 741 0 R /F48 955 0 R /F39 900 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2002 0 obj <<
-/Length 1439
+2001 0 obj <<
+/Length 2984
/Filter /FlateDecode
>>
stream
-xÚ­X[sÚ8~çWð3EÕÝò#Mh›nK²ìîL›Dp×—®mÒ¦¿~,ÉØ`Èdv§3Yþ¬sôï\bøG†J ÌB> BŽ&b¸Jxø
-… ÎN‘bÌz¼xÊòïe\FJÝ 8“®‡‰ìc–À ©à°îÕ FX€¦&í#jÖ9éÑ`ƒêeHÿŸ'Û{¿zlVßšUe¯+ÚÌS ¡$µæÜu\èU•OÚqDp$© éNÝĉ6Îx¿îû8PÉâXt¹½œ-.n¯n–W×óæ«Ž(¨BŒÑ~Q«HQPÈ
-b˜ì˼G]”MÙòUμ=®Ç0@ÖcéòÒzìbûPDéK’› ˆ<1¹ìÐB €GÕøÕ
- æíD:š9”gtGÀÛÙòîvnuóǘM?ÞÍÿÿ`l…\lK_ˆ÷uØ5Í*ªve·‘®Äuaëyá`?´oäæi­+ |‹m*=vG‚ Šqù’ y1›Ù§×ýBÖ¤°='_°À
-þ#¯ZÞe“»y]Ƕ²¹©óćñÍÕüÒ:/ÖiœArƒ|sW˜oõÆq­ Ÿ¢l%=ÞBK@TJyV% D¨º<Lï–ï¯oÏàTq•AÇÈ´ èâ HêBu‘ge^Tñ.=õ󃙋±¾Ò€ÿóOûa`
-fJe6µ($Þ)s9BÉ¡ëÍǾÿ ‘Dáendstream
+xÚ¥Z[wÛ6~÷¯Ð£|qq%‰î“[{Ótc'»Ýí¶} EÚæ‰Dº"×ýõ;ƒ ‚¢¤œ³öÁÁÌåà >cðÏg:MR#Ì,3*ÑŒëÙr}ÆfÐ÷öŒ;ž…gZ ¹¾»;ûÛ?d63‰IE:»{Œ•',Ïùì®üuþ]’&ç0›_ÞÜÞ^}¿¸}÷öæ¿n®Î<Ïx6¿øøñêæòÝÎB3`fÆæ×7?]¼'ÚÇs#æo¯nÏ¿ûñìê.6ž3‰RýqöëïlVÂ~<c‰4¹ž½À K¸1b¶>SZ&ZIé)«³Û³…½öÓIep–™Š m>ã<1Z‹HÚ$©ÒªãòêöûOï>Þ½ûpƒ«±ßì4Èf ‘&J
+Ë[6]W-]ýØüÕ6•ã—þ,K¤P|‡üÈØÊR5/ð!çø(Tj>×é±jªMÑWŽñLBESéÓ'0Ñ6ç<ŸWËÖ>K?61Êù³%·åvYÅÓ¢ •íKµé궡Žöšsr/‚º@üþ©.¤VÒÔ@*V]K­¡üØAZQC-r‘3áÔò¹zíª~1¡>¥’,å^}¿1&VN„eÛôEÝÔÍ#½Ù`0kЃ£SëÔ3ãBÞ€ú™×.ÐêzúA¬>x&ÀsãB¡ƒÚ̹…Z/Oõò‰šNÀŽÞÊjU==è¹{ƒ3¯{ÇW ês1oŸ±»X­^©Ãë‘Þ.oé¹op Ò A ÃQŸêU¹“Îó‘?¬iB`®7Öa±ÕZGJ[§KBÔ "máY2‡ˆT¹ý⃲}ÐàIÆy:KK”‚øœrbZ ¹|Œï#^àÂyÅxÊT%Æðüø”žibÊ¡VRhf’ÇSþ|Î9ŸW›úá• ìL oæ’^ÑëŠ~Kf&eNéFçp‰ãºrÖM಺Y’ý´Æ+*À(z¹*ºn,˜I“œ u\0Ï4!˜Œ¦ƒð–H²ÛçjY£“YoU‘³k»oQƒ$³ÍöaÄD˜uH:‡ KO¨sÀuDžËªóó”:y’-wè7+O c•ÊñL5T¥án@‰„º;7ÌI($ŸwA¹%P*Û(:÷Œè"ÀcÌ ÄvÈEó:ê‡)dñØa!äüî©v£øQ{]¸)î«}á,Ãú˜Èc˜ZoW}ý¼rÖîëõ±èá:É :aî×s{.kîÕ„¹MÂ…ö(Y¶kØÆ‚¡Ç§¹âÇ% \¢Åñ²¥ZŲ½Ýí'>ÐóË÷˜ºýL4€y¢Öc*˺w¹ž÷-Q)¤ a­Š=¿1Í ÿyõ ´x”„hÚ¹hôΦ:h÷Šúœ6lÝ­x~®šÒ›Zè„¥ÚŒ‘vÜM±®ÄýhÃ<è
+vx#N
+p!™§ú¨hi_69ʸdšå‘pïÛö3) ˆýD@A
+ž™(I›È`G—:q@Ã’£F•àÄŒO-~40èS也¿£>|J¦Ò]°ª ãF0ë€ëˆ]=—5ìã^¡a¯2'¦ôLSFeK´d£)ßY×öñ§¥Ï;4H6µ$ØEò(ëÔ>*iRŸ£»—}s !aó‡Œí+ru™šlß”ËO‡’Q˜úLWàVhÚ„õM³¡Öå­Øøä&ê á¦M}Z ?KºK‹úRÛd ˆ÷Žo˜”¥QÞœ
+?÷•Ãp¢¶sC„tx!•š_ýYw=•$ÐGȧ¥¶ÒàRY\lÜG€¶n¿TåA0“y––žpû!×a·\Öí»“éa×›~ð> ¥I Àqñׄ|¤!äÃņ,Ñ&ÙÌG
+4JÚ÷B™‡}õÚu¾íøed¶+¸¡¹o2 Þaí>ýR¬j0 ”Úå7ÈAUže%7Ö,a9æoCWµ Ë…©îyßµ«­_èyëzIŒÄö—Š(¸t6Æç 1?Ud—/µ¬|wü²>Çb”Ö ”ûW7?=šíúÞ‹V»ñ¿ëëËEì­—?üp}} ~.y6oÚÞ¢Ðßé¤C0ø|ãJiÆTY$òsõ­Òßú®Ÿî@²ï©msDึ9"$런‚—Ê‹‰%ó ⊵„줄 y½Jr§’ܪ$è#wúÈçßÜ 4 jýÁ'7ôèÀšÒÑØoäaÐXn7$]Ó»o?I@¤¦Ü>a af2ØÆ•(l*O«rM¿!_”Y–h ÅAäŒa£EuÉ5µÖu³uû2§ÇS»ÝP “BŸ¨AµÛ¾ìR W¬µK—~tŸ«—9bÖàFÜvÇŽå‰Ê¡Ì>Žp®#ç¹,ÂUÓ—AÊæ4 éé4¾iÀ~ü¸pkBº8eXÍ•ŠÅ øÆË…°Aø†-‹o¶Ï [„oÿ
+È„4Ly\#n u7ägqºÖñ<9«^” p±‚ f$iÏv¨ ÉŠqÐ ¤zÝ
+ždî@ŨÝq¦Å„í@)feè›°yœÛ¢V Zrµ£1ãè÷ãX¤Tb¸H©¸[$v4íË77 µâ°w⸂”3eùD¸‡'°!éÂáàÂ-$Ô–’QOY¼:žQ »Zû)iÐÒ¬¾ìŠÜ7HÔW8JáN‡‚…‚;rײz(¶«þ „Á&’€çŸ8…r†°Àe!ìaò"Í¥ÈvÛ?oûÅC½Ú1zÆ/pMÈ'iYÂ9±€¶þ—<uu;FH!K ÁŠHDðôáÁ?¾÷~,§í¿Zði{G¡Y¶›ÎY„>´VÅ[z§s‡)4Ka *ó^–8ˆ‚Â;Õf”Á9!UɾìÝ;À¨»XÚ7q±¨™ƒžÃóOÀNl~C®Ãž¸¬ç<íUµiÂLvbJÏ41eTÕò„Á6OùqS7½Ûñ —<µ§Œn»^›×g;tjè?nÜ:Õ²ÛuîÛ‰»<¡  ‡'s§/ó¨ ŠñLZGëĘSgC®#Öñ\Ö:õ©ÓEPeµ
+d?3 Yy\¶À5!\Ô<OR¨¸béþÒŒ‚tûX}©Ûm·¢K9ŸpÐɶj—I<]ç{ G³A#Óy‰=)ÆÆ}5Ì^h&—ª`ðOÄ4ØÞ¥&ô6Z,T¡à­
+tívþÀ:Ψ»q–ÿº\ù²ÂOaß
+ÇY¸!ÀµAò:U Æ8«¨=Y8P 3j̪mU!BUQÐ8¾¦J¬Û©³‡]èn‹‡¾Ú»st‹ÍyX¬½ëÌÃ]gÝ /1Æ­™Ô<°ò}©»êÀ'°š®.Ý™•»Ù´(š»SxZ)éÞº¶mÜ]kÑ”“‹wþ£ÙèŒåyU,] b?ÍÁ2µÛÁ8¤GaKáFx }gnûÖƒs{9ÿc yj_×°·ƒÖän¹ÍÒÑï«þ¥¢(pGW†Dª¨
+¾©!6ww#c…ܶô+
+ÿ÷¯“v¿ÃRàAy~à2Fd¸mBÛ …*ƒj?Ÿp¿cÚ—ý¾ÑXendstream
endobj
-2001 0 obj <<
+2000 0 obj <<
/Type /Page
-/Contents 2002 0 R
-/Resources 2000 0 R
+/Contents 2001 0 R
+/Resources 1999 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2012 0 R
+/Parent 1964 0 R
>> endobj
-2003 0 obj <<
-/D [2001 0 R /XYZ 85.0394 794.5015 null]
+2002 0 obj <<
+/D [2000 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-674 0 obj <<
-/D [2001 0 R /XYZ 85.0394 769.5949 null]
+2003 0 obj <<
+/D [2000 0 R /XYZ 56.6929 751.9327 null]
>> endobj
2004 0 obj <<
-/D [2001 0 R /XYZ 85.0394 747.1998 null]
->> endobj
-2005 0 obj <<
-/D [2001 0 R /XYZ 85.0394 709.1513 null]
+/D [2000 0 R /XYZ 56.6929 651.1304 null]
>> endobj
-2006 0 obj <<
-/D [2001 0 R /XYZ 85.0394 635.0632 null]
+1999 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F55 1040 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
2007 0 obj <<
-/D [2001 0 R /XYZ 85.0394 566.8617 null]
+/Length 3048
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ZKsã6¾ûWè¶tUÄÁ“ã¼k’]3öÔnm’%R63©ˆ”=ίßn4@IÕÔ–€F£Ñ/˜/üñE¢C&SµˆSjÆõb½»b‹èûxÅ-fé@Ë!êÍýÕ«2^¤a‰hq¿Ì•„,Iøâ>ÿ-x}{ûþæݧÿ\/…fÁ›ðz© þõúæëëíö:Áëïï®—<‰y  a ÞÝÜݽ»¼ûôñæ¿ŸoÞ_ÿqÿóÕûûŽ±!óœIä꯫ßþ`‹öðó ešèÅ3|°§©Xì®”–¡VR:Êöêîê×nÂA¯:& ¥“P -–Z…RK5.22 "XÆ
+VRÐr"|Ld…"[~¾ú õ
+˜ìãȲ‘­êŽ#â¦Ïv£;Ã3ñ(0bhÌÍPÃ;N#29»'ú,“0¹³ú΀H.‚f_¬KÔO³+8ÞŒèv*Ó~.«¼~¦6™W>—FZ@3Û†_²ÜUæ
+ *†B†ãÙYv˜så Ú*²ÓŒÉÓ[„ÔŽæVuÓU=»¢â‰(,û®v™Mg–órsj–2RRDÊh†2B`8#&°di‡tARØŒ°jRCüZ¨­Œ.°`A#ø•&<V> Ÿ†ñÓHÌ´M‡}ùð–<M„u’ÈŽv)­›á‚¥Ñb¢n7î
+LÚ&Èx ߆•.jíæp|Mì/RâBÄ8DÍœŸC™óû|)®€üb¦bCHcgùs þ¼3L8Þ#é3HõÚ˜õõÚ˜S˜»ÜÄ$µÝ! Ðï®y`Ì’º1.ÈÀ¶ 2"èv»U:dÄdCÀpdÌ×wÙty×èÎhT S¸ú?ZÞÓ/‘ª²Ï CÔ´~u(£_ûÓ%¡W)uaIYr¸»²u¡O–üŠuO`$Ø7Å1¯—TŸ@D÷Y›Q糩óI[k&íH•Õ[uÆ°SI[÷–¶Ö¨MÖ´]Q œj°2ÊJC†Ú–,†òPì²Îñ6I¡Ô–£ÿ8Tû"†}´]qìŠñ±ìKÅ
+endobj
+2006 0 obj <<
+/Type /Page
+/Contents 2007 0 R
+/Resources 2005 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2009 0 R
>> endobj
2008 0 obj <<
-/D [2001 0 R /XYZ 85.0394 495.6953 null]
->> endobj
-2009 0 obj <<
-/D [2001 0 R /XYZ 85.0394 227.6801 null]
->> endobj
-2010 0 obj <<
-/D [2001 0 R /XYZ 85.0394 156.5137 null]
+/D [2006 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2011 0 obj <<
-/D [2001 0 R /XYZ 85.0394 85.3474 null]
->> endobj
-2000 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R /F39 895 0 R >>
+2005 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2015 0 obj <<
-/Length 2415
+2012 0 obj <<
+/Length 2545
/Filter /FlateDecode
>>
stream
-xÚíZ[wÛÆ~ׯà#tŽ±ÁÞw[I•V²©O?@(Á™
-%JáÙmö>ú)t
-’èêìòüMüú/ç¯ÿúÏ·Wç§1–‚àèìúúüêÍŻӘðÈ8I¢Ë³«¿ŸýÍÍ]Ÿjýx~súáö§“óÛN°¾ð8¡FªÏ'ï?$³ tøé$AT+>{‚—a­ÉlyÂ8EœQfÊ“›“Ÿ;†½UûÑI0p‚d ‚g˜!Ê`±׈(I xVé2ÏâùC>ÿô¯ºÊn°AL’B1K|$f8ÓÎ@E’:Ñ–jÄè•ÍÏÖËÇ¢Ìívú7B¤õæ’„”~ü%-‹¬h7îÍ2-ª{÷V¯ül]}ÉWm7ßÖuéÅ
-&­œ7›ª~lŠflEŠ‘T‚΄!öf£ŽA{ÂÁ.{L‚$Æb÷YX‹0<áŸÕz§±
-ÙEë&ó• ;Y\ÌÔV¥Í„ž”*„ àZ='´‹!£ô(Feun˜+==ä••uš¹þC95”SDg˜D·EãÖ–é§|J$,¹IJª/Ò1è%Ñጬ›|±.ݾ ÛÁ ×-ÁÎU˜w¨zîrCUä¡™2ë÷±ËÍr3ƒ²zÁzµm¶ò¥Qk7J·-Ÿ5ù
-:´SÉ"4ív:ôDÉ=)vW{ÍÁ"œ;.lS,‹2µÚcè'¶‚óªÓÏG”NHˆ¦•U*º[·n¿¢u[¥åSºñ2dëå£:ׄõ
-¸2èNë¦ÍYp¯¾(eƒž×,¸&ÕÔ‘JG×uÓ6ñJ£Dã¨RßšMd2¨Ö¡‡5V‚°´ÖÚ[†Rý-ቯÕaˆ_M°g %JÓ÷ØH ‡|Ï.J9!q×-í²…–Z <þ‚Æ°+ëyºOzh†8Ãü
+xÚ­YÝsÛ6÷_¡—Nåi„â‹ùè6n.uëäFδwMh²8‘Hפì¸ýíbˆ¤h%sw£‚‹%v±Ÿ?@bÆá'fIÊÒ\æ3“k–p‘ÌV»3>»ƒ¹7gÂó,Ó¢ÏõÃÍÙ÷?)3ËYžÊtv³î­•1žebvSþ1ÿ¥ìVàó××Ëåå‹åÛ7×ÿ~w}y¾™f~ñþýåõë·¿Ÿ/d˜9Ÿÿzqýá⢽?ÏåüâÍåòüÏ›ŸÏ.o¢b}åW¨Õ_güÉg%ìáç3ÎTž%³'xáL乜íÎt¢X¢•
+”íÙòìŸqÁÞ¬ûtÊ:ÉX"u
+fÑL›4Ÿ6™`F`2š3ŽìÁdRL™,p¡É7šj–ç"›õ;˜&DªžÈ†F‰¡È·wuóp.²¹%“_-¯hð‘sUÜѸ©éùÉ>Óàic=©´}ØUuUß…©¢£Q×г­îjväAo&Ã3¦SPþ´-{\'l¸œ-Šüþ§$éq
+ÎL–'°:²´Å¶ë• 
+•°$1b¨ßo/±˜6aôB0upÔ®¨}¡¨ê¸%ˆJ%øü&8¤´ëb?v±àüeÇ(Å4—Ó~90p‹gr^¹8ª¹†™T¨“òϱ¼¾dFËt ¬¬d>°2¾ôðVÆ¡·2[ÛÑÀ4Þ½¿Áºýîà ½‡‚ãÆUl·G‹Rµ_QÕ/[ÏX—4(zÖM7Ð’’7cYb†‰Û Š£•‘¸†W
+­]íû½¦´[{‚ã§'YβTvzée§&Tú禮`/¹µGõ_²45ùI¹çXî ú–j
+ï‚R¯—4 ¸ƒPÃKâ¼}Ž6éiƒP Ës/¡¬[(× X>žÐg¡5f::!æUo'ì;èJß #µAÈ1iDNöƒÜ>¾Å”Ðö\ÌŸýËnßvÄrëY]#Ì|–!aW´€-hÊ)2P®îïO)Í+€Üò–¶w¦Xš¥²w£îUK@VKgF-‚(ˆªú±Y¹¦êèd¾mšO- 14Ë À$سÆNáo•CIÔ&*„ÆüRiN¶Ñ>p0È/¥ÓéüÂOÛ&|Zt4z½¤ç1NÐíãÀ¹î…–Û¢ã&‹"•L#¼A}» ]0¸jŠŽKR ¿ÕÅÝ”{À—©xçز p¹49Àa‘³”CÝEîoÎ)ç!À1K)›²èÙг#ôÕ0ní£PzX
+êáU¼8ÓóÚZwŸ5†bh”5M¹_Y"ôXïAAg*„/%ý¹°AÈN\ïI»vðµß,È)J¼Dm;è¥Ðqvý™'Îk¬ÛÕµ¼ùÜŠáé×71—˜GÁCG!‚Ÿ
+'éª )xëb?W·Õ¶êži2L¹¸Ÿ@7ÒÅ×·ÙŒ‰TƶÜX¿>]Ñ€ÀÕÆ®>y™ ‘vÅ'K”6^¹à[AÚ}ë¬â°²<䈆¦;)áï¤BR",í¦ðŽ'\à=ö| ƒª$"e“ãëüs»Å¿x@gsà):h ÷~ÚiOò³›&ÂPv³ïFâ’èXè&ïïmñ@ó°ðT8íW+K‡ø”÷²ÛßÂ
+$𯔚GD 2C`Ïz¡‹ëÌí è¼Ù]T
+{ä¡ fþ¾3|c „>„ œl÷Ô³x³:?¬ÑMíÐU¦£ë¢1Z¤ú¤„ŒÖ“„íá Ø?´W‡ïäNB’o$Èèá%èØÚ¢uõ/7â M`°³EÝU;WÈ$Ì/ìŠ'h[—^%ºñÁ×Ps‚{Š‰)9ÙÐíô렬ϰ
endobj
-2014 0 obj <<
+2011 0 obj <<
/Type /Page
-/Contents 2015 0 R
-/Resources 2013 0 R
+/Contents 2012 0 R
+/Resources 2010 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2012 0 R
+/Parent 2009 0 R
>> endobj
-2016 0 obj <<
-/D [2014 0 R /XYZ 56.6929 794.5015 null]
+2013 0 obj <<
+/D [2011 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-678 0 obj <<
-/D [2014 0 R /XYZ 56.6929 769.5949 null]
+2014 0 obj <<
+/D [2011 0 R /XYZ 56.6929 485.757 null]
>> endobj
-2017 0 obj <<
-/D [2014 0 R /XYZ 56.6929 748.2469 null]
+2015 0 obj <<
+/D [2011 0 R /XYZ 56.6929 207.615 null]
+>> endobj
+2010 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F55 1040 0 R /F53 1032 0 R /F48 955 0 R /F41 940 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
2018 0 obj <<
-/D [2014 0 R /XYZ 56.6929 713.4785 null]
+/Length 1499
+/Filter /FlateDecode
+>>
+stream
+xÚ½X[sÚ8~çWøfŠª»íÇ”Ð6Ý–dÙÝ™6.ˆÄ-Ø]Û$¥¿~,ÉØ `ÛÙÉLÆ–?sô+"†?Daó Œ9˜ˆ`¾îá྽é‹:аz5ë½|Í F±¤2˜-[²"„£ˆ³ÅÇþÅÍÍxryõ×`Hî¿Bƒ¡À¸ÿábrwñÞ¬Ý bÚ¿x3ž†$”Œ(Ô0‰û“‹ãËáèíxôÛèzòzp?{×ÏÃÚÆÌ´U÷>Þã`gx×Èőžá#Ç4X÷¸`HpÆÜʪ7íýÞl}­·úÈ,B"¢¡‡ JBP,íÐ!b$e5ÓñØœúâýôZŸv±‡8€¯H
+Êkø"+K5~UÛ•}ÂGð¼0YÜ&Ÿ ê@€Þ÷êjriôÄVÝbfiYI•féV-U1 Q_ese–>$Ù&YyÌ"2BTJiÅû à(Ž³€Û×##lbyœ ʱhdú†4(Še ™D!COw³·×·ç™»Ê*Udª2fL·e¥Ö¥yåY™UºYïôrĸ¤VXE46L¢âCÌfÉZ-†óG5ÿ:ϳ¥Þ«ÁL &Cž
+›“•¹ú˜Xñi6_mʼ€ º3ΫôI•0 ýÌí²¸ƒôЋ®@ëçÄÈ1/ßÌæ
+šú¢î@œXj®\q‰ÍëÔ¦e1ˆú›{Ÿ·T-ÓuºJŠÕÖõ
+endobj
+2017 0 obj <<
+/Type /Page
+/Contents 2018 0 R
+/Resources 2016 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2009 0 R
>> endobj
2019 0 obj <<
-/D [2014 0 R /XYZ 56.6929 650.1391 null]
+/D [2017 0 R /XYZ 85.0394 794.5015 null]
>> endobj
2020 0 obj <<
-/D [2014 0 R /XYZ 56.6929 514.9018 null]
+/D [2017 0 R /XYZ 85.0394 752.1815 null]
>> endobj
2021 0 obj <<
-/D [2014 0 R /XYZ 56.6929 376.6996 null]
+/D [2017 0 R /XYZ 85.0394 689.7995 null]
>> endobj
-2013 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R >>
-/ProcSet [ /PDF /Text ]
+678 0 obj <<
+/D [2017 0 R /XYZ 85.0394 651.2999 null]
+>> endobj
+2022 0 obj <<
+/D [2017 0 R /XYZ 85.0394 618.4832 null]
>> endobj
-2024 0 obj <<
-/Length 3046
-/Filter /FlateDecode
->>
-stream
-xÚÝZK—Û¶ÞϯТ Í9Š',ñ8uOÜxÒä4É‚#QO(r"Rž¸¿¾O‚IkoÚ™…@ð¸¸øî ÿd¡ÂLó…Ô LÄb½¿Â‹÷ðî›+âiVh•R}}õ×WL.4ÒÍ÷Ûd,…°Rdq¿ùeùâíÛÛ»—¯¾^Q—_£ë•ÀxùæÅÝ/¾s}o¯5]¾øæöÝõŠÈŒ R†,ÃË»on_®nþv{ó÷}w{ýÛý·W·÷‘±”y‚™áê«_~Ë ¬áÛ+Œ˜Vbñ­ébÅC‚3zª«wWÿˆ&oí§cÂL!¡¨‘e‰4†6ÏRh”1xe¤ñðÑ­¹Û®±Þ•ÕVË¥Ùf‰0ŠUriæ7#üJ)¯šu^™†§N§edBuSWÃDÅú÷ÖµïÞ¹ßÃ5QËbÝØßù´+×»ôý¶8x¦÷[Ö«7µ_À®i»:ßþë&ÐîòεÚfoWµX¢‘” th!-µ,ºIþ8–®±q_½¯Ž~‚âϲíÚ¯N‡-#»E}"SËNqøø¤¥'ÌÑ»¦Y²Lb`N!F¥°ÌMl €s,“-Ù«jÕ–UY¿ŸØ™Œ#ª8÷åõfd`Qül¯/¬ÍD`gS¶ùCedÁØÒhh*tG4@ïñs¹Û×Û€8Oeë?pÂ5‚pEÞŽ,
-PÃYÖ"ÕoC¸H&H ™‹paŠ;D0Å"\L§‹éó/¡ãØ=;×é
-Ðâ‚÷ÎdÄ|w"ìóTçyAù4€ó‹
-Ì º%Ò\|àâKEú,»ÐÿÿQ‡‚ÄòBrŸRÍhf ²šÙ\NîaG”δ“sD±äóÌEªîúÉMñSÉ!{?]K¾<”1ìŒø,1Ü'ñ̆9v <]-$AJÆ`º†“‰¹» >æèAÐåëíÈ´Dh~yHA ÍŽCÙŽvœDw±ÓDe, t¶Îmû¤á*ò¦«í
-“OVy} ÞÌ`S+³ðN©¦á©¬`Û1xcD ²o»Õˆç5›Ír©FX–®0"“!o½ïQÚ24öìØ>[èLߙ‡u/Ðé ЊEONµóàÄœÓ㵎r.›&¬Öé™ÆtÙ“ÇXè< 63ÚÆ #!uqŠ*7Eù‰‰Œí±åKöœB¨eR­4ñ¸·u¦–†mß
-E@h;%PàB[ßÓËΔxZ×x´"jÖà…íÁ‰éË]#•ë¼2çi¦ëÁÿæ~°â1?ä¬]ÊG«€R,¿¯]g´G+ñ´)Y„öЈÜ“‘ëéWE–Aµ÷MÌâ wwe^¹ž|ÖèüÕà³nwl½9dzy ¼,6eçAüª±åÔÛ—ñâ!—gøXÈæÑÚÙ²¡Ô¡l-W6”*– ¥öeCh ˆÐˆÐ.ý‡¡l(ƒFɨEÐêˆ+¦³åëÎOQµMŠ;3òÌv/–5wù‡Óªæ¾Èkw gª˜§ÇÁ•žs”§SSFž6¡8CZ^*ÿ§T3&4PYúî³b÷Y¾bì~Î×hì>`,$•Â×5à7w?ï~¸bùO÷p–YŠ“Ìh¬'í¿™¥d–"†à–v&³ÌLmõ f–T°çg–òÐÉÔÒ0>Z2ÂÅùy—`a÷dŠ Ñ48‘Åf7z xéÃ`L\s½B4—16ËY$:gm€OH)4—”òv³s®Äh/Ãz<Jå •2{Sšx6.«mü öF„i•õº:n
-÷°ñ×)ìwë ÀÄ×á+OFÏDïà¼ÊÆ¿gbX§åAúÆbã‹€°
-¼ìf.ý„ 1ÆØ]ršÞ*ŸHq!xJ©f¶*PÙ­úéójò³Œõ5ùsÎFkòÖúC'wûC'x°Ñü®}€¥¥Ï ¶wz¾/k³ÇöÓ²Ú¬}õÁDÏ’«åÝ<•ëê} LW65sØâôd)`…ûCfÓðSWðƒg›1sÇ™ŸÁ‘³ý°q¿Çz±_g3¢Á€)›®ð»Þ¹àÝ \½oe·Û»G_ýðêÆ≠‰²líVõãHª*¹³W‘LaŠ`þ¿xÆ¥áêRµ2!šÖ¦@d¦3:>Zˆd ÆÕì´‘è|Þa©&C‚dd0ñ}ô,Í>¦®vW!ç/¤=1ïó‡Ó÷· ‹záúVO4s{Ë9(=fcì=¥¹‰#Ñù̧†FSߧ7rŸ}uoâ’7àÛÜÌá/‚f}öðþª;èSjbµ ¡h˜2‹%”²¯ŠŸóþu!ugendstream
-endobj
2023 0 obj <<
-/Type /Page
-/Contents 2024 0 R
-/Resources 2022 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 2012 0 R
+/D [2017 0 R /XYZ 85.0394 583.1153 null]
+>> endobj
+2024 0 obj <<
+/D [2017 0 R /XYZ 85.0394 517.8114 null]
>> endobj
2025 0 obj <<
-/D [2023 0 R /XYZ 85.0394 794.5015 null]
+/D [2017 0 R /XYZ 85.0394 458.3941 null]
>> endobj
-2022 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R >>
-/ProcSet [ /PDF /Text ]
+2026 0 obj <<
+/D [2017 0 R /XYZ 85.0394 396.012 null]
+>> endobj
+2027 0 obj <<
+/D [2017 0 R /XYZ 85.0394 145.9047 null]
>> endobj
2028 0 obj <<
-/Length 2003
+/D [2017 0 R /XYZ 85.0394 83.5226 null]
+>> endobj
+2016 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F53 1032 0 R /F55 1040 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2031 0 obj <<
+/Length 2089
/Filter /FlateDecode
>>
stream
-xÚÝYßoÛ8~÷_a`Î"–¿E>¦Mº—E›æbgw¶Š-ÛBmÉkII»ýER–dÚ)p¸—C€h$ g†Ã3e2ÆðGÆB"©©Çš#‰Ï·#<^Á»_GÄéD^)êj½Þ¼gñX#-©Ï–[
-a¥Èx¶ø<y‹4º
-þ‘K;´“©y‘/;¯{LwìN#J»¤=¼çÒ€™¸mÊ…OqÈ GZæÞÞÞ][{ÚÍj±Íò¬¬öIUìí£‡téršÏ]Z?&ylî‰TˆJ)ùp^™H¢}bE£{õ8û÷§‡sµø¼Í«tŸ§!Óe•nÝÚ¿+ò²ØWY½=ø…5ä’:;œ"ðûÍ~ŒÝr˜F… ÄcˆÍ¨ÜÁ‹iÄ5g‡%¶|¡4¶R?ÊE±M²ü°øÝéþ2H`îG^ìʬVFP¬ -œ)$)‘¡j@ n*Ìz‡KŠ Œº&šJÁI Z¶ZyKÈàçˆõ’l¥¹šèâ‚Ä þÙ*Zf—èž[i–q§ÛÚ]ì²))„S]¤Oõ*Ú¤ÏéæçÍ.[iÕJÛ€+-äÄ_n’UÀå
-°rì÷$Ô™jæ$±—kW»ŒÜÄF²u×ʦ]ßMM³\a‹94 ˆÅx²K
-™z"~À/%S]V-š4î—½n´&Ã?Ý˳*K6®&U2\‚ À&ukºôÔå¯:Ýgi‰~¢Ç~jöÐ1w ’ª4¡â|íjy¾}ÜE[-ã7âC—Þj¢Î»ôJ—½: b ¶çò±tø¾½æ~7l\¢¡gæ}†ÝîuQ:>³…b–åîqæöÈ<Ù%O›´ÏÖÁ…D¡‚ P«ØWp›…!™4¹íf¥PÔˆ‰ØÓÙHž4ã÷EÒ=lë
-xl;õïóM]fÏö8D[R«WPÐÑ:ƒ¯u<ˆ‚s.(8rDA×eòþÿƒs„)D}]­Ó(hµšÀ=cÝÀÍažˆ0aî†GE2ŽõùøZ­@€½|±I¡i?Bšc¦C1˜Tê§bQ*áYQb¸†Žh~܈Ì[׈9ˡΛö`´6ÑîšÚekD"
-X€Í˜‡6—¡U
-áX’ã¥?ƒc…(ç¾r•@ç6Ž‰<¥ýÏYÉSYlêÊ=Ý%ÕÚÀîtuÁ1J¿R]:Zgª‹×jªË"T]RZ°ð¹¹_]Ì—8¸Ÿ¯Õ
-د.P±áI/Àió¹D»…4Â"I·Eþ¯ÒÝ™è¬hCŒ¾
+xÚÕY[sÛ¶~÷¯Ð#=¢¸À£ë¸­{N·v§¦y %ÚfB‘ŽHÙU}7Š¤H)N|δã –{ùv±ØÉ Ã™‰%šê™Ô LÄl¾<³;Xûþˆxš8Å]ªo¯¾ùŽÉ™F:¡Éìú¶ÃK!¬™]/ÞEß"…ŽŽ.NÞœ½ŽO8;ýÏïo/ÎŽc"J¢“Ë˳‹×ç¿ÇT` bŒ£7'¿œü×Í]k|vuüþúÇ£³ëV±®ò3£Õ§£wïñl6üx„ÓJÌžà#¢5-¸`HpÆÂLqtuôSË°³j_ƒ`DYBGРdFÒBÐB£„Qfá8ùåú‡·?C€œuÀó˜&ˆ
+Gv^6ÙªÌÀÕ¦n²eíN«²®VM¾^z. ”#ÆêÙpl0èÎ
+R€¢\>Ê`4¦!¹˜V©èfÝ8yyãD¥ÅSºñ:,ÖË?t¡ ëzÛ 6YÙ‚Ê¿ïÕÈæv(œ4gƒœÏ@¨Æ ‹¶7f8èÝ\ê £­;©M0J, Î«2-ŠÍ1!Ęň¶ÖX&EnÂòjVù¼ßÙ% •[(²Ç¬¨ÝôÍÆý.²Ût]4†5Þ(ç™[°H˜· :á>¡PÕºy0¨2»*/
+7ºÉÜ/D÷ÂÒÚÿ–þwÞ¬SOíP6£âvfxûf3Èâ@2€l¬5 秽z¢Ñ¯6ÖË´\[@íSß0Q«§¼6w Ø- ~A¾åŠöíq6['àlÆËuí¯yÒ&¬¦aêÆïµÔ;Ïõçšûª[²«¢Û¾í†C)Ñ™B‰!®x{«àsÉz•š€ëÞé Ñ#‹aj®ÉtÿÌzk«Ý+=ßÐ8$pPîmºTán·}h©ŒÜx1 έˆ D#"»PIh#¤ˆ<+Ó›páµÈnÖwwhѤå%È!»[š=V;kóý¤ÍÓ¶„Ú»v ÇH³:;X×é]Ñõr™®ü…Ÿ¯p”ý™7Óˆ`s«éL:T{P T—O“¸ì¹EfGä(6]‘?­óp«kËN;Š· „+Ï°T•>ŸO¢C`'dò²Ú£Ó¥šF§¥²è<î #Låt@d ÙC#Áð@äXì@Q·yÆ•Sù Ú+¨kpòœz‹i*Ž[2Uw«tùœð$Ö“ò€:T{¨¬>ì8€!F¥Þ/2ˆìõ@
+þ¬/Ò}öj‹ß®3Æoñ]©™.Īõª4¹=‰¼çBˆ¤uSOƒŠá¬‰>
endobj
-2027 0 obj <<
+2030 0 obj <<
/Type /Page
-/Contents 2028 0 R
-/Resources 2026 0 R
+/Contents 2031 0 R
+/Resources 2029 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2012 0 R
->> endobj
-2029 0 obj <<
-/D [2027 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-2030 0 obj <<
-/D [2027 0 R /XYZ 56.6929 752.1483 null]
->> endobj
-2031 0 obj <<
-/D [2027 0 R /XYZ 56.6929 689.4255 null]
+/Parent 2009 0 R
>> endobj
2032 0 obj <<
-/D [2027 0 R /XYZ 56.6929 626.7027 null]
->> endobj
-682 0 obj <<
-/D [2027 0 R /XYZ 56.6929 587.9664 null]
+/D [2030 0 R /XYZ 56.6929 794.5015 null]
>> endobj
2033 0 obj <<
-/D [2027 0 R /XYZ 56.6929 555.0457 null]
+/D [2030 0 R /XYZ 56.6929 751.9898 null]
+>> endobj
+682 0 obj <<
+/D [2030 0 R /XYZ 56.6929 712.1227 null]
>> endobj
2034 0 obj <<
-/D [2027 0 R /XYZ 56.6929 519.5738 null]
+/D [2030 0 R /XYZ 56.6929 678.7055 null]
>> endobj
2035 0 obj <<
-/D [2027 0 R /XYZ 56.6929 453.9292 null]
+/D [2030 0 R /XYZ 56.6929 642.737 null]
>> endobj
2036 0 obj <<
-/D [2027 0 R /XYZ 56.6929 370.2609 null]
+/D [2030 0 R /XYZ 56.6929 575.4649 null]
>> endobj
2037 0 obj <<
-/D [2027 0 R /XYZ 56.6929 265.1402 null]
+/D [2030 0 R /XYZ 56.6929 435.4781 null]
>> endobj
-2026 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R >>
+2038 0 obj <<
+/D [2030 0 R /XYZ 56.6929 292.5265 null]
+>> endobj
+2029 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2040 0 obj <<
-/Length 2882
-/Filter /FlateDecode
->>
-stream
-xÚÅZmÛ6þ¾¿ÂÀ}8-P+|§„;°I¶ÁÍ^®Ùâ
-´ý •µ»jdɵ¤lr¿þf8¤,Ù²Ý"-š
-Í=×}Õ•›Ê½z÷}ë«žOP7µ›"/Á}D±òà3±z)3ƒtu¶.æPl)S%÷°æ¹tùP»Ã ૱ÀI»b».ëÂw?ùFݯï]úW´¤Eù©gãñ¥¨;ê Ä|g7§ÙqJô,wàíÍõ”žiéWëëÌå ¤¡šÔ0Ùàxcvm· xâ.¾òe‰/u ûU~F°;±‰Œce(cîÒ»]G–Æ ró™pQÇ@åÂqs67Ͷ;ŒF'JŸ–+ÍÈ5­? m
-³'Ø·eÛõ®t_ûb[?äÛÏ‚€µb‹;ªóiðÆ[Ù–3î8°¦Þ±*2PÏíH$ׂ³À1›jkc©RqÚ¦cªã6¨œMÀ3±M@'— D3KNJ[ÃÍtÉÿ^ZmËÎ+%”‰Øöe¢Sc—u`Ö2oOÔî\i@±+Ý›~Îp2"ÇpO|¡øTv
-çàW)ÔÁZGØ4ý-é^&îÐy$árÀî1'Ž‹4/ß 3öj‡ ÝRõº4cµø„þ z4¤"¦Rã6~;R6 H¤d±–"¤ø_. ‡r~iDt} `*…N
-Š§”k·øâ×…[!•D5j»Ýî´à:^ܬÅâu{ZŒ·8/ǬݾŒ›ŽjiÂ@‚õ@g'
-$5›®$ÛZ\&Zge]}öã~¬ì.ÚŽÞ¨NµÑË›Û×4'¥ŽUq)YôñR訨È~ä´À >Ó$h õþº¹äÚÏ[ÍåPΪOYýèŠ5xq'^xfôxè»~[P{[TE¥6p=pW…éW‚£ŒâË|L&ПÌ-ww_KdçSe"8€‡ä
-@­²sÓ<#ÓÑÔáÙR1…W ÃÀ,bâáEbIbK)±±7'©±9‚ìšq8ò”¹²0Z?ôõÜyæ¢ÉÜ°wT½Qmªêýø
-ÒXõÙÝáhûjÛ5\½»‰©÷æ’G5Q%~má ãWl‹Î/…IpF±ÏO¨'ÅŒ+âAu*väMúxìáèý^~@õµÔ&M<AÏnÜíi¼£ÕÀ½Í½Slºfëgû«©}éÈ(c˜}‡Å3´H.ÀØ嶩×îXˆ”Î?`ðCí²ðsMÝîü Ým¿Ù S*ù ÃSÃm+úãœâaÎÎ
-ª1
-½¥€l”¨Äî¹ó/WM p…•V׆’«£ƒwä|
-»úseÖ8­|aªúkë,¡ @JØ™¯D•«³º™:+áHŒ½*·EÞáin?*P›‘r1^ö°Ê
-T3ÒM\L Hòå'⽢˓ÆÃ…™/ˆðöSÊ9q÷Ö€‚©áš?{ W¶tÕ`N¤ïJƒ'6òf½¦ó¼Tt=„¡ãæ<öˆSî*Hòè¾÷rÞá㽇+ äî¼›+¼Ofj
-<埳pþa>`Ž–o<5q¢þCÊ·Ô¨éï‰0ãXñÆ™Œ¥ågO·<FZ$rñÆ¥†b>åBñ6f}¢xã†ÅÊ$ɤxxS3*Þ¬/Þ,™ï)=8Ë/}‡i6z.»'j¡CÍ|*é Âe?ƒå\x¸C ¡¾B8çP óüi 9¸´
-'®ðœsì6|´ÞñËð¡fïÂÇR½/º¾tA/Žd@[0Þž„û7ÝxºŸý€%$¸MUt”ùà}³õ~æ—ÄJÝ¥¡Ö
+2041 0 obj <<
+/Length 3061
+/Filter /FlateDecode
+>>
+stream
+xÚÝZKwã¶ÞûWhÑ…|ÎÅ“
+ Eå€4(kHƒ`hód&…F ƒGF·Å*3«
+ ‘%˜ÇáÜ-šT.ê$1x¤2ì,ÖŽcèÖ”•*&<Ãëâ
+ºÍZíÊ01‰ ÁM‡ºêÊQa°ÜG“ɘöcæ^°Û›ùA[Ë1„™š¯ýƒMæ¿cÛ©ScS²€µ´T&pªé²:…®;ñþ¸¾4ü§®
+¡–Iµšø}°u¦æ†mß
+¥@h;%PàBK?RóÊ—xZ×x²"*–à…íñ‰KU3åËtkNÕÌУÿMýdÙSzH+?Y¹<äOV¥˜ÿ°wƒU`а´ÏýÑ7í ЈpêÈÂIœ“‘©WEæAµwEÌâ`tse^¸‘tÖˆýI|ãµjs,½9djy <ÏVyåAüª±åÔÛ—ábçôó  y¸Â4Z;[<”:¡åŠ‡RÅâ¡Ô¾xvñbñÚ¹1eÐ(µZuñpÁtbÏ•í'ì¹rdÅyf[»‹››ôs·¶¹ËÒ½;Œ3µÌî!FpeÝÓŽ¼[65ÅäqŠ%d('Mhƒj„*kBï¿*vŸä+Æî}¾c÷c!©¾®¿©û©/½@§—YŠNf 4Ö“ÖïÇÌR´2KCpK;‘Y&¦¶úŠ™%ìüÌR’x¤ŸZÆÇSKF¸è'¯À’„#œœ@gƒhœÈb³<μԇâ°
+&®éE¯Í%ŒMr‰ú¬µð )…æà’š¼]oœ+1ÚË°ŽR¹@B%ƒÌvcJÏÆeÙË.fRwÁZù~¹=®2×YùKöØ»ô`â÷á-OFÏDŸŽ/È Æ“1¬›åAÝôþ– Л¶¹O˶¥;\*0È®.Âø»e¾Ë·é¡¾¬dîƒX×1Ž*°‰ÄÉ X5¨&p¨,°ž‡‹ÅŸVÃs‘j€»6´
+ÜxÖ7 *…0å´*;§•iµÃ3âÀá/þp*ìåó`—–Uvh¹ö_Þß]ÿãÛ×ë
endobj
-2039 0 obj <<
+2040 0 obj <<
/Type /Page
-/Contents 2040 0 R
-/Resources 2038 0 R
+/Contents 2041 0 R
+/Resources 2039 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2012 0 R
+/Parent 2009 0 R
>> endobj
-2041 0 obj <<
-/D [2039 0 R /XYZ 85.0394 794.5015 null]
+2042 0 obj <<
+/D [2040 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2038 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F55 1035 0 R /F53 1027 0 R /F62 1060 0 R /F63 1063 0 R >>
-/XObject << /Im2 1049 0 R /Im3 1172 0 R >>
+2039 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F55 1040 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2044 0 obj <<
-/Length 2113
-/Filter /FlateDecode
->>
-stream
-xÚµÛrÛ¸õÝ_Á·R3Œbúä4Ž«GI¥íÌî>Ð"dsV"µ"i;¿ç
-bWÑbÕ£•š¦,Zä?Çï‰! @ãùÕ§ë“)—R¨øêË—ëù‡Ù¿á=¡€(”ÆŸ®æß®n=ìËÄðøêæúëä×ÅO׋½8}‘(Ëï?ÿJ£$ÿé‚aÒ$z†J˜1<Ú\ÈDD
-ÑAÖ_/þ±'ØÛuGÇL yJ”PV)á hülEê ‘Ž³¥Ñ”1EDš°ÓÄüA
-ÄÂrdHlš2’“DSÅ Iæ{q‡ˆIŽNJ5á:å‘‚Pæhb‡hH¢$C<FI"¸âˆñy2U,^À/¯’*bÀ‘Ò`Ç”)äý1B¥1Â#õÖN×W#8Àålã(õu
-„§}ÊN'Å{qǸ
-@./r9™
-©âÛ¢œ0·/ï¼–JôŽJER¡Ò e™ml°ú DB’Dë€ÕÖ¶ö¤›Gë¿M8í7.íú/ˆß€³Ì¶Ù}±.šïþ}c—YYÔ|ÕqSyp¾«¶~•­×~±«ª…;pˆ™`¼?‚[`Ç’¸x*ÖöÁI¤ÒØN_–vÛøw/¡2ñ« ­¼’àéžD†<hy_”ù/4¡~؈M$Ø„±.>œ@9ó¡l¹a[TÒ8ˆ–•¹_Ô¶éNUS¯0µLÔP㥭AM¬;[WíniñMÇëbS4õBI™‰¿•+´Cǯ-³Æ®¿CÐø€tv)jxc³2Pm³¦[Ù q9AStž¶#fÁ줜”jÛUéiV%ˆà´ã¢ŽQÝiç å3Fiå ÷º“›øùÑ–#Q P2#ߎZ‘ò.¶‹@Ò3h19xW¥‡°ßä„–z ak0åÃû)ßÃG ˆ1ÓíÎ
-¯¹a$¥œÝêHP6$Mu\%zÌ ‘áû©¨ÚÚ#ð мÈý²j<²©ÂÈxö¯ÇI@¼pèÞú÷m²¢ta‹V(Öq4СÅmq6c Ë@gÁä°ŠJeOMõ ø6Õ^è‘Ó×ÖöcMkŠÂ¥fAHÑ n*<±}3b#ÃË¥ÕÓ¡e”iTÔ'vIJCaÙOm°¼³P›?v¸Š‰‹'»«]òâKÙnî}´Q_¸pa_ŠæÈê pÒ”‰óöéc¶ÏËÙçŸGöÑD+Ø=˲Ca9°^®†,ÿKûÜ·Å:,}!¬ßý) Š”&Þˆ°>Ö vX΂/>;“¤_¸Aßæ'ŸËlùh§+¨‡Ò1m24>+ÞkD>1hºPd…QCo«,(Ϛ̯V» ƒz½ ¢Ä´ÒRŠ~ÀO;¥:-‹KßÀ«îtðÙê`/·«¬]‡8x*ì3NèGîëÑ„Â]A0ý?”µ†9Íü‰Šœ’!Ä10ôC²„†Å¸/ÿ’žæÝ`xåÆã;÷;wól¿æñÍ©±YÂjŒÔal¦Ä0¸"9¤þúÄØ,ÎŒÍ}ÊgÆf s eÆ! 7‰Dï‡\oÜ]7þÍwWX¸Ž O‰s¼Â¥ rØÚSÁ±Ç¯Va§„†j=-å›/@ßÏæüÊøGî[þ¼]W[¨6n†8h»¾”è4ÞdˆþÝ¿ \øÜÙëþžJÀÄyŸ8‡?tÀ¢ôÏÌ?VmÓîöDÖ6«­Ÿ/O5í~@ýPˆþZö 깑¼_+{QßK˜a¾L½¿ÎnæW·_Gj x/ÅPÂâ -Èa6wuªm`‚ò
-÷á$†•_¹:ÏeU6žÁÚŸñÅ vp
-®íºÒ_ƒ¬ý>  kžv#ó®Ì—#qh~PÒ«hÇa×Íò“ÝKpFÔÉùîÕÇ:ݽöXÁ!ÿöå­Ñ„ÆγíFØšå„j¸ûø~¬œá—¡„¶ä`Ÿ]Ã:jÞ'-㓦‚"ôAéç´™N0Òl¾ÀþF
-"5øEüÛçùÇÙÍ·»+4÷böyþv­Xt÷ë™?š‘1RBB³RÝg
-((êCëK ^ÙDŒµ»ÌI߇
-p¼ú0õav;ò­6ä/£pïb:=Ÿä},—a2Ió=r½´ÍòÒ…
-PXç7\Œ¥Ï °Ç:–à Ç"J°â>.OÖA°=ƒhyãFýŠtÚD’³ÐS¶»Üµ¥·R°Õ¶È¥à ƒ+ôY1öHGr )M`W‰ ã†
-©ßö¦E~ÞN];„£µšîãô‡ÿ)ðúO© Xü„¦šƒu
-e\»˜Â=ªÖ±ì
+2045 0 obj <<
+/Length 1826
+/Filter /FlateDecode
+>>
+stream
+xÚÝXKoÛF¾ëWÈEÌÍ.÷}tb'u‘(®%§Ò‰’‰ðáòaÇýõå.)RZÉŠ^
+8¤†3³ß¼I¦~dÊ:ÔS©â˜ðé*›àéþ{?!Ž'蘂!×›åäõ;*§iŠér3¥VŠL—ë/³7H£3€gó‹W—gAȳ‹››«ùåõpÏ10 Ƴó»‹öÙÍ™gï¯g_—¿N®–½9C“ ¦Æ–¿&_¾âé,ÿu‚ÕŠOŸà#¢u8Í&ŒSĥݓt²˜üÖ ü۾ꃀq…xÈÄ4  )ÐïŠ I0I®‘ !í
+‰¨ŽË
+mŒÂ‰I¤f.Hþ Cö•¹¹:æ¡)‡Ø/˜µŽ7àb rŠà°‡J "¤æd $ÙæES£ÅðIJ£ƒv‰"1dåô…lpȦŽËhü»Èã<ÊÒ°GD)vZsÏåQ=N…ˆÐr¬{Ù ¹.²(É-ÝÓRmìÁµîØŒ­–úÛ
+¥*Ä8±Ž¹½ZÞÝÎíËŸÏH¨gîlƒÙCÒ0ˆaèæEcÎ:h]Òª?ŒwÅ wÐ.=lªÖM™wÉë¢ þ‘Ô–‚¢R7ÕøŒ.w—­œ¢tlOq_¢LpÅu¼ªãõ.i[;‘¦J?%Õx:sGð,®®ìËŸ<gôb*ˆ2µã|ç8‡ÔªÈ7ƒ¿[yTc€A»!J;Ðl}40`Ê=ê;d}ò dz¤«9o®ç—Vžv§ZC›IªºŒjӤ̣Ûxã0ÍWÖQÞ@/:TO„B¡bXÒp…î µ˜è1°wË_>ݾŒèu½0]„,ž«:ÎœïßyU”uÒd;½àC&B'‡Q$0ãÝÌu5 ;wt…
+DBÖrÌ]zÚCaDb‚í<ìr- ¥¥ÆFúK\—
+uUPæÉ ûëwŸ,Cmb¾Øs Î-
+j·`¤{}“F[Ž!&Ùב{ä«CD¨Ðã¡æÕê¡©|’5RJê}É/‚ò
+),=‡¶ÿµq:endstream
endobj
-2043 0 obj <<
+2044 0 obj <<
/Type /Page
-/Contents 2044 0 R
-/Resources 2042 0 R
+/Contents 2045 0 R
+/Resources 2043 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2012 0 R
->> endobj
-2045 0 obj <<
-/D [2043 0 R /XYZ 56.6929 794.5015 null]
+/Parent 2009 0 R
>> endobj
2046 0 obj <<
-/D [2043 0 R /XYZ 56.6929 374.0222 null]
+/D [2044 0 R /XYZ 56.6929 794.5015 null]
>> endobj
2047 0 obj <<
-/D [2043 0 R /XYZ 56.6929 216.7302 null]
+/D [2044 0 R /XYZ 56.6929 627.8052 null]
>> endobj
2048 0 obj <<
-/D [2043 0 R /XYZ 56.6929 132.6902 null]
+/D [2044 0 R /XYZ 56.6929 562.9454 null]
>> endobj
-2042 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F41 935 0 R /F21 710 0 R /F55 1035 0 R /F53 1027 0 R /F39 895 0 R /F48 950 0 R >>
-/XObject << /Im2 1049 0 R /Im3 1172 0 R >>
-/ProcSet [ /PDF /Text ]
+2049 0 obj <<
+/D [2044 0 R /XYZ 56.6929 498.0856 null]
+>> endobj
+686 0 obj <<
+/D [2044 0 R /XYZ 56.6929 457.8644 null]
>> endobj
-2051 0 obj <<
-/Length 3048
-/Filter /FlateDecode
->>
-stream
-xÚ­ZÝsÛ6÷_¡·“§K|ûæÆnê¦q|‘3½»4”H[œH¤*Röùzýßo»à—áÄ7wãsñµX,v»
-ç?§‹( çoÏ®>œýBuק©œŸ½¾XBQjC'b¿8œ_-?\ŸŸ&z~sqúéæç“‹›N¬¡è"T(Óï'?…³VðóI¨ÔD³(„HS9ÛèH‘VÊÕlO–'íZíPŸ*"e‚ÈÈÄ£ )fBiÉ‘2¢4ˆ•TVË‹ ZóÙ/Ëw¸Ð`:Ð`8ƒVXL(m÷÷?¾:]ˆ4œÃòuF}w±Ž ÃÞßz¢ˆJp‡!;ýÿe½€ÝB†r^e»"_¬7Åúóº®n £ÐÀ?ñ´ù_uUL›U¾žÖm§ÂÌ‹&÷2 Ü4µ<]ÔB¨0Huåöþáòêœ6+å=ËweU6í!këU½/n š½ZTõ6«ŽÙÖ£›@Æ0 é#à.#£Yt*
-tÂfsöáæ§wï=<'örYµÅ¡*Z’dùØ´Å®¡Â«ºjêC[wý¼:P:–ÌwKF-XÂÖ†à¨UsÜçY[à(ì¦t`D”ØnW ßg„2Q†„ê8X9~“2!êüö§\sájIÄ°ï±-·eûèST8VÐò±ª÷MÙL!"?Wà¬:MIísi’ËHí…¾0#€²Å…uw-<Ð×õ¯<M~\äŸuÞQwDü›>‹z\äµG#;‚)d xGvôq³ËÖßú\ :‹ï›b}
-%Ày;wt3|öÌ ÓÀ˜$åžÀù¶Ü–ZFwpÐ-©õ°\¨$
-¢Ð’}Œ‚C[îŠúؾœ÷Ñà ÁÄ`¹Ôõ˜ïŸç
-Xœ$‘™r=¼„+¨õPͳ\Ó)×÷_åzȪ¼Þ厩âŒ}ÂôÞQ¸'¸ãŸ¼8¢´!¨¹ÉùÅòÕûËë›ËwWݨgÁdèùSd‡€«µfÙJ„îÚ9QmMßæ¸Ú•-ѽ» çî@|pî4éïÇ¢i™cÆßA(+Ǿ¬è H
-çÌ胪a!ŠÃ=€4¤SÈ4™ßl(À§y#Ü϶Ûú'Ž‹ÔÔGKXˆïj×µý涫¦ù¡qŲ<·òi£t¡q»úÞ5ÜÚšzÇ#èƒqú?”ííØVïl\Ù>R©È˶¬î¨Ðnx€ªæ¨¯m V¸x—ÙÀðmñt»@ë¬b¢®Ú¬¬žtãc
-lÇ ›/\â$€=ƒæM‡·ìëÙ†wY^LÜ›ö±c²ß–x׊’"Ô "Ùp$Gáh…ÿ›Mq—ˆ.Î}›¬­»ŒÎm2­è™M–ã¼È¿´t¬Y p†êÂ\‰“9|µû}G19šìã¢o
-ÒÜðËfÌ[;86b~ã¹$qZ4¤ÅS8CRÙdk6œp¢¼«²öÈ(Ku6¦#a1
-¾”»!eÑ ¾Ùv `M–2
-7´éyOÜ,/_ûrO$Hô#¨®}Üs+¸ÏúP®
-n°î—(›Q¥8jÃ`~¼ñJàùI¼¬5²V‘bÖÖ[¸V¦Jø–e§‡¤ìõr¹°K·%LnU,G³@µ%¶ P1à ¤ûˆ<L² ä‹Ø¯æþ}š »5³Ãó -·4œ#¨íÉé†eB‘“ÒWü~®êæì,wzXú—ÝH'aÂöKè¢]Ò
-cÄÓðd毎¾]iA>!„½EÒºL‚ÛÁÇ=:gÁì‹j}xth
-î‹Ko¨ò¡Ün©gU¹ÏBmaRÐZsìf4õüH-M±-l’h8‘A"ÛÃLÈö‡’¢Ö”ņ¾…•øºšŽÓgšuZT<ª BU”/³
-7Ngd*Z&óëƒ/Ñ(«¦Í@Ñ R6DzÍVxì4&E‚œ8Œút*a`[ì@‚†Êì.ÐmÅ \šj?¼K±îŠïŠvý])éñ•TBÒ]45ó&Ÿ…‰ À ªêSÈ$ ^ZOw¼‘j{$²¦©×´KX´Ì ¡ÑŒ÷[‡Àe«,Ë•e‰~—±HG‡ãËkî™ç í U`ª8è 2 U<Ù0…NŸ­’6DÌv”ÝøJ €dÄjhHue Ì4رRÚW[Þ€&ÂÂI}wÈö‚"ftƒ¯uÇ‚§¤ÏÓIã˜RªËä&Vë@8"Ï
-zðu »2T<ÉÒ õ–‘!dDû}éIIÓÁ]$ì]$ݹ)MGç&;DßÛì¸m©òO¤lº
-RÊ€ïnmúb(\aÍžs
->ߌlä£ï'P¢ÛNûBçݾ³õQ_á2~áã· ®ôéEÅ kwµàiÈÅ
-endobj
2050 0 obj <<
-/Type /Page
-/Contents 2051 0 R
-/Resources 2049 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 2059 0 R
+/D [2044 0 R /XYZ 56.6929 424.2917 null]
+>> endobj
+2051 0 obj <<
+/D [2044 0 R /XYZ 56.6929 388.1677 null]
>> endobj
2052 0 obj <<
-/D [2050 0 R /XYZ 85.0394 794.5015 null]
+/D [2044 0 R /XYZ 56.6929 320.386 null]
>> endobj
2053 0 obj <<
-/D [2050 0 R /XYZ 85.0394 752.3578 null]
+/D [2044 0 R /XYZ 56.6929 234.5807 null]
>> endobj
2054 0 obj <<
-/D [2050 0 R /XYZ 85.0394 679.8301 null]
->> endobj
-686 0 obj <<
-/D [2050 0 R /XYZ 85.0394 642.5879 null]
->> endobj
-2055 0 obj <<
-/D [2050 0 R /XYZ 85.0394 606.8804 null]
+/D [2044 0 R /XYZ 56.6929 126.8791 null]
>> endobj
-2056 0 obj <<
-/D [2050 0 R /XYZ 85.0394 575.5077 null]
+2043 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F53 1032 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
2057 0 obj <<
-/D [2050 0 R /XYZ 85.0394 512.0134 null]
+/Length 2978
+/Filter /FlateDecode
+>>
+stream
+xÚÅZmÛ8þ>¿"À}8¨]½ÛLÛÙbÛÙÞvŠ[`w?xeâ«_ÒØî´÷ëÔ‹c;N2@ \ Œe‰¢(Š|HÊ¡ ÿé"‘á©XÄ©ˆ$¡r±*¯ÈâÆÞ^QGz¢pHõêþêåO<^¤Qª˜ZÜo¼’ˆ$ ]ܯÿ®ß¿¿¹{sûû2d’¯¢e( Þ]ß}¼þÅö½_¦,¸~{ó^…à
+ˆR$S$¸»~wófù×ýÏW7÷½8C‘)á(Ëç«?þ"‹5Hþó‰xšÈżˆ¦)[”WBòH
+Î}Oqõáê_=ÃÁ¨™:§!“H2¡!'°ßY=‘ˆHØw ©XôÄ蜞<ê)\á>_þ¯JJ"ÆAÝĬêj“?†›¼ÐSPE#Â_ W>’¯§š—U*"DÆc ?6Ú‰8¤eH‘Äó"Nøª4R‰dŽ6k–!OeÐn56Nþ“öØí³6¯+;Š=…¶í¼jZ­-u½™L_ëMÖí »°jœQ ™z)_êvõ²ÊJ½ŽxrÅ¢$ )R "úÍÌì‚ñ(E»³¼ÀR%‚{4âz
+.]5Ý~I“@Û÷v›µØí-êlW~ÐQí;ýîq2´yÕéÆMt«=ÕûO– Û´z?áÚèýß¹›íú¸ÝZG]m³êQ£ryämcÈÝÈŠ/ëÜn`ÕÖûo®«Ó¶â Ÿ™}ìê¦É¼5Œ…“(%D9EsÇøXå2Ž(š¡¥¬wÎ<PP÷´V
+@@á1`SdG'I!F+
+ùæYÁzªÉFˆÈ {Me: rt{Œ‘‚&V
+”`Ó&ºC_×dÚ6×LD*ˆ¨<{l0O&ï}”7¤n̾d¶f2GE¢ãZ-صfÒ­R3ÀEK5ÃUDEÏÆ€õ)6És¹@*Rï×Íé"ŸÀád
+)†\ 0œzÈDì!¡«Ì„¸4â2ö ÊUûõ9‰*‚ØýVû¸[´‡Óìjïm=qáÛ¯§¶É!ÁÐ!/c©žQ±(5꟫¿Âža8àxlÅ,²„ Ö¯‹Ûzwón*ýI•ü8ùz†çåãàÖ@0–ïÍÍ«o‡>¢8ß°qºYíó½îáóçÀ˜P4oPÿÈ›ÕKpÑhûÏgd3§À, r ìTgÀÎS°«.¦™[íºæíÕ@~V²žjF´‘s@"‰h¯]îÓÎALˆ©ˆ§"gn„Ÿßae„SÞⸯõ¨°UdŸ´íÉÖ_²ªµp
+¦z…g k¾+Ñë÷wCrëL²cÍN¯r,dôúÅLö‰6J¹”}B¥ Ù·à“zç)7‘ðºEì7ÚÜÇ€‘BUYæ•vÝ[רºòÁ~awƒ´(¿íÙ9dÑUk;lȇÆêpfN}àì•èXxîÀ5²´·Û“;¦¹[­«2}Æf  †Ñ‡»Â[¿ h›]ÀwñÂ%$.ɸW¸þÜ-›È8–ûÆ‚‡Ý®Oº£ˆ^hœœwÇ!Õiwì©Œ;î.ºã®Þ·ÇÞH¢DÈóry¢¹Æ™‡Ä벉`¿äM««C
+hŸ;½ÏµƒÆÚzù¦ñ –|ñ@u9
+Ê,¯Šon|ãÆ*@oÝ´öÍæ¨qðêöî“ÚŽµ^r|Y2‰—¬?Ü2®ÜŒ7|³“,DÇë—õ’J7o== DÅÉáŽ_Lµ ÏÌ>6]Ûíµmïu·,ÈõÈ``ÐÇ™DòýVÆèOñB÷ðãû| tåDT<^~Æ`yÖpÂ,‰Á¯—SÄ2û6õêÓqž($jD-ú%ã’'™Š5¾‚¤ 0šäº.Šúi&¯EćòóÌ¥žH„߀/¢:_iu»1&Žb™ç}I9Þü4¿gSª¿ó
+j“Œ\E&ÿ’T¹h4Š[ÄÌ×H×3ï @Þöm¼= “t c&ب‡í0ÉÏÁäõ˜d\B\Øu0™&˜„vÿµÚÁàÙU•^é¦É°±ø½Ä:ƒ\ðânÕ‹r™Rx+³ÿ àTÞšis‘iƒøi,DàÅA?0‹‘X°pLãsóíˆ ¾Ó@Öo¥Ææ
+„"†/ —=N°<ÕŒt#“}ó#ñ^Û“ÚßLÍgDxåÉùs~  |éoõÝï­½~ª1(ÚÏHÌ¡'6VuYÚ’
+{'„¾cæ<vTæþ‡Óà¡sr>èÍá,¼û{änÌ›
+¼B&bí]ûäg î2<&:õ'.#Ág „ôiÒwÿøéðã.8W0ÝSwÛ³Ô”z¡ps”ÅSÑ%Tî2añŒìÿÎ*endstream
+endobj
+2056 0 obj <<
+/Type /Page
+/Contents 2057 0 R
+/Resources 2055 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2059 0 R
>> endobj
2058 0 obj <<
-/D [2050 0 R /XYZ 85.0394 442.4505 null]
+/D [2056 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2049 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F39 895 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >>
+2055 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R /F62 1065 0 R /F63 1068 0 R >>
+/XObject << /Im2 1054 0 R /Im3 1188 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
2062 0 obj <<
-/Length 3460
+/Length 2423
/Filter /FlateDecode
>>
stream
-xÚ¥ZYsÜ6~ׯÐÛRUM
-0¬²ÚæÇÝðßezß;râo{6ÑÓKÇvŒ“ \«§µß=ƒƒ”œ}…Xˆoî@šûœŸlà1•[ïÄ‹´»ªï=ë#Q¶™ÜuDÝ1¼z:=ÑX¼F…©ÕͤK¨Ç®ñäÌE‰à?=ÔÅ1£3ñþ'þÙ§z·£ANä¬NEêœ+©$LÅp×pC-‚nÓä@§ºMDe¥¾I·J%ÝÎäá/Vtm[¸oÈ@qßdY:Gª{T„Â:"AÀsO"ÝV‡œâÐ>t221s>XéÂ|zK‚ñÂ’&×äeõAEfÒÉ|8T¢d™h€¶ÀDíîÊÙ/ šüsÝ¦Ö “sþÅþɲ€P8®tI£Mµí¼•Ã{ͬö¶Jù¦; lW‰½¢f_Ÿò&´ð¡gnÿõtmi£ˆ‚ÿT„I.Ø´srôÓ>á ¹Ö¨M‘P
-Eü„yÓQ†Q'ä"Ø3È-.¤dÆþ˜O©óZ¦±s˜ëR¹ÂNùDIetd äô( œÍ‹Áz–r2 )+'5©â½³E)W¹‹Ó8/JENÊÉLæˬÁr~qGáSzY‡k!cnL—ÌAÇ5ßIÁ8Ÿ’³ʵ<Æ„™N]x€|ÙVd=mE¥î³P$ÌÕ-UʈôœÎ#yçäü¢…‹ cô‰9ÑñÏÊ0ëB¢Óšt"  z¿›€{úDÎ3nQ|
-®iTjöòõ›w÷ô›Ÿ}ûê{F÷+ `„õDeÚ|C(¥öàc11/ñ¦"óÒ“>Â)~¥:ÔÆÙû¶WD3]U’1±šú/,Ù`|£NÜ®6»‰‚ÛÜf„謮ÙbYø€c{߬RðŸÁ,ö ÃØÔ±AfbÑ ±­))ýîZêà®CC*ïÞÓ›/B”&kD-ð©~@ØüÈ¿Ûû®·ñ ´æô¼åÐÓ“ÕdPÕ8Cc­èX°ð8¡MÃû¹o /Q•<çÚ.¾Õ}m ¯x¨Š=qÙÆ™p-1œP
-£œ ø ©Ó;ã{sìy™ s4ÕÀ{miâLÏ ûI>ý7jÌYŒZä,†Ïm¨ÝÏþX•Å¬X™àý)³pz£ÍlµÿBeg=ÈðÑŒ»,¸Ø‚¡µóÙ亡áÌD+†ºÍëõà-ÿØFIÇ¢I¥éüÖ8 Ë÷¤Cœ¶¦
-Ï/ÕguOèÙør
-¼vj^‰š¹Àó¥:]'™­ãšèÙIf8<ØEv;ìÖ¬hÛÆ)¤RÇz€ºÉ^TÍZˆ%1Œw—Ë»sc+õj›õ–ØÇR9o Ž‹M}pâCÈ:‚’ß«"×ÀŸt‡5½6ußSN‘ÍÏYÆ6#
-þÚ~ÿêݯ7Dœƒ.Mº B öË”Ñ.à&þ^HôætÍËMÃY„$ô“5¬L+]9eÝÜöG0Š'' åévø-4ê[Ì3‡±³ŽOÕ5“½Ë1ã Pê“î°ÞÛ„Kk À˜±É˜ÛÚšµ¿
-i>ƒ‚)‰³…ùOZj®Û< «Ë¯qc›aŠçN^ë:­æËSÍyJ…FÍÄÉÓX:å:¦ž /ºë
-ßO,Ëõ@Î#i¬B$ñÓçñ\+R `ÐqšÎOÄh*ÓˆÐT¦b¢ýt&S±Ô>Îr*’º.Ðè’+(*ñ þ‹€À
-0‰0‹•!TÁò¿Ñw Y«òûX’ÅÊk×N×ËP ¤"& ê«@šÉ0æ›`Tø㌢° £¨P±ó–æQ”ùõn¢¤™4òP߶DÅ¿@1w ×pÈöE´I¾ŽÆÄÍ.²‡³%Ç#Qì§×Èz8Y†gc?®àè4ì”/Ãܘ²Úõéá½½ w<"Æ‚ÄX0ARÛSLa?Çqí’E{‰3¾$û­¾1m3®¾~ßú$ò,Ld&”êkׄé<H8&io9Ÿá‚ÄŽ]öäþŽçtÿ&€¯HLק¸›uFï ˜&ˆHôhÓø2¦«ÈÜM rmùÓe€ÅÞt'”€ÄÄ™Jaézi˜É(
-O/dvêïügz§gÿër˜6endstream
+xÚµYÝsÛ6÷_¡·R3Šâkúä\œœ;‰“Kœ»›iû@KpÌF"]‘²ãÿ¾»XP"%J¹^’ñŒ‰Åb±ØÝßb%&þÄDf¼ôës¦¹Ð“ùêŒO>ÂÜË3‘hfѬOõìúì§ÊN<óFšÉõm—cÜ91¹^üš=cžMÏ®Î__<ŸÎdž+“¿}{qõüò¿Ð׈€„óìõùÕ‡óW4övêevþòâýô÷ë_Î.®·âôE\¡,žýú;Ÿ,@ò_Î8SÞéÉ#t8ÞËÉê,׊é\©ndyöþì_[†½Ù¸tL¹tÌ(c' S\‹ÿe[å¢"Üø¶|2óŠå.÷ÇyÑ:¼R³[1d5s‚iïõdf¬fVônHª‰Ìk-ñŠœeÒ:9±ȼ´ñŠþƒŽ”ži“ $„5ÚÂ<çÓ™‘Ù»øÿ
+þ‹ìrÛ–ÙËýr†y¸‰å–9í£®&‚¼€ËDýv<ýN+qà§Ë•š<¯áŒ“þ1ãYŸs<¦‘=CRÁew«$sÜÑ1¯ïÊLËÛ¬¾o˺¶ɚ»z³\ÐøM ï¦ i¤LTóºúcSÍ»e6{,Û;jµwôŠÛ‰ eΤ‡6)p¶!š¡˜9(A䉄„úq:S\dE’t~·®ë¶¬>âr°=å™äpþí•Â–•Ý¯ëyh꬧3¡³MUáÒ8Rt3À[2[Ô¡©~hi8TwE5ÔiÂ|CÊö‰†ðÜø]ÕMZÑ<5mX5?COñN hÔ$yÿã˜S xSgœ[™@gýk.áŸQx¾Î¹Hôñ6­Îá7Îe¯ ºÅrYã®qÚ zpx«ì¤Ûƒ©ƒèÄå2| iq[ÓdhæÅ=pfQ
+«.+Úå’í»Fnàw“¾£~ï+pjã!Îvñëë"˜sÎúì„´~À@ÌÑÀÅé3J1‚
+[ª¾?hÝ÷Áœ×*]/8áz_{^²Ü;3éïx WG4"—êíæ-Ë­ß“ë}h7eô}‰wO2öWå’Yà¾'ãki˜¾ žÅm T‘å¼^Ý/CôçØ¿_'sK[Ö÷a]`hbY³™ßÑE•Í×Sá²P´S‘%>à‹õüS€6µwEKË–%xi•¸WdÀN³<‡“ x
+Àï}½n›óípÆp°^ŒßÁˆ˜r§ õÀ¶KŽá`î<Syþ%ÔÑX¼Š*¸ÃAδ’]Œ~±ï:¢ÞÅ1ÔÓJ1.ἄz‚ñ¸C$êµ ž<z}Î'POCŒQ€$2îÜd¯
+‚±•®Ë’×Õb>V±
+@IaEó´ªzT'TÕQ%U]^]#H¥Œ®/Þ½>Àsx¿zgóÓ’l©FD¨OCÌ6à‹CYî6 8õcuZIpS9ÀÆâ`¨æ]`}¥7[(î”Þ„jAÕ°˜]=¥YØ&åd;×ÃÝëq)b»LD›j[Xf[¿êE 
+DtŠRļ¹zqùòûsTúõ囫Q#)æº{^îÎm¼©Å X©œqÐr—øÔŠúqCá_l*Ñe|Ëå„H0ÖÖ55¨ù™fÛ4¸Í|]ÞtkªnÞKj£>ñÖ8‚>R¦²fès¹ß B›çøêÄø•Šøfˆh墫?–=K‰Ç¸è½f9&ót|ÂO¤öô9_¬ÊªlZPG®õ]¸M²W#¿.ªM±Q®0sEsìÚ¹œ)”s¾µ”¯þur÷ëknáuëä¸ïÓ0?8%¡Ppx˜FI·‘#²ÿ’Cþendstream
endobj
2061 0 obj <<
/Type /Page
@@ -9184,328 +9175,444 @@ endobj
/D [2061 0 R /XYZ 56.6929 794.5015 null]
>> endobj
2064 0 obj <<
-/D [2061 0 R /XYZ 56.6929 420.5648 null]
+/D [2061 0 R /XYZ 56.6929 243.4864 null]
+>> endobj
+2065 0 obj <<
+/D [2061 0 R /XYZ 56.6929 96.2114 null]
>> endobj
2060 0 obj <<
-/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R >>
+/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F41 940 0 R /F21 714 0 R /F55 1040 0 R /F53 1032 0 R /F63 1068 0 R /F39 900 0 R >>
+/XObject << /Im3 1188 0 R /Im2 1054 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2067 0 obj <<
-/Length 2757
+2068 0 obj <<
+/Length 2295
/Filter /FlateDecode
>>
stream
-xÚ½Z[oÛ¸~ϯðÛq€†Ë«H>fÑlÑE·èi¼ÀÝ<(¶’•%×’“fý^­»“ö`Q ¢¨19œËÇoȆd¡ÂLó…Ô LÄb½=Ë{øöîŒx™‹ tÑ–úuuöËoL.4Ò M«»ÖX
-a¥Èbµù²¼üôéêãÛ÷_P—¿¢ó ñòË^~p}ŸÎ5]^¾»º†WÊYB¹/?^ÿùéíå¹äËÕÕùÍê÷³«UT«­:ÁÌèôíìË ^l`¿ŸaÄ´‹'xÁˆhMÛ3.œ±ÐSœ]Ÿý7Øúj:f
-.”'‹ ÁãtÂ`a¸f:Ú‹’1{y!c®u‘Öµ³‹m–é6ë/œ„älÑ} BêÀZ:#!DÒQâz—­ó»g§Fó¹Æ&»KEÓRœÄ^¾¿s}ee4ýå7Ñ™€1¤uJ—g¥:j0Š˜“;©Ü[ 6zü1Í6oN*ãšy=ªC‚$¬Òÿþ㈄ -õ"hlÞ£+$NN¸½%5ã÷ eflšÂ/:[Wå¦8ìȹäóD©ºQˆS¥º:ýŽ…754Ž¦6½ùÖw7•{ù£íáË»jïºöçD-aö¹©»ò·þ÷éf“m ‚¨ËU˜ë1-Ùˆ©âHS­½{ʪÌF|Hø/ô”…u]dé~bU0Êâ‚1XÂЇwÉd$‰€ô—óaКŽ‚ dfüšù¤³iÂaŸ5CH
-Ãn“6á{ê\î…+÷¼õï«ë÷ï.êü¾Ì6þ§u^Þ‡GÝ àE•TÞ“`oø¼mÒ_ &ˆR"`—æ{³w çeŽ5ìK°Sx/» j4èx‡hD©
-ŒÍÃiÅ´UÛmZnœ×ªÇl¿Ï7™G¥´ô~nA›ÿEÙC¸ÎxE^úîÇ<uªpÒÉ[ º\ŒªËD°)$çp°‹J£|ýqœL(È%ŒŸH–ÔL†)ëÓ}¶Ï¾ù,ù¾©¶iî-çÚc;&¥
-ip7«V”Ñ«fK£˜vûœ};ä. ÀëD‡¤1-ØíÓ®¶±ÎÚ½.]_uçž6rì`Ï;/ž}ÏëÆOñ”7~
-¿ì~&%·¾žz ‚‰S¾8;Á|ZBÓž B}Ç>¿Æ±Lc5«S*Õw+“”v´ê{•9¯ -4’J½ÐÎ%ÜŽîdË¿±À©‰OD| ›Xݸ.³ýÙÆX@±^@½qè–DJSÙE¿ê®‡P&Î@ 2í}%ȉÌnKÍø?H 3{¿¯³fèÛñž›£Âƒ°0ŒÎ+¥F´í†¤²\tÕíFe$l’Ð2ùnžC÷{ùnúB˜¶õ‰Ïÿ ½YŒ¤8Ð,@r°Ç º‘6U’z32Χ "¦´iÈ<c¼ÞlT#¼X•ìØÃ#ö„ÊbdTŽ$pܪ(ªmÞ4±š€BÀ>MÚåe“íˬ1±K —u}ت:•˜!i¸Â|B´¤f"H ñ§‚`ضg•R#ÚöQ誻z0ã8lhíôà8¤‡ùž¶ÅÚÙqì=f‡ù©ÉóÍf„iœÈ¨e±/Êþ‚Œ ݺà_K …(çÌnµw¿ÅŠ¹ 1{‘/Jä_Hž`Ägó Ò–šN(õ³ âäÒ&Eh 8Õ âLœÐ<J¨Þ14%œ$=ÝWã…¶¦¶õÆWB Ñ tg¥ÚB<ðd™¥ëÓKk Óe’Çtì\fÅä¬s[¾µE›Â¦jù­ç X1§½Ú¸~H÷¶ˆc‰0ù Õ³­X Œ®JI@ìˆÅ?œŽ`n¬N$Q”Š…Ä13j4!¹5–òe¹y«D6–»fõ°ìÛÜֶƦø5½Ö€¶'uÎаƆþÏŸÍ”[9±9‡œ×=[Û°ÖÚxÂ/]Ãc´²ïéº)€Ã1@ÇmÚ˜(0ýŽC@cz '® ‡7KºÛ?üÇ’MÓ2ðÍ
-›Žûü1ó7a!–‘$4#¯v8!‡­ð\ö(ð+y Çl*yÒR“É ¦Áƒ8‚ú}ù´7Ð[º—Ü?­¡Q7°¦4RFó)ûîÏdÜ(>¿ë¬lÒ&¯ü
-ÇÀEÛÐošâfÿ¿7€/~¸¹é/ƒQS8ãëˆR# édì¶X“ÞJÞZíë^¥ÿ’C‚úXô² Ôƃœ×E¸;+ƒ&”Ó®çGÙl±˜JõQÂØ)fD’“[Ÿˆ·I ÔG.ò«Ç|㘠- š ¼½°"³£Òp~ Ÿo;bÛêÑ\3ÌýÁ53ùêØ‘{‹Xe#]@¹Ò…œsòtj‚ÊiÌÕ;eåéP}ØíŠÜ) œq½4Fã¸I7Řù1â´k~£ø}é,yc<·Œ´Ò¹CØóãê),ÙݸÃ΀Öm^äÍó9ŸÆ€Y©“ÇOm©\ R}\I7› P‰÷4¯§”‰æb^ý(5¢ŸR&R¨î.7&t™t”eödb$êÍç~¥eúÜ¢iÙ Ã4NÔZh™bóqC$Ò,2Ö—>üß+­ <éÎɘ£Š…§'Jü¶ÔtÌE)G£«§ÁÝ6\Íì¬QjdÚîy=G,Ñ´;ïÛ¼Þé³ÉN™xn
-_Ý]tõCg ‰ZÃþÈb4ŽHðÒ½1y¹ÎŽ£ºMÉ OoK*ÒPñ™®AÍ!¦úD Ú–šñ`räÜE_׃ÆæNmvÖ(52m׃x0ìŒy¯³rS÷¯Œ:îƒネûyÝ…eãšÇ´ˆòöæÎô›Ý̹YØãó¸-Òòëñ:jÚÔX¢ãSÉÒ’š1ury^?eû±\•Èùy£ÔÈÄcSŠ’Du'neKÛÜ^ŸpÁ8f "MÁqê¯DÚRÓ¶ˆRϲÛÃýÐ )àGóÓF©‘y»q§Â€Ú‰WçÀ;û²{kiÕ¹‡ˆAáBÉ„™)4â’¹ý
-wÿMa=ÀjÜ é¶Óc{ÿf™SÃÃfXÖžw §æ©ã=Ѻ:7…»X§ËCùwåN†ÖÙ¾q}Î2ЈEŒUl„ÿ‚èñ`ÉÎ@˜( 5!íÕ„Þhmår˜cƒ;*Y~¬šÜa¹w$2ü%4òrwðÛ­z¡ËbÙ–×½øý§vo©gŸk [R
+xÚ­YKsܸ¾ëWÌ-£ª/‚äÞdKöjË–\•Š×Š¤4ŒfÈY>¤(•ŸºÁ!)JV*©9àÕh4úñuƒ#~bŒ«X/ÂX³€‹`‘îŽøâÖ> ¢Yy¢ÕêýõÑ»*\Ä,6Ò,®o¼"Æ£H,®³ïË“Ë˳‹Óó¿¯dÀ—ïÙñ*à|ùåäâÛÉgœ»<ŽåòäÓÙ†R+D‚[:×ëo—§'Ç¡^^Ÿÿ¸þýèìºk(ºàÊÊôçÑ÷|‘Á ~?âLÅQ°x„g"Žåbw¤Å­”ŸÙ­þÚ3¬º­sªTÄ‚H†3ºbNAÌŒ’Êé¢Lvyf¯Äj@¬à\H8ÁRå&¯‹¶±Ú‘Ëv“ã=dH¦…iG·Kšû9¾.DõøœËmŽœÓúXDË<i‹ªÄ™]•ÑšeôG·Ž²Ú$‚ŽZîäP‹eKSH™æMTÂ,ÏoqžÜLŽu¸‰›'xIÅ UlHþµÇY+Oõ‹¥X¬t ¨Ô,VB°8
+–ÿ¨ººL¶8I2þ£X-ËÜIóm…Ä›ä!Ç™´kZ§èïózW4 hÑ™4’ÅÜÄ?7Z(¹7m³©º-‰q“£MÞâDþÏý¶H‹vû„ã¢D´L4i]ì[ÔˆŒfd8ÑH×  8^Ú¦Mê–¦ü=Ff ~fÅt¤Qü³ì帙¸a&ŒâÅJ(’îãùg€…iÜs°, ‹1‚£_€,"Z ©\˜êh&L{*{껼Mß¹{±´*o§ç‹P³«ŸÐS=—`¤'@D°:ácŒ/³ü6é¶dƺè]W÷AËÉiÙ‹ZR‚©
+"edqR¿.IOõ\”‘º¤ó+Àß‘,óê8ݪȞië¹êˆi‹ÿ#\ŸáÖ“Ï미Oʼn8°À $W?¯DÌ—‘ÔLXhÎŒ6Ѭ&ülVQ‚†ìôÿ—]ðv+É%Fø*Ýäé½ ›F"›ž/ÿ«*óér]fétnûˆøßd³Ì˜?&À•ç—Z úÚLÀìýùÅ)Ú*&“e»¢,š⥪qê*¿Í)m¥ä4_’²ƒð\ÂDLãSË ^ã‰F^sòíú·¯W3<Çîr^¶y]æä°ë§¦Íw >@>©ê¶èv‡c5SÚHb£/¢HãÍ¡Ër(­Ê¦ÛgYê™
+˜Œ$Âʨ÷™b¦8õ 0`¤ ±wúÖ)R\¬±3¤íÚb[´Osjâ“ z*«}S4S°0P˜)ˆn% ‹„Œç°B€à2ÐÐÒ†,Òæ곞j|sŠü¾Ê~øÞiß»Ãο±YUã!Ý=yQ‚ƒpŸ
+¿ovIúëûܪ3ÿµÉÓ:ogÊ
+ÕsÑ”ký® ÖºÈ›¹ÆS®W?åZ'eVí²üaŽ©fæPÄ÷L|ÏÚÄZüÇ,Š(!PS˜àƒáôlýáêüòúüëÅL!6†’aÜOaHZkÿ¾°
+{˜ÇWgï;ÌÉÁÄ~„‹sTPåò×ݘL;x3ÚòÎØgI8ÔcxŠCMÙ$)9N 8QÜ•IÛÊâœËé¶ã0
+Z¬ÝlÏ¡´IV(Hѳc
+á“ÖÅMN .üBåjÃH8ér€Ýµ¡Mp¾ýÀñ“ôK‡Ì²Ö–5ÔÓÄÚE ÍÊX‰9´sÇCQöi½^¹«»‘-n•‘£S`ÚbÜ”œjßâm“$(Æ¢¥«ˆ>Á¦ÙPX;ûtã·Su”Tn8&˜9±|µí}Y=gôܹJà1c?oÍ<›yï¶ÿó¿(‡‹tÈTÉùy6o+p./”U<¼Ã§¢÷ÿ·<—ý?=¯±endstream
endobj
-2066 0 obj <<
+2067 0 obj <<
/Type /Page
-/Contents 2067 0 R
-/Resources 2065 0 R
+/Contents 2068 0 R
+/Resources 2066 0 R
/MediaBox [0 0 595.2756 841.8898]
/Parent 2059 0 R
>> endobj
-2068 0 obj <<
-/D [2066 0 R /XYZ 85.0394 794.5015 null]
->> endobj
2069 0 obj <<
-/D [2066 0 R /XYZ 85.0394 108.4894 null]
+/D [2067 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2065 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R >>
-/ProcSet [ /PDF /Text ]
+2070 0 obj <<
+/D [2067 0 R /XYZ 85.0394 691.7632 null]
>> endobj
-2072 0 obj <<
-/Length 1863
-/Filter /FlateDecode
->>
-stream
-xÚíXK“Û6¾ëW¨*©2„ñà¼l•<3v&±g½–²•-Ç I,S¤,Pëߧ)RâHÉæšR•4ýBlLáÇÆAH˜Çã(öI@Y0N7#:^ÁØÛs<^Ãäu¹^/F¯Þˆh“8äáx±ì`IB¥dãEöiòš0F¦
-Õ´«"[Wº&ê{²ÙŠ¤Õf}0öX’eNõ<Œ$CŸÒÔ~XÄ #ì‚ÄZ•™~õ†‹Ž€YPÐ*¨Ó0ÏÊÃÂ@›ÏnÊäD¥•ýfÚùd ];:¸[3à<ì ~2p?”°BæxÊÎJüd%jT†xÎëõf> s‚:Xk$tteû¹n­ˆ‚ÑÉb­ËÏ!áTHC[' „[?YrÀÆbáåwPg<ÓÕ€Sf¨wÖ0==1ÌŸwÍíNíÔWÇþ=«6I^º^ž~)“ê©ñ¯ºåÆ©_Þ>ÎÞß;·«6êÌtÿ¿—ú– …°WküÿºÏu^Û‘`bt›×yU"ãJÕ[u3×ìyµÚ} ®ð›®Uú¥™‘ÔÈsÇ6I·Sº‰Îݪ½m¤n‰³82¬ÕÒᘠ³+¶ƒ–µqÀ9¨}ã´ÂŸ<° îÉ3œŒ7Ѓ̎›rc[Ón´§t„e’ÚÂVÂLŒÙè ZY¥Z妪﹮Ýb
-„Îðâ®$Ä`í¾¿M,ú”©ªßwÊE‚³ ´ž×ÊØY2·Aٺ଑MÊvÉ4)QvÓ®Êß)yÚ šÜâVR_TåÊÓu¾U®†Bg7ÝÀÍbX¤4ßhòñÍ-œ>QjCN€ú4„Í^׎V9«O¤™4c§o1„ÊšÚÒNó’]È8“Í—Nž.¨>AÅ®UÁ¶ÉW6Òp…ÎÆLÊ0蓲f̹—I‚:;õîq>¿¿Åv^â è†"@¢ > &EQ=#É
-¤ûÃëä›BÊÇó‡·7-ú/÷ÿs
-ùÑhóÇ Ÿé ögÅÙãQy‚#"à ¸&P#1ù¢§ÖàTÆ!e]4GËunžûp& ¾ý¾Až­¼ÐG§PeZÙ”i{ö܃ïOïg·Þû»
-"=änê±ÍNg†IèÇ!& 3oµœG/Ô
-É! }1ûw.<9¦ã¾ÍMõ“÷„[ºj
-‰bÙ¤Vs L•y@Ø™ˆóK¾$”`)dÿÜ §ÈýllŠÂ|å-óB À†‰áŸÂ~¹
- Áù¦ÉitŠ©¯b ÂDnrø âv
-endobj
2071 0 obj <<
-/Type /Page
-/Contents 2072 0 R
-/Resources 2070 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 2059 0 R
+/D [2067 0 R /XYZ 85.0394 587.392 null]
+>> endobj
+2072 0 obj <<
+/D [2067 0 R /XYZ 85.0394 513.3346 null]
+>> endobj
+690 0 obj <<
+/D [2067 0 R /XYZ 85.0394 475.0295 null]
>> endobj
2073 0 obj <<
-/D [2071 0 R /XYZ 56.6929 794.5015 null]
+/D [2067 0 R /XYZ 85.0394 438.8551 null]
>> endobj
2074 0 obj <<
-/D [2071 0 R /XYZ 56.6929 479.6712 null]
+/D [2067 0 R /XYZ 85.0394 407.0157 null]
>> endobj
2075 0 obj <<
-/D [2071 0 R /XYZ 56.6929 343.3873 null]
+/D [2067 0 R /XYZ 85.0394 341.9916 null]
>> endobj
2076 0 obj <<
-/D [2071 0 R /XYZ 56.6929 280.1555 null]
->> endobj
-690 0 obj <<
-/D [2071 0 R /XYZ 56.6929 229.1103 null]
+/D [2067 0 R /XYZ 85.0394 270.8991 null]
>> endobj
-2077 0 obj <<
-/D [2071 0 R /XYZ 56.6929 196.0344 null]
+2066 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F39 900 0 R /F53 1032 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
+2079 0 obj <<
+/Length 3927
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ÙrÜ6ò]_¡·¥*š
+OðfÇaœF)l‚€E³ÃÇ&èo*4ÅžF:èªã‡êˆ\f™( ~8* ª¦ßÝ^(¥‚o2^nXà—O‡C{ì+A_5åñöÐ×mÃÏÅîº=ÖýÍž·í‘_»º|þ#OÕÿþýÅãVxŽó•#}¥T˜[«é/žX¢" >ÞÔå sy9 6ÕoQ¤¦" ê†_?ûZE1.~iÊŠ'[8Α‡žLÁWðù‘Ë2:÷LGq8ìêòB½ãÉõnÇM/ãÑ¢é™úÖ³¸ÖüŽY†|¾å•®ÚUeÏcæ~†»ÁNz¡=k”?Ϙÿ~¬ˆÀëf<¦÷¼ò´jä­¬6}]ÂQšk¡¯ †gŽg¬*±NƒgÀŒÉÁØFë¦ë `4°Ç
+Y̯”ìáÚ²^+«Bpsù¹Ôz_î=TF‚¥ýÁ™n€M±ŠÉ¡ÀJW_7Eï3ÝXy´áw½~‡ … ùÙ„CoôÔ„FyqÞì‹ò»Òuf™£üÝCX€ý(²ïЄ*ä ÎS7¹Ä“
+ugd)')Zå”ð-X¢JÂTkgaLÕ&Å¡¾ŒuÑUIÌ“P³µpaä9X;Á»§IšOísð'h3 ¿7”‚ÅŠ-7¾×c‚­û°vŸ^™¹ÃdŒ¤*°Ã¦îÊöt,®IY`a]•ÅÉíÏO] .LÂà° ®¢“_^,Ûýž«˜ÛÕ$ÿ9$¼Ü4âúëÓž2j Å%{ð[îªkF •]õ©§BJà’
+¬ï‹[^]C]WñðCÝÕT1±ø`ОúégÈ‘/‡•C‡©¯âÔ—@cežðȾí–Ä{ 1uÓÃ)<¯…¶;9³v)l
+¼|Îj«GÉ_Ç…Ì·\OÓ¥<³ZhÙ¥øJÆŸ2­v
+¬¸¹9‡ˆn»¾ÚóXúÁ0’ÔROún1fe³p±ÀŸ4Ô¾ÁúŽýˆI[8}’…‘òù¢+\@‚5˜‚TUx÷¡¦›%¨À\E”ô^™0k - L‘šH~!C^·…ïÓkºATÁAœÜ¼ ¬ã0öd~Iœ+“ça[5óÊYWן'™ŒI†™‚J¨f‹²'Ë2Ž¼D|2£"Á[ªáX¸Æœ×À@)×8©ä2™¯~Rº¿Ãæ?o°Péy.Õƒâsc>d!îäwZ²”#ñ¹ˆa³”Æäaf} Òe*È:ÞŠ+Üg&HX«.”ÑÓK6Ók¡RÒ7Ž.2 Ñ'–<Ç{øxR…ùþ·Rù¬·Õ‡Ýȹ.,<àÙ‡£W|íùËWo®øg¿¼~ño¹®ò?xM[pË6ýŠPk›.4ŒUæ¹£²IËmæ¿RØ)wúŽß{z_ ¤<ÍØ~ñò·ådâv¥ì&
+žòÕ2«ëµˆ8tgð‰„‚ø¶@¾_åâûavèÏ€ 35ëϸž²ÛÝj\¶{iàÊî?ùo?¶®\lö`S]nóƒ¼w8mGñ ^¹†0]”wrŸ2`ÓAUóg8vÑŠÉÄ`„%__,ÜOÊwt]|«»š@†WÞTåûŽ¡¨oæú‹´NAîÕ•4êÆËx‰·)¨q|›‚ËcŒõÎÓ¦–[ÆÁwÃ
+}CÐý±Ð áÊÞGRK÷ôûµSü, ¯¥ÜW…$ŠàÓè4Û–4þ»;ßKª0…r…²¸4Q÷|ÞÈ0«Ð>n ñ·TÃÁF¼ÅoßÍéQIBI’~‘ t—¢iÍ*—dŠ.+N ,è(lœ€ñÁÛµoM¸^–|«6þšÌº9|
+endobj
2078 0 obj <<
-/D [2071 0 R /XYZ 56.6929 160.4072 null]
+/Type /Page
+/Contents 2079 0 R
+/Resources 2077 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2059 0 R
>> endobj
-2079 0 obj <<
-/D [2071 0 R /XYZ 56.6929 94.2535 null]
+2080 0 obj <<
+/D [2078 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2070 0 obj <<
-/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F14 737 0 R /F53 1027 0 R >>
+2081 0 obj <<
+/D [2078 0 R /XYZ 56.6929 258.0612 null]
+>> endobj
+2077 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2082 0 obj <<
-/Length 3151
+2084 0 obj <<
+/Length 3135
/Filter /FlateDecode
>>
stream
-xÚ­]sÛ6òÝ¿Bo•g"ßÓ$í¹Ó¤¹Ú½¹™^h‰²8¡HW¤ìó¿¿]| EÉéµã\,Åb¿WlAá-Œ"TX¹È¬$Š2µXï¯èâæ~¸bg‘V)ÖwwWß~/²…%Vs½¸Û&kBa‹»ÍoË·Ÿ?øôþæß×+®èò;r½R”.?¾ýôëÛŸ<ìóµåË·?|¸…Wi¬$ÆOÓå/ŸÞ¿»þýîÇ«w=9)ÉŒ
-¤å«ß~§‹ Pþã%µx†J˜µ|±¿’J%…ˆêêöêŸý‚ɬûtŽJ¢ ÏfxÀÙèµJñ”%Zpá˜ðþÃí»_n>ßÝüü Oã¾øF+nˆÌwȇz³X"Áâœ(& `#Òº©»Ã53˦joT-»]áÍcqÈ»²©ÃëÖ?sÿ¨ó}Àk‹ÃSq¸ÎԘͭZÞtaâ+´Å¦HV>¥šK ìÒžyš™
-TÏo9BE¦ƒ<#(ȳ7ý(÷»wŸ=>(N]¬»òš-›˜.i_Ö›²~ð˜gÜçGØ©î› yÈ‘àEIËMùPvyåUª-ê¼;z±t)Åò¦ö˜žÙ€µ><FÝù ¾ò¢ÂOÕì7Z¾*Â’êÈP¼¸Ó•˜%QÈ‘™›™e%ÖŠ¨.NTu$_«?J…ÌŽ˜‡æ(è­&Òè ûòê¡9
-¤Nø¶ªFMH÷wÐzñCmwKŽìÁz—O*ÿ²?¶ó>ZóhZî_‚Ið/ÅËÔƒs“Ë4[€s Ô2ö5>œkÐÏyðU¿â*]Ò»ç‘>€×°TÚaggÛå_êæ¹o& ˆÞR.ç¬:'b´R_eåð(–EÍuו{Sì½B?Rÿ‡Rþpì]9Ì!Ä[dËMч½w4
-Â7n±Ÿ]Ät{
-¬g™™YÒ*ÅŠñÚiÌÚcᾫ{O\gb&1VESÚ6ÇúXå›Í¡hÛ)… vלÚË$öX34Ž£(E4å|Lä¯mˆÊÔH¶(‘R«³TN–µFeÑ?8§Ç¢såî{Ïuá'p!o]¦7e€>a‰í k5„‰"!ÀI#Ç‚ôñXuåcŒ?ʺíòz]´i´æQþ»>²‰š›W•×ÔÝ®sþÝ·m0SóØ©Žß|~’“@:,’ð¡ ¼(|Ä3'£23ÄfT^–Ñ뼌öXNF×s2J!djȶåÃj[Vʼn€jF(—â2}=Ö #ÕšP
-b4¢p^@1%Ð ó³$NÖÕàf2‘Nfƒ$1;c#m$ŽQjÀ²ú¼wfÅðù¦Øæ doüÆr\Q¸™ŒE*¿-ºõ·hÌ Ò;§F‚h£y@?/ RñŠ0$X„!b9aøòªÁ{</ R’L)y™¸k†ºÑíBR˜A\2&ï¬$ØLòú&‹B²Fef1à<FÏ\OÞ=r1\=N8•çÑýàÂÕ3eˆáÖœ\}ˆc&´eɨÑýÍCdÌ \ ûÒœ™­ä—6ÓéNÞ"BðC20‰“Üö<ÀukX¤ù¹Äp…Ïà þvãGÎ:Â3Ík¢ÓŒe1L¾ðÌcCȉãr;LÎ8£L•±¯ÕuËd4]›¦„ÔM™ÂˆÔÙ$q(þ[¶ÝY…îÉL½!¤Xç®Çr
-×¾j}›¦ê&at\&­Ç:¥m¬BBƲlLÜ°ó4Ñ–½ÆùŠ†yœA!Œ|…ÂŽý½›ØN¾é…Æ!=Ãá>ïÖ»"|”Ÿ¢‚7ïŠ}Èw­¯ó¤Ë‚¬¬üµk`?Sv|ëc³/Ì`ö…ñAÉiˆn¤W²ed¢t9£
-ËGnQ,ðàF}•`.)D¤½Ué2Oxó$Å(Ê$5!„bMË,Ö0
-šyßD¬š‡HFÎ2k Á$,w‘ )Öy&ôXŽ /ó2.›7S«aL‚cÎøˆ®¿T«éW<=Ä„4 ¨¢Üœê %F3~™q=Ö çÆUbg@wýÕ]žŽMôqØHÛ”nRuž›œB¼È„úû¸Ù¯8ÃÍ‘ŠCt’Q8ë ;O‚x¢¬ŽñöÖ«õ~€SÓ@oÚɬâD0›g€$Òù÷±¦_ñÖ˜eÂüyÖ„:(ü>ŠE¨ "C­£KGPhh58u ‘3cù¸ŠÜ†òœJ ãîÕ{5*o»÷î*¡k¦$Fq€±ñaòµLlµZî!¾ËÂŽOyUnzw­‚§Á®àz] o^ îÃ"„BXtzÙÂ*Â4çç/+YZ˜lÁˆ¯æ/_v¿â*]òô²ø:Í35ì|ö²!H\ý(ärQ…àé±X—(ñÅæÍ\‹­ÜW´å.ùh×Æe.(¤è1š/>±ôå6êjëøpù%bȇc¼~|úð’²!d¥£ˆ_]ëcÀ¥#ÜûÂ7Å` ŒÊÞ„6£€bÚ¿ñ ƒôù U¡*“˜_c~ÒØõ-Ú~ÂË©í[Ä
-D1À†¥`Ôÿ0`R‡=yÛ&-Æbºî»ü)€Šº8äaãØíÑeÈXžÁÄŲ*X™¶%}«"
-v23
-çø ¢QÏœ’5ÊúÚËWekèžšc7ÓЋ‰?¥kí„™]Q=†Ö w%³Ý°Ñ`Á©‰MŸ?Ý|¼¹s?Â}ÃçÿýLržPDJ¥ò¥èF?‡è[ÓvçH?Ò¼x’ ™ÙDYËûß™ŸÆXü”˜ü4†1Û"ké˜M¤ÂµËŠÖÛPx&? p­x
+xÚÅkoÛ8ò{~…¿­Ô\>%ñcí]\{½Æ‹; ›Š­$Bm)µ”¤¹_3|YÔËi Ü"@D ÇäpÞ3[Pøc‹L*´\¤ZE™Zlögtq soϘÃYy¤Uë·õÙ¯¿‹t¡‰Nx²XßtÖÊÍ2¶Xo?//>~|óáõ»ÿœ¯¸¢ËßÈùJQº|ñáÏ‹XØÇsÍ—oß\Â+—"$F/¡Ë—~|}qžÊåúÍùÕú³7ë@V—tFÒôõìó]láœQ"t¦OðB Óš/ögR ¢¤²;»<ûWX°3k~:Æ
+%2¢2žŽð‚‹/…±L©Ò$0…¼øo]p0)“åú®€ãêdùþÃÅû78TË¿(åÅnkáõ¶wyk!øë_ ½üç…ÎY¶,6µyníäS¹ÛÙÙr[Tmyóì—r{îó¦-؇G;N–7õalS‚œÿõwÕ=]¬#Z)nNv_Z‹q'DJ ȈS"íÊ“ó#Éeõ°¿6D
+Ë¢ÞÞÛgøy¹±Û?ÜoóÖMXì¯EÓ:zo‹Ö`&ˆOp¹|wcAUÝ9
+Ð\ÉRB™Åü9:>Ðes_lJ#óí+ qÔÑ嶸Év­}yýáÒ<¿h´œQx*/ÿÐ[2°J¨ËL©""•é¸¹;¤U˪83w…ÝÕ›|g È·ÛCÑ8j>#ñW}rX
+<b<›§'`Ù\šLKStYT[$"ŠŒ]¤¬#}€éÃDOú8Û”Õ­´â˜=äPK9’dÜéžgÀPG%#™Ìá¡NÁòÿ¾+*»‘Ѫ°5-и²*&¨¸BÜU±=h',ĤÑ
+Áˆà0¦#áL¦$ã4í¸
+åÂObÂÏÈÚšÀtgéqSP2 ïbˆu0 5%3k™ ,™>éVTBOÒø šÌdäXpƒ¼bî[û²- UÙ—FcàÕ2ò¸ÜÇ!:­BœÚ>ƒc‡ñunŒ‡uÕ[Êù&·Ž‰§nÚFtÊœ¦w]LYÝ?´“†£28•jÞrºXÓ¦°ŒÛÚå>¤šá”õ¨TŠy*ÖûQ*‰é0dËɼÅЇ
+˨˗è¸Â2!ˆÖÞì ‡Ú‚A/ÍT”L¾<‰êð­lFiHH
+ÇtË¿û0B7oŠS²WP¨Tœ}kFö wl[ç¾Hø1©éËø(e*ç)X#$ÄɈäYÓp”;õ^GV#´Ü;°1DxîÊG‘®Â ªW·41þµû=„fÌaMI²ö{=滇Q—ŠêÉuÈg&üžrûXu³+òÃÄ©\Ò¥‰äõ ’i=`œ@u¡OèAkF<nú¥pvgŒßkÄ¡h‡Ž
+iõ"Iþ¥E‚‰ò¼t°f Äcý¬X¼¼Í ÎuB¤P'(X#¤GŒ†¢D²¤Gûz¼ð¡­iïÛ¼1Å… ¤¸Gê´¥e²,òÍŽðZ«µ 4Ø_Œ³)ms¿ƒÒFTô{—1ÈŠ%ïUÈÍ]~°ØEŇi•ïG¯ù²<vðÅ?lŽÀnšê'qM²,n Ç“§Q[Ä–; 7 'lì6S~ÙPîâéáØ×¥©m‘ æN †’[€• ³þé¶Ñ Ü²žÓ2[J°yW¨V­µëaÂ~iÎ'À¨ø–oZ{ÓA—û¼E-@¸»Ö3‹wb rx3w÷‡®«µIA…÷¸-‹1yƒA¬ÒŸÍHQ:\§½\àŒMBGbî¼"UþμDR1e¼ŠèT³Æ ¬¡=‚ú}ùt@×[Ù—Ò=]7ÛÜVÛ<¤Œ8U|s=»Š³o¼ÎÎñæËbÙ¾wg¡‘œ4ë礿8ud,#TÌ°OîÓ üw1éõ¹D z¢JìbM{ý€…Û¯õ±¼+ÂxàôÛvw5âÿ?Àg®wØ‚cáLOœ#`$²ˆ¶T³ÞI^ê›^¥ÿ’&As,úG³ ©œïÓpÛ+“xÝ#y,ùÑlÂC(c§L=!œ q*3bÉÉÐg’ݤê£øê
+@ø¹ :Cœ4Îк·VdfUî»È0}¡íëGÓ¾ÆÛáµ/Ñ|vdß‚¯2š®R){·LqæäÒ©‰TNS™ýP±SÕ.jîïw¥%rÆqï¥)ᔆ ÝîÆØO‰ä1û‘ðÛÊr.ä¡oÒJ+eúÇõ“?²½7°ÍÎ{pZ×å®lŸÏxðI¿Â`
endobj
-2081 0 obj <<
+2083 0 obj <<
/Type /Page
-/Contents 2082 0 R
-/Resources 2080 0 R
+/Contents 2084 0 R
+/Resources 2082 0 R
/MediaBox [0 0 595.2756 841.8898]
/Parent 2059 0 R
>> endobj
-2083 0 obj <<
-/D [2081 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-2084 0 obj <<
-/D [2081 0 R /XYZ 85.0394 751.281 null]
->> endobj
2085 0 obj <<
-/D [2081 0 R /XYZ 85.0394 555.2948 null]
+/D [2083 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2086 0 obj <<
-/D [2081 0 R /XYZ 85.0394 126.1169 null]
->> endobj
-2080 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F55 1035 0 R /F53 1027 0 R /F41 935 0 R >>
+2082 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F53 1032 0 R /F21 714 0 R /F41 940 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2089 0 obj <<
-/Length 2725
+2088 0 obj <<
+/Length 1929
/Filter /FlateDecode
>>
stream
-xÚ¥Y_sÛF÷§ÐÌ=Tn£Íþç2÷ä8NëNãäbeæfš>Ðms*‘®HÚõ·?`±K‘§sãk‰±X
-7ÏËUN¤YÙf›‰ 똴Öñ!¶†¦\hÑ BVY&´v:_–¿|üü²/Ë&ß•yCš\?×M¾­éá¼*ëj×ív¿®fJ[ähÁdêºÐ'.X¿Ç,N'IØ@ç²)‹È»P† Aº×¹b´‰” ¥Ì¤\5Dªt."ê«”É>Jh/~å\޵ॢ*‰ˆ”M>ið(1Ø;¥à}.«‡º¨Ç8T‚%ΪÄ$¥§p#@[i0ˆ¦A)AXôDxL L!Õq1ø~#|1ï.®Ï?_~Z^~¼:bñ)ðMY<°àÑâ`p¨˜7÷9&̳ÁÜžá ÕíaAB¨(n{¡4±¶äL'Ž
- бÜlj?©`"éºçéHèa¹NûÀXPpiè0ƒGÁ~p>ДÏ/QqëÐ߇‹C„3”Ú¯]¬'VWp¦2©é·J6?P÷ñX@T®ýNè;%-ËR‹$,\T‡ŒùŸÔ…Ú “JgMn’—Ìc¹Vc?ƒLRÖŸÛ¸Œï,y·Y³ºÆ1g…³(ï¦
-©eç‘ciDÁÉѸƒŒ[×B•¼~NÄ8¦
-.Ç#’]@²ëì¨4"%kÁÖo+M²=°D@Cºø!¬œžÈôÀI(X:cë1Ämý
-©q+Qµ»U¾ÀzŽµ|âžo Rñ¾™0 tiÌb=Àoz‘Å£ZÇH&¬¦Cl!ªC¹‚Îw¾òý#ÐÐ H ƒ Å·Ý@©ý |§
-ƒËOšæ¨A$’ ìW¹×Úäu€SÔmàôÀõ
-…F±$u²×jÊ$šIƾNöÛw'™áã£Ó¶Åv[ZE9Ž†ä]«ƒGä¬ð›Ñ£ìÀø‚¿BØKPáHÈè¢f©”ÏpT¶Û—( €Cýf=’ù¤ÒHÏW….o‡×áòcêÐ+㶻7û¦¥-ø$Wx)©+Ã_¼—Ø>ëP׆™Ã“(ãè&0…|…òʺɳðà-›x¿J„0ŒÑ1þô­æ™wÛp5r9œ„æ#°Q¾”`ÊìÏœFD1X¿¡j@ ÷—4@@»ûe„ïï”1-4ÿ2v·/–gX*:“ÆÈ¡Hì…»øþ®zÁs¦;TAá¾s|(»¹ÉO$*ò,G}ÒMøt<Õ»Ðñ!{®ÈS†T]úסºà+ýê‚,£1üÔ‘#•ÃYJËoŸ5ð[Jêï(4Çмó78öW‹Ðæs&H¡ƒáí³/H b-L,9H¥ä#t
-è¦P¥p¿›8Gy ÔðÙÍS‰,±zÐñÚäÐØl9Ã2ÛÜU;ØÍvú]ÕÝ£í¾X_THEJI¼¤Ý=Ç>&öBýã‘ëôZ&ןŽ]@Jß3ùnNùvæßØ×éùªÝ…oYÍæ™&«’Frþˇ³óŇw&Ü“¥º/5º¦êm÷÷¨ÝÍ$ÇþÌ‚T<³ 5£Ç:_‘ ‘»”ã®Wè_táDè@XVç «‰
-Ö¬Ö¡ÑH²}Þθ?ÔS÷Á}_Ä˽VxùºŒxÜ/é/þBg㢎÷²ñæÝSƒ¸uÕúǵpÊ¢›úð -1~­ø¢Ä»@ÿ÷Gáýçr0åœÜïöoClT
--%”<P=~>>Ôý€Û-Òendstream
+xÚí]“Û6îÝ¿Â3}±§k†_’¨—›q²NºíîÞ^ìÌô¦íƒV¢mMlÉ‘älÜ_ Aʲ­x{Ó{¼Ñƒ
+cÓ—ÁoÐa+øy@‰ˆU0|„Ç|¸È@@
+á)›Á|ð¯V`gÔNís…  ¸ Á)’ÄJõû‹‘ˆ1à‰DL&Žþâ¬Ï_žËø+ÓÏûÕùRU@d$;œ}Z=SVÑÑS"ƒŸj]Œc:ÚWº¼tkË*/VÄ4œA¢ü3áà?‹7SïóB×Èÿ¬¹
+öµv”¦DJ^Ôºj†ž Óݸ)蔺Ü[ u‹AjŠ.ËÜš–+·NÃZch™Šˆ”<
+ŽË&·š€Ü¬“ÆCŽ”»½¥…
+%¥^¨ý±ˆFØ‹!Yÿîí8`Z #©0’Íï"íåè[3Ú»X3Ц€AÐ=Pe&2T !s<EG?Ó„C­¢^_˜[{{÷ä’.ËÜ~vÙ×q–Áºe´&
+F] l6‡‰êfæÑHC[ûÄv…Ù Î’‹…;|§u±Ãl…ÍšÕ@eÿËÄÜUºÒ_û·¬Ü&¦dX,O?›ÍrâÅÿ6)ûdœgå»ÇéÃÌ%]¹Õ‘û›9ŠáÚ´Ãpør‘×ys,ƒYÞäöp4ELÛ³ ÆÏuUÔ>_5Ìp‰ÿt­ÓÏ~F§·• ’.R¸‰=‡̼<<€ÕO#Çl9«é°Ó}ñp¥Lõ:ߤ¬£;[‰ãa†³ñ°°-ŸªSlÕy±U£%µ8±
+fâ>Qmµ…u”ÚÓJ7UËëÆ)KÐ Ì…žˆãªìÀÆýküû()ƒP{ª†ÔwÎE‚‹ @/km⬘[ j3ðB¬±M©Vešh»ËâwJEžz©Øp)ï6ÍÖjR7pҙôgMÕ|kŽb+{R³8}|ÿ:j‰D´Ú$ ? a»¯G+õ'ÒL‘±ÓL¶BiCmiçUÉ*2ÉdG󥳧+´>“Š¨uAØT+»ÓPCga¦àõ¤é³¶aÌ¥—)ÂÄ@½}œÏgï¶] ‚ox $ÚÍÄdƒ"¬Aõéð:ùª‘òñãüîÃM+ý—Ù¿
+Ó®ÞZº\öþ UÏ­¥å2Zßè&}SAÙ|…^,Ï €N›Àž×-h¹.M8©­,ˆˆ`Axjƒë›;½WžA'—/þ6³Lö›æ;Ø÷<Psã¯x¬ÃuÅcžËXû †’É.#‰£(t7ƒ¥;`»’Ì•æ»;†YÂ¥.H̨tL«×¤7ì$QR°¿jN)Œå™À…'^3È[L>ëÃy48…ˇM{5-×e<NÒ‡3A åi@ž“ZOBé:ð"-³ö"ëï ?=LßMnÄŒx•ÀêꇹûŒ+jè˜&À¸Ò…m¥ÚΩ7ט‚m½–k®+¹æ¹þŸk×rmWå_]oz’o¦u¼’–ë2&§ù&"BY¨NƒÒæ‹»ùf°r‰ÿc¾Ìæ›NòÍžÝÀ•|;?4àÂO‰à">}2™Ïf˜ºÓûù?_71g!á ÎLP1¹ÑÁ” Ž˜é/:cp¢v°X°›cÎڥܼº¯^yzûéÃ_~Šùh‡µ˜Ûì
+M…cµ6=oa;t ÛªíËR÷5–-£uÝÛ›ßÎèÆMþ\%Õáìñ!÷opiuØ5åªJvkÿâQî4˜w”úæìn믎é:)Vþ½Î=ô-÷;ûÀ‚ðFèÉ÷žua+›·ØžGÛ
endobj
-2088 0 obj <<
+2087 0 obj <<
/Type /Page
-/Contents 2089 0 R
-/Resources 2087 0 R
+/Contents 2088 0 R
+/Resources 2086 0 R
/MediaBox [0 0 595.2756 841.8898]
/Parent 2059 0 R
>> endobj
+2089 0 obj <<
+/D [2087 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
2090 0 obj <<
-/D [2088 0 R /XYZ 56.6929 794.5015 null]
+/D [2087 0 R /XYZ 56.6929 668.7228 null]
>> endobj
2091 0 obj <<
-/D [2088 0 R /XYZ 56.6929 752.2635 null]
+/D [2087 0 R /XYZ 56.6929 314.4341 null]
>> endobj
2092 0 obj <<
-/D [2088 0 R /XYZ 56.6929 690.7232 null]
->> endobj
-694 0 obj <<
-/D [2088 0 R /XYZ 56.6929 652.8084 null]
+/D [2087 0 R /XYZ 56.6929 167.7554 null]
>> endobj
2093 0 obj <<
-/D [2088 0 R /XYZ 56.6929 620.2916 null]
+/D [2087 0 R /XYZ 56.6929 97.1798 null]
>> endobj
-2094 0 obj <<
-/D [2088 0 R /XYZ 56.6929 585.1376 null]
+2086 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F14 741 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
+2096 0 obj <<
+/Length 3033
+/Filter /FlateDecode
+>>
+stream
+xÚ­ZKsã6¾ûWè¹j„àMâ8¯Í:µãÌÆNj«&9Ðe±F"‘²ã¿Ýx
+#g™‘DQ¦fËÝ=ÂÚOWÌÓ,Ñ"¦zwõã?D63Äh®g÷ëˆWNhž³ÙýêËüíçÏo?ÜüçzÁ¿#× EéüÓÛÛßÞþËÍ}¾6|þö§wð(s#ˆ1¤Ótþëí‡÷×Þÿ|õñ¾'™Q²üuõåO:[ä?_Q"L®fÏð@ 3†ÏvWR ¢¤af{uwõïža´j_R9Q9Ï&tÀÙŒI"¤æ‰”!<ϸU~Ñõ‚QøòC½ZâÛ…P„ñL[’ÛbWâ<ð‘NŠ»!}×êìÎ37ªñ=;jËÃSypãeSw‡k–Ï›­›8vÕ¶ê^ü 1#F)î·š°œ;Aî^êfßVíXít'@Z"™4Sjb 8WÆ“fD U`‹˜…U¡dfÔS Ÿ®A_î+T¬'8B0;!uÛËrQ¬V‡²myº‡ :×üÏÀy9Á)×JyRPìºz\¬«m9ÁV+’)!Çl¿¾ÊökùrŽ§ÌHÎi6æÙ¾ÊÓÛÃ)G8mÎ%sÜOpË€‡Œ«ÙÂYŒsê}sè&sA zäˆñïýèeb‹Tg ˆ±áq–&­æŒHeòoñxNLžçÓþ¾è9.b–ÖÑ8¬2nØ°3ŠX­&>q"”Ðé§/›Ý®¨WSN·`2'ƒŽw>çá>Þ½ÿõæóýÍ/·ý[i0Pàœ >q28'
+¸"A ¡€ªy·)Ý Ù—‡¢«šÚ?®Ýoá~|`‘7¤LÎ!*sÐ7_8‡¶\•çS©¹4p@A5Ó2ÃhôyG‚•gZøíž ¿ÏÞ}ÐSµ*Wn¦
+ß°õïnn?Ø0 S¢åÁ‚]D¶ÊmY´e _%E>¿YO¯(É%ŸӸ "
+¯PH#@¤§æ«•ÒÛsÕmÜtݸ™`vr[Õ¥›nöx žEsp¿…•öñ¸+ë®}s½Øwî…ý¡‚IOç~Ú º§]m°Ëáų[;d’pAuêÒÎ*0÷èÞVrÕÛpëžœÄ0èÉ‹§¢Ú[ÿ8È?¢®|fJ¾…L9XW‚_T9|c¢7òÝîXWË¢CS™ò
+Ç‘•TdÚ4N…L‰ã¦îçþýgGžS—Ë®ºfó¦­KšÁ›õªªå ûúvª;+ÄÊ›ž2±¼`
+r¾ª«®Àm@¦ê±.º£³Kk’RÌojGé´ TËãÁQÔ[éÛ`0ÊŸðØÿ ð\ËWmXRG­ÈK VŽÊ\M°”ÓÇAk«:ˆ/AÛ7Š­Ì$ÊÃxäW™ë‘úŠícs
+ÁFšNLK3¿ß‰¢ ÕÀ;ÜýÝÍO‹¶{ÙZVùXvn@è,l˜aœØ˶ó<ÂJOï^g½ÑCÿ¡ßo÷`?%Ê_øv»M6‰Î=²°æ‡îÞ#Î> ,7èÄÃÎݱõ”!¼€‡Øòðâc‚û™ÊýyBF‚%Åw§þÀpqt0>ñH†ö T>ñ;9ëæ¹ö_ÝŒ¾>Ε§„©ÉA´oŠqø%&à4wX…‹Ä.Ö+L#õ”òÇcŸÉa g\@æ^B1_•]yع<Ó›æÙÍ»u˨+–ŸÜx²P]ˆ¨ºà!®#Ó%˜·?»<˽‹:?öŸ‘ºqH xèvPyCìuÜúÅ#Ú奒š¦_,`º;)}½!4Ðrž_.JbªP×%=îÛW"*’ŒäF‰³•H,!ƒÝ5§æ²ˆ=Õ„Œ)ˆRDSÎS!kË ÔÍ) O­.ÔK kð‘«P„6å±Z¹}ÍsYºdäb‹§t (ý+,ŠœžW3"yªRTžËÔ>·]µð£ªÛ®¨—eƒ ¿¶Gûïz`\·Øn/ óvÍî6´­}jl¾Žüæó“!˜ÒžI¤ K2è¢t€gÒF±vRF¼b£Õ TÖF—S6J²35mb šÊ¥¸,_O5!`b `—”‚%N(VlþLÙðÕÐf2²Nf¼%13#q2ÄH£Õ@duxî̈áõU¹.ÀÈÞL¼N&cAÊËnù#s‚òN¹QÒv8k
+Ág™gð ùvåF6:Âo\ÕàŒŽ B–(½á”ÇÀ‰ãj=,N$£L•±oõuÃd]«¦ô‚ÔM”ˆԙHÑvùwÕvçN¢dÎËQ]p¸@e®}5úmºÄÝ# JŽË¢õT§²¥.„h‰eY*\Ü L‹80mÙ{œkh˜PÅ™
+aä&Í÷va=z§7ûâ ‡»¢[nJÿRqJ
+Ù¼+w¾Ú5®Í³[Y¸c× ~¦LzêiØùöEî@É)FÏÑÙ+µ2€§L ¾œQ…Ý#Ëû;¸Qßc€9[â½ÛÊÖðäD
+(*ZB8‹-!l:°ÐÁ€¹Mc ½œûòÛNb…SÞµ@”&Ge³d‹ä’`[€Ãà4Â8I#'>†é÷ ¨Ê¤xE…Ph‘ .?®bhTÅЪ¢:CÕYF$¬˜P—ý9¦:ïÏ=•õçý« 4ôÆoæØFT—å
+Dr%¾Ì¡„äz$Ø]YO6ìʵ]-‹‚ûÖ}!¸!"ë7UzjšHâô:#“°}W;2?x¼é¹˜JÚ¸íÿ:d½³Ç«T½®cª Ǩìñþ>ÞÒ@à¤8/nˆ&¶LtL&ç&Ýòc=4OÁ3šà‘ÛæñŠ‘óJ
+x}ûÿ¦Ížã„6t’QøÖ už€x¢Œx{íÜz7RÀih‡IÚÉdâD0“WmnÈØh¿W5=ÇWTƒw¡Läÿ»j|>ü!˜…o!âB­CJÇ)E ÕÔ"g¹Ýbµ¾=§â¶¸}tÙ@%ÍmûÜ|‡Ã_š)‰((V(׫ÁÁ(V«ùð]ñèw|*¶ÕªO×Êg¼\.KÌÍ Á,ÂY€E÷ÕF¦9?ØŠCÅ,rˆ¿LÀ1ý݇Ýs\Ä,O[A®Ó<SÃÎg@ÐæltInQð´/—Z|¹z3uÈQînå
+éêA£üm¨Œ0¿J1¿ôåG¸ô-Û~ÁÙ©éoˆa
+òpç”^žõÕüÂUÛx›
+endobj
2095 0 obj <<
-/D [2088 0 R /XYZ 56.6929 520.6753 null]
+/Type /Page
+/Contents 2096 0 R
+/Resources 2094 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2103 0 R
>> endobj
-2096 0 obj <<
-/D [2088 0 R /XYZ 56.6929 462.0998 null]
+2097 0 obj <<
+/D [2095 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2087 0 obj <<
-/Font << /F37 799 0 R /F53 1027 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F48 950 0 R /F41 935 0 R >>
-/ProcSet [ /PDF /Text ]
+694 0 obj <<
+/D [2095 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-2099 0 obj <<
-/Length 1782
-/Filter /FlateDecode
->>
-stream
-xÚ¥XKsÔ8¾Ï¯˜ÊeZ,ô´¥¥8’@€„
-Øíf,0õ¥µ tEP|ÿqéDoÝ“4›'«¢ ›lùJRÈ8ðõ,)uÓ>pév$»-6³ 8ÐÎ_˜#8ªé{/L*ÈOíôFCµ·ZíTÇúvÕ쎪۬i‡óÛtsé7õšé6W’¦Ë¬i²þÆ<¼¬—~¤„pøýç=q&EÃhÜêER\ÔKH&Ègi|Q&³°LÕ¨3ö¡ÈÐRìD‡Çó¿¥xÙ|“ÅÕ9—/2ž?9øfŠ9+Šg//¾íü‚>ª?ãAtWܱí¼OôiôèùÚ¼[¿]Ÿˆ¿Þ=_½zøðV_«\aŸzB!(²¹rß• a‚ä¼þ’!-ûêŽèÞH½„·'fLÑœ­ŒòLë¼(PîùªòɉD¨ùHEK$íï¼³Ês .¥% €exL(üLra ÊÂD
-l/ð]v7Ð?ýŒ3¢bj¶OÂ_Oû"W=‚ÇX mYä'ûuZ8۲轰ä½*::Ü6ÈK¢
-j$nªC $¶ó Xñ‰² ö‰ê,ÅC]¾ÍÖ—oÌp¬
-endobj
2098 0 obj <<
-/Type /Page
-/Contents 2099 0 R
-/Resources 2097 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 2102 0 R
+/D [2095 0 R /XYZ 85.0394 748.1323 null]
+>> endobj
+2099 0 obj <<
+/D [2095 0 R /XYZ 85.0394 713.0047 null]
>> endobj
2100 0 obj <<
-/D [2098 0 R /XYZ 85.0394 794.5015 null]
+/D [2095 0 R /XYZ 85.0394 648.4882 null]
>> endobj
2101 0 obj <<
-/D [2098 0 R /XYZ 85.0394 668.3939 null]
+/D [2095 0 R /XYZ 85.0394 577.9033 null]
>> endobj
-2097 0 obj <<
-/Font << /F37 799 0 R /F53 1027 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F48 950 0 R >>
+2102 0 obj <<
+/D [2095 0 R /XYZ 85.0394 396.1161 null]
+>> endobj
+2094 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R /F55 1040 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2105 0 obj <<
-/Length 2487
+2106 0 obj <<
+/Length 2231
/Filter /FlateDecode
>>
stream
-xÚ¥Y[oÛÆ~÷¯Ð£DÛ½_pžÜØÍqÑØ9¶sp€$2E[D%R)»î¯?³W‘ÒÊrQ×ËÑììÌì7ß,ÉÃ?2ICÍHŽ&bT¬Îðè Þ}:#Af…¦}©ŸïÏ~ú…©‘AFR9ºìéÒkMF÷óoãŸah*ðøöúâãôãÍõ/Ÿ.¯'Sb¸âãó/_.¯/®þ7™RA$1>¿þzþ›Ÿû21t|þéònòãþ׳ËûdVßt‚™µé³o?ðh;øõ #f´½ÀcèhuÆC‚3g–gwgÿI
-{oÝO³® Q&iÆ”ŒAF:p†0H2Êœ3®Ï?_ú]Ý]ÞN`ûÿ…‡ûÛºåêÓ×Ûs»Ûû«›k»[ÐÉzþÅ#E˜3í”Ý/ÊÉ”9®g+7ã¶Ü<—?»Ú¶=„·ESǘ>m7¢ÇåÜ¿íÿœE¹î¼ä¦ž~~S—EW5uÄê¹—‰¿óÊŠæ©®þ
-u‹°âïå«Ÿi×eQÙÅãªUm7h·ä}æ“ÅþÐ훓޾‰D†IÂVÆÚ†À¬ÇŒ‡Àé†($ízËò,HÍxÛVõ“]›Eó˜Ý\çÌo–­Ÿi»YW®Êºóz+Ìü:,b??jAJ%QHnnÌø®,÷ìh{fã¦Þ½Î¬þRŒGn ÖüÃŧ ¤(UÑÇÔý¢·E›x°E÷tƸ3xu}áGÆ?Î竪®Ún3뚟º-K÷º?û<«·³¥?F¹yÙͪe‹‚uƒ¡g1bͺ» 'ãü·»›ÓÉo³à;XÃäƒÿ¥›ÚH<•õþ»ì¸hæ¥'~Þ­ÁLß·J!¡`ì}ûÏ<q¸"5¢RÊ”¯LH3À¦wοÞÿûæö´[®ê®ÜÔeˆíÝk ¡nÂ@‚5›®Ú®vërXAÆhpŒ¸‘:¡6@4ÆC¯Æ3Ë8\ ˜fÑ'o˜FJ•â•´8{¾CfîâæG/ì
-gFK6âà+®tÙ ˜N`ÿØGŠ NÚip ?8›ó£ÐáÆ%8ôÛtö#Žü¦Ä MÀZÞOZ‹¬‡PÀ Òœ‘ —tà$-…Ø©|¬–Cå"~Ï(—
-l)ÁÉë׺
-ÊÞ`É €
-ÇêšïÚ¥ÃüSÙùÌUÀ/ 0û9[´¬h&"·¯­=‰/ ûB}ˆ–XqìÅV0E`Ыۉøâea)¬ùÎÈÍÅ—ÛjÙÙÆÊÿÙ©îŽg\à÷ Ó«{6€‡§8¥¤äDä)â$ß‘º{ÅÚô @î8SdvîkÂ6áXoºíÙJ@Ý}K¦À€~*å!Z1í×zˆVG t^f­0ÛŽÓÚ%+.YÝìãl»ìüE³ZyPêU].ý›4 glBÆ>8f‘3áp=ã—Ëæ%_åÎÈ8 M —+;Á²mm—,ƒO š1ªÄ^æUù€zÌ9?9†8pê^ä·˦ˆ·‹¦ øŠ.Œê&ÜXl7®ÝâlÜ”±—)aËMíz·ÛºÎû ¨>´iÕoU¾’+ ¨LÅdrQi½x¼‹þ.BÉv FîþqÀÄ ë~°@¡c' ?PZ»DX{îïÈÖÓ*Øîòz9+ÿ‚†[Ÿ­j¬#±åk¹8Gy ‰ç7@$FEýp,¨ö,<•m¼AØËŒòϪí<¹Üzél+°J%¿ž¢‘€bp–C
-Q{¿döRèêÑ®ë‰Ç«Æ{×O–ËÙCc[ÿçaç“
-WË6&’Æ”€}ü9[­— ý½>çÑ^Ôêx÷ #«Ü>ÝM3<Ý=6<!CÍæAÜ-¸jºûf\_›­hÍv™„óÎøÂ^ëïJÉéîT˜D.mâ5Û.ØšeñPÍØ› hjÁ[}þºÝn£ +X
-ïÞdòvn9ȾkOt…T§Ò“Î$?<“üïgÿ,¾yÈ‹2#·+DSo“Û¾Ôqr›¤œËã-›º\›ðÞ%[ß4iÁaoÛ–¤2Æ £ L’P5´î.Ñ-›îœ†Ï0hý5{¯  ª¹ó[`P…‰‡ªkí5`ŽŸýÇ ;YÆg÷R–A’­.Ù` µæTü †:e6äƒN‘!¯Ù1ûM!„P}4ÚŽ„îÍXïdŽG:ȸ8¹8Ûïu$só9ˆ34cJ/yê$s`Ö0Æ̲¾]_CEíר<N@?ÅTף;Nt,5û½
-çøûãkìvSKên)z´h÷Ët]6<õ«w´=\ƪÿU#÷™Ú\{O•q-Nñ?þ„»ûTÍí]š>Ò…ÆÆÁ(k8aü0WÃÇÞCÛÿk™·*endstream
+xÚ¥YÝoÛ8Ï_aàNÙ­Y~ô-MÓ½,ڴפÀÛ}Pm%N–r–ÔlþûjHY–ém‡
+™]Vyߥ:-¢_…Õ íDZ?1J;¼Tm–\ÃþQ¸pÊ]dØ·ýPä`‘燎s«{®¢ñ¯ Z`{õWã줆^†>Îózfa4{ùÒ~z™Üðóω-/[Û¢^¶|UY)nŸëòcvÿøAnÇ
+Z?l |´xŽß…®#)oz•ùÚ  å=¶’„.”òØîO$Ô ˆ——^OÿæMö­3˜>k,;%‚–zjo4Å}ÞWÝ2XàX«‰‘*Þúð<­ Ü7UÕ< HB‡ ððD‡Aš¨_p –’&×èæ¶E‚ñaþ¹G¡s– âÝ*\E„x˜Ý4m‡£§ÒßÂüèkØÙt„¹MQ¾Òþ¡¼À8r}(¿Å y åñ}r¯EJÄþù}sŠE?R½nRp$7Äng~ —¤W WC>^¤F'ÂM õsS'upb¼—xB4Ž ^±è‹éàéO›ÒCÆ”'\ë®ô:盼í9F˜Ñ³ÛÞÜ<Œp*Ý41–\ZL£üÕm\˜Ÿþ6—]{Áµõþ>>@nƒbvò.'QÊ©i¯¤'·_ˆÊõ )‡VIG ±ØÁzRø€dß¾óq6gíÒrfüeØ|Ï<šJ1÷³vAX ~îã1Cƒ Ñ“ðºÍ»Õ&|D¬föИþºš
+i£`²ø9
+qîÄøY{l%š~·*–¾žûZžøT"aŽÅüð¾9ñ+‚ÿP-Dê¢MÇ»ñÿý Ãþ·i µ<ýã7Ê×…ò¢3!D¿EËþ'É”ðendstream
endobj
-2104 0 obj <<
+2105 0 obj <<
/Type /Page
-/Contents 2105 0 R
-/Resources 2103 0 R
+/Contents 2106 0 R
+/Resources 2104 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2102 0 R
->> endobj
-2106 0 obj <<
-/D [2104 0 R /XYZ 56.6929 794.5015 null]
+/Parent 2103 0 R
>> endobj
2107 0 obj <<
-/D [2104 0 R /XYZ 56.6929 752.3759 null]
+/D [2105 0 R /XYZ 56.6929 794.5015 null]
>> endobj
2108 0 obj <<
-/D [2104 0 R /XYZ 56.6929 668.0781 null]
+/D [2105 0 R /XYZ 56.6929 703.1515 null]
>> endobj
2109 0 obj <<
-/D [2104 0 R /XYZ 56.6929 607.6906 null]
->> endobj
-698 0 obj <<
-/D [2104 0 R /XYZ 56.6929 570.577 null]
+/D [2105 0 R /XYZ 56.6929 603.3192 null]
>> endobj
2110 0 obj <<
-/D [2104 0 R /XYZ 56.6929 534.8112 null]
+/D [2105 0 R /XYZ 56.6929 540.5015 null]
+>> endobj
+698 0 obj <<
+/D [2105 0 R /XYZ 56.6929 501.6992 null]
>> endobj
2111 0 obj <<
-/D [2104 0 R /XYZ 56.6929 503.6098 null]
+/D [2105 0 R /XYZ 56.6929 468.7926 null]
>> endobj
2112 0 obj <<
-/D [2104 0 R /XYZ 56.6929 440.3004 null]
+/D [2105 0 R /XYZ 56.6929 433.2488 null]
>> endobj
2113 0 obj <<
-/D [2104 0 R /XYZ 56.6929 370.9227 null]
+/D [2105 0 R /XYZ 56.6929 367.5092 null]
>> endobj
2114 0 obj <<
-/D [2104 0 R /XYZ 56.6929 274.6697 null]
+/D [2105 0 R /XYZ 56.6929 307.6563 null]
>> endobj
-2103 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >>
+2104 0 obj <<
+/Font << /F37 803 0 R /F53 1032 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F39 900 0 R /F48 955 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
2117 0 obj <<
-/Length 2188
+/Length 2228
/Filter /FlateDecode
>>
stream
-xÚ¥Y[oÛ¸~ϯð£¬YÞE>¦m¶'‹6ÍiR`Ý}P,9*K^Inýõgx“%™¶ÏÁA€ˆ¢Fäpæ›ofd²ÀðGJ Ì4_¤š#‰X¬¶WxñÏ>]/³ B˱Ôû§«w¿²t¡‘–T.žÖ£µÂJ‘ÅSþGróðp{ÿñî÷ë%8y®—ãäËÍý÷›ÏnîáZÓäæÓíãõ’hžr"ÌÈIœ|»ÿøaùáëý¯Ÿnï¯ÿzúíêöiPk¬:ÁÌèô÷ÕáE'øí
-#¦•X¼Â FDkºØ^qÁàŒ…™êêñêߣ§öÕ˜)¸PHP.KA‘Â4n/Œ°€ó/SNÔú`/Jbö
-RÆ^ËÍüœp<Î9YŒ;Ú2E¶d£-µFœŠÙ–mY÷sFæ.ݦi{?Üo·Yûænšµ»ö›ÂOìú²©ÃËuîí5QÉË~[ ÷9×Ì”kD)Má F‘¶ÎWËUS¯_ŠÚK•—àʨFGxðVO AŠyÁ5#©3® RÖ5?œRBŒ$€Ì+õ£x«³m1W0…Ò4Uçu¤"Êí@8C©ÐdªÝã®X•bL kq|$Rn`U³#çÇ‘Œ1½e{˜¬ûr•ÏV „€Í—ŒªäiSú=¶û®w£g¿Pæ.?³ªÌÝ0o¶YY4°Ž[,Ý™96AZjñp•ël_yÂnÖð|ì"I‘P\Œ¡cÔ<† O‘¢X^‚”æ•a?Àf,u6ƒ”…Íî"lv&Ú昡™óÕ+Eôš †
-°œ)6A Ó f°j æM03-’Õ&«ë¢rO¬¦vôº)l”±¸ÆÁ0Ïx=x†q¤Y¤ª²ë‹Ú«²nÚ 
-l¾ò$cÔYÛ]›md[€×1ç#LDv“ñaS@tÊ•ÅE%ÇaJø–s4Ú+¸ï4˜¨BÄíy0¤Î€)HY0µ0i$"×l×euÌB’„Vê¼vƒTD½ ¦ä…ÉT¿)¦7|À„Hºfoý¶*Ü´! suÚ:™<ë37ë¼HE DT¿8‡P³,°TÓ–ÿX’'JÊ’;¿¦œÂËη ÆgŒÓ½ê@*)0•åNI’ºéÝÔΡíg™n"‹P!
-*íð./~¾óçŠ$1•88˜ӬZü½/2wÝþ°D¹*~17þÐV¿† 2¶¨yh)®nçºè:wj¢¤É"Û•eÀ2Ÿ—®=]—õnߣÈ)•©Ž(™À ôŒœQHÄxìÑLLÇùÈg œ6[õ…±Ž†µ†—lÝÕ,Xù9àˆRŒE‰MfƒñMRÕÀ´³p¶@3F„ª®Øe/¸ßwEîfÊp‘ånÚÙ6”=Ö?Ö&rê³<·GÍ*'þÜ;R®<‡’Áx ƘŠHåË:7I9@´ßd½ÛuæCxf}èÎO¡—©b3Ôoš}勵gŸrÍÙOšºœ%´±ÔiB¤,¡u±ìˆeƒ…²<o=œ§EUŠáçU BÕ¦%оÉÇݦ% þ§$¹{pF5›;/q.+Èw˜“ôRVdˆ(%çYѬnyÑì?$h3;$h{3ΗöÓùª"D5ûßò¥£R*1]ИSNoÓ–¡jšÝs¶úá[…‰a‚О9E =X
-­çy,Ž¤Î`1HY,öÑä
-É-ølµi›¦ÏËöŒPej ½ãY婈vÓÜJ‘æ`߉zß9i¼–ýÆúM iÊ=¦Bü,³ˆWÁq4•Áõ®óK6îjÉlýæn _jà—Ò9kÕ7­rñP#`ÂÉeÄ딄Æ*·t{­’½×
-,oqÜô†¥ —É”åKßRQlJ—1,óҜͱ2ƒøؽ&;˜pší€6UJG¡âí…! 6„«W–u)…%¯mÙ_]µ»wƪ .ùé%\2ŠØX1‰~ffxØ BŽöYRú+l ëÏv]7{Kfêí Êjš †°8âJ‘¢TÒ‹Ü…‘Öìb¯Å¡ÆLSq¡×KŽàAÊB}±×‚4מêµÎê5ôZÇzE{­‰b>v­»lìJ~*ví[älì‚•)ÑóØ Ä“®èඃ浶å”®gûO‹YF¡^Äú¿C>@ß ìàËv© °•ùñASúòÀ½ÓÏUðbÐK²ª §òsî @˜Ïʽ¦®Þf9èP=šJoöð ã¯Y…ÿ4¶É|¢*ç­`ZáRñ‹/£ìq=ÖPŠA»‹¥4jBM‚Ýg›Ûßo¾<|¾}Œœ»W8q­Õ“ùNÚx•ªªyØ”CÞdš\HèÔ$¡Ê}s\º‘G*Œj/5ÇÞ©°…†±â˾µ=Ø/nÖS¶ƒ•mº”PÖ`jØr £éñ¿¥Ä8xÞRK0,¡A+MÓd†™»tÙvWE) Æ&¸6;ÇûÅ縶;Øo"Øt­¯Zv ”å®Ãœ'?l¿pÞ1MJÛT]Œ5µ) ¹ØlY †DŽš†/h$EÖézˆ@ÿÖèÜ{‹=ûÃ8gšÐ0we’(%¦´“³†¡hû€ 0x1/´×óq‚8i_m(.xâ"r†Ä•j}:‘pÃÓ8{¼½uûÜ|~üz9ØÌêb(¿à ȘbôÀv$mW¤Mû ¢DÀÔû»ûþ#’W*ßBÿÚõK§’oÅÚVõʇæ~ÇKÓRÊIÞ=¢iƒ €ÙÄ.7ߟþõõÛeƒÜÕЎׅ§ÄGûÕÄóßè5š¶/÷ÛS?ÑÀ†æw•HVŃŠÿ÷Ï7‡Ÿ© ÊfJÑx~f˜ A)s8ÂÄ\uÁ òV€µcÝÿ*
-zendstream
+xÚ­YYsÜ6~ׯ˜òKFµAëʃlËŽœHVbeË•ãšáh¸æ1r4+o忧n€ä„ñQ»¥‡îƇ¾
+¶öú„3•&zv€ÎDšÊYuiÅt¤”§”'oO~³néFZ%L'ÒL€‰)tÊb%•ÛÊ*_gû²[´Í~·ÌÙjµËÛvñ#
+rˆ‚Ð’‰€A–e¶oó°3Ñü°)–;TóeV#í.Gp­Ò5HióŽ›—7Îeõ*bbãNE2_³µÒ~ƒ¥  -‚m !Xªµt&×6_vÅC^>ž
+!æî€a ‘°ThÄá|Ýå;%Î&·ùz‘`&1ÞÚ|÷
+süÜ6m[Ü•´ˆ\çŸ8KmXœFià”'–*™ÏÙ„Í hbØ6»nBŠ4°u!‰ÉúÝ„9œqc¼
+tº#i©~¼4“ñ0I·S‡¼J$Dk,ÆÐWûÖºA¬æUÖ¹S†!žnщXR³Æß œ|;ú,(ê‘5ÿ•sYæ`ž‚xë©!7ª÷ÕóK+ §° œ/¥x~
+i ,›º†0#¾†\®C°¹=
+‚zi¡yú9HÇp&i<JC6ƒ§ ðÛî·Û²pYGº˜ó ãÌáH‡¢,qtGL”¯¬¼ºíòŒ>âÒ‡°ÕâCÆö`ìž¹š_dîØÆÚðÈ㔉ˆæK Pfïs!EÏ›mw*æESg%,îN°ÐzÞ)0c& ÔJW£ì>)Ô†TH›Ý”HÁbüû³êW,ÑÒ׋† Ž«
+„%`±€’ù’c©˜<ìÈ…¦¬I¸§…IÌ (hd†ËîvÐ<ŸH2GGÙM
+l‡Š^µ¯×9‡^¬‡/˜¼¶)Ã^ÕRƒ)Ãë¨Xp“ˆíýÈÝìÒ[—ã@YÌùü¿/{„K¸]S§($ð—Í2+í5íéT
+õKðÂ
+o:¼¿Z«ˆkà”–ü+×\HÃ8ü øÈ…Il( (°¼ÄÂì<j¿‚i×åŒäž¾å‚ãxŽÒÝu%V'÷8ã.ZbdÐû­÷bI.D‚¤Ç ßHZN˜¡× XB5hw$d•Û~¾Æ‹ Ä&”L:šm÷WîÍÑõ³VÂý
+-Ö “Ðû2PA3Æ¿3&Örš¬Ãˆ^z6•RÏfYp«füTô¢^K ´^;vÔCMD<=›ŸíÂm¸ö‡
endobj
2116 0 obj <<
/Type /Page
/Contents 2117 0 R
/Resources 2115 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2102 0 R
+/Parent 2103 0 R
>> endobj
2118 0 obj <<
/D [2116 0 R /XYZ 85.0394 794.5015 null]
>> endobj
2119 0 obj <<
-/D [2116 0 R /XYZ 85.0394 400.4859 null]
+/D [2116 0 R /XYZ 85.0394 513.4321 null]
>> endobj
-2120 0 obj <<
-/D [2116 0 R /XYZ 85.0394 274.6805 null]
+2115 0 obj <<
+/Font << /F37 803 0 R /F53 1032 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
+2122 0 obj <<
+/Length 2274
+/Filter /FlateDecode
+>>
+stream
+xÚ¥YKoã8¾çWs²1‡o‘{ó$™Þ ¦“ž$=X »Š­$BË’×’“ÍbüVñ!Ë6§1‘T©X¬ÇWU4Qøc#¥‰¶ÜŽ2+‰¢LæË:z€wNX ™F¢éê×Û“_~ÙÈ«¹ÝÞxBa£ÛÅ—ñ¯„ 2t|}yv:=½ºüíÃùådʬÌäxöéÓùåÙÅ¿&S®(%¥ã³Ëϳ?üÚ§‰åãÙ‡ó›É·ÛßOÎo{±†¢3*P¦Ÿ|ùFG 8Áï'”kÔè&”0kùhy"• J
+Wª“›“?{†ƒ·îÓ¤*%\hžÐ)](K´€W¨‹‹{<P²¥!Xw¤X׋9[°ñ´Å'wEÛµÅú©X‡o‡»d†)·eë¿Ü´Å"|ûXÔ‰•$™j¸å!kÎI–e‘蹬*Ï}ÞÔu1ïÂ_ ºqSûgÕÌóê±iéªYwþ…JDIËú¡Õ¯}/^ü
+8£ßfDzŠhɆÎD{‚µÊˆÊ ”_)åUñód*AÙe=¯6 gÜÎYF˜ Æ /«¿•½ð„ÑXw|qWøçóºì:8¨gÛ Ùàí€æäà`s«w²6›nµé
+Ë …0×ÌŠxN1áê”H.¢Ö@Š#K„Ê¢‰A©Ýº©Ú”bÁ@ð@‡ê
+”°õîv̵߬$€71Öê|Y,^³›æ„kI½º¢·Wmˆ‚ÕºD„¨|Hdì£æ.o‹©–?6š(c² ÚfÞ,ŠÄ9¤%†qóVÈ0«‰D€Ý‘»˜?‚Ô’ÄOßëæ¹öãU•ã‘ÿÓù)ªÙ rÿ@ñ‹î'?ùŸì ÇF½“¹ÀŠ˜Ìz—»œ}<÷ç¾9¿ž@Öú nŽÙìâÃçëjóöâê2Å\žëïžigg©>qu¹AÄÄÑ]x ž€ñù°ñXø·.~à™ÏçŪó”>{àj@鲩Û@V/<MüÎ3›7uùß E qŒ+íª˜—¸yܵt0å€ÉiËçxü02šX¡í{À(Yv
+ˆÉ„ÌŽÈTRE2“د¬ýÓçM,..ÏüÈúÇl±,ë²í °1p麸/¼Ýëyøìc^oòj Nn°(º¼¬ZòŽÐ¸9‘1ûãæê¸ó£|¥ŠøÇ~éy÷ßÅ Åuæ×ÝÂu›a2ãÿž&À´AÌÕ½;$´2”"@);Ú™}¾ýçÕõqµ\
+¬hy –Áõ ÀfP·GÀëyÎ<QOº¯ €å}Yý
+`a³ò yBU™!–26ô¤´Ú=ãûŽì½#!ÿ§¦\ñë¢K¾D|E 0¡²lGŽ 
+jJÍÙÑÛeÉzà{%¯ÀY©±Ã
+gNìV}M8&„õºÛ¬fî®\ øs­ÑJXùÖìiùÕÄfu/dVTŽ±i¥¼vÎJ•sV·zŸoªÎOæÍréA æ¯ê¢òoúUˆ± ƒù ÌbÍDà #¬ªæ9åx’öø=¿¢6šË¥ Ù¦Æ-‹ Èf‚gj7ƒ¾r ˆ¿H)YN¹ýõ¢Ù¿Ðp¿øaø!Þ;ºQî.ï7k×nr
+•Á„>L$ᇧCÙÿ Sñendstream
+endobj
2121 0 obj <<
-/D [2116 0 R /XYZ 85.0394 214.6285 null]
+/Type /Page
+/Contents 2122 0 R
+/Resources 2120 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2103 0 R
>> endobj
-2115 0 obj <<
-/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F55 1035 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >>
+2123 0 obj <<
+/D [2121 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+2124 0 obj <<
+/D [2121 0 R /XYZ 56.6929 613.6539 null]
+>> endobj
+2125 0 obj <<
+/D [2121 0 R /XYZ 56.6929 528.5855 null]
+>> endobj
+2126 0 obj <<
+/D [2121 0 R /XYZ 56.6929 467.4275 null]
+>> endobj
+702 0 obj <<
+/D [2121 0 R /XYZ 56.6929 429.7784 null]
+>> endobj
+2127 0 obj <<
+/D [2121 0 R /XYZ 56.6929 393.7775 null]
+>> endobj
+2128 0 obj <<
+/D [2121 0 R /XYZ 56.6929 362.3409 null]
+>> endobj
+2129 0 obj <<
+/D [2121 0 R /XYZ 56.6929 298.261 null]
+>> endobj
+2130 0 obj <<
+/D [2121 0 R /XYZ 56.6929 228.1126 null]
+>> endobj
+2131 0 obj <<
+/D [2121 0 R /XYZ 56.6929 131.089 null]
+>> endobj
+2120 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F41 940 0 R /F39 900 0 R /F53 1032 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2134 0 obj <<
+/Length 2734
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Z]oÛ6¾Ï¯ð¥Ì,¿Eâ½J×´èÐfy› °íB±äD¨,y–Ü,ûõ;‡¤dI¡ìCŠ¦ŽÈÃsžóÉ°…la¡ÂÊEb%Q”©Åz{Aðîà 4«Žh5¤z{ñæ½H–XÍõâ~3XËj [Üg¿-¯no¯oÞ}üõrÅ]¾%—+EéòóÕÍ/WŸüÜí¥åË«×w—+fe"ˆ ¤ÓtùåæÝ«¾yÿáúæòûŸ.®ï{¶†¬3*§?/~ûƒ.28ÁO”kÔâ~P¬å‹í…T‚()D7S^Ü]ü¿_pðÖ}…†(Óˆ,¸È‚QK½H”%ZÀ+”Å—CUÕ#ÈÙ€\2B·°Òí«l½Z×Õæ1¯PFÉr•††{$‚$"Ñᣴ,ëçÆ“¿ýxóGziýDZe‘]&\+5Ø5²  fjQ[ûr¿þ¡É³°EØ;Û_2³¬w«"ðî~ç»2]çÛ¼jÿá¦ÞyM–w_¬8—
+tGú;¥¼ÌIC’ ã0
+ƒàƃÖpq|¢êð‰Å' ô’-³@î6ÜÖm^¾\2ÆBšåK}ðÍS}({bøºŠÉ‚Q™ŠÊ"¢bàßRˆxõ¡ ¼>å‘å•"ÝÒQ¡‚”V ëW.®‡F⑇»ð&‚S89%:™Š3WØÎOõ6)_Û¤ü÷èOƒñek@$yåõ)xJˆ-À7aÊŠxÀ
+D«!•wÒ,°z*'òÏ(ØïHäÆö
+ÿš¿4Åßù”5±!I
+Ž#7ª7“Wé†U[¬ƒÀ98ƒaâ¡hŒºF/?š6Læݳ}Îó@ɪl0PŒã@¸%þCÓ#0&ˆab±,ߤ‡²õê.‚Ú7óÚæšXÎÍm¨Nh»£rÚ^Ç´ æ-˜:j{S”m'„1yšµŽ(ÂÚXלPÄ׈·_BlF«¸ÇÐNïfãNƒ‚'¶jâ4†±®Ahm^ü4¼LË6ßW!¤ÐeY¯Óã—è°#öoÅ ‚X{Í‘Lˆá´sc³ªWgi9—™vªRÍ«¾§rbzšn o¥”g¶ìˆ"[Og-‘\M¶¼Ý!¢.‚£ÔŸê}0„æ°Ý¦û €z3É@¼Êº«€ŒÔ¹ÊÇCŸY9}ÆÃ7ç<ùÎ…‡àgUþ[hÊϨf@uB5•SÍ×ïñÁZf}ðIÞŽ>ø5sQ<ânäƒ1— :ÒÞ©âÀ±æF^Ÿ±àhê–»0/!>lß?a­óÉ8êRïÔ?¾¥e‘ùaVoÓ¢:r@N¸àûWS_üÚ áìÊÈa™°:eÑú,l˜!ŒCéx6ª°é¨lvga³Ck›bl<ßI¾:¢_#Äp2ÐÆÆQÛ4à`]ƒÍ»@j•+Aª¼ôo§nôü”‡,?b×R8®Å0ÛŠhFHbE_'•PËäU`ÅeÝžØ|œ ²³ñ•Ü6Vw ¨ ©”gJGJd¿) :‘ÆáΡRRˆycãÙÌ
+‚„5æ4w=U„½¦ÄCÙ˜¿1¦”D ”Z6õÁémûi— ÂÓsëi²´Mý¬×> B èJ\$ñÅeÁKÕûâoç¤@‰š W…â»@¤ 8u{ÝZ¢„ì=Ž/]›@ÝÖ—zYí|§fP~·~jçÑö­Èr?+YX•°]ýñ&Ë¿½ çŠ1ƒ.»Ïxö~U,;Áe‚ßõûÃÅ:wh8´ã¯‡! %Š/K‡§ß¹Ê›ÆŸšÑBM*Õ¦÷ìµ×Á]ÕîÐ’È) ö¡8Á øŒ×cB&<šÙÀô:…è.gŸB¡å*o¤(÷þ雼®Z1¡¢—GácPµài'æ쀆BtY¦¦>zÁïÐ8‚™¢\¤™Ÿö²íÒ§§ âK µtHVÓÒÓ€>yDŽ\¨/‡‰<j æx*¦û>E•aPî zl”LtïœC¿Æ¨¦˜ >4Ð=„‹gŸuhÂbÏD)l‡Tó­§r­9[ê¤Y¶pŽ•:'YëK׬EKo㔊wúçlùñÖO k.6âTTdï¨dɹ¨(3FO£"®î{Q° q¶ÐîÇ0^ºoæã%dE„[ñïâ¥w¥P2©¿3y— e]ïÒõ×P*Œ$è
+î„
+,šp˜úGÓ_ÓM]:#BŒp=Ÿdä×nסXqìCÖ²«!-Þž3ê:\ßÁ"e_—MÌkj.§÷WÓ;eËô hˆùKôñŽ«iÁCynƒÄÂa¼2Ñ4ðWQuA”3Lí&¹8ͶüŽˆRI¿ë‚ ¬\œß}Ï#ÿj%P_@iÌŽíìîúÚïsõéîçóƆ«ÿN5ðë8ì ƒ/Ôà…;ì€Ú­H×̨SÇ›z˜Ê¶P¿6-ØR\É—|«jLó³7¿Ø`I©çãn—í*‚I‰n´Ýþƒ•ãæ@¶+Œ™é *ÑYÇ2ÕÚ”õþO[^óþÒ²ÍXendstream
+endobj
+2133 0 obj <<
+/Type /Page
+/Contents 2134 0 R
+/Resources 2132 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2103 0 R
+>> endobj
+2135 0 obj <<
+/D [2133 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+2136 0 obj <<
+/D [2133 0 R /XYZ 85.0394 229.9393 null]
+>> endobj
+2137 0 obj <<
+/D [2133 0 R /XYZ 85.0394 85.432 null]
+>> endobj
+2132 0 obj <<
+/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F55 1040 0 R /F48 955 0 R /F39 900 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2140 0 obj <<
+/Length 317
+/Filter /FlateDecode
+>>
+stream
+xÚ¥’AOÂ@…ïû+öØ:Îì춻Ç!ZJbB8  jŒÿÞ-X¨OfO3ófòÞ—%‰þ‘41ÄN9™8 ÉȧR |ñ³ MÔˆ¢¶ªSˆ›>'Ò‹U,‹çÖ- h-Ébµ:@ ¡?Á4ïu£î8ï²<ŒÈéDéd’å½ác)ƒ^안Á}šÏÓ»co:¤ƒl.‹‘ÈŠ“­¶uB®=½‹ÅåÊ' vÖÈO_ sJ–B£™›Î›˜‰‡ÓÁÖô°z!(ŽÕŠ$8cÔ/ÆAÌŠ0Òyq;žÖA¼œ[èPFJƒÓ¤ºá¦Zï6ëêH`öµ¯ÖåþXt·›ývW½~”ñ`uˆ+îñdð߬ÎB'ÀÖª3†v.•ðËqcªGl/¬7T/½óbendstream
+endobj
+2139 0 obj <<
+/Type /Page
+/Contents 2140 0 R
+/Resources 2138 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2103 0 R
+>> endobj
+2141 0 obj <<
+/D [2139 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+2142 0 obj <<
+/D [2139 0 R /XYZ 56.6929 752.4085 null]
+>> endobj
+2138 0 obj <<
+/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1592 0 obj
-[702 0 R /Fit]
+1610 0 obj
+[706 0 R /Fit]
endobj
-1447 0 obj
-[702 0 R /Fit]
+1463 0 obj
+[706 0 R /Fit]
endobj
-1198 0 obj
-[702 0 R /Fit]
+1215 0 obj
+[706 0 R /Fit]
endobj
-2122 0 obj <<
+2143 0 obj <<
/Type /Encoding
/Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
>> endobj
-1627 0 obj <<
+1644 0 obj <<
/Length1 1628
/Length2 8040
/Length3 532
@@ -9515,7 +9622,7 @@ endobj
stream
xÚíte\Ôí¶6Ò ˆtÃÐÝÝÝÝ¡Ä0 00Ì ÝÝÝÝ’‚R"‚´t ÒÈ‹>ïÞûüž³?³?½¿w¾Ìÿ^×Z׺î7¶‡Œ5Ü
¬‡¹rðpr‹ t´P(ÐWç…C­fL9g0ЇÉ]Á¢
-Äü{fXE
+Äü{fXE
0Üú÷äè¹aÖÃöOÃoäæìüØã?ûÿxýœÿŒ=ì a.ÌÁAb¡ö™9Y® Ä£ò/z{xÂœ*Þè—ÖÁ»2#×Dj,ïêÃ8›ÇEµyÍî;Ýoª²n öA™ºÓÁß‹(üèX>ã.3v±ms™W`gÅúϨ¯"›
rn­êèš—ß¡RŽwð9£_²Ò¹Ð_8=óe4%v>oFÀk(Ù?`LÙ½¼`êú4ð±ûåÃ&9[~ƒ˜;26cLà«|r)Sƒj…×Íl(ßÛ
b¬Å7ÎßÊçÏVð™h9Žù,¢I‚°RÊ• e®äß·RÆ%=²ìÙ êt›œ(†Ì%³LÇî)®Ž>1Ù¥‘„µ…^Ñ2¼éˆO£Ý %õ‰>•pjÕr{2–ÂwÍ<–g¬™-j—!3cäáakIè,AŒ$ÁLˆÇÆ‹J¯³nöùU»Ïm›Þ‰D3
@@ -9538,35 +9645,35 @@ $OíœàÅ€DÈ
t‡Í=žÝbóÆÃwî6ß"£“˵?”JËOP2RÐ oQo+†â1)©w†¦ÜèådîI½ÈZ¿VÍ­(e÷åû È"QÔüFØs(úF$'‘qL ®/¶!õÔ ¤HvkÖ‰Œh¼È‰¬ê؉á¶o?Ùa:Šÿ±qêcŒ° gã!_QÇ~ÏWê¡1üaœ¯UÝGmã§Yñmn%ìRãr9÷¬ß0qˆ5†/‚E…(êÚ“†,W‚˜$Ù½ï¶åçLxËÎÔ|ú奕£w†Z|ÂV€ãž÷,éOd
ÞyŠGÝ ŽÎ¨Ý3lÍ4©¿Î\×T2Zª½Ag—.7Ù#ÏPæï™v¼eŦQLÞ»±Oþ¼Ô\’ ¬ÿĵJÅñ¾(š3Ç].Å*,MÎ>ÛBx(ÃSÃó|D³uû‚Þ¡ï†{:Ò‘Á¨2G9¡Cê{É•<|?ÒK áéá@F)Ø,êw÷ó?È ¸¢Ëa„Çh%Ù±o^Œñ{‹6™Ý @¥-«ä%Å~jÉwXjz1îi´·î¬%uÕ3^¿±g¸`d+ÎK[ŽDe—„]âò†YèÖýÇ?Ï>£³HjË,èkѸÍhÔ8Š” ™v_Å [ªJÖ®²9m=·âú?\‹k>¼à¬‡¤*³Ñ³ž,Y ê<‹ý¹uÓ Z/ZV$S·é#ƒmNOš¨5M@¿§rãÝ0Hõ7¬&7[àçŽAØñêOõƧÈêÚ5±pE6~d»Ž^.x¨T1¬µ¤$£Í7¿ÿ4òÆêüj§‹G1¬èípoóÌ3³QýÐZ:œNÍÆéç,0½‹Š‡Zg‹ðâ£à)‹Q©¯³‹X""œÛÆ0ÏÁ¾äBvFA‚)Y9(ÎYÖý…ì¬S…|¸Ôü¾“qbæÇN.LÔX§…_ï‚¿œ%%½¥åŒìé|°D>W²7}C–Í#—ZR¸­$º`bÛGο…a¿9gÝS%\”Á/œîñhC|?s§ Ø…šg¯ÎÙÈ)ª¬m}ÐvÖËk†Ÿ.bÉ&O
üõí+uqfº`Îa‡„°£â,I§ã¯½/‘˜÷ÇÝ›Á¤'P6ߢH‚Ú?÷›½šÙ¹˜Žà9¦ŠmHr7:pMRYŸ#£ 'æW¥¿ðKCß|-¡mWÝ躖nᲶË0–«ÞÐ3äÛÙ=j’¸Ë-,n–³e±€¢üb½iÙ;‘˜Hâ°l<)žL.ßÐYÖÿ°Ú·)wL=(‚Œ£± L|)=å'ÀÆ-Å@²öò¾µ<ÃNrä³6îµEôʃ3±d¶kÓ»¬ÿ‹%ôµøü·(kD~ô(¬_yñ‡Í; ¯åä²fùOî{&*‰äyÒ¯9ÛB±T¨d>è.<Sâ¢éX3p7«Á~ª"럽Ÿ“lË´ÍÔDQÿfŒ°Ì
-*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€Ž¶Xo³êÙ}
+*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€Ž¶Xo³êÙ}
endobj
-1628 0 obj <<
+1645 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 67
/LastChar 85
-/Widths 2123 0 R
-/BaseFont /ZJTCSQ+URWPalladioL-Bold-Slant_167
-/FontDescriptor 1626 0 R
+/Widths 2144 0 R
+/BaseFont /NYULSI+URWPalladioL-Bold-Slant_167
+/FontDescriptor 1643 0 R
>> endobj
-1626 0 obj <<
+1643 0 obj <<
/Ascent 708
/CapHeight 672
/Descent -266
-/FontName /ZJTCSQ+URWPalladioL-Bold-Slant_167
+/FontName /NYULSI+URWPalladioL-Bold-Slant_167
/ItalicAngle -9
/StemV 123
/XHeight 471
/FontBBox [-152 -301 1000 935]
/Flags 4
/CharSet (/C/D/E/H/I/O/R/S/T/U)
-/FontFile 1627 0 R
+/FontFile 1644 0 R
>> endobj
-2123 0 obj
+2144 0 obj
[722 833 611 0 0 833 389 0 0 0 0 0 833 0 0 722 611 667 778 ]
endobj
-1608 0 obj <<
+1626 0 obj <<
/Length1 1630
/Length2 6133
/Length3 532
@@ -9578,8 +9685,7 @@ xÚíVuTÔí¶VA!¤†n†n”.IéΆ˜f(‘N)én$†FJ Á!¤[:%•$.úÝï|g}÷üuÏùë®;kͬ߻Ÿ½Ÿýìø½
Òy¦§aáèha …«pJí•Ž H
±@Bá0Y $D¤±ÉB¬@¼¼ 
µµC‚XnxXÙÙ9þ²ürYzý‰ÜD" ¶0Ó̓;Äîì!o(þ×ZiÙ@! u %5‹‚šHƒ¸Þ¡áf鵩@­ 0„dw9þq
-³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸
-ìÿúvýí«q³Hm/gè¿é©Â­ÿqøÅ$- ÷ysòqƒ8ùnäðp ñDø|þEÖßD<U-®PO777èæ÷Ïï_'“¿ÑÈÁ¬àÖ¿öF i³¾Yµ~ÁVn®®7þýößþçù÷ÒC ž+ÀôÜJ,Ø>5# YEžÓÓ/kô¡ƒ£'ŸFûu¾¼Ý/5|Q¤Ìü¢2„«vPôªÉk|ÛùrU™m­·ƒÌ‘¹=²—GåCÏú>ŸhžéûZ Ø´?í«^”÷þ˜Ê¦¡ ·îÚR¿æ3Ó¢‹{ÀÁw|®Øû§¬þôîùþ¤ 'ξV)o_=h!¬½E\U°ý•)aóô„¹«ïcOwûáÝ÷«”ìÙ¯pÅÜ1ñ™"ý]²)Ÿê”Ê•¿U»—w„ÄêÄ‚‡_)x¾¼–‹ À:7ÒD/–²‹óP'òÆ€,? N¸vðIn+\£š}§Z(Åç^XrˆL©GXrŒMß—ìdc§ õÕwÑÏíK
+³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸
ïeë[ă»4fÖ)Æ»'c£»¶*2‡Ìu•ÙÖ£™øM×E;
at
½’•sJÜkŒ "êC 3ó®cUÉÙ4eHÎH~0+¾÷ì
@@ -9601,81 +9707,127 @@ V1-S¸`_3ÄÝËú%6BëbØ r¨Ãt©a*Óغ0ɼ•uï´ñï¨Î)y©@[gbL¦Ç)Ä?ÊDâÐ÷*éԒꟲGê«à
ÐíC¡Ówï»ëÉ“º¿Zèp½÷äOô>/¨lÝ4nlŽ°U-oMôÙ“ˆ o:œ©Í|y„7MT{õ ¯=i3RÇVHA9jQ¾rÁ3ãaÂ3œ´X_¿ÆdhÚ—E/Oö\ìKɬÝOõš_·— &†÷ê$ÀuæbsAƒytN.`.šâb™Ê¥܆€ð6é瘯l¾}êÈg|ëwRŠžhXŠs×L84ØGê} 1Y³mgzÑìÅÓŒ$»9ñNh‹Í”ŸâÕ÷ºXsm{Ôg"'H±¨ª®RU\O¹<Š>ÊlSñ"
‰ôt.CB±|…—(z?п)|Æö…›‡8csa4«ªy=~U»+jð*Ì8Ó“«&ÐÐåÇw?´,IpöÛ7oå¡#½Ëõqw¾}eüJü¢šïUølœ]Rçm‘LغÂ=Îk¡·ÐóKJ;œuY8:B.²åžðŒC\„0&õê®X¨ÕåsÊ;2•©`‡¬#¿Ê"ÿÿátökä
¹Ø+`‹ï—Rp 36‚FŊݹÎ%:b‰»•¯·0Î&SwjÒ V‹­C%#N^©Û™KuÓÏy,ÅEŸq&¨ãò8¿ªÊ{D LGÌ8½UTmÚ5leUÍ?6¹6ÞÒ6!-+ÁöŽ·¶¯T(wu9eQ–éáö:Jmš»4 û_}ö~N†ŒÁOkôÚ‹Ö»µ§½Mìð}íîɲư™qÀ“ë`Á+–»5ãéö×­d[%˦×÷[M–ŠÁÃ#ߦT\Ú*wqªÝ¯¢Øg”‰˜÷Õžà$²dß]Í|®yó9¾è?)ì#IiwñùŠ€%z :õÔÝ3°ˆKzW†Fc¾òm={‚ú³8uL‚ÂôwÌY«|í»U&›±”n{ÀeóbL=Xûy*áwSYø"FžN†j×'›<ºÚyÍ7Ì4`u¹§h‚Žï›Ô
-M0 V”µ@¦ØRšÁSÇ8${^™æÒu”œqÿ›ÀÿüŸ °r„X¸"áN®€ÿ'yžendstream
+M0 V”µ@¦ØRšÁSÇ8${^™æÒu”œqÿ›ÀÿüŸ °r„X¸"áN®€ÿÕyˆendstream
endobj
-1609 0 obj <<
+1627 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 66
/LastChar 78
-/Widths 2124 0 R
-/BaseFont /DGWQKG+URWPalladioL-BoldItal
-/FontDescriptor 1607 0 R
+/Widths 2145 0 R
+/BaseFont /WCEADK+URWPalladioL-BoldItal
+/FontDescriptor 1625 0 R
>> endobj
-1607 0 obj <<
+1625 0 obj <<
/Ascent 728
/CapHeight 669
/Descent -256
-/FontName /DGWQKG+URWPalladioL-BoldItal
+/FontName /WCEADK+URWPalladioL-BoldItal
/ItalicAngle -9.9
/StemV 114
/XHeight 469
/FontBBox [-170 -300 1073 935]
/Flags 4
/CharSet (/B/D/I/N)
-/FontFile 1608 0 R
+/FontFile 1626 0 R
>> endobj
-2124 0 obj
+2145 0 obj
[667 0 778 0 0 0 0 389 0 0 0 0 778 ]
endobj
-1383 0 obj <<
+1399 0 obj <<
/Length1 771
/Length2 1151
/Length3 532
-/Length 1713
+/Length 1712
/Filter /FlateDecode
>>
stream
-xÚíRkTSW‘ª¡¬òRIÕzX%2yj   `, ‰¹7ä–ä^z¹¤D|PIU–EltÉST”
-«Š@} Ô«0|‘VXŽƒT­Š€¯¹`]]¥?g~ÍšsþœýíïìýïlšG”Œ!‚°p(† “#ÁR©„Ãä™Í¦ÐhÁ8¬  Q°p¡Ó
-Àæ y+„<>…‚±tŽ¤ª àLŸ$ñH ãˆR©‚PÃZ²†R¡2L‰À„ D X7y#¬ƒ3`<†˜@ˆ’
-W(ä‘9
-Ã)“ÿêÃ, œ‘1‰¾¸€•:9{¤{“Ø_Ÿ„éŒ\ÀàòÈV앾€Ïcçü‰¨Ôá8ŒSãCô.V!¤§0¬‡•ëMLé·õÓ}§·×䊫:ÙÓ3šlm?¿í”Ù9Üëçroü)þè7çmΟ"ÇJF"¿aA*^õ´(Ûb”±¶õ8[Ýèûe³*‡“g\.kký@{pÇ=ëâÁôFï‡?{>»›yÞ¾nõ}¿’:R8³æÖÍWOrÓ6uôY¾†<‡J(IegVï…åÿ¼[tuâAV…Y«/ÏOÜÿÌõµ•Úz§;í¶£Y`*“ÚÝ0û¿œÃ¦ëUýδÅÖ¸RA„L8{¡Ïuy¹Ø|èïaŽ hnŠ”þ:{ ‹.ð0¿ß-ÉÏ) •ÄŒ.8V᢬Y ñ«¦ÚÂõ­ë[´èÅ‚Áúµù.iõ\ÿbNzã^Úº”ñW´ß–ìœù4éÅ‹ÞçoLÔ–‡J£‡û‰±Þ¾3½¼‡éílªýµ/,ñ
-õW÷Q`x¯Ã*S›öïýÙÍcR'¸‘çvóèžV.å¾p\»¯üoÒõÞß6Yö$Šõ6‚øKèÇý•þu©Åt€›œÐ›r6ú–÷åÚ† U!®µ3“,M¡¡UKšfc=Aó=\úÍu%Fõ.ëÅn}Ñõ¹lÞÄø¢ãBŸƒÝ/ý†~*‰±4ŽñY”k?´eAÚ.æƒèåFß_íÎGÖ¦:}kOZ~œ·lÍX»/íxMdÍv­á±`ÎÞc‚úG»òìsOEM?¨Êð"Pç¹éÙrzmÕÚÇ„SQÔ‹Ê&x¶¥ÅÑÁãÆLîÙO6ðüS_wYw¨Ú¸{ÓÃÇ·V.Ú±"tèïPÓÅŸ—ä¾Ù:Ú¦sp7µ'XÑ{ÇÌw~ìC[ÎrÖyúÇ}³4 …Zwác«Ö2¸Îªh#[ï]hÛ?Aƒš+µµn4Èmðr"ÕËên‘º~/yêŽZšÓMÛC ÚáW'«Jä¬ÜÁžU§|<ˆÕc•BT¶TrZ³ÜfÆ™cOJÜŸá›^ ç7”ï‚oWD­­˜ð¿Û5¡Ës½2RØñË™R•ôM‚loÊ|U–Aß9/«©«tS¹>˜áµõÌ'Æ/¹_65n¶™‡¯‘DAßÙªÛ·_w½.wÔr¶Ä
-ôÜçGã:òíÞÏ)Œ R?CMKëÆôûëÂKûŽî¼”óa宗ܽT\òÚ6^^7Ôn[–x˜+tiT6Ö›ö\¬,vüX® ÆK£ó•m·“·D KëNìvØÁ9¤Î.îš[Ð<káÎÍ?»=^–)«øz}Ày~~¦ü\(¯/pÎ÷ž‹‹Ô”œsr¨H\}0õž¸'<ûyà@ïÙ‡Œ.y{Ö\XðbPÝ{Æ·¼X2|¥St«u­¶KÓT]Z°G:·ÆeÃ{aN‡Û¯¯9ùïn/nç}Ö6N]F¼|pj¹Û·†”"NH·éQXËê,=Ò‚…8®émti dæå‰JƒºnìQ'7t\/Ëû‘5P'ÚªöÏáÄä±Úfá‹v³ît5þóïRªùcÄ-I×z¾]»“ÿҚĢ'1ĪnÞ<ëƧYQ‡ó«¨µýìÿpQþ_ࢀR+pÓ*ð4Ê¿ŒŒ¶endstream
+xÚíRkTSW‘ª¡¬òRIÕzX%2yj   b,žò˜{CnIH@Ä•TeYÄF—<EE©°ªÔJ-±
+SÀiaËqªUð5¬««ôç̯YsΟ³¿ý½¿óMóˆ”1D¶ÅP‚Áar„ X*•pØ€<³Ù-‡å‚¡!rŽ@àVkÕ€»°ùBÞ
+!O¡`,C#i*xÓ'I| ÒÀ8¢£@*'T°†¬¡« S 0¡g‘Z ÖMÞÈëàLÏ‚!&…â ÀF8 A)¬IMT‰þ[Òf¼KeÁx&)
+xMɤR$„¡j=€`%…µ#»Á¤–ÿ†¬éÅCµjõZ¹f²ü”SÉË5ˆZÿ;Ódh R ‚qt:5~+N
+CˆV3=+!äjD!BÓÔ0`pV2Ù+ßâHf(¢ƒ¡H„P¨€R®Î„§p…¦+!ý›ÒÁŠEÉ‚ÄÞ¿íT2RŽ D´>ì?ØS1ç˜4 Gt ‘Íd³9$‘ÜïNÉÓš‰Q!hàò|€Çåz
+9DdÄ@PÖXG*f1QŒ ¯
+÷HçÖºlx/ÌépÇá5'ÿÝ%¼ÏÚǩˈ—¯O-wûVŸZÌ é1>
+k]“ ¡GZ±ǵ}M.íÌü|QYP÷]#ª”ÆÎëåù¿ 1²FêD{õþ9œ˜|V@û,|±ÀnÖý®&|þ]j p삸5ùZï—£Q;ù/-É,zr1CN¬êáͳl|šy¸ šZ7Àþåÿþ'
+(Ô°'0O§üQsŒendstream
endobj
-1384 0 obj <<
+1400 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2125 0 R
+/Encoding 2146 0 R
/FirstChar 60
/LastChar 62
-/Widths 2126 0 R
-/BaseFont /WVJXVA+CMMI10
-/FontDescriptor 1382 0 R
+/Widths 2147 0 R
+/BaseFont /QAQSBE+CMMI10
+/FontDescriptor 1398 0 R
>> endobj
-1382 0 obj <<
+1398 0 obj <<
/Ascent 694
/CapHeight 683
/Descent -194
-/FontName /WVJXVA+CMMI10
+/FontName /QAQSBE+CMMI10
/ItalicAngle -14.04
/StemV 72
/XHeight 431
/FontBBox [-32 -250 1048 750]
/Flags 4
/CharSet (/less/greater)
-/FontFile 1383 0 R
+/FontFile 1399 0 R
>> endobj
-2126 0 obj
+2147 0 obj
[778 0 778 ]
endobj
-2125 0 obj <<
+2146 0 obj <<
/Type /Encoding
/Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef]
>> endobj
-1062 0 obj <<
+1139 0 obj <<
+/Length1 1199
+/Length2 2269
+/Length3 544
+/Length 3057
+/Filter /FlateDecode
+>>
+stream
+xÚíWi<Tm2e$[–qÈ2Â,vSö½'ŒÆNeÌœ‡1Ã,ö¥ˆâÉV–É’G¶J»-Ñb¢ˆJ‹’(EY¢§Þ£žê}zûö~{ï9Î}_ÿëú_×õ¿¯ûÃQU"µ-(LЖÉàhãÐX<àûsÙDc›övÆuàè
+Á%‚`HFö3É›÷Öím\8m!®ýüŽn›ÛÜg®¢2Î7Šæou’ :)§W<k”ShMè0­õY鸒/9SÎ&Í0<Èز ½Z\"Iœß>Eöúì'üÚ·kPÝÓØ6Ù¬2yE/­"oØ¿QªšóR5µº-NLfJÆoXð~1êŒS¨*­tï×0–ZL˜r¶§Ç¹à÷xÍÖØÀ„}yB[¯\¸ûA}«·Ð…Wó5Mâ~}ý×,…õãï%Û!9uoýå¼Nâ›o_ÑY ¨l .žæ…”êoÕÝ2¬ÕuÖ•ö&¡ÙRóÈúÓܯd=÷T)·–ÅV–MµT<,¾}^C÷\MáþR˾añÁ¦Iø@>P]á)ãЖ¼`k­¿ÅbÑ2­CÌ;uÂ÷„ÌQ…÷yEˆPó@¥ÂNÛöŒvö%÷8»‹DÊÒ”ì~³kZ=O&=78®U¼âE\?¡ àêsÓq¦¸>äjMr¨Üº¤òŽ±Ïƒê®$;GšAöÐÙ}ˆaŠrGݹ#-íùQ32M{? Iô§Lzak„«|…ÜæÝ[“^ß÷Ù‚ü$—Éç±éÕZƒƒ9ñ¦RÃkµvõWË&еb˜
+q™#[xŠ/íZEY+ igûÙ{‰±¾$kí¨QW3Óëm=ÂÛ.·Žh÷†;fbUŠMG„=Ï ¢ò‚äžêZ?=c»–Á ss˜¡Ù: :©ƒã¶¡Ûé¹Ò?&¸¿9ÄìæšÅ¹Ö‰ +Þ½¡ÚwØÁês„É+…ëO™<Ú50
+æ劚ùð™¤<:›ùgS5r£ü yû·ç%ŸÖ£[˜fBt·åÛ“ cš›ùÒ(aÿ;ä4þñüA'¾y|óV^”Ç¡SU“앨#Wm¼zã¥k† ×ð·ü–›xÞ4Á œDfä¹´lï¬ë}3¨éÞVé|«.1ÓmÊþ¨¼~ÊÔ<±óå=’ ²Ê[ýöâ›ò`4ñPëPñŠfV¢ñíëâOlž¦$]-:Ìõ¿X‚˜¥ú7çÖ:4Kd:fÐHªºRñ÷ÏšvÏÖ›RlcÊ×ytOóRÑ‹‹¥%LzÞ `#Š‚m*—ÌUÕ öÞ÷O4«‘í¶ìÜôTE!í¤ÍaH1Üzuævµê­åø%%¢ºüÈ눆U¨<yÞž žÝý<"ßØ“æãj¤c
+ ¡ýR.Ór®ŸêVhË<’%ƒÙl-ûÈL'³³ìXè¤ÒëtµÇgˆÇ?cœ½æ}EôË„ˆùnGÛ¯
+í7ïÝõˆÿ®+$‹£NŸÙu¥=[Ï8 8j>ão¯Ëû¸½(Q§[¨~"%Ù—v/º p}'²Üô^F„ñ»\?~·‘·z¡<-E)i—ŠYþ³À®]£—vWO ¢m¢v!œ ÆÈUó‚g~Ê~|Éê:žôÚ –żè1œ5ºÝ 6¹ÞʱuÙiž#Z÷f”yÑœ’]^†«gIgRwU©6ßôaØ–Ÿ«œlL
+wò² 6óx†l‘}&ï¿GmÛ‹KW2.øf_.䙃’—»yù¹uï°³ÒLÉ=Ò}wG5’ûÃSâwg’±ïh/Ü“V¤¸ñ{]×Àé7(u?®Õˆé±BÅ…6–VÄöìqóÿà*’°€=É­ûðèn^/+3}ýELº]NªbM7¢º¸€4N[YÊɼ}íc­[f¼ªTòÓK%¬ï+;ÿ^òsžÎ›‹ ù.æIIˆUÛÚY±/¦÷
+ûôòH/âÂ+oéLˆËÇO¤Š›9麗òo*d· nFŠ¶–Èá)“É.²©¿¿}]dÅ/Ò"Ý•Øk×xyœh¿naM÷½+ƒŽ÷ÇÏØ
+OT¹‘ÞúMv±gûS‹J¤ø¬³4ŒX1µ¹Ù1ŽùÎg’új½W¸TZnzW¯]hnÆË~«WÂJ‘ê.68<¢R@ ¹žQ *^?W+kâª~'b M,k"ÃÊ1KšÙ?Lq)ã÷I™¾ßpl‘_Àõæê´êC´€Ï ÞsŠSt±ÔœwÕÆ4Í¿ØOžä¶"òL&l“†U+<|`x¡×‡Ö§v¡DØt-²’»fcf…ày­¥t¾âNiìù ÿOð?A@¦ƒ$‡Lb!£Y þ¡\þ7Cþ ‹Ú@Èendstream
+endobj
+1140 0 obj <<
+/Type /Font
+/Subtype /Type1
+/Encoding 2143 0 R
+/FirstChar 97
+/LastChar 110
+/Widths 2148 0 R
+/BaseFont /MQZMVP+NimbusSanL-ReguItal
+/FontDescriptor 1138 0 R
+>> endobj
+1138 0 obj <<
+/Ascent 712
+/CapHeight 712
+/Descent -213
+/FontName /MQZMVP+NimbusSanL-ReguItal
+/ItalicAngle -12
+/StemV 88
+/XHeight 523
+/FontBBox [-178 -284 1108 953]
+/Flags 4
+/CharSet (/a/c/n)
+/FontFile 1139 0 R
+>> endobj
+2148 0 obj
+[556 0 500 0 0 0 0 0 0 0 0 0 0 556 ]
+endobj
+1067 0 obj <<
/Length1 1608
/Length2 7939
/Length3 532
@@ -9686,7 +9838,7 @@ stream
xÚívgPTݶ-HPPÉ™&çÐÉ™–œƒº–††î&K(HÎQÉH ’sÎ 9#$ˆ€øÐïžsn}ïüº÷üzõvÕ®ÚkιÆsŽ¹VmVF-]^Yª„p@óùž4`ö–Î(]°ƒ¯ÜEXYå‘P0†pP
G8ÚCзÿãºP(
²BÂÑ€Û¬Z
-JñDÛ‚Ñ¿s£`·n
+JñDÛ‚Ñ¿s£`·n
uƒZ|™BX‰¼LLIB—Qdt (<okbu:æ}Ò{ŸíûÑ쓼,Vôâº4¯rèéMûäŽãÏõg\=-äpöæxèA­3gkö£¶Qî ~ó<¤]ÃpÏà µ%l“Ç+Ú:æ¹×w醄x‡ß9}™]²}IYΉ¼­*"ÉVb—åìì²Å|ý~ÎÞÑÛÝÕÙ|ŒÓºNÉÏ*î‚MÈæë”N#m¢_äa™ ŒéøÛÔªÏ!´0sL^µ$0ÙÂÿTh5ë¹[­Fúù{ª\™ÏíßÉúÐâ¦Ùé%üföC ~–fí*!Î:‰EvýÔzð­´÷Û6гßÕ•Ü 곺£Âgü«e‰;}ƒv©b]ùßÖÒï6”‡ùÚ}sø.Gj¢T«$Kñ£•I âQ–®‹Â~ÒìEÛ1w.ì*Çbr|¬½}$oÖ‡·Gs]> Ã?V1ñŸx£+w¿³^õ9’e‡Ð†ŠÚ¥ÍäÊu””7œœ¸äN­Ñ÷ˆ¨/ùŠõ.‹ú…'Ð)á0äPùÝÚ…ke
¸éÛR§ö
]8sô&sß±­|*åŸî#>cÕ¯‡‹úœ‚ œEëÑymeê÷AÆ€>8m„ 1œ4¬jõõr¦XÜâd8„²³¤¿V>M¼çÀ7ÁÜ&N\€*ÄJÒÜOµøï8•^Ýçôáö¼J%qõ‡ ‘®.µ&у;ìXBÒ0ÊÚcVKŸ0-SÛ·ߌG?óí·Eƒòñ(€(§¸Ëš’=´øô•ú+y\J6.æꔋ‚œÞ»ó^eúÞ‚·V„(õb*$Ã=AÁžéÌmEéïa9žoñ€Rý3™ÙÑS×!÷8ÎãÒ9‹ÅÕçÜrƒÅ£‘C™Äù\‹-ÕÕ²k±ò¡øáÃÍ8
@@ -9718,104 +9870,103 @@ QH;ǘ¢&šùŸe“ô¿žUÙ|µ°Sc0R2YE]¨
‡á{__bçâ.°ßþ
LóÃI8GU–¿Bã¡\‚–Ÿˆ{éõ´Sû›7M‹Š–…;ûÛ䃵h¹0GQœ&÷ <‹"œ_ý¼ÈAze‰ÀN2ÿPÜJ"u]©¶ÕLòs.}æQùü‰iõHö5¨ñ‹‚‘öqLðëƒýUj[’ =Á®…1Ñè²YÆHOŠåoq ’„!¿‡RÒ¯¸ð%ê«~u¯ ³¿0Š×·6î;>nE=m½aÔ\{\ÄcïQq”&T/bµ^þü‹}m“¹ò A’ü陈×O/ÍI>c×b%ÒÌ&ìýºªú· ¶mJ;û7žb{ª6eC‰Æô_è<@ÀbW’+Q'‘šäçÚU›‚ݧ/ˆ+ƒË°a
<¤þdÑ _IÒõ.˜ê¢Ï\9¾§é-xÚÖ-9?›ìÐv_ wóý}¾éH`…Ñ'>Êß4¬>äŽT‹¬ÌÛúGäµGÔà…$Í ï‚7LI›u`žUJ2ì„΃79ç¯~f´lá­ÊΚìïW 5?|¸':U—.ûrJo ÇÓlÔË5áAÜçxE ³º×ا‰3Ç•ÚTñ#åKþtâ•.iKW@ö/É›ÔÑ÷ ûj&Q ¦Œ²È˜¥t°Èð§Äh-ؤ1íý b?e¾™F Š– ÉXrÙ/&Šjz©¨rAÁM°re.2Òe%ÉÍ£™6"5[¹(H4 :\mdb“™[i:ýP½2“¿Ýä÷ö0JÑ»pÕh¯QšQ¨ý±Qó_»Ã7;mþã«÷Aú^ÁÐ; Ó èvñ¡Õñ¥ã«*’Hóß¹,QëtT½}…ÁbWý€g”ùxÔ$Ó¬GÞ×™®'}¡uÞói õ´’D§ùõ; ¼xðÞÔ¡Æ°~. °öâ%ÅÅ4O”˜»ª¡ Þ»Bï­\ÿÆÈæ 
-†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿ
+†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿ
endobj
-1063 0 obj <<
+1068 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 36
/LastChar 121
-/Widths 2127 0 R
-/BaseFont /TNXFDF+NimbusSanL-Bold
-/FontDescriptor 1061 0 R
+/Widths 2149 0 R
+/BaseFont /WAKSUB+NimbusSanL-Bold
+/FontDescriptor 1066 0 R
>> endobj
-1061 0 obj <<
+1066 0 obj <<
/Ascent 722
/CapHeight 722
/Descent -217
-/FontName /TNXFDF+NimbusSanL-Bold
+/FontName /WAKSUB+NimbusSanL-Bold
/ItalicAngle 0
/StemV 141
/XHeight 532
/FontBBox [-173 -307 1003 949]
/Flags 4
/CharSet (/dollar/hyphen/semicolon/C/D/E/F/G/I/L/N/O/R/T/U/Y/a/c/d/e/f/g/h/i/l/m/n/o/p/q/r/s/t/u/w/y)
-/FontFile 1062 0 R
+/FontFile 1067 0 R
>> endobj
-2127 0 obj
+2149 0 obj
[556 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 722 722 667 611 778 0 278 0 0 611 0 722 778 0 0 722 0 611 722 0 0 0 667 0 0 0 0 0 0 0 556 0 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 0 778 0 556 ]
endobj
-1059 0 obj <<
+1064 0 obj <<
/Length1 1166
-/Length2 8309
+/Length2 8686
/Length3 544
-/Length 9124
-/Filter /FlateDecode
->>
-stream
-xÚízeTÛÖ-–
-Ìj +àsÛ@C£†Ùþ~ÄA¦0°DÂöŒkX»
-r¶Cž! s{¦îâèhY¨ .Îæ (ÐòyeÿY(îàèá ¶²†é4Õ´é™þaçååšyü…
-²spü£Ò3…4r~^´Å¹*–¦’`Øíé¬a0G>VVGKSÐsŒjÉÁXéŸ* ±w°ÿƒ
-øC3 °3Èü¹)Ö¿ëf qpƒxýGØ ±ø³% GVMØÉ$+ñ?ÉÏ!À¿bV ›ƒ—r‚ÜÍ­Yÿ(©ááúdÿ#l
-±ðörtpZšÚAAÞ`KÐóà5uaÎ. o¯ÿø÷€h6‡Í@VÏÛð/öç0ÈòsES˜3بÏÆÂÆÆdûãÿÏ‘áó†Z8@ì<þ•®dj²ªi©+*Ê3þ½÷f‰‰9<S2³¿ã2s¼ç~vÊ3#/7çßÿ©Å_:üU1ÿÏ:ÙþE) ±t
-ÝØ)[7q\ä딬Ÿâ}2Ç”¥Wº4BâÃ8êÁø¾d7z»{NÊ/IÈKsËQ•÷fèy eì|Tù^N ~“`³ IA“k¯¿¥•ÓC«?¸Æ-oÃ1™žéÃàö
-–ÀªOÌHt‹ßñ}n縳.i±¼«tÌå–ã4t\dêÍFÔÏZïÖEη2Úú`¿Lè-Š²FsŽ]Ä!JÞlø*@çìwÓ>ׇ&ª©æˆy²¥@¥]kU>=­rEÞ-çŠÇ™°V£¨ÙaQmL1!h²R%^×àj¸Öl;ÓÛì^R‹
-8ÆßÆûOvj(øÏñTÔ¤\¥+Ö#2\…¿n5;ÿH¯i}¤ß®£Ñå~º9$m`Ƶ'4É)ù6b›•½.†eC[•+ÚËG}*”µ>A¼­dÏGæjøf¬%€Ê4ìªÉ$›Š ÛwÃPoÄd‰÷ú´ÊÈÓƒ8~Gžõ‘÷<Yqðæ3z©ÞÆ 2[¢ÉIJIH>Èe¦_h‘Q¤Ç‹×g\<©‡3Ѿ¯òJ­’ûÁ«‘e‚gìº N¦bŽO+ÞÀ“îS­™c­Hœ4ÞCØKH÷²m:§dÔ’ÆC»t½€!…Âæ©.—IóÉ^!Øæ¾ÔD’ZÐZ¢˜ÝËMïQ•¦ùÜȇ®CÄTÄZÅ‚zŽz­‹Ä#EÄ7ÏLm}.éF?:ÃÓ¬v­Ä3*ŸH“¾˜sLfZžÓ$Vf‹B4®»%DÚ”6òÛì!Ó7ôRI¿S{ŽØ¸Õü ØKÒG;ë¢Od€V@Sp¾¿–_
-eÀ_±2äÀéŠê×Ü÷qóºÄÃfhÙzÇð#e6Pw=3vd[¼¶#mýç;±ýO߇P÷LèLI Š `ßy·bgh¶£ûô•À|ª¿2Õ 1äÔ@ßX ˆãàç¹ÒH_Li¹=YK/0¯§E ÒÀ(èù\²ÈÖ«:˜ðCÃkX[ÐBf µÝ÷l¼
-¥ô€áëÖKŒ× m5X€>ÚíÀ½ æؙԄ(QjiVJÒ˜˜¢`ßÛCÄ9UoðzÙ„íÖðWvªD+ž
-VËkþy…Šä]WzÃÈ”} ÑDE\Mó½}º Ÿ záuÙ Ë
-Ec'b£cƒâºb+"±¡ežê±3<}M ëMÖM6À–è¿ùùn¬¹˜¶´30ÿ= ùƨÔc¿¯¸§šŠQ½¤
-cª†O\—aðIoìì}¦êZzPoë
-Û¸Áü—%N㞺°Åøjâ6c¹×tÔ¶­æ§dÆ#ÒÎIî!QLé=+£oì·Ìl‰Hžñ EF˜‘gr8™!söw’RZ¥÷ªëEËpÍxé(R”Iã½E£"ŒÖ!$ÿŠ+3þà\aø-ñ^Ønàêdb{QÉ°n«D75¡¤Ý`:4ä¾é-TËu—6"Ä;ü¶·M9—sïôñ«£#ÚO1èÒ{!Ìá8„‚_Ü2ähh.‚LjÚqÍŒè• hê1€RàZlƒ‰N?Lä&ÍÀ÷ÝÛ@Tý¾‘VÒb\0í¡ë0ÿª…É0N‚%»î•+1¶•Ì1ÁÙ7Lûêš_Ô>X–ÙG]td1KâƒÑŠQ¶SF$‰·U¥8:ï¾Ó5Ÿ½OÜÇ'vp¦3gGp|wã›À„J÷Wó¯c¶LLËFÊY7pŠäh·nK.q ¥'Œ/®Â9bŽ‡±Ïw 9_2ÇÐfÊê¶VWdÞ·¸áË™w7‰œ"Óù}R4T˾jVø?âó~:Ãí1~uÊæ|*€Ó”ʱŒ«HÂ@pÎúNšú 7¹á8[³?p~¨y4Ñ5r€»ö£õ5C6Œæѵ,âM˜“ÕQÓ8®‚ùÐùU7 ¬Ûþ§>S+zâŸ[VÑUŠ<¥< s²Ê&:Nð )ÎIJÀÃTãÃX×ò
-ÓsñŸ¬5ŠN!úŠNÌJiJ¥…+kkŸÏÆròæ¢ß ÛŠ)Äxžcé\Œ>Ð~í.í¯râ<èªëf׌Óy¬VÑ‹ÌYÝn§ FÈK Rd"1f…U´†ÇŠŠ”> ¿¬öH‰Bç9Ÿâ‚â%¨„$‘ûò$,gÊóMV0êôÈ­ž·ñQÔ‡‡´
-åƒb3èu¯ÃízSHø”Ç!=ÐSV«ènÞèõÐ`åÍ’ª;qg?Ìj†o+ÌÊ€/F;=!`ž· ÀË!¢Ëþiú)*z‘ñÄïø.ëœØ½ 8Òà4AgÉ—õ:fÞv\JÞ
-L^e°ls›NäºÔ§ßýšR6úù¤Û°éµÁkkùéÓü½I°±U-«a¾rBïñØ;e9Ïx¡‹K€q("Ãßj¯mµW.~ØÛüÔÚuf«ù)ýûU=¼?R‹ï7éÙ5ĺºWéŽò¹ÊaÉ[Ð4Œ@Çrßg|óy¢X–%}ƒ _l3÷ó*CÈz:â0ÂÈ(PóÇŽZÝô†vÌ£1Í5KUFêçöóÉ„¨Bß¹DóV¿ý\öâ•GþÐò$uI“!š›*«±5í1ÀÌD(©u›P¹©üò®¤Ãóãõ€2^DõÚTnÀo—£AÜžÈ77lŽ×¿2+ó33£‚…VØsùÜÁ&ùK
-
- ×yLˆßº§(Pœ(4Ä3dBmÝkÇ–?v7‹]çì£ PܹïÏ›ËèÓ}
-ð(8ôðY&Ò”}„yäÖ5ð±KêÑ&Ek)Oá†x°ñîs=BˆFÆðïDœxѯÁÛìÍ㓶‹]Õ¼ô½Ó lIÃÏ6<<*°OÖehÞÁ»GÝ„1S¯¿–Z
-4; ÃkÊZTwïG¶¾htû»Ï4êªÖR¡Þ'­ DIn>˜Qâܤ¹*'_I¦äÆ6 ¦æ>»\<º¿UQ, ‘baà&#ç^ËmÛÝ[oâù$Ç©e$òÔqµ=¿=jY ÄPs˜³ûD<‰™*Jß–¡£fo,_mSBºØɾ z ªS Q_øi¼ÔR@¯KFÀ®+µ™øìiåÁMwš”¶µ<ñiÒ^ìjg–Öëã~f쇬òÑK§kY¤Ó
-
-j¤¹‹4;X£O<eïc¯¿ðK’s…]䆎sÇï#ó ThäP•©îyÙú¼Ø ¤× ‰"i§ ¿wç}¨Þ‡ø Û¾yI¨A¤ÚáTŸÑ8{Z/|&jêãõ®Ý>]ãPò÷2× EQà{‚°rëáÞ8,~;;ÁWâŒÄ¯Fõ9ŠCá•
-j[ÕeÀUoóOõe¹#´M7îL°”XËzÛƒñ…Œ‚´Wvû¼‰¼†Æ«<¶eªhYÃ<ÀæþÆêè²o¦ B‹Ï¯¢:YAW󹄛é_³óöÛЛë7.ï.¹m{(Az>oɧÊé^˜ë@Zc—‰7*wÈê
-›»WVö]°dÙ®ã\öý™fÛµ‰t9¶¤V}îñìÝØì¾Vᱸ¨Ô3Z( -ógWÎà iÔ“g±Âî1µúnG¿Õi/ Ö®aª\z6wH5VkÃÂXŒYg týSH}vˆqé-ÂY/Dbø¼ýdyP8s
-$RÇÌvé…h'w$K´|†·í…§™;Y¸ñç?óg›+HGÓðF~pQD=YwW´äL;v£ˆ§&Ì3p}OG_½¼¯2y¼¢@Õï·URåo<õ4"¶ÐþÁ€àþ2½öÝCI;¥ €)ª¤ÿéì¼Íµ¾ZnùˆÛ„œß~‹øŒþ—¢@™ðÔ6!†%ÿKu9Èš¸ØA`ŸÊŒa¦ ±¾!¿¯yÙ´FmîLRÂöqu8.ó‹j5Žó®Ö?ÍžÉÎÅ¿ïÅ4‡ôc…g96·¼ oìŽ~¬ðBGÆY6-¹ª…M6õÐêY Z`–ÄR:´t‰¡¼JÆB ÂP™\µÔäœöF-<u¯Âû]ÍÞ¨6ÆÚÚ”u0ÜôæN;q3ŒN³Pq]Øw'çjªóMõÜA0”‰R‡Àâ=ùé.Ùèí'wÜÒÛD†äúŸu®ûÍ£\y6EGíŽC¾ô/èÆbIÝ72Š#ÜrnTözêñ k7Ób’Q|{wy™ÉsŠBd‰êqzðõåñ·D‹,j1^U‰pðá—‚[vžgVD#vR…ôz¤uí3íë œ¬ûvªÈ¤©³q.ÑA øƒ„£Â«|Ìon<oÌaJ‚P4„¶@“ bIðò)R!%|rÏOì6&Ö¡‡Í
-s–¬7ôäP"sÌœ9|p]\ÉlfÏ'ªv7K¶iÍÕ$¸Áî}S[ÜVK cب0D×”ê0Ø5ò«¤gitËZhg7ñí­¢•dÞÚÇ_ê¶~XD¦pô§Æ%=Ñ*F꟱–⯹ߟþžª+ ýê»\~d+Gϼ%OÙU2ª©³g(÷|˜KÞ8åº~ý=M¿¨U;µ
-ëAv4>ÂâÉb[&èëÛXåõ‡ R'䄉¥ü"Üñý"É)¥F{WqÜj³‡h!YNéðˆ~~ò"ÙÐ5Œ©»Xçà ‡‹-Ýxä%ñqÉ>ÿó1¹rP*#7
-¶²çìÞê’ñ¬Õ(àmÆÊÞš± ~µnH¤a0³•JT½6‹’¾eËŒL£õ•ÃSóM <zÉÞ7B“Ü¿‡Ì/ñd=£TªÂ÷!Ö«7#.lG‘e‚ª'6;?3n*Ìö{<^iÿyŸÇ5½ÆL ž›4Ûã6P_††
-Ëȯúô$ šü=Z¤ïs£öjïM ­È"±óBc!¤d³£©Ëb”ű‰„g²@›€³y‹u
-¢ï,Ý™Š£°ƒûüµ±ÒI‡c&”ü¼ün®'ñ°~ÅH¿ßýø ‡é+RúŸRû#Ì»’ŒŒ[È1Z‚«„äî<úüEþ„þ'¢DEPˆ¨½|”‘s¼j#U(»1é·–½,ÝÓ4Ešç×Ü WŸuÓ‚S{:D¦àæ }ª¯ÏB%Ö^‰$—Y –Œ8Ǹ %³šc&h˜!ç¹ÙG£ÀŽ–+([;3ˆý¡ŸA`´ž°ç£G°øªlV˜SÞRÿS”W~V'¦—,É*ZÊÿëH™­ >FþrRZ§³¹™ª$@!È¿Æf'%N¯Íqg'á4¤ÄÛeù+¡D‚A¿x0J1»ôÖ©Cøp:©¡Ý69‡Ñr;âš>ã|º‹Úˆ²;h“Ùé gÖÐŒíõÒ½Ó’iH)è¿iŸö&Iû RKÈÜ-‹Åx°VÅ Ec°ÖH·1ÁïX™hF¸íµnQtCç¬``*<L5f¾ž‹•3®h¥ÞÞÃI‡€Ú;¿ ñXú¡}JlZaÒÝO—˜‹s1ä¥gH—Mî\åœàdH
-_„á}<É!‹à¨'…K^y‚ë:­C†j½Åê%½2šI‚£Dϵé¼H
-Å2ÑÈùðîì”í êzTóM¥ŸýØc¶ªáq_Ø™
+/Length 9500
+/Filter /FlateDecode
+>>
+stream
+xÚízUX\[ÖmàÜ¡pww—à.…+ pªp‚— Á58„àN°àîî—
+ìhùgK–nÎì:Ž`7Ð[™ÿ ~Pþ…Yƒ\¼\‚\
+ò[^(>P3wÀâòõù߉ß¡pr,Á®
+{ 9Ø888Üÿ\¿¨¥“£½×¿ÂUÍ@
+<A(‹sNÂÁ¶5Á­7U’$¬;cÜÝ|:WÏn<(Ñö0[l°]ª„v¥$<¹¿’²dÔ‡mÄ* áTà`BãHd£ù=ì¥ÚرqB°a"ˆÙjET…ÐÎ&~qtÇ$LÉ9öêS8¥,»2 “ÅÖ
+uÂó'»îí»¨!—å—#«íÏ1
+âßž¨)Øûi!Ì ¶Ëp؆¥ *v4LÞÒ+QŽ¯qÊÛ°Mgçz¤ÐyýgBåQ\kÎÌI Jù…ÚG;¸îl¾|³º«tÎçUä6v^féÍD5ÌÛìÕ\le¶óÃBøÔ[mƒ
+‰[Æ&JÞj¨¡Æ…Üt,ô¡Jêh:cžm+SéÕY—ÏΪ_‘w+ºãrÚ¨UÑ録¬‹yG1éˆßl­A¼©ÍÓx­Óv®'¿Õ½¢®oñ]nñô¼—ï©cåuž±ë!î;qMÒ%|˜îÕR_àªkʹËWnFe¹‹Wl·@†3tlN ;ôµ»<mÈ™óì‹MsËÒEí°#sÖÇr°-¡ëiðÄøøiÍ„³7|’nû²ï§pµ Y8¦øú-ˆÌ2ê®# ÿ¶Ñõ"…-¢Õ„É–à“ºÎÌ×7yGž,x‘¬2x“ŽVü1ˆÈ‘hz–ò%¬ ä6×/¶Ì,щ·ëÁ#è7)ÔÃè ÓWu¥YÅûèÓÄ6Å7qÝõJ¡rAH7ÁÈ›!µÎܹN"^L÷1ì#fð»m6ï˸­—^Ùf/l>‰#‡·–b6ulªƒr¨í}™7* Ð1í Šî
+Åü~~f†<mz?œš>K {5òòµn<Ÿ‘Ð"+µÍ…¬Ìø6_‹æµ*߸R"mærÞ)™Yù§¼f©Ò;$¢)4ƒm‰Òæ숰óÇlÿðߪ†ßõˆßµ:ƒS½$}ôón†DF¨å´E‡…E®û•vX­}Yãïš²¢6~ì<ùцߊ닩²;ÎÊúÅ5ÃV±kÌ*å JÅï†]ç! ½CËN’’çd[Ñb}Ö}Þæ[öÕÎ’‚ëó-ñ`b‡2á­YsawE÷ëlMàÙzøüÆÅbú¶ÍÏ4œ2¤€³‚7¶#]×™±yÀ/u˜Ú44‚üÐ3e`r<#7(uR‹uçÛŠ5š¥Óæ×÷ÅÕ¯¦‚¥v„µ}oPíÇF`<—0ß•værÊ·Û³%©ÌÒ‹FI¤mô¢žô/ËÝqƒŸ†µ}FõD-V;üÏ'«‘ÊŽ™*¶Ð ™Újß ôÑï í_²ÆÍ¥ ÀFKR˳S’Æ~sUñí£û · á Þü:e·}#^Á‰M•øÁš/Ð'FM¹ ÿµ=¾ö6ç¡?R9ôÛf;Qq¹C‘ÐFÿï|ÓBáZM›‘8l#7ÙÅÙ ú³òdÅ"‡3À•`{e&ËP`' ÅœŒÆ‹.tjåø]Rƒš·i‘É°Q|Õa;¿îÕ_¿zøz {îÁ™À—8»´üµÚq=oûõ·k€»fwþȶʣÀ÷çJ¼ùÀß=p½¥n”~Â{ÉPÓ›$ ñŽŒ Ùè`œ“êè_‰:ˆtHlÊÜ·2Ùs79ç ­
+ÅWy\:T*‚}ò
+…ÉGÿÐJãöÄ{ ¨ÃÈÝÅÔiÜVnnFʹÁtj̧é-ÖÌ÷”–7!ÀýÙ¾¿C¹x—wï\áìŒz ]Ç}Ä?âU GEu=…Ó‹ jaF«AÓNQ(E®¥~°0FHÜdùós D7jé6Ã/Ç“½ÊAd<vý,¼*Ab1Ž—aË­Çp'ƲV8Å?oÇt¨©=¢ö{sl•{Òõ^ÿ- vEz0F%ÚnÆ„$Qû¶º [Ÿˆ¡å\ ñØ)Â`Á Žâòš Ä„Ê÷×ob~›š}ûQѦ‘["O¯õ3NiËyk8>l—ú;WyOAûÓ"Ôž ½Òrã*ÙŒAÖŠ®ðïì”UIhYT¬Ž}¹¬:(k¥ì™š©˜¡%¬½}Ý"ÃòLÕ»÷a”°àmt>u‰fP:&&Õ2€ØŒsRÔ® ZŽ!6{½‡doàgƒÛŸTÕ¯ØFø™G¿ÀÃÙWHn»–ÄÍ8ªÛÈÈ"¼8µM™XÇ„eÇ™¶HŠ`²LؤŠæ]§ÈþKÇÍÓ攟ä²#¥FÔÑ»ßþð³ÓI
+³çWD`û9ÒäÝ$ËýšžÅ7—©‘+1ì‘n
+eñß3:Æ=ûGÕU¿.Íúø¦ Li¿žÔubb¾¯j&ä©¢ëÝH[.=X
+ŸgB„Ì|PÉV[™¾ÜõÎw yýˆ¸›9O2…ê)ÊâF½·Ñäƒ e„ Ë׎HW¼3°üê ±ˆ.‚_Ûl˜–ûœSrèVšÊ
+W€ì­‰6ÅBÛæ¯"Åç|ü<ah÷•‹ÎÉ¢Ø&Õ 4£HT(h[.”­E‹LéUýi$%Ý‘¾&ÊÊtLz'b5üDW$óÂDwâÖLŠX°+µç9röåÂ~n„îX± ëT.:TìX“@žãÈCÃ3,8Ÿm€²Žä÷sÀ+(t·ûh*ožj:–b—q Ô‹Q
+~"
+˜†OÔ¨‰PØøàVß]ñs<å#ýûµf²ÊÌWÄX,K½ˆ‘Р†Gáî[QØ°•€…,a¡ú÷²TG‹•áE¿ÄH
+TêCBz…Ejä
+J1Vk–pò6E¥–ÜÓì=ïE=÷7$Õ‰_¯ýý8'½ð\¤gq<#±¸CêMË;ÄÖêZw'ìª'öñú_å»ðú %Æ
+s¿6ùýáÜûßa¸lÊqö¦«ÉlÇ„zªu؉¶jò r4irªè/Šð–›ši}¬=Ú±¢ž£±¾†Ž¬VR4ØËã|hwFT+þòijÐú°ých;ôˆ4È*¬B¢ÿ¦€Ð6°$O¶^ÊÇÍ·0~ºSy æ ÍÿÍÂ' ÓµâÙŒLšM½¤gà[A¿ŠÞc‹ÍÌ“[›i±“¿„M¼~®³yE'ÛçI9Ä\ûŠø>ûKÈͧÁæXå°·wžØ#ÝGT¢$5î\u¢;º§”-®18û¤X»†KkÏÅßòû»H(sª“¼xó¼è¼-ÀTÅèÛ‹ªv"1™=¼Ù2'1ýá,BK‚ǘOý=ÄžBÑùë[ÏÓ⟎c@«ne[Ø'Ýà†(ªÕÊuyo߯æá£-º±Ëm=ý„‚W 8î»;<Ú±‹ƒÙzs,l¯ˆ·9Ëu?§\(^Ò‰“ȉ|-
+ôsˆÓ Pî—¯böAGЕ=tÂb??y°÷(QZR›Ðs ­dóé¤Í\=*$3ËSfYå±s;9¿â6Œ¾;²e›\«kæã(u}5‰M§ !Ðöe˜äÝQ'-ç{÷óF{ …ýPë&=¼|ˆÙìÌ&Î’ÆåÁVí*]÷!ž£uàµFØwhIÏ)ò¹îÜäHYù
+ža“î‘fh³+œ‚Ö*CÜñ¡«i«Yezœ^²¶Æg‡ä‰ÖáȽ±b×.˜V+É>´@h¬ëÍ3Œ+ èyÑÅë]ûÊÖHgU€fþ¸Rf»‡‚w`¶:Cd÷Ýaè$ñz¹'¼ÿ9™?!!MÌVT¡æ?—Î7Ñ[Þõððëàoõ»ó]é¡Æ4Í­rƒQtb,Aï‹ïÎjJ6à}dÝŸâ?ÉpG¤Ø½Ø~wß²æ:™®¥¥[éä˜jR¹Nù•Õê~V¶=0L®DÚ!$¹*µÐÙµ+.¦O¡©”i¡R}Rn<Ä)תNUŒw‚„~W²K‰9-Ê“)øY%ÿÁôCöéQYÞ·AȦùAðÚ—w•Ðlu +FºgF„L|º÷Ì®,2Éî95 mL††ÿLçÈW­ªJú93a6ùí7êÙ·IÖÞb;}õ'vT5»‰É{£s†gÊ)»Vì–ë‹bY\Ÿ5è(&·ƒÌI§
+ã1~*]èÛ—ŽÙ‡Ðƃ”ûGàf{·ûÔ9½“V0˜š¤×`¢«%n'ô'ñ¿~Ã{º,ƒð`æl&‚S†Äó¾¥·-o„"ÄuòŽ §3YG\6¶_=2[žªœ6ÏŸ*<†Nc§FÊ”çm诟pƱ¢T *¸ŸÀLõ¾VÕm&ËP
+ќ
+ќȖçiH ÒÎÐx_~ƒ
+<àDKrøˆ– vWXØL[+(¨¼ôu i ùXN¸?<íW%fÁ;j`QsŽüÉZ’áÏQæ¥ ÚbG3¨4ÆÎÌògUã#•šF0ÃÔV`w]§öGŒhýÈ6B¿‚Úš$˜ÿ€Þ°ÁNXîIcFN+ùÙ´:¼¨Hàõth
+šcK&Ž5Ï¢=trPォ¦â·ñ7?U%q^ÿväŸìöí„8&]2ì¶&ÑûŸ5ó¨ð·J²Ä²…|±i…¶ª¶ÃÛáËùÝ? ¾­øÞyÿ;œ:·Ä6Ú~ÝïVŸ¿Ó¿Át®«6p½!#ð©TH¾öÌ}S€‚„2#ŠÚäQ×|`IûXÉÔ}’2pVÿæˆ>ivÁ“T¼,Ôü¢ß3qZ\eºà<×</œàÙuÙ§ÐÒž`F6ô ¥õ9¾@þ3rå4Ê%àÁãÓ)=¨/¡gB‡E;ð>fgö“(ûÅmdgZ1Ón&uX#7›N+Sql΂œu 8Ê›Î|Ÿu;ñwí×ÈmÝ°‰”dh!\
+Fí¢– ¢ÇWB'u6ŠÑ—NÚƒtä£ÌÛ‡²ÞƒÃ­%=hð#,‡“úbç,ðÁ¶jî÷ÁˆØ¸ûn°å¢·ƒªÔc¢všŠåǯ†L¨ñ.ÁC;"&V‚”›W¤ÑÛj­Š] c%æ£ò'­Ê_+zOïI
+ÅPÍ+‹§+d«òtŽ]Ò½þ³ÍoÑÈj)ƒû;[Sz’ÆO™æ³<˜´Á¡43H˜µ³é6˜8ç)—#¸[áÅôÓ}FJ7j–ŒŒžFA1ÎÊåªÁÖ~| t¸o­ WTd`^Wѧp|Ågºyß$ŠÍßbÌh²#Æ«„+o0Í&ÃhM|y:bIëDðâÜ
+Ô…Ö¹™ºãº?Éê‚ú„‰×®áþ¹,L'åò#j2ï4ê•ï7cAIúy´ocpàß¹*y¹¢T„†è==lï5¸§D1Âs¹Ÿ¯2Ê´8çh†Œ4¸²¶u‹BSê71ó°ã
+úcd¸´fôwwX£l¾‡»C"žžá°Ó;Õ €Þ#§9ðñ’_7©Ÿ›K^¥ß÷[ŸŸ'}l«i3…ƒ–Œ—¨™ÎÏÑ¥û‡*eáÁÌ—F
+®L{¹V4Jz}í‰@ŸÌ×V­Ï`Ãr3å>js4_}РEÜ‘*áq Å‰ÚiP¯|-²š§SÊG‹“¸`îK/¡K¶yÓ¡Ú~x°¦î¦Gp;·ï¤>«kñ#t-Š™;Ù¾÷wæ¹SxE”Ù c\‚ßh}U;Q ) 5›wðhى嬭¦“qƒÑÔõηé™õ¥g2qÄ¢G¿žÄihq­˜?Ŭةæó;‰À_ð_Ïáìà,ŸŽG(
+䦶°¬"oucZ^£¯»¥ï}¦ñ¸¸Ãÿ²§ñü³µÿ$4W—ötëœ}¹Åêèb„”ÖÇZË0%/î É`ó#“)±{¿ñÃ3Çî·}Žô„Ûá  +‰(&c¾! Sb4ôékå͵þ˜aåØò;ú€ £€ÿuÁÐh^314ÎjT+Ò2é·O­7<¦iz’2 ðÎ"ÃÌ™. ¤@q'¤esú–¼ÔÅxzäY~&¯÷óG5Á]5Et„Ç2·¬Ý€UŽÿË åÿ ü?!`a2ƒ¸:9˜AìP| ¨«äÿ§¡ü/åØÎŒendstream
endobj
-1060 0 obj <<
+1065 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 2
/LastChar 151
-/Widths 2128 0 R
-/BaseFont /RVSMMK+NimbusSanL-Regu
-/FontDescriptor 1058 0 R
+/Widths 2150 0 R
+/BaseFont /JKZOOX+NimbusSanL-Regu
+/FontDescriptor 1063 0 R
>> endobj
-1058 0 obj <<
+1063 0 obj <<
/Ascent 712
/CapHeight 712
/Descent -213
-/FontName /RVSMMK+NimbusSanL-Regu
+/FontName /JKZOOX+NimbusSanL-Regu
/ItalicAngle 0
/StemV 85
/XHeight 523
/FontBBox [-174 -285 1001 953]
/Flags 4
-/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/zero/one/two/three/five/eight/nine/semicolon/A/B/C/D/F/I/L/N/O/P/R/S/T/U/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash)
-/FontFile 1059 0 R
+/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/five/seven/eight/nine/semicolon/A/B/C/D/E/F/H/I/L/N/O/P/R/S/T/U/W/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash)
+/FontFile 1064 0 R
>> endobj
-2128 0 obj
-[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 0 556 556 556 556 0 556 0 0 556 556 0 278 0 0 0 0 0 667 667 722 722 0 611 0 0 278 0 0 556 0 722 778 667 0 722 667 611 722 0 0 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ]
+2150 0 obj
+[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 278 556 556 556 556 0 556 0 556 556 556 0 278 0 0 0 0 0 667 667 722 722 667 611 0 722 278 0 0 556 0 722 778 667 0 722 667 611 722 0 944 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ]
endobj
-1034 0 obj <<
+1039 0 obj <<
/Length1 1624
/Length2 8579
/Length3 532
@@ -9823,67 +9974,61 @@ endobj
/Filter /FlateDecode
>>
stream
-xÚíwePœë–.îîNCpwOpw‚{ 4ÖÐ4îî \Ü!h€`ÁÝ,÷$À½ï™3uîüš9¿nÝ®ê®ï]ÏZÏÒw}ÕŒtZ¯9¥m V ˆ Œ“—‹G  v¶òpW‡¸¨qÊ@œl4­œÀ€g@ƒ‘Q
-ÂÀ9 $0
-&b¸qÅ ´ÎhxC܉×GPWüýˆ)õàö†¹øËà@÷9òço”ìyoÐÅ=‘°™â‚Ýò(%õ*ýb^Éâcš¦JOЯúaÆxŠÂÓ®
-h\ãO—Ó8Õ¤'Çn¢¾Â3ÑdéR¢¼‚cØÂÏûËFEÏz¿};“bºW’'•Jˆ[o,?Íc J›£a³b tÎ}6ªØR Pu}Oøû¾‰Èäè0‹ÐÐ÷ªï­,1…PŸ=îbño¬«0¼p«¯E4´J‹æü,OÉõ†ôÞ¸u—œ‰³”J¹çJ¹úçƈ2üâeÒ&CƒžÞñUÀôj…Ÿæ¾Õ’Rȹï¸Q>Äþ|WØ^[ø
-Y`Šù½'‡•”ò7;)uƒÉ5ð{yi¯ôlVÇtùŠ°ap™$=Ú¼| ¿Ã2¥ÔD$mCG75vܾU‘'Ÿ·^¨%Qëê>±Œ­v¤i¢œÆœ\DÅæ$Uyœrï…¹Š]îI“°pS{ÕZXÕkÝJ´ÎÈw\xTû ni¨ õà=7¶Yˆ}Mäo“ÊÊôA6'¨'qž1§?õýµuÞ†mŒ:‡Ë]”9š5ÒŒÚieÕ¶®ÎZúN¿‚ 4¶°ÀZ™hïøT£n q8ßÊM#ù}J¼ÆK/'œ­îküNáNñu”¬;Ïa¨t&+ã;&ÛTüøŽ}¯_ÙÎ/åP”Ì¥µbªhSúOMDC:C£ýquo*¶“Ȼʹ*ÊÕã Û ¯ò“»í6ãµXp—
-C݆î°|Dƒn’l³Fs*™3DÛj^®.kmiM'
-ýœêe#¥M ó£Yùìì"Fà4¨¬œÎq›Â邱Jë ß¡cùºj çÉ
-¥!M"Uk×ӠѽDöþÄ®v¸é5¾›¿˜”ÖžÐvÆ{mÚDÍ[‚‚µYxë04Æõáû™¼ã¡x¨`ï㢘ÿGÅŸl¿Þ‚¿M2[韷(ÿ<Æ%ÏúSÒKÜÖxóŒÐTÕÌK
-Ê¢z4²ô+êŠBÆ=ø ÖYäæVwv \,‘Äçí0~¬94¤6ƒ M<5îº+® äÙmf!à­4‡¿•2SÁbVa=áî¡bLïW7ÖrïŒ7‡­4üþVG»!\èpÊŽ¥5ÒäG­o#V×#KR‰gû³p(-¢K餒|D5Á\ UïËb¥Ä¡ïÎÕ*8G‰mT±%vžIßOH°w“3Ö+ؽgß°)»œjÝ„¯~ÍÜŸkºôØœ°&k¨;™¯—Öì$‚Å— £
-
-ûäаQoâIÒîGžaWŸ¨•h‰ˆx=}«Ïí“|ûؼ‡Ðé6ÙF£¹VàjÁÓllyÛÃüù5N†¹á±£LtÝ“¡‰>åìÉ÷¾ƒŽ´OT ôNó˜yûõ²ëáô—p£KTóÓ+±Áz’ÈÜ™ ªÌ@¼Îâü/Œœê}í“Xñ$R¨ÅኾÝë;toK’Ö~ÕŠç7~g¨ nX,ÿ\¡Žˆ/νtD¨scÓÐý#íã‹™%¦”ƒ~¥@Úë+“wZï34ÃŽ®ÔÚ^Ûz:d3
-Žš(nÛ¬³&XÈ{‰TX
-oaguÊ!ÛçÜ…ÒŒ9dëÉ’¿Õš[»Ó7õ§aNLÉH•.‹ð·ä“q#t|%öuþÄRÓ¹+Ænvê–‘¦žh}í½B׫üsóø‚Õ9*«¼ª¡M‹E“½h|íøiG½¡^¨!¥®_œÍeÜŠáâuç±ýïQÎ`Ÿñ‘Eôï þ<hû×ïãÇí/¿Z´;OKœ3*Ñ7št9êª}aëqî`˜KeY†Ð%×4Í»Š“0Ýð4Òó½F4ÈK ~ÔkL¬µí÷²æíû<?Sg曬‡4(­i £v,oó'$@ÚFÒĬ…2cVîŠÏ*Üsí-ª?6:Ô†í牷:öL^§îµƒVËÞÞpjf<‘Ä®º9Ž dÍkǨÀÇ… —°# å N‰{«·7üX|‡B/[Ýxä~Xš¿ý ‡r>©¦%³u£:GPb²Ü"â ž$•Ç…t“3=òáüŒ€-ÚYlAòv½YŽ¿ÛAòàò›œjv¿mºF­$ÎàeKOÓÞ|±•”.ÔèÁºAu–>Ëé(gEp‰ÃˆbP3P-,œYàm™Y‡ä£5OhÓoÝüŠú˜ V{Ÿ*»”
-ð„pÞõ¨©îñ{ª•[•#ZòPxéÞ¾‘
-NÝ^8Ü «3ëæmVšRrnÓ%B#mÝÅÛ
- i"á4
-ýeë_|I'ýe²%É*”-:ŽOPÏÕë—|6DêFëÈ:Ý‚bšFãƒoi˜SŸÚÕ¶ù•LÁV¡ðáx{kð§WìãAøÁnË}é…Þ‹bäQ>irîåÏu×㯣 ‚9CMs{–=&SíFSNñ+cnç9ü“7Œ ¡ù_zµ’èh€Y?(8³X>×
-°.àVجÛ4ñmJÉŒûwB´Û›Ì:3ÖºÐéÅ’ñ×Ñ-ÌŽ<̲×q!]¦½M#Ýò¢ÇèšEÙ),f)é±³Gk§ËùdIÙ(<Š*ñýLØ)8Ñ|©®iÄ.#w°³‘.Ìnøk›ýXþ‡¿U6ÿR¸Z¦å«~úɨíx>$Ž$w‰íqí°ð“j.¡9bDE߬õg»oÈêK2´ï¦Ë¡”’¤DõÙÏO$;ô¿c’2ßVª¦¼z(ƒA(iÀvnýkÇ—“ƒÑÚùó‰Ü<ÞwëãOÛæÛùõ˜z)
- †ª¥
- cÎI­7ã*oTQ¹¾Í†Û‰…¾(϶jääiý¶[ÿ6ýMññ<«$e —8§Äk¡ág©’–ˆÕ¬€ªºa¶”U…¬L‡RÊÍï¨_û7¬G$Øö<¡ñÁãx)M"Mi<ÅDF='Dí¹ThßÉô=¤Ì]”:H闤߮«4~ØM\§®­˜Æ«HÌK½™¯#·áÇ)U%¸_°ƒÄçaB[ctN½çÒˆõ˜#dŸÛ+i(]Ê¢ðé}ÚI“¢ÓFƒOTåXi Ø9U¡Nr°4‚ø0ÑHpVXõ¾ÁM
-V¾%FŽ¬´~Tûù’én…ÕÞðd´ùñ}sBu‘ißÔf6…–âo§Ü/ÙÎ3Ô›n¼¦p±s
--Ñ}B¾{?æâ/,­˜úJØK=1G¼ça8Ðq)‹ùB¨éÅîi”ÐF`r"–»è¯²%$åIwÁýK5Í6×ýØÇ.é\&ŸCÁEÇçeΛð]BR¼ô˜‹Åع­ü’f<øußýûà°¤WÜz±Ë"ŽÇ•gTu‡KBÉ/ïE>GÂÂ'‚‚˜HJmú¦4=­ô‘Ÿ¨ý˜,‘´úe5ß_‘T )FÚÍšÂÔîKÑð'׫£üt††Ðlgëžÿ™í-Mu×±|Ôõ}À}/é‰4¶OÛvGâEš~…sð¨ïª=/¸£bmæSÄ.È’”Ûˆm)Ê‚?^FáÔ|ó«»(úü&­¸¬lVkùîØœišYã­kïX­¹Us»P÷Íž_TÝ› µ3æÉžëMË€¾Ó醈`Žõ*cªüR5fí¤6uci&C±{’g>׺ÞüÓî·yÙܱ]ârA¡À„ ¢9ÉÍ|ŠH…:%9]ò¼ôåS”³xb¶Þ<'áRçÂe\¹$ă¾Já(-â›äc툣ôýˆu˜q‹nõÓ¥áÁrg)Æ<ôÄt0ôoôp›èÑ2å9Ð{ïÇ|óYaÝosó4cBù5Å«‘åÚBèoðï¸Ä·É{X. ¼yz¢2ïnQ‘6Ôð”D3¢èüÆ&4“ƾévÉ28àËá-=î•l)àÛÕ4xažœ ½”Ò{,·S#`áÐ_Ù—s²~a¥d⚺½+:.3R•;k?ú]±$—ÏÈÖ²Ö}™¬ý®Û—¤úëŠÖxùGôÝA zcZm€õM]Å)ü5òÜ÷Ô÷ΓòlÉÄç¶vr_ kbPwÎæZßýÞýæ X\¥U}®pðc#®~?ùö+Ãümå¶$WZTÎÚç¨_᥿ÉLËbàQg*'”qØw³†óq•Nyá¹ËM°¬h‡òzÆ['¿¥×"ôÅ¢±-9f)ûÈÂy1ù»œ‡U†°–b}¼fγũíÓUf9^¨,ສg(+:ÒvÏÐóò½ß؉ñΟ<o¶·HW˜­Û+PûV™{p˜³…’A©@ÞC×F DÒUV3<—®t‹ì  žBú¦2û@Z48,ÆZYÙ ßéœZGÖsTK`|µú•±mŠ‹é°
-ö7n&„B¹š.p{%ø*\¸ %ßÖ˜8e•^4íã9m®RÊgAW?­•â«.oh76 ÐÉPXd™2{²nLÏXý®u8ÊÔ­ÙB¡2‡Ö­bÏuNç7ÖsÏ J~ü™äM•¦ióíF¬‡0Þ—ÉÕ¿ÈöÎ2«—l”nç“oú«6”|‡Ç Jr!˜ÊbÊ|øˆ¶“q2XõüðóäQã콿À¢ ®ÉáÁcl×Ï—Ý~ΔêJ¢1¯ª"…‘Ê Z¸ÆÐÃü¹\ÌKðÀ$5wÅ¡¦á‡ZJ4‘¥*4›
-IÅD³H?4“ÂÜœJ“ƒ•›¿$%èY}e‰ŠÕÉ$L(¯ÝyI 2Uü$4ðUðú3ÿpXé%DmßþAלÊ Cšv&¢J%­ ZŸ¬Úõ8…b¤CÁÜ„±÷'Ë*šÓ‚®Õéxô¨w |D$Ø•8Ò->IÝ3?Z‰ŽÉu;–ò(Ð]'üMÇUàJ"ôUøúÕAƒÆy¡¼¿1>ÝèPx,õ)òat{³Ü׆(ÿ¶f­()è­ßš§W²P<ðIˆþ^òÉÓØNiÉÇ«ß$x abzî¸8j_, Ùböa’è¨Ï`KÔ«Âu+«Û·kc·­¹|
-IÌÐI íßòÓÇi€39!5ÄäáÃ^,$)¿Û˜p©P]¾ÃRÛéòfû&Ú_Àå„ÿ"r¥–VkDqO½`D’Õ3 ÷üà‡x|ÚR¶¸òÝ/0Å4oÈ@ݤýûÀçp»¶ ĉS켘=ÛY¸ÛÄkánšqt¢úþPoBÉ6rÊ.Ô«‹´òÕÇÂÛ^*6I7õ4·áJøÐD붩»ö¨m~Íb½®G¥!$ @ž¨KÌU*Y±ÂA§lnw1P‚™ÿ$­cV¡¿Û;ûŒ—lׯN„Ho6ÐÄ¥‰QDÕâsÉ¢”µE»È„Ó=ºƒKÞÆb9…~vÞhö%Êüžæ;ý¡(3»í ´ýMïo<ùb±AvC‰ö¤úÅ^ýÎFÎE3y¹Ñ"Ã>ßRâµV£¢u(ï5ÙÐõ%§?*ßuGJ¯ ÌÑ/R˜pÁéÎoÄí…¸ Gf~ö}7Òc‡ª%)o9çqâ_wǾ|¿ò2ëBdØ2ºg¬‰MÜíáÔ(rñ$ÿRÅôja«•ËôCîÉ÷ƒþûTÔ÷µT.EÓØØ´ÊÝ‹—gon)QTsï¯æ©¹¡_9ýuÁæJO§T´6^Ö´<‘¥§³ù6x_Ç`X‹àVpÔYá®xèøãûŠ9Ÿa?…’¡
-0s¯ÿò×}+4šlØõ%7éì‰é.d·AAŠfõ>DÆc,+ÁÒɸYw
- I³4sýõ;`°¦Öǧ‰žCͨÃE…ªÊÕˆ@ Òöà¸ÊĺÈþíØûz1Ó$Þâ†uFØä}ŸÙ†uõSÍA›²”ww›ž4s{+2‘'¡ð^®ý2ú;ú3tŽ—R¾¯EstÛS+Nys
-Q6‘TòÁØá§dÑß’1÷uÎT(6R_m]Ô1Iä›5·DÌTÚ[W”e$']ûyá¾Ü²AOê®5
-)“âgÊ7Mýæñ(xâ)—8¾°Ù¯&ªSNù¹_ªÈ¾„Ñ8þ‹†óê^u;Œ\¤ƒ€¡w óµUXÌ(fMF#ÂìûÕÃL7¡¾]ñž°…šâQEÿz•óM×ÐQÜýóšÒv¡eôâ Ôº¾ÊEÉ,Ï[J[&i]»y’œÎ3³ªÁÇ}+gµ~mŸSÁ ¯-$é%ó¶ }Å+j¢Ú›ú…ÞZ£Ðã涨Ã`=ÙbÁWŽ›íc?fº¨RßEXAúÊ*O‹Þ"bóʱœf׬J
-:¥*j@þVÂ_&u.Š¬çè<1­–øpåŠücÝ$<†³ÏãðÛ¿t!Þ!+·šFX;µ±÷
-?í(M<¸¤8ôCî@Æàú+—»Ò•#d“P{—¤ù¶‡Ög¯ù©7½lŒyçÂóé½c!sª²DFà–=÷WË\·Ú8ìû´eÏ/nÃBÙî&¡ô˜››uÍûä/L»}Á â…Í ,~ ¤”vbÂAèªÐeE»ÏÐ/ÁEÑÏæX¹Œâ-¢aëͶîƤ´C³0Ù–,^Õþ”C,OkáÑßÑV *º[‰»¹Ò÷sç'¶±P™n¼ZÓ§€qé’:S·Ÿˆ˜QI •]žØ:h~ª¤Zoá@„¯-_¬N7,¬Š$J/’5i²S#*Þl¾.*zr¾È–Öþ)l,Œª;v`áiÏ-Dÿ¶•Ý»@%˜8…ÞB$ˆ«#O¿;Æ1‘ú#­Ç Ùa²:çu†ç‚†sž–ÿG3®áOpŒÓYáÚt1r¨Tü¼ÊÃÛYíÁ „BDùxµ»lûôY¿øÆw‹§™n¬XA{
-u‚jUãá(Õ6óü1ùõd…é†Øœ‚(øìyþÁ»&õgzYsNDu^$¯lÝsÓÚÙ¸¾GJÿ0¨“À{3†þíÇ|^/Õvyaq'°´¸ËPópnF3g=?!a;D+!}Æœ¸J[4=ËÁ‹¥Óa|_j´Ëˆìª«§mÊÎl¸?Êhl0|¬õ¼À†Ú5‹“UŽ÷5c3ê…b à ƒÖnœØ }Hdv*õ–ÀûŒ*±«àVVE,f–á b_Y,\þ#¶w"\¾ShÙ_½Gö¾’øì5D›™Õ3¬F·‚Êáwü¨«î¼mŽ†Þ{ ôq¬pt‡!ø¼„?dØ
-ÁkVHÜW/¹¹Kefv?ù~‚I¬µÖ­êtKcuâŒ7´L-ø9è2Ìÿ&ÊÉ-¡ïþ!D°‡ú(jµ#Vo+¥ú1/±q”y¢Ì¸g yܲ ùN ¾æ‰ñpþÀhf%ǹD!a%Þ*kEty,ô/ÄéÀÛÅ°ú{^N:•ã Õ#£BiØðÇT§¼÷NM‚N“œC jJc38'NZ÷mõ±4ký„bWTÞ?PPÐ}ȈŒG/óTô›!|±,dGXSú&ÓÉr~áíÔäÈÅŠw]|Þ’Ó„cÅR4•ÆÀôå¼ÿo•oh{{t«õª¨©Îm²
+xÚíwePœë–.îîNCpwM‚»Üh ±†¦qw'H°à’àA îî48A“
+‹ß5á\ãb­Þsß]v”Ùv»I™»Ò@§Tþ/X¿â¯1µ ³ï†p›•`géÇùžÍªn  ñèínji›}üB=ÞÎE;»e záQDÄpã‚`•^ÿ–¸¯Ž ¶èûSÊÁí sßÐ×þ® ä/;”ì¹oÑÅ=°™bƒ\s)%Œt+|£^Ë àcš¤HÓ¯øbD{ˆÂÓ®hå_ãO•Ñ8V§%Ål¢¾Æ3Ö`éT¤¼‚cØÄÍùÉDF͸wvÎ%™îåH%ãc×ÊÎrYÓÀfhجس_ Ë7åCüUœB>þ¾o¤²:ØÏ Ô÷¾î}'CL!Ôk‡»Pôë*/Ìò[! ­â‚Y?ËSR]¸½ní΄Ê~Åœ Ž #DiþqõÒi!Oï
+ùÊaº5BOsö;5¤²nÛ®”‡1?ß×!¶Õ¼Fä›`¾EïÎf%¥üÍNJ]Ë`| ü^VÒ#5“Ù>U¶,lT*$A6 /WÍo¿D)9A[ßÞE»¯oOäÁçeˆbAÔ²²O,m£a’ «>+^¾1AU«Ôsi¦l›sÚ(,ÜØV¹ZùF§­#â=Õþ§‚[Fª½Ph7ÆM&âCo#ù»¤ø²ù2y=õ)êilºGôÙO=?-íw¡ë#Ž'a²—¥¦ 4#¶š™5-+3>S¯áŒÌͱæEÆÛÚ?W«EAì/6sRI~ߟ¯òÒË
+g©ùX½—ÿˆN|)ãÆs"•AàÂøžÉ&?®}߳ݚÀG¦ãkx%cqµˆ*Ê„þs#Ñ öàH_líÛòþЭDò.SÍò2µ¸‚¶cô~r×Ý&¼¶aËnàbAˆëàö‘·hàm|¢MæHvsºhkõ«Õ‚%ÍÍsu¢©¤¡Ÿ“=l¤´É¡¾4Ë_œœÅ¨””Ò8n“91Vh½#àÛµ-ÞTöw?Y¢Ô§¾LÑÜõÐop+–¹?µ­ªEzƒïê'&éµ' ´™öZ2VõzIÁ¿Ò$¼yíîRÿ}LÎáP<D°çœqAì%ÿ'…Ÿl¿ÞwF'N,µ…¿Ï™—}å’cý)á)nc´qNhªlâ%eR=ZøvF"ãÆ|‡éÌsr
+ª:ÚÉú/Iâr·?UP›…Â…ÆŸv]NVûsm72ðVó›ÂÞIš*c1+³žrwS1&‰÷©j¸·ÇšB—ëïÔÒ®K…ØŸ±ci7úRëY‹Õ¶GKÇTàÙ¼Á,L ïTü © –B7ÓFCÕýºPñòÐgûjœ­È6¢Ð3Ǥç+$سÁãäÖ½oИUFµfÌW·jæÇ5UrâŽ_•1ЙÈÓMm²OÁâË‚ÑN†~öò¯_¯³ö ió%O·­ŒKÐL°@D¼žºÕãöNº}lÚCèph¥ÑXÍw1çéJ2²¸ífþò'ÝÌp’ØA:ªöÉÀXræô{ïA{êg*PZ‡Yt¿ŽÝZ?ÙõúPÚ«p¸ýEªÇ¹þ©ðå˜ ] dîôŒxf ^GQÞWFNsµÞý¶ ¬8uIÔ¢0Ÿ®µômºwʼn«¿jD‰ó>Š3”×/”})WCÄç^<"Ô¾±®ïÚáÆHýôbºY‘)ù O1€öúÊø½:†æ‡tУ+ÕÖ7v
+\F P2ç´¢•ácƒÑ‹Ù‘…rò‹'ŽÔZOêÞ£ÐËT5ù„–ämýÂÆ¡\ƒO¬nÎhY¯ÊT£˜(3‚'Iáq&ÝàL‹x¸8'`‹r›—¸]kãï²—8x¯ô6»ŠÝw‹®A3‘3hÉÂä'O,˜G9¹5j v@Í¥×b*’ÅIœOb?¬Ð ÔP M%gxWªIVÈ!ñhÅÒø['¯¼¿.:°ÅλÒ6ù€@š<.œ»M=b¢³G<Éžb©ÎV逖4–Hº·ïK¤ŒS»7àâĺq›™ª””Óx`Ð@[{ù®Hš€@8ÅïÏSAø²ýäʲ½e#óòœ‡)P'dÖŒno¸”]`ú›Ð/ý»„ª6.˜²;NVßn81—hL°g/#³†õ½T5N•È&œ#kXÒ·Z‰[¦ZO¦í Vñ¨ÖŒ[ŸÓƒá~‰ò¼/×èa¶î^"’]d³¨ˆU?c«<œ)´ NGWŸÓJª"Z!ÉÜžo½¥I´¼ ½g:>:ªk{ˆëçÈ Žœ}ÊÌbÒ¡}Åó~@ó±F|íƒ-˜(2.°p{¶šIĨËq þ"AßEðI ý¼Ë¢oÒE±ã‡¢÷§Ðú0 r¿¡þâ°åÅKŒh—W‡ÃégäËC²},7Øz íå¶[D“ð §Ý÷3ð­beÖz«ë{çòCŒⲯÍ-kÛÓ~µ‘ñQÔ;¹F׌~Z¯r[Ÿ¾ÖcOSô•Üše  O4CwT(„¨]§kfž—zëd̹:E.g3G5Õ_üIA…nµ>Ĉe! ªÐ½×~sýücê{?ê…s’.âÈÑ¢8é+û3FX©wvÝ*— n~ ,!PÁzc³ÐMÕÁ—=®“@ ®±&Ó/C¦ì>š#ö¥X÷Þ•ß|/"rÈÏÞJð‚WXhÕö13/¾¼v"sõ]8«{¢5¬•n/ÁîÄÌÖZñÛÕêÇDßõÓ'R
+­)ýHF º6Y~Ûé»n{0òiSÖ^q _±ð¦ÀO¦îEþ‘”8¢±7_'š-CØ¢bùu]<ÉeA$o4¬ÒÌ)¦hÔ?úõt’†:öª^m™]IçoÅÙY?¿î(g‡$ ÀO Æs[ìKÍ÷\!xóI‘s/}©¥¸{•Äb’Ó½ä>‘b;’|†_};ËÈá—´nT
+ƒPÒ€m\ûVO~L DiåÍå¿Làæñº[{Ú2ÛÊ«ÃÔM–7P)‘uJl¹!{øXq£‚ʵ3f+ò¢,˲“§eg·î+lê šÂãEfqrqv±ç|ý{EMË5ƒ,IËrévÅä›ß‘¿öoXH°íxBâ‚Æð’ESyŠˆ »O‰Ú0r¨Ð¾/é¹Kš9+¶“Ò/J½[Snø¸›°F]Sç?…)Vž›r3WKn'ÂS¢Bp?o ‰ËÅ„¶DkŸxͦ;é›!dœ\Ø)ª+þAáÓý¼+I§…Ÿ Â1/ÒØO±}¦Lhoañf¢yÉYnÙó7XîÙu®DBÈ_ÞI‰^nù¤úóÓÝ2«Áé
+hãÓ‡¦øªB“ÞÉ,
+M…ߎ9_³œü§Ó©7\y9LàbfLý”Bãôžå˦fð(iÚB5ö±¬r/Ö@¦•
+/ôÙ°úQw.#EœêhüYУ„%UÛ96‘iYÆ·ŒÌï\]”¬®)”ÏâõŽê£p¯ª, ¹ESIªfs èLü„Ü#€˜ð5õ|ºó XŠÜ´Ñ;1*ýó$]˜o4^|œÖarAG–´@îõ´\ph®«`­
+ãDáð£ìÆU¦1*] ÓýQ„dl¯}ߨ¨7(cKqÞ9–ã¨[kwOŽÌ|ö$·¨íŸí«æ|sŠR¿
+ÞgÔ h¥%Ñî›!«RèPêé]å’qh”ö$Õk<©6–ìùŒ“=Ý°ãs8Ëqçsïï>®ê še{Þ1#ìgŠ²8egç~¤’+J˜gÑ“¯©²j>-Z’µ×vi™4/CTÊ´Š]±‡|ë‰
+)¯…=ղŻ†â &И2Ù‘)„j‘^ êK¡„4
+uHöó¾¤Ç|X(ÂÎiá—0åÁ¯ýî× ‡%ɸìÚƒ]~2¦ˆ8­¢3¤PBþã^äK,l<0‰”¡ÄºwRÃÃRù‰Ú—É I³OFAãÃI•B„íŒ Lõ¾ b­*ÒW{pͦa¦öùŸÙÞâdW-Ë'ŸÜH£û´Í`7$^¤©W‘8z.êЋü;*Ö&>0A̼ I™µØú‘‚ ø3àU$NõŽoíeá—·©E¥¥Ë°‹c¸3¦)fõwÖ.=£5f–MmB]7{¾ùP5/‚–Žè';n¬·ÍýòøŽ—D¤ë"‚ÙV+Œ)r‹U˜5ZV % En‰y\kºsóL£¸;s2¹c:ÅeCÜñ—D³Ùyò뵊²:ä¹iKg(Ç3æxb6^<§a’ êÂ¥\9$Ä>Ša(Íâä£mˆ#ô}ˆµ˜± ®uS%aéA²çÉF<ôÄt0côz¸ ô(é²Oè=wÈF£>yN¬F0‚®w9¹ê Ñ!ŒüâUȲ­Áô7ø÷ó\â‡[äÝ,—PÞ\]Qé÷·¨ÈŽëªxŠ¢é‘t¾£ã‰£ò;:2 öø²x‹{e@
+ø6Uu^˜ç|:¥ÔËíäð%X8ä—@ÖONÙ™¿°
+SÒ±H]^åí?ÒS”:j>ù^±$•MËÔ°Ö~¨ù®Ó›¨òëŠÖhé¸Zêî @­!5“Ößꦶü þyö{¶=êÇ{§ 9¶$â [Ùo„5òѨÛç³ -ïoGóù/. ÈR+¿”Ûû²W }˜x÷aî¶bK‚+52gõK䯰’Oß󅤧d0ð¨3”âK9ìºXÃø¹Ê'=ñÜdÇY–µBø Üc‰­’ÞRNªzcÐØ2•¼eཙüœ/ŒB+‚YK°>]3çÚàÔô‰é(±œÌ×üq]ÔÒ•h»¦éyù>¬oG{åM\4Ù™§© ÌÔîå«îTäfo¢d¥SʆuÓµ‘´F”T/¤*ÜÄ"Úé‚&‘v”gH æÅBY+*z âÛ“kȺªñŒ¯W¾q ¶Nr1=æÁ{F ³N·>©)‡kêøW}À{×.¬´;UBòœ•$‡3/ïtwG¤òt$qËoGćâ·éçë][
+‘mv¿`€÷˜¶”¬d檥—ˆT®•¨U~Ì:¼dLTФo*`›ð=Csì„ :Ó‚$G£C‹*zÒÛüªˆÇzY]R?Ž§iÊ­6&ldr¹á}Ö¢ç2D’©cŽ–RŽ½4õ1@@Ü zå©jF ¿Ê%™RQݤóvš•7Vi4(Á¦¿ o-ÎË C
+È<S
+ò`]Ÿš¶ü]c”¡S½‰Be­])Àžm''Îk¨%æ:™F•øô3Ñ‹*UÃzçF¬›0Þ‡ÉůÐæÎ"³‡l„nû³OÚëV”<ûÇtJr!˜ò&b,Ê\Ø°–=“QXåâãÓÄQ(ãÌ0½ŸÀ‚5®&ÉáÁcLçÏWá]¾N”jŠ¢Ñ¯+#„‘J¡š¸FÐüÙÌàþ jîòCYLƒ5”h"‹ThîÖå
+Ɉ¦/Ž5C]K‚š¾&ÆëZ~c‰ŒÑÎ Œ/«ÙyE <Yô$ÔÿMðú ÿPhÉñ"¢–O߀KvÅ †M Q…¢f`÷væú±BÝ#NA»é`7aÌý钲Ɣ K•{=‚0ê]= v…;ŽT³wz{b×ôq Ñ ™‚NûbîE?Z½ ‚˸¯ƒÉ˜2\qÄ‘ž2_ŸhÀ(7„÷7Æçm
+÷ÅžA>Œ./–ûš¡`¥ßV¬åÅù=uësôŠæò‚~ÃñQß‹?{Ù*.z{ö­`!ŒOÍžE¡â‹ù'™Ï<LõêoŠz–»lfvùt®ï¶6•@! éÚñ´}›¾z8õpƧ¤˜<|Ø¡
+c.8=ƒ¹-ýؽ`硈‚Œ/>mQ5%ä,fÝOýjïøÖî—_e^Š¬
+ÒÆ °9QðÙsý‚v9êÎu12g‰j=I^Û¸å<¦¶±q;~?”,
+:Ö¯}‰÷v,}çx>¯‡j+’¼ ¨XRÔi q8;­‘½–„¿¬Ÿ6mF\©%šÆžéƒàÉÒi?6‡/9ÒiHö^Å’ÕÃ&y{&Ìe$66Úr‘oMí’ÉÉ*Ëû†± õR¡ð•Á¯k7Î[ì…$"+•zSàCz¥ØöUP‹µ;«3ËP:1Ž .ÿ Û{‘q.ŸI´¬o^Ã{ßH¼÷ê£LMëV¢Z@eð» ¾Ô•w^6'þƒ¼¾
+ˆÒ—³AÕ÷Üì4*‡ËGFO„’P°Áñd‡œ¾×vu¼v£¬}  J6J(c8'Nj×mÕ‰kݸBgdî?PPÐuȈŒG/ýTø›!ž|¹$dKX]ò6ÃÑb~þÝäÄðå²W/]\î¢ã¸;cùb•zÿÔ9¿ßÊÍ^Ð`ö¶¨«QíÛ$ÂÐ2Òn«Ã­+³Çø/Bîr/–YÖmí‘×… ¯ñ™I"Wâ}-è¨>¢×6n#°Öӧ˿ÏT‹YeFÚ@ìT‰¨Ç¶&TGŒN·p/SòÖŽgzaN»zµú8#Xáü=ö6Œ¬ªˆ§)xû#YÄ)´9pÍd™"üF‚š¯€ÉŽ÷Ó±ü—j" F!m:™­•0./1S¿Àþ4×<¼ý@(°tÈ£^ž<bâfvßf£ZÏùÌ6G%2À1-øu" gŸü55KS½©¥ÛX'ó”±ÜIlÛbßÖ.’Vð*£Ð´Ëk,nñIlìØî­ƒ|4xn¸·"‹p,€˜,©VÞFôkÍ÷™Ÿ0¦ûÛ~ĵ·_"muFÛF,V¬+×)ö³1|¡n”"Ü3÷QÑjªßõ…°^rÚŠ .áÓ®ÓÅY¹YD§HÚ
+ćPíˆb}Õö#çù_~0þ?ÁÿVŽ qB0þƒÑ*5endstream
endobj
-1035 0 obj <<
+1040 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 35
/LastChar 122
-/Widths 2129 0 R
-/BaseFont /JWHHZP+NimbusMonL-BoldObli
-/FontDescriptor 1033 0 R
+/Widths 2151 0 R
+/BaseFont /PMBWXU+NimbusMonL-BoldObli
+/FontDescriptor 1038 0 R
>> endobj
-1033 0 obj <<
+1038 0 obj <<
/Ascent 624
/CapHeight 552
/Descent -126
-/FontName /JWHHZP+NimbusMonL-BoldObli
+/FontName /PMBWXU+NimbusMonL-BoldObli
/ItalicAngle -12
/StemV 103
/XHeight 439
/FontBBox [-61 -278 840 871]
/Flags 4
/CharSet (/numbersign/hyphen/period/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z)
-/FontFile 1034 0 R
+/FontFile 1039 0 R
>> endobj
-2129 0 obj
+2151 0 obj
[600 0 0 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 ]
endobj
-1026 0 obj <<
+1031 0 obj <<
/Length1 1630
/Length2 10814
/Length3 532
@@ -9893,8 +10038,7 @@ endobj
stream
xÚíteT\ë–-w‚-Ü ®ÁÝ-h h…KáîîÜ¡p'H ¸;—àÜýqÎíîÛã¾þÕÝ¿Þx5Æ®±¿5ךKæÚ5¹Š:³¨©1PÊÎÌÌÆÂÊPÙ;;)ÚÙ*0«Í•­A€7€ ™šZÜhÙÙJü
 ­`fç°þÇ`bgk
-ú«5'–7.Q'€ÀÉhz º™
-š’JŒÿÕ û·§ÊÛ&€?»Ûÿ–FKÑÎô?ñˆ‰Ù¹<™¹Ù
+ú«5'–7.Q'€ÀÉhz º™
k°ºÜ¬š;£ªj_!Oð$ã­Žˆ§·ô~”.ù~8T7öè>&)u±¸m˜ PX5‡G4‰û·7´½Cý}çp]ÛDŒÙ±HÔ.°h4‘~ÙDºåžáŒ[ïjwÈbºr¸°ÌN¤î“ƒðÆüSgÊrUm4>_pû´e{eÊóÀ@’ªí!B¾^gYâ¶fˆ^FT{ônRçz[âœ5Zóì3ŠìŒ—*J–>#
sÁx§¼*o.á_g}wýœñl^îkÝŠÔ'Ø’(Mô{Ä'’WuçÙ>`·pòdèŸoR[ÌÒö! íë&XôÕFZü¦½ê>ì%Ü}g·û[˽æb6J¸uq ÖDP»}"ßžo«/2åKžxÊ$©ü&Ú6|I²k¢QᲪÖÒß(Fà"A=PÎ2íܘ??ý@²å·‡•Hki–óº‚i¦
Û#Ò¾ç‚u¨Öåºp³àž\¢4hS ©–Eéf< ¢sj`ß®›ÌFpï(üÊæú|k-è=‹ãEâï°ü‹üTvalÝ´X\0X¿Ù¦?˜|ew…­K£KòÉäÃïÚجäÊŠíŒ]Ý: %¢˜~¡¨ç7GÊÎÉÃÄ} .Íâ<!˜ !†As¥»˜ö”ÌÔš(;¯3á‘7ÅÆÊ0]²Q|Â^ÿg×C´U´raáfùgzfÊeÑE=n«d?8!j¨¤WR-å…D¡œÊ¯mh$¦œa—C½Þæþ©ƒ®Cä¶wk!FËèIØßaNó4dý6x^z/ë„:Ž ºøÒÈQgæAÊN6æ ž›pP¬Š?¼û‰DÜÄÐ9Ó,4(E#´Íô;Õð¬ŸIaê‚«{Š‰ÏU–¦/ƒH»9ì’Újà(XW†ôí¦Ëø­Œ¶ù¸ä»Ü_Cþ[uë†LFq ­Æ!ü
@@ -9928,35 +10072,35 @@ NaãLïñ˾œ[{Uy<-Þ€-§Žà@÷ÎG{|Ñâ'ú*&MËDß×°‚ÚKÆí¹W!¡ÏN¤µ‘ÖÅe<Ò}øÖÐÇÞfnÑ»
øÍæ6?ÅÖ%X<²˜6˜ü” èýÇÓ·55ιbÏ(L853ïáˆÕë¡›íÐêº/ÂÐ7q‹^¿_5
r•ŽQ¾¹42"ÒQyܽ…8[E~*ï\ºÊYòÃå«&R½n<NÁŽ¨ÎŒóöÀ8mÈpf0 <«±Ìœ/Fµ{ —·î9ýöÝ„PœÒÄ@cÅÿ4¦; ™«×”¯ü¨K­ À$çdLÎð©»$?ÊCîYÇF¢á‰á&Ø,ØÏ<Ú#@Ë%® ]g‰hƦÌäÒ†F`{&(]ž·/iÇÕÜ\p±"Ëbö>¸M¸  ý¡$úu}ÞÕ*äW˹ÑwçQ
®ŽW_hi+yñ¸âÅ‹…†
-ë‰f m…ÚÐJï¬ùÏ¥‹û ´¤ešÌiûFt& ß–³´Ó²ë“´›>Y`™å³{ëéÄ2 û“°dõ>sf gz s‘žI Ï¡¡Æá÷”êK“VeùÞÉÄ;NIN² -ÅêàÒ[xŽø?‹¬ !¼Ž”xí°åJ¦v<x¬/ OKÁ5
+ë‰f m…ÚÐJï¬ùÏ¥‹û ´¤ešÌiûFt& ß–³´Ó²ë“´›>Y`™å³{ëéÄ2 û“°dõ>sf gz s‘žI Ï¡¡Æá÷”êK“VeùÞÉÄ;NIN² -ÅêàÒ[xŽø?‹¬ !¼Ž”xí°åJ¦v<x¬/ OKÁ5
endobj
-1027 0 obj <<
+1032 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 34
/LastChar 122
-/Widths 2130 0 R
-/BaseFont /SVLVEN+NimbusMonL-ReguObli
-/FontDescriptor 1025 0 R
+/Widths 2152 0 R
+/BaseFont /WXJWBU+NimbusMonL-ReguObli
+/FontDescriptor 1030 0 R
>> endobj
-1025 0 obj <<
+1030 0 obj <<
/Ascent 625
/CapHeight 557
/Descent -147
-/FontName /SVLVEN+NimbusMonL-ReguObli
+/FontName /WXJWBU+NimbusMonL-ReguObli
/ItalicAngle -12
/StemV 43
/XHeight 426
/FontBBox [-61 -237 774 811]
/Flags 4
/CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/four/six/colon/B/C/D/F/I/N/O/R/T/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z)
-/FontFile 1026 0 R
+/FontFile 1031 0 R
>> endobj
-2130 0 obj
+2152 0 obj
[600 600 0 0 0 0 600 600 0 600 0 600 600 0 0 0 0 0 600 0 600 0 0 0 600 0 0 0 0 0 0 0 600 600 600 0 600 0 0 600 0 0 0 0 600 600 0 0 600 0 600 0 0 0 0 0 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
endobj
-949 0 obj <<
+954 0 obj <<
/Length1 1606
/Length2 17112
/Length3 532
@@ -9968,107 +10112,104 @@ xÚ¬µct¦ÝÖ%ÛvîضY1+¶mÛ¶Y±mÛIŶm[õÕsNw¿=Î׿ºß×מ síµÉˆ”è„Œí MÄìlé˜è¹r6†.N
.†ÖF
¢bÿÎÓÙÜÀùŸØNÍ
à gçü7$€òÿŽeúÿ>’ÿ(þo!ø¿…Þÿ7rÿ“£ÿíÿ¿Þçÿ„s±¶–3°ù;
-FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF
-ükìzýÒÃw¹*õ?kC蛦¹¿Û=–Îí¿¥¨Æú0¬)zSM®óñ|H¨ú ·È;9hŽtKá3.Ô¢½nevÀ4ÙUö&ê–|BàOw²8BݼPù“¸ø£‘>Û#ø¥5Ä¡w!5¡Ôž_'¾<S ýî½ï?ĥɉƒ&ãqƒ'òwÈÁÐT©ôŠ ^:Ο´Æ¼`4ë‘ä|Ä`ßg
-çÙªqó¹Æ¼?•ÇW‚µS!r¹´rô ìOšëóÇJìÜh2%ï&º¯îüBOºq‘:×Ã[gA:åsÏKÇ€3]®‰‘tˆÉîÏ‹v†<yŽáÝ-݃F–˜e
-꼉ûÊJV=³W¡´F“åÿœ7TDº«q%EòèéÏàªJ¥‡-CeËB¯óv^: %2;GΘÇ+ ôÞºë R#Ç] ÷ø.éWq~úÑuó$ò3@ú¸‘GIß·çøÕpqôgÍ!/ÐTï¼ú¨«ªºŽÉ5¨œ:ú¶Ç$ùP)@ß«¶, éš#°‹vU~_\
-ÕZŒ™ÓØANvŠ]Ïy–ãÅ{iGç<y©0~î–逌’$Ö”›ù¥hYRéõ„MÊ V›OA{ïZm†ŸÃ‰¨õ/å^•ï¾4ãyô,*HisàvßùLM¿N¹a§Î·\ï”øcFè—¤!]š…A‘Ü•Ž›ˆJ Dû
-™”qD½49½ZÔ*G½êþ:) Gg༥¶þÈ.#J¡¤™;>ý2ê-úA
- ,ÐmÍŒ%²Ž¬î|ø"Õ?YHå¦õÆ]½ô!P!1):X·œø~R¯µËöÛÀï/ìº×Ø,‡°ñ
-Ø:|‚¬·.¶–ó_Mv“ôacæ~ϼr²]‹Ë±¬ˆóÄa©Öbß:g× ¯ïëb¥-±÷#ƒP!»‚ŒCîîœbL ÓÞ˘]÷]¯* dÏÕ §„n˜"}x3< `C X‰ì4áJrÛBHõ“ÁÊ„edÔI¿Ì | `Zþ©Å 9;LgÇp™or¬ø
-ùÇ£o&d2Š-j!òçƒ$ÉÉVû~0øºoÞ¼c¥ŒñÖ˜tT
->=èÞ[|T^Êh¸Õ>w~õO¿þÜДr_Ï68È·R©¡XVÏ-‚˜$JÁÏBG×2E"ÏÈš×å=Ú¤2߬ '¢Fö‘bP©¿)‹ÐÞ Ç³Í~Èo´‰¯Ëd˜ž¨D¹²|§ƒ#!vµ’oÑý$WG+³…Íö÷—¶vËx‘’ÁT:UYà‘’ˆ”y€—øÞ¨ôû³b›3¶¦~"î ³Íþ i !ÝT=ŒªÐr/ 2çñÅÂâлHh:cA×ušÍ/[L€ˆ¸?´4~i-pL6‹¯¯g’^†æ
-v߶o…'siEI݇‚>TàM‚ ó.¥t§>À)— 7J®ò¶M¶"Wv,ð ò{ Ò~|oÄ$ï!½Ü¦ |ñõï˨²ͦBÇÓX¹2á{dåÖÔ ÈåuîæÙÓÜŒ¢±
-åsõ´ÊåÐh?‘«åŒß¥éÂExÜ%8Û5µÃ³ÊóËoÁÒ¨§^RýÏjfrM¿Êí8ÅŽµxà„ˆ;“JÇÒéy.±\Gj×tP6;L` Ÿ6ìRØ#6C+9G÷`Xòñ/+?þ±ÔE²d n`ëæ/F»Ó y³¦s™N520üBoëÂ¥ÕTu¥X³W™ÓeBi¢±¡Ú€™nŒÆÕŠøÉ t¢Ë¨ûCØí ¹Í^„<ß™&ñ2Ý5’­*}¤ô/Šd²FЛØêZÁ
-_Ë£Ý% }\RÖ:èJÞd­ÖX¶d–> /Ä,n’5¸r%£à²ºš–øŸmV$H‘Æql=ˆKZ»(‡ruP÷S™äR“Çчȵc;"+?Ócù†”•!kȼª6´ÊïÓ‡l¥ýá4Ç(A¦†K)-Ý’vÝéÏîÅ‘‚LÿJÊr ÷è½Úƒž ~g°Ç¿2c‘„$St[Ž¼ì“[É]ø³1Vz¶ÞZè
-;Ãü ç%}ïÞœƒØz+qÁÝùŽlß«eÍs… fiølFN…mü*¤þ.dT[?§o;et©øRšoÖXÜ6<¶º¬d׆e€ò7êÈ™s•Ý O<$9þ2f–|‘ÌôåhòWb€*â4’ô²"‹úƒ;Ÿ]gþjÕ9Cjã\£.÷ø͆l2u9æ]¤Á;¯¸@—,ÚìeªiN¬Íslâ—Æ!¤Cù.ø!7¿ÖïMß·HÚaìü¬•ÄAß@ê‹<êÃ5Á† ¼ãmRwi³fÔ-ÂøE^voFÀæ¿ÑþGÚµá¾}NS¿`‚çuOuÇ÷M‹6ü'µÅðÄ—÷‡ÝégþæhmУ÷'Ø'Bß²€½&µ)-¼ü†TUn J»¥‘”`ÔZß© ·?ßWæJj«þ€òãR»ÿ–bà¬þ\k4‡ÓX¨×ÆÕžÝØöå²M²IA>2ží-L¤JËÄÂ~º0¸3y©*¥#fç^ø¢(¦þ˜QËŒ¥m0ò˜&C–òŠˆ\ ‚ ·sTj‡¬A:&Ô¬XõDGi¬x~7ãJ/oìØ Ò—48é®Ì¨¤ðbÍå8m{|gòG—b2m˜êVüoidmçÑñþËÒ6ài;è<ҤϹ‚%lYãÍ¢xÌî—jzÈÙÉuLƒÚu_­\êæ»´åe¿÷|2Du\Ô`ÐTãE»+‡U>|
-RÉ_‚!'zÍ”FøÔ”Vé†u# Žežà º°ÙOLSÀžeúíÖEx!#ãp Ê^0ˆ1üS¸à–lƒîÂC‰«„2í¸Ü}Ýóx(¿à
-ξ.¼ÙúáäãD¾[ÙvÄ›)LH”k€Å!C¼…eHêtrƒ÷I/K‚ Ì'…&‡"Å‚u´ƒø.BˆJ½ÖÉ6Ï<ômJ®b2¢´<zBþ2~[ñ­é6lèͲðÖa.µƒ¶¯í3QÒl¤!…Äv„ÞwURo~ÛF/›õ¿
-há| Ú}ªRdÿýCh4y_¸•TÎçe¼¯€¬Á-á¹bb¹uŸ—±qÙª‡éŸŽœ"Í.5MݧóSÙ6"+0ú"–íÔoF.˜ ±èÖÔÎ’§ȦÛäp
-Ý÷B#?ƒôúT×ϧxß :ÉÜápø»ß­Ó«§ Òµî2Ó­óƒ׌Èð“- „Z°è–¿
- cHì›R¤»°C\qbl
-pïswóH
-kç„¡ºØ-y*ÄmkYÙ>â2š¸’Ë»§
-À§i°~†<T2½Üá’ÂVò9H;·åuH“5sé~t ¼ª\hÝ2ßÀ¦”á ¿
-×hÐ
-ñ"9ŒÖfÓ‰æ hrx¡Î
-zAâ:Û—p¼!™^ŒúvAò£b<±¼«·ÏQždWŒøÍHŠãD*uK*½­:ÉíF~±1`gÇ
-& SºY e H;Hÿ—q¤ðËêXæWiú@ã&kêoÄé"´%ËÚúWÅ;yfÅ
-v«šÌóvI]ô« ;î÷÷¨¸F÷.Ù¢™ÁTÌï„`/ ¸˜˜­Ji‚>S,®#˜”‘Ž—õñMâ‘lL÷Š‹ïŒ®zöœçŸ¥z¯„Ú^Hì»8§jƒ9Ux,§}s'^­V‘Ÿ«¤ñ¾`<@\-ؘãûÄvžN‚ðüìAåqy|ª“™Ç>$’ïÒÍÇH¬ðù·ÆHÄUÇMXá –&£‰.BÍÓTøÐÙ̃DXÂ5ʼ$×Chë¹âG÷ MøÄ‚)¸ÕPk®GSJBc‰%»ÐXê›XÔò‚bcž
-{{~D'ÛûÔ ð.$*>>¿¹1îmÌ›ÿ‰ó(¦Wýbš¥ìl6ÃÅ>-³øªd~R3ù
-|hD +i^Dí£.(€ù«483R£ÁIJ“@¢t)­ü„ÔIm1iM?!+øM{äa÷]¢°A4àƒš$–O}÷™'ä§îÞ¬Ò[{/T|F¸óC}¥Œ±°sH|=OKRe©y”‚«Ÿ>¼O¡ì%œG“)Ä6<¦—rÔ¢þS,ÂHǮڇ‚‰¾Ì&%@¡™~
-øvéç¡ŽŸQ-\~X^Y<.ê /ŠÀ­1F0îñ­ßÀñ¨<ØøùJ]Rî9˜¹t›V¢6[8ýÍÉô½T5é]ý¢âì;÷¨:ÒB¸ájÛÑO7õ\CÉeáÌq.ªš¡èËŠH–»ªÛ©]ïd”Ò+>,ܼ`LšoXGØçv-seSÞd¯W†éɇ۞ 0§H[x— ô…Ì>„^¤ÁvJ• ð@FƒÞ„–ôÿ憉’étŒBžÑ ”ýÕ&!¶¢ªH*Z"¼ñG¦?€Ââ‘Š¬g
-R}¼nÜÎè-xâû1-ÿ;„&Y A½œ¥AçºxýˆK\ëS‡¾¨ b¥nGU/0´J·P›Ò(ïeߢ½œiñž¨Î»È’È g 1ë{"ÀÜ|¨G3+a/Lò·Ù¹–ß2çÓŠ,›»Á¨©âà ½F9¿¿#úSŠoxûCw|g¯óu`¶ªu¤MÔm†² D™×ô—|ë3Ž;Û•êú½W:Ùe¸Ìg-ö(ƒÀkЋ˜®5ü¥ìTlf²¤íiìØMO­3prN]ý
-AAé/«®|ô‡ïm?‡ïŸý±jj2q¾4(æ²Øèð‹zQcaœ
-¾Ôáç†8˜¨±“EH•.¨ü‡ÐFM)ŽC‚†-‹QõYzö?·­l’KÂDŠ¶öŽ·­'÷!QiMùbƒìè÷ÌË¡k †ÜÛö
-ò7ðሳÇW°tò>*4HN˜zú½á0 Ð\ìiüp?ØJ³)Ó'žÐêd<×ê`YæV .-Y#ÈåÜò/¥Ë(ì…ÕqÞÎx6¿ATK,rOÈ Ýœn¨åá¶4)š³m0½¼ˆ.Ó3Ãe¹+Îvûçg¨[ù§r©Ñk]x2ÙèÏ,Rè\žmê,†J ZFFx¾8ŸïÚu¶.!¥^R¿o}ø¶¶Ê—ºNy”ì1€XÑ0× yⳘÄû%
-ý³[r]Ù'‡Ê’œÕV©_jÇÅqÛ4åÁŒ<W‚¼R›û1n‰¦Ã2f¸IÔQˆ”€Z*zN<Ë´žŸ‘—åwçJœ iý$UbõSþh£·S ³ICHÊPbGmû:uÆHR 4ã¦b;‹qgïÉ“X@ý7{Λb~S}~¿ŽfÑØ1«~SŽ úÐŽ›Ò~÷î”ãÏBVù¸dÈZæº4:}Ú35i´¤6W– #úâ ØÜÞqÕ SÕƒªÓm¤`âÛî¥5´ÅO,£0ö‰÷³³Â-ý8É”´4-eÈì•ø²˜§tC5 Õ\Ð-ðb¾—,>¢ð›ÚŠC.Xuÿ ûûÖÑ;exhhÞyvM¢*Š%`d#­˜~Ýi­4Y}Ï
-QhNÐúf.•“"©xÆbä!‹4ö|/8ôë©c©û¨Ö2_Uÿ9NF“¦‘˜8MæÕÁ
-E$Í] 02vL¿1ý©â&ÉwxÝîÆ;|JWF³¡¥Ü_†>)27ê`Ú>µ ½| ëÔ©$@ôƒ
-¢Xo× ¸çœ÷åõ¥|_wùät ø²jšç—¶:âlÁÕ*‚h#²°#Ò”‘g¿s$Hç’gñ&¥n!"ÖÝ3à T¦x›iã×/°…æ÷¥hüiXðꪽ1[„n” ÅT²µÖ·@Q Û’….nŒÈ‡0¶ÇfÆÑ8… ‰Ž
-Ïg•¤ÔÒdkqQÛÓÑW_½æ·¦5ˆÞ°Ä-IL>Ä‹S¶?üD#èU‚¯ð&š¬\ Ãàb‡âÂÐèrÖX[nþ¯L^•S¿Øš1'¢/n–ÂÌò$µën/&glÑiø‡ÖÅæaCÀ^@×é4¾nï¹nIãÊ<÷I‚ŒÕÙzßËž€¤˜Zh‚q‚rŒ±^ZgÇî=D`ÁË¥ƒ†·íl
-úÀžºéâ9Bõ$ÚÀ +¢§0mA®ìR–¨öüBQÀ†9FJÐÔ ²õú ï™´Œ ¯¥µßªñ_['ˆ|zì·UÍcNiØ11žö¨É|Ú~iÔ(ÙRãÿJ T-~=ÝZÁBd´¹³õ(˜ßHK?ÄÍ‚™&Ð=¸LszŒ%:‘W^ßµwk-iéšRoº ÀSKd€{™W_Þm¹°Tk•3*TŒ5õ…ìÐh6¹qºÊœX+¿C²ç¸:ü€2–¿ýåX/ŸD»šÃu Y· ñíwEAM·ôå¡9ÿ®ëŧv[ŒÑ º.h¯l~gfíмiŒiºI&›“~l<´<},n_MWêznÏo{êt ¦™‰!ÞEâ37ÔC)jFC ;> ªÖ“UL¾Û5Ã1.Š§r™v¦zß3¶îŒš8 î‰ük§{°pX2>}íRCçXñÒ@Þ4õT4_d„5wé´9¿ 5ŽoB¹ÐPªúÏ
-Ü ò6éx3¯¡œ)ÐlXÞ:Ø#kõ«!1ÌÍÝÞîv¢[m4ðg¥¸ð«AA07–JîºywÓ½ßñzHM_PQ =#
-àà·ÜÊèëTwAU!¾Í†¦vÆIˆ:#·¿âŠŸ?ò—´ù}’A„rÇ܈ÉL{@½j»<ø!Ñ«ŸÑªjH¶Ëpá• ž¦oHä7oáDžGÀ{{«žT«îÅÒ[Éh‰{Ø]åO]Ø•ýÌ1ù"Õ\³¢Î}Ї)õ»XÎ3«Â4oâ#Ä£Œ´9Ûõ4‰taÊüÔšU­q7Æ6y·ŸXDºoœy§]C¨£zLyX_°ÂÃé¨2ÿhfåϼäo¬E7ƒnÇWvV)(¦Gè¬[ƒHlÊõIÖ§;Z‰‰¥Ë©¾7"M8ßTÏ~«·—.~¥òN^Ël­ÕÞӷ* Iée„ìFòäoÄÍ´]P‹^m5YÀ IƒZ)·O„1™Î艕þC9ëü<M²uZ)j~7KÓ`¯ûH©UÞVn§AlÝcàÜxä 8Sƒ®Kÿ(…g˜ÅîX±BÌÈtç Š"k¯ÊóËx¦ë`0ìDUYâ4·ãÖZÐùº)ØiG/‰—·7Oÿ~÷4û±þ\ŸN:W¨Òs<${ÖZ Ø<¸.ÅN"ýHæuú»Úál‡áådê¼òšhôת¿ñœ‹•ÀÌËýCµïh—œÆ4YV9_fT!c5BHÛ­r8)‰
-µŽqÀ Š¡$è*8 .Ï!~º4?CàAúûsA0¸™£+ÕBÖ;©ÜÞ]z¾š¢¿»ÉO`b¼oðñ@g0æ†õ´O£s2 çÓõ9å
-(ÉóÅ^96µ‡ÆJ#àË¿µ$¬!O¢kÅVÛˆdgúsM\Ý<Ÿ]÷Yj«Òbc½5uÞäß ‡oB­ŽùWKn³íu°eQ4e$¦f¿h2w[·óû²X¶bR…sÿ¼ÃªkVh®$úKFs̵ª+Ñ~ÛÕØ"70ÿ [Ÿ¦ óHÜÍUc×~^;L0š’æ|$|—.ÉuïnJz¬†ƒý9võ-$ÖÆ» ‡£q s%˜¨89I¬’îÃpîf–6ümôSëbçôµDõ±©s"ªÂ|rn«ÉÜñO¾Ö*Ý/†r¦ÛÕÚé±v²÷飋HسÏ*æÅ÷?lÞºƒHÆò"TŒ™?] Æá2ÓéÌسVç’Œý~]ÈÓèFÇ°ž—'è±àhÿ!Vµ˜ƒ¢UJÚ× é.4Ÿ†~•ÜI«Öý‚PˆSRœ…DtÝøÒ¿1v•¡¥&-Ñ+ʘ^Q|Ö>(+3®áИ7—Âgry#ïˆUƈYÀ¶5 DP í´û¸Ñ?‹ZK '¼Œ8±Ç!é‚ÃœiúдÞZí‡Ù€b¾4šÛÆó3ð•Îg£ÆÍNt³d#8g¢¸R&ürzmÔ? ú‰¶ZûX(ŸBßv"Ù­~ìD ãÒú‹;71ÿw°—1dÒÒ~ikcFbY.Õh•/;§pÔÅ[˸ÛAp,-÷ƒ@b!4–mKß$iHR
-„ŠèÄŒ®[1õŠSG›X*£ Ç|ÌonçþÌÎ`mKý‰—5µ°D®Y‡`´W¼ÆÊ;×!søߘïÈöZ1¯È O²­†‹òS6ÌbþÒìu¬í´‹à[,5a„y¬‹ÍæÝ÷§Bc/°½\ix½¿ñälñ`^¡œ" Z$6²ˆ¯µ3îMܦLñ¬ªš%KtÇ$]ˆe#/…¯*µÀ}ÙB\g˜°àYëû ‡ E)F^SZ¡ÁXRP€óæ7•q>Þ"û
-%þ4MG9uÄbÝ{2ŽÐÞá?Ó˜·ñÂO‰t8ÔyÕx…ÇØmÛ‰¸Î@
-»3ç{i›TÔç¿ë b
-4½ÇZj,%·Þ,î§ ˆ¾O²àœ8[°mÍÑ ó„r¹yðUýF]O“/ñúó°6;^dï¾ ê'7zSí2¯N ,Ó$œ’*ÆÐru>‹ÔJ#*»"¦;ˆwá1Ô2nœ@f'=/M`AÕ÷ 9£ fqLwËÛ”Û.„­¶gReЛJZ^
-;U–Vº'¿P@´ò~þ¢:Üi<8ô_¤;µ^D+
-SŠzªÛ'_P èc¦¹8*Mgí)ÿ®O "z¨¿™Œc),ó•S±:…ìÙ‚0U®f„,õMP QOAQ5‰r*Dû-+±E-JñÛ^k z¤î¼.xáeú¶¾£29ÆÀ•hÔ¿ãC\¯¥s‘úõÑ?õrãl×Ý^ŸÇ=s[í²«˜©áfoçô£?=Šß;ò4]·ÓóUµkÁ”^ÚÖfÊÜúìKZ=lÔíÓÅÙ¹¼f${¿ÊvR²ƒVõPhÜÊ¡Û'Í$4‹æb?Ý 0dLù#S&¬JokÒQjº‚õÚ#³½g™ÎÜlZtn›j‚zì(nÐG7€#ð,;YREj¹†D€}«ÿ9RÒ&ñJ4•À° €e͆¶µ…‚œò„ K
-\=c¹²E®¾98wyÖP—Vg••ÄÌÀ÷ æy©é“ÜŠÎf´ÜÄ0pѼ!€Ÿ„üú†z·®Jn%Ë
-âÚ?ÆCÏz| þ±rèou¤¥J¡ð9`º · 5àñ û˜ä9X´É™¶”'÷ºœš¿=ÞrŠ2}òzåÄ0Š„ Ñq9pÉ»ô2|Š¹Ðûö ÆeNαðYÿð6ÒúátŒîîF̶*Dÿ{ÚF°€ÜÛ‹,T’«Mƒi½¢‰UÔ2÷•?Ã\~æ¿9«,¿>Ö~z×ÚÇ›?¼ø1èW?œ,ñQ ¾®Õìñ,¦íÚ_J= 鵬Ôvæi«®Æ ï3
-ßZbÔj­ÿ*»5ÊÁÝtŠc@u¤A®èÂY‰îLœ@º<·Â!SÍX¹
-¡ñÍæ1V|wØÒ½Ý$çþŠ‡J_ùÞ$Sç8e‹‘1wÜ;ËÌ]>-‰D\6©O²mF±÷[¼ü:_­ýúc´ã²&Ò•üC«Ý W
-¼Oíäwx%2Äk¾ýÄS(GQœü|sª\ÏìTäG¡ùƒOJý®Å1‹ñpqw ^¿±›±DdOuüÒ¶?Ü©Àô„í˜;†d×xˆ< ÂÓì‹ño½K­Ê%ÊLœX±[×ÚqA©Aw£-¬î2’5´ª2ŸÌœs°ÒvÔ©BòSº ã†^i:?)Mµuß“U@t®~PÉ#£ÊݤHè…¶eC
-DãäÈ¥1™ÈO¬=1ô'¦9ö‚ã²½m.6Ëš '{`ê¡8à^†ÎD(|s÷éz¡¹¯Gœ1nßNqø‰f*O‘[Ö\Lbî,‡–Íáó±up¹÷ž!º«hÆ8j"cÔóΨڢë¸Sô²—59Ø™
-*Ÿgj.[‹šœ²
-3b\å}šzÓ JÜ\P?­ ±r jx¦ª¿Ñ’=‚N&ýòOj¥ú“÷qxKž9 iPŠ5­Ô¨×#é)y²k˜åñÀ…Ôi¾ ëk'ƒØ™{Ξ`Î숉 {é5züñ-à@¶–bo˜zP«uxÿâ/ëSôê„¢ k¸ÎCSx¤`ŠÇ]ÒdÛÎ’E[”kÏîéÉç[DÁ†8ºÒ’èû¸ŠÇ) á:{W†nî¿°¯ƒ†1eŒ“UÅw°l½ê{\A‡ZcÝZÝø™G!‹–¬Àü¤_›Ö†äW¡Ï*¯ÕŒã›hF &6l‘Gà}8¶ˆÝ×}@Ž<Ç_øÅ%“ï¸:Z›“Œp·¬Ñ¯Ó)rÙÂÕxÊ=BF@èFŠ’|ð!íQT…â›Ë.u9õ±Ê~r
-'|ã2žˆ»Y‘{‚vi6 pQó 9$¦û,ß’ƒäܾpŒnÔóß¼ñúføBó¶:'OÙŸxRF¹²úSÐÊ fH—ñÁjx¤Sân-~uGÚä3®»œàŽ‘?ö6õ–WËqMù.‘RÒ£Ú¢ÔÔI™/2U¶JC~ b>ÑëZ/î°’ž„OAf?aÅ H,O
-áW©²`{£‹)H ÌÊÀ!{eêHÀð™”™V³ü"­)A˜Wô‡ÄgÕÞ}Ï"yþS¯rîªîzZΨnq¦]¢5z>×˹1Eî¸"öˆ=ªæÝ”>ùÀ†·»“÷ á+Öë1ÎjŠÏñLC~Û>ª‚-)0Ö?~AµœŸ"M)@o¢NœCh›çý>^ 6H•ªW¤mE¾ÊÊ(ËôG•LdbHk‰ï»z¶µŒ‰&2Ay”;!LöHs§é GŸ@ËyåG·~Sïýè‘$›„5•¨ÃG¸¦y'¼k/j–Ð@pÓ·Ø ðÆ*Іì ùú…«Éó=à1þì×nLº?ÜåÒ‚©N‹:üâ
-JŽË‹&:ß’nd0‡}2·#^ÚÈíÞAW£Nb_̽Ø¥e»pw'Ö
-Þ¨H,Ò”ž<1ˆ2,ÀÚ1BÞãÍÐœ†‡S\œ‰>ý~Ô±BºÐñNºÊÕ[Îõ½àBh’SÒoëÚcŽôT“ÉÕS?^X1µ^Y1ªfg/'¦gL¹L‚¢TïhŒ£‰HöIùT²=Ï ¼²ÏÊR‡Ø.²-é|ç™LÐs¢íˤ^¯Ë¬d»"EÏ¢Â4¹Ñ®2iÁæþ}oMÄáxéh-¢©Á·˜
-- |™Z¢Æënw(QîkÔ¨å ¯øh§HˆnïBºM}D«õÌVK`­ËÝ ±}]Ê}ë¼Â¤té\40PfÓ­³8<²ÀE ŒºßÏÉV>ÔKsê—ã¹x‡¨Æ^ì‚j6‘e;–Ì3–Šû´^_GÒ5÷£íD;õ?eú5²ãmÑKklÒ§Hƒgn]èB—ïü׊‘ã6ôß.hun?Æö_õ´Yå]»æ°0¬|Îr”±X¬g,©õq€ð¿/(ñ²¸ŠÁ÷ ËÏ~TxËò‚¶¢õ'V±¨½—(°§_û6çȼ® ÕV /ùïñ©0R¦8«K#K¥¹©ÑN»b¼ H'ÎÙE³ÖúŽ=¨)Ø´=ð7Ã!eÈr%­mái¤]“ðj&#‘LñCwµ"íˆø?w-¢…8/ ,d?œ3Ü9TpfR„ †\½Ò©GEÊÄàšz”õqMÌ_ö«6‰*›¬‹øŸ7sÇ$ÁG¡_îamï~¬)ÎÞÓÀÚ0¶»?­Z«Lf1v«|̉TÇ®27T 0$È‘–-ç3¦’„y!=lpn2^÷'z½;í§§LTÞÔî,¦ý˜ê4ºöŸŠ\Ç_†+˜æñÖDˆ§ã58ÿà
-³úöèÓÒúáBå«
-cô|æ'`ÎÄS%Q 2ÃÜ &aÔð†Ó²YŒ½ ò…ûów‘Ž?£x…–Öê"WÛüy36h?¬‡jø^²iJkӮ߇ÕÆLgøÿ_;sþÏ„
-»»yÇ&Ķ1òþ‡ókÄCÆ)aº„íájÏ1¼AøZ
-U¢´’™…ç"óWÇ ¿NãÐhŸgÈ –6¢À¡yX¬{fÜL:’Õ ³kÔ6n›'±u •Ÿ$E—Ò9ls+ª; ’†hNÍ2Ápƒoc&úFåÖÍ„Ì­‘P!
-aÏOB&Ã~€Y°R0ˆ3¦ë+*Z–ä:_7‘ßÛ¿ 8ò~Bî¶Þúfë¾Ã2ˆ 1ý´óèhc4|yC¤1à”eP¥(¡†ûuF#õ`?wÜ<Œ•Ag ÏÙÔf
-“ü½óMìcFæ/.ˆ›'A!¯™•Û[Q M£ð+hú#¾,¹¡.a£à#_°FÜÝ™rÍ”®Q‡læ tD³ÁoF•}àº}l£Iâ¼Ò›Ëñ UÝU>DM¦
-‘íð]ukëßXâMå•#Ó`[ÛÑš^×/D­Ò6bÊŒçJÝÉr1¢ [)´‚i×àçÝc즭qˆˆfÖ¤<ÇÜ`Kå·I#-X ïò6‘5¾ÍÜíÖÙ1A˸?º—þ~¿Ö!¿©‹]Êmn!ÚyA{A]
-Õ¬²ãÎ]­¨€¢¦ b<Åwù.©D<ãçáĈ:Ïe]¿8%âÜY›>¸ØÚ¹8Èùß—’¿ï#6{†ç"L’îX¤¯ßî¹"V»³ãGZe &¿3óu_9û_fû^nlê
-R ‹Ï¡ev,;è+c$?  âÍ{µázÊ*¯ì>èD5É'_›oa9Iyî¨áÆFÜæk$Uj‚×À$ì‰áÉRJDµ=%¤¥Z¥³Í’fLãŽaíORŠ>’|„AÝŸ…®Å©Tï Ⱥ៱ JòÊx €dUº|O¶ÖO±Ñ;~·”´ô¾Þ–]ÂÁQs\Íâ¤^Gš‡Rh÷8ú/‰ýü'¿
+FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF
+Ð÷ª-KCºæì¢]•ß@e›‡á±Í R©e7ãÝ8æ¥X¼Ý ú^¯bª¿fiWã¦Ç6hé("ôæ?ü…$ØVS̓÷â¹-Àõæ}DJš2½œœ$~T’D™ˆ‡…:Nq®ó#5ßì" 󧈼ˆÎQჶL–­Èµðc“Êç؉/WöýîŸX2ŸÈÈðxª©-“[¿F7žsWÆ{4B
+pÇ€úâLV›‰¨ÛE°¼õ`K«Vá½Öž\ºÍªk:K?>1ÁÆy9ãd™5 @P2ƒ÷Í°]öþ6Í(9Ð`®¦ ~ Ì¢ß +¹9y´Æ¢]’ˆåþJ¿*ú¨ gÒöK“]?e’CÌ(m
+D\ïN¤Ô´|˜Ǧ¡‹Uf¥—øŒÉïÀúÒáè
+ûÙ £)¨Ž&‹"º–Qª86Æ…‡â9xV6jƒxlˆÊù†º’2–^ù
+|Ò Ä;c g¯lt_´û•jP°– ¼ãT³mê=-ŽÙ
+ ËÖ /¨é?&§ Ã­¤oø
+%Ñ]µÃ³V‹Éµ‡†#hižrX£2¾K±²Å?²©Ç‹t3V<«×üHl'}µ“œ7ÂnhJ권buKÉ)O^Œ Z5‰OßöÚÖ?ý<ÿs88z™l­; %ÔVæ ËŒõ”ððßEôÌH«íjÚ ~öÖ´Öb}ë­MùñÍê+GÝq’Yµ£[N¢+C1¸Ë¯ö
+RÚ8Ýw>SÓ¯S®A˜Ç©ó-×;%¾À˜úe
+ß$TAÂrü—ÇDUËx,¬mCFË„vh”V¬èæÝod%·Ýͼc‹ò¡R´©kð97Aa¸ö<ër Ñ¿5{ßîRÖÀª—Öì
+(ÙóŸAuÂ)¡¦HŸÞ OØV";M¸’…ܶRýd°2auÒ/3ߘ–¿AjqBGÎÓÙ1\æ›+>€y¥&0•²jmÚqý[„ìÑL6Qb~´+¹PÄ-sÙø¿µ$ÈÑ*ªï ¥ ðÈOÓ…¦JûèY[éýSækŒ¹©[üm}ÿ˜Ð6L÷èO³[²ò½¼ƒëÆÐNOp:„ùHïä7CĬ“ü]½yî´¶ïïÃ>Õ“·aý'×M½®qê äîbà_w– ž]4ðÚÀˆ²öÒøÞó¬n +: § Ìô 8û›cÑJR[2£mXÅw‹}y7ˆ×ÅLeD$ç,?Yh{³ÛÆBÅΙki¿ŽøК¿ Ø1ò°ºŸ;eó‚T›n|˜)94µ9uæÐ¥x´ ƒã½R
+>ç³]æoM%„£¬ÎG)³‘4°ký‡ïbZ~ø ¼`_[hã»8ë<¾4²}$.îÁ³Ö
+Œ(iýŽà-º 7~õSLcüýkÅ!.0Yü:7— `hPêoˆÜä¦ójÂlƒG¥v‚j»8Ç«Á¨›ÕäÅÆ6nÂN'éú3ÑX®ÐH¨Ïü%›zl½ ýƒ©´
+)‡¿ ÕÖÏéÛNÄD]*¾ÔŸæ›õ· ­‡.kÙõ£a ü:ræ\e·ûá&ÈÉDŽ¿Œ™%_$$3}9šü• Š8$½¬€È¢þàÎg×™„¿ZuÎÚ8רË=~³a#›L]gŽyiðÎ+.ÐÇå‹6{™jšSksÀ›ø¥qéD¾ ~Èͯõ{Ó·Æm'¤v;?«A%qÐ7ú"úpM°!(ïx[„Ô]Ä,…u‹0~‘—Ý›°ùot…ÿ‘vm¸oŸÓÔ/˜àyÝSÝñ}Ó"‡ÍÿImñ@ü
+åÚ`qÈoa’:Üà}ÒË’àóI¡ Å¡H±`í ¾‹¢R¯u²Í3}›’«˜Œ(-ž ŒßD<Akº z³,¼u˜Kí mÇkûL”4iH!±¡wÅE•Ô›ß¶ÑËf½Ä¯Z8_‚vŸªÙÿMÞW'n%Õ‡óyï+ kpKx®˜XnÝÅçel\¶êaºÆ§#§ˆA³K ES÷éüT¶È
+Œ¾ˆeD;õ›‘ æB,º„5µ³äé
+IEVx[i©ó•û MCá–‚C÷=…ÐÈÏ ½~ÀÕõó)Þ7ƒNòw8>Çîwëôêé‚t­»Ìt«Ã<EÀ ‚†Å5#²üd ¡,º%¯BBç;¦é.lãWœ›ÜûÜÝ<’ÂÚ9a¨Äƒ.vKž
+q›ÅßZV¶¸Œ&®äò®Å©ði¬Ÿa•ÌF/wø†¤°•|ÒÎmyÒd`Í\º¯*ÚßDw§Ìw °)eG8ïÂ5´B¼Hc†µÙt¢ùš^¨3€6ŸoÈ:W¦ z´˜˜éÁéä’*ëÔ£Ÿ@îàâp¯_© ¥ì%Šcga>¯W¹4#UâRwXPƯY“4ìg·FRß vßû<ÔxP>†uÂËe&+
+Dì2Çüߢ¿¢‚IÔnèEYÒÒÇe)ü²:V ùUš>иɚúq:…mɲ¶þUñNžY±B§Ýêƒ&³Ã¼]Rý*ÃŽûý=*n…ѽKv„hf0ó;!ØÅ .&f«RÚ„ Ï‹ë&e¤ãe}|“x$Ó½ââ;£kgž=çyÅg©Þ+a…¶’û.Î)†Ú`NËiߜʼnW«Uäç*i¼/W 6æø>±§“ <?;dPy\Ÿêd汉ä»tóñ#+|þ­1qÕqVø‚¥Éh¢‹P³Á4>t6ó –p2/ÉõÚzî„øÑ=h>±`
+n5TÁšëÑ”’ÐX"GEÉ.4–ú&µ¼ ØØ…'Àú|€PÜLêar ¾0N1fo÷í¼Á¶Uå" ‹*0âù$]s¨>ÓΆ”'â¾ÞÑØèÝf6qì©)¡}mZ€šÍûIÄN§
+Îþ@PD # V{¿Ö%þVõ|3ùÈ”JE3)&Níð{_’ Ê m3™Î1 oåñ S“•/bì~O«¸8/*™Œ²éëíZφä(.Pÿ§žÏdÔö¤¾X<é§îrî9YJÛ)E抰z6Ø/v0 ¡ ªD °¾T㹋˜€7ýP“Ú¡ûµ¿^¶û°iDØF…ṳ̈9Ô\ðØDˆ“Ï%Ë;¥Ø—qëŒà2ß œNý.¶8bWÉI0Uy®ƒÎÈfPw³‘ Õ8ŒÌ" Çsäs
+ZmØFÐÃʶÞïPhzI÷™ð€*qaBrÒ·Ø^ðƒMâÝàí-Õ¨ô¡À˜å®™ÂÞžÑÉö>u¼ ‰ŠÏãonŒ{óæâ<ŠéU¿˜f);›Íp±OË,¾†ª™ŸÔL~‡(ÂJšW
+`þ* ÎŒÔÀh0±ì$(]J+?!uR[LGÓOÁ
+>DGÓyØ}—(l ø &‰åSß}fÄ †ù©»7«ôÖÞ •ŸÑ;!)îüP_©cEìì_Ï“Á’TYj¥àê§ïS({ çÑd
+± éÇ¥µ¨ÿ‹0Ò±«ö¡`¢/³I Ph¦€ZhtDįcÅxBkô¹õ¾z힢Uˆ1áû-C^­î@\’ž¶Ê#f„†µ]òOÍÕ5 Ñôh‚˜CGÚc(hƼ<@žðŒe/ºˆ¾]úyèŸãgT —–B„W‹:ƒÅ‹"p+EŒŒûE|ë7p<*6~¾R—”{N f.]Æ&‡•è…MÀNsr'=d/UMzW¿¨8ûÎ=ªŽ´n¸ÚvDôÓM=×ArY8sœ‹ªf(ú²"’å®êvj×;¥ôŠË7/“æÖö¹]Ë\Ù”7Ùë•azgòá¶gÌ)RàÞ%H}!³¡i°Re<Ñ 7¡%ý¿¹a¢d:£gteµIˆ­¨*’
+‡–oü‘éO' °xd"뙂T¯·3z ^‡ø~LËÿ¡IÖBcP/giй.^ÿâ×úÔ¡/jƒX©ÛQÕ ­€ÒÆ-Ô¦4Ê{Ù·hïgZ¼'ªF§ó.²$2ÈÙB Æúž07êÅÌJFØ “|Àmv®å·Ìù´"Ëæn0jª8xB¯QÎïïˆþ”âÞþÐßÙ«À|˜­jiu›¡lQæ5ý%ßzÅŒãÎv¥ú…>GïÀ•Nv.óY‹=Šð ðô"¦k ¿E)û›™,$i{;vÓSë œ†œSW¿BPPúËj…+ýá{ÛÏáûg¬ššLœ/
+¹,6:üâƒ^ÔX'€å9U¿œ‹fkM6¼¿tî˜è^‚(Ò2g¡I›yÕ²˜RôÓ(.ãcÃÿBM¶SaÓv¨‚/uø¹!&jìdR¥ *ÿ!´BSJ‡ã !DË¢FT=B–žýÏm+›ä’…0Ñ
+ ’¦ž~o8LÃć4»DÜ϶ÒlÊô‰'´:Y'ϵ:X–¹ȃKKÖr97…ü dé2
+{¡„Fuœ·3žÍÇoÕ‹Ü2C7§jy¸-Í@Šæ,dL//¢„KàôÌ°FYîÊ„³Ýþ9Å™
+*–÷oz ×PýÚúŽÇä–G”30¢ ò ¡€?Žê)^¿)’£Êw8:B-sìFDò±û¹Õ.¯ýaËmwñ¶ÀBUôz8sš3&¥JÎ|ñ$¡9ê
+¿’ƒ½[žBš´¾™Kåd H*ž±yÈ"ýƒß ýzêXê>ªµÌWÕŽ“Ѥi$&N“yu°BIsŒŒÓoLª¸IòD·»ñŸ’ÆãÇ•ÑlèE)÷—¡OŠÌ:˜¶O-h/_cÂ:u* ý ‚(ÖÛõî9ç}y}F)ß×]>9]¾¬šæù%†­Ž8[pµŠ Úˆììˆ4eAäÙoÀÄÜ# Ò¹äY¼I©[ˆˆu÷Ìp•)ÁæDÚøõ l¡ù})¼ºjoÌa %h1•l­õíP”Eöd¡‹#ò!Œí±Y‡q4NaB¢#@÷3ÁÜ´*ìåFÖ‡ù–[>¼üózëþ2‰ØMÌDn…Þ ÜwKØ¢Y(i£X‹ßüƒd¤ú9ò ¯L,ÿì“^^ñëàö­ÂóY%)µ4ÙZ\ÔötôÕW¯ù­i ¢7,qK“ñâ”-Ç?ÑúE@•àë#¼‰&+ƒÄ0¸Ø¡¸04ºœ5Ö–›ÿë“WåÔ/¶fLƉèß‹›¥0³<IíºÛ‹ÉÄ[t>Å¡u±yØ°Ðu:¯Û{®[’ĸ2Ï}’ cu¶Þ÷²' )¦Z`‡`\… c¬—ÖÙ±{OÑØD°Çré ám;€¸LÐl} JÜ„Ž6 ‘nþ‹‚>°§nºxŽPc=‰6pÊè)L[‡+»†%ª}'¿P°aŽ‘45¨lG½>(ÅûE&-#Èkií·jEüÅ×Ö "ŸûmUó˜SvL „„§=ªA2Ÿ¶_5J¶Ôø¿ÒU‹‡_O·V°mîl=
+æ7ÒÁÒq3‚`¦ t.Ó„c‰Nä•×wíÝZKGº¦Ô›.(ðÔà^æÕ—w[.,ÕZåŒ
+cGM}!;4šÍCnœ®2'ÖÊïìù®? Œå¯@9ÖË'Ñ®æp]CÖ-C¼Dû]QPÓ-}yhÎëzqã©Ýcô‚®ËÚ+›ß™A;tocšn’Éæ¤-O‹ÛÃWÓ•ºžÛóÛž:]‚é#Â_fbÈ°g‘øÌÇ õPŠ€Ú†ÑPÅŽO£ªõdU “ï6dÍpŒ‹bçÆ©\¦©Þ÷Œ­;£&{"ÿÚé,–ŒO_»ÔÇÐ9V¼47M=ÍaÍ]:mÎïGAã›P.4”ªþ3€ãd—&•É–è*HfÅ„÷‚¼M:ÞÌk(g
+4–·öÈZýjH sóG··»èV üY).üjcPÌ¥’»nÞÝtïw¼RÓTÔBÇ
+ŠéÑ:kÅÖ ›r}’õéŽVbbérªïHÎ7Õã³ßêí¥‹_©¼“×2[ëAõ°çô­JCRz!»‘<ùq3mÔ¢W[M0hÒ VÊíaL¦3zb¥ÿÐCNãú?O“lVŠšßÍÒ4Øë>Rj•·•ÛéD[÷87ž
+vÚÑKâåÅíÍÓ¿½Í~¬?קS§ÎªôÉžµè6.¤K±“H?R‡yþnv8Âax9™:¯¼&ýµêo<çßb%ðórÿDí;Ú%§1M–UΗUÈÁXÒ6G«NJ"€Ùíì£â%Àì”w¶ðtý—_7×¾`!—
+;ÜÆŠF¸*Cb&Znf]C¡ÈN‹×6Á.þÂÑ, èW91£ðà«iK;m+úbTèSpïGsÊuÊkÏ&ALH^Ö™FV{ð$ ÝkúÝMbxáñå6ÿa˜ƒØÅYå›a¹5°þ¦J0Ëšëö“©¾é™ý¡
+Ó†©"S—Ïz_¥¬Sþ@Î lÀ£ì†D/®¨÷þ¹B­c0ˆb( º
+ƒËsˆŸ.ÍÏxP£þþ\ næèJµõN*·ƒ7A—^…¯f£èïnò˜Øc#ï|<ÐŒ¹a=íÂèœL¹Çt}N9@œí2ò“º¬ð;ŒÔ’`Ÿš瘓gÛ–» “(kw“Hˆ«fz# ü«TU5aQW.;ì§øtÁTK!bñ6Û¨Ú±A2®Èü„è-£þ|âáŒMÍU5j2~áúˆ^]i‘åe-·¨^žÿWeoÙ~äèžÞÊ„×Cô®ïw= ý² {ì}Åï÷šNå)àÒ„½\Š*‹Jò|±WŽMí¡±Òøòo- kÈ“èZ±Õ6"Ù™þ\W7ϧGÂ}VÁc§Úª4ØXoM7ùwÂá›P«cþÕ’Ûl{lY B‰©Ù/šÌÝÖíü¾ì–­˜T¡ÁÜ?ï°êšš+‰¾Å’Ñs­êŠGô†äv5¶ÈÍÌ?ÈÖ§éBÄ<wsÕÆصŸ×ŒD¦¤9 ߥKòã_Ý»›’«á`Ž]} ‰µñnÃáhDÜÀÂ\É&*NNk…¤û0œ†»™¥ ›ýÔº˜Å9}­Q}lêœDª0ŸœÛj2wü“¯µJ÷‹¡œéÃvµvz¬,Æ}úè"öìijƒŠyñý›·î ’±¼cæOˆq¸Ìpãd:3ö¬Õ¹$c¿_W#ò4ºÑ1¬ç¥†Á z,8ÚÈÕD-æ h•’ö5Cº ͧáƒ_%wÒªu¿ â#¤Ç”g!]7¾ô/BŒ]eh©IKôŠ2¦WTŸuÊÊŒk84æÍ¥0Ç‚AÞÈ;b•1b°mÍH;í>nôÏ¢ÖR /#NìqHºà0gÚ…>tí°§Vûa¶ ˜/æöŸñü |¥sçYà¨q³Ý,ÙŽÆ™(®” ¿œ^õÏ‚~¢­Ö>ʧÐÃwHv«;ø´þâÎMÌÿ$ìe ™´´_ÚژтX–KµÆ
+Ú…W¨•fI•M@ï±–KÉ­7‹û)Cc¢ïS`…,8'Îl[stÂ<¡\nc<BU¿Q×ÓãäKüŸþ<¬ÍŽÙ»¯ÅƒúÉM€^ÆÃT»Ì«ÓË4 §¤Š1´\Ï"µÒˆÊ®ˆéâ]x µŒ'ƃÙIÏKXPõ}BÎè‚YÓÝ2Ä6å¶ a«í™TÙÀô&†’–Àiû‰Ÿº¾îpÆ4
+~[ØÝñ°Lå ¸ ¡©Ûa¨Ë=‘yÿn¬%YçYt½¿Ëú7R¬lN%mÄQ$: QŒ²›DµØ†È¨Ð¬)¦ÃºÊìH%Ûß ^>«¡T&8Ñew‹¹ƒã'}'ÅrW÷ ŸMì7#X1nfœ÷ ~¸ŒÓ2Û*¡U§ %›ˆÁÇ:èDMÂ|Ò.Ž«ªˆàc:š®)IËü*ŠÎ¿žê³Â:
+ºâreA5n!Ñ…êì]Œ¨ÁºØ»‚õOWìõHƒ:Ô…—‡uÀÏk2Q:ú†Édf¬š¢ µ‡$EÏÐï8f±æ™€âNØÔ@Gœ¹}\=ñõ°¨öˆ¨‹¼_W/nÀÄbÛíÿ¸¯ß0^8U¤>¾û=O?°g›¾U̧[aý;óþÓSX¦ä”gÚLÁ´·¹‹.võ@/Ò&ÿ”i:dÏk0G£u¨ð“rÏBž7gO‚w üúàü•–”À‰KY&j øœ7¼r 2–á°WNÎxëh“õÒ¿Í7§LŽ„×VC@]ÒÖóºÁ*óë-Å ÃA;}üvñïiCU…—.úZl¬ õå?²ŠcHÕ¸´Ôu½ö!» »†ó±œW‚Ñ/ðó\Hvq•bf€úOÕy3¹;¾Ð¤ ² ÜŒ°š'ÿˆêIܯE|Ÿ¹ š­p:ÔC9èc
+gŽ}“ú£qÍòÛ¨ù›ÂN•¥•îÉ/­„¼Ÿ¿¨ÎwýéN­ъ”⃞êöÉ(ú˜i.ŽJÓY{Ê…ë߃ˆêo&ãX
+Ë|åT¬N!{¶ L•„«a` K=ETBÔSEÐATMb§œ
+Q‡Æ~ËJlQ‹Rü¶×ZB§©{g¯ ^x™‡¾m€ï¨LŽ1p%õïø×ké\¤~}ôO½Ü8Ûu·×çqÏÜV»ì*æGj¸ÙÛ9ýèOâ÷Ž<M×mÆô|UíZ0¥—¶µ™r'·>û’VuûtñCv.¯ÉÞ¯²”ì U=Ú·rèöI3 Í¢¹ØO7( S~ãÈ”‡ «ÒÛšt”š®`½öÈl/ÅY¦37›„Û¦š ;ŠôÑ à<‹ÆN–T‘Z.!`ßêã…”´I¼M%0,(`Y³¡mm¡ §<!È’WÏX®l‘«oÎFž5Ô¥ÕÂYe%13ð}‡yBjú$·¢³-71 \4oà'!¿¾¡Þ­«’[É2@2´F´‚ø„ö€ñг…ǬÜÄ#ºÅ[i©R(|˜.Èm‚F x¼HÃ>&ymr¦-åɽ.§æo·œ¢ŒEŸ¼B91Œâƒ!ÈD4B\\ò.½ Ÿ†‡b.ô¾=ƒq™“s,|Ö?¼´~8£»»³­
+Ñÿž¶l ÷ö" •äjÓ`Zo…hbµÌ}åÏ0—ŸùoÎ*˯µŸÞµöñæ/~ úÕ'Kü@Tƒ¯k5{<‹i»ö—ROBz@-+µyÚª«1èûŒÂ·–µZë¿ÊnòEp7âPi«ú€pV¢;g.Oã­pÈTA3V.ÀÙòV…I’]UAÍÊ&¯æwú{¥,¿f
+ý’OP\h{†!Ë/:9*ÁþNª‘À„y†Ý¢›¼~¸®<rÍ¥Ø.k¹áR\ÄKÀõ=™Ê³ô¤µéšàš)É 
+Ìó¬¤^©êzX-Ta’•éÔUÚjLØ–‡ÁPϲ ‘ Ú €,j%‚‹Bè_|³yŒß]¶to7ɹ¿"Á¡ÒW¾7ÉÔ9NÙbdÌ÷Î2s—O‹D"—MêÓ†l›Ñc,Å=Æ/¿ÎWDk¿þ-ţø¬‰tF%ÿÐjwÕïS;ù^É£ ñšo?ñ
+ÆQ'?ßœ†*×3;ùQhþà“R¿«A±FÌb<\gÜÝ@ƒ×oìfg,ÙS¿´íw*0=a{ æŽ!Ù5"OBŃð4ûbü[ïR«r‰2Ó'VìÖĵv\PjÐÝh «»Œd ­ªÌ'3çÜŸ¬ô£uªü”.ø¡×cšÎO
+DSmÝ÷dU«TòȨr7)z¡mYÅÀX˜Ä5ê¦[Ø÷ËÅŸ"f ‰@êéqD„ç™Õ'~ñHA[€‹Vû¤“õ^C
+ݓ׀-xú€°šNce<Pdc–0`RôA˜‹¬ß”™…r8HXÞú§Ó•~ «÷®tOý08em_¦;nÒB0ÕüYÂð-'y©_‰ôÛº@Á=¬È*ÃE\ŽKδ¿ÅÿØÙ½/™‰HíMâÑÁ8g7m‘ÿ{<Q-u·´å´_;M;S1Dá[ñ7;žŒØ‚†ò”ÎD!m÷í¯`èhpÚh16jä¬Ö’ØŸ¸*¿v/¯`%–ëekáÍ?LhÎ=”v‹…}éƒíý8ÔµÑ89riL&òëcO ý‰„iŽý†àÁ¸¬Go›‹Í²fÂɘz(¸—¡3
+ßÜ}º^hîëgŒÛ·S~¢Y 
+ÄSä–5“˜{'Ë¡esøücl\î½gˆî*š1ŽšÈõ¼3ª¶è:ÃegMvc¦‚Ê癚ËÖ¢&§,€íIš®Ø1¤¯à
+©*É&;jDú`çsÞ#)„Ê4s‡oEcà &ßÙIÉ;qÝ#K¸n›å¯ý´Y|”àŒmãø•6ŒÊÑé>Ÿ[å˥ߺŽ1½é˜Ê®aYÝ«ÀF5PYåaÉ|3ãä¡ïbøM@©Nyav.åh­nî×ņ®ô²¡RŠÅ—ȬŒWyŸ¦Þtƒ7×ÔÀOkB¬œC@ƒž©êo´dÏ “I¿ü“Z©þä}\žÅ’gÎBT…bM+5êõHzJžìfy<p!uš/ÃúZÇÉ vc&Bãž³'˜3{âC"Ã^z| 8m§¥ØÛ#¦ÔjÞ¿øËú½:¡(Èn‡óÐ)˜âq—4Ù¶³dÑåÚ³;AúGòùVQ°!‡®´$ú>®âq
+C¸ÎÞ•¡‡›û/ìë aLãdU±Å,[g¯úWСÖX·V7~æQÈ¢%+ð?éצµ!ùUè³Êk5ãø&Z£Q‚É [äxŽ-b÷uP…#Ïñ¾†E@qIÀ$ä;®ŽVçæ$#ÜíkôëtJ€\¶p5žr„º‘¢€$|H{U¡øæòƒK]N}¬ò†Ÿ€E×D°
+FÏ-¶ 6© †Â ߸ŒçânVä^… ]šMg\Ô<C‰é>KÇ·ä 9·/£‡õü7o¼¾¾Ð¼­ÎÉSö'ž”Q®¬þ´òB†‡Òe|°ià”¸[‹_Ý‘†6ùŒë.'¸cä½M½åÕr\S>‚K䃔t§C稶h5uREæ‹LU§­Òƒ˜Oôz VÇ‹;¬¤'áS™ÇOXñË€¿®›¦™;µWEƒeÔ #:0츜BøUª,ØÞèb
+Òó…2pÈ^Ù†:0|&e¦Õ,?‚HFkJæU'ý!qÆYµwß³HžÿÔ«œ;…ª»ž–3ª[œé@—hžÏuãrnL‘;®ˆ=bªy7¥E>°áíîä=HøŠõzŒ³šâs|Ó߶ª`KA
+Œõ_P-ç'„HS
+Л¨'ÁÚæãy¿ˆ Re†êi[‘¯²2Ê2ýQ%™ÒZâû®žm-c¢‰LPe³o“=ÒÜi:èÑ'Ðr^ùÑ­ßÔ{?z$É&aM%*Æð®iÞ ïÚ‹š%4Üôí#6¼±
+´!;h¾þGáÁj2Á|O¸D ‡?ûµ“îw¹´`ªÓ¢¿¸‚’cçÅò¢†‰‡Î·¤ÌaŸŒÄÆ툗62A»wÆÕ(†“Øs/A'viÙ.Ü]Á‰µ‚7*‹4¥'O ¢ °vŒ÷øF34§¡Æág¢O¿u¬.t¼“®rõ–s}/¸šä”ôÛºö˜#=ÕdrõÔVL­WVŒªÙÄKã‰éS.“ (Õ;ãh"’€}R>•lÏs¯ì³²Ô!¶‹lAËE:ßy&ôœh»Æ2©×Äë2+Ù®HѳÁŸ¨0An´ë‡Lš@°ƒy‡ß[q8^:ZËÄc hjð-¦B _¦–¨ñº€ÛJT§ûš5j9È«>Ú)¢Û»nSÑj=³ÕXër÷Hl_—rß:¯0)]F: ”Ùtë,,pQ£î÷s²•õÒœúåx.Þ!ª±…» šMdÙŽ%󌥢À>­×בtÍýh;ÑN}ÅO™~ìx[ôÒ[ ô)Ò`Ç™[z€Ð¥Ç;ÿµbä¸ ý· ZÛ±ýW=mVùD×®9, «Ÿ³e,ëKj}Ü üï J¼,®bðýÂò3Þ2¼ ­h=Á‰U,jï%
+ìé×¾ Ä92¯kƒG`µÕÂKþ{|*Œ”)ÎêÒˆÁÄRéAîCêD´Ó®ïÒ‰svѬµ>cj
+6müÍpHr£\Ik[xi×$¼šÉH$S<ÂÐ]­H;"þÏ] …h!ÎK Ùç wœÙƒaƒ!Wo§têQ‘21¸¦e}œDó—ýªM¢Ê&ëÅ"þçÍÜ1IpÅQè—{ØAÛ»kJ‡³÷4°6ŒíîO«Ö*“YŒÝ*³A"Õ±«Ì Õ r¤eKãùŒ©$a^Hœ›Œ×ý‰ÞFïNûé)•7µ»‹i?¦: ¤®ý§"×ñ—á
+¦y¼5âéx Î?8€†,ÄÙ%š¼ø*%q$GÐ]È%\íðÀ¸¯±ÆLÆø¤z*­Ë"7›U0ž$¥¨ ×”€ïøq*櫸×\~ghL[ü ¢rñY{âkây9‘ä¹_­-¡„­“ߣ|ÒœZ¿€ë˜û.†zžÜbé><ZwúµžËtÄw/*‘ê}5Tö4[Ï*ùaÅ6y¡W;åRÊØŸ7¦½jJAºjæ”ÅhÜU–Fî¦|ð¥Ûê:]Ù+ärå’ß±¯µíju:Ûdí>1aNÓßø–à—ÒK!5hI¾?K3²< áŸ,ÞÅÁ¸²Ü$j:=úzåmÈ_N4ƒ˜Fäûq
+°’胱«T«þÃ5jíaƒ"¯‹¬Î×Эô'7kˆ]ú†A§òuSà‰epÀƒZ˜%ÆÅ…¹­Â¬¾=úð¤´~¸Pù*€üÕÝ+àŒVd˜¥ódqɈÎEX—dÓJHÁ+°:ƒÊ}Ð)#ôø@ײ!R»ÿ©€£ì–ù
+;\ùˆ¹¥e7ÍHÖx³¡l½ [sÉHù[êƒáëXôËUNÑõ¢i X–Ø«c4ë7û\Aº0«<{ Evg]8xp[lZщ5õè¹r÷ûGâÈm*Nêê:Q+|‡gµ}ÁÞ\d„äO¾>hžDä¡GXnöº +b¸¬óÇ;½<nõ ÄߺƶrEiO8võÞH•kö}aq²2ß5|LÇŽ´Fa
+ÐQk|/Û9¾ÑxÜÜúÙP7˜ªl©¼å© 敱<ý6œÍ¶Â=Ÿù …3ñTI‡@TƒÌ07ƒI`5¼áô‡lcoƒ|áþü]¤ãÏ(^¡¥µºÈÕ6ÿCÞŒ Ú롾—lšÒÚ´ë÷aµ1Óþÿ×Îœÿ3¡
+šþˆ/KnèEKØ(xÆÈìƒww¦\3¥kÔ!›ùÑÆlð›Qe8‚nÛh’8¯tãær|BUw•Q“)€gÏ£ŽWºè¥@Pñ„¥¾‡LZð7×(fÐlç9¬Œ bf r·Ñá·šPæ}p
+øš*›íßyýá“ãûB/1;Aì2ÕÙ3ÕSs±‘woÃñÕ“VÝÝíßv¼¯å¹ÜÆ{¯’XcÇú9'*:ÞÒˆVÂ)BSzŠ)Xý_ƒÓŠÖpm{§z¼¸—±u±)ôc¹ÿÕ)€+H2Qi·'Âڱ׉×b@akÊE¿¢vÉÃBakR‡å:›ñ†‡Fˆ~¨êÈ’Ìm®g4šv~\œI©¸
+^ýì¶<[7Û-ú%çq´Å5mââËÊž¶t“Bdc;|WÝÚú7–xSyåÈ4ØÇÖv´¦×Åõ Q«´˜„2ã¹Rwr\Œ¨ÇÂCÀVD
+­`Ú5øy÷»é@k"¢™5)Ï1·ØRù-DÒH Ö»¼ÍDdM†o3w»5Gv`LÐ2îä¯uÈoêb—r›[ˆv^Ð^P€ó]üQ¨‹ÔS^?¨Ïóè_û³£ 'C2T5ÍyÅ [<;ËÛÜ}‹hLé4mMmÖéҎ/À}"ÑçB0%’éVE~µb(e’ ”峕UòïiN“ýië€ëÜ„{X#Œ=dÓ[娽 ÿÆOƒHð”£Vê ªëvGJMGÚêåÄLX^9ymiZPpù˜B5«¬Âø#…sW+* ¨)¨OñD¾Ë_*Ïøy81¢ÎsY×/NI„8wÖ¦.¶v.rþ÷¥äïûˆÍžá¹ˆ“¤;éë7¤{®ÈEÕîÄìø‘VYƒÉïÌ|ÝWN`ÄþÅW‡Ù¾—›º‚ÔÂâsh™ËúÊIÆ(ˆxó^m¸ƒž²Ê+»O':QGrçÉ×æ[XFRž;j¸±·ùI•šà5A
endobj
-950 0 obj <<
+955 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 34
/LastChar 125
-/Widths 2131 0 R
-/BaseFont /EUDNXE+NimbusMonL-Bold
-/FontDescriptor 948 0 R
+/Widths 2153 0 R
+/BaseFont /OCIZJD+NimbusMonL-Bold
+/FontDescriptor 953 0 R
>> endobj
-948 0 obj <<
+953 0 obj <<
/Ascent 624
/CapHeight 552
/Descent -126
-/FontName /EUDNXE+NimbusMonL-Bold
+/FontName /OCIZJD+NimbusMonL-Bold
/ItalicAngle 0
/StemV 101
/XHeight 439
/FontBBox [-43 -278 681 871]
/Flags 4
/CharSet (/quotedbl/numbersign/plus/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/semicolon/equal/at/A/B/C/D/E/F/G/H/I/K/M/N/O/R/S/T/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright)
-/FontFile 949 0 R
+/FontFile 954 0 R
>> endobj
-2131 0 obj
+2153 0 obj
[600 600 0 0 0 0 0 0 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 0 0 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 0 0 600 600 600 0 0 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
endobj
-934 0 obj <<
+939 0 obj <<
/Length1 1612
/Length2 18760
/Length3 532
@@ -10077,116 +10218,121 @@ endobj
>>
stream
xÚ¬·ctåßÖ&›£’Û¶mWœT²cÛ¶m§bÛ¶]±*¶­[ÿsºûíqnß/}ß{Œßšxæ3ç3×c“)ªÐ ÛþŠÛÚ8Ñ1Ñ3räÍ­:;ÊÙÚÈÒ)Mlpdd"@C's[QC' 7@h ˜™L\\\pd
-ŠšRò
-üªm{|ÓÂv¸* Þk‚駹?ÛÜ—Ní>ö¥©F{1­(zR€—ùøÞ$T}¨›ä4 z%ˆégQžW‹²ÛZìŒê»“JÊzÅïPߧ;X`®ž¨üH\
-üÐIí|ŒRëc1:QA¾Õžž‘'?=R Ž õÜ@öíãÑäÄÂ’ñ¸@ ’GúÙçà h©Ux†SA¥7!àÝ´_}jt{êå‘‘â’FX˾*šæ¯Ù´Ë¾'A¦· ð&Ê9H¶îWþÀ¼žŸŽäJœæšËýZw&sÄâmŸ
-쿵$ œÉ„®'~
-j8+¼="HOló‰à|V”LôIŽÅ_y·1A‘T5dSoEy%|Dm3N†Á‡P¥{ú¼ÞÆÙˆ
-šÔ0ã#¢DËFwˆ(¤ ÙÓ§~¾f%ž©Y·˜"<Ø™Él¶‹Ç¹ÿúä2Ý©²HˆîKöÿ¢Õê’2|Cu˜Äï4‡Ùb
-dÇ$[ß4˜h3iï*#§†]Y·6_¡$l¥—\5Š´
-ÖƒGÒgÏt7êz \ÄØSÂèÑÝá Kz¬Å~»šF£¦s>y{­)ÕCóaÑýû²Ú7× Ý#ÓF¾o¯Q2v3äòÔן¼xÒ¾#x9s¬(ÃÇÊÒ÷öUX7Žqb‘ŠŒHö;QºÙö³ˆÊëí:²5p,sÍŠ˜VÚÜýXQý3j .jWô…¼¬[Ç2#oîä2’«²6¢£yé0O ÙÓËø8³)Kz¡l„ïzä^骟|‚gOH)àY îó¸¢e¾,Ùê›Ì,ðŒ‚þ²Êsźy&Ê⥄ñϤì*“@bKiyäúk@WÁ»¾/ÿë÷îÆ5 Ï##êáù@¹‡ŽRƒ;ÇË6ÈV|¶å9{<)¼ç QU+ó؉¬@"9ãå·¾9Ì-–†Æ¬»î³ØŽÈ³¼…„e†t Y.ž±áWËÔÀ;žš¹„PfÙWÐBNûŠX÷a|nÓd5ÕR©¡Ûo÷¿]fǧ_$¿å0[^ž‚IpƒVzrEÄsÜó^Á¤ÑÏJó„½Ë®Ïô—qŠž€3«Çþt¿ipôøɼïÆ/ÑøµÑ7d™§©M’°{<1†/ß{€"Ãg'”Dnnë«J0 VkÜ„},j6ä²6”ª ’nå'Ž`gâ[ö
-õ Ò””d³3þˆA*ú<ì;»ãçëȈÏÞr‘U¦Ξƒ ¸R64yEIÝ#ب[@“4ÂS»Ð¯«±÷è(pÖg/ä/ÄX»ÐÖ@­Å»b¾äcŠÅIî n¿¿„îçç3Ã"çU=^ó»\XºwV¯”¡ûB:Ï‘
-[—ÒØ$ ´zEø}:µ`s(éHô‚Å+X—³÷¶*5Â^ÁmøÆÊ$¶ïÉéGH
->êò:Û†ç-àñwN‰
-3“7º]Ç }"}xt¿-i7Ÿè¹½‚•
-üƉ¾ÏÑüІž@S&_#‰= ]Œ% ešPŠ†¼RŽ”oQÈJt{¸œñàº0ê8&ò½A"zXXª‰„^i$º@õÁh0škm}…“u­@îK/²OÊ\®zOóu#«"ùÈR.¯AÇ„ŠòÙôÐJ©4I°muþ`*?섨0­V2
-p‡÷/ó¢nD(0ÂD
-[Õ%:P+t¦*5Gil@ÐvmY‘ ‚œÁ‰~¦S JÖjn5£ë—ðys¬Ø0ÒÉð¹¼tOC»¯‰æ÷­™ÄiÐDX¯Ð
-Ù¿®;ªôŠD™r]9@èšÌˆ“ÖS|æ[Û, ('|f¤~}Ã!Ónëw¦©®n”Š\8ÖgK½Uz:'=*"Ô›%FWHO´­Ú³ÒèÒõÖDÐ_|ÌÎ\ê\Û
-qá‚ú a¾ýGŸºî“•e
-™âîÑ~)Ü“U‚™$¹ß“ñA=‡C“ü‘:³œW•Pv Æû§hbÖ¼ð»AàlmoÎUÁùË7…¹í \~3È
-ÂÏå±äÑs‰TNŸ +Ã<ˆ•9O¶¥fÈËDˆF§‹ÑÉöY廙l›¸·°6¿33ïáð\1ôb° a÷ Á{ó|³m«é*Ê›}½"é?Yš,µÔ¹‹ e§úPh‹ŽŸXEô¸º\©çÜ[ëgøV3C^à ±çSø¥$š ƒÛáÃ:“É»®’´ ð¾ˆïÅ^ƒÑÁ´‹¶ù´ë¬†)à!jáìKøGR~ŽCkCœùŒBΔí!$ÐdÕˆV`¨­\ ©n¿»Gó§æHðnê Úïvœ&ëÌŠ":—íÞÕ^"Æ;bÊz³N¾0UÅÕ–ûÖ1ÃÁ,Ծ㢫|7ßoV};º:Mý³éØc£ôÂà¤=™MhüCÔgaì‘7¨²Âˆ±b®5_¡·¸/ H:L« >r>Õ²"™y£6o„Aù±RQ ¼“_;N\¾L©µá%7¸àÀ‘¾g$µc [ž Ü80›=~Øü.¥T¿†ñ¥™^šW`/ž$8¢%S>ô”æý XÞ$'ñ.ά¡¥„2Éÿoƒã;At«!Äò‚´žÖ&\Åžã™dn£˜kjÓ¥³< -YRç˜oiæUìÚÆ‘ÌY Kî%?ê5TXrz¶ë[È/¨£=gU0‰Ü„€UShW´1ûºzcw™>ÔXê1§†S\»²3Š‘ÎBaʉ@,ŒëÂ?/ßu3u¤ð;…®MXÛ;Í0¾z“ƒE9–T¨ÕÖ[x,ÐÏsô1Æ÷Ìó–Q£×©VNcÌ…ËrÖs,¨ ³“eeµ‚l€N0j—;î
-??zÜ…¤Ÿ'PìE¶e6¹-Vƒú£ò>áÂPe†–½Í•Gèf5©{AuÔ¦JÑø^V¡ÌP
-:Ù‰4GÌCe*Z­:?ß"íÖŠS$`ë¾*~=QîFf†£¾d5 ?Užaú9v¢÷"“T!KÈ õð;[ùÛ
-ðþ¿$ vCÎÛš,Ù‡¦_¡ÌÐpvœY4Ô}ay=,”¸Ý
-׌’üïa,ZÆ¢O>c!Ö’&,î—AØ$l‹ˆ4`¿Ì™é„G ‘9h{±I K­àôáî·3ÂF£Ýйô±Peûw
- 8ø=ÇC¦ñÙ"ê®ÒL¨ì:0%»¸vÕ´HƒŒ?˜ø¾âù¢õ3™VF _?Òí)Û÷³qoTŒ²>ô£‚ùvî[±~á+Ó ñ¢øøhÂ…ª>çV©Ã{‰iÜÁɾ,ÓPhF°1J4‘÷Ò.’×l"ü<KÑ*ÊûY•eûÊ]XODÏ^,@+Ý4‘‚èbiœüÙÄÛù§ô¥‘mJ÷e g§÷H9×-7,z3’ '‘nKÜ‹)«ZÞu¯,Ú.«9¡²ûÚ3Ö¥$¯Ü šc
-9P “½¥Þ8€Fl‘…RÜ⎩r«'¶&ÍÖr+v¤Ì•³7_¾‡ßm/!ÚûÑ9òÌÀæAVÔ•I°ÃL"ö„O]á²Â!³™¦WD§w<·¿ `Ÿœõ[ï ¼¡°)!䛽'2Rj:PCøÄfűbü]–¬L¡ÅpÝ·mñª}pÜf†Ë ÑSYá‚ë^0Ñx‘Ê·€ýÍEÛÝöEô7N‚)ÕmÑŒªæÀ á7Š•U÷ↇK›—ß²9¯É,‡…ŒŸX¨<™¡ÌÅ…cÆ"ûgÚùÏ=j³é b«*"ìëLZaì{oFðÂ{¹†âMAÆ ßQƒ(°Á0ÖkøcÇǦŽtDþ<`N%ìy0ÉB´¨þ•PPˆ?Ĭ‰…šåxùVày»—.Jª“ÈÌë/vg`ž0zðõà~¬ |ôiÄlTªœXöA¥j–çW¸ӷôµœñø€l/^ôŠ^ÿ‘XÕH6«3d"Èî:¤úá_T`‚¨KÆ÷Xž³¬¦€­À›†ÚÐt¨bØ×82ºÙ‹°Y
-g–w¸Ò_ÍÑf4…,lÕF¯tçÜ äÊåšv…è0 ‚Z„•åIÝX®E˜w²b!ZhÙ”áÉTëkS¸¼SÉômз}P¼½ËiGýÖ´b Â/ÚãzNÓŸylQ]*+ ºÞ"†V!™s¾Ð›Íáüô¸Hм‘ôCÕ93Š+-q¤Õ01=*ã±ù¬uŸrÀeÂËÇ
-{ÃbFg#‚˜–lyù>.i¾™?#E¬4*872lºGÝ›ü”òóÕƒ¹óšAúa§¢+lµh ›¹cÿ[ÅU‚·_Q'ï–íMÇ7&U6æØ‹{tÍ3_ŸÔ_óerˆ$q¿E½â>$zr,¾.ÄBËëDÒ‰ú@û‡ÍDü”Ä­wPL+w1xàKDTjã_žKU÷‡Š¿÷ðN€úè±=©C; ]‹‰ØÑ\z©r¸úÕ~ÈK*¼Æf:²}䥳ý]°¤Bu›B<+2¦ø¥Ø×Iÿ§½²¿S©ôûü¨·zM­<ƒïˆn1•ùu›Ó÷^Vú#:.æ?¿yÙž®ïµá§ðƒ£|`q^ Iš©åâ:kÓãZFMd§Í‡ˆ¨><…÷Å4I)'16TØ͆Nß°`‹ð` [€r óz‡ÅÜl8±§ ’¹Ll[@Æh_ëí; Hk¢ÉjLÁf'‘Ö%З&så@µTýb[Ojöß 0®šm-Z‡µ<"ÂVç­wSp#H¸Í°ÿ,3L\g*±Ý¾–Ýçpg¡’^uІªH%a€ÃuQlàÎZK‡B£vHÕqe·lAW`¬úÑ–îxüFÁŽ¸“Õ7º¼Î IhB($y{³ÓËòMSô~¥ã # Z|Ѻ6Æ×c>ÁB’Y”ï‚*¤ÓµEkèið„ûܲ²ê6ë#¥ÊxNÛµqqŠ®k%:ЂÃÏý0{Â4Û¤8¿ŸJØTá‡ð~UâjçµDg,Vå|ÌÙ)îmÛ ÁÎ n$;ùâßÎWûË)6{ô2÷Å1§ßÿ2_Q.4ÓZxWG)ûqŠ·óGŠõ{RÜh¯ºÎW¦ãrzÞõÈÐKËDä]Üw¹Qöº¯G…\å# n—ë{aæÆŸð»Â¯U"¨k;`aEw}øŽ¦¢´Äætf µŒu &ßéæsÜk¶Qk¥pxNšnL’v’Ô(|)²FðcˆÇY£0c…‚Ø0cX{Ò}hƒ¸eÐúƒKŸ:†ohÁhdYÔ}îw¼Vj¾]½¹cû¦wní†PžQY@V)[7ôU5:Ò³ûÑ
-¢ðBîBZYø ¡QÚ÷¥Ä:_}ÒbeÚ*r³9ò”¯Ô¿åÏ{ݘéËáªÝ]1÷WšeÂ…5âo#”‰Nb… ¨ô>¶ïÓAÎì·¼žíÉzàá]M¸Q»„)ˆ'°&má"²‡8øg+Gž‹-¯ðJÁÙ¶(!‚d%šò÷F¨é’‹Íü0ÓK^žŒð §.Úf9Õºi"‚Bœ‘תÂh<MÆOOìu h9ž&ZO{èìxö6"÷rWNÕ6Ù$Çøâ0™…´žUîÇ>‚0æ£Þ·/Dž¿V™¹6j©Û̇‡o—
-_0ß9ø™Ü®Á³@3&i ¯)BBD‚Òr8ª¯sÿ’¶þø¶6ù5EåÇÁ‡›3§ŸÒûišI©R«‹ª]S¯Ðeÿzý!KþãÑÑÛ7çÙ96@:áO´ˆE(Q`¡W¡ÐêgÉCIචœ7·@ªÁ×N~ðOÎÏL ÔšîÑ„6t>æ€ñtFt&QòŒõk©ú¡Ì: ZBw˜0.•Ö
-X˜DöBà矉uƒRá±êëŒãù³"‹‡»½øS,VëUgÈÓÑ×Hë‡ Ö•Ø®ôh3ßõ½@gYa°«¯ÃK}\)ÚÖ„èoô}7dÔ{Â+ä’רþ‘ǟúiæpC8[bk%u‘I0: ]¯úíŽI*]¬NꌕԲî<'âÌ€Dq¥1öYßþù4ˆù;4Ù´Ô˜¥^ðžöE›:ãZ”¢‡ÖãßhSÁÒ"”‘æeGq ¿¸ú‚Ò®ˆ÷ñ"‰v=}ç¾ÌÅ%ű;>RÕw´ºÊuú)DãPèñåVÂ-{ i¢87£rC ~zIu(a=/åÓ`éÇ
-`JVæ€ÝM?Ë-*\šFì\q¬w÷4³Ç"Ây'LÜi æI²úвTxÝCxEåÇ7#Í=䬯šÐ]ÏÂ)9™šj^wpŸiuØ•°I/9c½šÙ;ˆ†YÂV%íÇ’:ðgEFÙÒ·O(–qS”•=ŽM.A¥ó¾5Æ·ôŸ·¸PF×/ *ÝXåï·Dê,oö°`ÐO„&ÄÓú1¢ç)ã”au§4‚x­¦"ô£šVKnþ?af¿½ðÒâº-©Þ(äM×4jý€‘âª[ Âx06Ä–3± ÊbV®gG¬$¨ˆX”£þÙ]0ML]B@! !k“ö'9iH„%7ØdÇýý³ê«VÂiH€ð‹Lêõº «§ÜTÉMÓ´1=1TäöÅ¢ÕæûH&LÏ5« "ŒúÞ¶jªÏa1¾5e‘ׯŠ9³dfƒC|—fS}½Á¢^3²Ry€!©ìcÊ^Ù±•CyÞ>æäŸGY›µöLˆ²Í+ðüw…¯‰‡›]E™†ÏIœº#½Á”“W¿ig/€¶0@hçnlÊäª5Áç®ýF6PI¥pKˆÈKUëqßoÁÎJôƒED=§É*óS½PlBø±a`
-^ñ2Ý9á4GÌMdHä:a,h&y að;!Ù$õÖaÖ8|Z2ÃdÞ‹J‰Óc—…6‘Ñ}Äu"åÈÄ7)õ)ÚÞ”L#mõ0n—Ü^žÇl¡~c[øïz¡AèÖЕ–êÍ™qùÐEm)PF½÷¢xŠÔ–ŒisØ€ç³D6 &œ<ÝÍYï’Úl¥ç¬œs·ÚCò£ypKWFsš£jƒ“ÃÉs ÈÚË~
-¸š4?æ·q|CÇÂ[9ËÞnÑŽ¯U…”kCWvܾOøHB ÔfGpÊñ¦Ú™uw"£Û¬‘M+<ÂREÍœËâ`Ôщ) SßêÓk3—ÌŒÊy‰m:ãs‚êf“Bܲþà ĨÙþ†¨4ÃJ´§ ¹=µ¬l%Ž»Wa*ÂÎK6#º=\{œ˜{áÒBz[òaey}1i%œ1ˆpÊeDNi±`à6^¥
-“V-Á …ê©>Zw>î^’:ðëÖ£,AÎó=a¼PP?N}“­8s3zxC4-áÙ'Ð@¢¯Äa0½ÌåŠ&vù& Ê«¹jÐ-OB;ó¹bîAl/­äÝÈ»÷ #o«²#yÁ?.¶Üè© ®Ï²
-sf"7íȘ'z½½Aܬù;˜-Ø„º5½ŸPoö’RnÃã—§cÄ­d>­Õ‚ëmOévXš}Ý…["äC»Îµš Ú·ñfº ?jÊ…Šs$!ϧmAb÷yg‘Õ3–ã¾ú©Ÿ™ì‰YÊIÚÓjû[«Òaî ë—e·Ù{/ûÀjÂé‰õÙÊZXÀüì˜à äa.ð–Ïæ\àß›¶üؼ¾~ ê¶Éþ¶ü5öZ š‘X’oJQ˜iOÎãÅ[=Z)é!³»&ç–ÃîIëBå\Ý;»"B7›§ c)Œ—†Þa%ó‡ŸTÚÅLn_´´i·‘c•udg/U†Å=7
-BÎA>ȨÅt»î„ÞñMt7¡Š:»ùœ=2>ï((Ÿ!{GÅo’8DiåGÍlœ ÊãVÍÒUŒÖº‘jÜ”Õíë
-ÞÐõ)δ¨ŠP=¥ŠúçÇ ºÚiÓNRŠÓ€„™m:ô¹¾@1??¡– ­”x!MÕT•ÛŸAsË•-&I˜·ö@ãݪƒêE!F_Õç5²î´ÛT² «ô±.è-ó°{m”´YÐßžëÈC&ÐöºoÕ¬ìêW5iø·Š ¹Ž–ðûï~dÏFœöN{uÍUg¿a`BFtCÙ¾VØ-¯Vâe*ï@ì @uòQµ ä8L°4§2Ir©¶Ð“†¤o§¿Ù §¥ëÁIÆtPÕ'ÆiÎâsëŽÉÇTЃF`Þ™0Úu­5hJ»½ Ù‡,KíÜкÔP¡f|éO7§Hf|dÑr^kç Žß¼¥'@>¢íð@‘…„—Ä”ÄÄJÄÞ¿Ý>3„Œµ¬èZˆ›Ù¡R^XÚ9ÈÍjÕy0”Nš¯s„gA‚îWˆ™[Uú £™2õÞzבl‡KØ6`ñ
-î†Å×°æËùß'™+¹O?àªH‡q@…
-…eȤ½øÛ ]Ûq};—¼¿ý%W[J¨÷¡¼–Þè aÁþ[Ò-@^ŸFðGH¿ ìÏÈÜ°<·eÕ@wô¨‰Îy«(‘«xd;{”«‰U¸otÁªDÕL
-˜ªˆÍ|Îóp—aÜ^§9Lî÷‹¥¨`=1OþL
-^ú”ãh@RÄfíÁ•6—U
-×qóp&+yPå°1¦àÙÂ¥å Xˆ|¿ð$6Uç»’ÄŽ¸%¼ûm'v»!†æ^™íç Åä.°¥6q2Œ\õº«CÛ7E.ÄÔ—¨lwBÂæ8=÷_so09Fµtéf²ÅoÊRaáÜJýèb;†xŸ)ォG œþW¤ÈùQw¤ØØV„K˜7µºy$•o5MåÐà,=²æ_³4¥ñ3ž•÷°Ÿ
-áB«¦¨Û$EZk°`ë¥Y 5qÁ[œù¥ëÂF… :ÁƒN„´®jîܨ€›JV[‘
-ü™±8Ébº¢¾9àѲœ&Â&9 h°¼§!`Z„ù“½M$¨'Ì é·Ç ˆ‰b|ö]·[EÍ\çtHL”.=MSeî{F"ä(ËfIÜ
-ˆ4ƬÆx»ák&ªˆü• “KѡڪƎ5soõUKæU6Û‹m™³Ó<{WûFgsü2‘“+tëÑɇ¡ˆ§Ç—–Fë¹mù¨ö9¥ûŒí¬ ( Q«¿˜?©Fߧ$‹OÌr?ãZJŠM¿{m9ùœÄ1+É°‡!¨Ú‚§¨næòY:ŸAÈ‹Wv¿ ˜iq“~ˆRŠ
-íqÃoØ8\"ÉÄø‰m~'8 £Éùª¤\"~Ķº…puX‚8R±·ù;¤‡,qÞ\;1´L AÈ›œ>lϴʘƒš¶ü¸\UÆækèK¬ôó(29÷ðJ3ôûõrï˜O²âåMçÑñBu”蓼!þ*²‰ñØx“–ãfðÔƒªáFb6ä([N£+þe÷#Ìó,+CðÇUÓ3Mcf‘ÐAñn0Ja¸Þ.H”#ÓJ>U³ÂåbFµîV?4™;>
-Û Ì_÷cvDMÄȺ„‘)˜3,fÅ·„@sž?X³¡˜ò\ªå$@Š$ÈW;ö=W!za(NGv È(èᇓÃY†CõdQ1”On?S9Ç>Oµ
-dõ›#.
-óÕu«ðaxÍ'¢T´Æ49¿}
-„¹ƒ°yeàêÙÔSYãæœjî×]…)Å’ÀY¡vSWòÀ­¢ÒGÕîUê£ ãþh4× ¯DTÚè¢Ë ¾ŠŒ}dœœ'.ßñ»c)sùÂ4E©”€cr'L’q!2XdêFÒ±!NMi€âñ¢ÂdÖ |H—^ÉuÞõ“ù¦?aÈísNfBèÈ(û;Ÿ>§[Q-„- ï$àKor§ËûI’;G¸],˜úJâAžXÚ€àvÞ9g•0žh}[ü £Å‹—T€%/WHþî×Dªÿ~Å!¬„ŒµWJQ;dZUüÁˆo 7êU ‰iT†dGà!y×"?αLÛuº·Ô~¡šŒ{U#[Ö÷g_SÚ®s·ßñs=„Ñý}Ž´þ^W@ƒ¨IÙ9¼£ýè@‡}Ó$0_>)’¤Èz®Ep,—ðóõè¦
-ÈïQš4Zl’€AÍMNÒ1B.NèL·YÏ¥£ÌÊ©“0d›±)š„¢«ëOØF'Í<I('Ó.DÁ=Œ”³‡pEd­ùØøõmQÜÛÓ
-~z#ë6 å˜Mmné©^«ŠÒŽ†y§×ù{?¤¾ó ÃN[„!H-Èâ–‘Ôyúê³Ból«nsªYòU4Mö¤ ©0lÕÜ´~µÇê½æ`
-chô„, 3 ‹ ï‘“#•ÃùG ÖÑŠ9$5à »l|ëQλM}ž¥’>‚ÈÔ!¦}™n¿°B=…_½' qŠ=ò¼²D½JQ:|4ù "V&71¢‡»Ê´XGŽÌ˜Û6¸XÉLjðD^«Pìˆ,0ª°>«ÇŒzK „Uê• Á;ð# zJí™ÛG ÃLtåk ­' , 2ýòô™ÏªÍÑk|Õ[~>'}A–ž­h¦M$™O¤{É™™aý|Fo¾á¦›\basmç­‚‹ÝjM߃½€—RÚ·Ž¤`W<Tº;ˆˆ³õì&> 5YC¶]Þœ}ËA… IñFÝi„—¤>4Å1 <ÏÜïQ»ÔäJ!¼@ïµ/g”Æ
-¹?¯²YÉLµOÿº“oc€ùÃ^vu?ÂYáQbâÔò%hñ£›Þ|ù:µ˜Âôʼn "¶®œ%v ¾õ
-U¨!š»N}œ Ñ“;æJ›ªÙCĵ?ûœôý+¼<¹è¾ŒÐp—³[»õþAN
-ç´hô@ª{âN'H_È9S(rÚ·kEü&ßÏ•tÛª.Ü,çx>A(wYœÐ%
- ±(ø'E5 Í0Á{'­WÈÐÐlûù 4·Oÿæþk¨ÕÏÙ€œ“æ¬)Tlý¼SM¢ÌºtÙö:ʇOI[|¹,™á
-¸} ³i¼<nU·ƒÊ'D†7Òz;%s}S°l<•’y°46Ê–TZ¹eÛ]DÕ\Y¹ñ}˜en|(xèn)<¸ËŒ¢G/Çê‚«þf$'„ƒ":èuë ìðx/’<€Â?‰CòSÁ064qcZŒz¸ÙÝü\! ;‰^ ¼·'PZÖ‰EvdŒ¢bòjGYþ=Ñh/«¹È´®ŸË $8éÈ'kê¼²à
-%gsðùB§*÷Ä•TÝþô¶VÔ½~Þgÿ°s-Ãê¾ù¤‡I3ôÀâʨbŠÅ4ZŨǾdzçÏ—à Áç‰÷ø׳ŠX]"ïe‰¥?ÂÛjš…<®ÛsÒfÔAgV+¢ÔŸ8ýdÚ¥_ÜÌl:ɶ™q
-L! … a¥,C-CŒ}M¾~šÞƒÔCzâë—ò '|;¦DÜ‹ Ž‹¼”ýû·NsŠŠô c‹Ð9T#qY%%ËGð 0Ù¥*÷f’
-.³ã׋ÏLH]DÒ.½Å¦œÈçûNcxï*ÿÍRŒõjHGmwr$Æ›~üzXÉõ½c7G9±fRpÂÔ›õñ`ç¾/ŽFöøÍ¡Sësöe‘Ä¡ûůjrv±K ±‚º‹—li¬@b Á̧òÓµ¬FÁ§”L¡s¾´_úm\9G›8+¥£XmK‰^γ³æ&„m©œtðÞì]ª_l„Š@O3º] q—ÃX;Ü3œåá›
-kƒãåxÄüÁ‡¹C ¥"QPf¦CY_vŠÓÑô|‚ŸŽîdœîÃ: eФÛw‘éûe« VÑê–†P-o‰ ã¶*‚½—€:GçMøŸ¥ÀOr¿/CîlMk[6qÉŠP·eÙ0ÿ¸•Ëzý?TRÈõó·—Ï(ªå8“j$27BjߺÌèÖ–õ¦òãȹÿäâÌ-:N ^TüÚO`bŒvï ×o(<>yýeþðHó‚Tƒƒ2¸¹ÁíåÞ(å2Çæ¬9½³g¦F³Ù å’Ë?q…ÃNßJšPZØcš¹ÔiΑ88›ï…wäD&oô\<朕çÞ‡.'cve‰kÎþšØuôI¡]Èš‡þý+‡¨§Ä ~¸db D:{‹ÛÖq •¢j+˜ZÖ+·?ÜT±æ­ºŸÀÜÀ!
-û:%é5¾¯åV¾çu™J°5Jòb´â"2jþä³àí=j¹ òüÅÍ·½OÖ±¼×Ñi¥Réqødoeל}½j(áIaRFT¼‡{°˜Të‰n°‹W÷'½y@,}H5»A¬8ÑLØÑ]ƒ5ævYÛÐD"ßïŽÊDʺ°z¡Ž »z}ð…ˆÇÄ_@ïO>s0<#gr¹ñ´»f!bºÛèÊ5ƒ¢Ã–x¦ÐJÚ./°A>x»! jm–²sÞ7vÁßC}AœíÁ÷}Žn4XìÅVÄés¡%›†¹¢{Pû< ´éÔ Ì7¹d±·ÝÖ.´?²s1‹t¯}¼;¯±Ý½’×Gû»{UÔ.!ó!T-ºž¸9Çݯ~_’*gûkèŽvª»¦$û¦ÝU‰ô¥5Sü¼
-¨ïÃÌ'l¿:¦ðè;{3¦Íäeµ—Ä;»¯McÕÒÚ-ÿXON´Â½²ùr0‘õC€ƒºÆ…L9ꉱSWËñÛÖþN2¼‹ÆvÃñ’ýÐ È*ö{ä•k^‡jogÊ"oØÊglÂóIüPÚ}tq(½Ÿ
-QCm6õ
-Ê’¸È˜”m€¿™»_–pÛD‹KÅ|iVWeeÀÀ«‰ „lÐÁôÿê4èT0Éëë]Ïd‹;PL¹£¥e!D*%)f­­Ð¾ì {ÄùíÐîòsÃÕ|0ŠLï-ûÈØÀªY‚èZ`ä<Üu´N!ìÆÂçaæ¨ÞôIJE OÕFÚØÙ‚™O¥ì鲟‹„œ*+aB5*êëˆYš0MŽŒ£>ÂãðSΚb¤³(=nìj‘·æÑ4W­ÁÂ-ÕÏ·­_ѱîíô‡Çº™·` î%âg›«ïW‘iІJmøª º¢Ô††ß‘$1½ÑØ“](snr…„L¹Rœ±¹UbµVfn3]ú‘ÛÀáˆÿ3È9ÆTÄk›“¯Bšž«µW¯ôoäˆ9u“lܲ‡vxvèô3Õ ÖÞlQ;, ÿ®w½ß,Öf9z ïï‹?ŽJ¬äl* +pË(ÑMÁ™ž eF×gº‡@‰<·5ð˜MêÍ jmòÏ °ñksŒ]VY:zÅPÆ]•a£¿u_d„‰ê`”]&6ú‚–2#³ëb…S–ä|_'UBÉ9ÇØÔ*+‹©´ËY[–µ²zŽ’w
-Áë±(`°1BøÍéÑ÷kL»;B„/ˆ,à  G70“›(Y:¥ö
-ùµi¸ŸÔ§îwX\Ÿy=rû„7"¬ˆiÝe6ÕÈý`Cõì¥oØ?g`ÍF朌‹ÀH‹†ò×ÓÕÏ‘`ñ» ‚ƒT~65Î.96,`³xõµôlë Ä\θ;&¦!kÇ×å ÆæÁJôV>ÓÛnQ3­‹c…8¤„½aGãÐ$îÉ(»çf†A*"CÛï}„:¾¹ Ìl{‹7nN^ÐÊ`„påƒå˘ÌV—Ûyþ2>÷{Ή =½"ž;ôl`¦GS=)ÅhhR:ê bÞ°ã}µ;íYÏHey~aN'¡¦o¦NQ»ð%`\ô?G°2™9×Á>ìSŠ¬7…¾»Ù6ò_qÛ§ÍȒΊŽ¤¦vغä.Ù#*Íõ¹²G-–à°Ã~3º½øÕNôdàÐH¬|ò€Ò>I6]ñs˜öüåÛ{ñ7cÌ a8d?‡ÉNV¦æWíûê^ÙŸ\W’é†;ˆwÒ`–v0zA…füA©‰õ§$=›Ò¥˜ÖÒGVöašMŒs*(±Ó8üì¹äô¶^d•àŒ1÷·»s®ÛCºDdq
-I¢BŸîÙ¿¿²ÊXãÞLbÁcÔÅã‡Î0¸±hÿŸvæû
-‡
-ïÔ2AÆìöâ©eîÛ›Ó¦;»ŠÞ¹‘°!¸„è`Ò]åU-YñÌëŸò¬ùM5ÁF³·&RGßw´+ùûè8šŒÁÈfïyFW OU£wÀº$¾¿@i¼ù9ºùr¹>ÒHÝÂö§õÆe¢Íw{˜¡Ù
-,ùÌçÖ6ºþ‘ß‘—§ìä*ƒšA>SxÏå’ò§Oœ•Ãøjäwcâ]o¸‡´×ç?e•é%Iôm ßÞl)·œ?Þ4‹™æI¿´—.¦Äì Ê×AÖŒqh}Ä_J¬Qêõu‘¦ZX´y7³xÄ,i’¸«^飯\µ1) Ík„ÝÅ TÅ>¹Þðô3¥Ÿ¦õ1!}KGf³[ZdɦÚ^Ýs>¶ì¨¹…ç›ý˜“]û·çÁ ~V\Yƒ°ÕæÆÐ¥–tQrÿ=<e¢w†|hó$¿åÜ£ëØÁSä<þxØI'è÷¤ïëÚ_tšd¯„§wòÒs_×àdI#ØÙÒ¿˜
-ogÓƒ1GC6E®Í]cdv®l}©µžÆÍE*û‚Xí øVr,À8è–>7%×5/ÔQz 6@^î$Æ
-Ìkª¸â§hDlU¼v7X}ñÂúZ%fòb+†Î5ƒ;TÅHÿ$IÀÒR.X/+ùeÌö2¸Õ4•õ…6È(z¡ØîõÉìg,Í¢ÛäZ}~û JmÕg(±èe{u›"&Œ›Å?c
-áò¼\¶¿ûë¦n
-Ý)¥ÀÓ,Ú €ž–ñ;Þ©x%ŽÇ*:Gï­Ì‘bàÞšÈÚ±ÓÀ'“(' ø·&ᦗ„Bfs^0©^T
-i¿5xÑ@>,Ïu> w?tiÓ¶0ûôIÏä#%(ù‰ö
-©«ˆ|LO†D¨Å÷¦gîÑå¼Þ8vÉC÷I~®O–ÙÍ>mŒáõÞ¢‰‘}‚
-^hâŒð·¹ œ£“hZ™Í/øÅ_à7œÀ+P¸¸&&êåî$+Nȶp®Ô ~I(–»c¹ÚŸYªÓÅg¶%ø¥p%ö>­’H¾iL¿\ÚõÐß(¦µâ_«8Cƒ—R{‹
-Žµrð¦ëØíû‹0Ê{‡˜ÊQê¸2‰«Zœa‰ƒ†*7Äc¹äJî„I›ÏüìÒ]©æÁ 1=Š¡å©òñS€MX¡¥GMøªéþP¢‹:*½ÙOT9†ÜD¨*ÀzÞÃ*Úž“¬ÿ°Ë_hg
-‚œ«ê9ŸjˆŠ"J7Þ®(ðhT(ìâ ª¦¼ÜðÊ™§Ä‹V¬áÝq
-oò]ç }£¯9B‘7õ· öœH{È­’ëæi`T&éVÇãs"¹‡‡ªÃßÛçVMo¼iá÷׈â{C„^×;¿_g¿`,·÷þ2 Ún“ R ɫǶ]ÅjÍuib°ƒãÏV!QÏÆ>²¦aO<ö”ñOÁxƒªH²$áófe°§Åû›ê¥úКxÇÑiêÅà>ò$­–Ìy"-Ú-ŵ ôý‰¤Ëq ¸ŠÖˆÕ"™[Ø m¥cA¸¶¹"t8Q+PK¥ìó÷Ñ”¶ëÛãh_“ ®$+ƒº‡¼S¾ÎúÜþµ$áØ™éezv~7EhÅZÞ‚¥ÓªãHÝåûm®Ý‘(ãŸÄ"Þïòwnúê›»ÉÕ”^«¦
+ŠšRò
+P7É;8hôJÓÏ4¢<¯e·!´ØÕv'•”õŠß¡¾Ow°8À\=Qù‘¸ø¡“>Ú!ù¥ÖÇbt¢4‚|«-<=#O<~z¤ê¹ìÛǣɉ…%ãq@$ô³ÏÁÐR«ð §‚JoBÀ»i¿ú$ÔèöÔË##Å%°–}U4Í_³i—}O‚LoàM”slݯüy=?É+”8Í5—ûµîL&æˆÅÛ„?Ø;kI8“ ]O0ü
+ôX‹ýv5FMç|.òöZSª‡æâû÷eµo® ºG¦|ß^£dìfÈ婯?ÿxñ¤}GðrçXQ†•¥ïí«°nãÄ"‘ì v¢t³íg•×ÛudkàXþæš1­´¹û±¢þúgÔ\Ô®:è'&
+yY·ŽeFÞÜÉe$WemDGóÒaž@²§—ñqfS–ô6BÙßõȽÒU?ùÏ žRÀ=²ÜçqEË4|Y²Õ7˜Yàýe•çŠuóL*”ÅK 㟠$HÙU&Ä–ÒòÈõ×€® 8ƒw}_þ×ïÝk0žGFÔÃó'€r¥wŽ—m­ølËsöxRxÏ¢ªVæ±YD
+rÆËo}s˜[, Yw?Üg±‘g x :Ë é²\<cï:—©w<5s ¡Ì²¯ … œö!±îÃøܦÉjª¥RC·Þî+~»ÌŽO¿H~Ëa&¶¼<“à­ô䊈ç¸ÿ潂I£Ÿ•æ {—]Ÿé10.ã=gVýé~Óàèñ“yß_¢‡qk£.nÈ2OS›0$a÷xb _¾÷
+'ëZ;/€Ü –^dŸ”¹\ ô 0:ŸæëFVEò‘¥0\^ƒŽ å³Ý1wé¡•>Rh’`ÛêüÁT~Ø QaZ­d
+U~-UÙ1`¿ôB}èÿ[à|ýÛ¢˜‘èþà éz]n¡·†ätœÍOîø
+é+¦ÞâwªÉ"=ÖšTÂb.Ê;9§D¿KBr•ZDIé°É¬/$h-5…œë¼_àï_æE݈P`„‰
+eŸCN[hÀÌ"¯5sß¡¶s«ÒVÛBfžáœD(˜Ü¤胢&BˆóáÛ§Œ—=Ü9bª©s ß¨nZîÉÄõn^’¡ïg^í*ªüdïfº×D°>M*|™vži­}ç`1;s~ŸNÀê~m©Ó±‡„æ\£"éc ã9D^ŸÍ1ÿ˜,F»9ÿÙªø¥só=Ê>çR³¿N§EUÝ£¾ÊPäý60|õ‘³9& x¿«é:d=ˆ“ºª¯’!êö9šu96¯¬|ö
+ œÉò;Fª¥)Ò—³ö­nEä ûÆÀ%g5HF¢´`Æ÷‘1
+S4DB~Öõ‚iJìÞóex
+r€Ð5™'­§øÌ·¶YPNøÌHý ú†C¦ÝÖïLS]Ý(…3¹p¬Ï–z«ôtNzTD¨7KŒ:®žh[µg¥Ñ¤ë­‰ ¿ø˜¹Ô¹¶âÂõA?Â}û Ž>uÝ'9*Ë25 ÄÜ£ýR¹'«3Ir¿'ãƒz‡&ù#uf9¯*¡ì@ Œ÷OÑĬyáw‚ÀÙÚÞœ«‚ó—o
+s%Ú¸üf„ŸËcÉ£ç ©œ>V† x*sžlKÍ?–‰N£“í³Þ;TÙ6qoam~gfÞÃá¹b:èÅ `Âî ƒ3öæùfÛVÓT”75"úzEÒ²4Yj©sÊNõ Ñ?±Šèqu""¸RϹ·ÖÏð­f†¼ÀA'bϧð!KI4 @·Ã‡u&“w]!&$ià}ߊ½£ƒimói×Y +RÀCÔÂÙ—ð¤ü‡Ö†8ó1…œ)ÛC0H Éª­ÀP[¹@SÝ~w0æOÍ‘àÝÔ´#Þ%ì8MÖ™E
+t.Û½«½DŒ/vÄ”õf&|aªŠ«-÷­c†ƒY¨}ÇEWùn¾ß¬úvtÿtšúgÓ±ÇFé…ÁI{>2›Ðø‡¨ÏÂØ#7nPe…cÄ\k¾Boq_„t˜V/|å|ªeE2óFm<Þƒòc):¥¢@y'¿v4œ¸}!™RkÃKnpÁÿ"}ÏHj/Æ*.@¶<A¹;p`6{ü°ù]J©84~ ãK3½4¯À_<IpDK¦|è)ÍûA±¼INâ\œ%XCK e’ÿÞÇw‚è2V1Bˆå1 h=­M¸Š=Ç3ÉÜF1×Ô¦Kgy@[²¤Î1ßÒ̪ص;#=˜³8–ÜK~.Ô/j¨°äôl×·_PG{
+Î(ª`¹ «8¦Ð®2hcöuõÆîþ2}¨±*ÔcN §¸veg "…”…X×…^¾ëfêHá?v
+]›°¶wša|õ&‹r, ¨<P«¬ ¶ð.X ŸçècŒ#î™ç-£F¯Sÿ¬œÆ˜ —å¬çXPAf'ËÊjÙ
+T´Zu~¾EÚ­§HÀÖ}Uüz¢ÜÌ G}!Éj@6ª<ÃôsìDïD&©B–%êáw¶0&ò·†j·e£ÉIø’+ÿG"ºb nYˆ#ÎÊ…5Æ|èZ:éŸ_ xØ0g÷à?§û3â£8®ˆÜ˲À˜Qïü±Ç7×X¨œÞmÙCìc#y¨àýIì&†œ·5Y²M¿>B™¡áì8³h¨ûÂò0:z$X(q»®%ù9ÞÃX*´ŒEŸ|ÆB¬-$MXÜ/ƒ°I,Ø iÀ~™3Ó &"sÐöb“–ZÁéÃÝog„F#º¡séc¡Êöïpð{Ž‡Lã³EÔ]¥™PÙu`Jvqíªi‘0ñ}ÅóEëg2!­Œ:¾~¤ÛS¶ïgãÞ¨e}èGóíÜ+¶býÂW¦âEñ%,ðÑ„ U |έR †÷Ó¸ ‚“7|Y0¦¡ÐŒ`c”h"ï¥]$¯ÙDøy–¢U”÷³*Ëö;•»°žˆž½X€Vºi<„#ÑÅÒ8ù³‰·5òNéK#Û”îËÏNï‘r®[nXôf$AO"Ý–¸SVµ¼7ê^Y´]VsBe÷ ´g¬KI^¹A5Çr &&# zK½q*
+´ÂØ÷þÞŒ4à…÷r Å› ‚$Œ¾£Q`ƒ-`¬×ðÇŽMéˆüyÀœJØ ò`’…hQý)*¡ $ˆY
+5Ëñò­Àóv3.]”T'‘™×_ìÎ"À<aôàëÁýXø èÒˆÙ¨>T'8±ìƒJÕ2,ί„q;§oék9ãñÙ^¼è½þ#±ª‘l VgÈDÝ/tHõÿ¨ÀQ—Œï±<=fYM[=€7 µ¡éPÅ°¯qdt³a³
+x^ðÁ=‰/‰Ž³'Bhùb£ÏX‚ghÃF/çœBÀî™ñ(qF¦ü¦S>à6æŒ#°ÅóŽùI4MœÑb¸ï=pû{níÒË%ˆfcY¨¬×¿þécaöyqÌÝ1¯Æ ì—n7
+4?äÀYÜ
+Yت^éιAÈ•Ë5í
+Ñaµ+Ë“º±\‹0ïdÅ C´Ð²(Ó©Öצpy§’éÛ …oû x#z–ÓŽú­iÅ6„_´'Æõœ¦?óØ&¢6ºT&V@t½E ­B:3ç|¡7›Ãù)èq‘ y#釪sfWZâH«abzTÆcóY!ë>=ä€Ë„—ö†ÅŒÎF1-Ùòò}\Ò|3GŠXi
+TpndØtº7ù)åç«sç/4ƒ8ôÃNE#.VØjÑ6sÇþ·Šª,o¿¢N(Þ-Ú›:ŽoLªḻ9ö8èš?&f¾>©¾*æËäIâ~‹zÅ}HôäX|]ˆ…–5Ö‰¤õö3›‰ø/(‰[ï ˜Vîb6ðÀ—ˆ¨ÔÆ¿<—ªîïá
+ï‹i’6RNbl¨°› (¾/`Á%àÁ¶
+èýJÇF@´ø¢umŒ¯Æ8|‚…$³(ßUH§k‹ÖÐÓà ÷¹eeÕmÖGJ•#𠜶k%ââ];$ÖJt ‡Ÿû?`ö„i¶Iq~?•°©Âá/üªÄÕÎk‰ÎX¬Êù˜³SÜÛ¶‚ÜHvòÅ¿¯ö—Slöèeî‹*bN¿ÿe¾¢\h¦µð®ŽRöã
+oçë÷¤¸Ñ^u¯LÇåô¼ë‘¡—–‰È/º¸ïr£ìu_
+¹ÊGÜ.×÷ÂÌ?áw…_«DP×vÀÊîúðMEi‰Í;èÌjêL¾ÓÍç¸×l£ÖJáðœ4ݘ$í$©QøRdàdzFaÆ
+±aÆ°ö¤ûÐq#Ê õ;–>u ßЂÑȲ¨ûÜ î(x­Ô>|»zsÇöMïÜÚ ¡<£²€*¬R¶nè«jt¤g6ö!;¢
+AQé}lߧ‚>œ'Øoy=Û“õÀ!»šp£v SO`MÚ
+ÂEdqðÏVŽ<[^/à•‚³mQB(ÉJ4åïPÓ%›ù5`¦—¼<áN]´ÍrªuÓD…8#¯U…ÑxšŒŸžþØë$@Ñr<M´žöÐÙñìlDîå®
+œ8ªm²IŽñÅa&2 i=-ªÜÿ: Ž}aÌG½o_ˆ<­2smÔR·™ß.;¾ `¾sð3¹]ƒß9mg!€fLÒ ^R„„>ˆ ¥åpT_ç6þ3$$mýñmmòk ŠÊƒ!7gN?¥÷Ó
+4“R¥VU»4¦^¡ËþõúB–üLJ#£·nγsl€tŸh‹P¢ÀB¯B¡1ÔÏ’‡’ÀmA8onTƒ¯üàŸœŸ™@©5Ý£ m>è|Ìãé$Œè8L¢äë×RõC™u´„î0a\*;­A° 0‰ì…ÀÏ?'ê=¤†CcÕ×ÇógEw{ñ§X<¬Ö«Î§¢¯‘Ö/¬+±]éÐf¾ë{Î"²Â.`W_‡—ú¸R2´  ¬ ÑßèûnȨ÷„W:È%¯Qý#?‡uÓÌá†8p¶ÄÖKê"“`t@ º^õÛ“TºXÔ+©eÝy,NÄ™‰âJcì³¾ýóiówh²i©1K½à#<í‹6uƵ(E
+¬Ç¿Ñ¦‚¤E(#ÍËŽâ~qõ¥]ïãDí
+zúÎ}™‹KŠcw|¤ªïhu•ëôSˆÆ¡ÐãË­„[ö:Ò-DqnFå†üô’êP>Âz^ʧÁÒÀ”¬Ì»›~–[T¸4عâXïîif%ŽE„óN˜¸þÒ:Í“dõ¡#d©ðº+†ðŠÊoFš{ÈY_5¡»$ž…Sr25Õ¼îà>Ó ë°+a“^r8Æz5³w ³„­JÚ%uàÏŠŒ²¥oŸP,ã¦8(+{(š\‚J)æ}kŒné?op¡Œ®_@U<º°4Êßo‰ÔYÞ<ìaÁ ŸMˆ§õcDÏSÆ)ÃêNiñZMEèG5­:—ÜüÂ.Ì{á¥Åu[R½Q0È›®iÔú#ÅU·@„ñ`lˆ-gb”Ŭ\ÏŽXIP'°(Gý³»`š˜º„€B@BÖ&íOrÒKn°ÉŽ‡{ûgÕ.V­„Ó
+.^7=º6Š2#0 Ÿ“8uGzƒ)?&¯~Ó&Î^
+)׆þ®ì¸}Ÿð‘„¨ÍŽà”ÿâMµ3ëîDþþF·X#›Vx„¥Šš9—ÅÁ¨¢S@§¾Õ§+Öf.;™•óÛtÆçÕÍ&…¸eýÁˆQ³ý Qi†•hOr{jY%ÙJw¯ÂT„—lFt{¸ö81÷(Â¥…ô¶äÃÊòûb2ÒJ8cá”ˈÒbÁÀm¼J&­Z‚A
+Õ!R3|´î|ܽ$uà×­GY‚œ æ{Âx¡  ~.œú&[qæfôð†hZ³O D_‰Ã`z™7ÊMìòMA•WsÕ [ž„væsÅÜ!ƒØ^ZÉ»‘wïFÞVeGò‚\l¹ÑS\Ÿeæ"þÌDnÚ‘15Nôz{ƒ¸Yów0[° ukz?¡Þì%¥
+Ü0†Ç/OLj[É|Z«×Ûž<Òí°4ûº ·Dɇvk5A´oã ÌtAÔ”
+çHBžO+Ú‚ÄîóÎ"«g,Ç}õS?3Ù³”“´§+Ôö·V¥+ÂÜÖ/'Ên³÷^ö/€Õ…Óÿ곕µ°€ùÙ?"0ÁAÉÃ\(à-ŸÍ¹À/¾7mù±y}ýÔm“ýmùkìµ4#±$ß”
+¢0ÓžœÇ‹·z´RÒCfwMÎ-‡Ý ’օʹºwvE:…n6OAÆR . ½Ã Kæÿ>©´‹™Ü¾hiÓn#Ç*ëÈÎ^ª ‹{n„œƒ|Q‹évÝ 5¼ã›ènB uv%ò9{d|ÞQP>CöŽŠß$qˆÒÊšÙ8”Ç­š¥«­u#Õ¸)«Û×¼¡ëSœiQ¡zJõÏA*tµÓ¦¤§ 3;Ûtès-|b~0~B-Z)ñBšª©*·?ƒæ–+[L’0o!ìÆ»UÕ‹B"Œ¾ªÏ5jdÝi·©dVéc]Ð[æa÷Ú(i³ ¿=ב;†L íu߆+YÙÔ¯jÒðoAs-á÷!Þ;ýÈž8íöêš«Î~à 0 À„
+Œè†²}­°[^­ÄÊ"<TÞØ€êä£jÈq˜`iNe“äR'l¡' Iß<N³NK×?‚ÿ’Œé ªOŒÓœÅçÖ“© <À ½2a´/êZkДv{²Y–Ú¹¡u©¡ BÍøÒŸnN;‘ÌøÈ¢+ä¼ÖοyKO€|DÛ/à5€" /‰)‰‰•ˆ½~» |fkYѵ7³C¥¼°´s›Ôªó`(4_çÏ‚5ܯ3·ªôF3eê)¼õ®#Ù —°mÀâÜ ‹¯aÍ—ó¿O(2Wr'ž~ÀU‘,ã€
++
+Brãx­€V¿…{x=p m9‡ãCäb Á¼lº•ùWß Ç¸(Nn@¬vt&4Å03§Ø=: ËI{ñ·A
+º¶ãúv$.yûK®¶”Pï By-½Ñ‚ý·¤[€¼?.à~ØŸ)¹aynË"ª ïèQóVQ"WñÈvö(W«pßè‚U‰ª™0U7šùœçá.¸½Ns˜ÜïKQÁzbžü™
+ó½ýÙ ÍËF£jkN°3½WäfÜÁ)8+í':º/¨%²+žG%$Åw·í=¾tÀÜ~ÆéÁúäi*¨ÐuÙ>lû2{†X’GVM"¹ï§¿äØÞóŠ-I¦./q*#Ú-ÍÌûS­n®Þ~¿5f58O&Ó=ƒSµ@·ŒVÓÃܧçOPkÓÿ hÙ)&ÒªîÏWfzv,Þ6ì,Ïp¸êÉã7­ ‡ixÔÆ­SÆ;Øc¹}¤ÛUŸV¼ðœxç.»wQ~ßÓJ3CÙNcYB»Ñƒ¤3Æ›õ?­ÔæuÅXŽÝʇÌ®þÈ}‹b×"¼ô)ÿÆ;Ñ€¤ˆÍ
+Ú‚+m.'ª®ãæáLVò ÊacL-À³…KË+@±ù~àI mªÎw3$‰/pKx÷ÛNìv þB ͽ2ÛÏA‹É]`Kmâd¹êuW‡¶oŠ\ˆ©/QÙî„„!'Ìqzî¿æÞ`rŒjéÒÍd‹ß”¥
+¹•úÑÅ0v ñ>R0Þ{W8ý34®H‘ó£îH±±­
+—0oj+tóH*ßj<šÊ¡ÁYzdÍ¿f1hJãg<+ïa??Â…VMQ·IŠ´Ö`ÁÖK)²jâ‚·8óK×…
+t‚i]ÕܹQ7•¬¶">ø'2cq’ÅuE}sÀ£e9L&„MrÐ`yOCÀ´ó'{›HPO˜ÒoÅø8ì»n·Šš¹Î1è˜(]zš¦ÊÜ÷ŒDÈQ–Í’>¸iŒYñvÃ×LT%ù+0&—¢1BµUkæÞê«–Ì«l
+¶Û2g§yö$®ö*Îæøe"'WèÖ£“C N1.-ÖsÛòQí5rJ÷ÛYAQ&¢V1R7Œ¾'NI,Ÿ*˜å~Ƶ”›~÷Úrò9!ˆcV†aCPµO;;PÝÌå³(t>ƒ ¯ì~0Óâ&ý¥tdW)T?&ÔzISÆ—µ Ñéô9óóŒl|—T¶·ô¤+NÓÄn“4üÑ«#éÜ‘ñÑÄüÁÉ֕aã_.›+A¯@™øêSÈ3•'üp‡IøÐÌySzùO ‡´æìÍ®¼Ck;ë2O3Ô‰áy/sT²—»ŸŸhŸúĈäomg…Zˆ­‰fº9ðþÒnjĹ.&i&ß7AŸÀ’\aö(±V­J¸ãnÔœm> ØŸ) þêy…ñålkMO¸éX8VEdàŸs][» NÆoñ3F_ 4å`}†v,ïˆnd ‚ì’تLÚB+;1‹h²QÀú·î´¢f)²kß8OÒ# õ:‰É°*NøG0Úðž{Ï·¸Gâ3]ÒB]ÝãŸeõÊUút–Zä¡ÛQ*He'3u}š&ºaVÙ0nÂ_å · Ø5J泧Þ;R~&ôc5Æ¥:3…/ïì&Ó¢.AðáÁÎƸÃÄžR¿nÈ€¦ã~E2Kâèš”¾³klÌM"÷mkòù¶Bˆ)™öøï¿¿ÓIF{/õð·לuù[Š“‹ÜhV¥<õ!1QÏG)9ì(Å¥ ÒtM ËëqÌõþ¸]%tƒP]¦ûtàÆ&Ks:!lg‡€†)®7ì,èøÔ:Åaäæá·ãäQùÔò=•ÃýnÙ,×À­¼kZ^IºgàÁô.uQ³÷ },Œz“¸»•dA@{â^@±ÝƒžÅ&ýþ°Æ¹rVL*ç‹jïRf§ž¦|ú¦ØhwFjPÜ{tnã𠞸Â1LM‰ðg6þ>¬€ä¨è!³ßO’N·3PsÞvz¤' W›Bb×÷d•ª;ì;Ъ"j7Ž”‹98ô©å,³ÑÕ4ÛÕ-뀌éÂçË+[ã®fΠ´=5"ëO_Z§ÝQýJå÷# ;~Æ×:¦ùOuP2Ãþû9¿™Úã†ß°q¸D’!ˆñÛü"Np G“ó TI¹Düˆmu áê°q¤boówH/Xâ¼¹vbh™‚79}Øži• 0!5mù'p¸ªŒÍ-ÖЗXéçQdrîá•fè÷ëåÞ1ŸdÅ˛Σã…ê(?ÞOCüUd;â±ñ.&- ÆÍ á©UÃ&ÄlÈQ¶œFWü ÊîG˜ç;!:XV†à Ž«¦g.šÆÌ" ƒâÝ`”Âp¼](G¦•|ªf?„ËÄŒjݬ~h2w|¶A™¿îÇ숚ˆ‘u #S0g0XÌŠo æ< ~°fC1å¹TËI€I¯v8ì{0®BôÂPœŽì>@;QÐÃ'‡³ †êÉ2$¢b(ŸÜ~¦r Ž}žjÈê 6G\æ«ëVáÃðšOD©h#Œir ~7úsaóÊÀ?Ô³©§²ÆÍ9Õܯ»
+%*RŠ 8$ ²Bí¦®ä[D¥ªÝ«ÔGÆ;üÑh<®^‰¨´ÑE—@$|ûÈ89O\2¾ãw3ÆRæò…iŠR)ÇäN(˜$ âBd ±ÈÔ: ¤cCœšÒ
+БQöw>}N·>¢Z[@ß HÀ—ÞäN—÷“$wŽp»X0õ•Äƒ<±´Áí¼sÎ*`<Ñú¶øAF‹/©
+¦£Ò턳`à*ùê™>÷)›td¾ñlË•]“î×=í
+9l¿»YªjËŠÍa™°Tt÷W.™”Õ>/žú„ VݪdspÏ#¸îú§+^üƺ§h¥ÔS-b©\LÔåg› llª¦¢,#Un¥`ÙD2ïÑw^´îWƒ…jžÚòHƒ,ߣ4i´Ø$ƒšš4œ¤c„\œÐ9˜n³žK=F™•S'a&È6cS4 EV×#ž°Nšy’ QN¦]ˆ‚{4)gáŠÈZó±ñëÛ¢¸$¶§”tÖ©ç< K·fÐ2o„mê„‘iª:Ï”)Ðö¬ ×ø,m/@=ÉFËi‚tÖ²$Q."]å+&•²jjÄD™Þ}Û­n38e(Ö²õ²·™s,ÒõáÙĽëÃîñ¦Öà#”
+, kÉ÷´éhÏ·.rLgâ×hž„—pZ??ÎË;@·aQÞ¦fÍ‘Á£˜ÁüÒ,_g+õÇDê–[ÖË`lƒÿmjC“½ µ‰¹ñ•«ßyÁÙUe°M ©P21=ÑAC6R²ãxÖ¢Ó»ÌiI˜µnþ¡twÙW|$Ø©Ýv;Œ4âcƒäy.,üôFÖm@Ë1›ÚÜÒS½V%¥ òN)®#ò÷~H}ç†/œ¶C<ZÅ-#©óô;=Ôg…æÙVÝæ<T³4ä5ªhš íIRaت¹iýjÕ{Í!Á
+ÛhÆ‚p!Þ 7©ÃïsíÝ!³Vðû”Sr«­r ÏýØÛ 6ç¼ÓÆÐè Y2f@Þ#'G*)†ó¬£sHj†AvÙøÖ£œw›ú<K%}9©CLû2Ý~a…z
+¿zN@â{äye‰z•¢tø8h(òD¬LnbDw•i±Ž™1·mq±’™Õà‰¼V¡ØY`Ta}Võ–«Ô+@<‚wàGô*”Ú3·†™èÊ×ZO@X@eúåé3Ÿ!U›£×øª·ü|Nú‚,=[ÑLšH2ŸH÷’3?2Ã<ú1øŒÞ|/ÂM'6¹ÄÂæÚÎ[»Õš¾{/".¤´oIÁ®x¨tw!g;ëÙM|@j²†l»¼!9û–ƒ
+ ’â;ŒºÓ/I}hŠb@xž¹ß£vÿ¨É•BxÞk_Î(7Œ˜
+—M±ñdr%´/™&HñæQÕ´+ y–›=PÎ3këЗìº;KNrÉ CMH°è-ª»Êìü9!… [ZÖ´DvI—4ê!\†Cj.©­eœ’ 0
+ÂJY†Z†ûš|ý4-¼©‡ôÄÖ/äNø&vL‰¸y)û÷oæéÆ¡s¨Fâ²JJ–à!`²K-TîÍ$\ \8fÇ®Ÿ™ºˆ¤]z‹9L9‘Ïÿö4ÆðÞ/Tþ&š¥ëÕŽÛîäHŒ7ýø1ô°’ë{ÇnŽrbÍ¤à„©7ëã!ÀÎ|#^ìñ›C§.Öçì1Ê"‰ >B÷‹=^Õäìb—bu/ÙÒXÄ‚™Oå§kY‚O)™:&Bç|i¿ôÚ¸rŽ:7q.8VJG±Ú–=
+¼œggÍMÛR9éà½Ù»T¿Ø6žft»@ã.‡±v¸g8ËÃ7ÖÇËñˆùƒs‡@JE¢ ÌL‡²¾ì§£é-ø?ÝÉ8݇uÊ I·ï*"3 Ò÷ËVA¬¢Õ- ¡Z"ÞÆmU{/)tŽÎ›ð?KŸä~_†ÜÙš Ö¶lâ’¡n˲aþq+—ôú¨¤ë1æo/+žQTËq&ÕHdn„Ô¾u ˜Ñ­-ëMåÇ‘sÿÉÅ™[tœ¼¨øµŸÀÄíÞ®ßPx|òúËüá‘æ/¨-epsƒÛ;ʽQÊeŽÍYszgÏLf²Ê%—â
+‡3¾•þ4¡´°Ç4s©Ó(œ#qp6ß ïȈLÞè¹xÌ9ÿ*Ͻ-+\NÆ"ìÊלý 4±ëè“B»5ýû/VQO‰Aüp ÈÄ@ˆtö·­ã*EÕV0µ¬7Vn¸¨bÍ[u?¹CöuJ4,Òk|_Ë­|Ïë2•`k”äÅhÅEdÔ<üÉgÁÛ{Ôrä5ø‹›o{Ÿ¬cy¯£ÓJ¥Ò/âðÉÞ28Ê8®9!úzÕP“¤¨x÷6`1©ÖÝ`¯îOzó€Xú8jvƒXq¢™°£»kÌí²¶¡‰2D¾ß•‰”uaôBAwõúà ‰¿
+€ÞŸ|æ`xFÎärãiwÍBÄt·Ñ9”kE‡-ñL¡•´]^`ƒ|ðv?B@ÕÚ,eç¼oì.9‚¿‡ú‚8ÛƒïûÝ
+2h°Ø‹­ˆÓçBJ6 rD÷ öy@hÓ©A˜orÉbo»­]hdçb;é^ûxw^c»{$¯öw÷ª(:©]Bæ?0B¨Zt=qsŽ»_ý¾$UÎö×ÐíT! vMIöM»ªéKk¦øy"Óî“hŸQ¨¿tHg½Å#v³ Ë¢¹(^Ë×"F¸Cáß Úï~µÍO[ŸåÇ•ÖZ²Æ~!íg‚dö¯hÙ¿¿«ðÉ×_j¼ºÞÑñ¯EAåƒß€MŽ›_ô?¸M¼½Ñ¹t~ŒÜ+ì SVáu¤T…r©¡l®¥Uƒ0P;Þ‡™OØ~uLáÑwöÞ5gL›É+Êj/1ˆwv_›Æª¥µ[þ±žœh…{eóåa"ë‡
+É5w½‚'☺²¡tg‚ÉGѺÐäQ`Æ9vÉlpúÿÖ§ÿ¢^ʆÁ.¸7%Ò` ã±¬Fœ}a<õŽÞµªž2Ȇ´h¶”RÒ`k‰ÉÓUúÞê¤/˜÷¢ú¹«É«¿ð\”)$q‘1)Û
+ !˜s¥8cs;ªÄj­ÌÜfºô#·Ãÿg:‘s2$Œ©ˆ×6'?^1„4=Wk¯^éßÈsê&Ù¸e;ìðìÐégªA¬½Ù¢vXþ]ïz¿Y¬ÍrôÞ=
+ Þ?”XÉÙTVà†Q¢›‚3=A(ÊŒ®?Ît??xnkà1›Ô›ÔÚ äŸA`ã×0滬²tôŠ¡Œ»*!ÂFë¾ÈÕÁ(»L lô-eFf×Å
+§,Éù¾Nª„8’sŽ±©U WSi—³¶,keõ%ï"‚×cQ:Á`c„†3p› Ò£ïט vv„_Y†)„A(@n`'7)$P²tJíòkÓp? ¨OÝï°¸>ózäö o"DXÓº3Êlª‘ûÁ†êÙKß±6ÎÀš9ŒÌ9‘ 寧«Ÿ#Áâw©üljœ]rlXÀfñêjéÙÖ ˆ¹œqwLLCÖŽ¯ËAŒÍƒ•è­0|¦·Ý¢fZ/Ç
+qH {ÃŽÆ¡I<Ü“QvÏÍ ‚TD†¶ßûu|s˜ÙöoÜœ¼ •ÁáÊË—1™­.·óüe|î÷œzzE<wèÙÀ
+L¦zRŠÑФtÔļaÇ;újwÛ³
+ž‘ÊòüÂœNBMßL¢váKÀ$¸èŽ`e2s®5‚}ا:Yo
+} v³m"ä¿â¶O›‘%)6HMí°uÉ]²GTšëseZ,Áa‡ýft{ñ«èÉÀ¡?*Xù å¥}’lºâç0íùË·=öâoÆ,˜ÂpÈ~“ œ¬L+̯Ú÷;Õ½²?¹®$Ó wï¤Á,í`ô‚
+ÍøƒRëOIz6¥K1#:­¥¬ìÃ4›çTPb§qø/:ÙsÉém½ É*Ácîowæ\·‡t‰Èâ’D…>Ý³Ý U1d•1°Æ½™Ä<‚Ǩ‹Ç/œapbÑþ?íÌ÷?
+eËè2R¼ÄûÛûyŸ?à ·Cžtж‰ä€¢rªØt°W¨ÂÃ^Ã>
+ŒÙí?ÄSËÜ·7 ¦Mwv½ r#aCp ÑÁ¤»Ê«Z²â™×?åYó›j‚foM¤Ž¾ïhWò÷%Ñq.4ƒ5ÍÞóŒ®:žªFï€uI|Òxóstóår}¤‘(º…íOëËD›ïö0C³Xò™Ï­mtý#¿#/OÙÉU5ƒ|¦ðžË%åOŸ8+‡!ðÕÈïÆÄ»Þpi¯ÏÊ*ÓK(’èÛ¾½ÙR„n9 ½i3Í“~i/]L‰ÙA•+®ƒ¬-ãÐúˆ¿”X£Ôëë"M3µ°hónf;ñˆYþÒ$qW½ÒG_¹jcR2š×»‹7¨Š}r ¼áègJ?%Lë9bBú<–ŽÌ&f·´È’Mµ½>ºç|lÙQs-
+Ï7û1'»öoσAü¬¸²a«Í¡K-é¢äþ{." xÊDï ùÐæI~˹G=Ö±?‚§>Èyüñ°“NÐ%îIß×µ¿è4É^)Oïä¥ç¾®ÁÉ’F°³¥1ŽžzÓ€SÚóJîi¸g_ ~`ñ›1E!ûŽ±Ö]Óhcotí¿AàçUpö„ß*&"-š{~gò&ú{ …rO]ÉOœ…È”[‰„î£-•;J×VAЊü$JJX&Ê×"é 5
+¼ØñÆV¼_±  ’™c€AÆ
+€~g´¦™L#ZeöܬðrF
+¨ì¿öžÓpÇ£†äH¶Õ2Señϵt(å¶õOÖt†Ò[ \„¢73}ñƒça-ø{û9…Ô8‚Ãõa8K<ªä-™£UÍZˆjzìɲ¦Omuã–‹
+|BÖÝB|kæZÄ@ºÛt7B5úÿü¥/Òµ׃1šòò‚Æû±®¸—ÜQZÖ¿S^©Àþz?§â7*¬UÌ‘Ž´Á9a¸|ø2DyúQZg‰?D[á4m|‚B–*õ¹÷kîìDRºÚ0„¾ýç–É­wó~ýØÒPÇü>?
+»ë~÷aœ¿nïOÝp}ê#Æ)f’’¦„?BË`„ú ~R(hà'Ùç¾óì ØÉ»žOÛšù.»ûe<™“1êÌÇÒïÒÂfÔÕóÏ“¤òÞ!°(íTLÈÃÖ¥råúDÌ|–ÐÅ8Gä|}¥|è+ÏTPDpƒˆíJN5ª,»sa}èàÝ!/ÿhEî:±‰–ÂÖuL¥èmzÍŒÈ%áØß+pJ^‚…®Ù†V§óÕ7ƒ° 3¡‘ áâ9zU¯Ì…‰ò;é–Ÿ·(Nâ°­|&=×ÝÉEr4GîÇ4ê˽/Vñùén :,'劘ʕc(x^µ@$<B'Ϙ½23n
+ͬm wðôš].{aëyjø0}ïuÁ¸lƒÁ'ŽC»£"éƒíK±Ú¢@=Ñ~ºÈµÔÁ'pî,¿,Çî×/¶'™¯æµ‘Ʊiá«‘ œGäÂôÞtµoyOYú÷zšH™
+ŠwêˆVM¤¬Èôv£äGÓtøu #£yå\x¦CžšƒÇŸÇ˜ZçU.æ@ÈÄôÄe²˜=æ÷ÉáyÜuù^é"HÄÇ׬íôœ™Í ®h;@‰¦$ˆ;ï¼ã>ÛL‰†¸æVìP¤ýÄJÍÏD{¤>pV$QJ¬©ô=˜Ð9 Úp€Õâ«ùD¤å0ù_‡b>éRêVtÃÖ ÄM
+Úð­,6äX€qÐ-}nJ®k^¨£ô@l€¼ÜI>Œ˜×TqÅOшتxín°úâ…õµ4JÌäÅV kw¨Š‘þI’€¥¤\°^0Vò˘íep«%"h* ê mQôB±Ýë“ÙÏXšEÿ¶Éµú0üöA•ÚªÏPbÑËöê6EL7‹:Æ6
+ϥ
+mŽ[A±Ræ¦ØíŸeµ1£¿YÝÒ~kð¢|Xžë,|@î~èÒ<¦maöè“žÉGJPòíRWù˜ž ‰P ŠïMÏÜ£Ëÿx½qì’‡î“ü\Ÿ,³›}ÛÃë½E#û¼ÐÄ!áosA8G'Ñ´2›_ð‹¿Ào8V  qqML2ÔËÜIVœmá\©ü:’P -wÇrµ? ²T§‹ÏlKðKáJì}Z%=|Ó˜~¹´ê¡¿QL-jÅ¿Vq†/¥ökåàM×±Û÷a”÷1•£Ôq/dWµ8à UnˆÇrÉ•Ü “6ŸùÙ¥»R̓AczCËSåã§
endobj
-935 0 obj <<
+940 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 33
/LastChar 125
-/Widths 2132 0 R
-/BaseFont /MYZKVY+NimbusMonL-Regu
-/FontDescriptor 933 0 R
+/Widths 2154 0 R
+/BaseFont /RMTOSX+NimbusMonL-Regu
+/FontDescriptor 938 0 R
>> endobj
-933 0 obj <<
+938 0 obj <<
/Ascent 625
/CapHeight 557
/Descent -147
-/FontName /MYZKVY+NimbusMonL-Regu
+/FontName /RMTOSX+NimbusMonL-Regu
/ItalicAngle 0
/StemV 41
/XHeight 426
/FontBBox [-12 -237 650 811]
/Flags 4
/CharSet (/exclam/quotedbl/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright)
-/FontFile 934 0 R
+/FontFile 939 0 R
>> endobj
-2132 0 obj
+2154 0 obj
[600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
endobj
-894 0 obj <<
+899 0 obj <<
/Length1 1620
/Length2 20127
/Length3 532
@@ -10194,7 +10340,7 @@ endobj
/Filter /FlateDecode
>>
stream
-xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<
+xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<
šþô­¯œtGLz¥ÈéQž7K²;P?8˜Õö¦””õJ>`ˆg:Yánžiü(\
ü°¾<Ù£ø§6Äbw¡5aÔž_|M<}~¢î½…î?$¤Ë‰…§äuBþéçC(øC­B¼ªùÕi{Ju ¡glŸÏÏìC(»ƒ¢ÈbÓËZÁçjð§fÌÁpC@¶
¦éÂú”/é„ÐaF)¹ìÉT_Äü AÇDF@’_²– z¿IÂ>^"ò“£œŸpÖj×Ñm¡HNZ¬¹Šù—;Ão{ô«OŠ—©š}¾ŽÈïqM gÀÁõ@‰Î
@@ -10268,35 +10414,35 @@ K› ÀöYt^¬evQ&57Ñ„t9Æ©‘;ØQLV2²ûËI2­U^¹¨%Ô~ŸŒ×ˆzW
p
íSß»bò7+֘ߠáænÍwˆ'£#µE°nx‹¢PšL~|ö4KQ¦–!¯jn£ÕªîØãVBGE”}œœ Žý­Ð{ƒéV³”Vã0¾ô.¶Tv‚Ì|` °SU[¸U!&ýø7 >hI£YÉì0…òÇ*껪¦úݳj€í¨ž¨ß`Ù?8sGx9g3ÎîèñÙt÷:n:—SúluHx‹œ›ÍÉPo·«ÃJAüÕh€ß¾ÅW'ˆÃô´B ¶q…¡Jˆ`“ý kaæ®´bg>–MO”¶æB8uk—ÄþÙ7)Çê®Ü¿5GVQ(ë¿P­m-FG*åTA¸¡WK2z)· Ž×?3Ì›QOl
-¹ƒ%ÔÕÝÙêjýákáüendstream
+¹ƒ%ÔÕÝÙêjýM>â endstream
endobj
-895 0 obj <<
+900 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 2
/LastChar 151
-/Widths 2133 0 R
-/BaseFont /EUFTTG+URWPalladioL-Ital
-/FontDescriptor 893 0 R
+/Widths 2155 0 R
+/BaseFont /FKTXQR+URWPalladioL-Ital
+/FontDescriptor 898 0 R
>> endobj
-893 0 obj <<
+898 0 obj <<
/Ascent 722
/CapHeight 693
/Descent -261
-/FontName /EUFTTG+URWPalladioL-Ital
+/FontName /FKTXQR+URWPalladioL-Ital
/ItalicAngle -9.5
/StemV 78
/XHeight 482
/FontBBox [-170 -305 1010 941]
/Flags 4
/CharSet (/fi/fl/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/emdash)
-/FontFile 894 0 R
+/FontFile 899 0 R
>> endobj
-2133 0 obj
+2155 0 obj
[528 545 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 722 611 667 778 611 556 722 778 333 0 667 556 944 778 778 611 778 667 556 611 778 722 944 722 667 667 0 0 0 0 0 0 444 463 407 500 389 278 500 500 278 0 444 278 778 556 444 500 463 389 389 333 556 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 ]
endobj
-798 0 obj <<
+802 0 obj <<
/Length1 1630
/Length2 15892
/Length3 532
@@ -10307,7 +10453,7 @@ stream
xÚ¬¹cx¥]³-Ûv¯ØfǶm¯$+6:ìض“Žm;éØè°culãëç}ÏÞû\ûœ_çÛ¿Ö=kTªY£æ¼îûZ”¤ÊjŒ"æ¦@I{WFV&^€†ª–²‰­­‰9ÈAžQÕÁÎð×̉@I)æ 4q9Ø‹›¸yZ@s€8Ð ÀÆ`ýúõ+%@ÌÁÑËdiå
 ùËAKOÏð_–\
ø›UY\òßuºZ™¸þ“Ûô8Xüõ4w0sûgKÿÂþÒüE]M@ö.
-`abû·Wÿ²kØ›mAöÀ¿šþ«
+`abû·Wÿ²kØ›mAöÀ¿šþ«
™**À)—PHW£B¢ªU³m·WÛÔOrí]VÉ• $«ùqyĤ"õÂzŒf<0ëûë£Îðf}/Ÿí¤>bêFè,VØUd‹ÕƒæÔJlNÍo’©+¬OXÏ1Ï-¼§c-NÂ1ipÝ›í\AÖ
úêì`uvdé,RHžê$žkK‚>&Y ¤ºÛ”OØ&â„o™kâÆœm§Ù WëÙÉ
¨œ/û«Ð[BÒó´`Ûtä¯äÍN¿GfáĈHªýmVéDÇÏ“Ÿ”Ä÷¦Y_kÉóÍ+èü1pÇÒ¨åÁ³ñÂjD•jÊ
@@ -10369,35 +10515,35 @@ MIª\ÂuTØjGI-gýÂÓ–GâydføæÅxÃÃ,oÛ.رÌ*_ùSÕúƒóØCkëÚ™­¨·>]ÙrÿÅ:K¥ÓS%œx
¿n$rÝ XðD˜t ÎõÓ…”2§—n„sÞmOÆ„ ˆ;²ÃßshuåU9ñÖ&;y-sõP~K*ªÅz4rnp´}ª÷œõ)RB—+«å—>¢cI£Ž¹w× éhz€Ì\mm £MúHþ×<×|Ìï­&‰ Ÿw³s£Üë+\?VË´<=yò‹ØH»M'²ñÑ67Cøoí+A5x5½·x¯'_Ë
c!vÜ~óÓ4¶bIpµP]ãH^ŒúÀnkLßYßÙ„æÀ,•‰)tCœrÀ‘ Çi†Ï±m$hýÈn.ÿ¶»öO¿ªWÂ[–{OFChÓ'žWùÆ*6L‡1±’g^H]u Ââa3ð¸g@—TÕL_1@d7¾ùÁ“†µ‹Œ:…‘XF.ÿ§Òfb1\ÄñSÙ£Ö®TÁIS ÒŽã{9.´ v´ôPš_$ ƒºÃ™.T€Áj”¤RÚ.zàÂiXÎ^;-”ûkwå0HMKyÃûSc-‘tkâôk'a.*bí Û¶4ŠdÇ&ž*qÉŸX‡ÒÝÓä"c°4 *+9‚3£
cáE¢Lg%ãŸïÁó§KíÚï©=ëg‡~Q)œu‘Še7@ô`­¥¡c˜„s2¬ìe/ï´Ã÷5ØI*·[ÔrHîD4;"«hntRÉ´c¬¥ŸýÝ„u å{ÿÁØ }hë …
-¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þK
+¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þK
endobj
-799 0 obj <<
+803 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 40
/LastChar 90
-/Widths 2134 0 R
-/BaseFont /ODIXFB+URWPalladioL-Roma-Slant_167
-/FontDescriptor 797 0 R
+/Widths 2156 0 R
+/BaseFont /VADHEJ+URWPalladioL-Roma-Slant_167
+/FontDescriptor 801 0 R
>> endobj
-797 0 obj <<
+801 0 obj <<
/Ascent 715
/CapHeight 680
/Descent -282
-/FontName /ODIXFB+URWPalladioL-Roma-Slant_167
+/FontName /VADHEJ+URWPalladioL-Roma-Slant_167
/ItalicAngle -9
/StemV 84
/XHeight 469
/FontBBox [-166 -283 1021 943]
/Flags 4
/CharSet (/parenleft/parenright/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z)
-/FontFile 798 0 R
+/FontFile 802 0 R
>> endobj
-2134 0 obj
+2156 0 obj
[333 333 0 0 0 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 0 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ]
endobj
-736 0 obj <<
+740 0 obj <<
/Length1 862
/Length2 1251
/Length3 532
@@ -10406,46 +10552,45 @@ endobj
>>
stream
xÚíUkTgnõJÀ+Å€€¸
-æ2%X$-wTP¤2$H20I0@¹,P ‚A…ÊE ÒJi½
-& X¹ê
-ºè±KîþÚ³3æ}žç{¿gž÷;ç33ñô!8²‘ ØŠ ¤Nn>A2
-WJ}áesn0›'¬d™bˆÏc9
-ƒù0@
-Dƒ
-Z$eñaÖâÔÄ‹ì2AHAXæðŸ 2ÃPˆóaΟaë7ðòÐßᶡï
-Y¥8Ç9­=›™žáàîå÷…FÜá漤
+æ2@ Š&X4•;"(R’ $˜$ \(PÁ Bå"Pi¥´^€–‹ÁŠ‚g¹iL@°rÕtÐc—þÜýµggþÌû<Ï÷~Ï<ïwÎgfâáM ³‘ ØŠ ¤N®Þ‡@2
+¸"l®”úÂËæ\a6O"XÉ2ÅŸÇ¢ ƒù0@
+ø“‰d2ˆ ±÷ÝWÀŠÍ¾²6O P¨¶
+ ÅKg‹ÿ]Íáa#ƒa)ÌÂõv#,‡¤¼êäŠØ/Îßùá#’Ö˶Ju¯f³_ml>ãM=çi,.-V^=!LJ*ô¿d9œÒE¯d¸¥5]¢{ñjZQ¹_V<µ‰ØãLL“­yme>Ê”‡<]ðÒÖ„>:ûí¶í½ÓÛâÚtαUŒÃç绵7Zz´4Ýl×{AsàÃMøÈ'['kãònìdMܾïÂôÀ‹œÓÌGí ihö1.€¡PXyŽÐ[î©”ÇôÙóëÝÓ›ü¥OSMSÌž·z—KgÒb £»¦‰¿›:–Q<󵻮ɘq}àŽ<醒”¿·ÑØŨí‘5÷Õæ6+7Ù'ÁäAëU—Fj ÚCûüR¦¼Qin.‹}Q…Ôäïyþ}ýÎ9|F qõéCÏJëåÚÝõz î®{½N™/ µÜ:4Ò(®’«³²Zî‰1~xܦ£ûÎÞÒGñ‚t ¾ûÚ3 —á9¿ÖÈh<~=Œ¢e*ë²32ÿêà+æêòµ¢‹M¢’Kñc‰´þc`ÕÍÎ.ðj<ãHN,s’™¦—|-Æ‘ãí«,›7ÊêôzjÎÊä}:Æšýʬ(=…‰¬RÈãœÑžÍLÏðpóôÛ¯w¤9/)À=à¹ZÝ÷¢âYrvÇØ–„1_u2óDëËÁ «)Ѹ·6íRW©_Š¡y$|©ÁÑf¦@“^~v½Š©@rÚo2ü.èâ&gs£¦RÏýÃôeÜàï“ßo,
+!üm94¡ÜÚ—=7âjp²Œû\é^çP]flBìµ·Kê ‰À9¢²¤v嚧ø›Ö‡÷= ‡Çe 3ñÐÐu/—]qÐNH¨¹.[( ™Ý¡¡9ÿ¬TL [¨Ÿzd€kz·îØ3ù±ö寑S;~RS,%­ßÕ`>˜®öÙô&óàó†~î'¡ÓõS¿
+Ï›?:¬>®r—õÉ/ã>Ìo”þ øý/C¥“áëó¯Ý’_“ ­­ý·Šl©Šc'•×+oŒIn:˜ËHÊÛŸ„3YlÿÒ<ß‹?ªÝ#YWT«š{êæSE aÐ=EÕ§´y”óÌy¼Âa²²ÔŸö¹÷¾_ã¨bÎIú‹¿Ÿ"½Iì~¡Q×*5*óeT¥LM—hµ¾Ùê‘Õ>ä>¨'›³²dPª×Hö5€4ûÝý†;öpæ.ü&µoY7î«HŒ¶×ñ
+ntÂY~¬óôç»Í»_sóŸ׈N‘1ð‰ëüï«V©Ô§Âh÷åcĺ´ ¿ºí*T¦$ÏGlɺÞX±ë`³Ù»å¡Ýñ ³M¯-TßfVy˜®6.î[(©Û†‹Õ‘ÄÛË\Ãõ £4ÖÄçE ás]’œ†Ü„7ù•(ræ“R¤Ø¯ÕF§_Ü}YÔ½Ž2j«i¸ó×TÇc]ëfîÞƒSë ec.ªUÑš}ºw;ËFu[jÙ»[n:† ѯiI‚ømš?/È7€„þyéš36“œô€ñî‚íú†ë²ö’8||XÓ<þ õáìVÏAÛñ©l=¿éS x}ÞäÇo¢ŽªFü׆þÒ×¢¯ª«;zº³+Ù7ÖÅt®]šrF9µqg{7áÄ®l÷ÇÌ“}_2\ÎhôÏɵV'•Ç²;BêmиC’ž˜l/^·`m`onçòøàþßà¢vuC¨@h(î_Û-þRendstream
endobj
-737 0 obj <<
+741 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2135 0 R
+/Encoding 2157 0 R
/FirstChar 13
/LastChar 110
-/Widths 2136 0 R
-/BaseFont /QQRSYH+CMSY10
-/FontDescriptor 735 0 R
+/Widths 2158 0 R
+/BaseFont /BFRUCK+CMSY10
+/FontDescriptor 739 0 R
>> endobj
-735 0 obj <<
+739 0 obj <<
/Ascent 750
/CapHeight 683
/Descent -194
-/FontName /QQRSYH+CMSY10
+/FontName /BFRUCK+CMSY10
/ItalicAngle -14.035
/StemV 85
/XHeight 431
/FontBBox [-29 -960 1116 775]
/Flags 4
/CharSet (/circlecopyrt/bullet/braceleft/braceright/bar/backslash)
-/FontFile 736 0 R
+/FontFile 740 0 R
>> endobj
-2136 0 obj
+2158 0 obj
[1000 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278 0 0 0 500 ]
endobj
-2135 0 obj <<
+2157 0 obj <<
/Type /Encoding
/Differences [ 0 /.notdef 13/circlecopyrt 14/.notdef 15/bullet 16/.notdef 102/braceleft/braceright 104/.notdef 106/bar 107/.notdef 110/backslash 111/.notdef]
>> endobj
-733 0 obj <<
+737 0 obj <<
/Length1 1616
/Length2 25334
/Length3 532
@@ -10453,7 +10598,7 @@ endobj
/Filter /FlateDecode
>>
stream
-xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdU
+xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdU
üPˆŸìá|ŒRbQ»š€ê
ÏÎIOžŸÈ†ÆGG†{oÁú°©rb’p¹€Â’FúýÊÁæÓT©©jUmÛëÕb3ô]ÿ””sÂ
Îl~^õ­H¹²çŸÈôÿbاÑÙ®ï岞ÒæNHÙ ™C ½‰h1R^iC«ÙÂ{»AùÖˆqwÛÁxyÒWcÁ·ÿ¡y÷'‡—ÁOéTñ´šŸ­wôêuòÓsPMTUËçýNÀ(5±†ÅÄ ö¶‘ÛMüc,‚¨×]EI[™Y… ¸îˆ0^ ÆMÏm}™× Ë 3ž@óÉ ª0öGƺ°>KÛyE‡“åÜTh6þÁØŸøÐJ¢w¢§æ_[c ³öB8xÕ¾Vk”Ô‚—I¯¿ä„÷gÞk‰òŒ+(}‘²Å+åýdä„P9Œ,U•äD¡&w("Z·´U¾D£|yÛ)Õ‚þ0ŽÖ)¹` Á6l¬NÒµ½žŒÍ&²˜ W
@@ -10547,35 +10692,35 @@ A™âõ2ѶŠŸÓ¶Äøí÷w6Ê+–IºÓœnµq×oúWïkN)ï‡mÖ8/1aÀÈ[­ø'! ´ŒÄPxÉ¢rB<–ðœØEÔ?Pr|7°™2
­u|Ðí8t^ˆš/€‹MÝp­_’<{*ñ>Jn ÐÅ—6¹s²R¯aÆ‹úr×€]9ä¯:²(`\‰áÉlA7¾ĦK”ž·†9z8nb64Ë¢jE¢$µ1V|·ZBËÐöX#Y»ͪföWßqYûlf/ö»­8Fj…›ë_X1¡ÁèínÕ (N1©þ¢CÑð´ýÆ9(AÄEêÞ–«ôáÃÉ€ÖÜÑf}_¢£J¾:¤ íéJ$<ÂBÿˆSUÅöìMø›Yr¤˜¾ÃÈ×`Qíå?›Ù±VƒÝŽˆ½¸ÂˆÚÖñhÃÙƒXÔ‡7Ó¶,Í!Á•FÿÁEè^F ¸¯xÀÁ¦ÿàB*·ÛvªR&¤N<•ê`¢µ+çN¼é¬
g¤£Ê¾2f~mû„m}…i
'óP4I×¥ŸÐ?`b¬FH. ÷R}ÿÀ#] «iÀAñ7FÌÐ5øùq6O‰ Ç/êúWbõÑFåq-¢´ð §]xžök%˜Ã–td˜¯‘ŒÎ¼r¿
-ä&oH[œ¯A•9f
+ä&oH[œ¯A•9f
endobj
-734 0 obj <<
+738 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 2
/LastChar 216
-/Widths 2137 0 R
-/BaseFont /GSFITG+URWPalladioL-Roma
-/FontDescriptor 732 0 R
+/Widths 2159 0 R
+/BaseFont /MQLDYB+URWPalladioL-Roma
+/FontDescriptor 736 0 R
>> endobj
-732 0 obj <<
+736 0 obj <<
/Ascent 715
/CapHeight 680
/Descent -282
-/FontName /GSFITG+URWPalladioL-Roma
+/FontName /MQLDYB+URWPalladioL-Roma
/ItalicAngle 0
/StemV 84
/XHeight 469
/FontBBox [-166 -283 1021 943]
/Flags 4
/CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblright/endash/emdash/Oslash)
-/FontFile 733 0 R
+/FontFile 737 0 R
>> endobj
-2137 0 obj
+2159 0 obj
[605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 840 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 500 0 500 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 833 ]
endobj
-709 0 obj <<
+713 0 obj <<
/Length1 1614
/Length2 24766
/Length3 532
@@ -10583,7 +10728,7 @@ endobj
/Filter /FlateDecode
>>
stream
-xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:Me YuªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS
+xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:QqI%iiªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS
Šº%`¸3LŽ7)ü‰] üQHžíá|ÒâP»š
ÿ\%ý}þ54>:2Ü{Ú„M•IÊå
KåïƒÍ§©R!RÕDzÝžeÌ}øØ"œ³\ʤ!g?5íµ Îk“T $f}QìŒ}}œ7Ãë–aI­zQ£Ø`{1®ËÊ›¡9sõ‰ór5úË<#¤=ø…ˆ´±36…è4Ó+òŽÇ¾a‘Ïp:‰é"“|:[5P6“Ó<M`IÍÍÍLÕ‘˜‡‰ŠŒDa_gÁ¡Ãœá½]é–§ 9ç8sêÓšÆô e¬bô:miØ*N±«z|+hytHOÛV77Ùa‰
@@ -10682,528 +10827,535 @@ Iö×~pºóE¦f}^!˜tQ°Ù’‹ƒEäì>‰ n|'ÆV²5D9_äå‹7â̬FJvõ˜2È­ÛŒ’ý;Û£K¿>Z&ú‰Àš¤þØɉ,
y‘üP'càÜ^M#R°·ñÃ4 {LJ B«œ»×ën¾HïŸMc–9|þ*S5ïV®ñKãÁ“üvÚJ¦‰‡’à°áR‹ÁPKw©ä;ÉͳðåH-ºOÖ²ÉâØÉ*Wü—¼éýšö•p…+èó®a7AÔºº;˜âR·~4ÿÕ|S®‘mƒ®W•~ ©Ãâ‡}DL×WF5J‰åéØ|¨i÷>#\2®˜
šÒ30D”€`Ÿ†§¾ç4}&1xÒ¤Ö¥ ÎdP•Ý‹$ȾCO‡Ù’jÛvëö?`C&W'aÔCJ•I'sŠFðìM˼k©¡¨»°+X ŠcAÐÀ«á¥£ùr!<s%!ÈbˆÀNÑ* d3³Ê6†Ø0´+3ïÍNYÀ8îj•ÛP³7Þ¨VäÎc=$0€Ž9€òõ «£…WCÒ¸1å Ô²9L±ž±~óŸ –äWÚyüInÐäöÀ'¼I3 ú]`+ò7vÃÝ!’ÔËö—k«Zœ–(&4¨j„¸`é+àpôxÿÅë«SüWâ$åM7ƒ[IZÒýš®ê~‚VƒÍ:Ø\é«…Œ€Øy_à£öý
.ÈëÃ6‹û¯™ÅSßcŽ¾Q&É5 fd
-ön’“,6"”@K;\ÿŸÁüø¯
+ön’“,6"”@K;\ÿŸÁüø¯
endobj
-710 0 obj <<
+714 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2122 0 R
+/Encoding 2143 0 R
/FirstChar 2
/LastChar 151
-/Widths 2138 0 R
-/BaseFont /ZTEYNX+URWPalladioL-Bold
-/FontDescriptor 708 0 R
+/Widths 2160 0 R
+/BaseFont /FHJSLL+URWPalladioL-Bold
+/FontDescriptor 712 0 R
>> endobj
-708 0 obj <<
+712 0 obj <<
/Ascent 708
/CapHeight 672
/Descent -266
-/FontName /ZTEYNX+URWPalladioL-Bold
+/FontName /FHJSLL+URWPalladioL-Bold
/ItalicAngle 0
/StemV 123
/XHeight 471
/FontBBox [-152 -301 1000 935]
/Flags 4
/CharSet (/fi/fl/exclam/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/question/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash)
-/FontFile 709 0 R
+/FontFile 713 0 R
>> endobj
-2138 0 obj
+2160 0 obj
[611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 0 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 0 0 444 747 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 ]
endobj
-711 0 obj <<
+715 0 obj <<
/Type /Pages
/Count 6
-/Parent 2139 0 R
-/Kids [702 0 R 729 0 R 739 0 R 794 0 R 858 0 R 920 0 R]
+/Parent 2161 0 R
+/Kids [706 0 R 733 0 R 743 0 R 798 0 R 862 0 R 924 0 R]
>> endobj
-951 0 obj <<
+956 0 obj <<
/Type /Pages
/Count 6
-/Parent 2139 0 R
-/Kids [939 0 R 953 0 R 967 0 R 978 0 R 985 0 R 997 0 R]
+/Parent 2161 0 R
+/Kids [944 0 R 958 0 R 972 0 R 983 0 R 990 0 R 1002 0 R]
>> endobj
-1009 0 obj <<
+1014 0 obj <<
/Type /Pages
/Count 6
-/Parent 2139 0 R
-/Kids [1002 0 R 1011 0 R 1022 0 R 1030 0 R 1037 0 R 1043 0 R]
+/Parent 2161 0 R
+/Kids [1007 0 R 1016 0 R 1027 0 R 1035 0 R 1042 0 R 1048 0 R]
>> endobj
-1066 0 obj <<
+1071 0 obj <<
/Type /Pages
/Count 6
-/Parent 2139 0 R
-/Kids [1051 0 R 1073 0 R 1083 0 R 1088 0 R 1092 0 R 1099 0 R]
+/Parent 2161 0 R
+/Kids [1056 0 R 1078 0 R 1088 0 R 1093 0 R 1097 0 R 1104 0 R]
>> endobj
-1115 0 obj <<
+1120 0 obj <<
/Type /Pages
/Count 6
-/Parent 2139 0 R
-/Kids [1107 0 R 1118 0 R 1125 0 R 1130 0 R 1139 0 R 1146 0 R]
+/Parent 2161 0 R
+/Kids [1112 0 R 1123 0 R 1130 0 R 1135 0 R 1145 0 R 1151 0 R]
>> endobj
-1158 0 obj <<
+1161 0 obj <<
/Type /Pages
/Count 6
-/Parent 2139 0 R
-/Kids [1150 0 R 1161 0 R 1166 0 R 1174 0 R 1182 0 R 1191 0 R]
+/Parent 2161 0 R
+/Kids [1155 0 R 1163 0 R 1167 0 R 1177 0 R 1182 0 R 1190 0 R]
>> endobj
-1210 0 obj <<
+1206 0 obj <<
/Type /Pages
/Count 6
-/Parent 2140 0 R
-/Kids [1200 0 R 1212 0 R 1217 0 R 1223 0 R 1229 0 R 1233 0 R]
+/Parent 2162 0 R
+/Kids [1198 0 R 1208 0 R 1217 0 R 1228 0 R 1233 0 R 1239 0 R]
>> endobj
-1250 0 obj <<
+1248 0 obj <<
/Type /Pages
/Count 6
-/Parent 2140 0 R
-/Kids [1241 0 R 1252 0 R 1256 0 R 1260 0 R 1265 0 R 1271 0 R]
+/Parent 2162 0 R
+/Kids [1245 0 R 1250 0 R 1258 0 R 1268 0 R 1272 0 R 1276 0 R]
>> endobj
-1280 0 obj <<
+1285 0 obj <<
/Type /Pages
/Count 6
-/Parent 2140 0 R
-/Kids [1275 0 R 1282 0 R 1293 0 R 1297 0 R 1301 0 R 1311 0 R]
+/Parent 2162 0 R
+/Kids [1281 0 R 1288 0 R 1292 0 R 1298 0 R 1309 0 R 1313 0 R]
>> endobj
-1323 0 obj <<
+1325 0 obj <<
/Type /Pages
/Count 6
-/Parent 2140 0 R
-/Kids [1318 0 R 1325 0 R 1329 0 R 1333 0 R 1337 0 R 1345 0 R]
+/Parent 2162 0 R
+/Kids [1317 0 R 1328 0 R 1335 0 R 1340 0 R 1345 0 R 1349 0 R]
>> endobj
-1356 0 obj <<
+1359 0 obj <<
/Type /Pages
/Count 6
-/Parent 2140 0 R
-/Kids [1351 0 R 1358 0 R 1365 0 R 1372 0 R 1378 0 R 1390 0 R]
+/Parent 2162 0 R
+/Kids [1353 0 R 1361 0 R 1368 0 R 1374 0 R 1381 0 R 1388 0 R]
>> endobj
-1398 0 obj <<
+1401 0 obj <<
/Type /Pages
/Count 6
-/Parent 2140 0 R
-/Kids [1395 0 R 1400 0 R 1405 0 R 1413 0 R 1420 0 R 1425 0 R]
+/Parent 2162 0 R
+/Kids [1394 0 R 1404 0 R 1412 0 R 1416 0 R 1421 0 R 1428 0 R]
>> endobj
-1432 0 obj <<
+1440 0 obj <<
/Type /Pages
/Count 6
-/Parent 2141 0 R
-/Kids [1429 0 R 1434 0 R 1442 0 R 1449 0 R 1468 0 R 1482 0 R]
+/Parent 2163 0 R
+/Kids [1436 0 R 1442 0 R 1446 0 R 1450 0 R 1458 0 R 1465 0 R]
>> endobj
-1507 0 obj <<
+1497 0 obj <<
/Type /Pages
/Count 6
-/Parent 2141 0 R
-/Kids [1502 0 R 1509 0 R 1521 0 R 1525 0 R 1531 0 R 1541 0 R]
+/Parent 2163 0 R
+/Kids [1484 0 R 1499 0 R 1519 0 R 1525 0 R 1537 0 R 1541 0 R]
>> endobj
-1560 0 obj <<
+1556 0 obj <<
/Type /Pages
/Count 6
-/Parent 2141 0 R
-/Kids [1553 0 R 1562 0 R 1569 0 R 1577 0 R 1585 0 R 1594 0 R]
+/Parent 2163 0 R
+/Kids [1547 0 R 1558 0 R 1570 0 R 1578 0 R 1586 0 R 1593 0 R]
>> endobj
-1611 0 obj <<
+1609 0 obj <<
/Type /Pages
/Count 6
-/Parent 2141 0 R
-/Kids [1604 0 R 1613 0 R 1617 0 R 1623 0 R 1634 0 R 1638 0 R]
+/Parent 2163 0 R
+/Kids [1602 0 R 1612 0 R 1619 0 R 1630 0 R 1634 0 R 1640 0 R]
>> endobj
-1652 0 obj <<
+1654 0 obj <<
/Type /Pages
/Count 6
-/Parent 2141 0 R
-/Kids [1642 0 R 1654 0 R 1658 0 R 1665 0 R 1675 0 R 1734 0 R]
+/Parent 2163 0 R
+/Kids [1651 0 R 1656 0 R 1660 0 R 1671 0 R 1675 0 R 1682 0 R]
>> endobj
-1843 0 obj <<
+1750 0 obj <<
/Type /Pages
/Count 6
-/Parent 2141 0 R
-/Kids [1790 0 R 1845 0 R 1879 0 R 1888 0 R 1894 0 R 1899 0 R]
+/Parent 2163 0 R
+/Kids [1692 0 R 1752 0 R 1808 0 R 1862 0 R 1896 0 R 1905 0 R]
>> endobj
-1907 0 obj <<
+1915 0 obj <<
/Type /Pages
/Count 6
-/Parent 2142 0 R
-/Kids [1903 0 R 1909 0 R 1920 0 R 1925 0 R 1937 0 R 1948 0 R]
+/Parent 2164 0 R
+/Kids [1911 0 R 1917 0 R 1921 0 R 1926 0 R 1937 0 R 1942 0 R]
>> endobj
-1966 0 obj <<
+1964 0 obj <<
/Type /Pages
/Count 6
-/Parent 2142 0 R
-/Kids [1955 0 R 1968 0 R 1972 0 R 1983 0 R 1989 0 R 1993 0 R]
+/Parent 2164 0 R
+/Kids [1954 0 R 1966 0 R 1973 0 R 1985 0 R 1989 0 R 2000 0 R]
>> endobj
-2012 0 obj <<
+2009 0 obj <<
/Type /Pages
/Count 6
-/Parent 2142 0 R
-/Kids [2001 0 R 2014 0 R 2023 0 R 2027 0 R 2039 0 R 2043 0 R]
+/Parent 2164 0 R
+/Kids [2006 0 R 2011 0 R 2017 0 R 2030 0 R 2040 0 R 2044 0 R]
>> endobj
2059 0 obj <<
/Type /Pages
/Count 6
-/Parent 2142 0 R
-/Kids [2050 0 R 2061 0 R 2066 0 R 2071 0 R 2081 0 R 2088 0 R]
+/Parent 2164 0 R
+/Kids [2056 0 R 2061 0 R 2067 0 R 2078 0 R 2083 0 R 2087 0 R]
>> endobj
-2102 0 obj <<
+2103 0 obj <<
/Type /Pages
-/Count 3
-/Parent 2142 0 R
-/Kids [2098 0 R 2104 0 R 2116 0 R]
+/Count 6
+/Parent 2164 0 R
+/Kids [2095 0 R 2105 0 R 2116 0 R 2121 0 R 2133 0 R 2139 0 R]
>> endobj
-2139 0 obj <<
+2161 0 obj <<
/Type /Pages
/Count 36
-/Parent 2143 0 R
-/Kids [711 0 R 951 0 R 1009 0 R 1066 0 R 1115 0 R 1158 0 R]
+/Parent 2165 0 R
+/Kids [715 0 R 956 0 R 1014 0 R 1071 0 R 1120 0 R 1161 0 R]
>> endobj
-2140 0 obj <<
+2162 0 obj <<
/Type /Pages
/Count 36
-/Parent 2143 0 R
-/Kids [1210 0 R 1250 0 R 1280 0 R 1323 0 R 1356 0 R 1398 0 R]
+/Parent 2165 0 R
+/Kids [1206 0 R 1248 0 R 1285 0 R 1325 0 R 1359 0 R 1401 0 R]
>> endobj
-2141 0 obj <<
+2163 0 obj <<
/Type /Pages
/Count 36
-/Parent 2143 0 R
-/Kids [1432 0 R 1507 0 R 1560 0 R 1611 0 R 1652 0 R 1843 0 R]
+/Parent 2165 0 R
+/Kids [1440 0 R 1497 0 R 1556 0 R 1609 0 R 1654 0 R 1750 0 R]
>> endobj
-2142 0 obj <<
+2164 0 obj <<
/Type /Pages
-/Count 27
-/Parent 2143 0 R
-/Kids [1907 0 R 1966 0 R 2012 0 R 2059 0 R 2102 0 R]
+/Count 30
+/Parent 2165 0 R
+/Kids [1915 0 R 1964 0 R 2009 0 R 2059 0 R 2103 0 R]
>> endobj
-2143 0 obj <<
+2165 0 obj <<
/Type /Pages
-/Count 135
-/Kids [2139 0 R 2140 0 R 2141 0 R 2142 0 R]
+/Count 138
+/Kids [2161 0 R 2162 0 R 2163 0 R 2164 0 R]
>> endobj
-2144 0 obj <<
+2166 0 obj <<
/Type /Outlines
/First 7 0 R
-/Last 647 0 R
+/Last 651 0 R
/Count 10
>> endobj
+703 0 obj <<
+/Title 704 0 R
+/A 701 0 R
+/Parent 651 0 R
+/Prev 699 0 R
+>> endobj
699 0 obj <<
/Title 700 0 R
/A 697 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 695 0 R
+/Next 703 0 R
>> endobj
695 0 obj <<
/Title 696 0 R
/A 693 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 691 0 R
/Next 699 0 R
>> endobj
691 0 obj <<
/Title 692 0 R
/A 689 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 687 0 R
/Next 695 0 R
>> endobj
687 0 obj <<
/Title 688 0 R
/A 685 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 683 0 R
/Next 691 0 R
>> endobj
683 0 obj <<
/Title 684 0 R
/A 681 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 679 0 R
/Next 687 0 R
>> endobj
679 0 obj <<
/Title 680 0 R
/A 677 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 675 0 R
/Next 683 0 R
>> endobj
675 0 obj <<
/Title 676 0 R
/A 673 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 671 0 R
/Next 679 0 R
>> endobj
671 0 obj <<
/Title 672 0 R
/A 669 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 667 0 R
/Next 675 0 R
>> endobj
667 0 obj <<
/Title 668 0 R
/A 665 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 663 0 R
/Next 671 0 R
>> endobj
663 0 obj <<
/Title 664 0 R
/A 661 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 659 0 R
/Next 667 0 R
>> endobj
659 0 obj <<
/Title 660 0 R
/A 657 0 R
-/Parent 647 0 R
+/Parent 651 0 R
/Prev 655 0 R
/Next 663 0 R
>> endobj
655 0 obj <<
/Title 656 0 R
/A 653 0 R
-/Parent 647 0 R
-/Prev 651 0 R
+/Parent 651 0 R
/Next 659 0 R
>> endobj
651 0 obj <<
/Title 652 0 R
/A 649 0 R
-/Parent 647 0 R
-/Next 655 0 R
+/Parent 2166 0 R
+/Prev 615 0 R
+/First 655 0 R
+/Last 703 0 R
+/Count -13
>> endobj
647 0 obj <<
/Title 648 0 R
/A 645 0 R
-/Parent 2144 0 R
-/Prev 611 0 R
-/First 651 0 R
-/Last 699 0 R
-/Count -13
+/Parent 635 0 R
+/Prev 643 0 R
>> endobj
643 0 obj <<
/Title 644 0 R
/A 641 0 R
-/Parent 631 0 R
+/Parent 635 0 R
/Prev 639 0 R
+/Next 647 0 R
>> endobj
639 0 obj <<
/Title 640 0 R
/A 637 0 R
-/Parent 631 0 R
-/Prev 635 0 R
+/Parent 635 0 R
/Next 643 0 R
>> endobj
635 0 obj <<
/Title 636 0 R
/A 633 0 R
-/Parent 631 0 R
-/Next 639 0 R
+/Parent 615 0 R
+/Prev 627 0 R
+/First 639 0 R
+/Last 647 0 R
+/Count -3
>> endobj
631 0 obj <<
/Title 632 0 R
/A 629 0 R
-/Parent 611 0 R
-/Prev 623 0 R
-/First 635 0 R
-/Last 643 0 R
-/Count -3
+/Parent 627 0 R
>> endobj
627 0 obj <<
/Title 628 0 R
/A 625 0 R
-/Parent 623 0 R
+/Parent 615 0 R
+/Prev 619 0 R
+/Next 635 0 R
+/First 631 0 R
+/Last 631 0 R
+/Count -1
>> endobj
623 0 obj <<
/Title 624 0 R
/A 621 0 R
-/Parent 611 0 R
-/Prev 615 0 R
-/Next 631 0 R
-/First 627 0 R
-/Last 627 0 R
-/Count -1
+/Parent 619 0 R
>> endobj
619 0 obj <<
/Title 620 0 R
/A 617 0 R
/Parent 615 0 R
+/Next 627 0 R
+/First 623 0 R
+/Last 623 0 R
+/Count -1
>> endobj
615 0 obj <<
/Title 616 0 R
/A 613 0 R
-/Parent 611 0 R
-/Next 623 0 R
+/Parent 2166 0 R
+/Prev 595 0 R
+/Next 651 0 R
/First 619 0 R
-/Last 619 0 R
-/Count -1
+/Last 635 0 R
+/Count -3
>> endobj
611 0 obj <<
/Title 612 0 R
/A 609 0 R
-/Parent 2144 0 R
-/Prev 591 0 R
-/Next 647 0 R
-/First 615 0 R
-/Last 631 0 R
-/Count -3
+/Parent 595 0 R
+/Prev 607 0 R
>> endobj
607 0 obj <<
/Title 608 0 R
/A 605 0 R
-/Parent 591 0 R
-/Prev 603 0 R
+/Parent 595 0 R
+/Prev 599 0 R
+/Next 611 0 R
>> endobj
603 0 obj <<
/Title 604 0 R
/A 601 0 R
-/Parent 591 0 R
-/Prev 595 0 R
-/Next 607 0 R
+/Parent 599 0 R
>> endobj
599 0 obj <<
/Title 600 0 R
/A 597 0 R
/Parent 595 0 R
+/Next 607 0 R
+/First 603 0 R
+/Last 603 0 R
+/Count -1
>> endobj
595 0 obj <<
/Title 596 0 R
/A 593 0 R
-/Parent 591 0 R
-/Next 603 0 R
+/Parent 2166 0 R
+/Prev 571 0 R
+/Next 615 0 R
/First 599 0 R
-/Last 599 0 R
-/Count -1
+/Last 611 0 R
+/Count -3
>> endobj
591 0 obj <<
/Title 592 0 R
/A 589 0 R
-/Parent 2144 0 R
-/Prev 567 0 R
-/Next 611 0 R
-/First 595 0 R
-/Last 607 0 R
-/Count -3
+/Parent 571 0 R
+/Prev 579 0 R
>> endobj
587 0 obj <<
/Title 588 0 R
/A 585 0 R
-/Parent 567 0 R
-/Prev 575 0 R
+/Parent 579 0 R
+/Prev 583 0 R
>> endobj
583 0 obj <<
/Title 584 0 R
/A 581 0 R
-/Parent 575 0 R
-/Prev 579 0 R
+/Parent 579 0 R
+/Next 587 0 R
>> endobj
579 0 obj <<
/Title 580 0 R
/A 577 0 R
-/Parent 575 0 R
-/Next 583 0 R
+/Parent 571 0 R
+/Prev 575 0 R
+/Next 591 0 R
+/First 583 0 R
+/Last 587 0 R
+/Count -2
>> endobj
575 0 obj <<
/Title 576 0 R
/A 573 0 R
-/Parent 567 0 R
-/Prev 571 0 R
-/Next 587 0 R
-/First 579 0 R
-/Last 583 0 R
-/Count -2
+/Parent 571 0 R
+/Next 579 0 R
>> endobj
571 0 obj <<
/Title 572 0 R
/A 569 0 R
-/Parent 567 0 R
-/Next 575 0 R
+/Parent 2166 0 R
+/Prev 243 0 R
+/Next 595 0 R
+/First 575 0 R
+/Last 591 0 R
+/Count -3
>> endobj
567 0 obj <<
/Title 568 0 R
/A 565 0 R
-/Parent 2144 0 R
-/Prev 243 0 R
-/Next 591 0 R
-/First 571 0 R
-/Last 587 0 R
-/Count -3
+/Parent 547 0 R
+/Prev 563 0 R
>> endobj
563 0 obj <<
/Title 564 0 R
/A 561 0 R
-/Parent 543 0 R
+/Parent 547 0 R
/Prev 559 0 R
+/Next 567 0 R
>> endobj
559 0 obj <<
/Title 560 0 R
/A 557 0 R
-/Parent 543 0 R
+/Parent 547 0 R
/Prev 555 0 R
/Next 563 0 R
>> endobj
555 0 obj <<
/Title 556 0 R
/A 553 0 R
-/Parent 543 0 R
+/Parent 547 0 R
/Prev 551 0 R
/Next 559 0 R
>> endobj
551 0 obj <<
/Title 552 0 R
/A 549 0 R
-/Parent 543 0 R
-/Prev 547 0 R
+/Parent 547 0 R
/Next 555 0 R
>> endobj
547 0 obj <<
/Title 548 0 R
/A 545 0 R
-/Parent 543 0 R
-/Next 551 0 R
+/Parent 539 0 R
+/Prev 543 0 R
+/First 551 0 R
+/Last 567 0 R
+/Count -5
>> endobj
543 0 obj <<
/Title 544 0 R
/A 541 0 R
-/Parent 535 0 R
-/Prev 539 0 R
-/First 547 0 R
-/Last 563 0 R
-/Count -5
+/Parent 539 0 R
+/Next 547 0 R
>> endobj
539 0 obj <<
/Title 540 0 R
/A 537 0 R
-/Parent 535 0 R
-/Next 543 0 R
+/Parent 243 0 R
+/Prev 483 0 R
+/First 543 0 R
+/Last 547 0 R
+/Count -2
>> endobj
535 0 obj <<
/Title 536 0 R
/A 533 0 R
-/Parent 243 0 R
-/Prev 483 0 R
-/First 539 0 R
-/Last 543 0 R
-/Count -2
+/Parent 483 0 R
+/Prev 531 0 R
>> endobj
531 0 obj <<
/Title 532 0 R
/A 529 0 R
/Parent 483 0 R
-/Prev 527 0 R
+/Prev 511 0 R
+/Next 535 0 R
>> endobj
527 0 obj <<
/Title 528 0 R
/A 525 0 R
-/Parent 483 0 R
-/Prev 511 0 R
-/Next 531 0 R
+/Parent 511 0 R
+/Prev 523 0 R
>> endobj
523 0 obj <<
/Title 524 0 R
/A 521 0 R
/Parent 511 0 R
/Prev 519 0 R
+/Next 527 0 R
>> endobj
519 0 obj <<
/Title 520 0 R
@@ -11223,10 +11375,10 @@ endobj
/A 509 0 R
/Parent 483 0 R
/Prev 507 0 R
-/Next 527 0 R
+/Next 531 0 R
/First 515 0 R
-/Last 523 0 R
-/Count -3
+/Last 527 0 R
+/Count -4
>> endobj
507 0 obj <<
/Title 508 0 R
@@ -11275,9 +11427,9 @@ endobj
/A 481 0 R
/Parent 243 0 R
/Prev 275 0 R
-/Next 535 0 R
+/Next 539 0 R
/First 487 0 R
-/Last 531 0 R
+/Last 535 0 R
/Count -7
>> endobj
479 0 obj <<
@@ -11702,11 +11854,11 @@ endobj
243 0 obj <<
/Title 244 0 R
/A 241 0 R
-/Parent 2144 0 R
+/Parent 2166 0 R
/Prev 231 0 R
-/Next 567 0 R
+/Next 571 0 R
/First 247 0 R
-/Last 535 0 R
+/Last 539 0 R
/Count -4
>> endobj
239 0 obj <<
@@ -11724,7 +11876,7 @@ endobj
231 0 obj <<
/Title 232 0 R
/A 229 0 R
-/Parent 2144 0 R
+/Parent 2166 0 R
/Prev 131 0 R
/Next 243 0 R
/First 235 0 R
@@ -11906,7 +12058,7 @@ endobj
131 0 obj <<
/Title 132 0 R
/A 129 0 R
-/Parent 2144 0 R
+/Parent 2166 0 R
/Prev 91 0 R
/Next 231 0 R
/First 135 0 R
@@ -11980,7 +12132,7 @@ endobj
91 0 obj <<
/Title 92 0 R
/A 89 0 R
-/Parent 2144 0 R
+/Parent 2166 0 R
/Prev 67 0 R
/Next 131 0 R
/First 95 0 R
@@ -12023,7 +12175,7 @@ endobj
67 0 obj <<
/Title 68 0 R
/A 65 0 R
-/Parent 2144 0 R
+/Parent 2166 0 R
/Prev 7 0 R
/Next 91 0 R
/First 71 0 R
@@ -12132,1760 +12284,1731 @@ endobj
7 0 obj <<
/Title 8 0 R
/A 5 0 R
-/Parent 2144 0 R
+/Parent 2166 0 R
/Next 67 0 R
/First 11 0 R
/Last 23 0 R
/Count -4
>> endobj
-2145 0 obj <<
-/Names [(Access_Control_Lists) 1621 0 R (Bv9ARM.ch01) 942 0 R (Bv9ARM.ch02) 988 0 R (Bv9ARM.ch03) 1005 0 R (Bv9ARM.ch04) 1054 0 R (Bv9ARM.ch05) 1142 0 R (Bv9ARM.ch06) 1153 0 R (Bv9ARM.ch07) 1620 0 R (Bv9ARM.ch08) 1645 0 R (Bv9ARM.ch09) 1661 0 R (Bv9ARM.ch10) 1882 0 R (Configuration_File_Grammar) 1178 0 R (DNSSEC) 1121 0 R (Doc-Start) 707 0 R (Setting_TTLs) 1546 0 R (acache) 995 0 R (access_control) 1307 0 R (acl) 1186 0 R (address_match_lists) 1159 0 R (admin_tools) 1028 0 R (appendix.A) 610 0 R (appendix.B) 646 0 R (bibliography) 1669 0 R (boolean_options) 1070 0 R (builtin) 1385 0 R (chapter*.1) 742 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 566 0 R (chapter.8) 590 0 R (cite.RFC1033) 1796 0 R (cite.RFC1034) 1681 0 R (cite.RFC1035) 1683 0 R (cite.RFC1101) 1778 0 R (cite.RFC1123) 1780 0 R (cite.RFC1183) 1740 0 R (cite.RFC1464) 1818 0 R (cite.RFC1535) 1726 0 R (cite.RFC1536) 1728 0 R (cite.RFC1537) 1798 0 R (cite.RFC1591) 1782 0 R (cite.RFC1706) 1742 0 R (cite.RFC1712) 1838 0 R (cite.RFC1713) 1820 0 R (cite.RFC1794) 1822 0 R (cite.RFC1876) 1744 0 R (cite.RFC1912) 1800 0 R (cite.RFC1982) 1730 0 R (cite.RFC1995) 1688 0 R (cite.RFC1996) 1690 0 R (cite.RFC2010) 1802 0 R (cite.RFC2052) 1746 0 R (cite.RFC2065) 1851 0 R (cite.RFC2136) 1692 0 R (cite.RFC2137) 1853 0 R (cite.RFC2163) 1748 0 R (cite.RFC2168) 1750 0 R (cite.RFC2181) 1694 0 R (cite.RFC2219) 1804 0 R (cite.RFC2230) 1752 0 R (cite.RFC2240) 1824 0 R (cite.RFC2308) 1696 0 R (cite.RFC2317) 1784 0 R (cite.RFC2345) 1826 0 R (cite.RFC2352) 1828 0 R (cite.RFC2535) 1855 0 R (cite.RFC2536) 1754 0 R (cite.RFC2537) 1756 0 R (cite.RFC2538) 1758 0 R (cite.RFC2539) 1760 0 R (cite.RFC2540) 1762 0 R (cite.RFC2671) 1698 0 R (cite.RFC2672) 1700 0 R (cite.RFC2673) 1840 0 R (cite.RFC2782) 1764 0 R (cite.RFC2825) 1808 0 R (cite.RFC2826) 1786 0 R (cite.RFC2845) 1702 0 R (cite.RFC2874) 1842 0 R (cite.RFC2915) 1766 0 R (cite.RFC2929) 1788 0 R (cite.RFC2930) 1704 0 R (cite.RFC2931) 1706 0 R (cite.RFC3007) 1708 0 R (cite.RFC3008) 1857 0 R (cite.RFC3071) 1830 0 R (cite.RFC3090) 1859 0 R (cite.RFC3110) 1768 0 R (cite.RFC3123) 1770 0 R (cite.RFC3225) 1714 0 R (cite.RFC3258) 1832 0 R (cite.RFC3445) 1861 0 R (cite.RFC3490) 1810 0 R (cite.RFC3491) 1812 0 R (cite.RFC3492) 1814 0 R (cite.RFC3596) 1772 0 R (cite.RFC3597) 1774 0 R (cite.RFC3645) 1710 0 R (cite.RFC3655) 1863 0 R (cite.RFC3658) 1865 0 R (cite.RFC3755) 1867 0 R (cite.RFC3757) 1869 0 R (cite.RFC3833) 1716 0 R (cite.RFC3845) 1871 0 R (cite.RFC3901) 1834 0 R (cite.RFC4033) 1718 0 R (cite.RFC4034) 1720 0 R (cite.RFC4035) 1722 0 R (cite.RFC4074) 1732 0 R (cite.RFC974) 1685 0 R (cite.id2505777) 1876 0 R (clients-per-query) 1592 0 R (configuration_file_elements) 1154 0 R (controls_statement_definition_and_usage) 1041 0 R (diagnostic_tools) 976 0 R (dynamic_update) 1064 0 R (dynamic_update_policies) 1116 0 R (dynamic_update_security) 1316 0 R (empty) 1393 0 R (historical_dns_information) 1663 0 R (id2466552) 943 0 R (id2466576) 944 0 R (id2467534) 945 0 R (id2467544) 946 0 R (id2467716) 958 0 R (id2467737) 959 0 R (id2467771) 960 0 R (id2467856) 963 0 R (id2467948) 956 0 R (id2470253) 970 0 R (id2470277) 973 0 R (id2470375) 974 0 R (id2470396) 975 0 R (id2470426) 981 0 R (id2470530) 982 0 R (id2470556) 983 0 R (id2470590) 989 0 R (id2470617) 990 0 R (id2470630) 991 0 R (id2470724) 994 0 R (id2470734) 1000 0 R (id2470766) 1007 0 R (id2470782) 1008 0 R (id2470805) 1014 0 R (id2470822) 1015 0 R (id2471227) 1018 0 R (id2471233) 1019 0 R (id2473009) 1046 0 R (id2473020) 1047 0 R (id2473420) 1079 0 R (id2473438) 1080 0 R (id2473942) 1096 0 R (id2473959) 1097 0 R (id2473997) 1102 0 R (id2474016) 1103 0 R (id2474026) 1104 0 R (id2474069) 1105 0 R (id2474263) 1110 0 R (id2474311) 1112 0 R (id2474325) 1113 0 R (id2474374) 1114 0 R (id2474510) 1122 0 R (id2474589) 1123 0 R (id2474670) 1128 0 R (id2474953) 1133 0 R (id2475083) 1135 0 R (id2475105) 1136 0 R (id2475138) 1143 0 R (id2475285) 1155 0 R (id2476147) 1164 0 R (id2476174) 1169 0 R (id2476380) 1170 0 R (id2476395) 1171 0 R (id2476425) 1177 0 R (id2476500) 1179 0 R (id2477079) 1185 0 R (id2477122) 1187 0 R (id2477269) 1189 0 R (id2477629) 1196 0 R (id2477646) 1197 0 R (id2477806) 1203 0 R (id2477830) 1204 0 R (id2477921) 1208 0 R (id2478115) 1209 0 R (id2478167) 1215 0 R (id2478997) 1226 0 R (id2479731) 1236 0 R (id2479859) 1237 0 R (id2480244) 1239 0 R (id2480317) 1244 0 R (id2480381) 1247 0 R (id2480425) 1248 0 R (id2480440) 1249 0 R (id2482851) 1278 0 R (id2484684) 1304 0 R (id2484743) 1306 0 R (id2485249) 1321 0 R (id2486520) 1340 0 R (id2486580) 1342 0 R (id2486934) 1354 0 R (id2487436) 1369 0 R (id2489703) 1411 0 R (id2489789) 1416 0 R (id2489841) 1417 0 R (id2489923) 1423 0 R (id2491460) 1437 0 R (id2491467) 1438 0 R (id2491473) 1439 0 R (id2491963) 1446 0 R (id2491996) 1452 0 R (id2493692) 1505 0 R (id2494007) 1512 0 R (id2494025) 1513 0 R (id2494045) 1516 0 R (id2494282) 1518 0 R (id2495452) 1528 0 R (id2495580) 1534 0 R (id2495602) 1535 0 R (id2495964) 1537 0 R (id2496101) 1539 0 R (id2496119) 1544 0 R (id2496660) 1547 0 R (id2496785) 1549 0 R (id2496800) 1550 0 R (id2496980) 1556 0 R (id2497002) 1557 0 R (id2497063) 1558 0 R (id2497132) 1559 0 R (id2497169) 1565 0 R (id2497299) 1566 0 R (id2497798) 1573 0 R (id2498301) 1581 0 R (id2498307) 1582 0 R (id2499706) 1589 0 R (id2499713) 1590 0 R (id2500089) 1597 0 R (id2500094) 1598 0 R (id2501108) 1600 0 R (id2501140) 1601 0 R (id2501549) 1610 0 R (id2501792) 1630 0 R (id2501941) 1631 0 R (id2502069) 1632 0 R (id2502149) 1646 0 R (id2502154) 1647 0 R (id2502166) 1648 0 R (id2502251) 1649 0 R (id2502313) 1662 0 R (id2502485) 1668 0 R (id2502741) 1673 0 R (id2502743) 1679 0 R (id2502752) 1684 0 R (id2502775) 1680 0 R (id2502798) 1682 0 R (id2502835) 1693 0 R (id2502861) 1695 0 R (id2502887) 1687 0 R (id2502912) 1689 0 R (id2502935) 1691 0 R (id2502990) 1697 0 R (id2503017) 1699 0 R (id2503044) 1701 0 R (id2503106) 1703 0 R (id2503136) 1705 0 R (id2503165) 1707 0 R (id2503192) 1709 0 R (id2503267) 1712 0 R (id2503274) 1713 0 R (id2503301) 1715 0 R (id2503337) 1717 0 R (id2503402) 1719 0 R (id2503467) 1721 0 R (id2503532) 1724 0 R (id2503541) 1725 0 R (id2503635) 1727 0 R (id2503703) 1729 0 R (id2503738) 1731 0 R (id2503779) 1738 0 R (id2503784) 1739 0 R (id2503842) 1741 0 R (id2503879) 1749 0 R (id2503914) 1743 0 R (id2503969) 1745 0 R (id2504007) 1747 0 R (id2504033) 1751 0 R (id2504058) 1753 0 R (id2504085) 1755 0 R (id2504112) 1757 0 R (id2504151) 1759 0 R (id2504181) 1761 0 R (id2504211) 1763 0 R (id2504253) 1765 0 R (id2504286) 1767 0 R (id2504313) 1769 0 R (id2504337) 1771 0 R (id2504394) 1773 0 R (id2504419) 1776 0 R (id2504426) 1777 0 R (id2504452) 1779 0 R (id2504474) 1781 0 R (id2504498) 1783 0 R (id2504612) 1785 0 R (id2504635) 1787 0 R (id2504685) 1794 0 R (id2504693) 1795 0 R (id2504716) 1797 0 R (id2504743) 1799 0 R (id2504770) 1801 0 R (id2504806) 1803 0 R (id2504846) 1806 0 R (id2504852) 1807 0 R (id2504884) 1809 0 R (id2504930) 1811 0 R (id2504965) 1813 0 R (id2504992) 1816 0 R (id2505010) 1817 0 R (id2505032) 1819 0 R (id2505058) 1821 0 R (id2505083) 1823 0 R (id2505107) 1825 0 R (id2505153) 1827 0 R (id2505176) 1829 0 R (id2505203) 1831 0 R (id2505228) 1833 0 R (id2505266) 1836 0 R (id2505272) 1837 0 R (id2505330) 1839 0 R (id2505356) 1841 0 R (id2505393) 1849 0 R (id2505404) 1850 0 R (id2505444) 1852 0 R (id2505470) 1854 0 R (id2505500) 1856 0 R (id2505526) 1858 0 R (id2505553) 1860 0 R (id2505589) 1862 0 R (id2505625) 1864 0 R (id2505652) 1866 0 R (id2505678) 1868 0 R (id2505723) 1870 0 R (id2505765) 1873 0 R (id2505774) 1875 0 R (id2505777) 1877 0 R (incremental_zone_transfers) 1076 0 R (internet_drafts) 1872 0 R (ipv6addresses) 1137 0 R (journal) 1065 0 R (lwresd) 1144 0 R (man.dig) 1883 0 R (man.dnssec-dsfromkey) 1931 0 R (man.dnssec-keyfromlabel) 1945 0 R (man.dnssec-keygen) 1961 0 R (man.dnssec-signzone) 1979 0 R (man.host) 1916 0 R (man.named) 2033 0 R (man.named-checkconf) 2004 0 R (man.named-checkzone) 2017 0 R (man.nsupdate) 2055 0 R (man.rndc) 2077 0 R (man.rndc-confgen) 2110 0 R (man.rndc.conf) 2093 0 R (notify) 1055 0 R (options) 1263 0 R (page.1) 706 0 R (page.10) 980 0 R (page.100) 1667 0 R (page.101) 1677 0 R (page.102) 1736 0 R (page.103) 1792 0 R (page.104) 1847 0 R (page.105) 1881 0 R (page.106) 1890 0 R (page.107) 1896 0 R (page.108) 1901 0 R (page.109) 1905 0 R (page.11) 987 0 R (page.110) 1911 0 R (page.111) 1922 0 R (page.112) 1927 0 R (page.113) 1939 0 R (page.114) 1950 0 R (page.115) 1957 0 R (page.116) 1970 0 R (page.117) 1974 0 R (page.118) 1985 0 R (page.119) 1991 0 R (page.12) 999 0 R (page.120) 1995 0 R (page.121) 2003 0 R (page.122) 2016 0 R (page.123) 2025 0 R (page.124) 2029 0 R (page.125) 2041 0 R (page.126) 2045 0 R (page.127) 2052 0 R (page.128) 2063 0 R (page.129) 2068 0 R (page.13) 1004 0 R (page.130) 2073 0 R (page.131) 2083 0 R (page.132) 2090 0 R (page.133) 2100 0 R (page.134) 2106 0 R (page.135) 2118 0 R (page.14) 1013 0 R (page.15) 1024 0 R (page.16) 1032 0 R (page.17) 1039 0 R (page.18) 1045 0 R (page.19) 1053 0 R (page.2) 731 0 R (page.20) 1075 0 R (page.21) 1085 0 R (page.22) 1090 0 R (page.23) 1094 0 R (page.24) 1101 0 R (page.25) 1109 0 R (page.26) 1120 0 R (page.27) 1127 0 R (page.28) 1132 0 R (page.29) 1141 0 R (page.3) 741 0 R (page.30) 1148 0 R (page.31) 1152 0 R (page.32) 1163 0 R (page.33) 1168 0 R (page.34) 1176 0 R (page.35) 1184 0 R (page.36) 1193 0 R (page.37) 1202 0 R (page.38) 1214 0 R (page.39) 1219 0 R (page.4) 796 0 R (page.40) 1225 0 R (page.41) 1231 0 R (page.42) 1235 0 R (page.43) 1243 0 R (page.44) 1254 0 R (page.45) 1258 0 R (page.46) 1262 0 R (page.47) 1267 0 R (page.48) 1273 0 R (page.49) 1277 0 R (page.5) 860 0 R (page.50) 1284 0 R (page.51) 1295 0 R (page.52) 1299 0 R (page.53) 1303 0 R (page.54) 1313 0 R (page.55) 1320 0 R (page.56) 1327 0 R (page.57) 1331 0 R (page.58) 1335 0 R (page.59) 1339 0 R (page.6) 922 0 R (page.60) 1347 0 R (page.61) 1353 0 R (page.62) 1360 0 R (page.63) 1367 0 R (page.64) 1374 0 R (page.65) 1380 0 R (page.66) 1392 0 R (page.67) 1397 0 R (page.68) 1402 0 R (page.69) 1407 0 R (page.7) 941 0 R (page.70) 1415 0 R (page.71) 1422 0 R (page.72) 1427 0 R (page.73) 1431 0 R (page.74) 1436 0 R (page.75) 1444 0 R (page.76) 1451 0 R (page.77) 1470 0 R (page.78) 1484 0 R (page.79) 1504 0 R (page.8) 955 0 R (page.80) 1511 0 R (page.81) 1523 0 R (page.82) 1527 0 R (page.83) 1533 0 R (page.84) 1543 0 R (page.85) 1555 0 R (page.86) 1564 0 R (page.87) 1571 0 R (page.88) 1579 0 R (page.89) 1587 0 R (page.9) 969 0 R (page.90) 1596 0 R (page.91) 1606 0 R (page.92) 1615 0 R (page.93) 1619 0 R (page.94) 1625 0 R (page.95) 1636 0 R (page.96) 1640 0 R (page.97) 1644 0 R (page.98) 1656 0 R (page.99) 1660 0 R (proposed_standards) 1081 0 R (query_address) 1322 0 R (rfcs) 965 0 R (rndc) 1198 0 R (root_delegation_only) 1447 0 R (rrset_ordering) 1020 0 R (sample_configuration) 1006 0 R (section*.10) 1805 0 R (section*.100) 2091 0 R (section*.101) 2092 0 R (section*.102) 2094 0 R (section*.103) 2095 0 R (section*.104) 2096 0 R (section*.105) 2101 0 R (section*.106) 2107 0 R (section*.107) 2108 0 R (section*.108) 2109 0 R (section*.109) 2111 0 R (section*.11) 1815 0 R (section*.110) 2112 0 R (section*.111) 2113 0 R (section*.112) 2114 0 R (section*.113) 2119 0 R (section*.114) 2120 0 R (section*.115) 2121 0 R (section*.12) 1835 0 R (section*.13) 1848 0 R (section*.14) 1874 0 R (section*.15) 1884 0 R (section*.16) 1885 0 R (section*.17) 1886 0 R (section*.18) 1891 0 R (section*.19) 1892 0 R (section*.2) 1672 0 R (section*.20) 1897 0 R (section*.21) 1906 0 R (section*.22) 1912 0 R (section*.23) 1913 0 R (section*.24) 1914 0 R (section*.25) 1915 0 R (section*.26) 1917 0 R (section*.27) 1918 0 R (section*.28) 1923 0 R (section*.29) 1928 0 R (section*.3) 1678 0 R (section*.30) 1929 0 R (section*.31) 1930 0 R (section*.32) 1932 0 R (section*.33) 1933 0 R (section*.34) 1934 0 R (section*.35) 1935 0 R (section*.36) 1940 0 R (section*.37) 1941 0 R (section*.38) 1942 0 R (section*.39) 1943 0 R (section*.4) 1686 0 R (section*.40) 1944 0 R (section*.41) 1946 0 R (section*.42) 1951 0 R (section*.43) 1952 0 R (section*.44) 1953 0 R (section*.45) 1958 0 R (section*.46) 1959 0 R (section*.47) 1960 0 R (section*.48) 1962 0 R (section*.49) 1963 0 R (section*.5) 1711 0 R (section*.50) 1964 0 R (section*.51) 1965 0 R (section*.52) 1975 0 R (section*.53) 1976 0 R (section*.54) 1977 0 R (section*.55) 1978 0 R (section*.56) 1980 0 R (section*.57) 1981 0 R (section*.58) 1986 0 R (section*.59) 1987 0 R (section*.6) 1723 0 R (section*.60) 1996 0 R (section*.61) 1997 0 R (section*.62) 1998 0 R (section*.63) 1999 0 R (section*.64) 2005 0 R (section*.65) 2006 0 R (section*.66) 2007 0 R (section*.67) 2008 0 R (section*.68) 2009 0 R (section*.69) 2010 0 R (section*.7) 1737 0 R (section*.70) 2011 0 R (section*.71) 2018 0 R (section*.72) 2019 0 R (section*.73) 2020 0 R (section*.74) 2021 0 R (section*.75) 2030 0 R (section*.76) 2031 0 R (section*.77) 2032 0 R (section*.78) 2034 0 R (section*.79) 2035 0 R (section*.8) 1775 0 R (section*.80) 2036 0 R (section*.81) 2037 0 R (section*.82) 2046 0 R (section*.83) 2047 0 R (section*.84) 2048 0 R (section*.85) 2053 0 R (section*.86) 2054 0 R (section*.87) 2056 0 R (section*.88) 2057 0 R (section*.89) 2058 0 R (section*.9) 1793 0 R (section*.90) 2064 0 R (section*.91) 2069 0 R (section*.92) 2074 0 R (section*.93) 2075 0 R (section*.94) 2076 0 R (section*.95) 2078 0 R (section*.96) 2079 0 R (section*.97) 2084 0 R (section*.98) 2085 0 R (section*.99) 2086 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 482 0 R (section.6.4) 534 0 R (section.7.1) 570 0 R (section.7.2) 574 0 R (section.7.3) 586 0 R (section.8.1) 594 0 R (section.8.2) 602 0 R (section.8.3) 606 0 R (section.A.1) 614 0 R (section.A.2) 622 0 R (section.A.3) 630 0 R (section.B.1) 650 0 R (section.B.10) 686 0 R (section.B.11) 690 0 R (section.B.12) 694 0 R (section.B.13) 698 0 R (section.B.2) 654 0 R (section.B.3) 658 0 R (section.B.4) 662 0 R (section.B.5) 666 0 R (section.B.6) 670 0 R (section.B.7) 674 0 R (section.B.8) 678 0 R (section.B.9) 682 0 R (server_resource_limits) 1348 0 R (server_statement_definition_and_usage) 1291 0 R (server_statement_grammar) 1403 0 R (statistics) 1572 0 R (statistics_counters) 1580 0 R (statschannels) 1410 0 R (statsfile) 1269 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 330 0 R (subsection.6.2.12) 334 0 R (subsection.6.2.13) 338 0 R (subsection.6.2.14) 342 0 R (subsection.6.2.15) 346 0 R (subsection.6.2.16) 350 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.25) 458 0 R (subsection.6.2.26) 462 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 486 0 R (subsection.6.3.2) 498 0 R (subsection.6.3.3) 502 0 R (subsection.6.3.4) 506 0 R (subsection.6.3.5) 510 0 R (subsection.6.3.6) 526 0 R (subsection.6.3.7) 530 0 R (subsection.6.4.1) 542 0 R (subsection.7.2.1) 578 0 R (subsection.7.2.2) 582 0 R (subsection.8.1.1) 598 0 R (subsection.A.1.1) 618 0 R (subsection.A.2.1) 626 0 R (subsection.A.3.1) 634 0 R (subsection.A.3.2) 638 0 R (subsection.A.3.3) 642 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.10.3) 326 0 R (subsubsection.6.2.16.1) 354 0 R (subsubsection.6.2.16.10) 390 0 R (subsubsection.6.2.16.11) 394 0 R (subsubsection.6.2.16.12) 398 0 R (subsubsection.6.2.16.13) 402 0 R (subsubsection.6.2.16.14) 406 0 R (subsubsection.6.2.16.15) 410 0 R (subsubsection.6.2.16.16) 414 0 R (subsubsection.6.2.16.17) 418 0 R (subsubsection.6.2.16.18) 422 0 R (subsubsection.6.2.16.2) 358 0 R (subsubsection.6.2.16.3) 362 0 R (subsubsection.6.2.16.4) 366 0 R (subsubsection.6.2.16.5) 370 0 R (subsubsection.6.2.16.6) 374 0 R (subsubsection.6.2.16.7) 378 0 R (subsubsection.6.2.16.8) 382 0 R (subsubsection.6.2.16.9) 386 0 R (subsubsection.6.2.26.1) 466 0 R (subsubsection.6.2.26.2) 470 0 R (subsubsection.6.2.26.3) 474 0 R (subsubsection.6.2.26.4) 478 0 R (subsubsection.6.3.1.1) 490 0 R (subsubsection.6.3.1.2) 494 0 R (subsubsection.6.3.5.1) 514 0 R (subsubsection.6.3.5.2) 518 0 R (subsubsection.6.3.5.3) 522 0 R (subsubsection.6.4.0.1) 538 0 R (subsubsection.6.4.1.1) 546 0 R (subsubsection.6.4.1.2) 550 0 R (subsubsection.6.4.1.3) 554 0 R (subsubsection.6.4.1.4) 558 0 R (subsubsection.6.4.1.5) 562 0 R (table.1.1) 947 0 R (table.1.2) 957 0 R (table.3.1) 1016 0 R (table.3.2) 1048 0 R (table.6.1) 1156 0 R (table.6.10) 1517 0 R (table.6.11) 1519 0 R (table.6.12) 1529 0 R (table.6.13) 1536 0 R (table.6.14) 1538 0 R (table.6.15) 1545 0 R (table.6.16) 1548 0 R (table.6.17) 1551 0 R (table.6.18) 1567 0 R (table.6.19) 1574 0 R (table.6.2) 1180 0 R (table.6.20) 1583 0 R (table.6.21) 1591 0 R (table.6.22) 1599 0 R (table.6.23) 1602 0 R (table.6.3) 1188 0 R (table.6.4) 1227 0 R (table.6.5) 1238 0 R (table.6.6) 1279 0 R (table.6.7) 1370 0 R (table.6.8) 1440 0 R (table.6.9) 1506 0 R (the_category_phrase) 1221 0 R (the_sortlist_statement) 1361 0 R (topology) 1355 0 R (tsig) 1095 0 R (tuning) 1375 0 R (types_of_resource_records_and_when_to_use_them) 964 0 R (view_statement_grammar) 1388 0 R (zone_statement_grammar) 1309 0 R (zone_transfers) 1071 0 R (zonefile_format) 1387 0 R]
+2167 0 obj <<
+/Names [(Access_Control_Lists) 1638 0 R (Bv9ARM.ch01) 947 0 R (Bv9ARM.ch02) 993 0 R (Bv9ARM.ch03) 1010 0 R (Bv9ARM.ch04) 1059 0 R (Bv9ARM.ch05) 1158 0 R (Bv9ARM.ch06) 1170 0 R (Bv9ARM.ch07) 1637 0 R (Bv9ARM.ch08) 1663 0 R (Bv9ARM.ch09) 1678 0 R (Bv9ARM.ch10) 1899 0 R (Configuration_File_Grammar) 1194 0 R (DNSSEC) 1126 0 R (Doc-Start) 711 0 R (Setting_TTLs) 1563 0 R (acache) 1000 0 R (access_control) 1323 0 R (acl) 1202 0 R (address_match_lists) 1175 0 R (admin_tools) 1033 0 R (appendix.A) 614 0 R (appendix.B) 650 0 R (bibliography) 1686 0 R (boolean_options) 1075 0 R (builtin) 1407 0 R (chapter*.1) 746 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 570 0 R (chapter.8) 594 0 R (cite.RFC1033) 1814 0 R (cite.RFC1034) 1698 0 R (cite.RFC1035) 1700 0 R (cite.RFC1101) 1796 0 R (cite.RFC1123) 1798 0 R (cite.RFC1183) 1758 0 R (cite.RFC1464) 1836 0 R (cite.RFC1535) 1743 0 R (cite.RFC1536) 1745 0 R (cite.RFC1537) 1816 0 R (cite.RFC1591) 1800 0 R (cite.RFC1706) 1760 0 R (cite.RFC1712) 1856 0 R (cite.RFC1713) 1838 0 R (cite.RFC1794) 1840 0 R (cite.RFC1876) 1762 0 R (cite.RFC1912) 1818 0 R (cite.RFC1982) 1747 0 R (cite.RFC1995) 1705 0 R (cite.RFC1996) 1707 0 R (cite.RFC2010) 1820 0 R (cite.RFC2052) 1764 0 R (cite.RFC2065) 1868 0 R (cite.RFC2136) 1709 0 R (cite.RFC2137) 1870 0 R (cite.RFC2163) 1766 0 R (cite.RFC2168) 1768 0 R (cite.RFC2181) 1711 0 R (cite.RFC2219) 1822 0 R (cite.RFC2230) 1770 0 R (cite.RFC2240) 1842 0 R (cite.RFC2308) 1713 0 R (cite.RFC2317) 1802 0 R (cite.RFC2345) 1844 0 R (cite.RFC2352) 1846 0 R (cite.RFC2535) 1872 0 R (cite.RFC2536) 1772 0 R (cite.RFC2537) 1774 0 R (cite.RFC2538) 1776 0 R (cite.RFC2539) 1778 0 R (cite.RFC2540) 1780 0 R (cite.RFC2671) 1715 0 R (cite.RFC2672) 1717 0 R (cite.RFC2673) 1858 0 R (cite.RFC2782) 1782 0 R (cite.RFC2825) 1826 0 R (cite.RFC2826) 1804 0 R (cite.RFC2845) 1719 0 R (cite.RFC2874) 1860 0 R (cite.RFC2915) 1784 0 R (cite.RFC2929) 1806 0 R (cite.RFC2930) 1721 0 R (cite.RFC2931) 1723 0 R (cite.RFC3007) 1725 0 R (cite.RFC3008) 1874 0 R (cite.RFC3071) 1848 0 R (cite.RFC3090) 1876 0 R (cite.RFC3110) 1786 0 R (cite.RFC3123) 1788 0 R (cite.RFC3225) 1731 0 R (cite.RFC3258) 1850 0 R (cite.RFC3445) 1878 0 R (cite.RFC3490) 1828 0 R (cite.RFC3491) 1830 0 R (cite.RFC3492) 1832 0 R (cite.RFC3596) 1790 0 R (cite.RFC3597) 1792 0 R (cite.RFC3645) 1727 0 R (cite.RFC3655) 1880 0 R (cite.RFC3658) 1882 0 R (cite.RFC3755) 1884 0 R (cite.RFC3757) 1886 0 R (cite.RFC3833) 1733 0 R (cite.RFC3845) 1888 0 R (cite.RFC3901) 1852 0 R (cite.RFC4033) 1735 0 R (cite.RFC4034) 1737 0 R (cite.RFC4035) 1739 0 R (cite.RFC4074) 1749 0 R (cite.RFC974) 1702 0 R (cite.id2506250) 1893 0 R (clients-per-query) 1610 0 R (configuration_file_elements) 1171 0 R (controls_statement_definition_and_usage) 1046 0 R (diagnostic_tools) 981 0 R (dynamic_update) 1069 0 R (dynamic_update_policies) 1121 0 R (dynamic_update_security) 1333 0 R (empty) 1409 0 R (historical_dns_information) 1680 0 R (id2466555) 948 0 R (id2466579) 949 0 R (id2467422) 1084 0 R (id2467441) 1085 0 R (id2467538) 950 0 R (id2467547) 951 0 R (id2467719) 963 0 R (id2467740) 964 0 R (id2467774) 965 0 R (id2467859) 968 0 R (id2467952) 961 0 R (id2470257) 975 0 R (id2470280) 978 0 R (id2470378) 979 0 R (id2470400) 980 0 R (id2470429) 986 0 R (id2470533) 987 0 R (id2470560) 988 0 R (id2470594) 994 0 R (id2470620) 995 0 R (id2470633) 996 0 R (id2470727) 999 0 R (id2470738) 1005 0 R (id2470770) 1012 0 R (id2470786) 1013 0 R (id2470808) 1019 0 R (id2470825) 1020 0 R (id2471230) 1023 0 R (id2471236) 1024 0 R (id2473012) 1051 0 R (id2473024) 1052 0 R (id2473610) 1101 0 R (id2473627) 1102 0 R (id2474417) 1107 0 R (id2474435) 1108 0 R (id2474445) 1109 0 R (id2474482) 1110 0 R (id2474676) 1115 0 R (id2474724) 1117 0 R (id2474738) 1118 0 R (id2474787) 1119 0 R (id2474855) 1127 0 R (id2475002) 1128 0 R (id2475083) 1133 0 R (id2475389) 1141 0 R (id2475520) 1148 0 R (id2475541) 1149 0 R (id2475574) 1159 0 R (id2475858) 1172 0 R (id2476720) 1180 0 R (id2476747) 1185 0 R (id2476953) 1186 0 R (id2476968) 1187 0 R (id2477066) 1193 0 R (id2477209) 1195 0 R (id2477652) 1201 0 R (id2477694) 1203 0 R (id2477842) 1205 0 R (id2478270) 1213 0 R (id2478288) 1214 0 R (id2478311) 1220 0 R (id2478334) 1221 0 R (id2478493) 1225 0 R (id2478619) 1226 0 R (id2478672) 1231 0 R (id2479433) 1242 0 R (id2480030) 1253 0 R (id2480158) 1254 0 R (id2480544) 1256 0 R (id2480617) 1261 0 R (id2480681) 1264 0 R (id2480725) 1265 0 R (id2480740) 1266 0 R (id2483226) 1295 0 R (id2484998) 1320 0 R (id2485057) 1322 0 R (id2485630) 1338 0 R (id2486902) 1356 0 R (id2486962) 1358 0 R (id2487316) 1371 0 R (id2487818) 1385 0 R (id2489952) 1431 0 R (id2490106) 1432 0 R (id2490157) 1433 0 R (id2490376) 1439 0 R (id2491781) 1453 0 R (id2491788) 1454 0 R (id2491794) 1455 0 R (id2492284) 1462 0 R (id2492317) 1468 0 R (id2494013) 1522 0 R (id2494328) 1528 0 R (id2494346) 1529 0 R (id2494366) 1532 0 R (id2494672) 1534 0 R (id2495773) 1544 0 R (id2495970) 1550 0 R (id2495991) 1551 0 R (id2496422) 1553 0 R (id2496558) 1555 0 R (id2496577) 1561 0 R (id2496981) 1564 0 R (id2497106) 1566 0 R (id2497121) 1567 0 R (id2497301) 1573 0 R (id2497323) 1574 0 R (id2497339) 1575 0 R (id2497468) 1576 0 R (id2497538) 1581 0 R (id2497574) 1582 0 R (id2497704) 1583 0 R (id2498203) 1590 0 R (id2498638) 1598 0 R (id2498644) 1599 0 R (id2500112) 1606 0 R (id2500118) 1607 0 R (id2500563) 1615 0 R (id2500568) 1616 0 R (id2501513) 1622 0 R (id2501545) 1623 0 R (id2502023) 1628 0 R (id2502197) 1647 0 R (id2502278) 1648 0 R (id2502406) 1649 0 R (id2502486) 1664 0 R (id2502491) 1665 0 R (id2502503) 1666 0 R (id2502520) 1667 0 R (id2502582) 1679 0 R (id2503027) 1685 0 R (id2503214) 1690 0 R (id2503217) 1696 0 R (id2503225) 1701 0 R (id2503249) 1697 0 R (id2503272) 1699 0 R (id2503308) 1710 0 R (id2503335) 1712 0 R (id2503361) 1704 0 R (id2503385) 1706 0 R (id2503409) 1708 0 R (id2503464) 1714 0 R (id2503491) 1716 0 R (id2503517) 1718 0 R (id2503579) 1720 0 R (id2503609) 1722 0 R (id2503639) 1724 0 R (id2503666) 1726 0 R (id2503740) 1729 0 R (id2503748) 1730 0 R (id2503774) 1732 0 R (id2503811) 1734 0 R (id2503876) 1736 0 R (id2503941) 1738 0 R (id2504006) 1741 0 R (id2504014) 1742 0 R (id2504040) 1744 0 R (id2504108) 1746 0 R (id2504144) 1748 0 R (id2504184) 1756 0 R (id2504189) 1757 0 R (id2504247) 1759 0 R (id2504284) 1767 0 R (id2504320) 1761 0 R (id2504374) 1763 0 R (id2504412) 1765 0 R (id2504438) 1769 0 R (id2504464) 1771 0 R (id2504490) 1773 0 R (id2504517) 1775 0 R (id2504556) 1777 0 R (id2504586) 1779 0 R (id2504616) 1781 0 R (id2504659) 1783 0 R (id2504692) 1785 0 R (id2504718) 1787 0 R (id2504742) 1789 0 R (id2504868) 1791 0 R (id2504892) 1794 0 R (id2504900) 1795 0 R (id2504925) 1797 0 R (id2504948) 1799 0 R (id2504971) 1801 0 R (id2505017) 1803 0 R (id2505041) 1805 0 R (id2505091) 1812 0 R (id2505098) 1813 0 R (id2505122) 1815 0 R (id2505148) 1817 0 R (id2505175) 1819 0 R (id2505211) 1821 0 R (id2505252) 1824 0 R (id2505257) 1825 0 R (id2505289) 1827 0 R (id2505335) 1829 0 R (id2505370) 1831 0 R (id2505397) 1834 0 R (id2505415) 1835 0 R (id2505437) 1837 0 R (id2505463) 1839 0 R (id2505489) 1841 0 R (id2505512) 1843 0 R (id2505558) 1845 0 R (id2505581) 1847 0 R (id2505608) 1849 0 R (id2505634) 1851 0 R (id2505671) 1854 0 R (id2505677) 1855 0 R (id2505735) 1857 0 R (id2505762) 1859 0 R (id2505798) 1866 0 R (id2505810) 1867 0 R (id2505849) 1869 0 R (id2505944) 1871 0 R (id2505974) 1873 0 R (id2506000) 1875 0 R (id2506026) 1877 0 R (id2506062) 1879 0 R (id2506099) 1881 0 R (id2506125) 1883 0 R (id2506152) 1885 0 R (id2506197) 1887 0 R (id2506238) 1890 0 R (id2506248) 1892 0 R (id2506250) 1894 0 R (incremental_zone_transfers) 1081 0 R (internet_drafts) 1889 0 R (ipv6addresses) 1143 0 R (journal) 1070 0 R (lwresd) 1160 0 R (man.dig) 1900 0 R (man.dnssec-dsfromkey) 1948 0 R (man.dnssec-keyfromlabel) 1962 0 R (man.dnssec-keygen) 1979 0 R (man.dnssec-signzone) 1996 0 R (man.host) 1933 0 R (man.named) 2050 0 R (man.named-checkconf) 2022 0 R (man.named-checkzone) 2034 0 R (man.nsupdate) 2073 0 R (man.rndc) 2098 0 R (man.rndc-confgen) 2127 0 R (man.rndc.conf) 2111 0 R (notify) 1060 0 R (options) 1279 0 R (page.1) 710 0 R (page.10) 985 0 R (page.100) 1673 0 R (page.101) 1677 0 R (page.102) 1684 0 R (page.103) 1694 0 R (page.104) 1754 0 R (page.105) 1810 0 R (page.106) 1864 0 R (page.107) 1898 0 R (page.108) 1907 0 R (page.109) 1913 0 R (page.11) 992 0 R (page.110) 1919 0 R (page.111) 1923 0 R (page.112) 1928 0 R (page.113) 1939 0 R (page.114) 1944 0 R (page.115) 1956 0 R (page.116) 1968 0 R (page.117) 1975 0 R (page.118) 1987 0 R (page.119) 1991 0 R (page.12) 1004 0 R (page.120) 2002 0 R (page.121) 2008 0 R (page.122) 2013 0 R (page.123) 2019 0 R (page.124) 2032 0 R (page.125) 2042 0 R (page.126) 2046 0 R (page.127) 2058 0 R (page.128) 2063 0 R (page.129) 2069 0 R (page.13) 1009 0 R (page.130) 2080 0 R (page.131) 2085 0 R (page.132) 2089 0 R (page.133) 2097 0 R (page.134) 2107 0 R (page.135) 2118 0 R (page.136) 2123 0 R (page.137) 2135 0 R (page.138) 2141 0 R (page.14) 1018 0 R (page.15) 1029 0 R (page.16) 1037 0 R (page.17) 1044 0 R (page.18) 1050 0 R (page.19) 1058 0 R (page.2) 735 0 R (page.20) 1080 0 R (page.21) 1090 0 R (page.22) 1095 0 R (page.23) 1099 0 R (page.24) 1106 0 R (page.25) 1114 0 R (page.26) 1125 0 R (page.27) 1132 0 R (page.28) 1137 0 R (page.29) 1147 0 R (page.3) 745 0 R (page.30) 1153 0 R (page.31) 1157 0 R (page.32) 1165 0 R (page.33) 1169 0 R (page.34) 1179 0 R (page.35) 1184 0 R (page.36) 1192 0 R (page.37) 1200 0 R (page.38) 1210 0 R (page.39) 1219 0 R (page.4) 800 0 R (page.40) 1230 0 R (page.41) 1235 0 R (page.42) 1241 0 R (page.43) 1247 0 R (page.44) 1252 0 R (page.45) 1260 0 R (page.46) 1270 0 R (page.47) 1274 0 R (page.48) 1278 0 R (page.49) 1283 0 R (page.5) 864 0 R (page.50) 1290 0 R (page.51) 1294 0 R (page.52) 1300 0 R (page.53) 1311 0 R (page.54) 1315 0 R (page.55) 1319 0 R (page.56) 1330 0 R (page.57) 1337 0 R (page.58) 1342 0 R (page.59) 1347 0 R (page.6) 926 0 R (page.60) 1351 0 R (page.61) 1355 0 R (page.62) 1363 0 R (page.63) 1370 0 R (page.64) 1376 0 R (page.65) 1383 0 R (page.66) 1390 0 R (page.67) 1396 0 R (page.68) 1406 0 R (page.69) 1414 0 R (page.7) 946 0 R (page.70) 1418 0 R (page.71) 1423 0 R (page.72) 1430 0 R (page.73) 1438 0 R (page.74) 1444 0 R (page.75) 1448 0 R (page.76) 1452 0 R (page.77) 1460 0 R (page.78) 1467 0 R (page.79) 1486 0 R (page.8) 960 0 R (page.80) 1501 0 R (page.81) 1521 0 R (page.82) 1527 0 R (page.83) 1539 0 R (page.84) 1543 0 R (page.85) 1549 0 R (page.86) 1560 0 R (page.87) 1572 0 R (page.88) 1580 0 R (page.89) 1588 0 R (page.9) 974 0 R (page.90) 1595 0 R (page.91) 1604 0 R (page.92) 1614 0 R (page.93) 1621 0 R (page.94) 1632 0 R (page.95) 1636 0 R (page.96) 1642 0 R (page.97) 1653 0 R (page.98) 1658 0 R (page.99) 1662 0 R (proposed_standards) 1086 0 R (query_address) 1343 0 R (rfcs) 970 0 R (rndc) 1215 0 R (root_delegation_only) 1463 0 R (rrset_ordering) 1025 0 R (sample_configuration) 1011 0 R (section*.10) 1823 0 R (section*.100) 2109 0 R (section*.101) 2110 0 R (section*.102) 2112 0 R (section*.103) 2113 0 R (section*.104) 2114 0 R (section*.105) 2119 0 R (section*.106) 2124 0 R (section*.107) 2125 0 R (section*.108) 2126 0 R (section*.109) 2128 0 R (section*.11) 1833 0 R (section*.110) 2129 0 R (section*.111) 2130 0 R (section*.112) 2131 0 R (section*.113) 2136 0 R (section*.114) 2137 0 R (section*.115) 2142 0 R (section*.12) 1853 0 R (section*.13) 1865 0 R (section*.14) 1891 0 R (section*.15) 1901 0 R (section*.16) 1902 0 R (section*.17) 1903 0 R (section*.18) 1908 0 R (section*.19) 1909 0 R (section*.2) 1689 0 R (section*.20) 1914 0 R (section*.21) 1924 0 R (section*.22) 1929 0 R (section*.23) 1930 0 R (section*.24) 1931 0 R (section*.25) 1932 0 R (section*.26) 1934 0 R (section*.27) 1935 0 R (section*.28) 1940 0 R (section*.29) 1945 0 R (section*.3) 1695 0 R (section*.30) 1946 0 R (section*.31) 1947 0 R (section*.32) 1949 0 R (section*.33) 1950 0 R (section*.34) 1951 0 R (section*.35) 1952 0 R (section*.36) 1957 0 R (section*.37) 1958 0 R (section*.38) 1959 0 R (section*.39) 1960 0 R (section*.4) 1703 0 R (section*.40) 1961 0 R (section*.41) 1963 0 R (section*.42) 1969 0 R (section*.43) 1970 0 R (section*.44) 1971 0 R (section*.45) 1976 0 R (section*.46) 1977 0 R (section*.47) 1978 0 R (section*.48) 1980 0 R (section*.49) 1981 0 R (section*.5) 1728 0 R (section*.50) 1982 0 R (section*.51) 1983 0 R (section*.52) 1992 0 R (section*.53) 1993 0 R (section*.54) 1994 0 R (section*.55) 1995 0 R (section*.56) 1997 0 R (section*.57) 1998 0 R (section*.58) 2003 0 R (section*.59) 2004 0 R (section*.6) 1740 0 R (section*.60) 2014 0 R (section*.61) 2015 0 R (section*.62) 2020 0 R (section*.63) 2021 0 R (section*.64) 2023 0 R (section*.65) 2024 0 R (section*.66) 2025 0 R (section*.67) 2026 0 R (section*.68) 2027 0 R (section*.69) 2028 0 R (section*.7) 1755 0 R (section*.70) 2033 0 R (section*.71) 2035 0 R (section*.72) 2036 0 R (section*.73) 2037 0 R (section*.74) 2038 0 R (section*.75) 2047 0 R (section*.76) 2048 0 R (section*.77) 2049 0 R (section*.78) 2051 0 R (section*.79) 2052 0 R (section*.8) 1793 0 R (section*.80) 2053 0 R (section*.81) 2054 0 R (section*.82) 2064 0 R (section*.83) 2065 0 R (section*.84) 2070 0 R (section*.85) 2071 0 R (section*.86) 2072 0 R (section*.87) 2074 0 R (section*.88) 2075 0 R (section*.89) 2076 0 R (section*.9) 1811 0 R (section*.90) 2081 0 R (section*.91) 2090 0 R (section*.92) 2091 0 R (section*.93) 2092 0 R (section*.94) 2093 0 R (section*.95) 2099 0 R (section*.96) 2100 0 R (section*.97) 2101 0 R (section*.98) 2102 0 R (section*.99) 2108 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 482 0 R (section.6.4) 538 0 R (section.7.1) 574 0 R (section.7.2) 578 0 R (section.7.3) 590 0 R (section.8.1) 598 0 R (section.8.2) 606 0 R (section.8.3) 610 0 R (section.A.1) 618 0 R (section.A.2) 626 0 R (section.A.3) 634 0 R (section.B.1) 654 0 R (section.B.10) 690 0 R (section.B.11) 694 0 R (section.B.12) 698 0 R (section.B.13) 702 0 R (section.B.2) 658 0 R (section.B.3) 662 0 R (section.B.4) 666 0 R (section.B.5) 670 0 R (section.B.6) 674 0 R (section.B.7) 678 0 R (section.B.8) 682 0 R (section.B.9) 686 0 R (server_resource_limits) 1365 0 R (server_statement_definition_and_usage) 1307 0 R (server_statement_grammar) 1419 0 R (statistics) 1589 0 R (statistics_counters) 1597 0 R (statschannels) 1426 0 R (statsfile) 1286 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 330 0 R (subsection.6.2.12) 334 0 R (subsection.6.2.13) 338 0 R (subsection.6.2.14) 342 0 R (subsection.6.2.15) 346 0 R (subsection.6.2.16) 350 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.25) 458 0 R (subsection.6.2.26) 462 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 486 0 R (subsection.6.3.2) 498 0 R (subsection.6.3.3) 502 0 R (subsection.6.3.4) 506 0 R (subsection.6.3.5) 510 0 R (subsection.6.3.6) 530 0 R (subsection.6.3.7) 534 0 R (subsection.6.4.1) 546 0 R (subsection.7.2.1) 582 0 R (subsection.7.2.2) 586 0 R (subsection.8.1.1) 602 0 R (subsection.A.1.1) 622 0 R (subsection.A.2.1) 630 0 R (subsection.A.3.1) 638 0 R (subsection.A.3.2) 642 0 R (subsection.A.3.3) 646 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.10.3) 326 0 R (subsubsection.6.2.16.1) 354 0 R (subsubsection.6.2.16.10) 390 0 R (subsubsection.6.2.16.11) 394 0 R (subsubsection.6.2.16.12) 398 0 R (subsubsection.6.2.16.13) 402 0 R (subsubsection.6.2.16.14) 406 0 R (subsubsection.6.2.16.15) 410 0 R (subsubsection.6.2.16.16) 414 0 R (subsubsection.6.2.16.17) 418 0 R (subsubsection.6.2.16.18) 422 0 R (subsubsection.6.2.16.2) 358 0 R (subsubsection.6.2.16.3) 362 0 R (subsubsection.6.2.16.4) 366 0 R (subsubsection.6.2.16.5) 370 0 R (subsubsection.6.2.16.6) 374 0 R (subsubsection.6.2.16.7) 378 0 R (subsubsection.6.2.16.8) 382 0 R (subsubsection.6.2.16.9) 386 0 R (subsubsection.6.2.26.1) 466 0 R (subsubsection.6.2.26.2) 470 0 R (subsubsection.6.2.26.3) 474 0 R (subsubsection.6.2.26.4) 478 0 R (subsubsection.6.3.1.1) 490 0 R (subsubsection.6.3.1.2) 494 0 R (subsubsection.6.3.5.1) 514 0 R (subsubsection.6.3.5.2) 518 0 R (subsubsection.6.3.5.3) 522 0 R (subsubsection.6.3.5.4) 526 0 R (subsubsection.6.4.0.1) 542 0 R (subsubsection.6.4.1.1) 550 0 R (subsubsection.6.4.1.2) 554 0 R (subsubsection.6.4.1.3) 558 0 R (subsubsection.6.4.1.4) 562 0 R (subsubsection.6.4.1.5) 566 0 R (table.1.1) 952 0 R (table.1.2) 962 0 R (table.3.1) 1021 0 R (table.3.2) 1053 0 R (table.6.1) 1173 0 R (table.6.10) 1533 0 R (table.6.11) 1535 0 R (table.6.12) 1545 0 R (table.6.13) 1552 0 R (table.6.14) 1554 0 R (table.6.15) 1562 0 R (table.6.16) 1565 0 R (table.6.17) 1568 0 R (table.6.18) 1584 0 R (table.6.19) 1591 0 R (table.6.2) 1196 0 R (table.6.20) 1600 0 R (table.6.21) 1608 0 R (table.6.22) 1617 0 R (table.6.23) 1624 0 R (table.6.3) 1204 0 R (table.6.4) 1243 0 R (table.6.5) 1255 0 R (table.6.6) 1296 0 R (table.6.7) 1386 0 R (table.6.8) 1456 0 R (table.6.9) 1523 0 R (the_category_phrase) 1237 0 R (the_sortlist_statement) 1377 0 R (topology) 1372 0 R (tsig) 1100 0 R (tuning) 1391 0 R (types_of_resource_records_and_when_to_use_them) 969 0 R (view_statement_grammar) 1410 0 R (zone_statement_grammar) 1326 0 R (zone_transfers) 1076 0 R (zonefile_format) 1402 0 R]
/Limits [(Access_Control_Lists) (zonefile_format)]
>> endobj
-2146 0 obj <<
-/Kids [2145 0 R]
+2168 0 obj <<
+/Kids [2167 0 R]
>> endobj
-2147 0 obj <<
-/Dests 2146 0 R
+2169 0 obj <<
+/Dests 2168 0 R
>> endobj
-2148 0 obj <<
+2170 0 obj <<
/Type /Catalog
-/Pages 2143 0 R
-/Outlines 2144 0 R
-/Names 2147 0 R
+/Pages 2165 0 R
+/Outlines 2166 0 R
+/Names 2169 0 R
/PageMode /UseOutlines
-/OpenAction 701 0 R
+/OpenAction 705 0 R
>> endobj
-2149 0 obj <<
+2171 0 obj <<
/Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords()
-/CreationDate (D:20091231231729Z)
+/CreationDate (D:20100225121620Z)
/PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4)
>> endobj
xref
-0 2150
+0 2172
0000000001 65535 f
0000000002 00000 f
0000000003 00000 f
0000000004 00000 f
0000000000 00000 f
0000000009 00000 n
-0000071459 00000 n
-0000744619 00000 n
+0000071778 00000 n
+0000753335 00000 n
0000000054 00000 n
0000000086 00000 n
-0000071583 00000 n
-0000744547 00000 n
+0000071902 00000 n
+0000753263 00000 n
0000000133 00000 n
0000000173 00000 n
-0000071708 00000 n
-0000744461 00000 n
+0000072027 00000 n
+0000753177 00000 n
0000000221 00000 n
0000000273 00000 n
-0000071833 00000 n
-0000744375 00000 n
+0000072152 00000 n
+0000753091 00000 n
0000000321 00000 n
0000000377 00000 n
-0000076158 00000 n
-0000744265 00000 n
+0000076477 00000 n
+0000752981 00000 n
0000000425 00000 n
0000000478 00000 n
-0000076282 00000 n
-0000744191 00000 n
+0000076601 00000 n
+0000752907 00000 n
0000000531 00000 n
0000000572 00000 n
-0000076407 00000 n
-0000744104 00000 n
+0000076726 00000 n
+0000752820 00000 n
0000000625 00000 n
0000000674 00000 n
-0000076531 00000 n
-0000744017 00000 n
+0000076850 00000 n
+0000752733 00000 n
0000000727 00000 n
0000000757 00000 n
-0000080810 00000 n
-0000743893 00000 n
+0000081129 00000 n
+0000752609 00000 n
0000000810 00000 n
0000000861 00000 n
-0000080935 00000 n
-0000743819 00000 n
+0000081254 00000 n
+0000752535 00000 n
0000000919 00000 n
0000000964 00000 n
-0000081060 00000 n
-0000743732 00000 n
+0000081379 00000 n
+0000752448 00000 n
0000001022 00000 n
0000001062 00000 n
-0000081185 00000 n
-0000743658 00000 n
+0000081504 00000 n
+0000752374 00000 n
0000001120 00000 n
0000001162 00000 n
-0000084157 00000 n
-0000743534 00000 n
+0000084476 00000 n
+0000752250 00000 n
0000001215 00000 n
0000001260 00000 n
-0000084282 00000 n
-0000743473 00000 n
+0000084601 00000 n
+0000752189 00000 n
0000001318 00000 n
0000001355 00000 n
-0000084407 00000 n
-0000743399 00000 n
+0000084726 00000 n
+0000752115 00000 n
0000001408 00000 n
0000001463 00000 n
-0000087335 00000 n
-0000743274 00000 n
+0000087654 00000 n
+0000751990 00000 n
0000001509 00000 n
0000001556 00000 n
-0000087460 00000 n
-0000743200 00000 n
+0000087779 00000 n
+0000751916 00000 n
0000001604 00000 n
0000001648 00000 n
-0000087585 00000 n
-0000743113 00000 n
+0000087904 00000 n
+0000751829 00000 n
0000001696 00000 n
0000001735 00000 n
-0000087710 00000 n
-0000743026 00000 n
+0000088029 00000 n
+0000751742 00000 n
0000001783 00000 n
0000001825 00000 n
-0000087834 00000 n
-0000742939 00000 n
+0000088153 00000 n
+0000751655 00000 n
0000001873 00000 n
0000001936 00000 n
-0000088914 00000 n
-0000742865 00000 n
+0000089239 00000 n
+0000751581 00000 n
0000001984 00000 n
0000002034 00000 n
-0000090625 00000 n
-0000742737 00000 n
+0000090953 00000 n
+0000751453 00000 n
0000002080 00000 n
0000002126 00000 n
-0000090752 00000 n
-0000742624 00000 n
+0000091080 00000 n
+0000751340 00000 n
0000002174 00000 n
0000002218 00000 n
-0000090880 00000 n
-0000742548 00000 n
+0000091208 00000 n
+0000751264 00000 n
0000002271 00000 n
0000002323 00000 n
-0000091008 00000 n
-0000742471 00000 n
+0000091336 00000 n
+0000751187 00000 n
0000002377 00000 n
0000002436 00000 n
-0000093550 00000 n
-0000742380 00000 n
+0000093878 00000 n
+0000751096 00000 n
0000002485 00000 n
0000002523 00000 n
-0000093809 00000 n
-0000742263 00000 n
+0000094137 00000 n
+0000750979 00000 n
0000002572 00000 n
0000002618 00000 n
-0000093938 00000 n
-0000742145 00000 n
+0000094266 00000 n
+0000750861 00000 n
0000002672 00000 n
0000002739 00000 n
-0000097170 00000 n
-0000742066 00000 n
+0000097498 00000 n
+0000750782 00000 n
0000002798 00000 n
0000002842 00000 n
-0000097298 00000 n
-0000741987 00000 n
+0000097626 00000 n
+0000750703 00000 n
0000002901 00000 n
0000002949 00000 n
-0000107947 00000 n
-0000741908 00000 n
+0000108275 00000 n
+0000750624 00000 n
0000003003 00000 n
0000003036 00000 n
-0000112966 00000 n
-0000741776 00000 n
+0000113294 00000 n
+0000750492 00000 n
0000003083 00000 n
0000003126 00000 n
-0000113095 00000 n
-0000741697 00000 n
+0000113423 00000 n
+0000750413 00000 n
0000003175 00000 n
0000003205 00000 n
-0000113224 00000 n
-0000741565 00000 n
+0000113552 00000 n
+0000750281 00000 n
0000003254 00000 n
0000003292 00000 n
-0000113353 00000 n
-0000741500 00000 n
+0000113681 00000 n
+0000750216 00000 n
0000003346 00000 n
0000003388 00000 n
-0000117615 00000 n
-0000741407 00000 n
+0000118088 00000 n
+0000750123 00000 n
0000003437 00000 n
0000003496 00000 n
-0000117744 00000 n
-0000741275 00000 n
+0000118217 00000 n
+0000749991 00000 n
0000003545 00000 n
0000003578 00000 n
-0000117873 00000 n
-0000741210 00000 n
+0000118346 00000 n
+0000749926 00000 n
0000003632 00000 n
0000003681 00000 n
-0000125183 00000 n
-0000741078 00000 n
+0000125674 00000 n
+0000749794 00000 n
0000003730 00000 n
0000003758 00000 n
-0000125312 00000 n
-0000740960 00000 n
+0000125803 00000 n
+0000749676 00000 n
0000003812 00000 n
0000003881 00000 n
-0000125441 00000 n
-0000740881 00000 n
+0000125932 00000 n
+0000749597 00000 n
0000003940 00000 n
0000003988 00000 n
-0000128293 00000 n
-0000740802 00000 n
+0000128724 00000 n
+0000749518 00000 n
0000004047 00000 n
0000004092 00000 n
-0000128422 00000 n
-0000740709 00000 n
+0000128853 00000 n
+0000749425 00000 n
0000004146 00000 n
0000004214 00000 n
-0000128551 00000 n
-0000740616 00000 n
+0000128982 00000 n
+0000749332 00000 n
0000004268 00000 n
0000004338 00000 n
-0000128680 00000 n
-0000740523 00000 n
+0000129111 00000 n
+0000749239 00000 n
0000004392 00000 n
0000004455 00000 n
-0000132601 00000 n
-0000740430 00000 n
+0000133032 00000 n
+0000749146 00000 n
0000004509 00000 n
0000004564 00000 n
-0000132730 00000 n
-0000740351 00000 n
+0000133161 00000 n
+0000749067 00000 n
0000004618 00000 n
0000004650 00000 n
-0000132859 00000 n
-0000740258 00000 n
+0000133290 00000 n
+0000748974 00000 n
0000004699 00000 n
0000004727 00000 n
-0000132988 00000 n
-0000740165 00000 n
+0000133419 00000 n
+0000748881 00000 n
0000004776 00000 n
0000004808 00000 n
-0000136765 00000 n
-0000740033 00000 n
+0000137196 00000 n
+0000748749 00000 n
0000004857 00000 n
0000004887 00000 n
-0000136894 00000 n
-0000739954 00000 n
+0000137325 00000 n
+0000748670 00000 n
0000004941 00000 n
0000004982 00000 n
-0000137023 00000 n
-0000739861 00000 n
+0000137454 00000 n
+0000748577 00000 n
0000005036 00000 n
0000005078 00000 n
-0000140484 00000 n
-0000739782 00000 n
+0000141049 00000 n
+0000748498 00000 n
0000005132 00000 n
0000005177 00000 n
-0000143559 00000 n
-0000739664 00000 n
+0000144495 00000 n
+0000748380 00000 n
0000005226 00000 n
0000005272 00000 n
-0000143688 00000 n
-0000739585 00000 n
+0000146096 00000 n
+0000748301 00000 n
0000005326 00000 n
0000005386 00000 n
-0000143816 00000 n
-0000739506 00000 n
+0000146225 00000 n
+0000748222 00000 n
0000005440 00000 n
0000005509 00000 n
-0000146298 00000 n
-0000739373 00000 n
+0000149032 00000 n
+0000748089 00000 n
0000005556 00000 n
0000005609 00000 n
-0000146427 00000 n
-0000739294 00000 n
+0000149161 00000 n
+0000748010 00000 n
0000005658 00000 n
0000005714 00000 n
-0000146556 00000 n
-0000739215 00000 n
+0000149290 00000 n
+0000747931 00000 n
0000005763 00000 n
0000005812 00000 n
-0000150740 00000 n
-0000739082 00000 n
+0000153474 00000 n
+0000747798 00000 n
0000005859 00000 n
0000005911 00000 n
-0000150869 00000 n
-0000738964 00000 n
+0000153603 00000 n
+0000747680 00000 n
0000005960 00000 n
0000006011 00000 n
-0000155559 00000 n
-0000738846 00000 n
+0000158293 00000 n
+0000747562 00000 n
0000006065 00000 n
0000006110 00000 n
-0000155687 00000 n
-0000738767 00000 n
+0000158421 00000 n
+0000747483 00000 n
0000006169 00000 n
0000006203 00000 n
-0000159308 00000 n
-0000738688 00000 n
+0000162042 00000 n
+0000747404 00000 n
0000006262 00000 n
0000006310 00000 n
-0000159436 00000 n
-0000738570 00000 n
+0000162170 00000 n
+0000747286 00000 n
0000006364 00000 n
0000006404 00000 n
-0000159565 00000 n
-0000738491 00000 n
+0000162299 00000 n
+0000747207 00000 n
0000006463 00000 n
0000006497 00000 n
-0000163504 00000 n
-0000738412 00000 n
+0000166238 00000 n
+0000747128 00000 n
0000006556 00000 n
0000006604 00000 n
-0000163633 00000 n
-0000738279 00000 n
+0000166367 00000 n
+0000746995 00000 n
0000006653 00000 n
0000006703 00000 n
-0000166453 00000 n
-0000738200 00000 n
+0000169187 00000 n
+0000746916 00000 n
0000006757 00000 n
0000006804 00000 n
-0000166581 00000 n
-0000738107 00000 n
+0000169315 00000 n
+0000746823 00000 n
0000006858 00000 n
0000006918 00000 n
-0000166840 00000 n
-0000738014 00000 n
+0000169574 00000 n
+0000746730 00000 n
0000006972 00000 n
0000007024 00000 n
-0000172189 00000 n
-0000737921 00000 n
+0000174923 00000 n
+0000746637 00000 n
0000007078 00000 n
0000007143 00000 n
-0000172318 00000 n
-0000737828 00000 n
+0000175052 00000 n
+0000746544 00000 n
0000007197 00000 n
0000007248 00000 n
-0000172447 00000 n
-0000737735 00000 n
+0000175181 00000 n
+0000746451 00000 n
0000007302 00000 n
0000007366 00000 n
-0000175899 00000 n
-0000737642 00000 n
+0000178633 00000 n
+0000746358 00000 n
0000007420 00000 n
0000007467 00000 n
-0000176028 00000 n
-0000737549 00000 n
+0000178762 00000 n
+0000746265 00000 n
0000007521 00000 n
0000007581 00000 n
-0000176157 00000 n
-0000737456 00000 n
+0000178891 00000 n
+0000746172 00000 n
0000007635 00000 n
0000007686 00000 n
-0000176286 00000 n
-0000737324 00000 n
+0000179020 00000 n
+0000746040 00000 n
0000007741 00000 n
0000007806 00000 n
-0000180517 00000 n
-0000737245 00000 n
+0000183251 00000 n
+0000745961 00000 n
0000007866 00000 n
0000007913 00000 n
-0000187075 00000 n
-0000737152 00000 n
+0000189809 00000 n
+0000745868 00000 n
0000007973 00000 n
0000008021 00000 n
-0000194627 00000 n
-0000737073 00000 n
+0000197361 00000 n
+0000745789 00000 n
0000008081 00000 n
0000008135 00000 n
-0000194886 00000 n
-0000736980 00000 n
+0000197620 00000 n
+0000745696 00000 n
0000008190 00000 n
0000008240 00000 n
-0000197709 00000 n
-0000736887 00000 n
+0000200443 00000 n
+0000745603 00000 n
0000008295 00000 n
0000008358 00000 n
-0000197838 00000 n
-0000736794 00000 n
+0000200572 00000 n
+0000745510 00000 n
0000008413 00000 n
0000008465 00000 n
-0000197967 00000 n
-0000736701 00000 n
+0000200701 00000 n
+0000745417 00000 n
0000008520 00000 n
0000008585 00000 n
-0000198096 00000 n
-0000736608 00000 n
+0000200830 00000 n
+0000745324 00000 n
0000008640 00000 n
0000008692 00000 n
-0000203976 00000 n
-0000736475 00000 n
+0000206840 00000 n
+0000745191 00000 n
0000008747 00000 n
0000008812 00000 n
-0000212370 00000 n
-0000736396 00000 n
+0000215241 00000 n
+0000745112 00000 n
0000008872 00000 n
0000008916 00000 n
-0000233628 00000 n
-0000736303 00000 n
+0000236497 00000 n
+0000745019 00000 n
0000008976 00000 n
0000009015 00000 n
-0000233757 00000 n
-0000736210 00000 n
+0000236626 00000 n
+0000744926 00000 n
0000009075 00000 n
0000009122 00000 n
-0000233886 00000 n
-0000736117 00000 n
+0000236755 00000 n
+0000744833 00000 n
0000009182 00000 n
0000009225 00000 n
-0000240979 00000 n
-0000736024 00000 n
+0000243668 00000 n
+0000744740 00000 n
0000009285 00000 n
0000009324 00000 n
-0000241107 00000 n
-0000735931 00000 n
+0000247184 00000 n
+0000744647 00000 n
0000009384 00000 n
0000009426 00000 n
-0000248082 00000 n
-0000735838 00000 n
+0000250363 00000 n
+0000744554 00000 n
0000009486 00000 n
0000009529 00000 n
-0000255955 00000 n
-0000735745 00000 n
+0000257930 00000 n
+0000744461 00000 n
0000009589 00000 n
0000009632 00000 n
-0000256084 00000 n
-0000735652 00000 n
+0000258059 00000 n
+0000744368 00000 n
0000009692 00000 n
0000009753 00000 n
-0000260235 00000 n
-0000735559 00000 n
+0000262252 00000 n
+0000744275 00000 n
0000009814 00000 n
0000009866 00000 n
-0000263744 00000 n
-0000735466 00000 n
+0000266146 00000 n
+0000744182 00000 n
0000009927 00000 n
0000009980 00000 n
-0000263873 00000 n
-0000735373 00000 n
+0000266275 00000 n
+0000744089 00000 n
0000010041 00000 n
0000010079 00000 n
-0000267780 00000 n
-0000735280 00000 n
+0000270312 00000 n
+0000743996 00000 n
0000010140 00000 n
0000010192 00000 n
-0000271179 00000 n
-0000735187 00000 n
+0000273468 00000 n
+0000743903 00000 n
0000010253 00000 n
0000010297 00000 n
-0000275345 00000 n
-0000735094 00000 n
+0000277408 00000 n
+0000743810 00000 n
0000010358 00000 n
0000010394 00000 n
-0000280135 00000 n
-0000735001 00000 n
+0000285781 00000 n
+0000743717 00000 n
0000010455 00000 n
0000010518 00000 n
-0000283544 00000 n
-0000734908 00000 n
+0000285910 00000 n
+0000743624 00000 n
0000010579 00000 n
0000010629 00000 n
-0000287237 00000 n
-0000734829 00000 n
+0000289666 00000 n
+0000743545 00000 n
0000010690 00000 n
0000010746 00000 n
-0000290642 00000 n
-0000734736 00000 n
+0000292910 00000 n
+0000743452 00000 n
0000010801 00000 n
0000010852 00000 n
-0000290771 00000 n
-0000734643 00000 n
+0000293039 00000 n
+0000743359 00000 n
0000010907 00000 n
0000010971 00000 n
-0000295142 00000 n
-0000734550 00000 n
+0000297800 00000 n
+0000743266 00000 n
0000011026 00000 n
0000011090 00000 n
-0000295271 00000 n
-0000734457 00000 n
+0000301569 00000 n
+0000743173 00000 n
0000011145 00000 n
0000011222 00000 n
-0000298928 00000 n
-0000734364 00000 n
+0000301698 00000 n
+0000743080 00000 n
0000011277 00000 n
0000011334 00000 n
-0000299057 00000 n
-0000734271 00000 n
+0000301827 00000 n
+0000742987 00000 n
0000011389 00000 n
0000011459 00000 n
-0000299186 00000 n
-0000734178 00000 n
+0000301956 00000 n
+0000742894 00000 n
0000011514 00000 n
0000011563 00000 n
-0000302629 00000 n
-0000734085 00000 n
+0000305399 00000 n
+0000742801 00000 n
0000011618 00000 n
0000011680 00000 n
-0000304248 00000 n
-0000733992 00000 n
+0000307024 00000 n
+0000742708 00000 n
0000011735 00000 n
0000011784 00000 n
-0000308427 00000 n
-0000733874 00000 n
+0000311203 00000 n
+0000742590 00000 n
0000011839 00000 n
0000011901 00000 n
-0000308556 00000 n
-0000733795 00000 n
+0000311332 00000 n
+0000742511 00000 n
0000011961 00000 n
0000012000 00000 n
-0000312881 00000 n
-0000733702 00000 n
+0000315657 00000 n
+0000742418 00000 n
0000012060 00000 n
0000012094 00000 n
-0000318771 00000 n
-0000733609 00000 n
+0000321547 00000 n
+0000742325 00000 n
0000012154 00000 n
0000012195 00000 n
-0000330157 00000 n
-0000733530 00000 n
+0000332933 00000 n
+0000742246 00000 n
0000012255 00000 n
0000012307 00000 n
-0000337397 00000 n
-0000733398 00000 n
+0000340173 00000 n
+0000742114 00000 n
0000012356 00000 n
0000012389 00000 n
-0000337526 00000 n
-0000733280 00000 n
+0000340302 00000 n
+0000741996 00000 n
0000012443 00000 n
0000012515 00000 n
-0000337654 00000 n
-0000733201 00000 n
+0000340430 00000 n
+0000741917 00000 n
0000012574 00000 n
0000012618 00000 n
-0000348444 00000 n
-0000733122 00000 n
+0000351220 00000 n
+0000741838 00000 n
0000012677 00000 n
0000012730 00000 n
-0000348831 00000 n
-0000733029 00000 n
+0000351607 00000 n
+0000741745 00000 n
0000012784 00000 n
0000012834 00000 n
-0000352195 00000 n
-0000732936 00000 n
+0000354971 00000 n
+0000741652 00000 n
0000012888 00000 n
0000012926 00000 n
-0000352454 00000 n
-0000732843 00000 n
+0000355230 00000 n
+0000741559 00000 n
0000012980 00000 n
0000013029 00000 n
-0000355319 00000 n
-0000732711 00000 n
+0000358315 00000 n
+0000741427 00000 n
0000013083 00000 n
0000013135 00000 n
-0000355447 00000 n
-0000732632 00000 n
+0000358444 00000 n
+0000741348 00000 n
0000013194 00000 n
-0000013246 00000 n
-0000355576 00000 n
-0000732539 00000 n
-0000013305 00000 n
-0000013358 00000 n
-0000355705 00000 n
-0000732460 00000 n
-0000013417 00000 n
-0000013466 00000 n
-0000359352 00000 n
-0000732367 00000 n
-0000013520 00000 n
-0000013600 00000 n
-0000363488 00000 n
-0000732288 00000 n
-0000013654 00000 n
-0000013703 00000 n
-0000363617 00000 n
-0000732170 00000 n
-0000013752 00000 n
-0000013792 00000 n
-0000366917 00000 n
-0000732091 00000 n
-0000013851 00000 n
-0000013898 00000 n
-0000367046 00000 n
-0000731973 00000 n
-0000013952 00000 n
-0000013997 00000 n
-0000367175 00000 n
-0000731894 00000 n
+0000013239 00000 n
+0000358573 00000 n
+0000741255 00000 n
+0000013298 00000 n
+0000013350 00000 n
+0000358702 00000 n
+0000741162 00000 n
+0000013409 00000 n
+0000013462 00000 n
+0000362349 00000 n
+0000741083 00000 n
+0000013521 00000 n
+0000013570 00000 n
+0000362477 00000 n
+0000740990 00000 n
+0000013624 00000 n
+0000013704 00000 n
+0000366241 00000 n
+0000740911 00000 n
+0000013758 00000 n
+0000013807 00000 n
+0000366370 00000 n
+0000740793 00000 n
+0000013856 00000 n
+0000013896 00000 n
+0000369810 00000 n
+0000740714 00000 n
+0000013955 00000 n
+0000014002 00000 n
+0000369939 00000 n
+0000740596 00000 n
0000014056 00000 n
-0000014115 00000 n
-0000370864 00000 n
-0000731801 00000 n
-0000014174 00000 n
-0000014238 00000 n
-0000374585 00000 n
-0000731708 00000 n
-0000014297 00000 n
-0000014353 00000 n
-0000374843 00000 n
-0000731615 00000 n
-0000014412 00000 n
-0000014470 00000 n
-0000377514 00000 n
-0000731536 00000 n
-0000014529 00000 n
-0000014591 00000 n
-0000379759 00000 n
-0000731403 00000 n
-0000014638 00000 n
-0000014690 00000 n
-0000379888 00000 n
-0000731324 00000 n
-0000014739 00000 n
-0000014783 00000 n
-0000384086 00000 n
-0000731192 00000 n
-0000014832 00000 n
-0000014873 00000 n
-0000384215 00000 n
-0000731113 00000 n
-0000014927 00000 n
-0000014975 00000 n
-0000384343 00000 n
-0000731034 00000 n
-0000015029 00000 n
-0000015080 00000 n
-0000384472 00000 n
-0000730955 00000 n
-0000015129 00000 n
-0000015176 00000 n
-0000388739 00000 n
-0000730822 00000 n
-0000015223 00000 n
-0000015260 00000 n
-0000388868 00000 n
-0000730704 00000 n
-0000015309 00000 n
-0000015348 00000 n
-0000388997 00000 n
-0000730639 00000 n
-0000015402 00000 n
-0000015480 00000 n
-0000389126 00000 n
-0000730546 00000 n
-0000015529 00000 n
-0000015596 00000 n
-0000389255 00000 n
-0000730467 00000 n
-0000015645 00000 n
-0000015690 00000 n
-0000392694 00000 n
-0000730334 00000 n
-0000015738 00000 n
-0000015770 00000 n
-0000392823 00000 n
-0000730216 00000 n
-0000015819 00000 n
-0000015858 00000 n
-0000392952 00000 n
-0000730151 00000 n
-0000015912 00000 n
-0000015973 00000 n
-0000396633 00000 n
-0000730019 00000 n
-0000016022 00000 n
-0000016079 00000 n
-0000396762 00000 n
-0000729954 00000 n
-0000016133 00000 n
-0000016182 00000 n
-0000396891 00000 n
-0000729836 00000 n
-0000016231 00000 n
-0000016293 00000 n
-0000397020 00000 n
-0000729757 00000 n
-0000016347 00000 n
-0000016402 00000 n
-0000421042 00000 n
-0000729664 00000 n
-0000016456 00000 n
-0000016497 00000 n
-0000421171 00000 n
-0000729585 00000 n
-0000016551 00000 n
-0000016603 00000 n
-0000423902 00000 n
-0000729465 00000 n
-0000016651 00000 n
-0000016685 00000 n
-0000424031 00000 n
-0000729386 00000 n
-0000016734 00000 n
-0000016761 00000 n
-0000441854 00000 n
-0000729293 00000 n
-0000016810 00000 n
+0000014101 00000 n
+0000370068 00000 n
+0000740517 00000 n
+0000014160 00000 n
+0000014219 00000 n
+0000373824 00000 n
+0000740424 00000 n
+0000014278 00000 n
+0000014342 00000 n
+0000377291 00000 n
+0000740331 00000 n
+0000014401 00000 n
+0000014457 00000 n
+0000380308 00000 n
+0000740238 00000 n
+0000014516 00000 n
+0000014574 00000 n
+0000380566 00000 n
+0000740159 00000 n
+0000014633 00000 n
+0000014695 00000 n
+0000382811 00000 n
+0000740026 00000 n
+0000014742 00000 n
+0000014794 00000 n
+0000382940 00000 n
+0000739947 00000 n
+0000014843 00000 n
+0000014887 00000 n
+0000387139 00000 n
+0000739815 00000 n
+0000014936 00000 n
+0000014977 00000 n
+0000387268 00000 n
+0000739736 00000 n
+0000015031 00000 n
+0000015079 00000 n
+0000387396 00000 n
+0000739657 00000 n
+0000015133 00000 n
+0000015184 00000 n
+0000387525 00000 n
+0000739578 00000 n
+0000015233 00000 n
+0000015280 00000 n
+0000391792 00000 n
+0000739445 00000 n
+0000015327 00000 n
+0000015364 00000 n
+0000391921 00000 n
+0000739327 00000 n
+0000015413 00000 n
+0000015452 00000 n
+0000392050 00000 n
+0000739262 00000 n
+0000015506 00000 n
+0000015584 00000 n
+0000392179 00000 n
+0000739169 00000 n
+0000015633 00000 n
+0000015700 00000 n
+0000392308 00000 n
+0000739090 00000 n
+0000015749 00000 n
+0000015794 00000 n
+0000395748 00000 n
+0000738957 00000 n
+0000015842 00000 n
+0000015874 00000 n
+0000395877 00000 n
+0000738839 00000 n
+0000015923 00000 n
+0000015962 00000 n
+0000396006 00000 n
+0000738774 00000 n
+0000016016 00000 n
+0000016077 00000 n
+0000399687 00000 n
+0000738642 00000 n
+0000016126 00000 n
+0000016183 00000 n
+0000399816 00000 n
+0000738577 00000 n
+0000016237 00000 n
+0000016286 00000 n
+0000399945 00000 n
+0000738459 00000 n
+0000016335 00000 n
+0000016397 00000 n
+0000400074 00000 n
+0000738380 00000 n
+0000016451 00000 n
+0000016506 00000 n
+0000424096 00000 n
+0000738287 00000 n
+0000016560 00000 n
+0000016601 00000 n
+0000424225 00000 n
+0000738208 00000 n
+0000016655 00000 n
+0000016707 00000 n
+0000426956 00000 n
+0000738088 00000 n
+0000016755 00000 n
+0000016789 00000 n
+0000427085 00000 n
+0000738009 00000 n
0000016838 00000 n
-0000449343 00000 n
-0000729200 00000 n
-0000016887 00000 n
-0000016927 00000 n
-0000452138 00000 n
-0000729107 00000 n
-0000016976 00000 n
-0000017019 00000 n
-0000458062 00000 n
-0000729014 00000 n
-0000017068 00000 n
-0000017105 00000 n
-0000464564 00000 n
-0000728921 00000 n
-0000017154 00000 n
-0000017193 00000 n
-0000476717 00000 n
-0000728828 00000 n
-0000017242 00000 n
-0000017281 00000 n
-0000480140 00000 n
-0000728735 00000 n
-0000017330 00000 n
-0000017369 00000 n
-0000486583 00000 n
-0000728642 00000 n
-0000017418 00000 n
-0000017447 00000 n
-0000496757 00000 n
-0000728549 00000 n
-0000017497 00000 n
-0000017530 00000 n
-0000506693 00000 n
-0000728456 00000 n
-0000017580 00000 n
-0000017609 00000 n
-0000513987 00000 n
-0000728363 00000 n
-0000017659 00000 n
-0000017693 00000 n
-0000519675 00000 n
-0000728284 00000 n
-0000017743 00000 n
-0000017780 00000 n
-0000018149 00000 n
-0000018271 00000 n
-0000026100 00000 n
-0000017833 00000 n
-0000025974 00000 n
-0000026037 00000 n
-0000723763 00000 n
-0000697820 00000 n
-0000723589 00000 n
-0000724788 00000 n
-0000021134 00000 n
-0000021351 00000 n
-0000021420 00000 n
-0000021489 00000 n
-0000021557 00000 n
-0000021625 00000 n
-0000021674 00000 n
-0000021721 00000 n
-0000022054 00000 n
-0000022076 00000 n
-0000022244 00000 n
-0000022409 00000 n
-0000022578 00000 n
-0000022757 00000 n
-0000023066 00000 n
-0000023226 00000 n
-0000027466 00000 n
-0000027281 00000 n
-0000026200 00000 n
-0000027403 00000 n
-0000696599 00000 n
-0000670078 00000 n
-0000696425 00000 n
-0000669393 00000 n
-0000667249 00000 n
-0000669229 00000 n
-0000039173 00000 n
-0000030522 00000 n
-0000027551 00000 n
-0000039047 00000 n
-0000039110 00000 n
-0000031056 00000 n
-0000031210 00000 n
-0000031367 00000 n
-0000031524 00000 n
-0000031680 00000 n
-0000031837 00000 n
-0000031999 00000 n
-0000032160 00000 n
-0000032321 00000 n
-0000032483 00000 n
-0000032650 00000 n
-0000032817 00000 n
-0000032982 00000 n
-0000033144 00000 n
-0000033310 00000 n
-0000033471 00000 n
-0000033626 00000 n
-0000033783 00000 n
-0000033939 00000 n
-0000034096 00000 n
-0000034253 00000 n
-0000034410 00000 n
-0000034564 00000 n
-0000034720 00000 n
-0000034882 00000 n
-0000035044 00000 n
-0000035200 00000 n
-0000035357 00000 n
-0000035519 00000 n
-0000035686 00000 n
-0000035852 00000 n
-0000036013 00000 n
-0000036168 00000 n
-0000036325 00000 n
-0000036482 00000 n
-0000036644 00000 n
-0000036801 00000 n
-0000036958 00000 n
-0000037120 00000 n
-0000037277 00000 n
-0000037439 00000 n
-0000037606 00000 n
-0000037772 00000 n
-0000037934 00000 n
-0000038096 00000 n
-0000038258 00000 n
-0000038420 00000 n
-0000038582 00000 n
-0000038737 00000 n
-0000038892 00000 n
-0000052547 00000 n
-0000042497 00000 n
-0000039258 00000 n
-0000052484 00000 n
-0000666698 00000 n
-0000649617 00000 n
-0000666514 00000 n
-0000043087 00000 n
-0000043250 00000 n
-0000043412 00000 n
-0000043575 00000 n
-0000043733 00000 n
-0000043896 00000 n
-0000044059 00000 n
-0000044214 00000 n
-0000044372 00000 n
-0000044530 00000 n
-0000044686 00000 n
-0000044844 00000 n
-0000045007 00000 n
-0000045175 00000 n
-0000045343 00000 n
-0000045506 00000 n
-0000045674 00000 n
-0000045842 00000 n
-0000046000 00000 n
-0000046163 00000 n
-0000046326 00000 n
-0000046488 00000 n
-0000046650 00000 n
-0000046813 00000 n
-0000046975 00000 n
-0000047137 00000 n
-0000047300 00000 n
-0000047463 00000 n
-0000047626 00000 n
-0000047795 00000 n
-0000047964 00000 n
-0000048133 00000 n
-0000048296 00000 n
-0000048460 00000 n
-0000048624 00000 n
-0000048787 00000 n
-0000048951 00000 n
-0000049115 00000 n
-0000049283 00000 n
-0000049452 00000 n
-0000049621 00000 n
-0000049790 00000 n
-0000049959 00000 n
-0000050128 00000 n
-0000050297 00000 n
-0000050466 00000 n
-0000050635 00000 n
-0000050805 00000 n
-0000050975 00000 n
-0000051145 00000 n
-0000051315 00000 n
-0000051485 00000 n
-0000051655 00000 n
-0000051824 00000 n
-0000051994 00000 n
-0000052161 00000 n
-0000052322 00000 n
-0000065709 00000 n
-0000056176 00000 n
-0000052645 00000 n
-0000065646 00000 n
-0000056750 00000 n
-0000056913 00000 n
-0000057076 00000 n
-0000057239 00000 n
-0000057402 00000 n
-0000057565 00000 n
-0000057728 00000 n
-0000057890 00000 n
-0000058051 00000 n
-0000058218 00000 n
-0000058386 00000 n
-0000058554 00000 n
-0000058722 00000 n
-0000058879 00000 n
-0000059039 00000 n
-0000059205 00000 n
-0000059372 00000 n
-0000059534 00000 n
-0000059696 00000 n
-0000059858 00000 n
-0000060019 00000 n
-0000060185 00000 n
-0000060352 00000 n
-0000060519 00000 n
-0000060681 00000 n
-0000060843 00000 n
-0000061000 00000 n
-0000061167 00000 n
-0000061329 00000 n
-0000061496 00000 n
-0000061663 00000 n
-0000061830 00000 n
-0000648728 00000 n
-0000627397 00000 n
-0000648554 00000 n
-0000061997 00000 n
-0000062164 00000 n
-0000062318 00000 n
-0000062475 00000 n
-0000062632 00000 n
-0000062794 00000 n
-0000062956 00000 n
-0000063113 00000 n
-0000063268 00000 n
-0000063425 00000 n
-0000063587 00000 n
-0000063744 00000 n
-0000063901 00000 n
-0000064057 00000 n
-0000064214 00000 n
-0000064376 00000 n
-0000064533 00000 n
-0000064695 00000 n
-0000064852 00000 n
-0000065014 00000 n
-0000065176 00000 n
-0000065337 00000 n
-0000065491 00000 n
-0000068921 00000 n
-0000066744 00000 n
-0000065820 00000 n
-0000068858 00000 n
-0000066974 00000 n
-0000067131 00000 n
-0000067288 00000 n
-0000067444 00000 n
-0000067601 00000 n
-0000067758 00000 n
-0000067915 00000 n
-0000068072 00000 n
-0000068229 00000 n
-0000068385 00000 n
-0000626431 00000 n
-0000606464 00000 n
-0000626258 00000 n
-0000068543 00000 n
-0000068700 00000 n
-0000072084 00000 n
-0000071274 00000 n
+0000016865 00000 n
+0000444909 00000 n
+0000737916 00000 n
+0000016914 00000 n
+0000016942 00000 n
+0000452398 00000 n
+0000737823 00000 n
+0000016991 00000 n
+0000017031 00000 n
+0000455193 00000 n
+0000737730 00000 n
+0000017080 00000 n
+0000017123 00000 n
+0000461374 00000 n
+0000737637 00000 n
+0000017172 00000 n
+0000017209 00000 n
+0000467999 00000 n
+0000737544 00000 n
+0000017258 00000 n
+0000017297 00000 n
+0000480380 00000 n
+0000737451 00000 n
+0000017346 00000 n
+0000017385 00000 n
+0000483476 00000 n
+0000737358 00000 n
+0000017434 00000 n
+0000017473 00000 n
+0000489756 00000 n
+0000737265 00000 n
+0000017522 00000 n
+0000017551 00000 n
+0000499567 00000 n
+0000737172 00000 n
+0000017601 00000 n
+0000017634 00000 n
+0000513869 00000 n
+0000737079 00000 n
+0000017684 00000 n
+0000017713 00000 n
+0000517096 00000 n
+0000736986 00000 n
+0000017763 00000 n
+0000017797 00000 n
+0000523004 00000 n
+0000736907 00000 n
+0000017847 00000 n
+0000017884 00000 n
+0000018253 00000 n
+0000018375 00000 n
+0000026204 00000 n
+0000017937 00000 n
+0000026078 00000 n
+0000026141 00000 n
+0000732358 00000 n
+0000706415 00000 n
+0000732184 00000 n
+0000733383 00000 n
+0000021238 00000 n
+0000021455 00000 n
+0000021524 00000 n
+0000021593 00000 n
+0000021661 00000 n
+0000021729 00000 n
+0000021778 00000 n
+0000021825 00000 n
+0000022158 00000 n
+0000022180 00000 n
+0000022348 00000 n
+0000022513 00000 n
+0000022682 00000 n
+0000022861 00000 n
+0000023170 00000 n
+0000023330 00000 n
+0000027570 00000 n
+0000027385 00000 n
+0000026304 00000 n
+0000027507 00000 n
+0000705194 00000 n
+0000678673 00000 n
+0000705020 00000 n
+0000677988 00000 n
+0000675844 00000 n
+0000677824 00000 n
+0000039277 00000 n
+0000030626 00000 n
+0000027655 00000 n
+0000039151 00000 n
+0000039214 00000 n
+0000031160 00000 n
+0000031314 00000 n
+0000031471 00000 n
+0000031628 00000 n
+0000031784 00000 n
+0000031941 00000 n
+0000032103 00000 n
+0000032264 00000 n
+0000032425 00000 n
+0000032587 00000 n
+0000032754 00000 n
+0000032921 00000 n
+0000033086 00000 n
+0000033248 00000 n
+0000033414 00000 n
+0000033575 00000 n
+0000033730 00000 n
+0000033887 00000 n
+0000034043 00000 n
+0000034200 00000 n
+0000034357 00000 n
+0000034514 00000 n
+0000034668 00000 n
+0000034824 00000 n
+0000034986 00000 n
+0000035148 00000 n
+0000035304 00000 n
+0000035461 00000 n
+0000035623 00000 n
+0000035790 00000 n
+0000035956 00000 n
+0000036117 00000 n
+0000036272 00000 n
+0000036429 00000 n
+0000036586 00000 n
+0000036748 00000 n
+0000036905 00000 n
+0000037062 00000 n
+0000037224 00000 n
+0000037381 00000 n
+0000037543 00000 n
+0000037710 00000 n
+0000037876 00000 n
+0000038038 00000 n
+0000038200 00000 n
+0000038362 00000 n
+0000038524 00000 n
+0000038686 00000 n
+0000038841 00000 n
+0000038996 00000 n
+0000052649 00000 n
+0000042603 00000 n
+0000039362 00000 n
+0000052586 00000 n
+0000675293 00000 n
+0000658212 00000 n
+0000675109 00000 n
+0000043193 00000 n
+0000043356 00000 n
+0000043518 00000 n
+0000043681 00000 n
+0000043839 00000 n
+0000044002 00000 n
+0000044165 00000 n
+0000044320 00000 n
+0000044478 00000 n
+0000044636 00000 n
+0000044792 00000 n
+0000044950 00000 n
+0000045113 00000 n
+0000045281 00000 n
+0000045449 00000 n
+0000045612 00000 n
+0000045780 00000 n
+0000045948 00000 n
+0000046105 00000 n
+0000046268 00000 n
+0000046431 00000 n
+0000046593 00000 n
+0000046755 00000 n
+0000046918 00000 n
+0000047080 00000 n
+0000047242 00000 n
+0000047405 00000 n
+0000047568 00000 n
+0000047731 00000 n
+0000047899 00000 n
+0000048068 00000 n
+0000048237 00000 n
+0000048400 00000 n
+0000048564 00000 n
+0000048728 00000 n
+0000048891 00000 n
+0000049055 00000 n
+0000049219 00000 n
+0000049388 00000 n
+0000049557 00000 n
+0000049726 00000 n
+0000049895 00000 n
+0000050064 00000 n
+0000050233 00000 n
+0000050402 00000 n
+0000050571 00000 n
+0000050740 00000 n
+0000050910 00000 n
+0000051080 00000 n
+0000051249 00000 n
+0000051419 00000 n
+0000051589 00000 n
+0000051757 00000 n
+0000051926 00000 n
+0000052096 00000 n
+0000052263 00000 n
+0000052424 00000 n
+0000065826 00000 n
+0000056283 00000 n
+0000052747 00000 n
+0000065763 00000 n
+0000056857 00000 n
+0000057020 00000 n
+0000057183 00000 n
+0000057346 00000 n
+0000057509 00000 n
+0000057672 00000 n
+0000057835 00000 n
+0000057997 00000 n
+0000058160 00000 n
+0000058328 00000 n
+0000058496 00000 n
+0000058664 00000 n
+0000058832 00000 n
+0000058989 00000 n
+0000059149 00000 n
+0000059315 00000 n
+0000059482 00000 n
+0000059644 00000 n
+0000059806 00000 n
+0000059967 00000 n
+0000060128 00000 n
+0000060294 00000 n
+0000060461 00000 n
+0000060628 00000 n
+0000060795 00000 n
+0000060957 00000 n
+0000061119 00000 n
+0000061276 00000 n
+0000061443 00000 n
+0000061605 00000 n
+0000061772 00000 n
+0000061939 00000 n
+0000062106 00000 n
+0000657323 00000 n
+0000635992 00000 n
+0000657149 00000 n
+0000062273 00000 n
+0000062439 00000 n
+0000062594 00000 n
+0000062750 00000 n
+0000062906 00000 n
+0000063068 00000 n
+0000063230 00000 n
+0000063387 00000 n
+0000063542 00000 n
+0000063699 00000 n
+0000063861 00000 n
+0000064018 00000 n
+0000064175 00000 n
+0000064331 00000 n
+0000064488 00000 n
+0000064650 00000 n
+0000064807 00000 n
+0000064969 00000 n
+0000065126 00000 n
+0000065288 00000 n
+0000065449 00000 n
+0000065609 00000 n
+0000069240 00000 n
+0000066898 00000 n
+0000065937 00000 n
+0000069177 00000 n
+0000067136 00000 n
+0000067293 00000 n
+0000067450 00000 n
+0000067605 00000 n
+0000067762 00000 n
+0000067919 00000 n
+0000068076 00000 n
+0000068233 00000 n
+0000068390 00000 n
+0000068546 00000 n
+0000068704 00000 n
+0000635026 00000 n
+0000615059 00000 n
+0000634853 00000 n
+0000068861 00000 n
0000069019 00000 n
-0000071396 00000 n
-0000071520 00000 n
-0000071645 00000 n
-0000071770 00000 n
-0000071895 00000 n
-0000071958 00000 n
-0000072021 00000 n
-0000605670 00000 n
-0000587353 00000 n
-0000605497 00000 n
-0000724906 00000 n
-0000076655 00000 n
-0000075475 00000 n
-0000072208 00000 n
-0000075969 00000 n
-0000076032 00000 n
-0000076095 00000 n
-0000076219 00000 n
-0000076344 00000 n
-0000076469 00000 n
-0000075625 00000 n
-0000075818 00000 n
-0000076592 00000 n
-0000337590 00000 n
-0000397084 00000 n
-0000081310 00000 n
-0000080274 00000 n
-0000076779 00000 n
-0000080747 00000 n
-0000080872 00000 n
-0000080424 00000 n
-0000080586 00000 n
-0000080997 00000 n
-0000081122 00000 n
-0000081247 00000 n
-0000097234 00000 n
-0000084532 00000 n
-0000083972 00000 n
-0000081434 00000 n
-0000084094 00000 n
-0000084219 00000 n
-0000084344 00000 n
-0000084469 00000 n
-0000087959 00000 n
-0000086818 00000 n
-0000084643 00000 n
-0000087272 00000 n
-0000087397 00000 n
-0000087522 00000 n
-0000087647 00000 n
-0000087772 00000 n
-0000086968 00000 n
-0000087120 00000 n
-0000087896 00000 n
-0000287301 00000 n
-0000089040 00000 n
-0000088729 00000 n
-0000088044 00000 n
-0000088851 00000 n
-0000088976 00000 n
-0000091137 00000 n
-0000090434 00000 n
-0000089138 00000 n
-0000090560 00000 n
-0000090688 00000 n
-0000090815 00000 n
-0000090943 00000 n
-0000091072 00000 n
-0000725024 00000 n
-0000094066 00000 n
-0000093177 00000 n
-0000091236 00000 n
-0000093485 00000 n
-0000093614 00000 n
-0000093679 00000 n
-0000093744 00000 n
-0000093324 00000 n
-0000093873 00000 n
-0000094002 00000 n
-0000271243 00000 n
-0000097427 00000 n
-0000096979 00000 n
-0000094178 00000 n
-0000097105 00000 n
-0000586678 00000 n
-0000574689 00000 n
-0000586499 00000 n
-0000097362 00000 n
-0000101249 00000 n
-0000101058 00000 n
-0000097553 00000 n
-0000101184 00000 n
-0000574148 00000 n
-0000564404 00000 n
-0000573969 00000 n
-0000105860 00000 n
-0000105461 00000 n
-0000101415 00000 n
-0000105795 00000 n
-0000105608 00000 n
-0000172253 00000 n
-0000108206 00000 n
-0000107756 00000 n
-0000105999 00000 n
-0000107882 00000 n
-0000108011 00000 n
-0000108076 00000 n
-0000108141 00000 n
-0000110935 00000 n
-0000113482 00000 n
-0000110779 00000 n
-0000108331 00000 n
-0000112901 00000 n
-0000113030 00000 n
-0000113159 00000 n
-0000112578 00000 n
-0000112740 00000 n
-0000563534 00000 n
-0000554114 00000 n
-0000563360 00000 n
-0000553550 00000 n
-0000544464 00000 n
-0000553375 00000 n
-0000113288 00000 n
-0000113417 00000 n
-0000725149 00000 n
-0000112407 00000 n
-0000112465 00000 n
-0000112555 00000 n
-0000212434 00000 n
-0000248146 00000 n
-0000118002 00000 n
-0000117067 00000 n
-0000113638 00000 n
-0000117550 00000 n
-0000117679 00000 n
-0000117223 00000 n
-0000117388 00000 n
-0000117808 00000 n
-0000117937 00000 n
-0000401111 00000 n
-0000121616 00000 n
-0000121236 00000 n
-0000118154 00000 n
-0000121551 00000 n
-0000121383 00000 n
-0000122866 00000 n
-0000122675 00000 n
-0000121741 00000 n
-0000122801 00000 n
-0000125569 00000 n
-0000124992 00000 n
-0000122965 00000 n
-0000125118 00000 n
-0000125247 00000 n
-0000125376 00000 n
-0000125505 00000 n
-0000128809 00000 n
-0000128102 00000 n
-0000125707 00000 n
-0000128228 00000 n
-0000128357 00000 n
-0000128486 00000 n
-0000128615 00000 n
-0000128744 00000 n
-0000133116 00000 n
-0000132218 00000 n
-0000128934 00000 n
-0000132536 00000 n
-0000132665 00000 n
-0000132365 00000 n
-0000132794 00000 n
-0000132923 00000 n
-0000133051 00000 n
-0000725274 00000 n
-0000330221 00000 n
-0000137152 00000 n
-0000136574 00000 n
-0000133241 00000 n
-0000136700 00000 n
-0000136829 00000 n
-0000136958 00000 n
-0000137087 00000 n
-0000140613 00000 n
-0000140293 00000 n
-0000137290 00000 n
-0000140419 00000 n
-0000140548 00000 n
-0000143945 00000 n
-0000143186 00000 n
-0000140725 00000 n
-0000143494 00000 n
-0000143623 00000 n
-0000143333 00000 n
-0000143752 00000 n
-0000143880 00000 n
-0000396826 00000 n
-0000146685 00000 n
-0000146107 00000 n
-0000144113 00000 n
-0000146233 00000 n
-0000146362 00000 n
-0000146491 00000 n
-0000146620 00000 n
-0000147125 00000 n
-0000146934 00000 n
-0000146784 00000 n
-0000147060 00000 n
-0000151127 00000 n
-0000150361 00000 n
-0000147167 00000 n
-0000150675 00000 n
-0000150804 00000 n
-0000150932 00000 n
-0000150997 00000 n
-0000151062 00000 n
-0000150508 00000 n
-0000725399 00000 n
-0000155623 00000 n
-0000155815 00000 n
-0000155368 00000 n
-0000151226 00000 n
-0000155494 00000 n
-0000155750 00000 n
-0000159694 00000 n
-0000159117 00000 n
-0000155940 00000 n
-0000159243 00000 n
-0000159371 00000 n
-0000159500 00000 n
-0000159629 00000 n
-0000162513 00000 n
-0000163892 00000 n
-0000162387 00000 n
-0000159832 00000 n
-0000163439 00000 n
-0000163568 00000 n
-0000163697 00000 n
-0000163762 00000 n
-0000163827 00000 n
-0000166969 00000 n
-0000166262 00000 n
-0000164047 00000 n
-0000166388 00000 n
-0000166517 00000 n
-0000166645 00000 n
-0000166710 00000 n
-0000166775 00000 n
-0000166904 00000 n
-0000172576 00000 n
-0000171658 00000 n
-0000167081 00000 n
-0000172124 00000 n
-0000171814 00000 n
-0000171965 00000 n
-0000172382 00000 n
-0000172511 00000 n
-0000523089 00000 n
-0000176415 00000 n
-0000175144 00000 n
-0000172714 00000 n
-0000175834 00000 n
-0000175963 00000 n
-0000176092 00000 n
-0000175309 00000 n
-0000175461 00000 n
-0000175647 00000 n
-0000176221 00000 n
-0000176350 00000 n
-0000725524 00000 n
-0000180646 00000 n
-0000180326 00000 n
-0000176541 00000 n
-0000180452 00000 n
-0000180581 00000 n
-0000184122 00000 n
-0000183743 00000 n
-0000180771 00000 n
-0000184057 00000 n
-0000183890 00000 n
-0000187139 00000 n
-0000187334 00000 n
-0000186884 00000 n
-0000184234 00000 n
-0000187010 00000 n
-0000187204 00000 n
-0000187269 00000 n
-0000190703 00000 n
-0000190512 00000 n
-0000187446 00000 n
-0000190638 00000 n
-0000195014 00000 n
-0000194436 00000 n
-0000190815 00000 n
-0000194562 00000 n
-0000194691 00000 n
-0000194756 00000 n
-0000194821 00000 n
-0000194950 00000 n
-0000198225 00000 n
-0000197183 00000 n
-0000195126 00000 n
-0000197644 00000 n
-0000197773 00000 n
-0000197339 00000 n
-0000197491 00000 n
-0000197902 00000 n
-0000198031 00000 n
-0000198160 00000 n
-0000725649 00000 n
-0000199777 00000 n
-0000199586 00000 n
-0000198337 00000 n
-0000199712 00000 n
-0000201300 00000 n
-0000201109 00000 n
-0000199876 00000 n
-0000201235 00000 n
-0000204105 00000 n
-0000203785 00000 n
-0000201399 00000 n
-0000203911 00000 n
-0000204040 00000 n
-0000208528 00000 n
-0000208159 00000 n
-0000204243 00000 n
-0000208463 00000 n
-0000208306 00000 n
-0000366981 00000 n
-0000212499 00000 n
-0000212179 00000 n
-0000208640 00000 n
-0000212305 00000 n
-0000216337 00000 n
-0000216017 00000 n
-0000212624 00000 n
-0000216143 00000 n
-0000216208 00000 n
-0000216272 00000 n
-0000725774 00000 n
-0000221633 00000 n
-0000220341 00000 n
-0000216462 00000 n
-0000221568 00000 n
-0000220533 00000 n
-0000220687 00000 n
-0000220842 00000 n
-0000221027 00000 n
-0000221201 00000 n
-0000221386 00000 n
-0000290835 00000 n
-0000225939 00000 n
-0000225748 00000 n
-0000221814 00000 n
-0000225874 00000 n
-0000229702 00000 n
-0000229511 00000 n
-0000226064 00000 n
-0000229637 00000 n
-0000234015 00000 n
-0000233073 00000 n
-0000229814 00000 n
-0000233563 00000 n
-0000233692 00000 n
-0000233229 00000 n
-0000233821 00000 n
-0000233950 00000 n
-0000233397 00000 n
-0000304312 00000 n
-0000237811 00000 n
-0000237249 00000 n
-0000234127 00000 n
-0000237746 00000 n
-0000237405 00000 n
-0000237576 00000 n
-0000384536 00000 n
-0000241235 00000 n
-0000240788 00000 n
-0000237980 00000 n
-0000240914 00000 n
-0000241042 00000 n
-0000241171 00000 n
-0000725899 00000 n
-0000244802 00000 n
-0000244611 00000 n
-0000241360 00000 n
-0000244737 00000 n
-0000248211 00000 n
-0000247891 00000 n
-0000244971 00000 n
-0000248017 00000 n
-0000251891 00000 n
-0000251700 00000 n
-0000248367 00000 n
-0000251826 00000 n
-0000256213 00000 n
-0000255399 00000 n
-0000252060 00000 n
-0000255890 00000 n
-0000256019 00000 n
-0000255555 00000 n
-0000256148 00000 n
-0000255715 00000 n
-0000260364 00000 n
-0000259868 00000 n
-0000256368 00000 n
-0000260170 00000 n
-0000260299 00000 n
-0000260015 00000 n
-0000264002 00000 n
-0000263553 00000 n
-0000260489 00000 n
-0000263679 00000 n
-0000263808 00000 n
-0000263937 00000 n
-0000726024 00000 n
-0000267909 00000 n
-0000267242 00000 n
-0000264157 00000 n
-0000267715 00000 n
-0000267844 00000 n
-0000267398 00000 n
-0000267560 00000 n
-0000271438 00000 n
-0000270798 00000 n
-0000268078 00000 n
-0000271114 00000 n
-0000270945 00000 n
-0000271308 00000 n
-0000271373 00000 n
-0000275474 00000 n
-0000274971 00000 n
-0000271621 00000 n
-0000275280 00000 n
-0000275409 00000 n
-0000275118 00000 n
-0000280264 00000 n
-0000279585 00000 n
-0000275642 00000 n
-0000280070 00000 n
-0000279741 00000 n
-0000544109 00000 n
-0000542110 00000 n
-0000543944 00000 n
-0000280199 00000 n
-0000279902 00000 n
-0000363552 00000 n
-0000299250 00000 n
-0000283673 00000 n
-0000283353 00000 n
-0000280390 00000 n
-0000283479 00000 n
-0000283608 00000 n
-0000287365 00000 n
-0000287046 00000 n
-0000283798 00000 n
-0000287172 00000 n
-0000726149 00000 n
-0000290900 00000 n
-0000290451 00000 n
-0000287507 00000 n
-0000290577 00000 n
-0000290706 00000 n
-0000295399 00000 n
-0000294607 00000 n
-0000291012 00000 n
-0000295077 00000 n
-0000294763 00000 n
-0000294915 00000 n
-0000295206 00000 n
-0000295335 00000 n
-0000299315 00000 n
-0000298562 00000 n
-0000295511 00000 n
-0000298863 00000 n
-0000298992 00000 n
-0000299121 00000 n
-0000298709 00000 n
-0000302758 00000 n
-0000302438 00000 n
-0000299427 00000 n
-0000302564 00000 n
-0000302693 00000 n
-0000304377 00000 n
-0000304057 00000 n
-0000302870 00000 n
-0000304183 00000 n
-0000305902 00000 n
-0000305711 00000 n
-0000304489 00000 n
-0000305837 00000 n
-0000726274 00000 n
-0000308815 00000 n
-0000308236 00000 n
-0000306001 00000 n
-0000308362 00000 n
-0000308491 00000 n
-0000308620 00000 n
-0000308685 00000 n
-0000308750 00000 n
-0000313010 00000 n
-0000312501 00000 n
-0000308927 00000 n
-0000312816 00000 n
-0000312648 00000 n
-0000312945 00000 n
-0000523056 00000 n
-0000318900 00000 n
-0000316165 00000 n
-0000313122 00000 n
-0000318706 00000 n
-0000318835 00000 n
-0000316429 00000 n
-0000316591 00000 n
-0000316753 00000 n
-0000316914 00000 n
-0000317074 00000 n
-0000317236 00000 n
-0000317407 00000 n
-0000317569 00000 n
-0000317731 00000 n
-0000317894 00000 n
-0000318057 00000 n
-0000318220 00000 n
-0000318383 00000 n
-0000318546 00000 n
-0000324121 00000 n
-0000322204 00000 n
-0000319012 00000 n
-0000324056 00000 n
-0000322432 00000 n
-0000322595 00000 n
-0000322762 00000 n
-0000322931 00000 n
-0000323093 00000 n
-0000323254 00000 n
-0000323416 00000 n
-0000323577 00000 n
-0000323740 00000 n
-0000323893 00000 n
-0000330286 00000 n
-0000327279 00000 n
-0000324246 00000 n
-0000330092 00000 n
-0000327561 00000 n
-0000327714 00000 n
-0000327868 00000 n
-0000328019 00000 n
-0000328173 00000 n
-0000328334 00000 n
-0000328496 00000 n
-0000328658 00000 n
-0000328820 00000 n
-0000328982 00000 n
-0000329144 00000 n
-0000329306 00000 n
-0000329458 00000 n
-0000329621 00000 n
-0000329776 00000 n
-0000329938 00000 n
-0000333816 00000 n
-0000333495 00000 n
-0000330398 00000 n
-0000333621 00000 n
-0000333686 00000 n
-0000333751 00000 n
-0000726399 00000 n
-0000338041 00000 n
-0000336845 00000 n
-0000333985 00000 n
-0000337332 00000 n
-0000337461 00000 n
-0000337718 00000 n
-0000337001 00000 n
-0000337171 00000 n
-0000337783 00000 n
-0000337848 00000 n
-0000337913 00000 n
-0000337977 00000 n
-0000341388 00000 n
-0000341197 00000 n
-0000338223 00000 n
-0000341323 00000 n
-0000345128 00000 n
-0000344807 00000 n
-0000341474 00000 n
-0000344933 00000 n
-0000344998 00000 n
-0000345063 00000 n
-0000348960 00000 n
-0000348253 00000 n
-0000345240 00000 n
-0000348379 00000 n
-0000348508 00000 n
-0000348571 00000 n
-0000348636 00000 n
-0000348701 00000 n
-0000348766 00000 n
-0000348895 00000 n
-0000352712 00000 n
-0000351874 00000 n
-0000349072 00000 n
-0000352000 00000 n
-0000352065 00000 n
-0000352130 00000 n
-0000352259 00000 n
-0000352324 00000 n
-0000352389 00000 n
-0000352518 00000 n
-0000352583 00000 n
-0000352647 00000 n
-0000355833 00000 n
-0000355128 00000 n
-0000352837 00000 n
-0000355254 00000 n
-0000355382 00000 n
-0000355511 00000 n
-0000355640 00000 n
-0000355769 00000 n
-0000726524 00000 n
-0000359611 00000 n
-0000359161 00000 n
-0000356030 00000 n
-0000359287 00000 n
-0000359416 00000 n
-0000359481 00000 n
-0000359546 00000 n
-0000363876 00000 n
-0000363118 00000 n
-0000359750 00000 n
-0000363423 00000 n
-0000363681 00000 n
-0000363746 00000 n
-0000363811 00000 n
-0000363265 00000 n
-0000367434 00000 n
-0000366726 00000 n
-0000364001 00000 n
-0000366852 00000 n
-0000367110 00000 n
-0000367239 00000 n
-0000367304 00000 n
-0000367369 00000 n
-0000371121 00000 n
-0000370487 00000 n
-0000367546 00000 n
-0000370799 00000 n
-0000370634 00000 n
-0000370928 00000 n
-0000370992 00000 n
-0000371056 00000 n
-0000523023 00000 n
-0000375100 00000 n
-0000374394 00000 n
-0000371233 00000 n
-0000374520 00000 n
-0000374648 00000 n
-0000374713 00000 n
-0000374778 00000 n
-0000374907 00000 n
-0000374972 00000 n
-0000375036 00000 n
-0000377643 00000 n
-0000377323 00000 n
-0000375226 00000 n
-0000377449 00000 n
-0000541829 00000 n
-0000534545 00000 n
-0000541649 00000 n
-0000377578 00000 n
-0000726649 00000 n
-0000378124 00000 n
-0000377933 00000 n
-0000377783 00000 n
-0000378059 00000 n
-0000380016 00000 n
-0000379568 00000 n
-0000378166 00000 n
-0000379694 00000 n
-0000379823 00000 n
-0000379952 00000 n
-0000384601 00000 n
-0000383658 00000 n
-0000380128 00000 n
-0000384021 00000 n
-0000534224 00000 n
-0000525011 00000 n
-0000534038 00000 n
-0000383805 00000 n
-0000384150 00000 n
-0000384278 00000 n
-0000384407 00000 n
-0000385643 00000 n
-0000385452 00000 n
-0000384838 00000 n
-0000385578 00000 n
-0000386070 00000 n
-0000385879 00000 n
-0000385729 00000 n
-0000386005 00000 n
-0000389383 00000 n
-0000388157 00000 n
-0000386112 00000 n
-0000388674 00000 n
-0000388803 00000 n
+0000072403 00000 n
+0000071593 00000 n
+0000069338 00000 n
+0000071715 00000 n
+0000071839 00000 n
+0000071964 00000 n
+0000072089 00000 n
+0000072214 00000 n
+0000072277 00000 n
+0000072340 00000 n
+0000614265 00000 n
+0000595948 00000 n
+0000614092 00000 n
+0000733501 00000 n
+0000076974 00000 n
+0000075794 00000 n
+0000072527 00000 n
+0000076288 00000 n
+0000076351 00000 n
+0000076414 00000 n
+0000076538 00000 n
+0000076663 00000 n
+0000076788 00000 n
+0000075944 00000 n
+0000076137 00000 n
+0000076911 00000 n
+0000340366 00000 n
+0000400138 00000 n
+0000081629 00000 n
+0000080593 00000 n
+0000077098 00000 n
+0000081066 00000 n
+0000081191 00000 n
+0000080743 00000 n
+0000080905 00000 n
+0000081316 00000 n
+0000081441 00000 n
+0000081566 00000 n
+0000097562 00000 n
+0000084851 00000 n
+0000084291 00000 n
+0000081753 00000 n
+0000084413 00000 n
+0000084538 00000 n
+0000084663 00000 n
+0000084788 00000 n
+0000088278 00000 n
+0000087137 00000 n
+0000084962 00000 n
+0000087591 00000 n
+0000087716 00000 n
+0000087841 00000 n
+0000087966 00000 n
+0000088091 00000 n
+0000087287 00000 n
+0000087439 00000 n
+0000088215 00000 n
+0000289730 00000 n
+0000089367 00000 n
+0000089049 00000 n
+0000088363 00000 n
+0000089174 00000 n
+0000089302 00000 n
+0000091465 00000 n
+0000090762 00000 n
+0000089466 00000 n
+0000090888 00000 n
+0000091016 00000 n
+0000091143 00000 n
+0000091271 00000 n
+0000091400 00000 n
+0000733620 00000 n
+0000094394 00000 n
+0000093505 00000 n
+0000091564 00000 n
+0000093813 00000 n
+0000093942 00000 n
+0000094007 00000 n
+0000094072 00000 n
+0000093652 00000 n
+0000094201 00000 n
+0000094330 00000 n
+0000273532 00000 n
+0000097755 00000 n
+0000097307 00000 n
+0000094506 00000 n
+0000097433 00000 n
+0000595273 00000 n
+0000583284 00000 n
+0000595094 00000 n
+0000097690 00000 n
+0000101577 00000 n
+0000101386 00000 n
+0000097881 00000 n
+0000101512 00000 n
+0000582743 00000 n
+0000572999 00000 n
+0000582564 00000 n
+0000106188 00000 n
+0000105789 00000 n
+0000101743 00000 n
+0000106123 00000 n
+0000105936 00000 n
+0000174987 00000 n
+0000108534 00000 n
+0000108084 00000 n
+0000106327 00000 n
+0000108210 00000 n
+0000108339 00000 n
+0000108404 00000 n
+0000108469 00000 n
+0000111263 00000 n
+0000113810 00000 n
+0000111107 00000 n
+0000108659 00000 n
+0000113229 00000 n
+0000113358 00000 n
+0000113487 00000 n
+0000112906 00000 n
+0000113068 00000 n
+0000572101 00000 n
+0000562305 00000 n
+0000571927 00000 n
+0000561741 00000 n
+0000552655 00000 n
+0000561566 00000 n
+0000113616 00000 n
+0000113745 00000 n
+0000733745 00000 n
+0000112735 00000 n
+0000112793 00000 n
+0000112883 00000 n
+0000215305 00000 n
+0000250427 00000 n
+0000118474 00000 n
+0000117539 00000 n
+0000113966 00000 n
+0000118023 00000 n
+0000118152 00000 n
+0000117695 00000 n
+0000117861 00000 n
+0000118281 00000 n
+0000118410 00000 n
+0000404165 00000 n
+0000122133 00000 n
+0000121753 00000 n
+0000118626 00000 n
+0000122068 00000 n
+0000121900 00000 n
+0000123358 00000 n
+0000123167 00000 n
+0000122258 00000 n
+0000123293 00000 n
+0000126061 00000 n
+0000125483 00000 n
+0000123457 00000 n
+0000125609 00000 n
+0000125738 00000 n
+0000125867 00000 n
+0000125996 00000 n
+0000129240 00000 n
+0000128533 00000 n
+0000126199 00000 n
+0000128659 00000 n
+0000128788 00000 n
+0000128917 00000 n
+0000129046 00000 n
+0000129175 00000 n
+0000133547 00000 n
+0000132649 00000 n
+0000129365 00000 n
+0000132967 00000 n
+0000133096 00000 n
+0000132796 00000 n
+0000133225 00000 n
+0000133354 00000 n
+0000133482 00000 n
+0000733870 00000 n
+0000332997 00000 n
+0000137583 00000 n
+0000137005 00000 n
+0000133672 00000 n
+0000137131 00000 n
+0000137260 00000 n
+0000137389 00000 n
+0000137518 00000 n
+0000141178 00000 n
+0000140858 00000 n
+0000137721 00000 n
+0000140984 00000 n
+0000141113 00000 n
+0000144624 00000 n
+0000144124 00000 n
+0000141290 00000 n
+0000144430 00000 n
+0000552380 00000 n
+0000549022 00000 n
+0000552201 00000 n
+0000144559 00000 n
+0000144271 00000 n
+0000399880 00000 n
+0000146352 00000 n
+0000145905 00000 n
+0000144806 00000 n
+0000146031 00000 n
+0000146160 00000 n
+0000146287 00000 n
+0000146805 00000 n
+0000146614 00000 n
+0000146464 00000 n
+0000146740 00000 n
+0000149419 00000 n
+0000148841 00000 n
+0000146847 00000 n
+0000148967 00000 n
+0000149096 00000 n
+0000149225 00000 n
+0000149354 00000 n
+0000733995 00000 n
+0000149859 00000 n
+0000149668 00000 n
+0000149518 00000 n
+0000149794 00000 n
+0000153861 00000 n
+0000153095 00000 n
+0000149901 00000 n
+0000153409 00000 n
+0000153538 00000 n
+0000153666 00000 n
+0000153731 00000 n
+0000153796 00000 n
+0000153242 00000 n
+0000158357 00000 n
+0000158549 00000 n
+0000158102 00000 n
+0000153960 00000 n
+0000158228 00000 n
+0000158484 00000 n
+0000162428 00000 n
+0000161851 00000 n
+0000158674 00000 n
+0000161977 00000 n
+0000162105 00000 n
+0000162234 00000 n
+0000162363 00000 n
+0000165247 00000 n
+0000166626 00000 n
+0000165121 00000 n
+0000162566 00000 n
+0000166173 00000 n
+0000166302 00000 n
+0000166431 00000 n
+0000166496 00000 n
+0000166561 00000 n
+0000169703 00000 n
+0000168996 00000 n
+0000166781 00000 n
+0000169122 00000 n
+0000169251 00000 n
+0000169379 00000 n
+0000169444 00000 n
+0000169509 00000 n
+0000169638 00000 n
+0000734120 00000 n
+0000175310 00000 n
+0000174392 00000 n
+0000169815 00000 n
+0000174858 00000 n
+0000174548 00000 n
+0000174699 00000 n
+0000175116 00000 n
+0000175245 00000 n
+0000527648 00000 n
+0000179149 00000 n
+0000177878 00000 n
+0000175448 00000 n
+0000178568 00000 n
+0000178697 00000 n
+0000178826 00000 n
+0000178043 00000 n
+0000178195 00000 n
+0000178381 00000 n
+0000178955 00000 n
+0000179084 00000 n
+0000183380 00000 n
+0000183060 00000 n
+0000179275 00000 n
+0000183186 00000 n
+0000183315 00000 n
+0000186856 00000 n
+0000186477 00000 n
+0000183505 00000 n
+0000186791 00000 n
+0000186624 00000 n
+0000189873 00000 n
+0000190068 00000 n
+0000189618 00000 n
+0000186968 00000 n
+0000189744 00000 n
+0000189938 00000 n
+0000190003 00000 n
+0000193437 00000 n
+0000193246 00000 n
+0000190180 00000 n
+0000193372 00000 n
+0000734245 00000 n
+0000197748 00000 n
+0000197170 00000 n
+0000193549 00000 n
+0000197296 00000 n
+0000197425 00000 n
+0000197490 00000 n
+0000197555 00000 n
+0000197684 00000 n
+0000200959 00000 n
+0000199917 00000 n
+0000197860 00000 n
+0000200378 00000 n
+0000200507 00000 n
+0000200073 00000 n
+0000200225 00000 n
+0000200636 00000 n
+0000200765 00000 n
+0000200894 00000 n
+0000202511 00000 n
+0000202320 00000 n
+0000201071 00000 n
+0000202446 00000 n
+0000204046 00000 n
+0000203855 00000 n
+0000202610 00000 n
+0000203981 00000 n
+0000206969 00000 n
+0000206649 00000 n
+0000204145 00000 n
+0000206775 00000 n
+0000206904 00000 n
+0000211399 00000 n
+0000211030 00000 n
+0000207107 00000 n
+0000211334 00000 n
+0000211177 00000 n
+0000734370 00000 n
+0000369874 00000 n
+0000215370 00000 n
+0000215050 00000 n
+0000211511 00000 n
+0000215176 00000 n
+0000219208 00000 n
+0000218888 00000 n
+0000215495 00000 n
+0000219014 00000 n
+0000219079 00000 n
+0000219143 00000 n
+0000224504 00000 n
+0000223212 00000 n
+0000219333 00000 n
+0000224439 00000 n
+0000223404 00000 n
+0000223558 00000 n
+0000223713 00000 n
+0000223898 00000 n
+0000224072 00000 n
+0000224257 00000 n
+0000293103 00000 n
+0000228807 00000 n
+0000228616 00000 n
+0000224685 00000 n
+0000228742 00000 n
+0000232570 00000 n
+0000232379 00000 n
+0000228932 00000 n
+0000232505 00000 n
+0000236884 00000 n
+0000235941 00000 n
+0000232682 00000 n
+0000236432 00000 n
+0000236561 00000 n
+0000236097 00000 n
+0000236690 00000 n
+0000236819 00000 n
+0000236266 00000 n
+0000734495 00000 n
+0000307088 00000 n
+0000240544 00000 n
+0000239982 00000 n
+0000236996 00000 n
+0000240479 00000 n
+0000240138 00000 n
+0000240309 00000 n
+0000387589 00000 n
+0000243797 00000 n
+0000243477 00000 n
+0000240713 00000 n
+0000243603 00000 n
+0000243732 00000 n
+0000247313 00000 n
+0000246993 00000 n
+0000243922 00000 n
+0000247119 00000 n
+0000247248 00000 n
+0000250492 00000 n
+0000250172 00000 n
+0000247425 00000 n
+0000250298 00000 n
+0000254305 00000 n
+0000254114 00000 n
+0000250648 00000 n
+0000254240 00000 n
+0000258187 00000 n
+0000257558 00000 n
+0000254460 00000 n
+0000257865 00000 n
+0000257994 00000 n
+0000257705 00000 n
+0000258123 00000 n
+0000734620 00000 n
+0000262381 00000 n
+0000261702 00000 n
+0000258356 00000 n
+0000262187 00000 n
+0000261858 00000 n
+0000262316 00000 n
+0000262032 00000 n
+0000266404 00000 n
+0000265955 00000 n
+0000262493 00000 n
+0000266081 00000 n
+0000266210 00000 n
+0000266339 00000 n
+0000270440 00000 n
+0000269774 00000 n
+0000266559 00000 n
+0000270247 00000 n
+0000270376 00000 n
+0000269930 00000 n
+0000270092 00000 n
+0000273727 00000 n
+0000273088 00000 n
+0000270609 00000 n
+0000273403 00000 n
+0000273235 00000 n
+0000273597 00000 n
+0000273662 00000 n
+0000277537 00000 n
+0000277034 00000 n
+0000273853 00000 n
+0000277343 00000 n
+0000277472 00000 n
+0000277181 00000 n
+0000282138 00000 n
+0000281764 00000 n
+0000277719 00000 n
+0000282073 00000 n
+0000281911 00000 n
+0000548667 00000 n
+0000546669 00000 n
+0000548502 00000 n
+0000734745 00000 n
+0000366305 00000 n
+0000286039 00000 n
+0000285403 00000 n
+0000282264 00000 n
+0000285716 00000 n
+0000285845 00000 n
+0000285550 00000 n
+0000285974 00000 n
+0000302020 00000 n
+0000289795 00000 n
+0000289475 00000 n
+0000286164 00000 n
+0000289601 00000 n
+0000293168 00000 n
+0000292719 00000 n
+0000289950 00000 n
+0000292845 00000 n
+0000292974 00000 n
+0000297929 00000 n
+0000297265 00000 n
+0000293280 00000 n
+0000297735 00000 n
+0000297421 00000 n
+0000297573 00000 n
+0000297864 00000 n
+0000302085 00000 n
+0000301204 00000 n
+0000298041 00000 n
+0000301504 00000 n
+0000301633 00000 n
+0000301762 00000 n
+0000301891 00000 n
+0000301351 00000 n
+0000305528 00000 n
+0000305208 00000 n
+0000302197 00000 n
+0000305334 00000 n
+0000305463 00000 n
+0000734870 00000 n
+0000307153 00000 n
+0000306833 00000 n
+0000305640 00000 n
+0000306959 00000 n
+0000308678 00000 n
+0000308487 00000 n
+0000307265 00000 n
+0000308613 00000 n
+0000311591 00000 n
+0000311012 00000 n
+0000308777 00000 n
+0000311138 00000 n
+0000311267 00000 n
+0000311396 00000 n
+0000311461 00000 n
+0000311526 00000 n
+0000315786 00000 n
+0000315277 00000 n
+0000311703 00000 n
+0000315592 00000 n
+0000315424 00000 n
+0000315721 00000 n
+0000527615 00000 n
+0000321676 00000 n
+0000318941 00000 n
+0000315898 00000 n
+0000321482 00000 n
+0000321611 00000 n
+0000319205 00000 n
+0000319367 00000 n
+0000319529 00000 n
+0000319690 00000 n
+0000319850 00000 n
+0000320012 00000 n
+0000320183 00000 n
+0000320345 00000 n
+0000320507 00000 n
+0000320670 00000 n
+0000320833 00000 n
+0000320996 00000 n
+0000321159 00000 n
+0000321322 00000 n
+0000326897 00000 n
+0000324980 00000 n
+0000321788 00000 n
+0000326832 00000 n
+0000325208 00000 n
+0000325371 00000 n
+0000325538 00000 n
+0000325707 00000 n
+0000325869 00000 n
+0000326030 00000 n
+0000326192 00000 n
+0000326353 00000 n
+0000326516 00000 n
+0000326669 00000 n
+0000734995 00000 n
+0000333062 00000 n
+0000330055 00000 n
+0000327022 00000 n
+0000332868 00000 n
+0000330337 00000 n
+0000330490 00000 n
+0000330644 00000 n
+0000330795 00000 n
+0000330949 00000 n
+0000331110 00000 n
+0000331272 00000 n
+0000331434 00000 n
+0000331596 00000 n
+0000331758 00000 n
+0000331920 00000 n
+0000332082 00000 n
+0000332234 00000 n
+0000332397 00000 n
+0000332552 00000 n
+0000332714 00000 n
+0000336592 00000 n
+0000336271 00000 n
+0000333174 00000 n
+0000336397 00000 n
+0000336462 00000 n
+0000336527 00000 n
+0000340817 00000 n
+0000339621 00000 n
+0000336761 00000 n
+0000340108 00000 n
+0000340237 00000 n
+0000340494 00000 n
+0000339777 00000 n
+0000339947 00000 n
+0000340559 00000 n
+0000340624 00000 n
+0000340689 00000 n
+0000340753 00000 n
+0000344164 00000 n
+0000343973 00000 n
+0000340999 00000 n
+0000344099 00000 n
+0000347904 00000 n
+0000347583 00000 n
+0000344250 00000 n
+0000347709 00000 n
+0000347774 00000 n
+0000347839 00000 n
+0000351736 00000 n
+0000351029 00000 n
+0000348016 00000 n
+0000351155 00000 n
+0000351284 00000 n
+0000351347 00000 n
+0000351412 00000 n
+0000351477 00000 n
+0000351542 00000 n
+0000351671 00000 n
+0000735120 00000 n
+0000355488 00000 n
+0000354650 00000 n
+0000351848 00000 n
+0000354776 00000 n
+0000354841 00000 n
+0000354906 00000 n
+0000355035 00000 n
+0000355100 00000 n
+0000355165 00000 n
+0000355294 00000 n
+0000355359 00000 n
+0000355423 00000 n
+0000358831 00000 n
+0000358124 00000 n
+0000355613 00000 n
+0000358250 00000 n
+0000358379 00000 n
+0000358508 00000 n
+0000358637 00000 n
+0000358766 00000 n
+0000362736 00000 n
+0000362158 00000 n
+0000359028 00000 n
+0000362284 00000 n
+0000362413 00000 n
+0000362541 00000 n
+0000362606 00000 n
+0000362671 00000 n
+0000366629 00000 n
+0000366050 00000 n
+0000362875 00000 n
+0000366176 00000 n
+0000366434 00000 n
+0000366499 00000 n
+0000366564 00000 n
+0000370327 00000 n
+0000369438 00000 n
+0000366754 00000 n
+0000369745 00000 n
+0000369585 00000 n
+0000370003 00000 n
+0000370132 00000 n
+0000370197 00000 n
+0000370262 00000 n
+0000374079 00000 n
+0000373447 00000 n
+0000370439 00000 n
+0000373759 00000 n
+0000373594 00000 n
+0000373888 00000 n
+0000373951 00000 n
+0000374014 00000 n
+0000735245 00000 n
+0000527582 00000 n
+0000377549 00000 n
+0000377100 00000 n
+0000374191 00000 n
+0000377226 00000 n
+0000377354 00000 n
+0000377419 00000 n
+0000377484 00000 n
+0000380695 00000 n
+0000380117 00000 n
+0000377661 00000 n
+0000380243 00000 n
+0000380372 00000 n
+0000380437 00000 n
+0000380501 00000 n
+0000546388 00000 n
+0000539104 00000 n
+0000546208 00000 n
+0000380630 00000 n
+0000381176 00000 n
+0000380985 00000 n
+0000380835 00000 n
+0000381111 00000 n
+0000383068 00000 n
+0000382620 00000 n
+0000381218 00000 n
+0000382746 00000 n
+0000382875 00000 n
+0000383004 00000 n
+0000387654 00000 n
+0000386711 00000 n
+0000383180 00000 n
+0000387074 00000 n
+0000538783 00000 n
+0000529570 00000 n
+0000538597 00000 n
+0000386858 00000 n
+0000387203 00000 n
+0000387331 00000 n
+0000387460 00000 n
+0000388696 00000 n
+0000388505 00000 n
+0000387891 00000 n
+0000388631 00000 n
+0000735370 00000 n
+0000389123 00000 n
0000388932 00000 n
-0000389061 00000 n
-0000389190 00000 n
-0000389319 00000 n
-0000388313 00000 n
-0000388485 00000 n
-0000726774 00000 n
-0000389837 00000 n
-0000389646 00000 n
-0000389496 00000 n
-0000389772 00000 n
-0000393081 00000 n
-0000392503 00000 n
-0000389879 00000 n
-0000392629 00000 n
-0000392758 00000 n
-0000392887 00000 n
-0000393016 00000 n
-0000397276 00000 n
-0000396058 00000 n
-0000393167 00000 n
-0000396568 00000 n
-0000396697 00000 n
-0000396955 00000 n
-0000396214 00000 n
-0000396393 00000 n
-0000397148 00000 n
-0000397212 00000 n
-0000404163 00000 n
-0000400335 00000 n
-0000397429 00000 n
-0000400461 00000 n
-0000400526 00000 n
-0000400591 00000 n
-0000400656 00000 n
-0000400721 00000 n
-0000400786 00000 n
-0000400851 00000 n
-0000400916 00000 n
-0000400981 00000 n
-0000401046 00000 n
-0000401176 00000 n
-0000401241 00000 n
-0000401306 00000 n
-0000401371 00000 n
-0000401436 00000 n
-0000401501 00000 n
-0000401566 00000 n
-0000401631 00000 n
-0000401696 00000 n
-0000401761 00000 n
-0000401826 00000 n
-0000401891 00000 n
-0000401956 00000 n
-0000402021 00000 n
-0000402086 00000 n
-0000402151 00000 n
-0000402216 00000 n
-0000402281 00000 n
-0000402346 00000 n
-0000402411 00000 n
-0000402476 00000 n
-0000402541 00000 n
-0000402606 00000 n
-0000402671 00000 n
-0000402735 00000 n
-0000402800 00000 n
-0000402865 00000 n
-0000402930 00000 n
-0000402995 00000 n
-0000403060 00000 n
-0000403125 00000 n
-0000403190 00000 n
-0000403255 00000 n
-0000403320 00000 n
-0000403385 00000 n
-0000403450 00000 n
+0000388782 00000 n
+0000389058 00000 n
+0000392436 00000 n
+0000391210 00000 n
+0000389165 00000 n
+0000391727 00000 n
+0000391856 00000 n
+0000391985 00000 n
+0000392114 00000 n
+0000392243 00000 n
+0000392372 00000 n
+0000391366 00000 n
+0000391538 00000 n
+0000392890 00000 n
+0000392699 00000 n
+0000392549 00000 n
+0000392825 00000 n
+0000396135 00000 n
+0000395557 00000 n
+0000392932 00000 n
+0000395683 00000 n
+0000395812 00000 n
+0000395941 00000 n
+0000396070 00000 n
+0000400330 00000 n
+0000399112 00000 n
+0000396221 00000 n
+0000399622 00000 n
+0000399751 00000 n
+0000400009 00000 n
+0000399268 00000 n
+0000399447 00000 n
+0000400202 00000 n
+0000400266 00000 n
+0000407217 00000 n
+0000403389 00000 n
+0000400483 00000 n
0000403515 00000 n
0000403580 00000 n
0000403645 00000 n
@@ -13895,431 +14018,482 @@ xref
0000403905 00000 n
0000403970 00000 n
0000404035 00000 n
-0000404099 00000 n
-0000410809 00000 n
-0000407245 00000 n
-0000404275 00000 n
-0000407371 00000 n
-0000407436 00000 n
-0000407501 00000 n
-0000407566 00000 n
-0000407631 00000 n
-0000407696 00000 n
-0000407761 00000 n
-0000407826 00000 n
-0000407891 00000 n
-0000407956 00000 n
-0000408021 00000 n
-0000408086 00000 n
-0000408150 00000 n
-0000408215 00000 n
-0000408280 00000 n
-0000408345 00000 n
-0000408410 00000 n
-0000408475 00000 n
-0000408540 00000 n
-0000408605 00000 n
-0000408670 00000 n
-0000408735 00000 n
-0000408800 00000 n
-0000408865 00000 n
-0000408929 00000 n
-0000408994 00000 n
-0000409059 00000 n
-0000409124 00000 n
-0000409189 00000 n
-0000409254 00000 n
-0000409319 00000 n
-0000409384 00000 n
-0000409449 00000 n
-0000409514 00000 n
-0000409579 00000 n
-0000409644 00000 n
-0000409709 00000 n
-0000409774 00000 n
-0000409839 00000 n
-0000409904 00000 n
-0000409968 00000 n
-0000410032 00000 n
-0000410096 00000 n
-0000410161 00000 n
-0000410226 00000 n
-0000410291 00000 n
-0000410356 00000 n
-0000410421 00000 n
-0000410486 00000 n
-0000410551 00000 n
-0000410616 00000 n
-0000410681 00000 n
-0000410745 00000 n
-0000416982 00000 n
-0000413544 00000 n
-0000410921 00000 n
+0000404100 00000 n
+0000404230 00000 n
+0000404295 00000 n
+0000404360 00000 n
+0000404425 00000 n
+0000404490 00000 n
+0000404555 00000 n
+0000404620 00000 n
+0000404685 00000 n
+0000404750 00000 n
+0000404815 00000 n
+0000404880 00000 n
+0000404945 00000 n
+0000405010 00000 n
+0000405075 00000 n
+0000405140 00000 n
+0000405205 00000 n
+0000405270 00000 n
+0000405335 00000 n
+0000405400 00000 n
+0000405465 00000 n
+0000405530 00000 n
+0000405595 00000 n
+0000405660 00000 n
+0000405725 00000 n
+0000405789 00000 n
+0000405854 00000 n
+0000405919 00000 n
+0000405984 00000 n
+0000406049 00000 n
+0000406114 00000 n
+0000406179 00000 n
+0000406244 00000 n
+0000406309 00000 n
+0000406374 00000 n
+0000406439 00000 n
+0000406504 00000 n
+0000406569 00000 n
+0000406634 00000 n
+0000406699 00000 n
+0000406764 00000 n
+0000406829 00000 n
+0000406894 00000 n
+0000406959 00000 n
+0000407024 00000 n
+0000407089 00000 n
+0000407153 00000 n
+0000735495 00000 n
+0000413863 00000 n
+0000410299 00000 n
+0000407329 00000 n
+0000410425 00000 n
+0000410490 00000 n
+0000410555 00000 n
+0000410620 00000 n
+0000410685 00000 n
+0000410750 00000 n
+0000410815 00000 n
+0000410880 00000 n
+0000410945 00000 n
+0000411010 00000 n
+0000411075 00000 n
+0000411140 00000 n
+0000411204 00000 n
+0000411269 00000 n
+0000411334 00000 n
+0000411399 00000 n
+0000411464 00000 n
+0000411529 00000 n
+0000411594 00000 n
+0000411659 00000 n
+0000411724 00000 n
+0000411789 00000 n
+0000411854 00000 n
+0000411919 00000 n
+0000411983 00000 n
+0000412048 00000 n
+0000412113 00000 n
+0000412178 00000 n
+0000412243 00000 n
+0000412308 00000 n
+0000412373 00000 n
+0000412438 00000 n
+0000412503 00000 n
+0000412568 00000 n
+0000412633 00000 n
+0000412698 00000 n
+0000412763 00000 n
+0000412828 00000 n
+0000412893 00000 n
+0000412958 00000 n
+0000413022 00000 n
+0000413086 00000 n
+0000413150 00000 n
+0000413215 00000 n
+0000413280 00000 n
+0000413345 00000 n
+0000413410 00000 n
+0000413475 00000 n
+0000413540 00000 n
+0000413605 00000 n
0000413670 00000 n
0000413735 00000 n
-0000413800 00000 n
-0000413865 00000 n
-0000413930 00000 n
-0000413995 00000 n
-0000414060 00000 n
-0000414125 00000 n
-0000414190 00000 n
-0000414255 00000 n
-0000414320 00000 n
-0000414385 00000 n
-0000414450 00000 n
-0000414515 00000 n
-0000414580 00000 n
-0000414645 00000 n
-0000414710 00000 n
-0000414775 00000 n
-0000414840 00000 n
-0000414905 00000 n
-0000414970 00000 n
-0000415035 00000 n
-0000415100 00000 n
-0000415165 00000 n
-0000415230 00000 n
-0000415295 00000 n
-0000415360 00000 n
-0000415425 00000 n
-0000415490 00000 n
-0000415555 00000 n
-0000415620 00000 n
-0000415685 00000 n
-0000415750 00000 n
-0000415815 00000 n
-0000415879 00000 n
-0000415944 00000 n
-0000416009 00000 n
-0000416074 00000 n
-0000416139 00000 n
-0000416204 00000 n
-0000416269 00000 n
-0000416334 00000 n
-0000416399 00000 n
-0000416464 00000 n
-0000416529 00000 n
-0000416594 00000 n
-0000416659 00000 n
+0000413799 00000 n
+0000420036 00000 n
+0000416598 00000 n
+0000413975 00000 n
0000416724 00000 n
0000416789 00000 n
0000416854 00000 n
-0000416918 00000 n
-0000726899 00000 n
-0000421560 00000 n
-0000419296 00000 n
-0000417094 00000 n
-0000419422 00000 n
-0000419487 00000 n
-0000419552 00000 n
-0000419617 00000 n
-0000419682 00000 n
-0000419747 00000 n
-0000419812 00000 n
-0000419877 00000 n
-0000419942 00000 n
-0000420007 00000 n
-0000420072 00000 n
-0000420137 00000 n
-0000420202 00000 n
-0000420267 00000 n
-0000420329 00000 n
-0000420393 00000 n
-0000420458 00000 n
-0000420522 00000 n
-0000420587 00000 n
-0000420652 00000 n
-0000420717 00000 n
-0000420782 00000 n
-0000420847 00000 n
-0000420912 00000 n
-0000420977 00000 n
-0000421106 00000 n
-0000421235 00000 n
-0000421300 00000 n
-0000421365 00000 n
-0000421430 00000 n
-0000421495 00000 n
-0000424355 00000 n
-0000423711 00000 n
-0000421685 00000 n
-0000423837 00000 n
+0000416919 00000 n
+0000416984 00000 n
+0000417049 00000 n
+0000417114 00000 n
+0000417179 00000 n
+0000417244 00000 n
+0000417309 00000 n
+0000417374 00000 n
+0000417439 00000 n
+0000417504 00000 n
+0000417569 00000 n
+0000417634 00000 n
+0000417699 00000 n
+0000417764 00000 n
+0000417829 00000 n
+0000417894 00000 n
+0000417959 00000 n
+0000418024 00000 n
+0000418089 00000 n
+0000418154 00000 n
+0000418219 00000 n
+0000418284 00000 n
+0000418349 00000 n
+0000418414 00000 n
+0000418479 00000 n
+0000418544 00000 n
+0000418609 00000 n
+0000418674 00000 n
+0000418739 00000 n
+0000418804 00000 n
+0000418869 00000 n
+0000418933 00000 n
+0000418998 00000 n
+0000419063 00000 n
+0000419128 00000 n
+0000419193 00000 n
+0000419258 00000 n
+0000419323 00000 n
+0000419388 00000 n
+0000419453 00000 n
+0000419518 00000 n
+0000419583 00000 n
+0000419648 00000 n
+0000419713 00000 n
+0000419778 00000 n
+0000419843 00000 n
+0000419908 00000 n
+0000419972 00000 n
+0000424614 00000 n
+0000422350 00000 n
+0000420148 00000 n
+0000422476 00000 n
+0000422541 00000 n
+0000422606 00000 n
+0000422671 00000 n
+0000422736 00000 n
+0000422801 00000 n
+0000422866 00000 n
+0000422931 00000 n
+0000422996 00000 n
+0000423061 00000 n
+0000423126 00000 n
+0000423191 00000 n
+0000423256 00000 n
+0000423321 00000 n
+0000423383 00000 n
+0000423447 00000 n
+0000423512 00000 n
+0000423576 00000 n
+0000423641 00000 n
+0000423706 00000 n
+0000423771 00000 n
+0000423836 00000 n
+0000423901 00000 n
0000423966 00000 n
-0000424095 00000 n
+0000424031 00000 n
0000424160 00000 n
-0000424225 00000 n
-0000424290 00000 n
-0000428694 00000 n
-0000428374 00000 n
-0000424468 00000 n
-0000428500 00000 n
-0000428565 00000 n
-0000428630 00000 n
-0000432294 00000 n
-0000432039 00000 n
-0000428847 00000 n
-0000432165 00000 n
-0000432230 00000 n
-0000435543 00000 n
-0000435352 00000 n
-0000432433 00000 n
-0000435478 00000 n
-0000439271 00000 n
-0000439015 00000 n
-0000435669 00000 n
-0000439141 00000 n
-0000439206 00000 n
-0000727024 00000 n
-0000442111 00000 n
-0000441403 00000 n
-0000439410 00000 n
-0000441529 00000 n
-0000441594 00000 n
-0000441659 00000 n
-0000441724 00000 n
-0000441789 00000 n
-0000441918 00000 n
-0000441983 00000 n
-0000442047 00000 n
-0000446779 00000 n
-0000446523 00000 n
-0000442250 00000 n
-0000446649 00000 n
-0000446714 00000 n
-0000449730 00000 n
-0000448957 00000 n
-0000446905 00000 n
-0000449083 00000 n
-0000449148 00000 n
-0000449213 00000 n
-0000449278 00000 n
-0000449407 00000 n
-0000449472 00000 n
-0000449535 00000 n
-0000449600 00000 n
-0000449665 00000 n
-0000452331 00000 n
-0000451622 00000 n
-0000449883 00000 n
-0000451748 00000 n
-0000451813 00000 n
-0000451878 00000 n
-0000451943 00000 n
-0000452008 00000 n
-0000452073 00000 n
-0000452202 00000 n
-0000452267 00000 n
-0000455355 00000 n
-0000454970 00000 n
-0000452483 00000 n
-0000455096 00000 n
-0000455161 00000 n
-0000455225 00000 n
-0000455290 00000 n
-0000458450 00000 n
-0000457676 00000 n
-0000455495 00000 n
-0000457802 00000 n
-0000457867 00000 n
-0000457932 00000 n
-0000457997 00000 n
-0000458126 00000 n
-0000458191 00000 n
-0000458256 00000 n
-0000458320 00000 n
-0000458385 00000 n
-0000727149 00000 n
-0000461723 00000 n
-0000461532 00000 n
-0000458616 00000 n
-0000461658 00000 n
-0000464823 00000 n
-0000464113 00000 n
-0000461849 00000 n
-0000464239 00000 n
-0000464304 00000 n
-0000464369 00000 n
-0000464434 00000 n
-0000464499 00000 n
-0000464628 00000 n
-0000464693 00000 n
-0000464758 00000 n
-0000468481 00000 n
-0000468162 00000 n
-0000464988 00000 n
-0000468288 00000 n
-0000468353 00000 n
-0000468417 00000 n
-0000471857 00000 n
-0000471666 00000 n
-0000468607 00000 n
-0000471792 00000 n
-0000474868 00000 n
-0000474418 00000 n
-0000471997 00000 n
-0000474544 00000 n
-0000474609 00000 n
-0000474674 00000 n
-0000474739 00000 n
-0000474804 00000 n
-0000477300 00000 n
-0000476526 00000 n
-0000475006 00000 n
-0000476652 00000 n
-0000476781 00000 n
-0000476846 00000 n
-0000476911 00000 n
-0000476976 00000 n
-0000477041 00000 n
-0000477106 00000 n
-0000477171 00000 n
-0000477236 00000 n
-0000727274 00000 n
-0000480529 00000 n
-0000479949 00000 n
-0000477453 00000 n
-0000480075 00000 n
-0000480204 00000 n
-0000480269 00000 n
-0000480334 00000 n
-0000480399 00000 n
-0000480464 00000 n
-0000483987 00000 n
-0000483796 00000 n
-0000480669 00000 n
-0000483922 00000 n
-0000486972 00000 n
-0000486197 00000 n
-0000484113 00000 n
-0000486323 00000 n
-0000486388 00000 n
-0000486453 00000 n
-0000486518 00000 n
-0000486647 00000 n
-0000486712 00000 n
-0000486777 00000 n
-0000486842 00000 n
-0000486907 00000 n
-0000490279 00000 n
-0000490088 00000 n
-0000487125 00000 n
-0000490214 00000 n
-0000493070 00000 n
-0000492684 00000 n
-0000490490 00000 n
-0000492810 00000 n
-0000492875 00000 n
-0000492940 00000 n
-0000493005 00000 n
-0000497081 00000 n
-0000496436 00000 n
-0000493307 00000 n
-0000496562 00000 n
-0000496627 00000 n
-0000496692 00000 n
-0000496821 00000 n
-0000496886 00000 n
-0000496951 00000 n
-0000497016 00000 n
-0000727399 00000 n
-0000501017 00000 n
-0000500761 00000 n
-0000497220 00000 n
-0000500887 00000 n
-0000500952 00000 n
-0000504237 00000 n
-0000503981 00000 n
-0000501143 00000 n
-0000504107 00000 n
-0000504172 00000 n
-0000506951 00000 n
-0000506307 00000 n
-0000504363 00000 n
-0000506433 00000 n
-0000506498 00000 n
-0000506563 00000 n
-0000506628 00000 n
-0000506757 00000 n
-0000506822 00000 n
-0000506887 00000 n
-0000510720 00000 n
-0000510335 00000 n
-0000507103 00000 n
-0000510461 00000 n
-0000510526 00000 n
-0000510590 00000 n
-0000510655 00000 n
-0000514311 00000 n
-0000513666 00000 n
-0000510860 00000 n
-0000513792 00000 n
-0000513857 00000 n
-0000513922 00000 n
-0000514051 00000 n
-0000514116 00000 n
-0000514181 00000 n
-0000514246 00000 n
-0000516582 00000 n
-0000516326 00000 n
-0000514463 00000 n
-0000516452 00000 n
-0000516517 00000 n
-0000727524 00000 n
-0000520063 00000 n
-0000519289 00000 n
-0000516721 00000 n
-0000519415 00000 n
-0000519480 00000 n
-0000519545 00000 n
-0000519610 00000 n
-0000519738 00000 n
-0000519803 00000 n
-0000519868 00000 n
-0000519933 00000 n
-0000519998 00000 n
-0000522871 00000 n
-0000522485 00000 n
-0000520216 00000 n
-0000522611 00000 n
-0000522676 00000 n
-0000522741 00000 n
-0000522806 00000 n
-0000523122 00000 n
-0000534466 00000 n
-0000542055 00000 n
-0000544356 00000 n
-0000544325 00000 n
-0000553849 00000 n
-0000563962 00000 n
-0000574436 00000 n
-0000587060 00000 n
-0000606125 00000 n
-0000627012 00000 n
-0000649155 00000 n
-0000667050 00000 n
-0000669880 00000 n
-0000669650 00000 n
-0000697187 00000 n
-0000724298 00000 n
-0000727622 00000 n
-0000727746 00000 n
-0000727872 00000 n
-0000727998 00000 n
-0000728115 00000 n
-0000728207 00000 n
-0000744729 00000 n
-0000763926 00000 n
-0000763967 00000 n
-0000764007 00000 n
-0000764141 00000 n
+0000424289 00000 n
+0000424354 00000 n
+0000424419 00000 n
+0000424484 00000 n
+0000424549 00000 n
+0000427409 00000 n
+0000426765 00000 n
+0000424739 00000 n
+0000426891 00000 n
+0000427020 00000 n
+0000427149 00000 n
+0000427214 00000 n
+0000427279 00000 n
+0000427344 00000 n
+0000431747 00000 n
+0000431427 00000 n
+0000427522 00000 n
+0000431553 00000 n
+0000431618 00000 n
+0000431683 00000 n
+0000435347 00000 n
+0000435092 00000 n
+0000431900 00000 n
+0000435218 00000 n
+0000435283 00000 n
+0000735620 00000 n
+0000438595 00000 n
+0000438404 00000 n
+0000435486 00000 n
+0000438530 00000 n
+0000442326 00000 n
+0000442070 00000 n
+0000438721 00000 n
+0000442196 00000 n
+0000442261 00000 n
+0000445166 00000 n
+0000444458 00000 n
+0000442465 00000 n
+0000444584 00000 n
+0000444649 00000 n
+0000444714 00000 n
+0000444779 00000 n
+0000444844 00000 n
+0000444973 00000 n
+0000445038 00000 n
+0000445102 00000 n
+0000449834 00000 n
+0000449578 00000 n
+0000445305 00000 n
+0000449704 00000 n
+0000449769 00000 n
+0000452785 00000 n
+0000452012 00000 n
+0000449960 00000 n
+0000452138 00000 n
+0000452203 00000 n
+0000452268 00000 n
+0000452333 00000 n
+0000452462 00000 n
+0000452527 00000 n
+0000452590 00000 n
+0000452655 00000 n
+0000452720 00000 n
+0000455386 00000 n
+0000454677 00000 n
+0000452938 00000 n
+0000454803 00000 n
+0000454868 00000 n
+0000454933 00000 n
+0000454998 00000 n
+0000455063 00000 n
+0000455128 00000 n
+0000455257 00000 n
+0000455322 00000 n
+0000735745 00000 n
+0000458629 00000 n
+0000458243 00000 n
+0000455538 00000 n
+0000458369 00000 n
+0000458434 00000 n
+0000458499 00000 n
+0000458564 00000 n
+0000461762 00000 n
+0000460989 00000 n
+0000458769 00000 n
+0000461115 00000 n
+0000461180 00000 n
+0000461245 00000 n
+0000461309 00000 n
+0000461437 00000 n
+0000461502 00000 n
+0000461567 00000 n
+0000461632 00000 n
+0000461697 00000 n
+0000465149 00000 n
+0000464958 00000 n
+0000461928 00000 n
+0000465084 00000 n
+0000468258 00000 n
+0000467548 00000 n
+0000465275 00000 n
+0000467674 00000 n
+0000467739 00000 n
+0000467804 00000 n
+0000467869 00000 n
+0000467934 00000 n
+0000468063 00000 n
+0000468128 00000 n
+0000468193 00000 n
+0000471809 00000 n
+0000471488 00000 n
+0000468423 00000 n
+0000471614 00000 n
+0000471679 00000 n
+0000471744 00000 n
+0000475255 00000 n
+0000475064 00000 n
+0000471935 00000 n
+0000475190 00000 n
+0000735870 00000 n
+0000478326 00000 n
+0000478007 00000 n
+0000475381 00000 n
+0000478133 00000 n
+0000478198 00000 n
+0000478262 00000 n
+0000480897 00000 n
+0000480059 00000 n
+0000478479 00000 n
+0000480185 00000 n
+0000480250 00000 n
+0000480315 00000 n
+0000480444 00000 n
+0000480509 00000 n
+0000480574 00000 n
+0000480639 00000 n
+0000480704 00000 n
+0000480768 00000 n
+0000480833 00000 n
+0000483864 00000 n
+0000483220 00000 n
+0000481050 00000 n
+0000483346 00000 n
+0000483411 00000 n
+0000483540 00000 n
+0000483605 00000 n
+0000483669 00000 n
+0000483734 00000 n
+0000483799 00000 n
+0000487337 00000 n
+0000487146 00000 n
+0000484004 00000 n
+0000487272 00000 n
+0000490144 00000 n
+0000489370 00000 n
+0000487463 00000 n
+0000489496 00000 n
+0000489561 00000 n
+0000489626 00000 n
+0000489691 00000 n
+0000489820 00000 n
+0000489885 00000 n
+0000489950 00000 n
+0000490014 00000 n
+0000490079 00000 n
+0000493547 00000 n
+0000493356 00000 n
+0000490297 00000 n
+0000493482 00000 n
+0000735995 00000 n
+0000496582 00000 n
+0000496262 00000 n
+0000493758 00000 n
+0000496388 00000 n
+0000496453 00000 n
+0000496518 00000 n
+0000499891 00000 n
+0000499182 00000 n
+0000496806 00000 n
+0000499308 00000 n
+0000499373 00000 n
+0000499438 00000 n
+0000499502 00000 n
+0000499631 00000 n
+0000499696 00000 n
+0000499761 00000 n
+0000499826 00000 n
+0000504307 00000 n
+0000504051 00000 n
+0000500043 00000 n
+0000504177 00000 n
+0000504242 00000 n
+0000507840 00000 n
+0000507649 00000 n
+0000504433 00000 n
+0000507775 00000 n
+0000510426 00000 n
+0000509976 00000 n
+0000507966 00000 n
+0000510102 00000 n
+0000510167 00000 n
+0000510232 00000 n
+0000510297 00000 n
+0000510362 00000 n
+0000514258 00000 n
+0000513678 00000 n
+0000510564 00000 n
+0000513804 00000 n
+0000513933 00000 n
+0000513998 00000 n
+0000514063 00000 n
+0000514128 00000 n
+0000514193 00000 n
+0000736120 00000 n
+0000517420 00000 n
+0000516710 00000 n
+0000514398 00000 n
+0000516836 00000 n
+0000516901 00000 n
+0000516966 00000 n
+0000517031 00000 n
+0000517160 00000 n
+0000517225 00000 n
+0000517290 00000 n
+0000517355 00000 n
+0000520137 00000 n
+0000519881 00000 n
+0000517572 00000 n
+0000520007 00000 n
+0000520072 00000 n
+0000523391 00000 n
+0000522618 00000 n
+0000520263 00000 n
+0000522744 00000 n
+0000522809 00000 n
+0000522874 00000 n
+0000522939 00000 n
+0000523068 00000 n
+0000523133 00000 n
+0000523198 00000 n
+0000523262 00000 n
+0000523327 00000 n
+0000526677 00000 n
+0000526358 00000 n
+0000523543 00000 n
+0000526484 00000 n
+0000526549 00000 n
+0000526614 00000 n
+0000527483 00000 n
+0000527227 00000 n
+0000526829 00000 n
+0000527353 00000 n
+0000527418 00000 n
+0000527681 00000 n
+0000539025 00000 n
+0000546614 00000 n
+0000548914 00000 n
+0000548883 00000 n
+0000552600 00000 n
+0000562040 00000 n
+0000572547 00000 n
+0000583031 00000 n
+0000595655 00000 n
+0000614720 00000 n
+0000635607 00000 n
+0000657750 00000 n
+0000675645 00000 n
+0000678475 00000 n
+0000678245 00000 n
+0000705782 00000 n
+0000732893 00000 n
+0000736245 00000 n
+0000736369 00000 n
+0000736495 00000 n
+0000736621 00000 n
+0000736738 00000 n
+0000736830 00000 n
+0000753445 00000 n
+0000772757 00000 n
+0000772798 00000 n
+0000772838 00000 n
+0000772972 00000 n
trailer
<<
-/Size 2150
-/Root 2148 0 R
-/Info 2149 0 R
-/ID [<D072E790DA0DA0DFD173C4B6B452D087> <D072E790DA0DA0DFD173C4B6B452D087>]
+/Size 2172
+/Root 2170 0 R
+/Info 2171 0 R
+/ID [<5A3C18693D743104F54A9671E6A3E513> <5A3C18693D743104F54A9671E6A3E513>]
>>
startxref
-764399
+773230
%%EOF
diff --git a/contrib/bind9/doc/arm/man.dig.html b/contrib/bind9/doc/arm/man.dig.html
index 2758a8f..bf39f83 100644
--- a/contrib/bind9/doc/arm/man.dig.html
+++ b/contrib/bind9/doc/arm/man.dig.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dig.html,v 1.93.14.8 2009/06/03 01:54:40 tbox Exp $ -->
+<!-- $Id: man.dig.html,v 1.93.14.15.2.1 2010/02/25 12:16:48 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -52,7 +52,7 @@
<div class="cmdsynopsis"><p><code class="command">dig</code> [global-queryopt...] [query...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2563899"></a><h2>DESCRIPTION</h2>
+<a name="id2563895"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dig</strong></span>
(domain information groper) is a flexible tool
for interrogating DNS name servers. It performs DNS lookups and
@@ -98,7 +98,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2570411"></a><h2>SIMPLE USAGE</h2>
+<a name="id2575937"></a><h2>SIMPLE USAGE</h2>
<p>
A typical invocation of <span><strong class="command">dig</strong></span> looks like:
</p>
@@ -144,7 +144,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2570522"></a><h2>OPTIONS</h2>
+<a name="id2576048"></a><h2>OPTIONS</h2>
<p>
The <code class="option">-b</code> option sets the source IP address of the query
to <em class="parameter"><code>address</code></em>. This must be a valid
@@ -248,7 +248,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2630188"></a><h2>QUERY OPTIONS</h2>
+<a name="id2630184"></a><h2>QUERY OPTIONS</h2>
<p><span><strong class="command">dig</strong></span>
provides a number of query options which affect
the way in which lookups are made and the results displayed. Some of
@@ -573,7 +573,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631257"></a><h2>MULTIPLE QUERIES</h2>
+<a name="id2631253"></a><h2>MULTIPLE QUERIES</h2>
<p>
The BIND 9 implementation of <span><strong class="command">dig </strong></span>
supports
@@ -619,7 +619,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631342"></a><h2>IDN SUPPORT</h2>
+<a name="id2631406"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">dig</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -633,14 +633,14 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631371"></a><h2>FILES</h2>
+<a name="id2631435"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
<p><code class="filename">${HOME}/.digrc</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631393"></a><h2>SEE ALSO</h2>
+<a name="id2631457"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">host</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
@@ -648,7 +648,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631430"></a><h2>BUGS</h2>
+<a name="id2631494"></a><h2>BUGS</h2>
<p>
There are probably too many query options.
</p>
diff --git a/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html b/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html
index f9a20e3..be8c749 100644
--- a/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html
+++ b/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-dsfromkey.html,v 1.6.14.7 2009/06/03 01:54:41 tbox Exp $ -->
+<!-- $Id: man.dnssec-dsfromkey.html,v 1.6.14.14.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -51,14 +51,14 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>dir</code></em></code>] {dnsname}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2603928"></a><h2>DESCRIPTION</h2>
+<a name="id2604060"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-dsfromkey</strong></span>
outputs the Delegation Signer (DS) resource record (RR), as defined in
RFC 3658 and RFC 4509, for the given key(s).
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603942"></a><h2>OPTIONS</h2>
+<a name="id2604074"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-1</span></dt>
<dd><p>
@@ -99,7 +99,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604072"></a><h2>EXAMPLE</h2>
+<a name="id2604204"></a><h2>EXAMPLE</h2>
<p>
To build the SHA-256 DS RR from the
<strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
@@ -114,7 +114,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604108"></a><h2>FILES</h2>
+<a name="id2604241"></a><h2>FILES</h2>
<p>
The keyfile can be designed by the key identification
<code class="filename">Knnnn.+aaa+iiiii</code> or the full file name
@@ -128,13 +128,13 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604150"></a><h2>CAVEAT</h2>
+<a name="id2604282"></a><h2>CAVEAT</h2>
<p>
A keyfile error can give a "file not found" even if the file exists.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604160"></a><h2>SEE ALSO</h2>
+<a name="id2604292"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -143,7 +143,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604196"></a><h2>AUTHOR</h2>
+<a name="id2604328"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html b/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html
index c885dbe..849528e 100644
--- a/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html
+++ b/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-keyfromlabel.html,v 1.31.14.7 2009/06/03 01:54:41 tbox Exp $ -->
+<!-- $Id: man.dnssec-keyfromlabel.html,v 1.31.14.17.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604515"></a><h2>DESCRIPTION</h2>
+<a name="id2604588"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
@@ -58,17 +58,25 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604529"></a><h2>OPTIONS</h2>
+<a name="id2604602"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5 (RSA)
- or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5,
+ RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
+ RSASHA512 or DH (Diffie Hellman).
These values are case insensitive.
</p>
<p>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <code class="option">-3</code> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <code class="option">-3</code> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </p>
+<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended.
</p>
@@ -131,7 +139,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604930"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2604945"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -172,17 +180,15 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605024"></a><h2>SEE ALSO</h2>
+<a name="id2605038"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
- <em class="citetitle">RFC 2539</em>,
- <em class="citetitle">RFC 2845</em>,
- <em class="citetitle">RFC 4033</em>.
+ <em class="citetitle">RFC 4034</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605063"></a><h2>AUTHOR</h2>
+<a name="id2605072"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.dnssec-keygen.html b/contrib/bind9/doc/arm/man.dnssec-keygen.html
index 17d08e2..8c00bec 100644
--- a/contrib/bind9/doc/arm/man.dnssec-keygen.html
+++ b/contrib/bind9/doc/arm/man.dnssec-keygen.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-keygen.html,v 1.97.14.7 2009/06/03 01:54:40 tbox Exp $ -->
+<!-- $Id: man.dnssec-keygen.html,v 1.97.14.17.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,23 +50,31 @@
<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-b <em class="replaceable"><code>keysize</code></em>} {-n <em class="replaceable"><code>nametype</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k</code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2605709"></a><h2>DESCRIPTION</h2>
+<a name="id2605799"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keygen</strong></span>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
TSIG (Transaction Signatures), as defined in RFC 2845.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. For DNSSEC keys, this must match the name of the zone for
+ which the key is being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605723"></a><h2>OPTIONS</h2>
+<a name="id2605819"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
- Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5 (RSA) or RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5.
- These values are case insensitive.
+ Selects the cryptographic algorithm. For DNSSEC keys, the value
+ of <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
+ For TSIG/TKEY, the value must
+ be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
+ HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
+ case insensitive.
</p>
<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
@@ -80,11 +88,10 @@
<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt>
<dd><p>
Specifies the number of bits in the key. The choice of key
- size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be
- between
- 512 and 2048 bits. Diffie Hellman keys must be between
+ size depends on the algorithm used. RSA keys must be
+ between 512 and 2048 bits. Diffie Hellman keys must be between
128 and 4096 bits. DSA keys must be between 512 and 1024
- bits and an exact multiple of 64. HMAC-MD5 keys must be
+ bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
</p></dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
@@ -166,7 +173,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2606408"></a><h2>GENERATED KEYS</h2>
+<a name="id2607528"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -212,7 +219,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608564"></a><h2>EXAMPLE</h2>
+<a name="id2608865"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -233,16 +240,16 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608893"></a><h2>SEE ALSO</h2>
+<a name="id2608921"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
<em class="citetitle">RFC 2845</em>,
- <em class="citetitle">RFC 4033</em>.
+ <em class="citetitle">RFC 4034</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608924"></a><h2>AUTHOR</h2>
+<a name="id2608952"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.dnssec-signzone.html b/contrib/bind9/doc/arm/man.dnssec-signzone.html
index 40c0976..5ecf0b8 100644
--- a/contrib/bind9/doc/arm/man.dnssec-signzone.html
+++ b/contrib/bind9/doc/arm/man.dnssec-signzone.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-signzone.html,v 1.94.14.11.8.1 2009/12/31 23:17:55 tbox Exp $ -->
+<!-- $Id: man.dnssec-signzone.html,v 1.94.14.23.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,21 +47,21 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2607752"></a><h2>DESCRIPTION</h2>
+<a name="id2608017"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-signzone</strong></span>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. The security status of delegations from the signed zone
- (that is, whether the child zones are secure or not) is
- determined by the presence or absence of a
- <code class="filename">keyset</code> file for each child zone.
+ zone. It also generates a <code class="filename">keyset-</code> file containing
+ the key-signing keys for the zone, and if signing a zone which
+ contains delegations, it can optionally generate DS records for
+ the child zones from their <code class="filename">keyset-</code> files.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2607771"></a><h2>OPTIONS</h2>
+<a name="id2608041"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -88,8 +88,10 @@
</p></dd>
<dt><span class="term">-g</span></dt>
<dd><p>
- Generate DS records for child zones from keyset files.
- Existing DS records will be removed.
+ If the zone contains any delegations, and there are
+ <code class="filename">keyset-</code> files for any of the child zones,
+ then DS records for the child zones will be generated from the
+ keys in those files. Existing DS records will be removed.
</p></dd>
<dt><span class="term">-s <em class="replaceable"><code>start-time</code></em></span></dt>
<dd><p>
@@ -220,6 +222,19 @@
may be useful when signing large zones or when the entropy
source is limited.
</p></dd>
+<dt><span class="term">-P</span></dt>
+<dd>
+<p>
+ Disable post sign verification tests.
+ </p>
+<p>
+ The post sign verification test ensures that for each algorithm
+ in use there is at least one non revoked self signed KSK key,
+ that all revoked KSK keys are self signed, and that all records
+ in the zone are signed by the algorithm.
+ This option skips these tests.
+ </p>
+</dd>
<dt><span class="term">-r <em class="replaceable"><code>randomdev</code></em></span></dt>
<dd><p>
Specifies the source of randomness. If the operating
@@ -276,7 +291,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2659163"></a><h2>EXAMPLE</h2>
+<a name="id2658773"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
@@ -305,7 +320,7 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2659304"></a><h2>KNOWN BUGS</h2>
+<a name="id2658845"></a><h2>KNOWN BUGS</h2>
<p>
<span><strong class="command">dnssec-signzone</strong></span> was designed so that it could
sign a zone partially, using only a subset of the DNSSEC keys
@@ -330,14 +345,14 @@ db.example.com.signed
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659404"></a><h2>SEE ALSO</h2>
+<a name="id2658877"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 4033</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659429"></a><h2>AUTHOR</h2>
+<a name="id2658902"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.host.html b/contrib/bind9/doc/arm/man.host.html
index 22f6731..7f9eeb9 100644
--- a/contrib/bind9/doc/arm/man.host.html
+++ b/contrib/bind9/doc/arm/man.host.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.host.html,v 1.93.14.7 2009/06/03 01:54:40 tbox Exp $ -->
+<!-- $Id: man.host.html,v 1.93.14.15.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">host</code> [<code class="option">-aCdlnrsTwv</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-N <em class="replaceable"><code>ndots</code></em></code>] [<code class="option">-R <em class="replaceable"><code>number</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-W <em class="replaceable"><code>wait</code></em></code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-4</code>] [<code class="option">-6</code>] {name} [server]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2603221"></a><h2>DESCRIPTION</h2>
+<a name="id2603353"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">host</strong></span>
is a simple utility for performing DNS lookups.
It is normally used to convert names to IP addresses and vice versa.
@@ -202,7 +202,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603735"></a><h2>IDN SUPPORT</h2>
+<a name="id2603867"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">host</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -216,12 +216,12 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603764"></a><h2>FILES</h2>
+<a name="id2603896"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603778"></a><h2>SEE ALSO</h2>
+<a name="id2603910"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dig</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>.
</p>
diff --git a/contrib/bind9/doc/arm/man.named-checkconf.html b/contrib/bind9/doc/arm/man.named-checkconf.html
index 94c22f6..9d4c0ed 100644
--- a/contrib/bind9/doc/arm/man.named-checkconf.html
+++ b/contrib/bind9/doc/arm/man.named-checkconf.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named-checkconf.html,v 1.92.14.8.8.1 2009/12/31 23:17:55 tbox Exp $ -->
+<!-- $Id: man.named-checkconf.html,v 1.92.14.20.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,14 +50,14 @@
<div class="cmdsynopsis"><p><code class="command">named-checkconf</code> [<code class="option">-h</code>] [<code class="option">-v</code>] [<code class="option">-j</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] {filename} [<code class="option">-z</code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608660"></a><h2>DESCRIPTION</h2>
+<a name="id2609121"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkconf</strong></span>
checks the syntax, but not the semantics, of a named
configuration file.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608674"></a><h2>OPTIONS</h2>
+<a name="id2609134"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-h</span></dt>
<dd><p>
@@ -92,21 +92,21 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608790"></a><h2>RETURN VALUES</h2>
+<a name="id2609319"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkconf</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608804"></a><h2>SEE ALSO</h2>
+<a name="id2609333"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608834"></a><h2>AUTHOR</h2>
+<a name="id2609363"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.named-checkzone.html b/contrib/bind9/doc/arm/man.named-checkzone.html
index b187a1a..a44e59f 100644
--- a/contrib/bind9/doc/arm/man.named-checkzone.html
+++ b/contrib/bind9/doc/arm/man.named-checkzone.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named-checkzone.html,v 1.98.14.8.8.1 2009/12/31 23:17:55 tbox Exp $ -->
+<!-- $Id: man.named-checkzone.html,v 1.98.14.20.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,11 +47,11 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
-<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {<code class="option">-o <em class="replaceable"><code>filename</code></em></code>} {zonename} {filename}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2609649"></a><h2>DESCRIPTION</h2>
+<a name="id2609973"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkzone</strong></span>
checks the syntax and integrity of a zone file. It performs the
same checks as <span><strong class="command">named</strong></span> does when loading a
@@ -71,7 +71,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659465"></a><h2>OPTIONS</h2>
+<a name="id2610023"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-d</span></dt>
<dd><p>
@@ -257,14 +257,14 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2660272"></a><h2>RETURN VALUES</h2>
+<a name="id2659640"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkzone</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2660285"></a><h2>SEE ALSO</h2>
+<a name="id2659654"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<em class="citetitle">RFC 1035</em>,
@@ -272,7 +272,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2660318"></a><h2>AUTHOR</h2>
+<a name="id2659755"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.named.html b/contrib/bind9/doc/arm/man.named.html
index 2a440ce..c3ba7fb 100644
--- a/contrib/bind9/doc/arm/man.named.html
+++ b/contrib/bind9/doc/arm/man.named.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named.html,v 1.99.14.8.8.1 2009/12/31 23:17:55 tbox Exp $ -->
+<!-- $Id: man.named.html,v 1.99.14.20.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610097"></a><h2>DESCRIPTION</h2>
+<a name="id2610525"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named</strong></span>
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -65,7 +65,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2610128"></a><h2>OPTIONS</h2>
+<a name="id2610556"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-4</span></dt>
<dd><p>
@@ -238,7 +238,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2612161"></a><h2>SIGNALS</h2>
+<a name="id2652594"></a><h2>SIGNALS</h2>
<p>
In routine operation, signals should not be used to control
the nameserver; <span><strong class="command">rndc</strong></span> should be used
@@ -259,16 +259,24 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612211"></a><h2>CONFIGURATION</h2>
+<a name="id2652644"></a><h2>CONFIGURATION</h2>
<p>
The <span><strong class="command">named</strong></span> configuration file is too complex
to describe in detail here. A complete description is provided
in the
<em class="citetitle">BIND 9 Administrator Reference Manual</em>.
</p>
+<p>
+ <span><strong class="command">named</strong></span> inherits the <code class="function">umask</code>
+ (file creation mode mask) from the parent process. If files
+ created by <span><strong class="command">named</strong></span>, such as journal files,
+ need to have custom permissions, the <code class="function">umask</code>
+ should be set explicitly in the script used to start the
+ <span><strong class="command">named</strong></span> process.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612298"></a><h2>FILES</h2>
+<a name="id2652693"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt>
<dd><p>
@@ -281,7 +289,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2612342"></a><h2>SEE ALSO</h2>
+<a name="id2659836"></a><h2>SEE ALSO</h2>
<p><em class="citetitle">RFC 1033</em>,
<em class="citetitle">RFC 1034</em>,
<em class="citetitle">RFC 1035</em>,
@@ -294,7 +302,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612412"></a><h2>AUTHOR</h2>
+<a name="id2659907"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.nsupdate.html b/contrib/bind9/doc/arm/man.nsupdate.html
index eb3b7be..9ba954b 100644
--- a/contrib/bind9/doc/arm/man.nsupdate.html
+++ b/contrib/bind9/doc/arm/man.nsupdate.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.nsupdate.html,v 1.22.14.9.8.1 2009/12/31 23:17:55 tbox Exp $ -->
+<!-- $Id: man.nsupdate.html,v 1.22.14.21.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610846"></a><h2>DESCRIPTION</h2>
+<a name="id2611204"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">nsupdate</strong></span>
is used to submit Dynamic DNS Update requests as defined in RFC2136
to a name server.
@@ -187,7 +187,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611241"></a><h2>INPUT FORMAT</h2>
+<a name="id2611667"></a><h2>INPUT FORMAT</h2>
<p><span><strong class="command">nsupdate</strong></span>
reads input from
<em class="parameter"><code>filename</code></em>
@@ -451,7 +451,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2667228"></a><h2>EXAMPLES</h2>
+<a name="id2660691"></a><h2>EXAMPLES</h2>
<p>
The examples below show how
<span><strong class="command">nsupdate</strong></span>
@@ -505,7 +505,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2667278"></a><h2>FILES</h2>
+<a name="id2660741"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="constant">/etc/resolv.conf</code></span></dt>
<dd><p>
@@ -524,7 +524,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2667348"></a><h2>SEE ALSO</h2>
+<a name="id2660810"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">RFC2136</span></span>,
<span class="citerefentry"><span class="refentrytitle">RFC3007</span></span>,
<span class="citerefentry"><span class="refentrytitle">RFC2104</span></span>,
@@ -537,7 +537,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2667418"></a><h2>BUGS</h2>
+<a name="id2660881"></a><h2>BUGS</h2>
<p>
The TSIG key is redundantly stored in two separate files.
This is a consequence of nsupdate using the DST library
diff --git a/contrib/bind9/doc/arm/man.rndc-confgen.html b/contrib/bind9/doc/arm/man.rndc-confgen.html
index cb59c2e..853b250 100644
--- a/contrib/bind9/doc/arm/man.rndc-confgen.html
+++ b/contrib/bind9/doc/arm/man.rndc-confgen.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc-confgen.html,v 1.102.14.9.8.1 2009/12/31 23:17:56 tbox Exp $ -->
+<!-- $Id: man.rndc-confgen.html,v 1.102.14.21.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -48,7 +48,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc-confgen</code> [<code class="option">-a</code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-c <em class="replaceable"><code>keyfile</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [<code class="option">-s <em class="replaceable"><code>address</code></em></code>] [<code class="option">-t <em class="replaceable"><code>chrootdir</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2613358"></a><h2>DESCRIPTION</h2>
+<a name="id2633104"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc-confgen</strong></span>
generates configuration files
for <span><strong class="command">rndc</strong></span>. It can be used as a
@@ -64,7 +64,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2613425"></a><h2>OPTIONS</h2>
+<a name="id2633170"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd>
@@ -171,7 +171,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2633130"></a><h2>EXAMPLES</h2>
+<a name="id2634989"></a><h2>EXAMPLES</h2>
<p>
To allow <span><strong class="command">rndc</strong></span> to be used with
no manual configuration, run
@@ -188,7 +188,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2633187"></a><h2>SEE ALSO</h2>
+<a name="id2635046"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -196,7 +196,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2633225"></a><h2>AUTHOR</h2>
+<a name="id2635084"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.rndc.conf.html b/contrib/bind9/doc/arm/man.rndc.conf.html
index e8e86ba..66dbe934 100644
--- a/contrib/bind9/doc/arm/man.rndc.conf.html
+++ b/contrib/bind9/doc/arm/man.rndc.conf.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc.conf.html,v 1.103.14.9.8.1 2009/12/31 23:17:56 tbox Exp $ -->
+<!-- $Id: man.rndc.conf.html,v 1.103.14.21.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc.conf</code> </p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2607278"></a><h2>DESCRIPTION</h2>
+<a name="id2606202"></a><h2>DESCRIPTION</h2>
<p><code class="filename">rndc.conf</code> is the configuration file
for <span><strong class="command">rndc</strong></span>, the BIND 9 name server control
utility. This file has a similar structure and syntax to
@@ -135,7 +135,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612843"></a><h2>EXAMPLE</h2>
+<a name="id2613269"></a><h2>EXAMPLE</h2>
<pre class="programlisting">
options {
default-server localhost;
@@ -209,7 +209,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612965"></a><h2>NAME SERVER CONFIGURATION</h2>
+<a name="id2628000"></a><h2>NAME SERVER CONFIGURATION</h2>
<p>
The name server must be configured to accept rndc connections and
to recognize the key specified in the <code class="filename">rndc.conf</code>
@@ -219,7 +219,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612990"></a><h2>SEE ALSO</h2>
+<a name="id2628025"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">mmencode</span>(1)</span>,
@@ -227,7 +227,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2613029"></a><h2>AUTHOR</h2>
+<a name="id2628064"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/arm/man.rndc.html b/contrib/bind9/doc/arm/man.rndc.html
index 36843bc..0bb3085 100644
--- a/contrib/bind9/doc/arm/man.rndc.html
+++ b/contrib/bind9/doc/arm/man.rndc.html
@@ -1,8 +1,8 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc.html,v 1.101.14.9.8.1 2009/12/31 23:17:55 tbox Exp $ -->
+<!-- $Id: man.rndc.html,v 1.101.14.21.2.1 2010/02/25 12:16:49 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc</code> [<code class="option">-b <em class="replaceable"><code>source-address</code></em></code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-k <em class="replaceable"><code>key-file</code></em></code>] [<code class="option">-s <em class="replaceable"><code>server</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-V</code>] [<code class="option">-y <em class="replaceable"><code>key_id</code></em></code>] {command}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2611413"></a><h2>DESCRIPTION</h2>
+<a name="id2612248"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc</strong></span>
controls the operation of a name
server. It supersedes the <span><strong class="command">ndc</strong></span> utility
@@ -79,7 +79,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611463"></a><h2>OPTIONS</h2>
+<a name="id2612298"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-b <em class="replaceable"><code>source-address</code></em></span></dt>
<dd><p>
@@ -151,7 +151,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611961"></a><h2>LIMITATIONS</h2>
+<a name="id2612523"></a><h2>LIMITATIONS</h2>
<p><span><strong class="command">rndc</strong></span>
does not yet support all the commands of
the BIND 8 <span><strong class="command">ndc</strong></span> utility.
@@ -165,7 +165,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611992"></a><h2>SEE ALSO</h2>
+<a name="id2612554"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -175,7 +175,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612048"></a><h2>AUTHOR</h2>
+<a name="id2613088"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/doc/misc/Makefile.in b/contrib/bind9/doc/misc/Makefile.in
index 501e3be..24ef3bc 100644
--- a/contrib/bind9/doc/misc/Makefile.in
+++ b/contrib/bind9/doc/misc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.7 2007/09/24 04:21:59 marka Exp $
+# $Id: Makefile.in,v 1.7.252.2 2009/07/11 23:47:17 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -38,11 +38,13 @@ docclean manclean maintainer-clean::
CFG_TEST = ../../bin/tests/cfg_test
options: FORCE
- if test -x ${CFG_TEST} && \
- ${CFG_TEST} --named --grammar | \
- ${PERL} ${srcdir}/sort-options.pl | \
- ${PERL} ${srcdir}/format-options.pl >$@.new ; then \
+ if test -x ${CFG_TEST} ; \
+ then \
+ ${CFG_TEST} --named --grammar > $@.raw ; \
+ ${PERL} ${srcdir}/sort-options.pl < $@.raw > $@.sorted ; \
+ ${PERL} ${srcdir}/format-options.pl < $@.sorted > $@.new ; \
mv -f $@.new $@ ; \
+ rm -f $@.raw $@.sorted ; \
else \
- rm -f $@.new ; \
+ rm -f $@.new $@.raw $@.sorted ; \
fi
diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api
index 4bcf883..4fc7eca 100644
--- a/contrib/bind9/lib/dns/api
+++ b/contrib/bind9/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 53
+LIBINTERFACE = 56
LIBREVISION = 0
-LIBAGE = 0
+LIBAGE = 1
diff --git a/contrib/bind9/lib/dns/db.c b/contrib/bind9/lib/dns/db.c
index a4c2864..02ea6b5 100644
--- a/contrib/bind9/lib/dns/db.c
+++ b/contrib/bind9/lib/dns/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.c,v 1.88 2008/09/24 02:46:22 marka Exp $ */
+/* $Id: db.c,v 1.88.50.2 2009/06/23 00:19:34 tbox Exp $ */
/*! \file */
@@ -854,12 +854,14 @@ dns_db_unregister(dns_dbimplementation_t **dbimp) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
imp = *dbimp;
+ *dbimp = NULL;
RWLOCK(&implock, isc_rwlocktype_write);
ISC_LIST_UNLINK(implementations, imp, link);
mctx = imp->mctx;
isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t));
isc_mem_detach(&mctx);
RWUNLOCK(&implock, isc_rwlocktype_write);
+ ENSURE(*dbimp == NULL);
}
isc_result_t
diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c
index 9b4e968..1d04961 100644
--- a/contrib/bind9/lib/dns/dispatch.c
+++ b/contrib/bind9/lib/dns/dispatch.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.155.12.7 2009/04/28 21:39:45 jinmei Exp $ */
+/* $Id: dispatch.c,v 1.155.12.11 2009/12/02 23:26:28 marka Exp $ */
/*! \file */
@@ -746,13 +746,19 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
return (portentry);
}
+/*%
+ * The caller must not hold the qid->lock.
+ */
static void
deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
dispportentry_t *portentry = *portentryp;
+ dns_qid_t *qid;
REQUIRE(disp->port_table != NULL);
REQUIRE(portentry != NULL && portentry->refs > 0);
+ qid = DNS_QID(disp);
+ LOCK(&qid->lock);
portentry->refs--;
if (portentry->refs == 0) {
ISC_LIST_UNLINK(disp->port_table[portentry->port %
@@ -762,6 +768,7 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
}
*portentryp = NULL;
+ UNLOCK(&qid->lock);
}
/*%
@@ -779,8 +786,9 @@ socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]);
while (dispsock != NULL) {
- if (isc_sockaddr_equal(dest, &dispsock->host) &&
- dispsock->portentry->port == port)
+ if (dispsock->portentry != NULL &&
+ dispsock->portentry->port == port &&
+ isc_sockaddr_equal(dest, &dispsock->host))
return (dispsock);
dispsock = ISC_LIST_NEXT(dispsock, blink);
}
@@ -2048,8 +2056,18 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
/* Create or adjust buffer pool */
if (mgr->bpool != NULL) {
- isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
- mgr->maxbuffers = maxbuffers;
+ /*
+ * We only increase the maxbuffers to avoid accidental buffer
+ * shortage. Ideally we'd separate the manager-wide maximum
+ * from per-dispatch limits and respect the latter within the
+ * global limit. But at this moment that's deemed to be
+ * overkilling and isn't worth additional implementation
+ * complexity.
+ */
+ if (maxbuffers > mgr->maxbuffers) {
+ isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
+ mgr->maxbuffers = maxbuffers;
+ }
} else {
result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool);
if (result != ISC_R_SUCCESS) {
diff --git a/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c
index baf3ec5..8ae29bc 100644
--- a/contrib/bind9/lib/dns/dnssec.c
+++ b/contrib/bind9/lib/dns/dnssec.c
@@ -16,7 +16,7 @@
*/
/*
- * $Id: dnssec.c,v 1.93.12.4 2009/06/08 23:47:00 tbox Exp $
+ * $Id: dnssec.c,v 1.93.12.6 2009/06/22 23:47:18 tbox Exp $
*/
/*! \file */
@@ -93,6 +93,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
isc_result_t ret;
int i = 0, n;
dns_rdata_t *data;
+ dns_rdataset_t rdataset;
n = dns_rdataset_count(set);
@@ -100,8 +101,11 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
if (data == NULL)
return (ISC_R_NOMEMORY);
- ret = dns_rdataset_first(set);
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_clone(set, &rdataset);
+ ret = dns_rdataset_first(&rdataset);
if (ret != ISC_R_SUCCESS) {
+ dns_rdataset_disassociate(&rdataset);
isc_mem_put(mctx, data, n * sizeof(dns_rdata_t));
return (ret);
}
@@ -111,8 +115,8 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
*/
do {
dns_rdata_init(&data[i]);
- dns_rdataset_current(set, &data[i++]);
- } while (dns_rdataset_next(set) == ISC_R_SUCCESS);
+ dns_rdataset_current(&rdataset, &data[i++]);
+ } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS);
/*
* Sort the array.
@@ -120,6 +124,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper);
*rdata = data;
*nrdata = n;
+ dns_rdataset_disassociate(&rdataset);
return (ISC_R_SUCCESS);
}
@@ -890,3 +895,59 @@ failure:
return (result);
}
+
+/*%
+ * Does this key ('rdata') self sign the rrset ('rdataset')?
+ */
+isc_boolean_t
+dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ isc_boolean_t ignoretime, isc_mem_t *mctx)
+{
+ dst_key_t *dstkey = NULL;
+ dns_keytag_t keytag;
+ dns_rdata_dnskey_t key;
+ dns_rdata_rrsig_t sig;
+ dns_rdata_t sigrdata = DNS_RDATA_INIT;
+ isc_result_t result;
+
+ INSIST(rdataset->type == dns_rdatatype_key ||
+ rdataset->type == dns_rdatatype_dnskey);
+ if (rdataset->type == dns_rdatatype_key) {
+ INSIST(sigrdataset->type == dns_rdatatype_sig);
+ INSIST(sigrdataset->covers == dns_rdatatype_key);
+ } else {
+ INSIST(sigrdataset->type == dns_rdatatype_rrsig);
+ INSIST(sigrdataset->covers == dns_rdatatype_dnskey);
+ }
+
+ result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ result = dns_rdata_tostruct(rdata, &key, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ keytag = dst_key_id(dstkey);
+ for (result = dns_rdataset_first(sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(sigrdataset))
+ {
+ dns_rdata_reset(&sigrdata);
+ dns_rdataset_current(sigrdataset, &sigrdata);
+ result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ if (sig.algorithm == key.algorithm &&
+ sig.keyid == keytag) {
+ result = dns_dnssec_verify2(name, rdataset, dstkey,
+ ignoretime, mctx,
+ &sigrdata, NULL);
+ if (result == ISC_R_SUCCESS) {
+ dst_key_free(&dstkey);
+ return (ISC_TRUE);
+ }
+ }
+ }
+ dst_key_free(&dstkey);
+ return (ISC_FALSE);
+}
diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c
index 144c685..bbb0a09 100644
--- a/contrib/bind9/lib/dns/dst_api.c
+++ b/contrib/bind9/lib/dns/dst_api.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.16.12.3 2009/03/02 02:00:34 marka Exp $
+ * $Id: dst_api.c,v 1.16.12.10 2010/01/15 19:38:53 each Exp $
*/
/*! \file */
@@ -183,9 +183,16 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512]));
#ifdef OPENSSL
RETERR(dst__openssl_init());
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5]));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1]));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1]));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5],
+ DST_ALG_RSAMD5));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1],
+ DST_ALG_RSASHA1));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1],
+ DST_ALG_NSEC3RSASHA1));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256],
+ DST_ALG_RSASHA256));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512],
+ DST_ALG_RSASHA512));
#ifdef HAVE_OPENSSL_DSA
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA]));
@@ -848,6 +855,8 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
*n = (key->key_size + 7) / 8;
break;
case DST_ALG_DSA:
@@ -1017,6 +1026,9 @@ dst_key_read_public(const char *filename, int type,
/* Read the next word: either TTL, class, or 'KEY' */
NEXTTOKEN(lex, opt, &token);
+ if (token.type != isc_tokentype_string)
+ BADTOKEN();
+
/* If it's a TTL, read the next one */
result = dns_ttl_fromtext(&token.value.as_textregion, &ttl);
if (result == ISC_R_SUCCESS)
@@ -1072,6 +1084,8 @@ issymmetric(const dst_key_t *key) {
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
case DST_ALG_DH:
@@ -1152,7 +1166,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) {
fprintf(fp, " ");
isc_buffer_usedregion(&classb, &r);
- fwrite(r.base, 1, r.length, fp);
+ isc_util_fwrite(r.base, 1, r.length, fp);
if ((type & DST_TYPE_KEY) != 0)
fprintf(fp, " KEY ");
@@ -1160,7 +1174,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) {
fprintf(fp, " DNSKEY ");
isc_buffer_usedregion(&textb, &r);
- fwrite(r.base, 1, r.length, fp);
+ isc_util_fwrite(r.base, 1, r.length, fp);
fputc('\n', fp);
fflush(fp);
@@ -1275,7 +1289,8 @@ algorithm_status(unsigned int alg) {
if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
alg == DST_ALG_DSA || alg == DST_ALG_DH ||
alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA ||
- alg == DST_ALG_NSEC3RSASHA1)
+ alg == DST_ALG_NSEC3RSASHA1 ||
+ alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512)
return (DST_R_NOCRYPTO);
#endif
return (DST_R_UNSUPPORTEDALG);
@@ -1297,6 +1312,8 @@ addsuffix(char *filename, unsigned int len, const char *ofilename,
n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix);
if (n < 0)
+ return (ISC_R_FAILURE);
+ if ((unsigned int)n >= len)
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
}
@@ -1304,6 +1321,9 @@ addsuffix(char *filename, unsigned int len, const char *ofilename,
isc_result_t
dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
unsigned int flags = dst_entropy_flags;
+
+ if (len == 0)
+ return (ISC_R_SUCCESS);
if (pseudo)
flags &= ~ISC_ENTROPY_GOODONLY;
return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
@@ -1311,5 +1331,22 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
unsigned int
dst__entropy_status(void) {
+#ifdef GSSAPI
+ unsigned int flags = dst_entropy_flags;
+ isc_result_t ret;
+ unsigned char buf[32];
+ static isc_boolean_t first = ISC_TRUE;
+
+ if (first) {
+ /* Someone believes RAND_status() initializes the PRNG */
+ flags &= ~ISC_ENTROPY_GOODONLY;
+ ret = isc_entropy_getdata(dst_entropy_pool, buf,
+ sizeof(buf), NULL, flags);
+ INSIST(ret == ISC_R_SUCCESS);
+ isc_entropy_putdata(dst_entropy_pool, buf,
+ sizeof(buf), 2 * sizeof(buf));
+ first = ISC_FALSE;
+ }
+#endif
return (isc_entropy_status(dst_entropy_pool));
}
diff --git a/contrib/bind9/lib/dns/dst_internal.h b/contrib/bind9/lib/dns/dst_internal.h
index 0c1a71c..1669648 100644
--- a/contrib/bind9/lib/dns/dst_internal.h
+++ b/contrib/bind9/lib/dns/dst_internal.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_internal.h,v 1.11 2008/04/01 23:47:10 tbox Exp $ */
+/* $Id: dst_internal.h,v 1.11.120.2 2010/01/15 23:47:33 tbox Exp $ */
#ifndef DST_DST_INTERNAL_H
#define DST_DST_INTERNAL_H 1
@@ -42,6 +42,7 @@
#include <isc/types.h>
#include <isc/md5.h>
#include <isc/sha1.h>
+#include <isc/sha2.h>
#include <isc/hmacmd5.h>
#include <isc/hmacsha.h>
@@ -97,7 +98,7 @@ struct dst_key {
void *generic;
gss_ctx_id_t gssctx;
#ifdef OPENSSL
-#if USE_EVP_RSA
+#if !defined(USE_EVP) || !USE_EVP
RSA *rsa;
#endif
DSA *dsa;
@@ -124,6 +125,8 @@ struct dst_context {
dst_gssapi_signverifyctx_t *gssctx;
isc_md5_t *md5ctx;
isc_sha1_t *sha1ctx;
+ isc_sha256_t *sha256ctx;
+ isc_sha512_t *sha512ctx;
isc_hmacmd5_t *hmacmd5ctx;
isc_hmacsha1_t *hmacsha1ctx;
isc_hmacsha224_t *hmacsha224ctx;
@@ -183,7 +186,8 @@ isc_result_t dst__hmacsha224_init(struct dst_func **funcp);
isc_result_t dst__hmacsha256_init(struct dst_func **funcp);
isc_result_t dst__hmacsha384_init(struct dst_func **funcp);
isc_result_t dst__hmacsha512_init(struct dst_func **funcp);
-isc_result_t dst__opensslrsa_init(struct dst_func **funcp);
+isc_result_t dst__opensslrsa_init(struct dst_func **funcp,
+ unsigned char algorithm);
isc_result_t dst__openssldsa_init(struct dst_func **funcp);
isc_result_t dst__openssldh_init(struct dst_func **funcp);
isc_result_t dst__gssapi_init(struct dst_func **funcp);
diff --git a/contrib/bind9/lib/dns/dst_parse.c b/contrib/bind9/lib/dns/dst_parse.c
index 2da72ae..e8ab34f 100644
--- a/contrib/bind9/lib/dns/dst_parse.c
+++ b/contrib/bind9/lib/dns/dst_parse.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*%
* Principal Author: Brian Wellington
- * $Id: dst_parse.c,v 1.14.120.2 2009/03/02 23:47:11 tbox Exp $
+ * $Id: dst_parse.c,v 1.14.120.6 2010/01/15 19:38:53 each Exp $
*/
#include <config.h>
@@ -480,6 +480,18 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
case DST_ALG_RSASHA1:
fprintf(fp, "(RSASHA1)\n");
break;
+ case DST_ALG_NSEC3DSA:
+ fprintf(fp, "(NSEC3DSA)\n");
+ break;
+ case DST_ALG_NSEC3RSASHA1:
+ fprintf(fp, "(NSEC3RSASHA1)\n");
+ break;
+ case DST_ALG_RSASHA256:
+ fprintf(fp, "(RSASHA256)\n");
+ break;
+ case DST_ALG_RSASHA512:
+ fprintf(fp, "(RSASHA512)\n");
+ break;
case DST_ALG_HMACMD5:
fprintf(fp, "(HMAC_MD5)\n");
break;
@@ -521,7 +533,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
isc_buffer_usedregion(&b, &r);
fprintf(fp, "%s ", s);
- fwrite(r.base, 1, r.length, fp);
+ isc_util_fwrite(r.base, 1, r.length, fp);
fprintf(fp, "\n");
}
diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h
index c75c774..9a1126d 100644
--- a/contrib/bind9/lib/dns/include/dns/db.h
+++ b/contrib/bind9/lib/dns/include/dns/db.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.h,v 1.93.50.3.12.1 2009/12/31 21:44:37 each Exp $ */
+/* $Id: db.h,v 1.93.50.5 2009/11/25 23:48:42 tbox Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -695,6 +695,10 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* For cache databases, glue is any rdataset with a trust of
* dns_trust_glue.
*
+ * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no
+ * additional records will be returned. Only caches can have
+ * rdataset with trust dns_trust_additional.
+ *
* \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no
* pending data will be returned. This option is only meaningful for
* cache databases.
diff --git a/contrib/bind9/lib/dns/include/dns/dnssec.h b/contrib/bind9/lib/dns/include/dns/dnssec.h
index c5206be..1446266 100644
--- a/contrib/bind9/lib/dns/include/dns/dnssec.h
+++ b/contrib/bind9/lib/dns/include/dns/dnssec.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec.h,v 1.32.332.4 2009/06/08 23:47:00 tbox Exp $ */
+/* $Id: dnssec.h,v 1.32.332.6 2009/06/22 23:47:18 tbox Exp $ */
#ifndef DNS_DNSSEC_H
#define DNS_DNSSEC_H 1
@@ -178,6 +178,12 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
*\li DST_R_*
*/
+isc_boolean_t
+dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ isc_boolean_t ignoretime, isc_mem_t *mctx);
+
+
ISC_LANG_ENDDECLS
#endif /* DNS_DNSSEC_H */
diff --git a/contrib/bind9/lib/dns/include/dns/journal.h b/contrib/bind9/lib/dns/include/dns/journal.h
index 3917d8d..a1e16e4 100644
--- a/contrib/bind9/lib/dns/include/dns/journal.h
+++ b/contrib/bind9/lib/dns/include/dns/journal.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.h,v 1.33.120.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: journal.h,v 1.33.120.4 2009/11/04 23:47:25 tbox Exp $ */
#ifndef DNS_JOURNAL_H
#define DNS_JOURNAL_H 1
@@ -232,12 +232,19 @@ dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,
isc_result_t
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
const char *filename);
+
+isc_result_t
+dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
+ isc_uint32_t resign, const char *filename);
/*%<
* Roll forward (play back) the journal file "filename" into the
* database "db". This should be called when the server starts
- * after a shutdown or crash.
+ * after a shutdown or crash. 'resign' is how many seconds before
+ * a RRSIG is due to expire it should be scheduled to be regenerated.
*
* Requires:
+ *\li dns_journal_rollforward() requires that DNS_JOURNALOPT_RESIGN
+ * is not set.
*\li 'mctx' is a valid memory context.
*\li 'db' is a valid database which does not have a version
* open for writing.
diff --git a/contrib/bind9/lib/dns/include/dns/keyvalues.h b/contrib/bind9/lib/dns/include/dns/keyvalues.h
index 7f509e6..f4a50fa 100644
--- a/contrib/bind9/lib/dns/include/dns/keyvalues.h
+++ b/contrib/bind9/lib/dns/include/dns/keyvalues.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: keyvalues.h,v 1.23.48.2 2009/06/04 02:56:14 tbox Exp $ */
+/* $Id: keyvalues.h,v 1.23.48.4 2010/01/15 23:47:33 tbox Exp $ */
#ifndef DNS_KEYVALUES_H
#define DNS_KEYVALUES_H 1
@@ -69,6 +69,8 @@
#define DNS_KEYALG_ECC 4
#define DNS_KEYALG_RSASHA1 5
#define DNS_KEYALG_NSEC3RSASHA1 7
+#define DNS_KEYALG_RSASHA256 8
+#define DNS_KEYALG_RSASHA512 10
#define DNS_KEYALG_INDIRECT 252
#define DNS_KEYALG_PRIVATEDNS 253
#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */
diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h
index 0149301..dc6e525 100644
--- a/contrib/bind9/lib/dns/include/dns/name.h
+++ b/contrib/bind9/lib/dns/include/dns/name.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name.h,v 1.126.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: name.h,v 1.126.332.3 2009/12/24 00:34:59 each Exp $ */
#ifndef DNS_NAME_H
#define DNS_NAME_H 1
@@ -99,12 +99,6 @@ ISC_LANG_BEGINDECLS
*****/
/***
- *** Compression pointer chaining limit
- ***/
-
-#define DNS_POINTER_MAXHOPS 16
-
-/***
*** Types
***/
diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h
index d61684d..0677211 100644
--- a/contrib/bind9/lib/dns/include/dns/ncache.h
+++ b/contrib/bind9/lib/dns/include/dns/ncache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.h,v 1.25.142.1 2009/12/31 20:29:21 each Exp $ */
+/* $Id: ncache.h,v 1.25.48.2 2009/12/30 23:47:31 tbox Exp $ */
#ifndef DNS_NCACHE_H
#define DNS_NCACHE_H 1
diff --git a/contrib/bind9/lib/dns/include/dns/nsec3.h b/contrib/bind9/lib/dns/include/dns/nsec3.h
index 2d6a8dd..6243fdb 100644
--- a/contrib/bind9/lib/dns/include/dns/nsec3.h
+++ b/contrib/bind9/lib/dns/include/dns/nsec3.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.h,v 1.5.48.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: nsec3.h,v 1.5.48.3 2009/10/06 21:20:18 each Exp $ */
#ifndef DNS_NSEC3_H
#define DNS_NSEC3_H 1
@@ -28,6 +28,8 @@
#include <dns/rdatastruct.h>
#include <dns/types.h>
+#define DNS_NSEC3_SALTSIZE 255
+
/*
* hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max)
* hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max)
diff --git a/contrib/bind9/lib/dns/include/dns/rbt.h b/contrib/bind9/lib/dns/include/dns/rbt.h
index 6eea787..2615596 100644
--- a/contrib/bind9/lib/dns/include/dns/rbt.h
+++ b/contrib/bind9/lib/dns/include/dns/rbt.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt.h,v 1.71.48.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: rbt.h,v 1.71.48.3 2009/10/20 05:06:04 marka Exp $ */
#ifndef DNS_RBT_H
#define DNS_RBT_H 1
@@ -105,11 +105,11 @@ struct dns_rbtnode {
unsigned int is_root : 1; /*%< range is 0..1 */
unsigned int color : 1; /*%< range is 0..1 */
unsigned int find_callback : 1; /*%< range is 0..1 */
- unsigned int attributes : 3; /*%< range is 0..2 */
+ unsigned int attributes : 4; /*%< range is 0..2 */
unsigned int nsec3 : 1; /*%< range is 0..1 */
unsigned int namelen : 8; /*%< range is 1..255 */
unsigned int offsetlen : 8; /*%< range is 1..128 */
- unsigned int padbytes : 9; /*%< range is 0..380 */
+ unsigned int oldnamelen : 8; /*%< range is 1..255 */
/*@}*/
#ifdef DNS_RBT_USEHASH
diff --git a/contrib/bind9/lib/dns/include/dns/rdataset.h b/contrib/bind9/lib/dns/include/dns/rdataset.h
index baff146..d435ed0 100644
--- a/contrib/bind9/lib/dns/include/dns/rdataset.h
+++ b/contrib/bind9/lib/dns/include/dns/rdataset.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.h,v 1.65.50.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: rdataset.h,v 1.65.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
@@ -110,6 +110,9 @@ typedef struct dns_rdatasetmethods {
dns_rdataset_t *rdataset,
dns_rdatasetadditional_t type,
dns_rdatatype_t qtype);
+ void (*settrust)(dns_rdataset_t *rdataset,
+ dns_trust_t trust);
+ void (*expire)(dns_rdataset_t *rdataset);
} dns_rdatasetmethods_t;
#define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R')
@@ -634,6 +637,19 @@ dns_rdataset_putadditional(dns_acache_t *acache,
* information for 'rdataset.'
*/
+void
+dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
+/*%<
+ * Set the trust of the 'rdataset' to trust in any in the backing database.
+ * The local trust level of 'rdataset' is also set.
+ */
+
+void
+dns_rdataset_expire(dns_rdataset_t *rdataset);
+/*%<
+ * Mark the rdataset to be expired in the backing database.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_RDATASET_H */
diff --git a/contrib/bind9/lib/dns/include/dns/resolver.h b/contrib/bind9/lib/dns/include/dns/resolver.h
index fa837c1..8c7ad72 100644
--- a/contrib/bind9/lib/dns/include/dns/resolver.h
+++ b/contrib/bind9/lib/dns/include/dns/resolver.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.h,v 1.60.56.3 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: resolver.h,v 1.60.56.3.22.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -508,6 +508,48 @@ dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state);
unsigned int
dns_resolver_getoptions(dns_resolver_t *resolver);
+void
+dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *expire);
+/*%<
+ * Add a entry to the bad cache for <name,type> that will expire at 'expire'.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ * \li name to be valid.
+ */
+
+isc_boolean_t
+dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *now);
+/*%<
+ * Check to see if there is a unexpired entry in the bad cache for
+ * <name,type>.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ * \li name to be valid.
+ */
+
+void
+dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name);
+/*%<
+ * Flush the bad cache of all entries at 'name' if 'name' is non NULL.
+ * Flush the entire bad cache if 'name' is NULL.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
+void
+dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp);
+/*%
+ * Print out the contents of the bad cache to 'fp'.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_RESOLVER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/result.h b/contrib/bind9/lib/dns/include/dns/result.h
index ed29bcd..a1e7f53 100644
--- a/contrib/bind9/lib/dns/include/dns/result.h
+++ b/contrib/bind9/lib/dns/include/dns/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.116 2008/09/25 04:02:39 tbox Exp $ */
+/* $Id: result.h,v 1.116.226.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
@@ -148,8 +148,10 @@
#define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102)
#define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103)
#define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104)
+#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105)
+#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106)
-#define DNS_R_NRESULTS 105 /*%< Number of results */
+#define DNS_R_NRESULTS 107 /*%< Number of results */
/*
* DNS wire format rcodes.
diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h
index 525dd8d..10ce229 100644
--- a/contrib/bind9/lib/dns/include/dns/types.h
+++ b/contrib/bind9/lib/dns/include/dns/types.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.130.50.3.12.2 2009/12/31 20:29:21 each Exp $ */
+/* $Id: types.h,v 1.130.50.5 2009/12/30 08:34:30 jinmei Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h
index 2555214..1da4e0c 100644
--- a/contrib/bind9/lib/dns/include/dns/validator.h
+++ b/contrib/bind9/lib/dns/include/dns/validator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.h,v 1.41.48.3 2009/01/18 23:25:17 marka Exp $ */
+/* $Id: validator.h,v 1.41.48.3.22.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_VALIDATOR_H
#define DNS_VALIDATOR_H 1
@@ -159,6 +159,8 @@ struct dns_validator {
isc_boolean_t mustbesecure;
unsigned int dlvlabels;
unsigned int depth;
+ unsigned int authcount;
+ unsigned int authfail;
};
/*%
diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h
index e2859ae..746b43c 100644
--- a/contrib/bind9/lib/dns/include/dns/zone.h
+++ b/contrib/bind9/lib/dns/include/dns/zone.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.160.50.4 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: zone.h,v 1.160.50.6 2009/10/05 21:57:00 each Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
@@ -149,13 +149,24 @@ dns_zone_getclass(dns_zone_t *zone);
*\li 'zone' to be a valid zone.
*/
+isc_result_t
+dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp);
+
isc_uint32_t
dns_zone_getserial(dns_zone_t *zone);
/*%<
- * Returns the current serial number of the zone.
+ * Returns the current serial number of the zone. On success, the SOA
+ * serial of the zone will be copied into '*serialp'.
+ * dns_zone_getserial() cannot catch failure cases and is deprecated by
+ * dns_zone_getserial2().
*
* Requires:
*\li 'zone' to be a valid zone.
+ *\li 'serialp' to be non NULL
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #DNS_R_NOTLOADED zone DB is not loaded
*/
void
@@ -256,6 +267,9 @@ dns_zone_load(dns_zone_t *zone);
isc_result_t
dns_zone_loadnew(dns_zone_t *zone);
+
+isc_result_t
+dns_zone_loadandthaw(dns_zone_t *zone);
/*%<
* Cause the database to be loaded from its backing store.
* Confirm that the minimum requirements for the zone type are
@@ -264,6 +278,8 @@ dns_zone_loadnew(dns_zone_t *zone);
* dns_zone_loadnew() only loads zones that are not yet loaded.
* dns_zone_load() also loads zones that are already loaded and
* and whose master file has changed since the last load.
+ * dns_zone_loadandthaw() is similar to dns_zone_load() but will
+ * also re-enable DNS UPDATEs when the load completes.
*
* Require:
*\li 'zone' to be a valid zone.
diff --git a/contrib/bind9/lib/dns/include/dst/dst.h b/contrib/bind9/lib/dns/include/dst/dst.h
index 702ad71..de262bd 100644
--- a/contrib/bind9/lib/dns/include/dst/dst.h
+++ b/contrib/bind9/lib/dns/include/dst/dst.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst.h,v 1.12 2008/09/24 02:46:23 marka Exp $ */
+/* $Id: dst.h,v 1.12.50.2 2010/01/15 23:47:34 tbox Exp $ */
#ifndef DST_DST_H
#define DST_DST_H 1
@@ -53,6 +53,8 @@ typedef struct dst_context dst_context_t;
#define DST_ALG_RSASHA1 5
#define DST_ALG_NSEC3DSA 6
#define DST_ALG_NSEC3RSASHA1 7
+#define DST_ALG_RSASHA256 8
+#define DST_ALG_RSASHA512 10
#define DST_ALG_HMACMD5 157
#define DST_ALG_GSSAPI 160
#define DST_ALG_HMACSHA1 161 /* XXXMPA */
diff --git a/contrib/bind9/lib/dns/journal.c b/contrib/bind9/lib/dns/journal.c
index 8c21f1e..638e647 100644
--- a/contrib/bind9/lib/dns/journal.c
+++ b/contrib/bind9/lib/dns/journal.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.c,v 1.103.48.2 2009/01/18 23:47:37 tbox Exp $ */
+/* $Id: journal.c,v 1.103.48.6 2009/11/04 23:47:25 tbox Exp $ */
#include <config.h>
@@ -1218,7 +1218,9 @@ dns_journal_destroy(dns_journal_t **journalp) {
/* XXX Share code with incoming IXFR? */
static isc_result_t
-roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
+roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options,
+ isc_uint32_t resign)
+{
isc_buffer_t source; /* Transaction data from disk */
isc_buffer_t target; /* Ditto after _fromwire check */
isc_uint32_t db_serial; /* Database SOA serial */
@@ -1235,6 +1237,7 @@ roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
REQUIRE(DNS_DB_VALID(db));
dns_diff_init(j->mctx, &diff);
+ diff.resign = resign;
/*
* Set up empty initial buffers for unchecked and checked
@@ -1353,6 +1356,14 @@ isc_result_t
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db,
unsigned int options, const char *filename)
{
+ REQUIRE((options & DNS_JOURNALOPT_RESIGN) == 0);
+ return (dns_journal_rollforward2(mctx, db, options, 0, filename));
+}
+
+isc_result_t
+dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
+ isc_uint32_t resign, const char *filename)
+{
dns_journal_t *j;
isc_result_t result;
@@ -1371,7 +1382,7 @@ dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db,
if (JOURNAL_EMPTY(&j->header))
result = DNS_R_UPTODATE;
else
- result = roll_forward(j, db, options);
+ result = roll_forward(j, db, options, resign);
dns_journal_destroy(&j);
@@ -1850,18 +1861,11 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) {
return (result);
}
-/*
- * Compare the databases 'dba' and 'dbb' and generate a journal
- * entry containing the changes to make 'dba' from 'dbb' (note
- * the order). This journal entry will consist of a single,
- * possibly very large transaction.
- */
-
-isc_result_t
-dns_db_diff(isc_mem_t *mctx,
- dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb,
- const char *journal_filename)
+static isc_result_t
+diff_namespace(isc_mem_t *mctx,
+ dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb,
+ unsigned int options, dns_diff_t *resultdiff)
{
dns_db_t *db[2];
dns_dbversion_t *ver[2];
@@ -1869,30 +1873,24 @@ dns_db_diff(isc_mem_t *mctx,
isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE };
dns_fixedname_t fixname[2];
isc_result_t result, itresult[2];
- dns_diff_t diff[2], resultdiff;
+ dns_diff_t diff[2];
int i, t;
- dns_journal_t *journal = NULL;
db[0] = dba, db[1] = dbb;
ver[0] = dbvera, ver[1] = dbverb;
dns_diff_init(mctx, &diff[0]);
dns_diff_init(mctx, &diff[1]);
- dns_diff_init(mctx, &resultdiff);
dns_fixedname_init(&fixname[0]);
dns_fixedname_init(&fixname[1]);
- result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal);
+ result = dns_db_createiterator(db[0], options, &dbit[0]);
if (result != ISC_R_SUCCESS)
return (result);
-
- result = dns_db_createiterator(db[0], 0, &dbit[0]);
- if (result != ISC_R_SUCCESS)
- goto cleanup_journal;
- result = dns_db_createiterator(db[1], 0, &dbit[1]);
+ result = dns_db_createiterator(db[1], options, &dbit[1]);
if (result != ISC_R_SUCCESS)
- goto cleanup_interator0;
+ goto cleanup_iterator;
itresult[0] = dns_dbiterator_first(dbit[0]);
itresult[1] = dns_dbiterator_first(dbit[1]);
@@ -1919,7 +1917,7 @@ dns_db_diff(isc_mem_t *mctx,
for (i = 0; i < 2; i++) {
if (! have[!i]) {
- ISC_LIST_APPENDLIST(resultdiff.tuples,
+ ISC_LIST_APPENDLIST(resultdiff->tuples,
diff[i].tuples, link);
INSIST(ISC_LIST_EMPTY(diff[i].tuples));
have[i] = ISC_FALSE;
@@ -1930,21 +1928,21 @@ dns_db_diff(isc_mem_t *mctx,
t = dns_name_compare(dns_fixedname_name(&fixname[0]),
dns_fixedname_name(&fixname[1]));
if (t < 0) {
- ISC_LIST_APPENDLIST(resultdiff.tuples,
+ ISC_LIST_APPENDLIST(resultdiff->tuples,
diff[0].tuples, link);
INSIST(ISC_LIST_EMPTY(diff[0].tuples));
have[0] = ISC_FALSE;
continue;
}
if (t > 0) {
- ISC_LIST_APPENDLIST(resultdiff.tuples,
+ ISC_LIST_APPENDLIST(resultdiff->tuples,
diff[1].tuples, link);
INSIST(ISC_LIST_EMPTY(diff[1].tuples));
have[1] = ISC_FALSE;
continue;
}
INSIST(t == 0);
- CHECK(dns_diff_subtract(diff, &resultdiff));
+ CHECK(dns_diff_subtract(diff, resultdiff));
INSIST(ISC_LIST_EMPTY(diff[0].tuples));
INSIST(ISC_LIST_EMPTY(diff[1].tuples));
have[0] = have[1] = ISC_FALSE;
@@ -1955,20 +1953,49 @@ dns_db_diff(isc_mem_t *mctx,
if (itresult[1] != ISC_R_NOMORE)
FAIL(itresult[1]);
+ INSIST(ISC_LIST_EMPTY(diff[0].tuples));
+ INSIST(ISC_LIST_EMPTY(diff[1].tuples));
+
+ failure:
+ dns_dbiterator_destroy(&dbit[1]);
+ cleanup_iterator:
+ dns_dbiterator_destroy(&dbit[0]);
+ return (result);
+}
+
+/*
+ * Compare the databases 'dba' and 'dbb' and generate a journal
+ * entry containing the changes to make 'dba' from 'dbb' (note
+ * the order). This journal entry will consist of a single,
+ * possibly very large transaction.
+ */
+isc_result_t
+dns_db_diff(isc_mem_t *mctx,
+ dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb,
+ const char *journal_filename)
+{
+ isc_result_t result;
+ dns_journal_t *journal = NULL;
+ dns_diff_t resultdiff;
+
+ result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_diff_init(mctx, &resultdiff);
+
+ CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb,
+ DNS_DB_NONSEC3, &resultdiff));
+ CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb,
+ DNS_DB_NSEC3ONLY, &resultdiff));
if (ISC_LIST_EMPTY(resultdiff.tuples)) {
isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes");
} else {
CHECK(dns_journal_write_transaction(journal, &resultdiff));
}
- INSIST(ISC_LIST_EMPTY(diff[0].tuples));
- INSIST(ISC_LIST_EMPTY(diff[1].tuples));
-
failure:
dns_diff_clear(&resultdiff);
- dns_dbiterator_destroy(&dbit[1]);
- cleanup_interator0:
- dns_dbiterator_destroy(&dbit[0]);
- cleanup_journal:
dns_journal_destroy(&journal);
return (result);
}
diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c
index 1dbb1e6..314112c 100644
--- a/contrib/bind9/lib/dns/masterdump.c
+++ b/contrib/bind9/lib/dns/masterdump.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.94.50.2.12.1 2009/11/18 23:58:04 marka Exp $ */
+/* $Id: masterdump.c,v 1.94.50.3 2009/11/18 00:15:37 marka Exp $ */
/*! \file */
diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c
index b541635..2e34120 100644
--- a/contrib/bind9/lib/dns/message.c
+++ b/contrib/bind9/lib/dns/message.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: message.c,v 1.245.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: message.c,v 1.245.50.3 2009/11/24 03:25:53 marka Exp $ */
/*! \file */
@@ -1888,6 +1888,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
msg->counts[sectionid] += total;
return (result);
}
+ if (result == ISC_R_NOSPACE)
+ msg->flags |= DNS_MESSAGEFLAG_TC;
if (result != ISC_R_SUCCESS) {
INSIST(st.used < 65536);
dns_compress_rollback(msg->cctx,
diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c
index af0450b..733d138 100644
--- a/contrib/bind9/lib/dns/ncache.c
+++ b/contrib/bind9/lib/dns/ncache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.c,v 1.43 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: ncache.c,v 1.43.334.2 2010/02/25 10:57:11 tbox Exp $ */
/*! \file */
@@ -519,6 +519,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/nsec3.c b/contrib/bind9/lib/dns/nsec3.c
index f9b8cad..ea6546d 100644
--- a/contrib/bind9/lib/dns/nsec3.c
+++ b/contrib/bind9/lib/dns/nsec3.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.c,v 1.6.12.2 2009/06/04 02:56:14 tbox Exp $ */
+/* $Id: nsec3.c,v 1.6.12.4 2009/11/03 23:47:46 tbox Exp $ */
#include <config.h>
@@ -87,6 +87,8 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
unsigned int i, window;
int octet;
isc_boolean_t found;
+ isc_boolean_t found_ns;
+ isc_boolean_t need_rrsig;
unsigned char *nsec_bits, *bm;
unsigned int max_type;
@@ -140,7 +142,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
if (result != ISC_R_SUCCESS)
return (result);
- found = ISC_FALSE;
+ found = found_ns = need_rrsig = ISC_FALSE;
for (result = dns_rdatasetiter_first(rdsiter);
result == ISC_R_SUCCESS;
result = dns_rdatasetiter_next(rdsiter))
@@ -152,13 +154,26 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
if (rdataset.type > max_type)
max_type = rdataset.type;
set_bit(bm, rdataset.type, 1);
- /* Don't set RRSIG for insecure delegation. */
- if (rdataset.type != dns_rdatatype_ns)
+ /*
+ * Work out if we need to set the RRSIG bit for
+ * this node. We set the RRSIG bit if either of
+ * the following conditions are met:
+ * 1) We have a SOA or DS then we need to set
+ * the RRSIG bit as both always will be signed.
+ * 2) We set the RRSIG bit if we don't have
+ * a NS record but do have other data.
+ */
+ if (rdataset.type == dns_rdatatype_soa ||
+ rdataset.type == dns_rdatatype_ds)
+ need_rrsig = ISC_TRUE;
+ else if (rdataset.type == dns_rdatatype_ns)
+ found_ns = ISC_TRUE;
+ else
found = ISC_TRUE;
}
dns_rdataset_disassociate(&rdataset);
}
- if (found) {
+ if ((found && !found_ns) || need_rrsig) {
if (dns_rdatatype_rrsig > max_type)
max_type = dns_rdatatype_rrsig;
set_bit(bm, dns_rdatatype_rrsig, 1);
diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c
index d557c43..95095d11 100644
--- a/contrib/bind9/lib/dns/opensslrsa_link.c
+++ b/contrib/bind9/lib/dns/opensslrsa_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -17,21 +17,23 @@
/*
* Principal Author: Brian Wellington
- * $Id: opensslrsa_link.c,v 1.20.50.3 2009/01/18 23:25:16 marka Exp $
+ * $Id: opensslrsa_link.c,v 1.20.50.8 2010/01/22 02:36:49 marka Exp $
*/
#ifdef OPENSSL
+#include <config.h>
+
#ifndef USE_EVP
+#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512)
+#define USE_EVP 0
+#else
#define USE_EVP 1
#endif
-#if USE_EVP
-#define USE_EVP_RSA 1
#endif
-#include <config.h>
-
#include <isc/entropy.h>
#include <isc/md5.h>
#include <isc/sha1.h>
+#include <isc/sha2.h>
#include <isc/mem.h>
#include <isc/string.h>
#include <isc/util.h>
@@ -112,23 +114,42 @@ static isc_result_t
opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
#if USE_EVP
EVP_MD_CTX *evp_md_ctx;
- const EVP_MD *type;
+ const EVP_MD *type = NULL;
#endif
UNUSED(key);
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
evp_md_ctx = EVP_MD_CTX_create();
if (evp_md_ctx == NULL)
return (ISC_R_NOMEMORY);
- if (dctx->key->key_alg == DST_ALG_RSAMD5)
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
type = EVP_md5(); /* MD5 + RSA */
- else
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
type = EVP_sha1(); /* SHA1 + RSA */
+ break;
+#ifdef HAVE_EVP_SHA256
+ case DST_ALG_RSASHA256:
+ type = EVP_sha256(); /* SHA256 + RSA */
+ break;
+#endif
+#ifdef HAVE_EVP_SHA512
+ case DST_ALG_RSASHA512:
+ type = EVP_sha512();
+ break;
+#endif
+ default:
+ INSIST(0);
+ }
if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
EVP_MD_CTX_destroy(evp_md_ctx);
@@ -136,22 +157,56 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
}
dctx->ctxdata.evp_md_ctx = evp_md_ctx;
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx;
-
- md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
- if (md5ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_md5_init(md5ctx);
- dctx->ctxdata.md5ctx = md5ctx;
- } else {
- isc_sha1_t *sha1ctx;
-
- sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
- if (sha1ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_sha1_init(sha1ctx);
- dctx->ctxdata.sha1ctx = sha1ctx;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx;
+
+ md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
+ if (md5ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_md5_init(md5ctx);
+ dctx->ctxdata.md5ctx = md5ctx;
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx;
+
+ sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
+ if (sha1ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_sha1_init(sha1ctx);
+ dctx->ctxdata.sha1ctx = sha1ctx;
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx;
+
+ sha256ctx = isc_mem_get(dctx->mctx,
+ sizeof(isc_sha256_t));
+ if (sha256ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_sha256_init(sha256ctx);
+ dctx->ctxdata.sha256ctx = sha256ctx;
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx;
+
+ sha512ctx = isc_mem_get(dctx->mctx,
+ sizeof(isc_sha512_t));
+ if (sha512ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_sha512_init(sha512ctx);
+ dctx->ctxdata.sha512ctx = sha512ctx;
+ }
+ break;
+ default:
+ INSIST(0);
}
#endif
@@ -166,7 +221,9 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
if (evp_md_ctx != NULL) {
@@ -174,22 +231,58 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
dctx->ctxdata.evp_md_ctx = NULL;
}
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
-
- if (md5ctx != NULL) {
- isc_md5_invalidate(md5ctx);
- isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
- dctx->ctxdata.md5ctx = NULL;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ if (md5ctx != NULL) {
+ isc_md5_invalidate(md5ctx);
+ isc_mem_put(dctx->mctx, md5ctx,
+ sizeof(isc_md5_t));
+ dctx->ctxdata.md5ctx = NULL;
+ }
}
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- if (sha1ctx != NULL) {
- isc_sha1_invalidate(sha1ctx);
- isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
- dctx->ctxdata.sha1ctx = NULL;
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ if (sha1ctx != NULL) {
+ isc_sha1_invalidate(sha1ctx);
+ isc_mem_put(dctx->mctx, sha1ctx,
+ sizeof(isc_sha1_t));
+ dctx->ctxdata.sha1ctx = NULL;
+ }
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ if (sha256ctx != NULL) {
+ isc_sha256_invalidate(sha256ctx);
+ isc_mem_put(dctx->mctx, sha256ctx,
+ sizeof(isc_sha256_t));
+ dctx->ctxdata.sha256ctx = NULL;
+ }
}
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ if (sha512ctx != NULL) {
+ isc_sha512_invalidate(sha512ctx);
+ isc_mem_put(dctx->mctx, sha512ctx,
+ sizeof(isc_sha512_t));
+ dctx->ctxdata.sha512ctx = NULL;
+ }
+ }
+ break;
+ default:
+ INSIST(0);
}
#endif
}
@@ -202,24 +295,67 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
return (ISC_R_FAILURE);
}
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- isc_md5_update(md5ctx, data->base, data->length);
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- isc_sha1_update(sha1ctx, data->base, data->length);
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ isc_md5_update(md5ctx, data->base, data->length);
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ isc_sha1_update(sha1ctx, data->base, data->length);
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ isc_sha256_update(sha256ctx, data->base, data->length);
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ isc_sha512_update(sha512ctx, data->base, data->length);
+ }
+ break;
+ default:
+ INSIST(0);
}
#endif
return (ISC_R_SUCCESS);
}
+#if ! USE_EVP && OPENSSL_VERSION_NUMBER < 0x00908000L
+/*
+ * Digest prefixes from RFC 5702.
+ */
+static unsigned char sha256_prefix[] =
+ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
+static unsigned char sha512_prefix[] =
+ { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
+#define PREFIXLEN sizeof(sha512_prefix)
+#else
+#define PREFIXLEN 0
+#endif
+
static isc_result_t
opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
dst_key_t *key = dctx->key;
@@ -230,20 +366,26 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
EVP_PKEY *pkey = key->keydata.pkey;
#else
RSA *rsa = key->keydata.rsa;
- /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
- unsigned char digest[ISC_SHA1_DIGESTLENGTH];
- int status;
- int type;
- unsigned int digestlen;
+ /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
+ unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH];
+ int status = 0;
+ int type = 0;
+ unsigned int digestlen = 0;
char *message;
unsigned long err;
const char* file;
int line;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ unsigned int prefixlen = 0;
+ const unsigned char *prefix = NULL;
+#endif
#endif
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
isc_buffer_availableregion(sig, &r);
@@ -258,19 +400,92 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
if (r.length < (unsigned int) RSA_size(rsa))
return (ISC_R_NOSPACE);
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- isc_md5_final(md5ctx, digest);
- type = NID_md5;
- digestlen = ISC_MD5_DIGESTLENGTH;
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- isc_sha1_final(sha1ctx, digest);
- type = NID_sha1;
- digestlen = ISC_SHA1_DIGESTLENGTH;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ isc_md5_final(md5ctx, digest);
+ type = NID_md5;
+ digestlen = ISC_MD5_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ isc_sha1_final(sha1ctx, digest);
+ type = NID_sha1;
+ digestlen = ISC_SHA1_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ isc_sha256_final(digest, sha256ctx);
+ digestlen = ISC_SHA256_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha256_prefix;
+ prefixlen = sizeof(sha256_prefix);
+#else
+ type = NID_sha256;
+#endif
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ isc_sha512_final(digest, sha512ctx);
+ digestlen = ISC_SHA512_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha512_prefix;
+ prefixlen = sizeof(sha512_prefix);
+#else
+ type = NID_sha512;
+#endif
+ }
+ break;
+ default:
+ INSIST(0);
}
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ INSIST(type != 0);
+ status = RSA_sign(type, digest, digestlen, r.base,
+ &siglen, rsa);
+ break;
+
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
+ INSIST(prefix != NULL);
+ INSIST(prefixlen != 0);
+ INSIST(prefixlen + digestlen <= sizeof(digest));
+
+ memmove(digest + prefixlen, digest, digestlen);
+ memcpy(digest, prefix, prefixlen);
+ status = RSA_private_encrypt(digestlen + prefixlen,
+ digest, r.base, rsa,
+ RSA_PKCS1_PADDING);
+ if (status < 0)
+ status = 0;
+ else
+ siglen = status;
+ break;
+
+ default:
+ INSIST(0);
+ }
+#else
+ INSIST(type != 0);
status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
+#endif
if (status == 0) {
err = ERR_peek_error_line(&file, &line);
if (err != 0U) {
@@ -293,37 +508,129 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
EVP_PKEY *pkey = key->keydata.pkey;
#else
- /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
- unsigned char digest[ISC_SHA1_DIGESTLENGTH];
- int type;
- unsigned int digestlen;
+ /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
+ unsigned char digest[ISC_SHA512_DIGESTLENGTH];
+ int type = 0;
+ unsigned int digestlen = 0;
RSA *rsa = key->keydata.rsa;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ unsigned int prefixlen = 0;
+ const unsigned char *prefix = NULL;
+#endif
#endif
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- isc_md5_final(md5ctx, digest);
- type = NID_md5;
- digestlen = ISC_MD5_DIGESTLENGTH;
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- isc_sha1_final(sha1ctx, digest);
- type = NID_sha1;
- digestlen = ISC_SHA1_DIGESTLENGTH;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ isc_md5_final(md5ctx, digest);
+ type = NID_md5;
+ digestlen = ISC_MD5_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ isc_sha1_final(sha1ctx, digest);
+ type = NID_sha1;
+ digestlen = ISC_SHA1_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ isc_sha256_final(digest, sha256ctx);
+ digestlen = ISC_SHA256_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha256_prefix;
+ prefixlen = sizeof(sha256_prefix);
+#else
+ type = NID_sha256;
+#endif
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ isc_sha512_final(digest, sha512ctx);
+ digestlen = ISC_SHA512_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha512_prefix;
+ prefixlen = sizeof(sha512_prefix);
+#else
+ type = NID_sha512;
+#endif
+ }
+ break;
+ default:
+ INSIST(0);
}
- if (sig->length < (unsigned int) RSA_size(rsa))
+ if (sig->length != (unsigned int) RSA_size(rsa))
return (DST_R_VERIFYFAILURE);
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ INSIST(type != 0);
+ status = RSA_verify(type, digest, digestlen, sig->base,
+ RSA_size(rsa), rsa);
+ break;
+
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
+ {
+ /*
+ * 1024 is big enough for all valid RSA bit sizes
+ * for use with DNSSEC.
+ */
+ unsigned char original[PREFIXLEN + 1024];
+
+ INSIST(prefix != NULL);
+ INSIST(prefixlen != 0U);
+
+ if (RSA_size(rsa) > (int)sizeof(original))
+ return (DST_R_VERIFYFAILURE);
+
+ status = RSA_public_decrypt(sig->length, sig->base,
+ original, rsa,
+ RSA_PKCS1_PADDING);
+ if (status <= 0)
+ return (DST_R_VERIFYFAILURE);
+ if (status != (int)(prefixlen + digestlen))
+ return (DST_R_VERIFYFAILURE);
+ if (memcmp(original, prefix, prefixlen))
+ return (DST_R_VERIFYFAILURE);
+ if (memcmp(original + prefixlen, digest, digestlen))
+ return (DST_R_VERIFYFAILURE);
+ status = 1;
+ }
+ break;
+
+ default:
+ INSIST(0);
+ }
+#else
+ INSIST(type != 0);
status = RSA_verify(type, digest, digestlen, sig->base,
- RSA_size(rsa), rsa);
+ RSA_size(rsa), rsa);
+#endif
#endif
if (status != 1)
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
@@ -552,19 +859,20 @@ opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
if (r.length < 1)
DST_RET(ISC_R_NOSPACE);
isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
+ isc_region_consume(&r, 1);
} else {
if (r.length < 3)
DST_RET(ISC_R_NOSPACE);
isc_buffer_putuint8(data, 0);
isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
+ isc_region_consume(&r, 3);
}
if (r.length < e_bytes + mod_bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_availableregion(data, &r);
+ DST_RET(ISC_R_NOSPACE);
BN_bn2bin(rsa->e, r.base);
- r.base += e_bytes;
+ isc_region_consume(&r, e_bytes);
BN_bn2bin(rsa->n, r.base);
isc_buffer_add(data, e_bytes + mod_bytes);
@@ -805,8 +1113,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
DST_RET(DST_R_NOENGINE);
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL) {
- ERR_print_errors_fp(stderr);
- DST_RET(ISC_R_FAILURE);
+ /* ERR_print_errors_fp(stderr); */
+ DST_RET(ISC_R_NOTFOUND);
}
key->engine = isc_mem_strdup(key->mctx, name);
if (key->engine == NULL)
@@ -924,7 +1232,7 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
DST_RET(DST_R_NOENGINE);
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL)
- DST_RET(ISC_R_NOMEMORY);
+ DST_RET(ISC_R_NOTFOUND);
key->engine = isc_mem_strdup(key->mctx, label);
if (key->engine == NULL)
DST_RET(ISC_R_NOMEMORY);
@@ -969,10 +1277,26 @@ static dst_func_t opensslrsa_functions = {
};
isc_result_t
-dst__opensslrsa_init(dst_func_t **funcp) {
+dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) {
REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &opensslrsa_functions;
+
+ if (*funcp == NULL) {
+ switch (algorithm) {
+ case DST_ALG_RSASHA256:
+#if defined(HAVE_EVP_SHA256) || !USE_EVP
+ *funcp = &opensslrsa_functions;
+#endif
+ break;
+ case DST_ALG_RSASHA512:
+#if defined(HAVE_EVP_SHA512) || !USE_EVP
+ *funcp = &opensslrsa_functions;
+#endif
+ break;
+ default:
+ *funcp = &opensslrsa_functions;
+ break;
+ }
+ }
return (ISC_R_SUCCESS);
}
diff --git a/contrib/bind9/lib/dns/rbt.c b/contrib/bind9/lib/dns/rbt.c
index ff8b3a3..62a9e2b 100644
--- a/contrib/bind9/lib/dns/rbt.c
+++ b/contrib/bind9/lib/dns/rbt.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt.c,v 1.142.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: rbt.c,v 1.142.50.3 2009/10/20 05:06:04 marka Exp $ */
/*! \file */
@@ -85,9 +85,9 @@ struct dns_rbt {
#define HASHVAL(node) ((node)->hashval)
#define COLOR(node) ((node)->color)
#define NAMELEN(node) ((node)->namelen)
+#define OLDNAMELEN(node) ((node)->oldnamelen)
#define OFFSETLEN(node) ((node)->offsetlen)
#define ATTRS(node) ((node)->attributes)
-#define PADBYTES(node) ((node)->padbytes)
#define IS_ROOT(node) ISC_TF((node)->is_root == 1)
#define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1)
@@ -100,13 +100,23 @@ struct dns_rbt {
#define LOCKNUM(node) ((node)->locknum)
/*%
- * The variable length stuff stored after the node.
+ * The variable length stuff stored after the node has the following
+ * structure.
+ *
+ * <name_data>{1..255}<oldoffsetlen>{1}<offsets>{1..128}
+ *
+ * <name_data> contains the name of the node when it was created.
+ * <oldoffsetlen> contains the length of <offsets> when the node was created.
+ * <offsets> contains the offets into name for each label when the node was
+ * created.
*/
+
#define NAME(node) ((unsigned char *)((node) + 1))
-#define OFFSETS(node) (NAME(node) + NAMELEN(node))
+#define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1)
+#define OLDOFFSETLEN(node) (OFFSETS(node)[-1])
#define NODE_SIZE(node) (sizeof(*node) + \
- NAMELEN(node) + OFFSETLEN(node) + PADBYTES(node))
+ OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1)
/*%
* Color management.
@@ -553,11 +563,6 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
NAMELEN(current) = prefix->length;
OFFSETLEN(current) = prefix->labels;
- memcpy(OFFSETS(current), prefix->offsets,
- prefix->labels);
- PADBYTES(current) +=
- (current_name.length - prefix->length) +
- (current_name.labels - prefix->labels);
/*
* Set up the new root of the next level.
@@ -1423,7 +1428,7 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
* Allocate space for the node structure, the name, and the offsets.
*/
node = (dns_rbtnode_t *)isc_mem_get(mctx, sizeof(*node) +
- region.length + labels);
+ region.length + labels + 1);
if (node == NULL)
return (ISC_R_NOMEMORY);
@@ -1460,10 +1465,12 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
* The offsets table could be made smaller by eliminating the
* first offset, which is always 0. This requires changes to
* lib/dns/name.c.
+ *
+ * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned
+ * as it uses OLDNAMELEN.
*/
- NAMELEN(node) = region.length;
- PADBYTES(node) = 0;
- OFFSETLEN(node) = labels;
+ OLDNAMELEN(node) = NAMELEN(node) = region.length;
+ OLDOFFSETLEN(node) = OFFSETLEN(node) = labels;
ATTRS(node) = name->attributes;
memcpy(NAME(node), region.base, region.length);
diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c
index d5b5b5c..df3a5f4 100644
--- a/contrib/bind9/lib/dns/rbtdb.c
+++ b/contrib/bind9/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.270.12.6.10.2 2009/12/31 21:44:36 each Exp $ */
+/* $Id: rbtdb.c,v 1.270.12.16.8.3 2010/02/26 00:24:39 marka Exp $ */
/*! \file */
@@ -258,21 +258,8 @@ typedef struct rdatasetheader {
dns_rbtnode_t *node;
isc_stdtime_t last_used;
- ISC_LINK(struct rdatasetheader) lru_link;
- /*%<
- * Used for LRU-based cache management. We should probably make
- * these cache-DB specific. We might also make it a pointer and
- * ensure only the top header has a valid link to save memory.
- * The linked-list is locked by the rbtdb->lrulock.
- */
+ ISC_LINK(struct rdatasetheader) link;
- /*
- * It's possible this should not be here anymore, but instead
- * referenced from the bucket's heap directly.
- */
-#if 0
- isc_heap_t *heap;
-#endif
unsigned int heap_index;
/*%<
* Used for TTL-based cache cleaning.
@@ -396,7 +383,7 @@ typedef struct rbtdb_version {
isc_uint8_t flags;
isc_uint16_t iterations;
isc_uint8_t salt_length;
- unsigned char salt[NSEC3_MAX_HASH_LENGTH];
+ unsigned char salt[DNS_NSEC3_SALTSIZE];
} rbtdb_version_t;
typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t;
@@ -534,6 +521,8 @@ static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
rdatasetheader_t *newheader);
static void prune_tree(isc_task_t *task, isc_event_t *event);
+static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
+static void rdataset_expire(dns_rdataset_t *rdataset);
static dns_rdatasetmethods_t rdataset_methods = {
rdataset_disassociate,
@@ -548,7 +537,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
rdataset_getclosest,
rdataset_getadditional,
rdataset_setadditional,
- rdataset_putadditional
+ rdataset_putadditional,
+ rdataset_settrust,
+ rdataset_expire
};
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
@@ -1227,7 +1218,7 @@ free_noqname(isc_mem_t *mctx, struct noqname **noqname) {
static inline void
init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h)
{
- ISC_LINK_INIT(h, lru_link);
+ ISC_LINK_INIT(h, link);
h->heap_index = 0;
#if TRACE_HEADER
@@ -1267,8 +1258,10 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
}
idx = rdataset->node->locknum;
- if (ISC_LINK_LINKED(rdataset, lru_link))
- ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link);
+ if (ISC_LINK_LINKED(rdataset, link)) {
+ INSIST(IS_CACHE(rbtdb));
+ ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, link);
+ }
if (rdataset->heap_index != 0)
isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index);
rdataset->heap_index = 0;
@@ -2075,8 +2068,6 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
continue;
#endif
- INSIST(nsec3param.salt_length <=
- sizeof(version->salt));
memcpy(version->salt, nsec3param.salt,
nsec3param.salt_length);
version->hash = nsec3param.hash;
@@ -2284,17 +2275,18 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
for (header = HEAD(resigned_list);
header != NULL;
header = HEAD(resigned_list)) {
- ISC_LIST_UNLINK(resigned_list, header, lru_link);
- if (rollback) {
- nodelock_t *lock;
- lock = &rbtdb->node_locks[header->node->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_write);
+ nodelock_t *lock;
+
+ ISC_LIST_UNLINK(resigned_list, header, link);
+
+ lock = &rbtdb->node_locks[header->node->locknum].lock;
+ NODE_LOCK(lock, isc_rwlocktype_write);
+ if (rollback)
resign_insert(rbtdb, header->node->locknum, header);
- NODE_UNLOCK(lock, isc_rwlocktype_write);
- }
decrement_reference(rbtdb, header->node, least_serial,
isc_rwlocktype_write, isc_rwlocktype_none,
ISC_FALSE);
+ NODE_UNLOCK(lock, isc_rwlocktype_write);
}
if (!EMPTY(cleanup_list)) {
@@ -3524,11 +3516,17 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
/*
* The node may be a zone cut itself. If it might be one,
* make sure we check for it later.
+ *
+ * DS records live above the zone cut in ordinary zone so
+ * we want to ignore any referral.
+ *
+ * Stub zones don't have anything "above" the delgation so
+ * we always return a referral.
*/
if (node->find_callback &&
- (node != search.rbtdb->origin_node ||
- IS_STUB(search.rbtdb)) &&
- !dns_rdatatype_atparent(type))
+ ((node != search.rbtdb->origin_node &&
+ !dns_rdatatype_atparent(type)) ||
+ IS_STUB(search.rbtdb)))
maybe_zonecut = ISC_TRUE;
}
@@ -3546,8 +3544,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* We now go looking for rdata...
*/
- NODE_LOCK(&(search.rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ lock = &search.rbtdb->node_locks[node->locknum].lock;
+ NODE_LOCK(lock, isc_rwlocktype_read);
found = NULL;
foundsig = NULL;
@@ -3625,8 +3623,10 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* we are using behave as if it isn't here.
*/
if (header->type == dns_rdatatype_nsec3 &&
- !matchparams(header, &search))
+ !matchparams(header, &search)) {
+ NODE_UNLOCK(lock, isc_rwlocktype_read);
goto partial_match;
+ }
/*
* If we found a type we were looking for,
* remember it.
@@ -3705,7 +3705,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* we really have a partial match.
*/
if (!wild) {
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
goto partial_match;
}
@@ -3722,7 +3721,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*
* Return the delegation.
*/
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
result = setup_delegation(&search, nodep, foundname,
rdataset, sigrdataset);
@@ -3744,7 +3742,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
goto node_exit;
}
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
result = find_closest_nsec(&search, nodep, foundname,
rdataset, sigrdataset,
@@ -3829,7 +3826,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
if (result == DNS_R_GLUE &&
(search.options & DNS_DBFIND_VALIDATEGLUE) != 0 &&
!valid_glue(&search, foundname, type, node)) {
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
result = setup_delegation(&search, nodep, foundname,
rdataset, sigrdataset);
@@ -3861,8 +3857,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
foundname->attributes |= DNS_NAMEATTR_WILDCARD;
node_exit:
- NODE_UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_UNLOCK(lock, isc_rwlocktype_read);
tree_exit:
RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
@@ -5408,8 +5403,10 @@ static isc_result_t
resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) {
isc_result_t result;
+ INSIST(!IS_CACHE(rbtdb));
INSIST(newheader->heap_index == 0);
- INSIST(!ISC_LINK_LINKED(newheader, lru_link));
+ INSIST(!ISC_LINK_LINKED(newheader, link));
+
result = isc_heap_insert(rbtdb->heaps[idx], newheader);
return (result);
}
@@ -5735,7 +5732,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) {
ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
- newheader, lru_link);
+ newheader, link);
/*
* XXXMLG We don't check the return value
* here. If it fails, we will not do TTL
@@ -5794,7 +5791,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) {
ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
- newheader, lru_link);
+ newheader, link);
isc_heap_insert(rbtdb->heaps[idx], newheader);
} else if (RESIGN(newheader)) {
resign_insert(rbtdb, idx, newheader);
@@ -6519,11 +6516,17 @@ static void
delete_callback(void *data, void *arg) {
dns_rbtdb_t *rbtdb = arg;
rdatasetheader_t *current, *next;
+ unsigned int locknum;
- for (current = data; current != NULL; current = next) {
+ current = data;
+ locknum = current->node->locknum;
+ NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
+ while (current != NULL) {
next = current->next;
free_rdataset(rbtdb, rbtdb->common.mctx, current);
+ current = next;
}
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
}
static isc_boolean_t
@@ -6642,8 +6645,8 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
if (rbtversion->havensec3) {
if (hash != NULL)
*hash = rbtversion->hash;
- if (salt != NULL && salt_length != 0) {
- REQUIRE(*salt_length > rbtversion->salt_length);
+ if (salt != NULL && salt_length != NULL) {
+ REQUIRE(*salt_length >= rbtversion->salt_length);
memcpy(salt, rbtversion->salt, rbtversion->salt_length);
}
if (salt_length != NULL)
@@ -6707,27 +6710,35 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
rdatasetheader_t *header = NULL, *this;
unsigned int i;
isc_result_t result = ISC_R_NOTFOUND;
+ unsigned int locknum;
REQUIRE(VALID_RBTDB(rbtdb));
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
for (i = 0; i < rbtdb->node_lock_count; i++) {
+ NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read);
this = isc_heap_element(rbtdb->heaps[i], 1);
- if (this == NULL)
+ if (this == NULL) {
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock,
+ isc_rwlocktype_read);
continue;
+ }
if (header == NULL)
header = this;
- else if (isc_serial_lt(this->resign, header->resign))
+ else if (isc_serial_lt(this->resign, header->resign)) {
+ locknum = header->node->locknum;
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
+ isc_rwlocktype_read);
header = this;
+ } else
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock,
+ isc_rwlocktype_read);
}
if (header == NULL)
goto unlock;
- NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_read);
-
bind_rdataset(rbtdb, header->node, header, 0, rdataset);
if (foundname != NULL)
@@ -6761,7 +6772,7 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
header = rdataset->private3;
header--;
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
+ RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
NODE_LOCK(&rbtdb->node_locks[node->locknum].lock,
isc_rwlocktype_write);
/*
@@ -6771,11 +6782,11 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
new_reference(rbtdb, node);
isc_heap_delete(rbtdb->heaps[node->locknum], header->heap_index);
header->heap_index = 0;
- ISC_LIST_APPEND(rbtversion->resigned_list, header, lru_link);
+ ISC_LIST_APPEND(rbtversion->resigned_list, header, link);
NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
isc_rwlocktype_write);
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
+ RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
}
static dns_stats_t *
@@ -7400,6 +7411,34 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
return (ISC_R_SUCCESS);
}
+static void
+rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
+ dns_rbtdb_t *rbtdb = rdataset->private1;
+ dns_rbtnode_t *rbtnode = rdataset->private2;
+ rdatasetheader_t *header = rdataset->private3;
+
+ header--;
+ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+ header->trust = rdataset->trust = trust;
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+}
+
+static void
+rdataset_expire(dns_rdataset_t *rdataset) {
+ dns_rbtdb_t *rbtdb = rdataset->private1;
+ dns_rbtnode_t *rbtnode = rdataset->private2;
+ rdatasetheader_t *header = rdataset->private3;
+
+ header--;
+ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+ expire_header(rbtdb, header, ISC_FALSE);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+}
+
/*
* Rdataset Iterator Methods
*/
@@ -8497,13 +8536,11 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
INSIST(IS_CACHE(rbtdb));
/* To be checked: can we really assume this? XXXMLG */
- INSIST(ISC_LINK_LINKED(header, lru_link));
+ INSIST(ISC_LINK_LINKED(header, link));
- ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum],
- header, lru_link);
+ ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], header, link);
header->last_used = now;
- ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum],
- header, lru_link);
+ ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link);
}
/*%
@@ -8539,7 +8576,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
header != NULL && purgecount > 0;
header = header_prev) {
- header_prev = ISC_LIST_PREV(header, lru_link);
+ header_prev = ISC_LIST_PREV(header, link);
/*
* Unlink the entry at this point to avoid checking it
* again even if it's currently used someone else and
@@ -8548,7 +8585,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
* TTL was reset to 0.
*/
ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
- lru_link);
+ link);
expire_header(rbtdb, header, tree_locked);
purgecount--;
}
diff --git a/contrib/bind9/lib/dns/rcode.c b/contrib/bind9/lib/dns/rcode.c
index 58ade85..9feaeb0 100644
--- a/contrib/bind9/lib/dns/rcode.c
+++ b/contrib/bind9/lib/dns/rcode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rcode.c,v 1.8 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: rcode.c,v 1.8.48.2 2010/01/15 23:47:33 tbox Exp $ */
#include <config.h>
#include <ctype.h>
@@ -100,6 +100,8 @@
{ DNS_KEYALG_ECC, "ECC", 0 }, \
{ DNS_KEYALG_RSASHA1, "RSASHA1", 0 }, \
{ DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \
+ { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \
+ { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \
{ DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \
{ DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \
{ DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \
diff --git a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
index bc2b4e8..6a58bc9 100644
--- a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
+++ b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ipseckey_45.c,v 1.4.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: ipseckey_45.c,v 1.4.332.3 2009/09/18 21:55:48 jinmei Exp $ */
#ifndef RDATA_GENERIC_IPSECKEY_45_C
#define RDATA_GENERIC_IPSECKEY_45_C
@@ -243,6 +243,7 @@ fromwire_ipseckey(ARGS_FROMWIRE) {
isc_buffer_forward(source, 3);
RETERR(dns_name_fromwire(&name, source, dctx, options, target));
isc_buffer_activeregion(source, &region);
+ isc_buffer_forward(source, region.length);
return(mem_tobuffer(target, region.base, region.length));
default:
diff --git a/contrib/bind9/lib/dns/rdatalist.c b/contrib/bind9/lib/dns/rdatalist.c
index d6f11ae..d072619 100644
--- a/contrib/bind9/lib/dns/rdatalist.c
+++ b/contrib/bind9/lib/dns/rdatalist.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdatalist.c,v 1.36 2008/09/24 02:46:22 marka Exp $ */
+/* $Id: rdatalist.c,v 1.36.336.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -46,6 +46,8 @@ static dns_rdatasetmethods_t methods = {
isc__rdatalist_getclosest,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/rdataset.c b/contrib/bind9/lib/dns/rdataset.c
index 6088a06..946ec9a 100644
--- a/contrib/bind9/lib/dns/rdataset.c
+++ b/contrib/bind9/lib/dns/rdataset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.c,v 1.82.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: rdataset.c,v 1.82.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -182,6 +182,8 @@ static dns_rdatasetmethods_t question_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -732,3 +734,22 @@ dns_rdataset_putadditional(dns_acache_t *acache,
return (ISC_R_FAILURE);
}
+void
+dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
+ REQUIRE(DNS_RDATASET_VALID(rdataset));
+ REQUIRE(rdataset->methods != NULL);
+
+ if (rdataset->methods->settrust != NULL)
+ (rdataset->methods->settrust)(rdataset, trust);
+ else
+ rdataset->trust = trust;
+}
+
+void
+dns_rdataset_expire(dns_rdataset_t *rdataset) {
+ REQUIRE(DNS_RDATASET_VALID(rdataset));
+ REQUIRE(rdataset->methods != NULL);
+
+ if (rdataset->methods->expire != NULL)
+ (rdataset->methods->expire)(rdataset);
+}
diff --git a/contrib/bind9/lib/dns/rdataslab.c b/contrib/bind9/lib/dns/rdataslab.c
index b22868d..4eadff9 100644
--- a/contrib/bind9/lib/dns/rdataslab.c
+++ b/contrib/bind9/lib/dns/rdataslab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataslab.c,v 1.48.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: rdataslab.c,v 1.48.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -436,6 +436,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c
index 1b4f407..244718f 100644
--- a/contrib/bind9/lib/dns/resolver.c
+++ b/contrib/bind9/lib/dns/resolver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.384.14.14.8.2 2010/01/07 17:17:19 each Exp $ */
+/* $Id: resolver.c,v 1.384.14.20.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -334,6 +334,18 @@ typedef struct alternate {
ISC_LINK(struct alternate) link;
} alternate_t;
+typedef struct dns_badcache dns_badcache_t;
+struct dns_badcache {
+ dns_badcache_t * next;
+ dns_rdatatype_t type;
+ isc_time_t expire;
+ unsigned int hashval;
+ dns_name_t name;
+};
+#define DNS_BADCACHE_SIZE 1021
+#define DNS_BADCACHE_TTL(fctx) \
+ (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30)
+
struct dns_resolver {
/* Unlocked. */
unsigned int magic;
@@ -380,6 +392,13 @@ struct dns_resolver {
isc_boolean_t priming;
unsigned int spillat; /* clients-per-query */
unsigned int nextdisp;
+
+ /* Bad cache. */
+ dns_badcache_t ** badcache;
+ unsigned int badcount;
+ unsigned int badhash;
+ unsigned int badsweep;
+
/* Locked by primelock. */
dns_fetch_t * primefetch;
/* Locked by nlock. */
@@ -410,7 +429,8 @@ static void empty_bucket(dns_resolver_t *res);
static isc_result_t resquery_send(resquery_t *query);
static void resquery_response(isc_task_t *task, isc_event_t *event);
static void resquery_connected(isc_task_t *task, isc_event_t *event);
-static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying);
+static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
+ isc_boolean_t badcache);
static isc_boolean_t fctx_destroy(fetchctx_t *fctx);
static isc_result_t ncache_adderesult(dns_message_t *message,
dns_db_t *cache, dns_dbnode_t *node,
@@ -1169,7 +1189,7 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
else
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
}
}
@@ -2071,7 +2091,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
else
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
}
}
@@ -2133,7 +2153,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
dns_adb_destroyfind(&find);
if (want_try)
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
else if (want_done)
fctx_done(fctx, ISC_R_FAILURE, __LINE__);
else if (bucket_empty)
@@ -2534,8 +2554,18 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
}
}
+static isc_boolean_t
+isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) {
+ int order;
+ unsigned int nlabels;
+ dns_namereln_t namereln;
+
+ namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
+ return (ISC_TF(namereln == dns_namereln_subdomain));
+}
+
static isc_result_t
-fctx_getaddresses(fetchctx_t *fctx) {
+fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
dns_resolver_t *res;
@@ -2579,23 +2609,40 @@ fctx_getaddresses(fetchctx_t *fctx) {
dns_name_t *name = &fctx->name;
dns_name_t suffix;
unsigned int labels;
+ dns_fixedname_t fixed;
+ dns_name_t *domain;
/*
* DS records are found in the parent server.
* Strip label to get the correct forwarder (if any).
*/
- if (fctx->type == dns_rdatatype_ds &&
+ if (dns_rdatatype_atparent(fctx->type) &&
dns_name_countlabels(name) > 1) {
dns_name_init(&suffix, NULL);
labels = dns_name_countlabels(name);
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
name = &suffix;
}
- result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
- &forwarders);
+
+ dns_fixedname_init(&fixed);
+ domain = dns_fixedname_name(&fixed);
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ domain, &forwarders);
if (result == ISC_R_SUCCESS) {
sa = ISC_LIST_HEAD(forwarders->addrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
+ if (fctx->fwdpolicy == dns_fwdpolicy_only &&
+ isstrictsubdomain(domain, &fctx->domain)) {
+ isc_mem_t *mctx;
+
+ mctx = res->buckets[fctx->bucketnum].mctx;
+ dns_name_free(&fctx->domain, mctx);
+ dns_name_init(&fctx->domain, NULL);
+ result = dns_name_dup(domain, mctx,
+ &fctx->domain);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
}
}
@@ -2737,12 +2784,24 @@ fctx_getaddresses(fetchctx_t *fctx) {
*/
result = DNS_R_WAIT;
} else {
+ isc_time_t expire;
+ isc_interval_t i;
/*
* We've lost completely. We don't know any
* addresses, and the ADB has told us it can't get
* them.
*/
FCTXTRACE("no addresses");
+ isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
+ result = isc_time_nowplusinterval(&expire, &i);
+ if (badcache &&
+ (fctx->type == dns_rdatatype_dnskey ||
+ fctx->type == dns_rdatatype_dlv ||
+ fctx->type == dns_rdatatype_ds) &&
+ result == ISC_R_SUCCESS)
+ dns_resolver_addbadcache(fctx->res,
+ &fctx->name,
+ fctx->type, &expire);
result = ISC_R_FAILURE;
}
} else {
@@ -2965,7 +3024,7 @@ fctx_nextaddress(fetchctx_t *fctx) {
}
static void
-fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) {
+fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
isc_result_t result;
dns_adbaddrinfo_t *addrinfo;
@@ -2983,7 +3042,7 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) {
fctx_cleanupaltfinds(fctx);
fctx_cleanupforwaddrs(fctx);
fctx_cleanupaltaddrs(fctx);
- result = fctx_getaddresses(fctx);
+ result = fctx_getaddresses(fctx, badcache);
if (result == DNS_R_WAIT) {
/*
* Sleep waiting for addresses.
@@ -3148,7 +3207,7 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) {
/*
* Keep trying.
*/
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
}
isc_event_free(&event);
@@ -3318,7 +3377,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
else
- fctx_try(fctx, ISC_FALSE);
+ fctx_try(fctx, ISC_FALSE, ISC_FALSE);
} else if (bucket_empty)
empty_bucket(res);
}
@@ -3477,21 +3536,22 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
if (domain == NULL) {
dns_forwarders_t *forwarders = NULL;
unsigned int labels;
+ dns_name_t *fwdname = name;
/*
* DS records are found in the parent server.
* Strip label to get the correct forwarder (if any).
*/
- if (fctx->type == dns_rdatatype_ds &&
+ if (dns_rdatatype_atparent(fctx->type) &&
dns_name_countlabels(name) > 1) {
dns_name_init(&suffix, NULL);
labels = dns_name_countlabels(name);
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
- name = &suffix;
+ fwdname = &suffix;
}
dns_fixedname_init(&fixed);
domain = dns_fixedname_name(&fixed);
- result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname,
domain, &forwarders);
if (result == ISC_R_SUCCESS)
fctx->fwdpolicy = forwarders->fwdpolicy;
@@ -3502,7 +3562,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
* nameservers, and we're not in forward-only mode,
* so find the best nameservers to use.
*/
- if (dns_rdatatype_atparent(type))
+ if (dns_rdatatype_atparent(fctx->type))
findoptions |= DNS_DBFIND_NOEXACT;
result = dns_view_findzonecut(res->view, name, domain,
0, findoptions, ISC_TRUE,
@@ -3895,6 +3955,8 @@ validated(isc_task_t *task, isc_event_t *event) {
LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ isc_stdtime_get(&now);
+
/*
* If chaining, we need to make sure that the right result code is
* returned, and that the rdatasets are bound.
@@ -3941,35 +4003,80 @@ validated(isc_task_t *task, isc_event_t *event) {
inc_stats(fctx->res, dns_resstatscounter_valfail);
fctx->valfail++;
fctx->vresult = vevent->result;
- result = ISC_R_NOTFOUND;
- if (vevent->rdataset != NULL)
- result = dns_db_findnode(fctx->cache, vevent->name,
- ISC_TRUE, &node);
- if (result == ISC_R_SUCCESS)
- (void)dns_db_deleterdataset(fctx->cache, node, NULL,
- vevent->type, 0);
- if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL)
- (void)dns_db_deleterdataset(fctx->cache, node, NULL,
- dns_rdatatype_rrsig,
- vevent->type);
- if (result == ISC_R_SUCCESS)
- dns_db_detachnode(fctx->cache, &node);
- result = vevent->result;
+ if (fctx->vresult != DNS_R_BROKENCHAIN) {
+ result = ISC_R_NOTFOUND;
+ if (vevent->rdataset != NULL)
+ result = dns_db_findnode(fctx->cache,
+ vevent->name,
+ ISC_TRUE, &node);
+ if (result == ISC_R_SUCCESS)
+ (void)dns_db_deleterdataset(fctx->cache, node,
+ NULL,
+ vevent->type, 0);
+ if (result == ISC_R_SUCCESS &&
+ vevent->sigrdataset != NULL)
+ (void)dns_db_deleterdataset(fctx->cache, node,
+ NULL,
+ dns_rdatatype_rrsig,
+ vevent->type);
+ if (result == ISC_R_SUCCESS)
+ dns_db_detachnode(fctx->cache, &node);
+ }
+ if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) {
+ /*
+ * Cache the data as pending for later validation.
+ */
+ result = ISC_R_NOTFOUND;
+ if (vevent->rdataset != NULL)
+ result = dns_db_findnode(fctx->cache,
+ vevent->name,
+ ISC_TRUE, &node);
+ if (result == ISC_R_SUCCESS) {
+ (void)dns_db_addrdataset(fctx->cache, node,
+ NULL, now,
+ vevent->rdataset, 0,
+ NULL);
+ }
+ if (result == ISC_R_SUCCESS &&
+ vevent->sigrdataset != NULL)
+ (void)dns_db_addrdataset(fctx->cache, node,
+ NULL, now,
+ vevent->sigrdataset,
+ 0, NULL);
+ if (result == ISC_R_SUCCESS)
+ dns_db_detachnode(fctx->cache, &node);
+ }
+ result = fctx->vresult;
add_bad(fctx, addrinfo, result, badns_validation);
isc_event_free(&event);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
INSIST(fctx->validator == NULL);
fctx->validator = ISC_LIST_HEAD(fctx->validators);
- if (fctx->validator != NULL) {
+ if (fctx->validator != NULL)
dns_validator_send(fctx->validator);
- } else if (sentresponse)
+ else if (sentresponse)
fctx_done(fctx, result, __LINE__); /* Locks bucket. */
- else
- fctx_try(fctx, ISC_TRUE); /* Locks bucket. */
+ else if (result == DNS_R_BROKENCHAIN) {
+ isc_result_t tresult;
+ isc_time_t expire;
+ isc_interval_t i;
+
+ isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
+ tresult = isc_time_nowplusinterval(&expire, &i);
+ if (negative &&
+ (fctx->type == dns_rdatatype_dnskey ||
+ fctx->type == dns_rdatatype_dlv ||
+ fctx->type == dns_rdatatype_ds) &&
+ tresult == ISC_R_SUCCESS)
+ dns_resolver_addbadcache(fctx->res,
+ &fctx->name,
+ fctx->type, &expire);
+ fctx_done(fctx, result, __LINE__); /* Locks bucket. */
+ } else
+ fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */
return;
}
- isc_stdtime_get(&now);
if (negative) {
dns_rdatatype_t covers;
@@ -5762,7 +5869,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
/*
* Try again.
*/
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
} else {
unsigned int n;
dns_rdataset_t *nsrdataset = NULL;
@@ -6601,7 +6708,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/*
* Try again.
*/
- fctx_try(fctx, !get_nameservers);
+ fctx_try(fctx, !get_nameservers, ISC_FALSE);
} else if (resend) {
/*
* Resend (probably with changed options).
@@ -6663,6 +6770,27 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/***
*** Resolver Methods
***/
+static void
+destroy_badcache(dns_resolver_t *res) {
+ dns_badcache_t *bad, *next;
+ unsigned int i;
+
+ if (res->badcache != NULL) {
+ for (i = 0; i < res->badhash; i++)
+ for (bad = res->badcache[i]; bad != NULL;
+ bad = next) {
+ next = bad->next;
+ isc_mem_put(res->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ res->badcount--;
+ }
+ isc_mem_put(res->mctx, res->badcache,
+ sizeof(*res->badcache) * res->badhash);
+ res->badcache = NULL;
+ res->badhash = 0;
+ INSIST(res->badcount == 0);
+ }
+}
static void
destroy(dns_resolver_t *res) {
@@ -6700,6 +6828,7 @@ destroy(dns_resolver_t *res) {
isc_mem_put(res->mctx, a, sizeof(*a));
}
dns_resolver_reset_algorithms(res);
+ destroy_badcache(res);
dns_resolver_resetmustbesecure(res);
#if USE_ALGLOCK
isc_rwlock_destroy(&res->alglock);
@@ -6823,6 +6952,10 @@ dns_resolver_create(dns_view_t *view,
ISC_LIST_INIT(res->alternates);
res->udpsize = RECV_BUFFER_SIZE;
res->algorithms = NULL;
+ res->badcache = NULL;
+ res->badcount = 0;
+ res->badhash = 0;
+ res->badsweep = 0;
res->mustbesecure = NULL;
res->spillatmin = res->spillat = 10;
res->spillatmax = 100;
@@ -7664,6 +7797,256 @@ dns_resolver_getudpsize(dns_resolver_t *resolver) {
return (resolver->udpsize);
}
+void
+dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) {
+ unsigned int i;
+ dns_badcache_t *bad, *prev, *next;
+
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ LOCK(&resolver->lock);
+ if (resolver->badcache == NULL)
+ goto unlock;
+
+ if (name != NULL) {
+ isc_time_t now;
+ isc_result_t result;
+ result = isc_time_now(&now);
+ if (result != ISC_R_SUCCESS)
+ isc_time_settoepoch(&now);
+ i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ int n;
+ next = bad->next;
+ n = isc_time_compare(&bad->expire, &now);
+ if (n < 0 || dns_name_equal(name, &bad->name)) {
+ if (prev == NULL)
+ resolver->badcache[i] = bad->next;
+ else
+ prev->next = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ } else
+ prev = bad;
+ }
+ } else
+ destroy_badcache(resolver);
+
+ unlock:
+ UNLOCK(&resolver->lock);
+
+}
+
+static void
+resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
+ unsigned int newsize;
+ dns_badcache_t **new, *bad, *next;
+ unsigned int i;
+
+ if (grow)
+ newsize = resolver->badhash * 2 + 1;
+ else
+ newsize = (resolver->badhash - 1) / 2;
+
+ new = isc_mem_get(resolver->mctx,
+ sizeof(*resolver->badcache) * newsize);
+ if (new == NULL)
+ return;
+ memset(new, 0, sizeof(*resolver->badcache) * newsize);
+ for (i = 0; i < resolver->badhash; i++) {
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ if (isc_time_compare(&bad->expire, now) < 0) {
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ } else {
+ bad->next = new[bad->hashval % newsize];
+ new[bad->hashval % newsize] = bad;
+ }
+ }
+ }
+ isc_mem_put(resolver->mctx, resolver->badcache,
+ sizeof(*resolver->badcache) * resolver->badhash);
+ resolver->badhash = newsize;
+ resolver->badcache = new;
+}
+
+void
+dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *expire)
+{
+ isc_time_t now;
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned int i, hashval;
+ dns_badcache_t *bad, *prev, *next;
+
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ LOCK(&resolver->lock);
+ if (resolver->badcache == NULL) {
+ resolver->badcache = isc_mem_get(resolver->mctx,
+ sizeof(*resolver->badcache) *
+ DNS_BADCACHE_SIZE);
+ if (resolver->badcache == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ resolver->badhash = DNS_BADCACHE_SIZE;
+ memset(resolver->badcache, 0, sizeof(*resolver->badcache) *
+ resolver->badhash);
+ }
+
+ result = isc_time_now(&now);
+ if (result != ISC_R_SUCCESS)
+ isc_time_settoepoch(&now);
+ hashval = dns_name_hash(name, ISC_FALSE);
+ i = hashval % resolver->badhash;
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ if (bad->type == type && dns_name_equal(name, &bad->name))
+ break;
+ if (isc_time_compare(&bad->expire, &now) < 0) {
+ if (prev == NULL)
+ resolver->badcache[i] = bad->next;
+ else
+ prev->next = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ } else
+ prev = bad;
+ }
+ if (bad == NULL) {
+ isc_buffer_t buffer;
+ bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length);
+ if (bad == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ bad->type = type;
+ bad->hashval = hashval;
+ isc_buffer_init(&buffer, bad + 1, name->length);
+ dns_name_init(&bad->name, NULL);
+ dns_name_copy(name, &bad->name, &buffer);
+ bad->next = resolver->badcache[i];
+ resolver->badcache[i] = bad;
+ resolver->badcount++;
+ if (resolver->badcount > resolver->badhash * 8)
+ resizehash(resolver, &now, ISC_TRUE);
+ if (resolver->badcount < resolver->badhash * 2 &&
+ resolver->badhash > DNS_BADCACHE_SIZE)
+ resizehash(resolver, &now, ISC_FALSE);
+ }
+ bad->expire = *expire;
+ cleanup:
+ UNLOCK(&resolver->lock);
+}
+
+isc_boolean_t
+dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *now)
+{
+ dns_badcache_t *bad, *prev, *next;
+ isc_boolean_t answer = ISC_FALSE;
+ unsigned int i;
+
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ LOCK(&resolver->lock);
+ if (resolver->badcache == NULL)
+ goto unlock;
+
+ i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ /*
+ * Search the hash list. Clean out expired records as we go.
+ */
+ if (isc_time_compare(&bad->expire, now) < 0) {
+ if (prev != NULL)
+ prev->next = bad->next;
+ else
+ resolver->badcache[i] = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ continue;
+ }
+ if (bad->type == type && dns_name_equal(name, &bad->name)) {
+ answer = ISC_TRUE;
+ break;
+ }
+ prev = bad;
+ }
+
+ /*
+ * Slow sweep to clean out stale records.
+ */
+ i = resolver->badsweep++ % resolver->badhash;
+ bad = resolver->badcache[i];
+ if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) {
+ resolver->badcache[i] = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ }
+
+ unlock:
+ UNLOCK(&resolver->lock);
+ return (answer);
+}
+
+void
+dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
+ dns_badcache_t *bad, *next, *prev;
+ isc_time_t now;
+ unsigned int i;
+ isc_uint64_t t;
+
+ LOCK(&resolver->lock);
+ fprintf(fp, ";\n; Bad cache\n;\n");
+
+ if (resolver->badcache == NULL)
+ goto unlock;
+
+ TIME_NOW(&now);
+ for (i = 0; i < resolver->badhash; i++) {
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ if (isc_time_compare(&bad->expire, &now) < 0) {
+ if (prev != NULL)
+ prev->next = bad->next;
+ else
+ resolver->badcache[i] = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ continue;
+ }
+ prev = bad;
+ dns_name_format(&bad->name, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(bad->type, typebuf,
+ sizeof(typebuf));
+ t = isc_time_microdiff(&bad->expire, &now);
+ t /= 1000;
+ fprintf(fp, "; %s/%s [ttl "
+ "%" ISC_PLATFORM_QUADFORMAT "u]\n",
+ namebuf, typebuf, t);
+ }
+ }
+
+ unlock:
+ UNLOCK(&resolver->lock);
+}
+
static void
free_algorithm(void *node, void *arg) {
unsigned char *algorithms = node;
diff --git a/contrib/bind9/lib/dns/result.c b/contrib/bind9/lib/dns/result.c
index 54c70e0..e336197 100644
--- a/contrib/bind9/lib/dns/result.c
+++ b/contrib/bind9/lib/dns/result.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.c,v 1.125 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: result.c,v 1.125.122.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -157,6 +157,9 @@ static const char *text[DNS_R_NRESULTS] = {
"MX is an address", /*%< 102 DNS_R_MXISADDRESS */
"duplicate query", /*%< 103 DNS_R_DUPLICATE */
"invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */
+
+ "not master", /*%< 105 DNS_R_NOTMASTER */
+ "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
diff --git a/contrib/bind9/lib/dns/sdb.c b/contrib/bind9/lib/dns/sdb.c
index 03fca9e..e0c8786 100644
--- a/contrib/bind9/lib/dns/sdb.c
+++ b/contrib/bind9/lib/dns/sdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.66.48.2 2009/04/21 23:47:18 tbox Exp $ */
+/* $Id: sdb.c,v 1.66.48.3.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -1387,6 +1387,8 @@ static dns_rdatasetmethods_t methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -1458,9 +1460,11 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
- while (sdbiter->current != NULL)
+ while (sdbiter->current != NULL) {
if (dns_name_equal(sdbiter->current->name, name))
return (ISC_R_SUCCESS);
+ sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
+ }
return (ISC_R_NOTFOUND);
}
diff --git a/contrib/bind9/lib/dns/sdlz.c b/contrib/bind9/lib/dns/sdlz.c
index 89cd0ee..caf71b5 100644
--- a/contrib/bind9/lib/dns/sdlz.c
+++ b/contrib/bind9/lib/dns/sdlz.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.c,v 1.18.50.2 2009/04/21 23:47:18 tbox Exp $ */
+/* $Id: sdlz.c,v 1.18.50.3.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -1117,9 +1117,11 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
- while (sdlziter->current != NULL)
+ while (sdlziter->current != NULL) {
if (dns_name_equal(sdlziter->current->name, name))
return (ISC_R_SUCCESS);
+ sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
+ }
return (ISC_R_NOTFOUND);
}
@@ -1209,6 +1211,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/spnego.c b/contrib/bind9/lib/dns/spnego.c
index 0ae6ea2..6c94e51 100644
--- a/contrib/bind9/lib/dns/spnego.c
+++ b/contrib/bind9/lib/dns/spnego.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: spnego.c,v 1.8.118.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: spnego.c,v 1.8.118.4 2009/07/21 07:27:13 marka Exp $ */
/*! \file
* \brief
@@ -265,8 +265,7 @@ decode_oid(const unsigned char *p, size_t len,
oid * k, size_t * size);
static int
-decode_enumerated(const unsigned char *p, size_t len,
- unsigned *num, size_t *size);
+decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size);
static int
decode_octet_string(const unsigned char *, size_t, octet_string *, size_t *);
@@ -291,8 +290,7 @@ der_put_length_and_tag(unsigned char *, size_t, size_t,
Der_class, Der_type, int, size_t *);
static int
-encode_enumerated(unsigned char *p, size_t len,
- const unsigned *data, size_t *);
+encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *);
static int
encode_octet_string(unsigned char *p, size_t len,
@@ -622,7 +620,7 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status,
}
for (i = 0; !found && i < init_token.mechTypes.len; ++i) {
- char mechbuf[17];
+ unsigned char mechbuf[17];
size_t mech_len;
ret = der_put_oid(mechbuf + sizeof(mechbuf) - 1,
@@ -956,8 +954,7 @@ der_match_tag_and_length(const unsigned char *p, size_t len,
}
static int
-decode_enumerated(const unsigned char *p, size_t len,
- unsigned *num, size_t *size)
+decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
@@ -1269,10 +1266,9 @@ der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val,
}
static int
-encode_enumerated(unsigned char *p, size_t len, const unsigned *data,
- size_t *size)
+encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *size)
{
- unsigned num = *data;
+ unsigned num = *(const unsigned *)data;
size_t ret = 0;
size_t l;
int e;
diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c
index ce49daf..0ccdc41 100644
--- a/contrib/bind9/lib/dns/validator.c
+++ b/contrib/bind9/lib/dns/validator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.164.12.9.8.2 2009/12/31 20:29:21 each Exp $ */
+/* $Id: validator.c,v 1.164.12.11.8.2 2010/02/25 10:57:12 tbox Exp $ */
#include <config.h>
@@ -177,9 +177,16 @@ static inline void
markanswer(dns_validator_t *val) {
validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
if (val->event->rdataset != NULL)
- val->event->rdataset->trust = dns_trust_answer;
+ dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
if (val->event->sigrdataset != NULL)
- val->event->sigrdataset->trust = dns_trust_answer;
+ dns_rdataset_settrust(val->event->sigrdataset,
+ dns_trust_answer);
+}
+
+static inline void
+marksecure(dns_validatorevent_t *event) {
+ dns_rdataset_settrust(event->rdataset, dns_trust_secure);
+ dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
}
static void
@@ -425,7 +432,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
if (eresult == ISC_R_CANCELED)
validator_done(val, eresult);
else
- validator_done(val, DNS_R_NOVALIDKEY);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -495,7 +502,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
if (eresult == ISC_R_CANCELED)
validator_done(val, eresult);
else
- validator_done(val, DNS_R_NOVALIDDS);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -635,10 +642,16 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
+ if (eresult != DNS_R_BROKENCHAIN) {
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_expire(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_expire(&val->fsigrdataset);
+ }
validator_log(val, ISC_LOG_DEBUG(3),
"keyvalidated: got %s",
isc_result_totext(eresult));
- validator_done(val, eresult);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -685,10 +698,16 @@ dsvalidated(isc_task_t *task, isc_event_t *event) {
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
+ if (eresult != DNS_R_BROKENCHAIN) {
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_expire(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_expire(&val->fsigrdataset);
+ }
validator_log(val, ISC_LOG_DEBUG(3),
"dsvalidated: got %s",
isc_result_totext(eresult));
- validator_done(val, eresult);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -1199,6 +1218,8 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
validator_log(val, ISC_LOG_DEBUG(3),
"authvalidated: got %s",
isc_result_totext(result));
+ if (result == DNS_R_BROKENCHAIN)
+ val->authfail++;
if (result == ISC_R_CANCELED)
validator_done(val, result);
else {
@@ -1271,6 +1292,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
* \li DNS_R_NCACHENXRRSET
* \li DNS_R_NXRRSET
* \li DNS_R_NXDOMAIN
+ * \li DNS_R_BROKENCHAIN
*/
static inline isc_result_t
view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
@@ -1280,9 +1302,12 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
unsigned int options;
+ isc_time_t now;
char buf1[DNS_NAME_FORMATSIZE];
char buf2[DNS_NAME_FORMATSIZE];
char buf3[DNS_NAME_FORMATSIZE];
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
if (dns_rdataset_isassociated(&val->frdataset))
dns_rdataset_disassociate(&val->frdataset);
@@ -1292,6 +1317,16 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
if (val->view->zonetable == NULL)
return (ISC_R_CANCELED);
+ if (isc_time_now(&now) == ISC_R_SUCCESS &&
+ dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
+
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+ validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)",
+ namebuf, typebuf);
+ return (DNS_R_BROKENCHAIN);
+ }
+
options = DNS_DBFIND_PENDINGOK;
if (type == dns_rdatatype_dlv)
options |= DNS_DBFIND_COVERINGNSEC;
@@ -1300,6 +1335,7 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
result = dns_view_find(val->view, name, type, 0, options,
ISC_FALSE, NULL, NULL, foundname,
&val->frdataset, &val->fsigrdataset);
+
if (result == DNS_R_NXDOMAIN) {
if (dns_rdataset_isassociated(&val->frdataset))
dns_rdataset_disassociate(&val->frdataset);
@@ -1656,7 +1692,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
/*
* We don't know anything about this key.
*/
- result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey,
+ result = create_fetch(val, &siginfo->signer,
+ dns_rdatatype_dnskey,
fetch_callback_validator, "get_key");
if (result != ISC_R_SUCCESS)
return (result);
@@ -1671,7 +1708,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
* This key doesn't exist.
*/
result = DNS_R_CONTINUE;
- }
+ } else if (result == DNS_R_BROKENCHAIN)
+ return (result);
if (dns_rdataset_isassociated(&val->frdataset) &&
val->keyset != &val->frdataset)
@@ -1919,8 +1957,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
"looking for noqname proof");
return (nsecvalidate(val, ISC_FALSE));
} else if (result == ISC_R_SUCCESS) {
- event->rdataset->trust = dns_trust_secure;
- event->sigrdataset->trust = dns_trust_secure;
+ marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure");
return (result);
@@ -2096,8 +2133,7 @@ dlv_validatezonekey(dns_validator_t *val) {
"no RRSIG matching DLV key");
}
if (result == ISC_R_SUCCESS) {
- val->event->rdataset->trust = dns_trust_secure;
- val->event->sigrdataset->trust = dns_trust_secure;
+ marksecure(val->event);
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
@@ -2198,8 +2234,7 @@ validatezonekey(dns_validator_t *val) {
keynode = nextnode;
}
if (result == ISC_R_SUCCESS) {
- event->rdataset->trust = dns_trust_secure;
- event->sigrdataset->trust = dns_trust_secure;
+ marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3),
"signed by trusted key; "
"marking as secure");
@@ -2226,11 +2261,14 @@ validatezonekey(dns_validator_t *val) {
*/
dns_name_format(val->event->name, namebuf,
sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(2),
+ validator_log(val, ISC_LOG_NOTICE,
"unable to find a DNSKEY which verifies "
"the DNSKEY RRset and also matches one "
"of specified trusted-keys for '%s'",
namebuf);
+ validator_log(val, ISC_LOG_NOTICE,
+ "please check the 'trusted-keys' for "
+ "'%s' in named.conf.", namebuf);
return (DNS_R_NOVALIDKEY);
}
@@ -2291,7 +2329,8 @@ validatezonekey(dns_validator_t *val) {
dns_rdataset_disassociate(&val->fsigrdataset);
validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
return (DNS_R_NOVALIDSIG);
- }
+ } else if (result == DNS_R_BROKENCHAIN)
+ return (result);
}
/*
@@ -2440,8 +2479,7 @@ validatezonekey(dns_validator_t *val) {
"no RRSIG matching DS key");
}
if (result == ISC_R_SUCCESS) {
- event->rdataset->trust = dns_trust_secure;
- event->sigrdataset->trust = dns_trust_secure;
+ marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
@@ -2844,6 +2882,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
"nsecvalidate");
if (result != ISC_R_SUCCESS)
return (result);
+ val->authcount++;
return (DNS_R_WAIT);
}
@@ -2868,8 +2907,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
"noqname proof found");
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure");
- val->event->rdataset->trust = dns_trust_secure;
- val->event->sigrdataset->trust = dns_trust_secure;
+ marksecure(val->event);
return (ISC_R_SUCCESS);
} else if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0 &&
dns_name_countlabels(dns_fixedname_name(&val->wild))
@@ -2923,6 +2961,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
}
findnsec3proofs(val);
+ if (val->authcount == val->authfail)
+ return (DNS_R_BROKENCHAIN);
validator_log(val, ISC_LOG_DEBUG(3),
"nonexistence proof(s) not found");
val->attributes |= VALATTR_INSECURITY;
@@ -2954,6 +2994,58 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
return (ISC_FALSE);
}
+static void
+dlvvalidated(isc_task_t *task, isc_event_t *event) {
+ dns_validatorevent_t *devent;
+ dns_validator_t *val;
+ isc_result_t eresult;
+ isc_boolean_t want_destroy;
+
+ UNUSED(task);
+ INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
+
+ devent = (dns_validatorevent_t *)event;
+ val = devent->ev_arg;
+ eresult = devent->result;
+
+ isc_event_free(&event);
+ dns_validator_destroy(&val->subvalidator);
+
+ INSIST(val->event != NULL);
+
+ validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated");
+ LOCK(&val->lock);
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dlvset with trust %d", val->frdataset.trust);
+ dns_rdataset_clone(&val->frdataset, &val->dlv);
+ val->havedlvsep = ISC_TRUE;
+ if (dlv_algorithm_supported(val))
+ dlv_validator_start(val);
+ else {
+ markanswer(val);
+ validator_done(val, ISC_R_SUCCESS);
+ }
+ } else {
+ if (eresult != DNS_R_BROKENCHAIN) {
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_expire(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_expire(&val->fsigrdataset);
+ }
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dlvvalidated: got %s",
+ isc_result_totext(eresult));
+ validator_done(val, DNS_R_BROKENCHAIN);
+ }
+ want_destroy = exit_check(val);
+ UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
+}
+
/*%
* Callback from fetching a DLV record.
*
@@ -3173,6 +3265,24 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
namebuf);
result = view_find(val, dlvname, dns_rdatatype_dlv);
if (result == ISC_R_SUCCESS) {
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
+ dns_rdataset_isassociated(&val->fsigrdataset))
+ {
+ dns_fixedname_init(&val->fname);
+ dns_name_copy(dlvname,
+ dns_fixedname_name(&val->fname),
+ NULL);
+ result = create_validator(val,
+ dns_fixedname_name(&val->fname),
+ dns_rdatatype_dlv,
+ &val->frdataset,
+ &val->fsigrdataset,
+ dlvvalidated,
+ "finddlvsep");
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return (DNS_R_WAIT);
+ }
if (val->frdataset.trust < dns_trust_secure)
return (DNS_R_NOVALIDSIG);
val->havedlvsep = ISC_TRUE;
@@ -3223,6 +3333,7 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
* \li DNS_R_NOVALIDSIG
* \li DNS_R_NOVALIDNSEC
* \li DNS_R_NOTINSECURE
+ * \li DNS_R_BROKENCHAIN
*/
static isc_result_t
proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
@@ -3465,7 +3576,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
- }
+ } else if (result == DNS_R_BROKENCHAIN)
+ return (result);
}
/*
@@ -3682,6 +3794,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
val->seensig = ISC_FALSE;
val->havedlvsep = ISC_FALSE;
val->depth = 0;
+ val->authcount = 0;
+ val->authfail = 0;
val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
dns_rdataset_init(&val->frdataset);
dns_rdataset_init(&val->fsigrdataset);
diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c
index 5f1447a..72163b4 100644
--- a/contrib/bind9/lib/dns/view.c
+++ b/contrib/bind9/lib/dns/view.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.150.84.2 2009/01/29 23:47:44 tbox Exp $ */
+/* $Id: view.c,v 1.150.84.3.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -1250,7 +1250,8 @@ dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
if (result != ISC_R_SUCCESS)
return (result);
- return (dns_view_gettsig(view, keyname, keyp));
+ result = dns_view_gettsig(view, keyname, keyp);
+ return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
}
isc_result_t
@@ -1270,10 +1271,11 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
(void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
- &dns_master_style_cache, fp);
+ &dns_master_style_cache, fp);
if (result != ISC_R_SUCCESS)
return (result);
dns_adb_dump(view->adb, fp);
+ dns_resolver_printbadcache(view->resolver, fp);
return (ISC_R_SUCCESS);
}
@@ -1294,6 +1296,8 @@ dns_view_flushcache(dns_view_t *view) {
dns_cache_attachdb(view->cache, &view->cachedb);
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
+ if (view->resolver != NULL)
+ dns_resolver_flushbadcache(view->resolver, NULL);
dns_adb_flush(view->adb);
return (ISC_R_SUCCESS);
@@ -1308,6 +1312,8 @@ dns_view_flushname(dns_view_t *view, dns_name_t *name) {
dns_adb_flushname(view->adb, name);
if (view->cache == NULL)
return (ISC_R_SUCCESS);
+ if (view->resolver != NULL)
+ dns_resolver_flushbadcache(view->resolver, name);
return (dns_cache_flushname(view->cache, name));
}
diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c
index 423b005..c21b1f0 100644
--- a/contrib/bind9/lib/dns/zone.c
+++ b/contrib/bind9/lib/dns/zone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.483.36.6 2009/03/26 22:57:07 marka Exp $ */
+/* $Id: zone.c,v 1.483.36.17 2009/12/21 04:32:42 marka Exp $ */
/*! \file */
@@ -200,7 +200,6 @@ struct dns_zone {
isc_time_t keywarntime;
isc_time_t signingtime;
isc_time_t nsec3chaintime;
- isc_uint32_t serial;
isc_uint32_t refresh;
isc_uint32_t retry;
isc_uint32_t expire;
@@ -351,11 +350,15 @@ struct dns_zone {
#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
+#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
+#define DNS_ZONEFLG_THAW 0x08000000U
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
/* Flags for zone_load() */
#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
+#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
+ load. */
#define UNREACH_CHACHE_SIZE 10U
#define UNREACH_HOLD_TIME 600 /* 10 minutes */
@@ -718,7 +721,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
isc_time_settoepoch(&zone->keywarntime);
isc_time_settoepoch(&zone->signingtime);
isc_time_settoepoch(&zone->nsec3chaintime);
- zone->serial = 0;
zone->refresh = DNS_ZONE_DEFAULTREFRESH;
zone->retry = DNS_ZONE_DEFAULTRETRY;
zone->expire = 0;
@@ -967,16 +969,35 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
UNLOCK_ZONE(zone);
}
-isc_uint32_t
-dns_zone_getserial(dns_zone_t *zone) {
- isc_uint32_t serial;
+isc_result_t
+dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
+ isc_result_t result;
REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(serialp != NULL);
LOCK_ZONE(zone);
- serial = zone->serial;
+ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
+ if (zone->db != NULL) {
+ result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
+ NULL, NULL, NULL, NULL, NULL);
+ } else
+ result = DNS_R_NOTLOADED;
+ ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
UNLOCK_ZONE(zone);
+ return (result);
+}
+
+isc_uint32_t
+dns_zone_getserial(dns_zone_t *zone) {
+ isc_result_t result;
+ isc_uint32_t serial;
+
+ result = dns_zone_getserial2(zone, &serial);
+ if (result != ISC_R_SUCCESS)
+ serial = 0; /* XXX: not really correct, but no other choice */
+
return (serial);
}
@@ -1314,7 +1335,9 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
INSIST(zone->type != dns_zone_none);
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
- result = ISC_R_SUCCESS;
+ if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
+ result = DNS_R_CONTINUE;
goto cleanup;
}
@@ -1448,6 +1471,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
if (result == DNS_R_CONTINUE) {
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
+ if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
goto cleanup;
}
@@ -1470,6 +1495,30 @@ dns_zone_loadnew(dns_zone_t *zone) {
return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
}
+isc_result_t
+dns_zone_loadandthaw(dns_zone_t *zone) {
+ isc_result_t result;
+
+ result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
+ switch (result) {
+ case DNS_R_CONTINUE:
+ /* Deferred thaw. */
+ break;
+ case ISC_R_SUCCESS:
+ case DNS_R_UPTODATE:
+ case DNS_R_SEENINCLUDE:
+ zone->update_disabled = ISC_FALSE;
+ break;
+ case DNS_R_NOMASTERFILE:
+ zone->update_disabled = ISC_FALSE;
+ break;
+ default:
+ /* Error, remain in disabled state. */
+ break;
+ }
+ return (result);
+}
+
static unsigned int
get_master_options(dns_zone_t *zone) {
unsigned int options;
@@ -2148,7 +2197,8 @@ resume_signingwithkey(dns_zone_t *zone) {
}
result = zone_signwithkey(zone, rdata.data[0],
- (rdata.data[1] << 8) | rdata.data[2], ISC_TF(rdata.data[3]));
+ (rdata.data[1] << 8) | rdata.data[2],
+ ISC_TF(rdata.data[3]));
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_signwithkey failed: %s",
@@ -2291,7 +2341,6 @@ static void
set_resigntime(dns_zone_t *zone) {
dns_rdataset_t rdataset;
dns_fixedname_t fixed;
- char namebuf[DNS_NAME_FORMATSIZE];
unsigned int resign;
isc_result_t result;
isc_uint32_t nanosecs;
@@ -2305,7 +2354,6 @@ set_resigntime(dns_zone_t *zone) {
return;
}
resign = rdataset.resign;
- dns_name_format(dns_fixedname_name(&fixed), namebuf, sizeof(namebuf));
dns_rdataset_disassociate(&rdataset);
isc_random_get(&nanosecs);
nanosecs %= 1000000000;
@@ -2409,7 +2457,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
unsigned int soacount = 0;
unsigned int nscount = 0;
unsigned int errors = 0;
- isc_uint32_t serial, refresh, retry, expire, minimum;
+ isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
isc_time_t now;
isc_boolean_t needdump = ISC_FALSE;
isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
@@ -2463,8 +2511,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
options = DNS_JOURNALOPT_RESIGN;
else
options = 0;
- result = dns_journal_rollforward(zone->mctx, db, options,
- zone->journal);
+ result = dns_journal_rollforward2(zone->mctx, db, options,
+ zone->sigresigninginterval,
+ zone->journal);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
result != ISC_R_RANGE) {
@@ -2544,14 +2593,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
* This is checked in zone_replacedb() for slave zones
* as they don't reload from disk.
*/
+ result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ &oldserial, NULL, NULL, NULL,
+ NULL, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
- !isc_serial_gt(serial, zone->serial)) {
+ !isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
INSIST(zone->type == dns_zone_master);
- serialmin = (zone->serial + 1) & 0xffffffffU;
- serialmax = (zone->serial + 0x7fffffffU) &
+ serialmin = (oldserial + 1) & 0xffffffffU;
+ serialmax = (oldserial + 0x7fffffffU) &
0xffffffffU;
dns_zone_log(zone, ISC_LOG_ERROR,
"ixfr-from-differences: "
@@ -2560,10 +2613,10 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
serialmax);
result = DNS_R_BADZONE;
goto cleanup;
- } else if (!isc_serial_ge(serial, zone->serial))
+ } else if (!isc_serial_ge(serial, oldserial))
dns_zone_log(zone, ISC_LOG_ERROR,
"zone serial has gone backwards");
- else if (serial == zone->serial && !hasinclude)
+ else if (serial == oldserial && !hasinclude)
dns_zone_log(zone, ISC_LOG_ERROR,
"zone serial unchanged. "
"zone may fail to transfer "
@@ -2580,7 +2633,6 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
"3 * refresh.");
}
- zone->serial = serial;
zone->refresh = RANGE(refresh,
zone->minrefresh, zone->maxrefresh);
zone->retry = RANGE(retry,
@@ -2664,8 +2716,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
}
if (! dns_db_ispersistent(db))
- dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
- zone->serial,
+ dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
dns_db_issecure(db) ? " (signed)" : "");
return (result);
@@ -2683,7 +2734,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
if (zone->task != NULL)
zone_settimer(zone, &now);
result = ISC_R_SUCCESS;
- }
+ } else if (zone->type == dns_zone_master)
+ dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
return (result);
}
@@ -4374,7 +4426,8 @@ updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
seen_done = ISC_TRUE;
else
CHECK(update_one_rr(signing->db, version, diff,
- DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata));
+ DNS_DIFFOP_DEL, name,
+ rdataset.ttl, &rdata));
dns_rdata_reset(&rdata);
}
if (result == ISC_R_NOMORE)
@@ -5458,6 +5511,7 @@ zone_sign(dns_zone_t *zone) {
dst_key_t *zone_keys[MAXZONEKEYS];
isc_int32_t signatures;
isc_boolean_t check_ksk, is_ksk;
+ isc_boolean_t commit = ISC_FALSE;
isc_boolean_t delegation;
isc_boolean_t finishedakey = ISC_FALSE;
isc_boolean_t secureupdated = ISC_FALSE;
@@ -5745,6 +5799,7 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
+
if (finishedakey) {
/*
* We have changed the RRset above so we need to update
@@ -5770,6 +5825,15 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
+
+ /*
+ * Have we changed anything?
+ */
+ if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
+ goto pauseall;
+
+ commit = ISC_TRUE;
+
result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
&sig_diff, zone_keys, nkeys, now);
if (result != ISC_R_SUCCESS) {
@@ -5801,6 +5865,9 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
+ /*
+ * Write changes to journal file.
+ */
journalfile = dns_zone_getjournal(zone);
if (journalfile != NULL) {
dns_journal_t *journal = NULL;
@@ -5823,7 +5890,7 @@ zone_sign(dns_zone_t *zone) {
}
}
-
+ pauseall:
/*
* Pause all iterators so that dns_db_closeversion() can succeed.
*/
@@ -5840,7 +5907,7 @@ zone_sign(dns_zone_t *zone) {
/*
* Everything has succeeded. Commit the changes.
*/
- dns_db_closeversion(db, &version, ISC_TRUE);
+ dns_db_closeversion(db, &version, commit);
/*
* Everything succeeded so we can clean these up now.
@@ -5856,9 +5923,11 @@ zone_sign(dns_zone_t *zone) {
set_resigntime(zone);
- LOCK_ZONE(zone);
- zone_needdump(zone, DNS_DUMP_DELAY);
- UNLOCK_ZONE(zone);
+ if (commit) {
+ LOCK_ZONE(zone);
+ zone_needdump(zone, DNS_DUMP_DELAY);
+ UNLOCK_ZONE(zone);
+ }
failure:
/*
@@ -6498,6 +6567,7 @@ notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
isc_sockaddr_t any;
isc_boolean_t isself;
isc_netaddr_t dstaddr;
+ isc_result_t result;
if (zone->view == NULL || zone->isself == NULL)
return (ISC_FALSE);
@@ -6523,7 +6593,9 @@ notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
src = *dst;
isc_netaddr_fromsockaddr(&dstaddr, dst);
- (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
+ result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ return (ISC_FALSE);
isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
zone->isselfarg);
if (key != NULL)
@@ -6725,9 +6797,14 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
goto cleanup;
isc_netaddr_fromsockaddr(&dstip, &notify->dst);
- (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key);
-
isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
+ result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
+ notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
+ "sent. Peer TSIG key lookup failure.", addrbuf);
+ goto cleanup_message;
+ }
+
notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
addrbuf);
if (notify->zone->view->peers != NULL) {
@@ -6774,6 +6851,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
cleanup_key:
if (key != NULL)
dns_tsigkey_detach(&key);
+ cleanup_message:
dns_message_destroy(&message);
cleanup:
UNLOCK_ZONE(notify->zone);
@@ -7386,7 +7464,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_soa_t soa;
isc_result_t result;
- isc_uint32_t serial;
+ isc_uint32_t serial, oldserial;
unsigned int j;
zone = revent->ev_arg;
@@ -7609,12 +7687,17 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
serial = soa.serial;
-
- zone_debuglog(zone, me, 1, "serial: new %u, old %u",
- serial, zone->serial);
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
+ result = dns_zone_getserial2(zone, &oldserial);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ zone_debuglog(zone, me, 1, "serial: new %u, old %u",
+ serial, oldserial);
+ } else
+ zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
+ serial);
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
- isc_serial_gt(serial, zone->serial)) {
+ isc_serial_gt(serial, oldserial)) {
if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
&zone->sourceaddr, &now)) {
dns_zone_log(zone, ISC_LOG_INFO,
@@ -7638,7 +7721,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
}
if (msg != NULL)
dns_message_destroy(&msg);
- } else if (isc_serial_eq(soa.serial, zone->serial)) {
+ } else if (isc_serial_eq(soa.serial, oldserial)) {
if (zone->masterfile != NULL) {
result = ISC_R_FAILURE;
if (zone->journal != NULL)
@@ -7671,7 +7754,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
"received from master %s < ours (%u)",
- soa.serial, master, zone->serial);
+ soa.serial, master, oldserial);
else
zone_debuglog(zone, me, 1, "ahead");
zone->mastersok[zone->curmaster] = ISC_TRUE;
@@ -7965,10 +8048,19 @@ soa_query(isc_task_t *task, isc_event_t *event) {
dns_name_format(keyname, namebuf, sizeof(namebuf));
dns_zone_log(zone, ISC_LOG_ERROR,
"unable to find key: %s", namebuf);
+ goto skip_master;
+ }
+ }
+ if (key == NULL) {
+ result = dns_view_getpeertsig(zone->view, &masterip, &key);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
+ char addrbuf[ISC_NETADDR_FORMATSIZE];
+ isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "unable to find TSIG key for %s", addrbuf);
+ goto skip_master;
}
}
- if (key == NULL)
- (void)dns_view_getpeertsig(zone->view, &masterip, &key);
have_xfrsource = ISC_FALSE;
reqnsid = zone->view->requestnsid;
@@ -8789,13 +8881,21 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
if (result == ISC_R_SUCCESS)
result = dns_rdataset_first(rdataset);
if (result == ISC_R_SUCCESS) {
- isc_uint32_t serial = 0;
+ isc_uint32_t serial = 0, oldserial;
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &soa, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
serial = soa.serial;
- if (isc_serial_le(serial, zone->serial)) {
+ /*
+ * The following should safely be performed without DB
+ * lock and succeed in this context.
+ */
+ result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ &oldserial, NULL, NULL, NULL,
+ NULL, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (isc_serial_le(serial, oldserial)) {
dns_zone_log(zone, ISC_LOG_INFO,
"notify from %s: "
"zone is up to date",
@@ -9473,7 +9573,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
if (zone->db != NULL && zone->journal != NULL &&
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
- isc_uint32_t serial;
+ isc_uint32_t serial, oldserial;
dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
@@ -9488,11 +9588,15 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
/*
* This is checked in zone_postload() for master zones.
*/
+ result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ &oldserial, NULL, NULL, NULL, NULL,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (zone->type == dns_zone_slave &&
- !isc_serial_gt(serial, zone->serial)) {
+ !isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
- serialmin = (zone->serial + 1) & 0xffffffffU;
- serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
+ serialmin = (oldserial + 1) & 0xffffffffU;
+ serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
dns_zone_log(zone, ISC_LOG_ERROR,
"ixfr-from-differences: failed: "
"new serial (%u) out of range [%u - %u]",
@@ -9685,7 +9789,6 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
zone_unload(zone);
goto next_master;
}
- zone->serial = serial;
zone->refresh = RANGE(refresh, zone->minrefresh,
zone->maxrefresh);
zone->retry = RANGE(retry, zone->minretry,
@@ -9723,7 +9826,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
buf[0] = '\0';
dns_zone_log(zone, ISC_LOG_INFO,
"transferred serial %u%s",
- zone->serial, buf);
+ serial, buf);
}
/*
@@ -9873,6 +9976,13 @@ zone_loaddone(void *arg, isc_result_t result) {
(void)zone_postload(load->zone, load->db, load->loadtime, result);
zonemgr_putio(&load->zone->readio);
DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
+ /*
+ * Leave the zone frozen if the reload fails.
+ */
+ if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
+ DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
+ zone->update_disabled = ISC_FALSE;
+ DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
UNLOCK_ZONE(load->zone);
load->magic = 0;
@@ -11508,7 +11618,8 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
cleanup:
if (signing != NULL) {
- dns_db_detach(&signing->db);
+ if (signing->db != NULL)
+ dns_db_detach(&signing->db);
if (signing->dbiterator != NULL)
dns_dbiterator_destroy(&signing->dbiterator);
isc_mem_put(zone->mctx, signing, sizeof *signing);
diff --git a/contrib/bind9/lib/isc/api b/contrib/bind9/lib/isc/api
index 5ef8dc0..e55996b 100644
--- a/contrib/bind9/lib/isc/api
+++ b/contrib/bind9/lib/isc/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 51
+LIBINTERFACE = 52
LIBREVISION = 1
-LIBAGE = 1
+LIBAGE = 2
diff --git a/contrib/bind9/lib/isc/base32.c b/contrib/bind9/lib/isc/base32.c
index 3000a84..d324da9 100644
--- a/contrib/bind9/lib/isc/base32.c
+++ b/contrib/bind9/lib/isc/base32.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: base32.c,v 1.3.116.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: base32.c,v 1.3.116.3 2009/10/21 01:22:47 each Exp $ */
/*! \file */
@@ -112,6 +112,8 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak,
RETERR(str_totext(wordbreak, target));
}
}
+ if (source->length > 0)
+ isc_region_consume(source, source->length);
return (ISC_R_SUCCESS);
}
diff --git a/contrib/bind9/lib/isc/base64.c b/contrib/bind9/lib/isc/base64.c
index 13ed6b5..4844a4b 100644
--- a/contrib/bind9/lib/isc/base64.c
+++ b/contrib/bind9/lib/isc/base64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: base64.c,v 1.32 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: base64.c,v 1.32.332.2 2009/10/21 23:47:20 tbox Exp $ */
/*! \file */
@@ -85,11 +85,13 @@ isc_base64_totext(isc_region_t *source, int wordlength,
buf[2] = base64[((source->base[1]<<2)&0x3c)];
buf[3] = '=';
RETERR(str_totext(buf, target));
+ isc_region_consume(source, 2);
} else if (source->length == 1) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)];
buf[2] = buf[3] = '=';
RETERR(str_totext(buf, target));
+ isc_region_consume(source, 1);
}
return (ISC_R_SUCCESS);
}
@@ -217,7 +219,7 @@ isc_base64_decodestring(const char *cstr, isc_buffer_t *target) {
continue;
RETERR(base64_decode_char(&ctx, c));
}
- RETERR(base64_decode_finish(&ctx));
+ RETERR(base64_decode_finish(&ctx));
return (ISC_R_SUCCESS);
}
diff --git a/contrib/bind9/lib/isc/heap.c b/contrib/bind9/lib/isc/heap.c
index 91d78c0..dc32100 100644
--- a/contrib/bind9/lib/isc/heap.c
+++ b/contrib/bind9/lib/isc/heap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: heap.c,v 1.37 2007/10/19 17:15:53 explorer Exp $ */
+/* $Id: heap.c,v 1.37.240.3 2010/02/04 23:47:46 tbox Exp $ */
/*! \file
* Heap implementation of priority queues adapted from the following:
@@ -186,15 +186,17 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) {
isc_result_t
isc_heap_insert(isc_heap_t *heap, void *elt) {
- unsigned int i;
+ unsigned int new_last;
REQUIRE(VALID_HEAP(heap));
- i = ++heap->last;
- if (heap->last >= heap->size && !resize(heap))
+ new_last = heap->last + 1;
+ RUNTIME_CHECK(new_last > 0); /* overflow check */
+ if (new_last >= heap->size && !resize(heap))
return (ISC_R_NOMEMORY);
+ heap->last = new_last;
- float_up(heap, i, elt);
+ float_up(heap, new_last, elt);
return (ISC_R_SUCCESS);
}
diff --git a/contrib/bind9/lib/isc/httpd.c b/contrib/bind9/lib/isc/httpd.c
index fa31325..066939d 100644
--- a/contrib/bind9/lib/isc/httpd.c
+++ b/contrib/bind9/lib/isc/httpd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: httpd.c,v 1.16 2008/08/08 05:06:49 marka Exp $ */
+/* $Id: httpd.c,v 1.16.64.2 2010/02/04 23:47:46 tbox Exp $ */
/*! \file */
@@ -151,6 +151,7 @@ struct isc_httpdmgr {
ISC_LIST(isc_httpdurl_t) urls; /*%< urls we manage */
isc_httpdaction_t *render_404;
+ isc_httpdaction_t *render_500;
};
/*%
@@ -221,6 +222,11 @@ static isc_result_t render_404(const char *, const char *,
unsigned int *, const char **,
const char **, isc_buffer_t *,
isc_httpdfree_t **, void **);
+static isc_result_t render_500(const char *, const char *,
+ void *,
+ unsigned int *, const char **,
+ const char **, isc_buffer_t *,
+ isc_httpdfree_t **, void **);
static void
destroy_client(isc_httpd_t **httpdp)
@@ -300,6 +306,7 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
goto cleanup;
httpd->render_404 = render_404;
+ httpd->render_500 = render_500;
*httpdp = httpd;
return (ISC_R_SUCCESS);
@@ -623,6 +630,30 @@ render_404(const char *url, const char *querystring,
return (ISC_R_SUCCESS);
}
+static isc_result_t
+render_500(const char *url, const char *querystring,
+ void *arg,
+ unsigned int *retcode, const char **retmsg,
+ const char **mimetype, isc_buffer_t *b,
+ isc_httpdfree_t **freecb, void **freecb_args)
+{
+ static char msg[] = "Internal server failure.";
+
+ UNUSED(url);
+ UNUSED(querystring);
+ UNUSED(arg);
+
+ *retcode = 500;
+ *retmsg = "Internal server failure";
+ *mimetype = "text/plain";
+ isc_buffer_reinit(b, msg, strlen(msg));
+ isc_buffer_add(b, strlen(msg));
+ *freecb = NULL;
+ *freecb_args = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
static void
isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev)
{
@@ -691,8 +722,14 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev)
&httpd->mimetype, &httpd->bodybuffer,
&httpd->freecb, &httpd->freecb_arg);
if (result != ISC_R_SUCCESS) {
- destroy_client(&httpd);
- goto out;
+ result = httpd->mgr->render_500(httpd->url, httpd->querystring,
+ NULL,
+ &httpd->retcode,
+ &httpd->retmsg,
+ &httpd->mimetype,
+ &httpd->bodybuffer,
+ &httpd->freecb,
+ &httpd->freecb_arg);
}
isc_httpd_response(httpd);
diff --git a/contrib/bind9/lib/isc/ia64/include/isc/atomic.h b/contrib/bind9/lib/isc/ia64/include/isc/atomic.h
index 0fac76f..5d7c366 100644
--- a/contrib/bind9/lib/isc/ia64/include/isc/atomic.h
+++ b/contrib/bind9/lib/isc/ia64/include/isc/atomic.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: atomic.h,v 1.4.326.2 2009/02/06 23:47:11 tbox Exp $ */
+/* $Id: atomic.h,v 1.4.326.3 2009/06/24 02:21:28 marka Exp $ */
#ifndef ISC_ATOMIC_H
#define ISC_ATOMIC_H 1
diff --git a/contrib/bind9/lib/isc/include/isc/entropy.h b/contrib/bind9/lib/isc/include/isc/entropy.h
index e9e59c4..125669c 100644
--- a/contrib/bind9/lib/isc/include/isc/entropy.h
+++ b/contrib/bind9/lib/isc/include/isc/entropy.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: entropy.h,v 1.32.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: entropy.h,v 1.32.332.3 2009/10/19 02:46:07 marka Exp $ */
#ifndef ISC_ENTROPY_H
#define ISC_ENTROPY_H 1
@@ -182,8 +182,8 @@ isc_result_t
isc_entropy_createsamplesource(isc_entropy_t *ent,
isc_entropysource_t **sourcep);
/*!<
- * \brief Create an entropy source that consists of samples. Each sample is added
- * to the source via isc_entropy_addsamples(), below.
+ * \brief Create an entropy source that consists of samples. Each sample is
+ * added to the source via isc_entropy_addsamples(), below.
*/
isc_result_t
@@ -254,11 +254,11 @@ void
isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
isc_uint32_t entropy);
/*!<
- * \brief Add "length" bytes in "data" to the entropy pool, incrementing the pool's
- * entropy count by "entropy."
+ * \brief Add "length" bytes in "data" to the entropy pool, incrementing the
+ * pool's entropy count by "entropy."
*
- * These bytes will prime the pseudorandom portion even no entropy is actually
- * added.
+ * These bytes will prime the pseudorandom portion even if no entropy is
+ * actually added.
*/
void
diff --git a/contrib/bind9/lib/isc/include/isc/netscope.h b/contrib/bind9/lib/isc/include/isc/netscope.h
index ba4e792..0883140 100644
--- a/contrib/bind9/lib/isc/include/isc/netscope.h
+++ b/contrib/bind9/lib/isc/include/isc/netscope.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netscope.h,v 1.11 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: netscope.h,v 1.11.332.2 2009/06/25 23:47:24 tbox Exp $ */
#ifndef ISC_NETSCOPE_H
#define ISC_NETSCOPE_H 1
@@ -40,4 +40,4 @@ isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid);
ISC_LANG_ENDDECLS
-#endif /* ISC_NETADDR_H */
+#endif /* ISC_NETSCOPE_H */
diff --git a/contrib/bind9/lib/isc/include/isc/portset.h b/contrib/bind9/lib/isc/include/isc/portset.h
index dc1f856..a7ad3d6 100644
--- a/contrib/bind9/lib/isc/include/isc/portset.h
+++ b/contrib/bind9/lib/isc/include/isc/portset.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: portset.h,v 1.3.90.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: portset.h,v 1.3.90.3 2009/06/25 05:31:51 marka Exp $ */
/*! \file isc/portset.h
* \brief Transport Protocol Port Manipulation Module
@@ -138,4 +138,4 @@ isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
ISC_LANG_ENDDECLS
-#endif /* ISC_NETADDR_H */
+#endif /* ISC_PORTSET_H */
diff --git a/contrib/bind9/lib/isc/include/isc/sha2.h b/contrib/bind9/lib/isc/include/isc/sha2.h
index 211e255..edafa61 100644
--- a/contrib/bind9/lib/isc/include/isc/sha2.h
+++ b/contrib/bind9/lib/isc/include/isc/sha2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sha2.h,v 1.9 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: sha2.h,v 1.9.332.2 2010/01/15 23:47:34 tbox Exp $ */
/* $FreeBSD$ */
/* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */
@@ -39,7 +39,7 @@
* 3. Neither the name of the copyright holder 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 THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -104,24 +104,28 @@ typedef isc_sha512_t isc_sha384_t;
/*** SHA-224/256/384/512 Function Prototypes ******************************/
void isc_sha224_init (isc_sha224_t *);
+void isc_sha224_invalidate (isc_sha224_t *);
void isc_sha224_update (isc_sha224_t *, const isc_uint8_t *, size_t);
void isc_sha224_final (isc_uint8_t[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *);
char *isc_sha224_end (isc_sha224_t *, char[ISC_SHA224_DIGESTSTRINGLENGTH]);
char *isc_sha224_data (const isc_uint8_t *, size_t, char[ISC_SHA224_DIGESTSTRINGLENGTH]);
void isc_sha256_init (isc_sha256_t *);
+void isc_sha256_invalidate (isc_sha256_t *);
void isc_sha256_update (isc_sha256_t *, const isc_uint8_t *, size_t);
void isc_sha256_final (isc_uint8_t[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *);
char *isc_sha256_end (isc_sha256_t *, char[ISC_SHA256_DIGESTSTRINGLENGTH]);
char *isc_sha256_data (const isc_uint8_t *, size_t, char[ISC_SHA256_DIGESTSTRINGLENGTH]);
void isc_sha384_init (isc_sha384_t *);
+void isc_sha384_invalidate (isc_sha384_t *);
void isc_sha384_update (isc_sha384_t *, const isc_uint8_t *, size_t);
void isc_sha384_final (isc_uint8_t[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *);
char *isc_sha384_end (isc_sha384_t *, char[ISC_SHA384_DIGESTSTRINGLENGTH]);
char *isc_sha384_data (const isc_uint8_t *, size_t, char[ISC_SHA384_DIGESTSTRINGLENGTH]);
void isc_sha512_init (isc_sha512_t *);
+void isc_sha512_invalidate (isc_sha512_t *);
void isc_sha512_update (isc_sha512_t *, const isc_uint8_t *, size_t);
void isc_sha512_final (isc_uint8_t[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *);
char *isc_sha512_end (isc_sha512_t *, char[ISC_SHA512_DIGESTSTRINGLENGTH]);
diff --git a/contrib/bind9/lib/isc/include/isc/util.h b/contrib/bind9/lib/isc/include/isc/util.h
index 8a3b95d..85846b6 100644
--- a/contrib/bind9/lib/isc/include/isc/util.h
+++ b/contrib/bind9/lib/isc/include/isc/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: util.h,v 1.30 2007/06/19 23:47:18 tbox Exp $ */
+/* $Id: util.h,v 1.30.332.2 2010/01/11 23:47:22 tbox Exp $ */
#ifndef ISC_UTIL_H
#define ISC_UTIL_H 1
@@ -230,4 +230,14 @@
*/
#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
+/*%
+ * Prevent Linux spurious warnings
+ */
+#if defined(__GNUC__) && (__GNUC__ > 3)
+#define isc_util_fwrite(a, b, c, d) \
+ __builtin_expect(fwrite((a), (b), (c), (d)), (c))
+#else
+#define isc_util_fwrite(a, b, c, d) fwrite((a), (b), (c), (d))
+#endif
+
#endif /* ISC_UTIL_H */
diff --git a/contrib/bind9/lib/isc/inet_ntop.c b/contrib/bind9/lib/isc/inet_ntop.c
index dc053ed..c37be5c 100644
--- a/contrib/bind9/lib/isc/inet_ntop.c
+++ b/contrib/bind9/lib/isc/inet_ntop.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -19,7 +19,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] =
- "$Id: inet_ntop.c,v 1.19 2007/06/19 23:47:17 tbox Exp $";
+ "$Id: inet_ntop.c,v 1.19.332.2 2009/07/18 23:47:25 tbox Exp $";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
@@ -52,7 +52,7 @@ static const char *inet_ntop6(const unsigned char *src, char *dst,
* convert a network format address to presentation format.
* \return
* pointer to presentation format address (`dst'), or NULL (see errno).
- * \author
+ * \author
* Paul Vixie, 1996.
*/
const char *
@@ -169,8 +169,9 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
if (i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
- if (i == 6 && best.base == 0 &&
- (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (i == 6 && best.base == 0 && (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp,
sizeof(tmp) - (tp - tmp)))
return (NULL);
diff --git a/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h b/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h
index 765cb6d..2114767 100644
--- a/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h
+++ b/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: atomic.h,v 1.6 2007/06/18 23:47:47 tbox Exp $ */
+/* $Id: atomic.h,v 1.6.332.2 2009/10/14 23:47:14 tbox Exp $ */
#ifndef ISC_ATOMIC_H
#define ISC_ATOMIC_H 1
@@ -46,25 +46,56 @@
#include <sys/atomic_op.h>
-#define isc_atomic_xadd(p, v) fetch_and_add(p, v)
#define isc_atomic_store(p, v) _clear_lock(p, v)
#ifdef __GNUC__
+static inline isc_int32_t
+#else
+static isc_int32_t
+#endif
+isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
+ int ret;
+
+#ifdef __GNUC__
+ asm("ics");
+#else
+ __isync();
+#endif
+
+ ret = fetch_and_add((atomic_p)p, (int)val);
+
+#ifdef __GNUC__
+ asm("ics");
+#else
+ __isync();
+#endif
+
+ return (ret);
+}
+
+#ifdef __GNUC__
static inline int
#else
static int
#endif
isc_atomic_cmpxchg(atomic_p p, int old, int new) {
- int orig = old;
+ int orig = old;
#ifdef __GNUC__
- asm("ics");
+ asm("ics");
#else
- __isync();
+ __isync();
#endif
- if (compare_and_swap(p, &orig, new))
- return (old);
- return (orig);
+ if (compare_and_swap(p, &orig, new))
+ orig = old;
+
+#ifdef __GNUC__
+ asm("ics");
+#else
+ __isync();
+#endif
+
+ return (orig);
}
#elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM)
@@ -76,14 +107,14 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
#ifdef ISC_PLATFORM_USEMACASM
"1:"
"lwarx r6, 0, %1\n"
- "mr %0, r6\n"
+ "mr %0, r6\n"
"add r6, r6, %2\n"
"stwcx. r6, 0, %1\n"
"bne- 1b"
#else
"1:"
"lwarx 6, 0, %1\n"
- "mr %0, 6\n"
+ "mr %0, 6\n"
"add 6, 6, %2\n"
"stwcx. 6, 0, %1\n"
"bne- 1b"
diff --git a/contrib/bind9/lib/isc/random.c b/contrib/bind9/lib/isc/random.c
index 0329abd..84ba6a0 100644
--- a/contrib/bind9/lib/isc/random.c
+++ b/contrib/bind9/lib/isc/random.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: random.c,v 1.25 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: random.c,v 1.25.332.2 2009/07/16 23:47:17 tbox Exp $ */
/*! \file */
@@ -43,7 +43,7 @@ initialize_rand(void)
{
#ifndef HAVE_ARC4RANDOM
unsigned int pid = getpid();
-
+
/*
* The low bits of pid generally change faster.
* Xor them with the high bits of time which change slowly.
@@ -84,7 +84,16 @@ isc_random_get(isc_uint32_t *val)
* rand()'s lower bits are not random.
* rand()'s upper bit is zero.
*/
+#if RAND_MAX >= 0xfffff
+ /* We have at least 20 bits. Use lower 16 excluding lower most 4 */
*val = ((rand() >> 4) & 0xffff) | ((rand() << 12) & 0xffff0000);
+#elif RAND_MAX >= 0x7fff
+ /* We have at least 15 bits. Use lower 10/11 excluding lower most 4 */
+ *val = ((rand() >> 4) & 0x000007ff) | ((rand() << 7) & 0x003ff800) |
+ ((rand() << 18) & 0xffc00000);
+#else
+#error RAND_MAX is too small
+#endif
#else
*val = arc4random();
#endif
@@ -92,13 +101,13 @@ isc_random_get(isc_uint32_t *val)
isc_uint32_t
isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) {
+ isc_uint32_t rnd;
+
REQUIRE(jitter < max);
+
if (jitter == 0)
return (max);
- else
-#ifndef HAVE_ARC4RANDOM
- return (max - rand() % jitter);
-#else
- return (max - arc4random() % jitter);
-#endif
+
+ isc_random_get(&rnd);
+ return (max - rnd % jitter);
}
diff --git a/contrib/bind9/lib/isc/sha2.c b/contrib/bind9/lib/isc/sha2.c
index 70eea4f..ff19274 100644
--- a/contrib/bind9/lib/isc/sha2.c
+++ b/contrib/bind9/lib/isc/sha2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sha2.c,v 1.13.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: sha2.c,v 1.13.332.4 2010/01/15 23:47:34 tbox Exp $ */
/* $FreeBSD$ */
/* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */
@@ -415,6 +415,11 @@ isc_sha224_init(isc_sha224_t *context) {
}
void
+isc_sha224_invalidate(isc_sha224_t *context) {
+ memset(context, 0, sizeof(isc_sha224_t));
+}
+
+void
isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
isc_sha256_update((isc_sha256_t *)context, data, len);
}
@@ -651,6 +656,11 @@ isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) {
#endif /* ISC_SHA2_UNROLL_TRANSFORM */
void
+isc_sha256_invalidate(isc_sha256_t *context) {
+ memset(context, 0, sizeof(isc_sha256_t));
+}
+
+void
isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
unsigned int freespace, usedspace;
@@ -990,7 +1000,13 @@ isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {
#endif /* ISC_SHA2_UNROLL_TRANSFORM */
-void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
+void
+isc_sha512_invalidate(isc_sha512_t *context) {
+ memset(context, 0, sizeof(isc_sha512_t));
+}
+
+void
+isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
unsigned int freespace, usedspace;
if (len == 0U) {
@@ -1164,6 +1180,11 @@ isc_sha384_init(isc_sha384_t *context) {
}
void
+isc_sha384_invalidate(isc_sha384_t *context) {
+ memset(context, 0, sizeof(isc_sha384_t));
+}
+
+void
isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
isc_sha512_update((isc_sha512_t *)context, data, len);
}
diff --git a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c
index b576d46..87ef9ba 100644
--- a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c
+++ b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ifiter_getifaddrs.c,v 1.11 2008/03/20 23:47:00 tbox Exp $ */
+/* $Id: ifiter_getifaddrs.c,v 1.11.120.2 2009/09/24 23:47:34 tbox Exp $ */
/*! \file
* \brief
@@ -181,7 +181,7 @@ internal_current(isc_interfaceiter_t *iter) {
ifa->ifa_name);
if (ifa->ifa_dstaddr != NULL &&
- (iter->current.flags & IFF_POINTOPOINT) != 0)
+ (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr,
ifa->ifa_name);
diff --git a/contrib/bind9/lib/isc/unix/socket.c b/contrib/bind9/lib/isc/unix/socket.c
index d09fe51..004a038 100644
--- a/contrib/bind9/lib/isc/unix/socket.c
+++ b/contrib/bind9/lib/isc/unix/socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.308.12.8 2009/04/18 01:29:26 jinmei Exp $ */
+/* $Id: socket.c,v 1.308.12.12 2010/01/31 23:47:31 tbox Exp $ */
/*! \file */
@@ -1520,12 +1520,22 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
}
/*
- * On TCP, zero length reads indicate EOF, while on
- * UDP, zero length reads are perfectly valid, although
- * strange.
+ * On TCP and UNIX sockets, zero length reads indicate EOF,
+ * while on UDP sockets, zero length reads are perfectly valid,
+ * although strange.
*/
- if ((sock->type == isc_sockettype_tcp) && (cc == 0))
- return (DOIO_EOF);
+ switch (sock->type) {
+ case isc_sockettype_tcp:
+ case isc_sockettype_unix:
+ if (cc == 0)
+ return (DOIO_EOF);
+ break;
+ case isc_sockettype_udp:
+ break;
+ case isc_sockettype_fdwatch:
+ default:
+ INSIST(0);
+ }
if (sock->type == isc_sockettype_udp) {
dev->address.length = msghdr.msg_namelen;
@@ -3645,7 +3655,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
manager->maxsocks);
if (manager->fdpollinfo == NULL) {
isc_mem_put(mctx, manager->events,
- sizeof(pollinfo_t) * manager->maxsocks);
+ sizeof(struct pollfd) * manager->nevents);
return (ISC_R_NOMEMORY);
}
memset(manager->fdpollinfo, 0, sizeof(pollinfo_t) * manager->maxsocks);
@@ -4851,6 +4861,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
isc_socketmgr_t *manager;
int cc;
char strbuf[ISC_STRERRORSIZE];
+ char addrbuf[ISC_SOCKADDR_FORMATSIZE];
REQUIRE(VALID_SOCKET(sock));
REQUIRE(addr != NULL);
@@ -4919,7 +4930,9 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
sock->connected = 0;
isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__, "%d/%s", errno, strbuf);
+ isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "connect(%s) %d/%s",
+ addrbuf, errno, strbuf);
UNLOCK(&sock->lock);
inc_stats(sock->manager->stats,
diff --git a/contrib/bind9/lib/isccc/api b/contrib/bind9/lib/isccc/api
index 8459d42..2240cdd 100644
--- a/contrib/bind9/lib/isccc/api
+++ b/contrib/bind9/lib/isccc/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 50
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
diff --git a/contrib/bind9/lib/isccfg/aclconf.c b/contrib/bind9/lib/isccfg/aclconf.c
index ad3d58e..92839e4 100644
--- a/contrib/bind9/lib/isccfg/aclconf.c
+++ b/contrib/bind9/lib/isccfg/aclconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: aclconf.c,v 1.22.34.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: aclconf.c,v 1.22.34.4 2009/10/01 23:47:17 tbox Exp $ */
#include <config.h>
@@ -168,26 +168,36 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx,
* parent.
*/
static int
-count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx)
+count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_boolean_t *has_negative)
{
const cfg_listelt_t *elt;
const cfg_obj_t *cacl = NULL;
isc_result_t result;
int n = 0;
+ if (has_negative != NULL)
+ *has_negative = ISC_FALSE;
+
for (elt = cfg_list_first(caml);
elt != NULL;
elt = cfg_list_next(elt)) {
const cfg_obj_t *ce = cfg_listelt_value(elt);
/* negated element; just get the value. */
- if (cfg_obj_istuple(ce))
+ if (cfg_obj_istuple(ce)) {
ce = cfg_tuple_get(ce, "value");
+ if (has_negative != NULL)
+ *has_negative = ISC_TRUE;
+ }
if (cfg_obj_istype(ce, &cfg_type_keyref)) {
n++;
} else if (cfg_obj_islist(ce)) {
- n += count_acl_elements(ce, cctx);
+ isc_boolean_t negative;
+ n += count_acl_elements(ce, cctx, &negative);
+ if (negative)
+ n++;
} else if (cfg_obj_isstring(ce)) {
const char *name = cfg_obj_asstring(ce);
if (strcasecmp(name, "localhost") == 0 ||
@@ -197,7 +207,8 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx)
strcasecmp(name, "none") != 0) {
result = get_acl_def(cctx, name, &cacl);
if (result == ISC_R_SUCCESS)
- n += count_acl_elements(cacl, cctx) + 1;
+ n += count_acl_elements(cacl, cctx,
+ NULL) + 1;
}
}
}
@@ -246,7 +257,7 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
int nelem;
if (nest_level == 0)
- nelem = count_acl_elements(caml, cctx);
+ nelem = count_acl_elements(caml, cctx, NULL);
else
nelem = cfg_list_length(caml, ISC_FALSE);
diff --git a/contrib/bind9/lib/isccfg/api b/contrib/bind9/lib/isccfg/api
index 8459d42..2240cdd 100644
--- a/contrib/bind9/lib/isccfg/api
+++ b/contrib/bind9/lib/isccfg/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 50
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
diff --git a/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h b/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h
index 9689a2a..55c5a81 100644
--- a/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h
+++ b/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.h,v 1.9 2007/06/19 23:47:22 tbox Exp $ */
+/* $Id: namedconf.h,v 1.9.332.2 2009/06/25 23:47:28 tbox Exp $ */
#ifndef ISCCFG_NAMEDCONF_H
#define ISCCFG_NAMEDCONF_H 1
@@ -42,4 +42,4 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
/*%< A key reference, used as an ACL element */
-#endif /* ISCCFG_CFG_H */
+#endif /* ISCCFG_NAMEDCONF_H */
diff --git a/contrib/bind9/lib/lwres/api b/contrib/bind9/lib/lwres/api
index 39934b4..fbbf923 100644
--- a/contrib/bind9/lib/lwres/api
+++ b/contrib/bind9/lib/lwres/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 50
-LIBREVISION = 2
+LIBREVISION = 3
LIBAGE = 0
diff --git a/contrib/bind9/lib/lwres/context.c b/contrib/bind9/lib/lwres/context.c
index 464a2cf..d042c87 100644
--- a/contrib/bind9/lib/lwres/context.c
+++ b/contrib/bind9/lib/lwres/context.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: context.c,v 1.50.332.2 2008/12/30 23:46:49 tbox Exp $ */
+/* $Id: context.c,v 1.50.332.5 2009/09/01 23:47:05 tbox Exp $ */
/*! \file context.c
lwres_context_create() creates a #lwres_context_t structure for use in
@@ -471,6 +471,17 @@ lwres_context_sendrecv(lwres_context_t *ctx,
result = lwres_context_send(ctx, sendbase, sendlen);
if (result != LWRES_R_SUCCESS)
return (result);
+
+ /*
+ * If this is not checked, select() can overflow,
+ * causing corruption elsewhere.
+ */
+ if (ctx->sock >= (int)FD_SETSIZE) {
+ close(ctx->sock);
+ ctx->sock = -1;
+ return (LWRES_R_IOERROR);
+ }
+
again:
FD_ZERO(&readfds);
FD_SET(ctx->sock, &readfds);
diff --git a/contrib/bind9/lib/lwres/getipnode.c b/contrib/bind9/lib/lwres/getipnode.c
index a6c50c2..4331638 100644
--- a/contrib/bind9/lib/lwres/getipnode.c
+++ b/contrib/bind9/lib/lwres/getipnode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getipnode.c,v 1.42 2007/06/18 23:47:51 tbox Exp $ */
+/* $Id: getipnode.c,v 1.42.332.5 2009/09/01 23:47:05 tbox Exp $ */
/*! \file */
@@ -23,7 +23,7 @@
* These functions perform thread safe, protocol independent
* nodename-to-address and address-to-nodename translation as defined in
* RFC2553. This use a struct hostent which is defined in namedb.h:
- *
+ *
* \code
* struct hostent {
* char *h_name; // official name of host
@@ -34,90 +34,90 @@
* };
* #define h_addr h_addr_list[0] // address, for backward compatibility
* \endcode
- *
+ *
* The members of this structure are:
- *
+ *
* \li h_name:
* The official (canonical) name of the host.
- *
+ *
* \li h_aliases:
* A NULL-terminated array of alternate names (nicknames) for the
* host.
- *
+ *
* \li h_addrtype:
* The type of address being returned - usually PF_INET or
* PF_INET6.
- *
+ *
* \li h_length:
* The length of the address in bytes.
- *
+ *
* \li h_addr_list:
* A NULL terminated array of network addresses for the host. Host
* addresses are returned in network byte order.
- *
+ *
* lwres_getipnodebyname() looks up addresses of protocol family af for
* the hostname name. The flags parameter contains ORed flag bits to
* specify the types of addresses that are searched for, and the types of
* addresses that are returned. The flag bits are:
- *
+ *
* \li #AI_V4MAPPED:
* This is used with an af of #AF_INET6, and causes IPv4 addresses
* to be returned as IPv4-mapped IPv6 addresses.
- *
+ *
* \li #AI_ALL:
* This is used with an af of #AF_INET6, and causes all known
* addresses (IPv6 and IPv4) to be returned. If #AI_V4MAPPED is
* also set, the IPv4 addresses are return as mapped IPv6
* addresses.
- *
+ *
* \li #AI_ADDRCONFIG:
* Only return an IPv6 or IPv4 address if here is an active
* network interface of that type. This is not currently
* implemented in the BIND 9 lightweight resolver, and the flag is
* ignored.
- *
+ *
* \li #AI_DEFAULT:
* This default sets the #AI_V4MAPPED and #AI_ADDRCONFIG flag bits.
- *
+ *
* lwres_getipnodebyaddr() performs a reverse lookup of address src which
* is len bytes long. af denotes the protocol family, typically PF_INET
* or PF_INET6.
- *
+ *
* lwres_freehostent() releases all the memory associated with the struct
* hostent pointer. Any memory allocated for the h_name, h_addr_list
* and h_aliases is freed, as is the memory for the hostent structure
* itself.
- *
+ *
* \section getipnode_return Return Values
- *
+ *
* If an error occurs, lwres_getipnodebyname() and
* lwres_getipnodebyaddr() set *error_num to an appropriate error code
* and the function returns a NULL pointer. The error codes and their
* meanings are defined in \link netdb.h <lwres/netdb.h>\endlink:
- *
+ *
* \li #HOST_NOT_FOUND:
* No such host is known.
- *
+ *
* \li #NO_ADDRESS:
* The server recognised the request and the name but no address
* is available. Another type of request to the name server for
* the domain might return an answer.
- *
+ *
* \li #TRY_AGAIN:
* A temporary and possibly transient error occurred, such as a
* failure of a server to respond. The request may succeed if
* retried.
- *
+ *
* \li #NO_RECOVERY:
* An unexpected failure occurred, and retrying the request is
* pointless.
- *
+ *
* lwres_hstrerror() translates these error codes to suitable error
* messages.
- *
+ *
* \section getipnode_see See Also
- *
- * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
+ *
+ * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553
*/
#include <config.h>
@@ -146,21 +146,21 @@ LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#ifndef IN6_IS_ADDR_V4COMPAT
static const unsigned char in6addr_compat[12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
- ((x)->s6_addr[12] != 0 || \
- (x)->s6_addr[13] != 0 || \
- (x)->s6_addr[14] != 0 || \
- ((x)->s6_addr[15] != 0 && \
- (x)->s6_addr[15] != 1)))
+ ((x)->s6_addr[12] != 0 || \
+ (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && \
+ (x)->s6_addr[15] != 1)))
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
#endif
static const unsigned char in6addr_mapped[12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
};
/***
@@ -202,7 +202,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
struct in6_addr in6;
struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
int v4 = 0, v6 = 0;
- int tmp_err;
+ int tmp_err = 0;
lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL;
int n;
@@ -275,7 +275,6 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
tmp_err = NO_RECOVERY;
if (have_v6 && af == AF_INET6) {
-
n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
if (n == 0) {
he1 = hostfromname(by, AF_INET6);
@@ -285,7 +284,12 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
goto cleanup;
}
} else {
- tmp_err = HOST_NOT_FOUND;
+ if (n == LWRES_R_NOTFOUND)
+ tmp_err = HOST_NOT_FOUND;
+ else {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
}
}
@@ -437,9 +441,15 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
if (n != 0) {
lwres_conf_clear(lwrctx);
lwres_context_destroy(&lwrctx);
- *error_num = HOST_NOT_FOUND;
+
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+
return (NULL);
}
+
he1 = hostfromaddr(by, AF_INET6, src);
lwres_gnbaresponse_free(lwrctx, &by);
if (he1 == NULL)
@@ -492,7 +502,7 @@ lwres_freehostent(struct hostent *he) {
*/
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
- !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
+ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
#ifdef __hpux
#define lifc_len iflc_len
@@ -504,7 +514,7 @@ lwres_freehostent(struct hostent *he) {
#define ISC_HAVE_LIFC_FLAGS 1
#define LIFCONF lifconf
#endif
-
+
#ifdef __hpux
#define lifr_addr iflr_addr
#define lifr_name iflr_name
@@ -557,7 +567,7 @@ scan_interfaces6(int *have_v4, int *have_v6) {
/*
* Some OS's just return what will fit rather
* than set EINVAL if the buffer is too small
- * to fit all the interfaces in. If
+ * to fit all the interfaces in. If
* lifc.lifc_len is too near to the end of the
* buffer we will grow it just in case and
* retry.
@@ -619,13 +629,13 @@ scan_interfaces6(int *have_v4, int *have_v6) {
if ((lifreq.lifr_flags & IFF_UP) == 0)
break;
*have_v4 = 1;
- }
+ }
break;
case AF_INET6:
if (*have_v6 == 0) {
memcpy(&in6,
&((struct sockaddr_in6 *)
- &lifreq.lifr_addr)->sin6_addr,
+ &lifreq.lifr_addr)->sin6_addr,
sizeof(in6));
if (memcmp(&in6, &in6addr_any,
sizeof(in6)) == 0)
@@ -675,7 +685,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
InitSockets();
#endif
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
- !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
+ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
/*
* Try to scan the interfaces using IPv6 ioctls().
*/
@@ -721,7 +731,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
/*
* Some OS's just return what will fit rather
* than set EINVAL if the buffer is too small
- * to fit all the interfaces in. If
+ * to fit all the interfaces in. If
* ifc.ifc_len is too near to the end of the
* buffer we will grow it just in case and
* retry.
@@ -786,7 +796,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
if ((u.ifreq.ifr_flags & IFF_UP) == 0)
break;
*have_v4 = 1;
- }
+ }
break;
case AF_INET6:
if (*have_v6 == 0) {
diff --git a/contrib/bind9/lib/lwres/man/lwres.3 b/contrib/bind9/lib/lwres/man/lwres.3
index e1f8793..14c719a 100644
--- a/contrib/bind9/lib/lwres/man/lwres.3
+++ b/contrib/bind9/lib/lwres/man/lwres.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres.3,v 1.28 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres.html b/contrib/bind9/lib/lwres/man/lwres.html
index 986918a..465b876 100644
--- a/contrib/bind9/lib/lwres/man/lwres.html
+++ b/contrib/bind9/lib/lwres/man/lwres.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres.html,v 1.23.514.1 2009/12/31 23:17:47 tbox Exp $ -->
+<!-- $Id: lwres.html,v 1.23.418.1.8.1 2010/02/25 12:16:40 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_buffer.3 b/contrib/bind9/lib/lwres/man/lwres_buffer.3
index cc0959d..e8fe631 100644
--- a/contrib/bind9/lib/lwres/man/lwres_buffer.3
+++ b/contrib/bind9/lib/lwres/man/lwres_buffer.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_buffer.3,v 1.26 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_buffer.3,v 1.26.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_buffer.html b/contrib/bind9/lib/lwres/man/lwres_buffer.html
index 7ed5407..80fd383 100644
--- a/contrib/bind9/lib/lwres/man/lwres_buffer.html
+++ b/contrib/bind9/lib/lwres/man/lwres_buffer.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_buffer.html,v 1.21.514.1 2009/12/31 23:17:47 tbox Exp $ -->
+<!-- $Id: lwres_buffer.html,v 1.21.418.1.8.1 2010/02/25 12:16:40 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_config.3 b/contrib/bind9/lib/lwres/man/lwres_config.3
index 6184cb2..2d3b813 100644
--- a/contrib/bind9/lib/lwres/man/lwres_config.3
+++ b/contrib/bind9/lib/lwres/man/lwres_config.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_config.3,v 1.26 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_config.3,v 1.26.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_config.html b/contrib/bind9/lib/lwres/man/lwres_config.html
index 050fd5d..055ae91 100644
--- a/contrib/bind9/lib/lwres/man/lwres_config.html
+++ b/contrib/bind9/lib/lwres/man/lwres_config.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_config.html,v 1.22.514.1 2009/12/31 23:17:47 tbox Exp $ -->
+<!-- $Id: lwres_config.html,v 1.22.418.1.8.1 2010/02/25 12:16:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_context.3 b/contrib/bind9/lib/lwres/man/lwres_context.3
index b1022d8..dae7ee5 100644
--- a/contrib/bind9/lib/lwres/man/lwres_context.3
+++ b/contrib/bind9/lib/lwres/man/lwres_context.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_context.3,v 1.28 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_context.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_context.html b/contrib/bind9/lib/lwres/man/lwres_context.html
index d6fada9..d86e508 100644
--- a/contrib/bind9/lib/lwres/man/lwres_context.html
+++ b/contrib/bind9/lib/lwres/man/lwres_context.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_context.html,v 1.23.514.1 2009/12/31 23:17:47 tbox Exp $ -->
+<!-- $Id: lwres_context.html,v 1.23.418.1.8.1 2010/02/25 12:16:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_gabn.3 b/contrib/bind9/lib/lwres/man/lwres_gabn.3
index 0c14384..64846d1 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gabn.3
+++ b/contrib/bind9/lib/lwres/man/lwres_gabn.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gabn.3,v 1.27 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_gabn.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_gabn.html b/contrib/bind9/lib/lwres/man/lwres_gabn.html
index efb152a3..91734dd 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gabn.html
+++ b/contrib/bind9/lib/lwres/man/lwres_gabn.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gabn.html,v 1.24.514.1 2009/12/31 23:17:47 tbox Exp $ -->
+<!-- $Id: lwres_gabn.html,v 1.24.418.1.8.1 2010/02/25 12:16:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3
index e412b8f..46b54c0 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3
+++ b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gai_strerror.3,v 1.27 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_gai_strerror.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html
index aeb0967..03b67b8 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html
+++ b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gai_strerror.html,v 1.24.514.1 2009/12/31 23:17:48 tbox Exp $ -->
+<!-- $Id: lwres_gai_strerror.html,v 1.24.418.1.8.1 2010/02/25 12:16:43 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3
index 7a1b5d7..edac051 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3
+++ b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getaddrinfo.3,v 1.31 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_getaddrinfo.3,v 1.31.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html
index ec00839..5d02f4b 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html
+++ b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getaddrinfo.html,v 1.27.514.1 2009/12/31 23:17:48 tbox Exp $ -->
+<!-- $Id: lwres_getaddrinfo.html,v 1.27.418.1.8.1 2010/02/25 12:16:43 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_gethostent.3 b/contrib/bind9/lib/lwres/man/lwres_gethostent.3
index 847d882..688c618 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gethostent.3
+++ b/contrib/bind9/lib/lwres/man/lwres_gethostent.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gethostent.3,v 1.29 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_gethostent.3,v 1.29.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_gethostent.html b/contrib/bind9/lib/lwres/man/lwres_gethostent.html
index 9465440..576c8d9 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gethostent.html
+++ b/contrib/bind9/lib/lwres/man/lwres_gethostent.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gethostent.html,v 1.24.514.1 2009/12/31 23:17:52 tbox Exp $ -->
+<!-- $Id: lwres_gethostent.html,v 1.24.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_getipnode.3 b/contrib/bind9/lib/lwres/man/lwres_getipnode.3
index e5c51a9..b74b342 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getipnode.3
+++ b/contrib/bind9/lib/lwres/man/lwres_getipnode.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getipnode.3,v 1.28 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_getipnode.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_getipnode.html b/contrib/bind9/lib/lwres/man/lwres_getipnode.html
index c92c51c..9acc616 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getipnode.html
+++ b/contrib/bind9/lib/lwres/man/lwres_getipnode.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getipnode.html,v 1.25.514.1 2009/12/31 23:17:52 tbox Exp $ -->
+<!-- $Id: lwres_getipnode.html,v 1.25.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3
index c477f79..d77776b 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3
+++ b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getnameinfo.3,v 1.29 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_getnameinfo.3,v 1.29.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html
index 7730131..8b84397 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html
+++ b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getnameinfo.html,v 1.23.514.1 2009/12/31 23:17:52 tbox Exp $ -->
+<!-- $Id: lwres_getnameinfo.html,v 1.23.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3
index 8419fff..bda5aa2 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3
+++ b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getrrsetbyname.3,v 1.25 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_getrrsetbyname.3,v 1.25.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html
index 15bfb82..14f1e65 100644
--- a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html
+++ b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getrrsetbyname.html,v 1.23.514.1 2009/12/31 23:17:53 tbox Exp $ -->
+<!-- $Id: lwres_getrrsetbyname.html,v 1.23.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_gnba.3 b/contrib/bind9/lib/lwres/man/lwres_gnba.3
index 39a1b9d..e04fa8f 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gnba.3
+++ b/contrib/bind9/lib/lwres/man/lwres_gnba.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gnba.3,v 1.27 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_gnba.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_gnba.html b/contrib/bind9/lib/lwres/man/lwres_gnba.html
index 80c909e..368a848 100644
--- a/contrib/bind9/lib/lwres/man/lwres_gnba.html
+++ b/contrib/bind9/lib/lwres/man/lwres_gnba.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gnba.html,v 1.24.514.1 2009/12/31 23:17:47 tbox Exp $ -->
+<!-- $Id: lwres_gnba.html,v 1.24.418.1.8.1 2010/02/25 12:16:42 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_hstrerror.3 b/contrib/bind9/lib/lwres/man/lwres_hstrerror.3
index 5998238..badb5fe 100644
--- a/contrib/bind9/lib/lwres/man/lwres_hstrerror.3
+++ b/contrib/bind9/lib/lwres/man/lwres_hstrerror.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_hstrerror.3,v 1.27 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_hstrerror.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_hstrerror.html b/contrib/bind9/lib/lwres/man/lwres_hstrerror.html
index b166e3d..1ca798d 100644
--- a/contrib/bind9/lib/lwres/man/lwres_hstrerror.html
+++ b/contrib/bind9/lib/lwres/man/lwres_hstrerror.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_hstrerror.html,v 1.23.514.1 2009/12/31 23:17:54 tbox Exp $ -->
+<!-- $Id: lwres_hstrerror.html,v 1.23.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_inetntop.3 b/contrib/bind9/lib/lwres/man/lwres_inetntop.3
index c7d3d12..1f9e097 100644
--- a/contrib/bind9/lib/lwres/man/lwres_inetntop.3
+++ b/contrib/bind9/lib/lwres/man/lwres_inetntop.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_inetntop.3,v 1.26 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_inetntop.3,v 1.26.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_inetntop.html b/contrib/bind9/lib/lwres/man/lwres_inetntop.html
index 3522a1d..9535c35 100644
--- a/contrib/bind9/lib/lwres/man/lwres_inetntop.html
+++ b/contrib/bind9/lib/lwres/man/lwres_inetntop.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_inetntop.html,v 1.23.514.1 2009/12/31 23:17:48 tbox Exp $ -->
+<!-- $Id: lwres_inetntop.html,v 1.23.418.1.8.1 2010/02/25 12:16:43 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_noop.3 b/contrib/bind9/lib/lwres/man/lwres_noop.3
index 0e4ed71..6c39ce6 100644
--- a/contrib/bind9/lib/lwres/man/lwres_noop.3
+++ b/contrib/bind9/lib/lwres/man/lwres_noop.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_noop.3,v 1.28 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_noop.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_noop.html b/contrib/bind9/lib/lwres/man/lwres_noop.html
index 18a41fa..43539ad 100644
--- a/contrib/bind9/lib/lwres/man/lwres_noop.html
+++ b/contrib/bind9/lib/lwres/man/lwres_noop.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_noop.html,v 1.25.514.1 2009/12/31 23:17:54 tbox Exp $ -->
+<!-- $Id: lwres_noop.html,v 1.25.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_packet.3 b/contrib/bind9/lib/lwres/man/lwres_packet.3
index 1e1f98f..068d241 100644
--- a/contrib/bind9/lib/lwres/man/lwres_packet.3
+++ b/contrib/bind9/lib/lwres/man/lwres_packet.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_packet.3,v 1.29 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_packet.3,v 1.29.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_packet.html b/contrib/bind9/lib/lwres/man/lwres_packet.html
index 11601e8..985e5f6 100644
--- a/contrib/bind9/lib/lwres/man/lwres_packet.html
+++ b/contrib/bind9/lib/lwres/man/lwres_packet.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_packet.html,v 1.26.514.1 2009/12/31 23:17:54 tbox Exp $ -->
+<!-- $Id: lwres_packet.html,v 1.26.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/lib/lwres/man/lwres_resutil.3 b/contrib/bind9/lib/lwres/man/lwres_resutil.3
index d26f77c..2297cb7 100644
--- a/contrib/bind9/lib/lwres/man/lwres_resutil.3
+++ b/contrib/bind9/lib/lwres/man/lwres_resutil.3
@@ -1,7 +1,7 @@
.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
.\"
-.\" Permission to use, copy, modify, and distribute this software for any
+.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_resutil.3,v 1.28 2007/01/30 00:24:59 marka Exp $
+.\" $Id: lwres_resutil.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/contrib/bind9/lib/lwres/man/lwres_resutil.html b/contrib/bind9/lib/lwres/man/lwres_resutil.html
index e67ac0a..e11aa6f 100644
--- a/contrib/bind9/lib/lwres/man/lwres_resutil.html
+++ b/contrib/bind9/lib/lwres/man/lwres_resutil.html
@@ -2,7 +2,7 @@
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
-
- - Permission to use, copy, modify, and distribute this software for any
+ - Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_resutil.html,v 1.25.514.1 2009/12/31 23:17:54 tbox Exp $ -->
+<!-- $Id: lwres_resutil.html,v 1.25.418.1.8.1 2010/02/25 12:16:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/contrib/bind9/version b/contrib/bind9/version
index c6fcc3f..79bbd49 100644
--- a/contrib/bind9/version
+++ b/contrib/bind9/version
@@ -1,10 +1,10 @@
-# $Id: version,v 1.43.12.5.8.3 2009/12/31 20:29:20 each Exp $
+# $Id: version,v 1.43.12.8.2.3 2010/03/04 00:08:28 marka Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
#
MAJORVER=9
MINORVER=6
-PATCHVER=1
+PATCHVER=2
RELEASETYPE=-P
-RELEASEVER=3
+RELEASEVER=1
diff --git a/contrib/binutils/bfd/config.bfd b/contrib/binutils/bfd/config.bfd
index 034da18..5f115f0 100755
--- a/contrib/binutils/bfd/config.bfd
+++ b/contrib/binutils/bfd/config.bfd
@@ -221,6 +221,10 @@ case "${targ}" in
targ_defvec=bfd_elf32_littlearm_vec
targ_selvecs=bfd_elf32_bigarm_vec
;;
+ armeb-*-freebsd*)
+ targ_defvec=bfd_elf32_bigarm_vec
+ targ_selvecs=bfd_elf32_littlearm_vec
+ ;;
arm-*-elf | arm-*-freebsd* | arm*-*-linux-gnu* | arm*-*-conix* | \
arm*-*-uclinux* | arm-*-kfreebsd*-gnu | arm-*-vxworks)
targ_defvec=bfd_elf32_littlearm_vec
diff --git a/contrib/bsnmp/gensnmpdef/gensnmpdef.c b/contrib/bsnmp/gensnmpdef/gensnmpdef.c
index 55c02c7..e4f1e5c 100644
--- a/contrib/bsnmp/gensnmpdef/gensnmpdef.c
+++ b/contrib/bsnmp/gensnmpdef/gensnmpdef.c
@@ -59,7 +59,7 @@ struct tdef {
SLIST_ENTRY(tdef) link;
};
-static SLIST_HEAD(, tdef) tdefs = SLIST_HEAD_INITIALIZER(tdef);
+static SLIST_HEAD(, tdef) tdefs = SLIST_HEAD_INITIALIZER(tdefs);
static int do_typedef = 0;
static void print_node(SmiNode *n, u_int level);
diff --git a/contrib/bsnmp/gensnmptree/gensnmptree.1 b/contrib/bsnmp/gensnmptree/gensnmptree.1
index 930f426..a4d2a80 100644
--- a/contrib/bsnmp/gensnmptree/gensnmptree.1
+++ b/contrib/bsnmp/gensnmptree/gensnmptree.1
@@ -58,7 +58,7 @@ If none of the options
.Fl e ,
.Fl E
or
-.FL t
+.Fl t
are used
.Nm
reads a MIB description from its standard input and creates two files: a
diff --git a/contrib/bsnmp/snmpd/config.c b/contrib/bsnmp/snmpd/config.c
index 6480d20..48044ec 100644
--- a/contrib/bsnmp/snmpd/config.c
+++ b/contrib/bsnmp/snmpd/config.c
@@ -134,7 +134,7 @@ struct macro {
LIST_ENTRY(macro) link;
int perm;
};
-static LIST_HEAD(, macro) macros = LIST_HEAD_INITIALIZER(&macros);
+static LIST_HEAD(, macro) macros = LIST_HEAD_INITIALIZER(macros);
enum {
TOK_EOF = 0200,
diff --git a/contrib/bsnmp/snmpd/snmpmod.3 b/contrib/bsnmp/snmpd/snmpmod.3
index 3ca067a..176fb47 100644
--- a/contrib/bsnmp/snmpd/snmpmod.3
+++ b/contrib/bsnmp/snmpd/snmpmod.3
@@ -777,7 +777,8 @@ is used for GET or GETNEXT.
The function
.It Fn string_get_max
can be used instead of
-.Nf stringto ensure that the returned string has a certain maximum length.
+.Fn string_get
+to ensure that the returned string has a certain maximum length.
If
.Fa len
is -1, the length is computed via
diff --git a/contrib/com_err/compile_et.1 b/contrib/com_err/compile_et.1
index bdc608b..32f2eee 100644
--- a/contrib/com_err/compile_et.1
+++ b/contrib/com_err/compile_et.1
@@ -4,8 +4,8 @@
.\" $FreeBSD$
.\"
.Dd November 22, 1988
-.Os
.Dt COMPILE_ET 1
+.Os
.Sh NAME
.Nm compile_et
.Nd error table compiler
diff --git a/contrib/cpio/ABOUT-NLS b/contrib/cpio/ABOUT-NLS
deleted file mode 100644
index ec20977..0000000
--- a/contrib/cpio/ABOUT-NLS
+++ /dev/null
@@ -1,1101 +0,0 @@
-1 Notes on the Free Translation Project
-***************************************
-
-Free software is going international! The Free Translation Project is
-a way to get maintainers of free software, translators, and users all
-together, so that free software will gradually become able to speak many
-languages. A few packages already provide translations for their
-messages.
-
- If you found this `ABOUT-NLS' file inside a distribution, you may
-assume that the distributed package does use GNU `gettext' internally,
-itself available at your nearest GNU archive site. But you do _not_
-need to install GNU `gettext' prior to configuring, installing or using
-this package with messages translated.
-
- Installers will find here some useful hints. These notes also
-explain how users should proceed for getting the programs to use the
-available translations. They tell how people wanting to contribute and
-work on translations can contact the appropriate team.
-
- When reporting bugs in the `intl/' directory or bugs which may be
-related to internationalization, you should tell about the version of
-`gettext' which is used. The information can be found in the
-`intl/VERSION' file, in internationalized packages.
-
-1.1 Quick configuration advice
-==============================
-
-If you want to exploit the full power of internationalization, you
-should configure it using
-
- ./configure --with-included-gettext
-
-to force usage of internationalizing routines provided within this
-package, despite the existence of internationalizing capabilities in the
-operating system where this package is being installed. So far, only
-the `gettext' implementation in the GNU C library version 2 provides as
-many features (such as locale alias, message inheritance, automatic
-charset conversion or plural form handling) as the implementation here.
-It is also not possible to offer this additional functionality on top
-of a `catgets' implementation. Future versions of GNU `gettext' will
-very likely convey even more functionality. So it might be a good idea
-to change to GNU `gettext' as soon as possible.
-
- So you need _not_ provide this option if you are using GNU libc 2 or
-you have installed a recent copy of the GNU gettext package with the
-included `libintl'.
-
-1.2 INSTALL Matters
-===================
-
-Some packages are "localizable" when properly installed; the programs
-they contain can be made to speak your own native language. Most such
-packages use GNU `gettext'. Other packages have their own ways to
-internationalization, predating GNU `gettext'.
-
- By default, this package will be installed to allow translation of
-messages. It will automatically detect whether the system already
-provides the GNU `gettext' functions. If not, the included GNU
-`gettext' library will be used. This library is wholly contained
-within this package, usually in the `intl/' subdirectory, so prior
-installation of the GNU `gettext' package is _not_ required.
-Installers may use special options at configuration time for changing
-the default behaviour. The commands:
-
- ./configure --with-included-gettext
- ./configure --disable-nls
-
-will, respectively, bypass any pre-existing `gettext' to use the
-internationalizing routines provided within this package, or else,
-_totally_ disable translation of messages.
-
- When you already have GNU `gettext' installed on your system and run
-configure without an option for your new package, `configure' will
-probably detect the previously built and installed `libintl.a' file and
-will decide to use this. This might not be desirable. You should use
-the more recent version of the GNU `gettext' library. I.e. if the file
-`intl/VERSION' shows that the library which comes with this package is
-more recent, you should use
-
- ./configure --with-included-gettext
-
-to prevent auto-detection.
-
- The configuration process will not test for the `catgets' function
-and therefore it will not be used. The reason is that even an
-emulation of `gettext' on top of `catgets' could not provide all the
-extensions of the GNU `gettext' library.
-
- Internationalized packages usually have many `po/LL.po' files, where
-LL gives an ISO 639 two-letter code identifying the language. Unless
-translations have been forbidden at `configure' time by using the
-`--disable-nls' switch, all available translations are installed
-together with the package. However, the environment variable `LINGUAS'
-may be set, prior to configuration, to limit the installed set.
-`LINGUAS' should then contain a space separated list of two-letter
-codes, stating which languages are allowed.
-
-1.3 Using This Package
-======================
-
-As a user, if your language has been installed for this package, you
-only have to set the `LANG' environment variable to the appropriate
-`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
-and `CC' is an ISO 3166 two-letter country code. For example, let's
-suppose that you speak German and live in Germany. At the shell
-prompt, merely execute `setenv LANG de_DE' (in `csh'),
-`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
-This can be done from your `.login' or `.profile' file, once and for
-all.
-
- You might think that the country code specification is redundant.
-But in fact, some languages have dialects in different countries. For
-example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
-country code serves to distinguish the dialects.
-
- The locale naming convention of `LL_CC', with `LL' denoting the
-language and `CC' denoting the country, is the one use on systems based
-on GNU libc. On other systems, some variations of this scheme are
-used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
-locales supported by your system for your language by running the
-command `locale -a | grep '^LL''.
-
- Not all programs have translations for all languages. By default, an
-English message is shown in place of a nonexistent translation. If you
-understand other languages, you can set up a priority list of languages.
-This is done through a different environment variable, called
-`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
-for the purpose of message handling, but you still need to have `LANG'
-set to the primary language; this is required by other parts of the
-system libraries. For example, some Swedish users who would rather
-read translations in German than English for when Swedish is not
-available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
-
- Special advice for Norwegian users: The language code for Norwegian
-bokma*l changed from `no' to `nb' recently (in 2003). During the
-transition period, while some message catalogs for this language are
-installed under `nb' and some older ones under `no', it's recommended
-for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
-older translations are used.
-
- In the `LANGUAGE' environment variable, but not in the `LANG'
-environment variable, `LL_CC' combinations can be abbreviated as `LL'
-to denote the language's main dialect. For example, `de' is equivalent
-to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
-(Portuguese as spoken in Portugal) in this context.
-
-1.4 Translating Teams
-=====================
-
-For the Free Translation Project to be a success, we need interested
-people who like their own language and write it well, and who are also
-able to synergize with other translators speaking the same language.
-Each translation team has its own mailing list. The up-to-date list of
-teams can be found at the Free Translation Project's homepage,
-`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
-area.
-
- If you'd like to volunteer to _work_ at translating messages, you
-should become a member of the translating team for your own language.
-The subscribing address is _not_ the same as the list itself, it has
-`-request' appended. For example, speakers of Swedish can send a
-message to `sv-request@li.org', having this message body:
-
- subscribe
-
- Keep in mind that team members are expected to participate
-_actively_ in translations, or at solving translational difficulties,
-rather than merely lurking around. If your team does not exist yet and
-you want to start one, or if you are unsure about what to do or how to
-get started, please write to `translation@iro.umontreal.ca' to reach the
-coordinator for all translator teams.
-
- The English team is special. It works at improving and uniformizing
-the terminology in use. Proven linguistic skills are praised more than
-programming skills, here.
-
-1.5 Available Packages
-======================
-
-Languages are not equally supported in all packages. The following
-matrix shows the current state of internationalization, as of October
-2006. The matrix shows, in regard of each package, for which languages
-PO files have been submitted to translation coordination, with a
-translation percentage of at least 50%.
-
- Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB eo
- +----------------------------------------------------+
- GNUnet | [] |
- a2ps | [] [] [] [] [] |
- aegis | () |
- ant-phone | () |
- anubis | [] |
- ap-utils | |
- aspell | [] [] [] [] [] |
- bash | [] [] [] |
- batchelor | [] |
- bfd | |
- bibshelf | [] |
- binutils | [] |
- bison | [] [] |
- bison-runtime | |
- bluez-pin | [] [] [] [] [] |
- cflow | [] |
- clisp | [] [] |
- console-tools | [] [] |
- coreutils | [] [] [] |
- cpio | |
- cpplib | [] [] [] |
- cryptonit | [] |
- darkstat | [] () [] |
- dialog | [] [] [] [] [] [] |
- diffutils | [] [] [] [] [] [] |
- doodle | [] |
- e2fsprogs | [] [] |
- enscript | [] [] [] [] |
- error | [] [] [] [] |
- fetchmail | [] [] () [] |
- fileutils | [] [] |
- findutils | [] [] [] |
- flex | [] [] [] |
- fslint | [] |
- gas | |
- gawk | [] [] [] |
- gbiff | [] |
- gcal | [] |
- gcc | [] |
- gettext-examples | [] [] [] [] [] |
- gettext-runtime | [] [] [] [] [] |
- gettext-tools | [] [] |
- gimp-print | [] [] [] [] |
- gip | [] |
- gliv | [] |
- glunarclock | [] |
- gmult | [] [] |
- gnubiff | () |
- gnucash | () () [] |
- gnucash-glossary | [] () |
- gnuedu | |
- gnulib | [] [] [] [] [] [] |
- gnunet-gtk | |
- gnutls | |
- gpe-aerial | [] [] |
- gpe-beam | [] [] |
- gpe-calendar | |
- gpe-clock | [] [] |
- gpe-conf | [] [] |
- gpe-contacts | |
- gpe-edit | [] |
- gpe-filemanager | |
- gpe-go | [] |
- gpe-login | [] [] |
- gpe-ownerinfo | [] [] |
- gpe-package | |
- gpe-sketchbook | [] [] |
- gpe-su | [] [] |
- gpe-taskmanager | [] [] |
- gpe-timesheet | [] |
- gpe-today | [] [] |
- gpe-todo | |
- gphoto2 | [] [] [] [] |
- gprof | [] [] |
- gpsdrive | () () |
- gramadoir | [] [] |
- grep | [] [] [] [] [] [] |
- gretl | |
- gsasl | |
- gss | |
- gst-plugins | [] [] [] [] |
- gst-plugins-base | [] [] [] |
- gst-plugins-good | [] [] [] [] [] [] [] |
- gstreamer | [] [] [] [] [] [] [] |
- gtick | () |
- gtkam | [] [] [] |
- gtkorphan | [] [] |
- gtkspell | [] [] [] [] |
- gutenprint | [] |
- hello | [] [] [] [] [] |
- id-utils | [] [] |
- impost | |
- indent | [] [] [] |
- iso_3166 | [] [] |
- iso_3166_2 | |
- iso_4217 | [] |
- iso_639 | [] [] |
- jpilot | [] |
- jtag | |
- jwhois | |
- kbd | [] [] [] [] |
- keytouch | |
- keytouch-editor | |
- keytouch-keyboa... | |
- latrine | () |
- ld | [] |
- leafpad | [] [] [] [] [] |
- libc | [] [] [] [] [] |
- libexif | [] |
- libextractor | [] |
- libgpewidget | [] [] [] |
- libgpg-error | [] |
- libgphoto2 | [] [] |
- libgphoto2_port | [] [] |
- libgsasl | |
- libiconv | [] [] |
- libidn | [] [] |
- lifelines | [] () |
- lilypond | [] |
- lingoteach | |
- lynx | [] [] [] [] |
- m4 | [] [] [] [] |
- mailutils | [] |
- make | [] [] |
- man-db | [] () [] [] |
- minicom | [] [] [] |
- mysecretdiary | [] [] |
- nano | [] [] [] |
- nano_1_0 | [] () [] [] |
- opcodes | [] |
- parted | |
- pilot-qof | [] |
- psmisc | [] |
- pwdutils | |
- python | |
- qof | |
- radius | [] |
- recode | [] [] [] [] [] [] |
- rpm | [] [] |
- screem | |
- scrollkeeper | [] [] [] [] [] [] [] [] |
- sed | [] [] [] |
- sh-utils | [] [] |
- shared-mime-info | [] [] [] [] |
- sharutils | [] [] [] [] [] [] |
- shishi | |
- silky | |
- skencil | [] () |
- sketch | [] () |
- solfege | |
- soundtracker | [] [] |
- sp | [] |
- stardict | [] |
- system-tools-ba... | [] [] [] [] [] [] [] [] [] |
- tar | [] |
- texinfo | [] [] [] |
- textutils | [] [] [] |
- tin | () () |
- tp-robot | [] |
- tuxpaint | [] [] [] [] [] |
- unicode-han-tra... | |
- unicode-transla... | |
- util-linux | [] [] [] [] |
- vorbis-tools | [] [] [] [] |
- wastesedge | () |
- wdiff | [] [] [] [] |
- wget | [] [] |
- xchat | [] [] [] [] [] [] |
- xkeyboard-config | |
- xpad | [] [] |
- +----------------------------------------------------+
- af am ar az be bg bs ca cs cy da de el en en_GB eo
- 10 0 1 2 9 22 1 42 41 2 60 95 16 1 17 16
-
- es et eu fa fi fr ga gl gu he hi hr hu id is it
- +--------------------------------------------------+
- GNUnet | |
- a2ps | [] [] [] () |
- aegis | |
- ant-phone | [] |
- anubis | [] |
- ap-utils | [] [] |
- aspell | [] [] [] |
- bash | [] [] [] |
- batchelor | [] [] |
- bfd | [] |
- bibshelf | [] [] [] |
- binutils | [] [] [] |
- bison | [] [] [] [] [] [] |
- bison-runtime | [] [] [] [] [] |
- bluez-pin | [] [] [] [] [] |
- cflow | [] |
- clisp | [] [] |
- console-tools | |
- coreutils | [] [] [] [] [] [] |
- cpio | [] [] [] |
- cpplib | [] [] |
- cryptonit | [] |
- darkstat | [] () [] [] [] |
- dialog | [] [] [] [] [] [] [] [] |
- diffutils | [] [] [] [] [] [] [] [] [] |
- doodle | [] [] |
- e2fsprogs | [] [] [] |
- enscript | [] [] [] |
- error | [] [] [] [] [] |
- fetchmail | [] |
- fileutils | [] [] [] [] [] [] |
- findutils | [] [] [] [] |
- flex | [] [] [] |
- fslint | [] |
- gas | [] [] |
- gawk | [] [] [] [] |
- gbiff | [] |
- gcal | [] [] |
- gcc | [] |
- gettext-examples | [] [] [] [] [] [] |
- gettext-runtime | [] [] [] [] [] [] |
- gettext-tools | [] [] [] |
- gimp-print | [] [] |
- gip | [] [] [] |
- gliv | () |
- glunarclock | [] [] [] |
- gmult | [] [] [] |
- gnubiff | () () |
- gnucash | () () () |
- gnucash-glossary | [] [] |
- gnuedu | [] |
- gnulib | [] [] [] [] [] [] [] [] |
- gnunet-gtk | |
- gnutls | |
- gpe-aerial | [] [] |
- gpe-beam | [] [] |
- gpe-calendar | |
- gpe-clock | [] [] [] [] |
- gpe-conf | [] |
- gpe-contacts | [] [] |
- gpe-edit | [] [] [] [] |
- gpe-filemanager | [] |
- gpe-go | [] [] [] |
- gpe-login | [] [] [] |
- gpe-ownerinfo | [] [] [] [] [] |
- gpe-package | [] |
- gpe-sketchbook | [] [] |
- gpe-su | [] [] [] [] |
- gpe-taskmanager | [] [] [] |
- gpe-timesheet | [] [] [] [] |
- gpe-today | [] [] [] [] |
- gpe-todo | [] |
- gphoto2 | [] [] [] [] [] |
- gprof | [] [] [] [] |
- gpsdrive | () () [] () |
- gramadoir | [] [] |
- grep | [] [] [] [] [] [] [] [] [] [] [] [] |
- gretl | [] [] [] |
- gsasl | [] [] |
- gss | [] |
- gst-plugins | [] [] [] |
- gst-plugins-base | [] [] |
- gst-plugins-good | [] [] [] |
- gstreamer | [] [] [] |
- gtick | [] |
- gtkam | [] [] [] [] |
- gtkorphan | [] [] |
- gtkspell | [] [] [] [] [] [] |
- gutenprint | [] |
- hello | [] [] [] [] [] [] [] [] [] [] [] [] [] |
- id-utils | [] [] [] [] [] |
- impost | [] [] |
- indent | [] [] [] [] [] [] [] [] [] [] |
- iso_3166 | [] [] [] |
- iso_3166_2 | [] |
- iso_4217 | [] [] [] [] |
- iso_639 | [] [] [] [] [] |
- jpilot | [] [] |
- jtag | [] |
- jwhois | [] [] [] [] [] |
- kbd | [] [] |
- keytouch | [] |
- keytouch-editor | [] |
- keytouch-keyboa... | [] |
- latrine | [] [] [] |
- ld | [] [] |
- leafpad | [] [] [] [] [] [] |
- libc | [] [] [] [] [] |
- libexif | [] |
- libextractor | [] |
- libgpewidget | [] [] [] [] [] |
- libgpg-error | |
- libgphoto2 | [] [] [] |
- libgphoto2_port | [] [] |
- libgsasl | [] [] |
- libiconv | [] [] |
- libidn | [] [] |
- lifelines | () |
- lilypond | [] |
- lingoteach | [] [] [] |
- lynx | [] [] [] |
- m4 | [] [] [] [] |
- mailutils | [] [] |
- make | [] [] [] [] [] [] [] [] |
- man-db | () |
- minicom | [] [] [] [] |
- mysecretdiary | [] [] [] |
- nano | [] [] [] [] [] [] |
- nano_1_0 | [] [] [] [] [] |
- opcodes | [] [] [] [] |
- parted | [] [] [] [] |
- pilot-qof | |
- psmisc | [] [] [] |
- pwdutils | |
- python | |
- qof | [] |
- radius | [] [] |
- recode | [] [] [] [] [] [] [] [] |
- rpm | [] [] |
- screem | |
- scrollkeeper | [] [] [] |
- sed | [] [] [] [] [] |
- sh-utils | [] [] [] [] [] [] [] |
- shared-mime-info | [] [] [] [] [] [] |
- sharutils | [] [] [] [] [] [] [] [] |
- shishi | |
- silky | [] |
- skencil | [] [] |
- sketch | [] [] |
- solfege | [] |
- soundtracker | [] [] [] |
- sp | [] |
- stardict | [] |
- system-tools-ba... | [] [] [] [] [] [] [] [] |
- tar | [] [] [] [] [] [] [] |
- texinfo | [] [] |
- textutils | [] [] [] [] [] |
- tin | [] () |
- tp-robot | [] [] [] [] |
- tuxpaint | [] [] |
- unicode-han-tra... | |
- unicode-transla... | [] [] |
- util-linux | [] [] [] [] [] [] [] |
- vorbis-tools | [] [] |
- wastesedge | () |
- wdiff | [] [] [] [] [] [] [] [] |
- wget | [] [] [] [] [] [] [] [] |
- xchat | [] [] [] [] [] [] [] [] |
- xkeyboard-config | [] [] [] [] |
- xpad | [] [] [] |
- +--------------------------------------------------+
- es et eu fa fi fr ga gl gu he hi hr hu id is it
- 88 22 14 2 40 115 61 14 1 8 1 6 59 31 0 52
-
- ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no
- +-------------------------------------------------+
- GNUnet | |
- a2ps | () [] [] () |
- aegis | () |
- ant-phone | [] |
- anubis | [] [] [] |
- ap-utils | [] |
- aspell | [] [] |
- bash | [] |
- batchelor | [] [] |
- bfd | |
- bibshelf | [] |
- binutils | |
- bison | [] [] [] |
- bison-runtime | [] [] [] |
- bluez-pin | [] [] [] |
- cflow | |
- clisp | [] |
- console-tools | |
- coreutils | [] |
- cpio | |
- cpplib | [] |
- cryptonit | [] |
- darkstat | [] [] |
- dialog | [] [] |
- diffutils | [] [] [] |
- doodle | |
- e2fsprogs | [] |
- enscript | [] |
- error | [] |
- fetchmail | [] [] |
- fileutils | [] [] |
- findutils | [] |
- flex | [] [] |
- fslint | [] [] |
- gas | |
- gawk | [] [] |
- gbiff | [] |
- gcal | |
- gcc | |
- gettext-examples | [] [] |
- gettext-runtime | [] [] [] |
- gettext-tools | [] [] |
- gimp-print | [] [] |
- gip | [] [] |
- gliv | [] |
- glunarclock | [] [] |
- gmult | [] [] |
- gnubiff | |
- gnucash | () () |
- gnucash-glossary | [] |
- gnuedu | |
- gnulib | [] [] [] [] |
- gnunet-gtk | |
- gnutls | |
- gpe-aerial | [] |
- gpe-beam | [] |
- gpe-calendar | [] |
- gpe-clock | [] [] [] |
- gpe-conf | [] [] |
- gpe-contacts | [] |
- gpe-edit | [] [] [] |
- gpe-filemanager | [] [] |
- gpe-go | [] [] [] |
- gpe-login | [] [] [] |
- gpe-ownerinfo | [] [] |
- gpe-package | [] [] |
- gpe-sketchbook | [] [] |
- gpe-su | [] [] [] |
- gpe-taskmanager | [] [] [] [] |
- gpe-timesheet | [] |
- gpe-today | [] [] |
- gpe-todo | [] |
- gphoto2 | [] [] |
- gprof | |
- gpsdrive | () () () |
- gramadoir | () |
- grep | [] [] [] [] |
- gretl | |
- gsasl | [] |
- gss | |
- gst-plugins | [] |
- gst-plugins-base | |
- gst-plugins-good | [] |
- gstreamer | [] |
- gtick | |
- gtkam | [] |
- gtkorphan | [] |
- gtkspell | [] [] |
- gutenprint | |
- hello | [] [] [] [] [] [] |
- id-utils | [] |
- impost | |
- indent | [] [] |
- iso_3166 | [] |
- iso_3166_2 | [] |
- iso_4217 | [] [] [] |
- iso_639 | [] [] |
- jpilot | () () () |
- jtag | |
- jwhois | [] |
- kbd | [] |
- keytouch | [] |
- keytouch-editor | |
- keytouch-keyboa... | |
- latrine | [] |
- ld | |
- leafpad | [] [] |
- libc | [] [] [] [] [] |
- libexif | |
- libextractor | |
- libgpewidget | [] |
- libgpg-error | |
- libgphoto2 | [] |
- libgphoto2_port | [] |
- libgsasl | [] |
- libiconv | |
- libidn | [] [] |
- lifelines | [] |
- lilypond | |
- lingoteach | [] |
- lynx | [] [] |
- m4 | [] [] |
- mailutils | |
- make | [] [] [] |
- man-db | () |
- minicom | [] |
- mysecretdiary | [] |
- nano | [] [] [] |
- nano_1_0 | [] [] [] |
- opcodes | [] |
- parted | [] [] |
- pilot-qof | |
- psmisc | [] [] [] |
- pwdutils | |
- python | |
- qof | |
- radius | |
- recode | [] |
- rpm | [] [] |
- screem | [] |
- scrollkeeper | [] [] [] [] |
- sed | [] [] |
- sh-utils | [] [] |
- shared-mime-info | [] [] [] [] [] |
- sharutils | [] [] |
- shishi | |
- silky | [] |
- skencil | |
- sketch | |
- solfege | |
- soundtracker | |
- sp | () |
- stardict | [] [] |
- system-tools-ba... | [] [] [] [] |
- tar | [] [] [] |
- texinfo | [] [] [] |
- textutils | [] [] [] |
- tin | |
- tp-robot | [] |
- tuxpaint | [] |
- unicode-han-tra... | |
- unicode-transla... | |
- util-linux | [] [] |
- vorbis-tools | [] |
- wastesedge | [] |
- wdiff | [] [] |
- wget | [] [] |
- xchat | [] [] [] [] |
- xkeyboard-config | [] |
- xpad | [] [] [] |
- +-------------------------------------------------+
- ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no
- 52 24 2 2 1 3 0 2 3 21 0 15 1 97 5 1
-
- nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
- +------------------------------------------------------+
- GNUnet | |
- a2ps | () [] [] [] [] [] [] |
- aegis | () () |
- ant-phone | [] [] |
- anubis | [] [] [] |
- ap-utils | () |
- aspell | [] [] |
- bash | [] [] [] |
- batchelor | [] [] |
- bfd | |
- bibshelf | [] |
- binutils | [] [] |
- bison | [] [] [] [] [] |
- bison-runtime | [] [] [] [] |
- bluez-pin | [] [] [] [] [] [] [] [] [] |
- cflow | [] |
- clisp | [] |
- console-tools | [] |
- coreutils | [] [] [] [] |
- cpio | [] [] [] |
- cpplib | [] |
- cryptonit | [] [] |
- darkstat | [] [] [] [] [] [] |
- dialog | [] [] [] [] [] [] [] [] [] |
- diffutils | [] [] [] [] [] [] |
- doodle | [] [] |
- e2fsprogs | [] [] |
- enscript | [] [] [] [] [] |
- error | [] [] [] [] |
- fetchmail | [] [] [] |
- fileutils | [] [] [] [] [] |
- findutils | [] [] [] [] [] [] |
- flex | [] [] [] [] [] |
- fslint | [] [] [] [] |
- gas | |
- gawk | [] [] [] [] |
- gbiff | [] |
- gcal | [] |
- gcc | [] |
- gettext-examples | [] [] [] [] [] [] [] [] |
- gettext-runtime | [] [] [] [] [] [] [] [] |
- gettext-tools | [] [] [] [] [] [] [] |
- gimp-print | [] [] |
- gip | [] [] [] [] |
- gliv | [] [] [] [] |
- glunarclock | [] [] [] [] [] [] |
- gmult | [] [] [] [] |
- gnubiff | () |
- gnucash | () [] |
- gnucash-glossary | [] [] [] |
- gnuedu | |
- gnulib | [] [] [] [] [] |
- gnunet-gtk | [] |
- gnutls | [] [] |
- gpe-aerial | [] [] [] [] [] [] [] |
- gpe-beam | [] [] [] [] [] [] [] |
- gpe-calendar | [] |
- gpe-clock | [] [] [] [] [] [] [] [] |
- gpe-conf | [] [] [] [] [] [] [] |
- gpe-contacts | [] [] [] [] [] |
- gpe-edit | [] [] [] [] [] [] [] [] |
- gpe-filemanager | [] [] |
- gpe-go | [] [] [] [] [] [] |
- gpe-login | [] [] [] [] [] [] [] [] |
- gpe-ownerinfo | [] [] [] [] [] [] [] [] |
- gpe-package | [] [] |
- gpe-sketchbook | [] [] [] [] [] [] [] [] |
- gpe-su | [] [] [] [] [] [] [] [] |
- gpe-taskmanager | [] [] [] [] [] [] [] [] |
- gpe-timesheet | [] [] [] [] [] [] [] [] |
- gpe-today | [] [] [] [] [] [] [] [] |
- gpe-todo | [] [] [] [] |
- gphoto2 | [] [] [] [] [] |
- gprof | [] [] [] |
- gpsdrive | [] [] [] |
- gramadoir | [] [] |
- grep | [] [] [] [] [] [] [] [] |
- gretl | [] |
- gsasl | [] [] [] |
- gss | [] [] [] |
- gst-plugins | [] [] [] [] |
- gst-plugins-base | [] |
- gst-plugins-good | [] [] [] [] |
- gstreamer | [] [] [] |
- gtick | [] |
- gtkam | [] [] [] [] |
- gtkorphan | [] |
- gtkspell | [] [] [] [] [] [] [] [] |
- gutenprint | [] |
- hello | [] [] [] [] [] [] [] [] |
- id-utils | [] [] [] [] |
- impost | [] |
- indent | [] [] [] [] [] [] |
- iso_3166 | [] [] [] [] [] [] |
- iso_3166_2 | |
- iso_4217 | [] [] [] [] |
- iso_639 | [] [] [] [] |
- jpilot | |
- jtag | [] |
- jwhois | [] [] [] [] |
- kbd | [] [] [] |
- keytouch | [] |
- keytouch-editor | [] |
- keytouch-keyboa... | [] |
- latrine | [] [] |
- ld | [] |
- leafpad | [] [] [] [] [] [] |
- libc | [] [] [] [] [] |
- libexif | [] |
- libextractor | [] [] |
- libgpewidget | [] [] [] [] [] [] [] |
- libgpg-error | [] [] |
- libgphoto2 | [] |
- libgphoto2_port | [] [] [] |
- libgsasl | [] [] [] [] |
- libiconv | [] [] |
- libidn | [] [] () |
- lifelines | [] [] |
- lilypond | |
- lingoteach | [] |
- lynx | [] [] [] |
- m4 | [] [] [] [] [] |
- mailutils | [] [] [] [] |
- make | [] [] [] [] |
- man-db | [] [] |
- minicom | [] [] [] [] [] |
- mysecretdiary | [] [] [] [] |
- nano | [] [] [] |
- nano_1_0 | [] [] [] [] |
- opcodes | [] [] |
- parted | [] |
- pilot-qof | [] |
- psmisc | [] [] |
- pwdutils | [] [] |
- python | |
- qof | [] [] |
- radius | [] [] |
- recode | [] [] [] [] [] [] [] |
- rpm | [] [] [] [] |
- screem | |
- scrollkeeper | [] [] [] [] [] [] [] |
- sed | [] [] [] [] [] [] [] [] [] |
- sh-utils | [] [] [] |
- shared-mime-info | [] [] [] [] [] |
- sharutils | [] [] [] [] |
- shishi | [] |
- silky | [] |
- skencil | [] [] [] |
- sketch | [] [] [] |
- solfege | [] |
- soundtracker | [] [] |
- sp | |
- stardict | [] [] [] |
- system-tools-ba... | [] [] [] [] [] [] [] [] [] |
- tar | [] [] [] [] [] |
- texinfo | [] [] [] [] |
- textutils | [] [] [] |
- tin | () |
- tp-robot | [] |
- tuxpaint | [] [] [] [] [] |
- unicode-han-tra... | |
- unicode-transla... | |
- util-linux | [] [] [] [] |
- vorbis-tools | [] [] |
- wastesedge | |
- wdiff | [] [] [] [] [] [] |
- wget | [] [] [] [] |
- xchat | [] [] [] [] [] [] [] |
- xkeyboard-config | [] [] |
- xpad | [] [] [] |
- +------------------------------------------------------+
- nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
- 0 2 3 58 30 54 5 73 72 4 40 46 11 50 128 2
-
- tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu
- +---------------------------------------------------+
- GNUnet | [] | 2
- a2ps | [] [] [] | 19
- aegis | | 0
- ant-phone | [] [] | 6
- anubis | [] [] [] | 11
- ap-utils | () [] | 4
- aspell | [] [] [] | 15
- bash | [] | 11
- batchelor | [] [] | 9
- bfd | | 1
- bibshelf | [] | 7
- binutils | [] [] [] | 9
- bison | [] [] [] | 19
- bison-runtime | [] [] [] | 15
- bluez-pin | [] [] [] [] [] [] | 28
- cflow | [] [] | 5
- clisp | | 6
- console-tools | [] [] | 5
- coreutils | [] [] | 16
- cpio | [] [] [] | 9
- cpplib | [] [] [] [] | 11
- cryptonit | | 5
- darkstat | [] () () | 15
- dialog | [] [] [] [] [] | 30
- diffutils | [] [] [] [] | 28
- doodle | [] | 6
- e2fsprogs | [] [] | 10
- enscript | [] [] [] | 16
- error | [] [] [] [] | 18
- fetchmail | [] [] | 12
- fileutils | [] [] [] | 18
- findutils | [] [] [] | 17
- flex | [] [] | 15
- fslint | [] | 9
- gas | [] | 3
- gawk | [] [] | 15
- gbiff | [] | 5
- gcal | [] | 5
- gcc | [] [] [] | 6
- gettext-examples | [] [] [] [] [] [] | 27
- gettext-runtime | [] [] [] [] [] [] | 28
- gettext-tools | [] [] [] [] [] | 19
- gimp-print | [] [] | 12
- gip | [] [] | 12
- gliv | [] [] | 8
- glunarclock | [] [] [] | 15
- gmult | [] [] [] [] | 15
- gnubiff | [] | 1
- gnucash | () | 2
- gnucash-glossary | [] [] | 9
- gnuedu | [] | 2
- gnulib | [] [] [] [] [] | 28
- gnunet-gtk | | 1
- gnutls | | 2
- gpe-aerial | [] [] | 14
- gpe-beam | [] [] | 14
- gpe-calendar | [] | 3
- gpe-clock | [] [] [] [] | 21
- gpe-conf | [] [] | 14
- gpe-contacts | [] [] | 10
- gpe-edit | [] [] [] [] | 20
- gpe-filemanager | [] | 6
- gpe-go | [] [] | 15
- gpe-login | [] [] [] [] [] | 21
- gpe-ownerinfo | [] [] [] [] | 21
- gpe-package | [] | 6
- gpe-sketchbook | [] [] | 16
- gpe-su | [] [] [] | 20
- gpe-taskmanager | [] [] [] | 20
- gpe-timesheet | [] [] [] [] | 18
- gpe-today | [] [] [] [] [] | 21
- gpe-todo | [] | 7
- gphoto2 | [] [] [] [] | 20
- gprof | [] [] | 11
- gpsdrive | | 4
- gramadoir | [] | 7
- grep | [] [] [] [] | 34
- gretl | | 4
- gsasl | [] [] | 8
- gss | [] | 5
- gst-plugins | [] [] [] | 15
- gst-plugins-base | [] [] [] | 9
- gst-plugins-good | [] [] [] [] [] | 20
- gstreamer | [] [] [] | 17
- gtick | [] | 3
- gtkam | [] | 13
- gtkorphan | [] | 7
- gtkspell | [] [] [] [] [] [] | 26
- gutenprint | | 3
- hello | [] [] [] [] [] | 37
- id-utils | [] [] | 14
- impost | [] | 4
- indent | [] [] [] [] | 25
- iso_3166 | [] [] [] [] | 16
- iso_3166_2 | | 2
- iso_4217 | [] [] | 14
- iso_639 | [] | 14
- jpilot | [] [] [] [] | 7
- jtag | [] | 3
- jwhois | [] [] [] | 13
- kbd | [] [] | 12
- keytouch | [] | 4
- keytouch-editor | | 2
- keytouch-keyboa... | [] | 3
- latrine | [] [] | 8
- ld | [] [] [] [] | 8
- leafpad | [] [] [] [] | 23
- libc | [] [] [] | 23
- libexif | [] | 4
- libextractor | [] | 5
- libgpewidget | [] [] [] | 19
- libgpg-error | [] | 4
- libgphoto2 | [] | 8
- libgphoto2_port | [] [] [] | 11
- libgsasl | [] | 8
- libiconv | [] | 7
- libidn | [] [] | 10
- lifelines | | 4
- lilypond | | 2
- lingoteach | [] | 6
- lynx | [] [] [] | 15
- m4 | [] [] [] | 18
- mailutils | [] | 8
- make | [] [] [] | 20
- man-db | [] | 6
- minicom | [] | 14
- mysecretdiary | [] [] | 12
- nano | [] [] | 17
- nano_1_0 | [] [] [] | 18
- opcodes | [] [] | 10
- parted | [] [] [] | 10
- pilot-qof | [] | 3
- psmisc | [] | 10
- pwdutils | [] | 3
- python | | 0
- qof | [] | 4
- radius | [] | 6
- recode | [] [] [] | 25
- rpm | [] [] [] [] | 14
- screem | [] | 2
- scrollkeeper | [] [] [] [] | 26
- sed | [] [] [] | 22
- sh-utils | [] | 15
- shared-mime-info | [] [] [] [] | 24
- sharutils | [] [] [] | 23
- shishi | | 1
- silky | [] | 4
- skencil | [] | 7
- sketch | | 6
- solfege | | 2
- soundtracker | [] [] | 9
- sp | [] | 3
- stardict | [] [] [] [] | 11
- system-tools-ba... | [] [] [] [] [] [] [] | 37
- tar | [] [] [] [] | 20
- texinfo | [] [] [] | 15
- textutils | [] [] [] | 17
- tin | | 1
- tp-robot | [] [] [] | 10
- tuxpaint | [] [] [] | 16
- unicode-han-tra... | | 0
- unicode-transla... | | 2
- util-linux | [] [] [] | 20
- vorbis-tools | [] [] | 11
- wastesedge | | 1
- wdiff | [] [] | 22
- wget | [] [] [] | 19
- xchat | [] [] [] [] | 29
- xkeyboard-config | [] [] [] [] | 11
- xpad | [] [] [] | 14
- +---------------------------------------------------+
- 77 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu
- 170 domains 0 1 1 77 39 0 136 10 1 48 5 54 0 2028
-
- Some counters in the preceding matrix are higher than the number of
-visible blocks let us expect. This is because a few extra PO files are
-used for implementing regional variants of languages, or language
-dialects.
-
- For a PO file in the matrix above to be effective, the package to
-which it applies should also have been internationalized and
-distributed as such by its maintainer. There might be an observable
-lag between the mere existence a PO file and its wide availability in a
-distribution.
-
- If October 2006 seems to be old, you may fetch a more recent copy of
-this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date
-matrix with full percentage details can be found at
-`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
-
-1.6 Using `gettext' in new packages
-===================================
-
-If you are writing a freely available program and want to
-internationalize it you are welcome to use GNU `gettext' in your
-package. Of course you have to respect the GNU Library General Public
-License which covers the use of the GNU `gettext' library. This means
-in particular that even non-free programs can use `libintl' as a shared
-library, whereas only free software can use `libintl' as a static
-library or use modified versions of `libintl'.
-
- Once the sources are changed appropriately and the setup can handle
-the use of `gettext' the only thing missing are the translations. The
-Free Translation Project is also available for packages which are not
-developed inside the GNU project. Therefore the information given above
-applies also for every other Free Software Project. Contact
-`translation@iro.umontreal.ca' to make the `.pot' files available to
-the translation teams.
-
diff --git a/contrib/cpio/AUTHORS b/contrib/cpio/AUTHORS
deleted file mode 100644
index 980c8f3..0000000
--- a/contrib/cpio/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-Authors of GNU cpio
-
-Phil Nelson <phil@cs.wwu.edu>
-David MacKenzie <djm@gnu.ai.mit.edu>
-John Oleynick <juo@klinzhai.rutgers.edu>
-Sergey Poznyakoff <gray@mirddin.farlep.net> \ No newline at end of file
diff --git a/contrib/cpio/COPYING b/contrib/cpio/COPYING
deleted file mode 100644
index 5c95a60..0000000
--- a/contrib/cpio/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/contrib/cpio/ChangeLog b/contrib/cpio/ChangeLog
deleted file mode 100644
index 1307353..0000000
--- a/contrib/cpio/ChangeLog
+++ /dev/null
@@ -1,1781 +0,0 @@
-2007-06-08 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * configure.ac, NEWS: Version number 2.8
- * bootstrap.conf: Update
-
-2007-06-07 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * NEWS: Update
- * configure.ac: Raise version to 2.7.90
- * doc/cpio.texi: Update
- * src/extern.h (set_perms, set_file_times): Take file descriptor
- as the first argument.
- * src/util.c (set_perms): Take file descriptor
- as the first argument and use fchmod/fchown if available. Fixes
- CAN-2005-1111.
- * src/copyin.c, src/copyout.c, src/copypass.c: Update calls to
- set_perms.
- * src/makepath.c: Remove useless includes.
-
- * src/util.c (set_perms, stat_to_cpio): Use CPIO_UID and CPIO_GID
- macros to set uid and gid
- * src/main.c (process_args): Allow to use --owner in copy-out mode.
- * THANKS: Add Mike Frysinger
-
-2007-05-18 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * bootstrap: Update from tar repository
- * doc/cpio.texi: Fix typo
- * src/copyin.c (from_ascii): Bugfix: allow for empty fields
- * src/copyout.c (process_copy_out): Fix memory leaks on
- orig_file_name.
- * src/copypass.c (process_copy_pass): symlink_error takes two
- arguments.
- * src/extern.h: Add missing includes.
-
-2006-12-18 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * README-cvs: New file
- * lib/Makefile.tmpl, lib/bcopy.c, lib/mkdir.c, lib/strdup.c,
- lib/strerror.c, lib/.cvsignore, po/.cvsignore,
- po/Makevars: Removed
- * lib/Makefile.am: New file
- * po/POTFILES.in: Update
- * bootstrap: Synch with tar.
- * configure.ac: Update
- * gnulib.modules: Add lchown, strerror
- * src/Makefile.am: Update
- * src/main.c, src/mt.c: Include rmt-command.h instead of localedir.h
- * .cvsignore, doc/.cvsignore: Sort
-
- * src/util.c (sparse_write): Static. Provide a forward
- declaration. Define enum sparse_write_states inside the function.
-
- * src/copyin.c (long_format): Use PRIuMAX for printing file size
- * src/copyout.c (write_out_binary_header): Fix size conversion
- * src/extern.h (tape_toss_input, warn_if_file_changed): Last
- argument is off_t
- * src/util.c (tape_toss_input, warn_if_file_changed): Last
- argument is off_t
- (warn_if_file_changed): Use ngettext
-
-2006-11-15 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * src/copypass.c: Fix setting output file permissions
-
-2006-11-13 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * doc/cpio.texi: Consistently use @option{} for displaying command
- line options.
- Fix formatting in "Invoking `cpio'" section
- * src/main.c (process_args): Fix usage error diagnostics in
- copy-pass mode.
-
-2006-10-24 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * src/copyout.c (process_copy_out): Add terminating zero to the
- link_name.
-
- * tests/symlink.at: New testcase
- * tests/Makefile.am: New test symlink.at
- * tests/inout.at: Add keywords
- * tests/testsuite.at (AT_SKIP_TEST): New macro
- New test symlink.at
-
-2006-10-21 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * configure.ac, NEWS: Version 2.7
- * gnulib.modules: Add stdint
- * src/util.c: Use STRINGIFY_BIGINT to display num_bytes
-
-2006-09-27 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * TODO: Update
- * README-alpha: Update
- * bootstrap: Imported from tar
- * configure.ac: Require autoconf 2.59 and gettext 1.15
- * gnulib.modules: add inttypes
- * doc/cpio.texi: Minor fixes
- * po/Makevars: Remove automatically generated file
- * po/.cvsignore: Add Makevars
- * lib/.cvsignore: Update
- * src/copyin.c, src/copyout.c, src/copypass.c, src/cpio.h,
- src/cpiohdr.h, src/defer.c, src/defer.h, src/extern.h,
- src/global.c, src/main.c, src/makepath.c, src/tar.c,
- src/util.c: Update copyright year.
-
-2006-07-04 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * bootstrap (update_po): Fix single translation update
- * lib/Makefile.tmpl: Initialize AM_CPPFLAGS
- (noinst_HEADERS): Add system-ioctl.h
-
- Start rewriting using a better suited internal representation for
- the file meta-data.
-
- * src/cpiohdr.h (struct old_cpio_header): Remove unused fields
- c_mtime, c_filesize and c_name.
- (struct old_ascii_header): New data type
- (struct new_ascii_header): New data type. Describes the header
- structure, not its internal representation.
- (struct cpio_file_stat): New data type. Describes internal
- representation of a file metadata
-
- * src/copyin.c (from_ascii): New function
- Use cpio_file_stat for internal header representation.
- * src/copyout.c: Use cpio_file_stat for internal header
- representation. Among other things this fixes bug reported by
- Peter Vrabec on Mar 2, 2006
- (http://lists.gnu.org/archive/html/bug-cpio/2006-03/msg00000.html)
- * src/copypass.c: Use cpio_file_stat for internal header
- representation.
- * src/tar.c: Likewise
- * src/util.c: Likewise
- * src/defer.c: Likewise
- * src/defer.h: Likewise
- * src/extern.h: Likewise
- (from_ascii): New prototype
- (LG_8,LG_16,FROM_OCTAL,FROM_HEX): New defines
- * src/main.c: New command line option --HANG (hidden)
-
-2006-03-12 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * tests/Makefile.am (AM_CPPFLAGS): Define LOCALEDIR
-
-2006-02-18 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * gnulib.modules: Add stpcpy. Thanks Benigno B. Junior for
- reporting.
- * THANKS: Add Benigno B. Junior
- * src/makepath.c: Fix indentation.
-
-2005-11-16 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * src/copyout.c (process_copy_out): Fix typo.
-
-2005-11-12 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * bootstrap: Minor fix
- * src/copyout.c (write_out_header): Rewritten using separate
- functions for each file format. Use to_ascii to convert numbers to
- ascii representation. Check for overflows and report them if
- appropriate. Return 0 if it is OK to proceed with archiving this
- file, 1 otherwise. All callers updated.
- * src/extern.h (write_out_header): Return int.
-
-2005-10-28 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * src/util.c: Include paxlib.
- * bootstrap: If file `.bootstrap' exists in the cwd and is
- readable, prepend its contents to the command line.
-
- Fix Debian bug 335580:
-
- * src/copyout.c (read_for_checksum,write_out_header): CRC is a
- 32-bit unsigned value. Patch proposed by Jim Castleberry and
- Peter Vrabec.
- * src/extern.h (crc): Change declaration
- * src/global.c: Likewise
- * src/tar.c (tar_checksum): Return unsigned int
-
- * THANKS: Add Jim Castleberry
- * NEWS: Updated
-
-2005-09-30 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * src/copyout.c (process_copy_out): Discern between original and
- (eventually fixed) file name (in tar terminology, `file name'
- vs. `member name'.
-
-2005-09-08 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * gnulib.modules: Add utimens
- * src/util.c (cpio_safer_name_suffix): Preserve ./ no matter what
- the value of strip_leading_dots is.
- (set_file_times): New function
- * src/extern.h (set_file_times): New function
- * src/copyin.c: Use set_file_times() to update file atime/mtime
- * src/copyout.c: Likewise.
- * src/copypass.c: Likewise.
-
-2005-05-25 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/copyin.c: Use cpio_safer_name_suffix() and CPIO_TRAILER_NAME
- define instead of hardcoding the trailer file name.
- * src/copyout.c: Likewise.
- * src/cpio.h (CPIO_TRAILER_NAME): New define
- * src/extern.h (cpio_safer_name_suffix): New proto
- * src/tar.c: Use CPIO_TRAILER_NAME define instead of hardcoding
- the trailer file name.
- * src/util.c (cpio_safer_name_suffix): New function
- (add_cdf_double_slashes): Add FIXME warning.
-
- * lib/fatal.c: New file
- * lib/Makefile.tmpl (libcpio_a_SOURCES): Add fatal.c
- * src/copyout.c: Use error reporting functions from paxlib
- * src/makepath.c: Likewise
- * src/mt.c: Likewise
- * src/main.c (fatal_exit): Moved to lib/fatal.c
-
-2005-05-24 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/copyin.c (process_copy_in): Use safer_name_suffix no matter
- what the value of no_abs_paths_flag. The function knows better
- what to do in any case.
- * src/copyout.c (process_copy_out): Honor no_abs_paths_flag.
- * src/main.c (options): Minor fixes.
-
-2005-05-23 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * bootstrap (copy_files): Create destination directory if it does
- not exist.
- Preserve longlong.m4 as longlong_gl.m4
- * src/main.c: Include paxlib.h
-
-2005-05-22 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * lib/.cvsignore: Updated
- * gnulib.modules: Add hash
- * doc/cpio.texi (Reports): New chapter
- * lib/Makefile.tmpl: Add new paxutils files.
- * po/POTFILES.in: Likewise
- * src/copyin.c [!HAVE_LCHOWN] (lchown): Define to 0 to avoid
- changing ownership of the target file.
- (process_copy_in): Use safer_name_suffix()
- * src/main.c (parse_opt): Handle new --absolute-filenames option.
- (process_args): Updated
- * src/util.c: Rewrite inode lookup/insertion functions using hash
- module.
-
-u2005-05-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * configure.ac: Raised version number to 2.6.90
- * NEWS: Updated
- * src/copyin.c: Use set_perms.
- * src/copypass.c: Likewise.
- * src/copyout.c (process_copy_out): Use stat_to_cpio() to convert
- struct stat to struct new_cpio_header.
- * src/defer.h: Remove legacy P_() stuff.
- * src/dstring.c: Likewise
- * src/extern.h: Likewise
- * src/util.c (stat_to_cpio,set_perms): New functions
- * doc/.cvsignore: Updated
- * lib/.cvsignore: Updated
- * tests/.cvsignore: Updated
- * .cvsignore: Updated
- * COPYING: Added to the repository
-
-2005-05-19 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * po/POTFILES.in: Add paxerror.c paxexit.c paxconvert.c
-
- * bootstrap (copy_files): Accept optional third argument: a prefix
- to be appended to destination file names.
- Import paxutils/paxlib files.
- * lib/Makefile.tmpl (libcpio_a_SOURCES): Add paxerror.c paxexit.c
- paxconvert.c
- * src/copyin.c: Use paxutils error reporting functions
- * src/copyout.c: Likewise
- * src/copypass.c: Likewise
- * src/util.c: Likewise. Add missing includes
- * src/main.c (USAGE_ERROR): Removed
- (CHECK_USAGE,parse_opt,process_args): Use error() instead of USAGE_ERROR
- (fatal_exit): New function
- * src/tar.c (is_tar_filename_too_long): Removed unused variable
-
- * Makefile.am, configure.ac, doc/Makefile.am,
- doc/cpio.texi, doc/gendocs_template, headers/Makefile.am,
- headers/fnmatch.h, lib/Makefile.tmpl, lib/mkdir.c,
- lib/strdup.c, lib/strerror.c, src/Makefile.am,
- src/copyin.c, src/copyout.c, src/copypass.c, src/cpio.h,
- src/cpiohdr.h, src/defer.c, src/defer.h, src/dstring.c,
- src/dstring.h, src/extern.h, src/filemode.c,
- src/filetypes.h, src/global.c, src/idcache.c,
- src/main.c, src/makepath.c, src/mt.c, src/tar.c,
- src/tar.h, src/tarhdr.h, src/userspec.c, src/util.c,
- tests/Makefile.am, tests/inout.at, tests/testsuite.at,
- tests/version.at: Updated FSF postal mail address.
-
- * bootstrap: Port recent changes from tar bootstrap.
- * gnulib.modules: New file
- * tests/Makefile.am (genfile_SOURCES,LDADD): Updated
-
- * THANKS: Updated
- * configure.ac: Remove check for gethostname, it is never used.
- Remove check for setsockopt, it is provided by paxutils.
-
- Fix LFS support issues. Proposed by Peter Vrabec and Dmitry V. Levin
-
- * src/extern.h (copy_files_tape_to_disk, copy_files_disk_to_tape,
- copy_files_disk_to_disk): Change num_bytes argument type from
- long to off_t.
- * src/util.c (copy_files_tape_to_disk, copy_files_disk_to_tape,
- copy_files_disk_to_disk, disk_fill_input_buffer,
- write_nuls_to_file): Likewise.
- (write_nuls_to_file, copy_files_disk_to_tape,
- copy_files_disk_to_disk): Handle `off_t num_bytes' properly.
-
- * src/util.c (find_inode_file): Fix typos causing function to
- occasionally miss inodes and, therefore, to copy out the same
- (hard-linked) file several times to archive. Proposed by Brian
- Mays.
-
-2005-03-24 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/main.c (process_args): Fixed discrepancy I have been
- overlooking so far: cpio still does not handle --sparse option
- the same way tar is handling it. --sparse is allowed in copy-in
- and copy-pass modes, just as docs say it. Thanks Dmitry Levin.
- * THANKS: Updated
-
-2005-03-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/util.c (disk_buffered_write): Fix typo introduced
- 2005-01-11.
- * src/main.c (process_args): Fixed error message
-
-2005-01-31 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/main.c (main): Remove umask(0). Fixes CAN-1999-1572.
- [__TURBOC__,__EMX__]: Removed
- * src/copypass.c (process_copy_pass): Set umask 0
- * src/copyin.c (process_copy_in): Likewise
- * src/util.c (open_archive): Use MODE_RW.
-
-2005-01-11 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * doc/gendocs_template: Template file for gendocs.sh.
- * doc/Makefile.am: Use gendocs.sh to generate webdocs.
- * doc/cpio.texi: Updated.
-
- * src/copyin.c: Use memset instead of bzero, memmove
- (or memcpy, if appropriate), instead of bcopy, and
- strchr/strrchr instead of index/rindex.
- * src/copypass.c: Likewise.
- * src/main.c: Likewise.
- * src/makepath.c: Likewise.
- * src/tar.c: Likewise.
- * src/util.c: Likewise.
- (write_nuls_to_file): Made extern. All callers updated
-
- * src/copyout.c: Likewise. Use write_nuls_to_file instead
- of explicitely accessing zeros_512
- * src/userspec.c: Likewise.
- Rename isnumber to isnumber_p. Proposed by
- Albert Chin
- * src/extern.h (zeros_512): Removed
- (write_nuls_to_file): New function
- * src/global.c (zeros_512): Removed
-
-2005-01-06 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * bootstrap: Add 'fileblocks' gnulib module
- Create paxutils.m4
- * configure.ac: Call cpio_PAXUTILS
- * src/main.c: Remove ifdef around setlocale
- * src/mt.c: Likewise
-
-2004-12-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * configure.ac: New option --enable-mt
- Check for locale.h
- * doc/cpio.info: Removed
- * src/mt.c (main): Use argmatch_invalid()
-
-2004-12-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- Released version 2.6. Sources up to this point are tagged
- release_2_6.
-
- * configure.ac: Raised version number to 2.6
- * NEWS: Likewise
- * bootstrap (update_po): Give -r to wget. Always remove index.html
- Ignore alloca-opt module (it duplicates alloca)
-
-2004-11-23 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/main.c (enum cpio_options): Bugfix: Initialize first enum
- value to 256.
- * bootstrap: Add unlocked-io
- * headers/argp.h: Removed
- * headers/getopt.h: Removed
- * headers/Makefile.am: Updated
-
-2004-10-14 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/copyout.c: Add trailing slash to directory names in
- ustar format.
- * src/makepath.c: Removed redeclaration of error().
- * src/tar.c: Fixed deviations from POSIX.1-1988:
- Properly split long file names. Fill in octal fields with zeros,
- not spaces. Save only protection modes, not the whole mode.
-
- * NEWS: Updated
-
-2004-09-08 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * NEWS: Updated
- * TODO: Updated
- * bootstrap: Install po files by default
- * po/LINGUAS: Removed. File is generated automatically
- * po/.cvsignore: Updated
- * src/copyin.c: Implemented --to-stdout option
- * src/copyout.c: Display the annoying 'truncating inode number'
- message only if the user wishes it.
- * src/extern.h: Added new globals.
- * src/global.c: Likewise.
-
- * src/main.c: Added support for --to-stdout and --warning options
- * src/tar.c (read_in_tar_header): Use warn_junk_bytes()
- * src/util.c (create_all_directories): Use dir_name.
-
- * configure.ac: Added support for the test suite
- * Makefile.am: Likewise
-
- * tests: New directory
- * tests/.cvsignore: New file
- * tests/Makefile.am: New file
- * tests/testsuite.at: New file
- * tests/inout.at: New file
- * tests/version.at: New file
- * tests/atlocal.in: New file
-
-2004-09-07 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/main.c (process_args): Bugfix. Allow extra arguments
- in copy_in mode.
- * src/util.c (write_nuls_to_file): Use buffered I/O. All
- callers changed. Thanks Matthew Braithwaite <mab@cnet.com>
- for noticing.
- Bugfix: extra_bytes was mistakenly used instead of blocks.
- * THANKS: Added Matthew Braithwaite.
-
-2004-09-06 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- Started merging with tar into paxutils. Sources before
- this point are tagged alpha-2_50_90.
-
- * bootstrap: New file
- * autogen.sh: Removed
- * Makefile.am: Updated
- * NEWS: Updated
- * README-alpha: Updated
- * configure.ac: Updated
- * doc/cpio.1: Updated
- * po/POTFILES.in: Updated
-
- * src/Makefile.am: Updated
- * src/error.c: Removed
- * src/dirname.c: Likewise
- * src/xmalloc.c: Likewise
- * src/stripslash.c: Likewise
- * src/xstrdup.c
- * src/gettext.h: Likewise
- * src/system.h: Likewise
- * src/rmt.h: Likewise
- * src/getopt.c: Likewise
- * src/getopt1.c: Likewise
- * src/bcopy.c: Likewise
- * src/fnmatch.c: Likewise
- * src/mkdir.c: Likewise
- * src/strdup.c: Likewise
- * src/argp-ba.c: Likewise
- * src/argp-eexst.c: Likewise
- * src/argp-fmtstream.c: Likewise
- * src/argp-fs-xinl.c: Likewise
- * src/argp-help.c: Likewise
- * src/argp-parse.c: Likewise
- * src/argp-pv.c: Likewise
- * src/argp-pvh.c: Likewise
- * src/argp-xinl.c: Likewise
- * src/pin.c: Likewise
- * src/alloca.c: Likewise
- * src/argmatch.c: Likewise
- * src/rmt.c: Likewise
- * src/rtapelib.c: Likewise
- * src/strerror.c: Likewise
-
- * src/copyin.c: Switched to ANSI C (sigh)
- * src/copyout.c: Likewise
- * src/copypass.c: Likewise
- * src/defer.c: Likewise
- * src/defer.h: Likewise
- * src/dstring.c: Likewise
- * src/dstring.h: Likewise
- * src/extern.h: Likewise
- * src/filemode.c: Likewise
- * src/global.c: Likewise
- * src/idcache.c: Likewise
- * src/main.c: Likewise
- * src/makepath.c: Likewise
- * src/mt.c: Likewise
- * src/tar.c: Likewise
- * src/userspec.c: Likewise
- * src/util.c: Likewise
-
- * lib: New directory
- * lib/Makefile.tmpl: New file
- * lib/bcopy.c: Moved from ../src
- * lib/mkdir.c: Likewise.
- * lib/strdup.c: Likewise.
- * lib/strerror.c: Likewise.
-
-2004-08-30 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * Makefile.am: Added headers to SUBDIRS.
- * configure.ac: Check for AC_SYS_LARGEFILE.
- Use AC_CONFIG_LINKS to provide for fnmatch.h and getopt.h on
- the systems where these are missing
- Check for argp and replace it if necessary.
- * src/Makefile.am: Updated
- * src/fnmatch.h: Moved to headers/
- * src/getopt.h: Likewise.
- * src/main.c: Option parsing rewritten using argp. Improved
- option consistency checking.
- * src/rmt.c: Include getopt.h
-
- * src/argp-ba.c: New file
- * src/argp-eexst.c: New file
- * src/argp-fmtstream.c: New file
- * src/argp-fs-xinl.c: New file
- * src/argp-help.c: New file
- * src/argp-parse.c: New file
- * src/argp-pv.c: New file
- * src/argp-pvh.c: New file
- * src/argp-xinl.c: New file
- * src/pin.c: New file
-
- * headers: New directory
- * headers/Makefile.am: New file
- * headers/getopt.h: New file
- * headers/argp.h: New file
- * headers/fnmatch.h: New file
- * headers/.cvsignore: New file
-
-2004-03-02 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/util.c (copy_files_disk_to_disk): Bugfix. If a file
- grew n bytes in copy-pass mode, these n bytes got prepended
- to the contents of all subsequent files. Fix provided by
- Holger Fleischmann <holger_fleischmann@mra.man.de>
- * THANKS: Added Holger Fleischmann.
-
-2004-02-27 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * src/makepath.c: Remove unneded typedefs
-
- * src/copyin.c: Remove __MSDOS__ conditionals
- * src/copyout.c: Likewise
- * src/copypass.c: Likewise
- * src/main.c: Likewise
- * src/tar.c: Likewise
- * src/util.c: Likewise
-
-2004-02-27 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- Changed from flat to deep package layout. Added the framework
- for NLS support.
-
- * .cvsignore: Updated
- * Makefile.am: Updated
- * configure.ac: Updated
- * NEWS: Updated
- * README-alpha: Updated
- * THANKS: Updated
-
- * autogen.sh: New file
-
- * alloca.c: Moved to src
- * argmatch.c: Likewise
- * bcopy.c: Likewise
- * dstring.h: Likewise
- * copyin.c: Likewise
- * copyout.c: Likewise
- * copypass.c: Likewise
- * cpio.h: Likewise
- * cpiohdr.h: Likewise
- * defer.c: Likewise
- * defer.h: Likewise
- * dirname.c: Likewise
- * dstring.c: Likewise
- * dstring.h: Likewise
- * error.c: Likewise
- * extern.h: Likewise
- * filemode.c: Likewise
- * filetypes.h: Likewise
- * fnmatch.c: Likewise
- * fnmatch.h: Likewise
- * getopt.c: Likewise
- * getopt.h: Likewise
- * getopt1.c: Likewise
- * global.c: Likewise
- * idcache.c: Likewise
- * main.c: Likewise
- * makepath.c: Likewise
- * mkdir.c: Likewise
- * mt.c: Likewise
- * rmt.c: Likewise
- * rmt.h: Likewise
- * rtapelib.c: Likewise
- * safe-stat.h: Likewise
- * strdup.c: Likewise
- * strerror.c: Likewise
- * stripslash.c: Likewise
- * system.h: Likewise
- * tar.c: Likewise
- * tar.h: Likewise
- * tarhdr.h: Likewise
- * userspec.c: Likewise
- * util.c: Likewise
- * xmalloc.c: Likewise
- * xstrdup.c: Likewise
-
- * cpio.1: Moved to doc
- * cpio.texi: Likewise
- * mt.1: Likewise
-
- * src: New directory
- * src/.cvsignore: New file
- * src/Makefile.am: Likewise
- * src/alloca.c: Likewise
- * src/argmatch.c: Likewise
- * src/bcopy.c: Likewise
- * src/copyin.c: Likewise
- * src/copyout.c: Likewise
- * src/copypass.c: Likewise
- * src/cpio.h: Likewise
- * src/cpiohdr.h: Likewise
- * src/defer.c: Likewise
- * src/defer.h: Likewise
- * src/dirname.c: Likewise
- * src/dstring.c: Likewise
- * src/dstring.h: Likewise
- * src/error.c: Likewise
- * src/extern.h: Likewise
- * src/filemode.c: Likewise
- * src/filetypes.h: Likewise
- * src/fnmatch.c: Likewise
- * src/fnmatch.h: Likewise
- * src/getopt.c: Likewise
- * src/getopt.h: Likewise
- * src/getopt1.c: Likewise
- * src/gettext.h: Likewise
- * src/global.c: Likewise
- * src/idcache.c: Likewise
- * src/main.c: Likewise
- * src/makepath.c: Likewise
- * src/mkdir.c: Likewise
- * src/mt.c: Likewise
- * src/rmt.c: Likewise
- * src/rmt.h: Likewise
- * src/rtapelib.c: Likewise
- * src/safe-stat.h: Likewise
- * src/strdup.c: Likewise
- * src/strerror.c: Likewise
- * src/stripslash.c: Likewise
- * src/system.h: Likewise
- * src/tar.c: Likewise
- * src/tar.h: Likewise
- * src/tarhdr.h: Likewise
- * src/userspec.c: Likewise
- * src/util.c: Likewise
- * src/xmalloc.c: Likewise
- * src/xstrdup.c: Likewise
-
- * doc: New directory
- * doc/.cvsignore: New file
- * doc/Makefile.am: New file
- * doc/cpio.1: New file
- * doc/cpio.info: New file
- * doc/cpio.texi: New file
- * doc/mt.1: New file
-
- * po: New directory
- * po/.cvsignore: New file
- * po/LINGUAS: New file
- * po/Makevars: New file
- * po/POTFILES.in: New file
-
-2003-11-28 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * configure.ac: Added various checks
- * Makefile.am (rmt_LDADD): Added.
- * error.c: Updated
- * rmt.c: Removed useless private_errstring
- * system.h: Updated
- * userspec.c: Changed the way of handling declared vs. undeclared
- system calls.
- * strerror.c: New file. Borrowed from GNU Radius.
-
- * copyin.c: Removed kludgy declaration of delayed_seek_count.
- * copypass.c: Likewise
- * extern.h: Declare delayed_seek_count.
- * mkdir.c: Fixed handling of undeclared errno
- * mt.c: Likewise
- * util.c: Likewise
- * rtapelib.c: Likewise
-
-2003-11-28 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * TODO: New file
-
- * README-alpha: New file
- * Makefile.am: Require at least version 1.7.1
- * configure.ac: Check for locale.h
- * main.c (main): Call setlocale. Thanks
- Mitsuru Chinen <mchinen@yamato.ibm.com> for the patch.
- * THANKS: Updated
-
-2003-11-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
-
- * configure.ac: Added to the repository
- * Makefile.am: Likewise
- * NEWS: Likewise
- * README: Likewise
- * AUTHORS: Likewise
- * .cvsignore: Likewise
-
- * configure.in: Removed
- * Makefile.in: Removed
- * makefile.pc: Removed
- * configure: Removed
-
- * alloca.c: Added to the repository
- * argmatch.c: Likewise
- * bcopy.c: Likewise
- * cpio.h: Likewise
- * cpiohdr.h: Likewise
- * defer.c: Likewise
- * defer.h: Likewise
- * dirname.c: Likewise
- * dstring.c: Likewise
- * dstring.h: Likewise
- * error.c: Likewise
- * filemode.c: Likewise
- * filetypes.h: Likewise
- * fnmatch.c: Likewise
- * fnmatch.h: Likewise
- * getopt.c: Likewise
- * getopt.h: Likewise
- * getopt1.c: Likewise
- * idcache.c: Likewise
- * mkdir.c: Likewise
- * rmt.h: Likewise
- * rtapelib.c: Likewise
- * safe-stat.h: Likewise
- * strdup.c: Likewise
- * stripslash.c: Likewise
- * tar.c: Likewise
- * tar.h: Likewise
- * tarhdr.h: Likewise
- * xmalloc.c: Likewise
- * xstrdup.c: Likewise
-
- * makepath.c: Updated
- * mt.c: Likewise.
- * rmt.c: Likewise.
- * util.c: Likewise.
- * copyin.c: Likewise.
- * copyout.c: Likewise.
- * copypass.c: Likewise.
- * global.c: Likewise.
- * main.c: Likewise.
-
-Thu Jun 13 20:14:48 2002 John Oleynick (juo@gnu.org)
- * copyin.c: Strip leading / on absolute filenames after
- comparing to the list of files specified on the command line
- (instead of before). Problem reported by Jeff Holt.
- * Version 2.5 released.
-
-Thu Jun 13 00:20:30 2002 John Oleynick (juo@gnu.org)
- * Makefile.in: Fixed problem of looking in srcdir for info files.
- Bug reported by Mike Castle.
- * cpio.texi: Fixed typo. Problem reported by Fabrice Bauzac.
-
-Sun Jan 13 18:45:02 2002 John Oleynick (juo@gnu.org)
- * copyin.c: Fixed a problem skipping files with multiple links
- in a newc or CRC format archive. If the file with the shared copy
- of the data was skipped, but other links were not skipped, the
- other links were created as empty files. Bug reported by
- Hendrik-Jan Thomassen.
-
-Thu Dec 6 20:05:10 2001 John Oleynick (juo@gnu.org)
- * mt.c, mt.1: Merged Debian --rsh-command option and -V fix.
- * copyout.c, copypass.c, util.c, extern.h: Modified to warn
- if a file grows or its mtime is changed while it is being
- copied.
-
-Wed Dec 6 00:02:04 2001 John Oleynick (juo@gnu.org)
- * Many files: Updated FSF's address in copyright notices.
-
-Wed Aug 29 23:57:05 2001 John Oleynick (juo@gnu.org)
- * Many files: Numerous fixes from Debian, Red Hat and SuSE
- GNU/Linux distributions.
-
-Tue Jan 16 19:03:05 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * util.c: An I/O error reading a file would cause the last byte
- of the next file to be corrupted in the archive. Thanks to a
- buggy NT NFS server for pointing out this problem.
- * Version 2.4.2 released.
-
-Tue Jan 9 23:19:37 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * copyout.c: missed 1 part of last bug fix.
-
-Mon Jan 8 16:49:01 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * copyout.c, copypass.c: Use result of readlink() as length
- of link name instead of size from lstat(). On some OS's lstat()
- doesn't return the true length in size. Bug reported by
- Robert Joop (rj@rainbow.IN-berlin.DE).
-
-Wed Dec 20 10:52:56 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * rmt.c: Added temporary kludge so make rmt will work on Linux.
- * configure.in: Only define HAVE_UTIME_H if utime.h declares
- struct utimbuf.
- * Makefile.in: Change prefix, exec_prefix and bindir to get their
- values from configure. Added cpio.info to DISTFILES.
- * cpio.texi: Added INFO-DIR-ENTRY.
- * Version 2.4.1 released.
-
-Wed Nov 22 19:37:05 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * cpio.texi: Updated release date and FSF's address.
- * NEWS: Listed major new features for 2.4.
- * mt.c, mt.1: Added seek and fsfm commands.
- * Version 2.4 released.
-
-Tue Jun 27 19:14:27 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * configure.in: fixed for new autoconf. Added check to make
- sure fnmatch() works.
- * Makefile.in: changed realclean to maintainer-clean. Added
- support to handle fnmatch separate from other LIBOBJS.
- * cpio.texi: More changes for 2.4.
-
-Wed Dec 14 16:14:27 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * copypass.h: When given the -a option, set the access time of
- the copy to be the access time of the original (instead of the
- modification time of the original). Reported by
- karney@pppl.gov (Charles Karney).
- * cpio.texi: Updated with changes for 2.4.
-
-Wed Nov 3 18:18:07 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * safe-stat.h, Makefile.in: New file used by mkdir.c. This will go
- away when we get the real safe-xstat.[ch]in for mkdir.c.
- * main.c: Don't mention [--null] twice in -p's usage message.
- Changed --no-absolute-paths to --no-absolute-filenames.
- * cpio.1: Updated man page with new features.
- * cpio.texi, texinfo.tex, Makefile.in: Added texi documentation
- from Robert Carleton (rbc@gnu.ai.mit.edu).
-
-Mon Oct 3 00:46:30 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * makefile.pc, system.h: Changes to compile with Borland C++ 4.0.
-
-Thu Sep 29 22:15:50 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * makepath.c: Don't #define index if it is already #defined.
-
- * mt.c: Check for __hpux defined instead of __hpux__. Reported
- by ericb@lsid.hp.com (Eric Backus).
-
-Thu Sep 29 11:21:31 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * extern.h, util.c, copyout.c, copypass.c, main.c, global.c:
- Never mind --ignore-disk-input-errors flag, we'll just always
- do that, like tar.
-
- * global.c, extern.h, main.c, copyin.c, copyout.c, copypass.c:
- Added --quiet flag to supress printing number of blocks copied.
-
- * global.c, extern.h: If compiled with gcc, make input_bytes
- and output_bytes `long long' instead of `long'. We need more
- than 32 bits to keep track of the number of bytes copied to
- and from tape drives that hold more than 4Gbytes.
-
- * util.c, copyin.c, main.c, global.c, extern.h: Added
- --only-verify-crc flag to read a CRC format archive and verify
- its contents' CRCs.
-
- * copyout.c: Fixed problem with creating oldc format archives
- on machines with 16 bit ints. Reported by mpoole@cix.compulink.co.uk
- (Martin Poole).
-
- * mt.c: Need to open tape WR_ONLY for erase command (and probably
- others?). Reported by robert@hst.e.technik.uni-kl.de (Robert
- Vogelgesan). Accept `eject' as a synonym for `offline'. Accept
- `-t' as a synonym for `-f' (to be compatible with HPUX mt, which
- only accepts `-t').
-
-Wed Sep 28 12:01:55 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu)
- * extern.h, global.c, main.c, util.c: only write sparse files
- when given --sparse flag.
- * extern.h, util.c, copyout.c, copypass.c, main.c, global.c:
- Added support for --ignore-disk-input-errors flag.
-
-Wed Aug 24 12:55:38 1994 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
-
- * configure.in: Replace calls to AC_REMOTE_TAPE and AC_RSH
- with equivalent code, since those macros are going away.
-
-Sun Feb 13 00:56:48 1994 John Oleynick (juo@goldman.gnu.ai.mit.edu)
- * extern.h, global.c, main.c, util.c: Added code to
- tape_buffered_peek() to properly handle large, corrutped
- archives, without overrunning the allocated buffer and
- dumping core. Also changed the way the input and output
- buffers are allocated in initialize_buffers().
-
-Tue Jan 25 01:04:32 1994 John Oleynick (juo@goldman.gnu.ai.mit.edu)
- * copyin.c, copyout.c, copypass.c, extern.h, main.c, tar.c, util.c:
- Redid i/o buffer code. Previously, the same routines buffered input and
- output for accessing the archive and the filesystem. Now there are
- separate routines for buffering input and output and for buffering the
- archive and the filesystem. This simplifies much of the buffer code
- (e.g., only input from the archive has to check for end of tape and
- allow the tape to be changed, only output to the filesystem has to
- handle byte and word swapping, etc.; previously one routine had to
- handle all of these special cases) This is how the routines got split
- and renamed (old name -> new name):
-
- clear_rest_of_block -> tape_clear_rest_of_block
- copy_files -> copy_files_tape_to_disk
- " -> copy_files_disk_to_disk
- " -> copy_files_disk_to_tape
- copy_buf_out -> disk_buffered_write
- " -> tape_buffered_write
- copy_in_buf -> tape_buffered_read
- empty_output_buffer -> tape_empty_output_buffer
- " -> disk_empty_output_buffer
- fill_input_buffer -> tape_fill_input_buffer
- " -> disk_fill_input_buffer
- pad_output -> tape_pad_output
- peek_in_buf -> tape_buffered_peek
- skip_padding -> tape_skip_padding
- toss_input -> tape_toss_input
-
- * extern.h, global.c, main.c, util.c: Added support for
- writing sparse files.
-
-Tue Dec 28 23:01:36 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
- * util.c, system.h, makepath.c, extern.h: don't define chown()
- and don't typedef uid_t and gid_t if we are being compiled
- by DJGPP.
-
- * copyin.c, extern.h, global.c, main.c: Added support for
- --rename-batch-file.
-
- * copyin.c, copyout.c, extern.h: Cleaned up to pass gcc -Wall.
-
-Wed Dec 22 02:17:44 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * makepath.c, copypass.c, copyin.c: If cpio was creating a
- directory that contained `.' in the pathname (e.g. `foo/./bar'),
- it would complain that it could not create `.', since it already
- exists. From schwab@issan.informatik.uni-dortmund.de (Andreas
- Schwab).
-
- * mt.c: Added "eject" as a synonym for "offline".
-
- * util.c: Slight modification to when we lseek with
- BROKEN_LONG_TAPE_DRIVER (do it every 1Gb, instead
- of every 2Gb).
-
- * copyin.c, global.c, extern.h: Added --no-absolute-paths option,
- to ignore absolute paths in archives.
-
-Tue Dec 21 01:30:59 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * util.c: Fix for copying new_media_message_after_number. From
- Christian.Kuehnke@arbi.informatik.uni-oldenburg.de (Christian
- Kuehnke).
-
-Thu Jul 29 20:35:57 1993 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu)
-
- * Makefile.in (config.status): Run config.status --recheck, not
- configure, to get the right args passed.
-
-Mon Jul 19 23:01:00 1993 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
-
- * Makefile.in (libdir): Use standard GNU value --
- $(exec_prefix)/lib, not /etc.
- (.c.o): Put CFLAGS last.
-
-Thu Jul 8 19:43:39 1993 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
-
- * Makefile.in: Add rules for remaking Makefile, configure,
- config.status.
-
-Mon Jul 5 14:54:08 1993 John Oleynick (juo@spiff.gnu.ai.mit.edu)
-
- * cpio.1: Updated man page for 2.3.
- * Makefile.in: Create distribution with .gz extension, instead of .z.
-
-Tue Jun 29 18:54:37 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * Makefile.in: Added installdirs target (using mkinstalldirs).
- * Added mkinstalldirs script.
- * main.c, mt.c: Added --help option. Changed usage() to
- take a stream and exit value (so --help can print on stdout
- and return a 0 exit status).
- * extern.h: Removed usage()'s prototype (it was out of date,
- and only used in main.c).
-
-Thu May 6 00:22:22 1993 John Oleynick (juo@hal.gnu.ai.mit.edu)
-
- * cpio.1: Added hpbin and hpodc.
-
-Tue May 4 00:32:29 1993 John Oleynick (juo@hal.gnu.ai.mit.edu)
-
- * copyin.c (process_copy_in), copypass.c (process_copy_pass): When
- deleting an existing file, if the file is a directory, use rmdir()
- instead of unlink().
-
-Thu Apr 29 14:43:56 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * tar.c (read_in_tar_header): Clear non-protection bits from
- mode, in case tar has left some device bits in there.
-
-Wed Apr 28 10:36:53 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * util.c: Added code to try and work around broken tape drivers
- that have problems with tapes > 2Gb.
-
- * copyout.c (process_copy_out): Pass file_hdr to
- writeout_other_defers() and add_link_defer() by reference,
- not by value.
-
- * copyin.c (process_copy_in): Pass file_hdr to defer_copyin()
- and create_defered_links() by reference, not by value.
-
- * defer.c: include <sys/types.h> (to build on BSD 4.3 on HP300)
-
-Fri Apr 16 18:01:17 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * mt.c, util.c: Include <sys/mtio.h> if HAVE_SYS_MTIO_H is
- defined, not HAVE_MTIO_H.
-
-Wed Apr 14 17:37:46 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * util.c: Include <sys/io/trioctl.h> if HAVE_SYS_IO_TRIOCTL_H
- is defined.
-
- * mt.c: Only include <sys/mtio.h> if HAVE_SYS_MTIO_H is defined.
-
-Fri Apr 2 13:09:11 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu)
-
- * configure.in: Added fnmatch to AC_REPLACE_FUNCS. Added
- sys/io/trioctl.h to AC_HAVE_HEADERS.
-
- * Makefile.in: Removed fnmatch.o from OBJS.
-
- * copyin.c: Only include "fnmatch.h" if FNM_PATHNAME isn't
- defined yet.
-
- * mt.c: Include <sys/io/trioctl.h> if HAVE_SYS_IO_TRIOCTL_H is
- defined.
-
-Mon Mar 29 17:04:06 1993 John Oleynick (juo@hal.gnu.ai.mit.edu)
-
- * Many changes for supporting HPUX Context Dependent Files;
- also some bug fixes to fix problems with multiply (hard) linked
- device files; minor changes to support HPUX format archives
- (slightly broken?) System V.4 posix tar archives and HPUX
- posix tar archives.
-
- * Makefile.in: New files defer.o, defer,c and defer.h; added
- -DSYMLINK_USES_UMASK and -DHPUX_CDF comments; changed dist rule
- to use gzip with tar, instead of compress.
-
- * copyin.c: changes for new arf_hpbinary and arf_hpascii formats;
- HPUX CDF's; DEBUG_CPIO; fixes to properly handle multiple
- links in newc and crc format archives (new routines defer_copyin(),
- create_defered_links(), create_final_defers()); move most
- multiple (hard) link code to new routines link_name() and
- link_to_maj_min_ino(); use new macro UMASKED_SYMLINK instead of
- symlink().
-
- * copyout.c: fixes to properly handle multiple links in newc
- and crc format archives (new routines last_link(),
- count_defered_links_to_dev_ino(), add_link_defer(),
- writeout_other_defers(), writeout_final_defers(),
- writeout_defered_file()); support for new arf_hpbinary and
- arf_hpascii formats; support for HPUX CDF's.
-
- * copypass.c: move most multiple link code to new routines
- link_name() and link_to_maj_min_ino(); use new macro UMASKED_SYMLINK
- instead of symlink(); support for HPUX CDF's.
-
- * extern.h: added arf_hpascii and arf_hpbinary archive enum types;
- added debug_flag.
-
- * global.c: added debug_flag.
-
- * main.c: added debug_flag; support for hpodc and hpbin formats.
-
- * makepath.c: split from standard makpath.c to add support
- for HPUX CDF's.
-
- * mt.c: added !defined(__osf__) (from Andrew Marquis
- <amarquis@genome.wi.mit.edu>).
-
- * system.h: new macro UMASKED_SYMLINK
-
- * tar.c: minor changes to read (slightly broken?) System V.4 posix
- tar archives and HPUX posix tar archives.
-
- * util.c: HPUX CDF support (including new routines
- add_cdf_double_slashes() and islasparentcdf()); new routine
- umasked_symlink().
-
-Sun Mar 14 23:00:14 1993 Jim Meyering (meyering@comco.com)
-
- * copypass.c (process_copy_pass): Use <=, not just <, when comparing
- mtimes. From Pieter Bowman <bowman@math.utah.edu>.
-
-Fri Jan 15 14:35:37 1993 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu)
-
- * copyin.c: Move include of fnmatch.h to get right FNM* macros.
-
-Tue Nov 24 08:45:32 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
-
- * Version 2.2.
-
- * copyout.c (process_copy_out): Add parens for gcc -Wall.
- From Jim Meyering.
-
- * system.h: Use HAVE_FCNTL_H, not USG.
-
- * dstring.c, mt.c, system.h: Use HAVE_STRING_H, not USG.
-
-Fri Nov 20 22:47:18 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
-
- * copyin.c (read_in_binary): Copy the dev and ino that are
- already in `file_hdr' into `short_hdr'.
- From dao@abars.att.com (David A Oshinsky).
-
- * system.h [!_POSIX_VERSION]: Declare lseek as off_t, not long.
- From Karl Berry.
-
-Wed Oct 14 13:53:41 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
-
- * Version 2.1.
-
-Tue Oct 13 22:51:34 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
-
- * main.c: Add --swap equivalent to -b.
-
- * mt.c: Add f_force_local variable and -V --version option.
-
-Fri Oct 2 18:42:27 1992 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu)
-
- * main.c (long_opts, usage): Add --force-local option.
-
-Thu Oct 1 23:23:43 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
-
- * main.c (process_args) [__MSDOS__]: Don't call geteuid.
-
- * copyin.c (read_in_{old,new}_ascii): Use `l' for sscanf into longs.
- * copyout.c (write_out_header): Ditto for sprintf.
- * global.c, extern.h: Make input_size and output_size long.
-
-Thu Sep 10 23:39:30 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
-
- * global.c, extern.h: Add new var f_force_local to work with
- rmt.h change from tar.
-
-Sun Aug 23 00:18:20 1992 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
-
- * Version 2.0.
-
- * tar.c (otoa): Compute value in an unsigned long, not an int.
- * copyout.c (write_out_header) [__MSDOS__]: Don't use dev_t.
-
- * main.c (process_args): By default, don't chown for non-root users.
-
-Sat Aug 22 14:17:54 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
-
- * global.c, extern.h: Use uid_t and gid_t.
-
- * main.c (main) [__EMX__]: Expand wildcards.
- * system.h [__EMX__]: Alias some error names. From Kai Uwe Rommel.
-
- * extern.h [__STDC__]: Use prototypes.
-
- * copyin.c (process_copy_in), copyout.c (process_copy_out),
- copypass.c (process_copy_pass): Open all files with O_BINARY.
- Add cast to chmod call.
- * util.c: Add cast to bcopy calls. Make hash_insert static.
- From Kai Uwe Rommel.
-
-Thu Aug 20 22:03:49 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
-
- * util.c (peek_in_buf): Don't print "end of file" before
- getting the next reel of medium.
-
- * copyin.c (read_in_old_ascii): Allocate space for NUL terminator.
- Print newline for dot line when done, even if appending.
-
-Thu Jul 23 16:34:53 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
-
- * tar.c (write_out_tar_header, read_in_tar_header)
- [__MSDOS__]: Don't try to get user and group names.
- * extern.h: Don't declare the functions to do it (need uid_t).
-
- * main.c [__MSDOS__]: Ignore the -R option.
-
- * system.h: Define makedev if defining major and minor.
-
- * copyin.c, copyout.c [__MSDOS__]: setmode on archive_des, not
- 0 and 1.
-
-Sat Jul 18 14:30:55 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
-
- * tar.c, stripslash.c, userspec.c, cpiohdr.h, tar.h, tarhdr.h,
- system.h: New files.
- * Move portability stuff from various files to system.h.
- * cpio.h: Rename header structure and members, and add
- new structure for SVR4 format.
- * copyin.c, copyout.c: Use the new structure internally, the
- old one only for I/O in the old formats.
- * copyin.c (read_in_header): Recognize the new archive formats.
- (read_in_new_ascii, read_pattern_file, skip_padding): New functions.
- (swab_array): Do the swapping using char pointers instead of
- bitwise arithmetic.
- (process_copy_in): Handle byte and halfword swapping and new formats.
- Ok if a directory we want to make already exists, but set its perms.
- Do chmod after chown to fix any set[ug]id bits.
- Use `struct utimbuf' instead of a long array.
- * copyout.c (write_out_header): Handle new formats.
- (process_copy_out): Use `struct utimbuf'.
- Handle appending and new formats.
- Remove any leading `./' from filenames.
- (read_for_checksum, clear_rest_of_block, pad_output): New functions.
- * copypass.c (process_copy_pass): Use `struct utimbuf'.
- Ok if a directory we want to make already exists, but set its perms.
- Do chmod after chown to fix any set[ug]id bits.
- Don't change perms of `.'.
- * extern.h, global.c: Replace the separate format flags with
- one variable. Add new variables for the new options.
- * main.c: Add new options -A --append, -H --format, -C --io-size,
- -M --message, --no-preserve-owner, -R --owner, -E --pattern-file,
- -V --dot, -s --swap-bytes, -S --swap-halfwords, -b, -I, -k, -O.
- (usage): Document them.
- (process_args): Recognize them. Use open_archive.
- (initialize_buffers): Allow room for tar archives and double buffers.
- * util.c (empty_output_buffer_swap): New function.
- (empty_output_buffer): Call it if swapping current file.
- Check additional end of media indicators.
- (swahw_array, peek_in_buf, prepare_append, open_archive,
- set_new_media_message): New functions.
- (fill_input_buffer): Don't print error message if end of media.
- (toss_input): Don't seek, always read.
- (copy_files): Update crc if needed.
- (find_inode_file, add_inode): Check major and minor numbers as
- well as dev.
- (get_next_reel): Prompt user if archive name is unknown.
- Print fancy messages.
- Close the archive and reopen it.
-
- Above primarily from John Oleynick <juo@klinzhai.rutgers.edu>.
-
- * util.c (find_inode_file): Use modulus when computing initial
- loop index.
- (add_inode): Zero out new entry.
- From scott@sctc.com (Scott Hammond).
-
- * cpio.h, copyin.c, copyout.c: Rename `struct cpio_header'
- members from h_foo to c_foo.
-
-Wed May 20 00:09:26 1992 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
-
- * copyin.c: If we include a header file specifically to get
- major et al., assume we have them.
-
-Mon Mar 9 19:29:20 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
-
- * mt.c (main): rmtclose the tape file descriptor.
-
- * main.c (main): rmtclose the archive, if not in copy-pass mode.
-
- * util.c (create_all_directories): Don't print a message when
- creating a directory, for UNIX compat.
-
- * copyin.c (process_copy_in), copypass.c (process_copy_pass):
- Skip file if it has the same timestamp as existing file, not just
- if it is older than existing file, for UNIX compat.
-
-Tue Mar 3 12:06:58 1992 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu)
-
- * main.c, mt.c (usage): Document long options as starting with
- -- instead of +.
-
- * extern.h: Only declare lseek if not _POSIX_VERSION.
-
-Tue Dec 24 00:19:45 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
-
- * copyin.c: Use MAJOR_IN_MKDEV and MAJOR_IN_SYSMACROS instead
- of USG and _POSIX_VERSION to find major and minor macros.
-
- * mt.c: Use unistd.h and stdlib.h if available.
-
- * copyin.c, copyout.c, copypass.c, util.c, extern.h: Change
- POSIX ifdefs to HAVE_UNISTD_H and _POSIX_VERSION.
-
-Sun Aug 25 06:31:08 1991 David J. MacKenzie (djm at apple-gunkies)
-
- * Version 1.5.
-
- * bcopy.c: New file (moved from util.c).
-
- * mt.c (print_status): Not all hpux machines have mt_fileno
- and mt_blkno; rather than trying to track HP's product line,
- just assume none of them have them.
-
- * util.c (copy_buf_out, copy_in_buf): Use more efficient
- copying technique for a big speedup.
-
-Fri Aug 2 04:06:45 1991 David J. MacKenzie (djm at apple-gunkies)
-
- * configure: Support +srcdir. Create config.status.
- Remove it and Makefile if interrupted while creating them.
-
-Thu Jul 18 09:43:40 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
-
- * Many files: use __MSDOS__ instead of MSDOS.
-
- * util.c, configure: Use NO_MTIO instead of HAVE_MTIO, to keep
- up with tar and rtapelib.c.
-
-Mon Jul 15 13:45:30 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
-
- * configure: Also look in sys/signal.h for signal decl.
-
-Thu Jul 11 01:50:32 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
-
- * Version 1.4.
-
- * configure: Remove /etc and /usr/etc from PATH to avoid
- finding /etc/install.
-
-Wed Jul 10 01:40:07 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
-
- * makefile.pc: Rewrite for Turbo C 2.0.
- * util.c [__TURBOC__] (utime): New function.
- * alloca.c, tcexparg.c: New files.
-
- * extern.h [STDC_HEADERS]: Don't declare malloc and realloc.
-
- * main.c [MSDOS]: Make binary mode the default.
- * copyin.c, copyout.c: Make stdin or stdout binary mode as
- appropriate (so cpio archives don't get corrupted).
-
- * Many files: Use <string.h> if STDC_HEADERS as well as if USG.
-
- * configure, Makefile.in: $(INSTALLPROG) -> $(INSTALL),
- $(INSTALLTEXT) -> $(INSTALLDATA).
-
-Mon Jul 8 23:18:28 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
-
- * configure: For some library functions that might be missing,
- conditionally add the .o files to Makefile instead of
- defining func_MISSING.
- * mkdir.c: Renamed from mkrmdir.c.
-
-Sat Jul 6 02:27:22 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
-
- * configure: echo messages to stdout, not stderr.
- Use a test program to see if alloca needs -lPW.
-
-Thu Jun 27 16:15:15 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
-
- * copyin.c (process_copy_in), copyout.c (process_copy_out),
- copypass.c (process_copy_pass): Check close return value for
- delayed error notification because of NFS.
-
-Thu Jun 20 02:43:33 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
-
- * configure: Include $DEFS when compiling test programs.
-
- * util.c: Only declare getpwuid and getgrgid if not POSIX.
-
- * Version 1.3.
-
- * copyin.c: Use time_t, not long, for time values.
-
- * mt.c (print_status): Special cases for HP-UX and Ultrix.
-
- * util.c: Compile bcopy if USG or STDC_HEADERS, not BCOPY_MISSING.
-
-Tue Jun 11 16:40:02 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
-
- * copyin.c: Don't include sys/sysmacros.h if _POSIX_SOURCE.
-
- * copyin.c, copyout.c, copypass.c: Don't include sys/file.h if POSIX.
-
- * util.c: Include sys/types.h before, not after, pwd.h and grp.h.
-
- * configure: New shell script to aid configuration and create
- Makefile from Makefile.in.
-
- * copyin.c (process_copy_in): Use POSIX.2 fnmatch instead of
- glob_match.
-
-Mon Jun 10 22:11:19 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
-
- * global.c, extern.h: New variable, name_end.
- * main.c (process_args, usage): Add -0 +null option to set it.
- * copypass.c (process_copy_pass), copyout.c (process_copy_out):
- Use it.
-
- * dstring.c (ds_fgetstr): New function made from ds_fgets.
- (ds_fgets, ds_fgetname): Implement as front ends to ds_fgetstr.
-
-Sun Jun 2 15:45:24 1991 David J. MacKenzie (djm at wheat-chex)
-
- * most files: use GPL version 2.
-
-Sat May 18 11:39:22 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
-
- * copyin.c, copypass.c: Take out #ifdef MSDOS around chown.
- * util.c [MSDOS]: Provide dummy chown.
-
-Fri May 17 21:29:05 1991 David J. MacKenzie (djm at churchy.gnu.ai.mit.edu)
-
- * Version 1.2.
-
- * makefile.pc, cpio.cs: Update for new source and object files.
-
-Fri Mar 15 05:48:36 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
-
- * global.c, extern.h: New variable `archive_desc'.
- * main.c (process_args): Set it.
- * copyout.c (process_copy_out), copyin.c (process_copy_in):
- Use it.
-
- * copyout.c (process_copy_out), copyin.c (process_copy_in):
- Remote tapes are special and not seekable; don't fstat them.
-
- * main.c (main, usage): Add -F, +file option. Use rmtopen.
- (main): Exit after printing version number.
- * util.c (empty_output_buffer): Use rmtwrite instead of write.
- (fill_input_buffer): Use rmtread instead of read.
- (tape_offline): Use rmtioctl instead of ioctl.
- Test HAVE_MTIO instead of MTIO_MISSING, for tar compatibility.
-
-Thu Mar 14 17:49:57 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
-
- * util.c (create_all_directories): Use make_path to do the work.
-
-Sat Jan 12 15:32:15 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
-
- * copyin.c, copyout.c, copypass.c, util.c: Only declare
- `errno' if not MSDOS. Some Unix errno.h do, some don't . . . .
-
- * global.c, extern.h: Make `input_size' and `output_size'
- unsigned, for 16 bit machines.
-
- * copyin.c (print_name_with_quoting): All non-ctrl chars are
- printable on MS-DOS.
-
- * util.c (empty_output_buffer): Never make sparse files;
- can create unrunnable executables.
- * copyin.c, copyout.c, copypass.c: Callers changed.
- * util.c (finish_output_file): Function removed.
-
-Tue Nov 6 15:47:16 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * copyin.c, util.c, extern.h: Rename copystring to xstrdup.
-
-Mon Oct 29 02:24:41 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * util.c (empty_output_buffer): Only make sparse files if
- NO_SPARSE_FILES is undefined, to accomodate dumb kernels.
-
-Wed Jul 25 18:48:35 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * util.c (getuser, getgroup): Make uid and gid unsigned short,
- not int.
-
-Sat Jul 21 00:44:44 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * copyin.c, copyout.c, copypass.c, util.c, cpio.h: Add ifdefs
- for MSDOS.
-
-Sun Jul 15 23:51:48 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * copyin.c, copyout.c, copypass.c, global.c, extern.h, util.c:
- Use longs where appropriate, for 16 bit machines.
-
-Sun Jul 8 22:58:06 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * main.c (process_args, usage): Change -b option to -O (old), to
- allow adding byte swapping later.
-
-Sat Jul 7 14:48:35 1990 David J. MacKenzie (dave at edfmd)
-
- * Version 1.1.
-
- * cpio.h: Make `mtime' and `filesize' unsigned long.
- * copyin.c (read_in_binary), copyout.c (write_out_header):
- High short-word of `mtime' and `filesize' always comes first.
-
- * (read_in_ascii, read_in_binary): New functions, from code in
- read_in_header.
- (read_in_header): Search for valid magic number, then fill in
- rest of header using read_in_ascii and read_in_binary.
- * global.c, extern.h: New variable, `binary_flag'.
- * main.c (process_args): Recognize new -b +binary option.
- * util.c [BCOPY_MISSING] (bcopy): New function.
-
-Wed Jul 4 00:40:58 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * main.c (process_args): Add local pointers to functions to
- work around a pcc bug found on a Convex.
-
- * copyin.c (process_copy_in), util.c (toss_input,
- create_all_directories, add_inode): Don't use `index' as a
- variable name.
-
-Tue Jul 3 02:33:36 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * version 1.0.
-
-Mon Jul 2 23:18:56 1990 David J. MacKenzie (djm at twiddle)
-
- * copyin.c (process_copy_in), copyout.c (process_copy_out),
- copypass.c (process_copy_pass): Print "1 block", not "1 blocks".
-
- * copyin.c (process_copy_in), copypass.c (process_copy_pass):
- Unlink existing dest. file unless either it is newer and
- not unconditional, or it is a directory.
-
-Mon Jul 2 03:57:41 1990 David J. MacKenzie (dave at edfmd)
-
- * util.c (xrealloc): New function.
- * dstring.c (ds_resize): Use xrealloc instead of free and
- xmalloc. Never shrink the string.
-
- * copypass.c (process_copy_pass): More efficient
- string handling while constructing output filename.
-
- * global.c, extern.h, main.c, cpio.h: Change from an enum,
- `copy_command', to a pointer to a void function, `copy_function'.
-
- * cpio.h (struct cpio_header): Make most fields unsigned.
- Rename h_filesize to h_filesizes and h_mtime to h_mtimes, and
- add new `long' fields with the old names at the end of the
- structure.
- * copyin.c (read_in_header): Set the long fields from the
- short arrays, making sure longs are aligned properly.
- (process_copy_in, long_format): Use the long fields.
- * copyout.c (write_out_header): Set the short arrays from the
- long fields, making sure longs are aligned properly.
- (process_copy_out): Use the long fields.
-
- * global.c, extern.h: New variable `output_is_seekable'.
- * util.c (empty_output_buffer): If output_is_seekable, use
- lseek to write blocks of zeros.
- (finish_output_file): New function.
- * copyin.c (process_copy_in), copyout.c (process_copy_out),
- copypass.c (process_copy_pass): Set `output_is_seekable'
- correctly and call finish_output_file.
- * main.c (initialize_buffers): Allocate space for sentinel in
- `output_buffer'.
-
- * global.c, extern.h: New variable `numeric_uid'.
- * main.c (process_args): Accept -n +numeric-uid-gid option, like ls.
- * copyin.c (long_format): Use numeric_uid.
-
- * copyin.c (process_copy_in), copyout.c (process_copy_out),
- copypass.c (process_copy_pass): Don't (for verbose) print the
- names of files that are not copied because of errors. Try to
- create missing directories for all file types. Free temporary
- buffers on error.
-
-Sat Jun 30 14:28:45 1990 David J. MacKenzie (djm at apple-gunkies)
-
- * version.c: New file.
- * main.c: Add -V, +version option.
- * Makefile [dist]: Extract version number from version.c.
-
-Sat Jun 30 12:44:47 1990 David J. MacKenzie (dave at edfmd)
-
- * global.c, extern.h, copyin.c, copyout.c, util.c: Rename
- `{input,output}_is_regular' to `{input,output}_is_special' and
- reverse the truth value.
-
- * global.c, extern.h: New variable `input_is_seekable' to
- control whether to skip data with lseek or read.
- * copyin.c (process_copy_in): Set it.
- * util.c (toss_input): Use it.
-
- * global.c, extern.h: New variable `xstat' that selects stat
- or lstat for input files.
- * main.c (process_args): New option -L, +dereference to set
- xstat to stat instead of lstat.
- (usage): Document it.
- * copyout.c (process_copy_out), copypass.c
- (process_copy_pass): Use *xstat on input file.
-
-Sat Jun 30 01:53:12 1990 David J. MacKenzie (dave at edfmd)
-
- * dstring.c (ds_init): Return void because return value was
- never used.
- (ds_resize): Ditto, and free old value instead of new one.
-
- * util.c (empty_output_buffer, fill_input_buffer,
- copy_out_buf, copy_in_buf, toss_input, copy_files): Return
- void instead of an error value and make errors fatal
- immediately instead of several levels up, to prevent printing
- of multiple error messages by different levels of functions.
-
- * copyin.c (read_in_header): Return void, because the error
- handling all happens at lower levels.
- (print_name_with_quoting): New function.
- (long_format): Call print_name_with_quoting. Take additional
- arg for name of linked-to file, and print it if nonzero.
- (process_copy_in): For verbose listing of symlinks, read in
- the linkname and pass it to long_format.
-
- * extern.h: Declare some more functions.
-
-Thu Jun 28 16:07:15 1990 David J. MacKenzie (dave at edfmd)
-
- * copypass.c (process_copy_pass): Warn about unknown file types.
-
- * copyout.c (process_copy_out): Check fstat return for error.
- Record filesize of 0 for special files. Warn about unknown
- file types.
-
- * copyin.c (process_copy_in): Warn about unknown file types.
- (read_in_header): Warn about byte-reversed binary headers.
-
-Sat Jun 23 22:50:45 1990 David J. MacKenzie (dave at edfmd)
-
- * main.c (main): Set umask to 0 so permissions of created
- files are preserved.
-
- * copyin.c, copyout.c, copypass.c, util.c: Pass file
- descriptors as ints, not pointers to ints.
- Cast file timestamps and sizes to long *, not int *, for 16
- bit machines.
- Use lstat instead of stat, if available.
- Handle FIFO's, sockets, and symlinks, if supported by O.S.
-
- * copyin.c (process_copy_in), copyout.c (process_copy_out):
- Don't consider FIFO'S, sockets, etc. to be possible tape drives.
-
- * util.c (create_all_directories): Fix incorrect loop
- termination check. Only copy string if it contains slashes.
- Don't check whether directory "" exists.
- (tape_offline): Code moved from get_next_reel.
- (get_next_reel): Print message before taking tape offline.
- Read a line of arbitrary length.
-
- * copyout.c, copyin.c, copypass.c: Always use utime, not utimes.
-
- * copyin.c (swab_short): New macro.
- (swab_array): New function.
- (read_in_header): In binary mode, if a byte-swapped header is
- read, swap the bytes back.
- (process_copy_in, process_copy_pass): Don't stat each file to
- create unless !unconditional_flag. Create device files correctly.
- Don't temporarily allow files being created to be read by
- other users. Don't unnecessarily chmod special files.
-
-Thu May 31 20:51:43 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * copyin.c (long_format): Use mode_string to format
- file protections instead of doing it ourselves.
- (protections): Function removed.
-
-Sat Apr 14 02:31:01 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * cpio.h (struct cpio_header): Make inode, mode, uid, gid
- fields unsigned.
-
- * util.c (getgroup): New function.
- * copyin.c (long_format): Print group name of files.
- Print file size, etc. as unsigned integers, not signed.
-
- * main.c (process_args): If -t is given and neither -i, -o, or
- -p is given, assume -i.
-
- * Add -f, +nonmatching option.
- * main.c: Rename +out to +create, +in to +extract,
- +modification-time to +preserve-modification-time,
- +pass to +pass-through.
-
- * copyin.c (process_copy_in), copypass.c (process_copy_pass):
- Don't complain in chown fails because the user doesn't have
- permission.
-
-Fri Apr 13 13:53:20 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * Add ifdefs for USG/Xenix.
- * util.c (cpio_error): Function removed.
- * Use error instead of cpio_error, so system error messages
- will be included.
- * cpio.h: Rename 'hdr_struct' to 'struct cpio_header'.
- * Move definition of xmalloc from dstring.c to util.c.
- * global.c, extern.c: Add global `program_name'.
- * main.c (main): Set program_name.
- (process_args): Rename +reset-atime to +reset-access-time,
- +table to +list.
- Have +block-size take an argument.
-
-Thu Apr 12 13:33:32 1990 David J. MacKenzie (djm at rice-chex)
-
- * util.c (find_inode_file): Make inode an int, not a short.
-
- * Make functions that don't return a value have type void.
- Add some casts to function calls.
-
-Wed Apr 11 14:55:28 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * main.c (process_args): -i, -o, and -p don't take arguments.
-
- * main.c (process_args): Get the non-option args from the
- correct elements of argv.
-
-Tue Apr 10 00:20:26 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
-
- * Indent source code and update copyrights.
-
- * cpio.c (usage): Change `collection' to `archive' in message.
-
-Thu Dec 28 03:03:55 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu)
-
- * dstring.c (xmalloc): Don't return a null pointer if size is 0,
- on the assumption that trying to allocate 0 bytes is a bug that
- should be trapped.
-
-Wed Dec 20 03:24:48 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu)
-
- * All files: Change from GNU CPIO General Public License to
- GNU General Public License.
-
-Mon Dec 18 13:18:36 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu)
-
- * Makefile: Add clean target and defines for CC and LDFLAGS.
- Add dist target and SRCS, DISTFILES macros. Add tags and TAGS targets.
- * dstring.c (ds_fgets): Read characters into an int, not char.
- (xmalloc): New function.
- (out_of_memory): Function removed.
- Global: use xmalloc instead of malloc and out_of_memory.
- * extern.h, global.c: Make flag variables ints instead of chars for
- compatibility with getopt_long.
- * extern.h: Declare more functions.
- * main.c (usage): Put the whole usage message into a single string
- and fix errors.
- * util.c (create_all_directories): Remove unused variable.
- (get_next_reel): Ditto.
- * dstring.h: Declare function.
-
-Sat Dec 2 13:22:37 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu)
-
- * main.c: Change +copy-pass option to +pass, +copy-in to +in,
- +copy-out to +out, and +mkdir to +make-directories, and add null
- option to terminate table.
- (process_args): Use the same code to handle long and short named
- options.
- (usage): Mention long options in message.
-
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/contrib/cpio/FREEBSD-upgrade b/contrib/cpio/FREEBSD-upgrade
deleted file mode 100644
index a3e31a0..0000000
--- a/contrib/cpio/FREEBSD-upgrade
+++ /dev/null
@@ -1,29 +0,0 @@
-$FreeBSD$
-
-GNU cpio:
-
- Originals can be found at: ftp://ftp.gnu.org/pub/gnu/cpio
-
-Configure by:
-
- ./configure --disable-nls --without-libiconv-prefix \
- --without-libintl-prefix
-
-Trim by:
-
- rm Makefile.am Makefile.in aclocal.m4 config.h.in configure \
- configure.ac
- rm -r headers m4 rmt tests scripts po
- rm doc/Makefile.am doc/Makefile.in doc/mt.1 doc/cpio.info
- rm src/Makefile.am src/Makefile.in
- rm src/mt.c
- rm lib/Makefile.am lib/Makefile.in lib/Makefile.tmpl lib/alloca.c \
- lib/argmatch.[ch] lib/bcopy.c lib/fnmatch.c lib/fnmatch_.h \
- lib/fnmatch_loop.c lib/mkdir.c lib/quote.[ch] \
- lib/quotearg.[ch] lib/stdbool_.h lib/strcasecmp.c \
- lib/strdup.c lib/strerror.c lib/strncasecmp.c lib/sysexit_.h
-
-Import by:
-
- cvs import -m "Import GNU cpio 2.6 (trimmed)" src/contrib/cpio \
- GNU v2_6
diff --git a/contrib/cpio/INSTALL b/contrib/cpio/INSTALL
deleted file mode 100644
index 5458714..0000000
--- a/contrib/cpio/INSTALL
+++ /dev/null
@@ -1,234 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
-
-This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about. Run `./configure --help' for
-details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-Installation Names
-==================
-
-By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-`configure' recognizes the following options to control how it operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/contrib/cpio/NEWS b/contrib/cpio/NEWS
deleted file mode 100644
index 857ae89..0000000
--- a/contrib/cpio/NEWS
+++ /dev/null
@@ -1,155 +0,0 @@
-GNU cpio NEWS -- history of user-visible changes. 2007-06-08
-Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
-See the end of file for copying conditions.
-
-Please send cpio bug reports to <bug-cpio@gnu.org>.
-
-Version 2.8 - Sergey Poznyakoff, 2007-06-08
-
-* Option --owner can be used in copy-out mode, allowing to uniformly override
-ownership of the files being added to the archive.
-
-* Bugfixes:
-
-** Symlinks were handled incorrectly in copy-out mode.
-** Fix handling of large files.
-** Fix setting the file permissions in copy-out mode.
-** Fix CAN-2005-1111
-
-
-Version 2.7 - Sergey Poznyakoff, 2006-10-21
-
-* Improved error checking and diagnostics
-
-* Bugfixes
-** Fixed CAN-1999-1572
-** Allow to use --sparse in both copy-in and copy-pass.
-** Fix bug that eventually caused copying out the same hard-linked
-file several times to archive.
-** Fix several LFS-related issues.
-** Fix Debian bug 335580.
-
-
-Version 2.6 - Sergey Poznyakoff, 2004-12-20
-
-* Added NLS support
-
-* Improved configure script
-
-* Improved invocation consistency checking and help output
-
-* Printing warning about truncation of inode numbers is suppressed by
-default. See below.
-
-* New option --warning (-W) controls the level of output warnings:
-
- -Wnone Disables all warnings
- -Wtruncate Enable warning about truncation of the inode number
- -Wall Enables all warnings
-
- To disable a particular warning, prefix its name with 'no-', just
- like in gcc.
-
-* New option --to-stdout extracts files to standard output.
-
-* The output of `cpio --help' is largely improved.
-
-* Bugfixes:
-** If a file grew n bytes in copy-pass mode, these n bytes got prepended
-to the contents of all subsequent files.
-** Padding the archive with zero bytes upon truncation of the file being
-archived was broken.
-
-
-Major changes in version 2.5:
-
-* bug fixes from Debian, Red Hat, and SuSE GNU/Linux Distribution patches
-* --rsh-command option
-
-Major changes in version 2.4:
-
-* new texinfo documentation
-* --sparse option to write sparse files
-* --only-verify-crc option to verify a CRC format archive
-* --no-absolute-paths option to ignore absolute paths
-* --quiet option to supress printing number of blocks copied
-* handle disk input errors more gracefully
-
-Major changes in version 2.3:
-
-* in newc and crc format archives, only store 1 copy of multiply linked files
-* handle multiply linked devices properly
-* handle multiply linked files with cpio -pl even when the source and
- destination are on different file systems
-* support HPUX Context Dependent Files
-* read and write HPUX cpio archives
-* read System V.4 POSIX tar archives and HPUX POSIX tar archives
-* use rmdir, instead of unlink, to delete existing directories
-
-Major changes in version 2.2:
-
-* handle link counts correctly when reading binary cpio archives
-* configure checks for some libraries that SVR4 needs
-
-Major changes in version 2.1:
-
-* cpio can access remote non-device files as well as remote devices
-* fix bugs in the MS-DOS port
-* add --swap equivalent to -b option
-
-Version 2.0 adds the following features:
-
-Support for the SVR4 cpio formats, which can store inodes >65535, and
-for traditional and POSIX tar archives. Also adds these options:
-
--A --append append to instead of replacing the archive
--V --dot print a dot for each file processed
--H --format select archive format
--C --io-size select I/O block size in bytes
--M --message print a message at end of media volumes
---no-preserve-owner don't change files' owners when extracting
--R --owner set files' owners when extracting
--E --pattern-file list of shell filename patterns to process
--s --swap-bytes handle byte-order differences when extracting files
--S --swap-halfwords ditto
--b like -sS
--I input archive filename
--k recognize corrupted archives (we alawys do it, though)
--O output archive filename
-
-Some options of previous versions have been renamed in 2.0:
-
---binary was replaced by --format=bin
---portability was replaced by --format=odc
-
-Some options have changed meaning in 2.0, for SVR4 compatibility:
-
--O used to select the binary archive format, now selects the output file
--V used to print the version number, now prints a dot for each file
-
-Version 2.0 also fixes several bugs in the handling of files with
-multiple links and of multi-volume archives on floppy disks.
-
-----------------------------------------------------------------------
-Copyright information:
-
-Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
-
- Permission is granted to anyone to make or distribute verbatim copies
- of this document as received, in any medium, provided that the
- copyright notice and this permission notice are preserved,
- thus giving the recipient permission to redistribute in turn.
-
- Permission is granted to distribute modified versions
- of this document, or of portions of it,
- under the above conditions, provided also that they
- carry prominent notices stating who last changed them.
-
-Local variables:
-mode: outline
-paragraph-separate: "[ ]*$"
-eval: (add-hook 'write-file-hooks 'time-stamp)
-time-stamp-start: "changes. "
-time-stamp-format: "%:y-%02m-%02d"
-time-stamp-end: "\n"
-end:
diff --git a/contrib/cpio/README b/contrib/cpio/README
deleted file mode 100644
index fafff13..0000000
--- a/contrib/cpio/README
+++ /dev/null
@@ -1,71 +0,0 @@
-This is GNU cpio, a program to manage archives of files.
-As of version 2.0, it supports the features of the System V release 4
-cpio, including support for tar archives.
-
-This package also includes rmt, the remote tape server, and mt, a tape
-drive control program; these two programs will only be compiled if
-your system supports remote command execution, and tape drive control
-operations, respectively.
-
-See the file INSTALL for compilation and installation instructions for Unix.
-
-For non-Unix systems [ Note: The non-Unix makefiles have not been tested
- for this release ]
-
-makefile.pc is a makefile for Turbo C or C++ or Borland C++ on MS-DOS.
-
-makefile.os2 is a makefile for MS C and GNU C (emx/gcc) on OS/2.
-cpio.def is a linker definition file for the MS C OS/2 version.
-
-
-The main advantages of GNU cpio over Unix versions are:
-
-* It can access tape drives on other hosts using TCP/IP.
-
-* `-o' and `-p' can copy symbolic links either as symbolic links or,
-with `-L', as the files they point to.
-
-* `-i' automatically recognizes the archive format and tries to
-recover from corrupted archives.
-
-* The output of '-itv' looks like 'ls -l'.
-
-* It accepts long-named options as well as traditional
-single-character options.
-
-A few features of other versions of cpio are missing from GNU cpio, including:
-
-* The `-6' option to support Sixth Edition Unix cpio archives with `-i'.
-
-* An option to limit volume size, like afio -s.
-
-
-GNU cpio supports the POSIX.1 "ustar" tar format. GNU tar supports a
-somewhat different, early draft of that format. That draft format has
-a slightly different magic number in the tar header and doesn't
-include the path prefix part of the header, which allows storing file
-names that are longer than 100 characters. GNU cpio knows to
-recognize the nonstandard GNU tar "ustar" archives.
-
-The following patch to GNU tar 1.11.1 makes GNU tar recognize standard
-"ustar" archives, such as GNU cpio produces, except that it won't use
-the path prefix. Without this patch, GNU tar thinks that standard
-"ustar" archives are old-format tar archives and can not use the extra
-information that "ustar" format contains. If you use this patch,
-remember that you will lose the beginnings of paths that are longer
-than 100 characters. That's why it's not an official part of GNU tar.
-(Adding support for the path prefix to GNU tar is not trivial.)
-
---- list.c.orig Mon Sep 14 17:04:03 1992
-+++ list.c Wed Oct 14 14:02:28 1992
-@@ -439,7 +439,7 @@
- st->st_ctime = from_oct(1+12, header->header.ctime);
- }
-
-- if (0==strcmp(header->header.magic, TMAGIC)) {
-+ if (0==strncmp(header->header.magic, TMAGIC, 5)) {
- /* Unix Standard tar archive */
- *stdp = 1;
- if (wantug) {
-
-Mail suggestions and bug reports for GNU cpio to bug-cpio@gnu.org.
diff --git a/contrib/cpio/THANKS b/contrib/cpio/THANKS
deleted file mode 100644
index 393de05..0000000
--- a/contrib/cpio/THANKS
+++ /dev/null
@@ -1,20 +0,0 @@
-GNU cpio THANKS file
-
-GNU cpio has originally been written by Phil Nelson <phil@cs.wwu.edu>
-and David MacKenzie <djm@gnu.ai.mit.edu>. It was further modified
-by John Oleynick <juo@gnu.org> and Sergey Poznyakoff <gray@gnu.org>
-who currently maintains it.
-
-The following is a list of people who contributed to GNU cpio by
-reporting problems, suggesting various improvements or submitting actual
-code. Help us keep it complete and exempt of errors.
-
-Benigno B. Junior <bbj@gentux.com.br>
-Brian Mays <brian@debian.org>
-Dmitry V. Levin <ldv@altlinux.org>
-Jim Castleberry <bhg9aha02@sneakemail.com>
-Holger Fleischmann <holger_fleischmann@mra.man.de>
-Matthew Braithwaite <mab@cnet.com>
-Mike Frysinger <vapier@gentoo.org>
-Mitsuru Chinen <mchinen@yamato.ibm.com>
-Peter Vrabec <pvrabec@redhat.com>
diff --git a/contrib/cpio/TODO b/contrib/cpio/TODO
deleted file mode 100644
index ffd63d5..0000000
--- a/contrib/cpio/TODO
+++ /dev/null
@@ -1,159 +0,0 @@
-Following is the list of cpio-related reports to bug-gnu-utils.
-Many of them appear to be fixed, but quite a number of them is
-probably still waiting for being handled. The list is divided
-into two parts, the messages are in somehow arbitrary order.
-
-* Bug reports
---------------
-
-** cpio -d bug (fwd) (score: 47)
- Author: Christian Smith <csmith@micromuse.com>
- Date: Wed, 14 Nov 2001 02:06:46 +0000 (GMT)
- This was bounced from bug-cpio@bogus.example.com I guess that
- isn't set up yet. -- /"\ \ / ASCII RIBBON CAMPAIGN - AGAINST
- HTML MAIL X - AGAINST MS ATTACHMENTS / \ $ cpio --version GNU
- cpio version 2
- /archive/html/bug-gnu-utils/2001-11/msg00170.html (4,548 bytes)
-
-** bug in cpio with tapechange in copy-in-mode (score: 34)
- Author: Bernd =?ISO-8859-1?Q?Sch=FCler?=
- <b.schueler@eckert-buerotechnik.de>
- Date: 05 Aug 2002 18:37:56 +0200
- Hello, last i made a restore from tape, and no request for next
- tape happend, only an read-error occured. Here is an quick
- patch, please verify the problem and the patch-code. I'm not
- sure, if the pr
- /archive/html/bug-gnu-utils/2002-08/msg00122.html (4,518 bytes)
-
-** Re: bug in cpio? (score: 40)
- Author: kasal@matsrv.math.cas.cz (Stepan Kasal)
- Date: Thu, 13 Jun 2002 07:44:14 +0000 (UTC)
- Hallo, the following option should help: -d, --make-directories
- Create leading directories where needed. Details: cpio won't
- create the directory for the file. Observe: kasal$ echo
- /home/kasal/tmp/db
- /archive/html/bug-gnu-utils/2002-06/msg00306.html (4,862 bytes)
-
-** cpio 2.4.2 bug? (score: 40)
- Author: "H.J. Thomassen" <H.J.Thomassen@ATComputing.nl>
- Date: Thu, 10 Jan 2002 18:09:10 +0100 (CET)
- Hello, We use GNU-cpio 2.4.2 and have the following problem:
- Short: Assume I have a directory with two filenames, which are
- hardlinks to the same i-node. I make a crc-cpio archive with
- both files; th
- /archive/html/bug-gnu-utils/2002-01/msg00161.html (5,624 bytes)
-
-** These two seem to be related:
-*** cpio copy-in and multiply-linked files (score: 35)
- Author: Chris Jaeger <cjaeger@ensim.com>
- Date: Tue, 07 Aug 2001 23:46:04 -0700
- Hi, I was wondering whether it was a bug or a feature that GNU
- cpio, while in copy-in mode, will create a multiply-linked set
- of files all of size 0 if the last linked file is not copied in
- due to th
- /archive/html/bug-gnu-utils/2001-08/msg00074.html (4,142 bytes)
-
-*** (no subject) (score: 2)
- Author: brian@debian.org (Brian Mays)
- Date: Sat, 07 Jul 2001 16:35:13 -0400
- When hard-linked files (along with many other files) are
- archived to a cpio ustar format archive, the files are _not_
- all archived as hard links to each other in the archive. When
- the same set of fil
- /archive/html/bug-gnu-utils/2001-07/msg00080.html (5,666 bytes)
-
-** These too:
-
-*** Re: minor problems with slackware-current (score: 7)
- Author: Cezary Sliwa <sliwa@cft.edu.pl>
- Date: Wed, 1 Aug 2001 10:43:37 +0200
- "cpio --sparse" corrupts data. A fix attached. C.S. Attachment:
- cpio-2.4.2-sparse.diff Description: Text document
- /archive/html/bug-gnu-utils/2001-08/msg00000.html (3,989 bytes)
-
-*** cpio --sparse (score: 34)
- Author: Cezary Sliwa <sliwa@cft.edu.pl>
- Date: Mon, 26 Mar 2001 10:43:34 +0200 (CEST)
- the '--sparse' option of gnu cpio causes data corruption
- (blocks of zeros are lost or appended to other files). C.S.
- /archive/html/bug-gnu-utils/2001-03/msg00235.html (3,671 bytes)
-
-** And these too
-*** cpio-2.4.2: data corruption bug (score: 35)
- Author: Todd Kelley <toddk@oeone.com>
- Date: Fri, 09 Feb 2001 17:00:06 -0500
- Hello, Recently at OEone we fixed a bug in GNU cpio-2.4.2: When
- a file over about 0.5 megabyes grows while it is being
- archived, it and all files following it in the archive are
- corrupted. The crc do
- /archive/html/bug-gnu-utils/2001-02/msg00062.html (4,297 bytes)
-
-*** cpio pass-through can corrupt files (score: 36)
- Author: "Parrott, Jeff" <Jeff.Parrott@sea.siemens.com>
- Date: Mon, 16 Oct 2000 13:32:57 -0400
- I have seen corrupted files as a result of using the
- pass-through option in cpio. The corruption occurs when
- active/in-use (and growing) files are being copied. The problem
- is that the file size has
- /archive/html/bug-gnu-utils/2000-10/msg00087.html (4,974 bytes)
-
-** cpio 2.4.2 unconditionally takes the tape drive offline (score:
- 39)
- Author: Scott Larson <scowl@plaza.ds.adp.com>
- Date: Thu, 11 Jan 2001 13:15:52 -0800
- We have been copying multiple volumes to a single tape with the
- System 5 version of cpio. The gnu version of cpio doesn't
- support this since it takes the tape offline (i.e. ejects the
- tape) after rea
- /archive/html/bug-gnu-utils/2001-01/msg00087.html (4,264 bytes)
-
-** cpio -t can see international filenames, find -ls also suffers
- (score: 35)
- Author: "Dan Jacobson" <jidanni@kimo.FiXcomTHiS.tw>
- Date: Tue, 26 Dec 2000 07:38:53 +0800
- GNU cpio version 2.4.2 with cpio -t I can see Chinese [big5]
- filenames. with -tv, they become \267\247 etc Just like what
- happens with find . -print vs. find . -ls --
- http://www.geocities.com/jidanni
- /archive/html/bug-gnu-utils/2000-12/msg00143.html (4,084 bytes)
-
-* Suggestions
--------------
-
-** GNU cpio suggestion (score: 42)
- Author: "H.J.Thomassen" <hjt@ATComputing.nl>
- Date: Mon, 17 Dec 2001 11:27:11 +0100
- Re: suggestion for GNU-cpio extension (plus reference
- implementation) We use cpio for our backup purposes. The backup
- is started automatically in the middle of the night. To chase
- away all users we d
- /archive/html/bug-gnu-utils/2001-12/msg00244.html (7,474 bytes)
-
-** cpio suggestion + patch (score: 38)
- Author: Taylor Gautier <tgautier@s8.com>
- Date: Fri, 20 Apr 2001 09:40:05 -0700
- I have a suggestion for cpio. The suggestion is to make it copy
- files into a temporary name and then rename the file as the
- last operation. Since UNIX filesystems are supposed to
- gaurantee atomicity
- /archive/html/bug-gnu-utils/2001-04/msg00169.html (10,674
- bytes)
-
-** [cpio] man page enhancement: a Example section ? (score: 5)
- Author: Yannick Patois <patois@calvix.org>
- Date: Wed, 24 Oct 2001 12:48:33 +0200 (CEST)
- Hello, I seldom use cpio (as I think many people) and only had
- to use it once or twice. IMHA, would be good to have a small
- section with an example of most often performed actions
- (creating an archiv
- /archive/html/bug-gnu-utils/2001-10/msg00270.html (4,336 bytes)
-
-** Patch to cpio to enable verbose *skipping* of files (score: 40)
- Author: Tomas Pospisek <tpo@sourcepole.ch>
- Date: Mon, 8 Oct 2001 13:54:14 +0200 (CEST)
- This patch enables cpio to be verbose about the files that it
- does not copy, which is very handy for seeing cpio's progress
- through a tape or simply for debuging. The patch along with a
- Debian packag
- /archive/html/bug-gnu-utils/2001-10/msg00083.html (4,548 bytes)
-
diff --git a/contrib/cpio/doc/cpio.1 b/contrib/cpio/doc/cpio.1
deleted file mode 100644
index a59094a..0000000
--- a/contrib/cpio/doc/cpio.1
+++ /dev/null
@@ -1,41 +0,0 @@
-.TH CPIO 1L \" -*- nroff -*-
-.SH NAME
-cpio \- copy files to and from archives
-.SH SYNOPSIS
-.B cpio
-{\-o|\-\-create} [\-0acvABLV] [\-C bytes] [\-H format] [\-M message]
-[\-O [[user@]host:]archive] [\-F [[user@]host:]archive]
-[\-\-file=[[user@]host:]archive] [\-\-format=format] [\-\-message=message]
-[\-\-null] [\-\-reset-access-time] [\-\-verbose] [\-\-dot] [\-\-append]
-[\-\-block-size=blocks] [\-\-dereference] [\-\-io-size=bytes] [\-\-quiet]
-[\-\-force\-local] [\-\-rsh-command=command] [\-\-help] [\-\-version]
-< name-list [> archive]
-
-.B cpio
-{\-i|\-\-extract} [\-bcdfmnrtsuvBSV] [\-C bytes] [\-E file] [\-H format]
-[\-M message] [\-R [user][:.][group]] [\-I [[user@]host:]archive]
-[\-F [[user@]host:]archive] [\-\-file=[[user@]host:]archive]
-[\-\-make-directories] [\-\-nonmatching] [\-\-preserve-modification-time]
-[\-\-numeric-uid-gid] [\-\-rename] [\-t|\-\-list] [\-\-swap-bytes] [\-\-swap] [\-\-dot]
-[\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords]
-[\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format]
-[\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message]
-[\-\-force\-local] [\-\-absolute\-filenames] [\-\-sparse]
-[\-\-only\-verify\-crc] [\-\-quiet] [\-\-rsh-command=command] [\-\-help]
-[\-\-version] [pattern...] [< archive]
-
-.B cpio
-{\-p|\-\-pass-through} [\-0adlmuvLV] [\-R [user][:.][group]]
-[\-\-null] [\-\-reset-access-time] [\-\-make-directories] [\-\-link] [\-\-quiet]
-[\-\-preserve-modification-time] [\-\-unconditional] [\-\-verbose] [\-\-dot]
-[\-\-dereference] [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner]
-[\-\-sparse] [\-\-help] [\-\-version] destination-directory < name-list
-.SH DESCRIPTION
-GNU cpio is fully documented in the texinfo documentation. To access the
-help from your command line, type
-.PP
-\fBinfo cpio
-.PP
-The online copy of the documentation is available at the following address:
-.PP
-http://www.gnu.org/software/cpio/manual
diff --git a/contrib/cpio/doc/cpio.texi b/contrib/cpio/doc/cpio.texi
deleted file mode 100644
index 8bf4dde..0000000
--- a/contrib/cpio/doc/cpio.texi
+++ /dev/null
@@ -1,602 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-@c %**start of header
-@setfilename cpio.info
-@settitle cpio
-@setchapternewpage off
-@c %**end of header
-
-@dircategory Archiving
-@direntry
-* Cpio: (cpio). Copy-in-copy-out archiver to tape or disk.
-@end direntry
-
-@include version.texi
-
-@copying
-This manual documents GNU cpio (version @value{VERSION}, @value{UPDATED}).
-
-Copyright @copyright{} 1995, 2001, 2002, 2004 Free Software Foundation, Inc.
-@sp 1
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.2 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
-and with the Back-Cover Texts as in (a) below. A copy of the license
-is included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
-this GNU Manual, like GNU software. Copies published by the Free
-Software Foundation raise funds for GNU development.''
-@end quotation
-@end copying
-
-@titlepage
-@title GNU CPIO
-@subtitle @value{VERSION} @value{UPDATED}
-@author by Robert Carleton
-@c copyright page
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@sp 2
-Published by the Free Software Foundation @*
-51 Franklin Street, Fifth Floor, @*
-Boston, MA 02110-1301, USA @*
-@end titlepage
-
-@node Top, Introduction, (dir), (dir)
-@comment node-name, next, previous, up
-
-@ifinfo
-@top
-
-GNU cpio is a tool for creating and extracting archives, or copying
-files from one place to another. It handles a number of cpio formats as
-well as reading and writing tar files. This is the first edition of the
-GNU cpio documentation and is consistent with @value{VERSION}.
-
-@end ifinfo
-
-@menu
-* Introduction::
-* Tutorial:: Getting started.
-* Invoking cpio:: How to invoke @command{cpio}.
-* Media:: Using tapes and other archive media.
-* Reports:: Reporting bugs or suggestions
-* Concept Index:: Concept index.
-
-@detailmenu
- --- The Detailed Node Listing ---
-
-Invoking cpio
-
-* Copy-out mode::
-* Copy-in mode::
-* Copy-pass mode::
-* Options::
-
-@end detailmenu
-@end menu
-
-@node Introduction, Tutorial, Top, Top
-@comment node-name, next, previous, up
-@chapter Introduction
-
-GNU cpio copies files into or out of a cpio or tar archive, The archive
-can be another file on the disk, a magnetic tape, or a pipe.
-
-GNU cpio supports the following archive formats: binary, old ASCII, new
-ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. The
-tar format is provided for compatibility with the tar program. By
-default, cpio creates binary format archives, for compatibility with
-older cpio programs. When extracting from archives, cpio automatically
-recognizes which kind of archive it is reading and can read archives
-created on machines with a different byte-order.
-
-@node Tutorial, Invoking cpio, Introduction, Top
-@comment node-name, next, previous, up
-@chapter Tutorial
-@cindex creating a cpio archive
-@cindex extracting a cpio archive
-@cindex copying directory structures
-@cindex passing directory structures
-
-
-GNU cpio performs three primary functions. Copying files to an
-archive, Extracting files from an archive, and passing files to another
-directory tree. An archive can be a file on disk, one or more floppy
-disks, or one or more tapes.
-
-When creating an archive, cpio takes the list of files to be processed
-from the standard input, and then sends the archive to the standard
-output, or to the device defined by the @option{-F} option.
-@xref{Copy-out mode}. Usually find or ls is used to provide this list
-to the standard input. In the following example you can see the
-possibilities for archiving the contents of a single directory.
-
-
-@example
-@cartouche
-% ls | cpio -ov > directory.cpio
-@end cartouche
-@end example
-
-The @option{-o} option creates the archive, and the @option{-v} option
-prints the names of the files archived as they are added. Notice that
-the options can be put together after a single @option{-} or can be placed
-separately on the command line. The @samp{>} redirects the cpio output
-to the file @samp{directory.cpio}.
-
-
-If you wanted to archive an entire directory tree, the find command can
-provide the file list to cpio:
-
-
-@example
-@cartouche
-% find . -print -depth | cpio -ov > tree.cpio
-@end cartouche
-@end example
-
-
-This will take all the files in the current directory, the directories
-below and place them in the archive tree.cpio. Again the @option{-o}
-creates an archive, and the @option{-v} option shows you the name of the
-files as they are archived. @xref{Copy-out mode}. Using the @samp{.} in the
-find statement will give you more flexibility when doing restores, as it
-will save file names with a relative path vice a hard wired, absolute
-path. The @option{-depth} option forces @samp{find} to print of the
-entries in a directory before printing the directory itself. This
-limits the effects of restrictive directory permissions by printing the
-directory entries in a directory before the directory name itself.
-
-
-
-
-Extracting an archive requires a bit more thought because cpio will not
-create directories by default. Another characteristic, is it will not
-overwrite existing files unless you tell it to.
-
-
-@example
-@cartouche
-% cpio -iv < directory.cpio
-@end cartouche
-@end example
-
-This will retrieve the files archived in the file directory.cpio and
-place them in the present directory. The @option{-i} option extracts the
-archive and the @option{-v} shows the file names as they are extracted.
-If you are dealing with an archived directory tree, you need to use the
-@option{-d} option to create directories as necessary, something like:
-
-@example
-@cartouche
-% cpio -idv < tree.cpio
-@end cartouche
-@end example
-
-This will take the contents of the archive tree.cpio and extract it to
-the current directory. If you try to extract the files on top of files
-of the same name that already exist (and have the same or later
-modification time) cpio will not extract the file unless told to do so
-by the -u option. @xref{Copy-in mode}.
-
-
-In copy-pass mode, cpio copies files from one directory tree to another,
-combining the copy-out and copy-in steps without actually using an
-archive. It reads the list of files to copy from the standard input;
-the directory into which it will copy them is given as a non-option
-argument. @xref{Copy-pass mode}.
-
-@example
-@cartouche
-% find . -depth -print0 | cpio --null -pvd new-dir
-@end cartouche
-@end example
-
-
-The example shows copying the files of the present directory, and
-sub-directories to a new directory called new-dir. Some new options are
-the @option{-print0} available with GNU find, combined with the
-@option{--null} option of cpio. These two options act together to send
-file names between find and cpio, even if special characters are
-embedded in the file names. Another is @option{-p}, which tells cpio to
-pass the files it finds to the directory @samp{new-dir}.
-
-@node Invoking cpio, Media, Tutorial, Top
-@comment node-name, next, previous, up
-@chapter Invoking cpio
-@cindex invoking cpio
-@cindex command line options
-
-@menu
-* Copy-out mode::
-* Copy-in mode::
-* Copy-pass mode::
-* Options::
-@end menu
-
-@node Copy-out mode, Copy-in mode, Invoking cpio, Invoking cpio
-@comment node-name, next, previous, up
-@section Copy-out mode
-
-In copy-out mode, cpio copies files into an archive. It reads a list
-of filenames, one per line, on the standard input, and writes the
-archive onto the standard output. A typical way to generate the list
-of filenames is with the find command; you should give find the -depth
-option to minimize problems with permissions on directories that are
-unreadable.
-@xref{Options}.
-
-@example
-cpio @{-o|--create@} [-0acvABLV] [-C bytes] [-H format]
-[-M message] [-O [[user@@]host:]archive] [-F [[user@@]host:]archive]
-[--file=[[user@@]host:]archive] [--format=format]
-[--message=message][--null] [--reset-access-time] [--verbose]
-[--dot] [--append] [--block-size=blocks] [--dereference]
-[--io-size=bytes] [--rsh-command=command] [--help] [--version]
-< name-list [> archive]
-@end example
-
-@node Copy-in mode, Copy-pass mode, Copy-out mode, Invoking cpio
-@comment node-name, next, previous, up
-@section Copy-in mode
-
-In copy-in mode, cpio copies files out of an archive or lists the
-archive contents. It reads the archive from the standard input. Any
-non-option command line arguments are shell globbing patterns; only
-files in the archive whose names match one or more of those patterns are
-copied from the archive. Unlike in the shell, an initial @samp{.} in a
-filename does match a wildcard at the start of a pattern, and a @samp{/} in a
-filename can match wildcards. If no patterns are given, all files are
-extracted. @xref{Options}.
-
-@example
-cpio @{-i|--extract@} [-bcdfmnrtsuvBSV] [-C bytes] [-E file]
-[-H format] [-M message] [-R [user][:.][group]]
-[-I [[user@@]host:]archive] [-F [[user@@]host:]archive]
-[--file=[[user@@]host:]archive] [--make-directories]
-[--nonmatching] [--preserve-modification-time]
-[--numeric-uid-gid] [--rename] [--list] [--swap-bytes] [--swap]
-[--dot] [--unconditional] [--verbose] [--block-size=blocks]
-[--swap-halfwords] [--io-size=bytes] [--pattern-file=file]
-[--format=format] [--owner=[user][:.][group]]
-[--no-preserve-owner] [--message=message] [--help] [--version]
-[--absolute-filenames] [--sparse] [-only-verify-crc] [-quiet]
-[--rsh-command=command] [pattern...] [< archive]
-@end example
-
-@node Copy-pass mode, Options, Copy-in mode, Invoking cpio
-@comment node-name, next, previous, up
-@section Copy-pass mode
-
-In copy-pass mode, cpio copies files from one directory tree to
-another, combining the copy-out and copy-in steps without actually
-using an archive. It reads the list of files to copy from the
-standard input; the directory into which it will copy them is given as
-a non-option argument.
-@xref{Options}.
-
-@example
-cpio @{-p|--pass-through@} [-0adlmuvLV] [-R [user][:.][group]]
-[--null] [--reset-access-time] [--make-directories] [--link]
-[--preserve-modification-time] [--unconditional] [--verbose]
-[--dot] [--dereference] [--owner=[user][:.][group]] [--sparse]
-[--no-preserve-owner] [--help] [--version] destination-directory
-< name-list
-@end example
-
-
-
-@node Options, , Copy-pass mode, Invoking cpio
-@comment node-name, next, previous, up
-@section Options
-
-
-@table @code
-
-
-@item -0
-@itemx --null
-Read a list of filenames terminated by a null character, instead of a
-newline, so that files whose names contain newlines can be archived.
-GNU find is one way to produce a list of null-terminated filenames.
-This option may be used in copy-out and copy-pass modes.
-
-@item -a
-@itemx --reset-access-time
-Reset the access times of files after reading them, so
-that it does not look like they have just been read.
-
-@item -A
-@itemx --append
-Append to an existing archive. Only works in copy-out
-mode. The archive must be a disk file specified with
-the @option{-O} or @option{-F} (@option{--file}) option.
-
-@item -b
-@itemx --swap
-Swap both halfwords of words and bytes of halfwords in the data.
-Equivalent to -sS. This option may be used in copy-in mode. Use this
-option to convert 32-bit integers between big-endian and little-endian
-machines.
-
-@item -B
-Set the I/O block size to 5120 bytes. Initially the
-block size is 512 bytes.
-
-@item --block-size=@var{block-size}
-Set the I/O block size to @var{block-size} * 512 bytes.
-
-@item -c
-Use the old portable (ASCII) archive format.
-
-@item -C @var{io-size}
-@itemx --io-size=@var{io-size}
-Set the I/O block size to @var{io-size} bytes.
-
-@item -d
-@itemx --make-directories
-Create leading directories where needed.
-
-@item -E @var{file}
-@itemx --pattern-file=@var{file}
-Read additional patterns specifying filenames to extract or list from
-@var{file}. The lines of @var{file} are treated as if they had been non-option
-arguments to cpio. This option is used in copy-in mode,
-
-@item -f
-@itemx --nonmatching
-Only copy files that do not match any of the given
-patterns.
-
-@item -F @var{archive}
-@itemx --file=@var{archive}
-Archive filename to use instead of standard input or output. To use a
-tape drive on another machine as the archive, use a filename that starts
-with @samp{@var{hostname}:}, where @var{hostname} is the name or IP
-address of the machine. The hostname can be preceded by a username and an
-@samp{@@} to access the remote tape drive as that user, if you have
-permission to do so (typically an entry in that user's @file{~/.rhosts}
-file).
-
-@item --force-local
-With @option{-F}, @option{-I}, or @option{-O}, take the archive file name to be a
-local file even if it contains a colon, which would
-ordinarily indicate a remote host name.
-
-@item -H @var{format}
-@itemx --format=@var{format}
-Use archive format @var{format}. The valid formats are listed below; the same
-names are also recognized in all-caps. The default in copy-in mode is
-to automatically detect the archive format, and in copy-out mode is
-@samp{bin}.
-
-@table @samp
-@item bin
-The obsolete binary format.
-
-@item odc
-The old (POSIX.1) portable format.
-
-@item newc
-The new (SVR4) portable format, which supports file systems having more
-than 65536 i-nodes.
-
-@item crc
-The new (SVR4) portable format with a checksum added.
-
-@item tar
-The old tar format.
-
-@item ustar
-The POSIX.1 tar format. Also recognizes GNU tar archives, which are
-similar but not identical.
-
-@item hpbin
-The obsolete binary format used by HPUX's cpio (which stores device
-files differently).
-
-@item hpodc
-The portable format used by HPUX's cpio (which stores device files
-differently).
-@end table
-
-@item -i
-@itemx --extract
-Run in copy-in mode.
-@xref{Copy-in mode}.
-
-@item -I @var{archive}
-Archive filename to use instead of standard input. To use a tape drive
-on another machine as the archive, use a filename that starts with
-@samp{@var{hostname}:}, where @var{hostname} is the name or IP address
-of the remote host. The hostname can be preceded by a username and an @samp{@@} to
-access the remote tape drive as that user, if you have permission to do
-so (typically an entry in that user's @file{~/.rhosts} file).
-
-@item -k
-Ignored; for compatibility with other versions of cpio.
-
-@item -l
-@itemx --link
-Link files instead of copying them, when possible.
-
-@item -L
-@itemx --dereference
-Copy the file that a symbolic link points to, rather than the symbolic
-link itself.
-
-@item -m
-@itemx --preserve-modification-time
-Retain previous file modification times when creating files.
-
-@item -M @var{message}
-@itemx --message=@var{message}
-Print @var{message} when the end of a volume of the backup media (such as a
-tape or a floppy disk) is reached, to prompt the user to insert a new
-volume. If @var{message} contains the string @samp{%d}, it is replaced by the
-current volume number (starting at 1).
-
-@item -n
-@itemx --numeric-uid-gid
-Show numeric UID and GID instead of translating them into names when using the
-@option{--verbose} option.
-
-@item --absolute-filenames
-Do not strip leading file name components that contain ".." and
-leading slashes from file names in copy-in mode
-
-@item --no-preserve-owner
-Do not change the ownership of the files; leave them owned by the user
-extracting them. This is the default for non-root users, so that users
-on System V don't inadvertantly give away files. This option can be
-used in copy-in mode and copy-pass mode
-
-@item -o
-@itemx --create
-Run in copy-out mode.
-@xref{Copy-out mode}.
-
-@item -O @var{archive}
-Archive filename to use instead of standard output. To use a tape drive
-on another machine as the archive, use a filename that starts with
-@samp{@var{hostname}:}, where @var{hostname} is the name or IP address
-of the machine. The hostname can be preceded by a username and an @samp{@@} to
-access the remote tape drive as that user, if you have permission to do
-so (typically an entry in that user's @file{~/.rhosts} file).
-
-@item --only-verify-crc
-Verify the CRC's of each file in the archive, when reading a CRC format
-archive. Don't actually extract the files.
-
-@item -p
-@itemx --pass-through
-Run in copy-pass mode.
-@xref{Copy-pass mode}.
-
-@item --quiet
-Do not print the number of blocks copied.
-
-@item -r
-@itemx --rename
-Interactively rename files.
-
-@item -R @var{owner}
-@itemx --owner @var{owner}
-
-In copy-in and copy-pass mode, set the ownership of all files created
-to the specified @var{owner} (this operation is allowed only for the
-super-user). In copy-out mode, store the supplied owner information in
-the archive.
-
-The argument can be either the user name or the user name
-and group name, separated by a dot or a colon, or the group name,
-preceeded by a dot or a colon, as shown in the examples below:
-
-@smallexample
-@group
-cpio --owner smith
-cpio --owner smith:
-cpio --owner smith:users
-cpio --owner :users
-@end group
-@end smallexample
-
-@noindent
-If the group is omitted but the @samp{:} or @samp{.} separator is
-given, as in the second example. the given user's login group will be
-used.
-
-@item --rsh-command=@var{command}
-Notifies cpio that is should use @var{command} to communicate with remote
-devices.
-
-@item -s
-@itemx --swap-bytes
-Swap the bytes of each halfword (pair of bytes) in the files. This option
-can be used in copy-in mode.
-
-@item -S
-@itemx --swap-halfwords
-Swap the halfwords of each word (4 bytes) in the files. This option may
-be used in copy-in mode.
-
-@item --sparse
-Write files with large blocks of zeros as sparse files. This option is
-used in copy-in and copy-pass modes.
-
-@item -t
-@itemx --list
-Print a table of contents of the input.
-
-@item -u
-@itemx --unconditional
-Replace all files, without asking whether to replace
-existing newer files with older files.
-
-@item -v
-@itemx --verbose
-List the files processed, or with @option{-t}, give an @samp{ls -l} style
-table of contents listing. In a verbose table of contents of a ustar
-archive, user and group names in the archive that do not exist on the
-local system are replaced by the names that correspond locally to the
-numeric UID and GID stored in the archive.
-
-@item -V
-@itemx --dot
-Print a @samp{.} for each file processed.
-
-@item --version
-Print the cpio program version number and exit.
-@end table
-
-
-@node Media, Reports, Invoking cpio, Top
-@comment node-name, next, previous, up
-@chapter Magnetic Media
-@cindex magnetic media
-
-Archives are usually written on removable media--tape cartridges, mag
-tapes, or floppy disks.
-
-The amount of data a tape or disk holds depends not only on its size,
-but also on how it is formatted. A 2400 foot long reel of mag tape
-holds 40 megabytes of data when formated at 1600 bits per inch. The
-physically smaller EXABYTE tape cartridge holds 2.3 gigabytes.
-
-Magnetic media are re-usable--once the archive on a tape is no longer
-needed, the archive can be erased and the tape or disk used over. Media
-quality does deteriorate with use, however. Most tapes or disks should
-be disgarded when they begin to produce data errors.
-
-Magnetic media are written and erased using magnetic fields, and should
-be protected from such fields to avoid damage to stored data. Sticking
-a floppy disk to a filing cabinet using a magnet is probably not a good
-idea.
-
-@node Reports, Concept Index, Media, Top
-@chapter Reporting bugs or suggestions
-
-It is possible you will encounter a bug in @command{cpio}.
-If this happens, we would like to hear about it. As the purpose of bug
-reporting is to improve software, please be sure to include maximum
-information when reporting a bug. The information needed is:
-
-@itemize @bullet
-@item Version of the package you are using.
-@item Compilation options used when configuring the package.
-@item Conditions under which the bug appears.
-@end itemize
-
-Send your report to <bug-cpio@@gnu.org>. Allow us a couple of
-days to answer.
-
-@node Concept Index, , Reports, Top
-@comment node-name, next, previous, up
-@unnumbered Concept Index
-@printindex cp
-@contents
-@bye
diff --git a/contrib/cpio/doc/version.texi b/contrib/cpio/doc/version.texi
deleted file mode 100644
index c20cd8c..0000000
--- a/contrib/cpio/doc/version.texi
+++ /dev/null
@@ -1,4 +0,0 @@
-@set UPDATED 7 June 2007
-@set UPDATED-MONTH June 2007
-@set EDITION 2.8
-@set VERSION 2.8
diff --git a/contrib/cpio/lib/alloca_.h b/contrib/cpio/lib/alloca_.h
deleted file mode 100644
index af274b9..0000000
--- a/contrib/cpio/lib/alloca_.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Memory allocation on the stack.
-
- Copyright (C) 1995, 1999, 2001-2004, 2006-2007 Free Software
- Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- USA. */
-
-/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
- means there is a real alloca function. */
-#ifndef _GL_ALLOCA_H
-#define _GL_ALLOCA_H
-
-/* alloca (N) returns a pointer to N bytes of memory
- allocated on the stack, which will last until the function returns.
- Use of alloca should be avoided:
- - inside arguments of function calls - undefined behaviour,
- - in inline functions - the allocation may actually last until the
- calling function returns,
- - for huge N (say, N >= 65536) - you never know how large (or small)
- the stack is, and when the stack cannot fulfill the memory allocation
- request, the program just crashes.
- */
-
-#ifndef alloca
-# ifdef __GNUC__
-# define alloca __builtin_alloca
-# elif defined _AIX
-# define alloca __alloca
-# elif defined _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-# else
-# include <stddef.h>
-# ifdef __cplusplus
-extern "C"
-# endif
-void *alloca (size_t);
-# endif
-#endif
-
-#endif /* _GL_ALLOCA_H */
diff --git a/contrib/cpio/lib/argp-ba.c b/contrib/cpio/lib/argp-ba.c
deleted file mode 100644
index 8bb7309..0000000
--- a/contrib/cpio/lib/argp-ba.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
- Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* If set by the user program, it should point to string that is the
- bug-reporting address for the program. It will be printed by argp_help if
- the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
- messages), embedded in a sentence that says something like `Report bugs to
- ADDR.'. */
-const char *argp_program_bug_address;
diff --git a/contrib/cpio/lib/argp-eexst.c b/contrib/cpio/lib/argp-eexst.c
deleted file mode 100644
index bcab1c0..0000000
--- a/contrib/cpio/lib/argp-eexst.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Default definition for ARGP_ERR_EXIT_STATUS
- Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <sysexits.h>
-
-#include "argp.h"
-
-/* The exit status that argp will use when exiting due to a parsing error.
- If not defined or set by the user program, this defaults to EX_USAGE from
- <sysexits.h>. */
-error_t argp_err_exit_status = EX_USAGE;
diff --git a/contrib/cpio/lib/argp-fmtstream.c b/contrib/cpio/lib/argp-fmtstream.c
deleted file mode 100644
index 0dd9256..0000000
--- a/contrib/cpio/lib/argp-fmtstream.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* Word-wrapping and line-truncating streams
- Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* This package emulates glibc `line_wrap_stream' semantics for systems that
- don't have that. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#include "argp-fmtstream.h"
-#include "argp-namefrob.h"
-
-#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
-
-#ifndef isblank
-#define isblank(ch) ((ch)==' ' || (ch)=='\t')
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-# include <wchar.h>
-# include <libio/libioP.h>
-# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
-#endif
-
-#define INIT_BUF_SIZE 200
-#define PRINTF_SIZE_GUESS 150
-
-/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
- written on it with LMARGIN spaces and limits them to RMARGIN columns
- total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
- replacing the whitespace before them with a newline and WMARGIN spaces.
- Otherwise, chars beyond RMARGIN are simply dropped until a newline.
- Returns NULL if there was an error. */
-argp_fmtstream_t
-__argp_make_fmtstream (FILE *stream,
- size_t lmargin, size_t rmargin, ssize_t wmargin)
-{
- argp_fmtstream_t fs;
-
- fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
- if (fs != NULL)
- {
- fs->stream = stream;
-
- fs->lmargin = lmargin;
- fs->rmargin = rmargin;
- fs->wmargin = wmargin;
- fs->point_col = 0;
- fs->point_offs = 0;
-
- fs->buf = (char *) malloc (INIT_BUF_SIZE);
- if (! fs->buf)
- {
- free (fs);
- fs = 0;
- }
- else
- {
- fs->p = fs->buf;
- fs->end = fs->buf + INIT_BUF_SIZE;
- }
- }
-
- return fs;
-}
-#if 0
-/* Not exported. */
-#ifdef weak_alias
-weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
-#endif
-#endif
-
-/* Flush FS to its stream, and free it (but don't close the stream). */
-void
-__argp_fmtstream_free (argp_fmtstream_t fs)
-{
- __argp_fmtstream_update (fs);
- if (fs->p > fs->buf)
- {
-#ifdef USE_IN_LIBIO
- __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
-#else
- fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
-#endif
- }
- free (fs->buf);
- free (fs);
-}
-#if 0
-/* Not exported. */
-#ifdef weak_alias
-weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
-#endif
-#endif
-
-/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
- end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
-void
-__argp_fmtstream_update (argp_fmtstream_t fs)
-{
- char *buf, *nl;
- size_t len;
-
- /* Scan the buffer for newlines. */
- buf = fs->buf + fs->point_offs;
- while (buf < fs->p)
- {
- size_t r;
-
- if (fs->point_col == 0 && fs->lmargin != 0)
- {
- /* We are starting a new line. Print spaces to the left margin. */
- const size_t pad = fs->lmargin;
- if (fs->p + pad < fs->end)
- {
- /* We can fit in them in the buffer by moving the
- buffer text up and filling in the beginning. */
- memmove (buf + pad, buf, fs->p - buf);
- fs->p += pad; /* Compensate for bigger buffer. */
- memset (buf, ' ', pad); /* Fill in the spaces. */
- buf += pad; /* Don't bother searching them. */
- }
- else
- {
- /* No buffer space for spaces. Must flush. */
- size_t i;
- for (i = 0; i < pad; i++)
- {
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (fs->stream, 0) > 0)
- putwc_unlocked (L' ', fs->stream);
- else
-#endif
- putc_unlocked (' ', fs->stream);
- }
- }
- fs->point_col = pad;
- }
-
- len = fs->p - buf;
- nl = memchr (buf, '\n', len);
-
- if (fs->point_col < 0)
- fs->point_col = 0;
-
- if (!nl)
- {
- /* The buffer ends in a partial line. */
-
- if (fs->point_col + len < fs->rmargin)
- {
- /* The remaining buffer text is a partial line and fits
- within the maximum line width. Advance point for the
- characters to be written and stop scanning. */
- fs->point_col += len;
- break;
- }
- else
- /* Set the end-of-line pointer for the code below to
- the end of the buffer. */
- nl = fs->p;
- }
- else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
- {
- /* The buffer contains a full line that fits within the maximum
- line width. Reset point and scan the next line. */
- fs->point_col = 0;
- buf = nl + 1;
- continue;
- }
-
- /* This line is too long. */
- r = fs->rmargin - 1;
-
- if (fs->wmargin < 0)
- {
- /* Truncate the line by overwriting the excess with the
- newline and anything after it in the buffer. */
- if (nl < fs->p)
- {
- memmove (buf + (r - fs->point_col), nl, fs->p - nl);
- fs->p -= buf + (r - fs->point_col) - nl;
- /* Reset point for the next line and start scanning it. */
- fs->point_col = 0;
- buf += r + 1; /* Skip full line plus \n. */
- }
- else
- {
- /* The buffer ends with a partial line that is beyond the
- maximum line width. Advance point for the characters
- written, and discard those past the max from the buffer. */
- fs->point_col += len;
- fs->p -= fs->point_col - r;
- break;
- }
- }
- else
- {
- /* Do word wrap. Go to the column just past the maximum line
- width and scan back for the beginning of the word there.
- Then insert a line break. */
-
- char *p, *nextline;
- int i;
-
- p = buf + (r + 1 - fs->point_col);
- while (p >= buf && !isblank (*p))
- --p;
- nextline = p + 1; /* This will begin the next line. */
-
- if (nextline > buf)
- {
- /* Swallow separating blanks. */
- if (p >= buf)
- do
- --p;
- while (p >= buf && isblank (*p));
- nl = p + 1; /* The newline will replace the first blank. */
- }
- else
- {
- /* A single word that is greater than the maximum line width.
- Oh well. Put it on an overlong line by itself. */
- p = buf + (r + 1 - fs->point_col);
- /* Find the end of the long word. */
- if (p < nl)
- do
- ++p;
- while (p < nl && !isblank (*p));
- if (p == nl)
- {
- /* It already ends a line. No fussing required. */
- fs->point_col = 0;
- buf = nl + 1;
- continue;
- }
- /* We will move the newline to replace the first blank. */
- nl = p;
- /* Swallow separating blanks. */
- do
- ++p;
- while (isblank (*p));
- /* The next line will start here. */
- nextline = p;
- }
-
- /* Note: There are a bunch of tests below for
- NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
- at the end of the buffer, and NEXTLINE is in fact empty (and so
- we need not be careful to maintain its contents). */
-
- if ((nextline == buf + len + 1
- ? fs->end - nl < fs->wmargin + 1
- : nextline - (nl + 1) < fs->wmargin)
- && fs->p > nextline)
- {
- /* The margin needs more blanks than we removed. */
- if (fs->end - fs->p > fs->wmargin + 1)
- /* Make some space for them. */
- {
- size_t mv = fs->p - nextline;
- memmove (nl + 1 + fs->wmargin, nextline, mv);
- nextline = nl + 1 + fs->wmargin;
- len = nextline + mv - buf;
- *nl++ = '\n';
- }
- else
- /* Output the first line so we can use the space. */
- {
-#ifdef _LIBC
- __fxprintf (fs->stream, "%.*s\n",
- (int) (nl - fs->buf), fs->buf);
-#else
- if (nl > fs->buf)
- fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
- putc_unlocked ('\n', fs->stream);
-#endif
-
- len += buf - fs->buf;
- nl = buf = fs->buf;
- }
- }
- else
- /* We can fit the newline and blanks in before
- the next word. */
- *nl++ = '\n';
-
- if (nextline - nl >= fs->wmargin
- || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
- /* Add blanks up to the wrap margin column. */
- for (i = 0; i < fs->wmargin; ++i)
- *nl++ = ' ';
- else
- for (i = 0; i < fs->wmargin; ++i)
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (fs->stream, 0) > 0)
- putwc_unlocked (L' ', fs->stream);
- else
-#endif
- putc_unlocked (' ', fs->stream);
-
- /* Copy the tail of the original buffer into the current buffer
- position. */
- if (nl < nextline)
- memmove (nl, nextline, buf + len - nextline);
- len -= nextline - buf;
-
- /* Continue the scan on the remaining lines in the buffer. */
- buf = nl;
-
- /* Restore bufp to include all the remaining text. */
- fs->p = nl + len;
-
- /* Reset the counter of what has been output this line. If wmargin
- is 0, we want to avoid the lmargin getting added, so we set
- point_col to a magic value of -1 in that case. */
- fs->point_col = fs->wmargin ? fs->wmargin : -1;
- }
- }
-
- /* Remember that we've scanned as far as the end of the buffer. */
- fs->point_offs = fs->p - fs->buf;
-}
-
-/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
- growing the buffer, or by flushing it. True is returned iff we succeed. */
-int
-__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
-{
- if ((size_t) (fs->end - fs->p) < amount)
- {
- ssize_t wrote;
-
- /* Flush FS's buffer. */
- __argp_fmtstream_update (fs);
-
-#ifdef _LIBC
- __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
- wrote = fs->p - fs->buf;
-#else
- wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
-#endif
- if (wrote == fs->p - fs->buf)
- {
- fs->p = fs->buf;
- fs->point_offs = 0;
- }
- else
- {
- fs->p -= wrote;
- fs->point_offs -= wrote;
- memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
- return 0;
- }
-
- if ((size_t) (fs->end - fs->buf) < amount)
- /* Gotta grow the buffer. */
- {
- size_t old_size = fs->end - fs->buf;
- size_t new_size = old_size + amount;
- char *new_buf;
-
- if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
- {
- __set_errno (ENOMEM);
- return 0;
- }
-
- fs->buf = new_buf;
- fs->end = new_buf + new_size;
- fs->p = fs->buf;
- }
- }
-
- return 1;
-}
-
-ssize_t
-__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
-{
- int out;
- size_t avail;
- size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
-
- do
- {
- va_list args;
-
- if (! __argp_fmtstream_ensure (fs, size_guess))
- return -1;
-
- va_start (args, fmt);
- avail = fs->end - fs->p;
- out = __vsnprintf (fs->p, avail, fmt, args);
- va_end (args);
- if ((size_t) out >= avail)
- size_guess = out + 1;
- }
- while ((size_t) out >= avail);
-
- fs->p += out;
-
- return out;
-}
-#if 0
-/* Not exported. */
-#ifdef weak_alias
-weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
-#endif
-#endif
-
-#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
diff --git a/contrib/cpio/lib/argp-fmtstream.h b/contrib/cpio/lib/argp-fmtstream.h
deleted file mode 100644
index e045a72..0000000
--- a/contrib/cpio/lib/argp-fmtstream.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/* Word-wrapping and line-truncating streams.
- Copyright (C) 1997, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* This package emulates glibc `line_wrap_stream' semantics for systems that
- don't have that. If the system does have it, it is just a wrapper for
- that. This header file is only used internally while compiling argp, and
- shouldn't be installed. */
-
-#ifndef _ARGP_FMTSTREAM_H
-#define _ARGP_FMTSTREAM_H
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
-#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
- || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
-/* line_wrap_stream is available, so use that. */
-#define ARGP_FMTSTREAM_USE_LINEWRAP
-#endif
-
-#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
-/* Just be a simple wrapper for line_wrap_stream; the semantics are
- *slightly* different, as line_wrap_stream doesn't actually make a new
- object, it just modifies the given stream (reversibly) to do
- line-wrapping. Since we control who uses this code, it doesn't matter. */
-
-#include <linewrap.h>
-
-typedef FILE *argp_fmtstream_t;
-
-#define argp_make_fmtstream line_wrap_stream
-#define __argp_make_fmtstream line_wrap_stream
-#define argp_fmtstream_free line_unwrap_stream
-#define __argp_fmtstream_free line_unwrap_stream
-
-#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
-#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
-#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
-#define argp_fmtstream_puts(fs,str) fputs(str,fs)
-#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
-#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
-#define __argp_fmtstream_printf fprintf
-#define argp_fmtstream_printf fprintf
-
-#define __argp_fmtstream_lmargin line_wrap_lmargin
-#define argp_fmtstream_lmargin line_wrap_lmargin
-#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
-#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
-#define __argp_fmtstream_rmargin line_wrap_rmargin
-#define argp_fmtstream_rmargin line_wrap_rmargin
-#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
-#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
-#define __argp_fmtstream_wmargin line_wrap_wmargin
-#define argp_fmtstream_wmargin line_wrap_wmargin
-#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
-#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
-#define __argp_fmtstream_point line_wrap_point
-#define argp_fmtstream_point line_wrap_point
-
-#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
-/* Guess we have to define our own version. */
-
-struct argp_fmtstream
-{
- FILE *stream; /* The stream we're outputting to. */
-
- size_t lmargin, rmargin; /* Left and right margins. */
- ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
-
- /* Point in buffer to which we've processed for wrapping, but not output. */
- size_t point_offs;
- /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
- ssize_t point_col;
-
- char *buf; /* Output buffer. */
- char *p; /* Current end of text in BUF. */
- char *end; /* Absolute end of BUF. */
-};
-
-typedef struct argp_fmtstream *argp_fmtstream_t;
-
-/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
- written on it with LMARGIN spaces and limits them to RMARGIN columns
- total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
- replacing the whitespace before them with a newline and WMARGIN spaces.
- Otherwise, chars beyond RMARGIN are simply dropped until a newline.
- Returns NULL if there was an error. */
-extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
- size_t __lmargin,
- size_t __rmargin,
- ssize_t __wmargin);
-extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
- size_t __lmargin,
- size_t __rmargin,
- ssize_t __wmargin);
-
-/* Flush __FS to its stream, and free it (but don't close the stream). */
-extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
-extern void argp_fmtstream_free (argp_fmtstream_t __fs);
-
-extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
- const char *__fmt, ...)
- __attribute__ ((__format__ (printf, 2, 3)));
-extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
- const char *__fmt, ...)
- __attribute__ ((__format__ (printf, 2, 3)));
-
-extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
-extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
-
-extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
-extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
-
-extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
- const char *__str, size_t __len);
-extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
- const char *__str, size_t __len);
-
-/* Access macros for various bits of state. */
-#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
-#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
-#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
-#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
-#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
-#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-/* Set __FS's left margin to LMARGIN and return the old value. */
-extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
- size_t __lmargin);
-extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
- size_t __lmargin);
-
-/* Set __FS's right margin to __RMARGIN and return the old value. */
-extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
- size_t __rmargin);
-extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
- size_t __rmargin);
-
-/* Set __FS's wrap margin to __WMARGIN and return the old value. */
-extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
- size_t __wmargin);
-extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
- size_t __wmargin);
-
-/* Return the column number of the current output point in __FS. */
-extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
-extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
-
-/* Internal routines. */
-extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
-extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
-extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
-extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
-
-#ifdef __OPTIMIZE__
-/* Inline versions of above routines. */
-
-#if !_LIBC
-#define __argp_fmtstream_putc argp_fmtstream_putc
-#define __argp_fmtstream_puts argp_fmtstream_puts
-#define __argp_fmtstream_write argp_fmtstream_write
-#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
-#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
-#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
-#define __argp_fmtstream_point argp_fmtstream_point
-#define __argp_fmtstream_update _argp_fmtstream_update
-#define __argp_fmtstream_ensure _argp_fmtstream_ensure
-#endif
-
-#ifndef ARGP_FS_EI
-#define ARGP_FS_EI extern inline
-#endif
-
-ARGP_FS_EI size_t
-__argp_fmtstream_write (argp_fmtstream_t __fs,
- const char *__str, size_t __len)
-{
- if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
- {
- memcpy (__fs->p, __str, __len);
- __fs->p += __len;
- return __len;
- }
- else
- return 0;
-}
-
-ARGP_FS_EI int
-__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
-{
- size_t __len = strlen (__str);
- if (__len)
- {
- size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
- return __wrote == __len ? 0 : -1;
- }
- else
- return 0;
-}
-
-ARGP_FS_EI int
-__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
-{
- if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
- return *__fs->p++ = __ch;
- else
- return EOF;
-}
-
-/* Set __FS's left margin to __LMARGIN and return the old value. */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->lmargin;
- __fs->lmargin = __lmargin;
- return __old;
-}
-
-/* Set __FS's right margin to __RMARGIN and return the old value. */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->rmargin;
- __fs->rmargin = __rmargin;
- return __old;
-}
-
-/* Set FS's wrap margin to __WMARGIN and return the old value. */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->wmargin;
- __fs->wmargin = __wmargin;
- return __old;
-}
-
-/* Return the column number of the current output point in __FS. */
-ARGP_FS_EI size_t
-__argp_fmtstream_point (argp_fmtstream_t __fs)
-{
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- return __fs->point_col >= 0 ? __fs->point_col : 0;
-}
-
-#if !_LIBC
-#undef __argp_fmtstream_putc
-#undef __argp_fmtstream_puts
-#undef __argp_fmtstream_write
-#undef __argp_fmtstream_set_lmargin
-#undef __argp_fmtstream_set_rmargin
-#undef __argp_fmtstream_set_wmargin
-#undef __argp_fmtstream_point
-#undef __argp_fmtstream_update
-#undef __argp_fmtstream_ensure
-#endif
-
-#endif /* __OPTIMIZE__ */
-
-#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
-
-#endif /* argp-fmtstream.h */
diff --git a/contrib/cpio/lib/argp-fs-xinl.c b/contrib/cpio/lib/argp-fs-xinl.c
deleted file mode 100644
index 3b4c917..0000000
--- a/contrib/cpio/lib/argp-fs-xinl.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Real definitions for extern inline functions in argp-fmtstream.h
- Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define ARGP_FS_EI
-#undef __OPTIMIZE__
-#define __OPTIMIZE__ 1
-#include "argp-fmtstream.h"
-
-#if 0
-/* Not exported. */
-/* Add weak aliases. */
-#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
-
-weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
-weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
-weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
-weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
-weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
-weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
-weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
-
-#endif
-#endif
diff --git a/contrib/cpio/lib/argp-help.c b/contrib/cpio/lib/argp-help.c
deleted file mode 100644
index 396e733..0000000
--- a/contrib/cpio/lib/argp-help.c
+++ /dev/null
@@ -1,1954 +0,0 @@
-/* Hierarchial argument parsing help output
- Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <alloca.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <limits.h>
-#ifdef USE_IN_LIBIO
-# include <wchar.h>
-#endif
-
-#ifdef _LIBC
-# include <libintl.h>
-# undef dgettext
-# define dgettext(domain, msgid) \
- INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
-#else
-# include "gettext.h"
-#endif
-
-#include "argp.h"
-#include "argp-fmtstream.h"
-#include "argp-namefrob.h"
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-/* User-selectable (using an environment variable) formatting parameters.
-
- These may be specified in an environment variable called `ARGP_HELP_FMT',
- with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
- Where VALn must be a positive integer. The list of variables is in the
- UPARAM_NAMES vector, below. */
-
-/* Default parameters. */
-#define DUP_ARGS 0 /* True if option argument can be duplicated. */
-#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
-#define SHORT_OPT_COL 2 /* column in which short options start */
-#define LONG_OPT_COL 6 /* column in which long options start */
-#define DOC_OPT_COL 2 /* column in which doc options start */
-#define OPT_DOC_COL 29 /* column in which option text starts */
-#define HEADER_COL 1 /* column in which group headers are printed */
-#define USAGE_INDENT 12 /* indentation of wrapped usage lines */
-#define RMARGIN 79 /* right margin used for wrapping */
-
-/* User-selectable (using an environment variable) formatting parameters.
- They must all be of type `int' for the parsing code to work. */
-struct uparams
-{
- /* If true, arguments for an option are shown with both short and long
- options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
- If false, then if an option has both, the argument is only shown with
- the long one, e.g., `-x, --longx=ARG', and a message indicating that
- this really means both is printed below the options. */
- int dup_args;
-
- /* This is true if when DUP_ARGS is false, and some duplicate arguments have
- been suppressed, an explanatory message should be printed. */
- int dup_args_note;
-
- /* Various output columns. */
- int short_opt_col; /* column in which short options start */
- int long_opt_col; /* column in which long options start */
- int doc_opt_col; /* column in which doc options start */
- int opt_doc_col; /* column in which option text starts */
- int header_col; /* column in which group headers are printed */
- int usage_indent; /* indentation of wrapped usage lines */
- int rmargin; /* right margin used for wrapping */
-
- int valid; /* True when the values in here are valid. */
-};
-
-/* This is a global variable, as user options are only ever read once. */
-static struct uparams uparams = {
- DUP_ARGS, DUP_ARGS_NOTE,
- SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
- USAGE_INDENT, RMARGIN,
- 0
-};
-
-/* A particular uparam, and what the user name is. */
-struct uparam_name
-{
- const char *name; /* User name. */
- int is_bool; /* Whether it's `boolean'. */
- size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
-};
-
-/* The name-field mappings we know about. */
-static const struct uparam_name uparam_names[] =
-{
- { "dup-args", 1, offsetof (struct uparams, dup_args) },
- { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
- { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
- { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
- { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
- { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
- { "header-col", 0, offsetof (struct uparams, header_col) },
- { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
- { "rmargin", 0, offsetof (struct uparams, rmargin) },
- { 0 }
-};
-
-static void
-validate_uparams (const struct argp_state *state, struct uparams *upptr)
-{
- const struct uparam_name *up;
-
- for (up = uparam_names; up->name; up++)
- {
- if (up->is_bool
- || up->uparams_offs == offsetof (struct uparams, rmargin))
- continue;
- if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
- {
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain,
- "\
-ARGP_HELP_FMT: %s value is less than or equal to %s"),
- "rmargin", up->name);
- return;
- }
- }
- uparams = *upptr;
- uparams.valid = 1;
-}
-
-/* Read user options from the environment, and fill in UPARAMS appropiately. */
-static void
-fill_in_uparams (const struct argp_state *state)
-{
- const char *var = getenv ("ARGP_HELP_FMT");
- struct uparams new_params = uparams;
-
-#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0);
-
- if (var)
- {
- /* Parse var. */
- while (*var)
- {
- SKIPWS (var);
-
- if (isalpha ((unsigned char) *var))
- {
- size_t var_len;
- const struct uparam_name *un;
- int unspec = 0, val = 0;
- const char *arg = var;
-
- while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_')
- arg++;
- var_len = arg - var;
-
- SKIPWS (arg);
-
- if (*arg == '\0' || *arg == ',')
- unspec = 1;
- else if (*arg == '=')
- {
- arg++;
- SKIPWS (arg);
- }
-
- if (unspec)
- {
- if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
- {
- val = 0;
- var += 3;
- var_len -= 3;
- }
- else
- val = 1;
- }
- else if (isdigit ((unsigned char) *arg))
- {
- val = atoi (arg);
- while (isdigit ((unsigned char) *arg))
- arg++;
- SKIPWS (arg);
- }
-
- for (un = uparam_names; un->name; un++)
- if (strlen (un->name) == var_len
- && strncmp (var, un->name, var_len) == 0)
- {
- if (unspec && !un->is_bool)
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain,
- "\
-%.*s: ARGP_HELP_FMT parameter requires a value"),
- (int) var_len, var);
- else if (val < 0)
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain,
- "\
-%.*s: ARGP_HELP_FMT parameter must be positive"),
- (int) var_len, var);
- else
- *(int *)((char *)&new_params + un->uparams_offs) = val;
- break;
- }
- if (! un->name)
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain, "\
-%.*s: Unknown ARGP_HELP_FMT parameter"),
- (int) var_len, var);
-
- var = arg;
- if (*var == ',')
- var++;
- }
- else if (*var)
- {
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain,
- "Garbage in ARGP_HELP_FMT: %s"), var);
- break;
- }
- }
- validate_uparams (state, &new_params);
- }
-}
-
-/* Returns true if OPT hasn't been marked invisible. Visibility only affects
- whether OPT is displayed or used in sorting, not option shadowing. */
-#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
-
-/* Returns true if OPT is an alias for an earlier option. */
-#define oalias(opt) ((opt)->flags & OPTION_ALIAS)
-
-/* Returns true if OPT is an documentation-only entry. */
-#define odoc(opt) ((opt)->flags & OPTION_DOC)
-
-/* Returns true if OPT should not be translated */
-#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
-
-/* Returns true if OPT is the end-of-list marker for a list of options. */
-#define oend(opt) __option_is_end (opt)
-
-/* Returns true if OPT has a short option. */
-#define oshort(opt) __option_is_short (opt)
-
-/*
- The help format for a particular option is like:
-
- -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
-
- Where ARG will be omitted if there's no argument, for this option, or
- will be surrounded by "[" and "]" appropiately if the argument is
- optional. The documentation string is word-wrapped appropiately, and if
- the list of options is long enough, it will be started on a separate line.
- If there are no short options for a given option, the first long option is
- indented slighly in a way that's supposed to make most long options appear
- to be in a separate column.
-
- For example, the following output (from ps):
-
- -p PID, --pid=PID List the process PID
- --pgrp=PGRP List processes in the process group PGRP
- -P, -x, --no-parent Include processes without parents
- -Q, --all-fields Don't elide unusable fields (normally if there's
- some reason ps can't print a field for any
- process, it's removed from the output entirely)
- -r, --reverse, --gratuitously-long-reverse-option
- Reverse the order of any sort
- --session[=SID] Add the processes from the session SID (which
- defaults to the sid of the current process)
-
- Here are some more options:
- -f ZOT, --foonly=ZOT Glork a foonly
- -z, --zaza Snit a zar
-
- -?, --help Give this help list
- --usage Give a short usage message
- -V, --version Print program version
-
- The struct argp_option array for the above could look like:
-
- {
- {"pid", 'p', "PID", 0, "List the process PID"},
- {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
- {"no-parent", 'P', 0, 0, "Include processes without parents"},
- {0, 'x', 0, OPTION_ALIAS},
- {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
- " if there's some reason ps can't"
- " print a field for any process, it's"
- " removed from the output entirely)" },
- {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
- {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
- {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
- "Add the processes from the session"
- " SID (which defaults to the sid of"
- " the current process)" },
-
- {0,0,0,0, "Here are some more options:"},
- {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
- {"zaza", 'z', 0, 0, "Snit a zar"},
-
- {0}
- }
-
- Note that the last three options are automatically supplied by argp_parse,
- unless you tell it not to with ARGP_NO_HELP.
-
-*/
-
-/* Returns true if CH occurs between BEG and END. */
-static int
-find_char (char ch, char *beg, char *end)
-{
- while (beg < end)
- if (*beg == ch)
- return 1;
- else
- beg++;
- return 0;
-}
-
-struct hol_cluster; /* fwd decl */
-
-struct hol_entry
-{
- /* First option. */
- const struct argp_option *opt;
- /* Number of options (including aliases). */
- unsigned num;
-
- /* A pointers into the HOL's short_options field, to the first short option
- letter for this entry. The order of the characters following this point
- corresponds to the order of options pointed to by OPT, and there are at
- most NUM. A short option recorded in a option following OPT is only
- valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
- probably been shadowed by some other entry). */
- char *short_options;
-
- /* Entries are sorted by their group first, in the order:
- 1, 2, ..., n, 0, -m, ..., -2, -1
- and then alphabetically within each group. The default is 0. */
- int group;
-
- /* The cluster of options this entry belongs to, or 0 if none. */
- struct hol_cluster *cluster;
-
- /* The argp from which this option came. */
- const struct argp *argp;
-
- /* Position in the array */
- unsigned ord;
-};
-
-/* A cluster of entries to reflect the argp tree structure. */
-struct hol_cluster
-{
- /* A descriptive header printed before options in this cluster. */
- const char *header;
-
- /* Used to order clusters within the same group with the same parent,
- according to the order in which they occurred in the parent argp's child
- list. */
- int index;
-
- /* How to sort this cluster with respect to options and other clusters at the
- same depth (clusters always follow options in the same group). */
- int group;
-
- /* The cluster to which this cluster belongs, or 0 if it's at the base
- level. */
- struct hol_cluster *parent;
-
- /* The argp from which this cluster is (eventually) derived. */
- const struct argp *argp;
-
- /* The distance this cluster is from the root. */
- int depth;
-
- /* Clusters in a given hol are kept in a linked list, to make freeing them
- possible. */
- struct hol_cluster *next;
-};
-
-/* A list of options for help. */
-struct hol
-{
- /* An array of hol_entry's. */
- struct hol_entry *entries;
- /* The number of entries in this hol. If this field is zero, the others
- are undefined. */
- unsigned num_entries;
-
- /* A string containing all short options in this HOL. Each entry contains
- pointers into this string, so the order can't be messed with blindly. */
- char *short_options;
-
- /* Clusters of entries in this hol. */
- struct hol_cluster *clusters;
-};
-
-/* Create a struct hol from the options in ARGP. CLUSTER is the
- hol_cluster in which these entries occur, or 0, if at the root. */
-static struct hol *
-make_hol (const struct argp *argp, struct hol_cluster *cluster)
-{
- char *so;
- const struct argp_option *o;
- const struct argp_option *opts = argp->options;
- struct hol_entry *entry;
- unsigned num_short_options = 0;
- struct hol *hol = malloc (sizeof (struct hol));
-
- assert (hol);
-
- hol->num_entries = 0;
- hol->clusters = 0;
-
- if (opts)
- {
- int cur_group = 0;
-
- /* The first option must not be an alias. */
- assert (! oalias (opts));
-
- /* Calculate the space needed. */
- for (o = opts; ! oend (o); o++)
- {
- if (! oalias (o))
- hol->num_entries++;
- if (oshort (o))
- num_short_options++; /* This is an upper bound. */
- }
-
- hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
- hol->short_options = malloc (num_short_options + 1);
-
- assert (hol->entries && hol->short_options);
- if (SIZE_MAX <= UINT_MAX)
- assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
-
- /* Fill in the entries. */
- so = hol->short_options;
- for (o = opts, entry = hol->entries; ! oend (o); entry++)
- {
- entry->opt = o;
- entry->num = 0;
- entry->short_options = so;
- entry->group = cur_group =
- o->group
- ? o->group
- : ((!o->name && !o->key)
- ? cur_group + 1
- : cur_group);
- entry->cluster = cluster;
- entry->argp = argp;
-
- do
- {
- entry->num++;
- if (oshort (o) && ! find_char (o->key, hol->short_options, so))
- /* O has a valid short option which hasn't already been used.*/
- *so++ = o->key;
- o++;
- }
- while (! oend (o) && oalias (o));
- }
- *so = '\0'; /* null terminated so we can find the length */
- }
-
- return hol;
-}
-
-/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
- associated argp child list entry), INDEX, and PARENT, and return a pointer
- to it. ARGP is the argp that this cluster results from. */
-static struct hol_cluster *
-hol_add_cluster (struct hol *hol, int group, const char *header, int index,
- struct hol_cluster *parent, const struct argp *argp)
-{
- struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
- if (cl)
- {
- cl->group = group;
- cl->header = header;
-
- cl->index = index;
- cl->parent = parent;
- cl->argp = argp;
- cl->depth = parent ? parent->depth + 1 : 0;
-
- cl->next = hol->clusters;
- hol->clusters = cl;
- }
- return cl;
-}
-
-/* Free HOL and any resources it uses. */
-static void
-hol_free (struct hol *hol)
-{
- struct hol_cluster *cl = hol->clusters;
-
- while (cl)
- {
- struct hol_cluster *next = cl->next;
- free (cl);
- cl = next;
- }
-
- if (hol->num_entries > 0)
- {
- free (hol->entries);
- free (hol->short_options);
- }
-
- free (hol);
-}
-
-static int
-hol_entry_short_iterate (const struct hol_entry *entry,
- int (*func)(const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie),
- const char *domain, void *cookie)
-{
- unsigned nopts;
- int val = 0;
- const struct argp_option *opt, *real = entry->opt;
- char *so = entry->short_options;
-
- for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
- if (oshort (opt) && *so == opt->key)
- {
- if (!oalias (opt))
- real = opt;
- if (ovisible (opt))
- val = (*func)(opt, real, domain, cookie);
- so++;
- }
-
- return val;
-}
-
-static inline int
-__attribute__ ((always_inline))
-hol_entry_long_iterate (const struct hol_entry *entry,
- int (*func)(const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie),
- const char *domain, void *cookie)
-{
- unsigned nopts;
- int val = 0;
- const struct argp_option *opt, *real = entry->opt;
-
- for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
- if (opt->name)
- {
- if (!oalias (opt))
- real = opt;
- if (ovisible (opt))
- val = (*func)(opt, real, domain, cookie);
- }
-
- return val;
-}
-
-/* Iterator that returns true for the first short option. */
-static inline int
-until_short (const struct argp_option *opt, const struct argp_option *real,
- const char *domain, void *cookie)
-{
- return oshort (opt) ? opt->key : 0;
-}
-
-/* Returns the first valid short option in ENTRY, or 0 if there is none. */
-static char
-hol_entry_first_short (const struct hol_entry *entry)
-{
- return hol_entry_short_iterate (entry, until_short,
- entry->argp->argp_domain, 0);
-}
-
-/* Returns the first valid long option in ENTRY, or 0 if there is none. */
-static const char *
-hol_entry_first_long (const struct hol_entry *entry)
-{
- const struct argp_option *opt;
- unsigned num;
- for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- return opt->name;
- return 0;
-}
-
-/* Returns the entry in HOL with the long option name NAME, or 0 if there is
- none. */
-static struct hol_entry *
-hol_find_entry (struct hol *hol, const char *name)
-{
- struct hol_entry *entry = hol->entries;
- unsigned num_entries = hol->num_entries;
-
- while (num_entries-- > 0)
- {
- const struct argp_option *opt = entry->opt;
- unsigned num_opts = entry->num;
-
- while (num_opts-- > 0)
- if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
- return entry;
- else
- opt++;
-
- entry++;
- }
-
- return 0;
-}
-
-/* If an entry with the long option NAME occurs in HOL, set it's special
- sort position to GROUP. */
-static void
-hol_set_group (struct hol *hol, const char *name, int group)
-{
- struct hol_entry *entry = hol_find_entry (hol, name);
- if (entry)
- entry->group = group;
-}
-
-/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
- EQ is what to return if GROUP1 and GROUP2 are the same. */
-static int
-group_cmp (int group1, int group2, int eq)
-{
- if (group1 == group2)
- return eq;
- else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
- return group1 - group2;
- else
- return group2 - group1;
-}
-
-/* Compare clusters CL1 & CL2 by the order that they should appear in
- output. */
-static int
-hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
-{
- /* If one cluster is deeper than the other, use its ancestor at the same
- level, so that finding the common ancestor is straightforward.
-
- clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */
- while (cl1->depth > cl2->depth)
- cl1 = cl1->parent;
- while (cl2->depth > cl1->depth)
- cl2 = cl2->parent;
-
- /* Now reduce both clusters to their ancestors at the point where both have
- a common parent; these can be directly compared. */
- while (cl1->parent != cl2->parent)
- cl1 = cl1->parent, cl2 = cl2->parent;
-
- return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
-}
-
-/* Return the ancestor of CL that's just below the root (i.e., has a parent
- of 0). */
-static struct hol_cluster *
-hol_cluster_base (struct hol_cluster *cl)
-{
- while (cl->parent)
- cl = cl->parent;
- return cl;
-}
-
-/* Return true if CL1 is a child of CL2. */
-static int
-hol_cluster_is_child (const struct hol_cluster *cl1,
- const struct hol_cluster *cl2)
-{
- while (cl1 && cl1 != cl2)
- cl1 = cl1->parent;
- return cl1 == cl2;
-}
-
-/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
- that should be used for comparisons, and returns true iff it should be
- treated as a non-option. */
-static int
-canon_doc_option (const char **name)
-{
- int non_opt;
-
- if (!*name)
- non_opt = 1;
- else
- {
- /* Skip initial whitespace. */
- while (isspace ((unsigned char) **name))
- (*name)++;
- /* Decide whether this looks like an option (leading `-') or not. */
- non_opt = (**name != '-');
- /* Skip until part of name used for sorting. */
- while (**name && !isalnum ((unsigned char) **name))
- (*name)++;
- }
- return non_opt;
-}
-
-#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1)
-
-/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
- listing. */
-static int
-hol_entry_cmp (const struct hol_entry *entry1,
- const struct hol_entry *entry2)
-{
- /* The group numbers by which the entries should be ordered; if either is
- in a cluster, then this is just the group within the cluster. */
- int group1 = entry1->group, group2 = entry2->group;
- int rc;
-
- if (entry1->cluster != entry2->cluster)
- {
- /* The entries are not within the same cluster, so we can't compare them
- directly, we have to use the appropiate clustering level too. */
- if (! entry1->cluster)
- /* ENTRY1 is at the `base level', not in a cluster, so we have to
- compare it's group number with that of the base cluster in which
- ENTRY2 resides. Note that if they're in the same group, the
- clustered option always comes laster. */
- return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
- else if (! entry2->cluster)
- /* Likewise, but ENTRY2's not in a cluster. */
- return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
- else
- /* Both entries are in clusters, we can just compare the clusters. */
- return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ?
- rc : HOL_ENTRY_PTRCMP(entry1, entry2);
- }
- else if (group1 == group2)
- /* The entries are both in the same cluster and group, so compare them
- alphabetically. */
- {
- int short1 = hol_entry_first_short (entry1);
- int short2 = hol_entry_first_short (entry2);
- int doc1 = odoc (entry1->opt);
- int doc2 = odoc (entry2->opt);
- const char *long1 = hol_entry_first_long (entry1);
- const char *long2 = hol_entry_first_long (entry2);
-
- if (doc1)
- doc1 = canon_doc_option (&long1);
- if (doc2)
- doc2 = canon_doc_option (&long2);
-
- if (doc1 != doc2)
- /* `documentation' options always follow normal options (or
- documentation options that *look* like normal options). */
- return doc1 - doc2;
- else if (!short1 && !short2 && long1 && long2)
- /* Only long options. */
- return (rc = __strcasecmp (long1, long2)) ?
- rc : HOL_ENTRY_PTRCMP(entry1, entry2);
- else
- /* Compare short/short, long/short, short/long, using the first
- character of long options. Entries without *any* valid
- options (such as options with OPTION_HIDDEN set) will be put
- first, but as they're not displayed, it doesn't matter where
- they are. */
- {
- char first1 = short1 ? short1 : long1 ? *long1 : 0;
- char first2 = short2 ? short2 : long2 ? *long2 : 0;
-#ifdef _tolower
- int lower_cmp = _tolower (first1) - _tolower (first2);
-#else
- int lower_cmp = tolower (first1) - tolower (first2);
-#endif
- /* Compare ignoring case, except when the options are both the
- same letter, in which case lower-case always comes first. */
- return lower_cmp ? lower_cmp :
- (rc = first2 - first1) ?
- rc : HOL_ENTRY_PTRCMP(entry1, entry2);
- }
- }
- else
- /* Within the same cluster, but not the same group, so just compare
- groups. */
- return group_cmp (group1, group2, HOL_ENTRY_PTRCMP(entry1, entry2));
-}
-
-/* Version of hol_entry_cmp with correct signature for qsort. */
-static int
-hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
-{
- return hol_entry_cmp (entry1_v, entry2_v);
-}
-
-/* Sort HOL by group and alphabetically by option name (with short options
- taking precedence over long). Since the sorting is for display purposes
- only, the shadowing of options isn't effected. */
-static void
-hol_sort (struct hol *hol)
-{
- if (hol->num_entries > 0)
- {
- unsigned i;
- struct hol_entry *e;
- for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
- e->ord = i;
- qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
- hol_entry_qcmp);
- }
-}
-
-/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
- any in MORE with the same name. */
-static void
-hol_append (struct hol *hol, struct hol *more)
-{
- struct hol_cluster **cl_end = &hol->clusters;
-
- /* Steal MORE's cluster list, and add it to the end of HOL's. */
- while (*cl_end)
- cl_end = &(*cl_end)->next;
- *cl_end = more->clusters;
- more->clusters = 0;
-
- /* Merge entries. */
- if (more->num_entries > 0)
- {
- if (hol->num_entries == 0)
- {
- hol->num_entries = more->num_entries;
- hol->entries = more->entries;
- hol->short_options = more->short_options;
- more->num_entries = 0; /* Mark MORE's fields as invalid. */
- }
- else
- /* Append the entries in MORE to those in HOL, taking care to only add
- non-shadowed SHORT_OPTIONS values. */
- {
- unsigned left;
- char *so, *more_so;
- struct hol_entry *e;
- unsigned num_entries = hol->num_entries + more->num_entries;
- struct hol_entry *entries =
- malloc (num_entries * sizeof (struct hol_entry));
- unsigned hol_so_len = strlen (hol->short_options);
- char *short_options =
- malloc (hol_so_len + strlen (more->short_options) + 1);
-
- assert (entries && short_options);
- if (SIZE_MAX <= UINT_MAX)
- assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
-
- __mempcpy (__mempcpy (entries, hol->entries,
- hol->num_entries * sizeof (struct hol_entry)),
- more->entries,
- more->num_entries * sizeof (struct hol_entry));
-
- __mempcpy (short_options, hol->short_options, hol_so_len);
-
- /* Fix up the short options pointers from HOL. */
- for (e = entries, left = hol->num_entries; left > 0; e++, left--)
- e->short_options += (short_options - hol->short_options);
-
- /* Now add the short options from MORE, fixing up its entries
- too. */
- so = short_options + hol_so_len;
- more_so = more->short_options;
- for (left = more->num_entries; left > 0; e++, left--)
- {
- int opts_left;
- const struct argp_option *opt;
-
- e->short_options = so;
-
- for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
- {
- int ch = *more_so;
- if (oshort (opt) && ch == opt->key)
- /* The next short option in MORE_SO, CH, is from OPT. */
- {
- if (! find_char (ch, short_options,
- short_options + hol_so_len))
- /* The short option CH isn't shadowed by HOL's options,
- so add it to the sum. */
- *so++ = ch;
- more_so++;
- }
- }
- }
-
- *so = '\0';
-
- free (hol->entries);
- free (hol->short_options);
-
- hol->entries = entries;
- hol->num_entries = num_entries;
- hol->short_options = short_options;
- }
- }
-
- hol_free (more);
-}
-
-/* Inserts enough spaces to make sure STREAM is at column COL. */
-static void
-indent_to (argp_fmtstream_t stream, unsigned col)
-{
- int needed = col - __argp_fmtstream_point (stream);
- while (needed-- > 0)
- __argp_fmtstream_putc (stream, ' ');
-}
-
-/* Output to STREAM either a space, or a newline if there isn't room for at
- least ENSURE characters before the right margin. */
-static void
-space (argp_fmtstream_t stream, size_t ensure)
-{
- if (__argp_fmtstream_point (stream) + ensure
- >= __argp_fmtstream_rmargin (stream))
- __argp_fmtstream_putc (stream, '\n');
- else
- __argp_fmtstream_putc (stream, ' ');
-}
-
-/* If the option REAL has an argument, we print it in using the printf
- format REQ_FMT or OPT_FMT depending on whether it's a required or
- optional argument. */
-static void
-arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
- const char *domain, argp_fmtstream_t stream)
-{
- if (real->arg)
- {
- if (real->flags & OPTION_ARG_OPTIONAL)
- __argp_fmtstream_printf (stream, opt_fmt,
- dgettext (domain, real->arg));
- else
- __argp_fmtstream_printf (stream, req_fmt,
- dgettext (domain, real->arg));
- }
-}
-
-/* Helper functions for hol_entry_help. */
-
-/* State used during the execution of hol_help. */
-struct hol_help_state
-{
- /* PREV_ENTRY should contain the previous entry printed, or 0. */
- struct hol_entry *prev_entry;
-
- /* If an entry is in a different group from the previous one, and SEP_GROUPS
- is true, then a blank line will be printed before any output. */
- int sep_groups;
-
- /* True if a duplicate option argument was suppressed (only ever set if
- UPARAMS.dup_args is false). */
- int suppressed_dup_arg;
-};
-
-/* Some state used while printing a help entry (used to communicate with
- helper functions). See the doc for hol_entry_help for more info, as most
- of the fields are copied from its arguments. */
-struct pentry_state
-{
- const struct hol_entry *entry;
- argp_fmtstream_t stream;
- struct hol_help_state *hhstate;
-
- /* True if nothing's been printed so far. */
- int first;
-
- /* If non-zero, the state that was used to print this help. */
- const struct argp_state *state;
-};
-
-/* If a user doc filter should be applied to DOC, do so. */
-static const char *
-filter_doc (const char *doc, int key, const struct argp *argp,
- const struct argp_state *state)
-{
- if (argp->help_filter)
- /* We must apply a user filter to this output. */
- {
- void *input = __argp_input (argp, state);
- return (*argp->help_filter) (key, doc, input);
- }
- else
- /* No filter. */
- return doc;
-}
-
-/* Prints STR as a header line, with the margin lines set appropiately, and
- notes the fact that groups should be separated with a blank line. ARGP is
- the argp that should dictate any user doc filtering to take place. Note
- that the previous wrap margin isn't restored, but the left margin is reset
- to 0. */
-static void
-print_header (const char *str, const struct argp *argp,
- struct pentry_state *pest)
-{
- const char *tstr = dgettext (argp->argp_domain, str);
- const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
-
- if (fstr)
- {
- if (*fstr)
- {
- if (pest->hhstate->prev_entry)
- /* Precede with a blank line. */
- __argp_fmtstream_putc (pest->stream, '\n');
- indent_to (pest->stream, uparams.header_col);
- __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
- __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
- __argp_fmtstream_puts (pest->stream, fstr);
- __argp_fmtstream_set_lmargin (pest->stream, 0);
- __argp_fmtstream_putc (pest->stream, '\n');
- }
-
- pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
- }
-
- if (fstr != tstr)
- free ((char *) fstr);
-}
-
-/* Inserts a comma if this isn't the first item on the line, and then makes
- sure we're at least to column COL. If this *is* the first item on a line,
- prints any pending whitespace/headers that should precede this line. Also
- clears FIRST. */
-static void
-comma (unsigned col, struct pentry_state *pest)
-{
- if (pest->first)
- {
- const struct hol_entry *pe = pest->hhstate->prev_entry;
- const struct hol_cluster *cl = pest->entry->cluster;
-
- if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
- __argp_fmtstream_putc (pest->stream, '\n');
-
- if (cl && cl->header && *cl->header
- && (!pe
- || (pe->cluster != cl
- && !hol_cluster_is_child (pe->cluster, cl))))
- /* If we're changing clusters, then this must be the start of the
- ENTRY's cluster unless that is an ancestor of the previous one
- (in which case we had just popped into a sub-cluster for a bit).
- If so, then print the cluster's header line. */
- {
- int old_wm = __argp_fmtstream_wmargin (pest->stream);
- print_header (cl->header, cl->argp, pest);
- __argp_fmtstream_set_wmargin (pest->stream, old_wm);
- }
-
- pest->first = 0;
- }
- else
- __argp_fmtstream_puts (pest->stream, ", ");
-
- indent_to (pest->stream, col);
-}
-
-/* Print help for ENTRY to STREAM. */
-static void
-hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
- argp_fmtstream_t stream, struct hol_help_state *hhstate)
-{
- unsigned num;
- const struct argp_option *real = entry->opt, *opt;
- char *so = entry->short_options;
- int have_long_opt = 0; /* We have any long options. */
- /* Saved margins. */
- int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
- int old_wm = __argp_fmtstream_wmargin (stream);
- /* PEST is a state block holding some of our variables that we'd like to
- share with helper functions. */
- struct pentry_state pest;
-
- pest.entry = entry;
- pest.stream = stream;
- pest.hhstate = hhstate;
- pest.first = 1;
- pest.state = state;
-
- if (! odoc (real))
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- {
- have_long_opt = 1;
- break;
- }
-
- /* First emit short options. */
- __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (oshort (opt) && opt->key == *so)
- /* OPT has a valid (non shadowed) short option. */
- {
- if (ovisible (opt))
- {
- comma (uparams.short_opt_col, &pest);
- __argp_fmtstream_putc (stream, '-');
- __argp_fmtstream_putc (stream, *so);
- if (!have_long_opt || uparams.dup_args)
- arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
- else if (real->arg)
- hhstate->suppressed_dup_arg = 1;
- }
- so++;
- }
-
- /* Now, long options. */
- if (odoc (real))
- /* A `documentation' option. */
- {
- __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (opt->name && *opt->name && ovisible (opt))
- {
- comma (uparams.doc_opt_col, &pest);
- /* Calling dgettext here isn't quite right, since sorting will
- have been done on the original; but documentation options
- should be pretty rare anyway... */
- __argp_fmtstream_puts (stream,
- onotrans (opt) ?
- opt->name :
- dgettext (state->root_argp->argp_domain,
- opt->name));
- }
- }
- else
- /* A real long option. */
- {
- int first_long_opt = 1;
-
- __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- {
- comma (uparams.long_opt_col, &pest);
- __argp_fmtstream_printf (stream, "--%s", opt->name);
- if (first_long_opt || uparams.dup_args)
- arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
- stream);
- else if (real->arg)
- hhstate->suppressed_dup_arg = 1;
- }
- }
-
- /* Next, documentation strings. */
- __argp_fmtstream_set_lmargin (stream, 0);
-
- if (pest.first)
- {
- /* Didn't print any switches, what's up? */
- if (!oshort (real) && !real->name)
- /* This is a group header, print it nicely. */
- print_header (real->doc, entry->argp, &pest);
- else
- /* Just a totally shadowed option or null header; print nothing. */
- goto cleanup; /* Just return, after cleaning up. */
- }
- else
- {
- const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
- real->doc) : 0;
- const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
- if (fstr && *fstr)
- {
- unsigned int col = __argp_fmtstream_point (stream);
-
- __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
- __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
-
- if (col > (unsigned int) (uparams.opt_doc_col + 3))
- __argp_fmtstream_putc (stream, '\n');
- else if (col >= (unsigned int) uparams.opt_doc_col)
- __argp_fmtstream_puts (stream, " ");
- else
- indent_to (stream, uparams.opt_doc_col);
-
- __argp_fmtstream_puts (stream, fstr);
- }
- if (fstr && fstr != tstr)
- free ((char *) fstr);
-
- /* Reset the left margin. */
- __argp_fmtstream_set_lmargin (stream, 0);
- __argp_fmtstream_putc (stream, '\n');
- }
-
- hhstate->prev_entry = entry;
-
-cleanup:
- __argp_fmtstream_set_lmargin (stream, old_lm);
- __argp_fmtstream_set_wmargin (stream, old_wm);
-}
-
-/* Output a long help message about the options in HOL to STREAM. */
-static void
-hol_help (struct hol *hol, const struct argp_state *state,
- argp_fmtstream_t stream)
-{
- unsigned num;
- struct hol_entry *entry;
- struct hol_help_state hhstate = { 0, 0, 0 };
-
- for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
- hol_entry_help (entry, state, stream, &hhstate);
-
- if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
- {
- const char *tstr = dgettext (state->root_argp->argp_domain, "\
-Mandatory or optional arguments to long options are also mandatory or \
-optional for any corresponding short options.");
- const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
- state ? state->root_argp : 0, state);
- if (fstr && *fstr)
- {
- __argp_fmtstream_putc (stream, '\n');
- __argp_fmtstream_puts (stream, fstr);
- __argp_fmtstream_putc (stream, '\n');
- }
- if (fstr && fstr != tstr)
- free ((char *) fstr);
- }
-}
-
-/* Helper functions for hol_usage. */
-
-/* If OPT is a short option without an arg, append its key to the string
- pointer pointer to by COOKIE, and advance the pointer. */
-static int
-add_argless_short_opt (const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie)
-{
- char **snao_end = cookie;
- if (!(opt->arg || real->arg)
- && !((opt->flags | real->flags) & OPTION_NO_USAGE))
- *(*snao_end)++ = opt->key;
- return 0;
-}
-
-/* If OPT is a short option with an arg, output a usage entry for it to the
- stream pointed at by COOKIE. */
-static int
-usage_argful_short_opt (const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie)
-{
- argp_fmtstream_t stream = cookie;
- const char *arg = opt->arg;
- int flags = opt->flags | real->flags;
-
- if (! arg)
- arg = real->arg;
-
- if (arg && !(flags & OPTION_NO_USAGE))
- {
- arg = dgettext (domain, arg);
-
- if (flags & OPTION_ARG_OPTIONAL)
- __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
- else
- {
- /* Manually do line wrapping so that it (probably) won't
- get wrapped at the embedded space. */
- space (stream, 6 + strlen (arg));
- __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
- }
- }
-
- return 0;
-}
-
-/* Output a usage entry for the long option opt to the stream pointed at by
- COOKIE. */
-static int
-usage_long_opt (const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie)
-{
- argp_fmtstream_t stream = cookie;
- const char *arg = opt->arg;
- int flags = opt->flags | real->flags;
-
- if (! arg)
- arg = real->arg;
-
- if (! (flags & OPTION_NO_USAGE) && !odoc (opt))
- {
- if (arg)
- {
- arg = dgettext (domain, arg);
- if (flags & OPTION_ARG_OPTIONAL)
- __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
- else
- __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
- }
- else
- __argp_fmtstream_printf (stream, " [--%s]", opt->name);
- }
-
- return 0;
-}
-
-/* Print a short usage description for the arguments in HOL to STREAM. */
-static void
-hol_usage (struct hol *hol, argp_fmtstream_t stream)
-{
- if (hol->num_entries > 0)
- {
- unsigned nentries;
- struct hol_entry *entry;
- char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
- char *snao_end = short_no_arg_opts;
-
- /* First we put a list of short options without arguments. */
- for (entry = hol->entries, nentries = hol->num_entries
- ; nentries > 0
- ; entry++, nentries--)
- hol_entry_short_iterate (entry, add_argless_short_opt,
- entry->argp->argp_domain, &snao_end);
- if (snao_end > short_no_arg_opts)
- {
- *snao_end++ = 0;
- __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
- }
-
- /* Now a list of short options *with* arguments. */
- for (entry = hol->entries, nentries = hol->num_entries
- ; nentries > 0
- ; entry++, nentries--)
- hol_entry_short_iterate (entry, usage_argful_short_opt,
- entry->argp->argp_domain, stream);
-
- /* Finally, a list of long options (whew!). */
- for (entry = hol->entries, nentries = hol->num_entries
- ; nentries > 0
- ; entry++, nentries--)
- hol_entry_long_iterate (entry, usage_long_opt,
- entry->argp->argp_domain, stream);
- }
-}
-
-/* Make a HOL containing all levels of options in ARGP. CLUSTER is the
- cluster in which ARGP's entries should be clustered, or 0. */
-static struct hol *
-argp_hol (const struct argp *argp, struct hol_cluster *cluster)
-{
- const struct argp_child *child = argp->children;
- struct hol *hol = make_hol (argp, cluster);
- if (child)
- while (child->argp)
- {
- struct hol_cluster *child_cluster =
- ((child->group || child->header)
- /* Put CHILD->argp within its own cluster. */
- ? hol_add_cluster (hol, child->group, child->header,
- child - argp->children, cluster, argp)
- /* Just merge it into the parent's cluster. */
- : cluster);
- hol_append (hol, argp_hol (child->argp, child_cluster)) ;
- child++;
- }
- return hol;
-}
-
-/* Calculate how many different levels with alternative args strings exist in
- ARGP. */
-static size_t
-argp_args_levels (const struct argp *argp)
-{
- size_t levels = 0;
- const struct argp_child *child = argp->children;
-
- if (argp->args_doc && strchr (argp->args_doc, '\n'))
- levels++;
-
- if (child)
- while (child->argp)
- levels += argp_args_levels ((child++)->argp);
-
- return levels;
-}
-
-/* Print all the non-option args documented in ARGP to STREAM. Any output is
- preceded by a space. LEVELS is a pointer to a byte vector the length
- returned by argp_args_levels; it should be initialized to zero, and
- updated by this routine for the next call if ADVANCE is true. True is
- returned as long as there are more patterns to output. */
-static int
-argp_args_usage (const struct argp *argp, const struct argp_state *state,
- char **levels, int advance, argp_fmtstream_t stream)
-{
- char *our_level = *levels;
- int multiple = 0;
- const struct argp_child *child = argp->children;
- const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
- const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
-
- if (fdoc)
- {
- const char *cp = fdoc;
- nl = __strchrnul (cp, '\n');
- if (*nl != '\0')
- /* This is a `multi-level' args doc; advance to the correct position
- as determined by our state in LEVELS, and update LEVELS. */
- {
- int i;
- multiple = 1;
- for (i = 0; i < *our_level; i++)
- cp = nl + 1, nl = __strchrnul (cp, '\n');
- (*levels)++;
- }
-
- /* Manually do line wrapping so that it (probably) won't get wrapped at
- any embedded spaces. */
- space (stream, 1 + nl - cp);
-
- __argp_fmtstream_write (stream, cp, nl - cp);
- }
- if (fdoc && fdoc != tdoc)
- free ((char *)fdoc); /* Free user's modified doc string. */
-
- if (child)
- while (child->argp)
- advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
-
- if (advance && multiple)
- {
- /* Need to increment our level. */
- if (*nl)
- /* There's more we can do here. */
- {
- (*our_level)++;
- advance = 0; /* Our parent shouldn't advance also. */
- }
- else if (*our_level > 0)
- /* We had multiple levels, but used them up; reset to zero. */
- *our_level = 0;
- }
-
- return !advance;
-}
-
-/* Print the documentation for ARGP to STREAM; if POST is false, then
- everything preceeding a `\v' character in the documentation strings (or
- the whole string, for those with none) is printed, otherwise, everything
- following the `\v' character (nothing for strings without). Each separate
- bit of documentation is separated a blank line, and if PRE_BLANK is true,
- then the first is as well. If FIRST_ONLY is true, only the first
- occurrence is output. Returns true if anything was output. */
-static int
-argp_doc (const struct argp *argp, const struct argp_state *state,
- int post, int pre_blank, int first_only,
- argp_fmtstream_t stream)
-{
- const char *text;
- const char *inp_text;
- size_t inp_text_len = 0;
- const char *trans_text;
- void *input = 0;
- int anything = 0;
- const struct argp_child *child = argp->children;
-
- if (argp->doc)
- {
- char *vt = strchr (argp->doc, '\v');
- if (vt)
- {
- if (post)
- inp_text = vt + 1;
- else
- {
- inp_text_len = vt - argp->doc;
- inp_text = __strndup (argp->doc, inp_text_len);
- }
- }
- else
- inp_text = post ? 0 : argp->doc;
- trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL;
- }
- else
- trans_text = inp_text = 0;
-
- if (argp->help_filter)
- /* We have to filter the doc strings. */
- {
- input = __argp_input (argp, state);
- text =
- (*argp->help_filter) (post
- ? ARGP_KEY_HELP_POST_DOC
- : ARGP_KEY_HELP_PRE_DOC,
- trans_text, input);
- }
- else
- text = (const char *) trans_text;
-
- if (text)
- {
- if (pre_blank)
- __argp_fmtstream_putc (stream, '\n');
-
- __argp_fmtstream_puts (stream, text);
-
- if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
- __argp_fmtstream_putc (stream, '\n');
-
- anything = 1;
- }
-
- if (text && text != trans_text)
- free ((char *) text); /* Free TEXT returned from the help filter. */
-
- if (inp_text && inp_text_len)
- free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
-
- if (post && argp->help_filter)
- /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
- {
- text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
- if (text)
- {
- if (anything || pre_blank)
- __argp_fmtstream_putc (stream, '\n');
- __argp_fmtstream_puts (stream, text);
- free ((char *) text);
- if (__argp_fmtstream_point (stream)
- > __argp_fmtstream_lmargin (stream))
- __argp_fmtstream_putc (stream, '\n');
- anything = 1;
- }
- }
-
- if (child)
- while (child->argp && !(first_only && anything))
- anything |=
- argp_doc ((child++)->argp, state,
- post, anything || pre_blank, first_only,
- stream);
-
- return anything;
-}
-
-/* Output a usage message for ARGP to STREAM. If called from
- argp_state_help, STATE is the relevent parsing state. FLAGS are from the
- set ARGP_HELP_*. NAME is what to use wherever a `program name' is
- needed. */
-static void
-_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
- unsigned flags, char *name)
-{
- int anything = 0; /* Whether we've output anything. */
- struct hol *hol = 0;
- argp_fmtstream_t fs;
-
- if (! stream)
- return;
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __flockfile (stream);
-#endif
-
- if (! uparams.valid)
- fill_in_uparams (state);
-
- fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
- if (! fs)
- {
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __funlockfile (stream);
-#endif
- return;
- }
-
- if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
- {
- hol = argp_hol (argp, 0);
-
- /* If present, these options always come last. */
- hol_set_group (hol, "help", -1);
- hol_set_group (hol, "version", -1);
-
- hol_sort (hol);
- }
-
- if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
- /* Print a short `Usage:' message. */
- {
- int first_pattern = 1, more_patterns;
- size_t num_pattern_levels = argp_args_levels (argp);
- char *pattern_levels = alloca (num_pattern_levels);
-
- memset (pattern_levels, 0, num_pattern_levels);
-
- do
- {
- int old_lm;
- int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
- char *levels = pattern_levels;
-
- if (first_pattern)
- __argp_fmtstream_printf (fs, "%s %s",
- dgettext (argp->argp_domain, "Usage:"),
- name);
- else
- __argp_fmtstream_printf (fs, "%s %s",
- dgettext (argp->argp_domain, " or: "),
- name);
-
- /* We set the lmargin as well as the wmargin, because hol_usage
- manually wraps options with newline to avoid annoying breaks. */
- old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
-
- if (flags & ARGP_HELP_SHORT_USAGE)
- /* Just show where the options go. */
- {
- if (hol->num_entries > 0)
- __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
- " [OPTION...]"));
- }
- else
- /* Actually print the options. */
- {
- hol_usage (hol, fs);
- flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
- }
-
- more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
-
- __argp_fmtstream_set_wmargin (fs, old_wm);
- __argp_fmtstream_set_lmargin (fs, old_lm);
-
- __argp_fmtstream_putc (fs, '\n');
- anything = 1;
-
- first_pattern = 0;
- }
- while (more_patterns);
- }
-
- if (flags & ARGP_HELP_PRE_DOC)
- anything |= argp_doc (argp, state, 0, 0, 1, fs);
-
- if (flags & ARGP_HELP_SEE)
- {
- __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
-Try `%s --help' or `%s --usage' for more information.\n"),
- name, name);
- anything = 1;
- }
-
- if (flags & ARGP_HELP_LONG)
- /* Print a long, detailed help message. */
- {
- /* Print info about all the options. */
- if (hol->num_entries > 0)
- {
- if (anything)
- __argp_fmtstream_putc (fs, '\n');
- hol_help (hol, state, fs);
- anything = 1;
- }
- }
-
- if (flags & ARGP_HELP_POST_DOC)
- /* Print any documentation strings at the end. */
- anything |= argp_doc (argp, state, 1, anything, 0, fs);
-
- if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
- {
- if (anything)
- __argp_fmtstream_putc (fs, '\n');
- __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
- "Report bugs to %s.\n"),
- argp_program_bug_address);
- anything = 1;
- }
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __funlockfile (stream);
-#endif
-
- if (hol)
- hol_free (hol);
-
- __argp_fmtstream_free (fs);
-}
-
-/* Output a usage message for ARGP to STREAM. FLAGS are from the set
- ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
-void __argp_help (const struct argp *argp, FILE *stream,
- unsigned flags, char *name)
-{
- struct argp_state state;
- memset (&state, 0, sizeof state);
- state.root_argp = argp;
- _help (argp, &state, stream, flags, name);
-}
-#ifdef weak_alias
-weak_alias (__argp_help, argp_help)
-#endif
-
-#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
-char *
-__argp_short_program_name (void)
-{
-# if HAVE_DECL_PROGRAM_INVOCATION_NAME
- return __argp_base_name (program_invocation_name);
-# else
- /* FIXME: What now? Miles suggests that it is better to use NULL,
- but currently the value is passed on directly to fputs_unlocked,
- so that requires more changes. */
-# if __GNUC__
-# warning No reasonable value to return
-# endif /* __GNUC__ */
- return "";
-# endif
-}
-#endif
-
-/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
- from the set ARGP_HELP_*. */
-void
-__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
-{
- if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
- {
- if (state && (state->flags & ARGP_LONG_ONLY))
- flags |= ARGP_HELP_LONG_ONLY;
-
- _help (state ? state->root_argp : 0, state, stream, flags,
- state ? state->name : __argp_short_program_name ());
-
- if (!state || ! (state->flags & ARGP_NO_EXIT))
- {
- if (flags & ARGP_HELP_EXIT_ERR)
- exit (argp_err_exit_status);
- if (flags & ARGP_HELP_EXIT_OK)
- exit (0);
- }
- }
-}
-#ifdef weak_alias
-weak_alias (__argp_state_help, argp_state_help)
-#endif
-
-/* If appropriate, print the printf string FMT and following args, preceded
- by the program name and `:', to stderr, and followed by a `Try ... --help'
- message, then exit (1). */
-void
-__argp_error (const struct argp_state *state, const char *fmt, ...)
-{
- if (!state || !(state->flags & ARGP_NO_ERRS))
- {
- FILE *stream = state ? state->err_stream : stderr;
-
- if (stream)
- {
- va_list ap;
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __flockfile (stream);
-#endif
-
- va_start (ap, fmt);
-
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- {
- char *buf;
-
- if (__asprintf (&buf, fmt, ap) < 0)
- buf = NULL;
-
- __fwprintf (stream, L"%s: %s\n",
- state ? state->name : __argp_short_program_name (),
- buf);
-
- free (buf);
- }
- else
-#endif
- {
- fputs_unlocked (state
- ? state->name : __argp_short_program_name (),
- stream);
- putc_unlocked (':', stream);
- putc_unlocked (' ', stream);
-
- vfprintf (stream, fmt, ap);
-
- putc_unlocked ('\n', stream);
- }
-
- __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
-
- va_end (ap);
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __funlockfile (stream);
-#endif
- }
- }
-}
-#ifdef weak_alias
-weak_alias (__argp_error, argp_error)
-#endif
-
-/* Similar to the standard gnu error-reporting function error(), but will
- respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
- to STATE->err_stream. This is useful for argument parsing code that is
- shared between program startup (when exiting is desired) and runtime
- option parsing (when typically an error code is returned instead). The
- difference between this function and argp_error is that the latter is for
- *parsing errors*, and the former is for other problems that occur during
- parsing but don't reflect a (syntactic) problem with the input. */
-void
-__argp_failure (const struct argp_state *state, int status, int errnum,
- const char *fmt, ...)
-{
- if (!state || !(state->flags & ARGP_NO_ERRS))
- {
- FILE *stream = state ? state->err_stream : stderr;
-
- if (stream)
- {
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __flockfile (stream);
-#endif
-
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- __fwprintf (stream, L"%s",
- state ? state->name : __argp_short_program_name ());
- else
-#endif
- fputs_unlocked (state
- ? state->name : __argp_short_program_name (),
- stream);
-
- if (fmt)
- {
- va_list ap;
-
- va_start (ap, fmt);
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- {
- char *buf;
-
- if (__asprintf (&buf, fmt, ap) < 0)
- buf = NULL;
-
- __fwprintf (stream, L": %s", buf);
-
- free (buf);
- }
- else
-#endif
- {
- putc_unlocked (':', stream);
- putc_unlocked (' ', stream);
-
- vfprintf (stream, fmt, ap);
- }
-
- va_end (ap);
- }
-
- if (errnum)
- {
- char buf[200];
-
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- __fwprintf (stream, L": %s",
- __strerror_r (errnum, buf, sizeof (buf)));
- else
-#endif
- {
- char const *s = NULL;
- putc_unlocked (':', stream);
- putc_unlocked (' ', stream);
-#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P)
- s = __strerror_r (errnum, buf, sizeof buf);
-#elif HAVE_DECL_STRERROR_R
- if (__strerror_r (errnum, buf, sizeof buf) == 0)
- s = buf;
-#endif
-#if !_LIBC
- if (! s && ! (s = strerror (errnum)))
- s = dgettext (state->root_argp->argp_domain,
- "Unknown system error");
-#endif
- fputs (s, stream);
- }
- }
-
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- putwc_unlocked (L'\n', stream);
- else
-#endif
- putc_unlocked ('\n', stream);
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
- __funlockfile (stream);
-#endif
-
- if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
- exit (status);
- }
- }
-}
-#ifdef weak_alias
-weak_alias (__argp_failure, argp_failure)
-#endif
diff --git a/contrib/cpio/lib/argp-namefrob.h b/contrib/cpio/lib/argp-namefrob.h
deleted file mode 100644
index 6fe99cd..0000000
--- a/contrib/cpio/lib/argp-namefrob.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Name frobnication for compiling argp outside of glibc
- Copyright (C) 1997, 2003, 2007 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#if !_LIBC
-/* This code is written for inclusion in gnu-libc, and uses names in the
- namespace reserved for libc. If we're not compiling in libc, define those
- names to be the normal ones instead. */
-
-/* argp-parse functions */
-#undef __argp_parse
-#define __argp_parse argp_parse
-#undef __option_is_end
-#define __option_is_end _option_is_end
-#undef __option_is_short
-#define __option_is_short _option_is_short
-#undef __argp_input
-#define __argp_input _argp_input
-
-/* argp-help functions */
-#undef __argp_help
-#define __argp_help argp_help
-#undef __argp_error
-#define __argp_error argp_error
-#undef __argp_failure
-#define __argp_failure argp_failure
-#undef __argp_state_help
-#define __argp_state_help argp_state_help
-#undef __argp_usage
-#define __argp_usage argp_usage
-
-/* argp-fmtstream functions */
-#undef __argp_make_fmtstream
-#define __argp_make_fmtstream argp_make_fmtstream
-#undef __argp_fmtstream_free
-#define __argp_fmtstream_free argp_fmtstream_free
-#undef __argp_fmtstream_putc
-#define __argp_fmtstream_putc argp_fmtstream_putc
-#undef __argp_fmtstream_puts
-#define __argp_fmtstream_puts argp_fmtstream_puts
-#undef __argp_fmtstream_write
-#define __argp_fmtstream_write argp_fmtstream_write
-#undef __argp_fmtstream_printf
-#define __argp_fmtstream_printf argp_fmtstream_printf
-#undef __argp_fmtstream_set_lmargin
-#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
-#undef __argp_fmtstream_set_rmargin
-#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
-#undef __argp_fmtstream_set_wmargin
-#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
-#undef __argp_fmtstream_point
-#define __argp_fmtstream_point argp_fmtstream_point
-#undef __argp_fmtstream_update
-#define __argp_fmtstream_update _argp_fmtstream_update
-#undef __argp_fmtstream_ensure
-#define __argp_fmtstream_ensure _argp_fmtstream_ensure
-#undef __argp_fmtstream_lmargin
-#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
-#undef __argp_fmtstream_rmargin
-#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
-#undef __argp_fmtstream_wmargin
-#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-/* normal libc functions we call */
-#undef __flockfile
-#define __flockfile flockfile
-#undef __funlockfile
-#define __funlockfile funlockfile
-#undef __mempcpy
-#define __mempcpy mempcpy
-#undef __sleep
-#define __sleep sleep
-#undef __strcasecmp
-#define __strcasecmp strcasecmp
-#undef __strchrnul
-#define __strchrnul strchrnul
-#undef __strerror_r
-#define __strerror_r strerror_r
-#undef __strndup
-#define __strndup strndup
-#undef __vsnprintf
-#define __vsnprintf vsnprintf
-
-#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
-# define clearerr_unlocked(x) clearerr (x)
-#endif
-#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
-# define feof_unlocked(x) feof (x)
-# endif
-#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
-# define ferror_unlocked(x) ferror (x)
-# endif
-#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
-# define fflush_unlocked(x) fflush (x)
-# endif
-#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
-# define fgets_unlocked(x,y,z) fgets (x,y,z)
-# endif
-#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
-# define fputc_unlocked(x,y) fputc (x,y)
-# endif
-#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
-# define fputs_unlocked(x,y) fputs (x,y)
-# endif
-#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
-# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
-# endif
-#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
-# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
-# endif
-#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
-# define getc_unlocked(x) getc (x)
-# endif
-#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
-# define getchar_unlocked() getchar ()
-# endif
-#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
-# define putc_unlocked(x,y) putc (x,y)
-# endif
-#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
-# define putchar_unlocked(x) putchar (x)
-# endif
-
-#endif /* !_LIBC */
-
-#ifndef __set_errno
-#define __set_errno(e) (errno = (e))
-#endif
-
-#if defined GNULIB_ARGP_DISABLE_DIRNAME
-# define __argp_base_name(arg) arg
-#elif defined GNULIB_ARGP_EXTERN_BASENAME
-extern char *__argp_base_name(const char *arg);
-#else
-# include "dirname.h"
-# define __argp_base_name base_name
-#endif
-
-#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-# define __argp_short_program_name() (program_invocation_short_name)
-#else
-extern char *__argp_short_program_name (void);
-#endif
diff --git a/contrib/cpio/lib/argp-parse.c b/contrib/cpio/lib/argp-parse.c
deleted file mode 100644
index a7de729..0000000
--- a/contrib/cpio/lib/argp-parse.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/* Hierarchial argument parsing, layered over getopt
- Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <alloca.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-#include <getopt.h>
-#include <getopt_int.h>
-
-#ifdef _LIBC
-# include <libintl.h>
-# undef dgettext
-# define dgettext(domain, msgid) \
- INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
-#else
-# include "gettext.h"
-#endif
-#define N_(msgid) msgid
-
-#include "argp.h"
-#include "argp-namefrob.h"
-
-#define alignof(type) offsetof (struct { char c; type x; }, x)
-#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
-
-/* Getopt return values. */
-#define KEY_END (-1) /* The end of the options. */
-#define KEY_ARG 1 /* A non-option argument. */
-#define KEY_ERR '?' /* An error parsing the options. */
-
-/* The meta-argument used to prevent any further arguments being interpreted
- as options. */
-#define QUOTE "--"
-
-/* The number of bits we steal in a long-option value for our own use. */
-#define GROUP_BITS CHAR_BIT
-
-/* The number of bits available for the user value. */
-#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
-#define USER_MASK ((1 << USER_BITS) - 1)
-
-/* EZ alias for ARGP_ERR_UNKNOWN. */
-#define EBADKEY ARGP_ERR_UNKNOWN
-
-/* Default options. */
-
-/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
- for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
- you can force the program to continue by attaching a debugger and setting
- it to 0 yourself. */
-static volatile int _argp_hang;
-
-#define OPT_PROGNAME -2
-#define OPT_USAGE -3
-#define OPT_HANG -4
-
-static const struct argp_option argp_default_options[] =
-{
- {"help", '?', 0, 0, N_("give this help list"), -1},
- {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0},
- {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0},
- {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
- N_("hang for SECS seconds (default 3600)"), 0},
- {NULL, 0, 0, 0, NULL, 0}
-};
-
-static error_t
-argp_default_parser (int key, char *arg, struct argp_state *state)
-{
- switch (key)
- {
- case '?':
- __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
- break;
- case OPT_USAGE:
- __argp_state_help (state, state->out_stream,
- ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
- break;
-
- case OPT_PROGNAME: /* Set the program name. */
-#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
- program_invocation_name = arg;
-#endif
- /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
- __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
- to be that, so we have to be a bit careful here.] */
-
- /* Update what we use for messages. */
- state->name = __argp_base_name (arg);
-
-#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
- program_invocation_short_name = state->name;
-#endif
-
- if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
- == ARGP_PARSE_ARGV0)
- /* Update what getopt uses too. */
- state->argv[0] = arg;
-
- break;
-
- case OPT_HANG:
- _argp_hang = atoi (arg ? arg : "3600");
- while (_argp_hang-- > 0)
- __sleep (1);
- break;
-
- default:
- return EBADKEY;
- }
- return 0;
-}
-
-static const struct argp argp_default_argp =
- {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
-
-
-static const struct argp_option argp_version_options[] =
-{
- {"version", 'V', 0, 0, N_("print program version"), -1},
- {NULL, 0, 0, 0, NULL, 0}
-};
-
-static error_t
-argp_version_parser (int key, char *arg, struct argp_state *state)
-{
- switch (key)
- {
- case 'V':
- if (argp_program_version_hook)
- (*argp_program_version_hook) (state->out_stream, state);
- else if (argp_program_version)
- fprintf (state->out_stream, "%s\n", argp_program_version);
- else
- __argp_error (state, dgettext (state->root_argp->argp_domain,
- "(PROGRAM ERROR) No version known!?"));
- if (! (state->flags & ARGP_NO_EXIT))
- exit (0);
- break;
- default:
- return EBADKEY;
- }
- return 0;
-}
-
-static const struct argp argp_version_argp =
- {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
-
-/* Returns the offset into the getopt long options array LONG_OPTIONS of a
- long option with called NAME, or -1 if none is found. Passing NULL as
- NAME will return the number of options. */
-static int
-find_long_option (struct option *long_options, const char *name)
-{
- struct option *l = long_options;
- while (l->name != NULL)
- if (name != NULL && strcmp (l->name, name) == 0)
- return l - long_options;
- else
- l++;
- if (name == NULL)
- return l - long_options;
- else
- return -1;
-}
-
-
-/* The state of a `group' during parsing. Each group corresponds to a
- particular argp structure from the tree of such descending from the top
- level argp passed to argp_parse. */
-struct group
-{
- /* This group's parsing function. */
- argp_parser_t parser;
-
- /* Which argp this group is from. */
- const struct argp *argp;
-
- /* Points to the point in SHORT_OPTS corresponding to the end of the short
- options for this group. We use it to determine from which group a
- particular short options is from. */
- char *short_end;
-
- /* The number of non-option args sucessfully handled by this parser. */
- unsigned args_processed;
-
- /* This group's parser's parent's group. */
- struct group *parent;
- unsigned parent_index; /* And the our position in the parent. */
-
- /* These fields are swapped into and out of the state structure when
- calling this group's parser. */
- void *input, **child_inputs;
- void *hook;
-};
-
-/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
- from STATE before calling, and back into state afterwards. If GROUP has
- no parser, EBADKEY is returned. */
-static error_t
-group_parse (struct group *group, struct argp_state *state, int key, char *arg)
-{
- if (group->parser)
- {
- error_t err;
- state->hook = group->hook;
- state->input = group->input;
- state->child_inputs = group->child_inputs;
- state->arg_num = group->args_processed;
- err = (*group->parser)(key, arg, state);
- group->hook = state->hook;
- return err;
- }
- else
- return EBADKEY;
-}
-
-struct parser
-{
- const struct argp *argp;
-
- /* SHORT_OPTS is the getopt short options string for the union of all the
- groups of options. */
- char *short_opts;
- /* LONG_OPTS is the array of getop long option structures for the union of
- all the groups of options. */
- struct option *long_opts;
- /* OPT_DATA is the getopt data used for the re-entrant getopt. */
- struct _getopt_data opt_data;
-
- /* States of the various parsing groups. */
- struct group *groups;
- /* The end of the GROUPS array. */
- struct group *egroup;
- /* An vector containing storage for the CHILD_INPUTS field in all groups. */
- void **child_inputs;
-
- /* True if we think using getopt is still useful; if false, then
- remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is
- cleared whenever getopt returns KEY_END, but may be set again if the user
- moves the next argument pointer backwards. */
- int try_getopt;
-
- /* State block supplied to parsing routines. */
- struct argp_state state;
-
- /* Memory used by this parser. */
- void *storage;
-};
-
-/* The next usable entries in the various parser tables being filled in by
- convert_options. */
-struct parser_convert_state
-{
- struct parser *parser;
- char *short_end;
- struct option *long_end;
- void **child_inputs_end;
-};
-
-/* Converts all options in ARGP (which is put in GROUP) and ancestors
- into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
- CVT->LONG_END are the points at which new options are added. Returns the
- next unused group entry. CVT holds state used during the conversion. */
-static struct group *
-convert_options (const struct argp *argp,
- struct group *parent, unsigned parent_index,
- struct group *group, struct parser_convert_state *cvt)
-{
- /* REAL is the most recent non-alias value of OPT. */
- const struct argp_option *real = argp->options;
- const struct argp_child *children = argp->children;
-
- if (real || argp->parser)
- {
- const struct argp_option *opt;
-
- if (real)
- for (opt = real; !__option_is_end (opt); opt++)
- {
- if (! (opt->flags & OPTION_ALIAS))
- /* OPT isn't an alias, so we can use values from it. */
- real = opt;
-
- if (! (real->flags & OPTION_DOC))
- /* A real option (not just documentation). */
- {
- if (__option_is_short (opt))
- /* OPT can be used as a short option. */
- {
- *cvt->short_end++ = opt->key;
- if (real->arg)
- {
- *cvt->short_end++ = ':';
- if (real->flags & OPTION_ARG_OPTIONAL)
- *cvt->short_end++ = ':';
- }
- *cvt->short_end = '\0'; /* keep 0 terminated */
- }
-
- if (opt->name
- && find_long_option (cvt->parser->long_opts, opt->name) < 0)
- /* OPT can be used as a long option. */
- {
- cvt->long_end->name = opt->name;
- cvt->long_end->has_arg =
- (real->arg
- ? (real->flags & OPTION_ARG_OPTIONAL
- ? optional_argument
- : required_argument)
- : no_argument);
- cvt->long_end->flag = 0;
- /* we add a disambiguating code to all the user's
- values (which is removed before we actually call
- the function to parse the value); this means that
- the user loses use of the high 8 bits in all his
- values (the sign of the lower bits is preserved
- however)... */
- cvt->long_end->val =
- ((opt->key | real->key) & USER_MASK)
- + (((group - cvt->parser->groups) + 1) << USER_BITS);
-
- /* Keep the LONG_OPTS list terminated. */
- (++cvt->long_end)->name = NULL;
- }
- }
- }
-
- group->parser = argp->parser;
- group->argp = argp;
- group->short_end = cvt->short_end;
- group->args_processed = 0;
- group->parent = parent;
- group->parent_index = parent_index;
- group->input = 0;
- group->hook = 0;
- group->child_inputs = 0;
-
- if (children)
- /* Assign GROUP's CHILD_INPUTS field some space from
- CVT->child_inputs_end.*/
- {
- unsigned num_children = 0;
- while (children[num_children].argp)
- num_children++;
- group->child_inputs = cvt->child_inputs_end;
- cvt->child_inputs_end += num_children;
- }
-
- parent = group++;
- }
- else
- parent = 0;
-
- if (children)
- {
- unsigned index = 0;
- while (children->argp)
- group =
- convert_options (children++->argp, parent, index++, group, cvt);
- }
-
- return group;
-}
-
-/* Find the merged set of getopt options, with keys appropiately prefixed. */
-static void
-parser_convert (struct parser *parser, const struct argp *argp, int flags)
-{
- struct parser_convert_state cvt;
-
- cvt.parser = parser;
- cvt.short_end = parser->short_opts;
- cvt.long_end = parser->long_opts;
- cvt.child_inputs_end = parser->child_inputs;
-
- if (flags & ARGP_IN_ORDER)
- *cvt.short_end++ = '-';
- else if (flags & ARGP_NO_ARGS)
- *cvt.short_end++ = '+';
- *cvt.short_end = '\0';
-
- cvt.long_end->name = NULL;
-
- parser->argp = argp;
-
- if (argp)
- parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
- else
- parser->egroup = parser->groups; /* No parsers at all! */
-}
-
-/* Lengths of various parser fields which we will allocated. */
-struct parser_sizes
-{
- size_t short_len; /* Getopt short options string. */
- size_t long_len; /* Getopt long options vector. */
- size_t num_groups; /* Group structures we allocate. */
- size_t num_child_inputs; /* Child input slots. */
-};
-
-/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
- argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
- the maximum lengths of the resulting merged getopt short options string and
- long-options array, respectively. */
-static void
-calc_sizes (const struct argp *argp, struct parser_sizes *szs)
-{
- const struct argp_child *child = argp->children;
- const struct argp_option *opt = argp->options;
-
- if (opt || argp->parser)
- {
- szs->num_groups++;
- if (opt)
- {
- int num_opts = 0;
- while (!__option_is_end (opt++))
- num_opts++;
- szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
- szs->long_len += num_opts;
- }
- }
-
- if (child)
- while (child->argp)
- {
- calc_sizes ((child++)->argp, szs);
- szs->num_child_inputs++;
- }
-}
-
-/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */
-static error_t
-parser_init (struct parser *parser, const struct argp *argp,
- int argc, char **argv, int flags, void *input)
-{
- error_t err = 0;
- struct group *group;
- struct parser_sizes szs;
- struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
- char *storage;
- size_t glen, gsum;
- size_t clen, csum;
- size_t llen, lsum;
- size_t slen, ssum;
-
- szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
- szs.long_len = 0;
- szs.num_groups = 0;
- szs.num_child_inputs = 0;
-
- if (argp)
- calc_sizes (argp, &szs);
-
- /* Lengths of the various bits of storage used by PARSER. */
- glen = (szs.num_groups + 1) * sizeof (struct group);
- clen = szs.num_child_inputs * sizeof (void *);
- llen = (szs.long_len + 1) * sizeof (struct option);
- slen = szs.short_len + 1;
-
- /* Sums of previous lengths, properly aligned. There's no need to
- align gsum, since struct group is aligned at least as strictly as
- void * (since it contains a void * member). And there's no need
- to align lsum, since struct option is aligned at least as
- strictly as char. */
- gsum = glen;
- csum = alignto (gsum + clen, alignof (struct option));
- lsum = csum + llen;
- ssum = lsum + slen;
-
- parser->storage = malloc (ssum);
- if (! parser->storage)
- return ENOMEM;
-
- storage = parser->storage;
- parser->groups = parser->storage;
- parser->child_inputs = (void **) (storage + gsum);
- parser->long_opts = (struct option *) (storage + csum);
- parser->short_opts = storage + lsum;
- parser->opt_data = opt_data;
-
- memset (parser->child_inputs, 0, clen);
- parser_convert (parser, argp, flags);
-
- memset (&parser->state, 0, sizeof (struct argp_state));
- parser->state.root_argp = parser->argp;
- parser->state.argc = argc;
- parser->state.argv = argv;
- parser->state.flags = flags;
- parser->state.err_stream = stderr;
- parser->state.out_stream = stdout;
- parser->state.next = 0; /* Tell getopt to initialize. */
- parser->state.pstate = parser;
-
- parser->try_getopt = 1;
-
- /* Call each parser for the first time, giving it a chance to propagate
- values to child parsers. */
- if (parser->groups < parser->egroup)
- parser->groups->input = input;
- for (group = parser->groups;
- group < parser->egroup && (!err || err == EBADKEY);
- group++)
- {
- if (group->parent)
- /* If a child parser, get the initial input value from the parent. */
- group->input = group->parent->child_inputs[group->parent_index];
-
- if (!group->parser
- && group->argp->children && group->argp->children->argp)
- /* For the special case where no parsing function is supplied for an
- argp, propagate its input to its first child, if any (this just
- makes very simple wrapper argps more convenient). */
- group->child_inputs[0] = group->input;
-
- err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
- }
- if (err == EBADKEY)
- err = 0; /* Some parser didn't understand. */
-
- if (err)
- return err;
-
- if (parser->state.flags & ARGP_NO_ERRS)
- {
- parser->opt_data.opterr = 0;
- if (parser->state.flags & ARGP_PARSE_ARGV0)
- /* getopt always skips ARGV[0], so we have to fake it out. As long
- as OPTERR is 0, then it shouldn't actually try to access it. */
- parser->state.argv--, parser->state.argc++;
- }
- else
- parser->opt_data.opterr = 1; /* Print error messages. */
-
- if (parser->state.argv == argv && argv[0])
- /* There's an argv[0]; use it for messages. */
- parser->state.name = __argp_base_name (argv[0]);
- else
- parser->state.name = __argp_short_program_name ();
-
- return 0;
-}
-
-/* Free any storage consumed by PARSER (but not PARSER itself). */
-static error_t
-parser_finalize (struct parser *parser,
- error_t err, int arg_ebadkey, int *end_index)
-{
- struct group *group;
-
- if (err == EBADKEY && arg_ebadkey)
- /* Suppress errors generated by unparsed arguments. */
- err = 0;
-
- if (! err)
- {
- if (parser->state.next == parser->state.argc)
- /* We successfully parsed all arguments! Call all the parsers again,
- just a few more times... */
- {
- for (group = parser->groups;
- group < parser->egroup && (!err || err==EBADKEY);
- group++)
- if (group->args_processed == 0)
- err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
- for (group = parser->egroup - 1;
- group >= parser->groups && (!err || err==EBADKEY);
- group--)
- err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
-
- if (err == EBADKEY)
- err = 0; /* Some parser didn't understand. */
-
- /* Tell the user that all arguments are parsed. */
- if (end_index)
- *end_index = parser->state.next;
- }
- else if (end_index)
- /* Return any remaining arguments to the user. */
- *end_index = parser->state.next;
- else
- /* No way to return the remaining arguments, they must be bogus. */
- {
- if (!(parser->state.flags & ARGP_NO_ERRS)
- && parser->state.err_stream)
- fprintf (parser->state.err_stream,
- dgettext (parser->argp->argp_domain,
- "%s: Too many arguments\n"),
- parser->state.name);
- err = EBADKEY;
- }
- }
-
- /* Okay, we're all done, with either an error or success; call the parsers
- to indicate which one. */
-
- if (err)
- {
- /* Maybe print an error message. */
- if (err == EBADKEY)
- /* An appropriate message describing what the error was should have
- been printed earlier. */
- __argp_state_help (&parser->state, parser->state.err_stream,
- ARGP_HELP_STD_ERR);
-
- /* Since we didn't exit, give each parser an error indication. */
- for (group = parser->groups; group < parser->egroup; group++)
- group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
- }
- else
- /* Notify parsers of success, and propagate back values from parsers. */
- {
- /* We pass over the groups in reverse order so that child groups are
- given a chance to do there processing before passing back a value to
- the parent. */
- for (group = parser->egroup - 1
- ; group >= parser->groups && (!err || err == EBADKEY)
- ; group--)
- err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
- if (err == EBADKEY)
- err = 0; /* Some parser didn't understand. */
- }
-
- /* Call parsers once more, to do any final cleanup. Errors are ignored. */
- for (group = parser->egroup - 1; group >= parser->groups; group--)
- group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
-
- if (err == EBADKEY)
- err = EINVAL;
-
- free (parser->storage);
-
- return err;
-}
-
-/* Call the user parsers to parse the non-option argument VAL, at the current
- position, returning any error. The state NEXT pointer is assumed to have
- been adjusted (by getopt) to point after this argument; this function will
- adjust it correctly to reflect however many args actually end up being
- consumed. */
-static error_t
-parser_parse_arg (struct parser *parser, char *val)
-{
- /* Save the starting value of NEXT, first adjusting it so that the arg
- we're parsing is again the front of the arg vector. */
- int index = --parser->state.next;
- error_t err = EBADKEY;
- struct group *group;
- int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */
-
- /* Try to parse the argument in each parser. */
- for (group = parser->groups
- ; group < parser->egroup && err == EBADKEY
- ; group++)
- {
- parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */
- key = ARGP_KEY_ARG;
- err = group_parse (group, &parser->state, key, val);
-
- if (err == EBADKEY)
- /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
- {
- parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */
- key = ARGP_KEY_ARGS;
- err = group_parse (group, &parser->state, key, 0);
- }
- }
-
- if (! err)
- {
- if (key == ARGP_KEY_ARGS)
- /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
- changed by the user, *all* arguments should be considered
- consumed. */
- parser->state.next = parser->state.argc;
-
- if (parser->state.next > index)
- /* Remember that we successfully processed a non-option
- argument -- but only if the user hasn't gotten tricky and set
- the clock back. */
- (--group)->args_processed += (parser->state.next - index);
- else
- /* The user wants to reparse some args, give getopt another try. */
- parser->try_getopt = 1;
- }
-
- return err;
-}
-
-/* Call the user parsers to parse the option OPT, with argument VAL, at the
- current position, returning any error. */
-static error_t
-parser_parse_opt (struct parser *parser, int opt, char *val)
-{
- /* The group key encoded in the high bits; 0 for short opts or
- group_number + 1 for long opts. */
- int group_key = opt >> USER_BITS;
- error_t err = EBADKEY;
-
- if (group_key == 0)
- /* A short option. By comparing OPT's position in SHORT_OPTS to the
- various starting positions in each group's SHORT_END field, we can
- determine which group OPT came from. */
- {
- struct group *group;
- char *short_index = strchr (parser->short_opts, opt);
-
- if (short_index)
- for (group = parser->groups; group < parser->egroup; group++)
- if (group->short_end > short_index)
- {
- err = group_parse (group, &parser->state, opt,
- parser->opt_data.optarg);
- break;
- }
- }
- else
- /* A long option. We use shifts instead of masking for extracting
- the user value in order to preserve the sign. */
- err =
- group_parse (&parser->groups[group_key - 1], &parser->state,
- (opt << GROUP_BITS) >> GROUP_BITS,
- parser->opt_data.optarg);
-
- if (err == EBADKEY)
- /* At least currently, an option not recognized is an error in the
- parser, because we pre-compute which parser is supposed to deal
- with each option. */
- {
- static const char bad_key_err[] =
- N_("(PROGRAM ERROR) Option should have been recognized!?");
- if (group_key == 0)
- __argp_error (&parser->state, "-%c: %s", opt,
- dgettext (parser->argp->argp_domain, bad_key_err));
- else
- {
- struct option *long_opt = parser->long_opts;
- while (long_opt->val != opt && long_opt->name)
- long_opt++;
- __argp_error (&parser->state, "--%s: %s",
- long_opt->name ? long_opt->name : "???",
- dgettext (parser->argp->argp_domain, bad_key_err));
- }
- }
-
- return err;
-}
-
-/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
- Any error from the parsers is returned, and *ARGP_EBADKEY indicates
- whether a value of EBADKEY is due to an unrecognized argument (which is
- generally not fatal). */
-static error_t
-parser_parse_next (struct parser *parser, int *arg_ebadkey)
-{
- int opt;
- error_t err = 0;
-
- if (parser->state.quoted && parser->state.next < parser->state.quoted)
- /* The next argument pointer has been moved to before the quoted
- region, so pretend we never saw the quoting `--', and give getopt
- another chance. If the user hasn't removed it, getopt will just
- process it again. */
- parser->state.quoted = 0;
-
- if (parser->try_getopt && !parser->state.quoted)
- /* Give getopt a chance to parse this. */
- {
- /* Put it back in OPTIND for getopt. */
- parser->opt_data.optind = parser->state.next;
- /* Distinguish KEY_ERR from a real option. */
- parser->opt_data.optopt = KEY_END;
- if (parser->state.flags & ARGP_LONG_ONLY)
- opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
- parser->short_opts, parser->long_opts, 0,
- &parser->opt_data);
- else
- opt = _getopt_long_r (parser->state.argc, parser->state.argv,
- parser->short_opts, parser->long_opts, 0,
- &parser->opt_data);
- /* And see what getopt did. */
- parser->state.next = parser->opt_data.optind;
-
- if (opt == KEY_END)
- /* Getopt says there are no more options, so stop using
- getopt; we'll continue if necessary on our own. */
- {
- parser->try_getopt = 0;
- if (parser->state.next > 1
- && strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
- == 0)
- /* Not only is this the end of the options, but it's a
- `quoted' region, which may have args that *look* like
- options, so we definitely shouldn't try to use getopt past
- here, whatever happens. */
- parser->state.quoted = parser->state.next;
- }
- else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
- /* KEY_ERR can have the same value as a valid user short
- option, but in the case of a real error, getopt sets OPTOPT
- to the offending character, which can never be KEY_END. */
- {
- *arg_ebadkey = 0;
- return EBADKEY;
- }
- }
- else
- opt = KEY_END;
-
- if (opt == KEY_END)
- {
- /* We're past what getopt considers the options. */
- if (parser->state.next >= parser->state.argc
- || (parser->state.flags & ARGP_NO_ARGS))
- /* Indicate that we're done. */
- {
- *arg_ebadkey = 1;
- return EBADKEY;
- }
- else
- /* A non-option arg; simulate what getopt might have done. */
- {
- opt = KEY_ARG;
- parser->opt_data.optarg = parser->state.argv[parser->state.next++];
- }
- }
-
- if (opt == KEY_ARG)
- /* A non-option argument; try each parser in turn. */
- err = parser_parse_arg (parser, parser->opt_data.optarg);
- else
- err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
-
- if (err == EBADKEY)
- *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
-
- return err;
-}
-
-/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
- FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the
- index in ARGV of the first unparsed option is returned in it. If an
- unknown option is present, EINVAL is returned; if some parser routine
- returned a non-zero value, it is returned; otherwise 0 is returned. */
-error_t
-__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
- int *end_index, void *input)
-{
- error_t err;
- struct parser parser;
-
- /* If true, then err == EBADKEY is a result of a non-option argument failing
- to be parsed (which in some cases isn't actually an error). */
- int arg_ebadkey = 0;
-
-#ifndef _LIBC
- if (!(flags & ARGP_PARSE_ARGV0))
- {
-#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME
- if (!program_invocation_name)
- program_invocation_name = argv[0];
-#endif
-#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
- if (!program_invocation_short_name)
- program_invocation_short_name = __argp_base_name (argv[0]);
-#endif
- }
-#endif
-
- if (! (flags & ARGP_NO_HELP))
- /* Add our own options. */
- {
- struct argp_child *child = alloca (4 * sizeof (struct argp_child));
- struct argp *top_argp = alloca (sizeof (struct argp));
-
- /* TOP_ARGP has no options, it just serves to group the user & default
- argps. */
- memset (top_argp, 0, sizeof (*top_argp));
- top_argp->children = child;
-
- memset (child, 0, 4 * sizeof (struct argp_child));
-
- if (argp)
- (child++)->argp = argp;
- (child++)->argp = &argp_default_argp;
- if (argp_program_version || argp_program_version_hook)
- (child++)->argp = &argp_version_argp;
- child->argp = 0;
-
- argp = top_argp;
- }
-
- /* Construct a parser for these arguments. */
- err = parser_init (&parser, argp, argc, argv, flags, input);
-
- if (! err)
- /* Parse! */
- {
- while (! err)
- err = parser_parse_next (&parser, &arg_ebadkey);
- err = parser_finalize (&parser, err, arg_ebadkey, end_index);
- }
-
- return err;
-}
-#ifdef weak_alias
-weak_alias (__argp_parse, argp_parse)
-#endif
-
-/* Return the input field for ARGP in the parser corresponding to STATE; used
- by the help routines. */
-void *
-__argp_input (const struct argp *argp, const struct argp_state *state)
-{
- if (state)
- {
- struct group *group;
- struct parser *parser = state->pstate;
-
- for (group = parser->groups; group < parser->egroup; group++)
- if (group->argp == argp)
- return group->input;
- }
-
- return 0;
-}
-#ifdef weak_alias
-weak_alias (__argp_input, _argp_input)
-#endif
diff --git a/contrib/cpio/lib/argp-pin.c b/contrib/cpio/lib/argp-pin.c
deleted file mode 100644
index 852c6d6..0000000
--- a/contrib/cpio/lib/argp-pin.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Full and short program names for argp module
- Copyright (C) 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
-char *program_invocation_short_name = 0;
-#endif
-#ifndef HAVE_PROGRAM_INVOCATION_NAME
-char *program_invocation_name = 0;
-#endif
-
diff --git a/contrib/cpio/lib/argp-pv.c b/contrib/cpio/lib/argp-pv.c
deleted file mode 100644
index a11298b..0000000
--- a/contrib/cpio/lib/argp-pv.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Default definition for ARGP_PROGRAM_VERSION.
- Copyright (C) 1996, 1997, 1999, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* If set by the user program to a non-zero value, then a default option
- --version is added (unless the ARGP_NO_HELP flag is used), which will
- print this string followed by a newline and exit (unless the
- ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
-const char *argp_program_version;
diff --git a/contrib/cpio/lib/argp-pvh.c b/contrib/cpio/lib/argp-pvh.c
deleted file mode 100644
index 6bf7c49..0000000
--- a/contrib/cpio/lib/argp-pvh.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
- Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "argp.h"
-
-/* If set by the user program to a non-zero value, then a default option
- --version is added (unless the ARGP_NO_HELP flag is used), which calls
- this function with a stream to print the version to and a pointer to the
- current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
- used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
-void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL;
diff --git a/contrib/cpio/lib/argp-xinl.c b/contrib/cpio/lib/argp-xinl.c
deleted file mode 100644
index a6afb1f..0000000
--- a/contrib/cpio/lib/argp-xinl.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Real definitions for extern inline functions in argp.h
- Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || defined HAVE_FEATURES_H
-# include <features.h>
-#endif
-
-#ifndef __USE_EXTERN_INLINES
-# define __USE_EXTERN_INLINES 1
-#endif
-#define ARGP_EI
-#undef __OPTIMIZE__
-#define __OPTIMIZE__ 1
-#include "argp.h"
-
-/* Add weak aliases. */
-#if _LIBC - 0 && defined (weak_alias)
-
-weak_alias (__argp_usage, argp_usage)
-weak_alias (__option_is_short, _option_is_short)
-weak_alias (__option_is_end, _option_is_end)
-
-#endif
diff --git a/contrib/cpio/lib/argp.h b/contrib/cpio/lib/argp.h
deleted file mode 100644
index b5aadcf..0000000
--- a/contrib/cpio/lib/argp.h
+++ /dev/null
@@ -1,624 +0,0 @@
-/* $FreeBSD$ */
-
-/* Hierarchial argument parsing, layered over getopt.
- Copyright (C) 1995-1999,2003-2007 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _ARGP_H
-#define _ARGP_H
-
-#include <stdio.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <limits.h>
-
-#define __need_error_t
-#include <errno.h>
-
-#ifndef __THROW
-# define __THROW
-#endif
-#ifndef __NTH
-# define __NTH(fct) fct __THROW
-#endif
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
-/* GCC 2.95 and later have "__restrict"; C99 compilers have
- "restrict", and "configure" may have defined "restrict".
- Other compilers use __restrict, __restrict__, and _Restrict, and
- 'configure' might #define 'restrict' to those words. */
-#ifndef __restrict
-# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
-# if 199901L <= __STDC_VERSION__
-# define __restrict restrict
-# else
-# define __restrict
-# endif
-# endif
-#endif
-
-#ifndef __error_t_defined
-typedef int error_t;
-# define __error_t_defined
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* A description of a particular option. A pointer to an array of
- these is passed in the OPTIONS field of an argp structure. Each option
- entry can correspond to one long option and/or one short option; more
- names for the same option can be added by following an entry in an option
- array with options having the OPTION_ALIAS flag set. */
-struct argp_option
-{
- /* The long option name. For more than one name for the same option, you
- can use following options with the OPTION_ALIAS flag set. */
- const char *name;
-
- /* What key is returned for this option. If > 0 and printable, then it's
- also accepted as a short option. */
- int key;
-
- /* If non-NULL, this is the name of the argument associated with this
- option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
- const char *arg;
-
- /* OPTION_ flags. */
- int flags;
-
- /* The doc string for this option. If both NAME and KEY are 0, This string
- will be printed outdented from the normal option column, making it
- useful as a group header (it will be the first thing printed in its
- group); in this usage, it's conventional to end the string with a `:'.
-
- Write the initial value as N_("TEXT") if you want xgettext to collect
- it into a POT file. */
- const char *doc;
-
- /* The group this option is in. In a long help message, options are sorted
- alphabetically within each group, and the groups presented in the order
- 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with
- if this field 0 will inherit the group number of the previous entry, or
- zero if it's the first one, unless its a group header (NAME and KEY both
- 0), in which case, the previous entry + 1 is the default. Automagic
- options such as --help are put into group -1. */
- int group;
-};
-
-/* The argument associated with this option is optional. */
-#define OPTION_ARG_OPTIONAL 0x1
-
-/* This option isn't displayed in any help messages. */
-#define OPTION_HIDDEN 0x2
-
-/* This option is an alias for the closest previous non-alias option. This
- means that it will be displayed in the same help entry, and will inherit
- fields other than NAME and KEY from the aliased option. */
-#define OPTION_ALIAS 0x4
-
-/* This option isn't actually an option (and so should be ignored by the
- actual option parser), but rather an arbitrary piece of documentation that
- should be displayed in much the same manner as the options. If this flag
- is set, then the option NAME field is displayed unmodified (e.g., no `--'
- prefix is added) at the left-margin (where a *short* option would normally
- be displayed), and the documentation string in the normal place. The NAME
- field will be translated using gettext, unless OPTION_NO_TRANS is set (see
- below). For purposes of sorting, any leading whitespace and punctuation is
- ignored, except that if the first non-whitespace character is not `-', this
- entry is displayed after all options (and OPTION_DOC entries with a leading
- `-') in the same group. */
-#define OPTION_DOC 0x8
-
-/* This option shouldn't be included in `long' usage messages (but is still
- included in help messages). This is mainly intended for options that are
- completely documented in an argp's ARGS_DOC field, in which case including
- the option in the generic usage list would be redundant. For instance,
- if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
- distinguish these two cases, -x should probably be marked
- OPTION_NO_USAGE. */
-#define OPTION_NO_USAGE 0x10
-
-/* Valid only in conjunction with OPTION_DOC. This option disables translation
- of option name. */
-#define OPTION_NO_TRANS 0x20
-
-
-struct argp; /* fwd declare this type */
-struct argp_state; /* " */
-struct argp_child; /* " */
-
-/* The type of a pointer to an argp parsing function. */
-typedef error_t (*argp_parser_t) (int key, char *arg,
- struct argp_state *state);
-
-/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such
- returns will simply be ignored. For user keys, this error will be turned
- into EINVAL (if the call to argp_parse is such that errors are propagated
- back to the user instead of exiting); returning EINVAL itself would result
- in an immediate stop to parsing in *all* cases. */
-#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */
-
-/* Special values for the KEY argument to an argument parsing function.
- ARGP_ERR_UNKNOWN should be returned if they aren't understood.
-
- The sequence of keys to a parsing function is either (where each
- uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
-
- INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all
- or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed
- or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized
-
- The third case is where every parser returned ARGP_KEY_UNKNOWN for an
- argument, in which case parsing stops at that argument (returning the
- unparsed arguments to the caller of argp_parse if requested, or stopping
- with an error message if not).
-
- If an error occurs (either detected by argp, or because the parsing
- function returned an error value), then the parser is called with
- ARGP_KEY_ERROR, and no further calls are made. */
-
-/* This is not an option at all, but rather a command line argument. If a
- parser receiving this key returns success, the fact is recorded, and the
- ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the
- argument, a parser function decrements the NEXT field of the state it's
- passed, the option won't be considered processed; this is to allow you to
- actually modify the argument (perhaps into an option), and have it
- processed again. */
-#define ARGP_KEY_ARG 0
-/* There are remaining arguments not parsed by any parser, which may be found
- starting at (STATE->argv + STATE->next). If success is returned, but
- STATE->next left untouched, it's assumed that all arguments were consume,
- otherwise, the parser should adjust STATE->next to reflect any arguments
- consumed. */
-#define ARGP_KEY_ARGS 0x1000006
-/* There are no more command line arguments at all. */
-#define ARGP_KEY_END 0x1000001
-/* Because it's common to want to do some special processing if there aren't
- any non-option args, user parsers are called with this key if they didn't
- successfully process any non-option arguments. Called just before
- ARGP_KEY_END (where more general validity checks on previously parsed
- arguments can take place). */
-#define ARGP_KEY_NO_ARGS 0x1000002
-/* Passed in before any parsing is done. Afterwards, the values of each
- element of the CHILD_INPUT field, if any, in the state structure is
- copied to each child's state to be the initial value of the INPUT field. */
-#define ARGP_KEY_INIT 0x1000003
-/* Use after all other keys, including SUCCESS & END. */
-#define ARGP_KEY_FINI 0x1000007
-/* Passed in when parsing has successfully been completed (even if there are
- still arguments remaining). */
-#define ARGP_KEY_SUCCESS 0x1000004
-/* Passed in if an error occurs. */
-#define ARGP_KEY_ERROR 0x1000005
-
-/* An argp structure contains a set of options declarations, a function to
- deal with parsing one, documentation string, a possible vector of child
- argp's, and perhaps a function to filter help output. When actually
- parsing options, getopt is called with the union of all the argp
- structures chained together through their CHILD pointers, with conflicts
- being resolved in favor of the first occurrence in the chain. */
-struct argp
-{
- /* An array of argp_option structures, terminated by an entry with both
- NAME and KEY having a value of 0. */
- const struct argp_option *options;
-
- /* What to do with an option from this structure. KEY is the key
- associated with the option, and ARG is any associated argument (NULL if
- none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be
- returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
- parsing is stopped immediately, and that value is returned from
- argp_parse(). For special (non-user-supplied) values of KEY, see the
- ARGP_KEY_ definitions below. */
- argp_parser_t parser;
-
- /* A string describing what other arguments are wanted by this program. It
- is only used by argp_usage to print the `Usage:' message. If it
- contains newlines, the strings separated by them are considered
- alternative usage patterns, and printed on separate lines (lines after
- the first are prefix by ` or: ' instead of `Usage:'). */
- const char *args_doc;
-
- /* If non-NULL, a string containing extra text to be printed before and
- after the options in a long help message (separated by a vertical tab
- `\v' character).
- Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if
- you want xgettext to collect the two pieces of text into a POT file. */
- const char *doc;
-
- /* A vector of argp_children structures, terminated by a member with a 0
- argp field, pointing to child argps should be parsed with this one. Any
- conflicts are resolved in favor of this argp, or early argps in the
- CHILDREN list. This field is useful if you use libraries that supply
- their own argp structure, which you want to use in conjunction with your
- own. */
- const struct argp_child *children;
-
- /* If non-zero, this should be a function to filter the output of help
- messages. KEY is either a key from an option, in which case TEXT is
- that option's help text, or a special key from the ARGP_KEY_HELP_
- defines, below, describing which other help text TEXT is. The function
- should return either TEXT, if it should be used as-is, a replacement
- string, which should be malloced, and will be freed by argp, or NULL,
- meaning `print nothing'. The value for TEXT is *after* any translation
- has been done, so if any of the replacement text also needs translation,
- that should be done by the filter function. INPUT is either the input
- supplied to argp_parse, or NULL, if argp_help was called directly. */
- char *(*help_filter) (int __key, const char *__text, void *__input);
-
- /* If non-zero the strings used in the argp library are translated using
- the domain described by this string. Otherwise the currently installed
- default domain is used. */
- const char *argp_domain;
-};
-
-/* Possible KEY arguments to a help filter function. */
-#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */
-#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */
-#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */
-#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation;
- TEXT is NULL for this key. */
-/* Explanatory note emitted when duplicate option arguments have been
- suppressed. */
-#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
-#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */
-
-/* When an argp has a non-zero CHILDREN field, it should point to a vector of
- argp_child structures, each of which describes a subsidiary argp. */
-struct argp_child
-{
- /* The child parser. */
- const struct argp *argp;
-
- /* Flags for this child. */
- int flags;
-
- /* If non-zero, an optional header to be printed in help output before the
- child options. As a side-effect, a non-zero value forces the child
- options to be grouped together; to achieve this effect without actually
- printing a header string, use a value of "". */
- const char *header;
-
- /* Where to group the child options relative to the other (`consolidated')
- options in the parent argp; the values are the same as the GROUP field
- in argp_option structs, but all child-groupings follow parent options at
- a particular group level. If both this field and HEADER are zero, then
- they aren't grouped at all, but rather merged with the parent options
- (merging the child's grouping levels with the parents). */
- int group;
-};
-
-/* Parsing state. This is provided to parsing functions called by argp,
- which may examine and, as noted, modify fields. */
-struct argp_state
-{
- /* The top level ARGP being parsed. */
- const struct argp *root_argp;
-
- /* The argument vector being parsed. May be modified. */
- int argc;
- char **argv;
-
- /* The index in ARGV of the next arg that to be parsed. May be modified. */
- int next;
-
- /* The flags supplied to argp_parse. May be modified. */
- unsigned flags;
-
- /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
- number of the current arg, starting at zero, and incremented after each
- such call returns. At all other times, this is the number of such
- arguments that have been processed. */
- unsigned arg_num;
-
- /* If non-zero, the index in ARGV of the first argument following a special
- `--' argument (which prevents anything following being interpreted as an
- option). Only set once argument parsing has proceeded past this point. */
- int quoted;
-
- /* An arbitrary pointer passed in from the user. */
- void *input;
- /* Values to pass to child parsers. This vector will be the same length as
- the number of children for the current parser. */
- void **child_inputs;
-
- /* For the parser's use. Initialized to 0. */
- void *hook;
-
- /* The name used when printing messages. This is initialized to ARGV[0],
- or PROGRAM_INVOCATION_NAME if that is unavailable. */
- char *name;
-
- /* Streams used when argp prints something. */
- FILE *err_stream; /* For errors; initialized to stderr. */
- FILE *out_stream; /* For information; initialized to stdout. */
-
- void *pstate; /* Private, for use by argp. */
-};
-
-/* Flags for argp_parse (note that the defaults are those that are
- convenient for program command line parsing): */
-
-/* Don't ignore the first element of ARGV. Normally (and always unless
- ARGP_NO_ERRS is set) the first element of the argument vector is
- skipped for option parsing purposes, as it corresponds to the program name
- in a command line. */
-#define ARGP_PARSE_ARGV0 0x01
-
-/* Don't print error messages for unknown options to stderr; unless this flag
- is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
- name in the error messages. This flag implies ARGP_NO_EXIT (on the
- assumption that silent exiting upon errors is bad behaviour). */
-#define ARGP_NO_ERRS 0x02
-
-/* Don't parse any non-option args. Normally non-option args are parsed by
- calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
- as the value. Since it's impossible to know which parse function wants to
- handle it, each one is called in turn, until one returns 0 or an error
- other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
- argp_parse returns prematurely (but with a return value of 0). If all
- args have been parsed without error, all parsing functions are called one
- last time with a key of ARGP_KEY_END. This flag needn't normally be set,
- as the normal behavior is to stop parsing as soon as some argument can't
- be handled. */
-#define ARGP_NO_ARGS 0x04
-
-/* Parse options and arguments in the same order they occur on the command
- line -- normally they're rearranged so that all options come first. */
-#define ARGP_IN_ORDER 0x08
-
-/* Don't provide the standard long option --help, which causes usage and
- option help information to be output to stdout, and exit (0) called. */
-#define ARGP_NO_HELP 0x10
-
-/* Don't exit on errors (they may still result in error messages). */
-#define ARGP_NO_EXIT 0x20
-
-/* Use the gnu getopt `long-only' rules for parsing arguments. */
-#define ARGP_LONG_ONLY 0x40
-
-/* Turns off any message-printing/exiting options. */
-#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
-
-/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
- FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the
- index in ARGV of the first unparsed option is returned in it. If an
- unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
- routine returned a non-zero value, it is returned; otherwise 0 is
- returned. This function may also call exit unless the ARGP_NO_HELP flag
- is set. INPUT is a pointer to a value to be passed in to the parser. */
-extern error_t argp_parse (const struct argp *__restrict __argp,
- int /*argc*/, char **__restrict /*argv*/,
- unsigned __flags, int *__restrict __arg_index,
- void *__restrict __input);
-extern error_t __argp_parse (const struct argp *__restrict __argp,
- int /*argc*/, char **__restrict /*argv*/,
- unsigned __flags, int *__restrict __arg_index,
- void *__restrict __input);
-
-/* Global variables. */
-
-/* GNULIB makes sure both program_invocation_name and
- program_invocation_short_name are available */
-#ifdef GNULIB_PROGRAM_INVOCATION_NAME
-extern char *program_invocation_name;
-# undef HAVE_DECL_PROGRAM_INVOCATION_NAME
-# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1
-#endif
-
-#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME
-extern char *program_invocation_short_name;
-# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1
-#endif
-
-/* If defined or set by the user program to a non-zero value, then a default
- option --version is added (unless the ARGP_NO_HELP flag is used), which
- will print this string followed by a newline and exit (unless the
- ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
-extern const char *argp_program_version;
-
-/* If defined or set by the user program to a non-zero value, then a default
- option --version is added (unless the ARGP_NO_HELP flag is used), which
- calls this function with a stream to print the version to and a pointer to
- the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
- used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
-extern void (*argp_program_version_hook) (FILE *__restrict __stream,
- struct argp_state *__restrict
- __state);
-
-/* If defined or set by the user program, it should point to string that is
- the bug-reporting address for the program. It will be printed by
- argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
- standard help messages), embedded in a sentence that says something like
- `Report bugs to ADDR.'. */
-extern const char *argp_program_bug_address;
-
-/* The exit status that argp will use when exiting due to a parsing error.
- If not defined or set by the user program, this defaults to EX_USAGE from
- <sysexits.h>. */
-extern error_t argp_err_exit_status;
-
-/* Flags for argp_help. */
-#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */
-#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */
-#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */
-#define ARGP_HELP_LONG 0x08 /* a long help message. */
-#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */
-#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */
-#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
-#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */
-#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to
- reflect ARGP_LONG_ONLY mode. */
-
-/* These ARGP_HELP flags are only understood by argp_state_help. */
-#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */
-#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */
-
-/* The standard thing to do after a program command line parsing error, if an
- error message has already been printed. */
-#define ARGP_HELP_STD_ERR \
- (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
-/* The standard thing to do after a program command line parsing error, if no
- more specific error message has been printed. */
-#define ARGP_HELP_STD_USAGE \
- (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
-/* The standard thing to do in response to a --help option. */
-#define ARGP_HELP_STD_HELP \
- (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
- | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
-
-/* Output a usage message for ARGP to STREAM. FLAGS are from the set
- ARGP_HELP_*. */
-extern void argp_help (const struct argp *__restrict __argp,
- FILE *__restrict __stream,
- unsigned __flags, char *__restrict __name);
-extern void __argp_help (const struct argp *__restrict __argp,
- FILE *__restrict __stream, unsigned __flags,
- char *__name);
-
-/* The following routines are intended to be called from within an argp
- parsing routine (thus taking an argp_state structure as the first
- argument). They may or may not print an error message and exit, depending
- on the flags in STATE -- in any case, the caller should be prepared for
- them *not* to exit, and should return an appropiate error after calling
- them. [argp_usage & argp_error should probably be called argp_state_...,
- but they're used often enough that they should be short] */
-
-/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
- from the set ARGP_HELP_*. */
-extern void argp_state_help (const struct argp_state *__restrict __state,
- FILE *__restrict __stream,
- unsigned int __flags);
-extern void __argp_state_help (const struct argp_state *__restrict __state,
- FILE *__restrict __stream,
- unsigned int __flags);
-
-/* Possibly output the standard usage message for ARGP to stderr and exit. */
-extern void argp_usage (const struct argp_state *__state);
-extern void __argp_usage (const struct argp_state *__state);
-
-/* If appropriate, print the printf string FMT and following args, preceded
- by the program name and `:', to stderr, and followed by a `Try ... --help'
- message, then exit (1). */
-extern void argp_error (const struct argp_state *__restrict __state,
- const char *__restrict __fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
-extern void __argp_error (const struct argp_state *__restrict __state,
- const char *__restrict __fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
-
-/* Similar to the standard gnu error-reporting function error(), but will
- respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
- to STATE->err_stream. This is useful for argument parsing code that is
- shared between program startup (when exiting is desired) and runtime
- option parsing (when typically an error code is returned instead). The
- difference between this function and argp_error is that the latter is for
- *parsing errors*, and the former is for other problems that occur during
- parsing but don't reflect a (syntactic) problem with the input. */
-extern void argp_failure (const struct argp_state *__restrict __state,
- int __status, int __errnum,
- const char *__restrict __fmt, ...)
- __attribute__ ((__format__ (__printf__, 4, 5)));
-extern void __argp_failure (const struct argp_state *__restrict __state,
- int __status, int __errnum,
- const char *__restrict __fmt, ...)
- __attribute__ ((__format__ (__printf__, 4, 5)));
-
-/* Returns true if the option OPT is a valid short option. */
-extern int _option_is_short (const struct argp_option *__opt) __THROW;
-extern int __option_is_short (const struct argp_option *__opt) __THROW;
-
-/* Returns true if the option OPT is in fact the last (unused) entry in an
- options array. */
-extern int _option_is_end (const struct argp_option *__opt) __THROW;
-extern int __option_is_end (const struct argp_option *__opt) __THROW;
-
-/* Return the input field for ARGP in the parser corresponding to STATE; used
- by the help routines. */
-extern void *_argp_input (const struct argp *__restrict __argp,
- const struct argp_state *__restrict __state)
- __THROW;
-extern void *__argp_input (const struct argp *__restrict __argp,
- const struct argp_state *__restrict __state)
- __THROW;
-
-#ifdef __USE_EXTERN_INLINES
-
-# if !_LIBC
-# define __argp_usage argp_usage
-# define __argp_state_help argp_state_help
-# define __option_is_short _option_is_short
-# define __option_is_end _option_is_end
-# endif
-
-# ifndef ARGP_EI
-# define ARGP_EI extern __inline__
-# endif
-
-ARGP_EI void
-__argp_usage (const struct argp_state *__state)
-{
- __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
-}
-
-ARGP_EI int
-__NTH (__option_is_short (const struct argp_option *__opt))
-{
- if (__opt->flags & OPTION_DOC)
- return 0;
- else
- {
- int __key = __opt->key;
- return __key > 0 && __key <= UCHAR_MAX && isprint (__key);
- }
-}
-
-ARGP_EI int
-__NTH (__option_is_end (const struct argp_option *__opt))
-{
- return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
-}
-
-# if !_LIBC
-# undef __argp_usage
-# undef __argp_state_help
-# undef __option_is_short
-# undef __option_is_end
-# endif
-#endif /* Use extern inlines. */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* argp.h */
diff --git a/contrib/cpio/lib/basename.c b/contrib/cpio/lib/basename.c
deleted file mode 100644
index fbe17ff..0000000
--- a/contrib/cpio/lib/basename.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* basename.c -- return the last element in a file name
-
- Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include "dirname.h"
-
-#include <string.h>
-#include "xalloc.h"
-#include "xstrndup.h"
-
-/* Return the address of the last file name component of NAME. If
- NAME has no relative file name components because it is a file
- system root, return the empty string. */
-
-char *
-last_component (char const *name)
-{
- char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
- char const *p;
- bool saw_slash = false;
-
- while (ISSLASH (*base))
- base++;
-
- for (p = base; *p; p++)
- {
- if (ISSLASH (*p))
- saw_slash = true;
- else if (saw_slash)
- {
- base = p;
- saw_slash = false;
- }
- }
-
- return (char *) base;
-}
-
-
-/* In general, we can't use the builtin `basename' function if available,
- since it has different meanings in different environments.
- In some environments the builtin `basename' modifies its argument.
-
- Return the last file name component of NAME, allocated with
- xmalloc. On systems with drive letters, a leading "./"
- distinguishes relative names that would otherwise look like a drive
- letter. Unlike POSIX basename(), NAME cannot be NULL,
- base_name("") returns "", and the first trailing slash is not
- stripped.
-
- If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
- lstat (base_name (NAME)); } will access the same file. Likewise,
- if the sequence { chdir (dir_name (NAME));
- rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
- to "foo" in the same directory NAME was in. */
-
-char *
-base_name (char const *name)
-{
- char const *base = last_component (name);
- size_t length;
-
- /* If there is no last component, then name is a file system root or the
- empty string. */
- if (! *base)
- return xstrndup (name, base_len (name));
-
- /* Collapse a sequence of trailing slashes into one. */
- length = base_len (base);
- if (ISSLASH (base[length]))
- length++;
-
- /* On systems with drive letters, `a/b:c' must return `./b:c' rather
- than `b:c' to avoid confusion with a drive letter. On systems
- with pure POSIX semantics, this is not an issue. */
- if (FILE_SYSTEM_PREFIX_LEN (base))
- {
- char *p = xmalloc (length + 3);
- p[0] = '.';
- p[1] = '/';
- memcpy (p + 2, base, length);
- p[length + 2] = '\0';
- return p;
- }
-
- /* Finally, copy the basename. */
- return xstrndup (base, length);
-}
-
-/* Return the length of the basename NAME. Typically NAME is the
- value returned by base_name or last_component. Act like strlen
- (NAME), except omit all trailing slashes. */
-
-size_t
-base_len (char const *name)
-{
- size_t len;
- size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
-
- for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
- continue;
-
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
- && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
- return 2;
-
- if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
- && len == prefix_len && ISSLASH (name[prefix_len]))
- return prefix_len + 1;
-
- return len;
-}
diff --git a/contrib/cpio/lib/dirname.c b/contrib/cpio/lib/dirname.c
deleted file mode 100644
index 16552c6..0000000
--- a/contrib/cpio/lib/dirname.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* dirname.c -- return all but the last element in a file name
-
- Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software
- Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include "dirname.h"
-
-#include <string.h>
-#include "xalloc.h"
-
-/* Return the length of the prefix of FILE that will be used by
- dir_name. If FILE is in the working directory, this returns zero
- even though `dir_name (FILE)' will return ".". Works properly even
- if there are trailing slashes (by effectively ignoring them). */
-
-size_t
-dir_len (char const *file)
-{
- size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
- size_t length;
-
- /* Advance prefix_length beyond important leading slashes. */
- prefix_length += (prefix_length != 0
- ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
- && ISSLASH (file[prefix_length]))
- : (ISSLASH (file[0])
- ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
- && ISSLASH (file[1]) && ! ISSLASH (file[2])
- ? 2 : 1))
- : 0));
-
- /* Strip the basename and any redundant slashes before it. */
- for (length = last_component (file) - file;
- prefix_length < length; length--)
- if (! ISSLASH (file[length - 1]))
- break;
- return length;
-}
-
-
-/* In general, we can't use the builtin `dirname' function if available,
- since it has different meanings in different environments.
- In some environments the builtin `dirname' modifies its argument.
-
- Return the leading directories part of FILE, allocated with xmalloc.
- Works properly even if there are trailing slashes (by effectively
- ignoring them). Unlike POSIX dirname(), FILE cannot be NULL.
-
- If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
- lstat (base_name (FILE)); } will access the same file. Likewise,
- if the sequence { chdir (dir_name (FILE));
- rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
- to "foo" in the same directory FILE was in. */
-
-char *
-dir_name (char const *file)
-{
- size_t length = dir_len (file);
- bool append_dot = (length == 0
- || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
- && length == FILE_SYSTEM_PREFIX_LEN (file)
- && file[2] != '\0' && ! ISSLASH (file[2])));
- char *dir = xmalloc (length + append_dot + 1);
- memcpy (dir, file, length);
- if (append_dot)
- dir[length++] = '.';
- dir[length] = '\0';
- return dir;
-}
diff --git a/contrib/cpio/lib/dirname.h b/contrib/cpio/lib/dirname.h
deleted file mode 100644
index 91e7ed3..0000000
--- a/contrib/cpio/lib/dirname.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Take file names apart into directory and base names.
-
- Copyright (C) 1998, 2001, 2003-2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef DIRNAME_H_
-# define DIRNAME_H_ 1
-
-# include <stdbool.h>
-# include <stddef.h>
-
-# ifndef DIRECTORY_SEPARATOR
-# define DIRECTORY_SEPARATOR '/'
-# endif
-
-# ifndef ISSLASH
-# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
-# endif
-
-# ifndef FILE_SYSTEM_PREFIX_LEN
-# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
- /* This internal macro assumes ASCII, but all hosts that support drive
- letters use ASCII. */
-# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
- <= 'z' - 'a')
-# define FILE_SYSTEM_PREFIX_LEN(Filename) \
- (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
-# else
-# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
-# endif
-# endif
-
-# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
-# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
-# endif
-
-# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
-# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
-# endif
-
-# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
-# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
-# else
-# define IS_ABSOLUTE_FILE_NAME(F) \
- (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
-# endif
-# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
-
-char *base_name (char const *file);
-char *dir_name (char const *file);
-size_t base_len (char const *file);
-size_t dir_len (char const *file);
-char *last_component (char const *file);
-
-bool strip_trailing_slashes (char *file);
-
-#endif /* not DIRNAME_H_ */
diff --git a/contrib/cpio/lib/error.c b/contrib/cpio/lib/error.c
deleted file mode 100644
index cf86343..0000000
--- a/contrib/cpio/lib/error.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Error handler for noninteractive utilities
- Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#if !_LIBC
-# include <config.h>
-#endif
-
-#include "error.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if !_LIBC && ENABLE_NLS
-# include "gettext.h"
-#endif
-
-#ifdef _LIBC
-# include <libintl.h>
-# include <stdbool.h>
-# include <stdint.h>
-# include <wchar.h>
-# define mbsrtowcs __mbsrtowcs
-#endif
-
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
-#ifndef _
-# define _(String) String
-#endif
-
-/* If NULL, error will flush stdout, then print on stderr the program
- name, a colon and a space. Otherwise, error will call this
- function without parameters instead. */
-void (*error_print_progname) (void);
-
-/* This variable is incremented each time `error' is called. */
-unsigned int error_message_count;
-
-#ifdef _LIBC
-/* In the GNU C library, there is a predefined variable for this. */
-
-# define program_name program_invocation_name
-# include <errno.h>
-# include <limits.h>
-# include <libio/libioP.h>
-
-/* In GNU libc we want do not want to use the common name `error' directly.
- Instead make it a weak alias. */
-extern void __error (int status, int errnum, const char *message, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-extern void __error_at_line (int status, int errnum, const char *file_name,
- unsigned int line_number, const char *message,
- ...)
- __attribute__ ((__format__ (__printf__, 5, 6)));;
-# define error __error
-# define error_at_line __error_at_line
-
-# include <libio/iolibio.h>
-# define fflush(s) INTUSE(_IO_fflush) (s)
-# undef putc
-# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
-
-# include <bits/libc-lock.h>
-
-#else /* not _LIBC */
-
-# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
-# ifndef HAVE_DECL_STRERROR_R
-"this configure-time declaration test was not run"
-# endif
-char *strerror_r ();
-# endif
-
-/* The calling program should define program_name and set it to the
- name of the executing program. */
-extern char *program_name;
-
-# if HAVE_STRERROR_R || defined strerror_r
-# define __strerror_r strerror_r
-# endif /* HAVE_STRERROR_R || defined strerror_r */
-#endif /* not _LIBC */
-
-static void
-print_errno_message (int errnum)
-{
- char const *s;
-
-#if defined HAVE_STRERROR_R || _LIBC
- char errbuf[1024];
-# if STRERROR_R_CHAR_P || _LIBC
- s = __strerror_r (errnum, errbuf, sizeof errbuf);
-# else
- if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
- s = errbuf;
- else
- s = 0;
-# endif
-#else
- s = strerror (errnum);
-#endif
-
-#if !_LIBC
- if (! s)
- s = _("Unknown system error");
-#endif
-
-#if _LIBC
- __fxprintf (NULL, ": %s", s);
-#else
- fprintf (stderr, ": %s", s);
-#endif
-}
-
-static void
-error_tail (int status, int errnum, const char *message, va_list args)
-{
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- {
-# define ALLOCA_LIMIT 2000
- size_t len = strlen (message) + 1;
- wchar_t *wmessage = NULL;
- mbstate_t st;
- size_t res;
- const char *tmp;
- bool use_malloc = false;
-
- while (1)
- {
- if (__libc_use_alloca (len * sizeof (wchar_t)))
- wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
- else
- {
- if (!use_malloc)
- wmessage = NULL;
-
- wchar_t *p = (wchar_t *) realloc (wmessage,
- len * sizeof (wchar_t));
- if (p == NULL)
- {
- free (wmessage);
- fputws_unlocked (L"out of memory\n", stderr);
- return;
- }
- wmessage = p;
- use_malloc = true;
- }
-
- memset (&st, '\0', sizeof (st));
- tmp = message;
-
- res = mbsrtowcs (wmessage, &tmp, len, &st);
- if (res != len)
- break;
-
- if (__builtin_expect (len >= SIZE_MAX / 2, 0))
- {
- /* This really should not happen if everything is fine. */
- res = (size_t) -1;
- break;
- }
-
- len *= 2;
- }
-
- if (res == (size_t) -1)
- {
- /* The string cannot be converted. */
- if (use_malloc)
- {
- free (wmessage);
- use_malloc = false;
- }
- wmessage = (wchar_t *) L"???";
- }
-
- __vfwprintf (stderr, wmessage, args);
-
- if (use_malloc)
- free (wmessage);
- }
- else
-#endif
- vfprintf (stderr, message, args);
- va_end (args);
-
- ++error_message_count;
- if (errnum)
- print_errno_message (errnum);
-#if _LIBC
- __fxprintf (NULL, "\n");
-#else
- putc ('\n', stderr);
-#endif
- fflush (stderr);
- if (status)
- exit (status);
-}
-
-
-/* Print the program name and error message MESSAGE, which is a printf-style
- format string with optional args.
- If ERRNUM is nonzero, print its corresponding system error message.
- Exit with status STATUS if it is nonzero. */
-void
-error (int status, int errnum, const char *message, ...)
-{
- va_list args;
-
-#if defined _LIBC && defined __libc_ptf_call
- /* We do not want this call to be cut short by a thread
- cancellation. Therefore disable cancellation for now. */
- int state = PTHREAD_CANCEL_ENABLE;
- __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
- 0);
-#endif
-
- fflush (stdout);
-#ifdef _LIBC
- _IO_flockfile (stderr);
-#endif
- if (error_print_progname)
- (*error_print_progname) ();
- else
- {
-#if _LIBC
- __fxprintf (NULL, "%s: ", program_name);
-#else
- fprintf (stderr, "%s: ", program_name);
-#endif
- }
-
- va_start (args, message);
- error_tail (status, errnum, message, args);
-
-#ifdef _LIBC
- _IO_funlockfile (stderr);
-# ifdef __libc_ptf_call
- __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
-# endif
-#endif
-}
-
-/* Sometimes we want to have at most one error per line. This
- variable controls whether this mode is selected or not. */
-int error_one_per_line;
-
-void
-error_at_line (int status, int errnum, const char *file_name,
- unsigned int line_number, const char *message, ...)
-{
- va_list args;
-
- if (error_one_per_line)
- {
- static const char *old_file_name;
- static unsigned int old_line_number;
-
- if (old_line_number == line_number
- && (file_name == old_file_name
- || strcmp (old_file_name, file_name) == 0))
- /* Simply return and print nothing. */
- return;
-
- old_file_name = file_name;
- old_line_number = line_number;
- }
-
-#if defined _LIBC && defined __libc_ptf_call
- /* We do not want this call to be cut short by a thread
- cancellation. Therefore disable cancellation for now. */
- int state = PTHREAD_CANCEL_ENABLE;
- __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
- 0);
-#endif
-
- fflush (stdout);
-#ifdef _LIBC
- _IO_flockfile (stderr);
-#endif
- if (error_print_progname)
- (*error_print_progname) ();
- else
- {
-#if _LIBC
- __fxprintf (NULL, "%s:", program_name);
-#else
- fprintf (stderr, "%s:", program_name);
-#endif
- }
-
-#if _LIBC
- __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
- file_name, line_number);
-#else
- fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
- file_name, line_number);
-#endif
-
- va_start (args, message);
- error_tail (status, errnum, message, args);
-
-#ifdef _LIBC
- _IO_funlockfile (stderr);
-# ifdef __libc_ptf_call
- __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
-# endif
-#endif
-}
-
-#ifdef _LIBC
-/* Make the weak alias. */
-# undef error
-# undef error_at_line
-weak_alias (__error, error)
-weak_alias (__error_at_line, error_at_line)
-#endif
diff --git a/contrib/cpio/lib/error.h b/contrib/cpio/lib/error.h
deleted file mode 100644
index 5a5f247..0000000
--- a/contrib/cpio/lib/error.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Declaration for error-reporting function
- Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _ERROR_H
-#define _ERROR_H 1
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Print a message with `fprintf (stderr, FORMAT, ...)';
- if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
- If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
-
-extern void error (int __status, int __errnum, const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-
-extern void error_at_line (int __status, int __errnum, const char *__fname,
- unsigned int __lineno, const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 5, 6)));
-
-/* If NULL, error will flush stdout, then print on stderr the program
- name, a colon and a space. Otherwise, error will call this
- function without parameters instead. */
-extern void (*error_print_progname) (void);
-
-/* This variable is incremented each time `error' is called. */
-extern unsigned int error_message_count;
-
-/* Sometimes we want to have at most one error per line. This
- variable controls whether this mode is selected or not. */
-extern int error_one_per_line;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* error.h */
diff --git a/contrib/cpio/lib/exitfail.c b/contrib/cpio/lib/exitfail.c
deleted file mode 100644
index 373d325..0000000
--- a/contrib/cpio/lib/exitfail.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Failure exit status
-
- Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING.
- If not, write to the Free Software Foundation,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include "exitfail.h"
-
-#include <stdlib.h>
-
-int volatile exit_failure = EXIT_FAILURE;
diff --git a/contrib/cpio/lib/exitfail.h b/contrib/cpio/lib/exitfail.h
deleted file mode 100644
index e46cf9c..0000000
--- a/contrib/cpio/lib/exitfail.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Failure exit status
-
- Copyright (C) 2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING.
- If not, write to the Free Software Foundation,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-extern int volatile exit_failure;
diff --git a/contrib/cpio/lib/fatal.c b/contrib/cpio/lib/fatal.c
deleted file mode 100644
index bcce42c..0000000
--- a/contrib/cpio/lib/fatal.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* This file is part of GNU cpio.
- Copyright (C) 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-#include <paxlib.h>
-
-void
-fatal_exit ()
-{
- exit (PAXEXIT_FAILURE);
-}
-
diff --git a/contrib/cpio/lib/full-write.c b/contrib/cpio/lib/full-write.c
deleted file mode 100644
index cc16872..0000000
--- a/contrib/cpio/lib/full-write.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* An interface to read and write that retries (if necessary) until complete.
-
- Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-/* Specification. */
-#ifdef FULL_READ
-# include "full-read.h"
-#else
-# include "full-write.h"
-#endif
-
-#include <errno.h>
-
-#ifdef FULL_READ
-# include "safe-read.h"
-# define safe_rw safe_read
-# define full_rw full_read
-# undef const
-# define const /* empty */
-#else
-# include "safe-write.h"
-# define safe_rw safe_write
-# define full_rw full_write
-#endif
-
-#ifdef FULL_READ
-/* Set errno to zero upon EOF. */
-# define ZERO_BYTE_TRANSFER_ERRNO 0
-#else
-/* Some buggy drivers return 0 when one tries to write beyond
- a device's end. (Example: Linux 1.2.13 on /dev/fd0.)
- Set errno to ENOSPC so they get a sensible diagnostic. */
-# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC
-#endif
-
-/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if
- interrupted or if a partial write(read) occurs. Return the number
- of bytes transferred.
- When writing, set errno if fewer than COUNT bytes are written.
- When reading, if fewer than COUNT bytes are read, you must examine
- errno to distinguish failure from EOF (errno == 0). */
-size_t
-full_rw (int fd, const void *buf, size_t count)
-{
- size_t total = 0;
- const char *ptr = (const char *) buf;
-
- while (count > 0)
- {
- size_t n_rw = safe_rw (fd, ptr, count);
- if (n_rw == (size_t) -1)
- break;
- if (n_rw == 0)
- {
- errno = ZERO_BYTE_TRANSFER_ERRNO;
- break;
- }
- total += n_rw;
- ptr += n_rw;
- count -= n_rw;
- }
-
- return total;
-}
diff --git a/contrib/cpio/lib/full-write.h b/contrib/cpio/lib/full-write.h
deleted file mode 100644
index d20d2fe..0000000
--- a/contrib/cpio/lib/full-write.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* An interface to write() that writes all it is asked to write.
-
- Copyright (C) 2002-2003 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <stddef.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted
- or if partial writes occur. Return the number of bytes successfully
- written, setting errno if that is less than COUNT. */
-extern size_t full_write (int fd, const void *buf, size_t count);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/cpio/lib/getopt.c b/contrib/cpio/lib/getopt.c
deleted file mode 100644
index 3580ad8..0000000
--- a/contrib/cpio/lib/getopt.c
+++ /dev/null
@@ -1,1191 +0,0 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to drepper@gnu.org
- before changing it!
- Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _LIBC
-# include <config.h>
-#endif
-
-#include "getopt.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef __VMS
-# include <unixlib.h>
-#endif
-
-#ifdef _LIBC
-# include <libintl.h>
-#else
-# include "gettext.h"
-# define _(msgid) gettext (msgid)
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-# include <wchar.h>
-#endif
-
-#ifndef attribute_hidden
-# define attribute_hidden
-#endif
-
-/* Unlike standard Unix `getopt', functions like `getopt_long'
- let the user intersperse the options with the other arguments.
-
- As `getopt_long' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Using `getopt' or setting the environment variable POSIXLY_CORRECT
- disables permutation.
- Then the application's behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt_int.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Keep a global copy of all internal members of getopt_data. */
-
-static struct _getopt_data getopt_data;
-
-
-#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV
-extern char *getenv ();
-#endif
-
-#ifdef _LIBC
-/* Stored original parameters.
- XXX This is no good solution. We should rather copy the args so
- that we can compare them later. But we must not use malloc(3). */
-extern int __libc_argc;
-extern char **__libc_argv;
-
-/* Bash 2.0 gives us an environment variable containing flags
- indicating ARGV elements that should not be considered arguments. */
-
-# ifdef USE_NONOPTION_FLAGS
-/* Defined in getopt_init.c */
-extern char *__getopt_nonoption_flags;
-# endif
-
-# ifdef USE_NONOPTION_FLAGS
-# define SWAP_FLAGS(ch1, ch2) \
- if (d->__nonoption_flags_len > 0) \
- { \
- char __tmp = __getopt_nonoption_flags[ch1]; \
- __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
- __getopt_nonoption_flags[ch2] = __tmp; \
- }
-# else
-# define SWAP_FLAGS(ch1, ch2)
-# endif
-#else /* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif /* _LIBC */
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-static void
-exchange (char **argv, struct _getopt_data *d)
-{
- int bottom = d->__first_nonopt;
- int middle = d->__last_nonopt;
- int top = d->optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
- /* First make sure the handling of the `__getopt_nonoption_flags'
- string can work normally. Our top argument must be in the range
- of the string. */
- if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
- {
- /* We must extend the array. The user plays games with us and
- presents new arguments. */
- char *new_str = malloc (top + 1);
- if (new_str == NULL)
- d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
- else
- {
- memset (__mempcpy (new_str, __getopt_nonoption_flags,
- d->__nonoption_flags_max_len),
- '\0', top + 1 - d->__nonoption_flags_max_len);
- d->__nonoption_flags_max_len = top + 1;
- __getopt_nonoption_flags = new_str;
- }
- }
-#endif
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- SWAP_FLAGS (bottom + i, middle + i);
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- d->__first_nonopt += (d->optind - d->__last_nonopt);
- d->__last_nonopt = d->optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-static const char *
-_getopt_initialize (int argc, char **argv, const char *optstring,
- int posixly_correct, struct _getopt_data *d)
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- d->__first_nonopt = d->__last_nonopt = d->optind;
-
- d->__nextchar = NULL;
-
- d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- d->__ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- d->__ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (d->__posixly_correct)
- d->__ordering = REQUIRE_ORDER;
- else
- d->__ordering = PERMUTE;
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
- if (!d->__posixly_correct
- && argc == __libc_argc && argv == __libc_argv)
- {
- if (d->__nonoption_flags_max_len == 0)
- {
- if (__getopt_nonoption_flags == NULL
- || __getopt_nonoption_flags[0] == '\0')
- d->__nonoption_flags_max_len = -1;
- else
- {
- const char *orig_str = __getopt_nonoption_flags;
- int len = d->__nonoption_flags_max_len = strlen (orig_str);
- if (d->__nonoption_flags_max_len < argc)
- d->__nonoption_flags_max_len = argc;
- __getopt_nonoption_flags =
- (char *) malloc (d->__nonoption_flags_max_len);
- if (__getopt_nonoption_flags == NULL)
- d->__nonoption_flags_max_len = -1;
- else
- memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
- '\0', d->__nonoption_flags_max_len - len);
- }
- }
- d->__nonoption_flags_len = d->__nonoption_flags_max_len;
- }
- else
- d->__nonoption_flags_len = 0;
-#endif
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns -1.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options.
-
- If POSIXLY_CORRECT is nonzero, behave as if the POSIXLY_CORRECT
- environment variable were set. */
-
-int
-_getopt_internal_r (int argc, char **argv, const char *optstring,
- const struct option *longopts, int *longind,
- int long_only, int posixly_correct, struct _getopt_data *d)
-{
- int print_errors = d->opterr;
- if (optstring[0] == ':')
- print_errors = 0;
-
- if (argc < 1)
- return -1;
-
- d->optarg = NULL;
-
- if (d->optind == 0 || !d->__initialized)
- {
- if (d->optind == 0)
- d->optind = 1; /* Don't scan ARGV[0], the program name. */
- optstring = _getopt_initialize (argc, argv, optstring,
- posixly_correct, d);
- d->__initialized = 1;
- }
-
- /* Test whether ARGV[optind] points to a non-option argument.
- Either it does not have option syntax, or there is an environment flag
- from the shell indicating it is not an option. The later information
- is only used when the used in the GNU libc. */
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
- || (d->optind < d->__nonoption_flags_len \
- && __getopt_nonoption_flags[d->optind] == '1'))
-#else
-# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
-#endif
-
- if (d->__nextchar == NULL || *d->__nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
- moved back by the user (who may also have changed the arguments). */
- if (d->__last_nonopt > d->optind)
- d->__last_nonopt = d->optind;
- if (d->__first_nonopt > d->optind)
- d->__first_nonopt = d->optind;
-
- if (d->__ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (d->__first_nonopt != d->__last_nonopt
- && d->__last_nonopt != d->optind)
- exchange ((char **) argv, d);
- else if (d->__last_nonopt != d->optind)
- d->__first_nonopt = d->optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (d->optind < argc && NONOPTION_P)
- d->optind++;
- d->__last_nonopt = d->optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (d->optind != argc && !strcmp (argv[d->optind], "--"))
- {
- d->optind++;
-
- if (d->__first_nonopt != d->__last_nonopt
- && d->__last_nonopt != d->optind)
- exchange ((char **) argv, d);
- else if (d->__first_nonopt == d->__last_nonopt)
- d->__first_nonopt = d->optind;
- d->__last_nonopt = argc;
-
- d->optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (d->optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (d->__first_nonopt != d->__last_nonopt)
- d->optind = d->__first_nonopt;
- return -1;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if (NONOPTION_P)
- {
- if (d->__ordering == REQUIRE_ORDER)
- return -1;
- d->optarg = argv[d->optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- d->__nextchar = (argv[d->optind] + 1
- + (longopts != NULL && argv[d->optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[d->optind][1] == '-'
- || (long_only && (argv[d->optind][2]
- || !strchr (optstring, argv[d->optind][1])))))
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = -1;
- int option_index;
-
- for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
- {
- if ((unsigned int) (nameend - d->__nextchar)
- == (unsigned int) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else if (long_only
- || pfound->has_arg != p->has_arg
- || pfound->flag != p->flag
- || pfound->val != p->val)
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
- argv[0], argv[d->optind]) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
- argv[0], argv[d->optind]);
-#endif
- }
- d->__nextchar += strlen (d->__nextchar);
- d->optind++;
- d->optopt = 0;
- return '?';
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- d->optind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- d->optarg = nameend + 1;
- else
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
- int n;
-#endif
-
- if (argv[d->optind - 1][1] == '-')
- {
- /* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
- n = __asprintf (&buf, _("\
-%s: option `--%s' doesn't allow an argument\n"),
- argv[0], pfound->name);
-#else
- fprintf (stderr, _("\
-%s: option `--%s' doesn't allow an argument\n"),
- argv[0], pfound->name);
-#endif
- }
- else
- {
- /* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
- n = __asprintf (&buf, _("\
-%s: option `%c%s' doesn't allow an argument\n"),
- argv[0], argv[d->optind - 1][0],
- pfound->name);
-#else
- fprintf (stderr, _("\
-%s: option `%c%s' doesn't allow an argument\n"),
- argv[0], argv[d->optind - 1][0],
- pfound->name);
-#endif
- }
-
-#if defined _LIBC && defined USE_IN_LIBIO
- if (n >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2
- |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#endif
- }
-
- d->__nextchar += strlen (d->__nextchar);
-
- d->optopt = pfound->val;
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (d->optind < argc)
- d->optarg = argv[d->optind++];
- else
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf, _("\
-%s: option `%s' requires an argument\n"),
- argv[0], argv[d->optind - 1]) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2
- |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr,
- _("%s: option `%s' requires an argument\n"),
- argv[0], argv[d->optind - 1]);
-#endif
- }
- d->__nextchar += strlen (d->__nextchar);
- d->optopt = pfound->val;
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- d->__nextchar += strlen (d->__nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[d->optind][1] == '-'
- || strchr (optstring, *d->__nextchar) == NULL)
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
- int n;
-#endif
-
- if (argv[d->optind][1] == '-')
- {
- /* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
- n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
- argv[0], d->__nextchar);
-#else
- fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
- argv[0], d->__nextchar);
-#endif
- }
- else
- {
- /* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
- n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
- argv[0], argv[d->optind][0], d->__nextchar);
-#else
- fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
- argv[0], argv[d->optind][0], d->__nextchar);
-#endif
- }
-
-#if defined _LIBC && defined USE_IN_LIBIO
- if (n >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#endif
- }
- d->__nextchar = (char *) "";
- d->optind++;
- d->optopt = 0;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *d->__nextchar++;
- char *temp = strchr (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*d->__nextchar == '\0')
- ++d->optind;
-
- if (temp == NULL || c == ':')
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
- int n;
-#endif
-
- if (d->__posixly_correct)
- {
- /* 1003.2 specifies the format of this message. */
-#if defined _LIBC && defined USE_IN_LIBIO
- n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
- argv[0], c);
-#else
- fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
-#endif
- }
- else
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
- argv[0], c);
-#else
- fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
-#endif
- }
-
-#if defined _LIBC && defined USE_IN_LIBIO
- if (n >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#endif
- }
- d->optopt = c;
- return '?';
- }
- /* Convenience. Treat POSIX -W foo same as long option --foo */
- if (temp[0] == 'W' && temp[1] == ';')
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = 0;
- int option_index;
-
- /* This is an option that requires an argument. */
- if (*d->__nextchar != '\0')
- {
- d->optarg = d->__nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- d->optind++;
- }
- else if (d->optind == argc)
- {
- if (print_errors)
- {
- /* 1003.2 specifies the format of this message. */
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf,
- _("%s: option requires an argument -- %c\n"),
- argv[0], c) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr, _("%s: option requires an argument -- %c\n"),
- argv[0], c);
-#endif
- }
- d->optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- return c;
- }
- else
- /* We already incremented `d->optind' once;
- increment it again when taking next ARGV-elt as argument. */
- d->optarg = argv[d->optind++];
-
- /* optarg is now the argument, see if it's in the
- table of longopts. */
-
- for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
- nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
- {
- if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
- if (ambig && !exact)
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
- argv[0], argv[d->optind]) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
- argv[0], argv[d->optind]);
-#endif
- }
- d->__nextchar += strlen (d->__nextchar);
- d->optind++;
- return '?';
- }
- if (pfound != NULL)
- {
- option_index = indfound;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- d->optarg = nameend + 1;
- else
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
- argv[0], pfound->name) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2
- |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
- argv[0], pfound->name);
-#endif
- }
-
- d->__nextchar += strlen (d->__nextchar);
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (d->optind < argc)
- d->optarg = argv[d->optind++];
- else
- {
- if (print_errors)
- {
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf, _("\
-%s: option `%s' requires an argument\n"),
- argv[0], argv[d->optind - 1]) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2
- |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr,
- _("%s: option `%s' requires an argument\n"),
- argv[0], argv[d->optind - 1]);
-#endif
- }
- d->__nextchar += strlen (d->__nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- d->__nextchar += strlen (d->__nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- d->__nextchar = NULL;
- return 'W'; /* Let the application handle it. */
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*d->__nextchar != '\0')
- {
- d->optarg = d->__nextchar;
- d->optind++;
- }
- else
- d->optarg = NULL;
- d->__nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*d->__nextchar != '\0')
- {
- d->optarg = d->__nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- d->optind++;
- }
- else if (d->optind == argc)
- {
- if (print_errors)
- {
- /* 1003.2 specifies the format of this message. */
-#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
-
- if (__asprintf (&buf, _("\
-%s: option requires an argument -- %c\n"),
- argv[0], c) >= 0)
- {
- _IO_flockfile (stderr);
-
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
- __fxprintf (NULL, "%s", buf);
-
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
-
- free (buf);
- }
-#else
- fprintf (stderr,
- _("%s: option requires an argument -- %c\n"),
- argv[0], c);
-#endif
- }
- d->optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- d->optarg = argv[d->optind++];
- d->__nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-int
-_getopt_internal (int argc, char **argv, const char *optstring,
- const struct option *longopts, int *longind,
- int long_only, int posixly_correct)
-{
- int result;
-
- getopt_data.optind = optind;
- getopt_data.opterr = opterr;
-
- result = _getopt_internal_r (argc, argv, optstring, longopts, longind,
- long_only, posixly_correct, &getopt_data);
-
- optind = getopt_data.optind;
- optarg = getopt_data.optarg;
- optopt = getopt_data.optopt;
-
- return result;
-}
-
-/* glibc gets a LSB-compliant getopt.
- Standalone applications get a POSIX-compliant getopt. */
-#if _LIBC
-enum { POSIXLY_CORRECT = 0 };
-#else
-enum { POSIXLY_CORRECT = 1 };
-#endif
-
-int
-getopt (int argc, char *const *argv, const char *optstring)
-{
- return _getopt_internal (argc, (char **) argv, optstring, NULL, NULL, 0,
- POSIXLY_CORRECT);
-}
-
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (int argc, char **argv)
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt (argc, argv, "abc:d:0123456789");
- if (c == -1)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/contrib/cpio/lib/getopt1.c b/contrib/cpio/lib/getopt1.c
deleted file mode 100644
index cc0746e..0000000
--- a/contrib/cpio/lib/getopt1.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifdef _LIBC
-# include <getopt.h>
-#else
-# include <config.h>
-# include "getopt.h"
-#endif
-#include "getopt_int.h"
-
-#include <stdio.h>
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
- const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, (char **) argv, options, long_options,
- opt_index, 0, 0);
-}
-
-int
-_getopt_long_r (int argc, char **argv, const char *options,
- const struct option *long_options, int *opt_index,
- struct _getopt_data *d)
-{
- return _getopt_internal_r (argc, argv, options, long_options, opt_index,
- 0, 0, d);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int
-getopt_long_only (int argc, char *__getopt_argv_const *argv,
- const char *options,
- const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, (char **) argv, options, long_options,
- opt_index, 1, 0);
-}
-
-int
-_getopt_long_only_r (int argc, char **argv, const char *options,
- const struct option *long_options, int *opt_index,
- struct _getopt_data *d)
-{
- return _getopt_internal_r (argc, argv, options, long_options, opt_index,
- 1, 0, d);
-}
-
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (int argc, char **argv)
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] =
- {
- {"add", 1, 0, 0},
- {"append", 0, 0, 0},
- {"delete", 1, 0, 0},
- {"verbose", 0, 0, 0},
- {"create", 0, 0, 0},
- {"file", 1, 0, 0},
- {0, 0, 0, 0}
- };
-
- c = getopt_long (argc, argv, "abc:d:0123456789",
- long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c)
- {
- case 0:
- printf ("option %s", long_options[option_index].name);
- if (optarg)
- printf (" with arg %s", optarg);
- printf ("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf ("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/contrib/cpio/lib/getopt_.h b/contrib/cpio/lib/getopt_.h
deleted file mode 100644
index 615ef9a..0000000
--- a/contrib/cpio/lib/getopt_.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Declarations for getopt.
- Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _GETOPT_H
-
-#ifndef __need_getopt
-# define _GETOPT_H 1
-#endif
-
-/* Standalone applications should #define __GETOPT_PREFIX to an
- identifier that prefixes the external functions and variables
- defined in this header. When this happens, include the
- headers that might declare getopt so that they will not cause
- confusion if included after this file. Then systematically rename
- identifiers so that they do not collide with the system functions
- and variables. Renaming avoids problems with some compilers and
- linkers. */
-#if defined __GETOPT_PREFIX && !defined __need_getopt
-# include <stdlib.h>
-# include <stdio.h>
-# include <unistd.h>
-# undef __need_getopt
-# undef getopt
-# undef getopt_long
-# undef getopt_long_only
-# undef optarg
-# undef opterr
-# undef optind
-# undef optopt
-# define __GETOPT_CONCAT(x, y) x ## y
-# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
-# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
-# define getopt __GETOPT_ID (getopt)
-# define getopt_long __GETOPT_ID (getopt_long)
-# define getopt_long_only __GETOPT_ID (getopt_long_only)
-# define optarg __GETOPT_ID (optarg)
-# define opterr __GETOPT_ID (opterr)
-# define optind __GETOPT_ID (optind)
-# define optopt __GETOPT_ID (optopt)
-#endif
-
-/* Standalone applications get correct prototypes for getopt_long and
- getopt_long_only; they declare "char **argv". libc uses prototypes
- with "char *const *argv" that are incorrect because getopt_long and
- getopt_long_only can permute argv; this is required for backward
- compatibility (e.g., for LSB 2.0.1).
-
- This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
- but it caused redefinition warnings if both unistd.h and getopt.h were
- included, since unistd.h includes getopt.h having previously defined
- __need_getopt.
-
- The only place where __getopt_argv_const is used is in definitions
- of getopt_long and getopt_long_only below, but these are visible
- only if __need_getopt is not defined, so it is quite safe to rewrite
- the conditional as follows:
-*/
-#if !defined __need_getopt
-# if defined __GETOPT_PREFIX
-# define __getopt_argv_const /* empty */
-# else
-# define __getopt_argv_const const
-# endif
-#endif
-
-/* If __GNU_LIBRARY__ is not already defined, either we are being used
- standalone, or this is the first header included in the source file.
- If we are being used with glibc, we need to include <features.h>, but
- that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
- not defined, include <ctype.h>, which will pull in <features.h> for us
- if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
- doesn't flood the namespace with stuff the way some other headers do.) */
-#if !defined __GNU_LIBRARY__
-# include <ctype.h>
-#endif
-
-#ifndef __THROW
-# ifndef __GNUC_PREREQ
-# define __GNUC_PREREQ(maj, min) (0)
-# endif
-# if defined __cplusplus && __GNUC_PREREQ (2,8)
-# define __THROW throw ()
-# else
-# define __THROW
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-#ifndef __need_getopt
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option
-{
- const char *name;
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-# define no_argument 0
-# define required_argument 1
-# define optional_argument 2
-#endif /* need getopt */
-
-
-/* Get definitions and prototypes for functions to process the
- arguments in ARGV (ARGC of them, minus the program name) for
- options given in OPTS.
-
- Return the option character from OPTS just read. Return -1 when
- there are no more options. For unrecognized options, or options
- missing arguments, `optopt' is set to the option letter, and '?' is
- returned.
-
- The OPTS string is a list of characters which are recognized option
- letters, optionally followed by colons, specifying that that letter
- takes an argument, to be placed in `optarg'.
-
- If a letter in OPTS is followed by two colons, its argument is
- optional. This behavior is specific to the GNU `getopt'.
-
- The argument `--' causes premature termination of argument
- scanning, explicitly telling `getopt' that there are no more
- options.
-
- If OPTS begins with `-', then non-option arguments are treated as
- arguments to the option '\1'. This behavior is specific to the GNU
- `getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in
- the environment, then do not permute arguments. */
-
-extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
- __THROW;
-
-#ifndef __need_getopt
-extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind)
- __THROW;
-extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind)
- __THROW;
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Make sure we later can get all the definitions and declarations. */
-#undef __need_getopt
-
-#endif /* getopt.h */
diff --git a/contrib/cpio/lib/getopt_int.h b/contrib/cpio/lib/getopt_int.h
deleted file mode 100644
index 401579f..0000000
--- a/contrib/cpio/lib/getopt_int.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Internal declarations for getopt.
- Copyright (C) 1989-1994,1996-1999,2001,2003,2004
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _GETOPT_INT_H
-#define _GETOPT_INT_H 1
-
-extern int _getopt_internal (int ___argc, char **___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind,
- int __long_only, int __posixly_correct);
-
-
-/* Reentrant versions which can handle parsing multiple argument
- vectors at the same time. */
-
-/* Data type for reentrant functions. */
-struct _getopt_data
-{
- /* These have exactly the same meaning as the corresponding global
- variables, except that they are used for the reentrant
- versions of getopt. */
- int optind;
- int opterr;
- int optopt;
- char *optarg;
-
- /* Internal members. */
-
- /* True if the internal members have been initialized. */
- int __initialized;
-
- /* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
- char *__nextchar;
-
- /* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters, or by calling getopt.
-
- PERMUTE is the default. We permute the contents of ARGV as we
- scan, so that eventually all the non-options are at the end.
- This allows options to be given in any order, even with programs
- that were not written to expect this.
-
- RETURN_IN_ORDER is an option available to programs that were
- written to expect options and other ARGV-elements in any order
- and that care about the ordering of the two. We describe each
- non-option ARGV-element as if it were the argument of an option
- with character code 1. Using `-' as the first character of the
- list of option characters selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return -1 with `optind' != ARGC. */
-
- enum
- {
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
- } __ordering;
-
- /* If the POSIXLY_CORRECT environment variable is set
- or getopt was called. */
- int __posixly_correct;
-
-
- /* Handle permutation of arguments. */
-
- /* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first
- of them; `last_nonopt' is the index after the last of them. */
-
- int __first_nonopt;
- int __last_nonopt;
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
- int __nonoption_flags_max_len;
- int __nonoption_flags_len;
-# endif
-};
-
-/* The initializer is necessary to set OPTIND and OPTERR to their
- default values and to clear the initialization flag. */
-#define _GETOPT_DATA_INITIALIZER { 1, 1 }
-
-extern int _getopt_internal_r (int ___argc, char **___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind,
- int __long_only, int __posixly_correct,
- struct _getopt_data *__data);
-
-extern int _getopt_long_r (int ___argc, char **___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind,
- struct _getopt_data *__data);
-
-extern int _getopt_long_only_r (int ___argc, char **___argv,
- const char *__shortopts,
- const struct option *__longopts,
- int *__longind,
- struct _getopt_data *__data);
-
-#endif /* getopt_int.h */
diff --git a/contrib/cpio/lib/gettext.h b/contrib/cpio/lib/gettext.h
deleted file mode 100644
index 9d76ec9..0000000
--- a/contrib/cpio/lib/gettext.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/* Convenience header for conditional use of GNU <libintl.h>.
- Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H 1
-
-/* NLS can be disabled through the configure --disable-nls option. */
-#if ENABLE_NLS
-
-/* Get declarations of GNU message catalog functions. */
-# include <libintl.h>
-
-/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
- the gettext() and ngettext() macros. This is an alternative to calling
- textdomain(), and is useful for libraries. */
-# ifdef DEFAULT_TEXT_DOMAIN
-# undef gettext
-# define gettext(Msgid) \
- dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
-# undef ngettext
-# define ngettext(Msgid1, Msgid2, N) \
- dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
-# endif
-
-#else
-
-/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
- chokes if dcgettext is defined as a macro. So include it now, to make
- later inclusions of <locale.h> a NOP. We don't include <libintl.h>
- as well because people using "gettext.h" will not include <libintl.h>,
- and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
- is OK. */
-#if defined(__sun)
-# include <locale.h>
-#endif
-
-/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
- <libintl.h>, which chokes if dcgettext is defined as a macro. So include
- it now, to make later inclusions of <libintl.h> a NOP. */
-#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
-# include <cstdlib>
-# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
-# include <libintl.h>
-# endif
-#endif
-
-/* Disabled NLS.
- The casts to 'const char *' serve the purpose of producing warnings
- for invalid uses of the value returned from these functions.
- On pre-ANSI systems without 'const', the config.h file is supposed to
- contain "#define const". */
-# define gettext(Msgid) ((const char *) (Msgid))
-# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
-# define dcgettext(Domainname, Msgid, Category) \
- ((void) (Category), dgettext (Domainname, Msgid))
-# define ngettext(Msgid1, Msgid2, N) \
- ((N) == 1 \
- ? ((void) (Msgid2), (const char *) (Msgid1)) \
- : ((void) (Msgid1), (const char *) (Msgid2)))
-# define dngettext(Domainname, Msgid1, Msgid2, N) \
- ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
-# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
- ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) \
- ((void) (Domainname), (const char *) (Dirname))
-# define bind_textdomain_codeset(Domainname, Codeset) \
- ((void) (Domainname), (const char *) (Codeset))
-
-#endif
-
-/* A pseudo function call that serves as a marker for the automated
- extraction of messages, but does not call gettext(). The run-time
- translation is done at a different place in the code.
- The argument, String, should be a literal string. Concatenated strings
- and other string expressions won't work.
- The macro's expansion is not parenthesized, so that it is suitable as
- initializer for static 'char[]' or 'const char[]' variables. */
-#define gettext_noop(String) String
-
-/* The separator between msgctxt and msgid in a .mo file. */
-#define GETTEXT_CONTEXT_GLUE "\004"
-
-/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
- MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
- short and rarely need to change.
- The letter 'p' stands for 'particular' or 'special'. */
-#ifdef DEFAULT_TEXT_DOMAIN
-# define pgettext(Msgctxt, Msgid) \
- pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
-#else
-# define pgettext(Msgctxt, Msgid) \
- pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
-#endif
-#define dpgettext(Domainname, Msgctxt, Msgid) \
- pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
-#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
- pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
-#ifdef DEFAULT_TEXT_DOMAIN
-# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
- npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
-#else
-# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
- npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
-#endif
-#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
- npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
-#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
- npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-pgettext_aux (const char *domain,
- const char *msg_ctxt_id, const char *msgid,
- int category)
-{
- const char *translation = dcgettext (domain, msg_ctxt_id, category);
- if (translation == msg_ctxt_id)
- return msgid;
- else
- return translation;
-}
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-npgettext_aux (const char *domain,
- const char *msg_ctxt_id, const char *msgid,
- const char *msgid_plural, unsigned long int n,
- int category)
-{
- const char *translation =
- dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
- if (translation == msg_ctxt_id || translation == msgid_plural)
- return (n == 1 ? msgid : msgid_plural);
- else
- return translation;
-}
-
-/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
- can be arbitrary expressions. But for string literals these macros are
- less efficient than those above. */
-
-#include <string.h>
-
-#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
- (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
- /* || __STDC_VERSION__ >= 199901L */ )
-
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
-#include <stdlib.h>
-#endif
-
-#define pgettext_expr(Msgctxt, Msgid) \
- dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
-#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
- dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-dcpgettext_expr (const char *domain,
- const char *msgctxt, const char *msgid,
- int category)
-{
- size_t msgctxt_len = strlen (msgctxt) + 1;
- size_t msgid_len = strlen (msgid) + 1;
- const char *translation;
-#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
- char msg_ctxt_id[msgctxt_len + msgid_len];
-#else
- char buf[1024];
- char *msg_ctxt_id =
- (msgctxt_len + msgid_len <= sizeof (buf)
- ? buf
- : (char *) malloc (msgctxt_len + msgid_len));
- if (msg_ctxt_id != NULL)
-#endif
- {
- memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
- msg_ctxt_id[msgctxt_len - 1] = '\004';
- memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
- translation = dcgettext (domain, msg_ctxt_id, category);
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
- if (msg_ctxt_id != buf)
- free (msg_ctxt_id);
-#endif
- if (translation != msg_ctxt_id)
- return translation;
- }
- return msgid;
-}
-
-#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
- dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
-#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
- dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-dcnpgettext_expr (const char *domain,
- const char *msgctxt, const char *msgid,
- const char *msgid_plural, unsigned long int n,
- int category)
-{
- size_t msgctxt_len = strlen (msgctxt) + 1;
- size_t msgid_len = strlen (msgid) + 1;
- const char *translation;
-#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
- char msg_ctxt_id[msgctxt_len + msgid_len];
-#else
- char buf[1024];
- char *msg_ctxt_id =
- (msgctxt_len + msgid_len <= sizeof (buf)
- ? buf
- : (char *) malloc (msgctxt_len + msgid_len));
- if (msg_ctxt_id != NULL)
-#endif
- {
- memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
- msg_ctxt_id[msgctxt_len - 1] = '\004';
- memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
- translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
- if (msg_ctxt_id != buf)
- free (msg_ctxt_id);
-#endif
- if (!(translation == msg_ctxt_id || translation == msgid_plural))
- return translation;
- }
- return (n == 1 ? msgid : msgid_plural);
-}
-
-#endif /* _LIBGETTEXT_H */
diff --git a/contrib/cpio/lib/hash.c b/contrib/cpio/lib/hash.c
deleted file mode 100644
index f4ab12f..0000000
--- a/contrib/cpio/lib/hash.c
+++ /dev/null
@@ -1,1048 +0,0 @@
-/* hash - hashing table processing.
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 Free
- Software Foundation, Inc.
-
- Written by Jim Meyering, 1992.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* A generic hash table package. */
-
-/* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead
- of malloc. If you change USE_OBSTACK, you have to recompile! */
-
-#include <config.h>
-
-#include "hash.h"
-#include "xalloc.h"
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#if USE_OBSTACK
-# include "obstack.h"
-# ifndef obstack_chunk_alloc
-# define obstack_chunk_alloc malloc
-# endif
-# ifndef obstack_chunk_free
-# define obstack_chunk_free free
-# endif
-#endif
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-struct hash_table
- {
- /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
- for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets
- are not empty, there are N_ENTRIES active entries in the table. */
- struct hash_entry *bucket;
- struct hash_entry const *bucket_limit;
- size_t n_buckets;
- size_t n_buckets_used;
- size_t n_entries;
-
- /* Tuning arguments, kept in a physicaly separate structure. */
- const Hash_tuning *tuning;
-
- /* Three functions are given to `hash_initialize', see the documentation
- block for this function. In a word, HASHER randomizes a user entry
- into a number up from 0 up to some maximum minus 1; COMPARATOR returns
- true if two user entries compare equally; and DATA_FREER is the cleanup
- function for a user entry. */
- Hash_hasher hasher;
- Hash_comparator comparator;
- Hash_data_freer data_freer;
-
- /* A linked list of freed struct hash_entry structs. */
- struct hash_entry *free_entry_list;
-
-#if USE_OBSTACK
- /* Whenever obstacks are used, it is possible to allocate all overflowed
- entries into a single stack, so they all can be freed in a single
- operation. It is not clear if the speedup is worth the trouble. */
- struct obstack entry_stack;
-#endif
- };
-
-/* A hash table contains many internal entries, each holding a pointer to
- some user provided data (also called a user entry). An entry indistinctly
- refers to both the internal entry and its associated user entry. A user
- entry contents may be hashed by a randomization function (the hashing
- function, or just `hasher' for short) into a number (or `slot') between 0
- and the current table size. At each slot position in the hash table,
- starts a linked chain of entries for which the user data all hash to this
- slot. A bucket is the collection of all entries hashing to the same slot.
-
- A good `hasher' function will distribute entries rather evenly in buckets.
- In the ideal case, the length of each bucket is roughly the number of
- entries divided by the table size. Finding the slot for a data is usually
- done in constant time by the `hasher', and the later finding of a precise
- entry is linear in time with the size of the bucket. Consequently, a
- larger hash table size (that is, a larger number of buckets) is prone to
- yielding shorter chains, *given* the `hasher' function behaves properly.
-
- Long buckets slow down the lookup algorithm. One might use big hash table
- sizes in hope to reduce the average length of buckets, but this might
- become inordinate, as unused slots in the hash table take some space. The
- best bet is to make sure you are using a good `hasher' function (beware
- that those are not that easy to write! :-), and to use a table size
- larger than the actual number of entries. */
-
-/* If an insertion makes the ratio of nonempty buckets to table size larger
- than the growth threshold (a number between 0.0 and 1.0), then increase
- the table size by multiplying by the growth factor (a number greater than
- 1.0). The growth threshold defaults to 0.8, and the growth factor
- defaults to 1.414, meaning that the table will have doubled its size
- every second time 80% of the buckets get used. */
-#define DEFAULT_GROWTH_THRESHOLD 0.8
-#define DEFAULT_GROWTH_FACTOR 1.414
-
-/* If a deletion empties a bucket and causes the ratio of used buckets to
- table size to become smaller than the shrink threshold (a number between
- 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a
- number greater than the shrink threshold but smaller than 1.0). The shrink
- threshold and factor default to 0.0 and 1.0, meaning that the table never
- shrinks. */
-#define DEFAULT_SHRINK_THRESHOLD 0.0
-#define DEFAULT_SHRINK_FACTOR 1.0
-
-/* Use this to initialize or reset a TUNING structure to
- some sensible values. */
-static const Hash_tuning default_tuning =
- {
- DEFAULT_SHRINK_THRESHOLD,
- DEFAULT_SHRINK_FACTOR,
- DEFAULT_GROWTH_THRESHOLD,
- DEFAULT_GROWTH_FACTOR,
- false
- };
-
-/* Information and lookup. */
-
-/* The following few functions provide information about the overall hash
- table organization: the number of entries, number of buckets and maximum
- length of buckets. */
-
-/* Return the number of buckets in the hash table. The table size, the total
- number of buckets (used plus unused), or the maximum number of slots, are
- the same quantity. */
-
-size_t
-hash_get_n_buckets (const Hash_table *table)
-{
- return table->n_buckets;
-}
-
-/* Return the number of slots in use (non-empty buckets). */
-
-size_t
-hash_get_n_buckets_used (const Hash_table *table)
-{
- return table->n_buckets_used;
-}
-
-/* Return the number of active entries. */
-
-size_t
-hash_get_n_entries (const Hash_table *table)
-{
- return table->n_entries;
-}
-
-/* Return the length of the longest chain (bucket). */
-
-size_t
-hash_get_max_bucket_length (const Hash_table *table)
-{
- struct hash_entry const *bucket;
- size_t max_bucket_length = 0;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- if (bucket->data)
- {
- struct hash_entry const *cursor = bucket;
- size_t bucket_length = 1;
-
- while (cursor = cursor->next, cursor)
- bucket_length++;
-
- if (bucket_length > max_bucket_length)
- max_bucket_length = bucket_length;
- }
- }
-
- return max_bucket_length;
-}
-
-/* Do a mild validation of a hash table, by traversing it and checking two
- statistics. */
-
-bool
-hash_table_ok (const Hash_table *table)
-{
- struct hash_entry const *bucket;
- size_t n_buckets_used = 0;
- size_t n_entries = 0;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- if (bucket->data)
- {
- struct hash_entry const *cursor = bucket;
-
- /* Count bucket head. */
- n_buckets_used++;
- n_entries++;
-
- /* Count bucket overflow. */
- while (cursor = cursor->next, cursor)
- n_entries++;
- }
- }
-
- if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries)
- return true;
-
- return false;
-}
-
-void
-hash_print_statistics (const Hash_table *table, FILE *stream)
-{
- size_t n_entries = hash_get_n_entries (table);
- size_t n_buckets = hash_get_n_buckets (table);
- size_t n_buckets_used = hash_get_n_buckets_used (table);
- size_t max_bucket_length = hash_get_max_bucket_length (table);
-
- fprintf (stream, "# entries: %lu\n", (unsigned long int) n_entries);
- fprintf (stream, "# buckets: %lu\n", (unsigned long int) n_buckets);
- fprintf (stream, "# buckets used: %lu (%.2f%%)\n",
- (unsigned long int) n_buckets_used,
- (100.0 * n_buckets_used) / n_buckets);
- fprintf (stream, "max bucket length: %lu\n",
- (unsigned long int) max_bucket_length);
-}
-
-/* If ENTRY matches an entry already in the hash table, return the
- entry from the table. Otherwise, return NULL. */
-
-void *
-hash_lookup (const Hash_table *table, const void *entry)
-{
- struct hash_entry const *bucket
- = table->bucket + table->hasher (entry, table->n_buckets);
- struct hash_entry const *cursor;
-
- if (! (bucket < table->bucket_limit))
- abort ();
-
- if (bucket->data == NULL)
- return NULL;
-
- for (cursor = bucket; cursor; cursor = cursor->next)
- if (table->comparator (entry, cursor->data))
- return cursor->data;
-
- return NULL;
-}
-
-/* Walking. */
-
-/* The functions in this page traverse the hash table and process the
- contained entries. For the traversal to work properly, the hash table
- should not be resized nor modified while any particular entry is being
- processed. In particular, entries should not be added or removed. */
-
-/* Return the first data in the table, or NULL if the table is empty. */
-
-void *
-hash_get_first (const Hash_table *table)
-{
- struct hash_entry const *bucket;
-
- if (table->n_entries == 0)
- return NULL;
-
- for (bucket = table->bucket; ; bucket++)
- if (! (bucket < table->bucket_limit))
- abort ();
- else if (bucket->data)
- return bucket->data;
-}
-
-/* Return the user data for the entry following ENTRY, where ENTRY has been
- returned by a previous call to either `hash_get_first' or `hash_get_next'.
- Return NULL if there are no more entries. */
-
-void *
-hash_get_next (const Hash_table *table, const void *entry)
-{
- struct hash_entry const *bucket
- = table->bucket + table->hasher (entry, table->n_buckets);
- struct hash_entry const *cursor;
-
- if (! (bucket < table->bucket_limit))
- abort ();
-
- /* Find next entry in the same bucket. */
- for (cursor = bucket; cursor; cursor = cursor->next)
- if (cursor->data == entry && cursor->next)
- return cursor->next->data;
-
- /* Find first entry in any subsequent bucket. */
- while (++bucket < table->bucket_limit)
- if (bucket->data)
- return bucket->data;
-
- /* None found. */
- return NULL;
-}
-
-/* Fill BUFFER with pointers to active user entries in the hash table, then
- return the number of pointers copied. Do not copy more than BUFFER_SIZE
- pointers. */
-
-size_t
-hash_get_entries (const Hash_table *table, void **buffer,
- size_t buffer_size)
-{
- size_t counter = 0;
- struct hash_entry const *bucket;
- struct hash_entry const *cursor;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- if (bucket->data)
- {
- for (cursor = bucket; cursor; cursor = cursor->next)
- {
- if (counter >= buffer_size)
- return counter;
- buffer[counter++] = cursor->data;
- }
- }
- }
-
- return counter;
-}
-
-/* Call a PROCESSOR function for each entry of a hash table, and return the
- number of entries for which the processor function returned success. A
- pointer to some PROCESSOR_DATA which will be made available to each call to
- the processor function. The PROCESSOR accepts two arguments: the first is
- the user entry being walked into, the second is the value of PROCESSOR_DATA
- as received. The walking continue for as long as the PROCESSOR function
- returns nonzero. When it returns zero, the walking is interrupted. */
-
-size_t
-hash_do_for_each (const Hash_table *table, Hash_processor processor,
- void *processor_data)
-{
- size_t counter = 0;
- struct hash_entry const *bucket;
- struct hash_entry const *cursor;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- if (bucket->data)
- {
- for (cursor = bucket; cursor; cursor = cursor->next)
- {
- if (!(*processor) (cursor->data, processor_data))
- return counter;
- counter++;
- }
- }
- }
-
- return counter;
-}
-
-/* Allocation and clean-up. */
-
-/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
- This is a convenience routine for constructing other hashing functions. */
-
-#if USE_DIFF_HASH
-
-/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
- B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
- Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
- algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
- may not be good for your application." */
-
-size_t
-hash_string (const char *string, size_t n_buckets)
-{
-# define ROTATE_LEFT(Value, Shift) \
- ((Value) << (Shift) | (Value) >> ((sizeof (size_t) * CHAR_BIT) - (Shift)))
-# define HASH_ONE_CHAR(Value, Byte) \
- ((Byte) + ROTATE_LEFT (Value, 7))
-
- size_t value = 0;
- unsigned char ch;
-
- for (; (ch = *string); string++)
- value = HASH_ONE_CHAR (value, ch);
- return value % n_buckets;
-
-# undef ROTATE_LEFT
-# undef HASH_ONE_CHAR
-}
-
-#else /* not USE_DIFF_HASH */
-
-/* This one comes from `recode', and performs a bit better than the above as
- per a few experiments. It is inspired from a hashing routine found in the
- very old Cyber `snoop', itself written in typical Greg Mansfield style.
- (By the way, what happened to this excellent man? Is he still alive?) */
-
-size_t
-hash_string (const char *string, size_t n_buckets)
-{
- size_t value = 0;
- unsigned char ch;
-
- for (; (ch = *string); string++)
- value = (value * 31 + ch) % n_buckets;
- return value;
-}
-
-#endif /* not USE_DIFF_HASH */
-
-/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
- number at least equal to 11. */
-
-static bool
-is_prime (size_t candidate)
-{
- size_t divisor = 3;
- size_t square = divisor * divisor;
-
- while (square < candidate && (candidate % divisor))
- {
- divisor++;
- square += 4 * divisor;
- divisor++;
- }
-
- return (candidate % divisor ? true : false);
-}
-
-/* Round a given CANDIDATE number up to the nearest prime, and return that
- prime. Primes lower than 10 are merely skipped. */
-
-static size_t
-next_prime (size_t candidate)
-{
- /* Skip small primes. */
- if (candidate < 10)
- candidate = 10;
-
- /* Make it definitely odd. */
- candidate |= 1;
-
- while (!is_prime (candidate))
- candidate += 2;
-
- return candidate;
-}
-
-void
-hash_reset_tuning (Hash_tuning *tuning)
-{
- *tuning = default_tuning;
-}
-
-/* For the given hash TABLE, check the user supplied tuning structure for
- reasonable values, and return true if there is no gross error with it.
- Otherwise, definitively reset the TUNING field to some acceptable default
- in the hash table (that is, the user loses the right of further modifying
- tuning arguments), and return false. */
-
-static bool
-check_tuning (Hash_table *table)
-{
- const Hash_tuning *tuning = table->tuning;
-
- /* Be a bit stricter than mathematics would require, so that
- rounding errors in size calculations do not cause allocations to
- fail to grow or shrink as they should. The smallest allocation
- is 11 (due to next_prime's algorithm), so an epsilon of 0.1
- should be good enough. */
- float epsilon = 0.1f;
-
- if (epsilon < tuning->growth_threshold
- && tuning->growth_threshold < 1 - epsilon
- && 1 + epsilon < tuning->growth_factor
- && 0 <= tuning->shrink_threshold
- && tuning->shrink_threshold + epsilon < tuning->shrink_factor
- && tuning->shrink_factor <= 1
- && tuning->shrink_threshold + epsilon < tuning->growth_threshold)
- return true;
-
- table->tuning = &default_tuning;
- return false;
-}
-
-/* Allocate and return a new hash table, or NULL upon failure. The initial
- number of buckets is automatically selected so as to _guarantee_ that you
- may insert at least CANDIDATE different user entries before any growth of
- the hash table size occurs. So, if have a reasonably tight a-priori upper
- bound on the number of entries you intend to insert in the hash table, you
- may save some table memory and insertion time, by specifying it here. If
- the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE
- argument has its meaning changed to the wanted number of buckets.
-
- TUNING points to a structure of user-supplied values, in case some fine
- tuning is wanted over the default behavior of the hasher. If TUNING is
- NULL, the default tuning parameters are used instead.
-
- The user-supplied HASHER function should be provided. It accepts two
- arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a
- slot number for that entry which should be in the range 0..TABLE_SIZE-1.
- This slot number is then returned.
-
- The user-supplied COMPARATOR function should be provided. It accepts two
- arguments pointing to user data, it then returns true for a pair of entries
- that compare equal, or false otherwise. This function is internally called
- on entries which are already known to hash to the same bucket index.
-
- The user-supplied DATA_FREER function, when not NULL, may be later called
- with the user data as an argument, just before the entry containing the
- data gets freed. This happens from within `hash_free' or `hash_clear'.
- You should specify this function only if you want these functions to free
- all of your `data' data. This is typically the case when your data is
- simply an auxiliary struct that you have malloc'd to aggregate several
- values. */
-
-Hash_table *
-hash_initialize (size_t candidate, const Hash_tuning *tuning,
- Hash_hasher hasher, Hash_comparator comparator,
- Hash_data_freer data_freer)
-{
- Hash_table *table;
-
- if (hasher == NULL || comparator == NULL)
- return NULL;
-
- table = malloc (sizeof *table);
- if (table == NULL)
- return NULL;
-
- if (!tuning)
- tuning = &default_tuning;
- table->tuning = tuning;
- if (!check_tuning (table))
- {
- /* Fail if the tuning options are invalid. This is the only occasion
- when the user gets some feedback about it. Once the table is created,
- if the user provides invalid tuning options, we silently revert to
- using the defaults, and ignore further request to change the tuning
- options. */
- goto fail;
- }
-
- if (!tuning->is_n_buckets)
- {
- float new_candidate = candidate / tuning->growth_threshold;
- if (SIZE_MAX <= new_candidate)
- goto fail;
- candidate = new_candidate;
- }
-
- if (xalloc_oversized (candidate, sizeof *table->bucket))
- goto fail;
- table->n_buckets = next_prime (candidate);
- if (xalloc_oversized (table->n_buckets, sizeof *table->bucket))
- goto fail;
-
- table->bucket = calloc (table->n_buckets, sizeof *table->bucket);
- table->bucket_limit = table->bucket + table->n_buckets;
- table->n_buckets_used = 0;
- table->n_entries = 0;
-
- table->hasher = hasher;
- table->comparator = comparator;
- table->data_freer = data_freer;
-
- table->free_entry_list = NULL;
-#if USE_OBSTACK
- obstack_init (&table->entry_stack);
-#endif
- return table;
-
- fail:
- free (table);
- return NULL;
-}
-
-/* Make all buckets empty, placing any chained entries on the free list.
- Apply the user-specified function data_freer (if any) to the datas of any
- affected entries. */
-
-void
-hash_clear (Hash_table *table)
-{
- struct hash_entry *bucket;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- if (bucket->data)
- {
- struct hash_entry *cursor;
- struct hash_entry *next;
-
- /* Free the bucket overflow. */
- for (cursor = bucket->next; cursor; cursor = next)
- {
- if (table->data_freer)
- (*table->data_freer) (cursor->data);
- cursor->data = NULL;
-
- next = cursor->next;
- /* Relinking is done one entry at a time, as it is to be expected
- that overflows are either rare or short. */
- cursor->next = table->free_entry_list;
- table->free_entry_list = cursor;
- }
-
- /* Free the bucket head. */
- if (table->data_freer)
- (*table->data_freer) (bucket->data);
- bucket->data = NULL;
- bucket->next = NULL;
- }
- }
-
- table->n_buckets_used = 0;
- table->n_entries = 0;
-}
-
-/* Reclaim all storage associated with a hash table. If a data_freer
- function has been supplied by the user when the hash table was created,
- this function applies it to the data of each entry before freeing that
- entry. */
-
-void
-hash_free (Hash_table *table)
-{
- struct hash_entry *bucket;
- struct hash_entry *cursor;
- struct hash_entry *next;
-
- /* Call the user data_freer function. */
- if (table->data_freer && table->n_entries)
- {
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- if (bucket->data)
- {
- for (cursor = bucket; cursor; cursor = cursor->next)
- {
- (*table->data_freer) (cursor->data);
- }
- }
- }
- }
-
-#if USE_OBSTACK
-
- obstack_free (&table->entry_stack, NULL);
-
-#else
-
- /* Free all bucket overflowed entries. */
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- for (cursor = bucket->next; cursor; cursor = next)
- {
- next = cursor->next;
- free (cursor);
- }
- }
-
- /* Also reclaim the internal list of previously freed entries. */
- for (cursor = table->free_entry_list; cursor; cursor = next)
- {
- next = cursor->next;
- free (cursor);
- }
-
-#endif
-
- /* Free the remainder of the hash table structure. */
- free (table->bucket);
- free (table);
-}
-
-/* Insertion and deletion. */
-
-/* Get a new hash entry for a bucket overflow, possibly by reclying a
- previously freed one. If this is not possible, allocate a new one. */
-
-static struct hash_entry *
-allocate_entry (Hash_table *table)
-{
- struct hash_entry *new;
-
- if (table->free_entry_list)
- {
- new = table->free_entry_list;
- table->free_entry_list = new->next;
- }
- else
- {
-#if USE_OBSTACK
- new = obstack_alloc (&table->entry_stack, sizeof *new);
-#else
- new = malloc (sizeof *new);
-#endif
- }
-
- return new;
-}
-
-/* Free a hash entry which was part of some bucket overflow,
- saving it for later recycling. */
-
-static void
-free_entry (Hash_table *table, struct hash_entry *entry)
-{
- entry->data = NULL;
- entry->next = table->free_entry_list;
- table->free_entry_list = entry;
-}
-
-/* This private function is used to help with insertion and deletion. When
- ENTRY matches an entry in the table, return a pointer to the corresponding
- user data and set *BUCKET_HEAD to the head of the selected bucket.
- Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in
- the table, unlink the matching entry. */
-
-static void *
-hash_find_entry (Hash_table *table, const void *entry,
- struct hash_entry **bucket_head, bool delete)
-{
- struct hash_entry *bucket
- = table->bucket + table->hasher (entry, table->n_buckets);
- struct hash_entry *cursor;
-
- if (! (bucket < table->bucket_limit))
- abort ();
-
- *bucket_head = bucket;
-
- /* Test for empty bucket. */
- if (bucket->data == NULL)
- return NULL;
-
- /* See if the entry is the first in the bucket. */
- if ((*table->comparator) (entry, bucket->data))
- {
- void *data = bucket->data;
-
- if (delete)
- {
- if (bucket->next)
- {
- struct hash_entry *next = bucket->next;
-
- /* Bump the first overflow entry into the bucket head, then save
- the previous first overflow entry for later recycling. */
- *bucket = *next;
- free_entry (table, next);
- }
- else
- {
- bucket->data = NULL;
- }
- }
-
- return data;
- }
-
- /* Scan the bucket overflow. */
- for (cursor = bucket; cursor->next; cursor = cursor->next)
- {
- if ((*table->comparator) (entry, cursor->next->data))
- {
- void *data = cursor->next->data;
-
- if (delete)
- {
- struct hash_entry *next = cursor->next;
-
- /* Unlink the entry to delete, then save the freed entry for later
- recycling. */
- cursor->next = next->next;
- free_entry (table, next);
- }
-
- return data;
- }
- }
-
- /* No entry found. */
- return NULL;
-}
-
-/* For an already existing hash table, change the number of buckets through
- specifying CANDIDATE. The contents of the hash table are preserved. The
- new number of buckets is automatically selected so as to _guarantee_ that
- the table may receive at least CANDIDATE different user entries, including
- those already in the table, before any other growth of the hash table size
- occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the
- exact number of buckets desired. */
-
-bool
-hash_rehash (Hash_table *table, size_t candidate)
-{
- Hash_table *new_table;
- struct hash_entry *bucket;
- struct hash_entry *cursor;
- struct hash_entry *next;
-
- new_table = hash_initialize (candidate, table->tuning, table->hasher,
- table->comparator, table->data_freer);
- if (new_table == NULL)
- return false;
-
- /* Merely reuse the extra old space into the new table. */
-#if USE_OBSTACK
- obstack_free (&new_table->entry_stack, NULL);
- new_table->entry_stack = table->entry_stack;
-#endif
- new_table->free_entry_list = table->free_entry_list;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- if (bucket->data)
- for (cursor = bucket; cursor; cursor = next)
- {
- void *data = cursor->data;
- struct hash_entry *new_bucket
- = (new_table->bucket
- + new_table->hasher (data, new_table->n_buckets));
-
- if (! (new_bucket < new_table->bucket_limit))
- abort ();
-
- next = cursor->next;
-
- if (new_bucket->data)
- {
- if (cursor == bucket)
- {
- /* Allocate or recycle an entry, when moving from a bucket
- header into a bucket overflow. */
- struct hash_entry *new_entry = allocate_entry (new_table);
-
- if (new_entry == NULL)
- return false;
-
- new_entry->data = data;
- new_entry->next = new_bucket->next;
- new_bucket->next = new_entry;
- }
- else
- {
- /* Merely relink an existing entry, when moving from a
- bucket overflow into a bucket overflow. */
- cursor->next = new_bucket->next;
- new_bucket->next = cursor;
- }
- }
- else
- {
- /* Free an existing entry, when moving from a bucket
- overflow into a bucket header. Also take care of the
- simple case of moving from a bucket header into a bucket
- header. */
- new_bucket->data = data;
- new_table->n_buckets_used++;
- if (cursor != bucket)
- free_entry (new_table, cursor);
- }
- }
-
- free (table->bucket);
- table->bucket = new_table->bucket;
- table->bucket_limit = new_table->bucket_limit;
- table->n_buckets = new_table->n_buckets;
- table->n_buckets_used = new_table->n_buckets_used;
- table->free_entry_list = new_table->free_entry_list;
- /* table->n_entries already holds its value. */
-#if USE_OBSTACK
- table->entry_stack = new_table->entry_stack;
-#endif
- free (new_table);
-
- return true;
-}
-
-/* If ENTRY matches an entry already in the hash table, return the pointer
- to the entry from the table. Otherwise, insert ENTRY and return ENTRY.
- Return NULL if the storage required for insertion cannot be allocated. */
-
-void *
-hash_insert (Hash_table *table, const void *entry)
-{
- void *data;
- struct hash_entry *bucket;
-
- /* The caller cannot insert a NULL entry. */
- if (! entry)
- abort ();
-
- /* If there's a matching entry already in the table, return that. */
- if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL)
- return data;
-
- /* ENTRY is not matched, it should be inserted. */
-
- if (bucket->data)
- {
- struct hash_entry *new_entry = allocate_entry (table);
-
- if (new_entry == NULL)
- return NULL;
-
- /* Add ENTRY in the overflow of the bucket. */
-
- new_entry->data = (void *) entry;
- new_entry->next = bucket->next;
- bucket->next = new_entry;
- table->n_entries++;
- return (void *) entry;
- }
-
- /* Add ENTRY right in the bucket head. */
-
- bucket->data = (void *) entry;
- table->n_entries++;
- table->n_buckets_used++;
-
- /* If the growth threshold of the buckets in use has been reached, increase
- the table size and rehash. There's no point in checking the number of
- entries: if the hashing function is ill-conditioned, rehashing is not
- likely to improve it. */
-
- if (table->n_buckets_used
- > table->tuning->growth_threshold * table->n_buckets)
- {
- /* Check more fully, before starting real work. If tuning arguments
- became invalid, the second check will rely on proper defaults. */
- check_tuning (table);
- if (table->n_buckets_used
- > table->tuning->growth_threshold * table->n_buckets)
- {
- const Hash_tuning *tuning = table->tuning;
- float candidate =
- (tuning->is_n_buckets
- ? (table->n_buckets * tuning->growth_factor)
- : (table->n_buckets * tuning->growth_factor
- * tuning->growth_threshold));
-
- if (SIZE_MAX <= candidate)
- return NULL;
-
- /* If the rehash fails, arrange to return NULL. */
- if (!hash_rehash (table, candidate))
- entry = NULL;
- }
- }
-
- return (void *) entry;
-}
-
-/* If ENTRY is already in the table, remove it and return the just-deleted
- data (the user may want to deallocate its storage). If ENTRY is not in the
- table, don't modify the table and return NULL. */
-
-void *
-hash_delete (Hash_table *table, const void *entry)
-{
- void *data;
- struct hash_entry *bucket;
-
- data = hash_find_entry (table, entry, &bucket, true);
- if (!data)
- return NULL;
-
- table->n_entries--;
- if (!bucket->data)
- {
- table->n_buckets_used--;
-
- /* If the shrink threshold of the buckets in use has been reached,
- rehash into a smaller table. */
-
- if (table->n_buckets_used
- < table->tuning->shrink_threshold * table->n_buckets)
- {
- /* Check more fully, before starting real work. If tuning arguments
- became invalid, the second check will rely on proper defaults. */
- check_tuning (table);
- if (table->n_buckets_used
- < table->tuning->shrink_threshold * table->n_buckets)
- {
- const Hash_tuning *tuning = table->tuning;
- size_t candidate =
- (tuning->is_n_buckets
- ? table->n_buckets * tuning->shrink_factor
- : (table->n_buckets * tuning->shrink_factor
- * tuning->growth_threshold));
-
- hash_rehash (table, candidate);
- }
- }
- }
-
- return data;
-}
-
-/* Testing. */
-
-#if TESTING
-
-void
-hash_print (const Hash_table *table)
-{
- struct hash_entry const *bucket;
-
- for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
- {
- struct hash_entry *cursor;
-
- if (bucket)
- printf ("%lu:\n", (unsigned long int) (bucket - table->bucket));
-
- for (cursor = bucket; cursor; cursor = cursor->next)
- {
- char const *s = cursor->data;
- /* FIXME */
- if (s)
- printf (" %s\n", s);
- }
- }
-}
-
-#endif /* TESTING */
diff --git a/contrib/cpio/lib/hash.h b/contrib/cpio/lib/hash.h
deleted file mode 100644
index ab63a86..0000000
--- a/contrib/cpio/lib/hash.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* hash - hashing table processing.
- Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc.
- Written by Jim Meyering <meyering@ascend.com>, 1998.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* A generic hash table package. */
-
-/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use
- obstacks instead of malloc, and recompile `hash.c' with same setting. */
-
-#ifndef HASH_H_
-# define HASH_H_
-
-# include <stdio.h>
-# include <stdbool.h>
-
-typedef size_t (*Hash_hasher) (const void *, size_t);
-typedef bool (*Hash_comparator) (const void *, const void *);
-typedef void (*Hash_data_freer) (void *);
-typedef bool (*Hash_processor) (void *, void *);
-
-struct hash_entry
- {
- void *data;
- struct hash_entry *next;
- };
-
-struct hash_tuning
- {
- /* This structure is mainly used for `hash_initialize', see the block
- documentation of `hash_reset_tuning' for more complete comments. */
-
- float shrink_threshold; /* ratio of used buckets to trigger a shrink */
- float shrink_factor; /* ratio of new smaller size to original size */
- float growth_threshold; /* ratio of used buckets to trigger a growth */
- float growth_factor; /* ratio of new bigger size to original size */
- bool is_n_buckets; /* if CANDIDATE really means table size */
- };
-
-typedef struct hash_tuning Hash_tuning;
-
-struct hash_table;
-
-typedef struct hash_table Hash_table;
-
-/* Information and lookup. */
-size_t hash_get_n_buckets (const Hash_table *);
-size_t hash_get_n_buckets_used (const Hash_table *);
-size_t hash_get_n_entries (const Hash_table *);
-size_t hash_get_max_bucket_length (const Hash_table *);
-bool hash_table_ok (const Hash_table *);
-void hash_print_statistics (const Hash_table *, FILE *);
-void *hash_lookup (const Hash_table *, const void *);
-
-/* Walking. */
-void *hash_get_first (const Hash_table *);
-void *hash_get_next (const Hash_table *, const void *);
-size_t hash_get_entries (const Hash_table *, void **, size_t);
-size_t hash_do_for_each (const Hash_table *, Hash_processor, void *);
-
-/* Allocation and clean-up. */
-size_t hash_string (const char *, size_t);
-void hash_reset_tuning (Hash_tuning *);
-Hash_table *hash_initialize (size_t, const Hash_tuning *,
- Hash_hasher, Hash_comparator,
- Hash_data_freer);
-void hash_clear (Hash_table *);
-void hash_free (Hash_table *);
-
-/* Insertion and deletion. */
-bool hash_rehash (Hash_table *, size_t);
-void *hash_insert (Hash_table *, const void *);
-void *hash_delete (Hash_table *, const void *);
-
-#endif
diff --git a/contrib/cpio/lib/intprops.h b/contrib/cpio/lib/intprops.h
deleted file mode 100644
index 34f971c..0000000
--- a/contrib/cpio/lib/intprops.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* intprops.h -- properties of integer types
-
- Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert. */
-
-#include <limits.h>
-
-/* The extra casts in the following macros work around compiler bugs,
- e.g., in Cray C 5.0.3.0. */
-
-/* True if the arithmetic type T is an integer type. bool counts as
- an integer. */
-#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
-
-/* True if negative values of the signed integer type T use two's
- complement, ones' complement, or signed magnitude representation,
- respectively. Much GNU code assumes two's complement, but some
- people like to be portable to all possible C hosts. */
-#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
-#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
-#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
-
-/* True if the arithmetic type T is signed. */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* The maximum and minimum values for the integer type T. These
- macros have undefined behavior if T is signed and has padding bits.
- If this is a problem for you, please let us know how to fix it for
- your host. */
-#define TYPE_MINIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) 0 \
- : TYPE_SIGNED_MAGNITUDE (t) \
- ? ~ (t) 0 \
- : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
-#define TYPE_MAXIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) -1 \
- : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
-
-/* Return zero if T can be determined to be an unsigned type.
- Otherwise, return 1.
- When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
- tighter bound. Otherwise, it overestimates the true bound by one byte
- when applied to unsigned types of size 2, 4, 16, ... bytes.
- The symbol signed_type_or_expr__ is private to this header file. */
-#if __GNUC__ >= 2
-# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
-#else
-# define signed_type_or_expr__(t) 1
-#endif
-
-/* Bound on length of the string representing an integer type or expression T.
- Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;
- add 1 for integer division truncation; add 1 more for a minus sign
- if needed. */
-#define INT_STRLEN_BOUND(t) \
- ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \
- + signed_type_or_expr__ (t) + 1)
-
-/* Bound on buffer size needed to represent an integer type or expression T,
- including the terminating null. */
-#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
diff --git a/contrib/cpio/lib/inttostr.c b/contrib/cpio/lib/inttostr.c
deleted file mode 100644
index 246d658..0000000
--- a/contrib/cpio/lib/inttostr.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* inttostr.c -- convert integers to printable strings
-
- Copyright (C) 2001, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert */
-
-#include <config.h>
-
-#include "inttostr.h"
-
-/* Convert I to a printable string in BUF, which must be at least
- INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the
- printable string, which need not start at BUF. */
-
-char *
-inttostr (inttype i, char *buf)
-{
- char *p = buf + INT_STRLEN_BOUND (inttype);
- *p = 0;
-
- if (i < 0)
- {
- do
- *--p = '0' - i % 10;
- while ((i /= 10) != 0);
-
- *--p = '-';
- }
- else
- {
- do
- *--p = '0' + i % 10;
- while ((i /= 10) != 0);
- }
-
- return p;
-}
diff --git a/contrib/cpio/lib/inttostr.h b/contrib/cpio/lib/inttostr.h
deleted file mode 100644
index 31258ca..0000000
--- a/contrib/cpio/lib/inttostr.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* inttostr.h -- convert integers to printable strings
-
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
- Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "intprops.h"
-
-char *offtostr (off_t, char *);
-char *imaxtostr (intmax_t, char *);
-char *umaxtostr (uintmax_t, char *);
-char *uinttostr (unsigned int, char *);
diff --git a/contrib/cpio/lib/mempcpy.c b/contrib/cpio/lib/mempcpy.c
deleted file mode 100644
index 1c702c7..0000000
--- a/contrib/cpio/lib/mempcpy.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copy memory area and return pointer after last written byte.
- Copyright (C) 2003, 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-/* Specification. */
-#include <string.h>
-
-/* Copy N bytes of SRC to DEST, return pointer to bytes after the
- last written byte. */
-void *
-mempcpy (void *dest, const void *src, size_t n)
-{
- return (char *) memcpy (dest, src, n) + n;
-}
diff --git a/contrib/cpio/lib/paxerror.c b/contrib/cpio/lib/paxerror.c
deleted file mode 100644
index 000d9e4..0000000
--- a/contrib/cpio/lib/paxerror.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/* Miscellaneous error functions
-
- Copyright (C) 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
- version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <system.h>
-#include <paxlib.h>
-#include <quote.h>
-#include <quotearg.h>
-
-/* Decode MODE from its binary form in a stat structure, and encode it
- into a 9-byte string STRING, terminated with a NUL. */
-
-void
-pax_decode_mode (mode_t mode, char *string)
-{
- *string++ = mode & S_IRUSR ? 'r' : '-';
- *string++ = mode & S_IWUSR ? 'w' : '-';
- *string++ = (mode & S_ISUID
- ? (mode & S_IXUSR ? 's' : 'S')
- : (mode & S_IXUSR ? 'x' : '-'));
- *string++ = mode & S_IRGRP ? 'r' : '-';
- *string++ = mode & S_IWGRP ? 'w' : '-';
- *string++ = (mode & S_ISGID
- ? (mode & S_IXGRP ? 's' : 'S')
- : (mode & S_IXGRP ? 'x' : '-'));
- *string++ = mode & S_IROTH ? 'r' : '-';
- *string++ = mode & S_IWOTH ? 'w' : '-';
- *string++ = (mode & S_ISVTX
- ? (mode & S_IXOTH ? 't' : 'T')
- : (mode & S_IXOTH ? 'x' : '-'));
- *string = '\0';
-}
-
-/* Report an error associated with the system call CALL and the
- optional name NAME. */
-void
-call_arg_error (char const *call, char const *name)
-{
- int e = errno;
- /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
- Directly translating this to another language will not work, first because
- %s itself is not translated.
- Translate it as `%s: Function %s failed'. */
- ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call));
-}
-
-/* Report a fatal error associated with the system call CALL and
- the optional file name NAME. */
-void
-call_arg_fatal (char const *call, char const *name)
-{
- int e = errno;
- /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
- Directly translating this to another language will not work, first because
- %s itself is not translated.
- Translate it as `%s: Function %s failed'. */
- FATAL_ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call));
-}
-
-/* Report a warning associated with the system call CALL and
- the optional file name NAME. */
-void
-call_arg_warn (char const *call, char const *name)
-{
- int e = errno;
- /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
- Directly translating this to another language will not work, first because
- %s itself is not translated.
- Translate it as `%s: Function %s failed'. */
- WARN ((0, e, _("%s: Warning: Cannot %s"), quotearg_colon (name), call));
-}
-
-void
-chmod_error_details (char const *name, mode_t mode)
-{
- int e = errno;
- char buf[10];
- pax_decode_mode (mode, buf);
- ERROR ((0, e, _("%s: Cannot change mode to %s"),
- quotearg_colon (name), buf));
-}
-
-void
-chown_error_details (char const *name, uid_t uid, gid_t gid)
-{
- int e = errno;
- ERROR ((0, e, _("%s: Cannot change ownership to uid %lu, gid %lu"),
- quotearg_colon (name), (unsigned long) uid, (unsigned long) gid));
-}
-
-void
-close_error (char const *name)
-{
- call_arg_error ("close", name);
-}
-
-void
-close_warn (char const *name)
-{
- call_arg_warn ("close", name);
-}
-
-void
-exec_fatal (char const *name)
-{
- call_arg_fatal ("exec", name);
-}
-
-void
-link_error (char const *target, char const *source)
-{
- int e = errno;
- ERROR ((0, e, _("%s: Cannot hard link to %s"),
- quotearg_colon (source), quote_n (1, target)));
-}
-
-void
-mkdir_error (char const *name)
-{
- call_arg_error ("mkdir", name);
-}
-
-void
-mkfifo_error (char const *name)
-{
- call_arg_error ("mkfifo", name);
-}
-
-void
-mknod_error (char const *name)
-{
- call_arg_error ("mknod", name);
-}
-
-void
-open_error (char const *name)
-{
- call_arg_error ("open", name);
-}
-
-void
-open_fatal (char const *name)
-{
- call_arg_fatal ("open", name);
-}
-
-void
-open_warn (char const *name)
-{
- call_arg_warn ("open", name);
-}
-
-void
-read_error (char const *name)
-{
- call_arg_error ("read", name);
-}
-
-void
-read_error_details (char const *name, off_t offset, size_t size)
-{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- ERROR ((0, e,
- ngettext ("%s: Read error at byte %s, while reading %lu byte",
- "%s: Read error at byte %s, while reading %lu bytes",
- size),
- quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
- (unsigned long) size));
-}
-
-void
-read_warn_details (char const *name, off_t offset, size_t size)
-{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- WARN ((0, e,
- ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte",
- "%s: Warning: Read error at byte %s, while reading %lu bytes",
- size),
- quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
- (unsigned long) size));
-}
-
-void
-read_fatal (char const *name)
-{
- call_arg_fatal ("read", name);
-}
-
-void
-read_fatal_details (char const *name, off_t offset, size_t size)
-{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- FATAL_ERROR ((0, e,
- ngettext ("%s: Read error at byte %s, while reading %lu byte",
- "%s: Read error at byte %s, while reading %lu bytes",
- size),
- quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
- (unsigned long) size));
-}
-
-void
-readlink_error (char const *name)
-{
- call_arg_error ("readlink", name);
-}
-
-void
-readlink_warn (char const *name)
-{
- call_arg_warn ("readlink", name);
-}
-
-void
-rmdir_error (char const *name)
-{
- call_arg_error ("rmdir", name);
-}
-
-void
-savedir_error (char const *name)
-{
- call_arg_error ("savedir", name);
-}
-
-void
-savedir_warn (char const *name)
-{
- call_arg_warn ("savedir", name);
-}
-
-void
-seek_error (char const *name)
-{
- call_arg_error ("seek", name);
-}
-
-void
-seek_error_details (char const *name, off_t offset)
-{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- ERROR ((0, e, _("%s: Cannot seek to %s"),
- quotearg_colon (name),
- STRINGIFY_BIGINT (offset, buf)));
-}
-
-void
-seek_warn (char const *name)
-{
- call_arg_warn ("seek", name);
-}
-
-void
-seek_warn_details (char const *name, off_t offset)
-{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- WARN ((0, e, _("%s: Warning: Cannot seek to %s"),
- quotearg_colon (name),
- STRINGIFY_BIGINT (offset, buf)));
-}
-
-void
-symlink_error (char const *contents, char const *name)
-{
- int e = errno;
- ERROR ((0, e, _("%s: Cannot create symlink to %s"),
- quotearg_colon (name), quote_n (1, contents)));
-}
-
-void
-stat_fatal (char const *name)
-{
- call_arg_fatal ("stat", name);
-}
-
-void
-stat_error (char const *name)
-{
- call_arg_error ("stat", name);
-}
-
-void
-stat_warn (char const *name)
-{
- call_arg_warn ("stat", name);
-}
-
-void
-truncate_error (char const *name)
-{
- call_arg_error ("truncate", name);
-}
-
-void
-truncate_warn (char const *name)
-{
- call_arg_warn ("truncate", name);
-}
-
-void
-unlink_error (char const *name)
-{
- call_arg_error ("unlink", name);
-}
-
-void
-utime_error (char const *name)
-{
- call_arg_error ("utime", name);
-}
-
-void
-waitpid_error (char const *name)
-{
- call_arg_error ("waitpid", name);
-}
-
-void
-write_error (char const *name)
-{
- call_arg_error ("write", name);
-}
-
-void
-write_error_details (char const *name, size_t status, size_t size)
-{
- if (status == 0)
- write_error (name);
- else
- ERROR ((0, 0,
- ngettext ("%s: Wrote only %lu of %lu byte",
- "%s: Wrote only %lu of %lu bytes",
- size),
- name, (unsigned long int) status, (unsigned long int) size));
-}
-
-void
-write_fatal (char const *name)
-{
- call_arg_fatal ("write", name);
-}
-
-void
-chdir_fatal (char const *name)
-{
- call_arg_fatal ("chdir", name);
-}
diff --git a/contrib/cpio/lib/paxexit.c b/contrib/cpio/lib/paxexit.c
deleted file mode 100644
index a511f79..0000000
--- a/contrib/cpio/lib/paxexit.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Miscellaneous error functions
-
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
- version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <system.h>
-#include <paxlib.h>
-
-int exit_status = PAXEXIT_SUCCESS;
-
-void
-pax_exit ()
-{
- exit (exit_status);
-}
diff --git a/contrib/cpio/lib/paxlib.h b/contrib/cpio/lib/paxlib.h
deleted file mode 100644
index 381c4c7..0000000
--- a/contrib/cpio/lib/paxlib.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* This file is part of GNU paxutils
-
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
- 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-#ifndef _paxlib_h_
-#define _paxlib_h_
-
-#include <hash.h>
-#include <inttostr.h>
-
-/* Error reporting functions and definitions */
-
-/* Exit status for paxutils app. Let's try to keep this list as simple as
- possible. tar -d option strongly invites a status different for unequal
- comparison and other errors. */
-#define PAXEXIT_SUCCESS 0
-#define PAXEXIT_DIFFERS 1
-#define PAXEXIT_FAILURE 2
-
-/* Both WARN and ERROR write a message on stderr and continue processing,
- however ERROR manages so tar will exit unsuccessfully. FATAL_ERROR
- writes a message on stderr and aborts immediately, with another message
- line telling so. USAGE_ERROR works like FATAL_ERROR except that the
- other message line suggests trying --help. All four macros accept a
- single argument of the form ((0, errno, _("FORMAT"), Args...)). errno
- is zero when the error is not being detected by the system. */
-
-#define WARN(Args) \
- error Args
-#define ERROR(Args) \
- (error Args, exit_status = PAXEXIT_FAILURE)
-#define FATAL_ERROR(Args) \
- (error Args, fatal_exit ())
-#define USAGE_ERROR(Args) \
- (error Args, usage (PAXEXIT_FAILURE))
-
-extern int exit_status;
-
-void pax_decode_mode (mode_t mode, char *string);
-void call_arg_error (char const *call, char const *name);
-void call_arg_fatal (char const *call, char const *name) __attribute__ ((noreturn));
-void call_arg_warn (char const *call, char const *name);
-void chmod_error_details (char const *name, mode_t mode);
-void chown_error_details (char const *name, uid_t uid, gid_t gid);
-
-void decode_mode (mode_t, char *);
-
-void chdir_fatal (char const *) __attribute__ ((noreturn));
-void chmod_error_details (char const *, mode_t);
-void chown_error_details (char const *, uid_t, gid_t);
-void close_error (char const *);
-void close_warn (char const *);
-void exec_fatal (char const *) __attribute__ ((noreturn));
-void link_error (char const *, char const *);
-void mkdir_error (char const *);
-void mkfifo_error (char const *);
-void mknod_error (char const *);
-void open_error (char const *);
-void open_fatal (char const *) __attribute__ ((noreturn));
-void open_warn (char const *);
-void read_error (char const *);
-void read_error_details (char const *, off_t, size_t);
-void read_fatal (char const *) __attribute__ ((noreturn));
-void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn));
-void read_warn_details (char const *, off_t, size_t);
-void readlink_error (char const *);
-void readlink_warn (char const *);
-void rmdir_error (char const *);
-void savedir_error (char const *);
-void savedir_warn (char const *);
-void seek_error (char const *);
-void seek_error_details (char const *, off_t);
-void seek_warn (char const *);
-void seek_warn_details (char const *, off_t);
-void stat_fatal (char const *);
-void stat_error (char const *);
-void stat_warn (char const *);
-void symlink_error (char const *, char const *);
-void truncate_error (char const *);
-void truncate_warn (char const *);
-void unlink_error (char const *);
-void utime_error (char const *);
-void waitpid_error (char const *);
-void write_error (char const *);
-
-void pax_exit (void);
-void fatal_exit (void) __attribute__ ((noreturn));
-
-#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b)
-
-
-/* Name-related functions */
-bool hash_string_insert (Hash_table **table, char const *string);
-bool hash_string_lookup (Hash_table const *table, char const *string);
-
-bool removed_prefixes_p (void);
-char *safer_name_suffix (char const *file_name, bool link_target, bool absolute_names);
-
-#endif
diff --git a/contrib/cpio/lib/paxnames.c b/contrib/cpio/lib/paxnames.c
deleted file mode 100644
index 3ca8bfa..0000000
--- a/contrib/cpio/lib/paxnames.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* This file is part of GNU paxutils
- Copyright (C) 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
- version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <system.h>
-#include <hash.h>
-#include <paxlib.h>
-
-
-/* Hash tables of strings. */
-
-/* Calculate the hash of a string. */
-static size_t
-hash_string_hasher (void const *name, size_t n_buckets)
-{
- return hash_string (name, n_buckets);
-}
-
-/* Compare two strings for equality. */
-static bool
-hash_string_compare (void const *name1, void const *name2)
-{
- return strcmp (name1, name2) == 0;
-}
-
-/* Return zero if TABLE contains a copy of STRING; otherwise, insert a
- copy of STRING to TABLE and return 1. */
-bool
-hash_string_insert (Hash_table **table, char const *string)
-{
- Hash_table *t = *table;
- char *s = xstrdup (string);
- char *e;
-
- if (! ((t
- || (*table = t = hash_initialize (0, 0, hash_string_hasher,
- hash_string_compare, 0)))
- && (e = hash_insert (t, s))))
- xalloc_die ();
-
- if (e == s)
- return 1;
- else
- {
- free (s);
- return 0;
- }
-}
-
-/* Return 1 if TABLE contains STRING. */
-bool
-hash_string_lookup (Hash_table const *table, char const *string)
-{
- return table && hash_lookup (table, string);
-}
-
-
-static Hash_table *prefix_table[2];
-
-/* Return true if file names of some members in the archive were stripped off
- their leading components. We could have used
- return prefix_table[0] || prefix_table[1]
- but the following seems to be safer: */
-bool
-removed_prefixes_p (void)
-{
- return (prefix_table[0] && hash_get_n_entries (prefix_table[0]) != 0)
- || (prefix_table[1] && hash_get_n_entries (prefix_table[1]) != 0);
-}
-
-/* Return a safer suffix of FILE_NAME, or "." if it has no safer
- suffix. Check for fully specified file names and other atrocities.
- Warn the user if we do not return NAME. If LINK_TARGET is 1,
- FILE_NAME is the target of a hard link, not a member name.
- If ABSOLUTE_NAMES is 0, strip filesystem prefix from the file name. */
-
-char *
-safer_name_suffix (char const *file_name, bool link_target, bool absolute_names)
-{
- char const *p;
-
- if (absolute_names)
- p = file_name;
- else
- {
- /* Skip file system prefixes, leading file name components that contain
- "..", and leading slashes. */
-
- size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);
-
- for (p = file_name + prefix_len; *p; )
- {
- if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
- prefix_len = p + 2 - file_name;
-
- do
- {
- char c = *p++;
- if (ISSLASH (c))
- break;
- }
- while (*p);
- }
-
- for (p = file_name + prefix_len; ISSLASH (*p); p++)
- continue;
- prefix_len = p - file_name;
-
- if (prefix_len)
- {
- char *prefix = alloca (prefix_len + 1);
- memcpy (prefix, file_name, prefix_len);
- prefix[prefix_len] = '\0';
-
- if (hash_string_insert (&prefix_table[link_target], prefix))
- {
- static char const *const diagnostic[] =
- {
- N_("Removing leading `%s' from member names"),
- N_("Removing leading `%s' from hard link targets")
- };
- WARN ((0, 0, _(diagnostic[link_target]), prefix));
- }
- }
- }
-
- if (! *p)
- {
- if (p == file_name)
- {
- static char const *const diagnostic[] =
- {
- N_("Substituting `.' for empty member name"),
- N_("Substituting `.' for empty hard link target")
- };
- WARN ((0, 0, "%s", _(diagnostic[link_target])));
- }
-
- p = ".";
- }
-
- return (char *) p;
-}
diff --git a/contrib/cpio/lib/quote.c b/contrib/cpio/lib/quote.c
deleted file mode 100644
index 119be72..0000000
--- a/contrib/cpio/lib/quote.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* quote.c - quote arguments for output
-
- Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert <eggert@twinsun.com> */
-
-#include <config.h>
-
-#include "quotearg.h"
-#include "quote.h"
-
-/* Return an unambiguous printable representation of NAME,
- allocated in slot N, suitable for diagnostics. */
-char const *
-quote_n (int n, char const *name)
-{
- return quotearg_n_style (n, locale_quoting_style, name);
-}
-
-/* Return an unambiguous printable representation of NAME,
- suitable for diagnostics. */
-char const *
-quote (char const *name)
-{
- return quote_n (0, name);
-}
diff --git a/contrib/cpio/lib/quote.h b/contrib/cpio/lib/quote.h
deleted file mode 100644
index 5400ead..0000000
--- a/contrib/cpio/lib/quote.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* quote.h - prototypes for quote.c
-
- Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software
- Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-
-char const *quote_n (int n, char const *name);
-char const *quote (char const *name);
diff --git a/contrib/cpio/lib/quotearg.c b/contrib/cpio/lib/quotearg.c
deleted file mode 100644
index f7f326a..0000000
--- a/contrib/cpio/lib/quotearg.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/* quotearg.c - quote arguments for output
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert <eggert@twinsun.com> */
-
-#include <config.h>
-
-#include "quotearg.h"
-
-#include "xalloc.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-#if !HAVE_MBRTOWC
-/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the
- other macros are defined only for documentation and to satisfy C
- syntax. */
-# undef MB_CUR_MAX
-# define MB_CUR_MAX 1
-# undef mbstate_t
-# define mbstate_t int
-# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
-# define iswprint(wc) isprint ((unsigned char) (wc))
-# undef HAVE_MBSINIT
-#endif
-
-#if !defined mbsinit && !HAVE_MBSINIT
-# define mbsinit(ps) 1
-#endif
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-#define INT_BITS (sizeof (int) * CHAR_BIT)
-
-struct quoting_options
-{
- /* Basic quoting style. */
- enum quoting_style style;
-
- /* Quote the characters indicated by this bit vector even if the
- quoting style would not normally require them to be quoted. */
- unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
-};
-
-/* Names of quoting styles. */
-char const *const quoting_style_args[] =
-{
- "literal",
- "shell",
- "shell-always",
- "c",
- "escape",
- "locale",
- "clocale",
- 0
-};
-
-/* Correspondences to quoting style names. */
-enum quoting_style const quoting_style_vals[] =
-{
- literal_quoting_style,
- shell_quoting_style,
- shell_always_quoting_style,
- c_quoting_style,
- escape_quoting_style,
- locale_quoting_style,
- clocale_quoting_style
-};
-
-/* The default quoting options. */
-static struct quoting_options default_quoting_options;
-
-/* Allocate a new set of quoting options, with contents initially identical
- to O if O is not null, or to the default if O is null.
- It is the caller's responsibility to free the result. */
-struct quoting_options *
-clone_quoting_options (struct quoting_options *o)
-{
- int e = errno;
- struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
- sizeof *o);
- errno = e;
- return p;
-}
-
-/* Get the value of O's quoting style. If O is null, use the default. */
-enum quoting_style
-get_quoting_style (struct quoting_options *o)
-{
- return (o ? o : &default_quoting_options)->style;
-}
-
-/* In O (or in the default if O is null),
- set the value of the quoting style to S. */
-void
-set_quoting_style (struct quoting_options *o, enum quoting_style s)
-{
- (o ? o : &default_quoting_options)->style = s;
-}
-
-/* In O (or in the default if O is null),
- set the value of the quoting options for character C to I.
- Return the old value. Currently, the only values defined for I are
- 0 (the default) and 1 (which means to quote the character even if
- it would not otherwise be quoted). */
-int
-set_char_quoting (struct quoting_options *o, char c, int i)
-{
- unsigned char uc = c;
- unsigned int *p =
- (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
- int shift = uc % INT_BITS;
- int r = (*p >> shift) & 1;
- *p ^= ((i & 1) ^ r) << shift;
- return r;
-}
-
-/* MSGID approximates a quotation mark. Return its translation if it
- has one; otherwise, return either it or "\"", depending on S. */
-static char const *
-gettext_quote (char const *msgid, enum quoting_style s)
-{
- char const *translation = _(msgid);
- if (translation == msgid && s == clocale_quoting_style)
- translation = "\"";
- return translation;
-}
-
-/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
- argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
- non-quoting-style part of O to control quoting.
- Terminate the output with a null character, and return the written
- size of the output, not counting the terminating null.
- If BUFFERSIZE is too small to store the output string, return the
- value that would have been returned had BUFFERSIZE been large enough.
- If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
-
- This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
- ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
- style specified by O, and O may not be null. */
-
-static size_t
-quotearg_buffer_restyled (char *buffer, size_t buffersize,
- char const *arg, size_t argsize,
- enum quoting_style quoting_style,
- struct quoting_options const *o)
-{
- size_t i;
- size_t len = 0;
- char const *quote_string = 0;
- size_t quote_string_len = 0;
- bool backslash_escapes = false;
- bool unibyte_locale = MB_CUR_MAX == 1;
-
-#define STORE(c) \
- do \
- { \
- if (len < buffersize) \
- buffer[len] = (c); \
- len++; \
- } \
- while (0)
-
- switch (quoting_style)
- {
- case c_quoting_style:
- STORE ('"');
- backslash_escapes = true;
- quote_string = "\"";
- quote_string_len = 1;
- break;
-
- case escape_quoting_style:
- backslash_escapes = true;
- break;
-
- case locale_quoting_style:
- case clocale_quoting_style:
- {
- /* TRANSLATORS:
- Get translations for open and closing quotation marks.
-
- The message catalog should translate "`" to a left
- quotation mark suitable for the locale, and similarly for
- "'". If the catalog has no translation,
- locale_quoting_style quotes `like this', and
- clocale_quoting_style quotes "like this".
-
- For example, an American English Unicode locale should
- translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
- should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
- MARK). A British English Unicode locale should instead
- translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
- U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.
-
- If you don't know what to put here, please see
- <http://en.wikipedia.org/wiki/Quotation_mark#Glyphs>
- and use glyphs suitable for your language. */
-
- char const *left = gettext_quote (N_("`"), quoting_style);
- char const *right = gettext_quote (N_("'"), quoting_style);
- for (quote_string = left; *quote_string; quote_string++)
- STORE (*quote_string);
- backslash_escapes = true;
- quote_string = right;
- quote_string_len = strlen (quote_string);
- }
- break;
-
- case shell_always_quoting_style:
- STORE ('\'');
- quote_string = "'";
- quote_string_len = 1;
- break;
-
- default:
- break;
- }
-
- for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
- {
- unsigned char c;
- unsigned char esc;
-
- if (backslash_escapes
- && quote_string_len
- && i + quote_string_len <= argsize
- && memcmp (arg + i, quote_string, quote_string_len) == 0)
- STORE ('\\');
-
- c = arg[i];
- switch (c)
- {
- case '\0':
- if (backslash_escapes)
- {
- STORE ('\\');
- STORE ('0');
- STORE ('0');
- c = '0';
- }
- break;
-
- case '?':
- switch (quoting_style)
- {
- case shell_quoting_style:
- goto use_shell_always_quoting_style;
-
- case c_quoting_style:
- if (i + 2 < argsize && arg[i + 1] == '?')
- switch (arg[i + 2])
- {
- case '!': case '\'':
- case '(': case ')': case '-': case '/':
- case '<': case '=': case '>':
- /* Escape the second '?' in what would otherwise be
- a trigraph. */
- c = arg[i + 2];
- i += 2;
- STORE ('?');
- STORE ('\\');
- STORE ('?');
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case '\a': esc = 'a'; goto c_escape;
- case '\b': esc = 'b'; goto c_escape;
- case '\f': esc = 'f'; goto c_escape;
- case '\n': esc = 'n'; goto c_and_shell_escape;
- case '\r': esc = 'r'; goto c_and_shell_escape;
- case '\t': esc = 't'; goto c_and_shell_escape;
- case '\v': esc = 'v'; goto c_escape;
- case '\\': esc = c; goto c_and_shell_escape;
-
- c_and_shell_escape:
- if (quoting_style == shell_quoting_style)
- goto use_shell_always_quoting_style;
- c_escape:
- if (backslash_escapes)
- {
- c = esc;
- goto store_escape;
- }
- break;
-
- case '{': case '}': /* sometimes special if isolated */
- if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
- break;
- /* Fall through. */
- case '#': case '~':
- if (i != 0)
- break;
- /* Fall through. */
- case ' ':
- case '!': /* special in bash */
- case '"': case '$': case '&':
- case '(': case ')': case '*': case ';':
- case '<':
- case '=': /* sometimes special in 0th or (with "set -k") later args */
- case '>': case '[':
- case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
- case '`': case '|':
- /* A shell special character. In theory, '$' and '`' could
- be the first bytes of multibyte characters, which means
- we should check them with mbrtowc, but in practice this
- doesn't happen so it's not worth worrying about. */
- if (quoting_style == shell_quoting_style)
- goto use_shell_always_quoting_style;
- break;
-
- case '\'':
- switch (quoting_style)
- {
- case shell_quoting_style:
- goto use_shell_always_quoting_style;
-
- case shell_always_quoting_style:
- STORE ('\'');
- STORE ('\\');
- STORE ('\'');
- break;
-
- default:
- break;
- }
- break;
-
- case '%': case '+': case ',': case '-': case '.': case '/':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9': case ':':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
- case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
- case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
- /* These characters don't cause problems, no matter what the
- quoting style is. They cannot start multibyte sequences. */
- break;
-
- default:
- /* If we have a multibyte sequence, copy it until we reach
- its end, find an error, or come back to the initial shift
- state. For C-like styles, if the sequence has
- unprintable characters, escape the whole sequence, since
- we can't easily escape single characters within it. */
- {
- /* Length of multibyte sequence found so far. */
- size_t m;
-
- bool printable;
-
- if (unibyte_locale)
- {
- m = 1;
- printable = isprint (c) != 0;
- }
- else
- {
- mbstate_t mbstate;
- memset (&mbstate, 0, sizeof mbstate);
-
- m = 0;
- printable = true;
- if (argsize == SIZE_MAX)
- argsize = strlen (arg);
-
- do
- {
- wchar_t w;
- size_t bytes = mbrtowc (&w, &arg[i + m],
- argsize - (i + m), &mbstate);
- if (bytes == 0)
- break;
- else if (bytes == (size_t) -1)
- {
- printable = false;
- break;
- }
- else if (bytes == (size_t) -2)
- {
- printable = false;
- while (i + m < argsize && arg[i + m])
- m++;
- break;
- }
- else
- {
- /* Work around a bug with older shells that "see" a '\'
- that is really the 2nd byte of a multibyte character.
- In practice the problem is limited to ASCII
- chars >= '@' that are shell special chars. */
- if ('[' == 0x5b && quoting_style == shell_quoting_style)
- {
- size_t j;
- for (j = 1; j < bytes; j++)
- switch (arg[i + m + j])
- {
- case '[': case '\\': case '^':
- case '`': case '|':
- goto use_shell_always_quoting_style;
-
- default:
- break;
- }
- }
-
- if (! iswprint (w))
- printable = false;
- m += bytes;
- }
- }
- while (! mbsinit (&mbstate));
- }
-
- if (1 < m || (backslash_escapes && ! printable))
- {
- /* Output a multibyte sequence, or an escaped
- unprintable unibyte character. */
- size_t ilim = i + m;
-
- for (;;)
- {
- if (backslash_escapes && ! printable)
- {
- STORE ('\\');
- STORE ('0' + (c >> 6));
- STORE ('0' + ((c >> 3) & 7));
- c = '0' + (c & 7);
- }
- if (ilim <= i + 1)
- break;
- STORE (c);
- c = arg[++i];
- }
-
- goto store_c;
- }
- }
- }
-
- if (! (backslash_escapes
- && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
- goto store_c;
-
- store_escape:
- STORE ('\\');
-
- store_c:
- STORE (c);
- }
-
- if (i == 0 && quoting_style == shell_quoting_style)
- goto use_shell_always_quoting_style;
-
- if (quote_string)
- for (; *quote_string; quote_string++)
- STORE (*quote_string);
-
- if (len < buffersize)
- buffer[len] = '\0';
- return len;
-
- use_shell_always_quoting_style:
- return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
- shell_always_quoting_style, o);
-}
-
-/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
- argument ARG (of size ARGSIZE), using O to control quoting.
- If O is null, use the default.
- Terminate the output with a null character, and return the written
- size of the output, not counting the terminating null.
- If BUFFERSIZE is too small to store the output string, return the
- value that would have been returned had BUFFERSIZE been large enough.
- If ARGSIZE is SIZE_MAX, use the string length of the argument for
- ARGSIZE. */
-size_t
-quotearg_buffer (char *buffer, size_t buffersize,
- char const *arg, size_t argsize,
- struct quoting_options const *o)
-{
- struct quoting_options const *p = o ? o : &default_quoting_options;
- int e = errno;
- size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
- p->style, p);
- errno = e;
- return r;
-}
-
-/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
- allocated storage containing the quoted string. */
-char *
-quotearg_alloc (char const *arg, size_t argsize,
- struct quoting_options const *o)
-{
- int e = errno;
- size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1;
- char *buf = xcharalloc (bufsize);
- quotearg_buffer (buf, bufsize, arg, argsize, o);
- errno = e;
- return buf;
-}
-
-/* A storage slot with size and pointer to a value. */
-struct slotvec
-{
- size_t size;
- char *val;
-};
-
-/* Preallocate a slot 0 buffer, so that the caller can always quote
- one small component of a "memory exhausted" message in slot 0. */
-static char slot0[256];
-static unsigned int nslots = 1;
-static struct slotvec slotvec0 = {sizeof slot0, slot0};
-static struct slotvec *slotvec = &slotvec0;
-
-void
-quotearg_free (void)
-{
- struct slotvec *sv = slotvec;
- unsigned int i;
- for (i = 1; i < nslots; i++)
- free (sv[i].val);
- if (sv[0].val != slot0)
- {
- free (sv[0].val);
- slotvec0.size = sizeof slot0;
- slotvec0.val = slot0;
- }
- if (sv != &slotvec0)
- {
- free (sv);
- slotvec = &slotvec0;
- }
- nslots = 1;
-}
-
-/* Use storage slot N to return a quoted version of argument ARG.
- ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
- null-terminated string.
- OPTIONS specifies the quoting options.
- The returned value points to static storage that can be
- reused by the next call to this function with the same value of N.
- N must be nonnegative. N is deliberately declared with type "int"
- to allow for future extensions (using negative values). */
-static char *
-quotearg_n_options (int n, char const *arg, size_t argsize,
- struct quoting_options const *options)
-{
- int e = errno;
-
- unsigned int n0 = n;
- struct slotvec *sv = slotvec;
-
- if (n < 0)
- abort ();
-
- if (nslots <= n0)
- {
- /* FIXME: technically, the type of n1 should be `unsigned int',
- but that evokes an unsuppressible warning from gcc-4.0.1 and
- older. If gcc ever provides an option to suppress that warning,
- revert to the original type, so that the test in xalloc_oversized
- is once again performed only at compile time. */
- size_t n1 = n0 + 1;
- bool preallocated = (sv == &slotvec0);
-
- if (xalloc_oversized (n1, sizeof *sv))
- xalloc_die ();
-
- slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
- if (preallocated)
- *sv = slotvec0;
- memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
- nslots = n1;
- }
-
- {
- size_t size = sv[n].size;
- char *val = sv[n].val;
- size_t qsize = quotearg_buffer (val, size, arg, argsize, options);
-
- if (size <= qsize)
- {
- sv[n].size = size = qsize + 1;
- if (val != slot0)
- free (val);
- sv[n].val = val = xcharalloc (size);
- quotearg_buffer (val, size, arg, argsize, options);
- }
-
- errno = e;
- return val;
- }
-}
-
-char *
-quotearg_n (int n, char const *arg)
-{
- return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
-}
-
-char *
-quotearg (char const *arg)
-{
- return quotearg_n (0, arg);
-}
-
-/* Return quoting options for STYLE, with no extra quoting. */
-static struct quoting_options
-quoting_options_from_style (enum quoting_style style)
-{
- struct quoting_options o;
- o.style = style;
- memset (o.quote_these_too, 0, sizeof o.quote_these_too);
- return o;
-}
-
-char *
-quotearg_n_style (int n, enum quoting_style s, char const *arg)
-{
- struct quoting_options const o = quoting_options_from_style (s);
- return quotearg_n_options (n, arg, SIZE_MAX, &o);
-}
-
-char *
-quotearg_n_style_mem (int n, enum quoting_style s,
- char const *arg, size_t argsize)
-{
- struct quoting_options const o = quoting_options_from_style (s);
- return quotearg_n_options (n, arg, argsize, &o);
-}
-
-char *
-quotearg_style (enum quoting_style s, char const *arg)
-{
- return quotearg_n_style (0, s, arg);
-}
-
-char *
-quotearg_char (char const *arg, char ch)
-{
- struct quoting_options options;
- options = default_quoting_options;
- set_char_quoting (&options, ch, 1);
- return quotearg_n_options (0, arg, SIZE_MAX, &options);
-}
-
-char *
-quotearg_colon (char const *arg)
-{
- return quotearg_char (arg, ':');
-}
diff --git a/contrib/cpio/lib/quotearg.h b/contrib/cpio/lib/quotearg.h
deleted file mode 100644
index 4887df3..0000000
--- a/contrib/cpio/lib/quotearg.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/* quotearg.h - quote arguments for output
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert <eggert@twinsun.com> */
-
-#ifndef QUOTEARG_H_
-# define QUOTEARG_H_ 1
-
-# include <stddef.h>
-
-/* Basic quoting styles. */
-enum quoting_style
- {
- /* Output names as-is (ls --quoting-style=literal). */
- literal_quoting_style,
-
- /* Quote names for the shell if they contain shell metacharacters
- or would cause ambiguous output (ls --quoting-style=shell). */
- shell_quoting_style,
-
- /* Quote names for the shell, even if they would normally not
- require quoting (ls --quoting-style=shell-always). */
- shell_always_quoting_style,
-
- /* Quote names as for a C language string (ls --quoting-style=c). */
- c_quoting_style,
-
- /* Like c_quoting_style except omit the surrounding double-quote
- characters (ls --quoting-style=escape). */
- escape_quoting_style,
-
- /* Like clocale_quoting_style, but quote `like this' instead of
- "like this" in the default C locale (ls --quoting-style=locale). */
- locale_quoting_style,
-
- /* Like c_quoting_style except use quotation marks appropriate for
- the locale (ls --quoting-style=clocale). */
- clocale_quoting_style
- };
-
-/* For now, --quoting-style=literal is the default, but this may change. */
-# ifndef DEFAULT_QUOTING_STYLE
-# define DEFAULT_QUOTING_STYLE literal_quoting_style
-# endif
-
-/* Names of quoting styles and their corresponding values. */
-extern char const *const quoting_style_args[];
-extern enum quoting_style const quoting_style_vals[];
-
-struct quoting_options;
-
-/* The functions listed below set and use a hidden variable
- that contains the default quoting style options. */
-
-/* Allocate a new set of quoting options, with contents initially identical
- to O if O is not null, or to the default if O is null.
- It is the caller's responsibility to free the result. */
-struct quoting_options *clone_quoting_options (struct quoting_options *o);
-
-/* Get the value of O's quoting style. If O is null, use the default. */
-enum quoting_style get_quoting_style (struct quoting_options *o);
-
-/* In O (or in the default if O is null),
- set the value of the quoting style to S. */
-void set_quoting_style (struct quoting_options *o, enum quoting_style s);
-
-/* In O (or in the default if O is null),
- set the value of the quoting options for character C to I.
- Return the old value. Currently, the only values defined for I are
- 0 (the default) and 1 (which means to quote the character even if
- it would not otherwise be quoted). */
-int set_char_quoting (struct quoting_options *o, char c, int i);
-
-/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
- argument ARG (of size ARGSIZE), using O to control quoting.
- If O is null, use the default.
- Terminate the output with a null character, and return the written
- size of the output, not counting the terminating null.
- If BUFFERSIZE is too small to store the output string, return the
- value that would have been returned had BUFFERSIZE been large enough.
- If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
-size_t quotearg_buffer (char *buffer, size_t buffersize,
- char const *arg, size_t argsize,
- struct quoting_options const *o);
-
-/* Like quotearg_buffer, except return the result in a newly allocated
- buffer. It is the caller's responsibility to free the result. */
-char *quotearg_alloc (char const *arg, size_t argsize,
- struct quoting_options const *o);
-
-/* Use storage slot N to return a quoted version of the string ARG.
- Use the default quoting options.
- The returned value points to static storage that can be
- reused by the next call to this function with the same value of N.
- N must be nonnegative. */
-char *quotearg_n (int n, char const *arg);
-
-/* Equivalent to quotearg_n (0, ARG). */
-char *quotearg (char const *arg);
-
-/* Use style S and storage slot N to return a quoted version of the string ARG.
- This is like quotearg_n (N, ARG), except that it uses S with no other
- options to specify the quoting method. */
-char *quotearg_n_style (int n, enum quoting_style s, char const *arg);
-
-/* Use style S and storage slot N to return a quoted version of the
- argument ARG of size ARGSIZE. This is like quotearg_n_style
- (N, S, ARG), except it can quote null bytes. */
-char *quotearg_n_style_mem (int n, enum quoting_style s,
- char const *arg, size_t argsize);
-
-/* Equivalent to quotearg_n_style (0, S, ARG). */
-char *quotearg_style (enum quoting_style s, char const *arg);
-
-/* Like quotearg (ARG), except also quote any instances of CH. */
-char *quotearg_char (char const *arg, char ch);
-
-/* Equivalent to quotearg_char (ARG, ':'). */
-char *quotearg_colon (char const *arg);
-
-/* Free any dynamically allocated memory. */
-void quotearg_free (void);
-
-#endif /* !QUOTEARG_H_ */
diff --git a/contrib/cpio/lib/rmt-command.h b/contrib/cpio/lib/rmt-command.h
deleted file mode 100644
index 7460e6f..0000000
--- a/contrib/cpio/lib/rmt-command.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define LOCALEDIR "/usr/local/share/locale"
-#ifndef DEFAULT_RMT_COMMAND
-# define DEFAULT_RMT_COMMAND "/usr/local/libexec/rmt"
-#endif
diff --git a/contrib/cpio/lib/rmt.h b/contrib/cpio/lib/rmt.h
deleted file mode 100644
index 9f96cdb..0000000
--- a/contrib/cpio/lib/rmt.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Definitions for communicating with a remote tape drive.
-
- Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-extern char *rmt_command;
-extern char *rmt_dev_name__;
-
-int rmt_open__ (const char *, int, int, const char *);
-int rmt_close__ (int);
-size_t rmt_read__ (int, char *, size_t);
-size_t rmt_write__ (int, char *, size_t);
-off_t rmt_lseek__ (int, off_t, int);
-int rmt_ioctl__ (int, int, char *);
-
-extern bool force_local_option;
-
-/* A filename is remote if it contains a colon not preceded by a slash,
- to take care of `/:/' which is a shorthand for `/.../<CELL-NAME>/fs'
- on machines running OSF's Distributing Computing Environment (DCE) and
- Distributed File System (DFS). However, when --force-local, a
- filename is never remote. */
-
-#define _remdev(dev_name) \
- (!force_local_option && (rmt_dev_name__ = strchr (dev_name, ':')) \
- && rmt_dev_name__ > (dev_name) \
- && ! memchr (dev_name, '/', rmt_dev_name__ - (dev_name)))
-
-#define _isrmt(fd) \
- ((fd) >= __REM_BIAS)
-
-#define __REM_BIAS (1 << 30)
-
-#ifndef O_CREAT
-# define O_CREAT 01000
-#endif
-
-#define rmtopen(dev_name, oflag, mode, command) \
- (_remdev (dev_name) ? rmt_open__ (dev_name, oflag, __REM_BIAS, command) \
- : open (dev_name, oflag, mode))
-
-#define rmtaccess(dev_name, amode) \
- (_remdev (dev_name) ? 0 : access (dev_name, amode))
-
-#define rmtstat(dev_name, buffer) \
- (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : stat (dev_name, buffer))
-
-#define rmtcreat(dev_name, mode, command) \
- (_remdev (dev_name) \
- ? rmt_open__ (dev_name, 1 | O_CREAT, __REM_BIAS, command) \
- : creat (dev_name, mode))
-
-#define rmtlstat(dev_name, muffer) \
- (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : lstat (dev_name, buffer))
-
-#define rmtread(fd, buffer, length) \
- (_isrmt (fd) ? rmt_read__ (fd - __REM_BIAS, buffer, length) \
- : safe_read (fd, buffer, length))
-
-#define rmtwrite(fd, buffer, length) \
- (_isrmt (fd) ? rmt_write__ (fd - __REM_BIAS, buffer, length) \
- : full_write (fd, buffer, length))
-
-#define rmtlseek(fd, offset, where) \
- (_isrmt (fd) ? rmt_lseek__ (fd - __REM_BIAS, offset, where) \
- : lseek (fd, offset, where))
-
-#define rmtclose(fd) \
- (_isrmt (fd) ? rmt_close__ (fd - __REM_BIAS) : close (fd))
-
-#define rmtioctl(fd, request, argument) \
- (_isrmt (fd) ? rmt_ioctl__ (fd - __REM_BIAS, request, argument) \
- : ioctl (fd, request, argument))
-
-#define rmtdup(fd) \
- (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : dup (fd))
-
-#define rmtfstat(fd, buffer) \
- (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fstat (fd, buffer))
-
-#define rmtfcntl(cd, command, argument) \
- (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fcntl (fd, command, argument))
-
-#define rmtisatty(fd) \
- (_isrmt (fd) ? 0 : isatty (fd))
diff --git a/contrib/cpio/lib/rtapelib.c b/contrib/cpio/lib/rtapelib.c
deleted file mode 100644
index af19b04..0000000
--- a/contrib/cpio/lib/rtapelib.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/* Functions for communicating with a remote tape drive.
-
- Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004,
- 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol
- which rdump and rrestore use. Unfortunately, the man page is *WRONG*.
- The author of the routines I'm including originally wrote his code just
- based on the man page, and it didn't work, so he went to the rdump source
- to figure out why. The only thing he had to change was to check for the
- 'F' return code in addition to the 'E', and to separate the various
- arguments with \n instead of a space. I personally don't think that this
- is much of a problem, but I wanted to point it out. -- Arnold Robbins
-
- Originally written by Jeff Lee, modified some by Arnold Robbins. Redone
- as a library that can replace open, read, write, etc., by Fred Fish, with
- some additional work by Arnold Robbins. Modified to make all rmt* calls
- into macros for speed by Jay Fenlason. Use -DWITH_REXEC for rexec
- code, courtesy of Dan Kegel. */
-
-#include "system.h"
-#include "system-ioctl.h"
-
-#include <safe-read.h>
-#include <full-write.h>
-
-/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h,
- 3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */
-
-#ifndef EOPNOTSUPP
-# if HAVE_NET_ERRNO_H
-# include <net/errno.h>
-# endif
-# if HAVE_SYS_INET_H
-# include <sys/inet.h>
-# endif
-# ifndef EOPNOTSUPP
-# define EOPNOTSUPP EINVAL
-# endif
-#endif
-
-#include <signal.h>
-
-#if HAVE_NETDB_H
-# include <netdb.h>
-#endif
-
-#include <rmt.h>
-#include <rmt-command.h>
-
-/* Exit status if exec errors. */
-#define EXIT_ON_EXEC_ERROR 128
-
-/* FIXME: Size of buffers for reading and writing commands to rmt. */
-#define COMMAND_BUFFER_SIZE 64
-
-#ifndef RETSIGTYPE
-# define RETSIGTYPE void
-#endif
-
-/* FIXME: Maximum number of simultaneous remote tape connections. */
-#define MAXUNIT 4
-
-#define PREAD 0 /* read file descriptor from pipe() */
-#define PWRITE 1 /* write file descriptor from pipe() */
-
-/* Return the parent's read side of remote tape connection Fd. */
-#define READ_SIDE(Fd) (from_remote[Fd][PREAD])
-
-/* Return the parent's write side of remote tape connection Fd. */
-#define WRITE_SIDE(Fd) (to_remote[Fd][PWRITE])
-
-/* The pipes for receiving data from remote tape drives. */
-static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
-
-/* The pipes for sending data to remote tape drives. */
-static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
-
-char *rmt_command = DEFAULT_RMT_COMMAND;
-
-/* Temporary variable used by macros in rmt.h. */
-char *rmt_dev_name__;
-
-/* If true, always consider file names to be local, even if they contain
- colons */
-bool force_local_option;
-
-
-
-/* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE. */
-static void
-_rmt_shutdown (int handle, int errno_value)
-{
- close (READ_SIDE (handle));
- close (WRITE_SIDE (handle));
- READ_SIDE (handle) = -1;
- WRITE_SIDE (handle) = -1;
- errno = errno_value;
-}
-
-/* Attempt to perform the remote tape command specified in BUFFER on
- remote tape connection HANDLE. Return 0 if successful, -1 on
- error. */
-static int
-do_command (int handle, const char *buffer)
-{
- /* Save the current pipe handler and try to make the request. */
-
- size_t length = strlen (buffer);
- RETSIGTYPE (*pipe_handler) () = signal (SIGPIPE, SIG_IGN);
- ssize_t written = full_write (WRITE_SIDE (handle), buffer, length);
- signal (SIGPIPE, pipe_handler);
-
- if (written == length)
- return 0;
-
- /* Something went wrong. Close down and go home. */
-
- _rmt_shutdown (handle, EIO);
- return -1;
-}
-
-static char *
-get_status_string (int handle, char *command_buffer)
-{
- char *cursor;
- int counter;
-
- /* Read the reply command line. */
-
- for (counter = 0, cursor = command_buffer;
- counter < COMMAND_BUFFER_SIZE;
- counter++, cursor++)
- {
- if (safe_read (READ_SIDE (handle), cursor, 1) != 1)
- {
- _rmt_shutdown (handle, EIO);
- return 0;
- }
- if (*cursor == '\n')
- {
- *cursor = '\0';
- break;
- }
- }
-
- if (counter == COMMAND_BUFFER_SIZE)
- {
- _rmt_shutdown (handle, EIO);
- return 0;
- }
-
- /* Check the return status. */
-
- for (cursor = command_buffer; *cursor; cursor++)
- if (*cursor != ' ')
- break;
-
- if (*cursor == 'E' || *cursor == 'F')
- {
- /* Skip the error message line. */
-
- /* FIXME: there is better to do than merely ignoring error messages
- coming from the remote end. Translate them, too... */
-
- {
- char character;
-
- while (safe_read (READ_SIDE (handle), &character, 1) == 1)
- if (character == '\n')
- break;
- }
-
- errno = atoi (cursor + 1);
-
- if (*cursor == 'F')
- _rmt_shutdown (handle, errno);
-
- return 0;
- }
-
- /* Check for mis-synced pipes. */
-
- if (*cursor != 'A')
- {
- _rmt_shutdown (handle, EIO);
- return 0;
- }
-
- /* Got an `A' (success) response. */
-
- return cursor + 1;
-}
-
-/* Read and return the status from remote tape connection HANDLE. If
- an error occurred, return -1 and set errno. */
-static long int
-get_status (int handle)
-{
- char command_buffer[COMMAND_BUFFER_SIZE];
- const char *status = get_status_string (handle, command_buffer);
- if (status)
- {
- long int result = atol (status);
- if (0 <= result)
- return result;
- errno = EIO;
- }
- return -1;
-}
-
-static off_t
-get_status_off (int handle)
-{
- char command_buffer[COMMAND_BUFFER_SIZE];
- const char *status = get_status_string (handle, command_buffer);
-
- if (! status)
- return -1;
- else
- {
- /* Parse status, taking care to check for overflow.
- We can't use standard functions,
- since off_t might be longer than long. */
-
- off_t count = 0;
- int negative;
-
- for (; *status == ' ' || *status == '\t'; status++)
- continue;
-
- negative = *status == '-';
- status += negative || *status == '+';
-
- for (;;)
- {
- int digit = *status++ - '0';
- if (9 < (unsigned) digit)
- break;
- else
- {
- off_t c10 = 10 * count;
- off_t nc = negative ? c10 - digit : c10 + digit;
- if (c10 / 10 != count || (negative ? c10 < nc : nc < c10))
- return -1;
- count = nc;
- }
- }
-
- return count;
- }
-}
-
-#if WITH_REXEC
-
-/* Execute /etc/rmt as user USER on remote system HOST using rexec.
- Return a file descriptor of a bidirectional socket for stdin and
- stdout. If USER is zero, use the current username.
-
- By default, this code is not used, since it requires that the user
- have a .netrc file in his/her home directory, or that the
- application designer be willing to have rexec prompt for login and
- password info. This may be unacceptable, and .rhosts files for use
- with rsh are much more common on BSD systems. */
-static int
-_rmt_rexec (char *host, char *user)
-{
- int saved_stdin = dup (STDIN_FILENO);
- int saved_stdout = dup (STDOUT_FILENO);
- struct servent *rexecserv;
- int result;
-
- /* When using cpio -o < filename, stdin is no longer the tty. But the
- rexec subroutine reads the login and the passwd on stdin, to allow
- remote execution of the command. So, reopen stdin and stdout on
- /dev/tty before the rexec and give them back their original value
- after. */
-
- if (! freopen ("/dev/tty", "r", stdin))
- freopen ("/dev/null", "r", stdin);
- if (! freopen ("/dev/tty", "w", stdout))
- freopen ("/dev/null", "w", stdout);
-
- if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv)
- error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available"));
-
- result = rexec (&host, rexecserv->s_port, user, 0, rmt_command, 0);
- if (fclose (stdin) == EOF)
- error (0, errno, _("stdin"));
- fdopen (saved_stdin, "r");
- if (fclose (stdout) == EOF)
- error (0, errno, _("stdout"));
- fdopen (saved_stdout, "w");
-
- return result;
-}
-
-#endif /* WITH_REXEC */
-
-/* Place into BUF a string representing OFLAG, which must be suitable
- as argument 2 of `open'. BUF must be large enough to hold the
- result. This function should generate a string that decode_oflag
- can parse. */
-static void
-encode_oflag (char *buf, int oflag)
-{
- sprintf (buf, "%d ", oflag);
-
- switch (oflag & O_ACCMODE)
- {
- case O_RDONLY: strcat (buf, "O_RDONLY"); break;
- case O_RDWR: strcat (buf, "O_RDWR"); break;
- case O_WRONLY: strcat (buf, "O_WRONLY"); break;
- default: abort ();
- }
-
-#ifdef O_APPEND
- if (oflag & O_APPEND) strcat (buf, "|O_APPEND");
-#endif
- if (oflag & O_CREAT) strcat (buf, "|O_CREAT");
-#ifdef O_DSYNC
- if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC");
-#endif
- if (oflag & O_EXCL) strcat (buf, "|O_EXCL");
-#ifdef O_LARGEFILE
- if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE");
-#endif
-#ifdef O_NOCTTY
- if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY");
-#endif
- if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK");
-#ifdef O_RSYNC
- if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC");
-#endif
-#ifdef O_SYNC
- if (oflag & O_SYNC) strcat (buf, "|O_SYNC");
-#endif
- if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC");
-}
-
-/* Open a file (a magnetic tape device?) on the system specified in
- FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'.
- OPEN_MODE is O_RDONLY, O_WRONLY, etc. If successful, return the
- remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On
- error, return -1. */
-int
-rmt_open__ (const char *file_name, int open_mode, int bias,
- const char *remote_shell)
-{
- int remote_pipe_number; /* pseudo, biased file descriptor */
- char *file_name_copy; /* copy of file_name string */
- char *remote_host; /* remote host name */
- char *remote_file; /* remote file name (often a device) */
- char *remote_user; /* remote user name */
-
- /* Find an unused pair of file descriptors. */
-
- for (remote_pipe_number = 0;
- remote_pipe_number < MAXUNIT;
- remote_pipe_number++)
- if (READ_SIDE (remote_pipe_number) == -1
- && WRITE_SIDE (remote_pipe_number) == -1)
- break;
-
- if (remote_pipe_number == MAXUNIT)
- {
- errno = EMFILE;
- return -1;
- }
-
- /* Pull apart the system and device, and optional user. */
-
- {
- char *cursor;
-
- file_name_copy = xstrdup (file_name);
- remote_host = file_name_copy;
- remote_user = 0;
- remote_file = 0;
-
- for (cursor = file_name_copy; *cursor; cursor++)
- switch (*cursor)
- {
- default:
- break;
-
- case '\n':
- /* Do not allow newlines in the file_name, since the protocol
- uses newline delimiters. */
- free (file_name_copy);
- errno = ENOENT;
- return -1;
-
- case '@':
- if (!remote_user)
- {
- remote_user = remote_host;
- *cursor = '\0';
- remote_host = cursor + 1;
- }
- break;
-
- case ':':
- if (!remote_file)
- {
- *cursor = '\0';
- remote_file = cursor + 1;
- }
- break;
- }
- }
-
- /* FIXME: Should somewhat validate the decoding, here. */
-
- if (remote_user && *remote_user == '\0')
- remote_user = 0;
-
-#if WITH_REXEC
-
- /* Execute the remote command using rexec. */
-
- READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user);
- if (READ_SIDE (remote_pipe_number) < 0)
- {
- int e = errno;
- free (file_name_copy);
- errno = e;
- return -1;
- }
-
- WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number);
-
-#else /* not WITH_REXEC */
- {
- const char *remote_shell_basename;
- pid_t status;
-
- /* Identify the remote command to be executed. */
-
- if (!remote_shell)
- {
-#ifdef REMOTE_SHELL
- remote_shell = REMOTE_SHELL;
-#else
- free (file_name_copy);
- errno = EIO;
- return -1;
-#endif
- }
- remote_shell_basename = base_name (remote_shell);
-
- /* Set up the pipes for the `rsh' command, and fork. */
-
- if (pipe (to_remote[remote_pipe_number]) == -1
- || pipe (from_remote[remote_pipe_number]) == -1)
- {
- int e = errno;
- free (file_name_copy);
- errno = e;
- return -1;
- }
-
- status = fork ();
- if (status == -1)
- {
- int e = errno;
- free (file_name_copy);
- errno = e;
- return -1;
- }
-
- if (status == 0)
- {
- /* Child. */
-
- close (STDIN_FILENO);
- dup (to_remote[remote_pipe_number][PREAD]);
- close (to_remote[remote_pipe_number][PREAD]);
- close (to_remote[remote_pipe_number][PWRITE]);
-
- close (STDOUT_FILENO);
- dup (from_remote[remote_pipe_number][PWRITE]);
- close (from_remote[remote_pipe_number][PREAD]);
- close (from_remote[remote_pipe_number][PWRITE]);
-
- sys_reset_uid_gid ();
-
- if (remote_user)
- execl (remote_shell, remote_shell_basename, remote_host,
- "-l", remote_user, rmt_command, (char *) 0);
- else
- execl (remote_shell, remote_shell_basename, remote_host,
- rmt_command, (char *) 0);
-
- /* Bad problems if we get here. */
-
- /* In a previous version, _exit was used here instead of exit. */
- error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell"));
- }
-
- /* Parent. */
-
- close (from_remote[remote_pipe_number][PWRITE]);
- close (to_remote[remote_pipe_number][PREAD]);
- }
-#endif /* not WITH_REXEC */
-
- /* Attempt to open the tape device. */
-
- {
- size_t remote_file_len = strlen (remote_file);
- char *command_buffer = xmalloc (remote_file_len + 1000);
- sprintf (command_buffer, "O%s\n", remote_file);
- encode_oflag (command_buffer + remote_file_len + 2, open_mode);
- strcat (command_buffer, "\n");
- if (do_command (remote_pipe_number, command_buffer) == -1
- || get_status (remote_pipe_number) == -1)
- {
- int e = errno;
- free (command_buffer);
- free (file_name_copy);
- _rmt_shutdown (remote_pipe_number, e);
- return -1;
- }
- free (command_buffer);
- }
-
- free (file_name_copy);
- return remote_pipe_number + bias;
-}
-
-/* Close remote tape connection HANDLE and shut down. Return 0 if
- successful, -1 on error. */
-int
-rmt_close__ (int handle)
-{
- long int status;
-
- if (do_command (handle, "C\n") == -1)
- return -1;
-
- status = get_status (handle);
- _rmt_shutdown (handle, errno);
- return status;
-}
-
-/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE.
- Return the number of bytes read on success, SAFE_READ_ERROR on error. */
-size_t
-rmt_read__ (int handle, char *buffer, size_t length)
-{
- char command_buffer[COMMAND_BUFFER_SIZE];
- size_t status;
- size_t rlen;
- size_t counter;
-
- sprintf (command_buffer, "R%lu\n", (unsigned long) length);
- if (do_command (handle, command_buffer) == -1
- || (status = get_status (handle)) == SAFE_READ_ERROR)
- return SAFE_READ_ERROR;
-
- for (counter = 0; counter < status; counter += rlen, buffer += rlen)
- {
- rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
- if (rlen == SAFE_READ_ERROR || rlen == 0)
- {
- _rmt_shutdown (handle, EIO);
- return SAFE_READ_ERROR;
- }
- }
-
- return status;
-}
-
-/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE.
- Return the number of bytes written. */
-size_t
-rmt_write__ (int handle, char *buffer, size_t length)
-{
- char command_buffer[COMMAND_BUFFER_SIZE];
- RETSIGTYPE (*pipe_handler) ();
- size_t written;
-
- sprintf (command_buffer, "W%lu\n", (unsigned long) length);
- if (do_command (handle, command_buffer) == -1)
- return 0;
-
- pipe_handler = signal (SIGPIPE, SIG_IGN);
- written = full_write (WRITE_SIDE (handle), buffer, length);
- signal (SIGPIPE, pipe_handler);
- if (written == length)
- {
- long int r = get_status (handle);
- if (r < 0)
- return 0;
- if (r == length)
- return length;
- written = r;
- }
-
- /* Write error. */
-
- _rmt_shutdown (handle, EIO);
- return written;
-}
-
-/* Perform an imitation lseek operation on remote tape connection
- HANDLE. Return the new file offset if successful, -1 if on error. */
-off_t
-rmt_lseek__ (int handle, off_t offset, int whence)
-{
- char command_buffer[COMMAND_BUFFER_SIZE];
- char operand_buffer[UINTMAX_STRSIZE_BOUND];
- uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset;
- char *p = operand_buffer + sizeof operand_buffer;
-
- *--p = 0;
- do
- *--p = '0' + (int) (u % 10);
- while ((u /= 10) != 0);
- if (offset < 0)
- *--p = '-';
-
- switch (whence)
- {
- case SEEK_SET: whence = 0; break;
- case SEEK_CUR: whence = 1; break;
- case SEEK_END: whence = 2; break;
- default: abort ();
- }
-
- sprintf (command_buffer, "L%s\n%d\n", p, whence);
-
- if (do_command (handle, command_buffer) == -1)
- return -1;
-
- return get_status_off (handle);
-}
-
-/* Perform a raw tape operation on remote tape connection HANDLE.
- Return the results of the ioctl, or -1 on error. */
-int
-rmt_ioctl__ (int handle, int operation, char *argument)
-{
- switch (operation)
- {
- default:
- errno = EOPNOTSUPP;
- return -1;
-
-#ifdef MTIOCTOP
- case MTIOCTOP:
- {
- char command_buffer[COMMAND_BUFFER_SIZE];
- char operand_buffer[UINTMAX_STRSIZE_BOUND];
- uintmax_t u = (((struct mtop *) argument)->mt_count < 0
- ? - (uintmax_t) ((struct mtop *) argument)->mt_count
- : (uintmax_t) ((struct mtop *) argument)->mt_count);
- char *p = operand_buffer + sizeof operand_buffer;
-
- *--p = 0;
- do
- *--p = '0' + (int) (u % 10);
- while ((u /= 10) != 0);
- if (((struct mtop *) argument)->mt_count < 0)
- *--p = '-';
-
- /* MTIOCTOP is the easy one. Nothing is transferred in binary. */
-
- sprintf (command_buffer, "I%d\n%s\n",
- ((struct mtop *) argument)->mt_op, p);
- if (do_command (handle, command_buffer) == -1)
- return -1;
-
- return get_status (handle);
- }
-#endif /* MTIOCTOP */
-
-#ifdef MTIOCGET
- case MTIOCGET:
- {
- ssize_t status;
- size_t counter;
-
- /* Grab the status and read it directly into the structure. This
- assumes that the status buffer is not padded and that 2 shorts
- fit in a long without any word alignment problems; i.e., the
- whole struct is contiguous. NOTE - this is probably NOT a good
- assumption. */
-
- if (do_command (handle, "S") == -1
- || (status = get_status (handle), status == -1))
- return -1;
-
- for (; status > 0; status -= counter, argument += counter)
- {
- counter = safe_read (READ_SIDE (handle), argument, status);
- if (counter == SAFE_READ_ERROR || counter == 0)
- {
- _rmt_shutdown (handle, EIO);
- return -1;
- }
- }
-
- /* Check for byte position. mt_type (or mt_model) is a small integer
- field (normally) so we will check its magnitude. If it is larger
- than 256, we will assume that the bytes are swapped and go through
- and reverse all the bytes. */
-
- if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256)
- return 0;
-
- for (counter = 0; counter < status; counter += 2)
- {
- char copy = argument[counter];
-
- argument[counter] = argument[counter + 1];
- argument[counter + 1] = copy;
- }
-
- return 0;
- }
-#endif /* MTIOCGET */
-
- }
-}
diff --git a/contrib/cpio/lib/safe-read.c b/contrib/cpio/lib/safe-read.c
deleted file mode 100644
index b7bf1d5..0000000
--- a/contrib/cpio/lib/safe-read.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* An interface to read and write that retries after interrupts.
-
- Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004, 2005, 2006 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-/* Specification. */
-#ifdef SAFE_WRITE
-# include "safe-write.h"
-#else
-# include "safe-read.h"
-#endif
-
-/* Get ssize_t. */
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <errno.h>
-
-#ifdef EINTR
-# define IS_EINTR(x) ((x) == EINTR)
-#else
-# define IS_EINTR(x) 0
-#endif
-
-#include <limits.h>
-
-#ifdef SAFE_WRITE
-# define safe_rw safe_write
-# define rw write
-#else
-# define safe_rw safe_read
-# define rw read
-# undef const
-# define const /* empty */
-#endif
-
-/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if
- interrupted. Return the actual number of bytes read(written), zero for EOF,
- or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */
-size_t
-safe_rw (int fd, void const *buf, size_t count)
-{
- /* Work around a bug in Tru64 5.1. Attempting to read more than
- INT_MAX bytes fails with errno == EINVAL. See
- <http://lists.gnu.org/archive/html/bug-gnu-utils/2002-04/msg00010.html>.
- When decreasing COUNT, keep it block-aligned. */
- enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 };
-
- for (;;)
- {
- ssize_t result = rw (fd, buf, count);
-
- if (0 <= result)
- return result;
- else if (IS_EINTR (errno))
- continue;
- else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count)
- count = BUGGY_READ_MAXIMUM;
- else
- return result;
- }
-}
diff --git a/contrib/cpio/lib/safe-read.h b/contrib/cpio/lib/safe-read.h
deleted file mode 100644
index 3451955..0000000
--- a/contrib/cpio/lib/safe-read.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* An interface to read() that retries after interrupts.
- Copyright (C) 2002, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define SAFE_READ_ERROR ((size_t) -1)
-
-/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
- Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
- upon error. */
-extern size_t safe_read (int fd, void *buf, size_t count);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/cpio/lib/safe-write.c b/contrib/cpio/lib/safe-write.c
deleted file mode 100644
index 4c375a6..0000000
--- a/contrib/cpio/lib/safe-write.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* An interface to write that retries after interrupts.
- Copyright (C) 2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#define SAFE_WRITE
-#include "safe-read.c"
diff --git a/contrib/cpio/lib/safe-write.h b/contrib/cpio/lib/safe-write.h
deleted file mode 100644
index c194636..0000000
--- a/contrib/cpio/lib/safe-write.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* An interface to write() that retries after interrupts.
- Copyright (C) 2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <stddef.h>
-
-#define SAFE_WRITE_ERROR ((size_t) -1)
-
-/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted.
- Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR
- upon error. */
-extern size_t safe_write (int fd, const void *buf, size_t count);
diff --git a/contrib/cpio/lib/savedir.c b/contrib/cpio/lib/savedir.c
deleted file mode 100644
index d930fb4..0000000
--- a/contrib/cpio/lib/savedir.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* savedir.c -- save the list of files in a directory in a string
-
- Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
- 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#include <config.h>
-
-#include "savedir.h"
-
-#include <sys/types.h>
-
-#include <errno.h>
-
-#include <dirent.h>
-#ifndef _D_EXACT_NAMLEN
-# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "openat.h"
-#include "xalloc.h"
-
-#ifndef NAME_SIZE_DEFAULT
-# define NAME_SIZE_DEFAULT 512
-#endif
-
-/* The results of opendir() in this file are not used with dirfd and fchdir,
- therefore save some unnecessary work in fchdir.c. */
-#undef opendir
-#undef closedir
-
-/* Return a freshly allocated string containing the file names
- in directory DIRP, separated by '\0' characters;
- the end is marked by two '\0' characters in a row.
- Return NULL (setting errno) if DIRP cannot be read or closed.
- If DIRP is NULL, return NULL without affecting errno. */
-
-static char *
-savedirstream (DIR *dirp)
-{
- char *name_space;
- size_t allocated = NAME_SIZE_DEFAULT;
- size_t used = 0;
- int save_errno;
-
- if (dirp == NULL)
- return NULL;
-
- name_space = xmalloc (allocated);
-
- for (;;)
- {
- struct dirent const *dp;
- char const *entry;
-
- errno = 0;
- dp = readdir (dirp);
- if (! dp)
- break;
-
- /* Skip "", ".", and "..". "" is returned by at least one buggy
- implementation: Solaris 2.4 readdir on NFS file systems. */
- entry = dp->d_name;
- if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
- {
- size_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
- if (used + entry_size < used)
- xalloc_die ();
- if (allocated <= used + entry_size)
- {
- do
- {
- if (2 * allocated < allocated)
- xalloc_die ();
- allocated *= 2;
- }
- while (allocated <= used + entry_size);
-
- name_space = xrealloc (name_space, allocated);
- }
- memcpy (name_space + used, entry, entry_size);
- used += entry_size;
- }
- }
- name_space[used] = '\0';
- save_errno = errno;
- if (closedir (dirp) != 0)
- save_errno = errno;
- if (save_errno != 0)
- {
- free (name_space);
- errno = save_errno;
- return NULL;
- }
- return name_space;
-}
-
-/* Return a freshly allocated string containing the file names
- in directory DIR, separated by '\0' characters;
- the end is marked by two '\0' characters in a row.
- Return NULL (setting errno) if DIR cannot be opened, read, or closed. */
-
-char *
-savedir (char const *dir)
-{
- return savedirstream (opendir (dir));
-}
-
-/* Return a freshly allocated string containing the file names
- in directory FD, separated by '\0' characters;
- the end is marked by two '\0' characters in a row.
- Return NULL (setting errno) if FD cannot be read or closed. */
-
-char *
-fdsavedir (int fd)
-{
- return savedirstream (fdopendir (fd));
-}
diff --git a/contrib/cpio/lib/savedir.h b/contrib/cpio/lib/savedir.h
deleted file mode 100644
index 5b7bef9..0000000
--- a/contrib/cpio/lib/savedir.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Save the list of files in a directory in a string.
-
- Copyright (C) 1997, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#if !defined SAVEDIR_H_
-# define SAVEDIR_H_
-
-char *savedir (char const *dir);
-char *fdsavedir (int fd);
-
-#endif
diff --git a/contrib/cpio/lib/strchrnul.c b/contrib/cpio/lib/strchrnul.c
deleted file mode 100644
index 07014be..0000000
--- a/contrib/cpio/lib/strchrnul.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Searching in a string.
- Copyright (C) 2003, 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-/* Specification. */
-#include <string.h>
-
-/* Find the first occurrence of C in S or the final NUL byte. */
-char *
-strchrnul (const char *s, int c_in)
-{
- char c = c_in;
- while (*s && (*s != c))
- s++;
-
- return (char *) s;
-}
diff --git a/contrib/cpio/lib/stripslash.c b/contrib/cpio/lib/stripslash.c
deleted file mode 100644
index 342d497..0000000
--- a/contrib/cpio/lib/stripslash.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* stripslash.c -- remove redundant trailing slashes from a file name
-
- Copyright (C) 1990, 2001, 2003-2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include "dirname.h"
-
-/* Remove trailing slashes from FILE. Return true if a trailing slash
- was removed. This is useful when using file name completion from a
- shell that adds a "/" after directory names (such as tcsh and
- bash), because on symlinks to directories, several system calls
- have different semantics according to whether a trailing slash is
- present. */
-
-bool
-strip_trailing_slashes (char *file)
-{
- char *base = last_component (file);
- char *base_lim;
- bool had_slash;
-
- /* last_component returns "" for file system roots, but we need to turn
- `///' into `/'. */
- if (! *base)
- base = file;
- base_lim = base + base_len (base);
- had_slash = (*base_lim != '\0');
- *base_lim = '\0';
- return had_slash;
-}
diff --git a/contrib/cpio/lib/strndup.c b/contrib/cpio/lib/strndup.c
deleted file mode 100644
index 3a1b0ea..0000000
--- a/contrib/cpio/lib/strndup.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* A replacement function, for systems that lack strndup.
-
- Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <stdlib.h>
-
-char *
-strndup (char const *s, size_t n)
-{
- size_t len = strnlen (s, n);
- char *new = malloc (len + 1);
-
- if (new == NULL)
- return NULL;
-
- new[len] = '\0';
- return memcpy (new, s, len);
-}
diff --git a/contrib/cpio/lib/strnlen.c b/contrib/cpio/lib/strnlen.c
deleted file mode 100644
index d346d32..0000000
--- a/contrib/cpio/lib/strnlen.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Find the length of STRING, but scan at most MAXLEN characters.
- Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
- Written by Simon Josefsson.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include <string.h>
-
-/* Find the length of STRING, but scan at most MAXLEN characters.
- If no '\0' terminator is found in that many characters, return MAXLEN. */
-
-size_t
-strnlen (const char *string, size_t maxlen)
-{
- const char *end = memchr (string, '\0', maxlen);
- return end ? (size_t) (end - string) : maxlen;
-}
diff --git a/contrib/cpio/lib/system-ioctl.h b/contrib/cpio/lib/system-ioctl.h
deleted file mode 100644
index a61c5fd..0000000
--- a/contrib/cpio/lib/system-ioctl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* System dependent definitions for GNU tar's use of ioctl macros.
-
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
- 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses
- <sys/gentape.h>. SCO and BSDi uses <sys/tape.h>; BSDi also requires
- <sys/tprintf.h> and <sys/device.h> for defining tp_dev and tpr_t. It
- seems that the rest use <sys/mtio.h>, which itself requires other files,
- depending on systems. Pyramid defines _IOW in <sgtty.h>, for example. */
-
-#if HAVE_SYS_GENTAPE_H
-# include <sys/gentape.h>
-#else
-# if HAVE_SYS_TAPE_H
-# if HAVE_SYS_DEVICE_H
-# include <sys/device.h>
-# endif
-# if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-# endif
-# if HAVE_SYS_BUF_H
-# include <sys/buf.h>
-# endif
-# if HAVE_SYS_TPRINTF_H
-# include <sys/tprintf.h>
-# endif
-# include <sys/tape.h>
-# else
-# if HAVE_SYS_MTIO_H
-# include <sys/ioctl.h>
-# if HAVE_SGTTY_H
-# include <sgtty.h>
-# endif
-# if HAVE_SYS_IO_TRIOCTL_H
-# include <sys/io/trioctl.h>
-# endif
-# include <sys/mtio.h>
-# endif
-# endif
-#endif
diff --git a/contrib/cpio/lib/system.h b/contrib/cpio/lib/system.h
deleted file mode 100644
index 7602263..0000000
--- a/contrib/cpio/lib/system.h
+++ /dev/null
@@ -1,475 +0,0 @@
-/* System dependent definitions for GNU tar.
-
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
- 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <alloca.h>
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
-# define __attribute__(spec) /* empty */
-# endif
-#endif
-
-#include <sys/types.h>
-#include <ctype.h>
-
-/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
- as an argument to <ctype.h> macros like `isspace'. */
-#if STDC_HEADERS
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)
-#endif
-
-#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
-#define ISODIGIT(c) ((unsigned) (c) - '0' <= 7)
-#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
-#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
-
-/* Declare string and memory handling routines. Take care that an ANSI
- string.h and pre-ANSI memory.h might conflict, and that memory.h and
- strings.h conflict on some systems. */
-
-#if STDC_HEADERS || HAVE_STRING_H
-# include <string.h>
-# if !STDC_HEADERS && HAVE_MEMORY_H
-# include <memory.h>
-# endif
-#else
-# include <strings.h>
-# ifndef strchr
-# define strchr index
-# endif
-# ifndef strrchr
-# define strrchr rindex
-# endif
-# ifndef memcpy
-# define memcpy(d, s, n) bcopy ((char const *) (s), (char *) (d), n)
-# endif
-# ifndef memcmp
-# define memcmp(a, b, n) bcmp ((char const *) (a), (char const *) (b), n)
-# endif
-#endif
-
-/* Declare errno. */
-
-#include <errno.h>
-#ifndef errno
-extern int errno;
-#endif
-
-/* Declare open parameters. */
-
-#if HAVE_FCNTL_H
-# include <fcntl.h>
-#else
-# include <sys/file.h>
-#endif
- /* Pick only one of the next three: */
-#ifndef O_RDONLY
-# define O_RDONLY 0 /* only allow read */
-#endif
-#ifndef O_WRONLY
-# define O_WRONLY 1 /* only allow write */
-#endif
-#ifndef O_RDWR
-# define O_RDWR 2 /* both are allowed */
-#endif
-#ifndef O_ACCMODE
-# define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY)
-#endif
- /* The rest can be OR-ed in to the above: */
-#ifndef O_CREAT
-# define O_CREAT 8 /* create file if needed */
-#endif
-#ifndef O_EXCL
-# define O_EXCL 16 /* file cannot already exist */
-#endif
-#ifndef O_TRUNC
-# define O_TRUNC 32 /* truncate file on open */
-#endif
-
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-#ifndef O_DIRECTORY
-# define O_DIRECTORY 0
-#endif
-#ifndef O_NOATIME
-# define O_NOATIME 0
-#endif
-#ifndef O_NONBLOCK
-# define O_NONBLOCK 0
-#endif
-
-/* Declare file status routines and bits. */
-
-#include <sys/stat.h>
-
-#if !HAVE_LSTAT && !defined lstat
-# define lstat stat
-#endif
-
-#if STX_HIDDEN && !_LARGE_FILES /* AIX */
-# ifdef stat
-# undef stat
-# endif
-# define stat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN)
-# ifdef lstat
-# undef lstat
-# endif
-# define lstat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN | STX_LINK)
-#endif
-
-#if STAT_MACROS_BROKEN
-# undef S_ISBLK
-# undef S_ISCHR
-# undef S_ISCTG
-# undef S_ISDIR
-# undef S_ISFIFO
-# undef S_ISLNK
-# undef S_ISREG
-# undef S_ISSOCK
-#endif
-
-/* On MSDOS, there are missing things from <sys/stat.h>. */
-#if MSDOS
-# define S_ISUID 0
-# define S_ISGID 0
-# define S_ISVTX 0
-#endif
-
-#ifndef S_ISDIR
-# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#endif
-#ifndef S_ISREG
-# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef S_ISBLK
-# ifdef S_IFBLK
-# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
-# else
-# define S_ISBLK(mode) 0
-# endif
-#endif
-#ifndef S_ISCHR
-# ifdef S_IFCHR
-# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
-# else
-# define S_ISCHR(mode) 0
-# endif
-#endif
-#ifndef S_ISCTG
-# ifdef S_IFCTG
-# define S_ISCTG(mode) (((mode) & S_IFMT) == S_IFCTG)
-# else
-# define S_ISCTG(mode) 0
-# endif
-#endif
-#ifndef S_ISDOOR
-# define S_ISDOOR(mode) 0
-#endif
-#ifndef S_ISFIFO
-# ifdef S_IFIFO
-# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
-# else
-# define S_ISFIFO(mode) 0
-# endif
-#endif
-#ifndef S_ISLNK
-# ifdef S_IFLNK
-# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
-# else
-# define S_ISLNK(mode) 0
-# endif
-#endif
-#ifndef S_ISSOCK
-# ifdef S_IFSOCK
-# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
-# else
-# define S_ISSOCK(mode) 0
-# endif
-#endif
-
-#if !HAVE_MKFIFO && !defined mkfifo && defined S_IFIFO
-# define mkfifo(file_name, mode) (mknod (file_name, (mode) | S_IFIFO, 0))
-#endif
-
-#ifndef S_ISUID
-# define S_ISUID 0004000
-#endif
-#ifndef S_ISGID
-# define S_ISGID 0002000
-#endif
-#ifndef S_ISVTX
-# define S_ISVTX 0001000
-#endif
-#ifndef S_IRUSR
-# define S_IRUSR 0000400
-#endif
-#ifndef S_IWUSR
-# define S_IWUSR 0000200
-#endif
-#ifndef S_IXUSR
-# define S_IXUSR 0000100
-#endif
-#ifndef S_IRGRP
-# define S_IRGRP 0000040
-#endif
-#ifndef S_IWGRP
-# define S_IWGRP 0000020
-#endif
-#ifndef S_IXGRP
-# define S_IXGRP 0000010
-#endif
-#ifndef S_IROTH
-# define S_IROTH 0000004
-#endif
-#ifndef S_IWOTH
-# define S_IWOTH 0000002
-#endif
-#ifndef S_IXOTH
-# define S_IXOTH 0000001
-#endif
-
-#define MODE_WXUSR (S_IWUSR | S_IXUSR)
-#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
-#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
-#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
-#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
-
-/* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */
-#include <unistd.h>
-
-#ifndef SEEK_SET
-# define SEEK_SET 0
-#endif
-#ifndef SEEK_CUR
-# define SEEK_CUR 1
-#endif
-#ifndef SEEK_END
-# define SEEK_END 2
-#endif
-
-#ifndef STDIN_FILENO
-# define STDIN_FILENO 0
-#endif
-#ifndef STDOUT_FILENO
-# define STDOUT_FILENO 1
-#endif
-#ifndef STDERR_FILENO
-# define STDERR_FILENO 2
-#endif
-
-/* Declare make device, major and minor. Since major is a function on
- SVR4, we have to resort to GOT_MAJOR instead of just testing if
- major is #define'd. */
-
-#if MAJOR_IN_MKDEV
-# include <sys/mkdev.h>
-# if !defined(makedev) && defined(mkdev)
-# define makedev(a,b) mkdev((a),(b))
-# endif
-# define GOT_MAJOR
-#endif
-
-#if MAJOR_IN_SYSMACROS
-# include <sys/sysmacros.h>
-# define GOT_MAJOR
-#endif
-
-/* Some <sys/types.h> defines the macros. */
-#ifdef major
-# define GOT_MAJOR
-#endif
-
-#ifndef GOT_MAJOR
-# if MSDOS
-# define major(device) (device)
-# define minor(device) (device)
-# define makedev(major, minor) (((major) << 8) | (minor))
-# define GOT_MAJOR
-# endif
-#endif
-
-/* For HP-UX before HP-UX 8, major/minor are not in <sys/sysmacros.h>. */
-#ifndef GOT_MAJOR
-# if defined(hpux) || defined(__hpux__) || defined(__hpux)
-# include <sys/mknod.h>
-# define GOT_MAJOR
-# endif
-#endif
-
-#ifndef GOT_MAJOR
-# define major(device) (((device) >> 8) & 0xff)
-# define minor(device) ((device) & 0xff)
-# define makedev(major, minor) (((major) << 8) | (minor))
-#endif
-
-#undef GOT_MAJOR
-
-/* Declare wait status. */
-
-#if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(s) (((s) >> 8) & 0xff)
-#endif
-#ifndef WIFSIGNALED
-# define WIFSIGNALED(s) (((s) & 0xffff) - 1 < (unsigned) 0xff)
-#endif
-#ifndef WTERMSIG
-# define WTERMSIG(s) ((s) & 0x7f)
-#endif
-
-/* FIXME: It is wrong to use BLOCKSIZE for buffers when the logical block
- size is greater than 512 bytes; so ST_BLKSIZE code below, in preparation
- for some cleanup in this area, later. */
-
-/* Extract or fake data from a `struct stat'. ST_BLKSIZE gives the
- optimal I/O blocksize for the file, in bytes. Some systems, like
- Sequents, return st_blksize of 0 on pipes. */
-
-#define DEFAULT_ST_BLKSIZE 512
-
-#if !HAVE_ST_BLKSIZE
-# define ST_BLKSIZE(statbuf) DEFAULT_ST_BLKSIZE
-#else
-# define ST_BLKSIZE(statbuf) \
- ((statbuf).st_blksize > 0 ? (statbuf).st_blksize : DEFAULT_ST_BLKSIZE)
-#endif
-
-/* Extract or fake data from a `struct stat'. ST_NBLOCKS gives the
- number of ST_NBLOCKSIZE-byte blocks in the file (including indirect blocks).
- HP-UX counts st_blocks in 1024-byte units,
- this loses when mixing HP-UX and BSD filesystems with NFS. AIX PS/2
- counts st_blocks in 4K units. */
-
-#if !HAVE_ST_BLOCKS
-# if defined(_POSIX_SOURCE) || !defined(BSIZE)
-# define ST_NBLOCKS(statbuf) ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0))
-# else
- off_t st_blocks ();
-# define ST_NBLOCKS(statbuf) (st_blocks ((statbuf).st_size))
-# endif
-#else
-# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
-# if defined(hpux) || defined(__hpux__) || defined(__hpux)
-# define ST_NBLOCKSIZE 1024
-# else
-# if defined(_AIX) && defined(_I386)
-# define ST_NBLOCKSIZE (4 * 1024)
-# endif
-# endif
-#endif
-
-#ifndef ST_NBLOCKSIZE
-# define ST_NBLOCKSIZE 512
-#endif
-
-#define ST_IS_SPARSE(st) \
- (ST_NBLOCKS (st) \
- < ((st).st_size / ST_NBLOCKSIZE + ((st).st_size % ST_NBLOCKSIZE != 0)))
-
-/* Declare standard functions. */
-
-#if STDC_HEADERS
-# include <stdlib.h>
-#else
-void *malloc ();
-char *getenv ();
-#endif
-
-#include <stdbool.h>
-#include <stddef.h>
-
-#include <stdio.h>
-#if !defined _POSIX_VERSION && MSDOS
-# include <io.h>
-#endif
-
-#if WITH_DMALLOC
-# define DMALLOC_FUNC_CHECK
-# include <dmalloc.h>
-#endif
-
-#include <limits.h>
-
-#ifndef MB_LEN_MAX
-# define MB_LEN_MAX 1
-#endif
-
-#include <inttypes.h>
-
-#include <intprops.h>
-
-#define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND (uintmax_t)
-
-/* Prototypes for external functions. */
-
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-#if !HAVE_SETLOCALE
-# define setlocale(category, locale) /* empty */
-#endif
-
-#include <time.h>
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-#endif
-
-/* Library modules. */
-
-#include <dirname.h>
-#include <error.h>
-#include <savedir.h>
-#include <unlocked-io.h>
-#include <xalloc.h>
-
-#include <gettext.h>
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-#if MSDOS
-# include <process.h>
-# define SET_BINARY_MODE(arc) setmode(arc, O_BINARY)
-# define ERRNO_IS_EACCES errno == EACCES
-# define mkdir(file, mode) (mkdir) (file)
-# define TTY_NAME "con"
-# define sys_reset_uid_gid()
-#else
-# include <pwd.h>
-# include <grp.h>
-# define SET_BINARY_MODE(arc)
-# define ERRNO_IS_EACCES 0
-# define TTY_NAME "/dev/tty"
-# define sys_reset_uid_gid() \
- do { setuid (getuid ()); setgid (getgid ()); } while (0)
-#endif
-
-#if XENIX
-# include <sys/inode.h>
-#endif
diff --git a/contrib/cpio/lib/umaxtostr.c b/contrib/cpio/lib/umaxtostr.c
deleted file mode 100644
index 4f49a7f..0000000
--- a/contrib/cpio/lib/umaxtostr.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#define inttostr umaxtostr
-#define inttype uintmax_t
-#include "inttostr.c"
diff --git a/contrib/cpio/lib/unlocked-io.h b/contrib/cpio/lib/unlocked-io.h
deleted file mode 100644
index d009303..0000000
--- a/contrib/cpio/lib/unlocked-io.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Prefer faster, non-thread-safe stdio functions if available.
-
- Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Jim Meyering. */
-
-#ifndef UNLOCKED_IO_H
-# define UNLOCKED_IO_H 1
-
-/* These are wrappers for functions/macros from the GNU C library, and
- from other C libraries supporting POSIX's optional thread-safe functions.
-
- The standard I/O functions are thread-safe. These *_unlocked ones are
- more efficient but not thread-safe. That they're not thread-safe is
- fine since all of the applications in this package are single threaded.
-
- Also, some code that is shared with the GNU C library may invoke
- the *_unlocked functions directly. On hosts that lack those
- functions, invoke the non-thread-safe versions instead. */
-
-# include <stdio.h>
-
-# if HAVE_DECL_CLEARERR_UNLOCKED
-# undef clearerr
-# define clearerr(x) clearerr_unlocked (x)
-# else
-# define clearerr_unlocked(x) clearerr (x)
-# endif
-
-# if HAVE_DECL_FEOF_UNLOCKED
-# undef feof
-# define feof(x) feof_unlocked (x)
-# else
-# define feof_unlocked(x) feof (x)
-# endif
-
-# if HAVE_DECL_FERROR_UNLOCKED
-# undef ferror
-# define ferror(x) ferror_unlocked (x)
-# else
-# define ferror_unlocked(x) ferror (x)
-# endif
-
-# if HAVE_DECL_FFLUSH_UNLOCKED
-# undef fflush
-# define fflush(x) fflush_unlocked (x)
-# else
-# define fflush_unlocked(x) fflush (x)
-# endif
-
-# if HAVE_DECL_FGETS_UNLOCKED
-# undef fgets
-# define fgets(x,y,z) fgets_unlocked (x,y,z)
-# else
-# define fgets_unlocked(x,y,z) fgets (x,y,z)
-# endif
-
-# if HAVE_DECL_FPUTC_UNLOCKED
-# undef fputc
-# define fputc(x,y) fputc_unlocked (x,y)
-# else
-# define fputc_unlocked(x,y) fputc (x,y)
-# endif
-
-# if HAVE_DECL_FPUTS_UNLOCKED
-# undef fputs
-# define fputs(x,y) fputs_unlocked (x,y)
-# else
-# define fputs_unlocked(x,y) fputs (x,y)
-# endif
-
-# if HAVE_DECL_FREAD_UNLOCKED
-# undef fread
-# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
-# else
-# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
-# endif
-
-# if HAVE_DECL_FWRITE_UNLOCKED
-# undef fwrite
-# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
-# else
-# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
-# endif
-
-# if HAVE_DECL_GETC_UNLOCKED
-# undef getc
-# define getc(x) getc_unlocked (x)
-# else
-# define getc_unlocked(x) getc (x)
-# endif
-
-# if HAVE_DECL_GETCHAR_UNLOCKED
-# undef getchar
-# define getchar() getchar_unlocked ()
-# else
-# define getchar_unlocked() getchar ()
-# endif
-
-# if HAVE_DECL_PUTC_UNLOCKED
-# undef putc
-# define putc(x,y) putc_unlocked (x,y)
-# else
-# define putc_unlocked(x,y) putc (x,y)
-# endif
-
-# if HAVE_DECL_PUTCHAR_UNLOCKED
-# undef putchar
-# define putchar(x) putchar_unlocked (x)
-# else
-# define putchar_unlocked(x) putchar (x)
-# endif
-
-# undef flockfile
-# define flockfile(x) ((void) 0)
-
-# undef ftrylockfile
-# define ftrylockfile(x) 0
-
-# undef funlockfile
-# define funlockfile(x) ((void) 0)
-
-#endif /* UNLOCKED_IO_H */
diff --git a/contrib/cpio/lib/utimens.c b/contrib/cpio/lib/utimens.c
deleted file mode 100644
index 7e3175a..0000000
--- a/contrib/cpio/lib/utimens.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Set file access and modification times.
-
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software
- Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert. */
-
-/* derived from a function in touch.c */
-
-#include <config.h>
-
-#include "utimens.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#if HAVE_UTIME_H
-# include <utime.h>
-#endif
-
-/* Some systems (even some that do have <utime.h>) don't declare this
- structure anywhere. */
-#ifndef HAVE_STRUCT_UTIMBUF
-struct utimbuf
-{
- long actime;
- long modtime;
-};
-#endif
-
-/* Some systems don't have ENOSYS. */
-#ifndef ENOSYS
-# ifdef ENOTSUP
-# define ENOSYS ENOTSUP
-# else
-/* Some systems don't have ENOTSUP either. */
-# define ENOSYS EINVAL
-# endif
-#endif
-
-#ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-# endif
-#endif
-
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
-
-/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
- TIMESPEC[0] and TIMESPEC[1], respectively.
- FD must be either negative -- in which case it is ignored --
- or a file descriptor that is open on FILE.
- If FD is nonnegative, then FILE can be NULL, which means
- use just futimes (or equivalent) instead of utimes (or equivalent),
- and fail if on an old system without futimes (or equivalent).
- If TIMESPEC is null, set the time stamps to the current time.
- Return 0 on success, -1 (setting errno) on failure. */
-
-int
-gl_futimens (int fd ATTRIBUTE_UNUSED,
- char const *file, struct timespec const timespec[2])
-{
- /* Some Linux-based NFS clients are buggy, and mishandle time stamps
- of files in NFS file systems in some cases. We have no
- configure-time test for this, but please see
- <http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
- some of the problems with Linux 2.6.16. If this affects you,
- compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
- help in some cases, albeit at a cost in performance. But you
- really should upgrade your kernel to a fixed version, since the
- problem affects many applications. */
-
-#if HAVE_BUGGY_NFS_TIME_STAMPS
- if (fd < 0)
- sync ();
- else
- fsync (fd);
-#endif
-
- /* There's currently no interface to set file timestamps with
- nanosecond resolution, so do the best we can, discarding any
- fractional part of the timestamp. */
-#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
- struct timeval timeval[2];
- struct timeval const *t;
- if (timespec)
- {
- timeval[0].tv_sec = timespec[0].tv_sec;
- timeval[0].tv_usec = timespec[0].tv_nsec / 1000;
- timeval[1].tv_sec = timespec[1].tv_sec;
- timeval[1].tv_usec = timespec[1].tv_nsec / 1000;
- t = timeval;
- }
- else
- t = NULL;
-
-
- if (fd < 0)
- {
-# if HAVE_FUTIMESAT
- return futimesat (AT_FDCWD, file, t);
-# endif
- }
- else
- {
- /* If futimesat or futimes fails here, don't try to speed things
- up by returning right away. glibc can incorrectly fail with
- errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0
- in high security mode doesn't allow ordinary users to read
- /proc/self, so glibc incorrectly fails with errno == EACCES.
- If errno == EIO, EPERM, or EROFS, it's probably safe to fail
- right away, but these cases are rare enough that they're not
- worth optimizing, and who knows what other messed-up systems
- are out there? So play it safe and fall back on the code
- below. */
-# if HAVE_FUTIMESAT
- if (futimesat (fd, NULL, t) == 0)
- return 0;
-# elif HAVE_FUTIMES
- if (futimes (fd, t) == 0)
- return 0;
-# endif
- }
-#endif
-
- if (!file)
- {
-#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
- errno = ENOSYS;
-#endif
-
- /* Prefer EBADF to ENOSYS if both error numbers apply. */
- if (errno == ENOSYS)
- {
- int fd2 = dup (fd);
- int dup_errno = errno;
- if (0 <= fd2)
- close (fd2);
- errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS);
- }
-
- return -1;
- }
-
-#if HAVE_WORKING_UTIMES
- return utimes (file, t);
-#else
- {
- struct utimbuf utimbuf;
- struct utimbuf const *ut;
- if (timespec)
- {
- utimbuf.actime = timespec[0].tv_sec;
- utimbuf.modtime = timespec[1].tv_sec;
- ut = &utimbuf;
- }
- else
- ut = NULL;
-
- return utime (file, ut);
- }
-#endif
-}
-
-/* Set the access and modification time stamps of FILE to be
- TIMESPEC[0] and TIMESPEC[1], respectively. */
-int
-utimens (char const *file, struct timespec const timespec[2])
-{
- return gl_futimens (-1, file, timespec);
-}
diff --git a/contrib/cpio/lib/utimens.h b/contrib/cpio/lib/utimens.h
deleted file mode 100644
index 169521d..0000000
--- a/contrib/cpio/lib/utimens.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <time.h>
-int gl_futimens (int, char const *, struct timespec const [2]);
-int utimens (char const *, struct timespec const [2]);
diff --git a/contrib/cpio/lib/xalloc-die.c b/contrib/cpio/lib/xalloc-die.c
deleted file mode 100644
index 090f060..0000000
--- a/contrib/cpio/lib/xalloc-die.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Report a memory allocation failure and exit.
-
- Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2006 Free
- Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#include "xalloc.h"
-
-#include <stdlib.h>
-
-#include "error.h"
-#include "exitfail.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-void
-xalloc_die (void)
-{
- error (exit_failure, 0, "%s", _("memory exhausted"));
-
- /* The `noreturn' cannot be given to error, since it may return if
- its first argument is 0. To help compilers understand the
- xalloc_die does not return, call abort. Also, the abort is a
- safety feature if exit_failure is 0 (which shouldn't happen). */
- abort ();
-}
diff --git a/contrib/cpio/lib/xalloc.h b/contrib/cpio/lib/xalloc.h
deleted file mode 100644
index 0c6d8dc..0000000
--- a/contrib/cpio/lib/xalloc.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/* xalloc.h -- malloc with out-of-memory checking
-
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef XALLOC_H_
-# define XALLOC_H_
-
-# include <stddef.h>
-
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-
-# ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-# endif
-# endif
-
-# ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
-# endif
-
-/* This function is always triggered when memory is exhausted.
- It must be defined by the application, either explicitly
- or by using gnulib's xalloc-die module. This is the
- function to call when one wants the program to die because of a
- memory allocation failure. */
-extern void xalloc_die (void) ATTRIBUTE_NORETURN;
-
-void *xmalloc (size_t s);
-void *xzalloc (size_t s);
-void *xcalloc (size_t n, size_t s);
-void *xrealloc (void *p, size_t s);
-void *x2realloc (void *p, size_t *pn);
-void *xmemdup (void const *p, size_t s);
-char *xstrdup (char const *str);
-
-/* Return 1 if an array of N objects, each of size S, cannot exist due
- to size arithmetic overflow. S must be positive and N must be
- nonnegative. This is a macro, not an inline function, so that it
- works correctly even when SIZE_MAX < N.
-
- By gnulib convention, SIZE_MAX represents overflow in size
- calculations, so the conservative dividend to use here is
- SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
- However, malloc (SIZE_MAX) fails on all known hosts where
- sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
- exactly-SIZE_MAX allocations on such hosts; this avoids a test and
- branch when S is known to be 1. */
-# define xalloc_oversized(n, s) \
- ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
-
-
-/* In the following macros, T must be an elementary or structure/union or
- typedef'ed type, or a pointer to such a type. To apply one of the
- following macros to a function pointer or array type, you need to typedef
- it first and use the typedef name. */
-
-/* Allocate an object of type T dynamically, with error checking. */
-/* extern t *XMALLOC (typename t); */
-# define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
-
-/* Allocate memory for N elements of type T, with error checking. */
-/* extern t *XNMALLOC (size_t n, typename t); */
-# define XNMALLOC(n, t) \
- ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
-
-/* Allocate an object of type T dynamically, with error checking,
- and zero it. */
-/* extern t *XZALLOC (typename t); */
-# define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
-
-/* Allocate memory for N elements of type T, with error checking,
- and zero it. */
-/* extern t *XCALLOC (size_t n, typename t); */
-# define XCALLOC(n, t) \
- ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
-
-
-# if HAVE_INLINE
-# define static_inline static inline
-# else
- void *xnmalloc (size_t n, size_t s);
- void *xnrealloc (void *p, size_t n, size_t s);
- void *x2nrealloc (void *p, size_t *pn, size_t s);
- char *xcharalloc (size_t n);
-# endif
-
-# ifdef static_inline
-
-/* Allocate an array of N objects, each with S bytes of memory,
- dynamically, with error checking. S must be nonzero. */
-
-static_inline void *
-xnmalloc (size_t n, size_t s)
-{
- if (xalloc_oversized (n, s))
- xalloc_die ();
- return xmalloc (n * s);
-}
-
-/* Change the size of an allocated block of memory P to an array of N
- objects each of S bytes, with error checking. S must be nonzero. */
-
-static_inline void *
-xnrealloc (void *p, size_t n, size_t s)
-{
- if (xalloc_oversized (n, s))
- xalloc_die ();
- return xrealloc (p, n * s);
-}
-
-/* If P is null, allocate a block of at least *PN such objects;
- otherwise, reallocate P so that it contains more than *PN objects
- each of S bytes. *PN must be nonzero unless P is null, and S must
- be nonzero. Set *PN to the new number of objects, and return the
- pointer to the new block. *PN is never set to zero, and the
- returned pointer is never null.
-
- Repeated reallocations are guaranteed to make progress, either by
- allocating an initial block with a nonzero size, or by allocating a
- larger block.
-
- In the following implementation, nonzero sizes are increased by a
- factor of approximately 1.5 so that repeated reallocations have
- O(N) overall cost rather than O(N**2) cost, but the
- specification for this function does not guarantee that rate.
-
- Here is an example of use:
-
- int *p = NULL;
- size_t used = 0;
- size_t allocated = 0;
-
- void
- append_int (int value)
- {
- if (used == allocated)
- p = x2nrealloc (p, &allocated, sizeof *p);
- p[used++] = value;
- }
-
- This causes x2nrealloc to allocate a block of some nonzero size the
- first time it is called.
-
- To have finer-grained control over the initial size, set *PN to a
- nonzero value before calling this function with P == NULL. For
- example:
-
- int *p = NULL;
- size_t used = 0;
- size_t allocated = 0;
- size_t allocated1 = 1000;
-
- void
- append_int (int value)
- {
- if (used == allocated)
- {
- p = x2nrealloc (p, &allocated1, sizeof *p);
- allocated = allocated1;
- }
- p[used++] = value;
- }
-
- */
-
-static_inline void *
-x2nrealloc (void *p, size_t *pn, size_t s)
-{
- size_t n = *pn;
-
- if (! p)
- {
- if (! n)
- {
- /* The approximate size to use for initial small allocation
- requests, when the invoking code specifies an old size of
- zero. 64 bytes is the largest "small" request for the
- GNU C library malloc. */
- enum { DEFAULT_MXFAST = 64 };
-
- n = DEFAULT_MXFAST / s;
- n += !n;
- }
- }
- else
- {
- /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
- Check for overflow, so that N * S stays in size_t range.
- The check is slightly conservative, but an exact check isn't
- worth the trouble. */
- if ((size_t) -1 / 3 * 2 / s <= n)
- xalloc_die ();
- n += (n + 1) / 2;
- }
-
- *pn = n;
- return xrealloc (p, n * s);
-}
-
-/* Return a pointer to a new buffer of N bytes. This is like xmalloc,
- except it returns char *. */
-
-static_inline char *
-xcharalloc (size_t n)
-{
- return XNMALLOC (n, char);
-}
-
-# endif
-
-# ifdef __cplusplus
-}
-
-/* C++ does not allow conversions from void * to other pointer types
- without a cast. Use templates to work around the problem when
- possible. */
-
-template <typename T> inline T *
-xrealloc (T *p, size_t s)
-{
- return (T *) xrealloc ((void *) p, s);
-}
-
-template <typename T> inline T *
-xnrealloc (T *p, size_t n, size_t s)
-{
- return (T *) xnrealloc ((void *) p, n, s);
-}
-
-template <typename T> inline T *
-x2realloc (T *p, size_t *pn)
-{
- return (T *) x2realloc ((void *) p, pn);
-}
-
-template <typename T> inline T *
-x2nrealloc (T *p, size_t *pn, size_t s)
-{
- return (T *) x2nrealloc ((void *) p, pn, s);
-}
-
-template <typename T> inline T *
-xmemdup (T const *p, size_t s)
-{
- return (T *) xmemdup ((void const *) p, s);
-}
-
-# endif
-
-
-#endif /* !XALLOC_H_ */
diff --git a/contrib/cpio/lib/xmalloc.c b/contrib/cpio/lib/xmalloc.c
deleted file mode 100644
index 318e0dd..0000000
--- a/contrib/cpio/lib/xmalloc.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* xmalloc.c -- malloc with out of memory checking
-
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
- Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-#if ! HAVE_INLINE
-# define static_inline
-#endif
-#include "xalloc.h"
-#undef static_inline
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-/* 1 if calloc is known to be compatible with GNU calloc. This
- matters if we are not also using the calloc module, which defines
- HAVE_CALLOC and supports the GNU API even on non-GNU platforms. */
-#if defined HAVE_CALLOC || defined __GLIBC__
-enum { HAVE_GNU_CALLOC = 1 };
-#else
-enum { HAVE_GNU_CALLOC = 0 };
-#endif
-
-/* Allocate N bytes of memory dynamically, with error checking. */
-
-void *
-xmalloc (size_t n)
-{
- void *p = malloc (n);
- if (!p && n != 0)
- xalloc_die ();
- return p;
-}
-
-/* Change the size of an allocated block of memory P to N bytes,
- with error checking. */
-
-void *
-xrealloc (void *p, size_t n)
-{
- p = realloc (p, n);
- if (!p && n != 0)
- xalloc_die ();
- return p;
-}
-
-/* If P is null, allocate a block of at least *PN bytes; otherwise,
- reallocate P so that it contains more than *PN bytes. *PN must be
- nonzero unless P is null. Set *PN to the new block's size, and
- return the pointer to the new block. *PN is never set to zero, and
- the returned pointer is never null. */
-
-void *
-x2realloc (void *p, size_t *pn)
-{
- return x2nrealloc (p, pn, 1);
-}
-
-/* Allocate S bytes of zeroed memory dynamically, with error checking.
- There's no need for xnzalloc (N, S), since it would be equivalent
- to xcalloc (N, S). */
-
-void *
-xzalloc (size_t s)
-{
- return memset (xmalloc (s), 0, s);
-}
-
-/* Allocate zeroed memory for N elements of S bytes, with error
- checking. S must be nonzero. */
-
-void *
-xcalloc (size_t n, size_t s)
-{
- void *p;
- /* Test for overflow, since some calloc implementations don't have
- proper overflow checks. But omit overflow and size-zero tests if
- HAVE_GNU_CALLOC, since GNU calloc catches overflow and never
- returns NULL if successful. */
- if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s))
- || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0)))
- xalloc_die ();
- return p;
-}
-
-/* Clone an object P of size S, with error checking. There's no need
- for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
- need for an arithmetic overflow check. */
-
-void *
-xmemdup (void const *p, size_t s)
-{
- return memcpy (xmalloc (s), p, s);
-}
-
-/* Clone STRING. */
-
-char *
-xstrdup (char const *string)
-{
- return xmemdup (string, strlen (string) + 1);
-}
diff --git a/contrib/cpio/lib/xstrndup.c b/contrib/cpio/lib/xstrndup.c
deleted file mode 100644
index 7ccefd7..0000000
--- a/contrib/cpio/lib/xstrndup.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Duplicate a bounded initial segment of a string, with out-of-memory
- checking.
- Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-/* Specification. */
-#include "xstrndup.h"
-
-#include <string.h>
-#include "xalloc.h"
-
-/* Return a newly allocated copy of at most N bytes of STRING.
- In other words, return a copy of the initial segment of length N of
- STRING. */
-char *
-xstrndup (const char *string, size_t n)
-{
- char *s = strndup (string, n);
- if (! s)
- xalloc_die ();
- return s;
-}
diff --git a/contrib/cpio/lib/xstrndup.h b/contrib/cpio/lib/xstrndup.h
deleted file mode 100644
index 88354cf..0000000
--- a/contrib/cpio/lib/xstrndup.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Duplicate a bounded initial segment of a string, with out-of-memory
- checking.
- Copyright (C) 2003 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <stddef.h>
-
-/* Return a newly allocated copy of at most N bytes of STRING.
- In other words, return a copy of the initial segment of length N of
- STRING. */
-extern char *xstrndup (const char *string, size_t n);
diff --git a/contrib/cpio/src/copyin.c b/contrib/cpio/src/copyin.c
deleted file mode 100644
index 5659136..0000000
--- a/contrib/cpio/src/copyin.c
+++ /dev/null
@@ -1,1644 +0,0 @@
-/* $FreeBSD$ */
-
-/* copyin.c - extract or list a cpio archive
- Copyright (C) 1990,1991,1992,2001,2002,2003,2004,
- 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "filetypes.h"
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-#include "defer.h"
-#include "dirname.h"
-#include <rmt.h>
-#ifndef FNM_PATHNAME
-# include <fnmatch.h>
-#endif
-#include <langinfo.h>
-
-#ifndef HAVE_LCHOWN
-# define lchown(f,u,g) 0
-#endif
-
-static void copyin_regular_file(struct cpio_file_stat* file_hdr,
- int in_file_des);
-
-void
-warn_junk_bytes (long bytes_skipped)
-{
- error (0, 0, ngettext ("warning: skipped %ld byte of junk",
- "warning: skipped %ld bytes of junk", bytes_skipped),
- bytes_skipped);
-}
-
-
-static int
-query_rename(struct cpio_file_stat* file_hdr, FILE *tty_in, FILE *tty_out,
- FILE *rename_in)
-{
- char *str_res; /* Result for string function. */
- static dynamic_string new_name; /* New file name for rename option. */
- static int initialized_new_name = false;
- if (!initialized_new_name)
- {
- ds_init (&new_name, 128);
- initialized_new_name = true;
- }
-
- if (rename_flag)
- {
- fprintf (tty_out, _("rename %s -> "), file_hdr->c_name);
- fflush (tty_out);
- str_res = ds_fgets (tty_in, &new_name);
- }
- else
- {
- str_res = ds_fgetstr (rename_in, &new_name, '\n');
- }
- if (str_res == NULL || str_res[0] == 0)
- {
- return -1;
- }
- else
- /* Debian hack: file_hrd.c_name is sometimes set to
- point to static memory by code in tar.c. This
- causes a segfault. This has been fixed and an
- additional check to ensure that the file name
- is not too long has been added. (Reported by
- Horst Knobloch.) This bug has been reported to
- "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM */
- {
- if (archive_format != arf_tar && archive_format != arf_ustar)
- {
- free (file_hdr->c_name);
- file_hdr->c_name = xstrdup (new_name.ds_string);
- }
- else
- {
- if (is_tar_filename_too_long (new_name.ds_string))
- error (0, 0, _("%s: file name too long"),
- new_name.ds_string);
- else
- strcpy (file_hdr->c_name, new_name.ds_string);
- }
- }
- return 0;
-}
-
-/* Skip the padding on IN_FILE_DES after a header or file,
- up to the next header.
- The number of bytes skipped is based on OFFSET -- the current offset
- from the last start of a header (or file) -- and the current
- header type. */
-
-static void
-tape_skip_padding (int in_file_des, int offset)
-{
- int pad;
-
- if (archive_format == arf_crcascii || archive_format == arf_newascii)
- pad = (4 - (offset % 4)) % 4;
- else if (archive_format == arf_binary || archive_format == arf_hpbinary)
- pad = (2 - (offset % 2)) % 2;
- else if (archive_format == arf_tar || archive_format == arf_ustar)
- pad = (512 - (offset % 512)) % 512;
- else
- pad = 0;
-
- if (pad != 0)
- tape_toss_input (in_file_des, pad);
-}
-
-
-static void
-list_file(struct cpio_file_stat* file_hdr, int in_file_des)
-{
- if (verbose_flag)
- {
-#ifdef CP_IFLNK
- if ((file_hdr->c_mode & CP_IFMT) == CP_IFLNK)
- {
- if (archive_format != arf_tar && archive_format != arf_ustar)
- {
- char *link_name = NULL; /* Name of hard and symbolic links. */
-
- link_name = (char *) xmalloc ((unsigned int) file_hdr->c_filesize + 1);
- link_name[file_hdr->c_filesize] = '\0';
- tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize);
- long_format (file_hdr, link_name);
- free (link_name);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return;
- }
- else
- {
- long_format (file_hdr, file_hdr->c_tar_linkname);
- return;
- }
- }
- else
-#endif
- long_format (file_hdr, (char *) 0);
- }
- else
- {
- /* Debian hack: Modified to print a list of filenames
- terminiated by a null character when the -t and -0
- flags are used. This has been submitted as a
- suggestion to "bug-gnu-utils@prep.ai.mit.edu". -BEM */
- printf ("%s%c", file_hdr->c_name, name_end);
- }
-
- crc = 0;
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- if (only_verify_crc_flag)
- {
-#ifdef CP_IFLNK
- if ((file_hdr->c_mode & CP_IFMT) == CP_IFLNK)
- {
- return; /* links don't have a checksum */
- }
-#endif
- if (crc != file_hdr->c_chksum)
- {
- error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
- file_hdr->c_name, crc, file_hdr->c_chksum);
- }
- }
-}
-
-static int
-try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des,
- int *existing_dir)
-{
- struct stat file_stat;
-
- *existing_dir = false;
- if (lstat (file_hdr->c_name, &file_stat) == 0)
- {
- if (S_ISDIR (file_stat.st_mode)
- && ((file_hdr->c_mode & CP_IFMT) == CP_IFDIR))
- {
- /* If there is already a directory there that
- we are trying to create, don't complain about
- it. */
- *existing_dir = true;
- return 0;
- }
- else if (!unconditional_flag
- && file_hdr->c_mtime <= file_stat.st_mtime)
- {
- error (0, 0, _("%s not created: newer or same age version exists"),
- file_hdr->c_name);
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return -1; /* Go to the next file. */
- }
- else if (S_ISDIR (file_stat.st_mode)
- ? rmdir (file_hdr->c_name)
- : unlink (file_hdr->c_name))
- {
- error (0, errno, _("cannot remove current %s"),
- file_hdr->c_name);
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return -1; /* Go to the next file. */
- }
- }
- return 0;
-}
-
-/* The newc and crc formats store multiply linked copies of the same file
- in the archive only once. The actual data is attached to the last link
- in the archive, and the other links all have a filesize of 0. When a
- file in the archive has multiple links and a filesize of 0, its data is
- probably "attatched" to another file in the archive, so we can't create
- it right away. We have to "defer" creating it until we have created
- the file that has the data "attatched" to it. We keep a list of the
- "defered" links on deferments. */
-
-struct deferment *deferments = NULL;
-
-/* Add a file header to the deferments list. For now they all just
- go on one list, although we could optimize this if necessary. */
-
-static void
-defer_copyin (struct cpio_file_stat *file_hdr)
-{
- struct deferment *d;
- d = create_deferment (file_hdr);
- d->next = deferments;
- deferments = d;
- return;
-}
-
-/* We just created a file that (probably) has some other links to it
- which have been defered. Go through all of the links on the deferments
- list and create any which are links to this file. */
-
-static void
-create_defered_links (struct cpio_file_stat *file_hdr)
-{
- struct deferment *d;
- struct deferment *d_prev;
- int ino;
- int maj;
- int min;
- int link_res;
- ino = file_hdr->c_ino;
- maj = file_hdr->c_dev_maj;
- min = file_hdr->c_dev_min;
- d = deferments;
- d_prev = NULL;
- while (d != NULL)
- {
- if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
- && (d->header.c_dev_min == min) )
- {
- struct deferment *d_free;
- link_res = link_to_name (d->header.c_name, file_hdr->c_name);
- if (link_res < 0)
- {
- error (0, errno, _("cannot link %s to %s"),
- d->header.c_name, file_hdr->c_name);
- }
- if (d_prev != NULL)
- d_prev->next = d->next;
- else
- deferments = d->next;
- d_free = d;
- d = d->next;
- free_deferment (d_free);
- }
- else
- {
- d_prev = d;
- d = d->next;
- }
- }
-}
-
-/* We are skipping a file but there might be other links to it that we
- did not skip, so we have to copy its data for the other links. Find
- the first link that we didn't skip and try to create that. That will
- then create the other deferred links. */
-
-static int
-create_defered_links_to_skipped (struct cpio_file_stat *file_hdr,
- int in_file_des)
-{
- struct deferment *d;
- struct deferment *d_prev;
- int ino;
- int maj;
- int min;
- if (file_hdr->c_filesize == 0)
- {
- /* The file doesn't have any data attached to it so we don't have
- to bother. */
- return -1;
- }
- ino = file_hdr->c_ino;
- maj = file_hdr->c_dev_maj;
- min = file_hdr->c_dev_min;
- d = deferments;
- d_prev = NULL;
- while (d != NULL)
- {
- if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
- && (d->header.c_dev_min == min) )
- {
- if (d_prev != NULL)
- d_prev->next = d->next;
- else
- deferments = d->next;
- free (file_hdr->c_name);
- file_hdr->c_name = xstrdup(d->header.c_name);
- free_deferment (d);
- copyin_regular_file(file_hdr, in_file_des);
- return 0;
- }
- else
- {
- d_prev = d;
- d = d->next;
- }
- }
- return -1;
-}
-
-/* If we had a multiply linked file that really was empty then we would
- have defered all of its links, since we never found any with data
- "attached", and they will still be on the deferment list even when
- we are done reading the whole archive. Write out all of these
- empty links that are still on the deferments list. */
-
-static void
-create_final_defers ()
-{
- struct deferment *d;
- int link_res;
- int out_file_des;
-
- for (d = deferments; d != NULL; d = d->next)
- {
- /* Debian hack: A line, which could cause an endless loop, was
- removed (97/1/2). It was reported by Ronald F. Guilmette to
- the upstream maintainers. -BEM */
- /* Debian hack: This was reported by Horst Knobloch. This bug has
- been reported to "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM
- */
- link_res = link_to_maj_min_ino (d->header.c_name,
- d->header.c_dev_maj, d->header.c_dev_min,
- d->header.c_ino);
- if (link_res == 0)
- {
- continue;
- }
- out_file_des = open (d->header.c_name,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
- if (out_file_des < 0 && create_dir_flag)
- {
- create_all_directories (d->header.c_name);
- out_file_des = open (d->header.c_name,
- O_CREAT | O_WRONLY | O_BINARY,
- 0600);
- }
- if (out_file_des < 0)
- {
- open_error (d->header.c_name);
- continue;
- }
-
- set_perms (out_file_des, &d->header);
-
- if (close (out_file_des) < 0)
- close_error (d->header.c_name);
-
- }
-}
-
-static void
-copyin_regular_file (struct cpio_file_stat* file_hdr, int in_file_des)
-{
- int out_file_des; /* Output file descriptor. */
-
- if (to_stdout_option)
- out_file_des = STDOUT_FILENO;
- else
- {
- /* Can the current file be linked to a previously copied file? */
- if (file_hdr->c_nlink > 1
- && (archive_format == arf_newascii
- || archive_format == arf_crcascii) )
- {
- int link_res;
- if (file_hdr->c_filesize == 0)
- {
- /* The newc and crc formats store multiply linked copies
- of the same file in the archive only once. The
- actual data is attached to the last link in the
- archive, and the other links all have a filesize
- of 0. Since this file has multiple links and a
- filesize of 0, its data is probably attatched to
- another file in the archive. Save the link, and
- process it later when we get the actual data. We
- can't just create it with length 0 and add the
- data later, in case the file is readonly. We still
- lose if its parent directory is readonly (and we aren't
- running as root), but there's nothing we can do about
- that. */
- defer_copyin (file_hdr);
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return;
- }
- /* If the file has data (filesize != 0), then presumably
- any other links have already been defer_copyin'ed(),
- but GNU cpio version 2.0-2.2 didn't do that, so we
- still have to check for links here (and also in case
- the archive was created and later appeneded to). */
- /* Debian hack: (97/1/2) This was reported by Ronald
- F. Guilmette to the upstream maintainers. -BEM */
- link_res = link_to_maj_min_ino (file_hdr->c_name,
- file_hdr->c_dev_maj, file_hdr->c_dev_min,
- file_hdr->c_ino);
- if (link_res == 0)
- {
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return;
- }
- }
- else if (file_hdr->c_nlink > 1
- && archive_format != arf_tar
- && archive_format != arf_ustar)
- {
- int link_res;
- /* Debian hack: (97/1/2) This was reported by Ronald
- F. Guilmette to the upstream maintainers. -BEM */
- link_res = link_to_maj_min_ino (file_hdr->c_name,
- file_hdr->c_dev_maj,
- file_hdr->c_dev_min,
- file_hdr->c_ino);
- if (link_res == 0)
- {
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return;
- }
- }
- else if ((archive_format == arf_tar || archive_format == arf_ustar)
- && file_hdr->c_tar_linkname
- && file_hdr->c_tar_linkname[0] != '\0')
- {
- int link_res;
- link_res = link_to_name (file_hdr->c_name, file_hdr->c_tar_linkname);
- if (link_res < 0)
- {
- error (0, errno, _("cannot link %s to %s"),
- file_hdr->c_tar_linkname, file_hdr->c_name);
- }
- return;
- }
-
- /* If not linked, copy the contents of the file. */
- out_file_des = open (file_hdr->c_name,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
-
- if (out_file_des < 0 && create_dir_flag)
- {
- create_all_directories (file_hdr->c_name);
- out_file_des = open (file_hdr->c_name,
- O_CREAT | O_WRONLY | O_BINARY,
- 0600);
- }
-
- if (out_file_des < 0)
- {
- open_error (file_hdr->c_name);
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return;
- }
- }
-
- crc = 0;
- if (swap_halfwords_flag)
- {
- if ((file_hdr->c_filesize % 4) == 0)
- swapping_halfwords = true;
- else
- error (0, 0, _("cannot swap halfwords of %s: odd number of halfwords"),
- file_hdr->c_name);
- }
- if (swap_bytes_flag)
- {
- if ((file_hdr->c_filesize % 2) == 0)
- swapping_bytes = true;
- else
- error (0, 0, _("cannot swap bytes of %s: odd number of bytes"),
- file_hdr->c_name);
- }
- copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr->c_filesize);
- disk_empty_output_buffer (out_file_des);
-
- if (to_stdout_option)
- {
- if (archive_format == arf_crcascii)
- {
- if (crc != file_hdr->c_chksum)
- error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
- file_hdr->c_name, crc, file_hdr->c_chksum);
- }
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- return;
- }
-
- /* Debian hack to fix a bug in the --sparse option.
- This bug has been reported to
- "bug-gnu-utils@prep.ai.mit.edu". (96/7/10) -BEM */
- if (delayed_seek_count > 0)
- {
- lseek (out_file_des, delayed_seek_count-1, SEEK_CUR);
- write (out_file_des, "", 1);
- delayed_seek_count = 0;
- }
-
- set_perms (out_file_des, file_hdr);
-
- if (close (out_file_des) < 0)
- close_error (file_hdr->c_name);
-
- if (archive_format == arf_crcascii)
- {
- if (crc != file_hdr->c_chksum)
- error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
- file_hdr->c_name, crc, file_hdr->c_chksum);
- }
-
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- if (file_hdr->c_nlink > 1
- && (archive_format == arf_newascii || archive_format == arf_crcascii) )
- {
- /* (see comment above for how the newc and crc formats
- store multiple links). Now that we have the data
- for this file, create any other links to it which
- we defered. */
- create_defered_links (file_hdr);
- }
-}
-
-static void
-copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir)
-{
- int res; /* Result of various function calls. */
-#ifdef HPUX_CDF
- int cdf_flag; /* True if file is a CDF. */
- int cdf_char; /* Index of `+' char indicating a CDF. */
-#endif
-
- if (to_stdout_option)
- return;
-
- /* Strip any trailing `/'s off the filename; tar puts
- them on. We might as well do it here in case anybody
- else does too, since they cause strange things to happen. */
- strip_trailing_slashes (file_hdr->c_name);
-
- /* Ignore the current directory. It must already exist,
- and we don't want to change its permission, ownership
- or time. */
- if (file_hdr->c_name[0] == '.' && file_hdr->c_name[1] == '\0')
- {
- return;
- }
-
-#ifdef HPUX_CDF
- cdf_flag = 0;
-#endif
- if (!existing_dir)
-
- {
-#ifdef HPUX_CDF
- /* If the directory name ends in a + and is SUID,
- then it is a CDF. Strip the trailing + from
- the name before creating it. */
- cdf_char = strlen (file_hdr->c_name) - 1;
- if ( (cdf_char > 0) &&
- (file_hdr->c_mode & 04000) &&
- (file_hdr->c_name [cdf_char] == '+') )
- {
- file_hdr->c_name [cdf_char] = '\0';
- cdf_flag = 1;
- }
-#endif
- res = mkdir (file_hdr->c_name, file_hdr->c_mode);
- }
- else
- res = 0;
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (file_hdr->c_name);
- res = mkdir (file_hdr->c_name, file_hdr->c_mode);
- }
- if (res < 0)
- {
- /* In some odd cases where the file_hdr->c_name includes `.',
- the directory may have actually been created by
- create_all_directories(), so the mkdir will fail
- because the directory exists. If that's the case,
- don't complain about it. */
- struct stat file_stat;
- if (errno != EEXIST)
- {
- mkdir_error (file_hdr->c_name);
- return;
- }
- if (lstat (file_hdr->c_name, &file_stat))
- {
- stat_error (file_hdr->c_name);
- return;
- }
- if (!(S_ISDIR (file_stat.st_mode)))
- {
- error (0, 0, _("%s is not a directory"),
- quotearg_colon (file_hdr->c_name));
- return;
- }
- }
-
- set_perms (-1, file_hdr);
-}
-
-static void
-copyin_device (struct cpio_file_stat* file_hdr)
-{
- int res; /* Result of various function calls. */
-
- if (to_stdout_option)
- return;
-
- if (file_hdr->c_nlink > 1 && archive_format != arf_tar
- && archive_format != arf_ustar)
- {
- int link_res;
- /* Debian hack: This was reported by Horst
- Knobloch. This bug has been reported to
- "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM */
- link_res = link_to_maj_min_ino (file_hdr->c_name,
- file_hdr->c_dev_maj, file_hdr->c_dev_min,
- file_hdr->c_ino);
- if (link_res == 0)
- {
- return;
- }
- }
- else if (archive_format == arf_ustar &&
- file_hdr->c_tar_linkname &&
- file_hdr->c_tar_linkname [0] != '\0')
- {
- int link_res;
- link_res = link_to_name (file_hdr->c_name,
- file_hdr->c_tar_linkname);
- if (link_res < 0)
- {
- error (0, errno, _("cannot link %s to %s"),
- file_hdr->c_tar_linkname, file_hdr->c_name);
- /* Something must be wrong, because we couldn't
- find the file to link to. But can we assume
- that the device maj/min numbers are correct
- and fall through to the mknod? It's probably
- safer to just return, rather than possibly
- creating a bogus device file. */
- }
- return;
- }
-
-#ifdef CP_IFIFO
- if ((file_hdr->c_mode & CP_IFMT) == CP_IFIFO)
- res = mkfifo (file_hdr->c_name, file_hdr->c_mode);
- else
-#endif
- res = mknod (file_hdr->c_name, file_hdr->c_mode,
- makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (file_hdr->c_name);
-#ifdef CP_IFIFO
- if ((file_hdr->c_mode & CP_IFMT) == CP_IFIFO)
- res = mkfifo (file_hdr->c_name, file_hdr->c_mode);
- else
-#endif
- res = mknod (file_hdr->c_name, file_hdr->c_mode,
- makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
- }
- if (res < 0)
- {
- mknod_error (file_hdr->c_name);
- return;
- }
- if (!no_chown_flag)
- {
- uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
- gid_t gid = set_group_flag ? set_group : file_hdr->c_gid;
- if ((chown (file_hdr->c_name, uid, gid) < 0)
- && errno != EPERM)
- chown_error_details (file_hdr->c_name, uid, gid);
- }
- /* chown may have turned off some permissions we wanted. */
- if (chmod (file_hdr->c_name, file_hdr->c_mode) < 0)
- chmod_error_details (file_hdr->c_name, file_hdr->c_mode);
- if (retain_time_flag)
- set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime,
- file_hdr->c_mtime);
-}
-
-static void
-copyin_link(struct cpio_file_stat *file_hdr, int in_file_des)
-{
- char *link_name = NULL; /* Name of hard and symbolic links. */
- int res; /* Result of various function calls. */
-
- if (to_stdout_option)
- return;
-
- if (archive_format != arf_tar && archive_format != arf_ustar)
- {
- link_name = (char *) xmalloc ((unsigned int) file_hdr->c_filesize + 1);
- link_name[file_hdr->c_filesize] = '\0';
- tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- }
- else
- {
- link_name = xstrdup (file_hdr->c_tar_linkname);
- }
-
- res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
- file_hdr->c_mode);
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (file_hdr->c_name);
- res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
- file_hdr->c_mode);
- }
- if (res < 0)
- {
- error (0, errno, _("%s: Cannot symlink to %s"),
- quotearg_colon (link_name), quote_n (1, file_hdr->c_name));
- free (link_name);
- return;
- }
- if (!no_chown_flag)
- {
- uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
- gid_t gid = set_group_flag ? set_group : file_hdr->c_gid;
- if ((lchown (file_hdr->c_name, uid, gid) < 0)
- && errno != EPERM)
- chown_error_details (file_hdr->c_name, uid, gid);
- }
- free (link_name);
-}
-
-static void
-copyin_file (struct cpio_file_stat* file_hdr, int in_file_des)
-{
- int existing_dir;
-
- if (!to_stdout_option
- && try_existing_file (file_hdr, in_file_des, &existing_dir) < 0)
- return;
-
- /* Do the real copy or link. */
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFREG:
- copyin_regular_file (file_hdr, in_file_des);
- break;
-
- case CP_IFDIR:
- copyin_directory (file_hdr, existing_dir);
- break;
-
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- copyin_device (file_hdr);
- break;
-
-#ifdef CP_IFLNK
- case CP_IFLNK:
- copyin_link (file_hdr, in_file_des);
- break;
-#endif
-
- default:
- error (0, 0, _("%s: unknown file type"), file_hdr->c_name);
- tape_toss_input (in_file_des, file_hdr->c_filesize);
- tape_skip_padding (in_file_des, file_hdr->c_filesize);
- }
-}
-
-
-/* Current time for verbose table. */
-static time_t current_time;
-
-
-/* Print the file described by FILE_HDR in long format.
- If LINK_NAME is nonzero, it is the name of the file that
- this file is a symbolic link to. */
-
-void
-long_format (struct cpio_file_stat *file_hdr, char *link_name)
-{
- char mbuf[11];
- char tbuf[40];
- time_t when;
- char *ptbuf;
- static int d_first = -1;
-
- mode_string (file_hdr->c_mode, mbuf);
- mbuf[10] = '\0';
-
- /* Get time values ready to print. */
- when = file_hdr->c_mtime;
- if (d_first < 0)
- d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
- if (current_time - when > 6L * 30L * 24L * 60L * 60L
- || current_time - when < 0L)
- ptbuf = d_first ? "%e %b %Y" : "%b %e %Y";
- else
- ptbuf = d_first ? "%e %b %R" : "%b %e %R";
- strftime(tbuf, sizeof(tbuf), ptbuf, localtime(&when));
- ptbuf = tbuf;
-
- printf ("%s %3lu ", mbuf, file_hdr->c_nlink);
-
- if (numeric_uid)
- printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid,
- (unsigned int) file_hdr->c_gid);
- else
- printf ("%-8.8s %-8.8s ", getuser (file_hdr->c_uid),
- getgroup (file_hdr->c_gid));
-
- if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
- || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
- printf ("%3lu, %3lu ", file_hdr->c_rdev_maj,
- file_hdr->c_rdev_min);
- else
- printf ("%8"PRIuMAX" ", (uintmax_t) file_hdr->c_filesize);
-
- printf ("%s ", ptbuf);
-
- print_name_with_quoting (file_hdr->c_name);
- if (link_name)
- {
- printf (" -> ");
- print_name_with_quoting (link_name);
- }
- putc ('\n', stdout);
-}
-
-void
-print_name_with_quoting (register char *p)
-{
- register unsigned char c;
-
- while ( (c = *p++) )
- {
- switch (c)
- {
- case '\\':
- printf ("\\\\");
- break;
-
- case '\n':
- printf ("\\n");
- break;
-
- case '\b':
- printf ("\\b");
- break;
-
- case '\r':
- printf ("\\r");
- break;
-
- case '\t':
- printf ("\\t");
- break;
-
- case '\f':
- printf ("\\f");
- break;
-
- case ' ':
- printf ("\\ ");
- break;
-
- case '"':
- printf ("\\\"");
- break;
-
- default:
- if (isprint (c))
- putchar (c);
- else
- printf ("\\%03o", (unsigned int) c);
- }
- }
-}
-
-/* Read a pattern file (for the -E option). Put a list of
- `num_patterns' elements in `save_patterns'. Any patterns that were
- already in `save_patterns' (from the command line) are preserved. */
-
-static void
-read_pattern_file ()
-{
- int max_new_patterns;
- char **new_save_patterns;
- int new_num_patterns;
- int i;
- dynamic_string pattern_name;
- FILE *pattern_fp;
-
- if (num_patterns < 0)
- num_patterns = 0;
- max_new_patterns = 1 + num_patterns;
- new_save_patterns = (char **) xmalloc (max_new_patterns * sizeof (char *));
- new_num_patterns = num_patterns;
- ds_init (&pattern_name, 128);
-
- pattern_fp = fopen (pattern_file_name, "r");
- if (pattern_fp == NULL)
- open_error (pattern_file_name);
- while (ds_fgetstr (pattern_fp, &pattern_name, '\n') != NULL)
- {
- if (new_num_patterns >= max_new_patterns)
- {
- max_new_patterns += 1;
- new_save_patterns = (char **)
- xrealloc ((char *) new_save_patterns,
- max_new_patterns * sizeof (char *));
- }
- new_save_patterns[new_num_patterns] = xstrdup (pattern_name.ds_string);
- ++new_num_patterns;
- }
- if (ferror (pattern_fp) || fclose (pattern_fp) == EOF)
- close_error (pattern_file_name);
-
- for (i = 0; i < num_patterns; ++i)
- new_save_patterns[i] = save_patterns[i];
-
- save_patterns = new_save_patterns;
- num_patterns = new_num_patterns;
-}
-
-
-uintmax_t
-from_ascii (char const *where, size_t digs, unsigned logbase)
-{
- uintmax_t value = 0;
- char const *buf = where;
- char const *end = buf + digs;
- int overflow = 0;
- static char codetab[] = "0123456789ABCDEF";
-
- for (; *buf == ' '; buf++)
- {
- if (buf == end)
- return 0;
- }
-
- if (buf == end || *buf == 0)
- return 0;
- while (1)
- {
- unsigned d;
-
- char *p = strchr (codetab, toupper (*buf));
- if (!p)
- {
- error (0, 0, _("Malformed number %.*s"), digs, where);
- break;
- }
-
- d = p - codetab;
- if ((d >> logbase) > 1)
- {
- error (0, 0, _("Malformed number %.*s"), digs, where);
- break;
- }
- value += d;
- if (++buf == end || *buf == 0)
- break;
- overflow |= value ^ (value << logbase >> logbase);
- value <<= logbase;
- }
- if (overflow)
- error (0, 0, _("Archive value %.*s is out of range"),
- digs, where);
- return value;
-}
-
-
-
-/* Return 16-bit integer I with the bytes swapped. */
-#define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff))
-
-/* Read the header, including the name of the file, from file
- descriptor IN_DES into FILE_HDR. */
-
-void
-read_in_header (struct cpio_file_stat *file_hdr, int in_des)
-{
- union {
- char str[6];
- unsigned short num;
- struct old_cpio_header old_header;
- } magic;
- long bytes_skipped = 0; /* Bytes of junk found before magic number. */
-
- /* Search for a valid magic number. */
-
- if (archive_format == arf_unknown)
- {
- char tmpbuf[512];
- int check_tar;
- int peeked_bytes;
-
- while (archive_format == arf_unknown)
- {
- peeked_bytes = tape_buffered_peek (tmpbuf, in_des, 512);
- if (peeked_bytes < 6)
- error (1, 0, _("premature end of archive"));
-
- if (!strncmp (tmpbuf, "070701", 6))
- archive_format = arf_newascii;
- else if (!strncmp (tmpbuf, "070707", 6))
- archive_format = arf_oldascii;
- else if (!strncmp (tmpbuf, "070702", 6))
- {
- archive_format = arf_crcascii;
- crc_i_flag = true;
- }
- else if ((*((unsigned short *) tmpbuf) == 070707) ||
- (*((unsigned short *) tmpbuf) == swab_short ((unsigned short) 070707)))
- archive_format = arf_binary;
- else if (peeked_bytes >= 512
- && (check_tar = is_tar_header (tmpbuf)))
- {
- if (check_tar == 2)
- archive_format = arf_ustar;
- else
- archive_format = arf_tar;
- }
- else
- {
- tape_buffered_read ((char *) tmpbuf, in_des, 1L);
- ++bytes_skipped;
- }
- }
- }
-
- if (archive_format == arf_tar || archive_format == arf_ustar)
- {
- if (append_flag)
- last_header_start = input_bytes - io_block_size +
- (in_buff - input_buffer);
- if (bytes_skipped > 0)
- warn_junk_bytes (bytes_skipped);
-
- read_in_tar_header (file_hdr, in_des);
- return;
- }
-
- file_hdr->c_tar_linkname = NULL;
-
- tape_buffered_read (magic.str, in_des, 6L);
- while (1)
- {
- if (append_flag)
- last_header_start = input_bytes - io_block_size
- + (in_buff - input_buffer) - 6;
- if (archive_format == arf_newascii
- && !strncmp (magic.str, "070701", 6))
- {
- if (bytes_skipped > 0)
- warn_junk_bytes (bytes_skipped);
- file_hdr->c_magic = 070701;
- read_in_new_ascii (file_hdr, in_des);
- break;
- }
- if (archive_format == arf_crcascii
- && !strncmp (magic.str, "070702", 6))
- {
- if (bytes_skipped > 0)
- warn_junk_bytes (bytes_skipped);
- file_hdr->c_magic = 070702;
- read_in_new_ascii (file_hdr, in_des);
- break;
- }
- if ( (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
- && !strncmp (magic.str, "070707", 6))
- {
- if (bytes_skipped > 0)
- warn_junk_bytes (bytes_skipped);
- file_hdr->c_magic = 070707;
- read_in_old_ascii (file_hdr, in_des);
- break;
- }
- if ( (archive_format == arf_binary || archive_format == arf_hpbinary)
- && (magic.num == 070707
- || magic.num == swab_short ((unsigned short) 070707)))
- {
- /* Having to skip 1 byte because of word alignment is normal. */
- if (bytes_skipped > 0)
- warn_junk_bytes (bytes_skipped);
- file_hdr->c_magic = 070707;
- read_in_binary (file_hdr, &magic.old_header, in_des);
- break;
- }
- bytes_skipped++;
- memmove (magic.str, magic.str + 1, 5);
- tape_buffered_read (magic.str, in_des, 1L);
- }
-}
-
-/* Fill in FILE_HDR by reading an old-format ASCII format cpio header from
- file descriptor IN_DES, except for the magic number, which is
- already filled in. */
-
-void
-read_in_old_ascii (struct cpio_file_stat *file_hdr, int in_des)
-{
- struct old_ascii_header ascii_header;
- unsigned long dev;
-
- tape_buffered_read (ascii_header.c_dev, in_des,
- sizeof ascii_header - sizeof ascii_header.c_magic);
- dev = FROM_OCTAL (ascii_header.c_dev);
- file_hdr->c_dev_maj = major (dev);
- file_hdr->c_dev_min = minor (dev);
-
- file_hdr->c_ino = FROM_OCTAL (ascii_header.c_ino);
- file_hdr->c_mode = FROM_OCTAL (ascii_header.c_mode);
- file_hdr->c_uid = FROM_OCTAL (ascii_header.c_uid);
- file_hdr->c_gid = FROM_OCTAL (ascii_header.c_gid);
- file_hdr->c_nlink = FROM_OCTAL (ascii_header.c_nlink);
- dev = FROM_OCTAL (ascii_header.c_rdev);
- file_hdr->c_rdev_maj = major (dev);
- file_hdr->c_rdev_min = minor (dev);
-
- file_hdr->c_mtime = FROM_OCTAL (ascii_header.c_mtime);
- file_hdr->c_namesize = FROM_OCTAL (ascii_header.c_namesize);
- file_hdr->c_filesize = FROM_OCTAL (ascii_header.c_filesize);
-
- /* Read file name from input. */
- if (file_hdr->c_name != NULL)
- free (file_hdr->c_name);
- file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize + 1);
- tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
-
- /* HP/UX cpio creates archives that look just like ordinary archives,
- but for devices it sets major = 0, minor = 1, and puts the
- actual major/minor number in the filesize field. See if this
- is an HP/UX cpio archive, and if so fix it. We have to do this
- here because process_copy_in() assumes filesize is always 0
- for devices. */
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- if (file_hdr->c_filesize != 0
- && file_hdr->c_rdev_maj == 0
- && file_hdr->c_rdev_min == 1)
- {
- file_hdr->c_rdev_maj = major (file_hdr->c_filesize);
- file_hdr->c_rdev_min = minor (file_hdr->c_filesize);
- file_hdr->c_filesize = 0;
- }
- break;
- default:
- break;
- }
-}
-
-/* Fill in FILE_HDR by reading a new-format ASCII format cpio header from
- file descriptor IN_DES, except for the magic number, which is
- already filled in. */
-
-void
-read_in_new_ascii (struct cpio_file_stat *file_hdr, int in_des)
-{
- struct new_ascii_header ascii_header;
-
- tape_buffered_read (ascii_header.c_ino, in_des,
- sizeof ascii_header - sizeof ascii_header.c_magic);
-
- file_hdr->c_ino = FROM_HEX (ascii_header.c_ino);
- file_hdr->c_mode = FROM_HEX (ascii_header.c_mode);
- file_hdr->c_uid = FROM_HEX (ascii_header.c_uid);
- file_hdr->c_gid = FROM_HEX (ascii_header.c_gid);
- file_hdr->c_nlink = FROM_HEX (ascii_header.c_nlink);
- file_hdr->c_mtime = FROM_HEX (ascii_header.c_mtime);
- file_hdr->c_filesize = FROM_HEX (ascii_header.c_filesize);
- file_hdr->c_dev_maj = FROM_HEX (ascii_header.c_dev_maj);
- file_hdr->c_dev_min = FROM_HEX (ascii_header.c_dev_min);
- file_hdr->c_rdev_maj = FROM_HEX (ascii_header.c_rdev_maj);
- file_hdr->c_rdev_min = FROM_HEX (ascii_header.c_rdev_min);
- file_hdr->c_namesize = FROM_HEX (ascii_header.c_namesize);
- file_hdr->c_chksum = FROM_HEX (ascii_header.c_chksum);
-
- /* Read file name from input. */
- if (file_hdr->c_name != NULL)
- free (file_hdr->c_name);
- file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
- tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
-
- /* In SVR4 ASCII format, the amount of space allocated for the header
- is rounded up to the next long-word, so we might need to drop
- 1-3 bytes. */
- tape_skip_padding (in_des, file_hdr->c_namesize + 110);
-}
-
-/* Fill in FILE_HDR by reading a binary format cpio header from
- file descriptor IN_DES, except for the first 6 bytes (the magic
- number, device, and inode number), which are already filled in. */
-
-void
-read_in_binary (struct cpio_file_stat *file_hdr,
- struct old_cpio_header *short_hdr,
- int in_des)
-{
- file_hdr->c_magic = short_hdr->c_magic;
-
- tape_buffered_read (((char *) short_hdr) + 6, in_des,
- sizeof *short_hdr - 6 /* = 20 */);
-
- /* If the magic number is byte swapped, fix the header. */
- if (file_hdr->c_magic == swab_short ((unsigned short) 070707))
- {
- static int warned = 0;
-
- /* Alert the user that they might have to do byte swapping on
- the file contents. */
- if (warned == 0)
- {
- error (0, 0, _("warning: archive header has reverse byte-order"));
- warned = 1;
- }
- swab_array ((char *) &short_hdr, 13);
- }
-
- file_hdr->c_dev_maj = major (short_hdr->c_dev);
- file_hdr->c_dev_min = minor (short_hdr->c_dev);
- file_hdr->c_ino = short_hdr->c_ino;
- file_hdr->c_mode = short_hdr->c_mode;
- file_hdr->c_uid = short_hdr->c_uid;
- file_hdr->c_gid = short_hdr->c_gid;
- file_hdr->c_nlink = short_hdr->c_nlink;
- file_hdr->c_rdev_maj = major (short_hdr->c_rdev);
- file_hdr->c_rdev_min = minor (short_hdr->c_rdev);
- file_hdr->c_mtime = (unsigned long) short_hdr->c_mtimes[0] << 16
- | short_hdr->c_mtimes[1];
-
- file_hdr->c_namesize = short_hdr->c_namesize;
- file_hdr->c_filesize = (unsigned long) short_hdr->c_filesizes[0] << 16
- | short_hdr->c_filesizes[1];
-
- /* Read file name from input. */
- if (file_hdr->c_name != NULL)
- free (file_hdr->c_name);
- file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
- tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
-
- /* In binary mode, the amount of space allocated in the header for
- the filename is `c_namesize' rounded up to the next short-word,
- so we might need to drop a byte. */
- if (file_hdr->c_namesize % 2)
- tape_toss_input (in_des, 1L);
-
- /* HP/UX cpio creates archives that look just like ordinary archives,
- but for devices it sets major = 0, minor = 1, and puts the
- actual major/minor number in the filesize field. See if this
- is an HP/UX cpio archive, and if so fix it. We have to do this
- here because process_copy_in() assumes filesize is always 0
- for devices. */
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- if (file_hdr->c_filesize != 0
- && file_hdr->c_rdev_maj == 0
- && file_hdr->c_rdev_min == 1)
- {
- file_hdr->c_rdev_maj = major (file_hdr->c_filesize);
- file_hdr->c_rdev_min = minor (file_hdr->c_filesize);
- file_hdr->c_filesize = 0;
- }
- break;
- default:
- break;
- }
-}
-
-/* Exchange the bytes of each element of the array of COUNT shorts
- starting at PTR. */
-
-void
-swab_array (char *ptr, int count)
-{
- char tmp;
-
- while (count-- > 0)
- {
- tmp = *ptr;
- *ptr = *(ptr + 1);
- ++ptr;
- *ptr = tmp;
- ++ptr;
- }
-}
-
-#if 0 /* Now in util.c, but different */
-/* Return a safer suffix of FILE_NAME, or "." if it has no safer
- suffix. Check for fully specified file names and other atrocities. */
-
-static const char *
-safer_name_suffix (char const *file_name)
-{
- char const *p;
-
- /* Skip file system prefixes, leading file name components that contain
- "..", and leading slashes. */
-
- size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);
-
- for (p = file_name + prefix_len; *p;)
- {
- if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
- prefix_len = p + 2 - file_name;
-
- do
- {
- char c = *p++;
- if (ISSLASH (c))
- break;
- }
- while (*p);
- }
-
- for (p = file_name + prefix_len; ISSLASH (*p); p++)
- continue;
- prefix_len = p - file_name;
-
- if (prefix_len)
- {
- char *prefix = alloca (prefix_len + 1);
- memcpy (prefix, file_name, prefix_len);
- prefix[prefix_len] = '\0';
-
-
- error (0, 0, _("Removing leading `%s' from member names"), prefix);
- }
-
- if (!*p)
- p = ".";
-
- return p;
-}
-#endif
-
-/* Read the collection from standard input and create files
- in the file system. */
-
-void
-process_copy_in ()
-{
- char done = false; /* True if trailer reached. */
- FILE *tty_in = NULL; /* Interactive file for rename option. */
- FILE *tty_out = NULL; /* Interactive file for rename option. */
- FILE *rename_in = NULL; /* Batch file for rename option. */
- struct stat file_stat; /* Output file stat record. */
- struct cpio_file_stat file_hdr; /* Output header information. */
- int in_file_des; /* Input file descriptor. */
- char skip_file; /* Flag for use with patterns. */
- int i; /* Loop index variable. */
-
- umask (0); /* Reset umask to preserve modes of
- created files */
-
- /* Initialize the copy in. */
- if (pattern_file_name)
- {
- read_pattern_file ();
- }
- file_hdr.c_name = NULL;
-
- if (rename_batch_file)
- {
- rename_in = fopen (rename_batch_file, "r");
- if (rename_in == NULL)
- {
- error (2, errno, TTY_NAME);
- }
- }
- else if (rename_flag)
- {
- /* Open interactive file pair for rename operation. */
- tty_in = fopen (TTY_NAME, "r");
- if (tty_in == NULL)
- {
- error (2, errno, TTY_NAME);
- }
- tty_out = fopen (TTY_NAME, "w");
- if (tty_out == NULL)
- {
- error (2, errno, TTY_NAME);
- }
- }
-
- /* Get date and time if needed for processing the table option. */
- if (table_flag && verbose_flag)
- {
- time (&current_time);
- }
-
- /* Check whether the input file might be a tape. */
- in_file_des = archive_des;
- if (_isrmt (in_file_des))
- {
- input_is_special = 1;
- input_is_seekable = 0;
- }
- else
- {
- if (fstat (in_file_des, &file_stat))
- error (1, errno, _("standard input is closed"));
- input_is_special =
-#ifdef S_ISBLK
- S_ISBLK (file_stat.st_mode) ||
-#endif
- S_ISCHR (file_stat.st_mode);
- input_is_seekable = S_ISREG (file_stat.st_mode);
- }
- output_is_seekable = true;
-
- /* While there is more input in the collection, process the input. */
- while (!done)
- {
- swapping_halfwords = swapping_bytes = false;
-
- /* Start processing the next file by reading the header. */
- read_in_header (&file_hdr, in_file_des);
-
-#ifdef DEBUG_CPIO
- if (debug_flag)
- {
- struct cpio_file_stat *h;
- h = &file_hdr;
- fprintf (stderr,
- "magic = 0%o, ino = %d, mode = 0%o, uid = %d, gid = %d\n",
- h->c_magic, h->c_ino, h->c_mode, h->c_uid, h->c_gid);
- fprintf (stderr,
- "nlink = %d, mtime = %d, filesize = %d, dev_maj = 0x%x\n",
- h->c_nlink, h->c_mtime, h->c_filesize, h->c_dev_maj);
- fprintf (stderr,
- "dev_min = 0x%x, rdev_maj = 0x%x, rdev_min = 0x%x, namesize = %d\n",
- h->c_dev_min, h->c_rdev_maj, h->c_rdev_min, h->c_namesize);
- fprintf (stderr,
- "chksum = %d, name = \"%s\", tar_linkname = \"%s\"\n",
- h->c_chksum, h->c_name,
- h->c_tar_linkname ? h->c_tar_linkname : "(null)" );
-
- }
-#endif
- /* Is this the header for the TRAILER file? */
- if (strcmp (CPIO_TRAILER_NAME, file_hdr.c_name) == 0)
- {
- done = true;
- break;
- }
-
- cpio_safer_name_suffix (file_hdr.c_name, false, abs_paths_flag,
- false);
-
- /* Does the file name match one of the given patterns? */
- if (num_patterns <= 0)
- skip_file = false;
- else
- {
- skip_file = copy_matching_files;
- for (i = 0; i < num_patterns
- && skip_file == copy_matching_files; i++)
- {
- if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0)
- skip_file = !copy_matching_files;
- }
- }
-
- if (skip_file)
- {
- /* If we're skipping a file with links, there might be other
- links that we didn't skip, and this file might have the
- data for the links. If it does, we'll copy in the data
- to the links, but not to this file. */
- if (file_hdr.c_nlink > 1 && (archive_format == arf_newascii
- || archive_format == arf_crcascii) )
- {
- if (create_defered_links_to_skipped(&file_hdr, in_file_des) < 0)
- {
- tape_toss_input (in_file_des, file_hdr.c_filesize);
- tape_skip_padding (in_file_des, file_hdr.c_filesize);
- }
- }
- else
- {
- tape_toss_input (in_file_des, file_hdr.c_filesize);
- tape_skip_padding (in_file_des, file_hdr.c_filesize);
- }
- }
- else if (table_flag)
- {
- list_file(&file_hdr, in_file_des);
- }
- else if (append_flag)
- {
- tape_toss_input (in_file_des, file_hdr.c_filesize);
- tape_skip_padding (in_file_des, file_hdr.c_filesize);
- }
- else if (only_verify_crc_flag)
- {
-#ifdef CP_IFLNK
- if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
- {
- if (archive_format != arf_tar && archive_format != arf_ustar)
- {
- tape_toss_input (in_file_des, file_hdr.c_filesize);
- tape_skip_padding (in_file_des, file_hdr.c_filesize);
- continue;
- }
- }
-#endif
- crc = 0;
- tape_toss_input (in_file_des, file_hdr.c_filesize);
- tape_skip_padding (in_file_des, file_hdr.c_filesize);
- if (crc != file_hdr.c_chksum)
- {
- error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
- file_hdr.c_name, crc, file_hdr.c_chksum);
- }
- /* Debian hack: -v and -V now work with --only-verify-crc.
- (99/11/10) -BEM */
- if (verbose_flag)
- {
- fprintf (stderr, "%s\n", file_hdr.c_name);
- }
- if (dot_flag)
- {
- fputc ('.', stderr);
- }
- }
- else
- {
- /* Copy the input file into the directory structure. */
-
- /* Do we need to rename the file? */
- if (rename_flag || rename_batch_file)
- {
- if (query_rename(&file_hdr, tty_in, tty_out, rename_in) < 0)
- {
- tape_toss_input (in_file_des, file_hdr.c_filesize);
- tape_skip_padding (in_file_des, file_hdr.c_filesize);
- continue;
- }
- }
-
- copyin_file(&file_hdr, in_file_des);
-
- if (verbose_flag)
- fprintf (stderr, "%s\n", file_hdr.c_name);
- if (dot_flag)
- fputc ('.', stderr);
- }
- }
-
- if (dot_flag)
- fputc ('\n', stderr);
-
- if (append_flag)
- return;
-
- if (archive_format == arf_newascii || archive_format == arf_crcascii)
- {
- create_final_defers ();
- }
- if (!quiet_flag)
- {
- int blocks;
- blocks = (input_bytes + io_block_size - 1) / io_block_size;
- fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", blocks), blocks);
- }
-}
-
diff --git a/contrib/cpio/src/copyout.c b/contrib/cpio/src/copyout.c
deleted file mode 100644
index 5e429fa..0000000
--- a/contrib/cpio/src/copyout.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/* $FreeBSD$ */
-
-/* copyout.c - create a cpio archive
- Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004,
- 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "filetypes.h"
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-#include "defer.h"
-#include <rmt.h>
-#include <paxlib.h>
-
-static int check_rdev ();
-
-/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
- compute and return a checksum for them. */
-
-static unsigned int
-read_for_checksum (int in_file_des, int file_size, char *file_name)
-{
- unsigned int crc;
- char buf[BUFSIZ];
- int bytes_left;
- int bytes_read;
- int i;
-
- crc = 0;
-
- for (bytes_left = file_size; bytes_left > 0; bytes_left -= bytes_read)
- {
- bytes_read = read (in_file_des, buf, BUFSIZ);
- if (bytes_read < 0)
- error (1, errno, _("cannot read checksum for %s"), file_name);
- if (bytes_read == 0)
- break;
- if (bytes_left < bytes_read)
- bytes_read = bytes_left;
- for (i = 0; i < bytes_read; ++i)
- crc += buf[i] & 0xff;
- }
- if (lseek (in_file_des, 0L, SEEK_SET))
- error (1, errno, _("cannot read checksum for %s"), file_name);
-
- return crc;
-}
-
-/* Write out NULs to fill out the rest of the current block on
- OUT_FILE_DES. */
-
-static void
-tape_clear_rest_of_block (int out_file_des)
-{
- write_nuls_to_file (io_block_size - output_size, out_file_des,
- tape_buffered_write);
-}
-
-/* Write NULs on OUT_FILE_DES to move from OFFSET (the current location)
- to the end of the header. */
-
-static void
-tape_pad_output (int out_file_des, int offset)
-{
- size_t pad;
-
- if (archive_format == arf_newascii || archive_format == arf_crcascii)
- pad = (4 - (offset % 4)) % 4;
- else if (archive_format == arf_tar || archive_format == arf_ustar)
- pad = (512 - (offset % 512)) % 512;
- else if (archive_format != arf_oldascii && archive_format != arf_hpoldascii)
- pad = (2 - (offset % 2)) % 2;
- else
- pad = 0;
-
- if (pad != 0)
- write_nuls_to_file (pad, out_file_des, tape_buffered_write);
-}
-
-
-/* When creating newc and crc archives if a file has multiple (hard)
- links, we don't put any of them into the archive until we have seen
- all of them (or until we get to the end of the list of files that
- are going into the archive and know that we have seen all of the links
- to the file that we will see). We keep these "defered" files on
- this list. */
-
-struct deferment *deferouts = NULL;
-
-/* Count the number of other (hard) links to this file that have
- already been defered. */
-
-static int
-count_defered_links_to_dev_ino (struct cpio_file_stat *file_hdr)
-{
- struct deferment *d;
- int ino;
- int maj;
- int min;
- int count;
- ino = file_hdr->c_ino;
- maj = file_hdr->c_dev_maj;
- min = file_hdr->c_dev_min;
- count = 0;
- for (d = deferouts; d != NULL; d = d->next)
- {
- if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
- && (d->header.c_dev_min == min) )
- ++count;
- }
- return count;
-}
-
-/* Is this file_hdr the last (hard) link to a file? I.e., have
- we already seen and defered all of the other links? */
-
-static int
-last_link (struct cpio_file_stat *file_hdr)
-{
- int other_files_sofar;
-
- other_files_sofar = count_defered_links_to_dev_ino (file_hdr);
- if (file_hdr->c_nlink == (other_files_sofar + 1) )
- {
- return 1;
- }
- return 0;
-}
-
-
-/* Add the file header for a link that is being defered to the deferouts
- list. */
-
-static void
-add_link_defer (struct cpio_file_stat *file_hdr)
-{
- struct deferment *d;
- d = create_deferment (file_hdr);
- d->next = deferouts;
- deferouts = d;
-}
-
-/* We are about to put a file into a newc or crc archive that is
- multiply linked. We have already seen and deferred all of the
- other links to the file but haven't written them into the archive.
- Write the other links into the archive, and remove them from the
- deferouts list. */
-
-static void
-writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des)
-{
- struct deferment *d;
- struct deferment *d_prev;
- int ino;
- int maj;
- int min;
- ino = file_hdr->c_ino;
- maj = file_hdr->c_dev_maj;
- min = file_hdr->c_dev_min;
- d_prev = NULL;
- d = deferouts;
- while (d != NULL)
- {
- if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
- && (d->header.c_dev_min == min) )
- {
- struct deferment *d_free;
- d->header.c_filesize = 0;
- write_out_header (&d->header, out_des);
- if (d_prev != NULL)
- d_prev->next = d->next;
- else
- deferouts = d->next;
- d_free = d;
- d = d->next;
- free_deferment (d_free);
- }
- else
- {
- d_prev = d;
- d = d->next;
- }
- }
- return;
-}
-
-/* Write a file into the archive. This code is the same as
- the code in process_copy_out(), but we need it here too
- for writeout_final_defers() to call. */
-
-static void
-writeout_defered_file (struct cpio_file_stat *header, int out_file_des)
-{
- int in_file_des;
- struct cpio_file_stat file_hdr;
-
- file_hdr = *header;
-
-
- in_file_des = open (header->c_name,
- O_RDONLY | O_BINARY, 0);
- if (in_file_des < 0)
- {
- open_error (header->c_name);
- return;
- }
-
- if (archive_format == arf_crcascii)
- file_hdr.c_chksum = read_for_checksum (in_file_des,
- file_hdr.c_filesize,
- header->c_name);
-
- if (write_out_header (&file_hdr, out_file_des))
- return;
- copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize,
- header->c_name);
- warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
-
- if (archive_format == arf_tar || archive_format == arf_ustar)
- add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
- file_hdr.c_dev_min);
-
- tape_pad_output (out_file_des, file_hdr.c_filesize);
-
- if (reset_time_flag)
- set_file_times (in_file_des, file_hdr.c_name, file_hdr.c_mtime,
- file_hdr.c_mtime);
- if (close (in_file_des) < 0)
- close_error (header->c_name);
-}
-
-/* When writing newc and crc format archives we defer multiply linked
- files until we have seen all of the links to the file. If a file
- has links to it that aren't going into the archive, then we will
- never see the "last" link to the file, so at the end we just write
- all of the leftover defered files into the archive. */
-
-static void
-writeout_final_defers (int out_des)
-{
- struct deferment *d;
- int other_count;
- while (deferouts != NULL)
- {
- d = deferouts;
- other_count = count_defered_links_to_dev_ino (&d->header);
- if (other_count == 1)
- {
- writeout_defered_file (&d->header, out_des);
- }
- else
- {
- struct cpio_file_stat file_hdr;
- file_hdr = d->header;
- file_hdr.c_filesize = 0;
- write_out_header (&file_hdr, out_des);
- }
- deferouts = deferouts->next;
- }
-}
-
-/* FIXME: to_ascii could be used instead of to_oct() and to_octal() from tar,
- so it should be moved to paxutils too.
- Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */
-int
-to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase)
-{
- static char codetab[] = "0123456789ABCDEF";
- int i = digits;
-
- do
- {
- where[--i] = codetab[(v & ((1 << logbase) - 1))];
- v >>= logbase;
- }
- while (i);
-
- return v != 0;
-}
-
-static void
-field_width_error (const char *filename, const char *fieldname)
-{
- error (0, 0, _("%s: field width not sufficient for storing %s"),
- filename, fieldname);
-}
-
-static void
-field_width_warning (const char *filename, const char *fieldname)
-{
- if (warn_option & CPIO_WARN_TRUNCATE)
- error (0, 0, _("%s: truncating %s"), filename, fieldname);
-}
-
-void
-to_ascii_or_warn (char *where, uintmax_t n, size_t digits,
- unsigned logbase,
- const char *filename, const char *fieldname)
-{
- if (to_ascii (where, n, digits, logbase))
- field_width_warning (filename, fieldname);
-}
-
-int
-to_ascii_or_error (char *where, uintmax_t n, size_t digits,
- unsigned logbase,
- const char *filename, const char *fieldname)
-{
- if (to_ascii (where, n, digits, logbase))
- {
- field_width_error (filename, fieldname);
- return 1;
- }
- return 0;
-}
-
-
-int
-write_out_new_ascii_header (const char *magic_string,
- struct cpio_file_stat *file_hdr, int out_des)
-{
- char ascii_header[110];
- char *p;
-
- p = stpcpy (ascii_header, magic_string);
- to_ascii_or_warn (p, file_hdr->c_ino, 8, LG_16,
- file_hdr->c_name, _("inode number"));
- p += 8;
- to_ascii_or_warn (p, file_hdr->c_mode, 8, LG_16, file_hdr->c_name,
- _("file mode"));
- p += 8;
- to_ascii_or_warn (p, file_hdr->c_uid, 8, LG_16, file_hdr->c_name,
- _("uid"));
- p += 8;
- to_ascii_or_warn (p, file_hdr->c_gid, 8, LG_16, file_hdr->c_name,
- _("gid"));
- p += 8;
- to_ascii_or_warn (p, file_hdr->c_nlink, 8, LG_16, file_hdr->c_name,
- _("number of links"));
- p += 8;
- to_ascii_or_warn (p, file_hdr->c_mtime, 8, LG_16, file_hdr->c_name,
- _("modification time"));
- p += 8;
- if (to_ascii_or_error (p, file_hdr->c_filesize, 8, LG_16, file_hdr->c_name,
- _("file size")))
- return 1;
- p += 8;
- if (to_ascii_or_error (p, file_hdr->c_dev_maj, 8, LG_16, file_hdr->c_name,
- _("device major number")))
- return 1;
- p += 8;
- if (to_ascii_or_error (p, file_hdr->c_dev_min, 8, LG_16, file_hdr->c_name,
- _("device minor number")))
- return 1;
- p += 8;
- if (to_ascii_or_error (p, file_hdr->c_rdev_maj, 8, LG_16, file_hdr->c_name,
- _("rdev major")))
- return 1;
- p += 8;
- if (to_ascii_or_error (p, file_hdr->c_rdev_min, 8, LG_16, file_hdr->c_name,
- _("rdev minor")))
- return 1;
- p += 8;
- if (to_ascii_or_error (p, file_hdr->c_namesize, 8, LG_16, file_hdr->c_name,
- _("name size")))
- return 1;
- p += 8;
- to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16);
-
- tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
-
- /* Write file name to output. */
- tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
- tape_pad_output (out_des, file_hdr->c_namesize + sizeof ascii_header);
- return 0;
-}
-
-int
-write_out_old_ascii_header (dev_t dev, dev_t rdev,
- struct cpio_file_stat *file_hdr, int out_des)
-{
- char ascii_header[76];
- char *p = ascii_header;
-
- to_ascii (p, file_hdr->c_magic, 6, LG_8);
- p += 6;
- to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number"));
- p += 6;
- to_ascii_or_warn (p, file_hdr->c_ino, 6, LG_8, file_hdr->c_name,
- _("inode number"));
- p += 6;
- to_ascii_or_warn (p, file_hdr->c_mode, 6, LG_8, file_hdr->c_name,
- _("file mode"));
- p += 6;
- to_ascii_or_warn (p, file_hdr->c_uid, 6, LG_8, file_hdr->c_name, _("uid"));
- p += 6;
- to_ascii_or_warn (p, file_hdr->c_gid, 6, LG_8, file_hdr->c_name, _("gid"));
- p += 6;
- to_ascii_or_warn (p, file_hdr->c_nlink, 6, LG_8, file_hdr->c_name,
- _("number of links"));
- p += 6;
- to_ascii_or_warn (p, rdev, 6, LG_8, file_hdr->c_name, _("rdev"));
- p += 6;
- to_ascii_or_warn (p, file_hdr->c_mtime, 11, LG_8, file_hdr->c_name,
- _("modification time"));
- p += 11;
- if (to_ascii_or_error (p, file_hdr->c_namesize, 6, LG_8, file_hdr->c_name,
- _("name size")))
- return 1;
- p += 6;
- if (to_ascii_or_error (p, file_hdr->c_filesize, 11, LG_8, file_hdr->c_name,
- _("file size")))
- return 1;
-
- tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
-
- /* Write file name to output. */
- tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
- return 0;
-}
-
-void
-hp_compute_dev (struct cpio_file_stat *file_hdr, dev_t *pdev, dev_t *prdev)
-{
- /* HP/UX cpio creates archives that look just like ordinary archives,
- but for devices it sets major = 0, minor = 1, and puts the
- actual major/minor number in the filesize field. */
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
- file_hdr->c_rdev_min);
- *pdev = *prdev = makedev (0, 1);
- break;
-
- default:
- *pdev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
- *prdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
- break;
- }
-}
-
-int
-write_out_binary_header (dev_t rdev,
- struct cpio_file_stat *file_hdr, int out_des)
-{
- struct old_cpio_header short_hdr;
-
- short_hdr.c_magic = 070707;
- short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
-
- if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
- error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
-
- short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
- if (short_hdr.c_ino != file_hdr->c_ino)
- field_width_warning (file_hdr->c_name, _("inode number"));
-
- short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
- if (short_hdr.c_mode != file_hdr->c_mode)
- field_width_warning (file_hdr->c_name, _("file mode"));
-
- short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
- if (short_hdr.c_uid != file_hdr->c_uid)
- field_width_warning (file_hdr->c_name, _("uid"));
-
- short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
- if (short_hdr.c_gid != file_hdr->c_gid)
- field_width_warning (file_hdr->c_name, _("gid"));
-
- short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
- if (short_hdr.c_nlink != file_hdr->c_nlink)
- field_width_warning (file_hdr->c_name, _("number of links"));
-
- short_hdr.c_rdev = rdev;
- short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
- short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
-
- short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
- if (short_hdr.c_namesize != file_hdr->c_namesize)
- {
- field_width_error (file_hdr->c_name, _("name size"));
- return 1;
- }
-
- short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
- short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
-
- if (((off_t)short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1]
- != file_hdr->c_filesize)
- {
- field_width_error (file_hdr->c_name, _("file size"));
- return 1;
- }
-
- /* Output the file header. */
- tape_buffered_write ((char *) &short_hdr, out_des, 26);
-
- /* Write file name to output. */
- tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
-
- tape_pad_output (out_des, file_hdr->c_namesize + 26);
- return 0;
-}
-
-
-/* Write out header FILE_HDR, including the file name, to file
- descriptor OUT_DES. */
-
-int
-write_out_header (struct cpio_file_stat *file_hdr, int out_des)
-{
- dev_t dev;
- dev_t rdev;
-
- switch (archive_format)
- {
- case arf_newascii:
- return write_out_new_ascii_header ("070701", file_hdr, out_des);
-
- case arf_crcascii:
- return write_out_new_ascii_header ("070702", file_hdr, out_des);
-
- case arf_oldascii:
- return write_out_old_ascii_header (makedev (file_hdr->c_dev_maj,
- file_hdr->c_dev_min),
- makedev (file_hdr->c_rdev_maj,
- file_hdr->c_rdev_min),
- file_hdr, out_des);
-
- case arf_hpoldascii:
- hp_compute_dev (file_hdr, &dev, &rdev);
- return write_out_old_ascii_header (dev, rdev, file_hdr, out_des);
-
- case arf_tar:
- case arf_ustar:
- if (is_tar_filename_too_long (file_hdr->c_name))
- {
- error (0, 0, _("%s: file name too long"), file_hdr->c_name);
- return 1;
- }
- write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */
- return 0;
-
- case arf_binary:
- return write_out_binary_header (makedev (file_hdr->c_rdev_maj,
- file_hdr->c_rdev_min),
- file_hdr, out_des);
-
- case arf_hpbinary:
- hp_compute_dev (file_hdr, &dev, &rdev);
- /* FIXME: dev ignored. Should it be? */
- return write_out_binary_header (rdev, file_hdr, out_des);
-
- default:
- abort ();
- }
-}
-
-static void
-assign_string (char **pvar, char *value)
-{
- char *p = xrealloc (*pvar, strlen (value) + 1);
- strcpy (p, value);
- *pvar = p;
-}
-
-/* Read a list of file names from the standard input
- and write a cpio collection on the standard output.
- The format of the header depends on the compatibility (-c) flag. */
-
-void
-process_copy_out ()
-{
- int res; /* Result of functions. */
- dynamic_string input_name; /* Name of file read from stdin. */
- struct stat file_stat; /* Stat record for file. */
- struct cpio_file_stat file_hdr; /* Output header information. */
- int in_file_des; /* Source file descriptor. */
- int out_file_des; /* Output file descriptor. */
- char *orig_file_name = NULL;
-
- /* Initialize the copy out. */
- ds_init (&input_name, 128);
- file_hdr.c_magic = 070707;
-
- /* Check whether the output file might be a tape. */
- out_file_des = archive_des;
- if (_isrmt (out_file_des))
- {
- output_is_special = 1;
- output_is_seekable = 0;
- }
- else
- {
- if (fstat (out_file_des, &file_stat))
- error (1, errno, _("standard output is closed"));
- output_is_special =
-#ifdef S_ISBLK
- S_ISBLK (file_stat.st_mode) ||
-#endif
- S_ISCHR (file_stat.st_mode);
- output_is_seekable = S_ISREG (file_stat.st_mode);
- }
-
- if (append_flag)
- {
- process_copy_in ();
- prepare_append (out_file_des);
- }
-
- /* Copy files with names read from stdin. */
- while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
- {
- /* Check for blank line. */
- if (input_name.ds_string[0] == 0)
- {
- error (0, 0, _("blank line ignored"));
- continue;
- }
-
- /* Process next file. */
- if ((*xstat) (input_name.ds_string, &file_stat) < 0)
- stat_error (input_name.ds_string);
- else
- {
- /* Set values in output header. */
- stat_to_cpio (&file_hdr, &file_stat);
-
- if (archive_format == arf_tar || archive_format == arf_ustar)
- {
- if (file_hdr.c_mode & CP_IFDIR)
- {
- int len = strlen (input_name.ds_string);
- /* Make sure the name ends with a slash */
- if (input_name.ds_string[len-1] != '/')
- {
- ds_resize (&input_name, len + 2);
- input_name.ds_string[len] = '/';
- input_name.ds_string[len+1] = 0;
- }
- }
- }
-
- switch (check_rdev (&file_hdr))
- {
- case 1:
- error (0, 0, "%s not dumped: major number would be truncated",
- file_hdr.c_name);
- continue;
- case 2:
- error (0, 0, "%s not dumped: minor number would be truncated",
- file_hdr.c_name);
- continue;
- case 4:
- error (0, 0, "%s not dumped: device number would be truncated",
- file_hdr.c_name);
- continue;
- }
-
- assign_string (&orig_file_name, input_name.ds_string);
- cpio_safer_name_suffix (input_name.ds_string, false,
- abs_paths_flag, true);
-#ifndef HPUX_CDF
- file_hdr.c_name = input_name.ds_string;
- file_hdr.c_namesize = strlen (input_name.ds_string) + 1;
-#else
- if ( (archive_format != arf_tar) && (archive_format != arf_ustar) )
- {
- /* We mark CDF's in cpio files by adding a 2nd `/' after the
- "hidden" directory name. We need to do this so we can
- properly recreate the directory as hidden (in case the
- files of a directory go into the archive before the
- directory itself (e.g from "find ... -depth ... | cpio")). */
- file_hdr.c_name = add_cdf_double_slashes (input_name.ds_string);
- file_hdr.c_namesize = strlen (file_hdr.c_name) + 1;
- }
- else
- {
- /* We don't mark CDF's in tar files. We assume the "hidden"
- directory will always go into the archive before any of
- its files. */
- file_hdr.c_name = input_name.ds_string;
- file_hdr.c_namesize = strlen (input_name.ds_string) + 1;
- }
-#endif
-
- /* Copy the named file to the output. */
- switch (file_hdr.c_mode & CP_IFMT)
- {
- case CP_IFREG:
- if (archive_format == arf_tar || archive_format == arf_ustar)
- {
- char *otherfile;
- if ((otherfile = find_inode_file (file_hdr.c_ino,
- file_hdr.c_dev_maj,
- file_hdr.c_dev_min)))
- {
- file_hdr.c_tar_linkname = otherfile;
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- break;
- }
- }
- if ( (archive_format == arf_newascii || archive_format == arf_crcascii)
- && (file_hdr.c_nlink > 1) )
- {
- if (last_link (&file_hdr) )
- {
- writeout_other_defers (&file_hdr, out_file_des);
- }
- else
- {
- add_link_defer (&file_hdr);
- break;
- }
- }
- in_file_des = open (orig_file_name,
- O_RDONLY | O_BINARY, 0);
- if (in_file_des < 0)
- {
- open_error (orig_file_name);
- continue;
- }
-
- if (archive_format == arf_crcascii)
- file_hdr.c_chksum = read_for_checksum (in_file_des,
- file_hdr.c_filesize,
- orig_file_name);
-
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- copy_files_disk_to_tape (in_file_des,
- out_file_des, file_hdr.c_filesize,
- orig_file_name);
- warn_if_file_changed(orig_file_name, file_hdr.c_filesize,
- file_hdr.c_mtime);
-
- if (archive_format == arf_tar || archive_format == arf_ustar)
- add_inode (file_hdr.c_ino, orig_file_name, file_hdr.c_dev_maj,
- file_hdr.c_dev_min);
-
- tape_pad_output (out_file_des, file_hdr.c_filesize);
-
- if (reset_time_flag)
- set_file_times (in_file_des,
- orig_file_name,
- file_stat.st_atime, file_stat.st_mtime);
- if (close (in_file_des) < 0)
- close_error (orig_file_name);
- break;
-
- case CP_IFDIR:
- file_hdr.c_filesize = 0;
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- break;
-
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- if (archive_format == arf_tar)
- {
- error (0, 0, _("%s not dumped: not a regular file"),
- orig_file_name);
- continue;
- }
- else if (archive_format == arf_ustar)
- {
- char *otherfile;
- if ((otherfile = find_inode_file (file_hdr.c_ino,
- file_hdr.c_dev_maj,
- file_hdr.c_dev_min)))
- {
- /* This file is linked to another file already in the
- archive, so write it out as a hard link. */
- file_hdr.c_mode = (file_stat.st_mode & 07777);
- file_hdr.c_mode |= CP_IFREG;
- file_hdr.c_tar_linkname = otherfile;
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- break;
- }
- add_inode (file_hdr.c_ino, orig_file_name,
- file_hdr.c_dev_maj, file_hdr.c_dev_min);
- }
- file_hdr.c_filesize = 0;
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- break;
-
-#ifdef CP_IFLNK
- case CP_IFLNK:
- {
- char *link_name = (char *) xmalloc (file_stat.st_size + 1);
- int link_size;
-
- link_size = readlink (orig_file_name, link_name,
- file_stat.st_size);
- if (link_size < 0)
- {
- readlink_warn (orig_file_name);
- free (link_name);
- continue;
- }
- link_name[link_size] = 0;
- cpio_safer_name_suffix (link_name, false,
- abs_paths_flag, true);
- link_size = strlen (link_name);
- file_hdr.c_filesize = link_size;
- if (archive_format == arf_tar || archive_format == arf_ustar)
- {
- if (link_size + 1 > 100)
- {
- error (0, 0, _("%s: symbolic link too long"),
- file_hdr.c_name);
- }
- else
- {
- link_name[link_size] = '\0';
- file_hdr.c_tar_linkname = link_name;
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- }
- }
- else
- {
- if (write_out_header (&file_hdr, out_file_des))
- continue;
- tape_buffered_write (link_name, out_file_des, link_size);
- tape_pad_output (out_file_des, link_size);
- }
- free (link_name);
- }
- break;
-#endif
-
- default:
- error (0, 0, _("%s: unknown file type"), orig_file_name);
- }
-
- if (verbose_flag)
- fprintf (stderr, "%s\n", orig_file_name);
- if (dot_flag)
- fputc ('.', stderr);
- }
- }
-
- free (orig_file_name);
-
- writeout_final_defers(out_file_des);
- /* The collection is complete; append the trailer. */
- file_hdr.c_ino = 0;
- file_hdr.c_mode = 0;
- file_hdr.c_uid = 0;
- file_hdr.c_gid = 0;
- file_hdr.c_nlink = 1; /* Must be 1 for crc format. */
- file_hdr.c_dev_maj = 0;
- file_hdr.c_dev_min = 0;
- file_hdr.c_rdev_maj = 0;
- file_hdr.c_rdev_min = 0;
- file_hdr.c_mtime = 0;
- file_hdr.c_chksum = 0;
-
- file_hdr.c_filesize = 0;
- file_hdr.c_namesize = 11;
- file_hdr.c_name = CPIO_TRAILER_NAME;
- if (archive_format != arf_tar && archive_format != arf_ustar)
- write_out_header (&file_hdr, out_file_des);
- else
- write_nuls_to_file (1024, out_file_des, tape_buffered_write);
-
- /* Fill up the output block. */
- tape_clear_rest_of_block (out_file_des);
- tape_empty_output_buffer (out_file_des);
- if (dot_flag)
- fputc ('\n', stderr);
- if (!quiet_flag)
- {
- res = (output_bytes + io_block_size - 1) / io_block_size;
- fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res);
- }
-}
-
-static int
-check_rdev (file_hdr)
- struct cpio_file_stat *file_hdr;
-{
- if (archive_format == arf_newascii || archive_format == arf_crcascii)
- {
- if ((file_hdr->c_rdev_maj & 0xFFFFFFFF) != file_hdr->c_rdev_maj)
- return 1;
- if ((file_hdr->c_rdev_min & 0xFFFFFFFF) != file_hdr->c_rdev_min)
- return 2;
- }
- else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
- {
-#ifndef __MSDOS__
- dev_t rdev;
-
- rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
- if (archive_format == arf_oldascii)
- {
- if ((rdev & 0xFFFF) != rdev)
- return 4;
- }
- else
- {
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- /* We could handle one more bit if longs are >= 33 bits. */
- if ((rdev & 037777777777) != rdev)
- return 4;
- break;
- default:
- if ((rdev & 0xFFFF) != rdev)
- return 4;
- break;
- }
- }
-#endif
- }
- else if (archive_format == arf_tar || archive_format == arf_ustar)
- {
- /* The major and minor formats are limited to 7 octal digits in ustar
- format, and to_oct () adds a gratuitous trailing blank to further
- limit the format to 6 octal digits. */
- if ((file_hdr->c_rdev_maj & 0777777) != file_hdr->c_rdev_maj)
- return 1;
- if ((file_hdr->c_rdev_min & 0777777) != file_hdr->c_rdev_min)
- return 2;
- }
- else
- {
-#ifndef __MSDOS__
- dev_t rdev;
-
- rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
- if (archive_format != arf_hpbinary)
- {
- if ((rdev & 0xFFFF) != rdev)
- return 4;
- }
- else
- {
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFCHR:
- case CP_IFBLK:
-#ifdef CP_IFSOCK
- case CP_IFSOCK:
-#endif
-#ifdef CP_IFIFO
- case CP_IFIFO:
-#endif
- if ((rdev & 0xFFFFFFFF) != rdev)
- return 4;
- file_hdr->c_filesize = rdev;
- rdev = makedev (0, 1);
- break;
- default:
- if ((rdev & 0xFFFF) != rdev)
- return 4;
- break;
- }
- }
-#endif
- }
- return 0;
-}
diff --git a/contrib/cpio/src/copypass.c b/contrib/cpio/src/copypass.c
deleted file mode 100644
index bdcbbeb..0000000
--- a/contrib/cpio/src/copypass.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* $FreeBSD$ */
-
-/* copypass.c - cpio copy pass sub-function.
- Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004,
- 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "filetypes.h"
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-#include "paxlib.h"
-
-#ifndef HAVE_LCHOWN
-# define lchown chown
-#endif
-
-
-/* A wrapper around set_perms using another set of arguments */
-static void
-set_copypass_perms (int fd, const char *name, struct stat *st)
-{
- struct cpio_file_stat header;
- header.c_name = name;
- stat_to_cpio (&header, st);
- set_perms (fd, &header);
-}
-
-/* Copy files listed on the standard input into directory `directory_name'.
- If `link_flag', link instead of copying. */
-
-void
-process_copy_pass ()
-{
- dynamic_string input_name; /* Name of file from stdin. */
- dynamic_string output_name; /* Name of new file. */
- int dirname_len; /* Length of `directory_name'. */
- int res; /* Result of functions. */
- char *slash; /* For moving past slashes in input name. */
- struct stat in_file_stat; /* Stat record for input file. */
- struct stat out_file_stat; /* Stat record for output file. */
- int in_file_des; /* Input file descriptor. */
- int out_file_des; /* Output file descriptor. */
- int existing_dir; /* True if file is a dir & already exists. */
-#ifdef HPUX_CDF
- int cdf_flag;
- int cdf_char;
-#endif
-
- umask (0); /* Reset umask to preserve modes of
- created files */
-
- /* Initialize the copy pass. */
- dirname_len = strlen (directory_name);
- ds_init (&input_name, 128);
- ds_init (&output_name, dirname_len + 2);
- strcpy (output_name.ds_string, directory_name);
- output_name.ds_string[dirname_len] = '/';
- output_is_seekable = true;
-
- /* Copy files with names read from stdin. */
- while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
- {
- int link_res = -1;
-
- /* Check for blank line and ignore it if found. */
- if (input_name.ds_string[0] == '\0')
- {
- error (0, 0, _("blank line ignored"));
- continue;
- }
-
- /* Check for current directory and ignore it if found. */
- if (input_name.ds_string[0] == '.'
- && (input_name.ds_string[1] == '\0'
- || (input_name.ds_string[1] == '/'
- && input_name.ds_string[2] == '\0')))
- continue;
-
- if ((*xstat) (input_name.ds_string, &in_file_stat) < 0)
- {
- stat_error (input_name.ds_string);
- continue;
- }
-
- /* Make the name of the new file. */
- for (slash = input_name.ds_string; *slash == '/'; ++slash)
- ;
-#ifdef HPUX_CDF
- /* For CDF's we add a 2nd `/' after all "hidden" directories.
- This kind of a kludge, but it's what we do when creating
- archives, and it's easier to do this than to separately
- keep track of which directories in a path are "hidden". */
- slash = add_cdf_double_slashes (slash);
-#endif
- ds_resize (&output_name, dirname_len + strlen (slash) + 2);
- strcpy (output_name.ds_string + dirname_len + 1, slash);
-
- existing_dir = false;
- if (lstat (output_name.ds_string, &out_file_stat) == 0)
- {
- if (S_ISDIR (out_file_stat.st_mode)
- && S_ISDIR (in_file_stat.st_mode))
- {
- /* If there is already a directory there that
- we are trying to create, don't complain about it. */
- existing_dir = true;
- }
- else if (!unconditional_flag
- && in_file_stat.st_mtime <= out_file_stat.st_mtime)
- {
- error (0, 0, _("%s not created: newer or same age version exists"),
- output_name.ds_string);
- continue; /* Go to the next file. */
- }
- else if (S_ISDIR (out_file_stat.st_mode)
- ? rmdir (output_name.ds_string)
- : unlink (output_name.ds_string))
- {
- error (0, errno, _("cannot remove current %s"),
- output_name.ds_string);
- continue; /* Go to the next file. */
- }
- }
-
- /* Do the real copy or link. */
- if (S_ISREG (in_file_stat.st_mode))
- {
- /* Can the current file be linked to a another file?
- Set link_name to the original file name. */
- if (link_flag)
- /* User said to link it if possible. Try and link to
- the original copy. If that fails we'll still try
- and link to a copy we've already made. */
- link_res = link_to_name (output_name.ds_string,
- input_name.ds_string);
- if ( (link_res < 0) && (in_file_stat.st_nlink > 1) )
- link_res = link_to_maj_min_ino (output_name.ds_string,
- major (in_file_stat.st_dev),
- minor (in_file_stat.st_dev),
- in_file_stat.st_ino);
-
- /* If the file was not linked, copy contents of file. */
- if (link_res < 0)
- {
- in_file_des = open (input_name.ds_string,
- O_RDONLY | O_BINARY, 0);
- if (in_file_des < 0)
- {
- open_error (input_name.ds_string);
- continue;
- }
- out_file_des = open (output_name.ds_string,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
- if (out_file_des < 0 && create_dir_flag)
- {
- create_all_directories (output_name.ds_string);
- out_file_des = open (output_name.ds_string,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
- }
- if (out_file_des < 0)
- {
- open_error (output_name.ds_string);
- close (in_file_des);
- continue;
- }
-
- copy_files_disk_to_disk (in_file_des, out_file_des, in_file_stat.st_size, input_name.ds_string);
- disk_empty_output_buffer (out_file_des);
- /* Debian hack to fix a bug in the --sparse option.
- This bug has been reported to
- "bug-gnu-utils@prep.ai.mit.edu". (96/7/10) -BEM */
- if (delayed_seek_count > 0)
- {
- lseek (out_file_des, delayed_seek_count-1, SEEK_CUR);
- write (out_file_des, "", 1);
- delayed_seek_count = 0;
- }
-
- set_copypass_perms (out_file_des,
- output_name.ds_string, &in_file_stat);
-
- if (reset_time_flag)
- {
- set_file_times (in_file_des,
- input_name.ds_string,
- in_file_stat.st_atime,
- in_file_stat.st_mtime);
- set_file_times (out_file_des,
- output_name.ds_string,
- in_file_stat.st_atime,
- in_file_stat.st_mtime);
- }
-
- if (close (in_file_des) < 0)
- close_error (input_name.ds_string);
-
- if (close (out_file_des) < 0)
- close_error (output_name.ds_string);
-
- warn_if_file_changed(input_name.ds_string, in_file_stat.st_size,
- in_file_stat.st_mtime);
- }
- }
- else if (S_ISDIR (in_file_stat.st_mode))
- {
-#ifdef HPUX_CDF
- cdf_flag = 0;
-#endif
- if (!existing_dir)
- {
-#ifdef HPUX_CDF
- /* If the directory name ends in a + and is SUID,
- then it is a CDF. Strip the trailing + from the name
- before creating it. */
- cdf_char = strlen (output_name.ds_string) - 1;
- if ( (cdf_char > 0) &&
- (in_file_stat.st_mode & 04000) &&
- (output_name.ds_string [cdf_char] == '+') )
- {
- output_name.ds_string [cdf_char] = '\0';
- cdf_flag = 1;
- }
-#endif
- res = mkdir (output_name.ds_string, in_file_stat.st_mode);
-
- }
- else
- res = 0;
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (output_name.ds_string);
- res = mkdir (output_name.ds_string, in_file_stat.st_mode);
- }
- if (res < 0)
- {
- /* In some odd cases where the output_name includes `.',
- the directory may have actually been created by
- create_all_directories(), so the mkdir will fail
- because the directory exists. If that's the case,
- don't complain about it. */
- if ( (errno != EEXIST) ||
- (lstat (output_name.ds_string, &out_file_stat) != 0) ||
- !(S_ISDIR (out_file_stat.st_mode) ) )
- {
- stat_error (output_name.ds_string);
- continue;
- }
- }
- set_copypass_perms (-1, output_name.ds_string, &in_file_stat);
- }
- else if (S_ISCHR (in_file_stat.st_mode) ||
- S_ISBLK (in_file_stat.st_mode) ||
-#ifdef S_ISFIFO
- S_ISFIFO (in_file_stat.st_mode) ||
-#endif
-#ifdef S_ISSOCK
- S_ISSOCK (in_file_stat.st_mode) ||
-#endif
- 0)
- {
- /* Can the current file be linked to a another file?
- Set link_name to the original file name. */
- if (link_flag)
- /* User said to link it if possible. */
- link_res = link_to_name (output_name.ds_string,
- input_name.ds_string);
- if ( (link_res < 0) && (in_file_stat.st_nlink > 1) )
- link_res = link_to_maj_min_ino (output_name.ds_string,
- major (in_file_stat.st_dev),
- minor (in_file_stat.st_dev),
- in_file_stat.st_ino);
-
- if (link_res < 0)
- {
-#ifdef S_ISFIFO
- if (S_ISFIFO (in_file_stat.st_mode))
- res = mkfifo (output_name.ds_string, in_file_stat.st_mode);
- else
-#endif
- res = mknod (output_name.ds_string, in_file_stat.st_mode,
- in_file_stat.st_rdev);
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (output_name.ds_string);
-#ifdef S_ISFIFO
- if (S_ISFIFO (in_file_stat.st_mode))
- res = mkfifo (output_name.ds_string, in_file_stat.st_mode);
- else
-#endif
- res = mknod (output_name.ds_string, in_file_stat.st_mode,
- in_file_stat.st_rdev);
- }
- if (res < 0)
- {
- mknod_error (output_name.ds_string);
- continue;
- }
- set_copypass_perms (-1, output_name.ds_string, &in_file_stat);
- }
- }
-
-#ifdef S_ISLNK
- else if (S_ISLNK (in_file_stat.st_mode))
- {
- char *link_name;
- int link_size;
- link_name = (char *) xmalloc ((unsigned int) in_file_stat.st_size + 1);
-
- link_size = readlink (input_name.ds_string, link_name,
- in_file_stat.st_size);
- if (link_size < 0)
- {
- readlink_error (input_name.ds_string);
- free (link_name);
- continue;
- }
- link_name[link_size] = '\0';
-
- res = UMASKED_SYMLINK (link_name, output_name.ds_string,
- in_file_stat.st_mode);
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (output_name.ds_string);
- res = UMASKED_SYMLINK (link_name, output_name.ds_string,
- in_file_stat.st_mode);
- }
- if (res < 0)
- {
- symlink_error (output_name.ds_string, link_name);
- free (link_name);
- continue;
- }
-
- /* Set the attributes of the new link. */
- if (!no_chown_flag)
- {
- uid_t uid = set_owner_flag ? set_owner : in_file_stat.st_uid;
- gid_t gid = set_group_flag ? set_group : in_file_stat.st_gid;
- if ((lchown (output_name.ds_string, uid, gid) < 0)
- && errno != EPERM)
- chown_error_details (output_name.ds_string, uid, gid);
- }
- free (link_name);
- }
-#endif
- else
- {
- error (0, 0, _("%s: unknown file type"), input_name.ds_string);
- }
-
- if (verbose_flag)
- fprintf (stderr, "%s\n", output_name.ds_string);
- if (dot_flag)
- fputc ('.', stderr);
- }
-
- if (dot_flag)
- fputc ('\n', stderr);
- if (!quiet_flag)
- {
- res = (output_bytes + io_block_size - 1) / io_block_size;
- fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res);
- }
-}
-
-/* Try and create a hard link from FILE_NAME to another file
- with the given major/minor device number and inode. If no other
- file with the same major/minor/inode numbers is known, add this file
- to the list of known files and associated major/minor/inode numbers
- and return -1. If another file with the same major/minor/inode
- numbers is found, try and create another link to it using
- link_to_name, and return 0 for success and -1 for failure. */
-
-int
-link_to_maj_min_ino (char *file_name, int st_dev_maj, int st_dev_min,
- int st_ino)
-{
- int link_res;
- char *link_name;
- link_res = -1;
- /* Is the file a link to a previously copied file? */
- link_name = find_inode_file (st_ino,
- st_dev_maj,
- st_dev_min);
- if (link_name == NULL)
- add_inode (st_ino, file_name,
- st_dev_maj,
- st_dev_min);
- else
- link_res = link_to_name (file_name, link_name);
- return link_res;
-}
-
-/* Try and create a hard link from LINK_NAME to LINK_TARGET. If
- `create_dir_flag' is set, any non-existent (parent) directories
- needed by LINK_NAME will be created. If the link is successfully
- created and `verbose_flag' is set, print "LINK_TARGET linked to LINK_NAME\n".
- If the link can not be created and `link_flag' is set, print
- "cannot link LINK_TARGET to LINK_NAME\n". Return 0 if the link
- is created, -1 otherwise. */
-
-int
-link_to_name (char *link_name, char *link_target)
-{
- int res = link (link_target, link_name);
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (link_name);
- res = link (link_target, link_name);
- }
- if (res == 0)
- {
- if (verbose_flag)
- error (0, 0, _("%s linked to %s"),
- link_target, link_name);
- }
- else if (link_flag)
- {
- error (0, errno, _("cannot link %s to %s (will copy instead)"),
- link_target, link_name);
- }
- return res;
-}
diff --git a/contrib/cpio/src/cpio.h b/contrib/cpio/src/cpio.h
deleted file mode 100644
index 34d1cf1..0000000
--- a/contrib/cpio/src/cpio.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Extended cpio format from POSIX.1.
- Copyright (C) 1992, 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#ifndef _CPIO_H
-
-#define _CPIO_H 1
-
-/* A cpio archive consists of a sequence of files.
- Each file has a 76 byte header,
- a variable length, NUL terminated filename,
- and variable length file data.
- A header for a filename "TRAILER!!!" indicates the end of the archive. */
-
-#define CPIO_TRAILER_NAME "TRAILER!!!"
-
-/* All the fields in the header are ISO 646 (approximately ASCII) strings
- of octal numbers, left padded, not NUL terminated.
-
- Field Name Length in Bytes Notes
- c_magic 6 must be "070707"
- c_dev 6
- c_ino 6
- c_mode 6 see below for value
- c_uid 6
- c_gid 6
- c_nlink 6
- c_rdev 6 only valid for chr and blk special files
- c_mtime 11
- c_namesize 6 count includes terminating NUL in pathname
- c_filesize 11 must be 0 for FIFOs and directories */
-
-/* Values for c_mode, OR'd together: */
-
-#define C_IRUSR 000400
-#define C_IWUSR 000200
-#define C_IXUSR 000100
-#define C_IRGRP 000040
-#define C_IWGRP 000020
-#define C_IXGRP 000010
-#define C_IROTH 000004
-#define C_IWOTH 000002
-#define C_IXOTH 000001
-
-#define C_ISUID 004000
-#define C_ISGID 002000
-#define C_ISVTX 001000
-
-#define C_ISBLK 060000
-#define C_ISCHR 020000
-#define C_ISDIR 040000
-#define C_ISFIFO 010000
-#define C_ISSOCK 0140000
-#define C_ISLNK 0120000
-#define C_ISCTG 0110000
-#define C_ISREG 0100000
-
-#endif /* cpio.h */
diff --git a/contrib/cpio/src/cpiohdr.h b/contrib/cpio/src/cpiohdr.h
deleted file mode 100644
index 503563f..0000000
--- a/contrib/cpio/src/cpiohdr.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Extended cpio header from POSIX.1.
- Copyright (C) 1992, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#ifndef _CPIOHDR_H
-
-#define _CPIOHDR_H 1
-
-#include <cpio.h>
-
-struct old_cpio_header
-{
- unsigned short c_magic;
- short c_dev;
- unsigned short c_ino;
- unsigned short c_mode;
- unsigned short c_uid;
- unsigned short c_gid;
- unsigned short c_nlink;
- short c_rdev;
- unsigned short c_mtimes[2];
- unsigned short c_namesize;
- unsigned short c_filesizes[2];
-};
-
-struct old_ascii_header
-{
- char c_magic[6];
- char c_dev[6];
- char c_ino[6];
- char c_mode[6];
- char c_uid[6];
- char c_gid[6];
- char c_nlink[6];
- char c_rdev[6];
- char c_mtime[11];
- char c_namesize[6];
- char c_filesize[11];
-};
-
-/* "New" portable format and CRC format:
-
- Each file has a 110 byte header,
- a variable length, NUL terminated filename,
- and variable length file data.
- A header for a filename "TRAILER!!!" indicates the end of the archive. */
-
-/* All the fields in the header are ISO 646 (approximately ASCII) strings
- of hexadecimal numbers, left padded, not NUL terminated: */
-
-struct new_ascii_header
-{
- char c_magic[6]; /* "070701" for "new" portable format
- "070702" for CRC format */
- char c_ino[8];
- char c_mode[8];
- char c_uid[8];
- char c_gid[8];
- char c_nlink[8];
- char c_mtime[8];
- char c_filesize[8]; /* must be 0 for FIFOs and directories */
- char c_dev_maj[8];
- char c_dev_min[8];
- char c_rdev_maj[8]; /* only valid for chr and blk special files */
- char c_rdev_min[8]; /* only valid for chr and blk special files */
- char c_namesize[8]; /* count includes terminating NUL in pathname */
- char c_chksum[8]; /* 0 for "new" portable format; for CRC format
- the sum of all the bytes in the file */
-};
-
-struct cpio_file_stat /* Internal representation of a CPIO header */
-{
- unsigned short c_magic;
- ino_t c_ino;
- mode_t c_mode;
- uid_t c_uid;
- gid_t c_gid;
- size_t c_nlink;
- time_t c_mtime;
- off_t c_filesize;
- long c_dev_maj;
- long c_dev_min;
- long c_rdev_maj;
- long c_rdev_min;
- size_t c_namesize;
- unsigned long c_chksum;
- char *c_name;
- char *c_tar_linkname;
-};
-
-
-#endif /* cpiohdr.h */
diff --git a/contrib/cpio/src/defer.c b/contrib/cpio/src/defer.c
deleted file mode 100644
index 83e15dd..0000000
--- a/contrib/cpio/src/defer.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* defer.c - handle "defered" links in newc and crc archives
- Copyright (C) 1993, 2003, 2004, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include "cpiohdr.h"
-#include "extern.h"
-#include "defer.h"
-
-struct deferment *
-create_deferment (struct cpio_file_stat *file_hdr)
-{
- struct deferment *d;
- d = (struct deferment *) xmalloc (sizeof (struct deferment) );
- d->header = *file_hdr;
- d->header.c_name = (char *) xmalloc (strlen (file_hdr->c_name) + 1);
- strcpy (d->header.c_name, file_hdr->c_name);
- return d;
-}
-
-void
-free_deferment (struct deferment *d)
-{
- free (d->header.c_name);
- free (d);
-}
diff --git a/contrib/cpio/src/defer.h b/contrib/cpio/src/defer.h
deleted file mode 100644
index 00aafec..0000000
--- a/contrib/cpio/src/defer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* defer.h
- Copyright (C) 1993, 2001, 2004, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-struct deferment
- {
- struct deferment *next;
- struct cpio_file_stat header;
- };
-
-struct deferment *create_deferment (struct cpio_file_stat *file_hdr);
-void free_deferment (struct deferment *d);
diff --git a/contrib/cpio/src/dstring.c b/contrib/cpio/src/dstring.c
deleted file mode 100644
index aefeab8..0000000
--- a/contrib/cpio/src/dstring.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* dstring.c - The dynamic string handling routines used by cpio.
- Copyright (C) 1990, 1991, 1992, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#if defined(HAVE_CONFIG_H)
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#include "dstring.h"
-
-char *xmalloc (unsigned n);
-char *xrealloc (char *p, unsigned n);
-
-/* Initialiaze dynamic string STRING with space for SIZE characters. */
-
-void
-ds_init (dynamic_string *string, int size)
-{
- string->ds_length = size;
- string->ds_string = (char *) xmalloc (size);
-}
-
-/* Expand dynamic string STRING, if necessary, to hold SIZE characters. */
-
-void
-ds_resize (dynamic_string *string, int size)
-{
- if (size > string->ds_length)
- {
- string->ds_length = size;
- string->ds_string = (char *) xrealloc ((char *) string->ds_string, size);
- }
-}
-
-/* Dynamic string S gets a string terminated by the EOS character
- (which is removed) from file F. S will increase
- in size during the function if the string from F is longer than
- the current size of S.
- Return NULL if end of file is detected. Otherwise,
- Return a pointer to the null-terminated string in S. */
-
-char *
-ds_fgetstr (FILE *f, dynamic_string *s, char eos)
-{
- int insize; /* Amount needed for line. */
- int strsize; /* Amount allocated for S. */
- int next_ch;
-
- /* Initialize. */
- insize = 0;
- strsize = s->ds_length;
-
- /* Read the input string. */
- next_ch = getc (f);
- while (next_ch != eos && next_ch != EOF)
- {
- if (insize >= strsize - 1)
- {
- ds_resize (s, strsize * 2 + 2);
- strsize = s->ds_length;
- }
- s->ds_string[insize++] = next_ch;
- next_ch = getc (f);
- }
- s->ds_string[insize++] = '\0';
-
- if (insize == 1 && next_ch == EOF)
- return NULL;
- else
- return s->ds_string;
-}
-
-char *
-ds_fgets (FILE *f, dynamic_string *s)
-{
- return ds_fgetstr (f, s, '\n');
-}
-
-char *
-ds_fgetname (FILE *f, dynamic_string *s)
-{
- return ds_fgetstr (f, s, '\0');
-}
diff --git a/contrib/cpio/src/dstring.h b/contrib/cpio/src/dstring.h
deleted file mode 100644
index 3628b99..0000000
--- a/contrib/cpio/src/dstring.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* dstring.h - Dynamic string handling include file. Requires strings.h.
- Copyright (C) 1990, 1991, 1992, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* A dynamic string consists of record that records the size of an
- allocated string and the pointer to that string. The actual string
- is a normal zero byte terminated string that can be used with the
- usual string functions. The major difference is that the
- dynamic_string routines know how to get more space if it is needed
- by allocating new space and copying the current string. */
-
-typedef struct
-{
- int ds_length; /* Actual amount of storage allocated. */
- char *ds_string; /* String. */
-} dynamic_string;
-
-
-/* Macros that look similar to the original string functions.
- WARNING: These macros work only on pointers to dynamic string records.
- If used with a real record, an "&" must be used to get the pointer. */
-#define ds_strlen(s) strlen ((s)->ds_string)
-#define ds_strcmp(s1, s2) strcmp ((s1)->ds_string, (s2)->ds_string)
-#define ds_strncmp(s1, s2, n) strncmp ((s1)->ds_string, (s2)->ds_string, n)
-#define ds_index(s, c) index ((s)->ds_string, c)
-#define ds_rindex(s, c) rindex ((s)->ds_string, c)
-
-void ds_init (dynamic_string *string, int size);
-void ds_resize (dynamic_string *string, int size);
-char *ds_fgetname (FILE *f, dynamic_string *s);
-char *ds_fgets (FILE *f, dynamic_string *s);
-char *ds_fgetstr (FILE *f, dynamic_string *s, char eos);
diff --git a/contrib/cpio/src/extern.h b/contrib/cpio/src/extern.h
deleted file mode 100644
index cc5bf89..0000000
--- a/contrib/cpio/src/extern.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/* extern.h - External declarations for cpio. Requires system.h.
- Copyright (C) 1990, 1991, 1992, 2001, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include "paxlib.h"
-#include "quotearg.h"
-#include "quote.h"
-
-enum archive_format
-{
- arf_unknown, arf_binary, arf_oldascii, arf_newascii, arf_crcascii,
- arf_tar, arf_ustar, arf_hpoldascii, arf_hpbinary
-};
-
-extern enum archive_format archive_format;
-extern int reset_time_flag;
-extern int io_block_size;
-extern int create_dir_flag;
-extern int rename_flag;
-extern char *rename_batch_file;
-extern int table_flag;
-extern int unconditional_flag;
-extern int verbose_flag;
-extern int dot_flag;
-extern int link_flag;
-extern int retain_time_flag;
-extern int crc_i_flag;
-extern int append_flag;
-extern int swap_bytes_flag;
-extern int swap_halfwords_flag;
-extern int swapping_bytes;
-extern int swapping_halfwords;
-extern int set_owner_flag;
-extern uid_t set_owner;
-extern int set_group_flag;
-extern gid_t set_group;
-extern int no_chown_flag;
-extern int sparse_flag;
-extern int quiet_flag;
-extern int only_verify_crc_flag;
-extern int abs_paths_flag;
-extern unsigned int warn_option;
-
-/* Values for warn_option */
-#define CPIO_WARN_NONE 0
-#define CPIO_WARN_TRUNCATE 0x01
-#define CPIO_WARN_ALL (unsigned int)-1
-
-extern bool to_stdout_option;
-
-extern int last_header_start;
-extern int copy_matching_files;
-extern int numeric_uid;
-extern char *pattern_file_name;
-extern char *new_media_message;
-extern char *new_media_message_with_number;
-extern char *new_media_message_after_number;
-extern int archive_des;
-extern char *archive_name;
-extern char *rsh_command_option;
-extern unsigned int crc;
-extern int delayed_seek_count;
-#ifdef DEBUG_CPIO
-extern int debug_flag;
-#endif
-
-extern char *input_buffer, *output_buffer;
-extern char *in_buff, *out_buff;
-extern long input_buffer_size;
-extern long input_size, output_size;
-#ifdef __GNUC__
-extern long long input_bytes, output_bytes;
-#else
-extern long input_bytes, output_bytes;
-#endif
-extern char *directory_name;
-extern char **save_patterns;
-extern int num_patterns;
-extern char name_end;
-extern char input_is_special;
-extern char output_is_special;
-extern char input_is_seekable;
-extern char output_is_seekable;
-extern char *program_name;
-extern int (*xstat) ();
-extern void (*copy_function) ();
-
-
-/* copyin.c */
-void warn_junk_bytes (long bytes_skipped);
-/* FIXME: make read_* static in copyin.c */
-void read_in_header (struct cpio_file_stat *file_hdr, int in_des);
-void read_in_old_ascii (struct cpio_file_stat *file_hdr, int in_des);
-void read_in_new_ascii (struct cpio_file_stat *file_hdr, int in_des);
-void read_in_binary (struct cpio_file_stat *file_hdr,
- struct old_cpio_header *short_hdr, int in_des);
-void swab_array (char *arg, int count);
-void process_copy_in (void);
-void long_format (struct cpio_file_stat *file_hdr, char *link_name);
-void print_name_with_quoting (char *p);
-
-/* copyout.c */
-int write_out_header (struct cpio_file_stat *file_hdr, int out_des);
-void process_copy_out (void);
-
-/* copypass.c */
-void process_copy_pass (void);
-int link_to_maj_min_ino (char *file_name, int st_dev_maj,
- int st_dev_min, int st_ino);
-int link_to_name (char *link_name, char *link_target);
-
-/* dirname.c */
-char *dirname (char *path);
-
-/* filemode.c */
-void mode_string (unsigned int mode, char *str);
-
-/* idcache.c */
-#ifndef __MSDOS__
-char *getgroup ();
-char *getuser ();
-uid_t *getuidbyname ();
-gid_t *getgidbyname ();
-#endif
-
-/* main.c */
-void process_args (int argc, char *argv[]);
-void initialize_buffers (void);
-
-/* makepath.c */
-int make_path (char *argpath, int mode, int parent_mode,
- uid_t owner, gid_t group, char *verbose_fmt_string);
-
-/* tar.c */
-void write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des);
-int null_block (long *block, int size);
-void read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des);
-int otoa (char *s, unsigned long *n);
-int is_tar_header (char *buf);
-int is_tar_filename_too_long (char *name);
-
-/* userspec.c */
-#ifndef __MSDOS__
-char *parse_user_spec (char *name, uid_t *uid, gid_t *gid,
- char **username, char **groupname);
-#endif
-
-/* util.c */
-void tape_empty_output_buffer (int out_des);
-void disk_empty_output_buffer (int out_des);
-void swahw_array (char *ptr, int count);
-void tape_buffered_write (char *in_buf, int out_des, off_t num_bytes);
-void tape_buffered_read (char *in_buf, int in_des, off_t num_bytes);
-int tape_buffered_peek (char *peek_buf, int in_des, int num_bytes);
-void tape_toss_input (int in_des, off_t num_bytes);
-void copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes);
-void copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes, char *filename);
-void copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes, char *filename);
-void warn_if_file_changed (char *file_name, unsigned long old_file_size,
- off_t old_file_mtime);
-void create_all_directories (char *name);
-void prepare_append (int out_file_des);
-char *find_inode_file (unsigned long node_num,
- unsigned long major_num, unsigned long minor_num);
-void add_inode (unsigned long node_num, char *file_name,
- unsigned long major_num, unsigned long minor_num);
-int open_archive (char *file);
-void tape_offline (int tape_des);
-void get_next_reel (int tape_des);
-void set_new_media_message (char *message);
-#if defined(__MSDOS__) && !defined(__GNUC__)
-int chown (char *path, int owner, int group);
-#endif
-#ifdef __TURBOC__
-int utime (char *filename, struct utimbuf *utb);
-#endif
-#ifdef HPUX_CDF
-char *add_cdf_double_slashes (char *filename);
-#endif
-void write_nuls_to_file (off_t num_bytes, int out_des,
- void (*writer) (char *in_buf,
- int out_des, off_t num_bytes));
-#define DISK_IO_BLOCK_SIZE 512
-
-/* FIXME: Move to system.h? */
-#ifndef SYMLINK_USES_UMASK
-# define UMASKED_SYMLINK(name1,name2,mode) symlink(name1,name2)
-#else
-# define UMASKED_SYMLINK(name1,name2,mode) umasked_symlink(name1,name2,mode)
-#endif /* SYMLINK_USES_UMASK */
-
-void set_perms (int fd, struct cpio_file_stat *header);
-void set_file_times (int fd, const char *name, unsigned long atime,
- unsigned long mtime);
-void stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st);
-void cpio_safer_name_suffix (char *name, bool link_target,
- bool absolute_names, bool strip_leading_dots);
-
-/* FIXME: These two defines should be defined in paxutils */
-#define LG_8 3
-#define LG_16 4
-
-uintmax_t from_ascii (char const *where, size_t digs, unsigned logbase);
-
-#define FROM_OCTAL(f) from_ascii (f, sizeof f, LG_8)
-#define FROM_HEX(f) from_ascii (f, sizeof f, LG_16)
-
diff --git a/contrib/cpio/src/filemode.c b/contrib/cpio/src/filemode.c
deleted file mode 100644
index 98f2813..0000000
--- a/contrib/cpio/src/filemode.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* filemode.c -- make a string describing file modes
- Copyright (C) 1985, 1990, 1993, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if !S_IRUSR
-# if S_IREAD
-# define S_IRUSR S_IREAD
-# else
-# define S_IRUSR 00400
-# endif
-#endif
-
-#if !S_IWUSR
-# if S_IWRITE
-# define S_IWUSR S_IWRITE
-# else
-# define S_IWUSR 00200
-# endif
-#endif
-
-#if !S_IXUSR
-# if S_IEXEC
-# define S_IXUSR S_IEXEC
-# else
-# define S_IXUSR 00100
-# endif
-#endif
-
-#ifdef STAT_MACROS_BROKEN
-#undef S_ISBLK
-#undef S_ISCHR
-#undef S_ISDIR
-#undef S_ISFIFO
-#undef S_ISLNK
-#undef S_ISMPB
-#undef S_ISMPC
-#undef S_ISNWK
-#undef S_ISREG
-#undef S_ISSOCK
-#endif /* STAT_MACROS_BROKEN. */
-
-#if !defined(S_ISBLK) && defined(S_IFBLK)
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#endif
-#if !defined(S_ISCHR) && defined(S_IFCHR)
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#endif
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-#if !defined(S_ISREG) && defined(S_IFREG)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-#if !defined(S_ISFIFO) && defined(S_IFIFO)
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#endif
-#if !defined(S_ISLNK) && defined(S_IFLNK)
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#endif
-#if !defined(S_ISSOCK) && defined(S_IFSOCK)
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-#endif
-#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
-#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
-#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
-#endif
-#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
-#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
-#endif
-
-/* Return a character indicating the type of file described by
- file mode BITS:
- 'd' for directories
- 'b' for block special files
- 'c' for character special files
- 'm' for multiplexor files
- 'l' for symbolic links
- 's' for sockets
- 'p' for fifos
- '-' for regular files
- '?' for any other file type. */
-
-static char
-ftypelet (long bits)
-{
-#ifdef S_ISBLK
- if (S_ISBLK (bits))
- return 'b';
-#endif
- if (S_ISCHR (bits))
- return 'c';
- if (S_ISDIR (bits))
- return 'd';
- if (S_ISREG (bits))
- return '-';
-#ifdef S_ISFIFO
- if (S_ISFIFO (bits))
- return 'p';
-#endif
-#ifdef S_ISLNK
- if (S_ISLNK (bits))
- return 'l';
-#endif
-#ifdef S_ISSOCK
- if (S_ISSOCK (bits))
- return 's';
-#endif
-#ifdef S_ISMPC
- if (S_ISMPC (bits))
- return 'm';
-#endif
-#ifdef S_ISNWK
- if (S_ISNWK (bits))
- return 'n';
-#endif
- return '?';
-}
-
-/* Look at read, write, and execute bits in BITS and set
- flags in CHARS accordingly. */
-
-static void
-rwx (unsigned short bits, char *chars)
-{
- chars[0] = (bits & S_IRUSR) ? 'r' : '-';
- chars[1] = (bits & S_IWUSR) ? 'w' : '-';
- chars[2] = (bits & S_IXUSR) ? 'x' : '-';
-}
-
-/* Set the 's' and 't' flags in file attributes string CHARS,
- according to the file mode BITS. */
-
-static void
-setst (unsigned short bits, char *chars)
-{
-#ifdef S_ISUID
- if (bits & S_ISUID)
- {
- if (chars[3] != 'x')
- /* Set-uid, but not executable by owner. */
- chars[3] = 'S';
- else
- chars[3] = 's';
- }
-#endif
-#ifdef S_ISGID
- if (bits & S_ISGID)
- {
- if (chars[6] != 'x')
- /* Set-gid, but not executable by group. */
- chars[6] = 'S';
- else
- chars[6] = 's';
- }
-#endif
-#ifdef S_ISVTX
- if (bits & S_ISVTX)
- {
- if (chars[9] != 'x')
- /* Sticky, but not executable by others. */
- chars[9] = 'T';
- else
- chars[9] = 't';
- }
-#endif
-}
-
-/* Like filemodestring (see below), but only the relevant part of the
- `struct stat' is given as an argument. */
-
-void
-mode_string (unsigned short mode, char *str)
-{
- str[0] = ftypelet ((long) mode);
- rwx ((mode & 0700) << 0, &str[1]);
- rwx ((mode & 0070) << 3, &str[4]);
- rwx ((mode & 0007) << 6, &str[7]);
- setst (mode, str);
-}
-
-/* filemodestring - fill in string STR with an ls-style ASCII
- representation of the st_mode field of file stats block STATP.
- 10 characters are stored in STR; no terminating null is added.
- The characters stored in STR are:
-
- 0 File type. 'd' for directory, 'c' for character
- special, 'b' for block special, 'm' for multiplex,
- 'l' for symbolic link, 's' for socket, 'p' for fifo,
- '-' for regular, '?' for any other file type
-
- 1 'r' if the owner may read, '-' otherwise.
-
- 2 'w' if the owner may write, '-' otherwise.
-
- 3 'x' if the owner may execute, 's' if the file is
- set-user-id, '-' otherwise.
- 'S' if the file is set-user-id, but the execute
- bit isn't set.
-
- 4 'r' if group members may read, '-' otherwise.
-
- 5 'w' if group members may write, '-' otherwise.
-
- 6 'x' if group members may execute, 's' if the file is
- set-group-id, '-' otherwise.
- 'S' if it is set-group-id but not executable.
-
- 7 'r' if any user may read, '-' otherwise.
-
- 8 'w' if any user may write, '-' otherwise.
-
- 9 'x' if any user may execute, 't' if the file is "sticky"
- (will be retained in swap space after execution), '-'
- otherwise.
- 'T' if the file is sticky but not executable. */
-
-void
-filemodestring (struct stat *statp, char *str)
-{
- mode_string (statp->st_mode, str);
-}
-
diff --git a/contrib/cpio/src/filetypes.h b/contrib/cpio/src/filetypes.h
deleted file mode 100644
index de6d77f..0000000
--- a/contrib/cpio/src/filetypes.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* filetypes.h - deal with POSIX annoyances
- Copyright (C) 1991 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-/* Include sys/types.h and sys/stat.h before this file. */
-
-#ifndef S_ISREG /* Doesn't have POSIX.1 stat stuff. */
-#define mode_t unsigned short
-#endif
-
-/* Define the POSIX macros for systems that lack them. */
-#if !defined(S_ISBLK) && defined(S_IFBLK)
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#endif
-#if !defined(S_ISCHR) && defined(S_IFCHR)
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#endif
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-#if !defined(S_ISREG) && defined(S_IFREG)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-#if !defined(S_ISFIFO) && defined(S_IFIFO)
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#endif
-#if !defined(S_ISLNK) && defined(S_IFLNK)
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#endif
-#if !defined(S_ISSOCK) && defined(S_IFSOCK)
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-#endif
-#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX network special */
-#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
-#endif
-
-/* Define the file type bits used in cpio archives.
- They have the same values as the S_IF bits in traditional Unix. */
-
-#define CP_IFMT 0170000 /* Mask for all file type bits. */
-
-#if defined(S_ISBLK)
-#define CP_IFBLK 0060000
-#endif
-#if defined(S_ISCHR)
-#define CP_IFCHR 0020000
-#endif
-#if defined(S_ISDIR)
-#define CP_IFDIR 0040000
-#endif
-#if defined(S_ISREG)
-#define CP_IFREG 0100000
-#endif
-#if defined(S_ISFIFO)
-#define CP_IFIFO 0010000
-#endif
-#if defined(S_ISLNK)
-#define CP_IFLNK 0120000
-#endif
-#if defined(S_ISSOCK)
-#define CP_IFSOCK 0140000
-#endif
-#if defined(S_ISNWK)
-#define CP_IFNWK 0110000
-#endif
-
-#ifndef S_ISLNK
-#define lstat stat
-#endif
-int lstat ();
-int stat ();
diff --git a/contrib/cpio/src/global.c b/contrib/cpio/src/global.c
deleted file mode 100644
index fdee7be..0000000
--- a/contrib/cpio/src/global.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* global.c - global variables and initial values for cpio.
- Copyright (C) 1990, 1991, 1992, 2001, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <sys/types.h>
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-
-/* If true, reset access times after reading files (-a). */
-int reset_time_flag = false;
-
-/* Block size value, initially 512. -B sets to 5120. */
-int io_block_size = 512;
-
-/* The header format to recognize and produce. */
-enum archive_format archive_format = arf_unknown;
-
-/* If true, create directories as needed. (-d with -i or -p) */
-int create_dir_flag = false;
-
-/* If true, interactively rename files. (-r) */
-int rename_flag = false;
-
-/* If non-NULL, the name of a file that will be read to
- rename all of the files in the archive. --rename-batch-file. */
-char *rename_batch_file = NULL;
-
-/* If true, print a table of contents of input. (-t) */
-int table_flag = false;
-
-/* If true, copy unconditionally (older replaces newer). (-u) */
-int unconditional_flag = false;
-
-/* If true, list the files processed, or ls -l style output with -t. (-v) */
-int verbose_flag = false;
-
-/* If true, print a . for each file processed. (-V) */
-int dot_flag = false;
-
-/* If true, link files whenever possible. Used with -p option. (-l) */
-int link_flag = false;
-
-/* If true, retain previous file modification time. (-m) */
-int retain_time_flag = false;
-
-/* Set true if crc_flag is true and we are doing a cpio -i. Used
- by copy_files so it knows whether to compute the crc. */
-int crc_i_flag = false;
-
-/* If true, append to end of archive. (-A) */
-int append_flag = false;
-
-/* If true, swap bytes of each file during cpio -i. */
-int swap_bytes_flag = false;
-
-/* If true, swap halfwords of each file during cpio -i. */
-int swap_halfwords_flag = false;
-
-/* If true, we are swapping halfwords on the current file. */
-int swapping_halfwords = false;
-
-/* If true, we are swapping bytes on the current file. */
-int swapping_bytes = false;
-
-/* If true, set ownership of all files to UID `set_owner'. */
-int set_owner_flag = false;
-uid_t set_owner;
-
-/* If true, set group ownership of all files to GID `set_group'. */
-int set_group_flag = false;
-gid_t set_group;
-
-/* If true, do not chown the files. */
-int no_chown_flag = false;
-
-/* If true, try to write sparse ("holey") files. */
-int sparse_flag = false;
-
-/* If true, don't report number of blocks copied. */
-int quiet_flag = false;
-
-/* If true, only read the archive and verify the files' CRC's, don't
- actually extract the files. */
-int only_verify_crc_flag = false;
-
-/* If true, don't use any absolute paths, prefix them by `./'. */
-int abs_paths_flag = false;
-
-#ifdef DEBUG_CPIO
-/* If true, print debugging information. */
-int debug_flag = false;
-#endif
-
-/* File position of last header read. Only used during -A to determine
- where the old TRAILER!!! record started. */
-int last_header_start = 0;
-
-/* With -i; if true, copy only files that match any of the given patterns;
- if false, copy only files that do not match any of the patterns. (-f) */
-int copy_matching_files = true;
-
-/* With -itv; if true, list numeric uid and gid instead of translating them
- into names. */
-int numeric_uid = false;
-
-/* Name of file containing additional patterns (-E). */
-char *pattern_file_name = NULL;
-
-/* Message to print when end of medium is reached (-M). */
-char *new_media_message = NULL;
-
-/* With -M with %d, message to print when end of medium is reached. */
-char *new_media_message_with_number = NULL;
-char *new_media_message_after_number = NULL;
-
-/* File descriptor containing the archive. */
-int archive_des;
-
-/* Name of file containing the archive, if known; NULL if stdin/out. */
-char *archive_name = NULL;
-
-/* Name of the remote shell command, if known; NULL otherwise. */
-char *rsh_command_option = NULL;
-
-/* CRC checksum. */
-unsigned int crc;
-
-/* Input and output buffers. */
-char *input_buffer, *output_buffer;
-
-/* The size of the input buffer. */
-long input_buffer_size;
-
-/* Current locations in `input_buffer' and `output_buffer'. */
-char *in_buff, *out_buff;
-
-/* Current number of bytes stored at `input_buff' and `output_buff'. */
-long input_size, output_size;
-
-/* Total number of bytes read and written for all files.
- Now that many tape drives hold more than 4Gb we need more than 32
- bits to hold input_bytes and output_bytes. But it's not worth
- the trouble of adding special multi-precision arithmetic if the
- compiler doesn't support 64 bit ints since input_bytes and
- output_bytes are only used to print the number of blocks copied. */
-#ifdef __GNUC__
-long long input_bytes, output_bytes;
-#else
-long input_bytes, output_bytes;
-#endif
-
-/* Saving of argument values for later reference. */
-char *directory_name = NULL;
-char **save_patterns;
-int num_patterns;
-
-/* Character that terminates file names read from stdin. */
-char name_end = '\n';
-
-/* true if input (cpio -i) or output (cpio -o) is a device node. */
-char input_is_special = false;
-char output_is_special = false;
-
-/* true if lseek works on the input. */
-char input_is_seekable = false;
-
-/* true if lseek works on the output. */
-char output_is_seekable = false;
-
-/* Print extra warning messages */
-unsigned int warn_option = 0;
-
-/* Extract to standard output? */
-bool to_stdout_option = false;
-
-/* The name this program was run with. */
-char *program_name;
-
-/* A pointer to either lstat or stat, depending on whether
- dereferencing of symlinks is done for input files. */
-int (*xstat) ();
-
-/* Which copy operation to perform. (-i, -o, -p) */
-void (*copy_function) () = 0;
diff --git a/contrib/cpio/src/idcache.c b/contrib/cpio/src/idcache.c
deleted file mode 100644
index 17fcc04..0000000
--- a/contrib/cpio/src/idcache.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* idcache.c -- map user and group IDs, cached for speed
- Copyright (C) 1985, 1988, 1989, 1990, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifndef _POSIX_VERSION
-struct passwd *getpwuid ();
-struct passwd *getpwnam ();
-struct group *getgrgid ();
-struct group *getgrnam ();
-#endif
-
-char *xmalloc ();
-char *xstrdup ();
-
-struct userid
-{
- union
- {
- uid_t u;
- gid_t g;
- } id;
- char *name;
- struct userid *next;
-};
-
-static struct userid *user_alist;
-
-/* The members of this list have names not in the local passwd file. */
-static struct userid *nouser_alist;
-
-/* Translate UID to a login name or a stringified number,
- with cache. */
-
-char *
-getuser (uid_t uid)
-{
- register struct userid *tail;
- struct passwd *pwent;
- char usernum_string[20];
-
- for (tail = user_alist; tail; tail = tail->next)
- if (tail->id.u == uid)
- return tail->name;
-
- pwent = getpwuid (uid);
- tail = (struct userid *) xmalloc (sizeof (struct userid));
- tail->id.u = uid;
- if (pwent == 0)
- {
- sprintf (usernum_string, "%u", (unsigned) uid);
- tail->name = xstrdup (usernum_string);
- }
- else
- tail->name = xstrdup (pwent->pw_name);
-
- /* Add to the head of the list, so most recently used is first. */
- tail->next = user_alist;
- user_alist = tail;
- return tail->name;
-}
-
-/* Translate USER to a UID, with cache.
- Return NULL if there is no such user.
- (We also cache which user names have no passwd entry,
- so we don't keep looking them up.) */
-
-uid_t *
-getuidbyname (char *user)
-{
- register struct userid *tail;
- struct passwd *pwent;
-
- for (tail = user_alist; tail; tail = tail->next)
- /* Avoid a function call for the most common case. */
- if (*tail->name == *user && !strcmp (tail->name, user))
- return &tail->id.u;
-
- for (tail = nouser_alist; tail; tail = tail->next)
- /* Avoid a function call for the most common case. */
- if (*tail->name == *user && !strcmp (tail->name, user))
- return 0;
-
- pwent = getpwnam (user);
-
- tail = (struct userid *) xmalloc (sizeof (struct userid));
- tail->name = xstrdup (user);
-
- /* Add to the head of the list, so most recently used is first. */
- if (pwent)
- {
- tail->id.u = pwent->pw_uid;
- tail->next = user_alist;
- user_alist = tail;
- return &tail->id.u;
- }
-
- tail->next = nouser_alist;
- nouser_alist = tail;
- return 0;
-}
-
-/* Use the same struct as for userids. */
-static struct userid *group_alist;
-static struct userid *nogroup_alist;
-
-/* Translate GID to a group name or a stringified number,
- with cache. */
-
-char *
-getgroup (gid_t gid)
-{
- register struct userid *tail;
- struct group *grent;
- char groupnum_string[20];
-
- for (tail = group_alist; tail; tail = tail->next)
- if (tail->id.g == gid)
- return tail->name;
-
- grent = getgrgid (gid);
- tail = (struct userid *) xmalloc (sizeof (struct userid));
- tail->id.g = gid;
- if (grent == 0)
- {
- sprintf (groupnum_string, "%u", (unsigned int) gid);
- tail->name = xstrdup (groupnum_string);
- }
- else
- tail->name = xstrdup (grent->gr_name);
-
- /* Add to the head of the list, so most recently used is first. */
- tail->next = group_alist;
- group_alist = tail;
- return tail->name;
-}
-
-/* Translate GROUP to a UID, with cache.
- Return NULL if there is no such group.
- (We also cache which group names have no group entry,
- so we don't keep looking them up.) */
-
-gid_t *
-getgidbyname (char *group)
-{
- register struct userid *tail;
- struct group *grent;
-
- for (tail = group_alist; tail; tail = tail->next)
- /* Avoid a function call for the most common case. */
- if (*tail->name == *group && !strcmp (tail->name, group))
- return &tail->id.g;
-
- for (tail = nogroup_alist; tail; tail = tail->next)
- /* Avoid a function call for the most common case. */
- if (*tail->name == *group && !strcmp (tail->name, group))
- return 0;
-
- grent = getgrnam (group);
-
- tail = (struct userid *) xmalloc (sizeof (struct userid));
- tail->name = xstrdup (group);
-
- /* Add to the head of the list, so most recently used is first. */
- if (grent)
- {
- tail->id.g = grent->gr_gid;
- tail->next = group_alist;
- group_alist = tail;
- return &tail->id.g;
- }
-
- tail->next = nogroup_alist;
- nogroup_alist = tail;
- return 0;
-}
diff --git a/contrib/cpio/src/main.c b/contrib/cpio/src/main.c
deleted file mode 100644
index 675f61e..0000000
--- a/contrib/cpio/src/main.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/* $FreeBSD$ */
-
-/* main.c - main program and argument processing for cpio.
- Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-/* Written by Phil Nelson <phil@cs.wwu.edu>,
- David MacKenzie <djm@gnu.ai.mit.edu>,
- John Oleynick <juo@klinzhai.rutgers.edu>,
- and Sergey Poznyakoff <gray@mirddin.farlep.net> */
-
-#include <system.h>
-#include <paxlib.h>
-
-#include <stdio.h>
-#include <getopt.h>
-#include <argp.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#include "filetypes.h"
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-#include <rmt.h>
-#include <rmt-command.h>
-
-enum cpio_options {
- NO_ABSOLUTE_FILENAMES_OPTION=256,
- ABSOLUTE_FILENAMES_OPTION,
- NO_PRESERVE_OWNER_OPTION,
- ONLY_VERIFY_CRC_OPTION,
- RENAME_BATCH_FILE_OPTION,
- RSH_COMMAND_OPTION,
- QUIET_OPTION,
- SPARSE_OPTION,
- FORCE_LOCAL_OPTION,
- DEBUG_OPTION,
- BLOCK_SIZE_OPTION,
- TO_STDOUT_OPTION,
-
- HANG_OPTION,
- USAGE_OPTION,
- LICENSE_OPTION,
- VERSION_OPTION
-};
-
-const char *argp_program_version = "cpio (" PACKAGE_NAME ") " VERSION;
-const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
-static char doc[] = N_("GNU `cpio' copies files to and from archives\n\
-\n\
-Examples:\n\
- # Copy files named in name-list to the archive\n\
- cpio -o < name-list [> archive]\n\
- # Extract files from the archive\n\
- cpio -i [< archive]\n\
- # Copy files named in name-list to destination-directory\n\
- cpio -p destination-directory < name-list\n");
-
-/* Print usage error message and exit with error. */
-
-#define CHECK_USAGE(cond, opt, mode_opt) \
- if (cond) \
- ERROR((PAXEXIT_FAILURE, 0, _("%s is meaningless with %s"), opt, mode_opt));
-
-static struct argp_option options[] = {
- /* ********** */
-#define GRID 10
- {NULL, 0, NULL, 0,
- N_("Main operation mode:"), GRID },
- {"create", 'o', 0, 0,
- N_("Create the archive (run in copy-out mode)"), GRID },
- {"extract", 'i', 0, 0,
- N_("Extract files from an archive (run in copy-in mode)"), GRID },
- {"pass-through", 'p', 0, 0,
- N_("Run in copy-pass mode"), GRID },
- {"list", 't', 0, 0,
- N_("Print a table of contents of the input"), GRID },
-#undef GRID
-
- /* ********** */
-#define GRID 100
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid in any mode:"), GRID },
-
- {"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0,
- N_("Use this FILE-NAME instead of standard input or output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
- {"force-local", FORCE_LOCAL_OPTION, 0, 0,
- N_("Archive file is local, even if its name contains colons"), GRID+1 },
- {"format", 'H', N_("FORMAT"), 0,
- N_("Use given archive FORMAT"), GRID+1 },
- {NULL, 'B', NULL, 0,
- N_("Set the I/O block size to 5120 bytes"), GRID+1 },
- {"block-size", BLOCK_SIZE_OPTION, N_("BLOCK-SIZE"), 0,
- N_("Set the I/O block size to BLOCK-SIZE * 512 bytes"), GRID+1 },
- {NULL, 'c', NULL, 0,
- N_("Use the old portable (ASCII) archive format"), GRID+1 },
- {"dot", 'V', NULL, 0,
- N_("Print a \".\" for each file processed"), GRID+1 },
- {"io-size", 'C', N_("NUMBER"), 0,
- N_("Set the I/O block size to the given NUMBER of bytes"), GRID+1 },
- {"message", 'M', N_("STRING"), 0,
- N_("Print STRING when the end of a volume of the backup media is reached"),
- GRID+1 },
- {"nonmatching", 'f', 0, 0,
- N_("Only copy files that do not match any of the given patterns"), GRID+1 },
- {"numeric-uid-gid", 'n', 0, 0,
- N_("In the verbose table of contents listing, show numeric UID and GID"),
- GRID+1 },
- {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
- N_("Use remote COMMAND instead of rsh"), GRID+1 },
- {"quiet", QUIET_OPTION, NULL, 0,
- N_("Do not print the number of blocks copied"), GRID+1 },
- {"verbose", 'v', NULL, 0,
- N_("Verbosely list the files processed"), GRID+1 },
-#ifdef DEBUG_CPIO
- {"debug", DEBUG_OPTION, NULL, 0,
- N_("Enable debugging info"), GRID+1 },
-#endif
- {"warning", 'W', N_("FLAG"), 0,
- N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 'all'. Multiple options accumulate."), GRID+1 },
-#undef GRID
-
- /* ********** */
-#define GRID 200
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid only in copy-in mode:"), GRID },
- {"pattern-file", 'E', N_("FILE"), 0,
- N_("Read additional patterns specifying filenames to extract or list from FILE"), 210},
- {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0,
- N_("do not strip leading file name components that contain \"..\" and leading slashes from file names"), 210},
- {"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0,
- N_("When reading a CRC format archive, only verify the CRC's of each file in the archive, don't actually extract the files"), 210},
- {"rename", 'r', 0, 0,
- N_("Interactively rename files"), GRID+1 },
- {"rename-batch-file", RENAME_BATCH_FILE_OPTION, N_("FILE"), OPTION_HIDDEN,
- "", GRID+1 },
- {"swap", 'b', NULL, 0,
- N_("Swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS"), GRID+1 },
- {"swap-bytes", 's', NULL, 0,
- N_("Swap the bytes of each halfword in the files"), GRID+1 },
- {"swap-halfwords", 'S', NULL, 0,
- N_("Swap the halfwords of each word (4 bytes) in the files"),
- GRID+1 },
- {"to-stdout", TO_STDOUT_OPTION, NULL, 0,
- N_("Extract files to standard output"), GRID+1 },
-#undef GRID
-
- /* ********** */
-#define GRID 300
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid only in copy-out mode:"), GRID },
- {"append", 'A', 0, 0,
- N_("Append to an existing archive."), GRID+1 },
- {NULL, 'O', N_("[[USER@]HOST:]FILE-NAME"), 0,
- N_("Archive filename to use instead of standard output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
-#undef GRID
-
- /* ********** */
-#define GRID 400
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid only in copy-pass mode:"), GRID},
- {"link", 'l', 0, 0,
- N_("Link files instead of copying them, when possible"), GRID+1 },
-
-#undef GRID
-
- /* ********** */
-#define GRID 500
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid in copy-in and copy-out modes:"), GRID },
- {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0,
- N_("Do not strip file system prefix components from the file names"),
- GRID+1 },
- {"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0,
- N_("Create all files relative to the current directory"), GRID+1 },
-#undef GRID
- /* ********** */
-#define GRID 600
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid in copy-out and copy-pass modes:"), GRID },
- {"null", '0', 0, 0,
- N_("A list of filenames is terminated by a null character instead of a newline"), GRID+1 },
- {NULL, 'I', N_("[[USER@]HOST:]FILE-NAME"), 0,
- N_("Archive filename to use instead of standard input. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
- {"dereference", 'L', 0, 0,
- N_("Dereference symbolic links (copy the files that they point to instead of copying the links)."), GRID+1 },
- {"owner", 'R', N_("[USER][:.][GROUP]"), 0,
- N_("Set the ownership of all files created to the specified USER and/or GROUP"), GRID+1 },
- {"reset-access-time", 'a', NULL, 0,
- N_("Reset the access times of files after reading them"), GRID+1 },
-
-#undef GRID
- /* ********** */
-#define GRID 700
- {NULL, 0, NULL, 0,
- N_("Operation modifiers valid in copy-in and copy-pass modes:"), GRID },
- {"preserve-modification-time", 'm', 0, 0,
- N_("Retain previous file modification times when creating files"), GRID+1 },
- {"make-directories", 'd', 0, 0,
- N_("Create leading directories where needed"), GRID+1 },
- {"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
- N_("Do not change the ownership of the files"), GRID+1 },
- {"unconditional", 'u', NULL, 0,
- N_("Replace all files unconditionally"), GRID+1 },
- {"sparse", SPARSE_OPTION, NULL, 0,
- N_("Write files with large blocks of zeros as sparse files"), GRID+1 },
-#undef GRID
-
- /* ********** */
-#define GRID 800
- {NULL, 0, NULL, 0,
- N_("Informative options:"), GRID },
-
- {"help", '?', 0, 0, N_("Give this help list"), -1},
- {"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1},
- {"license", LICENSE_OPTION, 0, 0, N_("Print license and exit"), -1},
- {"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1},
- /* FIXME -V (--dot) conflicts with the default short option for
- --version */
- {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
- N_("hang for SECS seconds (default 3600)"), 0},
-#undef GRID
- {0, 0, 0, 0}
-};
-
-static char *input_archive_name = 0;
-static char *output_archive_name = 0;
-
-static void
-license ()
-{
- printf ("%s (%s) %s\n%s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION,
- "Copyright (C) 2004 Free Software Foundation, Inc.\n");
- printf (_(" GNU cpio is free software; you can redistribute it and/or modify\n"
- " it under the terms of the GNU General Public License as published by\n"
- " the Free Software Foundation; either version 2 of the License, or\n"
- " (at your option) any later version.\n"
- "\n"
- " GNU cpio is distributed in the hope that it will be useful,\n"
- " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- " GNU General Public License for more details.\n"
- "\n"
- " You should have received a copy of the GNU General Public License\n"
- " along with GNU cpio; if not, write to the Free Software Foundation,\n"
- " Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n"));
- exit (0);
-}
-
-static int
-warn_control (char *arg)
-{
- static struct warn_tab {
- char *name;
- int flag;
- } warn_tab[] = {
- { "none", CPIO_WARN_ALL },
- { "truncate", CPIO_WARN_TRUNCATE },
- { "all", CPIO_WARN_ALL },
- { NULL }
- };
- struct warn_tab *wt;
- int offset = 0;
-
- if (strcmp (arg, "none") == 0)
- {
- warn_option = 0;
- return 0;
- }
-
- if (strlen (arg) > 2 && memcmp (arg, "no-", 3) == 0)
- offset = 3;
-
- for (wt = warn_tab; wt->name; wt++)
- if (strcmp (arg + offset, wt->name) == 0)
- {
- if (offset)
- warn_option &= ~wt->flag;
- else
- warn_option |= wt->flag;
- return 0;
- }
-
- return 1;
-}
-
-static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
-{
- static volatile int _argp_hang;
- switch (key)
- {
- case '0': /* Read null-terminated filenames. */
- name_end = '\0';
- break;
-
- case 'a': /* Reset access times. */
- reset_time_flag = true;
- break;
-
- case 'A': /* Append to the archive. */
- append_flag = true;
- break;
-
- case 'b': /* Swap bytes and halfwords. */
- swap_bytes_flag = true;
- swap_halfwords_flag = true;
- break;
-
- case 'B': /* Set block size to 5120. */
- io_block_size = 5120;
- break;
-
- case BLOCK_SIZE_OPTION: /* --block-size */
- io_block_size = atoi (arg);
- if (io_block_size < 1)
- error (2, 0, _("invalid block size"));
- io_block_size *= 512;
- break;
-
- case 'c': /* Use the old portable ASCII format. */
- if (archive_format != arf_unknown)
- error (0, EXIT_FAILURE, _("Archive format multiply defined"));
-#ifdef SVR4_COMPAT
- archive_format = arf_newascii; /* -H newc. */
-#else
- archive_format = arf_oldascii; /* -H odc. */
-#endif
- break;
-
- case 'C': /* Block size. */
- io_block_size = atoi (arg);
- if (io_block_size < 1)
- error (2, 0, _("invalid block size"));
- break;
-
- case 'd': /* Create directories where needed. */
- create_dir_flag = true;
- break;
-
- case 'f': /* Only copy files not matching patterns. */
- copy_matching_files = false;
- break;
-
- case 'E': /* Pattern file name. */
- pattern_file_name = arg;
- break;
-
- case 'F': /* Archive file name. */
- archive_name = arg;
- break;
-
- case 'H': /* Header format name. */
- if (archive_format != arf_unknown)
- error (PAXEXIT_FAILURE, 0, _("Archive format multiply defined"));
- if (!strcasecmp (arg, "crc"))
- archive_format = arf_crcascii;
- else if (!strcasecmp (arg, "newc"))
- archive_format = arf_newascii;
- else if (!strcasecmp (arg, "odc"))
- archive_format = arf_oldascii;
- else if (!strcasecmp (arg, "bin"))
- archive_format = arf_binary;
- else if (!strcasecmp (arg, "ustar"))
- archive_format = arf_ustar;
- else if (!strcasecmp (arg, "tar"))
- archive_format = arf_tar;
- else if (!strcasecmp (arg, "hpodc"))
- archive_format = arf_hpoldascii;
- else if (!strcasecmp (arg, "hpbin"))
- archive_format = arf_hpbinary;
- else
- error (2, 0, _("\
-invalid archive format `%s'; valid formats are:\n\
-crc newc odc bin ustar tar (all-caps also recognized)"), arg);
- break;
-
- case 'i': /* Copy-in mode. */
- if (copy_function != 0)
- error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
- copy_function = process_copy_in;
- break;
-
- case 'I': /* Input archive file name. */
- input_archive_name = arg;
- break;
-
- case 'k': /* Handle corrupted archives. We always handle
- corrupted archives, but recognize this
- option for compatability. */
- break;
-
- case 'l': /* Link files when possible. */
- link_flag = true;
- break;
-
- case 'L': /* Dereference symbolic links. */
- xstat = stat;
- break;
-
- case 'm': /* Retain previous file modify times. */
- retain_time_flag = true;
- break;
-
- case 'M': /* New media message. */
- set_new_media_message (arg);
- break;
-
- case 'n': /* Long list owner and group as numbers. */
- numeric_uid = true;
- break;
-
- case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
- abs_paths_flag = false;
- break;
-
- case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */
- abs_paths_flag = true;
- break;
-
- case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
- if (set_owner_flag || set_group_flag)
- error (PAXEXIT_FAILURE, 0,
- _("--no-preserve-owner cannot be used with --owner"));
- no_chown_flag = true;
- break;
-
- case 'o': /* Copy-out mode. */
- if (copy_function != 0)
- error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
- copy_function = process_copy_out;
- break;
-
- case 'O': /* Output archive file name. */
- output_archive_name = arg;
- break;
-
- case ONLY_VERIFY_CRC_OPTION:
- only_verify_crc_flag = true;
- break;
-
- case 'p': /* Copy-pass mode. */
- if (copy_function != 0)
- error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
- copy_function = process_copy_pass;
- break;
-
- case RSH_COMMAND_OPTION:
- rsh_command_option = arg;
- break;
-
- case 'r': /* Interactively rename. */
- rename_flag = true;
- break;
-
- case RENAME_BATCH_FILE_OPTION:
- rename_batch_file = arg;
- break;
-
- case QUIET_OPTION:
- quiet_flag = true;
- break;
-
- case 'R': /* Set the owner. */
- if (no_chown_flag)
- error (PAXEXIT_FAILURE, 0,
- _("--owner cannot be used with --no-preserve-owner"));
- else
- {
- char *e, *u, *g;
-
- e = parse_user_spec (arg, &set_owner, &set_group, &u, &g);
- if (e)
- error (PAXEXIT_FAILURE, 0, "%s: %s", arg, e);
- if (u)
- {
- free (u);
- set_owner_flag = true;
- }
- if (g)
- {
- free (g);
- set_group_flag = true;
- }
- }
- break;
-
- case 's': /* Swap bytes. */
- swap_bytes_flag = true;
- break;
-
- case 'S': /* Swap halfwords. */
- swap_halfwords_flag = true;
- break;
-
- case 't': /* Only print a list. */
- table_flag = true;
- break;
-
- case 'u': /* Replace all! Unconditionally! */
- unconditional_flag = true;
- break;
-
- case 'v': /* Verbose! */
- verbose_flag = true;
- break;
-
- case 'V': /* Print `.' for each file. */
- dot_flag = true;
- break;
-
- case 'W':
- if (warn_control (arg))
- argp_error (state, _("Invalid value for --warning option: %s"), arg);
- break;
-
- case SPARSE_OPTION:
- sparse_flag = true;
- break;
-
- case FORCE_LOCAL_OPTION:
- force_local_option = 1;
- break;
-
-#ifdef DEBUG_CPIO
- case DEBUG_OPTION:
- debug_flag = true;
- break;
-#endif
-
- case TO_STDOUT_OPTION:
- to_stdout_option = true;
- break;
-
- case HANG_OPTION:
- _argp_hang = atoi (arg ? arg : "3600");
- while (_argp_hang-- > 0)
- sleep (1);
- break;
-
- case '?':
- argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
- break;
-
- case USAGE_OPTION:
- argp_state_help (state, state->out_stream,
- ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
- break;
-
- case VERSION_OPTION:
- fprintf (state->out_stream, "%s\n", argp_program_version);
- exit (0);
-
- case LICENSE_OPTION:
- license ();
- break;
-
- default:
- return ARGP_ERR_UNKNOWN;
- }
- return 0;
-}
-
-static struct argp argp = {
- options,
- parse_opt,
- N_("[destination-directory]"),
- doc,
- NULL,
- NULL,
- NULL
-};
-
-/* Process the arguments. Set all options and set up the copy pass
- directory or the copy in patterns. */
-
-void
-process_args (int argc, char *argv[])
-{
- void (*copy_in) (); /* Work around for pcc bug. */
- void (*copy_out) ();
- int index;
-
- if (argc < 2)
- error (PAXEXIT_FAILURE, 0,
- _("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
- program_name, program_name);
-
- xstat = lstat;
-
- if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, &index, NULL))
- exit (1);
-
- /* Do error checking and look at other args. */
-
- if (copy_function == 0)
- {
- if (table_flag)
- copy_function = process_copy_in;
- else
- error (PAXEXIT_FAILURE, 0,
- _("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
- program_name, program_name);
- }
-
- /* Work around for pcc bug. */
- copy_in = process_copy_in;
- copy_out = process_copy_out;
-
- if (copy_function == copy_in)
- {
- archive_des = 0;
- CHECK_USAGE(link_flag, "--link", "--extract");
- CHECK_USAGE(reset_time_flag, "--reset", "--extract");
- CHECK_USAGE(xstat != lstat, "--dereference", "--extract");
- CHECK_USAGE(append_flag, "--append", "--extract");
- CHECK_USAGE(output_archive_name, "-O", "--extract");
- if (to_stdout_option)
- {
- CHECK_USAGE(create_dir_flag, "--make-directories", "--to-stdout");
- CHECK_USAGE(rename_flag, "--rename", "--to-stdout");
- CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--to-stdout");
- CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--to-stdout");
- CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
- "--to-stdout");
- }
-
- if (archive_name && input_archive_name)
- error (PAXEXIT_FAILURE, 0,
- _("Both -I and -F are used in copy-in mode"));
-
- if (archive_format == arf_crcascii)
- crc_i_flag = true;
- num_patterns = argc - index;
- save_patterns = &argv[index];
- if (input_archive_name)
- archive_name = input_archive_name;
- }
- else if (copy_function == copy_out)
- {
- if (index != argc)
- error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
-
- archive_des = 1;
- CHECK_USAGE(create_dir_flag, "--make-directories", "--create");
- CHECK_USAGE(rename_flag, "--rename", "--create");
- CHECK_USAGE(table_flag, "--list", "--create");
- CHECK_USAGE(unconditional_flag, "--unconditional", "--create");
- CHECK_USAGE(link_flag, "--link", "--create");
- CHECK_USAGE(sparse_flag, "--sparse", "--create");
- CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
- "--create");
- CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create");
- CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create");
- CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
- "--create");
- CHECK_USAGE(to_stdout_option, "--to-stdout", "--create");
-
- if (append_flag && !(archive_name || output_archive_name))
- error (PAXEXIT_FAILURE, 0,
- _("--append is used but no archive file name is given (use -F or -O options)"));
-
- CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
- CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--create");
- CHECK_USAGE(input_archive_name, "-I", "--create");
- if (archive_name && output_archive_name)
- error (PAXEXIT_FAILURE, 0,
- _("Both -O and -F are used in copy-out mode"));
-
- if (archive_format == arf_unknown)
- archive_format = arf_binary;
- if (output_archive_name)
- archive_name = output_archive_name;
- }
- else
- {
- /* Copy pass. */
- if (index < argc - 1)
- error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
- else if (index > argc - 1)
- error (PAXEXIT_FAILURE, 0, _("Not enough arguments"));
-
- if (archive_format != arf_unknown)
- error (PAXEXIT_FAILURE, 0,
- _("Archive format is not specified in copy-pass mode (use --format option)"));
-
- CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
- CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
- "--pass-through");
- CHECK_USAGE(table_flag, "--list", "--pass-through");
- CHECK_USAGE(rename_flag, "--rename", "--pass-through");
- CHECK_USAGE(append_flag, "--append", "--pass-through");
- CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
- CHECK_USAGE(abs_paths_flag, "--absolute-pathnames",
- "--pass-through");
- CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
-
- directory_name = argv[index];
- }
-
- if (archive_name)
- {
- if (copy_function != copy_in && copy_function != copy_out)
- error (PAXEXIT_FAILURE, 0,
- _("-F can be used only with --create or --extract"));
- archive_des = open_archive (archive_name);
- if (archive_des < 0)
- error (PAXEXIT_FAILURE, errno, _("Cannot open %s"),
- quotearg_colon (archive_name));
- }
-
- /* Prevent SysV non-root users from giving away files inadvertantly.
- This happens automatically on BSD, where only root can give
- away files. */
- if (set_owner_flag == false && set_group_flag == false && geteuid ())
- no_chown_flag = true;
-}
-
-/* Initialize the input and output buffers to their proper size and
- initialize all variables associated with the input and output
- buffers. */
-
-void
-initialize_buffers ()
-{
- int in_buf_size, out_buf_size;
-
- if (copy_function == process_copy_in)
- {
- /* Make sure the input buffer can always hold 2 blocks and that it
- is big enough to hold 1 tar record (512 bytes) even if it
- is not aligned on a block boundary. The extra buffer space
- is needed by process_copyin and peek_in_buf to automatically
- figure out what kind of archive it is reading. */
- if (io_block_size >= 512)
- in_buf_size = 2 * io_block_size;
- else
- in_buf_size = 1024;
- out_buf_size = DISK_IO_BLOCK_SIZE;
- }
- else if (copy_function == process_copy_out)
- {
- in_buf_size = DISK_IO_BLOCK_SIZE;
- out_buf_size = io_block_size;
- }
- else
- {
- in_buf_size = DISK_IO_BLOCK_SIZE;
- out_buf_size = DISK_IO_BLOCK_SIZE;
- }
-
- input_buffer = (char *) xmalloc (in_buf_size);
- in_buff = input_buffer;
- input_buffer_size = in_buf_size;
- input_size = 0;
- input_bytes = 0;
-
- output_buffer = (char *) xmalloc (out_buf_size);
- out_buff = output_buffer;
- output_size = 0;
- output_bytes = 0;
-}
-
-int
-main (int argc, char *argv[])
-{
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-
- program_name = argv[0];
-
- process_args (argc, argv);
- umask (0);
-
- initialize_buffers ();
-
- (*copy_function) ();
-
- if (archive_des >= 0 && rmtclose (archive_des) == -1)
- error (1, errno, _("error closing archive"));
-
- exit (0);
-}
diff --git a/contrib/cpio/src/makepath.c b/contrib/cpio/src/makepath.c
deleted file mode 100644
index ff4c25f..0000000
--- a/contrib/cpio/src/makepath.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* makepath.c -- Ensure that a directory path exists.
- Copyright (C) 1990, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and
- Jim Meyering <meyering@cs.utexas.edu>. */
-
-/* This copy of makepath is almost like the fileutils one, but has
- changes for HPUX CDF's. Maybe the 2 versions of makepath can
- come together again in the future. */
-
-#include <system.h>
-#include <paxlib.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-/* Ensure that the directory ARGPATH exists.
- Remove any trailing slashes from ARGPATH before calling this function.
-
- Make any leading directories that don't already exist, with
- permissions PARENT_MODE.
- If the last element of ARGPATH does not exist, create it as
- a new directory with permissions MODE.
- If OWNER and GROUP are non-negative, make them the UID and GID of
- created directories.
- If VERBOSE_FMT_STRING is nonzero, use it as a printf format
- string for printing a message after successfully making a directory,
- with the name of the directory that was just made as an argument.
-
- Return 0 if ARGPATH exists as a directory with the proper
- ownership and permissions when done, otherwise 1. */
-
-int
-make_path (char *argpath,
- int mode,
- int parent_mode,
- uid_t owner,
- gid_t group,
- char *verbose_fmt_string)
-{
- char *dirpath; /* A copy we can scribble NULs on. */
- struct stat stats;
- int retval = 0;
- int oldmask = umask (0);
- dirpath = alloca (strlen (argpath) + 1);
- strcpy (dirpath, argpath);
-
- if (stat (dirpath, &stats))
- {
- char *slash;
- int tmp_mode; /* Initial perms for leading dirs. */
- int re_protect; /* Should leading dirs be unwritable? */
- struct ptr_list
- {
- char *dirname_end;
- struct ptr_list *next;
- };
- struct ptr_list *p, *leading_dirs = NULL;
-
- /* If leading directories shouldn't be writable or executable,
- or should have set[ug]id or sticky bits set and we are setting
- their owners, we need to fix their permissions after making them. */
- if (((parent_mode & 0300) != 0300)
- || (owner != (uid_t) -1 && group != (gid_t) -1
- && (parent_mode & 07000) != 0))
- {
- tmp_mode = 0700;
- re_protect = 1;
- }
- else
- {
- tmp_mode = parent_mode;
- re_protect = 0;
- }
-
- slash = dirpath;
- while (*slash == '/')
- slash++;
- while ((slash = strchr (slash, '/')))
- {
-#ifdef HPUX_CDF
- int iscdf;
- iscdf = 0;
-#endif
- *slash = '\0';
- if (stat (dirpath, &stats))
- {
-#ifdef HPUX_CDF
- /* If this component of the pathname ends in `+' and is
- followed by 2 `/'s, then this is a CDF. We remove the
- `+' from the name and create the directory. Later
- we will "hide" the directory. */
- if ( (*(slash +1) == '/') && (*(slash -1) == '+') )
- {
- iscdf = 1;
- *(slash -1) = '\0';
- }
-#endif
- if (mkdir (dirpath, tmp_mode))
- {
- error (0, errno, _("cannot make directory `%s'"), dirpath);
- umask (oldmask);
- return 1;
- }
- else
- {
- if (verbose_fmt_string != NULL)
- error (0, 0, verbose_fmt_string, dirpath);
-
- if (owner != (uid_t) -1 && group != (gid_t) -1
- && chown (dirpath, owner, group)
-#ifdef AFS
- && errno != EPERM
-#endif
- )
- {
- chown_error_details (dirpath, owner, group);
- retval = 1;
- }
- if (re_protect)
- {
- struct ptr_list *new = (struct ptr_list *)
- alloca (sizeof (struct ptr_list));
- new->dirname_end = slash;
- new->next = leading_dirs;
- leading_dirs = new;
- }
-#ifdef HPUX_CDF
- if (iscdf)
- {
- /* If this is a CDF, "hide" the directory by setting
- its hidden/setuid bit. Also add the `+' back to
- its name (since once it's "hidden" we must refer
- to as `name+' instead of `name'). */
- chmod (dirpath, 04700);
- *(slash - 1) = '+';
- }
-#endif
- }
- }
- else if (!S_ISDIR (stats.st_mode))
- {
- error (0, 0, _("`%s' exists but is not a directory"), dirpath);
- umask (oldmask);
- return 1;
- }
-
- *slash++ = '/';
-
- /* Avoid unnecessary calls to `stat' when given
- pathnames containing multiple adjacent slashes. */
- while (*slash == '/')
- slash++;
- }
-
- /* We're done making leading directories.
- Make the final component of the path. */
-
- if (mkdir (dirpath, mode))
- {
- /* In some cases, if the final component in dirpath was `.' then we
- just got an EEXIST error from that last mkdir(). If that's
- the case, ignore it. */
- if ( (errno != EEXIST) ||
- (stat (dirpath, &stats) != 0) ||
- (!S_ISDIR (stats.st_mode) ) )
- {
- error (0, errno, _("cannot make directory `%s'"), dirpath);
- umask (oldmask);
- return 1;
- }
- }
- if (verbose_fmt_string != NULL)
- error (0, 0, verbose_fmt_string, dirpath);
-
- if (owner != (uid_t) -1 && group != (gid_t) -1)
- {
- if (chown (dirpath, owner, group)
-#ifdef AFS
- && errno != EPERM
-#endif
- )
- {
- chown_error_details (dirpath, owner, group);
- retval = 1;
- }
- }
- /* chown may have turned off some permission bits we wanted. */
- if ((mode & 07000) != 0 && chmod (dirpath, mode))
- {
- chmod_error_details (dirpath, mode);
- retval = 1;
- }
-
- /* If the mode for leading directories didn't include owner "wx"
- privileges, we have to reset their protections to the correct
- value. */
- for (p = leading_dirs; p != NULL; p = p->next)
- {
- *p->dirname_end = '\0';
-#if 0
- /* cpio always calls make_path with parent mode 0700, so
- we don't have to do this. If we ever do have to do this,
- we have to stat the directory first to get the setuid
- bit so we don't break HP CDF's. */
- if (chmod (dirpath, parent_mode))
- {
- chmod_error_details (dirpath, parent_mode);
- retval = 1;
- }
-#endif
-
- }
- }
- else
- {
- /* We get here if the entire path already exists. */
-
- if (!S_ISDIR (stats.st_mode))
- {
- error (0, 0, _("`%s' exists but is not a directory"), dirpath);
- umask (oldmask);
- return 1;
- }
-
- /* chown must precede chmod because on some systems,
- chown clears the set[ug]id bits for non-superusers,
- resulting in incorrect permissions.
- On System V, users can give away files with chown and then not
- be able to chmod them. So don't give files away. */
-
- if (owner != (uid_t) -1 && group != (gid_t) -1
- && chown (dirpath, owner, group)
-#ifdef AFS
- && errno != EPERM
-#endif
- )
- {
- chown_error_details (dirpath, owner, group);
- retval = 1;
- }
- if (chmod (dirpath, mode))
- {
- chmod_error_details (dirpath, mode);
- retval = 1;
- }
- }
-
- umask (oldmask);
- return retval;
-}
diff --git a/contrib/cpio/src/safe-stat.h b/contrib/cpio/src/safe-stat.h
deleted file mode 100644
index 3a37970..0000000
--- a/contrib/cpio/src/safe-stat.h
+++ /dev/null
@@ -1 +0,0 @@
-#define SAFE_STAT(path,pbuf) stat(path,pbuf)
diff --git a/contrib/cpio/src/tar.c b/contrib/cpio/src/tar.c
deleted file mode 100644
index 9340372..0000000
--- a/contrib/cpio/src/tar.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/* $FreeBSD$ */
-
-/* tar.c - read in write tar headers for cpio
- Copyright (C) 1992, 2001, 2004, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "filetypes.h"
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-#include <rmt.h>
-#include "tarhdr.h"
-
-/* Stash the tar linkname in static storage. */
-
-static char *
-stash_tar_linkname (char *linkname)
-{
- static char hold_tar_linkname[TARLINKNAMESIZE + 1];
-
- strncpy (hold_tar_linkname, linkname, TARLINKNAMESIZE);
- hold_tar_linkname[TARLINKNAMESIZE] = '\0';
- return hold_tar_linkname;
-}
-
-/* Try to split a long file name into prefix and suffix parts separated
- by a slash. Return the length of the prefix (not counting the slash). */
-
-static size_t
-split_long_name (const char *name, size_t length)
-{
- size_t i;
-
- if (length > TARPREFIXSIZE)
- length = TARPREFIXSIZE+2;
- for (i = length - 1; i > 0; i--)
- if (name[i] == '/')
- break;
- return i;
-}
-
-/* Stash the tar filename and optional prefix in static storage. */
-
-static char *
-stash_tar_filename (char *prefix, char *filename)
-{
- static char hold_tar_filename[TARNAMESIZE + TARPREFIXSIZE + 2];
- if (prefix == NULL || *prefix == '\0')
- {
- strncpy (hold_tar_filename, filename, TARNAMESIZE);
- hold_tar_filename[TARNAMESIZE] = '\0';
- }
- else
- {
- strncpy (hold_tar_filename, prefix, TARPREFIXSIZE);
- hold_tar_filename[TARPREFIXSIZE] = '\0';
- strcat (hold_tar_filename, "/");
- strncat (hold_tar_filename, filename, TARNAMESIZE);
- hold_tar_filename[TARPREFIXSIZE + TARNAMESIZE] = '\0';
- }
- return hold_tar_filename;
-}
-
-/* Convert a number into a string of octal digits.
- Convert long VALUE into a DIGITS-digit field at WHERE,
- including a trailing space and room for a NUL. DIGITS==3 means
- 1 digit, a space, and room for a NUL.
-
- We assume the trailing NUL is already there and don't fill it in.
- This fact is used by start_header and finish_header, so don't change it!
-
- This is be equivalent to:
- sprintf (where, "%*lo ", digits - 2, value);
- except that sprintf fills in the trailing NUL and we don't. */
-
-static void
-to_oct (register long value, register int digits, register char *where)
-{
- --digits; /* Leave the trailing NUL slot alone. */
-
- /* Produce the digits -- at least one. */
- do
- {
- where[--digits] = '0' + (char) (value & 7); /* One octal digit. */
- value >>= 3;
- }
- while (digits > 0 && value != 0);
-
- /* Add leading zeroes, if necessary. */
- while (digits > 0)
- where[--digits] = '0';
-}
-
-
-
-/* Compute and return a checksum for TAR_HDR,
- counting the checksum bytes as if they were spaces. */
-
-unsigned int
-tar_checksum (struct tar_header *tar_hdr)
-{
- unsigned int sum = 0;
- char *p = (char *) tar_hdr;
- char *q = p + TARRECORDSIZE;
- int i;
-
- while (p < tar_hdr->chksum)
- sum += *p++ & 0xff;
- for (i = 0; i < 8; ++i)
- {
- sum += ' ';
- ++p;
- }
- while (p < q)
- sum += *p++ & 0xff;
- return sum;
-}
-
-/* Write out header FILE_HDR, including the file name, to file
- descriptor OUT_DES. */
-
-void
-write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des)
-{
- int name_len;
- union tar_record tar_rec;
- struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
-
- memset (&tar_rec, 0, sizeof tar_rec);
-
- /* process_copy_out must ensure that file_hdr->c_name is short enough,
- or we will lose here. */
-
- name_len = strlen (file_hdr->c_name);
- if (name_len <= TARNAMESIZE)
- {
- strncpy (tar_hdr->name, file_hdr->c_name, name_len);
- }
- else
- {
- /* Fit as much as we can into `name', the rest into `prefix'. */
- int prefix_len = split_long_name (file_hdr->c_name, name_len);
-
- strncpy (tar_hdr->prefix, file_hdr->c_name, prefix_len);
- strncpy (tar_hdr->name, file_hdr->c_name + prefix_len + 1,
- name_len - prefix_len - 1);
- }
-
- /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal
- digits */
- to_oct (file_hdr->c_mode & MODE_ALL, 8, tar_hdr->mode);
- to_oct (file_hdr->c_uid, 8, tar_hdr->uid);
- to_oct (file_hdr->c_gid, 8, tar_hdr->gid);
- to_oct (file_hdr->c_filesize, 12, tar_hdr->size);
- to_oct (file_hdr->c_mtime, 12, tar_hdr->mtime);
-
- switch (file_hdr->c_mode & CP_IFMT)
- {
- case CP_IFREG:
- if (file_hdr->c_tar_linkname)
- {
- /* process_copy_out makes sure that c_tar_linkname is shorter
- than TARLINKNAMESIZE. */
- strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
- TARLINKNAMESIZE);
- tar_hdr->typeflag = LNKTYPE;
- to_oct (0, 12, tar_hdr->size);
- }
- else
- tar_hdr->typeflag = REGTYPE;
- break;
- case CP_IFDIR:
- tar_hdr->typeflag = DIRTYPE;
- break;
- case CP_IFCHR:
- tar_hdr->typeflag = CHRTYPE;
- break;
- case CP_IFBLK:
- tar_hdr->typeflag = BLKTYPE;
- break;
-#ifdef CP_IFIFO
- case CP_IFIFO:
- tar_hdr->typeflag = FIFOTYPE;
- break;
-#endif /* CP_IFIFO */
-#ifdef CP_IFLNK
- case CP_IFLNK:
- tar_hdr->typeflag = SYMTYPE;
- /* process_copy_out makes sure that c_tar_linkname is shorter
- than TARLINKNAMESIZE. */
- strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
- TARLINKNAMESIZE);
- to_oct (0, 12, tar_hdr->size);
- break;
-#endif /* CP_IFLNK */
- }
-
- if (archive_format == arf_ustar)
- {
- char *name;
-
- strncpy (tar_hdr->magic, TMAGIC, TMAGLEN);
- strncpy (tar_hdr->magic + TMAGLEN, TVERSION, TVERSLEN);
-
- name = getuser (file_hdr->c_uid);
- if (name)
- strcpy (tar_hdr->uname, name);
- name = getgroup (file_hdr->c_gid);
- if (name)
- strcpy (tar_hdr->gname, name);
-
- to_oct (file_hdr->c_rdev_maj, 8, tar_hdr->devmajor);
- to_oct (file_hdr->c_rdev_min, 8, tar_hdr->devminor);
- }
-
- to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum);
-
- tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE);
-}
-
-/* Return nonzero iff all the bytes in BLOCK are NUL.
- SIZE is the number of bytes to check in BLOCK; it must be a
- multiple of sizeof (long). */
-
-int
-null_block (long *block, int size)
-{
- register long *p = block;
- register int i = size / sizeof (long);
-
- while (i--)
- if (*p++)
- return 0;
- return 1;
-}
-
-/* Read a tar header, including the file name, from file descriptor IN_DES
- into FILE_HDR. */
-
-void
-read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des)
-{
- long bytes_skipped = 0;
- int warned = false;
- union tar_record tar_rec;
- struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
- uid_t *uidp;
- gid_t *gidp;
-
- tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
-
- /* Check for a block of 0's. */
- if (null_block ((long *) &tar_rec, TARRECORDSIZE))
- {
-#if 0
- /* Found one block of 512 0's. If the next block is also all 0's
- then this is the end of the archive. If not, assume the
- previous block was all corruption and continue reading
- the archive. */
- /* Commented out because GNU tar sometimes creates archives with
- only one block of 0's at the end. This happened for the
- cpio 2.0 distribution! */
- tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
- if (null_block ((long *) &tar_rec, TARRECORDSIZE))
-#endif
- {
- file_hdr->c_name = CPIO_TRAILER_NAME;
- return;
- }
-#if 0
- bytes_skipped = TARRECORDSIZE;
-#endif
- }
-
- while (1)
- {
- file_hdr->c_chksum = FROM_OCTAL (tar_hdr->chksum);
-
- if (file_hdr->c_chksum != tar_checksum (tar_hdr))
- {
- /* If the checksum is bad, skip 1 byte and try again. When
- we try again we do not look for an EOF record (all zeros),
- because when we start skipping bytes in a corrupted archive
- the chances are pretty good that we might stumble across
- 2 blocks of 512 zeros (that probably is not really the last
- record) and it is better to miss the EOF and give the user
- a "premature EOF" error than to give up too soon on a corrupted
- archive. */
- if (!warned)
- {
- error (0, 0, _("invalid header: checksum error"));
- warned = true;
- }
- memmove (&tar_rec, ((char *) &tar_rec) + 1, TARRECORDSIZE - 1);
- tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
- ++bytes_skipped;
- continue;
- }
-
- if (archive_format != arf_ustar)
- file_hdr->c_name = stash_tar_filename (NULL, tar_hdr->name);
- else
- file_hdr->c_name = stash_tar_filename (tar_hdr->prefix, tar_hdr->name);
- file_hdr->c_nlink = 1;
- file_hdr->c_mode = FROM_OCTAL (tar_hdr->mode);
- file_hdr->c_mode = file_hdr->c_mode & 07777;
- /* Debian hack: This version of cpio uses the -n flag also to extract
- tar archives using the numeric UID/GID instead of the user/group
- names in /etc/passwd and /etc/groups. (98/10/15) -BEM */
- if (archive_format == arf_ustar && !numeric_uid
- && (uidp = getuidbyname (tar_hdr->uname)))
- file_hdr->c_uid = *uidp;
- else
- file_hdr->c_uid = FROM_OCTAL (tar_hdr->uid);
-
- if (archive_format == arf_ustar && !numeric_uid
- && (gidp = getgidbyname (tar_hdr->gname)))
- file_hdr->c_gid = *gidp;
- else
- file_hdr->c_gid = FROM_OCTAL (tar_hdr->gid);
- file_hdr->c_filesize = FROM_OCTAL (tar_hdr->size);
- file_hdr->c_mtime = FROM_OCTAL (tar_hdr->mtime);
- file_hdr->c_rdev_maj = FROM_OCTAL (tar_hdr->devmajor);
- file_hdr->c_rdev_min = FROM_OCTAL (tar_hdr->devminor);
- file_hdr->c_tar_linkname = NULL;
-
- switch (tar_hdr->typeflag)
- {
- case REGTYPE:
- case CONTTYPE: /* For now, punt. */
- default:
- file_hdr->c_mode |= CP_IFREG;
- break;
- case DIRTYPE:
- file_hdr->c_mode |= CP_IFDIR;
- break;
- case CHRTYPE:
- file_hdr->c_mode |= CP_IFCHR;
- /* If a POSIX tar header has a valid linkname it's always supposed
- to set typeflag to be LNKTYPE. System V.4 tar seems to
- be broken, and for device files with multiple links it
- puts the name of the link into linkname, but leaves typeflag
- as CHRTYPE, BLKTYPE, FIFOTYPE, etc. */
- file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
-
- /* Does POSIX say that the filesize must be 0 for devices? We
- assume so, but HPUX's POSIX tar sets it to be 1 which causes
- us problems (when reading an archive we assume we can always
- skip to the next file by skipping filesize bytes). For
- now at least, it's easier to clear filesize for devices,
- rather than check everywhere we skip in copyin.c. */
- file_hdr->c_filesize = 0;
- break;
- case BLKTYPE:
- file_hdr->c_mode |= CP_IFBLK;
- file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
- file_hdr->c_filesize = 0;
- break;
-#ifdef CP_IFIFO
- case FIFOTYPE:
- file_hdr->c_mode |= CP_IFIFO;
- file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
- file_hdr->c_filesize = 0;
- break;
-#endif
- case SYMTYPE:
-#ifdef CP_IFLNK
- file_hdr->c_mode |= CP_IFLNK;
- file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
- file_hdr->c_filesize = 0;
- break;
- /* Else fall through. */
-#endif
- case LNKTYPE:
- file_hdr->c_mode |= CP_IFREG;
- file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
- file_hdr->c_filesize = 0;
- break;
-
- case AREGTYPE:
- /* Old tar format; if the last char in filename is '/' then it is
- a directory, otherwise it's a regular file. */
- if (file_hdr->c_name[strlen (file_hdr->c_name) - 1] == '/')
- file_hdr->c_mode |= CP_IFDIR;
- else
- file_hdr->c_mode |= CP_IFREG;
- break;
- case 'x': case 'g':
- /* Ignore pax 'x' and 'g' extension entries. */
- /* Skip body of this entry. */
- while (file_hdr->c_filesize > 0) {
- tape_buffered_read(((char *) &tar_rec), in_des, TARRECORDSIZE);
- if (file_hdr->c_filesize > TARRECORDSIZE)
- file_hdr->c_filesize -= TARRECORDSIZE;
- else
- file_hdr->c_filesize = 0;
- }
- /* Read next header and return that instead. */
- read_in_tar_header(file_hdr, in_des);
- break;
- }
- break;
- }
- if (bytes_skipped > 0)
- warn_junk_bytes (bytes_skipped);
-}
-
-/* Return
- 2 if BUF is a valid POSIX tar header (the checksum is correct
- and it has the "ustar" magic string),
- 1 if BUF is a valid old tar header (the checksum is correct),
- 0 otherwise. */
-
-int
-is_tar_header (char *buf)
-{
- struct tar_header *tar_hdr = (struct tar_header *) buf;
- unsigned long chksum;
-
- chksum = FROM_OCTAL (tar_hdr->chksum);
-
- if (chksum != tar_checksum (tar_hdr))
- return 0;
-
- /* GNU tar 1.10 and previous set the magic field to be "ustar " instead
- of "ustar\0". Only look at the first 5 characters of the magic
- field so we can recognize old GNU tar ustar archives. */
- if (!strncmp (tar_hdr->magic, TMAGIC, TMAGLEN - 1))
- return 2;
- return 1;
-}
-
-/* Return true if the filename is too long to fit in a tar header.
- For old tar headers, if the filename's length is less than or equal
- to 100 then it will fit, otherwise it will not. For POSIX tar headers,
- if the filename's length is less than or equal to 100 then it
- will definitely fit, and if it is greater than 256 then it
- will definitely not fit. If the length is between 100 and 256,
- then the filename will fit only if it is possible to break it
- into a 155 character "prefix" and 100 character "name". There
- must be a slash between the "prefix" and the "name", although
- the slash is not stored or counted in either the "prefix" or
- the "name", and there must be at least one character in both
- the "prefix" and the "name". If it is not possible to break down
- the filename like this then it will not fit. */
-
-int
-is_tar_filename_too_long (char *name)
-{
- int whole_name_len;
- int prefix_name_len;
-
- whole_name_len = strlen (name);
- if (whole_name_len <= TARNAMESIZE)
- return false;
-
- if (archive_format != arf_ustar)
- return true;
-
- if (whole_name_len > TARNAMESIZE + TARPREFIXSIZE + 1)
- return true;
-
- /* See whether we can split up the name into acceptably-sized
- `prefix' and `name' (`p') pieces. */
- prefix_name_len = split_long_name (name, whole_name_len);
-
- /* Interestingly, a name consisting of a slash followed by
- TARNAMESIZE characters can't be stored, because the prefix
- would be empty, and thus ignored. */
- if (prefix_name_len == 0
- || whole_name_len - prefix_name_len - 1 > TARNAMESIZE)
- return true;
-
- return false;
-}
diff --git a/contrib/cpio/src/tar.h b/contrib/cpio/src/tar.h
deleted file mode 100644
index 7b27e86..0000000
--- a/contrib/cpio/src/tar.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Extended tar format from POSIX.1.
- Copyright (C) 1992 Free Software Foundation, Inc.
- Written by David J. MacKenzie.
-
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General
-Public License along with this library; see the file COPYING.LIB.
-If not, write to the Free Software Foundation, Inc., 51 Franklin
-Street, Fifth Floor, Boston, MA 02110-1301 USA. */
-
-#ifndef _TAR_H
-
-#define _TAR_H 1
-
-
-/* A tar archive consists of 512-byte blocks.
- Each file in the archive has a header block followed by 0+ data blocks.
- Two blocks of NUL bytes indicate the end of the archive. */
-
-/* The fields of header blocks:
- All strings are stored as ISO 646 (approximately ASCII) strings.
-
- Fields are numeric unless otherwise noted below; numbers are ISO 646
- representations of octal numbers, with leading zeros as needed.
-
- linkname is only valid when typeflag==LNKTYPE. It doesn't use prefix;
- files that are links to pathnames >100 chars long can not be stored
- in a tar archive.
-
- If typeflag=={LNKTYPE,SYMTYPE,DIRTYPE} then size must be 0.
-
- devmajor and devminor are only valid for typeflag=={BLKTYPE,CHRTYPE}.
-
- chksum contains the sum of all 512 bytes in the header block,
- treating each byte as an 8-bit unsigned value and treating the
- 8 bytes of chksum as blank characters.
-
- uname and gname are used in preference to uid and gid, if those
- names exist locally.
-
- Field Name Byte Offset Length in Bytes Field Type
- name 0 100 NUL-terminated if NUL fits
- mode 100 8
- uid 108 8
- gid 116 8
- size 124 12
- mtime 136 12
- chksum 148 8
- typeflag 156 1 see below
- linkname 157 100 NUL-terminated if NUL fits
- magic 257 6 must be TMAGIC (NUL term.)
- version 263 2 must be TVERSION
- uname 265 32 NUL-terminated
- gname 297 32 NUL-terminated
- devmajor 329 8
- devminor 337 8
- prefix 345 155 NUL-terminated if NUL fits
-
- If the first character of prefix is '\0', the file name is name;
- otherwise, it is prefix/name. Files whose pathnames don't fit in that
- length can not be stored in a tar archive. */
-
-/* The bits in mode: */
-#define TSUID 04000
-#define TSGID 02000
-#define TSVTX 01000
-#define TUREAD 00400
-#define TUWRITE 00200
-#define TUEXEC 00100
-#define TGREAD 00040
-#define TGWRITE 00020
-#define TGEXEC 00010
-#define TOREAD 00004
-#define TOWRITE 00002
-#define TOEXEC 00001
-
-/* The values for typeflag:
- Values 'A'-'Z' are reserved for custom implementations.
- All other values are reserved for future POSIX.1 revisions. */
-
-#define REGTYPE '0' /* Regular file (preferred code). */
-#define AREGTYPE '\0' /* Regular file (alternate code). */
-#define LNKTYPE '1' /* Hard link. */
-#define SYMTYPE '2' /* Symbolic link (hard if not supported). */
-#define CHRTYPE '3' /* Character special. */
-#define BLKTYPE '4' /* Block special. */
-#define DIRTYPE '5' /* Directory. */
-#define FIFOTYPE '6' /* Named pipe. */
-#define CONTTYPE '7' /* Contiguous file */
- /* (regular file if not supported). */
-
-/* Contents of magic field and its length. */
-#define TMAGIC "ustar"
-#define TMAGLEN 6
-
-/* Contents of the version field and its length. */
-#define TVERSION "00"
-#define TVERSLEN 2
-
-
-#endif /* tar.h */
diff --git a/contrib/cpio/src/tarhdr.h b/contrib/cpio/src/tarhdr.h
deleted file mode 100644
index b901739..0000000
--- a/contrib/cpio/src/tarhdr.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Extended tar header from POSIX.1.
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#ifndef _TARHDR_H
-
-#define _TARHDR_H 1
-
-#include <tar.h>
-
-/* Size of `name' field. */
-#define TARNAMESIZE 100
-
-/* Size of `linkname' field. */
-#define TARLINKNAMESIZE 100
-
-/* Size of `prefix' field. */
-#define TARPREFIXSIZE 155
-
-/* Size of entire tar header. */
-#define TARRECORDSIZE 512
-
-struct tar_header
-{
- char name[TARNAMESIZE];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char chksum[8];
- char typeflag;
- char linkname[TARLINKNAMESIZE];
- char magic[6];
- char version[2];
- char uname[32];
- char gname[32];
- char devmajor[8];
- char devminor[8];
- char prefix[TARPREFIXSIZE];
-};
-
-union tar_record
-{
- struct tar_header header;
- char buffer[TARRECORDSIZE];
-};
-
-#endif /* tarhdr.h */
diff --git a/contrib/cpio/src/userspec.c b/contrib/cpio/src/userspec.c
deleted file mode 100644
index c33d6e2..0000000
--- a/contrib/cpio/src/userspec.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* $FreeBSD$ */
-
-/* userspec.c -- Parse a user and group string.
- Copyright (C) 1989, 1990, 1991, 1992, 2001,
- 2004, 2005 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#include <system.h>
-
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#else
-#ifdef _AIX
- #pragma alloca
-#else
-char *alloca ();
-#endif
-#endif
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-
-#if !HAVE_DECL_GETPWNAM
-extern struct passwd *getpwnam (const char *name);
-#endif
-#if !HAVE_DECL_GETGRNAM
-extern struct group *getgrnam (const char *name);
-#endif
-#if !HAVE_DECL_GETGRGID
-extern struct group *getgrgid (gid_t gid);
-#endif
-
-#ifndef HAVE_ENDPWENT
-# define endpwent()
-#endif
-#ifndef HAVE_ENDGRENT
-# define endgrent()
-#endif
-
-/* Perform the equivalent of the statement `dest = strdup (src);',
- but obtaining storage via alloca instead of from the heap. */
-
-#define V_STRDUP(dest, src) \
- do \
- { \
- int _len = strlen ((src)); \
- (dest) = (char *) alloca (_len + 1); \
- strcpy (dest, src); \
- } \
- while (0)
-
-/* Return nonzero if STR represents an unsigned decimal integer,
- otherwise return 0. */
-
-static int
-isnumber_p (const char *str)
-{
- for (; *str; str++)
- if (!isdigit (*str))
- return 0;
- return 1;
-}
-
-/* Extract from NAME, which has the form "[user][:.][group]",
- a USERNAME, UID U, GROUPNAME, and GID G.
- Either user or group, or both, must be present.
- If the group is omitted but the ":" or "." separator is given,
- use the given user's login group.
-
- USERNAME and GROUPNAME will be in newly malloc'd memory.
- Either one might be NULL instead, indicating that it was not
- given and the corresponding numeric ID was left unchanged.
-
- Return NULL if successful, a static error message string if not. */
-
-const char *
-parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
- char **username_arg, char **groupname_arg)
-{
- static const char *tired = "virtual memory exhausted";
- const char *error_msg;
- char *spec; /* A copy we can write on. */
- struct passwd *pwd;
- struct group *grp;
- char *g, *u, *separator;
- char *groupname;
-
- error_msg = NULL;
- *username_arg = *groupname_arg = NULL;
- groupname = NULL;
-
- V_STRDUP (spec, spec_arg);
-
- /* Find the separator if there is one. */
- separator = strchr (spec, ':');
- if (separator == NULL)
- separator = strchr (spec, '.');
-
- /* Replace separator with a NUL. */
- if (separator != NULL)
- *separator = '\0';
-
- /* Set U and G to non-zero length strings corresponding to user and
- group specifiers or to NULL. */
- u = (*spec == '\0' ? NULL : spec);
-
- g = (separator == NULL || *(separator + 1) == '\0'
- ? NULL
- : separator + 1);
-
- if (u == NULL && g == NULL)
- return "can not omit both user and group";
-
- if (u != NULL)
- {
- pwd = getpwnam (u);
- if (pwd == NULL)
- {
-
- if (!isnumber_p (u))
- error_msg = _("invalid user");
- else
- {
- int use_login_group;
- use_login_group = (separator != NULL && g == NULL);
- if (use_login_group)
- error_msg = _("cannot get the login group of a numeric UID");
- else
- *uid = atoi (u);
- }
- }
- else
- {
- *uid = pwd->pw_uid;
- if (g == NULL && separator != NULL)
- {
- /* A separator was given, but a group was not specified,
- so get the login group. */
- *gid = pwd->pw_gid;
- grp = getgrgid (pwd->pw_gid);
- if (grp == NULL)
- {
- /* This is enough room to hold the unsigned decimal
- representation of any 32-bit quantity and the trailing
- zero byte. */
- char uint_buf[21];
- sprintf (uint_buf, "%u", (unsigned) (pwd->pw_gid));
- V_STRDUP (groupname, uint_buf);
- }
- else
- {
- V_STRDUP (groupname, grp->gr_name);
- }
- endgrent ();
- }
- }
- endpwent ();
- }
-
- if (g != NULL && error_msg == NULL)
- {
- /* Explicit group. */
- grp = getgrnam (g);
- if (grp == NULL)
- {
- if (!isnumber_p (g))
- error_msg = _("invalid group");
- else
- *gid = atoi (g);
- }
- else
- *gid = grp->gr_gid;
- endgrent (); /* Save a file descriptor. */
-
- if (error_msg == NULL)
- V_STRDUP (groupname, g);
- }
-
- if (error_msg == NULL)
- {
- if (u != NULL)
- {
- *username_arg = strdup (u);
- if (*username_arg == NULL)
- error_msg = tired;
- }
-
- if (groupname != NULL && error_msg == NULL)
- {
- *groupname_arg = strdup (groupname);
- if (*groupname_arg == NULL)
- {
- if (*username_arg != NULL)
- {
- free (*username_arg);
- *username_arg = NULL;
- }
- error_msg = tired;
- }
- }
- }
-
- return error_msg;
-}
-
-#ifdef TEST
-
-#define NULL_CHECK(s) ((s) == NULL ? "(null)" : (s))
-
-int
-main (int argc, char **argv)
-{
- int i;
-
- for (i = 1; i < argc; i++)
- {
- const char *e;
- char *username, *groupname;
- uid_t uid;
- gid_t gid;
- char *tmp;
-
- tmp = strdup (argv[i]);
- e = parse_user_spec (tmp, &uid, &gid, &username, &groupname);
- free (tmp);
- printf ("%s: %u %u %s %s %s\n",
- argv[i],
- (unsigned int) uid,
- (unsigned int) gid,
- NULL_CHECK (username),
- NULL_CHECK (groupname),
- NULL_CHECK (e));
- }
-
- exit (0);
-}
-
-#endif
diff --git a/contrib/cpio/src/util.c b/contrib/cpio/src/util.c
deleted file mode 100644
index 8773f75..0000000
--- a/contrib/cpio/src/util.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/* $FreeBSD$ */
-
-/* util.c - Several utility routines for cpio.
- Copyright (C) 1990, 1991, 1992, 2001, 2004,
- 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301 USA. */
-
-#include <system.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "cpiohdr.h"
-#include "dstring.h"
-#include "extern.h"
-#include <paxlib.h>
-#include "filetypes.h"
-#include <safe-read.h>
-#include <full-write.h>
-#include <rmt.h>
-#include <hash.h>
-#include <utimens.h>
-
-#include <sys/ioctl.h>
-
-#ifdef HAVE_SYS_MTIO_H
-# ifdef HAVE_SYS_IO_TRIOCTL_H
-# include <sys/io/trioctl.h>
-# endif
-# include <sys/mtio.h>
-#endif
-
-#if !HAVE_DECL_ERRNO
-extern int errno;
-#endif
-
-/* Write `output_size' bytes of `output_buffer' to file
- descriptor OUT_DES and reset `output_size' and `out_buff'. */
-
-void
-tape_empty_output_buffer (int out_des)
-{
- int bytes_written;
-
-#ifdef BROKEN_LONG_TAPE_DRIVER
- static long output_bytes_before_lseek = 0;
-
- /* Some tape drivers seem to have a signed internal seek pointer and
- they lose if it overflows and becomes negative (e.g. when writing
- tapes > 2Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
- seek pointer and prevent it from overflowing. */
- if (output_is_special
- && ( (output_bytes_before_lseek += output_size) >= 1073741824L) )
- {
- lseek(out_des, 0L, SEEK_SET);
- output_bytes_before_lseek = 0;
- }
-#endif
-
- bytes_written = rmtwrite (out_des, output_buffer, output_size);
- if (bytes_written != output_size)
- {
- int rest_bytes_written;
- int rest_output_size;
-
- if (output_is_special
- && (bytes_written >= 0
- || (bytes_written < 0
- && (errno == ENOSPC || errno == EIO || errno == ENXIO))))
- {
- get_next_reel (out_des);
- if (bytes_written > 0)
- rest_output_size = output_size - bytes_written;
- else
- rest_output_size = output_size;
- rest_bytes_written = rmtwrite (out_des, output_buffer,
- rest_output_size);
- if (rest_bytes_written != rest_output_size)
- error (1, errno, _("write error"));
- }
- else
- error (1, errno, _("write error"));
- }
- output_bytes += output_size;
- out_buff = output_buffer;
- output_size = 0;
-}
-
-static int sparse_write (int fildes, char *buf, unsigned int nbyte);
-
-/* Write `output_size' bytes of `output_buffer' to file
- descriptor OUT_DES and reset `output_size' and `out_buff'.
- If `swapping_halfwords' or `swapping_bytes' is set,
- do the appropriate swapping first. Our callers have
- to make sure to only set these flags if `output_size'
- is appropriate (a multiple of 4 for `swapping_halfwords',
- 2 for `swapping_bytes'). The fact that DISK_IO_BLOCK_SIZE
- must always be a multiple of 4 helps us (and our callers)
- insure this. */
-
-void
-disk_empty_output_buffer (int out_des)
-{
- int bytes_written;
-
- if (swapping_halfwords || swapping_bytes)
- {
- if (swapping_halfwords)
- {
- int complete_words;
- complete_words = output_size / 4;
- swahw_array (output_buffer, complete_words);
- if (swapping_bytes)
- swab_array (output_buffer, 2 * complete_words);
- }
- else
- {
- int complete_halfwords;
- complete_halfwords = output_size /2;
- swab_array (output_buffer, complete_halfwords);
- }
- }
-
- if (sparse_flag)
- bytes_written = sparse_write (out_des, output_buffer, output_size);
- else
- bytes_written = write (out_des, output_buffer, output_size);
-
- if (bytes_written != output_size)
- {
- error (1, errno, _("write error"));
- }
- output_bytes += output_size;
- out_buff = output_buffer;
- output_size = 0;
-}
-
-/* Exchange the halfwords of each element of the array of COUNT longs
- starting at PTR. PTR does not have to be aligned at a word
- boundary. */
-
-void
-swahw_array (char *ptr, int count)
-{
- char tmp;
-
- for (; count > 0; --count)
- {
- tmp = *ptr;
- *ptr = *(ptr + 2);
- *(ptr + 2) = tmp;
- ++ptr;
- tmp = *ptr;
- *ptr = *(ptr + 2);
- *(ptr + 2) = tmp;
- ptr += 3;
- }
-}
-
-/* Read at most NUM_BYTES or `io_block_size' bytes, whichever is smaller,
- into the start of `input_buffer' from file descriptor IN_DES.
- Set `input_size' to the number of bytes read and reset `in_buff'.
- Exit with an error if end of file is reached. */
-
-#ifdef BROKEN_LONG_TAPE_DRIVER
-static long input_bytes_before_lseek = 0;
-#endif
-
-static void
-tape_fill_input_buffer (int in_des, int num_bytes)
-{
-#ifdef BROKEN_LONG_TAPE_DRIVER
- /* Some tape drivers seem to have a signed internal seek pointer and
- they lose if it overflows and becomes negative (e.g. when writing
- tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
- seek pointer and prevent it from overflowing. */
- if (input_is_special
- && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) )
- {
- lseek(in_des, 0L, SEEK_SET);
- input_bytes_before_lseek = 0;
- }
-#endif
- in_buff = input_buffer;
- num_bytes = (num_bytes < io_block_size) ? num_bytes : io_block_size;
- input_size = rmtread (in_des, input_buffer, num_bytes);
- if (input_size == 0 && input_is_special)
- {
- get_next_reel (in_des);
- input_size = rmtread (in_des, input_buffer, num_bytes);
- }
- if (input_size < 0)
- error (1, errno, _("read error"));
- if (input_size == 0)
- {
- error (0, 0, _("premature end of file"));
- exit (1);
- }
- input_bytes += input_size;
-}
-
-/* Read at most NUM_BYTES or `DISK_IO_BLOCK_SIZE' bytes, whichever is smaller,
- into the start of `input_buffer' from file descriptor IN_DES.
- Set `input_size' to the number of bytes read and reset `in_buff'.
- Exit with an error if end of file is reached. */
-
-static int
-disk_fill_input_buffer (int in_des, off_t num_bytes)
-{
- in_buff = input_buffer;
- num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE;
- input_size = read (in_des, input_buffer, num_bytes);
- if (input_size < 0)
- {
- input_size = 0;
- return (-1);
- }
- else if (input_size == 0)
- return (1);
- input_bytes += input_size;
- return (0);
-}
-
-/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
- When `out_buff' fills up, flush it to file descriptor OUT_DES. */
-
-void
-tape_buffered_write (char *in_buf, int out_des, off_t num_bytes)
-{
- off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
- off_t space_left; /* Room left in output buffer. */
-
- while (bytes_left > 0)
- {
- space_left = io_block_size - output_size;
- if (space_left == 0)
- tape_empty_output_buffer (out_des);
- else
- {
- if (bytes_left < space_left)
- space_left = bytes_left;
- memcpy (out_buff, in_buf, (unsigned) space_left);
- out_buff += space_left;
- output_size += space_left;
- in_buf += space_left;
- bytes_left -= space_left;
- }
- }
-}
-
-/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
- When `out_buff' fills up, flush it to file descriptor OUT_DES. */
-
-void
-disk_buffered_write (char *in_buf, int out_des, off_t num_bytes)
-{
- off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
- off_t space_left; /* Room left in output buffer. */
-
- while (bytes_left > 0)
- {
- space_left = DISK_IO_BLOCK_SIZE - output_size;
- if (space_left == 0)
- disk_empty_output_buffer (out_des);
- else
- {
- if (bytes_left < space_left)
- space_left = bytes_left;
- memcpy (out_buff, in_buf, (unsigned) space_left);
- out_buff += space_left;
- output_size += space_left;
- in_buf += space_left;
- bytes_left -= space_left;
- }
- }
-}
-
-/* Copy NUM_BYTES of buffer `in_buff' into IN_BUF.
- `in_buff' may be partly full.
- When `in_buff' is exhausted, refill it from file descriptor IN_DES. */
-
-void
-tape_buffered_read (char *in_buf, int in_des, off_t num_bytes)
-{
- off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
- off_t space_left; /* Bytes to copy from input buffer. */
-
- while (bytes_left > 0)
- {
- if (input_size == 0)
- tape_fill_input_buffer (in_des, io_block_size);
- if (bytes_left < input_size)
- space_left = bytes_left;
- else
- space_left = input_size;
- memcpy (in_buf, in_buff, (unsigned) space_left);
- in_buff += space_left;
- in_buf += space_left;
- input_size -= space_left;
- bytes_left -= space_left;
- }
-}
-
-/* Copy the the next NUM_BYTES bytes of `input_buffer' into PEEK_BUF.
- If NUM_BYTES bytes are not available, read the next `io_block_size' bytes
- into the end of `input_buffer' and update `input_size'.
-
- Return the number of bytes copied into PEEK_BUF.
- If the number of bytes returned is less than NUM_BYTES,
- then EOF has been reached. */
-
-int
-tape_buffered_peek (char *peek_buf, int in_des, int num_bytes)
-{
- long tmp_input_size;
- long got_bytes;
- char *append_buf;
-
-#ifdef BROKEN_LONG_TAPE_DRIVER
- /* Some tape drivers seem to have a signed internal seek pointer and
- they lose if it overflows and becomes negative (e.g. when writing
- tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
- seek pointer and prevent it from overflowing. */
- if (input_is_special
- && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) )
- {
- lseek(in_des, 0L, SEEK_SET);
- input_bytes_before_lseek = 0;
- }
-#endif
-
- while (input_size < num_bytes)
- {
- append_buf = in_buff + input_size;
- if ( (append_buf - input_buffer) >= input_buffer_size)
- {
- /* We can keep up to 2 "blocks" (either the physical block size
- or 512 bytes(the size of a tar record), which ever is
- larger) in the input buffer when we are peeking. We
- assume that our caller will never be interested in peeking
- ahead at more than 512 bytes, so we know that by the time
- we need a 3rd "block" in the buffer we can throw away the
- first block to make room. */
- int half;
- half = input_buffer_size / 2;
- memmove (input_buffer, input_buffer + half, half);
- in_buff = in_buff - half;
- append_buf = append_buf - half;
- }
- tmp_input_size = rmtread (in_des, append_buf, io_block_size);
- if (tmp_input_size == 0)
- {
- if (input_is_special)
- {
- get_next_reel (in_des);
- tmp_input_size = rmtread (in_des, append_buf, io_block_size);
- }
- else
- break;
- }
- if (tmp_input_size < 0)
- error (1, errno, _("read error"));
- input_bytes += tmp_input_size;
- input_size += tmp_input_size;
- }
- if (num_bytes <= input_size)
- got_bytes = num_bytes;
- else
- got_bytes = input_size;
- memcpy (peek_buf, in_buff, (unsigned) got_bytes);
- return got_bytes;
-}
-
-/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
-
-void
-tape_toss_input (int in_des, off_t num_bytes)
-{
- off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
- off_t space_left; /* Bytes to copy from input buffer. */
-
- while (bytes_left > 0)
- {
- if (input_size == 0)
- tape_fill_input_buffer (in_des, io_block_size);
- if (bytes_left < input_size)
- space_left = bytes_left;
- else
- space_left = input_size;
-
- if (crc_i_flag && only_verify_crc_flag)
- {
- int k;
- for (k = 0; k < space_left; ++k)
- crc += in_buff[k] & 0xff;
- }
-
- in_buff += space_left;
- input_size -= space_left;
- bytes_left -= space_left;
- }
-}
-
-void
-write_nuls_to_file (off_t num_bytes, int out_des,
- void (*writer) (char *in_buf, int out_des, off_t num_bytes))
-{
- off_t blocks;
- off_t extra_bytes;
- off_t i;
- static char zeros_512[512];
-
- blocks = num_bytes / sizeof zeros_512;
- extra_bytes = num_bytes % sizeof zeros_512;
- for (i = 0; i < blocks; ++i)
- writer (zeros_512, out_des, sizeof zeros_512);
- if (extra_bytes)
- writer (zeros_512, out_des, extra_bytes);
-}
-
-/* Copy a file using the input and output buffers, which may start out
- partly full. After the copy, the files are not closed nor the last
- block flushed to output, and the input buffer may still be partly
- full. If `crc_i_flag' is set, add each byte to `crc'.
- IN_DES is the file descriptor for input;
- OUT_DES is the file descriptor for output;
- NUM_BYTES is the number of bytes to copy. */
-
-void
-copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes)
-{
- long size;
- long k;
-
- while (num_bytes > 0)
- {
- if (input_size == 0)
- tape_fill_input_buffer (in_des, io_block_size);
- size = (input_size < num_bytes) ? input_size : num_bytes;
- if (crc_i_flag)
- {
- for (k = 0; k < size; ++k)
- crc += in_buff[k] & 0xff;
- }
- disk_buffered_write (in_buff, out_des, size);
- num_bytes -= size;
- input_size -= size;
- in_buff += size;
- }
-}
-/* Copy a file using the input and output buffers, which may start out
- partly full. After the copy, the files are not closed nor the last
- block flushed to output, and the input buffer may still be partly
- full. If `crc_i_flag' is set, add each byte to `crc'.
- IN_DES is the file descriptor for input;
- OUT_DES is the file descriptor for output;
- NUM_BYTES is the number of bytes to copy. */
-
-void
-copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes,
- char *filename)
-{
- long size;
- long k;
- int rc;
- off_t original_num_bytes;
-
- original_num_bytes = num_bytes;
-
- while (num_bytes > 0)
- {
- if (input_size == 0)
- if (rc = disk_fill_input_buffer (in_des,
- num_bytes < DISK_IO_BLOCK_SIZE ?
- num_bytes : DISK_IO_BLOCK_SIZE))
- {
- if (rc > 0)
- {
- char buf[UINTMAX_STRSIZE_BOUND];
- error (0, 0,
- ngettext ("File %s shrunk by %s byte, padding with zeros",
- "File %s shrunk by %s bytes, padding with zeros",
- num_bytes),
- filename, STRINGIFY_BIGINT (num_bytes, buf));
- }
- else
- error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
- original_num_bytes - num_bytes, filename);
- write_nuls_to_file (num_bytes, out_des, tape_buffered_write);
- break;
- }
- size = (input_size < num_bytes) ? input_size : num_bytes;
- if (crc_i_flag)
- {
- for (k = 0; k < size; ++k)
- crc += in_buff[k] & 0xff;
- }
- tape_buffered_write (in_buff, out_des, size);
- num_bytes -= size;
- input_size -= size;
- in_buff += size;
- }
-}
-/* Copy a file using the input and output buffers, which may start out
- partly full. After the copy, the files are not closed nor the last
- block flushed to output, and the input buffer may still be partly
- full. If `crc_i_flag' is set, add each byte to `crc'.
- IN_DES is the file descriptor for input;
- OUT_DES is the file descriptor for output;
- NUM_BYTES is the number of bytes to copy. */
-
-void
-copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes,
- char *filename)
-{
- long size;
- long k;
- off_t original_num_bytes;
- int rc;
-
- original_num_bytes = num_bytes;
- while (num_bytes > 0)
- {
- if (input_size == 0)
- if (rc = disk_fill_input_buffer (in_des, num_bytes))
- {
- if (rc > 0)
- {
- char buf[UINTMAX_STRSIZE_BOUND];
- error (0, 0,
- ngettext ("File %s shrunk by %s byte, padding with zeros",
- "File %s shrunk by %s bytes, padding with zeros",
- num_bytes),
- filename, STRINGIFY_BIGINT (num_bytes, buf));
- }
- else
- error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
- original_num_bytes - num_bytes, filename);
- write_nuls_to_file (num_bytes, out_des, disk_buffered_write);
- break;
- }
- size = (input_size < num_bytes) ? input_size : num_bytes;
- if (crc_i_flag)
- {
- for (k = 0; k < size; ++k)
- crc += in_buff[k] & 0xff;
- }
- disk_buffered_write (in_buff, out_des, size);
- num_bytes -= size;
- input_size -= size;
- in_buff += size;
- }
-}
-
-/* Warn if file changed while it was being copied. */
-
-void
-warn_if_file_changed (char *file_name, unsigned long old_file_size,
- off_t old_file_mtime)
-{
- struct stat new_file_stat;
- if ((*xstat) (file_name, &new_file_stat) < 0)
- {
- stat_error (file_name);
- return;
- }
-
- /* Only check growth, shrinkage detected in copy_files_disk_to_{disk,tape}()
- */
- if (new_file_stat.st_size > old_file_size)
- error (0, 0,
- ngettext ("File %s grew, %"PRIuMAX" new byte not copied",
- "File %s grew, %"PRIuMAX" new bytes not copied",
- (long)(new_file_stat.st_size - old_file_size)),
- file_name, (uintmax_t) (new_file_stat.st_size - old_file_size));
-
- else if (new_file_stat.st_mtime != old_file_mtime)
- error (0, 0, _("File %s was modified while being copied"), file_name);
-}
-
-/* Create all directories up to but not including the last part of NAME.
- Do not destroy any nondirectories while creating directories. */
-
-void
-create_all_directories (char *name)
-{
- char *dir;
- int mode;
-#ifdef HPUX_CDF
- int cdf;
-#endif
-
- dir = dir_name (name);
- mode = 0700;
-#ifdef HPUX_CDF
- cdf = islastparentcdf (name);
- if (cdf)
- {
- dir [strlen (dir) - 1] = '\0'; /* remove final + */
- mode = 04700;
- }
-
-#endif
-
- if (dir == NULL)
- error (2, 0, _("virtual memory exhausted"));
-
- if (dir[0] != '.' || dir[1] != '\0')
- make_path (dir, mode, 0700, -1, -1, (char *) NULL);
-
- free (dir);
-}
-
-/* Prepare to append to an archive. We have been in
- process_copy_in, keeping track of the position where
- the last header started in `last_header_start'. Now we
- have the starting position of the last header (the TRAILER!!!
- header, or blank record for tar archives) and we want to start
- writing (appending) over the last header. The last header may
- be in the middle of a block, so to keep the buffering in sync
- we lseek back to the start of the block, read everything up
- to but not including the last header, lseek back to the start
- of the block, and then do a copy_buf_out of what we read.
- Actually, we probably don't have to worry so much about keeping the
- buffering perfect since you can only append to archives that
- are disk files. */
-
-void
-prepare_append (int out_file_des)
-{
- int start_of_header;
- int start_of_block;
- int useful_bytes_in_block;
- char *tmp_buf;
-
- start_of_header = last_header_start;
- /* Figure out how many bytes we will rewrite, and where they start. */
- useful_bytes_in_block = start_of_header % io_block_size;
- start_of_block = start_of_header - useful_bytes_in_block;
-
- if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
- error (1, errno, _("cannot seek on output"));
- if (useful_bytes_in_block > 0)
- {
- tmp_buf = (char *) xmalloc (useful_bytes_in_block);
- read (out_file_des, tmp_buf, useful_bytes_in_block);
- if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
- error (1, errno, _("cannot seek on output"));
- /* fix juo -- is this copy_tape_buf_out? or copy_disk? */
- tape_buffered_write (tmp_buf, out_file_des, useful_bytes_in_block);
- free (tmp_buf);
- }
-
- /* We are done reading the archive, so clear these since they
- will now be used for reading in files that we are appending
- to the archive. */
- input_size = 0;
- input_bytes = 0;
- in_buff = input_buffer;
-}
-
-/* Support for remembering inodes with multiple links. Used in the
- "copy in" and "copy pass" modes for making links instead of copying
- the file. */
-
-struct inode_val
-{
- unsigned long inode;
- unsigned long major_num;
- unsigned long minor_num;
- char *file_name;
-};
-
-/* Inode hash table. Allocated by first call to add_inode. */
-static Hash_table *hash_table = NULL;
-
-static size_t
-inode_val_hasher (const void *val, size_t n_buckets)
-{
- const struct inode_val *ival = val;
- return ival->inode % n_buckets;
-}
-
-static bool
-inode_val_compare (const void *val1, const void *val2)
-{
- const struct inode_val *ival1 = val1;
- const struct inode_val *ival2 = val2;
- return ival1->inode == ival2->inode
- && ival1->major_num == ival2->major_num
- && ival1->minor_num == ival2->minor_num;
-}
-
-char *
-find_inode_file (unsigned long node_num, unsigned long major_num,
- unsigned long minor_num)
-{
- struct inode_val sample;
- struct inode_val *ival;
-
- if (!hash_table)
- return NULL;
-
- sample.inode = node_num;
- sample.major_num = major_num;
- sample.minor_num = minor_num;
- ival = hash_lookup (hash_table, &sample);
- return ival ? ival->file_name : NULL;
-}
-
-/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */
-
-void
-add_inode (unsigned long node_num, char *file_name, unsigned long major_num,
- unsigned long minor_num)
-{
- struct inode_val *temp;
- struct inode_val *e;
-
- /* Create new inode record. */
- temp = (struct inode_val *) xmalloc (sizeof (struct inode_val));
- temp->inode = node_num;
- temp->major_num = major_num;
- temp->minor_num = minor_num;
- temp->file_name = xstrdup (file_name);
-
- if (!((hash_table
- || (hash_table = hash_initialize (0, 0, inode_val_hasher,
- inode_val_compare, 0)))
- && (e = hash_insert (hash_table, temp))))
- xalloc_die ();
- /* FIXME: e is not used */
-}
-
-
-/* Open FILE in the mode specified by the command line options
- and return an open file descriptor for it,
- or -1 if it can't be opened. */
-
-int
-open_archive (char *file)
-{
- int fd;
- void (*copy_in) (); /* Workaround for pcc bug. */
-
- copy_in = process_copy_in;
-
- if (copy_function == copy_in)
- fd = rmtopen (file, O_RDONLY | O_BINARY, MODE_RW, rsh_command_option);
- else
- {
- if (!append_flag)
- fd = rmtopen (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, MODE_RW,
- rsh_command_option);
- else
- fd = rmtopen (file, O_RDWR | O_BINARY, MODE_RW, rsh_command_option);
- }
-
- return fd;
-}
-
-/* Attempt to rewind the tape drive on file descriptor TAPE_DES
- and take it offline. */
-
-void
-tape_offline (int tape_des)
-{
-#if defined(MTIOCTOP) && defined(MTOFFL)
- struct mtop control;
-
- control.mt_op = MTOFFL;
- control.mt_count = 1;
- rmtioctl (tape_des, MTIOCTOP, (char*) &control); /* Don't care if it fails. */
-#endif
-}
-
-/* The file on file descriptor TAPE_DES is assumed to be magnetic tape
- (or floppy disk or other device) and the end of the medium
- has been reached. Ask the user for to mount a new "tape" to continue
- the processing. If the user specified the device name on the
- command line (with the -I, -O, -F or --file options), then we can
- automatically re-open the same device to use the next medium. If the
- user did not specify the device name, then we have to ask them which
- device to use. */
-
-void
-get_next_reel (int tape_des)
-{
- static int reel_number = 1;
- FILE *tty_in; /* File for interacting with user. */
- FILE *tty_out; /* File for interacting with user. */
- int old_tape_des;
- char *next_archive_name;
- dynamic_string new_name;
- char *str_res;
-
- ds_init (&new_name, 128);
-
- /* Open files for interactive communication. */
- tty_in = fopen (TTY_NAME, "r");
- if (tty_in == NULL)
- error (2, errno, TTY_NAME);
- tty_out = fopen (TTY_NAME, "w");
- if (tty_out == NULL)
- error (2, errno, TTY_NAME);
-
- old_tape_des = tape_des;
- tape_offline (tape_des);
- rmtclose (tape_des);
-
- /* Give message and wait for carrage return. User should hit carrage return
- only after loading the next tape. */
- ++reel_number;
- if (new_media_message)
- fprintf (tty_out, "%s", new_media_message);
- else if (new_media_message_with_number)
- fprintf (tty_out, "%s%d%s", new_media_message_with_number, reel_number,
- new_media_message_after_number);
- else if (archive_name)
- fprintf (tty_out, _("Found end of volume. Load next volume and press RETURN. "));
- else
- fprintf (tty_out, _("Found end of volume. To continue, type device/file name when ready.\n"));
-
- fflush (tty_out);
-
- if (archive_name)
- {
- int c;
-
- do
- c = getc (tty_in);
- while (c != EOF && c != '\n');
-
- tape_des = open_archive (archive_name);
- if (tape_des == -1)
- open_error (archive_name);
- }
- else
- {
- do
- {
- if (tape_des < 0)
- {
- fprintf (tty_out,
- _("To continue, type device/file name when ready.\n"));
- fflush (tty_out);
- }
-
- str_res = ds_fgets (tty_in, &new_name);
- if (str_res == NULL || str_res[0] == '\0')
- exit (1);
- next_archive_name = str_res;
-
- tape_des = open_archive (next_archive_name);
- if (tape_des == -1)
- open_error (next_archive_name);
- }
- while (tape_des < 0);
- }
-
- /* We have to make sure that `tape_des' has not changed its value even
- though we closed it and reopened it, since there are local
- copies of it in other routines. This works fine on Unix (even with
- rmtread and rmtwrite) since open will always return the lowest
- available file descriptor and we haven't closed any files (e.g.,
- stdin, stdout or stderr) that were opened before we originally opened
- the archive. */
-
- if (tape_des != old_tape_des)
- error (1, 0, _("internal error: tape descriptor changed from %d to %d"),
- old_tape_des, tape_des);
-
- free (new_name.ds_string);
- fclose (tty_in);
- fclose (tty_out);
-}
-
-/* If MESSAGE does not contain the string "%d", make `new_media_message'
- a copy of MESSAGE. If MESSAGES does contain the string "%d", make
- `new_media_message_with_number' a copy of MESSAGE up to, but
- not including, the string "%d", and make `new_media_message_after_number'
- a copy of MESSAGE after the string "%d". */
-
-void
-set_new_media_message (char *message)
-{
- char *p;
- int prev_was_percent;
-
- p = message;
- prev_was_percent = 0;
- while (*p != '\0')
- {
- if (*p == 'd' && prev_was_percent)
- break;
- prev_was_percent = (*p == '%');
- ++p;
- }
- if (*p == '\0')
- {
- new_media_message = xstrdup (message);
- }
- else
- {
- int length = p - message - 1;
-
- new_media_message_with_number = xmalloc (length + 1);
- strncpy (new_media_message_with_number, message, length);
- new_media_message_with_number[length] = '\0';
- length = strlen (p + 1);
- new_media_message_after_number = xmalloc (length + 1);
- strcpy (new_media_message_after_number, p + 1);
- }
-}
-
-#ifdef SYMLINK_USES_UMASK
-/* Most machines always create symlinks with rwxrwxrwx protection,
- but some (HP/UX 8.07; maybe DEC's OSF on MIPS, too?) use the
- umask when creating symlinks, so if your umask is 022 you end
- up with rwxr-xr-x symlinks (although HP/UX seems to completely
- ignore the protection). There doesn't seem to be any way to
- manipulate the modes once the symlinks are created (e.g.
- a hypothetical "lchmod"), so to create them with the right
- modes we have to set the umask first. */
-
-int
-umasked_symlink (char *name1, char *name2, int mode)
-{
- int old_umask;
- int rc;
- mode = ~(mode & 0777) & 0777;
- old_umask = umask (mode);
- rc = symlink (name1, name2);
- umask (old_umask);
- return rc;
-}
-#endif /* SYMLINK_USES_UMASK */
-
-#ifdef HPUX_CDF
-/* When we create a cpio archive we mark CDF's by putting an extra `/'
- after their component name so we can distinguish the CDF's when we
- extract the archive (in case the "hidden" directory's files appear
- in the archive before the directory itself). E.g., in the path
- "a/b+/c", if b+ is a CDF, we will write this path as "a/b+//c" in
- the archive so when we extract the archive we will know that b+
- is actually a CDF, and not an ordinary directory whose name happens
- to end in `+'. We also do the same thing internally in copypass.c. */
-
-
-/* Take an input pathname and check it for CDF's. Insert an extra
- `/' in the pathname after each "hidden" directory. If we add
- any `/'s, return a malloced string instead of the original input
- string.
- FIXME: This creates a memory leak.
-*/
-
-char *
-add_cdf_double_slashes (char *input_name)
-{
- static char *ret_name = NULL; /* re-usuable return buffer (malloc'ed) */
- static int ret_size = -1; /* size of return buffer. */
- char *p;
- char *q;
- int n;
- struct stat dir_stat;
-
- /* Search for a `/' preceeded by a `+'. */
-
- for (p = input_name; *p != '\0'; ++p)
- {
- if ( (*p == '+') && (*(p + 1) == '/') )
- break;
- }
-
- /* If we didn't find a `/' preceeded by a `+' then there are
- no CDF's in this pathname. Return the original pathname. */
-
- if (*p == '\0')
- return input_name;
-
- /* There was a `/' preceeded by a `+' in the pathname. If it is a CDF
- then we will need to copy the input pathname to our return
- buffer so we can insert the extra `/'s. Since we can't tell
- yet whether or not it is a CDF we will just always copy the
- string to the return buffer. First we have to make sure the
- buffer is large enough to hold the string and any number of
- extra `/'s we might add. */
-
- n = 2 * (strlen (input_name) + 1);
- if (n >= ret_size)
- {
- if (ret_size < 0)
- ret_name = (char *) malloc (n);
- else
- ret_name = (char *)realloc (ret_name, n);
- ret_size = n;
- }
-
- /* Clear the `/' after this component, so we can stat the pathname
- up to and including this component. */
- ++p;
- *p = '\0';
- if ((*xstat) (input_name, &dir_stat) < 0)
- {
- stat_error (input_name);
- return input_name;
- }
-
- /* Now put back the `/' after this component and copy the pathname up to
- and including this component and its trailing `/' to the return
- buffer. */
- *p++ = '/';
- strncpy (ret_name, input_name, p - input_name);
- q = ret_name + (p - input_name);
-
- /* If it was a CDF, add another `/'. */
- if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) )
- *q++ = '/';
-
- /* Go through the rest of the input pathname, copying it to the
- return buffer, and adding an extra `/' after each CDF. */
- while (*p != '\0')
- {
- if ( (*p == '+') && (*(p + 1) == '/') )
- {
- *q++ = *p++;
-
- *p = '\0';
- if ((*xstat) (input_name, &dir_stat) < 0)
- {
- stat_error (input_name);
- return input_name;
- }
- *p = '/';
-
- if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) )
- *q++ = '/';
- }
- *q++ = *p++;
- }
- *q = '\0';
-
- return ret_name;
-}
-
-/* Is the last parent directory (e.g., c in a/b/c/d) a CDF? If the
- directory name ends in `+' and is followed by 2 `/'s instead of 1
- then it is. This is only the case for cpio archives, but we don't
- have to worry about tar because tar always has the directory before
- its files (or else we lose). */
-int
-islastparentcdf (char *path)
-{
- char *newpath;
- char *slash;
- int slash_count;
- int length; /* Length of result, not including NUL. */
-
- slash = strrchr (path, '/');
- if (slash == 0)
- return 0;
- else
- {
- slash_count = 0;
- while (slash > path && *slash == '/')
- {
- ++slash_count;
- --slash;
- }
-
-
- if ( (*slash == '+') && (slash_count >= 2) )
- return 1;
- }
- return 0;
-}
-#endif
-
-#define DISKBLOCKSIZE (512)
-
-static int
-buf_all_zeros (char *buf, int bufsize)
-{
- int i;
- for (i = 0; i < bufsize; ++i)
- {
- if (*buf++ != '\0')
- return 0;
- }
- return 1;
-}
-
-int delayed_seek_count = 0;
-
-/* Write NBYTE bytes from BUF to remote tape connection FILDES.
- Return the number of bytes written on success, -1 on error. */
-
-static int
-sparse_write (int fildes, char *buf, unsigned int nbyte)
-{
- int complete_block_count;
- int leftover_bytes_count;
- int seek_count;
- int write_count;
- char *cur_write_start;
- int lseek_rc;
- int write_rc;
- int i;
- enum { begin, in_zeros, not_in_zeros } state;
-
- complete_block_count = nbyte / DISKBLOCKSIZE;
- leftover_bytes_count = nbyte % DISKBLOCKSIZE;
-
- if (delayed_seek_count != 0)
- state = in_zeros;
- else
- state = begin;
-
- seek_count = delayed_seek_count;
-
- for (i = 0; i < complete_block_count; ++i)
- {
- switch (state)
- {
- case begin :
- if (buf_all_zeros (buf, DISKBLOCKSIZE))
- {
- seek_count = DISKBLOCKSIZE;
- state = in_zeros;
- }
- else
- {
- cur_write_start = buf;
- write_count = DISKBLOCKSIZE;
- state = not_in_zeros;
- }
- buf += DISKBLOCKSIZE;
- break;
-
- case in_zeros :
- if (buf_all_zeros (buf, DISKBLOCKSIZE))
- {
- seek_count += DISKBLOCKSIZE;
- }
- else
- {
- lseek (fildes, seek_count, SEEK_CUR);
- cur_write_start = buf;
- write_count = DISKBLOCKSIZE;
- state = not_in_zeros;
- }
- buf += DISKBLOCKSIZE;
- break;
-
- case not_in_zeros :
- if (buf_all_zeros (buf, DISKBLOCKSIZE))
- {
- write_rc = write (fildes, cur_write_start, write_count);
- seek_count = DISKBLOCKSIZE;
- state = in_zeros;
- }
- else
- {
- write_count += DISKBLOCKSIZE;
- }
- buf += DISKBLOCKSIZE;
- break;
- }
- }
-
- switch (state)
- {
- case begin :
- case in_zeros :
- delayed_seek_count = seek_count;
- break;
-
- case not_in_zeros :
- write_rc = write (fildes, cur_write_start, write_count);
- delayed_seek_count = 0;
- break;
- }
-
- if (leftover_bytes_count != 0)
- {
- if (delayed_seek_count != 0)
- {
- lseek_rc = lseek (fildes, delayed_seek_count, SEEK_CUR);
- delayed_seek_count = 0;
- }
- write_rc = write (fildes, buf, leftover_bytes_count);
- }
- return nbyte;
-}
-
-#define CPIO_UID(uid) (set_owner_flag ? set_owner : (uid))
-#define CPIO_GID(gid) (set_group_flag ? set_group : (gid))
-
-void
-stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st)
-{
- hdr->c_dev_maj = major (st->st_dev);
- hdr->c_dev_min = minor (st->st_dev);
- hdr->c_ino = st->st_ino;
- /* For POSIX systems that don't define the S_IF macros,
- we can't assume that S_ISfoo means the standard Unix
- S_IFfoo bit(s) are set. So do it manually, with a
- different name. Bleah. */
- hdr->c_mode = (st->st_mode & 07777);
- if (S_ISREG (st->st_mode))
- hdr->c_mode |= CP_IFREG;
- else if (S_ISDIR (st->st_mode))
- hdr->c_mode |= CP_IFDIR;
-#ifdef S_ISBLK
- else if (S_ISBLK (st->st_mode))
- hdr->c_mode |= CP_IFBLK;
-#endif
-#ifdef S_ISCHR
- else if (S_ISCHR (st->st_mode))
- hdr->c_mode |= CP_IFCHR;
-#endif
-#ifdef S_ISFIFO
- else if (S_ISFIFO (st->st_mode))
- hdr->c_mode |= CP_IFIFO;
-#endif
-#ifdef S_ISLNK
- else if (S_ISLNK (st->st_mode))
- hdr->c_mode |= CP_IFLNK;
-#endif
-#ifdef S_ISSOCK
- else if (S_ISSOCK (st->st_mode))
- hdr->c_mode |= CP_IFSOCK;
-#endif
-#ifdef S_ISNWK
- else if (S_ISNWK (st->st_mode))
- hdr->c_mode |= CP_IFNWK;
-#endif
- hdr->c_uid = CPIO_UID (st->st_uid);
- hdr->c_gid = CPIO_GID (st->st_gid);
- hdr->c_nlink = st->st_nlink;
- hdr->c_rdev_maj = major (st->st_rdev);
- hdr->c_rdev_min = minor (st->st_rdev);
- hdr->c_mtime = st->st_mtime;
- hdr->c_filesize = st->st_size;
- hdr->c_chksum = 0;
- hdr->c_tar_linkname = NULL;
-}
-
-#ifndef HAVE_FCHOWN
-# define fchown(fd, uid, gid) (-1)
-#endif
-
-int
-fchown_or_chown (int fd, const char *name, uid_t uid, uid_t gid)
-{
- if (HAVE_FCHOWN && fd != -1)
- return fchown (fd, uid, gid);
- else
- return chown (name, uid, gid);
-}
-
-int
-fchmod_or_chmod (int fd, const char *name, mode_t mode)
-{
- if (HAVE_FCHMOD && fd != -1)
- return fchmod (fd, mode);
- else
- return chmod(name, mode);
-}
-
-void
-set_perms (int fd, struct cpio_file_stat *header)
-{
- if (!no_chown_flag)
- {
- uid_t uid = CPIO_UID (header->c_uid);
- gid_t gid = CPIO_GID (header->c_gid);
- if ((fchown_or_chown (fd, header->c_name, uid, gid) < 0)
- && errno != EPERM)
- chown_error_details (header->c_name, uid, gid);
- }
- /* chown may have turned off some permissions we wanted. */
- if (fchmod_or_chmod (fd, header->c_name, header->c_mode) < 0)
- chmod_error_details (header->c_name, header->c_mode);
-#ifdef HPUX_CDF
- if ((header->c_mode & CP_IFMT) && cdf_flag)
- /* Once we "hide" the directory with the chmod(),
- we have to refer to it using name+ instead of name. */
- file_hdr->c_name [cdf_char] = '+';
-#endif
- if (retain_time_flag)
- set_file_times (fd, header->c_name, header->c_mtime, header->c_mtime);
-}
-
-void
-set_file_times (int fd,
- const char *name, unsigned long atime, unsigned long mtime)
-{
- struct timespec ts[2];
-
- memset (&ts, 0, sizeof ts);
-
- ts[0].tv_sec = atime;
- ts[1].tv_sec = mtime;
-
- /* Silently ignore EROFS because reading the file won't have upset its
- timestamp if it's on a read-only filesystem. */
- if (gl_futimens (fd, name, ts) < 0 && errno != EROFS)
- utime_error (name);
-}
-
-/* Do we have to ignore absolute paths, and if so, does the filename
- have an absolute path? */
-void
-cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names,
- bool strip_leading_dots)
-{
- char *p = safer_name_suffix (name, link_target, absolute_names);
- if (strip_leading_dots && strcmp (p, "./"))
- /* strip leading `./' from the filename. */
- while (*p == '.' && *(p + 1) == '/')
- {
- ++p;
- while (*p == '/')
- ++p;
- }
- if (p != name)
- memmove (name, p, (size_t)(strlen (p) + 1));
-}
-
diff --git a/contrib/gcc/config/mips/freebsd.h b/contrib/gcc/config/mips/freebsd.h
index 6627e03..35159ab 100644
--- a/contrib/gcc/config/mips/freebsd.h
+++ b/contrib/gcc/config/mips/freebsd.h
@@ -65,19 +65,23 @@ Boston, MA 02110-1301, USA. */
#undef LINK_SPEC
#define LINK_SPEC "\
- %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \
+ %{EB} %{EL} %(endian_spec) \
+ %{G*} %{mips1} %{mips2} %{mips3} %{mips4} \
+ %{mips32} %{mips32r2} %{mips64} %{mips64r2} \
%{bestGnum} %{call_shared} %{no_archive} %{exact_version} \
- %(fbsd_link_spec) "
-#if 0
- %(endian_spec)
-#endif
+ %{mabi=32:-melf32%{EB:b}%{EL:l}tsmip_fbsd} \
+ %{mabi=n32:-melf32%{EB:b}%{EL:l}tsmipn32_fbsd} \
+ %{mabi=64:-melf64%{EB:b}%{EL:l}tsmip_fbsd} \
+ %{mabi=o64:-melf64%{EB:b}%{EL:l}tsmip_fbsd} \
+ %(fbsd_link_spec)"
+
/* Reset our STARTFILE_SPEC which was properly set in config/freebsd.h
but trashed by config/mips/elf.h. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC FBSD_STARTFILE_SPEC
-/* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386. */
+/* Provide an ENDFILE_SPEC appropriate for FreeBSD/mips. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC FBSD_ENDFILE_SPEC
@@ -187,31 +191,47 @@ Boston, MA 02110-1301, USA. */
MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \
\
if (ISA_MIPS1) \
- builtin_define ("__mips=1"); \
+ { \
+ builtin_define ("__mips=1"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS1"); \
+ } \
else if (ISA_MIPS2) \
- builtin_define ("__mips=2"); \
+ { \
+ builtin_define ("__mips=2"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS2"); \
+ } \
else if (ISA_MIPS3) \
- builtin_define ("__mips=3"); \
+ { \
+ builtin_define ("__mips=3"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS3"); \
+ } \
else if (ISA_MIPS4) \
- builtin_define ("__mips=4"); \
+ { \
+ builtin_define ("__mips=4"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS4"); \
+ } \
else if (ISA_MIPS32) \
{ \
builtin_define ("__mips=32"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \
builtin_define ("__mips_isa_rev=1"); \
} \
else if (ISA_MIPS32R2) \
{ \
builtin_define ("__mips=32"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \
builtin_define ("__mips_isa_rev=2"); \
} \
else if (ISA_MIPS64) \
{ \
builtin_define ("__mips=64"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \
builtin_define ("__mips_isa_rev=1"); \
} \
/* else if (ISA_MIPS64R2) \
{ \
builtin_define ("__mips=64"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \
builtin_define ("__mips_isa_rev=2"); \
} \
*/ \
@@ -234,12 +254,28 @@ Boston, MA 02110-1301, USA. */
} \
while (0)
-/* Default to the mips32 ISA */
-#undef DRIVER_SELF_SPECS
+/* Default ABI and ISA */
+#undef DRIVER_SELF_SPECS
+#if MIPS_ABI_DEFAULT == ABI_N32
#define DRIVER_SELF_SPECS \
- "%{!march=*: -march=mips32}"
-#if 0
- "%{!EB:%{!EL:%(endian_spec)}}",
+ "%{!EB:%{!EL:%(endian_spec)}}", \
+ "%{!march=*: -march=mips64}", \
+ "%{!mabi=*: -mabi=n32}"
+#elif MIPS_ABI_DEFAULT == ABI_64
+#define DRIVER_SELF_SPECS \
+ "%{!EB:%{!EL:%(endian_spec)}}", \
+ "%{!march=*: -march=mips64}", \
+ "%{!mabi=*: -mabi=64}"
+#elif MIPS_ABI_DEFAULT == ABI_O64
+#define DRIVER_SELF_SPECS \
+ "%{!EB:%{!EL:%(endian_spec)}}", \
+ "%{!march=*: -march=mips64}", \
+ "%{!mabi=*: -mabi=o64}"
+#else /* default to o32 */
+#define DRIVER_SELF_SPECS \
+ "%{!EB:%{!EL:%(endian_spec)}}", \
+ "%{!march=*: -march=mips32}", \
+ "%{!mabi=*: -mabi=32}"
#endif
#if 0
diff --git a/contrib/ipfilter/ipsend/sbpf.c b/contrib/ipfilter/ipsend/sbpf.c
index 9a5cc2e..2b356b6 100644
--- a/contrib/ipfilter/ipsend/sbpf.c
+++ b/contrib/ipfilter/ipsend/sbpf.c
@@ -9,7 +9,6 @@
#include <sys/types.h>
#include <sys/mbuf.h>
#include <sys/time.h>
-#include <sys/timeb.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
diff --git a/contrib/netcat/FREEBSD-upgrade b/contrib/netcat/FREEBSD-upgrade
index 5a52ebc..33f5ea2 100644
--- a/contrib/netcat/FREEBSD-upgrade
+++ b/contrib/netcat/FREEBSD-upgrade
@@ -1,19 +1,14 @@
$FreeBSD$
-1. Export from OpenBSD's nc(1) into an empty directory (say "v-nc").
-2. while read pattern; do rm ${pattern} ; done < FREEBSD-Xlist
-3. Checkout our contrib/netcat to another directory (say "f-nc"),
- with -rOPENBSD, and usr.bin/nc to its ../../
-4. copy the files from v-nc to f-nc
-5. do cvs up -A in f-nc
-6. If there is conflicits, try to resolve them.
-7. do build in f-nc/../../usr.bin/nc
-8. If everything seems ok, do the actual import in v-nc:
- cvs -n import src/contrib/netcat OPENBSD OPENBSD_<release>
- Everything appears be Ok? Do:
- cvs import src/contrib/netcat OPENBSD OPENBSD_<release>
- (note: recently we import from OpenBSD's release branches
- rather than importing -HEAD snapshots)
-9. Resolve the conflicits with the patchset obtained in step 6.
+Most of the instructions is outlined on FreeBSD wiki at:
-delphij@FreeBSD.org - 21 Apr 2008
+ http://wiki.freebsd.org/SubversionPrimer/VendorImports
+
+nc(1) is very small and most of code are just copied as-is from OpenBSD. With a
+few exceptions:
+
+ * --no-tcpopt: Local feature specific to FreeBSD.
+ * -V: We use FIB to map what OpenBSD do for "rdomain"
+ * -E, -e: These are mostly self contained IPsec extensions
+
+delphij@FreeBSD.org - Mar 23, 2010
diff --git a/contrib/netcat/FREEBSD-vendor b/contrib/netcat/FREEBSD-vendor
index c808f5b..f540175 100644
--- a/contrib/netcat/FREEBSD-vendor
+++ b/contrib/netcat/FREEBSD-vendor
@@ -1,5 +1,5 @@
# $FreeBSD$
Project: netcat (aka src/usr.bin/nc in OpenBSD)
ProjectURL: http://www.openbsd.org/
-Version: 4.6
+Version: 4.7
License: BSD
diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1
index 4375ae8..ac6aa47 100644
--- a/contrib/netcat/nc.1
+++ b/contrib/netcat/nc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: nc.1,v 1.50 2009/06/05 06:47:12 jmc Exp $
+.\" $OpenBSD: nc.1,v 1.53 2010/02/23 23:00:52 schwarze Exp $
.\"
.\" Copyright (c) 1996 David Sacerdote
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 5 2009
+.Dd April 15, 2010
.Dt NC 1
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Sh SYNOPSIS
.Nm nc
.Bk -words
-.Op Fl 46DdEhklnorStUuvz
+.Op Fl 46DdEhklnrStUuvz
.Op Fl e Ar IPsec_policy
.Op Fl I Ar length
.Op Fl i Ar interval
@@ -51,8 +51,8 @@
.Op Fl X Ar proxy_protocol
.Oo Xo
.Fl x Ar proxy_address Ns Oo : Ns
-.Ar port Oc Oc
-.Xc
+.Ar port Oc
+.Xc Oc
.Op Ar hostname
.Op Ar port
.Ek
@@ -159,15 +159,6 @@ socket option.
.It Fl O Ar length
Specifies the size of the TCP send buffer.
When
-.It Fl o
-.Dq Once-only mode .
-By default,
-.Nm
-does not terminate on EOF condition on input,
-but continues until the network side has been closed down.
-Specifying
-.Fl o
-will make it terminate on EOF as well.
.It Fl P Ar proxy_username
Specifies a username to present to a proxy server that requires authentication.
If no username is specified then authentication will not be attempted.
@@ -206,7 +197,9 @@ This makes it possible to use
.Nm
to script telnet sessions.
.It Fl U
-Specifies to use Unix Domain Sockets.
+Specifies to use
+.Ux Ns -domain
+sockets.
.It Fl u
Use UDP instead of the default option of TCP.
.It Fl V Ar fib
@@ -428,7 +421,9 @@ outgoing traffic only.
.Pp
.Dl $ nc -e 'out ipsec esp/transport//require' host.example.com 42
.Pp
-Create and listen on a Unix Domain Socket:
+Create and listen on a
+.Ux Ns -domain
+socket:
.Pp
.Dl $ nc -lU /var/tmp/dsocket
.Pp
diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c
index a9ce18b..28a9823 100644
--- a/contrib/netcat/netcat.c
+++ b/contrib/netcat/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.93 2009/06/05 00:18:10 claudio Exp $ */
+/* $OpenBSD: netcat.c,v 1.95 2010/02/27 00:58:56 nicm Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
@@ -72,14 +72,12 @@
#define PORT_MAX_LEN 6
/* Command Line Options */
-int Eflag; /* Use IPsec ESP */
int dflag; /* detached, no stdin */
unsigned int iflag; /* Interval Flag */
int jflag; /* use jumbo frames if we can */
int kflag; /* More than one connect */
int lflag; /* Bind to local port */
int nflag; /* Don't do name look up */
-int oflag; /* Once only: stop on EOF */
int FreeBSD_Oflag; /* Do not use TCP options */
char *Pflag; /* Proxy username */
char *pflag; /* Localport flag */
@@ -151,7 +149,7 @@ main(int argc, char *argv[])
sv = NULL;
while ((ch = getopt_long(argc, argv,
- "46DdEe:hI:i:jklnO:oP:p:rSs:tT:UuV:vw:X:x:z",
+ "46DdEe:hI:i:jklnoO:P:p:rSs:tT:UuV:vw:X:x:z",
longopts, NULL)) != -1) {
switch (ch) {
case '4':
@@ -214,7 +212,7 @@ main(int argc, char *argv[])
nflag = 1;
break;
case 'o':
- oflag = 1;
+ fprintf(stderr, "option -o is deprecated.\n");
break;
case 'P':
Pflag = optarg;
@@ -282,8 +280,6 @@ main(int argc, char *argv[])
case 'T':
Tflag = parse_iptos(optarg);
break;
- case 0:
- break;
default:
usage(1);
}
@@ -455,8 +451,10 @@ main(int argc, char *argv[])
uflag ? "udp" : "tcp");
}
- printf("Connection to %s %s port [%s/%s] succeeded!\n",
- host, portlist[i], uflag ? "udp" : "tcp",
+ fprintf(stderr,
+ "Connection to %s %s port [%s/%s] "
+ "succeeded!\n", host, portlist[i],
+ uflag ? "udp" : "tcp",
sv ? sv->s_name : "*");
}
if (!zflag)
@@ -572,10 +570,8 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
if (sflag || pflag) {
struct addrinfo ahints, *ares;
-#ifdef SO_BINDANY
- /* try SO_BINDANY, but don't insist */
- setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on));
-#endif
+ /* try IP_BINDANY, but don't insist */
+ setsockopt(s, IPPROTO_IP, IP_BINDANY, &on, sizeof(on));
memset(&ahints, 0, sizeof(struct addrinfo));
ahints.ai_family = res0->ai_family;
ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
@@ -727,10 +723,9 @@ readwrite(int nfd)
}
if (!dflag && pfd[1].revents & POLLIN) {
- if ((n = read(wfd, buf, plen)) < 0 ||
- (oflag && n == 0)) {
+ if ((n = read(wfd, buf, plen)) < 0)
return;
- } else if (n == 0) {
+ else if (n == 0) {
shutdown(nfd, SHUT_WR);
pfd[1].fd = -1;
pfd[1].events = 0;
@@ -749,27 +744,27 @@ atelnet(int nfd, unsigned char *buf, unsigned int size)
unsigned char *p, *end;
unsigned char obuf[4];
- end = buf + size;
- obuf[0] = '\0';
+ if (size < 3)
+ return;
+ end = buf + size - 2;
for (p = buf; p < end; p++) {
if (*p != IAC)
- break;
+ continue;
obuf[0] = IAC;
p++;
if ((*p == WILL) || (*p == WONT))
obuf[1] = DONT;
- if ((*p == DO) || (*p == DONT))
+ else if ((*p == DO) || (*p == DONT))
obuf[1] = WONT;
- if (obuf) {
- p++;
- obuf[2] = *p;
- obuf[3] = '\0';
- if (atomicio(vwrite, nfd, obuf, 3) != 3)
- warn("Write Error!");
- obuf[0] = '\0';
- }
+ else
+ continue;
+
+ p++;
+ obuf[2] = *p;
+ if (atomicio(vwrite, nfd, obuf, 3) != 3)
+ warn("Write Error!");
}
}
@@ -943,7 +938,6 @@ help(void)
\t-n Suppress name/port resolutions\n\
\t--no-tcpopt Disable TCP options\n\
\t-O length TCP send buffer length\n\
- \t-o Terminate on EOF on input\n\
\t-P proxyuser\tUsername for proxy authentication\n\
\t-p port\t Specify local port for remote connects\n\
\t-r Randomize remote ports\n\
@@ -993,9 +987,9 @@ usage(int ret)
{
fprintf(stderr,
#ifdef IPSEC
- "usage: nc [-46DdEhklnorStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n"
+ "usage: nc [-46DdEhklnrStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n"
#else
- "usage: nc [-46DdhklnorStUuvz] [-I length] [-i interval] [-O length]\n"
+ "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n"
#endif
"\t [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n"
"\t [-V fib] [-w timeout] [-X proxy_protocol]\n"
diff --git a/contrib/openpam/include/security/pam_appl.h b/contrib/openpam/include/security/pam_appl.h
index 8316c68..131c2f9 100644
--- a/contrib/openpam/include/security/pam_appl.h
+++ b/contrib/openpam/include/security/pam_appl.h
@@ -72,8 +72,7 @@ pam_close_session(pam_handle_t *_pamh,
int
pam_end(pam_handle_t *_pamh,
- int _status)
- OPENPAM_NONNULL((1));
+ int _status);
int
pam_get_data(const pam_handle_t *_pamh,
diff --git a/contrib/top/utils.c b/contrib/top/utils.c
index 906170a..43072b1 100644
--- a/contrib/top/utils.c
+++ b/contrib/top/utils.c
@@ -476,7 +476,7 @@ int amt;
char *format_k2(amt)
-int amt;
+unsigned long long amt;
{
static char retarray[NUM_STRINGS][16];
@@ -499,7 +499,7 @@ int amt;
}
}
- p = strecpy(p, itoa(amt));
+ p = strecpy(p, itoa((int)amt));
*p++ = tag;
*p = '\0';
diff --git a/contrib/top/utils.h b/contrib/top/utils.h
index 6717092..12a6c76 100644
--- a/contrib/top/utils.h
+++ b/contrib/top/utils.h
@@ -21,4 +21,4 @@ long percentages();
char *errmsg();
char *format_time();
char *format_k();
-char *format_k2();
+char *format_k2(unsigned long long);
diff --git a/contrib/tzdata/africa b/contrib/tzdata/africa
index ad89bb7..8cae7a6 100644
--- a/contrib/tzdata/africa
+++ b/contrib/tzdata/africa
@@ -1,5 +1,5 @@
# <pre>
-# @(#)africa 8.23
+# @(#)africa 8.26
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -680,6 +680,21 @@ Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou
# http://www.worldtimezone.com/dst_news/dst_news_morocco03.html
# </a>
+# From Steffen Thorsen (2010-04-13):
+# Several news media in Morocco report that the Ministry of Modernization
+# of Public Sectors has announced that Morocco will have DST from
+# 2010-05-02 to 2010-08-08.
+#
+# Example:
+# <a href="http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html">
+# http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html
+# </a>
+# (French)
+# Our page:
+# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html">
+# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html
+# </a>
+
# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Morocco 1939 only - Sep 12 0:00 1:00 S
@@ -701,6 +716,8 @@ Rule Morocco 2008 only - Jun 1 0:00 1:00 S
Rule Morocco 2008 only - Sep 1 0:00 0 -
Rule Morocco 2009 only - Jun 1 0:00 1:00 S
Rule Morocco 2009 only - Aug 21 0:00 0 -
+Rule Morocco 2010 only - May 2 0:00 1:00 S
+Rule Morocco 2010 only - Aug 8 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
0:00 Morocco WE%sT 1984 Mar 16
@@ -942,6 +959,24 @@ Zone Africa/Lome 0:04:52 - LMT 1893
# Therefore, the standard time will be kept unchanged the whole year long."
# So foregoing DST seems to be an exception (albeit one that may be repeated in the future).
+# From Alexander Krivenyshev (2010-03-27):
+# According to some news reports Tunis confirmed not to use DST in 2010
+#
+# (translation):
+# "The Tunisian government has decided to abandon DST, which was scheduled on
+# Sunday...
+# Tunisian authorities had suspended the DST for the first time last year also
+# coincided with the month of Ramadan..."
+#
+# (in Arabic)
+# <a href="http://www.moheet.com/show_news.aspx?nid=358861&pg=1">
+# http://www.moheet.com/show_news.aspx?nid=358861&pg=1
+# <a href="http://www.almadenahnews.com/newss/news.php?c=118&id=38036">
+# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_tunis02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Tunisia 1939 only - Apr 15 23:00s 1:00 S
Rule Tunisia 1939 only - Nov 18 23:00s 0 -
@@ -968,8 +1003,7 @@ Rule Tunisia 2005 only - May 1 0:00s 1:00 S
Rule Tunisia 2005 only - Sep 30 1:00s 0 -
Rule Tunisia 2006 2008 - Mar lastSun 2:00s 1:00 S
Rule Tunisia 2006 2008 - Oct lastSun 2:00s 0 -
-Rule Tunisia 2010 max - Mar lastSun 2:00s 1:00 S
-Rule Tunisia 2010 max - Oct lastSun 2:00s 0 -
+
# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
# more precise 0:09:21.
# Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
diff --git a/contrib/tzdata/antarctica b/contrib/tzdata/antarctica
index f18ae95..629b2d7 100644
--- a/contrib/tzdata/antarctica
+++ b/contrib/tzdata/antarctica
@@ -1,5 +1,5 @@
# <pre>
-# @(#)antarctica 8.7
+# @(#)antarctica 8.8
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -57,6 +57,33 @@ Rule ChileAQ 1999 only - Apr 4 3:00u 0 -
Rule ChileAQ 1999 max - Oct Sun>=9 4:00u 1:00 S
Rule ChileAQ 2000 max - Mar Sun>=9 3:00u 0 -
+# These rules are stolen from the `australasia' file.
+Rule AusAQ 1917 only - Jan 1 0:01 1:00 -
+Rule AusAQ 1917 only - Mar 25 2:00 0 -
+Rule AusAQ 1942 only - Jan 1 2:00 1:00 -
+Rule AusAQ 1942 only - Mar 29 2:00 0 -
+Rule AusAQ 1942 only - Sep 27 2:00 1:00 -
+Rule AusAQ 1943 1944 - Mar lastSun 2:00 0 -
+Rule AusAQ 1943 only - Oct 3 2:00 1:00 -
+Rule ATAQ 1967 only - Oct Sun>=1 2:00s 1:00 -
+Rule ATAQ 1968 only - Mar lastSun 2:00s 0 -
+Rule ATAQ 1968 1985 - Oct lastSun 2:00s 1:00 -
+Rule ATAQ 1969 1971 - Mar Sun>=8 2:00s 0 -
+Rule ATAQ 1972 only - Feb lastSun 2:00s 0 -
+Rule ATAQ 1973 1981 - Mar Sun>=1 2:00s 0 -
+Rule ATAQ 1982 1983 - Mar lastSun 2:00s 0 -
+Rule ATAQ 1984 1986 - Mar Sun>=1 2:00s 0 -
+Rule ATAQ 1986 only - Oct Sun>=15 2:00s 1:00 -
+Rule ATAQ 1987 1990 - Mar Sun>=15 2:00s 0 -
+Rule ATAQ 1987 only - Oct Sun>=22 2:00s 1:00 -
+Rule ATAQ 1988 1990 - Oct lastSun 2:00s 1:00 -
+Rule ATAQ 1991 1999 - Oct Sun>=1 2:00s 1:00 -
+Rule ATAQ 1991 2005 - Mar lastSun 2:00s 0 -
+Rule ATAQ 2000 only - Aug lastSun 2:00s 1:00 -
+Rule ATAQ 2001 max - Oct Sun>=1 2:00s 1:00 -
+Rule ATAQ 2006 only - Apr Sun>=1 2:00s 0 -
+Rule ATAQ 2007 only - Mar lastSun 2:00s 0 -
+Rule ATAQ 2008 max - Apr Sun>=1 2:00s 0 -
# Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -98,20 +125,52 @@ Rule ChileAQ 2000 max - Mar Sun>=9 3:00u 0 -
# http://www.timeanddate.com/news/time/antarctica-new-times.html
# </a>
+# From Steffen Thorsen (2010-03-10):
+# We got these changes from the Australian Antarctic Division:
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
+# switch back from daylight savings time when other parts of Australia do
+# on 4 April.
+#
+# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
+# The change to UTC+11 is being considered as a regular summer thing but
+# has not been decided yet.
+#
+# - Davis station will revert to its normal time of UTC+7 at 10 March 2010
+# 20:00 UTC.
+#
+# - Mawson station stays on UTC+5.
+#
+# In addition to the Rule changes for Casey/Davis, it means that Macquarie
+# will no longer be like Hobart and will have to have its own Zone created.
+#
+# Background:
+# <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
+# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
+# </a>
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - zzz 1969
8:00 - WST 2009 Oct 18 2:00
# Western (Aus) Standard Time
- 11:00 - CAST # Casey Time
+ 11:00 - CAST 2010 Mar 5 2:00
+ # Casey Time
+ 8:00 - WST
Zone Antarctica/Davis 0 - zzz 1957 Jan 13
7:00 - DAVT 1964 Nov # Davis Time
0 - zzz 1969 Feb
7:00 - DAVT 2009 Oct 18 2:00
- 5:00 - DAVT
+ 5:00 - DAVT 2010 Mar 10 20:00u
+ 7:00 - DAVT
Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
6:00 - MAWT 2009 Oct 18 2:00
# Mawson Time
5:00 - MAWT
+Zone Antarctica/Macquarie 0 - zzz 1911
+ 10:00 - EST 1916 Oct 1 2:00
+ 10:00 1:00 EST 1917 Feb
+ 10:00 AusAQ EST 1967
+ 10:00 ATAQ EST 2010 Apr 4 3:00
+ 11:00 - MIST # Macquarie Island Time
# References:
# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
# Casey Weather (1998-02-26)
diff --git a/contrib/tzdata/asia b/contrib/tzdata/asia
index e9780ac..78ff2ff 100644
--- a/contrib/tzdata/asia
+++ b/contrib/tzdata/asia
@@ -1,4 +1,4 @@
-# @(#)asia 8.51
+# @(#)asia 8.60
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -214,22 +214,20 @@ Zone Asia/Bahrain 3:22:20 - LMT 1920 # Al Manamah
# 2010 midnight. The decision came at a cabinet meeting at the Prime
# Minister's Office last night..."
-# From Danvin Ruangchan (2009-12-24):
-# ...the news mentions DST will be turned off again 7 months after March
-# 31st on Oct 31, 2010.
-
-# From Arthur David Olson (2009-12-26):
-# Indeed, "The government will advance again the Banglasdesh Standard
-# Time by one one hour on March 31 next year by enforcing the Daylight
-# Saving Time (DST) for seven months. It will continue till October 31
-# until further notice." I take that last sentence as the
-# establishment of a rule.
+# From Alexander Krivenyshev (2010-03-22):
+# According to Bangladesh newspaper "The Daily Star,"
+# Cabinet cancels Daylight Saving Time
+# <a href="http://www.thedailystar.net/newDesign/latest_news.php?nid=22817">
+# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html
+# </a>
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Dhaka 2009 only - Jun 19 23:00 1:00 S
-Rule Dhaka 2010 only - Jan 1 0:00 0 -
-Rule Dhaka 2010 max - Mar 31 23:00 1:00 S
-Rule Dhaka 2010 max - Nov 1 0:00 0 -
+Rule Dhaka 2009 only - Dec 31 23:59 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Dhaka 6:01:40 - LMT 1890
@@ -568,6 +566,28 @@ Zone Asia/Hong_Kong 7:36:36 - LMT 1904 Oct 30
# was still controlled by Japan. This is hard to believe, but we don't
# have any other information.
+# From smallufo (2010-04-03):
+# According to Taiwan's CWB,
+# <a href="http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm">
+# http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm
+# </a>
+# Taipei has DST in 1979 between July 1st and Sep 30.
+
+# From Arthur David Olson (2010-04-07):
+# Here's Google's translation of the table at the bottom of the "summert.htm" page:
+# Decade Name Start and end date
+# Republic of China 34 years to 40 years (AD 1945-1951 years) Summer Time May 1 to September 30
+# 41 years of the Republic of China (AD 1952) Daylight Saving Time March 1 to October 31
+# Republic of China 42 years to 43 years (AD 1953-1954 years) Daylight Saving Time April 1 to October 31
+# In the 44 years to 45 years (AD 1955-1956 years) Daylight Saving Time April 1 to September 30
+# Republic of China 46 years to 48 years (AD 1957-1959) Summer Time April 1 to September 30
+# Republic of China 49 years to 50 years (AD 1960-1961) Summer Time June 1 to September 30
+# Republic of China 51 years to 62 years (AD 1962-1973 years) Stop Summer Time
+# Republic of China 63 years to 64 years (1974-1975 AD) Daylight Saving Time April 1 to September 30
+# Republic of China 65 years to 67 years (1976-1978 AD) Stop Daylight Saving Time
+# Republic of China 68 years (AD 1979) Daylight Saving Time July 1 to September 30
+# Republic of China since 69 years (AD 1980) Stop Daylight Saving Time
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Taiwan 1945 1951 - May 1 0:00 1:00 D
Rule Taiwan 1945 1951 - Oct 1 0:00 0 S
@@ -578,8 +598,9 @@ Rule Taiwan 1955 1961 - Oct 1 0:00 0 S
Rule Taiwan 1960 1961 - Jun 1 0:00 1:00 D
Rule Taiwan 1974 1975 - Apr 1 0:00 1:00 D
Rule Taiwan 1974 1975 - Oct 1 0:00 0 S
-Rule Taiwan 1980 only - Jun 30 0:00 1:00 D
-Rule Taiwan 1980 only - Sep 30 0:00 0 S
+Rule Taiwan 1979 only - Jun 30 0:00 1:00 D
+Rule Taiwan 1979 only - Sep 30 0:00 0 S
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Taipei 8:06:00 - LMT 1896 # or Taibei or T'ai-pei
8:00 Taiwan C%sT
@@ -1914,13 +1935,35 @@ Zone Asia/Muscat 3:54:20 - LMT 1920
# [T]he German Consulate General in Karachi reported me today that Pakistan
# will go back to standard time on 1st of November.
+# From Steffen Thorsen (2010-03-26):
+# Steffen Thorsen wrote:
+# > On Thursday (2010-03-25) it was announced that DST would start in
+# > Pakistan on 2010-04-01.
+# >
+# > Then today, the president said that they might have to revert the
+# > decision if it is not supported by the parliament. So at the time
+# > being, it seems unclear if DST will be actually observed or not - but
+# > April 1 could be a more likely date than April 15.
+# Now, it seems that the decision to not observe DST in final:
+#
+# "Govt Withdraws Plan To Advance Clocks"
+# <a href="http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041">
+# http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041
+# </a>
+#
+# "People laud PM's announcement to end DST"
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2">
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
+# </a>
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Pakistan 2002 only - Apr Sun>=2 0:01 1:00 S
Rule Pakistan 2002 only - Oct Sun>=2 0:01 0 -
Rule Pakistan 2008 only - Jun 1 0:00 1:00 S
Rule Pakistan 2008 only - Nov 1 0:00 0 -
-Rule Pakistan 2009 max - Apr 15 0:00 1:00 S
-Rule Pakistan 2009 max - Nov 1 0:00 0 -
+Rule Pakistan 2009 only - Apr 15 0:00 1:00 S
+Rule Pakistan 2009 only - Nov 1 0:00 0 -
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Karachi 4:28:12 - LMT 1907
5:30 - IST 1942 Sep
@@ -2109,6 +2152,32 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
# </a>
+# From Alexander Krivenyshev (2010-03-19):
+# According to Voice of Palestine DST will last for 191 days, from March
+# 26, 2010 till "the last Sunday before the tenth day of Tishri
+# (October), each year" (October 03, 2010?)
+#
+# <a href="http://palvoice.org/forums/showthread.php?t=245697">
+# http://palvoice.org/forums/showthread.php?t=245697
+# </a>
+# (in Arabic)
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_westbank03.html
+# </a>
+
+# From Steffen Thorsen (2010-03-24):
+# ...Ma'an News Agency reports that Hamas cabinet has decided it will
+# start one day later, at 12:01am. Not sure if they really mean 12:01am or
+# noon though:
+#
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=271178">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=271178
+# </a>
+# (Ma'an News Agency)
+# "At 12:01am Friday, clocks in Israel and the West Bank will change to
+# 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
+
# The rules for Egypt are stolen from the `africa' file.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2126,7 +2195,8 @@ Rule Palestine 2006 2008 - Apr 1 0:00 1:00 S
Rule Palestine 2006 only - Sep 22 0:00 0 -
Rule Palestine 2007 only - Sep Thu>=8 2:00 0 -
Rule Palestine 2008 only - Aug lastFri 2:00 0 -
-Rule Palestine 2009 max - Mar lastFri 0:00 1:00 S
+Rule Palestine 2009 only - Mar lastFri 0:00 1:00 S
+Rule Palestine 2010 max - Mar lastSat 0:01 1:00 S
Rule Palestine 2009 max - Sep Fri>=1 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -2418,9 +2488,18 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 -
# Thursday of the month or the start of the last Friday of the month or
# something else. For now, use the start of the last Friday.
+# From Steffen Thorsen (2010-03-17):
+# The "Syrian News Station" reported on 2010-03-16 that the Council of
+# Ministers has decided that Syria will start DST on midnight Thursday
+# 2010-04-01: (midnight between Thursday and Friday):
+# <a href="http://sns.sy/sns/?path=news/read/11421">
+# http://sns.sy/sns/?path=news/read/11421 (Arabic)
+# </a>
+
Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S
Rule Syria 2008 only - Nov 1 0:00 0 -
-Rule Syria 2009 max - Mar lastFri 0:00 1:00 S
+Rule Syria 2009 only - Mar lastFri 0:00 1:00 S
+Rule Syria 2010 max - Apr Fri>=1 0:00 1:00 S
Rule Syria 2009 max - Oct lastFri 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
diff --git a/contrib/tzdata/australasia b/contrib/tzdata/australasia
index 3812390..9884b67 100644
--- a/contrib/tzdata/australasia
+++ b/contrib/tzdata/australasia
@@ -1,5 +1,5 @@
# <pre>
-# @(#)australasia 8.15
+# @(#)australasia 8.17
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -267,11 +267,30 @@ Zone Indian/Cocos 6:27:40 - LMT 1900
# <a href="http://www.fiji.gov.fj/publish/page_16198.shtml">
# http://www.fiji.gov.fj/publish/page_16198.shtml
# </a>
+
+# From Steffen Thorsen (2010-03-03):
+# The Cabinet in Fiji has decided to end DST about a month early, on
+# 2010-03-28 at 03:00.
+# The plan is to observe DST again, from 2010-10-24 to sometime in March
+# 2011 (last Sunday a good guess?).
+#
+# Official source:
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166">
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166
+# </a>
+#
+# A bit more background info here:
+# <a href="http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html">
+# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
+# </a>
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S
Rule Fiji 1999 2000 - Feb lastSun 3:00 0 -
Rule Fiji 2009 only - Nov 29 2:00 1:00 S
-Rule Fiji 2010 only - Apr 25 3:00 0 -
+Rule Fiji 2010 only - Mar lastSun 3:00 0 -
+Rule Fiji 2010 only - Oct 24 2:00 1:00 S
+Rule Fiji 2011 only - Mar lastSun 3:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Fiji 11:53:40 - LMT 1915 Oct 26 # Suva
12:00 Fiji FJ%sT # Fiji Time
@@ -449,70 +468,30 @@ Zone Pacific/Pago_Pago 12:37:12 - LMT 1879 Jul 5
# Samoa
-# From Alexander Krivenyshev (2008-12-06):
-# The Samoa government (Western Samoa) may implement DST on the first Sunday of
-# October 2009 (October 4, 2009) until the last Sunday of March 2010 (March 28,
-# 2010).
-#
-# "Selected Committee reports to Cabinet on Daylight Saving Time",
-# Government of Samoa:
-# <a href="http://www.govt.ws/pr_article.cfm?pr_id=560">
-# http://www.govt.ws/pr_article.cfm?pr_id=560
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_samoa01.html">
-# http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
-# </a>
-
-# From Steffen Thorsen (2009-08-27):
-# Samoa's parliament passed the Daylight Saving Bill 2009, and will start
-# daylight saving time on the first Sunday of October 2009 and end on the
-# last Sunday of March 2010. We hope that the full text will be published
-# soon, but we believe that the bill is only valid for 2009-2010. Samoa's
-# Daylight Saving Act 2009 will be enforced as soon as the Head of State
-# executes a proclamation publicizing this Act.
+# From Steffen Thorsen (2009-10-16):
+# We have been in contact with the government of Samoa again, and received
+# the following info:
+#
+# "Cabinet has now approved Daylight Saving to be effected next year
+# commencing from the last Sunday of September 2010 and conclude first
+# Sunday of April 2011."
#
-# Some background information here, which will be updated once we have
-# more details:
+# Background info:
# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
# </a>
-
-# From Alexander Krivenyshev (2009-10-03):
-# First, my deepest condolences to people of Samoa islands and all families and
-# loved ones around the world who lost their lives in the earthquake and tsunami.
-#
-# Considering the recent devastation on Samoa by earthquake and tsunami and that
-# many government offices/ ministers are closed- not sure if "Daylight Saving
-# Bill 2009" will be implemented in next few days- on October 4, 2009.
-#
-# Here is reply from Consulate-General of Samoa in New Zealand
-# ---------------------------
-# Consul General
-# consulgeneral@samoaconsulate.org.nz
#
-# Talofa Alexander,
-#
-# Thank you for your sympathy for our country but at this time we have not
-# been informed about the Daylight Savings Time Change. Most Ministries in
-# Apia are closed or relocating due to weather concerns.
-#
-# When we do find out if they are still proceeding with the time change we
-# will advise you soonest.
-#
-# Kind Regards,
-# Lana
-# for: Consul General
-
-# From Steffen Thorsen (2009-10-05):
-# We have called a hotel in Samoa and asked about local time there - they
-# are still on standard time.
+# Samoa's Daylight Saving Time Act 2009 is available here, but does not
+# contain any dates:
+# <a href="http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf">
+# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
+# </a>
Zone Pacific/Apia 12:33:04 - LMT 1879 Jul 5
-11:26:56 - LMT 1911
-11:30 - SAMT 1950 # Samoa Time
- -11:00 - WST 2009 Oct 4
- -11:00 1:00 WSDT 2010 Mar 28
+ -11:00 - WST 2010 Sep 26
+ -11:00 1:00 WSDT 2011 Apr 3
-11:00 - WST
# Solomon Is
diff --git a/contrib/tzdata/europe b/contrib/tzdata/europe
index 05e3cae..aca3a0b 100644
--- a/contrib/tzdata/europe
+++ b/contrib/tzdata/europe
@@ -1,5 +1,5 @@
# <pre>
-# @(#)europe 8.25
+# @(#)europe 8.26
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -2041,7 +2041,9 @@ Zone Europe/Samara 3:20:36 - LMT 1919 Jul 1 2:00
3:00 Russia KUY%sT 1991 Mar 31 2:00s
2:00 Russia KUY%sT 1991 Sep 29 2:00s
3:00 - KUYT 1991 Oct 20 3:00
- 4:00 Russia SAM%sT # Samara Time
+ 4:00 Russia SAM%sT 2010 Mar 28 2:00s # Samara Time
+ 3:00 Russia SAM%sT
+
#
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
# Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
@@ -2194,7 +2196,8 @@ Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10
11:00 - PETT 1930 Jun 21 # P-K Time
12:00 Russia PET%sT 1991 Mar 31 2:00s
11:00 Russia PET%sT 1992 Jan 19 2:00s
- 12:00 Russia PET%sT
+ 12:00 Russia PET%sT 2010 Mar 28 2:00s
+ 11:00 Russia PET%sT
#
# Chukotskij avtonomnyj okrug
Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
@@ -2202,7 +2205,8 @@ Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
13:00 Russia ANA%sT 1982 Apr 1 0:00s
12:00 Russia ANA%sT 1991 Mar 31 2:00s
11:00 Russia ANA%sT 1992 Jan 19 2:00s
- 12:00 Russia ANA%sT
+ 12:00 Russia ANA%sT 2010 Mar 28 2:00s
+ 11:00 Russia ANA%sT
# Serbia
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
diff --git a/contrib/tzdata/southamerica b/contrib/tzdata/southamerica
index 7ad8170..7355022 100644
--- a/contrib/tzdata/southamerica
+++ b/contrib/tzdata/southamerica
@@ -1,5 +1,5 @@
# <pre>
-# @(#)southamerica 8.41
+# @(#)southamerica 8.44
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -437,6 +437,27 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 S
# of the country calls it "ART".
# ...
+# From Alexander Krivenyshev (2010-04-09):
+# According to news reports from El Diario de la Republica Province San
+# Luis, Argentina (standard time UTC-04) will keep Daylight Saving Time
+# after April 11, 2010--will continue to have same time as rest of
+# Argentina (UTC-3) (no DST).
+#
+# Confirmaron la pr&oacute;rroga del huso horario de verano (Spanish)
+# <a href="http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9">
+# http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9
+# </a>
+# or (some English translation):
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina08.html">
+# http://www.worldtimezone.com/dst_news/dst_news_argentina08.html
+# </a>
+
+# From Mariano Absatz (2010-04-12):
+# yes...I can confirm this...and given that San Luis keeps calling
+# UTC-03:00 "summer time", we should't just let San Luis go back to "Arg"
+# rules...San Luis is still using "Western ARgentina Time" and it got
+# stuck on Summer daylight savings time even though the summer is over.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
#
# Buenos Aires (BA), Capital Federal (CF),
@@ -570,8 +591,8 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31
#
# San Luis (SL)
-Rule SanLuis 2008 max - Mar Sun>=8 0:00 0 -
-Rule SanLuis 2007 max - Oct Sun>=8 0:00 1:00 S
+Rule SanLuis 2008 2009 - Mar Sun>=8 0:00 0 -
+Rule SanLuis 2007 2009 - Oct Sun>=8 0:00 1:00 S
Zone America/Argentina/San_Luis -4:25:24 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May
@@ -1121,6 +1142,18 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# http://www.shoa.cl/noticias/2008/04hora/hora.htm
# </a>.
+# From Angel Chiang (2010-03-04):
+# Subject: DST in Chile exceptionally extended to 3 April due to earthquake
+# <a href="http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098">
+# http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098
+# </a>
+# (in Spanish, last paragraph).
+#
+# This is breaking news. There should be more information available later.
+
+# From Arthur Daivd Olson (2010-03-06):
+# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Chile 1927 1932 - Sep 1 0:00 1:00 S
Rule Chile 1928 1932 - Apr 1 0:00 0 -
@@ -1155,7 +1188,9 @@ Rule Chile 2000 2007 - Mar Sun>=9 3:00u 0 -
# N.B.: the end of March 29 in Chile is March 30 in Universal time,
# which is used below in specifying the transition.
Rule Chile 2008 only - Mar 30 3:00u 0 -
-Rule Chile 2009 max - Mar Sun>=9 3:00u 0 -
+Rule Chile 2009 only - Mar Sun>=9 3:00u 0 -
+Rule Chile 2010 only - Apr 4 3:00u 0 -
+Rule Chile 2011 max - Mar Sun>=9 3:00u 0 -
# IATA SSIM anomalies: (1992-02) says 1992-03-14;
# (1996-09) says 1998-03-08. Ignore these.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1380,7 +1415,7 @@ Rule Para 2005 2009 - Mar Sun>=8 0:00 0 -
# and that on the first Sunday of the month of October, it is to be set
# forward 60 minutes, in all the territory of the Paraguayan Republic.
# ...
-Rule Para 2010 max - Oct Sun<=7 0:00 1:00 S
+Rule Para 2010 max - Oct Sun>=1 0:00 1:00 S
Rule Para 2010 max - Apr Sun>=8 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
diff --git a/contrib/tzdata/zone.tab b/contrib/tzdata/zone.tab
index c8fb250..6959c49 100644
--- a/contrib/tzdata/zone.tab
+++ b/contrib/tzdata/zone.tab
@@ -1,5 +1,5 @@
# <pre>
-# @(#)zone.tab 8.33
+# @(#)zone.tab 8.35
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
#
@@ -44,6 +44,7 @@ AQ -6617+11031 Antarctica/Casey Casey Station, Bailey Peninsula
AQ -7824+10654 Antarctica/Vostok Vostok Station, S Magnetic Pole
AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie
AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I
+AQ -5430+15857 Antarctica/Macquarie Macquarie Island Station, Macquarie Island
AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF)
AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN)
@@ -329,7 +330,7 @@ RS +4450+02030 Europe/Belgrade
RU +5443+02030 Europe/Kaliningrad Moscow-01 - Kaliningrad
RU +5545+03735 Europe/Moscow Moscow+00 - west Russia
RU +4844+04425 Europe/Volgograd Moscow+00 - Caspian Sea
-RU +5312+05009 Europe/Samara Moscow+01 - Samara, Udmurtia
+RU +5312+05009 Europe/Samara Moscow - Samara, Udmurtia
RU +5651+06036 Asia/Yekaterinburg Moscow+02 - Urals
RU +5500+07324 Asia/Omsk Moscow+03 - west Siberia
RU +5502+08255 Asia/Novosibirsk Moscow+03 - Novosibirsk
@@ -340,8 +341,8 @@ RU +6200+12940 Asia/Yakutsk Moscow+06 - Lena River
RU +4310+13156 Asia/Vladivostok Moscow+07 - Amur River
RU +4658+14242 Asia/Sakhalin Moscow+07 - Sakhalin Island
RU +5934+15048 Asia/Magadan Moscow+08 - Magadan
-RU +5301+15839 Asia/Kamchatka Moscow+09 - Kamchatka
-RU +6445+17729 Asia/Anadyr Moscow+10 - Bering Sea
+RU +5301+15839 Asia/Kamchatka Moscow+08 - Kamchatka
+RU +6445+17729 Asia/Anadyr Moscow+08 - Bering Sea
RW -0157+03004 Africa/Kigali
SA +2438+04643 Asia/Riyadh
SB -0932+16012 Pacific/Guadalcanal
diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog
index b2df660..d6e4a4a 100644
--- a/crypto/openssh/ChangeLog
+++ b/crypto/openssh/ChangeLog
@@ -1,3 +1,982 @@
+20100307
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/03/07 22:16:01
+ [ssh-keygen.c]
+ make internal strptime string match strftime format;
+ suggested by vinschen AT redhat.com and markus@
+ - djm@cvs.openbsd.org 2010/03/08 00:28:55
+ [ssh-keygen.1]
+ document permit-agent-forwarding certificate constraint; patch from
+ stevesk@
+ - djm@cvs.openbsd.org 2010/03/07 22:01:32
+ [version.h]
+ openssh-5.4
+ - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
+ crank version numbers
+ - (djm) Release OpenSSH-5.4p1
+
+20100307
+ - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that
+ it gets the passwd struct from the LAM that knows about the user which is
+ not necessarily the default. Patch from Alexandre Letourneau.
+ - (dtucker) [session.c] Bug #1567: move setpcred call to before chroot and
+ do not set real uid, since that's needed for the chroot, and will be set
+ by permanently_set_uid.
+ - (dtucker) [session.c] Also initialize creds to NULL for handing to
+ setpcred.
+ - (dtucker) OpenBSD CVS Sync
+ - dtucker@cvs.openbsd.org 2010/03/07 11:57:13
+ [auth-rhosts.c monitor.c monitor_wrap.c session.c auth-options.c sshd.c]
+ Hold authentication debug messages until after successful authentication.
+ Fixes an info leak of environment variables specified in authorized_keys,
+ reported by Jacob Appelbaum. ok djm@
+
+20100305
+ - OpenBSD CVS Sync
+ - jmc@cvs.openbsd.org 2010/03/04 12:51:25
+ [ssh.1 sshd_config.5]
+ tweak previous;
+ - djm@cvs.openbsd.org 2010/03/04 20:35:08
+ [ssh-keygen.1 ssh-keygen.c]
+ Add a -L flag to print the contents of a certificate; ok markus@
+ - jmc@cvs.openbsd.org 2010/03/04 22:52:40
+ [ssh-keygen.1]
+ fix Bk/Ek;
+ - djm@cvs.openbsd.org 2010/03/04 23:17:25
+ [sshd_config.5]
+ missing word; spotted by jmc@
+ - djm@cvs.openbsd.org 2010/03/04 23:19:29
+ [ssh.1 sshd.8]
+ move section on CA and revoked keys from ssh.1 to sshd.8's known hosts
+ format section and rework it a bit; requested by jmc@
+ - djm@cvs.openbsd.org 2010/03/04 23:27:25
+ [auth-options.c ssh-keygen.c]
+ "force-command" is not spelled "forced-command"; spotted by
+ imorgan AT nas.nasa.gov
+ - djm@cvs.openbsd.org 2010/03/05 02:58:11
+ [auth.c]
+ make the warning for a revoked key louder and more noticable
+ - jmc@cvs.openbsd.org 2010/03/05 06:50:35
+ [ssh.1 sshd.8]
+ tweak previous;
+ - jmc@cvs.openbsd.org 2010/03/05 08:31:20
+ [ssh.1]
+ document certificate authentication; help/ok djm
+ - djm@cvs.openbsd.org 2010/03/05 10:28:21
+ [ssh-add.1 ssh.1 ssh_config.5]
+ mention loading of certificate files from [private]-cert.pub when
+ they are present; feedback and ok jmc@
+ - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older
+ compilers. OK djm@
+ - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure
+ on some platforms
+ - (djm) [configure.ac] set -fno-strict-aliasing for gcc4; ok dtucker@
+
+20100304
+ - (djm) [ssh-keygen.c] Use correct local variable, instead of
+ maybe-undefined global "optarg"
+ - (djm) [contrib/redhat/openssh.spec] Replace obsolete BuildPreReq
+ on XFree86-devel with neutral /usr/include/X11/Xlib.h;
+ imorgan AT nas.nasa.gov in bz#1731
+ - (djm) [.cvsignore] Ignore ssh-pkcs11-helper
+ - (djm) [regress/Makefile] Cleanup sshd_proxy_orig
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/03/03 01:44:36
+ [auth-options.c key.c]
+ reject strings with embedded ASCII nul chars in certificate key IDs,
+ principal names and constraints
+ - djm@cvs.openbsd.org 2010/03/03 22:49:50
+ [sshd.8]
+ the authorized_keys option for CA keys is "cert-authority", not
+ "from=cert-authority". spotted by imorgan AT nas.nasa.gov
+ - djm@cvs.openbsd.org 2010/03/03 22:50:40
+ [PROTOCOL.certkeys]
+ s/similar same/similar/; from imorgan AT nas.nasa.gov
+ - djm@cvs.openbsd.org 2010/03/04 01:44:57
+ [key.c]
+ use buffer_get_string_ptr_ret() where we are checking the return
+ value explicitly instead of the fatal()-causing buffer_get_string_ptr()
+ - djm@cvs.openbsd.org 2010/03/04 10:36:03
+ [auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c]
+ [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h]
+ [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5]
+ Add a TrustedUserCAKeys option to sshd_config to specify CA keys that
+ are trusted to authenticate users (in addition than doing it per-user
+ in authorized_keys).
+
+ Add a RevokedKeys option to sshd_config and a @revoked marker to
+ known_hosts to allow keys to me revoked and banned for user or host
+ authentication.
+
+ feedback and ok markus@
+ - djm@cvs.openbsd.org 2010/03/03 00:47:23
+ [regress/cert-hostkey.sh regress/cert-userkey.sh]
+ add an extra test to ensure that authentication with the wrong
+ certificate fails as it should (and it does)
+ - djm@cvs.openbsd.org 2010/03/04 10:38:23
+ [regress/cert-hostkey.sh regress/cert-userkey.sh]
+ additional regression tests for revoked keys and TrustedUserCAKeys
+
+20100303
+ - (djm) [PROTOCOL.certkeys] Add RCS Ident
+ - OpenBSD CVS Sync
+ - jmc@cvs.openbsd.org 2010/02/26 22:09:28
+ [ssh-keygen.1 ssh.1 sshd.8]
+ tweak previous;
+ - otto@cvs.openbsd.org 2010/03/01 11:07:06
+ [ssh-add.c]
+ zap what seems to be a left-over debug message; ok markus@
+ - djm@cvs.openbsd.org 2010/03/02 23:20:57
+ [ssh-keygen.c]
+ POSIX strptime is stricter than OpenBSD's so do a little dance to
+ appease it.
+ - (djm) [regress/cert-userkey.sh] s/echo -n/echon/ here too
+
+20100302
+ - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from
+ http://git.savannah.gnu.org/gitweb/ (2009-12-30 and 2010-01-22
+ respectively).
+
+20100301
+ - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace
+ "echo -n" with "echon" for portability.
+ - (dtucker) [openbsd-compat/port-linux.c] Make failure to write to the OOM
+ adjust log at verbose only, since according to cjwatson in bug #1470
+ some virtualization platforms don't allow writes.
+
+20100228
+ - (djm) [auth.c] On Cygwin, refuse usernames that have differences in
+ case from that matched in the system password database. On this
+ platform, passwords are stored case-insensitively, but sshd requires
+ exact case matching for Match blocks in sshd_config(5). Based on
+ a patch from vinschen AT redhat.com.
+ - (tim) [ssh-pkcs11-helper.c] Move declarations before calling functions
+ to make older compilers (gcc 2.95) happy.
+
+20100227
+ - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded
+ - (djm) [openbsd-compat/bsd-cygwin_util.c] Reduce the set of environment
+ variables copied into sshd child processes. From vinschen AT redhat.com
+
+20100226
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/02/26 20:29:54
+ [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys addrmatch.c auth-options.c]
+ [auth-options.h auth.h auth2-pubkey.c authfd.c dns.c dns.h hostfile.c]
+ [hostfile.h kex.h kexdhs.c kexgexs.c key.c key.h match.h monitor.c]
+ [myproposal.h servconf.c servconf.h ssh-add.c ssh-agent.c ssh-dss.c]
+ [ssh-keygen.1 ssh-keygen.c ssh-rsa.c ssh.1 ssh.c ssh2.h sshconnect.c]
+ [sshconnect2.c sshd.8 sshd.c sshd_config.5]
+ Add support for certificate key types for users and hosts.
+
+ OpenSSH certificate key types are not X.509 certificates, but a much
+ simpler format that encodes a public key, identity information and
+ some validity constraints and signs it with a CA key. CA keys are
+ regular SSH keys. This certificate style avoids the attack surface
+ of X.509 certificates and is very easy to deploy.
+
+ Certified host keys allow automatic acceptance of new host keys
+ when a CA certificate is marked as trusted in ~/.ssh/known_hosts.
+ see VERIFYING HOST KEYS in ssh(1) for details.
+
+ Certified user keys allow authentication of users when the signing
+ CA key is marked as trusted in authorized_keys. See "AUTHORIZED_KEYS
+ FILE FORMAT" in sshd(8) for details.
+
+ Certificates are minted using ssh-keygen(1), documentation is in
+ the "CERTIFICATES" section of that manpage.
+
+ Documentation on the format of certificates is in the file
+ PROTOCOL.certkeys
+
+ feedback and ok markus@
+ - djm@cvs.openbsd.org 2010/02/26 20:33:21
+ [Makefile regress/cert-hostkey.sh regress/cert-userkey.sh]
+ regression tests for certified keys
+
+20100224
+ - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c]
+ [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/02/11 20:37:47
+ [pathnames.h]
+ correct comment
+ - dtucker@cvs.openbsd.org 2009/11/09 04:20:04
+ [regress/Makefile]
+ add regression test for ssh-keygen pubkey conversions
+ - dtucker@cvs.openbsd.org 2010/01/11 02:53:44
+ [regress/forwarding.sh]
+ regress test for stdio forwarding
+ - djm@cvs.openbsd.org 2010/02/09 04:57:36
+ [regress/addrmatch.sh]
+ clean up droppings
+ - djm@cvs.openbsd.org 2010/02/09 06:29:02
+ [regress/Makefile]
+ turn on all the malloc(3) checking options when running regression
+ tests. this has caught a few bugs for me in the past; ok dtucker@
+ - djm@cvs.openbsd.org 2010/02/24 06:21:56
+ [regress/test-exec.sh]
+ wait for sshd to fully stop in cleanup() function; avoids races in tests
+ that do multiple start_sshd/cleanup cycles; "I hate pidfiles" deraadt@
+ - markus@cvs.openbsd.org 2010/02/08 10:52:47
+ [regress/agent-pkcs11.sh]
+ test for PKCS#11 support (currently disabled)
+ - (djm) [Makefile.in ssh-pkcs11-helper.8] Add manpage for PKCS#11 helper
+ - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
+ [contrib/suse/openssh.spec] Add PKCS#11 helper binary and manpage
+
+20100212
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/02/02 22:49:34
+ [bufaux.c]
+ make buffer_get_string_ret() really non-fatal in all cases (it was
+ using buffer_get_int(), which could fatal() on buffer empty);
+ ok markus dtucker
+ - markus@cvs.openbsd.org 2010/02/08 10:50:20
+ [pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c]
+ [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5]
+ replace our obsolete smartcard code with PKCS#11.
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf
+ ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11
+ provider (shared library) while ssh-agent(1) delegates PKCS#11 to
+ a forked a ssh-pkcs11-helper process.
+ PKCS#11 is currently a compile time option.
+ feedback and ok djm@; inspired by patches from Alon Bar-Lev
+ - jmc@cvs.openbsd.org 2010/02/08 22:03:05
+ [ssh-add.1 ssh-keygen.1 ssh.1 ssh.c]
+ tweak previous; ok markus
+ - djm@cvs.openbsd.org 2010/02/09 00:50:36
+ [ssh-agent.c]
+ fallout from PKCS#11: unbreak -D
+ - djm@cvs.openbsd.org 2010/02/09 00:50:59
+ [ssh-keygen.c]
+ fix -Wall
+ - djm@cvs.openbsd.org 2010/02/09 03:56:28
+ [buffer.c buffer.h]
+ constify the arguments to buffer_len, buffer_ptr and buffer_dump
+ - djm@cvs.openbsd.org 2010/02/09 06:18:46
+ [auth.c]
+ unbreak ChrootDirectory+internal-sftp by skipping check for executable
+ shell when chrooting; reported by danh AT wzrd.com; ok dtucker@
+ - markus@cvs.openbsd.org 2010/02/10 23:20:38
+ [ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5]
+ pkcs#11 is no longer optional; improve wording; ok jmc@
+ - jmc@cvs.openbsd.org 2010/02/11 13:23:29
+ [ssh.1]
+ libarary -> library;
+ - (djm) [INSTALL Makefile.in README.smartcard configure.ac scard-opensc.c]
+ [scard.c scard.h pkcs11.h scard/Makefile.in scard/Ssh.bin.uu scard/Ssh.java]
+ Remove obsolete smartcard support
+ - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c]
+ Make it compile on OSX
+ - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c]
+ Use ssh_get_progname to fill __progname
+ - (djm) [configure.ac] Enable PKCS#11 support only when we find a working
+ dlopen()
+
+20100210
+ - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for
+ getseuserbyname; patch from calebcase AT gmail.com via
+ cjwatson AT debian.org
+
+20100202
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/01/30 21:08:33
+ [sshd.8]
+ debug output goes to stderr, not "the system log"; ok markus dtucker
+ - djm@cvs.openbsd.org 2010/01/30 21:12:08
+ [channels.c]
+ fake local addr:port when stdio fowarding as some servers (Tectia at
+ least) validate that they are well-formed;
+ reported by imorgan AT nas.nasa.gov
+ ok dtucker
+
+20100130
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/01/28 00:21:18
+ [clientloop.c]
+ downgrade an error() to a debug() - this particular case can be hit in
+ normal operation for certain sequences of mux slave vs session closure
+ and is harmless
+ - djm@cvs.openbsd.org 2010/01/29 00:20:41
+ [sshd.c]
+ set FD_CLOEXEC on sock_in/sock_out; bz#1706 from jchadima AT redhat.com
+ ok dtucker@
+ - djm@cvs.openbsd.org 2010/01/29 20:16:17
+ [mux.c]
+ kill correct channel (was killing already-dead mux channel, not
+ its session channel)
+ - djm@cvs.openbsd.org 2010/01/30 02:54:53
+ [mux.c]
+ don't mark channel as read failed if it is already closing; suppresses
+ harmless error messages when connecting to SSH.COM Tectia server
+ report by imorgan AT nas.nasa.gov
+
+20100129
+ - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config()
+ after registering the hardware engines, which causes the openssl.cnf file to
+ be processed. See OpenSSL's man page for OPENSSL_config(3) for details.
+ Patch from Solomon Peachy, ok djm@.
+
+20100128
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/01/26 02:15:20
+ [mux.c]
+ -Wuninitialized and remove a // comment; from portable
+ (Id sync only)
+ - djm@cvs.openbsd.org 2010/01/27 13:26:17
+ [mux.c]
+ fix bug introduced in mux rewrite:
+
+ In a mux master, when a socket to a mux slave closes before its server
+ session (as may occur when the slave has been signalled), gracefully
+ close the server session rather than deleting its channel immediately.
+ A server may have more messages on that channel to send (e.g. an exit
+ message) that will fatal() the client if they are sent to a channel that
+ has been prematurely deleted.
+
+ spotted by imorgan AT nas.nasa.gov
+ - djm@cvs.openbsd.org 2010/01/27 19:21:39
+ [sftp.c]
+ add missing "p" flag to getopt optstring;
+ bz#1704 from imorgan AT nas.nasa.gov
+
+20100126
+ - (djm) OpenBSD CVS Sync
+ - tedu@cvs.openbsd.org 2010/01/17 21:49:09
+ [ssh-agent.1]
+ Correct and clarify ssh-add's password asking behavior.
+ Improved text dtucker and ok jmc
+ - dtucker@cvs.openbsd.org 2010/01/18 01:50:27
+ [roaming_client.c]
+ s/long long unsigned/unsigned long long/, from tim via portable
+ (Id sync only, change already in portable)
+ - djm@cvs.openbsd.org 2010/01/26 01:28:35
+ [channels.c channels.h clientloop.c clientloop.h mux.c nchan.c ssh.c]
+ rewrite ssh(1) multiplexing code to a more sensible protocol.
+
+ The new multiplexing code uses channels for the listener and
+ accepted control sockets to make the mux master non-blocking, so
+ no stalls when processing messages from a slave.
+
+ avoid use of fatal() in mux master protocol parsing so an errant slave
+ process cannot take down a running master.
+
+ implement requesting of port-forwards over multiplexed sessions. Any
+ port forwards requested by the slave are added to those the master has
+ established.
+
+ add support for stdio forwarding ("ssh -W host:port ...") in mux slaves.
+
+ document master/slave mux protocol so that other tools can use it to
+ control a running ssh(1). Note: there are no guarantees that this
+ protocol won't be incompatibly changed (though it is versioned).
+
+ feedback Salvador Fandino, dtucker@
+ channel changes ok markus@
+
+20100122
+ - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of
+ socket inheritance, reduce the default SO_RCVBUF/SO_SNDBUF buffer size
+ in Cygwin to 65535. Patch from Corinna Vinschen.
+
+20100117
+ - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too.
+ - (tim) [configure.ac] On SVR5 systems, use the C99-conforming functions
+ snprintf() and vsnprintf() named _xsnprintf() and _xvsnprintf().
+
+20100116
+ - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h
+ so we correctly detect whether or not we have a native user_from_uid.
+ - (dtucker) [openbsd-compat/openbsd-compat.h] Prototypes for user_from_uid
+ and group_from_gid.
+ - (dtucker) [openbsd-compat/openbsd-compat.h] Fix prototypes, spotted by
+ Tim.
+ - (dtucker) OpenBSD CVS Sync
+ - markus@cvs.openbsd.org 2010/01/15 09:24:23
+ [sftp-common.c]
+ unused
+ - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused
+ variable warnings.
+ - (dtucker) [openbsd-compat/openbsd-compat.h] Typo.
+ - (tim) [regress/portnum.sh] Shell portability fix.
+ - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native
+ getaddrinfo() is too old and limited for addr_pton() in addrmatch.c.
+ - (tim) [roaming_client.c] Use of <sys/queue.h> is not really portable so we
+ use "openbsd-compat/sys-queue.h". s/long long unsigned/unsigned long long/
+ to keep USL compilers happy.
+
+20100115
+ - (dtucker) OpenBSD CVS Sync
+ - jmc@cvs.openbsd.org 2010/01/13 12:48:34
+ [sftp.1 sftp.c]
+ sftp.1: put ls -h in the right place
+ sftp.c: as above, plus add -p to get/put, and shorten their arg names
+ to keep the help usage nicely aligned
+ ok djm
+ - djm@cvs.openbsd.org 2010/01/13 23:47:26
+ [auth.c]
+ when using ChrootDirectory, make sure we test for the existence of the
+ user's shell inside the chroot; bz #1679, patch from alex AT rtfs.hu;
+ ok dtucker
+ - dtucker@cvs.openbsd.org 2010/01/14 23:41:49
+ [sftp-common.c]
+ use user_from{uid,gid} to lookup up ids since it keeps a small cache.
+ ok djm
+ - guenther@cvs.openbsd.org 2010/01/15 00:05:22
+ [sftp.c]
+ Reset SIGTERM to SIG_DFL before executing ssh, so that even if sftp
+ inherited SIGTERM as ignored it will still be able to kill the ssh it
+ starts.
+ ok dtucker@
+ - (dtucker) [openbsd-compat/pwcache.c] Pull in pwcache.c from OpenBSD (no
+ changes yet but there will be some to come).
+ - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability
+ for pwcache. Also, added caching of negative hits.
+
+20100114
+ - (djm) [platform.h] Add missing prototype for
+ platform_krb5_get_principal_name
+
+20100113
+ - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs.
+ - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18:
+ missing restore of SIGTTOU and some whitespace.
+ - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.21.
+ - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.22.
+ Fixes bz #1590, where sometimes you could not interrupt a connection while
+ ssh was prompting for a passphrase or password.
+ - (dtucker) OpenBSD CVS Sync
+ - dtucker@cvs.openbsd.org 2010/01/13 00:19:04
+ [sshconnect.c auth.c]
+ Fix a couple of typos/mispellings in comments
+ - dtucker@cvs.openbsd.org 2010/01/13 01:10:56
+ [key.c]
+ Ignore and log any Protocol 1 keys where the claimed size is not equal to
+ the actual size. Noted by Derek Martin, ok djm@
+ - dtucker@cvs.openbsd.org 2010/01/13 01:20:20
+ [canohost.c ssh-keysign.c sshconnect2.c]
+ Make HostBased authentication work with a ProxyCommand. bz #1569, patch
+ from imorgan at nas nasa gov, ok djm@
+ - djm@cvs.openbsd.org 2010/01/13 01:40:16
+ [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h]
+ support '-h' (human-readable units) for sftp's ls command, just like
+ ls(1); ok dtucker@
+ - djm@cvs.openbsd.org 2010/01/13 03:48:13
+ [servconf.c servconf.h sshd.c]
+ avoid run-time failures when specifying hostkeys via a relative
+ path by prepending the cwd in these cases; bz#1290; ok dtucker@
+ - djm@cvs.openbsd.org 2010/01/13 04:10:50
+ [sftp.c]
+ don't append a space after inserting a completion of a directory (i.e.
+ a path ending in '/') for a slightly better user experience; ok dtucker@
+ - (dtucker) [sftp-common.c] Wrap include of util.h in an ifdef.
+ - (tim) [defines.h] openbsd-compat/readpassphrase.c now needs _NSIG.
+ feedback and ok dtucker@
+
+20100112
+ - (dtucker) OpenBSD CVS Sync
+ - dtucker@cvs.openbsd.org 2010/01/11 01:39:46
+ [ssh_config channels.c ssh.1 channels.h ssh.c]
+ Add a 'netcat mode' (ssh -W). This connects stdio on the client to a
+ single port forward on the server. This allows, for example, using ssh as
+ a ProxyCommand to route connections via intermediate servers.
+ bz #1618, man page help from jmc@, ok markus@
+ - dtucker@cvs.openbsd.org 2010/01/11 04:46:45
+ [authfile.c sshconnect2.c]
+ Do not prompt for a passphrase if we fail to open a keyfile, and log the
+ reason the open failed to debug.
+ bz #1693, found by tj AT castaglia org, ok djm@
+ - djm@cvs.openbsd.org 2010/01/11 10:51:07
+ [ssh-keygen.c]
+ when converting keys, truncate key comments at 72 chars as per RFC4716;
+ bz#1630 reported by tj AT castaglia.org; ok markus@
+ - dtucker@cvs.openbsd.org 2010/01/12 00:16:47
+ [authfile.c]
+ Fix bug introduced in r1.78 (incorrect brace location) that broke key auth.
+ Patch from joachim joachimschipper nl.
+ - djm@cvs.openbsd.org 2010/01/12 00:58:25
+ [monitor_fdpass.c]
+ avoid spinning when fd passing on nonblocking sockets by calling poll()
+ in the EINTR/EAGAIN path, much like we do in atomicio; ok dtucker@
+ - djm@cvs.openbsd.org 2010/01/12 00:59:29
+ [roaming_common.c]
+ delete with extreme prejudice a debug() that fired with every keypress;
+ ok dtucker deraadt
+ - dtucker@cvs.openbsd.org 2010/01/12 01:31:05
+ [session.c]
+ Do not allow logins if /etc/nologin exists but is not readable by the user
+ logging in. Noted by Jan.Pechanec at Sun, ok djm@ deraadt@
+ - djm@cvs.openbsd.org 2010/01/12 01:36:08
+ [buffer.h bufaux.c]
+ add a buffer_get_string_ptr_ret() that does the same as
+ buffer_get_string_ptr() but does not fatal() on error; ok dtucker@
+ - dtucker@cvs.openbsd.org 2010/01/12 08:33:17
+ [session.c]
+ Add explicit stat so we reliably detect nologin with bad perms.
+ ok djm markus
+
+20100110
+ - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c]
+ Remove hacks add for RoutingDomain in preparation for its removal.
+ - (dtucker) OpenBSD CVS Sync
+ - dtucker@cvs.openbsd.org 2010/01/09 23:04:13
+ [channels.c ssh.1 servconf.c sshd_config.5 sshd.c channels.h servconf.h
+ ssh-keyscan.1 ssh-keyscan.c readconf.c sshconnect.c misc.c ssh.c
+ readconf.h scp.1 sftp.1 ssh_config.5 misc.h]
+ Remove RoutingDomain from ssh since it's now not needed. It can be
+ replaced with "route exec" or "nc -V" as a proxycommand. "route exec"
+ also ensures that trafic such as DNS lookups stays withing the specified
+ routingdomain. For example (from reyk):
+ # route -T 2 exec /usr/sbin/sshd
+ or inherited from the parent process
+ $ route -T 2 exec sh
+ $ ssh 10.1.2.3
+ ok deraadt@ markus@ stevesk@ reyk@
+ - dtucker@cvs.openbsd.org 2010/01/10 03:51:17
+ [servconf.c]
+ Add ChrootDirectory to sshd.c test-mode output
+ - dtucker@cvs.openbsd.org 2010/01/10 07:15:56
+ [auth.c]
+ Output a debug if we can't open an existing keyfile. bz#1694, ok djm@
+
+20100109
+ - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't
+ have it.
+ - (dtucker) [defines.h] define PRIu64 for platforms that don't have it.
+ - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef.
+ - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name
+ when using utmpx. Patch from Ed Schouten.
+ - (dtucker) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/01/09 00:20:26
+ [sftp-server.c sftp-server.8]
+ add a 'read-only' mode to sftp-server(8) that disables open in write mode
+ and all other fs-modifying protocol methods. bz#430 ok dtucker@
+ - djm@cvs.openbsd.org 2010/01/09 00:57:10
+ [PROTOCOL]
+ tweak language
+ - jmc@cvs.openbsd.org 2010/01/09 03:36:00
+ [sftp-server.8]
+ bad place to forget a comma...
+ - djm@cvs.openbsd.org 2010/01/09 05:04:24
+ [mux.c sshpty.h clientloop.c sshtty.c]
+ quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we
+ usually don't actually have a tty to read/set; bz#1686 ok dtucker@
+ - dtucker@cvs.openbsd.org 2010/01/09 05:17:00
+ [roaming_client.c]
+ Remove a PRIu64 format string that snuck in with roaming. ok djm@
+ - dtucker@cvs.openbsd.org 2010/01/09 11:13:02
+ [sftp.c]
+ Prevent sftp from derefing a null pointer when given a "-" without a
+ command. Also, allow whitespace to follow a "-". bz#1691, path from
+ Colin Watson via Debian. ok djm@ deraadt@
+ - dtucker@cvs.openbsd.org 2010/01/09 11:17:56
+ [sshd.c]
+ Afer sshd receives a SIGHUP, ignore subsequent HUPs while sshd re-execs
+ itself. Prevents two HUPs in quick succession from resulting in sshd
+ dying. bz#1692, patch from Colin Watson via Ubuntu.
+ - (dtucker) [defines.h] Remove now-undeeded PRIu64 define.
+
+20100108
+ - (dtucker) OpenBSD CVS Sync
+ - andreas@cvs.openbsd.org 2009/10/24 11:11:58
+ [roaming.h]
+ Declarations needed for upcoming changes.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/10/24 11:13:54
+ [sshconnect2.c kex.h kex.c]
+ Let the client detect if the server supports roaming by looking
+ for the resume@appgate.com kex algorithm.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/10/24 11:15:29
+ [clientloop.c]
+ client_loop() must detect if the session has been suspended and resumed,
+ and take appropriate action in that case.
+ From Martin Forssen, maf at appgate dot com
+ - andreas@cvs.openbsd.org 2009/10/24 11:19:17
+ [ssh2.h]
+ Define the KEX messages used when resuming a suspended connection.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/10/24 11:22:37
+ [roaming_common.c]
+ Do the actual suspend/resume in the client. This won't be useful until
+ the server side supports roaming.
+ Most code from Martin Forssen, maf at appgate dot com. Some changes by
+ me and markus@
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/10/24 11:23:42
+ [ssh.c]
+ Request roaming to be enabled if UseRoaming is true and the server
+ supports it.
+ ok markus@
+ - reyk@cvs.openbsd.org 2009/10/28 16:38:18
+ [ssh_config.5 sshd.c misc.h ssh-keyscan.1 readconf.h sshconnect.c
+ channels.c channels.h servconf.h servconf.c ssh.1 ssh-keyscan.c scp.1
+ sftp.1 sshd_config.5 readconf.c ssh.c misc.c]
+ Allow to set the rdomain in ssh/sftp/scp/sshd and ssh-keyscan.
+ ok markus@
+ - jmc@cvs.openbsd.org 2009/10/28 21:45:08
+ [sshd_config.5 sftp.1]
+ tweak previous;
+ - djm@cvs.openbsd.org 2009/11/10 02:56:22
+ [ssh_config.5]
+ explain the constraints on LocalCommand some more so people don't
+ try to abuse it.
+ - djm@cvs.openbsd.org 2009/11/10 02:58:56
+ [sshd_config.5]
+ clarify that StrictModes does not apply to ChrootDirectory. Permissions
+ and ownership are always checked when chrooting. bz#1532
+ - dtucker@cvs.openbsd.org 2009/11/10 04:30:45
+ [sshconnect2.c channels.c sshconnect.c]
+ Set close-on-exec on various descriptors so they don't get leaked to
+ child processes. bz #1643, patch from jchadima at redhat, ok deraadt.
+ - markus@cvs.openbsd.org 2009/11/11 21:37:03
+ [channels.c channels.h]
+ fix race condition in x11/agent channel allocation: don't read after
+ the end of the select read/write fdset and make sure a reused FD
+ is not touched before the pre-handlers are called.
+ with and ok djm@
+ - djm@cvs.openbsd.org 2009/11/17 05:31:44
+ [clientloop.c]
+ fix incorrect exit status when multiplexing and channel ID 0 is recycled
+ bz#1570 reported by peter.oliver AT eon-is.co.uk; ok dtucker
+ - djm@cvs.openbsd.org 2009/11/19 23:39:50
+ [session.c]
+ bz#1606: error when an attempt is made to connect to a server
+ with ForceCommand=internal-sftp with a shell session (i.e. not a
+ subsystem session). Avoids stuck client when attempting to ssh to such a
+ service. ok dtucker@
+ - dtucker@cvs.openbsd.org 2009/11/20 00:15:41
+ [session.c]
+ Warn but do not fail if stat()ing the subsystem binary fails. This helps
+ with chrootdirectory+forcecommand=sftp-server and restricted shells.
+ bz #1599, ok djm.
+ - djm@cvs.openbsd.org 2009/11/20 00:54:01
+ [sftp.c]
+ bz#1588 change "Connecting to host..." message to "Connected to host."
+ and delay it until after the sftp protocol connection has been established.
+ Avoids confusing sequence of messages when the underlying ssh connection
+ experiences problems. ok dtucker@
+ - dtucker@cvs.openbsd.org 2009/11/20 00:59:36
+ [sshconnect2.c]
+ Use the HostKeyAlias when prompting for passwords. bz#1039, ok djm@
+ - djm@cvs.openbsd.org 2009/11/20 03:24:07
+ [misc.c]
+ correct off-by-one in percent_expand(): we would fatal() when trying
+ to expand EXPAND_MAX_KEYS, allowing only EXPAND_MAX_KEYS-1 to actually
+ work. Note that nothing in OpenSSH actually uses close to this limit at
+ present. bz#1607 from Jan.Pechanec AT Sun.COM
+ - halex@cvs.openbsd.org 2009/11/22 13:18:00
+ [sftp.c]
+ make passing of zero-length arguments to ssh safe by
+ passing "-<switch>" "<value>" rather than "-<switch><value>"
+ ok dtucker@, guenther@, djm@
+ - dtucker@cvs.openbsd.org 2009/12/06 23:41:15
+ [sshconnect2.c]
+ zap unused variable and strlen; from Steve McClellan, ok djm
+ - djm@cvs.openbsd.org 2009/12/06 23:53:45
+ [roaming_common.c]
+ use socklen_t for getsockopt optlen parameter; reported by
+ Steve.McClellan AT radisys.com, ok dtucker@
+ - dtucker@cvs.openbsd.org 2009/12/06 23:53:54
+ [sftp.c]
+ fix potential divide-by-zero in sftp's "df" output when talking to a server
+ that reports zero files on the filesystem (Unix filesystems always have at
+ least the root inode). From Steve McClellan at radisys, ok djm@
+ - markus@cvs.openbsd.org 2009/12/11 18:16:33
+ [key.c]
+ switch from 35 to the more common value of RSA_F4 == (2**16)+1 == 65537
+ for the RSA public exponent; discussed with provos; ok djm@
+ - guenther@cvs.openbsd.org 2009/12/20 07:28:36
+ [ssh.c sftp.c scp.c]
+ When passing user-controlled options with arguments to other programs,
+ pass the option and option argument as separate argv entries and
+ not smashed into one (e.g., as -l foo and not -lfoo). Also, always
+ pass a "--" argument to stop option parsing, so that a positional
+ argument that starts with a '-' isn't treated as an option. This
+ fixes some error cases as well as the handling of hostnames and
+ filenames that start with a '-'.
+ Based on a diff by halex@
+ ok halex@ djm@ deraadt@
+ - djm@cvs.openbsd.org 2009/12/20 23:20:40
+ [PROTOCOL]
+ fix an incorrect magic number and typo in PROTOCOL; bz#1688
+ report and fix from ueno AT unixuser.org
+ - stevesk@cvs.openbsd.org 2009/12/25 19:40:21
+ [readconf.c servconf.c misc.h ssh-keyscan.c misc.c]
+ validate routing domain is in range 0-RT_TABLEID_MAX.
+ 'Looks right' deraadt@
+ - stevesk@cvs.openbsd.org 2009/12/29 16:38:41
+ [sshd_config.5 readconf.c ssh_config.5 scp.1 servconf.c sftp.1 ssh.1]
+ Rename RDomain config option to RoutingDomain to be more clear and
+ consistent with other options.
+ NOTE: if you currently use RDomain in the ssh client or server config,
+ or ssh/sshd -o, you must update to use RoutingDomain.
+ ok markus@ djm@
+ - jmc@cvs.openbsd.org 2009/12/29 18:03:32
+ [sshd_config.5 ssh_config.5]
+ sort previous;
+ - dtucker@cvs.openbsd.org 2010/01/04 01:45:30
+ [sshconnect2.c]
+ Don't escape backslashes in the SSH2 banner. bz#1533, patch from
+ Michal Gorny via Gentoo.
+ - djm@cvs.openbsd.org 2010/01/04 02:03:57
+ [sftp.c]
+ Implement tab-completion of commands, local and remote filenames for sftp.
+ Hacked on and off for some time by myself, mouring, Carlos Silva (via 2009
+ Google Summer of Code) and polished to a fine sheen by myself again.
+ It should deal more-or-less correctly with the ikky corner-cases presented
+ by quoted filenames, but the UI could still be slightly improved.
+ In particular, it is quite slow for remote completion on large directories.
+ bz#200; ok markus@
+ - djm@cvs.openbsd.org 2010/01/04 02:25:15
+ [sftp-server.c]
+ bz#1566 don't unnecessarily dup() in and out fds for sftp-server;
+ ok markus@
+ - dtucker@cvs.openbsd.org 2010/01/08 21:50:49
+ [sftp.c]
+ Fix two warnings: possibly used unitialized and use a nul byte instead of
+ NULL pointer. ok djm@
+ - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new
+ files for roaming and add to Makefile.
+ - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines.
+ - (dtucker) [sftp.c] ifdef out the sftp completion bits for platforms that
+ don't have libedit.
+ - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Make
+ RoutingDomain an unsupported option on platforms that don't have it.
+ - (dtucker) [sftp.c] Expand ifdef for libedit to cover complete_is_remote
+ too.
+ - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to
+ be created.
+ - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more
+ to eliminate an unused variable warning.
+ - (dtucker) [roaming_serv.c] Include includes.h for u_intXX_t types.
+
+20091226
+ - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1
+ Gzip all man pages. Patch from Corinna Vinschen.
+
+20091221
+ - (dtucker) [auth-krb5.c platform.{c,h} openbsd-compat/port-aix.{c,h}]
+ Bug #1583: Use system's kerberos principal name on AIX if it's available.
+ Based on a patch from and tested by Miguel Sanders
+
+20091208
+ - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux,
+ based on a patch from Vaclav Ovsik and Colin Watson. ok djm.
+
+20091207
+ - (dtucker) Bug #1160: use pkg-config for opensc config if it's available.
+ Tested by Martin Paljak.
+ - (dtucker) Bug #1677: add conditionals around the source for ssh-askpass.
+
+20091121
+ - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it.
+ Bug 1628. OK dtucker@
+
+20091120
+ - (djm) [ssh-rand-helper.c] Print error and usage() when passed command-
+ line arguments as none are supported. Exit when passed unrecognised
+ commandline flags. bz#1568 from gson AT araneus.fi
+
+20091118
+ - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to
+ set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify
+ setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only()
+ bz#1648, report and fix from jan.kratochvil AT redhat.com
+ - (djm) [contrib/gnome-ssh-askpass2.c] Make askpass dialog desktop-modal.
+ bz#1645, patch from jchadima AT redhat.com
+
+20091107
+ - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private
+ keys when built with OpenSSL versions that don't do AES.
+
+20091105
+ - (dtucker) [authfile.c] Add OpenSSL compat header so this still builds with
+ older versions of OpenSSL.
+
+20091024
+ - (dtucker) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2009/10/11 23:03:15
+ [hostfile.c]
+ mention the host name that we are looking for in check_host_in_hostfile()
+ - sobrado@cvs.openbsd.org 2009/10/17 12:10:39
+ [sftp-server.c]
+ sort flags.
+ - sobrado@cvs.openbsd.org 2009/10/22 12:35:53
+ [ssh.1 ssh-agent.1 ssh-add.1]
+ use the UNIX-related macros (.At and .Ux) where appropriate.
+ ok jmc@
+ - sobrado@cvs.openbsd.org 2009/10/22 15:02:12
+ [ssh-agent.1 ssh-add.1 ssh.1]
+ write UNIX-domain in a more consistent way; while here, replace a
+ few remaining ".Tn UNIX" macros with ".Ux" ones.
+ pointed out by ratchov@, thanks!
+ ok jmc@
+ - djm@cvs.openbsd.org 2009/10/22 22:26:13
+ [authfile.c]
+ switch from 3DES to AES-128 for encryption of passphrase-protected
+ SSH protocol 2 private keys; ok several
+ - djm@cvs.openbsd.org 2009/10/23 01:57:11
+ [sshconnect2.c]
+ disallow a hostile server from checking jpake auth by sending an
+ out-of-sequence success message. (doesn't affect code enabled by default)
+ - dtucker@cvs.openbsd.org 2009/10/24 00:48:34
+ [ssh-keygen.1]
+ ssh-keygen now uses AES-128 for private keys
+ - (dtucker) [mdoc2man.awk] Teach it to understand the .Ux macro.
+ - (dtucker) [session.c openbsd-compat/port-linux.{c,h}] Bug #1637: if selinux
+ is enabled set the security context to "sftpd_t" before running the
+ internal sftp server Based on a patch from jchadima at redhat.
+
+20091011
+ - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for
+ dirent d_type and DTTOIF as we've switched OpenBSD to the more portable
+ lstat.
+ - (dtucker) OpenBSD CVS Sync
+ - markus@cvs.openbsd.org 2009/10/08 14:03:41
+ [sshd_config readconf.c ssh_config.5 servconf.c sshd_config.5]
+ disable protocol 1 by default (after a transition period of about 10 years)
+ ok deraadt
+ - jmc@cvs.openbsd.org 2009/10/08 20:42:12
+ [sshd_config.5 ssh_config.5 sshd.8 ssh.1]
+ some tweaks now that protocol 1 is not offered by default; ok markus
+ - dtucker@cvs.openbsd.org 2009/10/11 10:41:26
+ [sftp-client.c]
+ d_type isn't portable so use lstat to get dirent modes. Suggested by and
+ "looks sane" deraadt@
+ - markus@cvs.openbsd.org 2009/10/08 18:04:27
+ [regress/test-exec.sh]
+ re-enable protocol v1 for the tests.
+
+20091007
+ - (dtucker) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2009/08/12 00:13:00
+ [sftp.c sftp.1]
+ support most of scp(1)'s commandline arguments in sftp(1), as a first
+ step towards making sftp(1) a drop-in replacement for scp(1).
+ One conflicting option (-P) has not been changed, pending further
+ discussion.
+ Patch from carlosvsilvapt@gmail.com as part of his work in the
+ Google Summer of Code
+ - jmc@cvs.openbsd.org 2009/08/12 06:31:42
+ [sftp.1]
+ sort options;
+ - djm@cvs.openbsd.org 2009/08/13 01:11:19
+ [sftp.1 sftp.c]
+ Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path",
+ add "-P port" to match scp(1). Fortunately, the -P option is only really
+ used by our regression scripts.
+ part of larger patch from carlosvsilvapt@gmail.com for his Google Summer
+ of Code work; ok deraadt markus
+ - jmc@cvs.openbsd.org 2009/08/13 13:39:54
+ [sftp.1 sftp.c]
+ sync synopsis and usage();
+ - djm@cvs.openbsd.org 2009/08/14 18:17:49
+ [sftp-client.c]
+ make the "get_handle: ..." error messages vaguely useful by allowing
+ callers to specify their own error message strings.
+ - fgsch@cvs.openbsd.org 2009/08/15 18:56:34
+ [auth.h]
+ remove unused define. markus@ ok.
+ (Id sync only, Portable still uses this.)
+ - dtucker@cvs.openbsd.org 2009/08/16 23:29:26
+ [sshd_config.5]
+ Add PubkeyAuthentication to the list allowed in a Match block (bz #1577)
+ - djm@cvs.openbsd.org 2009/08/18 18:36:21
+ [sftp-client.h sftp.1 sftp-client.c sftp.c]
+ recursive transfer support for get/put and on the commandline
+ work mostly by carlosvsilvapt@gmail.com for the Google Summer of Code
+ with some tweaks by me; "go for it" deraadt@
+ - djm@cvs.openbsd.org 2009/08/18 21:15:59
+ [sftp.1]
+ fix "get" command usage, spotted by jmc@
+ - jmc@cvs.openbsd.org 2009/08/19 04:56:03
+ [sftp.1]
+ ether -> either;
+ - dtucker@cvs.openbsd.org 2009/08/20 23:54:28
+ [mux.c]
+ subsystem_flag is defined in ssh.c so it's extern; ok djm
+ - djm@cvs.openbsd.org 2009/08/27 17:28:52
+ [sftp-server.c]
+ allow setting an explicit umask on the commandline to override whatever
+ default the user has. bz#1229; ok dtucker@ deraadt@ markus@
+ - djm@cvs.openbsd.org 2009/08/27 17:33:49
+ [ssh-keygen.c]
+ force use of correct hash function for random-art signature display
+ as it was inheriting the wrong one when bubblebabble signatures were
+ activated; bz#1611 report and patch from fwojcik+openssh AT besh.com;
+ ok markus@
+ - djm@cvs.openbsd.org 2009/08/27 17:43:00
+ [sftp-server.8]
+ allow setting an explicit umask on the commandline to override whatever
+ default the user has. bz#1229; ok dtucker@ deraadt@ markus@
+ - djm@cvs.openbsd.org 2009/08/27 17:44:52
+ [authfd.c ssh-add.c authfd.h]
+ Do not fall back to adding keys without contraints (ssh-add -c / -t ...)
+ when the agent refuses the constrained add request. This was a useful
+ migration measure back in 2002 when constraints were new, but just
+ adds risk now.
+ bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@
+ - djm@cvs.openbsd.org 2009/08/31 20:56:02
+ [sftp-server.c]
+ check correct variable for error message, spotted by martynas@
+ - djm@cvs.openbsd.org 2009/08/31 21:01:29
+ [sftp-server.8]
+ document -e and -h; prodded by jmc@
+ - djm@cvs.openbsd.org 2009/09/01 14:43:17
+ [ssh-agent.c]
+ fix a race condition in ssh-agent that could result in a wedged or
+ spinning agent: don't read off the end of the allocated fd_sets, and
+ don't issue blocking read/write on agent sockets - just fall back to
+ select() on retriable read/write errors. bz#1633 reported and tested
+ by "noodle10000 AT googlemail.com"; ok dtucker@ markus@
+ - grunk@cvs.openbsd.org 2009/10/01 11:37:33
+ [dh.c]
+ fix a cast
+ ok djm@ markus@
+ - djm@cvs.openbsd.org 2009/10/06 04:46:40
+ [session.c]
+ bz#1596: fflush(NULL) before exec() to ensure that everying (motd
+ in particular) has made it out before the streams go away.
+ - djm@cvs.openbsd.org 2008/12/07 22:17:48
+ [regress/addrmatch.sh]
+ match string "passwordauthentication" only at start of line, not anywhere
+ in sshd -T output
+ - dtucker@cvs.openbsd.org 2009/05/05 07:51:36
+ [regress/multiplex.sh]
+ Always specify ssh_config for multiplex tests: prevents breakage caused
+ by options in ~/.ssh/config. From Dan Peterson.
+ - djm@cvs.openbsd.org 2009/08/13 00:57:17
+ [regress/Makefile]
+ regression test for port number parsing. written as part of the a2port
+ change that went into 5.2 but I forgot to commit it at the time...
+ - djm@cvs.openbsd.org 2009/08/13 01:11:55
+ [regress/sftp-batch.sh regress/sftp-badcmds.sh regress/sftp.sh
+ regress/sftp-cmds.sh regres/sftp-glob.sh]
+ date: 2009/08/13 01:11:19; author: djm; state: Exp; lines: +10 -7
+ Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path",
+ add "-P port" to match scp(1). Fortunately, the -P option is only really
+ used by our regression scripts.
+ part of larger patch from carlosvsilvapt@gmail.com for his Google Summer
+ of Code work; ok deraadt markus
+ - djm@cvs.openbsd.org 2009/08/20 18:43:07
+ [regress/ssh-com-sftp.sh]
+ fix one sftp -D ... => sftp -P ... conversion that I missed; from Carlos
+ Silva for Google Summer of Code
+ - dtucker@cvs.openbsd.org 2009/10/06 23:51:49
+ [regress/ssh2putty.sh]
+ Add OpenBSD tag to make syncs easier
+ - (dtucker) [regress/portnum.sh] Import new test.
+ - (dtucker) [configure.ac sftp-client.c] DTOTIF is in fs/ffs/dir.h on at
+ least dragonflybsd.
+ - (dtucker) d_type is not mandated by POSIX, so add fallback code using
+ stat(), needed on at least cygwin.
+
+20091002
+ - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps.
+ spotted by des AT des.no
+
20090926
- (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
[contrib/suse/openssh.spec] Update for release
diff --git a/crypto/openssh/INSTALL b/crypto/openssh/INSTALL
index 001ebb6..09dfd66 100644
--- a/crypto/openssh/INSTALL
+++ b/crypto/openssh/INSTALL
@@ -208,10 +208,6 @@ are installed.
--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
---with-opensc=DIR
---with-sectok=DIR allows for OpenSC or sectok smartcard libraries to
-be used with OpenSSH. See 'README.smartcard' for more details.
-
If you need to pass special options to the compiler or linker, you
can specify these as environment variables before running ./configure.
For example:
@@ -266,4 +262,4 @@ Please refer to the "reporting bugs" section of the webpage at
http://www.openssh.com/
-$Id: INSTALL,v 1.84 2007/08/17 12:52:05 dtucker Exp $
+$Id: INSTALL,v 1.85 2010/02/11 22:34:22 djm Exp $
diff --git a/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL
index 5aada63..5fc31ea 100644
--- a/crypto/openssh/PROTOCOL
+++ b/crypto/openssh/PROTOCOL
@@ -6,8 +6,8 @@ filexfer protocol described in:
http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
-Features from newer versions of the draft are not supported, unless
-explicitly implemented as extensions described below.
+Newer versions of the draft will not be supported, though some features
+are individually implemented as extensions described below.
The protocol used by OpenSSH's ssh-agent is described in the file
PROTOCOL.agent
@@ -31,7 +31,14 @@ The method is documented in:
http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
-3. connection: Channel write close extension "eow@openssh.com"
+3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and
+ "ssh-dsa-cert-v00@openssh.com"
+
+OpenSSH introduces two new public key algorithms to support certificate
+authentication for users and hostkeys. These methods are documented in
+the file PROTOCOL.certkeys
+
+4. connection: Channel write close extension "eow@openssh.com"
The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
message to allow an endpoint to signal its peer that it will send no
@@ -70,7 +77,7 @@ message is only sent to OpenSSH peers (identified by banner).
Other SSH implementations may be whitelisted to receive this message
upon request.
-4. connection: disallow additional sessions extension
+5. connection: disallow additional sessions extension
"no-more-sessions@openssh.com"
Most SSH connections will only ever request a single session, but a
@@ -98,7 +105,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH
servers (identified by banner). Other SSH implementations may be
whitelisted to receive this message upon request.
-5. connection: Tunnel forward extension "tun@openssh.com"
+6. connection: Tunnel forward extension "tun@openssh.com"
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
channel type. This channel type supports forwarding of network packets
@@ -121,10 +128,10 @@ layer 2 frames or layer 3 packets. It may take one of the following values:
SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */
The "tunnel unit number" specifies the remote interface number, or may
-be zero to allow the server to automatically chose an interface. A server
-that is not willing to open a client-specified unit should refuse the
-request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful open,
-the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
+be 0x7fffffff to allow the server to automatically chose an interface. A
+server that is not willing to open a client-specified unit should refuse
+the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
+open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
Once established the client and server may exchange packet or frames
over the tunnel channel by encapsulating them in SSH protocol strings
@@ -151,7 +158,7 @@ It may be one of:
The "packet data" field consists of the IPv4/IPv6 datagram itself
without any link layer header.
-The contents of the "data" field for layer 3 packets is:
+The contents of the "data" field for layer 2 packets is:
uint32 packet length
byte[packet length] frame
@@ -159,7 +166,7 @@ The contents of the "data" field for layer 3 packets is:
The "frame" field contains an IEEE 802.3 Ethernet frame, including
header.
-6. sftp: Reversal of arguments to SSH_FXP_SYMLINK
+7. sftp: Reversal of arguments to SSH_FXP_SYMLINK
When OpenSSH's sftp-server was implemented, the order of the arguments
to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
@@ -172,7 +179,7 @@ SSH_FXP_SYMLINK as follows:
string targetpath
string linkpath
-7. sftp: Server extension announcement in SSH_FXP_VERSION
+8. sftp: Server extension announcement in SSH_FXP_VERSION
OpenSSH's sftp-server lists the extensions it supports using the
standard extension announcement mechanism in the SSH_FXP_VERSION server
@@ -193,7 +200,7 @@ ever changed in an incompatible way. The server MAY advertise the same
extension with multiple versions (though this is unlikely). Clients MUST
check the version number before attempting to use the extension.
-8. sftp: Extension request "posix-rename@openssh.com"
+9. sftp: Extension request "posix-rename@openssh.com"
This operation provides a rename operation with POSIX semantics, which
are different to those provided by the standard SSH_FXP_RENAME in
@@ -210,7 +217,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
-9. sftp: Extension requests "statvfs@openssh.com" and
+10. sftp: Extension requests "statvfs@openssh.com" and
"fstatvfs@openssh.com"
These requests correspond to the statvfs and fstatvfs POSIX system
@@ -251,4 +258,4 @@ The values of the f_flag bitmask are as follows:
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
advertised in the SSH_FXP_VERSION hello with version "2".
-$OpenBSD: PROTOCOL,v 1.12 2009/02/14 06:35:49 djm Exp $
+$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.agent b/crypto/openssh/PROTOCOL.agent
index 49adbdd..b34fcd3 100644
--- a/crypto/openssh/PROTOCOL.agent
+++ b/crypto/openssh/PROTOCOL.agent
@@ -173,6 +173,15 @@ be added using the following request
string key_comment
constraint[] key_constraints
+DSA certificates may be added with:
+ byte SSH2_AGENTC_ADD_IDENTITY or
+ SSH2_AGENTC_ADD_ID_CONSTRAINED
+ string "ssh-dss-cert-v00@openssh.com"
+ string certificate
+ mpint dsa_private_key
+ string key_comment
+ constraint[] key_constraints
+
RSA keys may be added with this request:
byte SSH2_AGENTC_ADD_IDENTITY or
@@ -187,6 +196,19 @@ RSA keys may be added with this request:
string key_comment
constraint[] key_constraints
+RSA certificates may be added with this request:
+
+ byte SSH2_AGENTC_ADD_IDENTITY or
+ SSH2_AGENTC_ADD_ID_CONSTRAINED
+ string "ssh-rsa-cert-v00@openssh.com"
+ string certificate
+ mpint rsa_d
+ mpint rsa_iqmp
+ mpint rsa_p
+ mpint rsa_q
+ string key_comment
+ constraint[] key_constraints
+
Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
order to the protocol 1 add keys message. As with the corresponding
protocol 1 "add key" request, the private key is overspecified to avoid
@@ -513,4 +535,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
SSH_AGENT_CONSTRAIN_LIFETIME 1
SSH_AGENT_CONSTRAIN_CONFIRM 2
-$OpenBSD: PROTOCOL.agent,v 1.4 2008/07/01 23:12:47 stevesk Exp $
+$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.certkeys b/crypto/openssh/PROTOCOL.certkeys
new file mode 100644
index 0000000..1ed9e20
--- /dev/null
+++ b/crypto/openssh/PROTOCOL.certkeys
@@ -0,0 +1,193 @@
+This document describes a simple public-key certificate authentication
+system for use by SSH.
+
+Background
+----------
+
+The SSH protocol currently supports a simple public key authentication
+mechanism. Unlike other public key implementations, SSH eschews the
+use of X.509 certificates and uses raw keys. This approach has some
+benefits relating to simplicity of configuration and minimisation
+of attack surface, but it does not support the important use-cases
+of centrally managed, passwordless authentication and centrally
+certified host keys.
+
+These protocol extensions build on the simple public key authentication
+system already in SSH to allow certificate-based authentication.
+The certificates used are not traditional X.509 certificates, with
+numerous options and complex encoding rules, but something rather
+more minimal: a key, some identity information and usage constraints
+that have been signed with some other trusted key.
+
+A sshd server may be configured to allow authentication via certified
+keys, by extending the existing ~/.ssh/authorized_keys mechanism
+to allow specification of certification authority keys in addition
+to raw user keys. The ssh client will support automatic verification
+of acceptance of certified host keys, by adding a similar ability
+to specify CA keys in ~/.ssh/known_hosts.
+
+Certified keys are represented using two new key types:
+ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com that
+include certification information along with the public key that is used
+to sign challenges. ssh-keygen performs the CA signing operation.
+
+Protocol extensions
+-------------------
+
+The SSH wire protocol includes several extensibility mechanisms.
+These modifications shall take advantage of namespaced public key
+algorithm names to add support for certificate authentication without
+breaking the protocol - implementations that do not support the
+extensions will simply ignore them.
+
+Authentication using the new key formats described below proceeds
+using the existing SSH "publickey" authentication method described
+in RFC4252 section 7.
+
+New public key formats
+----------------------
+
+The ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com key
+types take a similar high-level format (note: data types and
+encoding are as per RFC4251 section 5). The serialised wire encoding of
+these certificates is also used for storing them on disk.
+
+#define SSH_CERT_TYPE_USER 1
+#define SSH_CERT_TYPE_HOST 2
+
+RSA certificate
+
+ string "ssh-rsa-cert-v00@openssh.com"
+ mpint e
+ mpint n
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string constraints
+ string nonce
+ string reserved
+ string signature key
+ string signature
+
+DSA certificate
+
+ string "ssh-dss-cert-v00@openssh.com"
+ mpint p
+ mpint q
+ mpint g
+ mpint y
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string constraints
+ string nonce
+ string reserved
+ string signature key
+ string signature
+
+e and n are the RSA exponent and public modulus respectively.
+
+p, q, g, y are the DSA parameters as described in FIPS-186-2.
+
+type specifies whether this certificate is for identification of a user
+or a host using a SSH_CERT_TYPE_... value.
+
+key id is a free-form text field that is filled in by the CA at the time
+of signing; the intention is that the contents of this field are used to
+identify the identity principal in log messages.
+
+"valid principals" is a string containing zero or more principals as
+strings packed inside it. These principals list the names for which this
+certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and
+usernames for SSH_CERT_TYPE_USER certificates. As a special case, a
+zero-length "valid principals" field means the certificate is valid for
+any principal of the specified type. XXX DNS wildcards?
+
+"valid after" and "valid before" specify a validity period for the
+certificate. Each represents a time in seconds since 1970-01-01
+00:00:00. A certificate is considered valid if:
+ valid after <= current time < valid before
+
+constraints is a set of zero or more key constraints encoded as below.
+
+The nonce field is a CA-provided random bitstring of arbitrary length
+(but typically 16 or 32 bytes) included to make attacks that depend on
+inducing collisions in the signature hash infeasible.
+
+The reserved field is current unused and is ignored in this version of
+the protocol.
+
+signature key contains the CA key used to sign the certificate.
+The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained"
+certificates, where the signature key type is a certificate type itself
+are NOT supported. Note that it is possible for a RSA certificate key to
+be signed by a DSS CA key and vice-versa.
+
+signature is computed over all preceding fields from the initial string
+up to, and including the signature key. Signatures are computed and
+encoded according to the rules defined for the CA's public key algorithm
+(RFC4253 section 6.6 for ssh-rsa and ssh-dss).
+
+Constraints
+-----------
+
+The constraints section of the certificate specifies zero or more
+constraints on the certificates validity. The format of this field
+is a sequence of zero or more tuples:
+
+ string name
+ string data
+
+The name field identifies the constraint and the data field encodes
+constraint-specific information (see below). All constraints are
+"critical", if an implementation does not recognise a constraint
+then the validating party should refuse to accept the certificate.
+
+The supported constraints and the contents and structure of their
+data fields are:
+
+Name Format Description
+-----------------------------------------------------------------------------
+force-command string Specifies a command that is executed
+ (replacing any the user specified on the
+ ssh command-line) whenever this key is
+ used for authentication.
+
+permit-X11-forwarding empty Flag indicating that X11 forwarding
+ should be permitted. X11 forwarding will
+ be refused if this constraint is absent.
+
+permit-agent-forwarding empty Flag indicating that agent forwarding
+ should be allowed. Agent forwarding
+ must not be permitted unless this
+ constraint is present.
+
+permit-port-forwarding empty Flag indicating that port-forwarding
+ should be allowed. If this constraint is
+ not present then no port forwarding will
+ be allowed.
+
+permit-pty empty Flag indicating that PTY allocation
+ should be permitted. In the absence of
+ this constraint PTY allocation will be
+ disabled.
+
+permit-user-rc empty Flag indicating that execution of
+ ~/.ssh/rc should be permitted. Execution
+ of this script will not be permitted if
+ this constraint is not present.
+
+source-address string Comma-separated list of source addresses
+ from which this certificate is accepted
+ for authentication. Addresses are
+ specified in CIDR format (nn.nn.nn.nn/nn
+ or hhhh::hhhh/nn).
+ If this constraint is not present then
+ certificates may be presented from any
+ source address.
+
+$OpenBSD: PROTOCOL.certkeys,v 1.3 2010/03/03 22:50:40 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.mux b/crypto/openssh/PROTOCOL.mux
new file mode 100644
index 0000000..d22f737
--- /dev/null
+++ b/crypto/openssh/PROTOCOL.mux
@@ -0,0 +1,196 @@
+This document describes the multiplexing protocol used by ssh(1)'s
+ControlMaster connection-sharing.
+
+Most messages from the client to the server contain a "request id" field.
+This field is returned in replies as "client request id" to facilitate
+matching of responses to requests.
+
+1. Connection setup
+
+When a multiplexing connection is made to a ssh(1) operating as a
+ControlMaster from a ssh(1) in multiplex slave mode, the first
+action of each is to exchange hello messages:
+
+ uint32 MUX_MSG_HELLO
+ uint32 protocol version
+ string extension name [optional]
+ string extension value [optional]
+ ...
+
+The current version of the mux protocol is 4. A slave should refuse
+to connect to a master that speaks an unsupported protocol version.
+Following the version identifier are zero or more extensions
+represented as a name/value pair. No extensions are currently
+defined.
+
+2. Opening sessions
+
+To open a new multiplexed session, a client may send the following
+request:
+
+ uint32 MUX_C_MSG_NEW_SESSION
+ uint32 request id
+ string reserved
+ bool want tty flag
+ bool want X11 forwarding flag
+ bool want agent flag
+ bool subsystem flag
+ uint32 escape char
+ string terminal type
+ string command
+ string environment string 0 [optional]
+ ...
+
+To disable the use of an escape character, "escape char" may be set
+to 0xffffffff. "terminal type" is generally set to the value of
+$TERM. zero or more environment strings may follow the command.
+
+The client then sends its standard input, output and error file
+descriptors (in that order) using Unix domain socket control messages.
+
+The contents of "reserved" are currently ignored.
+
+If successful, the server will reply with MUX_S_SESSION_OPENED
+
+ uint32 MUX_S_SESSION_OPENED
+ uint32 client request id
+ uint32 session id
+
+Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or
+MUX_S_FAILURE.
+
+Once the server has received the fds, it will respond with MUX_S_OK
+indicating that the session is up. The client now waits for the
+session to end. When it does, the server will send an exit status
+message:
+
+ uint32 MUX_S_EXIT_MESSAGE
+ uint32 session id
+ uint32 exit value
+
+The client should exit with this value to mimic the behaviour of a
+non-multiplexed ssh(1) connection. Two additional cases that the
+client must cope with are it receiving a signal itself and the
+server disconnecting without sending an exit message.
+
+3. Health checks
+
+The client may request a health check/PID report from a server:
+
+ uint32 MUX_C_ALIVE_CHECK
+ uint32 request id
+
+The server replies with:
+
+ uint32 MUX_S_ALIVE
+ uint32 client request id
+ uint32 server pid
+
+4. Remotely terminating a master
+
+A client may request that a master terminate immediately:
+
+ uint32 MUX_C_TERMINATE
+ uint32 request id
+
+The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
+
+5. Requesting establishment of port forwards
+
+A client may request the master to establish a port forward:
+
+ uint32 MUX_C_OPEN_FORWARD
+ uint32 request id
+ uint32 forwarding type
+ string listen host
+ string listen port
+ string connect host
+ string connect port
+
+forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
+
+A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
+MUX_S_FAILURE.
+
+5. Requesting closure of port forwards
+
+A client may request the master to establish a port forward:
+
+ uint32 MUX_C_OPEN_FORWARD
+ uint32 request id
+ uint32 forwarding type
+ string listen host
+ string listen port
+ string connect host
+ string connect port
+
+forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
+
+A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
+MUX_S_FAILURE.
+
+6. Requesting stdio forwarding
+
+A client may request the master to establish a stdio forwarding:
+
+ uint32 MUX_C_NEW_STDIO_FWD
+ uint32 request id
+ string reserved
+ string connect host
+ string connect port
+
+The client then sends its standard input and output file descriptors
+(in that order) using Unix domain socket control messages.
+
+The contents of "reserved" are currently ignored.
+
+A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED
+or a MUX_S_FAILURE.
+
+7. Status messages
+
+The MUX_S_OK message is empty:
+
+ uint32 MUX_S_OK
+ uint32 client request id
+
+The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
+
+ uint32 MUX_S_PERMISSION_DENIED
+ uint32 client request id
+ string reason
+
+ uint32 MUX_S_FAILURE
+ uint32 client request id
+ string reason
+
+7. Protocol numbers
+
+#define MUX_MSG_HELLO 0x00000001
+#define MUX_C_NEW_SESSION 0x10000002
+#define MUX_C_ALIVE_CHECK 0x10000004
+#define MUX_C_TERMINATE 0x10000005
+#define MUX_C_OPEN_FORWARD 0x10000006
+#define MUX_C_CLOSE_FORWARD 0x10000007
+#define MUX_S_OK 0x80000001
+#define MUX_S_PERMISSION_DENIED 0x80000002
+#define MUX_S_FAILURE 0x80000003
+#define MUX_S_EXIT_MESSAGE 0x80000004
+#define MUX_S_ALIVE 0x80000005
+#define MUX_S_SESSION_OPENED 0x80000006
+
+#define MUX_FWD_LOCAL 1
+#define MUX_FWD_REMOTE 2
+#define MUX_FWD_DYNAMIC 3
+
+XXX TODO
+XXX extended status (e.g. report open channels / forwards)
+XXX graceful close (delete listening socket, but keep existing sessions active)
+XXX lock (maybe)
+XXX watch in/out traffic (pre/post crypto)
+XXX inject packet (what about replies)
+XXX server->client error/warning notifications
+XXX port0 rfwd (need custom response message)
+XXX send signals via mux
+
+$OpenBSD: PROTOCOL.mux,v 1.1 2010/01/26 01:28:35 djm Exp $
diff --git a/crypto/openssh/README b/crypto/openssh/README
index 8538e8c..0ecb670 100644
--- a/crypto/openssh/README
+++ b/crypto/openssh/README
@@ -1,4 +1,4 @@
-See http://www.openssh.com/txt/release-5.3 for the release notes.
+See http://www.openssh.com/txt/release-5.4 for the release notes.
- A Japanese translation of this document and of the OpenSSH FAQ is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@@ -62,4 +62,4 @@ References -
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
[7] http://www.openssh.com/faq.html
-$Id: README,v 1.70.4.1 2009/09/26 04:11:47 djm Exp $
+$Id: README,v 1.72 2010/03/07 22:41:02 djm Exp $
diff --git a/crypto/openssh/README.smartcard b/crypto/openssh/README.smartcard
deleted file mode 100644
index fdf83ec..0000000
--- a/crypto/openssh/README.smartcard
+++ /dev/null
@@ -1,93 +0,0 @@
-How to use smartcards with OpenSSH?
-
-OpenSSH contains experimental support for authentication using
-Cyberflex smartcards and TODOS card readers, in addition to the cards
-with PKCS#15 structure supported by OpenSC. To enable this you
-need to:
-
-Using libsectok:
-
-(1) enable sectok support in OpenSSH:
-
- $ ./configure --with-sectok
-
-(2) If you have used a previous version of ssh with your card, you
- must remove the old applet and keys.
-
- $ sectok
- sectok> login -d
- sectok> junload Ssh.bin
- sectok> delete 0012
- sectok> delete sh
- sectok> quit
-
-(3) load the Java Cardlet to the Cyberflex card and set card passphrase:
-
- $ sectok
- sectok> login -d
- sectok> jload /usr/libdata/ssh/Ssh.bin
- sectok> setpass
- Enter new AUT0 passphrase:
- Re-enter passphrase:
- sectok> quit
-
- Do not forget the passphrase. There is no way to
- recover if you do.
-
- IMPORTANT WARNING: If you attempt to login with the
- wrong passphrase three times in a row, you will
- destroy your card.
-
-(4) load a RSA key to the card:
-
- $ ssh-keygen -f /path/to/rsakey -U 1
- (where 1 is the reader number, you can also try 0)
-
- In spite of the name, this does not generate a key.
- It just loads an already existing key on to the card.
-
-(5) Optional: If you don't want to use a card passphrase, change the
- acl on the private key file:
-
- $ sectok
- sectok> login -d
- sectok> acl 0012 world: w
- world: w
- AUT0: w inval
- sectok> quit
-
- If you do this, anyone who has access to your card
- can assume your identity. This is not recommended.
-
-
-Using OpenSC:
-
-(1) install OpenSC:
-
- Sources and instructions are available from
- http://www.opensc.org/
-
-(2) enable OpenSC support in OpenSSH:
-
- $ ./configure --with-opensc[=/path/to/opensc] [options]
-
-(3) load a RSA key to the card:
-
- Not supported yet.
-
-
-Common operations:
-
-(1) tell the ssh client to use the card reader:
-
- $ ssh -I 1 otherhost
-
-(2) or tell the agent (don't forget to restart) to use the smartcard:
-
- $ ssh-add -s 1
-
-
--markus,
-Tue Jul 17 23:54:51 CEST 2001
-
-$OpenBSD: README.smartcard,v 1.9 2003/11/21 11:57:02 djm Exp $
diff --git a/crypto/openssh/addrmatch.c b/crypto/openssh/addrmatch.c
index d39885b..5b6773c 100644
--- a/crypto/openssh/addrmatch.c
+++ b/crypto/openssh/addrmatch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */
+/* $OpenBSD: addrmatch.c,v 1.5 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
@@ -126,6 +126,8 @@ addr_netmask(int af, u_int l, struct xaddr *n)
switch (af) {
case AF_INET:
n->af = AF_INET;
+ if (l == 0)
+ return 0;
n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
return 0;
case AF_INET6:
@@ -422,3 +424,77 @@ addr_match_list(const char *addr, const char *_list)
return ret;
}
+
+/*
+ * Match "addr" against list CIDR list "_list". Lexical wildcards and
+ * negation are not supported. If "addr" == NULL, will verify structure
+ * of "_list".
+ *
+ * Returns 1 on match found (never returned when addr == NULL).
+ * Returns 0 on if no match found, or no errors found when addr == NULL.
+ * Returns -1 on error
+ */
+int
+addr_match_cidr_list(const char *addr, const char *_list)
+{
+ char *list, *cp, *o;
+ struct xaddr try_addr, match_addr;
+ u_int masklen;
+ int ret = 0, r;
+
+ if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
+ debug2("%s: couldn't parse address %.100s", __func__, addr);
+ return 0;
+ }
+ if ((o = list = strdup(_list)) == NULL)
+ return -1;
+ while ((cp = strsep(&list, ",")) != NULL) {
+ if (*cp == '\0') {
+ error("%s: empty entry in list \"%.100s\"",
+ __func__, o);
+ ret = -1;
+ break;
+ }
+
+ /*
+ * NB. This function is called in pre-auth with untrusted data,
+ * so be extra paranoid about junk reaching getaddrino (via
+ * addr_pton_cidr).
+ */
+
+ /* Stop junk from reaching getaddrinfo. +3 is for masklen */
+ if (strlen(cp) > INET6_ADDRSTRLEN + 3) {
+ error("%s: list entry \"%.100s\" too long",
+ __func__, cp);
+ ret = -1;
+ break;
+ }
+#define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/"
+ if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) {
+ error("%s: list entry \"%.100s\" contains invalid "
+ "characters", __func__, cp);
+ ret = -1;
+ }
+
+ /* Prefer CIDR address matching */
+ r = addr_pton_cidr(cp, &match_addr, &masklen);
+ if (r == -1) {
+ error("Invalid network entry \"%.100s\"", cp);
+ ret = -1;
+ break;
+ } else if (r == -2) {
+ error("Inconsistent mask length for "
+ "network \"%.100s\"", cp);
+ ret = -1;
+ break;
+ } else if (r == 0 && addr != NULL) {
+ if (addr_netmatch(&try_addr, &match_addr,
+ masklen) == 0)
+ ret = 1;
+ continue;
+ }
+ }
+ xfree(o);
+
+ return ret;
+}
diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c
index 8682881..d019fe2 100644
--- a/crypto/openssh/auth-krb5.c
+++ b/crypto/openssh/auth-krb5.c
@@ -78,6 +78,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
krb5_error_code problem;
krb5_ccache ccache = NULL;
int len;
+ char *client, *platform_client;
+
+ /* get platform-specific kerberos client principal name (if it exists) */
+ platform_client = platform_krb5_get_principal_name(authctxt->pw->pw_name);
+ client = platform_client ? platform_client : authctxt->pw->pw_name;
temporarily_use_uid(authctxt->pw);
@@ -85,7 +90,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
if (problem)
goto out;
- problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
+ problem = krb5_parse_name(authctxt->krb5_ctx, client,
&authctxt->krb5_user);
if (problem)
goto out;
@@ -141,8 +146,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
if (problem)
goto out;
- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
- authctxt->pw->pw_name)) {
+ if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) {
problem = -1;
goto out;
}
@@ -176,6 +180,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
out:
restore_uid();
+
+ if (platform_client != NULL)
+ xfree(platform_client);
if (problem) {
if (ccache)
diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c
index ab085c2..1293017 100644
--- a/crypto/openssh/auth-options.c
+++ b/crypto/openssh/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.48 2010/03/07 11:57:13 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -44,6 +44,7 @@ int no_agent_forwarding_flag = 0;
int no_x11_forwarding_flag = 0;
int no_pty_flag = 0;
int no_user_rc = 0;
+int key_is_cert_authority = 0;
/* "command=" option. */
char *forced_command = NULL;
@@ -64,6 +65,7 @@ auth_clear_options(void)
no_pty_flag = 0;
no_x11_forwarding_flag = 0;
no_user_rc = 0;
+ key_is_cert_authority = 0;
while (custom_environment) {
struct envstring *ce = custom_environment;
custom_environment = ce->next;
@@ -76,7 +78,6 @@ auth_clear_options(void)
}
forced_tun_device = -1;
channel_clear_permitted_opens();
- auth_debug_reset();
}
/*
@@ -96,6 +97,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
return 1;
while (*opts && *opts != ' ' && *opts != '\t') {
+ cp = "cert-authority";
+ if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ key_is_cert_authority = 1;
+ opts += strlen(cp);
+ goto next_option;
+ }
cp = "no-port-forwarding";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
auth_debug_add("Port forwarding disabled.");
@@ -356,9 +363,6 @@ next_option:
/* Process the next option. */
}
- if (!use_privsep)
- auth_debug_send();
-
/* grant access */
return 1;
@@ -368,9 +372,158 @@ bad_option:
auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
file, linenum, opts);
- if (!use_privsep)
- auth_debug_send();
-
/* deny access */
return 0;
}
+
+/*
+ * Set options from certificate constraints. These supersede user key options
+ * so this must be called after auth_parse_options().
+ */
+int
+auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
+{
+ u_char *name = NULL, *data_blob = NULL;
+ u_int nlen, dlen, clen;
+ Buffer c, data;
+ int ret = -1;
+
+ int cert_no_port_forwarding_flag = 1;
+ int cert_no_agent_forwarding_flag = 1;
+ int cert_no_x11_forwarding_flag = 1;
+ int cert_no_pty_flag = 1;
+ int cert_no_user_rc = 1;
+ char *cert_forced_command = NULL;
+ int cert_source_address_done = 0;
+
+ buffer_init(&data);
+
+ /* Make copy to avoid altering original */
+ buffer_init(&c);
+ buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
+
+ while (buffer_len(&c) > 0) {
+ if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
+ (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
+ error("Certificate constraints corrupt");
+ goto out;
+ }
+ buffer_append(&data, data_blob, dlen);
+ debug3("found certificate constraint \"%.100s\" len %u",
+ name, dlen);
+ if (strlen(name) != nlen) {
+ error("Certificate constraint name contains \\0");
+ goto out;
+ }
+ if (strcmp(name, "permit-X11-forwarding") == 0)
+ cert_no_x11_forwarding_flag = 0;
+ else if (strcmp(name, "permit-agent-forwarding") == 0)
+ cert_no_agent_forwarding_flag = 0;
+ else if (strcmp(name, "permit-port-forwarding") == 0)
+ cert_no_port_forwarding_flag = 0;
+ else if (strcmp(name, "permit-pty") == 0)
+ cert_no_pty_flag = 0;
+ else if (strcmp(name, "permit-user-rc") == 0)
+ cert_no_user_rc = 0;
+ else if (strcmp(name, "force-command") == 0) {
+ char *command = buffer_get_string_ret(&data, &clen);
+
+ if (command == NULL) {
+ error("Certificate constraint \"%s\" corrupt",
+ name);
+ goto out;
+ }
+ if (strlen(command) != clen) {
+ error("force-command constrain contains \\0");
+ goto out;
+ }
+ if (cert_forced_command != NULL) {
+ error("Certificate has multiple "
+ "force-command constraints");
+ xfree(command);
+ goto out;
+ }
+ cert_forced_command = command;
+ } else if (strcmp(name, "source-address") == 0) {
+ char *allowed = buffer_get_string_ret(&data, &clen);
+ const char *remote_ip = get_remote_ipaddr();
+
+ if (allowed == NULL) {
+ error("Certificate constraint \"%s\" corrupt",
+ name);
+ goto out;
+ }
+ if (strlen(allowed) != clen) {
+ error("source-address constrain contains \\0");
+ goto out;
+ }
+ if (cert_source_address_done++) {
+ error("Certificate has multiple "
+ "source-address constraints");
+ xfree(allowed);
+ goto out;
+ }
+ switch (addr_match_cidr_list(remote_ip, allowed)) {
+ case 1:
+ /* accepted */
+ xfree(allowed);
+ break;
+ case 0:
+ /* no match */
+ logit("Authentication tried for %.100s with "
+ "valid certificate but not from a "
+ "permitted host (ip=%.200s).",
+ pw->pw_name, remote_ip);
+ auth_debug_add("Your address '%.200s' is not "
+ "permitted to use this certificate for "
+ "login.", remote_ip);
+ xfree(allowed);
+ goto out;
+ case -1:
+ error("Certificate source-address contents "
+ "invalid");
+ xfree(allowed);
+ goto out;
+ }
+ } else {
+ error("Certificate constraint \"%s\" is not supported",
+ name);
+ goto out;
+ }
+
+ if (buffer_len(&data) != 0) {
+ error("Certificate constraint \"%s\" corrupt "
+ "(extra data)", name);
+ goto out;
+ }
+ buffer_clear(&data);
+ xfree(name);
+ xfree(data_blob);
+ name = data_blob = NULL;
+ }
+
+ /* successfully parsed all constraints */
+ ret = 0;
+
+ no_port_forwarding_flag |= cert_no_port_forwarding_flag;
+ no_agent_forwarding_flag |= cert_no_agent_forwarding_flag;
+ no_x11_forwarding_flag |= cert_no_x11_forwarding_flag;
+ no_pty_flag |= cert_no_pty_flag;
+ no_user_rc |= cert_no_user_rc;
+ /* CA-specified forced command supersedes key option */
+ if (cert_forced_command != NULL) {
+ if (forced_command != NULL)
+ xfree(forced_command);
+ forced_command = cert_forced_command;
+ }
+
+ out:
+ if (name != NULL)
+ xfree(name);
+ if (data_blob != NULL)
+ xfree(data_blob);
+ buffer_free(&data);
+ buffer_free(&c);
+ return ret;
+}
+
diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h
index 14488f7..694edc8 100644
--- a/crypto/openssh/auth-options.h
+++ b/crypto/openssh/auth-options.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.h,v 1.17 2008/03/26 21:28:14 djm Exp $ */
+/* $OpenBSD: auth-options.h,v 1.18 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -30,8 +30,10 @@ extern int no_user_rc;
extern char *forced_command;
extern struct envstring *custom_environment;
extern int forced_tun_device;
+extern int key_is_cert_authority;
int auth_parse_options(struct passwd *, char *, char *, u_long);
void auth_clear_options(void);
+int auth_cert_constraints(Buffer *, struct passwd *);
#endif
diff --git a/crypto/openssh/auth-rh-rsa.c b/crypto/openssh/auth-rh-rsa.c
index eca7502..b21a0f4 100644
--- a/crypto/openssh/auth-rh-rsa.c
+++ b/crypto/openssh/auth-rh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rh-rsa.c,v 1.42 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth-rh-rsa.c,v 1.43 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -44,6 +44,9 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
{
HostStatus host_status;
+ if (auth_key_is_revoked(client_host_key))
+ return 0;
+
/* Check if we would accept it using rhosts authentication. */
if (!auth_rhosts(pw, cuser))
return 0;
diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c
index 5c12967..06ae7f0 100644
--- a/crypto/openssh/auth-rhosts.c
+++ b/crypto/openssh/auth-rhosts.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rhosts.c,v 1.43 2008/06/13 14:18:51 dtucker Exp $ */
+/* $OpenBSD: auth-rhosts.c,v 1.44 2010/03/07 11:57:13 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -317,11 +317,5 @@ int
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
const char *ipaddr)
{
- int ret;
-
- auth_debug_reset();
- ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
- if (!use_privsep)
- auth_debug_send();
- return ret;
+ return auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
}
diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c
index bf54620..65571a8 100644
--- a/crypto/openssh/auth-rsa.c
+++ b/crypto/openssh/auth-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rsa.c,v 1.73 2008/07/02 12:03:51 dtucker Exp $ */
+/* $OpenBSD: auth-rsa.c,v 1.74 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -94,6 +94,9 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
MD5_CTX md;
int len;
+ if (auth_key_is_revoked(key))
+ return 0;
+
/* don't allow short keys */
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c
index 02f9175..2917414 100644
--- a/crypto/openssh/auth.c
+++ b/crypto/openssh/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -70,6 +70,7 @@ __RCSID("$FreeBSD$");
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
+#include "authfile.h"
#include "monitor_wrap.h"
/* import */
@@ -96,7 +97,6 @@ allowed_user(struct passwd * pw)
{
struct stat st;
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
- char *shell;
u_int i;
#ifdef USE_SHADOW
struct spwd *spw = NULL;
@@ -154,22 +154,28 @@ allowed_user(struct passwd * pw)
}
/*
- * Get the shell from the password data. An empty shell field is
- * legal, and means /bin/sh.
+ * Deny if shell does not exist or is not executable unless we
+ * are chrooting.
*/
- shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
-
- /* deny if shell does not exists or is not executable */
- if (stat(shell, &st) != 0) {
- logit("User %.100s not allowed because shell %.100s does not exist",
- pw->pw_name, shell);
- return 0;
- }
- if (S_ISREG(st.st_mode) == 0 ||
- (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
- logit("User %.100s not allowed because shell %.100s is not executable",
- pw->pw_name, shell);
- return 0;
+ if (options.chroot_directory == NULL ||
+ strcasecmp(options.chroot_directory, "none") == 0) {
+ char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
+ _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */
+
+ if (stat(shell, &st) != 0) {
+ logit("User %.100s not allowed because shell %.100s "
+ "does not exist", pw->pw_name, shell);
+ xfree(shell);
+ return 0;
+ }
+ if (S_ISREG(st.st_mode) == 0 ||
+ (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
+ logit("User %.100s not allowed because shell %.100s "
+ "is not executable", pw->pw_name, shell);
+ xfree(shell);
+ return 0;
+ }
+ xfree(shell);
}
if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
@@ -456,7 +462,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
return -1;
}
- /* If are passed the homedir then we can stop */
+ /* If are past the homedir then we can stop */
if (comparehome && strcmp(homedir, buf) == 0) {
debug3("secure_filename: terminating check at '%s'",
buf);
@@ -484,8 +490,12 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
* Open the file containing the authorized keys
* Fail quietly if file does not exist
*/
- if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1)
+ if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
+ if (errno != ENOENT)
+ debug("Could not open keyfile '%s': %s", file,
+ strerror(errno));
return NULL;
+ }
if (fstat(fd, &st) < 0) {
close(fd);
@@ -526,7 +536,28 @@ getpwnamallow(const char *user)
parse_server_match_config(&options, user,
get_canonical_hostname(options.use_dns), get_remote_ipaddr());
+#if defined(_AIX) && defined(HAVE_SETAUTHDB)
+ aix_setauthdb(user);
+#endif
+
pw = getpwnam(user);
+
+#if defined(_AIX) && defined(HAVE_SETAUTHDB)
+ aix_restoreauthdb();
+#endif
+#ifdef HAVE_CYGWIN
+ /*
+ * Windows usernames are case-insensitive. To avoid later problems
+ * when trying to match the username, the user is only allowed to
+ * login if the username is given in the same case as stored in the
+ * user database.
+ */
+ if (pw != NULL && strcmp(user, pw->pw_name) != 0) {
+ logit("Login name %.100s does not match stored username %.100s",
+ user, pw->pw_name);
+ pw = NULL;
+ }
+#endif
if (pw == NULL) {
logit("Invalid user %.100s from %.100s",
user, get_remote_ipaddr());
@@ -561,6 +592,35 @@ getpwnamallow(const char *user)
return (NULL);
}
+/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
+int
+auth_key_is_revoked(Key *key)
+{
+ char *key_fp;
+
+ if (options.revoked_keys_file == NULL)
+ return 0;
+
+ switch (key_in_file(key, options.revoked_keys_file, 0)) {
+ case 0:
+ /* key not revoked */
+ return 0;
+ case -1:
+ /* Error opening revoked_keys_file: refuse all keys */
+ error("Revoked keys file is unreadable: refusing public key "
+ "authentication");
+ return 1;
+ case 1:
+ /* Key revoked */
+ key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ error("WARNING: authentication attempt with a revoked "
+ "%s key %s ", key_type(key), key_fp);
+ xfree(key_fp);
+ return 1;
+ }
+ fatal("key_in_file returned junk");
+}
+
void
auth_debug_add(const char *fmt,...)
{
diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h
index 3a70f44..a65b87d 100644
--- a/crypto/openssh/auth.h
+++ b/crypto/openssh/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.62 2008/11/04 08:22:12 djm Exp $ */
+/* $OpenBSD: auth.h,v 1.65 2010/03/04 10:36:03 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -171,6 +171,7 @@ char *authorized_keys_file(struct passwd *);
char *authorized_keys_file2(struct passwd *);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
+int auth_key_is_revoked(Key *);
HostStatus
check_key_in_hostfiles(struct passwd *, Key *, const char *,
@@ -178,7 +179,8 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *,
/* hostkey handling */
Key *get_hostkey_by_index(int);
-Key *get_hostkey_by_type(int);
+Key *get_hostkey_public_by_type(int);
+Key *get_hostkey_private_by_type(int);
int get_hostkey_index(Key *);
int ssh1_session_key(BIGNUM *);
diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c
index 041051c..7216465 100644
--- a/crypto/openssh/auth2-hostbased.c
+++ b/crypto/openssh/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.12 2008/07/17 08:51:07 djm Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.13 2010/03/04 10:36:03 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -145,6 +145,9 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
HostStatus host_status;
int len;
+ if (auth_key_is_revoked(key))
+ return 0;
+
resolvedname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c
index 2886f12..51aa774 100644
--- a/crypto/openssh/auth2-pubkey.c
+++ b/crypto/openssh/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -32,6 +32,8 @@
#include <pwd.h>
#include <stdio.h>
#include <stdarg.h>
+#include <string.h>
+#include <time.h>
#include <unistd.h>
#include "xmalloc.h"
@@ -54,6 +56,7 @@
#endif
#include "monitor_wrap.h"
#include "misc.h"
+#include "authfile.h"
/* import */
extern ServerOptions options;
@@ -178,6 +181,7 @@ static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
char line[SSH_MAX_PUBKEY_BYTES];
+ const char *reason;
int found_key = 0;
FILE *f;
u_long linenum = 0;
@@ -196,11 +200,13 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
}
found_key = 0;
- found = key_new(key->type);
+ found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
char *cp, *key_options = NULL;
+ auth_clear_options();
+
/* Skip leading whitespace, empty and comment lines. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
;
@@ -227,8 +233,32 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
continue;
}
}
- if (key_equal(found, key) &&
- auth_parse_options(pw, key_options, file, linenum) == 1) {
+ if (auth_parse_options(pw, key_options, file, linenum) != 1)
+ continue;
+ if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) {
+ if (!key_is_cert_authority)
+ continue;
+ if (!key_equal(found, key->cert->signature_key))
+ continue;
+ debug("matching CA found: file %s, line %lu",
+ file, linenum);
+ fp = key_fingerprint(found, SSH_FP_MD5,
+ SSH_FP_HEX);
+ verbose("Found matching %s CA: %s",
+ key_type(found), fp);
+ xfree(fp);
+ if (key_cert_check_authority(key, 0, 0, pw->pw_name,
+ &reason) != 0) {
+ error("%s", reason);
+ auth_debug_add("%s", reason);
+ continue;
+ }
+ if (auth_cert_constraints(&key->cert->constraints,
+ pw) != 0)
+ continue;
+ found_key = 1;
+ break;
+ } else if (!key_is_cert_authority && key_equal(found, key)) {
found_key = 1;
debug("matching key found: file %s, line %lu",
file, linenum);
@@ -247,6 +277,47 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
return found_key;
}
+/* Authenticate a certificate key against TrustedUserCAKeys */
+static int
+user_cert_trusted_ca(struct passwd *pw, Key *key)
+{
+ char *key_fp, *ca_fp;
+ const char *reason;
+ int ret = 0;
+
+ if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
+ return 0;
+
+ key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+
+ if (key_in_file(key->cert->signature_key,
+ options.trusted_user_ca_keys, 1) != 1) {
+ debug2("%s: CA %s %s is not listed in %s", __func__,
+ key_type(key->cert->signature_key), ca_fp,
+ options.trusted_user_ca_keys);
+ goto out;
+ }
+ if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) {
+ error("%s", reason);
+ auth_debug_add("%s", reason);
+ goto out;
+ }
+ if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
+ goto out;
+
+ verbose("%s certificate %s allowed by trusted %s key %s",
+ key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp);
+ ret = 1;
+
+ out:
+ if (key_fp != NULL)
+ xfree(key_fp);
+ if (ca_fp != NULL)
+ xfree(ca_fp);
+ return ret;
+}
+
/* check whether given key is in .ssh/authorized_keys* */
int
user_key_allowed(struct passwd *pw, Key *key)
@@ -254,6 +325,15 @@ user_key_allowed(struct passwd *pw, Key *key)
int success;
char *file;
+ if (auth_key_is_revoked(key))
+ return 0;
+ if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
+ return 0;
+
+ success = user_cert_trusted_ca(pw, key);
+ if (success)
+ return success;
+
file = authorized_keys_file(pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c
index 61faad1..28a8cf2 100644
--- a/crypto/openssh/authfd.c
+++ b/crypto/openssh/authfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.c,v 1.80 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: authfd.c,v 1.82 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -483,6 +483,16 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_put_bignum2(b, key->rsa->p);
buffer_put_bignum2(b, key->rsa->q);
break;
+ case KEY_RSA_CERT:
+ if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
+ fatal("%s: no cert/certblob", __func__);
+ buffer_put_string(b, buffer_ptr(&key->cert->certblob),
+ buffer_len(&key->cert->certblob));
+ buffer_put_bignum2(b, key->rsa->d);
+ buffer_put_bignum2(b, key->rsa->iqmp);
+ buffer_put_bignum2(b, key->rsa->p);
+ buffer_put_bignum2(b, key->rsa->q);
+ break;
case KEY_DSA:
buffer_put_bignum2(b, key->dsa->p);
buffer_put_bignum2(b, key->dsa->q);
@@ -490,6 +500,13 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_put_bignum2(b, key->dsa->pub_key);
buffer_put_bignum2(b, key->dsa->priv_key);
break;
+ case KEY_DSA_CERT:
+ if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
+ fatal("%s: no cert/certblob", __func__);
+ buffer_put_string(b, buffer_ptr(&key->cert->certblob),
+ buffer_len(&key->cert->certblob));
+ buffer_put_bignum2(b, key->dsa->priv_key);
+ break;
}
buffer_put_cstring(b, comment);
}
@@ -517,7 +534,9 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
ssh_encode_identity_rsa1(&msg, key->rsa, comment);
break;
case KEY_RSA:
+ case KEY_RSA_CERT:
case KEY_DSA:
+ case KEY_DSA_CERT:
type = constrained ?
SSH2_AGENTC_ADD_ID_CONSTRAINED :
SSH2_AGENTC_ADD_IDENTITY;
@@ -545,12 +564,6 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
return decode_reply(type);
}
-int
-ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
-{
- return ssh_add_identity_constrained(auth, key, comment, 0, 0);
-}
-
/*
* Removes an identity from the authentication server. This call is not
* meant to be used by normal applications.
@@ -571,7 +584,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
buffer_put_int(&msg, BN_num_bits(key->rsa->n));
buffer_put_bignum(&msg, key->rsa->e);
buffer_put_bignum(&msg, key->rsa->n);
- } else if (key->type == KEY_DSA || key->type == KEY_RSA) {
+ } else if (key_type_plain(key->type) == KEY_DSA ||
+ key_type_plain(key->type) == KEY_RSA) {
key_to_blob(key, &blob, &blen);
buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
buffer_put_string(&msg, blob, blen);
diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h
index 3da2561..2582a27 100644
--- a/crypto/openssh/authfd.h
+++ b/crypto/openssh/authfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.h,v 1.36 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: authfd.h,v 1.37 2009/08/27 17:44:52 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -75,7 +75,6 @@ void ssh_close_authentication_connection(AuthenticationConnection *);
int ssh_get_num_identities(AuthenticationConnection *, int);
Key *ssh_get_first_identity(AuthenticationConnection *, char **, int);
Key *ssh_get_next_identity(AuthenticationConnection *, char **, int);
-int ssh_add_identity(AuthenticationConnection *, Key *, const char *);
int ssh_add_identity_constrained(AuthenticationConnection *, Key *,
const char *, u_int, u_int);
int ssh_remove_identity(AuthenticationConnection *, Key *);
diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c
index 735c647..224c6aa 100644
--- a/crypto/openssh/authfile.c
+++ b/crypto/openssh/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.76 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -47,6 +47,9 @@
#include <openssl/evp.h>
#include <openssl/pem.h>
+/* compatibility with old or broken OpenSSL versions */
+#include "openbsd-compat/openssl-compat.h"
+
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
@@ -184,7 +187,11 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
int success = 0;
int len = strlen(_passphrase);
u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
+#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
+#else
+ const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
+#endif
if (len > 0 && len <= 4) {
error("passphrase too short: have %d bytes, need > 4", len);
@@ -552,8 +559,13 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
int fd;
fd = open(filename, O_RDONLY);
- if (fd < 0)
+ if (fd < 0) {
+ debug("could not open key file '%s': %s", filename,
+ strerror(errno));
+ if (perm_ok != NULL)
+ *perm_ok = 0;
return NULL;
+ }
if (!key_perm_ok(fd, filename)) {
if (perm_ok != NULL)
*perm_ok = 0;
@@ -588,8 +600,11 @@ key_load_private(const char *filename, const char *passphrase,
int fd;
fd = open(filename, O_RDONLY);
- if (fd < 0)
+ if (fd < 0) {
+ debug("could not open key file '%s': %s", filename,
+ strerror(errno));
return NULL;
+ }
if (!key_perm_ok(fd, filename)) {
error("bad permissions: ignore key: %s", filename);
close(fd);
@@ -677,3 +692,65 @@ key_load_public(const char *filename, char **commentp)
key_free(pub);
return NULL;
}
+
+/*
+ * Returns 1 if the specified "key" is listed in the file "filename",
+ * 0 if the key is not listed or -1 on error.
+ * If strict_type is set then the key type must match exactly,
+ * otherwise a comparison that ignores certficiate data is performed.
+ */
+int
+key_in_file(Key *key, const char *filename, int strict_type)
+{
+ FILE *f;
+ char line[SSH_MAX_PUBKEY_BYTES];
+ char *cp;
+ u_long linenum = 0;
+ int ret = 0;
+ Key *pub;
+ int (*key_compare)(const Key *, const Key *) = strict_type ?
+ key_equal : key_equal_public;
+
+ if ((f = fopen(filename, "r")) == NULL) {
+ if (errno == ENOENT) {
+ debug("%s: keyfile \"%s\" missing", __func__, filename);
+ return 0;
+ } else {
+ error("%s: could not open keyfile \"%s\": %s", __func__,
+ filename, strerror(errno));
+ return -1;
+ }
+ }
+
+ while (read_keyfile_line(f, filename, line, sizeof(line),
+ &linenum) != -1) {
+ cp = line;
+
+ /* Skip leading whitespace. */
+ for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
+ ;
+
+ /* Skip comments and empty lines */
+ switch (*cp) {
+ case '#':
+ case '\n':
+ case '\0':
+ continue;
+ }
+
+ pub = key_new(KEY_UNSPEC);
+ if (key_read(pub, &cp) != 1) {
+ key_free(pub);
+ continue;
+ }
+ if (key_compare(key, pub)) {
+ ret = 1;
+ key_free(pub);
+ break;
+ }
+ key_free(pub);
+ }
+ fclose(f);
+ return ret;
+}
+
diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h
index a6c7493..6dfa478 100644
--- a/crypto/openssh/authfile.h
+++ b/crypto/openssh/authfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.h,v 1.13 2006/04/25 08:02:27 dtucker Exp $ */
+/* $OpenBSD: authfile.h,v 1.14 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -22,5 +22,6 @@ Key *key_load_private(const char *, const char *, char **);
Key *key_load_private_type(int, const char *, const char *, char **, int *);
Key *key_load_private_pem(int, int, const char *, char **);
int key_perm_ok(int, const char *);
+int key_in_file(Key *, const char *, int);
#endif
diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c
index cd9a35d..4ef19c4 100644
--- a/crypto/openssh/bufaux.c
+++ b/crypto/openssh/bufaux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bufaux.c,v 1.46 2008/06/10 23:21:34 dtucker Exp $ */
+/* $OpenBSD: bufaux.c,v 1.48 2010/02/02 22:49:34 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -166,7 +166,10 @@ buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
u_int len;
/* Get the length. */
- len = buffer_get_int(buffer);
+ if (buffer_get_int_ret(&len, buffer) != 0) {
+ error("buffer_get_string_ret: cannot extract length");
+ return (NULL);
+ }
if (len > 256 * 1024) {
error("buffer_get_string_ret: bad string length %u", len);
return (NULL);
@@ -198,14 +201,17 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
}
void *
-buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
+buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
{
void *ptr;
u_int len;
- len = buffer_get_int(buffer);
- if (len > 256 * 1024)
- fatal("buffer_get_string_ptr: bad string length %u", len);
+ if (buffer_get_int_ret(&len, buffer) != 0)
+ return NULL;
+ if (len > 256 * 1024) {
+ error("buffer_get_string_ptr: bad string length %u", len);
+ return NULL;
+ }
ptr = buffer_ptr(buffer);
buffer_consume(buffer, len);
if (length_ptr)
@@ -213,6 +219,16 @@ buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
return (ptr);
}
+void *
+buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
+{
+ void *ret;
+
+ if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL)
+ fatal("buffer_get_string_ptr: buffer error");
+ return (ret);
+}
+
/*
* Stores and arbitrary binary string in the buffer.
*/
diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c
index e02e1e3..ae97003 100644
--- a/crypto/openssh/buffer.c
+++ b/crypto/openssh/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: buffer.c,v 1.32 2010/02/09 03:56:28 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -160,7 +160,7 @@ buffer_check_alloc(Buffer *buffer, u_int len)
/* Returns the number of bytes of data in the buffer. */
u_int
-buffer_len(Buffer *buffer)
+buffer_len(const Buffer *buffer)
{
return buffer->end - buffer->offset;
}
@@ -228,7 +228,7 @@ buffer_consume_end(Buffer *buffer, u_int bytes)
/* Returns a pointer to the first used byte in the buffer. */
void *
-buffer_ptr(Buffer *buffer)
+buffer_ptr(const Buffer *buffer)
{
return buffer->buf + buffer->offset;
}
@@ -236,7 +236,7 @@ buffer_ptr(Buffer *buffer)
/* Dumps the contents of the buffer to stderr. */
void
-buffer_dump(Buffer *buffer)
+buffer_dump(const Buffer *buffer)
{
u_int i;
u_char *ucp = buffer->buf;
diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h
index d0f354e..4ef4f80 100644
--- a/crypto/openssh/buffer.h
+++ b/crypto/openssh/buffer.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.h,v 1.17 2008/05/08 06:59:01 markus Exp $ */
+/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -27,8 +27,8 @@ void buffer_init(Buffer *);
void buffer_clear(Buffer *);
void buffer_free(Buffer *);
-u_int buffer_len(Buffer *);
-void *buffer_ptr(Buffer *);
+u_int buffer_len(const Buffer *);
+void *buffer_ptr(const Buffer *);
void buffer_append(Buffer *, const void *, u_int);
void *buffer_append_space(Buffer *, u_int);
@@ -40,7 +40,7 @@ void buffer_get(Buffer *, void *, u_int);
void buffer_consume(Buffer *, u_int);
void buffer_consume_end(Buffer *, u_int);
-void buffer_dump(Buffer *);
+void buffer_dump(const Buffer *);
int buffer_get_ret(Buffer *, void *, u_int);
int buffer_consume_ret(Buffer *, u_int);
@@ -81,6 +81,7 @@ int buffer_get_short_ret(u_short *, Buffer *);
int buffer_get_int_ret(u_int *, Buffer *);
int buffer_get_int64_ret(u_int64_t *, Buffer *);
void *buffer_get_string_ret(Buffer *, u_int *);
+void *buffer_get_string_ptr_ret(Buffer *, u_int *);
int buffer_get_char_ret(char *, Buffer *);
#endif /* BUFFER_H */
diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c
index 22b19bb..ef94d91 100644
--- a/crypto/openssh/canohost.c
+++ b/crypto/openssh/canohost.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.c,v 1.65 2009/05/27 06:31:25 andreas Exp $ */
+/* $OpenBSD: canohost.c,v 1.66 2010/01/13 01:20:20 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <unistd.h>
#include "xmalloc.h"
#include "packet.h"
@@ -301,9 +302,22 @@ get_local_ipaddr(int sock)
}
char *
-get_local_name(int sock)
+get_local_name(int fd)
{
- return get_socket_address(sock, 0, NI_NAMEREQD);
+ char *host, myname[NI_MAXHOST];
+
+ /* Assume we were passed a socket */
+ if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)
+ return host;
+
+ /* Handle the case where we were passed a pipe */
+ if (gethostname(myname, sizeof(myname)) == -1) {
+ verbose("get_local_name: gethostname: %s", strerror(errno));
+ } else {
+ host = xstrdup(myname);
+ }
+
+ return host;
}
void
diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c
index e8b8aa0..d8c53a4 100644
--- a/crypto/openssh/channels.c
+++ b/crypto/openssh/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.296 2009/05/25 06:48:00 andreas Exp $ */
+/* $OpenBSD: channels.c,v 1.303 2010/01/30 21:12:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -53,6 +53,7 @@
#include <arpa/inet.h>
#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
@@ -228,12 +229,16 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
channel_max_fd = MAX(channel_max_fd, wfd);
channel_max_fd = MAX(channel_max_fd, efd);
- /* XXX set close-on-exec -markus */
+ if (rfd != -1)
+ fcntl(rfd, F_SETFD, FD_CLOEXEC);
+ if (wfd != -1 && wfd != rfd)
+ fcntl(wfd, F_SETFD, FD_CLOEXEC);
+ if (efd != -1 && efd != rfd && efd != wfd)
+ fcntl(efd, F_SETFD, FD_CLOEXEC);
c->rfd = rfd;
c->wfd = wfd;
c->sock = (rfd == wfd) ? rfd : -1;
- c->ctl_fd = -1; /* XXX: set elsewhere */
c->efd = efd;
c->extended_usage = extusage;
@@ -322,6 +327,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
c->output_filter = NULL;
c->filter_ctx = NULL;
c->filter_cleanup = NULL;
+ c->ctl_chan = -1;
+ c->mux_rcb = NULL;
+ c->mux_ctx = NULL;
+ c->delayed = 1; /* prevent call to channel_post handler */
TAILQ_INIT(&c->status_confirms);
debug("channel %d: new [%s]", found, remote_name);
return c;
@@ -363,11 +372,10 @@ channel_close_fd(int *fdp)
static void
channel_close_fds(Channel *c)
{
- debug3("channel %d: close_fds r %d w %d e %d c %d",
- c->self, c->rfd, c->wfd, c->efd, c->ctl_fd);
+ debug3("channel %d: close_fds r %d w %d e %d",
+ c->self, c->rfd, c->wfd, c->efd);
channel_close_fd(&c->sock);
- channel_close_fd(&c->ctl_fd);
channel_close_fd(&c->rfd);
channel_close_fd(&c->wfd);
channel_close_fd(&c->efd);
@@ -393,8 +401,6 @@ channel_free(Channel *c)
if (c->sock != -1)
shutdown(c->sock, SHUT_RDWR);
- if (c->ctl_fd != -1)
- shutdown(c->ctl_fd, SHUT_RDWR);
channel_close_fds(c);
buffer_free(&c->input);
buffer_free(&c->output);
@@ -516,6 +522,7 @@ channel_still_open(void)
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_PORT_LISTENER:
case SSH_CHANNEL_RPORT_LISTENER:
+ case SSH_CHANNEL_MUX_LISTENER:
case SSH_CHANNEL_CLOSED:
case SSH_CHANNEL_AUTH_SOCKET:
case SSH_CHANNEL_DYNAMIC:
@@ -529,6 +536,7 @@ channel_still_open(void)
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_X11_OPEN:
+ case SSH_CHANNEL_MUX_CLIENT:
return 1;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
@@ -560,6 +568,8 @@ channel_find_open(void)
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_PORT_LISTENER:
case SSH_CHANNEL_RPORT_LISTENER:
+ case SSH_CHANNEL_MUX_LISTENER:
+ case SSH_CHANNEL_MUX_CLIENT:
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_CONNECTING:
case SSH_CHANNEL_ZOMBIE:
@@ -610,6 +620,8 @@ channel_open_message(void)
case SSH_CHANNEL_CLOSED:
case SSH_CHANNEL_AUTH_SOCKET:
case SSH_CHANNEL_ZOMBIE:
+ case SSH_CHANNEL_MUX_CLIENT:
+ case SSH_CHANNEL_MUX_LISTENER:
continue;
case SSH_CHANNEL_LARVAL:
case SSH_CHANNEL_OPENING:
@@ -620,12 +632,12 @@ channel_open_message(void)
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
snprintf(buf, sizeof buf,
- " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n",
+ " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cc %d)\r\n",
c->self, c->remote_name,
c->type, c->remote_id,
c->istate, buffer_len(&c->input),
c->ostate, buffer_len(&c->output),
- c->rfd, c->wfd, c->ctl_fd);
+ c->rfd, c->wfd, c->ctl_chan);
buffer_append(&buffer, buf, strlen(buf));
continue;
default:
@@ -832,9 +844,6 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
FD_SET(c->efd, readset);
}
/* XXX: What about efd? races? */
- if (compat20 && c->ctl_fd != -1 &&
- c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN)
- FD_SET(c->ctl_fd, readset);
}
/* ARGSUSED */
@@ -979,6 +988,28 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
}
}
+static void
+channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
+{
+ if (c->istate == CHAN_INPUT_OPEN &&
+ buffer_check_alloc(&c->input, CHAN_RBUF))
+ FD_SET(c->rfd, readset);
+ if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
+ /* clear buffer immediately (discard any partial packet) */
+ buffer_clear(&c->input);
+ chan_ibuf_empty(c);
+ /* Start output drain. XXX just kill chan? */
+ chan_rcvd_oclose(c);
+ }
+ if (c->ostate == CHAN_OUTPUT_OPEN ||
+ c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
+ if (buffer_len(&c->output) > 0)
+ FD_SET(c->wfd, writeset);
+ else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)
+ chan_obuf_empty(c);
+ }
+}
+
/* try to decode a socks4 header */
/* ARGSUSED */
static int
@@ -1210,6 +1241,30 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
return 1;
}
+Channel *
+channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect,
+ int in, int out)
+{
+ Channel *c;
+
+ debug("channel_connect_stdio_fwd %s:%d", host_to_connect,
+ port_to_connect);
+
+ c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out,
+ -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
+ 0, "stdio-forward", /*nonblock*/0);
+
+ c->path = xstrdup(host_to_connect);
+ c->host_port = port_to_connect;
+ c->listening_port = 0;
+ c->force_drain = 1;
+
+ channel_register_fds(c, in, out, -1, 0, 1, 0);
+ port_open_helper(c, "direct-tcpip");
+
+ return c;
+}
+
/* dynamic port forwarding */
static void
channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
@@ -1219,7 +1274,6 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
int ret;
have = buffer_len(&c->input);
- c->delayed = 0;
debug2("channel %d: pre_dynamic: have %d", c->self, have);
/* buffer_dump(&c->input); */
/* check if the fixed size part of the packet is in buffer. */
@@ -1322,6 +1376,13 @@ port_open_helper(Channel *c, char *rtype)
char *remote_ipaddr = get_peer_ipaddr(c->sock);
int remote_port = get_peer_port(c->sock);
+ if (remote_port == -1) {
+ /* Fake addr/port to appease peers that validate it (Tectia) */
+ xfree(remote_ipaddr);
+ remote_ipaddr = xstrdup("127.0.0.1");
+ remote_port = 65535;
+ }
+
direct = (strcmp(rtype, "direct-tcpip") == 0);
snprintf(buf, sizeof buf,
@@ -1423,16 +1484,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
if (c->path != NULL)
nc->path = xstrdup(c->path);
- if (nextstate == SSH_CHANNEL_DYNAMIC) {
- /*
- * do not call the channel_post handler until
- * this flag has been reset by a pre-handler.
- * otherwise the FD_ISSET calls might overflow
- */
- nc->delayed = 1;
- } else {
+ if (nextstate != SSH_CHANNEL_DYNAMIC)
port_open_helper(nc, rtype);
- }
}
}
@@ -1722,36 +1775,6 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
return 1;
}
-/* ARGSUSED */
-static int
-channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset)
-{
- char buf[16];
- int len;
-
- /* Monitor control fd to detect if the slave client exits */
- if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) {
- len = read(c->ctl_fd, buf, sizeof(buf));
- if (len < 0 &&
- (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
- return 1;
- if (len <= 0) {
- debug2("channel %d: ctl read<=0", c->self);
- if (c->type != SSH_CHANNEL_OPEN) {
- debug2("channel %d: not open", c->self);
- chan_mark_dead(c);
- return -1;
- } else {
- chan_read_failed(c);
- chan_write_failed(c);
- }
- return -1;
- } else
- fatal("%s: unexpected data on ctl fd", __func__);
- }
- return 1;
-}
-
static int
channel_check_window(Channel *c)
{
@@ -1777,17 +1800,136 @@ channel_check_window(Channel *c)
static void
channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
{
- if (c->delayed)
- return;
channel_handle_rfd(c, readset, writeset);
channel_handle_wfd(c, readset, writeset);
if (!compat20)
return;
channel_handle_efd(c, readset, writeset);
- channel_handle_ctl(c, readset, writeset);
channel_check_window(c);
}
+static u_int
+read_mux(Channel *c, u_int need)
+{
+ char buf[CHAN_RBUF];
+ int len;
+ u_int rlen;
+
+ if (buffer_len(&c->input) < need) {
+ rlen = need - buffer_len(&c->input);
+ len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF));
+ if (len <= 0) {
+ if (errno != EINTR && errno != EAGAIN) {
+ debug2("channel %d: ctl read<=0 rfd %d len %d",
+ c->self, c->rfd, len);
+ chan_read_failed(c);
+ return 0;
+ }
+ } else
+ buffer_append(&c->input, buf, len);
+ }
+ return buffer_len(&c->input);
+}
+
+static void
+channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
+{
+ u_int need;
+ ssize_t len;
+
+ if (!compat20)
+ fatal("%s: entered with !compat20", __func__);
+
+ if (c->rfd != -1 && FD_ISSET(c->rfd, readset) &&
+ (c->istate == CHAN_INPUT_OPEN ||
+ c->istate == CHAN_INPUT_WAIT_DRAIN)) {
+ /*
+ * Don't not read past the precise end of packets to
+ * avoid disrupting fd passing.
+ */
+ if (read_mux(c, 4) < 4) /* read header */
+ return;
+ need = get_u32(buffer_ptr(&c->input));
+#define CHANNEL_MUX_MAX_PACKET (256 * 1024)
+ if (need > CHANNEL_MUX_MAX_PACKET) {
+ debug2("channel %d: packet too big %u > %u",
+ c->self, CHANNEL_MUX_MAX_PACKET, need);
+ chan_rcvd_oclose(c);
+ return;
+ }
+ if (read_mux(c, need + 4) < need + 4) /* read body */
+ return;
+ if (c->mux_rcb(c) != 0) {
+ debug("channel %d: mux_rcb failed", c->self);
+ chan_mark_dead(c);
+ return;
+ }
+ }
+
+ if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) &&
+ buffer_len(&c->output) > 0) {
+ len = write(c->wfd, buffer_ptr(&c->output),
+ buffer_len(&c->output));
+ if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ return;
+ if (len <= 0) {
+ chan_mark_dead(c);
+ return;
+ }
+ buffer_consume(&c->output, len);
+ }
+}
+
+static void
+channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
+{
+ Channel *nc;
+ struct sockaddr_storage addr;
+ socklen_t addrlen;
+ int newsock;
+ uid_t euid;
+ gid_t egid;
+
+ if (!FD_ISSET(c->sock, readset))
+ return;
+
+ debug("multiplexing control connection");
+
+ /*
+ * Accept connection on control socket
+ */
+ memset(&addr, 0, sizeof(addr));
+ addrlen = sizeof(addr);
+ if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
+ &addrlen)) == -1) {
+ error("%s accept: %s", __func__, strerror(errno));
+ return;
+ }
+
+ if (getpeereid(newsock, &euid, &egid) < 0) {
+ error("%s getpeereid failed: %s", __func__,
+ strerror(errno));
+ close(newsock);
+ return;
+ }
+ if ((euid != 0) && (getuid() != euid)) {
+ error("multiplex uid mismatch: peer euid %u != uid %u",
+ (u_int)euid, (u_int)getuid());
+ close(newsock);
+ return;
+ }
+ nc = channel_new("multiplex client", SSH_CHANNEL_MUX_CLIENT,
+ newsock, newsock, -1, c->local_window_max,
+ c->local_maxpacket, 0, "mux-control", 1);
+ nc->mux_rcb = c->mux_rcb;
+ debug3("%s: new mux channel %d fd %d", __func__,
+ nc->self, nc->sock);
+ /* establish state */
+ nc->mux_rcb(nc);
+ /* mux state transitions must not elicit protocol messages */
+ nc->flags |= CHAN_LOCAL;
+}
+
/* ARGSUSED */
static void
channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
@@ -1816,6 +1958,8 @@ channel_handler_init_20(void)
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
+ channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener;
+ channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client;
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
@@ -1824,6 +1968,8 @@ channel_handler_init_20(void)
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
+ channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener;
+ channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
}
static void
@@ -1910,17 +2056,23 @@ static void
channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
{
static int did_init = 0;
- u_int i;
+ u_int i, oalloc;
Channel *c;
if (!did_init) {
channel_handler_init();
did_init = 1;
}
- for (i = 0; i < channels_alloc; i++) {
+ for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {
c = channels[i];
if (c == NULL)
continue;
+ if (c->delayed) {
+ if (ftab == channel_pre)
+ c->delayed = 0;
+ else
+ continue;
+ }
if (ftab[c->type] != NULL)
(*ftab[c->type])(c, readset, writeset);
channel_garbage_collect(c);
@@ -2577,6 +2729,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr,
}
channel_set_reuseaddr(sock);
+ if (ai->ai_family == AF_INET6)
+ sock_set_v6only(sock);
debug("Local forwarding listening on %s port %s.",
ntop, strport);
@@ -3108,13 +3262,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
continue;
}
}
-#ifdef IPV6_V6ONLY
- if (ai->ai_family == AF_INET6) {
- int on = 1;
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
- error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
- }
-#endif
+ if (ai->ai_family == AF_INET6)
+ sock_set_v6only(sock);
if (x11_use_localhost)
channel_set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h
index 1488ed7..cc71885 100644
--- a/crypto/openssh/channels.h
+++ b/crypto/openssh/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.98 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.103 2010/01/26 01:28:35 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -53,7 +53,9 @@
#define SSH_CHANNEL_CONNECTING 12
#define SSH_CHANNEL_DYNAMIC 13
#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */
-#define SSH_CHANNEL_MAX_TYPE 15
+#define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */
+#define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux slave */
+#define SSH_CHANNEL_MAX_TYPE 17
struct Channel;
typedef struct Channel Channel;
@@ -81,6 +83,9 @@ struct channel_connect {
struct addrinfo *ai, *aitop;
};
+/* Callbacks for mux channels back into client-specific code */
+typedef int mux_callback_fn(struct Channel *);
+
struct Channel {
int type; /* channel type/state */
int self; /* my own channel identifier */
@@ -92,12 +97,16 @@ struct Channel {
int wfd; /* write fd */
int efd; /* extended fd */
int sock; /* sock fd */
- int ctl_fd; /* control fd (client sharing) */
+ int ctl_chan; /* control channel (multiplexed connections) */
int isatty; /* rfd is a tty */
int wfd_isatty; /* wfd is a tty */
int client_tty; /* (client) TTY has been requested */
int force_drain; /* force close on iEOF */
- int delayed; /* fdset hack */
+ int delayed; /* post-select handlers for newly created
+ * channels are delayed until the first call
+ * to a matching pre-select handler.
+ * this way post-select handlers are not
+ * accidenly called if a FD gets reused */
Buffer input; /* data read from socket, to be sent over
* encrypted connection */
Buffer output; /* data received over encrypted connection for
@@ -138,6 +147,10 @@ struct Channel {
/* non-blocking connect */
struct channel_connect connect_ctx;
+
+ /* multiplexing protocol hook, called for each packet received */
+ mux_callback_fn *mux_rcb;
+ void *mux_ctx;
};
#define CHAN_EXTENDED_IGNORE 0
@@ -168,6 +181,7 @@ struct Channel {
#define CHAN_CLOSE_RCVD 0x02
#define CHAN_EOF_SENT 0x04
#define CHAN_EOF_RCVD 0x08
+#define CHAN_LOCAL 0x10
#define CHAN_RBUF 16*1024
@@ -239,6 +253,7 @@ void channel_clear_adm_permitted_opens(void);
void channel_print_adm_permitted_opens(void);
int channel_input_port_forward_request(int, int);
Channel *channel_connect_to(const char *, u_short, char *, char *);
+Channel *channel_connect_stdio_fwd(const char*, u_short, int, int);
Channel *channel_connect_by_listen_address(u_short, char *, char *);
int channel_request_remote_forwarding(const char *, u_short,
const char *, u_short);
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index 9a7dc0a..6ffef95 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.213 2009/07/05 19:28:33 stevesk Exp $ */
+/* $OpenBSD: clientloop.c,v 1.218 2010/01/28 00:21:18 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -121,7 +121,7 @@ extern int stdin_null_flag;
extern int no_shell_flag;
/* Control socket */
-extern int muxserver_sock;
+extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
/*
* Name of the host we are connecting to. This is the name given on the
@@ -130,6 +130,9 @@ extern int muxserver_sock;
*/
extern char *host;
+/* Force TTY allocation */
+extern int force_tty_flag;
+
/*
* Flag to indicate that we have received a window change signal which has
* not yet been processed. This will cause a message indicating the new
@@ -143,7 +146,7 @@ static volatile sig_atomic_t received_signal = 0;
static int in_non_blocking_mode = 0;
/* Common data for the client loop code. */
-static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
+volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
static int escape_char1; /* Escape character. (proto1 only) */
static int escape_pending1; /* Last character was an escape (proto1 only) */
static int last_was_cr; /* Last character was a newline. */
@@ -161,6 +164,8 @@ static int session_closed = 0; /* In SSH2: login session closed. */
static void client_init_dispatch(void);
int session_ident = -1;
+int session_resumed = 0;
+
/* Track escape per proto2 channel */
struct escape_filter_ctx {
int escape_pending;
@@ -559,9 +564,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
if (packet_have_data_to_write())
FD_SET(connection_out, *writesetp);
- if (muxserver_sock != -1)
- FD_SET(muxserver_sock, *readsetp);
-
/*
* Wait for something to happen. This will suspend the process until
* some selected descriptor can be read, written, or has some other
@@ -608,7 +610,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
buffer_len(berr));
- leave_raw_mode();
+ leave_raw_mode(force_tty_flag);
/*
* Free (and clear) the buffer to reduce the amount of data that gets
@@ -629,7 +631,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
buffer_init(bout);
buffer_init(berr);
- enter_raw_mode();
+ enter_raw_mode(force_tty_flag);
}
static void
@@ -690,7 +692,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
/* XXX supress on mux _client_ quietmode */
tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
- c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
+ c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
if (type == SSH2_MSG_CHANNEL_SUCCESS) {
debug2("%s request accepted on channel %d",
@@ -772,7 +774,7 @@ process_cmdline(void)
bzero(&fwd, sizeof(fwd));
fwd.listen_host = fwd.connect_host = NULL;
- leave_raw_mode();
+ leave_raw_mode(force_tty_flag);
handler = signal(SIGINT, SIG_IGN);
cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
if (s == NULL)
@@ -834,6 +836,7 @@ process_cmdline(void)
while (isspace(*++s))
;
+ /* XXX update list of forwards in options */
if (delete) {
cancel_port = 0;
cancel_host = hpdelim(&s); /* may be NULL */
@@ -875,7 +878,7 @@ process_cmdline(void)
out:
signal(SIGINT, handler);
- enter_raw_mode();
+ enter_raw_mode(force_tty_flag);
if (cmd)
xfree(cmd);
if (fwd.listen_host != NULL)
@@ -931,7 +934,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
escape_char);
buffer_append(berr, string, strlen(string));
- if (c && c->ctl_fd != -1) {
+ if (c && c->ctl_chan != -1) {
chan_read_failed(c);
chan_write_failed(c);
return 0;
@@ -941,7 +944,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
case 'Z' - 64:
/* XXX support this for mux clients */
- if (c && c->ctl_fd != -1) {
+ if (c && c->ctl_chan != -1) {
noescape:
snprintf(string, sizeof string,
"%c%c escape not available to "
@@ -986,7 +989,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
continue;
case '&':
- if (c && c->ctl_fd != -1)
+ if (c && c->ctl_chan != -1)
goto noescape;
/*
* Detach the program (continue to serve
@@ -994,7 +997,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
* more new connections).
*/
/* Restore tty modes. */
- leave_raw_mode();
+ leave_raw_mode(force_tty_flag);
/* Stop listening for new connections. */
channel_stop_listening();
@@ -1037,7 +1040,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
continue;
case '?':
- if (c && c->ctl_fd != -1) {
+ if (c && c->ctl_chan != -1) {
snprintf(string, sizeof string,
"%c?\r\n\
Supported escape sequences:\r\n\
@@ -1086,7 +1089,7 @@ Supported escape sequences:\r\n\
continue;
case 'C':
- if (c && c->ctl_fd != -1)
+ if (c && c->ctl_chan != -1)
goto noescape;
process_cmdline();
continue;
@@ -1289,7 +1292,7 @@ client_channel_closed(int id, void *arg)
{
channel_cancel_cleanup(id);
session_closed = 1;
- leave_raw_mode();
+ leave_raw_mode(force_tty_flag);
}
/*
@@ -1322,8 +1325,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
connection_in = packet_get_connection_in();
connection_out = packet_get_connection_out();
max_fd = MAX(connection_in, connection_out);
- if (muxserver_sock != -1)
- max_fd = MAX(max_fd, muxserver_sock);
if (!compat20) {
/* enable nonblocking unless tty */
@@ -1362,7 +1363,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
signal(SIGWINCH, window_change_handler);
if (have_pty)
- enter_raw_mode();
+ enter_raw_mode(force_tty_flag);
if (compat20) {
session_ident = ssh2_chan_id;
@@ -1441,12 +1442,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Buffer input from the connection. */
client_process_net_input(readset);
- /* Accept control connections. */
- if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) {
- if (muxserver_accept_control())
- quit_pending = 1;
- }
-
if (quit_pending)
break;
@@ -1460,6 +1455,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
client_process_output(writeset);
}
+ if (session_resumed) {
+ connection_in = packet_get_connection_in();
+ connection_out = packet_get_connection_out();
+ max_fd = MAX(max_fd, connection_out);
+ max_fd = MAX(max_fd, connection_in);
+ session_resumed = 0;
+ }
+
/*
* Send as much buffered packet data as possible to the
* sender.
@@ -1488,7 +1491,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
channel_free_all();
if (have_pty)
- leave_raw_mode();
+ leave_raw_mode(force_tty_flag);
/* restore blocking io */
if (!isatty(fileno(stdin)))
@@ -1846,15 +1849,17 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
chan_rcvd_eow(c);
} else if (strcmp(rtype, "exit-status") == 0) {
exitval = packet_get_int();
- if (id == session_ident) {
+ if (c->ctl_chan != -1) {
+ mux_exit_message(c, exitval);
+ success = 1;
+ } else if (id == session_ident) {
+ /* Record exit value of local session */
success = 1;
exit_status = exitval;
- } else if (c->ctl_fd == -1) {
- error("client_input_channel_req: unexpected channel %d",
- session_ident);
} else {
- atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval));
- success = 1;
+ /* Probably for a mux channel that has already closed */
+ debug("%s: no sink for exit-status on channel %d",
+ __func__, id);
}
packet_check_eom();
}
@@ -2050,7 +2055,7 @@ client_init_dispatch(void)
void
cleanup_exit(int i)
{
- leave_raw_mode();
+ leave_raw_mode(force_tty_flag);
leave_non_blocking();
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
diff --git a/crypto/openssh/clientloop.h b/crypto/openssh/clientloop.h
index 8bb874b..0b8257b 100644
--- a/crypto/openssh/clientloop.h
+++ b/crypto/openssh/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.22 2008/06/12 15:19:17 djm Exp $ */
+/* $OpenBSD: clientloop.h,v 1.23 2010/01/26 01:28:35 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -56,18 +56,14 @@ typedef void global_confirm_cb(int, u_int32_t seq, void *);
void client_register_global_confirm(global_confirm_cb *, void *);
/* Multiplexing protocol version */
-#define SSHMUX_VER 2
+#define SSHMUX_VER 4
/* Multiplexing control protocol flags */
#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
-
-#define SSHMUX_FLAG_TTY (1) /* Request tty on open */
-#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */
-#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */
-#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */
+#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
void muxserver_listen(void);
-int muxserver_accept_control(void);
void muxclient(const char *);
+void mux_exit_message(Channel *, int);
diff --git a/crypto/openssh/config.guess b/crypto/openssh/config.guess
index c7607c7..c2246a4 100755
--- a/crypto/openssh/config.guess
+++ b/crypto/openssh/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.
-timestamp='2008-04-14'
+timestamp='2009-12-30'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -27,16 +27,16 @@ timestamp='2008-04-14'
# the same distribution terms that you use for the rest of that program.
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,8 +56,9 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -170,7 +171,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
+ | grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -324,14 +325,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -640,7 +660,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
+ grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -791,12 +811,12 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- *:Interix*:[3456]*)
+ *:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
- EM64T | authenticamd)
+ authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
@@ -806,6 +826,9 @@ EOF
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -835,6 +858,20 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
@@ -857,6 +894,17 @@ EOF
frv:Linux:*:*)
echo frv-unknown-linux-gnu
exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
@@ -866,74 +914,33 @@ EOF
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- mips:Linux:*:*)
+ mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
- #undef mips
- #undef mipsel
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
+ CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
+ CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
@@ -943,8 +950,11 @@ EOF
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
@@ -967,66 +977,6 @@ EOF
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@@ -1055,7 +1005,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1099,8 +1049,11 @@ EOF
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
@@ -1138,6 +1091,16 @@ EOF
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1150,7 +1113,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1243,6 +1206,16 @@ EOF
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1324,6 +1297,9 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h
index 2240a37..66e3c7a 100644
--- a/crypto/openssh/config.h
+++ b/crypto/openssh/config.h
@@ -123,6 +123,9 @@
/* Define if you don't want to use wtmpx */
#define DISABLE_WTMPX 1
+/* Enable for PKCS#11 support */
+#define ENABLE_PKCS11
+
/* Builtin PRNG command timeout */
#define ENTROPY_TIMEOUT_MSEC 200
@@ -462,6 +465,9 @@
/* Define to 1 if you have the <glob.h> header file. */
#define HAVE_GLOB_H 1
+/* Define to 1 if you have the `group_from_gid' function. */
+#define HAVE_GROUP_FROM_GID 1
+
/* Define to 1 if you have the <gssapi_generic.h> header file. */
/* #undef HAVE_GSSAPI_GENERIC_H */
@@ -552,9 +558,6 @@
/* Define to 1 if you have the `pam' library (-lpam). */
#define HAVE_LIBPAM 1
-/* Define to 1 if you have the `sectok' library (-lsectok). */
-/* #undef HAVE_LIBSECTOK */
-
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
@@ -736,9 +739,6 @@
/* define if you have sa_family_t data type */
#define HAVE_SA_FAMILY_T 1
-/* Define to 1 if you have the <sectok.h> header file. */
-/* #undef HAVE_SECTOK_H */
-
/* Define if you have SecureWare-based protected password database */
/* #undef HAVE_SECUREWARE */
@@ -763,6 +763,9 @@
/* Define to 1 if you have the `seteuid' function. */
#define HAVE_SETEUID 1
+/* Define to 1 if you have the `setgroupent' function. */
+#define HAVE_SETGROUPENT 1
+
/* Define to 1 if you have the `setgroups' function. */
#define HAVE_SETGROUPS 1
@@ -772,6 +775,9 @@
/* Define to 1 if you have the `setluid' function. */
/* #undef HAVE_SETLUID */
+/* Define to 1 if you have the `setpassent' function. */
+#define HAVE_SETPASSENT 1
+
/* Define to 1 if you have the `setpcred' function. */
/* #undef HAVE_SETPCRED */
@@ -1075,6 +1081,9 @@
/* Define to 1 if you have the <usersec.h> header file. */
/* #undef HAVE_USERSEC_H */
+/* Define to 1 if you have the `user_from_uid' function. */
+#define HAVE_USER_FROM_UID 1
+
/* Define to 1 if you have the <util.h> header file. */
/* #undef HAVE_UTIL_H */
@@ -1184,6 +1193,9 @@
EOPNOTSUPP. */
/* #undef LINK_OPNOTSUPP_ERRNO */
+/* Adjust Linux out-of-memory killer */
+/* #undef LINUX_OOM_ADJUST */
+
/* max value of long long calculated by configure */
/* #undef LLONG_MAX */
@@ -1303,9 +1315,6 @@
/* Define if your skeychallenge() function takes 4 arguments (NetBSD) */
/* #undef SKEYCHALLENGE_4ARG */
-/* Define if you want smartcard support */
-/* #undef SMARTCARD */
-
/* Define as const if snprintf() can declare const char *fmt */
#define SNPRINTF_CONST const
@@ -1373,9 +1382,6 @@
/* Use libedit for sftp */
#define USE_LIBEDIT 1
-/* Define if you want smartcard support using OpenSC */
-/* #undef USE_OPENSC */
-
/* Enable OpenSSL engine support */
#define USE_OPENSSL_ENGINE 1
@@ -1385,9 +1391,6 @@
/* Use PIPES instead of a socketpair() */
/* #undef USE_PIPES */
-/* Define if you want smartcard support using sectok */
-/* #undef USE_SECTOK */
-
/* Define if you have Solaris process contracts */
/* #undef USE_SOLARIS_PROCESS_CONTRACTS */
@@ -1413,8 +1416,8 @@
/* Define if you want SELinux support. */
/* #undef WITH_SELINUX */
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
#if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
#elif ! defined __LITTLE_ENDIAN__
diff --git a/crypto/openssh/config.h.in b/crypto/openssh/config.h.in
index fc195ba..a61dec6 100644
--- a/crypto/openssh/config.h.in
+++ b/crypto/openssh/config.h.in
@@ -1,8 +1,5 @@
/* config.h.in. Generated from configure.ac by autoheader. */
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
*/
#undef AIX_GETNAMEINFO_HACK
@@ -125,6 +122,9 @@
/* Define if you don't want to use wtmpx */
#undef DISABLE_WTMPX
+/* Enable for PKCS#11 support */
+#undef ENABLE_PKCS11
+
/* Builtin PRNG command timeout */
#undef ENTROPY_TIMEOUT_MSEC
@@ -464,6 +464,9 @@
/* Define to 1 if you have the <glob.h> header file. */
#undef HAVE_GLOB_H
+/* Define to 1 if you have the `group_from_gid' function. */
+#undef HAVE_GROUP_FROM_GID
+
/* Define to 1 if you have the <gssapi_generic.h> header file. */
#undef HAVE_GSSAPI_GENERIC_H
@@ -554,9 +557,6 @@
/* Define to 1 if you have the `pam' library (-lpam). */
#undef HAVE_LIBPAM
-/* Define to 1 if you have the `sectok' library (-lsectok). */
-#undef HAVE_LIBSECTOK
-
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
@@ -738,9 +738,6 @@
/* define if you have sa_family_t data type */
#undef HAVE_SA_FAMILY_T
-/* Define to 1 if you have the <sectok.h> header file. */
-#undef HAVE_SECTOK_H
-
/* Define if you have SecureWare-based protected password database */
#undef HAVE_SECUREWARE
@@ -765,6 +762,9 @@
/* Define to 1 if you have the `seteuid' function. */
#undef HAVE_SETEUID
+/* Define to 1 if you have the `setgroupent' function. */
+#undef HAVE_SETGROUPENT
+
/* Define to 1 if you have the `setgroups' function. */
#undef HAVE_SETGROUPS
@@ -774,6 +774,9 @@
/* Define to 1 if you have the `setluid' function. */
#undef HAVE_SETLUID
+/* Define to 1 if you have the `setpassent' function. */
+#undef HAVE_SETPASSENT
+
/* Define to 1 if you have the `setpcred' function. */
#undef HAVE_SETPCRED
@@ -1077,6 +1080,9 @@
/* Define to 1 if you have the <usersec.h> header file. */
#undef HAVE_USERSEC_H
+/* Define to 1 if you have the `user_from_uid' function. */
+#undef HAVE_USER_FROM_UID
+
/* Define to 1 if you have the <util.h> header file. */
#undef HAVE_UTIL_H
@@ -1186,6 +1192,9 @@
EOPNOTSUPP. */
#undef LINK_OPNOTSUPP_ERRNO
+/* Adjust Linux out-of-memory killer */
+#undef LINUX_OOM_ADJUST
+
/* max value of long long calculated by configure */
#undef LLONG_MAX
@@ -1305,9 +1314,6 @@
/* Define if your skeychallenge() function takes 4 arguments (NetBSD) */
#undef SKEYCHALLENGE_4ARG
-/* Define if you want smartcard support */
-#undef SMARTCARD
-
/* Define as const if snprintf() can declare const char *fmt */
#undef SNPRINTF_CONST
@@ -1375,9 +1381,6 @@
/* Use libedit for sftp */
#undef USE_LIBEDIT
-/* Define if you want smartcard support using OpenSC */
-#undef USE_OPENSC
-
/* Enable OpenSSL engine support */
#undef USE_OPENSSL_ENGINE
@@ -1387,9 +1390,6 @@
/* Use PIPES instead of a socketpair() */
#undef USE_PIPES
-/* Define if you want smartcard support using sectok */
-#undef USE_SECTOK
-
/* Define if you have Solaris process contracts */
#undef USE_SOLARIS_PROCESS_CONTRACTS
@@ -1415,17 +1415,9 @@
/* Define if you want SELinux support. */
#undef WITH_SELINUX
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-# undef WORDS_BIGENDIAN
-# endif
-#endif
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
/* Define if xauth is found in your path */
#undef XAUTH_PATH
diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h
index 827e92d..e592249 100644
--- a/crypto/openssh/defines.h
+++ b/crypto/openssh/defines.h
@@ -25,7 +25,7 @@
#ifndef _DEFINES_H
#define _DEFINES_H
-/* $Id: defines.h,v 1.156 2009/08/28 01:21:07 dtucker Exp $ */
+/* $Id: defines.h,v 1.159 2010/01/13 23:44:34 tim Exp $ */
/* Constants */
@@ -753,4 +753,12 @@ struct winsize {
# define SSH_IOBUFSZ 8192
#endif
+#ifndef _NSIG
+# ifdef NSIG
+# define _NSIG NSIG
+# else
+# define _NSIG 128
+# endif
+#endif
+
#endif /* _DEFINES_H */
diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c
index b766053..b9029d8 100644
--- a/crypto/openssh/dh.c
+++ b/crypto/openssh/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.47 2008/06/26 09:19:39 djm Exp $ */
+/* $OpenBSD: dh.c,v 1.48 2009/10/01 11:37:33 grunk Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
@@ -83,7 +83,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
goto fail;
strsize = strsep(&cp, " "); /* size */
if (cp == NULL || *strsize == '\0' ||
- (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
+ (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
errstr)
goto fail;
/* The whole group is one bit larger */
diff --git a/crypto/openssh/dns.c b/crypto/openssh/dns.c
index a7da03f..2e7bb5a 100644
--- a/crypto/openssh/dns.c
+++ b/crypto/openssh/dns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dns.c,v 1.25 2008/06/12 00:03:49 dtucker Exp $ */
+/* $OpenBSD: dns.c,v 1.26 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -75,7 +75,7 @@ dns_result_totext(unsigned int res)
*/
static int
dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
- u_char **digest, u_int *digest_len, const Key *key)
+ u_char **digest, u_int *digest_len, Key *key)
{
int success = 0;
@@ -172,7 +172,7 @@ is_numeric_hostname(const char *hostname)
*/
int
verify_host_key_dns(const char *hostname, struct sockaddr *address,
- const Key *hostkey, int *flags)
+ Key *hostkey, int *flags)
{
u_int counter;
int result;
@@ -271,7 +271,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
* Export the fingerprint of a key as a DNS resource record
*/
int
-export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
+export_dns_rr(const char *hostname, Key *key, FILE *f, int generic)
{
u_int8_t rdata_pubkey_algorithm = 0;
u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
diff --git a/crypto/openssh/dns.h b/crypto/openssh/dns.h
index b2633a1..90cfd7b 100644
--- a/crypto/openssh/dns.h
+++ b/crypto/openssh/dns.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dns.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: dns.h,v 1.11 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -46,7 +46,7 @@ enum sshfp_hashes {
#define DNS_VERIFY_MATCH 0x00000002
#define DNS_VERIFY_SECURE 0x00000004
-int verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
-int export_dns_rr(const char *, const Key *, FILE *, int);
+int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *);
+int export_dns_rr(const char *, Key *, FILE *, int);
#endif /* DNS_H */
diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c
index 2cceb35..afab6da 100644
--- a/crypto/openssh/hostfile.c
+++ b/crypto/openssh/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.45 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -183,6 +183,41 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
return 1;
}
+static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA }
+check_markers(char **cpp)
+{
+ char marker[32], *sp, *cp = *cpp;
+ int ret = MRK_NONE;
+
+ while (*cp == '@') {
+ /* Only one marker is allowed */
+ if (ret != MRK_NONE)
+ return MRK_ERROR;
+ /* Markers are terminated by whitespace */
+ if ((sp = strchr(cp, ' ')) == NULL &&
+ (sp = strchr(cp, '\t')) == NULL)
+ return MRK_ERROR;
+ /* Extract marker for comparison */
+ if (sp <= cp + 1 || sp >= cp + sizeof(marker))
+ return MRK_ERROR;
+ memcpy(marker, cp, sp - cp);
+ marker[sp - cp] = '\0';
+ if (strcmp(marker, CA_MARKER) == 0)
+ ret = MRK_CA;
+ else if (strcmp(marker, REVOKE_MARKER) == 0)
+ ret = MRK_REVOKE;
+ else
+ return MRK_ERROR;
+
+ /* Skip past marker and any whitespace that follows it */
+ cp = sp;
+ for (; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ }
+ *cpp = cp;
+ return ret;
+}
+
/*
* Checks whether the given host (which must be in all lowercase) is already
* in the list of our known hosts. Returns HOST_OK if the host is known and
@@ -195,16 +230,20 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
static HostStatus
check_host_in_hostfile_by_key_or_type(const char *filename,
- const char *host, const Key *key, int keytype, Key *found, int *numret)
+ const char *host, const Key *key, int keytype, Key *found,
+ int want_revocation, int *numret)
{
FILE *f;
char line[8192];
- int linenum = 0;
+ int want, have, linenum = 0, want_cert = key_is_cert(key);
u_int kbits;
char *cp, *cp2, *hashed_host;
HostStatus end_return;
- debug3("check_host_in_hostfile: filename %s", filename);
+ debug3("check_host_in_hostfile: host %s filename %s", host, filename);
+
+ if (want_revocation && (key == NULL || keytype != 0 || found != NULL))
+ fatal("%s: invalid arguments", __func__);
/* Open the file containing the list of known hosts. */
f = fopen(filename, "r");
@@ -229,6 +268,20 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
if (!*cp || *cp == '#' || *cp == '\n')
continue;
+ if (want_revocation)
+ want = MRK_REVOKE;
+ else if (want_cert)
+ want = MRK_CA;
+ else
+ want = MRK_NONE;
+
+ if ((have = check_markers(&cp)) == MRK_ERROR) {
+ verbose("%s: invalid marker at %s:%d",
+ __func__, filename, linenum);
+ continue;
+ } else if (want != have)
+ continue;
+
/* Find the end of the host name portion. */
for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
;
@@ -250,6 +303,9 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
/* Got a match. Skip host name. */
cp = cp2;
+ if (want_revocation)
+ found = key_new(KEY_UNSPEC);
+
/*
* Extract the key from the line. This will skip any leading
* whitespace. Ignore badly formatted lines.
@@ -272,9 +328,33 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
if (!hostfile_check_key(kbits, found, host, filename, linenum))
continue;
+ if (want_revocation) {
+ if (key_is_cert(key) &&
+ key_equal_public(key->cert->signature_key, found)) {
+ verbose("check_host_in_hostfile: revoked CA "
+ "line %d", linenum);
+ key_free(found);
+ return HOST_REVOKED;
+ }
+ if (key_equal_public(key, found)) {
+ verbose("check_host_in_hostfile: revoked key "
+ "line %d", linenum);
+ key_free(found);
+ return HOST_REVOKED;
+ }
+ key_free(found);
+ continue;
+ }
+
/* Check if the current key is the same as the given key. */
- if (key_equal(key, found)) {
- /* Ok, they match. */
+ if (want_cert && key_equal(key->cert->signature_key, found)) {
+ /* Found CA cert for key */
+ debug3("check_host_in_hostfile: CA match line %d",
+ linenum);
+ fclose(f);
+ return HOST_OK;
+ } else if (!want_cert && key_equal(key, found)) {
+ /* Found identical key */
debug3("check_host_in_hostfile: match line %d", linenum);
fclose(f);
return HOST_OK;
@@ -302,8 +382,11 @@ check_host_in_hostfile(const char *filename, const char *host, const Key *key,
{
if (key == NULL)
fatal("no key to look up");
- return (check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
- found, numret));
+ if (check_host_in_hostfile_by_key_or_type(filename, host,
+ key, 0, NULL, 1, NULL) == HOST_REVOKED)
+ return HOST_REVOKED;
+ return check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
+ found, 0, numret);
}
int
@@ -311,7 +394,7 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
int keytype, Key *found, int *numret)
{
return (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
- keytype, found, numret) == HOST_FOUND);
+ keytype, found, 0, numret) == HOST_FOUND);
}
/*
diff --git a/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h
index d1983b3..1d460c1 100644
--- a/crypto/openssh/hostfile.h
+++ b/crypto/openssh/hostfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -15,7 +15,7 @@
#define HOSTFILE_H
typedef enum {
- HOST_OK, HOST_NEW, HOST_CHANGED, HOST_FOUND
+ HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND
} HostStatus;
int hostfile_read_key(char **, u_int *, Key *);
@@ -28,6 +28,9 @@ int lookup_key_in_hostfile_by_type(const char *, const char *,
#define HASH_MAGIC "|1|"
#define HASH_DELIM '|'
+#define CA_MARKER "@cert-authority"
+#define REVOKE_MARKER "@revoked"
+
char *host_hash(const char *, const char *, u_int);
#endif
diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
index f4f44f0..148cfee 100644
--- a/crypto/openssh/kex.c
+++ b/crypto/openssh/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.81 2009/05/27 06:34:36 andreas Exp $ */
+/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -48,6 +48,7 @@
#include "match.h"
#include "dispatch.h"
#include "monitor.h"
+#include "roaming.h"
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
# if defined(HAVE_EVP_SHA256)
@@ -386,6 +387,16 @@ kex_choose_conf(Kex *kex)
sprop=peer;
}
+ /* Check whether server offers roaming */
+ if (!kex->server) {
+ char *roaming;
+ roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL);
+ if (roaming) {
+ kex->roaming = 1;
+ xfree(roaming);
+ }
+ }
+
/* Algorithm Negotiation */
for (mode = 0; mode < MODE_MAX; mode++) {
newkeys = xcalloc(1, sizeof(*newkeys));
diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h
index 68c80c5..62fa2ea 100644
--- a/crypto/openssh/kex.h
+++ b/crypto/openssh/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.47 2009/05/27 06:34:36 andreas Exp $ */
+/* $OpenBSD: kex.h,v 1.49 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -36,6 +36,7 @@
#define KEX_DH14 "diffie-hellman-group14-sha1"
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256"
+#define KEX_RESUME "resume@appgate.com"
#define COMP_NONE 0
#define COMP_ZLIB 1
@@ -116,6 +117,7 @@ struct Kex {
char *name;
int hostkey_type;
int kex_type;
+ int roaming;
Buffer my;
Buffer peer;
sig_atomic_t done;
@@ -124,7 +126,8 @@ struct Kex {
char *client_version_string;
char *server_version_string;
int (*verify_host_key)(Key *);
- Key *(*load_host_key)(int);
+ Key *(*load_host_public_key)(int);
+ Key *(*load_host_private_key)(int);
int (*host_key_index)(Key *);
void (*kex[KEX_MAX])(Kex *);
};
diff --git a/crypto/openssh/kexdhs.c b/crypto/openssh/kexdhs.c
index a6719f6..e722877 100644
--- a/crypto/openssh/kexdhs.c
+++ b/crypto/openssh/kexdhs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexdhs.c,v 1.10 2009/06/21 07:37:15 dtucker Exp $ */
+/* $OpenBSD: kexdhs.c,v 1.11 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -50,7 +50,7 @@ kexdh_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
DH *dh;
- Key *server_host_key;
+ Key *server_host_public, *server_host_private;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, hashlen, slen;
int kout;
@@ -71,11 +71,16 @@ kexdh_server(Kex *kex)
debug("expecting SSH2_MSG_KEXDH_INIT");
packet_read_expect(SSH2_MSG_KEXDH_INIT);
- if (kex->load_host_key == NULL)
+ if (kex->load_host_public_key == NULL ||
+ kex->load_host_private_key == NULL)
fatal("Cannot load hostkey");
- server_host_key = kex->load_host_key(kex->hostkey_type);
- if (server_host_key == NULL)
+ server_host_public = kex->load_host_public_key(kex->hostkey_type);
+ if (server_host_public == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
+ server_host_private = kex->load_host_private_key(kex->hostkey_type);
+ if (server_host_private == NULL)
+ fatal("Missing private key for hostkey type %d",
+ kex->hostkey_type);
/* key, cert */
if ((dh_client_pub = BN_new()) == NULL)
@@ -113,7 +118,7 @@ kexdh_server(Kex *kex)
memset(kbuf, 0, klen);
xfree(kbuf);
- key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
+ key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
/* calc H */
kex_dh_hash(
@@ -137,7 +142,7 @@ kexdh_server(Kex *kex)
}
/* sign H */
- if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash,
+ if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash,
hashlen)) < 0)
fatal("kexdh_server: key_sign failed");
diff --git a/crypto/openssh/kexgexs.c b/crypto/openssh/kexgexs.c
index 8515568..f4156af 100644
--- a/crypto/openssh/kexgexs.c
+++ b/crypto/openssh/kexgexs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.12 2009/06/21 07:37:15 dtucker Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.13 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -52,18 +52,24 @@ void
kexgex_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
- Key *server_host_key;
+ Key *server_host_public, *server_host_private;
DH *dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, slen, hashlen;
int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1;
int type, kout;
- if (kex->load_host_key == NULL)
+ if (kex->load_host_public_key == NULL ||
+ kex->load_host_private_key == NULL)
fatal("Cannot load hostkey");
- server_host_key = kex->load_host_key(kex->hostkey_type);
- if (server_host_key == NULL)
+ server_host_public = kex->load_host_public_key(kex->hostkey_type);
+ if (server_host_public == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
+ server_host_private = kex->load_host_private_key(kex->hostkey_type);
+ if (server_host_private == NULL)
+ fatal("Missing private key for hostkey type %d",
+ kex->hostkey_type);
+
type = packet_read();
switch (type) {
@@ -149,7 +155,7 @@ kexgex_server(Kex *kex)
memset(kbuf, 0, klen);
xfree(kbuf);
- key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
+ key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
omin = min = omax = max = -1;
@@ -179,7 +185,7 @@ kexgex_server(Kex *kex)
}
/* sign H */
- if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash,
+ if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash,
hashlen)) < 0)
fatal("kexgex_server: key_sign failed");
diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c
index 3e17da6..0d0c912 100644
--- a/crypto/openssh/key.c
+++ b/crypto/openssh/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */
+/* $OpenBSD: key.c,v 1.85 2010/03/04 01:44:57 djm Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -52,6 +52,21 @@
#include "uuencode.h"
#include "buffer.h"
#include "log.h"
+#include "ssh2.h"
+
+static struct KeyCert *
+cert_new(void)
+{
+ struct KeyCert *cert;
+
+ cert = xcalloc(1, sizeof(*cert));
+ buffer_init(&cert->certblob);
+ buffer_init(&cert->constraints);
+ cert->key_id = NULL;
+ cert->principals = NULL;
+ cert->signature_key = NULL;
+ return cert;
+}
Key *
key_new(int type)
@@ -63,9 +78,11 @@ key_new(int type)
k->type = type;
k->dsa = NULL;
k->rsa = NULL;
+ k->cert = NULL;
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT:
if ((rsa = RSA_new()) == NULL)
fatal("key_new: RSA_new failed");
if ((rsa->n = BN_new()) == NULL)
@@ -75,6 +92,7 @@ key_new(int type)
k->rsa = rsa;
break;
case KEY_DSA:
+ case KEY_DSA_CERT:
if ((dsa = DSA_new()) == NULL)
fatal("key_new: DSA_new failed");
if ((dsa->p = BN_new()) == NULL)
@@ -93,16 +111,20 @@ key_new(int type)
fatal("key_new: bad key type %d", k->type);
break;
}
+
+ if (key_is_cert(k))
+ k->cert = cert_new();
+
return k;
}
-Key *
-key_new_private(int type)
+void
+key_add_private(Key *k)
{
- Key *k = key_new(type);
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT:
if ((k->rsa->d = BN_new()) == NULL)
fatal("key_new_private: BN_new failed");
if ((k->rsa->iqmp = BN_new()) == NULL)
@@ -117,6 +139,7 @@ key_new_private(int type)
fatal("key_new_private: BN_new failed");
break;
case KEY_DSA:
+ case KEY_DSA_CERT:
if ((k->dsa->priv_key = BN_new()) == NULL)
fatal("key_new_private: BN_new failed");
break;
@@ -125,9 +148,34 @@ key_new_private(int type)
default:
break;
}
+}
+
+Key *
+key_new_private(int type)
+{
+ Key *k = key_new(type);
+
+ key_add_private(k);
return k;
}
+static void
+cert_free(struct KeyCert *cert)
+{
+ u_int i;
+
+ buffer_free(&cert->certblob);
+ buffer_free(&cert->constraints);
+ if (cert->key_id != NULL)
+ xfree(cert->key_id);
+ for (i = 0; i < cert->nprincipals; i++)
+ xfree(cert->principals[i]);
+ if (cert->principals != NULL)
+ xfree(cert->principals);
+ if (cert->signature_key != NULL)
+ key_free(cert->signature_key);
+}
+
void
key_free(Key *k)
{
@@ -136,11 +184,13 @@ key_free(Key *k)
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT:
if (k->rsa != NULL)
RSA_free(k->rsa);
k->rsa = NULL;
break;
case KEY_DSA:
+ case KEY_DSA_CERT:
if (k->dsa != NULL)
DSA_free(k->dsa);
k->dsa = NULL;
@@ -151,20 +201,49 @@ key_free(Key *k)
fatal("key_free: bad key type %d", k->type);
break;
}
+ if (key_is_cert(k)) {
+ if (k->cert != NULL)
+ cert_free(k->cert);
+ k->cert = NULL;
+ }
+
xfree(k);
}
+static int
+cert_compare(struct KeyCert *a, struct KeyCert *b)
+{
+ if (a == NULL && b == NULL)
+ return 1;
+ if (a == NULL || b == NULL)
+ return 0;
+ if (buffer_len(&a->certblob) != buffer_len(&b->certblob))
+ return 0;
+ if (memcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob),
+ buffer_len(&a->certblob)) != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Compare public portions of key only, allowing comparisons between
+ * certificates and plain keys too.
+ */
int
-key_equal(const Key *a, const Key *b)
+key_equal_public(const Key *a, const Key *b)
{
- if (a == NULL || b == NULL || a->type != b->type)
+ if (a == NULL || b == NULL ||
+ key_type_plain(a->type) != key_type_plain(b->type))
return 0;
+
switch (a->type) {
case KEY_RSA1:
+ case KEY_RSA_CERT:
case KEY_RSA:
return a->rsa != NULL && b->rsa != NULL &&
BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
BN_cmp(a->rsa->n, b->rsa->n) == 0;
+ case KEY_DSA_CERT:
case KEY_DSA:
return a->dsa != NULL && b->dsa != NULL &&
BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
@@ -177,16 +256,27 @@ key_equal(const Key *a, const Key *b)
/* NOTREACHED */
}
+int
+key_equal(const Key *a, const Key *b)
+{
+ if (a == NULL || b == NULL || a->type != b->type)
+ return 0;
+ if (key_is_cert(a)) {
+ if (!cert_compare(a->cert, b->cert))
+ return 0;
+ }
+ return key_equal_public(a, b);
+}
+
u_char*
-key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
- u_int *dgst_raw_length)
+key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
{
const EVP_MD *md = NULL;
EVP_MD_CTX ctx;
u_char *blob = NULL;
u_char *retval = NULL;
u_int len = 0;
- int nlen, elen;
+ int nlen, elen, otype;
*dgst_raw_length = 0;
@@ -214,6 +304,14 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
case KEY_RSA:
key_to_blob(k, &blob, &len);
break;
+ case KEY_DSA_CERT:
+ case KEY_RSA_CERT:
+ /* We want a fingerprint of the _key_ not of the cert */
+ otype = k->type;
+ k->type = key_type_plain(k->type);
+ key_to_blob(k, &blob, &len);
+ k->type = otype;
+ break;
case KEY_UNSPEC:
return retval;
default:
@@ -408,7 +506,7 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
}
char *
-key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
+key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
{
char *retval = NULL;
u_char *dgst_raw;
@@ -522,11 +620,19 @@ key_read(Key *ret, char **cpp)
return -1;
if (!read_bignum(cpp, ret->rsa->n))
return -1;
+ /* validate the claimed number of bits */
+ if ((u_int)BN_num_bits(ret->rsa->n) != bits) {
+ verbose("key_read: claimed key size %d does not match "
+ "actual %d", bits, BN_num_bits(ret->rsa->n));
+ return -1;
+ }
success = 1;
break;
case KEY_UNSPEC:
case KEY_RSA:
case KEY_DSA:
+ case KEY_DSA_CERT:
+ case KEY_RSA_CERT:
space = strchr(cp, ' ');
if (space == NULL) {
debug3("key_read: missing whitespace");
@@ -571,25 +677,36 @@ key_read(Key *ret, char **cpp)
return -1;
}
/*XXXX*/
- if (ret->type == KEY_RSA) {
+ if (key_is_cert(ret)) {
+ if (!key_is_cert(k)) {
+ error("key_read: loaded key is not a cert");
+ key_free(k);
+ return -1;
+ }
+ if (ret->cert != NULL)
+ cert_free(ret->cert);
+ ret->cert = k->cert;
+ k->cert = NULL;
+ }
+ if (key_type_plain(ret->type) == KEY_RSA) {
if (ret->rsa != NULL)
RSA_free(ret->rsa);
ret->rsa = k->rsa;
k->rsa = NULL;
- success = 1;
#ifdef DEBUG_PK
RSA_print_fp(stderr, ret->rsa, 8);
#endif
- } else {
+ }
+ if (key_type_plain(ret->type) == KEY_DSA) {
if (ret->dsa != NULL)
DSA_free(ret->dsa);
ret->dsa = k->dsa;
k->dsa = NULL;
- success = 1;
#ifdef DEBUG_PK
DSA_print_fp(stderr, ret->dsa, 8);
#endif
}
+ success = 1;
/*XXXX*/
key_free(k);
if (success != 1)
@@ -616,28 +733,53 @@ key_write(const Key *key, FILE *f)
u_char *blob;
char *uu;
- if (key->type == KEY_RSA1 && key->rsa != NULL) {
+ if (key_is_cert(key)) {
+ if (key->cert == NULL) {
+ error("%s: no cert data", __func__);
+ return 0;
+ }
+ if (buffer_len(&key->cert->certblob) == 0) {
+ error("%s: no signed certificate blob", __func__);
+ return 0;
+ }
+ }
+
+ switch (key->type) {
+ case KEY_RSA1:
+ if (key->rsa == NULL)
+ return 0;
/* size of modulus 'n' */
bits = BN_num_bits(key->rsa->n);
fprintf(f, "%u", bits);
if (write_bignum(f, key->rsa->e) &&
- write_bignum(f, key->rsa->n)) {
- success = 1;
- } else {
- error("key_write: failed for RSA key");
- }
- } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
- (key->type == KEY_RSA && key->rsa != NULL)) {
- key_to_blob(key, &blob, &len);
- uu = xmalloc(2*len);
- n = uuencode(blob, len, uu, 2*len);
- if (n > 0) {
- fprintf(f, "%s %s", key_ssh_name(key), uu);
- success = 1;
- }
- xfree(blob);
- xfree(uu);
+ write_bignum(f, key->rsa->n))
+ return 1;
+ error("key_write: failed for RSA key");
+ return 0;
+ case KEY_DSA:
+ case KEY_DSA_CERT:
+ if (key->dsa == NULL)
+ return 0;
+ break;
+ case KEY_RSA:
+ case KEY_RSA_CERT:
+ if (key->rsa == NULL)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ key_to_blob(key, &blob, &len);
+ uu = xmalloc(2*len);
+ n = uuencode(blob, len, uu, 2*len);
+ if (n > 0) {
+ fprintf(f, "%s %s", key_ssh_name(key), uu);
+ success = 1;
}
+ xfree(blob);
+ xfree(uu);
+
return success;
}
@@ -651,6 +793,10 @@ key_type(const Key *k)
return "RSA";
case KEY_DSA:
return "DSA";
+ case KEY_RSA_CERT:
+ return "RSA-CERT";
+ case KEY_DSA_CERT:
+ return "DSA-CERT";
}
return "unknown";
}
@@ -663,6 +809,10 @@ key_ssh_name(const Key *k)
return "ssh-rsa";
case KEY_DSA:
return "ssh-dss";
+ case KEY_RSA_CERT:
+ return "ssh-rsa-cert-v00@openssh.com";
+ case KEY_DSA_CERT:
+ return "ssh-dss-cert-v00@openssh.com";
}
return "ssh-unknown";
}
@@ -673,8 +823,10 @@ key_size(const Key *k)
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT:
return BN_num_bits(k->rsa->n);
case KEY_DSA:
+ case KEY_DSA_CERT:
return BN_num_bits(k->dsa->p);
}
return 0;
@@ -685,7 +837,7 @@ rsa_generate_private_key(u_int bits)
{
RSA *private;
- private = RSA_generate_key(bits, 35, NULL, NULL);
+ private = RSA_generate_key(bits, RSA_F4, NULL, NULL);
if (private == NULL)
fatal("rsa_generate_private_key: key generation failed.");
return private;
@@ -717,6 +869,9 @@ key_generate(int type, u_int bits)
case KEY_RSA1:
k->rsa = rsa_generate_private_key(bits);
break;
+ case KEY_RSA_CERT:
+ case KEY_DSA_CERT:
+ fatal("key_generate: cert keys cannot be generated directly");
default:
fatal("key_generate: unknown type %d", type);
}
@@ -724,12 +879,55 @@ key_generate(int type, u_int bits)
return k;
}
+void
+key_cert_copy(const Key *from_key, struct Key *to_key)
+{
+ u_int i;
+ const struct KeyCert *from;
+ struct KeyCert *to;
+
+ if (to_key->cert != NULL) {
+ cert_free(to_key->cert);
+ to_key->cert = NULL;
+ }
+
+ if ((from = from_key->cert) == NULL)
+ return;
+
+ to = to_key->cert = cert_new();
+
+ buffer_append(&to->certblob, buffer_ptr(&from->certblob),
+ buffer_len(&from->certblob));
+
+ buffer_append(&to->constraints, buffer_ptr(&from->constraints),
+ buffer_len(&from->constraints));
+
+ to->type = from->type;
+ to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
+ to->valid_after = from->valid_after;
+ to->valid_before = from->valid_before;
+ to->signature_key = from->signature_key == NULL ?
+ NULL : key_from_private(from->signature_key);
+
+ to->nprincipals = from->nprincipals;
+ if (to->nprincipals > CERT_MAX_PRINCIPALS)
+ fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)",
+ __func__, to->nprincipals, CERT_MAX_PRINCIPALS);
+ if (to->nprincipals > 0) {
+ to->principals = xcalloc(from->nprincipals,
+ sizeof(*to->principals));
+ for (i = 0; i < to->nprincipals; i++)
+ to->principals[i] = xstrdup(from->principals[i]);
+ }
+}
+
Key *
key_from_private(const Key *k)
{
Key *n = NULL;
switch (k->type) {
case KEY_DSA:
+ case KEY_DSA_CERT:
n = key_new(k->type);
if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
(BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
@@ -739,6 +937,7 @@ key_from_private(const Key *k)
break;
case KEY_RSA:
case KEY_RSA1:
+ case KEY_RSA_CERT:
n = key_new(k->type);
if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
(BN_copy(n->rsa->e, k->rsa->e) == NULL))
@@ -748,6 +947,8 @@ key_from_private(const Key *k)
fatal("key_from_private: unknown type %d", k->type);
break;
}
+ if (key_is_cert(k))
+ key_cert_copy(k, n);
return n;
}
@@ -764,6 +965,10 @@ key_type_from_name(char *name)
return KEY_RSA;
} else if (strcmp(name, "ssh-dss") == 0) {
return KEY_DSA;
+ } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
+ return KEY_RSA_CERT;
+ } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
+ return KEY_DSA_CERT;
}
debug2("key_type_from_name: unknown key type '%s'", name);
return KEY_UNSPEC;
@@ -791,6 +996,127 @@ key_names_valid2(const char *names)
return 1;
}
+static int
+cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
+{
+ u_char *principals, *constraints, *sig_key, *sig;
+ u_int signed_len, plen, clen, sklen, slen, kidlen;
+ Buffer tmp;
+ char *principal;
+ int ret = -1;
+
+ buffer_init(&tmp);
+
+ /* Copy the entire key blob for verification and later serialisation */
+ buffer_append(&key->cert->certblob, blob, blen);
+
+ principals = constraints = sig_key = sig = NULL;
+ if (buffer_get_int_ret(&key->cert->type, b) != 0 ||
+ (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL ||
+ (principals = buffer_get_string_ret(b, &plen)) == NULL ||
+ buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
+ buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
+ (constraints = buffer_get_string_ret(b, &clen)) == NULL ||
+ /* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
+ /* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
+ (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
+ error("%s: parse error", __func__);
+ goto out;
+ }
+
+ if (kidlen != strlen(key->cert->key_id)) {
+ error("%s: key ID contains \\0 character", __func__);
+ goto out;
+ }
+
+ /* Signature is left in the buffer so we can calculate this length */
+ signed_len = buffer_len(&key->cert->certblob) - buffer_len(b);
+
+ if ((sig = buffer_get_string_ret(b, &slen)) == NULL) {
+ error("%s: parse error", __func__);
+ goto out;
+ }
+
+ if (key->cert->type != SSH2_CERT_TYPE_USER &&
+ key->cert->type != SSH2_CERT_TYPE_HOST) {
+ error("Unknown certificate type %u", key->cert->type);
+ goto out;
+ }
+
+ buffer_append(&tmp, principals, plen);
+ while (buffer_len(&tmp) > 0) {
+ if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) {
+ error("%s: Too many principals", __func__);
+ goto out;
+ }
+ if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) {
+ error("%s: Principals data invalid", __func__);
+ goto out;
+ }
+ if (strlen(principal) != plen) {
+ error("%s: Principal contains \\0 character",
+ __func__);
+ goto out;
+ }
+ key->cert->principals = xrealloc(key->cert->principals,
+ key->cert->nprincipals + 1, sizeof(*key->cert->principals));
+ key->cert->principals[key->cert->nprincipals++] = principal;
+ }
+
+ buffer_clear(&tmp);
+
+ buffer_append(&key->cert->constraints, constraints, clen);
+ buffer_append(&tmp, constraints, clen);
+ /* validate structure */
+ while (buffer_len(&tmp) != 0) {
+ if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
+ buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
+ error("%s: Constraints data invalid", __func__);
+ goto out;
+ }
+ }
+ buffer_clear(&tmp);
+
+ if ((key->cert->signature_key = key_from_blob(sig_key,
+ sklen)) == NULL) {
+ error("%s: Signature key invalid", __func__);
+ goto out;
+ }
+ if (key->cert->signature_key->type != KEY_RSA &&
+ key->cert->signature_key->type != KEY_DSA) {
+ error("%s: Invalid signature key type %s (%d)", __func__,
+ key_type(key->cert->signature_key),
+ key->cert->signature_key->type);
+ goto out;
+ }
+
+ switch (key_verify(key->cert->signature_key, sig, slen,
+ buffer_ptr(&key->cert->certblob), signed_len)) {
+ case 1:
+ ret = 0;
+ break; /* Good signature */
+ case 0:
+ error("%s: Invalid signature on certificate", __func__);
+ goto out;
+ case -1:
+ error("%s: Certificate signature verification failed",
+ __func__);
+ goto out;
+ }
+
+ out:
+ buffer_free(&tmp);
+ if (principals != NULL)
+ xfree(principals);
+ if (constraints != NULL)
+ xfree(constraints);
+ if (sig_key != NULL)
+ xfree(sig_key);
+ if (sig != NULL)
+ xfree(sig);
+ return ret;
+}
+
Key *
key_from_blob(const u_char *blob, u_int blen)
{
@@ -813,10 +1139,12 @@ key_from_blob(const u_char *blob, u_int blen)
switch (type) {
case KEY_RSA:
+ case KEY_RSA_CERT:
key = key_new(type);
if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
error("key_from_blob: can't read rsa key");
+ badkey:
key_free(key);
key = NULL;
goto out;
@@ -826,15 +1154,14 @@ key_from_blob(const u_char *blob, u_int blen)
#endif
break;
case KEY_DSA:
+ case KEY_DSA_CERT:
key = key_new(type);
if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
error("key_from_blob: can't read dsa key");
- key_free(key);
- key = NULL;
- goto out;
+ goto badkey;
}
#ifdef DEBUG_PK
DSA_print_fp(stderr, key->dsa, 8);
@@ -847,6 +1174,10 @@ key_from_blob(const u_char *blob, u_int blen)
error("key_from_blob: cannot handle type %s", ktype);
goto out;
}
+ if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) {
+ error("key_from_blob: can't parse cert data");
+ goto badkey;
+ }
rlen = buffer_len(&b);
if (key != NULL && rlen != 0)
error("key_from_blob: remaining bytes in key blob %d", rlen);
@@ -869,6 +1200,12 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
}
buffer_init(&b);
switch (key->type) {
+ case KEY_DSA_CERT:
+ case KEY_RSA_CERT:
+ /* Use the existing blob */
+ buffer_append(&b, buffer_ptr(&key->cert->certblob),
+ buffer_len(&key->cert->certblob));
+ break;
case KEY_DSA:
buffer_put_cstring(&b, key_ssh_name(key));
buffer_put_bignum2(&b, key->dsa->p);
@@ -905,8 +1242,10 @@ key_sign(
const u_char *data, u_int datalen)
{
switch (key->type) {
+ case KEY_DSA_CERT:
case KEY_DSA:
return ssh_dss_sign(key, sigp, lenp, data, datalen);
+ case KEY_RSA_CERT:
case KEY_RSA:
return ssh_rsa_sign(key, sigp, lenp, data, datalen);
default:
@@ -929,8 +1268,10 @@ key_verify(
return -1;
switch (key->type) {
+ case KEY_DSA_CERT:
case KEY_DSA:
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
+ case KEY_RSA_CERT:
case KEY_RSA:
return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
default:
@@ -952,6 +1293,9 @@ key_demote(const Key *k)
pk->rsa = NULL;
switch (k->type) {
+ case KEY_RSA_CERT:
+ key_cert_copy(k, pk);
+ /* FALLTHROUGH */
case KEY_RSA1:
case KEY_RSA:
if ((pk->rsa = RSA_new()) == NULL)
@@ -961,6 +1305,9 @@ key_demote(const Key *k)
if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
fatal("key_demote: BN_dup failed");
break;
+ case KEY_DSA_CERT:
+ key_cert_copy(k, pk);
+ /* FALLTHROUGH */
case KEY_DSA:
if ((pk->dsa = DSA_new()) == NULL)
fatal("key_demote: DSA_new failed");
@@ -980,3 +1327,199 @@ key_demote(const Key *k)
return (pk);
}
+
+int
+key_is_cert(const Key *k)
+{
+ return k != NULL &&
+ (k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT);
+}
+
+/* Return the cert-less equivalent to a certified key type */
+int
+key_type_plain(int type)
+{
+ switch (type) {
+ case KEY_RSA_CERT:
+ return KEY_RSA;
+ case KEY_DSA_CERT:
+ return KEY_DSA;
+ default:
+ return type;
+ }
+}
+
+/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */
+int
+key_to_certified(Key *k)
+{
+ switch (k->type) {
+ case KEY_RSA:
+ k->cert = cert_new();
+ k->type = KEY_RSA_CERT;
+ return 0;
+ case KEY_DSA:
+ k->cert = cert_new();
+ k->type = KEY_DSA_CERT;
+ return 0;
+ default:
+ error("%s: key has incorrect type %s", __func__, key_type(k));
+ return -1;
+ }
+}
+
+/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */
+int
+key_drop_cert(Key *k)
+{
+ switch (k->type) {
+ case KEY_RSA_CERT:
+ cert_free(k->cert);
+ k->type = KEY_RSA;
+ return 0;
+ case KEY_DSA_CERT:
+ cert_free(k->cert);
+ k->type = KEY_DSA;
+ return 0;
+ default:
+ error("%s: key has incorrect type %s", __func__, key_type(k));
+ return -1;
+ }
+}
+
+/* Sign a KEY_RSA_CERT or KEY_DSA_CERT, (re-)generating the signed certblob */
+int
+key_certify(Key *k, Key *ca)
+{
+ Buffer principals;
+ u_char *ca_blob, *sig_blob, nonce[32];
+ u_int i, ca_len, sig_len;
+
+ if (k->cert == NULL) {
+ error("%s: key lacks cert info", __func__);
+ return -1;
+ }
+
+ if (!key_is_cert(k)) {
+ error("%s: certificate has unknown type %d", __func__,
+ k->cert->type);
+ return -1;
+ }
+
+ if (ca->type != KEY_RSA && ca->type != KEY_DSA) {
+ error("%s: CA key has unsupported type %s", __func__,
+ key_type(ca));
+ return -1;
+ }
+
+ key_to_blob(ca, &ca_blob, &ca_len);
+
+ buffer_clear(&k->cert->certblob);
+ buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
+
+ switch (k->type) {
+ case KEY_DSA_CERT:
+ buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
+ buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
+ buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
+ buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
+ break;
+ case KEY_RSA_CERT:
+ buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
+ buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
+ break;
+ default:
+ error("%s: key has incorrect type %s", __func__, key_type(k));
+ buffer_clear(&k->cert->certblob);
+ xfree(ca_blob);
+ return -1;
+ }
+
+ buffer_put_int(&k->cert->certblob, k->cert->type);
+ buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
+
+ buffer_init(&principals);
+ for (i = 0; i < k->cert->nprincipals; i++)
+ buffer_put_cstring(&principals, k->cert->principals[i]);
+ buffer_put_string(&k->cert->certblob, buffer_ptr(&principals),
+ buffer_len(&principals));
+ buffer_free(&principals);
+
+ buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
+ buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
+ buffer_put_string(&k->cert->certblob,
+ buffer_ptr(&k->cert->constraints),
+ buffer_len(&k->cert->constraints));
+
+ arc4random_buf(&nonce, sizeof(nonce));
+ buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
+ buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
+ buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
+ xfree(ca_blob);
+
+ /* Sign the whole mess */
+ if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob),
+ buffer_len(&k->cert->certblob)) != 0) {
+ error("%s: signature operation failed", __func__);
+ buffer_clear(&k->cert->certblob);
+ return -1;
+ }
+ /* Append signature and we are done */
+ buffer_put_string(&k->cert->certblob, sig_blob, sig_len);
+ xfree(sig_blob);
+
+ return 0;
+}
+
+int
+key_cert_check_authority(const Key *k, int want_host, int require_principal,
+ const char *name, const char **reason)
+{
+ u_int i, principal_matches;
+ time_t now = time(NULL);
+
+ if (want_host) {
+ if (k->cert->type != SSH2_CERT_TYPE_HOST) {
+ *reason = "Certificate invalid: not a host certificate";
+ return -1;
+ }
+ } else {
+ if (k->cert->type != SSH2_CERT_TYPE_USER) {
+ *reason = "Certificate invalid: not a user certificate";
+ return -1;
+ }
+ }
+ if (now < 0) {
+ error("%s: system clock lies before epoch", __func__);
+ *reason = "Certificate invalid: not yet valid";
+ return -1;
+ }
+ if ((u_int64_t)now < k->cert->valid_after) {
+ *reason = "Certificate invalid: not yet valid";
+ return -1;
+ }
+ if ((u_int64_t)now >= k->cert->valid_before) {
+ *reason = "Certificate invalid: expired";
+ return -1;
+ }
+ if (k->cert->nprincipals == 0) {
+ if (require_principal) {
+ *reason = "Certificate lacks principal list";
+ return -1;
+ }
+ } else {
+ principal_matches = 0;
+ for (i = 0; i < k->cert->nprincipals; i++) {
+ if (strcmp(name, k->cert->principals[i]) == 0) {
+ principal_matches = 1;
+ break;
+ }
+ }
+ if (!principal_matches) {
+ *reason = "Certificate invalid: name is not a listed "
+ "principal";
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h
index 14aac79..6a2e049 100644
--- a/crypto/openssh/key.h
+++ b/crypto/openssh/key.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.h,v 1.27 2008/06/11 21:01:35 grunk Exp $ */
+/* $OpenBSD: key.h,v 1.28 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -26,6 +26,7 @@
#ifndef KEY_H
#define KEY_H
+#include "buffer.h"
#include <openssl/rsa.h>
#include <openssl/dsa.h>
@@ -34,6 +35,8 @@ enum types {
KEY_RSA1,
KEY_RSA,
KEY_DSA,
+ KEY_RSA_CERT,
+ KEY_DSA_CERT,
KEY_UNSPEC
};
enum fp_type {
@@ -49,20 +52,35 @@ enum fp_rep {
/* key is stored in external hardware */
#define KEY_FLAG_EXT 0x0001
+#define CERT_MAX_PRINCIPALS 256
+struct KeyCert {
+ Buffer certblob; /* Kept around for use on wire */
+ u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
+ char *key_id;
+ u_int nprincipals;
+ char **principals;
+ u_int64_t valid_after, valid_before;
+ Buffer constraints;
+ Key *signature_key;
+};
+
struct Key {
int type;
int flags;
RSA *rsa;
DSA *dsa;
+ struct KeyCert *cert;
};
Key *key_new(int);
+void key_add_private(Key *);
Key *key_new_private(int);
void key_free(Key *);
Key *key_demote(const Key *);
+int key_equal_public(const Key *, const Key *);
int key_equal(const Key *, const Key *);
-char *key_fingerprint(const Key *, enum fp_type, enum fp_rep);
-u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
+char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
+u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
const char *key_type(const Key *);
int key_write(const Key *, FILE *);
int key_read(Key *, char **);
@@ -71,6 +89,14 @@ u_int key_size(const Key *);
Key *key_generate(int, u_int);
Key *key_from_private(const Key *);
int key_type_from_name(char *);
+int key_is_cert(const Key *);
+int key_type_plain(int);
+int key_to_certified(Key *);
+int key_drop_cert(Key *);
+int key_certify(Key *, Key *);
+void key_cert_copy(const Key *, struct Key *);
+int key_cert_check_authority(const Key *, int, int, const char *,
+ const char **);
Key *key_from_blob(const u_char *, u_int);
int key_to_blob(const Key *, u_char **, u_int *);
diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c
index 0ce5bb4..e6eaf0b 100644
--- a/crypto/openssh/loginrec.c
+++ b/crypto/openssh/loginrec.c
@@ -1322,8 +1322,8 @@ wtmpx_write_entry(struct logininfo *li)
static int
wtmpx_islogin(struct logininfo *li, struct utmpx *utx)
{
- if (strncmp(li->username, utx->ut_name,
- MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) {
+ if (strncmp(li->username, utx->ut_user,
+ MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) {
# ifdef HAVE_TYPE_IN_UTMPX
if (utx->ut_type == USER_PROCESS)
return (1);
diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h
index 18f6830..3d7f70f 100644
--- a/crypto/openssh/match.h
+++ b/crypto/openssh/match.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: match.h,v 1.14 2008/06/10 03:57:27 djm Exp $ */
+/* $OpenBSD: match.h,v 1.15 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -23,5 +23,5 @@ char *match_list(const char *, const char *, u_int *);
/* addrmatch.c */
int addr_match_list(const char *, const char *);
-
+int addr_match_cidr_list(const char *, const char *);
#endif
diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
index 143dbf0..e1f7231 100644
--- a/crypto/openssh/misc.c
+++ b/crypto/openssh/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.71 2009/02/21 19:32:04 tobias Exp $ */
+/* $OpenBSD: misc.c,v 1.75 2010/01/09 23:04:13 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -560,11 +560,11 @@ char *
percent_expand(const char *string, ...)
{
#define EXPAND_MAX_KEYS 16
+ u_int num_keys, i, j;
struct {
const char *key;
const char *repl;
} keys[EXPAND_MAX_KEYS];
- u_int num_keys, i, j;
char buf[4096];
va_list ap;
@@ -576,13 +576,12 @@ percent_expand(const char *string, ...)
break;
keys[num_keys].repl = va_arg(ap, char *);
if (keys[num_keys].repl == NULL)
- fatal("percent_expand: NULL replacement");
+ fatal("%s: NULL replacement", __func__);
}
+ if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
+ fatal("%s: too many keys", __func__);
va_end(ap);
- if (num_keys >= EXPAND_MAX_KEYS)
- fatal("percent_expand: too many keys");
-
/* Expand string */
*buf = '\0';
for (i = 0; *string != '\0'; string++) {
@@ -590,23 +589,24 @@ percent_expand(const char *string, ...)
append:
buf[i++] = *string;
if (i >= sizeof(buf))
- fatal("percent_expand: string too long");
+ fatal("%s: string too long", __func__);
buf[i] = '\0';
continue;
}
string++;
+ /* %% case */
if (*string == '%')
goto append;
for (j = 0; j < num_keys; j++) {
if (strchr(keys[j].key, *string) != NULL) {
i = strlcat(buf, keys[j].repl, sizeof(buf));
if (i >= sizeof(buf))
- fatal("percent_expand: string too long");
+ fatal("%s: string too long", __func__);
break;
}
}
if (j >= num_keys)
- fatal("percent_expand: unknown key %%%c", *string);
+ fatal("%s: unknown key %%%c", __func__, *string);
}
return (xstrdup(buf));
#undef EXPAND_MAX_KEYS
@@ -849,3 +849,14 @@ ms_to_timeval(struct timeval *tv, int ms)
tv->tv_usec = (ms % 1000) * 1000;
}
+void
+sock_set_v6only(int s)
+{
+#ifdef IPV6_V6ONLY
+ int on = 1;
+
+ debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
+ error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
+#endif
+}
diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
index 5da170d..32073ac 100644
--- a/crypto/openssh/misc.h
+++ b/crypto/openssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.38 2008/06/12 20:38:28 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.41 2010/01/09 23:04:13 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -35,6 +35,7 @@ char *tohex(const void *, size_t);
void sanitise_stdfd(void);
void ms_subtract_diff(struct timeval *, int *);
void ms_to_timeval(struct timeval *, int);
+void sock_set_v6only(int);
struct passwd *pwcopy(struct passwd *);
const char *ssh_gai_strerror(int);
diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c
index ace25c4..334aedd 100644
--- a/crypto/openssh/monitor.c
+++ b/crypto/openssh/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.104 2009/06/12 20:43:22 andreas Exp $ */
+/* $OpenBSD: monitor.c,v 1.106 2010/03/07 11:57:13 dtucker Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -997,17 +997,6 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
}
#endif
-static void
-mm_append_debug(Buffer *m)
-{
- if (auth_debug_init && buffer_len(&auth_debug)) {
- debug3("%s: Appending debug messages for child", __func__);
- buffer_append(m, buffer_ptr(&auth_debug),
- buffer_len(&auth_debug));
- buffer_clear(&auth_debug);
- }
-}
-
int
mm_answer_keyallowed(int sock, Buffer *m)
{
@@ -1090,8 +1079,6 @@ mm_answer_keyallowed(int sock, Buffer *m)
buffer_put_int(m, allowed);
buffer_put_int(m, forced_command != NULL);
- mm_append_debug(m);
-
mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m);
if (type == MM_RSAHOSTKEY)
@@ -1475,8 +1462,6 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m)
if (key != NULL)
key_free(key);
- mm_append_debug(m);
-
mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m);
monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
@@ -1721,7 +1706,8 @@ mm_get_kex(Buffer *m)
kex->flags = buffer_get_int(m);
kex->client_version_string = buffer_get_string(m, NULL);
kex->server_version_string = buffer_get_string(m, NULL);
- kex->load_host_key=&get_hostkey_by_type;
+ kex->load_host_public_key=&get_hostkey_public_by_type;
+ kex->load_host_private_key=&get_hostkey_private_by_type;
kex->host_key_index=&get_hostkey_index;
return (kex);
diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c
index 4b9a066..7eb6f5c 100644
--- a/crypto/openssh/monitor_fdpass.c
+++ b/crypto/openssh/monitor_fdpass.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_fdpass.c,v 1.18 2008/11/30 11:59:26 dtucker Exp $ */
+/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -34,6 +34,9 @@
#endif
#include <errno.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <string.h>
#include <stdarg.h>
@@ -55,6 +58,7 @@ mm_send_fd(int sock, int fd)
struct iovec vec;
char ch = '\0';
ssize_t n;
+ struct pollfd pfd;
memset(&msg, 0, sizeof(msg));
#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
@@ -75,9 +79,13 @@ mm_send_fd(int sock, int fd)
msg.msg_iov = &vec;
msg.msg_iovlen = 1;
- while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
- errno == EINTR))
+ pfd.fd = sock;
+ pfd.events = POLLOUT;
+ while ((n = sendmsg(sock, &msg, 0)) == -1 &&
+ (errno == EAGAIN || errno == EINTR)) {
debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno));
+ (void)poll(&pfd, 1, -1);
+ }
if (n == -1) {
error("%s: sendmsg(%d): %s", __func__, fd,
strerror(errno));
@@ -112,6 +120,7 @@ mm_receive_fd(int sock)
ssize_t n;
char ch;
int fd;
+ struct pollfd pfd;
memset(&msg, 0, sizeof(msg));
vec.iov_base = &ch;
@@ -126,9 +135,13 @@ mm_receive_fd(int sock)
msg.msg_controllen = sizeof(cmsgbuf.buf);
#endif
- while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
- errno == EINTR))
+ pfd.fd = sock;
+ pfd.events = POLLIN;
+ while ((n = recvmsg(sock, &msg, 0)) == -1 &&
+ (errno == EAGAIN || errno == EINTR)) {
debug3("%s: recvmsg: %s", __func__, strerror(errno));
+ (void)poll(&pfd, 1, -1);
+ }
if (n == -1) {
error("%s: recvmsg: %s", __func__, strerror(errno));
return -1;
diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c
index b8e8710..faeb02c 100644
--- a/crypto/openssh/monitor_wrap.c
+++ b/crypto/openssh/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.68 2009/06/22 05:39:28 dtucker Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.69 2010/03/07 11:57:13 dtucker Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -347,19 +347,6 @@ mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
return (ret);
}
-static void
-mm_send_debug(Buffer *m)
-{
- char *msg;
-
- while (buffer_len(m)) {
- msg = buffer_get_string(m, NULL);
- debug3("%s: Sending debug: %s", __func__, msg);
- packet_send_debug("%s", msg);
- xfree(msg);
- }
-}
-
int
mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
{
@@ -393,9 +380,6 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
have_forced = buffer_get_int(&m);
forced_command = have_forced ? xstrdup("true") : NULL;
- /* Send potential debug messages */
- mm_send_debug(&m);
-
buffer_free(&m);
return (allowed);
@@ -1085,7 +1069,6 @@ mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
*rkey = key;
xfree(blob);
}
- mm_send_debug(&m);
buffer_free(&m);
return (allowed);
diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c
index 79f8376..825fb7a 100644
--- a/crypto/openssh/mux.c
+++ b/crypto/openssh/mux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.7 2008/06/13 17:21:20 dtucker Exp $ */
+/* $OpenBSD: mux.c,v 1.14 2010/01/30 02:54:53 djm Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
@@ -17,25 +17,21 @@
/* ssh session multiplexing support */
-#include "includes.h"
-
/*
* TODO:
- * 1. partial reads in muxserver_accept_control (maybe make channels
- * from accepted connections)
- * 2. Better signalling from master to slave, especially passing of
+ * - Better signalling from master to slave, especially passing of
* error messages
- * 3. Better fall-back from mux slave error to new connection.
- * 3. Add/delete forwardings via slave
- * 4. ExitOnForwardingFailure (after #3 obviously)
- * 5. Maybe extension mechanisms for multi-X11/multi-agent forwarding
- * 6. Document the mux mini-protocol somewhere.
- * 7. Support ~^Z in mux slaves.
- * 8. Inspect or control sessions in master.
- * 9. If we ever support the "signal" channel request, send signals on
- * sessions in master.
+ * - Better fall-back from mux slave error to new connection.
+ * - ExitOnForwardingFailure
+ * - Maybe extension mechanisms for multi-X11/multi-agent forwarding
+ * - Support ~^Z in mux slaves.
+ * - Inspect or control sessions in master.
+ * - If we ever support the "signal" channel request, send signals on
+ * sessions in master.
*/
+#include "includes.h"
+
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
@@ -55,6 +51,14 @@
#include <paths.h>
#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+# ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+# endif
+#endif
+
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
@@ -82,18 +86,22 @@
/* from ssh.c */
extern int tty_flag;
+extern int force_tty_flag;
extern Options options;
extern int stdin_null_flag;
extern char *host;
-int subsystem_flag;
+extern int subsystem_flag;
extern Buffer command;
+extern volatile sig_atomic_t quit_pending;
+extern char *stdio_forward_host;
+extern int stdio_forward_port;
/* Context for session open confirmation callback */
struct mux_session_confirm_ctx {
- int want_tty;
- int want_subsys;
- int want_x_fwd;
- int want_agent_fwd;
+ u_int want_tty;
+ u_int want_subsys;
+ u_int want_x_fwd;
+ u_int want_agent_fwd;
Buffer cmd;
char *term;
struct termios tio;
@@ -103,6 +111,9 @@ struct mux_session_confirm_ctx {
/* fd to control socket */
int muxserver_sock = -1;
+/* client request id */
+u_int muxclient_request_id = 0;
+
/* Multiplexing control command */
u_int muxclient_command = 0;
@@ -112,16 +123,831 @@ static volatile sig_atomic_t muxclient_terminate = 0;
/* PID of multiplex server */
static u_int muxserver_pid = 0;
+static Channel *mux_listener_channel = NULL;
+
+struct mux_master_state {
+ int hello_rcvd;
+};
+
+/* mux protocol messages */
+#define MUX_MSG_HELLO 0x00000001
+#define MUX_C_NEW_SESSION 0x10000002
+#define MUX_C_ALIVE_CHECK 0x10000004
+#define MUX_C_TERMINATE 0x10000005
+#define MUX_C_OPEN_FWD 0x10000006
+#define MUX_C_CLOSE_FWD 0x10000007
+#define MUX_C_NEW_STDIO_FWD 0x10000008
+#define MUX_S_OK 0x80000001
+#define MUX_S_PERMISSION_DENIED 0x80000002
+#define MUX_S_FAILURE 0x80000003
+#define MUX_S_EXIT_MESSAGE 0x80000004
+#define MUX_S_ALIVE 0x80000005
+#define MUX_S_SESSION_OPENED 0x80000006
+
+/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
+#define MUX_FWD_LOCAL 1
+#define MUX_FWD_REMOTE 2
+#define MUX_FWD_DYNAMIC 3
+
+static void mux_session_confirm(int, void *);
+
+static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
+
+static const struct {
+ u_int type;
+ int (*handler)(u_int, Channel *, Buffer *, Buffer *);
+} mux_master_handlers[] = {
+ { MUX_MSG_HELLO, process_mux_master_hello },
+ { MUX_C_NEW_SESSION, process_mux_new_session },
+ { MUX_C_ALIVE_CHECK, process_mux_alive_check },
+ { MUX_C_TERMINATE, process_mux_terminate },
+ { MUX_C_OPEN_FWD, process_mux_open_fwd },
+ { MUX_C_CLOSE_FWD, process_mux_close_fwd },
+ { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
+ { 0, NULL }
+};
+
+/* Cleanup callback fired on closure of mux slave _session_ channel */
+/* ARGSUSED */
+static void
+mux_master_session_cleanup_cb(int cid, void *unused)
+{
+ Channel *cc, *c = channel_by_id(cid);
+
+ debug3("%s: entering for channel %d", __func__, cid);
+ if (c == NULL)
+ fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
+ if (c->ctl_chan != -1) {
+ if ((cc = channel_by_id(c->ctl_chan)) == NULL)
+ fatal("%s: channel %d missing control channel %d",
+ __func__, c->self, c->ctl_chan);
+ c->ctl_chan = -1;
+ cc->remote_id = -1;
+ chan_rcvd_oclose(cc);
+ }
+ channel_cancel_cleanup(c->self);
+}
+
+/* Cleanup callback fired on closure of mux slave _control_ channel */
+/* ARGSUSED */
+static void
+mux_master_control_cleanup_cb(int cid, void *unused)
+{
+ Channel *sc, *c = channel_by_id(cid);
+
+ debug3("%s: entering for channel %d", __func__, cid);
+ if (c == NULL)
+ fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
+ if (c->remote_id != -1) {
+ if ((sc = channel_by_id(c->remote_id)) == NULL)
+ debug2("%s: channel %d n session channel %d",
+ __func__, c->self, c->remote_id);
+ c->remote_id = -1;
+ sc->ctl_chan = -1;
+ if (sc->type != SSH_CHANNEL_OPEN) {
+ debug2("%s: channel %d: not open", __func__, sc->self);
+ chan_mark_dead(sc);
+ } else {
+ if (sc->istate == CHAN_INPUT_OPEN)
+ chan_read_failed(sc);
+ if (sc->ostate == CHAN_OUTPUT_OPEN)
+ chan_write_failed(sc);
+ }
+ }
+ channel_cancel_cleanup(c->self);
+}
+
+/* Check mux client environment variables before passing them to mux master. */
+static int
+env_permitted(char *env)
+{
+ int i, ret;
+ char name[1024], *cp;
+
+ if ((cp = strchr(env, '=')) == NULL || cp == env)
+ return 0;
+ ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
+ if (ret <= 0 || (size_t)ret >= sizeof(name)) {
+ error("env_permitted: name '%.100s...' too long", env);
+ return 0;
+ }
+
+ for (i = 0; i < options.num_send_env; i++)
+ if (match_pattern(name, options.send_env[i]))
+ return 1;
+
+ return 0;
+}
+
+/* Mux master protocol message handlers */
+
+static int
+process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ u_int ver;
+ struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
+
+ if (state == NULL)
+ fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self);
+ if (state->hello_rcvd) {
+ error("%s: HELLO received twice", __func__);
+ return -1;
+ }
+ if (buffer_get_int_ret(&ver, m) != 0) {
+ malf:
+ error("%s: malformed message", __func__);
+ return -1;
+ }
+ if (ver != SSHMUX_VER) {
+ error("Unsupported multiplexing protocol version %d "
+ "(expected %d)", ver, SSHMUX_VER);
+ return -1;
+ }
+ debug2("%s: channel %d slave version %u", __func__, c->self, ver);
+
+ /* No extensions are presently defined */
+ while (buffer_len(m) > 0) {
+ char *name = buffer_get_string_ret(m, NULL);
+ char *value = buffer_get_string_ret(m, NULL);
+
+ if (name == NULL || value == NULL) {
+ if (name != NULL)
+ xfree(name);
+ goto malf;
+ }
+ debug2("Unrecognised slave extension \"%s\"", name);
+ xfree(name);
+ xfree(value);
+ }
+ state->hello_rcvd = 1;
+ return 0;
+}
+
+static int
+process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ Channel *nc;
+ struct mux_session_confirm_ctx *cctx;
+ char *reserved, *cmd, *cp;
+ u_int i, j, len, env_len, escape_char, window, packetmax;
+ int new_fd[3];
+
+ /* Reply for SSHMUX_COMMAND_OPEN */
+ cctx = xcalloc(1, sizeof(*cctx));
+ cctx->term = NULL;
+ cmd = reserved = NULL;
+ if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
+ buffer_get_int_ret(&cctx->want_tty, m) != 0 ||
+ buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 ||
+ buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 ||
+ buffer_get_int_ret(&cctx->want_subsys, m) != 0 ||
+ buffer_get_int_ret(&escape_char, m) != 0 ||
+ (cctx->term = buffer_get_string_ret(m, &len)) == NULL ||
+ (cmd = buffer_get_string_ret(m, &len)) == NULL) {
+ malf:
+ if (cmd != NULL)
+ xfree(cmd);
+ if (reserved != NULL)
+ xfree(reserved);
+ if (cctx->term != NULL)
+ xfree(cctx->term);
+ error("%s: malformed message", __func__);
+ return -1;
+ }
+ xfree(reserved);
+ reserved = NULL;
+
+ cctx->env = NULL;
+ env_len = 0;
+ while (buffer_len(m) > 0) {
+#define MUX_MAX_ENV_VARS 4096
+ if ((cp = buffer_get_string_ret(m, &len)) == NULL) {
+ xfree(cmd);
+ goto malf;
+ }
+ if (!env_permitted(cp)) {
+ xfree(cp);
+ continue;
+ }
+ cctx->env = xrealloc(cctx->env, env_len + 2,
+ sizeof(*cctx->env));
+ cctx->env[env_len++] = cp;
+ cctx->env[env_len] = NULL;
+ if (env_len > MUX_MAX_ENV_VARS) {
+ error(">%d environment variables received, ignoring "
+ "additional", MUX_MAX_ENV_VARS);
+ break;
+ }
+ }
+
+ debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, "
+ "term \"%s\", cmd \"%s\", env %u", __func__, c->self,
+ cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,
+ cctx->want_subsys, cctx->term, cmd, env_len);
+
+ buffer_init(&cctx->cmd);
+ buffer_append(&cctx->cmd, cmd, strlen(cmd));
+ xfree(cmd);
+ cmd = NULL;
+
+ /* Gather fds from client */
+ for(i = 0; i < 3; i++) {
+ if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
+ error("%s: failed to receive fd %d from slave",
+ __func__, i);
+ for (j = 0; j < i; j++)
+ close(new_fd[j]);
+ for (j = 0; j < env_len; j++)
+ xfree(cctx->env[j]);
+ if (env_len > 0)
+ xfree(cctx->env);
+ xfree(cctx->term);
+ buffer_free(&cctx->cmd);
+ xfree(cctx);
+
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r,
+ "did not receive file descriptors");
+ return -1;
+ }
+ }
+
+ debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
+ new_fd[0], new_fd[1], new_fd[2]);
+
+ /* XXX support multiple child sessions in future */
+ if (c->remote_id != -1) {
+ debug2("%s: session already open", __func__);
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Multiple sessions not supported");
+ cleanup:
+ close(new_fd[0]);
+ close(new_fd[1]);
+ close(new_fd[2]);
+ xfree(cctx->term);
+ if (env_len != 0) {
+ for (i = 0; i < env_len; i++)
+ xfree(cctx->env[i]);
+ xfree(cctx->env);
+ }
+ buffer_free(&cctx->cmd);
+ return 0;
+ }
+
+ if (options.control_master == SSHCTL_MASTER_ASK ||
+ options.control_master == SSHCTL_MASTER_AUTO_ASK) {
+ if (!ask_permission("Allow shared connection to %s? ", host)) {
+ debug2("%s: session refused by user", __func__);
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_PERMISSION_DENIED);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Permission denied");
+ goto cleanup;
+ }
+ }
+
+ /* Try to pick up ttymodes from client before it goes raw */
+ if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
+ error("%s: tcgetattr: %s", __func__, strerror(errno));
+
+ /* enable nonblocking unless tty */
+ if (!isatty(new_fd[0]))
+ set_nonblock(new_fd[0]);
+ if (!isatty(new_fd[1]))
+ set_nonblock(new_fd[1]);
+ if (!isatty(new_fd[2]))
+ set_nonblock(new_fd[2]);
+
+ window = CHAN_SES_WINDOW_DEFAULT;
+ packetmax = CHAN_SES_PACKET_DEFAULT;
+ if (cctx->want_tty) {
+ window >>= 1;
+ packetmax >>= 1;
+ }
+
+ nc = channel_new("session", SSH_CHANNEL_OPENING,
+ new_fd[0], new_fd[1], new_fd[2], window, packetmax,
+ CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
+
+ nc->ctl_chan = c->self; /* link session -> control channel */
+ c->remote_id = nc->self; /* link control -> session channel */
+
+ if (cctx->want_tty && escape_char != 0xffffffff) {
+ channel_register_filter(nc->self,
+ client_simple_escape_filter, NULL,
+ client_filter_cleanup,
+ client_new_escape_filter_ctx((int)escape_char));
+ }
+
+ debug2("%s: channel_new: %d linked to control channel %d",
+ __func__, nc->self, nc->ctl_chan);
+
+ channel_send_open(nc->self);
+ channel_register_open_confirm(nc->self, mux_session_confirm, cctx);
+ channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0);
+
+ /* prepare reply */
+ /* XXX defer until mux_session_confirm() fires */
+ buffer_put_int(r, MUX_S_SESSION_OPENED);
+ buffer_put_int(r, rid);
+ buffer_put_int(r, nc->self);
+
+ return 0;
+}
+
+static int
+process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ debug2("%s: channel %d: alive check", __func__, c->self);
+
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_ALIVE);
+ buffer_put_int(r, rid);
+ buffer_put_int(r, (u_int)getpid());
+
+ return 0;
+}
+
+static int
+process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ debug2("%s: channel %d: terminate request", __func__, c->self);
+
+ if (options.control_master == SSHCTL_MASTER_ASK ||
+ options.control_master == SSHCTL_MASTER_AUTO_ASK) {
+ if (!ask_permission("Terminate shared connection to %s? ",
+ host)) {
+ debug2("%s: termination refused by user", __func__);
+ buffer_put_int(r, MUX_S_PERMISSION_DENIED);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Permission denied");
+ return 0;
+ }
+ }
+
+ quit_pending = 1;
+ buffer_put_int(r, MUX_S_OK);
+ buffer_put_int(r, rid);
+ /* XXX exit happens too soon - message never makes it to client */
+ return 0;
+}
+
+static char *
+format_forward(u_int ftype, Forward *fwd)
+{
+ char *ret;
+
+ switch (ftype) {
+ case MUX_FWD_LOCAL:
+ xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
+ (fwd->listen_host == NULL) ?
+ (options.gateway_ports ? "*" : "LOCALHOST") :
+ fwd->listen_host, fwd->listen_port,
+ fwd->connect_host, fwd->connect_port);
+ break;
+ case MUX_FWD_DYNAMIC:
+ xasprintf(&ret, "dynamic forward %.200s:%d -> *",
+ (fwd->listen_host == NULL) ?
+ (options.gateway_ports ? "*" : "LOCALHOST") :
+ fwd->listen_host, fwd->listen_port);
+ break;
+ case MUX_FWD_REMOTE:
+ xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
+ (fwd->listen_host == NULL) ?
+ "LOCALHOST" : fwd->listen_host,
+ fwd->listen_port,
+ fwd->connect_host, fwd->connect_port);
+ break;
+ default:
+ fatal("%s: unknown forward type %u", __func__, ftype);
+ }
+ return ret;
+}
+
+static int
+compare_host(const char *a, const char *b)
+{
+ if (a == NULL && b == NULL)
+ return 1;
+ if (a == NULL || b == NULL)
+ return 0;
+ return strcmp(a, b) == 0;
+}
+
+static int
+compare_forward(Forward *a, Forward *b)
+{
+ if (!compare_host(a->listen_host, b->listen_host))
+ return 0;
+ if (a->listen_port != b->listen_port)
+ return 0;
+ if (!compare_host(a->connect_host, b->connect_host))
+ return 0;
+ if (a->connect_port != b->connect_port)
+ return 0;
+
+ return 1;
+}
+
+static int
+process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ Forward fwd;
+ char *fwd_desc = NULL;
+ u_int ftype;
+ int i, ret = 0, freefwd = 1;
+
+ fwd.listen_host = fwd.connect_host = NULL;
+ if (buffer_get_int_ret(&ftype, m) != 0 ||
+ (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
+ buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
+ (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
+ buffer_get_int_ret(&fwd.connect_port, m) != 0) {
+ error("%s: malformed message", __func__);
+ ret = -1;
+ goto out;
+ }
+
+ if (*fwd.listen_host == '\0') {
+ xfree(fwd.listen_host);
+ fwd.listen_host = NULL;
+ }
+ if (*fwd.connect_host == '\0') {
+ xfree(fwd.connect_host);
+ fwd.connect_host = NULL;
+ }
+
+ debug2("%s: channel %d: request %s", __func__, c->self,
+ (fwd_desc = format_forward(ftype, &fwd)));
+
+ if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&
+ ftype != MUX_FWD_DYNAMIC) {
+ logit("%s: invalid forwarding type %u", __func__, ftype);
+ invalid:
+ xfree(fwd.listen_host);
+ xfree(fwd.connect_host);
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Invalid forwarding request");
+ return 0;
+ }
+ /* XXX support rport0 forwarding with reply of port assigned */
+ if (fwd.listen_port == 0 || fwd.listen_port >= 65536) {
+ logit("%s: invalid listen port %u", __func__,
+ fwd.listen_port);
+ goto invalid;
+ }
+ if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC &&
+ ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
+ logit("%s: invalid connect port %u", __func__,
+ fwd.connect_port);
+ goto invalid;
+ }
+ if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) {
+ logit("%s: missing connect host", __func__);
+ goto invalid;
+ }
+
+ /* Skip forwards that have already been requested */
+ switch (ftype) {
+ case MUX_FWD_LOCAL:
+ case MUX_FWD_DYNAMIC:
+ for (i = 0; i < options.num_local_forwards; i++) {
+ if (compare_forward(&fwd,
+ options.local_forwards + i)) {
+ exists:
+ debug2("%s: found existing forwarding",
+ __func__);
+ buffer_put_int(r, MUX_S_OK);
+ buffer_put_int(r, rid);
+ goto out;
+ }
+ }
+ break;
+ case MUX_FWD_REMOTE:
+ for (i = 0; i < options.num_remote_forwards; i++) {
+ if (compare_forward(&fwd,
+ options.remote_forwards + i))
+ goto exists;
+ }
+ break;
+ }
+
+ if (options.control_master == SSHCTL_MASTER_ASK ||
+ options.control_master == SSHCTL_MASTER_AUTO_ASK) {
+ if (!ask_permission("Open %s on %s?", fwd_desc, host)) {
+ debug2("%s: forwarding refused by user", __func__);
+ buffer_put_int(r, MUX_S_PERMISSION_DENIED);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Permission denied");
+ goto out;
+ }
+ }
+
+ if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
+ if (options.num_local_forwards + 1 >=
+ SSH_MAX_FORWARDS_PER_DIRECTION ||
+ channel_setup_local_fwd_listener(fwd.listen_host,
+ fwd.listen_port, fwd.connect_host, fwd.connect_port,
+ options.gateway_ports) < 0) {
+ fail:
+ logit("slave-requested %s failed", fwd_desc);
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Port forwarding failed");
+ goto out;
+ }
+ add_local_forward(&options, &fwd);
+ freefwd = 0;
+ } else {
+ /* XXX wait for remote to confirm */
+ if (options.num_remote_forwards + 1 >=
+ SSH_MAX_FORWARDS_PER_DIRECTION ||
+ channel_request_remote_forwarding(fwd.listen_host,
+ fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0)
+ goto fail;
+ add_remote_forward(&options, &fwd);
+ freefwd = 0;
+ }
+ buffer_put_int(r, MUX_S_OK);
+ buffer_put_int(r, rid);
+ out:
+ if (fwd_desc != NULL)
+ xfree(fwd_desc);
+ if (freefwd) {
+ if (fwd.listen_host != NULL)
+ xfree(fwd.listen_host);
+ if (fwd.connect_host != NULL)
+ xfree(fwd.connect_host);
+ }
+ return ret;
+}
+
+static int
+process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ Forward fwd;
+ char *fwd_desc = NULL;
+ u_int ftype;
+ int ret = 0;
+
+ fwd.listen_host = fwd.connect_host = NULL;
+ if (buffer_get_int_ret(&ftype, m) != 0 ||
+ (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
+ buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
+ (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
+ buffer_get_int_ret(&fwd.connect_port, m) != 0) {
+ error("%s: malformed message", __func__);
+ ret = -1;
+ goto out;
+ }
+
+ if (*fwd.listen_host == '\0') {
+ xfree(fwd.listen_host);
+ fwd.listen_host = NULL;
+ }
+ if (*fwd.connect_host == '\0') {
+ xfree(fwd.connect_host);
+ fwd.connect_host = NULL;
+ }
+
+ debug2("%s: channel %d: request %s", __func__, c->self,
+ (fwd_desc = format_forward(ftype, &fwd)));
+
+ /* XXX implement this */
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "unimplemented");
+
+ out:
+ if (fwd_desc != NULL)
+ xfree(fwd_desc);
+ if (fwd.listen_host != NULL)
+ xfree(fwd.listen_host);
+ if (fwd.connect_host != NULL)
+ xfree(fwd.connect_host);
+
+ return ret;
+}
+
+static int
+process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ Channel *nc;
+ char *reserved, *chost;
+ u_int cport, i, j;
+ int new_fd[2];
+
+ chost = reserved = NULL;
+ if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
+ (chost = buffer_get_string_ret(m, NULL)) == NULL ||
+ buffer_get_int_ret(&cport, m) != 0) {
+ if (reserved != NULL)
+ xfree(reserved);
+ if (chost != NULL)
+ xfree(chost);
+ error("%s: malformed message", __func__);
+ return -1;
+ }
+ xfree(reserved);
+
+ debug2("%s: channel %d: request stdio fwd to %s:%u",
+ __func__, c->self, chost, cport);
+
+ /* Gather fds from client */
+ for(i = 0; i < 2; i++) {
+ if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
+ error("%s: failed to receive fd %d from slave",
+ __func__, i);
+ for (j = 0; j < i; j++)
+ close(new_fd[j]);
+ xfree(chost);
+
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r,
+ "did not receive file descriptors");
+ return -1;
+ }
+ }
+
+ debug3("%s: got fds stdin %d, stdout %d", __func__,
+ new_fd[0], new_fd[1]);
+
+ /* XXX support multiple child sessions in future */
+ if (c->remote_id != -1) {
+ debug2("%s: session already open", __func__);
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_FAILURE);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Multiple sessions not supported");
+ cleanup:
+ close(new_fd[0]);
+ close(new_fd[1]);
+ xfree(chost);
+ return 0;
+ }
+
+ if (options.control_master == SSHCTL_MASTER_ASK ||
+ options.control_master == SSHCTL_MASTER_AUTO_ASK) {
+ if (!ask_permission("Allow forward to to %s:%u? ",
+ chost, cport)) {
+ debug2("%s: stdio fwd refused by user", __func__);
+ /* prepare reply */
+ buffer_put_int(r, MUX_S_PERMISSION_DENIED);
+ buffer_put_int(r, rid);
+ buffer_put_cstring(r, "Permission denied");
+ goto cleanup;
+ }
+ }
+
+ /* enable nonblocking unless tty */
+ if (!isatty(new_fd[0]))
+ set_nonblock(new_fd[0]);
+ if (!isatty(new_fd[1]))
+ set_nonblock(new_fd[1]);
+
+ nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]);
-/* ** Multiplexing master support */
+ nc->ctl_chan = c->self; /* link session -> control channel */
+ c->remote_id = nc->self; /* link control -> session channel */
+
+ debug2("%s: channel_new: %d linked to control channel %d",
+ __func__, nc->self, nc->ctl_chan);
+
+ channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0);
+
+ /* prepare reply */
+ /* XXX defer until channel confirmed */
+ buffer_put_int(r, MUX_S_SESSION_OPENED);
+ buffer_put_int(r, rid);
+ buffer_put_int(r, nc->self);
+
+ return 0;
+}
+
+/* Channel callbacks fired on read/write from mux slave fd */
+static int
+mux_master_read_cb(Channel *c)
+{
+ struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
+ Buffer in, out;
+ void *ptr;
+ u_int type, rid, have, i;
+ int ret = -1;
+
+ /* Setup ctx and */
+ if (c->mux_ctx == NULL) {
+ state = xcalloc(1, sizeof(state));
+ c->mux_ctx = state;
+ channel_register_cleanup(c->self,
+ mux_master_control_cleanup_cb, 0);
+
+ /* Send hello */
+ buffer_init(&out);
+ buffer_put_int(&out, MUX_MSG_HELLO);
+ buffer_put_int(&out, SSHMUX_VER);
+ /* no extensions */
+ buffer_put_string(&c->output, buffer_ptr(&out),
+ buffer_len(&out));
+ buffer_free(&out);
+ debug3("%s: channel %d: hello sent", __func__, c->self);
+ return 0;
+ }
+
+ buffer_init(&in);
+ buffer_init(&out);
+
+ /* Channel code ensures that we receive whole packets */
+ if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) {
+ malf:
+ error("%s: malformed message", __func__);
+ goto out;
+ }
+ buffer_append(&in, ptr, have);
+
+ if (buffer_get_int_ret(&type, &in) != 0)
+ goto malf;
+ debug3("%s: channel %d packet type 0x%08x len %u",
+ __func__, c->self, type, buffer_len(&in));
+
+ if (type == MUX_MSG_HELLO)
+ rid = 0;
+ else {
+ if (!state->hello_rcvd) {
+ error("%s: expected MUX_MSG_HELLO(0x%08x), "
+ "received 0x%08x", __func__, MUX_MSG_HELLO, type);
+ goto out;
+ }
+ if (buffer_get_int_ret(&rid, &in) != 0)
+ goto malf;
+ }
+
+ for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
+ if (type == mux_master_handlers[i].type) {
+ ret = mux_master_handlers[i].handler(rid, c, &in, &out);
+ break;
+ }
+ }
+ if (mux_master_handlers[i].handler == NULL) {
+ error("%s: unsupported mux message 0x%08x", __func__, type);
+ buffer_put_int(&out, MUX_S_FAILURE);
+ buffer_put_int(&out, rid);
+ buffer_put_cstring(&out, "unsupported request");
+ ret = 0;
+ }
+ /* Enqueue reply packet */
+ if (buffer_len(&out) != 0) {
+ buffer_put_string(&c->output, buffer_ptr(&out),
+ buffer_len(&out));
+ }
+ out:
+ buffer_free(&in);
+ buffer_free(&out);
+ return ret;
+}
+
+void
+mux_exit_message(Channel *c, int exitval)
+{
+ Buffer m;
+ Channel *mux_chan;
+
+ debug3("%s: channel %d: exit message, evitval %d", __func__, c->self,
+ exitval);
+
+ if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
+ fatal("%s: channel %d missing mux channel %d",
+ __func__, c->self, c->ctl_chan);
+
+ /* Append exit message packet to control socket output queue */
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_S_EXIT_MESSAGE);
+ buffer_put_int(&m, c->self);
+ buffer_put_int(&m, exitval);
+
+ buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
+ buffer_free(&m);
+}
/* Prepare a mux master to listen on a Unix domain socket. */
void
muxserver_listen(void)
{
struct sockaddr_un addr;
+ socklen_t sun_len;
mode_t old_umask;
- int addr_len;
if (options.control_path == NULL ||
options.control_master == SSHCTL_MASTER_NO)
@@ -131,7 +957,7 @@ muxserver_listen(void)
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
- addr_len = offsetof(struct sockaddr_un, sun_path) +
+ sun_len = offsetof(struct sockaddr_un, sun_path) +
strlen(options.control_path) + 1;
if (strlcpy(addr.sun_path, options.control_path,
@@ -142,7 +968,7 @@ muxserver_listen(void)
fatal("%s socket(): %s", __func__, strerror(errno));
old_umask = umask(0177);
- if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) {
+ if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) {
muxserver_sock = -1;
if (errno == EINVAL || errno == EADDRINUSE) {
error("ControlSocket %s already exists, "
@@ -162,6 +988,14 @@ muxserver_listen(void)
fatal("%s listen(): %s", __func__, strerror(errno));
set_nonblock(muxserver_sock);
+
+ mux_listener_channel = channel_new("mux listener",
+ SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
+ CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
+ 0, addr.sun_path, 1);
+ mux_listener_channel->mux_rcb = mux_master_read_cb;
+ debug3("%s: mux listener channel %d fd %d", __func__,
+ mux_listener_channel->self, mux_listener_channel->sock);
}
/* Callback on open confirmation in mux master for a mux client session. */
@@ -175,7 +1009,7 @@ mux_session_confirm(int id, void *arg)
if (cctx == NULL)
fatal("%s: cctx == NULL", __func__);
- if ((c = channel_lookup(id)) == NULL)
+ if ((c = channel_by_id(id)) == NULL)
fatal("%s: no channel for id %d", __func__, id);
display = getenv("DISPLAY");
@@ -210,291 +1044,616 @@ mux_session_confirm(int id, void *arg)
xfree(cctx);
}
+/* ** Multiplexing client support */
+
+/* Exit signal handler */
+static void
+control_client_sighandler(int signo)
+{
+ muxclient_terminate = signo;
+}
+
/*
- * Accept a connection on the mux master socket and process the
- * client's request. Returns flag indicating whether mux master should
- * begin graceful close.
+ * Relay signal handler - used to pass some signals from mux client to
+ * mux master.
*/
-int
-muxserver_accept_control(void)
+static void
+control_client_sigrelay(int signo)
{
- Buffer m;
- Channel *c;
- int client_fd, new_fd[3], ver, allowed, window, packetmax;
- socklen_t addrlen;
- struct sockaddr_storage addr;
- struct mux_session_confirm_ctx *cctx;
- char *cmd;
- u_int i, j, len, env_len, mux_command, flags, escape_char;
- uid_t euid;
- gid_t egid;
- int start_close = 0;
+ int save_errno = errno;
- /*
- * Accept connection on control socket
- */
- memset(&addr, 0, sizeof(addr));
- addrlen = sizeof(addr);
- if ((client_fd = accept(muxserver_sock,
- (struct sockaddr*)&addr, &addrlen)) == -1) {
- error("%s accept: %s", __func__, strerror(errno));
- return 0;
+ if (muxserver_pid > 1)
+ kill(muxserver_pid, signo);
+
+ errno = save_errno;
+}
+
+static int
+mux_client_read(int fd, Buffer *b, u_int need)
+{
+ u_int have;
+ ssize_t len;
+ u_char *p;
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ p = buffer_append_space(b, need);
+ for (have = 0; have < need; ) {
+ if (muxclient_terminate) {
+ errno = EINTR;
+ return -1;
+ }
+ len = read(fd, p + have, need - have);
+ if (len < 0) {
+ switch (errno) {
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK:
+#endif
+ case EAGAIN:
+ (void)poll(&pfd, 1, -1);
+ /* FALLTHROUGH */
+ case EINTR:
+ continue;
+ default:
+ return -1;
+ }
+ }
+ if (len == 0) {
+ errno = EPIPE;
+ return -1;
+ }
+ have += (u_int)len;
}
+ return 0;
+}
- if (getpeereid(client_fd, &euid, &egid) < 0) {
- error("%s getpeereid failed: %s", __func__, strerror(errno));
- close(client_fd);
- return 0;
+static int
+mux_client_write_packet(int fd, Buffer *m)
+{
+ Buffer queue;
+ u_int have, need;
+ int oerrno, len;
+ u_char *ptr;
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = POLLOUT;
+ buffer_init(&queue);
+ buffer_put_string(&queue, buffer_ptr(m), buffer_len(m));
+
+ need = buffer_len(&queue);
+ ptr = buffer_ptr(&queue);
+
+ for (have = 0; have < need; ) {
+ if (muxclient_terminate) {
+ buffer_free(&queue);
+ errno = EINTR;
+ return -1;
+ }
+ len = write(fd, ptr + have, need - have);
+ if (len < 0) {
+ switch (errno) {
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK:
+#endif
+ case EAGAIN:
+ (void)poll(&pfd, 1, -1);
+ /* FALLTHROUGH */
+ case EINTR:
+ continue;
+ default:
+ oerrno = errno;
+ buffer_free(&queue);
+ errno = oerrno;
+ return -1;
+ }
+ }
+ if (len == 0) {
+ buffer_free(&queue);
+ errno = EPIPE;
+ return -1;
+ }
+ have += (u_int)len;
}
- if ((euid != 0) && (getuid() != euid)) {
- error("control mode uid mismatch: peer euid %u != uid %u",
- (u_int) euid, (u_int) getuid());
- close(client_fd);
- return 0;
+ buffer_free(&queue);
+ return 0;
+}
+
+static int
+mux_client_read_packet(int fd, Buffer *m)
+{
+ Buffer queue;
+ u_int need, have;
+ void *ptr;
+ int oerrno;
+
+ buffer_init(&queue);
+ if (mux_client_read(fd, &queue, 4) != 0) {
+ if ((oerrno = errno) == EPIPE)
+ debug3("%s: read header failed: %s", __func__, strerror(errno));
+ errno = oerrno;
+ return -1;
}
+ need = get_u32(buffer_ptr(&queue));
+ if (mux_client_read(fd, &queue, need) != 0) {
+ oerrno = errno;
+ debug3("%s: read body failed: %s", __func__, strerror(errno));
+ errno = oerrno;
+ return -1;
+ }
+ ptr = buffer_get_string_ptr(&queue, &have);
+ buffer_append(m, ptr, have);
+ buffer_free(&queue);
+ return 0;
+}
- /* XXX handle asynchronously */
- unset_nonblock(client_fd);
+static int
+mux_client_hello_exchange(int fd)
+{
+ Buffer m;
+ u_int type, ver;
- /* Read command */
buffer_init(&m);
- if (ssh_msg_recv(client_fd, &m) == -1) {
- error("%s: client msg_recv failed", __func__);
- close(client_fd);
+ buffer_put_int(&m, MUX_MSG_HELLO);
+ buffer_put_int(&m, SSHMUX_VER);
+ /* no extensions */
+
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
+
+ buffer_clear(&m);
+
+ /* Read their HELLO */
+ if (mux_client_read_packet(fd, &m) != 0) {
buffer_free(&m);
- return 0;
+ return -1;
+ }
+
+ type = buffer_get_int(&m);
+ if (type != MUX_MSG_HELLO)
+ fatal("%s: expected HELLO (%u) received %u",
+ __func__, MUX_MSG_HELLO, type);
+ ver = buffer_get_int(&m);
+ if (ver != SSHMUX_VER)
+ fatal("Unsupported multiplexing protocol version %d "
+ "(expected %d)", ver, SSHMUX_VER);
+ debug2("%s: master version %u", __func__, ver);
+ /* No extensions are presently defined */
+ while (buffer_len(&m) > 0) {
+ char *name = buffer_get_string(&m, NULL);
+ char *value = buffer_get_string(&m, NULL);
+
+ debug2("Unrecognised master extension \"%s\"", name);
+ xfree(name);
+ xfree(value);
}
- if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
- error("%s: wrong client version %d", __func__, ver);
+ buffer_free(&m);
+ return 0;
+}
+
+static u_int
+mux_client_request_alive(int fd)
+{
+ Buffer m;
+ char *e;
+ u_int pid, type, rid;
+
+ debug3("%s: entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_C_ALIVE_CHECK);
+ buffer_put_int(&m, muxclient_request_id);
+
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
+
+ buffer_clear(&m);
+
+ /* Read their reply */
+ if (mux_client_read_packet(fd, &m) != 0) {
buffer_free(&m);
- close(client_fd);
return 0;
}
- allowed = 1;
- mux_command = buffer_get_int(&m);
- flags = buffer_get_int(&m);
+ type = buffer_get_int(&m);
+ if (type != MUX_S_ALIVE) {
+ e = buffer_get_string(&m, NULL);
+ fatal("%s: master returned error: %s", __func__, e);
+ }
+
+ if ((rid = buffer_get_int(&m)) != muxclient_request_id)
+ fatal("%s: out of sequence reply: my id %u theirs %u",
+ __func__, muxclient_request_id, rid);
+ pid = buffer_get_int(&m);
+ buffer_free(&m);
+
+ debug3("%s: done pid = %u", __func__, pid);
+
+ muxclient_request_id++;
+
+ return pid;
+}
+
+static void
+mux_client_request_terminate(int fd)
+{
+ Buffer m;
+ char *e;
+ u_int type, rid;
+
+ debug3("%s: entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_C_TERMINATE);
+ buffer_put_int(&m, muxclient_request_id);
+
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
buffer_clear(&m);
- switch (mux_command) {
- case SSHMUX_COMMAND_OPEN:
- if (options.control_master == SSHCTL_MASTER_ASK ||
- options.control_master == SSHCTL_MASTER_AUTO_ASK)
- allowed = ask_permission("Allow shared connection "
- "to %s? ", host);
- /* continue below */
- break;
- case SSHMUX_COMMAND_TERMINATE:
- if (options.control_master == SSHCTL_MASTER_ASK ||
- options.control_master == SSHCTL_MASTER_AUTO_ASK)
- allowed = ask_permission("Terminate shared connection "
- "to %s? ", host);
- if (allowed)
- start_close = 1;
- /* FALLTHROUGH */
- case SSHMUX_COMMAND_ALIVE_CHECK:
- /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
- buffer_clear(&m);
- buffer_put_int(&m, allowed);
- buffer_put_int(&m, getpid());
- if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
- error("%s: client msg_send failed", __func__);
- close(client_fd);
+ /* Read their reply */
+ if (mux_client_read_packet(fd, &m) != 0) {
+ /* Remote end exited already */
+ if (errno == EPIPE) {
buffer_free(&m);
- return start_close;
+ return;
}
- buffer_free(&m);
- close(client_fd);
- return start_close;
+ fatal("%s: read from master failed: %s",
+ __func__, strerror(errno));
+ }
+
+ type = buffer_get_int(&m);
+ if ((rid = buffer_get_int(&m)) != muxclient_request_id)
+ fatal("%s: out of sequence reply: my id %u theirs %u",
+ __func__, muxclient_request_id, rid);
+ switch (type) {
+ case MUX_S_OK:
+ break;
+ case MUX_S_PERMISSION_DENIED:
+ e = buffer_get_string(&m, NULL);
+ fatal("Master refused termination request: %s", e);
+ case MUX_S_FAILURE:
+ e = buffer_get_string(&m, NULL);
+ fatal("%s: termination request failed: %s", __func__, e);
default:
- error("Unsupported command %d", mux_command);
- buffer_free(&m);
- close(client_fd);
- return 0;
+ fatal("%s: unexpected response from master 0x%08x",
+ __func__, type);
}
+ buffer_free(&m);
+ muxclient_request_id++;
+}
+
+static int
+mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
+{
+ Buffer m;
+ char *e, *fwd_desc;
+ u_int type, rid;
+
+ fwd_desc = format_forward(ftype, fwd);
+ debug("Requesting %s", fwd_desc);
+ xfree(fwd_desc);
+
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_C_OPEN_FWD);
+ buffer_put_int(&m, muxclient_request_id);
+ buffer_put_int(&m, ftype);
+ buffer_put_cstring(&m,
+ fwd->listen_host == NULL ? "" : fwd->listen_host);
+ buffer_put_int(&m, fwd->listen_port);
+ buffer_put_cstring(&m,
+ fwd->connect_host == NULL ? "" : fwd->connect_host);
+ buffer_put_int(&m, fwd->connect_port);
+
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
- /* Reply for SSHMUX_COMMAND_OPEN */
buffer_clear(&m);
- buffer_put_int(&m, allowed);
- buffer_put_int(&m, getpid());
- if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
- error("%s: client msg_send failed", __func__);
- close(client_fd);
+
+ /* Read their reply */
+ if (mux_client_read_packet(fd, &m) != 0) {
buffer_free(&m);
- return 0;
+ return -1;
}
- if (!allowed) {
- error("Refused control connection");
- close(client_fd);
+ type = buffer_get_int(&m);
+ if ((rid = buffer_get_int(&m)) != muxclient_request_id)
+ fatal("%s: out of sequence reply: my id %u theirs %u",
+ __func__, muxclient_request_id, rid);
+ switch (type) {
+ case MUX_S_OK:
+ break;
+ case MUX_S_PERMISSION_DENIED:
+ e = buffer_get_string(&m, NULL);
buffer_free(&m);
- return 0;
+ error("Master refused forwarding request: %s", e);
+ return -1;
+ case MUX_S_FAILURE:
+ e = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+ error("%s: session request failed: %s", __func__, e);
+ return -1;
+ default:
+ fatal("%s: unexpected response from master 0x%08x",
+ __func__, type);
}
+ buffer_free(&m);
- buffer_clear(&m);
- if (ssh_msg_recv(client_fd, &m) == -1) {
- error("%s: client msg_recv failed", __func__);
- close(client_fd);
- buffer_free(&m);
- return 0;
+ muxclient_request_id++;
+ return 0;
+}
+
+static int
+mux_client_request_forwards(int fd)
+{
+ int i;
+
+ debug3("%s: requesting forwardings: %d local, %d remote", __func__,
+ options.num_local_forwards, options.num_remote_forwards);
+
+ /* XXX ExitOnForwardingFailure */
+ for (i = 0; i < options.num_local_forwards; i++) {
+ if (mux_client_request_forward(fd,
+ options.local_forwards[i].connect_port == 0 ?
+ MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
+ options.local_forwards + i) != 0)
+ return -1;
}
- if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
- error("%s: wrong client version %d", __func__, ver);
- buffer_free(&m);
- close(client_fd);
- return 0;
+ for (i = 0; i < options.num_remote_forwards; i++) {
+ if (mux_client_request_forward(fd, MUX_FWD_REMOTE,
+ options.remote_forwards + i) != 0)
+ return -1;
}
+ return 0;
+}
- cctx = xcalloc(1, sizeof(*cctx));
- cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
- cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
- cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
- cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
- cctx->term = buffer_get_string(&m, &len);
- escape_char = buffer_get_int(&m);
-
- cmd = buffer_get_string(&m, &len);
- buffer_init(&cctx->cmd);
- buffer_append(&cctx->cmd, cmd, strlen(cmd));
+static int
+mux_client_request_session(int fd)
+{
+ Buffer m;
+ char *e, *term;
+ u_int i, rid, sid, esid, exitval, type, exitval_seen;
+ extern char **environ;
+ int devnull;
+
+ debug3("%s: entering", __func__);
- env_len = buffer_get_int(&m);
- env_len = MIN(env_len, 4096);
- debug3("%s: receiving %d env vars", __func__, env_len);
- if (env_len != 0) {
- cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env));
- for (i = 0; i < env_len; i++)
- cctx->env[i] = buffer_get_string(&m, &len);
- cctx->env[i] = NULL;
+ if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
+ error("%s: master alive request failed", __func__);
+ return -1;
}
- debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
- cctx->want_tty, cctx->want_subsys, cmd);
- xfree(cmd);
+ signal(SIGPIPE, SIG_IGN);
- /* Gather fds from client */
- for(i = 0; i < 3; i++) {
- if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) {
- error("%s: failed to receive fd %d from slave",
- __func__, i);
- for (j = 0; j < i; j++)
- close(new_fd[j]);
- for (j = 0; j < env_len; j++)
- xfree(cctx->env[j]);
- if (env_len > 0)
- xfree(cctx->env);
- xfree(cctx->term);
- buffer_free(&cctx->cmd);
- close(client_fd);
- xfree(cctx);
- return 0;
+ if (stdin_null_flag) {
+ if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+ fatal("open(/dev/null): %s", strerror(errno));
+ if (dup2(devnull, STDIN_FILENO) == -1)
+ fatal("dup2: %s", strerror(errno));
+ if (devnull > STDERR_FILENO)
+ close(devnull);
+ }
+
+ term = getenv("TERM");
+
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_C_NEW_SESSION);
+ buffer_put_int(&m, muxclient_request_id);
+ buffer_put_cstring(&m, ""); /* reserved */
+ buffer_put_int(&m, tty_flag);
+ buffer_put_int(&m, options.forward_x11);
+ buffer_put_int(&m, options.forward_agent);
+ buffer_put_int(&m, subsystem_flag);
+ buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ?
+ 0xffffffff : (u_int)options.escape_char);
+ buffer_put_cstring(&m, term == NULL ? "" : term);
+ buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command));
+
+ if (options.num_send_env > 0 && environ != NULL) {
+ /* Pass environment */
+ for (i = 0; environ[i] != NULL; i++) {
+ if (env_permitted(environ[i])) {
+ buffer_put_cstring(&m, environ[i]);
+ }
}
}
- debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
- new_fd[0], new_fd[1], new_fd[2]);
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
- /* Try to pick up ttymodes from client before it goes raw */
- if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
- error("%s: tcgetattr: %s", __func__, strerror(errno));
+ /* Send the stdio file descriptors */
+ if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
+ mm_send_fd(fd, STDOUT_FILENO) == -1 ||
+ mm_send_fd(fd, STDERR_FILENO) == -1)
+ fatal("%s: send fds failed", __func__);
+
+ debug3("%s: session request sent", __func__);
- /* This roundtrip is just for synchronisation of ttymodes */
+ /* Read their reply */
buffer_clear(&m);
- if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
- error("%s: client msg_send failed", __func__);
- close(client_fd);
- close(new_fd[0]);
- close(new_fd[1]);
- close(new_fd[2]);
+ if (mux_client_read_packet(fd, &m) != 0) {
+ error("%s: read from master failed: %s",
+ __func__, strerror(errno));
buffer_free(&m);
- xfree(cctx->term);
- if (env_len != 0) {
- for (i = 0; i < env_len; i++)
- xfree(cctx->env[i]);
- xfree(cctx->env);
- }
- return 0;
+ return -1;
}
- buffer_free(&m);
- /* enable nonblocking unless tty */
- if (!isatty(new_fd[0]))
- set_nonblock(new_fd[0]);
- if (!isatty(new_fd[1]))
- set_nonblock(new_fd[1]);
- if (!isatty(new_fd[2]))
- set_nonblock(new_fd[2]);
+ type = buffer_get_int(&m);
+ if ((rid = buffer_get_int(&m)) != muxclient_request_id)
+ fatal("%s: out of sequence reply: my id %u theirs %u",
+ __func__, muxclient_request_id, rid);
+ switch (type) {
+ case MUX_S_SESSION_OPENED:
+ sid = buffer_get_int(&m);
+ debug("%s: master session id: %u", __func__, sid);
+ break;
+ case MUX_S_PERMISSION_DENIED:
+ e = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+ error("Master refused forwarding request: %s", e);
+ return -1;
+ case MUX_S_FAILURE:
+ e = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+ error("%s: forwarding request failed: %s", __func__, e);
+ return -1;
+ default:
+ buffer_free(&m);
+ error("%s: unexpected response from master 0x%08x",
+ __func__, type);
+ return -1;
+ }
+ muxclient_request_id++;
- set_nonblock(client_fd);
+ signal(SIGHUP, control_client_sighandler);
+ signal(SIGINT, control_client_sighandler);
+ signal(SIGTERM, control_client_sighandler);
+ signal(SIGWINCH, control_client_sigrelay);
- window = CHAN_SES_WINDOW_DEFAULT;
- packetmax = CHAN_SES_PACKET_DEFAULT;
- if (cctx->want_tty) {
- window >>= 1;
- packetmax >>= 1;
- }
-
- c = channel_new("session", SSH_CHANNEL_OPENING,
- new_fd[0], new_fd[1], new_fd[2], window, packetmax,
- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
+ if (tty_flag)
+ enter_raw_mode(force_tty_flag);
- c->ctl_fd = client_fd;
- if (cctx->want_tty && escape_char != 0xffffffff) {
- channel_register_filter(c->self,
- client_simple_escape_filter, NULL,
- client_filter_cleanup,
- client_new_escape_filter_ctx((int)escape_char));
+ /*
+ * Stick around until the controlee closes the client_fd.
+ * Before it does, it is expected to write an exit message.
+ * This process must read the value and wait for the closure of
+ * the client_fd; if this one closes early, the multiplex master will
+ * terminate early too (possibly losing data).
+ */
+ for (exitval = 255, exitval_seen = 0;;) {
+ buffer_clear(&m);
+ if (mux_client_read_packet(fd, &m) != 0)
+ break;
+ type = buffer_get_int(&m);
+ if (type != MUX_S_EXIT_MESSAGE) {
+ e = buffer_get_string(&m, NULL);
+ fatal("%s: master returned error: %s", __func__, e);
+ }
+ if ((esid = buffer_get_int(&m)) != sid)
+ fatal("%s: exit on unknown session: my id %u theirs %u",
+ __func__, sid, esid);
+ debug("%s: master session id: %u", __func__, sid);
+ if (exitval_seen)
+ fatal("%s: exitval sent twice", __func__);
+ exitval = buffer_get_int(&m);
+ exitval_seen = 1;
}
- debug3("%s: channel_new: %d", __func__, c->self);
+ close(fd);
+ leave_raw_mode(force_tty_flag);
- channel_send_open(c->self);
- channel_register_open_confirm(c->self, mux_session_confirm, cctx);
- return 0;
-}
+ if (muxclient_terminate) {
+ debug2("Exiting on signal %d", muxclient_terminate);
+ exitval = 255;
+ } else if (!exitval_seen) {
+ debug2("Control master terminated unexpectedly");
+ exitval = 255;
+ } else
+ debug2("Received exit status from master %d", exitval);
-/* ** Multiplexing client support */
+ if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
+ fprintf(stderr, "Shared connection to %s closed.\r\n", host);
-/* Exit signal handler */
-static void
-control_client_sighandler(int signo)
-{
- muxclient_terminate = signo;
+ exit(exitval);
}
-/*
- * Relay signal handler - used to pass some signals from mux client to
- * mux master.
- */
-static void
-control_client_sigrelay(int signo)
+static int
+mux_client_request_stdio_fwd(int fd)
{
- int save_errno = errno;
+ Buffer m;
+ char *e;
+ u_int type, rid, sid;
+ int devnull;
- if (muxserver_pid > 1)
- kill(muxserver_pid, signo);
+ debug3("%s: entering", __func__);
- errno = save_errno;
-}
+ if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
+ error("%s: master alive request failed", __func__);
+ return -1;
+ }
-/* Check mux client environment variables before passing them to mux master. */
-static int
-env_permitted(char *env)
-{
- int i, ret;
- char name[1024], *cp;
+ signal(SIGPIPE, SIG_IGN);
- if ((cp = strchr(env, '=')) == NULL || cp == env)
- return (0);
- ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
- if (ret <= 0 || (size_t)ret >= sizeof(name))
- fatal("env_permitted: name '%.100s...' too long", env);
+ if (stdin_null_flag) {
+ if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+ fatal("open(/dev/null): %s", strerror(errno));
+ if (dup2(devnull, STDIN_FILENO) == -1)
+ fatal("dup2: %s", strerror(errno));
+ if (devnull > STDERR_FILENO)
+ close(devnull);
+ }
- for (i = 0; i < options.num_send_env; i++)
- if (match_pattern(name, options.send_env[i]))
- return (1);
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_C_NEW_STDIO_FWD);
+ buffer_put_int(&m, muxclient_request_id);
+ buffer_put_cstring(&m, ""); /* reserved */
+ buffer_put_cstring(&m, stdio_forward_host);
+ buffer_put_int(&m, stdio_forward_port);
+
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
+
+ /* Send the stdio file descriptors */
+ if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
+ mm_send_fd(fd, STDOUT_FILENO) == -1)
+ fatal("%s: send fds failed", __func__);
+
+ debug3("%s: stdio forward request sent", __func__);
+
+ /* Read their reply */
+ buffer_clear(&m);
+
+ if (mux_client_read_packet(fd, &m) != 0) {
+ error("%s: read from master failed: %s",
+ __func__, strerror(errno));
+ buffer_free(&m);
+ return -1;
+ }
+
+ type = buffer_get_int(&m);
+ if ((rid = buffer_get_int(&m)) != muxclient_request_id)
+ fatal("%s: out of sequence reply: my id %u theirs %u",
+ __func__, muxclient_request_id, rid);
+ switch (type) {
+ case MUX_S_SESSION_OPENED:
+ sid = buffer_get_int(&m);
+ debug("%s: master session id: %u", __func__, sid);
+ break;
+ case MUX_S_PERMISSION_DENIED:
+ e = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+ fatal("Master refused forwarding request: %s", e);
+ case MUX_S_FAILURE:
+ e = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+ fatal("%s: stdio forwarding request failed: %s", __func__, e);
+ default:
+ buffer_free(&m);
+ error("%s: unexpected response from master 0x%08x",
+ __func__, type);
+ return -1;
+ }
+ muxclient_request_id++;
+
+ signal(SIGHUP, control_client_sighandler);
+ signal(SIGINT, control_client_sighandler);
+ signal(SIGTERM, control_client_sighandler);
+ signal(SIGWINCH, control_client_sigrelay);
- return (0);
+ /*
+ * Stick around until the controlee closes the client_fd.
+ */
+ buffer_clear(&m);
+ if (mux_client_read_packet(fd, &m) != 0) {
+ if (errno == EPIPE ||
+ (errno == EINTR && muxclient_terminate != 0))
+ return 0;
+ fatal("%s: mux_client_read_packet: %s",
+ __func__, strerror(errno));
+ }
+ fatal("%s: master returned unexpected message %u", __func__, type);
}
/* Multiplex client main loop. */
@@ -502,14 +1661,16 @@ void
muxclient(const char *path)
{
struct sockaddr_un addr;
- int i, r, fd, sock, exitval[2], num_env, addr_len;
- Buffer m;
- char *term;
- extern char **environ;
- u_int allowed, flags;
+ socklen_t sun_len;
+ int sock;
+ u_int pid;
- if (muxclient_command == 0)
- muxclient_command = SSHMUX_COMMAND_OPEN;
+ if (muxclient_command == 0) {
+ if (stdio_forward_host != NULL)
+ muxclient_command = SSHMUX_COMMAND_STDIO_FWD;
+ else
+ muxclient_command = SSHMUX_COMMAND_OPEN;
+ }
switch (options.control_master) {
case SSHCTL_MASTER_AUTO:
@@ -524,7 +1685,7 @@ muxclient(const char *path)
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
- addr_len = offsetof(struct sockaddr_un, sun_path) +
+ sun_len = offsetof(struct sockaddr_un, sun_path) +
strlen(path) + 1;
if (strlcpy(addr.sun_path, path,
@@ -534,8 +1695,12 @@ muxclient(const char *path)
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
fatal("%s socket(): %s", __func__, strerror(errno));
- if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
- if (muxclient_command != SSHMUX_COMMAND_OPEN) {
+ if (connect(sock, (struct sockaddr *)&addr, sun_len) == -1) {
+ switch (muxclient_command) {
+ case SSHMUX_COMMAND_OPEN:
+ case SSHMUX_COMMAND_STDIO_FWD:
+ break;
+ default:
fatal("Control socket connect(%.100s): %s", path,
strerror(errno));
}
@@ -548,181 +1713,35 @@ muxclient(const char *path)
close(sock);
return;
}
+ set_nonblock(sock);
- if (stdin_null_flag) {
- if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
- fatal("open(/dev/null): %s", strerror(errno));
- if (dup2(fd, STDIN_FILENO) == -1)
- fatal("dup2: %s", strerror(errno));
- if (fd > STDERR_FILENO)
- close(fd);
- }
-
- term = getenv("TERM");
-
- flags = 0;
- if (tty_flag)
- flags |= SSHMUX_FLAG_TTY;
- if (subsystem_flag)
- flags |= SSHMUX_FLAG_SUBSYS;
- if (options.forward_x11)
- flags |= SSHMUX_FLAG_X11_FWD;
- if (options.forward_agent)
- flags |= SSHMUX_FLAG_AGENT_FWD;
-
- signal(SIGPIPE, SIG_IGN);
-
- buffer_init(&m);
-
- /* Send our command to server */
- buffer_put_int(&m, muxclient_command);
- buffer_put_int(&m, flags);
- if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
- error("%s: msg_send", __func__);
- muxerr:
+ if (mux_client_hello_exchange(sock) != 0) {
+ error("%s: master hello exchange failed", __func__);
close(sock);
- buffer_free(&m);
- if (muxclient_command != SSHMUX_COMMAND_OPEN)
- cleanup_exit(255);
- logit("Falling back to non-multiplexed connection");
- xfree(options.control_path);
- options.control_path = NULL;
- options.control_master = SSHCTL_MASTER_NO;
return;
}
- buffer_clear(&m);
-
- /* Get authorisation status and PID of controlee */
- if (ssh_msg_recv(sock, &m) == -1) {
- error("%s: Did not receive reply from master", __func__);
- goto muxerr;
- }
- if (buffer_get_char(&m) != SSHMUX_VER) {
- error("%s: Master replied with wrong version", __func__);
- goto muxerr;
- }
- if (buffer_get_int_ret(&allowed, &m) != 0) {
- error("%s: bad server reply", __func__);
- goto muxerr;
- }
- if (allowed != 1) {
- error("Connection to master denied");
- goto muxerr;
- }
- muxserver_pid = buffer_get_int(&m);
-
- buffer_clear(&m);
switch (muxclient_command) {
case SSHMUX_COMMAND_ALIVE_CHECK:
- fprintf(stderr, "Master running (pid=%d)\r\n",
- muxserver_pid);
+ if ((pid = mux_client_request_alive(sock)) == 0)
+ fatal("%s: master alive check failed", __func__);
+ fprintf(stderr, "Master running (pid=%d)\r\n", pid);
exit(0);
case SSHMUX_COMMAND_TERMINATE:
+ mux_client_request_terminate(sock);
fprintf(stderr, "Exit request sent.\r\n");
exit(0);
case SSHMUX_COMMAND_OPEN:
- buffer_put_cstring(&m, term ? term : "");
- if (options.escape_char == SSH_ESCAPECHAR_NONE)
- buffer_put_int(&m, 0xffffffff);
- else
- buffer_put_int(&m, options.escape_char);
- buffer_append(&command, "\0", 1);
- buffer_put_cstring(&m, buffer_ptr(&command));
-
- if (options.num_send_env == 0 || environ == NULL) {
- buffer_put_int(&m, 0);
- } else {
- /* Pass environment */
- num_env = 0;
- for (i = 0; environ[i] != NULL; i++) {
- if (env_permitted(environ[i]))
- num_env++; /* Count */
- }
- buffer_put_int(&m, num_env);
- for (i = 0; environ[i] != NULL && num_env >= 0; i++) {
- if (env_permitted(environ[i])) {
- num_env--;
- buffer_put_cstring(&m, environ[i]);
- }
- }
+ if (mux_client_request_forwards(sock) != 0) {
+ error("%s: master forward request failed", __func__);
+ return;
}
- break;
+ mux_client_request_session(sock);
+ return;
+ case SSHMUX_COMMAND_STDIO_FWD:
+ mux_client_request_stdio_fwd(sock);
+ exit(0);
default:
fatal("unrecognised muxclient_command %d", muxclient_command);
}
-
- if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
- error("%s: msg_send", __func__);
- goto muxerr;
- }
-
- if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
- mm_send_fd(sock, STDOUT_FILENO) == -1 ||
- mm_send_fd(sock, STDERR_FILENO) == -1) {
- error("%s: send fds failed", __func__);
- goto muxerr;
- }
-
- /*
- * Mux errors are non-recoverable from this point as the master
- * has ownership of the session now.
- */
-
- /* Wait for reply, so master has a chance to gather ttymodes */
- buffer_clear(&m);
- if (ssh_msg_recv(sock, &m) == -1)
- fatal("%s: msg_recv", __func__);
- if (buffer_get_char(&m) != SSHMUX_VER)
- fatal("%s: wrong version", __func__);
- buffer_free(&m);
-
- signal(SIGHUP, control_client_sighandler);
- signal(SIGINT, control_client_sighandler);
- signal(SIGTERM, control_client_sighandler);
- signal(SIGWINCH, control_client_sigrelay);
-
- if (tty_flag)
- enter_raw_mode();
-
- /*
- * Stick around until the controlee closes the client_fd.
- * Before it does, it is expected to write this process' exit
- * value (one int). This process must read the value and wait for
- * the closure of the client_fd; if this one closes early, the
- * multiplex master will terminate early too (possibly losing data).
- */
- exitval[0] = 0;
- for (i = 0; !muxclient_terminate && i < (int)sizeof(exitval);) {
- r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
- if (r == 0) {
- debug2("Received EOF from master");
- break;
- }
- if (r == -1) {
- if (errno == EINTR)
- continue;
- fatal("%s: read %s", __func__, strerror(errno));
- }
- i += r;
- }
-
- close(sock);
- leave_raw_mode();
- if (i > (int)sizeof(int))
- fatal("%s: master returned too much data (%d > %lu)",
- __func__, i, (u_long)sizeof(int));
- if (muxclient_terminate) {
- debug2("Exiting on signal %d", muxclient_terminate);
- exitval[0] = 255;
- } else if (i < (int)sizeof(int)) {
- debug2("Control master terminated unexpectedly");
- exitval[0] = 255;
- } else
- debug2("Received exit status from master %d", exitval[0]);
-
- if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
- fprintf(stderr, "Shared connection to %s closed.\r\n", host);
-
- exit(exitval[0]);
}
diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h
index 7bca3bc..98f27fd 100644
--- a/crypto/openssh/myproposal.h
+++ b/crypto/openssh/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.23 2009/01/23 07:58:11 djm Exp $ */
+/* $OpenBSD: myproposal.h,v 1.24 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -40,7 +40,9 @@
"diffie-hellman-group1-sha1"
#endif
-#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
+#define KEX_DEFAULT_PK_ALG "ssh-rsa-cert-v00@openssh.com," \
+ "ssh-dss-cert-v00@openssh.com," \
+ "ssh-rsa,ssh-dss"
#define KEX_DEFAULT_ENCRYPT \
"aes128-ctr,aes192-ctr,aes256-ctr," \
diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c
index 160445e..20f6a2f 100644
--- a/crypto/openssh/nchan.c
+++ b/crypto/openssh/nchan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */
+/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@@ -161,7 +161,7 @@ chan_ibuf_empty(Channel *c)
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
if (compat20) {
- if (!(c->flags & CHAN_CLOSE_SENT))
+ if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
} else {
@@ -278,9 +278,12 @@ static void
chan_rcvd_close2(Channel *c)
{
debug2("channel %d: rcvd close", c->self);
- if (c->flags & CHAN_CLOSE_RCVD)
- error("channel %d: protocol error: close rcvd twice", c->self);
- c->flags |= CHAN_CLOSE_RCVD;
+ if (!(c->flags & CHAN_LOCAL)) {
+ if (c->flags & CHAN_CLOSE_RCVD)
+ error("channel %d: protocol error: close rcvd twice",
+ c->self);
+ c->flags |= CHAN_CLOSE_RCVD;
+ }
if (c->type == SSH_CHANNEL_LARVAL) {
/* tear down larval channels immediately */
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
@@ -302,11 +305,13 @@ chan_rcvd_close2(Channel *c)
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
- chan_send_eof2(c);
+ if (!(c->flags & CHAN_LOCAL))
+ chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
}
}
+
void
chan_rcvd_eow(Channel *c)
{
@@ -454,6 +459,10 @@ chan_is_dead(Channel *c, int do_send)
c->self, c->efd, buffer_len(&c->extended));
return 0;
}
+ if (c->flags & CHAN_LOCAL) {
+ debug2("channel %d: is dead (local)", c->self);
+ return 1;
+ }
if (!(c->flags & CHAN_CLOSE_SENT)) {
if (do_send) {
chan_send_close2(c);
diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
index e90c159..e9fa3a0 100644
--- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
+++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
@@ -85,23 +85,14 @@ static struct wenv {
size_t namelen;
} wenv_arr[] = {
{ NL("ALLUSERSPROFILE=") },
- { NL("COMMONPROGRAMFILES=") },
{ NL("COMPUTERNAME=") },
{ NL("COMSPEC=") },
{ NL("CYGWIN=") },
- { NL("NUMBER_OF_PROCESSORS=") },
{ NL("OS=") },
{ NL("PATH=") },
{ NL("PATHEXT=") },
- { NL("PROCESSOR_ARCHITECTURE=") },
- { NL("PROCESSOR_IDENTIFIER=") },
- { NL("PROCESSOR_LEVEL=") },
- { NL("PROCESSOR_REVISION=") },
- { NL("PROGRAMFILES=") },
{ NL("SYSTEMDRIVE=") },
{ NL("SYSTEMROOT=") },
- { NL("TMP=") },
- { NL("TEMP=") },
{ NL("WINDIR=") }
};
diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h
index 50c6d99..cad2408 100644
--- a/crypto/openssh/openbsd-compat/openbsd-compat.h
+++ b/crypto/openssh/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
-/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker Exp $ */
+/* $Id: openbsd-compat.h,v 1.49 2010/01/16 12:58:37 dtucker Exp $ */
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@@ -200,6 +200,14 @@ int vasprintf(char **, const char *, va_list);
int vsnprintf(char *, size_t, const char *, va_list);
#endif
+#ifndef HAVE_USER_FROM_UID
+char *user_from_uid(uid_t, int);
+#endif
+
+#ifndef HAVE_GROUP_FROM_GID
+char *group_from_gid(gid_t, int);
+#endif
+
void *xmmap(size_t size);
char *xcrypt(const char *password, const char *salt);
char *shadow_pw(struct passwd *pw);
diff --git a/crypto/openssh/openbsd-compat/openssl-compat.c b/crypto/openssh/openbsd-compat/openssl-compat.c
index dd326c0..420496c 100644
--- a/crypto/openssh/openbsd-compat/openssl-compat.c
+++ b/crypto/openssh/openbsd-compat/openssl-compat.c
@@ -1,4 +1,4 @@
-/* $Id: openssl-compat.c,v 1.8 2009/03/07 11:22:35 dtucker Exp $ */
+/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */
/*
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -67,5 +67,6 @@ ssh_SSLeay_add_all_algorithms(void)
/* Enable use of crypto hardware */
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
+ OPENSSL_config(NULL);
}
#endif
diff --git a/crypto/openssh/openbsd-compat/port-aix.c b/crypto/openssh/openbsd-compat/port-aix.c
index d9c0876..0bdefbf 100644
--- a/crypto/openssh/openbsd-compat/port-aix.c
+++ b/crypto/openssh/openbsd-compat/port-aix.c
@@ -374,6 +374,31 @@ aix_restoreauthdb(void)
# endif /* WITH_AIXAUTHENTICATE */
+# ifdef USE_AIX_KRB_NAME
+/*
+ * aix_krb5_get_principal_name: returns the user's kerberos client principal name if
+ * configured, otherwise NULL. Caller must free returned string.
+ */
+char *
+aix_krb5_get_principal_name(char *pw_name)
+{
+ char *authname = NULL, *authdomain = NULL, *principal = NULL;
+
+ setuserdb(S_READ);
+ if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0)
+ debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno));
+ if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0)
+ debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno));
+
+ if (authdomain != NULL)
+ xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain);
+ else if (authname != NULL)
+ principal = xstrdup(authname);
+ enduserdb();
+ return principal;
+}
+# endif /* USE_AIX_KRB_NAME */
+
# if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO)
# undef getnameinfo
/*
diff --git a/crypto/openssh/openbsd-compat/port-aix.h b/crypto/openssh/openbsd-compat/port-aix.h
index 3ac76ae..53e4e88 100644
--- a/crypto/openssh/openbsd-compat/port-aix.h
+++ b/crypto/openssh/openbsd-compat/port-aix.h
@@ -1,4 +1,4 @@
-/* $Id: port-aix.h,v 1.31 2009/08/20 06:20:50 dtucker Exp $ */
+/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */
/*
*
@@ -95,6 +95,10 @@ int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
char *sys_auth_get_lastlogin_msg(const char *, uid_t);
# define CUSTOM_FAILED_LOGIN 1
+# if defined(S_AUTHDOMAIN) && defined (S_AUTHNAME)
+# define USE_AIX_KRB_NAME
+char *aix_krb5_get_principal_name(char *);
+# endif
#endif
void aix_setauthdb(const char *);
diff --git a/crypto/openssh/openbsd-compat/port-linux.c b/crypto/openssh/openbsd-compat/port-linux.c
index ad26275..89b9a73 100644
--- a/crypto/openssh/openbsd-compat/port-linux.c
+++ b/crypto/openssh/openbsd-compat/port-linux.c
@@ -1,4 +1,4 @@
-/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */
+/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */
/*
* Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
@@ -23,14 +23,17 @@
#include "includes.h"
+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
#include <errno.h>
#include <stdarg.h>
#include <string.h>
+#include <stdio.h>
-#ifdef WITH_SELINUX
#include "log.h"
+#include "xmalloc.h"
#include "port-linux.h"
+#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#include <selinux/flask.h>
#include <selinux/get_context_list.h>
@@ -168,4 +171,95 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
freecon(user_ctx);
debug3("%s: done", __func__);
}
+
+void
+ssh_selinux_change_context(const char *newname)
+{
+ int len, newlen;
+ char *oldctx, *newctx, *cx;
+
+ if (!ssh_selinux_enabled())
+ return;
+
+ if (getcon((security_context_t *)&oldctx) < 0) {
+ logit("%s: getcon failed with %s", __func__, strerror (errno));
+ return;
+ }
+ if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) ==
+ NULL) {
+ logit ("%s: unparseable context %s", __func__, oldctx);
+ return;
+ }
+
+ newlen = strlen(oldctx) + strlen(newname) + 1;
+ newctx = xmalloc(newlen);
+ len = cx - oldctx + 1;
+ memcpy(newctx, oldctx, len);
+ strlcpy(newctx + len, newname, newlen - len);
+ if ((cx = index(cx + 1, ':')))
+ strlcat(newctx, cx, newlen);
+ debug3("%s: setting context from '%s' to '%s'", __func__, oldctx,
+ newctx);
+ if (setcon(newctx) < 0)
+ logit("%s: setcon failed with %s", __func__, strerror (errno));
+ xfree(oldctx);
+ xfree(newctx);
+}
#endif /* WITH_SELINUX */
+
+#ifdef LINUX_OOM_ADJUST
+#define OOM_ADJ_PATH "/proc/self/oom_adj"
+/*
+ * The magic "don't kill me", as documented in eg:
+ * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
+ */
+#define OOM_ADJ_NOKILL -17
+
+static int oom_adj_save = INT_MIN;
+
+/*
+ * Tell the kernel's out-of-memory killer to avoid sshd.
+ * Returns the previous oom_adj value or zero.
+ */
+void
+oom_adjust_setup(void)
+{
+ FILE *fp;
+
+ debug3("%s", __func__);
+ if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) {
+ if (fscanf(fp, "%d", &oom_adj_save) != 1)
+ verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno));
+ else {
+ rewind(fp);
+ if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0)
+ verbose("error writing %s: %s",
+ OOM_ADJ_PATH, strerror(errno));
+ else
+ verbose("Set %s from %d to %d",
+ OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL);
+ }
+ fclose(fp);
+ }
+}
+
+/* Restore the saved OOM adjustment */
+void
+oom_adjust_restore(void)
+{
+ FILE *fp;
+
+ debug3("%s", __func__);
+ if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL)
+ return;
+
+ if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
+ verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno));
+ else
+ verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save);
+
+ fclose(fp);
+ return;
+}
+#endif /* LINUX_OOM_ADJUST */
+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
diff --git a/crypto/openssh/openbsd-compat/port-linux.h b/crypto/openssh/openbsd-compat/port-linux.h
index 5cd39bf..209d9a7 100644
--- a/crypto/openssh/openbsd-compat/port-linux.h
+++ b/crypto/openssh/openbsd-compat/port-linux.h
@@ -1,4 +1,4 @@
-/* $Id: port-linux.h,v 1.2 2008/03/26 20:27:21 dtucker Exp $ */
+/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */
/*
* Copyright (c) 2006 Damien Miller <djm@openbsd.org>
@@ -23,6 +23,12 @@
int ssh_selinux_enabled(void);
void ssh_selinux_setup_pty(char *, const char *);
void ssh_selinux_setup_exec_context(char *);
+void ssh_selinux_change_context(const char *);
+#endif
+
+#ifdef LINUX_OOM_ADJUST
+void oom_adjust_restore(void);
+void oom_adjust_setup(void);
#endif
#endif /* ! _PORT_LINUX_H */
diff --git a/crypto/openssh/openbsd-compat/pwcache.c b/crypto/openssh/openbsd-compat/pwcache.c
new file mode 100644
index 0000000..5a8b788
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/pwcache.c
@@ -0,0 +1,114 @@
+/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NCACHE 64 /* power of 2 */
+#define MASK (NCACHE - 1) /* bits to store with */
+
+#ifndef HAVE_USER_FROM_UID
+char *
+user_from_uid(uid_t uid, int nouser)
+{
+ static struct ncache {
+ uid_t uid;
+ char *name;
+ } c_uid[NCACHE];
+ static int pwopen;
+ static char nbuf[15]; /* 32 bits == 10 digits */
+ struct passwd *pw;
+ struct ncache *cp;
+
+ cp = c_uid + (uid & MASK);
+ if (cp->uid != uid || cp->name == NULL) {
+ if (pwopen == 0) {
+#ifdef HAVE_SETPASSENT
+ setpassent(1);
+#endif
+ pwopen = 1;
+ }
+ if ((pw = getpwuid(uid)) == NULL) {
+ if (nouser)
+ return (NULL);
+ (void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
+ }
+ cp->uid = uid;
+ if (cp->name != NULL)
+ free(cp->name);
+ cp->name = strdup(pw ? pw->pw_name : nbuf);
+ }
+ return (cp->name);
+}
+#endif
+
+#ifndef HAVE_GROUP_FROM_GID
+char *
+group_from_gid(gid_t gid, int nogroup)
+{
+ static struct ncache {
+ gid_t gid;
+ char *name;
+ } c_gid[NCACHE];
+ static int gropen;
+ static char nbuf[15]; /* 32 bits == 10 digits */
+ struct group *gr;
+ struct ncache *cp;
+
+ cp = c_gid + (gid & MASK);
+ if (cp->gid != gid || cp->name == NULL) {
+ if (gropen == 0) {
+#ifdef HAVE_SETGROUPENT
+ setgroupent(1);
+#endif
+ gropen = 1;
+ }
+ if ((gr = getgrgid(gid)) == NULL) {
+ if (nogroup)
+ return (NULL);
+ (void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
+ }
+ cp->gid = gid;
+ if (cp->name != NULL)
+ free(cp->name);
+ cp->name = strdup(gr ? gr->gr_name : nbuf);
+ }
+ return (cp->name);
+}
+#endif
diff --git a/crypto/openssh/openbsd-compat/readpassphrase.c b/crypto/openssh/openbsd-compat/readpassphrase.c
index 11bd8f6..62b6d0d 100644
--- a/crypto/openssh/openbsd-compat/readpassphrase.c
+++ b/crypto/openssh/openbsd-compat/readpassphrase.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: readpassphrase.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */
+/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */
/*
- * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -46,7 +46,7 @@
# define _POSIX_VDISABLE VDISABLE
#endif
-static volatile sig_atomic_t signo;
+static volatile sig_atomic_t signo[_NSIG];
static void handler(int);
@@ -54,7 +54,7 @@ char *
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
{
ssize_t nr;
- int input, output, save_errno;
+ int input, output, save_errno, i, need_restart;
char ch, *p, *end;
struct termios term, oterm;
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
@@ -67,7 +67,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
}
restart:
- signo = 0;
+ for (i = 0; i < _NSIG; i++)
+ signo[i] = 0;
+ nr = -1;
+ save_errno = 0;
+ need_restart = 0;
/*
* Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required.
@@ -117,26 +121,30 @@ restart:
oterm.c_lflag |= ECHO;
}
- if (!(flags & RPP_STDIN))
- (void)write(output, prompt, strlen(prompt));
- end = buf + bufsiz - 1;
- for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) {
- if (p < end) {
- if ((flags & RPP_SEVENBIT))
- ch &= 0x7f;
- if (isalpha(ch)) {
- if ((flags & RPP_FORCELOWER))
- ch = tolower(ch);
- if ((flags & RPP_FORCEUPPER))
- ch = toupper(ch);
+ /* No I/O if we are already backgrounded. */
+ if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) {
+ if (!(flags & RPP_STDIN))
+ (void)write(output, prompt, strlen(prompt));
+ end = buf + bufsiz - 1;
+ p = buf;
+ while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
+ if (p < end) {
+ if ((flags & RPP_SEVENBIT))
+ ch &= 0x7f;
+ if (isalpha(ch)) {
+ if ((flags & RPP_FORCELOWER))
+ ch = (char)tolower(ch);
+ if ((flags & RPP_FORCEUPPER))
+ ch = (char)toupper(ch);
+ }
+ *p++ = ch;
}
- *p++ = ch;
}
+ *p = '\0';
+ save_errno = errno;
+ if (!(term.c_lflag & ECHO))
+ (void)write(output, "\n", 1);
}
- *p = '\0';
- save_errno = errno;
- if (!(term.c_lflag & ECHO))
- (void)write(output, "\n", 1);
/* Restore old terminal settings and signals. */
if (memcmp(&term, &oterm, sizeof(term)) != 0) {
@@ -152,6 +160,7 @@ restart:
(void)sigaction(SIGTERM, &saveterm, NULL);
(void)sigaction(SIGTSTP, &savetstp, NULL);
(void)sigaction(SIGTTIN, &savettin, NULL);
+ (void)sigaction(SIGTTOU, &savettou, NULL);
if (input != STDIN_FILENO)
(void)close(input);
@@ -159,20 +168,25 @@ restart:
* If we were interrupted by a signal, resend it to ourselves
* now that we have restored the signal handlers.
*/
- if (signo) {
- kill(getpid(), signo);
- switch (signo) {
- case SIGTSTP:
- case SIGTTIN:
- case SIGTTOU:
- goto restart;
+ for (i = 0; i < _NSIG; i++) {
+ if (signo[i]) {
+ kill(getpid(), i);
+ switch (i) {
+ case SIGTSTP:
+ case SIGTTIN:
+ case SIGTTOU:
+ need_restart = 1;
+ }
}
}
+ if (need_restart)
+ goto restart;
- errno = save_errno;
+ if (save_errno)
+ errno = save_errno;
return(nr == -1 ? NULL : buf);
}
-
+
#if 0
char *
getpass(const char *prompt)
@@ -186,6 +200,6 @@ getpass(const char *prompt)
static void handler(int s)
{
- signo = s;
+ signo[s] = 1;
}
#endif /* HAVE_READPASSPHRASE */
diff --git a/crypto/openssh/pathnames.h b/crypto/openssh/pathnames.h
index bc4f66a..0bb0c06 100644
--- a/crypto/openssh/pathnames.h
+++ b/crypto/openssh/pathnames.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */
+/* $OpenBSD: pathnames.h,v 1.19 2010/02/11 20:37:47 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -125,6 +125,11 @@
#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign"
#endif
+/* Location of ssh-pkcs11-helper to support keys in tokens */
+#ifndef _PATH_SSH_PKCS11_HELPER
+#define _PATH_SSH_PKCS11_HELPER "/usr/libexec/ssh-pkcs11-helper"
+#endif
+
/* xauth for X11 forwarding */
#ifndef _PATH_XAUTH
#define _PATH_XAUTH "/usr/local/bin/xauth"
diff --git a/crypto/openssh/pkcs11.h b/crypto/openssh/pkcs11.h
new file mode 100644
index 0000000..2cde5b3
--- /dev/null
+++ b/crypto/openssh/pkcs11.h
@@ -0,0 +1,1357 @@
+/* $OpenBSD: pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */
+/* pkcs11.h
+ Copyright 2006, 2007 g10 Code GmbH
+ Copyright 2006 Andreas Jellinghaus
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. */
+
+/* Please submit changes back to the Scute project at
+ http://www.scute.org/ (or send them to marcus@g10code.com), so that
+ they can be picked up by other projects from there as well. */
+
+/* This file is a modified implementation of the PKCS #11 standard by
+ RSA Security Inc. It is mostly a drop-in replacement, with the
+ following change:
+
+ This header file does not require any macro definitions by the user
+ (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros
+ for you (if useful, some are missing, let me know if you need
+ more).
+
+ There is an additional API available that does comply better to the
+ GNU coding standard. It can be switched on by defining
+ CRYPTOKI_GNU before including this header file. For this, the
+ following changes are made to the specification:
+
+ All structure types are changed to a "struct ck_foo" where CK_FOO
+ is the type name in PKCS #11.
+
+ All non-structure types are changed to ck_foo_t where CK_FOO is the
+ lowercase version of the type name in PKCS #11. The basic types
+ (CK_ULONG et al.) are removed without substitute.
+
+ All members of structures are modified in the following way: Type
+ indication prefixes are removed, and underscore characters are
+ inserted before words. Then the result is lowercased.
+
+ Note that function names are still in the original case, as they
+ need for ABI compatibility.
+
+ CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use
+ <stdbool.h>.
+
+ If CRYPTOKI_COMPAT is defined before including this header file,
+ then none of the API changes above take place, and the API is the
+ one defined by the PKCS #11 standard. */
+
+#ifndef PKCS11_H
+#define PKCS11_H 1
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* The version of cryptoki we implement. The revision is changed with
+ each modification of this file. If you do not use the "official"
+ version of this file, please consider deleting the revision macro
+ (you may use a macro with a different name to keep track of your
+ versions). */
+#define CRYPTOKI_VERSION_MAJOR 2
+#define CRYPTOKI_VERSION_MINOR 20
+#define CRYPTOKI_VERSION_REVISION 6
+
+
+/* Compatibility interface is default, unless CRYPTOKI_GNU is
+ given. */
+#ifndef CRYPTOKI_GNU
+#ifndef CRYPTOKI_COMPAT
+#define CRYPTOKI_COMPAT 1
+#endif
+#endif
+
+/* System dependencies. */
+
+#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
+
+/* There is a matching pop below. */
+#pragma pack(push, cryptoki, 1)
+
+#ifdef CRYPTOKI_EXPORTS
+#define CK_SPEC __declspec(dllexport)
+#else
+#define CK_SPEC __declspec(dllimport)
+#endif
+
+#else
+
+#define CK_SPEC
+
+#endif
+
+
+#ifdef CRYPTOKI_COMPAT
+ /* If we are in compatibility mode, switch all exposed names to the
+ PKCS #11 variant. There are corresponding #undefs below. */
+
+#define ck_flags_t CK_FLAGS
+#define ck_version _CK_VERSION
+
+#define ck_info _CK_INFO
+#define cryptoki_version cryptokiVersion
+#define manufacturer_id manufacturerID
+#define library_description libraryDescription
+#define library_version libraryVersion
+
+#define ck_notification_t CK_NOTIFICATION
+#define ck_slot_id_t CK_SLOT_ID
+
+#define ck_slot_info _CK_SLOT_INFO
+#define slot_description slotDescription
+#define hardware_version hardwareVersion
+#define firmware_version firmwareVersion
+
+#define ck_token_info _CK_TOKEN_INFO
+#define serial_number serialNumber
+#define max_session_count ulMaxSessionCount
+#define session_count ulSessionCount
+#define max_rw_session_count ulMaxRwSessionCount
+#define rw_session_count ulRwSessionCount
+#define max_pin_len ulMaxPinLen
+#define min_pin_len ulMinPinLen
+#define total_public_memory ulTotalPublicMemory
+#define free_public_memory ulFreePublicMemory
+#define total_private_memory ulTotalPrivateMemory
+#define free_private_memory ulFreePrivateMemory
+#define utc_time utcTime
+
+#define ck_session_handle_t CK_SESSION_HANDLE
+#define ck_user_type_t CK_USER_TYPE
+#define ck_state_t CK_STATE
+
+#define ck_session_info _CK_SESSION_INFO
+#define slot_id slotID
+#define device_error ulDeviceError
+
+#define ck_object_handle_t CK_OBJECT_HANDLE
+#define ck_object_class_t CK_OBJECT_CLASS
+#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE
+#define ck_key_type_t CK_KEY_TYPE
+#define ck_certificate_type_t CK_CERTIFICATE_TYPE
+#define ck_attribute_type_t CK_ATTRIBUTE_TYPE
+
+#define ck_attribute _CK_ATTRIBUTE
+#define value pValue
+#define value_len ulValueLen
+
+#define ck_date _CK_DATE
+
+#define ck_mechanism_type_t CK_MECHANISM_TYPE
+
+#define ck_mechanism _CK_MECHANISM
+#define parameter pParameter
+#define parameter_len ulParameterLen
+
+#define ck_mechanism_info _CK_MECHANISM_INFO
+#define min_key_size ulMinKeySize
+#define max_key_size ulMaxKeySize
+
+#define ck_rv_t CK_RV
+#define ck_notify_t CK_NOTIFY
+
+#define ck_function_list _CK_FUNCTION_LIST
+
+#define ck_createmutex_t CK_CREATEMUTEX
+#define ck_destroymutex_t CK_DESTROYMUTEX
+#define ck_lockmutex_t CK_LOCKMUTEX
+#define ck_unlockmutex_t CK_UNLOCKMUTEX
+
+#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS
+#define create_mutex CreateMutex
+#define destroy_mutex DestroyMutex
+#define lock_mutex LockMutex
+#define unlock_mutex UnlockMutex
+#define reserved pReserved
+
+#endif /* CRYPTOKI_COMPAT */
+
+
+
+typedef unsigned long ck_flags_t;
+
+struct ck_version
+{
+ unsigned char major;
+ unsigned char minor;
+};
+
+
+struct ck_info
+{
+ struct ck_version cryptoki_version;
+ unsigned char manufacturer_id[32];
+ ck_flags_t flags;
+ unsigned char library_description[32];
+ struct ck_version library_version;
+};
+
+
+typedef unsigned long ck_notification_t;
+
+#define CKN_SURRENDER (0)
+
+
+typedef unsigned long ck_slot_id_t;
+
+
+struct ck_slot_info
+{
+ unsigned char slot_description[64];
+ unsigned char manufacturer_id[32];
+ ck_flags_t flags;
+ struct ck_version hardware_version;
+ struct ck_version firmware_version;
+};
+
+
+#define CKF_TOKEN_PRESENT (1 << 0)
+#define CKF_REMOVABLE_DEVICE (1 << 1)
+#define CKF_HW_SLOT (1 << 2)
+#define CKF_ARRAY_ATTRIBUTE (1 << 30)
+
+
+struct ck_token_info
+{
+ unsigned char label[32];
+ unsigned char manufacturer_id[32];
+ unsigned char model[16];
+ unsigned char serial_number[16];
+ ck_flags_t flags;
+ unsigned long max_session_count;
+ unsigned long session_count;
+ unsigned long max_rw_session_count;
+ unsigned long rw_session_count;
+ unsigned long max_pin_len;
+ unsigned long min_pin_len;
+ unsigned long total_public_memory;
+ unsigned long free_public_memory;
+ unsigned long total_private_memory;
+ unsigned long free_private_memory;
+ struct ck_version hardware_version;
+ struct ck_version firmware_version;
+ unsigned char utc_time[16];
+};
+
+
+#define CKF_RNG (1 << 0)
+#define CKF_WRITE_PROTECTED (1 << 1)
+#define CKF_LOGIN_REQUIRED (1 << 2)
+#define CKF_USER_PIN_INITIALIZED (1 << 3)
+#define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5)
+#define CKF_CLOCK_ON_TOKEN (1 << 6)
+#define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8)
+#define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9)
+#define CKF_TOKEN_INITIALIZED (1 << 10)
+#define CKF_SECONDARY_AUTHENTICATION (1 << 11)
+#define CKF_USER_PIN_COUNT_LOW (1 << 16)
+#define CKF_USER_PIN_FINAL_TRY (1 << 17)
+#define CKF_USER_PIN_LOCKED (1 << 18)
+#define CKF_USER_PIN_TO_BE_CHANGED (1 << 19)
+#define CKF_SO_PIN_COUNT_LOW (1 << 20)
+#define CKF_SO_PIN_FINAL_TRY (1 << 21)
+#define CKF_SO_PIN_LOCKED (1 << 22)
+#define CKF_SO_PIN_TO_BE_CHANGED (1 << 23)
+
+#define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1)
+#define CK_EFFECTIVELY_INFINITE (0)
+
+
+typedef unsigned long ck_session_handle_t;
+
+#define CK_INVALID_HANDLE (0)
+
+
+typedef unsigned long ck_user_type_t;
+
+#define CKU_SO (0)
+#define CKU_USER (1)
+#define CKU_CONTEXT_SPECIFIC (2)
+
+
+typedef unsigned long ck_state_t;
+
+#define CKS_RO_PUBLIC_SESSION (0)
+#define CKS_RO_USER_FUNCTIONS (1)
+#define CKS_RW_PUBLIC_SESSION (2)
+#define CKS_RW_USER_FUNCTIONS (3)
+#define CKS_RW_SO_FUNCTIONS (4)
+
+
+struct ck_session_info
+{
+ ck_slot_id_t slot_id;
+ ck_state_t state;
+ ck_flags_t flags;
+ unsigned long device_error;
+};
+
+#define CKF_RW_SESSION (1 << 1)
+#define CKF_SERIAL_SESSION (1 << 2)
+
+
+typedef unsigned long ck_object_handle_t;
+
+
+typedef unsigned long ck_object_class_t;
+
+#define CKO_DATA (0)
+#define CKO_CERTIFICATE (1)
+#define CKO_PUBLIC_KEY (2)
+#define CKO_PRIVATE_KEY (3)
+#define CKO_SECRET_KEY (4)
+#define CKO_HW_FEATURE (5)
+#define CKO_DOMAIN_PARAMETERS (6)
+#define CKO_MECHANISM (7)
+#define CKO_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+
+typedef unsigned long ck_hw_feature_type_t;
+
+#define CKH_MONOTONIC_COUNTER (1)
+#define CKH_CLOCK (2)
+#define CKH_USER_INTERFACE (3)
+#define CKH_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+
+typedef unsigned long ck_key_type_t;
+
+#define CKK_RSA (0)
+#define CKK_DSA (1)
+#define CKK_DH (2)
+#define CKK_ECDSA (3)
+#define CKK_EC (3)
+#define CKK_X9_42_DH (4)
+#define CKK_KEA (5)
+#define CKK_GENERIC_SECRET (0x10)
+#define CKK_RC2 (0x11)
+#define CKK_RC4 (0x12)
+#define CKK_DES (0x13)
+#define CKK_DES2 (0x14)
+#define CKK_DES3 (0x15)
+#define CKK_CAST (0x16)
+#define CKK_CAST3 (0x17)
+#define CKK_CAST128 (0x18)
+#define CKK_RC5 (0x19)
+#define CKK_IDEA (0x1a)
+#define CKK_SKIPJACK (0x1b)
+#define CKK_BATON (0x1c)
+#define CKK_JUNIPER (0x1d)
+#define CKK_CDMF (0x1e)
+#define CKK_AES (0x1f)
+#define CKK_BLOWFISH (0x20)
+#define CKK_TWOFISH (0x21)
+#define CKK_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+typedef unsigned long ck_certificate_type_t;
+
+#define CKC_X_509 (0)
+#define CKC_X_509_ATTR_CERT (1)
+#define CKC_WTLS (2)
+#define CKC_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+
+typedef unsigned long ck_attribute_type_t;
+
+#define CKA_CLASS (0)
+#define CKA_TOKEN (1)
+#define CKA_PRIVATE (2)
+#define CKA_LABEL (3)
+#define CKA_APPLICATION (0x10)
+#define CKA_VALUE (0x11)
+#define CKA_OBJECT_ID (0x12)
+#define CKA_CERTIFICATE_TYPE (0x80)
+#define CKA_ISSUER (0x81)
+#define CKA_SERIAL_NUMBER (0x82)
+#define CKA_AC_ISSUER (0x83)
+#define CKA_OWNER (0x84)
+#define CKA_ATTR_TYPES (0x85)
+#define CKA_TRUSTED (0x86)
+#define CKA_CERTIFICATE_CATEGORY (0x87)
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88)
+#define CKA_URL (0x89)
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a)
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b)
+#define CKA_CHECK_VALUE (0x90)
+#define CKA_KEY_TYPE (0x100)
+#define CKA_SUBJECT (0x101)
+#define CKA_ID (0x102)
+#define CKA_SENSITIVE (0x103)
+#define CKA_ENCRYPT (0x104)
+#define CKA_DECRYPT (0x105)
+#define CKA_WRAP (0x106)
+#define CKA_UNWRAP (0x107)
+#define CKA_SIGN (0x108)
+#define CKA_SIGN_RECOVER (0x109)
+#define CKA_VERIFY (0x10a)
+#define CKA_VERIFY_RECOVER (0x10b)
+#define CKA_DERIVE (0x10c)
+#define CKA_START_DATE (0x110)
+#define CKA_END_DATE (0x111)
+#define CKA_MODULUS (0x120)
+#define CKA_MODULUS_BITS (0x121)
+#define CKA_PUBLIC_EXPONENT (0x122)
+#define CKA_PRIVATE_EXPONENT (0x123)
+#define CKA_PRIME_1 (0x124)
+#define CKA_PRIME_2 (0x125)
+#define CKA_EXPONENT_1 (0x126)
+#define CKA_EXPONENT_2 (0x127)
+#define CKA_COEFFICIENT (0x128)
+#define CKA_PRIME (0x130)
+#define CKA_SUBPRIME (0x131)
+#define CKA_BASE (0x132)
+#define CKA_PRIME_BITS (0x133)
+#define CKA_SUB_PRIME_BITS (0x134)
+#define CKA_VALUE_BITS (0x160)
+#define CKA_VALUE_LEN (0x161)
+#define CKA_EXTRACTABLE (0x162)
+#define CKA_LOCAL (0x163)
+#define CKA_NEVER_EXTRACTABLE (0x164)
+#define CKA_ALWAYS_SENSITIVE (0x165)
+#define CKA_KEY_GEN_MECHANISM (0x166)
+#define CKA_MODIFIABLE (0x170)
+#define CKA_ECDSA_PARAMS (0x180)
+#define CKA_EC_PARAMS (0x180)
+#define CKA_EC_POINT (0x181)
+#define CKA_SECONDARY_AUTH (0x200)
+#define CKA_AUTH_PIN_FLAGS (0x201)
+#define CKA_ALWAYS_AUTHENTICATE (0x202)
+#define CKA_WRAP_WITH_TRUSTED (0x210)
+#define CKA_HW_FEATURE_TYPE (0x300)
+#define CKA_RESET_ON_INIT (0x301)
+#define CKA_HAS_RESET (0x302)
+#define CKA_PIXEL_X (0x400)
+#define CKA_PIXEL_Y (0x401)
+#define CKA_RESOLUTION (0x402)
+#define CKA_CHAR_ROWS (0x403)
+#define CKA_CHAR_COLUMNS (0x404)
+#define CKA_COLOR (0x405)
+#define CKA_BITS_PER_PIXEL (0x406)
+#define CKA_CHAR_SETS (0x480)
+#define CKA_ENCODING_METHODS (0x481)
+#define CKA_MIME_TYPES (0x482)
+#define CKA_MECHANISM_TYPE (0x500)
+#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501)
+#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502)
+#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503)
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212)
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600)
+#define CKA_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+
+struct ck_attribute
+{
+ ck_attribute_type_t type;
+ void *value;
+ unsigned long value_len;
+};
+
+
+struct ck_date
+{
+ unsigned char year[4];
+ unsigned char month[2];
+ unsigned char day[2];
+};
+
+
+typedef unsigned long ck_mechanism_type_t;
+
+#define CKM_RSA_PKCS_KEY_PAIR_GEN (0)
+#define CKM_RSA_PKCS (1)
+#define CKM_RSA_9796 (2)
+#define CKM_RSA_X_509 (3)
+#define CKM_MD2_RSA_PKCS (4)
+#define CKM_MD5_RSA_PKCS (5)
+#define CKM_SHA1_RSA_PKCS (6)
+#define CKM_RIPEMD128_RSA_PKCS (7)
+#define CKM_RIPEMD160_RSA_PKCS (8)
+#define CKM_RSA_PKCS_OAEP (9)
+#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa)
+#define CKM_RSA_X9_31 (0xb)
+#define CKM_SHA1_RSA_X9_31 (0xc)
+#define CKM_RSA_PKCS_PSS (0xd)
+#define CKM_SHA1_RSA_PKCS_PSS (0xe)
+#define CKM_DSA_KEY_PAIR_GEN (0x10)
+#define CKM_DSA (0x11)
+#define CKM_DSA_SHA1 (0x12)
+#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20)
+#define CKM_DH_PKCS_DERIVE (0x21)
+#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30)
+#define CKM_X9_42_DH_DERIVE (0x31)
+#define CKM_X9_42_DH_HYBRID_DERIVE (0x32)
+#define CKM_X9_42_MQV_DERIVE (0x33)
+#define CKM_SHA256_RSA_PKCS (0x40)
+#define CKM_SHA384_RSA_PKCS (0x41)
+#define CKM_SHA512_RSA_PKCS (0x42)
+#define CKM_SHA256_RSA_PKCS_PSS (0x43)
+#define CKM_SHA384_RSA_PKCS_PSS (0x44)
+#define CKM_SHA512_RSA_PKCS_PSS (0x45)
+#define CKM_RC2_KEY_GEN (0x100)
+#define CKM_RC2_ECB (0x101)
+#define CKM_RC2_CBC (0x102)
+#define CKM_RC2_MAC (0x103)
+#define CKM_RC2_MAC_GENERAL (0x104)
+#define CKM_RC2_CBC_PAD (0x105)
+#define CKM_RC4_KEY_GEN (0x110)
+#define CKM_RC4 (0x111)
+#define CKM_DES_KEY_GEN (0x120)
+#define CKM_DES_ECB (0x121)
+#define CKM_DES_CBC (0x122)
+#define CKM_DES_MAC (0x123)
+#define CKM_DES_MAC_GENERAL (0x124)
+#define CKM_DES_CBC_PAD (0x125)
+#define CKM_DES2_KEY_GEN (0x130)
+#define CKM_DES3_KEY_GEN (0x131)
+#define CKM_DES3_ECB (0x132)
+#define CKM_DES3_CBC (0x133)
+#define CKM_DES3_MAC (0x134)
+#define CKM_DES3_MAC_GENERAL (0x135)
+#define CKM_DES3_CBC_PAD (0x136)
+#define CKM_CDMF_KEY_GEN (0x140)
+#define CKM_CDMF_ECB (0x141)
+#define CKM_CDMF_CBC (0x142)
+#define CKM_CDMF_MAC (0x143)
+#define CKM_CDMF_MAC_GENERAL (0x144)
+#define CKM_CDMF_CBC_PAD (0x145)
+#define CKM_MD2 (0x200)
+#define CKM_MD2_HMAC (0x201)
+#define CKM_MD2_HMAC_GENERAL (0x202)
+#define CKM_MD5 (0x210)
+#define CKM_MD5_HMAC (0x211)
+#define CKM_MD5_HMAC_GENERAL (0x212)
+#define CKM_SHA_1 (0x220)
+#define CKM_SHA_1_HMAC (0x221)
+#define CKM_SHA_1_HMAC_GENERAL (0x222)
+#define CKM_RIPEMD128 (0x230)
+#define CKM_RIPEMD128_HMAC (0x231)
+#define CKM_RIPEMD128_HMAC_GENERAL (0x232)
+#define CKM_RIPEMD160 (0x240)
+#define CKM_RIPEMD160_HMAC (0x241)
+#define CKM_RIPEMD160_HMAC_GENERAL (0x242)
+#define CKM_SHA256 (0x250)
+#define CKM_SHA256_HMAC (0x251)
+#define CKM_SHA256_HMAC_GENERAL (0x252)
+#define CKM_SHA384 (0x260)
+#define CKM_SHA384_HMAC (0x261)
+#define CKM_SHA384_HMAC_GENERAL (0x262)
+#define CKM_SHA512 (0x270)
+#define CKM_SHA512_HMAC (0x271)
+#define CKM_SHA512_HMAC_GENERAL (0x272)
+#define CKM_CAST_KEY_GEN (0x300)
+#define CKM_CAST_ECB (0x301)
+#define CKM_CAST_CBC (0x302)
+#define CKM_CAST_MAC (0x303)
+#define CKM_CAST_MAC_GENERAL (0x304)
+#define CKM_CAST_CBC_PAD (0x305)
+#define CKM_CAST3_KEY_GEN (0x310)
+#define CKM_CAST3_ECB (0x311)
+#define CKM_CAST3_CBC (0x312)
+#define CKM_CAST3_MAC (0x313)
+#define CKM_CAST3_MAC_GENERAL (0x314)
+#define CKM_CAST3_CBC_PAD (0x315)
+#define CKM_CAST5_KEY_GEN (0x320)
+#define CKM_CAST128_KEY_GEN (0x320)
+#define CKM_CAST5_ECB (0x321)
+#define CKM_CAST128_ECB (0x321)
+#define CKM_CAST5_CBC (0x322)
+#define CKM_CAST128_CBC (0x322)
+#define CKM_CAST5_MAC (0x323)
+#define CKM_CAST128_MAC (0x323)
+#define CKM_CAST5_MAC_GENERAL (0x324)
+#define CKM_CAST128_MAC_GENERAL (0x324)
+#define CKM_CAST5_CBC_PAD (0x325)
+#define CKM_CAST128_CBC_PAD (0x325)
+#define CKM_RC5_KEY_GEN (0x330)
+#define CKM_RC5_ECB (0x331)
+#define CKM_RC5_CBC (0x332)
+#define CKM_RC5_MAC (0x333)
+#define CKM_RC5_MAC_GENERAL (0x334)
+#define CKM_RC5_CBC_PAD (0x335)
+#define CKM_IDEA_KEY_GEN (0x340)
+#define CKM_IDEA_ECB (0x341)
+#define CKM_IDEA_CBC (0x342)
+#define CKM_IDEA_MAC (0x343)
+#define CKM_IDEA_MAC_GENERAL (0x344)
+#define CKM_IDEA_CBC_PAD (0x345)
+#define CKM_GENERIC_SECRET_KEY_GEN (0x350)
+#define CKM_CONCATENATE_BASE_AND_KEY (0x360)
+#define CKM_CONCATENATE_BASE_AND_DATA (0x362)
+#define CKM_CONCATENATE_DATA_AND_BASE (0x363)
+#define CKM_XOR_BASE_AND_DATA (0x364)
+#define CKM_EXTRACT_KEY_FROM_KEY (0x365)
+#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370)
+#define CKM_SSL3_MASTER_KEY_DERIVE (0x371)
+#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372)
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373)
+#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374)
+#define CKM_TLS_MASTER_KEY_DERIVE (0x375)
+#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376)
+#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377)
+#define CKM_SSL3_MD5_MAC (0x380)
+#define CKM_SSL3_SHA1_MAC (0x381)
+#define CKM_MD5_KEY_DERIVATION (0x390)
+#define CKM_MD2_KEY_DERIVATION (0x391)
+#define CKM_SHA1_KEY_DERIVATION (0x392)
+#define CKM_PBE_MD2_DES_CBC (0x3a0)
+#define CKM_PBE_MD5_DES_CBC (0x3a1)
+#define CKM_PBE_MD5_CAST_CBC (0x3a2)
+#define CKM_PBE_MD5_CAST3_CBC (0x3a3)
+#define CKM_PBE_MD5_CAST5_CBC (0x3a4)
+#define CKM_PBE_MD5_CAST128_CBC (0x3a4)
+#define CKM_PBE_SHA1_CAST5_CBC (0x3a5)
+#define CKM_PBE_SHA1_CAST128_CBC (0x3a5)
+#define CKM_PBE_SHA1_RC4_128 (0x3a6)
+#define CKM_PBE_SHA1_RC4_40 (0x3a7)
+#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8)
+#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9)
+#define CKM_PBE_SHA1_RC2_128_CBC (0x3aa)
+#define CKM_PBE_SHA1_RC2_40_CBC (0x3ab)
+#define CKM_PKCS5_PBKD2 (0x3b0)
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0)
+#define CKM_KEY_WRAP_LYNKS (0x400)
+#define CKM_KEY_WRAP_SET_OAEP (0x401)
+#define CKM_SKIPJACK_KEY_GEN (0x1000)
+#define CKM_SKIPJACK_ECB64 (0x1001)
+#define CKM_SKIPJACK_CBC64 (0x1002)
+#define CKM_SKIPJACK_OFB64 (0x1003)
+#define CKM_SKIPJACK_CFB64 (0x1004)
+#define CKM_SKIPJACK_CFB32 (0x1005)
+#define CKM_SKIPJACK_CFB16 (0x1006)
+#define CKM_SKIPJACK_CFB8 (0x1007)
+#define CKM_SKIPJACK_WRAP (0x1008)
+#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009)
+#define CKM_SKIPJACK_RELAYX (0x100a)
+#define CKM_KEA_KEY_PAIR_GEN (0x1010)
+#define CKM_KEA_KEY_DERIVE (0x1011)
+#define CKM_FORTEZZA_TIMESTAMP (0x1020)
+#define CKM_BATON_KEY_GEN (0x1030)
+#define CKM_BATON_ECB128 (0x1031)
+#define CKM_BATON_ECB96 (0x1032)
+#define CKM_BATON_CBC128 (0x1033)
+#define CKM_BATON_COUNTER (0x1034)
+#define CKM_BATON_SHUFFLE (0x1035)
+#define CKM_BATON_WRAP (0x1036)
+#define CKM_ECDSA_KEY_PAIR_GEN (0x1040)
+#define CKM_EC_KEY_PAIR_GEN (0x1040)
+#define CKM_ECDSA (0x1041)
+#define CKM_ECDSA_SHA1 (0x1042)
+#define CKM_ECDH1_DERIVE (0x1050)
+#define CKM_ECDH1_COFACTOR_DERIVE (0x1051)
+#define CKM_ECMQV_DERIVE (0x1052)
+#define CKM_JUNIPER_KEY_GEN (0x1060)
+#define CKM_JUNIPER_ECB128 (0x1061)
+#define CKM_JUNIPER_CBC128 (0x1062)
+#define CKM_JUNIPER_COUNTER (0x1063)
+#define CKM_JUNIPER_SHUFFLE (0x1064)
+#define CKM_JUNIPER_WRAP (0x1065)
+#define CKM_FASTHASH (0x1070)
+#define CKM_AES_KEY_GEN (0x1080)
+#define CKM_AES_ECB (0x1081)
+#define CKM_AES_CBC (0x1082)
+#define CKM_AES_MAC (0x1083)
+#define CKM_AES_MAC_GENERAL (0x1084)
+#define CKM_AES_CBC_PAD (0x1085)
+#define CKM_DSA_PARAMETER_GEN (0x2000)
+#define CKM_DH_PKCS_PARAMETER_GEN (0x2001)
+#define CKM_X9_42_DH_PARAMETER_GEN (0x2002)
+#define CKM_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+
+struct ck_mechanism
+{
+ ck_mechanism_type_t mechanism;
+ void *parameter;
+ unsigned long parameter_len;
+};
+
+
+struct ck_mechanism_info
+{
+ unsigned long min_key_size;
+ unsigned long max_key_size;
+ ck_flags_t flags;
+};
+
+#define CKF_HW (1 << 0)
+#define CKF_ENCRYPT (1 << 8)
+#define CKF_DECRYPT (1 << 9)
+#define CKF_DIGEST (1 << 10)
+#define CKF_SIGN (1 << 11)
+#define CKF_SIGN_RECOVER (1 << 12)
+#define CKF_VERIFY (1 << 13)
+#define CKF_VERIFY_RECOVER (1 << 14)
+#define CKF_GENERATE (1 << 15)
+#define CKF_GENERATE_KEY_PAIR (1 << 16)
+#define CKF_WRAP (1 << 17)
+#define CKF_UNWRAP (1 << 18)
+#define CKF_DERIVE (1 << 19)
+#define CKF_EXTENSION ((unsigned long) (1 << 31))
+
+
+/* Flags for C_WaitForSlotEvent. */
+#define CKF_DONT_BLOCK (1)
+
+
+typedef unsigned long ck_rv_t;
+
+
+typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session,
+ ck_notification_t event, void *application);
+
+/* Forward reference. */
+struct ck_function_list;
+
+#define _CK_DECLARE_FUNCTION(name, args) \
+typedef ck_rv_t (*CK_ ## name) args; \
+ck_rv_t CK_SPEC name args
+
+_CK_DECLARE_FUNCTION (C_Initialize, (void *init_args));
+_CK_DECLARE_FUNCTION (C_Finalize, (void *reserved));
+_CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info));
+_CK_DECLARE_FUNCTION (C_GetFunctionList,
+ (struct ck_function_list **function_list));
+
+_CK_DECLARE_FUNCTION (C_GetSlotList,
+ (unsigned char token_present, ck_slot_id_t *slot_list,
+ unsigned long *count));
+_CK_DECLARE_FUNCTION (C_GetSlotInfo,
+ (ck_slot_id_t slot_id, struct ck_slot_info *info));
+_CK_DECLARE_FUNCTION (C_GetTokenInfo,
+ (ck_slot_id_t slot_id, struct ck_token_info *info));
+_CK_DECLARE_FUNCTION (C_WaitForSlotEvent,
+ (ck_flags_t flags, ck_slot_id_t *slot, void *reserved));
+_CK_DECLARE_FUNCTION (C_GetMechanismList,
+ (ck_slot_id_t slot_id,
+ ck_mechanism_type_t *mechanism_list,
+ unsigned long *count));
+_CK_DECLARE_FUNCTION (C_GetMechanismInfo,
+ (ck_slot_id_t slot_id, ck_mechanism_type_t type,
+ struct ck_mechanism_info *info));
+_CK_DECLARE_FUNCTION (C_InitToken,
+ (ck_slot_id_t slot_id, unsigned char *pin,
+ unsigned long pin_len, unsigned char *label));
+_CK_DECLARE_FUNCTION (C_InitPIN,
+ (ck_session_handle_t session, unsigned char *pin,
+ unsigned long pin_len));
+_CK_DECLARE_FUNCTION (C_SetPIN,
+ (ck_session_handle_t session, unsigned char *old_pin,
+ unsigned long old_len, unsigned char *new_pin,
+ unsigned long new_len));
+
+_CK_DECLARE_FUNCTION (C_OpenSession,
+ (ck_slot_id_t slot_id, ck_flags_t flags,
+ void *application, ck_notify_t notify,
+ ck_session_handle_t *session));
+_CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session));
+_CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id));
+_CK_DECLARE_FUNCTION (C_GetSessionInfo,
+ (ck_session_handle_t session,
+ struct ck_session_info *info));
+_CK_DECLARE_FUNCTION (C_GetOperationState,
+ (ck_session_handle_t session,
+ unsigned char *operation_state,
+ unsigned long *operation_state_len));
+_CK_DECLARE_FUNCTION (C_SetOperationState,
+ (ck_session_handle_t session,
+ unsigned char *operation_state,
+ unsigned long operation_state_len,
+ ck_object_handle_t encryption_key,
+ ck_object_handle_t authentiation_key));
+_CK_DECLARE_FUNCTION (C_Login,
+ (ck_session_handle_t session, ck_user_type_t user_type,
+ unsigned char *pin, unsigned long pin_len));
+_CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session));
+
+_CK_DECLARE_FUNCTION (C_CreateObject,
+ (ck_session_handle_t session,
+ struct ck_attribute *templ,
+ unsigned long count, ck_object_handle_t *object));
+_CK_DECLARE_FUNCTION (C_CopyObject,
+ (ck_session_handle_t session, ck_object_handle_t object,
+ struct ck_attribute *templ, unsigned long count,
+ ck_object_handle_t *new_object));
+_CK_DECLARE_FUNCTION (C_DestroyObject,
+ (ck_session_handle_t session,
+ ck_object_handle_t object));
+_CK_DECLARE_FUNCTION (C_GetObjectSize,
+ (ck_session_handle_t session,
+ ck_object_handle_t object,
+ unsigned long *size));
+_CK_DECLARE_FUNCTION (C_GetAttributeValue,
+ (ck_session_handle_t session,
+ ck_object_handle_t object,
+ struct ck_attribute *templ,
+ unsigned long count));
+_CK_DECLARE_FUNCTION (C_SetAttributeValue,
+ (ck_session_handle_t session,
+ ck_object_handle_t object,
+ struct ck_attribute *templ,
+ unsigned long count));
+_CK_DECLARE_FUNCTION (C_FindObjectsInit,
+ (ck_session_handle_t session,
+ struct ck_attribute *templ,
+ unsigned long count));
+_CK_DECLARE_FUNCTION (C_FindObjects,
+ (ck_session_handle_t session,
+ ck_object_handle_t *object,
+ unsigned long max_object_count,
+ unsigned long *object_count));
+_CK_DECLARE_FUNCTION (C_FindObjectsFinal,
+ (ck_session_handle_t session));
+
+_CK_DECLARE_FUNCTION (C_EncryptInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_Encrypt,
+ (ck_session_handle_t session,
+ unsigned char *data, unsigned long data_len,
+ unsigned char *encrypted_data,
+ unsigned long *encrypted_data_len));
+_CK_DECLARE_FUNCTION (C_EncryptUpdate,
+ (ck_session_handle_t session,
+ unsigned char *part, unsigned long part_len,
+ unsigned char *encrypted_part,
+ unsigned long *encrypted_part_len));
+_CK_DECLARE_FUNCTION (C_EncryptFinal,
+ (ck_session_handle_t session,
+ unsigned char *last_encrypted_part,
+ unsigned long *last_encrypted_part_len));
+
+_CK_DECLARE_FUNCTION (C_DecryptInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_Decrypt,
+ (ck_session_handle_t session,
+ unsigned char *encrypted_data,
+ unsigned long encrypted_data_len,
+ unsigned char *data, unsigned long *data_len));
+_CK_DECLARE_FUNCTION (C_DecryptUpdate,
+ (ck_session_handle_t session,
+ unsigned char *encrypted_part,
+ unsigned long encrypted_part_len,
+ unsigned char *part, unsigned long *part_len));
+_CK_DECLARE_FUNCTION (C_DecryptFinal,
+ (ck_session_handle_t session,
+ unsigned char *last_part,
+ unsigned long *last_part_len));
+
+_CK_DECLARE_FUNCTION (C_DigestInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism));
+_CK_DECLARE_FUNCTION (C_Digest,
+ (ck_session_handle_t session,
+ unsigned char *data, unsigned long data_len,
+ unsigned char *digest,
+ unsigned long *digest_len));
+_CK_DECLARE_FUNCTION (C_DigestUpdate,
+ (ck_session_handle_t session,
+ unsigned char *part, unsigned long part_len));
+_CK_DECLARE_FUNCTION (C_DigestKey,
+ (ck_session_handle_t session, ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_DigestFinal,
+ (ck_session_handle_t session,
+ unsigned char *digest,
+ unsigned long *digest_len));
+
+_CK_DECLARE_FUNCTION (C_SignInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_Sign,
+ (ck_session_handle_t session,
+ unsigned char *data, unsigned long data_len,
+ unsigned char *signature,
+ unsigned long *signature_len));
+_CK_DECLARE_FUNCTION (C_SignUpdate,
+ (ck_session_handle_t session,
+ unsigned char *part, unsigned long part_len));
+_CK_DECLARE_FUNCTION (C_SignFinal,
+ (ck_session_handle_t session,
+ unsigned char *signature,
+ unsigned long *signature_len));
+_CK_DECLARE_FUNCTION (C_SignRecoverInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_SignRecover,
+ (ck_session_handle_t session,
+ unsigned char *data, unsigned long data_len,
+ unsigned char *signature,
+ unsigned long *signature_len));
+
+_CK_DECLARE_FUNCTION (C_VerifyInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_Verify,
+ (ck_session_handle_t session,
+ unsigned char *data, unsigned long data_len,
+ unsigned char *signature,
+ unsigned long signature_len));
+_CK_DECLARE_FUNCTION (C_VerifyUpdate,
+ (ck_session_handle_t session,
+ unsigned char *part, unsigned long part_len));
+_CK_DECLARE_FUNCTION (C_VerifyFinal,
+ (ck_session_handle_t session,
+ unsigned char *signature,
+ unsigned long signature_len));
+_CK_DECLARE_FUNCTION (C_VerifyRecoverInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_VerifyRecover,
+ (ck_session_handle_t session,
+ unsigned char *signature,
+ unsigned long signature_len,
+ unsigned char *data,
+ unsigned long *data_len));
+
+_CK_DECLARE_FUNCTION (C_DigestEncryptUpdate,
+ (ck_session_handle_t session,
+ unsigned char *part, unsigned long part_len,
+ unsigned char *encrypted_part,
+ unsigned long *encrypted_part_len));
+_CK_DECLARE_FUNCTION (C_DecryptDigestUpdate,
+ (ck_session_handle_t session,
+ unsigned char *encrypted_part,
+ unsigned long encrypted_part_len,
+ unsigned char *part,
+ unsigned long *part_len));
+_CK_DECLARE_FUNCTION (C_SignEncryptUpdate,
+ (ck_session_handle_t session,
+ unsigned char *part, unsigned long part_len,
+ unsigned char *encrypted_part,
+ unsigned long *encrypted_part_len));
+_CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate,
+ (ck_session_handle_t session,
+ unsigned char *encrypted_part,
+ unsigned long encrypted_part_len,
+ unsigned char *part,
+ unsigned long *part_len));
+
+_CK_DECLARE_FUNCTION (C_GenerateKey,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ struct ck_attribute *templ,
+ unsigned long count,
+ ck_object_handle_t *key));
+_CK_DECLARE_FUNCTION (C_GenerateKeyPair,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ struct ck_attribute *public_key_template,
+ unsigned long public_key_attribute_count,
+ struct ck_attribute *private_key_template,
+ unsigned long private_key_attribute_count,
+ ck_object_handle_t *public_key,
+ ck_object_handle_t *private_key));
+_CK_DECLARE_FUNCTION (C_WrapKey,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t wrapping_key,
+ ck_object_handle_t key,
+ unsigned char *wrapped_key,
+ unsigned long *wrapped_key_len));
+_CK_DECLARE_FUNCTION (C_UnwrapKey,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t unwrapping_key,
+ unsigned char *wrapped_key,
+ unsigned long wrapped_key_len,
+ struct ck_attribute *templ,
+ unsigned long attribute_count,
+ ck_object_handle_t *key));
+_CK_DECLARE_FUNCTION (C_DeriveKey,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t base_key,
+ struct ck_attribute *templ,
+ unsigned long attribute_count,
+ ck_object_handle_t *key));
+
+_CK_DECLARE_FUNCTION (C_SeedRandom,
+ (ck_session_handle_t session, unsigned char *seed,
+ unsigned long seed_len));
+_CK_DECLARE_FUNCTION (C_GenerateRandom,
+ (ck_session_handle_t session,
+ unsigned char *random_data,
+ unsigned long random_len));
+
+_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session));
+_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session));
+
+
+struct ck_function_list
+{
+ struct ck_version version;
+ CK_C_Initialize C_Initialize;
+ CK_C_Finalize C_Finalize;
+ CK_C_GetInfo C_GetInfo;
+ CK_C_GetFunctionList C_GetFunctionList;
+ CK_C_GetSlotList C_GetSlotList;
+ CK_C_GetSlotInfo C_GetSlotInfo;
+ CK_C_GetTokenInfo C_GetTokenInfo;
+ CK_C_GetMechanismList C_GetMechanismList;
+ CK_C_GetMechanismInfo C_GetMechanismInfo;
+ CK_C_InitToken C_InitToken;
+ CK_C_InitPIN C_InitPIN;
+ CK_C_SetPIN C_SetPIN;
+ CK_C_OpenSession C_OpenSession;
+ CK_C_CloseSession C_CloseSession;
+ CK_C_CloseAllSessions C_CloseAllSessions;
+ CK_C_GetSessionInfo C_GetSessionInfo;
+ CK_C_GetOperationState C_GetOperationState;
+ CK_C_SetOperationState C_SetOperationState;
+ CK_C_Login C_Login;
+ CK_C_Logout C_Logout;
+ CK_C_CreateObject C_CreateObject;
+ CK_C_CopyObject C_CopyObject;
+ CK_C_DestroyObject C_DestroyObject;
+ CK_C_GetObjectSize C_GetObjectSize;
+ CK_C_GetAttributeValue C_GetAttributeValue;
+ CK_C_SetAttributeValue C_SetAttributeValue;
+ CK_C_FindObjectsInit C_FindObjectsInit;
+ CK_C_FindObjects C_FindObjects;
+ CK_C_FindObjectsFinal C_FindObjectsFinal;
+ CK_C_EncryptInit C_EncryptInit;
+ CK_C_Encrypt C_Encrypt;
+ CK_C_EncryptUpdate C_EncryptUpdate;
+ CK_C_EncryptFinal C_EncryptFinal;
+ CK_C_DecryptInit C_DecryptInit;
+ CK_C_Decrypt C_Decrypt;
+ CK_C_DecryptUpdate C_DecryptUpdate;
+ CK_C_DecryptFinal C_DecryptFinal;
+ CK_C_DigestInit C_DigestInit;
+ CK_C_Digest C_Digest;
+ CK_C_DigestUpdate C_DigestUpdate;
+ CK_C_DigestKey C_DigestKey;
+ CK_C_DigestFinal C_DigestFinal;
+ CK_C_SignInit C_SignInit;
+ CK_C_Sign C_Sign;
+ CK_C_SignUpdate C_SignUpdate;
+ CK_C_SignFinal C_SignFinal;
+ CK_C_SignRecoverInit C_SignRecoverInit;
+ CK_C_SignRecover C_SignRecover;
+ CK_C_VerifyInit C_VerifyInit;
+ CK_C_Verify C_Verify;
+ CK_C_VerifyUpdate C_VerifyUpdate;
+ CK_C_VerifyFinal C_VerifyFinal;
+ CK_C_VerifyRecoverInit C_VerifyRecoverInit;
+ CK_C_VerifyRecover C_VerifyRecover;
+ CK_C_DigestEncryptUpdate C_DigestEncryptUpdate;
+ CK_C_DecryptDigestUpdate C_DecryptDigestUpdate;
+ CK_C_SignEncryptUpdate C_SignEncryptUpdate;
+ CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate;
+ CK_C_GenerateKey C_GenerateKey;
+ CK_C_GenerateKeyPair C_GenerateKeyPair;
+ CK_C_WrapKey C_WrapKey;
+ CK_C_UnwrapKey C_UnwrapKey;
+ CK_C_DeriveKey C_DeriveKey;
+ CK_C_SeedRandom C_SeedRandom;
+ CK_C_GenerateRandom C_GenerateRandom;
+ CK_C_GetFunctionStatus C_GetFunctionStatus;
+ CK_C_CancelFunction C_CancelFunction;
+ CK_C_WaitForSlotEvent C_WaitForSlotEvent;
+};
+
+
+typedef ck_rv_t (*ck_createmutex_t) (void **mutex);
+typedef ck_rv_t (*ck_destroymutex_t) (void *mutex);
+typedef ck_rv_t (*ck_lockmutex_t) (void *mutex);
+typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex);
+
+
+struct ck_c_initialize_args
+{
+ ck_createmutex_t create_mutex;
+ ck_destroymutex_t destroy_mutex;
+ ck_lockmutex_t lock_mutex;
+ ck_unlockmutex_t unlock_mutex;
+ ck_flags_t flags;
+ void *reserved;
+};
+
+
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0)
+#define CKF_OS_LOCKING_OK (1 << 1)
+
+#define CKR_OK (0)
+#define CKR_CANCEL (1)
+#define CKR_HOST_MEMORY (2)
+#define CKR_SLOT_ID_INVALID (3)
+#define CKR_GENERAL_ERROR (5)
+#define CKR_FUNCTION_FAILED (6)
+#define CKR_ARGUMENTS_BAD (7)
+#define CKR_NO_EVENT (8)
+#define CKR_NEED_TO_CREATE_THREADS (9)
+#define CKR_CANT_LOCK (0xa)
+#define CKR_ATTRIBUTE_READ_ONLY (0x10)
+#define CKR_ATTRIBUTE_SENSITIVE (0x11)
+#define CKR_ATTRIBUTE_TYPE_INVALID (0x12)
+#define CKR_ATTRIBUTE_VALUE_INVALID (0x13)
+#define CKR_DATA_INVALID (0x20)
+#define CKR_DATA_LEN_RANGE (0x21)
+#define CKR_DEVICE_ERROR (0x30)
+#define CKR_DEVICE_MEMORY (0x31)
+#define CKR_DEVICE_REMOVED (0x32)
+#define CKR_ENCRYPTED_DATA_INVALID (0x40)
+#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41)
+#define CKR_FUNCTION_CANCELED (0x50)
+#define CKR_FUNCTION_NOT_PARALLEL (0x51)
+#define CKR_FUNCTION_NOT_SUPPORTED (0x54)
+#define CKR_KEY_HANDLE_INVALID (0x60)
+#define CKR_KEY_SIZE_RANGE (0x62)
+#define CKR_KEY_TYPE_INCONSISTENT (0x63)
+#define CKR_KEY_NOT_NEEDED (0x64)
+#define CKR_KEY_CHANGED (0x65)
+#define CKR_KEY_NEEDED (0x66)
+#define CKR_KEY_INDIGESTIBLE (0x67)
+#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68)
+#define CKR_KEY_NOT_WRAPPABLE (0x69)
+#define CKR_KEY_UNEXTRACTABLE (0x6a)
+#define CKR_MECHANISM_INVALID (0x70)
+#define CKR_MECHANISM_PARAM_INVALID (0x71)
+#define CKR_OBJECT_HANDLE_INVALID (0x82)
+#define CKR_OPERATION_ACTIVE (0x90)
+#define CKR_OPERATION_NOT_INITIALIZED (0x91)
+#define CKR_PIN_INCORRECT (0xa0)
+#define CKR_PIN_INVALID (0xa1)
+#define CKR_PIN_LEN_RANGE (0xa2)
+#define CKR_PIN_EXPIRED (0xa3)
+#define CKR_PIN_LOCKED (0xa4)
+#define CKR_SESSION_CLOSED (0xb0)
+#define CKR_SESSION_COUNT (0xb1)
+#define CKR_SESSION_HANDLE_INVALID (0xb3)
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4)
+#define CKR_SESSION_READ_ONLY (0xb5)
+#define CKR_SESSION_EXISTS (0xb6)
+#define CKR_SESSION_READ_ONLY_EXISTS (0xb7)
+#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8)
+#define CKR_SIGNATURE_INVALID (0xc0)
+#define CKR_SIGNATURE_LEN_RANGE (0xc1)
+#define CKR_TEMPLATE_INCOMPLETE (0xd0)
+#define CKR_TEMPLATE_INCONSISTENT (0xd1)
+#define CKR_TOKEN_NOT_PRESENT (0xe0)
+#define CKR_TOKEN_NOT_RECOGNIZED (0xe1)
+#define CKR_TOKEN_WRITE_PROTECTED (0xe2)
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0)
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1)
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2)
+#define CKR_USER_ALREADY_LOGGED_IN (0x100)
+#define CKR_USER_NOT_LOGGED_IN (0x101)
+#define CKR_USER_PIN_NOT_INITIALIZED (0x102)
+#define CKR_USER_TYPE_INVALID (0x103)
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104)
+#define CKR_USER_TOO_MANY_TYPES (0x105)
+#define CKR_WRAPPED_KEY_INVALID (0x110)
+#define CKR_WRAPPED_KEY_LEN_RANGE (0x112)
+#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113)
+#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114)
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115)
+#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120)
+#define CKR_RANDOM_NO_RNG (0x121)
+#define CKR_DOMAIN_PARAMS_INVALID (0x130)
+#define CKR_BUFFER_TOO_SMALL (0x150)
+#define CKR_SAVED_STATE_INVALID (0x160)
+#define CKR_INFORMATION_SENSITIVE (0x170)
+#define CKR_STATE_UNSAVEABLE (0x180)
+#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190)
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191)
+#define CKR_MUTEX_BAD (0x1a0)
+#define CKR_MUTEX_NOT_LOCKED (0x1a1)
+#define CKR_FUNCTION_REJECTED (0x200)
+#define CKR_VENDOR_DEFINED ((unsigned long) (1 << 31))
+
+
+
+/* Compatibility layer. */
+
+#ifdef CRYPTOKI_COMPAT
+
+#undef CK_DEFINE_FUNCTION
+#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name
+
+/* For NULL. */
+#include <stddef.h>
+
+typedef unsigned char CK_BYTE;
+typedef unsigned char CK_CHAR;
+typedef unsigned char CK_UTF8CHAR;
+typedef unsigned char CK_BBOOL;
+typedef unsigned long int CK_ULONG;
+typedef long int CK_LONG;
+typedef CK_BYTE *CK_BYTE_PTR;
+typedef CK_CHAR *CK_CHAR_PTR;
+typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR;
+typedef CK_ULONG *CK_ULONG_PTR;
+typedef void *CK_VOID_PTR;
+typedef void **CK_VOID_PTR_PTR;
+#define CK_FALSE 0
+#define CK_TRUE 1
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#endif
+
+typedef struct ck_version CK_VERSION;
+typedef struct ck_version *CK_VERSION_PTR;
+
+typedef struct ck_info CK_INFO;
+typedef struct ck_info *CK_INFO_PTR;
+
+typedef ck_slot_id_t *CK_SLOT_ID_PTR;
+
+typedef struct ck_slot_info CK_SLOT_INFO;
+typedef struct ck_slot_info *CK_SLOT_INFO_PTR;
+
+typedef struct ck_token_info CK_TOKEN_INFO;
+typedef struct ck_token_info *CK_TOKEN_INFO_PTR;
+
+typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR;
+
+typedef struct ck_session_info CK_SESSION_INFO;
+typedef struct ck_session_info *CK_SESSION_INFO_PTR;
+
+typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR;
+
+typedef ck_object_class_t *CK_OBJECT_CLASS_PTR;
+
+typedef struct ck_attribute CK_ATTRIBUTE;
+typedef struct ck_attribute *CK_ATTRIBUTE_PTR;
+
+typedef struct ck_date CK_DATE;
+typedef struct ck_date *CK_DATE_PTR;
+
+typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR;
+
+typedef struct ck_mechanism CK_MECHANISM;
+typedef struct ck_mechanism *CK_MECHANISM_PTR;
+
+typedef struct ck_mechanism_info CK_MECHANISM_INFO;
+typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR;
+
+typedef struct ck_function_list CK_FUNCTION_LIST;
+typedef struct ck_function_list *CK_FUNCTION_LIST_PTR;
+typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR;
+
+typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS;
+typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
+
+#define NULL_PTR NULL
+
+/* Delete the helper macros defined at the top of the file. */
+#undef ck_flags_t
+#undef ck_version
+
+#undef ck_info
+#undef cryptoki_version
+#undef manufacturer_id
+#undef library_description
+#undef library_version
+
+#undef ck_notification_t
+#undef ck_slot_id_t
+
+#undef ck_slot_info
+#undef slot_description
+#undef hardware_version
+#undef firmware_version
+
+#undef ck_token_info
+#undef serial_number
+#undef max_session_count
+#undef session_count
+#undef max_rw_session_count
+#undef rw_session_count
+#undef max_pin_len
+#undef min_pin_len
+#undef total_public_memory
+#undef free_public_memory
+#undef total_private_memory
+#undef free_private_memory
+#undef utc_time
+
+#undef ck_session_handle_t
+#undef ck_user_type_t
+#undef ck_state_t
+
+#undef ck_session_info
+#undef slot_id
+#undef device_error
+
+#undef ck_object_handle_t
+#undef ck_object_class_t
+#undef ck_hw_feature_type_t
+#undef ck_key_type_t
+#undef ck_certificate_type_t
+#undef ck_attribute_type_t
+
+#undef ck_attribute
+#undef value
+#undef value_len
+
+#undef ck_date
+
+#undef ck_mechanism_type_t
+
+#undef ck_mechanism
+#undef parameter
+#undef parameter_len
+
+#undef ck_mechanism_info
+#undef min_key_size
+#undef max_key_size
+
+#undef ck_rv_t
+#undef ck_notify_t
+
+#undef ck_function_list
+
+#undef ck_createmutex_t
+#undef ck_destroymutex_t
+#undef ck_lockmutex_t
+#undef ck_unlockmutex_t
+
+#undef ck_c_initialize_args
+#undef create_mutex
+#undef destroy_mutex
+#undef lock_mutex
+#undef unlock_mutex
+#undef reserved
+
+#endif /* CRYPTOKI_COMPAT */
+
+
+/* System dependencies. */
+#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
+#pragma pack(pop, cryptoki)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* PKCS11_H */
diff --git a/crypto/openssh/platform.c b/crypto/openssh/platform.c
index aee4b01..e3a428a 100644
--- a/crypto/openssh/platform.c
+++ b/crypto/openssh/platform.c
@@ -1,4 +1,4 @@
-/* $Id: platform.c,v 1.1 2006/08/30 17:24:41 djm Exp $ */
+/* $Id: platform.c,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */
/*
* Copyright (c) 2006 Darren Tucker. All rights reserved.
@@ -22,6 +22,15 @@
#include "openbsd-compat/openbsd-compat.h"
void
+platform_pre_listen(void)
+{
+#ifdef LINUX_OOM_ADJUST
+ /* Adjust out-of-memory killer so listening process is not killed */
+ oom_adjust_setup();
+#endif
+}
+
+void
platform_pre_fork(void)
{
#ifdef USE_SOLARIS_PROCESS_CONTRACTS
@@ -43,4 +52,17 @@ platform_post_fork_child(void)
#ifdef USE_SOLARIS_PROCESS_CONTRACTS
solaris_contract_post_fork_child();
#endif
+#ifdef LINUX_OOM_ADJUST
+ oom_adjust_restore();
+#endif
+}
+
+char *
+platform_krb5_get_principal_name(const char *pw_name)
+{
+#ifdef USE_AIX_KRB_NAME
+ return aix_krb5_get_principal_name(pw_name);
+#else
+ return NULL;
+#endif
}
diff --git a/crypto/openssh/platform.h b/crypto/openssh/platform.h
index cf93bc5..30a1d22 100644
--- a/crypto/openssh/platform.h
+++ b/crypto/openssh/platform.h
@@ -1,4 +1,4 @@
-/* $Id: platform.h,v 1.1 2006/08/30 17:24:41 djm Exp $ */
+/* $Id: platform.h,v 1.4 2010/01/14 01:44:16 djm Exp $ */
/*
* Copyright (c) 2006 Darren Tucker. All rights reserved.
@@ -18,6 +18,11 @@
#include <sys/types.h>
+void platform_pre_listen(void);
void platform_pre_fork(void);
void platform_post_fork_parent(pid_t child_pid);
void platform_post_fork_child(void);
+char *platform_get_krb5_client(const char *);
+char *platform_krb5_get_principal_name(const char *);
+
+
diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
index 8d3fc40..6c4bb34 100644
--- a/crypto/openssh/readconf.c
+++ b/crypto/openssh/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.177 2009/06/27 09:35:06 andreas Exp $ */
+/* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -126,7 +126,7 @@ typedef enum {
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
- oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
+ oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
@@ -209,10 +209,12 @@ static struct {
{ "preferredauthentications", oPreferredAuthentications },
{ "hostkeyalgorithms", oHostKeyAlgorithms },
{ "bindaddress", oBindAddress },
-#ifdef SMARTCARD
- { "smartcarddevice", oSmartcardDevice },
+#ifdef ENABLE_PKCS11
+ { "smartcarddevice", oPKCS11Provider },
+ { "pkcs11provider", oPKCS11Provider },
#else
{ "smartcarddevice", oUnsupported },
+ { "pkcs11provider", oUnsupported },
#endif
{ "clearallforwardings", oClearAllForwardings },
{ "enablesshkeysign", oEnableSSHKeysign },
@@ -626,8 +628,8 @@ parse_string:
charptr = &options->bind_address;
goto parse_string;
- case oSmartcardDevice:
- charptr = &options->smartcard_device;
+ case oPKCS11Provider:
+ charptr = &options->pkcs11_provider;
goto parse_string;
case oProxyCommand:
@@ -1075,7 +1077,7 @@ initialize_options(Options * options)
options->log_level = SYSLOG_LEVEL_NOT_SET;
options->preferred_authentications = NULL;
options->bind_address = NULL;
- options->smartcard_device = NULL;
+ options->pkcs11_provider = NULL;
options->enable_ssh_keysign = - 1;
options->no_host_authentication_for_localhost = - 1;
options->identities_only = - 1;
@@ -1166,7 +1168,7 @@ fill_default_options(Options * options)
/* options->macs, default set in myproposals.h */
/* options->hostkeyalgorithms, default set in myproposals.h */
if (options->protocol == SSH_PROTO_UNKNOWN)
- options->protocol = SSH_PROTO_1|SSH_PROTO_2;
+ options->protocol = SSH_PROTO_2;
if (options->num_identity_files == 0) {
if (options->protocol & SSH_PROTO_1) {
len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
index 2ebfebe..4264751 100644
--- a/crypto/openssh/readconf.h
+++ b/crypto/openssh/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.79 2009/06/27 09:35:06 andreas Exp $ */
+/* $OpenBSD: readconf.h,v 1.82 2010/02/08 10:50:20 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -84,7 +84,7 @@ typedef struct {
char *user_hostfile2;
char *preferred_authentications;
char *bind_address; /* local socket address for connection to sshd */
- char *smartcard_device; /* Smartcard reader device */
+ char *pkcs11_provider; /* PKCS#11 provider */
int verify_host_key_dns; /* Verify host key using DNS */
int num_identity_files; /* Number of files for RSA/DSA identities. */
diff --git a/crypto/openssh/roaming.h b/crypto/openssh/roaming.h
index e517161..6bb94cc 100644
--- a/crypto/openssh/roaming.h
+++ b/crypto/openssh/roaming.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: roaming.h,v 1.4 2009/06/27 09:32:43 andreas Exp $ */
+/* $OpenBSD: roaming.h,v 1.5 2009/10/24 11:11:58 andreas Exp $ */
/*
* Copyright (c) 2004-2009 AppGate Network Security AB
*
@@ -19,12 +19,17 @@
#define ROAMING_H
#define DEFAULT_ROAMBUF 65536
+#define ROAMING_REQUEST "roaming@appgate.com"
+extern int roaming_enabled;
extern int resume_in_progress;
+void request_roaming(void);
int get_snd_buf_size(void);
int get_recv_buf_size(void);
void add_recv_bytes(u_int64_t);
+int wait_for_roaming_reconnect(void);
+void roaming_reply(int, u_int32_t, void *);
void set_out_buffer_size(size_t);
ssize_t roaming_write(int, const void *, size_t, int *);
ssize_t roaming_read(int, void *, size_t, int *);
@@ -33,6 +38,7 @@ u_int64_t get_recv_bytes(void);
u_int64_t get_sent_bytes(void);
void roam_set_bytes(u_int64_t, u_int64_t);
void resend_bytes(int, u_int64_t *);
+void calculate_new_key(u_int64_t *, u_int64_t, u_int64_t);
int resume_kex(void);
#endif /* ROAMING */
diff --git a/crypto/openssh/roaming_client.c b/crypto/openssh/roaming_client.c
new file mode 100644
index 0000000..cea8e73
--- /dev/null
+++ b/crypto/openssh/roaming_client.c
@@ -0,0 +1,280 @@
+/* $OpenBSD: roaming_client.c,v 1.3 2010/01/18 01:50:27 dtucker Exp $ */
+/*
+ * Copyright (c) 2004-2009 AppGate Network Security AB
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include "openbsd-compat/sys-queue.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "channels.h"
+#include "cipher.h"
+#include "dispatch.h"
+#include "clientloop.h"
+#include "log.h"
+#include "match.h"
+#include "misc.h"
+#include "packet.h"
+#include "ssh.h"
+#include "key.h"
+#include "kex.h"
+#include "readconf.h"
+#include "roaming.h"
+#include "ssh2.h"
+#include "sshconnect.h"
+
+/* import */
+extern Options options;
+extern char *host;
+extern struct sockaddr_storage hostaddr;
+extern int session_resumed;
+
+static u_int32_t roaming_id;
+static u_int64_t cookie;
+static u_int64_t lastseenchall;
+static u_int64_t key1, key2, oldkey1, oldkey2;
+
+void
+roaming_reply(int type, u_int32_t seq, void *ctxt)
+{
+ if (type == SSH2_MSG_REQUEST_FAILURE) {
+ logit("Server denied roaming");
+ return;
+ }
+ verbose("Roaming enabled");
+ roaming_id = packet_get_int();
+ cookie = packet_get_int64();
+ key1 = oldkey1 = packet_get_int64();
+ key2 = oldkey2 = packet_get_int64();
+ set_out_buffer_size(packet_get_int() + get_snd_buf_size());
+ roaming_enabled = 1;
+}
+
+void
+request_roaming(void)
+{
+ packet_start(SSH2_MSG_GLOBAL_REQUEST);
+ packet_put_cstring(ROAMING_REQUEST);
+ packet_put_char(1);
+ packet_put_int(get_recv_buf_size());
+ packet_send();
+ client_register_global_confirm(roaming_reply, NULL);
+}
+
+static void
+roaming_auth_required(void)
+{
+ u_char digest[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX md;
+ Buffer b;
+ const EVP_MD *evp_md = EVP_sha1();
+ u_int64_t chall, oldchall;
+
+ chall = packet_get_int64();
+ oldchall = packet_get_int64();
+ if (oldchall != lastseenchall) {
+ key1 = oldkey1;
+ key2 = oldkey2;
+ }
+ lastseenchall = chall;
+
+ buffer_init(&b);
+ buffer_put_int64(&b, cookie);
+ buffer_put_int64(&b, chall);
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+ EVP_DigestFinal(&md, digest, NULL);
+ buffer_free(&b);
+
+ packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
+ packet_put_int64(key1 ^ get_recv_bytes());
+ packet_put_raw(digest, sizeof(digest));
+ packet_send();
+
+ oldkey1 = key1;
+ oldkey2 = key2;
+ calculate_new_key(&key1, cookie, chall);
+ calculate_new_key(&key2, cookie, chall);
+
+ debug("Received %llu bytes", (unsigned long long)get_recv_bytes());
+ debug("Sent roaming_auth packet");
+}
+
+int
+resume_kex(void)
+{
+ /*
+ * This should not happen - if the client sends the kex method
+ * resume@appgate.com then the kex is done in roaming_resume().
+ */
+ return 1;
+}
+
+static int
+roaming_resume(void)
+{
+ u_int64_t recv_bytes;
+ char *str = NULL, *kexlist = NULL, *c;
+ int i, type;
+ int timeout_ms = options.connection_timeout * 1000;
+ u_int len;
+ u_int32_t rnd = 0;
+
+ resume_in_progress = 1;
+
+ /* Exchange banners */
+ ssh_exchange_identification(timeout_ms);
+ packet_set_nonblocking();
+
+ /* Send a kexinit message with resume@appgate.com as only kex algo */
+ packet_start(SSH2_MSG_KEXINIT);
+ for (i = 0; i < KEX_COOKIE_LEN; i++) {
+ if (i % 4 == 0)
+ rnd = arc4random();
+ packet_put_char(rnd & 0xff);
+ rnd >>= 8;
+ }
+ packet_put_cstring(KEX_RESUME);
+ for (i = 1; i < PROPOSAL_MAX; i++) {
+ /* kex algorithm added so start with i=1 and not 0 */
+ packet_put_cstring(""); /* Not used when we resume */
+ }
+ packet_put_char(1); /* first kex_packet follows */
+ packet_put_int(0); /* reserved */
+ packet_send();
+
+ /* Assume that resume@appgate.com will be accepted */
+ packet_start(SSH2_MSG_KEX_ROAMING_RESUME);
+ packet_put_int(roaming_id);
+ packet_send();
+
+ /* Read the server's kexinit and check for resume@appgate.com */
+ if ((type = packet_read()) != SSH2_MSG_KEXINIT) {
+ debug("expected kexinit on resume, got %d", type);
+ goto fail;
+ }
+ for (i = 0; i < KEX_COOKIE_LEN; i++)
+ (void)packet_get_char();
+ kexlist = packet_get_string(&len);
+ if (!kexlist
+ || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) {
+ debug("server doesn't allow resume");
+ goto fail;
+ }
+ xfree(str);
+ for (i = 1; i < PROPOSAL_MAX; i++) {
+ /* kex algorithm taken care of so start with i=1 and not 0 */
+ xfree(packet_get_string(&len));
+ }
+ i = packet_get_char(); /* first_kex_packet_follows */
+ if (i && (c = strchr(kexlist, ',')))
+ *c = 0;
+ if (i && strcmp(kexlist, KEX_RESUME)) {
+ debug("server's kex guess (%s) was wrong, skipping", kexlist);
+ (void)packet_read(); /* Wrong guess - discard packet */
+ }
+
+ /*
+ * Read the ROAMING_AUTH_REQUIRED challenge from the server and
+ * send ROAMING_AUTH
+ */
+ if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) {
+ debug("expected roaming_auth_required, got %d", type);
+ goto fail;
+ }
+ roaming_auth_required();
+
+ /* Read ROAMING_AUTH_OK from the server */
+ if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) {
+ debug("expected roaming_auth_ok, got %d", type);
+ goto fail;
+ }
+ recv_bytes = packet_get_int64() ^ oldkey2;
+ debug("Peer received %llu bytes", (unsigned long long)recv_bytes);
+ resend_bytes(packet_get_connection_out(), &recv_bytes);
+
+ resume_in_progress = 0;
+
+ session_resumed = 1; /* Tell clientloop */
+
+ return 0;
+
+fail:
+ if (kexlist)
+ xfree(kexlist);
+ if (packet_get_connection_in() == packet_get_connection_out())
+ close(packet_get_connection_in());
+ else {
+ close(packet_get_connection_in());
+ close(packet_get_connection_out());
+ }
+ return 1;
+}
+
+int
+wait_for_roaming_reconnect(void)
+{
+ static int reenter_guard = 0;
+ int timeout_ms = options.connection_timeout * 1000;
+ int c;
+
+ if (reenter_guard != 0)
+ fatal("Server refused resume, roaming timeout may be exceeded");
+ reenter_guard = 1;
+
+ fprintf(stderr, "[connection suspended, press return to resume]");
+ fflush(stderr);
+ packet_backup_state();
+ /* TODO Perhaps we should read from tty here */
+ while ((c = fgetc(stdin)) != EOF) {
+ if (c == 'Z' - 64) {
+ kill(getpid(), SIGTSTP);
+ continue;
+ }
+ if (c != '\n' && c != '\r')
+ continue;
+
+ if (ssh_connect(host, &hostaddr, options.port,
+ options.address_family, 1, &timeout_ms,
+ options.tcp_keep_alive, options.use_privileged_port,
+ options.proxy_command) == 0 && roaming_resume() == 0) {
+ packet_restore_state();
+ reenter_guard = 0;
+ fprintf(stderr, "[connection resumed]\n");
+ fflush(stderr);
+ return 0;
+ }
+
+ fprintf(stderr, "[reconnect failed, press return to retry]");
+ fflush(stderr);
+ }
+ fprintf(stderr, "[exiting]\n");
+ fflush(stderr);
+ exit(0);
+}
diff --git a/crypto/openssh/roaming_common.c b/crypto/openssh/roaming_common.c
index 73db09d..9adbe56 100644
--- a/crypto/openssh/roaming_common.c
+++ b/crypto/openssh/roaming_common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roaming_common.c,v 1.5 2009/06/27 09:32:43 andreas Exp $ */
+/* $OpenBSD: roaming_common.c,v 1.8 2010/01/12 00:59:29 djm Exp $ */
/*
* Copyright (c) 2004-2009 AppGate Network Security AB
*
@@ -52,9 +52,9 @@ int
get_snd_buf_size()
{
int fd = packet_get_connection_out();
- int optval, optvallen;
+ int optval;
+ socklen_t optvallen = sizeof(optval);
- optvallen = sizeof(optval);
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0)
optval = DEFAULT_ROAMBUF;
return optval;
@@ -64,9 +64,9 @@ int
get_recv_buf_size()
{
int fd = packet_get_connection_in();
- int optval, optvallen;
+ int optval;
+ socklen_t optvallen = sizeof(optval);
- optvallen = sizeof(optval);
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0)
optval = DEFAULT_ROAMBUF;
return optval;
@@ -145,8 +145,16 @@ roaming_write(int fd, const void *buf, size_t count, int *cont)
if (out_buf_size > 0)
buf_append(buf, ret);
}
- debug3("Wrote %ld bytes for a total of %llu", (long)ret,
- (unsigned long long)write_bytes);
+ if (out_buf_size > 0 &&
+ (ret == 0 || (ret == -1 && errno == EPIPE))) {
+ if (wait_for_roaming_reconnect() != 0) {
+ ret = 0;
+ *cont = 1;
+ } else {
+ ret = -1;
+ errno = EAGAIN;
+ }
+ }
return ret;
}
@@ -158,6 +166,15 @@ roaming_read(int fd, void *buf, size_t count, int *cont)
if (!resume_in_progress) {
read_bytes += ret;
}
+ } else if (out_buf_size > 0 &&
+ (ret == 0 || (ret == -1 && (errno == ECONNRESET
+ || errno == ECONNABORTED || errno == ETIMEDOUT
+ || errno == EHOSTUNREACH)))) {
+ debug("roaming_read failed for %d ret=%ld errno=%d",
+ fd, (long)ret, errno);
+ ret = 0;
+ if (wait_for_roaming_reconnect() == 0)
+ *cont = 1;
}
return ret;
}
@@ -199,3 +216,29 @@ resend_bytes(int fd, u_int64_t *offset)
atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
}
}
+
+/*
+ * Caclulate a new key after a reconnect
+ */
+void
+calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
+{
+ const EVP_MD *md = EVP_sha1();
+ EVP_MD_CTX ctx;
+ char hash[EVP_MAX_MD_SIZE];
+ Buffer b;
+
+ buffer_init(&b);
+ buffer_put_int64(&b, *key);
+ buffer_put_int64(&b, cookie);
+ buffer_put_int64(&b, challenge);
+
+ EVP_DigestInit(&ctx, md);
+ EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b));
+ EVP_DigestFinal(&ctx, hash, NULL);
+
+ buffer_clear(&b);
+ buffer_append(&b, hash, EVP_MD_size(md));
+ *key = buffer_get_int64(&b);
+ buffer_free(&b);
+}
diff --git a/crypto/openssh/roaming_serv.c b/crypto/openssh/roaming_serv.c
new file mode 100644
index 0000000..511ca84
--- /dev/null
+++ b/crypto/openssh/roaming_serv.c
@@ -0,0 +1,31 @@
+/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 andreas Exp $ */
+/*
+ * Copyright (c) 2004-2009 AppGate Network Security AB
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include "roaming.h"
+
+/*
+ * Wait for the roaming client to reconnect. Returns 0 if a connect ocurred.
+ */
+int
+wait_for_roaming_reconnect(void)
+{
+ return 1;
+}
diff --git a/crypto/openssh/scard-opensc.c b/crypto/openssh/scard-opensc.c
deleted file mode 100644
index 36dae05..0000000
--- a/crypto/openssh/scard-opensc.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (c) 2002 Juha Yrjölä. All rights reserved.
- * Copyright (c) 2001 Markus Friedl.
- *
- * 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 ``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 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 "includes.h"
-#if defined(SMARTCARD) && defined(USE_OPENSC)
-
-#include <sys/types.h>
-
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-
-#include <stdarg.h>
-#include <string.h>
-
-#include <opensc/opensc.h>
-#include <opensc/pkcs15.h>
-
-#include "key.h"
-#include "log.h"
-#include "xmalloc.h"
-#include "misc.h"
-#include "scard.h"
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
-#define USE_ENGINE
-#define RSA_get_default_method RSA_get_default_openssl_method
-#else
-#endif
-
-#ifdef USE_ENGINE
-#include <openssl/engine.h>
-#define sc_get_rsa sc_get_engine
-#else
-#define sc_get_rsa sc_get_rsa_method
-#endif
-
-static int sc_reader_id;
-static sc_context_t *ctx = NULL;
-static sc_card_t *card = NULL;
-static sc_pkcs15_card_t *p15card = NULL;
-
-static char *sc_pin = NULL;
-
-struct sc_priv_data
-{
- struct sc_pkcs15_id cert_id;
- int ref_count;
-};
-
-void
-sc_close(void)
-{
- if (p15card) {
- sc_pkcs15_unbind(p15card);
- p15card = NULL;
- }
- if (card) {
- sc_disconnect_card(card, 0);
- card = NULL;
- }
- if (ctx) {
- sc_release_context(ctx);
- ctx = NULL;
- }
-}
-
-static int
-sc_init(void)
-{
- int r;
-
- r = sc_establish_context(&ctx, "openssh");
- if (r)
- goto err;
- if (sc_reader_id >= ctx->reader_count) {
- r = SC_ERROR_NO_READERS_FOUND;
- error("Illegal reader number %d (max %d)", sc_reader_id,
- ctx->reader_count -1);
- goto err;
- }
- r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card);
- if (r)
- goto err;
- r = sc_pkcs15_bind(card, &p15card);
- if (r)
- goto err;
- return 0;
-err:
- sc_close();
- return r;
-}
-
-/* private key operations */
-
-static int
-sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out,
- unsigned int usage)
-{
- int r;
- struct sc_priv_data *priv;
- struct sc_pkcs15_object *key_obj;
- struct sc_pkcs15_prkey_info *key;
- struct sc_pkcs15_object *pin_obj;
- struct sc_pkcs15_pin_info *pin;
-
- priv = (struct sc_priv_data *) RSA_get_app_data(rsa);
- if (priv == NULL)
- return -1;
- if (p15card == NULL) {
- sc_close();
- r = sc_init();
- if (r) {
- error("SmartCard init failed: %s", sc_strerror(r));
- goto err;
- }
- }
- r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id,
- usage, &key_obj);
- if (r) {
- error("Unable to find private key from SmartCard: %s",
- sc_strerror(r));
- goto err;
- }
- key = key_obj->data;
- r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
- &pin_obj);
- if (r == SC_ERROR_OBJECT_NOT_FOUND) {
- /* no pin required */
- r = sc_lock(card);
- if (r) {
- error("Unable to lock smartcard: %s", sc_strerror(r));
- goto err;
- }
- *key_obj_out = key_obj;
- return 0;
- } else if (r) {
- error("Unable to find PIN object from SmartCard: %s",
- sc_strerror(r));
- goto err;
- }
- pin = pin_obj->data;
- r = sc_lock(card);
- if (r) {
- error("Unable to lock smartcard: %s", sc_strerror(r));
- goto err;
- }
- if (sc_pin != NULL) {
- r = sc_pkcs15_verify_pin(p15card, pin, sc_pin,
- strlen(sc_pin));
- if (r) {
- sc_unlock(card);
- error("PIN code verification failed: %s",
- sc_strerror(r));
- goto err;
- }
- }
- *key_obj_out = key_obj;
- return 0;
-err:
- sc_close();
- return -1;
-}
-
-#define SC_USAGE_DECRYPT SC_PKCS15_PRKEY_USAGE_DECRYPT | \
- SC_PKCS15_PRKEY_USAGE_UNWRAP
-
-static int
-sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
- int padding)
-{
- struct sc_pkcs15_object *key_obj;
- int r;
-
- if (padding != RSA_PKCS1_PADDING)
- return -1;
- r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT);
- if (r)
- return -1;
- r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1,
- from, flen, to, flen);
- sc_unlock(card);
- if (r < 0) {
- error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
- goto err;
- }
- return r;
-err:
- sc_close();
- return -1;
-}
-
-#define SC_USAGE_SIGN SC_PKCS15_PRKEY_USAGE_SIGN | \
- SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
-
-static int
-sc_sign(int type, u_char *m, unsigned int m_len,
- unsigned char *sigret, unsigned int *siglen, RSA *rsa)
-{
- struct sc_pkcs15_object *key_obj;
- int r;
- unsigned long flags = 0;
-
- /* XXX: sc_prkey_op_init will search for a pkcs15 private
- * key object with the sign or signrecover usage flag set.
- * If the signing key has only the non-repudiation flag set
- * the key will be rejected as using a non-repudiation key
- * for authentication is not recommended. Note: This does not
- * prevent the use of a non-repudiation key for authentication
- * if the sign or signrecover flag is set as well.
- */
- r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN);
- if (r)
- return -1;
- /* FIXME: length of sigret correct? */
- /* FIXME: check 'type' and modify flags accordingly */
- flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
- r = sc_pkcs15_compute_signature(p15card, key_obj, flags,
- m, m_len, sigret, RSA_size(rsa));
- sc_unlock(card);
- if (r < 0) {
- error("sc_pkcs15_compute_signature() failed: %s",
- sc_strerror(r));
- goto err;
- }
- *siglen = r;
- return 1;
-err:
- sc_close();
- return 0;
-}
-
-static int
-sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
- int padding)
-{
- error("Private key encryption not supported");
- return -1;
-}
-
-/* called on free */
-
-static int (*orig_finish)(RSA *rsa) = NULL;
-
-static int
-sc_finish(RSA *rsa)
-{
- struct sc_priv_data *priv;
-
- priv = RSA_get_app_data(rsa);
- priv->ref_count--;
- if (priv->ref_count == 0) {
- free(priv);
- sc_close();
- }
- if (orig_finish)
- orig_finish(rsa);
- return 1;
-}
-
-/* engine for overloading private key operations */
-
-static RSA_METHOD *
-sc_get_rsa_method(void)
-{
- static RSA_METHOD smart_rsa;
- const RSA_METHOD *def = RSA_get_default_method();
-
- /* use the OpenSSL version */
- memcpy(&smart_rsa, def, sizeof(smart_rsa));
-
- smart_rsa.name = "opensc";
-
- /* overload */
- smart_rsa.rsa_priv_enc = sc_private_encrypt;
- smart_rsa.rsa_priv_dec = sc_private_decrypt;
- smart_rsa.rsa_sign = sc_sign;
-
- /* save original */
- orig_finish = def->finish;
- smart_rsa.finish = sc_finish;
-
- return &smart_rsa;
-}
-
-#ifdef USE_ENGINE
-static ENGINE *
-sc_get_engine(void)
-{
- static ENGINE *smart_engine = NULL;
-
- if ((smart_engine = ENGINE_new()) == NULL)
- fatal("ENGINE_new failed");
-
- ENGINE_set_id(smart_engine, "opensc");
- ENGINE_set_name(smart_engine, "OpenSC");
-
- ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
- ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
- ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
- ENGINE_set_RAND(smart_engine, RAND_SSLeay());
- ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
-
- return smart_engine;
-}
-#endif
-
-static void
-convert_rsa_to_rsa1(Key * in, Key * out)
-{
- struct sc_priv_data *priv;
-
- out->rsa->flags = in->rsa->flags;
- out->flags = in->flags;
- RSA_set_method(out->rsa, RSA_get_method(in->rsa));
- BN_copy(out->rsa->n, in->rsa->n);
- BN_copy(out->rsa->e, in->rsa->e);
- priv = RSA_get_app_data(in->rsa);
- priv->ref_count++;
- RSA_set_app_data(out->rsa, priv);
- return;
-}
-
-static int
-sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
-{
- int r;
- sc_pkcs15_cert_t *cert = NULL;
- struct sc_priv_data *priv = NULL;
- sc_pkcs15_cert_info_t *cinfo = cert_obj->data;
-
- X509 *x509 = NULL;
- EVP_PKEY *pubkey = NULL;
- u8 *p;
- char *tmp;
-
- debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
- r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
- if (r) {
- logit("Certificate read failed: %s", sc_strerror(r));
- goto err;
- }
- x509 = X509_new();
- if (x509 == NULL) {
- r = -1;
- goto err;
- }
- p = cert->data;
- if (!d2i_X509(&x509, &p, cert->data_len)) {
- logit("Unable to parse X.509 certificate");
- r = -1;
- goto err;
- }
- sc_pkcs15_free_certificate(cert);
- cert = NULL;
- pubkey = X509_get_pubkey(x509);
- X509_free(x509);
- x509 = NULL;
- if (pubkey->type != EVP_PKEY_RSA) {
- logit("Public key is of unknown type");
- r = -1;
- goto err;
- }
- k->rsa = EVP_PKEY_get1_RSA(pubkey);
- EVP_PKEY_free(pubkey);
-
- k->rsa->flags |= RSA_FLAG_SIGN_VER;
- RSA_set_method(k->rsa, sc_get_rsa_method());
- priv = xmalloc(sizeof(struct sc_priv_data));
- priv->cert_id = cinfo->id;
- priv->ref_count = 1;
- RSA_set_app_data(k->rsa, priv);
-
- k->flags = KEY_FLAG_EXT;
- tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
- debug("fingerprint %d %s", key_size(k), tmp);
- xfree(tmp);
-
- return 0;
-err:
- if (cert)
- sc_pkcs15_free_certificate(cert);
- if (pubkey)
- EVP_PKEY_free(pubkey);
- if (x509)
- X509_free(x509);
- return r;
-}
-
-Key **
-sc_get_keys(const char *id, const char *pin)
-{
- Key *k, **keys;
- int i, r, real_count = 0, key_count;
- sc_pkcs15_id_t cert_id;
- sc_pkcs15_object_t *certs[32];
- char *buf = xstrdup(id), *p;
-
- debug("sc_get_keys called: id = %s", id);
-
- if (sc_pin != NULL)
- xfree(sc_pin);
- sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
-
- cert_id.len = 0;
- if ((p = strchr(buf, ':')) != NULL) {
- *p = 0;
- p++;
- sc_pkcs15_hex_string_to_id(p, &cert_id);
- }
- r = sscanf(buf, "%d", &sc_reader_id);
- xfree(buf);
- if (r != 1)
- goto err;
- if (p15card == NULL) {
- sc_close();
- r = sc_init();
- if (r) {
- error("Smartcard init failed: %s", sc_strerror(r));
- goto err;
- }
- }
- if (cert_id.len) {
- r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]);
- if (r < 0)
- goto err;
- key_count = 1;
- } else {
- r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509,
- certs, 32);
- if (r == 0) {
- logit("No certificates found on smartcard");
- r = -1;
- goto err;
- } else if (r < 0) {
- error("Certificate enumeration failed: %s",
- sc_strerror(r));
- goto err;
- }
- key_count = r;
- }
- if (key_count > 1024)
- fatal("Too many keys (%u), expected <= 1024", key_count);
- keys = xcalloc(key_count * 2 + 1, sizeof(Key *));
- for (i = 0; i < key_count; i++) {
- sc_pkcs15_object_t *tmp_obj = NULL;
- cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id;
- if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj))
- /* skip the public key (certificate) if no
- * corresponding private key is present */
- continue;
- k = key_new(KEY_RSA);
- if (k == NULL)
- break;
- r = sc_read_pubkey(k, certs[i]);
- if (r) {
- error("sc_read_pubkey failed: %s", sc_strerror(r));
- key_free(k);
- continue;
- }
- keys[real_count] = k;
- real_count++;
- k = key_new(KEY_RSA1);
- if (k == NULL)
- break;
- convert_rsa_to_rsa1(keys[real_count-1], k);
- keys[real_count] = k;
- real_count++;
- }
- keys[real_count] = NULL;
-
- return keys;
-err:
- sc_close();
- return NULL;
-}
-
-int
-sc_put_key(Key *prv, const char *id)
-{
- error("key uploading not yet supported");
- return -1;
-}
-
-char *
-sc_get_key_label(Key *key)
-{
- int r;
- const struct sc_priv_data *priv;
- struct sc_pkcs15_object *key_obj;
-
- priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa);
- if (priv == NULL || p15card == NULL) {
- logit("SmartCard key not loaded");
- /* internal error => return default label */
- return xstrdup("smartcard key");
- }
- r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
- if (r) {
- logit("Unable to find private key from SmartCard: %s",
- sc_strerror(r));
- return xstrdup("smartcard key");
- }
- if (key_obj == NULL || key_obj->label == NULL)
- /* the optional PKCS#15 label does not exists
- * => return the default label */
- return xstrdup("smartcard key");
- return xstrdup(key_obj->label);
-}
-
-#endif /* SMARTCARD */
diff --git a/crypto/openssh/scard.c b/crypto/openssh/scard.c
deleted file mode 100644
index 9fd3ca1..0000000
--- a/crypto/openssh/scard.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/* $OpenBSD: scard.c,v 1.36 2006/11/06 21:25:28 markus Exp $ */
-/*
- * Copyright (c) 2001 Markus Friedl. 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 ``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 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 "includes.h"
-#if defined(SMARTCARD) && defined(USE_SECTOK)
-
-#include <sys/types.h>
-
-#include <sectok.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include <openssl/evp.h>
-
-#include "xmalloc.h"
-#include "key.h"
-#include "log.h"
-#include "misc.h"
-#include "scard.h"
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-#define USE_ENGINE
-#define RSA_get_default_method RSA_get_default_openssl_method
-#else
-#endif
-
-#ifdef USE_ENGINE
-#include <openssl/engine.h>
-#define sc_get_rsa sc_get_engine
-#else
-#define sc_get_rsa sc_get_rsa_method
-#endif
-
-#define CLA_SSH 0x05
-#define INS_DECRYPT 0x10
-#define INS_GET_KEYLENGTH 0x20
-#define INS_GET_PUBKEY 0x30
-#define INS_GET_RESPONSE 0xc0
-
-#define MAX_BUF_SIZE 256
-
-u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
-
-static int sc_fd = -1;
-static char *sc_reader_id = NULL;
-static char *sc_pin = NULL;
-static int cla = 0x00; /* class */
-
-static void sc_mk_digest(const char *pin, u_char *digest);
-static int get_AUT0(u_char *aut0);
-static int try_AUT0(void);
-
-/* interface to libsectok */
-
-static int
-sc_open(void)
-{
- int sw;
-
- if (sc_fd >= 0)
- return sc_fd;
-
- sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
- if (sc_fd < 0) {
- error("sectok_open failed: %s", sectok_get_sw(sw));
- return SCARD_ERROR_FAIL;
- }
- if (! sectok_cardpresent(sc_fd)) {
- debug("smartcard in reader %s not present, skipping",
- sc_reader_id);
- sc_close();
- return SCARD_ERROR_NOCARD;
- }
- if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
- error("sectok_reset failed: %s", sectok_get_sw(sw));
- sc_fd = -1;
- return SCARD_ERROR_FAIL;
- }
- if ((cla = cyberflex_inq_class(sc_fd)) < 0)
- cla = 0;
-
- debug("sc_open ok %d", sc_fd);
- return sc_fd;
-}
-
-static int
-sc_enable_applet(void)
-{
- static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
- int sw = 0;
-
- /* select applet id */
- sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
- if (!sectok_swOK(sw)) {
- error("sectok_apdu failed: %s", sectok_get_sw(sw));
- sc_close();
- return -1;
- }
- return 0;
-}
-
-static int
-sc_init(void)
-{
- int status;
-
- status = sc_open();
- if (status == SCARD_ERROR_NOCARD) {
- return SCARD_ERROR_NOCARD;
- }
- if (status < 0) {
- error("sc_open failed");
- return status;
- }
- if (sc_enable_applet() < 0) {
- error("sc_enable_applet failed");
- return SCARD_ERROR_APPLET;
- }
- return 0;
-}
-
-static int
-sc_read_pubkey(Key * k)
-{
- u_char buf[2], *n;
- char *p;
- int len, sw, status = -1;
-
- len = sw = 0;
- n = NULL;
-
- if (sc_fd < 0) {
- if (sc_init() < 0)
- goto err;
- }
-
- /* get key size */
- sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
- sizeof(buf), buf, &sw);
- if (!sectok_swOK(sw)) {
- error("could not obtain key length: %s", sectok_get_sw(sw));
- goto err;
- }
- len = (buf[0] << 8) | buf[1];
- len /= 8;
- debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
-
- n = xmalloc(len);
- /* get n */
- sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
-
- if (sw == 0x6982) {
- if (try_AUT0() < 0)
- goto err;
- sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
- }
- if (!sectok_swOK(sw)) {
- error("could not obtain public key: %s", sectok_get_sw(sw));
- goto err;
- }
-
- debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
-
- if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
- error("c_read_pubkey: BN_bin2bn failed");
- goto err;
- }
-
- /* currently the java applet just stores 'n' */
- if (!BN_set_word(k->rsa->e, 35)) {
- error("c_read_pubkey: BN_set_word(e, 35) failed");
- goto err;
- }
-
- status = 0;
- p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
- debug("fingerprint %u %s", key_size(k), p);
- xfree(p);
-
-err:
- if (n != NULL)
- xfree(n);
- sc_close();
- return status;
-}
-
-/* private key operations */
-
-static int
-sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
- int padding)
-{
- u_char *padded = NULL;
- int sw, len, olen, status = -1;
-
- debug("sc_private_decrypt called");
-
- olen = len = sw = 0;
- if (sc_fd < 0) {
- status = sc_init();
- if (status < 0)
- goto err;
- }
- if (padding != RSA_PKCS1_PADDING)
- goto err;
-
- len = BN_num_bytes(rsa->n);
- padded = xmalloc(len);
-
- sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
-
- if (sw == 0x6982) {
- if (try_AUT0() < 0)
- goto err;
- sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
- }
- if (!sectok_swOK(sw)) {
- error("sc_private_decrypt: INS_DECRYPT failed: %s",
- sectok_get_sw(sw));
- goto err;
- }
- olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
- len);
-err:
- if (padded)
- xfree(padded);
- sc_close();
- return (olen >= 0 ? olen : status);
-}
-
-static int
-sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
- int padding)
-{
- u_char *padded = NULL;
- int sw, len, status = -1;
-
- len = sw = 0;
- if (sc_fd < 0) {
- status = sc_init();
- if (status < 0)
- goto err;
- }
- if (padding != RSA_PKCS1_PADDING)
- goto err;
-
- debug("sc_private_encrypt called");
- len = BN_num_bytes(rsa->n);
- padded = xmalloc(len);
-
- if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
- error("RSA_padding_add_PKCS1_type_1 failed");
- goto err;
- }
- sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
- if (sw == 0x6982) {
- if (try_AUT0() < 0)
- goto err;
- sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
- }
- if (!sectok_swOK(sw)) {
- error("sc_private_encrypt: INS_DECRYPT failed: %s",
- sectok_get_sw(sw));
- goto err;
- }
-err:
- if (padded)
- xfree(padded);
- sc_close();
- return (len >= 0 ? len : status);
-}
-
-/* called on free */
-
-static int (*orig_finish)(RSA *rsa) = NULL;
-
-static int
-sc_finish(RSA *rsa)
-{
- if (orig_finish)
- orig_finish(rsa);
- sc_close();
- return 1;
-}
-
-/* engine for overloading private key operations */
-
-static RSA_METHOD *
-sc_get_rsa_method(void)
-{
- static RSA_METHOD smart_rsa;
- const RSA_METHOD *def = RSA_get_default_method();
-
- /* use the OpenSSL version */
- memcpy(&smart_rsa, def, sizeof(smart_rsa));
-
- smart_rsa.name = "sectok";
-
- /* overload */
- smart_rsa.rsa_priv_enc = sc_private_encrypt;
- smart_rsa.rsa_priv_dec = sc_private_decrypt;
-
- /* save original */
- orig_finish = def->finish;
- smart_rsa.finish = sc_finish;
-
- return &smart_rsa;
-}
-
-#ifdef USE_ENGINE
-static ENGINE *
-sc_get_engine(void)
-{
- static ENGINE *smart_engine = NULL;
-
- if ((smart_engine = ENGINE_new()) == NULL)
- fatal("ENGINE_new failed");
-
- ENGINE_set_id(smart_engine, "sectok");
- ENGINE_set_name(smart_engine, "libsectok");
-
- ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
- ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
- ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
- ENGINE_set_RAND(smart_engine, RAND_SSLeay());
- ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
-
- return smart_engine;
-}
-#endif
-
-void
-sc_close(void)
-{
- if (sc_fd >= 0) {
- sectok_close(sc_fd);
- sc_fd = -1;
- }
-}
-
-Key **
-sc_get_keys(const char *id, const char *pin)
-{
- Key *k, *n, **keys;
- int status, nkeys = 2;
-
- if (sc_reader_id != NULL)
- xfree(sc_reader_id);
- sc_reader_id = xstrdup(id);
-
- if (sc_pin != NULL)
- xfree(sc_pin);
- sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
-
- k = key_new(KEY_RSA);
- if (k == NULL) {
- return NULL;
- }
- status = sc_read_pubkey(k);
- if (status == SCARD_ERROR_NOCARD) {
- key_free(k);
- return NULL;
- }
- if (status < 0) {
- error("sc_read_pubkey failed");
- key_free(k);
- return NULL;
- }
- keys = xcalloc((nkeys+1), sizeof(Key *));
-
- n = key_new(KEY_RSA1);
- if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
- (BN_copy(n->rsa->e, k->rsa->e) == NULL))
- fatal("sc_get_keys: BN_copy failed");
- RSA_set_method(n->rsa, sc_get_rsa());
- n->flags |= KEY_FLAG_EXT;
- keys[0] = n;
-
- n = key_new(KEY_RSA);
- if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
- (BN_copy(n->rsa->e, k->rsa->e) == NULL))
- fatal("sc_get_keys: BN_copy failed");
- RSA_set_method(n->rsa, sc_get_rsa());
- n->flags |= KEY_FLAG_EXT;
- keys[1] = n;
-
- keys[2] = NULL;
-
- key_free(k);
- return keys;
-}
-
-#define NUM_RSA_KEY_ELEMENTS 5+1
-#define COPY_RSA_KEY(x, i) \
- do { \
- len = BN_num_bytes(prv->rsa->x); \
- elements[i] = xmalloc(len); \
- debug("#bytes %d", len); \
- if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
- goto done; \
- } while (0)
-
-static void
-sc_mk_digest(const char *pin, u_char *digest)
-{
- const EVP_MD *evp_md = EVP_sha1();
- EVP_MD_CTX md;
-
- EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, pin, strlen(pin));
- EVP_DigestFinal(&md, digest, NULL);
-}
-
-static int
-get_AUT0(u_char *aut0)
-{
- char *pass;
-
- pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
- if (pass == NULL)
- return -1;
- if (!strcmp(pass, "-")) {
- memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
- return 0;
- }
- sc_mk_digest(pass, aut0);
- memset(pass, 0, strlen(pass));
- xfree(pass);
- return 0;
-}
-
-static int
-try_AUT0(void)
-{
- u_char aut0[EVP_MAX_MD_SIZE];
-
- /* permission denied; try PIN if provided */
- if (sc_pin && strlen(sc_pin) > 0) {
- sc_mk_digest(sc_pin, aut0);
- if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
- error("smartcard passphrase incorrect");
- return (-1);
- }
- } else {
- /* try default AUT0 key */
- if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
- /* default AUT0 key failed; prompt for passphrase */
- if (get_AUT0(aut0) < 0 ||
- cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
- error("smartcard passphrase incorrect");
- return (-1);
- }
- }
- }
- return (0);
-}
-
-int
-sc_put_key(Key *prv, const char *id)
-{
- u_char *elements[NUM_RSA_KEY_ELEMENTS];
- u_char key_fid[2];
- u_char AUT0[EVP_MAX_MD_SIZE];
- int len, status = -1, i, fd = -1, ret;
- int sw = 0, cla = 0x00;
-
- for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
- elements[i] = NULL;
-
- COPY_RSA_KEY(q, 0);
- COPY_RSA_KEY(p, 1);
- COPY_RSA_KEY(iqmp, 2);
- COPY_RSA_KEY(dmq1, 3);
- COPY_RSA_KEY(dmp1, 4);
- COPY_RSA_KEY(n, 5);
- len = BN_num_bytes(prv->rsa->n);
- fd = sectok_friendly_open(id, STONOWAIT, &sw);
- if (fd < 0) {
- error("sectok_open failed: %s", sectok_get_sw(sw));
- goto done;
- }
- if (! sectok_cardpresent(fd)) {
- error("smartcard in reader %s not present", id);
- goto done;
- }
- ret = sectok_reset(fd, 0, NULL, &sw);
- if (ret <= 0) {
- error("sectok_reset failed: %s", sectok_get_sw(sw));
- goto done;
- }
- if ((cla = cyberflex_inq_class(fd)) < 0) {
- error("cyberflex_inq_class failed");
- goto done;
- }
- memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
- if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
- if (get_AUT0(AUT0) < 0 ||
- cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
- memset(AUT0, 0, sizeof(DEFAUT0));
- error("smartcard passphrase incorrect");
- goto done;
- }
- }
- memset(AUT0, 0, sizeof(DEFAUT0));
- key_fid[0] = 0x00;
- key_fid[1] = 0x12;
- if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
- &sw) < 0) {
- error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
- goto done;
- }
- if (!sectok_swOK(sw))
- goto done;
- logit("cyberflex_load_rsa_priv done");
- key_fid[0] = 0x73;
- key_fid[1] = 0x68;
- if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
- &sw) < 0) {
- error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
- goto done;
- }
- if (!sectok_swOK(sw))
- goto done;
- logit("cyberflex_load_rsa_pub done");
- status = 0;
-
-done:
- memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
- memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
- memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
- memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
- memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
- memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
-
- for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
- if (elements[i])
- xfree(elements[i]);
- if (fd != -1)
- sectok_close(fd);
- return (status);
-}
-
-char *
-sc_get_key_label(Key *key)
-{
- return xstrdup("smartcard key");
-}
-
-#endif /* SMARTCARD && USE_SECTOK */
diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1
index 611beea..615520b 100644
--- a/crypto/openssh/scp.1
+++ b/crypto/openssh/scp.1
@@ -9,9 +9,9 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
-.\" $OpenBSD: scp.1,v 1.46 2008/07/12 05:33:41 djm Exp $
+.\" $OpenBSD: scp.1,v 1.50 2010/02/08 10:50:20 markus Exp $
.\"
-.Dd July 12 2008
+.Dd February 8 2010
.Dt SCP 1
.Os
.Sh NAME
@@ -153,6 +153,7 @@ For full details of the options listed below, and their possible values, see
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
+.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It Protocol
@@ -164,7 +165,6 @@ For full details of the options listed below, and their possible values, see
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
-.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive
.It UsePrivilegedPort
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
index 3237478..09efb82 100644
--- a/crypto/openssh/scp.c
+++ b/crypto/openssh/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.164 2008/10/10 04:55:16 stevesk Exp $ */
+/* $OpenBSD: scp.c,v 1.165 2009/12/20 07:28:36 guenther Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@@ -244,8 +244,11 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
close(pout[1]);
replacearg(&args, 0, "%s", ssh_program);
- if (remuser != NULL)
- addargs(&args, "-l%s", remuser);
+ if (remuser != NULL) {
+ addargs(&args, "-l");
+ addargs(&args, "%s", remuser);
+ }
+ addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", cmd);
@@ -337,10 +340,12 @@ main(int argc, char **argv)
case 'c':
case 'i':
case 'F':
- addargs(&args, "-%c%s", ch, optarg);
+ addargs(&args, "-%c", ch);
+ addargs(&args, "%s", optarg);
break;
case 'P':
- addargs(&args, "-p%s", optarg);
+ addargs(&args, "-p");
+ addargs(&args, "%s", optarg);
break;
case 'B':
addargs(&args, "-oBatchmode yes");
@@ -548,6 +553,7 @@ toremote(char *targ, int argc, char **argv)
} else {
host = cleanhostname(argv[i]);
}
+ addargs(&alist, "--");
addargs(&alist, "%s", host);
addargs(&alist, "%s", cmd);
addargs(&alist, "%s", src);
@@ -558,7 +564,7 @@ toremote(char *targ, int argc, char **argv)
errs = 1;
} else { /* local to remote */
if (remin == -1) {
- xasprintf(&bp, "%s -t %s", cmd, targ);
+ xasprintf(&bp, "%s -t -- %s", cmd, targ);
host = cleanhostname(thost);
if (do_cmd(host, tuser, bp, &remin,
&remout) < 0)
@@ -591,6 +597,7 @@ tolocal(int argc, char **argv)
addargs(&alist, "-r");
if (pflag)
addargs(&alist, "-p");
+ addargs(&alist, "--");
addargs(&alist, "%s", argv[i]);
addargs(&alist, "%s", argv[argc-1]);
if (do_local_cmd(&alist))
@@ -610,7 +617,7 @@ tolocal(int argc, char **argv)
suser = pwd->pw_name;
}
host = cleanhostname(host);
- xasprintf(&bp, "%s -f %s", cmd, src);
+ xasprintf(&bp, "%s -f -- %s", cmd, src);
if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
(void) xfree(bp);
++errs;
diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
index ad25fef..603c586 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.195 2009/04/14 21:10:54 jj Exp $ */
+/* $OpenBSD: servconf.c,v 1.204 2010/03/04 10:36:03 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -42,6 +42,7 @@ __RCSID("$FreeBSD$");
#include "match.h"
#include "channels.h"
#include "groupaccess.h"
+#include "version.h"
static void add_listen_addr(ServerOptions *, char *, int);
static void add_one_listen_addr(ServerOptions *, char *, int);
@@ -66,6 +67,7 @@ initialize_server_options(ServerOptions *options)
options->listen_addrs = NULL;
options->address_family = -1;
options->num_host_key_files = 0;
+ options->num_host_cert_files = 0;
options->pid_file = NULL;
options->server_key_bits = -1;
options->login_grace_time = -1;
@@ -129,6 +131,8 @@ initialize_server_options(ServerOptions *options)
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
options->zero_knowledge_password_authentication = -1;
+ options->revoked_keys_file = NULL;
+ options->trusted_user_ca_keys = NULL;
}
void
@@ -153,6 +157,7 @@ fill_default_server_options(ServerOptions *options)
_PATH_HOST_DSA_KEY_FILE;
}
}
+ /* No certificates by default */
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->listen_addrs == NULL)
@@ -306,7 +311,8 @@ typedef enum {
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
- sZeroKnowledgePasswordAuthentication,
+ sZeroKnowledgePasswordAuthentication, sHostCertificate,
+ sRevokedKeys, sTrustedUserCAKeys,
sVersionAddendum,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -426,6 +432,9 @@ static struct {
{ "permitopen", sPermitOpen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
+ { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
+ { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
+ { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@@ -462,6 +471,22 @@ parse_token(const char *cp, const char *filename,
return sBadOption;
}
+char *
+derelativise_path(const char *path)
+{
+ char *expanded, *ret, *cwd;
+
+ expanded = tilde_expand_filename(path, getuid());
+ if (*expanded == '/')
+ return expanded;
+ if ((cwd = getcwd(NULL, 0)) == NULL)
+ fatal("%s: getcwd: %s", __func__, strerror(errno));
+ xasprintf(&ret, "%s/%s", cwd, expanded);
+ xfree(cwd);
+ xfree(expanded);
+ return ret;
+}
+
static void
add_listen_addr(ServerOptions *options, char *addr, int port)
{
@@ -796,13 +821,23 @@ process_server_config_line(ServerOptions *options, char *line,
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep && *charptr == NULL) {
- *charptr = tilde_expand_filename(arg, getuid());
+ *charptr = derelativise_path(arg);
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
+ case sHostCertificate:
+ intptr = &options->num_host_cert_files;
+ if (*intptr >= MAX_HOSTKEYS)
+ fatal("%s line %d: too many host certificates "
+ "specified (max %d).", filename, linenum,
+ MAX_HOSTCERTS);
+ charptr = &options->host_cert_files[*intptr];
+ goto parse_filename;
+ break;
+
case sPidFile:
charptr = &options->pid_file;
goto parse_filename;
@@ -1297,6 +1332,14 @@ process_server_config_line(ServerOptions *options, char *line,
*charptr = xstrdup(arg);
break;
+ case sTrustedUserCAKeys:
+ charptr = &options->trusted_user_ca_keys;
+ goto parse_filename;
+
+ case sRevokedKeys:
+ charptr = &options->revoked_keys_file;
+ goto parse_filename;
+
case sVersionAddendum:
ssh_version_set_addendum(strtok(cp, "\n"));
do {
@@ -1418,6 +1461,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
return;
M_CP_STROPT(adm_forced_command);
M_CP_STROPT(chroot_directory);
+ M_CP_STROPT(trusted_user_ca_keys);
+ M_CP_STROPT(revoked_keys_file);
}
#undef M_CP_INTOPT
@@ -1636,6 +1681,9 @@ dump_config(ServerOptions *o)
dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
dump_cfg_string(sForceCommand, o->adm_forced_command);
+ dump_cfg_string(sChrootDirectory, o->chroot_directory);
+ dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
+ dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
@@ -1644,6 +1692,8 @@ dump_config(ServerOptions *o)
/* string array arguments */
dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
o->host_key_files);
+ dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
+ o->host_cert_files);
dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
index b3ac7da..860009f 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.87 2009/01/22 10:02:34 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.92 2010/03/04 10:36:03 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -24,6 +24,7 @@
#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */
#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
#define MAX_HOSTKEYS 256 /* Max # hostkeys. */
+#define MAX_HOSTCERTS 256 /* Max # host certificates. */
#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */
#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */
@@ -49,6 +50,8 @@ typedef struct {
int address_family; /* Address family used by the server. */
char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */
int num_host_key_files; /* Number of files for host keys. */
+ char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */
+ int num_host_cert_files; /* Number of files for host certs. */
char *pid_file; /* Where to put our pid */
int server_key_bits;/* Size of the server key. */
int login_grace_time; /* Disconnect if no auth in this time
@@ -151,6 +154,8 @@ typedef struct {
int num_permitted_opens;
char *chroot_directory;
+ char *revoked_keys_file;
+ char *trusted_user_ca_keys;
} ServerOptions;
void initialize_server_options(ServerOptions *);
@@ -164,5 +169,6 @@ void parse_server_match_config(ServerOptions *, const char *, const char *,
const char *);
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
void dump_config(ServerOptions *);
+char *derelativise_path(const char *);
#endif /* SERVCONF_H */
diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c
index 51cca49..aad0979 100644
--- a/crypto/openssh/session.c
+++ b/crypto/openssh/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.246 2009/04/17 19:23:06 stevesk Exp $ */
+/* $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -143,9 +143,10 @@ static int sessions_first_unused = -1;
static int sessions_nalloc = 0;
static Session *sessions = NULL;
-#define SUBSYSTEM_NONE 0
-#define SUBSYSTEM_EXT 1
-#define SUBSYSTEM_INT_SFTP 2
+#define SUBSYSTEM_NONE 0
+#define SUBSYSTEM_EXT 1
+#define SUBSYSTEM_INT_SFTP 2
+#define SUBSYSTEM_INT_SFTP_ERROR 3
#ifdef HAVE_LOGIN_CAP
login_cap_t *lc;
@@ -271,6 +272,8 @@ do_authenticated(Authctxt *authctxt)
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
channel_permit_all_opens();
+ auth_debug_send();
+
if (compat20)
do_authenticated2(authctxt);
else
@@ -786,17 +789,19 @@ do_exec(Session *s, const char *command)
if (options.adm_forced_command) {
original_command = command;
command = options.adm_forced_command;
- if (IS_INTERNAL_SFTP(command))
- s->is_subsystem = SUBSYSTEM_INT_SFTP;
- else if (s->is_subsystem)
+ if (IS_INTERNAL_SFTP(command)) {
+ s->is_subsystem = s->is_subsystem ?
+ SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
+ } else if (s->is_subsystem)
s->is_subsystem = SUBSYSTEM_EXT;
debug("Forced command (config) '%.900s'", command);
} else if (forced_command) {
original_command = command;
command = forced_command;
- if (IS_INTERNAL_SFTP(command))
- s->is_subsystem = SUBSYSTEM_INT_SFTP;
- else if (s->is_subsystem)
+ if (IS_INTERNAL_SFTP(command)) {
+ s->is_subsystem = s->is_subsystem ?
+ SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
+ } else if (s->is_subsystem)
s->is_subsystem = SUBSYSTEM_EXT;
debug("Forced command (key option) '%.900s'", command);
}
@@ -1404,26 +1409,32 @@ static void
do_nologin(struct passwd *pw)
{
FILE *f = NULL;
- char buf[1024];
+ char buf[1024], *nl, *def_nl = _PATH_NOLOGIN;
+ struct stat sb;
#ifdef HAVE_LOGIN_CAP
- if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
- f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
- _PATH_NOLOGIN), "r");
+ if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
+ return;
+ nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
#else
- if (pw->pw_uid)
- f = fopen(_PATH_NOLOGIN, "r");
+ if (pw->pw_uid == 0)
+ return;
+ nl = def_nl;
#endif
- if (f) {
- /* /etc/nologin exists. Print its contents and exit. */
- logit("User %.100s not allowed because %s exists",
- pw->pw_name, _PATH_NOLOGIN);
- while (fgets(buf, sizeof(buf), f))
- fputs(buf, stderr);
- fclose(f);
- fflush(NULL);
- exit(254);
+ if (stat(nl, &sb) == -1) {
+ if (nl != def_nl)
+ xfree(nl);
+ return;
}
+
+ /* /etc/nologin exists. Print its contents if we can and exit. */
+ logit("User %.100s not allowed because %s exists", pw->pw_name, nl);
+ if ((f = fopen(nl, "r")) != NULL) {
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stderr);
+ fclose(f);
+ }
+ exit(254);
}
/*
@@ -1551,6 +1562,24 @@ do_setusercontext(struct passwd *pw)
}
# endif /* USE_LIBIAF */
#endif
+#ifdef HAVE_SETPCRED
+ /*
+ * If we have a chroot directory, we set all creds except real
+ * uid which we will need for chroot. If we don't have a
+ * chroot directory, we don't override anything.
+ */
+ {
+ char **creds = NULL, *chroot_creds[] =
+ { "REAL_USER=root", NULL };
+
+ if (options.chroot_directory != NULL &&
+ strcasecmp(options.chroot_directory, "none") != 0)
+ creds = chroot_creds;
+
+ if (setpcred(pw->pw_name, creds) == -1)
+ fatal("Failed to set process credentials");
+ }
+#endif /* HAVE_SETPCRED */
if (options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) {
@@ -1563,10 +1592,6 @@ do_setusercontext(struct passwd *pw)
free(chroot_path);
}
-#ifdef HAVE_SETPCRED
- if (setpcred(pw->pw_name, (char **)NULL) == -1)
- fatal("Failed to set process credentials");
-#endif /* HAVE_SETPCRED */
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
perror("unable to set user context (setuser)");
@@ -1813,7 +1838,11 @@ do_child(Session *s, const char *command)
/* restore SIGPIPE for child */
signal(SIGPIPE, SIG_DFL);
- if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
+ if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
+ printf("This service allows sftp connections only.\n");
+ fflush(NULL);
+ exit(1);
+ } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
extern int optind, optreset;
int i;
char *p, *args;
@@ -1826,9 +1855,14 @@ do_child(Session *s, const char *command)
argv[i] = NULL;
optind = optreset = 1;
__progname = argv[0];
+#ifdef WITH_SELINUX
+ ssh_selinux_change_context("sftpd_t");
+#endif
exit(sftp_server_main(i, argv, s->pw));
}
+ fflush(NULL);
+
if (options.use_login) {
launch_login(pw, hostname);
/* NEVERREACHED */
@@ -2139,16 +2173,16 @@ session_subsystem_req(Session *s)
if (strcmp(subsys, options.subsystem_name[i]) == 0) {
prog = options.subsystem_command[i];
cmd = options.subsystem_args[i];
- if (!strcmp(INTERNAL_SFTP_NAME, prog)) {
+ if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) {
s->is_subsystem = SUBSYSTEM_INT_SFTP;
- } else if (stat(prog, &st) < 0) {
- error("subsystem: cannot stat %s: %s", prog,
- strerror(errno));
- break;
+ debug("subsystem: %s", prog);
} else {
+ if (stat(prog, &st) < 0)
+ debug("subsystem: cannot stat %s: %s",
+ prog, strerror(errno));
s->is_subsystem = SUBSYSTEM_EXT;
+ debug("subsystem: exec() %s", cmd);
}
- debug("subsystem: exec() %s", cmd);
success = do_exec(s, cmd) == 0;
break;
}
diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c
index 0990b79..6124c0f 100644
--- a/crypto/openssh/sftp-client.c
+++ b/crypto/openssh/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.87 2009/06/22 05:39:28 dtucker Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.90 2009/10/11 10:41:26 dtucker Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -36,6 +36,7 @@
#endif
#include <sys/uio.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
@@ -61,6 +62,9 @@ extern int showprogress;
/* Minimum amount of data to read at a time */
#define MIN_READ_SIZE 512
+/* Maximum depth to descend in directory trees */
+#define MAX_DIR_DEPTH 64
+
struct sftp_conn {
int fd_in;
int fd_out;
@@ -74,6 +78,10 @@ struct sftp_conn {
u_int exts;
};
+static char *
+get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
+ __attribute__((format(printf, 4, 5)));
+
static void
send_msg(int fd, Buffer *m)
{
@@ -179,11 +187,18 @@ get_status(int fd, u_int expected_id)
}
static char *
-get_handle(int fd, u_int expected_id, u_int *len)
+get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
{
Buffer msg;
u_int type, id;
- char *handle;
+ char *handle, errmsg[256];
+ va_list args;
+ int status;
+
+ va_start(args, errfmt);
+ if (errfmt != NULL)
+ vsnprintf(errmsg, sizeof(errmsg), errfmt, args);
+ va_end(args);
buffer_init(&msg);
get_msg(fd, &msg);
@@ -191,16 +206,17 @@ get_handle(int fd, u_int expected_id, u_int *len)
id = buffer_get_int(&msg);
if (id != expected_id)
- fatal("ID mismatch (%u != %u)", id, expected_id);
+ fatal("%s: ID mismatch (%u != %u)",
+ errfmt == NULL ? __func__ : errmsg, id, expected_id);
if (type == SSH2_FXP_STATUS) {
- int status = buffer_get_int(&msg);
-
- error("Couldn't get handle: %s", fx2txt(status));
+ status = buffer_get_int(&msg);
+ if (errfmt != NULL)
+ error("%s: %s", errmsg, fx2txt(status));
buffer_free(&msg);
return(NULL);
} else if (type != SSH2_FXP_HANDLE)
- fatal("Expected SSH2_FXP_HANDLE(%u) packet, got %u",
- SSH2_FXP_HANDLE, type);
+ fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u",
+ errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type);
handle = buffer_get_string(&msg, len);
buffer_free(&msg);
@@ -418,7 +434,8 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
buffer_clear(&msg);
- handle = get_handle(conn->fd_in, id, &handle_len);
+ handle = get_handle(conn->fd_in, id, &handle_len,
+ "remote readdir(\"%s\")", path);
if (handle == NULL)
return(-1);
@@ -484,6 +501,17 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
if (printflag)
printf("%s\n", longname);
+ /*
+ * Directory entries should never contain '/'
+ * These can be used to attack recursive ops
+ * (e.g. send '../../../../etc/passwd')
+ */
+ if (strchr(filename, '/') != NULL) {
+ error("Server sent suspect path \"%s\" "
+ "during readdir of \"%s\"", filename, path);
+ goto next;
+ }
+
if (dir) {
*dir = xrealloc(*dir, ents + 2, sizeof(**dir));
(*dir)[ents] = xmalloc(sizeof(***dir));
@@ -492,7 +520,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
memcpy(&(*dir)[ents]->a, a, sizeof(*a));
(*dir)[++ents] = NULL;
}
-
+ next:
xfree(filename);
xfree(longname);
}
@@ -547,7 +575,7 @@ do_rm(struct sftp_conn *conn, char *path)
}
int
-do_mkdir(struct sftp_conn *conn, char *path, Attrib *a)
+do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag)
{
u_int status, id;
@@ -556,7 +584,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a)
strlen(path), a);
status = get_status(conn->fd_in, id);
- if (status != SSH2_FX_OK)
+ if (status != SSH2_FX_OK && printflag)
error("Couldn't create directory: %s", fx2txt(status));
return(status);
@@ -895,9 +923,9 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
int
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
- int pflag)
+ Attrib *a, int pflag)
{
- Attrib junk, *a;
+ Attrib junk;
Buffer msg;
char *handle;
int local_fd, status = 0, write_error;
@@ -916,9 +944,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
TAILQ_INIT(&requests);
- a = do_stat(conn, remote_path, 0);
- if (a == NULL)
- return(-1);
+ if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
+ return -1;
/* Do not preserve set[ug]id here, as we do not preserve ownership */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
@@ -951,7 +978,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
- handle = get_handle(conn->fd_in, id, &handle_len);
+ handle = get_handle(conn->fd_in, id, &handle_len,
+ "remote open(\"%s\")", remote_path);
if (handle == NULL) {
buffer_free(&msg);
return(-1);
@@ -1132,6 +1160,114 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
return(status);
}
+static int
+download_dir_internal(struct sftp_conn *conn, char *src, char *dst,
+ Attrib *dirattrib, int pflag, int printflag, int depth)
+{
+ int i, ret = 0;
+ SFTP_DIRENT **dir_entries;
+ char *filename, *new_src, *new_dst;
+ mode_t mode = 0777;
+
+ if (depth >= MAX_DIR_DEPTH) {
+ error("Maximum directory depth exceeded: %d levels", depth);
+ return -1;
+ }
+
+ if (dirattrib == NULL &&
+ (dirattrib = do_stat(conn, src, 1)) == NULL) {
+ error("Unable to stat remote directory \"%s\"", src);
+ return -1;
+ }
+ if (!S_ISDIR(dirattrib->perm)) {
+ error("\"%s\" is not a directory", src);
+ return -1;
+ }
+ if (printflag)
+ printf("Retrieving %s\n", src);
+
+ if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
+ mode = dirattrib->perm & 01777;
+ else {
+ debug("Server did not send permissions for "
+ "directory \"%s\"", dst);
+ }
+
+ if (mkdir(dst, mode) == -1 && errno != EEXIST) {
+ error("mkdir %s: %s", dst, strerror(errno));
+ return -1;
+ }
+
+ if (do_readdir(conn, src, &dir_entries) == -1) {
+ error("%s: Failed to get directory contents", src);
+ return -1;
+ }
+
+ for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
+ filename = dir_entries[i]->filename;
+
+ new_dst = path_append(dst, filename);
+ new_src = path_append(src, filename);
+
+ if (S_ISDIR(dir_entries[i]->a.perm)) {
+ if (strcmp(filename, ".") == 0 ||
+ strcmp(filename, "..") == 0)
+ continue;
+ if (download_dir_internal(conn, new_src, new_dst,
+ &(dir_entries[i]->a), pflag, printflag,
+ depth + 1) == -1)
+ ret = -1;
+ } else if (S_ISREG(dir_entries[i]->a.perm) ) {
+ if (do_download(conn, new_src, new_dst,
+ &(dir_entries[i]->a), pflag) == -1) {
+ error("Download of file %s to %s failed",
+ new_src, new_dst);
+ ret = -1;
+ }
+ } else
+ logit("%s: not a regular file\n", new_src);
+
+ xfree(new_dst);
+ xfree(new_src);
+ }
+
+ if (pflag) {
+ if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
+ struct timeval tv[2];
+ tv[0].tv_sec = dirattrib->atime;
+ tv[1].tv_sec = dirattrib->mtime;
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+ if (utimes(dst, tv) == -1)
+ error("Can't set times on \"%s\": %s",
+ dst, strerror(errno));
+ } else
+ debug("Server did not send times for directory "
+ "\"%s\"", dst);
+ }
+
+ free_sftp_dirents(dir_entries);
+
+ return ret;
+}
+
+int
+download_dir(struct sftp_conn *conn, char *src, char *dst,
+ Attrib *dirattrib, int pflag, int printflag)
+{
+ char *src_canon;
+ int ret;
+
+ if ((src_canon = do_realpath(conn, src)) == NULL) {
+ error("Unable to canonicalise path \"%s\"", src);
+ return -1;
+ }
+
+ ret = download_dir_internal(conn, src_canon, dst,
+ dirattrib, pflag, printflag, 0);
+ xfree(src_canon);
+ return ret;
+}
+
int
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
int pflag)
@@ -1195,7 +1331,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
buffer_clear(&msg);
- handle = get_handle(conn->fd_in, id, &handle_len);
+ handle = get_handle(conn->fd_in, id, &handle_len,
+ "remote open(\"%s\")", remote_path);
if (handle == NULL) {
close(local_fd);
buffer_free(&msg);
@@ -1313,3 +1450,127 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
return status;
}
+
+static int
+upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
+ int pflag, int printflag, int depth)
+{
+ int ret = 0, status;
+ DIR *dirp;
+ struct dirent *dp;
+ char *filename, *new_src, *new_dst;
+ struct stat sb;
+ Attrib a;
+
+ if (depth >= MAX_DIR_DEPTH) {
+ error("Maximum directory depth exceeded: %d levels", depth);
+ return -1;
+ }
+
+ if (stat(src, &sb) == -1) {
+ error("Couldn't stat directory \"%s\": %s",
+ src, strerror(errno));
+ return -1;
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ error("\"%s\" is not a directory", src);
+ return -1;
+ }
+ if (printflag)
+ printf("Entering %s\n", src);
+
+ attrib_clear(&a);
+ stat_to_attrib(&sb, &a);
+ a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
+ a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
+ a.perm &= 01777;
+ if (!pflag)
+ a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
+
+ status = do_mkdir(conn, dst, &a, 0);
+ /*
+ * we lack a portable status for errno EEXIST,
+ * so if we get a SSH2_FX_FAILURE back we must check
+ * if it was created successfully.
+ */
+ if (status != SSH2_FX_OK) {
+ if (status != SSH2_FX_FAILURE)
+ return -1;
+ if (do_stat(conn, dst, 0) == NULL)
+ return -1;
+ }
+
+ if ((dirp = opendir(src)) == NULL) {
+ error("Failed to open dir \"%s\": %s", src, strerror(errno));
+ return -1;
+ }
+
+ while (((dp = readdir(dirp)) != NULL) && !interrupted) {
+ if (dp->d_ino == 0)
+ continue;
+ filename = dp->d_name;
+ new_dst = path_append(dst, filename);
+ new_src = path_append(src, filename);
+
+ if (lstat(new_src, &sb) == -1) {
+ logit("%s: lstat failed: %s", filename,
+ strerror(errno));
+ ret = -1;
+ } else if (S_ISDIR(sb.st_mode)) {
+ if (strcmp(filename, ".") == 0 ||
+ strcmp(filename, "..") == 0)
+ continue;
+
+ if (upload_dir_internal(conn, new_src, new_dst,
+ pflag, depth + 1, printflag) == -1)
+ ret = -1;
+ } else if (S_ISREG(sb.st_mode)) {
+ if (do_upload(conn, new_src, new_dst, pflag) == -1) {
+ error("Uploading of file %s to %s failed!",
+ new_src, new_dst);
+ ret = -1;
+ }
+ } else
+ logit("%s: not a regular file\n", filename);
+ xfree(new_dst);
+ xfree(new_src);
+ }
+
+ do_setstat(conn, dst, &a);
+
+ (void) closedir(dirp);
+ return ret;
+}
+
+int
+upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag,
+ int pflag)
+{
+ char *dst_canon;
+ int ret;
+
+ if ((dst_canon = do_realpath(conn, dst)) == NULL) {
+ error("Unable to canonicalise path \"%s\"", dst);
+ return -1;
+ }
+
+ ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0);
+ xfree(dst_canon);
+ return ret;
+}
+
+char *
+path_append(char *p1, char *p2)
+{
+ char *ret;
+ size_t len = strlen(p1) + strlen(p2) + 2;
+
+ ret = xmalloc(len);
+ strlcpy(ret, p1, len);
+ if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
+ strlcat(ret, "/", len);
+ strlcat(ret, p2, len);
+
+ return(ret);
+}
+
diff --git a/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h
index edb4679..1d08c40 100644
--- a/crypto/openssh/sftp-client.h
+++ b/crypto/openssh/sftp-client.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.h,v 1.17 2008/06/08 20:15:29 dtucker Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.18 2009/08/18 18:36:20 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@@ -68,7 +68,7 @@ void free_sftp_dirents(SFTP_DIRENT **);
int do_rm(struct sftp_conn *, char *);
/* Create directory 'path' */
-int do_mkdir(struct sftp_conn *, char *, Attrib *);
+int do_mkdir(struct sftp_conn *, char *, Attrib *, int);
/* Remove directory 'path' */
int do_rmdir(struct sftp_conn *, char *);
@@ -103,7 +103,13 @@ int do_symlink(struct sftp_conn *, char *, char *);
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(struct sftp_conn *, char *, char *, int);
+int do_download(struct sftp_conn *, char *, char *, Attrib *, int);
+
+/*
+ * Recursively download 'remote_directory' to 'local_directory'. Preserve
+ * times if 'pflag' is set
+ */
+int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
@@ -111,4 +117,13 @@ int do_download(struct sftp_conn *, char *, char *, int);
*/
int do_upload(struct sftp_conn *, char *, char *, int);
+/*
+ * Recursively upload 'local_directory' to 'remote_directory'. Preserve
+ * times if 'pflag' is set
+ */
+int upload_dir(struct sftp_conn *, char *, char *, int, int);
+
+/* Concatenate paths, taking care of slashes. Caller must free result. */
+char *path_append(char *, char *);
+
#endif
diff --git a/crypto/openssh/sftp-common.c b/crypto/openssh/sftp-common.c
index 7ebadcc..a042875 100644
--- a/crypto/openssh/sftp-common.c
+++ b/crypto/openssh/sftp-common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: sftp-common.c,v 1.23 2010/01/15 09:24:23 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Damien Miller. All rights reserved.
@@ -36,6 +36,9 @@
#include <string.h>
#include <time.h>
#include <stdarg.h>
+#ifdef HAVE_UTIL_H
+#include <util.h>
+#endif
#include "xmalloc.h"
#include "buffer.h"
@@ -184,24 +187,23 @@ fx2txt(int status)
* drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh
*/
char *
-ls_file(const char *name, const struct stat *st, int remote)
+ls_file(const char *name, const struct stat *st, int remote, int si_units)
{
int ulen, glen, sz = 0;
- struct passwd *pw;
- struct group *gr;
struct tm *ltime = localtime(&st->st_mtime);
char *user, *group;
char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
+ char sbuf[FMT_SCALED_STRSIZE];
strmode(st->st_mode, mode);
- if (!remote && (pw = getpwuid(st->st_uid)) != NULL) {
- user = pw->pw_name;
+ if (!remote) {
+ user = user_from_uid(st->st_uid, 0);
} else {
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
user = ubuf;
}
- if (!remote && (gr = getgrgid(st->st_gid)) != NULL) {
- group = gr->gr_name;
+ if (!remote) {
+ group = group_from_gid(st->st_gid, 0);
} else {
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
group = gbuf;
@@ -216,8 +218,15 @@ ls_file(const char *name, const struct stat *st, int remote)
tbuf[0] = '\0';
ulen = MAX(strlen(user), 8);
glen = MAX(strlen(group), 8);
- snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
- (u_int)st->st_nlink, ulen, user, glen, group,
- (unsigned long long)st->st_size, tbuf, name);
+ if (si_units) {
+ fmt_scaled((long long)st->st_size, sbuf);
+ snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode,
+ (u_int)st->st_nlink, ulen, user, glen, group,
+ sbuf, tbuf, name);
+ } else {
+ snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
+ (u_int)st->st_nlink, ulen, user, glen, group,
+ (unsigned long long)st->st_size, tbuf, name);
+ }
return xstrdup(buf);
}
diff --git a/crypto/openssh/sftp-common.h b/crypto/openssh/sftp-common.h
index 9b58484..9ed86c0 100644
--- a/crypto/openssh/sftp-common.h
+++ b/crypto/openssh/sftp-common.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-common.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: sftp-common.h,v 1.11 2010/01/13 01:40:16 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -46,6 +46,6 @@ void stat_to_attrib(const struct stat *, Attrib *);
void attrib_to_stat(const Attrib *, struct stat *);
Attrib *decode_attrib(Buffer *);
void encode_attrib(Buffer *, const Attrib *);
-char *ls_file(const char *, const struct stat *, int);
+char *ls_file(const char *, const struct stat *, int, int);
const char *fx2txt(int);
diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8
index 0201d4b..fb0cc6e 100644
--- a/crypto/openssh/sftp-server.8
+++ b/crypto/openssh/sftp-server.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp-server.8,v 1.15 2009/03/26 08:38:39 sobrado Exp $
+.\" $OpenBSD: sftp-server.8,v 1.19 2010/01/09 03:36:00 jmc Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd March 26 2009
+.Dd January 9 2010
.Dt SFTP-SERVER 8
.Os
.Sh NAME
@@ -31,8 +31,10 @@
.Nd SFTP server subsystem
.Sh SYNOPSIS
.Nm sftp-server
+.Op Fl ehR
.Op Fl f Ar log_facility
.Op Fl l Ar log_level
+.Op Fl u Ar umask
.Sh DESCRIPTION
.Nm
is a program that speaks the server side of SFTP protocol
@@ -55,12 +57,20 @@ for more information.
.Pp
Valid options are:
.Bl -tag -width Ds
+.It Fl e
+Causes
+.Nm
+to print logging information to stderr instead of syslog for debugging.
.It Fl f Ar log_facility
Specifies the facility code that is used when logging messages from
.Nm .
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
+.It Fl h
+Displays
+.Nm
+usage information.
.It Fl l Ar log_level
Specifies which messages will be logged by
.Nm .
@@ -72,6 +82,17 @@ performs on behalf of the client.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
The default is ERROR.
+.It Fl R
+Places this instance of
+.Nm
+into a read-only mode.
+Attempts to open files for writing, as well as other operations that change
+the state of the filesystem, will be denied.
+.It Fl u Ar umask
+Sets an explicit
+.Xr umask 2
+to be applied to newly-created files and directories, instead of the
+user's default mask.
.El
.Pp
For logging to work,
diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c
index d984e60..a98ac2b 100644
--- a/crypto/openssh/sftp-server.c
+++ b/crypto/openssh/sftp-server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server.c,v 1.85 2009/04/14 16:33:42 stevesk Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.91 2010/01/13 01:40:16 djm Exp $ */
/*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
*
@@ -70,6 +70,9 @@ Buffer oqueue;
/* Version of client */
int version;
+/* Disable writes */
+int readonly;
+
/* portable attributes, etc. */
typedef struct Stat Stat;
@@ -553,16 +556,21 @@ process_open(void)
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
- fd = open(name, flags, mode);
- if (fd < 0) {
- status = errno_to_portable(errno);
- } else {
- handle = handle_new(HANDLE_FILE, name, fd, NULL);
- if (handle < 0) {
- close(fd);
+ if (readonly &&
+ ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR))
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
+ fd = open(name, flags, mode);
+ if (fd < 0) {
+ status = errno_to_portable(errno);
} else {
- send_handle(id, handle);
- status = SSH2_FX_OK;
+ handle = handle_new(HANDLE_FILE, name, fd, NULL);
+ if (handle < 0) {
+ close(fd);
+ } else {
+ send_handle(id, handle);
+ status = SSH2_FX_OK;
+ }
}
}
if (status != SSH2_FX_OK)
@@ -632,7 +640,7 @@ process_write(void)
u_int32_t id;
u_int64_t off;
u_int len;
- int handle, fd, ret, status = SSH2_FX_FAILURE;
+ int handle, fd, ret, status;
char *data;
id = get_int();
@@ -643,7 +651,12 @@ process_write(void)
debug("request %u: write \"%s\" (handle %d) off %llu len %d",
id, handle_to_name(handle), handle, (unsigned long long)off, len);
fd = handle_to_fd(handle);
- if (fd >= 0) {
+
+ if (fd < 0)
+ status = SSH2_FX_FAILURE;
+ else if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
if (lseek(fd, off, SEEK_SET) < 0) {
status = errno_to_portable(errno);
error("process_write: seek failed");
@@ -658,6 +671,7 @@ process_write(void)
handle_update_write(handle, ret);
} else {
debug2("nothing at all written");
+ status = SSH2_FX_FAILURE;
}
}
}
@@ -754,6 +768,10 @@ process_setstat(void)
name = get_string(NULL);
a = get_attrib();
debug("request %u: setstat name \"%s\"", id, name);
+ if (readonly) {
+ status = SSH2_FX_PERMISSION_DENIED;
+ a->flags = 0;
+ }
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
logit("set \"%s\" size %llu",
name, (unsigned long long)a->size);
@@ -802,9 +820,11 @@ process_fsetstat(void)
a = get_attrib();
debug("request %u: fsetstat handle %d", id, handle);
fd = handle_to_fd(handle);
- if (fd < 0) {
+ if (fd < 0)
status = SSH2_FX_FAILURE;
- } else {
+ else if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
char *name = handle_to_name(handle);
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
@@ -920,7 +940,7 @@ process_readdir(void)
continue;
stat_to_attrib(&st, &(stats[count].attrib));
stats[count].name = xstrdup(dp->d_name);
- stats[count].long_name = ls_file(dp->d_name, &st, 0);
+ stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
count++;
/* send up to 100 entries in one message */
/* XXX check packet size instead */
@@ -952,8 +972,12 @@ process_remove(void)
name = get_string(NULL);
debug3("request %u: remove", id);
logit("remove name \"%s\"", name);
- ret = unlink(name);
- status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
+ ret = unlink(name);
+ status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ }
send_status(id, status);
xfree(name);
}
@@ -973,8 +997,12 @@ process_mkdir(void)
a->perm & 07777 : 0777;
debug3("request %u: mkdir", id);
logit("mkdir name \"%s\" mode 0%o", name, mode);
- ret = mkdir(name, mode);
- status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
+ ret = mkdir(name, mode);
+ status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ }
send_status(id, status);
xfree(name);
}
@@ -990,8 +1018,12 @@ process_rmdir(void)
name = get_string(NULL);
debug3("request %u: rmdir", id);
logit("rmdir name \"%s\"", name);
- ret = rmdir(name);
- status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
+ ret = rmdir(name);
+ status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ }
send_status(id, status);
xfree(name);
}
@@ -1036,7 +1068,9 @@ process_rename(void)
debug3("request %u: rename", id);
logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
status = SSH2_FX_FAILURE;
- if (lstat(oldpath, &sb) == -1)
+ if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else if (lstat(oldpath, &sb) == -1)
status = errno_to_portable(errno);
else if (S_ISREG(sb.st_mode)) {
/* Race-free rename of regular files */
@@ -1120,8 +1154,12 @@ process_symlink(void)
debug3("request %u: symlink", id);
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
/* this will fail if 'newpath' exists */
- ret = symlink(oldpath, newpath);
- status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
+ ret = symlink(oldpath, newpath);
+ status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ }
send_status(id, status);
xfree(oldpath);
xfree(newpath);
@@ -1131,15 +1169,19 @@ static void
process_extended_posix_rename(u_int32_t id)
{
char *oldpath, *newpath;
+ int ret, status;
oldpath = get_string(NULL);
newpath = get_string(NULL);
debug3("request %u: posix-rename", id);
logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
- if (rename(oldpath, newpath) == -1)
- send_status(id, errno_to_portable(errno));
- else
- send_status(id, SSH2_FX_OK);
+ if (readonly)
+ status = SSH2_FX_PERMISSION_DENIED;
+ else {
+ ret = rename(oldpath, newpath);
+ status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ }
+ send_status(id, status);
xfree(oldpath);
xfree(newpath);
}
@@ -1322,7 +1364,8 @@ sftp_server_usage(void)
extern char *__progname;
fprintf(stderr,
- "usage: %s [-he] [-l log_level] [-f log_facility]\n", __progname);
+ "usage: %s [-ehR] [-f log_facility] [-l log_level] [-u umask]\n",
+ __progname);
exit(1);
}
@@ -1334,6 +1377,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
ssize_t len, olen, set_size;
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
char *cp, buf[4*4096];
+ const char *errmsg;
+ mode_t mask;
extern char *optarg;
extern char *__progname;
@@ -1341,8 +1386,11 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
__progname = ssh_get_progname(argv[0]);
log_init(__progname, log_level, log_facility, log_stderr);
- while (!skipargs && (ch = getopt(argc, argv, "f:l:che")) != -1) {
+ while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) {
switch (ch) {
+ case 'R':
+ readonly = 1;
+ break;
case 'c':
/*
* Ignore all arguments if we are invoked as a
@@ -1363,6 +1411,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
if (log_facility == SYSLOG_FACILITY_NOT_SET)
error("Invalid log facility \"%s\"", optarg);
break;
+ case 'u':
+ mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg);
+ if (errmsg != NULL)
+ fatal("Invalid umask \"%s\": %s",
+ optarg, errmsg);
+ (void)umask(mask);
+ break;
case 'h':
default:
sftp_server_usage();
@@ -1387,8 +1442,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
logit("session opened for local user %s from [%s]",
pw->pw_name, client_addr);
- in = dup(STDIN_FILENO);
- out = dup(STDOUT_FILENO);
+ in = STDIN_FILENO;
+ out = STDOUT_FILENO;
#ifdef HAVE_CYGWIN
setmode(in, O_BINARY);
diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
index ea56e50..9655cb8 100644
--- a/crypto/openssh/sftp.1
+++ b/crypto/openssh/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.69 2008/12/09 15:35:00 sobrado Exp $
+.\" $OpenBSD: sftp.1,v 1.83 2010/02/08 10:50:20 markus Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
@@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd December 9 2008
+.Dd February 8 2010
.Dt SFTP 1
.Os
.Sh NAME
@@ -32,12 +32,15 @@
.Sh SYNOPSIS
.Nm sftp
.Bk -words
-.Op Fl 1Cv
+.Op Fl 1246Cpqrv
.Op Fl B Ar buffer_size
.Op Fl b Ar batchfile
+.Op Fl c Ar cipher
+.Op Fl D Ar sftp_server_path
.Op Fl F Ar ssh_config
+.Op Fl i Ar identity_file
.Op Fl o Ar ssh_option
-.Op Fl P Ar sftp_server_path
+.Op Fl P Ar port
.Op Fl R Ar num_requests
.Op Fl S Ar program
.Op Fl s Ar subsystem | sftp_server
@@ -88,6 +91,16 @@ The options are as follows:
.Bl -tag -width Ds
.It Fl 1
Specify the use of protocol version 1.
+.It Fl 2
+Specify the use of protocol version 2.
+.It Fl 4
+Forces
+.Nm
+to use IPv4 addresses only.
+.It Fl 6
+Forces
+.Nm
+to use IPv6 addresses only.
.It Fl B Ar buffer_size
Specify the size of the buffer that
.Nm
@@ -125,12 +138,26 @@ character (for example,
Enables compression (via ssh's
.Fl C
flag).
+.It Fl c Ar cipher
+Selects the cipher to use for encrypting the data transfers.
+This option is directly passed to
+.Xr ssh 1 .
+.It Fl D Ar sftp_server_path
+Connect directly to a local sftp server
+(rather than via
+.Xr ssh 1 ) .
+This option may be useful in debugging the client and server.
.It Fl F Ar ssh_config
Specifies an alternative
per-user configuration file for
.Xr ssh 1 .
This option is directly passed to
.Xr ssh 1 .
+.It Fl i Ar identity_file
+Selects the file from which the identity (private key) for public key
+authentication is read.
+This option is directly passed to
+.Xr ssh 1 .
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
@@ -176,6 +203,7 @@ For full details of the options listed below, and their possible values, see
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
+.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It Protocol
@@ -187,7 +215,6 @@ For full details of the options listed below, and their possible values, see
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
-.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive
.It UsePrivilegedPort
@@ -195,16 +222,25 @@ For full details of the options listed below, and their possible values, see
.It UserKnownHostsFile
.It VerifyHostKeyDNS
.El
-.It Fl P Ar sftp_server_path
-Connect directly to a local sftp server
-(rather than via
-.Xr ssh 1 ) .
-This option may be useful in debugging the client and server.
+.It Fl P Ar port
+Specifies the port to connect to on the remote host.
+.It Fl p
+Preserves modification times, access times, and modes from the
+original files transferred.
+.It Fl q
+Quiet mode: disables the progress meter as well as warning and
+diagnostic messages from
+.Xr ssh 1 .
.It Fl R Ar num_requests
Specify how many requests may be outstanding at any one time.
Increasing this may slightly improve file transfer speed
but will increase memory usage.
The default is 64 outstanding requests.
+.It Fl r
+Recursively copy entire directories when uploading and downloading.
+Note that
+.Nm
+does not follow symbolic links encountered in the tree traversal.
.It Fl S Ar program
Name of the
.Ar program
@@ -295,7 +331,7 @@ extension.
Quit
.Nm sftp .
.It Xo Ic get
-.Op Fl P
+.Op Fl Ppr
.Ar remote-path
.Op Ar local-path
.Xc
@@ -314,10 +350,20 @@ If it does and
is specified, then
.Ar local-path
must specify a directory.
-If the
+.Pp
+If either the
.Fl P
+or
+.Fl p
flag is specified, then full file permissions and access times are
copied too.
+.Pp
+If the
+.Fl r
+flag is specified then directories will be copied recursively.
+Note that
+.Nm
+does not follow symbolic links when performing recursive transfers.
.It Ic help
Display help text.
.It Ic lcd Ar path
@@ -348,7 +394,7 @@ to
.It Ic lpwd
Print local working directory.
.It Xo Ic ls
-.Op Fl 1aflnrSt
+.Op Fl 1afhlnrSt
.Op Ar path
.Xc
Display a remote directory listing of either
@@ -373,6 +419,11 @@ List files beginning with a dot
.It Fl f
Do not sort the listing.
The default sort order is lexicographical.
+.It Fl h
+When used with a long format option, use unit suffixes: Byte, Kilobyte,
+Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce
+the number of digits to four or fewer using powers of 2 for sizes (K=1024,
+M=1048576, etc.).
.It Fl l
Display additional details including permissions
and ownership information.
@@ -395,7 +446,7 @@ Create remote directory specified by
.It Ic progress
Toggle display of progress meter.
.It Xo Ic put
-.Op Fl P
+.Op Fl Ppr
.Ar local-path
.Op Ar remote-path
.Xc
@@ -413,10 +464,20 @@ If it does and
is specified, then
.Ar remote-path
must specify a directory.
-If the
+.Pp
+If ether the
.Fl P
-flag is specified, then the file's full permission and access time are
+or
+.Fl p
+flag is specified, then full file permissions and access times are
copied too.
+.Pp
+If the
+.Fl r
+flag is specified then directories will be copied recursively.
+Note that
+.Nm
+does not follow symbolic links when performing recursive transfers.
.It Ic pwd
Display remote working directory.
.It Ic quit
diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
index 66bd111..d65d4ec 100644
--- a/crypto/openssh/sftp.c
+++ b/crypto/openssh/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.107 2009/02/02 11:15:14 dtucker Exp $ */
+/* $OpenBSD: sftp.c,v 1.123 2010/01/27 19:21:39 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -35,6 +35,9 @@
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
#ifdef USE_LIBEDIT
#include <histedit.h>
#else
@@ -65,30 +68,39 @@ typedef void EditLine;
#include "sftp-common.h"
#include "sftp-client.h"
+#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
+#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
+
/* File to read commands from */
FILE* infile;
/* Are we in batchfile mode? */
int batchmode = 0;
-/* Size of buffer used when copying files */
-size_t copy_buffer_len = 32768;
-
-/* Number of concurrent outstanding requests */
-size_t num_requests = 64;
-
/* PID of ssh transport process */
static pid_t sshpid = -1;
/* This is set to 0 if the progressmeter is not desired. */
int showprogress = 1;
+/* When this option is set, we always recursively download/upload directories */
+int global_rflag = 0;
+
+/* When this option is set, the file transfers will always preserve times */
+int global_pflag = 0;
+
/* SIGINT received during command processing */
volatile sig_atomic_t interrupted = 0;
/* I wish qsort() took a separate ctx for the comparison function...*/
int sort_flag;
+/* Context used for commandline completion */
+struct complete_ctx {
+ struct sftp_conn *conn;
+ char **remote_pathp;
+};
+
int remote_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
@@ -98,16 +110,17 @@ extern char *__progname;
#define WHITESPACE " \t\r\n"
/* ls flags */
-#define LS_LONG_VIEW 0x01 /* Full view ala ls -l */
-#define LS_SHORT_VIEW 0x02 /* Single row view ala ls -1 */
-#define LS_NUMERIC_VIEW 0x04 /* Long view with numeric uid/gid */
-#define LS_NAME_SORT 0x08 /* Sort by name (default) */
-#define LS_TIME_SORT 0x10 /* Sort by mtime */
-#define LS_SIZE_SORT 0x20 /* Sort by file size */
-#define LS_REVERSE_SORT 0x40 /* Reverse sort order */
-#define LS_SHOW_ALL 0x80 /* Don't skip filenames starting with '.' */
-
-#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW)
+#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */
+#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */
+#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */
+#define LS_NAME_SORT 0x0008 /* Sort by name (default) */
+#define LS_TIME_SORT 0x0010 /* Sort by mtime */
+#define LS_SIZE_SORT 0x0020 /* Sort by file size */
+#define LS_REVERSE_SORT 0x0040 /* Reverse sort order */
+#define LS_SHOW_ALL 0x0080 /* Don't skip filenames starting with '.' */
+#define LS_SI_UNITS 0x0100 /* Display sizes as K, M, G, etc. */
+
+#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS)
#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT)
/* Commands for interactive mode */
@@ -139,46 +152,50 @@ extern char *__progname;
struct CMD {
const char *c;
const int n;
+ const int t;
};
+/* Type of completion */
+#define NOARGS 0
+#define REMOTE 1
+#define LOCAL 2
+
static const struct CMD cmds[] = {
- { "bye", I_QUIT },
- { "cd", I_CHDIR },
- { "chdir", I_CHDIR },
- { "chgrp", I_CHGRP },
- { "chmod", I_CHMOD },
- { "chown", I_CHOWN },
- { "df", I_DF },
- { "dir", I_LS },
- { "exit", I_QUIT },
- { "get", I_GET },
- { "mget", I_GET },
- { "help", I_HELP },
- { "lcd", I_LCHDIR },
- { "lchdir", I_LCHDIR },
- { "lls", I_LLS },
- { "lmkdir", I_LMKDIR },
- { "ln", I_SYMLINK },
- { "lpwd", I_LPWD },
- { "ls", I_LS },
- { "lumask", I_LUMASK },
- { "mkdir", I_MKDIR },
- { "progress", I_PROGRESS },
- { "put", I_PUT },
- { "mput", I_PUT },
- { "pwd", I_PWD },
- { "quit", I_QUIT },
- { "rename", I_RENAME },
- { "rm", I_RM },
- { "rmdir", I_RMDIR },
- { "symlink", I_SYMLINK },
- { "version", I_VERSION },
- { "!", I_SHELL },
- { "?", I_HELP },
- { NULL, -1}
+ { "bye", I_QUIT, NOARGS },
+ { "cd", I_CHDIR, REMOTE },
+ { "chdir", I_CHDIR, REMOTE },
+ { "chgrp", I_CHGRP, REMOTE },
+ { "chmod", I_CHMOD, REMOTE },
+ { "chown", I_CHOWN, REMOTE },
+ { "df", I_DF, REMOTE },
+ { "dir", I_LS, REMOTE },
+ { "exit", I_QUIT, NOARGS },
+ { "get", I_GET, REMOTE },
+ { "help", I_HELP, NOARGS },
+ { "lcd", I_LCHDIR, LOCAL },
+ { "lchdir", I_LCHDIR, LOCAL },
+ { "lls", I_LLS, LOCAL },
+ { "lmkdir", I_LMKDIR, LOCAL },
+ { "ln", I_SYMLINK, REMOTE },
+ { "lpwd", I_LPWD, LOCAL },
+ { "ls", I_LS, REMOTE },
+ { "lumask", I_LUMASK, NOARGS },
+ { "mkdir", I_MKDIR, REMOTE },
+ { "progress", I_PROGRESS, NOARGS },
+ { "put", I_PUT, LOCAL },
+ { "pwd", I_PWD, REMOTE },
+ { "quit", I_QUIT, NOARGS },
+ { "rename", I_RENAME, REMOTE },
+ { "rm", I_RM, REMOTE },
+ { "rmdir", I_RMDIR, REMOTE },
+ { "symlink", I_SYMLINK, REMOTE },
+ { "version", I_VERSION, NOARGS },
+ { "!", I_SHELL, NOARGS },
+ { "?", I_HELP, NOARGS },
+ { NULL, -1, -1 }
};
-int interactive_loop(int fd_in, int fd_out, char *file1, char *file2);
+int interactive_loop(struct sftp_conn *, char *file1, char *file2);
/* ARGSUSED */
static void
@@ -216,18 +233,18 @@ help(void)
"df [-hi] [path] Display statistics for current directory or\n"
" filesystem containing 'path'\n"
"exit Quit sftp\n"
- "get [-P] remote-path [local-path] Download file\n"
+ "get [-Ppr] remote [local] Download file\n"
"help Display this help text\n"
"lcd path Change local directory to 'path'\n"
"lls [ls-options [path]] Display local directory listing\n"
"lmkdir path Create local directory\n"
"ln oldpath newpath Symlink remote file\n"
"lpwd Print local working directory\n"
- "ls [-1aflnrSt] [path] Display remote directory listing\n"
+ "ls [-1afhlnrSt] [path] Display remote directory listing\n"
"lumask umask Set local umask to 'umask'\n"
"mkdir path Create remote directory\n"
"progress Toggle display of progress meter\n"
- "put [-P] local-path [remote-path] Upload file\n"
+ "put [-Ppr] local [remote] Upload file\n"
"pwd Display remote working directory\n"
"quit Quit sftp\n"
"rename oldpath newpath Rename remote file\n"
@@ -314,21 +331,6 @@ path_strip(char *path, char *strip)
}
static char *
-path_append(char *p1, char *p2)
-{
- char *ret;
- size_t len = strlen(p1) + strlen(p2) + 2;
-
- ret = xmalloc(len);
- strlcpy(ret, p1, len);
- if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
- strlcat(ret, "/", len);
- strlcat(ret, p2, len);
-
- return(ret);
-}
-
-static char *
make_absolute(char *p, char *pwd)
{
char *abs_str;
@@ -343,27 +345,8 @@ make_absolute(char *p, char *pwd)
}
static int
-infer_path(const char *p, char **ifp)
-{
- char *cp;
-
- cp = strrchr(p, '/');
- if (cp == NULL) {
- *ifp = xstrdup(p);
- return(0);
- }
-
- if (!cp[1]) {
- error("Invalid path");
- return(-1);
- }
-
- *ifp = xstrdup(cp + 1);
- return(0);
-}
-
-static int
-parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
+parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
+ int *rflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
@@ -371,13 +354,17 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
optind = optreset = 1;
opterr = 0;
- *pflag = 0;
- while ((ch = getopt(argc, argv, "Pp")) != -1) {
+ *rflag = *pflag = 0;
+ while ((ch = getopt(argc, argv, "PpRr")) != -1) {
switch (ch) {
case 'p':
case 'P':
*pflag = 1;
break;
+ case 'r':
+ case 'R':
+ *rflag = 1;
+ break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
@@ -397,7 +384,7 @@ parse_ls_flags(char **argv, int argc, int *lflag)
opterr = 0;
*lflag = LS_NAME_SORT;
- while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) {
+ while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) {
switch (ch) {
case '1':
*lflag &= ~VIEW_FLAGS;
@@ -413,12 +400,15 @@ parse_ls_flags(char **argv, int argc, int *lflag)
case 'f':
*lflag &= ~SORT_FLAGS;
break;
+ case 'h':
+ *lflag |= LS_SI_UNITS;
+ break;
case 'l':
- *lflag &= ~VIEW_FLAGS;
+ *lflag &= ~LS_SHORT_VIEW;
*lflag |= LS_LONG_VIEW;
break;
case 'n':
- *lflag &= ~VIEW_FLAGS;
+ *lflag &= ~LS_SHORT_VIEW;
*lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
break;
case 'r':
@@ -489,62 +479,79 @@ remote_is_dir(struct sftp_conn *conn, char *path)
return(S_ISDIR(a->perm));
}
+/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
+static int
+pathname_is_dir(char *pathname)
+{
+ size_t l = strlen(pathname);
+
+ return l > 0 && pathname[l - 1] == '/';
+}
+
static int
-process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
+process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
+ int pflag, int rflag)
{
char *abs_src = NULL;
char *abs_dst = NULL;
- char *tmp;
glob_t g;
- int err = 0;
- int i;
+ char *filename, *tmp=NULL;
+ int i, err = 0;
abs_src = xstrdup(src);
abs_src = make_absolute(abs_src, pwd);
-
memset(&g, 0, sizeof(g));
+
debug3("Looking up %s", abs_src);
- if (remote_glob(conn, abs_src, 0, NULL, &g)) {
+ if (remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) {
error("File \"%s\" not found.", abs_src);
err = -1;
goto out;
}
- /* If multiple matches, dst must be a directory or unspecified */
- if (g.gl_matchc > 1 && dst && !is_dir(dst)) {
- error("Multiple files match, but \"%s\" is not a directory",
- dst);
+ /*
+ * If multiple matches then dst must be a directory or
+ * unspecified.
+ */
+ if (g.gl_matchc > 1 && dst != NULL && !is_dir(dst)) {
+ error("Multiple source paths, but destination "
+ "\"%s\" is not a directory", dst);
err = -1;
goto out;
}
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
- if (infer_path(g.gl_pathv[i], &tmp)) {
+ tmp = xstrdup(g.gl_pathv[i]);
+ if ((filename = basename(tmp)) == NULL) {
+ error("basename %s: %s", tmp, strerror(errno));
+ xfree(tmp);
err = -1;
goto out;
}
if (g.gl_matchc == 1 && dst) {
- /* If directory specified, append filename */
- xfree(tmp);
if (is_dir(dst)) {
- if (infer_path(g.gl_pathv[0], &tmp)) {
- err = 1;
- goto out;
- }
- abs_dst = path_append(dst, tmp);
- xfree(tmp);
- } else
+ abs_dst = path_append(dst, filename);
+ } else {
abs_dst = xstrdup(dst);
+ }
} else if (dst) {
- abs_dst = path_append(dst, tmp);
- xfree(tmp);
- } else
- abs_dst = tmp;
+ abs_dst = path_append(dst, filename);
+ } else {
+ abs_dst = xstrdup(filename);
+ }
+ xfree(tmp);
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
- if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
- err = -1;
+ if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
+ if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
+ pflag || global_pflag, 1) == -1)
+ err = -1;
+ } else {
+ if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
+ pflag || global_pflag) == -1)
+ err = -1;
+ }
xfree(abs_dst);
abs_dst = NULL;
}
@@ -556,14 +563,15 @@ out:
}
static int
-process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
+process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
+ int pflag, int rflag)
{
char *tmp_dst = NULL;
char *abs_dst = NULL;
- char *tmp;
+ char *tmp = NULL, *filename = NULL;
glob_t g;
int err = 0;
- int i;
+ int i, dst_is_dir = 1;
struct stat sb;
if (dst) {
@@ -573,16 +581,20 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
memset(&g, 0, sizeof(g));
debug3("Looking up %s", src);
- if (glob(src, GLOB_NOCHECK, NULL, &g)) {
+ if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) {
error("File \"%s\" not found.", src);
err = -1;
goto out;
}
+ /* If we aren't fetching to pwd then stash this status for later */
+ if (tmp_dst != NULL)
+ dst_is_dir = remote_is_dir(conn, tmp_dst);
+
/* If multiple matches, dst may be directory or unspecified */
- if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) {
- error("Multiple files match, but \"%s\" is not a directory",
- tmp_dst);
+ if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
+ error("Multiple paths match, but destination "
+ "\"%s\" is not a directory", tmp_dst);
err = -1;
goto out;
}
@@ -593,38 +605,38 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
error("stat %s: %s", g.gl_pathv[i], strerror(errno));
continue;
}
-
- if (!S_ISREG(sb.st_mode)) {
- error("skipping non-regular file %s",
- g.gl_pathv[i]);
- continue;
- }
- if (infer_path(g.gl_pathv[i], &tmp)) {
+
+ tmp = xstrdup(g.gl_pathv[i]);
+ if ((filename = basename(tmp)) == NULL) {
+ error("basename %s: %s", tmp, strerror(errno));
+ xfree(tmp);
err = -1;
goto out;
}
if (g.gl_matchc == 1 && tmp_dst) {
/* If directory specified, append filename */
- if (remote_is_dir(conn, tmp_dst)) {
- if (infer_path(g.gl_pathv[0], &tmp)) {
- err = 1;
- goto out;
- }
- abs_dst = path_append(tmp_dst, tmp);
- xfree(tmp);
- } else
+ if (dst_is_dir)
+ abs_dst = path_append(tmp_dst, filename);
+ else
abs_dst = xstrdup(tmp_dst);
-
} else if (tmp_dst) {
- abs_dst = path_append(tmp_dst, tmp);
- xfree(tmp);
- } else
- abs_dst = make_absolute(tmp, pwd);
+ abs_dst = path_append(tmp_dst, filename);
+ } else {
+ abs_dst = make_absolute(xstrdup(filename), pwd);
+ }
+ xfree(tmp);
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
- if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
- err = -1;
+ if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
+ if (upload_dir(conn, g.gl_pathv[i], abs_dst,
+ pflag || global_pflag, 1) == -1)
+ err = -1;
+ } else {
+ if (do_upload(conn, g.gl_pathv[i], abs_dst,
+ pflag || global_pflag) == -1)
+ err = -1;
+ }
}
out:
@@ -708,13 +720,14 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
xfree(tmp);
if (lflag & LS_LONG_VIEW) {
- if (lflag & LS_NUMERIC_VIEW) {
+ if (lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) {
char *lname;
struct stat sb;
memset(&sb, 0, sizeof(sb));
attrib_to_stat(&d[n]->a, &sb);
- lname = ls_file(fname, &sb, 1);
+ lname = ls_file(fname, &sb, 1,
+ (lflag & LS_SI_UNITS));
printf("%s\n", lname);
xfree(lname);
} else
@@ -816,7 +829,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
a = do_lstat(conn, g.gl_pathv[i], 1);
if (a != NULL)
attrib_to_stat(a, &sb);
- lname = ls_file(fname, &sb, 1);
+ lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS));
printf("%s\n", lname);
xfree(lname);
} else {
@@ -848,19 +861,19 @@ do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
char s_avail[FMT_SCALED_STRSIZE];
char s_root[FMT_SCALED_STRSIZE];
char s_total[FMT_SCALED_STRSIZE];
+ unsigned long long ffree;
if (do_statvfs(conn, path, &st, 1) == -1)
return -1;
if (iflag) {
+ ffree = st.f_files ? (100 * (st.f_files - st.f_ffree) / st.f_files) : 0;
printf(" Inodes Used Avail "
"(root) %%Capacity\n");
printf("%11llu %11llu %11llu %11llu %3llu%%\n",
(unsigned long long)st.f_files,
(unsigned long long)(st.f_files - st.f_ffree),
(unsigned long long)st.f_favail,
- (unsigned long long)st.f_ffree,
- (unsigned long long)(100 * (st.f_files - st.f_ffree) /
- st.f_files));
+ (unsigned long long)st.f_ffree, ffree);
} else if (hflag) {
strlcpy(s_used, "error", sizeof(s_used));
strlcpy(s_avail, "error", sizeof(s_avail));
@@ -934,12 +947,23 @@ undo_glob_escape(char *s)
* Split a string into an argument vector using sh(1)-style quoting,
* comment and escaping rules, but with some tweaks to handle glob(3)
* wildcards.
+ * The "sloppy" flag allows for recovery from missing terminating quote, for
+ * use in parsing incomplete commandlines during tab autocompletion.
+ *
* Returns NULL on error or a NULL-terminated array of arguments.
+ *
+ * If "lastquote" is not NULL, the quoting character used for the last
+ * argument is placed in *lastquote ("\0", "'" or "\"").
+ *
+ * If "terminated" is not NULL, *terminated will be set to 1 when the
+ * last argument's quote has been properly terminated or 0 otherwise.
+ * This parameter is only of use if "sloppy" is set.
*/
#define MAXARGS 128
#define MAXARGLEN 8192
static char **
-makeargv(const char *arg, int *argcp)
+makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
+ u_int *terminated)
{
int argc, quot;
size_t i, j;
@@ -953,6 +977,10 @@ makeargv(const char *arg, int *argcp)
error("string too long");
return NULL;
}
+ if (terminated != NULL)
+ *terminated = 1;
+ if (lastquote != NULL)
+ *lastquote = '\0';
state = MA_START;
i = j = 0;
for (;;) {
@@ -969,6 +997,8 @@ makeargv(const char *arg, int *argcp)
if (state == MA_START) {
argv[argc] = argvs + j;
state = q;
+ if (lastquote != NULL)
+ *lastquote = arg[i];
} else if (state == MA_UNQUOTED)
state = q;
else if (state == q)
@@ -1005,6 +1035,8 @@ makeargv(const char *arg, int *argcp)
if (state == MA_START) {
argv[argc] = argvs + j;
state = MA_UNQUOTED;
+ if (lastquote != NULL)
+ *lastquote = '\0';
}
if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
arg[i + 1] == '*' || arg[i + 1] == '\\') {
@@ -1030,6 +1062,12 @@ makeargv(const char *arg, int *argcp)
goto string_done;
} else if (arg[i] == '\0') {
if (state == MA_SQUOTE || state == MA_DQUOTE) {
+ if (sloppy) {
+ state = MA_UNQUOTED;
+ if (terminated != NULL)
+ *terminated = 0;
+ goto string_done;
+ }
error("Unterminated quoted argument");
return NULL;
}
@@ -1043,6 +1081,8 @@ makeargv(const char *arg, int *argcp)
if (state == MA_START) {
argv[argc] = argvs + j;
state = MA_UNQUOTED;
+ if (lastquote != NULL)
+ *lastquote = '\0';
}
if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
(arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
@@ -1065,8 +1105,8 @@ makeargv(const char *arg, int *argcp)
}
static int
-parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
- unsigned long *n_arg, char **path1, char **path2)
+parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
+ int *hflag, unsigned long *n_arg, char **path1, char **path2)
{
const char *cmd, *cp = *cpp;
char *cp2, **argv;
@@ -1077,18 +1117,19 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
/* Skip leading whitespace */
cp = cp + strspn(cp, WHITESPACE);
- /* Ignore blank lines and lines which begin with comment '#' char */
- if (*cp == '\0' || *cp == '#')
- return (0);
-
/* Check for leading '-' (disable error processing) */
*iflag = 0;
if (*cp == '-') {
*iflag = 1;
cp++;
+ cp = cp + strspn(cp, WHITESPACE);
}
- if ((argv = makeargv(cp, &argc)) == NULL)
+ /* Ignore blank lines and lines which begin with comment '#' char */
+ if (*cp == '\0' || *cp == '#')
+ return (0);
+
+ if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
return -1;
/* Figure out which command we have */
@@ -1109,13 +1150,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
}
/* Get arguments and parse flags */
- *lflag = *pflag = *hflag = *n_arg = 0;
+ *lflag = *pflag = *rflag = *hflag = *n_arg = 0;
*path1 = *path2 = NULL;
optidx = 1;
switch (cmdnum) {
case I_GET:
case I_PUT:
- if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1)
+ if ((optidx = parse_getput_flags(cmd, argv, argc, pflag, rflag)) == -1)
return -1;
/* Get first pathname (mandatory) */
if (argc - optidx < 1) {
@@ -1235,7 +1276,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
int err_abort)
{
char *path1, *path2, *tmp;
- int pflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
+ int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
unsigned long n_arg = 0;
Attrib a, *aa;
char path_buf[MAXPATHLEN];
@@ -1243,7 +1284,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
glob_t g;
path1 = path2 = NULL;
- cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg,
+ cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, &n_arg,
&path1, &path2);
if (iflag != 0)
@@ -1261,10 +1302,10 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
err = -1;
break;
case I_GET:
- err = process_get(conn, path1, path2, *pwd, pflag);
+ err = process_get(conn, path1, path2, *pwd, pflag, rflag);
break;
case I_PUT:
- err = process_put(conn, path1, path2, *pwd, pflag);
+ err = process_put(conn, path1, path2, *pwd, pflag, rflag);
break;
case I_RENAME:
path1 = make_absolute(path1, *pwd);
@@ -1290,7 +1331,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
- err = do_mkdir(conn, path1, &a);
+ err = do_mkdir(conn, path1, &a, 1);
break;
case I_RMDIR:
path1 = make_absolute(path1, *pwd);
@@ -1468,21 +1509,352 @@ prompt(EditLine *el)
{
return ("sftp> ");
}
-#endif
+
+/* Display entries in 'list' after skipping the first 'len' chars */
+static void
+complete_display(char **list, u_int len)
+{
+ u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen;
+ struct winsize ws;
+ char *tmp;
+
+ /* Count entries for sort and find longest */
+ for (y = 0; list[y]; y++)
+ m = MAX(m, strlen(list[y]));
+
+ if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
+ width = ws.ws_col;
+
+ m = m > len ? m - len : 0;
+ columns = width / (m + 2);
+ columns = MAX(columns, 1);
+ colspace = width / columns;
+ colspace = MIN(colspace, width);
+
+ printf("\n");
+ m = 1;
+ for (y = 0; list[y]; y++) {
+ llen = strlen(list[y]);
+ tmp = llen > len ? list[y] + len : "";
+ printf("%-*s", colspace, tmp);
+ if (m >= columns) {
+ printf("\n");
+ m = 1;
+ } else
+ m++;
+ }
+ printf("\n");
+}
+
+/*
+ * Given a "list" of words that begin with a common prefix of "word",
+ * attempt to find an autocompletion to extends "word" by the next
+ * characters common to all entries in "list".
+ */
+static char *
+complete_ambiguous(const char *word, char **list, size_t count)
+{
+ if (word == NULL)
+ return NULL;
+
+ if (count > 0) {
+ u_int y, matchlen = strlen(list[0]);
+
+ /* Find length of common stem */
+ for (y = 1; list[y]; y++) {
+ u_int x;
+
+ for (x = 0; x < matchlen; x++)
+ if (list[0][x] != list[y][x])
+ break;
+
+ matchlen = x;
+ }
+
+ if (matchlen > strlen(word)) {
+ char *tmp = xstrdup(list[0]);
+
+ tmp[matchlen] = '\0';
+ return tmp;
+ }
+ }
+
+ return xstrdup(word);
+}
+
+/* Autocomplete a sftp command */
+static int
+complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
+ int terminated)
+{
+ u_int y, count = 0, cmdlen, tmplen;
+ char *tmp, **list, argterm[3];
+ const LineInfo *lf;
+
+ list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *));
+
+ /* No command specified: display all available commands */
+ if (cmd == NULL) {
+ for (y = 0; cmds[y].c; y++)
+ list[count++] = xstrdup(cmds[y].c);
+
+ list[count] = NULL;
+ complete_display(list, 0);
+
+ for (y = 0; list[y] != NULL; y++)
+ xfree(list[y]);
+ xfree(list);
+ return count;
+ }
+
+ /* Prepare subset of commands that start with "cmd" */
+ cmdlen = strlen(cmd);
+ for (y = 0; cmds[y].c; y++) {
+ if (!strncasecmp(cmd, cmds[y].c, cmdlen))
+ list[count++] = xstrdup(cmds[y].c);
+ }
+ list[count] = NULL;
+
+ if (count == 0)
+ return 0;
+
+ /* Complete ambigious command */
+ tmp = complete_ambiguous(cmd, list, count);
+ if (count > 1)
+ complete_display(list, 0);
+
+ for (y = 0; list[y]; y++)
+ xfree(list[y]);
+ xfree(list);
+
+ if (tmp != NULL) {
+ tmplen = strlen(tmp);
+ cmdlen = strlen(cmd);
+ /* If cmd may be extended then do so */
+ if (tmplen > cmdlen)
+ if (el_insertstr(el, tmp + cmdlen) == -1)
+ fatal("el_insertstr failed.");
+ lf = el_line(el);
+ /* Terminate argument cleanly */
+ if (count == 1) {
+ y = 0;
+ if (!terminated)
+ argterm[y++] = quote;
+ if (lastarg || *(lf->cursor) != ' ')
+ argterm[y++] = ' ';
+ argterm[y] = '\0';
+ if (y > 0 && el_insertstr(el, argterm) == -1)
+ fatal("el_insertstr failed.");
+ }
+ xfree(tmp);
+ }
+
+ return count;
+}
+
+/*
+ * Determine whether a particular sftp command's arguments (if any)
+ * represent local or remote files.
+ */
+static int
+complete_is_remote(char *cmd) {
+ int i;
+
+ if (cmd == NULL)
+ return -1;
+
+ for (i = 0; cmds[i].c; i++) {
+ if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c)))
+ return cmds[i].t;
+ }
+
+ return -1;
+}
+
+/* Autocomplete a filename "file" */
+static int
+complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
+ char *file, int remote, int lastarg, char quote, int terminated)
+{
+ glob_t g;
+ char *tmp, *tmp2, ins[3];
+ u_int i, hadglob, pwdlen, len, tmplen, filelen;
+ const LineInfo *lf;
+
+ /* Glob from "file" location */
+ if (file == NULL)
+ tmp = xstrdup("*");
+ else
+ xasprintf(&tmp, "%s*", file);
+
+ memset(&g, 0, sizeof(g));
+ if (remote != LOCAL) {
+ tmp = make_absolute(tmp, remote_path);
+ remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
+ } else
+ glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
+
+ /* Determine length of pwd so we can trim completion display */
+ for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {
+ /* Terminate counting on first unescaped glob metacharacter */
+ if (tmp[tmplen] == '*' || tmp[tmplen] == '?') {
+ if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0')
+ hadglob = 1;
+ break;
+ }
+ if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0')
+ tmplen++;
+ if (tmp[tmplen] == '/')
+ pwdlen = tmplen + 1; /* track last seen '/' */
+ }
+ xfree(tmp);
+
+ if (g.gl_matchc == 0)
+ goto out;
+
+ if (g.gl_matchc > 1)
+ complete_display(g.gl_pathv, pwdlen);
+
+ tmp = NULL;
+ /* Don't try to extend globs */
+ if (file == NULL || hadglob)
+ goto out;
+
+ tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
+ tmp = path_strip(tmp2, remote_path);
+ xfree(tmp2);
+
+ if (tmp == NULL)
+ goto out;
+
+ tmplen = strlen(tmp);
+ filelen = strlen(file);
+
+ if (tmplen > filelen) {
+ tmp2 = tmp + filelen;
+ len = strlen(tmp2);
+ /* quote argument on way out */
+ for (i = 0; i < len; i++) {
+ ins[0] = '\\';
+ ins[1] = tmp2[i];
+ ins[2] = '\0';
+ switch (tmp2[i]) {
+ case '\'':
+ case '"':
+ case '\\':
+ case '\t':
+ case ' ':
+ if (quote == '\0' || tmp2[i] == quote) {
+ if (el_insertstr(el, ins) == -1)
+ fatal("el_insertstr "
+ "failed.");
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ if (el_insertstr(el, ins + 1) == -1)
+ fatal("el_insertstr failed.");
+ break;
+ }
+ }
+ }
+
+ lf = el_line(el);
+ if (g.gl_matchc == 1) {
+ i = 0;
+ if (!terminated)
+ ins[i++] = quote;
+ if (*(lf->cursor - 1) != '/' &&
+ (lastarg || *(lf->cursor) != ' '))
+ ins[i++] = ' ';
+ ins[i] = '\0';
+ if (i > 0 && el_insertstr(el, ins) == -1)
+ fatal("el_insertstr failed.");
+ }
+ xfree(tmp);
+
+ out:
+ globfree(&g);
+ return g.gl_matchc;
+}
+
+/* tab-completion hook function, called via libedit */
+static unsigned char
+complete(EditLine *el, int ch)
+{
+ char **argv, *line, quote;
+ u_int argc, carg, cursor, len, terminated, ret = CC_ERROR;
+ const LineInfo *lf;
+ struct complete_ctx *complete_ctx;
+
+ lf = el_line(el);
+ if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)
+ fatal("%s: el_get failed", __func__);
+
+ /* Figure out which argument the cursor points to */
+ cursor = lf->cursor - lf->buffer;
+ line = (char *)xmalloc(cursor + 1);
+ memcpy(line, lf->buffer, cursor);
+ line[cursor] = '\0';
+ argv = makeargv(line, &carg, 1, &quote, &terminated);
+ xfree(line);
+
+ /* Get all the arguments on the line */
+ len = lf->lastchar - lf->buffer;
+ line = (char *)xmalloc(len + 1);
+ memcpy(line, lf->buffer, len);
+ line[len] = '\0';
+ argv = makeargv(line, &argc, 1, NULL, NULL);
+
+ /* Ensure cursor is at EOL or a argument boundary */
+ if (line[cursor] != ' ' && line[cursor] != '\0' &&
+ line[cursor] != '\n') {
+ xfree(line);
+ return ret;
+ }
+
+ if (carg == 0) {
+ /* Show all available commands */
+ complete_cmd_parse(el, NULL, argc == carg, '\0', 1);
+ ret = CC_REDISPLAY;
+ } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') {
+ /* Handle the command parsing */
+ if (complete_cmd_parse(el, argv[0], argc == carg,
+ quote, terminated) != 0)
+ ret = CC_REDISPLAY;
+ } else if (carg >= 1) {
+ /* Handle file parsing */
+ int remote = complete_is_remote(argv[0]);
+ char *filematch = NULL;
+
+ if (carg > 1 && line[cursor-1] != ' ')
+ filematch = argv[carg - 1];
+
+ if (remote != 0 &&
+ complete_match(el, complete_ctx->conn,
+ *complete_ctx->remote_pathp, filematch,
+ remote, carg == argc, quote, terminated) != 0)
+ ret = CC_REDISPLAY;
+ }
+
+ xfree(line);
+ return ret;
+}
+#endif /* USE_LIBEDIT */
int
-interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
+interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
{
- char *pwd;
+ char *remote_path;
char *dir = NULL;
char cmd[2048];
- struct sftp_conn *conn;
int err, interactive;
EditLine *el = NULL;
#ifdef USE_LIBEDIT
History *hl = NULL;
HistEvent hev;
extern char *__progname;
+ struct complete_ctx complete_ctx;
if (!batchmode && isatty(STDIN_FILENO)) {
if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)
@@ -1497,27 +1869,32 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
el_set(el, EL_TERMINAL, NULL);
el_set(el, EL_SIGNAL, 1);
el_source(el, NULL);
+
+ /* Tab Completion */
+ el_set(el, EL_ADDFN, "ftp-complete",
+ "Context senstive argument completion", complete);
+ complete_ctx.conn = conn;
+ complete_ctx.remote_pathp = &remote_path;
+ el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
+ el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
}
#endif /* USE_LIBEDIT */
- conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
- if (conn == NULL)
- fatal("Couldn't initialise connection to server");
-
- pwd = do_realpath(conn, ".");
- if (pwd == NULL)
+ remote_path = do_realpath(conn, ".");
+ if (remote_path == NULL)
fatal("Need cwd");
if (file1 != NULL) {
dir = xstrdup(file1);
- dir = make_absolute(dir, pwd);
+ dir = make_absolute(dir, remote_path);
if (remote_is_dir(conn, dir) && file2 == NULL) {
printf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
- if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) {
+ if (parse_dispatch_command(conn, cmd,
+ &remote_path, 1) != 0) {
xfree(dir);
- xfree(pwd);
+ xfree(remote_path);
xfree(conn);
return (-1);
}
@@ -1528,9 +1905,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
snprintf(cmd, sizeof cmd, "get %s %s", dir,
file2);
- err = parse_dispatch_command(conn, cmd, &pwd, 1);
+ err = parse_dispatch_command(conn, cmd,
+ &remote_path, 1);
xfree(dir);
- xfree(pwd);
+ xfree(remote_path);
xfree(conn);
return (err);
}
@@ -1571,7 +1949,8 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
const char *line;
int count = 0;
- if ((line = el_gets(el, &count)) == NULL || count <= 0) {
+ if ((line = el_gets(el, &count)) == NULL ||
+ count <= 0) {
printf("\n");
break;
}
@@ -1591,11 +1970,12 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
interrupted = 0;
signal(SIGINT, cmd_interrupt);
- err = parse_dispatch_command(conn, cmd, &pwd, batchmode);
+ err = parse_dispatch_command(conn, cmd, &remote_path,
+ batchmode);
if (err != 0)
break;
}
- xfree(pwd);
+ xfree(remote_path);
xfree(conn);
#ifdef USE_LIBEDIT
@@ -1647,9 +2027,11 @@ connect_to_server(char *path, char **args, int *in, int *out)
* The underlying ssh is in the same process group, so we must
* ignore SIGINT if we want to gracefully abort commands,
* otherwise the signal will make it to the ssh process and
- * kill it too
+ * kill it too. Contrawise, since sftp sends SIGTERMs to the
+ * underlying ssh, it must *not* ignore that signal.
*/
signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_DFL);
execvp(path, args);
fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
_exit(1);
@@ -1668,12 +2050,16 @@ usage(void)
extern char *__progname;
fprintf(stderr,
- "usage: %s [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]\n"
- " [-o ssh_option] [-P sftp_server_path] [-R num_requests]\n"
- " [-S program] [-s subsystem | sftp_server] host\n"
+ "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
+ " [-D sftp_server_path] [-F ssh_config] "
+ "[-i identity_file]\n"
+ " [-o ssh_option] [-P port] [-R num_requests] "
+ "[-S program]\n"
+ " [-s subsystem | sftp_server] host\n"
" %s [user@]host[:file ...]\n"
" %s [user@]host[:dir[/]]\n"
- " %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname);
+ " %s -b batchfile [user@]host\n",
+ __progname, __progname, __progname, __progname);
exit(1);
}
@@ -1681,7 +2067,7 @@ int
main(int argc, char **argv)
{
int in, out, ch, err;
- char *host, *userhost, *cp, *file2 = NULL;
+ char *host = NULL, *userhost, *cp, *file2 = NULL;
int debug_level = 0, sshver = 2;
char *file1 = NULL, *sftp_server = NULL;
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
@@ -1689,6 +2075,9 @@ main(int argc, char **argv)
arglist args;
extern int optind;
extern char *optarg;
+ struct sftp_conn *conn;
+ size_t copy_buffer_len = DEFAULT_COPY_BUFLEN;
+ size_t num_requests = DEFAULT_NUM_REQUESTS;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
@@ -1705,10 +2094,29 @@ main(int argc, char **argv)
ll = SYSLOG_LEVEL_INFO;
infile = stdin;
- while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
+ while ((ch = getopt(argc, argv,
+ "1246hpqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) {
switch (ch) {
+ /* Passed through to ssh(1) */
+ case '4':
+ case '6':
case 'C':
- addargs(&args, "-C");
+ addargs(&args, "-%c", ch);
+ break;
+ /* Passed through to ssh(1) with argument */
+ case 'F':
+ case 'c':
+ case 'i':
+ case 'o':
+ addargs(&args, "-%c", ch);
+ addargs(&args, "%s", optarg);
+ break;
+ case 'q':
+ showprogress = 0;
+ addargs(&args, "-%c", ch);
+ break;
+ case 'P':
+ addargs(&args, "-oPort %s", optarg);
break;
case 'v':
if (debug_level < 3) {
@@ -1717,21 +2125,18 @@ main(int argc, char **argv)
}
debug_level++;
break;
- case 'F':
- case 'o':
- addargs(&args, "-%c%s", ch, optarg);
- break;
case '1':
sshver = 1;
if (sftp_server == NULL)
sftp_server = _PATH_SFTP_SERVER;
break;
- case 's':
- sftp_server = optarg;
+ case '2':
+ sshver = 2;
break;
- case 'S':
- ssh_program = optarg;
- replacearg(&args, 0, "%s", ssh_program);
+ case 'B':
+ copy_buffer_len = strtol(optarg, &cp, 10);
+ if (copy_buffer_len == 0 || *cp != '\0')
+ fatal("Invalid buffer size \"%s\"", optarg);
break;
case 'b':
if (batchmode)
@@ -1745,13 +2150,14 @@ main(int argc, char **argv)
batchmode = 1;
addargs(&args, "-obatchmode yes");
break;
- case 'P':
+ case 'p':
+ global_pflag = 1;
+ break;
+ case 'D':
sftp_direct = optarg;
break;
- case 'B':
- copy_buffer_len = strtol(optarg, &cp, 10);
- if (copy_buffer_len == 0 || *cp != '\0')
- fatal("Invalid buffer size \"%s\"", optarg);
+ case 'r':
+ global_rflag = 1;
break;
case 'R':
num_requests = strtol(optarg, &cp, 10);
@@ -1759,6 +2165,13 @@ main(int argc, char **argv)
fatal("Invalid number of requests \"%s\"",
optarg);
break;
+ case 's':
+ sftp_server = optarg;
+ break;
+ case 'S':
+ ssh_program = optarg;
+ replacearg(&args, 0, "%s", ssh_program);
+ break;
case 'h':
default:
usage();
@@ -1785,7 +2198,8 @@ main(int argc, char **argv)
fprintf(stderr, "Missing username\n");
usage();
}
- addargs(&args, "-l%s", userhost);
+ addargs(&args, "-l");
+ addargs(&args, "%s", userhost);
}
if ((cp = colon(host)) != NULL) {
@@ -1805,24 +2219,32 @@ main(int argc, char **argv)
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
addargs(&args, "-s");
+ addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", (sftp_server != NULL ?
sftp_server : "sftp"));
- if (!batchmode)
- fprintf(stderr, "Connecting to %s...\n", host);
connect_to_server(ssh_program, args.list, &in, &out);
} else {
args.list = NULL;
addargs(&args, "sftp-server");
- if (!batchmode)
- fprintf(stderr, "Attaching to %s...\n", sftp_direct);
connect_to_server(sftp_direct, args.list, &in, &out);
}
freeargs(&args);
- err = interactive_loop(in, out, file1, file2);
+ conn = do_init(in, out, copy_buffer_len, num_requests);
+ if (conn == NULL)
+ fatal("Couldn't initialise connection to server");
+
+ if (!batchmode) {
+ if (sftp_direct == NULL)
+ fprintf(stderr, "Connected to %s.\n", host);
+ else
+ fprintf(stderr, "Attached to %s.\n", sftp_direct);
+ }
+
+ err = interactive_loop(conn, file1, file2);
#if !defined(USE_PIPES)
shutdown(in, SHUT_RDWR);
diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1
index 464070e..1eb34f3 100644
--- a/crypto/openssh/ssh-add.1
+++ b/crypto/openssh/ssh-add.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-add.1,v 1.46 2007/06/12 13:41:03 jmc Exp $
+.\" $OpenBSD: ssh-add.1,v 1.52 2010/03/05 10:28:21 djm Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -37,7 +37,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 12 2007
+.Dd March 5 2010
.Dt SSH-ADD 1
.Os
.Sh NAME
@@ -49,9 +49,9 @@
.Op Fl t Ar life
.Op Ar
.Nm ssh-add
-.Fl s Ar reader
+.Fl s Ar pkcs11
.Nm ssh-add
-.Fl e Ar reader
+.Fl e Ar pkcs11
.Sh DESCRIPTION
.Nm
adds RSA or DSA identities to the authentication agent,
@@ -61,7 +61,14 @@ When run without arguments, it adds the files
.Pa ~/.ssh/id_dsa
and
.Pa ~/.ssh/identity .
+After loading a private key,
+.Nm
+will try to load corresponding certificate information from the
+filename obtained by appending
+.Pa -cert.pub
+to the name of the private key file.
Alternative file names can be given on the command line.
+.Pp
If any file requires a passphrase,
.Nm
asks for the passphrase from the user.
@@ -101,17 +108,17 @@ If no public key is found at a given path,
will append
.Pa .pub
and retry.
-.It Fl e Ar reader
-Remove key in smartcard
-.Ar reader .
+.It Fl e Ar pkcs11
+Remove keys provided by the PKCS#11 shared library
+.Ar pkcs11 .
.It Fl L
Lists public key parameters of all identities currently represented
by the agent.
.It Fl l
Lists fingerprints of all identities currently represented by the agent.
-.It Fl s Ar reader
-Add key in smartcard
-.Ar reader .
+.It Fl s Ar pkcs11
+Add keys provided by the PKCS#11 shared library
+.Ar pkcs11 .
.It Fl t Ar life
Set a maximum lifetime when adding identities to an agent.
The lifetime may be specified in seconds or in a time format
@@ -148,8 +155,9 @@ may be necessary to redirect the input from
.Pa /dev/null
to make this work.)
.It Ev SSH_AUTH_SOCK
-Identifies the path of a unix-domain socket used to communicate with the
-agent.
+Identifies the path of a
+.Ux Ns -domain
+socket used to communicate with the agent.
.El
.Sh FILES
.Bl -tag -width Ds
diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c
index 7a43282..ad9f7a8 100644
--- a/crypto/openssh/ssh-add.c
+++ b/crypto/openssh/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.90 2007/09/09 11:38:01 sobrado Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.94 2010/03/01 11:07:06 otto Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -138,9 +138,9 @@ delete_all(AuthenticationConnection *ac)
static int
add_file(AuthenticationConnection *ac, const char *filename)
{
- Key *private;
+ Key *private, *cert;
char *comment = NULL;
- char msg[1024];
+ char msg[1024], *certpath;
int fd, perms_ok, ret = -1;
if ((fd = open(filename, O_RDONLY)) < 0) {
@@ -195,13 +195,37 @@ add_file(AuthenticationConnection *ac, const char *filename)
if (confirm != 0)
fprintf(stderr,
"The user has to confirm each use of the key\n");
- } else if (ssh_add_identity(ac, private, comment)) {
- fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
- ret = 0;
} else {
fprintf(stderr, "Could not add identity: %s\n", filename);
}
+
+ /* Now try to add the certificate flavour too */
+ xasprintf(&certpath, "%s-cert.pub", filename);
+ if ((cert = key_load_public(certpath, NULL)) != NULL) {
+ /* Graft with private bits */
+ if (key_to_certified(private) != 0)
+ fatal("%s: key_to_certified failed", __func__);
+ key_cert_copy(cert, private);
+ key_free(cert);
+
+ if (ssh_add_identity_constrained(ac, private, comment,
+ lifetime, confirm)) {
+ fprintf(stderr, "Certificate added: %s (%s)\n",
+ certpath, private->cert->key_id);
+ if (lifetime != 0)
+ fprintf(stderr, "Lifetime set to %d seconds\n",
+ lifetime);
+ if (confirm != 0)
+ fprintf(stderr, "The user has to confirm each "
+ "use of the key\n");
+ } else {
+ error("Certificate %s (%s) add failed", certpath,
+ private->cert->key_id);
+ }
+ }
+
+ xfree(certpath);
xfree(comment);
key_free(private);
@@ -214,7 +238,7 @@ update_card(AuthenticationConnection *ac, int add, const char *id)
char *pin;
int ret = -1;
- pin = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
+ pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN);
if (pin == NULL)
return -1;
@@ -320,10 +344,8 @@ usage(void)
fprintf(stderr, " -X Unlock agent.\n");
fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n");
fprintf(stderr, " -c Require confirmation to sign using identities\n");
-#ifdef SMARTCARD
- fprintf(stderr, " -s reader Add key in smartcard reader.\n");
- fprintf(stderr, " -e reader Remove key in smartcard reader.\n");
-#endif
+ fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n");
+ fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n");
}
int
@@ -332,7 +354,7 @@ main(int argc, char **argv)
extern char *optarg;
extern int optind;
AuthenticationConnection *ac = NULL;
- char *sc_reader_id = NULL;
+ char *pkcs11provider = NULL;
int i, ch, deleting = 0, ret = 0;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -374,11 +396,11 @@ main(int argc, char **argv)
ret = 1;
goto done;
case 's':
- sc_reader_id = optarg;
+ pkcs11provider = optarg;
break;
case 'e':
deleting = 1;
- sc_reader_id = optarg;
+ pkcs11provider = optarg;
break;
case 't':
if ((lifetime = convtime(optarg)) == -1) {
@@ -395,8 +417,8 @@ main(int argc, char **argv)
}
argc -= optind;
argv += optind;
- if (sc_reader_id != NULL) {
- if (update_card(ac, !deleting, sc_reader_id) == -1)
+ if (pkcs11provider != NULL) {
+ if (update_card(ac, !deleting, pkcs11provider) == -1)
ret = 1;
goto done;
}
diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1
index bc38900..5bcfd8f 100644
--- a/crypto/openssh/ssh-agent.1
+++ b/crypto/openssh/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.47 2009/03/26 08:38:39 sobrado Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.50 2010/01/17 21:49:09 tedu Exp $
.\" $FreeBSD$
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd March 26 2009
+.Dd January 17 2010
.Dt SSH-AGENT 1
.Os
.Sh NAME
@@ -68,7 +68,9 @@ machines using
The options are as follows:
.Bl -tag -width Ds
.It Fl a Ar bind_address
-Bind the agent to the unix-domain socket
+Bind the agent to the
+.Ux Ns -domain
+socket
.Ar bind_address .
The default is
.Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .
@@ -118,8 +120,9 @@ and
.Pa ~/.ssh/identity .
If the identity has a passphrase,
.Xr ssh-add 1
-asks for the passphrase (using a small X11 application if running
-under X11, or from the terminal if running without X).
+asks for the passphrase on the terminal if it has one or from a small X11
+program if running under X11.
+If neither of these is the case then the authentication will fail.
It then sends the identity to the agent.
Several identities can be stored in the
agent; the agent can automatically use any of these identities.
@@ -163,8 +166,9 @@ Instead, operations that require a private key will be performed
by the agent, and the result will be returned to the requester.
This way, private keys are not exposed to clients using the agent.
.Pp
-A unix-domain socket is created
-and the name of this socket is stored in the
+A
+.Ux Ns -domain
+socket is created and the name of this socket is stored in the
.Ev SSH_AUTH_SOCK
environment
variable.
@@ -187,8 +191,8 @@ Contains the protocol version 2 DSA authentication identity of the user.
.It Pa ~/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of the user.
.It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt
-Unix-domain sockets used to contain the connection to the
-authentication agent.
+.Ux Ns -domain
+sockets used to contain the connection to the authentication agent.
These sockets should only be readable by the owner.
The sockets should get automatically removed when the agent exits.
.El
diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c
index 1fdf529..320591b 100644
--- a/crypto/openssh/ssh-agent.c
+++ b/crypto/openssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.165 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -77,8 +77,8 @@ __RCSID("$FreeBSD$");
#include "log.h"
#include "misc.h"
-#ifdef SMARTCARD
-#include "scard.h"
+#ifdef ENABLE_PKCS11
+#include "ssh-pkcs11.h"
#endif
#if defined(HAVE_SYS_PRCTL_H)
@@ -106,6 +106,7 @@ typedef struct identity {
TAILQ_ENTRY(identity) next;
Key *key;
char *comment;
+ char *provider;
u_int death;
u_int confirm;
} Identity;
@@ -172,6 +173,8 @@ static void
free_identity(Identity *id)
{
key_free(id->key);
+ if (id->provider != NULL)
+ xfree(id->provider);
xfree(id->comment);
xfree(id);
}
@@ -466,6 +469,8 @@ process_add_identity(SocketEntry *e, int version)
int type, success = 0, death = 0, confirm = 0;
char *type_name, *comment;
Key *k = NULL;
+ u_char *cert;
+ u_int len;
switch (version) {
case 1:
@@ -496,6 +501,14 @@ process_add_identity(SocketEntry *e, int version)
buffer_get_bignum2(&e->request, k->dsa->pub_key);
buffer_get_bignum2(&e->request, k->dsa->priv_key);
break;
+ case KEY_DSA_CERT:
+ cert = buffer_get_string(&e->request, &len);
+ if ((k = key_from_blob(cert, len)) == NULL)
+ fatal("Certificate parse failed");
+ xfree(cert);
+ key_add_private(k);
+ buffer_get_bignum2(&e->request, k->dsa->priv_key);
+ break;
case KEY_RSA:
k = key_new_private(type);
buffer_get_bignum2(&e->request, k->rsa->n);
@@ -508,6 +521,17 @@ process_add_identity(SocketEntry *e, int version)
/* Generate additional parameters */
rsa_generate_additional_parameters(k->rsa);
break;
+ case KEY_RSA_CERT:
+ cert = buffer_get_string(&e->request, &len);
+ if ((k = key_from_blob(cert, len)) == NULL)
+ fatal("Certificate parse failed");
+ xfree(cert);
+ key_add_private(k);
+ buffer_get_bignum2(&e->request, k->rsa->d);
+ buffer_get_bignum2(&e->request, k->rsa->iqmp);
+ buffer_get_bignum2(&e->request, k->rsa->p);
+ buffer_get_bignum2(&e->request, k->rsa->q);
+ break;
default:
buffer_clear(&e->request);
goto send;
@@ -517,6 +541,7 @@ process_add_identity(SocketEntry *e, int version)
/* enable blinding */
switch (k->type) {
case KEY_RSA:
+ case KEY_RSA_CERT:
case KEY_RSA1:
if (RSA_blinding_on(k->rsa, NULL) != 1) {
error("process_add_identity: RSA_blinding_on failed");
@@ -550,7 +575,7 @@ process_add_identity(SocketEntry *e, int version)
if (lifetime && !death)
death = time(NULL) + lifetime;
if ((id = lookup_identity(k, version)) == NULL) {
- id = xmalloc(sizeof(Identity));
+ id = xcalloc(1, sizeof(Identity));
id->key = k;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
/* Increment the number of identities. */
@@ -610,17 +635,17 @@ no_identities(SocketEntry *e, u_int type)
buffer_free(&msg);
}
-#ifdef SMARTCARD
+#ifdef ENABLE_PKCS11
static void
process_add_smartcard_key(SocketEntry *e)
{
- char *sc_reader_id = NULL, *pin;
- int i, type, version, success = 0, death = 0, confirm = 0;
- Key **keys, *k;
+ char *provider = NULL, *pin;
+ int i, type, version, count = 0, success = 0, death = 0, confirm = 0;
+ Key **keys = NULL, *k;
Identity *id;
Idtab *tab;
- sc_reader_id = buffer_get_string(&e->request, NULL);
+ provider = buffer_get_string(&e->request, NULL);
pin = buffer_get_string(&e->request, NULL);
while (buffer_len(&e->request)) {
@@ -634,30 +659,22 @@ process_add_smartcard_key(SocketEntry *e)
default:
error("process_add_smartcard_key: "
"Unknown constraint type %d", type);
- xfree(sc_reader_id);
- xfree(pin);
goto send;
}
}
if (lifetime && !death)
death = time(NULL) + lifetime;
- keys = sc_get_keys(sc_reader_id, pin);
- xfree(sc_reader_id);
- xfree(pin);
-
- if (keys == NULL || keys[0] == NULL) {
- error("sc_get_keys failed");
- goto send;
- }
- for (i = 0; keys[i] != NULL; i++) {
+ count = pkcs11_add_provider(provider, pin, &keys);
+ for (i = 0; i < count; i++) {
k = keys[i];
version = k->type == KEY_RSA1 ? 1 : 2;
tab = idtab_lookup(version);
if (lookup_identity(k, version) == NULL) {
- id = xmalloc(sizeof(Identity));
+ id = xcalloc(1, sizeof(Identity));
id->key = k;
- id->comment = sc_get_key_label(k);
+ id->provider = xstrdup(provider);
+ id->comment = xstrdup(provider); /* XXX */
id->death = death;
id->confirm = confirm;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@@ -668,8 +685,13 @@ process_add_smartcard_key(SocketEntry *e)
}
keys[i] = NULL;
}
- xfree(keys);
send:
+ if (pin)
+ xfree(pin);
+ if (provider)
+ xfree(provider);
+ if (keys)
+ xfree(keys);
buffer_put_int(&e->output, 1);
buffer_put_char(&e->output,
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
@@ -678,42 +700,37 @@ send:
static void
process_remove_smartcard_key(SocketEntry *e)
{
- char *sc_reader_id = NULL, *pin;
- int i, version, success = 0;
- Key **keys, *k = NULL;
- Identity *id;
+ char *provider = NULL, *pin = NULL;
+ int version, success = 0;
+ Identity *id, *nxt;
Idtab *tab;
- sc_reader_id = buffer_get_string(&e->request, NULL);
+ provider = buffer_get_string(&e->request, NULL);
pin = buffer_get_string(&e->request, NULL);
- keys = sc_get_keys(sc_reader_id, pin);
- xfree(sc_reader_id);
xfree(pin);
- if (keys == NULL || keys[0] == NULL) {
- error("sc_get_keys failed");
- goto send;
- }
- for (i = 0; keys[i] != NULL; i++) {
- k = keys[i];
- version = k->type == KEY_RSA1 ? 1 : 2;
- if ((id = lookup_identity(k, version)) != NULL) {
- tab = idtab_lookup(version);
- TAILQ_REMOVE(&tab->idlist, id, next);
- tab->nentries--;
- free_identity(id);
- success = 1;
+ for (version = 1; version < 3; version++) {
+ tab = idtab_lookup(version);
+ for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
+ nxt = TAILQ_NEXT(id, next);
+ if (!strcmp(provider, id->provider)) {
+ TAILQ_REMOVE(&tab->idlist, id, next);
+ free_identity(id);
+ tab->nentries--;
+ }
}
- key_free(k);
- keys[i] = NULL;
}
- xfree(keys);
-send:
+ if (pkcs11_del_provider(provider) == 0)
+ success = 1;
+ else
+ error("process_remove_smartcard_key:"
+ " pkcs11_del_provider failed");
+ xfree(provider);
buffer_put_int(&e->output, 1);
buffer_put_char(&e->output,
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
}
-#endif /* SMARTCARD */
+#endif /* ENABLE_PKCS11 */
/* dispatch incoming messages */
@@ -798,7 +815,7 @@ process_message(SocketEntry *e)
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
process_remove_all_identities(e, 2);
break;
-#ifdef SMARTCARD
+#ifdef ENABLE_PKCS11
case SSH_AGENTC_ADD_SMARTCARD_KEY:
case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
process_add_smartcard_key(e);
@@ -806,7 +823,7 @@ process_message(SocketEntry *e)
case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
process_remove_smartcard_key(e);
break;
-#endif /* SMARTCARD */
+#endif /* ENABLE_PKCS11 */
default:
/* Unknown message. Respond with failure. */
error("Unknown message %d", type);
@@ -920,11 +937,11 @@ after_select(fd_set *readset, fd_set *writeset)
socklen_t slen;
char buf[1024];
int len, sock;
- u_int i;
+ u_int i, orig_alloc;
uid_t euid;
gid_t egid;
- for (i = 0; i < sockets_alloc; i++)
+ for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
switch (sockets[i].type) {
case AUTH_UNUSED:
break;
@@ -957,16 +974,13 @@ after_select(fd_set *readset, fd_set *writeset)
case AUTH_CONNECTION:
if (buffer_len(&sockets[i].output) > 0 &&
FD_ISSET(sockets[i].fd, writeset)) {
- do {
- len = write(sockets[i].fd,
- buffer_ptr(&sockets[i].output),
- buffer_len(&sockets[i].output));
- if (len == -1 && (errno == EAGAIN ||
- errno == EINTR ||
- errno == EWOULDBLOCK))
- continue;
- break;
- } while (1);
+ len = write(sockets[i].fd,
+ buffer_ptr(&sockets[i].output),
+ buffer_len(&sockets[i].output));
+ if (len == -1 && (errno == EAGAIN ||
+ errno == EWOULDBLOCK ||
+ errno == EINTR))
+ continue;
if (len <= 0) {
close_socket(&sockets[i]);
break;
@@ -974,14 +988,11 @@ after_select(fd_set *readset, fd_set *writeset)
buffer_consume(&sockets[i].output, len);
}
if (FD_ISSET(sockets[i].fd, readset)) {
- do {
- len = read(sockets[i].fd, buf, sizeof(buf));
- if (len == -1 && (errno == EAGAIN ||
- errno == EINTR ||
- errno == EWOULDBLOCK))
- continue;
- break;
- } while (1);
+ len = read(sockets[i].fd, buf, sizeof(buf));
+ if (len == -1 && (errno == EAGAIN ||
+ errno == EWOULDBLOCK ||
+ errno == EINTR))
+ continue;
if (len <= 0) {
close_socket(&sockets[i]);
break;
@@ -1016,6 +1027,9 @@ static void
cleanup_handler(int sig)
{
cleanup_socket();
+#ifdef ENABLE_PKCS11
+ pkcs11_terminate();
+#endif
_exit(2);
}
@@ -1263,6 +1277,10 @@ main(int ac, char **av)
#endif
skip:
+
+#ifdef ENABLE_PKCS11
+ pkcs11_init(0);
+#endif
new_socket(AUTH_SOCKET, sock);
if (ac > 0)
parent_alive_interval = 10;
diff --git a/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c
index 51a06e9..449f493 100644
--- a/crypto/openssh/ssh-dss.c
+++ b/crypto/openssh/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.24 2006/11/06 21:25:28 markus Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.25 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -53,7 +53,9 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
u_int rlen, slen, len, dlen;
Buffer b;
- if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
+ if (key == NULL ||
+ (key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
+ key->dsa == NULL) {
error("ssh_dss_sign: no DSA key");
return -1;
}
@@ -116,7 +118,9 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
int rlen, ret;
Buffer b;
- if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
+ if (key == NULL ||
+ (key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
+ key->dsa == NULL) {
error("ssh_dss_verify: no DSA key");
return -1;
}
diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1
index 4247ea1..0da6354 100644
--- a/crypto/openssh/ssh-keygen.1
+++ b/crypto/openssh/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.79 2008/07/24 23:55:30 sthen Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.88 2010/03/08 00:28:55 djm Exp $
.\" $FreeBSD$
.\"
.\" -*- nroff -*-
@@ -38,7 +38,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 24 2008
+.Dd March 8 2010
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@@ -53,7 +53,6 @@
.Op Fl N Ar new_passphrase
.Op Fl C Ar comment
.Op Fl f Ar output_keyfile
-.Ek
.Nm ssh-keygen
.Fl p
.Op Fl P Ar old_passphrase
@@ -80,7 +79,7 @@
.Fl B
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
-.Fl D Ar reader
+.Fl D Ar pkcs11
.Nm ssh-keygen
.Fl F Ar hostname
.Op Fl f Ar known_hosts_file
@@ -92,9 +91,6 @@
.Fl R Ar hostname
.Op Fl f Ar known_hosts_file
.Nm ssh-keygen
-.Fl U Ar reader
-.Op Fl f Ar input_keyfile
-.Nm ssh-keygen
.Fl r Ar hostname
.Op Fl f Ar input_keyfile
.Op Fl g
@@ -110,6 +106,18 @@
.Op Fl v
.Op Fl a Ar num_trials
.Op Fl W Ar generator
+.Nm ssh-keygen
+.Fl s Ar ca_key
+.Fl I Ar certificate_identity
+.Op Fl h
+.Op Fl n Ar principals
+.Op Fl O Ar constraint
+.Op Fl V Ar validity_interval
+.Ar
+.Nm ssh-keygen
+.Fl L
+.Op Fl f Ar input_keyfile
+.Ek
.Sh DESCRIPTION
.Nm
generates, manages and converts authentication keys for
@@ -202,9 +210,9 @@ Requests changing the comment in the private and public key files.
This operation is only supported for RSA1 keys.
The program will prompt for the file containing the private keys, for
the passphrase if the key has one, and for the new comment.
-.It Fl D Ar reader
-Download the RSA public key stored in the smartcard in
-.Ar reader .
+.It Fl D Ar pkcs11
+Download the RSA public keys provided by the PKCS#11 shared library
+.Ar pkcs11 .
.It Fl e
This option will read a private or public OpenSSH key file and
print the key in
@@ -249,6 +257,17 @@ but they do not reveal identifying information should the file's contents
be disclosed.
This option will not modify existing hashed hostnames and is therefore safe
to use on files that mix hashed and non-hashed names.
+.It Fl h
+When signing a key, create a host certificate instead of a user
+certificate.
+Please see the
+.Sx CERTIFICATES
+section for details.
+.It Fl I Ar certificate_identity
+Specify the key identity when signing a public key.
+Please see the
+.Sx CERTIFICATES
+section for details.
.It Fl i
This option will read an unencrypted private (or public) key file
in SSH2-compatible format and print an OpenSSH compatible private
@@ -258,6 +277,8 @@ also reads the
RFC 4716 SSH Public Key File Format.
This option allows importing keys from several commercial
SSH implementations.
+.It Fl L
+Prints the contents of a certificate.
.It Fl l
Show fingerprint of specified public key file.
Private RSA1 keys are also supported.
@@ -272,6 +293,71 @@ Specify the amount of memory to use (in megabytes) when generating
candidate moduli for DH-GEX.
.It Fl N Ar new_passphrase
Provides the new passphrase.
+.It Fl n Ar principals
+Specify one or more principals (user or host names) to be included in
+a certificate when signing a key.
+Multiple principals may be specified, separated by commas.
+Please see the
+.Sx CERTIFICATES
+section for details.
+.It Fl O Ar constraint
+Specify a certificate constraint when signing a key.
+This option may be specified multiple times.
+Please see the
+.Sx CERTIFICATES
+section for details.
+The constraints that are valid for user certificates are:
+.Bl -tag -width Ds
+.It Ic no-x11-forwarding
+Disable X11 forwarding (permitted by default).
+.It Ic no-agent-forwarding
+Disable
+.Xr ssh-agent 1
+forwarding (permitted by default).
+.It Ic no-port-forwarding
+Disable port forwarding (permitted by default).
+.It Ic no-pty
+Disable PTY allocation (permitted by default).
+.It Ic no-user-rc
+Disable execution of
+.Pa ~/.ssh/rc
+by
+.Xr sshd 8
+(permitted by default).
+.It Ic clear
+Clear all enabled permissions.
+This is useful for clearing the default set of permissions so permissions may
+be added individually.
+.It Ic permit-x11-forwarding
+Allows X11 forwarding.
+.It Ic permit-agent-forwarding
+Allows
+.Xr ssh-agent 1
+forwarding.
+.It Ic permit-port-forwarding
+Allows port forwarding.
+.It Ic permit-pty
+Allows PTY allocation.
+.It Ic permit-user-rc
+Allows execution of
+.Pa ~/.ssh/rc
+by
+.Xr sshd 8 .
+.It Ic force-command=command
+Forces the execution of
+.Ar command
+instead of any shell or command specified by the user when
+the certificate is used for authentication.
+.It Ic source-address=address_list
+Restrict the source addresses from which the certificate is considered valid
+from.
+The
+.Ar address_list
+is a comma-separated list of one or more address/netmask pairs in CIDR
+format.
+.El
+.Pp
+At present, no constraints are valid for host keys.
.It Fl P Ar passphrase
Provides the (old) passphrase.
.It Fl p
@@ -301,6 +387,11 @@ Print the SSHFP fingerprint resource record named
for the specified public key file.
.It Fl S Ar start
Specify start point (in hex) when generating candidate moduli for DH-GEX.
+.It Fl s Ar ca_key
+Certify (sign) a public key using the specified CA key.
+Please see the
+.Sx CERTIFICATES
+section for details.
.It Fl T Ar output_file
Test DH group exchange candidate primes (generated using the
.Fl G
@@ -314,9 +405,29 @@ for protocol version 1 and
or
.Dq dsa
for protocol version 2.
-.It Fl U Ar reader
-Upload an existing RSA private key into the smartcard in
-.Ar reader .
+.It Fl V Ar validity_interval
+Specify a validity interval when signing a certificate.
+A validity interval may consist of a single time, indicating that the
+certificate is valid beginning now and expiring at that time, or may consist
+of two times separated by a colon to indicate an explicit time interval.
+The start time may be specified as a date in YYYYMMDD format, a time
+in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting
+of a minus sign followed by a relative time in the format described in the
+.Sx TIME FORMATS
+section of
+.Xr ssh_config 5 .
+The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
+a relative time starting with a plus character.
+.Pp
+For example:
+.Dq +52w1d
+(valid from now to 52 weeks and one day from now),
+.Dq -4w:+4w
+(valid from four weeks ago to four weeks from now),
+.Dq 20100101123000:20110101123000
+(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
+.Dq -1d:20110101
+(valid from yesterday to midnight, January 1st, 2011).
.It Fl v
Verbose mode.
Causes
@@ -387,6 +498,73 @@ Screened DH groups may be installed in
.Pa /etc/moduli .
It is important that this file contains moduli of a range of bit lengths and
that both ends of a connection share common moduli.
+.Sh CERTIFICATES
+.Nm
+supports signing of keys to produce certificates that may be used for
+user or host authentication.
+Certificates consist of a public key, some identity information, zero or
+more principal (user or host) names and an optional set of constraints that
+are signed by a Certification Authority (CA) key.
+Clients or servers may then trust only the CA key and verify its signature
+on a certificate rather than trusting many user/host keys.
+Note that OpenSSH certificates are a different, and much simpler, format to
+the X.509 certificates used in
+.Xr ssl 8 .
+.Pp
+.Nm
+supports two types of certificates: user and host.
+User certificates authenticate users to servers, whereas host certificates
+authenticate server hosts to users.
+To generate a user certificate:
+.Pp
+.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
+.Pp
+The resultant certificate will be placed in
+.Pa /path/to/user_key_cert.pub .
+A host certificate requires the
+.Fl h
+option:
+.Pp
+.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
+.Pp
+The host certificate will be output to
+.Pa /path/to/host_key_cert.pub .
+In both cases,
+.Ar key_id
+is a "key identifier" that is logged by the server when the certificate
+is used for authentication.
+.Pp
+Certificates may be limited to be valid for a set of principal (user/host)
+names.
+By default, generated certificates are valid for all users or hosts.
+To generate a certificate for a specified set of principals:
+.Pp
+.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
+.Dl $ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub
+.Pp
+Additional limitations on the validity and use of user certificates may
+be specified through certificate constraints.
+A constrained certificate may disable features of the SSH session, may be
+valid only when presented from particular source addresses or may
+force the use of a specific command.
+For a list of valid certificate constraints, see the documentation for the
+.Fl O
+option above.
+.Pp
+Finally, certificates may be defined with a validity lifetime.
+The
+.Fl V
+option allows specification of certificate start and end times.
+A certificate that is presented at a time outside this range will not be
+considered valid.
+By default, certificates have a maximum validity interval.
+.Pp
+For certificates to be used for user or host authentication, the CA
+public key must be trusted by
+.Xr sshd 8
+or
+.Xr ssh 1 .
+Please refer to those manual pages for details.
.Sh FILES
.Bl -tag -width Ds
.It Pa ~/.ssh/identity
@@ -394,7 +572,7 @@ Contains the protocol version 1 RSA authentication identity of the user.
This file should not be readable by anyone but the user.
It is possible to
specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file using 3DES.
+used to encrypt the private part of this file using 128-bit AES.
This file is not automatically accessed by
.Nm
but it is offered as the default file for the private key.
@@ -412,7 +590,7 @@ Contains the protocol version 2 DSA authentication identity of the user.
This file should not be readable by anyone but the user.
It is possible to
specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file using 3DES.
+used to encrypt the private part of this file using 128-bit AES.
This file is not automatically accessed by
.Nm
but it is offered as the default file for the private key.
@@ -430,7 +608,7 @@ Contains the protocol version 2 RSA authentication identity of the user.
This file should not be readable by anyone but the user.
It is possible to
specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file using 3DES.
+used to encrypt the private part of this file using 128-bit AES.
This file is not automatically accessed by
.Nm
but it is offered as the default file for the private key.
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
index da5db98..dd662c9 100644
--- a/crypto/openssh/ssh-keygen.c
+++ b/crypto/openssh/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.174 2009/06/22 05:39:28 dtucker Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.184 2010/03/07 22:16:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -48,9 +48,10 @@
#include "match.h"
#include "hostfile.h"
#include "dns.h"
+#include "ssh2.h"
-#ifdef SMARTCARD
-#include "scard.h"
+#ifdef ENABLE_PKCS11
+#include "ssh-pkcs11.h"
#endif
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
@@ -81,6 +82,9 @@ int find_host = 0;
/* Flag indicating that we want to delete a host from a known_hosts file */
int delete_host = 0;
+/* Flag indicating that we want to show the contents of a certificate */
+int show_cert = 0;
+
/* Flag indicating that we just want to see the key fingerprint */
int print_fingerprint = 0;
int print_bubblebabble = 0;
@@ -98,6 +102,35 @@ char *identity_new_passphrase = NULL;
/* This is set to the new comment if given on the command line. */
char *identity_comment = NULL;
+/* Path to CA key when certifying keys. */
+char *ca_key_path = NULL;
+
+/* Key type when certifying */
+u_int cert_key_type = SSH2_CERT_TYPE_USER;
+
+/* "key ID" of signed key */
+char *cert_key_id = NULL;
+
+/* Comma-separated list of principal names for certifying keys */
+char *cert_principals = NULL;
+
+/* Validity period for certificates */
+u_int64_t cert_valid_from = 0;
+u_int64_t cert_valid_to = ~0ULL;
+
+/* Certificate constraints */
+#define CONSTRAINT_X_FWD (1)
+#define CONSTRAINT_AGENT_FWD (1<<1)
+#define CONSTRAINT_PORT_FWD (1<<2)
+#define CONSTRAINT_PTY (1<<3)
+#define CONSTRAINT_USER_RC (1<<4)
+#define CONSTRAINT_DEFAULT (CONSTRAINT_X_FWD|CONSTRAINT_AGENT_FWD| \
+ CONSTRAINT_PORT_FWD|CONSTRAINT_PTY| \
+ CONSTRAINT_USER_RC)
+u_int32_t constraint_flags = CONSTRAINT_DEFAULT;
+char *constraint_command = NULL;
+char *constraint_src_addr = NULL;
+
/* Dump public key file in format used by real and the original SSH 2 */
int convert_to_ssh2 = 0;
int convert_from_ssh2 = 0;
@@ -181,6 +214,7 @@ do_convert_to_ssh2(struct passwd *pw)
Key *k;
u_int len;
u_char *blob;
+ char comment[61];
struct stat st;
if (!have_identity)
@@ -203,11 +237,14 @@ do_convert_to_ssh2(struct passwd *pw)
fprintf(stderr, "key_to_blob failed\n");
exit(1);
}
- fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
- fprintf(stdout,
- "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n",
+ /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
+ snprintf(comment, sizeof(comment),
+ "%u-bit %s, converted by %s@%s from OpenSSH",
key_size(k), key_type(k),
pw->pw_name, hostname);
+
+ fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
+ fprintf(stdout, "Comment: \"%s\"\n", comment);
dump_base64(stdout, blob, len);
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
key_free(k);
@@ -455,51 +492,29 @@ do_print_public(struct passwd *pw)
exit(0);
}
-#ifdef SMARTCARD
static void
-do_upload(struct passwd *pw, const char *sc_reader_id)
-{
- Key *prv = NULL;
- struct stat st;
- int ret;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- prv = load_identity(identity_file);
- if (prv == NULL) {
- error("load failed");
- exit(1);
- }
- ret = sc_put_key(prv, sc_reader_id);
- key_free(prv);
- if (ret < 0)
- exit(1);
- logit("loading key done");
- exit(0);
-}
-
-static void
-do_download(struct passwd *pw, const char *sc_reader_id)
+do_download(struct passwd *pw, char *pkcs11provider)
{
+#ifdef ENABLE_PKCS11
Key **keys = NULL;
- int i;
+ int i, nkeys;
- keys = sc_get_keys(sc_reader_id, NULL);
- if (keys == NULL)
- fatal("cannot read public key from smartcard");
- for (i = 0; keys[i]; i++) {
+ pkcs11_init(0);
+ nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
+ if (nkeys <= 0)
+ fatal("cannot read public key from pkcs11");
+ for (i = 0; i < nkeys; i++) {
key_write(keys[i], stdout);
key_free(keys[i]);
fprintf(stdout, "\n");
}
xfree(keys);
+ pkcs11_terminate();
exit(0);
+#else
+ fatal("no pkcs11 support");
+#endif /* ENABLE_PKCS11 */
}
-#endif /* SMARTCARD */
static void
do_fingerprint(struct passwd *pw)
@@ -524,7 +539,7 @@ do_fingerprint(struct passwd *pw)
public = key_load_public(identity_file, &comment);
if (public != NULL) {
fp = key_fingerprint(public, fptype, rep);
- ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
+ ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
printf("%u %s %s (%s)\n", key_size(public), fp, comment,
key_type(public));
if (log_level >= SYSLOG_LEVEL_VERBOSE)
@@ -589,7 +604,7 @@ do_fingerprint(struct passwd *pw)
}
comment = *cp ? cp : comment;
fp = key_fingerprint(public, fptype, rep);
- ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
+ ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
printf("%u %s %s (%s)\n", key_size(public), fp,
comment ? comment : "no comment", key_type(public));
if (log_level >= SYSLOG_LEVEL_VERBOSE)
@@ -609,7 +624,7 @@ do_fingerprint(struct passwd *pw)
}
static void
-print_host(FILE *f, const char *name, Key *public, int hash)
+printhost(FILE *f, const char *name, Key *public, int ca, int hash)
{
if (print_fingerprint) {
enum fp_rep rep;
@@ -619,7 +634,7 @@ print_host(FILE *f, const char *name, Key *public, int hash)
fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
fp = key_fingerprint(public, fptype, rep);
- ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
+ ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
printf("%u %s %s (%s)\n", key_size(public), fp, name,
key_type(public));
if (log_level >= SYSLOG_LEVEL_VERBOSE)
@@ -629,7 +644,7 @@ print_host(FILE *f, const char *name, Key *public, int hash)
} else {
if (hash && (name = host_hash(name, NULL, 0)) == NULL)
fatal("hash_host failed");
- fprintf(f, "%s ", name);
+ fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name);
if (!key_write(public, f))
fatal("key_write failed");
fprintf(f, "\n");
@@ -640,10 +655,11 @@ static void
do_known_hosts(struct passwd *pw, const char *name)
{
FILE *in, *out = stdout;
- Key *public;
+ Key *pub;
char *cp, *cp2, *kp, *kp2;
char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
+ int ca;
if (!have_identity) {
cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -699,9 +715,19 @@ do_known_hosts(struct passwd *pw, const char *name)
fprintf(out, "%s\n", cp);
continue;
}
+ /* Check whether this is a CA key */
+ if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
+ (cp[sizeof(CA_MARKER) - 1] == ' ' ||
+ cp[sizeof(CA_MARKER) - 1] == '\t')) {
+ ca = 1;
+ cp += sizeof(CA_MARKER);
+ } else
+ ca = 0;
+
/* Find the end of the host name portion. */
for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
;
+
if (*kp == '\0' || *(kp + 1) == '\0') {
error("line %d missing key: %.40s...",
num, line);
@@ -711,15 +737,15 @@ do_known_hosts(struct passwd *pw, const char *name)
*kp++ = '\0';
kp2 = kp;
- public = key_new(KEY_RSA1);
- if (key_read(public, &kp) != 1) {
+ pub = key_new(KEY_RSA1);
+ if (key_read(pub, &kp) != 1) {
kp = kp2;
- key_free(public);
- public = key_new(KEY_UNSPEC);
- if (key_read(public, &kp) != 1) {
+ key_free(pub);
+ pub = key_new(KEY_UNSPEC);
+ if (key_read(pub, &kp) != 1) {
error("line %d invalid key: %.40s...",
num, line);
- key_free(public);
+ key_free(pub);
invalid = 1;
continue;
}
@@ -737,43 +763,52 @@ do_known_hosts(struct passwd *pw, const char *name)
c = (strcmp(cp2, cp) == 0);
if (find_host && c) {
printf("# Host %s found: "
- "line %d type %s\n", name,
- num, key_type(public));
- print_host(out, cp, public, 0);
+ "line %d type %s%s\n", name,
+ num, key_type(pub),
+ ca ? " (CA key)" : "");
+ printhost(out, cp, pub, ca, 0);
}
- if (delete_host && !c)
- print_host(out, cp, public, 0);
+ if (delete_host && !c && !ca)
+ printhost(out, cp, pub, ca, 0);
} else if (hash_hosts)
- print_host(out, cp, public, 0);
+ printhost(out, cp, pub, ca, 0);
} else {
if (find_host || delete_host) {
c = (match_hostname(name, cp,
strlen(cp)) == 1);
if (find_host && c) {
printf("# Host %s found: "
- "line %d type %s\n", name,
- num, key_type(public));
- print_host(out, name, public,
- hash_hosts);
+ "line %d type %s%s\n", name,
+ num, key_type(pub),
+ ca ? " (CA key)" : "");
+ printhost(out, name, pub,
+ ca, hash_hosts && !ca);
}
- if (delete_host && !c)
- print_host(out, cp, public, 0);
+ if (delete_host && !c && !ca)
+ printhost(out, cp, pub, ca, 0);
} else if (hash_hosts) {
for (cp2 = strsep(&cp, ",");
cp2 != NULL && *cp2 != '\0';
cp2 = strsep(&cp, ",")) {
- if (strcspn(cp2, "*?!") != strlen(cp2))
+ if (ca) {
+ fprintf(stderr, "Warning: "
+ "ignoring CA key for host: "
+ "%.64s\n", cp2);
+ printhost(out, cp2, pub, ca, 0);
+ } else if (strcspn(cp2, "*?!") !=
+ strlen(cp2)) {
fprintf(stderr, "Warning: "
"ignoring host name with "
"metacharacters: %.64s\n",
cp2);
- else
- print_host(out, cp2, public, 1);
+ printhost(out, cp2, pub, ca, 0);
+ } else
+ printhost(out, cp2, pub, ca, 1);
}
has_unhashed = 1;
}
}
- key_free(public);
+ key_free(pub);
}
fclose(in);
@@ -1030,6 +1065,391 @@ do_change_comment(struct passwd *pw)
exit(0);
}
+static const char *
+fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
+{
+ char from[32], to[32];
+ static char ret[64];
+ time_t tt;
+ struct tm *tm;
+
+ *from = *to = '\0';
+ if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
+ return "forever";
+
+ if (valid_from != 0) {
+ /* XXX revisit INT_MAX in 2038 :) */
+ tt = valid_from > INT_MAX ? INT_MAX : valid_from;
+ tm = localtime(&tt);
+ strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
+ }
+ if (valid_to != 0xffffffffffffffffULL) {
+ /* XXX revisit INT_MAX in 2038 :) */
+ tt = valid_to > INT_MAX ? INT_MAX : valid_to;
+ tm = localtime(&tt);
+ strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
+ }
+
+ if (valid_from == 0) {
+ snprintf(ret, sizeof(ret), "before %s", to);
+ return ret;
+ }
+ if (valid_to == 0xffffffffffffffffULL) {
+ snprintf(ret, sizeof(ret), "after %s", from);
+ return ret;
+ }
+
+ snprintf(ret, sizeof(ret), "from %s to %s", from, to);
+ return ret;
+}
+
+static void
+add_flag_constraint(Buffer *c, const char *name)
+{
+ debug3("%s: %s", __func__, name);
+ buffer_put_cstring(c, name);
+ buffer_put_string(c, NULL, 0);
+}
+
+static void
+add_string_constraint(Buffer *c, const char *name, const char *value)
+{
+ Buffer b;
+
+ debug3("%s: %s=%s", __func__, name, value);
+ buffer_init(&b);
+ buffer_put_cstring(&b, value);
+
+ buffer_put_cstring(c, name);
+ buffer_put_string(c, buffer_ptr(&b), buffer_len(&b));
+
+ buffer_free(&b);
+}
+
+static void
+prepare_constraint_buf(Buffer *c)
+{
+
+ buffer_clear(c);
+ if ((constraint_flags & CONSTRAINT_X_FWD) != 0)
+ add_flag_constraint(c, "permit-X11-forwarding");
+ if ((constraint_flags & CONSTRAINT_AGENT_FWD) != 0)
+ add_flag_constraint(c, "permit-agent-forwarding");
+ if ((constraint_flags & CONSTRAINT_PORT_FWD) != 0)
+ add_flag_constraint(c, "permit-port-forwarding");
+ if ((constraint_flags & CONSTRAINT_PTY) != 0)
+ add_flag_constraint(c, "permit-pty");
+ if ((constraint_flags & CONSTRAINT_USER_RC) != 0)
+ add_flag_constraint(c, "permit-user-rc");
+ if (constraint_command != NULL)
+ add_string_constraint(c, "force-command", constraint_command);
+ if (constraint_src_addr != NULL)
+ add_string_constraint(c, "source-address", constraint_src_addr);
+}
+
+static void
+do_ca_sign(struct passwd *pw, int argc, char **argv)
+{
+ int i, fd;
+ u_int n;
+ Key *ca, *public;
+ char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
+ FILE *f;
+
+ tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
+ if ((ca = load_identity(tmp)) == NULL)
+ fatal("Couldn't load CA key \"%s\"", tmp);
+ xfree(tmp);
+
+ for (i = 0; i < argc; i++) {
+ /* Split list of principals */
+ n = 0;
+ if (cert_principals != NULL) {
+ otmp = tmp = xstrdup(cert_principals);
+ plist = NULL;
+ for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
+ plist = xrealloc(plist, n + 1, sizeof(*plist));
+ if (*(plist[n] = xstrdup(cp)) == '\0')
+ fatal("Empty principal name");
+ }
+ xfree(otmp);
+ }
+
+ tmp = tilde_expand_filename(argv[i], pw->pw_uid);
+ if ((public = key_load_public(tmp, &comment)) == NULL)
+ fatal("%s: unable to open \"%s\"", __func__, tmp);
+ if (public->type != KEY_RSA && public->type != KEY_DSA)
+ fatal("%s: key \"%s\" type %s cannot be certified",
+ __func__, tmp, key_type(public));
+
+ /* Prepare certificate to sign */
+ if (key_to_certified(public) != 0)
+ fatal("Could not upgrade key %s to certificate", tmp);
+ public->cert->type = cert_key_type;
+ public->cert->key_id = xstrdup(cert_key_id);
+ public->cert->nprincipals = n;
+ public->cert->principals = plist;
+ public->cert->valid_after = cert_valid_from;
+ public->cert->valid_before = cert_valid_to;
+ prepare_constraint_buf(&public->cert->constraints);
+ public->cert->signature_key = key_from_private(ca);
+
+ if (key_certify(public, ca) != 0)
+ fatal("Couldn't not certify key %s", tmp);
+
+ if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
+ *cp = '\0';
+ xasprintf(&out, "%s-cert.pub", tmp);
+ xfree(tmp);
+
+ if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
+ fatal("Could not open \"%s\" for writing: %s", out,
+ strerror(errno));
+ if ((f = fdopen(fd, "w")) == NULL)
+ fatal("%s: fdopen: %s", __func__, strerror(errno));
+ if (!key_write(public, f))
+ fatal("Could not write certified key to %s", out);
+ fprintf(f, " %s\n", comment);
+ fclose(f);
+
+ if (!quiet)
+ logit("Signed %s key %s: id \"%s\"%s%s valid %s",
+ cert_key_type == SSH2_CERT_TYPE_USER?"user":"host",
+ out, cert_key_id,
+ cert_principals != NULL ? " for " : "",
+ cert_principals != NULL ? cert_principals : "",
+ fmt_validity(cert_valid_from, cert_valid_to));
+
+ key_free(public);
+ xfree(out);
+ }
+ exit(0);
+}
+
+static u_int64_t
+parse_relative_time(const char *s, time_t now)
+{
+ int64_t mul, secs;
+
+ mul = *s == '-' ? -1 : 1;
+
+ if ((secs = convtime(s + 1)) == -1)
+ fatal("Invalid relative certificate time %s", s);
+ if (mul == -1 && secs > now)
+ fatal("Certificate time %s cannot be represented", s);
+ return now + (u_int64_t)(secs * mul);
+}
+
+static u_int64_t
+parse_absolute_time(const char *s)
+{
+ struct tm tm;
+ time_t tt;
+ char buf[32], *fmt;
+
+ /*
+ * POSIX strptime says "The application shall ensure that there
+ * is white-space or other non-alphanumeric characters between
+ * any two conversion specifications" so arrange things this way.
+ */
+ switch (strlen(s)) {
+ case 8:
+ fmt = "%Y-%m-%d";
+ snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
+ break;
+ case 14:
+ fmt = "%Y-%m-%dT%H:%M:%S";
+ snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
+ s, s + 4, s + 6, s + 8, s + 10, s + 12);
+ break;
+ default:
+ fatal("Invalid certificate time format %s", s);
+ }
+
+ bzero(&tm, sizeof(tm));
+ if (strptime(buf, fmt, &tm) == NULL)
+ fatal("Invalid certificate time %s", s);
+ if ((tt = mktime(&tm)) < 0)
+ fatal("Certificate time %s cannot be represented", s);
+ return (u_int64_t)tt;
+}
+
+static void
+parse_cert_times(char *timespec)
+{
+ char *from, *to;
+ time_t now = time(NULL);
+ int64_t secs;
+
+ /* +timespec relative to now */
+ if (*timespec == '+' && strchr(timespec, ':') == NULL) {
+ if ((secs = convtime(timespec + 1)) == -1)
+ fatal("Invalid relative certificate life %s", timespec);
+ cert_valid_to = now + secs;
+ /*
+ * Backdate certificate one minute to avoid problems on hosts
+ * with poorly-synchronised clocks.
+ */
+ cert_valid_from = ((now - 59)/ 60) * 60;
+ return;
+ }
+
+ /*
+ * from:to, where
+ * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
+ * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
+ */
+ from = xstrdup(timespec);
+ to = strchr(from, ':');
+ if (to == NULL || from == to || *(to + 1) == '\0')
+ fatal("Invalid certificate life specification %s", timespec);
+ *to++ = '\0';
+
+ if (*from == '-' || *from == '+')
+ cert_valid_from = parse_relative_time(from, now);
+ else
+ cert_valid_from = parse_absolute_time(from);
+
+ if (*to == '-' || *to == '+')
+ cert_valid_to = parse_relative_time(to, cert_valid_from);
+ else
+ cert_valid_to = parse_absolute_time(to);
+
+ if (cert_valid_to <= cert_valid_from)
+ fatal("Empty certificate validity interval");
+ xfree(from);
+}
+
+static void
+add_cert_constraint(char *opt)
+{
+ char *val;
+
+ if (strcmp(opt, "clear") == 0)
+ constraint_flags = 0;
+ else if (strcasecmp(opt, "no-x11-forwarding") == 0)
+ constraint_flags &= ~CONSTRAINT_X_FWD;
+ else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
+ constraint_flags |= CONSTRAINT_X_FWD;
+ else if (strcasecmp(opt, "no-agent-forwarding") == 0)
+ constraint_flags &= ~CONSTRAINT_AGENT_FWD;
+ else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
+ constraint_flags |= CONSTRAINT_AGENT_FWD;
+ else if (strcasecmp(opt, "no-port-forwarding") == 0)
+ constraint_flags &= ~CONSTRAINT_PORT_FWD;
+ else if (strcasecmp(opt, "permit-port-forwarding") == 0)
+ constraint_flags |= CONSTRAINT_PORT_FWD;
+ else if (strcasecmp(opt, "no-pty") == 0)
+ constraint_flags &= ~CONSTRAINT_PTY;
+ else if (strcasecmp(opt, "permit-pty") == 0)
+ constraint_flags |= CONSTRAINT_PTY;
+ else if (strcasecmp(opt, "no-user-rc") == 0)
+ constraint_flags &= ~CONSTRAINT_USER_RC;
+ else if (strcasecmp(opt, "permit-user-rc") == 0)
+ constraint_flags |= CONSTRAINT_USER_RC;
+ else if (strncasecmp(opt, "force-command=", 14) == 0) {
+ val = opt + 14;
+ if (*val == '\0')
+ fatal("Empty force-command constraint");
+ if (constraint_command != NULL)
+ fatal("force-command already specified");
+ constraint_command = xstrdup(val);
+ } else if (strncasecmp(opt, "source-address=", 15) == 0) {
+ val = opt + 15;
+ if (*val == '\0')
+ fatal("Empty source-address constraint");
+ if (constraint_src_addr != NULL)
+ fatal("source-address already specified");
+ if (addr_match_cidr_list(NULL, val) != 0)
+ fatal("Invalid source-address list");
+ constraint_src_addr = xstrdup(val);
+ } else
+ fatal("Unsupported certificate constraint \"%s\"", opt);
+}
+
+static void
+do_show_cert(struct passwd *pw)
+{
+ Key *key;
+ struct stat st;
+ char *key_fp, *ca_fp;
+ Buffer constraints, constraint;
+ u_char *name, *data;
+ u_int i, dlen;
+
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0) {
+ perror(identity_file);
+ exit(1);
+ }
+ if ((key = key_load_public(identity_file, NULL)) == NULL)
+ fatal("%s is not a public key", identity_file);
+ if (!key_is_cert(key))
+ fatal("%s is not a certificate", identity_file);
+
+ key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ ca_fp = key_fingerprint(key->cert->signature_key,
+ SSH_FP_MD5, SSH_FP_HEX);
+
+ printf("%s:\n", identity_file);
+ printf(" %s certificate %s\n", key_type(key), key_fp);
+ printf(" Signed by %s CA %s\n",
+ key_type(key->cert->signature_key), ca_fp);
+ printf(" Key ID \"%s\"\n", key->cert->key_id);
+ printf(" Valid: %s\n",
+ fmt_validity(key->cert->valid_after, key->cert->valid_before));
+ printf(" Principals: ");
+ if (key->cert->nprincipals == 0)
+ printf("(none)\n");
+ else {
+ for (i = 0; i < key->cert->nprincipals; i++)
+ printf("\n %s",
+ key->cert->principals[i]);
+ printf("\n");
+ }
+ printf(" Constraints: ");
+ if (buffer_len(&key->cert->constraints) == 0)
+ printf("(none)\n");
+ else {
+ printf("\n");
+ buffer_init(&constraints);
+ buffer_append(&constraints,
+ buffer_ptr(&key->cert->constraints),
+ buffer_len(&key->cert->constraints));
+ buffer_init(&constraint);
+ while (buffer_len(&constraints) != 0) {
+ name = buffer_get_string(&constraints, NULL);
+ data = buffer_get_string_ptr(&constraints, &dlen);
+ buffer_append(&constraint, data, dlen);
+ printf(" %s", name);
+ if (strcmp(name, "permit-X11-forwarding") == 0 ||
+ strcmp(name, "permit-agent-forwarding") == 0 ||
+ strcmp(name, "permit-port-forwarding") == 0 ||
+ strcmp(name, "permit-pty") == 0 ||
+ strcmp(name, "permit-user-rc") == 0)
+ printf("\n");
+ else if (strcmp(name, "force-command") == 0 ||
+ strcmp(name, "source-address") == 0) {
+ data = buffer_get_string(&constraint, NULL);
+ printf(" %s\n", data);
+ xfree(data);
+ } else {
+ printf(" UNKNOWN CONSTRAINT (len %u)\n",
+ buffer_len(&constraint));
+ buffer_clear(&constraint);
+ }
+ xfree(name);
+ if (buffer_len(&constraint) != 0)
+ fatal("Constraint corrupt: extra data at end");
+ }
+ buffer_free(&constraint);
+ buffer_free(&constraints);
+ }
+
+ exit(0);
+}
+
static void
usage(void)
{
@@ -1040,30 +1460,34 @@ usage(void)
fprintf(stderr, " -b bits Number of bits in the key to create.\n");
fprintf(stderr, " -C comment Provide new comment.\n");
fprintf(stderr, " -c Change comment in private and public key files.\n");
-#ifdef SMARTCARD
- fprintf(stderr, " -D reader Download public key from smartcard.\n");
-#endif /* SMARTCARD */
+#ifdef ENABLE_PKCS11
+ fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n");
+#endif
fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n");
fprintf(stderr, " -F hostname Find hostname in known hosts file.\n");
fprintf(stderr, " -f filename Filename of the key file.\n");
fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n");
fprintf(stderr, " -g Use generic DNS resource record format.\n");
fprintf(stderr, " -H Hash names in known_hosts file.\n");
+ fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n");
+ fprintf(stderr, " -I key_id Key identifier to include in certificate.\n");
fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n");
+ fprintf(stderr, " -L Print the contents of a certificate.\n");
fprintf(stderr, " -l Show fingerprint of key file.\n");
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
+ fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
fprintf(stderr, " -N phrase Provide new passphrase.\n");
+ fprintf(stderr, " -O cnstr Specify a certificate constraint.\n");
fprintf(stderr, " -P phrase Provide old passphrase.\n");
fprintf(stderr, " -p Change passphrase of private key file.\n");
fprintf(stderr, " -q Quiet.\n");
fprintf(stderr, " -R hostname Remove host from known_hosts file.\n");
fprintf(stderr, " -r hostname Print DNS resource record.\n");
+ fprintf(stderr, " -s ca_key Certify keys with CA key.\n");
fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n");
fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n");
fprintf(stderr, " -t type Specify type of key to create.\n");
-#ifdef SMARTCARD
- fprintf(stderr, " -U reader Upload private key to smartcard.\n");
-#endif /* SMARTCARD */
+ fprintf(stderr, " -V from:to Specify certificate validity interval.\n");
fprintf(stderr, " -v Verbose.\n");
fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
fprintf(stderr, " -y Read private key file and print public key.\n");
@@ -1078,12 +1502,12 @@ int
main(int argc, char **argv)
{
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
- char out_file[MAXPATHLEN], *reader_id = NULL;
+ char out_file[MAXPATHLEN], *pkcs11provider = NULL;
char *rr_hostname = NULL;
Key *private, *public;
struct passwd *pw;
struct stat st;
- int opt, type, fd, download = 0;
+ int opt, type, fd;
u_int32_t memory = 0, generator_wanted = 0, trials = 100;
int do_gen_candidates = 0, do_screen_candidates = 0;
BIGNUM *start = NULL;
@@ -1115,8 +1539,8 @@ main(int argc, char **argv)
exit(1);
}
- while ((opt = getopt(argc, argv,
- "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
+ while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:"
+ "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) {
switch (opt) {
case 'b':
bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
@@ -1131,16 +1555,25 @@ main(int argc, char **argv)
case 'H':
hash_hosts = 1;
break;
+ case 'I':
+ cert_key_id = optarg;
+ break;
case 'R':
delete_host = 1;
rr_hostname = optarg;
break;
+ case 'L':
+ show_cert = 1;
+ break;
case 'l':
print_fingerprint = 1;
break;
case 'B':
print_bubblebabble = 1;
break;
+ case 'n':
+ cert_principals = optarg;
+ break;
case 'p':
change_passphrase = 1;
break;
@@ -1162,6 +1595,9 @@ main(int argc, char **argv)
case 'N':
identity_new_passphrase = optarg;
break;
+ case 'O':
+ add_cert_constraint(optarg);
+ break;
case 'C':
identity_comment = optarg;
break;
@@ -1173,6 +1609,10 @@ main(int argc, char **argv)
/* export key */
convert_to_ssh2 = 1;
break;
+ case 'h':
+ cert_key_type = SSH2_CERT_TYPE_HOST;
+ constraint_flags = 0;
+ break;
case 'i':
case 'X':
/* import key */
@@ -1184,14 +1624,14 @@ main(int argc, char **argv)
case 'd':
key_type_name = "dsa";
break;
+ case 's':
+ ca_key_path = optarg;
+ break;
case 't':
key_type_name = optarg;
break;
case 'D':
- download = 1;
- /*FALLTHROUGH*/
- case 'U':
- reader_id = optarg;
+ pkcs11provider = optarg;
break;
case 'v':
if (log_level == SYSLOG_LEVEL_INFO)
@@ -1241,6 +1681,9 @@ main(int argc, char **argv)
if (BN_hex2bn(&start, optarg) == 0)
fatal("Invalid start point.");
break;
+ case 'V':
+ parse_cert_times(optarg);
+ break;
case '?':
default:
usage();
@@ -1250,7 +1693,15 @@ main(int argc, char **argv)
/* reinit */
log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
- if (optind < argc) {
+ argv += optind;
+ argc -= optind;
+
+ if (ca_key_path != NULL) {
+ if (argc < 1) {
+ printf("Too few arguments.\n");
+ usage();
+ }
+ } else if (argc > 0) {
printf("Too many arguments.\n");
usage();
}
@@ -1262,6 +1713,13 @@ main(int argc, char **argv)
printf("Cannot use -l with -D or -R.\n");
usage();
}
+ if (ca_key_path != NULL) {
+ if (cert_key_id == NULL)
+ fatal("Must specify key id (-I) when certifying");
+ do_ca_sign(pw, argc, argv);
+ }
+ if (show_cert)
+ do_show_cert(pw);
if (delete_host || hash_hosts || find_host)
do_known_hosts(pw, rr_hostname);
if (print_fingerprint || print_bubblebabble)
@@ -1299,16 +1757,8 @@ main(int argc, char **argv)
exit(0);
}
}
- if (reader_id != NULL) {
-#ifdef SMARTCARD
- if (download)
- do_download(pw, reader_id);
- else
- do_upload(pw, reader_id);
-#else /* SMARTCARD */
- fatal("no support for smartcards.");
-#endif /* SMARTCARD */
- }
+ if (pkcs11provider != NULL)
+ do_download(pw, pkcs11provider);
if (do_gen_candidates) {
FILE *out = fopen(out_file, "w");
diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1
index 2c7ac10..fd6b94a 100644
--- a/crypto/openssh/ssh-keyscan.1
+++ b/crypto/openssh/ssh-keyscan.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keyscan.1,v 1.26 2008/12/29 01:12:36 stevesk Exp $
+.\" $OpenBSD: ssh-keyscan.1,v 1.28 2010/01/09 23:04:13 dtucker Exp $
.\" $FreeBSD$
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
@@ -7,7 +7,7 @@
.\" permitted provided that due credit is given to the author and the
.\" OpenBSD project by leaving this copyright notice intact.
.\"
-.Dd December 29 2008
+.Dd January 9 2010
.Dt SSH-KEYSCAN 1
.Os
.Sh NAME
diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
index 9a91be4..7afe446 100644
--- a/crypto/openssh/ssh-keyscan.c
+++ b/crypto/openssh/ssh-keyscan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.78 2009/01/22 10:02:34 djm Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
diff --git a/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c
index c4bc7e5..0fdcebb 100644
--- a/crypto/openssh/ssh-keysign.c
+++ b/crypto/openssh/ssh-keysign.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keysign.c,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: ssh-keysign.c,v 1.30 2010/01/13 01:20:20 dtucker Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@@ -222,7 +222,7 @@ main(int argc, char **argv)
if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
fatal("bad fd");
if ((host = get_local_name(fd)) == NULL)
- fatal("cannot get sockname for fd");
+ fatal("cannot get local name for fd");
data = buffer_get_string(&b, &dlen);
if (valid_request(pw, host, &key, data, dlen) < 0)
diff --git a/crypto/openssh/ssh-pkcs11-client.c b/crypto/openssh/ssh-pkcs11-client.c
new file mode 100644
index 0000000..650c373
--- /dev/null
+++ b/crypto/openssh/ssh-pkcs11-client.c
@@ -0,0 +1,238 @@
+/* $OpenBSD: ssh-pkcs11-client.c,v 1.2 2010/02/24 06:12:53 djm Exp $ */
+/*
+ * Copyright (c) 2010 Markus Friedl. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifdef ENABLE_PKCS11
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/socket.h>
+
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "pathnames.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "log.h"
+#include "misc.h"
+#include "key.h"
+#include "authfd.h"
+#include "atomicio.h"
+#include "ssh-pkcs11.h"
+
+/* borrows code from sftp-server and ssh-agent */
+
+int fd = -1;
+pid_t pid = -1;
+
+static void
+send_msg(Buffer *m)
+{
+ u_char buf[4];
+ int mlen = buffer_len(m);
+
+ put_u32(buf, mlen);
+ if (atomicio(vwrite, fd, buf, 4) != 4 ||
+ atomicio(vwrite, fd, buffer_ptr(m),
+ buffer_len(m)) != buffer_len(m))
+ error("write to helper failed");
+ buffer_consume(m, mlen);
+}
+
+static int
+recv_msg(Buffer *m)
+{
+ u_int l, len;
+ u_char buf[1024];
+
+ if ((len = atomicio(read, fd, buf, 4)) != 4) {
+ error("read from helper failed: %u", len);
+ return (0); /* XXX */
+ }
+ len = get_u32(buf);
+ if (len > 256 * 1024)
+ fatal("response too long: %u", len);
+ /* read len bytes into m */
+ buffer_clear(m);
+ while (len > 0) {
+ l = len;
+ if (l > sizeof(buf))
+ l = sizeof(buf);
+ if (atomicio(read, fd, buf, l) != l) {
+ error("response from helper failed.");
+ return (0); /* XXX */
+ }
+ buffer_append(m, buf, l);
+ len -= l;
+ }
+ return (buffer_get_char(m));
+}
+
+int
+pkcs11_init(int interactive)
+{
+ return (0);
+}
+
+void
+pkcs11_terminate(void)
+{
+ close(fd);
+}
+
+static int
+pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
+ int padding)
+{
+ Key key;
+ u_char *blob, *signature = NULL;
+ u_int blen, slen = 0;
+ int ret = -1;
+ Buffer msg;
+
+ if (padding != RSA_PKCS1_PADDING)
+ return (-1);
+ key.type = KEY_RSA;
+ key.rsa = rsa;
+ if (key_to_blob(&key, &blob, &blen) == 0)
+ return -1;
+ buffer_init(&msg);
+ buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
+ buffer_put_string(&msg, blob, blen);
+ buffer_put_string(&msg, from, flen);
+ buffer_put_int(&msg, 0);
+ xfree(blob);
+ send_msg(&msg);
+
+ if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) {
+ signature = buffer_get_string(&msg, &slen);
+ if (slen <= (u_int)RSA_size(rsa)) {
+ memcpy(to, signature, slen);
+ ret = slen;
+ }
+ xfree(signature);
+ }
+ return (ret);
+}
+
+/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
+static int
+wrap_key(RSA *rsa)
+{
+ static RSA_METHOD helper_rsa;
+
+ memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
+ helper_rsa.name = "ssh-pkcs11-helper";
+ helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
+ RSA_set_method(rsa, &helper_rsa);
+ return (0);
+}
+
+static int
+pkcs11_start_helper(void)
+{
+ int pair[2];
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
+ error("socketpair: %s", strerror(errno));
+ return (-1);
+ }
+ if ((pid = fork()) == -1) {
+ error("fork: %s", strerror(errno));
+ return (-1);
+ } else if (pid == 0) {
+ if ((dup2(pair[1], STDIN_FILENO) == -1) ||
+ (dup2(pair[1], STDOUT_FILENO) == -1)) {
+ fprintf(stderr, "dup2: %s\n", strerror(errno));
+ _exit(1);
+ }
+ close(pair[0]);
+ close(pair[1]);
+ execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER,
+ (char *) 0);
+ fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER,
+ strerror(errno));
+ _exit(1);
+ }
+ close(pair[1]);
+ fd = pair[0];
+ return (0);
+}
+
+int
+pkcs11_add_provider(char *name, char *pin, Key ***keysp)
+{
+ Key *k;
+ int i, nkeys;
+ u_char *blob;
+ u_int blen;
+ Buffer msg;
+
+ if (fd < 0 && pkcs11_start_helper() < 0)
+ return (-1);
+
+ buffer_init(&msg);
+ buffer_put_char(&msg, SSH_AGENTC_ADD_SMARTCARD_KEY);
+ buffer_put_cstring(&msg, name);
+ buffer_put_cstring(&msg, pin);
+ send_msg(&msg);
+ buffer_clear(&msg);
+
+ if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) {
+ nkeys = buffer_get_int(&msg);
+ *keysp = xcalloc(nkeys, sizeof(Key *));
+ for (i = 0; i < nkeys; i++) {
+ blob = buffer_get_string(&msg, &blen);
+ xfree(buffer_get_string(&msg, NULL));
+ k = key_from_blob(blob, blen);
+ wrap_key(k->rsa);
+ (*keysp)[i] = k;
+ xfree(blob);
+ }
+ } else {
+ nkeys = -1;
+ }
+ buffer_free(&msg);
+ return (nkeys);
+}
+
+int
+pkcs11_del_provider(char *name)
+{
+ int ret = -1;
+ Buffer msg;
+
+ buffer_init(&msg);
+ buffer_put_char(&msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY);
+ buffer_put_cstring(&msg, name);
+ buffer_put_cstring(&msg, "");
+ send_msg(&msg);
+ buffer_clear(&msg);
+
+ if (recv_msg(&msg) == SSH_AGENT_SUCCESS)
+ ret = 0;
+ buffer_free(&msg);
+ return (ret);
+}
+
+#endif /* ENABLE_PKCS11 */
diff --git a/crypto/openssh/ssh-pkcs11-helper.0 b/crypto/openssh/ssh-pkcs11-helper.0
new file mode 100644
index 0000000..2760cad
--- /dev/null
+++ b/crypto/openssh/ssh-pkcs11-helper.0
@@ -0,0 +1,25 @@
+SSH-PKCS11-HELPER(8) OpenBSD System Manager's Manual SSH-PKCS11-HELPER(8)
+
+NAME
+ ssh-pkcs11-helper - ssh-agent helper program for PKCS#11 support
+
+SYNOPSIS
+ ssh-pkcs11-helper
+
+DESCRIPTION
+ ssh-pkcs11-helper is used by ssh-agent(1) to access keys provided by a
+ PKCS#11 token.
+
+ ssh-pkcs11-helper is not intended to be invoked by the user, but from
+ ssh-agent(1).
+
+SEE ALSO
+ ssh(1), ssh-add(1), ssh-agent(1)
+
+HISTORY
+ ssh-pkcs11-helper first appeared in OpenBSD 4.7.
+
+AUTHORS
+ Markus Friedl <markus@openbsd.org>
+
+OpenBSD 4.6 February 10, 2010 1
diff --git a/crypto/openssh/ssh-pkcs11-helper.8 b/crypto/openssh/ssh-pkcs11-helper.8
new file mode 100644
index 0000000..9bdaadc
--- /dev/null
+++ b/crypto/openssh/ssh-pkcs11-helper.8
@@ -0,0 +1,43 @@
+.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.3 2010/02/10 23:20:38 markus Exp $
+.\"
+.\" Copyright (c) 2010 Markus Friedl. All rights reserved.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: February 10 2010 $
+.Dt SSH-PKCS11-HELPER 8
+.Os
+.Sh NAME
+.Nm ssh-pkcs11-helper
+.Nd ssh-agent helper program for PKCS#11 support
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+is used by
+.Xr ssh-agent 1
+to access keys provided by a PKCS#11 token.
+.Pp
+.Nm
+is not intended to be invoked by the user, but from
+.Xr ssh-agent 1 .
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr ssh-add 1 ,
+.Xr ssh-agent 1
+.Sh HISTORY
+.Nm
+first appeared in
+.Ox 4.7 .
+.Sh AUTHORS
+.An Markus Friedl Aq markus@openbsd.org
diff --git a/crypto/openssh/ssh-pkcs11-helper.c b/crypto/openssh/ssh-pkcs11-helper.c
new file mode 100644
index 0000000..d3bfb98
--- /dev/null
+++ b/crypto/openssh/ssh-pkcs11-helper.c
@@ -0,0 +1,372 @@
+/* $OpenBSD: ssh-pkcs11-helper.c,v 1.3 2010/02/24 06:12:53 djm Exp $ */
+/*
+ * Copyright (c) 2010 Markus Friedl. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifdef ENABLE_PKCS11
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include "openbsd-compat/sys-queue.h"
+
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "log.h"
+#include "misc.h"
+#include "key.h"
+#include "authfd.h"
+#include "ssh-pkcs11.h"
+
+/* borrows code from sftp-server and ssh-agent */
+
+struct pkcs11_keyinfo {
+ Key *key;
+ char *providername;
+ TAILQ_ENTRY(pkcs11_keyinfo) next;
+};
+
+TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
+
+#define MAX_MSG_LENGTH 10240 /*XXX*/
+
+/* helper */
+#define get_int() buffer_get_int(&iqueue);
+#define get_string(lenp) buffer_get_string(&iqueue, lenp);
+
+/* input and output queue */
+Buffer iqueue;
+Buffer oqueue;
+
+static void
+add_key(Key *k, char *name)
+{
+ struct pkcs11_keyinfo *ki;
+
+ ki = xcalloc(1, sizeof(*ki));
+ ki->providername = xstrdup(name);
+ ki->key = k;
+ TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
+}
+
+static void
+del_keys_by_name(char *name)
+{
+ struct pkcs11_keyinfo *ki, *nxt;
+
+ for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) {
+ nxt = TAILQ_NEXT(ki, next);
+ if (!strcmp(ki->providername, name)) {
+ TAILQ_REMOVE(&pkcs11_keylist, ki, next);
+ xfree(ki->providername);
+ key_free(ki->key);
+ free(ki);
+ }
+ }
+}
+
+/* lookup matching 'private' key */
+static Key *
+lookup_key(Key *k)
+{
+ struct pkcs11_keyinfo *ki;
+
+ TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
+ debug("check %p %s", ki, ki->providername);
+ if (key_equal(k, ki->key))
+ return (ki->key);
+ }
+ return (NULL);
+}
+
+static void
+send_msg(Buffer *m)
+{
+ int mlen = buffer_len(m);
+
+ buffer_put_int(&oqueue, mlen);
+ buffer_append(&oqueue, buffer_ptr(m), mlen);
+ buffer_consume(m, mlen);
+}
+
+static void
+process_add(void)
+{
+ char *name, *pin;
+ Key **keys;
+ int i, nkeys;
+ u_char *blob;
+ u_int blen;
+ Buffer msg;
+
+ buffer_init(&msg);
+ name = get_string(NULL);
+ pin = get_string(NULL);
+ if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
+ buffer_put_char(&msg, SSH2_AGENT_IDENTITIES_ANSWER);
+ buffer_put_int(&msg, nkeys);
+ for (i = 0; i < nkeys; i++) {
+ key_to_blob(keys[i], &blob, &blen);
+ buffer_put_string(&msg, blob, blen);
+ buffer_put_cstring(&msg, name);
+ xfree(blob);
+ add_key(keys[i], name);
+ }
+ xfree(keys);
+ } else {
+ buffer_put_char(&msg, SSH_AGENT_FAILURE);
+ }
+ xfree(pin);
+ xfree(name);
+ send_msg(&msg);
+ buffer_free(&msg);
+}
+
+static void
+process_del(void)
+{
+ char *name, *pin;
+ Buffer msg;
+
+ buffer_init(&msg);
+ name = get_string(NULL);
+ pin = get_string(NULL);
+ del_keys_by_name(name);
+ if (pkcs11_del_provider(name) == 0)
+ buffer_put_char(&msg, SSH_AGENT_SUCCESS);
+ else
+ buffer_put_char(&msg, SSH_AGENT_FAILURE);
+ xfree(pin);
+ xfree(name);
+ send_msg(&msg);
+ buffer_free(&msg);
+}
+
+static void
+process_sign(void)
+{
+ u_char *blob, *data, *signature = NULL;
+ u_int blen, dlen, slen = 0;
+ int ok = -1, flags, ret;
+ Key *key, *found;
+ Buffer msg;
+
+ blob = get_string(&blen);
+ data = get_string(&dlen);
+ flags = get_int(); /* XXX ignore */
+
+ if ((key = key_from_blob(blob, blen)) != NULL) {
+ if ((found = lookup_key(key)) != NULL) {
+ slen = RSA_size(key->rsa);
+ signature = xmalloc(slen);
+ if ((ret = RSA_private_encrypt(dlen, data, signature,
+ found->rsa, RSA_PKCS1_PADDING)) != -1) {
+ slen = ret;
+ ok = 0;
+ }
+ }
+ key_free(key);
+ }
+ buffer_init(&msg);
+ if (ok == 0) {
+ buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
+ buffer_put_string(&msg, signature, slen);
+ } else {
+ buffer_put_char(&msg, SSH_AGENT_FAILURE);
+ }
+ xfree(data);
+ xfree(blob);
+ if (signature != NULL)
+ xfree(signature);
+ send_msg(&msg);
+ buffer_free(&msg);
+}
+
+static void
+process(void)
+{
+ u_int msg_len;
+ u_int buf_len;
+ u_int consumed;
+ u_int type;
+ u_char *cp;
+
+ buf_len = buffer_len(&iqueue);
+ if (buf_len < 5)
+ return; /* Incomplete message. */
+ cp = buffer_ptr(&iqueue);
+ msg_len = get_u32(cp);
+ if (msg_len > MAX_MSG_LENGTH) {
+ error("bad message len %d", msg_len);
+ cleanup_exit(11);
+ }
+ if (buf_len < msg_len + 4)
+ return;
+ buffer_consume(&iqueue, 4);
+ buf_len -= 4;
+ type = buffer_get_char(&iqueue);
+ switch (type) {
+ case SSH_AGENTC_ADD_SMARTCARD_KEY:
+ debug("process_add");
+ process_add();
+ break;
+ case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
+ debug("process_del");
+ process_del();
+ break;
+ case SSH2_AGENTC_SIGN_REQUEST:
+ debug("process_sign");
+ process_sign();
+ break;
+ default:
+ error("Unknown message %d", type);
+ break;
+ }
+ /* discard the remaining bytes from the current packet */
+ if (buf_len < buffer_len(&iqueue)) {
+ error("iqueue grew unexpectedly");
+ cleanup_exit(255);
+ }
+ consumed = buf_len - buffer_len(&iqueue);
+ if (msg_len < consumed) {
+ error("msg_len %d < consumed %d", msg_len, consumed);
+ cleanup_exit(255);
+ }
+ if (msg_len > consumed)
+ buffer_consume(&iqueue, msg_len - consumed);
+}
+
+void
+cleanup_exit(int i)
+{
+ /* XXX */
+ _exit(i);
+}
+
+int
+main(int argc, char **argv)
+{
+ fd_set *rset, *wset;
+ int in, out, max, log_stderr = 0;
+ ssize_t len, olen, set_size;
+ SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
+ LogLevel log_level = SYSLOG_LEVEL_ERROR;
+ char buf[4*4096];
+
+ extern char *optarg;
+ extern char *__progname;
+
+ TAILQ_INIT(&pkcs11_keylist);
+ pkcs11_init(0);
+
+ init_rng();
+ seed_rng();
+ __progname = ssh_get_progname(argv[0]);
+
+ log_init(__progname, log_level, log_facility, log_stderr);
+
+ in = STDIN_FILENO;
+ out = STDOUT_FILENO;
+
+ max = 0;
+ if (in > max)
+ max = in;
+ if (out > max)
+ max = out;
+
+ buffer_init(&iqueue);
+ buffer_init(&oqueue);
+
+ set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
+ rset = (fd_set *)xmalloc(set_size);
+ wset = (fd_set *)xmalloc(set_size);
+
+ for (;;) {
+ memset(rset, 0, set_size);
+ memset(wset, 0, set_size);
+
+ /*
+ * Ensure that we can read a full buffer and handle
+ * the worst-case length packet it can generate,
+ * otherwise apply backpressure by stopping reads.
+ */
+ if (buffer_check_alloc(&iqueue, sizeof(buf)) &&
+ buffer_check_alloc(&oqueue, MAX_MSG_LENGTH))
+ FD_SET(in, rset);
+
+ olen = buffer_len(&oqueue);
+ if (olen > 0)
+ FD_SET(out, wset);
+
+ if (select(max+1, rset, wset, NULL, NULL) < 0) {
+ if (errno == EINTR)
+ continue;
+ error("select: %s", strerror(errno));
+ cleanup_exit(2);
+ }
+
+ /* copy stdin to iqueue */
+ if (FD_ISSET(in, rset)) {
+ len = read(in, buf, sizeof buf);
+ if (len == 0) {
+ debug("read eof");
+ cleanup_exit(0);
+ } else if (len < 0) {
+ error("read: %s", strerror(errno));
+ cleanup_exit(1);
+ } else {
+ buffer_append(&iqueue, buf, len);
+ }
+ }
+ /* send oqueue to stdout */
+ if (FD_ISSET(out, wset)) {
+ len = write(out, buffer_ptr(&oqueue), olen);
+ if (len < 0) {
+ error("write: %s", strerror(errno));
+ cleanup_exit(1);
+ } else {
+ buffer_consume(&oqueue, len);
+ }
+ }
+
+ /*
+ * Process requests from client if we can fit the results
+ * into the output buffer, otherwise stop processing input
+ * and let the output queue drain.
+ */
+ if (buffer_check_alloc(&oqueue, MAX_MSG_LENGTH))
+ process();
+ }
+}
+#else /* ENABLE_PKCS11 */
+int
+main(int argc, char **argv)
+{
+ extern char *__progname;
+
+ __progname = ssh_get_progname(argv[0]);
+ log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0);
+ fatal("PKCS#11 support disabled at compile time");
+}
+#endif /* ENABLE_PKCS11 */
diff --git a/crypto/openssh/ssh-pkcs11.c b/crypto/openssh/ssh-pkcs11.c
new file mode 100644
index 0000000..f0192dc
--- /dev/null
+++ b/crypto/openssh/ssh-pkcs11.c
@@ -0,0 +1,564 @@
+/* $OpenBSD: ssh-pkcs11.c,v 1.4 2010/02/24 06:12:53 djm Exp $ */
+/*
+ * Copyright (c) 2010 Markus Friedl. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifdef ENABLE_PKCS11
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <string.h>
+#include <dlfcn.h>
+
+#include "openbsd-compat/sys-queue.h"
+
+#define CRYPTOKI_COMPAT
+#include "pkcs11.h"
+
+#include "log.h"
+#include "misc.h"
+#include "key.h"
+#include "ssh-pkcs11.h"
+#include "xmalloc.h"
+
+struct pkcs11_slotinfo {
+ CK_TOKEN_INFO token;
+ CK_SESSION_HANDLE session;
+ int logged_in;
+};
+
+struct pkcs11_provider {
+ char *name;
+ void *handle;
+ CK_FUNCTION_LIST *function_list;
+ CK_INFO info;
+ CK_ULONG nslots;
+ CK_SLOT_ID *slotlist;
+ struct pkcs11_slotinfo *slotinfo;
+ int valid;
+ int refcount;
+ TAILQ_ENTRY(pkcs11_provider) next;
+};
+
+TAILQ_HEAD(, pkcs11_provider) pkcs11_providers;
+
+struct pkcs11_key {
+ struct pkcs11_provider *provider;
+ CK_ULONG slotidx;
+ int (*orig_finish)(RSA *rsa);
+ RSA_METHOD rsa_method;
+ char *keyid;
+ int keyid_len;
+};
+
+int pkcs11_interactive = 0;
+
+int
+pkcs11_init(int interactive)
+{
+ pkcs11_interactive = interactive;
+ TAILQ_INIT(&pkcs11_providers);
+ return (0);
+}
+
+/*
+ * finalize a provider shared libarary, it's no longer usable.
+ * however, there might still be keys referencing this provider,
+ * so the actuall freeing of memory is handled by pkcs11_provider_unref().
+ * this is called when a provider gets unregistered.
+ */
+static void
+pkcs11_provider_finalize(struct pkcs11_provider *p)
+{
+ CK_RV rv;
+ CK_ULONG i;
+
+ debug("pkcs11_provider_finalize: %p refcount %d valid %d",
+ p, p->refcount, p->valid);
+ if (!p->valid)
+ return;
+ for (i = 0; i < p->nslots; i++) {
+ if (p->slotinfo[i].session &&
+ (rv = p->function_list->C_CloseSession(
+ p->slotinfo[i].session)) != CKR_OK)
+ error("C_CloseSession failed: %lu", rv);
+ }
+ if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK)
+ error("C_Finalize failed: %lu", rv);
+ p->valid = 0;
+ p->function_list = NULL;
+ dlclose(p->handle);
+}
+
+/*
+ * remove a reference to the provider.
+ * called when a key gets destroyed or when the provider is unregistered.
+ */
+static void
+pkcs11_provider_unref(struct pkcs11_provider *p)
+{
+ debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount);
+ if (--p->refcount <= 0) {
+ if (p->valid)
+ error("pkcs11_provider_unref: %p still valid", p);
+ xfree(p->slotlist);
+ xfree(p->slotinfo);
+ xfree(p);
+ }
+}
+
+/* unregister all providers, keys might still point to the providers */
+void
+pkcs11_terminate(void)
+{
+ struct pkcs11_provider *p;
+
+ while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) {
+ TAILQ_REMOVE(&pkcs11_providers, p, next);
+ pkcs11_provider_finalize(p);
+ pkcs11_provider_unref(p);
+ }
+}
+
+/* lookup provider by name */
+static struct pkcs11_provider *
+pkcs11_provider_lookup(char *provider_id)
+{
+ struct pkcs11_provider *p;
+
+ TAILQ_FOREACH(p, &pkcs11_providers, next) {
+ debug("check %p %s", p, p->name);
+ if (!strcmp(provider_id, p->name))
+ return (p);
+ }
+ return (NULL);
+}
+
+/* unregister provider by name */
+int
+pkcs11_del_provider(char *provider_id)
+{
+ struct pkcs11_provider *p;
+
+ if ((p = pkcs11_provider_lookup(provider_id)) != NULL) {
+ TAILQ_REMOVE(&pkcs11_providers, p, next);
+ pkcs11_provider_finalize(p);
+ pkcs11_provider_unref(p);
+ return (0);
+ }
+ return (-1);
+}
+
+/* openssl callback for freeing an RSA key */
+static int
+pkcs11_rsa_finish(RSA *rsa)
+{
+ struct pkcs11_key *k11;
+ int rv = -1;
+
+ if ((k11 = RSA_get_app_data(rsa)) != NULL) {
+ if (k11->orig_finish)
+ rv = k11->orig_finish(rsa);
+ if (k11->provider)
+ pkcs11_provider_unref(k11->provider);
+ if (k11->keyid)
+ xfree(k11->keyid);
+ xfree(k11);
+ }
+ return (rv);
+}
+
+/* openssl callback doing the actual signing operation */
+static int
+pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
+ int padding)
+{
+ struct pkcs11_key *k11;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG tlen = 0, nfound = 0;
+ CK_RV rv;
+ CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY;
+ CK_BBOOL true_val = CK_TRUE;
+ CK_MECHANISM mech = {
+ CKM_RSA_PKCS, NULL_PTR, 0
+ };
+ CK_ATTRIBUTE key_filter[] = {
+ {CKA_CLASS, NULL, sizeof(private_key_class) },
+ {CKA_ID, NULL, 0},
+ {CKA_SIGN, NULL, sizeof(true_val) }
+ };
+ char *pin, prompt[1024];
+ int rval = -1;
+
+ /* some compilers complain about non-constant initializer so we
+ use NULL in CK_ATTRIBUTE above and set the values here */
+ key_filter[0].pValue = &private_key_class;
+ key_filter[2].pValue = &true_val;
+
+ if ((k11 = RSA_get_app_data(rsa)) == NULL) {
+ error("RSA_get_app_data failed for rsa %p", rsa);
+ return (-1);
+ }
+ if (!k11->provider || !k11->provider->valid) {
+ error("no pkcs11 (valid) provider for rsa %p", rsa);
+ return (-1);
+ }
+ f = k11->provider->function_list;
+ si = &k11->provider->slotinfo[k11->slotidx];
+ if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
+ if (!pkcs11_interactive) {
+ error("need pin");
+ return (-1);
+ }
+ snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
+ si->token.label);
+ pin = read_passphrase(prompt, RP_ALLOW_EOF);
+ if (pin == NULL)
+ return (-1); /* bail out */
+ if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin)))
+ != CKR_OK) {
+ xfree(pin);
+ error("C_Login failed: %lu", rv);
+ return (-1);
+ }
+ xfree(pin);
+ si->logged_in = 1;
+ }
+ key_filter[1].pValue = k11->keyid;
+ key_filter[1].ulValueLen = k11->keyid_len;
+ if ((rv = f->C_FindObjectsInit(si->session, key_filter, 3)) != CKR_OK) {
+ error("C_FindObjectsInit failed: %lu", rv);
+ return (-1);
+ }
+ if ((rv = f->C_FindObjects(si->session, &obj, 1, &nfound)) != CKR_OK ||
+ nfound != 1) {
+ error("C_FindObjects failed (%lu nfound): %lu", nfound, rv);
+ } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
+ error("C_SignInit failed: %lu", rv);
+ } else {
+ /* XXX handle CKR_BUFFER_TOO_SMALL */
+ tlen = RSA_size(rsa);
+ rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen);
+ if (rv == CKR_OK)
+ rval = tlen;
+ else
+ error("C_Sign failed: %lu", rv);
+ }
+ if ((rv = f->C_FindObjectsFinal(si->session)) != CKR_OK)
+ error("C_FindObjectsFinal failed: %lu", rv);
+ return (rval);
+}
+
+static int
+pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
+ int padding)
+{
+ return (-1);
+}
+
+/* redirect private key operations for rsa key to pkcs11 token */
+static int
+pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
+ CK_ATTRIBUTE *keyid_attrib, RSA *rsa)
+{
+ struct pkcs11_key *k11;
+ const RSA_METHOD *def = RSA_get_default_method();
+
+ k11 = xcalloc(1, sizeof(*k11));
+ k11->provider = provider;
+ provider->refcount++; /* provider referenced by RSA key */
+ k11->slotidx = slotidx;
+ /* identify key object on smartcard */
+ k11->keyid_len = keyid_attrib->ulValueLen;
+ k11->keyid = xmalloc(k11->keyid_len);
+ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
+ k11->orig_finish = def->finish;
+ memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
+ k11->rsa_method.name = "pkcs11";
+ k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
+ k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
+ k11->rsa_method.finish = pkcs11_rsa_finish;
+ RSA_set_method(rsa, &k11->rsa_method);
+ RSA_set_app_data(rsa, k11);
+ return (0);
+}
+
+/* remove trailing spaces */
+static void
+rmspace(char *buf, size_t len)
+{
+ size_t i;
+
+ if (!len)
+ return;
+ for (i = len - 1; i > 0; i--)
+ if (i == len - 1 || buf[i] == ' ')
+ buf[i] = '\0';
+ else
+ break;
+}
+
+/*
+ * open a pkcs11 session and login if required.
+ * if pin == NULL we delay login until key use
+ */
+static int
+pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin)
+{
+ CK_RV rv;
+ CK_FUNCTION_LIST *f;
+ CK_SESSION_HANDLE session;
+ int login_required;
+
+ f = p->function_list;
+ login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED;
+ if (pin && login_required && !strlen(pin)) {
+ error("pin required");
+ return (-1);
+ }
+ if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION|
+ CKF_SERIAL_SESSION, NULL, NULL, &session))
+ != CKR_OK) {
+ error("C_OpenSession failed: %lu", rv);
+ return (-1);
+ }
+ if (login_required && pin) {
+ if ((rv = f->C_Login(session, CKU_USER, pin, strlen(pin)))
+ != CKR_OK) {
+ error("C_Login failed: %lu", rv);
+ if ((rv = f->C_CloseSession(session)) != CKR_OK)
+ error("C_CloseSession failed: %lu", rv);
+ return (-1);
+ }
+ p->slotinfo[slotidx].logged_in = 1;
+ }
+ p->slotinfo[slotidx].session = session;
+ return (0);
+}
+
+/*
+ * lookup public keys for token in slot identified by slotidx,
+ * add 'wrapped' public keys to the 'keysp' array and increment nkeys.
+ * keysp points to an (possibly empty) array with *nkeys keys.
+ */
+static int
+pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp,
+ int *nkeys)
+{
+ Key *key;
+ RSA *rsa;
+ int i;
+ CK_RV rv;
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG nfound;
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f;
+ CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
+ CK_ATTRIBUTE pubkey_filter[] = {
+ { CKA_CLASS, NULL, sizeof(pubkey_class) }
+ };
+ CK_ATTRIBUTE attribs[] = {
+ { CKA_ID, NULL, 0 },
+ { CKA_MODULUS, NULL, 0 },
+ { CKA_PUBLIC_EXPONENT, NULL, 0 }
+ };
+
+ /* some compilers complain about non-constant initializer so we
+ use NULL in CK_ATTRIBUTE above and set the value here */
+ pubkey_filter[0].pValue = &pubkey_class;
+
+ f = p->function_list;
+ session = p->slotinfo[slotidx].session;
+ /* setup a filter the looks for public keys */
+ if ((rv = f->C_FindObjectsInit(session, pubkey_filter, 1)) != CKR_OK) {
+ error("C_FindObjectsInit failed: %lu", rv);
+ return (-1);
+ }
+ while (1) {
+ /* XXX 3 attributes in attribs[] */
+ for (i = 0; i < 3; i++) {
+ attribs[i].pValue = NULL;
+ attribs[i].ulValueLen = 0;
+ }
+ if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK
+ || nfound == 0)
+ break;
+ /* found a key, so figure out size of the attributes */
+ if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
+ != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ continue;
+ }
+ /* allocate buffers for attributes, XXX check ulValueLen? */
+ for (i = 0; i < 3; i++)
+ attribs[i].pValue = xmalloc(attribs[i].ulValueLen);
+ /* retrieve ID, modulus and public exponent of RSA key */
+ if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
+ != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ } else if ((rsa = RSA_new()) == NULL) {
+ error("RSA_new failed");
+ } else {
+ rsa->n = BN_bin2bn(attribs[1].pValue,
+ attribs[1].ulValueLen, NULL);
+ rsa->e = BN_bin2bn(attribs[2].pValue,
+ attribs[2].ulValueLen, NULL);
+ if (rsa->n && rsa->e &&
+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
+ key = key_new(KEY_UNSPEC);
+ key->rsa = rsa;
+ key->type = KEY_RSA;
+ key->flags |= KEY_FLAG_EXT;
+ /* expand key array and add key */
+ *keysp = xrealloc(*keysp, *nkeys + 1,
+ sizeof(Key *));
+ (*keysp)[*nkeys] = key;
+ *nkeys = *nkeys + 1;
+ debug("have %d keys", *nkeys);
+ } else {
+ RSA_free(rsa);
+ }
+ }
+ for (i = 0; i < 3; i++)
+ xfree(attribs[i].pValue);
+ }
+ if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK)
+ error("C_FindObjectsFinal failed: %lu", rv);
+ return (0);
+}
+
+/* register a new provider, fails if provider already exists */
+int
+pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
+{
+ int nkeys, need_finalize = 0;
+ struct pkcs11_provider *p = NULL;
+ void *handle = NULL;
+ CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **);
+ CK_RV rv;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_TOKEN_INFO *token;
+ CK_ULONG i;
+
+ *keyp = NULL;
+ if (pkcs11_provider_lookup(provider_id) != NULL) {
+ error("provider already registered: %s", provider_id);
+ goto fail;
+ }
+ /* open shared pkcs11-libarary */
+ if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) {
+ error("dlopen %s failed: %s", provider_id, dlerror());
+ goto fail;
+ }
+ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) {
+ error("dlsym(C_GetFunctionList) failed: %s", dlerror());
+ goto fail;
+ }
+ p = xcalloc(1, sizeof(*p));
+ p->name = xstrdup(provider_id);
+ p->handle = handle;
+ /* setup the pkcs11 callbacks */
+ if ((rv = (*getfunctionlist)(&f)) != CKR_OK) {
+ error("C_GetFunctionList failed: %lu", rv);
+ goto fail;
+ }
+ p->function_list = f;
+ if ((rv = f->C_Initialize(NULL)) != CKR_OK) {
+ error("C_Initialize failed: %lu", rv);
+ goto fail;
+ }
+ need_finalize = 1;
+ if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) {
+ error("C_GetInfo failed: %lu", rv);
+ goto fail;
+ }
+ rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID));
+ rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription));
+ debug("manufacturerID <%s> cryptokiVersion %d.%d"
+ " libraryDescription <%s> libraryVersion %d.%d",
+ p->info.manufacturerID,
+ p->info.cryptokiVersion.major,
+ p->info.cryptokiVersion.minor,
+ p->info.libraryDescription,
+ p->info.libraryVersion.major,
+ p->info.libraryVersion.minor);
+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) {
+ error("C_GetSlotList failed: %lu", rv);
+ goto fail;
+ }
+ if (p->nslots == 0) {
+ error("no slots");
+ goto fail;
+ }
+ p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID));
+ if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots))
+ != CKR_OK) {
+ error("C_GetSlotList failed: %lu", rv);
+ goto fail;
+ }
+ p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo));
+ p->valid = 1;
+ nkeys = 0;
+ for (i = 0; i < p->nslots; i++) {
+ token = &p->slotinfo[i].token;
+ if ((rv = f->C_GetTokenInfo(p->slotlist[i], token))
+ != CKR_OK) {
+ error("C_GetTokenInfo failed: %lu", rv);
+ continue;
+ }
+ rmspace(token->label, sizeof(token->label));
+ rmspace(token->manufacturerID, sizeof(token->manufacturerID));
+ rmspace(token->model, sizeof(token->model));
+ rmspace(token->serialNumber, sizeof(token->serialNumber));
+ debug("label <%s> manufacturerID <%s> model <%s> serial <%s>"
+ " flags 0x%lx",
+ token->label, token->manufacturerID, token->model,
+ token->serialNumber, token->flags);
+ /* open session, login with pin and retrieve public keys */
+ if (pkcs11_open_session(p, i, pin) == 0)
+ pkcs11_fetch_keys(p, i, keyp, &nkeys);
+ }
+ if (nkeys > 0) {
+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next);
+ p->refcount++; /* add to provider list */
+ return (nkeys);
+ }
+ error("no keys");
+ /* don't add the provider, since it does not have any keys */
+fail:
+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK)
+ error("C_Finalize failed: %lu", rv);
+ if (p) {
+ if (p->slotlist)
+ xfree(p->slotlist);
+ if (p->slotinfo)
+ xfree(p->slotinfo);
+ xfree(p);
+ }
+ if (handle)
+ dlclose(handle);
+ return (-1);
+}
+
+#endif /* ENABLE_PKCS11 */
diff --git a/crypto/openssh/ssh-pkcs11.h b/crypto/openssh/ssh-pkcs11.h
new file mode 100644
index 0000000..59f456a
--- /dev/null
+++ b/crypto/openssh/ssh-pkcs11.h
@@ -0,0 +1,20 @@
+/* $OpenBSD: ssh-pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */
+/*
+ * Copyright (c) 2010 Markus Friedl. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+int pkcs11_init(int);
+void pkcs11_terminate(void);
+int pkcs11_add_provider(char *, char *, Key ***);
+int pkcs11_del_provider(char *);
diff --git a/crypto/openssh/ssh-rand-helper.c b/crypto/openssh/ssh-rand-helper.c
index 8b1c4b4..fa50704 100644
--- a/crypto/openssh/ssh-rand-helper.c
+++ b/crypto/openssh/ssh-rand-helper.c
@@ -818,6 +818,7 @@ main(int argc, char **argv)
unsigned char *buf;
int ret, ch, debug_level, output_hex, bytes;
extern char *optarg;
+ extern int optind;
LogLevel ll;
__progname = ssh_get_progname(argv[0]);
@@ -853,11 +854,17 @@ main(int argc, char **argv)
default:
error("Invalid commandline option");
usage();
+ exit(1);
}
}
-
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+ if (argc != optind) {
+ error("Unexpected commandline arguments.");
+ usage();
+ exit(1);
+ }
+
#ifdef USE_SEED_FILES
prng_read_seedfile();
#endif
diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c
index 0e16ff8..842857f 100644
--- a/crypto/openssh/ssh-rsa.c
+++ b/crypto/openssh/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.39 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.40 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
*
@@ -46,7 +46,9 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
int ok, nid;
Buffer b;
- if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
+ if (key == NULL ||
+ (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
+ key->rsa == NULL) {
error("ssh_rsa_sign: no RSA key");
return -1;
}
@@ -113,7 +115,9 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
u_int len, dlen, modlen;
int rlen, ret, nid;
- if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
+ if (key == NULL ||
+ (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
+ key->rsa == NULL) {
error("ssh_rsa_verify: no RSA key");
return -1;
}
diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1
index e88cfe3..e3a826e 100644
--- a/crypto/openssh/ssh.1
+++ b/crypto/openssh/ssh.1
@@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh.1,v 1.283 2009/03/19 15:15:09 jmc Exp $
+.\" $OpenBSD: ssh.1,v 1.302 2010/03/05 10:28:21 djm Exp $
.\" $FreeBSD$
-.Dd March 19 2009
+.Dd March 5 2010
.Dt SSH 1
.Os
.Sh NAME
@@ -55,6 +55,7 @@
.Oc
.Op Fl e Ar escape_char
.Op Fl F Ar configfile
+.Op Fl I Ar pkcs11
.Bk -words
.Op Fl i Ar identity_file
.Ek
@@ -78,12 +79,11 @@
.Sm on
.Oc
.Op Fl S Ar ctl_path
-.Bk -words
+.Op Fl W Ar host : Ns Ar port
.Oo Fl w Ar local_tun Ns
.Op : Ns Ar remote_tun Oc
.Oo Ar user Ns @ Oc Ns Ar hostname
.Op Ar command
-.Ek
.Sh DESCRIPTION
.Nm
(SSH client) is a program for logging into a remote machine and for
@@ -133,8 +133,9 @@ This can also be specified on a per-host basis in a configuration file.
.Pp
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
-(for the agent's Unix-domain socket)
-can access the local agent through the forwarded connection.
+(for the agent's
+.Ux Ns -domain
+socket) can access the local agent through the forwarded connection.
An attacker cannot obtain key material from the agent,
however they can perform operations on the keys that enable them to
authenticate using the identities loaded into the agent.
@@ -285,13 +286,11 @@ will wait for all remote port forwards to be successfully established
before placing itself in the background.
.It Fl g
Allows remote hosts to connect to local forwarded ports.
-.It Fl I Ar smartcard_device
-Specify the device
+.It Fl I Ar pkcs11
+Specify the PKCS#11 shared library
.Nm
-should use to communicate with a smartcard used for storing the user's
+should use to communicate with a PKCS#11 token providing the user's
private RSA key.
-This option is only available if support for smartcard devices
-is compiled in (default is no support).
.It Fl i Ar identity_file
Selects a file from which the identity (private key) for
RSA or DSA authentication is read.
@@ -308,6 +307,11 @@ It is possible to have multiple
.Fl i
options (and multiple identities specified in
configuration files).
+.Nm
+will also try to load certificate information from the filename obtained
+by appending
+.Pa -cert.pub
+to identity filenames.
.It Fl K
Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI
credentials to the server.
@@ -470,6 +474,7 @@ For full details of the options listed below, and their possible values, see
.It NumberOfPasswordPrompts
.It PasswordAuthentication
.It PermitLocalCommand
+.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It Protocol
@@ -482,7 +487,6 @@ For full details of the options listed below, and their possible values, see
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
-.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive
.It Tunnel
@@ -595,6 +599,19 @@ Multiple
.Fl v
options increase the verbosity.
The maximum is 3.
+.It Fl W Ar host : Ns Ar port
+Requests that standard input and output on the client be forwarded to
+.Ar host
+on
+.Ar port
+over the secure channel.
+Implies
+.Fl N ,
+.Fl T ,
+.Cm ExitOnForwardFailure
+and
+.Cm ClearAllForwardings
+and works with Protocol version 2 only.
.It Fl w Xo
.Ar local_tun Ns Op : Ns Ar remote_tun
.Xc
@@ -668,20 +685,18 @@ exits with the exit status of the remote command or with 255
if an error occurred.
.Sh AUTHENTICATION
The OpenSSH SSH client supports SSH protocols 1 and 2.
-Protocol 2 is the default, with
-.Nm
-falling back to protocol 1 if it detects protocol 2 is unsupported.
-These settings may be altered using the
+The default is to use protocol 2 only,
+though this can be changed via the
.Cm Protocol
option in
-.Xr ssh_config 5 ,
-or enforced using the
+.Xr ssh_config 5
+or the
.Fl 1
and
.Fl 2
options (see above).
Both protocols support similar authentication methods,
-but protocol 2 is preferred since
+but protocol 2 is the default since
it provides additional mechanisms for confidentiality
(the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour)
and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160).
@@ -790,8 +805,20 @@ file, and has one key
per line, though the lines can be very long.
After this, the user can log in without giving the password.
.Pp
-The most convenient way to use public key authentication may be with an
-authentication agent.
+A variation on public key authentication
+is available in the form of certificate authentication:
+instead of a set of public/private keys,
+signed certificates are used.
+This has the advantage that a single trusted certification authority
+can be used in place of many public/private keys.
+See the
+.Sx CERTIFICATES
+section of
+.Xr ssh-keygen 1
+for more information.
+.Pp
+The most convenient way to use public key or certificate authentication
+may be with an authentication agent.
See
.Xr ssh-agent 1
for more information.
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 25dd863..884d7e9 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.326 2009/07/02 02:11:47 dtucker Exp $ */
+/* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -101,10 +101,11 @@ __RCSID("$FreeBSD$");
#include "match.h"
#include "msg.h"
#include "uidswap.h"
+#include "roaming.h"
#include "version.h"
-#ifdef SMARTCARD
-#include "scard.h"
+#ifdef ENABLE_PKCS11
+#include "ssh-pkcs11.h"
#endif
extern char *__progname;
@@ -133,6 +134,10 @@ int stdin_null_flag = 0;
*/
int fork_after_authentication_flag = 0;
+/* forward stdio to remote host and port */
+char *stdio_forward_host = NULL;
+int stdio_forward_port = 0;
+
/*
* General data structure for command line options and options configurable
* in configuration files. See readconf.h.
@@ -183,10 +188,12 @@ usage(void)
fprintf(stderr,
"usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
" [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
-" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
+" [-I pkcs11] [-i identity_file]\n"
+" [-L [bind_address:]port:host:hostport]\n"
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
-" [-w local_tun[:remote_tun]] [user@]hostname [command]\n"
+" [-W host:port] [-w local_tun[:remote_tun]]\n"
+" [user@]hostname [command]\n"
);
exit(255);
}
@@ -276,7 +283,7 @@ main(int ac, char **av)
again:
while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
- "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) {
+ "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
@@ -314,6 +321,11 @@ main(int ac, char **av)
options.gateway_ports = 1;
break;
case 'O':
+ if (stdio_forward_host != NULL)
+ fatal("Cannot specify multiplexing "
+ "command with -W");
+ else if (muxclient_command != 0)
+ fatal("Multiplexing command already specified");
if (strcmp(optarg, "check") == 0)
muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
else if (strcmp(optarg, "exit") == 0)
@@ -352,10 +364,10 @@ main(int ac, char **av)
xstrdup(optarg);
break;
case 'I':
-#ifdef SMARTCARD
- options.smartcard_device = xstrdup(optarg);
+#ifdef ENABLE_PKCS11
+ options.pkcs11_provider = xstrdup(optarg);
#else
- fprintf(stderr, "no support for smartcards.\n");
+ fprintf(stderr, "no support for PKCS#11.\n");
#endif
break;
case 't':
@@ -389,6 +401,26 @@ main(int ac, char **av)
exit(255);
}
break;
+ case 'W':
+ if (stdio_forward_host != NULL)
+ fatal("stdio forward already specified");
+ if (muxclient_command != 0)
+ fatal("Cannot specify stdio forward with -O");
+ if (parse_forward(&fwd, optarg, 1, 0)) {
+ stdio_forward_host = fwd.listen_host;
+ stdio_forward_port = fwd.listen_port;
+ xfree(fwd.connect_host);
+ } else {
+ fprintf(stderr,
+ "Bad stdio forwarding specification '%s'\n",
+ optarg);
+ exit(255);
+ }
+ no_tty_flag = 1;
+ no_shell_flag = 1;
+ options.clear_forwardings = 1;
+ options.exit_on_forward_failure = 1;
+ break;
case 'q':
options.log_level = SYSLOG_LEVEL_QUIET;
break;
@@ -528,7 +560,7 @@ main(int ac, char **av)
ac -= optind;
av += optind;
- if (ac > 0 && !host && **av != '-') {
+ if (ac > 0 && !host) {
if (strrchr(*av, '@')) {
p = xstrdup(*av);
cp = strrchr(p, '@');
@@ -888,11 +920,48 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
}
static void
+client_cleanup_stdio_fwd(int id, void *arg)
+{
+ debug("stdio forwarding: done");
+ cleanup_exit(0);
+}
+
+static int
+client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect)
+{
+ Channel *c;
+ int in, out;
+
+ debug3("client_setup_stdio_fwd %s:%d", host_to_connect,
+ port_to_connect);
+
+ in = dup(STDIN_FILENO);
+ out = dup(STDOUT_FILENO);
+ if (in < 0 || out < 0)
+ fatal("channel_connect_stdio_fwd: dup() in/out failed");
+
+ if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect,
+ in, out)) == NULL)
+ return 0;
+ channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
+ return 1;
+}
+
+static void
ssh_init_forwarding(void)
{
int success = 0;
int i;
+ if (stdio_forward_host != NULL) {
+ if (!compat20) {
+ fatal("stdio forwarding require Protocol 2");
+ }
+ if (!client_setup_stdio_fwd(stdio_forward_host,
+ stdio_forward_port))
+ fatal("Failed to connect in stdio forward mode.");
+ }
+
/* Initiate local TCP/IP port forwardings. */
for (i = 0; i < options.num_local_forwards; i++) {
debug("Local connections to %.200s:%d forwarded to remote "
@@ -1240,6 +1309,9 @@ ssh_session2(void)
fatal("daemon() failed: %.200s", strerror(errno));
}
+ if (options.use_roaming)
+ request_roaming();
+
return client_loop(tty_flag, tty_flag ?
options.escape_char : SSH_ESCAPECHAR_NONE, id);
}
@@ -1252,31 +1324,37 @@ load_public_identity_files(void)
int i = 0;
Key *public;
struct passwd *pw;
-#ifdef SMARTCARD
+ u_int n_ids;
+ char *identity_files[SSH_MAX_IDENTITY_FILES];
+ Key *identity_keys[SSH_MAX_IDENTITY_FILES];
+#ifdef ENABLE_PKCS11
Key **keys;
+ int nkeys;
+#endif /* PKCS11 */
- if (options.smartcard_device != NULL &&
+ n_ids = 0;
+ bzero(identity_files, sizeof(identity_files));
+ bzero(identity_keys, sizeof(identity_keys));
+
+#ifdef ENABLE_PKCS11
+ if (options.pkcs11_provider != NULL &&
options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
- (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
- int count = 0;
- for (i = 0; keys[i] != NULL; i++) {
- count++;
- memmove(&options.identity_files[1],
- &options.identity_files[0],
- sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
- memmove(&options.identity_keys[1],
- &options.identity_keys[0],
- sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
- options.num_identity_files++;
- options.identity_keys[0] = keys[i];
- options.identity_files[0] = sc_get_key_label(keys[i]);
+ (pkcs11_init(!options.batch_mode) == 0) &&
+ (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
+ &keys)) > 0) {
+ for (i = 0; i < nkeys; i++) {
+ if (n_ids >= SSH_MAX_IDENTITY_FILES) {
+ key_free(keys[i]);
+ continue;
+ }
+ identity_keys[n_ids] = keys[i];
+ identity_files[n_ids] =
+ xstrdup(options.pkcs11_provider); /* XXX */
+ n_ids++;
}
- if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
- options.num_identity_files = SSH_MAX_IDENTITY_FILES;
- i = count;
xfree(keys);
}
-#endif /* SMARTCARD */
+#endif /* ENABLE_PKCS11 */
if ((pw = getpwuid(original_real_uid)) == NULL)
fatal("load_public_identity_files: getpwuid failed");
pwname = xstrdup(pw->pw_name);
@@ -1284,7 +1362,11 @@ load_public_identity_files(void)
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("load_public_identity_files: gethostname: %s",
strerror(errno));
- for (; i < options.num_identity_files; i++) {
+ for (i = 0; i < options.num_identity_files; i++) {
+ if (n_ids >= SSH_MAX_IDENTITY_FILES) {
+ xfree(options.identity_files[i]);
+ continue;
+ }
cp = tilde_expand_filename(options.identity_files[i],
original_real_uid);
filename = percent_expand(cp, "d", pwdir,
@@ -1295,9 +1377,37 @@ load_public_identity_files(void)
debug("identity file %s type %d", filename,
public ? public->type : -1);
xfree(options.identity_files[i]);
- options.identity_files[i] = filename;
- options.identity_keys[i] = public;
+ identity_files[n_ids] = filename;
+ identity_keys[n_ids] = public;
+
+ if (++n_ids >= SSH_MAX_IDENTITY_FILES)
+ continue;
+
+ /* Try to add the certificate variant too */
+ xasprintf(&cp, "%s-cert", filename);
+ public = key_load_public(cp, NULL);
+ debug("identity file %s type %d", cp,
+ public ? public->type : -1);
+ if (public == NULL) {
+ xfree(cp);
+ continue;
+ }
+ if (!key_is_cert(public)) {
+ debug("%s: key %s type %s is not a certificate",
+ __func__, cp, key_type(public));
+ key_free(public);
+ xfree(cp);
+ continue;
+ }
+ identity_keys[n_ids] = public;
+ /* point to the original path, most likely the private key */
+ identity_files[n_ids] = xstrdup(filename);
+ n_ids++;
}
+ options.num_identity_files = n_ids;
+ memcpy(options.identity_files, identity_files, sizeof(identity_files));
+ memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
+
bzero(pwname, strlen(pwname));
xfree(pwname);
bzero(pwdir, strlen(pwdir));
diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h
index 1c33dc2..3ffaf68 100644
--- a/crypto/openssh/ssh2.h
+++ b/crypto/openssh/ssh2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh2.h,v 1.11 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: ssh2.h,v 1.13 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -166,3 +166,13 @@
#define SSH2_EXTENDED_DATA_STDERR 1
+/* kex messages for resume@appgate.com */
+#define SSH2_MSG_KEX_ROAMING_RESUME 30
+#define SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED 31
+#define SSH2_MSG_KEX_ROAMING_AUTH 32
+#define SSH2_MSG_KEX_ROAMING_AUTH_OK 33
+#define SSH2_MSG_KEX_ROAMING_AUTH_FAIL 34
+
+/* Certificate types for OpenSSH certificate keys extension */
+#define SSH2_CERT_TYPE_USER 1
+#define SSH2_CERT_TYPE_HOST 2
diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config
index e5045a5..1edf164 100644
--- a/crypto/openssh/ssh_config
+++ b/crypto/openssh/ssh_config
@@ -1,4 +1,4 @@
-# $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $
+# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $
# $FreeBSD$
# This is the ssh client system-wide configuration file. See
@@ -45,4 +45,5 @@
# TunnelDevice any:any
# PermitLocalCommand no
# VisualHostKey no
-# VersionAddendum FreeBSD-20091001
+# ProxyCommand ssh -q -W %h:%p gateway.example.com
+# VersionAddendum FreeBSD-20100308
diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
index b0497d1..0f67fdc 100644
--- a/crypto/openssh/ssh_config.5
+++ b/crypto/openssh/ssh_config.5
@@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.119 2009/02/22 23:50:57 djm Exp $
+.\" $OpenBSD: ssh_config.5,v 1.129 2010/03/05 10:28:21 djm Exp $
.\" $FreeBSD$
-.Dd February 22 2009
+.Dd March 5 2010
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -560,6 +560,12 @@ and
for protocol version 2.
Additionally, any identities represented by the authentication agent
will be used for authentication.
+.Xr ssh 1
+will try to load certificate information from the filename obtained by
+appending
+.Pa -cert.pub
+to the path of a specified
+.Cm IdentityFile .
.Pp
The file name may use the tilde
syntax to refer to a user's home directory or one of the following
@@ -617,6 +623,13 @@ The following escape character substitutions will be performed:
(remote user name) or
.Ql %u
(local user name).
+.Pp
+The command is run synchronously and does not have access to the
+session of the
+.Xr ssh 1
+that spawned it.
+It should not be used for interactive commands.
+.Pp
This directive is ignored unless
.Cm PermitLocalCommand
has been enabled.
@@ -705,6 +718,12 @@ or
.Dq no .
The default is
.Dq no .
+.It Cm PKCS11Provider
+Specifies which PKCS#11 provider to use.
+The argument to this keyword is the PKCS#11 shared libary
+.Xr ssh 1
+should use to communicate with a PKCS#11 token providing the user's
+private RSA key.
.It Cm Port
Specifies the port number to connect on the remote host.
The default is 22.
@@ -731,11 +750,13 @@ The possible values are
and
.Sq 2 .
Multiple versions must be comma-separated.
-The default is
-.Dq 2,1 .
-This means that ssh
-tries version 2 and falls back to version 1
+When this option is set to
+.Dq 2,1
+.Nm ssh
+will try version 2 and fall back to version 1
if version 2 is not available.
+The default is
+.Sq 2 .
.It Cm ProxyCommand
Specifies the command to use to connect to the server.
The command
@@ -919,13 +940,6 @@ channel to request a response from the server.
The default
is 0, indicating that these messages will not be sent to the server.
This option applies to protocol version 2 only.
-.It Cm SmartcardDevice
-Specifies which smartcard device to use.
-The argument to this keyword is the device
-.Xr ssh 1
-should use to communicate with a smartcard used for storing the user's
-private RSA key.
-By default, no device is specified and smartcard support is not activated.
.It Cm StrictHostKeyChecking
If this flag is set to
.Dq yes ,
@@ -1073,7 +1087,7 @@ in
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20091001 .
+.Dq FreeBSD-20100308 .
.It Cm VisualHostKey
If this flag is set to
.Dq yes ,
diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h
index 89978fc..caa14c8 100644
--- a/crypto/openssh/ssh_namespace.h
+++ b/crypto/openssh/ssh_namespace.h
@@ -20,6 +20,7 @@
#define add_host_to_hostfile ssh_add_host_to_hostfile
#define add_recv_bytes ssh_add_recv_bytes
#define addargs ssh_addargs
+#define addr_match_cidr_list ssh_addr_match_cidr_list
#define addr_match_list ssh_addr_match_list
#define ask_permission ssh_ask_permission
#define atomicio ssh_atomicio
@@ -55,6 +56,7 @@
#define buffer_get_short_ret ssh_buffer_get_short_ret
#define buffer_get_string ssh_buffer_get_string
#define buffer_get_string_ptr ssh_buffer_get_string_ptr
+#define buffer_get_string_ptr_ret ssh_buffer_get_string_ptr_ret
#define buffer_get_string_ret ssh_buffer_get_string_ret
#define buffer_init ssh_buffer_init
#define buffer_len ssh_buffer_len
@@ -90,6 +92,7 @@
#define channel_close_all ssh_channel_close_all
#define channel_close_fd ssh_channel_close_fd
#define channel_connect_by_listen_address ssh_channel_connect_by_listen_address
+#define channel_connect_stdio_fwd ssh_channel_connect_stdio_fwd
#define channel_connect_to ssh_channel_connect_to
#define channel_find_open ssh_channel_find_open
#define channel_free ssh_channel_free
@@ -117,7 +120,6 @@
#define channel_prepare_select ssh_channel_prepare_select
#define channel_print_adm_permitted_opens ssh_channel_print_adm_permitted_opens
#define channel_register_cleanup ssh_channel_register_cleanup
-#define channel_register_confirm ssh_channel_register_confirm
#define channel_register_filter ssh_channel_register_filter
#define channel_register_open_confirm ssh_channel_register_open_confirm
#define channel_register_status_confirm ssh_channel_register_status_confirm
@@ -167,11 +169,8 @@
#define current_keys ssh_current_keys
#define datafellows ssh_datafellows
#define debug ssh_debug
-#define debug ssh_debug
-#define debug2 ssh_debug2
#define debug2 ssh_debug2
#define debug3 ssh_debug3
-#define debug3 ssh_debug3
#define decode_reply ssh_decode_reply
#define deny_input_open ssh_deny_input_open
#define derive_ssh1_session_id ssh_derive_ssh1_session_id
@@ -195,7 +194,6 @@
#define enable_compat13 ssh_enable_compat13
#define enable_compat20 ssh_enable_compat20
#define error ssh_error
-#define error ssh_error
#define evp_acss ssh_evp_acss
#define evp_aes_128_ctr ssh_evp_aes_128_ctr
#define evp_rijndael ssh_evp_rijndael
@@ -203,7 +201,6 @@
#define evp_ssh1_bf ssh_evp_ssh1_bf
#define export_dns_rr ssh_export_dns_rr
#define fatal ssh_fatal
-#define fatal ssh_fatal
#define fmt_scaled ssh_fmt_scaled
#define freeargs ssh_freeargs
#define freerrset ssh_freerrset
@@ -241,14 +238,22 @@
#define kexdh_client ssh_kexdh_client
#define kexgex_client ssh_kexgex_client
#define kexgex_hash ssh_kexgex_hash
+#define key_add_private ssh_key_add_private
+#define key_cert_check_authority ssh_key_cert_check_authority
+#define key_cert_copy ssh_key_cert_copy
+#define key_certify ssh_key_certify
#define key_demote ssh_key_demote
+#define key_drop_cert ssh_key_drop_cert
#define key_equal ssh_key_equal
+#define key_equal_public ssh_key_equal_public
#define key_fingerprint ssh_key_fingerprint
#define key_fingerprint_raw ssh_key_fingerprint_raw
#define key_free ssh_key_free
#define key_from_blob ssh_key_from_blob
#define key_from_private ssh_key_from_private
#define key_generate ssh_key_generate
+#define key_in_file ssh_key_in_file
+#define key_is_cert ssh_key_is_cert
#define key_load_private ssh_key_load_private
#define key_load_private_pem ssh_key_load_private_pem
#define key_load_private_type ssh_key_load_private_type
@@ -264,8 +269,10 @@
#define key_size ssh_key_size
#define key_ssh_name ssh_key_ssh_name
#define key_to_blob ssh_key_to_blob
+#define key_to_certified ssh_key_to_certified
#define key_type ssh_key_type
#define key_type_from_name ssh_key_type_from_name
+#define key_type_plain ssh_key_type_plain
#define key_verify ssh_key_verify
#define key_write ssh_key_write
#define log_facility_name ssh_log_facility_name
@@ -274,7 +281,6 @@
#define log_level_name ssh_log_level_name
#define log_level_number ssh_log_level_number
#define logit ssh_logit
-#define logit ssh_logit
#define lookup_key_in_hostfile_by_type ssh_lookup_key_in_hostfile_by_type
#define mac_clear ssh_mac_clear
#define mac_compute ssh_mac_compute
@@ -366,6 +372,12 @@
#define percent_expand ssh_percent_expand
#define permanently_drop_suid ssh_permanently_drop_suid
#define permanently_set_uid ssh_permanently_set_uid
+#define pkcs11_add_provider ssh_pkcs11_add_provider
+#define pkcs11_del_provider ssh_pkcs11_del_provider
+#define pkcs11_init ssh_pkcs11_init
+#define pkcs11_interactive ssh_pkcs11_interactive
+#define pkcs11_providers ssh_pkcs11_providers
+#define pkcs11_terminate ssh_pkcs11_terminate
#define prime_test ssh_prime_test
#define proto_spec ssh_proto_spec
#define put_host_port ssh_put_host_port
@@ -398,6 +410,7 @@
#define set_nonblock ssh_set_nonblock
#define shadow_pw ssh_shadow_pw
#define sigdie ssh_sigdie
+#define sock_set_v6only ssh_sock_set_v6only
#define ssh1_3des_iv ssh_ssh1_3des_iv
#define start_progress_meter ssh_start_progress_meter
#define stop_progress_meter ssh_stop_progress_meter
@@ -421,7 +434,6 @@
#define uudecode ssh_uudecode
#define uuencode ssh_uuencode
#define verbose ssh_verbose
-#define verbose ssh_verbose
#define verify_host_key_dns ssh_verify_host_key_dns
#define vis ssh_vis
#define x11_connect_display ssh_x11_connect_display
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index 19009cd..a54d942 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.214 2009/05/28 16:50:16 andreas Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.220 2010/03/04 10:36:03 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -29,6 +29,7 @@
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -58,6 +59,7 @@
#include "misc.h"
#include "dns.h"
#include "roaming.h"
+#include "ssh2.h"
#include "version.h"
char *client_version_string = NULL;
@@ -192,8 +194,11 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
return sock;
}
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (sock < 0)
+ if (sock < 0) {
error("socket: %.100s", strerror(errno));
+ return -1;
+ }
+ fcntl(sock, F_SETFD, FD_CLOEXEC);
/* Bind the socket to an alternative local IP address */
if (options.bind_address == NULL)
@@ -573,6 +578,23 @@ confirm(const char *prompt)
}
}
+static int
+check_host_cert(const char *host, const Key *host_key)
+{
+ const char *reason;
+
+ if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) {
+ error("%s", reason);
+ return 0;
+ }
+ if (buffer_len(&host_key->cert->constraints) != 0) {
+ error("Certificate for %s contains unsupported constraint(s)",
+ host);
+ return 0;
+ }
+ return 1;
+}
+
/*
* check whether the supplied host key is valid, return -1 if the key
* is not valid. the user_hostfile will not be updated if 'readonly' is true.
@@ -585,13 +607,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
Key *host_key, int readonly, const char *user_hostfile,
const char *system_hostfile)
{
- Key *file_key;
- const char *type = key_type(host_key);
+ Key *file_key, *raw_key = NULL;
+ const char *type;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
HostStatus host_status;
HostStatus ip_status;
- int r, local = 0, host_ip_differ = 0;
+ int r, want_cert, local = 0, host_ip_differ = 0;
int salen;
char ntop[NI_MAXHOST];
char msg[1024];
@@ -664,11 +686,15 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
host = put_host_port(hostname, port);
}
+ retry:
+ want_cert = key_is_cert(host_key);
+ type = key_type(host_key);
+
/*
* Store the host key from the known host file in here so that we can
* compare it with the key for the IP address.
*/
- file_key = key_new(host_key->type);
+ file_key = key_new(key_is_cert(host_key) ? KEY_UNSPEC : host_key->type);
/*
* Check if the host key is present in the user's list of known
@@ -684,9 +710,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
}
/*
* Also perform check for the ip address, skip the check if we are
- * localhost or the hostname was an ip address to begin with
+ * localhost, looking for a certificate, or the hostname was an ip
+ * address to begin with.
*/
- if (options.check_host_ip) {
+ if (!want_cert && options.check_host_ip) {
Key *ip_key = key_new(host_key->type);
ip_file = user_hostfile;
@@ -710,11 +737,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
switch (host_status) {
case HOST_OK:
/* The host is known and the key matches. */
- debug("Host '%.200s' is known and matches the %s host key.",
- host, type);
- debug("Found key in %s:%d", host_file, host_line);
+ debug("Host '%.200s' is known and matches the %s host %s.",
+ host, type, want_cert ? "certificate" : "key");
+ debug("Found %s in %s:%d",
+ want_cert ? "certificate" : "key", host_file, host_line);
+ if (want_cert && !check_host_cert(hostname, host_key))
+ goto fail;
if (options.check_host_ip && ip_status == HOST_NEW) {
- if (readonly)
+ if (readonly || want_cert)
logit("%s host key for IP address "
"'%.128s' not in list of known hosts.",
type, ip);
@@ -746,7 +776,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
break;
}
}
- if (readonly)
+ if (readonly || want_cert)
goto fail;
/* The host is new. */
if (options.strict_host_key_checking == 1) {
@@ -830,7 +860,37 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
logit("Warning: Permanently added '%.200s' (%s) to the "
"list of known hosts.", hostp, type);
break;
+ case HOST_REVOKED:
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("@ WARNING: REVOKED HOST KEY DETECTED! @");
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("The %s host key for %s is marked as revoked.", type, host);
+ error("This could mean that a stolen key is being used to");
+ error("impersonate this host.");
+
+ /*
+ * If strict host key checking is in use, the user will have
+ * to edit the key manually and we can only abort.
+ */
+ if (options.strict_host_key_checking) {
+ error("%s host key for %.200s was revoked and you have "
+ "requested strict checking.", type, host);
+ goto fail;
+ }
+ goto continue_unsafe;
+
case HOST_CHANGED:
+ if (want_cert) {
+ /*
+ * This is only a debug() since it is valid to have
+ * CAs with wildcard DNS matches that don't match
+ * all hosts that one might visit.
+ */
+ debug("Host certificate authority does not "
+ "match %s in %s:%d", CA_MARKER,
+ host_file, host_line);
+ goto fail;
+ }
if (readonly == ROQUIET)
goto fail;
if (options.check_host_ip && host_ip_differ) {
@@ -868,6 +928,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
goto fail;
}
+ continue_unsafe:
/*
* If strict host key checking has not been requested, allow
* the connection but without MITM-able authentication or
@@ -926,7 +987,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
* XXX Should permit the user to change to use the new id.
* This could be done by converting the host key to an
* identifying sentence, tell that the host identifies itself
- * by that sentence, and ask the user if he/she whishes to
+ * by that sentence, and ask the user if he/she wishes to
* accept the authentication.
*/
break;
@@ -967,6 +1028,20 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
return 0;
fail:
+ if (want_cert && host_status != HOST_REVOKED) {
+ /*
+ * No matching certificate. Downgrade cert to raw key and
+ * search normally.
+ */
+ debug("No matching CA found. Retry with plain key");
+ raw_key = key_from_private(host_key);
+ if (key_drop_cert(raw_key) != 0)
+ fatal("Couldn't drop certificate");
+ host_key = raw_key;
+ goto retry;
+ }
+ if (raw_key != NULL)
+ key_free(raw_key);
xfree(ip);
xfree(host);
return -1;
@@ -979,7 +1054,8 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
struct stat st;
int flags = 0;
- if (options.verify_host_key_dns &&
+ /* XXX certs are not yet supported for DNS */
+ if (!key_is_cert(host_key) && options.verify_host_key_dns &&
verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
if (flags & DNS_VERIFY_FOUND) {
diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c
index 260c630..2a5943e 100644
--- a/crypto/openssh/sshconnect2.c
+++ b/crypto/openssh/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.171 2009/03/05 07:18:19 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.180 2010/02/26 20:29:54 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
@@ -152,6 +153,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
+ if (options.use_roaming && !kex->roaming) {
+ debug("Roaming not allowed by server");
+ options.use_roaming = 0;
+ }
+
session_id2 = kex->session_id;
session_id2_len = kex->session_id_len;
@@ -210,6 +216,7 @@ struct Authmethod {
};
void input_userauth_success(int, u_int32_t, void *);
+void input_userauth_success_unexpected(int, u_int32_t, void *);
void input_userauth_failure(int, u_int32_t, void *);
void input_userauth_banner(int, u_int32_t, void *);
void input_userauth_error(int, u_int32_t, void *);
@@ -414,7 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
if (len > 65536)
len = 65536;
msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
- strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
+ strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
fprintf(stderr, "%s", msg);
xfree(msg);
}
@@ -427,12 +434,15 @@ void
input_userauth_success(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
+
if (authctxt == NULL)
fatal("input_userauth_success: no authentication context");
if (authctxt->authlist) {
xfree(authctxt->authlist);
authctxt->authlist = NULL;
}
+ if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
+ authctxt->method->cleanup(authctxt);
if (authctxt->methoddata) {
xfree(authctxt->methoddata);
authctxt->methoddata = NULL;
@@ -440,6 +450,18 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
authctxt->success = 1; /* break out */
}
+void
+input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
+{
+ Authctxt *authctxt = ctxt;
+
+ if (authctxt == NULL)
+ fatal("%s: no authentication context", __func__);
+
+ fatal("Unexpected authentication success during %s.",
+ authctxt->method->name);
+}
+
/* ARGSUSED */
void
input_userauth_failure(int type, u_int32_t seq, void *ctxt)
@@ -782,6 +804,8 @@ userauth_passwd(Authctxt *authctxt)
static int attempt = 0;
char prompt[150];
char *password;
+ const char *host = options.host_key_alias ? options.host_key_alias :
+ authctxt->host;
if (attempt++ >= options.number_of_password_prompts)
return 0;
@@ -790,7 +814,7 @@ userauth_passwd(Authctxt *authctxt)
error("Permission denied, please try again.");
snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
- authctxt->server_user, authctxt->host);
+ authctxt->server_user, host);
password = read_passphrase(prompt, 0);
packet_start(SSH2_MSG_USERAUTH_REQUEST);
packet_put_cstring(authctxt->server_user);
@@ -819,6 +843,8 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
Authctxt *authctxt = ctxt;
char *info, *lang, *password = NULL, *retype = NULL;
char prompt[150];
+ const char *host = options.host_key_alias ? options.host_key_alias :
+ authctxt->host;
debug2("input_userauth_passwd_changereq");
@@ -839,7 +865,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
packet_put_char(1); /* additional info */
snprintf(prompt, sizeof(prompt),
"Enter %.30s@%.128s's old password: ",
- authctxt->server_user, authctxt->host);
+ authctxt->server_user, host);
password = read_passphrase(prompt, 0);
packet_put_cstring(password);
memset(password, 0, strlen(password));
@@ -848,7 +874,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
while (password == NULL) {
snprintf(prompt, sizeof(prompt),
"Enter %.30s@%.128s's new password: ",
- authctxt->server_user, authctxt->host);
+ authctxt->server_user, host);
password = read_passphrase(prompt, RP_ALLOW_EOF);
if (password == NULL) {
/* bail out */
@@ -856,7 +882,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
}
snprintf(prompt, sizeof(prompt),
"Retype %.30s@%.128s's new password: ",
- authctxt->server_user, authctxt->host);
+ authctxt->server_user, host);
retype = read_passphrase(prompt, 0);
if (strcmp(password, retype) != 0) {
memset(password, 0, strlen(password));
@@ -1224,7 +1250,7 @@ load_identity_file(char *filename)
{
Key *private;
char prompt[300], *passphrase;
- int perm_ok, quit, i;
+ int perm_ok = 0, quit, i;
struct stat st;
if (stat(filename, &st) < 0) {
@@ -1285,6 +1311,8 @@ pubkey_prepare(Authctxt *authctxt)
key = options.identity_keys[i];
if (key && key->type == KEY_RSA1)
continue;
+ if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)
+ continue;
options.identity_keys[i] = NULL;
id = xcalloc(1, sizeof(*id));
id->key = key;
@@ -1488,7 +1516,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
debug2("ssh_keysign called");
if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
- error("ssh_keysign: no installed: %s", strerror(errno));
+ error("ssh_keysign: not installed: %s", strerror(errno));
return -1;
}
if (fflush(stdout) != 0)
@@ -1506,6 +1534,8 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
return -1;
}
if (pid == 0) {
+ /* keep the socket on exec */
+ fcntl(packet_get_connection_in(), F_SETFD, 0);
permanently_drop_suid(getuid());
close(from[0]);
if (dup2(from[1], STDOUT_FILENO) < 0)
@@ -1558,10 +1588,10 @@ userauth_hostbased(Authctxt *authctxt)
Sensitive *sensitive = authctxt->sensitive;
Buffer b;
u_char *signature, *blob;
- char *chost, *pkalg, *p, myname[NI_MAXHOST];
+ char *chost, *pkalg, *p;
const char *service;
u_int blen, slen;
- int ok, i, len, found = 0;
+ int ok, i, found = 0;
/* check for a useful key */
for (i = 0; i < sensitive->nkeys; i++) {
@@ -1582,23 +1612,13 @@ userauth_hostbased(Authctxt *authctxt)
return 0;
}
/* figure out a name for the client host */
- p = NULL;
- if (packet_connection_is_on_socket())
- p = get_local_name(packet_get_connection_in());
- if (p == NULL) {
- if (gethostname(myname, sizeof(myname)) == -1) {
- verbose("userauth_hostbased: gethostname: %s",
- strerror(errno));
- } else
- p = xstrdup(myname);
- }
+ p = get_local_name(packet_get_connection_in());
if (p == NULL) {
error("userauth_hostbased: cannot get local ipaddr/name");
key_free(private);
xfree(blob);
return 0;
}
- len = strlen(p) + 2;
xasprintf(&chost, "%s.", p);
debug2("userauth_hostbased: chost %s", chost);
xfree(p);
@@ -1709,6 +1729,8 @@ userauth_jpake(Authctxt *authctxt)
/* Expect step 1 packet from peer */
dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
input_userauth_jpake_server_step1);
+ dispatch_set(SSH2_MSG_USERAUTH_SUCCESS,
+ &input_userauth_success_unexpected);
return 1;
}
@@ -1721,6 +1743,7 @@ userauth_jpake_cleanup(Authctxt *authctxt)
jpake_free(authctxt->methoddata);
authctxt->methoddata = NULL;
}
+ dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
}
#endif /* JPAKE */
diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8
index 2e3c0a5..b4a88f8 100644
--- a/crypto/openssh/sshd.8
+++ b/crypto/openssh/sshd.8
@@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd.8,v 1.248 2009/03/26 08:38:39 sobrado Exp $
+.\" $OpenBSD: sshd.8,v 1.255 2010/03/05 06:50:35 jmc Exp $
.\" $FreeBSD$
-.Dd March 26 2009
+.Dd March 5 2010
.Dt SSHD 8
.Os
.Sh NAME
@@ -48,6 +48,7 @@
.Op Fl 46DdeiqTt
.Op Fl b Ar bits
.Op Fl C Ar connection_spec
+.Op Fl c Ar host_certificate_file
.Op Fl f Ar config_file
.Op Fl g Ar login_grace_time
.Op Fl h Ar host_key_file
@@ -120,6 +121,15 @@ and
All are required and may be supplied in any order, either with multiple
.Fl C
options or as a comma-separated list.
+.It Fl c Ar host_certificate_file
+Specifies a path to a certificate file to identify
+.Nm
+during key exchange.
+The certificate file must match a host key file specified using the
+.Fl h
+option or the
+.Cm HostKey
+configuration directive.
.It Fl D
When this option is specified,
.Nm
@@ -128,8 +138,8 @@ This allows easy monitoring of
.Nm sshd .
.It Fl d
Debug mode.
-The server sends verbose debug output to the system
-log, and does not put itself in the background.
+The server sends verbose debug output to standard error,
+and does not put itself in the background.
The server also will not fork and will only process one connection.
This option is only intended for debugging for the server.
Multiple
@@ -261,7 +271,7 @@ or
.El
.Sh AUTHENTICATION
The OpenSSH SSH daemon supports SSH protocols 1 and 2.
-Both protocols are supported by default,
+The default is to use protocol 2 only,
though this can be changed via the
.Cm Protocol
option in
@@ -501,6 +511,13 @@ No spaces are permitted, except within double quotes.
The following option specifications are supported (note
that option keywords are case-insensitive):
.Bl -tag -width Ds
+.It Cm cert-authority
+Specifies that the listed key is a certification authority (CA) that is
+trusted to validate signed certificates for user authentication.
+.Pp
+Certificates may encode access restrictions similar to these key options.
+If both certificate restrictions and key options are present, the most
+restrictive union of the two is applied.
.It Cm command="command"
Specifies that the command is executed whenever this key is used for
authentication.
@@ -520,6 +537,10 @@ The command originally supplied by the client is available in the
.Ev SSH_ORIGINAL_COMMAND
environment variable.
Note that this option applies to shell, command or subsystem execution.
+Also note that this command may be superseded by either a
+.Xr sshd_config 5
+.Cm ForceCommand
+directive or a command embedded in a certificate.
.It Cm environment="NAME=value"
Specifies that the string is to be added to the environment when
logging in using this key.
@@ -616,10 +637,19 @@ be prepared by the administrator (optional), and the per-user file is
maintained automatically: whenever the user connects from an unknown host,
its key is added to the per-user file.
.Pp
-Each line in these files contains the following fields: hostnames,
-bits, exponent, modulus, comment.
+Each line in these files contains the following fields: markers (optional),
+hostnames, bits, exponent, modulus, comment.
The fields are separated by spaces.
.Pp
+The marker is optional, but if it is present then it must be one of
+.Dq @cert-authority ,
+to indicate that the line contains a certification authority (CA) key,
+or
+.Dq @revoked ,
+to indicate that the key contained on the line is revoked and must not ever
+be accepted.
+Only one marker should be used on a key line.
+.Pp
Hostnames is a comma-separated list of patterns
.Pf ( Ql *
and
@@ -659,8 +689,25 @@ Lines starting with
and empty lines are ignored as comments.
.Pp
When performing host authentication, authentication is accepted if any
-matching line has the proper key.
-It is thus permissible (but not
+matching line has the proper key; either one that matches exactly or,
+if the server has presented a certificate for authentication, the key
+of the certification authority that signed the certificate.
+For a key to be trusted as a certification authority, it must use the
+.Dq @cert-authority
+marker described above.
+.Pp
+The known hosts file also provides a facility to mark keys as revoked,
+for example when it is known that the associated private key has been
+stolen.
+Revoked keys are specified by including the
+.Dq @revoked
+marker at the beginning of the key line, and are never accepted for
+authentication or as certification authorities, but instead will
+produce a warning from
+.Xr ssh 1
+when they are encountered.
+.Pp
+It is permissible (but not
recommended) to have several lines or different host keys for the same
names.
This will inevitably happen when short forms of host names
@@ -671,10 +718,16 @@ accepted if valid information can be found from either file.
.Pp
Note that the lines in these files are typically hundreds of characters
long, and you definitely don't want to type in the host keys by hand.
-Rather, generate them by a script
+Rather, generate them by a script,
+.Xr ssh-keyscan 1
or by taking
.Pa /etc/ssh/ssh_host_key.pub
and adding the host names at the front.
+.Xr ssh-keygen 1
+also offers some basic automated editing for
+.Pa ~/.ssh/known_hosts
+including removing hosts matching a host name and converting all host
+names to their hashed representations.
.Pp
An example ssh_known_hosts file:
.Bd -literal -offset 3n
@@ -684,6 +737,10 @@ cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
# A hashed hostname
|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
AAAA1234.....=
+# A revoked key
+@revoked * ssh-rsa AAAAB5W...
+# A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
+@cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
.Ed
.Sh FILES
.Bl -tag -width Ds -compact
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index 166f42b..5bd7cd4 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.367 2009/05/28 16:50:16 andreas Exp $ */
+/* $OpenBSD: sshd.c,v 1.374 2010/03/07 11:57:13 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -216,6 +216,7 @@ struct {
Key *server_key; /* ephemeral server key */
Key *ssh1_host_key; /* ssh1 host key */
Key **host_keys; /* all private host keys */
+ Key **host_certificates; /* all public host certificates */
int have_ssh1_key;
int have_ssh2_key;
u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH];
@@ -320,6 +321,7 @@ sighup_restart(void)
close_listen_socks();
close_startup_pipes();
alarm(0); /* alarm timer persists across exec */
+ signal(SIGHUP, SIG_IGN); /* will be restored after exec */
execv(saved_argv[0], saved_argv);
logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
strerror(errno));
@@ -555,6 +557,10 @@ destroy_sensitive_data(void)
key_free(sensitive_data.host_keys[i]);
sensitive_data.host_keys[i] = NULL;
}
+ if (sensitive_data.host_certificates[i]) {
+ key_free(sensitive_data.host_certificates[i]);
+ sensitive_data.host_certificates[i] = NULL;
+ }
}
sensitive_data.ssh1_host_key = NULL;
memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH);
@@ -581,6 +587,7 @@ demote_sensitive_data(void)
if (tmp->type == KEY_RSA1)
sensitive_data.ssh1_host_key = tmp;
}
+ /* Certs do not need demotion */
}
/* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */
@@ -727,10 +734,11 @@ list_hostkey_types(void)
const char *p;
char *ret;
int i;
+ Key *key;
buffer_init(&b);
for (i = 0; i < options.num_host_key_files; i++) {
- Key *key = sensitive_data.host_keys[i];
+ key = sensitive_data.host_keys[i];
if (key == NULL)
continue;
switch (key->type) {
@@ -742,6 +750,19 @@ list_hostkey_types(void)
buffer_append(&b, p, strlen(p));
break;
}
+ /* If the private key has a cert peer, then list that too */
+ key = sensitive_data.host_certificates[i];
+ if (key == NULL)
+ continue;
+ switch (key->type) {
+ case KEY_RSA_CERT:
+ case KEY_DSA_CERT:
+ if (buffer_len(&b) > 0)
+ buffer_append(&b, ",", 1);
+ p = key_ssh_name(key);
+ buffer_append(&b, p, strlen(p));
+ break;
+ }
}
buffer_append(&b, "\0", 1);
ret = xstrdup(buffer_ptr(&b));
@@ -750,20 +771,37 @@ list_hostkey_types(void)
return ret;
}
-Key *
-get_hostkey_by_type(int type)
+static Key *
+get_hostkey_by_type(int type, int need_private)
{
int i;
+ Key *key;
for (i = 0; i < options.num_host_key_files; i++) {
- Key *key = sensitive_data.host_keys[i];
+ if (type == KEY_RSA_CERT || type == KEY_DSA_CERT)
+ key = sensitive_data.host_certificates[i];
+ else
+ key = sensitive_data.host_keys[i];
if (key != NULL && key->type == type)
- return key;
+ return need_private ?
+ sensitive_data.host_keys[i] : key;
}
return NULL;
}
Key *
+get_hostkey_public_by_type(int type)
+{
+ return get_hostkey_by_type(type, 0);
+}
+
+Key *
+get_hostkey_private_by_type(int type)
+{
+ return get_hostkey_by_type(type, 1);
+}
+
+Key *
get_hostkey_by_index(int ind)
{
if (ind < 0 || ind >= options.num_host_key_files)
@@ -777,8 +815,13 @@ get_hostkey_index(Key *key)
int i;
for (i = 0; i < options.num_host_key_files; i++) {
- if (key == sensitive_data.host_keys[i])
- return (i);
+ if (key_is_cert(key)) {
+ if (key == sensitive_data.host_certificates[i])
+ return (i);
+ } else {
+ if (key == sensitive_data.host_keys[i])
+ return (i);
+ }
}
return (-1);
}
@@ -817,9 +860,9 @@ usage(void)
fprintf(stderr, "%s, %s\n",
SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
fprintf(stderr,
-"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n"
-" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n"
-" [-o option] [-p port] [-u len]\n"
+"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n"
+" [-f config_file] [-g login_grace_time] [-h host_key_file]\n"
+" [-k key_gen_time] [-o option] [-p port] [-u len]\n"
);
exit(1);
}
@@ -990,15 +1033,9 @@ server_listen(void)
&on, sizeof(on)) == -1)
error("setsockopt SO_REUSEADDR: %s", strerror(errno));
-#ifdef IPV6_V6ONLY
/* Only communicate in IPv6 over AF_INET6 sockets. */
- if (ai->ai_family == AF_INET6) {
- if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
- &on, sizeof(on)) == -1)
- error("setsockopt IPV6_V6ONLY: %s",
- strerror(errno));
- }
-#endif
+ if (ai->ai_family == AF_INET6)
+ sock_set_v6only(listen_sock);
debug("Bind to port %s on %s.", strport, ntop);
@@ -1252,7 +1289,7 @@ main(int ac, char **av)
{
extern char *optarg;
extern int optind;
- int opt, i, on = 1;
+ int opt, i, j, on = 1;
int sock_in = -1, sock_out = -1, newsock = -1;
const char *remote_ip;
char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
@@ -1293,10 +1330,6 @@ main(int ac, char **av)
/* Initialize configuration options to their default values. */
initialize_server_options(&options);
- /* Avoid killing the process in high-pressure swapping environments. */
- if (madvise(NULL, 0, MADV_PROTECT) != 0)
- debug("madvise(): %.200s", strerror(errno));
-
/* Parse command-line arguments. */
while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
switch (opt) {
@@ -1309,6 +1342,14 @@ main(int ac, char **av)
case 'f':
config_file_name = optarg;
break;
+ case 'c':
+ if (options.num_host_cert_files >= MAX_HOSTCERTS) {
+ fprintf(stderr, "too many host certificates.\n");
+ exit(1);
+ }
+ options.host_cert_files[options.num_host_cert_files++] =
+ derelativise_path(optarg);
+ break;
case 'd':
if (debug_flag == 0) {
debug_flag = 1;
@@ -1371,7 +1412,8 @@ main(int ac, char **av)
fprintf(stderr, "too many host keys.\n");
exit(1);
}
- options.host_key_files[options.num_host_key_files++] = optarg;
+ options.host_key_files[options.num_host_key_files++] =
+ derelativise_path(optarg);
break;
case 't':
test_flag = 1;
@@ -1555,6 +1597,46 @@ main(int ac, char **av)
exit(1);
}
+ /*
+ * Load certificates. They are stored in an array at identical
+ * indices to the public keys that they relate to.
+ */
+ sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
+ sizeof(Key *));
+ for (i = 0; i < options.num_host_key_files; i++)
+ sensitive_data.host_certificates[i] = NULL;
+
+ for (i = 0; i < options.num_host_cert_files; i++) {
+ key = key_load_public(options.host_cert_files[i], NULL);
+ if (key == NULL) {
+ error("Could not load host certificate: %s",
+ options.host_cert_files[i]);
+ continue;
+ }
+ if (!key_is_cert(key)) {
+ error("Certificate file is not a certificate: %s",
+ options.host_cert_files[i]);
+ key_free(key);
+ continue;
+ }
+ /* Find matching private key */
+ for (j = 0; j < options.num_host_key_files; j++) {
+ if (key_equal_public(key,
+ sensitive_data.host_keys[j])) {
+ sensitive_data.host_certificates[j] = key;
+ break;
+ }
+ }
+ if (j >= options.num_host_key_files) {
+ error("No matching private key for certificate: %s",
+ options.host_cert_files[i]);
+ key_free(key);
+ continue;
+ }
+ sensitive_data.host_certificates[j] = key;
+ debug("host certificate: #%d type %d %s", j, key->type,
+ key_type(key));
+ }
/* Check certain values for sanity. */
if (options.protocol & SSH_PROTO_1) {
if (options.server_key_bits < 512 ||
@@ -1663,6 +1745,10 @@ main(int ac, char **av)
/* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
+ /* Avoid killing the process in high-pressure swapping environments. */
+ if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0)
+ debug("madvise(): %.200s", strerror(errno));
+
/* Initialize the random number generator. */
arc4random_stir();
@@ -1677,6 +1763,7 @@ main(int ac, char **av)
if (inetd_flag) {
server_accept_inetd(&sock_in, &sock_out);
} else {
+ platform_pre_listen();
server_listen();
if (options.protocol & SSH_PROTO_1)
@@ -1766,6 +1853,10 @@ main(int ac, char **av)
sock_in, sock_out, newsock, startup_pipe, config_s[0]);
}
+ /* Executed child processes don't need these. */
+ fcntl(sock_out, F_SETFD, FD_CLOEXEC);
+ fcntl(sock_in, F_SETFD, FD_CLOEXEC);
+
/*
* Disable the key regeneration alarm. We will not regenerate the
* key since we are no longer in a position to give it to anyone. We
@@ -1886,6 +1977,7 @@ main(int ac, char **av)
/* prepare buffer to collect messages to display to user after login */
buffer_init(&loginmsg);
+ auth_debug_reset();
if (use_privsep)
if (privsep_preauth(authctxt) == 1)
@@ -2242,7 +2334,8 @@ do_ssh2_kex(void)
kex->server = 1;
kex->client_version_string=client_version_string;
kex->server_version_string=server_version_string;
- kex->load_host_key=&get_hostkey_by_type;
+ kex->load_host_public_key=&get_hostkey_public_by_type;
+ kex->load_host_private_key=&get_hostkey_private_by_type;
kex->host_key_index=&get_hostkey_index;
xxx_kex = kex;
diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
index fc2b683..44b7582 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -1,4 +1,4 @@
-# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $
+# $OpenBSD: sshd_config,v 1.81 2009/10/08 14:03:41 markus Exp $
# $FreeBSD$
# This is the sshd server system-wide configuration file. See
@@ -14,17 +14,15 @@
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options.
-#VersionAddendum FreeBSD-20091001
+#VersionAddendum FreeBSD-20100308
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
-# Disable legacy (protocol version 1) support in the server for new
-# installations. In future the default will change to require explicit
-# activation of protocol 1
-Protocol 2
+# The default requires explicit activation of protocol 1
+#Protocol 2
# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
index 84b0ae8..d0d3053 100644
--- a/crypto/openssh/sshd_config.5
+++ b/crypto/openssh/sshd_config.5
@@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd_config.5,v 1.106 2009/04/21 15:13:17 stevesk Exp $
+.\" $OpenBSD: sshd_config.5,v 1.120 2010/03/04 23:17:25 djm Exp $
.\" $FreeBSD$
-.Dd April 21 2009
+.Dd March 4 2010
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@@ -183,16 +183,16 @@ PAM or though authentication styles supported in
The default is
.Dq yes .
.It Cm ChrootDirectory
-Specifies a path to
+Specifies the pathname of a directory to
.Xr chroot 2
to after authentication.
-This path, and all its components, must be root-owned directories that are
+All components of the pathname must be root-owned directories that are
not writable by any other user or group.
After the chroot,
.Xr sshd 8
changes the working directory to the user's home directory.
.Pp
-The path may contain the following tokens that are expanded at runtime once
+The pathname may contain the following tokens that are expanded at runtime once
the connecting user has been authenticated: %% is replaced by a literal '%',
%h is replaced by the home directory of the user being authenticated, and
%u is replaced by the username of that user.
@@ -412,6 +412,14 @@ uses the name supplied by the client rather than
attempting to resolve the name from the TCP connection itself.
The default is
.Dq no .
+.It Cm HostCertificate
+Specifies a file containing a public host certificate.
+The certificate's public key must match a private host key already specified
+by
+.Cm HostKey .
+The default behaviour of
+.Xr sshd 8
+is not to load any certificates.
.It Cm HostKey
Specifies a file containing a private host key
used by SSH.
@@ -615,6 +623,7 @@ Available keywords are
.Cm PermitEmptyPasswords ,
.Cm PermitOpen ,
.Cm PermitRootLogin ,
+.Cm PubkeyAuthentication ,
.Cm RhostsRSAAuthentication ,
.Cm RSAAuthentication ,
.Cm X11DisplayOffset ,
@@ -802,7 +811,7 @@ and
.Sq 2 .
Multiple versions must be comma-separated.
The default is
-.Dq 2 .
+.Sq 2 .
Note that the order of the protocol list does not indicate preference,
because the client selects among multiple protocol versions offered
by the server.
@@ -815,6 +824,11 @@ Specifies whether public key authentication is allowed.
The default is
.Dq yes .
Note that this option applies to protocol version 2 only.
+.It Cm RevokedKeys
+Specifies a list of revoked public keys.
+Keys listed in this file will be refused for public key authentication.
+Note that if this file is not readable, then public key authentication will
+be refused for all users.
.It Cm RhostsRSAAuthentication
Specifies whether rhosts or
.Pa /etc/hosts.equiv
@@ -840,6 +854,9 @@ This is normally desirable because novices sometimes accidentally leave their
directory or files world-writable.
The default is
.Dq yes .
+Note that this does not apply to
+.Cm ChrootDirectory ,
+whose permissions and ownership are checked unconditionally.
.It Cm Subsystem
Configures an external subsystem (e.g. file transfer daemon).
Arguments should be a subsystem name and a command (with optional arguments)
@@ -889,6 +906,22 @@ This avoids infinitely hanging sessions.
.Pp
To disable TCP keepalive messages, the value should be set to
.Dq no .
+.It Cm TrustedUserCAKeys
+Specifies a file containing public keys of certificate authorities that are
+trusted to sign user certificates for authentication.
+Keys are listed one per line; empty lines and comments starting with
+.Ql #
+are allowed.
+If a certificate is presented for authentication and has its signing CA key
+listed in this file, then it may be used for authentication for any user
+listed in the certificate's principals list.
+Note that certificates that lack a list of principals will not be permitted
+for authentication using
+.Cm TrustedUserCAKeys .
+For more details on certificates, see the
+.Sx CERTIFICATES
+section in
+.Xr ssh-keygen 1 .
.It Cm UseDNS
Specifies whether
.Xr sshd 8
@@ -955,7 +988,7 @@ The default is
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20091001 .
+.Dq FreeBSD-20100308 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.Xr sshd 8 Ns 's
diff --git a/crypto/openssh/sshpty.h b/crypto/openssh/sshpty.h
index ac90035..cfa3224 100644
--- a/crypto/openssh/sshpty.h
+++ b/crypto/openssh/sshpty.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshpty.h,v 1.11 2008/05/19 15:45:07 djm Exp $ */
+/* $OpenBSD: sshpty.h,v 1.12 2010/01/09 05:04:24 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -17,8 +17,8 @@
#include <termios.h>
struct termios *get_saved_tio(void);
-void leave_raw_mode(void);
-void enter_raw_mode(void);
+void leave_raw_mode(int);
+void enter_raw_mode(int);
int pty_allocate(int *, int *, char *, size_t);
void pty_release(const char *);
diff --git a/crypto/openssh/sshtty.c b/crypto/openssh/sshtty.c
index 21ade4e..d214ce3 100644
--- a/crypto/openssh/sshtty.c
+++ b/crypto/openssh/sshtty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshtty.c,v 1.13 2008/05/19 15:45:07 djm Exp $ */
+/* $OpenBSD: sshtty.c,v 1.14 2010/01/09 05:04:24 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -54,23 +54,25 @@ get_saved_tio(void)
}
void
-leave_raw_mode(void)
+leave_raw_mode(int quiet)
{
if (!_in_raw_mode)
return;
- if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1)
- perror("tcsetattr");
- else
+ if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) {
+ if (!quiet)
+ perror("tcsetattr");
+ } else
_in_raw_mode = 0;
}
void
-enter_raw_mode(void)
+enter_raw_mode(int quiet)
{
struct termios tio;
if (tcgetattr(fileno(stdin), &tio) == -1) {
- perror("tcgetattr");
+ if (!quiet)
+ perror("tcgetattr");
return;
}
_saved_tio = tio;
@@ -86,8 +88,9 @@ enter_raw_mode(void)
tio.c_oflag &= ~OPOST;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
- if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1)
- perror("tcsetattr");
- else
+ if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) {
+ if (!quiet)
+ perror("tcsetattr");
+ } else
_in_raw_mode = 1;
}
diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
index 581decf..d1d1452 100644
--- a/crypto/openssh/version.h
+++ b/crypto/openssh/version.h
@@ -1,12 +1,12 @@
-/* $OpenBSD: version.h,v 1.56 2009/06/30 14:54:40 markus Exp $ */
+/* $OpenBSD: version.h,v 1.57 2010/03/07 22:01:32 djm Exp $ */
/* $FreeBSD$ */
#ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get())
#define SSH_RELEASE (ssh_version_get())
-#define SSH_VERSION_BASE "OpenSSH_5.3p1"
-#define SSH_VERSION_ADDENDUM "FreeBSD-20091001"
+#define SSH_VERSION_BASE "OpenSSH_5.4p1"
+#define SSH_VERSION_ADDENDUM "FreeBSD-20100308"
const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *);
diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES
index 04d332e..b350da7 100644
--- a/crypto/openssl/CHANGES
+++ b/crypto/openssl/CHANGES
@@ -2,6 +2,191 @@
OpenSSL CHANGES
_______________
+ Changes between 0.9.8m and 0.9.8n [24 Mar 2010]
+
+ *) When rejecting SSL/TLS records due to an incorrect version number, never
+ update s->server with a new major version number. As of
+ - OpenSSL 0.9.8m if 'short' is a 16-bit type,
+ - OpenSSL 0.9.8f if 'short' is longer than 16 bits,
+ the previous behavior could result in a read attempt at NULL when
+ receiving specific incorrect SSL/TLS records once record payload
+ protection is active. (CVE-2010-0740)
+ [Bodo Moeller, Adam Langley <agl@chromium.org>]
+
+ *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL
+ could be crashed if the relevant tables were not present (e.g. chrooted).
+ [Tomas Hoger <thoger@redhat.com>]
+
+ Changes between 0.9.8l and 0.9.8m [25 Feb 2010]
+
+ *) Always check bn_wexpend() return values for failure. (CVE-2009-3245)
+ [Martin Olsson, Neel Mehta]
+
+ *) Fix X509_STORE locking: Every 'objs' access requires a lock (to
+ accommodate for stack sorting, always a write lock!).
+ [Bodo Moeller]
+
+ *) On some versions of WIN32 Heap32Next is very slow. This can cause
+ excessive delays in the RAND_poll(): over a minute. As a workaround
+ include a time check in the inner Heap32Next loop too.
+ [Steve Henson]
+
+ *) The code that handled flushing of data in SSL/TLS originally used the
+ BIO_CTRL_INFO ctrl to see if any data was pending first. This caused
+ the problem outlined in PR#1949. The fix suggested there however can
+ trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions
+ of Apache). So instead simplify the code to flush unconditionally.
+ This should be fine since flushing with no data to flush is a no op.
+ [Steve Henson]
+
+ *) Handle TLS versions 2.0 and later properly and correctly use the
+ highest version of TLS/SSL supported. Although TLS >= 2.0 is some way
+ off ancient servers have a habit of sticking around for a while...
+ [Steve Henson]
+
+ *) Modify compression code so it frees up structures without using the
+ ex_data callbacks. This works around a problem where some applications
+ call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when
+ restarting) then use compression (e.g. SSL with compression) later.
+ This results in significant per-connection memory leaks and
+ has caused some security issues including CVE-2008-1678 and
+ CVE-2009-4355.
+ [Steve Henson]
+
+ *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
+ change when encrypting or decrypting.
+ [Bodo Moeller]
+
+ *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
+ connect and renegotiate with servers which do not support RI.
+ Until RI is more widely deployed this option is enabled by default.
+ [Steve Henson]
+
+ *) Add "missing" ssl ctrls to clear options and mode.
+ [Steve Henson]
+
+ *) If client attempts to renegotiate and doesn't support RI respond with
+ a no_renegotiation alert as required by RFC5746. Some renegotiating
+ TLS clients will continue a connection gracefully when they receive
+ the alert. Unfortunately OpenSSL mishandled this alert and would hang
+ waiting for a server hello which it will never receive. Now we treat a
+ received no_renegotiation alert as a fatal error. This is because
+ applications requesting a renegotiation might well expect it to succeed
+ and would have no code in place to handle the server denying it so the
+ only safe thing to do is to terminate the connection.
+ [Steve Henson]
+
+ *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if
+ peer supports secure renegotiation and 0 otherwise. Print out peer
+ renegotiation support in s_client/s_server.
+ [Steve Henson]
+
+ *) Replace the highly broken and deprecated SPKAC certification method with
+ the updated NID creation version. This should correctly handle UTF8.
+ [Steve Henson]
+
+ *) Implement RFC5746. Re-enable renegotiation but require the extension
+ as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+ turns out to be a bad idea. It has been replaced by
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
+ SSL_CTX_set_options(). This is really not recommended unless you
+ know what you are doing.
+ [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
+
+ *) Fixes to stateless session resumption handling. Use initial_ctx when
+ issuing and attempting to decrypt tickets in case it has changed during
+ servername handling. Use a non-zero length session ID when attempting
+ stateless session resumption: this makes it possible to determine if
+ a resumption has occurred immediately after receiving server hello
+ (several places in OpenSSL subtly assume this) instead of later in
+ the handshake.
+ [Steve Henson]
+
+ *) The functions ENGINE_ctrl(), OPENSSL_isservice(),
+ CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error
+ fixes for a few places where the return code is not checked
+ correctly.
+ [Julia Lawall <julia@diku.dk>]
+
+ *) Add --strict-warnings option to Configure script to include devteam
+ warnings in other configurations.
+ [Steve Henson]
+
+ *) Add support for --libdir option and LIBDIR variable in makefiles. This
+ makes it possible to install openssl libraries in locations which
+ have names other than "lib", for example "/usr/lib64" which some
+ systems need.
+ [Steve Henson, based on patch from Jeremy Utley]
+
+ *) Don't allow the use of leading 0x80 in OIDs. This is a violation of
+ X690 8.9.12 and can produce some misleading textual output of OIDs.
+ [Steve Henson, reported by Dan Kaminsky]
+
+ *) Delete MD2 from algorithm tables. This follows the recommendation in
+ several standards that it is not used in new applications due to
+ several cryptographic weaknesses. For binary compatibility reasons
+ the MD2 API is still compiled in by default.
+ [Steve Henson]
+
+ *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved
+ and restored.
+ [Steve Henson]
+
+ *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and
+ OPENSSL_asc2uni conditionally on Netware platforms to avoid a name
+ clash.
+ [Guenter <lists@gknw.net>]
+
+ *) Fix the server certificate chain building code to use X509_verify_cert(),
+ it used to have an ad-hoc builder which was unable to cope with anything
+ other than a simple chain.
+ [David Woodhouse <dwmw2@infradead.org>, Steve Henson]
+
+ *) Don't check self signed certificate signatures in X509_verify_cert()
+ by default (a flag can override this): it just wastes time without
+ adding any security. As a useful side effect self signed root CAs
+ with non-FIPS digests are now usable in FIPS mode.
+ [Steve Henson]
+
+ *) In dtls1_process_out_of_seq_message() the check if the current message
+ is already buffered was missing. For every new message was memory
+ allocated, allowing an attacker to perform an denial of service attack
+ with sending out of seq handshake messages until there is no memory
+ left. Additionally every future messege was buffered, even if the
+ sequence number made no sense and would be part of another handshake.
+ So only messages with sequence numbers less than 10 in advance will be
+ buffered. (CVE-2009-1378)
+ [Robin Seggelmann, discovered by Daniel Mentz]
+
+ *) Records are buffered if they arrive with a future epoch to be
+ processed after finishing the corresponding handshake. There is
+ currently no limitation to this buffer allowing an attacker to perform
+ a DOS attack with sending records with future epochs until there is no
+ memory left. This patch adds the pqueue_size() function to detemine
+ the size of a buffer and limits the record buffer to 100 entries.
+ (CVE-2009-1377)
+ [Robin Seggelmann, discovered by Daniel Mentz]
+
+ *) Keep a copy of frag->msg_header.frag_len so it can be used after the
+ parent structure is freed. (CVE-2009-1379)
+ [Daniel Mentz]
+
+ *) Handle non-blocking I/O properly in SSL_shutdown() call.
+ [Darryl Miles <darryl-mailinglists@netbauds.net>]
+
+ *) Add 2.5.4.* OIDs
+ [Ilya O. <vrghost@gmail.com>]
+
+ Changes between 0.9.8k and 0.9.8l [5 Nov 2009]
+
+ *) Disable renegotiation completely - this fixes a severe security
+ problem (CVE-2009-3555) at the cost of breaking all
+ renegotiation. Renegotiation can be re-enabled by setting
+ SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at
+ run-time. This is really not recommended unless you know what
+ you're doing.
+ [Ben Laurie]
+
Changes between 0.9.8j and 0.9.8k [25 Mar 2009]
*) Don't set val to NULL when freeing up structures, it is freed up by
@@ -86,6 +271,10 @@
Changes between 0.9.8h and 0.9.8i [15 Sep 2008]
+ *) Fix NULL pointer dereference if a DTLS server received
+ ChangeCipherSpec as first record (CVE-2009-1386).
+ [PR #1679]
+
*) Fix a state transitition in s3_srvr.c and d1_srvr.c
(was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...).
[Nagendra Modadugu]
@@ -1489,19 +1678,6 @@
differing sizes.
[Richard Levitte]
- Changes between 0.9.7m and 0.9.7n [xx XXX xxxx]
-
- *) In the SSL/TLS server implementation, be strict about session ID
- context matching (which matters if an application uses a single
- external cache for different purposes). Previously,
- out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
- set. This did ensure strict client verification, but meant that,
- with applications using a single external cache for quite
- different requirements, clients could circumvent ciphersuite
- restrictions for a given session ID context by starting a session
- in a different context.
- [Bodo Moeller]
-
Changes between 0.9.7l and 0.9.7m [23 Feb 2007]
*) Cleanse PEM buffers before freeing them since they may contain
diff --git a/crypto/openssl/Configure b/crypto/openssl/Configure
index c6dbfae..32e154b 100755
--- a/crypto/openssl/Configure
+++ b/crypto/openssl/Configure
@@ -106,6 +106,8 @@ my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimenta
my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED";
+my $strict_warnings = 0;
+
my $x86_gcc_des="DES_PTR DES_RISC1 DES_UNROLL";
# MD2_CHAR slags pentium pros
@@ -159,14 +161,15 @@ my %table=(
"debug-ben", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown):::::bn86-elf.o co86-elf.o",
"debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
"debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
-"debug-ben-debug", "gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DDEBUG_SAFESTACK -g3 -O2 -pipe::(unknown)::::::",
+"debug-ben-debug", "gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DDEBUG_SAFESTACK -ggdb3 -O2 -pipe::(unknown)::::::",
+"debug-ben-debug-noopt", "gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DDEBUG_SAFESTACK -ggdb3 -pipe::(unknown)::::::",
"debug-ben-strict", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
"debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
"debug-bodo", "gcc:-DL_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBIO_PAIR_DEBUG -DPEDANTIC -g -march=i486 -pedantic -Wshadow -Wall -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
"debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll",
-"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-steve", "gcc:-DL_ENDIAN -DREF_CHECK -DCONF_DEBUG -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG_ALL -DPEDANTIC -m32 -g -pedantic -Wno-long-long -Wall -Werror -Wshadow -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared",
"debug-steve-linux-pseudo64", "gcc:-DL_ENDIAN -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG_ALL -DOPENSSL_NO_ASM -g -mcpu=i486 -Wall -Werror -Wshadow -pipe::-D_REENTRANT::-rdynamic -ldl:SIXTY_FOUR_BIT:${no_asm}:dlfcn:linux-shared",
"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -178,6 +181,9 @@ my %table=(
"debug-linux-ppro","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
"debug-linux-elf","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-lefence -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-linux-elf-noefence","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-generic32","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-generic64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-x86_64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -DTERMIO -g -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"dist", "cc:-O::(unknown)::::::",
# Basic configs that should work on any (32 and less bit) box
@@ -203,11 +209,11 @@ my %table=(
# actually recommend to consider using gcc shared build even with vendor
# compiler:-)
# <appro@fy.chalmers.se>
-"solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN -DMD32_REG_T=int::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN -DMD32_REG_T=int::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### Solaris x86 with Sun C setups
"solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"solaris64-x86_64-cc","cc:-fast -xarch=amd64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:solaris-shared:-KPIC:-xarch=amd64 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris64-x86_64-cc","cc:-fast -xarch=amd64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:solaris-shared:-KPIC:-xarch=amd64 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### SPARC Solaris with GNU C setups
"solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -337,7 +343,7 @@ my %table=(
"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### SPARC Linux setups
# Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
# assisted with debugging of following two configs.
@@ -390,7 +396,8 @@ my %table=(
# QNX
"qnx4", "cc:-DL_ENDIAN -DTERMIO::(unknown):::${x86_gcc_des} ${x86_gcc_opts}:",
-"qnx6", "cc:-DL_ENDIAN -DTERMIOS::(unknown)::-lsocket:${x86_gcc_des} ${x86_gcc_opts}:",
+"QNX6", "gcc:-DTERMIOS::::-lsocket::${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"QNX6-i386", "gcc:-DL_ENDIAN -DTERMIOS -O2 -Wall::::-lsocket:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### SCO/Caldera targets.
#
@@ -520,7 +527,7 @@ my %table=(
"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::osx_ppc64.o::::::::::dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
-"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -fomit-frame-pointer -DL_ENDIAN -DMD32_REG_T=int -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -fomit-frame-pointer -DL_ENDIAN -DMD32_REG_T=int -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::osx_ppc32.o::::::::::dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
##### A/UX
@@ -581,9 +588,11 @@ my $idx_ranlib = $idx++;
my $idx_arflags = $idx++;
my $prefix="";
+my $libdir="";
my $openssldir="";
my $exe_ext="";
-my $install_prefix="";
+my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
+my $cross_compile_prefix="";
my $fipslibdir="/usr/local/ssl/fips-1.0/lib/";
my $nofipscanistercheck=0;
my $fipsdso=0;
@@ -747,6 +756,10 @@ PROCESS_ARGS:
{
exit(&test_sanity());
}
+ elsif (/^--strict-warnings/)
+ {
+ $strict_warnings = 1;
+ }
elsif (/^reconfigure/ || /^reconf/)
{
if (open(IN,"<$Makefile"))
@@ -816,6 +829,10 @@ PROCESS_ARGS:
{
$prefix=$1;
}
+ elsif (/^--libdir=(.*)$/)
+ {
+ $libdir=$1;
+ }
elsif (/^--openssldir=(.*)$/)
{
$openssldir=$1;
@@ -979,7 +996,8 @@ my $shared_target = $fields[$idx_shared_target];
my $shared_cflag = $fields[$idx_shared_cflag];
my $shared_ldflag = $fields[$idx_shared_ldflag];
my $shared_extension = $fields[$idx_shared_extension];
-my $ranlib = $fields[$idx_ranlib];
+my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib];
+my $ar = $ENV{'AR'} || "ar";
my $arflags = $fields[$idx_arflags];
if ($fips)
@@ -1079,9 +1097,14 @@ if ($openssldir eq "" and $prefix eq "")
}
$prefix=$openssldir if $prefix eq "";
+$libdir="lib" if $libdir eq "";
+
$default_ranlib= &which("ranlib") or $default_ranlib="true";
$perl=$ENV{'PERL'} or $perl=&which("perl5") or $perl=&which("perl")
or $perl="perl";
+my $make = $ENV{'MAKE'} || "make";
+
+$cross_compile_prefix=$ENV{'CROSS_COMPILE'} if $cross_compile_prefix eq "";
chop $openssldir if $openssldir =~ /\/$/;
chop $prefix if $prefix =~ /.\/$/;
@@ -1434,6 +1457,16 @@ if ($shlib_version_number =~ /(^[0-9]*)\.([0-9\.]*)/)
$shlib_minor=$2;
}
+if ($strict_warnings)
+ {
+ my $wopt;
+ die "ERROR --strict-warnings requires gcc" unless ($cc =~ /gcc$/);
+ foreach $wopt (split /\s+/, $gcc_devteam_warn)
+ {
+ $cflags .= " $wopt" unless ($cflags =~ /$wopt/)
+ }
+ }
+
open(IN,'<Makefile.org') || die "unable to read Makefile.org:$!\n";
unlink("$Makefile.new") || die "unable to remove old $Makefile.new:$!\n" if -e "$Makefile.new";
open(OUT,">$Makefile.new") || die "unable to create $Makefile.new:$!\n";
@@ -1463,11 +1496,22 @@ while (<IN>)
s/^SHLIB_EXT=.*/SHLIB_EXT=$shared_extension/;
s/^INSTALLTOP=.*$/INSTALLTOP=$prefix/;
s/^OPENSSLDIR=.*$/OPENSSLDIR=$openssldir/;
+ s/^LIBDIR=.*$/LIBDIR=$libdir/;
s/^INSTALL_PREFIX=.*$/INSTALL_PREFIX=$install_prefix/;
s/^PLATFORM=.*$/PLATFORM=$target/;
s/^OPTIONS=.*$/OPTIONS=$options/;
s/^CONFIGURE_ARGS=.*$/CONFIGURE_ARGS=$argvstring/;
- s/^CC=.*$/CC= $cc/;
+ if ($cross_compile_prefix)
+ {
+ s/^CC=.*$/CROSS_COMPILE= $cross_compile_prefix\nCC= \$\(CROSS_COMPILE\)$cc/;
+ s/^AR=\s*/AR= \$\(CROSS_COMPILE\)/;
+ s/^RANLIB=\s*/RANLIB= \$\(CROSS_COMPILE\)/;
+ }
+ else {
+ s/^CC=.*$/CC= $cc/;
+ s/^AR=\s*ar/AR= $ar/;
+ s/^RANLIB=.*/RANLIB= $ranlib/;
+ }
s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc";
s/^CFLAG=.*$/CFLAG= $cflags/;
s/^DEPFLAG=.*$/DEPFLAG=$depflags/;
@@ -1486,7 +1530,6 @@ while (<IN>)
s/^SHA1_ASM_OBJ=.*$/SHA1_ASM_OBJ= $sha1_obj/;
s/^RMD160_ASM_OBJ=.*$/RMD160_ASM_OBJ= $rmd160_obj/;
s/^PROCESSOR=.*/PROCESSOR= $processor/;
- s/^RANLIB=.*/RANLIB= $ranlib/;
s/^ARFLAGS=.*/ARFLAGS= $arflags/;
s/^PERL=.*/PERL= $perl/;
s/^KRB5_INCLUDES=.*/KRB5_INCLUDES=$withargs{"krb5-include"}/;
@@ -1643,9 +1686,20 @@ print OUT "#define OPENSSL_CPUID_OBJ\n\n" if ($cpuid_obj);
while (<IN>)
{
if (/^#define\s+OPENSSLDIR/)
- { print OUT "#define OPENSSLDIR \"$openssldir\"\n"; }
+ {
+ my $foo = $openssldir;
+ $foo =~ s/\\/\\\\/g;
+ print OUT "#define OPENSSLDIR \"$foo\"\n";
+ }
elsif (/^#define\s+ENGINESDIR/)
- { print OUT "#define ENGINESDIR \"$prefix/lib/engines\"\n"; }
+ {
+ # $foo is to become "$prefix/lib$multilib/engines";
+ # as Makefile.org and engines/Makefile are adapted for
+ # $multilib suffix.
+ my $foo = "$prefix/lib/engines";
+ $foo =~ s/\\/\\\\/g;
+ print OUT "#define ENGINESDIR \"$foo\"\n";
+ }
elsif (/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/)
{ printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n"
if $export_var_as_fn;
@@ -1750,7 +1804,7 @@ if($IsMK1MF) {
EOF
close(OUT);
} else {
- my $make_command = "make PERL=\'$perl\'";
+ my $make_command = "$make PERL=\'$perl\'";
my $make_targets = "";
$make_targets .= " links" if $symlink;
$make_targets .= " depend" if $depflags ne $default_depflags && $make_depend;
diff --git a/crypto/openssl/FAQ b/crypto/openssl/FAQ
index 942a671..f7aaede 100644
--- a/crypto/openssl/FAQ
+++ b/crypto/openssl/FAQ
@@ -78,7 +78,7 @@ OpenSSL - Frequently Asked Questions
* Which is the current version of OpenSSL?
The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 0.9.8k was released on Mar 25th, 2009.
+OpenSSL 0.9.8n was released on Mar 24th, 2010.
In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL:
diff --git a/crypto/openssl/Makefile b/crypto/openssl/Makefile
index 57d742e..7f48abd 100644
--- a/crypto/openssl/Makefile
+++ b/crypto/openssl/Makefile
@@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
-VERSION=0.9.8k
+VERSION=0.9.8n
MAJOR=0
MINOR=9.8
SHLIB_VERSION_NUMBER=0.9.8
@@ -66,13 +66,14 @@ PEX_LIBS=
EX_LIBS=
EXE_EXT=
ARFLAGS=
-AR=ar $(ARFLAGS) r
+AR= ar $(ARFLAGS) r
ARD=ar $(ARFLAGS) d
RANLIB= /usr/bin/ranlib
PERL= /usr/bin/perl
TAR= tar
TARFLAGS= --no-recursion
MAKEDEPPROG=makedepend
+LIBDIR=lib
# We let the C compiler driver to take care of .s files. This is done in
# order to be excused from maintaining a separate set of architecture
@@ -202,9 +203,10 @@ BUILDENV= PLATFORM='${PLATFORM}' PROCESSOR='${PROCESSOR}' \
CC='${CC}' CFLAG='${CFLAG}' \
AS='${CC}' ASFLAG='${CFLAG} -c' \
AR='${AR}' PERL='${PERL}' RANLIB='${RANLIB}' \
- SDIRS='${SDIRS}' LIBRPATH='${INSTALLTOP}/lib' \
+ SDIRS='${SDIRS}' LIBRPATH='${INSTALLTOP}/$(LIBDIR)' \
INSTALL_PREFIX='${INSTALL_PREFIX}' \
INSTALLTOP='${INSTALLTOP}' OPENSSLDIR='${OPENSSLDIR}' \
+ LIBDIR='${LIBDIR}' \
MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD ${MAKEDEPPROG}' \
DEPFLAG='-DOPENSSL_NO_DEPRECATED ${DEPFLAG}' \
MAKEDEPPROG='${MAKEDEPPROG}' \
@@ -335,15 +337,15 @@ build_crypto:
dir=crypto; target=all; $(BUILD_ONE_CMD)
build_fips:
@dir=fips; target=all; [ -z "$(FIPSCANLIB)" ] || $(BUILD_ONE_CMD)
-build_ssl:
+build_ssl: build_crypto
@dir=ssl; target=all; $(BUILD_ONE_CMD)
-build_engines:
+build_engines: build_crypto
@dir=engines; target=all; $(BUILD_ONE_CMD)
-build_apps:
+build_apps: build_libs
@dir=apps; target=all; $(BUILD_ONE_CMD)
-build_tests:
+build_tests: build_libs
@dir=test; target=all; $(BUILD_ONE_CMD)
-build_tools:
+build_tools: build_libs
@dir=tools; target=all; $(BUILD_ONE_CMD)
all_testapps: build_libs build_testapps
@@ -359,7 +361,7 @@ libcrypto$(SHLIB_EXT): libcrypto.a $(SHARED_FIPS)
$(AR) libcrypto.a fips/fipscanister.o ; \
else \
if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
- FIPSLD_CC=$(CC); CC=fips/fipsld; \
+ FIPSLD_CC="$(CC)"; CC=fips/fipsld; \
export CC FIPSLD_CC; \
fi; \
$(MAKE) -e SHLIBDIRS='crypto' build-shared; \
@@ -382,7 +384,7 @@ libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
fips/fipscanister.o: build_fips
libfips$(SHLIB_EXT): fips/fipscanister.o
@if [ "$(SHLIB_TARGET)" != "" ]; then \
- FIPSLD_CC=$(CC); CC=fips/fipsld; export CC FIPSLD_CC; \
+ FIPSLD_CC="$(CC)"; CC=fips/fipsld; export CC FIPSLD_CC; \
$(MAKE) -f Makefile.shared -e $(BUILDENV) \
CC=$${CC} LIBNAME=fips THIS=$@ \
LIBEXTRAS=fips/fipscanister.o \
@@ -438,7 +440,7 @@ do_$(SHLIB_TARGET):
libcrypto.pc: Makefile
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
- echo 'libdir=$${exec_prefix}/lib'; \
+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL-libcrypto'; \
@@ -451,7 +453,7 @@ libcrypto.pc: Makefile
libssl.pc: Makefile
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
- echo 'libdir=$${exec_prefix}/lib'; \
+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL'; \
@@ -464,7 +466,7 @@ libssl.pc: Makefile
openssl.pc: Makefile
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
- echo 'libdir=$${exec_prefix}/lib'; \
+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL'; \
@@ -519,12 +521,14 @@ dclean:
@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
rehash: rehash.time
-rehash.time: certs
- @(OPENSSL="`pwd`/util/opensslwrap.sh"; \
- OPENSSL_DEBUG_MEMORY=on; \
- export OPENSSL OPENSSL_DEBUG_MEMORY; \
- $(PERL) tools/c_rehash certs)
- touch rehash.time
+rehash.time: certs apps
+ @if [ -z "$(CROSS_COMPILE)" ]; then \
+ (OPENSSL="`pwd`/util/opensslwrap.sh"; \
+ OPENSSL_DEBUG_MEMORY=on; \
+ export OPENSSL OPENSSL_DEBUG_MEMORY; \
+ $(PERL) tools/c_rehash certs) && \
+ touch rehash.time; \
+ fi
test: tests
@@ -617,9 +621,9 @@ install: all install_docs install_sw
install_sw:
@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
@@ -634,10 +638,10 @@ install_sw:
do \
if [ -f "$$i" ]; then \
( echo installing $$i; \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- $(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i ); \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ $(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
fi; \
done;
@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
@@ -647,22 +651,22 @@ install_sw:
if [ -f "$$i" -o -f "$$i.a" ]; then \
( echo installing $$i; \
if [ "$(PLATFORM)" != "Cygwin" ]; then \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i; \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
else \
c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i; \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
fi ); \
fi; \
done; \
( here="`pwd`"; \
- cd $(INSTALL_PREFIX)$(INSTALLTOP)/lib; \
+ cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
if [ "$(INSTALLTOP)" != "/usr" ]; then \
echo 'OpenSSL shared libraries have been installed in:'; \
@@ -671,12 +675,12 @@ install_sw:
sed -e '1,/^$$/d' doc/openssl-shared.txt; \
fi; \
fi
- cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig/libcrypto.pc
- cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig/libssl.pc
- cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig/openssl.pc
+ cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
+ cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
+ cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
install_docs:
@$(PERL) $(TOP)/util/mkdir-p.pl \
@@ -684,7 +688,7 @@ install_docs:
$(INSTALL_PREFIX)$(MANDIR)/man3 \
$(INSTALL_PREFIX)$(MANDIR)/man5 \
$(INSTALL_PREFIX)$(MANDIR)/man7
- @pod2man="`cd util; ./pod2mantest $(PERL)`"; \
+ @pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
here="`pwd`"; \
filecase=; \
if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
diff --git a/crypto/openssl/Makefile.org b/crypto/openssl/Makefile.org
index d1b56b2..e87d623 100644
--- a/crypto/openssl/Makefile.org
+++ b/crypto/openssl/Makefile.org
@@ -71,6 +71,7 @@ PERL= perl
TAR= tar
TARFLAGS= --no-recursion
MAKEDEPPROG=makedepend
+LIBDIR=lib
# We let the C compiler driver to take care of .s files. This is done in
# order to be excused from maintaining a separate set of architecture
@@ -112,7 +113,7 @@ LIBZLIB=
# $(INSTALLTOP) for this build make be different so hard
# code the path.
-FIPSLIBDIR=/usr/local/ssl/lib/
+FIPSLIBDIR=/usr/local/ssl/$(LIBDIR)/
# This is set to "y" if fipscanister.o is compiled internally as
# opposed to coming from an external validated location.
@@ -200,9 +201,10 @@ BUILDENV= PLATFORM='${PLATFORM}' PROCESSOR='${PROCESSOR}' \
CC='${CC}' CFLAG='${CFLAG}' \
AS='${CC}' ASFLAG='${CFLAG} -c' \
AR='${AR}' PERL='${PERL}' RANLIB='${RANLIB}' \
- SDIRS='${SDIRS}' LIBRPATH='${INSTALLTOP}/lib' \
+ SDIRS='${SDIRS}' LIBRPATH='${INSTALLTOP}/$(LIBDIR)' \
INSTALL_PREFIX='${INSTALL_PREFIX}' \
INSTALLTOP='${INSTALLTOP}' OPENSSLDIR='${OPENSSLDIR}' \
+ LIBDIR='${LIBDIR}' \
MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD ${MAKEDEPPROG}' \
DEPFLAG='-DOPENSSL_NO_DEPRECATED ${DEPFLAG}' \
MAKEDEPPROG='${MAKEDEPPROG}' \
@@ -333,15 +335,15 @@ build_crypto:
dir=crypto; target=all; $(BUILD_ONE_CMD)
build_fips:
@dir=fips; target=all; [ -z "$(FIPSCANLIB)" ] || $(BUILD_ONE_CMD)
-build_ssl:
+build_ssl: build_crypto
@dir=ssl; target=all; $(BUILD_ONE_CMD)
-build_engines:
+build_engines: build_crypto
@dir=engines; target=all; $(BUILD_ONE_CMD)
-build_apps:
+build_apps: build_libs
@dir=apps; target=all; $(BUILD_ONE_CMD)
-build_tests:
+build_tests: build_libs
@dir=test; target=all; $(BUILD_ONE_CMD)
-build_tools:
+build_tools: build_libs
@dir=tools; target=all; $(BUILD_ONE_CMD)
all_testapps: build_libs build_testapps
@@ -357,7 +359,7 @@ libcrypto$(SHLIB_EXT): libcrypto.a $(SHARED_FIPS)
$(AR) libcrypto.a fips/fipscanister.o ; \
else \
if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
- FIPSLD_CC=$(CC); CC=fips/fipsld; \
+ FIPSLD_CC="$(CC)"; CC=fips/fipsld; \
export CC FIPSLD_CC; \
fi; \
$(MAKE) -e SHLIBDIRS='crypto' build-shared; \
@@ -380,7 +382,7 @@ libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
fips/fipscanister.o: build_fips
libfips$(SHLIB_EXT): fips/fipscanister.o
@if [ "$(SHLIB_TARGET)" != "" ]; then \
- FIPSLD_CC=$(CC); CC=fips/fipsld; export CC FIPSLD_CC; \
+ FIPSLD_CC="$(CC)"; CC=fips/fipsld; export CC FIPSLD_CC; \
$(MAKE) -f Makefile.shared -e $(BUILDENV) \
CC=$${CC} LIBNAME=fips THIS=$@ \
LIBEXTRAS=fips/fipscanister.o \
@@ -436,7 +438,7 @@ do_$(SHLIB_TARGET):
libcrypto.pc: Makefile
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
- echo 'libdir=$${exec_prefix}/lib'; \
+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL-libcrypto'; \
@@ -449,7 +451,7 @@ libcrypto.pc: Makefile
libssl.pc: Makefile
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
- echo 'libdir=$${exec_prefix}/lib'; \
+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL'; \
@@ -462,7 +464,7 @@ libssl.pc: Makefile
openssl.pc: Makefile
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
- echo 'libdir=$${exec_prefix}/lib'; \
+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL'; \
@@ -517,12 +519,14 @@ dclean:
@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
rehash: rehash.time
-rehash.time: certs
- @(OPENSSL="`pwd`/util/opensslwrap.sh"; \
- OPENSSL_DEBUG_MEMORY=on; \
- export OPENSSL OPENSSL_DEBUG_MEMORY; \
- $(PERL) tools/c_rehash certs)
- touch rehash.time
+rehash.time: certs apps
+ @if [ -z "$(CROSS_COMPILE)" ]; then \
+ (OPENSSL="`pwd`/util/opensslwrap.sh"; \
+ OPENSSL_DEBUG_MEMORY=on; \
+ export OPENSSL OPENSSL_DEBUG_MEMORY; \
+ $(PERL) tools/c_rehash certs) && \
+ touch rehash.time; \
+ fi
test: tests
@@ -615,9 +619,9 @@ install: all install_docs install_sw
install_sw:
@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
@@ -632,10 +636,10 @@ install_sw:
do \
if [ -f "$$i" ]; then \
( echo installing $$i; \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- $(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i ); \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ $(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
fi; \
done;
@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
@@ -645,22 +649,22 @@ install_sw:
if [ -f "$$i" -o -f "$$i.a" ]; then \
( echo installing $$i; \
if [ "$(PLATFORM)" != "Cygwin" ]; then \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i; \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
else \
c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i; \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
fi ); \
fi; \
done; \
( here="`pwd`"; \
- cd $(INSTALL_PREFIX)$(INSTALLTOP)/lib; \
+ cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
if [ "$(INSTALLTOP)" != "/usr" ]; then \
echo 'OpenSSL shared libraries have been installed in:'; \
@@ -669,12 +673,12 @@ install_sw:
sed -e '1,/^$$/d' doc/openssl-shared.txt; \
fi; \
fi
- cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig/libcrypto.pc
- cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig/libssl.pc
- cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig/openssl.pc
+ cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
+ cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
+ cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
install_docs:
@$(PERL) $(TOP)/util/mkdir-p.pl \
@@ -682,7 +686,7 @@ install_docs:
$(INSTALL_PREFIX)$(MANDIR)/man3 \
$(INSTALL_PREFIX)$(MANDIR)/man5 \
$(INSTALL_PREFIX)$(MANDIR)/man7
- @pod2man="`cd util; ./pod2mantest $(PERL)`"; \
+ @pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
here="`pwd`"; \
filecase=; \
if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS
index 37156fc..a00d06a 100644
--- a/crypto/openssl/NEWS
+++ b/crypto/openssl/NEWS
@@ -5,6 +5,27 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
+ Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n:
+
+ o CFB cipher definition fixes.
+ o Fix security issues CVE-2010-0740 and CVE-2010-0433.
+
+ Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m:
+
+ o Cipher definition fixes.
+ o Workaround for slow RAND_poll() on some WIN32 versions.
+ o Remove MD2 from algorithm tables.
+ o SPKAC handling fixes.
+ o Support for RFC5746 TLS renegotiation extension.
+ o Compression memory leak fixed.
+ o Compression session resumption fixed.
+ o Ticket and SNI coexistence fixes.
+ o Many fixes to DTLS handling.
+
+ Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l:
+
+ o Temporary work around for CVE-2009-3555: disable renegotiation.
+
Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k:
o Fix various build issues.
diff --git a/crypto/openssl/README b/crypto/openssl/README
index 99a6a7b..2a96ba3 100644
--- a/crypto/openssl/README
+++ b/crypto/openssl/README
@@ -1,7 +1,7 @@
- OpenSSL 0.9.8k
+ OpenSSL 0.9.8n
- Copyright (c) 1998-2008 The OpenSSL Project
+ Copyright (c) 1998-2009 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
All rights reserved.
@@ -112,8 +112,6 @@
should be contacted if that algorithm is to be used; their web page is
http://www.ascom.ch/.
- The MDC2 algorithm is patented by IBM.
-
NTT and Mitsubishi have patents and pending patents on the Camellia
algorithm, but allow use at no charge without requiring an explicit
licensing agreement: http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
@@ -139,6 +137,9 @@
SUPPORT
-------
+ See the OpenSSL website www.openssl.org for details of how to obtain
+ commercial technical support.
+
If you have any problems with OpenSSL then please take the following steps
first:
@@ -165,6 +166,10 @@
openssl-bugs@openssl.org
+ Note that the request tracker should NOT be used for general assistance
+ or support queries. Just because something doesn't work the way you expect
+ does not mean it is necessarily a bug in OpenSSL.
+
Note that mail to openssl-bugs@openssl.org is recorded in the publicly
readable request tracker database and is forwarded to a public
mailing list. Confidential mail may be sent to openssl-security@openssl.org
@@ -175,10 +180,22 @@
Development is coordinated on the openssl-dev mailing list (see
http://www.openssl.org for information on subscribing). If you
- would like to submit a patch, send it to openssl-dev@openssl.org with
+ would like to submit a patch, send it to openssl-bugs@openssl.org with
the string "[PATCH]" in the subject. Please be sure to include a
textual explanation of what your patch does.
+ If you are unsure as to whether a feature will be useful for the general
+ OpenSSL community please discuss it on the openssl-dev mailing list first.
+ Someone may be already working on the same thing or there may be a good
+ reason as to why that feature isn't implemented.
+
+ Patches should be as up to date as possible, preferably relative to the
+ current CVS or the last snapshot. They should follow the coding style of
+ OpenSSL and compile without warnings. Some of the core team developer targets
+ can be used for testing purposes, (debug-steve64, debug-geoff etc). OpenSSL
+ compiles on many varied platforms: try to ensure you only use portable
+ features.
+
Note: For legal reasons, contributions from the US can be accepted only
if a TSU notification and a copy of the patch are sent to crypt@bis.doc.gov
(formerly BXA) with a copy to the ENC Encryption Request Coordinator;
diff --git a/crypto/openssl/apps/CA.sh b/crypto/openssl/apps/CA.sh
index a0b20d8..7ad6b8c 100644
--- a/crypto/openssl/apps/CA.sh
+++ b/crypto/openssl/apps/CA.sh
@@ -5,10 +5,10 @@
# things easier between now and when Eric is convinced to fix it :-)
#
# CA -newca ... will setup the right stuff
-# CA -newreq ... will generate a certificate request
-# CA -sign ... will sign the generated request and output
+# CA -newreq ... will generate a certificate request
+# CA -sign ... will sign the generated request and output
#
-# At the end of that grab newreq.pem and newcert.pem (one has the key
+# At the end of that grab newreq.pem and newcert.pem (one has the key
# and the other the certificate) and cat them together and that is what
# you want/need ... I'll make even this a little cleaner later.
#
@@ -16,8 +16,8 @@
# 12-Jan-96 tjh Added more things ... including CA -signcert which
# converts a certificate to a request and then signs it.
# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG
-# environment variable so this can be driven from
-# a script.
+# environment variable so this can be driven from
+# a script.
# 25-Jul-96 eay Cleaned up filenames some more.
# 11-Jun-96 eay Fixed a few filename missmatches.
# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'.
@@ -29,52 +29,87 @@
# default openssl.cnf file has setup as per the following
# demoCA ... where everything is stored
+cp_pem() {
+ infile=$1
+ outfile=$2
+ bound=$3
+ flag=0
+ exec <$infile;
+ while read line; do
+ if [ $flag -eq 1 ]; then
+ echo $line|grep "^-----END.*$bound" 2>/dev/null 1>/dev/null
+ if [ $? -eq 0 ] ; then
+ echo $line >>$outfile
+ break
+ else
+ echo $line >>$outfile
+ fi
+ fi
+
+ echo $line|grep "^-----BEGIN.*$bound" 2>/dev/null 1>/dev/null
+ if [ $? -eq 0 ]; then
+ echo $line >$outfile
+ flag=1
+ fi
+ done
+}
+
+usage() {
+ echo "usage: $0 -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify" >&2
+}
if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi
-DAYS="-days 365" # 1 year
+if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi # 1 year
CADAYS="-days 1095" # 3 years
REQ="$OPENSSL req $SSLEAY_CONFIG"
CA="$OPENSSL ca $SSLEAY_CONFIG"
VERIFY="$OPENSSL verify"
X509="$OPENSSL x509"
+PKCS12="openssl pkcs12"
-CATOP=./demoCA
+if [ -z "$CATOP" ] ; then CATOP=./demoCA ; fi
CAKEY=./cakey.pem
CAREQ=./careq.pem
CACERT=./cacert.pem
-for i
-do
-case $i in
+RET=0
+
+while [ "$1" != "" ] ; do
+case $1 in
-\?|-h|-help)
- echo "usage: CA -newcert|-newreq|-newca|-sign|-verify" >&2
+ usage
exit 0
;;
--newcert)
+-newcert)
# create a certificate
$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS
RET=$?
echo "Certificate is in newcert.pem, private key is in newkey.pem"
;;
--newreq)
+-newreq)
# create a certificate request
$REQ -new -keyout newkey.pem -out newreq.pem $DAYS
RET=$?
echo "Request is in newreq.pem, private key is in newkey.pem"
;;
--newca)
+-newreq-nodes)
+ # create a certificate request
+ $REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
+ RET=$?
+ echo "Request (and private key) is in newreq.pem"
+ ;;
+-newca)
# if explicitly asked for or it doesn't exist then setup the directory
- # structure that Eric likes to manage things
+ # structure that Eric likes to manage things
NEW="1"
if [ "$NEW" -o ! -f ${CATOP}/serial ]; then
# create the directory hierarchy
- mkdir ${CATOP}
- mkdir ${CATOP}/certs
- mkdir ${CATOP}/crl
- mkdir ${CATOP}/newcerts
- mkdir ${CATOP}/private
- echo "00" > ${CATOP}/serial
+ mkdir -p ${CATOP}
+ mkdir -p ${CATOP}/certs
+ mkdir -p ${CATOP}/crl
+ mkdir -p ${CATOP}/newcerts
+ mkdir -p ${CATOP}/private
touch ${CATOP}/index.txt
fi
if [ ! -f ${CATOP}/private/$CAKEY ]; then
@@ -83,37 +118,60 @@ case $i in
# ask user for existing CA certificate
if [ "$FILE" ]; then
- cp $FILE ${CATOP}/private/$CAKEY
+ cp_pem $FILE ${CATOP}/private/$CAKEY PRIVATE
+ cp_pem $FILE ${CATOP}/$CACERT CERTIFICATE
RET=$?
+ if [ ! -f "${CATOP}/serial" ]; then
+ $X509 -in ${CATOP}/$CACERT -noout -next_serial \
+ -out ${CATOP}/serial
+ fi
else
echo "Making CA certificate ..."
$REQ -new -keyout ${CATOP}/private/$CAKEY \
-out ${CATOP}/$CAREQ
- $CA -out ${CATOP}/$CACERT $CADAYS -batch \
+ $CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \
-keyfile ${CATOP}/private/$CAKEY -selfsign \
- -infiles ${CATOP}/$CAREQ
+ -extensions v3_ca \
+ -infiles ${CATOP}/$CAREQ
RET=$?
fi
fi
;;
-xsign)
- $CA -policy policy_anything -infiles newreq.pem
+ $CA -policy policy_anything -infiles newreq.pem
RET=$?
;;
--sign|-signreq)
+-pkcs12)
+ if [ -z "$2" ] ; then
+ CNAME="My Certificate"
+ else
+ CNAME="$2"
+ fi
+ $PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \
+ -out newcert.p12 -export -name "$CNAME"
+ RET=$?
+ exit $RET
+ ;;
+-sign|-signreq)
$CA -policy policy_anything -out newcert.pem -infiles newreq.pem
RET=$?
cat newcert.pem
echo "Signed certificate is in newcert.pem"
;;
--signcert)
+-signCA)
+ $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
+ RET=$?
+ echo "Signed CA certificate is in newcert.pem"
+ ;;
+-signcert)
echo "Cert passphrase will be requested twice - bug?"
$X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
$CA -policy policy_anything -out newcert.pem -infiles tmp.pem
+ RET=$?
cat newcert.pem
echo "Signed certificate is in newcert.pem"
;;
--verify)
+-verify)
shift
if [ -z "$1" ]; then
$VERIFY -CAfile $CATOP/$CACERT newcert.pem
@@ -127,13 +185,14 @@ case $i in
fi
done
fi
- exit 0
+ exit $RET
;;
*)
- echo "Unknown arg $i";
+ echo "Unknown arg $i" >&2
+ usage
exit 1
;;
esac
+shift
done
exit $RET
-
diff --git a/crypto/openssl/apps/Makefile b/crypto/openssl/apps/Makefile
index 402981a..a548815 100644
--- a/crypto/openssl/apps/Makefile
+++ b/crypto/openssl/apps/Makefile
@@ -153,17 +153,19 @@ $(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
shlib_target="$(SHLIB_TARGET)"; \
elif [ -n "$(FIPSCANLIB)" ]; then \
- FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
+ FIPSLD_CC="$(CC)"; CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
fi; \
LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \
[ "x$(FIPSCANLIB)" = "xlibfips" ] && LIBRARIES="$$LIBRARIES -lfips"; \
$(MAKE) -f $(TOP)/Makefile.shared -e \
- CC=$${CC} APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
+ CC="$${CC}" APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
link_app.$${shlib_target}
- -(cd ..; \
- OPENSSL="`pwd`/util/opensslwrap.sh"; export OPENSSL; \
- $(PERL) tools/c_rehash certs)
+ @if [ -z "$(CROSS_COMPILE)" ]; then \
+ (cd ..; \
+ OPENSSL="`pwd`/util/opensslwrap.sh"; export OPENSSL; \
+ $(PERL) tools/c_rehash certs) \
+ fi
progs.h: progs.pl
$(PERL) progs.pl $(E_EXE) >progs.h
@@ -750,13 +752,14 @@ s_cb.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
s_cb.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s_cb.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s_cb.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s_cb.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s_cb.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s_cb.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s_cb.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s_cb.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-s_cb.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-s_cb.o: ../include/openssl/x509v3.h apps.h s_apps.h s_cb.c
+s_cb.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+s_cb.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s_cb.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s_cb.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s_cb.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s_cb.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_cb.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_cb.o: s_apps.h s_cb.c
s_client.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s_client.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s_client.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -805,28 +808,28 @@ s_server.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
s_server.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
s_server.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
s_server.o: ../include/openssl/x509v3.h apps.h s_apps.h s_server.c timeouts.h
-s_socket.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s_socket.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s_socket.o: ../include/openssl/comp.h ../include/openssl/conf.h
-s_socket.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-s_socket.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s_socket.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s_socket.o: ../include/openssl/engine.h ../include/openssl/evp.h
-s_socket.o: ../include/openssl/fips.h ../include/openssl/hmac.h
-s_socket.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s_socket.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-s_socket.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-s_socket.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s_socket.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s_socket.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-s_socket.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-s_socket.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s_socket.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s_socket.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s_socket.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s_socket.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-s_socket.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-s_socket.o: s_apps.h s_socket.c
+s_socket.o: ../e_os.h ../e_os2.h ../include/openssl/asn1.h
+s_socket.o: ../include/openssl/bio.h ../include/openssl/bn.h
+s_socket.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s_socket.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+s_socket.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s_socket.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s_socket.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s_socket.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s_socket.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_socket.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_socket.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_socket.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_socket.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_socket.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_socket.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+s_socket.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s_socket.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_socket.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_socket.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_socket.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_socket.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+s_socket.o: ../include/openssl/x509v3.h apps.h s_apps.h s_socket.c
s_time.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s_time.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s_time.o: ../include/openssl/comp.h ../include/openssl/conf.h
diff --git a/crypto/openssl/apps/apps.c b/crypto/openssl/apps/apps.c
index 498722a..35b62b8 100644
--- a/crypto/openssl/apps/apps.c
+++ b/crypto/openssl/apps/apps.c
@@ -2261,6 +2261,8 @@ int args_verify(char ***pargs, int *pargc,
flags |= X509_V_FLAG_X509_STRICT;
else if (!strcmp(arg, "-policy_print"))
flags |= X509_V_FLAG_NOTIFY_POLICY;
+ else if (!strcmp(arg, "-check_ss_sig"))
+ flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
else
return 0;
diff --git a/crypto/openssl/apps/ca.c b/crypto/openssl/apps/ca.c
index 68516ee..651c5a6 100644
--- a/crypto/openssl/apps/ca.c
+++ b/crypto/openssl/apps/ca.c
@@ -216,7 +216,6 @@ static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
char *startdate, char *enddate, long days, char *ext_sect,
CONF *conf, int verbose, unsigned long certopt,
unsigned long nameopt, int default_op, int ext_copy);
-static int fix_data(int nid, int *type);
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
@@ -227,7 +226,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
static int get_certificate_status(const char *ser_status, CA_DB *db);
static int do_updatedb(CA_DB *db);
-static int check_time_format(char *str);
+static int check_time_format(const char *str);
char *make_revocation_str(int rev_type, char *rev_arg);
int make_revoked(X509_REVOKED *rev, const char *str);
int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
@@ -858,8 +857,8 @@ bad:
perror(outdir);
goto err;
}
-#ifdef S_IFDIR
- if (!(sb.st_mode & S_IFDIR))
+#ifdef S_ISDIR
+ if (!S_ISDIR(sb.st_mode))
{
BIO_printf(bio_err,"%s need to be a directory\n",outdir);
perror(outdir);
@@ -895,7 +894,7 @@ bad:
BIO_printf(bio_err," in entry %d\n", i+1);
goto err;
}
- if (!check_time_format((char *)pp[DB_exp_date]))
+ if (!check_time_format(pp[DB_exp_date]))
{
BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
goto err;
@@ -1249,7 +1248,12 @@ bad:
BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
(void)BIO_flush(bio_err);
buf[0][0]='\0';
- fgets(buf[0],10,stdin);
+ if (!fgets(buf[0],10,stdin))
+ {
+ BIO_printf(bio_err,"CERTIFICATION CANCELED: I/O error\n");
+ ret=0;
+ goto err;
+ }
if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
{
BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
@@ -2091,7 +2095,7 @@ again2:
}
BIO_printf(bio_err,"Certificate is to be certified until ");
- ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
+ ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
if (days) BIO_printf(bio_err," (%ld days)",days);
BIO_printf(bio_err, "\n");
@@ -2101,7 +2105,12 @@ again2:
BIO_printf(bio_err,"Sign the certificate? [y/n]:");
(void)BIO_flush(bio_err);
buf[0]='\0';
- fgets(buf,sizeof(buf)-1,stdin);
+ if (!fgets(buf,sizeof(buf)-1,stdin))
+ {
+ BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
+ ok=0;
+ goto err;
+ }
if (!((buf[0] == 'y') || (buf[0] == 'Y')))
{
BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
@@ -2317,25 +2326,9 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
continue;
}
- /*
- if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
- continue;
- */
-
- j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
- if (fix_data(nid, &j) == 0)
- {
- BIO_printf(bio_err,
- "invalid characters in string %s\n",buf);
- goto err;
- }
-
- if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
- (unsigned char *)buf,
- strlen(buf))) == NULL)
+ if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+ (unsigned char *)buf, -1, -1, 0))
goto err;
-
- if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
}
if (spki == NULL)
{
@@ -2378,29 +2371,17 @@ err:
return(ok);
}
-static int fix_data(int nid, int *type)
- {
- if (nid == NID_pkcs9_emailAddress)
- *type=V_ASN1_IA5STRING;
- if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
- *type=V_ASN1_T61STRING;
- if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
- *type=V_ASN1_T61STRING;
- if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
- return(0);
- if (nid == NID_pkcs9_unstructuredName)
- *type=V_ASN1_IA5STRING;
- return(1);
- }
-
-static int check_time_format(char *str)
+static int check_time_format(const char *str)
{
- ASN1_UTCTIME tm;
+ ASN1_TIME tm;
tm.data=(unsigned char *)str;
tm.length=strlen(str);
tm.type=V_ASN1_UTCTIME;
- return(ASN1_UTCTIME_check(&tm));
+ if (ASN1_TIME_check(&tm))
+ return 1;
+ tm.type=V_ASN1_GENERALIZEDTIME;
+ return ASN1_TIME_check(&tm);
}
static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
diff --git a/crypto/openssl/apps/dsa.c b/crypto/openssl/apps/dsa.c
index cbc1fe3..5e68a56 100644
--- a/crypto/openssl/apps/dsa.c
+++ b/crypto/openssl/apps/dsa.c
@@ -65,11 +65,11 @@
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
-#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
+#include <openssl/dsa.h>
#undef PROG
#define PROG dsa_main
diff --git a/crypto/openssl/apps/dsaparam.c b/crypto/openssl/apps/dsaparam.c
index c301e81..4305a73 100644
--- a/crypto/openssl/apps/dsaparam.c
+++ b/crypto/openssl/apps/dsaparam.c
@@ -475,4 +475,10 @@ static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
#endif
return 1;
}
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
#endif
diff --git a/crypto/openssl/apps/enc.c b/crypto/openssl/apps/enc.c
index f4f9a4c..8f5e5b8 100644
--- a/crypto/openssl/apps/enc.c
+++ b/crypto/openssl/apps/enc.c
@@ -226,7 +226,12 @@ int MAIN(int argc, char **argv)
goto bad;
}
buf[0]='\0';
- fgets(buf,sizeof buf,infile);
+ if (!fgets(buf,sizeof buf,infile))
+ {
+ BIO_printf(bio_err,"unable to read key from '%s'\n",
+ file);
+ goto bad;
+ }
fclose(infile);
i=strlen(buf);
if ((i > 0) &&
diff --git a/crypto/openssl/apps/gendsa.c b/crypto/openssl/apps/gendsa.c
index 8a296c6..22c3962 100644
--- a/crypto/openssl/apps/gendsa.c
+++ b/crypto/openssl/apps/gendsa.c
@@ -279,4 +279,10 @@ end:
apps_shutdown();
OPENSSL_EXIT(ret);
}
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
#endif
diff --git a/crypto/openssl/apps/genpkey.c b/crypto/openssl/apps/genpkey.c
deleted file mode 100644
index 6dfda08..0000000
--- a/crypto/openssl/apps/genpkey.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* apps/genpkey.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-#include <stdio.h>
-#include <string.h>
-#include "apps.h"
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-
-static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
- const char *file, ENGINE *e);
-static int genpkey_cb(EVP_PKEY_CTX *ctx);
-
-#define PROG genpkey_main
-
-int MAIN(int, char **);
-
-int MAIN(int argc, char **argv)
- {
- ENGINE *e = NULL;
- char **args, *outfile = NULL;
- char *passarg = NULL;
- BIO *in = NULL, *out = NULL;
- const EVP_CIPHER *cipher = NULL;
- int outformat;
- int text = 0;
- EVP_PKEY *pkey=NULL;
- EVP_PKEY_CTX *ctx = NULL;
- char *pass = NULL;
- int badarg = 0;
- int ret = 1, rv;
-
- int do_param = 0;
-
- if (bio_err == NULL)
- bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
-
- if (!load_config(bio_err, NULL))
- goto end;
-
- outformat=FORMAT_PEM;
-
- ERR_load_crypto_strings();
- OpenSSL_add_all_algorithms();
- args = argv + 1;
- while (!badarg && *args && *args[0] == '-')
- {
- if (!strcmp(*args,"-outform"))
- {
- if (args[1])
- {
- args++;
- outformat=str2fmt(*args);
- }
- else badarg = 1;
- }
- else if (!strcmp(*args,"-pass"))
- {
- if (!args[1]) goto bad;
- passarg= *(++args);
- }
-#ifndef OPENSSL_NO_ENGINE
- else if (strcmp(*args,"-engine") == 0)
- {
- if (!args[1])
- goto bad;
- e = setup_engine(bio_err, *(++args), 0);
- }
-#endif
- else if (!strcmp (*args, "-paramfile"))
- {
- if (!args[1])
- goto bad;
- args++;
- if (do_param == 1)
- goto bad;
- if (!init_keygen_file(bio_err, &ctx, *args, e))
- goto end;
- }
- else if (!strcmp (*args, "-out"))
- {
- if (args[1])
- {
- args++;
- outfile = *args;
- }
- else badarg = 1;
- }
- else if (strcmp(*args,"-algorithm") == 0)
- {
- if (!args[1])
- goto bad;
- if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
- goto end;
- }
- else if (strcmp(*args,"-pkeyopt") == 0)
- {
- if (!args[1])
- goto bad;
- if (!ctx)
- {
- BIO_puts(bio_err, "No keytype specified\n");
- goto bad;
- }
- else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
- {
- BIO_puts(bio_err, "parameter setting error\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
- else if (strcmp(*args,"-genparam") == 0)
- {
- if (ctx)
- goto bad;
- do_param = 1;
- }
- else if (strcmp(*args,"-text") == 0)
- text=1;
- else
- {
- cipher = EVP_get_cipherbyname(*args + 1);
- if (!cipher)
- {
- BIO_printf(bio_err, "Unknown cipher %s\n",
- *args + 1);
- badarg = 1;
- }
- if (do_param == 1)
- badarg = 1;
- }
- args++;
- }
-
- if (!ctx)
- badarg = 1;
-
- if (badarg)
- {
- bad:
- BIO_printf(bio_err, "Usage: genpkey [options]\n");
- BIO_printf(bio_err, "where options may be\n");
- BIO_printf(bio_err, "-out file output file\n");
- BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
- BIO_printf(bio_err, "-pass arg output file pass phrase source\n");
- BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n");
-#ifndef OPENSSL_NO_ENGINE
- BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
-#endif
- BIO_printf(bio_err, "-paramfile file parameters file\n");
- BIO_printf(bio_err, "-algorithm alg the public key algorithm\n");
- BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
- " to value <value>\n");
- BIO_printf(bio_err, "-genparam generate parameters, not key\n");
- BIO_printf(bio_err, "-text print the in text\n");
- BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n");
- goto end;
- }
-
- if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
- {
- BIO_puts(bio_err, "Error getting password\n");
- goto end;
- }
-
- if (outfile)
- {
- if (!(out = BIO_new_file (outfile, "wb")))
- {
- BIO_printf(bio_err,
- "Can't open output file %s\n", outfile);
- goto end;
- }
- }
- else
- {
- out = BIO_new_fp (stdout, BIO_NOCLOSE);
-#ifdef OPENSSL_SYS_VMS
- {
- BIO *tmpbio = BIO_new(BIO_f_linebuffer());
- out = BIO_push(tmpbio, out);
- }
-#endif
- }
-
- EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
- EVP_PKEY_CTX_set_app_data(ctx, bio_err);
-
- if (do_param)
- {
- if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
- {
- BIO_puts(bio_err, "Error generating parameters\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
- else
- {
- if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
- {
- BIO_puts(bio_err, "Error generating key\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
-
- if (do_param)
- rv = PEM_write_bio_Parameters(out, pkey);
- else if (outformat == FORMAT_PEM)
- rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
- NULL, pass);
- else if (outformat == FORMAT_ASN1)
- rv = i2d_PrivateKey_bio(out, pkey);
- else
- {
- BIO_printf(bio_err, "Bad format specified for key\n");
- goto end;
- }
-
- if (rv <= 0)
- {
- BIO_puts(bio_err, "Error writing key\n");
- ERR_print_errors(bio_err);
- }
-
- if (text)
- {
- if (do_param)
- rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
- else
- rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
-
- if (rv <= 0)
- {
- BIO_puts(bio_err, "Error printing key\n");
- ERR_print_errors(bio_err);
- }
- }
-
- ret = 0;
-
- end:
- if (pkey)
- EVP_PKEY_free(pkey);
- if (ctx)
- EVP_PKEY_CTX_free(ctx);
- if (out)
- BIO_free_all(out);
- BIO_free(in);
- if (pass)
- OPENSSL_free(pass);
-
- return ret;
- }
-
-static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
- const char *file, ENGINE *e)
- {
- BIO *pbio;
- EVP_PKEY *pkey = NULL;
- EVP_PKEY_CTX *ctx = NULL;
- if (*pctx)
- {
- BIO_puts(err, "Parameters already set!\n");
- return 0;
- }
-
- pbio = BIO_new_file(file, "r");
- if (!pbio)
- {
- BIO_printf(err, "Can't open parameter file %s\n", file);
- return 0;
- }
-
- pkey = PEM_read_bio_Parameters(pbio, NULL);
- BIO_free(pbio);
-
- if (!pkey)
- {
- BIO_printf(bio_err, "Error reading parameter file %s\n", file);
- return 0;
- }
-
- ctx = EVP_PKEY_CTX_new(pkey, e);
- if (!ctx)
- goto err;
- if (EVP_PKEY_keygen_init(ctx) <= 0)
- goto err;
- EVP_PKEY_free(pkey);
- *pctx = ctx;
- return 1;
-
- err:
- BIO_puts(err, "Error initializing context\n");
- ERR_print_errors(err);
- if (ctx)
- EVP_PKEY_CTX_free(ctx);
- if (pkey)
- EVP_PKEY_free(pkey);
- return 0;
-
- }
-
-int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
- const char *algname, ENGINE *e, int do_param)
- {
- EVP_PKEY_CTX *ctx = NULL;
- const EVP_PKEY_ASN1_METHOD *ameth;
- ENGINE *tmpeng = NULL;
- int pkey_id;
-
- if (*pctx)
- {
- BIO_puts(err, "Algorithm already set!\n");
- return 0;
- }
-
- ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
-
-#ifndef OPENSSL_NO_ENGINE
- if (!ameth && e)
- ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
-#endif
-
- if (!ameth)
- {
- BIO_printf(bio_err, "Algorithm %s not found\n", algname);
- return 0;
- }
-
- ERR_clear_error();
-
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
-#ifndef OPENSSL_NO_ENGINE
- if (tmpeng)
- ENGINE_finish(tmpeng);
-#endif
- ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
-
- if (!ctx)
- goto err;
- if (do_param)
- {
- if (EVP_PKEY_paramgen_init(ctx) <= 0)
- goto err;
- }
- else
- {
- if (EVP_PKEY_keygen_init(ctx) <= 0)
- goto err;
- }
-
- *pctx = ctx;
- return 1;
-
- err:
- BIO_printf(err, "Error initializing %s context\n", algname);
- ERR_print_errors(err);
- if (ctx)
- EVP_PKEY_CTX_free(ctx);
- return 0;
-
- }
-
-static int genpkey_cb(EVP_PKEY_CTX *ctx)
- {
- char c='*';
- BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
- int p;
- p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
- if (p == 0) c='.';
- if (p == 1) c='+';
- if (p == 2) c='*';
- if (p == 3) c='\n';
- BIO_write(b,&c,1);
- (void)BIO_flush(b);
-#ifdef LINT
- p=n;
-#endif
- return 1;
- }
diff --git a/crypto/openssl/apps/genrsa.c b/crypto/openssl/apps/genrsa.c
index fdc0d4a..5759acb 100644
--- a/crypto/openssl/apps/genrsa.c
+++ b/crypto/openssl/apps/genrsa.c
@@ -106,9 +106,9 @@ int MAIN(int argc, char **argv)
char *inrand=NULL;
BIO *out=NULL;
BIGNUM *bn = BN_new();
- RSA *rsa = RSA_new();
+ RSA *rsa = NULL;
- if(!bn || !rsa) goto err;
+ if(!bn) goto err;
apps_startup();
BN_GENCB_set(&cb, genrsa_cb, bio_err);
@@ -269,6 +269,10 @@ bad:
BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
num);
+ rsa = RSA_new();
+ if (!rsa)
+ goto err;
+
if (use_x931)
{
BIGNUM *pubexp;
diff --git a/crypto/openssl/apps/openssl.c b/crypto/openssl/apps/openssl.c
index 7d2b476..480fef9 100644
--- a/crypto/openssl/apps/openssl.c
+++ b/crypto/openssl/apps/openssl.c
@@ -235,16 +235,19 @@ int main(int Argc, char *Argv[])
in_FIPS_mode = 0;
-#ifdef OPENSSL_FIPS
if(getenv("OPENSSL_FIPS")) {
+#ifdef OPENSSL_FIPS
if (!FIPS_mode_set(1)) {
ERR_load_crypto_strings();
ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
EXIT(1);
}
in_FIPS_mode = 1;
- }
+#else
+ fprintf(stderr, "FIPS mode not supported.\n");
+ EXIT(1);
#endif
+ }
if (bio_err == NULL)
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
@@ -333,7 +336,8 @@ int main(int Argc, char *Argv[])
else prompt="OpenSSL> ";
fputs(prompt,stdout);
fflush(stdout);
- fgets(p,n,stdin);
+ if (!fgets(p,n,stdin))
+ goto end;
if (p[0] == '\0') goto end;
i=strlen(p);
if (i <= 1) break;
diff --git a/crypto/openssl/apps/pkcs12.c b/crypto/openssl/apps/pkcs12.c
index 248bc11..0db0b79 100644
--- a/crypto/openssl/apps/pkcs12.c
+++ b/crypto/openssl/apps/pkcs12.c
@@ -68,6 +68,12 @@
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
+#ifdef OPENSSL_SYS_NETWARE
+/* Rename these functions to avoid name clashes on NetWare OS */
+#define uni2asc OPENSSL_uni2asc
+#define asc2uni OPENSSL_asc2uni
+#endif
+
#define PROG pkcs12_main
const EVP_CIPHER *enc;
diff --git a/crypto/openssl/apps/pkey.c b/crypto/openssl/apps/pkey.c
deleted file mode 100644
index 17e6702..0000000
--- a/crypto/openssl/apps/pkey.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* apps/pkey.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-#include <stdio.h>
-#include <string.h>
-#include "apps.h"
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
-#define PROG pkey_main
-
-int MAIN(int, char **);
-
-int MAIN(int argc, char **argv)
- {
- ENGINE *e = NULL;
- char **args, *infile = NULL, *outfile = NULL;
- char *passargin = NULL, *passargout = NULL;
- BIO *in = NULL, *out = NULL;
- const EVP_CIPHER *cipher = NULL;
- int informat, outformat;
- int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
- EVP_PKEY *pkey=NULL;
- char *passin = NULL, *passout = NULL;
- int badarg = 0;
-#ifndef OPENSSL_NO_ENGINE
- char *engine=NULL;
-#endif
- int ret = 1;
-
- if (bio_err == NULL)
- bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
-
- if (!load_config(bio_err, NULL))
- goto end;
-
- informat=FORMAT_PEM;
- outformat=FORMAT_PEM;
-
- ERR_load_crypto_strings();
- OpenSSL_add_all_algorithms();
- args = argv + 1;
- while (!badarg && *args && *args[0] == '-')
- {
- if (!strcmp(*args,"-inform"))
- {
- if (args[1])
- {
- args++;
- informat=str2fmt(*args);
- }
- else badarg = 1;
- }
- else if (!strcmp(*args,"-outform"))
- {
- if (args[1])
- {
- args++;
- outformat=str2fmt(*args);
- }
- else badarg = 1;
- }
- else if (!strcmp(*args,"-passin"))
- {
- if (!args[1]) goto bad;
- passargin= *(++args);
- }
- else if (!strcmp(*args,"-passout"))
- {
- if (!args[1]) goto bad;
- passargout= *(++args);
- }
-#ifndef OPENSSL_NO_ENGINE
- else if (strcmp(*args,"-engine") == 0)
- {
- if (!args[1]) goto bad;
- engine= *(++args);
- }
-#endif
- else if (!strcmp (*args, "-in"))
- {
- if (args[1])
- {
- args++;
- infile = *args;
- }
- else badarg = 1;
- }
- else if (!strcmp (*args, "-out"))
- {
- if (args[1])
- {
- args++;
- outfile = *args;
- }
- else badarg = 1;
- }
- else if (strcmp(*args,"-pubin") == 0)
- {
- pubin=1;
- pubout=1;
- pubtext=1;
- }
- else if (strcmp(*args,"-pubout") == 0)
- pubout=1;
- else if (strcmp(*args,"-text_pub") == 0)
- {
- pubtext=1;
- text=1;
- }
- else if (strcmp(*args,"-text") == 0)
- text=1;
- else if (strcmp(*args,"-noout") == 0)
- noout=1;
- else
- {
- cipher = EVP_get_cipherbyname(*args + 1);
- if (!cipher)
- {
- BIO_printf(bio_err, "Unknown cipher %s\n",
- *args + 1);
- badarg = 1;
- }
- }
- args++;
- }
-
- if (badarg)
- {
- bad:
- BIO_printf(bio_err, "Usage pkey [options]\n");
- BIO_printf(bio_err, "where options are\n");
- BIO_printf(bio_err, "-in file input file\n");
- BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
- BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
- BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
- BIO_printf(bio_err, "-out file output file\n");
- BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
-#ifndef OPENSSL_NO_ENGINE
- BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
-#endif
- return 1;
- }
-
-#ifndef OPENSSL_NO_ENGINE
- e = setup_engine(bio_err, engine, 0);
-#endif
-
- if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
- {
- BIO_printf(bio_err, "Error getting passwords\n");
- goto end;
- }
-
- if (outfile)
- {
- if (!(out = BIO_new_file (outfile, "wb")))
- {
- BIO_printf(bio_err,
- "Can't open output file %s\n", outfile);
- goto end;
- }
- }
- else
- {
- out = BIO_new_fp (stdout, BIO_NOCLOSE);
-#ifdef OPENSSL_SYS_VMS
- {
- BIO *tmpbio = BIO_new(BIO_f_linebuffer());
- out = BIO_push(tmpbio, out);
- }
-#endif
- }
-
- if (pubin)
- pkey = load_pubkey(bio_err, infile, informat, 1,
- passin, e, "Public Key");
- else
- pkey = load_key(bio_err, infile, informat, 1,
- passin, e, "key");
- if (!pkey)
- goto end;
-
- if (!noout)
- {
- if (outformat == FORMAT_PEM)
- {
- if (pubout)
- PEM_write_bio_PUBKEY(out,pkey);
- else
- PEM_write_bio_PrivateKey(out, pkey, cipher,
- NULL, 0, NULL, passout);
- }
- else if (outformat == FORMAT_ASN1)
- {
- if (pubout)
- i2d_PUBKEY_bio(out, pkey);
- else
- i2d_PrivateKey_bio(out, pkey);
- }
- else
- {
- BIO_printf(bio_err, "Bad format specified for key\n");
- goto end;
- }
-
- }
-
- if (text)
- {
- if (pubtext)
- EVP_PKEY_print_public(out, pkey, 0, NULL);
- else
- EVP_PKEY_print_private(out, pkey, 0, NULL);
- }
-
- ret = 0;
-
- end:
- EVP_PKEY_free(pkey);
- BIO_free_all(out);
- BIO_free(in);
- if (passin)
- OPENSSL_free(passin);
- if (passout)
- OPENSSL_free(passout);
-
- return ret;
- }
diff --git a/crypto/openssl/apps/pkeyparam.c b/crypto/openssl/apps/pkeyparam.c
deleted file mode 100644
index 4319eb4..0000000
--- a/crypto/openssl/apps/pkeyparam.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* apps/pkeyparam.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-#include <stdio.h>
-#include <string.h>
-#include "apps.h"
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
-#define PROG pkeyparam_main
-
-int MAIN(int, char **);
-
-int MAIN(int argc, char **argv)
- {
- char **args, *infile = NULL, *outfile = NULL;
- BIO *in = NULL, *out = NULL;
- int text = 0, noout = 0;
- EVP_PKEY *pkey=NULL;
- int badarg = 0;
-#ifndef OPENSSL_NO_ENGINE
- ENGINE *e = NULL;
- char *engine=NULL;
-#endif
- int ret = 1;
-
- if (bio_err == NULL)
- bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
-
- if (!load_config(bio_err, NULL))
- goto end;
-
- ERR_load_crypto_strings();
- OpenSSL_add_all_algorithms();
- args = argv + 1;
- while (!badarg && *args && *args[0] == '-')
- {
- if (!strcmp (*args, "-in"))
- {
- if (args[1])
- {
- args++;
- infile = *args;
- }
- else badarg = 1;
- }
- else if (!strcmp (*args, "-out"))
- {
- if (args[1])
- {
- args++;
- outfile = *args;
- }
- else badarg = 1;
- }
-#ifndef OPENSSL_NO_ENGINE
- else if (strcmp(*args,"-engine") == 0)
- {
- if (!args[1]) goto bad;
- engine= *(++args);
- }
-#endif
-
- else if (strcmp(*args,"-text") == 0)
- text=1;
- else if (strcmp(*args,"-noout") == 0)
- noout=1;
- args++;
- }
-
- if (badarg)
- {
-#ifndef OPENSSL_NO_ENGINE
- bad:
-#endif
- BIO_printf(bio_err, "Usage pkeyparam [options]\n");
- BIO_printf(bio_err, "where options are\n");
- BIO_printf(bio_err, "-in file input file\n");
- BIO_printf(bio_err, "-out file output file\n");
- BIO_printf(bio_err, "-text print parameters as text\n");
- BIO_printf(bio_err, "-noout don't output encoded parameters\n");
-#ifndef OPENSSL_NO_ENGINE
- BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
-#endif
- return 1;
- }
-
-#ifndef OPENSSL_NO_ENGINE
- e = setup_engine(bio_err, engine, 0);
-#endif
-
- if (infile)
- {
- if (!(in = BIO_new_file (infile, "r")))
- {
- BIO_printf(bio_err,
- "Can't open input file %s\n", infile);
- goto end;
- }
- }
- else
- in = BIO_new_fp (stdin, BIO_NOCLOSE);
-
- if (outfile)
- {
- if (!(out = BIO_new_file (outfile, "w")))
- {
- BIO_printf(bio_err,
- "Can't open output file %s\n", outfile);
- goto end;
- }
- }
- else
- {
- out = BIO_new_fp (stdout, BIO_NOCLOSE);
-#ifdef OPENSSL_SYS_VMS
- {
- BIO *tmpbio = BIO_new(BIO_f_linebuffer());
- out = BIO_push(tmpbio, out);
- }
-#endif
- }
-
- pkey = PEM_read_bio_Parameters(in, NULL);
- if (!pkey)
- {
- BIO_printf(bio_err, "Error reading paramters\n");
- ERR_print_errors(bio_err);
- goto end;
- }
-
- if (!noout)
- PEM_write_bio_Parameters(out,pkey);
-
- if (text)
- EVP_PKEY_print_params(out, pkey, 0, NULL);
-
- ret = 0;
-
- end:
- EVP_PKEY_free(pkey);
- BIO_free_all(out);
- BIO_free(in);
-
- return ret;
- }
diff --git a/crypto/openssl/apps/pkeyutl.c b/crypto/openssl/apps/pkeyutl.c
deleted file mode 100644
index b808e1e..0000000
--- a/crypto/openssl/apps/pkeyutl.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006.
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-
-#include "apps.h"
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/evp.h>
-
-#define KEY_PRIVKEY 1
-#define KEY_PUBKEY 2
-#define KEY_CERT 3
-
-static void usage(void);
-
-#undef PROG
-
-#define PROG pkeyutl_main
-
-static EVP_PKEY_CTX *init_ctx(int *pkeysize,
- char *keyfile, int keyform, int key_type,
- char *passargin, int pkey_op, ENGINE *e);
-
-static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
- const char *file);
-
-static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
- unsigned char *out, size_t *poutlen,
- unsigned char *in, size_t inlen);
-
-int MAIN(int argc, char **);
-
-int MAIN(int argc, char **argv)
-{
- BIO *in = NULL, *out = NULL;
- char *infile = NULL, *outfile = NULL, *sigfile = NULL;
- ENGINE *e = NULL;
- int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
- int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
- char badarg = 0, rev = 0;
- char hexdump = 0, asn1parse = 0;
- EVP_PKEY_CTX *ctx = NULL;
- char *passargin = NULL;
- int keysize = -1;
-
- unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
- size_t buf_outlen;
- int buf_inlen = 0, siglen = -1;
-
- int ret = 1, rv = -1;
-
- argc--;
- argv++;
-
- if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
-
- if (!load_config(bio_err, NULL))
- goto end;
- ERR_load_crypto_strings();
- OpenSSL_add_all_algorithms();
-
- while(argc >= 1)
- {
- if (!strcmp(*argv,"-in"))
- {
- if (--argc < 1) badarg = 1;
- infile= *(++argv);
- }
- else if (!strcmp(*argv,"-out"))
- {
- if (--argc < 1) badarg = 1;
- outfile= *(++argv);
- }
- else if (!strcmp(*argv,"-sigfile"))
- {
- if (--argc < 1) badarg = 1;
- sigfile= *(++argv);
- }
- else if(!strcmp(*argv, "-inkey"))
- {
- if (--argc < 1)
- badarg = 1;
- else
- {
- ctx = init_ctx(&keysize,
- *(++argv), keyform, key_type,
- passargin, pkey_op, e);
- if (!ctx)
- {
- BIO_puts(bio_err,
- "Error initializing context\n");
- ERR_print_errors(bio_err);
- badarg = 1;
- }
- }
- }
- else if (!strcmp(*argv,"-peerkey"))
- {
- if (--argc < 1)
- badarg = 1;
- else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
- badarg = 1;
- }
- else if (!strcmp(*argv,"-passin"))
- {
- if (--argc < 1) badarg = 1;
- passargin= *(++argv);
- }
- else if (strcmp(*argv,"-peerform") == 0)
- {
- if (--argc < 1) badarg = 1;
- peerform=str2fmt(*(++argv));
- }
- else if (strcmp(*argv,"-keyform") == 0)
- {
- if (--argc < 1) badarg = 1;
- keyform=str2fmt(*(++argv));
- }
-#ifndef OPENSSL_NO_ENGINE
- else if(!strcmp(*argv, "-engine"))
- {
- if (--argc < 1)
- badarg = 1;
- else
- e = setup_engine(bio_err, *(++argv), 0);
- }
-#endif
- else if(!strcmp(*argv, "-pubin"))
- key_type = KEY_PUBKEY;
- else if(!strcmp(*argv, "-certin"))
- key_type = KEY_CERT;
- else if(!strcmp(*argv, "-asn1parse"))
- asn1parse = 1;
- else if(!strcmp(*argv, "-hexdump"))
- hexdump = 1;
- else if(!strcmp(*argv, "-sign"))
- pkey_op = EVP_PKEY_OP_SIGN;
- else if(!strcmp(*argv, "-verify"))
- pkey_op = EVP_PKEY_OP_VERIFY;
- else if(!strcmp(*argv, "-verifyrecover"))
- pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
- else if(!strcmp(*argv, "-rev"))
- rev = 1;
- else if(!strcmp(*argv, "-encrypt"))
- pkey_op = EVP_PKEY_OP_ENCRYPT;
- else if(!strcmp(*argv, "-decrypt"))
- pkey_op = EVP_PKEY_OP_DECRYPT;
- else if(!strcmp(*argv, "-derive"))
- pkey_op = EVP_PKEY_OP_DERIVE;
- else if (strcmp(*argv,"-pkeyopt") == 0)
- {
- if (--argc < 1)
- badarg = 1;
- else if (!ctx)
- {
- BIO_puts(bio_err,
- "-pkeyopt command before -inkey\n");
- badarg = 1;
- }
- else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
- {
- BIO_puts(bio_err, "parameter setting error\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
- else badarg = 1;
- if(badarg)
- {
- usage();
- goto end;
- }
- argc--;
- argv++;
- }
-
- if (!ctx)
- {
- usage();
- goto end;
- }
-
- if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
- {
- BIO_puts(bio_err, "Signature file specified for non verify\n");
- goto end;
- }
-
- if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
- {
- BIO_puts(bio_err, "No signature file specified for verify\n");
- goto end;
- }
-
-/* FIXME: seed PRNG only if needed */
- app_RAND_load_file(NULL, bio_err, 0);
-
- if (pkey_op != EVP_PKEY_OP_DERIVE)
- {
- if(infile)
- {
- if(!(in = BIO_new_file(infile, "rb")))
- {
- BIO_puts(bio_err,
- "Error Opening Input File\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
- else
- in = BIO_new_fp(stdin, BIO_NOCLOSE);
- }
-
- if(outfile)
- {
- if(!(out = BIO_new_file(outfile, "wb")))
- {
- BIO_printf(bio_err, "Error Creating Output File\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
- else
- {
- out = BIO_new_fp(stdout, BIO_NOCLOSE);
-#ifdef OPENSSL_SYS_VMS
- {
- BIO *tmpbio = BIO_new(BIO_f_linebuffer());
- out = BIO_push(tmpbio, out);
- }
-#endif
- }
-
- if (sigfile)
- {
- BIO *sigbio = BIO_new_file(sigfile, "rb");
- if (!sigbio)
- {
- BIO_printf(bio_err, "Can't open signature file %s\n",
- sigfile);
- goto end;
- }
- siglen = bio_to_mem(&sig, keysize * 10, sigbio);
- BIO_free(sigbio);
- if (siglen <= 0)
- {
- BIO_printf(bio_err, "Error reading signature data\n");
- goto end;
- }
- }
-
- if (in)
- {
- /* Read the input data */
- buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
- if(buf_inlen <= 0)
- {
- BIO_printf(bio_err, "Error reading input Data\n");
- exit(1);
- }
- if(rev)
- {
- size_t i;
- unsigned char ctmp;
- size_t l = (size_t)buf_inlen;
- for(i = 0; i < l/2; i++)
- {
- ctmp = buf_in[i];
- buf_in[i] = buf_in[l - 1 - i];
- buf_in[l - 1 - i] = ctmp;
- }
- }
- }
-
- if(pkey_op == EVP_PKEY_OP_VERIFY)
- {
- rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
- buf_in, (size_t)buf_inlen);
- if (rv == 0)
- BIO_puts(out, "Signature Verification Failure\n");
- else if (rv == 1)
- BIO_puts(out, "Signature Verified Successfully\n");
- if (rv >= 0)
- goto end;
- }
- else
- {
- rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
- buf_in, (size_t)buf_inlen);
- if (rv > 0)
- {
- buf_out = OPENSSL_malloc(buf_outlen);
- if (!buf_out)
- rv = -1;
- else
- rv = do_keyop(ctx, pkey_op,
- buf_out, (size_t *)&buf_outlen,
- buf_in, (size_t)buf_inlen);
- }
- }
-
- if(rv <= 0)
- {
- BIO_printf(bio_err, "Public Key operation error\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- ret = 0;
- if(asn1parse)
- {
- if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
- ERR_print_errors(bio_err);
- }
- else if(hexdump)
- BIO_dump(out, (char *)buf_out, buf_outlen);
- else
- BIO_write(out, buf_out, buf_outlen);
-
- end:
- if (ctx)
- EVP_PKEY_CTX_free(ctx);
- BIO_free(in);
- BIO_free_all(out);
- if (buf_in)
- OPENSSL_free(buf_in);
- if (buf_out)
- OPENSSL_free(buf_out);
- if (sig)
- OPENSSL_free(sig);
- return ret;
-}
-
-static void usage()
-{
- BIO_printf(bio_err, "Usage: pkeyutl [options]\n");
- BIO_printf(bio_err, "-in file input file\n");
- BIO_printf(bio_err, "-out file output file\n");
- BIO_printf(bio_err, "-signature file signature file (verify operation only)\n");
- BIO_printf(bio_err, "-inkey file input key\n");
- BIO_printf(bio_err, "-keyform arg private key format - default PEM\n");
- BIO_printf(bio_err, "-pubin input is a public key\n");
- BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n");
- BIO_printf(bio_err, "-pkeyopt X:Y public key options\n");
- BIO_printf(bio_err, "-sign sign with private key\n");
- BIO_printf(bio_err, "-verify verify with public key\n");
- BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n");
- BIO_printf(bio_err, "-encrypt encrypt with public key\n");
- BIO_printf(bio_err, "-decrypt decrypt with private key\n");
- BIO_printf(bio_err, "-derive derive shared secret\n");
- BIO_printf(bio_err, "-hexdump hex dump output\n");
-#ifndef OPENSSL_NO_ENGINE
- BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
-#endif
- BIO_printf(bio_err, "-passin arg pass phrase source\n");
-
-}
-
-static EVP_PKEY_CTX *init_ctx(int *pkeysize,
- char *keyfile, int keyform, int key_type,
- char *passargin, int pkey_op, ENGINE *e)
- {
- EVP_PKEY *pkey = NULL;
- EVP_PKEY_CTX *ctx = NULL;
- char *passin = NULL;
- int rv = -1;
- X509 *x;
- if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
- || (pkey_op == EVP_PKEY_OP_DERIVE))
- && (key_type != KEY_PRIVKEY))
- {
- BIO_printf(bio_err, "A private key is needed for this operation\n");
- goto end;
- }
- if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
- {
- BIO_printf(bio_err, "Error getting password\n");
- goto end;
- }
- switch(key_type)
- {
- case KEY_PRIVKEY:
- pkey = load_key(bio_err, keyfile, keyform, 0,
- passin, e, "Private Key");
- break;
-
- case KEY_PUBKEY:
- pkey = load_pubkey(bio_err, keyfile, keyform, 0,
- NULL, e, "Public Key");
- break;
-
- case KEY_CERT:
- x = load_cert(bio_err, keyfile, keyform,
- NULL, e, "Certificate");
- if(x)
- {
- pkey = X509_get_pubkey(x);
- X509_free(x);
- }
- break;
-
- }
-
- *pkeysize = EVP_PKEY_size(pkey);
-
- if (!pkey)
- goto end;
-
- ctx = EVP_PKEY_CTX_new(pkey, e);
-
- EVP_PKEY_free(pkey);
-
- if (!ctx)
- goto end;
-
- switch(pkey_op)
- {
- case EVP_PKEY_OP_SIGN:
- rv = EVP_PKEY_sign_init(ctx);
- break;
-
- case EVP_PKEY_OP_VERIFY:
- rv = EVP_PKEY_verify_init(ctx);
- break;
-
- case EVP_PKEY_OP_VERIFYRECOVER:
- rv = EVP_PKEY_verify_recover_init(ctx);
- break;
-
- case EVP_PKEY_OP_ENCRYPT:
- rv = EVP_PKEY_encrypt_init(ctx);
- break;
-
- case EVP_PKEY_OP_DECRYPT:
- rv = EVP_PKEY_decrypt_init(ctx);
- break;
-
- case EVP_PKEY_OP_DERIVE:
- rv = EVP_PKEY_derive_init(ctx);
- break;
- }
-
- if (rv <= 0)
- {
- EVP_PKEY_CTX_free(ctx);
- ctx = NULL;
- }
-
- end:
-
- if (passin)
- OPENSSL_free(passin);
-
- return ctx;
-
-
- }
-
-static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
- const char *file)
- {
- EVP_PKEY *peer = NULL;
- int ret;
- if (!ctx)
- {
- BIO_puts(err, "-peerkey command before -inkey\n");
- return 0;
- }
-
- peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
-
- if (!peer)
- {
- BIO_printf(bio_err, "Error reading peer key %s\n", file);
- ERR_print_errors(err);
- return 0;
- }
-
- ret = EVP_PKEY_derive_set_peer(ctx, peer);
-
- EVP_PKEY_free(peer);
- if (ret <= 0)
- ERR_print_errors(err);
- return ret;
- }
-
-static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
- unsigned char *out, size_t *poutlen,
- unsigned char *in, size_t inlen)
- {
- int rv = 0;
- switch(pkey_op)
- {
- case EVP_PKEY_OP_VERIFYRECOVER:
- rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
- break;
-
- case EVP_PKEY_OP_SIGN:
- rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
- break;
-
- case EVP_PKEY_OP_ENCRYPT:
- rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
- break;
-
- case EVP_PKEY_OP_DECRYPT:
- rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
- break;
-
- case EVP_PKEY_OP_DERIVE:
- rv = EVP_PKEY_derive(ctx, out, poutlen);
- break;
-
- }
- return rv;
- }
diff --git a/crypto/openssl/apps/req.c b/crypto/openssl/apps/req.c
index 5ed0896..9f55cde 100644
--- a/crypto/openssl/apps/req.c
+++ b/crypto/openssl/apps/req.c
@@ -1433,11 +1433,17 @@ start2: for (;;)
BIO_snprintf(buf,sizeof buf,"%s_min",type);
if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
+ {
+ ERR_clear_error();
n_min = -1;
+ }
BIO_snprintf(buf,sizeof buf,"%s_max",type);
if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
+ {
+ ERR_clear_error();
n_max = -1;
+ }
if (!add_attribute_object(req,
v->value,def,value,nid,n_min,n_max, chtype))
@@ -1538,7 +1544,8 @@ start:
buf[0]='\0';
if (!batch)
{
- fgets(buf,sizeof buf,stdin);
+ if (!fgets(buf,sizeof buf,stdin))
+ return 0;
}
else
{
@@ -1596,7 +1603,8 @@ start:
buf[0]='\0';
if (!batch)
{
- fgets(buf,sizeof buf,stdin);
+ if (!fgets(buf,sizeof buf,stdin))
+ return 0;
}
else
{
diff --git a/crypto/openssl/apps/s_apps.h b/crypto/openssl/apps/s_apps.h
index 08fbbc2..f5a39ba 100644
--- a/crypto/openssl/apps/s_apps.h
+++ b/crypto/openssl/apps/s_apps.h
@@ -171,3 +171,6 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
unsigned char *data, int len,
void *arg);
#endif
+
+int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len);
+int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len);
diff --git a/crypto/openssl/apps/s_cb.c b/crypto/openssl/apps/s_cb.c
index a512589..97caffc 100644
--- a/crypto/openssl/apps/s_cb.c
+++ b/crypto/openssl/apps/s_cb.c
@@ -117,12 +117,17 @@
#undef NON_MAIN
#undef USE_SOCKETS
#include <openssl/err.h>
+#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include "s_apps.h"
+#define COOKIE_SECRET_LENGTH 16
+
int verify_depth=0;
int verify_error=X509_V_OK;
+unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
+int cookie_initialized=0;
int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
{
@@ -338,6 +343,12 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
break;
default:
str_version = "???";
+ case DTLS1_VERSION:
+ str_version = "DTLS 1.0 ";
+ break;
+ case DTLS1_BAD_VER:
+ str_version = "DTLS 1.0 (bad) ";
+ break;
}
if (version == SSL2_VERSION)
@@ -401,7 +412,10 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
}
}
- if (version == SSL3_VERSION || version == TLS1_VERSION)
+ if (version == SSL3_VERSION ||
+ version == TLS1_VERSION ||
+ version == DTLS1_VERSION ||
+ version == DTLS1_BAD_VER)
{
switch (content_type)
{
@@ -540,6 +554,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
case 15:
str_details1 = ", CertificateVerify";
break;
+ case 3:
+ str_details1 = ", HelloVerifyRequest";
+ break;
case 16:
str_details1 = ", ClientKeyExchange";
break;
@@ -621,6 +638,9 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
extname = "server ticket";
break;
+ case TLSEXT_TYPE_renegotiate:
+ extname = "renegotiate";
+ break;
default:
extname = "unknown";
@@ -634,3 +654,86 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
BIO_dump(bio, (char *)data, len);
(void)BIO_flush(bio);
}
+
+int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
+ {
+ unsigned char *buffer, result[EVP_MAX_MD_SIZE];
+ unsigned int length, resultlength;
+ struct sockaddr_in peer;
+
+ /* Initialize a random secret */
+ if (!cookie_initialized)
+ {
+ if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH))
+ {
+ BIO_printf(bio_err,"error setting random cookie secret\n");
+ return 0;
+ }
+ cookie_initialized = 1;
+ }
+
+ /* Read peer information */
+ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+
+ /* Create buffer with peer's address and port */
+ length = sizeof(peer.sin_addr);
+ length += sizeof(peer.sin_port);
+ buffer = OPENSSL_malloc(length);
+
+ if (buffer == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ return 0;
+ }
+
+ memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
+ memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
+
+ /* Calculate HMAC of buffer using the secret */
+ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+ buffer, length, result, &resultlength);
+ OPENSSL_free(buffer);
+
+ memcpy(cookie, result, resultlength);
+ *cookie_len = resultlength;
+
+ return 1;
+ }
+
+int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
+ {
+ unsigned char *buffer, result[EVP_MAX_MD_SIZE];
+ unsigned int length, resultlength;
+ struct sockaddr_in peer;
+
+ /* If secret isn't initialized yet, the cookie can't be valid */
+ if (!cookie_initialized)
+ return 0;
+
+ /* Read peer information */
+ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+
+ /* Create buffer with peer's address and port */
+ length = sizeof(peer.sin_addr);
+ length += sizeof(peer.sin_port);
+ buffer = (unsigned char*) OPENSSL_malloc(length);
+
+ if (buffer == NULL)
+ {
+ BIO_printf(bio_err,"out of memory\n");
+ return 0;
+ }
+
+ memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
+ memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
+
+ /* Calculate HMAC of buffer using the secret */
+ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+ buffer, length, result, &resultlength);
+ OPENSSL_free(buffer);
+
+ if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
+ return 1;
+
+ return 0;
+ }
diff --git a/crypto/openssl/apps/s_client.c b/crypto/openssl/apps/s_client.c
index 4974f5f..2f743f0 100644
--- a/crypto/openssl/apps/s_client.c
+++ b/crypto/openssl/apps/s_client.c
@@ -226,7 +226,7 @@ static void sc_usage(void)
BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
- BIO_printf(bio_err," -mtu - set the MTU\n");
+ BIO_printf(bio_err," -mtu - set the link layer MTU\n");
BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
BIO_printf(bio_err," -serverpref - Use server's cipher preferences (only SSLv2)\n");
@@ -249,6 +249,7 @@ static void sc_usage(void)
BIO_printf(bio_err," -status - request certificate status from server\n");
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
#endif
+ BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
}
#ifndef OPENSSL_NO_TLSEXT
@@ -286,7 +287,7 @@ int MAIN(int, char **);
int MAIN(int argc, char **argv)
{
- int off=0;
+ int off=0, clr = 0;
SSL *con=NULL,*con2=NULL;
X509_STORE *store = NULL;
int s,k,width,state=0;
@@ -318,6 +319,7 @@ int MAIN(int argc, char **argv)
BIO *sbio;
char *inrand=NULL;
int mbuf_len=0;
+ struct timeval timeout, *timeoutp;
#ifndef OPENSSL_NO_ENGINE
char *engine_id=NULL;
char *ssl_client_engine_id=NULL;
@@ -338,7 +340,7 @@ int MAIN(int argc, char **argv)
struct sockaddr peer;
int peerlen = sizeof(peer);
int enable_timeouts = 0 ;
- long mtu = 0;
+ long socket_mtu = 0;
#ifndef OPENSSL_NO_JPAKE
char *jpake_secret = NULL;
#endif
@@ -489,7 +491,7 @@ int MAIN(int argc, char **argv)
else if (strcmp(*argv,"-mtu") == 0)
{
if (--argc < 1) goto bad;
- mtu = atol(*(++argv));
+ socket_mtu = atol(*(++argv));
}
#endif
else if (strcmp(*argv,"-bugs") == 0)
@@ -535,6 +537,12 @@ int MAIN(int argc, char **argv)
#endif
else if (strcmp(*argv,"-serverpref") == 0)
off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
+ else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+ off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+ else if (strcmp(*argv,"-legacy_server_connect") == 0)
+ { off|=SSL_OP_LEGACY_SERVER_CONNECT; }
+ else if (strcmp(*argv,"-no_legacy_server_connect") == 0)
+ { clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
else if (strcmp(*argv,"-cipher") == 0)
{
if (--argc < 1) goto bad;
@@ -709,6 +717,9 @@ bad:
SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
else
SSL_CTX_set_options(ctx,off);
+
+ if (clr)
+ SSL_CTX_clear_options(ctx, clr);
/* DTLS: partial reads end up discarding unread UDP bytes :-(
* Setting read ahead solves this problem.
*/
@@ -819,7 +830,6 @@ re_start:
if ( SSL_version(con) == DTLS1_VERSION)
{
- struct timeval timeout;
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
if (getsockname(s, &peer, (void *)&peerlen) < 0)
@@ -843,10 +853,10 @@ re_start:
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
}
- if ( mtu > 0)
+ if (socket_mtu > 28)
{
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
- SSL_set_mtu(con, mtu);
+ SSL_set_mtu(con, socket_mtu - 28);
}
else
/* want to do MTU discovery */
@@ -1036,6 +1046,12 @@ SSL_set_tlsext_status_ids(con, ids);
FD_ZERO(&readfds);
FD_ZERO(&writefds);
+ if ((SSL_version(con) == DTLS1_VERSION) &&
+ DTLSv1_get_timeout(con, &timeout))
+ timeoutp = &timeout;
+ else
+ timeoutp = NULL;
+
if (SSL_in_init(con) && !SSL_total_renegotiations(con))
{
in_init=1;
@@ -1132,7 +1148,7 @@ SSL_set_tlsext_status_ids(con, ids);
if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
#endif
} else i=select(width,(void *)&readfds,(void *)&writefds,
- NULL,NULL);
+ NULL,timeoutp);
}
#elif defined(OPENSSL_SYS_NETWARE)
if(!write_tty) {
@@ -1142,11 +1158,11 @@ SSL_set_tlsext_status_ids(con, ids);
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
} else i=select(width,(void *)&readfds,(void *)&writefds,
- NULL,NULL);
+ NULL,timeoutp);
}
#else
i=select(width,(void *)&readfds,(void *)&writefds,
- NULL,NULL);
+ NULL,timeoutp);
#endif
if ( i < 0)
{
@@ -1157,6 +1173,11 @@ SSL_set_tlsext_status_ids(con, ids);
}
}
+ if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
+ {
+ BIO_printf(bio_err,"TIMEOUT occured\n");
+ }
+
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
{
k=SSL_write(con,&(cbuf[cbuf_off]),
@@ -1511,6 +1532,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
EVP_PKEY_bits(pktmp));
EVP_PKEY_free(pktmp);
}
+ BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
+ SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
#ifndef OPENSSL_NO_COMP
comp=SSL_get_current_compression(s);
expansion=SSL_get_current_expansion(s);
diff --git a/crypto/openssl/apps/s_server.c b/crypto/openssl/apps/s_server.c
index 84b1b28..88b308c 100644
--- a/crypto/openssl/apps/s_server.c
+++ b/crypto/openssl/apps/s_server.c
@@ -283,11 +283,10 @@ static char *engine_id=NULL;
static const char *session_id_prefix=NULL;
static int enable_timeouts = 0;
-#ifdef mtu
-#undef mtu
-#endif
-static long mtu;
+static long socket_mtu;
+#ifndef OPENSSL_NO_DTLS1
static int cert_chain = 0;
+#endif
#ifdef MONOLITH
@@ -375,7 +374,7 @@ static void sv_usage(void)
BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n");
BIO_printf(bio_err," -timeout - Enable timeouts\n");
- BIO_printf(bio_err," -mtu - Set MTU\n");
+ BIO_printf(bio_err," -mtu - Set link layer MTU\n");
BIO_printf(bio_err," -chain - Read a certificate chain\n");
BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n");
BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
@@ -405,6 +404,7 @@ static void sv_usage(void)
BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT2);
BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
+ BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
#endif
}
@@ -772,6 +772,7 @@ int MAIN(int argc, char *argv[])
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
X509 *s_cert = NULL, *s_dcert = NULL;
EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+ int no_cache = 0;
#ifndef OPENSSL_NO_TLSEXT
EVP_PKEY *s_key2 = NULL;
X509 *s_cert2 = NULL;
@@ -911,6 +912,8 @@ int MAIN(int argc, char *argv[])
if (--argc < 1) goto bad;
CApath= *(++argv);
}
+ else if (strcmp(*argv,"-no_cache") == 0)
+ no_cache = 1;
else if (strcmp(*argv,"-crl_check") == 0)
{
vflags |= X509_V_FLAG_CRL_CHECK;
@@ -921,6 +924,8 @@ int MAIN(int argc, char *argv[])
}
else if (strcmp(*argv,"-serverpref") == 0)
{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
+ else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+ off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
else if (strcmp(*argv,"-cipher") == 0)
{
if (--argc < 1) goto bad;
@@ -1032,7 +1037,7 @@ int MAIN(int argc, char *argv[])
else if (strcmp(*argv,"-mtu") == 0)
{
if (--argc < 1) goto bad;
- mtu = atol(*(++argv));
+ socket_mtu = atol(*(++argv));
}
else if (strcmp(*argv, "-chain") == 0)
cert_chain = 1;
@@ -1253,8 +1258,10 @@ bad:
if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
-
- SSL_CTX_sess_set_cache_size(ctx,128);
+ if (no_cache)
+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+ else
+ SSL_CTX_sess_set_cache_size(ctx,128);
#if 0
if (cipher == NULL) cipher=getenv("SSL_CIPHER");
@@ -1321,7 +1328,10 @@ bad:
if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
- SSL_CTX_sess_set_cache_size(ctx2,128);
+ if (no_cache)
+ SSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF);
+ else
+ SSL_CTX_sess_set_cache_size(ctx2,128);
if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
(!SSL_CTX_set_default_verify_paths(ctx2)))
@@ -1498,6 +1508,10 @@ bad:
SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
sizeof s_server_session_id_context);
+ /* Set DTLS cookie generation and verification callbacks */
+ SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
+ SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
+
#ifndef OPENSSL_NO_TLSEXT
if (ctx2)
{
@@ -1591,8 +1605,11 @@ static int sv_body(char *hostname, int s, unsigned char *context)
unsigned long l;
SSL *con=NULL;
BIO *sbio;
+ struct timeval timeout;
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
struct timeval tv;
+#else
+ struct timeval *timeoutp;
#endif
if ((buf=OPENSSL_malloc(bufsize)) == NULL)
@@ -1644,7 +1661,6 @@ static int sv_body(char *hostname, int s, unsigned char *context)
if (SSL_version(con) == DTLS1_VERSION)
{
- struct timeval timeout;
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
@@ -1660,10 +1676,10 @@ static int sv_body(char *hostname, int s, unsigned char *context)
}
- if ( mtu > 0)
+ if (socket_mtu > 28)
{
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
- SSL_set_mtu(con, mtu);
+ SSL_set_mtu(con, socket_mtu - 28);
}
else
/* want to do MTU discovery */
@@ -1745,7 +1761,19 @@ static int sv_body(char *hostname, int s, unsigned char *context)
if(_kbhit())
read_from_terminal = 1;
#else
- i=select(width,(void *)&readfds,NULL,NULL,NULL);
+ if ((SSL_version(con) == DTLS1_VERSION) &&
+ DTLSv1_get_timeout(con, &timeout))
+ timeoutp = &timeout;
+ else
+ timeoutp = NULL;
+
+ i=select(width,(void *)&readfds,NULL,NULL,timeoutp);
+
+ if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
+ {
+ BIO_printf(bio_err,"TIMEOUT occured\n");
+ }
+
if (i <= 0) continue;
if (FD_ISSET(fileno(stdin),&readfds))
read_from_terminal = 1;
@@ -2002,6 +2030,8 @@ static int init_ssl_connection(SSL *con)
con->kssl_ctx->client_princ);
}
#endif /* OPENSSL_NO_KRB5 */
+ BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
+ SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
return(1);
}
diff --git a/crypto/openssl/apps/s_socket.c b/crypto/openssl/apps/s_socket.c
index 4a922e1..cf82358 100644
--- a/crypto/openssl/apps/s_socket.c
+++ b/crypto/openssl/apps/s_socket.c
@@ -62,6 +62,12 @@
#include <errno.h>
#include <signal.h>
+#ifdef FLAT_INC
+#include "e_os2.h"
+#else
+#include "../e_os2.h"
+#endif
+
/* With IPv6, it looks like Digital has mixed up the proper order of
recursive header file inclusion, resulting in the compiler complaining
that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c
index af077b5..393a7ba 100644
--- a/crypto/openssl/apps/speed.c
+++ b/crypto/openssl/apps/speed.c
@@ -254,8 +254,18 @@
# endif
#endif
-#if !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_OS2) && !defined(OPENSSL_SYS_NETWARE)
-# define HAVE_FORK 1
+#ifndef HAVE_FORK
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
+# define HAVE_FORK 0
+# else
+# define HAVE_FORK 1
+# endif
+#endif
+
+#if HAVE_FORK
+# undef NO_FORK
+#else
+# define NO_FORK
#endif
#undef BUFSIZE
@@ -271,7 +281,7 @@ static void print_message(const char *s,long num,int length);
static void pkey_print_message(const char *str, const char *str2,
long num, int bits, int sec);
static void print_result(int alg,int run_no,int count,double time_used);
-#ifdef HAVE_FORK
+#ifndef NO_FORK
static int do_multi(int multi);
#endif
@@ -293,8 +303,12 @@ static const char *names[ALGOR_NUM]={
"aes-128 ige","aes-192 ige","aes-256 ige"};
static double results[ALGOR_NUM][SIZE_NUM];
static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
+#ifndef OPENSSL_NO_RSA
static double rsa_results[RSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_DSA
static double dsa_results[DSA_NUM][2];
+#endif
#ifndef OPENSSL_NO_ECDSA
static double ecdsa_results[EC_NUM][2];
#endif
@@ -749,7 +763,7 @@ int MAIN(int argc, char **argv)
const EVP_CIPHER *evp_cipher=NULL;
const EVP_MD *evp_md=NULL;
int decrypt=0;
-#ifdef HAVE_FORK
+#ifndef NO_FORK
int multi=0;
#endif
@@ -877,7 +891,7 @@ int MAIN(int argc, char **argv)
j--;
}
#endif
-#ifdef HAVE_FORK
+#ifndef NO_FORK
else if ((argc > 0) && (strcmp(*argv,"-multi") == 0))
{
argc--;
@@ -1257,7 +1271,7 @@ int MAIN(int argc, char **argv)
BIO_printf(bio_err,"-evp e use EVP e.\n");
BIO_printf(bio_err,"-decrypt time decryption instead of encryption (only EVP).\n");
BIO_printf(bio_err,"-mr produce machine readable output.\n");
-#ifdef HAVE_FORK
+#ifndef NO_FORK
BIO_printf(bio_err,"-multi n run n benchmarks in parallel.\n");
#endif
goto end;
@@ -1267,7 +1281,7 @@ int MAIN(int argc, char **argv)
j++;
}
-#ifdef HAVE_FORK
+#ifndef NO_FORK
if(multi && do_multi(multi))
goto show_res;
#endif
@@ -2462,7 +2476,7 @@ int MAIN(int argc, char **argv)
}
if (rnd_fake) RAND_cleanup();
#endif
-#ifdef HAVE_FORK
+#ifndef NO_FORK
show_res:
#endif
if(!mr)
@@ -2717,7 +2731,7 @@ static void print_result(int alg,int run_no,int count,double time_used)
results[alg][run_no]=((double)count)/time_used*lengths[run_no];
}
-#ifdef HAVE_FORK
+#ifndef NO_FORK
static char *sstrsep(char **string, const char *delim)
{
char isdelim[256];
diff --git a/crypto/openssl/apps/ts.c b/crypto/openssl/apps/ts.c
deleted file mode 100644
index 74e7e93..0000000
--- a/crypto/openssl/apps/ts.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-/* apps/ts.c */
-/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
- * project 2002.
- */
-/* ====================================================================
- * Copyright (c) 2001 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "apps.h"
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/rand.h>
-#include <openssl/ts.h>
-#include <openssl/bn.h>
-
-#undef PROG
-#define PROG ts_main
-
-/* Length of the nonce of the request in bits (must be a multiple of 8). */
-#define NONCE_LENGTH 64
-
-/* Macro definitions for the configuration file. */
-#define ENV_OID_FILE "oid_file"
-
-/* Local function declarations. */
-
-static ASN1_OBJECT *txt2obj(const char *oid);
-static CONF *load_config_file(const char *configfile);
-
-/* Query related functions. */
-static int query_command(const char *data, char *digest,
- const EVP_MD *md, const char *policy, int no_nonce,
- int cert, const char *in, const char *out, int text);
-static BIO *BIO_open_with_default(const char *file, const char *mode,
- FILE *default_fp);
-static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
- const char *policy, int no_nonce, int cert);
-static int create_digest(BIO *input, char *digest,
- const EVP_MD *md, unsigned char **md_value);
-static ASN1_INTEGER *create_nonce(int bits);
-
-/* Reply related functions. */
-static int reply_command(CONF *conf, char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
- char *signer, char *chain, const char *policy,
- char *in, int token_in, char *out, int token_out,
- int text);
-static TS_RESP *read_PKCS7(BIO *in_bio);
-static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
- char *signer, char *chain, const char *policy);
-static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
-static ASN1_INTEGER *next_serial(const char *serialfile);
-static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
-
-/* Verify related functions. */
-static int verify_command(char *data, char *digest, char *queryfile,
- char *in, int token_in,
- char *ca_path, char *ca_file, char *untrusted);
-static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
- char *queryfile,
- char *ca_path, char *ca_file,
- char *untrusted);
-static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
-static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx);
-
-/* Main function definition. */
-int MAIN(int, char **);
-
-int MAIN(int argc, char **argv)
- {
- int ret = 1;
- char *configfile = NULL;
- char *section = NULL;
- CONF *conf = NULL;
- enum mode {
- CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
- } mode = CMD_NONE;
- char *data = NULL;
- char *digest = NULL;
- const EVP_MD *md = NULL;
- char *rnd = NULL;
- char *policy = NULL;
- int no_nonce = 0;
- int cert = 0;
- char *in = NULL;
- char *out = NULL;
- int text = 0;
- char *queryfile = NULL;
- char *passin = NULL; /* Password source. */
- char *password =NULL; /* Password itself. */
- char *inkey = NULL;
- char *signer = NULL;
- char *chain = NULL;
- char *ca_path = NULL;
- char *ca_file = NULL;
- char *untrusted = NULL;
- char *engine = NULL;
- /* Input is ContentInfo instead of TimeStampResp. */
- int token_in = 0;
- /* Output is ContentInfo instead of TimeStampResp. */
- int token_out = 0;
- int free_bio_err = 0;
-
- ERR_load_crypto_strings();
- apps_startup();
-
- if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
- {
- free_bio_err = 1;
- BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
- }
-
- for (argc--, argv++; argc > 0; argc--, argv++)
- {
- if (strcmp(*argv, "-config") == 0)
- {
- if (argc-- < 1) goto usage;
- configfile = *++argv;
- }
- else if (strcmp(*argv, "-section") == 0)
- {
- if (argc-- < 1) goto usage;
- section = *++argv;
- }
- else if (strcmp(*argv, "-query") == 0)
- {
- if (mode != CMD_NONE) goto usage;
- mode = CMD_QUERY;
- }
- else if (strcmp(*argv, "-data") == 0)
- {
- if (argc-- < 1) goto usage;
- data = *++argv;
- }
- else if (strcmp(*argv, "-digest") == 0)
- {
- if (argc-- < 1) goto usage;
- digest = *++argv;
- }
- else if (strcmp(*argv, "-rand") == 0)
- {
- if (argc-- < 1) goto usage;
- rnd = *++argv;
- }
- else if (strcmp(*argv, "-policy") == 0)
- {
- if (argc-- < 1) goto usage;
- policy = *++argv;
- }
- else if (strcmp(*argv, "-no_nonce") == 0)
- {
- no_nonce = 1;
- }
- else if (strcmp(*argv, "-cert") == 0)
- {
- cert = 1;
- }
- else if (strcmp(*argv, "-in") == 0)
- {
- if (argc-- < 1) goto usage;
- in = *++argv;
- }
- else if (strcmp(*argv, "-token_in") == 0)
- {
- token_in = 1;
- }
- else if (strcmp(*argv, "-out") == 0)
- {
- if (argc-- < 1) goto usage;
- out = *++argv;
- }
- else if (strcmp(*argv, "-token_out") == 0)
- {
- token_out = 1;
- }
- else if (strcmp(*argv, "-text") == 0)
- {
- text = 1;
- }
- else if (strcmp(*argv, "-reply") == 0)
- {
- if (mode != CMD_NONE) goto usage;
- mode = CMD_REPLY;
- }
- else if (strcmp(*argv, "-queryfile") == 0)
- {
- if (argc-- < 1) goto usage;
- queryfile = *++argv;
- }
- else if (strcmp(*argv, "-passin") == 0)
- {
- if (argc-- < 1) goto usage;
- passin = *++argv;
- }
- else if (strcmp(*argv, "-inkey") == 0)
- {
- if (argc-- < 1) goto usage;
- inkey = *++argv;
- }
- else if (strcmp(*argv, "-signer") == 0)
- {
- if (argc-- < 1) goto usage;
- signer = *++argv;
- }
- else if (strcmp(*argv, "-chain") == 0)
- {
- if (argc-- < 1) goto usage;
- chain = *++argv;
- }
- else if (strcmp(*argv, "-verify") == 0)
- {
- if (mode != CMD_NONE) goto usage;
- mode = CMD_VERIFY;
- }
- else if (strcmp(*argv, "-CApath") == 0)
- {
- if (argc-- < 1) goto usage;
- ca_path = *++argv;
- }
- else if (strcmp(*argv, "-CAfile") == 0)
- {
- if (argc-- < 1) goto usage;
- ca_file = *++argv;
- }
- else if (strcmp(*argv, "-untrusted") == 0)
- {
- if (argc-- < 1) goto usage;
- untrusted = *++argv;
- }
- else if (strcmp(*argv, "-engine") == 0)
- {
- if (argc-- < 1) goto usage;
- engine = *++argv;
- }
- else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
- {
- /* empty. */
- }
- else
- goto usage;
- }
-
- /* Seed the random number generator if it is going to be used. */
- if (mode == CMD_QUERY && !no_nonce)
- {
- if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
- BIO_printf(bio_err, "warning, not much extra random "
- "data, consider using the -rand option\n");
- if (rnd != NULL)
- BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
- app_RAND_load_files(rnd));
- }
-
- /* Get the password if required. */
- if(mode == CMD_REPLY && passin &&
- !app_passwd(bio_err, passin, NULL, &password, NULL))
- {
- BIO_printf(bio_err,"Error getting password.\n");
- goto cleanup;
- }
-
- /* Check consistency of parameters and execute
- the appropriate function. */
- switch (mode)
- {
- case CMD_NONE:
- goto usage;
- case CMD_QUERY:
- /* Data file and message imprint cannot be specified
- at the same time. */
- ret = data != NULL && digest != NULL;
- if (ret) goto usage;
- /* Load the config file for possible policy OIDs. */
- conf = load_config_file(configfile);
- ret = !query_command(data, digest, md, policy, no_nonce, cert,
- in, out, text);
- break;
- case CMD_REPLY:
- conf = load_config_file(configfile);
- if (in == NULL)
- {
- ret = !(queryfile != NULL && conf != NULL && !token_in);
- if (ret) goto usage;
- }
- else
- {
- /* 'in' and 'queryfile' are exclusive. */
- ret = !(queryfile == NULL);
- if (ret) goto usage;
- }
-
- ret = !reply_command(conf, section, engine, queryfile,
- password, inkey, signer, chain, policy,
- in, token_in, out, token_out, text);
- break;
- case CMD_VERIFY:
- ret = !(((queryfile && !data && !digest)
- || (!queryfile && data && !digest)
- || (!queryfile && !data && digest))
- && in != NULL);
- if (ret) goto usage;
-
- ret = !verify_command(data, digest, queryfile, in, token_in,
- ca_path, ca_file, untrusted);
- }
-
- goto cleanup;
-
- usage:
- BIO_printf(bio_err, "usage:\n"
- "ts -query [-rand file%cfile%c...] [-config configfile] "
- "[-data file_to_hash] [-digest digest_bytes]"
- "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
- "[-policy object_id] [-no_nonce] [-cert] "
- "[-in request.tsq] [-out request.tsq] [-text]\n",
- LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
- BIO_printf(bio_err, "or\n"
- "ts -reply [-config configfile] [-section tsa_section] "
- "[-queryfile request.tsq] [-passin password] "
- "[-signer tsa_cert.pem] [-inkey private_key.pem] "
- "[-chain certs_file.pem] [-policy object_id] "
- "[-in response.tsr] [-token_in] "
- "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
- BIO_printf(bio_err, "or\n"
- "ts -verify [-data file_to_hash] [-digest digest_bytes] "
- "[-queryfile request.tsq] "
- "-in response.tsr [-token_in] "
- "-CApath ca_path -CAfile ca_file.pem "
- "-untrusted cert_file.pem\n");
- cleanup:
- /* Clean up. */
- app_RAND_write_file(NULL, bio_err);
- NCONF_free(conf);
- OPENSSL_free(password);
- OBJ_cleanup();
- if (free_bio_err)
- {
- BIO_free_all(bio_err);
- bio_err = NULL;
- }
-
- OPENSSL_EXIT(ret);
- }
-
-/*
- * Configuration file-related function definitions.
- */
-
-static ASN1_OBJECT *txt2obj(const char *oid)
- {
- ASN1_OBJECT *oid_obj = NULL;
-
- if (!(oid_obj = OBJ_txt2obj(oid, 0)))
- BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
-
- return oid_obj;
- }
-
-static CONF *load_config_file(const char *configfile)
- {
- CONF *conf = NULL;
- long errorline = -1;
-
- if (!configfile) configfile = getenv("OPENSSL_CONF");
- if (!configfile) configfile = getenv("SSLEAY_CONF");
-
- if (configfile &&
- (!(conf = NCONF_new(NULL)) ||
- NCONF_load(conf, configfile, &errorline) <= 0))
- {
- if (errorline <= 0)
- BIO_printf(bio_err, "error loading the config file "
- "'%s'\n", configfile);
- else
- BIO_printf(bio_err, "error on line %ld of config file "
- "'%s'\n", errorline, configfile);
- }
-
- if (conf != NULL)
- {
- const char *p;
-
- BIO_printf(bio_err,"Using configuration from %s\n", configfile);
- p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
- if (p != NULL)
- {
- BIO *oid_bio = BIO_new_file(p, "r");
- if (!oid_bio)
- ERR_print_errors(bio_err);
- else
- {
- OBJ_create_objects(oid_bio);
- BIO_free_all(oid_bio);
- }
- }
- else
- ERR_clear_error();
- if(!add_oid_section(bio_err, conf))
- ERR_print_errors(bio_err);
- }
- return conf;
- }
-
-/*
- * Query-related method definitions.
- */
-
-static int query_command(const char *data, char *digest, const EVP_MD *md,
- const char *policy, int no_nonce,
- int cert, const char *in, const char *out, int text)
- {
- int ret = 0;
- TS_REQ *query = NULL;
- BIO *in_bio = NULL;
- BIO *data_bio = NULL;
- BIO *out_bio = NULL;
-
- /* Build query object either from file or from scratch. */
- if (in != NULL)
- {
- if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
- query = d2i_TS_REQ_bio(in_bio, NULL);
- }
- else
- {
- /* Open the file if no explicit digest bytes were specified. */
- if (!digest
- && !(data_bio = BIO_open_with_default(data, "rb", stdin)))
- goto end;
- /* Creating the query object. */
- query = create_query(data_bio, digest, md,
- policy, no_nonce, cert);
- /* Saving the random number generator state. */
- }
- if (query == NULL) goto end;
-
- /* Write query either in ASN.1 or in text format. */
- if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
- goto end;
- if (text)
- {
- /* Text output. */
- if (!TS_REQ_print_bio(out_bio, query))
- goto end;
- }
- else
- {
- /* ASN.1 output. */
- if (!i2d_TS_REQ_bio(out_bio, query))
- goto end;
- }
-
- ret = 1;
-
- end:
- ERR_print_errors(bio_err);
-
- /* Clean up. */
- BIO_free_all(in_bio);
- BIO_free_all(data_bio);
- BIO_free_all(out_bio);
- TS_REQ_free(query);
-
- return ret;
- }
-
-static BIO *BIO_open_with_default(const char *file, const char *mode,
- FILE *default_fp)
- {
- return file == NULL ?
- BIO_new_fp(default_fp, BIO_NOCLOSE)
- : BIO_new_file(file, mode);
- }
-
-static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
- const char *policy, int no_nonce, int cert)
- {
- int ret = 0;
- TS_REQ *ts_req = NULL;
- int len;
- TS_MSG_IMPRINT *msg_imprint = NULL;
- X509_ALGOR *algo = NULL;
- unsigned char *data = NULL;
- ASN1_OBJECT *policy_obj = NULL;
- ASN1_INTEGER *nonce_asn1 = NULL;
-
- /* Setting default message digest. */
- if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err;
-
- /* Creating request object. */
- if (!(ts_req = TS_REQ_new())) goto err;
-
- /* Setting version. */
- if (!TS_REQ_set_version(ts_req, 1)) goto err;
-
- /* Creating and adding MSG_IMPRINT object. */
- if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err;
-
- /* Adding algorithm. */
- if (!(algo = X509_ALGOR_new())) goto err;
- if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err;
- if (!(algo->parameter = ASN1_TYPE_new())) goto err;
- algo->parameter->type = V_ASN1_NULL;
- if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err;
-
- /* Adding message digest. */
- if ((len = create_digest(data_bio, digest, md, &data)) == 0)
- goto err;
- if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err;
-
- if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;
-
- /* Setting policy if requested. */
- if (policy && !(policy_obj = txt2obj(policy))) goto err;
- if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;
-
- /* Setting nonce if requested. */
- if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err;
- if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err;
-
- /* Setting certificate request flag if requested. */
- if (!TS_REQ_set_cert_req(ts_req, cert)) goto err;
-
- ret = 1;
- err:
- if (!ret)
- {
- TS_REQ_free(ts_req);
- ts_req = NULL;
- BIO_printf(bio_err, "could not create query\n");
- }
- TS_MSG_IMPRINT_free(msg_imprint);
- X509_ALGOR_free(algo);
- OPENSSL_free(data);
- ASN1_OBJECT_free(policy_obj);
- ASN1_INTEGER_free(nonce_asn1);
- return ts_req;
- }
-
-static int create_digest(BIO *input, char *digest, const EVP_MD *md,
- unsigned char **md_value)
- {
- int md_value_len;
-
- md_value_len = EVP_MD_size(md);
- if (md_value_len < 0)
- goto err;
- if (input)
- {
- /* Digest must be computed from an input file. */
- EVP_MD_CTX md_ctx;
- unsigned char buffer[4096];
- int length;
-
- *md_value = OPENSSL_malloc(md_value_len);
- if (*md_value == 0) goto err;
-
- EVP_DigestInit(&md_ctx, md);
- while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0)
- {
- EVP_DigestUpdate(&md_ctx, buffer, length);
- }
- EVP_DigestFinal(&md_ctx, *md_value, NULL);
- }
- else
- {
- /* Digest bytes are specified with digest. */
- long digest_len;
- *md_value = string_to_hex(digest, &digest_len);
- if (!*md_value || md_value_len != digest_len)
- {
- OPENSSL_free(*md_value);
- *md_value = NULL;
- BIO_printf(bio_err, "bad digest, %d bytes "
- "must be specified\n", md_value_len);
- goto err;
- }
- }
-
- return md_value_len;
- err:
- return 0;
- }
-
-static ASN1_INTEGER *create_nonce(int bits)
- {
- unsigned char buf[20];
- ASN1_INTEGER *nonce = NULL;
- int len = (bits - 1) / 8 + 1;
- int i;
-
- /* Generating random byte sequence. */
- if (len > (int)sizeof(buf)) goto err;
- if (!RAND_bytes(buf, len)) goto err;
-
- /* Find the first non-zero byte and creating ASN1_INTEGER object. */
- for (i = 0; i < len && !buf[i]; ++i);
- if (!(nonce = ASN1_INTEGER_new())) goto err;
- OPENSSL_free(nonce->data);
- /* Allocate at least one byte. */
- nonce->length = len - i;
- if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err;
- memcpy(nonce->data, buf + i, nonce->length);
-
- return nonce;
- err:
- BIO_printf(bio_err, "could not create nonce\n");
- ASN1_INTEGER_free(nonce);
- return NULL;
- }
-/*
- * Reply-related method definitions.
- */
-
-static int reply_command(CONF *conf, char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
- char *signer, char *chain, const char *policy,
- char *in, int token_in,
- char *out, int token_out, int text)
- {
- int ret = 0;
- TS_RESP *response = NULL;
- BIO *in_bio = NULL;
- BIO *query_bio = NULL;
- BIO *inkey_bio = NULL;
- BIO *signer_bio = NULL;
- BIO *out_bio = NULL;
-
- /* Build response object either from response or query. */
- if (in != NULL)
- {
- if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
- if (token_in)
- {
- /* We have a ContentInfo (PKCS7) object, add
- 'granted' status info around it. */
- response = read_PKCS7(in_bio);
- }
- else
- {
- /* We have a ready-made TS_RESP object. */
- response = d2i_TS_RESP_bio(in_bio, NULL);
- }
- }
- else
- {
- response = create_response(conf, section, engine, queryfile,
- passin, inkey, signer, chain,
- policy);
- if (response)
- BIO_printf(bio_err, "Response has been generated.\n");
- else
- BIO_printf(bio_err, "Response is not generated.\n");
- }
- if (response == NULL) goto end;
-
- /* Write response either in ASN.1 or text format. */
- if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
- goto end;
- if (text)
- {
- /* Text output. */
- if (token_out)
- {
- TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
- if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end;
- }
- else
- {
- if (!TS_RESP_print_bio(out_bio, response)) goto end;
- }
- }
- else
- {
- /* ASN.1 DER output. */
- if (token_out)
- {
- PKCS7 *token = TS_RESP_get_token(response);
- if (!i2d_PKCS7_bio(out_bio, token)) goto end;
- }
- else
- {
- if (!i2d_TS_RESP_bio(out_bio, response)) goto end;
- }
- }
-
- ret = 1;
-
- end:
- ERR_print_errors(bio_err);
-
- /* Clean up. */
- BIO_free_all(in_bio);
- BIO_free_all(query_bio);
- BIO_free_all(inkey_bio);
- BIO_free_all(signer_bio);
- BIO_free_all(out_bio);
- TS_RESP_free(response);
-
- return ret;
- }
-
-/* Reads a PKCS7 token and adds default 'granted' status info to it. */
-static TS_RESP *read_PKCS7(BIO *in_bio)
- {
- int ret = 0;
- PKCS7 *token = NULL;
- TS_TST_INFO *tst_info = NULL;
- TS_RESP *resp = NULL;
- TS_STATUS_INFO *si = NULL;
-
- /* Read PKCS7 object and extract the signed time stamp info. */
- if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
- if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end;
-
- /* Creating response object. */
- if (!(resp = TS_RESP_new())) goto end;
-
- /* Create granted status info. */
- if (!(si = TS_STATUS_INFO_new())) goto end;
- if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end;
- if (!TS_RESP_set_status_info(resp, si)) goto end;
-
- /* Setting encapsulated token. */
- TS_RESP_set_tst_info(resp, token, tst_info);
- token = NULL; /* Ownership is lost. */
- tst_info = NULL; /* Ownership is lost. */
-
- ret = 1;
- end:
- PKCS7_free(token);
- TS_TST_INFO_free(tst_info);
- if (!ret)
- {
- TS_RESP_free(resp);
- resp = NULL;
- }
- TS_STATUS_INFO_free(si);
- return resp;
- }
-
-static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
- char *signer, char *chain, const char *policy)
- {
- int ret = 0;
- TS_RESP *response = NULL;
- BIO *query_bio = NULL;
- TS_RESP_CTX *resp_ctx = NULL;
-
- if (!(query_bio = BIO_new_file(queryfile, "rb")))
- goto end;
-
- /* Getting TSA configuration section. */
- if (!(section = TS_CONF_get_tsa_section(conf, section)))
- goto end;
-
- /* Setting up response generation context. */
- if (!(resp_ctx = TS_RESP_CTX_new())) goto end;
-
- /* Setting serial number provider callback. */
- if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end;
-#ifndef OPENSSL_NO_ENGINE
- /* Setting default OpenSSL engine. */
- if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end;
-#endif
-
- /* Setting TSA signer certificate. */
- if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end;
-
- /* Setting TSA signer certificate chain. */
- if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;
-
- /* Setting TSA signer private key. */
- if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
- goto end;
-
- /* Setting default policy OID. */
- if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
-
- /* Setting acceptable policy OIDs. */
- if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end;
-
- /* Setting the acceptable one-way hash algorithms. */
- if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end;
-
- /* Setting guaranteed time stamp accuracy. */
- if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end;
-
- /* Setting the precision of the time. */
- if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
- goto end;
-
- /* Setting the ordering flaf if requested. */
- if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end;
-
- /* Setting the TSA name required flag if requested. */
- if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end;
-
- /* Setting the ESS cert id chain flag if requested. */
- if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end;
-
- /* Creating the response. */
- if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
- goto end;
-
- ret = 1;
- end:
- if (!ret)
- {
- TS_RESP_free(response);
- response = NULL;
- }
- TS_RESP_CTX_free(resp_ctx);
- BIO_free_all(query_bio);
-
- return response;
- }
-
-static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data)
- {
- const char *serial_file = (const char *) data;
- ASN1_INTEGER *serial = next_serial(serial_file);
-
- if (!serial)
- {
- TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
- "Error during serial number "
- "generation.");
- TS_RESP_CTX_add_failure_info(ctx,
- TS_INFO_ADD_INFO_NOT_AVAILABLE);
- }
- else
- save_ts_serial(serial_file, serial);
-
- return serial;
- }
-
-static ASN1_INTEGER *next_serial(const char *serialfile)
- {
- int ret = 0;
- BIO *in = NULL;
- ASN1_INTEGER *serial = NULL;
- BIGNUM *bn = NULL;
-
- if (!(serial = ASN1_INTEGER_new())) goto err;
-
- if (!(in = BIO_new_file(serialfile, "r")))
- {
- ERR_clear_error();
- BIO_printf(bio_err, "Warning: could not open file %s for "
- "reading, using serial number: 1\n", serialfile);
- if (!ASN1_INTEGER_set(serial, 1)) goto err;
- }
- else
- {
- char buf[1024];
- if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf)))
- {
- BIO_printf(bio_err, "unable to load number from %s\n",
- serialfile);
- goto err;
- }
- if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err;
- ASN1_INTEGER_free(serial);
- serial = NULL;
- if (!BN_add_word(bn, 1)) goto err;
- if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err;
- }
- ret = 1;
- err:
- if (!ret)
- {
- ASN1_INTEGER_free(serial);
- serial = NULL;
- }
- BIO_free_all(in);
- BN_free(bn);
- return serial;
- }
-
-static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
- {
- int ret = 0;
- BIO *out = NULL;
-
- if (!(out = BIO_new_file(serialfile, "w"))) goto err;
- if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err;
- if (BIO_puts(out, "\n") <= 0) goto err;
- ret = 1;
- err:
- if (!ret)
- BIO_printf(bio_err, "could not save serial number to %s\n",
- serialfile);
- BIO_free_all(out);
- return ret;
- }
-
-/*
- * Verify-related method definitions.
- */
-
-static int verify_command(char *data, char *digest, char *queryfile,
- char *in, int token_in,
- char *ca_path, char *ca_file, char *untrusted)
- {
- BIO *in_bio = NULL;
- PKCS7 *token = NULL;
- TS_RESP *response = NULL;
- TS_VERIFY_CTX *verify_ctx = NULL;
- int ret = 0;
-
- /* Decode the token (PKCS7) or response (TS_RESP) files. */
- if (!(in_bio = BIO_new_file(in, "rb"))) goto end;
- if (token_in)
- {
- if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
- }
- else
- {
- if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end;
- }
-
- if (!(verify_ctx = create_verify_ctx(data, digest, queryfile,
- ca_path, ca_file, untrusted)))
- goto end;
-
- /* Checking the token or response against the request. */
- ret = token_in ?
- TS_RESP_verify_token(verify_ctx, token) :
- TS_RESP_verify_response(verify_ctx, response);
-
- end:
- printf("Verification: ");
- if (ret)
- printf("OK\n");
- else
- {
- printf("FAILED\n");
- /* Print errors, if there are any. */
- ERR_print_errors(bio_err);
- }
-
- /* Clean up. */
- BIO_free_all(in_bio);
- PKCS7_free(token);
- TS_RESP_free(response);
- TS_VERIFY_CTX_free(verify_ctx);
- return ret;
- }
-
-static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
- char *queryfile,
- char *ca_path, char *ca_file,
- char *untrusted)
- {
- TS_VERIFY_CTX *ctx = NULL;
- BIO *input = NULL;
- TS_REQ *request = NULL;
- int ret = 0;
-
- if (data != NULL || digest != NULL)
- {
- if (!(ctx = TS_VERIFY_CTX_new())) goto err;
- ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
- if (data != NULL)
- {
- ctx->flags |= TS_VFY_DATA;
- if (!(ctx->data = BIO_new_file(data, "rb"))) goto err;
- }
- else if (digest != NULL)
- {
- long imprint_len;
- ctx->flags |= TS_VFY_IMPRINT;
- if (!(ctx->imprint = string_to_hex(digest,
- &imprint_len)))
- {
- BIO_printf(bio_err, "invalid digest string\n");
- goto err;
- }
- ctx->imprint_len = imprint_len;
- }
-
- }
- else if (queryfile != NULL)
- {
- /* The request has just to be read, decoded and converted to
- a verify context object. */
- if (!(input = BIO_new_file(queryfile, "rb"))) goto err;
- if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err;
- if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err;
- }
- else
- return NULL;
-
- /* Add the signature verification flag and arguments. */
- ctx->flags |= TS_VFY_SIGNATURE;
-
- /* Initialising the X509_STORE object. */
- if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err;
-
- /* Loading untrusted certificates. */
- if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
- goto err;
-
- ret = 1;
- err:
- if (!ret)
- {
- TS_VERIFY_CTX_free(ctx);
- ctx = NULL;
- }
- BIO_free_all(input);
- TS_REQ_free(request);
- return ctx;
- }
-
-static X509_STORE *create_cert_store(char *ca_path, char *ca_file)
- {
- X509_STORE *cert_ctx = NULL;
- X509_LOOKUP *lookup = NULL;
- int i;
-
- /* Creating the X509_STORE object. */
- cert_ctx = X509_STORE_new();
-
- /* Setting the callback for certificate chain verification. */
- X509_STORE_set_verify_cb_func(cert_ctx, verify_cb);
-
- /* Adding a trusted certificate directory source. */
- if (ca_path)
- {
- lookup = X509_STORE_add_lookup(cert_ctx,
- X509_LOOKUP_hash_dir());
- if (lookup == NULL)
- {
- BIO_printf(bio_err, "memory allocation failure\n");
- goto err;
- }
- i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
- if (!i)
- {
- BIO_printf(bio_err, "Error loading directory %s\n",
- ca_path);
- goto err;
- }
- }
-
- /* Adding a trusted certificate file source. */
- if (ca_file)
- {
- lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
- if (lookup == NULL)
- {
- BIO_printf(bio_err, "memory allocation failure\n");
- goto err;
- }
- i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
- if (!i)
- {
- BIO_printf(bio_err, "Error loading file %s\n", ca_file);
- goto err;
- }
- }
-
- return cert_ctx;
- err:
- X509_STORE_free(cert_ctx);
- return NULL;
- }
-
-static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx)
- {
- /*
- char buf[256];
-
- if (!ok)
- {
- X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
- buf, sizeof(buf));
- printf("%s\n", buf);
- printf("error %d at %d depth lookup: %s\n",
- ctx->error, ctx->error_depth,
- X509_verify_cert_error_string(ctx->error));
- }
- */
-
- return ok;
- }
diff --git a/crypto/openssl/apps/tsget b/crypto/openssl/apps/tsget
deleted file mode 100644
index ddae803..0000000
--- a/crypto/openssl/apps/tsget
+++ /dev/null
@@ -1,195 +0,0 @@
-#!/usr/bin/perl -w
-# Written by Zoltan Glozik <zglozik@stones.com>.
-# Copyright (c) 2002 The OpenTSA Project. All rights reserved.
-$::version = '$Id: tsget,v 1.1 2006/02/12 23:11:21 ulf Exp $';
-
-use strict;
-use IO::Handle;
-use Getopt::Std;
-use File::Basename;
-use WWW::Curl::easy;
-
-use vars qw(%options);
-
-# Callback for reading the body.
-sub read_body {
- my ($maxlength, $state) = @_;
- my $return_data = "";
- my $data_len = length ${$state->{data}};
- if ($state->{bytes} < $data_len) {
- $data_len = $data_len - $state->{bytes};
- $data_len = $maxlength if $data_len > $maxlength;
- $return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
- $state->{bytes} += $data_len;
- }
- return $return_data;
-}
-
-# Callback for writing the body into a variable.
-sub write_body {
- my ($data, $pointer) = @_;
- ${$pointer} .= $data;
- return length($data);
-}
-
-# Initialise a new Curl object.
-sub create_curl {
- my $url = shift;
-
- # Create Curl object.
- my $curl = WWW::Curl::easy::new();
-
- # Error-handling related options.
- $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
- $curl->setopt(CURLOPT_FAILONERROR, 1);
- $curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/" . (split / /, $::version)[2]);
-
- # Options for POST method.
- $curl->setopt(CURLOPT_UPLOAD, 1);
- $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
- $curl->setopt(CURLOPT_HTTPHEADER,
- ["Content-Type: application/timestamp-query",
- "Accept: application/timestamp-reply"]);
- $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
- $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
-
- # Options for getting the result.
- $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
-
- # SSL related options.
- $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
- $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1); # Verify server's certificate.
- $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2); # Check server's CN.
- $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
- $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
- $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
- $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
- $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
- $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
- $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
-
- # Setting destination.
- $curl->setopt(CURLOPT_URL, $url);
-
- return $curl;
-}
-
-# Send a request and returns the body back.
-sub get_timestamp {
- my $curl = shift;
- my $body = shift;
- my $ts_body;
- local $::error_buf;
-
- # Error-handling related options.
- $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
-
- # Options for POST method.
- $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
- $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
-
- # Options for getting the result.
- $curl->setopt(CURLOPT_FILE, \$ts_body);
-
- # Send the request...
- my $error_code = $curl->perform();
- my $error_string;
- if ($error_code != 0) {
- my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
- $error_string = "could not get timestamp";
- $error_string .= ", http code: $http_code" unless $http_code == 0;
- $error_string .= ", curl code: $error_code";
- $error_string .= " ($::error_buf)" if defined($::error_buf);
- } else {
- my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
- if (lc($ct) ne "application/timestamp-reply") {
- $error_string = "unexpected content type returned: $ct";
- }
- }
- return ($ts_body, $error_string);
-
-}
-
-# Print usage information and exists.
-sub usage {
-
- print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
- print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
- print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
- print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
- exit 1;
-}
-
-# ----------------------------------------------------------------------
-# Main program
-# ----------------------------------------------------------------------
-
-# Getting command-line options (default comes from TSGET environment variable).
-my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:";
-if (exists $ENV{TSGET}) {
- my @old_argv = @ARGV;
- @ARGV = split /\s+/, $ENV{TSGET};
- getopts($getopt_arg, \%options) or usage;
- @ARGV = @old_argv;
-}
-getopts($getopt_arg, \%options) or usage;
-
-# Checking argument consistency.
-if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
- || (@ARGV > 1 && exists($options{o}))) {
- print STDERR "Inconsistent command line options.\n";
- usage;
-}
-# Setting defaults.
-@ARGV = ("-") unless @ARGV != 0;
-$options{e} = ".tsr" unless defined($options{e});
-
-# Processing requests.
-my $curl = create_curl $options{h};
-undef $/; # For reading whole files.
-REQUEST: foreach (@ARGV) {
- my $input = $_;
- my ($base, $path) = fileparse($input, '\.[^.]*');
- my $output_base = $base . $options{e};
- my $output = defined($options{o}) ? $options{o} : $path . $output_base;
-
- STDERR->printflush("$input: ") if $options{v};
- # Read request.
- my $body;
- if ($input eq "-") {
- # Read the request from STDIN;
- $body = <STDIN>;
- } else {
- # Read the request from file.
- open INPUT, "<" . $input
- or warn("$input: could not open input file: $!\n"), next REQUEST;
- $body = <INPUT>;
- close INPUT
- or warn("$input: could not close input file: $!\n"), next REQUEST;
- }
-
- # Send request.
- STDERR->printflush("sending request") if $options{v};
-
- my ($ts_body, $error) = get_timestamp $curl, \$body;
- if (defined($error)) {
- die "$input: fatal error: $error\n";
- }
- STDERR->printflush(", reply received") if $options{v};
-
- # Write response.
- if ($output eq "-") {
- # Write to STDOUT.
- print $ts_body;
- } else {
- # Write to file.
- open OUTPUT, ">", $output
- or warn("$output: could not open output file: $!\n"), next REQUEST;
- print OUTPUT $ts_body;
- close OUTPUT
- or warn("$output: could not close output file: $!\n"), next REQUEST;
- }
- STDERR->printflush(", $output written.\n") if $options{v};
-}
-$curl->cleanup();
-WWW::Curl::easy::global_cleanup();
diff --git a/crypto/openssl/apps/x509.c b/crypto/openssl/apps/x509.c
index 6debce4..b25508a 100644
--- a/crypto/openssl/apps/x509.c
+++ b/crypto/openssl/apps/x509.c
@@ -1151,6 +1151,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
/* NOTE: this certificate can/should be self signed, unless it was
* a certificate request in which case it is not. */
X509_STORE_CTX_set_cert(&xsc,x);
+ X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
if (!reqfile && X509_verify_cert(&xsc) <= 0)
goto end;
diff --git a/crypto/openssl/config b/crypto/openssl/config
index 68e7ea1..b9d1c7a 100755
--- a/crypto/openssl/config
+++ b/crypto/openssl/config
@@ -48,10 +48,10 @@ done
# First get uname entries that we use below
-MACHINE=`(uname -m) 2>/dev/null` || MACHINE="unknown"
-RELEASE=`(uname -r) 2>/dev/null` || RELEASE="unknown"
-SYSTEM=`(uname -s) 2>/dev/null` || SYSTEM="unknown"
-VERSION=`(uname -v) 2>/dev/null` || VERSION="unknown"
+[ "$MACHINE" ] || MACHINE=`(uname -m) 2>/dev/null` || MACHINE="unknown"
+[ "$RELEASE" ] || RELEASE=`(uname -r) 2>/dev/null` || RELEASE="unknown"
+[ "$SYSTEM" ] || SYSTEM=`(uname -s) 2>/dev/null` || SYSTEM="unknown"
+[ "$BUILD" ] || VERSION=`(uname -v) 2>/dev/null` || VERSION="unknown"
# Now test for ISC and SCO, since it is has a braindamaged uname.
@@ -741,6 +741,10 @@ case "$GUESSOS" in
OBJECT_MODE=${OBJECT_MODE:-32}
if [ "$CC" = "gcc" ]; then
OUT="aix-gcc"
+ if [ $OBJECT_MODE -eq 64 ]; then
+ echo 'Your $OBJECT_MODE was found to be set to 64'
+ OUT="aix64-gcc"
+ fi
elif [ $OBJECT_MODE -eq 64 ]; then
echo 'Your $OBJECT_MODE was found to be set to 64'
OUT="aix64-cc"
@@ -769,6 +773,8 @@ case "$GUESSOS" in
t3e-cray-unicosmk) OUT="cray-t3e" ;;
j90-cray-unicos) OUT="cray-j90" ;;
nsr-tandem-nsk) OUT="tandem-c89" ;;
+ x86pc-*-qnx6) OUT="QNX6-i386" ;;
+ *-*-qnx6) OUT="QNX6" ;;
*) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
esac
diff --git a/crypto/openssl/crypto/aes/aes_cfb.c b/crypto/openssl/crypto/aes/aes_cfb.c
index 49f0411..9384ba6 100644
--- a/crypto/openssl/crypto/aes/aes_cfb.c
+++ b/crypto/openssl/crypto/aes/aes_cfb.c
@@ -201,7 +201,6 @@ void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
assert(in && out && key && ivec && num);
assert(*num == 0);
- memset(out,0,(length+7)/8);
for(n=0 ; n < length ; ++n)
{
c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
diff --git a/crypto/openssl/crypto/aes/aes_x86core.c b/crypto/openssl/crypto/aes/aes_x86core.c
deleted file mode 100644
index d323e26..0000000
--- a/crypto/openssl/crypto/aes/aes_x86core.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
-/**
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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 is experimental x86[_64] derivative. It assumes little-endian
- * byte order and expects CPU to sustain unaligned memory references.
- * It is used as playground for cache-time attack mitigations and
- * serves as reference C implementation for x86[_64] assembler.
- *
- * <appro@fy.chalmers.se>
- */
-
-
-#ifndef AES_DEBUG
-# ifndef NDEBUG
-# define NDEBUG
-# endif
-#endif
-#include <assert.h>
-
-#include <stdlib.h>
-#include <openssl/aes.h>
-#include "aes_locl.h"
-
-/*
- * These two parameters control which table, 256-byte or 2KB, is
- * referenced in outer and respectively inner rounds.
- */
-#define AES_COMPACT_IN_OUTER_ROUNDS
-#ifdef AES_COMPACT_IN_OUTER_ROUNDS
-/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
- * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
- * by factor of ~2. */
-# undef AES_COMPACT_IN_INNER_ROUNDS
-#endif
-
-#if 1
-static void prefetch256(const void *table)
-{
- volatile unsigned long *t=(void *)table,ret;
- unsigned long sum;
- int i;
-
- /* 32 is common least cache-line size */
- for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0])) sum ^= t[i];
-
- ret = sum;
-}
-#else
-# define prefetch256(t)
-#endif
-
-#undef GETU32
-#define GETU32(p) (*((u32*)(p)))
-
-#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-typedef unsigned __int64 u64;
-#define U64(C) C##UI64
-#elif defined(__arch64__)
-typedef unsigned long u64;
-#define U64(C) C##UL
-#else
-typedef unsigned long long u64;
-#define U64(C) C##ULL
-#endif
-
-#undef ROTATE
-#if defined(_MSC_VER) || defined(__ICC)
-# define ROTATE(a,n) _lrotl(a,n)
-#elif defined(__GNUC__) && __GNUC__>=2
-# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-# define ROTATE(a,n) ({ register unsigned int ret; \
- asm ( \
- "roll %1,%0" \
- : "=r"(ret) \
- : "I"(n), "0"(a) \
- : "cc"); \
- ret; \
- })
-# endif
-#endif
-/*
-Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-*/
-#define Te0 (u32)((u64*)((u8*)Te+0))
-#define Te1 (u32)((u64*)((u8*)Te+3))
-#define Te2 (u32)((u64*)((u8*)Te+2))
-#define Te3 (u32)((u64*)((u8*)Te+1))
-/*
-Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01];
-*/
-#define Td0 (u32)((u64*)((u8*)Td+0))
-#define Td1 (u32)((u64*)((u8*)Td+3))
-#define Td2 (u32)((u64*)((u8*)Td+2))
-#define Td3 (u32)((u64*)((u8*)Td+1))
-
-static const u64 Te[256] = {
- U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
- U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
- U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
- U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
- U64(0x5030306050303060), U64(0x0301010203010102),
- U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
- U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
- U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
- U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
- U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
- U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
- U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
- U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
- U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
- U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
- U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
- U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
- U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
- U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
- U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
- U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
- U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
- U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
- U64(0x5331316253313162), U64(0x3f15152a3f15152a),
- U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
- U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
- U64(0x2818183028181830), U64(0xa1969637a1969637),
- U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
- U64(0x0907070e0907070e), U64(0x3612122436121224),
- U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
- U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
- U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
- U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
- U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
- U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
- U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
- U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
- U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
- U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
- U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
- U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
- U64(0x0000000000000000), U64(0x2cededc12cededc1),
- U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
- U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
- U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
- U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
- U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
- U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
- U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
- U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
- U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
- U64(0x5533336655333366), U64(0x9485851194858511),
- U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
- U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
- U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
- U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
- U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
- U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
- U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
- U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
- U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
- U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
- U64(0x3010102030101020), U64(0x1affffe51affffe5),
- U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
- U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
- U64(0x3513132635131326), U64(0x2fececc32fececc3),
- U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
- U64(0xcc444488cc444488), U64(0x3917172e3917172e),
- U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
- U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
- U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
- U64(0x2b1919322b191932), U64(0x957373e6957373e6),
- U64(0xa06060c0a06060c0), U64(0x9881811998818119),
- U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
- U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
- U64(0xab90903bab90903b), U64(0x8388880b8388880b),
- U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
- U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
- U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
- U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
- U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
- U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
- U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
- U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
- U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
- U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
- U64(0xa8919139a8919139), U64(0xa4959531a4959531),
- U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
- U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
- U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
- U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
- U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
- U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
- U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
- U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
- U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
- U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
- U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
- U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
- U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
- U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
- U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
- U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
- U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
- U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
- U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
- U64(0xd8484890d8484890), U64(0x0503030605030306),
- U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
- U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
- U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
- U64(0x9186861791868617), U64(0x58c1c19958c1c199),
- U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
- U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
- U64(0xb398982bb398982b), U64(0x3311112233111122),
- U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
- U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
- U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
- U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
- U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
- U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
- U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
- U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
- U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
- U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
- U64(0xc3414182c3414182), U64(0xb0999929b0999929),
- U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
- U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
- U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
-};
-
-static const u8 Te4[256] = {
- 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
- 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
- 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
- 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
- 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
- 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
- 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
- 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
- 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
- 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
- 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
- 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
- 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
- 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
- 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
- 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
- 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
- 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
- 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
- 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
- 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
- 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
- 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
- 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
- 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
- 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
- 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
- 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
- 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
- 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
- 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
- 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
-};
-
-static const u64 Td[256] = {
- U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
- U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
- U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
- U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
- U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
- U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
- U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
- U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
- U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
- U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
- U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
- U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
- U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
- U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
- U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
- U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
- U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
- U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
- U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
- U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
- U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
- U64(0x6033519760335197), U64(0x457f5362457f5362),
- U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
- U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
- U64(0x5868487058684870), U64(0x19fd458f19fd458f),
- U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
- U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
- U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
- U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
- U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
- U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
- U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
- U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
- U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
- U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
- U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
- U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
- U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
- U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
- U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
- U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
- U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
- U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
- U64(0x6fd406046fd40604), U64(0xff155060ff155060),
- U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
- U64(0xcc434089cc434089), U64(0x779ed967779ed967),
- U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
- U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
- U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
- U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
- U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
- U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
- U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
- U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
- U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
- U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
- U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
- U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
- U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
- U64(0x694b775a694b775a), U64(0x161a121c161a121c),
- U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
- U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
- U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
- U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
- U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
- U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
- U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
- U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
- U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
- U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
- U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
- U64(0x4022971340229713), U64(0x2011c6842011c684),
- U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
- U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
- U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
- U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
- U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
- U64(0xfa489411fa489411), U64(0x2264e9472264e947),
- U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
- U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
- U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
- U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
- U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
- U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
- U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
- U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
- U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
- U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
- U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
- U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
- U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
- U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
- U64(0x097826cd097826cd), U64(0xf418596ef418596e),
- U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
- U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
- U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
- U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
- U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
- U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
- U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
- U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
- U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
- U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
- U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
- U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
- U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
- U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
- U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
- U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
- U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
- U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
- U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
- U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
- U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
- U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
- U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
- U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
- U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
- U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
- U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
- U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
- U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
- U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
- U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
- U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
- U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
- U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
- U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
-};
-static const u8 Td4[256] = {
- 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
- 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
- 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
- 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
- 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
- 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
- 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
- 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
- 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
- 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
- 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
- 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
- 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
- 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
- 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
- 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
- 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
- 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
- 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
- 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
- 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
- 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
- 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
- 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
- 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
- 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
- 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
- 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
- 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
- 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
- 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
- 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
-};
-
-static const u32 rcon[] = {
- 0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U,
- 0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U,
- 0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-/**
- * Expand the cipher key into the encryption key schedule.
- */
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i = 0;
- u32 temp;
-
- if (!userKey || !key)
- return -1;
- if (bits != 128 && bits != 192 && bits != 256)
- return -2;
-
- rk = key->rd_key;
-
- if (bits==128)
- key->rounds = 10;
- else if (bits==192)
- key->rounds = 12;
- else
- key->rounds = 14;
-
- rk[0] = GETU32(userKey );
- rk[1] = GETU32(userKey + 4);
- rk[2] = GETU32(userKey + 8);
- rk[3] = GETU32(userKey + 12);
- if (bits == 128) {
- while (1) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (Te4[(temp >> 8) & 0xff] ) ^
- (Te4[(temp >> 16) & 0xff] << 8) ^
- (Te4[(temp >> 24) ] << 16) ^
- (Te4[(temp ) & 0xff] << 24) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 0;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(userKey + 16);
- rk[5] = GETU32(userKey + 20);
- if (bits == 192) {
- while (1) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (Te4[(temp >> 8) & 0xff] ) ^
- (Te4[(temp >> 16) & 0xff] << 8) ^
- (Te4[(temp >> 24) ] << 16) ^
- (Te4[(temp ) & 0xff] << 24) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 0;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(userKey + 24);
- rk[7] = GETU32(userKey + 28);
- if (bits == 256) {
- while (1) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (Te4[(temp >> 8) & 0xff] ) ^
- (Te4[(temp >> 16) & 0xff] << 8) ^
- (Te4[(temp >> 24) ] << 16) ^
- (Te4[(temp ) & 0xff] << 24) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 0;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (Te4[(temp ) & 0xff] ) ^
- (Te4[(temp >> 8) & 0xff] << 8) ^
- (Te4[(temp >> 16) & 0xff] << 16) ^
- (Te4[(temp >> 24) ] << 24);
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
-
- rk += 8;
- }
- }
- return 0;
-}
-
-/**
- * Expand the cipher key into the decryption key schedule.
- */
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i, j, status;
- u32 temp;
-
- /* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
- if (status < 0)
- return status;
-
- rk = key->rd_key;
-
- /* invert the order of the round keys: */
- for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */
- for (i = 1; i < (key->rounds); i++) {
- rk += 4;
-#if 1
- for (j = 0; j < 4; j++) {
- u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-
- tp1 = rk[j];
- m = tp1 & 0x80808080;
- tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- m = tp2 & 0x80808080;
- tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- m = tp4 & 0x80808080;
- tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- tp9 = tp8 ^ tp1;
- tpb = tp9 ^ tp2;
- tpd = tp9 ^ tp4;
- tpe = tp8 ^ tp4 ^ tp2;
-#if defined(ROTATE)
- rk[j] = tpe ^ ROTATE(tpd,16) ^
- ROTATE(tp9,8) ^ ROTATE(tpb,24);
-#else
- rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
- (tp9 >> 24) ^ (tp9 << 8) ^
- (tpb >> 8) ^ (tpb << 24);
-#endif
- }
-#else
- rk[0] =
- Td0[Te2[(rk[0] ) & 0xff] & 0xff] ^
- Td1[Te2[(rk[0] >> 8) & 0xff] & 0xff] ^
- Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^
- Td3[Te2[(rk[0] >> 24) ] & 0xff];
- rk[1] =
- Td0[Te2[(rk[1] ) & 0xff] & 0xff] ^
- Td1[Te2[(rk[1] >> 8) & 0xff] & 0xff] ^
- Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^
- Td3[Te2[(rk[1] >> 24) ] & 0xff];
- rk[2] =
- Td0[Te2[(rk[2] ) & 0xff] & 0xff] ^
- Td1[Te2[(rk[2] >> 8) & 0xff] & 0xff] ^
- Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^
- Td3[Te2[(rk[2] >> 24) ] & 0xff];
- rk[3] =
- Td0[Te2[(rk[3] ) & 0xff] & 0xff] ^
- Td1[Te2[(rk[3] >> 8) & 0xff] & 0xff] ^
- Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^
- Td3[Te2[(rk[3] >> 24) ] & 0xff];
-#endif
- }
- return 0;
-}
-
-/*
- * Encrypt a single block
- * in and out can overlap
- */
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t[4];
- int r;
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-
-#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
- prefetch256(Te4);
-
- t[0] = Te4[(s0 ) & 0xff] ^
- Te4[(s1 >> 8) & 0xff] << 8 ^
- Te4[(s2 >> 16) & 0xff] << 16 ^
- Te4[(s3 >> 24) ] << 24;
- t[1] = Te4[(s1 ) & 0xff] ^
- Te4[(s2 >> 8) & 0xff] << 8 ^
- Te4[(s3 >> 16) & 0xff] << 16 ^
- Te4[(s0 >> 24) ] << 24;
- t[2] = Te4[(s2 ) & 0xff] ^
- Te4[(s3 >> 8) & 0xff] << 8 ^
- Te4[(s0 >> 16) & 0xff] << 16 ^
- Te4[(s1 >> 24) ] << 24;
- t[3] = Te4[(s3 ) & 0xff] ^
- Te4[(s0 >> 8) & 0xff] << 8 ^
- Te4[(s1 >> 16) & 0xff] << 16 ^
- Te4[(s2 >> 24) ] << 24;
-
- /* now do the linear transform using words */
- { int i;
- u32 r0, r1, r2;
-
- for (i = 0; i < 4; i++) {
- r0 = t[i];
- r1 = r0 & 0x80808080;
- r2 = ((r0 & 0x7f7f7f7f) << 1) ^
- ((r1 - (r1 >> 7)) & 0x1b1b1b1b);
-#if defined(ROTATE)
- t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
- ROTATE(r0,16) ^ ROTATE(r0,8);
-#else
- t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
- (r0 << 16) ^ (r0 >> 16) ^
- (r0 << 8) ^ (r0 >> 24);
-#endif
- t[i] ^= rk[4+i];
- }
- }
-#else
- t[0] = Te0[(s0 ) & 0xff] ^
- Te1[(s1 >> 8) & 0xff] ^
- Te2[(s2 >> 16) & 0xff] ^
- Te3[(s3 >> 24) ] ^
- rk[4];
- t[1] = Te0[(s1 ) & 0xff] ^
- Te1[(s2 >> 8) & 0xff] ^
- Te2[(s3 >> 16) & 0xff] ^
- Te3[(s0 >> 24) ] ^
- rk[5];
- t[2] = Te0[(s2 ) & 0xff] ^
- Te1[(s3 >> 8) & 0xff] ^
- Te2[(s0 >> 16) & 0xff] ^
- Te3[(s1 >> 24) ] ^
- rk[6];
- t[3] = Te0[(s3 ) & 0xff] ^
- Te1[(s0 >> 8) & 0xff] ^
- Te2[(s1 >> 16) & 0xff] ^
- Te3[(s2 >> 24) ] ^
- rk[7];
-#endif
- s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
-
- /*
- * Nr - 2 full rounds:
- */
- for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
-#if defined(AES_COMPACT_IN_INNER_ROUNDS)
- t[0] = Te4[(s0 ) & 0xff] ^
- Te4[(s1 >> 8) & 0xff] << 8 ^
- Te4[(s2 >> 16) & 0xff] << 16 ^
- Te4[(s3 >> 24) ] << 24;
- t[1] = Te4[(s1 ) & 0xff] ^
- Te4[(s2 >> 8) & 0xff] << 8 ^
- Te4[(s3 >> 16) & 0xff] << 16 ^
- Te4[(s0 >> 24) ] << 24;
- t[2] = Te4[(s2 ) & 0xff] ^
- Te4[(s3 >> 8) & 0xff] << 8 ^
- Te4[(s0 >> 16) & 0xff] << 16 ^
- Te4[(s1 >> 24) ] << 24;
- t[3] = Te4[(s3 ) & 0xff] ^
- Te4[(s0 >> 8) & 0xff] << 8 ^
- Te4[(s1 >> 16) & 0xff] << 16 ^
- Te4[(s2 >> 24) ] << 24;
-
- /* now do the linear transform using words */
- { int i;
- u32 r0, r1, r2;
-
- for (i = 0; i < 4; i++) {
- r0 = t[i];
- r1 = r0 & 0x80808080;
- r2 = ((r0 & 0x7f7f7f7f) << 1) ^
- ((r1 - (r1 >> 7)) & 0x1b1b1b1b);
-#if defined(ROTATE)
- t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
- ROTATE(r0,16) ^ ROTATE(r0,8);
-#else
- t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
- (r0 << 16) ^ (r0 >> 16) ^
- (r0 << 8) ^ (r0 >> 24);
-#endif
- t[i] ^= rk[i];
- }
- }
-#else
- t[0] = Te0[(s0 ) & 0xff] ^
- Te1[(s1 >> 8) & 0xff] ^
- Te2[(s2 >> 16) & 0xff] ^
- Te3[(s3 >> 24) ] ^
- rk[0];
- t[1] = Te0[(s1 ) & 0xff] ^
- Te1[(s2 >> 8) & 0xff] ^
- Te2[(s3 >> 16) & 0xff] ^
- Te3[(s0 >> 24) ] ^
- rk[1];
- t[2] = Te0[(s2 ) & 0xff] ^
- Te1[(s3 >> 8) & 0xff] ^
- Te2[(s0 >> 16) & 0xff] ^
- Te3[(s1 >> 24) ] ^
- rk[2];
- t[3] = Te0[(s3 ) & 0xff] ^
- Te1[(s0 >> 8) & 0xff] ^
- Te2[(s1 >> 16) & 0xff] ^
- Te3[(s2 >> 24) ] ^
- rk[3];
-#endif
- s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
- }
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
-#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
- prefetch256(Te4);
-
- *(u32*)(out+0) =
- Te4[(s0 ) & 0xff] ^
- Te4[(s1 >> 8) & 0xff] << 8 ^
- Te4[(s2 >> 16) & 0xff] << 16 ^
- Te4[(s3 >> 24) ] << 24 ^
- rk[0];
- *(u32*)(out+4) =
- Te4[(s1 ) & 0xff] ^
- Te4[(s2 >> 8) & 0xff] << 8 ^
- Te4[(s3 >> 16) & 0xff] << 16 ^
- Te4[(s0 >> 24) ] << 24 ^
- rk[1];
- *(u32*)(out+8) =
- Te4[(s2 ) & 0xff] ^
- Te4[(s3 >> 8) & 0xff] << 8 ^
- Te4[(s0 >> 16) & 0xff] << 16 ^
- Te4[(s1 >> 24) ] << 24 ^
- rk[2];
- *(u32*)(out+12) =
- Te4[(s3 ) & 0xff] ^
- Te4[(s0 >> 8) & 0xff] << 8 ^
- Te4[(s1 >> 16) & 0xff] << 16 ^
- Te4[(s2 >> 24) ] << 24 ^
- rk[3];
-#else
- *(u32*)(out+0) =
- (Te2[(s0 ) & 0xff] & 0x000000ffU) ^
- (Te3[(s1 >> 8) & 0xff] & 0x0000ff00U) ^
- (Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^
- (Te1[(s3 >> 24) ] & 0xff000000U) ^
- rk[0];
- *(u32*)(out+4) =
- (Te2[(s1 ) & 0xff] & 0x000000ffU) ^
- (Te3[(s2 >> 8) & 0xff] & 0x0000ff00U) ^
- (Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^
- (Te1[(s0 >> 24) ] & 0xff000000U) ^
- rk[1];
- *(u32*)(out+8) =
- (Te2[(s2 ) & 0xff] & 0x000000ffU) ^
- (Te3[(s3 >> 8) & 0xff] & 0x0000ff00U) ^
- (Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^
- (Te1[(s1 >> 24) ] & 0xff000000U) ^
- rk[2];
- *(u32*)(out+12) =
- (Te2[(s3 ) & 0xff] & 0x000000ffU) ^
- (Te3[(s0 >> 8) & 0xff] & 0x0000ff00U) ^
- (Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^
- (Te1[(s2 >> 24) ] & 0xff000000U) ^
- rk[3];
-#endif
-}
-
-/*
- * Decrypt a single block
- * in and out can overlap
- */
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t[4];
- int r;
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-
-#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
- prefetch256(Td4);
-
- t[0] = Td4[(s0 ) & 0xff] ^
- Td4[(s3 >> 8) & 0xff] << 8 ^
- Td4[(s2 >> 16) & 0xff] << 16 ^
- Td4[(s1 >> 24) ] << 24;
- t[1] = Td4[(s1 ) & 0xff] ^
- Td4[(s0 >> 8) & 0xff] << 8 ^
- Td4[(s3 >> 16) & 0xff] << 16 ^
- Td4[(s2 >> 24) ] << 24;
- t[2] = Td4[(s2 ) & 0xff] ^
- Td4[(s1 >> 8) & 0xff] << 8 ^
- Td4[(s0 >> 16) & 0xff] << 16 ^
- Td4[(s3 >> 24) ] << 24;
- t[3] = Td4[(s3 ) & 0xff] ^
- Td4[(s2 >> 8) & 0xff] << 8 ^
- Td4[(s1 >> 16) & 0xff] << 16 ^
- Td4[(s0 >> 24) ] << 24;
-
- /* now do the linear transform using words */
- { int i;
- u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-
- for (i = 0; i < 4; i++) {
- tp1 = t[i];
- m = tp1 & 0x80808080;
- tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- m = tp2 & 0x80808080;
- tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- m = tp4 & 0x80808080;
- tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- tp9 = tp8 ^ tp1;
- tpb = tp9 ^ tp2;
- tpd = tp9 ^ tp4;
- tpe = tp8 ^ tp4 ^ tp2;
-#if defined(ROTATE)
- t[i] = tpe ^ ROTATE(tpd,16) ^
- ROTATE(tp9,8) ^ ROTATE(tpb,24);
-#else
- t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
- (tp9 >> 24) ^ (tp9 << 8) ^
- (tpb >> 8) ^ (tpb << 24);
-#endif
- t[i] ^= rk[4+i];
- }
- }
-#else
- t[0] = Td0[(s0 ) & 0xff] ^
- Td1[(s3 >> 8) & 0xff] ^
- Td2[(s2 >> 16) & 0xff] ^
- Td3[(s1 >> 24) ] ^
- rk[4];
- t[1] = Td0[(s1 ) & 0xff] ^
- Td1[(s0 >> 8) & 0xff] ^
- Td2[(s3 >> 16) & 0xff] ^
- Td3[(s2 >> 24) ] ^
- rk[5];
- t[2] = Td0[(s2 ) & 0xff] ^
- Td1[(s1 >> 8) & 0xff] ^
- Td2[(s0 >> 16) & 0xff] ^
- Td3[(s3 >> 24) ] ^
- rk[6];
- t[3] = Td0[(s3 ) & 0xff] ^
- Td1[(s2 >> 8) & 0xff] ^
- Td2[(s1 >> 16) & 0xff] ^
- Td3[(s0 >> 24) ] ^
- rk[7];
-#endif
- s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
-
- /*
- * Nr - 2 full rounds:
- */
- for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
-#if defined(AES_COMPACT_IN_INNER_ROUNDS)
- t[0] = Td4[(s0 ) & 0xff] ^
- Td4[(s3 >> 8) & 0xff] << 8 ^
- Td4[(s2 >> 16) & 0xff] << 16 ^
- Td4[(s1 >> 24) ] << 24;
- t[1] = Td4[(s1 ) & 0xff] ^
- Td4[(s0 >> 8) & 0xff] << 8 ^
- Td4[(s3 >> 16) & 0xff] << 16 ^
- Td4[(s2 >> 24) ] << 24;
- t[2] = Td4[(s2 ) & 0xff] ^
- Td4[(s1 >> 8) & 0xff] << 8 ^
- Td4[(s0 >> 16) & 0xff] << 16 ^
- Td4[(s3 >> 24) ] << 24;
- t[3] = Td4[(s3 ) & 0xff] ^
- Td4[(s2 >> 8) & 0xff] << 8 ^
- Td4[(s1 >> 16) & 0xff] << 16 ^
- Td4[(s0 >> 24) ] << 24;
-
- /* now do the linear transform using words */
- { int i;
- u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-
- for (i = 0; i < 4; i++) {
- tp1 = t[i];
- m = tp1 & 0x80808080;
- tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- m = tp2 & 0x80808080;
- tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- m = tp4 & 0x80808080;
- tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
- ((m - (m >> 7)) & 0x1b1b1b1b);
- tp9 = tp8 ^ tp1;
- tpb = tp9 ^ tp2;
- tpd = tp9 ^ tp4;
- tpe = tp8 ^ tp4 ^ tp2;
-#if defined(ROTATE)
- t[i] = tpe ^ ROTATE(tpd,16) ^
- ROTATE(tp9,8) ^ ROTATE(tpb,24);
-#else
- t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
- (tp9 >> 24) ^ (tp9 << 8) ^
- (tpb >> 8) ^ (tpb << 24);
-#endif
- t[i] ^= rk[i];
- }
- }
-#else
- t[0] = Td0[(s0 ) & 0xff] ^
- Td1[(s3 >> 8) & 0xff] ^
- Td2[(s2 >> 16) & 0xff] ^
- Td3[(s1 >> 24) ] ^
- rk[0];
- t[1] = Td0[(s1 ) & 0xff] ^
- Td1[(s0 >> 8) & 0xff] ^
- Td2[(s3 >> 16) & 0xff] ^
- Td3[(s2 >> 24) ] ^
- rk[1];
- t[2] = Td0[(s2 ) & 0xff] ^
- Td1[(s1 >> 8) & 0xff] ^
- Td2[(s0 >> 16) & 0xff] ^
- Td3[(s3 >> 24) ] ^
- rk[2];
- t[3] = Td0[(s3 ) & 0xff] ^
- Td1[(s2 >> 8) & 0xff] ^
- Td2[(s1 >> 16) & 0xff] ^
- Td3[(s0 >> 24) ] ^
- rk[3];
-#endif
- s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
- }
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- prefetch256(Td4);
-
- *(u32*)(out+0) =
- (Td4[(s0 ) & 0xff]) ^
- (Td4[(s3 >> 8) & 0xff] << 8) ^
- (Td4[(s2 >> 16) & 0xff] << 16) ^
- (Td4[(s1 >> 24) ] << 24) ^
- rk[0];
- *(u32*)(out+4) =
- (Td4[(s1 ) & 0xff]) ^
- (Td4[(s0 >> 8) & 0xff] << 8) ^
- (Td4[(s3 >> 16) & 0xff] << 16) ^
- (Td4[(s2 >> 24) ] << 24) ^
- rk[1];
- *(u32*)(out+8) =
- (Td4[(s2 ) & 0xff]) ^
- (Td4[(s1 >> 8) & 0xff] << 8) ^
- (Td4[(s0 >> 16) & 0xff] << 16) ^
- (Td4[(s3 >> 24) ] << 24) ^
- rk[2];
- *(u32*)(out+12) =
- (Td4[(s3 ) & 0xff]) ^
- (Td4[(s2 >> 8) & 0xff] << 8) ^
- (Td4[(s1 >> 16) & 0xff] << 16) ^
- (Td4[(s0 >> 24) ] << 24) ^
- rk[3];
-}
diff --git a/crypto/openssl/crypto/aes/asm/aes-armv4.pl b/crypto/openssl/crypto/aes/asm/aes-armv4.pl
deleted file mode 100755
index 15742c1..0000000
--- a/crypto/openssl/crypto/aes/asm/aes-armv4.pl
+++ /dev/null
@@ -1,1030 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# AES for ARMv4
-
-# January 2007.
-#
-# Code uses single 1K S-box and is >2 times faster than code generated
-# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
-# allows to merge logical or arithmetic operation with shift or rotate
-# in one instruction and emit combined result every cycle. The module
-# is endian-neutral. The performance is ~42 cycles/byte for 128-bit
-# key.
-
-# May 2007.
-#
-# AES_set_[en|de]crypt_key is added.
-
-$s0="r0";
-$s1="r1";
-$s2="r2";
-$s3="r3";
-$t1="r4";
-$t2="r5";
-$t3="r6";
-$i1="r7";
-$i2="r8";
-$i3="r9";
-
-$tbl="r10";
-$key="r11";
-$rounds="r12";
-
-$code=<<___;
-.text
-.code 32
-
-.type AES_Te,%object
-.align 5
-AES_Te:
-.word 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
-.word 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
-.word 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
-.word 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
-.word 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
-.word 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
-.word 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
-.word 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
-.word 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
-.word 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
-.word 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
-.word 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
-.word 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
-.word 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
-.word 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
-.word 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
-.word 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
-.word 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
-.word 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
-.word 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
-.word 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
-.word 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
-.word 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
-.word 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
-.word 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
-.word 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
-.word 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
-.word 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
-.word 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
-.word 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
-.word 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
-.word 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
-.word 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
-.word 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
-.word 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
-.word 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
-.word 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
-.word 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
-.word 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
-.word 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
-.word 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
-.word 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
-.word 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
-.word 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
-.word 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
-.word 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
-.word 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
-.word 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
-.word 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
-.word 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
-.word 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
-.word 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
-.word 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
-.word 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
-.word 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
-.word 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
-.word 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
-.word 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
-.word 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
-.word 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
-.word 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
-.word 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
-.word 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
-.word 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
-@ Te4[256]
-.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-@ rcon[]
-.word 0x01000000, 0x02000000, 0x04000000, 0x08000000
-.word 0x10000000, 0x20000000, 0x40000000, 0x80000000
-.word 0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
-.size AES_Te,.-AES_Te
-
-@ void AES_encrypt(const unsigned char *in, unsigned char *out,
-@ const AES_KEY *key) {
-.global AES_encrypt
-.type AES_encrypt,%function
-.align 5
-AES_encrypt:
- sub r3,pc,#8 @ AES_encrypt
- stmdb sp!,{r1,r4-r12,lr}
- mov $rounds,r0 @ inp
- mov $key,r2
- sub $tbl,r3,#AES_encrypt-AES_Te @ Te
-
- ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
- ldrb $t1,[$rounds,#2] @ manner...
- ldrb $t2,[$rounds,#1]
- ldrb $t3,[$rounds,#0]
- orr $s0,$s0,$t1,lsl#8
- orr $s0,$s0,$t2,lsl#16
- orr $s0,$s0,$t3,lsl#24
- ldrb $s1,[$rounds,#7]
- ldrb $t1,[$rounds,#6]
- ldrb $t2,[$rounds,#5]
- ldrb $t3,[$rounds,#4]
- orr $s1,$s1,$t1,lsl#8
- orr $s1,$s1,$t2,lsl#16
- orr $s1,$s1,$t3,lsl#24
- ldrb $s2,[$rounds,#11]
- ldrb $t1,[$rounds,#10]
- ldrb $t2,[$rounds,#9]
- ldrb $t3,[$rounds,#8]
- orr $s2,$s2,$t1,lsl#8
- orr $s2,$s2,$t2,lsl#16
- orr $s2,$s2,$t3,lsl#24
- ldrb $s3,[$rounds,#15]
- ldrb $t1,[$rounds,#14]
- ldrb $t2,[$rounds,#13]
- ldrb $t3,[$rounds,#12]
- orr $s3,$s3,$t1,lsl#8
- orr $s3,$s3,$t2,lsl#16
- orr $s3,$s3,$t3,lsl#24
-
- bl _armv4_AES_encrypt
-
- ldr $rounds,[sp],#4 @ pop out
- mov $t1,$s0,lsr#24 @ write output in endian-neutral
- mov $t2,$s0,lsr#16 @ manner...
- mov $t3,$s0,lsr#8
- strb $t1,[$rounds,#0]
- strb $t2,[$rounds,#1]
- strb $t3,[$rounds,#2]
- strb $s0,[$rounds,#3]
- mov $t1,$s1,lsr#24
- mov $t2,$s1,lsr#16
- mov $t3,$s1,lsr#8
- strb $t1,[$rounds,#4]
- strb $t2,[$rounds,#5]
- strb $t3,[$rounds,#6]
- strb $s1,[$rounds,#7]
- mov $t1,$s2,lsr#24
- mov $t2,$s2,lsr#16
- mov $t3,$s2,lsr#8
- strb $t1,[$rounds,#8]
- strb $t2,[$rounds,#9]
- strb $t3,[$rounds,#10]
- strb $s2,[$rounds,#11]
- mov $t1,$s3,lsr#24
- mov $t2,$s3,lsr#16
- mov $t3,$s3,lsr#8
- strb $t1,[$rounds,#12]
- strb $t2,[$rounds,#13]
- strb $t3,[$rounds,#14]
- strb $s3,[$rounds,#15]
-
- ldmia sp!,{r4-r12,lr}
- tst lr,#1
- moveq pc,lr @ be binary compatible with V4, yet
- bx lr @ interoperable with Thumb ISA:-)
-.size AES_encrypt,.-AES_encrypt
-
-.type _armv4_AES_encrypt,%function
-.align 2
-_armv4_AES_encrypt:
- str lr,[sp,#-4]! @ push lr
- ldr $t1,[$key],#16
- ldr $t2,[$key,#-12]
- ldr $t3,[$key,#-8]
- ldr $i1,[$key,#-4]
- ldr $rounds,[$key,#240-16]
- eor $s0,$s0,$t1
- eor $s1,$s1,$t2
- eor $s2,$s2,$t3
- eor $s3,$s3,$i1
- sub $rounds,$rounds,#1
- mov lr,#255
-
-.Lenc_loop:
- and $i2,lr,$s0,lsr#8
- and $i3,lr,$s0,lsr#16
- and $i1,lr,$s0
- mov $s0,$s0,lsr#24
- ldr $t1,[$tbl,$i1,lsl#2] @ Te3[s0>>0]
- ldr $s0,[$tbl,$s0,lsl#2] @ Te0[s0>>24]
- ldr $t2,[$tbl,$i2,lsl#2] @ Te2[s0>>8]
- ldr $t3,[$tbl,$i3,lsl#2] @ Te1[s0>>16]
-
- and $i1,lr,$s1,lsr#16 @ i0
- and $i2,lr,$s1
- and $i3,lr,$s1,lsr#8
- mov $s1,$s1,lsr#24
- ldr $i1,[$tbl,$i1,lsl#2] @ Te1[s1>>16]
- ldr $s1,[$tbl,$s1,lsl#2] @ Te0[s1>>24]
- ldr $i2,[$tbl,$i2,lsl#2] @ Te3[s1>>0]
- ldr $i3,[$tbl,$i3,lsl#2] @ Te2[s1>>8]
- eor $s0,$s0,$i1,ror#8
- eor $s1,$s1,$t1,ror#24
- eor $t2,$t2,$i2,ror#8
- eor $t3,$t3,$i3,ror#8
-
- and $i1,lr,$s2,lsr#8 @ i0
- and $i2,lr,$s2,lsr#16 @ i1
- and $i3,lr,$s2
- mov $s2,$s2,lsr#24
- ldr $i1,[$tbl,$i1,lsl#2] @ Te2[s2>>8]
- ldr $i2,[$tbl,$i2,lsl#2] @ Te1[s2>>16]
- ldr $s2,[$tbl,$s2,lsl#2] @ Te0[s2>>24]
- ldr $i3,[$tbl,$i3,lsl#2] @ Te3[s2>>0]
- eor $s0,$s0,$i1,ror#16
- eor $s1,$s1,$i2,ror#8
- eor $s2,$s2,$t2,ror#16
- eor $t3,$t3,$i3,ror#16
-
- and $i1,lr,$s3 @ i0
- and $i2,lr,$s3,lsr#8 @ i1
- and $i3,lr,$s3,lsr#16 @ i2
- mov $s3,$s3,lsr#24
- ldr $i1,[$tbl,$i1,lsl#2] @ Te3[s3>>0]
- ldr $i2,[$tbl,$i2,lsl#2] @ Te2[s3>>8]
- ldr $i3,[$tbl,$i3,lsl#2] @ Te1[s3>>16]
- ldr $s3,[$tbl,$s3,lsl#2] @ Te0[s3>>24]
- eor $s0,$s0,$i1,ror#24
- eor $s1,$s1,$i2,ror#16
- eor $s2,$s2,$i3,ror#8
- eor $s3,$s3,$t3,ror#8
-
- ldr $t1,[$key],#16
- ldr $t2,[$key,#-12]
- ldr $t3,[$key,#-8]
- ldr $i1,[$key,#-4]
- eor $s0,$s0,$t1
- eor $s1,$s1,$t2
- eor $s2,$s2,$t3
- eor $s3,$s3,$i1
-
- subs $rounds,$rounds,#1
- bne .Lenc_loop
-
- add $tbl,$tbl,#2
-
- and $i1,lr,$s0
- and $i2,lr,$s0,lsr#8
- and $i3,lr,$s0,lsr#16
- mov $s0,$s0,lsr#24
- ldrb $t1,[$tbl,$i1,lsl#2] @ Te4[s0>>0]
- ldrb $s0,[$tbl,$s0,lsl#2] @ Te4[s0>>24]
- ldrb $t2,[$tbl,$i2,lsl#2] @ Te4[s0>>8]
- ldrb $t3,[$tbl,$i3,lsl#2] @ Te4[s0>>16]
-
- and $i1,lr,$s1,lsr#16 @ i0
- and $i2,lr,$s1
- and $i3,lr,$s1,lsr#8
- mov $s1,$s1,lsr#24
- ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s1>>16]
- ldrb $s1,[$tbl,$s1,lsl#2] @ Te4[s1>>24]
- ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s1>>0]
- ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s1>>8]
- eor $s0,$i1,$s0,lsl#8
- eor $s1,$t1,$s1,lsl#24
- eor $t2,$i2,$t2,lsl#8
- eor $t3,$i3,$t3,lsl#8
-
- and $i1,lr,$s2,lsr#8 @ i0
- and $i2,lr,$s2,lsr#16 @ i1
- and $i3,lr,$s2
- mov $s2,$s2,lsr#24
- ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s2>>8]
- ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s2>>16]
- ldrb $s2,[$tbl,$s2,lsl#2] @ Te4[s2>>24]
- ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s2>>0]
- eor $s0,$i1,$s0,lsl#8
- eor $s1,$s1,$i2,lsl#16
- eor $s2,$t2,$s2,lsl#24
- eor $t3,$i3,$t3,lsl#8
-
- and $i1,lr,$s3 @ i0
- and $i2,lr,$s3,lsr#8 @ i1
- and $i3,lr,$s3,lsr#16 @ i2
- mov $s3,$s3,lsr#24
- ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s3>>0]
- ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s3>>8]
- ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s3>>16]
- ldrb $s3,[$tbl,$s3,lsl#2] @ Te4[s3>>24]
- eor $s0,$i1,$s0,lsl#8
- eor $s1,$s1,$i2,lsl#8
- eor $s2,$s2,$i3,lsl#16
- eor $s3,$t3,$s3,lsl#24
-
- ldr lr,[sp],#4 @ pop lr
- ldr $t1,[$key,#0]
- ldr $t2,[$key,#4]
- ldr $t3,[$key,#8]
- ldr $i1,[$key,#12]
- eor $s0,$s0,$t1
- eor $s1,$s1,$t2
- eor $s2,$s2,$t3
- eor $s3,$s3,$i1
-
- sub $tbl,$tbl,#2
- mov pc,lr @ return
-.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
-
-.global AES_set_encrypt_key
-.type AES_set_encrypt_key,%function
-.align 5
-AES_set_encrypt_key:
- sub r3,pc,#8 @ AES_set_encrypt_key
- teq r0,#0
- moveq r0,#-1
- beq .Labrt
- teq r2,#0
- moveq r0,#-1
- beq .Labrt
-
- teq r1,#128
- beq .Lok
- teq r1,#192
- beq .Lok
- teq r1,#256
- movne r0,#-1
- bne .Labrt
-
-.Lok: stmdb sp!,{r4-r12,lr}
- sub $tbl,r3,#AES_set_encrypt_key-AES_Te-1024 @ Te4
-
- mov $rounds,r0 @ inp
- mov lr,r1 @ bits
- mov $key,r2 @ key
-
- ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
- ldrb $t1,[$rounds,#2] @ manner...
- ldrb $t2,[$rounds,#1]
- ldrb $t3,[$rounds,#0]
- orr $s0,$s0,$t1,lsl#8
- orr $s0,$s0,$t2,lsl#16
- orr $s0,$s0,$t3,lsl#24
- ldrb $s1,[$rounds,#7]
- ldrb $t1,[$rounds,#6]
- ldrb $t2,[$rounds,#5]
- ldrb $t3,[$rounds,#4]
- orr $s1,$s1,$t1,lsl#8
- orr $s1,$s1,$t2,lsl#16
- orr $s1,$s1,$t3,lsl#24
- ldrb $s2,[$rounds,#11]
- ldrb $t1,[$rounds,#10]
- ldrb $t2,[$rounds,#9]
- ldrb $t3,[$rounds,#8]
- orr $s2,$s2,$t1,lsl#8
- orr $s2,$s2,$t2,lsl#16
- orr $s2,$s2,$t3,lsl#24
- ldrb $s3,[$rounds,#15]
- ldrb $t1,[$rounds,#14]
- ldrb $t2,[$rounds,#13]
- ldrb $t3,[$rounds,#12]
- orr $s3,$s3,$t1,lsl#8
- orr $s3,$s3,$t2,lsl#16
- orr $s3,$s3,$t3,lsl#24
- str $s0,[$key],#16
- str $s1,[$key,#-12]
- str $s2,[$key,#-8]
- str $s3,[$key,#-4]
-
- teq lr,#128
- bne .Lnot128
- mov $rounds,#10
- str $rounds,[$key,#240-16]
- add $t3,$tbl,#256 @ rcon
- mov lr,#255
-
-.L128_loop:
- and $t2,lr,$s3,lsr#24
- and $i1,lr,$s3,lsr#16
- and $i2,lr,$s3,lsr#8
- and $i3,lr,$s3
- ldrb $t2,[$tbl,$t2]
- ldrb $i1,[$tbl,$i1]
- ldrb $i2,[$tbl,$i2]
- ldrb $i3,[$tbl,$i3]
- ldr $t1,[$t3],#4 @ rcon[i++]
- orr $t2,$t2,$i1,lsl#24
- orr $t2,$t2,$i2,lsl#16
- orr $t2,$t2,$i3,lsl#8
- eor $t2,$t2,$t1
- eor $s0,$s0,$t2 @ rk[4]=rk[0]^...
- eor $s1,$s1,$s0 @ rk[5]=rk[1]^rk[4]
- eor $s2,$s2,$s1 @ rk[6]=rk[2]^rk[5]
- eor $s3,$s3,$s2 @ rk[7]=rk[3]^rk[6]
- str $s0,[$key],#16
- str $s1,[$key,#-12]
- str $s2,[$key,#-8]
- str $s3,[$key,#-4]
-
- subs $rounds,$rounds,#1
- bne .L128_loop
- sub r2,$key,#176
- b .Ldone
-
-.Lnot128:
- ldrb $i2,[$rounds,#19]
- ldrb $t1,[$rounds,#18]
- ldrb $t2,[$rounds,#17]
- ldrb $t3,[$rounds,#16]
- orr $i2,$i2,$t1,lsl#8
- orr $i2,$i2,$t2,lsl#16
- orr $i2,$i2,$t3,lsl#24
- ldrb $i3,[$rounds,#23]
- ldrb $t1,[$rounds,#22]
- ldrb $t2,[$rounds,#21]
- ldrb $t3,[$rounds,#20]
- orr $i3,$i3,$t1,lsl#8
- orr $i3,$i3,$t2,lsl#16
- orr $i3,$i3,$t3,lsl#24
- str $i2,[$key],#8
- str $i3,[$key,#-4]
-
- teq lr,#192
- bne .Lnot192
- mov $rounds,#12
- str $rounds,[$key,#240-24]
- add $t3,$tbl,#256 @ rcon
- mov lr,#255
- mov $rounds,#8
-
-.L192_loop:
- and $t2,lr,$i3,lsr#24
- and $i1,lr,$i3,lsr#16
- and $i2,lr,$i3,lsr#8
- and $i3,lr,$i3
- ldrb $t2,[$tbl,$t2]
- ldrb $i1,[$tbl,$i1]
- ldrb $i2,[$tbl,$i2]
- ldrb $i3,[$tbl,$i3]
- ldr $t1,[$t3],#4 @ rcon[i++]
- orr $t2,$t2,$i1,lsl#24
- orr $t2,$t2,$i2,lsl#16
- orr $t2,$t2,$i3,lsl#8
- eor $i3,$t2,$t1
- eor $s0,$s0,$i3 @ rk[6]=rk[0]^...
- eor $s1,$s1,$s0 @ rk[7]=rk[1]^rk[6]
- eor $s2,$s2,$s1 @ rk[8]=rk[2]^rk[7]
- eor $s3,$s3,$s2 @ rk[9]=rk[3]^rk[8]
- str $s0,[$key],#24
- str $s1,[$key,#-20]
- str $s2,[$key,#-16]
- str $s3,[$key,#-12]
-
- subs $rounds,$rounds,#1
- subeq r2,$key,#216
- beq .Ldone
-
- ldr $i1,[$key,#-32]
- ldr $i2,[$key,#-28]
- eor $i1,$i1,$s3 @ rk[10]=rk[4]^rk[9]
- eor $i3,$i2,$i1 @ rk[11]=rk[5]^rk[10]
- str $i1,[$key,#-8]
- str $i3,[$key,#-4]
- b .L192_loop
-
-.Lnot192:
- ldrb $i2,[$rounds,#27]
- ldrb $t1,[$rounds,#26]
- ldrb $t2,[$rounds,#25]
- ldrb $t3,[$rounds,#24]
- orr $i2,$i2,$t1,lsl#8
- orr $i2,$i2,$t2,lsl#16
- orr $i2,$i2,$t3,lsl#24
- ldrb $i3,[$rounds,#31]
- ldrb $t1,[$rounds,#30]
- ldrb $t2,[$rounds,#29]
- ldrb $t3,[$rounds,#28]
- orr $i3,$i3,$t1,lsl#8
- orr $i3,$i3,$t2,lsl#16
- orr $i3,$i3,$t3,lsl#24
- str $i2,[$key],#8
- str $i3,[$key,#-4]
-
- mov $rounds,#14
- str $rounds,[$key,#240-32]
- add $t3,$tbl,#256 @ rcon
- mov lr,#255
- mov $rounds,#7
-
-.L256_loop:
- and $t2,lr,$i3,lsr#24
- and $i1,lr,$i3,lsr#16
- and $i2,lr,$i3,lsr#8
- and $i3,lr,$i3
- ldrb $t2,[$tbl,$t2]
- ldrb $i1,[$tbl,$i1]
- ldrb $i2,[$tbl,$i2]
- ldrb $i3,[$tbl,$i3]
- ldr $t1,[$t3],#4 @ rcon[i++]
- orr $t2,$t2,$i1,lsl#24
- orr $t2,$t2,$i2,lsl#16
- orr $t2,$t2,$i3,lsl#8
- eor $i3,$t2,$t1
- eor $s0,$s0,$i3 @ rk[8]=rk[0]^...
- eor $s1,$s1,$s0 @ rk[9]=rk[1]^rk[8]
- eor $s2,$s2,$s1 @ rk[10]=rk[2]^rk[9]
- eor $s3,$s3,$s2 @ rk[11]=rk[3]^rk[10]
- str $s0,[$key],#32
- str $s1,[$key,#-28]
- str $s2,[$key,#-24]
- str $s3,[$key,#-20]
-
- subs $rounds,$rounds,#1
- subeq r2,$key,#256
- beq .Ldone
-
- and $t2,lr,$s3
- and $i1,lr,$s3,lsr#8
- and $i2,lr,$s3,lsr#16
- and $i3,lr,$s3,lsr#24
- ldrb $t2,[$tbl,$t2]
- ldrb $i1,[$tbl,$i1]
- ldrb $i2,[$tbl,$i2]
- ldrb $i3,[$tbl,$i3]
- orr $t2,$t2,$i1,lsl#8
- orr $t2,$t2,$i2,lsl#16
- orr $t2,$t2,$i3,lsl#24
-
- ldr $t1,[$key,#-48]
- ldr $i1,[$key,#-44]
- ldr $i2,[$key,#-40]
- ldr $i3,[$key,#-36]
- eor $t1,$t1,$t2 @ rk[12]=rk[4]^...
- eor $i1,$i1,$t1 @ rk[13]=rk[5]^rk[12]
- eor $i2,$i2,$i1 @ rk[14]=rk[6]^rk[13]
- eor $i3,$i3,$i2 @ rk[15]=rk[7]^rk[14]
- str $t1,[$key,#-16]
- str $i1,[$key,#-12]
- str $i2,[$key,#-8]
- str $i3,[$key,#-4]
- b .L256_loop
-
-.Ldone: mov r0,#0
- ldmia sp!,{r4-r12,lr}
-.Labrt: tst lr,#1
- moveq pc,lr @ be binary compatible with V4, yet
- bx lr @ interoperable with Thumb ISA:-)
-.size AES_set_encrypt_key,.-AES_set_encrypt_key
-
-.global AES_set_decrypt_key
-.type AES_set_decrypt_key,%function
-.align 5
-AES_set_decrypt_key:
- str lr,[sp,#-4]! @ push lr
- bl AES_set_encrypt_key
- teq r0,#0
- ldrne lr,[sp],#4 @ pop lr
- bne .Labrt
-
- stmdb sp!,{r4-r12}
-
- ldr $rounds,[r2,#240] @ AES_set_encrypt_key preserves r2,
- mov $key,r2 @ which is AES_KEY *key
- mov $i1,r2
- add $i2,r2,$rounds,lsl#4
-
-.Linv: ldr $s0,[$i1]
- ldr $s1,[$i1,#4]
- ldr $s2,[$i1,#8]
- ldr $s3,[$i1,#12]
- ldr $t1,[$i2]
- ldr $t2,[$i2,#4]
- ldr $t3,[$i2,#8]
- ldr $i3,[$i2,#12]
- str $s0,[$i2],#-16
- str $s1,[$i2,#16+4]
- str $s2,[$i2,#16+8]
- str $s3,[$i2,#16+12]
- str $t1,[$i1],#16
- str $t2,[$i1,#-12]
- str $t3,[$i1,#-8]
- str $i3,[$i1,#-4]
- teq $i1,$i2
- bne .Linv
-___
-$mask80=$i1;
-$mask1b=$i2;
-$mask7f=$i3;
-$code.=<<___;
- ldr $s0,[$key,#16]! @ prefetch tp1
- mov $mask80,#0x80
- mov $mask1b,#0x1b
- orr $mask80,$mask80,#0x8000
- orr $mask1b,$mask1b,#0x1b00
- orr $mask80,$mask80,$mask80,lsl#16
- orr $mask1b,$mask1b,$mask1b,lsl#16
- sub $rounds,$rounds,#1
- mvn $mask7f,$mask80
- mov $rounds,$rounds,lsl#2 @ (rounds-1)*4
-
-.Lmix: and $t1,$s0,$mask80
- and $s1,$s0,$mask7f
- sub $t1,$t1,$t1,lsr#7
- and $t1,$t1,$mask1b
- eor $s1,$t1,$s1,lsl#1 @ tp2
-
- and $t1,$s1,$mask80
- and $s2,$s1,$mask7f
- sub $t1,$t1,$t1,lsr#7
- and $t1,$t1,$mask1b
- eor $s2,$t1,$s2,lsl#1 @ tp4
-
- and $t1,$s2,$mask80
- and $s3,$s2,$mask7f
- sub $t1,$t1,$t1,lsr#7
- and $t1,$t1,$mask1b
- eor $s3,$t1,$s3,lsl#1 @ tp8
-
- eor $t1,$s1,$s2
- eor $t2,$s0,$s3 @ tp9
- eor $t1,$t1,$s3 @ tpe
- eor $t1,$t1,$s1,ror#24
- eor $t1,$t1,$t2,ror#24 @ ^= ROTATE(tpb=tp9^tp2,8)
- eor $t1,$t1,$s2,ror#16
- eor $t1,$t1,$t2,ror#16 @ ^= ROTATE(tpd=tp9^tp4,16)
- eor $t1,$t1,$t2,ror#8 @ ^= ROTATE(tp9,24)
-
- ldr $s0,[$key,#4] @ prefetch tp1
- str $t1,[$key],#4
- subs $rounds,$rounds,#1
- bne .Lmix
-
- mov r0,#0
- ldmia sp!,{r4-r12,lr}
- tst lr,#1
- moveq pc,lr @ be binary compatible with V4, yet
- bx lr @ interoperable with Thumb ISA:-)
-.size AES_set_decrypt_key,.-AES_set_decrypt_key
-
-.type AES_Td,%object
-.align 5
-AES_Td:
-.word 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
-.word 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
-.word 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
-.word 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
-.word 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
-.word 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
-.word 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
-.word 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
-.word 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
-.word 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
-.word 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
-.word 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
-.word 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
-.word 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
-.word 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
-.word 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
-.word 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
-.word 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
-.word 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
-.word 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
-.word 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
-.word 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
-.word 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
-.word 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
-.word 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
-.word 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
-.word 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
-.word 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
-.word 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
-.word 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
-.word 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
-.word 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
-.word 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
-.word 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
-.word 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
-.word 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
-.word 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
-.word 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
-.word 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
-.word 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
-.word 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
-.word 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
-.word 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
-.word 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
-.word 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
-.word 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
-.word 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
-.word 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
-.word 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
-.word 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
-.word 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
-.word 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
-.word 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
-.word 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
-.word 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
-.word 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
-.word 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
-.word 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
-.word 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
-.word 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
-.word 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
-.word 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
-.word 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
-.word 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
-@ Td4[256]
-.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-.size AES_Td,.-AES_Td
-
-@ void AES_decrypt(const unsigned char *in, unsigned char *out,
-@ const AES_KEY *key) {
-.global AES_decrypt
-.type AES_decrypt,%function
-.align 5
-AES_decrypt:
- sub r3,pc,#8 @ AES_decrypt
- stmdb sp!,{r1,r4-r12,lr}
- mov $rounds,r0 @ inp
- mov $key,r2
- sub $tbl,r3,#AES_decrypt-AES_Td @ Td
-
- ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
- ldrb $t1,[$rounds,#2] @ manner...
- ldrb $t2,[$rounds,#1]
- ldrb $t3,[$rounds,#0]
- orr $s0,$s0,$t1,lsl#8
- orr $s0,$s0,$t2,lsl#16
- orr $s0,$s0,$t3,lsl#24
- ldrb $s1,[$rounds,#7]
- ldrb $t1,[$rounds,#6]
- ldrb $t2,[$rounds,#5]
- ldrb $t3,[$rounds,#4]
- orr $s1,$s1,$t1,lsl#8
- orr $s1,$s1,$t2,lsl#16
- orr $s1,$s1,$t3,lsl#24
- ldrb $s2,[$rounds,#11]
- ldrb $t1,[$rounds,#10]
- ldrb $t2,[$rounds,#9]
- ldrb $t3,[$rounds,#8]
- orr $s2,$s2,$t1,lsl#8
- orr $s2,$s2,$t2,lsl#16
- orr $s2,$s2,$t3,lsl#24
- ldrb $s3,[$rounds,#15]
- ldrb $t1,[$rounds,#14]
- ldrb $t2,[$rounds,#13]
- ldrb $t3,[$rounds,#12]
- orr $s3,$s3,$t1,lsl#8
- orr $s3,$s3,$t2,lsl#16
- orr $s3,$s3,$t3,lsl#24
-
- bl _armv4_AES_decrypt
-
- ldr $rounds,[sp],#4 @ pop out
- mov $t1,$s0,lsr#24 @ write output in endian-neutral
- mov $t2,$s0,lsr#16 @ manner...
- mov $t3,$s0,lsr#8
- strb $t1,[$rounds,#0]
- strb $t2,[$rounds,#1]
- strb $t3,[$rounds,#2]
- strb $s0,[$rounds,#3]
- mov $t1,$s1,lsr#24
- mov $t2,$s1,lsr#16
- mov $t3,$s1,lsr#8
- strb $t1,[$rounds,#4]
- strb $t2,[$rounds,#5]
- strb $t3,[$rounds,#6]
- strb $s1,[$rounds,#7]
- mov $t1,$s2,lsr#24
- mov $t2,$s2,lsr#16
- mov $t3,$s2,lsr#8
- strb $t1,[$rounds,#8]
- strb $t2,[$rounds,#9]
- strb $t3,[$rounds,#10]
- strb $s2,[$rounds,#11]
- mov $t1,$s3,lsr#24
- mov $t2,$s3,lsr#16
- mov $t3,$s3,lsr#8
- strb $t1,[$rounds,#12]
- strb $t2,[$rounds,#13]
- strb $t3,[$rounds,#14]
- strb $s3,[$rounds,#15]
-
- ldmia sp!,{r4-r12,lr}
- tst lr,#1
- moveq pc,lr @ be binary compatible with V4, yet
- bx lr @ interoperable with Thumb ISA:-)
-.size AES_decrypt,.-AES_decrypt
-
-.type _armv4_AES_decrypt,%function
-.align 2
-_armv4_AES_decrypt:
- str lr,[sp,#-4]! @ push lr
- ldr $t1,[$key],#16
- ldr $t2,[$key,#-12]
- ldr $t3,[$key,#-8]
- ldr $i1,[$key,#-4]
- ldr $rounds,[$key,#240-16]
- eor $s0,$s0,$t1
- eor $s1,$s1,$t2
- eor $s2,$s2,$t3
- eor $s3,$s3,$i1
- sub $rounds,$rounds,#1
- mov lr,#255
-
-.Ldec_loop:
- and $i1,lr,$s0,lsr#16
- and $i2,lr,$s0,lsr#8
- and $i3,lr,$s0
- mov $s0,$s0,lsr#24
- ldr $t1,[$tbl,$i1,lsl#2] @ Td1[s0>>16]
- ldr $s0,[$tbl,$s0,lsl#2] @ Td0[s0>>24]
- ldr $t2,[$tbl,$i2,lsl#2] @ Td2[s0>>8]
- ldr $t3,[$tbl,$i3,lsl#2] @ Td3[s0>>0]
-
- and $i1,lr,$s1 @ i0
- and $i2,lr,$s1,lsr#16
- and $i3,lr,$s1,lsr#8
- mov $s1,$s1,lsr#24
- ldr $i1,[$tbl,$i1,lsl#2] @ Td3[s1>>0]
- ldr $s1,[$tbl,$s1,lsl#2] @ Td0[s1>>24]
- ldr $i2,[$tbl,$i2,lsl#2] @ Td1[s1>>16]
- ldr $i3,[$tbl,$i3,lsl#2] @ Td2[s1>>8]
- eor $s0,$s0,$i1,ror#24
- eor $s1,$s1,$t1,ror#8
- eor $t2,$i2,$t2,ror#8
- eor $t3,$i3,$t3,ror#8
-
- and $i1,lr,$s2,lsr#8 @ i0
- and $i2,lr,$s2 @ i1
- and $i3,lr,$s2,lsr#16
- mov $s2,$s2,lsr#24
- ldr $i1,[$tbl,$i1,lsl#2] @ Td2[s2>>8]
- ldr $i2,[$tbl,$i2,lsl#2] @ Td3[s2>>0]
- ldr $s2,[$tbl,$s2,lsl#2] @ Td0[s2>>24]
- ldr $i3,[$tbl,$i3,lsl#2] @ Td1[s2>>16]
- eor $s0,$s0,$i1,ror#16
- eor $s1,$s1,$i2,ror#24
- eor $s2,$s2,$t2,ror#8
- eor $t3,$i3,$t3,ror#8
-
- and $i1,lr,$s3,lsr#16 @ i0
- and $i2,lr,$s3,lsr#8 @ i1
- and $i3,lr,$s3 @ i2
- mov $s3,$s3,lsr#24
- ldr $i1,[$tbl,$i1,lsl#2] @ Td1[s3>>16]
- ldr $i2,[$tbl,$i2,lsl#2] @ Td2[s3>>8]
- ldr $i3,[$tbl,$i3,lsl#2] @ Td3[s3>>0]
- ldr $s3,[$tbl,$s3,lsl#2] @ Td0[s3>>24]
- eor $s0,$s0,$i1,ror#8
- eor $s1,$s1,$i2,ror#16
- eor $s2,$s2,$i3,ror#24
- eor $s3,$s3,$t3,ror#8
-
- ldr $t1,[$key],#16
- ldr $t2,[$key,#-12]
- ldr $t3,[$key,#-8]
- ldr $i1,[$key,#-4]
- eor $s0,$s0,$t1
- eor $s1,$s1,$t2
- eor $s2,$s2,$t3
- eor $s3,$s3,$i1
-
- subs $rounds,$rounds,#1
- bne .Ldec_loop
-
- add $tbl,$tbl,#1024
-
- ldr $t1,[$tbl,#0] @ prefetch Td4
- ldr $t2,[$tbl,#32]
- ldr $t3,[$tbl,#64]
- ldr $i1,[$tbl,#96]
- ldr $i2,[$tbl,#128]
- ldr $i3,[$tbl,#160]
- ldr $t1,[$tbl,#192]
- ldr $t2,[$tbl,#224]
-
- and $i1,lr,$s0,lsr#16
- and $i2,lr,$s0,lsr#8
- and $i3,lr,$s0
- ldrb $s0,[$tbl,$s0,lsr#24] @ Td4[s0>>24]
- ldrb $t1,[$tbl,$i1] @ Td4[s0>>16]
- ldrb $t2,[$tbl,$i2] @ Td4[s0>>8]
- ldrb $t3,[$tbl,$i3] @ Td4[s0>>0]
-
- and $i1,lr,$s1 @ i0
- and $i2,lr,$s1,lsr#16
- and $i3,lr,$s1,lsr#8
- ldrb $i1,[$tbl,$i1] @ Td4[s1>>0]
- ldrb $s1,[$tbl,$s1,lsr#24] @ Td4[s1>>24]
- ldrb $i2,[$tbl,$i2] @ Td4[s1>>16]
- ldrb $i3,[$tbl,$i3] @ Td4[s1>>8]
- eor $s0,$i1,$s0,lsl#24
- eor $s1,$t1,$s1,lsl#8
- eor $t2,$t2,$i2,lsl#8
- eor $t3,$t3,$i3,lsl#8
-
- and $i1,lr,$s2,lsr#8 @ i0
- and $i2,lr,$s2 @ i1
- and $i3,lr,$s2,lsr#16
- ldrb $i1,[$tbl,$i1] @ Td4[s2>>8]
- ldrb $i2,[$tbl,$i2] @ Td4[s2>>0]
- ldrb $s2,[$tbl,$s2,lsr#24] @ Td4[s2>>24]
- ldrb $i3,[$tbl,$i3] @ Td4[s2>>16]
- eor $s0,$s0,$i1,lsl#8
- eor $s1,$i2,$s1,lsl#16
- eor $s2,$t2,$s2,lsl#16
- eor $t3,$t3,$i3,lsl#16
-
- and $i1,lr,$s3,lsr#16 @ i0
- and $i2,lr,$s3,lsr#8 @ i1
- and $i3,lr,$s3 @ i2
- ldrb $i1,[$tbl,$i1] @ Td4[s3>>16]
- ldrb $i2,[$tbl,$i2] @ Td4[s3>>8]
- ldrb $i3,[$tbl,$i3] @ Td4[s3>>0]
- ldrb $s3,[$tbl,$s3,lsr#24] @ Td4[s3>>24]
- eor $s0,$s0,$i1,lsl#16
- eor $s1,$s1,$i2,lsl#8
- eor $s2,$i3,$s2,lsl#8
- eor $s3,$t3,$s3,lsl#24
-
- ldr lr,[sp],#4 @ pop lr
- ldr $t1,[$key,#0]
- ldr $t2,[$key,#4]
- ldr $t3,[$key,#8]
- ldr $i1,[$key,#12]
- eor $s0,$s0,$t1
- eor $s1,$s1,$t2
- eor $s2,$s2,$t3
- eor $s3,$s3,$i1
-
- sub $tbl,$tbl,#1024
- mov pc,lr @ return
-.size _armv4_AES_decrypt,.-_armv4_AES_decrypt
-.asciz "AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
-___
-
-$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
-print $code;
diff --git a/crypto/openssl/crypto/aes/asm/aes-ppc.pl b/crypto/openssl/crypto/aes/asm/aes-ppc.pl
deleted file mode 100755
index ce42765..0000000
--- a/crypto/openssl/crypto/aes/asm/aes-ppc.pl
+++ /dev/null
@@ -1,1176 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# Needs more work: key setup, page boundaries, CBC routine...
-#
-# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
-# 128-bit key, which is ~40% better than 64-bit code generated by gcc
-# 4.0. But these are not the ones currently used! Their "compact"
-# counterparts are, for security reason. ppc_AES_encrypt_compact runs
-# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
-# at 1/3 of ppc_AES_decrypt.
-
-$flavour = shift;
-
-if ($flavour =~ /64/) {
- $SIZE_T =8;
- $STU ="stdu";
- $POP ="ld";
- $PUSH ="std";
-} elsif ($flavour =~ /32/) {
- $SIZE_T =4;
- $STU ="stwu";
- $POP ="lwz";
- $PUSH ="stw";
-} else { die "nonsense $flavour"; }
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-die "can't locate ppc-xlate.pl";
-
-open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-
-$FRAME=32*$SIZE_T;
-
-sub _data_word()
-{ my $i;
- while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
-}
-
-$sp="r1";
-$toc="r2";
-$inp="r3";
-$out="r4";
-$key="r5";
-
-$Tbl0="r3";
-$Tbl1="r6";
-$Tbl2="r7";
-$Tbl3="r2";
-
-$s0="r8";
-$s1="r9";
-$s2="r10";
-$s3="r11";
-
-$t0="r12";
-$t1="r13";
-$t2="r14";
-$t3="r15";
-
-$acc00="r16";
-$acc01="r17";
-$acc02="r18";
-$acc03="r19";
-
-$acc04="r20";
-$acc05="r21";
-$acc06="r22";
-$acc07="r23";
-
-$acc08="r24";
-$acc09="r25";
-$acc10="r26";
-$acc11="r27";
-
-$acc12="r28";
-$acc13="r29";
-$acc14="r30";
-$acc15="r31";
-
-# stay away from TLS pointer
-if ($SIZE_T==8) { die if ($t1 ne "r13"); $t1="r0"; }
-else { die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0"; }
-$mask80=$Tbl2;
-$mask1b=$Tbl3;
-
-$code.=<<___;
-.machine "any"
-.text
-
-.align 7
-LAES_Te:
- mflr r0
- bcl 20,31,\$+4
- mflr $Tbl0 ; vvvvv "distance" between . and 1st data entry
- addi $Tbl0,$Tbl0,`128-8`
- mtlr r0
- blr
- .space `32-24`
-LAES_Td:
- mflr r0
- bcl 20,31,\$+4
- mflr $Tbl0 ; vvvvvvvv "distance" between . and 1st data entry
- addi $Tbl0,$Tbl0,`128-8-32+2048+256`
- mtlr r0
- blr
- .space `128-32-24`
-___
-&_data_word(
- 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
- 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
- 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
- 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
- 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
- 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
- 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
- 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
- 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
- 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
- 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
- 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
- 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
- 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
- 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
- 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
- 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
- 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
- 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
- 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
- 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
- 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
- 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
- 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
- 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
- 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
- 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
- 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
- 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
- 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
- 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
- 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
- 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
- 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
- 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
- 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
- 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
- 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
- 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
- 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
- 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
- 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
- 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
- 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
- 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
- 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
- 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
- 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
- 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
- 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
- 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
- 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
- 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
- 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
- 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
- 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
- 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
- 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
- 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
- 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
- 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
- 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
- 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
- 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
-$code.=<<___;
-.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-___
-&_data_word(
- 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
- 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
- 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
- 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
- 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
- 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
- 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
- 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
- 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
- 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
- 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
- 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
- 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
- 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
- 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
- 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
- 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
- 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
- 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
- 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
- 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
- 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
- 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
- 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
- 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
- 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
- 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
- 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
- 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
- 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
- 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
- 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
- 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
- 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
- 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
- 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
- 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
- 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
- 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
- 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
- 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
- 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
- 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
- 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
- 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
- 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
- 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
- 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
- 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
- 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
- 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
- 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
- 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
- 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
- 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
- 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
- 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
- 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
- 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
- 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
- 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
- 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
- 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
- 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
-$code.=<<___;
-.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-
-
-.globl .AES_encrypt
-.align 7
-.AES_encrypt:
- mflr r0
- $STU $sp,-$FRAME($sp)
-
- $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
- $PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
- $PUSH r13,`$FRAME-$SIZE_T*19`($sp)
- $PUSH r14,`$FRAME-$SIZE_T*18`($sp)
- $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
- $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
- $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
- $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
- $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
- $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
- $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
- $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
- $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
- $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
- $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
- $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
- $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
- $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
- $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
- $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
- $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
-
- lwz $s0,0($inp)
- lwz $s1,4($inp)
- lwz $s2,8($inp)
- lwz $s3,12($inp)
- bl LAES_Te
- bl Lppc_AES_encrypt_compact
- stw $s0,0($out)
- stw $s1,4($out)
- stw $s2,8($out)
- stw $s3,12($out)
-
- $POP r0,`$FRAME-$SIZE_T*21`($sp)
- $POP $toc,`$FRAME-$SIZE_T*20`($sp)
- $POP r13,`$FRAME-$SIZE_T*19`($sp)
- $POP r14,`$FRAME-$SIZE_T*18`($sp)
- $POP r15,`$FRAME-$SIZE_T*17`($sp)
- $POP r16,`$FRAME-$SIZE_T*16`($sp)
- $POP r17,`$FRAME-$SIZE_T*15`($sp)
- $POP r18,`$FRAME-$SIZE_T*14`($sp)
- $POP r19,`$FRAME-$SIZE_T*13`($sp)
- $POP r20,`$FRAME-$SIZE_T*12`($sp)
- $POP r21,`$FRAME-$SIZE_T*11`($sp)
- $POP r22,`$FRAME-$SIZE_T*10`($sp)
- $POP r23,`$FRAME-$SIZE_T*9`($sp)
- $POP r24,`$FRAME-$SIZE_T*8`($sp)
- $POP r25,`$FRAME-$SIZE_T*7`($sp)
- $POP r26,`$FRAME-$SIZE_T*6`($sp)
- $POP r27,`$FRAME-$SIZE_T*5`($sp)
- $POP r28,`$FRAME-$SIZE_T*4`($sp)
- $POP r29,`$FRAME-$SIZE_T*3`($sp)
- $POP r30,`$FRAME-$SIZE_T*2`($sp)
- $POP r31,`$FRAME-$SIZE_T*1`($sp)
- mtlr r0
- addi $sp,$sp,$FRAME
- blr
-
-.align 4
-Lppc_AES_encrypt:
- lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
- addi $Tbl1,$Tbl0,3
- addi $Tbl2,$Tbl0,2
- addi $Tbl3,$Tbl0,1
- addi $acc00,$acc00,-1
- addi $key,$key,16
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- mtctr $acc00
-.align 4
-Lenc_loop:
- rlwinm $acc00,$s0,`32-24+3`,21,28
- rlwinm $acc01,$s1,`32-24+3`,21,28
- lwz $t0,0($key)
- lwz $t1,4($key)
- rlwinm $acc02,$s2,`32-24+3`,21,28
- rlwinm $acc03,$s3,`32-24+3`,21,28
- lwz $t2,8($key)
- lwz $t3,12($key)
- rlwinm $acc04,$s1,`32-16+3`,21,28
- rlwinm $acc05,$s2,`32-16+3`,21,28
- lwzx $acc00,$Tbl0,$acc00
- lwzx $acc01,$Tbl0,$acc01
- rlwinm $acc06,$s3,`32-16+3`,21,28
- rlwinm $acc07,$s0,`32-16+3`,21,28
- lwzx $acc02,$Tbl0,$acc02
- lwzx $acc03,$Tbl0,$acc03
- rlwinm $acc08,$s2,`32-8+3`,21,28
- rlwinm $acc09,$s3,`32-8+3`,21,28
- lwzx $acc04,$Tbl1,$acc04
- lwzx $acc05,$Tbl1,$acc05
- rlwinm $acc10,$s0,`32-8+3`,21,28
- rlwinm $acc11,$s1,`32-8+3`,21,28
- lwzx $acc06,$Tbl1,$acc06
- lwzx $acc07,$Tbl1,$acc07
- rlwinm $acc12,$s3,`0+3`,21,28
- rlwinm $acc13,$s0,`0+3`,21,28
- lwzx $acc08,$Tbl2,$acc08
- lwzx $acc09,$Tbl2,$acc09
- rlwinm $acc14,$s1,`0+3`,21,28
- rlwinm $acc15,$s2,`0+3`,21,28
- lwzx $acc10,$Tbl2,$acc10
- lwzx $acc11,$Tbl2,$acc11
- xor $t0,$t0,$acc00
- xor $t1,$t1,$acc01
- lwzx $acc12,$Tbl3,$acc12
- lwzx $acc13,$Tbl3,$acc13
- xor $t2,$t2,$acc02
- xor $t3,$t3,$acc03
- lwzx $acc14,$Tbl3,$acc14
- lwzx $acc15,$Tbl3,$acc15
- xor $t0,$t0,$acc04
- xor $t1,$t1,$acc05
- xor $t2,$t2,$acc06
- xor $t3,$t3,$acc07
- xor $t0,$t0,$acc08
- xor $t1,$t1,$acc09
- xor $t2,$t2,$acc10
- xor $t3,$t3,$acc11
- xor $s0,$t0,$acc12
- xor $s1,$t1,$acc13
- xor $s2,$t2,$acc14
- xor $s3,$t3,$acc15
- addi $key,$key,16
- bdnz- Lenc_loop
-
- addi $Tbl2,$Tbl0,2048
- nop
- lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4
- lwz $acc09,`2048+32`($Tbl0)
- lwz $acc10,`2048+64`($Tbl0)
- lwz $acc11,`2048+96`($Tbl0)
- lwz $acc08,`2048+128`($Tbl0)
- lwz $acc09,`2048+160`($Tbl0)
- lwz $acc10,`2048+192`($Tbl0)
- lwz $acc11,`2048+224`($Tbl0)
- rlwinm $acc00,$s0,`32-24`,24,31
- rlwinm $acc01,$s1,`32-24`,24,31
- lwz $t0,0($key)
- lwz $t1,4($key)
- rlwinm $acc02,$s2,`32-24`,24,31
- rlwinm $acc03,$s3,`32-24`,24,31
- lwz $t2,8($key)
- lwz $t3,12($key)
- rlwinm $acc04,$s1,`32-16`,24,31
- rlwinm $acc05,$s2,`32-16`,24,31
- lbzx $acc00,$Tbl2,$acc00
- lbzx $acc01,$Tbl2,$acc01
- rlwinm $acc06,$s3,`32-16`,24,31
- rlwinm $acc07,$s0,`32-16`,24,31
- lbzx $acc02,$Tbl2,$acc02
- lbzx $acc03,$Tbl2,$acc03
- rlwinm $acc08,$s2,`32-8`,24,31
- rlwinm $acc09,$s3,`32-8`,24,31
- lbzx $acc04,$Tbl2,$acc04
- lbzx $acc05,$Tbl2,$acc05
- rlwinm $acc10,$s0,`32-8`,24,31
- rlwinm $acc11,$s1,`32-8`,24,31
- lbzx $acc06,$Tbl2,$acc06
- lbzx $acc07,$Tbl2,$acc07
- rlwinm $acc12,$s3,`0`,24,31
- rlwinm $acc13,$s0,`0`,24,31
- lbzx $acc08,$Tbl2,$acc08
- lbzx $acc09,$Tbl2,$acc09
- rlwinm $acc14,$s1,`0`,24,31
- rlwinm $acc15,$s2,`0`,24,31
- lbzx $acc10,$Tbl2,$acc10
- lbzx $acc11,$Tbl2,$acc11
- rlwinm $s0,$acc00,24,0,7
- rlwinm $s1,$acc01,24,0,7
- lbzx $acc12,$Tbl2,$acc12
- lbzx $acc13,$Tbl2,$acc13
- rlwinm $s2,$acc02,24,0,7
- rlwinm $s3,$acc03,24,0,7
- lbzx $acc14,$Tbl2,$acc14
- lbzx $acc15,$Tbl2,$acc15
- rlwimi $s0,$acc04,16,8,15
- rlwimi $s1,$acc05,16,8,15
- rlwimi $s2,$acc06,16,8,15
- rlwimi $s3,$acc07,16,8,15
- rlwimi $s0,$acc08,8,16,23
- rlwimi $s1,$acc09,8,16,23
- rlwimi $s2,$acc10,8,16,23
- rlwimi $s3,$acc11,8,16,23
- or $s0,$s0,$acc12
- or $s1,$s1,$acc13
- or $s2,$s2,$acc14
- or $s3,$s3,$acc15
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- blr
-
-.align 4
-Lppc_AES_encrypt_compact:
- lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
- addi $Tbl1,$Tbl0,2048
- lis $mask80,0x8080
- lis $mask1b,0x1b1b
- addi $key,$key,16
- ori $mask80,$mask80,0x8080
- ori $mask1b,$mask1b,0x1b1b
- mtctr $acc00
-.align 4
-Lenc_compact_loop:
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- rlwinm $acc00,$s0,`32-24`,24,31
- rlwinm $acc01,$s1,`32-24`,24,31
- rlwinm $acc02,$s2,`32-24`,24,31
- rlwinm $acc03,$s3,`32-24`,24,31
- lbzx $acc00,$Tbl1,$acc00
- lbzx $acc01,$Tbl1,$acc01
- rlwinm $acc04,$s1,`32-16`,24,31
- rlwinm $acc05,$s2,`32-16`,24,31
- lbzx $acc02,$Tbl1,$acc02
- lbzx $acc03,$Tbl1,$acc03
- rlwinm $acc06,$s3,`32-16`,24,31
- rlwinm $acc07,$s0,`32-16`,24,31
- lbzx $acc04,$Tbl1,$acc04
- lbzx $acc05,$Tbl1,$acc05
- rlwinm $acc08,$s2,`32-8`,24,31
- rlwinm $acc09,$s3,`32-8`,24,31
- lbzx $acc06,$Tbl1,$acc06
- lbzx $acc07,$Tbl1,$acc07
- rlwinm $acc10,$s0,`32-8`,24,31
- rlwinm $acc11,$s1,`32-8`,24,31
- lbzx $acc08,$Tbl1,$acc08
- lbzx $acc09,$Tbl1,$acc09
- rlwinm $acc12,$s3,`0`,24,31
- rlwinm $acc13,$s0,`0`,24,31
- lbzx $acc10,$Tbl1,$acc10
- lbzx $acc11,$Tbl1,$acc11
- rlwinm $acc14,$s1,`0`,24,31
- rlwinm $acc15,$s2,`0`,24,31
- lbzx $acc12,$Tbl1,$acc12
- lbzx $acc13,$Tbl1,$acc13
- rlwinm $s0,$acc00,24,0,7
- rlwinm $s1,$acc01,24,0,7
- lbzx $acc14,$Tbl1,$acc14
- lbzx $acc15,$Tbl1,$acc15
- rlwinm $s2,$acc02,24,0,7
- rlwinm $s3,$acc03,24,0,7
- rlwimi $s0,$acc04,16,8,15
- rlwimi $s1,$acc05,16,8,15
- rlwimi $s2,$acc06,16,8,15
- rlwimi $s3,$acc07,16,8,15
- rlwimi $s0,$acc08,8,16,23
- rlwimi $s1,$acc09,8,16,23
- rlwimi $s2,$acc10,8,16,23
- rlwimi $s3,$acc11,8,16,23
- lwz $t0,0($key)
- lwz $t1,4($key)
- or $s0,$s0,$acc12
- or $s1,$s1,$acc13
- lwz $t2,8($key)
- lwz $t3,12($key)
- or $s2,$s2,$acc14
- or $s3,$s3,$acc15
-
- addi $key,$key,16
- bdz Lenc_compact_done
-
- and $acc00,$s0,$mask80 # r1=r0&0x80808080
- and $acc01,$s1,$mask80
- and $acc02,$s2,$mask80
- and $acc03,$s3,$mask80
- srwi $acc04,$acc00,7 # r1>>7
- srwi $acc05,$acc01,7
- srwi $acc06,$acc02,7
- srwi $acc07,$acc03,7
- andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f
- andc $acc09,$s1,$mask80
- andc $acc10,$s2,$mask80
- andc $acc11,$s3,$mask80
- sub $acc00,$acc00,$acc04 # r1-(r1>>7)
- sub $acc01,$acc01,$acc05
- sub $acc02,$acc02,$acc06
- sub $acc03,$acc03,$acc07
- add $acc08,$acc08,$acc08 # (r0&0x7f7f7f7f)<<1
- add $acc09,$acc09,$acc09
- add $acc10,$acc10,$acc10
- add $acc11,$acc11,$acc11
- and $acc00,$acc00,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc01,$acc01,$mask1b
- and $acc02,$acc02,$mask1b
- and $acc03,$acc03,$mask1b
- xor $acc00,$acc00,$acc08 # r2
- xor $acc01,$acc01,$acc09
- xor $acc02,$acc02,$acc10
- xor $acc03,$acc03,$acc11
-
- rotlwi $acc12,$s0,16 # ROTATE(r0,16)
- rotlwi $acc13,$s1,16
- rotlwi $acc14,$s2,16
- rotlwi $acc15,$s3,16
- xor $s0,$s0,$acc00 # r0^r2
- xor $s1,$s1,$acc01
- xor $s2,$s2,$acc02
- xor $s3,$s3,$acc03
- rotrwi $s0,$s0,24 # ROTATE(r2^r0,24)
- rotrwi $s1,$s1,24
- rotrwi $s2,$s2,24
- rotrwi $s3,$s3,24
- xor $s0,$s0,$acc00 # ROTATE(r2^r0,24)^r2
- xor $s1,$s1,$acc01
- xor $s2,$s2,$acc02
- xor $s3,$s3,$acc03
- rotlwi $acc08,$acc12,8 # ROTATE(r0,24)
- rotlwi $acc09,$acc13,8
- rotlwi $acc10,$acc14,8
- rotlwi $acc11,$acc15,8
- xor $s0,$s0,$acc12 #
- xor $s1,$s1,$acc13
- xor $s2,$s2,$acc14
- xor $s3,$s3,$acc15
- xor $s0,$s0,$acc08 #
- xor $s1,$s1,$acc09
- xor $s2,$s2,$acc10
- xor $s3,$s3,$acc11
-
- b Lenc_compact_loop
-.align 4
-Lenc_compact_done:
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- blr
-
-.globl .AES_decrypt
-.align 7
-.AES_decrypt:
- mflr r0
- $STU $sp,-$FRAME($sp)
-
- $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
- $PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
- $PUSH r13,`$FRAME-$SIZE_T*19`($sp)
- $PUSH r14,`$FRAME-$SIZE_T*18`($sp)
- $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
- $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
- $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
- $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
- $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
- $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
- $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
- $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
- $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
- $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
- $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
- $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
- $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
- $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
- $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
- $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
- $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
-
- lwz $s0,0($inp)
- lwz $s1,4($inp)
- lwz $s2,8($inp)
- lwz $s3,12($inp)
- bl LAES_Td
- bl Lppc_AES_decrypt_compact
- stw $s0,0($out)
- stw $s1,4($out)
- stw $s2,8($out)
- stw $s3,12($out)
-
- $POP r0,`$FRAME-$SIZE_T*21`($sp)
- $POP $toc,`$FRAME-$SIZE_T*20`($sp)
- $POP r13,`$FRAME-$SIZE_T*19`($sp)
- $POP r14,`$FRAME-$SIZE_T*18`($sp)
- $POP r15,`$FRAME-$SIZE_T*17`($sp)
- $POP r16,`$FRAME-$SIZE_T*16`($sp)
- $POP r17,`$FRAME-$SIZE_T*15`($sp)
- $POP r18,`$FRAME-$SIZE_T*14`($sp)
- $POP r19,`$FRAME-$SIZE_T*13`($sp)
- $POP r20,`$FRAME-$SIZE_T*12`($sp)
- $POP r21,`$FRAME-$SIZE_T*11`($sp)
- $POP r22,`$FRAME-$SIZE_T*10`($sp)
- $POP r23,`$FRAME-$SIZE_T*9`($sp)
- $POP r24,`$FRAME-$SIZE_T*8`($sp)
- $POP r25,`$FRAME-$SIZE_T*7`($sp)
- $POP r26,`$FRAME-$SIZE_T*6`($sp)
- $POP r27,`$FRAME-$SIZE_T*5`($sp)
- $POP r28,`$FRAME-$SIZE_T*4`($sp)
- $POP r29,`$FRAME-$SIZE_T*3`($sp)
- $POP r30,`$FRAME-$SIZE_T*2`($sp)
- $POP r31,`$FRAME-$SIZE_T*1`($sp)
- mtlr r0
- addi $sp,$sp,$FRAME
- blr
-
-.align 4
-Lppc_AES_decrypt:
- lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
- addi $Tbl1,$Tbl0,3
- addi $Tbl2,$Tbl0,2
- addi $Tbl3,$Tbl0,1
- addi $acc00,$acc00,-1
- addi $key,$key,16
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- mtctr $acc00
-.align 4
-Ldec_loop:
- rlwinm $acc00,$s0,`32-24+3`,21,28
- rlwinm $acc01,$s1,`32-24+3`,21,28
- lwz $t0,0($key)
- lwz $t1,4($key)
- rlwinm $acc02,$s2,`32-24+3`,21,28
- rlwinm $acc03,$s3,`32-24+3`,21,28
- lwz $t2,8($key)
- lwz $t3,12($key)
- rlwinm $acc04,$s3,`32-16+3`,21,28
- rlwinm $acc05,$s0,`32-16+3`,21,28
- lwzx $acc00,$Tbl0,$acc00
- lwzx $acc01,$Tbl0,$acc01
- rlwinm $acc06,$s1,`32-16+3`,21,28
- rlwinm $acc07,$s2,`32-16+3`,21,28
- lwzx $acc02,$Tbl0,$acc02
- lwzx $acc03,$Tbl0,$acc03
- rlwinm $acc08,$s2,`32-8+3`,21,28
- rlwinm $acc09,$s3,`32-8+3`,21,28
- lwzx $acc04,$Tbl1,$acc04
- lwzx $acc05,$Tbl1,$acc05
- rlwinm $acc10,$s0,`32-8+3`,21,28
- rlwinm $acc11,$s1,`32-8+3`,21,28
- lwzx $acc06,$Tbl1,$acc06
- lwzx $acc07,$Tbl1,$acc07
- rlwinm $acc12,$s1,`0+3`,21,28
- rlwinm $acc13,$s2,`0+3`,21,28
- lwzx $acc08,$Tbl2,$acc08
- lwzx $acc09,$Tbl2,$acc09
- rlwinm $acc14,$s3,`0+3`,21,28
- rlwinm $acc15,$s0,`0+3`,21,28
- lwzx $acc10,$Tbl2,$acc10
- lwzx $acc11,$Tbl2,$acc11
- xor $t0,$t0,$acc00
- xor $t1,$t1,$acc01
- lwzx $acc12,$Tbl3,$acc12
- lwzx $acc13,$Tbl3,$acc13
- xor $t2,$t2,$acc02
- xor $t3,$t3,$acc03
- lwzx $acc14,$Tbl3,$acc14
- lwzx $acc15,$Tbl3,$acc15
- xor $t0,$t0,$acc04
- xor $t1,$t1,$acc05
- xor $t2,$t2,$acc06
- xor $t3,$t3,$acc07
- xor $t0,$t0,$acc08
- xor $t1,$t1,$acc09
- xor $t2,$t2,$acc10
- xor $t3,$t3,$acc11
- xor $s0,$t0,$acc12
- xor $s1,$t1,$acc13
- xor $s2,$t2,$acc14
- xor $s3,$t3,$acc15
- addi $key,$key,16
- bdnz- Ldec_loop
-
- addi $Tbl2,$Tbl0,2048
- nop
- lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4
- lwz $acc09,`2048+32`($Tbl0)
- lwz $acc10,`2048+64`($Tbl0)
- lwz $acc11,`2048+96`($Tbl0)
- lwz $acc08,`2048+128`($Tbl0)
- lwz $acc09,`2048+160`($Tbl0)
- lwz $acc10,`2048+192`($Tbl0)
- lwz $acc11,`2048+224`($Tbl0)
- rlwinm $acc00,$s0,`32-24`,24,31
- rlwinm $acc01,$s1,`32-24`,24,31
- lwz $t0,0($key)
- lwz $t1,4($key)
- rlwinm $acc02,$s2,`32-24`,24,31
- rlwinm $acc03,$s3,`32-24`,24,31
- lwz $t2,8($key)
- lwz $t3,12($key)
- rlwinm $acc04,$s3,`32-16`,24,31
- rlwinm $acc05,$s0,`32-16`,24,31
- lbzx $acc00,$Tbl2,$acc00
- lbzx $acc01,$Tbl2,$acc01
- rlwinm $acc06,$s1,`32-16`,24,31
- rlwinm $acc07,$s2,`32-16`,24,31
- lbzx $acc02,$Tbl2,$acc02
- lbzx $acc03,$Tbl2,$acc03
- rlwinm $acc08,$s2,`32-8`,24,31
- rlwinm $acc09,$s3,`32-8`,24,31
- lbzx $acc04,$Tbl2,$acc04
- lbzx $acc05,$Tbl2,$acc05
- rlwinm $acc10,$s0,`32-8`,24,31
- rlwinm $acc11,$s1,`32-8`,24,31
- lbzx $acc06,$Tbl2,$acc06
- lbzx $acc07,$Tbl2,$acc07
- rlwinm $acc12,$s1,`0`,24,31
- rlwinm $acc13,$s2,`0`,24,31
- lbzx $acc08,$Tbl2,$acc08
- lbzx $acc09,$Tbl2,$acc09
- rlwinm $acc14,$s3,`0`,24,31
- rlwinm $acc15,$s0,`0`,24,31
- lbzx $acc10,$Tbl2,$acc10
- lbzx $acc11,$Tbl2,$acc11
- rlwinm $s0,$acc00,24,0,7
- rlwinm $s1,$acc01,24,0,7
- lbzx $acc12,$Tbl2,$acc12
- lbzx $acc13,$Tbl2,$acc13
- rlwinm $s2,$acc02,24,0,7
- rlwinm $s3,$acc03,24,0,7
- lbzx $acc14,$Tbl2,$acc14
- lbzx $acc15,$Tbl2,$acc15
- rlwimi $s0,$acc04,16,8,15
- rlwimi $s1,$acc05,16,8,15
- rlwimi $s2,$acc06,16,8,15
- rlwimi $s3,$acc07,16,8,15
- rlwimi $s0,$acc08,8,16,23
- rlwimi $s1,$acc09,8,16,23
- rlwimi $s2,$acc10,8,16,23
- rlwimi $s3,$acc11,8,16,23
- or $s0,$s0,$acc12
- or $s1,$s1,$acc13
- or $s2,$s2,$acc14
- or $s3,$s3,$acc15
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- blr
-
-.align 4
-Lppc_AES_decrypt_compact:
- lwz $acc00,240($key)
- lwz $t0,0($key)
- lwz $t1,4($key)
- lwz $t2,8($key)
- lwz $t3,12($key)
- addi $Tbl1,$Tbl0,2048
- lis $mask80,0x8080
- lis $mask1b,0x1b1b
- addi $key,$key,16
- ori $mask80,$mask80,0x8080
- ori $mask1b,$mask1b,0x1b1b
-___
-$code.=<<___ if ($SIZE_T==8);
- insrdi $mask80,$mask80,32,0
- insrdi $mask1b,$mask1b,32,0
-___
-$code.=<<___;
- mtctr $acc00
-.align 4
-Ldec_compact_loop:
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- rlwinm $acc00,$s0,`32-24`,24,31
- rlwinm $acc01,$s1,`32-24`,24,31
- rlwinm $acc02,$s2,`32-24`,24,31
- rlwinm $acc03,$s3,`32-24`,24,31
- lbzx $acc00,$Tbl1,$acc00
- lbzx $acc01,$Tbl1,$acc01
- rlwinm $acc04,$s3,`32-16`,24,31
- rlwinm $acc05,$s0,`32-16`,24,31
- lbzx $acc02,$Tbl1,$acc02
- lbzx $acc03,$Tbl1,$acc03
- rlwinm $acc06,$s1,`32-16`,24,31
- rlwinm $acc07,$s2,`32-16`,24,31
- lbzx $acc04,$Tbl1,$acc04
- lbzx $acc05,$Tbl1,$acc05
- rlwinm $acc08,$s2,`32-8`,24,31
- rlwinm $acc09,$s3,`32-8`,24,31
- lbzx $acc06,$Tbl1,$acc06
- lbzx $acc07,$Tbl1,$acc07
- rlwinm $acc10,$s0,`32-8`,24,31
- rlwinm $acc11,$s1,`32-8`,24,31
- lbzx $acc08,$Tbl1,$acc08
- lbzx $acc09,$Tbl1,$acc09
- rlwinm $acc12,$s1,`0`,24,31
- rlwinm $acc13,$s2,`0`,24,31
- lbzx $acc10,$Tbl1,$acc10
- lbzx $acc11,$Tbl1,$acc11
- rlwinm $acc14,$s3,`0`,24,31
- rlwinm $acc15,$s0,`0`,24,31
- lbzx $acc12,$Tbl1,$acc12
- lbzx $acc13,$Tbl1,$acc13
- rlwinm $s0,$acc00,24,0,7
- rlwinm $s1,$acc01,24,0,7
- lbzx $acc14,$Tbl1,$acc14
- lbzx $acc15,$Tbl1,$acc15
- rlwinm $s2,$acc02,24,0,7
- rlwinm $s3,$acc03,24,0,7
- rlwimi $s0,$acc04,16,8,15
- rlwimi $s1,$acc05,16,8,15
- rlwimi $s2,$acc06,16,8,15
- rlwimi $s3,$acc07,16,8,15
- rlwimi $s0,$acc08,8,16,23
- rlwimi $s1,$acc09,8,16,23
- rlwimi $s2,$acc10,8,16,23
- rlwimi $s3,$acc11,8,16,23
- lwz $t0,0($key)
- lwz $t1,4($key)
- or $s0,$s0,$acc12
- or $s1,$s1,$acc13
- lwz $t2,8($key)
- lwz $t3,12($key)
- or $s2,$s2,$acc14
- or $s3,$s3,$acc15
-
- addi $key,$key,16
- bdz Ldec_compact_done
-___
-$code.=<<___ if ($SIZE_T==8);
- # vectorized permutation improves decrypt performance by 10%
- insrdi $s0,$s1,32,0
- insrdi $s2,$s3,32,0
-
- and $acc00,$s0,$mask80 # r1=r0&0x80808080
- and $acc02,$s2,$mask80
- srdi $acc04,$acc00,7 # r1>>7
- srdi $acc06,$acc02,7
- andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f
- andc $acc10,$s2,$mask80
- sub $acc00,$acc00,$acc04 # r1-(r1>>7)
- sub $acc02,$acc02,$acc06
- add $acc08,$acc08,$acc08 # (r0&0x7f7f7f7f)<<1
- add $acc10,$acc10,$acc10
- and $acc00,$acc00,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc02,$acc02,$mask1b
- xor $acc00,$acc00,$acc08 # r2
- xor $acc02,$acc02,$acc10
-
- and $acc04,$acc00,$mask80 # r1=r2&0x80808080
- and $acc06,$acc02,$mask80
- srdi $acc08,$acc04,7 # r1>>7
- srdi $acc10,$acc06,7
- andc $acc12,$acc00,$mask80 # r2&0x7f7f7f7f
- andc $acc14,$acc02,$mask80
- sub $acc04,$acc04,$acc08 # r1-(r1>>7)
- sub $acc06,$acc06,$acc10
- add $acc12,$acc12,$acc12 # (r2&0x7f7f7f7f)<<1
- add $acc14,$acc14,$acc14
- and $acc04,$acc04,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc06,$acc06,$mask1b
- xor $acc04,$acc04,$acc12 # r4
- xor $acc06,$acc06,$acc14
-
- and $acc08,$acc04,$mask80 # r1=r4&0x80808080
- and $acc10,$acc06,$mask80
- srdi $acc12,$acc08,7 # r1>>7
- srdi $acc14,$acc10,7
- sub $acc08,$acc08,$acc12 # r1-(r1>>7)
- sub $acc10,$acc10,$acc14
- andc $acc12,$acc04,$mask80 # r4&0x7f7f7f7f
- andc $acc14,$acc06,$mask80
- add $acc12,$acc12,$acc12 # (r4&0x7f7f7f7f)<<1
- add $acc14,$acc14,$acc14
- and $acc08,$acc08,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc10,$acc10,$mask1b
- xor $acc08,$acc08,$acc12 # r8
- xor $acc10,$acc10,$acc14
-
- xor $acc00,$acc00,$s0 # r2^r0
- xor $acc02,$acc02,$s2
- xor $acc04,$acc04,$s0 # r4^r0
- xor $acc06,$acc06,$s2
-
- extrdi $acc01,$acc00,32,0
- extrdi $acc03,$acc02,32,0
- extrdi $acc05,$acc04,32,0
- extrdi $acc07,$acc06,32,0
- extrdi $acc09,$acc08,32,0
- extrdi $acc11,$acc10,32,0
-___
-$code.=<<___ if ($SIZE_T==4);
- and $acc00,$s0,$mask80 # r1=r0&0x80808080
- and $acc01,$s1,$mask80
- and $acc02,$s2,$mask80
- and $acc03,$s3,$mask80
- srwi $acc04,$acc00,7 # r1>>7
- srwi $acc05,$acc01,7
- srwi $acc06,$acc02,7
- srwi $acc07,$acc03,7
- andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f
- andc $acc09,$s1,$mask80
- andc $acc10,$s2,$mask80
- andc $acc11,$s3,$mask80
- sub $acc00,$acc00,$acc04 # r1-(r1>>7)
- sub $acc01,$acc01,$acc05
- sub $acc02,$acc02,$acc06
- sub $acc03,$acc03,$acc07
- add $acc08,$acc08,$acc08 # (r0&0x7f7f7f7f)<<1
- add $acc09,$acc09,$acc09
- add $acc10,$acc10,$acc10
- add $acc11,$acc11,$acc11
- and $acc00,$acc00,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc01,$acc01,$mask1b
- and $acc02,$acc02,$mask1b
- and $acc03,$acc03,$mask1b
- xor $acc00,$acc00,$acc08 # r2
- xor $acc01,$acc01,$acc09
- xor $acc02,$acc02,$acc10
- xor $acc03,$acc03,$acc11
-
- and $acc04,$acc00,$mask80 # r1=r2&0x80808080
- and $acc05,$acc01,$mask80
- and $acc06,$acc02,$mask80
- and $acc07,$acc03,$mask80
- srwi $acc08,$acc04,7 # r1>>7
- srwi $acc09,$acc05,7
- srwi $acc10,$acc06,7
- srwi $acc11,$acc07,7
- andc $acc12,$acc00,$mask80 # r2&0x7f7f7f7f
- andc $acc13,$acc01,$mask80
- andc $acc14,$acc02,$mask80
- andc $acc15,$acc03,$mask80
- sub $acc04,$acc04,$acc08 # r1-(r1>>7)
- sub $acc05,$acc05,$acc09
- sub $acc06,$acc06,$acc10
- sub $acc07,$acc07,$acc11
- add $acc12,$acc12,$acc12 # (r2&0x7f7f7f7f)<<1
- add $acc13,$acc13,$acc13
- add $acc14,$acc14,$acc14
- add $acc15,$acc15,$acc15
- and $acc04,$acc04,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc05,$acc05,$mask1b
- and $acc06,$acc06,$mask1b
- and $acc07,$acc07,$mask1b
- xor $acc04,$acc04,$acc12 # r4
- xor $acc05,$acc05,$acc13
- xor $acc06,$acc06,$acc14
- xor $acc07,$acc07,$acc15
-
- and $acc08,$acc04,$mask80 # r1=r4&0x80808080
- and $acc09,$acc05,$mask80
- and $acc10,$acc06,$mask80
- and $acc11,$acc07,$mask80
- srwi $acc12,$acc08,7 # r1>>7
- srwi $acc13,$acc09,7
- srwi $acc14,$acc10,7
- srwi $acc15,$acc11,7
- sub $acc08,$acc08,$acc12 # r1-(r1>>7)
- sub $acc09,$acc09,$acc13
- sub $acc10,$acc10,$acc14
- sub $acc11,$acc11,$acc15
- andc $acc12,$acc04,$mask80 # r4&0x7f7f7f7f
- andc $acc13,$acc05,$mask80
- andc $acc14,$acc06,$mask80
- andc $acc15,$acc07,$mask80
- add $acc12,$acc12,$acc12 # (r4&0x7f7f7f7f)<<1
- add $acc13,$acc13,$acc13
- add $acc14,$acc14,$acc14
- add $acc15,$acc15,$acc15
- and $acc08,$acc08,$mask1b # (r1-(r1>>7))&0x1b1b1b1b
- and $acc09,$acc09,$mask1b
- and $acc10,$acc10,$mask1b
- and $acc11,$acc11,$mask1b
- xor $acc08,$acc08,$acc12 # r8
- xor $acc09,$acc09,$acc13
- xor $acc10,$acc10,$acc14
- xor $acc11,$acc11,$acc15
-
- xor $acc00,$acc00,$s0 # r2^r0
- xor $acc01,$acc01,$s1
- xor $acc02,$acc02,$s2
- xor $acc03,$acc03,$s3
- xor $acc04,$acc04,$s0 # r4^r0
- xor $acc05,$acc05,$s1
- xor $acc06,$acc06,$s2
- xor $acc07,$acc07,$s3
-___
-$code.=<<___;
- rotrwi $s0,$s0,8 # = ROTATE(r0,8)
- rotrwi $s1,$s1,8
- rotrwi $s2,$s2,8
- rotrwi $s3,$s3,8
- xor $s0,$s0,$acc00 # ^= r2^r0
- xor $s1,$s1,$acc01
- xor $s2,$s2,$acc02
- xor $s3,$s3,$acc03
- xor $acc00,$acc00,$acc08
- xor $acc01,$acc01,$acc09
- xor $acc02,$acc02,$acc10
- xor $acc03,$acc03,$acc11
- xor $s0,$s0,$acc04 # ^= r4^r0
- xor $s1,$s1,$acc05
- xor $s2,$s2,$acc06
- xor $s3,$s3,$acc07
- rotrwi $acc00,$acc00,24
- rotrwi $acc01,$acc01,24
- rotrwi $acc02,$acc02,24
- rotrwi $acc03,$acc03,24
- xor $acc04,$acc04,$acc08
- xor $acc05,$acc05,$acc09
- xor $acc06,$acc06,$acc10
- xor $acc07,$acc07,$acc11
- xor $s0,$s0,$acc08 # ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
- xor $s1,$s1,$acc09
- xor $s2,$s2,$acc10
- xor $s3,$s3,$acc11
- rotrwi $acc04,$acc04,16
- rotrwi $acc05,$acc05,16
- rotrwi $acc06,$acc06,16
- rotrwi $acc07,$acc07,16
- xor $s0,$s0,$acc00 # ^= ROTATE(r8^r2^r0,24)
- xor $s1,$s1,$acc01
- xor $s2,$s2,$acc02
- xor $s3,$s3,$acc03
- rotrwi $acc08,$acc08,8
- rotrwi $acc09,$acc09,8
- rotrwi $acc10,$acc10,8
- rotrwi $acc11,$acc11,8
- xor $s0,$s0,$acc04 # ^= ROTATE(r8^r4^r0,16)
- xor $s1,$s1,$acc05
- xor $s2,$s2,$acc06
- xor $s3,$s3,$acc07
- xor $s0,$s0,$acc08 # ^= ROTATE(r8,8)
- xor $s1,$s1,$acc09
- xor $s2,$s2,$acc10
- xor $s3,$s3,$acc11
-
- b Ldec_compact_loop
-.align 4
-Ldec_compact_done:
- xor $s0,$s0,$t0
- xor $s1,$s1,$t1
- xor $s2,$s2,$t2
- xor $s3,$s3,$t3
- blr
-.long 0
-.asciz "AES for PPC, CRYPTOGAMS by <appro\@openssl.org>"
-.align 7
-___
-
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/aes/asm/aes-s390x.pl b/crypto/openssl/crypto/aes/asm/aes-s390x.pl
deleted file mode 100755
index 4b27afd..0000000
--- a/crypto/openssl/crypto/aes/asm/aes-s390x.pl
+++ /dev/null
@@ -1,1333 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# AES for s390x.
-
-# April 2007.
-#
-# Software performance improvement over gcc-generated code is ~70% and
-# in absolute terms is ~73 cycles per byte processed with 128-bit key.
-# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
-# *strictly* in-order execution and issued instruction [in this case
-# load value from memory is critical] has to complete before execution
-# flow proceeds. S-boxes are compressed to 2KB[+256B].
-#
-# As for hardware acceleration support. It's basically a "teaser," as
-# it can and should be improved in several ways. Most notably support
-# for CBC is not utilized, nor multiple blocks are ever processed.
-# Then software key schedule can be postponed till hardware support
-# detection... Performance improvement over assembler is reportedly
-# ~2.5x, but can reach >8x [naturally on larger chunks] if proper
-# support is implemented.
-
-# May 2007.
-#
-# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
-# for 128-bit keys, if hardware support is detected.
-
-# Januray 2009.
-#
-# Add support for hardware AES192/256 and reschedule instructions to
-# minimize/avoid Address Generation Interlock hazard and to favour
-# dual-issue z10 pipeline. This gave ~25% improvement on z10 and
-# almost 50% on z9. The gain is smaller on z10, because being dual-
-# issue z10 makes it improssible to eliminate the interlock condition:
-# critial path is not long enough. Yet it spends ~24 cycles per byte
-# processed with 128-bit key.
-#
-# Unlike previous version hardware support detection takes place only
-# at the moment of key schedule setup, which is denoted in key->rounds.
-# This is done, because deferred key setup can't be made MT-safe, not
-# for key lengthes longer than 128 bits.
-#
-# Add AES_cbc_encrypt, which gives incredible performance improvement,
-# it was measured to be ~6.6x. It's less than previously mentioned 8x,
-# because software implementation was optimized.
-
-$softonly=0; # allow hardware support
-
-$t0="%r0"; $mask="%r0";
-$t1="%r1";
-$t2="%r2"; $inp="%r2";
-$t3="%r3"; $out="%r3"; $bits="%r3";
-$key="%r4";
-$i1="%r5";
-$i2="%r6";
-$i3="%r7";
-$s0="%r8";
-$s1="%r9";
-$s2="%r10";
-$s3="%r11";
-$tbl="%r12";
-$rounds="%r13";
-$ra="%r14";
-$sp="%r15";
-
-sub _data_word()
-{ my $i;
- while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
-}
-
-$code=<<___;
-.text
-
-.type AES_Te,\@object
-.align 256
-AES_Te:
-___
-&_data_word(
- 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
- 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
- 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
- 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
- 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
- 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
- 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
- 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
- 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
- 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
- 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
- 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
- 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
- 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
- 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
- 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
- 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
- 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
- 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
- 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
- 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
- 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
- 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
- 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
- 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
- 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
- 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
- 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
- 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
- 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
- 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
- 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
- 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
- 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
- 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
- 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
- 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
- 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
- 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
- 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
- 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
- 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
- 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
- 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
- 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
- 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
- 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
- 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
- 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
- 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
- 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
- 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
- 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
- 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
- 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
- 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
- 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
- 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
- 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
- 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
- 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
- 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
- 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
- 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
-$code.=<<___;
-# Te4[256]
-.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-# rcon[]
-.long 0x01000000, 0x02000000, 0x04000000, 0x08000000
-.long 0x10000000, 0x20000000, 0x40000000, 0x80000000
-.long 0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
-.align 256
-.size AES_Te,.-AES_Te
-
-# void AES_encrypt(const unsigned char *inp, unsigned char *out,
-# const AES_KEY *key) {
-.globl AES_encrypt
-.type AES_encrypt,\@function
-AES_encrypt:
-___
-$code.=<<___ if (!$softonly);
- l %r0,240($key)
- lhi %r1,16
- clr %r0,%r1
- jl .Lesoft
-
- la %r1,0($key)
- #la %r2,0($inp)
- la %r4,0($out)
- lghi %r3,16 # single block length
- .long 0xb92e0042 # km %r4,%r2
- brc 1,.-4 # can this happen?
- br %r14
-.align 64
-.Lesoft:
-___
-$code.=<<___;
- stmg %r3,$ra,24($sp)
-
- llgf $s0,0($inp)
- llgf $s1,4($inp)
- llgf $s2,8($inp)
- llgf $s3,12($inp)
-
- larl $tbl,AES_Te
- bras $ra,_s390x_AES_encrypt
-
- lg $out,24($sp)
- st $s0,0($out)
- st $s1,4($out)
- st $s2,8($out)
- st $s3,12($out)
-
- lmg %r6,$ra,48($sp)
- br $ra
-.size AES_encrypt,.-AES_encrypt
-
-.type _s390x_AES_encrypt,\@function
-.align 16
-_s390x_AES_encrypt:
- stg $ra,152($sp)
- x $s0,0($key)
- x $s1,4($key)
- x $s2,8($key)
- x $s3,12($key)
- l $rounds,240($key)
- llill $mask,`0xff<<3`
- aghi $rounds,-1
- j .Lenc_loop
-.align 16
-.Lenc_loop:
- sllg $t1,$s0,`0+3`
- srlg $t2,$s0,`8-3`
- srlg $t3,$s0,`16-3`
- srl $s0,`24-3`
- nr $s0,$mask
- ngr $t1,$mask
- nr $t2,$mask
- nr $t3,$mask
-
- srlg $i1,$s1,`16-3` # i0
- sllg $i2,$s1,`0+3`
- srlg $i3,$s1,`8-3`
- srl $s1,`24-3`
- nr $i1,$mask
- nr $s1,$mask
- ngr $i2,$mask
- nr $i3,$mask
-
- l $s0,0($s0,$tbl) # Te0[s0>>24]
- l $t1,1($t1,$tbl) # Te3[s0>>0]
- l $t2,2($t2,$tbl) # Te2[s0>>8]
- l $t3,3($t3,$tbl) # Te1[s0>>16]
-
- x $s0,3($i1,$tbl) # Te1[s1>>16]
- l $s1,0($s1,$tbl) # Te0[s1>>24]
- x $t2,1($i2,$tbl) # Te3[s1>>0]
- x $t3,2($i3,$tbl) # Te2[s1>>8]
-
- srlg $i1,$s2,`8-3` # i0
- srlg $i2,$s2,`16-3` # i1
- nr $i1,$mask
- nr $i2,$mask
- sllg $i3,$s2,`0+3`
- srl $s2,`24-3`
- nr $s2,$mask
- ngr $i3,$mask
-
- xr $s1,$t1
- srlg $ra,$s3,`8-3` # i1
- sllg $t1,$s3,`0+3` # i0
- nr $ra,$mask
- la $key,16($key)
- ngr $t1,$mask
-
- x $s0,2($i1,$tbl) # Te2[s2>>8]
- x $s1,3($i2,$tbl) # Te1[s2>>16]
- l $s2,0($s2,$tbl) # Te0[s2>>24]
- x $t3,1($i3,$tbl) # Te3[s2>>0]
-
- srlg $i3,$s3,`16-3` # i2
- xr $s2,$t2
- srl $s3,`24-3`
- nr $i3,$mask
- nr $s3,$mask
-
- x $s0,0($key)
- x $s1,4($key)
- x $s2,8($key)
- x $t3,12($key)
-
- x $s0,1($t1,$tbl) # Te3[s3>>0]
- x $s1,2($ra,$tbl) # Te2[s3>>8]
- x $s2,3($i3,$tbl) # Te1[s3>>16]
- l $s3,0($s3,$tbl) # Te0[s3>>24]
- xr $s3,$t3
-
- brct $rounds,.Lenc_loop
- .align 16
-
- sllg $t1,$s0,`0+3`
- srlg $t2,$s0,`8-3`
- ngr $t1,$mask
- srlg $t3,$s0,`16-3`
- srl $s0,`24-3`
- nr $s0,$mask
- nr $t2,$mask
- nr $t3,$mask
-
- srlg $i1,$s1,`16-3` # i0
- sllg $i2,$s1,`0+3`
- ngr $i2,$mask
- srlg $i3,$s1,`8-3`
- srl $s1,`24-3`
- nr $i1,$mask
- nr $s1,$mask
- nr $i3,$mask
-
- llgc $s0,2($s0,$tbl) # Te4[s0>>24]
- llgc $t1,2($t1,$tbl) # Te4[s0>>0]
- sll $s0,24
- llgc $t2,2($t2,$tbl) # Te4[s0>>8]
- llgc $t3,2($t3,$tbl) # Te4[s0>>16]
- sll $t2,8
- sll $t3,16
-
- llgc $i1,2($i1,$tbl) # Te4[s1>>16]
- llgc $s1,2($s1,$tbl) # Te4[s1>>24]
- llgc $i2,2($i2,$tbl) # Te4[s1>>0]
- llgc $i3,2($i3,$tbl) # Te4[s1>>8]
- sll $i1,16
- sll $s1,24
- sll $i3,8
- or $s0,$i1
- or $s1,$t1
- or $t2,$i2
- or $t3,$i3
-
- srlg $i1,$s2,`8-3` # i0
- srlg $i2,$s2,`16-3` # i1
- nr $i1,$mask
- nr $i2,$mask
- sllg $i3,$s2,`0+3`
- srl $s2,`24-3`
- ngr $i3,$mask
- nr $s2,$mask
-
- sllg $t1,$s3,`0+3` # i0
- srlg $ra,$s3,`8-3` # i1
- ngr $t1,$mask
-
- llgc $i1,2($i1,$tbl) # Te4[s2>>8]
- llgc $i2,2($i2,$tbl) # Te4[s2>>16]
- sll $i1,8
- llgc $s2,2($s2,$tbl) # Te4[s2>>24]
- llgc $i3,2($i3,$tbl) # Te4[s2>>0]
- sll $i2,16
- nr $ra,$mask
- sll $s2,24
- or $s0,$i1
- or $s1,$i2
- or $s2,$t2
- or $t3,$i3
-
- srlg $i3,$s3,`16-3` # i2
- srl $s3,`24-3`
- nr $i3,$mask
- nr $s3,$mask
-
- l $t0,16($key)
- l $t2,20($key)
-
- llgc $i1,2($t1,$tbl) # Te4[s3>>0]
- llgc $i2,2($ra,$tbl) # Te4[s3>>8]
- llgc $i3,2($i3,$tbl) # Te4[s3>>16]
- llgc $s3,2($s3,$tbl) # Te4[s3>>24]
- sll $i2,8
- sll $i3,16
- sll $s3,24
- or $s0,$i1
- or $s1,$i2
- or $s2,$i3
- or $s3,$t3
-
- lg $ra,152($sp)
- xr $s0,$t0
- xr $s1,$t2
- x $s2,24($key)
- x $s3,28($key)
-
- br $ra
-.size _s390x_AES_encrypt,.-_s390x_AES_encrypt
-___
-
-$code.=<<___;
-.type AES_Td,\@object
-.align 256
-AES_Td:
-___
-&_data_word(
- 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
- 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
- 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
- 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
- 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
- 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
- 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
- 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
- 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
- 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
- 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
- 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
- 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
- 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
- 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
- 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
- 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
- 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
- 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
- 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
- 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
- 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
- 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
- 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
- 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
- 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
- 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
- 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
- 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
- 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
- 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
- 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
- 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
- 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
- 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
- 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
- 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
- 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
- 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
- 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
- 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
- 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
- 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
- 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
- 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
- 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
- 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
- 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
- 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
- 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
- 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
- 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
- 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
- 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
- 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
- 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
- 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
- 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
- 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
- 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
- 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
- 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
- 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
- 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
-$code.=<<___;
-# Td4[256]
-.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-.size AES_Td,.-AES_Td
-
-# void AES_decrypt(const unsigned char *inp, unsigned char *out,
-# const AES_KEY *key) {
-.globl AES_decrypt
-.type AES_decrypt,\@function
-AES_decrypt:
-___
-$code.=<<___ if (!$softonly);
- l %r0,240($key)
- lhi %r1,16
- clr %r0,%r1
- jl .Ldsoft
-
- la %r1,0($key)
- #la %r2,0($inp)
- la %r4,0($out)
- lghi %r3,16 # single block length
- .long 0xb92e0042 # km %r4,%r2
- brc 1,.-4 # can this happen?
- br %r14
-.align 64
-.Ldsoft:
-___
-$code.=<<___;
- stmg %r3,$ra,24($sp)
-
- llgf $s0,0($inp)
- llgf $s1,4($inp)
- llgf $s2,8($inp)
- llgf $s3,12($inp)
-
- larl $tbl,AES_Td
- bras $ra,_s390x_AES_decrypt
-
- lg $out,24($sp)
- st $s0,0($out)
- st $s1,4($out)
- st $s2,8($out)
- st $s3,12($out)
-
- lmg %r6,$ra,48($sp)
- br $ra
-.size AES_decrypt,.-AES_decrypt
-
-.type _s390x_AES_decrypt,\@function
-.align 16
-_s390x_AES_decrypt:
- stg $ra,152($sp)
- x $s0,0($key)
- x $s1,4($key)
- x $s2,8($key)
- x $s3,12($key)
- l $rounds,240($key)
- llill $mask,`0xff<<3`
- aghi $rounds,-1
- j .Ldec_loop
-.align 16
-.Ldec_loop:
- srlg $t1,$s0,`16-3`
- srlg $t2,$s0,`8-3`
- sllg $t3,$s0,`0+3`
- srl $s0,`24-3`
- nr $s0,$mask
- nr $t1,$mask
- nr $t2,$mask
- ngr $t3,$mask
-
- sllg $i1,$s1,`0+3` # i0
- srlg $i2,$s1,`16-3`
- srlg $i3,$s1,`8-3`
- srl $s1,`24-3`
- ngr $i1,$mask
- nr $s1,$mask
- nr $i2,$mask
- nr $i3,$mask
-
- l $s0,0($s0,$tbl) # Td0[s0>>24]
- l $t1,3($t1,$tbl) # Td1[s0>>16]
- l $t2,2($t2,$tbl) # Td2[s0>>8]
- l $t3,1($t3,$tbl) # Td3[s0>>0]
-
- x $s0,1($i1,$tbl) # Td3[s1>>0]
- l $s1,0($s1,$tbl) # Td0[s1>>24]
- x $t2,3($i2,$tbl) # Td1[s1>>16]
- x $t3,2($i3,$tbl) # Td2[s1>>8]
-
- srlg $i1,$s2,`8-3` # i0
- sllg $i2,$s2,`0+3` # i1
- srlg $i3,$s2,`16-3`
- srl $s2,`24-3`
- nr $i1,$mask
- ngr $i2,$mask
- nr $s2,$mask
- nr $i3,$mask
-
- xr $s1,$t1
- srlg $ra,$s3,`8-3` # i1
- srlg $t1,$s3,`16-3` # i0
- nr $ra,$mask
- la $key,16($key)
- nr $t1,$mask
-
- x $s0,2($i1,$tbl) # Td2[s2>>8]
- x $s1,1($i2,$tbl) # Td3[s2>>0]
- l $s2,0($s2,$tbl) # Td0[s2>>24]
- x $t3,3($i3,$tbl) # Td1[s2>>16]
-
- sllg $i3,$s3,`0+3` # i2
- srl $s3,`24-3`
- ngr $i3,$mask
- nr $s3,$mask
-
- xr $s2,$t2
- x $s0,0($key)
- x $s1,4($key)
- x $s2,8($key)
- x $t3,12($key)
-
- x $s0,3($t1,$tbl) # Td1[s3>>16]
- x $s1,2($ra,$tbl) # Td2[s3>>8]
- x $s2,1($i3,$tbl) # Td3[s3>>0]
- l $s3,0($s3,$tbl) # Td0[s3>>24]
- xr $s3,$t3
-
- brct $rounds,.Ldec_loop
- .align 16
-
- l $t1,`2048+0`($tbl) # prefetch Td4
- l $t2,`2048+64`($tbl)
- l $t3,`2048+128`($tbl)
- l $i1,`2048+192`($tbl)
- llill $mask,0xff
-
- srlg $i3,$s0,24 # i0
- srlg $t1,$s0,16
- srlg $t2,$s0,8
- nr $s0,$mask # i3
- nr $t1,$mask
-
- srlg $i1,$s1,24
- nr $t2,$mask
- srlg $i2,$s1,16
- srlg $ra,$s1,8
- nr $s1,$mask # i0
- nr $i2,$mask
- nr $ra,$mask
-
- llgc $i3,2048($i3,$tbl) # Td4[s0>>24]
- llgc $t1,2048($t1,$tbl) # Td4[s0>>16]
- llgc $t2,2048($t2,$tbl) # Td4[s0>>8]
- sll $t1,16
- llgc $t3,2048($s0,$tbl) # Td4[s0>>0]
- sllg $s0,$i3,24
- sll $t2,8
-
- llgc $s1,2048($s1,$tbl) # Td4[s1>>0]
- llgc $i1,2048($i1,$tbl) # Td4[s1>>24]
- llgc $i2,2048($i2,$tbl) # Td4[s1>>16]
- sll $i1,24
- llgc $i3,2048($ra,$tbl) # Td4[s1>>8]
- sll $i2,16
- sll $i3,8
- or $s0,$s1
- or $t1,$i1
- or $t2,$i2
- or $t3,$i3
-
- srlg $i1,$s2,8 # i0
- srlg $i2,$s2,24
- srlg $i3,$s2,16
- nr $s2,$mask # i1
- nr $i1,$mask
- nr $i3,$mask
- llgc $i1,2048($i1,$tbl) # Td4[s2>>8]
- llgc $s1,2048($s2,$tbl) # Td4[s2>>0]
- llgc $i2,2048($i2,$tbl) # Td4[s2>>24]
- llgc $i3,2048($i3,$tbl) # Td4[s2>>16]
- sll $i1,8
- sll $i2,24
- or $s0,$i1
- sll $i3,16
- or $t2,$i2
- or $t3,$i3
-
- srlg $i1,$s3,16 # i0
- srlg $i2,$s3,8 # i1
- srlg $i3,$s3,24
- nr $s3,$mask # i2
- nr $i1,$mask
- nr $i2,$mask
-
- lg $ra,152($sp)
- or $s1,$t1
- l $t0,16($key)
- l $t1,20($key)
-
- llgc $i1,2048($i1,$tbl) # Td4[s3>>16]
- llgc $i2,2048($i2,$tbl) # Td4[s3>>8]
- sll $i1,16
- llgc $s2,2048($s3,$tbl) # Td4[s3>>0]
- llgc $s3,2048($i3,$tbl) # Td4[s3>>24]
- sll $i2,8
- sll $s3,24
- or $s0,$i1
- or $s1,$i2
- or $s2,$t2
- or $s3,$t3
-
- xr $s0,$t0
- xr $s1,$t1
- x $s2,24($key)
- x $s3,28($key)
-
- br $ra
-.size _s390x_AES_decrypt,.-_s390x_AES_decrypt
-___
-
-$code.=<<___;
-# void AES_set_encrypt_key(const unsigned char *in, int bits,
-# AES_KEY *key) {
-.globl AES_set_encrypt_key
-.type AES_set_encrypt_key,\@function
-.align 16
-AES_set_encrypt_key:
- lghi $t0,0
- clgr $inp,$t0
- je .Lminus1
- clgr $key,$t0
- je .Lminus1
-
- lghi $t0,128
- clr $bits,$t0
- je .Lproceed
- lghi $t0,192
- clr $bits,$t0
- je .Lproceed
- lghi $t0,256
- clr $bits,$t0
- je .Lproceed
- lghi %r2,-2
- br %r14
-
-.align 16
-.Lproceed:
-___
-$code.=<<___ if (!$softonly);
- # convert bits to km code, [128,192,256]->[18,19,20]
- lhi %r5,-128
- lhi %r0,18
- ar %r5,$bits
- srl %r5,6
- ar %r5,%r0
-
- lghi %r0,0 # query capability vector
- la %r1,16($sp)
- .long 0xb92f0042 # kmc %r4,%r2
-
- llihh %r1,0x8000
- srlg %r1,%r1,0(%r5)
- ng %r1,16($sp)
- jz .Lekey_internal
-
- lmg %r0,%r1,0($inp) # just copy 128 bits...
- stmg %r0,%r1,0($key)
- lhi %r0,192
- cr $bits,%r0
- jl 1f
- lg %r1,16($inp)
- stg %r1,16($key)
- je 1f
- lg %r1,24($inp)
- stg %r1,24($key)
-1: st $bits,236($key) # save bits
- st %r5,240($key) # save km code
- lghi %r2,0
- br %r14
-___
-$code.=<<___;
-.align 16
-.Lekey_internal:
- stmg %r6,%r13,48($sp) # all non-volatile regs
-
- larl $tbl,AES_Te+2048
-
- llgf $s0,0($inp)
- llgf $s1,4($inp)
- llgf $s2,8($inp)
- llgf $s3,12($inp)
- st $s0,0($key)
- st $s1,4($key)
- st $s2,8($key)
- st $s3,12($key)
- lghi $t0,128
- cr $bits,$t0
- jne .Lnot128
-
- llill $mask,0xff
- lghi $t3,0 # i=0
- lghi $rounds,10
- st $rounds,240($key)
-
- llgfr $t2,$s3 # temp=rk[3]
- srlg $i1,$s3,8
- srlg $i2,$s3,16
- srlg $i3,$s3,24
- nr $t2,$mask
- nr $i1,$mask
- nr $i2,$mask
-
-.align 16
-.L128_loop:
- la $t2,0($t2,$tbl)
- la $i1,0($i1,$tbl)
- la $i2,0($i2,$tbl)
- la $i3,0($i3,$tbl)
- icm $t2,2,0($t2) # Te4[rk[3]>>0]<<8
- icm $t2,4,0($i1) # Te4[rk[3]>>8]<<16
- icm $t2,8,0($i2) # Te4[rk[3]>>16]<<24
- icm $t2,1,0($i3) # Te4[rk[3]>>24]
- x $t2,256($t3,$tbl) # rcon[i]
- xr $s0,$t2 # rk[4]=rk[0]^...
- xr $s1,$s0 # rk[5]=rk[1]^rk[4]
- xr $s2,$s1 # rk[6]=rk[2]^rk[5]
- xr $s3,$s2 # rk[7]=rk[3]^rk[6]
-
- llgfr $t2,$s3 # temp=rk[3]
- srlg $i1,$s3,8
- srlg $i2,$s3,16
- nr $t2,$mask
- nr $i1,$mask
- srlg $i3,$s3,24
- nr $i2,$mask
-
- st $s0,16($key)
- st $s1,20($key)
- st $s2,24($key)
- st $s3,28($key)
- la $key,16($key) # key+=4
- la $t3,4($t3) # i++
- brct $rounds,.L128_loop
- lghi %r2,0
- lmg %r6,%r13,48($sp)
- br $ra
-
-.align 16
-.Lnot128:
- llgf $t0,16($inp)
- llgf $t1,20($inp)
- st $t0,16($key)
- st $t1,20($key)
- lghi $t0,192
- cr $bits,$t0
- jne .Lnot192
-
- llill $mask,0xff
- lghi $t3,0 # i=0
- lghi $rounds,12
- st $rounds,240($key)
- lghi $rounds,8
-
- srlg $i1,$t1,8
- srlg $i2,$t1,16
- srlg $i3,$t1,24
- nr $t1,$mask
- nr $i1,$mask
- nr $i2,$mask
-
-.align 16
-.L192_loop:
- la $t1,0($t1,$tbl)
- la $i1,0($i1,$tbl)
- la $i2,0($i2,$tbl)
- la $i3,0($i3,$tbl)
- icm $t1,2,0($t1) # Te4[rk[5]>>0]<<8
- icm $t1,4,0($i1) # Te4[rk[5]>>8]<<16
- icm $t1,8,0($i2) # Te4[rk[5]>>16]<<24
- icm $t1,1,0($i3) # Te4[rk[5]>>24]
- x $t1,256($t3,$tbl) # rcon[i]
- xr $s0,$t1 # rk[6]=rk[0]^...
- xr $s1,$s0 # rk[7]=rk[1]^rk[6]
- xr $s2,$s1 # rk[8]=rk[2]^rk[7]
- xr $s3,$s2 # rk[9]=rk[3]^rk[8]
-
- st $s0,24($key)
- st $s1,28($key)
- st $s2,32($key)
- st $s3,36($key)
- brct $rounds,.L192_continue
- lghi %r2,0
- lmg %r6,%r13,48($sp)
- br $ra
-
-.align 16
-.L192_continue:
- lgr $t1,$s3
- x $t1,16($key) # rk[10]=rk[4]^rk[9]
- st $t1,40($key)
- x $t1,20($key) # rk[11]=rk[5]^rk[10]
- st $t1,44($key)
-
- srlg $i1,$t1,8
- srlg $i2,$t1,16
- srlg $i3,$t1,24
- nr $t1,$mask
- nr $i1,$mask
- nr $i2,$mask
-
- la $key,24($key) # key+=6
- la $t3,4($t3) # i++
- j .L192_loop
-
-.align 16
-.Lnot192:
- llgf $t0,24($inp)
- llgf $t1,28($inp)
- st $t0,24($key)
- st $t1,28($key)
- llill $mask,0xff
- lghi $t3,0 # i=0
- lghi $rounds,14
- st $rounds,240($key)
- lghi $rounds,7
-
- srlg $i1,$t1,8
- srlg $i2,$t1,16
- srlg $i3,$t1,24
- nr $t1,$mask
- nr $i1,$mask
- nr $i2,$mask
-
-.align 16
-.L256_loop:
- la $t1,0($t1,$tbl)
- la $i1,0($i1,$tbl)
- la $i2,0($i2,$tbl)
- la $i3,0($i3,$tbl)
- icm $t1,2,0($t1) # Te4[rk[7]>>0]<<8
- icm $t1,4,0($i1) # Te4[rk[7]>>8]<<16
- icm $t1,8,0($i2) # Te4[rk[7]>>16]<<24
- icm $t1,1,0($i3) # Te4[rk[7]>>24]
- x $t1,256($t3,$tbl) # rcon[i]
- xr $s0,$t1 # rk[8]=rk[0]^...
- xr $s1,$s0 # rk[9]=rk[1]^rk[8]
- xr $s2,$s1 # rk[10]=rk[2]^rk[9]
- xr $s3,$s2 # rk[11]=rk[3]^rk[10]
- st $s0,32($key)
- st $s1,36($key)
- st $s2,40($key)
- st $s3,44($key)
- brct $rounds,.L256_continue
- lghi %r2,0
- lmg %r6,%r13,48($sp)
- br $ra
-
-.align 16
-.L256_continue:
- lgr $t1,$s3 # temp=rk[11]
- srlg $i1,$s3,8
- srlg $i2,$s3,16
- srlg $i3,$s3,24
- nr $t1,$mask
- nr $i1,$mask
- nr $i2,$mask
- la $t1,0($t1,$tbl)
- la $i1,0($i1,$tbl)
- la $i2,0($i2,$tbl)
- la $i3,0($i3,$tbl)
- llgc $t1,0($t1) # Te4[rk[11]>>0]
- icm $t1,2,0($i1) # Te4[rk[11]>>8]<<8
- icm $t1,4,0($i2) # Te4[rk[11]>>16]<<16
- icm $t1,8,0($i3) # Te4[rk[11]>>24]<<24
- x $t1,16($key) # rk[12]=rk[4]^...
- st $t1,48($key)
- x $t1,20($key) # rk[13]=rk[5]^rk[12]
- st $t1,52($key)
- x $t1,24($key) # rk[14]=rk[6]^rk[13]
- st $t1,56($key)
- x $t1,28($key) # rk[15]=rk[7]^rk[14]
- st $t1,60($key)
-
- srlg $i1,$t1,8
- srlg $i2,$t1,16
- srlg $i3,$t1,24
- nr $t1,$mask
- nr $i1,$mask
- nr $i2,$mask
-
- la $key,32($key) # key+=8
- la $t3,4($t3) # i++
- j .L256_loop
-
-.Lminus1:
- lghi %r2,-1
- br $ra
-.size AES_set_encrypt_key,.-AES_set_encrypt_key
-
-# void AES_set_decrypt_key(const unsigned char *in, int bits,
-# AES_KEY *key) {
-.globl AES_set_decrypt_key
-.type AES_set_decrypt_key,\@function
-.align 16
-AES_set_decrypt_key:
- stg $key,32($sp) # I rely on AES_set_encrypt_key to
- stg $ra,112($sp) # save non-volatile registers!
- bras $ra,AES_set_encrypt_key
- lg $key,32($sp)
- lg $ra,112($sp)
- ltgr %r2,%r2
- bnzr $ra
-___
-$code.=<<___ if (!$softonly);
- l $t0,240($key)
- lhi $t1,16
- cr $t0,$t1
- jl .Lgo
- oill $t0,0x80 # set "decrypt" bit
- st $t0,240($key)
- br $ra
-
-.align 16
-.Ldkey_internal:
- stg $key,32($sp)
- stg $ra,40($sp)
- bras $ra,.Lekey_internal
- lg $key,32($sp)
- lg $ra,40($sp)
-___
-$code.=<<___;
-
-.Lgo: llgf $rounds,240($key)
- la $i1,0($key)
- sllg $i2,$rounds,4
- la $i2,0($i2,$key)
- srl $rounds,1
- lghi $t1,-16
-
-.align 16
-.Linv: lmg $s0,$s1,0($i1)
- lmg $s2,$s3,0($i2)
- stmg $s0,$s1,0($i2)
- stmg $s2,$s3,0($i1)
- la $i1,16($i1)
- la $i2,0($t1,$i2)
- brct $rounds,.Linv
-___
-$mask80=$i1;
-$mask1b=$i2;
-$maskfe=$i3;
-$code.=<<___;
- llgf $rounds,240($key)
- aghi $rounds,-1
- sll $rounds,2 # (rounds-1)*4
- llilh $mask80,0x8080
- llilh $mask1b,0x1b1b
- llilh $maskfe,0xfefe
- oill $mask80,0x8080
- oill $mask1b,0x1b1b
- oill $maskfe,0xfefe
-
-.align 16
-.Lmix: l $s0,16($key) # tp1
- lr $s1,$s0
- ngr $s1,$mask80
- srlg $t1,$s1,7
- slr $s1,$t1
- nr $s1,$mask1b
- sllg $t1,$s0,1
- nr $t1,$maskfe
- xr $s1,$t1 # tp2
-
- lr $s2,$s1
- ngr $s2,$mask80
- srlg $t1,$s2,7
- slr $s2,$t1
- nr $s2,$mask1b
- sllg $t1,$s1,1
- nr $t1,$maskfe
- xr $s2,$t1 # tp4
-
- lr $s3,$s2
- ngr $s3,$mask80
- srlg $t1,$s3,7
- slr $s3,$t1
- nr $s3,$mask1b
- sllg $t1,$s2,1
- nr $t1,$maskfe
- xr $s3,$t1 # tp8
-
- xr $s1,$s0 # tp2^tp1
- xr $s2,$s0 # tp4^tp1
- rll $s0,$s0,24 # = ROTATE(tp1,8)
- xr $s2,$s3 # ^=tp8
- xr $s0,$s1 # ^=tp2^tp1
- xr $s1,$s3 # tp2^tp1^tp8
- xr $s0,$s2 # ^=tp4^tp1^tp8
- rll $s1,$s1,8
- rll $s2,$s2,16
- xr $s0,$s1 # ^= ROTATE(tp8^tp2^tp1,24)
- rll $s3,$s3,24
- xr $s0,$s2 # ^= ROTATE(tp8^tp4^tp1,16)
- xr $s0,$s3 # ^= ROTATE(tp8,8)
-
- st $s0,16($key)
- la $key,4($key)
- brct $rounds,.Lmix
-
- lmg %r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
- lghi %r2,0
- br $ra
-.size AES_set_decrypt_key,.-AES_set_decrypt_key
-___
-
-#void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
-# size_t length, const AES_KEY *key,
-# unsigned char *ivec, const int enc)
-{
-my $inp="%r2";
-my $out="%r4"; # length and out are swapped
-my $len="%r3";
-my $key="%r5";
-my $ivp="%r6";
-
-$code.=<<___;
-.globl AES_cbc_encrypt
-.type AES_cbc_encrypt,\@function
-.align 16
-AES_cbc_encrypt:
- xgr %r3,%r4 # flip %r3 and %r4, out and len
- xgr %r4,%r3
- xgr %r3,%r4
-___
-$code.=<<___ if (!$softonly);
- lhi %r0,16
- cl %r0,240($key)
- jh .Lcbc_software
-
- lg %r0,0($ivp) # copy ivec
- lg %r1,8($ivp)
- stmg %r0,%r1,16($sp)
- lmg %r0,%r1,0($key) # copy key, cover 256 bit
- stmg %r0,%r1,32($sp)
- lmg %r0,%r1,16($key)
- stmg %r0,%r1,48($sp)
- l %r0,240($key) # load kmc code
- lghi $key,15 # res=len%16, len-=res;
- ngr $key,$len
- slgr $len,$key
- la %r1,16($sp) # parameter block - ivec || key
- jz .Lkmc_truncated
- .long 0xb92f0042 # kmc %r4,%r2
- brc 1,.-4 # pay attention to "partial completion"
- ltr $key,$key
- jnz .Lkmc_truncated
-.Lkmc_done:
- lmg %r0,%r1,16($sp) # copy ivec to caller
- stg %r0,0($ivp)
- stg %r1,8($ivp)
- br $ra
-.align 16
-.Lkmc_truncated:
- ahi $key,-1 # it's the way it's encoded in mvc
- tmll %r0,0x80
- jnz .Lkmc_truncated_dec
- lghi %r1,0
- stg %r1,128($sp)
- stg %r1,136($sp)
- bras %r1,1f
- mvc 128(1,$sp),0($inp)
-1: ex $key,0(%r1)
- la %r1,16($sp) # restore parameter block
- la $inp,128($sp)
- lghi $len,16
- .long 0xb92f0042 # kmc %r4,%r2
- j .Lkmc_done
-.align 16
-.Lkmc_truncated_dec:
- stg $out,64($sp)
- la $out,128($sp)
- lghi $len,16
- .long 0xb92f0042 # kmc %r4,%r2
- lg $out,64($sp)
- bras %r1,2f
- mvc 0(1,$out),128($sp)
-2: ex $key,0(%r1)
- j .Lkmc_done
-.align 16
-.Lcbc_software:
-___
-$code.=<<___;
- stmg $key,$ra,40($sp)
- lhi %r0,0
- cl %r0,164($sp)
- je .Lcbc_decrypt
-
- larl $tbl,AES_Te
-
- llgf $s0,0($ivp)
- llgf $s1,4($ivp)
- llgf $s2,8($ivp)
- llgf $s3,12($ivp)
-
- lghi $t0,16
- slgr $len,$t0
- brc 4,.Lcbc_enc_tail # if borrow
-.Lcbc_enc_loop:
- stmg $inp,$out,16($sp)
- x $s0,0($inp)
- x $s1,4($inp)
- x $s2,8($inp)
- x $s3,12($inp)
- lgr %r4,$key
-
- bras $ra,_s390x_AES_encrypt
-
- lmg $inp,$key,16($sp)
- st $s0,0($out)
- st $s1,4($out)
- st $s2,8($out)
- st $s3,12($out)
-
- la $inp,16($inp)
- la $out,16($out)
- lghi $t0,16
- ltgr $len,$len
- jz .Lcbc_enc_done
- slgr $len,$t0
- brc 4,.Lcbc_enc_tail # if borrow
- j .Lcbc_enc_loop
-.align 16
-.Lcbc_enc_done:
- lg $ivp,48($sp)
- st $s0,0($ivp)
- st $s1,4($ivp)
- st $s2,8($ivp)
- st $s3,12($ivp)
-
- lmg %r7,$ra,56($sp)
- br $ra
-
-.align 16
-.Lcbc_enc_tail:
- aghi $len,15
- lghi $t0,0
- stg $t0,128($sp)
- stg $t0,136($sp)
- bras $t1,3f
- mvc 128(1,$sp),0($inp)
-3: ex $len,0($t1)
- lghi $len,0
- la $inp,128($sp)
- j .Lcbc_enc_loop
-
-.align 16
-.Lcbc_decrypt:
- larl $tbl,AES_Td
-
- lg $t0,0($ivp)
- lg $t1,8($ivp)
- stmg $t0,$t1,128($sp)
-
-.Lcbc_dec_loop:
- stmg $inp,$out,16($sp)
- llgf $s0,0($inp)
- llgf $s1,4($inp)
- llgf $s2,8($inp)
- llgf $s3,12($inp)
- lgr %r4,$key
-
- bras $ra,_s390x_AES_decrypt
-
- lmg $inp,$key,16($sp)
- sllg $s0,$s0,32
- sllg $s2,$s2,32
- lr $s0,$s1
- lr $s2,$s3
-
- lg $t0,0($inp)
- lg $t1,8($inp)
- xg $s0,128($sp)
- xg $s2,136($sp)
- lghi $s1,16
- slgr $len,$s1
- brc 4,.Lcbc_dec_tail # if borrow
- brc 2,.Lcbc_dec_done # if zero
- stg $s0,0($out)
- stg $s2,8($out)
- stmg $t0,$t1,128($sp)
-
- la $inp,16($inp)
- la $out,16($out)
- j .Lcbc_dec_loop
-
-.Lcbc_dec_done:
- stg $s0,0($out)
- stg $s2,8($out)
-.Lcbc_dec_exit:
- lmg $ivp,$ra,48($sp)
- stmg $t0,$t1,0($ivp)
-
- br $ra
-
-.align 16
-.Lcbc_dec_tail:
- aghi $len,15
- stg $s0,128($sp)
- stg $s2,136($sp)
- bras $s1,4f
- mvc 0(1,$out),128($sp)
-4: ex $len,0($s1)
- j .Lcbc_dec_exit
-.size AES_cbc_encrypt,.-AES_cbc_encrypt
-___
-}
-$code.=<<___;
-.string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
-___
-
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-print $code;
diff --git a/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl b/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl
deleted file mode 100755
index c57b3a2..0000000
--- a/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl
+++ /dev/null
@@ -1,1181 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. Rights for redistribution and usage in source and binary
-# forms are granted according to the OpenSSL license.
-# ====================================================================
-#
-# Version 1.1
-#
-# The major reason for undertaken effort was to mitigate the hazard of
-# cache-timing attack. This is [currently and initially!] addressed in
-# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each.
-# 2. References to them are scheduled for L2 cache latency, meaning
-# that the tables don't have to reside in L1 cache. Once again, this
-# is an initial draft and one should expect more countermeasures to
-# be implemented...
-#
-# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last
-# round.
-#
-# Even though performance was not the primary goal [on the contrary,
-# extra shifts "induced" by compressed S-box and longer loop epilogue
-# "induced" by scheduling for L2 have negative effect on performance],
-# the code turned out to run in ~23 cycles per processed byte en-/
-# decrypted with 128-bit key. This is pretty good result for code
-# with mentioned qualities and UltraSPARC core. Compared to Sun C
-# generated code my encrypt procedure runs just few percents faster,
-# while decrypt one - whole 50% faster [yes, Sun C failed to generate
-# optimal decrypt procedure]. Compared to GNU C generated code both
-# procedures are more than 60% faster:-)
-
-$bits=32;
-for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-if ($bits==64) { $bias=2047; $frame=192; }
-else { $bias=0; $frame=112; }
-$locals=16;
-
-$acc0="%l0";
-$acc1="%o0";
-$acc2="%o1";
-$acc3="%o2";
-
-$acc4="%l1";
-$acc5="%o3";
-$acc6="%o4";
-$acc7="%o5";
-
-$acc8="%l2";
-$acc9="%o7";
-$acc10="%g1";
-$acc11="%g2";
-
-$acc12="%l3";
-$acc13="%g3";
-$acc14="%g4";
-$acc15="%g5";
-
-$t0="%l4";
-$t1="%l5";
-$t2="%l6";
-$t3="%l7";
-
-$s0="%i0";
-$s1="%i1";
-$s2="%i2";
-$s3="%i3";
-$tbl="%i4";
-$key="%i5";
-$rounds="%i7"; # aliases with return address, which is off-loaded to stack
-
-sub _data_word()
-{ my $i;
- while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
-}
-
-$code.=<<___ if ($bits==64);
-.register %g2,#scratch
-.register %g3,#scratch
-___
-$code.=<<___;
-.section ".text",#alloc,#execinstr
-
-.align 256
-AES_Te:
-___
-&_data_word(
- 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
- 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
- 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
- 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
- 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
- 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
- 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
- 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
- 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
- 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
- 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
- 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
- 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
- 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
- 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
- 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
- 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
- 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
- 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
- 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
- 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
- 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
- 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
- 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
- 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
- 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
- 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
- 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
- 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
- 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
- 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
- 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
- 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
- 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
- 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
- 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
- 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
- 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
- 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
- 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
- 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
- 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
- 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
- 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
- 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
- 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
- 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
- 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
- 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
- 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
- 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
- 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
- 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
- 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
- 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
- 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
- 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
- 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
- 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
- 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
- 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
- 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
- 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
- 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
-$code.=<<___;
- .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
- .byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
- .byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
- .byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
- .byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
- .byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
- .byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
- .byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
- .byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
- .byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
- .byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
- .byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
- .byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
- .byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
- .byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
- .byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
- .byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
- .byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
- .byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
- .byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
- .byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
- .byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
- .byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
- .byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
- .byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
- .byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
- .byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
- .byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
- .byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
- .byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
- .byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
- .byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-.type AES_Te,#object
-.size AES_Te,(.-AES_Te)
-
-.align 64
-.skip 16
-_sparcv9_AES_encrypt:
- save %sp,-$frame-$locals,%sp
- stx %i7,[%sp+$bias+$frame+0] ! off-load return address
- ld [$key+240],$rounds
- ld [$key+0],$t0
- ld [$key+4],$t1 !
- ld [$key+8],$t2
- srl $rounds,1,$rounds
- xor $t0,$s0,$s0
- ld [$key+12],$t3
- srl $s0,21,$acc0
- xor $t1,$s1,$s1
- ld [$key+16],$t0
- srl $s1,13,$acc1 !
- xor $t2,$s2,$s2
- ld [$key+20],$t1
- xor $t3,$s3,$s3
- ld [$key+24],$t2
- and $acc0,2040,$acc0
- ld [$key+28],$t3
- nop
-.Lenc_loop:
- srl $s2,5,$acc2 !
- and $acc1,2040,$acc1
- ldx [$tbl+$acc0],$acc0
- sll $s3,3,$acc3
- and $acc2,2040,$acc2
- ldx [$tbl+$acc1],$acc1
- srl $s1,21,$acc4
- and $acc3,2040,$acc3
- ldx [$tbl+$acc2],$acc2 !
- srl $s2,13,$acc5
- and $acc4,2040,$acc4
- ldx [$tbl+$acc3],$acc3
- srl $s3,5,$acc6
- and $acc5,2040,$acc5
- ldx [$tbl+$acc4],$acc4
- fmovs %f0,%f0
- sll $s0,3,$acc7 !
- and $acc6,2040,$acc6
- ldx [$tbl+$acc5],$acc5
- srl $s2,21,$acc8
- and $acc7,2040,$acc7
- ldx [$tbl+$acc6],$acc6
- srl $s3,13,$acc9
- and $acc8,2040,$acc8
- ldx [$tbl+$acc7],$acc7 !
- srl $s0,5,$acc10
- and $acc9,2040,$acc9
- ldx [$tbl+$acc8],$acc8
- sll $s1,3,$acc11
- and $acc10,2040,$acc10
- ldx [$tbl+$acc9],$acc9
- fmovs %f0,%f0
- srl $s3,21,$acc12 !
- and $acc11,2040,$acc11
- ldx [$tbl+$acc10],$acc10
- srl $s0,13,$acc13
- and $acc12,2040,$acc12
- ldx [$tbl+$acc11],$acc11
- srl $s1,5,$acc14
- and $acc13,2040,$acc13
- ldx [$tbl+$acc12],$acc12 !
- sll $s2,3,$acc15
- and $acc14,2040,$acc14
- ldx [$tbl+$acc13],$acc13
- and $acc15,2040,$acc15
- add $key,32,$key
- ldx [$tbl+$acc14],$acc14
- fmovs %f0,%f0
- subcc $rounds,1,$rounds !
- ldx [$tbl+$acc15],$acc15
- bz,a,pn %icc,.Lenc_last
- add $tbl,2048,$rounds
-
- srlx $acc1,8,$acc1
- xor $acc0,$t0,$t0
- ld [$key+0],$s0
- fmovs %f0,%f0
- srlx $acc2,16,$acc2 !
- xor $acc1,$t0,$t0
- ld [$key+4],$s1
- srlx $acc3,24,$acc3
- xor $acc2,$t0,$t0
- ld [$key+8],$s2
- srlx $acc5,8,$acc5
- xor $acc3,$t0,$t0
- ld [$key+12],$s3 !
- srlx $acc6,16,$acc6
- xor $acc4,$t1,$t1
- fmovs %f0,%f0
- srlx $acc7,24,$acc7
- xor $acc5,$t1,$t1
- srlx $acc9,8,$acc9
- xor $acc6,$t1,$t1
- srlx $acc10,16,$acc10 !
- xor $acc7,$t1,$t1
- srlx $acc11,24,$acc11
- xor $acc8,$t2,$t2
- srlx $acc13,8,$acc13
- xor $acc9,$t2,$t2
- srlx $acc14,16,$acc14
- xor $acc10,$t2,$t2
- srlx $acc15,24,$acc15 !
- xor $acc11,$t2,$t2
- xor $acc12,$acc14,$acc14
- xor $acc13,$t3,$t3
- srl $t0,21,$acc0
- xor $acc14,$t3,$t3
- srl $t1,13,$acc1
- xor $acc15,$t3,$t3
-
- and $acc0,2040,$acc0 !
- srl $t2,5,$acc2
- and $acc1,2040,$acc1
- ldx [$tbl+$acc0],$acc0
- sll $t3,3,$acc3
- and $acc2,2040,$acc2
- ldx [$tbl+$acc1],$acc1
- fmovs %f0,%f0
- srl $t1,21,$acc4 !
- and $acc3,2040,$acc3
- ldx [$tbl+$acc2],$acc2
- srl $t2,13,$acc5
- and $acc4,2040,$acc4
- ldx [$tbl+$acc3],$acc3
- srl $t3,5,$acc6
- and $acc5,2040,$acc5
- ldx [$tbl+$acc4],$acc4 !
- sll $t0,3,$acc7
- and $acc6,2040,$acc6
- ldx [$tbl+$acc5],$acc5
- srl $t2,21,$acc8
- and $acc7,2040,$acc7
- ldx [$tbl+$acc6],$acc6
- fmovs %f0,%f0
- srl $t3,13,$acc9 !
- and $acc8,2040,$acc8
- ldx [$tbl+$acc7],$acc7
- srl $t0,5,$acc10
- and $acc9,2040,$acc9
- ldx [$tbl+$acc8],$acc8
- sll $t1,3,$acc11
- and $acc10,2040,$acc10
- ldx [$tbl+$acc9],$acc9 !
- srl $t3,21,$acc12
- and $acc11,2040,$acc11
- ldx [$tbl+$acc10],$acc10
- srl $t0,13,$acc13
- and $acc12,2040,$acc12
- ldx [$tbl+$acc11],$acc11
- fmovs %f0,%f0
- srl $t1,5,$acc14 !
- and $acc13,2040,$acc13
- ldx [$tbl+$acc12],$acc12
- sll $t2,3,$acc15
- and $acc14,2040,$acc14
- ldx [$tbl+$acc13],$acc13
- srlx $acc1,8,$acc1
- and $acc15,2040,$acc15
- ldx [$tbl+$acc14],$acc14 !
-
- srlx $acc2,16,$acc2
- xor $acc0,$s0,$s0
- ldx [$tbl+$acc15],$acc15
- srlx $acc3,24,$acc3
- xor $acc1,$s0,$s0
- ld [$key+16],$t0
- fmovs %f0,%f0
- srlx $acc5,8,$acc5 !
- xor $acc2,$s0,$s0
- ld [$key+20],$t1
- srlx $acc6,16,$acc6
- xor $acc3,$s0,$s0
- ld [$key+24],$t2
- srlx $acc7,24,$acc7
- xor $acc4,$s1,$s1
- ld [$key+28],$t3 !
- srlx $acc9,8,$acc9
- xor $acc5,$s1,$s1
- ldx [$tbl+2048+0],%g0 ! prefetch te4
- srlx $acc10,16,$acc10
- xor $acc6,$s1,$s1
- ldx [$tbl+2048+32],%g0 ! prefetch te4
- srlx $acc11,24,$acc11
- xor $acc7,$s1,$s1
- ldx [$tbl+2048+64],%g0 ! prefetch te4
- srlx $acc13,8,$acc13
- xor $acc8,$s2,$s2
- ldx [$tbl+2048+96],%g0 ! prefetch te4
- srlx $acc14,16,$acc14 !
- xor $acc9,$s2,$s2
- ldx [$tbl+2048+128],%g0 ! prefetch te4
- srlx $acc15,24,$acc15
- xor $acc10,$s2,$s2
- ldx [$tbl+2048+160],%g0 ! prefetch te4
- srl $s0,21,$acc0
- xor $acc11,$s2,$s2
- ldx [$tbl+2048+192],%g0 ! prefetch te4
- xor $acc12,$acc14,$acc14
- xor $acc13,$s3,$s3
- ldx [$tbl+2048+224],%g0 ! prefetch te4
- srl $s1,13,$acc1 !
- xor $acc14,$s3,$s3
- xor $acc15,$s3,$s3
- ba .Lenc_loop
- and $acc0,2040,$acc0
-
-.align 32
-.Lenc_last:
- srlx $acc1,8,$acc1 !
- xor $acc0,$t0,$t0
- ld [$key+0],$s0
- srlx $acc2,16,$acc2
- xor $acc1,$t0,$t0
- ld [$key+4],$s1
- srlx $acc3,24,$acc3
- xor $acc2,$t0,$t0
- ld [$key+8],$s2 !
- srlx $acc5,8,$acc5
- xor $acc3,$t0,$t0
- ld [$key+12],$s3
- srlx $acc6,16,$acc6
- xor $acc4,$t1,$t1
- srlx $acc7,24,$acc7
- xor $acc5,$t1,$t1
- srlx $acc9,8,$acc9 !
- xor $acc6,$t1,$t1
- srlx $acc10,16,$acc10
- xor $acc7,$t1,$t1
- srlx $acc11,24,$acc11
- xor $acc8,$t2,$t2
- srlx $acc13,8,$acc13
- xor $acc9,$t2,$t2
- srlx $acc14,16,$acc14 !
- xor $acc10,$t2,$t2
- srlx $acc15,24,$acc15
- xor $acc11,$t2,$t2
- xor $acc12,$acc14,$acc14
- xor $acc13,$t3,$t3
- srl $t0,24,$acc0
- xor $acc14,$t3,$t3
- srl $t1,16,$acc1 !
- xor $acc15,$t3,$t3
-
- srl $t2,8,$acc2
- and $acc1,255,$acc1
- ldub [$rounds+$acc0],$acc0
- srl $t1,24,$acc4
- and $acc2,255,$acc2
- ldub [$rounds+$acc1],$acc1
- srl $t2,16,$acc5 !
- and $t3,255,$acc3
- ldub [$rounds+$acc2],$acc2
- ldub [$rounds+$acc3],$acc3
- srl $t3,8,$acc6
- and $acc5,255,$acc5
- ldub [$rounds+$acc4],$acc4
- fmovs %f0,%f0
- srl $t2,24,$acc8 !
- and $acc6,255,$acc6
- ldub [$rounds+$acc5],$acc5
- srl $t3,16,$acc9
- and $t0,255,$acc7
- ldub [$rounds+$acc6],$acc6
- ldub [$rounds+$acc7],$acc7
- fmovs %f0,%f0
- srl $t0,8,$acc10 !
- and $acc9,255,$acc9
- ldub [$rounds+$acc8],$acc8
- srl $t3,24,$acc12
- and $acc10,255,$acc10
- ldub [$rounds+$acc9],$acc9
- srl $t0,16,$acc13
- and $t1,255,$acc11
- ldub [$rounds+$acc10],$acc10 !
- srl $t1,8,$acc14
- and $acc13,255,$acc13
- ldub [$rounds+$acc11],$acc11
- ldub [$rounds+$acc12],$acc12
- and $acc14,255,$acc14
- ldub [$rounds+$acc13],$acc13
- and $t2,255,$acc15
- ldub [$rounds+$acc14],$acc14 !
-
- sll $acc0,24,$acc0
- xor $acc3,$s0,$s0
- ldub [$rounds+$acc15],$acc15
- sll $acc1,16,$acc1
- xor $acc0,$s0,$s0
- ldx [%sp+$bias+$frame+0],%i7 ! restore return address
- fmovs %f0,%f0
- sll $acc2,8,$acc2 !
- xor $acc1,$s0,$s0
- sll $acc4,24,$acc4
- xor $acc2,$s0,$s0
- sll $acc5,16,$acc5
- xor $acc7,$s1,$s1
- sll $acc6,8,$acc6
- xor $acc4,$s1,$s1
- sll $acc8,24,$acc8 !
- xor $acc5,$s1,$s1
- sll $acc9,16,$acc9
- xor $acc11,$s2,$s2
- sll $acc10,8,$acc10
- xor $acc6,$s1,$s1
- sll $acc12,24,$acc12
- xor $acc8,$s2,$s2
- sll $acc13,16,$acc13 !
- xor $acc9,$s2,$s2
- sll $acc14,8,$acc14
- xor $acc10,$s2,$s2
- xor $acc12,$acc14,$acc14
- xor $acc13,$s3,$s3
- xor $acc14,$s3,$s3
- xor $acc15,$s3,$s3
-
- ret
- restore
-.type _sparcv9_AES_encrypt,#function
-.size _sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt)
-
-.align 32
-.globl AES_encrypt
-AES_encrypt:
- or %o0,%o1,%g1
- andcc %g1,3,%g0
- bnz,pn %xcc,.Lunaligned_enc
- save %sp,-$frame,%sp
-
- ld [%i0+0],%o0
- ld [%i0+4],%o1
- ld [%i0+8],%o2
- ld [%i0+12],%o3
-
-1: call .+8
- add %o7,AES_Te-1b,%o4
- call _sparcv9_AES_encrypt
- mov %i2,%o5
-
- st %o0,[%i1+0]
- st %o1,[%i1+4]
- st %o2,[%i1+8]
- st %o3,[%i1+12]
-
- ret
- restore
-
-.align 32
-.Lunaligned_enc:
- ldub [%i0+0],%l0
- ldub [%i0+1],%l1
- ldub [%i0+2],%l2
-
- sll %l0,24,%l0
- ldub [%i0+3],%l3
- sll %l1,16,%l1
- ldub [%i0+4],%l4
- sll %l2,8,%l2
- or %l1,%l0,%l0
- ldub [%i0+5],%l5
- sll %l4,24,%l4
- or %l3,%l2,%l2
- ldub [%i0+6],%l6
- sll %l5,16,%l5
- or %l0,%l2,%o0
- ldub [%i0+7],%l7
-
- sll %l6,8,%l6
- or %l5,%l4,%l4
- ldub [%i0+8],%l0
- or %l7,%l6,%l6
- ldub [%i0+9],%l1
- or %l4,%l6,%o1
- ldub [%i0+10],%l2
-
- sll %l0,24,%l0
- ldub [%i0+11],%l3
- sll %l1,16,%l1
- ldub [%i0+12],%l4
- sll %l2,8,%l2
- or %l1,%l0,%l0
- ldub [%i0+13],%l5
- sll %l4,24,%l4
- or %l3,%l2,%l2
- ldub [%i0+14],%l6
- sll %l5,16,%l5
- or %l0,%l2,%o2
- ldub [%i0+15],%l7
-
- sll %l6,8,%l6
- or %l5,%l4,%l4
- or %l7,%l6,%l6
- or %l4,%l6,%o3
-
-1: call .+8
- add %o7,AES_Te-1b,%o4
- call _sparcv9_AES_encrypt
- mov %i2,%o5
-
- srl %o0,24,%l0
- srl %o0,16,%l1
- stb %l0,[%i1+0]
- srl %o0,8,%l2
- stb %l1,[%i1+1]
- stb %l2,[%i1+2]
- srl %o1,24,%l4
- stb %o0,[%i1+3]
-
- srl %o1,16,%l5
- stb %l4,[%i1+4]
- srl %o1,8,%l6
- stb %l5,[%i1+5]
- stb %l6,[%i1+6]
- srl %o2,24,%l0
- stb %o1,[%i1+7]
-
- srl %o2,16,%l1
- stb %l0,[%i1+8]
- srl %o2,8,%l2
- stb %l1,[%i1+9]
- stb %l2,[%i1+10]
- srl %o3,24,%l4
- stb %o2,[%i1+11]
-
- srl %o3,16,%l5
- stb %l4,[%i1+12]
- srl %o3,8,%l6
- stb %l5,[%i1+13]
- stb %l6,[%i1+14]
- stb %o3,[%i1+15]
-
- ret
- restore
-.type AES_encrypt,#function
-.size AES_encrypt,(.-AES_encrypt)
-
-___
-
-$code.=<<___;
-.align 256
-AES_Td:
-___
-&_data_word(
- 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
- 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
- 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
- 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
- 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
- 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
- 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
- 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
- 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
- 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
- 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
- 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
- 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
- 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
- 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
- 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
- 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
- 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
- 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
- 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
- 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
- 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
- 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
- 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
- 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
- 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
- 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
- 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
- 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
- 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
- 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
- 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
- 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
- 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
- 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
- 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
- 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
- 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
- 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
- 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
- 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
- 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
- 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
- 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
- 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
- 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
- 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
- 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
- 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
- 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
- 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
- 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
- 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
- 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
- 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
- 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
- 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
- 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
- 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
- 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
- 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
- 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
- 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
- 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
-$code.=<<___;
- .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
- .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
- .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
- .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
- .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
- .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
- .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
- .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
- .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
- .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
- .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
- .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
- .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
- .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
- .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
- .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
- .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
- .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
- .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
- .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
- .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
- .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
- .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
- .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
- .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
- .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
- .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
- .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
- .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
- .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
- .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
- .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-.type AES_Td,#object
-.size AES_Td,(.-AES_Td)
-
-.align 64
-.skip 16
-_sparcv9_AES_decrypt:
- save %sp,-$frame-$locals,%sp
- stx %i7,[%sp+$bias+$frame+0] ! off-load return address
- ld [$key+240],$rounds
- ld [$key+0],$t0
- ld [$key+4],$t1 !
- ld [$key+8],$t2
- ld [$key+12],$t3
- srl $rounds,1,$rounds
- xor $t0,$s0,$s0
- ld [$key+16],$t0
- xor $t1,$s1,$s1
- ld [$key+20],$t1
- srl $s0,21,$acc0 !
- xor $t2,$s2,$s2
- ld [$key+24],$t2
- xor $t3,$s3,$s3
- and $acc0,2040,$acc0
- ld [$key+28],$t3
- srl $s3,13,$acc1
- nop
-.Ldec_loop:
- srl $s2,5,$acc2 !
- and $acc1,2040,$acc1
- ldx [$tbl+$acc0],$acc0
- sll $s1,3,$acc3
- and $acc2,2040,$acc2
- ldx [$tbl+$acc1],$acc1
- srl $s1,21,$acc4
- and $acc3,2040,$acc3
- ldx [$tbl+$acc2],$acc2 !
- srl $s0,13,$acc5
- and $acc4,2040,$acc4
- ldx [$tbl+$acc3],$acc3
- srl $s3,5,$acc6
- and $acc5,2040,$acc5
- ldx [$tbl+$acc4],$acc4
- fmovs %f0,%f0
- sll $s2,3,$acc7 !
- and $acc6,2040,$acc6
- ldx [$tbl+$acc5],$acc5
- srl $s2,21,$acc8
- and $acc7,2040,$acc7
- ldx [$tbl+$acc6],$acc6
- srl $s1,13,$acc9
- and $acc8,2040,$acc8
- ldx [$tbl+$acc7],$acc7 !
- srl $s0,5,$acc10
- and $acc9,2040,$acc9
- ldx [$tbl+$acc8],$acc8
- sll $s3,3,$acc11
- and $acc10,2040,$acc10
- ldx [$tbl+$acc9],$acc9
- fmovs %f0,%f0
- srl $s3,21,$acc12 !
- and $acc11,2040,$acc11
- ldx [$tbl+$acc10],$acc10
- srl $s2,13,$acc13
- and $acc12,2040,$acc12
- ldx [$tbl+$acc11],$acc11
- srl $s1,5,$acc14
- and $acc13,2040,$acc13
- ldx [$tbl+$acc12],$acc12 !
- sll $s0,3,$acc15
- and $acc14,2040,$acc14
- ldx [$tbl+$acc13],$acc13
- and $acc15,2040,$acc15
- add $key,32,$key
- ldx [$tbl+$acc14],$acc14
- fmovs %f0,%f0
- subcc $rounds,1,$rounds !
- ldx [$tbl+$acc15],$acc15
- bz,a,pn %icc,.Ldec_last
- add $tbl,2048,$rounds
-
- srlx $acc1,8,$acc1
- xor $acc0,$t0,$t0
- ld [$key+0],$s0
- fmovs %f0,%f0
- srlx $acc2,16,$acc2 !
- xor $acc1,$t0,$t0
- ld [$key+4],$s1
- srlx $acc3,24,$acc3
- xor $acc2,$t0,$t0
- ld [$key+8],$s2
- srlx $acc5,8,$acc5
- xor $acc3,$t0,$t0
- ld [$key+12],$s3 !
- srlx $acc6,16,$acc6
- xor $acc4,$t1,$t1
- fmovs %f0,%f0
- srlx $acc7,24,$acc7
- xor $acc5,$t1,$t1
- srlx $acc9,8,$acc9
- xor $acc6,$t1,$t1
- srlx $acc10,16,$acc10 !
- xor $acc7,$t1,$t1
- srlx $acc11,24,$acc11
- xor $acc8,$t2,$t2
- srlx $acc13,8,$acc13
- xor $acc9,$t2,$t2
- srlx $acc14,16,$acc14
- xor $acc10,$t2,$t2
- srlx $acc15,24,$acc15 !
- xor $acc11,$t2,$t2
- xor $acc12,$acc14,$acc14
- xor $acc13,$t3,$t3
- srl $t0,21,$acc0
- xor $acc14,$t3,$t3
- xor $acc15,$t3,$t3
- srl $t3,13,$acc1
-
- and $acc0,2040,$acc0 !
- srl $t2,5,$acc2
- and $acc1,2040,$acc1
- ldx [$tbl+$acc0],$acc0
- sll $t1,3,$acc3
- and $acc2,2040,$acc2
- ldx [$tbl+$acc1],$acc1
- fmovs %f0,%f0
- srl $t1,21,$acc4 !
- and $acc3,2040,$acc3
- ldx [$tbl+$acc2],$acc2
- srl $t0,13,$acc5
- and $acc4,2040,$acc4
- ldx [$tbl+$acc3],$acc3
- srl $t3,5,$acc6
- and $acc5,2040,$acc5
- ldx [$tbl+$acc4],$acc4 !
- sll $t2,3,$acc7
- and $acc6,2040,$acc6
- ldx [$tbl+$acc5],$acc5
- srl $t2,21,$acc8
- and $acc7,2040,$acc7
- ldx [$tbl+$acc6],$acc6
- fmovs %f0,%f0
- srl $t1,13,$acc9 !
- and $acc8,2040,$acc8
- ldx [$tbl+$acc7],$acc7
- srl $t0,5,$acc10
- and $acc9,2040,$acc9
- ldx [$tbl+$acc8],$acc8
- sll $t3,3,$acc11
- and $acc10,2040,$acc10
- ldx [$tbl+$acc9],$acc9 !
- srl $t3,21,$acc12
- and $acc11,2040,$acc11
- ldx [$tbl+$acc10],$acc10
- srl $t2,13,$acc13
- and $acc12,2040,$acc12
- ldx [$tbl+$acc11],$acc11
- fmovs %f0,%f0
- srl $t1,5,$acc14 !
- and $acc13,2040,$acc13
- ldx [$tbl+$acc12],$acc12
- sll $t0,3,$acc15
- and $acc14,2040,$acc14
- ldx [$tbl+$acc13],$acc13
- srlx $acc1,8,$acc1
- and $acc15,2040,$acc15
- ldx [$tbl+$acc14],$acc14 !
-
- srlx $acc2,16,$acc2
- xor $acc0,$s0,$s0
- ldx [$tbl+$acc15],$acc15
- srlx $acc3,24,$acc3
- xor $acc1,$s0,$s0
- ld [$key+16],$t0
- fmovs %f0,%f0
- srlx $acc5,8,$acc5 !
- xor $acc2,$s0,$s0
- ld [$key+20],$t1
- srlx $acc6,16,$acc6
- xor $acc3,$s0,$s0
- ld [$key+24],$t2
- srlx $acc7,24,$acc7
- xor $acc4,$s1,$s1
- ld [$key+28],$t3 !
- srlx $acc9,8,$acc9
- xor $acc5,$s1,$s1
- ldx [$tbl+2048+0],%g0 ! prefetch td4
- srlx $acc10,16,$acc10
- xor $acc6,$s1,$s1
- ldx [$tbl+2048+32],%g0 ! prefetch td4
- srlx $acc11,24,$acc11
- xor $acc7,$s1,$s1
- ldx [$tbl+2048+64],%g0 ! prefetch td4
- srlx $acc13,8,$acc13
- xor $acc8,$s2,$s2
- ldx [$tbl+2048+96],%g0 ! prefetch td4
- srlx $acc14,16,$acc14 !
- xor $acc9,$s2,$s2
- ldx [$tbl+2048+128],%g0 ! prefetch td4
- srlx $acc15,24,$acc15
- xor $acc10,$s2,$s2
- ldx [$tbl+2048+160],%g0 ! prefetch td4
- srl $s0,21,$acc0
- xor $acc11,$s2,$s2
- ldx [$tbl+2048+192],%g0 ! prefetch td4
- xor $acc12,$acc14,$acc14
- xor $acc13,$s3,$s3
- ldx [$tbl+2048+224],%g0 ! prefetch td4
- and $acc0,2040,$acc0 !
- xor $acc14,$s3,$s3
- xor $acc15,$s3,$s3
- ba .Ldec_loop
- srl $s3,13,$acc1
-
-.align 32
-.Ldec_last:
- srlx $acc1,8,$acc1 !
- xor $acc0,$t0,$t0
- ld [$key+0],$s0
- srlx $acc2,16,$acc2
- xor $acc1,$t0,$t0
- ld [$key+4],$s1
- srlx $acc3,24,$acc3
- xor $acc2,$t0,$t0
- ld [$key+8],$s2 !
- srlx $acc5,8,$acc5
- xor $acc3,$t0,$t0
- ld [$key+12],$s3
- srlx $acc6,16,$acc6
- xor $acc4,$t1,$t1
- srlx $acc7,24,$acc7
- xor $acc5,$t1,$t1
- srlx $acc9,8,$acc9 !
- xor $acc6,$t1,$t1
- srlx $acc10,16,$acc10
- xor $acc7,$t1,$t1
- srlx $acc11,24,$acc11
- xor $acc8,$t2,$t2
- srlx $acc13,8,$acc13
- xor $acc9,$t2,$t2
- srlx $acc14,16,$acc14 !
- xor $acc10,$t2,$t2
- srlx $acc15,24,$acc15
- xor $acc11,$t2,$t2
- xor $acc12,$acc14,$acc14
- xor $acc13,$t3,$t3
- srl $t0,24,$acc0
- xor $acc14,$t3,$t3
- xor $acc15,$t3,$t3 !
- srl $t3,16,$acc1
-
- srl $t2,8,$acc2
- and $acc1,255,$acc1
- ldub [$rounds+$acc0],$acc0
- srl $t1,24,$acc4
- and $acc2,255,$acc2
- ldub [$rounds+$acc1],$acc1
- srl $t0,16,$acc5 !
- and $t1,255,$acc3
- ldub [$rounds+$acc2],$acc2
- ldub [$rounds+$acc3],$acc3
- srl $t3,8,$acc6
- and $acc5,255,$acc5
- ldub [$rounds+$acc4],$acc4
- fmovs %f0,%f0
- srl $t2,24,$acc8 !
- and $acc6,255,$acc6
- ldub [$rounds+$acc5],$acc5
- srl $t1,16,$acc9
- and $t2,255,$acc7
- ldub [$rounds+$acc6],$acc6
- ldub [$rounds+$acc7],$acc7
- fmovs %f0,%f0
- srl $t0,8,$acc10 !
- and $acc9,255,$acc9
- ldub [$rounds+$acc8],$acc8
- srl $t3,24,$acc12
- and $acc10,255,$acc10
- ldub [$rounds+$acc9],$acc9
- srl $t2,16,$acc13
- and $t3,255,$acc11
- ldub [$rounds+$acc10],$acc10 !
- srl $t1,8,$acc14
- and $acc13,255,$acc13
- ldub [$rounds+$acc11],$acc11
- ldub [$rounds+$acc12],$acc12
- and $acc14,255,$acc14
- ldub [$rounds+$acc13],$acc13
- and $t0,255,$acc15
- ldub [$rounds+$acc14],$acc14 !
-
- sll $acc0,24,$acc0
- xor $acc3,$s0,$s0
- ldub [$rounds+$acc15],$acc15
- sll $acc1,16,$acc1
- xor $acc0,$s0,$s0
- ldx [%sp+$bias+$frame+0],%i7 ! restore return address
- fmovs %f0,%f0
- sll $acc2,8,$acc2 !
- xor $acc1,$s0,$s0
- sll $acc4,24,$acc4
- xor $acc2,$s0,$s0
- sll $acc5,16,$acc5
- xor $acc7,$s1,$s1
- sll $acc6,8,$acc6
- xor $acc4,$s1,$s1
- sll $acc8,24,$acc8 !
- xor $acc5,$s1,$s1
- sll $acc9,16,$acc9
- xor $acc11,$s2,$s2
- sll $acc10,8,$acc10
- xor $acc6,$s1,$s1
- sll $acc12,24,$acc12
- xor $acc8,$s2,$s2
- sll $acc13,16,$acc13 !
- xor $acc9,$s2,$s2
- sll $acc14,8,$acc14
- xor $acc10,$s2,$s2
- xor $acc12,$acc14,$acc14
- xor $acc13,$s3,$s3
- xor $acc14,$s3,$s3
- xor $acc15,$s3,$s3
-
- ret
- restore
-.type _sparcv9_AES_decrypt,#function
-.size _sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt)
-
-.align 32
-.globl AES_decrypt
-AES_decrypt:
- or %o0,%o1,%g1
- andcc %g1,3,%g0
- bnz,pn %xcc,.Lunaligned_dec
- save %sp,-$frame,%sp
-
- ld [%i0+0],%o0
- ld [%i0+4],%o1
- ld [%i0+8],%o2
- ld [%i0+12],%o3
-
-1: call .+8
- add %o7,AES_Td-1b,%o4
- call _sparcv9_AES_decrypt
- mov %i2,%o5
-
- st %o0,[%i1+0]
- st %o1,[%i1+4]
- st %o2,[%i1+8]
- st %o3,[%i1+12]
-
- ret
- restore
-
-.align 32
-.Lunaligned_dec:
- ldub [%i0+0],%l0
- ldub [%i0+1],%l1
- ldub [%i0+2],%l2
-
- sll %l0,24,%l0
- ldub [%i0+3],%l3
- sll %l1,16,%l1
- ldub [%i0+4],%l4
- sll %l2,8,%l2
- or %l1,%l0,%l0
- ldub [%i0+5],%l5
- sll %l4,24,%l4
- or %l3,%l2,%l2
- ldub [%i0+6],%l6
- sll %l5,16,%l5
- or %l0,%l2,%o0
- ldub [%i0+7],%l7
-
- sll %l6,8,%l6
- or %l5,%l4,%l4
- ldub [%i0+8],%l0
- or %l7,%l6,%l6
- ldub [%i0+9],%l1
- or %l4,%l6,%o1
- ldub [%i0+10],%l2
-
- sll %l0,24,%l0
- ldub [%i0+11],%l3
- sll %l1,16,%l1
- ldub [%i0+12],%l4
- sll %l2,8,%l2
- or %l1,%l0,%l0
- ldub [%i0+13],%l5
- sll %l4,24,%l4
- or %l3,%l2,%l2
- ldub [%i0+14],%l6
- sll %l5,16,%l5
- or %l0,%l2,%o2
- ldub [%i0+15],%l7
-
- sll %l6,8,%l6
- or %l5,%l4,%l4
- or %l7,%l6,%l6
- or %l4,%l6,%o3
-
-1: call .+8
- add %o7,AES_Td-1b,%o4
- call _sparcv9_AES_decrypt
- mov %i2,%o5
-
- srl %o0,24,%l0
- srl %o0,16,%l1
- stb %l0,[%i1+0]
- srl %o0,8,%l2
- stb %l1,[%i1+1]
- stb %l2,[%i1+2]
- srl %o1,24,%l4
- stb %o0,[%i1+3]
-
- srl %o1,16,%l5
- stb %l4,[%i1+4]
- srl %o1,8,%l6
- stb %l5,[%i1+5]
- stb %l6,[%i1+6]
- srl %o2,24,%l0
- stb %o1,[%i1+7]
-
- srl %o2,16,%l1
- stb %l0,[%i1+8]
- srl %o2,8,%l2
- stb %l1,[%i1+9]
- stb %l2,[%i1+10]
- srl %o3,24,%l4
- stb %o2,[%i1+11]
-
- srl %o3,16,%l5
- stb %l4,[%i1+12]
- srl %o3,8,%l6
- stb %l5,[%i1+13]
- stb %l6,[%i1+14]
- stb %o3,[%i1+15]
-
- ret
- restore
-.type AES_decrypt,#function
-.size AES_decrypt,(.-AES_decrypt)
-___
-
-# fmovs instructions substituting for FP nops were originally added
-# to meet specific instruction alignment requirements to maximize ILP.
-# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
-# undesired effect, so just omit them and sacrifice some portion of
-# percent in performance...
-$code =~ s/fmovs.*$//gem;
-
-print $code;
diff --git a/crypto/openssl/crypto/aes/asm/aes-x86_64.pl b/crypto/openssl/crypto/aes/asm/aes-x86_64.pl
index f616f17..b008ab5 100755
--- a/crypto/openssl/crypto/aes/asm/aes-x86_64.pl
+++ b/crypto/openssl/crypto/aes/asm/aes-x86_64.pl
@@ -1181,12 +1181,12 @@ AES_cbc_encrypt:
.Lcbc_cleanup:
cmpl \$0,$mark # was the key schedule copied?
lea $aes_key,%rdi
- mov $_rsp,%rsp
je .Lcbc_exit
mov \$240/8,%ecx
xor %rax,%rax
.long 0x90AB48F3 # rep stosq
.Lcbc_exit:
+ mov $_rsp,%rsp
popfq
pop %r15
pop %r14
diff --git a/crypto/openssl/crypto/asn1/a_mbstr.c b/crypto/openssl/crypto/asn1/a_mbstr.c
index 1bcd046..1538e0a 100644
--- a/crypto/openssl/crypto/asn1/a_mbstr.c
+++ b/crypto/openssl/crypto/asn1/a_mbstr.c
@@ -93,7 +93,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
int str_type;
int ret;
char free_out;
- int outform, outlen;
+ int outform, outlen = 0;
ASN1_STRING *dest;
unsigned char *p;
int nchar;
diff --git a/crypto/openssl/crypto/asn1/a_object.c b/crypto/openssl/crypto/asn1/a_object.c
index dc98042..365e467 100644
--- a/crypto/openssl/crypto/asn1/a_object.c
+++ b/crypto/openssl/crypto/asn1/a_object.c
@@ -291,6 +291,17 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
ASN1_OBJECT *ret=NULL;
const unsigned char *p;
int i;
+ /* Sanity check OID encoding: can't have leading 0x80 in
+ * subidentifiers, see: X.690 8.19.2
+ */
+ for (i = 0, p = *pp + 1; i < len - 1; i++, p++)
+ {
+ if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
+ {
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ }
/* only the ASN1_OBJECTs from the 'table' will have values
* for ->sn or ->ln */
diff --git a/crypto/openssl/crypto/asn1/ameth_lib.c b/crypto/openssl/crypto/asn1/ameth_lib.c
deleted file mode 100644
index 18957c6..0000000
--- a/crypto/openssl/crypto/asn1/ameth_lib.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006.
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/asn1t.h>
-#include <openssl/x509.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-#include "asn1_locl.h"
-
-extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
-extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
-extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
-
-/* Keep this sorted in type order !! */
-static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
- {
-#ifndef OPENSSL_NO_RSA
- &rsa_asn1_meths[0],
- &rsa_asn1_meths[1],
-#endif
-#ifndef OPENSSL_NO_DH
- &dh_asn1_meth,
-#endif
-#ifndef OPENSSL_NO_DSA
- &dsa_asn1_meths[0],
- &dsa_asn1_meths[1],
- &dsa_asn1_meths[2],
- &dsa_asn1_meths[3],
- &dsa_asn1_meths[4],
-#endif
-#ifndef OPENSSL_NO_EC
- &eckey_asn1_meth,
-#endif
- &hmac_asn1_meth
- };
-
-typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
-DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
-static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
-
-
-
-#ifdef TEST
-void main()
- {
- int i;
- for (i = 0;
- i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
- i++)
- fprintf(stderr, "Number %d id=%d (%s)\n", i,
- standard_methods[i]->pkey_id,
- OBJ_nid2sn(standard_methods[i]->pkey_id));
- }
-#endif
-
-DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
- const EVP_PKEY_ASN1_METHOD *, ameth);
-
-static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
- const EVP_PKEY_ASN1_METHOD * const *b)
- {
- return ((*a)->pkey_id - (*b)->pkey_id);
- }
-
-IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
- const EVP_PKEY_ASN1_METHOD *, ameth);
-
-int EVP_PKEY_asn1_get_count(void)
- {
- int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
- if (app_methods)
- num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
- return num;
- }
-
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
- {
- int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
- if (idx < 0)
- return NULL;
- if (idx < num)
- return standard_methods[idx];
- idx -= num;
- return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
-
-static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
- {
- EVP_PKEY_ASN1_METHOD tmp;
- const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
- tmp.pkey_id = type;
- if (app_methods)
- {
- int idx;
- idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
- if (idx >= 0)
- return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
- ret = OBJ_bsearch_ameth(&t, standard_methods,
- sizeof(standard_methods)
- /sizeof(EVP_PKEY_ASN1_METHOD *));
- if (!ret || !*ret)
- return NULL;
- return *ret;
- }
-
-/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
- * also search through engines and set *pe to a functional reference
- * to the engine implementing 'type' or NULL if no engine implements
- * it.
- */
-
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
- {
- const EVP_PKEY_ASN1_METHOD *t;
- ENGINE *e;
-
- for (;;)
- {
- t = pkey_asn1_find(type);
- if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
- break;
- type = t->pkey_base_id;
- }
- if (pe)
- {
-#ifndef OPENSSL_NO_ENGINE
- /* type will contain the final unaliased type */
- e = ENGINE_get_pkey_asn1_meth_engine(type);
- if (e)
- {
- *pe = e;
- return ENGINE_get_pkey_asn1_meth(e, type);
- }
-#endif
- *pe = NULL;
- }
- return t;
- }
-
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
- const char *str, int len)
- {
- int i;
- const EVP_PKEY_ASN1_METHOD *ameth;
- if (len == -1)
- len = strlen(str);
- if (pe)
- {
-#ifndef OPENSSL_NO_ENGINE
- ENGINE *e;
- ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
- if (ameth)
- {
- /* Convert structural into
- * functional reference
- */
- if (!ENGINE_init(e))
- ameth = NULL;
- ENGINE_free(e);
- *pe = e;
- return ameth;
- }
-#endif
- *pe = NULL;
- }
- for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
- {
- ameth = EVP_PKEY_asn1_get0(i);
- if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
- continue;
- if (((int)strlen(ameth->pem_str) == len) &&
- !strncasecmp(ameth->pem_str, str, len))
- return ameth;
- }
- return NULL;
- }
-
-int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
- {
- if (app_methods == NULL)
- {
- app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
- if (!app_methods)
- return 0;
- }
- if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
- return 0;
- sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
- return 1;
- }
-
-int EVP_PKEY_asn1_add_alias(int to, int from)
- {
- EVP_PKEY_ASN1_METHOD *ameth;
- ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
- if (!ameth)
- return 0;
- ameth->pkey_base_id = to;
- return EVP_PKEY_asn1_add0(ameth);
- }
-
-int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
- const char **pinfo, const char **ppem_str,
- const EVP_PKEY_ASN1_METHOD *ameth)
- {
- if (!ameth)
- return 0;
- if (ppkey_id)
- *ppkey_id = ameth->pkey_id;
- if (ppkey_base_id)
- *ppkey_base_id = ameth->pkey_base_id;
- if (ppkey_flags)
- *ppkey_flags = ameth->pkey_flags;
- if (pinfo)
- *pinfo = ameth->info;
- if (ppem_str)
- *ppem_str = ameth->pem_str;
- return 1;
- }
-
-const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
- {
- return pkey->ameth;
- }
-
-EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
- const char *pem_str, const char *info)
- {
- EVP_PKEY_ASN1_METHOD *ameth;
- ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
- if (!ameth)
- return NULL;
-
- ameth->pkey_id = id;
- ameth->pkey_base_id = id;
- ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
-
- if (info)
- {
- ameth->info = BUF_strdup(info);
- if (!ameth->info)
- goto err;
- }
-
- if (pem_str)
- {
- ameth->pem_str = BUF_strdup(pem_str);
- if (!ameth->pem_str)
- goto err;
- }
-
- ameth->pub_decode = 0;
- ameth->pub_encode = 0;
- ameth->pub_cmp = 0;
- ameth->pub_print = 0;
-
- ameth->priv_decode = 0;
- ameth->priv_encode = 0;
- ameth->priv_print = 0;
-
- ameth->old_priv_encode = 0;
- ameth->old_priv_decode = 0;
-
- ameth->pkey_size = 0;
- ameth->pkey_bits = 0;
-
- ameth->param_decode = 0;
- ameth->param_encode = 0;
- ameth->param_missing = 0;
- ameth->param_copy = 0;
- ameth->param_cmp = 0;
- ameth->param_print = 0;
-
- ameth->pkey_free = 0;
- ameth->pkey_ctrl = 0;
-
- return ameth;
-
- err:
-
- EVP_PKEY_asn1_free(ameth);
- return NULL;
-
- }
-
-void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
- const EVP_PKEY_ASN1_METHOD *src)
- {
-
- dst->pub_decode = src->pub_decode;
- dst->pub_encode = src->pub_encode;
- dst->pub_cmp = src->pub_cmp;
- dst->pub_print = src->pub_print;
-
- dst->priv_decode = src->priv_decode;
- dst->priv_encode = src->priv_encode;
- dst->priv_print = src->priv_print;
-
- dst->old_priv_encode = src->old_priv_encode;
- dst->old_priv_decode = src->old_priv_decode;
-
- dst->pkey_size = src->pkey_size;
- dst->pkey_bits = src->pkey_bits;
-
- dst->param_decode = src->param_decode;
- dst->param_encode = src->param_encode;
- dst->param_missing = src->param_missing;
- dst->param_copy = src->param_copy;
- dst->param_cmp = src->param_cmp;
- dst->param_print = src->param_print;
-
- dst->pkey_free = src->pkey_free;
- dst->pkey_ctrl = src->pkey_ctrl;
-
- }
-
-void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
- {
- if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
- {
- if (ameth->pem_str)
- OPENSSL_free(ameth->pem_str);
- if (ameth->info)
- OPENSSL_free(ameth->info);
- OPENSSL_free(ameth);
- }
- }
-
-void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
- int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
- int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
- int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
- int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx),
- int (*pkey_size)(const EVP_PKEY *pk),
- int (*pkey_bits)(const EVP_PKEY *pk))
- {
- ameth->pub_decode = pub_decode;
- ameth->pub_encode = pub_encode;
- ameth->pub_cmp = pub_cmp;
- ameth->pub_print = pub_print;
- ameth->pkey_size = pkey_size;
- ameth->pkey_bits = pkey_bits;
- }
-
-void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
- int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
- int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
- int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx))
- {
- ameth->priv_decode = priv_decode;
- ameth->priv_encode = priv_encode;
- ameth->priv_print = priv_print;
- }
-
-void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
- int (*param_decode)(EVP_PKEY *pkey,
- const unsigned char **pder, int derlen),
- int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
- int (*param_missing)(const EVP_PKEY *pk),
- int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
- int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
- int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx))
- {
- ameth->param_decode = param_decode;
- ameth->param_encode = param_encode;
- ameth->param_missing = param_missing;
- ameth->param_copy = param_copy;
- ameth->param_cmp = param_cmp;
- ameth->param_print = param_print;
- }
-
-void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
- void (*pkey_free)(EVP_PKEY *pkey))
- {
- ameth->pkey_free = pkey_free;
- }
-
-void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
- int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
- long arg1, void *arg2))
- {
- ameth->pkey_ctrl = pkey_ctrl;
- }
diff --git a/crypto/openssl/crypto/asn1/asn1.h b/crypto/openssl/crypto/asn1/asn1.h
index e338522..1958298 100644
--- a/crypto/openssl/crypto/asn1/asn1.h
+++ b/crypto/openssl/crypto/asn1/asn1.h
@@ -344,6 +344,8 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
((void*) (1 ? p : (type*)0))
#define CHECKED_PPTR_OF(type, p) \
((void**) (1 ? p : (type**)0))
+#define CHECKED_PTR_OF_TO_CHAR(type, p) \
+ ((char*) (1 ? p : (type*)0))
#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
@@ -933,12 +935,12 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
#define ASN1_dup_of(type,i2d,d2i,x) \
((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
CHECKED_D2I_OF(type, d2i), \
- CHECKED_PTR_OF(type, x)))
+ CHECKED_PTR_OF_TO_CHAR(type, x)))
#define ASN1_dup_of_const(type,i2d,d2i,x) \
((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
CHECKED_D2I_OF(type, d2i), \
- CHECKED_PTR_OF(const type, x)))
+ CHECKED_PTR_OF_TO_CHAR(const type, x)))
void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
@@ -1263,6 +1265,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_INVALID_MIME_TYPE 200
#define ASN1_R_INVALID_MODIFIER 186
#define ASN1_R_INVALID_NUMBER 187
+#define ASN1_R_INVALID_OBJECT_ENCODING 212
#define ASN1_R_INVALID_SEPARATOR 131
#define ASN1_R_INVALID_TIME_FORMAT 132
#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
diff --git a/crypto/openssl/crypto/asn1/asn1_err.c b/crypto/openssl/crypto/asn1/asn1_err.c
index 5f5de98..ba88eb3 100644
--- a/crypto/openssl/crypto/asn1/asn1_err.c
+++ b/crypto/openssl/crypto/asn1/asn1_err.c
@@ -240,6 +240,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
+{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"},
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
diff --git a/crypto/openssl/crypto/asn1/asn1_gen.c b/crypto/openssl/crypto/asn1/asn1_gen.c
index 2da3829..213a8e9 100644
--- a/crypto/openssl/crypto/asn1/asn1_gen.c
+++ b/crypto/openssl/crypto/asn1/asn1_gen.c
@@ -227,6 +227,8 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
/* Allocate buffer for new encoding */
new_der = OPENSSL_malloc(len);
+ if (!new_der)
+ goto err;
/* Generate tagged encoding */
@@ -446,6 +448,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
int derlen;
int i, is_set;
sk = sk_ASN1_TYPE_new_null();
+ if (!sk)
+ goto bad;
if (section)
{
if (!cnf)
@@ -458,7 +462,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
if (!typ)
goto bad;
- sk_ASN1_TYPE_push(sk, typ);
+ if (!sk_ASN1_TYPE_push(sk, typ))
+ goto bad;
typ = NULL;
}
}
@@ -474,6 +479,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype,
V_ASN1_UNIVERSAL, is_set);
der = OPENSSL_malloc(derlen);
+ if (!der)
+ goto bad;
p = der;
i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype,
V_ASN1_UNIVERSAL, is_set);
diff --git a/crypto/openssl/crypto/asn1/asn1_locl.h b/crypto/openssl/crypto/asn1/asn1_locl.h
deleted file mode 100644
index 5aa65e2..0000000
--- a/crypto/openssl/crypto/asn1/asn1_locl.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* asn1t.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006.
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/* Internal ASN1 structures and functions: not for application use */
-
-/* ASN1 print context structure */
-
-struct asn1_pctx_st
- {
- unsigned long flags;
- unsigned long nm_flags;
- unsigned long cert_flags;
- unsigned long oid_flags;
- unsigned long str_flags;
- } /* ASN1_PCTX */;
-
-/* ASN1 public key method structure */
-
-struct evp_pkey_asn1_method_st
- {
- int pkey_id;
- int pkey_base_id;
- unsigned long pkey_flags;
-
- char *pem_str;
- char *info;
-
- int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
- int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
- int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
- int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx);
-
- int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
- int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
- int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx);
-
- int (*pkey_size)(const EVP_PKEY *pk);
- int (*pkey_bits)(const EVP_PKEY *pk);
-
- int (*param_decode)(EVP_PKEY *pkey,
- const unsigned char **pder, int derlen);
- int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
- int (*param_missing)(const EVP_PKEY *pk);
- int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
- int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
- int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx);
-
- void (*pkey_free)(EVP_PKEY *pkey);
- int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
-
- /* Legacy functions for old PEM */
-
- int (*old_priv_decode)(EVP_PKEY *pkey,
- const unsigned char **pder, int derlen);
- int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
-
- } /* EVP_PKEY_ASN1_METHOD */;
-
-/* Method to handle CRL access.
- * In general a CRL could be very large (several Mb) and can consume large
- * amounts of resources if stored in memory by multiple processes.
- * This method allows general CRL operations to be redirected to more
- * efficient callbacks: for example a CRL entry database.
- */
-
-#define X509_CRL_METHOD_DYNAMIC 1
-
-struct x509_crl_method_st
- {
- int flags;
- int (*crl_init)(X509_CRL *crl);
- int (*crl_free)(X509_CRL *crl);
- int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
- ASN1_INTEGER *ser, X509_NAME *issuer);
- int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
- };
diff --git a/crypto/openssl/crypto/asn1/asn1_par.c b/crypto/openssl/crypto/asn1/asn1_par.c
index 8657f73..cb08e15 100644
--- a/crypto/openssl/crypto/asn1/asn1_par.c
+++ b/crypto/openssl/crypto/asn1/asn1_par.c
@@ -246,7 +246,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
if (ii < 0)
{
- if (BIO_write(bp,"Bad boolean\n",12))
+ if (BIO_write(bp,"Bad boolean\n",12) <= 0)
goto end;
}
BIO_printf(bp,":%d",ii);
diff --git a/crypto/openssl/crypto/asn1/bio_asn1.c b/crypto/openssl/crypto/asn1/bio_asn1.c
deleted file mode 100644
index dc7efd5..0000000
--- a/crypto/openssl/crypto/asn1/bio_asn1.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/* bio_asn1.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project.
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/* Experimental ASN1 BIO. When written through the data is converted
- * to an ASN1 string type: default is OCTET STRING. Additional functions
- * can be provided to add prefix and suffix data.
- */
-
-#include <string.h>
-#include <openssl/bio.h>
-#include <openssl/asn1.h>
-
-/* Must be large enough for biggest tag+length */
-#define DEFAULT_ASN1_BUF_SIZE 20
-
-typedef enum
- {
- ASN1_STATE_START,
- ASN1_STATE_PRE_COPY,
- ASN1_STATE_HEADER,
- ASN1_STATE_HEADER_COPY,
- ASN1_STATE_DATA_COPY,
- ASN1_STATE_POST_COPY,
- ASN1_STATE_DONE
- } asn1_bio_state_t;
-
-typedef struct BIO_ASN1_EX_FUNCS_st
- {
- asn1_ps_func *ex_func;
- asn1_ps_func *ex_free_func;
- } BIO_ASN1_EX_FUNCS;
-
-typedef struct BIO_ASN1_BUF_CTX_t
- {
- /* Internal state */
- asn1_bio_state_t state;
- /* Internal buffer */
- unsigned char *buf;
- /* Size of buffer */
- int bufsize;
- /* Current position in buffer */
- int bufpos;
- /* Current buffer length */
- int buflen;
- /* Amount of data to copy */
- int copylen;
- /* Class and tag to use */
- int asn1_class, asn1_tag;
- asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
- /* Extra buffer for prefix and suffix data */
- unsigned char *ex_buf;
- int ex_len;
- int ex_pos;
- void *ex_arg;
- } BIO_ASN1_BUF_CTX;
-
-
-static int asn1_bio_write(BIO *h, const char *buf,int num);
-static int asn1_bio_read(BIO *h, char *buf, int size);
-static int asn1_bio_puts(BIO *h, const char *str);
-static int asn1_bio_gets(BIO *h, char *str, int size);
-static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int asn1_bio_new(BIO *h);
-static int asn1_bio_free(BIO *data);
-static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-
-static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
-static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *cleanup, asn1_bio_state_t next);
-static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *setup,
- asn1_bio_state_t ex_state,
- asn1_bio_state_t other_state);
-
-static BIO_METHOD methods_asn1=
- {
- BIO_TYPE_ASN1,
- "asn1",
- asn1_bio_write,
- asn1_bio_read,
- asn1_bio_puts,
- asn1_bio_gets,
- asn1_bio_ctrl,
- asn1_bio_new,
- asn1_bio_free,
- asn1_bio_callback_ctrl,
- };
-
-BIO_METHOD *BIO_f_asn1(void)
- {
- return(&methods_asn1);
- }
-
-
-static int asn1_bio_new(BIO *b)
- {
- BIO_ASN1_BUF_CTX *ctx;
- ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
- if (!ctx)
- return 0;
- if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
- return 0;
- b->init = 1;
- b->ptr = (char *)ctx;
- b->flags = 0;
- return 1;
- }
-
-static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
- {
- ctx->buf = OPENSSL_malloc(size);
- if (!ctx->buf)
- return 0;
- ctx->bufsize = size;
- ctx->bufpos = 0;
- ctx->buflen = 0;
- ctx->copylen = 0;
- ctx->asn1_class = V_ASN1_UNIVERSAL;
- ctx->asn1_tag = V_ASN1_OCTET_STRING;
- ctx->ex_buf = 0;
- ctx->ex_pos = 0;
- ctx->ex_len = 0;
- ctx->state = ASN1_STATE_START;
- return 1;
- }
-
-static int asn1_bio_free(BIO *b)
- {
- BIO_ASN1_BUF_CTX *ctx;
- ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
- if (ctx == NULL)
- return 0;
- if (ctx->buf)
- OPENSSL_free(ctx->buf);
- OPENSSL_free(ctx);
- b->init = 0;
- b->ptr = NULL;
- b->flags = 0;
- return 1;
- }
-
-static int asn1_bio_write(BIO *b, const char *in , int inl)
- {
- BIO_ASN1_BUF_CTX *ctx;
- int wrmax, wrlen, ret;
- unsigned char *p;
- if (!in || (inl < 0) || (b->next_bio == NULL))
- return 0;
- ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
- if (ctx == NULL)
- return 0;
-
- wrlen = 0;
- ret = -1;
-
- for(;;)
- {
- switch (ctx->state)
- {
-
- /* Setup prefix data, call it */
- case ASN1_STATE_START:
- if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
- ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
- return 0;
- break;
-
- /* Copy any pre data first */
- case ASN1_STATE_PRE_COPY:
-
- ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
- ASN1_STATE_HEADER);
-
- if (ret <= 0)
- goto done;
-
- break;
-
- case ASN1_STATE_HEADER:
- ctx->buflen =
- ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
- OPENSSL_assert(ctx->buflen <= ctx->bufsize);
- p = ctx->buf;
- ASN1_put_object(&p, 0, inl,
- ctx->asn1_tag, ctx->asn1_class);
- ctx->copylen = inl;
- ctx->state = ASN1_STATE_HEADER_COPY;
-
- break;
-
- case ASN1_STATE_HEADER_COPY:
- ret = BIO_write(b->next_bio,
- ctx->buf + ctx->bufpos, ctx->buflen);
- if (ret <= 0)
- goto done;
-
- ctx->buflen -= ret;
- if (ctx->buflen)
- ctx->bufpos += ret;
- else
- {
- ctx->bufpos = 0;
- ctx->state = ASN1_STATE_DATA_COPY;
- }
-
- break;
-
- case ASN1_STATE_DATA_COPY:
-
- if (inl > ctx->copylen)
- wrmax = ctx->copylen;
- else
- wrmax = inl;
- ret = BIO_write(b->next_bio, in, wrmax);
- if (ret <= 0)
- break;
- wrlen += ret;
- ctx->copylen -= ret;
- in += ret;
- inl -= ret;
-
- if (ctx->copylen == 0)
- ctx->state = ASN1_STATE_HEADER;
-
- if (inl == 0)
- goto done;
-
- break;
-
- default:
- BIO_clear_retry_flags(b);
- return 0;
-
- }
-
- }
-
- done:
- BIO_clear_retry_flags(b);
- BIO_copy_next_retry(b);
-
- return (wrlen > 0) ? wrlen : ret;
-
- }
-
-static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *cleanup, asn1_bio_state_t next)
- {
- int ret;
- if (ctx->ex_len <= 0)
- return 1;
- for(;;)
- {
- ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
- ctx->ex_len);
- if (ret <= 0)
- break;
- ctx->ex_len -= ret;
- if (ctx->ex_len > 0)
- ctx->ex_pos += ret;
- else
- {
- if(cleanup)
- cleanup(b, &ctx->ex_buf, &ctx->ex_len,
- &ctx->ex_arg);
- ctx->state = next;
- ctx->ex_pos = 0;
- break;
- }
- }
- return ret;
- }
-
-static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *setup,
- asn1_bio_state_t ex_state,
- asn1_bio_state_t other_state)
- {
- if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
- {
- BIO_clear_retry_flags(b);
- return 0;
- }
- if (ctx->ex_len > 0)
- ctx->state = ex_state;
- else
- ctx->state = other_state;
- return 1;
- }
-
-static int asn1_bio_read(BIO *b, char *in , int inl)
- {
- if (!b->next_bio)
- return 0;
- return BIO_read(b->next_bio, in , inl);
- }
-
-static int asn1_bio_puts(BIO *b, const char *str)
- {
- return asn1_bio_write(b, str, strlen(str));
- }
-
-static int asn1_bio_gets(BIO *b, char *str, int size)
- {
- if (!b->next_bio)
- return 0;
- return BIO_gets(b->next_bio, str , size);
- }
-
-static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
- {
- if (b->next_bio == NULL) return(0);
- return BIO_callback_ctrl(b->next_bio,cmd,fp);
- }
-
-static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
- {
- BIO_ASN1_BUF_CTX *ctx;
- BIO_ASN1_EX_FUNCS *ex_func;
- long ret = 1;
- ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
- if (ctx == NULL)
- return 0;
- switch(cmd)
- {
-
- case BIO_C_SET_PREFIX:
- ex_func = arg2;
- ctx->prefix = ex_func->ex_func;
- ctx->prefix_free = ex_func->ex_free_func;
- break;
-
- case BIO_C_GET_PREFIX:
- ex_func = arg2;
- ex_func->ex_func = ctx->prefix;
- ex_func->ex_free_func = ctx->prefix_free;
- break;
-
- case BIO_C_SET_SUFFIX:
- ex_func = arg2;
- ctx->suffix = ex_func->ex_func;
- ctx->suffix_free = ex_func->ex_free_func;
- break;
-
- case BIO_C_GET_SUFFIX:
- ex_func = arg2;
- ex_func->ex_func = ctx->suffix;
- ex_func->ex_free_func = ctx->suffix_free;
- break;
-
- case BIO_C_SET_EX_ARG:
- ctx->ex_arg = arg2;
- break;
-
- case BIO_C_GET_EX_ARG:
- *(void **)arg2 = ctx->ex_arg;
- break;
-
- case BIO_CTRL_FLUSH:
- if (!b->next_bio)
- return 0;
-
- /* Call post function if possible */
- if (ctx->state == ASN1_STATE_HEADER)
- {
- if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
- ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
- return 0;
- }
-
- if (ctx->state == ASN1_STATE_POST_COPY)
- {
- ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
- ASN1_STATE_DONE);
- if (ret <= 0)
- return ret;
- }
-
- if (ctx->state == ASN1_STATE_DONE)
- return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
- else
- {
- BIO_clear_retry_flags(b);
- return 0;
- }
- break;
-
-
- default:
- if (!b->next_bio)
- return 0;
- return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
-
- }
-
- return ret;
- }
-
-static int asn1_bio_set_ex(BIO *b, int cmd,
- asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
- {
- BIO_ASN1_EX_FUNCS extmp;
- extmp.ex_func = ex_func;
- extmp.ex_free_func = ex_free_func;
- return BIO_ctrl(b, cmd, 0, &extmp);
- }
-
-static int asn1_bio_get_ex(BIO *b, int cmd,
- asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
- {
- BIO_ASN1_EX_FUNCS extmp;
- int ret;
- ret = BIO_ctrl(b, cmd, 0, &extmp);
- if (ret > 0)
- {
- *ex_func = extmp.ex_func;
- *ex_free_func = extmp.ex_free_func;
- }
- return ret;
- }
-
-int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
- {
- return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
- }
-
-int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
- {
- return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
- }
-
-int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
- {
- return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
- }
-
-int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
- {
- return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
- }
diff --git a/crypto/openssl/crypto/asn1/bio_ndef.c b/crypto/openssl/crypto/asn1/bio_ndef.c
deleted file mode 100644
index 370389b..0000000
--- a/crypto/openssl/crypto/asn1/bio_ndef.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* bio_ndef.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project.
- */
-/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-
-#ifndef OPENSSL_SYSNAME_NETWARE
-#include <memory.h>
-#endif
-#include <stdio.h>
-
-/* Experimental NDEF ASN1 BIO support routines */
-
-/* The usage is quite simple, initialize an ASN1 structure,
- * get a BIO from it then any data written through the BIO
- * will end up translated to approptiate format on the fly.
- * The data is streamed out and does *not* need to be
- * all held in memory at once.
- *
- * When the BIO is flushed the output is finalized and any
- * signatures etc written out.
- *
- * The BIO is a 'proper' BIO and can handle non blocking I/O
- * correctly.
- *
- * The usage is simple. The implementation is *not*...
- */
-
-/* BIO support data stored in the ASN1 BIO ex_arg */
-
-typedef struct ndef_aux_st
- {
- /* ASN1 structure this BIO refers to */
- ASN1_VALUE *val;
- const ASN1_ITEM *it;
- /* Top of the BIO chain */
- BIO *ndef_bio;
- /* Output BIO */
- BIO *out;
- /* Boundary where content is inserted */
- unsigned char **boundary;
- /* DER buffer start */
- unsigned char *derbuf;
- } NDEF_SUPPORT;
-
-static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-
-BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
- {
- NDEF_SUPPORT *ndef_aux = NULL;
- BIO *asn_bio = NULL;
- const ASN1_AUX *aux = it->funcs;
- ASN1_STREAM_ARG sarg;
-
- if (!aux || !aux->asn1_cb)
- {
- ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
- return NULL;
- }
- ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
- asn_bio = BIO_new(BIO_f_asn1());
-
- /* ASN1 bio needs to be next to output BIO */
-
- out = BIO_push(asn_bio, out);
-
- if (!ndef_aux || !asn_bio || !out)
- goto err;
-
- BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
- BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
-
- /* Now let callback prepend any digest, cipher etc BIOs
- * ASN1 structure needs.
- */
-
- sarg.out = out;
- sarg.ndef_bio = NULL;
- sarg.boundary = NULL;
-
- if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
- goto err;
-
- ndef_aux->val = val;
- ndef_aux->it = it;
- ndef_aux->ndef_bio = sarg.ndef_bio;
- ndef_aux->boundary = sarg.boundary;
- ndef_aux->out = out;
-
- BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
-
- return sarg.ndef_bio;
-
- err:
- if (asn_bio)
- BIO_free(asn_bio);
- if (ndef_aux)
- OPENSSL_free(ndef_aux);
- return NULL;
- }
-
-static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT *ndef_aux;
- unsigned char *p;
- int derlen;
-
- if (!parg)
- return 0;
-
- ndef_aux = *(NDEF_SUPPORT **)parg;
-
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
- p = OPENSSL_malloc(derlen);
- ndef_aux->derbuf = p;
- *pbuf = p;
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
-
- if (!*ndef_aux->boundary)
- return 0;
-
- *plen = *ndef_aux->boundary - *pbuf;
-
- return 1;
- }
-
-static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT *ndef_aux;
-
- if (!parg)
- return 0;
-
- ndef_aux = *(NDEF_SUPPORT **)parg;
-
- if (ndef_aux->derbuf)
- OPENSSL_free(ndef_aux->derbuf);
-
- ndef_aux->derbuf = NULL;
- *pbuf = NULL;
- *plen = 0;
- return 1;
- }
-
-static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
- if (!ndef_prefix_free(b, pbuf, plen, parg))
- return 0;
- OPENSSL_free(*pndef_aux);
- *pndef_aux = NULL;
- return 1;
- }
-
-static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT *ndef_aux;
- unsigned char *p;
- int derlen;
- const ASN1_AUX *aux;
- ASN1_STREAM_ARG sarg;
-
- if (!parg)
- return 0;
-
- ndef_aux = *(NDEF_SUPPORT **)parg;
-
- aux = ndef_aux->it->funcs;
-
- /* Finalize structures */
- sarg.ndef_bio = ndef_aux->ndef_bio;
- sarg.out = ndef_aux->out;
- sarg.boundary = ndef_aux->boundary;
- if (aux->asn1_cb(ASN1_OP_STREAM_POST,
- &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
- return 0;
-
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
- p = OPENSSL_malloc(derlen);
- ndef_aux->derbuf = p;
- *pbuf = p;
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
-
- if (!*ndef_aux->boundary)
- return 0;
- *pbuf = *ndef_aux->boundary;
- *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
-
- return 1;
- }
diff --git a/crypto/openssl/crypto/asn1/t_x509.c b/crypto/openssl/crypto/asn1/t_x509.c
index 8f746f9..6f295b4 100644
--- a/crypto/openssl/crypto/asn1/t_x509.c
+++ b/crypto/openssl/crypto/asn1/t_x509.c
@@ -379,6 +379,8 @@ int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
int gmt=0;
int i;
int y=0,M=0,d=0,h=0,m=0,s=0;
+ char *f = NULL;
+ int f_len = 0;
i=tm->length;
v=(char *)tm->data;
@@ -396,10 +398,21 @@ int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
if (tm->length >= 14 &&
(v[12] >= '0') && (v[12] <= '9') &&
(v[13] >= '0') && (v[13] <= '9'))
+ {
s= (v[12]-'0')*10+(v[13]-'0');
+ /* Check for fractions of seconds. */
+ if (tm->length >= 15 && v[14] == '.')
+ {
+ int l = tm->length;
+ f = &v[14]; /* The decimal point. */
+ f_len = 1;
+ while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
+ ++f_len;
+ }
+ }
- if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
- mon[M-1],d,h,m,s,y,(gmt)?" GMT":"") <= 0)
+ if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
+ mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
return(0);
else
return(1);
diff --git a/crypto/openssl/crypto/asn1/x_nx509.c b/crypto/openssl/crypto/asn1/x_nx509.c
deleted file mode 100644
index fbd9a22..0000000
--- a/crypto/openssl/crypto/asn1/x_nx509.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* x_nx509.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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 product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stddef.h>
-#include <openssl/x509.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
-
-/* Old netscape certificate wrapper format */
-
-ASN1_SEQUENCE(NETSCAPE_X509) = {
- ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
- ASN1_OPT(NETSCAPE_X509, cert, X509)
-} ASN1_SEQUENCE_END(NETSCAPE_X509)
-
-IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
-
diff --git a/crypto/openssl/crypto/bio/bio.h b/crypto/openssl/crypto/bio/bio.h
index cecb6a7..ebb4278 100644
--- a/crypto/openssl/crypto/bio/bio.h
+++ b/crypto/openssl/crypto/bio/bio.h
@@ -156,8 +156,11 @@ extern "C" {
* previous write
* operation */
+#define BIO_CTRL_DGRAM_GET_PEER 46
#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */
+#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to
+ * adjust socket timeouts */
/* modifiers */
#define BIO_FP_READ 0x02
@@ -405,7 +408,7 @@ typedef struct bio_f_buffer_ctx_struct
#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
#define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
-#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3)
+#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0)
#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
@@ -414,7 +417,7 @@ typedef struct bio_f_buffer_ctx_struct
#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
-#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL)
+#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
#define BIO_BIND_NORMAL 0
@@ -541,6 +544,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
#define BIO_dgram_send_timedout(b) \
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+#define BIO_dgram_get_peer(b,peer) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
#define BIO_dgram_set_peer(b,peer) \
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
diff --git a/crypto/openssl/crypto/bio/bss_dgram.c b/crypto/openssl/crypto/bio/bss_dgram.c
index c3da6dc..14ca854 100644
--- a/crypto/openssl/crypto/bio/bss_dgram.c
+++ b/crypto/openssl/crypto/bio/bss_dgram.c
@@ -66,7 +66,13 @@
#include <openssl/bio.h>
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
+#include <sys/timeb.h>
+#endif
+
+#ifdef OPENSSL_SYS_LINUX
#define IP_MTU 14 /* linux is lame */
+#endif
#ifdef WATT32
#define sock_write SockWrite /* Watt-32 uses same names */
@@ -84,6 +90,8 @@ static int dgram_clear(BIO *bio);
static int BIO_dgram_should_retry(int s);
+static void get_current_time(struct timeval *t);
+
static BIO_METHOD methods_dgramp=
{
BIO_TYPE_DGRAM,
@@ -104,6 +112,8 @@ typedef struct bio_dgram_data_st
unsigned int connected;
unsigned int _errno;
unsigned int mtu;
+ struct timeval next_timeout;
+ struct timeval socket_timeout;
} bio_dgram_data;
BIO_METHOD *BIO_s_datagram(void)
@@ -165,7 +175,100 @@ static int dgram_clear(BIO *a)
}
return(1);
}
-
+
+static void dgram_adjust_rcv_timeout(BIO *b)
+ {
+#if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ int sz = sizeof(int);
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
+ {
+ struct timeval timenow, timeleft;
+
+ /* Read current socket timeout */
+#ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, &sz) < 0)
+ { perror("getsockopt"); }
+ else
+ {
+ data->socket_timeout.tv_sec = timeout / 1000;
+ data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
+ }
+#else
+ if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ &(data->socket_timeout), (void *)&sz) < 0)
+ { perror("getsockopt"); }
+#endif
+
+ /* Get current time */
+ get_current_time(&timenow);
+
+ /* Calculate time left until timer expires */
+ memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+ timeleft.tv_sec -= timenow.tv_sec;
+ timeleft.tv_usec -= timenow.tv_usec;
+ if (timeleft.tv_usec < 0)
+ {
+ timeleft.tv_sec--;
+ timeleft.tv_usec += 1000000;
+ }
+
+ if (timeleft.tv_sec < 0)
+ {
+ timeleft.tv_sec = 0;
+ timeleft.tv_usec = 1;
+ }
+
+ /* Adjust socket timeout if next handhake message timer
+ * will expire earlier.
+ */
+ if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) ||
+ (data->socket_timeout.tv_sec > timeleft.tv_sec) ||
+ (data->socket_timeout.tv_sec == timeleft.tv_sec &&
+ data->socket_timeout.tv_usec >= timeleft.tv_usec))
+ {
+#ifdef OPENSSL_SYS_WINDOWS
+ timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, sizeof(timeout)) < 0)
+ { perror("setsockopt"); }
+#else
+ if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
+ sizeof(struct timeval)) < 0)
+ { perror("setsockopt"); }
+#endif
+ }
+ }
+#endif
+ }
+
+static void dgram_reset_rcv_timeout(BIO *b)
+ {
+#if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
+ {
+#ifdef OPENSSL_SYS_WINDOWS
+ int timeout = data->socket_timeout.tv_sec * 1000 +
+ data->socket_timeout.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, sizeof(timeout)) < 0)
+ { perror("setsockopt"); }
+#else
+ if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
+ sizeof(struct timeval)) < 0)
+ { perror("setsockopt"); }
+#endif
+ }
+#endif
+ }
+
static int dgram_read(BIO *b, char *out, int outl)
{
int ret=0;
@@ -183,13 +286,15 @@ static int dgram_read(BIO *b, char *out, int outl)
* but this is not universal. Cast to (void *) to avoid
* compiler warnings.
*/
+ dgram_adjust_rcv_timeout(b);
ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen);
+ dgram_reset_rcv_timeout(b);
- if ( ! data->connected && ret > 0)
- BIO_ctrl(b, BIO_CTRL_DGRAM_CONNECT, 0, &peer);
+ if ( ! data->connected && ret >= 0)
+ BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
BIO_clear_retry_flags(b);
- if (ret <= 0)
+ if (ret < 0)
{
if (BIO_dgram_should_retry(ret))
{
@@ -219,7 +324,7 @@ static int dgram_write(BIO *b, const char *in, int inl)
BIO_clear_retry_flags(b);
if (ret <= 0)
{
- if (BIO_sock_should_retry(ret))
+ if (BIO_dgram_should_retry(ret))
{
BIO_set_retry_write(b);
data->_errno = get_last_socket_error();
@@ -240,8 +345,14 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
int *ip;
struct sockaddr *to = NULL;
bio_dgram_data *data = NULL;
+#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
long sockopt_val = 0;
unsigned int sockopt_len = 0;
+#endif
+#ifdef OPENSSL_SYS_LINUX
+ socklen_t addr_len;
+ struct sockaddr_storage addr;
+#endif
data = (bio_dgram_data *)b->ptr;
@@ -300,24 +411,87 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif
break;
/* (Linux)kernel sets DF bit on outgoing IP packets */
-#ifdef IP_MTU_DISCOVER
case BIO_CTRL_DGRAM_MTU_DISCOVER:
- sockopt_val = IP_PMTUDISC_DO;
- if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0)
- perror("setsockopt");
+#ifdef OPENSSL_SYS_LINUX
+ addr_len = (socklen_t)sizeof(struct sockaddr_storage);
+ memset((void *)&addr, 0, sizeof(struct sockaddr_storage));
+ if (getsockname(b->num, (void *)&addr, &addr_len) < 0)
+ {
+ ret = 0;
+ break;
+ }
+ sockopt_len = sizeof(sockopt_val);
+ switch (addr.ss_family)
+ {
+ case AF_INET:
+ sockopt_val = IP_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+ case AF_INET6:
+ sockopt_val = IPV6_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ ret = -1;
+#else
break;
#endif
case BIO_CTRL_DGRAM_QUERY_MTU:
- sockopt_len = sizeof(sockopt_val);
- if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
- &sockopt_len)) < 0 || sockopt_val < 0)
- { ret = 0; }
- else
+#ifdef OPENSSL_SYS_LINUX
+ addr_len = (socklen_t)sizeof(struct sockaddr_storage);
+ memset((void *)&addr, 0, sizeof(struct sockaddr_storage));
+ if (getsockname(b->num, (void *)&addr, &addr_len) < 0)
{
- data->mtu = sockopt_val;
- ret = data->mtu;
+ ret = 0;
+ break;
}
+ sockopt_len = sizeof(sockopt_val);
+ switch (addr.ss_family)
+ {
+ case AF_INET:
+ if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+ &sockopt_len)) < 0 || sockopt_val < 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ /* we assume that the transport protocol is UDP and no
+ * IP options are used.
+ */
+ data->mtu = sockopt_val - 8 - 20;
+ ret = data->mtu;
+ }
+ break;
+ case AF_INET6:
+ if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
+ &sockopt_len)) < 0 || sockopt_val < 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ /* we assume that the transport protocol is UDP and no
+ * IPV6 options are used.
+ */
+ data->mtu = sockopt_val - 8 - 40;
+ ret = data->mtu;
+ }
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+#else
+ ret = 0;
+#endif
break;
case BIO_CTRL_DGRAM_GET_MTU:
return data->mtu;
@@ -340,11 +514,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
memset(&(data->peer), 0x00, sizeof(struct sockaddr));
}
break;
+ case BIO_CTRL_DGRAM_GET_PEER:
+ to = (struct sockaddr *) ptr;
+
+ memcpy(to, &(data->peer), sizeof(struct sockaddr));
+ ret = sizeof(struct sockaddr);
+ break;
case BIO_CTRL_DGRAM_SET_PEER:
to = (struct sockaddr *) ptr;
memcpy(&(data->peer), to, sizeof(struct sockaddr));
break;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+ break;
#if defined(SO_RCVTIMEO)
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
#ifdef OPENSSL_SYS_WINDOWS
@@ -507,10 +690,6 @@ int BIO_dgram_non_fatal_error(int err)
# endif
#endif
-#if defined(ENOTCONN)
- case ENOTCONN:
-#endif
-
#ifdef EINTR
case EINTR:
#endif
@@ -533,11 +712,6 @@ int BIO_dgram_non_fatal_error(int err)
case EALREADY:
#endif
-/* DF bit set, and packet larger than MTU */
-#ifdef EMSGSIZE
- case EMSGSIZE:
-#endif
-
return(1);
/* break; */
default:
@@ -546,3 +720,20 @@ int BIO_dgram_non_fatal_error(int err)
return(0);
}
#endif
+
+static void get_current_time(struct timeval *t)
+ {
+#ifdef OPENSSL_SYS_WIN32
+ struct _timeb tb;
+ _ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#elif defined(OPENSSL_SYS_VMS)
+ struct timeb tb;
+ ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#else
+ gettimeofday(t, NULL);
+#endif
+ }
diff --git a/crypto/openssl/crypto/bio/bss_file.c b/crypto/openssl/crypto/bio/bss_file.c
index 9ad46fa..47fa266 100644
--- a/crypto/openssl/crypto/bio/bss_file.c
+++ b/crypto/openssl/crypto/bio/bss_file.c
@@ -272,9 +272,9 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
BIO_clear_flags(b,BIO_FLAGS_UPLINK);
#endif
#endif
-#ifdef UP_fsetmode
+#ifdef UP_fsetmod
if (b->flags&BIO_FLAGS_UPLINK)
- UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b');
+ UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
else
#endif
{
@@ -404,11 +404,18 @@ static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
buf[0]='\0';
if (bp->flags&BIO_FLAGS_UPLINK)
- UP_fgets(buf,size,bp->ptr);
+ {
+ if (!UP_fgets(buf,size,bp->ptr))
+ goto err;
+ }
else
- fgets(buf,size,(FILE *)bp->ptr);
+ {
+ if (!fgets(buf,size,(FILE *)bp->ptr))
+ goto err;
+ }
if (buf[0] != '\0')
ret=strlen(buf);
+ err:
return(ret);
}
diff --git a/crypto/openssl/crypto/bn/asm/alpha-mont.pl b/crypto/openssl/crypto/bn/asm/alpha-mont.pl
deleted file mode 100755
index 7a2cc31..0000000
--- a/crypto/openssl/crypto/bn/asm/alpha-mont.pl
+++ /dev/null
@@ -1,317 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-#
-# On 21264 RSA sign performance improves by 70/35/20/15 percent for
-# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
-# instructed to '-tune host' code with in-line assembler. Other
-# benchmarks improve by 15-20%. To anchor it to something else, the
-# code provides approximately the same performance per GHz as AMD64.
-# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
-# difference.
-
-# int bn_mul_mont(
-$rp="a0"; # BN_ULONG *rp,
-$ap="a1"; # const BN_ULONG *ap,
-$bp="a2"; # const BN_ULONG *bp,
-$np="a3"; # const BN_ULONG *np,
-$n0="a4"; # const BN_ULONG *n0,
-$num="a5"; # int num);
-
-$lo0="t0";
-$hi0="t1";
-$lo1="t2";
-$hi1="t3";
-$aj="t4";
-$bi="t5";
-$nj="t6";
-$tp="t7";
-$alo="t8";
-$ahi="t9";
-$nlo="t10";
-$nhi="t11";
-$tj="t12";
-$i="s3";
-$j="s4";
-$m1="s5";
-
-$code=<<___;
-#include <asm.h>
-#include <regdef.h>
-
-.text
-
-.set noat
-.set noreorder
-
-.globl bn_mul_mont
-.align 5
-.ent bn_mul_mont
-bn_mul_mont:
- lda sp,-40(sp)
- stq ra,0(sp)
- stq s3,8(sp)
- stq s4,16(sp)
- stq s5,24(sp)
- stq fp,32(sp)
- mov sp,fp
- .mask 0x0400f000,-40
- .frame fp,40,ra
- .prologue 0
-
- .align 4
- .set reorder
- sextl $num,$num
- mov 0,v0
- cmplt $num,4,AT
- bne AT,.Lexit
-
- ldq $hi0,0($ap) # ap[0]
- s8addq $num,16,AT
- ldq $aj,8($ap)
- subq sp,AT,sp
- ldq $bi,0($bp) # bp[0]
- mov -4096,AT
- ldq $n0,0($n0)
- and sp,AT,sp
-
- mulq $hi0,$bi,$lo0
- ldq $hi1,0($np) # np[0]
- umulh $hi0,$bi,$hi0
- ldq $nj,8($np)
-
- mulq $lo0,$n0,$m1
-
- mulq $hi1,$m1,$lo1
- umulh $hi1,$m1,$hi1
-
- addq $lo1,$lo0,$lo1
- cmpult $lo1,$lo0,AT
- addq $hi1,AT,$hi1
-
- mulq $aj,$bi,$alo
- mov 2,$j
- umulh $aj,$bi,$ahi
- mov sp,$tp
-
- mulq $nj,$m1,$nlo
- s8addq $j,$ap,$aj
- umulh $nj,$m1,$nhi
- s8addq $j,$np,$nj
-.align 4
-.L1st:
- .set noreorder
- ldq $aj,($aj)
- addl $j,1,$j
- ldq $nj,($nj)
- lda $tp,8($tp)
-
- addq $alo,$hi0,$lo0
- mulq $aj,$bi,$alo
- cmpult $lo0,$hi0,AT
- addq $nlo,$hi1,$lo1
-
- mulq $nj,$m1,$nlo
- addq $ahi,AT,$hi0
- cmpult $lo1,$hi1,v0
- cmplt $j,$num,$tj
-
- umulh $aj,$bi,$ahi
- addq $nhi,v0,$hi1
- addq $lo1,$lo0,$lo1
- s8addq $j,$ap,$aj
-
- umulh $nj,$m1,$nhi
- cmpult $lo1,$lo0,v0
- addq $hi1,v0,$hi1
- s8addq $j,$np,$nj
-
- stq $lo1,-8($tp)
- nop
- unop
- bne $tj,.L1st
- .set reorder
-
- addq $alo,$hi0,$lo0
- addq $nlo,$hi1,$lo1
- cmpult $lo0,$hi0,AT
- cmpult $lo1,$hi1,v0
- addq $ahi,AT,$hi0
- addq $nhi,v0,$hi1
-
- addq $lo1,$lo0,$lo1
- cmpult $lo1,$lo0,v0
- addq $hi1,v0,$hi1
-
- stq $lo1,0($tp)
-
- addq $hi1,$hi0,$hi1
- cmpult $hi1,$hi0,AT
- stq $hi1,8($tp)
- stq AT,16($tp)
-
- mov 1,$i
-.align 4
-.Louter:
- s8addq $i,$bp,$bi
- ldq $hi0,($ap)
- ldq $aj,8($ap)
- ldq $bi,($bi)
- ldq $hi1,($np)
- ldq $nj,8($np)
- ldq $tj,(sp)
-
- mulq $hi0,$bi,$lo0
- umulh $hi0,$bi,$hi0
-
- addq $lo0,$tj,$lo0
- cmpult $lo0,$tj,AT
- addq $hi0,AT,$hi0
-
- mulq $lo0,$n0,$m1
-
- mulq $hi1,$m1,$lo1
- umulh $hi1,$m1,$hi1
-
- addq $lo1,$lo0,$lo1
- cmpult $lo1,$lo0,AT
- mov 2,$j
- addq $hi1,AT,$hi1
-
- mulq $aj,$bi,$alo
- mov sp,$tp
- umulh $aj,$bi,$ahi
-
- mulq $nj,$m1,$nlo
- s8addq $j,$ap,$aj
- umulh $nj,$m1,$nhi
-.align 4
-.Linner:
- .set noreorder
- ldq $tj,8($tp) #L0
- nop #U1
- ldq $aj,($aj) #L1
- s8addq $j,$np,$nj #U0
-
- ldq $nj,($nj) #L0
- nop #U1
- addq $alo,$hi0,$lo0 #L1
- lda $tp,8($tp)
-
- mulq $aj,$bi,$alo #U1
- cmpult $lo0,$hi0,AT #L0
- addq $nlo,$hi1,$lo1 #L1
- addl $j,1,$j
-
- mulq $nj,$m1,$nlo #U1
- addq $ahi,AT,$hi0 #L0
- addq $lo0,$tj,$lo0 #L1
- cmpult $lo1,$hi1,v0 #U0
-
- umulh $aj,$bi,$ahi #U1
- cmpult $lo0,$tj,AT #L0
- addq $lo1,$lo0,$lo1 #L1
- addq $nhi,v0,$hi1 #U0
-
- umulh $nj,$m1,$nhi #U1
- s8addq $j,$ap,$aj #L0
- cmpult $lo1,$lo0,v0 #L1
- cmplt $j,$num,$tj #U0 # borrow $tj
-
- addq $hi0,AT,$hi0 #L0
- addq $hi1,v0,$hi1 #U1
- stq $lo1,-8($tp) #L1
- bne $tj,.Linner #U0
- .set reorder
-
- ldq $tj,8($tp)
- addq $alo,$hi0,$lo0
- addq $nlo,$hi1,$lo1
- cmpult $lo0,$hi0,AT
- cmpult $lo1,$hi1,v0
- addq $ahi,AT,$hi0
- addq $nhi,v0,$hi1
-
- addq $lo0,$tj,$lo0
- cmpult $lo0,$tj,AT
- addq $hi0,AT,$hi0
-
- ldq $tj,16($tp)
- addq $lo1,$lo0,$j
- cmpult $j,$lo0,v0
- addq $hi1,v0,$hi1
-
- addq $hi1,$hi0,$lo1
- stq $j,($tp)
- cmpult $lo1,$hi0,$hi1
- addq $lo1,$tj,$lo1
- cmpult $lo1,$tj,AT
- addl $i,1,$i
- addq $hi1,AT,$hi1
- stq $lo1,8($tp)
- cmplt $i,$num,$tj # borrow $tj
- stq $hi1,16($tp)
- bne $tj,.Louter
-
- s8addq $num,sp,$tj # &tp[num]
- mov $rp,$bp # put rp aside
- mov sp,$tp
- mov sp,$ap
- mov 0,$hi0 # clear borrow bit
-
-.align 4
-.Lsub: ldq $lo0,($tp)
- ldq $lo1,($np)
- lda $tp,8($tp)
- lda $np,8($np)
- subq $lo0,$lo1,$lo1 # tp[i]-np[i]
- cmpult $lo0,$lo1,AT
- subq $lo1,$hi0,$lo0
- cmpult $lo1,$lo0,$hi0
- or $hi0,AT,$hi0
- stq $lo0,($rp)
- cmpult $tp,$tj,v0
- lda $rp,8($rp)
- bne v0,.Lsub
-
- subq $hi1,$hi0,$hi0 # handle upmost overflow bit
- mov sp,$tp
- mov $bp,$rp # restore rp
-
- and sp,$hi0,$ap
- bic $bp,$hi0,$bp
- bis $bp,$ap,$ap # ap=borrow?tp:rp
-
-.align 4
-.Lcopy: ldq $aj,($ap) # copy or in-place refresh
- lda $tp,8($tp)
- lda $rp,8($rp)
- lda $ap,8($ap)
- stq zero,-8($tp) # zap tp
- cmpult $tp,$tj,AT
- stq $aj,-8($rp)
- bne AT,.Lcopy
- mov 1,v0
-
-.Lexit:
- .set noreorder
- mov fp,sp
- /*ldq ra,0(sp)*/
- ldq s3,8(sp)
- ldq s4,16(sp)
- ldq s5,24(sp)
- ldq fp,32(sp)
- lda sp,40(sp)
- ret (ra)
-.end bn_mul_mont
-.rdata
-.asciiz "Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
-___
-
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/armv4-mont.pl b/crypto/openssl/crypto/bn/asm/armv4-mont.pl
deleted file mode 100755
index 05d5dc1..0000000
--- a/crypto/openssl/crypto/bn/asm/armv4-mont.pl
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# January 2007.
-
-# Montgomery multiplication for ARMv4.
-#
-# Performance improvement naturally varies among CPU implementations
-# and compilers. The code was observed to provide +65-35% improvement
-# [depending on key length, less for longer keys] on ARM920T, and
-# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
-# base and compiler generated code with in-lined umull and even umlal
-# instructions. The latter means that this code didn't really have an
-# "advantage" of utilizing some "secret" instruction.
-#
-# The code is interoperable with Thumb ISA and is rather compact, less
-# than 1/2KB. Windows CE port would be trivial, as it's exclusively
-# about decorations, ABI and instruction syntax are identical.
-
-$num="r0"; # starts as num argument, but holds &tp[num-1]
-$ap="r1";
-$bp="r2"; $bi="r2"; $rp="r2";
-$np="r3";
-$tp="r4";
-$aj="r5";
-$nj="r6";
-$tj="r7";
-$n0="r8";
-########### # r9 is reserved by ELF as platform specific, e.g. TLS pointer
-$alo="r10"; # sl, gcc uses it to keep @GOT
-$ahi="r11"; # fp
-$nlo="r12"; # ip
-########### # r13 is stack pointer
-$nhi="r14"; # lr
-########### # r15 is program counter
-
-#### argument block layout relative to &tp[num-1], a.k.a. $num
-$_rp="$num,#12*4";
-# ap permanently resides in r1
-$_bp="$num,#13*4";
-# np permanently resides in r3
-$_n0="$num,#14*4";
-$_num="$num,#15*4"; $_bpend=$_num;
-
-$code=<<___;
-.text
-
-.global bn_mul_mont
-.type bn_mul_mont,%function
-
-.align 2
-bn_mul_mont:
- stmdb sp!,{r0,r2} @ sp points at argument block
- ldr $num,[sp,#3*4] @ load num
- cmp $num,#2
- movlt r0,#0
- addlt sp,sp,#2*4
- blt .Labrt
-
- stmdb sp!,{r4-r12,lr} @ save 10 registers
-
- mov $num,$num,lsl#2 @ rescale $num for byte count
- sub sp,sp,$num @ alloca(4*num)
- sub sp,sp,#4 @ +extra dword
- sub $num,$num,#4 @ "num=num-1"
- add $tp,$bp,$num @ &bp[num-1]
-
- add $num,sp,$num @ $num to point at &tp[num-1]
- ldr $n0,[$_n0] @ &n0
- ldr $bi,[$bp] @ bp[0]
- ldr $aj,[$ap],#4 @ ap[0],ap++
- ldr $nj,[$np],#4 @ np[0],np++
- ldr $n0,[$n0] @ *n0
- str $tp,[$_bpend] @ save &bp[num]
-
- umull $alo,$ahi,$aj,$bi @ ap[0]*bp[0]
- str $n0,[$_n0] @ save n0 value
- mul $n0,$alo,$n0 @ "tp[0]"*n0
- mov $nlo,#0
- umlal $alo,$nlo,$nj,$n0 @ np[0]*n0+"t[0]"
- mov $tp,sp
-
-.L1st:
- ldr $aj,[$ap],#4 @ ap[j],ap++
- mov $alo,$ahi
- mov $ahi,#0
- umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[0]
- ldr $nj,[$np],#4 @ np[j],np++
- mov $nhi,#0
- umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0
- adds $nlo,$nlo,$alo
- str $nlo,[$tp],#4 @ tp[j-1]=,tp++
- adc $nlo,$nhi,#0
- cmp $tp,$num
- bne .L1st
-
- adds $nlo,$nlo,$ahi
- mov $nhi,#0
- adc $nhi,$nhi,#0
- ldr $tp,[$_bp] @ restore bp
- str $nlo,[$num] @ tp[num-1]=
- ldr $n0,[$_n0] @ restore n0
- str $nhi,[$num,#4] @ tp[num]=
-
-.Louter:
- sub $tj,$num,sp @ "original" $num-1 value
- sub $ap,$ap,$tj @ "rewind" ap to &ap[1]
- sub $np,$np,$tj @ "rewind" np to &np[1]
- ldr $bi,[$tp,#4]! @ *(++bp)
- ldr $aj,[$ap,#-4] @ ap[0]
- ldr $nj,[$np,#-4] @ np[0]
- ldr $alo,[sp] @ tp[0]
- ldr $tj,[sp,#4] @ tp[1]
-
- mov $ahi,#0
- umlal $alo,$ahi,$aj,$bi @ ap[0]*bp[i]+tp[0]
- str $tp,[$_bp] @ save bp
- mul $n0,$alo,$n0
- mov $nlo,#0
- umlal $alo,$nlo,$nj,$n0 @ np[0]*n0+"tp[0]"
- mov $tp,sp
-
-.Linner:
- ldr $aj,[$ap],#4 @ ap[j],ap++
- adds $alo,$ahi,$tj @ +=tp[j]
- mov $ahi,#0
- umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[i]
- ldr $nj,[$np],#4 @ np[j],np++
- mov $nhi,#0
- umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0
- ldr $tj,[$tp,#8] @ tp[j+1]
- adc $ahi,$ahi,#0
- adds $nlo,$nlo,$alo
- str $nlo,[$tp],#4 @ tp[j-1]=,tp++
- adc $nlo,$nhi,#0
- cmp $tp,$num
- bne .Linner
-
- adds $nlo,$nlo,$ahi
- mov $nhi,#0
- adc $nhi,$nhi,#0
- adds $nlo,$nlo,$tj
- adc $nhi,$nhi,#0
- ldr $tp,[$_bp] @ restore bp
- ldr $tj,[$_bpend] @ restore &bp[num]
- str $nlo,[$num] @ tp[num-1]=
- ldr $n0,[$_n0] @ restore n0
- str $nhi,[$num,#4] @ tp[num]=
-
- cmp $tp,$tj
- bne .Louter
-
- ldr $rp,[$_rp] @ pull rp
- add $num,$num,#4 @ $num to point at &tp[num]
- sub $aj,$num,sp @ "original" num value
- mov $tp,sp @ "rewind" $tp
- mov $ap,$tp @ "borrow" $ap
- sub $np,$np,$aj @ "rewind" $np to &np[0]
-
- subs $tj,$tj,$tj @ "clear" carry flag
-.Lsub: ldr $tj,[$tp],#4
- ldr $nj,[$np],#4
- sbcs $tj,$tj,$nj @ tp[j]-np[j]
- str $tj,[$rp],#4 @ rp[j]=
- teq $tp,$num @ preserve carry
- bne .Lsub
- sbcs $nhi,$nhi,#0 @ upmost carry
- mov $tp,sp @ "rewind" $tp
- sub $rp,$rp,$aj @ "rewind" $rp
-
- and $ap,$tp,$nhi
- bic $np,$rp,$nhi
- orr $ap,$ap,$np @ ap=borrow?tp:rp
-
-.Lcopy: ldr $tj,[$ap],#4 @ copy or in-place refresh
- str sp,[$tp],#4 @ zap tp
- str $tj,[$rp],#4
- cmp $tp,$num
- bne .Lcopy
-
- add sp,$num,#4 @ skip over tp[num+1]
- ldmia sp!,{r4-r12,lr} @ restore registers
- add sp,sp,#2*4 @ skip over {r0,r2}
- mov r0,#1
-.Labrt: tst lr,#1
- moveq pc,lr @ be binary compatible with V4, yet
- bx lr @ interoperable with Thumb ISA:-)
-.size bn_mul_mont,.-bn_mul_mont
-.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
-___
-
-$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/mips3-mont.pl b/crypto/openssl/crypto/bn/asm/mips3-mont.pl
deleted file mode 100755
index 8f9156e..0000000
--- a/crypto/openssl/crypto/bn/asm/mips3-mont.pl
+++ /dev/null
@@ -1,327 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# This module doesn't present direct interest for OpenSSL, because it
-# doesn't provide better performance for longer keys. While 512-bit
-# RSA private key operations are 40% faster, 1024-bit ones are hardly
-# faster at all, while longer key operations are slower by up to 20%.
-# It might be of interest to embedded system developers though, as
-# it's smaller than 1KB, yet offers ~3x improvement over compiler
-# generated code.
-#
-# The module targets N32 and N64 MIPS ABIs and currently is a bit
-# IRIX-centric, i.e. is likely to require adaptation for other OSes.
-
-# int bn_mul_mont(
-$rp="a0"; # BN_ULONG *rp,
-$ap="a1"; # const BN_ULONG *ap,
-$bp="a2"; # const BN_ULONG *bp,
-$np="a3"; # const BN_ULONG *np,
-$n0="a4"; # const BN_ULONG *n0,
-$num="a5"; # int num);
-
-$lo0="a6";
-$hi0="a7";
-$lo1="v0";
-$hi1="v1";
-$aj="t0";
-$bi="t1";
-$nj="t2";
-$tp="t3";
-$alo="s0";
-$ahi="s1";
-$nlo="s2";
-$nhi="s3";
-$tj="s4";
-$i="s5";
-$j="s6";
-$fp="t8";
-$m1="t9";
-
-$FRAME=8*(2+8);
-
-$code=<<___;
-#include <asm.h>
-#include <regdef.h>
-
-.text
-
-.set noat
-.set reorder
-
-.align 5
-.globl bn_mul_mont
-.ent bn_mul_mont
-bn_mul_mont:
- .set noreorder
- PTR_SUB sp,64
- move $fp,sp
- .frame $fp,64,ra
- slt AT,$num,4
- li v0,0
- beqzl AT,.Lproceed
- nop
- jr ra
- PTR_ADD sp,$fp,64
- .set reorder
-.align 5
-.Lproceed:
- ld $n0,0($n0)
- ld $bi,0($bp) # bp[0]
- ld $aj,0($ap) # ap[0]
- ld $nj,0($np) # np[0]
- PTR_SUB sp,16 # place for two extra words
- sll $num,3
- li AT,-4096
- PTR_SUB sp,$num
- and sp,AT
-
- sd s0,0($fp)
- sd s1,8($fp)
- sd s2,16($fp)
- sd s3,24($fp)
- sd s4,32($fp)
- sd s5,40($fp)
- sd s6,48($fp)
- sd s7,56($fp)
-
- dmultu $aj,$bi
- ld $alo,8($ap)
- ld $nlo,8($np)
- mflo $lo0
- mfhi $hi0
- dmultu $lo0,$n0
- mflo $m1
-
- dmultu $alo,$bi
- mflo $alo
- mfhi $ahi
-
- dmultu $nj,$m1
- mflo $lo1
- mfhi $hi1
- dmultu $nlo,$m1
- daddu $lo1,$lo0
- sltu AT,$lo1,$lo0
- daddu $hi1,AT
- mflo $nlo
- mfhi $nhi
-
- move $tp,sp
- li $j,16
-.align 4
-.L1st:
- .set noreorder
- PTR_ADD $aj,$ap,$j
- ld $aj,($aj)
- PTR_ADD $nj,$np,$j
- ld $nj,($nj)
-
- dmultu $aj,$bi
- daddu $lo0,$alo,$hi0
- daddu $lo1,$nlo,$hi1
- sltu AT,$lo0,$hi0
- sltu s7,$lo1,$hi1
- daddu $hi0,$ahi,AT
- daddu $hi1,$nhi,s7
- mflo $alo
- mfhi $ahi
-
- daddu $lo1,$lo0
- sltu AT,$lo1,$lo0
- dmultu $nj,$m1
- daddu $hi1,AT
- addu $j,8
- sd $lo1,($tp)
- sltu s7,$j,$num
- mflo $nlo
- mfhi $nhi
-
- bnez s7,.L1st
- PTR_ADD $tp,8
- .set reorder
-
- daddu $lo0,$alo,$hi0
- sltu AT,$lo0,$hi0
- daddu $hi0,$ahi,AT
-
- daddu $lo1,$nlo,$hi1
- sltu s7,$lo1,$hi1
- daddu $hi1,$nhi,s7
- daddu $lo1,$lo0
- sltu AT,$lo1,$lo0
- daddu $hi1,AT
-
- sd $lo1,($tp)
-
- daddu $hi1,$hi0
- sltu AT,$hi1,$hi0
- sd $hi1,8($tp)
- sd AT,16($tp)
-
- li $i,8
-.align 4
-.Louter:
- PTR_ADD $bi,$bp,$i
- ld $bi,($bi)
- ld $aj,($ap)
- ld $alo,8($ap)
- ld $tj,(sp)
-
- dmultu $aj,$bi
- ld $nj,($np)
- ld $nlo,8($np)
- mflo $lo0
- mfhi $hi0
- daddu $lo0,$tj
- dmultu $lo0,$n0
- sltu AT,$lo0,$tj
- daddu $hi0,AT
- mflo $m1
-
- dmultu $alo,$bi
- mflo $alo
- mfhi $ahi
-
- dmultu $nj,$m1
- mflo $lo1
- mfhi $hi1
-
- dmultu $nlo,$m1
- daddu $lo1,$lo0
- sltu AT,$lo1,$lo0
- daddu $hi1,AT
- mflo $nlo
- mfhi $nhi
-
- move $tp,sp
- li $j,16
- ld $tj,8($tp)
-.align 4
-.Linner:
- .set noreorder
- PTR_ADD $aj,$ap,$j
- ld $aj,($aj)
- PTR_ADD $nj,$np,$j
- ld $nj,($nj)
-
- dmultu $aj,$bi
- daddu $lo0,$alo,$hi0
- daddu $lo1,$nlo,$hi1
- sltu AT,$lo0,$hi0
- sltu s7,$lo1,$hi1
- daddu $hi0,$ahi,AT
- daddu $hi1,$nhi,s7
- mflo $alo
- mfhi $ahi
-
- daddu $lo0,$tj
- addu $j,8
- dmultu $nj,$m1
- sltu AT,$lo0,$tj
- daddu $lo1,$lo0
- daddu $hi0,AT
- sltu s7,$lo1,$lo0
- ld $tj,16($tp)
- daddu $hi1,s7
- sltu AT,$j,$num
- mflo $nlo
- mfhi $nhi
- sd $lo1,($tp)
- bnez AT,.Linner
- PTR_ADD $tp,8
- .set reorder
-
- daddu $lo0,$alo,$hi0
- sltu AT,$lo0,$hi0
- daddu $hi0,$ahi,AT
- daddu $lo0,$tj
- sltu s7,$lo0,$tj
- daddu $hi0,s7
-
- ld $tj,16($tp)
- daddu $lo1,$nlo,$hi1
- sltu AT,$lo1,$hi1
- daddu $hi1,$nhi,AT
- daddu $lo1,$lo0
- sltu s7,$lo1,$lo0
- daddu $hi1,s7
- sd $lo1,($tp)
-
- daddu $lo1,$hi1,$hi0
- sltu $hi1,$lo1,$hi0
- daddu $lo1,$tj
- sltu AT,$lo1,$tj
- daddu $hi1,AT
- sd $lo1,8($tp)
- sd $hi1,16($tp)
-
- addu $i,8
- sltu s7,$i,$num
- bnez s7,.Louter
-
- .set noreorder
- PTR_ADD $tj,sp,$num # &tp[num]
- move $tp,sp
- move $ap,sp
- li $hi0,0 # clear borrow bit
-
-.align 4
-.Lsub: ld $lo0,($tp)
- ld $lo1,($np)
- PTR_ADD $tp,8
- PTR_ADD $np,8
- dsubu $lo1,$lo0,$lo1 # tp[i]-np[i]
- sgtu AT,$lo1,$lo0
- dsubu $lo0,$lo1,$hi0
- sgtu $hi0,$lo0,$lo1
- sd $lo0,($rp)
- or $hi0,AT
- sltu AT,$tp,$tj
- bnez AT,.Lsub
- PTR_ADD $rp,8
-
- dsubu $hi0,$hi1,$hi0 # handle upmost overflow bit
- move $tp,sp
- PTR_SUB $rp,$num # restore rp
- not $hi1,$hi0
-
- and $ap,$hi0,sp
- and $bp,$hi1,$rp
- or $ap,$ap,$bp # ap=borrow?tp:rp
-
-.align 4
-.Lcopy: ld $aj,($ap)
- PTR_ADD $ap,8
- PTR_ADD $tp,8
- sd zero,-8($tp)
- sltu AT,$tp,$tj
- sd $aj,($rp)
- bnez AT,.Lcopy
- PTR_ADD $rp,8
-
- ld s0,0($fp)
- ld s1,8($fp)
- ld s2,16($fp)
- ld s3,24($fp)
- ld s4,32($fp)
- ld s5,40($fp)
- ld s6,48($fp)
- ld s7,56($fp)
- li v0,1
- jr ra
- PTR_ADD sp,$fp,64
- .set reorder
-END(bn_mul_mont)
-.rdata
-.asciiz "Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by <appro\@openssl.org>"
-___
-
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/ppc-mont.pl b/crypto/openssl/crypto/bn/asm/ppc-mont.pl
deleted file mode 100755
index 7849eae..0000000
--- a/crypto/openssl/crypto/bn/asm/ppc-mont.pl
+++ /dev/null
@@ -1,323 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# April 2006
-
-# "Teaser" Montgomery multiplication module for PowerPC. It's possible
-# to gain a bit more by modulo-scheduling outer loop, then dedicated
-# squaring procedure should give further 20% and code can be adapted
-# for 32-bit application running on 64-bit CPU. As for the latter.
-# It won't be able to achieve "native" 64-bit performance, because in
-# 32-bit application context every addc instruction will have to be
-# expanded as addc, twice right shift by 32 and finally adde, etc.
-# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
-# for 64-bit application running on PPC970/G5 is:
-#
-# 512-bit +65%
-# 1024-bit +35%
-# 2048-bit +18%
-# 4096-bit +4%
-
-$flavour = shift;
-
-if ($flavour =~ /32/) {
- $BITS= 32;
- $BNSZ= $BITS/8;
- $SIZE_T=4;
- $RZONE= 224;
- $FRAME= $SIZE_T*16;
-
- $LD= "lwz"; # load
- $LDU= "lwzu"; # load and update
- $LDX= "lwzx"; # load indexed
- $ST= "stw"; # store
- $STU= "stwu"; # store and update
- $STX= "stwx"; # store indexed
- $STUX= "stwux"; # store indexed and update
- $UMULL= "mullw"; # unsigned multiply low
- $UMULH= "mulhwu"; # unsigned multiply high
- $UCMP= "cmplw"; # unsigned compare
- $SHRI= "srwi"; # unsigned shift right by immediate
- $PUSH= $ST;
- $POP= $LD;
-} elsif ($flavour =~ /64/) {
- $BITS= 64;
- $BNSZ= $BITS/8;
- $SIZE_T=8;
- $RZONE= 288;
- $FRAME= $SIZE_T*16;
-
- # same as above, but 64-bit mnemonics...
- $LD= "ld"; # load
- $LDU= "ldu"; # load and update
- $LDX= "ldx"; # load indexed
- $ST= "std"; # store
- $STU= "stdu"; # store and update
- $STX= "stdx"; # store indexed
- $STUX= "stdux"; # store indexed and update
- $UMULL= "mulld"; # unsigned multiply low
- $UMULH= "mulhdu"; # unsigned multiply high
- $UCMP= "cmpld"; # unsigned compare
- $SHRI= "srdi"; # unsigned shift right by immediate
- $PUSH= $ST;
- $POP= $LD;
-} else { die "nonsense $flavour"; }
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-die "can't locate ppc-xlate.pl";
-
-open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-
-$sp="r1";
-$toc="r2";
-$rp="r3"; $ovf="r3";
-$ap="r4";
-$bp="r5";
-$np="r6";
-$n0="r7";
-$num="r8";
-$rp="r9"; # $rp is reassigned
-$aj="r10";
-$nj="r11";
-$tj="r12";
-# non-volatile registers
-$i="r14";
-$j="r15";
-$tp="r16";
-$m0="r17";
-$m1="r18";
-$lo0="r19";
-$hi0="r20";
-$lo1="r21";
-$hi1="r22";
-$alo="r23";
-$ahi="r24";
-$nlo="r25";
-#
-$nhi="r0";
-
-$code=<<___;
-.machine "any"
-.text
-
-.globl .bn_mul_mont
-.align 4
-.bn_mul_mont:
- cmpwi $num,4
- mr $rp,r3 ; $rp is reassigned
- li r3,0
- bltlr
-
- slwi $num,$num,`log($BNSZ)/log(2)`
- li $tj,-4096
- addi $ovf,$num,`$FRAME+$RZONE`
- subf $ovf,$ovf,$sp ; $sp-$ovf
- and $ovf,$ovf,$tj ; minimize TLB usage
- subf $ovf,$sp,$ovf ; $ovf-$sp
- srwi $num,$num,`log($BNSZ)/log(2)`
- $STUX $sp,$sp,$ovf
-
- $PUSH r14,`4*$SIZE_T`($sp)
- $PUSH r15,`5*$SIZE_T`($sp)
- $PUSH r16,`6*$SIZE_T`($sp)
- $PUSH r17,`7*$SIZE_T`($sp)
- $PUSH r18,`8*$SIZE_T`($sp)
- $PUSH r19,`9*$SIZE_T`($sp)
- $PUSH r20,`10*$SIZE_T`($sp)
- $PUSH r21,`11*$SIZE_T`($sp)
- $PUSH r22,`12*$SIZE_T`($sp)
- $PUSH r23,`13*$SIZE_T`($sp)
- $PUSH r24,`14*$SIZE_T`($sp)
- $PUSH r25,`15*$SIZE_T`($sp)
-
- $LD $n0,0($n0) ; pull n0[0] value
- addi $num,$num,-2 ; adjust $num for counter register
-
- $LD $m0,0($bp) ; m0=bp[0]
- $LD $aj,0($ap) ; ap[0]
- addi $tp,$sp,$FRAME
- $UMULL $lo0,$aj,$m0 ; ap[0]*bp[0]
- $UMULH $hi0,$aj,$m0
-
- $LD $aj,$BNSZ($ap) ; ap[1]
- $LD $nj,0($np) ; np[0]
-
- $UMULL $m1,$lo0,$n0 ; "tp[0]"*n0
-
- $UMULL $alo,$aj,$m0 ; ap[1]*bp[0]
- $UMULH $ahi,$aj,$m0
-
- $UMULL $lo1,$nj,$m1 ; np[0]*m1
- $UMULH $hi1,$nj,$m1
- $LD $nj,$BNSZ($np) ; np[1]
- addc $lo1,$lo1,$lo0
- addze $hi1,$hi1
-
- $UMULL $nlo,$nj,$m1 ; np[1]*m1
- $UMULH $nhi,$nj,$m1
-
- mtctr $num
- li $j,`2*$BNSZ`
-.align 4
-L1st:
- $LDX $aj,$ap,$j ; ap[j]
- addc $lo0,$alo,$hi0
- $LDX $nj,$np,$j ; np[j]
- addze $hi0,$ahi
- $UMULL $alo,$aj,$m0 ; ap[j]*bp[0]
- addc $lo1,$nlo,$hi1
- $UMULH $ahi,$aj,$m0
- addze $hi1,$nhi
- $UMULL $nlo,$nj,$m1 ; np[j]*m1
- addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[0]
- $UMULH $nhi,$nj,$m1
- addze $hi1,$hi1
- $ST $lo1,0($tp) ; tp[j-1]
-
- addi $j,$j,$BNSZ ; j++
- addi $tp,$tp,$BNSZ ; tp++
- bdnz- L1st
-;L1st
- addc $lo0,$alo,$hi0
- addze $hi0,$ahi
-
- addc $lo1,$nlo,$hi1
- addze $hi1,$nhi
- addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[0]
- addze $hi1,$hi1
- $ST $lo1,0($tp) ; tp[j-1]
-
- li $ovf,0
- addc $hi1,$hi1,$hi0
- addze $ovf,$ovf ; upmost overflow bit
- $ST $hi1,$BNSZ($tp)
-
- li $i,$BNSZ
-.align 4
-Louter:
- $LDX $m0,$bp,$i ; m0=bp[i]
- $LD $aj,0($ap) ; ap[0]
- addi $tp,$sp,$FRAME
- $LD $tj,$FRAME($sp) ; tp[0]
- $UMULL $lo0,$aj,$m0 ; ap[0]*bp[i]
- $UMULH $hi0,$aj,$m0
- $LD $aj,$BNSZ($ap) ; ap[1]
- $LD $nj,0($np) ; np[0]
- addc $lo0,$lo0,$tj ; ap[0]*bp[i]+tp[0]
- $UMULL $alo,$aj,$m0 ; ap[j]*bp[i]
- addze $hi0,$hi0
- $UMULL $m1,$lo0,$n0 ; tp[0]*n0
- $UMULH $ahi,$aj,$m0
- $UMULL $lo1,$nj,$m1 ; np[0]*m1
- $UMULH $hi1,$nj,$m1
- $LD $nj,$BNSZ($np) ; np[1]
- addc $lo1,$lo1,$lo0
- $UMULL $nlo,$nj,$m1 ; np[1]*m1
- addze $hi1,$hi1
- $UMULH $nhi,$nj,$m1
-
- mtctr $num
- li $j,`2*$BNSZ`
-.align 4
-Linner:
- $LDX $aj,$ap,$j ; ap[j]
- addc $lo0,$alo,$hi0
- $LD $tj,$BNSZ($tp) ; tp[j]
- addze $hi0,$ahi
- $LDX $nj,$np,$j ; np[j]
- addc $lo1,$nlo,$hi1
- $UMULL $alo,$aj,$m0 ; ap[j]*bp[i]
- addze $hi1,$nhi
- $UMULH $ahi,$aj,$m0
- addc $lo0,$lo0,$tj ; ap[j]*bp[i]+tp[j]
- $UMULL $nlo,$nj,$m1 ; np[j]*m1
- addze $hi0,$hi0
- $UMULH $nhi,$nj,$m1
- addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[i]+tp[j]
- addi $j,$j,$BNSZ ; j++
- addze $hi1,$hi1
- $ST $lo1,0($tp) ; tp[j-1]
- addi $tp,$tp,$BNSZ ; tp++
- bdnz- Linner
-;Linner
- $LD $tj,$BNSZ($tp) ; tp[j]
- addc $lo0,$alo,$hi0
- addze $hi0,$ahi
- addc $lo0,$lo0,$tj ; ap[j]*bp[i]+tp[j]
- addze $hi0,$hi0
-
- addc $lo1,$nlo,$hi1
- addze $hi1,$nhi
- addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[i]+tp[j]
- addze $hi1,$hi1
- $ST $lo1,0($tp) ; tp[j-1]
-
- addic $ovf,$ovf,-1 ; move upmost overflow to XER[CA]
- li $ovf,0
- adde $hi1,$hi1,$hi0
- addze $ovf,$ovf
- $ST $hi1,$BNSZ($tp)
-;
- slwi $tj,$num,`log($BNSZ)/log(2)`
- $UCMP $i,$tj
- addi $i,$i,$BNSZ
- ble- Louter
-
- addi $num,$num,2 ; restore $num
- subfc $j,$j,$j ; j=0 and "clear" XER[CA]
- addi $tp,$sp,$FRAME
- mtctr $num
-
-.align 4
-Lsub: $LDX $tj,$tp,$j
- $LDX $nj,$np,$j
- subfe $aj,$nj,$tj ; tp[j]-np[j]
- $STX $aj,$rp,$j
- addi $j,$j,$BNSZ
- bdnz- Lsub
-
- li $j,0
- mtctr $num
- subfe $ovf,$j,$ovf ; handle upmost overflow bit
- and $ap,$tp,$ovf
- andc $np,$rp,$ovf
- or $ap,$ap,$np ; ap=borrow?tp:rp
-
-.align 4
-Lcopy: ; copy or in-place refresh
- $LDX $tj,$ap,$j
- $STX $tj,$rp,$j
- $STX $j,$tp,$j ; zap at once
- addi $j,$j,$BNSZ
- bdnz- Lcopy
-
- $POP r14,`4*$SIZE_T`($sp)
- $POP r15,`5*$SIZE_T`($sp)
- $POP r16,`6*$SIZE_T`($sp)
- $POP r17,`7*$SIZE_T`($sp)
- $POP r18,`8*$SIZE_T`($sp)
- $POP r19,`9*$SIZE_T`($sp)
- $POP r20,`10*$SIZE_T`($sp)
- $POP r21,`11*$SIZE_T`($sp)
- $POP r22,`12*$SIZE_T`($sp)
- $POP r23,`13*$SIZE_T`($sp)
- $POP r24,`14*$SIZE_T`($sp)
- $POP r25,`15*$SIZE_T`($sp)
- $POP $sp,0($sp)
- li r3,1
- blr
- .long 0
-.asciz "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
-___
-
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/ppc.pl b/crypto/openssl/crypto/bn/asm/ppc.pl
index 08e0053..806e53a 100644
--- a/crypto/openssl/crypto/bn/asm/ppc.pl
+++ b/crypto/openssl/crypto/bn/asm/ppc.pl
@@ -2074,5 +2074,7 @@ EOF
$data =~ s/^(\s*)cmplw(\s+)([^,]+),(.*)/$1cmpl$2$3,0,$4/gm;
# assembler X doesn't accept li, load immediate value
#$data =~ s/^(\s*)li(\s+)([^,]+),(.*)/$1addi$2$3,0,$4/gm;
+ # assembler Y chokes on apostrophes in comments
+ $data =~ s/'//gm;
return($data);
}
diff --git a/crypto/openssl/crypto/bn/asm/ppc64-mont.pl b/crypto/openssl/crypto/bn/asm/ppc64-mont.pl
deleted file mode 100755
index 3449b35..0000000
--- a/crypto/openssl/crypto/bn/asm/ppc64-mont.pl
+++ /dev/null
@@ -1,918 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# December 2007
-
-# The reason for undertaken effort is basically following. Even though
-# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
-# performance was observed to be less than impressive, essentially as
-# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
-# Well, it's not surprising that IBM had to make some sacrifices to
-# boost the clock frequency that much, but no overall improvement?
-# Having observed how much difference did switching to FPU make on
-# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
-# Unfortunately the resulting performance improvement is not as
-# impressive, ~30%, and in absolute terms is still very far from what
-# one would expect from 4.7GHz CPU. There is a chance that I'm doing
-# something wrong, but in the lack of assembler level micro-profiling
-# data or at least decent platform guide I can't tell... Or better
-# results might be achieved with VMX... Anyway, this module provides
-# *worse* performance on other PowerPC implementations, ~40-15% slower
-# on PPC970 depending on key length and ~40% slower on Power 5 for all
-# key lengths. As it's obviously inappropriate as "best all-round"
-# alternative, it has to be complemented with run-time CPU family
-# detection. Oh! It should also be noted that unlike other PowerPC
-# implementation IALU ppc-mont.pl module performs *suboptimaly* on
-# >=1024-bit key lengths on Power 6. It should also be noted that
-# *everything* said so far applies to 64-bit builds! As far as 32-bit
-# application executed on 64-bit CPU goes, this module is likely to
-# become preferred choice, because it's easy to adapt it for such
-# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
-
-# February 2008
-
-# Micro-profiling assisted optimization results in ~15% improvement
-# over original ppc64-mont.pl version, or overall ~50% improvement
-# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
-# Power 6 CPU, this module is 5-150% faster depending on key length,
-# [hereafter] more for longer keys. But if compared to ppc-mont.pl
-# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
-# in absolute terms, but it's apparently the way Power 6 is...
-
-$flavour = shift;
-
-if ($flavour =~ /32/) {
- $SIZE_T=4;
- $RZONE= 224;
- $FRAME= $SIZE_T*12+8*12;
- $fname= "bn_mul_mont_ppc64";
-
- $STUX= "stwux"; # store indexed and update
- $PUSH= "stw";
- $POP= "lwz";
- die "not implemented yet";
-} elsif ($flavour =~ /64/) {
- $SIZE_T=8;
- $RZONE= 288;
- $FRAME= $SIZE_T*12+8*12;
- $fname= "bn_mul_mont";
-
- # same as above, but 64-bit mnemonics...
- $STUX= "stdux"; # store indexed and update
- $PUSH= "std";
- $POP= "ld";
-} else { die "nonsense $flavour"; }
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-die "can't locate ppc-xlate.pl";
-
-open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-
-$FRAME=($FRAME+63)&~63;
-$TRANSFER=16*8;
-
-$carry="r0";
-$sp="r1";
-$toc="r2";
-$rp="r3"; $ovf="r3";
-$ap="r4";
-$bp="r5";
-$np="r6";
-$n0="r7";
-$num="r8";
-$rp="r9"; # $rp is reassigned
-$tp="r10";
-$j="r11";
-$i="r12";
-# non-volatile registers
-$nap_d="r14"; # interleaved ap and np in double format
-$a0="r15"; # ap[0]
-$t0="r16"; # temporary registers
-$t1="r17";
-$t2="r18";
-$t3="r19";
-$t4="r20";
-$t5="r21";
-$t6="r22";
-$t7="r23";
-
-# PPC offers enough register bank capacity to unroll inner loops twice
-#
-# ..A3A2A1A0
-# dcba
-# -----------
-# A0a
-# A0b
-# A0c
-# A0d
-# A1a
-# A1b
-# A1c
-# A1d
-# A2a
-# A2b
-# A2c
-# A2d
-# A3a
-# A3b
-# A3c
-# A3d
-# ..a
-# ..b
-#
-$ba="f0"; $bb="f1"; $bc="f2"; $bd="f3";
-$na="f4"; $nb="f5"; $nc="f6"; $nd="f7";
-$dota="f8"; $dotb="f9";
-$A0="f10"; $A1="f11"; $A2="f12"; $A3="f13";
-$N0="f14"; $N1="f15"; $N2="f16"; $N3="f17";
-$T0a="f18"; $T0b="f19";
-$T1a="f20"; $T1b="f21";
-$T2a="f22"; $T2b="f23";
-$T3a="f24"; $T3b="f25";
-
-# sp----------->+-------------------------------+
-# | saved sp |
-# +-------------------------------+
-# | |
-# +-------------------------------+
-# | 10 saved gpr, r14-r23 |
-# . .
-# . .
-# +12*size_t +-------------------------------+
-# | 12 saved fpr, f14-f25 |
-# . .
-# . .
-# +12*8 +-------------------------------+
-# | padding to 64 byte boundary |
-# . .
-# +X +-------------------------------+
-# | 16 gpr<->fpr transfer zone |
-# . .
-# . .
-# +16*8 +-------------------------------+
-# | __int64 tmp[-1] |
-# +-------------------------------+
-# | __int64 tmp[num] |
-# . .
-# . .
-# . .
-# +(num+1)*8 +-------------------------------+
-# | padding to 64 byte boundary |
-# . .
-# +X +-------------------------------+
-# | double nap_d[4*num] |
-# . .
-# . .
-# . .
-# +-------------------------------+
-
-$code=<<___;
-.machine "any"
-.text
-
-.globl .$fname
-.align 5
-.$fname:
- cmpwi $num,4
- mr $rp,r3 ; $rp is reassigned
- li r3,0 ; possible "not handled" return code
- bltlr-
- andi. r0,$num,1 ; $num has to be even
- bnelr-
-
- slwi $num,$num,3 ; num*=8
- li $i,-4096
- slwi $tp,$num,2 ; place for {an}p_{lh}[num], i.e. 4*num
- add $tp,$tp,$num ; place for tp[num+1]
- addi $tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
- subf $tp,$tp,$sp ; $sp-$tp
- and $tp,$tp,$i ; minimize TLB usage
- subf $tp,$sp,$tp ; $tp-$sp
- $STUX $sp,$sp,$tp ; alloca
-
- $PUSH r14,`2*$SIZE_T`($sp)
- $PUSH r15,`3*$SIZE_T`($sp)
- $PUSH r16,`4*$SIZE_T`($sp)
- $PUSH r17,`5*$SIZE_T`($sp)
- $PUSH r18,`6*$SIZE_T`($sp)
- $PUSH r19,`7*$SIZE_T`($sp)
- $PUSH r20,`8*$SIZE_T`($sp)
- $PUSH r21,`9*$SIZE_T`($sp)
- $PUSH r22,`10*$SIZE_T`($sp)
- $PUSH r23,`11*$SIZE_T`($sp)
- stfd f14,`12*$SIZE_T+0`($sp)
- stfd f15,`12*$SIZE_T+8`($sp)
- stfd f16,`12*$SIZE_T+16`($sp)
- stfd f17,`12*$SIZE_T+24`($sp)
- stfd f18,`12*$SIZE_T+32`($sp)
- stfd f19,`12*$SIZE_T+40`($sp)
- stfd f20,`12*$SIZE_T+48`($sp)
- stfd f21,`12*$SIZE_T+56`($sp)
- stfd f22,`12*$SIZE_T+64`($sp)
- stfd f23,`12*$SIZE_T+72`($sp)
- stfd f24,`12*$SIZE_T+80`($sp)
- stfd f25,`12*$SIZE_T+88`($sp)
-
- ld $a0,0($ap) ; pull ap[0] value
- ld $n0,0($n0) ; pull n0[0] value
- ld $t3,0($bp) ; bp[0]
-
- addi $tp,$sp,`$FRAME+$TRANSFER+8+64`
- li $i,-64
- add $nap_d,$tp,$num
- and $nap_d,$nap_d,$i ; align to 64 bytes
-
- mulld $t7,$a0,$t3 ; ap[0]*bp[0]
- ; nap_d is off by 1, because it's used with stfdu/lfdu
- addi $nap_d,$nap_d,-8
- srwi $j,$num,`3+1` ; counter register, num/2
- mulld $t7,$t7,$n0 ; tp[0]*n0
- addi $j,$j,-1
- addi $tp,$sp,`$FRAME+$TRANSFER-8`
- li $carry,0
- mtctr $j
-
- ; transfer bp[0] to FPU as 4x16-bit values
- extrdi $t0,$t3,16,48
- extrdi $t1,$t3,16,32
- extrdi $t2,$t3,16,16
- extrdi $t3,$t3,16,0
- std $t0,`$FRAME+0`($sp)
- std $t1,`$FRAME+8`($sp)
- std $t2,`$FRAME+16`($sp)
- std $t3,`$FRAME+24`($sp)
- ; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
- extrdi $t4,$t7,16,48
- extrdi $t5,$t7,16,32
- extrdi $t6,$t7,16,16
- extrdi $t7,$t7,16,0
- std $t4,`$FRAME+32`($sp)
- std $t5,`$FRAME+40`($sp)
- std $t6,`$FRAME+48`($sp)
- std $t7,`$FRAME+56`($sp)
- lwz $t0,4($ap) ; load a[j] as 32-bit word pair
- lwz $t1,0($ap)
- lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair
- lwz $t3,8($ap)
- lwz $t4,4($np) ; load n[j] as 32-bit word pair
- lwz $t5,0($np)
- lwz $t6,12($np) ; load n[j+1] as 32-bit word pair
- lwz $t7,8($np)
- lfd $ba,`$FRAME+0`($sp)
- lfd $bb,`$FRAME+8`($sp)
- lfd $bc,`$FRAME+16`($sp)
- lfd $bd,`$FRAME+24`($sp)
- lfd $na,`$FRAME+32`($sp)
- lfd $nb,`$FRAME+40`($sp)
- lfd $nc,`$FRAME+48`($sp)
- lfd $nd,`$FRAME+56`($sp)
- std $t0,`$FRAME+64`($sp)
- std $t1,`$FRAME+72`($sp)
- std $t2,`$FRAME+80`($sp)
- std $t3,`$FRAME+88`($sp)
- std $t4,`$FRAME+96`($sp)
- std $t5,`$FRAME+104`($sp)
- std $t6,`$FRAME+112`($sp)
- std $t7,`$FRAME+120`($sp)
- fcfid $ba,$ba
- fcfid $bb,$bb
- fcfid $bc,$bc
- fcfid $bd,$bd
- fcfid $na,$na
- fcfid $nb,$nb
- fcfid $nc,$nc
- fcfid $nd,$nd
-
- lfd $A0,`$FRAME+64`($sp)
- lfd $A1,`$FRAME+72`($sp)
- lfd $A2,`$FRAME+80`($sp)
- lfd $A3,`$FRAME+88`($sp)
- lfd $N0,`$FRAME+96`($sp)
- lfd $N1,`$FRAME+104`($sp)
- lfd $N2,`$FRAME+112`($sp)
- lfd $N3,`$FRAME+120`($sp)
- fcfid $A0,$A0
- fcfid $A1,$A1
- fcfid $A2,$A2
- fcfid $A3,$A3
- fcfid $N0,$N0
- fcfid $N1,$N1
- fcfid $N2,$N2
- fcfid $N3,$N3
- addi $ap,$ap,16
- addi $np,$np,16
-
- fmul $T1a,$A1,$ba
- fmul $T1b,$A1,$bb
- stfd $A0,8($nap_d) ; save a[j] in double format
- stfd $A1,16($nap_d)
- fmul $T2a,$A2,$ba
- fmul $T2b,$A2,$bb
- stfd $A2,24($nap_d) ; save a[j+1] in double format
- stfd $A3,32($nap_d)
- fmul $T3a,$A3,$ba
- fmul $T3b,$A3,$bb
- stfd $N0,40($nap_d) ; save n[j] in double format
- stfd $N1,48($nap_d)
- fmul $T0a,$A0,$ba
- fmul $T0b,$A0,$bb
- stfd $N2,56($nap_d) ; save n[j+1] in double format
- stfdu $N3,64($nap_d)
-
- fmadd $T1a,$A0,$bc,$T1a
- fmadd $T1b,$A0,$bd,$T1b
- fmadd $T2a,$A1,$bc,$T2a
- fmadd $T2b,$A1,$bd,$T2b
- fmadd $T3a,$A2,$bc,$T3a
- fmadd $T3b,$A2,$bd,$T3b
- fmul $dota,$A3,$bc
- fmul $dotb,$A3,$bd
-
- fmadd $T1a,$N1,$na,$T1a
- fmadd $T1b,$N1,$nb,$T1b
- fmadd $T2a,$N2,$na,$T2a
- fmadd $T2b,$N2,$nb,$T2b
- fmadd $T3a,$N3,$na,$T3a
- fmadd $T3b,$N3,$nb,$T3b
- fmadd $T0a,$N0,$na,$T0a
- fmadd $T0b,$N0,$nb,$T0b
-
- fmadd $T1a,$N0,$nc,$T1a
- fmadd $T1b,$N0,$nd,$T1b
- fmadd $T2a,$N1,$nc,$T2a
- fmadd $T2b,$N1,$nd,$T2b
- fmadd $T3a,$N2,$nc,$T3a
- fmadd $T3b,$N2,$nd,$T3b
- fmadd $dota,$N3,$nc,$dota
- fmadd $dotb,$N3,$nd,$dotb
-
- fctid $T0a,$T0a
- fctid $T0b,$T0b
- fctid $T1a,$T1a
- fctid $T1b,$T1b
- fctid $T2a,$T2a
- fctid $T2b,$T2b
- fctid $T3a,$T3a
- fctid $T3b,$T3b
-
- stfd $T0a,`$FRAME+0`($sp)
- stfd $T0b,`$FRAME+8`($sp)
- stfd $T1a,`$FRAME+16`($sp)
- stfd $T1b,`$FRAME+24`($sp)
- stfd $T2a,`$FRAME+32`($sp)
- stfd $T2b,`$FRAME+40`($sp)
- stfd $T3a,`$FRAME+48`($sp)
- stfd $T3b,`$FRAME+56`($sp)
-
-.align 5
-L1st:
- lwz $t0,4($ap) ; load a[j] as 32-bit word pair
- lwz $t1,0($ap)
- lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair
- lwz $t3,8($ap)
- lwz $t4,4($np) ; load n[j] as 32-bit word pair
- lwz $t5,0($np)
- lwz $t6,12($np) ; load n[j+1] as 32-bit word pair
- lwz $t7,8($np)
- std $t0,`$FRAME+64`($sp)
- std $t1,`$FRAME+72`($sp)
- std $t2,`$FRAME+80`($sp)
- std $t3,`$FRAME+88`($sp)
- std $t4,`$FRAME+96`($sp)
- std $t5,`$FRAME+104`($sp)
- std $t6,`$FRAME+112`($sp)
- std $t7,`$FRAME+120`($sp)
- ld $t0,`$FRAME+0`($sp)
- ld $t1,`$FRAME+8`($sp)
- ld $t2,`$FRAME+16`($sp)
- ld $t3,`$FRAME+24`($sp)
- ld $t4,`$FRAME+32`($sp)
- ld $t5,`$FRAME+40`($sp)
- ld $t6,`$FRAME+48`($sp)
- ld $t7,`$FRAME+56`($sp)
- lfd $A0,`$FRAME+64`($sp)
- lfd $A1,`$FRAME+72`($sp)
- lfd $A2,`$FRAME+80`($sp)
- lfd $A3,`$FRAME+88`($sp)
- lfd $N0,`$FRAME+96`($sp)
- lfd $N1,`$FRAME+104`($sp)
- lfd $N2,`$FRAME+112`($sp)
- lfd $N3,`$FRAME+120`($sp)
- fcfid $A0,$A0
- fcfid $A1,$A1
- fcfid $A2,$A2
- fcfid $A3,$A3
- fcfid $N0,$N0
- fcfid $N1,$N1
- fcfid $N2,$N2
- fcfid $N3,$N3
- addi $ap,$ap,16
- addi $np,$np,16
-
- fmul $T1a,$A1,$ba
- fmul $T1b,$A1,$bb
- fmul $T2a,$A2,$ba
- fmul $T2b,$A2,$bb
- stfd $A0,8($nap_d) ; save a[j] in double format
- stfd $A1,16($nap_d)
- fmul $T3a,$A3,$ba
- fmul $T3b,$A3,$bb
- fmadd $T0a,$A0,$ba,$dota
- fmadd $T0b,$A0,$bb,$dotb
- stfd $A2,24($nap_d) ; save a[j+1] in double format
- stfd $A3,32($nap_d)
-
- fmadd $T1a,$A0,$bc,$T1a
- fmadd $T1b,$A0,$bd,$T1b
- fmadd $T2a,$A1,$bc,$T2a
- fmadd $T2b,$A1,$bd,$T2b
- stfd $N0,40($nap_d) ; save n[j] in double format
- stfd $N1,48($nap_d)
- fmadd $T3a,$A2,$bc,$T3a
- fmadd $T3b,$A2,$bd,$T3b
- add $t0,$t0,$carry ; can not overflow
- fmul $dota,$A3,$bc
- fmul $dotb,$A3,$bd
- stfd $N2,56($nap_d) ; save n[j+1] in double format
- stfdu $N3,64($nap_d)
- srdi $carry,$t0,16
- add $t1,$t1,$carry
- srdi $carry,$t1,16
-
- fmadd $T1a,$N1,$na,$T1a
- fmadd $T1b,$N1,$nb,$T1b
- insrdi $t0,$t1,16,32
- fmadd $T2a,$N2,$na,$T2a
- fmadd $T2b,$N2,$nb,$T2b
- add $t2,$t2,$carry
- fmadd $T3a,$N3,$na,$T3a
- fmadd $T3b,$N3,$nb,$T3b
- srdi $carry,$t2,16
- fmadd $T0a,$N0,$na,$T0a
- fmadd $T0b,$N0,$nb,$T0b
- insrdi $t0,$t2,16,16
- add $t3,$t3,$carry
- srdi $carry,$t3,16
-
- fmadd $T1a,$N0,$nc,$T1a
- fmadd $T1b,$N0,$nd,$T1b
- insrdi $t0,$t3,16,0 ; 0..63 bits
- fmadd $T2a,$N1,$nc,$T2a
- fmadd $T2b,$N1,$nd,$T2b
- add $t4,$t4,$carry
- fmadd $T3a,$N2,$nc,$T3a
- fmadd $T3b,$N2,$nd,$T3b
- srdi $carry,$t4,16
- fmadd $dota,$N3,$nc,$dota
- fmadd $dotb,$N3,$nd,$dotb
- add $t5,$t5,$carry
- srdi $carry,$t5,16
- insrdi $t4,$t5,16,32
-
- fctid $T0a,$T0a
- fctid $T0b,$T0b
- add $t6,$t6,$carry
- fctid $T1a,$T1a
- fctid $T1b,$T1b
- srdi $carry,$t6,16
- fctid $T2a,$T2a
- fctid $T2b,$T2b
- insrdi $t4,$t6,16,16
- fctid $T3a,$T3a
- fctid $T3b,$T3b
- add $t7,$t7,$carry
- insrdi $t4,$t7,16,0 ; 64..127 bits
- srdi $carry,$t7,16 ; upper 33 bits
-
- stfd $T0a,`$FRAME+0`($sp)
- stfd $T0b,`$FRAME+8`($sp)
- stfd $T1a,`$FRAME+16`($sp)
- stfd $T1b,`$FRAME+24`($sp)
- stfd $T2a,`$FRAME+32`($sp)
- stfd $T2b,`$FRAME+40`($sp)
- stfd $T3a,`$FRAME+48`($sp)
- stfd $T3b,`$FRAME+56`($sp)
- std $t0,8($tp) ; tp[j-1]
- stdu $t4,16($tp) ; tp[j]
- bdnz- L1st
-
- fctid $dota,$dota
- fctid $dotb,$dotb
-
- ld $t0,`$FRAME+0`($sp)
- ld $t1,`$FRAME+8`($sp)
- ld $t2,`$FRAME+16`($sp)
- ld $t3,`$FRAME+24`($sp)
- ld $t4,`$FRAME+32`($sp)
- ld $t5,`$FRAME+40`($sp)
- ld $t6,`$FRAME+48`($sp)
- ld $t7,`$FRAME+56`($sp)
- stfd $dota,`$FRAME+64`($sp)
- stfd $dotb,`$FRAME+72`($sp)
-
- add $t0,$t0,$carry ; can not overflow
- srdi $carry,$t0,16
- add $t1,$t1,$carry
- srdi $carry,$t1,16
- insrdi $t0,$t1,16,32
- add $t2,$t2,$carry
- srdi $carry,$t2,16
- insrdi $t0,$t2,16,16
- add $t3,$t3,$carry
- srdi $carry,$t3,16
- insrdi $t0,$t3,16,0 ; 0..63 bits
- add $t4,$t4,$carry
- srdi $carry,$t4,16
- add $t5,$t5,$carry
- srdi $carry,$t5,16
- insrdi $t4,$t5,16,32
- add $t6,$t6,$carry
- srdi $carry,$t6,16
- insrdi $t4,$t6,16,16
- add $t7,$t7,$carry
- insrdi $t4,$t7,16,0 ; 64..127 bits
- srdi $carry,$t7,16 ; upper 33 bits
- ld $t6,`$FRAME+64`($sp)
- ld $t7,`$FRAME+72`($sp)
-
- std $t0,8($tp) ; tp[j-1]
- stdu $t4,16($tp) ; tp[j]
-
- add $t6,$t6,$carry ; can not overflow
- srdi $carry,$t6,16
- add $t7,$t7,$carry
- insrdi $t6,$t7,48,0
- srdi $ovf,$t7,48
- std $t6,8($tp) ; tp[num-1]
-
- slwi $t7,$num,2
- subf $nap_d,$t7,$nap_d ; rewind pointer
-
- li $i,8 ; i=1
-.align 5
-Louter:
- ldx $t3,$bp,$i ; bp[i]
- ld $t6,`$FRAME+$TRANSFER+8`($sp) ; tp[0]
- mulld $t7,$a0,$t3 ; ap[0]*bp[i]
-
- addi $tp,$sp,`$FRAME+$TRANSFER`
- add $t7,$t7,$t6 ; ap[0]*bp[i]+tp[0]
- li $carry,0
- mulld $t7,$t7,$n0 ; tp[0]*n0
- mtctr $j
-
- ; transfer bp[i] to FPU as 4x16-bit values
- extrdi $t0,$t3,16,48
- extrdi $t1,$t3,16,32
- extrdi $t2,$t3,16,16
- extrdi $t3,$t3,16,0
- std $t0,`$FRAME+0`($sp)
- std $t1,`$FRAME+8`($sp)
- std $t2,`$FRAME+16`($sp)
- std $t3,`$FRAME+24`($sp)
- ; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
- extrdi $t4,$t7,16,48
- extrdi $t5,$t7,16,32
- extrdi $t6,$t7,16,16
- extrdi $t7,$t7,16,0
- std $t4,`$FRAME+32`($sp)
- std $t5,`$FRAME+40`($sp)
- std $t6,`$FRAME+48`($sp)
- std $t7,`$FRAME+56`($sp)
-
- lfd $A0,8($nap_d) ; load a[j] in double format
- lfd $A1,16($nap_d)
- lfd $A2,24($nap_d) ; load a[j+1] in double format
- lfd $A3,32($nap_d)
- lfd $N0,40($nap_d) ; load n[j] in double format
- lfd $N1,48($nap_d)
- lfd $N2,56($nap_d) ; load n[j+1] in double format
- lfdu $N3,64($nap_d)
-
- lfd $ba,`$FRAME+0`($sp)
- lfd $bb,`$FRAME+8`($sp)
- lfd $bc,`$FRAME+16`($sp)
- lfd $bd,`$FRAME+24`($sp)
- lfd $na,`$FRAME+32`($sp)
- lfd $nb,`$FRAME+40`($sp)
- lfd $nc,`$FRAME+48`($sp)
- lfd $nd,`$FRAME+56`($sp)
-
- fcfid $ba,$ba
- fcfid $bb,$bb
- fcfid $bc,$bc
- fcfid $bd,$bd
- fcfid $na,$na
- fcfid $nb,$nb
- fcfid $nc,$nc
- fcfid $nd,$nd
-
- fmul $T1a,$A1,$ba
- fmul $T1b,$A1,$bb
- fmul $T2a,$A2,$ba
- fmul $T2b,$A2,$bb
- fmul $T3a,$A3,$ba
- fmul $T3b,$A3,$bb
- fmul $T0a,$A0,$ba
- fmul $T0b,$A0,$bb
-
- fmadd $T1a,$A0,$bc,$T1a
- fmadd $T1b,$A0,$bd,$T1b
- fmadd $T2a,$A1,$bc,$T2a
- fmadd $T2b,$A1,$bd,$T2b
- fmadd $T3a,$A2,$bc,$T3a
- fmadd $T3b,$A2,$bd,$T3b
- fmul $dota,$A3,$bc
- fmul $dotb,$A3,$bd
-
- fmadd $T1a,$N1,$na,$T1a
- fmadd $T1b,$N1,$nb,$T1b
- lfd $A0,8($nap_d) ; load a[j] in double format
- lfd $A1,16($nap_d)
- fmadd $T2a,$N2,$na,$T2a
- fmadd $T2b,$N2,$nb,$T2b
- lfd $A2,24($nap_d) ; load a[j+1] in double format
- lfd $A3,32($nap_d)
- fmadd $T3a,$N3,$na,$T3a
- fmadd $T3b,$N3,$nb,$T3b
- fmadd $T0a,$N0,$na,$T0a
- fmadd $T0b,$N0,$nb,$T0b
-
- fmadd $T1a,$N0,$nc,$T1a
- fmadd $T1b,$N0,$nd,$T1b
- fmadd $T2a,$N1,$nc,$T2a
- fmadd $T2b,$N1,$nd,$T2b
- fmadd $T3a,$N2,$nc,$T3a
- fmadd $T3b,$N2,$nd,$T3b
- fmadd $dota,$N3,$nc,$dota
- fmadd $dotb,$N3,$nd,$dotb
-
- fctid $T0a,$T0a
- fctid $T0b,$T0b
- fctid $T1a,$T1a
- fctid $T1b,$T1b
- fctid $T2a,$T2a
- fctid $T2b,$T2b
- fctid $T3a,$T3a
- fctid $T3b,$T3b
-
- stfd $T0a,`$FRAME+0`($sp)
- stfd $T0b,`$FRAME+8`($sp)
- stfd $T1a,`$FRAME+16`($sp)
- stfd $T1b,`$FRAME+24`($sp)
- stfd $T2a,`$FRAME+32`($sp)
- stfd $T2b,`$FRAME+40`($sp)
- stfd $T3a,`$FRAME+48`($sp)
- stfd $T3b,`$FRAME+56`($sp)
-
-.align 5
-Linner:
- fmul $T1a,$A1,$ba
- fmul $T1b,$A1,$bb
- fmul $T2a,$A2,$ba
- fmul $T2b,$A2,$bb
- lfd $N0,40($nap_d) ; load n[j] in double format
- lfd $N1,48($nap_d)
- fmul $T3a,$A3,$ba
- fmul $T3b,$A3,$bb
- fmadd $T0a,$A0,$ba,$dota
- fmadd $T0b,$A0,$bb,$dotb
- lfd $N2,56($nap_d) ; load n[j+1] in double format
- lfdu $N3,64($nap_d)
-
- fmadd $T1a,$A0,$bc,$T1a
- fmadd $T1b,$A0,$bd,$T1b
- fmadd $T2a,$A1,$bc,$T2a
- fmadd $T2b,$A1,$bd,$T2b
- lfd $A0,8($nap_d) ; load a[j] in double format
- lfd $A1,16($nap_d)
- fmadd $T3a,$A2,$bc,$T3a
- fmadd $T3b,$A2,$bd,$T3b
- fmul $dota,$A3,$bc
- fmul $dotb,$A3,$bd
- lfd $A2,24($nap_d) ; load a[j+1] in double format
- lfd $A3,32($nap_d)
-
- fmadd $T1a,$N1,$na,$T1a
- fmadd $T1b,$N1,$nb,$T1b
- ld $t0,`$FRAME+0`($sp)
- ld $t1,`$FRAME+8`($sp)
- fmadd $T2a,$N2,$na,$T2a
- fmadd $T2b,$N2,$nb,$T2b
- ld $t2,`$FRAME+16`($sp)
- ld $t3,`$FRAME+24`($sp)
- fmadd $T3a,$N3,$na,$T3a
- fmadd $T3b,$N3,$nb,$T3b
- add $t0,$t0,$carry ; can not overflow
- ld $t4,`$FRAME+32`($sp)
- ld $t5,`$FRAME+40`($sp)
- fmadd $T0a,$N0,$na,$T0a
- fmadd $T0b,$N0,$nb,$T0b
- srdi $carry,$t0,16
- add $t1,$t1,$carry
- srdi $carry,$t1,16
- ld $t6,`$FRAME+48`($sp)
- ld $t7,`$FRAME+56`($sp)
-
- fmadd $T1a,$N0,$nc,$T1a
- fmadd $T1b,$N0,$nd,$T1b
- insrdi $t0,$t1,16,32
- ld $t1,8($tp) ; tp[j]
- fmadd $T2a,$N1,$nc,$T2a
- fmadd $T2b,$N1,$nd,$T2b
- add $t2,$t2,$carry
- fmadd $T3a,$N2,$nc,$T3a
- fmadd $T3b,$N2,$nd,$T3b
- srdi $carry,$t2,16
- insrdi $t0,$t2,16,16
- fmadd $dota,$N3,$nc,$dota
- fmadd $dotb,$N3,$nd,$dotb
- add $t3,$t3,$carry
- ldu $t2,16($tp) ; tp[j+1]
- srdi $carry,$t3,16
- insrdi $t0,$t3,16,0 ; 0..63 bits
- add $t4,$t4,$carry
-
- fctid $T0a,$T0a
- fctid $T0b,$T0b
- srdi $carry,$t4,16
- fctid $T1a,$T1a
- fctid $T1b,$T1b
- add $t5,$t5,$carry
- fctid $T2a,$T2a
- fctid $T2b,$T2b
- srdi $carry,$t5,16
- insrdi $t4,$t5,16,32
- fctid $T3a,$T3a
- fctid $T3b,$T3b
- add $t6,$t6,$carry
- srdi $carry,$t6,16
- insrdi $t4,$t6,16,16
-
- stfd $T0a,`$FRAME+0`($sp)
- stfd $T0b,`$FRAME+8`($sp)
- add $t7,$t7,$carry
- addc $t3,$t0,$t1
- stfd $T1a,`$FRAME+16`($sp)
- stfd $T1b,`$FRAME+24`($sp)
- insrdi $t4,$t7,16,0 ; 64..127 bits
- srdi $carry,$t7,16 ; upper 33 bits
- stfd $T2a,`$FRAME+32`($sp)
- stfd $T2b,`$FRAME+40`($sp)
- adde $t5,$t4,$t2
- stfd $T3a,`$FRAME+48`($sp)
- stfd $T3b,`$FRAME+56`($sp)
- addze $carry,$carry
- std $t3,-16($tp) ; tp[j-1]
- std $t5,-8($tp) ; tp[j]
- bdnz- Linner
-
- fctid $dota,$dota
- fctid $dotb,$dotb
- ld $t0,`$FRAME+0`($sp)
- ld $t1,`$FRAME+8`($sp)
- ld $t2,`$FRAME+16`($sp)
- ld $t3,`$FRAME+24`($sp)
- ld $t4,`$FRAME+32`($sp)
- ld $t5,`$FRAME+40`($sp)
- ld $t6,`$FRAME+48`($sp)
- ld $t7,`$FRAME+56`($sp)
- stfd $dota,`$FRAME+64`($sp)
- stfd $dotb,`$FRAME+72`($sp)
-
- add $t0,$t0,$carry ; can not overflow
- srdi $carry,$t0,16
- add $t1,$t1,$carry
- srdi $carry,$t1,16
- insrdi $t0,$t1,16,32
- add $t2,$t2,$carry
- ld $t1,8($tp) ; tp[j]
- srdi $carry,$t2,16
- insrdi $t0,$t2,16,16
- add $t3,$t3,$carry
- ldu $t2,16($tp) ; tp[j+1]
- srdi $carry,$t3,16
- insrdi $t0,$t3,16,0 ; 0..63 bits
- add $t4,$t4,$carry
- srdi $carry,$t4,16
- add $t5,$t5,$carry
- srdi $carry,$t5,16
- insrdi $t4,$t5,16,32
- add $t6,$t6,$carry
- srdi $carry,$t6,16
- insrdi $t4,$t6,16,16
- add $t7,$t7,$carry
- insrdi $t4,$t7,16,0 ; 64..127 bits
- srdi $carry,$t7,16 ; upper 33 bits
- ld $t6,`$FRAME+64`($sp)
- ld $t7,`$FRAME+72`($sp)
-
- addc $t3,$t0,$t1
- adde $t5,$t4,$t2
- addze $carry,$carry
-
- std $t3,-16($tp) ; tp[j-1]
- std $t5,-8($tp) ; tp[j]
-
- add $carry,$carry,$ovf ; comsume upmost overflow
- add $t6,$t6,$carry ; can not overflow
- srdi $carry,$t6,16
- add $t7,$t7,$carry
- insrdi $t6,$t7,48,0
- srdi $ovf,$t7,48
- std $t6,0($tp) ; tp[num-1]
-
- slwi $t7,$num,2
- addi $i,$i,8
- subf $nap_d,$t7,$nap_d ; rewind pointer
- cmpw $i,$num
- blt- Louter
-
- subf $np,$num,$np ; rewind np
- addi $j,$j,1 ; restore counter
- subfc $i,$i,$i ; j=0 and "clear" XER[CA]
- addi $tp,$sp,`$FRAME+$TRANSFER+8`
- addi $t4,$sp,`$FRAME+$TRANSFER+16`
- addi $t5,$np,8
- addi $t6,$rp,8
- mtctr $j
-
-.align 4
-Lsub: ldx $t0,$tp,$i
- ldx $t1,$np,$i
- ldx $t2,$t4,$i
- ldx $t3,$t5,$i
- subfe $t0,$t1,$t0 ; tp[j]-np[j]
- subfe $t2,$t3,$t2 ; tp[j+1]-np[j+1]
- stdx $t0,$rp,$i
- stdx $t2,$t6,$i
- addi $i,$i,16
- bdnz- Lsub
-
- li $i,0
- subfe $ovf,$i,$ovf ; handle upmost overflow bit
- and $ap,$tp,$ovf
- andc $np,$rp,$ovf
- or $ap,$ap,$np ; ap=borrow?tp:rp
- addi $t7,$ap,8
- mtctr $j
-
-.align 4
-Lcopy: ; copy or in-place refresh
- ldx $t0,$ap,$i
- ldx $t1,$t7,$i
- std $i,8($nap_d) ; zap nap_d
- std $i,16($nap_d)
- std $i,24($nap_d)
- std $i,32($nap_d)
- std $i,40($nap_d)
- std $i,48($nap_d)
- std $i,56($nap_d)
- stdu $i,64($nap_d)
- stdx $t0,$rp,$i
- stdx $t1,$t6,$i
- stdx $i,$tp,$i ; zap tp at once
- stdx $i,$t4,$i
- addi $i,$i,16
- bdnz- Lcopy
-
- $POP r14,`2*$SIZE_T`($sp)
- $POP r15,`3*$SIZE_T`($sp)
- $POP r16,`4*$SIZE_T`($sp)
- $POP r17,`5*$SIZE_T`($sp)
- $POP r18,`6*$SIZE_T`($sp)
- $POP r19,`7*$SIZE_T`($sp)
- $POP r20,`8*$SIZE_T`($sp)
- $POP r21,`9*$SIZE_T`($sp)
- $POP r22,`10*$SIZE_T`($sp)
- $POP r23,`11*$SIZE_T`($sp)
- lfd f14,`12*$SIZE_T+0`($sp)
- lfd f15,`12*$SIZE_T+8`($sp)
- lfd f16,`12*$SIZE_T+16`($sp)
- lfd f17,`12*$SIZE_T+24`($sp)
- lfd f18,`12*$SIZE_T+32`($sp)
- lfd f19,`12*$SIZE_T+40`($sp)
- lfd f20,`12*$SIZE_T+48`($sp)
- lfd f21,`12*$SIZE_T+56`($sp)
- lfd f22,`12*$SIZE_T+64`($sp)
- lfd f23,`12*$SIZE_T+72`($sp)
- lfd f24,`12*$SIZE_T+80`($sp)
- lfd f25,`12*$SIZE_T+88`($sp)
- $POP $sp,0($sp)
- li r3,1 ; signal "handled"
- blr
- .long 0
-.asciz "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@fy.chalmers.se>"
-___
-
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/s390x-mont.pl b/crypto/openssl/crypto/bn/asm/s390x-mont.pl
deleted file mode 100755
index d232510..0000000
--- a/crypto/openssl/crypto/bn/asm/s390x-mont.pl
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# April 2007.
-#
-# Performance improvement over vanilla C code varies from 85% to 45%
-# depending on key length and benchmark. Unfortunately in this context
-# these are not very impressive results [for code that utilizes "wide"
-# 64x64=128-bit multiplication, which is not commonly available to C
-# programmers], at least hand-coded bn_asm.c replacement is known to
-# provide 30-40% better results for longest keys. Well, on a second
-# thought it's not very surprising, because z-CPUs are single-issue
-# and _strictly_ in-order execution, while bn_mul_mont is more or less
-# dependent on CPU ability to pipe-line instructions and have several
-# of them "in-flight" at the same time. I mean while other methods,
-# for example Karatsuba, aim to minimize amount of multiplications at
-# the cost of other operations increase, bn_mul_mont aim to neatly
-# "overlap" multiplications and the other operations [and on most
-# platforms even minimize the amount of the other operations, in
-# particular references to memory]. But it's possible to improve this
-# module performance by implementing dedicated squaring code-path and
-# possibly by unrolling loops...
-
-# January 2009.
-#
-# Reschedule to minimize/avoid Address Generation Interlock hazard,
-# make inner loops counter-based.
-
-$mn0="%r0";
-$num="%r1";
-
-# int bn_mul_mont(
-$rp="%r2"; # BN_ULONG *rp,
-$ap="%r3"; # const BN_ULONG *ap,
-$bp="%r4"; # const BN_ULONG *bp,
-$np="%r5"; # const BN_ULONG *np,
-$n0="%r6"; # const BN_ULONG *n0,
-#$num="160(%r15)" # int num);
-
-$bi="%r2"; # zaps rp
-$j="%r7";
-
-$ahi="%r8";
-$alo="%r9";
-$nhi="%r10";
-$nlo="%r11";
-$AHI="%r12";
-$NHI="%r13";
-$count="%r14";
-$sp="%r15";
-
-$code.=<<___;
-.text
-.globl bn_mul_mont
-.type bn_mul_mont,\@function
-bn_mul_mont:
- lgf $num,164($sp) # pull $num
- sla $num,3 # $num to enumerate bytes
- la $bp,0($num,$bp)
-
- stg %r2,16($sp)
-
- cghi $num,16 #
- lghi %r2,0 #
- blr %r14 # if($num<16) return 0;
- cghi $num,128 #
- bhr %r14 # if($num>128) return 0;
-
- stmg %r3,%r15,24($sp)
-
- lghi $rp,-160-8 # leave room for carry bit
- lcgr $j,$num # -$num
- lgr %r0,$sp
- la $rp,0($rp,$sp)
- la $sp,0($j,$rp) # alloca
- stg %r0,0($sp) # back chain
-
- sra $num,3 # restore $num
- la $bp,0($j,$bp) # restore $bp
- ahi $num,-1 # adjust $num for inner loop
- lg $n0,0($n0) # pull n0
-
- lg $bi,0($bp)
- lg $alo,0($ap)
- mlgr $ahi,$bi # ap[0]*bp[0]
- lgr $AHI,$ahi
-
- lgr $mn0,$alo # "tp[0]"*n0
- msgr $mn0,$n0
-
- lg $nlo,0($np) #
- mlgr $nhi,$mn0 # np[0]*m1
- algr $nlo,$alo # +="tp[0]"
- lghi $NHI,0
- alcgr $NHI,$nhi
-
- la $j,8(%r0) # j=1
- lr $count,$num
-
-.align 16
-.L1st:
- lg $alo,0($j,$ap)
- mlgr $ahi,$bi # ap[j]*bp[0]
- algr $alo,$AHI
- lghi $AHI,0
- alcgr $AHI,$ahi
-
- lg $nlo,0($j,$np)
- mlgr $nhi,$mn0 # np[j]*m1
- algr $nlo,$NHI
- lghi $NHI,0
- alcgr $nhi,$NHI # +="tp[j]"
- algr $nlo,$alo
- alcgr $NHI,$nhi
-
- stg $nlo,160-8($j,$sp) # tp[j-1]=
- la $j,8($j) # j++
- brct $count,.L1st
-
- algr $NHI,$AHI
- lghi $AHI,0
- alcgr $AHI,$AHI # upmost overflow bit
- stg $NHI,160-8($j,$sp)
- stg $AHI,160($j,$sp)
- la $bp,8($bp) # bp++
-
-.Louter:
- lg $bi,0($bp) # bp[i]
- lg $alo,0($ap)
- mlgr $ahi,$bi # ap[0]*bp[i]
- alg $alo,160($sp) # +=tp[0]
- lghi $AHI,0
- alcgr $AHI,$ahi
-
- lgr $mn0,$alo
- msgr $mn0,$n0 # tp[0]*n0
-
- lg $nlo,0($np) # np[0]
- mlgr $nhi,$mn0 # np[0]*m1
- algr $nlo,$alo # +="tp[0]"
- lghi $NHI,0
- alcgr $NHI,$nhi
-
- la $j,8(%r0) # j=1
- lr $count,$num
-
-.align 16
-.Linner:
- lg $alo,0($j,$ap)
- mlgr $ahi,$bi # ap[j]*bp[i]
- algr $alo,$AHI
- lghi $AHI,0
- alcgr $ahi,$AHI
- alg $alo,160($j,$sp)# +=tp[j]
- alcgr $AHI,$ahi
-
- lg $nlo,0($j,$np)
- mlgr $nhi,$mn0 # np[j]*m1
- algr $nlo,$NHI
- lghi $NHI,0
- alcgr $nhi,$NHI
- algr $nlo,$alo # +="tp[j]"
- alcgr $NHI,$nhi
-
- stg $nlo,160-8($j,$sp) # tp[j-1]=
- la $j,8($j) # j++
- brct $count,.Linner
-
- algr $NHI,$AHI
- lghi $AHI,0
- alcgr $AHI,$AHI
- alg $NHI,160($j,$sp)# accumulate previous upmost overflow bit
- lghi $ahi,0
- alcgr $AHI,$ahi # new upmost overflow bit
- stg $NHI,160-8($j,$sp)
- stg $AHI,160($j,$sp)
-
- la $bp,8($bp) # bp++
- clg $bp,160+8+32($j,$sp) # compare to &bp[num]
- jne .Louter
-
- lg $rp,160+8+16($j,$sp) # reincarnate rp
- la $ap,160($sp)
- ahi $num,1 # restore $num, incidentally clears "borrow"
-
- la $j,0(%r0)
- lr $count,$num
-.Lsub: lg $alo,0($j,$ap)
- slbg $alo,0($j,$np)
- stg $alo,0($j,$rp)
- la $j,8($j)
- brct $count,.Lsub
- lghi $ahi,0
- slbgr $AHI,$ahi # handle upmost carry
-
- ngr $ap,$AHI
- lghi $np,-1
- xgr $np,$AHI
- ngr $np,$rp
- ogr $ap,$np # ap=borrow?tp:rp
-
- la $j,0(%r0)
- lgr $count,$num
-.Lcopy: lg $alo,0($j,$ap) # copy or in-place refresh
- stg $j,160($j,$sp) # zap tp
- stg $alo,0($j,$rp)
- la $j,8($j)
- brct $count,.Lcopy
-
- la %r1,160+8+48($j,$sp)
- lmg %r6,%r15,0(%r1)
- lghi %r2,1 # signal "processed"
- br %r14
-.size bn_mul_mont,.-bn_mul_mont
-.string "Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
-___
-
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/s390x.S b/crypto/openssl/crypto/bn/asm/s390x.S
deleted file mode 100755
index 8f45f5d..0000000
--- a/crypto/openssl/crypto/bn/asm/s390x.S
+++ /dev/null
@@ -1,678 +0,0 @@
-.ident "s390x.S, version 1.0"
-// ====================================================================
-// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-// project.
-//
-// Rights for redistribution and usage in source and binary forms are
-// granted according to the OpenSSL license. Warranty of any kind is
-// disclaimed.
-// ====================================================================
-
-.text
-
-#define zero %r0
-
-// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
-.globl bn_mul_add_words
-.type bn_mul_add_words,@function
-.align 4
-bn_mul_add_words:
- lghi zero,0 // zero = 0
- la %r1,0(%r2) // put rp aside
- lghi %r2,0 // i=0;
- ltgfr %r4,%r4
- bler %r14 // if (len<=0) return 0;
-
- stmg %r6,%r10,48(%r15)
- lghi %r8,0 // carry = 0
- srag %r10,%r4,2 // cnt=len/4
- jz .Loop1_madd
-
-.Loop4_madd:
- lg %r7,0(%r2,%r3) // ap[i]
- mlgr %r6,%r5 // *=w
- algr %r7,%r8 // +=carry
- alcgr %r6,zero
- alg %r7,0(%r2,%r1) // +=rp[i]
- alcgr %r6,zero
- stg %r7,0(%r2,%r1) // rp[i]=
-
- lg %r9,8(%r2,%r3)
- mlgr %r8,%r5
- algr %r9,%r6
- alcgr %r8,zero
- alg %r9,8(%r2,%r1)
- alcgr %r8,zero
- stg %r9,8(%r2,%r1)
-
- lg %r7,16(%r2,%r3)
- mlgr %r6,%r5
- algr %r7,%r8
- alcgr %r6,zero
- alg %r7,16(%r2,%r1)
- alcgr %r6,zero
- stg %r7,16(%r2,%r1)
-
- lg %r9,24(%r2,%r3)
- mlgr %r8,%r5
- algr %r9,%r6
- alcgr %r8,zero
- alg %r9,24(%r2,%r1)
- alcgr %r8,zero
- stg %r9,24(%r2,%r1)
-
- la %r2,32(%r2) // i+=4
- brct %r10,.Loop4_madd
-
- lghi %r10,3
- nr %r4,%r10 // cnt=len%4
- jz .Lend_madd
-
-.Loop1_madd:
- lg %r7,0(%r2,%r3) // ap[i]
- mlgr %r6,%r5 // *=w
- algr %r7,%r8 // +=carry
- alcgr %r6,zero
- alg %r7,0(%r2,%r1) // +=rp[i]
- alcgr %r6,zero
- stg %r7,0(%r2,%r1) // rp[i]=
-
- lgr %r8,%r6
- la %r2,8(%r2) // i++
- brct %r4,.Loop1_madd
-
-.Lend_madd:
- lgr %r2,%r8
- lmg %r6,%r10,48(%r15)
- br %r14
-.size bn_mul_add_words,.-bn_mul_add_words
-
-// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
-.globl bn_mul_words
-.type bn_mul_words,@function
-.align 4
-bn_mul_words:
- lghi zero,0 // zero = 0
- la %r1,0(%r2) // put rp aside
- lghi %r2,0 // i=0;
- ltgfr %r4,%r4
- bler %r14 // if (len<=0) return 0;
-
- stmg %r6,%r10,48(%r15)
- lghi %r8,0 // carry = 0
- srag %r10,%r4,2 // cnt=len/4
- jz .Loop1_mul
-
-.Loop4_mul:
- lg %r7,0(%r2,%r3) // ap[i]
- mlgr %r6,%r5 // *=w
- algr %r7,%r8 // +=carry
- alcgr %r6,zero
- stg %r7,0(%r2,%r1) // rp[i]=
-
- lg %r9,8(%r2,%r3)
- mlgr %r8,%r5
- algr %r9,%r6
- alcgr %r8,zero
- stg %r9,8(%r2,%r1)
-
- lg %r7,16(%r2,%r3)
- mlgr %r6,%r5
- algr %r7,%r8
- alcgr %r6,zero
- stg %r7,16(%r2,%r1)
-
- lg %r9,24(%r2,%r3)
- mlgr %r8,%r5
- algr %r9,%r6
- alcgr %r8,zero
- stg %r9,24(%r2,%r1)
-
- la %r2,32(%r2) // i+=4
- brct %r10,.Loop4_mul
-
- lghi %r10,3
- nr %r4,%r10 // cnt=len%4
- jz .Lend_mul
-
-.Loop1_mul:
- lg %r7,0(%r2,%r3) // ap[i]
- mlgr %r6,%r5 // *=w
- algr %r7,%r8 // +=carry
- alcgr %r6,zero
- stg %r7,0(%r2,%r1) // rp[i]=
-
- lgr %r8,%r6
- la %r2,8(%r2) // i++
- brct %r4,.Loop1_mul
-
-.Lend_mul:
- lgr %r2,%r8
- lmg %r6,%r10,48(%r15)
- br %r14
-.size bn_mul_words,.-bn_mul_words
-
-// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
-.globl bn_sqr_words
-.type bn_sqr_words,@function
-.align 4
-bn_sqr_words:
- ltgfr %r4,%r4
- bler %r14
-
- stmg %r6,%r7,48(%r15)
- srag %r1,%r4,2 // cnt=len/4
- jz .Loop1_sqr
-
-.Loop4_sqr:
- lg %r7,0(%r3)
- mlgr %r6,%r7
- stg %r7,0(%r2)
- stg %r6,8(%r2)
-
- lg %r7,8(%r3)
- mlgr %r6,%r7
- stg %r7,16(%r2)
- stg %r6,24(%r2)
-
- lg %r7,16(%r3)
- mlgr %r6,%r7
- stg %r7,32(%r2)
- stg %r6,40(%r2)
-
- lg %r7,24(%r3)
- mlgr %r6,%r7
- stg %r7,48(%r2)
- stg %r6,56(%r2)
-
- la %r3,32(%r3)
- la %r2,64(%r2)
- brct %r1,.Loop4_sqr
-
- lghi %r1,3
- nr %r4,%r1 // cnt=len%4
- jz .Lend_sqr
-
-.Loop1_sqr:
- lg %r7,0(%r3)
- mlgr %r6,%r7
- stg %r7,0(%r2)
- stg %r6,8(%r2)
-
- la %r3,8(%r3)
- la %r2,16(%r2)
- brct %r4,.Loop1_sqr
-
-.Lend_sqr:
- lmg %r6,%r7,48(%r15)
- br %r14
-.size bn_sqr_words,.-bn_sqr_words
-
-// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
-.globl bn_div_words
-.type bn_div_words,@function
-.align 4
-bn_div_words:
- dlgr %r2,%r4
- lgr %r2,%r3
- br %r14
-.size bn_div_words,.-bn_div_words
-
-// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
-.globl bn_add_words
-.type bn_add_words,@function
-.align 4
-bn_add_words:
- la %r1,0(%r2) // put rp aside
- lghi %r2,0 // i=0
- ltgfr %r5,%r5
- bler %r14 // if (len<=0) return 0;
-
- stg %r6,48(%r15)
- lghi %r6,3
- nr %r6,%r5 // len%4
- sra %r5,2 // len/4, use sra because it sets condition code
- jz .Loop1_add // carry is incidentally cleared if branch taken
- algr %r2,%r2 // clear carry
-
-.Loop4_add:
- lg %r0,0(%r2,%r3)
- alcg %r0,0(%r2,%r4)
- stg %r0,0(%r2,%r1)
- lg %r0,8(%r2,%r3)
- alcg %r0,8(%r2,%r4)
- stg %r0,8(%r2,%r1)
- lg %r0,16(%r2,%r3)
- alcg %r0,16(%r2,%r4)
- stg %r0,16(%r2,%r1)
- lg %r0,24(%r2,%r3)
- alcg %r0,24(%r2,%r4)
- stg %r0,24(%r2,%r1)
-
- la %r2,32(%r2) // i+=4
- brct %r5,.Loop4_add
-
- la %r6,1(%r6) // see if len%4 is zero ...
- brct %r6,.Loop1_add // without touching condition code:-)
-
-.Lexit_add:
- lghi %r2,0
- alcgr %r2,%r2
- lg %r6,48(%r15)
- br %r14
-
-.Loop1_add:
- lg %r0,0(%r2,%r3)
- alcg %r0,0(%r2,%r4)
- stg %r0,0(%r2,%r1)
-
- la %r2,8(%r2) // i++
- brct %r6,.Loop1_add
-
- j .Lexit_add
-.size bn_add_words,.-bn_add_words
-
-// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
-.globl bn_sub_words
-.type bn_sub_words,@function
-.align 4
-bn_sub_words:
- la %r1,0(%r2) // put rp aside
- lghi %r2,0 // i=0
- ltgfr %r5,%r5
- bler %r14 // if (len<=0) return 0;
-
- stg %r6,48(%r15)
- lghi %r6,3
- nr %r6,%r5 // len%4
- sra %r5,2 // len/4, use sra because it sets condition code
- jnz .Loop4_sub // borrow is incidentally cleared if branch taken
- slgr %r2,%r2 // clear borrow
-
-.Loop1_sub:
- lg %r0,0(%r2,%r3)
- slbg %r0,0(%r2,%r4)
- stg %r0,0(%r2,%r1)
-
- la %r2,8(%r2) // i++
- brct %r6,.Loop1_sub
- j .Lexit_sub
-
-.Loop4_sub:
- lg %r0,0(%r2,%r3)
- slbg %r0,0(%r2,%r4)
- stg %r0,0(%r2,%r1)
- lg %r0,8(%r2,%r3)
- slbg %r0,8(%r2,%r4)
- stg %r0,8(%r2,%r1)
- lg %r0,16(%r2,%r3)
- slbg %r0,16(%r2,%r4)
- stg %r0,16(%r2,%r1)
- lg %r0,24(%r2,%r3)
- slbg %r0,24(%r2,%r4)
- stg %r0,24(%r2,%r1)
-
- la %r2,32(%r2) // i+=4
- brct %r5,.Loop4_sub
-
- la %r6,1(%r6) // see if len%4 is zero ...
- brct %r6,.Loop1_sub // without touching condition code:-)
-
-.Lexit_sub:
- lghi %r2,0
- slbgr %r2,%r2
- lcgr %r2,%r2
- lg %r6,48(%r15)
- br %r14
-.size bn_sub_words,.-bn_sub_words
-
-#define c1 %r1
-#define c2 %r5
-#define c3 %r8
-
-#define mul_add_c(ai,bi,c1,c2,c3) \
- lg %r7,ai*8(%r3); \
- mlg %r6,bi*8(%r4); \
- algr c1,%r7; \
- alcgr c2,%r6; \
- alcgr c3,zero
-
-// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
-.globl bn_mul_comba8
-.type bn_mul_comba8,@function
-.align 4
-bn_mul_comba8:
- stmg %r6,%r8,48(%r15)
-
- lghi c1,0
- lghi c2,0
- lghi c3,0
- lghi zero,0
-
- mul_add_c(0,0,c1,c2,c3);
- stg c1,0*8(%r2)
- lghi c1,0
-
- mul_add_c(0,1,c2,c3,c1);
- mul_add_c(1,0,c2,c3,c1);
- stg c2,1*8(%r2)
- lghi c2,0
-
- mul_add_c(2,0,c3,c1,c2);
- mul_add_c(1,1,c3,c1,c2);
- mul_add_c(0,2,c3,c1,c2);
- stg c3,2*8(%r2)
- lghi c3,0
-
- mul_add_c(0,3,c1,c2,c3);
- mul_add_c(1,2,c1,c2,c3);
- mul_add_c(2,1,c1,c2,c3);
- mul_add_c(3,0,c1,c2,c3);
- stg c1,3*8(%r2)
- lghi c1,0
-
- mul_add_c(4,0,c2,c3,c1);
- mul_add_c(3,1,c2,c3,c1);
- mul_add_c(2,2,c2,c3,c1);
- mul_add_c(1,3,c2,c3,c1);
- mul_add_c(0,4,c2,c3,c1);
- stg c2,4*8(%r2)
- lghi c2,0
-
- mul_add_c(0,5,c3,c1,c2);
- mul_add_c(1,4,c3,c1,c2);
- mul_add_c(2,3,c3,c1,c2);
- mul_add_c(3,2,c3,c1,c2);
- mul_add_c(4,1,c3,c1,c2);
- mul_add_c(5,0,c3,c1,c2);
- stg c3,5*8(%r2)
- lghi c3,0
-
- mul_add_c(6,0,c1,c2,c3);
- mul_add_c(5,1,c1,c2,c3);
- mul_add_c(4,2,c1,c2,c3);
- mul_add_c(3,3,c1,c2,c3);
- mul_add_c(2,4,c1,c2,c3);
- mul_add_c(1,5,c1,c2,c3);
- mul_add_c(0,6,c1,c2,c3);
- stg c1,6*8(%r2)
- lghi c1,0
-
- mul_add_c(0,7,c2,c3,c1);
- mul_add_c(1,6,c2,c3,c1);
- mul_add_c(2,5,c2,c3,c1);
- mul_add_c(3,4,c2,c3,c1);
- mul_add_c(4,3,c2,c3,c1);
- mul_add_c(5,2,c2,c3,c1);
- mul_add_c(6,1,c2,c3,c1);
- mul_add_c(7,0,c2,c3,c1);
- stg c2,7*8(%r2)
- lghi c2,0
-
- mul_add_c(7,1,c3,c1,c2);
- mul_add_c(6,2,c3,c1,c2);
- mul_add_c(5,3,c3,c1,c2);
- mul_add_c(4,4,c3,c1,c2);
- mul_add_c(3,5,c3,c1,c2);
- mul_add_c(2,6,c3,c1,c2);
- mul_add_c(1,7,c3,c1,c2);
- stg c3,8*8(%r2)
- lghi c3,0
-
- mul_add_c(2,7,c1,c2,c3);
- mul_add_c(3,6,c1,c2,c3);
- mul_add_c(4,5,c1,c2,c3);
- mul_add_c(5,4,c1,c2,c3);
- mul_add_c(6,3,c1,c2,c3);
- mul_add_c(7,2,c1,c2,c3);
- stg c1,9*8(%r2)
- lghi c1,0
-
- mul_add_c(7,3,c2,c3,c1);
- mul_add_c(6,4,c2,c3,c1);
- mul_add_c(5,5,c2,c3,c1);
- mul_add_c(4,6,c2,c3,c1);
- mul_add_c(3,7,c2,c3,c1);
- stg c2,10*8(%r2)
- lghi c2,0
-
- mul_add_c(4,7,c3,c1,c2);
- mul_add_c(5,6,c3,c1,c2);
- mul_add_c(6,5,c3,c1,c2);
- mul_add_c(7,4,c3,c1,c2);
- stg c3,11*8(%r2)
- lghi c3,0
-
- mul_add_c(7,5,c1,c2,c3);
- mul_add_c(6,6,c1,c2,c3);
- mul_add_c(5,7,c1,c2,c3);
- stg c1,12*8(%r2)
- lghi c1,0
-
-
- mul_add_c(6,7,c2,c3,c1);
- mul_add_c(7,6,c2,c3,c1);
- stg c2,13*8(%r2)
- lghi c2,0
-
- mul_add_c(7,7,c3,c1,c2);
- stg c3,14*8(%r2)
- stg c1,15*8(%r2)
-
- lmg %r6,%r8,48(%r15)
- br %r14
-.size bn_mul_comba8,.-bn_mul_comba8
-
-// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
-.globl bn_mul_comba4
-.type bn_mul_comba4,@function
-.align 4
-bn_mul_comba4:
- stmg %r6,%r8,48(%r15)
-
- lghi c1,0
- lghi c2,0
- lghi c3,0
- lghi zero,0
-
- mul_add_c(0,0,c1,c2,c3);
- stg c1,0*8(%r3)
- lghi c1,0
-
- mul_add_c(0,1,c2,c3,c1);
- mul_add_c(1,0,c2,c3,c1);
- stg c2,1*8(%r2)
- lghi c2,0
-
- mul_add_c(2,0,c3,c1,c2);
- mul_add_c(1,1,c3,c1,c2);
- mul_add_c(0,2,c3,c1,c2);
- stg c3,2*8(%r2)
- lghi c3,0
-
- mul_add_c(0,3,c1,c2,c3);
- mul_add_c(1,2,c1,c2,c3);
- mul_add_c(2,1,c1,c2,c3);
- mul_add_c(3,0,c1,c2,c3);
- stg c1,3*8(%r2)
- lghi c1,0
-
- mul_add_c(3,1,c2,c3,c1);
- mul_add_c(2,2,c2,c3,c1);
- mul_add_c(1,3,c2,c3,c1);
- stg c2,4*8(%r2)
- lghi c2,0
-
- mul_add_c(2,3,c3,c1,c2);
- mul_add_c(3,2,c3,c1,c2);
- stg c3,5*8(%r2)
- lghi c3,0
-
- mul_add_c(3,3,c1,c2,c3);
- stg c1,6*8(%r2)
- stg c2,7*8(%r2)
-
- stmg %r6,%r8,48(%r15)
- br %r14
-.size bn_mul_comba4,.-bn_mul_comba4
-
-#define sqr_add_c(ai,c1,c2,c3) \
- lg %r7,ai*8(%r3); \
- mlgr %r6,%r7; \
- algr c1,%r7; \
- alcgr c2,%r6; \
- alcgr c3,zero
-
-#define sqr_add_c2(ai,aj,c1,c2,c3) \
- lg %r7,ai*8(%r3); \
- mlg %r6,aj*8(%r3); \
- algr c1,%r7; \
- alcgr c2,%r6; \
- alcgr c3,zero; \
- algr c1,%r7; \
- alcgr c2,%r6; \
- alcgr c3,zero
-
-// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
-.globl bn_sqr_comba8
-.type bn_sqr_comba8,@function
-.align 4
-bn_sqr_comba8:
- stmg %r6,%r8,48(%r15)
-
- lghi c1,0
- lghi c2,0
- lghi c3,0
- lghi zero,0
-
- sqr_add_c(0,c1,c2,c3);
- stg c1,0*8(%r2)
- lghi c1,0
-
- sqr_add_c2(1,0,c2,c3,c1);
- stg c2,1*8(%r2)
- lghi c2,0
-
- sqr_add_c(1,c3,c1,c2);
- sqr_add_c2(2,0,c3,c1,c2);
- stg c3,2*8(%r2)
- lghi c3,0
-
- sqr_add_c2(3,0,c1,c2,c3);
- sqr_add_c2(2,1,c1,c2,c3);
- stg c1,3*8(%r2)
- lghi c1,0
-
- sqr_add_c(2,c2,c3,c1);
- sqr_add_c2(3,1,c2,c3,c1);
- sqr_add_c2(4,0,c2,c3,c1);
- stg c2,4*8(%r2)
- lghi c2,0
-
- sqr_add_c2(5,0,c3,c1,c2);
- sqr_add_c2(4,1,c3,c1,c2);
- sqr_add_c2(3,2,c3,c1,c2);
- stg c3,5*8(%r2)
- lghi c3,0
-
- sqr_add_c(3,c1,c2,c3);
- sqr_add_c2(4,2,c1,c2,c3);
- sqr_add_c2(5,1,c1,c2,c3);
- sqr_add_c2(6,0,c1,c2,c3);
- stg c1,6*8(%r2)
- lghi c1,0
-
- sqr_add_c2(7,0,c2,c3,c1);
- sqr_add_c2(6,1,c2,c3,c1);
- sqr_add_c2(5,2,c2,c3,c1);
- sqr_add_c2(4,3,c2,c3,c1);
- stg c2,7*8(%r2)
- lghi c2,0
-
- sqr_add_c(4,c3,c1,c2);
- sqr_add_c2(5,3,c3,c1,c2);
- sqr_add_c2(6,2,c3,c1,c2);
- sqr_add_c2(7,1,c3,c1,c2);
- stg c3,8*8(%r2)
- lghi c3,0
-
- sqr_add_c2(7,2,c1,c2,c3);
- sqr_add_c2(6,3,c1,c2,c3);
- sqr_add_c2(5,4,c1,c2,c3);
- stg c1,9*8(%r2)
- lghi c1,0
-
- sqr_add_c(5,c2,c3,c1);
- sqr_add_c2(6,4,c2,c3,c1);
- sqr_add_c2(7,3,c2,c3,c1);
- stg c2,10*8(%r2)
- lghi c2,0
-
- sqr_add_c2(7,4,c3,c1,c2);
- sqr_add_c2(6,5,c3,c1,c2);
- stg c3,11*8(%r2)
- lghi c3,0
-
- sqr_add_c(6,c1,c2,c3);
- sqr_add_c2(7,5,c1,c2,c3);
- stg c1,12*8(%r2)
- lghi c1,0
-
- sqr_add_c2(7,6,c2,c3,c1);
- stg c2,13*8(%r2)
- lghi c2,0
-
- sqr_add_c(7,c3,c1,c2);
- stg c3,14*8(%r2)
- stg c1,15*8(%r2)
-
- lmg %r6,%r8,48(%r15)
- br %r14
-.size bn_sqr_comba8,.-bn_sqr_comba8
-
-// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
-.globl bn_sqr_comba4
-.type bn_sqr_comba4,@function
-.align 4
-bn_sqr_comba4:
- stmg %r6,%r8,48(%r15)
-
- lghi c1,0
- lghi c2,0
- lghi c3,0
- lghi zero,0
-
- sqr_add_c(0,c1,c2,c3);
- stg c1,0*8(%r2)
- lghi c1,0
-
- sqr_add_c2(1,0,c2,c3,c1);
- stg c2,1*8(%r2)
- lghi c2,0
-
- sqr_add_c(1,c3,c1,c2);
- sqr_add_c2(2,0,c3,c1,c2);
- stg c3,2*8(%r2)
- lghi c3,0
-
- sqr_add_c2(3,0,c1,c2,c3);
- sqr_add_c2(2,1,c1,c2,c3);
- stg c1,3*8(%r2)
- lghi c1,0
-
- sqr_add_c(2,c2,c3,c1);
- sqr_add_c2(3,1,c2,c3,c1);
- stg c2,4*8(%r2)
- lghi c2,0
-
- sqr_add_c2(3,2,c3,c1,c2);
- stg c3,5*8(%r2)
- lghi c3,0
-
- sqr_add_c(3,c1,c2,c3);
- stg c1,6*8(%r2)
- stg c2,7*8(%r2)
-
- lmg %r6,%r8,48(%r15)
- br %r14
-.size bn_sqr_comba4,.-bn_sqr_comba4
diff --git a/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl b/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl
deleted file mode 100755
index b8fb1e8..0000000
--- a/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl
+++ /dev/null
@@ -1,606 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# December 2005
-#
-# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
-# for undertaken effort are multiple. First of all, UltraSPARC is not
-# the whole SPARCv9 universe and other VIS-free implementations deserve
-# optimized code as much. Secondly, newly introduced UltraSPARC T1,
-# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes,
-# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
-# several integrated RSA/DSA accelerator circuits accessible through
-# kernel driver [only(*)], but having decent user-land software
-# implementation is important too. Finally, reasons like desire to
-# experiment with dedicated squaring procedure. Yes, this module
-# implements one, because it was easiest to draft it in SPARCv9
-# instructions...
-
-# (*) Engine accessing the driver in question is on my TODO list.
-# For reference, acceleator is estimated to give 6 to 10 times
-# improvement on single-threaded RSA sign. It should be noted
-# that 6-10x improvement coefficient does not actually mean
-# something extraordinary in terms of absolute [single-threaded]
-# performance, as SPARCv9 instruction set is by all means least
-# suitable for high performance crypto among other 64 bit
-# platforms. 6-10x factor simply places T1 in same performance
-# domain as say AMD64 and IA-64. Improvement of RSA verify don't
-# appear impressive at all, but it's the sign operation which is
-# far more critical/interesting.
-
-# You might notice that inner loops are modulo-scheduled:-) This has
-# essentially negligible impact on UltraSPARC performance, it's
-# Fujitsu SPARC64 V users who should notice and hopefully appreciate
-# the advantage... Currently this module surpasses sparcv9a-mont.pl
-# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
-# module still have hidden potential [see TODO list there], which is
-# estimated to be larger than 20%...
-
-# int bn_mul_mont(
-$rp="%i0"; # BN_ULONG *rp,
-$ap="%i1"; # const BN_ULONG *ap,
-$bp="%i2"; # const BN_ULONG *bp,
-$np="%i3"; # const BN_ULONG *np,
-$n0="%i4"; # const BN_ULONG *n0,
-$num="%i5"; # int num);
-
-$bits=32;
-for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-if ($bits==64) { $bias=2047; $frame=192; }
-else { $bias=0; $frame=128; }
-
-$car0="%o0";
-$car1="%o1";
-$car2="%o2"; # 1 bit
-$acc0="%o3";
-$acc1="%o4";
-$mask="%g1"; # 32 bits, what a waste...
-$tmp0="%g4";
-$tmp1="%g5";
-
-$i="%l0";
-$j="%l1";
-$mul0="%l2";
-$mul1="%l3";
-$tp="%l4";
-$apj="%l5";
-$npj="%l6";
-$tpj="%l7";
-
-$fname="bn_mul_mont_int";
-
-$code=<<___;
-.section ".text",#alloc,#execinstr
-
-.global $fname
-.align 32
-$fname:
- cmp %o5,4 ! 128 bits minimum
- bge,pt %icc,.Lenter
- sethi %hi(0xffffffff),$mask
- retl
- clr %o0
-.align 32
-.Lenter:
- save %sp,-$frame,%sp
- sll $num,2,$num ! num*=4
- or $mask,%lo(0xffffffff),$mask
- ld [$n0],$n0
- cmp $ap,$bp
- and $num,$mask,$num
- ld [$bp],$mul0 ! bp[0]
- nop
-
- add %sp,$bias,%o7 ! real top of stack
- ld [$ap],$car0 ! ap[0] ! redundant in squaring context
- sub %o7,$num,%o7
- ld [$ap+4],$apj ! ap[1]
- and %o7,-1024,%o7
- ld [$np],$car1 ! np[0]
- sub %o7,$bias,%sp ! alloca
- ld [$np+4],$npj ! np[1]
- be,pt `$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont
- mov 12,$j
-
- mulx $car0,$mul0,$car0 ! ap[0]*bp[0]
- mulx $apj,$mul0,$tmp0 !prologue! ap[1]*bp[0]
- and $car0,$mask,$acc0
- add %sp,$bias+$frame,$tp
- ld [$ap+8],$apj !prologue!
-
- mulx $n0,$acc0,$mul1 ! "t[0]"*n0
- and $mul1,$mask,$mul1
-
- mulx $car1,$mul1,$car1 ! np[0]*"t[0]"*n0
- mulx $npj,$mul1,$acc1 !prologue! np[1]*"t[0]"*n0
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- ld [$np+8],$npj !prologue!
- srlx $car1,32,$car1
- mov $tmp0,$acc0 !prologue!
-
-.L1st:
- mulx $apj,$mul0,$tmp0
- mulx $npj,$mul1,$tmp1
- add $acc0,$car0,$car0
- ld [$ap+$j],$apj ! ap[j]
- and $car0,$mask,$acc0
- add $acc1,$car1,$car1
- ld [$np+$j],$npj ! np[j]
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- add $j,4,$j ! j++
- mov $tmp0,$acc0
- st $car1,[$tp]
- cmp $j,$num
- mov $tmp1,$acc1
- srlx $car1,32,$car1
- bl %icc,.L1st
- add $tp,4,$tp ! tp++
-!.L1st
-
- mulx $apj,$mul0,$tmp0 !epilogue!
- mulx $npj,$mul1,$tmp1
- add $acc0,$car0,$car0
- and $car0,$mask,$acc0
- add $acc1,$car1,$car1
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- st $car1,[$tp]
- srlx $car1,32,$car1
-
- add $tmp0,$car0,$car0
- and $car0,$mask,$acc0
- add $tmp1,$car1,$car1
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- st $car1,[$tp+4]
- srlx $car1,32,$car1
-
- add $car0,$car1,$car1
- st $car1,[$tp+8]
- srlx $car1,32,$car2
-
- mov 4,$i ! i++
- ld [$bp+4],$mul0 ! bp[1]
-.Louter:
- add %sp,$bias+$frame,$tp
- ld [$ap],$car0 ! ap[0]
- ld [$ap+4],$apj ! ap[1]
- ld [$np],$car1 ! np[0]
- ld [$np+4],$npj ! np[1]
- ld [$tp],$tmp1 ! tp[0]
- ld [$tp+4],$tpj ! tp[1]
- mov 12,$j
-
- mulx $car0,$mul0,$car0
- mulx $apj,$mul0,$tmp0 !prologue!
- add $tmp1,$car0,$car0
- ld [$ap+8],$apj !prologue!
- and $car0,$mask,$acc0
-
- mulx $n0,$acc0,$mul1
- and $mul1,$mask,$mul1
-
- mulx $car1,$mul1,$car1
- mulx $npj,$mul1,$acc1 !prologue!
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- ld [$np+8],$npj !prologue!
- srlx $car1,32,$car1
- mov $tmp0,$acc0 !prologue!
-
-.Linner:
- mulx $apj,$mul0,$tmp0
- mulx $npj,$mul1,$tmp1
- add $tpj,$car0,$car0
- ld [$ap+$j],$apj ! ap[j]
- add $acc0,$car0,$car0
- add $acc1,$car1,$car1
- ld [$np+$j],$npj ! np[j]
- and $car0,$mask,$acc0
- ld [$tp+8],$tpj ! tp[j]
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- add $j,4,$j ! j++
- mov $tmp0,$acc0
- st $car1,[$tp] ! tp[j-1]
- srlx $car1,32,$car1
- mov $tmp1,$acc1
- cmp $j,$num
- bl %icc,.Linner
- add $tp,4,$tp ! tp++
-!.Linner
-
- mulx $apj,$mul0,$tmp0 !epilogue!
- mulx $npj,$mul1,$tmp1
- add $tpj,$car0,$car0
- add $acc0,$car0,$car0
- ld [$tp+8],$tpj ! tp[j]
- and $car0,$mask,$acc0
- add $acc1,$car1,$car1
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- st $car1,[$tp] ! tp[j-1]
- srlx $car1,32,$car1
-
- add $tpj,$car0,$car0
- add $tmp0,$car0,$car0
- and $car0,$mask,$acc0
- add $tmp1,$car1,$car1
- add $acc0,$car1,$car1
- st $car1,[$tp+4] ! tp[j-1]
- srlx $car0,32,$car0
- add $i,4,$i ! i++
- srlx $car1,32,$car1
-
- add $car0,$car1,$car1
- cmp $i,$num
- add $car2,$car1,$car1
- st $car1,[$tp+8]
-
- srlx $car1,32,$car2
- bl,a %icc,.Louter
- ld [$bp+$i],$mul0 ! bp[i]
-!.Louter
-
- add $tp,12,$tp
-
-.Ltail:
- add $np,$num,$np
- add $rp,$num,$rp
- mov $tp,$ap
- sub %g0,$num,%o7 ! k=-num
- ba .Lsub
- subcc %g0,%g0,%g0 ! clear %icc.c
-.align 16
-.Lsub:
- ld [$tp+%o7],%o0
- ld [$np+%o7],%o1
- subccc %o0,%o1,%o1 ! tp[j]-np[j]
- add $rp,%o7,$i
- add %o7,4,%o7
- brnz %o7,.Lsub
- st %o1,[$i]
- subc $car2,0,$car2 ! handle upmost overflow bit
- and $tp,$car2,$ap
- andn $rp,$car2,$np
- or $ap,$np,$ap
- sub %g0,$num,%o7
-
-.Lcopy:
- ld [$ap+%o7],%o0 ! copy or in-place refresh
- st %g0,[$tp+%o7] ! zap tp
- st %o0,[$rp+%o7]
- add %o7,4,%o7
- brnz %o7,.Lcopy
- nop
- mov 1,%i0
- ret
- restore
-___
-
-########
-######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
-######## code without following dedicated squaring procedure.
-########
-$sbit="%i2"; # re-use $bp!
-
-$code.=<<___;
-.align 32
-.Lbn_sqr_mont:
- mulx $mul0,$mul0,$car0 ! ap[0]*ap[0]
- mulx $apj,$mul0,$tmp0 !prologue!
- and $car0,$mask,$acc0
- add %sp,$bias+$frame,$tp
- ld [$ap+8],$apj !prologue!
-
- mulx $n0,$acc0,$mul1 ! "t[0]"*n0
- srlx $car0,32,$car0
- and $mul1,$mask,$mul1
-
- mulx $car1,$mul1,$car1 ! np[0]*"t[0]"*n0
- mulx $npj,$mul1,$acc1 !prologue!
- and $car0,1,$sbit
- ld [$np+8],$npj !prologue!
- srlx $car0,1,$car0
- add $acc0,$car1,$car1
- srlx $car1,32,$car1
- mov $tmp0,$acc0 !prologue!
-
-.Lsqr_1st:
- mulx $apj,$mul0,$tmp0
- mulx $npj,$mul1,$tmp1
- add $acc0,$car0,$car0 ! ap[j]*a0+c0
- add $acc1,$car1,$car1
- ld [$ap+$j],$apj ! ap[j]
- and $car0,$mask,$acc0
- ld [$np+$j],$npj ! np[j]
- srlx $car0,32,$car0
- add $acc0,$acc0,$acc0
- or $sbit,$acc0,$acc0
- mov $tmp1,$acc1
- srlx $acc0,32,$sbit
- add $j,4,$j ! j++
- and $acc0,$mask,$acc0
- cmp $j,$num
- add $acc0,$car1,$car1
- st $car1,[$tp]
- mov $tmp0,$acc0
- srlx $car1,32,$car1
- bl %icc,.Lsqr_1st
- add $tp,4,$tp ! tp++
-!.Lsqr_1st
-
- mulx $apj,$mul0,$tmp0 ! epilogue
- mulx $npj,$mul1,$tmp1
- add $acc0,$car0,$car0 ! ap[j]*a0+c0
- add $acc1,$car1,$car1
- and $car0,$mask,$acc0
- srlx $car0,32,$car0
- add $acc0,$acc0,$acc0
- or $sbit,$acc0,$acc0
- srlx $acc0,32,$sbit
- and $acc0,$mask,$acc0
- add $acc0,$car1,$car1
- st $car1,[$tp]
- srlx $car1,32,$car1
-
- add $tmp0,$car0,$car0 ! ap[j]*a0+c0
- add $tmp1,$car1,$car1
- and $car0,$mask,$acc0
- srlx $car0,32,$car0
- add $acc0,$acc0,$acc0
- or $sbit,$acc0,$acc0
- srlx $acc0,32,$sbit
- and $acc0,$mask,$acc0
- add $acc0,$car1,$car1
- st $car1,[$tp+4]
- srlx $car1,32,$car1
-
- add $car0,$car0,$car0
- or $sbit,$car0,$car0
- add $car0,$car1,$car1
- st $car1,[$tp+8]
- srlx $car1,32,$car2
-
- ld [%sp+$bias+$frame],$tmp0 ! tp[0]
- ld [%sp+$bias+$frame+4],$tmp1 ! tp[1]
- ld [%sp+$bias+$frame+8],$tpj ! tp[2]
- ld [$ap+4],$mul0 ! ap[1]
- ld [$ap+8],$apj ! ap[2]
- ld [$np],$car1 ! np[0]
- ld [$np+4],$npj ! np[1]
- mulx $n0,$tmp0,$mul1
-
- mulx $mul0,$mul0,$car0
- and $mul1,$mask,$mul1
-
- mulx $car1,$mul1,$car1
- mulx $npj,$mul1,$acc1
- add $tmp0,$car1,$car1
- and $car0,$mask,$acc0
- ld [$np+8],$npj ! np[2]
- srlx $car1,32,$car1
- add $tmp1,$car1,$car1
- srlx $car0,32,$car0
- add $acc0,$car1,$car1
- and $car0,1,$sbit
- add $acc1,$car1,$car1
- srlx $car0,1,$car0
- mov 12,$j
- st $car1,[%sp+$bias+$frame] ! tp[0]=
- srlx $car1,32,$car1
- add %sp,$bias+$frame+4,$tp
-
-.Lsqr_2nd:
- mulx $apj,$mul0,$acc0
- mulx $npj,$mul1,$acc1
- add $acc0,$car0,$car0
- add $tpj,$car1,$car1
- ld [$ap+$j],$apj ! ap[j]
- and $car0,$mask,$acc0
- ld [$np+$j],$npj ! np[j]
- srlx $car0,32,$car0
- add $acc1,$car1,$car1
- ld [$tp+8],$tpj ! tp[j]
- add $acc0,$acc0,$acc0
- add $j,4,$j ! j++
- or $sbit,$acc0,$acc0
- srlx $acc0,32,$sbit
- and $acc0,$mask,$acc0
- cmp $j,$num
- add $acc0,$car1,$car1
- st $car1,[$tp] ! tp[j-1]
- srlx $car1,32,$car1
- bl %icc,.Lsqr_2nd
- add $tp,4,$tp ! tp++
-!.Lsqr_2nd
-
- mulx $apj,$mul0,$acc0
- mulx $npj,$mul1,$acc1
- add $acc0,$car0,$car0
- add $tpj,$car1,$car1
- and $car0,$mask,$acc0
- srlx $car0,32,$car0
- add $acc1,$car1,$car1
- add $acc0,$acc0,$acc0
- or $sbit,$acc0,$acc0
- srlx $acc0,32,$sbit
- and $acc0,$mask,$acc0
- add $acc0,$car1,$car1
- st $car1,[$tp] ! tp[j-1]
- srlx $car1,32,$car1
-
- add $car0,$car0,$car0
- or $sbit,$car0,$car0
- add $car0,$car1,$car1
- add $car2,$car1,$car1
- st $car1,[$tp+4]
- srlx $car1,32,$car2
-
- ld [%sp+$bias+$frame],$tmp1 ! tp[0]
- ld [%sp+$bias+$frame+4],$tpj ! tp[1]
- ld [$ap+8],$mul0 ! ap[2]
- ld [$np],$car1 ! np[0]
- ld [$np+4],$npj ! np[1]
- mulx $n0,$tmp1,$mul1
- and $mul1,$mask,$mul1
- mov 8,$i
-
- mulx $mul0,$mul0,$car0
- mulx $car1,$mul1,$car1
- and $car0,$mask,$acc0
- add $tmp1,$car1,$car1
- srlx $car0,32,$car0
- add %sp,$bias+$frame,$tp
- srlx $car1,32,$car1
- and $car0,1,$sbit
- srlx $car0,1,$car0
- mov 4,$j
-
-.Lsqr_outer:
-.Lsqr_inner1:
- mulx $npj,$mul1,$acc1
- add $tpj,$car1,$car1
- add $j,4,$j
- ld [$tp+8],$tpj
- cmp $j,$i
- add $acc1,$car1,$car1
- ld [$np+$j],$npj
- st $car1,[$tp]
- srlx $car1,32,$car1
- bl %icc,.Lsqr_inner1
- add $tp,4,$tp
-!.Lsqr_inner1
-
- add $j,4,$j
- ld [$ap+$j],$apj ! ap[j]
- mulx $npj,$mul1,$acc1
- add $tpj,$car1,$car1
- ld [$np+$j],$npj ! np[j]
- add $acc0,$car1,$car1
- ld [$tp+8],$tpj ! tp[j]
- add $acc1,$car1,$car1
- st $car1,[$tp]
- srlx $car1,32,$car1
-
- add $j,4,$j
- cmp $j,$num
- be,pn %icc,.Lsqr_no_inner2
- add $tp,4,$tp
-
-.Lsqr_inner2:
- mulx $apj,$mul0,$acc0
- mulx $npj,$mul1,$acc1
- add $tpj,$car1,$car1
- add $acc0,$car0,$car0
- ld [$ap+$j],$apj ! ap[j]
- and $car0,$mask,$acc0
- ld [$np+$j],$npj ! np[j]
- srlx $car0,32,$car0
- add $acc0,$acc0,$acc0
- ld [$tp+8],$tpj ! tp[j]
- or $sbit,$acc0,$acc0
- add $j,4,$j ! j++
- srlx $acc0,32,$sbit
- and $acc0,$mask,$acc0
- cmp $j,$num
- add $acc0,$car1,$car1
- add $acc1,$car1,$car1
- st $car1,[$tp] ! tp[j-1]
- srlx $car1,32,$car1
- bl %icc,.Lsqr_inner2
- add $tp,4,$tp ! tp++
-
-.Lsqr_no_inner2:
- mulx $apj,$mul0,$acc0
- mulx $npj,$mul1,$acc1
- add $tpj,$car1,$car1
- add $acc0,$car0,$car0
- and $car0,$mask,$acc0
- srlx $car0,32,$car0
- add $acc0,$acc0,$acc0
- or $sbit,$acc0,$acc0
- srlx $acc0,32,$sbit
- and $acc0,$mask,$acc0
- add $acc0,$car1,$car1
- add $acc1,$car1,$car1
- st $car1,[$tp] ! tp[j-1]
- srlx $car1,32,$car1
-
- add $car0,$car0,$car0
- or $sbit,$car0,$car0
- add $car0,$car1,$car1
- add $car2,$car1,$car1
- st $car1,[$tp+4]
- srlx $car1,32,$car2
-
- add $i,4,$i ! i++
- ld [%sp+$bias+$frame],$tmp1 ! tp[0]
- ld [%sp+$bias+$frame+4],$tpj ! tp[1]
- ld [$ap+$i],$mul0 ! ap[j]
- ld [$np],$car1 ! np[0]
- ld [$np+4],$npj ! np[1]
- mulx $n0,$tmp1,$mul1
- and $mul1,$mask,$mul1
- add $i,4,$tmp0
-
- mulx $mul0,$mul0,$car0
- mulx $car1,$mul1,$car1
- and $car0,$mask,$acc0
- add $tmp1,$car1,$car1
- srlx $car0,32,$car0
- add %sp,$bias+$frame,$tp
- srlx $car1,32,$car1
- and $car0,1,$sbit
- srlx $car0,1,$car0
-
- cmp $tmp0,$num ! i<num-1
- bl %icc,.Lsqr_outer
- mov 4,$j
-
-.Lsqr_last:
- mulx $npj,$mul1,$acc1
- add $tpj,$car1,$car1
- add $j,4,$j
- ld [$tp+8],$tpj
- cmp $j,$i
- add $acc1,$car1,$car1
- ld [$np+$j],$npj
- st $car1,[$tp]
- srlx $car1,32,$car1
- bl %icc,.Lsqr_last
- add $tp,4,$tp
-!.Lsqr_last
-
- mulx $npj,$mul1,$acc1
- add $tpj,$car1,$car1
- add $acc0,$car1,$car1
- add $acc1,$car1,$car1
- st $car1,[$tp]
- srlx $car1,32,$car1
-
- add $car0,$car0,$car0 ! recover $car0
- or $sbit,$car0,$car0
- add $car0,$car1,$car1
- add $car2,$car1,$car1
- st $car1,[$tp+4]
- srlx $car1,32,$car2
-
- ba .Ltail
- add $tp,8,$tp
-.type $fname,#function
-.size $fname,(.-$fname)
-.asciz "Montgomery Multipltication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
-.align 32
-___
-$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl b/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl
deleted file mode 100755
index a14205f..0000000
--- a/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl
+++ /dev/null
@@ -1,882 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# October 2005
-#
-# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
-# Because unlike integer multiplier, which simply stalls whole CPU,
-# FPU is fully pipelined and can effectively emit 48 bit partial
-# product every cycle. Why not blended SPARC v9? One can argue that
-# making this module dependent on UltraSPARC VIS extension limits its
-# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
-# implementations from compatibility matrix. But the rest, whole Sun
-# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
-# VIS extension instructions used in this module. This is considered
-# good enough to not care about HAL SPARC64 users [if any] who have
-# integer-only pure SPARCv9 module to "fall down" to.
-
-# USI&II cores currently exhibit uniform 2x improvement [over pre-
-# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
-# performance improves few percents for shorter keys and worsens few
-# percents for longer keys. This is because USIII integer multiplier
-# is >3x faster than USI&II one, which is harder to match [but see
-# TODO list below]. It should also be noted that SPARC64 V features
-# out-of-order execution, which *might* mean that integer multiplier
-# is pipelined, which in turn *might* be impossible to match... On
-# additional note, SPARC64 V implements FP Multiply-Add instruction,
-# which is perfectly usable in this context... In other words, as far
-# as Fujitsu SPARC64 V goes, talk to the author:-)
-
-# The implementation implies following "non-natural" limitations on
-# input arguments:
-# - num may not be less than 4;
-# - num has to be even;
-# Failure to meet either condition has no fatal effects, simply
-# doesn't give any performance gain.
-
-# TODO:
-# - modulo-schedule inner loop for better performance (on in-order
-# execution core such as UltraSPARC this shall result in further
-# noticeable(!) improvement);
-# - dedicated squaring procedure[?];
-
-######################################################################
-# November 2006
-#
-# Modulo-scheduled inner loops allow to interleave floating point and
-# integer instructions and minimize Read-After-Write penalties. This
-# results in *further* 20-50% perfromance improvement [depending on
-# key length, more for longer keys] on USI&II cores and 30-80% - on
-# USIII&IV.
-
-$fname="bn_mul_mont_fpu";
-$bits=32;
-for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-
-if ($bits==64) {
- $bias=2047;
- $frame=192;
-} else {
- $bias=0;
- $frame=128; # 96 rounded up to largest known cache-line
-}
-$locals=64;
-
-# In order to provide for 32-/64-bit ABI duality, I keep integers wider
-# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
-# exclusively for pointers, indexes and other small values...
-# int bn_mul_mont(
-$rp="%i0"; # BN_ULONG *rp,
-$ap="%i1"; # const BN_ULONG *ap,
-$bp="%i2"; # const BN_ULONG *bp,
-$np="%i3"; # const BN_ULONG *np,
-$n0="%i4"; # const BN_ULONG *n0,
-$num="%i5"; # int num);
-
-$tp="%l0"; # t[num]
-$ap_l="%l1"; # a[num],n[num] are smashed to 32-bit words and saved
-$ap_h="%l2"; # to these four vectors as double-precision FP values.
-$np_l="%l3"; # This way a bunch of fxtods are eliminated in second
-$np_h="%l4"; # loop and L1-cache aliasing is minimized...
-$i="%l5";
-$j="%l6";
-$mask="%l7"; # 16-bit mask, 0xffff
-
-$n0="%g4"; # reassigned(!) to "64-bit" register
-$carry="%i4"; # %i4 reused(!) for a carry bit
-
-# FP register naming chart
-#
-# ..HILO
-# dcba
-# --------
-# LOa
-# LOb
-# LOc
-# LOd
-# HIa
-# HIb
-# HIc
-# HId
-# ..a
-# ..b
-$ba="%f0"; $bb="%f2"; $bc="%f4"; $bd="%f6";
-$na="%f8"; $nb="%f10"; $nc="%f12"; $nd="%f14";
-$alo="%f16"; $alo_="%f17"; $ahi="%f18"; $ahi_="%f19";
-$nlo="%f20"; $nlo_="%f21"; $nhi="%f22"; $nhi_="%f23";
-
-$dota="%f24"; $dotb="%f26";
-
-$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
-$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
-$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
-$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
-
-$ASI_FL16_P=0xD2; # magic ASI value to engage 16-bit FP load
-
-$code=<<___;
-.section ".text",#alloc,#execinstr
-
-.global $fname
-.align 32
-$fname:
- save %sp,-$frame-$locals,%sp
-
- cmp $num,4
- bl,a,pn %icc,.Lret
- clr %i0
- andcc $num,1,%g0 ! $num has to be even...
- bnz,a,pn %icc,.Lret
- clr %i0 ! signal "unsupported input value"
-
- srl $num,1,$num
- sethi %hi(0xffff),$mask
- ld [%i4+0],$n0 ! $n0 reassigned, remember?
- or $mask,%lo(0xffff),$mask
- ld [%i4+4],%o0
- sllx %o0,32,%o0
- or %o0,$n0,$n0 ! $n0=n0[1].n0[0]
-
- sll $num,3,$num ! num*=8
-
- add %sp,$bias,%o0 ! real top of stack
- sll $num,2,%o1
- add %o1,$num,%o1 ! %o1=num*5
- sub %o0,%o1,%o0
- and %o0,-2048,%o0 ! optimize TLB utilization
- sub %o0,$bias,%sp ! alloca(5*num*8)
-
- rd %asi,%o7 ! save %asi
- add %sp,$bias+$frame+$locals,$tp
- add $tp,$num,$ap_l
- add $ap_l,$num,$ap_l ! [an]p_[lh] point at the vectors' ends !
- add $ap_l,$num,$ap_h
- add $ap_h,$num,$np_l
- add $np_l,$num,$np_h
-
- wr %g0,$ASI_FL16_P,%asi ! setup %asi for 16-bit FP loads
-
- add $rp,$num,$rp ! readjust input pointers to point
- add $ap,$num,$ap ! at the ends too...
- add $bp,$num,$bp
- add $np,$num,$np
-
- stx %o7,[%sp+$bias+$frame+48] ! save %asi
-
- sub %g0,$num,$i ! i=-num
- sub %g0,$num,$j ! j=-num
-
- add $ap,$j,%o3
- add $bp,$i,%o4
-
- ld [%o3+4],%g1 ! bp[0]
- ld [%o3+0],%o0
- ld [%o4+4],%g5 ! ap[0]
- sllx %g1,32,%g1
- ld [%o4+0],%o1
- sllx %g5,32,%g5
- or %g1,%o0,%o0
- or %g5,%o1,%o1
-
- add $np,$j,%o5
-
- mulx %o1,%o0,%o0 ! ap[0]*bp[0]
- mulx $n0,%o0,%o0 ! ap[0]*bp[0]*n0
- stx %o0,[%sp+$bias+$frame+0]
-
- ld [%o3+0],$alo_ ! load a[j] as pair of 32-bit words
- fzeros $alo
- ld [%o3+4],$ahi_
- fzeros $ahi
- ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words
- fzeros $nlo
- ld [%o5+4],$nhi_
- fzeros $nhi
-
- ! transfer b[i] to FPU as 4x16-bit values
- ldda [%o4+2]%asi,$ba
- fxtod $alo,$alo
- ldda [%o4+0]%asi,$bb
- fxtod $ahi,$ahi
- ldda [%o4+6]%asi,$bc
- fxtod $nlo,$nlo
- ldda [%o4+4]%asi,$bd
- fxtod $nhi,$nhi
-
- ! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
- ldda [%sp+$bias+$frame+6]%asi,$na
- fxtod $ba,$ba
- ldda [%sp+$bias+$frame+4]%asi,$nb
- fxtod $bb,$bb
- ldda [%sp+$bias+$frame+2]%asi,$nc
- fxtod $bc,$bc
- ldda [%sp+$bias+$frame+0]%asi,$nd
- fxtod $bd,$bd
-
- std $alo,[$ap_l+$j] ! save smashed ap[j] in double format
- fxtod $na,$na
- std $ahi,[$ap_h+$j]
- fxtod $nb,$nb
- std $nlo,[$np_l+$j] ! save smashed np[j] in double format
- fxtod $nc,$nc
- std $nhi,[$np_h+$j]
- fxtod $nd,$nd
-
- fmuld $alo,$ba,$aloa
- fmuld $nlo,$na,$nloa
- fmuld $alo,$bb,$alob
- fmuld $nlo,$nb,$nlob
- fmuld $alo,$bc,$aloc
- faddd $aloa,$nloa,$nloa
- fmuld $nlo,$nc,$nloc
- fmuld $alo,$bd,$alod
- faddd $alob,$nlob,$nlob
- fmuld $nlo,$nd,$nlod
- fmuld $ahi,$ba,$ahia
- faddd $aloc,$nloc,$nloc
- fmuld $nhi,$na,$nhia
- fmuld $ahi,$bb,$ahib
- faddd $alod,$nlod,$nlod
- fmuld $nhi,$nb,$nhib
- fmuld $ahi,$bc,$ahic
- faddd $ahia,$nhia,$nhia
- fmuld $nhi,$nc,$nhic
- fmuld $ahi,$bd,$ahid
- faddd $ahib,$nhib,$nhib
- fmuld $nhi,$nd,$nhid
-
- faddd $ahic,$nhic,$dota ! $nhic
- faddd $ahid,$nhid,$dotb ! $nhid
-
- faddd $nloc,$nhia,$nloc
- faddd $nlod,$nhib,$nlod
-
- fdtox $nloa,$nloa
- fdtox $nlob,$nlob
- fdtox $nloc,$nloc
- fdtox $nlod,$nlod
-
- std $nloa,[%sp+$bias+$frame+0]
- add $j,8,$j
- std $nlob,[%sp+$bias+$frame+8]
- add $ap,$j,%o4
- std $nloc,[%sp+$bias+$frame+16]
- add $np,$j,%o5
- std $nlod,[%sp+$bias+$frame+24]
-
- ld [%o4+0],$alo_ ! load a[j] as pair of 32-bit words
- fzeros $alo
- ld [%o4+4],$ahi_
- fzeros $ahi
- ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words
- fzeros $nlo
- ld [%o5+4],$nhi_
- fzeros $nhi
-
- fxtod $alo,$alo
- fxtod $ahi,$ahi
- fxtod $nlo,$nlo
- fxtod $nhi,$nhi
-
- ldx [%sp+$bias+$frame+0],%o0
- fmuld $alo,$ba,$aloa
- ldx [%sp+$bias+$frame+8],%o1
- fmuld $nlo,$na,$nloa
- ldx [%sp+$bias+$frame+16],%o2
- fmuld $alo,$bb,$alob
- ldx [%sp+$bias+$frame+24],%o3
- fmuld $nlo,$nb,$nlob
-
- srlx %o0,16,%o7
- std $alo,[$ap_l+$j] ! save smashed ap[j] in double format
- fmuld $alo,$bc,$aloc
- add %o7,%o1,%o1
- std $ahi,[$ap_h+$j]
- faddd $aloa,$nloa,$nloa
- fmuld $nlo,$nc,$nloc
- srlx %o1,16,%o7
- std $nlo,[$np_l+$j] ! save smashed np[j] in double format
- fmuld $alo,$bd,$alod
- add %o7,%o2,%o2
- std $nhi,[$np_h+$j]
- faddd $alob,$nlob,$nlob
- fmuld $nlo,$nd,$nlod
- srlx %o2,16,%o7
- fmuld $ahi,$ba,$ahia
- add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
- faddd $aloc,$nloc,$nloc
- fmuld $nhi,$na,$nhia
- !and %o0,$mask,%o0
- !and %o1,$mask,%o1
- !and %o2,$mask,%o2
- !sllx %o1,16,%o1
- !sllx %o2,32,%o2
- !sllx %o3,48,%o7
- !or %o1,%o0,%o0
- !or %o2,%o0,%o0
- !or %o7,%o0,%o0 ! 64-bit result
- srlx %o3,16,%g1 ! 34-bit carry
- fmuld $ahi,$bb,$ahib
-
- faddd $alod,$nlod,$nlod
- fmuld $nhi,$nb,$nhib
- fmuld $ahi,$bc,$ahic
- faddd $ahia,$nhia,$nhia
- fmuld $nhi,$nc,$nhic
- fmuld $ahi,$bd,$ahid
- faddd $ahib,$nhib,$nhib
- fmuld $nhi,$nd,$nhid
-
- faddd $dota,$nloa,$nloa
- faddd $dotb,$nlob,$nlob
- faddd $ahic,$nhic,$dota ! $nhic
- faddd $ahid,$nhid,$dotb ! $nhid
-
- faddd $nloc,$nhia,$nloc
- faddd $nlod,$nhib,$nlod
-
- fdtox $nloa,$nloa
- fdtox $nlob,$nlob
- fdtox $nloc,$nloc
- fdtox $nlod,$nlod
-
- std $nloa,[%sp+$bias+$frame+0]
- std $nlob,[%sp+$bias+$frame+8]
- addcc $j,8,$j
- std $nloc,[%sp+$bias+$frame+16]
- bz,pn %icc,.L1stskip
- std $nlod,[%sp+$bias+$frame+24]
-
-.align 32 ! incidentally already aligned !
-.L1st:
- add $ap,$j,%o4
- add $np,$j,%o5
- ld [%o4+0],$alo_ ! load a[j] as pair of 32-bit words
- fzeros $alo
- ld [%o4+4],$ahi_
- fzeros $ahi
- ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words
- fzeros $nlo
- ld [%o5+4],$nhi_
- fzeros $nhi
-
- fxtod $alo,$alo
- fxtod $ahi,$ahi
- fxtod $nlo,$nlo
- fxtod $nhi,$nhi
-
- ldx [%sp+$bias+$frame+0],%o0
- fmuld $alo,$ba,$aloa
- ldx [%sp+$bias+$frame+8],%o1
- fmuld $nlo,$na,$nloa
- ldx [%sp+$bias+$frame+16],%o2
- fmuld $alo,$bb,$alob
- ldx [%sp+$bias+$frame+24],%o3
- fmuld $nlo,$nb,$nlob
-
- srlx %o0,16,%o7
- std $alo,[$ap_l+$j] ! save smashed ap[j] in double format
- fmuld $alo,$bc,$aloc
- add %o7,%o1,%o1
- std $ahi,[$ap_h+$j]
- faddd $aloa,$nloa,$nloa
- fmuld $nlo,$nc,$nloc
- srlx %o1,16,%o7
- std $nlo,[$np_l+$j] ! save smashed np[j] in double format
- fmuld $alo,$bd,$alod
- add %o7,%o2,%o2
- std $nhi,[$np_h+$j]
- faddd $alob,$nlob,$nlob
- fmuld $nlo,$nd,$nlod
- srlx %o2,16,%o7
- fmuld $ahi,$ba,$ahia
- add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
- and %o0,$mask,%o0
- faddd $aloc,$nloc,$nloc
- fmuld $nhi,$na,$nhia
- and %o1,$mask,%o1
- and %o2,$mask,%o2
- fmuld $ahi,$bb,$ahib
- sllx %o1,16,%o1
- faddd $alod,$nlod,$nlod
- fmuld $nhi,$nb,$nhib
- sllx %o2,32,%o2
- fmuld $ahi,$bc,$ahic
- sllx %o3,48,%o7
- or %o1,%o0,%o0
- faddd $ahia,$nhia,$nhia
- fmuld $nhi,$nc,$nhic
- or %o2,%o0,%o0
- fmuld $ahi,$bd,$ahid
- or %o7,%o0,%o0 ! 64-bit result
- faddd $ahib,$nhib,$nhib
- fmuld $nhi,$nd,$nhid
- addcc %g1,%o0,%o0
- faddd $dota,$nloa,$nloa
- srlx %o3,16,%g1 ! 34-bit carry
- faddd $dotb,$nlob,$nlob
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- stx %o0,[$tp] ! tp[j-1]=
-
- faddd $ahic,$nhic,$dota ! $nhic
- faddd $ahid,$nhid,$dotb ! $nhid
-
- faddd $nloc,$nhia,$nloc
- faddd $nlod,$nhib,$nlod
-
- fdtox $nloa,$nloa
- fdtox $nlob,$nlob
- fdtox $nloc,$nloc
- fdtox $nlod,$nlod
-
- std $nloa,[%sp+$bias+$frame+0]
- std $nlob,[%sp+$bias+$frame+8]
- std $nloc,[%sp+$bias+$frame+16]
- std $nlod,[%sp+$bias+$frame+24]
-
- addcc $j,8,$j
- bnz,pt %icc,.L1st
- add $tp,8,$tp
-
-.L1stskip:
- fdtox $dota,$dota
- fdtox $dotb,$dotb
-
- ldx [%sp+$bias+$frame+0],%o0
- ldx [%sp+$bias+$frame+8],%o1
- ldx [%sp+$bias+$frame+16],%o2
- ldx [%sp+$bias+$frame+24],%o3
-
- srlx %o0,16,%o7
- std $dota,[%sp+$bias+$frame+32]
- add %o7,%o1,%o1
- std $dotb,[%sp+$bias+$frame+40]
- srlx %o1,16,%o7
- add %o7,%o2,%o2
- srlx %o2,16,%o7
- add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
- and %o0,$mask,%o0
- and %o1,$mask,%o1
- and %o2,$mask,%o2
- sllx %o1,16,%o1
- sllx %o2,32,%o2
- sllx %o3,48,%o7
- or %o1,%o0,%o0
- or %o2,%o0,%o0
- or %o7,%o0,%o0 ! 64-bit result
- ldx [%sp+$bias+$frame+32],%o4
- addcc %g1,%o0,%o0
- ldx [%sp+$bias+$frame+40],%o5
- srlx %o3,16,%g1 ! 34-bit carry
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- stx %o0,[$tp] ! tp[j-1]=
- add $tp,8,$tp
-
- srlx %o4,16,%o7
- add %o7,%o5,%o5
- and %o4,$mask,%o4
- sllx %o5,16,%o7
- or %o7,%o4,%o4
- addcc %g1,%o4,%o4
- srlx %o5,48,%g1
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- mov %g1,$carry
- stx %o4,[$tp] ! tp[num-1]=
-
- ba .Louter
- add $i,8,$i
-.align 32
-.Louter:
- sub %g0,$num,$j ! j=-num
- add %sp,$bias+$frame+$locals,$tp
-
- add $ap,$j,%o3
- add $bp,$i,%o4
-
- ld [%o3+4],%g1 ! bp[i]
- ld [%o3+0],%o0
- ld [%o4+4],%g5 ! ap[0]
- sllx %g1,32,%g1
- ld [%o4+0],%o1
- sllx %g5,32,%g5
- or %g1,%o0,%o0
- or %g5,%o1,%o1
-
- ldx [$tp],%o2 ! tp[0]
- mulx %o1,%o0,%o0
- addcc %o2,%o0,%o0
- mulx $n0,%o0,%o0 ! (ap[0]*bp[i]+t[0])*n0
- stx %o0,[%sp+$bias+$frame+0]
-
- ! transfer b[i] to FPU as 4x16-bit values
- ldda [%o4+2]%asi,$ba
- ldda [%o4+0]%asi,$bb
- ldda [%o4+6]%asi,$bc
- ldda [%o4+4]%asi,$bd
-
- ! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
- ldda [%sp+$bias+$frame+6]%asi,$na
- fxtod $ba,$ba
- ldda [%sp+$bias+$frame+4]%asi,$nb
- fxtod $bb,$bb
- ldda [%sp+$bias+$frame+2]%asi,$nc
- fxtod $bc,$bc
- ldda [%sp+$bias+$frame+0]%asi,$nd
- fxtod $bd,$bd
- ldd [$ap_l+$j],$alo ! load a[j] in double format
- fxtod $na,$na
- ldd [$ap_h+$j],$ahi
- fxtod $nb,$nb
- ldd [$np_l+$j],$nlo ! load n[j] in double format
- fxtod $nc,$nc
- ldd [$np_h+$j],$nhi
- fxtod $nd,$nd
-
- fmuld $alo,$ba,$aloa
- fmuld $nlo,$na,$nloa
- fmuld $alo,$bb,$alob
- fmuld $nlo,$nb,$nlob
- fmuld $alo,$bc,$aloc
- faddd $aloa,$nloa,$nloa
- fmuld $nlo,$nc,$nloc
- fmuld $alo,$bd,$alod
- faddd $alob,$nlob,$nlob
- fmuld $nlo,$nd,$nlod
- fmuld $ahi,$ba,$ahia
- faddd $aloc,$nloc,$nloc
- fmuld $nhi,$na,$nhia
- fmuld $ahi,$bb,$ahib
- faddd $alod,$nlod,$nlod
- fmuld $nhi,$nb,$nhib
- fmuld $ahi,$bc,$ahic
- faddd $ahia,$nhia,$nhia
- fmuld $nhi,$nc,$nhic
- fmuld $ahi,$bd,$ahid
- faddd $ahib,$nhib,$nhib
- fmuld $nhi,$nd,$nhid
-
- faddd $ahic,$nhic,$dota ! $nhic
- faddd $ahid,$nhid,$dotb ! $nhid
-
- faddd $nloc,$nhia,$nloc
- faddd $nlod,$nhib,$nlod
-
- fdtox $nloa,$nloa
- fdtox $nlob,$nlob
- fdtox $nloc,$nloc
- fdtox $nlod,$nlod
-
- std $nloa,[%sp+$bias+$frame+0]
- std $nlob,[%sp+$bias+$frame+8]
- std $nloc,[%sp+$bias+$frame+16]
- add $j,8,$j
- std $nlod,[%sp+$bias+$frame+24]
-
- ldd [$ap_l+$j],$alo ! load a[j] in double format
- ldd [$ap_h+$j],$ahi
- ldd [$np_l+$j],$nlo ! load n[j] in double format
- ldd [$np_h+$j],$nhi
-
- fmuld $alo,$ba,$aloa
- fmuld $nlo,$na,$nloa
- fmuld $alo,$bb,$alob
- fmuld $nlo,$nb,$nlob
- fmuld $alo,$bc,$aloc
- ldx [%sp+$bias+$frame+0],%o0
- faddd $aloa,$nloa,$nloa
- fmuld $nlo,$nc,$nloc
- ldx [%sp+$bias+$frame+8],%o1
- fmuld $alo,$bd,$alod
- ldx [%sp+$bias+$frame+16],%o2
- faddd $alob,$nlob,$nlob
- fmuld $nlo,$nd,$nlod
- ldx [%sp+$bias+$frame+24],%o3
- fmuld $ahi,$ba,$ahia
-
- srlx %o0,16,%o7
- faddd $aloc,$nloc,$nloc
- fmuld $nhi,$na,$nhia
- add %o7,%o1,%o1
- fmuld $ahi,$bb,$ahib
- srlx %o1,16,%o7
- faddd $alod,$nlod,$nlod
- fmuld $nhi,$nb,$nhib
- add %o7,%o2,%o2
- fmuld $ahi,$bc,$ahic
- srlx %o2,16,%o7
- faddd $ahia,$nhia,$nhia
- fmuld $nhi,$nc,$nhic
- add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
- ! why?
- and %o0,$mask,%o0
- fmuld $ahi,$bd,$ahid
- and %o1,$mask,%o1
- and %o2,$mask,%o2
- faddd $ahib,$nhib,$nhib
- fmuld $nhi,$nd,$nhid
- sllx %o1,16,%o1
- faddd $dota,$nloa,$nloa
- sllx %o2,32,%o2
- faddd $dotb,$nlob,$nlob
- sllx %o3,48,%o7
- or %o1,%o0,%o0
- faddd $ahic,$nhic,$dota ! $nhic
- or %o2,%o0,%o0
- faddd $ahid,$nhid,$dotb ! $nhid
- or %o7,%o0,%o0 ! 64-bit result
- ldx [$tp],%o7
- faddd $nloc,$nhia,$nloc
- addcc %o7,%o0,%o0
- ! end-of-why?
- faddd $nlod,$nhib,$nlod
- srlx %o3,16,%g1 ! 34-bit carry
- fdtox $nloa,$nloa
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- fdtox $nlob,$nlob
- fdtox $nloc,$nloc
- fdtox $nlod,$nlod
-
- std $nloa,[%sp+$bias+$frame+0]
- std $nlob,[%sp+$bias+$frame+8]
- addcc $j,8,$j
- std $nloc,[%sp+$bias+$frame+16]
- bz,pn %icc,.Linnerskip
- std $nlod,[%sp+$bias+$frame+24]
-
- ba .Linner
- nop
-.align 32
-.Linner:
- ldd [$ap_l+$j],$alo ! load a[j] in double format
- ldd [$ap_h+$j],$ahi
- ldd [$np_l+$j],$nlo ! load n[j] in double format
- ldd [$np_h+$j],$nhi
-
- fmuld $alo,$ba,$aloa
- fmuld $nlo,$na,$nloa
- fmuld $alo,$bb,$alob
- fmuld $nlo,$nb,$nlob
- fmuld $alo,$bc,$aloc
- ldx [%sp+$bias+$frame+0],%o0
- faddd $aloa,$nloa,$nloa
- fmuld $nlo,$nc,$nloc
- ldx [%sp+$bias+$frame+8],%o1
- fmuld $alo,$bd,$alod
- ldx [%sp+$bias+$frame+16],%o2
- faddd $alob,$nlob,$nlob
- fmuld $nlo,$nd,$nlod
- ldx [%sp+$bias+$frame+24],%o3
- fmuld $ahi,$ba,$ahia
-
- srlx %o0,16,%o7
- faddd $aloc,$nloc,$nloc
- fmuld $nhi,$na,$nhia
- add %o7,%o1,%o1
- fmuld $ahi,$bb,$ahib
- srlx %o1,16,%o7
- faddd $alod,$nlod,$nlod
- fmuld $nhi,$nb,$nhib
- add %o7,%o2,%o2
- fmuld $ahi,$bc,$ahic
- srlx %o2,16,%o7
- faddd $ahia,$nhia,$nhia
- fmuld $nhi,$nc,$nhic
- add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
- and %o0,$mask,%o0
- fmuld $ahi,$bd,$ahid
- and %o1,$mask,%o1
- and %o2,$mask,%o2
- faddd $ahib,$nhib,$nhib
- fmuld $nhi,$nd,$nhid
- sllx %o1,16,%o1
- faddd $dota,$nloa,$nloa
- sllx %o2,32,%o2
- faddd $dotb,$nlob,$nlob
- sllx %o3,48,%o7
- or %o1,%o0,%o0
- faddd $ahic,$nhic,$dota ! $nhic
- or %o2,%o0,%o0
- faddd $ahid,$nhid,$dotb ! $nhid
- or %o7,%o0,%o0 ! 64-bit result
- faddd $nloc,$nhia,$nloc
- addcc %g1,%o0,%o0
- ldx [$tp+8],%o7 ! tp[j]
- faddd $nlod,$nhib,$nlod
- srlx %o3,16,%g1 ! 34-bit carry
- fdtox $nloa,$nloa
- bcs,a %xcc,.+8
- add %g1,1,%g1
- fdtox $nlob,$nlob
- addcc %o7,%o0,%o0
- fdtox $nloc,$nloc
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- stx %o0,[$tp] ! tp[j-1]
- fdtox $nlod,$nlod
-
- std $nloa,[%sp+$bias+$frame+0]
- std $nlob,[%sp+$bias+$frame+8]
- std $nloc,[%sp+$bias+$frame+16]
- addcc $j,8,$j
- std $nlod,[%sp+$bias+$frame+24]
- bnz,pt %icc,.Linner
- add $tp,8,$tp
-
-.Linnerskip:
- fdtox $dota,$dota
- fdtox $dotb,$dotb
-
- ldx [%sp+$bias+$frame+0],%o0
- ldx [%sp+$bias+$frame+8],%o1
- ldx [%sp+$bias+$frame+16],%o2
- ldx [%sp+$bias+$frame+24],%o3
-
- srlx %o0,16,%o7
- std $dota,[%sp+$bias+$frame+32]
- add %o7,%o1,%o1
- std $dotb,[%sp+$bias+$frame+40]
- srlx %o1,16,%o7
- add %o7,%o2,%o2
- srlx %o2,16,%o7
- add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
- and %o0,$mask,%o0
- and %o1,$mask,%o1
- and %o2,$mask,%o2
- sllx %o1,16,%o1
- sllx %o2,32,%o2
- sllx %o3,48,%o7
- or %o1,%o0,%o0
- or %o2,%o0,%o0
- ldx [%sp+$bias+$frame+32],%o4
- or %o7,%o0,%o0 ! 64-bit result
- ldx [%sp+$bias+$frame+40],%o5
- addcc %g1,%o0,%o0
- ldx [$tp+8],%o7 ! tp[j]
- srlx %o3,16,%g1 ! 34-bit carry
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- addcc %o7,%o0,%o0
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- stx %o0,[$tp] ! tp[j-1]
- add $tp,8,$tp
-
- srlx %o4,16,%o7
- add %o7,%o5,%o5
- and %o4,$mask,%o4
- sllx %o5,16,%o7
- or %o7,%o4,%o4
- addcc %g1,%o4,%o4
- srlx %o5,48,%g1
- bcs,a %xcc,.+8
- add %g1,1,%g1
-
- addcc $carry,%o4,%o4
- stx %o4,[$tp] ! tp[num-1]
- mov %g1,$carry
- bcs,a %xcc,.+8
- add $carry,1,$carry
-
- addcc $i,8,$i
- bnz %icc,.Louter
- nop
-
- add $tp,8,$tp ! adjust tp to point at the end
- orn %g0,%g0,%g4
- sub %g0,$num,%o7 ! n=-num
- ba .Lsub
- subcc %g0,%g0,%g0 ! clear %icc.c
-
-.align 32
-.Lsub:
- ldx [$tp+%o7],%o0
- add $np,%o7,%g1
- ld [%g1+0],%o2
- ld [%g1+4],%o3
- srlx %o0,32,%o1
- subccc %o0,%o2,%o2
- add $rp,%o7,%g1
- subccc %o1,%o3,%o3
- st %o2,[%g1+0]
- add %o7,8,%o7
- brnz,pt %o7,.Lsub
- st %o3,[%g1+4]
- subc $carry,0,%g4
- sub %g0,$num,%o7 ! n=-num
- ba .Lcopy
- nop
-
-.align 32
-.Lcopy:
- ldx [$tp+%o7],%o0
- add $rp,%o7,%g1
- ld [%g1+0],%o2
- ld [%g1+4],%o3
- stx %g0,[$tp+%o7]
- and %o0,%g4,%o0
- srlx %o0,32,%o1
- andn %o2,%g4,%o2
- andn %o3,%g4,%o3
- or %o2,%o0,%o0
- or %o3,%o1,%o1
- st %o0,[%g1+0]
- add %o7,8,%o7
- brnz,pt %o7,.Lcopy
- st %o1,[%g1+4]
- sub %g0,$num,%o7 ! n=-num
-
-.Lzap:
- stx %g0,[$ap_l+%o7]
- stx %g0,[$ap_h+%o7]
- stx %g0,[$np_l+%o7]
- stx %g0,[$np_h+%o7]
- add %o7,8,%o7
- brnz,pt %o7,.Lzap
- nop
-
- ldx [%sp+$bias+$frame+48],%o7
- wr %g0,%o7,%asi ! restore %asi
-
- mov 1,%i0
-.Lret:
- ret
- restore
-.type $fname,#function
-.size $fname,(.-$fname)
-.asciz "Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by <appro\@openssl.org>"
-.align 32
-___
-
-$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-
-# Below substitution makes it possible to compile without demanding
-# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
-# dare to do this, because VIS capability is detected at run-time now
-# and this routine is not called on CPU not capable to execute it. Do
-# note that fzeros is not the only VIS dependency! Another dependency
-# is implicit and is just _a_ numerical value loaded to %asi register,
-# which assembler can't recognize as VIS specific...
-$code =~ s/fzeros\s+%f([0-9]+)/
- sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
- /gem;
-
-print $code;
-# flush
-close STDOUT;
diff --git a/crypto/openssl/crypto/bn/asm/via-mont.pl b/crypto/openssl/crypto/bn/asm/via-mont.pl
deleted file mode 100755
index c046a51..0000000
--- a/crypto/openssl/crypto/bn/asm/via-mont.pl
+++ /dev/null
@@ -1,242 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-#
-# Wrapper around 'rep montmul', VIA-specific instruction accessing
-# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
-# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
-#
-# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
-# different software configurations on 1.5GHz VIA Esther processor.
-# Lines marked with "software integer" denote performance of hand-
-# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
-# refers to hand-coded SSE2 Montgomery multiplication procedure found
-# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
-# Padlock SDK 2.0.1 available for download from VIA, which naturally
-# utilizes the magic 'repz montmul' instruction. And finally "hardware
-# this" refers to *this* implementation which also uses 'repz montmul'
-#
-# sign verify sign/s verify/s
-# rsa 512 bits 0.001720s 0.000140s 581.4 7149.7 software integer
-# rsa 512 bits 0.000690s 0.000086s 1450.3 11606.0 software SSE2
-# rsa 512 bits 0.006136s 0.000201s 163.0 4974.5 hardware VIA SDK
-# rsa 512 bits 0.000712s 0.000050s 1404.9 19858.5 hardware this
-#
-# rsa 1024 bits 0.008518s 0.000413s 117.4 2420.8 software integer
-# rsa 1024 bits 0.004275s 0.000277s 233.9 3609.7 software SSE2
-# rsa 1024 bits 0.012136s 0.000260s 82.4 3844.5 hardware VIA SDK
-# rsa 1024 bits 0.002522s 0.000116s 396.5 8650.9 hardware this
-#
-# rsa 2048 bits 0.050101s 0.001371s 20.0 729.6 software integer
-# rsa 2048 bits 0.030273s 0.001008s 33.0 991.9 software SSE2
-# rsa 2048 bits 0.030833s 0.000976s 32.4 1025.1 hardware VIA SDK
-# rsa 2048 bits 0.011879s 0.000342s 84.2 2921.7 hardware this
-#
-# rsa 4096 bits 0.327097s 0.004859s 3.1 205.8 software integer
-# rsa 4096 bits 0.229318s 0.003859s 4.4 259.2 software SSE2
-# rsa 4096 bits 0.233953s 0.003274s 4.3 305.4 hardware VIA SDK
-# rsa 4096 bits 0.070493s 0.001166s 14.2 857.6 hardware this
-#
-# dsa 512 bits 0.001342s 0.001651s 745.2 605.7 software integer
-# dsa 512 bits 0.000844s 0.000987s 1185.3 1013.1 software SSE2
-# dsa 512 bits 0.001902s 0.002247s 525.6 444.9 hardware VIA SDK
-# dsa 512 bits 0.000458s 0.000524s 2182.2 1909.1 hardware this
-#
-# dsa 1024 bits 0.003964s 0.004926s 252.3 203.0 software integer
-# dsa 1024 bits 0.002686s 0.003166s 372.3 315.8 software SSE2
-# dsa 1024 bits 0.002397s 0.002823s 417.1 354.3 hardware VIA SDK
-# dsa 1024 bits 0.000978s 0.001170s 1022.2 855.0 hardware this
-#
-# dsa 2048 bits 0.013280s 0.016518s 75.3 60.5 software integer
-# dsa 2048 bits 0.009911s 0.011522s 100.9 86.8 software SSE2
-# dsa 2048 bits 0.009542s 0.011763s 104.8 85.0 hardware VIA SDK
-# dsa 2048 bits 0.002884s 0.003352s 346.8 298.3 hardware this
-#
-# To give you some other reference point here is output for 2.4GHz P4
-# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
-# SSE2" in above terms.
-#
-# rsa 512 bits 0.000407s 0.000047s 2454.2 21137.0
-# rsa 1024 bits 0.002426s 0.000141s 412.1 7100.0
-# rsa 2048 bits 0.015046s 0.000491s 66.5 2034.9
-# rsa 4096 bits 0.109770s 0.002379s 9.1 420.3
-# dsa 512 bits 0.000438s 0.000525s 2281.1 1904.1
-# dsa 1024 bits 0.001346s 0.001595s 742.7 627.0
-# dsa 2048 bits 0.004745s 0.005582s 210.7 179.1
-#
-# Conclusions:
-# - VIA SDK leaves a *lot* of room for improvement (which this
-# implementation successfully fills:-);
-# - 'rep montmul' gives up to >3x performance improvement depending on
-# key length;
-# - in terms of absolute performance it delivers approximately as much
-# as modern out-of-order 32-bit cores [again, for longer keys].
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "x86asm.pl";
-
-&asm_init($ARGV[0],"via-mont.pl");
-
-# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
-$func="bn_mul_mont_padlock";
-
-$pad=16*1; # amount of reserved bytes on top of every vector
-
-# stack layout
-$mZeroPrime=&DWP(0,"esp"); # these are specified by VIA
-$A=&DWP(4,"esp");
-$B=&DWP(8,"esp");
-$T=&DWP(12,"esp");
-$M=&DWP(16,"esp");
-$scratch=&DWP(20,"esp");
-$rp=&DWP(24,"esp"); # these are mine
-$sp=&DWP(28,"esp");
-# &DWP(32,"esp") # 32 byte scratch area
-# &DWP(64+(4*$num+$pad)*0,"esp") # padded tp[num]
-# &DWP(64+(4*$num+$pad)*1,"esp") # padded copy of ap[num]
-# &DWP(64+(4*$num+$pad)*2,"esp") # padded copy of bp[num]
-# &DWP(64+(4*$num+$pad)*3,"esp") # padded copy of np[num]
-# Note that SDK suggests to unconditionally allocate 2K per vector. This
-# has quite an impact on performance. It naturally depends on key length,
-# but to give an example 1024 bit private RSA key operations suffer >30%
-# penalty. I allocate only as much as actually required...
-
-&function_begin($func);
- &xor ("eax","eax");
- &mov ("ecx",&wparam(5)); # num
- # meet VIA's limitations for num [note that the specification
- # expresses them in bits, while we work with amount of 32-bit words]
- &test ("ecx",3);
- &jnz (&label("leave")); # num % 4 != 0
- &cmp ("ecx",8);
- &jb (&label("leave")); # num < 8
- &cmp ("ecx",1024);
- &ja (&label("leave")); # num > 1024
-
- &pushf ();
- &cld ();
-
- &mov ("edi",&wparam(0)); # rp
- &mov ("eax",&wparam(1)); # ap
- &mov ("ebx",&wparam(2)); # bp
- &mov ("edx",&wparam(3)); # np
- &mov ("esi",&wparam(4)); # n0
- &mov ("esi",&DWP(0,"esi")); # *n0
-
- &lea ("ecx",&DWP($pad,"","ecx",4)); # ecx becomes vector size in bytes
- &lea ("ebp",&DWP(64,"","ecx",4)); # allocate 4 vectors + 64 bytes
- &neg ("ebp");
- &add ("ebp","esp");
- &and ("ebp",-64); # align to cache-line
- &xchg ("ebp","esp"); # alloca
-
- &mov ($rp,"edi"); # save rp
- &mov ($sp,"ebp"); # save esp
-
- &mov ($mZeroPrime,"esi");
- &lea ("esi",&DWP(64,"esp")); # tp
- &mov ($T,"esi");
- &lea ("edi",&DWP(32,"esp")); # scratch area
- &mov ($scratch,"edi");
- &mov ("esi","eax");
-
- &lea ("ebp",&DWP(-$pad,"ecx"));
- &shr ("ebp",2); # restore original num value in ebp
-
- &xor ("eax","eax");
-
- &mov ("ecx","ebp");
- &lea ("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
- &data_byte(0xf3,0xab); # rep stosl, bzero
-
- &mov ("ecx","ebp");
- &lea ("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
- &mov ($A,"edi");
- &data_byte(0xf3,0xa5); # rep movsl, memcpy
- &mov ("ecx",$pad/4);
- &data_byte(0xf3,0xab); # rep stosl, bzero pad
- # edi points at the end of padded ap copy...
-
- &mov ("ecx","ebp");
- &mov ("esi","ebx");
- &mov ($B,"edi");
- &data_byte(0xf3,0xa5); # rep movsl, memcpy
- &mov ("ecx",$pad/4);
- &data_byte(0xf3,0xab); # rep stosl, bzero pad
- # edi points at the end of padded bp copy...
-
- &mov ("ecx","ebp");
- &mov ("esi","edx");
- &mov ($M,"edi");
- &data_byte(0xf3,0xa5); # rep movsl, memcpy
- &mov ("ecx",$pad/4);
- &data_byte(0xf3,0xab); # rep stosl, bzero pad
- # edi points at the end of padded np copy...
-
- # let magic happen...
- &mov ("ecx","ebp");
- &mov ("esi","esp");
- &shl ("ecx",5); # convert word counter to bit counter
- &align (4);
- &data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
-
- &mov ("ecx","ebp");
- &lea ("esi",&DWP(64,"esp")); # tp
- # edi still points at the end of padded np copy...
- &neg ("ebp");
- &lea ("ebp",&DWP(-$pad,"edi","ebp",4)); # so just "rewind"
- &mov ("edi",$rp); # restore rp
- &xor ("edx","edx"); # i=0 and clear CF
-
-&set_label("sub",8);
- &mov ("eax",&DWP(0,"esi","edx",4));
- &sbb ("eax",&DWP(0,"ebp","edx",4));
- &mov (&DWP(0,"edi","edx",4),"eax"); # rp[i]=tp[i]-np[i]
- &lea ("edx",&DWP(1,"edx")); # i++
- &loop (&label("sub")); # doesn't affect CF!
-
- &mov ("eax",&DWP(0,"esi","edx",4)); # upmost overflow bit
- &sbb ("eax",0);
- &and ("esi","eax");
- &not ("eax");
- &mov ("ebp","edi");
- &and ("ebp","eax");
- &or ("esi","ebp"); # tp=carry?tp:rp
-
- &mov ("ecx","edx"); # num
- &xor ("edx","edx"); # i=0
-
-&set_label("copy",8);
- &mov ("eax",&DWP(0,"esi","edx",4));
- &mov (&DWP(64,"esp","edx",4),"ecx"); # zap tp
- &mov (&DWP(0,"edi","edx",4),"eax");
- &lea ("edx",&DWP(1,"edx")); # i++
- &loop (&label("copy"));
-
- &mov ("ebp",$sp);
- &xor ("eax","eax");
-
- &mov ("ecx",64/4);
- &mov ("edi","esp"); # zap frame including scratch area
- &data_byte(0xf3,0xab); # rep stosl, bzero
-
- # zap copies of ap, bp and np
- &lea ("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
- &lea ("ecx",&DWP(3*$pad/4,"edx","edx",2));
- &data_byte(0xf3,0xab); # rep stosl, bzero
-
- &mov ("esp","ebp");
- &inc ("eax"); # signal "done"
- &popf ();
-&set_label("leave");
-&function_end($func);
-
-&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
-
-&asm_finish();
diff --git a/crypto/openssl/crypto/bn/asm/x86-mont.pl b/crypto/openssl/crypto/bn/asm/x86-mont.pl
deleted file mode 100755
index 5cd3cd2..0000000
--- a/crypto/openssl/crypto/bn/asm/x86-mont.pl
+++ /dev/null
@@ -1,591 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# October 2005
-#
-# This is a "teaser" code, as it can be improved in several ways...
-# First of all non-SSE2 path should be implemented (yes, for now it
-# performs Montgomery multiplication/convolution only on SSE2-capable
-# CPUs such as P4, others fall down to original code). Then inner loop
-# can be unrolled and modulo-scheduled to improve ILP and possibly
-# moved to 128-bit XMM register bank (though it would require input
-# rearrangement and/or increase bus bandwidth utilization). Dedicated
-# squaring procedure should give further performance improvement...
-# Yet, for being draft, the code improves rsa512 *sign* benchmark by
-# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-)
-
-# December 2006
-#
-# Modulo-scheduling SSE2 loops results in further 15-20% improvement.
-# Integer-only code [being equipped with dedicated squaring procedure]
-# gives ~40% on rsa512 sign benchmark...
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "x86asm.pl";
-
-&asm_init($ARGV[0],$0);
-
-$sse2=0;
-for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-
-&external_label("OPENSSL_ia32cap_P") if ($sse2);
-
-&function_begin("bn_mul_mont");
-
-$i="edx";
-$j="ecx";
-$ap="esi"; $tp="esi"; # overlapping variables!!!
-$rp="edi"; $bp="edi"; # overlapping variables!!!
-$np="ebp";
-$num="ebx";
-
-$_num=&DWP(4*0,"esp"); # stack top layout
-$_rp=&DWP(4*1,"esp");
-$_ap=&DWP(4*2,"esp");
-$_bp=&DWP(4*3,"esp");
-$_np=&DWP(4*4,"esp");
-$_n0=&DWP(4*5,"esp"); $_n0q=&QWP(4*5,"esp");
-$_sp=&DWP(4*6,"esp");
-$_bpend=&DWP(4*7,"esp");
-$frame=32; # size of above frame rounded up to 16n
-
- &xor ("eax","eax");
- &mov ("edi",&wparam(5)); # int num
- &cmp ("edi",4);
- &jl (&label("just_leave"));
-
- &lea ("esi",&wparam(0)); # put aside pointer to argument block
- &lea ("edx",&wparam(1)); # load ap
- &mov ("ebp","esp"); # saved stack pointer!
- &add ("edi",2); # extra two words on top of tp
- &neg ("edi");
- &lea ("esp",&DWP(-$frame,"esp","edi",4)); # alloca($frame+4*(num+2))
- &neg ("edi");
-
- # minimize cache contention by arraning 2K window between stack
- # pointer and ap argument [np is also position sensitive vector,
- # but it's assumed to be near ap, as it's allocated at ~same
- # time].
- &mov ("eax","esp");
- &sub ("eax","edx");
- &and ("eax",2047);
- &sub ("esp","eax"); # this aligns sp and ap modulo 2048
-
- &xor ("edx","esp");
- &and ("edx",2048);
- &xor ("edx",2048);
- &sub ("esp","edx"); # this splits them apart modulo 4096
-
- &and ("esp",-64); # align to cache line
-
- ################################# load argument block...
- &mov ("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
- &mov ("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
- &mov ("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
- &mov ("edx",&DWP(3*4,"esi"));# const BN_ULONG *np
- &mov ("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
- #&mov ("edi",&DWP(5*4,"esi"));# int num
-
- &mov ("esi",&DWP(0,"esi")); # pull n0[0]
- &mov ($_rp,"eax"); # ... save a copy of argument block
- &mov ($_ap,"ebx");
- &mov ($_bp,"ecx");
- &mov ($_np,"edx");
- &mov ($_n0,"esi");
- &lea ($num,&DWP(-3,"edi")); # num=num-1 to assist modulo-scheduling
- #&mov ($_num,$num); # redundant as $num is not reused
- &mov ($_sp,"ebp"); # saved stack pointer!
-
-if($sse2) {
-$acc0="mm0"; # mmx register bank layout
-$acc1="mm1";
-$car0="mm2";
-$car1="mm3";
-$mul0="mm4";
-$mul1="mm5";
-$temp="mm6";
-$mask="mm7";
-
- &picmeup("eax","OPENSSL_ia32cap_P");
- &bt (&DWP(0,"eax"),26);
- &jnc (&label("non_sse2"));
-
- &mov ("eax",-1);
- &movd ($mask,"eax"); # mask 32 lower bits
-
- &mov ($ap,$_ap); # load input pointers
- &mov ($bp,$_bp);
- &mov ($np,$_np);
-
- &xor ($i,$i); # i=0
- &xor ($j,$j); # j=0
-
- &movd ($mul0,&DWP(0,$bp)); # bp[0]
- &movd ($mul1,&DWP(0,$ap)); # ap[0]
- &movd ($car1,&DWP(0,$np)); # np[0]
-
- &pmuludq($mul1,$mul0); # ap[0]*bp[0]
- &movq ($car0,$mul1);
- &movq ($acc0,$mul1); # I wish movd worked for
- &pand ($acc0,$mask); # inter-register transfers
-
- &pmuludq($mul1,$_n0q); # *=n0
-
- &pmuludq($car1,$mul1); # "t[0]"*np[0]*n0
- &paddq ($car1,$acc0);
-
- &movd ($acc1,&DWP(4,$np)); # np[1]
- &movd ($acc0,&DWP(4,$ap)); # ap[1]
-
- &psrlq ($car0,32);
- &psrlq ($car1,32);
-
- &inc ($j); # j++
-&set_label("1st",16);
- &pmuludq($acc0,$mul0); # ap[j]*bp[0]
- &pmuludq($acc1,$mul1); # np[j]*m1
- &paddq ($car0,$acc0); # +=c0
- &paddq ($car1,$acc1); # +=c1
-
- &movq ($acc0,$car0);
- &pand ($acc0,$mask);
- &movd ($acc1,&DWP(4,$np,$j,4)); # np[j+1]
- &paddq ($car1,$acc0); # +=ap[j]*bp[0];
- &movd ($acc0,&DWP(4,$ap,$j,4)); # ap[j+1]
- &psrlq ($car0,32);
- &movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[j-1]=
- &psrlq ($car1,32);
-
- &lea ($j,&DWP(1,$j));
- &cmp ($j,$num);
- &jl (&label("1st"));
-
- &pmuludq($acc0,$mul0); # ap[num-1]*bp[0]
- &pmuludq($acc1,$mul1); # np[num-1]*m1
- &paddq ($car0,$acc0); # +=c0
- &paddq ($car1,$acc1); # +=c1
-
- &movq ($acc0,$car0);
- &pand ($acc0,$mask);
- &paddq ($car1,$acc0); # +=ap[num-1]*bp[0];
- &movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[num-2]=
-
- &psrlq ($car0,32);
- &psrlq ($car1,32);
-
- &paddq ($car1,$car0);
- &movq (&QWP($frame,"esp",$num,4),$car1); # tp[num].tp[num-1]
-
- &inc ($i); # i++
-&set_label("outer");
- &xor ($j,$j); # j=0
-
- &movd ($mul0,&DWP(0,$bp,$i,4)); # bp[i]
- &movd ($mul1,&DWP(0,$ap)); # ap[0]
- &movd ($temp,&DWP($frame,"esp")); # tp[0]
- &movd ($car1,&DWP(0,$np)); # np[0]
- &pmuludq($mul1,$mul0); # ap[0]*bp[i]
-
- &paddq ($mul1,$temp); # +=tp[0]
- &movq ($acc0,$mul1);
- &movq ($car0,$mul1);
- &pand ($acc0,$mask);
-
- &pmuludq($mul1,$_n0q); # *=n0
-
- &pmuludq($car1,$mul1);
- &paddq ($car1,$acc0);
-
- &movd ($temp,&DWP($frame+4,"esp")); # tp[1]
- &movd ($acc1,&DWP(4,$np)); # np[1]
- &movd ($acc0,&DWP(4,$ap)); # ap[1]
-
- &psrlq ($car0,32);
- &psrlq ($car1,32);
- &paddq ($car0,$temp); # +=tp[1]
-
- &inc ($j); # j++
- &dec ($num);
-&set_label("inner");
- &pmuludq($acc0,$mul0); # ap[j]*bp[i]
- &pmuludq($acc1,$mul1); # np[j]*m1
- &paddq ($car0,$acc0); # +=c0
- &paddq ($car1,$acc1); # +=c1
-
- &movq ($acc0,$car0);
- &movd ($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1]
- &pand ($acc0,$mask);
- &movd ($acc1,&DWP(4,$np,$j,4)); # np[j+1]
- &paddq ($car1,$acc0); # +=ap[j]*bp[i]+tp[j]
- &movd ($acc0,&DWP(4,$ap,$j,4)); # ap[j+1]
- &psrlq ($car0,32);
- &movd (&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]=
- &psrlq ($car1,32);
- &paddq ($car0,$temp); # +=tp[j+1]
-
- &dec ($num);
- &lea ($j,&DWP(1,$j)); # j++
- &jnz (&label("inner"));
-
- &mov ($num,$j);
- &pmuludq($acc0,$mul0); # ap[num-1]*bp[i]
- &pmuludq($acc1,$mul1); # np[num-1]*m1
- &paddq ($car0,$acc0); # +=c0
- &paddq ($car1,$acc1); # +=c1
-
- &movq ($acc0,$car0);
- &pand ($acc0,$mask);
- &paddq ($car1,$acc0); # +=ap[num-1]*bp[i]+tp[num-1]
- &movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[num-2]=
- &psrlq ($car0,32);
- &psrlq ($car1,32);
-
- &movd ($temp,&DWP($frame+4,"esp",$num,4)); # += tp[num]
- &paddq ($car1,$car0);
- &paddq ($car1,$temp);
- &movq (&QWP($frame,"esp",$num,4),$car1); # tp[num].tp[num-1]
-
- &lea ($i,&DWP(1,$i)); # i++
- &cmp ($i,$num);
- &jle (&label("outer"));
-
- &emms (); # done with mmx bank
- &jmp (&label("common_tail"));
-
-&set_label("non_sse2",16);
-}
-
-if (0) {
- &mov ("esp",$_sp);
- &xor ("eax","eax"); # signal "not fast enough [yet]"
- &jmp (&label("just_leave"));
- # While the below code provides competitive performance for
- # all key lengthes on modern Intel cores, it's still more
- # than 10% slower for 4096-bit key elsewhere:-( "Competitive"
- # means compared to the original integer-only assembler.
- # 512-bit RSA sign is better by ~40%, but that's about all
- # one can say about all CPUs...
-} else {
-$inp="esi"; # integer path uses these registers differently
-$word="edi";
-$carry="ebp";
-
- &mov ($inp,$_ap);
- &lea ($carry,&DWP(1,$num));
- &mov ($word,$_bp);
- &xor ($j,$j); # j=0
- &mov ("edx",$inp);
- &and ($carry,1); # see if num is even
- &sub ("edx",$word); # see if ap==bp
- &lea ("eax",&DWP(4,$word,$num,4)); # &bp[num]
- &or ($carry,"edx");
- &mov ($word,&DWP(0,$word)); # bp[0]
- &jz (&label("bn_sqr_mont"));
- &mov ($_bpend,"eax");
- &mov ("eax",&DWP(0,$inp));
- &xor ("edx","edx");
-
-&set_label("mull",16);
- &mov ($carry,"edx");
- &mul ($word); # ap[j]*bp[0]
- &add ($carry,"eax");
- &lea ($j,&DWP(1,$j));
- &adc ("edx",0);
- &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j+1]
- &cmp ($j,$num);
- &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
- &jl (&label("mull"));
-
- &mov ($carry,"edx");
- &mul ($word); # ap[num-1]*bp[0]
- &mov ($word,$_n0);
- &add ("eax",$carry);
- &mov ($inp,$_np);
- &adc ("edx",0);
- &imul ($word,&DWP($frame,"esp")); # n0*tp[0]
-
- &mov (&DWP($frame,"esp",$num,4),"eax"); # tp[num-1]=
- &xor ($j,$j);
- &mov (&DWP($frame+4,"esp",$num,4),"edx"); # tp[num]=
- &mov (&DWP($frame+8,"esp",$num,4),$j); # tp[num+1]=
-
- &mov ("eax",&DWP(0,$inp)); # np[0]
- &mul ($word); # np[0]*m
- &add ("eax",&DWP($frame,"esp")); # +=tp[0]
- &mov ("eax",&DWP(4,$inp)); # np[1]
- &adc ("edx",0);
- &inc ($j);
-
- &jmp (&label("2ndmadd"));
-
-&set_label("1stmadd",16);
- &mov ($carry,"edx");
- &mul ($word); # ap[j]*bp[i]
- &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
- &lea ($j,&DWP(1,$j));
- &adc ("edx",0);
- &add ($carry,"eax");
- &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j+1]
- &adc ("edx",0);
- &cmp ($j,$num);
- &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
- &jl (&label("1stmadd"));
-
- &mov ($carry,"edx");
- &mul ($word); # ap[num-1]*bp[i]
- &add ("eax",&DWP($frame,"esp",$num,4)); # +=tp[num-1]
- &mov ($word,$_n0);
- &adc ("edx",0);
- &mov ($inp,$_np);
- &add ($carry,"eax");
- &adc ("edx",0);
- &imul ($word,&DWP($frame,"esp")); # n0*tp[0]
-
- &xor ($j,$j);
- &add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num]
- &mov (&DWP($frame,"esp",$num,4),$carry); # tp[num-1]=
- &adc ($j,0);
- &mov ("eax",&DWP(0,$inp)); # np[0]
- &mov (&DWP($frame+4,"esp",$num,4),"edx"); # tp[num]=
- &mov (&DWP($frame+8,"esp",$num,4),$j); # tp[num+1]=
-
- &mul ($word); # np[0]*m
- &add ("eax",&DWP($frame,"esp")); # +=tp[0]
- &mov ("eax",&DWP(4,$inp)); # np[1]
- &adc ("edx",0);
- &mov ($j,1);
-
-&set_label("2ndmadd",16);
- &mov ($carry,"edx");
- &mul ($word); # np[j]*m
- &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
- &lea ($j,&DWP(1,$j));
- &adc ("edx",0);
- &add ($carry,"eax");
- &mov ("eax",&DWP(0,$inp,$j,4)); # np[j+1]
- &adc ("edx",0);
- &cmp ($j,$num);
- &mov (&DWP($frame-8,"esp",$j,4),$carry); # tp[j-1]=
- &jl (&label("2ndmadd"));
-
- &mov ($carry,"edx");
- &mul ($word); # np[j]*m
- &add ($carry,&DWP($frame,"esp",$num,4)); # +=tp[num-1]
- &adc ("edx",0);
- &add ($carry,"eax");
- &adc ("edx",0);
- &mov (&DWP($frame-4,"esp",$num,4),$carry); # tp[num-2]=
-
- &xor ("eax","eax");
- &mov ($j,$_bp); # &bp[i]
- &add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num]
- &adc ("eax",&DWP($frame+8,"esp",$num,4)); # +=tp[num+1]
- &lea ($j,&DWP(4,$j));
- &mov (&DWP($frame,"esp",$num,4),"edx"); # tp[num-1]=
- &cmp ($j,$_bpend);
- &mov (&DWP($frame+4,"esp",$num,4),"eax"); # tp[num]=
- &je (&label("common_tail"));
-
- &mov ($word,&DWP(0,$j)); # bp[i+1]
- &mov ($inp,$_ap);
- &mov ($_bp,$j); # &bp[++i]
- &xor ($j,$j);
- &xor ("edx","edx");
- &mov ("eax",&DWP(0,$inp));
- &jmp (&label("1stmadd"));
-
-&set_label("bn_sqr_mont",16);
-$sbit=$num;
- &mov ($_num,$num);
- &mov ($_bp,$j); # i=0
-
- &mov ("eax",$word); # ap[0]
- &mul ($word); # ap[0]*ap[0]
- &mov (&DWP($frame,"esp"),"eax"); # tp[0]=
- &mov ($sbit,"edx");
- &shr ("edx",1);
- &and ($sbit,1);
- &inc ($j);
-&set_label("sqr",16);
- &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j]
- &mov ($carry,"edx");
- &mul ($word); # ap[j]*ap[0]
- &add ("eax",$carry);
- &lea ($j,&DWP(1,$j));
- &adc ("edx",0);
- &lea ($carry,&DWP(0,$sbit,"eax",2));
- &shr ("eax",31);
- &cmp ($j,$_num);
- &mov ($sbit,"eax");
- &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
- &jl (&label("sqr"));
-
- &mov ("eax",&DWP(0,$inp,$j,4)); # ap[num-1]
- &mov ($carry,"edx");
- &mul ($word); # ap[num-1]*ap[0]
- &add ("eax",$carry);
- &mov ($word,$_n0);
- &adc ("edx",0);
- &mov ($inp,$_np);
- &lea ($carry,&DWP(0,$sbit,"eax",2));
- &imul ($word,&DWP($frame,"esp")); # n0*tp[0]
- &shr ("eax",31);
- &mov (&DWP($frame,"esp",$j,4),$carry); # tp[num-1]=
-
- &lea ($carry,&DWP(0,"eax","edx",2));
- &mov ("eax",&DWP(0,$inp)); # np[0]
- &shr ("edx",31);
- &mov (&DWP($frame+4,"esp",$j,4),$carry); # tp[num]=
- &mov (&DWP($frame+8,"esp",$j,4),"edx"); # tp[num+1]=
-
- &mul ($word); # np[0]*m
- &add ("eax",&DWP($frame,"esp")); # +=tp[0]
- &mov ($num,$j);
- &adc ("edx",0);
- &mov ("eax",&DWP(4,$inp)); # np[1]
- &mov ($j,1);
-
-&set_label("3rdmadd",16);
- &mov ($carry,"edx");
- &mul ($word); # np[j]*m
- &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
- &adc ("edx",0);
- &add ($carry,"eax");
- &mov ("eax",&DWP(4,$inp,$j,4)); # np[j+1]
- &adc ("edx",0);
- &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j-1]=
-
- &mov ($carry,"edx");
- &mul ($word); # np[j+1]*m
- &add ($carry,&DWP($frame+4,"esp",$j,4)); # +=tp[j+1]
- &lea ($j,&DWP(2,$j));
- &adc ("edx",0);
- &add ($carry,"eax");
- &mov ("eax",&DWP(0,$inp,$j,4)); # np[j+2]
- &adc ("edx",0);
- &cmp ($j,$num);
- &mov (&DWP($frame-8,"esp",$j,4),$carry); # tp[j]=
- &jl (&label("3rdmadd"));
-
- &mov ($carry,"edx");
- &mul ($word); # np[j]*m
- &add ($carry,&DWP($frame,"esp",$num,4)); # +=tp[num-1]
- &adc ("edx",0);
- &add ($carry,"eax");
- &adc ("edx",0);
- &mov (&DWP($frame-4,"esp",$num,4),$carry); # tp[num-2]=
-
- &mov ($j,$_bp); # i
- &xor ("eax","eax");
- &mov ($inp,$_ap);
- &add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num]
- &adc ("eax",&DWP($frame+8,"esp",$num,4)); # +=tp[num+1]
- &mov (&DWP($frame,"esp",$num,4),"edx"); # tp[num-1]=
- &cmp ($j,$num);
- &mov (&DWP($frame+4,"esp",$num,4),"eax"); # tp[num]=
- &je (&label("common_tail"));
-
- &mov ($word,&DWP(4,$inp,$j,4)); # ap[i]
- &lea ($j,&DWP(1,$j));
- &mov ("eax",$word);
- &mov ($_bp,$j); # ++i
- &mul ($word); # ap[i]*ap[i]
- &add ("eax",&DWP($frame,"esp",$j,4)); # +=tp[i]
- &adc ("edx",0);
- &mov (&DWP($frame,"esp",$j,4),"eax"); # tp[i]=
- &xor ($carry,$carry);
- &cmp ($j,$num);
- &lea ($j,&DWP(1,$j));
- &je (&label("sqrlast"));
-
- &mov ($sbit,"edx"); # zaps $num
- &shr ("edx",1);
- &and ($sbit,1);
-&set_label("sqradd",16);
- &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j]
- &mov ($carry,"edx");
- &mul ($word); # ap[j]*ap[i]
- &add ("eax",$carry);
- &lea ($carry,&DWP(0,"eax","eax"));
- &adc ("edx",0);
- &shr ("eax",31);
- &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
- &lea ($j,&DWP(1,$j));
- &adc ("eax",0);
- &add ($carry,$sbit);
- &adc ("eax",0);
- &cmp ($j,$_num);
- &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
- &mov ($sbit,"eax");
- &jle (&label("sqradd"));
-
- &mov ($carry,"edx");
- &lea ("edx",&DWP(0,$sbit,"edx",2));
- &shr ($carry,31);
-&set_label("sqrlast");
- &mov ($word,$_n0);
- &mov ($inp,$_np);
- &imul ($word,&DWP($frame,"esp")); # n0*tp[0]
-
- &add ("edx",&DWP($frame,"esp",$j,4)); # +=tp[num]
- &mov ("eax",&DWP(0,$inp)); # np[0]
- &adc ($carry,0);
- &mov (&DWP($frame,"esp",$j,4),"edx"); # tp[num]=
- &mov (&DWP($frame+4,"esp",$j,4),$carry); # tp[num+1]=
-
- &mul ($word); # np[0]*m
- &add ("eax",&DWP($frame,"esp")); # +=tp[0]
- &lea ($num,&DWP(-1,$j));
- &adc ("edx",0);
- &mov ($j,1);
- &mov ("eax",&DWP(4,$inp)); # np[1]
-
- &jmp (&label("3rdmadd"));
-}
-
-&set_label("common_tail",16);
- &mov ($np,$_np); # load modulus pointer
- &mov ($rp,$_rp); # load result pointer
- &lea ($tp,&DWP($frame,"esp")); # [$ap and $bp are zapped]
-
- &mov ("eax",&DWP(0,$tp)); # tp[0]
- &mov ($j,$num); # j=num-1
- &xor ($i,$i); # i=0 and clear CF!
-
-&set_label("sub",16);
- &sbb ("eax",&DWP(0,$np,$i,4));
- &mov (&DWP(0,$rp,$i,4),"eax"); # rp[i]=tp[i]-np[i]
- &dec ($j); # doesn't affect CF!
- &mov ("eax",&DWP(4,$tp,$i,4)); # tp[i+1]
- &lea ($i,&DWP(1,$i)); # i++
- &jge (&label("sub"));
-
- &sbb ("eax",0); # handle upmost overflow bit
- &and ($tp,"eax");
- &not ("eax");
- &mov ($np,$rp);
- &and ($np,"eax");
- &or ($tp,$np); # tp=carry?tp:rp
-
-&set_label("copy",16); # copy or in-place refresh
- &mov ("eax",&DWP(0,$tp,$num,4));
- &mov (&DWP(0,$rp,$num,4),"eax"); # rp[i]=tp[i]
- &mov (&DWP($frame,"esp",$num,4),$j); # zap temporary vector
- &dec ($num);
- &jge (&label("copy"));
-
- &mov ("esp",$_sp); # pull saved stack pointer
- &mov ("eax",1);
-&set_label("just_leave");
-&function_end("bn_mul_mont");
-
-&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
-
-&asm_finish();
diff --git a/crypto/openssl/crypto/bn/asm/x86_64-gcc.c b/crypto/openssl/crypto/bn/asm/x86_64-gcc.c
index f13f52d..b1b8a11 100644
--- a/crypto/openssl/crypto/bn/asm/x86_64-gcc.c
+++ b/crypto/openssl/crypto/bn/asm/x86_64-gcc.c
@@ -1,3 +1,4 @@
+#include "../bn_lcl.h"
#ifdef __SUNPRO_C
# include "../bn_asm.c" /* kind of dirty hack for Sun Studio */
#else
@@ -56,6 +57,10 @@
#define BN_ULONG unsigned long
+#undef mul
+#undef mul_add
+#undef sqr
+
/*
* "m"(a), "+m"(r) is the way to favor DirectPath µ-code;
* "g"(0) let the compiler to decide where does it
@@ -97,7 +102,7 @@
: "a"(a) \
: "cc");
-BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1=0;
@@ -121,7 +126,7 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
return(c1);
}
-BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1=0;
@@ -144,7 +149,7 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
return(c1);
}
-void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
{
if (n <= 0) return;
@@ -175,7 +180,7 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
return ret;
}
-BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
+BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
{ BN_ULONG ret=0,i=0;
if (n <= 0) return 0;
@@ -198,7 +203,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
}
#ifndef SIMICS
-BN_ULONG bn_sub_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
+BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
{ BN_ULONG ret=0,i=0;
if (n <= 0) return 0;
@@ -485,7 +490,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
r[7]=c2;
}
-void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
{
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
@@ -561,7 +566,7 @@ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
r[15]=c1;
}
-void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
{
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
diff --git a/crypto/openssl/crypto/bn/bn_div.c b/crypto/openssl/crypto/bn/bn_div.c
index 1e8e576..78c6507 100644
--- a/crypto/openssl/crypto/bn/bn_div.c
+++ b/crypto/openssl/crypto/bn/bn_div.c
@@ -102,7 +102,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
/* The next 2 are needed so we can do a dv->d[0]|=1 later
* since BN_lshift1 will only work once there is a value :-) */
BN_zero(dv);
- bn_wexpand(dv,1);
+ if(bn_wexpand(dv,1) == NULL) goto end;
dv->top=1;
if (!BN_lshift(D,D,nm-nd)) goto end;
@@ -229,7 +229,8 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
if (dv == NULL)
res=BN_CTX_get(ctx);
else res=dv;
- if (sdiv == NULL || res == NULL) goto err;
+ if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
+ goto err;
/* First we normalise the numbers */
norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
@@ -336,7 +337,10 @@ X) -> 0x%08X\n",
t2 -= d1;
}
#else /* !BN_LLONG */
- BN_ULONG t2l,t2h,ql,qh;
+ BN_ULONG t2l,t2h;
+#if !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
+ BN_ULONG ql,qh;
+#endif
q=bn_div_words(n0,n1,d0);
#ifdef BN_DEBUG_LEVITTE
@@ -560,7 +564,10 @@ X) -> 0x%08X\n",
t2 -= d1;
}
#else /* !BN_LLONG */
- BN_ULONG t2l,t2h,ql,qh;
+ BN_ULONG t2l,t2h;
+#if !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
+ BN_ULONG ql,qh;
+#endif
q=bn_div_words(n0,n1,d0);
#ifdef BN_DEBUG_LEVITTE
diff --git a/crypto/openssl/crypto/bn/bn_exp.c b/crypto/openssl/crypto/bn/bn_exp.c
index 70a33f0..d9b6c73 100644
--- a/crypto/openssl/crypto/bn/bn_exp.c
+++ b/crypto/openssl/crypto/bn/bn_exp.c
@@ -134,7 +134,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
rr = BN_CTX_get(ctx);
else
rr = r;
- if ((v = BN_CTX_get(ctx)) == NULL) goto err;
+ v = BN_CTX_get(ctx);
+ if (rr == NULL || v == NULL) goto err;
if (BN_copy(v,a) == NULL) goto err;
bits=BN_num_bits(p);
diff --git a/crypto/openssl/crypto/bn/bn_gf2m.c b/crypto/openssl/crypto/bn/bn_gf2m.c
index 306f029..ae642cc 100644
--- a/crypto/openssl/crypto/bn/bn_gf2m.c
+++ b/crypto/openssl/crypto/bn/bn_gf2m.c
@@ -294,7 +294,8 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
if (a->top < b->top) { at = b; bt = a; }
else { at = a; bt = b; }
- bn_wexpand(r, at->top);
+ if(bn_wexpand(r, at->top) == NULL)
+ return 0;
for (i = 0; i < bt->top; i++)
{
diff --git a/crypto/openssl/crypto/bn/bn_mul.c b/crypto/openssl/crypto/bn/bn_mul.c
index b848c8c..a0e9ec3 100644
--- a/crypto/openssl/crypto/bn/bn_mul.c
+++ b/crypto/openssl/crypto/bn/bn_mul.c
@@ -1028,17 +1028,19 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
assert(j <= al || j <= bl);
k = j+j;
t = BN_CTX_get(ctx);
+ if (t == NULL)
+ goto err;
if (al > j || bl > j)
{
- bn_wexpand(t,k*4);
- bn_wexpand(rr,k*4);
+ if (bn_wexpand(t,k*4) == NULL) goto err;
+ if (bn_wexpand(rr,k*4) == NULL) goto err;
bn_mul_part_recursive(rr->d,a->d,b->d,
j,al-j,bl-j,t->d);
}
else /* al <= j || bl <= j */
{
- bn_wexpand(t,k*2);
- bn_wexpand(rr,k*2);
+ if (bn_wexpand(t,k*2) == NULL) goto err;
+ if (bn_wexpand(rr,k*2) == NULL) goto err;
bn_mul_recursive(rr->d,a->d,b->d,
j,al-j,bl-j,t->d);
}
diff --git a/crypto/openssl/crypto/bn/bntest.c b/crypto/openssl/crypto/bn/bntest.c
index cf19038..d41daac 100644
--- a/crypto/openssl/crypto/bn/bntest.c
+++ b/crypto/openssl/crypto/bn/bntest.c
@@ -1027,7 +1027,7 @@ int test_exp(BIO *bp, BN_CTX *ctx)
BN_bntest_rand(a,20+i*5,0,0); /**/
BN_bntest_rand(b,2+i,0,0); /**/
- if (!BN_exp(d,a,b,ctx))
+ if (BN_exp(d,a,b,ctx) <= 0)
return(0);
if (bp != NULL)
diff --git a/crypto/openssl/crypto/camellia/Makefile b/crypto/openssl/crypto/camellia/Makefile
index dfb1295..dfd1a75 100644
--- a/crypto/openssl/crypto/camellia/Makefile
+++ b/crypto/openssl/crypto/camellia/Makefile
@@ -96,8 +96,11 @@ cmll_ctr.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
cmll_ctr.o: ../../include/openssl/opensslconf.h cmll_ctr.c cmll_locl.h
cmll_ecb.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
cmll_ecb.o: ../../include/openssl/opensslconf.h cmll_ecb.c cmll_locl.h
-cmll_misc.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
+cmll_misc.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
+cmll_misc.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
cmll_misc.o: ../../include/openssl/opensslconf.h
-cmll_misc.o: ../../include/openssl/opensslv.h cmll_locl.h cmll_misc.c
+cmll_misc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cmll_misc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cmll_misc.o: ../../include/openssl/symhacks.h cmll_locl.h cmll_misc.c
cmll_ofb.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
cmll_ofb.o: ../../include/openssl/opensslconf.h cmll_locl.h cmll_ofb.c
diff --git a/crypto/openssl/crypto/camellia/asm/cmll-x86.pl b/crypto/openssl/crypto/camellia/asm/cmll-x86.pl
deleted file mode 100755
index 0812815..0000000
--- a/crypto/openssl/crypto/camellia/asm/cmll-x86.pl
+++ /dev/null
@@ -1,1138 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
-#
-# This module may be used under the terms of either the GNU General
-# Public License version 2 or later, the GNU Lesser General Public
-# License version 2.1 or later, the Mozilla Public License version
-# 1.1 or the BSD License. The exact terms of either license are
-# distributed along with this module. For further details see
-# http://www.openssl.org/~appro/camellia/.
-# ====================================================================
-
-# Performance in cycles per processed byte (less is better) in
-# 'openssl speed ...' benchmark:
-#
-# AMD K8 Core2 PIII P4
-# -evp camellia-128-ecb 21.5 22.8 27.0 28.9
-# + over gcc 3.4.6 +90/11% +70/10% +53/4% +160/64%
-# + over icc 8.0 +48/19% +21/15% +21/17% +55/37%
-#
-# camellia-128-cbc 17.3 21.1 23.9 25.9
-#
-# 128-bit key setup 196 280 256 240 cycles/key
-# + over gcc 3.4.6 +30/0% +17/11% +11/0% +63/40%
-# + over icc 8.0 +18/3% +10/0% +10/3% +21/10%
-#
-# Pairs of numbers in "+" rows represent performance improvement over
-# compiler generated position-independent code, PIC, and non-PIC
-# respectively. PIC results are of greater relevance, as this module
-# is position-independent, i.e. suitable for a shared library or PIE.
-# Position independence "costs" one register, which is why compilers
-# are so close with non-PIC results, they have an extra register to
-# spare. CBC results are better than ECB ones thanks to "zero-copy"
-# private _x86_* interface, and are ~30-40% better than with compiler
-# generated cmll_cbc.o, and reach ~80-90% of x86_64 performance on
-# same CPU (where applicable).
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "x86asm.pl";
-
-$OPENSSL=1;
-
-&asm_init($ARGV[0],"cmll-586.pl",$ARGV[$#ARGV] eq "386");
-
-@T=("eax","ebx","ecx","edx");
-$idx="esi";
-$key="edi";
-$Tbl="ebp";
-
-# stack frame layout in _x86_Camellia_* routines, frame is allocated
-# by caller
-$__ra=&DWP(0,"esp"); # return address
-$__s0=&DWP(4,"esp"); # s0 backing store
-$__s1=&DWP(8,"esp"); # s1 backing store
-$__s2=&DWP(12,"esp"); # s2 backing store
-$__s3=&DWP(16,"esp"); # s3 backing store
-$__end=&DWP(20,"esp"); # pointer to end/start of key schedule
-
-# stack frame layout in Camellia_[en|crypt] routines, which differs from
-# above by 4 and overlaps by pointer to end/start of key schedule
-$_end=&DWP(16,"esp");
-$_esp=&DWP(20,"esp");
-
-# const unsigned int Camellia_SBOX[4][256];
-# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
-# and [2][] - with [3][]. This is done to optimize code size.
-$SBOX1_1110=0; # Camellia_SBOX[0]
-$SBOX4_4404=4; # Camellia_SBOX[1]
-$SBOX2_0222=2048; # Camellia_SBOX[2]
-$SBOX3_3033=2052; # Camellia_SBOX[3]
-&static_label("Camellia_SIGMA");
-&static_label("Camellia_SBOX");
-
-sub Camellia_Feistel {
-my $i=@_[0];
-my $seed=defined(@_[1])?@_[1]:0;
-my $scale=$seed<0?-8:8;
-my $frame=defined(@_[2])?@_[2]:0;
-my $j=($i&1)*2;
-my $t0=@T[($j)%4],$t1=@T[($j+1)%4],$t2=@T[($j+2)%4],$t3=@T[($j+3)%4];
-
- &xor ($t0,$idx); # t0^=key[0]
- &xor ($t1,&DWP($seed+$i*$scale+4,$key)); # t1^=key[1]
- &movz ($idx,&HB($t0)); # (t0>>8)&0xff
- &mov ($t3,&DWP($SBOX3_3033,$Tbl,$idx,8)); # t3=SBOX3_3033[0]
- &movz ($idx,&LB($t0)); # (t0>>0)&0xff
- &xor ($t3,&DWP($SBOX4_4404,$Tbl,$idx,8)); # t3^=SBOX4_4404[0]
- &shr ($t0,16);
- &movz ($idx,&LB($t1)); # (t1>>0)&0xff
- &mov ($t2,&DWP($SBOX1_1110,$Tbl,$idx,8)); # t2=SBOX1_1110[1]
- &movz ($idx,&HB($t0)); # (t0>>24)&0xff
- &xor ($t3,&DWP($SBOX1_1110,$Tbl,$idx,8)); # t3^=SBOX1_1110[0]
- &movz ($idx,&HB($t1)); # (t1>>8)&0xff
- &xor ($t2,&DWP($SBOX4_4404,$Tbl,$idx,8)); # t2^=SBOX4_4404[1]
- &shr ($t1,16);
- &movz ($t0,&LB($t0)); # (t0>>16)&0xff
- &xor ($t3,&DWP($SBOX2_0222,$Tbl,$t0,8)); # t3^=SBOX2_0222[0]
- &movz ($idx,&HB($t1)); # (t1>>24)&0xff
- &mov ($t0,&DWP($frame+4*(($j+3)%4),"esp")); # prefetch "s3"
- &xor ($t2,$t3); # t2^=t3
- &rotr ($t3,8); # t3=RightRotate(t3,8)
- &xor ($t2,&DWP($SBOX2_0222,$Tbl,$idx,8)); # t2^=SBOX2_0222[1]
- &movz ($idx,&LB($t1)); # (t1>>16)&0xff
- &mov ($t1,&DWP($frame+4*(($j+2)%4),"esp")); # prefetch "s2"
- &xor ($t3,$t0); # t3^=s3
- &xor ($t2,&DWP($SBOX3_3033,$Tbl,$idx,8)); # t2^=SBOX3_3033[1]
- &mov ($idx,&DWP($seed+($i+1)*$scale,$key)); # prefetch key[i+1]
- &xor ($t3,$t2); # t3^=t2
- &mov (&DWP($frame+4*(($j+3)%4),"esp"),$t3); # s3=t3
- &xor ($t2,$t1); # t2^=s2
- &mov (&DWP($frame+4*(($j+2)%4),"esp"),$t2); # s2=t2
-}
-
-# void Camellia_EncryptBlock_Rounds(
-# int grandRounds,
-# const Byte plaintext[],
-# const KEY_TABLE_TYPE keyTable,
-# Byte ciphertext[])
-&function_begin("Camellia_EncryptBlock_Rounds");
- &mov ("eax",&wparam(0)); # load grandRounds
- &mov ($idx,&wparam(1)); # load plaintext pointer
- &mov ($key,&wparam(2)); # load key schedule pointer
-
- &mov ("ebx","esp");
- &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra
- &and ("esp",-64);
-
- # place stack frame just "above mod 1024" the key schedule
- # this ensures that cache associativity of 2 suffices
- &lea ("ecx",&DWP(-64-63,$key));
- &sub ("ecx","esp");
- &neg ("ecx");
- &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line
- &sub ("esp","ecx");
- &add ("esp",4); # 4 is reserved for callee's return address
-
- &shl ("eax",6);
- &lea ("eax",&DWP(0,$key,"eax"));
- &mov ($_esp,"ebx"); # save %esp
- &mov ($_end,"eax"); # save keyEnd
-
- &call (&label("pic_point"));
- &set_label("pic_point");
- &blindpop($Tbl);
- &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-
- &mov (@T[0],&DWP(0,$idx)); # load plaintext
- &mov (@T[1],&DWP(4,$idx));
- &mov (@T[2],&DWP(8,$idx));
- &bswap (@T[0]);
- &mov (@T[3],&DWP(12,$idx));
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
-
- &call ("_x86_Camellia_encrypt");
-
- &mov ("esp",$_esp);
- &bswap (@T[0]);
- &mov ($idx,&wparam(3)); # load ciphertext pointer
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
- &mov (&DWP(0,$idx),@T[0]); # write ciphertext
- &mov (&DWP(4,$idx),@T[1]);
- &mov (&DWP(8,$idx),@T[2]);
- &mov (&DWP(12,$idx),@T[3]);
-&function_end("Camellia_EncryptBlock_Rounds");
-# V1.x API
-&function_begin_B("Camellia_EncryptBlock");
- &mov ("eax",128);
- &sub ("eax",&wparam(0)); # load keyBitLength
- &mov ("eax",3);
- &adc ("eax",0); # keyBitLength==128?3:4
- &mov (&wparam(0),"eax");
- &jmp (&label("Camellia_EncryptBlock_Rounds"));
-&function_end_B("Camellia_EncryptBlock");
-
-if ($OPENSSL) {
-# void Camellia_encrypt(
-# const unsigned char *in,
-# unsigned char *out,
-# const CAMELLIA_KEY *key)
-&function_begin("Camellia_encrypt");
- &mov ($idx,&wparam(0)); # load plaintext pointer
- &mov ($key,&wparam(2)); # load key schedule pointer
-
- &mov ("ebx","esp");
- &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra
- &and ("esp",-64);
- &mov ("eax",&DWP(272,$key)); # load grandRounds counter
-
- # place stack frame just "above mod 1024" the key schedule
- # this ensures that cache associativity of 2 suffices
- &lea ("ecx",&DWP(-64-63,$key));
- &sub ("ecx","esp");
- &neg ("ecx");
- &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line
- &sub ("esp","ecx");
- &add ("esp",4); # 4 is reserved for callee's return address
-
- &shl ("eax",6);
- &lea ("eax",&DWP(0,$key,"eax"));
- &mov ($_esp,"ebx"); # save %esp
- &mov ($_end,"eax"); # save keyEnd
-
- &call (&label("pic_point"));
- &set_label("pic_point");
- &blindpop($Tbl);
- &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-
- &mov (@T[0],&DWP(0,$idx)); # load plaintext
- &mov (@T[1],&DWP(4,$idx));
- &mov (@T[2],&DWP(8,$idx));
- &bswap (@T[0]);
- &mov (@T[3],&DWP(12,$idx));
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
-
- &call ("_x86_Camellia_encrypt");
-
- &mov ("esp",$_esp);
- &bswap (@T[0]);
- &mov ($idx,&wparam(1)); # load ciphertext pointer
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
- &mov (&DWP(0,$idx),@T[0]); # write ciphertext
- &mov (&DWP(4,$idx),@T[1]);
- &mov (&DWP(8,$idx),@T[2]);
- &mov (&DWP(12,$idx),@T[3]);
-&function_end("Camellia_encrypt");
-}
-
-&function_begin_B("_x86_Camellia_encrypt");
- &xor (@T[0],&DWP(0,$key)); # ^=key[0-3]
- &xor (@T[1],&DWP(4,$key));
- &xor (@T[2],&DWP(8,$key));
- &xor (@T[3],&DWP(12,$key));
- &mov ($idx,&DWP(16,$key)); # prefetch key[4]
-
- &mov ($__s0,@T[0]); # save s[0-3]
- &mov ($__s1,@T[1]);
- &mov ($__s2,@T[2]);
- &mov ($__s3,@T[3]);
-
-&set_label("loop",16);
- for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16,4); }
-
- &add ($key,16*4);
- &cmp ($key,$__end);
- &je (&label("done"));
-
- # @T[0-1] are preloaded, $idx is preloaded with key[0]
- &and ($idx,@T[0]);
- &mov (@T[3],$__s3);
- &rotl ($idx,1);
- &mov (@T[2],@T[3]);
- &xor (@T[1],$idx);
- &or (@T[2],&DWP(12,$key));
- &mov ($__s1,@T[1]); # s1^=LeftRotate(s0&key[0],1);
- &xor (@T[2],$__s2);
-
- &mov ($idx,&DWP(4,$key));
- &mov ($__s2,@T[2]); # s2^=s3|key[3];
- &or ($idx,@T[1]);
- &and (@T[2],&DWP(8,$key));
- &xor (@T[0],$idx);
- &rotl (@T[2],1);
- &mov ($__s0,@T[0]); # s0^=s1|key[1];
- &xor (@T[3],@T[2]);
- &mov ($idx,&DWP(16,$key)); # prefetch key[4]
- &mov ($__s3,@T[3]); # s3^=LeftRotate(s2&key[2],1);
- &jmp (&label("loop"));
-
-&set_label("done",8);
- &mov (@T[2],@T[0]); # SwapHalf
- &mov (@T[3],@T[1]);
- &mov (@T[0],$__s2);
- &mov (@T[1],$__s3);
- &xor (@T[0],$idx); # $idx is preloaded with key[0]
- &xor (@T[1],&DWP(4,$key));
- &xor (@T[2],&DWP(8,$key));
- &xor (@T[3],&DWP(12,$key));
- &ret ();
-&function_end_B("_x86_Camellia_encrypt");
-
-# void Camellia_DecryptBlock_Rounds(
-# int grandRounds,
-# const Byte ciphertext[],
-# const KEY_TABLE_TYPE keyTable,
-# Byte plaintext[])
-&function_begin("Camellia_DecryptBlock_Rounds");
- &mov ("eax",&wparam(0)); # load grandRounds
- &mov ($idx,&wparam(1)); # load ciphertext pointer
- &mov ($key,&wparam(2)); # load key schedule pointer
-
- &mov ("ebx","esp");
- &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra
- &and ("esp",-64);
-
- # place stack frame just "above mod 1024" the key schedule
- # this ensures that cache associativity of 2 suffices
- &lea ("ecx",&DWP(-64-63,$key));
- &sub ("ecx","esp");
- &neg ("ecx");
- &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line
- &sub ("esp","ecx");
- &add ("esp",4); # 4 is reserved for callee's return address
-
- &shl ("eax",6);
- &mov (&DWP(4*4,"esp"),$key); # save keyStart
- &lea ($key,&DWP(0,$key,"eax"));
- &mov (&DWP(5*4,"esp"),"ebx");# save %esp
-
- &call (&label("pic_point"));
- &set_label("pic_point");
- &blindpop($Tbl);
- &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-
- &mov (@T[0],&DWP(0,$idx)); # load ciphertext
- &mov (@T[1],&DWP(4,$idx));
- &mov (@T[2],&DWP(8,$idx));
- &bswap (@T[0]);
- &mov (@T[3],&DWP(12,$idx));
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
-
- &call ("_x86_Camellia_decrypt");
-
- &mov ("esp",&DWP(5*4,"esp"));
- &bswap (@T[0]);
- &mov ($idx,&wparam(3)); # load plaintext pointer
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
- &mov (&DWP(0,$idx),@T[0]); # write plaintext
- &mov (&DWP(4,$idx),@T[1]);
- &mov (&DWP(8,$idx),@T[2]);
- &mov (&DWP(12,$idx),@T[3]);
-&function_end("Camellia_DecryptBlock_Rounds");
-# V1.x API
-&function_begin_B("Camellia_DecryptBlock");
- &mov ("eax",128);
- &sub ("eax",&wparam(0)); # load keyBitLength
- &mov ("eax",3);
- &adc ("eax",0); # keyBitLength==128?3:4
- &mov (&wparam(0),"eax");
- &jmp (&label("Camellia_DecryptBlock_Rounds"));
-&function_end_B("Camellia_DecryptBlock");
-
-if ($OPENSSL) {
-# void Camellia_decrypt(
-# const unsigned char *in,
-# unsigned char *out,
-# const CAMELLIA_KEY *key)
-&function_begin("Camellia_decrypt");
- &mov ($idx,&wparam(0)); # load ciphertext pointer
- &mov ($key,&wparam(2)); # load key schedule pointer
-
- &mov ("ebx","esp");
- &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra
- &and ("esp",-64);
- &mov ("eax",&DWP(272,$key)); # load grandRounds counter
-
- # place stack frame just "above mod 1024" the key schedule
- # this ensures that cache associativity of 2 suffices
- &lea ("ecx",&DWP(-64-63,$key));
- &sub ("ecx","esp");
- &neg ("ecx");
- &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line
- &sub ("esp","ecx");
- &add ("esp",4); # 4 is reserved for callee's return address
-
- &shl ("eax",6);
- &mov (&DWP(4*4,"esp"),$key); # save keyStart
- &lea ($key,&DWP(0,$key,"eax"));
- &mov (&DWP(5*4,"esp"),"ebx");# save %esp
-
- &call (&label("pic_point"));
- &set_label("pic_point");
- &blindpop($Tbl);
- &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-
- &mov (@T[0],&DWP(0,$idx)); # load ciphertext
- &mov (@T[1],&DWP(4,$idx));
- &mov (@T[2],&DWP(8,$idx));
- &bswap (@T[0]);
- &mov (@T[3],&DWP(12,$idx));
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
-
- &call ("_x86_Camellia_decrypt");
-
- &mov ("esp",&DWP(5*4,"esp"));
- &bswap (@T[0]);
- &mov ($idx,&wparam(1)); # load plaintext pointer
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
- &mov (&DWP(0,$idx),@T[0]); # write plaintext
- &mov (&DWP(4,$idx),@T[1]);
- &mov (&DWP(8,$idx),@T[2]);
- &mov (&DWP(12,$idx),@T[3]);
-&function_end("Camellia_decrypt");
-}
-
-&function_begin_B("_x86_Camellia_decrypt");
- &xor (@T[0],&DWP(0,$key)); # ^=key[0-3]
- &xor (@T[1],&DWP(4,$key));
- &xor (@T[2],&DWP(8,$key));
- &xor (@T[3],&DWP(12,$key));
- &mov ($idx,&DWP(-8,$key)); # prefetch key[-2]
-
- &mov ($__s0,@T[0]); # save s[0-3]
- &mov ($__s1,@T[1]);
- &mov ($__s2,@T[2]);
- &mov ($__s3,@T[3]);
-
-&set_label("loop",16);
- for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8,4); }
-
- &sub ($key,16*4);
- &cmp ($key,$__end);
- &je (&label("done"));
-
- # @T[0-1] are preloaded, $idx is preloaded with key[2]
- &and ($idx,@T[0]);
- &mov (@T[3],$__s3);
- &rotl ($idx,1);
- &mov (@T[2],@T[3]);
- &xor (@T[1],$idx);
- &or (@T[2],&DWP(4,$key));
- &mov ($__s1,@T[1]); # s1^=LeftRotate(s0&key[0],1);
- &xor (@T[2],$__s2);
-
- &mov ($idx,&DWP(12,$key));
- &mov ($__s2,@T[2]); # s2^=s3|key[3];
- &or ($idx,@T[1]);
- &and (@T[2],&DWP(0,$key));
- &xor (@T[0],$idx);
- &rotl (@T[2],1);
- &mov ($__s0,@T[0]); # s0^=s1|key[1];
- &xor (@T[3],@T[2]);
- &mov ($idx,&DWP(-8,$key)); # prefetch key[4]
- &mov ($__s3,@T[3]); # s3^=LeftRotate(s2&key[2],1);
- &jmp (&label("loop"));
-
-&set_label("done",8);
- &mov (@T[2],@T[0]); # SwapHalf
- &mov (@T[3],@T[1]);
- &mov (@T[0],$__s2);
- &mov (@T[1],$__s3);
- &xor (@T[2],$idx); # $idx is preloaded with key[2]
- &xor (@T[3],&DWP(12,$key));
- &xor (@T[0],&DWP(0,$key));
- &xor (@T[1],&DWP(4,$key));
- &ret ();
-&function_end_B("_x86_Camellia_decrypt");
-
-# shld is very slow on Intel P4 family. Even on AMD it limits
-# instruction decode rate [because it's VectorPath] and consequently
-# performance. PIII, PM and Core[2] seem to be the only ones which
-# execute this code ~7% faster...
-sub __rotl128 {
- my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
-
- $rnd *= 2;
- if ($rot) {
- &mov ($idx,$i0);
- &shld ($i0,$i1,$rot);
- &shld ($i1,$i2,$rot);
- &shld ($i2,$i3,$rot);
- &shld ($i3,$idx,$rot);
- }
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i0 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i1 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i2 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i3 eq @T[0]);
-}
-
-# ... Implementing 128-bit rotate without shld gives >3x performance
-# improvement on P4, only ~7% degradation on other Intel CPUs and
-# not worse performance on AMD. This is therefore preferred.
-sub _rotl128 {
- my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
-
- $rnd *= 2;
- if ($rot) {
- &mov ($Tbl,$i0);
- &shl ($i0,$rot);
- &mov ($idx,$i1);
- &shr ($idx,32-$rot);
- &shl ($i1,$rot);
- &or ($i0,$idx);
- &mov ($idx,$i2);
- &shl ($i2,$rot);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i0 eq @T[0]);
- &shr ($idx,32-$rot);
- &or ($i1,$idx);
- &shr ($Tbl,32-$rot);
- &mov ($idx,$i3);
- &shr ($idx,32-$rot);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i1 eq @T[0]);
- &shl ($i3,$rot);
- &or ($i2,$idx);
- &or ($i3,$Tbl);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i2 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i3 eq @T[0]);
- } else {
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i0 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i1 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i2 eq @T[0]);
- &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i3 eq @T[0]);
- }
-}
-
-sub _saveround {
-my ($rnd,$key,@T)=@_;
-my $bias=int(@T[0])?shift(@T):0;
-
- &mov (&DWP($bias+$rnd*8+0,$key),@T[0]);
- &mov (&DWP($bias+$rnd*8+4,$key),@T[1]) if ($#T>=1);
- &mov (&DWP($bias+$rnd*8+8,$key),@T[2]) if ($#T>=2);
- &mov (&DWP($bias+$rnd*8+12,$key),@T[3]) if ($#T>=3);
-}
-
-sub _loadround {
-my ($rnd,$key,@T)=@_;
-my $bias=int(@T[0])?shift(@T):0;
-
- &mov (@T[0],&DWP($bias+$rnd*8+0,$key));
- &mov (@T[1],&DWP($bias+$rnd*8+4,$key)) if ($#T>=1);
- &mov (@T[2],&DWP($bias+$rnd*8+8,$key)) if ($#T>=2);
- &mov (@T[3],&DWP($bias+$rnd*8+12,$key)) if ($#T>=3);
-}
-
-# void Camellia_Ekeygen(
-# const int keyBitLength,
-# const Byte *rawKey,
-# KEY_TABLE_TYPE keyTable)
-&function_begin("Camellia_Ekeygen");
-{ my $step=0;
-
- &stack_push(4); # place for s[0-3]
-
- &mov ($Tbl,&wparam(0)); # load arguments
- &mov ($idx,&wparam(1));
- &mov ($key,&wparam(2));
-
- &mov (@T[0],&DWP(0,$idx)); # load 0-127 bits
- &mov (@T[1],&DWP(4,$idx));
- &mov (@T[2],&DWP(8,$idx));
- &mov (@T[3],&DWP(12,$idx));
-
- &bswap (@T[0]);
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
-
- &_saveround (0,$key,@T); # KL<<<0
-
- &cmp ($Tbl,128);
- &je (&label("1st128"));
-
- &mov (@T[0],&DWP(16,$idx)); # load 128-191 bits
- &mov (@T[1],&DWP(20,$idx));
- &cmp ($Tbl,192);
- &je (&label("1st192"));
- &mov (@T[2],&DWP(24,$idx)); # load 192-255 bits
- &mov (@T[3],&DWP(28,$idx));
- &jmp (&label("1st256"));
-&set_label("1st192",4);
- &mov (@T[2],@T[0]);
- &mov (@T[3],@T[1]);
- &not (@T[2]);
- &not (@T[3]);
-&set_label("1st256",4);
- &bswap (@T[0]);
- &bswap (@T[1]);
- &bswap (@T[2]);
- &bswap (@T[3]);
-
- &_saveround (4,$key,@T); # temporary storage for KR!
-
- &xor (@T[0],&DWP(0*8+0,$key)); # KR^KL
- &xor (@T[1],&DWP(0*8+4,$key));
- &xor (@T[2],&DWP(1*8+0,$key));
- &xor (@T[3],&DWP(1*8+4,$key));
-
-&set_label("1st128",4);
- &call (&label("pic_point"));
- &set_label("pic_point");
- &blindpop($Tbl);
- &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
- &lea ($key,&DWP(&label("Camellia_SIGMA")."-".&label("Camellia_SBOX"),$Tbl));
-
- &mov ($idx,&DWP($step*8,$key)); # prefetch SIGMA[0]
- &mov (&swtmp(0),@T[0]); # save s[0-3]
- &mov (&swtmp(1),@T[1]);
- &mov (&swtmp(2),@T[2]);
- &mov (&swtmp(3),@T[3]);
- &Camellia_Feistel($step++);
- &Camellia_Feistel($step++);
- &mov (@T[2],&swtmp(2));
- &mov (@T[3],&swtmp(3));
-
- &mov ($idx,&wparam(2));
- &xor (@T[0],&DWP(0*8+0,$idx)); # ^KL
- &xor (@T[1],&DWP(0*8+4,$idx));
- &xor (@T[2],&DWP(1*8+0,$idx));
- &xor (@T[3],&DWP(1*8+4,$idx));
-
- &mov ($idx,&DWP($step*8,$key)); # prefetch SIGMA[4]
- &mov (&swtmp(0),@T[0]); # save s[0-3]
- &mov (&swtmp(1),@T[1]);
- &mov (&swtmp(2),@T[2]);
- &mov (&swtmp(3),@T[3]);
- &Camellia_Feistel($step++);
- &Camellia_Feistel($step++);
- &mov (@T[2],&swtmp(2));
- &mov (@T[3],&swtmp(3));
-
- &mov ($idx,&wparam(0));
- &cmp ($idx,128);
- &jne (&label("2nd256"));
-
- &mov ($key,&wparam(2));
- &lea ($key,&DWP(128,$key)); # size optimization
-
- ####### process KA
- &_saveround (2,$key,-128,@T); # KA<<<0
- &_rotl128 (@T,15,6,@T); # KA<<<15
- &_rotl128 (@T,15,8,@T); # KA<<<(15+15=30)
- &_rotl128 (@T,15,12,@T[0],@T[1]); # KA<<<(30+15=45)
- &_rotl128 (@T,15,14,@T); # KA<<<(45+15=60)
- push (@T,shift(@T)); # rotl128(@T,32);
- &_rotl128 (@T,2,20,@T); # KA<<<(60+32+2=94)
- &_rotl128 (@T,17,24,@T); # KA<<<(94+17=111)
-
- ####### process KL
- &_loadround (0,$key,-128,@T); # load KL
- &_rotl128 (@T,15,4,@T); # KL<<<15
- &_rotl128 (@T,30,10,@T); # KL<<<(15+30=45)
- &_rotl128 (@T,15,13,@T[2],@T[3]); # KL<<<(45+15=60)
- &_rotl128 (@T,17,16,@T); # KL<<<(60+17=77)
- &_rotl128 (@T,17,18,@T); # KL<<<(77+17=94)
- &_rotl128 (@T,17,22,@T); # KL<<<(94+17=111)
-
- while (@T[0] ne "eax") # restore order
- { unshift (@T,pop(@T)); }
-
- &mov ("eax",3); # 3 grandRounds
- &jmp (&label("done"));
-
-&set_label("2nd256",16);
- &mov ($idx,&wparam(2));
- &_saveround (6,$idx,@T); # temporary storage for KA!
-
- &xor (@T[0],&DWP(4*8+0,$idx)); # KA^KR
- &xor (@T[1],&DWP(4*8+4,$idx));
- &xor (@T[2],&DWP(5*8+0,$idx));
- &xor (@T[3],&DWP(5*8+4,$idx));
-
- &mov ($idx,&DWP($step*8,$key)); # prefetch SIGMA[8]
- &mov (&swtmp(0),@T[0]); # save s[0-3]
- &mov (&swtmp(1),@T[1]);
- &mov (&swtmp(2),@T[2]);
- &mov (&swtmp(3),@T[3]);
- &Camellia_Feistel($step++);
- &Camellia_Feistel($step++);
- &mov (@T[2],&swtmp(2));
- &mov (@T[3],&swtmp(3));
-
- &mov ($key,&wparam(2));
- &lea ($key,&DWP(128,$key)); # size optimization
-
- ####### process KB
- &_saveround (2,$key,-128,@T); # KB<<<0
- &_rotl128 (@T,30,10,@T); # KB<<<30
- &_rotl128 (@T,30,20,@T); # KB<<<(30+30=60)
- push (@T,shift(@T)); # rotl128(@T,32);
- &_rotl128 (@T,19,32,@T); # KB<<<(60+32+19=111)
-
- ####### process KR
- &_loadround (4,$key,-128,@T); # load KR
- &_rotl128 (@T,15,4,@T); # KR<<<15
- &_rotl128 (@T,15,8,@T); # KR<<<(15+15=30)
- &_rotl128 (@T,30,18,@T); # KR<<<(30+30=60)
- push (@T,shift(@T)); # rotl128(@T,32);
- &_rotl128 (@T,2,26,@T); # KR<<<(60+32+2=94)
-
- ####### process KA
- &_loadround (6,$key,-128,@T); # load KA
- &_rotl128 (@T,15,6,@T); # KA<<<15
- &_rotl128 (@T,30,14,@T); # KA<<<(15+30=45)
- push (@T,shift(@T)); # rotl128(@T,32);
- &_rotl128 (@T,0,24,@T); # KA<<<(45+32+0=77)
- &_rotl128 (@T,17,28,@T); # KA<<<(77+17=94)
-
- ####### process KL
- &_loadround (0,$key,-128,@T); # load KL
- push (@T,shift(@T)); # rotl128(@T,32);
- &_rotl128 (@T,13,12,@T); # KL<<<(32+13=45)
- &_rotl128 (@T,15,16,@T); # KL<<<(45+15=60)
- &_rotl128 (@T,17,22,@T); # KL<<<(60+17=77)
- push (@T,shift(@T)); # rotl128(@T,32);
- &_rotl128 (@T,2,30,@T); # KL<<<(77+32+2=111)
-
- while (@T[0] ne "eax") # restore order
- { unshift (@T,pop(@T)); }
-
- &mov ("eax",4); # 4 grandRounds
-&set_label("done");
- &lea ("edx",&DWP(272-128,$key)); # end of key schedule
- &stack_pop(4);
-}
-&function_end("Camellia_Ekeygen");
-
-if ($OPENSSL) {
-# int Camellia_set_key (
-# const unsigned char *userKey,
-# int bits,
-# CAMELLIA_KEY *key)
-&function_begin_B("Camellia_set_key");
- &push ("ebx");
- &mov ("ecx",&wparam(0)); # pull arguments
- &mov ("ebx",&wparam(1));
- &mov ("edx",&wparam(2));
-
- &mov ("eax",-1);
- &test ("ecx","ecx");
- &jz (&label("done")); # userKey==NULL?
- &test ("edx","edx");
- &jz (&label("done")); # key==NULL?
-
- &mov ("eax",-2);
- &cmp ("ebx",256);
- &je (&label("arg_ok")); # bits==256?
- &cmp ("ebx",192);
- &je (&label("arg_ok")); # bits==192?
- &cmp ("ebx",128);
- &jne (&label("done")); # bits!=128?
-&set_label("arg_ok",4);
-
- &push ("edx"); # push arguments
- &push ("ecx");
- &push ("ebx");
- &call ("Camellia_Ekeygen");
- &stack_pop(3);
-
- # eax holds grandRounds and edx points at where to put it
- &mov (&DWP(0,"edx"),"eax");
- &xor ("eax","eax");
-&set_label("done",4);
- &pop ("ebx");
- &ret ();
-&function_end_B("Camellia_set_key");
-}
-
-@SBOX=(
-112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
- 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
-134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
-166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
-139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
-223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
- 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
-254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
-170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
- 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
-135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
- 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
-233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
-120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
-114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
- 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
-
-sub S1110 { my $i=shift; $i=@SBOX[$i]; return $i<<24|$i<<16|$i<<8; }
-sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; return $i<<24|$i<<16|$i; }
-sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; return $i<<16|$i<<8|$i; }
-sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; return $i<<24|$i<<8|$i; }
-
-&set_label("Camellia_SIGMA",64);
-&data_word(
- 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2,
- 0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c,
- 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd,
- 0, 0, 0, 0);
-&set_label("Camellia_SBOX",64);
-# tables are interleaved, remember?
-for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
-for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
-
-# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
-# size_t length, const CAMELLIA_KEY *key,
-# unsigned char *ivp,const int enc);
-{
-# stack frame layout
-# -4(%esp) # return address 0(%esp)
-# 0(%esp) # s0 4(%esp)
-# 4(%esp) # s1 8(%esp)
-# 8(%esp) # s2 12(%esp)
-# 12(%esp) # s3 16(%esp)
-# 16(%esp) # end of key schedule 20(%esp)
-# 20(%esp) # %esp backup
-my $_inp=&DWP(24,"esp"); #copy of wparam(0)
-my $_out=&DWP(28,"esp"); #copy of wparam(1)
-my $_len=&DWP(32,"esp"); #copy of wparam(2)
-my $_key=&DWP(36,"esp"); #copy of wparam(3)
-my $_ivp=&DWP(40,"esp"); #copy of wparam(4)
-my $ivec=&DWP(44,"esp"); #ivec[16]
-my $_tmp=&DWP(44,"esp"); #volatile variable [yes, aliases with ivec]
-my ($s0,$s1,$s2,$s3) = @T;
-
-&function_begin("Camellia_cbc_encrypt");
- &mov ($s2 eq "ecx"? $s2 : "",&wparam(2)); # load len
- &cmp ($s2,0);
- &je (&label("enc_out"));
-
- &pushf ();
- &cld ();
-
- &mov ($s0,&wparam(0)); # load inp
- &mov ($s1,&wparam(1)); # load out
- #&mov ($s2,&wparam(2)); # load len
- &mov ($s3,&wparam(3)); # load key
- &mov ($Tbl,&wparam(4)); # load ivp
-
- # allocate aligned stack frame...
- &lea ($idx,&DWP(-64,"esp"));
- &and ($idx,-64);
-
- # place stack frame just "above mod 1024" the key schedule
- # this ensures that cache associativity of 2 suffices
- &lea ($key,&DWP(-64-63,$s3));
- &sub ($key,$idx);
- &neg ($key);
- &and ($key,0x3C0); # modulo 1024, but aligned to cache-line
- &sub ($idx,$key);
-
- &mov ($key,&wparam(5)); # load enc
-
- &exch ("esp",$idx);
- &add ("esp",4); # reserve for return address!
- &mov ($_esp,$idx); # save %esp
-
- &mov ($_inp,$s0); # save copy of inp
- &mov ($_out,$s1); # save copy of out
- &mov ($_len,$s2); # save copy of len
- &mov ($_key,$s3); # save copy of key
- &mov ($_ivp,$Tbl); # save copy of ivp
-
- &call (&label("pic_point")); # make it PIC!
- &set_label("pic_point");
- &blindpop($Tbl);
- &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-
- &mov ($idx,32);
- &set_label("prefetch_sbox",4);
- &mov ($s0,&DWP(0,$Tbl));
- &mov ($s1,&DWP(32,$Tbl));
- &mov ($s2,&DWP(64,$Tbl));
- &mov ($s3,&DWP(96,$Tbl));
- &lea ($Tbl,&DWP(128,$Tbl));
- &dec ($idx);
- &jnz (&label("prefetch_sbox"));
- &mov ($s0,$_key);
- &sub ($Tbl,4096);
- &mov ($idx,$_inp);
- &mov ($s3,&DWP(272,$s0)); # load grandRounds
-
- &cmp ($key,0);
- &je (&label("DECRYPT"));
-
- &mov ($s2,$_len);
- &mov ($key,$_ivp);
- &shl ($s3,6);
- &lea ($s3,&DWP(0,$s0,$s3));
- &mov ($_end,$s3);
-
- &test ($s2,0xFFFFFFF0);
- &jz (&label("enc_tail")); # short input...
-
- &mov ($s0,&DWP(0,$key)); # load iv
- &mov ($s1,&DWP(4,$key));
-
- &set_label("enc_loop",4);
- &mov ($s2,&DWP(8,$key));
- &mov ($s3,&DWP(12,$key));
-
- &xor ($s0,&DWP(0,$idx)); # xor input data
- &xor ($s1,&DWP(4,$idx));
- &xor ($s2,&DWP(8,$idx));
- &bswap ($s0);
- &xor ($s3,&DWP(12,$idx));
- &bswap ($s1);
- &mov ($key,$_key); # load key
- &bswap ($s2);
- &bswap ($s3);
-
- &call ("_x86_Camellia_encrypt");
-
- &mov ($idx,$_inp); # load inp
- &mov ($key,$_out); # load out
-
- &bswap ($s0);
- &bswap ($s1);
- &bswap ($s2);
- &mov (&DWP(0,$key),$s0); # save output data
- &bswap ($s3);
- &mov (&DWP(4,$key),$s1);
- &mov (&DWP(8,$key),$s2);
- &mov (&DWP(12,$key),$s3);
-
- &mov ($s2,$_len); # load len
-
- &lea ($idx,&DWP(16,$idx));
- &mov ($_inp,$idx); # save inp
-
- &lea ($s3,&DWP(16,$key));
- &mov ($_out,$s3); # save out
-
- &sub ($s2,16);
- &test ($s2,0xFFFFFFF0);
- &mov ($_len,$s2); # save len
- &jnz (&label("enc_loop"));
- &test ($s2,15);
- &jnz (&label("enc_tail"));
- &mov ($idx,$_ivp); # load ivp
- &mov ($s2,&DWP(8,$key)); # restore last dwords
- &mov ($s3,&DWP(12,$key));
- &mov (&DWP(0,$idx),$s0); # save ivec
- &mov (&DWP(4,$idx),$s1);
- &mov (&DWP(8,$idx),$s2);
- &mov (&DWP(12,$idx),$s3);
-
- &mov ("esp",$_esp);
- &popf ();
- &set_label("enc_out");
- &function_end_A();
- &pushf (); # kludge, never executed
-
- &set_label("enc_tail",4);
- &mov ($s0,$key eq "edi" ? $key : "");
- &mov ($key,$_out); # load out
- &push ($s0); # push ivp
- &mov ($s1,16);
- &sub ($s1,$s2);
- &cmp ($key,$idx); # compare with inp
- &je (&label("enc_in_place"));
- &align (4);
- &data_word(0xA4F3F689); # rep movsb # copy input
- &jmp (&label("enc_skip_in_place"));
- &set_label("enc_in_place");
- &lea ($key,&DWP(0,$key,$s2));
- &set_label("enc_skip_in_place");
- &mov ($s2,$s1);
- &xor ($s0,$s0);
- &align (4);
- &data_word(0xAAF3F689); # rep stosb # zero tail
- &pop ($key); # pop ivp
-
- &mov ($idx,$_out); # output as input
- &mov ($s0,&DWP(0,$key));
- &mov ($s1,&DWP(4,$key));
- &mov ($_len,16); # len=16
- &jmp (&label("enc_loop")); # one more spin...
-
-#----------------------------- DECRYPT -----------------------------#
-&set_label("DECRYPT",16);
- &shl ($s3,6);
- &lea ($s3,&DWP(0,$s0,$s3));
- &mov ($_end,$s0);
- &mov ($_key,$s3);
-
- &cmp ($idx,$_out);
- &je (&label("dec_in_place")); # in-place processing...
-
- &mov ($key,$_ivp); # load ivp
- &mov ($_tmp,$key);
-
- &set_label("dec_loop",4);
- &mov ($s0,&DWP(0,$idx)); # read input
- &mov ($s1,&DWP(4,$idx));
- &mov ($s2,&DWP(8,$idx));
- &bswap ($s0);
- &mov ($s3,&DWP(12,$idx));
- &bswap ($s1);
- &mov ($key,$_key); # load key
- &bswap ($s2);
- &bswap ($s3);
-
- &call ("_x86_Camellia_decrypt");
-
- &mov ($key,$_tmp); # load ivp
- &mov ($idx,$_len); # load len
-
- &bswap ($s0);
- &bswap ($s1);
- &bswap ($s2);
- &xor ($s0,&DWP(0,$key)); # xor iv
- &bswap ($s3);
- &xor ($s1,&DWP(4,$key));
- &xor ($s2,&DWP(8,$key));
- &xor ($s3,&DWP(12,$key));
-
- &sub ($idx,16);
- &jc (&label("dec_partial"));
- &mov ($_len,$idx); # save len
- &mov ($idx,$_inp); # load inp
- &mov ($key,$_out); # load out
-
- &mov (&DWP(0,$key),$s0); # write output
- &mov (&DWP(4,$key),$s1);
- &mov (&DWP(8,$key),$s2);
- &mov (&DWP(12,$key),$s3);
-
- &mov ($_tmp,$idx); # save ivp
- &lea ($idx,&DWP(16,$idx));
- &mov ($_inp,$idx); # save inp
-
- &lea ($key,&DWP(16,$key));
- &mov ($_out,$key); # save out
-
- &jnz (&label("dec_loop"));
- &mov ($key,$_tmp); # load temp ivp
- &set_label("dec_end");
- &mov ($idx,$_ivp); # load user ivp
- &mov ($s0,&DWP(0,$key)); # load iv
- &mov ($s1,&DWP(4,$key));
- &mov ($s2,&DWP(8,$key));
- &mov ($s3,&DWP(12,$key));
- &mov (&DWP(0,$idx),$s0); # copy back to user
- &mov (&DWP(4,$idx),$s1);
- &mov (&DWP(8,$idx),$s2);
- &mov (&DWP(12,$idx),$s3);
- &jmp (&label("dec_out"));
-
- &set_label("dec_partial",4);
- &lea ($key,$ivec);
- &mov (&DWP(0,$key),$s0); # dump output to stack
- &mov (&DWP(4,$key),$s1);
- &mov (&DWP(8,$key),$s2);
- &mov (&DWP(12,$key),$s3);
- &lea ($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx));
- &mov ($idx eq "esi" ? $idx : "",$key);
- &mov ($key eq "edi" ? $key : "",$_out); # load out
- &data_word(0xA4F3F689); # rep movsb # copy output
- &mov ($key,$_inp); # use inp as temp ivp
- &jmp (&label("dec_end"));
-
- &set_label("dec_in_place",4);
- &set_label("dec_in_place_loop");
- &lea ($key,$ivec);
- &mov ($s0,&DWP(0,$idx)); # read input
- &mov ($s1,&DWP(4,$idx));
- &mov ($s2,&DWP(8,$idx));
- &mov ($s3,&DWP(12,$idx));
-
- &mov (&DWP(0,$key),$s0); # copy to temp
- &mov (&DWP(4,$key),$s1);
- &mov (&DWP(8,$key),$s2);
- &bswap ($s0);
- &mov (&DWP(12,$key),$s3);
- &bswap ($s1);
- &mov ($key,$_key); # load key
- &bswap ($s2);
- &bswap ($s3);
-
- &call ("_x86_Camellia_decrypt");
-
- &mov ($key,$_ivp); # load ivp
- &mov ($idx,$_out); # load out
-
- &bswap ($s0);
- &bswap ($s1);
- &bswap ($s2);
- &xor ($s0,&DWP(0,$key)); # xor iv
- &bswap ($s3);
- &xor ($s1,&DWP(4,$key));
- &xor ($s2,&DWP(8,$key));
- &xor ($s3,&DWP(12,$key));
-
- &mov (&DWP(0,$idx),$s0); # write output
- &mov (&DWP(4,$idx),$s1);
- &mov (&DWP(8,$idx),$s2);
- &mov (&DWP(12,$idx),$s3);
-
- &lea ($idx,&DWP(16,$idx));
- &mov ($_out,$idx); # save out
-
- &lea ($idx,$ivec);
- &mov ($s0,&DWP(0,$idx)); # read temp
- &mov ($s1,&DWP(4,$idx));
- &mov ($s2,&DWP(8,$idx));
- &mov ($s3,&DWP(12,$idx));
-
- &mov (&DWP(0,$key),$s0); # copy iv
- &mov (&DWP(4,$key),$s1);
- &mov (&DWP(8,$key),$s2);
- &mov (&DWP(12,$key),$s3);
-
- &mov ($idx,$_inp); # load inp
-
- &lea ($idx,&DWP(16,$idx));
- &mov ($_inp,$idx); # save inp
-
- &mov ($s2,$_len); # load len
- &sub ($s2,16);
- &jc (&label("dec_in_place_partial"));
- &mov ($_len,$s2); # save len
- &jnz (&label("dec_in_place_loop"));
- &jmp (&label("dec_out"));
-
- &set_label("dec_in_place_partial",4);
- # one can argue if this is actually required...
- &mov ($key eq "edi" ? $key : "",$_out);
- &lea ($idx eq "esi" ? $idx : "",$ivec);
- &lea ($key,&DWP(0,$key,$s2));
- &lea ($idx,&DWP(16,$idx,$s2));
- &neg ($s2 eq "ecx" ? $s2 : "");
- &data_word(0xA4F3F689); # rep movsb # restore tail
-
- &set_label("dec_out",4);
- &mov ("esp",$_esp);
- &popf ();
-&function_end("Camellia_cbc_encrypt");
-}
-
-&asciz("Camellia for x86 by <appro@openssl.org>");
-
-&asm_finish();
diff --git a/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl b/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl
deleted file mode 100755
index c683646..0000000
--- a/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl
+++ /dev/null
@@ -1,1080 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
-#
-# This module may be used under the terms of either the GNU General
-# Public License version 2 or later, the GNU Lesser General Public
-# License version 2.1 or later, the Mozilla Public License version
-# 1.1 or the BSD License. The exact terms of either license are
-# distributed along with this module. For further details see
-# http://www.openssl.org/~appro/camellia/.
-# ====================================================================
-
-# Performance in cycles per processed byte (less is better) in
-# 'openssl speed ...' benchmark:
-#
-# AMD64 Core2 EM64T
-# -evp camellia-128-ecb 16.7 21.0 22.7
-# + over gcc 3.4.6 +25% +5% 0%
-#
-# camellia-128-cbc 15.7 20.4 21.1
-#
-# 128-bit key setup 128 216 205 cycles/key
-# + over gcc 3.4.6 +54% +39% +15%
-#
-# Numbers in "+" rows represent performance improvement over compiler
-# generated code. Key setup timings are impressive on AMD and Core2
-# thanks to 64-bit operations being covertly deployed. Improvement on
-# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
-# apparently emulates some of 64-bit operations in [32-bit] microcode.
-
-$flavour = shift;
-$output = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-die "can't locate x86_64-xlate.pl";
-
-open STDOUT,"| $^X $xlate $flavour $output";
-
-sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; }
-sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
- $r =~ s/%[er]([sd]i)/%\1l/;
- $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; }
-
-$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
-@S=("%r8d","%r9d","%r10d","%r11d");
-$i0="%esi";
-$i1="%edi";
-$Tbl="%rbp"; # size optimization
-$inp="%r12";
-$out="%r13";
-$key="%r14";
-$keyend="%r15";
-$arg0d=$win64?"%ecx":"%edi";
-
-# const unsigned int Camellia_SBOX[4][256];
-# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
-# and [2][] - with [3][]. This is done to minimize code size.
-$SBOX1_1110=0; # Camellia_SBOX[0]
-$SBOX4_4404=4; # Camellia_SBOX[1]
-$SBOX2_0222=2048; # Camellia_SBOX[2]
-$SBOX3_3033=2052; # Camellia_SBOX[3]
-
-sub Camellia_Feistel {
-my $i=@_[0];
-my $seed=defined(@_[1])?@_[1]:0;
-my $scale=$seed<0?-8:8;
-my $j=($i&1)*2;
-my $s0=@S[($j)%4],$s1=@S[($j+1)%4],$s2=@S[($j+2)%4],$s3=@S[($j+3)%4];
-
-$code.=<<___;
- xor $s0,$t0 # t0^=key[0]
- xor $s1,$t1 # t1^=key[1]
- movz `&hi("$t0")`,$i0 # (t0>>8)&0xff
- movz `&lo("$t1")`,$i1 # (t1>>0)&0xff
- mov $SBOX3_3033($Tbl,$i0,8),$t3 # t3=SBOX3_3033[0]
- mov $SBOX1_1110($Tbl,$i1,8),$t2 # t2=SBOX1_1110[1]
- movz `&lo("$t0")`,$i0 # (t0>>0)&0xff
- shr \$16,$t0
- movz `&hi("$t1")`,$i1 # (t1>>8)&0xff
- xor $SBOX4_4404($Tbl,$i0,8),$t3 # t3^=SBOX4_4404[0]
- shr \$16,$t1
- xor $SBOX4_4404($Tbl,$i1,8),$t2 # t2^=SBOX4_4404[1]
- movz `&hi("$t0")`,$i0 # (t0>>24)&0xff
- movz `&lo("$t1")`,$i1 # (t1>>16)&0xff
- xor $SBOX1_1110($Tbl,$i0,8),$t3 # t3^=SBOX1_1110[0]
- xor $SBOX3_3033($Tbl,$i1,8),$t2 # t2^=SBOX3_3033[1]
- movz `&lo("$t0")`,$i0 # (t0>>16)&0xff
- movz `&hi("$t1")`,$i1 # (t1>>24)&0xff
- xor $SBOX2_0222($Tbl,$i0,8),$t3 # t3^=SBOX2_0222[0]
- xor $SBOX2_0222($Tbl,$i1,8),$t2 # t2^=SBOX2_0222[1]
- mov `$seed+($i+1)*$scale`($key),$t1 # prefetch key[i+1]
- mov `$seed+($i+1)*$scale+4`($key),$t0
- xor $t3,$t2 # t2^=t3
- ror \$8,$t3 # t3=RightRotate(t3,8)
- xor $t2,$s2
- xor $t2,$s3
- xor $t3,$s3
-___
-}
-
-# void Camellia_EncryptBlock_Rounds(
-# int grandRounds,
-# const Byte plaintext[],
-# const KEY_TABLE_TYPE keyTable,
-# Byte ciphertext[])
-$code=<<___;
-.text
-
-# V1.x API
-.globl Camellia_EncryptBlock
-.type Camellia_EncryptBlock,\@abi-omnipotent
-.align 16
-Camellia_EncryptBlock:
- movl \$128,%eax
- subl $arg0d,%eax
- movl \$3,$arg0d
- adcl \$0,$arg0d # keyBitLength==128?3:4
- jmp .Lenc_rounds
-.size Camellia_EncryptBlock,.-Camellia_EncryptBlock
-# V2
-.globl Camellia_EncryptBlock_Rounds
-.type Camellia_EncryptBlock_Rounds,\@function,4
-.align 16
-.Lenc_rounds:
-Camellia_EncryptBlock_Rounds:
- push %rbx
- push %rbp
- push %r13
- push %r14
- push %r15
-.Lenc_prologue:
-
- #mov %rsi,$inp # put away arguments
- mov %rcx,$out
- mov %rdx,$key
-
- shl \$6,%edi # process grandRounds
- lea .LCamellia_SBOX(%rip),$Tbl
- lea ($key,%rdi),$keyend
-
- mov 0(%rsi),@S[0] # load plaintext
- mov 4(%rsi),@S[1]
- mov 8(%rsi),@S[2]
- bswap @S[0]
- mov 12(%rsi),@S[3]
- bswap @S[1]
- bswap @S[2]
- bswap @S[3]
-
- call _x86_64_Camellia_encrypt
-
- bswap @S[0]
- bswap @S[1]
- bswap @S[2]
- mov @S[0],0($out)
- bswap @S[3]
- mov @S[1],4($out)
- mov @S[2],8($out)
- mov @S[3],12($out)
-
- mov 0(%rsp),%r15
- mov 8(%rsp),%r14
- mov 16(%rsp),%r13
- mov 24(%rsp),%rbp
- mov 32(%rsp),%rbx
- lea 40(%rsp),%rsp
-.Lenc_epilogue:
- ret
-.size Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
-
-.type _x86_64_Camellia_encrypt,\@abi-omnipotent
-.align 16
-_x86_64_Camellia_encrypt:
- xor 0($key),@S[1]
- xor 4($key),@S[0] # ^=key[0-3]
- xor 8($key),@S[3]
- xor 12($key),@S[2]
-.align 16
-.Leloop:
- mov 16($key),$t1 # prefetch key[4-5]
- mov 20($key),$t0
-
-___
- for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); }
-$code.=<<___;
- lea 16*4($key),$key
- cmp $keyend,$key
- mov 8($key),$t3 # prefetch key[2-3]
- mov 12($key),$t2
- je .Ledone
-
- and @S[0],$t0
- or @S[3],$t3
- rol \$1,$t0
- xor $t3,@S[2] # s2^=s3|key[3];
- xor $t0,@S[1] # s1^=LeftRotate(s0&key[0],1);
- and @S[2],$t2
- or @S[1],$t1
- rol \$1,$t2
- xor $t1,@S[0] # s0^=s1|key[1];
- xor $t2,@S[3] # s3^=LeftRotate(s2&key[2],1);
- jmp .Leloop
-
-.align 16
-.Ledone:
- xor @S[2],$t0 # SwapHalf
- xor @S[3],$t1
- xor @S[0],$t2
- xor @S[1],$t3
-
- mov $t0,@S[0]
- mov $t1,@S[1]
- mov $t2,@S[2]
- mov $t3,@S[3]
-
- .byte 0xf3,0xc3 # rep ret
-.size _x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
-
-# V1.x API
-.globl Camellia_DecryptBlock
-.type Camellia_DecryptBlock,\@abi-omnipotent
-.align 16
-Camellia_DecryptBlock:
- movl \$128,%eax
- subl $arg0d,%eax
- movl \$3,$arg0d
- adcl \$0,$arg0d # keyBitLength==128?3:4
- jmp .Ldec_rounds
-.size Camellia_DecryptBlock,.-Camellia_DecryptBlock
-# V2
-.globl Camellia_DecryptBlock_Rounds
-.type Camellia_DecryptBlock_Rounds,\@function,4
-.align 16
-.Ldec_rounds:
-Camellia_DecryptBlock_Rounds:
- push %rbx
- push %rbp
- push %r13
- push %r14
- push %r15
-.Ldec_prologue:
-
- #mov %rsi,$inp # put away arguments
- mov %rcx,$out
- mov %rdx,$keyend
-
- shl \$6,%edi # process grandRounds
- lea .LCamellia_SBOX(%rip),$Tbl
- lea ($keyend,%rdi),$key
-
- mov 0(%rsi),@S[0] # load plaintext
- mov 4(%rsi),@S[1]
- mov 8(%rsi),@S[2]
- bswap @S[0]
- mov 12(%rsi),@S[3]
- bswap @S[1]
- bswap @S[2]
- bswap @S[3]
-
- call _x86_64_Camellia_decrypt
-
- bswap @S[0]
- bswap @S[1]
- bswap @S[2]
- mov @S[0],0($out)
- bswap @S[3]
- mov @S[1],4($out)
- mov @S[2],8($out)
- mov @S[3],12($out)
-
- mov 0(%rsp),%r15
- mov 8(%rsp),%r14
- mov 16(%rsp),%r13
- mov 24(%rsp),%rbp
- mov 32(%rsp),%rbx
- lea 40(%rsp),%rsp
-.Ldec_epilogue:
- ret
-.size Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
-
-.type _x86_64_Camellia_decrypt,\@abi-omnipotent
-.align 16
-_x86_64_Camellia_decrypt:
- xor 0($key),@S[1]
- xor 4($key),@S[0] # ^=key[0-3]
- xor 8($key),@S[3]
- xor 12($key),@S[2]
-.align 16
-.Ldloop:
- mov -8($key),$t1 # prefetch key[4-5]
- mov -4($key),$t0
-
-___
- for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); }
-$code.=<<___;
- lea -16*4($key),$key
- cmp $keyend,$key
- mov 0($key),$t3 # prefetch key[2-3]
- mov 4($key),$t2
- je .Lddone
-
- and @S[0],$t0
- or @S[3],$t3
- rol \$1,$t0
- xor $t3,@S[2] # s2^=s3|key[3];
- xor $t0,@S[1] # s1^=LeftRotate(s0&key[0],1);
- and @S[2],$t2
- or @S[1],$t1
- rol \$1,$t2
- xor $t1,@S[0] # s0^=s1|key[1];
- xor $t2,@S[3] # s3^=LeftRotate(s2&key[2],1);
-
- jmp .Ldloop
-
-.align 16
-.Lddone:
- xor @S[2],$t2
- xor @S[3],$t3
- xor @S[0],$t0
- xor @S[1],$t1
-
- mov $t2,@S[0] # SwapHalf
- mov $t3,@S[1]
- mov $t0,@S[2]
- mov $t1,@S[3]
-
- .byte 0xf3,0xc3 # rep ret
-.size _x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
-___
-
-sub _saveround {
-my ($rnd,$key,@T)=@_;
-my $bias=int(@T[0])?shift(@T):0;
-
- if ($#T==3) {
- $code.=<<___;
- mov @T[1],`$bias+$rnd*8+0`($key)
- mov @T[0],`$bias+$rnd*8+4`($key)
- mov @T[3],`$bias+$rnd*8+8`($key)
- mov @T[2],`$bias+$rnd*8+12`($key)
-___
- } else {
- $code.=" mov @T[0],`$bias+$rnd*8+0`($key)\n";
- $code.=" mov @T[1],`$bias+$rnd*8+8`($key)\n" if ($#T>=1);
- }
-}
-
-sub _loadround {
-my ($rnd,$key,@T)=@_;
-my $bias=int(@T[0])?shift(@T):0;
-
-$code.=" mov `$bias+$rnd*8+0`($key),@T[0]\n";
-$code.=" mov `$bias+$rnd*8+8`($key),@T[1]\n" if ($#T>=1);
-}
-
-# shld is very slow on Intel EM64T family. Even on AMD it limits
-# instruction decode rate [because it's VectorPath] and consequently
-# performance...
-sub __rotl128 {
-my ($i0,$i1,$rot)=@_;
-
- if ($rot) {
- $code.=<<___;
- mov $i0,%r11
- shld \$$rot,$i1,$i0
- shld \$$rot,%r11,$i1
-___
- }
-}
-
-# ... Implementing 128-bit rotate without shld gives 80% better
-# performance EM64T, +15% on AMD64 and only ~7% degradation on
-# Core2. This is therefore preferred.
-sub _rotl128 {
-my ($i0,$i1,$rot)=@_;
-
- if ($rot) {
- $code.=<<___;
- mov $i0,%r11
- shl \$$rot,$i0
- mov $i1,%r9
- shr \$`64-$rot`,%r9
- shr \$`64-$rot`,%r11
- or %r9,$i0
- shl \$$rot,$i1
- or %r11,$i1
-___
- }
-}
-
-{ my $step=0;
-
-$code.=<<___;
-.globl Camellia_Ekeygen
-.type Camellia_Ekeygen,\@function,3
-.align 16
-Camellia_Ekeygen:
- push %rbx
- push %rbp
- push %r13
- push %r14
- push %r15
-.Lkey_prologue:
-
- mov %rdi,$keyend # put away arguments, keyBitLength
- mov %rdx,$out # keyTable
-
- mov 0(%rsi),@S[0] # load 0-127 bits
- mov 4(%rsi),@S[1]
- mov 8(%rsi),@S[2]
- mov 12(%rsi),@S[3]
-
- bswap @S[0]
- bswap @S[1]
- bswap @S[2]
- bswap @S[3]
-___
- &_saveround (0,$out,@S); # KL<<<0
-$code.=<<___;
- cmp \$128,$keyend # check keyBitLength
- je .L1st128
-
- mov 16(%rsi),@S[0] # load 128-191 bits
- mov 20(%rsi),@S[1]
- cmp \$192,$keyend
- je .L1st192
- mov 24(%rsi),@S[2] # load 192-255 bits
- mov 28(%rsi),@S[3]
- jmp .L1st256
-.L1st192:
- mov @S[0],@S[2]
- mov @S[1],@S[3]
- not @S[2]
- not @S[3]
-.L1st256:
- bswap @S[0]
- bswap @S[1]
- bswap @S[2]
- bswap @S[3]
-___
- &_saveround (4,$out,@S); # temp storage for KR!
-$code.=<<___;
- xor 0($out),@S[1] # KR^KL
- xor 4($out),@S[0]
- xor 8($out),@S[3]
- xor 12($out),@S[2]
-
-.L1st128:
- lea .LCamellia_SIGMA(%rip),$key
- lea .LCamellia_SBOX(%rip),$Tbl
-
- mov 0($key),$t1
- mov 4($key),$t0
-___
- &Camellia_Feistel($step++);
- &Camellia_Feistel($step++);
-$code.=<<___;
- xor 0($out),@S[1] # ^KL
- xor 4($out),@S[0]
- xor 8($out),@S[3]
- xor 12($out),@S[2]
-___
- &Camellia_Feistel($step++);
- &Camellia_Feistel($step++);
-$code.=<<___;
- cmp \$128,$keyend
- jne .L2nd256
-
- lea 128($out),$out # size optimization
- shl \$32,%r8 # @S[0]||
- shl \$32,%r10 # @S[2]||
- or %r9,%r8 # ||@S[1]
- or %r11,%r10 # ||@S[3]
-___
- &_loadround (0,$out,-128,"%rax","%rbx"); # KL
- &_saveround (2,$out,-128,"%r8","%r10"); # KA<<<0
- &_rotl128 ("%rax","%rbx",15);
- &_saveround (4,$out,-128,"%rax","%rbx"); # KL<<<15
- &_rotl128 ("%r8","%r10",15);
- &_saveround (6,$out,-128,"%r8","%r10"); # KA<<<15
- &_rotl128 ("%r8","%r10",15); # 15+15=30
- &_saveround (8,$out,-128,"%r8","%r10"); # KA<<<30
- &_rotl128 ("%rax","%rbx",30); # 15+30=45
- &_saveround (10,$out,-128,"%rax","%rbx"); # KL<<<45
- &_rotl128 ("%r8","%r10",15); # 30+15=45
- &_saveround (12,$out,-128,"%r8"); # KA<<<45
- &_rotl128 ("%rax","%rbx",15); # 45+15=60
- &_saveround (13,$out,-128,"%rbx"); # KL<<<60
- &_rotl128 ("%r8","%r10",15); # 45+15=60
- &_saveround (14,$out,-128,"%r8","%r10"); # KA<<<60
- &_rotl128 ("%rax","%rbx",17); # 60+17=77
- &_saveround (16,$out,-128,"%rax","%rbx"); # KL<<<77
- &_rotl128 ("%rax","%rbx",17); # 77+17=94
- &_saveround (18,$out,-128,"%rax","%rbx"); # KL<<<94
- &_rotl128 ("%r8","%r10",34); # 60+34=94
- &_saveround (20,$out,-128,"%r8","%r10"); # KA<<<94
- &_rotl128 ("%rax","%rbx",17); # 94+17=111
- &_saveround (22,$out,-128,"%rax","%rbx"); # KL<<<111
- &_rotl128 ("%r8","%r10",17); # 94+17=111
- &_saveround (24,$out,-128,"%r8","%r10"); # KA<<<111
-$code.=<<___;
- mov \$3,%eax
- jmp .Ldone
-.align 16
-.L2nd256:
-___
- &_saveround (6,$out,@S); # temp storage for KA!
-$code.=<<___;
- xor `4*8+0`($out),@S[1] # KA^KR
- xor `4*8+4`($out),@S[0]
- xor `5*8+0`($out),@S[3]
- xor `5*8+4`($out),@S[2]
-___
- &Camellia_Feistel($step++);
- &Camellia_Feistel($step++);
-
- &_loadround (0,$out,"%rax","%rbx"); # KL
- &_loadround (4,$out,"%rcx","%rdx"); # KR
- &_loadround (6,$out,"%r14","%r15"); # KA
-$code.=<<___;
- lea 128($out),$out # size optimization
- shl \$32,%r8 # @S[0]||
- shl \$32,%r10 # @S[2]||
- or %r9,%r8 # ||@S[1]
- or %r11,%r10 # ||@S[3]
-___
- &_saveround (2,$out,-128,"%r8","%r10"); # KB<<<0
- &_rotl128 ("%rcx","%rdx",15);
- &_saveround (4,$out,-128,"%rcx","%rdx"); # KR<<<15
- &_rotl128 ("%r14","%r15",15);
- &_saveround (6,$out,-128,"%r14","%r15"); # KA<<<15
- &_rotl128 ("%rcx","%rdx",15); # 15+15=30
- &_saveround (8,$out,-128,"%rcx","%rdx"); # KR<<<30
- &_rotl128 ("%r8","%r10",30);
- &_saveround (10,$out,-128,"%r8","%r10"); # KB<<<30
- &_rotl128 ("%rax","%rbx",45);
- &_saveround (12,$out,-128,"%rax","%rbx"); # KL<<<45
- &_rotl128 ("%r14","%r15",30); # 15+30=45
- &_saveround (14,$out,-128,"%r14","%r15"); # KA<<<45
- &_rotl128 ("%rax","%rbx",15); # 45+15=60
- &_saveround (16,$out,-128,"%rax","%rbx"); # KL<<<60
- &_rotl128 ("%rcx","%rdx",30); # 30+30=60
- &_saveround (18,$out,-128,"%rcx","%rdx"); # KR<<<60
- &_rotl128 ("%r8","%r10",30); # 30+30=60
- &_saveround (20,$out,-128,"%r8","%r10"); # KB<<<60
- &_rotl128 ("%rax","%rbx",17); # 60+17=77
- &_saveround (22,$out,-128,"%rax","%rbx"); # KL<<<77
- &_rotl128 ("%r14","%r15",32); # 45+32=77
- &_saveround (24,$out,-128,"%r14","%r15"); # KA<<<77
- &_rotl128 ("%rcx","%rdx",34); # 60+34=94
- &_saveround (26,$out,-128,"%rcx","%rdx"); # KR<<<94
- &_rotl128 ("%r14","%r15",17); # 77+17=94
- &_saveround (28,$out,-128,"%r14","%r15"); # KA<<<77
- &_rotl128 ("%rax","%rbx",34); # 77+34=111
- &_saveround (30,$out,-128,"%rax","%rbx"); # KL<<<111
- &_rotl128 ("%r8","%r10",51); # 60+51=111
- &_saveround (32,$out,-128,"%r8","%r10"); # KB<<<111
-$code.=<<___;
- mov \$4,%eax
-.Ldone:
- mov 0(%rsp),%r15
- mov 8(%rsp),%r14
- mov 16(%rsp),%r13
- mov 24(%rsp),%rbp
- mov 32(%rsp),%rbx
- lea 40(%rsp),%rsp
-.Lkey_epilogue:
- ret
-.size Camellia_Ekeygen,.-Camellia_Ekeygen
-___
-}
-
-@SBOX=(
-112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
- 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
-134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
-166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
-139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
-223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
- 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
-254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
-170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
- 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
-135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
- 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
-233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
-120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
-114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
- 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
-
-sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); }
-sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); }
-sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); }
-sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); }
-
-$code.=<<___;
-.align 64
-.LCamellia_SIGMA:
-.long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
-.long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
-.long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
-.long 0, 0, 0, 0
-.LCamellia_SBOX:
-___
-# tables are interleaved, remember?
-sub data_word { $code.=".long\t".join(',',@_)."\n"; }
-for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
-for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
-
-# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
-# size_t length, const CAMELLIA_KEY *key,
-# unsigned char *ivp,const int enc);
-{
-$_key="0(%rsp)";
-$_end="8(%rsp)"; # inp+len&~15
-$_res="16(%rsp)"; # len&15
-$ivec="24(%rsp)";
-$_ivp="40(%rsp)";
-$_rsp="48(%rsp)";
-
-$code.=<<___;
-.globl Camellia_cbc_encrypt
-.type Camellia_cbc_encrypt,\@function,6
-.align 16
-Camellia_cbc_encrypt:
- cmp \$0,%rdx
- je .Lcbc_abort
- push %rbx
- push %rbp
- push %r12
- push %r13
- push %r14
- push %r15
-.Lcbc_prologue:
-
- mov %rsp,%rbp
- sub \$64,%rsp
- and \$-64,%rsp
-
- # place stack frame just "above mod 1024" the key schedule,
- # this ensures that cache associativity suffices
- lea -64-63(%rcx),%r10
- sub %rsp,%r10
- neg %r10
- and \$0x3C0,%r10
- sub %r10,%rsp
- #add \$8,%rsp # 8 is reserved for callee's ra
-
- mov %rdi,$inp # inp argument
- mov %rsi,$out # out argument
- mov %r8,%rbx # ivp argument
- mov %rcx,$key # key argument
- mov 272(%rcx),$keyend # grandRounds
-
- mov %r8,$_ivp
- mov %rbp,$_rsp
-
-.Lcbc_body:
- lea .LCamellia_SBOX(%rip),$Tbl
-
- mov \$32,%ecx
-.align 4
-.Lcbc_prefetch_sbox:
- mov 0($Tbl),%rax
- mov 32($Tbl),%rsi
- mov 64($Tbl),%rdi
- mov 96($Tbl),%r11
- lea 128($Tbl),$Tbl
- loop .Lcbc_prefetch_sbox
- sub \$4096,$Tbl
- shl \$6,$keyend
- mov %rdx,%rcx # len argument
- lea ($key,$keyend),$keyend
-
- cmp \$0,%r9d # enc argument
- je .LCBC_DECRYPT
-
- and \$-16,%rdx
- and \$15,%rcx # length residue
- lea ($inp,%rdx),%rdx
- mov $key,$_key
- mov %rdx,$_end
- mov %rcx,$_res
-
- cmp $inp,%rdx
- mov 0(%rbx),@S[0] # load IV
- mov 4(%rbx),@S[1]
- mov 8(%rbx),@S[2]
- mov 12(%rbx),@S[3]
- je .Lcbc_enc_tail
- jmp .Lcbc_eloop
-
-.align 16
-.Lcbc_eloop:
- xor 0($inp),@S[0]
- xor 4($inp),@S[1]
- xor 8($inp),@S[2]
- bswap @S[0]
- xor 12($inp),@S[3]
- bswap @S[1]
- bswap @S[2]
- bswap @S[3]
-
- call _x86_64_Camellia_encrypt
-
- mov $_key,$key # "rewind" the key
- bswap @S[0]
- mov $_end,%rdx
- bswap @S[1]
- mov $_res,%rcx
- bswap @S[2]
- mov @S[0],0($out)
- bswap @S[3]
- mov @S[1],4($out)
- mov @S[2],8($out)
- lea 16($inp),$inp
- mov @S[3],12($out)
- cmp %rdx,$inp
- lea 16($out),$out
- jne .Lcbc_eloop
-
- cmp \$0,%rcx
- jne .Lcbc_enc_tail
-
- mov $_ivp,$out
- mov @S[0],0($out) # write out IV residue
- mov @S[1],4($out)
- mov @S[2],8($out)
- mov @S[3],12($out)
- jmp .Lcbc_done
-
-.align 16
-.Lcbc_enc_tail:
- xor %rax,%rax
- mov %rax,0+$ivec
- mov %rax,8+$ivec
- mov %rax,$_res
-
-.Lcbc_enc_pushf:
- pushfq
- cld
- mov $inp,%rsi
- lea 8+$ivec,%rdi
- .long 0x9066A4F3 # rep movsb
- popfq
-.Lcbc_enc_popf:
-
- lea $ivec,$inp
- lea 16+$ivec,%rax
- mov %rax,$_end
- jmp .Lcbc_eloop # one more time
-
-.align 16
-.LCBC_DECRYPT:
- xchg $key,$keyend
- add \$15,%rdx
- and \$15,%rcx # length residue
- and \$-16,%rdx
- mov $key,$_key
- lea ($inp,%rdx),%rdx
- mov %rdx,$_end
- mov %rcx,$_res
-
- mov (%rbx),%rax # load IV
- mov 8(%rbx),%rbx
- jmp .Lcbc_dloop
-.align 16
-.Lcbc_dloop:
- mov 0($inp),@S[0]
- mov 4($inp),@S[1]
- mov 8($inp),@S[2]
- bswap @S[0]
- mov 12($inp),@S[3]
- bswap @S[1]
- mov %rax,0+$ivec # save IV to temporary storage
- bswap @S[2]
- mov %rbx,8+$ivec
- bswap @S[3]
-
- call _x86_64_Camellia_decrypt
-
- mov $_key,$key # "rewind" the key
- mov $_end,%rdx
- mov $_res,%rcx
-
- bswap @S[0]
- mov ($inp),%rax # load IV for next iteration
- bswap @S[1]
- mov 8($inp),%rbx
- bswap @S[2]
- xor 0+$ivec,@S[0]
- bswap @S[3]
- xor 4+$ivec,@S[1]
- xor 8+$ivec,@S[2]
- lea 16($inp),$inp
- xor 12+$ivec,@S[3]
- cmp %rdx,$inp
- je .Lcbc_ddone
-
- mov @S[0],0($out)
- mov @S[1],4($out)
- mov @S[2],8($out)
- mov @S[3],12($out)
-
- lea 16($out),$out
- jmp .Lcbc_dloop
-
-.align 16
-.Lcbc_ddone:
- mov $_ivp,%rdx
- cmp \$0,%rcx
- jne .Lcbc_dec_tail
-
- mov @S[0],0($out)
- mov @S[1],4($out)
- mov @S[2],8($out)
- mov @S[3],12($out)
-
- mov %rax,(%rdx) # write out IV residue
- mov %rbx,8(%rdx)
- jmp .Lcbc_done
-.align 16
-.Lcbc_dec_tail:
- mov @S[0],0+$ivec
- mov @S[1],4+$ivec
- mov @S[2],8+$ivec
- mov @S[3],12+$ivec
-
-.Lcbc_dec_pushf:
- pushfq
- cld
- lea 8+$ivec,%rsi
- lea ($out),%rdi
- .long 0x9066A4F3 # rep movsb
- popfq
-.Lcbc_dec_popf:
-
- mov %rax,(%rdx) # write out IV residue
- mov %rbx,8(%rdx)
- jmp .Lcbc_done
-
-.align 16
-.Lcbc_done:
- mov $_rsp,%rcx
- mov 0(%rcx),%r15
- mov 8(%rcx),%r14
- mov 16(%rcx),%r13
- mov 24(%rcx),%r12
- mov 32(%rcx),%rbp
- mov 40(%rcx),%rbx
- lea 48(%rcx),%rsp
-.Lcbc_abort:
- ret
-.size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
-
-.asciz "Camellia for x86_64 by <appro@openssl.org>"
-___
-}
-
-# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-# CONTEXT *context,DISPATCHER_CONTEXT *disp)
-if ($win64) {
-$rec="%rcx";
-$frame="%rdx";
-$context="%r8";
-$disp="%r9";
-
-$code.=<<___;
-.extern __imp_RtlVirtualUnwind
-.type common_se_handler,\@abi-omnipotent
-.align 16
-common_se_handler:
- push %rsi
- push %rdi
- push %rbx
- push %rbp
- push %r12
- push %r13
- push %r14
- push %r15
- pushfq
- lea -64(%rsp),%rsp
-
- mov 120($context),%rax # pull context->Rax
- mov 248($context),%rbx # pull context->Rip
-
- mov 8($disp),%rsi # disp->ImageBase
- mov 56($disp),%r11 # disp->HandlerData
-
- mov 0(%r11),%r10d # HandlerData[0]
- lea (%rsi,%r10),%r10 # prologue label
- cmp %r10,%rbx # context->Rip<prologue label
- jb .Lin_prologue
-
- mov 152($context),%rax # pull context->Rsp
-
- mov 4(%r11),%r10d # HandlerData[1]
- lea (%rsi,%r10),%r10 # epilogue label
- cmp %r10,%rbx # context->Rip>=epilogue label
- jae .Lin_prologue
-
- lea 40(%rax),%rax
- mov -8(%rax),%rbx
- mov -16(%rax),%rbp
- mov -24(%rax),%r13
- mov -32(%rax),%r14
- mov -40(%rax),%r15
- mov %rbx,144($context) # restore context->Rbx
- mov %rbp,160($context) # restore context->Rbp
- mov %r13,224($context) # restore context->R13
- mov %r14,232($context) # restore context->R14
- mov %r15,240($context) # restore context->R15
-
-.Lin_prologue:
- mov 8(%rax),%rdi
- mov 16(%rax),%rsi
- mov %rax,152($context) # restore context->Rsp
- mov %rsi,168($context) # restore context->Rsi
- mov %rdi,176($context) # restore context->Rdi
-
- jmp .Lcommon_seh_exit
-.size common_se_handler,.-common_se_handler
-
-.type cbc_se_handler,\@abi-omnipotent
-.align 16
-cbc_se_handler:
- push %rsi
- push %rdi
- push %rbx
- push %rbp
- push %r12
- push %r13
- push %r14
- push %r15
- pushfq
- lea -64(%rsp),%rsp
-
- mov 120($context),%rax # pull context->Rax
- mov 248($context),%rbx # pull context->Rip
-
- lea .Lcbc_prologue(%rip),%r10
- cmp %r10,%rbx # context->Rip<.Lcbc_prologue
- jb .Lin_cbc_prologue
-
- lea .Lcbc_body(%rip),%r10
- cmp %r10,%rbx # context->Rip<.Lcbc_body
- jb .Lin_cbc_frame_setup
-
- mov 152($context),%rax # pull context->Rsp
-
- lea .Lcbc_abort(%rip),%r10
- cmp %r10,%rbx # context->Rip>=.Lcbc_abort
- jae .Lin_cbc_prologue
-
- # handle pushf/popf in Camellia_cbc_encrypt
- lea .Lcbc_enc_pushf(%rip),%r10
- cmp %r10,%rbx # context->Rip<=.Lcbc_enc_pushf
- jbe .Lin_cbc_no_flag
- lea 8(%rax),%rax
- lea .Lcbc_enc_popf(%rip),%r10
- cmp %r10,%rbx # context->Rip<.Lcbc_enc_popf
- jb .Lin_cbc_no_flag
- lea -8(%rax),%rax
- lea .Lcbc_dec_pushf(%rip),%r10
- cmp %r10,%rbx # context->Rip<=.Lcbc_dec_pushf
- jbe .Lin_cbc_no_flag
- lea 8(%rax),%rax
- lea .Lcbc_dec_popf(%rip),%r10
- cmp %r10,%rbx # context->Rip<.Lcbc_dec_popf
- jb .Lin_cbc_no_flag
- lea -8(%rax),%rax
-
-.Lin_cbc_no_flag:
- mov 48(%rax),%rax # $_rsp
- lea 48(%rax),%rax
-
-.Lin_cbc_frame_setup:
- mov -8(%rax),%rbx
- mov -16(%rax),%rbp
- mov -24(%rax),%r12
- mov -32(%rax),%r13
- mov -40(%rax),%r14
- mov -48(%rax),%r15
- mov %rbx,144($context) # restore context->Rbx
- mov %rbp,160($context) # restore context->Rbp
- mov %r12,216($context) # restore context->R12
- mov %r13,224($context) # restore context->R13
- mov %r14,232($context) # restore context->R14
- mov %r15,240($context) # restore context->R15
-
-.Lin_cbc_prologue:
- mov 8(%rax),%rdi
- mov 16(%rax),%rsi
- mov %rax,152($context) # restore context->Rsp
- mov %rsi,168($context) # restore context->Rsi
- mov %rdi,176($context) # restore context->Rdi
-
-.align 4
-.Lcommon_seh_exit:
-
- mov 40($disp),%rdi # disp->ContextRecord
- mov $context,%rsi # context
- mov \$`1232/8`,%ecx # sizeof(CONTEXT)
- .long 0xa548f3fc # cld; rep movsq
-
- mov $disp,%rsi
- xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
- mov 8(%rsi),%rdx # arg2, disp->ImageBase
- mov 0(%rsi),%r8 # arg3, disp->ControlPc
- mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
- mov 40(%rsi),%r10 # disp->ContextRecord
- lea 56(%rsi),%r11 # &disp->HandlerData
- lea 24(%rsi),%r12 # &disp->EstablisherFrame
- mov %r10,32(%rsp) # arg5
- mov %r11,40(%rsp) # arg6
- mov %r12,48(%rsp) # arg7
- mov %rcx,56(%rsp) # arg8, (NULL)
- call *__imp_RtlVirtualUnwind(%rip)
-
- mov \$1,%eax # ExceptionContinueSearch
- lea 64(%rsp),%rsp
- popfq
- pop %r15
- pop %r14
- pop %r13
- pop %r12
- pop %rbp
- pop %rbx
- pop %rdi
- pop %rsi
- ret
-.size cbc_se_handler,.-cbc_se_handler
-
-.section .pdata
-.align 4
- .rva .LSEH_begin_Camellia_EncryptBlock_Rounds
- .rva .LSEH_end_Camellia_EncryptBlock_Rounds
- .rva .LSEH_info_Camellia_EncryptBlock_Rounds
-
- .rva .LSEH_begin_Camellia_DecryptBlock_Rounds
- .rva .LSEH_end_Camellia_DecryptBlock_Rounds
- .rva .LSEH_info_Camellia_DecryptBlock_Rounds
-
- .rva .LSEH_begin_Camellia_Ekeygen
- .rva .LSEH_end_Camellia_Ekeygen
- .rva .LSEH_info_Camellia_Ekeygen
-
- .rva .LSEH_begin_Camellia_cbc_encrypt
- .rva .LSEH_end_Camellia_cbc_encrypt
- .rva .LSEH_info_Camellia_cbc_encrypt
-
-.section .xdata
-.align 8
-.LSEH_info_Camellia_EncryptBlock_Rounds:
- .byte 9,0,0,0
- .rva common_se_handler
- .rva .Lenc_prologue,.Lenc_epilogue # HandlerData[]
-.LSEH_info_Camellia_DecryptBlock_Rounds:
- .byte 9,0,0,0
- .rva common_se_handler
- .rva .Ldec_prologue,.Ldec_epilogue # HandlerData[]
-.LSEH_info_Camellia_Ekeygen:
- .byte 9,0,0,0
- .rva common_se_handler
- .rva .Lkey_prologue,.Lkey_epilogue # HandlerData[]
-.LSEH_info_Camellia_cbc_encrypt:
- .byte 9,0,0,0
- .rva cbc_se_handler
-___
-}
-
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/cast/c_cfb64.c b/crypto/openssl/crypto/cast/c_cfb64.c
index 514c005..dcec13a 100644
--- a/crypto/openssl/crypto/cast/c_cfb64.c
+++ b/crypto/openssl/crypto/cast/c_cfb64.c
@@ -65,7 +65,7 @@
*/
void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
- long length, CAST_KEY *schedule, unsigned char *ivec,
+ long length, const CAST_KEY *schedule, unsigned char *ivec,
int *num, int enc)
{
register CAST_LONG v0,v1,t;
@@ -119,4 +119,3 @@ void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
v0=v1=ti[0]=ti[1]=t=c=cc=0;
*num=n;
}
-
diff --git a/crypto/openssl/crypto/cast/c_ecb.c b/crypto/openssl/crypto/cast/c_ecb.c
index f2dc606..b6a3b1f 100644
--- a/crypto/openssl/crypto/cast/c_ecb.c
+++ b/crypto/openssl/crypto/cast/c_ecb.c
@@ -63,7 +63,7 @@
const char CAST_version[]="CAST" OPENSSL_VERSION_PTEXT;
void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
- CAST_KEY *ks, int enc)
+ const CAST_KEY *ks, int enc)
{
CAST_LONG l,d[2];
@@ -77,4 +77,3 @@ void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
l=d[1]; l2n(l,out);
l=d[0]=d[1]=0;
}
-
diff --git a/crypto/openssl/crypto/cast/c_enc.c b/crypto/openssl/crypto/cast/c_enc.c
index 0fe2cff..357c41e 100644
--- a/crypto/openssl/crypto/cast/c_enc.c
+++ b/crypto/openssl/crypto/cast/c_enc.c
@@ -59,9 +59,10 @@
#include <openssl/cast.h>
#include "cast_lcl.h"
-void CAST_encrypt(CAST_LONG *data, CAST_KEY *key)
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
{
- register CAST_LONG l,r,*k,t;
+ register CAST_LONG l,r,t;
+ const register CAST_LONG *k;
k= &(key->data[0]);
l=data[0];
@@ -91,9 +92,10 @@ void CAST_encrypt(CAST_LONG *data, CAST_KEY *key)
data[0]=r&0xffffffffL;
}
-void CAST_decrypt(CAST_LONG *data, CAST_KEY *key)
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
{
- register CAST_LONG l,r,*k,t;
+ register CAST_LONG l,r,t;
+ const register CAST_LONG *k;
k= &(key->data[0]);
l=data[0];
@@ -124,7 +126,7 @@ void CAST_decrypt(CAST_LONG *data, CAST_KEY *key)
}
void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
- CAST_KEY *ks, unsigned char *iv, int enc)
+ const CAST_KEY *ks, unsigned char *iv, int enc)
{
register CAST_LONG tin0,tin1;
register CAST_LONG tout0,tout1,xor0,xor1;
@@ -204,4 +206,3 @@ void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}
-
diff --git a/crypto/openssl/crypto/cast/c_ofb64.c b/crypto/openssl/crypto/cast/c_ofb64.c
index fd0469a..cb32224 100644
--- a/crypto/openssl/crypto/cast/c_ofb64.c
+++ b/crypto/openssl/crypto/cast/c_ofb64.c
@@ -64,7 +64,7 @@
* 64bit block we have used is contained in *num;
*/
void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
- long length, CAST_KEY *schedule, unsigned char *ivec,
+ long length, const CAST_KEY *schedule, unsigned char *ivec,
int *num)
{
register CAST_LONG v0,v1,t;
@@ -108,4 +108,3 @@ void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
t=v0=v1=ti[0]=ti[1]=0;
*num=n;
}
-
diff --git a/crypto/openssl/crypto/cast/cast.h b/crypto/openssl/crypto/cast/cast.h
index 1faf580..6e0cd31 100644
--- a/crypto/openssl/crypto/cast/cast.h
+++ b/crypto/openssl/crypto/cast/cast.h
@@ -87,17 +87,17 @@ typedef struct cast_key_st
void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
#endif
void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
-void CAST_ecb_encrypt(const unsigned char *in,unsigned char *out,CAST_KEY *key,
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key,
int enc);
-void CAST_encrypt(CAST_LONG *data,CAST_KEY *key);
-void CAST_decrypt(CAST_LONG *data,CAST_KEY *key);
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
- CAST_KEY *ks, unsigned char *iv, int enc);
+ const CAST_KEY *ks, unsigned char *iv, int enc);
void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
- long length, CAST_KEY *schedule, unsigned char *ivec,
+ long length, const CAST_KEY *schedule, unsigned char *ivec,
int *num, int enc);
void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
- long length, CAST_KEY *schedule, unsigned char *ivec,
+ long length, const CAST_KEY *schedule, unsigned char *ivec,
int *num);
#ifdef __cplusplus
diff --git a/crypto/openssl/crypto/cms/cms_ess.c b/crypto/openssl/crypto/cms/cms_ess.c
index ed34ff3..65613aa 100644
--- a/crypto/openssl/crypto/cms/cms_ess.c
+++ b/crypto/openssl/crypto/cms/cms_ess.c
@@ -344,7 +344,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
/* Get original receipt request details */
- if (!CMS_get1_ReceiptRequest(osi, &rr))
+ if (CMS_get1_ReceiptRequest(osi, &rr) <= 0)
{
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
goto err;
@@ -385,7 +385,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
/* Get original receipt request details */
- if (!CMS_get1_ReceiptRequest(si, &rr))
+ if (CMS_get1_ReceiptRequest(si, &rr) <= 0)
{
CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
goto err;
diff --git a/crypto/openssl/crypto/cms/cms_lib.c b/crypto/openssl/crypto/cms/cms_lib.c
index 8e6c1d2..cc00526 100644
--- a/crypto/openssl/crypto/cms/cms_lib.c
+++ b/crypto/openssl/crypto/cms/cms_lib.c
@@ -415,7 +415,11 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
return 0;
}
BIO_get_md_ctx(chain, &mtmp);
- if (EVP_MD_CTX_type(mtmp) == nid)
+ if (EVP_MD_CTX_type(mtmp) == nid
+ /* Workaround for broken implementations that use signature
+ * algorithm OID instead of digest.
+ */
+ || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
{
EVP_MD_CTX_copy_ex(mctx, mtmp);
return 1;
diff --git a/crypto/openssl/crypto/comp/c_zlib.c b/crypto/openssl/crypto/comp/c_zlib.c
index eccfd09..8df7792 100644
--- a/crypto/openssl/crypto/comp/c_zlib.c
+++ b/crypto/openssl/crypto/comp/c_zlib.c
@@ -136,15 +136,6 @@ struct zlib_state
static int zlib_stateful_ex_idx = -1;
-static void zlib_stateful_free_ex_data(void *obj, void *item,
- CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
- {
- struct zlib_state *state = (struct zlib_state *)item;
- inflateEnd(&state->istream);
- deflateEnd(&state->ostream);
- OPENSSL_free(state);
- }
-
static int zlib_stateful_init(COMP_CTX *ctx)
{
int err;
@@ -188,6 +179,12 @@ static int zlib_stateful_init(COMP_CTX *ctx)
static void zlib_stateful_finish(COMP_CTX *ctx)
{
+ struct zlib_state *state =
+ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+ zlib_stateful_ex_idx);
+ inflateEnd(&state->istream);
+ deflateEnd(&state->ostream);
+ OPENSSL_free(state);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
}
@@ -402,7 +399,7 @@ COMP_METHOD *COMP_zlib(void)
if (zlib_stateful_ex_idx == -1)
zlib_stateful_ex_idx =
CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
- 0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
+ 0,NULL,NULL,NULL,NULL);
CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
if (zlib_stateful_ex_idx == -1)
goto err;
diff --git a/crypto/openssl/crypto/cryptlib.c b/crypto/openssl/crypto/cryptlib.c
index 8f9e88e..497d003 100644
--- a/crypto/openssl/crypto/cryptlib.c
+++ b/crypto/openssl/crypto/cryptlib.c
@@ -513,7 +513,7 @@ void OPENSSL_showfatal (const char *fmta,...)
#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
/* this -------------v--- guards NT-specific calls */
- if (GetVersion() < 0x80000000 && OPENSSL_isservice())
+ if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0)
{ HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
const TCHAR *pmsg=buf;
ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
diff --git a/crypto/openssl/crypto/dsa/Makefile b/crypto/openssl/crypto/dsa/Makefile
index 2cc45cd..6c9578c 100644
--- a/crypto/openssl/crypto/dsa/Makefile
+++ b/crypto/openssl/crypto/dsa/Makefile
@@ -84,8 +84,9 @@ dsa_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
dsa_asn1.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
dsa_asn1.o: ../../include/openssl/opensslconf.h
dsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dsa_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dsa_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_asn1.c
+dsa_asn1.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_asn1.o: ../cryptlib.h dsa_asn1.c
dsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
dsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
dsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
diff --git a/crypto/openssl/crypto/dsa/dsa_asn1.c b/crypto/openssl/crypto/dsa/dsa_asn1.c
index 0645fac..bc7d7a0 100644
--- a/crypto/openssl/crypto/dsa/dsa_asn1.c
+++ b/crypto/openssl/crypto/dsa/dsa_asn1.c
@@ -62,6 +62,7 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
+#include <openssl/rand.h>
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#endif
@@ -155,6 +156,7 @@ int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
return 0;
}
#endif
+ RAND_seed(dgst, dlen);
s=DSA_do_sign(dgst,dlen,dsa);
if (s == NULL)
{
diff --git a/crypto/openssl/crypto/dsa/dsa_lib.c b/crypto/openssl/crypto/dsa/dsa_lib.c
index 7ac9dc8..85556d1 100644
--- a/crypto/openssl/crypto/dsa/dsa_lib.c
+++ b/crypto/openssl/crypto/dsa/dsa_lib.c
@@ -190,7 +190,7 @@ DSA *DSA_new_method(ENGINE *engine)
ret->method_mont_p=NULL;
ret->references=1;
- ret->flags=ret->meth->flags;
+ ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{
diff --git a/crypto/openssl/crypto/dso/dso_dlfcn.c b/crypto/openssl/crypto/dso/dso_dlfcn.c
index 1fd1010..d91e821 100644
--- a/crypto/openssl/crypto/dso/dso_dlfcn.c
+++ b/crypto/openssl/crypto/dso/dso_dlfcn.c
@@ -237,7 +237,10 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname)
static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
{
void *ptr;
- DSO_FUNC_TYPE sym, *tsym = &sym;
+ union {
+ DSO_FUNC_TYPE sym;
+ void *dlret;
+ } u;
if((dso == NULL) || (symname == NULL))
{
@@ -255,14 +258,14 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
return(NULL);
}
- *(void **)(tsym) = dlsym(ptr, symname);
- if(sym == NULL)
+ u.dlret = dlsym(ptr, symname);
+ if(u.dlret == NULL)
{
DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
return(NULL);
}
- return(sym);
+ return u.sym;
}
static char *dlfcn_merger(DSO *dso, const char *filespec1,
@@ -332,6 +335,15 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
return(merged);
}
+#ifdef OPENSSL_SYS_MACOSX
+#define DSO_ext ".dylib"
+#define DSO_extlen 6
+#else
+#define DSO_ext ".so"
+#define DSO_extlen 3
+#endif
+
+
static char *dlfcn_name_converter(DSO *dso, const char *filename)
{
char *translated;
@@ -342,8 +354,8 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
transform = (strstr(filename, "/") == NULL);
if(transform)
{
- /* We will convert this to "%s.so" or "lib%s.so" */
- rsize += 3; /* The length of ".so" */
+ /* We will convert this to "%s.so" or "lib%s.so" etc */
+ rsize += DSO_extlen; /* The length of ".so" */
if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
rsize += 3; /* The length of "lib" */
}
@@ -357,9 +369,9 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
if(transform)
{
if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
- sprintf(translated, "lib%s.so", filename);
+ sprintf(translated, "lib%s" DSO_ext, filename);
else
- sprintf(translated, "%s.so", filename);
+ sprintf(translated, "%s" DSO_ext, filename);
}
else
sprintf(translated, "%s", filename);
diff --git a/crypto/openssl/crypto/ec/ec2_smpl.c b/crypto/openssl/crypto/ec/ec2_smpl.c
index 5cd1eac..522d036 100644
--- a/crypto/openssl/crypto/ec/ec2_smpl.c
+++ b/crypto/openssl/crypto/ec/ec2_smpl.c
@@ -174,8 +174,10 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
dest->poly[2] = src->poly[2];
dest->poly[3] = src->poly[3];
dest->poly[4] = src->poly[4];
- bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2);
- bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2);
+ if(bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
+ return 0;
+ if(bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
+ return 0;
for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
return 1;
@@ -199,12 +201,12 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
/* group->a */
if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
- bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2);
+ if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
/* group->b */
if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
- bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2);
+ if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
ret = 1;
diff --git a/crypto/openssl/crypto/ecdsa/Makefile b/crypto/openssl/crypto/ecdsa/Makefile
index 4865f3c..49e2681 100644
--- a/crypto/openssl/crypto/ecdsa/Makefile
+++ b/crypto/openssl/crypto/ecdsa/Makefile
@@ -123,10 +123,11 @@ ecs_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
ecs_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ecs_sign.o: ../../include/openssl/opensslconf.h
ecs_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecs_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-ecs_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-ecs_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ecs_sign.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_sign.c
+ecs_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ecs_sign.o: ecs_locl.h ecs_sign.c
ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
diff --git a/crypto/openssl/crypto/ecdsa/ecs_ossl.c b/crypto/openssl/crypto/ecdsa/ecs_ossl.c
index 3ead1af9..551cf50 100644
--- a/crypto/openssl/crypto/ecdsa/ecs_ossl.c
+++ b/crypto/openssl/crypto/ecdsa/ecs_ossl.c
@@ -212,7 +212,7 @@ err:
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
- int ok = 0;
+ int ok = 0, i;
BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
@@ -251,22 +251,19 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
- if (8 * dgst_len > BN_num_bits(order))
+ i = BN_num_bits(order);
+ /* Need to truncate digest if it is too long: first truncate whole
+ * bytes.
+ */
+ if (8 * dgst_len > i)
+ dgst_len = (i + 7)/8;
+ if (!BN_bin2bn(dgst, dgst_len, m))
{
- /* XXX
- *
- * Should provide for optional hash truncation:
- * Keep the BN_num_bits(order) leftmost bits of dgst
- * (see March 2006 FIPS 186-3 draft, which has a few
- * confusing errors in this part though)
- */
-
- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
- ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
-
- if (!BN_bin2bn(dgst, dgst_len, m))
+ /* If still too long truncate remaining bits with a shift */
+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
@@ -346,7 +343,7 @@ err:
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey)
{
- int ret = -1;
+ int ret = -1, i;
BN_CTX *ctx;
BIGNUM *order, *u1, *u2, *m, *X;
EC_POINT *point = NULL;
@@ -384,21 +381,6 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
- if (8 * dgst_len > BN_num_bits(order))
- {
- /* XXX
- *
- * Should provide for optional hash truncation:
- * Keep the BN_num_bits(order) leftmost bits of dgst
- * (see March 2006 FIPS 186-3 draft, which has a few
- * confusing errors in this part though)
- */
-
- ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY,
- ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
- ret = 0;
- goto err;
- }
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
@@ -415,11 +397,23 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
goto err;
}
/* digest -> m */
+ i = BN_num_bits(order);
+ /* Need to truncate digest if it is too long: first truncate whole
+ * bytes.
+ */
+ if (8 * dgst_len > i)
+ dgst_len = (i + 7)/8;
if (!BN_bin2bn(dgst, dgst_len, m))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
+ /* If still too long truncate remaining bits with a shift */
+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
+ {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
/* u1 = m * tmp mod order */
if (!BN_mod_mul(u1, m, u2, order, ctx))
{
diff --git a/crypto/openssl/crypto/ecdsa/ecs_sign.c b/crypto/openssl/crypto/ecdsa/ecs_sign.c
index 74b1fe8..353d5af 100644
--- a/crypto/openssl/crypto/ecdsa/ecs_sign.c
+++ b/crypto/openssl/crypto/ecdsa/ecs_sign.c
@@ -57,6 +57,7 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#include <openssl/rand.h>
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
@@ -83,6 +84,7 @@ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
EC_KEY *eckey)
{
ECDSA_SIG *s;
+ RAND_seed(dgst, dlen);
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
if (s == NULL)
{
diff --git a/crypto/openssl/crypto/engine/Makefile b/crypto/openssl/crypto/engine/Makefile
index 0cc3722..b52fa48 100644
--- a/crypto/openssl/crypto/engine/Makefile
+++ b/crypto/openssl/crypto/engine/Makefile
@@ -112,19 +112,21 @@ eng_cnf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
eng_cnf.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_cnf.c eng_int.h
eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+eng_cryptodev.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
eng_cryptodev.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
eng_cryptodev.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
-eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-eng_cryptodev.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_cryptodev.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_cryptodev.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_cryptodev.o: ../../include/openssl/obj_mac.h
eng_cryptodev.o: ../../include/openssl/objects.h
eng_cryptodev.o: ../../include/openssl/opensslconf.h
eng_cryptodev.o: ../../include/openssl/opensslv.h
eng_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-eng_cryptodev.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-eng_cryptodev.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-eng_cryptodev.o: eng_cryptodev.c
+eng_cryptodev.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+eng_cryptodev.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_cryptodev.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_cryptodev.o: ../../include/openssl/x509_vfy.h eng_cryptodev.c
eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
eng_ctrl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/crypto/openssl/crypto/engine/eng_all.c b/crypto/openssl/crypto/engine/eng_all.c
index d29cd57..f29c167 100644
--- a/crypto/openssl/crypto/engine/eng_all.c
+++ b/crypto/openssl/crypto/engine/eng_all.c
@@ -104,7 +104,7 @@ void ENGINE_load_builtin_engines(void)
#endif
#endif
#ifndef OPENSSL_NO_HW
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
ENGINE_load_cryptodev();
#endif
#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
diff --git a/crypto/openssl/crypto/engine/eng_cnf.c b/crypto/openssl/crypto/engine/eng_cnf.c
index 08066ce..95c4070 100644
--- a/crypto/openssl/crypto/engine/eng_cnf.c
+++ b/crypto/openssl/crypto/engine/eng_cnf.c
@@ -95,7 +95,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
int ret = 0;
long do_init = -1;
STACK_OF(CONF_VALUE) *ecmds;
- CONF_VALUE *ecmd;
+ CONF_VALUE *ecmd = NULL;
char *ctrlname, *ctrlvalue;
ENGINE *e = NULL;
int soft = 0;
@@ -157,7 +157,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
return 1;
}
if (!e)
- return 0;
+ goto err;
}
/* Allow "EMPTY" to mean no value: this allows a valid
* "value" to be passed to ctrls of type NO_INPUT
@@ -186,16 +186,27 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
}
else if (!ENGINE_ctrl_cmd_string(e,
ctrlname, ctrlvalue, 0))
- return 0;
+ goto err;
}
}
if (e && (do_init == -1) && !int_engine_init(e))
+ {
+ ecmd = NULL;
goto err;
+ }
ret = 1;
err:
+ if (ret != 1)
+ {
+ ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
+ if (ecmd)
+ ERR_add_error_data(6, "section=", ecmd->section,
+ ", name=", ecmd->name,
+ ", value=", ecmd->value);
+ }
if (e)
ENGINE_free(e);
return ret;
diff --git a/crypto/openssl/crypto/engine/eng_cryptodev.c b/crypto/openssl/crypto/engine/eng_cryptodev.c
index 4f2ec69..eef1e2d 100644
--- a/crypto/openssl/crypto/engine/eng_cryptodev.c
+++ b/crypto/openssl/crypto/engine/eng_cryptodev.c
@@ -25,12 +25,15 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-/* $FreeBSD$ */
#include <openssl/objects.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
(defined(OpenBSD) || defined(__FreeBSD__))
@@ -80,7 +83,7 @@ static int cryptodev_max_iv(int cipher);
static int cryptodev_key_length_valid(int cipher, int len);
static int cipher_nid_to_cryptodev(int nid);
static int get_cryptodev_ciphers(const int **cnids);
-static int get_cryptodev_digests(const int **cnids);
+/*static int get_cryptodev_digests(const int **cnids);*/
static int cryptodev_usable_ciphers(const int **nids);
static int cryptodev_usable_digests(const int **nids);
static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -101,7 +104,7 @@ static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
- RSA *rsa);
+ RSA *rsa, BN_CTX *ctx);
static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
@@ -140,6 +143,7 @@ static struct {
{ 0, NID_undef, 0, 0, },
};
+#if 0
static struct {
int id;
int nid;
@@ -152,6 +156,7 @@ static struct {
{ CRYPTO_SHA1, NID_undef, },
{ 0, NID_undef, },
};
+#endif
/*
* Return a fd if /dev/crypto seems usable, 0 otherwise.
@@ -286,6 +291,7 @@ get_cryptodev_ciphers(const int **cnids)
return (count);
}
+#if 0 /* unused */
/*
* Find out what digests /dev/crypto will let us have a session for.
* XXX note, that some of these openssl doesn't deal with yet!
@@ -322,6 +328,8 @@ get_cryptodev_digests(const int **cnids)
return (count);
}
+#endif
+
/*
* Find the useable ciphers|digests from dev/crypto - this is the first
* thing called by the engine init crud which determines what it
@@ -375,7 +383,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
struct crypt_op cryp;
struct dev_crypto_state *state = ctx->cipher_data;
struct session_op *sess = &state->d_sess;
- void *iiv;
+ const void *iiv;
unsigned char save_iv[EVP_MAX_IV_LENGTH];
if (state->d_fd < 0)
@@ -399,7 +407,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (ctx->cipher->iv_len) {
cryp.iv = (caddr_t) ctx->iv;
if (!ctx->encrypt) {
- iiv = (void *) in + inl - ctx->cipher->iv_len;
+ iiv = in + inl - ctx->cipher->iv_len;
memcpy(save_iv, iiv, ctx->cipher->iv_len);
}
} else
@@ -414,7 +422,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (ctx->cipher->iv_len) {
if (ctx->encrypt)
- iiv = (void *) out + inl - ctx->cipher->iv_len;
+ iiv = out + inl - ctx->cipher->iv_len;
else
iiv = save_iv;
memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
@@ -444,7 +452,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
if ((state->d_fd = get_dev_crypto()) < 0)
return (0);
- sess->key = (unsigned char *)key;
+ sess->key = (char *)key;
sess->keylen = ctx->key_len;
sess->cipher = cipher;
@@ -626,7 +634,7 @@ static int
bn2crparam(const BIGNUM *a, struct crparam *crp)
{
int i, j, k;
- ssize_t words, bytes, bits;
+ ssize_t bytes, bits;
u_char *b;
crp->crp_p = NULL;
@@ -639,7 +647,7 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
if (b == NULL)
return (1);
- crp->crp_p = b;
+ crp->crp_p = (char *)b;
crp->crp_nbits = bits;
for (i = 0, j = 0; i < a->top; i++) {
@@ -747,24 +755,29 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
goto err;
kop.crk_iparams = 3;
- if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) {
+ if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ printf("OCF asym process failed, Running in software\n");
+ ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
+
+ } else if (ECANCELED == kop.crk_status) {
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ printf("OCF hardware operation cancelled. Running in Software\n");
ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
}
+ /* else cryptodev operation worked ok ==> ret = 1*/
+
err:
zapparams(&kop);
return (ret);
}
static int
-cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
+cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
{
int r;
- BN_CTX *ctx;
- ctx = BN_CTX_new();
r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
- BN_CTX_free(ctx);
return (r);
}
@@ -796,10 +809,18 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
goto err;
kop.crk_iparams = 6;
- if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
+ if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ printf("OCF asym process failed, running in Software\n");
+ ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+
+ } else if (ECANCELED == kop.crk_status) {
+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ printf("OCF hardware operation cancelled. Running in Software\n");
ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
}
+ /* else cryptodev operation worked ok ==> ret = 1*/
+
err:
zapparams(&kop);
return (ret);
@@ -935,7 +956,8 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
kop.crk_iparams = 7;
if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
- dsaret = kop.crk_status;
+/*OCF success value is 0, if not zero, change dsaret to fail*/
+ if(0 != kop.crk_status) dsaret = 0;
} else {
const DSA_METHOD *meth = DSA_OpenSSL();
@@ -995,7 +1017,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
goto err;
kop.crk_iparams = 3;
- kop.crk_param[3].crp_p = key;
+ kop.crk_param[3].crp_p = (char *)key;
kop.crk_param[3].crp_nbits = keylen * 8;
kop.crk_oparams = 1;
diff --git a/crypto/openssl/crypto/engine/eng_ctrl.c b/crypto/openssl/crypto/engine/eng_ctrl.c
index 95b6b45..5ce25d9 100644
--- a/crypto/openssl/crypto/engine/eng_ctrl.c
+++ b/crypto/openssl/crypto/engine/eng_ctrl.c
@@ -280,7 +280,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
}
/* Force the result of the control command to 0 or 1, for the reasons
* mentioned before. */
- if (ENGINE_ctrl(e, num, i, p, f))
+ if (ENGINE_ctrl(e, num, i, p, f) > 0)
return 1;
return 0;
}
@@ -345,7 +345,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
* usage of these commands is consistent across applications and
* that certain applications don't understand it one way, and
* others another. */
- if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
+ if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
return 1;
return 0;
}
@@ -360,7 +360,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
if(flags & ENGINE_CMD_FLAG_STRING)
{
/* Same explanation as above */
- if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
+ if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
return 1;
return 0;
}
@@ -383,7 +383,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
}
/* Force the result of the control command to 0 or 1, for the reasons
* mentioned before. */
- if(ENGINE_ctrl(e, num, l, NULL, NULL))
+ if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
return 1;
return 0;
}
diff --git a/crypto/openssl/crypto/engine/eng_err.c b/crypto/openssl/crypto/engine/eng_err.c
index 574ffbb..ac74dd1 100644
--- a/crypto/openssl/crypto/engine/eng_err.c
+++ b/crypto/openssl/crypto/engine/eng_err.c
@@ -1,6 +1,6 @@
/* crypto/engine/eng_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -124,6 +124,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
+{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
diff --git a/crypto/openssl/crypto/engine/eng_table.c b/crypto/openssl/crypto/engine/eng_table.c
index 8879a26..8fc47b3 100644
--- a/crypto/openssl/crypto/engine/eng_table.c
+++ b/crypto/openssl/crypto/engine/eng_table.c
@@ -237,6 +237,7 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
#endif
return NULL;
}
+ ERR_set_mark();
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
/* Check again inside the lock otherwise we could race against cleanup
* operations. But don't worry about a fprintf(stderr). */
@@ -310,6 +311,6 @@ end:
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
/* Whatever happened, any failed init()s are not failures in this
* context, so clear our error state. */
- ERR_clear_error();
+ ERR_pop_to_mark();
return ret;
}
diff --git a/crypto/openssl/crypto/engine/engine.h b/crypto/openssl/crypto/engine/engine.h
index f503595..d4bc1ef 100644
--- a/crypto/openssl/crypto/engine/engine.h
+++ b/crypto/openssl/crypto/engine/engine.h
@@ -339,9 +339,11 @@ void ENGINE_load_ubsec(void);
void ENGINE_load_cryptodev(void);
void ENGINE_load_padlock(void);
void ENGINE_load_builtin_engines(void);
+#ifdef OPENSSL_SYS_WIN32
#ifndef OPENSSL_NO_CAPIENG
void ENGINE_load_capi(void);
#endif
+#endif
/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
* "registry" handling. */
@@ -767,6 +769,7 @@ void ERR_load_ENGINE_strings(void);
#define ENGINE_R_DSO_FAILURE 104
#define ENGINE_R_DSO_NOT_FOUND 132
#define ENGINE_R_ENGINES_SECTION_ERROR 148
+#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 101
#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
#define ENGINE_R_ENGINE_SECTION_ERROR 149
#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
diff --git a/crypto/openssl/crypto/err/Makefile b/crypto/openssl/crypto/err/Makefile
index 91d1379..96d8a1a 100644
--- a/crypto/openssl/crypto/err/Makefile
+++ b/crypto/openssl/crypto/err/Makefile
@@ -83,23 +83,24 @@ err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
err.o: ../cryptlib.h err.c
err_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
err_all.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-err_all.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-err_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
-err_all.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-err_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-err_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
-err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-err_all.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-err_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-err_all.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
-err_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-err_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
-err_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-err_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-err_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-err_all.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-err_all.o: ../../include/openssl/x509v3.h err_all.c
+err_all.o: ../../include/openssl/comp.h ../../include/openssl/conf.h
+err_all.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+err_all.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
+err_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+err_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+err_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+err_all.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+err_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+err_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+err_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem2.h
+err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+err_all.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+err_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+err_all.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
+err_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+err_all.o: err_all.c
err_bio.o: ../../e_os.h ../../include/openssl/bio.h
err_bio.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
err_bio.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/openssl/crypto/err/err_all.c b/crypto/openssl/crypto/err/err_all.c
index f21a527..39796f7 100644
--- a/crypto/openssl/crypto/err/err_all.c
+++ b/crypto/openssl/crypto/err/err_all.c
@@ -104,6 +104,7 @@
#ifndef OPENSSL_NO_JPAKE
#include <openssl/jpake.h>
#endif
+#include <openssl/comp.h>
void ERR_load_crypto_strings(void)
{
@@ -157,5 +158,6 @@ void ERR_load_crypto_strings(void)
#ifndef OPENSSL_NO_JPAKE
ERR_load_JPAKE_strings();
#endif
+ ERR_load_COMP_strings();
#endif
}
diff --git a/crypto/openssl/crypto/evp/c_allc.c b/crypto/openssl/crypto/evp/c_allc.c
index 7054d81..e45cee8 100644
--- a/crypto/openssl/crypto/evp/c_allc.c
+++ b/crypto/openssl/crypto/evp/c_allc.c
@@ -71,6 +71,8 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_des_cfb8());
EVP_add_cipher(EVP_des_ede_cfb());
EVP_add_cipher(EVP_des_ede3_cfb());
+ EVP_add_cipher(EVP_des_ede3_cfb1());
+ EVP_add_cipher(EVP_des_ede3_cfb8());
EVP_add_cipher(EVP_des_ofb());
EVP_add_cipher(EVP_des_ede_ofb());
diff --git a/crypto/openssl/crypto/evp/c_alld.c b/crypto/openssl/crypto/evp/c_alld.c
index d270b0e..e0841d1 100644
--- a/crypto/openssl/crypto/evp/c_alld.c
+++ b/crypto/openssl/crypto/evp/c_alld.c
@@ -64,9 +64,6 @@
void OpenSSL_add_all_digests(void)
{
-#ifndef OPENSSL_NO_MD2
- EVP_add_digest(EVP_md2());
-#endif
#ifndef OPENSSL_NO_MD4
EVP_add_digest(EVP_md4());
#endif
diff --git a/crypto/openssl/crypto/evp/digest.c b/crypto/openssl/crypto/evp/digest.c
index 3bc2d12..10a3607 100644
--- a/crypto/openssl/crypto/evp/digest.c
+++ b/crypto/openssl/crypto/evp/digest.c
@@ -127,7 +127,8 @@ EVP_MD_CTX *EVP_MD_CTX_create(void)
{
EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
- EVP_MD_CTX_init(ctx);
+ if (ctx)
+ EVP_MD_CTX_init(ctx);
return ctx;
}
@@ -234,6 +235,7 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
{
/* Same comment from evp_enc.c */
EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
+ ENGINE_finish(impl);
return 0;
}
/* We'll use the ENGINE's private digest definition */
@@ -299,7 +301,14 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
OPENSSL_free(ctx->md_data);
ctx->digest=type;
if (type->ctx_size)
+ {
ctx->md_data=OPENSSL_malloc(type->ctx_size);
+ if (!ctx->md_data)
+ {
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
}
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
@@ -380,8 +389,17 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
if (out->digest->ctx_size)
{
- if (tmp_buf) out->md_data = tmp_buf;
- else out->md_data=OPENSSL_malloc(out->digest->ctx_size);
+ if (tmp_buf)
+ out->md_data = tmp_buf;
+ else
+ {
+ out->md_data=OPENSSL_malloc(out->digest->ctx_size);
+ if (!out->md_data)
+ {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
memcpy(out->md_data,in->md_data,out->digest->ctx_size);
}
diff --git a/crypto/openssl/crypto/evp/evp_lib.c b/crypto/openssl/crypto/evp/evp_lib.c
index 174cf6c..9c20061 100644
--- a/crypto/openssl/crypto/evp/evp_lib.c
+++ b/crypto/openssl/crypto/evp/evp_lib.c
@@ -163,6 +163,12 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
return NID_des_cfb64;
+ case NID_des_ede3_cfb64:
+ case NID_des_ede3_cfb8:
+ case NID_des_ede3_cfb1:
+
+ return NID_des_cfb64;
+
default:
/* Check it has an OID and it is valid */
otmp = OBJ_nid2obj(nid);
diff --git a/crypto/openssl/crypto/evp/evp_locl.h b/crypto/openssl/crypto/evp/evp_locl.h
index eabcc96..ef6c432 100644
--- a/crypto/openssl/crypto/evp/evp_locl.h
+++ b/crypto/openssl/crypto/evp/evp_locl.h
@@ -139,10 +139,10 @@ BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
get_asn1, ctrl)
#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
- iv_len, flags, init_key, cleanup, set_asn1, \
+ flags, init_key, cleanup, set_asn1, \
get_asn1, ctrl) \
BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
- iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+ 0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
#define BLOCK_CIPHER_defs(cname, kstruct, \
nid, block_size, key_len, iv_len, cbits, flags, \
@@ -153,7 +153,7 @@ BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
init_key, cleanup, set_asn1, get_asn1, ctrl)
diff --git a/crypto/openssl/crypto/evp/names.c b/crypto/openssl/crypto/evp/names.c
index e2e04c3..945879d 100644
--- a/crypto/openssl/crypto/evp/names.c
+++ b/crypto/openssl/crypto/evp/names.c
@@ -90,7 +90,7 @@ int EVP_add_digest(const EVP_MD *md)
r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md);
if (r == 0) return(0);
- if (md->type != md->pkey_type)
+ if (md->pkey_type && md->type != md->pkey_type)
{
r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
diff --git a/crypto/openssl/crypto/lhash/lhash.c b/crypto/openssl/crypto/lhash/lhash.c
index 04ea802..0b41f87 100644
--- a/crypto/openssl/crypto/lhash/lhash.c
+++ b/crypto/openssl/crypto/lhash/lhash.c
@@ -305,16 +305,40 @@ void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
static void expand(LHASH *lh)
{
LHASH_NODE **n,**n1,**n2,*np;
- unsigned int p,i,j;
+ unsigned int p,i,j,pmax;
unsigned long hash,nni;
+ p=(int)lh->p++;
+ nni=lh->num_alloc_nodes;
+ pmax=lh->pmax;
+
+ if ((lh->p) >= lh->pmax)
+ {
+ j=(int)lh->num_alloc_nodes*2;
+ n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
+ (int)sizeof(LHASH_NODE *)*j);
+ if (n == NULL)
+ {
+/* fputs("realloc error in lhash",stderr); */
+ lh->error++;
+ lh->p=0;
+ return;
+ }
+ /* else */
+ for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
+ n[i]=NULL; /* 02/03/92 eay */
+ lh->pmax=lh->num_alloc_nodes;
+ lh->num_alloc_nodes=j;
+ lh->num_expand_reallocs++;
+ lh->p=0;
+ lh->b=n;
+ }
+
lh->num_nodes++;
lh->num_expands++;
- p=(int)lh->p++;
n1= &(lh->b[p]);
- n2= &(lh->b[p+(int)lh->pmax]);
+ n2= &(lh->b[p+pmax]);
*n2=NULL; /* 27/07/92 - eay - undefined pointer bug */
- nni=lh->num_alloc_nodes;
for (np= *n1; np != NULL; )
{
@@ -335,35 +359,14 @@ static void expand(LHASH *lh)
np= *n1;
}
- if ((lh->p) >= lh->pmax)
- {
- j=(int)lh->num_alloc_nodes*2;
- n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
- (int)(sizeof(LHASH_NODE *)*j));
- if (n == NULL)
- {
-/* fputs("realloc error in lhash",stderr); */
- lh->error++;
- lh->p=0;
- return;
- }
- /* else */
- for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
- n[i]=NULL; /* 02/03/92 eay */
- lh->pmax=lh->num_alloc_nodes;
- lh->num_alloc_nodes=j;
- lh->num_expand_reallocs++;
- lh->p=0;
- lh->b=n;
- }
}
static void contract(LHASH *lh)
{
LHASH_NODE **n,*n1,*np;
+ int idx = lh->p+lh->pmax-1;
- np=lh->b[lh->p+lh->pmax-1];
- lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
+ np=lh->b[idx];
if (lh->p == 0)
{
n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
@@ -383,6 +386,7 @@ static void contract(LHASH *lh)
else
lh->p--;
+ lh->b[idx] = NULL;
lh->num_nodes--;
lh->num_contracts++;
diff --git a/crypto/openssl/crypto/md32_common.h b/crypto/openssl/crypto/md32_common.h
index 61bcd97..606aea6 100644
--- a/crypto/openssl/crypto/md32_common.h
+++ b/crypto/openssl/crypto/md32_common.h
@@ -241,11 +241,11 @@
#ifndef PEDANTIC
# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
# if defined(__s390x__)
-# define HOST_c2l(c,l) ({ asm ("lrv %0,0(%1)" \
- :"=r"(l) : "r"(c)); \
+# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \
+ :"=d"(l) :"m"(*(const unsigned int *)(c));\
(c)+=4; (l); })
-# define HOST_l2c(l,c) ({ asm ("strv %0,0(%1)" \
- : : "r"(l),"r"(c) : "memory"); \
+# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \
+ :"=m"(*(unsigned int *)(c)) :"d"(l));\
(c)+=4; (l); })
# endif
# endif
diff --git a/crypto/openssl/crypto/md5/asm/md5-x86_64.pl b/crypto/openssl/crypto/md5/asm/md5-x86_64.pl
index 9a6fa67..05d040f 100755
--- a/crypto/openssl/crypto/md5/asm/md5-x86_64.pl
+++ b/crypto/openssl/crypto/md5/asm/md5-x86_64.pl
@@ -19,6 +19,7 @@ my $code;
sub round1_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+ $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
$code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1);
$code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
$code .= <<EOF;
@@ -42,6 +43,7 @@ EOF
sub round2_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+ $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
$code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1);
$code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
$code .= <<EOF;
@@ -65,6 +67,7 @@ EOF
sub round3_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+ $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
$code .= " mov 5*4(%rsi), %r10d /* (NEXT STEP) X[5] */\n" if ($pos == -1);
$code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
$code .= <<EOF;
@@ -87,6 +90,7 @@ EOF
sub round4_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+ $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
$code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1);
$code .= " mov \$0xffffffff, %r11d\n" if ($pos == -1);
$code .= " xor %edx, %r11d /* (NEXT STEP) not z' = not %edx*/\n"
diff --git a/crypto/openssl/crypto/o_init.c b/crypto/openssl/crypto/o_init.c
index 00ed65a..2a5f5aa 100644
--- a/crypto/openssl/crypto/o_init.c
+++ b/crypto/openssl/crypto/o_init.c
@@ -58,6 +58,11 @@
#include <e_os.h>
#include <openssl/err.h>
+/* Internal only functions: only ever used here */
+extern void int_ERR_lib_init(void);
+extern void int_EVP_MD_init_engine_callbacks(void );
+extern void int_EVP_CIPHER_init_engine_callbacks(void );
+extern void int_RAND_init_engine_callbacks(void );
/* Perform any essential OpenSSL initialization operations.
* Currently only sets FIPS callbacks
@@ -73,7 +78,7 @@ void OPENSSL_init(void)
#ifdef CRYPTO_MDEBUG
CRYPTO_malloc_debug_init();
#endif
-#ifdef OPENSSL_ENGINE
+#ifndef OPENSSL_NO_ENGINE
int_EVP_MD_init_engine_callbacks();
int_EVP_CIPHER_init_engine_callbacks();
int_RAND_init_engine_callbacks();
diff --git a/crypto/openssl/crypto/o_str.c b/crypto/openssl/crypto/o_str.c
index 59cc250..56104a6 100644
--- a/crypto/openssl/crypto/o_str.c
+++ b/crypto/openssl/crypto/o_str.c
@@ -60,7 +60,9 @@
#include <e_os.h>
#include "o_str.h"
-#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && !defined(OPENSSL_SYSNAME_WIN32)
+#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
+ !defined(OPENSSL_SYSNAME_WIN32) && \
+ !defined(NETWARE_CLIB)
# include <strings.h>
#endif
diff --git a/crypto/openssl/crypto/objects/obj_dat.c b/crypto/openssl/crypto/objects/obj_dat.c
index 7fd7433..760af16 100644
--- a/crypto/openssl/crypto/objects/obj_dat.c
+++ b/crypto/openssl/crypto/objects/obj_dat.c
@@ -456,10 +456,13 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
s=OBJ_nid2ln(nid);
if (s == NULL)
s=OBJ_nid2sn(nid);
- if (buf)
- BUF_strlcpy(buf,s,buf_len);
- n=strlen(s);
- return n;
+ if (s)
+ {
+ if (buf)
+ BUF_strlcpy(buf,s,buf_len);
+ n=strlen(s);
+ return n;
+ }
}
diff --git a/crypto/openssl/crypto/objects/obj_dat.h b/crypto/openssl/crypto/objects/obj_dat.h
index dccc15e..23bdb46 100644
--- a/crypto/openssl/crypto/objects/obj_dat.h
+++ b/crypto/openssl/crypto/objects/obj_dat.h
@@ -62,12 +62,12 @@
* [including the GNU Public Licence.]
*/
-#define NUM_NID 859
-#define NUM_SN 852
-#define NUM_LN 852
-#define NUM_OBJ 806
+#define NUM_NID 893
+#define NUM_SN 886
+#define NUM_LN 886
+#define NUM_OBJ 840
-static unsigned char lvalues[5722]={
+static unsigned char lvalues[5824]={
0x00, /* [ 0] OBJ_undef */
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */
@@ -707,7 +707,7 @@ static unsigned char lvalues[5722]={
0x2B, /* [4582] OBJ_identified_organization */
0x2B,0x81,0x04, /* [4583] OBJ_certicom_arc */
0x67,0x2B, /* [4586] OBJ_wap */
-0x67,0x2B,0x0D, /* [4588] OBJ_wap_wsg */
+0x67,0x2B,0x01, /* [4588] OBJ_wap_wsg */
0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [4591] OBJ_X9_62_id_characteristic_two_basis */
0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4599] OBJ_X9_62_onBasis */
0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4608] OBJ_X9_62_tpBasis */
@@ -763,17 +763,17 @@ static unsigned char lvalues[5722]={
0x2B,0x81,0x04,0x00,0x25, /* [4926] OBJ_sect409r1 */
0x2B,0x81,0x04,0x00,0x26, /* [4931] OBJ_sect571k1 */
0x2B,0x81,0x04,0x00,0x27, /* [4936] OBJ_sect571r1 */
-0x67,0x2B,0x0D,0x04,0x01, /* [4941] OBJ_wap_wsg_idm_ecid_wtls1 */
-0x67,0x2B,0x0D,0x04,0x03, /* [4946] OBJ_wap_wsg_idm_ecid_wtls3 */
-0x67,0x2B,0x0D,0x04,0x04, /* [4951] OBJ_wap_wsg_idm_ecid_wtls4 */
-0x67,0x2B,0x0D,0x04,0x05, /* [4956] OBJ_wap_wsg_idm_ecid_wtls5 */
-0x67,0x2B,0x0D,0x04,0x06, /* [4961] OBJ_wap_wsg_idm_ecid_wtls6 */
-0x67,0x2B,0x0D,0x04,0x07, /* [4966] OBJ_wap_wsg_idm_ecid_wtls7 */
-0x67,0x2B,0x0D,0x04,0x08, /* [4971] OBJ_wap_wsg_idm_ecid_wtls8 */
-0x67,0x2B,0x0D,0x04,0x09, /* [4976] OBJ_wap_wsg_idm_ecid_wtls9 */
-0x67,0x2B,0x0D,0x04,0x0A, /* [4981] OBJ_wap_wsg_idm_ecid_wtls10 */
-0x67,0x2B,0x0D,0x04,0x0B, /* [4986] OBJ_wap_wsg_idm_ecid_wtls11 */
-0x67,0x2B,0x0D,0x04,0x0C, /* [4991] OBJ_wap_wsg_idm_ecid_wtls12 */
+0x67,0x2B,0x01,0x04,0x01, /* [4941] OBJ_wap_wsg_idm_ecid_wtls1 */
+0x67,0x2B,0x01,0x04,0x03, /* [4946] OBJ_wap_wsg_idm_ecid_wtls3 */
+0x67,0x2B,0x01,0x04,0x04, /* [4951] OBJ_wap_wsg_idm_ecid_wtls4 */
+0x67,0x2B,0x01,0x04,0x05, /* [4956] OBJ_wap_wsg_idm_ecid_wtls5 */
+0x67,0x2B,0x01,0x04,0x06, /* [4961] OBJ_wap_wsg_idm_ecid_wtls6 */
+0x67,0x2B,0x01,0x04,0x07, /* [4966] OBJ_wap_wsg_idm_ecid_wtls7 */
+0x67,0x2B,0x01,0x04,0x08, /* [4971] OBJ_wap_wsg_idm_ecid_wtls8 */
+0x67,0x2B,0x01,0x04,0x09, /* [4976] OBJ_wap_wsg_idm_ecid_wtls9 */
+0x67,0x2B,0x01,0x04,0x0A, /* [4981] OBJ_wap_wsg_idm_ecid_wtls10 */
+0x67,0x2B,0x01,0x04,0x0B, /* [4986] OBJ_wap_wsg_idm_ecid_wtls11 */
+0x67,0x2B,0x01,0x04,0x0C, /* [4991] OBJ_wap_wsg_idm_ecid_wtls12 */
0x55,0x1D,0x20,0x00, /* [4996] OBJ_any_policy */
0x55,0x1D,0x21, /* [5000] OBJ_policy_mappings */
0x55,0x1D,0x36, /* [5003] OBJ_inhibit_any_policy */
@@ -874,6 +874,40 @@ static unsigned char lvalues[5722]={
0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5701] OBJ_LocalKeySet */
0x55,0x1D,0x2E, /* [5710] OBJ_freshest_crl */
0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [5713] OBJ_id_on_permanentIdentifier */
+0x55,0x04,0x0E, /* [5721] OBJ_searchGuide */
+0x55,0x04,0x0F, /* [5724] OBJ_businessCategory */
+0x55,0x04,0x10, /* [5727] OBJ_postalAddress */
+0x55,0x04,0x12, /* [5730] OBJ_postOfficeBox */
+0x55,0x04,0x13, /* [5733] OBJ_physicalDeliveryOfficeName */
+0x55,0x04,0x14, /* [5736] OBJ_telephoneNumber */
+0x55,0x04,0x15, /* [5739] OBJ_telexNumber */
+0x55,0x04,0x16, /* [5742] OBJ_teletexTerminalIdentifier */
+0x55,0x04,0x17, /* [5745] OBJ_facsimileTelephoneNumber */
+0x55,0x04,0x18, /* [5748] OBJ_x121Address */
+0x55,0x04,0x19, /* [5751] OBJ_internationaliSDNNumber */
+0x55,0x04,0x1A, /* [5754] OBJ_registeredAddress */
+0x55,0x04,0x1B, /* [5757] OBJ_destinationIndicator */
+0x55,0x04,0x1C, /* [5760] OBJ_preferredDeliveryMethod */
+0x55,0x04,0x1D, /* [5763] OBJ_presentationAddress */
+0x55,0x04,0x1E, /* [5766] OBJ_supportedApplicationContext */
+0x55,0x04,0x1F, /* [5769] OBJ_member */
+0x55,0x04,0x20, /* [5772] OBJ_owner */
+0x55,0x04,0x21, /* [5775] OBJ_roleOccupant */
+0x55,0x04,0x22, /* [5778] OBJ_seeAlso */
+0x55,0x04,0x23, /* [5781] OBJ_userPassword */
+0x55,0x04,0x24, /* [5784] OBJ_userCertificate */
+0x55,0x04,0x25, /* [5787] OBJ_cACertificate */
+0x55,0x04,0x26, /* [5790] OBJ_authorityRevocationList */
+0x55,0x04,0x27, /* [5793] OBJ_certificateRevocationList */
+0x55,0x04,0x28, /* [5796] OBJ_crossCertificatePair */
+0x55,0x04,0x2F, /* [5799] OBJ_enhancedSearchGuide */
+0x55,0x04,0x30, /* [5802] OBJ_protocolInformation */
+0x55,0x04,0x31, /* [5805] OBJ_distinguishedName */
+0x55,0x04,0x32, /* [5808] OBJ_uniqueMember */
+0x55,0x04,0x33, /* [5811] OBJ_houseIdentifier */
+0x55,0x04,0x34, /* [5814] OBJ_supportedAlgorithms */
+0x55,0x04,0x35, /* [5817] OBJ_deltaRevocationList */
+0x55,0x04,0x36, /* [5820] OBJ_dmdName */
};
static ASN1_OBJECT nid_objs[NUM_NID]={
@@ -1928,7 +1962,7 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0},
{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0},
{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0},
-{"streetAddress","streetAddress",NID_streetAddress,3,&(lvalues[4462]),0},
+{"street","streetAddress",NID_streetAddress,3,&(lvalues[4462]),0},
{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4465]),0},
{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4468]),0},
{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
@@ -2262,6 +2296,61 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
&(lvalues[5710]),0},
{"id-on-permanentIdentifier","Permanent Identifier",
NID_id_on_permanentIdentifier,8,&(lvalues[5713]),0},
+{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5721]),0},
+{"businessCategory","businessCategory",NID_businessCategory,3,
+ &(lvalues[5724]),0},
+{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5727]),0},
+{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5730]),0},
+{"physicalDeliveryOfficeName","physicalDeliveryOfficeName",
+ NID_physicalDeliveryOfficeName,3,&(lvalues[5733]),0},
+{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3,
+ &(lvalues[5736]),0},
+{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5739]),0},
+{"teletexTerminalIdentifier","teletexTerminalIdentifier",
+ NID_teletexTerminalIdentifier,3,&(lvalues[5742]),0},
+{"facsimileTelephoneNumber","facsimileTelephoneNumber",
+ NID_facsimileTelephoneNumber,3,&(lvalues[5745]),0},
+{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5748]),0},
+{"internationaliSDNNumber","internationaliSDNNumber",
+ NID_internationaliSDNNumber,3,&(lvalues[5751]),0},
+{"registeredAddress","registeredAddress",NID_registeredAddress,3,
+ &(lvalues[5754]),0},
+{"destinationIndicator","destinationIndicator",
+ NID_destinationIndicator,3,&(lvalues[5757]),0},
+{"preferredDeliveryMethod","preferredDeliveryMethod",
+ NID_preferredDeliveryMethod,3,&(lvalues[5760]),0},
+{"presentationAddress","presentationAddress",NID_presentationAddress,
+ 3,&(lvalues[5763]),0},
+{"supportedApplicationContext","supportedApplicationContext",
+ NID_supportedApplicationContext,3,&(lvalues[5766]),0},
+{"member","member",NID_member,3,&(lvalues[5769]),0},
+{"owner","owner",NID_owner,3,&(lvalues[5772]),0},
+{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5775]),0},
+{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5778]),0},
+{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5781]),0},
+{"userCertificate","userCertificate",NID_userCertificate,3,
+ &(lvalues[5784]),0},
+{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5787]),0},
+{"authorityRevocationList","authorityRevocationList",
+ NID_authorityRevocationList,3,&(lvalues[5790]),0},
+{"certificateRevocationList","certificateRevocationList",
+ NID_certificateRevocationList,3,&(lvalues[5793]),0},
+{"crossCertificatePair","crossCertificatePair",
+ NID_crossCertificatePair,3,&(lvalues[5796]),0},
+{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide,
+ 3,&(lvalues[5799]),0},
+{"protocolInformation","protocolInformation",NID_protocolInformation,
+ 3,&(lvalues[5802]),0},
+{"distinguishedName","distinguishedName",NID_distinguishedName,3,
+ &(lvalues[5805]),0},
+{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5808]),0},
+{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3,
+ &(lvalues[5811]),0},
+{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms,
+ 3,&(lvalues[5814]),0},
+{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
+ 3,&(lvalues[5817]),0},
+{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5820]),0},
};
static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -2458,10 +2547,12 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[501]),/* "audio" */
&(nid_objs[177]),/* "authorityInfoAccess" */
&(nid_objs[90]),/* "authorityKeyIdentifier" */
+&(nid_objs[882]),/* "authorityRevocationList" */
&(nid_objs[87]),/* "basicConstraints" */
&(nid_objs[365]),/* "basicOCSPResponse" */
&(nid_objs[285]),/* "biometricInfo" */
&(nid_objs[494]),/* "buildingName" */
+&(nid_objs[860]),/* "businessCategory" */
&(nid_objs[691]),/* "c2onb191v4" */
&(nid_objs[692]),/* "c2onb191v5" */
&(nid_objs[697]),/* "c2onb239v4" */
@@ -2482,6 +2573,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[696]),/* "c2tnb239v3" */
&(nid_objs[701]),/* "c2tnb359v1" */
&(nid_objs[703]),/* "c2tnb431r1" */
+&(nid_objs[881]),/* "cACertificate" */
&(nid_objs[483]),/* "cNAMERecord" */
&(nid_objs[179]),/* "caIssuers" */
&(nid_objs[785]),/* "caRepository" */
@@ -2490,6 +2582,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[677]),/* "certicom-arc" */
&(nid_objs[771]),/* "certificateIssuer" */
&(nid_objs[89]),/* "certificatePolicies" */
+&(nid_objs[883]),/* "certificateRevocationList" */
&(nid_objs[54]),/* "challengePassword" */
&(nid_objs[407]),/* "characteristic-two-field" */
&(nid_objs[395]),/* "clearance" */
@@ -2500,6 +2593,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[153]),/* "crlBag" */
&(nid_objs[103]),/* "crlDistributionPoints" */
&(nid_objs[88]),/* "crlNumber" */
+&(nid_objs[884]),/* "crossCertificatePair" */
&(nid_objs[806]),/* "cryptocom" */
&(nid_objs[805]),/* "cryptopro" */
&(nid_objs[500]),/* "dITRedirect" */
@@ -2508,9 +2602,13 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[434]),/* "data" */
&(nid_objs[390]),/* "dcobject" */
&(nid_objs[140]),/* "deltaCRL" */
+&(nid_objs[891]),/* "deltaRevocationList" */
&(nid_objs[107]),/* "description" */
+&(nid_objs[871]),/* "destinationIndicator" */
&(nid_objs[28]),/* "dhKeyAgreement" */
&(nid_objs[382]),/* "directory" */
+&(nid_objs[887]),/* "distinguishedName" */
+&(nid_objs[892]),/* "dmdName" */
&(nid_objs[174]),/* "dnQualifier" */
&(nid_objs[447]),/* "document" */
&(nid_objs[471]),/* "documentAuthor" */
@@ -2533,12 +2631,14 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[792]),/* "ecdsa-with-Specified" */
&(nid_objs[48]),/* "emailAddress" */
&(nid_objs[132]),/* "emailProtection" */
+&(nid_objs[885]),/* "enhancedSearchGuide" */
&(nid_objs[389]),/* "enterprises" */
&(nid_objs[384]),/* "experimental" */
&(nid_objs[172]),/* "extReq" */
&(nid_objs[56]),/* "extendedCertificateAttributes" */
&(nid_objs[126]),/* "extendedKeyUsage" */
&(nid_objs[372]),/* "extendedStatus" */
+&(nid_objs[867]),/* "facsimileTelephoneNumber" */
&(nid_objs[462]),/* "favouriteDrink" */
&(nid_objs[857]),/* "freshestCRL" */
&(nid_objs[453]),/* "friendlyCountry" */
@@ -2565,6 +2665,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[486]),/* "homePostalAddress" */
&(nid_objs[473]),/* "homeTelephoneNumber" */
&(nid_objs[466]),/* "host" */
+&(nid_objs[889]),/* "houseIdentifier" */
&(nid_objs[442]),/* "iA5StringSyntax" */
&(nid_objs[783]),/* "id-DHBasedMac" */
&(nid_objs[824]),/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
@@ -2794,6 +2895,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[748]),/* "inhibitAnyPolicy" */
&(nid_objs[101]),/* "initials" */
&(nid_objs[647]),/* "international-organizations" */
+&(nid_objs[869]),/* "internationaliSDNNumber" */
&(nid_objs[142]),/* "invalidityDate" */
&(nid_objs[294]),/* "ipsecEndSystem" */
&(nid_objs[295]),/* "ipsecTunnel" */
@@ -2811,6 +2913,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[493]),/* "mailPreferenceOption" */
&(nid_objs[467]),/* "manager" */
&(nid_objs[809]),/* "md_gost94" */
+&(nid_objs[875]),/* "member" */
&(nid_objs[182]),/* "member-body" */
&(nid_objs[51]),/* "messageDigest" */
&(nid_objs[383]),/* "mgmt" */
@@ -2846,12 +2949,14 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[681]),/* "onBasis" */
&(nid_objs[491]),/* "organizationalStatus" */
&(nid_objs[475]),/* "otherMailbox" */
+&(nid_objs[876]),/* "owner" */
&(nid_objs[489]),/* "pagerTelephoneNumber" */
&(nid_objs[374]),/* "path" */
&(nid_objs[112]),/* "pbeWithMD5AndCast5CBC" */
&(nid_objs[499]),/* "personalSignature" */
&(nid_objs[487]),/* "personalTitle" */
&(nid_objs[464]),/* "photo" */
+&(nid_objs[863]),/* "physicalDeliveryOfficeName" */
&(nid_objs[437]),/* "pilot" */
&(nid_objs[439]),/* "pilotAttributeSyntax" */
&(nid_objs[438]),/* "pilotAttributeType" */
@@ -2877,8 +2982,12 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[47]),/* "pkcs9" */
&(nid_objs[401]),/* "policyConstraints" */
&(nid_objs[747]),/* "policyMappings" */
+&(nid_objs[862]),/* "postOfficeBox" */
+&(nid_objs[861]),/* "postalAddress" */
&(nid_objs[661]),/* "postalCode" */
&(nid_objs[683]),/* "ppBasis" */
+&(nid_objs[872]),/* "preferredDeliveryMethod" */
+&(nid_objs[873]),/* "presentationAddress" */
&(nid_objs[816]),/* "prf-gostr3411-94" */
&(nid_objs[406]),/* "prime-field" */
&(nid_objs[409]),/* "prime192v1" */
@@ -2890,13 +2999,16 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[415]),/* "prime256v1" */
&(nid_objs[385]),/* "private" */
&(nid_objs[84]),/* "privateKeyUsagePeriod" */
+&(nid_objs[886]),/* "protocolInformation" */
&(nid_objs[663]),/* "proxyCertInfo" */
&(nid_objs[510]),/* "pseudonym" */
&(nid_objs[435]),/* "pss" */
&(nid_objs[286]),/* "qcStatements" */
&(nid_objs[457]),/* "qualityLabelledData" */
&(nid_objs[450]),/* "rFC822localPart" */
+&(nid_objs[870]),/* "registeredAddress" */
&(nid_objs[400]),/* "role" */
+&(nid_objs[877]),/* "roleOccupant" */
&(nid_objs[448]),/* "room" */
&(nid_objs[463]),/* "roomNumber" */
&(nid_objs[ 6]),/* "rsaEncryption" */
@@ -2909,6 +3021,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[290]),/* "sbgp-ipAddrBlock" */
&(nid_objs[292]),/* "sbgp-routerIdentifier" */
&(nid_objs[159]),/* "sdsiCertificate" */
+&(nid_objs[859]),/* "searchGuide" */
&(nid_objs[704]),/* "secp112r1" */
&(nid_objs[705]),/* "secp112r2" */
&(nid_objs[706]),/* "secp128r1" */
@@ -2943,6 +3056,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[733]),/* "sect571k1" */
&(nid_objs[734]),/* "sect571r1" */
&(nid_objs[386]),/* "security" */
+&(nid_objs[878]),/* "seeAlso" */
&(nid_objs[394]),/* "selected-attribute-types" */
&(nid_objs[105]),/* "serialNumber" */
&(nid_objs[129]),/* "serverAuth" */
@@ -3081,14 +3195,19 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[454]),/* "simpleSecurityObject" */
&(nid_objs[496]),/* "singleLevelQuality" */
&(nid_objs[387]),/* "snmpv2" */
-&(nid_objs[660]),/* "streetAddress" */
+&(nid_objs[660]),/* "street" */
&(nid_objs[85]),/* "subjectAltName" */
&(nid_objs[769]),/* "subjectDirectoryAttributes" */
&(nid_objs[398]),/* "subjectInfoAccess" */
&(nid_objs[82]),/* "subjectKeyIdentifier" */
&(nid_objs[498]),/* "subtreeMaximumQuality" */
&(nid_objs[497]),/* "subtreeMinimumQuality" */
+&(nid_objs[890]),/* "supportedAlgorithms" */
+&(nid_objs[874]),/* "supportedApplicationContext" */
&(nid_objs[402]),/* "targetInformation" */
+&(nid_objs[864]),/* "telephoneNumber" */
+&(nid_objs[866]),/* "teletexTerminalIdentifier" */
+&(nid_objs[865]),/* "telexNumber" */
&(nid_objs[459]),/* "textEncodedORAddress" */
&(nid_objs[293]),/* "textNotice" */
&(nid_objs[133]),/* "timeStamping" */
@@ -3096,9 +3215,12 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[682]),/* "tpBasis" */
&(nid_objs[375]),/* "trustRoot" */
&(nid_objs[436]),/* "ucl" */
+&(nid_objs[888]),/* "uniqueMember" */
&(nid_objs[55]),/* "unstructuredAddress" */
&(nid_objs[49]),/* "unstructuredName" */
+&(nid_objs[880]),/* "userCertificate" */
&(nid_objs[465]),/* "userClass" */
+&(nid_objs[879]),/* "userPassword" */
&(nid_objs[373]),/* "valid" */
&(nid_objs[678]),/* "wap" */
&(nid_objs[679]),/* "wap-wsg" */
@@ -3114,6 +3236,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[741]),/* "wap-wsg-idm-ecid-wtls8" */
&(nid_objs[742]),/* "wap-wsg-idm-ecid-wtls9" */
&(nid_objs[804]),/* "whirlpool" */
+&(nid_objs[868]),/* "x121Address" */
&(nid_objs[503]),/* "x500UniqueIdentifier" */
&(nid_objs[158]),/* "x509Certificate" */
&(nid_objs[160]),/* "x509Crl" */
@@ -3284,11 +3407,13 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[484]),/* "associatedDomain" */
&(nid_objs[485]),/* "associatedName" */
&(nid_objs[501]),/* "audio" */
+&(nid_objs[882]),/* "authorityRevocationList" */
&(nid_objs[91]),/* "bf-cbc" */
&(nid_objs[93]),/* "bf-cfb" */
&(nid_objs[92]),/* "bf-ecb" */
&(nid_objs[94]),/* "bf-ofb" */
&(nid_objs[494]),/* "buildingName" */
+&(nid_objs[860]),/* "businessCategory" */
&(nid_objs[691]),/* "c2onb191v4" */
&(nid_objs[692]),/* "c2onb191v5" */
&(nid_objs[697]),/* "c2onb239v4" */
@@ -3309,6 +3434,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[696]),/* "c2tnb239v3" */
&(nid_objs[701]),/* "c2tnb359v1" */
&(nid_objs[703]),/* "c2tnb431r1" */
+&(nid_objs[881]),/* "cACertificate" */
&(nid_objs[483]),/* "cNAMERecord" */
&(nid_objs[751]),/* "camellia-128-cbc" */
&(nid_objs[757]),/* "camellia-128-cfb" */
@@ -3336,6 +3462,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[152]),/* "certBag" */
&(nid_objs[677]),/* "certicom-arc" */
&(nid_objs[517]),/* "certificate extensions" */
+&(nid_objs[883]),/* "certificateRevocationList" */
&(nid_objs[54]),/* "challengePassword" */
&(nid_objs[407]),/* "characteristic-two-field" */
&(nid_objs[395]),/* "clearance" */
@@ -3346,6 +3473,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[53]),/* "countersignature" */
&(nid_objs[14]),/* "countryName" */
&(nid_objs[153]),/* "crlBag" */
+&(nid_objs[884]),/* "crossCertificatePair" */
&(nid_objs[806]),/* "cryptocom" */
&(nid_objs[805]),/* "cryptopro" */
&(nid_objs[500]),/* "dITRedirect" */
@@ -3353,6 +3481,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[495]),/* "dSAQuality" */
&(nid_objs[434]),/* "data" */
&(nid_objs[390]),/* "dcObject" */
+&(nid_objs[891]),/* "deltaRevocationList" */
&(nid_objs[31]),/* "des-cbc" */
&(nid_objs[643]),/* "des-cdmf" */
&(nid_objs[30]),/* "des-cfb" */
@@ -3371,10 +3500,13 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[63]),/* "des-ede3-ofb" */
&(nid_objs[45]),/* "des-ofb" */
&(nid_objs[107]),/* "description" */
+&(nid_objs[871]),/* "destinationIndicator" */
&(nid_objs[80]),/* "desx-cbc" */
&(nid_objs[28]),/* "dhKeyAgreement" */
&(nid_objs[11]),/* "directory services (X.500)" */
&(nid_objs[378]),/* "directory services - algorithms" */
+&(nid_objs[887]),/* "distinguishedName" */
+&(nid_objs[892]),/* "dmdName" */
&(nid_objs[174]),/* "dnQualifier" */
&(nid_objs[447]),/* "document" */
&(nid_objs[471]),/* "documentAuthor" */
@@ -3404,7 +3536,9 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[792]),/* "ecdsa-with-Specified" */
&(nid_objs[48]),/* "emailAddress" */
&(nid_objs[632]),/* "encrypted track 2" */
+&(nid_objs[885]),/* "enhancedSearchGuide" */
&(nid_objs[56]),/* "extendedCertificateAttributes" */
+&(nid_objs[867]),/* "facsimileTelephoneNumber" */
&(nid_objs[462]),/* "favouriteDrink" */
&(nid_objs[453]),/* "friendlyCountry" */
&(nid_objs[490]),/* "friendlyCountryName" */
@@ -3426,6 +3560,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[486]),/* "homePostalAddress" */
&(nid_objs[473]),/* "homeTelephoneNumber" */
&(nid_objs[466]),/* "host" */
+&(nid_objs[889]),/* "houseIdentifier" */
&(nid_objs[442]),/* "iA5StringSyntax" */
&(nid_objs[381]),/* "iana" */
&(nid_objs[824]),/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
@@ -3640,6 +3775,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[676]),/* "identified-organization" */
&(nid_objs[461]),/* "info" */
&(nid_objs[101]),/* "initials" */
+&(nid_objs[869]),/* "internationaliSDNNumber" */
&(nid_objs[749]),/* "ipsec3" */
&(nid_objs[750]),/* "ipsec4" */
&(nid_objs[181]),/* "iso" */
@@ -3666,6 +3802,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[ 8]),/* "md5WithRSAEncryption" */
&(nid_objs[95]),/* "mdc2" */
&(nid_objs[96]),/* "mdc2WithRSA" */
+&(nid_objs[875]),/* "member" */
&(nid_objs[602]),/* "merchant initiated auth" */
&(nid_objs[514]),/* "message extensions" */
&(nid_objs[51]),/* "messageDigest" */
@@ -3680,6 +3817,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[491]),/* "organizationalStatus" */
&(nid_objs[18]),/* "organizationalUnitName" */
&(nid_objs[475]),/* "otherMailbox" */
+&(nid_objs[876]),/* "owner" */
&(nid_objs[489]),/* "pagerTelephoneNumber" */
&(nid_objs[782]),/* "password based MAC" */
&(nid_objs[374]),/* "path" */
@@ -3700,6 +3838,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[499]),/* "personalSignature" */
&(nid_objs[487]),/* "personalTitle" */
&(nid_objs[464]),/* "photo" */
+&(nid_objs[863]),/* "physicalDeliveryOfficeName" */
&(nid_objs[437]),/* "pilot" */
&(nid_objs[439]),/* "pilotAttributeSyntax" */
&(nid_objs[438]),/* "pilotAttributeType" */
@@ -3722,8 +3861,12 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[22]),/* "pkcs7-signedData" */
&(nid_objs[151]),/* "pkcs8ShroudedKeyBag" */
&(nid_objs[47]),/* "pkcs9" */
+&(nid_objs[862]),/* "postOfficeBox" */
+&(nid_objs[861]),/* "postalAddress" */
&(nid_objs[661]),/* "postalCode" */
&(nid_objs[683]),/* "ppBasis" */
+&(nid_objs[872]),/* "preferredDeliveryMethod" */
+&(nid_objs[873]),/* "presentationAddress" */
&(nid_objs[406]),/* "prime-field" */
&(nid_objs[409]),/* "prime192v1" */
&(nid_objs[410]),/* "prime192v2" */
@@ -3732,6 +3875,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[413]),/* "prime239v2" */
&(nid_objs[414]),/* "prime239v3" */
&(nid_objs[415]),/* "prime256v1" */
+&(nid_objs[886]),/* "protocolInformation" */
&(nid_objs[510]),/* "pseudonym" */
&(nid_objs[435]),/* "pss" */
&(nid_objs[286]),/* "qcStatements" */
@@ -3749,10 +3893,12 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[122]),/* "rc5-cfb" */
&(nid_objs[121]),/* "rc5-ecb" */
&(nid_objs[123]),/* "rc5-ofb" */
+&(nid_objs[870]),/* "registeredAddress" */
&(nid_objs[460]),/* "rfc822Mailbox" */
&(nid_objs[117]),/* "ripemd160" */
&(nid_objs[119]),/* "ripemd160WithRSA" */
&(nid_objs[400]),/* "role" */
+&(nid_objs[877]),/* "roleOccupant" */
&(nid_objs[448]),/* "room" */
&(nid_objs[463]),/* "roomNumber" */
&(nid_objs[19]),/* "rsa" */
@@ -3766,6 +3912,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[290]),/* "sbgp-ipAddrBlock" */
&(nid_objs[292]),/* "sbgp-routerIdentifier" */
&(nid_objs[159]),/* "sdsiCertificate" */
+&(nid_objs[859]),/* "searchGuide" */
&(nid_objs[704]),/* "secp112r1" */
&(nid_objs[705]),/* "secp112r2" */
&(nid_objs[706]),/* "secp128r1" */
@@ -3800,6 +3947,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[733]),/* "sect571k1" */
&(nid_objs[734]),/* "sect571r1" */
&(nid_objs[635]),/* "secure device signature" */
+&(nid_objs[878]),/* "seeAlso" */
&(nid_objs[777]),/* "seed-cbc" */
&(nid_objs[779]),/* "seed-cfb" */
&(nid_objs[776]),/* "seed-ecb" */
@@ -3942,17 +4090,25 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[660]),/* "streetAddress" */
&(nid_objs[498]),/* "subtreeMaximumQuality" */
&(nid_objs[497]),/* "subtreeMinimumQuality" */
+&(nid_objs[890]),/* "supportedAlgorithms" */
+&(nid_objs[874]),/* "supportedApplicationContext" */
&(nid_objs[100]),/* "surname" */
+&(nid_objs[864]),/* "telephoneNumber" */
+&(nid_objs[866]),/* "teletexTerminalIdentifier" */
+&(nid_objs[865]),/* "telexNumber" */
&(nid_objs[459]),/* "textEncodedORAddress" */
&(nid_objs[293]),/* "textNotice" */
&(nid_objs[106]),/* "title" */
&(nid_objs[682]),/* "tpBasis" */
&(nid_objs[436]),/* "ucl" */
&(nid_objs[ 0]),/* "undefined" */
+&(nid_objs[888]),/* "uniqueMember" */
&(nid_objs[55]),/* "unstructuredAddress" */
&(nid_objs[49]),/* "unstructuredName" */
+&(nid_objs[880]),/* "userCertificate" */
&(nid_objs[465]),/* "userClass" */
&(nid_objs[458]),/* "userId" */
+&(nid_objs[879]),/* "userPassword" */
&(nid_objs[373]),/* "valid" */
&(nid_objs[678]),/* "wap" */
&(nid_objs[679]),/* "wap-wsg" */
@@ -3968,6 +4124,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[741]),/* "wap-wsg-idm-ecid-wtls8" */
&(nid_objs[742]),/* "wap-wsg-idm-ecid-wtls9" */
&(nid_objs[804]),/* "whirlpool" */
+&(nid_objs[868]),/* "x121Address" */
&(nid_objs[503]),/* "x500UniqueIdentifier" */
&(nid_objs[158]),/* "x509Certificate" */
&(nid_objs[160]),/* "x509Crl" */
@@ -4009,13 +4166,47 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
&(nid_objs[18]),/* OBJ_organizationalUnitName 2 5 4 11 */
&(nid_objs[106]),/* OBJ_title 2 5 4 12 */
&(nid_objs[107]),/* OBJ_description 2 5 4 13 */
+&(nid_objs[859]),/* OBJ_searchGuide 2 5 4 14 */
+&(nid_objs[860]),/* OBJ_businessCategory 2 5 4 15 */
+&(nid_objs[861]),/* OBJ_postalAddress 2 5 4 16 */
&(nid_objs[661]),/* OBJ_postalCode 2 5 4 17 */
+&(nid_objs[862]),/* OBJ_postOfficeBox 2 5 4 18 */
+&(nid_objs[863]),/* OBJ_physicalDeliveryOfficeName 2 5 4 19 */
+&(nid_objs[864]),/* OBJ_telephoneNumber 2 5 4 20 */
+&(nid_objs[865]),/* OBJ_telexNumber 2 5 4 21 */
+&(nid_objs[866]),/* OBJ_teletexTerminalIdentifier 2 5 4 22 */
+&(nid_objs[867]),/* OBJ_facsimileTelephoneNumber 2 5 4 23 */
+&(nid_objs[868]),/* OBJ_x121Address 2 5 4 24 */
+&(nid_objs[869]),/* OBJ_internationaliSDNNumber 2 5 4 25 */
+&(nid_objs[870]),/* OBJ_registeredAddress 2 5 4 26 */
+&(nid_objs[871]),/* OBJ_destinationIndicator 2 5 4 27 */
+&(nid_objs[872]),/* OBJ_preferredDeliveryMethod 2 5 4 28 */
+&(nid_objs[873]),/* OBJ_presentationAddress 2 5 4 29 */
+&(nid_objs[874]),/* OBJ_supportedApplicationContext 2 5 4 30 */
+&(nid_objs[875]),/* OBJ_member 2 5 4 31 */
+&(nid_objs[876]),/* OBJ_owner 2 5 4 32 */
+&(nid_objs[877]),/* OBJ_roleOccupant 2 5 4 33 */
+&(nid_objs[878]),/* OBJ_seeAlso 2 5 4 34 */
+&(nid_objs[879]),/* OBJ_userPassword 2 5 4 35 */
+&(nid_objs[880]),/* OBJ_userCertificate 2 5 4 36 */
+&(nid_objs[881]),/* OBJ_cACertificate 2 5 4 37 */
+&(nid_objs[882]),/* OBJ_authorityRevocationList 2 5 4 38 */
+&(nid_objs[883]),/* OBJ_certificateRevocationList 2 5 4 39 */
+&(nid_objs[884]),/* OBJ_crossCertificatePair 2 5 4 40 */
&(nid_objs[173]),/* OBJ_name 2 5 4 41 */
&(nid_objs[99]),/* OBJ_givenName 2 5 4 42 */
&(nid_objs[101]),/* OBJ_initials 2 5 4 43 */
&(nid_objs[509]),/* OBJ_generationQualifier 2 5 4 44 */
&(nid_objs[503]),/* OBJ_x500UniqueIdentifier 2 5 4 45 */
&(nid_objs[174]),/* OBJ_dnQualifier 2 5 4 46 */
+&(nid_objs[885]),/* OBJ_enhancedSearchGuide 2 5 4 47 */
+&(nid_objs[886]),/* OBJ_protocolInformation 2 5 4 48 */
+&(nid_objs[887]),/* OBJ_distinguishedName 2 5 4 49 */
+&(nid_objs[888]),/* OBJ_uniqueMember 2 5 4 50 */
+&(nid_objs[889]),/* OBJ_houseIdentifier 2 5 4 51 */
+&(nid_objs[890]),/* OBJ_supportedAlgorithms 2 5 4 52 */
+&(nid_objs[891]),/* OBJ_deltaRevocationList 2 5 4 53 */
+&(nid_objs[892]),/* OBJ_dmdName 2 5 4 54 */
&(nid_objs[510]),/* OBJ_pseudonym 2 5 4 65 */
&(nid_objs[400]),/* OBJ_role 2 5 4 72 */
&(nid_objs[769]),/* OBJ_subject_directory_attributes 2 5 29 9 */
@@ -4049,7 +4240,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
&(nid_objs[516]),/* OBJ_set_policy 2 23 42 5 */
&(nid_objs[517]),/* OBJ_set_certExt 2 23 42 7 */
&(nid_objs[518]),/* OBJ_set_brand 2 23 42 8 */
-&(nid_objs[679]),/* OBJ_wap_wsg 2 23 43 13 */
+&(nid_objs[679]),/* OBJ_wap_wsg 2 23 43 1 */
&(nid_objs[382]),/* OBJ_Directory 1 3 6 1 1 */
&(nid_objs[383]),/* OBJ_Management 1 3 6 1 2 */
&(nid_objs[384]),/* OBJ_Experimental 1 3 6 1 3 */
@@ -4235,17 +4426,17 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
&(nid_objs[629]),/* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */
&(nid_objs[630]),/* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */
&(nid_objs[642]),/* OBJ_set_brand_Novus 2 23 42 8 6011 */
-&(nid_objs[735]),/* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 13 4 1 */
-&(nid_objs[736]),/* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 13 4 3 */
-&(nid_objs[737]),/* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 13 4 4 */
-&(nid_objs[738]),/* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 13 4 5 */
-&(nid_objs[739]),/* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 13 4 6 */
-&(nid_objs[740]),/* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 13 4 7 */
-&(nid_objs[741]),/* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 13 4 8 */
-&(nid_objs[742]),/* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 13 4 9 */
-&(nid_objs[743]),/* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 13 4 10 */
-&(nid_objs[744]),/* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 13 4 11 */
-&(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 13 4 12 */
+&(nid_objs[735]),/* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */
+&(nid_objs[736]),/* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */
+&(nid_objs[737]),/* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */
+&(nid_objs[738]),/* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */
+&(nid_objs[739]),/* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */
+&(nid_objs[740]),/* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */
+&(nid_objs[741]),/* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */
+&(nid_objs[742]),/* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */
+&(nid_objs[743]),/* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */
+&(nid_objs[744]),/* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */
+&(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */
&(nid_objs[804]),/* OBJ_whirlpool 1 0 10118 3 0 55 */
&(nid_objs[124]),/* OBJ_rle_compression 1 1 1 1 666 1 */
&(nid_objs[773]),/* OBJ_kisa 1 2 410 200004 */
diff --git a/crypto/openssl/crypto/objects/obj_mac.h b/crypto/openssl/crypto/objects/obj_mac.h
index ad5f7cf..282f11a 100644
--- a/crypto/openssl/crypto/objects/obj_mac.h
+++ b/crypto/openssl/crypto/objects/obj_mac.h
@@ -122,7 +122,7 @@
#define SN_wap_wsg "wap-wsg"
#define NID_wap_wsg 679
-#define OBJ_wap_wsg OBJ_wap,13L
+#define OBJ_wap_wsg OBJ_wap,1L
#define SN_selected_attribute_types "selected-attribute-types"
#define LN_selected_attribute_types "Selected Attribute Types"
@@ -2049,6 +2049,7 @@
#define NID_stateOrProvinceName 16
#define OBJ_stateOrProvinceName OBJ_X509,8L
+#define SN_streetAddress "street"
#define LN_streetAddress "streetAddress"
#define NID_streetAddress 660
#define OBJ_streetAddress OBJ_X509,9L
@@ -2063,6 +2064,7 @@
#define NID_organizationalUnitName 18
#define OBJ_organizationalUnitName OBJ_X509,11L
+#define SN_title "title"
#define LN_title "title"
#define NID_title 106
#define OBJ_title OBJ_X509,12L
@@ -2071,10 +2073,114 @@
#define NID_description 107
#define OBJ_description OBJ_X509,13L
+#define LN_searchGuide "searchGuide"
+#define NID_searchGuide 859
+#define OBJ_searchGuide OBJ_X509,14L
+
+#define LN_businessCategory "businessCategory"
+#define NID_businessCategory 860
+#define OBJ_businessCategory OBJ_X509,15L
+
+#define LN_postalAddress "postalAddress"
+#define NID_postalAddress 861
+#define OBJ_postalAddress OBJ_X509,16L
+
#define LN_postalCode "postalCode"
#define NID_postalCode 661
#define OBJ_postalCode OBJ_X509,17L
+#define LN_postOfficeBox "postOfficeBox"
+#define NID_postOfficeBox 862
+#define OBJ_postOfficeBox OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName 863
+#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L
+
+#define LN_telephoneNumber "telephoneNumber"
+#define NID_telephoneNumber 864
+#define OBJ_telephoneNumber OBJ_X509,20L
+
+#define LN_telexNumber "telexNumber"
+#define NID_telexNumber 865
+#define OBJ_telexNumber OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier 866
+#define OBJ_teletexTerminalIdentifier OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber 867
+#define OBJ_facsimileTelephoneNumber OBJ_X509,23L
+
+#define LN_x121Address "x121Address"
+#define NID_x121Address 868
+#define OBJ_x121Address OBJ_X509,24L
+
+#define LN_internationaliSDNNumber "internationaliSDNNumber"
+#define NID_internationaliSDNNumber 869
+#define OBJ_internationaliSDNNumber OBJ_X509,25L
+
+#define LN_registeredAddress "registeredAddress"
+#define NID_registeredAddress 870
+#define OBJ_registeredAddress OBJ_X509,26L
+
+#define LN_destinationIndicator "destinationIndicator"
+#define NID_destinationIndicator 871
+#define OBJ_destinationIndicator OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod "preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod 872
+#define OBJ_preferredDeliveryMethod OBJ_X509,28L
+
+#define LN_presentationAddress "presentationAddress"
+#define NID_presentationAddress 873
+#define OBJ_presentationAddress OBJ_X509,29L
+
+#define LN_supportedApplicationContext "supportedApplicationContext"
+#define NID_supportedApplicationContext 874
+#define OBJ_supportedApplicationContext OBJ_X509,30L
+
+#define SN_member "member"
+#define NID_member 875
+#define OBJ_member OBJ_X509,31L
+
+#define SN_owner "owner"
+#define NID_owner 876
+#define OBJ_owner OBJ_X509,32L
+
+#define LN_roleOccupant "roleOccupant"
+#define NID_roleOccupant 877
+#define OBJ_roleOccupant OBJ_X509,33L
+
+#define SN_seeAlso "seeAlso"
+#define NID_seeAlso 878
+#define OBJ_seeAlso OBJ_X509,34L
+
+#define LN_userPassword "userPassword"
+#define NID_userPassword 879
+#define OBJ_userPassword OBJ_X509,35L
+
+#define LN_userCertificate "userCertificate"
+#define NID_userCertificate 880
+#define OBJ_userCertificate OBJ_X509,36L
+
+#define LN_cACertificate "cACertificate"
+#define NID_cACertificate 881
+#define OBJ_cACertificate OBJ_X509,37L
+
+#define LN_authorityRevocationList "authorityRevocationList"
+#define NID_authorityRevocationList 882
+#define OBJ_authorityRevocationList OBJ_X509,38L
+
+#define LN_certificateRevocationList "certificateRevocationList"
+#define NID_certificateRevocationList 883
+#define OBJ_certificateRevocationList OBJ_X509,39L
+
+#define LN_crossCertificatePair "crossCertificatePair"
+#define NID_crossCertificatePair 884
+#define OBJ_crossCertificatePair OBJ_X509,40L
+
#define SN_name "name"
#define LN_name "name"
#define NID_name 173
@@ -2085,6 +2191,7 @@
#define NID_givenName 99
#define OBJ_givenName OBJ_X509,42L
+#define SN_initials "initials"
#define LN_initials "initials"
#define NID_initials 101
#define OBJ_initials OBJ_X509,43L
@@ -2102,6 +2209,38 @@
#define NID_dnQualifier 174
#define OBJ_dnQualifier OBJ_X509,46L
+#define LN_enhancedSearchGuide "enhancedSearchGuide"
+#define NID_enhancedSearchGuide 885
+#define OBJ_enhancedSearchGuide OBJ_X509,47L
+
+#define LN_protocolInformation "protocolInformation"
+#define NID_protocolInformation 886
+#define OBJ_protocolInformation OBJ_X509,48L
+
+#define LN_distinguishedName "distinguishedName"
+#define NID_distinguishedName 887
+#define OBJ_distinguishedName OBJ_X509,49L
+
+#define LN_uniqueMember "uniqueMember"
+#define NID_uniqueMember 888
+#define OBJ_uniqueMember OBJ_X509,50L
+
+#define LN_houseIdentifier "houseIdentifier"
+#define NID_houseIdentifier 889
+#define OBJ_houseIdentifier OBJ_X509,51L
+
+#define LN_supportedAlgorithms "supportedAlgorithms"
+#define NID_supportedAlgorithms 890
+#define OBJ_supportedAlgorithms OBJ_X509,52L
+
+#define LN_deltaRevocationList "deltaRevocationList"
+#define NID_deltaRevocationList 891
+#define OBJ_deltaRevocationList OBJ_X509,53L
+
+#define SN_dmdName "dmdName"
+#define NID_dmdName 892
+#define OBJ_dmdName OBJ_X509,54L
+
#define LN_pseudonym "pseudonym"
#define NID_pseudonym 510
#define OBJ_pseudonym OBJ_X509,65L
diff --git a/crypto/openssl/crypto/objects/obj_mac.num b/crypto/openssl/crypto/objects/obj_mac.num
index e3f56bc..8c50aac 100644
--- a/crypto/openssl/crypto/objects/obj_mac.num
+++ b/crypto/openssl/crypto/objects/obj_mac.num
@@ -856,3 +856,37 @@ hmac 855
LocalKeySet 856
freshest_crl 857
id_on_permanentIdentifier 858
+searchGuide 859
+businessCategory 860
+postalAddress 861
+postOfficeBox 862
+physicalDeliveryOfficeName 863
+telephoneNumber 864
+telexNumber 865
+teletexTerminalIdentifier 866
+facsimileTelephoneNumber 867
+x121Address 868
+internationaliSDNNumber 869
+registeredAddress 870
+destinationIndicator 871
+preferredDeliveryMethod 872
+presentationAddress 873
+supportedApplicationContext 874
+member 875
+owner 876
+roleOccupant 877
+seeAlso 878
+userPassword 879
+userCertificate 880
+cACertificate 881
+authorityRevocationList 882
+certificateRevocationList 883
+crossCertificatePair 884
+enhancedSearchGuide 885
+protocolInformation 886
+distinguishedName 887
+uniqueMember 888
+houseIdentifier 889
+supportedAlgorithms 890
+deltaRevocationList 891
+dmdName 892
diff --git a/crypto/openssl/crypto/objects/objects.txt b/crypto/openssl/crypto/objects/objects.txt
index a6a811b..e61fe60 100644
--- a/crypto/openssl/crypto/objects/objects.txt
+++ b/crypto/openssl/crypto/objects/objects.txt
@@ -20,7 +20,7 @@ identified-organization 132 : certicom-arc
joint-iso-itu-t 23 : international-organizations : International Organizations
international-organizations 43 : wap
-wap 13 : wap-wsg
+wap 1 : wap-wsg
joint-iso-itu-t 5 1 5 : selected-attribute-types : Selected Attribute Types
@@ -664,18 +664,52 @@ X509 5 : : serialNumber
X509 6 : C : countryName
X509 7 : L : localityName
X509 8 : ST : stateOrProvinceName
-X509 9 : : streetAddress
+X509 9 : street : streetAddress
X509 10 : O : organizationName
X509 11 : OU : organizationalUnitName
-X509 12 : : title
+X509 12 : title : title
X509 13 : : description
-X509 17 : : postalCode
+X509 14 : : searchGuide
+X509 15 : : businessCategory
+X509 16 : : postalAddress
+X509 17 : : postalCode
+X509 18 : : postOfficeBox
+X509 19 : : physicalDeliveryOfficeName
+X509 20 : : telephoneNumber
+X509 21 : : telexNumber
+X509 22 : : teletexTerminalIdentifier
+X509 23 : : facsimileTelephoneNumber
+X509 24 : : x121Address
+X509 25 : : internationaliSDNNumber
+X509 26 : : registeredAddress
+X509 27 : : destinationIndicator
+X509 28 : : preferredDeliveryMethod
+X509 29 : : presentationAddress
+X509 30 : : supportedApplicationContext
+X509 31 : member :
+X509 32 : owner :
+X509 33 : : roleOccupant
+X509 34 : seeAlso :
+X509 35 : : userPassword
+X509 36 : : userCertificate
+X509 37 : : cACertificate
+X509 38 : : authorityRevocationList
+X509 39 : : certificateRevocationList
+X509 40 : : crossCertificatePair
X509 41 : name : name
X509 42 : GN : givenName
-X509 43 : : initials
+X509 43 : initials : initials
X509 44 : : generationQualifier
X509 45 : : x500UniqueIdentifier
X509 46 : dnQualifier : dnQualifier
+X509 47 : : enhancedSearchGuide
+X509 48 : : protocolInformation
+X509 49 : : distinguishedName
+X509 50 : : uniqueMember
+X509 51 : : houseIdentifier
+X509 52 : : supportedAlgorithms
+X509 53 : : deltaRevocationList
+X509 54 : dmdName :
X509 65 : : pseudonym
X509 72 : role : role
diff --git a/crypto/openssl/crypto/ocsp/ocsp_prn.c b/crypto/openssl/crypto/ocsp/ocsp_prn.c
index 3dfb51c..90dd1aa 100644
--- a/crypto/openssl/crypto/ocsp/ocsp_prn.c
+++ b/crypto/openssl/crypto/ocsp/ocsp_prn.c
@@ -266,15 +266,16 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate))
goto err;
}
- if (!BIO_write(bp,"\n",1)) goto err;
+ if (BIO_write(bp,"\n",1) <= 0) goto err;
if (!X509V3_extensions_print(bp,
"Response Single Extensions",
single->singleExtensions, flags, 8))
goto err;
- if (!BIO_write(bp,"\n",1)) goto err;
+ if (BIO_write(bp,"\n",1) <= 0) goto err;
}
if (!X509V3_extensions_print(bp, "Response Extensions",
rd->responseExtensions, flags, 4))
+ goto err;
if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0)
goto err;
diff --git a/crypto/openssl/crypto/opensslv.h b/crypto/openssl/crypto/opensslv.h
index c6207f7..9f3981c 100644
--- a/crypto/openssl/crypto/opensslv.h
+++ b/crypto/openssl/crypto/opensslv.h
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-#define OPENSSL_VERSION_NUMBER 0x009080bfL
+#define OPENSSL_VERSION_NUMBER 0x009080efL
#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8k-fips 25 Mar 2009"
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8n-fips 24 Mar 2010"
#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8k 25 Mar 2009"
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8n 24 Mar 2010"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/crypto/openssl/crypto/pem/pem_seal.c b/crypto/openssl/crypto/pem/pem_seal.c
index 4e554e5..59690b5 100644
--- a/crypto/openssl/crypto/pem/pem_seal.c
+++ b/crypto/openssl/crypto/pem/pem_seal.c
@@ -100,7 +100,7 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
EVP_CIPHER_CTX_init(&ctx->cipher);
ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
- if (!ret) goto err;
+ if (ret <= 0) goto err;
/* base64 encode the keys */
for (i=0; i<npubk; i++)
diff --git a/crypto/openssl/crypto/perlasm/x86_64-xlate.pl b/crypto/openssl/crypto/perlasm/x86_64-xlate.pl
index a4af769..fe348b9 100755
--- a/crypto/openssl/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/openssl/crypto/perlasm/x86_64-xlate.pl
@@ -189,8 +189,10 @@ my $current_function;
if (!$masm) {
# Solaris /usr/ccs/bin/as can't handle multiplications
# in $self->{label}
+ use integer;
$self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi;
$self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
+ $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
if (defined($self->{index})) {
sprintf "%s(%%%s,%%%s,%d)",
diff --git a/crypto/openssl/crypto/pkcs12/p12_attr.c b/crypto/openssl/crypto/pkcs12/p12_attr.c
index 68d6c5a..856933d 100644
--- a/crypto/openssl/crypto/pkcs12/p12_attr.c
+++ b/crypto/openssl/crypto/pkcs12/p12_attr.c
@@ -60,6 +60,12 @@
#include "cryptlib.h"
#include <openssl/pkcs12.h>
+#ifdef OPENSSL_SYS_NETWARE
+/* Rename these functions to avoid name clashes on NetWare OS */
+#define uni2asc OPENSSL_uni2asc
+#define asc2uni OPENSSL_asc2uni
+#endif
+
/* Add a local keyid to a safebag */
int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
diff --git a/crypto/openssl/crypto/pkcs12/p12_key.c b/crypto/openssl/crypto/pkcs12/p12_key.c
index 9e57eee..5cfe727 100644
--- a/crypto/openssl/crypto/pkcs12/p12_key.c
+++ b/crypto/openssl/crypto/pkcs12/p12_key.c
@@ -69,6 +69,12 @@ extern BIO *bio_err;
void h__dump (unsigned char *p, int len);
#endif
+#ifdef OPENSSL_SYS_NETWARE
+/* Rename these functions to avoid name clashes on NetWare OS */
+#define uni2asc OPENSSL_uni2asc
+#define asc2uni OPENSSL_asc2uni
+#endif
+
/* PKCS12 compatible key/IV generation */
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
diff --git a/crypto/openssl/crypto/pkcs12/p12_utl.c b/crypto/openssl/crypto/pkcs12/p12_utl.c
index ca30ac4..2edbf90 100644
--- a/crypto/openssl/crypto/pkcs12/p12_utl.c
+++ b/crypto/openssl/crypto/pkcs12/p12_utl.c
@@ -60,6 +60,12 @@
#include "cryptlib.h"
#include <openssl/pkcs12.h>
+#ifdef OPENSSL_SYS_NETWARE
+/* Rename these functions to avoid name clashes on NetWare OS */
+#define uni2asc OPENSSL_uni2asc
+#define asc2uni OPENSSL_asc2uni
+#endif
+
/* Cheap and nasty Unicode stuff */
unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
diff --git a/crypto/openssl/crypto/pkcs12/pkcs12.h b/crypto/openssl/crypto/pkcs12/pkcs12.h
index 4bee605..78317fb 100644
--- a/crypto/openssl/crypto/pkcs12/pkcs12.h
+++ b/crypto/openssl/crypto/pkcs12/pkcs12.h
@@ -232,9 +232,14 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
const EVP_MD *md_type);
int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
int saltlen, const EVP_MD *md_type);
+#if defined(NETWARE) || defined(OPENSSL_SYS_NETWARE)
+/* Rename these functions to avoid name clashes on NetWare OS */
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
+char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
+#else
unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
char *uni2asc(unsigned char *uni, int unilen);
-
+#endif
DECLARE_ASN1_FUNCTIONS(PKCS12)
DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
diff --git a/crypto/openssl/crypto/pkcs7/pk7_mime.c b/crypto/openssl/crypto/pkcs7/pk7_mime.c
index bf19036..7762d64 100644
--- a/crypto/openssl/crypto/pkcs7/pk7_mime.c
+++ b/crypto/openssl/crypto/pkcs7/pk7_mime.c
@@ -50,10 +50,6 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
*/
#include <stdio.h>
@@ -61,200 +57,47 @@
#include "cryptlib.h"
#include <openssl/rand.h>
#include <openssl/x509.h>
+#include <openssl/asn1.h>
-/* MIME and related routines */
-
-/* MIME format structures
- * Note that all are translated to lower case apart from
- * parameter values. Quotes are stripped off
- */
-
-typedef struct {
-char *param_name; /* Param name e.g. "micalg" */
-char *param_value; /* Param value e.g. "sha1" */
-} MIME_PARAM;
-
-DECLARE_STACK_OF(MIME_PARAM)
-IMPLEMENT_STACK_OF(MIME_PARAM)
-
-typedef struct {
-char *name; /* Name of line e.g. "content-type" */
-char *value; /* Value of line e.g. "text/plain" */
-STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
-} MIME_HEADER;
-
-DECLARE_STACK_OF(MIME_HEADER)
-IMPLEMENT_STACK_OF(MIME_HEADER)
-
-static int pkcs7_output_data(BIO *bio, BIO *data, PKCS7 *p7, int flags);
-static int B64_write_PKCS7(BIO *bio, PKCS7 *p7);
-static PKCS7 *B64_read_PKCS7(BIO *bio);
-static char * strip_ends(char *name);
-static char * strip_start(char *name);
-static char * strip_end(char *name);
-static MIME_HEADER *mime_hdr_new(char *name, char *value);
-static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
-static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
-static int mime_hdr_cmp(const MIME_HEADER * const *a,
- const MIME_HEADER * const *b);
-static int mime_param_cmp(const MIME_PARAM * const *a,
- const MIME_PARAM * const *b);
-static void mime_param_free(MIME_PARAM *param);
-static int mime_bound_check(char *line, int linelen, char *bound, int blen);
-static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
-static int strip_eol(char *linebuf, int *plen);
-static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
-static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
-static void mime_hdr_free(MIME_HEADER *hdr);
+/* PKCS#7 wrappers round generalised MIME routines */
-#define MAX_SMLEN 1024
-#define mime_debug(x) /* x */
-
-/* Base 64 read and write of PKCS#7 structure */
-
-static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
-{
- BIO *b64;
- if(!(b64 = BIO_new(BIO_f_base64()))) {
- PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE);
- return 0;
- }
- bio = BIO_push(b64, bio);
- i2d_PKCS7_bio(bio, p7);
- (void)BIO_flush(bio);
- bio = BIO_pop(bio);
- BIO_free(b64);
- return 1;
-}
-
-static PKCS7 *B64_read_PKCS7(BIO *bio)
-{
- BIO *b64;
- PKCS7 *p7;
- if(!(b64 = BIO_new(BIO_f_base64()))) {
- PKCS7err(PKCS7_F_B64_READ_PKCS7,ERR_R_MALLOC_FAILURE);
- return 0;
- }
- bio = BIO_push(b64, bio);
- if(!(p7 = d2i_PKCS7_bio(bio, NULL)))
- PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
- (void)BIO_flush(bio);
- bio = BIO_pop(bio);
- BIO_free(b64);
- return p7;
-}
-
-/* SMIME sender */
-
-int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
-{
- char bound[33], c;
- int i;
- char *mime_prefix, *mime_eol, *msg_type=NULL;
- if (flags & PKCS7_NOOLDMIMETYPE)
- mime_prefix = "application/pkcs7-";
- else
- mime_prefix = "application/x-pkcs7-";
-
- if (flags & PKCS7_CRLFEOL)
- mime_eol = "\r\n";
- else
- mime_eol = "\n";
- if((flags & PKCS7_DETACHED) && data) {
- /* We want multipart/signed */
- /* Generate a random boundary */
- RAND_pseudo_bytes((unsigned char *)bound, 32);
- for(i = 0; i < 32; i++) {
- c = bound[i] & 0xf;
- if(c < 10) c += '0';
- else c += 'A' - 10;
- bound[i] = c;
- }
- bound[32] = 0;
- BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
- BIO_printf(bio, "Content-Type: multipart/signed;");
- BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
- BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s",
- bound, mime_eol, mime_eol);
- BIO_printf(bio, "This is an S/MIME signed message%s%s",
- mime_eol, mime_eol);
- /* Now write out the first part */
- BIO_printf(bio, "------%s%s", bound, mime_eol);
- pkcs7_output_data(bio, data, p7, flags);
- BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
-
- /* Headers for signature */
-
- BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
- BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
- BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
- mime_eol);
- BIO_printf(bio, "Content-Disposition: attachment;");
- BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
- mime_eol, mime_eol);
- B64_write_PKCS7(bio, p7);
- BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
- mime_eol, mime_eol);
- return 1;
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
+ {
+ return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
}
- /* Determine smime-type header */
-
- if (PKCS7_type_is_enveloped(p7))
- msg_type = "enveloped-data";
- else if (PKCS7_type_is_signed(p7))
- {
- /* If we have any signers it is signed-data othewise
- * certs-only.
- */
- STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
- sinfos = PKCS7_get_signer_info(p7);
- if (sk_PKCS7_SIGNER_INFO_num(sinfos) > 0)
- msg_type = "signed-data";
- else
- msg_type = "certs-only";
- }
- /* MIME headers */
- BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
- BIO_printf(bio, "Content-Disposition: attachment;");
- BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol);
- BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
- if (msg_type)
- BIO_printf(bio, " smime-type=%s;", msg_type);
- BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
- BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
- mime_eol, mime_eol);
- B64_write_PKCS7(bio, p7);
- BIO_printf(bio, "%s", mime_eol);
- return 1;
-}
-
-/* Handle output of PKCS#7 data */
+/* Callback for int_smime_write_ASN1 */
-
-static int pkcs7_output_data(BIO *out, BIO *data, PKCS7 *p7, int flags)
+static int pk7_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+ const ASN1_ITEM *it)
{
+ PKCS7 *p7 = (PKCS7 *)val;
BIO *tmpbio, *p7bio;
+ int r = 0;
- if (!(flags & PKCS7_STREAM))
+ if (!(flags & SMIME_DETACHED))
{
SMIME_crlf_copy(data, out, flags);
return 1;
}
- /* Partial sign operation */
+ /* Let PKCS7 code prepend any needed BIOs */
- /* Initialize sign operation */
p7bio = PKCS7_dataInit(p7, out);
- /* Copy data across, computing digests etc */
+ if (!p7bio)
+ return 0;
+
+ /* Copy data across, passing through filter BIOs for processing */
SMIME_crlf_copy(data, p7bio, flags);
- /* Must be detached */
- PKCS7_set_detached(p7, 1);
+ /* Finalize structure */
+ if (PKCS7_dataFinal(p7, p7bio) <= 0)
+ goto err;
+
+ r = 1;
- /* Finalize signatures */
- PKCS7_dataFinal(p7, p7bio);
+ err:
/* Now remove any digests prepended to the BIO */
@@ -269,454 +112,17 @@ static int pkcs7_output_data(BIO *out, BIO *data, PKCS7 *p7, int flags)
}
-/* SMIME reader: handle multipart/signed and opaque signing.
- * in multipart case the content is placed in a memory BIO
- * pointed to by "bcont". In opaque this is set to NULL
- */
-
-PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
-{
- BIO *p7in;
- STACK_OF(MIME_HEADER) *headers = NULL;
- STACK_OF(BIO) *parts = NULL;
- MIME_HEADER *hdr;
- MIME_PARAM *prm;
- PKCS7 *p7;
- int ret;
-
- if(bcont) *bcont = NULL;
-
- if (!(headers = mime_parse_hdr(bio))) {
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR);
- return NULL;
- }
-
- if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE);
- return NULL;
- }
-
- /* Handle multipart/signed */
-
- if(!strcmp(hdr->value, "multipart/signed")) {
- /* Split into two parts */
- prm = mime_param_find(hdr, "boundary");
- if(!prm || !prm->param_value) {
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY);
- return NULL;
- }
- ret = multi_split(bio, prm->param_value, &parts);
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- if(!ret || (sk_BIO_num(parts) != 2) ) {
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE);
- sk_BIO_pop_free(parts, BIO_vfree);
- return NULL;
- }
-
- /* Parse the signature piece */
- p7in = sk_BIO_value(parts, 1);
-
- if (!(headers = mime_parse_hdr(p7in))) {
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR);
- sk_BIO_pop_free(parts, BIO_vfree);
- return NULL;
- }
-
- /* Get content type */
-
- if(!(hdr = mime_hdr_find(headers, "content-type")) ||
- !hdr->value) {
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE);
- return NULL;
- }
-
- if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
- strcmp(hdr->value, "application/pkcs7-signature")) {
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE);
- ERR_add_error_data(2, "type: ", hdr->value);
- sk_BIO_pop_free(parts, BIO_vfree);
- return NULL;
- }
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- /* Read in PKCS#7 */
- if(!(p7 = B64_read_PKCS7(p7in))) {
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR);
- sk_BIO_pop_free(parts, BIO_vfree);
- return NULL;
- }
-
- if(bcont) {
- *bcont = sk_BIO_value(parts, 0);
- BIO_free(p7in);
- sk_BIO_free(parts);
- } else sk_BIO_pop_free(parts, BIO_vfree);
- return p7;
- }
-
- /* OK, if not multipart/signed try opaque signature */
-
- if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
- strcmp (hdr->value, "application/pkcs7-mime")) {
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE);
- ERR_add_error_data(2, "type: ", hdr->value);
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
- return NULL;
- }
-
- sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-
- if(!(p7 = B64_read_PKCS7(bio))) {
- PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR);
- return NULL;
- }
- return p7;
-
-}
-
-/* Split a multipart/XXX message body into component parts: result is
- * canonical parts in a STACK of bios
- */
-
-static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
-{
- char linebuf[MAX_SMLEN];
- int len, blen;
- int eol = 0, next_eol = 0;
- BIO *bpart = NULL;
- STACK_OF(BIO) *parts;
- char state, part, first;
-
- blen = strlen(bound);
- part = 0;
- state = 0;
- first = 1;
- parts = sk_BIO_new_null();
- *ret = parts;
- while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
- state = mime_bound_check(linebuf, len, bound, blen);
- if(state == 1) {
- first = 1;
- part++;
- } else if(state == 2) {
- sk_BIO_push(parts, bpart);
- return 1;
- } else if(part) {
- /* Strip CR+LF from linebuf */
- next_eol = strip_eol(linebuf, &len);
- if(first) {
- first = 0;
- if(bpart) sk_BIO_push(parts, bpart);
- bpart = BIO_new(BIO_s_mem());
- BIO_set_mem_eof_return(bpart, 0);
- } else if (eol)
- BIO_write(bpart, "\r\n", 2);
- eol = next_eol;
- if (len)
- BIO_write(bpart, linebuf, len);
- }
- }
- return 0;
-}
-
-/* This is the big one: parse MIME header lines up to message body */
-
-#define MIME_INVALID 0
-#define MIME_START 1
-#define MIME_TYPE 2
-#define MIME_NAME 3
-#define MIME_VALUE 4
-#define MIME_QUOTE 5
-#define MIME_COMMENT 6
-
-
-static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
-{
- char *p, *q, c;
- char *ntmp;
- char linebuf[MAX_SMLEN];
- MIME_HEADER *mhdr = NULL;
- STACK_OF(MIME_HEADER) *headers;
- int len, state, save_state = 0;
-
- headers = sk_MIME_HEADER_new(mime_hdr_cmp);
- while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
- /* If whitespace at line start then continuation line */
- if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
- else state = MIME_START;
- ntmp = NULL;
- /* Go through all characters */
- for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
-
- /* State machine to handle MIME headers
- * if this looks horrible that's because it *is*
- */
-
- switch(state) {
- case MIME_START:
- if(c == ':') {
- state = MIME_TYPE;
- *p = 0;
- ntmp = strip_ends(q);
- q = p + 1;
- }
- break;
-
- case MIME_TYPE:
- if(c == ';') {
- mime_debug("Found End Value\n");
- *p = 0;
- mhdr = mime_hdr_new(ntmp, strip_ends(q));
- sk_MIME_HEADER_push(headers, mhdr);
- ntmp = NULL;
- q = p + 1;
- state = MIME_NAME;
- } else if(c == '(') {
- save_state = state;
- state = MIME_COMMENT;
- }
- break;
-
- case MIME_COMMENT:
- if(c == ')') {
- state = save_state;
- }
- break;
-
- case MIME_NAME:
- if(c == '=') {
- state = MIME_VALUE;
- *p = 0;
- ntmp = strip_ends(q);
- q = p + 1;
- }
- break ;
-
- case MIME_VALUE:
- if(c == ';') {
- state = MIME_NAME;
- *p = 0;
- mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
- ntmp = NULL;
- q = p + 1;
- } else if (c == '"') {
- mime_debug("Found Quote\n");
- state = MIME_QUOTE;
- } else if(c == '(') {
- save_state = state;
- state = MIME_COMMENT;
- }
- break;
-
- case MIME_QUOTE:
- if(c == '"') {
- mime_debug("Found Match Quote\n");
- state = MIME_VALUE;
- }
- break;
- }
- }
-
- if(state == MIME_TYPE) {
- mhdr = mime_hdr_new(ntmp, strip_ends(q));
- sk_MIME_HEADER_push(headers, mhdr);
- } else if(state == MIME_VALUE)
- mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
- if(p == linebuf) break; /* Blank line means end of headers */
-}
-
-return headers;
-
-}
-
-static char *strip_ends(char *name)
-{
- return strip_end(strip_start(name));
-}
-
-/* Strip a parameter of whitespace from start of param */
-static char *strip_start(char *name)
-{
- char *p, c;
- /* Look for first non white space or quote */
- for(p = name; (c = *p) ;p++) {
- if(c == '"') {
- /* Next char is start of string if non null */
- if(p[1]) return p + 1;
- /* Else null string */
- return NULL;
- }
- if(!isspace((unsigned char)c)) return p;
- }
- return NULL;
-}
-
-/* As above but strip from end of string : maybe should handle brackets? */
-static char *strip_end(char *name)
-{
- char *p, c;
- if(!name) return NULL;
- /* Look for first non white space or quote */
- for(p = name + strlen(name) - 1; p >= name ;p--) {
- c = *p;
- if(c == '"') {
- if(p - 1 == name) return NULL;
- *p = 0;
- return name;
- }
- if(isspace((unsigned char)c)) *p = 0;
- else return name;
- }
- return NULL;
-}
-
-static MIME_HEADER *mime_hdr_new(char *name, char *value)
-{
- MIME_HEADER *mhdr;
- char *tmpname, *tmpval, *p;
- int c;
- if(name) {
- if(!(tmpname = BUF_strdup(name))) return NULL;
- for(p = tmpname ; *p; p++) {
- c = *p;
- if(isupper(c)) {
- c = tolower(c);
- *p = c;
- }
- }
- } else tmpname = NULL;
- if(value) {
- if(!(tmpval = BUF_strdup(value))) return NULL;
- for(p = tmpval ; *p; p++) {
- c = *p;
- if(isupper(c)) {
- c = tolower(c);
- *p = c;
- }
- }
- } else tmpval = NULL;
- mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
- if(!mhdr) return NULL;
- mhdr->name = tmpname;
- mhdr->value = tmpval;
- if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
- return mhdr;
-}
-
-static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
-{
- char *tmpname, *tmpval, *p;
- int c;
- MIME_PARAM *mparam;
- if(name) {
- tmpname = BUF_strdup(name);
- if(!tmpname) return 0;
- for(p = tmpname ; *p; p++) {
- c = *p;
- if(isupper(c)) {
- c = tolower(c);
- *p = c;
- }
- }
- } else tmpname = NULL;
- if(value) {
- tmpval = BUF_strdup(value);
- if(!tmpval) return 0;
- } else tmpval = NULL;
- /* Parameter values are case sensitive so leave as is */
- mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
- if(!mparam) return 0;
- mparam->param_name = tmpname;
- mparam->param_value = tmpval;
- sk_MIME_PARAM_push(mhdr->params, mparam);
- return 1;
-}
-
-static int mime_hdr_cmp(const MIME_HEADER * const *a,
- const MIME_HEADER * const *b)
-{
- return(strcmp((*a)->name, (*b)->name));
-}
-
-static int mime_param_cmp(const MIME_PARAM * const *a,
- const MIME_PARAM * const *b)
-{
- return(strcmp((*a)->param_name, (*b)->param_name));
-}
-
-/* Find a header with a given name (if possible) */
-
-static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
-{
- MIME_HEADER htmp;
- int idx;
- htmp.name = name;
- idx = sk_MIME_HEADER_find(hdrs, &htmp);
- if(idx < 0) return NULL;
- return sk_MIME_HEADER_value(hdrs, idx);
-}
-
-static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
-{
- MIME_PARAM param;
- int idx;
- param.param_name = name;
- idx = sk_MIME_PARAM_find(hdr->params, &param);
- if(idx < 0) return NULL;
- return sk_MIME_PARAM_value(hdr->params, idx);
-}
-
-static void mime_hdr_free(MIME_HEADER *hdr)
-{
- if(hdr->name) OPENSSL_free(hdr->name);
- if(hdr->value) OPENSSL_free(hdr->value);
- if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
- OPENSSL_free(hdr);
-}
-
-static void mime_param_free(MIME_PARAM *param)
-{
- if(param->param_name) OPENSSL_free(param->param_name);
- if(param->param_value) OPENSSL_free(param->param_value);
- OPENSSL_free(param);
-}
-
-/* Check for a multipart boundary. Returns:
- * 0 : no boundary
- * 1 : part boundary
- * 2 : final boundary
- */
-static int mime_bound_check(char *line, int linelen, char *bound, int blen)
-{
- if(linelen == -1) linelen = strlen(line);
- if(blen == -1) blen = strlen(bound);
- /* Quickly eliminate if line length too short */
- if(blen + 2 > linelen) return 0;
- /* Check for part boundary */
- if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
- if(!strncmp(line + blen + 2, "--", 2)) return 2;
- else return 1;
- }
- return 0;
-}
-
-static int strip_eol(char *linebuf, int *plen)
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
{
- int len = *plen;
- char *p, c;
- int is_eol = 0;
- p = linebuf + len - 1;
- for (p = linebuf + len - 1; len > 0; len--, p--)
- {
- c = *p;
- if (c == '\n')
- is_eol = 1;
- else if (c != '\r')
- break;
- }
- *plen = len;
- return is_eol;
+ STACK_OF(X509_ALGOR) *mdalgs;
+ int ctype_nid = OBJ_obj2nid(p7->type);
+ if (ctype_nid == NID_pkcs7_signed)
+ mdalgs = p7->d.sign->md_algs;
+ else
+ mdalgs = NULL;
+
+ return int_smime_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
+ ctype_nid, NID_undef, mdalgs,
+ pk7_output_data,
+ ASN1_ITEM_rptr(PKCS7));
}
diff --git a/crypto/openssl/crypto/ppccpuid.pl b/crypto/openssl/crypto/ppccpuid.pl
deleted file mode 100755
index fe44ff0..0000000
--- a/crypto/openssl/crypto/ppccpuid.pl
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env perl
-
-$flavour = shift;
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or
-die "can't locate ppc-xlate.pl";
-
-open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-
-if ($flavour=~/64/) {
- $CMPLI="cmpldi";
- $SHRLI="srdi";
- $SIGNX="extsw";
-} else {
- $CMPLI="cmplwi";
- $SHRLI="srwi";
- $SIGNX="mr";
-}
-
-$code=<<___;
-.machine "any"
-.text
-
-.globl .OPENSSL_cpuid_setup
-.align 4
-.OPENSSL_cpuid_setup:
- blr
-
-.globl .OPENSSL_wipe_cpu
-.align 4
-.OPENSSL_wipe_cpu:
- xor r0,r0,r0
- mr r3,r1
- xor r4,r4,r4
- xor r5,r5,r5
- xor r6,r6,r6
- xor r7,r7,r7
- xor r8,r8,r8
- xor r9,r9,r9
- xor r10,r10,r10
- xor r11,r11,r11
- xor r12,r12,r12
- blr
-
-.globl .OPENSSL_atomic_add
-.align 4
-.OPENSSL_atomic_add:
-Loop: lwarx r5,0,r3
- add r0,r4,r5
- stwcx. r0,0,r3
- bne- Loop
- $SIGNX r3,r0
- blr
-
-.globl .OPENSSL_rdtsc
-.align 4
-.OPENSSL_rdtsc:
- mftb r3
- mftbu r4
- blr
-
-.globl .OPENSSL_cleanse
-.align 4
-.OPENSSL_cleanse:
- $CMPLI r4,7
- li r0,0
- bge Lot
-Little: mtctr r4
- stb r0,0(r3)
- addi r3,r3,1
- bdnz- \$-8
- blr
-Lot: andi. r5,r3,3
- beq Laligned
- stb r0,0(r3)
- subi r4,r4,1
- addi r3,r3,1
- b Lot
-Laligned:
- $SHRLI r5,r4,2
- mtctr r5
- stw r0,0(r3)
- addi r3,r3,4
- bdnz- \$-8
- andi. r4,r4,3
- bne Little
- blr
-___
-
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-print $code;
-close STDOUT;
diff --git a/crypto/openssl/crypto/rand/rand_win.c b/crypto/openssl/crypto/rand/rand_win.c
index 00dbe42..5d134e1 100644
--- a/crypto/openssl/crypto/rand/rand_win.c
+++ b/crypto/openssl/crypto/rand/rand_win.c
@@ -463,7 +463,7 @@ int RAND_poll(void)
PROCESSENTRY32 p;
THREADENTRY32 t;
MODULEENTRY32 m;
- DWORD stoptime = 0;
+ DWORD starttime = 0;
snap = (CREATETOOLHELP32SNAPSHOT)
GetProcAddress(kernel, "CreateToolhelp32Snapshot");
@@ -494,12 +494,29 @@ int RAND_poll(void)
* each entry. Consider each field a source of 1 byte
* of entropy.
*/
+ ZeroMemory(&hlist, sizeof(HEAPLIST32));
hlist.dwSize = sizeof(HEAPLIST32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
+#ifdef _MSC_VER
if (heaplist_first(handle, &hlist))
+ {
+ /*
+ following discussion on dev ML, exception on WinCE (or other Win
+ platform) is theoretically of unknown origin; prevent infinite
+ loop here when this theoretical case occurs; otherwise cope with
+ the expected (MSDN documented) exception-throwing behaviour of
+ Heap32Next() on WinCE.
+
+ based on patch in original message by Tanguy Fautré (2009/03/02)
+ Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
+ */
+ int ex_cnt_limit = 42;
do
{
RAND_add(&hlist, hlist.dwSize, 3);
+ __try
+ {
+ ZeroMemory(&hentry, sizeof(HEAPENTRY32));
hentry.dwSize = sizeof(HEAPENTRY32);
if (heap_first(&hentry,
hlist.th32ProcessID,
@@ -510,10 +527,42 @@ int RAND_poll(void)
RAND_add(&hentry,
hentry.dwSize, 5);
while (heap_next(&hentry)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY)
&& --entrycnt > 0);
}
- } while (heaplist_next(handle,
- &hlist) && GetTickCount() < stoptime);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* ignore access violations when walking the heap list */
+ ex_cnt_limit--;
+ }
+ } while (heaplist_next(handle, &hlist)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY)
+ && ex_cnt_limit > 0);
+ }
+
+#else
+ if (heaplist_first(handle, &hlist))
+ {
+ do
+ {
+ RAND_add(&hlist, hlist.dwSize, 3);
+ hentry.dwSize = sizeof(HEAPENTRY32);
+ if (heap_first(&hentry,
+ hlist.th32ProcessID,
+ hlist.th32HeapID))
+ {
+ int entrycnt = 80;
+ do
+ RAND_add(&hentry,
+ hentry.dwSize, 5);
+ while (heap_next(&hentry)
+ && --entrycnt > 0);
+ }
+ } while (heaplist_next(handle, &hlist)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY));
+ }
+#endif
/* process walking */
/* PROCESSENTRY32 contains 9 fields that will change
@@ -522,11 +571,11 @@ int RAND_poll(void)
*/
p.dwSize = sizeof(PROCESSENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (process_first(handle, &p))
do
RAND_add(&p, p.dwSize, 9);
- while (process_next(handle, &p) && GetTickCount() < stoptime);
+ while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
/* thread walking */
/* THREADENTRY32 contains 6 fields that will change
@@ -534,11 +583,11 @@ int RAND_poll(void)
* 1 byte of entropy.
*/
t.dwSize = sizeof(THREADENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (thread_first(handle, &t))
do
RAND_add(&t, t.dwSize, 6);
- while (thread_next(handle, &t) && GetTickCount() < stoptime);
+ while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
/* module walking */
/* MODULEENTRY32 contains 9 fields that will change
@@ -546,12 +595,12 @@ int RAND_poll(void)
* 1 byte of entropy.
*/
m.dwSize = sizeof(MODULEENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (module_first(handle, &m))
do
RAND_add(&m, m.dwSize, 9);
while (module_next(handle, &m)
- && (GetTickCount() < stoptime));
+ && (!good || (GetTickCount()-starttime)<MAXDELAY));
if (close_snap)
close_snap(handle);
else
@@ -701,7 +750,7 @@ static void readscreen(void)
int y; /* y-coordinate of screen lines to grab */
int n = 16; /* number of screen lines to grab at a time */
- if (GetVersion() >= 0x80000000 || !OPENSSL_isservice())
+ if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
return;
/* Create a screen DC and a memory DC compatible to screen DC */
diff --git a/crypto/openssl/crypto/rand/randfile.c b/crypto/openssl/crypto/rand/randfile.c
index d108353..84276d7 100644
--- a/crypto/openssl/crypto/rand/randfile.c
+++ b/crypto/openssl/crypto/rand/randfile.c
@@ -117,6 +117,15 @@ int RAND_load_file(const char *file, long bytes)
if (file == NULL) return(0);
+#ifdef PURIFY
+ /* struct stat can have padding and unused fields that may not be
+ * initialized in the call to stat(). We need to clear the entire
+ * structure before calling RAND_add() to avoid complaints from
+ * applications such as Valgrind.
+ */
+ memset(&sb, 0, sizeof(sb));
+#endif
+
if (stat(file,&sb) < 0) return(0);
RAND_add(&sb,sizeof(sb),0.0);
if (bytes == 0) return(ret);
@@ -127,8 +136,8 @@ int RAND_load_file(const char *file, long bytes)
in=fopen(file,"rb");
#endif
if (in == NULL) goto err;
-#if defined(S_IFBLK) && defined(S_IFCHR)
- if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
+#if defined(S_ISBLK) && defined(S_ISCHR)
+ if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
/* this file is a device. we don't want read an infinite number
* of bytes from a random device, nor do we want to use buffered
* I/O because we will waste system entropy.
@@ -174,8 +183,8 @@ int RAND_write_file(const char *file)
i=stat(file,&sb);
if (i != -1) {
-#if defined(S_IFBLK) && defined(S_IFCHR)
- if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
+#if defined(S_ISBLK) && defined(S_ISCHR)
+ if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
/* this file is a device. we don't write back to it.
* we "succeed" on the assumption this is some sort
* of random device. Otherwise attempting to write to
diff --git a/crypto/openssl/crypto/rsa/rsa.h b/crypto/openssl/crypto/rsa/rsa.h
index b7903d3..5bb932a 100644
--- a/crypto/openssl/crypto/rsa/rsa.h
+++ b/crypto/openssl/crypto/rsa/rsa.h
@@ -55,7 +55,6 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
-/* $FreeBSD$ */
#ifndef HEADER_RSA_H
#define HEADER_RSA_H
diff --git a/crypto/openssl/crypto/rsa/rsa_eay.c b/crypto/openssl/crypto/rsa/rsa_eay.c
index 7d3b260..0ac6418 100644
--- a/crypto/openssl/crypto/rsa/rsa_eay.c
+++ b/crypto/openssl/crypto/rsa/rsa_eay.c
@@ -108,7 +108,6 @@
* Hudson (tjh@cryptsoft.com).
*
*/
-/* $FreeBSD$ */
#include <stdio.h>
#include "cryptlib.h"
diff --git a/crypto/openssl/crypto/rsa/rsa_eng.c b/crypto/openssl/crypto/rsa/rsa_eng.c
index 383a704..2f21ddb 100644
--- a/crypto/openssl/crypto/rsa/rsa_eng.c
+++ b/crypto/openssl/crypto/rsa/rsa_eng.c
@@ -207,8 +207,17 @@ RSA *RSA_new_method(ENGINE *engine)
ret->blinding=NULL;
ret->mt_blinding=NULL;
ret->bignum_data=NULL;
- ret->flags=ret->meth->flags;
- CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
+ ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
+ {
+#ifndef OPENSSL_NO_ENGINE
+ if (ret->engine)
+ ENGINE_finish(ret->engine);
+#endif
+ OPENSSL_free(ret);
+ return(NULL);
+ }
+
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{
#ifndef OPENSSL_NO_ENGINE
diff --git a/crypto/openssl/crypto/rsa/rsa_oaep.c b/crypto/openssl/crypto/rsa/rsa_oaep.c
index 4d30c9d..546ae5f 100644
--- a/crypto/openssl/crypto/rsa/rsa_oaep.c
+++ b/crypto/openssl/crypto/rsa/rsa_oaep.c
@@ -52,13 +52,6 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
return 0;
}
- dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
- if (dbmask == NULL)
- {
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
to[0] = 0;
seed = to + 1;
db = to + SHA_DIGEST_LENGTH + 1;
@@ -76,6 +69,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
20);
#endif
+ dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
+ if (dbmask == NULL)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
db[i] ^= dbmask[i];
diff --git a/crypto/openssl/crypto/rsa/rsa_pss.c b/crypto/openssl/crypto/rsa/rsa_pss.c
index 9b993ac..2bda491 100644
--- a/crypto/openssl/crypto/rsa/rsa_pss.c
+++ b/crypto/openssl/crypto/rsa/rsa_pss.c
@@ -217,7 +217,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!RAND_bytes(salt, sLen))
+ if (RAND_bytes(salt, sLen) <= 0)
goto err;
}
maskedDBLen = emLen - hLen - 1;
diff --git a/crypto/openssl/crypto/rsa/rsa_sign.c b/crypto/openssl/crypto/rsa/rsa_sign.c
index 5488c06..743dfd7 100644
--- a/crypto/openssl/crypto/rsa/rsa_sign.c
+++ b/crypto/openssl/crypto/rsa/rsa_sign.c
@@ -137,7 +137,12 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
i2d_X509_SIG(&sig,&p);
s=tmps;
}
+#ifdef OPENSSL_FIPS
+ /* Bypass algorithm blocking: this is allowed if we get this far */
+ i=rsa->meth->rsa_priv_enc(i,s,sigret,rsa,RSA_PKCS1_PADDING);
+#else
i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
+#endif
if (i <= 0)
ret=0;
else
@@ -190,8 +195,11 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
-#endif
+ /* Bypass algorithm blocking: this is allowed */
+ i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+#else
i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+#endif
if (i <= 0) goto err;
diff --git a/crypto/openssl/crypto/s390xcpuid.S b/crypto/openssl/crypto/s390xcpuid.S
deleted file mode 100644
index 8500133..0000000
--- a/crypto/openssl/crypto/s390xcpuid.S
+++ /dev/null
@@ -1,90 +0,0 @@
-.text
-
-.globl OPENSSL_cpuid_setup
-.type OPENSSL_cpuid_setup,@function
-.align 16
-OPENSSL_cpuid_setup:
- br %r14 # reserved for future
-.size OPENSSL_cpuid_setup,.-OPENSSL_cpuid_setup
-
-.globl OPENSSL_s390x_facilities
-.type OPENSSL_s390x_facilities,@function
-.align 16
-OPENSSL_s390x_facilities:
- lghi %r0,0
- .long 0xb2b0f010 # stfle 16(%r15)
- lg %r2,16(%r15)
- br %r14
-.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
-
-.globl OPENSSL_rdtsc
-.type OPENSSL_rdtsc,@function
-.align 16
-OPENSSL_rdtsc:
- stck 16(%r15)
- lg %r2,16(%r15)
- br %r14
-.size OPENSSL_rdtsc,.-OPENSSL_rdtsc
-
-.globl OPENSSL_atomic_add
-.type OPENSSL_atomic_add,@function
-.align 16
-OPENSSL_atomic_add:
- l %r1,0(%r2)
-.Lspin: lr %r0,%r1
- ar %r0,%r3
- cs %r1,%r0,0(%r2)
- brc 4,.Lspin
- lgfr %r2,%r0 # OpenSSL expects the new value
- br %r14
-.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
-
-.globl OPENSSL_wipe_cpu
-.type OPENSSL_wipe_cpu,@function
-.align 16
-OPENSSL_wipe_cpu:
- xgr %r0,%r0
- xgr %r1,%r1
- lgr %r2,%r15
- xgr %r3,%r3
- xgr %r4,%r4
- lzdr %f0
- lzdr %f1
- lzdr %f2
- lzdr %f3
- lzdr %f4
- lzdr %f5
- lzdr %f6
- lzdr %f7
- br %r14
-.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
-
-.globl OPENSSL_cleanse
-.type OPENSSL_cleanse,@function
-.align 16
-OPENSSL_cleanse:
- lghi %r4,15
- lghi %r0,0
- clgr %r3,%r4
- jh .Lot
-.Little:
- stc %r0,0(%r2)
- la %r2,1(%r2)
- brctg %r3,.Little
- br %r14
-.align 4
-.Lot: tmll %r2,7
- jz .Laligned
- stc %r0,0(%r2)
- la %r2,1(%r2)
- brctg %r3,.Lot
-.Laligned:
- srlg %r4,%r3,3
-.Loop: stg %r0,0(%r2)
- la %r2,8(%r2)
- brctg %r4,.Loop
- lghi %r4,7
- ngr %r3,%r4
- jnz .Little
- br %r14
-.size OPENSSL_cleanse,.-OPENSSL_cleanse
diff --git a/crypto/openssl/crypto/sha/sha512.c b/crypto/openssl/crypto/sha/sha512.c
index f5ed468..9e91bca 100644
--- a/crypto/openssl/crypto/sha/sha512.c
+++ b/crypto/openssl/crypto/sha/sha512.c
@@ -544,4 +544,13 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
#endif /* SHA512_ASM */
+#else /* OPENSSL_NO_SHA512 */
+
+/* Sensitive compilers ("Compaq C V6.4-005 on OpenVMS VAX V7.3", for
+ * example) dislike a statement-free file, complaining:
+ * "%CC-W-EMPTYFILE, Source file does not contain any declarations."
+ */
+
+int sha512_dummy();
+
#endif /* OPENSSL_NO_SHA512 */
diff --git a/crypto/openssl/crypto/sparcv9cap.c b/crypto/openssl/crypto/sparcv9cap.c
deleted file mode 100644
index 5f31d20..0000000
--- a/crypto/openssl/crypto/sparcv9cap.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <openssl/bn.h>
-
-#define SPARCV9_TICK_PRIVILEGED (1<<0)
-#define SPARCV9_PREFER_FPU (1<<1)
-#define SPARCV9_VIS1 (1<<2)
-#define SPARCV9_VIS2 (1<<3) /* reserved */
-#define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */
-static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
-
-int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
- {
- int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
- int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
-
- if ((OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
- (SPARCV9_PREFER_FPU|SPARCV9_VIS1))
- return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
- else
- return bn_mul_mont_int(rp,ap,bp,np,n0,num);
- }
-
-unsigned long OPENSSL_rdtsc(void)
- {
- unsigned long _sparcv9_rdtick(void);
-
- if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
-#if defined(__sun) && defined(__SVR4)
- return gethrtime();
-#else
- return 0;
-#endif
- else
- return _sparcv9_rdtick();
- }
-
-#if defined(__sun) && defined(__SVR4)
-
-#include <dlfcn.h>
-#include <libdevinfo.h>
-#include <sys/systeminfo.h>
-
-typedef di_node_t (*di_init_t)(const char *,uint_t);
-typedef void (*di_fini_t)(di_node_t);
-typedef char * (*di_node_name_t)(di_node_t);
-typedef int (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t));
-
-#define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))
-
-static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
- {
- char *name = (*di_node_name)(node);
-
- /* This is expected to catch all UltraSPARC flavors prior T1 */
- if (!strcmp (name,"SUNW,UltraSPARC") ||
- !strncmp(name,"SUNW,UltraSPARC-I",17)) /* covers II,III,IV */
- {
- OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
-
- /* %tick is privileged only on UltraSPARC-I/II, but not IIe */
- if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
- OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
-
- return DI_WALK_TERMINATE;
- }
- /* This is expected to catch remaining UltraSPARCs, such as T1 */
- else if (!strncmp(name,"SUNW,UltraSPARC",15))
- {
- OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
-
- return DI_WALK_TERMINATE;
- }
-
- return DI_WALK_CONTINUE;
- }
-
-void OPENSSL_cpuid_setup(void)
- {
- void *h;
- char *e,si[256];
- static int trigger=0;
-
- if (trigger) return;
- trigger=1;
-
- if ((e=getenv("OPENSSL_sparcv9cap")))
- {
- OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
- return;
- }
-
- if (sysinfo(SI_MACHINE,si,sizeof(si))>0)
- {
- if (strcmp(si,"sun4v"))
- /* FPU is preferred for all CPUs, but US-T1/2 */
- OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
- }
-
- if (sysinfo(SI_ISALIST,si,sizeof(si))>0)
- {
- if (strstr(si,"+vis"))
- OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
- if (strstr(si,"+vis2"))
- {
- OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
- OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
- return;
- }
- }
-
- if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do
- {
- di_init_t di_init;
- di_fini_t di_fini;
- di_walk_node_t di_walk_node;
- di_node_name_t di_node_name;
- di_node_t root_node;
-
- if (!DLLINK(h,di_init)) break;
- if (!DLLINK(h,di_fini)) break;
- if (!DLLINK(h,di_walk_node)) break;
- if (!DLLINK(h,di_node_name)) break;
-
- if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL)
- {
- (*di_walk_node)(root_node,DI_WALK_SIBFIRST,
- di_node_name,walk_nodename);
- (*di_fini)(root_node);
- }
- } while(0);
-
- if (h) dlclose(h);
- }
-
-#else
-
-void OPENSSL_cpuid_setup(void)
- {
- char *e;
-
- if ((e=getenv("OPENSSL_sparcv9cap")))
- {
- OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
- return;
- }
-
- /* For now we assume that the rest supports UltraSPARC-I* only */
- OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
- }
-
-#endif
diff --git a/crypto/openssl/crypto/stack/safestack.h b/crypto/openssl/crypto/stack/safestack.h
index 40b1790..78cc485 100644
--- a/crypto/openssl/crypto/stack/safestack.h
+++ b/crypto/openssl/crypto/stack/safestack.h
@@ -986,50 +986,6 @@ STACK_OF(type) \
#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
-#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st))
-#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
-#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
-#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
-#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
-#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
-#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
-#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
-#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
-#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
-#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
-#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
-#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
-#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
-#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
-#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
-#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
-
-#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
-#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
-#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
-#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
-#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
-#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
-#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
-#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
-#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
-#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
-#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
-#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
-#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
-#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
-#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
-#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
-#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
-
#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
diff --git a/crypto/openssl/crypto/symhacks.h b/crypto/openssl/crypto/symhacks.h
index 8728e61..0114093 100644
--- a/crypto/openssl/crypto/symhacks.h
+++ b/crypto/openssl/crypto/symhacks.h
@@ -60,6 +60,11 @@
/* Hacks to solve the problem with linkers incapable of handling very long
symbol names. In the case of VMS, the limit is 31 characters on VMS for
VAX. */
+/* Note that this affects util/libeay.num and util/ssleay.num... you may
+ change those manually, but that's not recommended, as those files are
+ controlled centrally and updated on Unix, and the central definition
+ may disagree with yours, which in turn may come with shareable library
+ incompatibilities. */
#ifdef OPENSSL_SYS_VMS
/* Hack a long name in crypto/cryptlib.c */
@@ -137,6 +142,8 @@
#define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers
#undef X509_STORE_CTX_get_explicit_policy
#define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy
+#undef X509_STORE_CTX_get0_current_issuer
+#define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer
/* Hack some long CRYPTO names */
#undef CRYPTO_set_dynlock_destroy_callback
@@ -174,6 +181,15 @@
#undef SSL_COMP_get_compression_methods
#define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods
+#undef ssl_add_clienthello_renegotiate_ext
+#define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext
+#undef ssl_add_serverhello_renegotiate_ext
+#define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext
+#undef ssl_parse_clienthello_renegotiate_ext
+#define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext
+#undef ssl_parse_serverhello_renegotiate_ext
+#define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext
+
/* Hack some long ENGINE names */
#undef ENGINE_get_default_BN_mod_exp_crt
#define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt
@@ -365,6 +381,10 @@
#undef cms_SignerIdentifier_get0_signer_id
#define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id
+/* Hack some long DTLS1 names */
+#undef dtls1_retransmit_buffered_messages
+#define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs
+
#endif /* defined OPENSSL_SYS_VMS */
diff --git a/crypto/openssl/crypto/ui/ui_openssl.c b/crypto/openssl/crypto/ui/ui_openssl.c
index ef930bf..06270f0 100644
--- a/crypto/openssl/crypto/ui/ui_openssl.c
+++ b/crypto/openssl/crypto/ui/ui_openssl.c
@@ -297,7 +297,7 @@ static int is_a_tty;
/* Declare static functions */
#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
-static void read_till_nl(FILE *);
+static int read_till_nl(FILE *);
static void recsig(int);
static void pushsig(void);
static void popsig(void);
@@ -390,14 +390,16 @@ static int read_string(UI *ui, UI_STRING *uis)
#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
/* Internal functions to read a string without echoing */
-static void read_till_nl(FILE *in)
+static int read_till_nl(FILE *in)
{
#define SIZE 4
char buf[SIZE+1];
do {
- fgets(buf,SIZE,in);
+ if (!fgets(buf,SIZE,in))
+ return 0;
} while (strchr(buf,'\n') == NULL);
+ return 1;
}
static volatile sig_atomic_t intr_signal;
@@ -445,7 +447,8 @@ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
*p='\0';
}
else
- read_till_nl(tty_in);
+ if (!read_till_nl(tty_in))
+ goto error;
if (UI_set_result(ui, uis, result) >= 0)
ok=1;
diff --git a/crypto/openssl/crypto/x509/by_dir.c b/crypto/openssl/crypto/x509/by_dir.c
index 341e0ba..b3acd80 100644
--- a/crypto/openssl/crypto/x509/by_dir.c
+++ b/crypto/openssl/crypto/x509/by_dir.c
@@ -360,11 +360,11 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
/* we have added it to the cache so now pull
* it out again */
- CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp);
if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j);
else tmp = NULL;
- CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (tmp != NULL)
{
@@ -383,4 +383,3 @@ finish:
if (b != NULL) BUF_MEM_free(b);
return(ok);
}
-
diff --git a/crypto/openssl/crypto/x509/x509.h b/crypto/openssl/crypto/x509/x509.h
index e71b525..8958e34 100644
--- a/crypto/openssl/crypto/x509/x509.h
+++ b/crypto/openssl/crypto/x509/x509.h
@@ -116,6 +116,7 @@ extern "C" {
/* Under Win32 these are defined in wincrypt.h */
#undef X509_NAME
#undef X509_CERT_PAIR
+#undef X509_EXTENSIONS
#endif
#define X509_FILETYPE_PEM 1
diff --git a/crypto/openssl/crypto/x509/x509_lu.c b/crypto/openssl/crypto/x509/x509_lu.c
index cd2cfb6..b486171 100644
--- a/crypto/openssl/crypto/x509/x509_lu.c
+++ b/crypto/openssl/crypto/x509/x509_lu.c
@@ -198,7 +198,13 @@ X509_STORE *X509_STORE_new(void)
ret->cert_crl = 0;
ret->cleanup = 0;
- CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data);
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
+ {
+ sk_X509_OBJECT_free(ret->objs);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
ret->references=1;
return ret;
}
@@ -286,7 +292,9 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
X509_OBJECT stmp,*tmp;
int i,j;
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (tmp == NULL)
{
@@ -340,7 +348,6 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
X509_OBJECT_up_ref_count(obj);
-
if (X509_OBJECT_retrieve_match(ctx->objs, obj))
{
X509_OBJECT_free_contents(obj);
@@ -446,15 +453,15 @@ int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
X509_NAME *name)
-{
+ {
int idx;
idx = X509_OBJECT_idx_by_subject(h, type, name);
if (idx==-1) return NULL;
return sk_X509_OBJECT_value(h, idx);
-}
+ }
X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
-{
+ {
int idx, i;
X509_OBJECT *obj;
idx = sk_X509_OBJECT_find(h, x);
@@ -469,13 +476,13 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x
return obj;
}
return NULL;
-}
+ }
/* Try to get issuer certificate from store. Due to limitations
* of the API this can only retrieve a single certificate matching
* a given subject name. However it will fill the cache with all
- * matching certificates, so we can examine the cache for all
+ * matching certificates, so we can examine the cache for all
* matches.
*
* Return values are:
@@ -483,13 +490,11 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x
* 0 certificate not found.
* -1 some other error.
*/
-
-
int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
-{
+ {
X509_NAME *xn;
X509_OBJECT obj, *pobj;
- int i, ok, idx;
+ int i, ok, idx, ret;
xn=X509_get_issuer_name(x);
ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
if (ok != X509_LU_X509)
@@ -515,27 +520,34 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
return 1;
}
X509_OBJECT_free_contents(&obj);
- /* Else find index of first matching cert */
- idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
- /* This shouldn't normally happen since we already have one match */
- if (idx == -1) return 0;
- /* Look through all matching certificates for a suitable issuer */
- for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
+ /* Else find index of first cert accepted by 'check_issued' */
+ ret = 0;
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
+ if (idx != -1) /* should be true as we've had at least one match */
{
- pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
- /* See if we've ran out of matches */
- if (pobj->type != X509_LU_X509) return 0;
- if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0;
- if (ctx->check_issued(ctx, x, pobj->data.x509))
+ /* Look through all matching certs for suitable issuer */
+ for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
{
- *issuer = pobj->data.x509;
- X509_OBJECT_up_ref_count(pobj);
- return 1;
+ pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+ /* See if we've run past the matches */
+ if (pobj->type != X509_LU_X509)
+ break;
+ if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
+ break;
+ if (ctx->check_issued(ctx, x, pobj->data.x509))
+ {
+ *issuer = pobj->data.x509;
+ X509_OBJECT_up_ref_count(pobj);
+ ret = 1;
+ break;
+ }
}
}
- return 0;
-}
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ return ret;
+ }
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
{
diff --git a/crypto/openssl/crypto/x509/x509_vfy.c b/crypto/openssl/crypto/x509/x509_vfy.c
index 336c40d..b85456e 100644
--- a/crypto/openssl/crypto/x509/x509_vfy.c
+++ b/crypto/openssl/crypto/x509/x509_vfy.c
@@ -986,7 +986,12 @@ static int internal_verify(X509_STORE_CTX *ctx)
while (n >= 0)
{
ctx->error_depth=n;
- if (!xs->valid)
+
+ /* Skip signature check for self signed certificates unless
+ * explicitly asked for. It doesn't add any security and
+ * just wastes time.
+ */
+ if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
{
if ((pkey=X509_get_pubkey(xi)) == NULL)
{
@@ -996,13 +1001,6 @@ static int internal_verify(X509_STORE_CTX *ctx)
if (!ok) goto end;
}
else if (X509_verify(xs,pkey) <= 0)
- /* XXX For the final trusted self-signed cert,
- * this is a waste of time. That check should
- * optional so that e.g. 'openssl x509' can be
- * used to detect invalid self-signatures, but
- * we don't verify again and again in SSL
- * handshakes and the like once the cert has
- * been declared trusted. */
{
ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
ctx->current_cert=xs;
diff --git a/crypto/openssl/crypto/x509/x509_vfy.h b/crypto/openssl/crypto/x509/x509_vfy.h
index 76c76e1..86ae35f 100644
--- a/crypto/openssl/crypto/x509/x509_vfy.h
+++ b/crypto/openssl/crypto/x509/x509_vfy.h
@@ -363,6 +363,9 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
/* Notify callback that policy is OK */
#define X509_V_FLAG_NOTIFY_POLICY 0x800
+/* Check selfsigned CA signature */
+#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
+
#define X509_VP_FLAG_DEFAULT 0x1
#define X509_VP_FLAG_OVERWRITE 0x2
#define X509_VP_FLAG_RESET_FLAGS 0x4
diff --git a/crypto/openssl/crypto/x509/x509_vpm.c b/crypto/openssl/crypto/x509/x509_vpm.c
index 2b06718..01c5541 100644
--- a/crypto/openssl/crypto/x509/x509_vpm.c
+++ b/crypto/openssl/crypto/x509/x509_vpm.c
@@ -198,8 +198,12 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
const X509_VERIFY_PARAM *from)
{
+ unsigned long save_flags = to->inh_flags;
+ int ret;
to->inh_flags |= X509_VP_FLAG_DEFAULT;
- return X509_VERIFY_PARAM_inherit(to, from);
+ ret = X509_VERIFY_PARAM_inherit(to, from);
+ to->inh_flags = save_flags;
+ return ret;
}
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
diff --git a/crypto/openssl/crypto/x509v3/pcy_tree.c b/crypto/openssl/crypto/x509v3/pcy_tree.c
index 6c87a7f..89f84bf 100644
--- a/crypto/openssl/crypto/x509v3/pcy_tree.c
+++ b/crypto/openssl/crypto/x509v3/pcy_tree.c
@@ -160,7 +160,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
tree->auth_policies = NULL;
tree->user_policies = NULL;
- if (!tree)
+ if (!tree->levels)
{
OPENSSL_free(tree);
return 0;
diff --git a/crypto/openssl/crypto/x509v3/v3_alt.c b/crypto/openssl/crypto/x509v3/v3_alt.c
index 58b2952..69244e4 100644
--- a/crypto/openssl/crypto/x509v3/v3_alt.c
+++ b/crypto/openssl/crypto/x509v3/v3_alt.c
@@ -360,6 +360,7 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
if (move_p)
{
X509_NAME_delete_entry(nm, i);
+ X509_NAME_ENTRY_free(ne);
i--;
}
if(!email || !(gen = GENERAL_NAME_new())) {
@@ -577,6 +578,8 @@ static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
if (!ret)
X509_NAME_free(nm);
gen->d.dirn = nm;
+
+ X509V3_section_free(ctx, sk);
return ret;
}
diff --git a/crypto/openssl/crypto/x509v3/v3_ocsp.c b/crypto/openssl/crypto/x509v3/v3_ocsp.c
index e426ea9..5c19cf4 100644
--- a/crypto/openssl/crypto/x509v3/v3_ocsp.c
+++ b/crypto/openssl/crypto/x509v3/v3_ocsp.c
@@ -153,21 +153,21 @@ static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
OCSP_CRLID *a = in;
if (a->crlUrl)
{
- if (!BIO_printf(bp, "%*scrlUrl: ", ind, "")) goto err;
+ if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) goto err;
if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
- if (!BIO_write(bp, "\n", 1)) goto err;
+ if (BIO_write(bp, "\n", 1) <= 0) goto err;
}
if (a->crlNum)
{
- if (!BIO_printf(bp, "%*scrlNum: ", ind, "")) goto err;
- if (!i2a_ASN1_INTEGER(bp, a->crlNum)) goto err;
- if (!BIO_write(bp, "\n", 1)) goto err;
+ if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) goto err;
+ if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) goto err;
+ if (BIO_write(bp, "\n", 1) <= 0) goto err;
}
if (a->crlTime)
{
- if (!BIO_printf(bp, "%*scrlTime: ", ind, "")) goto err;
+ if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) goto err;
if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
- if (!BIO_write(bp, "\n", 1)) goto err;
+ if (BIO_write(bp, "\n", 1) <= 0) goto err;
}
return 1;
err:
@@ -176,7 +176,7 @@ static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, int ind)
{
- if (!BIO_printf(bp, "%*s", ind, "")) return 0;
+ if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
return 1;
}
@@ -184,8 +184,8 @@ static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, in
static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind)
{
- if (!BIO_printf(bp, "%*s", ind, "")) return 0;
- if(!i2a_ASN1_OBJECT(bp, oid)) return 0;
+ if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
+ if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
return 1;
}
diff --git a/crypto/openssl/demos/x509/mkcert.c b/crypto/openssl/demos/x509/mkcert.c
index c5e67b8..6a52e5d 100644
--- a/crypto/openssl/demos/x509/mkcert.c
+++ b/crypto/openssl/demos/x509/mkcert.c
@@ -136,7 +136,7 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
}
#endif
- if (!X509_sign(x,pk,EVP_md5()))
+ if (!X509_sign(x,pk,EVP_sha1()))
goto err;
*x509p=x;
diff --git a/crypto/openssl/demos/x509/mkreq.c b/crypto/openssl/demos/x509/mkreq.c
index 3dfc65f..d17e4ad 100644
--- a/crypto/openssl/demos/x509/mkreq.c
+++ b/crypto/openssl/demos/x509/mkreq.c
@@ -134,7 +134,7 @@ int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
#endif
- if (!X509_REQ_sign(x,pk,EVP_md5()))
+ if (!X509_REQ_sign(x,pk,EVP_sha1()))
goto err;
*req=x;
diff --git a/crypto/openssl/doc/apps/enc.pod b/crypto/openssl/doc/apps/enc.pod
index 4391c93..d3049e8 100644
--- a/crypto/openssl/doc/apps/enc.pod
+++ b/crypto/openssl/doc/apps/enc.pod
@@ -50,15 +50,13 @@ see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
=item B<-salt>
-use a salt in the key derivation routines. This option should B<ALWAYS>
-be used unless compatibility with previous versions of OpenSSL or SSLeay
-is required. This option is only present on OpenSSL versions 0.9.5 or
-above.
+use a salt in the key derivation routines. This is the default.
=item B<-nosalt>
-don't use a salt in the key derivation routines. This is the default for
-compatibility with previous versions of OpenSSL and SSLeay.
+don't use a salt in the key derivation routines. This option B<SHOULD NOT> be
+used except for test purposes or compatibility with ancient versions of OpenSSL
+and SSLeay.
=item B<-e>
diff --git a/crypto/openssl/doc/apps/verify.pod b/crypto/openssl/doc/apps/verify.pod
index ff2629d..3187577 100644
--- a/crypto/openssl/doc/apps/verify.pod
+++ b/crypto/openssl/doc/apps/verify.pod
@@ -66,6 +66,11 @@ certificate was rejected. However the presence of rejection messages
does not itself imply that anything is wrong: during the normal
verify process several rejections may take place.
+=item B<-check_ss_sig>
+
+Verify the signature on the self-signed root CA. This is disabled by default
+because it doesn't add any security.
+
=item B<->
marks the last option. All arguments following this are assumed to be
@@ -166,8 +171,8 @@ the operation was successful.
=item B<2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
-the issuer certificate could not be found: this occurs if the issuer certificate
-of an untrusted certificate cannot be found.
+the issuer certificate of a looked up certificate could not be found. This
+normally means the list of trusted certificates is not complete.
=item B<3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
@@ -244,8 +249,8 @@ be found locally.
=item B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
-the issuer certificate of a locally looked up certificate could not be found. This normally means
-the list of trusted certificates is not complete.
+the issuer certificate could not be found: this occurs if the issuer
+certificate of an untrusted certificate cannot be found.
=item B<21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
@@ -321,6 +326,10 @@ the certificates in the file will be recognised.
Previous versions of OpenSSL assume certificates with matching subject name are identical and
mishandled them.
+Previous versions of this documentation swapped the meaning of the
+B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT> and
+B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.
+
=head1 SEE ALSO
L<x509(1)|x509(1)>
diff --git a/crypto/openssl/doc/crypto/ASN1_generate_nconf.pod b/crypto/openssl/doc/crypto/ASN1_generate_nconf.pod
index 1157cff..179132d 100644
--- a/crypto/openssl/doc/crypto/ASN1_generate_nconf.pod
+++ b/crypto/openssl/doc/crypto/ASN1_generate_nconf.pod
@@ -175,7 +175,7 @@ An IA5String explicitly tagged using APPLICATION tagging:
A BITSTRING with bits 1 and 5 set and all others zero:
- FORMAT=BITLIST,BITSTRING:1,5
+ FORMAT:BITLIST,BITSTRING:1,5
A more complex example using a config file to produce a
SEQUENCE consiting of a BOOL an OID and a UTF8String:
diff --git a/crypto/openssl/doc/crypto/EVP_DigestInit.pod b/crypto/openssl/doc/crypto/EVP_DigestInit.pod
index 130cd7f..98b1368 100644
--- a/crypto/openssl/doc/crypto/EVP_DigestInit.pod
+++ b/crypto/openssl/doc/crypto/EVP_DigestInit.pod
@@ -64,9 +64,9 @@ EVP digest routines
The EVP digest routines are a high level interface to message digests.
-EVP_MD_CTX_init() initializes digest contet B<ctx>.
+EVP_MD_CTX_init() initializes digest context B<ctx>.
-EVP_MD_CTX_create() allocates, initializes and returns a digest contet.
+EVP_MD_CTX_create() allocates, initializes and returns a digest context.
EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest
B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this
@@ -102,7 +102,7 @@ the passed context B<ctx> does not have to be initialized, and it always
uses the default digest implementation.
EVP_DigestFinal() is similar to EVP_DigestFinal_ex() except the digest
-contet B<ctx> is automatically cleaned up.
+context B<ctx> is automatically cleaned up.
EVP_MD_CTX_copy() is similar to EVP_MD_CTX_copy_ex() except the destination
B<out> does not have to be initialized.
diff --git a/crypto/openssl/doc/crypto/PKCS12_parse.pod b/crypto/openssl/doc/crypto/PKCS12_parse.pod
index 51344f8..c54cf2a 100644
--- a/crypto/openssl/doc/crypto/PKCS12_parse.pod
+++ b/crypto/openssl/doc/crypto/PKCS12_parse.pod
@@ -20,24 +20,31 @@ certificate to B<*cert> and any additional certificates to B<*ca>.
=head1 NOTES
-The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL>
-in which case additional certificates will be discarded. B<*ca> can also
-be a valid STACK in which case additional certificates are appended to
-B<*ca>. If B<*ca> is B<NULL> a new STACK will be allocated.
+The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> in
+which case additional certificates will be discarded. B<*ca> can also be a
+valid STACK in which case additional certificates are appended to B<*ca>. If
+B<*ca> is B<NULL> a new STACK will be allocated.
-The B<friendlyName> and B<localKeyID> attributes (if present) on each certificate
-will be stored in the B<alias> and B<keyid> attributes of the B<X509> structure.
+The B<friendlyName> and B<localKeyID> attributes (if present) on each
+certificate will be stored in the B<alias> and B<keyid> attributes of the
+B<X509> structure.
+
+=head1 RETURN VALUES
+
+PKCS12_parse() returns 1 for success and zero if an error occurred.
+
+The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
=head1 BUGS
-Only a single private key and corresponding certificate is returned by this function.
-More complex PKCS#12 files with multiple private keys will only return the first
-match.
+Only a single private key and corresponding certificate is returned by this
+function. More complex PKCS#12 files with multiple private keys will only
+return the first match.
-Only B<friendlyName> and B<localKeyID> attributes are currently stored in certificates.
-Other attributes are discarded.
+Only B<friendlyName> and B<localKeyID> attributes are currently stored in
+certificates. Other attributes are discarded.
-Attributes currently cannot be store in the private key B<EVP_PKEY> structure.
+Attributes currently cannot be stored in the private key B<EVP_PKEY> structure.
=head1 SEE ALSO
diff --git a/crypto/openssl/doc/crypto/bn_internal.pod b/crypto/openssl/doc/crypto/bn_internal.pod
index 8919146..d39ce90 100644
--- a/crypto/openssl/doc/crypto/bn_internal.pod
+++ b/crypto/openssl/doc/crypto/bn_internal.pod
@@ -70,24 +70,34 @@ applications.
=head2 The BIGNUM structure
- typedef struct bignum_st
+ typedef struct bignum_st BIGNUM;
+
+ struct bignum_st
{
- int top; /* number of words used in d */
- BN_ULONG *d; /* pointer to an array containing the integer value */
- int max; /* size of the d array */
- int neg; /* sign */
- } BIGNUM;
+ BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
+ int top; /* Index of last used d +1. */
+ /* The next are internal book keeping for bn_expand. */
+ int dmax; /* Size of the d array. */
+ int neg; /* one if the number is negative */
+ int flags;
+ };
+
The integer value is stored in B<d>, a malloc()ed array of words (B<BN_ULONG>),
least significant word first. A B<BN_ULONG> can be either 16, 32 or 64 bits
in size, depending on the 'number of bits' (B<BITS2>) specified in
C<openssl/bn.h>.
-B<max> is the size of the B<d> array that has been allocated. B<top>
+B<dmax> is the size of the B<d> array that has been allocated. B<top>
is the number of words being used, so for a value of 4, bn.d[0]=4 and
bn.top=1. B<neg> is 1 if the number is negative. When a B<BIGNUM> is
B<0>, the B<d> field can be B<NULL> and B<top> == B<0>.
+B<flags> is a bit field of flags which are defined in C<openssl/bn.h>. The
+flags begin with B<BN_FLG_>. The macros BN_set_flags(b,n) and
+BN_get_flags(b,n) exist to enable or fetch flag(s) B<n> from B<BIGNUM>
+structure B<b>.
+
Various routines in this library require the use of temporary
B<BIGNUM> variables during their execution. Since dynamic memory
allocation to create B<BIGNUM>s is rather expensive when used in
@@ -207,12 +217,12 @@ significant non-zero word plus one when B<a> has shrunk.
=head2 Debugging
bn_check_top() verifies that C<((a)-E<gt>top E<gt>= 0 && (a)-E<gt>top
-E<lt>= (a)-E<gt>max)>. A violation will cause the program to abort.
+E<lt>= (a)-E<gt>dmax)>. A violation will cause the program to abort.
bn_print() prints B<a> to stderr. bn_dump() prints B<n> words at B<d>
(in reverse order, i.e. most significant word first) to stderr.
-bn_set_max() makes B<a> a static number with a B<max> of its current size.
+bn_set_max() makes B<a> a static number with a B<dmax> of its current size.
This is used by bn_set_low() and bn_set_high() to make B<r> a read-only
B<BIGNUM> that contains the B<n> low or high words of B<a>.
diff --git a/crypto/openssl/doc/crypto/d2i_X509.pod b/crypto/openssl/doc/crypto/d2i_X509.pod
index 5bfa18a..298ec54 100644
--- a/crypto/openssl/doc/crypto/d2i_X509.pod
+++ b/crypto/openssl/doc/crypto/d2i_X509.pod
@@ -15,8 +15,8 @@ i2d_X509_fp - X509 encode and decode functions
X509 *d2i_X509_bio(BIO *bp, X509 **x);
X509 *d2i_X509_fp(FILE *fp, X509 **x);
- int i2d_X509_bio(X509 *x, BIO *bp);
- int i2d_X509_fp(X509 *x, FILE *fp);
+ int i2d_X509_bio(BIO *bp, X509 *x);
+ int i2d_X509_fp(FILE *fp, X509 *x);
=head1 DESCRIPTION
@@ -212,11 +212,11 @@ d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
or B<NULL> if an error occurs. The error code that can be obtained by
L<ERR_get_error(3)|ERR_get_error(3)>.
-i2d_X509(), i2d_X509_bio() and i2d_X509_fp() return a the number of bytes
-successfully encoded or a negative value if an error occurs. The error code
-can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+i2d_X509() returns the number of bytes successfully encoded or a negative
+value if an error occurs. The error code can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>.
-i2d_X509_bio() and i2d_X509_fp() returns 1 for success and 0 if an error
+i2d_X509_bio() and i2d_X509_fp() return 1 for success and 0 if an error
occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
=head1 SEE ALSO
diff --git a/crypto/openssl/doc/crypto/d2i_X509_CRL.pod b/crypto/openssl/doc/crypto/d2i_X509_CRL.pod
index e7295a5..224f9e0 100644
--- a/crypto/openssl/doc/crypto/d2i_X509_CRL.pod
+++ b/crypto/openssl/doc/crypto/d2i_X509_CRL.pod
@@ -15,8 +15,8 @@ i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions.
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x);
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x);
- int i2d_X509_CRL_bio(X509_CRL *x, BIO *bp);
- int i2d_X509_CRL_fp(X509_CRL *x, FILE *fp);
+ int i2d_X509_CRL_bio(BIO *bp, X509_CRL *x);
+ int i2d_X509_CRL_fp(FILE *fp, X509_CRL *x);
=head1 DESCRIPTION
diff --git a/crypto/openssl/doc/crypto/d2i_X509_REQ.pod b/crypto/openssl/doc/crypto/d2i_X509_REQ.pod
index ae32a38..91c0c19 100644
--- a/crypto/openssl/doc/crypto/d2i_X509_REQ.pod
+++ b/crypto/openssl/doc/crypto/d2i_X509_REQ.pod
@@ -15,8 +15,8 @@ i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions.
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x);
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x);
- int i2d_X509_REQ_bio(X509_REQ *x, BIO *bp);
- int i2d_X509_REQ_fp(X509_REQ *x, FILE *fp);
+ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *x);
+ int i2d_X509_REQ_fp(FILE *fp, X509_REQ *x);
=head1 DESCRIPTION
diff --git a/crypto/openssl/doc/crypto/hmac.pod b/crypto/openssl/doc/crypto/hmac.pod
index 0bd79a6..484e349 100644
--- a/crypto/openssl/doc/crypto/hmac.pod
+++ b/crypto/openssl/doc/crypto/hmac.pod
@@ -41,8 +41,6 @@ If B<md> is NULL, the digest is placed in a static array. The size of
the output is placed in B<md_len>, unless it is B<NULL>.
B<evp_md> can be EVP_sha1(), EVP_ripemd160() etc.
-B<key> and B<evp_md> may be B<NULL> if a key and hash function have
-been set in a previous call to HMAC_Init() for that B<HMAC_CTX>.
HMAC_CTX_init() initialises a B<HMAC_CTX> before first use. It must be
called.
diff --git a/crypto/openssl/doc/crypto/pem.pod b/crypto/openssl/doc/crypto/pem.pod
index 4f9a27d..d5b1896 100644
--- a/crypto/openssl/doc/crypto/pem.pod
+++ b/crypto/openssl/doc/crypto/pem.pod
@@ -2,7 +2,7 @@
=head1 NAME
-PEM - PEM routines
+PEM, PEM_read_bio_PrivateKey, PEM_read_PrivateKey, PEM_write_bio_PrivateKey, PEM_write_PrivateKey, PEM_write_bio_PKCS8PrivateKey, PEM_write_PKCS8PrivateKey, PEM_write_bio_PKCS8PrivateKey_nid, PEM_write_PKCS8PrivateKey_nid, PEM_read_bio_PUBKEY, PEM_read_PUBKEY, PEM_write_bio_PUBKEY, PEM_write_PUBKEY, PEM_read_bio_RSAPrivateKey, PEM_read_RSAPrivateKey, PEM_write_bio_RSAPrivateKey, PEM_write_RSAPrivateKey, PEM_read_bio_RSAPublicKey, PEM_read_RSAPublicKey, PEM_write_bio_RSAPublicKey, PEM_write_RSAPublicKey, PEM_read_bio_RSA_PUBKEY, PEM_read_RSA_PUBKEY, PEM_write_bio_RSA_PUBKEY, PEM_write_RSA_PUBKEY, PEM_read_bio_DSAPrivateKey, PEM_read_DSAPrivateKey, PEM_write_bio_DSAPrivateKey, PEM_write_DSAPrivateKey, PEM_read_bio_DSA_PUBKEY, PEM_read_DSA_PUBKEY, PEM_write_bio_DSA_PUBKEY, PEM_write_DSA_PUBKEY, PEM_read_bio_DSAparams, PEM_read_DSAparams, PEM_write_bio_DSAparams, PEM_write_DSAparams, PEM_read_bio_DHparams, PEM_read_DHparams, PEM_write_bio_DHparams, PEM_write_DHparams, PEM_read_bio_X509, PEM_read_X509, PEM_write_bio_X509, PEM_write_X509, PEM_read_bio_X509_AUX, PEM_read_X509_AUX, PEM_write_bio_X509_AUX, PEM_write_X509_AUX, PEM_read_bio_X509_REQ, PEM_read_X509_REQ, PEM_write_bio_X509_REQ, PEM_write_X509_REQ, PEM_write_bio_X509_REQ_NEW, PEM_write_X509_REQ_NEW, PEM_read_bio_X509_CRL, PEM_read_X509_CRL, PEM_write_bio_X509_CRL, PEM_write_X509_CRL, PEM_read_bio_PKCS7, PEM_read_PKCS7, PEM_write_bio_PKCS7, PEM_write_PKCS7, PEM_read_bio_NETSCAPE_CERT_SEQUENCE, PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE, PEM_write_NETSCAPE_CERT_SEQUENCE - PEM routines
=head1 SYNOPSIS
diff --git a/crypto/openssl/doc/ssl/SSL_CIPHER_get_name.pod b/crypto/openssl/doc/ssl/SSL_CIPHER_get_name.pod
index f62a869..eb772b5 100644
--- a/crypto/openssl/doc/ssl/SSL_CIPHER_get_name.pod
+++ b/crypto/openssl/doc/ssl/SSL_CIPHER_get_name.pod
@@ -11,7 +11,7 @@ SSL_CIPHER_get_name, SSL_CIPHER_get_bits, SSL_CIPHER_get_version, SSL_CIPHER_des
const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *alg_bits);
char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
- char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int size);
+ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int size);
=head1 DESCRIPTION
diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
index eaed190..06025d1 100644
--- a/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
+++ b/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
@@ -2,7 +2,7 @@
=head1 NAME
-SSL_CTX_set_options, SSL_set_options, SSL_CTX_get_options, SSL_get_options - manipulate SSL engine options
+SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options, SSL_clear_options, SSL_CTX_get_options, SSL_get_options, SSL_get_secure_renegotiation_support - manipulate SSL options
=head1 SYNOPSIS
@@ -11,26 +11,41 @@ SSL_CTX_set_options, SSL_set_options, SSL_CTX_get_options, SSL_get_options - man
long SSL_CTX_set_options(SSL_CTX *ctx, long options);
long SSL_set_options(SSL *ssl, long options);
+ long SSL_CTX_clear_options(SSL_CTX *ctx, long options);
+ long SSL_clear_options(SSL *ssl, long options);
+
long SSL_CTX_get_options(SSL_CTX *ctx);
long SSL_get_options(SSL *ssl);
+ long SSL_get_secure_renegotiation_support(SSL *ssl);
+
=head1 DESCRIPTION
+Note: all these functions are implemented using macros.
+
SSL_CTX_set_options() adds the options set via bitmask in B<options> to B<ctx>.
Options already set before are not cleared!
SSL_set_options() adds the options set via bitmask in B<options> to B<ssl>.
Options already set before are not cleared!
+SSL_CTX_clear_options() clears the options set via bitmask in B<options>
+to B<ctx>.
+
+SSL_clear_options() clears the options set via bitmask in B<options> to B<ssl>.
+
SSL_CTX_get_options() returns the options set for B<ctx>.
SSL_get_options() returns the options set for B<ssl>.
+SSL_get_secure_renegotiation_support() indicates whether the peer supports
+secure renegotiation.
+
=head1 NOTES
The behaviour of the SSL library can be changed by setting several options.
The options are coded as bitmasks and can be combined by a logical B<or>
-operation (|). Options can only be added but can never be reset.
+operation (|).
SSL_CTX_set_options() and SSL_set_options() affect the (external)
protocol behaviour of the SSL library. The (internal) behaviour of
@@ -199,7 +214,7 @@ Do not use the TLSv1 protocol.
When performing renegotiation as a server, always start a new session
(i.e., session resumption requests are only accepted in the initial
-handshake). This option is not needed for clients.
+handshake). This option is not needed for clients.
=item SSL_OP_NO_TICKET
@@ -210,15 +225,107 @@ is explicitly set when OpenSSL is compiled.
If this option is set this functionality is disabled and tickets will
not be used by clients or servers.
+=item SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+
+Allow legacy insecure renegotiation between OpenSSL and unpatched clients or
+servers. See the B<SECURE RENEGOTIATION> section for more details.
+
+=item SSL_OP_LEGACY_SERVER_CONNECT
+
+Allow legacy insecure renegotiation between OpenSSL and unpatched servers
+B<only>: this option is currently set by default. See the
+B<SECURE RENEGOTIATION> section for more details.
+
=back
+=head1 SECURE RENEGOTIATION
+
+OpenSSL 0.9.8m and later always attempts to use secure renegotiation as
+described in RFC5746. This counters the prefix attack described in
+CVE-2009-3555 and elsewhere.
+
+The deprecated and highly broken SSLv2 protocol does not support
+renegotiation at all: its use is B<strongly> discouraged.
+
+This attack has far reaching consequences which application writers should be
+aware of. In the description below an implementation supporting secure
+renegotiation is referred to as I<patched>. A server not supporting secure
+renegotiation is referred to as I<unpatched>.
+
+The following sections describe the operations permitted by OpenSSL's secure
+renegotiation implementation.
+
+=head2 Patched client and server
+
+Connections and renegotiation are always permitted by OpenSSL implementations.
+
+=head2 Unpatched client and patched OpenSSL server
+
+The initial connection suceeds but client renegotiation is denied by the
+server with a B<no_renegotiation> warning alert if TLS v1.0 is used or a fatal
+B<handshake_failure> alert in SSL v3.0.
+
+If the patched OpenSSL server attempts to renegotiate a fatal
+B<handshake_failure> alert is sent. This is because the server code may be
+unaware of the unpatched nature of the client.
+
+If the option B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then
+renegotiation B<always> succeeds.
+
+B<NB:> a bug in OpenSSL clients earlier than 0.9.8m (all of which are
+unpatched) will result in the connection hanging if it receives a
+B<no_renegotiation> alert. OpenSSL versions 0.9.8m and later will regard
+a B<no_renegotiation> alert as fatal and respond with a fatal
+B<handshake_failure> alert. This is because the OpenSSL API currently has
+no provision to indicate to an application that a renegotiation attempt
+was refused.
+
+=head2 Patched OpenSSL client and unpatched server.
+
+If the option B<SSL_OP_LEGACY_SERVER_CONNECT> or
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then initial connections
+and renegotiation between patched OpenSSL clients and unpatched servers
+succeeds. If neither option is set then initial connections to unpatched
+servers will fail.
+
+The option B<SSL_OP_LEGACY_SERVER_CONNECT> is currently set by default even
+though it has security implications: otherwise it would be impossible to
+connect to unpatched servers (i.e. all of them initially) and this is clearly
+not acceptable. Renegotiation is permitted because this does not add any
+additional security issues: during an attack clients do not see any
+renegotiations anyway.
+
+As more servers become patched the option B<SSL_OP_LEGACY_SERVER_CONNECT> will
+B<not> be set by default in a future version of OpenSSL.
+
+OpenSSL client applications wishing to ensure they can connect to unpatched
+servers should always B<set> B<SSL_OP_LEGACY_SERVER_CONNECT>
+
+OpenSSL client applications that want to ensure they can B<not> connect to
+unpatched servers (and thus avoid any security issues) should always B<clear>
+B<SSL_OP_LEGACY_SERVER_CONNECT> using SSL_CTX_clear_options() or
+SSL_clear_options().
+
+The difference between the B<SSL_OP_LEGACY_SERVER_CONNECT> and
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> options is that
+B<SSL_OP_LEGACY_SERVER_CONNECT> enables initial connections and secure
+renegotiation between OpenSSL clients and unpatched servers B<only>, while
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> allows initial connections
+and renegotiation between OpenSSL and unpatched clients or servers.
+
=head1 RETURN VALUES
SSL_CTX_set_options() and SSL_set_options() return the new options bitmask
after adding B<options>.
+SSL_CTX_clear_options() and SSL_clear_options() return the new options bitmask
+after clearing B<options>.
+
SSL_CTX_get_options() and SSL_get_options() return the current bitmask.
+SSL_get_secure_renegotiation_support() returns 1 is the peer supports
+secure renegotiation and 0 if it does not.
+
=head1 SEE ALSO
L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
@@ -241,4 +348,11 @@ Versions up to OpenSSL 0.9.6c do not include the countermeasure that
can be disabled with this option (in OpenSSL 0.9.6d, it was always
enabled).
+SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL
+0.9.8m.
+
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>, B<SSL_OP_LEGACY_SERVER_CONNECT>
+and the function SSL_get_secure_renegotiation_support() were first added in
+OpenSSL 0.9.8m.
+
=cut
diff --git a/crypto/openssl/engines/Makefile b/crypto/openssl/engines/Makefile
index 002d40c..7f13cd9 100644
--- a/crypto/openssl/engines/Makefile
+++ b/crypto/openssl/engines/Makefile
@@ -92,6 +92,7 @@ install:
@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
@if [ -n "$(SHARED_LIBS)" ]; then \
set -e; \
+ $(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines; \
for l in $(LIBNAMES); do \
( echo installing $$l; \
if [ "$(PLATFORM)" != "Cygwin" ]; then \
@@ -100,13 +101,13 @@ install:
*DSO_DL*) sfx="sl";; \
*) sfx="bad";; \
esac; \
- cp lib$$l.$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new; \
+ cp lib$$l.$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/lib$$l.$$sfx.new; \
else \
sfx="so"; \
- cp cyg$$l.dll $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new; \
+ cp cyg$$l.dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/lib$$l.$$sfx.new; \
fi; \
- chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx ); \
+ chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/lib$$l.$$sfx.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/lib$$l.$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/lib$$l.$$sfx ); \
done; \
fi
@@ -197,10 +198,10 @@ e_capi.o: ../include/openssl/evp.h ../include/openssl/fips.h
e_capi.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
e_capi.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
e_capi.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-e_capi.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
-e_capi.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-e_capi.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-e_capi.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_capi.c
+e_capi.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+e_capi.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_capi.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_capi.o: ../include/openssl/x509_vfy.h e_capi.c
e_chil.o: ../include/openssl/asn1.h ../include/openssl/bio.h
e_chil.o: ../include/openssl/bn.h ../include/openssl/buffer.h
e_chil.o: ../include/openssl/crypto.h ../include/openssl/dh.h
diff --git a/crypto/openssl/engines/axp.opt b/crypto/openssl/engines/alpha.opt
index 1dc71bf..1dc71bf 100644
--- a/crypto/openssl/engines/axp.opt
+++ b/crypto/openssl/engines/alpha.opt
diff --git a/crypto/openssl/engines/e_capi.c b/crypto/openssl/engines/e_capi.c
index e98946c..59b2ab7 100644
--- a/crypto/openssl/engines/e_capi.c
+++ b/crypto/openssl/engines/e_capi.c
@@ -56,12 +56,12 @@
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
-#include <openssl/rsa.h>
#include <openssl/bn.h>
#ifdef OPENSSL_SYS_WIN32
#ifndef OPENSSL_NO_CAPIENG
+#include <openssl/rsa.h>
#include <windows.h>
@@ -83,6 +83,10 @@
#define CERT_STORE_CREATE_NEW_FLAG 0x00002000
#endif
+#ifndef CERT_SYSTEM_STORE_CURRENT_USER
+#define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000
+#endif
+
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
@@ -152,21 +156,21 @@ struct CAPI_CTX_st {
char *debug_file;
/* Parameters to use for container lookup */
DWORD keytype;
- LPTSTR cspname;
+ LPSTR cspname;
DWORD csptype;
/* Certificate store name to use */
- LPTSTR storename;
- LPTSTR ssl_client_store;
+ LPSTR storename;
+ LPSTR ssl_client_store;
/* System store flags */
DWORD store_flags;
/* Lookup string meanings in load_private_key */
/* Substring of subject: uses "storename" */
-#define CAPI_LU_SUBSTR 0
+#define CAPI_LU_SUBSTR 1
/* Friendly name: uses storename */
-#define CAPI_LU_FNAME 1
+#define CAPI_LU_FNAME 2
/* Container name: uses cspname, keytype */
-#define CAPI_LU_CONTNAME 2
+#define CAPI_LU_CONTNAME 3
int lookup_method;
/* Info to dump with dumpcerts option */
/* Issuer and serial name strings */
@@ -442,7 +446,7 @@ static int capi_init(ENGINE *e)
#ifdef OPENSSL_CAPIENG_DIALOG
{
HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
- HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
+ HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
if (cryptui)
ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
if (kernel)
@@ -823,7 +827,7 @@ int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
/* Finally sign it */
slen = RSA_size(rsa);
- if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
+ if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
{
CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
capi_addlasterror();
@@ -961,7 +965,7 @@ static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
/* Finally sign it */
slen = sizeof(csigbuf);
- if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
+ if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
{
CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
capi_addlasterror();
@@ -1036,15 +1040,29 @@ static void capi_adderror(DWORD err)
static char *wide_to_asc(LPWSTR wstr)
{
char *str;
+ int len_0,sz;
+
if (!wstr)
return NULL;
- str = OPENSSL_malloc(wcslen(wstr) + 1);
+ len_0 = (int)wcslen(wstr)+1; /* WideCharToMultiByte expects int */
+ sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL);
+ if (!sz)
+ {
+ CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+ return NULL;
+ }
+ str = OPENSSL_malloc(sz);
if (!str)
{
CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
return NULL;
}
- sprintf(str, "%S", wstr);
+ if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL))
+ {
+ OPENSSL_free(str);
+ CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+ return NULL;
+ }
return str;
}
@@ -1053,7 +1071,7 @@ static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD id
LPSTR name;
DWORD len, err;
CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
- if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len))
+ if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len))
{
err = GetLastError();
if (err == ERROR_NO_MORE_ITEMS)
@@ -1063,7 +1081,7 @@ static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD id
return 0;
}
name = OPENSSL_malloc(len);
- if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len))
+ if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len))
{
err = GetLastError();
if (err == ERROR_NO_MORE_ITEMS)
@@ -1082,7 +1100,7 @@ static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
{
DWORD idx, ptype;
int ret;
- LPTSTR provname = NULL;
+ LPSTR provname = NULL;
CAPI_trace(ctx, "capi_list_providers\n");
BIO_printf(out, "Available CSPs:\n");
for(idx = 0; ; idx++)
@@ -1105,7 +1123,7 @@ static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
DWORD err, idx, flags, buflen = 0, clen;
LPSTR cname;
CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
- if (!CryptAcquireContext(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
+ if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
{
CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
capi_addlasterror();
@@ -1385,7 +1403,7 @@ static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provnam
key = OPENSSL_malloc(sizeof(CAPI_KEY));
CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
contname, provname, ptype);
- if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, 0))
+ if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
{
CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
capi_addlasterror();
@@ -1523,7 +1541,7 @@ static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int che
if (check)
{
HCRYPTPROV hprov;
- if (!CryptAcquireContext(&hprov, NULL, pname, type,
+ if (!CryptAcquireContextA(&hprov, NULL, pname, type,
CRYPT_VERIFYCONTEXT))
{
CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
diff --git a/crypto/openssl/engines/e_capi_err.c b/crypto/openssl/engines/e_capi_err.c
index 73bbaaa..eaaefb2 100644
--- a/crypto/openssl/engines/e_capi_err.c
+++ b/crypto/openssl/engines/e_capi_err.c
@@ -122,6 +122,7 @@ static ERR_STRING_DATA CAPI_str_reasons[]=
{ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID),"unsupported algorithm nid"},
{ERR_REASON(CAPI_R_UNSUPPORTED_PADDING) ,"unsupported padding"},
{ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM),"unsupported public key algorithm"},
+{ERR_REASON(CAPI_R_WIN32_ERROR) ,"win32 error"},
{0,NULL}
};
diff --git a/crypto/openssl/engines/e_capi_err.h b/crypto/openssl/engines/e_capi_err.h
index efdb751..4c749ec 100644
--- a/crypto/openssl/engines/e_capi_err.h
+++ b/crypto/openssl/engines/e_capi_err.h
@@ -116,6 +116,7 @@ static void ERR_CAPI_error(int function, int reason, char *file, int line);
#define CAPI_R_UNSUPPORTED_ALGORITHM_NID 119
#define CAPI_R_UNSUPPORTED_PADDING 120
#define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 121
+#define CAPI_R_WIN32_ERROR 127
#ifdef __cplusplus
}
diff --git a/crypto/openssl/engines/e_chil.c b/crypto/openssl/engines/e_chil.c
index e184762..3a07076 100644
--- a/crypto/openssl/engines/e_chil.c
+++ b/crypto/openssl/engines/e_chil.c
@@ -1204,6 +1204,11 @@ static int hwcrhk_get_pass(const char *prompt_info,
pem_password_cb *callback = NULL;
void *callback_data = NULL;
UI_METHOD *ui_method = NULL;
+ /* Despite what the documentation says prompt_info can be
+ * an empty string.
+ */
+ if (prompt_info && !*prompt_info)
+ prompt_info = NULL;
if (cactx)
{
@@ -1305,8 +1310,10 @@ static int hwcrhk_insert_card(const char *prompt_info,
{
char answer;
char buf[BUFSIZ];
-
- if (wrong_info)
+ /* Despite what the documentation says wrong_info can be
+ * an empty string.
+ */
+ if (wrong_info && *wrong_info)
BIO_snprintf(buf, sizeof(buf)-1,
"Current card: \"%s\"\n", wrong_info);
ok = UI_dup_info_string(ui, buf);
diff --git a/crypto/openssl/engines/e_ubsec.c b/crypto/openssl/engines/e_ubsec.c
index e8389de..a0f320c 100644
--- a/crypto/openssl/engines/e_ubsec.c
+++ b/crypto/openssl/engines/e_ubsec.c
@@ -934,7 +934,7 @@ static int ubsec_dh_generate_key(DH *dh)
priv_key = BN_new();
if (priv_key == NULL) goto err;
priv_key_len = BN_num_bits(dh->p);
- bn_wexpand(priv_key, dh->p->top);
+ if(bn_wexpand(priv_key, dh->p->top) == NULL) goto err;
do
if (!BN_rand_range(priv_key, dh->p)) goto err;
while (BN_is_zero(priv_key));
@@ -949,7 +949,7 @@ static int ubsec_dh_generate_key(DH *dh)
{
pub_key = BN_new();
pub_key_len = BN_num_bits(dh->p);
- bn_wexpand(pub_key, dh->p->top);
+ if(bn_wexpand(pub_key, dh->p->top) == NULL) goto err;
if(pub_key == NULL) goto err;
}
else
diff --git a/crypto/openssl/engines/ia64.opt b/crypto/openssl/engines/ia64.opt
new file mode 100644
index 0000000..1dc71bf
--- /dev/null
+++ b/crypto/openssl/engines/ia64.opt
@@ -0,0 +1 @@
+SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
diff --git a/crypto/openssl/fips/Makefile b/crypto/openssl/fips/Makefile
index e038be8..546b54b 100644
--- a/crypto/openssl/fips/Makefile
+++ b/crypto/openssl/fips/Makefile
@@ -63,7 +63,7 @@ testapps:
all:
@if [ -z "$(FIPSLIBDIR)" ]; then \
$(MAKE) -e subdirs lib fips_premain_dso$(EXE_EXT); \
- else \
+ else \
$(MAKE) -e lib fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT); \
fi
@@ -109,7 +109,7 @@ fipscanister.o: fips_start.o $(LIBOBJ) $(FIPS_OBJ_LISTS) fips_end.o
HP-UX|OSF1|SunOS) set -x; /usr/ccs/bin/ld -r -o $@ $$objs ;; \
*) set -x; $(CC) $$cflags -r -o $@ $$objs ;; \
esac fi
- ./fips_standalone_sha1 fipscanister.o > fipscanister.o.sha1
+ ./fips_standalone_sha1$(EXE_EXT) fipscanister.o > fipscanister.o.sha1
# If another exception is immediately required, assign approprite
# site-specific ld command to FIPS_SITE_LD environment variable.
@@ -123,7 +123,11 @@ fips_premain_dso$(EXE_EXT): fips_premain.c
$(FIPSLIBDIR)fipscanister.o ../libcrypto.a $(EX_LIBS)
# this is executed only when linking with external fipscanister.o
fips_standalone_sha1$(EXE_EXT): sha/fips_standalone_sha1.c
- $(CC) $(CFLAGS) -DFIPSCANISTER_O -o $@ sha/fips_standalone_sha1.c $(FIPSLIBDIR)fipscanister.o $(EX_LIBS)
+ if [ -z "$(HOSTCC)" ] ; then \
+ $(CC) $(CFLAGS) -DFIPSCANISTER_O -o $@ sha/fips_standalone_sha1.c $(FIPSLIBDIR)fipscanister.o $(EX_LIBS) ; \
+ else \
+ $(HOSTCC) $(HOSTCFLAGS) -o $ $@ -I../include -I../crypto sha/fips_standalone_sha1.c ../crypto/sha/sha1dgst.c ; \
+ fi
subdirs:
@target=all; $(RECURSIVE_MAKE)
@@ -188,8 +192,8 @@ install:
done
cp -p -f $(FIPSLIBDIR)fipscanister.o $(FIPSLIBDIR)fipscanister.o.sha1 \
$(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fips_premain.c.sha1 \
- $(INSTALL_PREFIX)$(INSTALLTOP)/lib/; \
- chmod 0444 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/fips*
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/; \
+ chmod 0444 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/fips*
lint:
@target=lint; $(RECURSIVE_MAKE)
diff --git a/crypto/openssl/fips/aes/fips_aesavs.c b/crypto/openssl/fips/aes/fips_aesavs.c
index 9ce613b..a3c8b40 100644
--- a/crypto/openssl/fips/aes/fips_aesavs.c
+++ b/crypto/openssl/fips/aes/fips_aesavs.c
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
/*-----------------------------------------------*/
-int AESTest(EVP_CIPHER_CTX *ctx,
+static int AESTest(EVP_CIPHER_CTX *ctx,
char *amode, int akeysz, unsigned char *aKey,
unsigned char *iVec,
int dir, /* 0 = decrypt, 1 = encrypt */
@@ -238,7 +238,7 @@ enum XCrypt {XDECRYPT, XENCRYPT};
#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1)
#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8)))
-int do_mct(char *amode,
+static int do_mct(char *amode,
int akeysz, unsigned char *aKey,unsigned char *iVec,
int dir, unsigned char *text, int len,
FILE *rfp)
@@ -546,7 +546,7 @@ int do_mct(char *amode,
# Fri Aug 30 04:07:22 PM
----------------------------*/
-int proc_file(char *rqfile, char *rspfile)
+static int proc_file(char *rqfile, char *rspfile)
{
char afn[256], rfn[256];
FILE *afp = NULL, *rfp = NULL;
@@ -767,7 +767,7 @@ int proc_file(char *rqfile, char *rspfile)
err =1;
break;
}
- if (len >= sizeof(plaintext))
+ if (len >= (int)sizeof(plaintext))
{
printf("Buffer overflow\n");
}
diff --git a/crypto/openssl/fips/des/fips_desmovs.c b/crypto/openssl/fips/des/fips_desmovs.c
index 2d3424c..f96a5ca 100644
--- a/crypto/openssl/fips/des/fips_desmovs.c
+++ b/crypto/openssl/fips/des/fips_desmovs.c
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
#define VERBOSE 0
-int DESTest(EVP_CIPHER_CTX *ctx,
+static int DESTest(EVP_CIPHER_CTX *ctx,
char *amode, int akeysz, unsigned char *aKey,
unsigned char *iVec,
int dir, /* 0 = decrypt, 1 = encrypt */
@@ -110,15 +110,10 @@ int DESTest(EVP_CIPHER_CTX *ctx,
cipher = EVP_des_ede3_cfb64();
else if (strncasecmp(amode, "OFB", 3) == 0)
cipher = EVP_des_ede3_ofb();
-#if 0
- else if(!strcasecmp(amode,"CFB1"))
- {
- ctx->cbits = 1;
- ctx->cmode = EVP_CIPH_CFB_MODE;
- }
-#endif
else if(!strcasecmp(amode,"CFB8"))
cipher = EVP_des_ede3_cfb8();
+ else if(!strcasecmp(amode,"CFB1"))
+ cipher = EVP_des_ede3_cfb1();
else
{
printf("Unknown mode: %s\n", amode);
@@ -127,20 +122,22 @@ int DESTest(EVP_CIPHER_CTX *ctx,
if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
return 0;
+ if(!strcasecmp(amode,"CFB1"))
+ M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
EVP_Cipher(ctx, out, in, len);
return 1;
}
-
-void DebugValue(char *tag, unsigned char *val, int len)
+#if 0
+static void DebugValue(char *tag, unsigned char *val, int len)
{
char obuf[2048];
int olen;
olen = bin2hex(val, len, obuf);
printf("%s = %.*s\n", tag, olen, obuf);
}
-
-void shiftin(unsigned char *dst,unsigned char *src,int nbits)
+#endif
+static void shiftin(unsigned char *dst,unsigned char *src,int nbits)
{
int n;
@@ -160,7 +157,7 @@ char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"};
enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64};
int Sizes[6]={64,64,64,1,8,64};
-void do_mct(char *amode,
+static void do_mct(char *amode,
int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec,
int dir, unsigned char *text, int len,
FILE *rfp)
@@ -200,11 +197,11 @@ void do_mct(char *amode,
if(imode != ECB)
OutputValue("IV",ivec,8,rfp,0);
OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1);
-
+#if 0
/* compensate for endianness */
if(imode == CFB1)
text[0]<<=7;
-
+#endif
memcpy(text0,text,8);
for(j=0 ; j < 10000 ; ++j)
@@ -267,7 +264,7 @@ void do_mct(char *amode,
}
}
-int proc_file(char *rqfile, char *rspfile)
+static int proc_file(char *rqfile, char *rspfile)
{
char afn[256], rfn[256];
FILE *afp = NULL, *rfp = NULL;
@@ -535,7 +532,7 @@ int proc_file(char *rqfile, char *rspfile)
err =1;
break;
}
- if (len >= sizeof(plaintext))
+ if (len >= (int)sizeof(plaintext))
{
printf("Buffer overflow\n");
}
diff --git a/crypto/openssl/fips/dsa/fips_dsa_key.c b/crypto/openssl/fips/dsa/fips_dsa_key.c
index b5f8cfa..9f21033 100644
--- a/crypto/openssl/fips/dsa/fips_dsa_key.c
+++ b/crypto/openssl/fips/dsa/fips_dsa_key.c
@@ -78,7 +78,7 @@ void FIPS_corrupt_dsa_keygen(void)
static int dsa_builtin_keygen(DSA *dsa);
-int fips_check_dsa(DSA *dsa)
+static int fips_check_dsa(DSA *dsa)
{
EVP_PKEY pk;
unsigned char tbs[] = "DSA Pairwise Check Data";
diff --git a/crypto/openssl/fips/dsa/fips_dsa_sign.c b/crypto/openssl/fips/dsa/fips_dsa_sign.c
index 32ea0b0..7a4d51d 100644
--- a/crypto/openssl/fips/dsa/fips_dsa_sign.c
+++ b/crypto/openssl/fips/dsa/fips_dsa_sign.c
@@ -70,6 +70,7 @@
* case of a DSA signature.
*/
+#if 0
int FIPS_dsa_size(DSA *r)
{
int ilen;
@@ -83,6 +84,7 @@ int FIPS_dsa_size(DSA *r)
*/
return ilen * 2 + 6;
}
+#endif
/* Tiny ASN1 encoder for DSA_SIG structure. We can assume r, s smaller than
* 0x80 octets as by the DSA standards they will be less than 2^160
diff --git a/crypto/openssl/fips/dsa/fips_dsatest.c b/crypto/openssl/fips/dsa/fips_dsatest.c
index c7e0f51..1aec089 100644
--- a/crypto/openssl/fips/dsa/fips_dsatest.c
+++ b/crypto/openssl/fips/dsa/fips_dsatest.c
@@ -69,7 +69,6 @@
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/err.h>
-#include <openssl/dsa.h>
#include <openssl/bn.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
@@ -83,6 +82,7 @@ int main(int argc, char *argv[])
return(0);
}
#else
+#include <openssl/dsa.h>
#include <openssl/fips.h>
#include <openssl/fips_rand.h>
#include <openssl/dsa.h>
diff --git a/crypto/openssl/fips/dsa/fips_dssvs.c b/crypto/openssl/fips/dsa/fips_dssvs.c
index aa74e8e..45f4e1c 100644
--- a/crypto/openssl/fips/dsa/fips_dssvs.c
+++ b/crypto/openssl/fips/dsa/fips_dssvs.c
@@ -40,7 +40,7 @@ static void pbn(const char *name, BIGNUM *bn)
return;
}
-void primes()
+static void primes()
{
char buf[10240];
char lbuf[10240];
@@ -63,7 +63,7 @@ void primes()
}
}
-void pqg()
+static void pqg()
{
char buf[1024];
char lbuf[1024];
@@ -112,7 +112,7 @@ void pqg()
}
}
-void pqgver()
+static void pqgver()
{
char buf[1024];
char lbuf[1024];
@@ -131,6 +131,7 @@ void pqgver()
fputs(buf,stdout);
continue;
}
+ fputs(buf, stdout);
if(!strcmp(keyword,"[mod"))
nmod=atoi(value);
else if(!strcmp(keyword,"P"))
@@ -158,12 +159,6 @@ void pqgver()
fprintf(stderr, "Parse Error\n");
exit (1);
}
- pbn("P",p);
- pbn("Q",q);
- pbn("G",g);
- pv("Seed",seed,20);
- printf("c = %d\n",counter);
- printf("H = %lx\n",h);
dsa = FIPS_dsa_new();
if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL))
{
@@ -174,7 +169,7 @@ void pqgver()
|| (counter != counter2) || (h != h2))
printf("Result = F\n");
else
- printf("Result = T\n");
+ printf("Result = P\n");
BN_free(p);
BN_free(q);
BN_free(g);
@@ -217,7 +212,7 @@ static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
return 1;
}
-void keyver()
+static void keyver()
{
char buf[1024];
char lbuf[1024];
@@ -286,7 +281,7 @@ void keyver()
if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
printf("Result = F\n");
else
- printf("Result = T\n");
+ printf("Result = P\n");
}
BN_free(X);
BN_free(Y);
@@ -304,7 +299,7 @@ void keyver()
BN_free(Y2);
}
-void keypair()
+static void keypair()
{
char buf[1024];
char lbuf[1024];
@@ -353,7 +348,7 @@ void keypair()
}
}
-void siggen()
+static void siggen()
{
char buf[1024];
char lbuf[1024];
@@ -426,7 +421,7 @@ void siggen()
FIPS_dsa_free(dsa);
}
-void sigver()
+static void sigver()
{
DSA *dsa=NULL;
char buf[1024];
diff --git a/crypto/openssl/fips/fips_locl.h b/crypto/openssl/fips/fips_locl.h
index 03fed36..b3ea289 100644
--- a/crypto/openssl/fips/fips_locl.h
+++ b/crypto/openssl/fips/fips_locl.h
@@ -64,6 +64,7 @@ int fips_set_owning_thread(void);
void fips_set_selftest_fail(void);
int fips_clear_owning_thread(void);
unsigned char *fips_signature_witness(void);
+int fips_check_rsa(RSA *rsa);
#define FIPS_MAX_CIPHER_TEST_SIZE 16
diff --git a/crypto/openssl/fips/fips_test_suite.c b/crypto/openssl/fips/fips_test_suite.c
index 78a15b7..2bc0ba9 100644
--- a/crypto/openssl/fips/fips_test_suite.c
+++ b/crypto/openssl/fips/fips_test_suite.c
@@ -18,9 +18,6 @@
#include <stdlib.h>
#include <openssl/aes.h>
#include <openssl/des.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-#include <openssl/dh.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
@@ -37,6 +34,10 @@ int main(int argc, char *argv[])
}
#else
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+
#include <openssl/fips.h>
#include "fips_utl.h"
@@ -379,7 +380,8 @@ static int Zeroize()
BIGNUM *bn;
unsigned char userkey[16] =
{ 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
- int i, n;
+ size_t i;
+ int n;
key = FIPS_rsa_new();
bn = BN_new();
@@ -410,13 +412,18 @@ static int Zeroize()
}
static int Error;
-const char * Fail(const char *msg)
+static const char * Fail(const char *msg)
{
do_print_errors();
Error++;
return msg;
}
+static void test_msg(const char *msg, int result)
+ {
+ printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
+ }
+
int main(int argc,char **argv)
{
@@ -487,20 +494,14 @@ int main(int argc,char **argv)
/* Non-Approved cryptographic operation
*/
printf("1. Non-Approved cryptographic operation test...\n");
- printf("\ta. Included algorithm (D-H)...");
- printf( dh_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("\ta. Included algorithm (D-H)...", dh_test());
/* Power-up self test
*/
ERR_clear_error();
- printf("2. Automatic power-up self test...");
- if (!FIPS_mode_set(1))
- {
- do_print_errors();
- printf(Fail("FAILED!\n"));
+ test_msg("2. Automatic power-up self test", FIPS_mode_set(1));
+ if (!FIPS_mode())
exit(1);
- }
- printf("successful\n");
if (do_corrupt_dsa_keygen)
FIPS_corrupt_dsa_keygen();
if (do_corrupt_rsa_keygen)
@@ -510,76 +511,66 @@ int main(int argc,char **argv)
/* AES encryption/decryption
*/
- printf("3. AES encryption/decryption...");
- printf( FIPS_aes_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("3. AES encryption/decryption", FIPS_aes_test());
/* RSA key generation and encryption/decryption
*/
- printf("4. RSA key generation and encryption/decryption...");
- printf( FIPS_rsa_test(bad_rsa) ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("4. RSA key generation and encryption/decryption",
+ FIPS_rsa_test(bad_rsa));
/* DES-CBC encryption/decryption
*/
- printf("5. DES-ECB encryption/decryption...");
- printf( FIPS_des3_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
/* DSA key generation and signature validation
*/
- printf("6. DSA key generation and signature validation...");
- printf( FIPS_dsa_test(bad_dsa) ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("6. DSA key generation and signature validation",
+ FIPS_dsa_test(bad_dsa));
/* SHA-1 hash
*/
- printf("7a. SHA-1 hash...");
- printf( FIPS_sha1_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7a. SHA-1 hash", FIPS_sha1_test());
/* SHA-256 hash
*/
- printf("7b. SHA-256 hash...");
- printf( FIPS_sha256_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7b. SHA-256 hash", FIPS_sha256_test());
/* SHA-512 hash
*/
- printf("7c. SHA-512 hash...");
- printf( FIPS_sha512_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7c. SHA-512 hash", FIPS_sha512_test());
/* HMAC-SHA-1 hash
*/
- printf("7d. HMAC-SHA-1 hash...");
- printf( FIPS_hmac_sha1_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
/* HMAC-SHA-224 hash
*/
- printf("7e. HMAC-SHA-224 hash...");
- printf( FIPS_hmac_sha224_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
/* HMAC-SHA-256 hash
*/
- printf("7f. HMAC-SHA-256 hash...");
- printf( FIPS_hmac_sha256_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
/* HMAC-SHA-384 hash
*/
- printf("7g. HMAC-SHA-384 hash...");
- printf( FIPS_hmac_sha384_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
/* HMAC-SHA-512 hash
*/
- printf("7h. HMAC-SHA-512 hash...");
- printf( FIPS_hmac_sha512_test() ? "successful\n" : Fail("FAILED!\n") );
+ test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
/* Non-Approved cryptographic operation
*/
printf("8. Non-Approved cryptographic operation test...\n");
- printf("\ta. Included algorithm (D-H)...");
- printf( dh_test() ? "successful as expected\n"
- : Fail("failed INCORRECTLY!\n") );
+ printf("\ta. Included algorithm (D-H)...%s\n",
+ dh_test() ? "successful as expected"
+ : Fail("failed INCORRECTLY!") );
/* Zeroization
*/
- printf("9. Zero-ization...\n");
- printf( Zeroize() ? "\tsuccessful as expected\n"
- : Fail("\tfailed INCORRECTLY!\n") );
+ printf("9. Zero-ization...\n\t%s\n",
+ Zeroize() ? "successful as expected"
+ : Fail("failed INCORRECTLY!") );
printf("\nAll tests completed with %d errors\n", Error);
return Error ? 1 : 0;
diff --git a/crypto/openssl/fips/fips_utl.h b/crypto/openssl/fips/fips_utl.h
index 02d4e44..85d9e12 100644
--- a/crypto/openssl/fips/fips_utl.h
+++ b/crypto/openssl/fips/fips_utl.h
@@ -47,6 +47,22 @@
*
*/
+void do_print_errors(void);
+int hex2bin(const char *in, unsigned char *out);
+unsigned char *hex2bin_m(const char *in, long *plen);
+int do_hex2bn(BIGNUM **pr, const char *in);
+int do_bn_print(FILE *out, BIGNUM *bn);
+int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn);
+int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf);
+BIGNUM *hex2bn(const char *in);
+int bin2hex(const unsigned char *in,int len,char *out);
+void pv(const char *tag,const unsigned char *val,int len);
+int tidy_line(char *linebuf, char *olinebuf);
+int bint2bin(const char *in, int len, unsigned char *out);
+int bin2bint(const unsigned char *in,int len,char *out);
+void PrintValue(char *tag, unsigned char *val, int len);
+void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode);
+
void do_print_errors(void)
{
const char *file, *data;
diff --git a/crypto/openssl/fips/fipsalgtest.pl b/crypto/openssl/fips/fipsalgtest.pl
index 44a5cca..851cc98 100755
--- a/crypto/openssl/fips/fipsalgtest.pl
+++ b/crypto/openssl/fips/fipsalgtest.pl
@@ -19,6 +19,12 @@ my @fips_dsa_test_list = (
);
+my @fips_dsa_pqgver_test_list = (
+
+ [ "PQGVer", "fips_dssvs pqgver" ]
+
+);
+
# RSA tests
my @fips_rsa_test_list = (
@@ -304,6 +310,24 @@ my @fips_des3_test_list = (
);
+my @fips_des3_cfb1_test_list = (
+
+ # DES3 CFB1 tests
+
+ [ "TCFB1invperm", "fips_desmovs -f" ],
+ [ "TCFB1MMT1", "fips_desmovs -f" ],
+ [ "TCFB1MMT2", "fips_desmovs -f" ],
+ [ "TCFB1MMT3", "fips_desmovs -f" ],
+ [ "TCFB1Monte1", "fips_desmovs -f" ],
+ [ "TCFB1Monte2", "fips_desmovs -f" ],
+ [ "TCFB1Monte3", "fips_desmovs -f" ],
+ [ "TCFB1permop", "fips_desmovs -f" ],
+ [ "TCFB1subtab", "fips_desmovs -f" ],
+ [ "TCFB1varkey", "fips_desmovs -f" ],
+ [ "TCFB1vartext", "fips_desmovs -f" ],
+
+);
+
# Verification special cases.
# In most cases the output of a test is deterministic and
# it can be compared to a known good result. A few involve
@@ -342,6 +366,7 @@ my $list_tests = 0;
my %fips_enabled = (
dsa => 1,
+ "dsa-pqgver" => 0,
rsa => 1,
"rsa-pss0" => 0,
"rsa-pss62" => 1,
@@ -351,7 +376,8 @@ my %fips_enabled = (
"rand-des2" => 0,
aes => 1,
"aes-cfb1" => 0,
- des3 => 1
+ des3 => 1,
+ "des3-cfb1" => 0
);
foreach (@ARGV) {
@@ -417,6 +443,7 @@ foreach (@ARGV) {
my @fips_test_list;
push @fips_test_list, @fips_dsa_test_list if $fips_enabled{"dsa"};
+push @fips_test_list, @fips_dsa_pqgver_test_list if $fips_enabled{"dsa-pqgver"};
push @fips_test_list, @fips_rsa_test_list if $fips_enabled{"rsa"};
push @fips_test_list, @fips_rsa_pss0_test_list if $fips_enabled{"rsa-pss0"};
push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"};
@@ -427,6 +454,7 @@ push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"};
push @fips_test_list, @fips_aes_test_list if $fips_enabled{"aes"};
push @fips_test_list, @fips_aes_cfb1_test_list if $fips_enabled{"aes-cfb1"};
push @fips_test_list, @fips_des3_test_list if $fips_enabled{"des3"};
+push @fips_test_list, @fips_des3_cfb1_test_list if $fips_enabled{"des3-cfb1"};
if ($list_tests) {
my ( $test, $en );
@@ -525,7 +553,7 @@ $cmd: generate run CMVP algorithm tests
--dir=<dirname> Optional root for *.req file search
--filter=<regexp>
--onedir <dirname> Assume all components in current directory
- --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "resp"
+ --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "rsp"
--shwrap_prefix=<prefix>
--tprefix=<prefix>
--ignore-bogus Ignore duplicate or bogus files
@@ -533,7 +561,16 @@ $cmd: generate run CMVP algorithm tests
--quiet Shhh....
--generate Generate algorithm test output
--win32 Win32 environment
+ --enable-<alg> Enable algorithm set <alg>.
+ --disable-<alg> Disable algorithm set <alg>.
+ Where <alg> can be one of:
EOF
+
+while (my ($key, $value) = each %fips_enabled)
+ {
+ printf "\t\t%-20s(%s by default)\n", $key ,
+ $value ? "enabled" : "disabled";
+ }
}
# Sanity check to see if all necessary executables exist
@@ -720,10 +757,10 @@ sub run_tests {
}
my $cmd = "$cmd_prefix$tprefix$tcmd ";
if ( $tcmd =~ /-f$/ ) {
- $cmd .= "$req $out";
+ $cmd .= "\"$req\" \"$out\"";
}
else {
- $cmd .= "<$req >$out";
+ $cmd .= "<\"$req\" >\"$out\"";
}
print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify );
system($cmd);
@@ -739,7 +776,7 @@ sub run_tests {
$vout =~ s/\.rsp$/.ver/;
$tcmd = $verify_special{$tname};
$cmd = "$cmd_prefix$tprefix$tcmd ";
- $cmd .= "<$out >$vout";
+ $cmd .= "<\"$out\" >\"$vout\"";
system($cmd);
if ( $? != 0 ) {
print STDERR
@@ -806,11 +843,11 @@ sub cmp_file {
return 1;
}
if ( !defined($rspline) ) {
- print STDERR "ERROR: $tname EOF on $rspf\n";
+ print STDERR "ERROR: $tname EOF on $rsp\n";
return 0;
}
if ( !defined($tstline) ) {
- print STDERR "ERROR: $tname EOF on $tstf\n";
+ print STDERR "ERROR: $tname EOF on $tst\n";
return 0;
}
@@ -821,7 +858,7 @@ sub cmp_file {
if ( $tstline ne $rspline ) {
print STDERR "ERROR: $tname mismatch:\n";
- print STDERR "\t $tstline != $rspline\n";
+ print STDERR "\t \"$tstline\" != \"$rspline\"\n";
return 0;
}
}
@@ -842,6 +879,8 @@ sub next_line {
# Translate multiple space into one
s/\s+/ /g;
+ # Delete trailing whitespace
+ s/\s+$//;
return $_;
}
return undef;
diff --git a/crypto/openssl/fips/fipsld b/crypto/openssl/fips/fipsld
index c71d4d9..8c26c85 100755
--- a/crypto/openssl/fips/fipsld
+++ b/crypto/openssl/fips/fipsld
@@ -117,7 +117,11 @@ lib*|*.dll) # must be linking a shared lib...
${_WL_PREMAIN} "$@"
# generate signature...
- SIG=`"${THERE}/fips/fips_premain_dso" "${TARGET}"`
+ if [ -z "${FIPS_SIG}" ]; then
+ SIG=`"${THERE}/fips/fips_premain_dso" "${TARGET}"`
+ else
+ SIG=`"${FIPS_SIG}" -dso "${TARGET}"`
+ fi
/bin/rm -f "${TARGET}"
if [ -z "${SIG}" ]; then
echo "unable to collect signature"; exit 1
@@ -156,7 +160,11 @@ lib*|*.dll) # must be linking a shared lib...
${_WL_PREMAIN} "$@"
# generate signature...
- SIG=`"${TARGET}"`
+ if [ -z "${FIPS_SIG}" ]; then
+ SIG=`"${TARGET}"`
+ else
+ SIG=`"${FIPS_SIG}" -exe "${TARGET}"`
+ fi
/bin/rm -f "${TARGET}"
if [ -z "${SIG}" ]; then
echo "unable to collect signature"; exit 1
diff --git a/crypto/openssl/fips/hmac/fips_hmac.c b/crypto/openssl/fips/hmac/fips_hmac.c
index 7c49c98..69a10da 100644
--- a/crypto/openssl/fips/hmac/fips_hmac.c
+++ b/crypto/openssl/fips/hmac/fips_hmac.c
@@ -88,7 +88,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
reset=1;
j=M_EVP_MD_block_size(md);
- OPENSSL_assert(j <= sizeof ctx->key);
+ OPENSSL_assert(j <= (int)sizeof ctx->key);
if (j < len)
{
EVP_DigestInit_ex(&ctx->md_ctx,md, impl);
@@ -98,7 +98,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
}
else
{
- OPENSSL_assert(len <= sizeof ctx->key);
+ OPENSSL_assert(len <= (int)sizeof ctx->key);
memcpy(ctx->key,key,len);
ctx->key_length=len;
}
diff --git a/crypto/openssl/fips/hmac/fips_hmac_selftest.c b/crypto/openssl/fips/hmac/fips_hmac_selftest.c
index a697770..73455ff 100644
--- a/crypto/openssl/fips/hmac/fips_hmac_selftest.c
+++ b/crypto/openssl/fips/hmac/fips_hmac_selftest.c
@@ -111,7 +111,7 @@ static const HMAC_KAT vector[] = {
int FIPS_selftest_hmac()
{
- int n;
+ size_t n;
unsigned int outlen;
unsigned char out[EVP_MAX_MD_SIZE];
const EVP_MD *md;
diff --git a/crypto/openssl/fips/rand/fips_rand.c b/crypto/openssl/fips/rand/fips_rand.c
index 58453e9..9492b15 100644
--- a/crypto/openssl/fips/rand/fips_rand.c
+++ b/crypto/openssl/fips/rand/fips_rand.c
@@ -114,7 +114,7 @@ void FIPS_rng_stick(void)
fips_prng_fail = 1;
}
-void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
+static void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
{
ctx->seeded = 0;
ctx->keyed = 0;
@@ -192,7 +192,7 @@ static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx,
return 1;
}
-int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
+static int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
{
if (ctx->keyed)
{
diff --git a/crypto/openssl/fips/rand/fips_rngvs.c b/crypto/openssl/fips/rand/fips_rngvs.c
index cb904ea..80a8017 100644
--- a/crypto/openssl/fips/rand/fips_rngvs.c
+++ b/crypto/openssl/fips/rand/fips_rngvs.c
@@ -31,7 +31,7 @@ int main(int argc, char **argv)
#include "fips_utl.h"
-void vst()
+static void vst()
{
unsigned char *key = NULL;
unsigned char *v = NULL;
@@ -108,7 +108,7 @@ void vst()
}
}
-void mct()
+static void mct()
{
unsigned char *key = NULL;
unsigned char *v = NULL;
diff --git a/crypto/openssl/fips/rsa/fips_rsagtest.c b/crypto/openssl/fips/rsa/fips_rsagtest.c
index 33a3d7a..657e1b6 100644
--- a/crypto/openssl/fips/rsa/fips_rsagtest.c
+++ b/crypto/openssl/fips/rsa/fips_rsagtest.c
@@ -63,7 +63,6 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
-#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
@@ -77,6 +76,7 @@ int main(int argc, char *argv[])
#else
+#include <openssl/rsa.h>
#include "fips_utl.h"
int rsa_test(FILE *out, FILE *in);
diff --git a/crypto/openssl/fips/rsa/fips_rsastest.c b/crypto/openssl/fips/rsa/fips_rsastest.c
index 16c174a..452084f 100644
--- a/crypto/openssl/fips/rsa/fips_rsastest.c
+++ b/crypto/openssl/fips/rsa/fips_rsastest.c
@@ -63,7 +63,6 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
-#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
@@ -77,6 +76,7 @@ int main(int argc, char *argv[])
#else
+#include <openssl/rsa.h>
#include "fips_utl.h"
static int rsa_stest(FILE *out, FILE *in, int Saltlen);
diff --git a/crypto/openssl/fips/rsa/fips_rsavtest.c b/crypto/openssl/fips/rsa/fips_rsavtest.c
index 6340f19..aadab27 100644
--- a/crypto/openssl/fips/rsa/fips_rsavtest.c
+++ b/crypto/openssl/fips/rsa/fips_rsavtest.c
@@ -65,7 +65,6 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include <openssl/bn.h>
-#include <openssl/rsa.h>
#ifndef OPENSSL_FIPS
@@ -77,6 +76,8 @@ int main(int argc, char *argv[])
#else
+#include <openssl/rsa.h>
+
#include "fips_utl.h"
int rsa_test(FILE *out, FILE *in, int saltlen);
diff --git a/crypto/openssl/fips/sha/Makefile b/crypto/openssl/fips/sha/Makefile
index a661640..0f8cca9 100644
--- a/crypto/openssl/fips/sha/Makefile
+++ b/crypto/openssl/fips/sha/Makefile
@@ -46,8 +46,12 @@ lib: $(LIBOBJ)
@echo $(LIBOBJ) > lib
../fips_standalone_sha1$(EXE_EXT): fips_standalone_sha1.o
+ if [ -z "$(HOSTCC)" ] ; then \
FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha1dgst.o ; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../../crypto/sha/$$i" ; done; \
- $(CC) -o $@ $(CFLAGS) fips_standalone_sha1.o $$FIPS_SHA_ASM
+ $(CC) -o $@ $(CFLAGS) fips_standalone_sha1.o $$FIPS_SHA_ASM ; \
+ else \
+ $(HOSTCC) $(HOSTCFLAGS) -o $ $@ -I../../include -I../../crypto fips_standalone_sha1.c ../../crypto/sha/sha1dgst.c ; \
+ fi
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
diff --git a/crypto/openssl/fips/sha/fips_sha1_selftest.c b/crypto/openssl/fips/sha/fips_sha1_selftest.c
index ba6a29e..4c0d463 100644
--- a/crypto/openssl/fips/sha/fips_sha1_selftest.c
+++ b/crypto/openssl/fips/sha/fips_sha1_selftest.c
@@ -78,7 +78,7 @@ void FIPS_corrupt_sha1()
int FIPS_selftest_sha1()
{
- int n;
+ size_t n;
for(n=0 ; n<sizeof(test)/sizeof(test[0]) ; ++n)
{
diff --git a/crypto/openssl/openssl.spec b/crypto/openssl/openssl.spec
index 329e392..19a002f 100644
--- a/crypto/openssl/openssl.spec
+++ b/crypto/openssl/openssl.spec
@@ -1,7 +1,8 @@
+%define _unpackaged_files_terminate_build 0
%define libmaj 0
%define libmin 9
%define librel 8
-%define librev k
+%define librev n
Release: 1
%define openssldir /var/ssl
@@ -96,6 +97,9 @@ perl util/perlpath.pl /usr/bin/perl
%ifarch alpha
./Configure %{CONFIG_FLAGS} linux-alpha shared
%endif
+%ifarch x86_64
+./Configure %{CONFIG_FLAGS} linux-x86_64 shared
+%endif
LD_LIBRARY_PATH=`pwd` make
LD_LIBRARY_PATH=`pwd` make rehash
LD_LIBRARY_PATH=`pwd` make test
diff --git a/crypto/openssl/ssl/Makefile b/crypto/openssl/ssl/Makefile
index 46c0659..5ac3507 100644
--- a/crypto/openssl/ssl/Makefile
+++ b/crypto/openssl/ssl/Makefile
@@ -30,7 +30,7 @@ LIBSRC= \
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
ssl_ciph.c ssl_stat.c ssl_rsa.c \
ssl_asn1.c ssl_txt.c ssl_algs.c \
- bio_ssl.c ssl_err.c kssl.c
+ bio_ssl.c ssl_err.c kssl.c t1_reneg.c
LIBOBJ= \
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
@@ -41,7 +41,7 @@ LIBOBJ= \
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
ssl_ciph.o ssl_stat.o ssl_rsa.o \
ssl_asn1.o ssl_txt.o ssl_algs.o \
- bio_ssl.o ssl_err.o kssl.o
+ bio_ssl.o ssl_err.o kssl.o t1_reneg.o
SRC= $(LIBSRC)
@@ -994,6 +994,27 @@ t1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
t1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
t1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
t1_meth.o: t1_meth.c
+t1_reneg.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_reneg.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+t1_reneg.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+t1_reneg.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+t1_reneg.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+t1_reneg.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+t1_reneg.o: ../include/openssl/err.h ../include/openssl/evp.h
+t1_reneg.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+t1_reneg.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_reneg.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+t1_reneg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_reneg.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_reneg.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_reneg.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+t1_reneg.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_reneg.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_reneg.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_reneg.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_reneg.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_reneg.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_reneg.o: t1_reneg.c
t1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
t1_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
t1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c
index 0177192..0a5c08d 100644
--- a/crypto/openssl/ssl/d1_both.c
+++ b/crypto/openssl/ssl/d1_both.c
@@ -136,7 +136,6 @@ static unsigned char *dtls1_write_message_header(SSL *s,
static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
unsigned long len, unsigned short seq_num, unsigned long frag_off,
unsigned long frag_len);
-static int dtls1_retransmit_buffered_messages(SSL *s);
static long dtls1_get_message_fragment(SSL *s, int st1, int stn,
long max, int *ok);
@@ -178,7 +177,7 @@ int dtls1_do_write(SSL *s, int type)
{
int ret;
int curr_mtu;
- unsigned int len, frag_off;
+ unsigned int len, frag_off, mac_size, blocksize;
/* AHA! Figure out the MTU, and stick to the right size */
if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
@@ -226,11 +225,22 @@ int dtls1_do_write(SSL *s, int type)
OPENSSL_assert(s->init_num ==
(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
+ if (s->write_hash)
+ mac_size = EVP_MD_size(s->write_hash);
+ else
+ mac_size = 0;
+
+ if (s->enc_write_ctx &&
+ (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE))
+ blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
+ else
+ blocksize = 0;
+
frag_off = 0;
while( s->init_num)
{
curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
- DTLS1_RT_HEADER_LENGTH;
+ DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
{
@@ -238,7 +248,8 @@ int dtls1_do_write(SSL *s, int type)
ret = BIO_flush(SSL_get_wbio(s));
if ( ret <= 0)
return ret;
- curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH;
+ curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
+ mac_size - blocksize;
}
if ( s->init_num > curr_mtu)
@@ -280,7 +291,7 @@ int dtls1_do_write(SSL *s, int type)
* retransmit
*/
if ( BIO_ctrl(SSL_get_wbio(s),
- BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL))
+ BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
else
@@ -569,9 +580,13 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
pq_64bit_free(&seq64);
/* Discard the message if sequence number was already there, is
- * too far in the future or the fragment is already in the queue */
+ * too far in the future, already in the queue or if we received
+ * a FINISHED before the SERVER_HELLO, which then must be a stale
+ * retransmit.
+ */
if (msg_hdr->seq <= s->d1->handshake_read_seq ||
- msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL)
+ msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
+ (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED))
{
unsigned char devnull [256];
@@ -750,6 +765,24 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
p+=i;
l=i;
+ /* Copy the finished so we can use it for
+ * renegotiation checks
+ */
+ if(s->type == SSL_ST_CONNECT)
+ {
+ OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+ memcpy(s->s3->previous_client_finished,
+ s->s3->tmp.finish_md, i);
+ s->s3->previous_client_finished_len=i;
+ }
+ else
+ {
+ OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+ memcpy(s->s3->previous_server_finished,
+ s->s3->tmp.finish_md, i);
+ s->s3->previous_server_finished_len=i;
+ }
+
#ifdef OPENSSL_SYS_WIN16
/* MSVC 1.5 does not clear the top bytes of the word unless
* I do this.
@@ -812,14 +845,30 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
}
+static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
+ {
+ int n;
+ unsigned char *p;
+
+ n=i2d_X509(x,NULL);
+ if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+ {
+ SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+ return 0;
+ }
+ p=(unsigned char *)&(buf->data[*l]);
+ l2n3(n,p);
+ i2d_X509(x,&p);
+ *l+=n+3;
+
+ return 1;
+ }
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
{
unsigned char *p;
- int n,i;
+ int i;
unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
BUF_MEM *buf;
- X509_STORE_CTX xs_ctx;
- X509_OBJECT obj;
/* TLSv1 sends a chain with nothing in it, instead of an alert */
buf=s->init_buf;
@@ -830,54 +879,33 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
}
if (x != NULL)
{
- if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
- {
- SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
- return(0);
- }
-
- for (;;)
- {
- n=i2d_X509(x,NULL);
- if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
- {
- SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
- return(0);
- }
- p=(unsigned char *)&(buf->data[l]);
- l2n3(n,p);
- i2d_X509(x,&p);
- l+=n+3;
- if (X509_NAME_cmp(X509_get_subject_name(x),
- X509_get_issuer_name(x)) == 0) break;
-
- i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
- X509_get_issuer_name(x),&obj);
- if (i <= 0) break;
- x=obj.data.x509;
- /* Count is one too high since the X509_STORE_get uped the
- * ref count */
- X509_free(x);
- }
-
- X509_STORE_CTX_cleanup(&xs_ctx);
- }
-
+ X509_STORE_CTX xs_ctx;
+
+ if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
+ {
+ SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
+ return(0);
+ }
+
+ X509_verify_cert(&xs_ctx);
+ for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
+ {
+ x = sk_X509_value(xs_ctx.chain, i);
+
+ if (!dtls1_add_cert_to_buf(buf, &l, x))
+ {
+ X509_STORE_CTX_cleanup(&xs_ctx);
+ return 0;
+ }
+ }
+ X509_STORE_CTX_cleanup(&xs_ctx);
+ }
/* Thawte special :-) */
- if (s->ctx->extra_certs != NULL)
for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
{
x=sk_X509_value(s->ctx->extra_certs,i);
- n=i2d_X509(x,NULL);
- if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
- {
- SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
- return(0);
- }
- p=(unsigned char *)&(buf->data[l]);
- l2n3(n,p);
- i2d_X509(x,&p);
- l+=n+3;
+ if (!dtls1_add_cert_to_buf(buf, &l, x))
+ return 0;
}
l-= (3 + DTLS1_HM_HEADER_LENGTH);
@@ -894,18 +922,13 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
int dtls1_read_failed(SSL *s, int code)
{
- DTLS1_STATE *state;
- BIO *bio;
- int send_alert = 0;
-
if ( code > 0)
{
fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
return 1;
}
- bio = SSL_get_rbio(s);
- if ( ! BIO_dgram_recv_timedout(bio))
+ if (!dtls1_is_timer_expired(s))
{
/* not a timeout, none of our business,
let higher layers handle this. in fact it's probably an error */
@@ -918,23 +941,6 @@ int dtls1_read_failed(SSL *s, int code)
return code;
}
- state = s->d1;
- state->timeout.num_alerts++;
- if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
- {
- /* fail the connection, enough alerts have been sent */
- SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED);
- return 0;
- }
-
- state->timeout.read_timeouts++;
- if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
- {
- send_alert = 1;
- state->timeout.read_timeouts = 1;
- }
-
-
#if 0 /* for now, each alert contains only one record number */
item = pqueue_peek(state->rcvd_records);
if ( item )
@@ -945,16 +951,29 @@ int dtls1_read_failed(SSL *s, int code)
#endif
#if 0 /* no more alert sending, just retransmit the last set of messages */
- if ( send_alert)
- ssl3_send_alert(s,SSL3_AL_WARNING,
- DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+ if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
+ ssl3_send_alert(s,SSL3_AL_WARNING,
+ DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
#endif
- return dtls1_retransmit_buffered_messages(s) ;
+ return dtls1_handle_timeout(s);
}
+int
+dtls1_get_queue_priority(unsigned short seq, int is_ccs)
+ {
+ /* The index of the retransmission queue actually is the message sequence number,
+ * since the queue only contains messages of a single handshake. However, the
+ * ChangeCipherSpec has no message sequence number and so using only the sequence
+ * will result in the CCS and Finished having the same index. To prevent this,
+ * the sequence number is multiplied by 2. In case of a CCS 1 is subtracted.
+ * This does not only differ CSS and Finished, it also maintains the order of the
+ * index (important for priority queues) and fits in the unsigned short variable.
+ */
+ return seq * 2 - is_ccs;
+ }
-static int
+int
dtls1_retransmit_buffered_messages(SSL *s)
{
pqueue sent = s->d1->sent_messages;
@@ -968,8 +987,9 @@ dtls1_retransmit_buffered_messages(SSL *s)
for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
{
frag = (hm_fragment *)item->data;
- if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 &&
- found)
+ if ( dtls1_retransmit_message(s,
+ (unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs),
+ 0, &found) <= 0 && found)
{
fprintf(stderr, "dtls1_retransmit_message() failed\n");
return -1;
@@ -985,7 +1005,6 @@ dtls1_buffer_message(SSL *s, int is_ccs)
pitem *item;
hm_fragment *frag;
PQ_64BIT seq64;
- unsigned int epoch = s->d1->w_epoch;
/* this function is called immediately after a message has
* been serialized */
@@ -999,7 +1018,6 @@ dtls1_buffer_message(SSL *s, int is_ccs)
{
OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
- epoch++;
}
else
{
@@ -1014,9 +1032,19 @@ dtls1_buffer_message(SSL *s, int is_ccs)
frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
frag->msg_header.is_ccs = is_ccs;
+ /* save current state*/
+ frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
+ frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
+ frag->msg_header.saved_retransmit_state.compress = s->compress;
+ frag->msg_header.saved_retransmit_state.session = s->session;
+ frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
+
pq_64bit_init(&seq64);
- pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq);
+ pq_64bit_assign_word(&seq64,
+ dtls1_get_queue_priority(frag->msg_header.seq,
+ frag->msg_header.is_ccs));
+
item = pitem_new(seq64, frag);
pq_64bit_free(&seq64);
if ( item == NULL)
@@ -1045,6 +1073,8 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
hm_fragment *frag ;
unsigned long header_length;
PQ_64BIT seq64;
+ struct dtls1_retransmit_state saved_state;
+ unsigned char save_write_sequence[8];
/*
OPENSSL_assert(s->init_num == 0);
@@ -1080,9 +1110,45 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
frag->msg_header.msg_len, frag->msg_header.seq, 0,
frag->msg_header.frag_len);
+ /* save current state */
+ saved_state.enc_write_ctx = s->enc_write_ctx;
+ saved_state.write_hash = s->write_hash;
+ saved_state.compress = s->compress;
+ saved_state.session = s->session;
+ saved_state.epoch = s->d1->w_epoch;
+ saved_state.epoch = s->d1->w_epoch;
+
s->d1->retransmitting = 1;
+
+ /* restore state in which the message was originally sent */
+ s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
+ s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
+ s->compress = frag->msg_header.saved_retransmit_state.compress;
+ s->session = frag->msg_header.saved_retransmit_state.session;
+ s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
+
+ if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
+ {
+ memcpy(save_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
+ memcpy(s->s3->write_sequence, s->d1->last_write_sequence, sizeof(s->s3->write_sequence));
+ }
+
ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
- SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
+ SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
+
+ /* restore current state */
+ s->enc_write_ctx = saved_state.enc_write_ctx;
+ s->write_hash = saved_state.write_hash;
+ s->compress = saved_state.compress;
+ s->session = saved_state.session;
+ s->d1->w_epoch = saved_state.epoch;
+
+ if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
+ {
+ memcpy(s->d1->last_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
+ memcpy(s->s3->write_sequence, save_write_sequence, sizeof(s->s3->write_sequence));
+ }
+
s->d1->retransmitting = 0;
(void)BIO_flush(SSL_get_wbio(s));
diff --git a/crypto/openssl/ssl/d1_clnt.c b/crypto/openssl/ssl/d1_clnt.c
index 49c6760..223d116 100644
--- a/crypto/openssl/ssl/d1_clnt.c
+++ b/crypto/openssl/ssl/d1_clnt.c
@@ -130,7 +130,7 @@ static int dtls1_get_hello_verify(SSL *s);
static SSL_METHOD *dtls1_get_client_method(int ver)
{
- if (ver == DTLS1_VERSION)
+ if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
return(DTLSv1_client_method());
else
return(NULL);
@@ -145,7 +145,6 @@ int dtls1_connect(SSL *s)
{
BUF_MEM *buf=NULL;
unsigned long Time=(unsigned long)time(NULL),l;
- long num1;
void (*cb)(const SSL *ssl,int type,int val)=NULL;
int ret= -1;
int new_state,state,skip=0;;
@@ -181,7 +180,8 @@ int dtls1_connect(SSL *s)
s->server=0;
if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
- if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00))
+ if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00) &&
+ (s->version & 0xff00 ) != (DTLS1_BAD_VER & 0xff00))
{
SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
ret = -1;
@@ -219,6 +219,8 @@ int dtls1_connect(SSL *s)
s->init_num=0;
/* mark client_random uninitialized */
memset(s->s3->client_random,0,sizeof(s->s3->client_random));
+ s->d1->send_cookie = 0;
+ s->hit = 0;
break;
case SSL3_ST_CW_CLNT_HELLO_A:
@@ -229,6 +231,7 @@ int dtls1_connect(SSL *s)
/* every DTLS ClientHello resets Finished MAC */
ssl3_init_finished_mac(s);
+ dtls1_start_timer(s);
ret=dtls1_client_hello(s);
if (ret <= 0) goto end;
@@ -254,6 +257,7 @@ int dtls1_connect(SSL *s)
if (ret <= 0) goto end;
else
{
+ dtls1_stop_timer(s);
if (s->hit)
s->state=SSL3_ST_CR_FINISHED_A;
else
@@ -268,6 +272,7 @@ int dtls1_connect(SSL *s)
ret = dtls1_get_hello_verify(s);
if ( ret <= 0)
goto end;
+ dtls1_stop_timer(s);
if ( s->d1->send_cookie) /* start again, with a cookie */
s->state=SSL3_ST_CW_CLNT_HELLO_A;
else
@@ -277,15 +282,43 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
+#ifndef OPENSSL_NO_TLSEXT
+ ret=ssl3_check_finished(s);
+ if (ret <= 0) goto end;
+ if (ret == 2)
+ {
+ s->hit = 1;
+ if (s->tlsext_ticket_expected)
+ s->state=SSL3_ST_CR_SESSION_TICKET_A;
+ else
+ s->state=SSL3_ST_CR_FINISHED_A;
+ s->init_num=0;
+ break;
+ }
+#endif
/* Check if it is anon DH */
if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
{
ret=ssl3_get_server_certificate(s);
if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s->tlsext_status_expected)
+ s->state=SSL3_ST_CR_CERT_STATUS_A;
+ else
+ s->state=SSL3_ST_CR_KEY_EXCH_A;
+ }
+ else
+ {
+ skip = 1;
+ s->state=SSL3_ST_CR_KEY_EXCH_A;
+ }
+#else
}
else
skip=1;
+
s->state=SSL3_ST_CR_KEY_EXCH_A;
+#endif
s->init_num=0;
break;
@@ -329,6 +362,7 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CW_CERT_B:
case SSL3_ST_CW_CERT_C:
case SSL3_ST_CW_CERT_D:
+ dtls1_start_timer(s);
ret=dtls1_send_client_certificate(s);
if (ret <= 0) goto end;
s->state=SSL3_ST_CW_KEY_EXCH_A;
@@ -337,6 +371,7 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CW_KEY_EXCH_A:
case SSL3_ST_CW_KEY_EXCH_B:
+ dtls1_start_timer(s);
ret=dtls1_send_client_key_exchange(s);
if (ret <= 0) goto end;
l=s->s3->tmp.new_cipher->algorithms;
@@ -359,6 +394,7 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CW_CERT_VRFY_A:
case SSL3_ST_CW_CERT_VRFY_B:
+ dtls1_start_timer(s);
ret=dtls1_send_client_verify(s);
if (ret <= 0) goto end;
s->state=SSL3_ST_CW_CHANGE_A;
@@ -368,6 +404,7 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_CW_CHANGE_B:
+ dtls1_start_timer(s);
ret=dtls1_send_change_cipher_spec(s,
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
if (ret <= 0) goto end;
@@ -402,6 +439,7 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
+ dtls1_start_timer(s);
ret=dtls1_send_finished(s,
SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
s->method->ssl3_enc->client_finished_label,
@@ -423,20 +461,44 @@ int dtls1_connect(SSL *s)
}
else
{
+#ifndef OPENSSL_NO_TLSEXT
+ /* Allow NewSessionTicket if ticket expected */
+ if (s->tlsext_ticket_expected)
+ s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
+ else
+#endif
+
s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
}
s->init_num=0;
- /* mark client_random uninitialized */
- memset (s->s3->client_random,0,sizeof(s->s3->client_random));
break;
+#ifndef OPENSSL_NO_TLSEXT
+ case SSL3_ST_CR_SESSION_TICKET_A:
+ case SSL3_ST_CR_SESSION_TICKET_B:
+ ret=ssl3_get_new_session_ticket(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_CR_FINISHED_A;
+ s->init_num=0;
+ break;
+
+ case SSL3_ST_CR_CERT_STATUS_A:
+ case SSL3_ST_CR_CERT_STATUS_B:
+ ret=ssl3_get_cert_status(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_CR_KEY_EXCH_A;
+ s->init_num=0;
+ break;
+#endif
+
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
-
+ s->d1->change_cipher_spec_ok = 1;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
if (ret <= 0) goto end;
+ dtls1_stop_timer(s);
if (s->hit)
s->state=SSL3_ST_CW_CHANGE_A;
@@ -446,16 +508,13 @@ int dtls1_connect(SSL *s)
break;
case SSL3_ST_CW_FLUSH:
- /* number of bytes to be flushed */
- num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
- if (num1 > 0)
+ s->rwstate=SSL_WRITING;
+ if (BIO_flush(s->wbio) <= 0)
{
- s->rwstate=SSL_WRITING;
- num1=BIO_flush(s->wbio);
- if (num1 <= 0) { ret= -1; goto end; }
- s->rwstate=SSL_NOTHING;
+ ret= -1;
+ goto end;
}
-
+ s->rwstate=SSL_NOTHING;
s->state=s->s3->tmp.next_state;
break;
@@ -492,6 +551,7 @@ int dtls1_connect(SSL *s)
/* done with handshaking */
s->d1->handshake_read_seq = 0;
+ s->d1->next_handshake_write_seq = 0;
goto end;
/* break; */
@@ -541,8 +601,14 @@ int dtls1_client_hello(SSL *s)
buf=(unsigned char *)s->init_buf->data;
if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
{
+ SSL_SESSION *sess = s->session;
if ((s->session == NULL) ||
(s->session->ssl_version != s->version) ||
+#ifdef OPENSSL_NO_TLSEXT
+ !sess->session_id_length ||
+#else
+ (!sess->session_id_length && !sess->tlsext_tick) ||
+#endif
(s->session->not_resumable))
{
if (!ssl_get_new_session(s,0))
@@ -621,7 +687,15 @@ int dtls1_client_hello(SSL *s)
*(p++)=comp->id;
}
*(p++)=0; /* Add the NULL method */
-
+
+#ifndef OPENSSL_NO_TLSEXT
+ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+ {
+ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+#endif
+
l=(p-d);
d=buf;
diff --git a/crypto/openssl/ssl/d1_enc.c b/crypto/openssl/ssl/d1_enc.c
index cf3332e..3dfa5ad 100644
--- a/crypto/openssl/ssl/d1_enc.c
+++ b/crypto/openssl/ssl/d1_enc.c
@@ -151,7 +151,7 @@ int dtls1_enc(SSL *s, int send)
__FILE__, __LINE__);
else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
{
- if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)))
+ if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
return -1;
}
}
diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c
index 3568e97..63bfbac 100644
--- a/crypto/openssl/ssl/d1_lib.c
+++ b/crypto/openssl/ssl/d1_lib.c
@@ -58,10 +58,17 @@
*/
#include <stdio.h>
+#define USE_SOCKETS
#include <openssl/objects.h>
#include "ssl_locl.h"
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
+#include <sys/timeb.h>
+#endif
+
+static void get_current_time(struct timeval *t);
const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
+int dtls1_listen(SSL *s, struct sockaddr *client);
SSL3_ENC_METHOD DTLSv1_enc_data={
dtls1_enc,
@@ -114,6 +121,7 @@ int dtls1_new(SSL *s)
d1->processed_rcds.q=pqueue_new();
d1->buffered_messages = pqueue_new();
d1->sent_messages=pqueue_new();
+ d1->buffered_app_data.q=pqueue_new();
if ( s->server)
{
@@ -121,12 +129,13 @@ int dtls1_new(SSL *s)
}
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
- || ! d1->buffered_messages || ! d1->sent_messages)
+ || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
{
if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
if ( d1->sent_messages) pqueue_free(d1->sent_messages);
+ if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
OPENSSL_free(d1);
return (0);
}
@@ -175,6 +184,15 @@ void dtls1_free(SSL *s)
}
pqueue_free(s->d1->sent_messages);
+ while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
+ {
+ frag = (hm_fragment *)item->data;
+ OPENSSL_free(frag->fragment);
+ OPENSSL_free(frag);
+ pitem_free(item);
+ }
+ pqueue_free(s->d1->buffered_app_data.q);
+
pq_64bit_free(&(s->d1->bitmap.map));
pq_64bit_free(&(s->d1->bitmap.max_seq_num));
@@ -187,7 +205,36 @@ void dtls1_free(SSL *s)
void dtls1_clear(SSL *s)
{
ssl3_clear(s);
- s->version=DTLS1_VERSION;
+ if (s->options & SSL_OP_CISCO_ANYCONNECT)
+ s->version=DTLS1_BAD_VER;
+ else
+ s->version=DTLS1_VERSION;
+ }
+
+long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
+ {
+ int ret=0;
+
+ switch (cmd)
+ {
+ case DTLS_CTRL_GET_TIMEOUT:
+ if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
+ {
+ ret = 1;
+ }
+ break;
+ case DTLS_CTRL_HANDLE_TIMEOUT:
+ ret = dtls1_handle_timeout(s);
+ break;
+ case DTLS_CTRL_LISTEN:
+ ret = dtls1_listen(s, parg);
+ break;
+
+ default:
+ ret = ssl3_ctrl(s, cmd, larg, parg);
+ break;
+ }
+ return(ret);
}
/*
@@ -209,3 +256,151 @@ SSL_CIPHER *dtls1_get_cipher(unsigned int u)
return ciph;
}
+
+void dtls1_start_timer(SSL *s)
+ {
+ /* If timer is not set, initialize duration with 1 second */
+ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
+ {
+ s->d1->timeout_duration = 1;
+ }
+
+ /* Set timeout to current time */
+ get_current_time(&(s->d1->next_timeout));
+
+ /* Add duration to current time */
+ s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
+ }
+
+struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
+ {
+ struct timeval timenow;
+
+ /* If no timeout is set, just return NULL */
+ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
+ {
+ return NULL;
+ }
+
+ /* Get current time */
+ get_current_time(&timenow);
+
+ /* If timer already expired, set remaining time to 0 */
+ if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
+ (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
+ s->d1->next_timeout.tv_usec <= timenow.tv_usec))
+ {
+ memset(timeleft, 0, sizeof(struct timeval));
+ return timeleft;
+ }
+
+ /* Calculate time left until timer expires */
+ memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
+ timeleft->tv_sec -= timenow.tv_sec;
+ timeleft->tv_usec -= timenow.tv_usec;
+ if (timeleft->tv_usec < 0)
+ {
+ timeleft->tv_sec--;
+ timeleft->tv_usec += 1000000;
+ }
+
+ return timeleft;
+ }
+
+int dtls1_is_timer_expired(SSL *s)
+ {
+ struct timeval timeleft;
+
+ /* Get time left until timeout, return false if no timer running */
+ if (dtls1_get_timeout(s, &timeleft) == NULL)
+ {
+ return 0;
+ }
+
+ /* Return false if timer is not expired yet */
+ if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
+ {
+ return 0;
+ }
+
+ /* Timer expired, so return true */
+ return 1;
+ }
+
+void dtls1_double_timeout(SSL *s)
+ {
+ s->d1->timeout_duration *= 2;
+ if (s->d1->timeout_duration > 60)
+ s->d1->timeout_duration = 60;
+ dtls1_start_timer(s);
+ }
+
+void dtls1_stop_timer(SSL *s)
+ {
+ /* Reset everything */
+ memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
+ s->d1->timeout_duration = 1;
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
+ }
+
+int dtls1_handle_timeout(SSL *s)
+ {
+ DTLS1_STATE *state;
+
+ /* if no timer is expired, don't do anything */
+ if (!dtls1_is_timer_expired(s))
+ {
+ return 0;
+ }
+
+ dtls1_double_timeout(s);
+ state = s->d1;
+ state->timeout.num_alerts++;
+ if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
+ {
+ /* fail the connection, enough alerts have been sent */
+ SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
+ return 0;
+ }
+
+ state->timeout.read_timeouts++;
+ if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+ {
+ state->timeout.read_timeouts = 1;
+ }
+
+ dtls1_start_timer(s);
+ return dtls1_retransmit_buffered_messages(s);
+ }
+
+static void get_current_time(struct timeval *t)
+{
+#ifdef OPENSSL_SYS_WIN32
+ struct _timeb tb;
+ _ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#elif defined(OPENSSL_SYS_VMS)
+ struct timeb tb;
+ ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#else
+ gettimeofday(t, NULL);
+#endif
+}
+
+int dtls1_listen(SSL *s, struct sockaddr *client)
+ {
+ int ret;
+
+ SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
+ s->d1->listen = 1;
+
+ ret = SSL_accept(s);
+ if (ret <= 0) return ret;
+
+ (void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
+ return 1;
+ }
diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c
index 4ae9be5..ca2d73f 100644
--- a/crypto/openssl/ssl/d1_pkt.c
+++ b/crypto/openssl/ssl/d1_pkt.c
@@ -134,7 +134,7 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
unsigned short *priority, unsigned long *offset);
#endif
static int dtls1_buffer_record(SSL *s, record_pqueue *q,
- PQ_64BIT priority);
+ PQ_64BIT *priority);
static int dtls1_process_record(SSL *s);
#if PQ_64BIT_IS_INTEGER
static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
@@ -162,7 +162,7 @@ dtls1_copy_record(SSL *s, pitem *item)
static int
-dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority)
+dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority)
{
DTLS1_RECORD_DATA *rdata;
pitem *item;
@@ -172,7 +172,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority)
return 0;
rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
- item = pitem_new(priority, rdata);
+ item = pitem_new(*priority, rdata);
if (rdata == NULL || item == NULL)
{
if (rdata != NULL) OPENSSL_free(rdata);
@@ -267,7 +267,7 @@ dtls1_process_buffered_records(SSL *s)
if ( ! dtls1_process_record(s))
return(0);
dtls1_buffer_record(s, &(s->d1->processed_rcds),
- s->s3->rrec.seq_num);
+ &s->s3->rrec.seq_num);
}
}
@@ -486,11 +486,11 @@ err:
/* used only by dtls1_read_bytes */
int dtls1_get_record(SSL *s)
{
- int ssl_major,ssl_minor,al;
+ int ssl_major,ssl_minor;
int i,n;
SSL3_RECORD *rr;
SSL_SESSION *sess;
- unsigned char *p;
+ unsigned char *p = NULL;
unsigned short version;
DTLS1_BITMAP *bitmap;
unsigned int is_next_epoch;
@@ -517,7 +517,12 @@ again:
/* read timeout is handled by dtls1_read_bytes */
if (n <= 0) return(n); /* error or non-blocking */
- OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH);
+ /* this packet contained a partial record, dump it */
+ if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
+ {
+ s->packet_length = 0;
+ goto again;
+ }
s->rstate=SSL_ST_READ_BODY;
@@ -542,27 +547,28 @@ again:
{
if (version != s->version && version != DTLS1_BAD_VER)
{
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
- /* Send back error using their
- * version number :-) */
- s->version=version;
- al=SSL_AD_PROTOCOL_VERSION;
- goto f_err;
+ /* unexpected version, silently discard */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
}
}
if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
(version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
{
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
- goto err;
+ /* wrong version, silently discard record */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
}
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
{
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
- goto f_err;
+ /* record too long, silently discard it */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
}
s->client_version = version;
@@ -581,6 +587,7 @@ again:
/* this packet contained a partial record, dump it */
if ( n != i)
{
+ rr->length = 0;
s->packet_length = 0;
goto again;
}
@@ -594,12 +601,20 @@ again:
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
if ( bitmap == NULL)
{
+ rr->length = 0;
s->packet_length = 0; /* dump this record */
goto again; /* get another record */
}
- /* check whether this is a repeat, or aged record */
- if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
+ /* Check whether this is a repeat, or aged record.
+ * Don't check if we're listening and this message is
+ * a ClientHello. They can look as if they're replayed,
+ * since they arrive from different connections and
+ * would be dropped unnecessarily.
+ */
+ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+ *p == SSL3_MT_CLIENT_HELLO) &&
+ ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
{
rr->length = 0;
s->packet_length=0; /* dump this record */
@@ -616,7 +631,8 @@ again:
if (is_next_epoch)
{
dtls1_record_bitmap_update(s, bitmap);
- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+ dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num);
+ rr->length = 0;
s->packet_length = 0;
goto again;
}
@@ -627,10 +643,6 @@ again:
dtls1_clear_timeouts(s); /* done waiting */
return(1);
-f_err:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
-err:
- return(0);
}
/* Return up to 'len' payload bytes received in 'type' records.
@@ -707,6 +719,27 @@ start:
* s->s3->rrec.length, - number of bytes. */
rr = &(s->s3->rrec);
+ /* We are not handshaking and have no data yet,
+ * so process data buffered during the last handshake
+ * in advance, if any.
+ */
+ if (s->state == SSL_ST_OK && rr->length == 0)
+ {
+ pitem *item;
+ item = pqueue_pop(s->d1->buffered_app_data.q);
+ if (item)
+ {
+ dtls1_copy_record(s, item);
+
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+ }
+
+ /* Check for timeout */
+ if (dtls1_handle_timeout(s) > 0)
+ goto start;
+
/* get new packet if necessary */
if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
{
@@ -728,9 +761,14 @@ start:
* reset by ssl3_get_finished */
&& (rr->type != SSL3_RT_HANDSHAKE))
{
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
- goto err;
+ /* We now have application data between CCS and Finished.
+ * Most likely the packets were reordered on their way, so
+ * buffer the application data for later processing rather
+ * than dropping the connection.
+ */
+ dtls1_buffer_record(s, &(s->d1->buffered_app_data), 0);
+ rr->length = 0;
+ goto start;
}
/* If the other end has shut down, throw anything we read away
@@ -800,15 +838,28 @@ start:
dest = s->d1->alert_fragment;
dest_len = &s->d1->alert_fragment_len;
}
- /* else it's a CCS message, or it's wrong */
- else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
- {
- /* Not certain if this is the right error handling */
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
- goto f_err;
- }
+ /* else it's a CCS message, or application data or wrong */
+ else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
+ {
+ /* Application data while renegotiating
+ * is allowed. Try again reading.
+ */
+ if (rr->type == SSL3_RT_APPLICATION_DATA)
+ {
+ BIO *bio;
+ s->s3->in_read_app_data=2;
+ bio=SSL_get_rbio(s);
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return(-1);
+ }
+ /* Not certain if this is the right error handling */
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
if (dest_maxlen > 0)
{
@@ -946,7 +997,9 @@ start:
n2s(p, seq);
n2l3(p, frag_off);
- dtls1_retransmit_message(s, seq, frag_off, &found);
+ dtls1_retransmit_message(s,
+ dtls1_get_queue_priority(frag->msg_header.seq, 0),
+ frag_off, &found);
if ( ! found && SSL_in_init(s))
{
/* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
@@ -991,15 +1044,17 @@ start:
if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
{
struct ccs_header_st ccs_hdr;
+ unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
dtls1_get_ccs_header(rr->data, &ccs_hdr);
/* 'Change Cipher Spec' is just a single byte, so we know
* exactly what the record payload has to look like */
/* XDTLS: check that epoch is consistent */
- if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) ||
- (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) ||
- (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
+ if (s->client_version == DTLS1_BAD_VER || s->version == DTLS1_BAD_VER)
+ ccs_hdr_len = 3;
+
+ if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
{
i=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
@@ -1012,6 +1067,16 @@ start:
s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
rr->data, 1, s, s->msg_callback_arg);
+ /* We can't process a CCS now, because previous handshake
+ * messages are still missing, so just drop it.
+ */
+ if (!s->d1->change_cipher_spec_ok)
+ {
+ goto start;
+ }
+
+ s->d1->change_cipher_spec_ok = 0;
+
s->s3->change_cipher_spec=1;
if (!ssl3_do_change_cipher_spec(s))
goto err;
@@ -1039,6 +1104,16 @@ start:
goto start;
}
+ /* If we are server, we may have a repeated FINISHED of the
+ * client here, then retransmit our CCS and FINISHED.
+ */
+ if (msg_hdr.type == SSL3_MT_FINISHED)
+ {
+ dtls1_retransmit_buffered_messages(s);
+ rr->length = 0;
+ goto start;
+ }
+
if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
{
@@ -1145,7 +1220,6 @@ err:
int
dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
{
- unsigned int n,tot;
int i;
if (SSL_in_init(s) && !s->in_handshake)
@@ -1159,31 +1233,14 @@ dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
}
}
- tot = s->s3->wnum;
- n = len - tot;
-
- while( n)
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH)
{
- /* dtls1_write_bytes sends one record at a time, sized according to
- * the currently known MTU */
- i = dtls1_write_bytes(s, type, buf_, len);
- if (i <= 0) return i;
-
- if ((i == (int)n) ||
- (type == SSL3_RT_APPLICATION_DATA &&
- (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
- {
- /* next chunk of data should get another prepended empty fragment
- * in ciphersuites with known-IV weakness: */
- s->s3->empty_fragment_done = 0;
- return tot+i;
- }
-
- tot += i;
- n-=i;
+ SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG);
+ return -1;
}
- return tot;
+ i = dtls1_write_bytes(s, type, buf_, len);
+ return i;
}
@@ -1224,46 +1281,13 @@ have_handshake_fragment(SSL *s, int type, unsigned char *buf,
/* Call this to write data in records of type 'type'
* It will return <= 0 if not all data has been sent or non-blocking IO.
*/
-int dtls1_write_bytes(SSL *s, int type, const void *buf_, int len)
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
{
- const unsigned char *buf=buf_;
- unsigned int tot,n,nw;
int i;
- unsigned int mtu;
+ OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
s->rwstate=SSL_NOTHING;
- tot=s->s3->wnum;
-
- n=(len-tot);
-
- /* handshake layer figures out MTU for itself, but data records
- * are also sent through this interface, so need to figure out MTU */
-#if 0
- mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_MTU, 0, NULL);
- mtu += DTLS1_HM_HEADER_LENGTH; /* HM already inserted */
-#endif
- mtu = s->d1->mtu;
-
- if (mtu > SSL3_RT_MAX_PLAIN_LENGTH)
- mtu = SSL3_RT_MAX_PLAIN_LENGTH;
-
- if (n > mtu)
- nw=mtu;
- else
- nw=n;
-
- i=do_dtls1_write(s, type, &(buf[tot]), nw, 0);
- if (i <= 0)
- {
- s->s3->wnum=tot;
- return i;
- }
-
- if ( (int)s->s3->wnum + i == len)
- s->s3->wnum = 0;
- else
- s->s3->wnum += i;
-
+ i=do_dtls1_write(s, type, buf, len, 0);
return i;
}
@@ -1315,7 +1339,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
#if 0
/* 'create_empty_fragment' is true only when this function calls itself */
if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
- && SSL_version(s) != DTLS1_VERSION)
+ && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
{
/* countermeasure against known-IV weakness in CBC ciphersuites
* (see http://www.openssl.org/~bodo/tls-cbc.txt)
@@ -1762,6 +1786,7 @@ dtls1_reset_seq_numbers(SSL *s, int rw)
else
{
seq = s->s3->write_sequence;
+ memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
s->d1->w_epoch++;
}
diff --git a/crypto/openssl/ssl/d1_srvr.c b/crypto/openssl/ssl/d1_srvr.c
index 0bbf8ae..5b31366 100644
--- a/crypto/openssl/ssl/d1_srvr.c
+++ b/crypto/openssl/ssl/d1_srvr.c
@@ -146,7 +146,6 @@ int dtls1_accept(SSL *s)
BUF_MEM *buf;
unsigned long l,Time=(unsigned long)time(NULL);
void (*cb)(const SSL *ssl,int type,int val)=NULL;
- long num1;
int ret= -1;
int new_state,state,skip=0;
@@ -236,17 +235,13 @@ int dtls1_accept(SSL *s)
s->state=SSL3_ST_SW_HELLO_REQ_A;
}
- if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
- s->d1->send_cookie = 1;
- else
- s->d1->send_cookie = 0;
-
break;
case SSL3_ST_SW_HELLO_REQ_A:
case SSL3_ST_SW_HELLO_REQ_B:
s->shutdown=0;
+ dtls1_start_timer(s);
ret=dtls1_send_hello_request(s);
if (ret <= 0) goto end;
s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
@@ -267,22 +262,31 @@ int dtls1_accept(SSL *s)
s->shutdown=0;
ret=ssl3_get_client_hello(s);
if (ret <= 0) goto end;
- s->new_session = 2;
+ dtls1_stop_timer(s);
- if ( s->d1->send_cookie)
+ if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
else
s->state = SSL3_ST_SW_SRVR_HELLO_A;
s->init_num=0;
+
+ /* If we're just listening, stop here */
+ if (s->d1->listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
+ {
+ ret = 2;
+ s->d1->listen = 0;
+ goto end;
+ }
+
break;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
+ dtls1_start_timer(s);
ret = dtls1_send_hello_verify_request(s);
if ( ret <= 0) goto end;
- s->d1->send_cookie = 0;
s->state=SSL3_ST_SW_FLUSH;
s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
@@ -293,11 +297,23 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_SRVR_HELLO_A:
case SSL3_ST_SW_SRVR_HELLO_B:
+ s->new_session = 2;
+ dtls1_start_timer(s);
ret=dtls1_send_server_hello(s);
if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
if (s->hit)
- s->state=SSL3_ST_SW_CHANGE_A;
+ {
+ if (s->tlsext_ticket_expected)
+ s->state=SSL3_ST_SW_SESSION_TICKET_A;
+ else
+ s->state=SSL3_ST_SW_CHANGE_A;
+ }
+#else
+ if (s->hit)
+ s->state=SSL3_ST_SW_CHANGE_A;
+#endif
else
s->state=SSL3_ST_SW_CERT_A;
s->init_num=0;
@@ -308,12 +324,27 @@ int dtls1_accept(SSL *s)
/* Check if it is anon DH */
if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
{
+ dtls1_start_timer(s);
ret=dtls1_send_server_certificate(s);
if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s->tlsext_status_expected)
+ s->state=SSL3_ST_SW_CERT_STATUS_A;
+ else
+ s->state=SSL3_ST_SW_KEY_EXCH_A;
+ }
+ else
+ {
+ skip = 1;
+ s->state=SSL3_ST_SW_KEY_EXCH_A;
+ }
+#else
}
else
skip=1;
+
s->state=SSL3_ST_SW_KEY_EXCH_A;
+#endif
s->init_num=0;
break;
@@ -349,6 +380,7 @@ int dtls1_accept(SSL *s)
)
)
{
+ dtls1_start_timer(s);
ret=dtls1_send_server_key_exchange(s);
if (ret <= 0) goto end;
}
@@ -385,6 +417,7 @@ int dtls1_accept(SSL *s)
else
{
s->s3->tmp.cert_request=1;
+ dtls1_start_timer(s);
ret=dtls1_send_certificate_request(s);
if (ret <= 0) goto end;
#ifndef NETSCAPE_HANG_BUG
@@ -399,6 +432,7 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_SRVR_DONE_A:
case SSL3_ST_SW_SRVR_DONE_B:
+ dtls1_start_timer(s);
ret=dtls1_send_server_done(s);
if (ret <= 0) goto end;
s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
@@ -407,16 +441,13 @@ int dtls1_accept(SSL *s)
break;
case SSL3_ST_SW_FLUSH:
- /* number of bytes to be flushed */
- num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
- if (num1 > 0)
+ s->rwstate=SSL_WRITING;
+ if (BIO_flush(s->wbio) <= 0)
{
- s->rwstate=SSL_WRITING;
- num1=BIO_flush(s->wbio);
- if (num1 <= 0) { ret= -1; goto end; }
- s->rwstate=SSL_NOTHING;
+ ret= -1;
+ goto end;
}
-
+ s->rwstate=SSL_NOTHING;
s->state=s->s3->tmp.next_state;
break;
@@ -426,6 +457,7 @@ int dtls1_accept(SSL *s)
ret = ssl3_check_client_hello(s);
if (ret <= 0)
goto end;
+ dtls1_stop_timer(s);
if (ret == 2)
s->state = SSL3_ST_SR_CLNT_HELLO_C;
else {
@@ -433,6 +465,7 @@ int dtls1_accept(SSL *s)
* have not asked for it :-) */
ret=ssl3_get_client_certificate(s);
if (ret <= 0) goto end;
+ dtls1_stop_timer(s);
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
}
@@ -442,6 +475,7 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_KEY_EXCH_B:
ret=ssl3_get_client_key_exchange(s);
if (ret <= 0) goto end;
+ dtls1_stop_timer(s);
s->state=SSL3_ST_SR_CERT_VRFY_A;
s->init_num=0;
@@ -459,9 +493,11 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
+ s->d1->change_cipher_spec_ok = 1;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
+ dtls1_stop_timer(s);
s->state=SSL3_ST_SR_FINISHED_A;
s->init_num=0;
@@ -469,16 +505,41 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
+ s->d1->change_cipher_spec_ok = 1;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
+ dtls1_stop_timer(s);
if (s->hit)
s->state=SSL_ST_OK;
+#ifndef OPENSSL_NO_TLSEXT
+ else if (s->tlsext_ticket_expected)
+ s->state=SSL3_ST_SW_SESSION_TICKET_A;
+#endif
else
s->state=SSL3_ST_SW_CHANGE_A;
s->init_num=0;
break;
+#ifndef OPENSSL_NO_TLSEXT
+ case SSL3_ST_SW_SESSION_TICKET_A:
+ case SSL3_ST_SW_SESSION_TICKET_B:
+ ret=dtls1_send_newsession_ticket(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_SW_CHANGE_A;
+ s->init_num=0;
+ break;
+
+ case SSL3_ST_SW_CERT_STATUS_A:
+ case SSL3_ST_SW_CERT_STATUS_B:
+ ret=ssl3_send_cert_status(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_SW_KEY_EXCH_A;
+ s->init_num=0;
+ break;
+
+#endif
+
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_SW_CHANGE_B:
@@ -554,6 +615,7 @@ int dtls1_accept(SSL *s)
s->d1->handshake_read_seq = 0;
/* next message is server hello */
s->d1->handshake_write_seq = 0;
+ s->d1->next_handshake_write_seq = 0;
goto end;
/* break; */
@@ -631,15 +693,13 @@ int dtls1_send_hello_verify_request(SSL *s)
*(p++) = s->version >> 8,
*(p++) = s->version & 0xFF;
- if (s->ctx->app_gen_cookie_cb != NULL &&
- s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
- &(s->d1->cookie_len)) == 0)
+ if (s->ctx->app_gen_cookie_cb == NULL ||
+ s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
+ &(s->d1->cookie_len)) == 0)
{
SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
return 0;
}
- /* else the cookie is assumed to have
- * been initialized by the application */
*(p++) = (unsigned char) s->d1->cookie_len;
memcpy(p, s->d1->cookie, s->d1->cookie_len);
@@ -713,6 +773,8 @@ int dtls1_send_server_hello(SSL *s)
p+=sl;
/* put the cipher */
+ if (s->s3->tmp.new_cipher == NULL)
+ return -1;
i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
p+=i;
@@ -726,6 +788,14 @@ int dtls1_send_server_hello(SSL *s)
*(p++)=s->s3->tmp.new_compression->id;
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+ {
+ SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+#endif
+
/* do the header */
l=(p-d);
d=buf;
@@ -1145,3 +1215,115 @@ int dtls1_send_server_certificate(SSL *s)
/* SSL3_ST_SW_CERT_B */
return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
}
+
+#ifndef OPENSSL_NO_TLSEXT
+int dtls1_send_newsession_ticket(SSL *s)
+ {
+ if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
+ {
+ unsigned char *p, *senc, *macstart;
+ int len, slen;
+ unsigned int hlen, msg_len;
+ EVP_CIPHER_CTX ctx;
+ HMAC_CTX hctx;
+ SSL_CTX *tctx = s->initial_ctx;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ unsigned char key_name[16];
+
+ /* get session encoding length */
+ slen = i2d_SSL_SESSION(s->session, NULL);
+ /* Some length values are 16 bits, so forget it if session is
+ * too long
+ */
+ if (slen > 0xFF00)
+ return -1;
+ /* Grow buffer if need be: the length calculation is as
+ * follows 12 (DTLS handshake message header) +
+ * 4 (ticket lifetime hint) + 2 (ticket length) +
+ * 16 (key name) + max_iv_len (iv length) +
+ * session_length + max_enc_block_size (max encrypted session
+ * length) + max_md_size (HMAC).
+ */
+ if (!BUF_MEM_grow(s->init_buf,
+ DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH +
+ EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
+ return -1;
+ senc = OPENSSL_malloc(slen);
+ if (!senc)
+ return -1;
+ p = senc;
+ i2d_SSL_SESSION(s->session, &p);
+
+ p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
+ EVP_CIPHER_CTX_init(&ctx);
+ HMAC_CTX_init(&hctx);
+ /* Initialize HMAC and cipher contexts. If callback present
+ * it does all the work otherwise use generated values
+ * from parent ctx.
+ */
+ if (tctx->tlsext_ticket_key_cb)
+ {
+ if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+ &hctx, 1) < 0)
+ {
+ OPENSSL_free(senc);
+ return -1;
+ }
+ }
+ else
+ {
+ RAND_pseudo_bytes(iv, 16);
+ EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ tctx->tlsext_tick_aes_key, iv);
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+ tlsext_tick_md(), NULL);
+ memcpy(key_name, tctx->tlsext_tick_key_name, 16);
+ }
+ l2n(s->session->tlsext_tick_lifetime_hint, p);
+ /* Skip ticket length for now */
+ p += 2;
+ /* Output key name */
+ macstart = p;
+ memcpy(p, key_name, 16);
+ p += 16;
+ /* output IV */
+ memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
+ p += EVP_CIPHER_CTX_iv_length(&ctx);
+ /* Encrypt session data */
+ EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
+ p += len;
+ EVP_EncryptFinal(&ctx, p, &len);
+ p += len;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ HMAC_Update(&hctx, macstart, p - macstart);
+ HMAC_Final(&hctx, p, &hlen);
+ HMAC_CTX_cleanup(&hctx);
+
+ p += hlen;
+ /* Now write out lengths: p points to end of data written */
+ /* Total length */
+ len = p - (unsigned char *)(s->init_buf->data);
+ /* Ticket length */
+ p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
+ s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p);
+
+ /* number of bytes to write */
+ s->init_num= len;
+ s->state=SSL3_ST_SW_SESSION_TICKET_B;
+ s->init_off=0;
+ OPENSSL_free(senc);
+
+ /* XDTLS: set message header ? */
+ msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
+ dtls1_set_message_header(s, (void *)s->init_buf->data,
+ SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len);
+
+ /* buffer the message to handle re-xmits */
+ dtls1_buffer_message(s, 0);
+ }
+
+ /* SSL3_ST_SW_SESSION_TICKET_B */
+ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+ }
+#endif
diff --git a/crypto/openssl/ssl/dtls1.h b/crypto/openssl/ssl/dtls1.h
index f159d37..a8ce51a 100644
--- a/crypto/openssl/ssl/dtls1.h
+++ b/crypto/openssl/ssl/dtls1.h
@@ -62,6 +62,18 @@
#include <openssl/buffer.h>
#include <openssl/pqueue.h>
+#ifdef OPENSSL_SYS_VMS
+#include <resource.h>
+#include <sys/timeb.h>
+#endif
+#ifdef OPENSSL_SYS_WIN32
+/* Needed for struct timeval */
+#include <winsock.h>
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
+#include <sys/timeval.h>
+#else
+#include <sys/time.h>
+#endif
#ifdef __cplusplus
extern "C" {
@@ -76,7 +88,7 @@ extern "C" {
#endif
/* lengths of messages */
-#define DTLS1_COOKIE_LENGTH 32
+#define DTLS1_COOKIE_LENGTH 256
#define DTLS1_RT_HEADER_LENGTH 13
@@ -101,6 +113,19 @@ typedef struct dtls1_bitmap_st
PQ_64BIT max_seq_num; /* max record number seen so far */
} DTLS1_BITMAP;
+struct dtls1_retransmit_state
+ {
+ EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+ const EVP_MD *write_hash; /* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+ COMP_CTX *compress; /* compression */
+#else
+ char *compress;
+#endif
+ SSL_SESSION *session;
+ unsigned short epoch;
+ };
+
struct hm_header_st
{
unsigned char type;
@@ -109,6 +134,7 @@ struct hm_header_st
unsigned long frag_off;
unsigned long frag_len;
unsigned int is_ccs;
+ struct dtls1_retransmit_state saved_retransmit_state;
};
struct ccs_header_st
@@ -168,6 +194,9 @@ typedef struct dtls1_state_st
unsigned short handshake_read_seq;
+ /* save last sequence number for retransmissions */
+ unsigned char last_write_sequence[8];
+
/* Received handshake records (processed and unprocessed) */
record_pqueue unprocessed_rcds;
record_pqueue processed_rcds;
@@ -178,13 +207,29 @@ typedef struct dtls1_state_st
/* Buffered (sent) handshake records */
pqueue sent_messages;
- unsigned int mtu; /* max wire packet size */
+ /* Buffered application records.
+ * Only for records between CCS and Finished
+ * to prevent either protocol violation or
+ * unnecessary message loss.
+ */
+ record_pqueue buffered_app_data;
+
+ /* Is set when listening for new connections with dtls1_listen() */
+ unsigned int listen;
+
+ unsigned int mtu; /* max DTLS packet size */
struct hm_header_st w_msg_hdr;
struct hm_header_st r_msg_hdr;
struct dtls1_timeout_st timeout;
-
+
+ /* Indicates when the last handshake msg sent will timeout */
+ struct timeval next_timeout;
+
+ /* Timeout duration */
+ unsigned short timeout_duration;
+
/* storage for Alert/Handshake protocol data received but not
* yet processed by ssl3_read_bytes: */
unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
@@ -193,6 +238,7 @@ typedef struct dtls1_state_st
unsigned int handshake_fragment_len;
unsigned int retransmitting;
+ unsigned int change_cipher_spec_ok;
} DTLS1_STATE;
diff --git a/crypto/openssl/ssl/kssl.c b/crypto/openssl/ssl/kssl.c
index 019030a..5cba28b 100644
--- a/crypto/openssl/ssl/kssl.c
+++ b/crypto/openssl/ssl/kssl.c
@@ -68,11 +68,6 @@
#include <openssl/opensslconf.h>
-#define _XOPEN_SOURCE 500 /* glibc2 needs this to declare strptime() */
-#include <time.h>
-#if 0 /* experimental */
-#undef _XOPEN_SOURCE /* To avoid clashes with anything else... */
-#endif
#include <string.h>
#define KRB5_PRIVATE 1
@@ -1807,6 +1802,9 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx)
kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC,
KRB5_NT_SRV_HST, &princ);
+ if (krb5rc)
+ goto exit;
+
krb5rc = krb5_kt_get_entry(krb5context, krb5keytab,
princ,
0 /* IGNORE_VNO */,
diff --git a/crypto/openssl/ssl/s23_clnt.c b/crypto/openssl/ssl/s23_clnt.c
index bc91817..de02389 100644
--- a/crypto/openssl/ssl/s23_clnt.c
+++ b/crypto/openssl/ssl/s23_clnt.c
@@ -202,11 +202,14 @@ static int ssl23_client_hello(SSL *s)
{
unsigned char *buf;
unsigned char *p,*d;
- int i,j,ch_len;
+ int i,ch_len;
unsigned long Time,l;
int ssl2_compat;
int version = 0, version_major, version_minor;
+#ifndef OPENSSL_NO_COMP
+ int j;
SSL_COMP *comp;
+#endif
int ret;
ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
diff --git a/crypto/openssl/ssl/s23_srvr.c b/crypto/openssl/ssl/s23_srvr.c
index ba06e7a..be05911 100644
--- a/crypto/openssl/ssl/s23_srvr.c
+++ b/crypto/openssl/ssl/s23_srvr.c
@@ -315,7 +315,7 @@ int ssl23_get_client_hello(SSL *s)
(p[1] == SSL3_VERSION_MAJOR) &&
(p[5] == SSL3_MT_CLIENT_HELLO) &&
((p[3] == 0 && p[4] < 5 /* silly record length? */)
- || (p[9] == p[1])))
+ || (p[9] >= p[1])))
{
/*
* SSLv3 or tls1 header
@@ -339,6 +339,13 @@ int ssl23_get_client_hello(SSL *s)
v[1] = TLS1_VERSION_MINOR;
#endif
}
+ /* if major version number > 3 set minor to a value
+ * which will use the highest version 3 we support.
+ * If TLS 2.0 ever appears we will need to revise
+ * this....
+ */
+ else if (p[9] > SSL3_VERSION_MAJOR)
+ v[1]=0xff;
else
v[1]=p[10]; /* minor version according to client_version */
if (v[1] >= TLS1_VERSION_MINOR)
diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c
index 50d55e6..01d62fa 100644
--- a/crypto/openssl/ssl/s2_srvr.c
+++ b/crypto/openssl/ssl/s2_srvr.c
@@ -267,7 +267,7 @@ int ssl2_accept(SSL *s)
case SSL2_ST_SEND_SERVER_VERIFY_C:
/* get the number of bytes to write */
num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
- if (num1 != 0)
+ if (num1 > 0)
{
s->rwstate=SSL_WRITING;
num1=BIO_flush(s->wbio);
diff --git a/crypto/openssl/ssl/s3_both.c b/crypto/openssl/ssl/s3_both.c
index 2ecfbb7..7f46225 100644
--- a/crypto/openssl/ssl/s3_both.c
+++ b/crypto/openssl/ssl/s3_both.c
@@ -168,6 +168,23 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
p+=i;
l=i;
+ /* Copy the finished so we can use it for
+ renegotiation checks */
+ if(s->type == SSL_ST_CONNECT)
+ {
+ OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+ memcpy(s->s3->previous_client_finished,
+ s->s3->tmp.finish_md, i);
+ s->s3->previous_client_finished_len=i;
+ }
+ else
+ {
+ OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+ memcpy(s->s3->previous_server_finished,
+ s->s3->tmp.finish_md, i);
+ s->s3->previous_server_finished_len=i;
+ }
+
#ifdef OPENSSL_SYS_WIN16
/* MSVC 1.5 does not clear the top bytes of the word unless
* I do this.
@@ -232,6 +249,23 @@ int ssl3_get_finished(SSL *s, int a, int b)
goto f_err;
}
+ /* Copy the finished so we can use it for
+ renegotiation checks */
+ if(s->type == SSL_ST_ACCEPT)
+ {
+ OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+ memcpy(s->s3->previous_client_finished,
+ s->s3->tmp.peer_finish_md, i);
+ s->s3->previous_client_finished_len=i;
+ }
+ else
+ {
+ OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+ memcpy(s->s3->previous_server_finished,
+ s->s3->tmp.peer_finish_md, i);
+ s->s3->previous_server_finished_len=i;
+ }
+
return(1);
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
@@ -264,15 +298,31 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
}
+static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
+ {
+ int n;
+ unsigned char *p;
+
+ n=i2d_X509(x,NULL);
+ if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+ {
+ SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+ return(-1);
+ }
+ p=(unsigned char *)&(buf->data[*l]);
+ l2n3(n,p);
+ i2d_X509(x,&p);
+ *l+=n+3;
+
+ return(0);
+ }
+
unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
{
unsigned char *p;
- int n,i;
+ int i;
unsigned long l=7;
BUF_MEM *buf;
- X509_STORE_CTX xs_ctx;
- X509_OBJECT obj;
-
int no_chain;
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
@@ -289,58 +339,40 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
}
if (x != NULL)
{
- if(!no_chain && !X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
+ if (no_chain)
{
- SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
- return(0);
+ if (ssl3_add_cert_to_buf(buf, &l, x))
+ return(0);
}
-
- for (;;)
+ else
{
- n=i2d_X509(x,NULL);
- if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
+ X509_STORE_CTX xs_ctx;
+
+ if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
{
- SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
+ SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
return(0);
}
- p=(unsigned char *)&(buf->data[l]);
- l2n3(n,p);
- i2d_X509(x,&p);
- l+=n+3;
-
- if (no_chain)
- break;
-
- if (X509_NAME_cmp(X509_get_subject_name(x),
- X509_get_issuer_name(x)) == 0) break;
-
- i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
- X509_get_issuer_name(x),&obj);
- if (i <= 0) break;
- x=obj.data.x509;
- /* Count is one too high since the X509_STORE_get uped the
- * ref count */
- X509_free(x);
- }
- if (!no_chain)
+ X509_verify_cert(&xs_ctx);
+ for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
+ {
+ x = sk_X509_value(xs_ctx.chain, i);
+
+ if (ssl3_add_cert_to_buf(buf, &l, x))
+ {
+ X509_STORE_CTX_cleanup(&xs_ctx);
+ return 0;
+ }
+ }
X509_STORE_CTX_cleanup(&xs_ctx);
+ }
}
-
/* Thawte special :-) */
- if (s->ctx->extra_certs != NULL)
for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
{
x=sk_X509_value(s->ctx->extra_certs,i);
- n=i2d_X509(x,NULL);
- if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
- {
- SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
+ if (ssl3_add_cert_to_buf(buf, &l, x))
return(0);
- }
- p=(unsigned char *)&(buf->data[l]);
- l2n3(n,p);
- i2d_X509(x,&p);
- l+=n+3;
}
l-=7;
@@ -589,9 +621,14 @@ int ssl_verify_alarm_type(long type)
int ssl3_setup_buffers(SSL *s)
{
unsigned char *p;
- unsigned int extra;
+ unsigned int extra,headerlen;
size_t len;
+ if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+ headerlen = DTLS1_RT_HEADER_LENGTH;
+ else
+ headerlen = SSL3_RT_HEADER_LENGTH;
+
if (s->s3->rbuf.buf == NULL)
{
if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
@@ -608,7 +645,7 @@ int ssl3_setup_buffers(SSL *s)
if (s->s3->wbuf.buf == NULL)
{
len = SSL3_RT_MAX_PACKET_SIZE;
- len += SSL3_RT_HEADER_LENGTH + 256; /* extra space for empty fragment */
+ len += headerlen + 256; /* extra space for empty fragment */
if ((p=OPENSSL_malloc(len)) == NULL)
goto err;
s->s3->wbuf.buf = p;
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index 5030848..e5138b6 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -144,9 +144,6 @@
static SSL_METHOD *ssl3_get_client_method(int ver);
static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
-#ifndef OPENSSL_NO_TLSEXT
-static int ssl3_check_finished(SSL *s);
-#endif
#ifndef OPENSSL_NO_ECDH
static int curve_id2nid(int curve_id);
@@ -170,7 +167,6 @@ int ssl3_connect(SSL *s)
{
BUF_MEM *buf=NULL;
unsigned long Time=(unsigned long)time(NULL),l;
- long num1;
void (*cb)(const SSL *ssl,int type,int val)=NULL;
int ret= -1;
int new_state,state,skip=0;
@@ -499,16 +495,13 @@ int ssl3_connect(SSL *s)
break;
case SSL3_ST_CW_FLUSH:
- /* number of bytes to be flushed */
- num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
- if (num1 > 0)
+ s->rwstate=SSL_WRITING;
+ if (BIO_flush(s->wbio) <= 0)
{
- s->rwstate=SSL_WRITING;
- num1=BIO_flush(s->wbio);
- if (num1 <= 0) { ret= -1; goto end; }
- s->rwstate=SSL_NOTHING;
+ ret= -1;
+ goto end;
}
-
+ s->rwstate=SSL_NOTHING;
s->state=s->s3->tmp.next_state;
break;
@@ -594,9 +587,15 @@ int ssl3_client_hello(SSL *s)
buf=(unsigned char *)s->init_buf->data;
if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
{
- if ((s->session == NULL) ||
- (s->session->ssl_version != s->version) ||
- (s->session->not_resumable))
+ SSL_SESSION *sess = s->session;
+ if ((sess == NULL) ||
+ (sess->ssl_version != s->version) ||
+#ifdef OPENSSL_NO_TLSEXT
+ !sess->session_id_length ||
+#else
+ (!sess->session_id_length && !sess->tlsext_tick) ||
+#endif
+ (sess->not_resumable))
{
if (!ssl_get_new_session(s,0))
goto err;
@@ -708,7 +707,7 @@ int ssl3_get_server_hello(SSL *s)
if (!ok) return((int)n);
- if ( SSL_version(s) == DTLS1_VERSION)
+ if ( SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
{
if ( s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST)
{
@@ -855,7 +854,7 @@ int ssl3_get_server_hello(SSL *s)
#endif
#ifndef OPENSSL_NO_TLSEXT
/* TLS extensions*/
- if (s->version > SSL3_VERSION)
+ if (s->version >= SSL3_VERSION)
{
if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
{
@@ -1715,6 +1714,7 @@ int ssl3_get_new_session_ticket(SSL *s)
SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
+
p=d=(unsigned char *)s->init_msg;
n2l(p, s->session->tlsext_tick_lifetime_hint);
n2s(p, ticklen);
@@ -1738,7 +1738,28 @@ int ssl3_get_new_session_ticket(SSL *s)
}
memcpy(s->session->tlsext_tick, p, ticklen);
s->session->tlsext_ticklen = ticklen;
-
+ /* There are two ways to detect a resumed ticket sesion.
+ * One is to set an appropriate session ID and then the server
+ * must return a match in ServerHello. This allows the normal
+ * client session ID matching to work and we know much
+ * earlier that the ticket has been accepted.
+ *
+ * The other way is to set zero length session ID when the
+ * ticket is presented and rely on the handshake to determine
+ * session resumption.
+ *
+ * We choose the former approach because this fits in with
+ * assumptions elsewhere in OpenSSL. The session ID is set
+ * to the SHA256 (or SHA1 is SHA256 is disabled) hash of the
+ * ticket.
+ */
+ EVP_Digest(p, ticklen,
+ s->session->session_id, &s->session->session_id_length,
+#ifndef OPENSSL_NO_SHA256
+ EVP_sha256(), NULL);
+#else
+ EVP_sha1(), NULL);
+#endif
ret=1;
return(ret);
f_err:
@@ -2697,7 +2718,7 @@ static int curve_id2nid(int curve_id)
*/
#ifndef OPENSSL_NO_TLSEXT
-static int ssl3_check_finished(SSL *s)
+int ssl3_check_finished(SSL *s)
{
int ok;
long n;
diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c
index 1b38f72..8fa4ab0 100644
--- a/crypto/openssl/ssl/s3_lib.c
+++ b/crypto/openssl/ssl/s3_lib.c
@@ -2458,6 +2458,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
int ssl3_shutdown(SSL *s)
{
+ int ret;
/* Don't do anything much if we have not done the handshake or
* we don't want to send messages :-) */
@@ -2475,18 +2476,32 @@ int ssl3_shutdown(SSL *s)
#endif
/* our shutdown alert has been sent now, and if it still needs
* to be written, s->s3->alert_dispatch will be true */
+ if (s->s3->alert_dispatch)
+ return(-1); /* return WANT_WRITE */
}
else if (s->s3->alert_dispatch)
{
/* resend it if not sent */
#if 1
- s->method->ssl_dispatch_alert(s);
+ ret=s->method->ssl_dispatch_alert(s);
+ if(ret == -1)
+ {
+ /* we only get to return -1 here the 2nd/Nth
+ * invocation, we must have already signalled
+ * return 0 upon a previous invoation,
+ * return WANT_WRITE */
+ return(ret);
+ }
#endif
}
else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN))
{
/* If we are waiting for a close from our peer, we are closed */
s->method->ssl_read_bytes(s,0,NULL,0,0);
+ if(!(s->shutdown & SSL_RECEIVED_SHUTDOWN))
+ {
+ return(-1); /* return WANT_READ */
+ }
}
if ((s->shutdown == (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) &&
@@ -2592,9 +2607,6 @@ int ssl3_renegotiate(SSL *s)
if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
return(0);
- if (1)
- return(0);
-
s->s3->renegotiate=1;
return(1);
}
diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c
index 1644f19..5e3583c 100644
--- a/crypto/openssl/ssl/s3_pkt.c
+++ b/crypto/openssl/ssl/s3_pkt.c
@@ -141,9 +141,10 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
/* ... now we can act as if 'extend' was set */
}
- /* extend reads should not span multiple packets for DTLS */
- if ( SSL_version(s) == DTLS1_VERSION &&
- extend)
+ /* For DTLS/UDP reads should not span multiple packets
+ * because the read operation returns the whole packet
+ * at once (as long as it fits into the buffer). */
+ if (SSL_version(s) == DTLS1_VERSION)
{
if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
n = s->s3->rbuf.left;
@@ -209,6 +210,14 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
return(i);
}
newb+=i;
+ /* reads should *never* span multiple packets for DTLS because
+ * the underlying transport protocol is message oriented as opposed
+ * to byte oriented as in the TLS case. */
+ if (SSL_version(s) == DTLS1_VERSION)
+ {
+ if (n > newb)
+ n = newb; /* makes the while condition false */
+ }
}
/* done reading, now the book-keeping */
@@ -282,9 +291,9 @@ again:
if (version != s->version)
{
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
- /* Send back error using their
- * version number :-) */
- s->version=version;
+ if ((s->version & 0xFF00) == (version & 0xFF00))
+ /* Send back error using their minor version number :-) */
+ s->version = (unsigned short)version;
al=SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
@@ -983,7 +992,9 @@ start:
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
- if (0)
+ if (SSL_is_init_finished(s) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+ !s->s3->renegotiate)
{
ssl3_renegotiate(s);
if (ssl3_renegotiate_check(s))
@@ -1018,7 +1029,25 @@ start:
* now try again to obtain the (application) data we were asked for */
goto start;
}
-
+ /* If we are a server and get a client hello when renegotiation isn't
+ * allowed send back a no renegotiation alert and carry on.
+ * WARNING: experimental code, needs reviewing (steve)
+ */
+ if (s->server &&
+ SSL_is_init_finished(s) &&
+ !s->s3->send_connection_binding &&
+ (s->version > SSL3_VERSION) &&
+ (s->s3->handshake_fragment_len >= 4) &&
+ (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
+ (s->session != NULL) && (s->session->cipher != NULL) &&
+ !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+
+ {
+ /*s->s3->handshake_fragment_len = 0;*/
+ rr->length = 0;
+ ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ goto start;
+ }
if (s->s3->alert_fragment_len >= 2)
{
int alert_level = s->s3->alert_fragment[0];
@@ -1048,6 +1077,21 @@ start:
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return(0);
}
+ /* This is a warning but we receive it if we requested
+ * renegotiation and the peer denied it. Terminate with
+ * a fatal alert because if application tried to
+ * renegotiatie it presumably had a good reason and
+ * expects it to succeed.
+ *
+ * In future we might have a renegotiation where we
+ * don't care if the peer refused it where we carry on.
+ */
+ else if (alert_descr == SSL_AD_NO_RENEGOTIATION)
+ {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
+ goto f_err;
+ }
}
else if (alert_level == 2) /* fatal */
{
@@ -1114,7 +1158,8 @@ start:
/* Unexpected handshake message (Client Hello, or protocol violation) */
if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake)
{
- if (0)
+ if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
{
#if 0 /* worked only because C operator preferences are not as expected (and
* because this is not really needed for clients except for detecting
@@ -1265,13 +1310,13 @@ int ssl3_do_change_cipher_spec(SSL *s)
return(1);
}
-void ssl3_send_alert(SSL *s, int level, int desc)
+int ssl3_send_alert(SSL *s, int level, int desc)
{
/* Map tls/ssl alert value to correct one */
desc=s->method->ssl3_enc->alert_value(desc);
if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */
- if (desc < 0) return;
+ if (desc < 0) return -1;
/* If a fatal one, remove from cache */
if ((level == 2) && (s->session != NULL))
SSL_CTX_remove_session(s->ctx,s->session);
@@ -1280,9 +1325,10 @@ void ssl3_send_alert(SSL *s, int level, int desc)
s->s3->send_alert[0]=level;
s->s3->send_alert[1]=desc;
if (s->s3->wbuf.left == 0) /* data still being written out? */
- s->method->ssl_dispatch_alert(s);
+ return s->method->ssl_dispatch_alert(s);
/* else data is still being written out, we will get written
* some time in the future */
+ return -1;
}
int ssl3_dispatch_alert(SSL *s)
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index b2ba9ff..e696450 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -166,7 +166,6 @@ int ssl3_accept(SSL *s)
BUF_MEM *buf;
unsigned long l,Time=(unsigned long)time(NULL);
void (*cb)(const SSL *ssl,int type,int val)=NULL;
- long num1;
int ret= -1;
int new_state,state,skip=0;
@@ -248,6 +247,18 @@ int ssl3_accept(SSL *s)
s->state=SSL3_ST_SR_CLNT_HELLO_A;
s->ctx->stats.sess_accept++;
}
+ else if (!s->s3->send_connection_binding &&
+ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ {
+ /* Server attempting to renegotiate with
+ * client that doesn't support secure
+ * renegotiation.
+ */
+ SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+ ret = -1;
+ goto end;
+ }
else
{
/* s->state == SSL_ST_RENEGOTIATE,
@@ -435,15 +446,24 @@ int ssl3_accept(SSL *s)
break;
case SSL3_ST_SW_FLUSH:
- /* number of bytes to be flushed */
- num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
- if (num1 > 0)
+
+ /* This code originally checked to see if
+ * any data was pending using BIO_CTRL_INFO
+ * and then flushed. This caused problems
+ * as documented in PR#1939. The proposed
+ * fix doesn't completely resolve this issue
+ * as buggy implementations of BIO_CTRL_PENDING
+ * still exist. So instead we just flush
+ * unconditionally.
+ */
+
+ s->rwstate=SSL_WRITING;
+ if (BIO_flush(s->wbio) <= 0)
{
- s->rwstate=SSL_WRITING;
- num1=BIO_flush(s->wbio);
- if (num1 <= 0) { ret= -1; goto end; }
- s->rwstate=SSL_NOTHING;
+ ret= -1;
+ goto end;
}
+ s->rwstate=SSL_NOTHING;
s->state=s->s3->tmp.next_state;
break;
@@ -718,13 +738,6 @@ int ssl3_get_client_hello(SSL *s)
#endif
STACK_OF(SSL_CIPHER) *ciphers=NULL;
- if (s->new_session)
- {
- al=SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
-
/* We do this so that we will respond with our native type.
* If we are TLSv1 and we get SSLv3, we will respond with TLSv1,
* This down switching should be handled by a different method.
@@ -765,6 +778,21 @@ int ssl3_get_client_hello(SSL *s)
goto f_err;
}
+ /* If we require cookies and this ClientHello doesn't
+ * contain one, just return since we do not want to
+ * allocate any memory yet. So check cookie length...
+ */
+ if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)
+ {
+ unsigned int session_length, cookie_length;
+
+ session_length = *(p + SSL3_RANDOM_SIZE);
+ cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
+
+ if (cookie_length == 0)
+ return 1;
+ }
+
/* load the client random */
memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE;
@@ -804,23 +832,11 @@ int ssl3_get_client_hello(SSL *s)
p+=j;
- if (s->version == DTLS1_VERSION)
+ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
{
/* cookie stuff */
cookie_len = *(p++);
- if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
- s->d1->send_cookie == 0)
- {
- /* HelloVerifyMessage has already been sent */
- if ( cookie_len != s->d1->cookie_len)
- {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
- goto f_err;
- }
- }
-
/*
* The ClientHello may contain a cookie even if the
* HelloVerify message has not been sent--make sure that it
@@ -835,7 +851,7 @@ int ssl3_get_client_hello(SSL *s)
}
/* verify the cookie if appropriate option is set. */
- if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
+ if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
cookie_len > 0)
{
memcpy(s->d1->rcvd_cookie, p, cookie_len);
@@ -860,6 +876,8 @@ int ssl3_get_client_hello(SSL *s)
SSL_R_COOKIE_MISMATCH);
goto f_err;
}
+
+ ret = 2;
}
p += cookie_len;
@@ -959,7 +977,7 @@ int ssl3_get_client_hello(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
/* TLS extensions*/
- if (s->version > SSL3_VERSION)
+ if (s->version >= SSL3_VERSION)
{
if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
{
@@ -1094,7 +1112,7 @@ int ssl3_get_client_hello(SSL *s)
* s->tmp.new_cipher - the new cipher to use.
*/
- ret=1;
+ if (ret < 0) ret=1;
if (0)
{
f_err:
@@ -2718,6 +2736,7 @@ int ssl3_send_newsession_ticket(SSL *s)
unsigned int hlen;
EVP_CIPHER_CTX ctx;
HMAC_CTX hctx;
+ SSL_CTX *tctx = s->initial_ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key_name[16];
@@ -2756,9 +2775,9 @@ int ssl3_send_newsession_ticket(SSL *s)
* it does all the work otherwise use generated values
* from parent ctx.
*/
- if (s->ctx->tlsext_ticket_key_cb)
+ if (tctx->tlsext_ticket_key_cb)
{
- if (s->ctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+ if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
&hctx, 1) < 0)
{
OPENSSL_free(senc);
@@ -2769,10 +2788,10 @@ int ssl3_send_newsession_ticket(SSL *s)
{
RAND_pseudo_bytes(iv, 16);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- s->ctx->tlsext_tick_aes_key, iv);
- HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
+ tctx->tlsext_tick_aes_key, iv);
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
- memcpy(key_name, s->ctx->tlsext_tick_key_name, 16);
+ memcpy(key_name, tctx->tlsext_tick_key_name, 16);
}
l2n(s->session->tlsext_tick_lifetime_hint, p);
/* Skip ticket length for now */
diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h
index ff8a128..7d4e46e 100644
--- a/crypto/openssl/ssl/ssl.h
+++ b/crypto/openssl/ssl/ssl.h
@@ -485,6 +485,8 @@ typedef struct ssl_session_st
#define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L
#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L
+/* Allow initial connection to servers that don't support RI */
+#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L
#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L
#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
@@ -510,9 +512,13 @@ typedef struct ssl_session_st
#define SSL_OP_COOKIE_EXCHANGE 0x00002000L
/* Don't use RFC4507 ticket extension */
#define SSL_OP_NO_TICKET 0x00004000L
+/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */
+#define SSL_OP_CISCO_ANYCONNECT 0x00008000L
/* As server, disallow session resumption on renegotiation */
#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L
+/* Permit unsafe legacy renegotiation */
+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
/* If set, always create a new key when using tmp_ecdh parameters */
#define SSL_OP_SINGLE_ECDH_USE 0x00080000L
/* If set, always create a new key when using tmp_dh parameters */
@@ -561,17 +567,25 @@ typedef struct ssl_session_st
#define SSL_CTX_set_options(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_CTX_clear_options(ctx,op) \
+ SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
#define SSL_CTX_get_options(ctx) \
SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
#define SSL_set_options(ssl,op) \
SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_clear_options(ssl,op) \
+ SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
#define SSL_get_options(ssl) \
SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
#define SSL_CTX_set_mode(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+#define SSL_CTX_clear_mode(ctx,op) \
+ SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
#define SSL_CTX_get_mode(ctx) \
SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
+#define SSL_clear_mode(ssl,op) \
+ SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
#define SSL_set_mode(ssl,op) \
SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
#define SSL_get_mode(ssl) \
@@ -579,6 +593,8 @@ typedef struct ssl_session_st
#define SSL_set_mtu(ssl, mtu) \
SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+#define SSL_get_secure_renegotiation_support(ssl) \
+ SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
@@ -1269,6 +1285,21 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
#endif
+#define DTLS_CTRL_GET_TIMEOUT 73
+#define DTLS_CTRL_HANDLE_TIMEOUT 74
+#define DTLS_CTRL_LISTEN 75
+
+#define SSL_CTRL_GET_RI_SUPPORT 76
+#define SSL_CTRL_CLEAR_OPTIONS 77
+#define SSL_CTRL_CLEAR_MODE 78
+
+#define DTLSv1_get_timeout(ssl, arg) \
+ SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
+#define DTLSv1_handle_timeout(ssl) \
+ SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
+#define DTLSv1_listen(ssl, peer) \
+ SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer)
+
#define SSL_session_reused(ssl) \
SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
#define SSL_num_renegotiations(ssl) \
@@ -1519,7 +1550,7 @@ long SSL_get_default_timeout(const SSL *s);
int SSL_library_init(void );
-char *SSL_CIPHER_description(SSL_CIPHER *,char *buf,int size);
+char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size);
STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
SSL *SSL_dup(SSL *ssl);
@@ -1649,6 +1680,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_DO_DTLS1_WRITE 245
#define SSL_F_DO_SSL3_WRITE 104
#define SSL_F_DTLS1_ACCEPT 246
+#define SSL_F_DTLS1_ADD_CERT_TO_BUF 280
#define SSL_F_DTLS1_BUFFER_RECORD 247
#define SSL_F_DTLS1_CLIENT_HELLO 248
#define SSL_F_DTLS1_CONNECT 249
@@ -1657,6 +1689,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_DTLS1_GET_MESSAGE 252
#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253
#define SSL_F_DTLS1_GET_RECORD 254
+#define SSL_F_DTLS1_HANDLE_TIMEOUT 282
#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255
#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277
#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256
@@ -1702,6 +1735,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL2_SET_CERTIFICATE 126
#define SSL_F_SSL2_WRITE 127
#define SSL_F_SSL3_ACCEPT 128
+#define SSL_F_SSL3_ADD_CERT_TO_BUF 281
#define SSL_F_SSL3_CALLBACK_CTRL 233
#define SSL_F_SSL3_CHANGE_CIPHER_STATE 129
#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130
@@ -1742,9 +1776,11 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_SETUP_KEY_BLOCK 157
#define SSL_F_SSL3_WRITE_BYTES 158
#define SSL_F_SSL3_WRITE_PENDING 159
+#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 285
#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 272
#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215
#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216
+#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 286
#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 273
#define SSL_F_SSL_BAD_METHOD 160
#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161
@@ -1786,6 +1822,10 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_INIT_WBIO_BUFFER 184
#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185
#define SSL_F_SSL_NEW 186
+#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 287
+#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 290
+#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 289
+#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 291
#define SSL_F_SSL_PEEK 270
#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 275
#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 276
@@ -1885,6 +1925,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281
#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148
#define SSL_R_DIGEST_CHECK_FAILED 149
+#define SSL_R_DTLS_MESSAGE_TOO_BIG 318
#define SSL_R_DUPLICATE_COMPRESSION_ID 309
#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310
#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
@@ -1952,6 +1993,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190
#define SSL_R_NO_PROTOCOLS_AVAILABLE 191
#define SSL_R_NO_PUBLICKEY 192
+#define SSL_R_NO_RENEGOTIATION 319
#define SSL_R_NO_SHARED_CIPHER 193
#define SSL_R_NO_VERIFY_CALLBACK 194
#define SSL_R_NULL_SSL_CTX 195
@@ -1979,10 +2021,14 @@ void ERR_load_SSL_strings(void);
#define SSL_R_RECORD_LENGTH_MISMATCH 213
#define SSL_R_RECORD_TOO_LARGE 214
#define SSL_R_RECORD_TOO_SMALL 298
+#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 320
+#define SSL_R_RENEGOTIATION_ENCODING_ERR 321
+#define SSL_R_RENEGOTIATION_MISMATCH 322
#define SSL_R_REQUIRED_CIPHER_MISSING 215
#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216
#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217
#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 324
#define SSL_R_SERVERHELLO_TLSEXT 224
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
#define SSL_R_SHORT_READ 219
@@ -2052,6 +2098,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253
#define SSL_R_UNKNOWN_SSL_VERSION 254
#define SSL_R_UNKNOWN_STATE 255
+#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 323
#define SSL_R_UNSUPPORTED_CIPHER 256
#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257
#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315
diff --git a/crypto/openssl/ssl/ssl3.h b/crypto/openssl/ssl/ssl3.h
index 4b1e2e9..2f579c2 100644
--- a/crypto/openssl/ssl/ssl3.h
+++ b/crypto/openssl/ssl/ssl3.h
@@ -129,6 +129,9 @@
extern "C" {
#endif
+/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
+#define SSL3_CK_SCSV 0x030000FF
+
#define SSL3_CK_RSA_NULL_MD5 0x03000001
#define SSL3_CK_RSA_NULL_SHA 0x03000002
#define SSL3_CK_RSA_RC4_40_MD5 0x03000003
@@ -440,6 +443,12 @@ typedef struct ssl3_state_st
int cert_request;
} tmp;
+ /* Connection binding to prevent renegotiation attacks */
+ unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
+ unsigned char previous_client_finished_len;
+ unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
+ unsigned char previous_server_finished_len;
+ int send_connection_binding; /* TODOEKR */
} SSL3_STATE;
diff --git a/crypto/openssl/ssl/ssl_algs.c b/crypto/openssl/ssl/ssl_algs.c
index 4717c0e..2d9077e 100644
--- a/crypto/openssl/ssl/ssl_algs.c
+++ b/crypto/openssl/ssl/ssl_algs.c
@@ -92,9 +92,6 @@ int SSL_library_init(void)
EVP_add_cipher(EVP_seed_cbc());
#endif
-#ifndef OPENSSL_NO_MD2
- EVP_add_digest(EVP_md2());
-#endif
#ifndef OPENSSL_NO_MD5
EVP_add_digest(EVP_md5());
EVP_add_digest_alias(SN_md5,"ssl2-md5");
diff --git a/crypto/openssl/ssl/ssl_asn1.c b/crypto/openssl/ssl/ssl_asn1.c
index 0f9a348..d82e47a 100644
--- a/crypto/openssl/ssl/ssl_asn1.c
+++ b/crypto/openssl/ssl/ssl_asn1.c
@@ -68,6 +68,7 @@ typedef struct ssl_session_asn1_st
ASN1_INTEGER version;
ASN1_INTEGER ssl_version;
ASN1_OCTET_STRING cipher;
+ ASN1_OCTET_STRING comp_id;
ASN1_OCTET_STRING master_key;
ASN1_OCTET_STRING session_id;
ASN1_OCTET_STRING session_id_context;
@@ -95,6 +96,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
int v6=0,v9=0,v10=0;
unsigned char ibuf6[LSIZE2];
#endif
+#ifndef OPENSSL_NO_COMP
+ int v11=0;
+ unsigned char cbuf;
+#endif
long l;
SSL_SESSION_ASN1 a;
M_ASN1_I2D_vars(in);
@@ -138,6 +143,16 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
buf[1]=((unsigned char)(l ))&0xff;
}
+#ifndef OPENSSL_NO_COMP
+ if (in->compress_meth)
+ {
+ cbuf = (unsigned char)in->compress_meth;
+ a.comp_id.length = 1;
+ a.comp_id.type = V_ASN1_OCTET_STRING;
+ a.comp_id.data = &cbuf;
+ }
+#endif
+
a.master_key.length=in->master_key_length;
a.master_key.type=V_ASN1_OCTET_STRING;
a.master_key.data=in->master_key;
@@ -199,12 +214,6 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
a.tlsext_tick.length= in->tlsext_ticklen;
a.tlsext_tick.type=V_ASN1_OCTET_STRING;
a.tlsext_tick.data=(unsigned char *)in->tlsext_tick;
- /* If we have a ticket set session ID to empty because
- * it will be bogus. If liftime hint is -1 treat as a special
- * case because the session is being used as a container
- */
- if (in->tlsext_ticklen && (in->tlsext_tick_lifetime_hint != -1))
- a.session_id.length=0;
}
if (in->tlsext_tick_lifetime_hint > 0)
{
@@ -242,6 +251,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
if (in->tlsext_hostname)
M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
+#ifndef OPENSSL_NO_COMP
+ if (in->compress_meth)
+ M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
+#endif
#endif /* OPENSSL_NO_TLSEXT */
M_ASN1_I2D_seq_total();
@@ -274,6 +287,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
if (in->tlsext_tick)
M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_COMP
+ if (in->compress_meth)
+ M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
+#endif
M_ASN1_I2D_finish();
}
@@ -317,7 +334,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
((unsigned long)os.data[1]<< 8L)|
(unsigned long)os.data[2];
}
- else if ((ssl_version>>8) == SSL3_VERSION_MAJOR)
+ else if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
{
if (os.length != 2)
{
@@ -330,15 +347,15 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
}
else
{
- SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_UNKNOWN_SSL_VERSION);
- return(NULL);
+ c.error=SSL_R_UNKNOWN_SSL_VERSION;
+ goto err;
}
ret->cipher=NULL;
ret->cipher_id=id;
M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
- if ((ssl_version>>8) == SSL3_VERSION_MAJOR)
+ if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
i=SSL3_MAX_SSL_SESSION_ID_LENGTH;
else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */
i=SSL2_MAX_SSL_SESSION_ID_LENGTH;
@@ -422,8 +439,8 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
{
if (os.length > SSL_MAX_SID_CTX_LENGTH)
{
- ret->sid_ctx_length=os.length;
- SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_BAD_LENGTH);
+ c.error=SSL_R_BAD_LENGTH;
+ goto err;
}
else
{
@@ -478,23 +495,21 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
ret->tlsext_ticklen = os.length;
os.data = NULL;
os.length = 0;
-#if 0
- /* There are two ways to detect a resumed ticket sesion.
- * One is to set a random session ID and then the server
- * must return a match in ServerHello. This allows the normal
- * client session ID matching to work.
- */
- if (ret->session_id_length == 0)
- {
- ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH;
- RAND_pseudo_bytes(ret->session_id,
- ret->session_id_length);
- }
-#endif
}
else
ret->tlsext_tick=NULL;
#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_COMP
+ os.length=0;
+ os.data=NULL;
+ M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
+ if (os.data)
+ {
+ ret->compress_meth = os.data[0];
+ OPENSSL_free(os.data);
+ os.data = NULL;
+ }
+#endif
M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
}
diff --git a/crypto/openssl/ssl/ssl_cert.c b/crypto/openssl/ssl/ssl_cert.c
index a32b2d4..16fda5d 100644
--- a/crypto/openssl/ssl/ssl_cert.c
+++ b/crypto/openssl/ssl/ssl_cert.c
@@ -500,9 +500,6 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
return(0);
}
- if (s->param)
- X509_VERIFY_PARAM_inherit(X509_STORE_CTX_get0_param(&ctx),
- s->param);
#if 0
if (SSL_get_verify_depth(s) >= 0)
X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
@@ -516,6 +513,10 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
X509_STORE_CTX_set_default(&ctx,
s->server ? "ssl_client" : "ssl_server");
+ /* Anything non-default in "param" should overwrite anything in the
+ * ctx.
+ */
+ X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
if (s->verify_callback)
X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
diff --git a/crypto/openssl/ssl/ssl_ciph.c b/crypto/openssl/ssl/ssl_ciph.c
index 52f91cf..5e2d436 100644
--- a/crypto/openssl/ssl/ssl_ciph.c
+++ b/crypto/openssl/ssl/ssl_ciph.c
@@ -1091,10 +1091,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
*cipher_list_by_id = tmp_cipher_list;
(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
+ sk_SSL_CIPHER_sort(*cipher_list_by_id);
return(cipherstack);
}
-char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
+char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
{
int is_export,pkl,kl;
const char *ver,*exp_str;
diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c
index 24a994f..7eb5202 100644
--- a/crypto/openssl/ssl/ssl_err.c
+++ b/crypto/openssl/ssl/ssl_err.c
@@ -78,6 +78,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "DO_DTLS1_WRITE"},
{ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"},
{ERR_FUNC(SSL_F_DTLS1_ACCEPT), "DTLS1_ACCEPT"},
+{ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"},
{ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"},
{ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"},
{ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"},
@@ -86,6 +87,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "DTLS1_GET_MESSAGE"},
{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"},
{ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"},
+{ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"},
{ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"},
{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
@@ -131,6 +133,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "SSL2_SET_CERTIFICATE"},
{ERR_FUNC(SSL_F_SSL2_WRITE), "SSL2_WRITE"},
{ERR_FUNC(SSL_F_SSL3_ACCEPT), "SSL3_ACCEPT"},
+{ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"},
{ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"},
{ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"},
{ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"},
@@ -171,9 +174,11 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"},
{ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"},
{ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"},
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), "SSL_ADD_CLIENTHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), "SSL_add_dir_cert_subjects_to_stack"},
{ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), "SSL_add_file_cert_subjects_to_stack"},
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), "SSL_ADD_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"},
{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"},
@@ -215,6 +220,10 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"},
{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"},
{ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"},
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), "SSL_PARSE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), "SSL_PARSE_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"},
{ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), "SSL_PREPARE_CLIENTHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), "SSL_PREPARE_SERVERHELLO_TLSEXT"},
@@ -317,6 +326,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"},
+{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"},
{ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID),"duplicate compression id"},
{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
@@ -384,6 +394,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
{ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
{ERR_REASON(SSL_R_NO_PUBLICKEY) ,"no publickey"},
+{ERR_REASON(SSL_R_NO_RENEGOTIATION) ,"no renegotiation"},
{ERR_REASON(SSL_R_NO_SHARED_CIPHER) ,"no shared cipher"},
{ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) ,"no verify callback"},
{ERR_REASON(SSL_R_NULL_SSL_CTX) ,"null ssl ctx"},
@@ -411,10 +422,14 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH),"record length mismatch"},
{ERR_REASON(SSL_R_RECORD_TOO_LARGE) ,"record too large"},
{ERR_REASON(SSL_R_RECORD_TOO_SMALL) ,"record too small"},
+{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG),"renegotiate ext too long"},
+{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"},
+{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"},
{ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"},
{ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"},
{ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"},
{ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"},
+{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
@@ -484,6 +499,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),"unknown remote error type"},
{ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION) ,"unknown ssl version"},
{ERR_REASON(SSL_R_UNKNOWN_STATE) ,"unknown state"},
+{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"},
{ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
{ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
{ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"},
diff --git a/crypto/openssl/ssl/ssl_lib.c b/crypto/openssl/ssl/ssl_lib.c
index 893abff..15650da 100644
--- a/crypto/openssl/ssl/ssl_lib.c
+++ b/crypto/openssl/ssl/ssl_lib.c
@@ -508,7 +508,6 @@ void SSL_free(SSL *s)
if (s->cert != NULL) ssl_cert_free(s->cert);
/* Free up if allocated */
- if (s->ctx) SSL_CTX_free(s->ctx);
#ifndef OPENSSL_NO_TLSEXT
if (s->tlsext_hostname)
OPENSSL_free(s->tlsext_hostname);
@@ -526,6 +525,8 @@ void SSL_free(SSL *s)
if (s->method != NULL) s->method->ssl_free(s);
+ if (s->ctx) SSL_CTX_free(s->ctx);
+
#ifndef OPENSSL_NO_KRB5
if (s->kssl_ctx != NULL)
kssl_ctx_free(s->kssl_ctx);
@@ -986,8 +987,12 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
case SSL_CTRL_OPTIONS:
return(s->options|=larg);
+ case SSL_CTRL_CLEAR_OPTIONS:
+ return(s->options&=~larg);
case SSL_CTRL_MODE:
return(s->mode|=larg);
+ case SSL_CTRL_CLEAR_MODE:
+ return(s->mode &=~larg);
case SSL_CTRL_GET_MAX_CERT_LIST:
return(s->max_cert_list);
case SSL_CTRL_SET_MAX_CERT_LIST:
@@ -995,12 +1000,17 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
s->max_cert_list=larg;
return(l);
case SSL_CTRL_SET_MTU:
- if (SSL_version(s) == DTLS1_VERSION)
+ if (SSL_version(s) == DTLS1_VERSION ||
+ SSL_version(s) == DTLS1_BAD_VER)
{
s->d1->mtu = larg;
return larg;
}
return 0;
+ case SSL_CTRL_GET_RI_SUPPORT:
+ if (s->s3)
+ return s->s3->send_connection_binding;
+ else return 0;
default:
return(s->method->ssl_ctrl(s,cmd,larg,parg));
}
@@ -1087,8 +1097,12 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg)
return(ctx->stats.sess_cache_full);
case SSL_CTRL_OPTIONS:
return(ctx->options|=larg);
+ case SSL_CTRL_CLEAR_OPTIONS:
+ return(ctx->options&=~larg);
case SSL_CTRL_MODE:
return(ctx->mode|=larg);
+ case SSL_CTRL_CLEAR_MODE:
+ return(ctx->mode&=~larg);
default:
return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
}
@@ -1285,6 +1299,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
p+=j;
}
+ /* If p == q, no ciphers and caller indicates an error. Otherwise
+ * add SCSV if not renegotiating.
+ */
+ if (p != q && !s->new_session)
+ {
+ static SSL_CIPHER scsv =
+ {
+ 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
+ };
+ j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
+ p+=j;
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "SCSV sent by client\n");
+#endif
+ }
+
return(p-q);
}
@@ -1294,6 +1324,8 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *sk;
int i,n;
+ if (s->s3)
+ s->s3->send_connection_binding = 0;
n=ssl_put_cipher_by_char(s,NULL,NULL);
if ((num%n) != 0)
@@ -1311,6 +1343,26 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
for (i=0; i<num; i+=n)
{
+ /* Check for SCSV */
+ if (s->s3 && (n != 3 || !p[0]) &&
+ (p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
+ (p[n-1] == (SSL3_CK_SCSV & 0xff)))
+ {
+ /* SCSV fatal if renegotiating */
+ if (s->new_session)
+ {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+ goto err;
+ }
+ s->s3->send_connection_binding = 1;
+ p += n;
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "SCSV received by server\n");
+#endif
+ continue;
+ }
+
c=ssl_get_cipher_by_char(s,p);
p+=n;
if (c != NULL)
@@ -1546,6 +1598,10 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
}
#endif
#endif
+ /* Default is to connect to non-RI servers. When RI is more widely
+ * deployed might change this.
+ */
+ ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
return(ret);
err:
diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h
index ed4ddbb..e305db4 100644
--- a/crypto/openssl/ssl/ssl_locl.h
+++ b/crypto/openssl/ssl/ssl_locl.h
@@ -694,7 +694,7 @@ SSL_METHOD *func_name(void) \
dtls1_read_bytes, \
dtls1_write_app_data_bytes, \
dtls1_dispatch_alert, \
- ssl3_ctrl, \
+ dtls1_ctrl, \
ssl3_ctx_ctrl, \
ssl3_get_cipher_by_char, \
ssl3_put_cipher_by_char, \
@@ -789,7 +789,7 @@ int ssl3_send_change_cipher_spec(SSL *s,int state_a,int state_b);
int ssl3_change_cipher_state(SSL *s,int which);
void ssl3_cleanup_key_block(SSL *s);
int ssl3_do_write(SSL *s,int type);
-void ssl3_send_alert(SSL *s,int level, int desc);
+int ssl3_send_alert(SSL *s,int level, int desc);
int ssl3_generate_master_secret(SSL *s, unsigned char *out,
unsigned char *p, int len);
int ssl3_get_req_cert_type(SSL *s,unsigned char *p);
@@ -862,13 +862,21 @@ int dtls1_read_failed(SSL *s, int code);
int dtls1_buffer_message(SSL *s, int ccs);
int dtls1_retransmit_message(SSL *s, unsigned short seq,
unsigned long frag_off, int *found);
+int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
+int dtls1_retransmit_buffered_messages(SSL *s);
void dtls1_clear_record_buffer(SSL *s);
void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr);
void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
void dtls1_reset_seq_numbers(SSL *s, int rw);
long dtls1_default_timeout(void);
+struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
+int dtls1_handle_timeout(SSL *s);
SSL_CIPHER *dtls1_get_cipher(unsigned int u);
-
+void dtls1_start_timer(SSL *s);
+void dtls1_stop_timer(SSL *s);
+int dtls1_is_timer_expired(SSL *s);
+void dtls1_double_timeout(SSL *s);
+int dtls1_send_newsession_ticket(SSL *s);
/* some client-only functions */
@@ -885,6 +893,9 @@ int ssl3_send_client_key_exchange(SSL *s);
int ssl3_get_key_exchange(SSL *s);
int ssl3_get_server_certificate(SSL *s);
int ssl3_check_cert_and_algorithm(SSL *s);
+#ifndef OPENSSL_NO_TLSEXT
+int ssl3_check_finished(SSL *s);
+#endif
int dtls1_client_hello(SSL *s);
int dtls1_send_client_certificate(SSL *s);
@@ -968,6 +979,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s);
int ssl_prepare_serverhello_tlsext(SSL *s);
int ssl_check_clienthello_tlsext(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
+
#ifdef OPENSSL_NO_SHA256
#define tlsext_tick_md EVP_sha1
#else
@@ -977,6 +989,15 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
const unsigned char *limit, SSL_SESSION **ret);
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
+
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+ int maxlen);
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+ int *al);
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+ int maxlen);
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+ int *al);
#endif
#endif
diff --git a/crypto/openssl/ssl/ssl_rsa.c b/crypto/openssl/ssl/ssl_rsa.c
index 27113eb..c0960b5 100644
--- a/crypto/openssl/ssl/ssl_rsa.c
+++ b/crypto/openssl/ssl/ssl_rsa.c
@@ -723,7 +723,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
goto end;
}
- x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+ x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
if (x == NULL)
{
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c
index 8391d62..e7802e1 100644
--- a/crypto/openssl/ssl/ssl_sess.c
+++ b/crypto/openssl/ssl/ssl_sess.c
@@ -211,6 +211,11 @@ int ssl_get_new_session(SSL *s, int session)
ss->ssl_version=TLS1_VERSION;
ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
}
+ else if (s->version == DTLS1_BAD_VER)
+ {
+ ss->ssl_version=DTLS1_BAD_VER;
+ ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+ }
else if (s->version == DTLS1_VERSION)
{
ss->ssl_version=DTLS1_VERSION;
@@ -418,7 +423,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
p=buf;
l=ret->cipher_id;
l2n(l,p);
- if ((ret->ssl_version>>8) == SSL3_VERSION_MAJOR)
+ if ((ret->ssl_version>>8) >= SSL3_VERSION_MAJOR)
ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
else
ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
diff --git a/crypto/openssl/ssl/ssl_stat.c b/crypto/openssl/ssl/ssl_stat.c
index 73b0250..e7509f0 100644
--- a/crypto/openssl/ssl/ssl_stat.c
+++ b/crypto/openssl/ssl/ssl_stat.c
@@ -198,6 +198,12 @@ case SSL23_ST_SR_CLNT_HELLO_A: str="SSLv2/v3 read client hello A"; break;
case SSL23_ST_SR_CLNT_HELLO_B: str="SSLv2/v3 read client hello B"; break;
#endif
+/* DTLS */
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DTLS1 read hello verify request A"; break;
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DTLS1 read hello verify request B"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: str="DTLS1 write hello verify request A"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: str="DTLS1 write hello verify request B"; break;
+
default: str="unknown state"; break;
}
return(str);
@@ -345,6 +351,11 @@ case SSL23_ST_CR_SRVR_HELLO_B: str="23RSHA"; break;
case SSL23_ST_SR_CLNT_HELLO_A: str="23RCHA"; break;
case SSL23_ST_SR_CLNT_HELLO_B: str="23RCHB"; break;
#endif
+/* DTLS */
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DRCHVA"; break;
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DRCHVB"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: str="DWCHVA"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: str="DWCHVB"; break;
default: str="UNKWN "; break;
}
diff --git a/crypto/openssl/ssl/ssl_txt.c b/crypto/openssl/ssl/ssl_txt.c
index 06b8675..81c1361 100644
--- a/crypto/openssl/ssl/ssl_txt.c
+++ b/crypto/openssl/ssl/ssl_txt.c
@@ -91,6 +91,10 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
s="SSLv3";
else if (x->ssl_version == TLS1_VERSION)
s="TLSv1";
+ else if (x->ssl_version == DTLS1_VERSION)
+ s="DTLSv1";
+ else if (x->ssl_version == DTLS1_BAD_VER)
+ s="DTLSv1-bad";
else
s="unknown";
if (BIO_printf(bp," Protocol : %s\n",s) <= 0) goto err;
@@ -174,11 +178,11 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
ssl_cipher_get_evp(x,NULL,NULL,&comp);
if (comp == NULL)
{
- if (BIO_printf(bp,"\n Compression: %d",x->compress_meth) <= 0) goto err;
+ if (BIO_printf(bp,"\n Compression: %d",x->compress_meth) <= 0) goto err;
}
else
{
- if (BIO_printf(bp,"\n Compression: %d (%s)", comp->id,comp->method->name) <= 0) goto err;
+ if (BIO_printf(bp,"\n Compression: %d (%s)", comp->id,comp->method->name) <= 0) goto err;
}
}
#endif
diff --git a/crypto/openssl/ssl/t1_enc.c b/crypto/openssl/ssl/t1_enc.c
index 7cb3e29..dab6e44 100644
--- a/crypto/openssl/ssl/t1_enc.c
+++ b/crypto/openssl/ssl/t1_enc.c
@@ -765,10 +765,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL);
- if (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER)
+ if (ssl->version == DTLS1_BAD_VER ||
+ (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER))
{
unsigned char dtlsseq[8],*p=dtlsseq;
-
s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
memcpy (p,&seq[2],6);
@@ -793,7 +793,7 @@ printf("rec=");
{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
#endif
- if ( SSL_version(ssl) != DTLS1_VERSION)
+ if ( SSL_version(ssl) != DTLS1_VERSION && SSL_version(ssl) != DTLS1_BAD_VER)
{
for (i=7; i>=0; i--)
{
diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c
index 9ce7269..8b53112 100644
--- a/crypto/openssl/ssl/t1_lib.c
+++ b/crypto/openssl/ssl/t1_lib.c
@@ -133,6 +133,11 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
int extdatalen=0;
unsigned char *ret = p;
+ /* don't add extensions for SSLv3 unless doing secure renegotiation */
+ if (s->client_version == SSL3_VERSION
+ && !s->s3->send_connection_binding)
+ return p;
+
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
@@ -169,11 +174,37 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret+=size_str;
}
-
+
+ /* Add RI if renegotiating */
+ if (s->new_session)
+ {
+ int el;
+
+ if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ if((limit - p - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+
+ if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ ret += el;
+ }
+
+
if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
{
int ticklen;
- if (s->session && s->session->tlsext_tick)
+ if (!s->new_session && s->session && s->session->tlsext_tick)
ticklen = s->session->tlsext_ticklen;
else
ticklen = 0;
@@ -191,7 +222,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
}
- if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
+ if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
+ s->version != DTLS1_VERSION)
{
int i;
long extlen, idlen, itmp;
@@ -251,6 +283,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
int extdatalen=0;
unsigned char *ret = p;
+ /* don't add extensions for SSLv3, unless doing secure renegotiation */
+ if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
+ return p;
+
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
@@ -261,6 +297,30 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
s2n(TLSEXT_TYPE_server_name,ret);
s2n(0,ret);
}
+
+ if(s->s3->send_connection_binding)
+ {
+ int el;
+
+ if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ if((limit - p - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+
+ if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ ret += el;
+ }
if (s->tlsext_ticket_expected
&& !(SSL_get_options(s) & SSL_OP_NO_TICKET))
@@ -290,15 +350,18 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
unsigned short size;
unsigned short len;
unsigned char *data = *p;
+ int renegotiate_seen = 0;
+
s->servername_done = 0;
s->tlsext_status_type = -1;
if (data >= (d+n-2))
- return 1;
+ goto ri_check;
+
n2s(data,len);
if (data > (d+n-len))
- return 1;
+ goto ri_check;
while (data <= (d+n-4))
{
@@ -306,7 +369,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
n2s(data,size);
if (data+size > (d+n))
- return 1;
+ goto ri_check;
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 0, type, data, size,
@@ -407,8 +470,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
}
- else if (type == TLSEXT_TYPE_status_request
- && s->ctx->tlsext_status_cb)
+ else if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+ return 0;
+ renegotiate_seen = 1;
+ }
+ else if (type == TLSEXT_TYPE_status_request &&
+ s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
{
if (size < 5)
@@ -507,12 +576,26 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
else
s->tlsext_status_type = -1;
}
+
/* session ticket processed earlier */
data+=size;
}
-
*p = data;
+
+ ri_check:
+
+ /* Need RI if renegotiating */
+
+ if (!renegotiate_seen && s->new_session &&
+ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ {
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
+ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ return 0;
+ }
+
return 1;
}
@@ -522,11 +605,11 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
unsigned short size;
unsigned short len;
unsigned char *data = *p;
-
int tlsext_servername = 0;
+ int renegotiate_seen = 0;
if (data >= (d+n-2))
- return 1;
+ goto ri_check;
n2s(data,len);
@@ -536,7 +619,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
n2s(data,size);
if (data+size > (d+n))
- return 1;
+ goto ri_check;
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 1, type, data, size,
@@ -561,7 +644,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
s->tlsext_ticket_expected = 1;
}
- else if (type == TLSEXT_TYPE_status_request)
+ else if (type == TLSEXT_TYPE_status_request &&
+ s->version != DTLS1_VERSION)
{
/* MUST be empty and only sent if we've requested
* a status request message.
@@ -574,7 +658,12 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
/* Set flag to expect CertificateStatus message */
s->tlsext_status_expected = 1;
}
-
+ else if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+ return 0;
+ renegotiate_seen = 1;
+ }
data+=size;
}
@@ -606,6 +695,26 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
*p = data;
+
+ ri_check:
+
+ /* Determine if we need to see RI. Strictly speaking if we want to
+ * avoid an attack we should *always* see RI even on initial server
+ * hello because the client doesn't see any renegotiation during an
+ * attack. However this would mean we could not connect to any server
+ * which doesn't support RI so for the immediate future tolerate RI
+ * absence on initial connect only.
+ */
+ if (!renegotiate_seen
+ && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
+ && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ {
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
+ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ return 0;
+ }
+
return 1;
}
@@ -745,6 +854,14 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
return 1;
if (p >= limit)
return -1;
+ /* Skip past DTLS cookie */
+ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
+ {
+ i = *(p++);
+ p+= i;
+ if (p >= limit)
+ return -1;
+ }
/* Skip past cipher list */
n2s(p, i);
p+= i;
@@ -795,16 +912,17 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
HMAC_CTX hctx;
EVP_CIPHER_CTX ctx;
+ SSL_CTX *tctx = s->initial_ctx;
/* Need at least keyname + iv + some encrypted data */
if (eticklen < 48)
goto tickerr;
/* Initialize session ticket encryption and HMAC contexts */
HMAC_CTX_init(&hctx);
EVP_CIPHER_CTX_init(&ctx);
- if (s->ctx->tlsext_ticket_key_cb)
+ if (tctx->tlsext_ticket_key_cb)
{
unsigned char *nctick = (unsigned char *)etick;
- int rv = s->ctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
+ int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
&ctx, &hctx, 0);
if (rv < 0)
return -1;
@@ -816,12 +934,12 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
else
{
/* Check key name matches */
- if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
+ if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
goto tickerr;
- HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- s->ctx->tlsext_tick_aes_key, etick + 16);
+ tctx->tlsext_tick_aes_key, etick + 16);
}
/* Attempt to process session ticket, first conduct sanity and
* integrity checks on ticket.
diff --git a/crypto/openssl/ssl/t1_reneg.c b/crypto/openssl/ssl/t1_reneg.c
new file mode 100644
index 0000000..9c2cc3c
--- /dev/null
+++ b/crypto/openssl/ssl/t1_reneg.c
@@ -0,0 +1,292 @@
+/* ssl/t1_reneg.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2009 The OpenSSL Project. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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 product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+/* Add the client's renegotiation binding */
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+ int maxlen)
+ {
+ if(p)
+ {
+ if((s->s3->previous_client_finished_len+1) > maxlen)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
+ return 0;
+ }
+
+ /* Length byte */
+ *p = s->s3->previous_client_finished_len;
+ p++;
+
+ memcpy(p, s->s3->previous_client_finished,
+ s->s3->previous_client_finished_len);
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "%s RI extension sent by client\n",
+ s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
+#endif
+ }
+
+ *len=s->s3->previous_client_finished_len + 1;
+
+
+ return 1;
+ }
+
+/* Parse the client's renegotiation binding and abort if it's not
+ right */
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+ int *al)
+ {
+ int ilen;
+
+ /* Parse the length byte */
+ if(len < 1)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ ilen = *d;
+ d++;
+
+ /* Consistency check */
+ if((ilen+1) != len)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+
+ /* Check that the extension matches */
+ if(ilen != s->s3->previous_client_finished_len)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+ *al=SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+
+ if(memcmp(d, s->s3->previous_client_finished,
+ s->s3->previous_client_finished_len))
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+ *al=SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "%s RI extension received by server\n",
+ ilen ? "Non-empty" : "Empty");
+#endif
+
+ s->s3->send_connection_binding=1;
+
+ return 1;
+ }
+
+/* Add the server's renegotiation binding */
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+ int maxlen)
+ {
+ if(p)
+ {
+ if((s->s3->previous_client_finished_len +
+ s->s3->previous_server_finished_len + 1) > maxlen)
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
+ return 0;
+ }
+
+ /* Length byte */
+ *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
+ p++;
+
+ memcpy(p, s->s3->previous_client_finished,
+ s->s3->previous_client_finished_len);
+ p += s->s3->previous_client_finished_len;
+
+ memcpy(p, s->s3->previous_server_finished,
+ s->s3->previous_server_finished_len);
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "%s RI extension sent by server\n",
+ s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
+#endif
+ }
+
+ *len=s->s3->previous_client_finished_len
+ + s->s3->previous_server_finished_len + 1;
+
+ return 1;
+ }
+
+/* Parse the server's renegotiation binding and abort if it's not
+ right */
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+ int *al)
+ {
+ int expected_len=s->s3->previous_client_finished_len
+ + s->s3->previous_server_finished_len;
+ int ilen;
+
+ /* Check for logic errors */
+ OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
+ OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
+
+ /* Parse the length byte */
+ if(len < 1)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ ilen = *d;
+ d++;
+
+ /* Consistency check */
+ if(ilen+1 != len)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+
+ /* Check that the extension matches */
+ if(ilen != expected_len)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+ *al=SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+
+ if(memcmp(d, s->s3->previous_client_finished,
+ s->s3->previous_client_finished_len))
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+ *al=SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+ d += s->s3->previous_client_finished_len;
+
+ if(memcmp(d, s->s3->previous_server_finished,
+ s->s3->previous_server_finished_len))
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "%s RI extension received by client\n",
+ ilen ? "Non-empty" : "Empty");
+#endif
+ s->s3->send_connection_binding=1;
+
+ return 1;
+ }
diff --git a/crypto/openssl/ssl/tls1.h b/crypto/openssl/ssl/tls1.h
index 2d1d293..afe4807 100644
--- a/crypto/openssl/ssl/tls1.h
+++ b/crypto/openssl/ssl/tls1.h
@@ -115,6 +115,9 @@ extern "C" {
#define TLSEXT_TYPE_ec_point_formats 11
#define TLSEXT_TYPE_session_ticket 35
+/* Temporary extension type */
+#define TLSEXT_TYPE_renegotiate 0xff01
+
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
/* status request value from RFC 3546 */
@@ -169,9 +172,9 @@ SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
- SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLXEXT_TICKET_KEYS,(keylen),(keys))
+ SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
- SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLXEXT_TICKET_KEYS,(keylen),(keys))
+ SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))
#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
diff --git a/crypto/openssl/test/Makefile b/crypto/openssl/test/Makefile
index 228ee36..0b3b3e8 100644
--- a/crypto/openssl/test/Makefile
+++ b/crypto/openssl/test/Makefile
@@ -402,13 +402,13 @@ FIPS_BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
if [ "$(FIPSCANLIB)" = "libfips" ]; then \
LIBRARIES="-L$(TOP) -lfips"; \
elif [ -n "$(FIPSCANLIB)" ]; then \
- FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
+ FIPSLD_CC="$(CC)"; CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
LIBRARIES="$${FIPSLIBDIR:-$(TOP)/fips/}fipscanister.o"; \
else \
LIBRARIES="$(LIBCRYPTO)"; \
fi; \
$(MAKE) -f $(TOP)/Makefile.shared -e \
- CC=$${CC} APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
+ CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
link_app.$${shlib_target}
@@ -417,11 +417,11 @@ FIPS_CRYPTO_BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
fi; \
LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
if [ -z "$(SHARED_LIBS)" -a -n "$(FIPSCANLIB)" ] ; then \
- FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
+ FIPSLD_CC="$(CC)"; CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
fi; \
[ "$(FIPSCANLIB)" = "libfips" ] && LIBRARIES="$$LIBRARIES -lfips"; \
$(MAKE) -f $(TOP)/Makefile.shared -e \
- CC=$${CC} APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
+ CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
link_app.$${shlib_target}
@@ -538,7 +538,7 @@ jpaketest$(EXE_EXT): jpaketest.o $(DLIBCRYPTO)
# fi
dummytest$(EXE_EXT): dummytest.o $(DLIBCRYPTO)
- @target=dummytest$; $(BUILD_CMD)
+ @target=dummytest; $(BUILD_CMD)
# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/crypto/openssl/test/cms-test.pl b/crypto/openssl/test/cms-test.pl
index a84e089..5c87b3a 100755
--- a/crypto/openssl/test/cms-test.pl
+++ b/crypto/openssl/test/cms-test.pl
@@ -58,6 +58,9 @@ my $ossl_path;
if ( -f "../apps/openssl" ) {
$ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
}
+elsif ( -f "../apps/openssl.exe" ) {
+ $ossl_path = "../util/shlib_wrap.sh ../apps/openssl.exe";
+}
elsif ( -f "..\\out32dll\\openssl.exe" ) {
$ossl_path = "..\\out32dll\\openssl.exe";
}
@@ -232,7 +235,7 @@ my @smime_cms_tests = (
[
"signed content MIME format, RSA key, signed receipt request",
"-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
- . " -receipt_request_to test@openssl.org -receipt_request_all"
+ . " -receipt_request_to test\@openssl.org -receipt_request_all"
. " -out test.cms",
"-verify -in test.cms "
. " -CAfile $smdir/smroot.pem -out smtst.txt"
diff --git a/crypto/openssl/util/domd b/crypto/openssl/util/domd
index 560ebea..112044c 100755
--- a/crypto/openssl/util/domd
+++ b/crypto/openssl/util/domd
@@ -14,7 +14,7 @@ if [ "$MAKEDEPEND" = "" ]; then MAKEDEPEND=makedepend; fi
cp Makefile Makefile.save
# fake the presence of Kerberos
touch $TOP/krb5.h
-if [ "$MAKEDEPEND" = "gcc" ]; then
+if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then
args=""
while [ $# -gt 0 ]; do
if [ "$1" != "--" ]; then args="$args $1"; fi
diff --git a/crypto/openssl/util/libeay.num b/crypto/openssl/util/libeay.num
index 74eb337..21f4a8f 100755
--- a/crypto/openssl/util/libeay.num
+++ b/crypto/openssl/util/libeay.num
@@ -1255,8 +1255,8 @@ PKCS12_gen_mac 1278 EXIST::FUNCTION:
PKCS12_verify_mac 1279 EXIST::FUNCTION:
PKCS12_set_mac 1280 EXIST::FUNCTION:
PKCS12_setup_mac 1281 EXIST::FUNCTION:
-asc2uni 1282 EXIST::FUNCTION:
-uni2asc 1283 EXIST::FUNCTION:
+asc2uni 1282 EXIST:!NETWARE:FUNCTION:
+uni2asc 1283 EXIST:!NETWARE:FUNCTION:
i2d_PKCS12_BAGS 1284 EXIST::FUNCTION:
PKCS12_BAGS_new 1285 EXIST::FUNCTION:
d2i_PKCS12_BAGS 1286 EXIST::FUNCTION:
@@ -2869,8 +2869,8 @@ PROXY_POLICY_free 3308 EXIST::FUNCTION:
PROXY_POLICY_new 3309 EXIST::FUNCTION:
BN_MONT_CTX_set_locked 3310 EXIST::FUNCTION:
FIPS_selftest_rng 3311 EXIST:OPENSSL_FIPS:FUNCTION:
-EVP_sha384 3312 EXIST::FUNCTION:SHA,SHA512
-EVP_sha512 3313 EXIST::FUNCTION:SHA,SHA512
+EVP_sha384 3312 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+EVP_sha512 3313 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
EVP_sha224 3314 EXIST::FUNCTION:SHA,SHA256
EVP_sha256 3315 EXIST::FUNCTION:SHA,SHA256
FIPS_selftest_hmac 3316 EXIST:OPENSSL_FIPS:FUNCTION:
@@ -2917,7 +2917,7 @@ EC_KEY_new_by_curve_name 3353 EXIST::FUNCTION:EC
STORE_method_get_update_store_function 3354 EXIST:!VMS:FUNCTION:
STORE_meth_get_update_store_fn 3354 EXIST:VMS:FUNCTION:
ENGINE_register_ECDH 3355 EXIST::FUNCTION:ENGINE
-SHA512_Update 3356 EXIST::FUNCTION:SHA,SHA512
+SHA512_Update 3356 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
i2d_ECPrivateKey 3357 EXIST::FUNCTION:EC
BN_get0_nist_prime_192 3358 EXIST::FUNCTION:
STORE_modify_certificate 3359 EXIST::FUNCTION:
@@ -3128,7 +3128,7 @@ POLICY_CONSTRAINTS_new 3547 EXIST::FUNCTION:
BN_GF2m_mod_sqrt 3548 EXIST::FUNCTION:
ECDH_set_default_method 3549 EXIST::FUNCTION:ECDH
EC_KEY_generate_key 3550 EXIST::FUNCTION:EC
-SHA384_Update 3551 EXIST::FUNCTION:SHA,SHA512
+SHA384_Update 3551 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
BN_GF2m_arr2poly 3552 EXIST::FUNCTION:
STORE_method_get_get_function 3553 EXIST::FUNCTION:
STORE_method_set_cleanup_function 3554 EXIST:!VMS:FUNCTION:
@@ -3161,7 +3161,7 @@ STORE_store_public_key 3577 EXIST::FUNCTION:
X509_CERT_PAIR_free 3578 EXIST::FUNCTION:
STORE_revoke_private_key 3579 EXIST::FUNCTION:
BN_nist_mod_224 3580 EXIST::FUNCTION:
-SHA512_Final 3581 EXIST::FUNCTION:SHA,SHA512
+SHA512_Final 3581 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
STORE_ATTR_INFO_modify_dn 3582 EXIST::FUNCTION:
STORE_method_get_initialise_function 3583 EXIST:!VMS:FUNCTION:
STORE_meth_get_initialise_fn 3583 EXIST:VMS:FUNCTION:
@@ -3220,7 +3220,7 @@ STORE_method_get_delete_function 3630 EXIST:!VMS:FUNCTION:
STORE_meth_get_delete_fn 3630 EXIST:VMS:FUNCTION:
SHA224_Init 3631 EXIST::FUNCTION:SHA,SHA256
PEM_read_ECPrivateKey 3632 EXIST:!WIN16:FUNCTION:EC
-SHA512_Init 3633 EXIST::FUNCTION:SHA,SHA512
+SHA512_Init 3633 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
STORE_parse_attrs_endp 3634 EXIST::FUNCTION:
BN_set_negative 3635 EXIST::FUNCTION:
ERR_load_ECDSA_strings 3636 EXIST::FUNCTION:ECDSA
@@ -3259,13 +3259,13 @@ EC_KEY_set_enc_flags 3665 EXIST::FUNCTION:EC
ECDSA_verify 3666 EXIST::FUNCTION:ECDSA
EC_POINT_point2hex 3667 EXIST::FUNCTION:EC
ENGINE_get_STORE 3668 EXIST::FUNCTION:ENGINE
-SHA512 3669 EXIST::FUNCTION:SHA,SHA512
+SHA512 3669 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
STORE_get_certificate 3670 EXIST::FUNCTION:
ECDSA_do_sign_ex 3671 EXIST::FUNCTION:ECDSA
ECDSA_do_verify 3672 EXIST::FUNCTION:ECDSA
d2i_ECPrivateKey_fp 3673 EXIST::FUNCTION:EC,FP_API
STORE_delete_certificate 3674 EXIST::FUNCTION:
-SHA512_Transform 3675 EXIST::FUNCTION:SHA,SHA512
+SHA512_Transform 3675 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
X509_STORE_set1_param 3676 EXIST::FUNCTION:
STORE_method_get_ctrl_function 3677 EXIST::FUNCTION:
STORE_free 3678 EXIST::FUNCTION:
@@ -3331,16 +3331,16 @@ d2i_ECParameters 3733 EXIST::FUNCTION:EC
STORE_list_certificate_end 3734 EXIST::FUNCTION:
STORE_get_crl 3735 EXIST::FUNCTION:
X509_POLICY_NODE_print 3736 EXIST::FUNCTION:
-SHA384_Init 3737 EXIST::FUNCTION:SHA,SHA512
+SHA384_Init 3737 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
EC_GF2m_simple_method 3738 EXIST::FUNCTION:EC
ECDSA_set_ex_data 3739 EXIST::FUNCTION:ECDSA
-SHA384_Final 3740 EXIST::FUNCTION:SHA,SHA512
+SHA384_Final 3740 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
PKCS7_set_digest 3741 EXIST::FUNCTION:
EC_KEY_print 3742 EXIST::FUNCTION:BIO,EC
STORE_method_set_lock_store_function 3743 EXIST:!VMS:FUNCTION:
STORE_meth_set_lock_store_fn 3743 EXIST:VMS:FUNCTION:
ECDSA_get_ex_new_index 3744 EXIST::FUNCTION:ECDSA
-SHA384 3745 EXIST::FUNCTION:SHA,SHA512
+SHA384 3745 EXIST:!VMSVAX:FUNCTION:SHA,SHA512
POLICY_MAPPING_new 3746 EXIST::FUNCTION:
STORE_list_certificate_endp 3747 EXIST::FUNCTION:
X509_STORE_CTX_get0_policy_tree 3748 EXIST::FUNCTION:
@@ -3657,7 +3657,7 @@ ENGINE_set_ld_ssl_clnt_cert_fn 4044 EXIST:VMS:FUNCTION:ENGINE
ENGINE_get_ssl_client_cert_function 4045 EXIST:!VMS:FUNCTION:ENGINE
ENGINE_get_ssl_client_cert_fn 4045 EXIST:VMS:FUNCTION:ENGINE
ENGINE_load_ssl_client_cert 4046 EXIST::FUNCTION:ENGINE
-ENGINE_load_capi 4047 EXIST::FUNCTION:CAPIENG,ENGINE
+ENGINE_load_capi 4047 EXIST:WIN32:FUNCTION:CAPIENG,ENGINE
OPENSSL_isservice 4048 EXIST::FUNCTION:
FIPS_dsa_sig_decode 4049 EXIST:OPENSSL_FIPS:FUNCTION:DSA
EVP_CIPHER_CTX_clear_flags 4050 EXIST::FUNCTION:
@@ -3725,3 +3725,6 @@ JPAKE_STEP2_release 4110 EXIST::FUNCTION:JPAKE
JPAKE_STEP3A_init 4111 EXIST::FUNCTION:JPAKE
ERR_load_JPAKE_strings 4112 EXIST::FUNCTION:JPAKE
JPAKE_STEP2_init 4113 EXIST::FUNCTION:JPAKE
+pqueue_size 4114 EXIST::FUNCTION:
+OPENSSL_uni2asc 4115 EXIST:NETWARE:FUNCTION:
+OPENSSL_asc2uni 4116 EXIST:NETWARE:FUNCTION:
diff --git a/crypto/openssl/util/mk1mf.pl b/crypto/openssl/util/mk1mf.pl
index f2b92b2..a21f6f4 100755
--- a/crypto/openssl/util/mk1mf.pl
+++ b/crypto/openssl/util/mk1mf.pl
@@ -863,7 +863,8 @@ foreach (values %lib_nam)
}
# hack to add version info on MSVC
-if (($platform eq "VC-WIN32") || ($platform eq "VC-NT")) {
+if (($platform eq "VC-WIN32") || ($platform eq "VC-WIN64A")
+ || ($platform eq "VC-WIN64I") || ($platform eq "VC-NT")) {
$rules.= <<"EOF";
\$(OBJ_D)\\\$(CRYPTO).res: ms\\version32.rc
\$(RSC) /fo"\$(OBJ_D)\\\$(CRYPTO).res" /d CRYPTO ms\\version32.rc
@@ -1142,7 +1143,7 @@ sub do_defs
$ret.=$t;
}
# hack to add version info on MSVC
- if ($shlib && (($platform eq "VC-WIN32") || ($platform eq "VC-NT")))
+ if ($shlib && (($platform eq "VC-WIN32") || ($platfrom eq "VC-WIN64I") || ($platform eq "VC-WIN64A") || ($platform eq "VC-NT")))
{
if ($var eq "CRYPTOOBJ")
{ $ret.="\$(OBJ_D)\\\$(CRYPTO).res "; }
diff --git a/crypto/openssl/util/mkdef.pl b/crypto/openssl/util/mkdef.pl
index 5ae9ebb..93dd251 100755
--- a/crypto/openssl/util/mkdef.pl
+++ b/crypto/openssl/util/mkdef.pl
@@ -69,7 +69,7 @@ my $do_ctestall = 0;
my $do_checkexist = 0;
my $VMSVAX=0;
-my $VMSAlpha=0;
+my $VMSNonVAX=0;
my $VMS=0;
my $W32=0;
my $W16=0;
@@ -78,7 +78,7 @@ my $OS2=0;
# Set this to make typesafe STACK definitions appear in DEF
my $safe_stack_def = 0;
-my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
+my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT", "NETWARE",
"EXPORT_VAR_AS_FUNCTION", "ZLIB", "OPENSSL_FIPS");
my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
@@ -141,9 +141,9 @@ foreach (@ARGV, split(/ /, $options))
$VMS=1;
$VMSVAX=1;
}
- if ($_ eq "VMS-Alpha") {
+ if ($_ eq "VMS-NonVAX") {
$VMS=1;
- $VMSAlpha=1;
+ $VMSNonVAX=1;
}
$VMS=1 if $_ eq "VMS";
$OS2=1 if $_ eq "OS2";
@@ -962,6 +962,19 @@ sub do_defs
$platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
$platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
+ $platform{"EVP_sha384"} = "!VMSVAX";
+ $platform{"EVP_sha512"} = "!VMSVAX";
+ $platform{"SHA384_Init"} = "!VMSVAX";
+ $platform{"SHA384_Transform"} = "!VMSVAX";
+ $platform{"SHA384_Update"} = "!VMSVAX";
+ $platform{"SHA384_Final"} = "!VMSVAX";
+ $platform{"SHA384"} = "!VMSVAX";
+ $platform{"SHA512_Init"} = "!VMSVAX";
+ $platform{"SHA512_Transform"} = "!VMSVAX";
+ $platform{"SHA512_Update"} = "!VMSVAX";
+ $platform{"SHA512_Final"} = "!VMSVAX";
+ $platform{"SHA512"} = "!VMSVAX";
+
# Info we know about
push @ret, map { $_."\\".&info_string($_,"EXIST",
@@ -1086,6 +1099,8 @@ sub is_valid
if ($platforms) {
# platforms
if ($keyword eq "VMS" && $VMS) { return 1; }
+ if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
+ if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
if ($keyword eq "WIN32" && $W32) { return 1; }
if ($keyword eq "WIN16" && $W16) { return 1; }
if ($keyword eq "WINNT" && $NT) { return 1; }
diff --git a/crypto/openssl/util/mkerr.pl b/crypto/openssl/util/mkerr.pl
index 554bebb..5d2f218 100644
--- a/crypto/openssl/util/mkerr.pl
+++ b/crypto/openssl/util/mkerr.pl
@@ -313,7 +313,7 @@ foreach $lib (keys %csrc)
} else {
push @out,
"/* ====================================================================\n",
-" * Copyright (c) 2001-2008 The OpenSSL Project. All rights reserved.\n",
+" * Copyright (c) 2001-2010 The OpenSSL Project. All rights reserved.\n",
" *\n",
" * Redistribution and use in source and binary forms, with or without\n",
" * modification, are permitted provided that the following conditions\n",
@@ -487,7 +487,7 @@ EOF
print OUT <<"EOF";
/* $cfile */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2010 The OpenSSL Project. 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/crypto/openssl/util/pl/Mingw32.pl b/crypto/openssl/util/pl/Mingw32.pl
index 6ea5179..8f0483f 100644
--- a/crypto/openssl/util/pl/Mingw32.pl
+++ b/crypto/openssl/util/pl/Mingw32.pl
@@ -1,5 +1,4 @@
#!/usr/local/bin/perl
-# $FreeBSD$
#
# Mingw32.pl -- Mingw
#
diff --git a/crypto/openssl/util/pl/VC-32.pl b/crypto/openssl/util/pl/VC-32.pl
index 85121c8..ed4a3f9 100644
--- a/crypto/openssl/util/pl/VC-32.pl
+++ b/crypto/openssl/util/pl/VC-32.pl
@@ -27,6 +27,10 @@ $rm='del /Q';
$zlib_lib="zlib1.lib";
+# Santize -L options for ms link
+$l_flags =~ s/-L("\[^"]+")/\/libpath:$1/g;
+$l_flags =~ s/-L(\S+)/\/libpath:$1/g;
+
# C compiler stuff
$cc='cl';
if ($FLAVOR =~ /WIN64/)
@@ -145,6 +149,18 @@ if ($no_sock) { $ex_libs=''; }
elsif ($FLAVOR =~ /CE/) { $ex_libs='winsock.lib'; }
else { $ex_libs='wsock32.lib'; }
+my $oflow;
+
+
+if ($FLAVOR =~ /WIN64/ and `cl 2>&1` =~ /14\.00\.4[0-9]{4}\./)
+ {
+ $oflow=' bufferoverflowu.lib';
+ }
+else
+ {
+ $oflow="";
+ }
+
if ($FLAVOR =~ /CE/)
{
$ex_libs.=' $(WCECOMPAT)/lib/wcecompatex.lib';
@@ -153,7 +169,8 @@ if ($FLAVOR =~ /CE/)
else
{
$ex_libs.=' gdi32.lib crypt32.lib advapi32.lib user32.lib';
- $ex_libs.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/);
+ $ex_libs.= $oflow;
+
}
# As native NT API is pure UNICODE, our WIN-NT build defaults to UNICODE,
@@ -338,7 +355,7 @@ sub do_lib_rule
if ($name eq "")
{
- $ex.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/);
+ $ex.= $oflow;
if ($target =~ /capi/)
{
$ex.=' crypt32.lib advapi32.lib';
@@ -353,7 +370,7 @@ sub do_lib_rule
$ex.=' unicows.lib' if ($FLAVOR =~ /NT/);
$ex.=' wsock32.lib gdi32.lib advapi32.lib user32.lib';
$ex.=' crypt32.lib';
- $ex.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/);
+ $ex.= $oflow;
}
$ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
diff --git a/crypto/openssl/util/pod2man.pl b/crypto/openssl/util/pod2man.pl
index 546d1ec..025d914 100755
--- a/crypto/openssl/util/pod2man.pl
+++ b/crypto/openssl/util/pod2man.pl
@@ -425,7 +425,7 @@ if ($name ne 'something') {
}
next if /^=cut\b/; # DB_File and Net::Ping have =cut before NAME
next if /^=pod\b/; # It is OK to have =pod before NAME
- next if /^=for\s+comment\b/; # It is OK to have =for comment before NAME
+ next if /^=(for|begin|end)\s+comment\b/; # It is OK to have =for =begin or =end comment before NAME
die "$0: Invalid man page - 1st pod line is not NAME in $ARGV[0]\n" unless $lax;
}
die "$0: Invalid man page - no documentation in $ARGV[0]\n" unless $lax;
diff --git a/crypto/openssl/util/shlib_wrap.sh b/crypto/openssl/util/shlib_wrap.sh
index a2f62d6..d744ff3 100755
--- a/crypto/openssl/util/shlib_wrap.sh
+++ b/crypto/openssl/util/shlib_wrap.sh
@@ -80,7 +80,7 @@ if [ -f "$LIBCRYPTOSO" -a -z "$preload_var" ]; then
# it into a script makes it possible to do so on multi-ABI
# platforms.
case "$SYSNAME" in
- *BSD) LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;; # *BSD
+ *BSD|QNX) LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;; # *BSD, QNX
*) LD_PRELOAD="$LIBCRYPTOSO $LIBSSLSO" ;; # SunOS, Linux, ELF HP-UX
esac
_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT" # Tru64, o32 IRIX
diff --git a/etc/Makefile b/etc/Makefile
index 42221a8..d8619af 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -18,7 +18,7 @@ BIN1= auth.conf \
rc rc.bsdextended rc.firewall rc.initdiskless \
rc.sendmail rc.shutdown \
rc.subr remote rpc services shells \
- sysctl.conf syslog.conf
+ sysctl.conf syslog.conf termcap.small
.if exists(${.CURDIR}/etc.${MACHINE}/ttys)
BIN1+= etc.${MACHINE}/ttys
@@ -161,6 +161,9 @@ distribution:
${BIN2} ${DESTDIR}/etc; \
${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \
master.passwd nsmb.conf opieaccess ${DESTDIR}/etc;
+.if ${MK_AT} == "no"
+ sed -i "" -e 's;.*/usr/libexec/atrun;#&;' ${DESTDIR}/etc/crontab
+.endif
.if ${MK_TCSH} == "no"
sed -i "" -e 's;/bin/csh;/bin/sh;' ${DESTDIR}/etc/master.passwd
.endif
diff --git a/etc/defaults/periodic.conf b/etc/defaults/periodic.conf
index b454838..de315ae 100644
--- a/etc/defaults/periodic.conf
+++ b/etc/defaults/periodic.conf
@@ -46,7 +46,7 @@ daily_clean_tmps_enable="NO" # Delete stuff daily
daily_clean_tmps_dirs="/tmp" # Delete under here
daily_clean_tmps_days="3" # If not accessed for
daily_clean_tmps_ignore=".X*-lock .X11-unix .ICE-unix .font-unix .XIM-unix"
-daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group"
+daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group .snap"
# Don't delete these
daily_clean_tmps_verbose="YES" # Mention files deleted
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 35b3a7b..63c94bb 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -210,6 +210,8 @@ cloned_interfaces="" # List of cloned network interfaces to create.
ifconfig_lo0="inet 127.0.0.1" # default loopback device configuration.
#ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry.
#ifconfig_ed0_ipx="ipx 0x00010010" # Sample IPX address family entry.
+#ifconfig_ed0_ipv6="RTADV" # Sample IPv6 entry for RA/rtsol(8)
+#ifconfig_ed0_ipv6="inet6 auto_linklocal" # To configure only link-local
#ifconfig_ed0_ipv6="inet6 2001:db8:1::1 prefixlen 64" # Sample IPv6 addr entry
#ifconfig_ed0_alias0="inet6 2001:db8:2::1 prefixlen 64" # Sample IPv6 alias
#ifconfig_fxp0_name="net0" # Change interface name from fxp0 to net0.
@@ -435,12 +437,18 @@ rfcomm_pppd_server_two_channel="3" # Override local channel for 'two'
#rfcomm_pppd_server_two_register_sp="NO" # Override SP and DUN register
#rfcomm_pppd_server_two_register_dun="NO" # for 'two'
+ubthidhci_enable="NO" # Switch an USB BT controller present on
+#ubthidhci_busnum="3" # bus 3 and addr 2 from HID mode to HCI mode.
+#ubthidhci_addr="2" # Check usbconfig list to find the correct
+ # numbers for your system.
+
### Miscellaneous network options: ###
icmp_bmcastecho="NO" # respond to broadcast ping packets
### IPv6 options: ###
-ipv6_network_interfaces="none" # List of IPv6 network interfaces
- # (or "auto" or "none").
+ipv6_network_interfaces="AUTO" # List of IPv6 network interfaces
+ipv6_prefer="YES" # Use IPv6 when both IPv4 and IPv6 can be used
+ipv6_privacy="NO" # Use privacy addresses with RTADV (RFC 4193)
ipv6_defaultrouter="NO" # Set to IPv6 default gateway (or NO).
#ipv6_defaultrouter="2002:c058:6301::" # Use this for 6to4 (RFC 3068)
ipv6_static_routes="" # Set to static route list (or leave empty).
@@ -462,8 +470,8 @@ route6d_flags="" # Flags to IPv6 routing daemon.
#ipv6_prefix_ed0="fec0:0000:0000:0001 fec0:0000:0000:0002" # Examples for rtr.
#ipv6_prefix_ep0="fec0:0000:0000:0003 fec0:0000:0000:0004" # Examples for rtr.
ipv6_default_interface="NO" # Default output interface for scoped addrs.
- # Now this works only for IPv6 link local
- # multicast addrs.
+ # This works only with
+ # ipv6_gateway_enable="NO".
rtsol_flags="" # Flags to IPv6 router solicitation.
rtsold_enable="NO" # Set to YES to enable an IPv6 router
# solicitation daemon.
@@ -499,7 +507,6 @@ ipv6_ipfilter_rules="/etc/ipf6.rules" # rules definition file for ipfilter,
# for examples
ip6addrctl_enable="YES" # Set to YES to enable default address selection
ip6addrctl_verbose="NO" # Set to YES to enable verbose configuration messages
-ipv6_prefer="NO" # Use IPv6 when both IPv4 and IPv6 can be used
##############################################################
### System console options #################################
@@ -637,6 +644,7 @@ mixer_enable="YES" # Run the sound mixer.
### Jail Configuration #######################################
##############################################################
jail_enable="NO" # Set to NO to disable starting of any jails
+jail_parallel_start="NO" # Start jails in the background
jail_list="" # Space separated list of names of jails
jail_set_hostname_allow="YES" # Allow root user in a jail to change its hostname
jail_socket_unixiproute_only="YES" # Route only TCP/IP within a jail
diff --git a/etc/devd.conf b/etc/devd.conf
index 696ac7c..8827e3b 100644
--- a/etc/devd.conf
+++ b/etc/devd.conf
@@ -138,12 +138,14 @@ attach 100 {
# This entry starts the ColdSync tool in daemon mode. Make sure you have an up
# to date /usr/local/etc/palms. We override the 'listen' settings for port and
# type in /usr/local/etc/coldsync.conf.
-attach 100 {
- device-name "ugen[0-9]+";
- match "vendor" "0x082d";
- match "product" "0x0100";
- match "release" "0x0100";
- action "/usr/local/bin/coldsync -md -p /dev/$device-name -t usb";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x082d";
+ match "product" "0x0100";
+ match "release" "0x0100";
+ action "/usr/local/bin/coldsync -md -p /dev/$cdev -t usb";
};
#
diff --git a/etc/devd/uath.conf b/etc/devd/uath.conf
index 33bee69..dc4019c 100644
--- a/etc/devd/uath.conf
+++ b/etc/devd/uath.conf
@@ -4,117 +4,143 @@
# Accton
# SMCWUSB-G and SMCWUSBT-G2
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x083a";
- match "product" "(0x4505|0x4507)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x083a";
+ match "product" "(0x4505|0x4507)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Atheros Communications
# AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x168c";
- match "product" "0x0002";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x168c";
+ match "product" "0x0002";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Atheros Communications
# AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x0cf3";
- match "product" "(0x0002|0x0004|0x0006)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x0cf3";
+ match "product" "(0x0002|0x0004|0x0006)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Conceptronic
# AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x0d8e";
- match "product" "(0x7802|0x7812)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x0d8e";
+ match "product" "(0x7802|0x7812)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# D-Link
# DWL-AG132, DWL-G132 and DWL-AG122
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x2001";
- match "product" "(0x3a01|0x3a03|0x3a05)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x2001";
+ match "product" "(0x3a01|0x3a03|0x3a05)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# D-Link
# DWA-120
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x07d1";
- match "product" "0x3a0c";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x07d1";
+ match "product" "0x3a0c";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Gigaset
# SMCWUSBT-G
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x1690";
- match "product" "(0x0711|0x0713)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x1690";
+ match "product" "(0x0711|0x0713)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Global Sun Technology
# AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x16ab";
- match "product" "(0x7802|0x7812)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x16ab";
+ match "product" "(0x7802|0x7812)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# BayNETGEAR
# WG111U
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x0846";
- match "product" "0x4301";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x0846";
+ match "product" "0x4301";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Netgear
# WG111T and WPN111
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x1385";
- match "product" "(0x4251|0x5f01)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x1385";
+ match "product" "(0x4251|0x5f01)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# U-MEDIA Communications
# TEW-444UB and AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x157e";
- match "product" "(0x3007|0x3206)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x157e";
+ match "product" "(0x3007|0x3206)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Wistron NeWeb
# AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x1435";
- match "product" "(0x0827|0x0829)";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x1435";
+ match "product" "(0x0827|0x0829)";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
# Z-Com
# AR5523
-attach 100 {
- device-name "ugen[0-9.]+";
- match "vendor" "0x0cde";
- match "product" "0x0013";
- action "/usr/sbin/uathload -d /dev/$device-name";
+notify 100 {
+ match "system" "USB";
+ match "subsystem" "DEVICE";
+ match "type" "ATTACH";
+ match "vendor" "0x0cde";
+ match "product" "0x0013";
+ action "/usr/sbin/uathload -d /dev/$cdev";
};
diff --git a/etc/inetd.conf b/etc/inetd.conf
index bbc21df..8b8e604 100644
--- a/etc/inetd.conf
+++ b/etc/inetd.conf
@@ -16,8 +16,8 @@
#shell stream tcp6 nowait root /usr/libexec/rshd rshd
#login stream tcp nowait root /usr/libexec/rlogind rlogind
#login stream tcp6 nowait root /usr/libexec/rlogind rlogind
-#finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -s
-#finger stream tcp6 nowait/3/10 nobody /usr/libexec/fingerd fingerd -s
+#finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
+#finger stream tcp6 nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
#
# run comsat as root to be able to print partial mailbox contents w/ biff,
# or use the safer tty:tty to just print that new mail has been received.
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index 7824011..1ec7171 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -104,8 +104,8 @@
..
lmc
..
- mfi
- ..
+ mfi
+ ..
mpt
mpilib
..
diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
index 87f7ca3..da3ad54 100644
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -219,6 +219,8 @@
..
ibcs2
..
+ indent
+ ..
ipfilter
..
ipfw
diff --git a/etc/network.subr b/etc/network.subr
index fbf3ff9..52c99db 100644
--- a/etc/network.subr
+++ b/etc/network.subr
@@ -96,44 +96,32 @@ ifconfig_up()
# inet6 specific
if afexists inet6; then
if ipv6if $1; then
- if checkyesno ipv6_gateway_enable; then
- _ipv6_opts="-accept_rtadv"
- fi
- else
- if checkyesno ipv6_prefer; then
- _ipv6_opts="-ifdisabled"
- else
- _ipv6_opts="ifdisabled"
+ # Implicitly handles ipv6_gateway_enable
+ _ipv6_opts='-ifdisabled -accept_rtadv'
+
+ if ipv6_autoconfif $1; then
+ _ipv6_opts='-ifdisabled accept_rtadv'
fi
- # backward compatibility: $ipv6_enable
- case $ipv6_enable in
- [Yy][Ee][Ss])
- _ipv6_opts="${_ipv6_opts} accept_rtadv"
- ;;
- esac
- fi
+ ifconfig $1 inet6 $_ipv6_opts
- if [ -n "${_ipv6_opts}" ]; then
- ifconfig $1 inet6 ${_ipv6_opts}
- fi
+ # ifconfig_IF_ipv6
+ ifconfig_args=`ifconfig_getargs $1 ipv6`
- # ifconfig_IF_ipv6
- ifconfig_args=`ifconfig_getargs $1 ipv6`
- if [ -n "${ifconfig_args}" ]; then
- ifconfig $1 inet6 -ifdisabled
- ifconfig $1 ${ifconfig_args}
- _cfg=0
- fi
+ if [ -n "$ifconfig_args" ]; then
+ ifconfig $1 $ifconfig_args
+ _cfg=0
+ fi
+ else
+ # Remove in FreeBSD 10.x
+ # Explicit test is necessary here to avoid nonexistence error
+ case "$ipv6_enable" in
+ [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+ warn "Interface $1 will NOT be configured for IPv6"
+ ;;
+ esac
- # backward compatiblity: $ipv6_ifconfig_IF
- ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF`
- if [ -n "${ifconfig_args}" ]; then
- warn "\$ipv6_ifconfig_$1 is obsolete." \
- " Use ifconfig_$1_ipv6 instead."
- ifconfig $1 inet6 -ifdisabled
- ifconfig $1 inet6 ${ifconfig_args}
- _cfg=0
+ ifconfig $1 inet6 ifdisabled
fi
fi
@@ -194,7 +182,7 @@ ifconfig_down()
# $default if given.
get_if_var()
{
- local _if _punct _var _default prefix suffix
+ local _if _punct _punct_c _var _default prefix suffix
if [ $# -ne 2 -a $# -ne 3 ]; then
err 3 'USAGE: get_if_var name var [default]'
@@ -219,7 +207,7 @@ get_if_var()
# outside this file.
_ifconfig_getargs()
{
- local _ifn _af
+ local _ifn _af value
_ifn=$1
_af=${2+_$2}
@@ -227,7 +215,18 @@ _ifconfig_getargs()
return 1
fi
- get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT"
+ value=`get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT"`
+
+ # Remove in FreeBSD 10.x
+ if [ "$_af" = _ipv6 -a -z "$value" ]; then
+ value=`get_if_var $_ifn ipv6_ifconfig_IF "$ifconfig_DEFAULT"`
+ if [ -n "$value" ]; then
+ warn "\$ipv6_ifconfig_$1 is obsolete." \
+ " Use ifconfig_$1_ipv6 instead."
+ fi
+ fi
+
+ echo $value
}
# ifconfig_getargs if [af]
@@ -249,6 +248,8 @@ ifconfig_getargs()
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
[Ww][Pp][Aa]) ;;
+ [Rr][Tt][Aa][Dd][Vv]) ;;
+ [Nn][Oo][Rr][Tt][Aa][Dd][Vv]) ;;
*)
_args="$_args $_arg"
;;
@@ -372,77 +373,45 @@ afexists()
esac
}
-# noafif if
-# Returns 0 if the interface has no af configuration and 1 otherwise.
-noafif()
-{
- local _if
- _if=$1
-
- case $_if in
- pflog[0-9]*|\
- pfsync[0-9]*|\
- an[0-9]*|\
- ath[0-9]*|\
- ipw[0-9]*|\
- iwi[0-9]*|\
- iwn[0-9]*|\
- ral[0-9]*|\
- wi[0-9]*|\
- wl[0-9]*|\
- wpi[0-9]*)
- return 0
- ;;
- esac
-
- return 1
-}
-
# ipv6if if
# Returns 0 if the interface should be configured for IPv6 and
# 1 otherwise.
ipv6if()
{
- local _if _tmpargs i
- _if=$1
-
if ! afexists inet6; then
return 1
fi
# lo0 is always IPv6-enabled
- case $_if in
+ case $1 in
lo0)
return 0
;;
esac
- # True if $ifconfig_IF_ipv6 is defined.
- _tmpargs=`_ifconfig_getargs $_if ipv6`
- if [ -n "${_tmpargs}" ]; then
- return 0
- fi
-
- # backward compatibility: True if $ipv6_ifconfig_IF is defined.
- _tmpargs=`get_if_var $_if ipv6_ifconfig_IF`
- if [ -n "${_tmpargs}" ]; then
- return 0
- fi
+ local _if _tmpargs i
+ _if=$1
- case "${ipv6_network_interfaces}" in
- [Aa][Uu][Tt][Oo])
- return 0
- ;;
+ case "$ipv6_network_interfaces" in
''|[Nn][Oo][Nn][Ee])
return 1
;;
+ $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
+ # True if $ifconfig_IF_ipv6 is defined.
+ _tmpargs=`_ifconfig_getargs $_if ipv6`
+ ;;
esac
- for i in ${ipv6_network_interfaces}; do
- if [ "$i" = "$_if" ]; then
- return 0
- fi
- done
+ if [ -n "$_tmpargs" ]; then
+ # Remove in FreeBSD 10.x
+ # Explicit test is necessary here to avoid nonexistence error
+ case "$ipv6_enable" in
+ [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
+ ;;
+ *) return 0
+ ;;
+ esac
+ fi
return 1
}
@@ -452,15 +421,24 @@ ipv6if()
# Stateless Address Configuration, 1 otherwise.
ipv6_autoconfif()
{
+ case $1 in
+ lo0|\
+ stf[0-9]*|\
+ faith[0-9]*|\
+ lp[0-9]*|\
+ sl[0-9]*|\
+ pflog[0-9]*|\
+ pfsync[0-9]*)
+ return 1
+ ;;
+ esac
+
local _if _tmpargs _arg
_if=$1
if ! ipv6if $_if; then
return 1
fi
- if noafif $_if; then
- return 1
- fi
if checkyesno ipv6_gateway_enable; then
return 1
fi
@@ -468,45 +446,24 @@ ipv6_autoconfif()
if [ -n "${_tmpargs}" ]; then
return 1
fi
+ if ! is_wired_interface $_if; then
+ case $_if in
+ wlan[0-9]*) ;; # Allow test to continue
+ *) return 1
+ ;;
+ esac
+ fi
- case $_if in
- lo0|\
- stf[0-9]*|\
- faith[0-9]*|\
- lp[0-9]*|\
- sl[0-9]*|\
- pflog[0-9]*|\
- pfsync[0-9]*)
+ _tmpargs=`_ifconfig_getargs $_if ipv6`
+ case "$_tmpargs" in
+ *inet6\ *|*[Nn][Oo][Rr][Tt][Aa][Dd][Vv]*|*-accept_rtadv*)
return 1
;;
- esac
-
- # backward compatibility: $ipv6_enable
- case $ipv6_enable in
- [Yy][Ee][Ss])
+ *[Rr][Tt][Aa][Dd][Vv]*|*accept_rtadv*)
return 0
;;
esac
- _tmpargs=`_ifconfig_getargs $_if ipv6`
- for _arg in $_tmpargs; do
- case $_arg in
- accept_rtadv)
- return 0
- ;;
- esac
- done
-
- # backward compatibility: $ipv6_ifconfig_IF
- _tmpargs=`get_if_var $_if ipv6_ifconfig_IF`
- for _arg in $_tmpargs; do
- case $_arg in
- accept_rtadv)
- return 0
- ;;
- esac
- done
-
return 1
}
diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
index 17f7634..802d717 100755
--- a/etc/rc.d/Makefile
+++ b/etc/rc.d/Makefile
@@ -50,6 +50,10 @@ FILES+= sshd
FILES+= nscd
.endif
+.if ${MK_BLUETOOTH} != "no"
+FILES+= ubthidhci
+.endif
+
FILESDIR= /etc/rc.d
FILESMODE= ${BINMODE}
diff --git a/etc/rc.d/ip6addrctl b/etc/rc.d/ip6addrctl
index d3b1856..3963b07 100755
--- a/etc/rc.d/ip6addrctl
+++ b/etc/rc.d/ip6addrctl
@@ -20,8 +20,6 @@ status_cmd="ip6addrctl"
prefer_ipv6_cmd="ip6addrctl_prefer_ipv6"
prefer_ipv4_cmd="ip6addrctl_prefer_ipv4"
-set_rcvar_obsolete ipv6_enable ipv6_prefer
-
ip6addrctl_prefer_ipv6()
{
afexists inet6 || return 0
diff --git a/etc/rc.d/jail b/etc/rc.d/jail
index 084acb7..70e151d 100755
--- a/etc/rc.d/jail
+++ b/etc/rc.d/jail
@@ -18,6 +18,8 @@
name="jail"
rcvar=`set_rcvar`
+
+start_precmd="jail_prestart"
start_cmd="jail_start"
stop_cmd="jail_stop"
@@ -545,6 +547,13 @@ jail_ips()
done
}
+jail_prestart()
+{
+ if checkyesno jail_parallel_start; then
+ command_args='&'
+ fi
+}
+
jail_start()
{
echo -n 'Configuring jails:'
@@ -636,7 +645,8 @@ jail_start()
done
eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \
- \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1
+ \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 \
+ </dev/null
if [ "$?" -eq 0 ] ; then
_jail_id=$(head -1 ${_tmp_jail})
@@ -728,4 +738,5 @@ fi
if [ -n "$*" ]; then
jail_list="$*"
fi
-run_rc_command "${cmd}" &
+
+run_rc_command "${cmd}"
diff --git a/etc/rc.d/netif b/etc/rc.d/netif
index f982cfc..06b8e76 100755
--- a/etc/rc.d/netif
+++ b/etc/rc.d/netif
@@ -34,6 +34,7 @@
. /etc/network.subr
name="network"
+start_precmd="network_prestart"
start_cmd="network_start"
stop_cmd="network_stop"
cloneup_cmd="clone_up"
@@ -41,7 +42,13 @@ clonedown_cmd="clone_down"
extra_commands="cloneup clonedown"
cmdifn=
-set_rcvar_obsolete ipv6_enable ipv6_prefer
+network_prestart()
+{
+ if [ -n "$ipv6_enable" ]; then
+ warn 'The ipv6_enable option is deprecated.'
+ warn 'See rc.conf(5) for information on disabling IPv6.'
+ fi
+}
network_start()
{
diff --git a/etc/rc.d/netoptions b/etc/rc.d/netoptions
index 4631304..433ce82 100755
--- a/etc/rc.d/netoptions
+++ b/etc/rc.d/netoptions
@@ -99,6 +99,13 @@ netoptions_inet6()
else
${SYSCTL_W} net.inet6.ip6.v6only=1 >/dev/null
fi
+
+ if checkyesno ipv6_privacy; then
+ netoptions_init
+ echo -n " IPv6 Privacy Addresses"
+ ${SYSCTL_W} net.inet6.ip6.use_tempaddr=1 >/dev/null
+ ${SYSCTL_W} net.inet6.ip6.prefer_tempaddr=1 >/dev/null
+ fi
}
load_rc_config $name
diff --git a/etc/rc.d/routing b/etc/rc.d/routing
index befceca..30242fc 100755
--- a/etc/rc.d/routing
+++ b/etc/rc.d/routing
@@ -210,34 +210,24 @@ static_inet6()
;;
esac
- # Disallow unicast packets without outgoing scope identifiers,
- # or route such packets to a "default" interface, if it is specified.
+ # Disallow link-local unicast packets without outgoing scope
+ # identifiers. However, if you set "ipv6_default_interface",
+ # for the host case, you will allow to omit the identifiers.
+ # Under this configuration, the packets will go to the default
+ # interface.
route ${_action} -inet6 fe80:: -prefixlen 10 ::1 -reject
+ route ${_action} -inet6 ff02:: -prefixlen 16 ::1 -reject
case ${ipv6_default_interface} in
'')
- route ${_action} -inet6 ff02:: -prefixlen 16 ::1 -reject
;;
*)
- laddr=`network6_getladdr ${ipv6_default_interface}`
- route ${_action} -inet6 ff02:: ${laddr} -prefixlen 16 -interface
-
- # Disable installing the default interface with the
- # case net.inet6.ip6.forwarding=0 and
- # the interface with no ND6_IFF_ACCEPT_RTADV
- # to avoid conflict between the default router list and
- # the manual configured default route.
+ # Disable installing the default interface when we act
+ # as router to avoid conflict between the default
+ # router list and the manual configured default route.
if ! checkyesno ipv6_gateway_enable; then
- ifconfig ${ipv6_default_interface} nd6 | \
- while read proto options
- do
- case "${proto}:${options}" in
- nd6:*ACCEPT_RTADV*)
- ifconfig ${ipv6_default_interface} inet6 defaultif
- break
- ;;
- esac
- done
+ ifconfig ${ipv6_default_interface} inet6 defaultif
+ sysctl net.inet6.ip6.use_defaultzone=1
fi
;;
esac
diff --git a/etc/rc.d/tmp b/etc/rc.d/tmp
index abf53ac..282709e 100755
--- a/etc/rc.d/tmp
+++ b/etc/rc.d/tmp
@@ -51,8 +51,8 @@ case "${tmpmfs}" in
[Nn][Oo])
;;
*)
- if /bin/mkdir -p /tmp/.diskless 2> /dev/null; then
- rmdir /tmp/.diskless
+ if _tmpdir=$(mktemp -d -q /tmp/.diskless.XXXXXX); then
+ rmdir ${_tmpdir}
else
if [ -h /tmp ]; then
echo "*** /tmp is a symlink to a non-writable area!"
diff --git a/etc/rc.d/ubthidhci b/etc/rc.d/ubthidhci
new file mode 100755
index 0000000..67d7346
--- /dev/null
+++ b/etc/rc.d/ubthidhci
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: ubthidhci
+# REQUIRE: DAEMON
+# BEFORE: bluetooth
+# KEYWORD: nojail shutdown
+
+. /etc/rc.subr
+
+name="ubthidhci"
+command="/usr/sbin/usbconfig"
+rcvar=`set_rcvar`
+start_precmd="ubthidhci_prestart"
+
+ubthidhci_prestart()
+{
+
+ if [ -z ${ubthidhci_busnum} ]; then
+ warn ubthidhci_busnum is not set
+ return 1
+ fi
+ if [ -z ${ubthidhci_addr} ]; then
+ warn ubthidhci_addr is not set
+ return 1
+ fi
+}
+
+load_rc_config $name
+#
+# We discard the output because:
+# 1) we don't want it to show up during boot; and
+# 2) the request usually returns an error, but that doesn't mean it failed
+#
+# NB: 0x40 is UT_VENDOR
+command_args="-u ${ubthidhci_busnum} -a ${ubthidhci_addr} do_request 0x40 0 0 0 0 > /dev/null 2>&1"
+
+run_rc_command "$1"
diff --git a/etc/rc.firewall b/etc/rc.firewall
index 7034359..cda7c34 100644
--- a/etc/rc.firewall
+++ b/etc/rc.firewall
@@ -424,24 +424,21 @@ case ${firewall_type} in
# Configuration:
# firewall_myservices: List of TCP ports on which this host
# offers services.
- # firewall_allowservices: List of IPs which has access to
+ # firewall_allowservices: List of IPv4 and/or IPv6 addresses
+ # that have access to
# $firewall_myservices.
- # firewall_trusted: List of IPv4s which has full access
- # to this host. Be very carefull
- # when setting this. This option can
- # seriously degrade the level of
- # protection provided by the firewall.
+ # firewall_trusted: List of IPv4 and/or IPv6 addresses
+ # that have full access to this host.
+ # Be very careful when setting this.
+ # This option can seriously degrade
+ # the level of protection provided by
+ # the firewall.
# firewall_logdeny: Boolean (YES/NO) specifying if the
# default denied packets should be
# logged (in /var/log/security).
# firewall_nologports: List of TCP/UDP ports for which
# denied incomming packets are not
# logged.
- # firewall_trusted_ipv6: List of IPv6s which has full access
- # to this host. Be very carefull
- # when setting this. This option can
- # seriously degrade the level of
- # protection provided by the firewall.
# Allow packets for which a state has been built.
${fwcmd} add check-state
diff --git a/etc/rc.subr b/etc/rc.subr
index 0c28f2d..397af1d 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -355,6 +355,8 @@ _find_processes()
#
wait_for_pids()
{
+ local _list _prefix _nlist _j
+
_list="$@"
if [ -z "$_list" ]; then
return
@@ -365,6 +367,7 @@ wait_for_pids()
for _j in $_list; do
if kill -0 $_j 2>/dev/null; then
_nlist="${_nlist}${_nlist:+ }$_j"
+ [ -n "$_prefix" ] && sleep 1
fi
done
if [ -z "$_nlist" ]; then
@@ -373,7 +376,7 @@ wait_for_pids()
_list=$_nlist
echo -n ${_prefix:-"Waiting for PIDS: "}$_list
_prefix=", "
- pwait $_list 2>/dev/null || sleep 2
+ pwait $_list 2>/dev/null
done
if [ -n "$_prefix" ]; then
echo "."
@@ -643,12 +646,12 @@ run_rc_command()
if [ "$_elem" != "$rc_arg" ]; then
continue
fi
- # if ${rcvar} is set, and $1 is not
- # "rcvar", then run
+ # if ${rcvar} is set, $1 is not "rcvar"
+ # and ${rc_pid} is not set, then run
# checkyesno ${rcvar}
# and return if that failed
#
- if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then
+ if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" -a -z "${rc_pid}" ]; then
if ! checkyesno ${rcvar}; then
if [ -n "${rc_quiet}" ]; then
return 0
diff --git a/etc/termcap.small b/etc/termcap.small
index 916e31c..8dde6e8 100644
--- a/etc/termcap.small
+++ b/etc/termcap.small
@@ -203,93 +203,46 @@ cons60l7|cons60-iso8859-7:\
:li#60:tc=cons25l7:
cons60l7-m|cons60-iso8859-7-mono:\
:li#60:tc=cons25l7-m:
-#
-dosansi|ANSI.SYS standard crt:\
- :am:bs:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:co#80:\
- :do=\E[B:li#25:mi:nd=\E[C:\
- :se=\E[m:so=\E[7m:up=\E[A:us=\E[4m:ue=\E[m:\
- :md=\E[1m:mr=\E[7m:mb=\E[5m:me=\E[m:\
- :kh=\EG:kb=^h:ku=\EH:kd=\EP:kl=\EK:kr=\EM:\
- :k1=\E;:k2=\E<:k3=\E=:k4=\E>:k5=\E?:\
- :k6=\E@:k7=\EA:k8=\EB:k9=\EC:k0=\ED:
-# The following is a version of the ibm-pc entry distributed with PC/IX,
-# (Interactive Systems' System 3 for the Big Blue), modified by Richard
-# McIntosh at UCB/CSM. The :pt: and :uc: have been removed from the original,
-# (the former is untrue, and the latter failed under UCB/man); standout and
-# underline modes have been added. Note: this entry describes the "native"
-# capabilities of the PC monochrome display, without ANY emulation; most
-# communications packages (but NOT PC/IX connect) do some kind of emulation.
-pc|ibmpc|ibm pc PC/IX:\
- :li#24:co#80:am:bs:bw:eo:\
- :cd=\E[J:ce=\E[K:cl=\Ec:cm=\E[%i%2;%2H:do=\E[B:ho=\E[;H:\
- :nd=\E[C:up=\E[A:so=\E[7m:se=\E[0m:us=\E[4m:ue=\E[0m:
-pc3|ibmpc3|IBM PC 386BSD Console:\
- :Co#8:\
- :DO=\E[%dB:\
- :F1=\E[W:\
- :F2=\E[X:\
- :K1=\E[H:\
- :K2=\E[I:\
- :K3=\E[E:\
- :K4=\E[F:\
- :K5=\E[G:\
- :LE=\E[%dD:\
- :RI=\E[%dC:\
- :AB=\E[1;%dx:\
- :AF=\E[2;%dx:\
- :UP=\E[%dA:\
- :ac=l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\305`^Da\260f\370g\361~\371.^Y-^Xh\261i^U0\333y\363z\362:\
- :am:\
- :bl=^G:\
- :bs:\
- :cb=\E[1K:\
- :cd=\E[J:\
- :ce=\E[K:\
- :cl=\E[H\E[J:\
- :cm=\E[%i%d;%dH:\
- :co#80:\
- :cr=^M:\
- :do=\E[B:\
- :ho=\E[H:\
- :is=\E[m:\
- :it#8:\
- :k;=\E[V:\
- :k1=\E[M:\
- :k2=\E[N:\
- :k3=\E[O:\
- :k4=\E[P:\
- :k5=\E[Q:\
- :k6=\E[R:\
- :k7=\E[S:\
- :k8=\E[T:\
- :k9=\E[U:\
- :kD=\177:\
- :@7=\E[F:\
- :kN=\E[G:\
- :kP=\E[I:\
- :kb=\177:\
- :kd=\E[B:\
- :kh=\E[H:\
- :kl=\E[D:\
- :kr=\E[C:\
- :ku=\E[A:\
- :le=^H:\
- :li#25:\
- :ms:\
- :nd=\E[C:\
- :op=\E[x:\
- :pa#64:\
- :rs=\E[m:\
- :se=\E[m:\
- :sf=\E[S:\
- :so=\E[7;1r\E[7m:\
- :sr=\E[T:\
- :ta=^I:\
- :te=\E[m:\
- :ti=\E[m:\
- :up=\E[A:\
- :ut:
+SC|screen|VT 100/ANSI X3.64 virtual terminal:\
+ :am:xn:ms:mi:G0:km:\
+ :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bs:bt=\E[Z:\
+ :cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:ct=\E[3g:\
+ :do=^J:nd=\E[C:pt:rc=\E8:rs=\Ec:sc=\E7:st=\EH:up=\EM:\
+ :le=^H:bl=^G:cr=^M:it#8:ho=\E[H:nw=\EE:ta=^I:is=\E)0:\
+ :li#24:co#80:us=\E[4m:ue=\E[24m:so=\E[3m:se=\E[23m:\
+ :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:sr=\EM:al=\E[L:\
+ :AL=\E[%dL:dl=\E[M:DL=\E[%dM:cs=\E[%i%d;%dr:dc=\E[P:\
+ :DC=\E[%dP:im=\E[4h:ei=\E[4l:IC=\E[%d@:\
+ :ks=\E[?1h\E=:ke=\E[?1l\E>:vb=\Eg:\
+ :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
+ :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:\
+ :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:\
+ :F3=\E[25~:F4=\E[26~:F5=\E[28~:F6=\E[29~:\
+ :F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\
+ :kh=\E[1~:kI=\E[2~:kD=\E[3~:@7=\E[4~:kP=\E[5~:\
+ :kN=\E[6~:eA=\E(B\E)0:as=^N:ae=^O:ti=\E[?1049h:te=\E[?1049l:\
+ :vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l:\
+ :Co#8:pa#64:AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:AX:\
+ :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:
+
+vt100|dec-vt100|vt100-am|vt100am|dec vt100:\
+ :do=2\E[B:co#80:li#24:cl=50\E[H\E[J:sf=2*\ED:\
+ :le=^H:bs:am:cm=5\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
+ :ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
+ :md=2\E[1m:mr=2\E[7m:mb=2\E[5m:me=2\E[m:\
+ :is=\E>\E[?1;3;4;5l\E[?7;8h\E[1;24r\E[24;1H:\
+ :if=/usr/share/tabset/vt100:nw=2\EE:ho=\E[H:\
+ :as=2\E(0:ae=2\E(B:\
+ :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||:\
+ :rs=\E>\E[?1;3;4;5l\E[?7;8h:ks=\E[?1h\E=:ke=\E[?1l\E>:\
+ :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=\177:\
+ :k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOt:\
+ :k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:@8=\EOM:\
+ :K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:pt:sr=2*\EM:xn:\
+ :sc=2\E7:rc=2\E8:cs=5\E[%i%d;%dr:UP=2\E[%dA:DO=2\E[%dB:RI=2\E[%dC:\
+ :LE=2\E[%dD:ct=2\E[3g:st=2\EH:ta=^I:ms:bl=^G:cr=^M:eo:it#8:\
+ :RA=\E[?7l:SA=\E[?7h:po=\E[5i:pf=\E[4i:
# $XTermId: termcap,v 1.78 2009/11/09 00:24:26 tom Exp $
#
@@ -325,3 +278,38 @@ xterm|X11 terminal emulator:\
xterm-clear:\
:te=\E[?1049l:ti=\E[?1049h:\
:tc=xterm-new:
+#
+# This should work for the commonly used "color xterm" variations (XFree86
+# xterm, color_xterm, nxterm, rxvt). Note that it does not set 'bce', so for
+# XFree86 and rxvt, some applications that use colors will be less efficient,
+# and in a few special cases (with "smart" optimization) the wrong color will
+# be painted in spots.
+xterm-color|generic "ANSI" color xterm:\
+ :Co#8:NC@:pa#64:\
+ :AB=\E[4%dm:AF=\E[3%dm:ac=:op=\E[m:tc=xterm-r6:
+#
+# Compatible with the X11R6.3 xterm
+xterm-r6|xterm-old|X11R6 xterm:\
+ :am:bs:km:mi:ms:pt:xn:\
+ :co#80:kn#20:li#24:\
+ :*6=\E[4~:@0=\E[1~:@7=\E[4~:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\
+ :DO=\E[%dB:F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:\
+ :F5=\E[28~:F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:\
+ :FA=\E[34~:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:\
+ :as=^N:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:\
+ :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:eA=\E)0:ei=\E[4l:\
+ :ho=\E[H:im=\E[4h:\
+ :is=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8:\
+ :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\
+ :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:\
+ :kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\EOB:\
+ :ke=\E[?1l\E>:kh=\E[1~:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\
+ :ku=\EOA:md=\E[1m:me=\E[m:ml=\El:mr=\E[7m:mu=\Em:nd=\E[C:\
+ :rc=\E8:rs=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8:\
+ :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:\
+ :ue=\E[m:up=\E[A:us=\E[4m:
+#
+# Add the capability to "clear the screen" after exiting vi, more/less, etc.
+xterm-r6-clear:\
+ :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:ue=\E[m:\
+ :tc=xterm-r6:
diff --git a/games/fortune/Notes b/games/fortune/Notes
index 83b062d..f049391 100644
--- a/games/fortune/Notes
+++ b/games/fortune/Notes
@@ -19,13 +19,13 @@ Warning:
/usr/share/games/fortune. A fortune file has two parts: the source file
(which contains the fortunes themselves) and the data file which describes
the fortunes. The data file always has the same name as the fortune file
-with the string ".dat" concatenated, i.e. "fort" is the standard fortune
-database, and "fort.dat" is the data file which describes it. See
+with the string ".dat" concatenated, i.e. "fortunes" is the standard fortune
+database, and "fortunes.dat" is the data file which describes it. See
strfile(8) for more information on creating the data files.
Fortunes are split into potentially offensive and not potentially
offensive parts. The offensive version of a file has the same name as the
-non-offensive version with "-o" concatenated, i.e. "fort" is the standard
-fortune database, and "fort-o" is the standard offensive database. The
+non-offensive version with "-o" concatenated, i.e. "fortunes" is the standard
+fortune database, and "fortunes-o" is the standard offensive database. The
fortune program automatically assumes that any file with a name ending in
"-o" is potentially offensive, and should therefore only be displayed if
explicitly requested, either with the -o option or by specifying a file name
@@ -42,10 +42,10 @@ MUST be in the potentially offensive database. Fortunes containing any
explicit language (see George Carlin's recent updated list) MUST be in the
potentially offensive database. Political and religious opinions are often
sequestered in the potentially offensive section as well. Anything which
-assumes as a world view blatantly racist, mysogynist (sexist), or homophobic
+assumes as a world view blatantly racist, misogynist (sexist), or homophobic
ideas should not be in either, since they are not really funny unless *you*
-are racist, mysogynist, or homophobic.
- The point of this is that people have should have a reasonable
+are racist, misogynist, or homophobic.
+ The point of this is that people should have a reasonable
expectation that, should they just run "fortune", they will not be offended.
We know that some people take offense at anything, but normal people do have
opinions, too, and have a right not to have their sensibilities offended by
@@ -53,7 +53,7 @@ a program which is supposed to be entertaining. People who run "fortune
-o" or "fortune -a" are saying, in effect, that they are willing to have
their sensibilities tweaked. However, they should not have their personal
worth seriously (i.e., not in jest) assaulted. Jokes which depend for their
-humor on racist, mysogynist, or homophobic stereotypes *do* seriously
+humor on racist, misogynist, or homophobic stereotypes *do* seriously
assault individual personal worth, and in a general entertainment medium
we should be able to get by without it.
diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes
index ceff2a0..7d6fdd5 100644
--- a/games/fortune/datfiles/fortunes
+++ b/games/fortune/datfiles/fortunes
@@ -368,8 +368,10 @@ OR'd together, outta sight!
Double bucky, I'd like a whole word of
Double bucky, I'm happy I heard of
Double bucky, I'd like a whole word of you!
-
- -- (C) 1978 by Guy L. Steele, Jr.
+ -- Guy L. Steele, Jr., (C) 1978
+ (to Nicholas Wirth, who suggested that an extra bit
+ be added to terminal codes on 36-bit machines for use
+ by screen editors.)
%
Hard Copies and Chmod
@@ -834,7 +836,7 @@ would like on it. "Here lies an honest man and a lawyer," responded the
lawyer.
"Sorry, but I can't do that," replied the stonecutter. "In this
state, it's against the law to bury two people in the same grave. However,
-I could put ``here lies an honest lawyer'', if that would be okay."
+I could put `here lies an honest lawyer', if that would be okay."
"But that won't let people know who it is" protested the lawyer.
"Certainly will," retorted the stonecutter. "people will read it
and exclaim, "That's Strange!"
@@ -1146,7 +1148,7 @@ strings of pearls. The spirit and intent of the program should be retained
throughout. There should be neither too little nor too much, neither needless
loops nor useless variables, neither lack of structure nor overwhelming
rigidity.
- A program should follow the 'Law of Least Astonishment'. What is this
+ A program should follow the "Law of Least Astonishment." What is this
law? It is simply that the program should always respond to the user in the
way that astonishes him least.
A program, no matter how complex, should act as a single unit. The
@@ -1161,7 +1163,7 @@ program.
conference and then returned to report to his manager, saying: "What sort
of programmers work for other companies? They behaved badly and were
unconcerned with appearances. Their hair was long and unkempt and their
-clothes were wrinkled and old. They crashed out hospitality suites and they
+clothes were wrinkled and old. They crashed our hospitality suites and they
made rude noises during my presentation."
The manager said: "I should have never sent you to the conference.
Those programmers live beyond the physical world. They consider life absurd,
@@ -1466,7 +1468,7 @@ generalizable.
The general tendency is to over-design the second system, using all
the ideas and frills that were cautiously sidetracked on the first one.
The result, as Ovid says, is a "big pile".
- -- Frederick Brooks, "The Mythical Man Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
%
An eighty-year-old woman is rocking away the afternoon on her
porch when she sees an old, tarnished lamp sitting near the steps. She
@@ -1513,7 +1515,7 @@ over canoe frames, for my people need transportation. We are a fair people,
and we offer you a chance to kill yourself with our ceremonial knife."
The Englishman accepts the knife and yells, "God Save the Queen",
while plunging the knife into his heart.
- The Frenchman removes the knife from the fallen body, and yells,
+ The Frenchman removes the knife from the fallen body, and yells,
"Vive la France", while plunging the knife into his heart.
The American removes the knife from the fallen body, and yells,
while stabbing himself all over his body, "Here's your lousy canoe!"
@@ -1562,7 +1564,7 @@ a postcard?"
"The curious incident of the stable dog in the nighttime."
"But the dog did nothing in the nighttime."
"That was the curious incident."
- -- A. Conan Doyle, "Silver Blaze"
+ -- Sir Arthur Conan Doyle, "Silver Blaze"
%
Approaching the gates of the monastery, Hakuin found Ken the Zen
preaching to a group of disciples.
@@ -1609,8 +1611,8 @@ Los Angeles fainted from hyperoxygenation, and we had to hold his head
under the exhaust of a bus until he revived.
%
Before he became a hermit, Zarathud was a young Priest, and
- took great delight in making fools of his opponents in front of
-his followers.
+took great delight in making fools of his opponents in front of his
+followers.
One day Zarathud took his students to a pleasant pasture and
there he confronted The Sacred Chao while She was contentedly grazing.
"Tell me, you dumb beast," demanded the Priest in his
@@ -1626,7 +1628,7 @@ Chinese ideogram for NO-THING.)
and finds himself no wiser than before," Bokonon tells us. "He is full
of murderous resentment of people who are ignorant without having come
by their ignorance the hard way."
- -- Kurt Vonnegut, "Cat's Cradle"
+ -- Kurt Vonnegut, Jr., "Cat's Cradle"
%
Bubba, Jim Bob, and Leroy were fishing out on the lake last November,
and, when Bubba tipped his head back to empty the Jim Beam, he fell out of the
@@ -1694,7 +1696,7 @@ way I ought to go from here?"
the Cat.
"I don't care much where--" said Alice.
"Then it doesn't matter which way you go," said the Cat.
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
Concerning the war in Vietnam, Senator George Aiken of Vermont noted
in January, 1966, "I'm not very keen for doves or hawks. I think we need more
@@ -1877,7 +1879,7 @@ how to be excellent: "In Search of Excellence", "Finding Excellence",
So the Cleaning Personnel Don't Steal It", etc.
-- Dave Barry, "In Search of Excellence"
%
- Exxon's 'Universe of Energy' tends to the peculiar rather than the
+ Exxon's "Universe of Energy" tends to the peculiar rather than the
humorous ... After [an incomprehensible film montage about wind and sun and
rain and strip mines and] two or three minutes of mechanical confusion, the
seats locomote through a short tunnel filled with clock-work dinosaurs.
@@ -1923,9 +1925,9 @@ of events, there lurks a singular, sinister attitude of mind."
"MINE! HA-HA!"
%
"Found it," the Mouse replied rather crossly:
-"of course you know what 'it' means."
+"of course you know what `it' means."
- "I know what 'it' means well enough, when I find a thing,"
+ "I know what `it' means well enough, when I find a thing,"
said the Duck: "it's generally a frog or a worm.
The question is, what did the archbishop find?"
@@ -1937,15 +1939,15 @@ such as a "pride of lions" or a "gaggle of geese."
One of the professors noticed a group of prostitutes down the block,
and posed the question, "What name would be given to that group?" The four
fell into silence for a moment, as they pondered the possibilities...
- At last, one spoke: "How about 'a Jam of Tarts'?" The others nodded
+ At last, one spoke: "How about `a Jam of Tarts'?" The others nodded
in acknowledgment as they continued to consider the problem. A second
-professor spoke: "I'd suggest 'an Essay of Trollops.'" Again, the others
-nodded. A third spoke: "I propose 'a Flourish of Strumpets.'"
+professor spoke: "I'd suggest `an Essay of Trollops.'" Again, the others
+nodded. A third spoke: "I propose `a Flourish of Strumpets.'"
They continued their walk in silence, until the first professor
remarked to the remaining professor, who was the most senior and learned of
the four, "You haven't suggested a name for our ladies. What are your
thoughts?"
- Replied the fourth professor, "'An Anthology of Prose.'"
+ Replied the fourth professor, "`An Anthology of Prose.'"
%
Fred noticed his roommate had a black eye upon returning from a dance.
"What happened?"
@@ -1958,12 +1960,11 @@ and sarcastic?"
"Of course not," said a sympathetic friend.
"Well," retorted Frank, "neither would Jennifer."
%
- "Gee, Mudhead, everyone at More Science High has an
+ "Gee, Mudhead, everyone at Morse Science High has an
extracurricular activity except you."
"Well, gee, doesn't Louise count?"
"Only to ten, Mudhead."
-
- -- Firesign Theater
+ -- The Firesign Theatre
%
"Gentlemen of the jury," said the defense attorney, now beginning
to warm to his summation, "the real question here before you is, shall this
@@ -2261,7 +2262,7 @@ each other up:
the floor.) S-word. Excuse me. Look, Bob, I'm going to
have to get back to you.
Bob: Fine.
- -- Dave Barry
+ -- Dave Barry, "$#$%#^%!^%&@%@!"
%
"I don't know what you mean by `glory,'" Alice said
Humpty Dumpty smiled contemptuously. "Of course you don't --
@@ -2276,7 +2277,9 @@ less."
so many different things."
"The question is," said Humpty Dumpty, "which is to be master--
that's all."
- -- Lewis Carroll, "Through the Looking Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
I for one cannot protest the recent M.T.A. fare hike and the
accompanying promises that this would in no way improve service. For
@@ -2328,7 +2331,7 @@ operation - namely, to remove those irritant bodies."
"And then he will be sane?"
"Then he will be perfectly sane, and a quite admirable citizen."
"Thank heaven for science!" said old Yacob.
- -- H.G. Wells, "The Country of the Blind"
+ -- H. G. Wells, "The Country of the Blind"
%
"I keep seeing spots in front of my eyes."
"Did you ever see a doctor?"
@@ -2403,7 +2406,7 @@ more simply -- `Never imagine yourself not to be otherwise than what it
might appear to others that what you were or might have been was not
otherwise than what you had been would have appeared to them to be
otherwise.'"
- -- Lewis Carroll, "Alice in Wonderland"
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
I said, "Preacher, give me strength for round 5."
He said, "What you need is to grow up, son."
@@ -2567,7 +2570,7 @@ man. Mud-as-man alone could speak.
"Certainly," said man.
"Then I leave it to you to think of one for all of this," said God.
And He went away.
- -- Kurt Vonnegut, "Between Time and Timbuktu"
+ -- Kurt Vonnegut, Jr., "Between Time and Timbuktu"
%
In the beginning there was data. The data was without form and
null, and darkness was upon the face of the console; and the Spirit of
@@ -2815,7 +2818,7 @@ guzzled in one gulp and then smashed on the bar. He then stood aghast as
the man stuffed the broken bottle in his mouth, munched broken glass and
smacked his lips with relish.
"Can I, ah, uh, get you another, sir?" the drifter stammered.
- "Naw, I gotta git outa here, boy," the man grunted. "Big Mike's
+ "Naw, I gotta git outta here, boy," the man grunted. "Big Mike's
a-comin'."
%
Love's Drug
@@ -3002,7 +3005,7 @@ confirm who I am.
-- Captain Freedom
%
Old Barlow was a crossing-tender at a junction where an express train
-demolished an automobile and it's occupants. Being the chief witness, his
+demolished an automobile and its occupants. Being the chief witness, his
testimony was vitally important. Barlow explained that the night was dark,
and he waved his lantern frantically, but the driver of the car paid
no attention to the signal.
@@ -3072,7 +3075,7 @@ and it was very juicy. I stood up and took aim, and went into the windup,
when my mother at the kitchen window called my name in a sharp voice. I had
to decide quickly. I decided.
A rotten Big Boy hitting the target is a memorable sound, like a fat
-man doing a belly-flop. With a whoop and a yell the tomatoe came after
+man doing a belly-flop. With a whoop and a yell the tomatoee came after me
faster than I knew she could run, and grabbed my shirt and was about to brain
me when Mother called her name in a sharp voice. And my sister, who was a
good person, obeyed and let go -- and burst into tears. I guess she knew that
@@ -3164,7 +3167,7 @@ biggest, strongest fish he had ever caught. He fought with it for hours,
until, finally, he managed to bring it to the surface. Looking of the edge
of the boat, he saw the head of this huge fish breaking the surface. Smiling
with pride, he reached over the edge to pull the fish up. Unfortunately, he
-accidently caught his watch on the edge, and, before he knew it, there was a
+accidentally caught his watch on the edge, and, before he knew it, there was a
snap, and his watch tumbled into the water next to the fish with a loud
"sploosh!" Distracted by this shiny object, the fish made a sudden lunge,
simultaneously snapping the line, and swallowing the watch. Sadly, the
@@ -3539,12 +3542,14 @@ know."
"An uncomfortable sort of age. Now if you'd asked MY advice, I'd have
said 'Leave off at seven' -- but it's too late now."
"I never ask advice about growing," Alice said indignantly.
- "Too proud?" the other enquired.
+ "Too proud?" the other enquired.
Alice felt even more indignant at this suggestion. "I mean,"
she said, "that one can't help growing older."
"ONE can't, perhaps," said Humpty Dumpty; "but TWO can. With
proper assistance, you might have left off at seven."
- -- Lewis Carroll, "Through the Looking-Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
Several students were asked to prove that all odd integers are prime.
The first student to try to do this was a math student. "Hmmm...
@@ -3732,7 +3737,7 @@ she'd been she said she'd spent the night with her sister Shirley."
%
"That's right; the upper-case shift works fine on the screen, but
they're not coming out on the damn printer... Hold? Sure, I'll hold."
- -- e.e. cummings last service call
+ -- e. e. cummings last service call
%
"The best thing for being sad," replied Merlin, beginning to puff
and blow, "is to learn something. That's the only thing that never fails.
@@ -3907,7 +3912,7 @@ married! You're a sadist, that's what!"
THE LESSER-KNOWN PROGRAMMING LANGUAGES #2: RENE
Named after the famous French philosopher and mathematician Rene
-DesCartes, RENE is a language used for artificial intelligence. The
+Descartes, RENE is a language used for artificial intelligence. The
language is being developed at the Chicago Center of Machine Politics
and Programming under a grant from the Jane Byrne Victory Fund. A
spokesman described the language as "Just as great as dis [sic] city of
@@ -4030,7 +4035,9 @@ called 'Ways and Means': but that's only what it is called you know!"
time completely bewildered.
"I was coming to that," the Knight said. "The song really is
"A-sitting on a Gate": and the tune's my own invention."
- --Lewis Carroll, "Through the Looking Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
The only real game in the world, I think, is baseball...
You've got to start way down, at the bottom, when you're six or seven years
@@ -4065,7 +4072,8 @@ blocks of wood. Opaque, like black pools in darkened caves.
"The pyramid is opening!"
"Which one?"
"The one with the ever-widening hole in it!"
- -- Firesign Theater, "How Can You Be In Two Places At
+ -- The Firesign Theatre,
+ "How Can You Be In Two Places At
Once When You're Not Anywhere At All"
%
The salesman and the system analyst took off to spend a weekend in the
@@ -4157,8 +4165,8 @@ make sure that they are Earthlings. Then there's the police. In Portland,
when some guy goes bananas, the cops rope off a sixteen block area around
him and call a shrink from the medical school who stands atop a patrol car
with a megaphone and shouts, "OK! THIS! ALL! STARTED! WHEN! YOU! WERE!
-THREE! YEARS! OLD! ON! ACCOUNT! OF! YOUR MOTHER! RIGHT? SO! LET'S!
-TALK! ABOUT! IT!" Down here they don't waste that kind of time. The LAPD
+THREE! YEARS! OLD! ON! ACCOUNT! OF! YOUR MOTHER! RIGHT? SO! LET'S!
+TALK! ABOUT! IT!" Down here they don't waste that kind of time. The LAPD
has SWAT teams composed of guys who make Darth Vader look like Mr. Peepers.
Before they go to bust a bookie joint they mortar it first.
-- M. Christensen, "A Portland Innocent in LA"
@@ -4270,7 +4278,7 @@ you the Widow Miffin?" a small boy asked.
"Oh, no?" replied the little boy. "Wait 'til you see what
they're carrying upstairs!"
%
- There was a mad scientist (a mad... social... scientist) who kidnaped
+ There was a mad scientist (a mad... social... scientist) who kidnapped
three colleagues, an engineer, a physicist, and a mathematician, and locked
each of them in separate cells with plenty of canned food and water but no
can opener.
@@ -4282,13 +4290,13 @@ and escaped.
off the tin cans by throwing them against the wall. She was developing a good
pitching arm and a new quantum theory.
The mathematician had stacked the unopened cans into a surprising
-solution to the kissing problem; his dessicated corpse was propped calmly
+solution to the kissing problem; his desiccated corpse was propped calmly
against a wall, and this was inscribed on the floor:
Theorem: If I can't open these cans, I'll die.
Proof: assume the opposite...
%
There was once a programmer who was attached to the court of the
-warlord Wu. The warlord asked the programmer: "Which is easier to design:
+warlord of Wu. The warlord asked the programmer: "Which is easier to design:
an accounting package or an operating system?"
"An operating system," replied the programmer.
The warlord uttered an exclamation of disbelief. "Surely an
@@ -4328,7 +4336,7 @@ demands from him more than his utmost strength, that absorbs him, bone and
sinew and brain and hope and fear and dreams -- and still calls for more.
They are fools that think otherwise. No great effort was ever bought.
No painting, no music, no poem, no cathedral in stone, no church, no state was
-ever raised into being for payment of any kind. No parthenon, no Thermopylae
+ever raised into being for payment of any kind. No Parthenon, no Thermopylae
was ever built or fought for pay or glory; no Bukhara sacked, or China ground
beneath Mongol heel, for loot or power alone. The payment for doing these
things was itself the doing of them.
@@ -4393,14 +4401,14 @@ be as easily led to beauty as to ugliness, to truth as to public
relations, to joy as to bitterness, be said to be suffering from Hunter
Thompson's disease. I don't have it this morning. It comes and goes.
This morning I don't have Hunter Thompson's disease.
- -- Kurt Vonnegut Jr. on Dr. Hunter S. Thompson: Excerpt
+ -- Kurt Vonnegut, Jr. on Dr. Hunter S. Thompson: Excerpt
from "A Political Disease", Vonnegut's review of "Fear
and Loathing: On the Campaign Trail '72"
%
- To A Quick Young Fox
+ To A Quick Young Fox:
Why jog exquisite bulk, fond crazy vamp,
Daft buxom jonquil, zephyr's gawky vice?
-Guy fed by work, quiz Jove's xanthic lamp--
+Guy fed by work, quiz Jove's xanthic lamp --
Zow! Qualms by deja vu gyp fox-kin thrice.
-- Lazy Dog
%
@@ -4565,7 +4573,7 @@ let him lie there all night."
"Don't worry about that. They have a guard station in front of the
White House that's open 24 hours a day. The guards would recognize Colson...
and by that time of course his wife would have called the cops and reported
-that a bunch of thugs had kidnaped him."
+that a bunch of thugs had kidnapped him."
"Wouldn't it be a little kinder if you drove about four more blocks
and stopped at a phone box to ring the hospital and say, 'Would you mind going
around to the front of the White House? There's a naked man lying outside
@@ -4574,7 +4582,7 @@ in the street, bleeding to death...'"
"It would be quite a story for the newspapers, wouldn't it?"
"Yeah, I think it's safe to say we'd see some headlines on that one."
-- Hunter S. Thompson, talking to R. Steadman on C. Colson,
- ex-Marine captain, now born again, of Watergate fame.
+ ex-Marine captain, now born again, of Watergate fame.
%
"Well, it's garish, ugly, and derelicts have used it for a toilet.
The rides are dilapidated to the point of being lethal, and could easily
@@ -4593,7 +4601,7 @@ an End-user of Very Little Brain, and long words bother me."
"Well, that was a piece of cake, eh K-9?"
"Piece of cake, Master? Radial slice of baked confection ...
coefficient of relevance to Key of Time: zero."
- -- Dr. Who
+ -- "Doctor Who"
%
"We're running out of adjectives to describe our situation. We
had crisis, then we went into chaos, and now what do we call this?" said
@@ -4691,7 +4699,7 @@ ever happened to me... the most dreadful thing."
"Well, it's a highly technical, sensitive instrument we use in
computer repair. Being a layman, you probably can't grasp exactly what
it does. We call it a two-by-four."
- -- Jeff MacNelley, "Shoe"
+ -- Jeff MacNelly, "Shoe"
%
"When I drink, *everybody* drinks!" a man shouted to the
assembled bar patrons. A loud general cheer went up. After downing his
@@ -4860,14 +4868,14 @@ There, that ought to patch it. Dist it out, wouldja?"
"The famous scientific criminal, as famous among crooks as --"
"My blushes, Watson," Holmes murmured, in a deprecating voice. "I
was about to say 'as he is unknown to the public.'"
- -- A. Conan Doyle, "The Valley of Fear"
+ -- Sir Arthur Conan Doyle, "The Valley of Fear"
%
"You know, it's at times like this when I'm trapped in a Vogon
airlock with a man from Betelgeuse and about to die of asphyxiation in
deep space that I really wish I'd listened to what my mother told me
when I was young!"
"Why, what did she tell you?"
- "I don't know, I didn't listen."
+ "I don't know, I didn't listen!"
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
%
"You mean, if you allow the master to be uncivil, to treat you
@@ -5076,7 +5084,7 @@ please communicate them by one of the following paths:
ARPA: WastebasketSLMHQ.ARPA
UUCP: [berkeley, seismo, harpo]!fubar!thekid!slmhq!wastebasket
- Non-network sites: Federal Express to:
+ Non-network sites: Federal Express to:
Wastebasket
Room NE43-926
Copernicus, The Moon, 12345-6789
@@ -5223,7 +5231,7 @@ III. Any body passing through solid matter will leave a perforation
8. Babes in Boyland
9. Santa's Magic Lap
10. Hot Buttered Elves
- -- David Letterman's "Top Ten Christmas Movies in Times
+ -- David Letterman, "Top Ten Christmas Movies in Times
Square"
%
... A booming voice says, "Wrong, cretin!", and you notice that you
@@ -5337,7 +5345,7 @@ other's private parts.
... computer hardware progress is so fast. No other technology since
civilization began has seen six orders of magnitude in performance-price
gain in 30 years.
- -- Fred Brooks
+ -- Frederick Brooks, Jr.
%
... [concerning quotation marks] even if we *_d_i_d* quote anybody in this
business, it probably would be gibberish.
@@ -5350,8 +5358,6 @@ introduction of Christianity, have been burnt, tortured, fined, imprisoned;
yet we have not advanced one inch towards uniformity.
-- Thomas Jefferson, "Notes on Virginia"
%
- Eat drink and be merry, for tomorrow they may make it illegal.
-%
<<<<< EVACUATION ROUTE <<<<<
%
... "fire" does not matter, "earth" and "air" and "water" do not matter.
@@ -5440,14 +5446,14 @@ legally ... impeccable!
-- Individuals who make their abode in vitreous edifices would be well advised
to refrain from catapulting projectiles.
-- Neophyte's serendipity.
--- Exclusive dedication to necessitious chores without interludes of hedonistic
+-- Exclusive dedication to necessitous chores without interludes of hedonistic
diversion renders John a hebetudinous fellow.
-- A revolving concretion of earthy or mineral matter accumulates no congeries
of small, green bryophytic plant.
-- Abstention from any aleatory undertaking precludes a potential escalation
of a lucrative nature.
-- Missiles of ligneous or osteal consistency have the potential of fracturing
- osseous structure, but appelations will eternally remain innocuous.
+ osseous structure, but appellations will eternally remain innocuous.
%
** MAXIMUM TERMINALS ACTIVE. TRY AGAIN LATER **
%
@@ -5492,7 +5498,7 @@ their C programs.
-- Robert Firth
%
... Our second completely true news item was sent to me by Mr. H. Boyce
-Connell Jr. of Atlanta, Ga., where he is involved in a law firm. One
+Connell, Jr. of Atlanta, Ga., where he is involved in a law firm. One
thing I like about the South is, folks there care about tradition. If
somebody gets handed a name like "H. Boyce," he hangs on to it, puts it
on his legal stationery, even passes it to his son, rather than do what
@@ -5519,7 +5525,7 @@ awareness of the great goals for Man and the society he conspired to erect.
galled saucepan does not reach 212 degrees Fahrenheit.
%
... so long as the people do not care to exercise their freedom, those
-who wish to tyrranize will do so; for tyrants are active and ardent,
+who wish to tyrannize will do so; for tyrants are active and ardent,
and will devote themselves in the name of any number of gods, religious
and otherwise, to put shackles upon sleeping men.
-- Voltarine de Cleyre
@@ -5596,13 +5602,13 @@ cleanersayingIllgetyoumyprettyandyourlittledogTototoo ...
%
... this is an awesome sight. The entire rebel resistance buried under six
million hardbound copies of "The Naked Lunch."
- -- The Firesign Theater
+ -- The Firesign Theatre
%
... though his invention worked superbly -- his theory was a crock of sewage
from beginning to end.
-- Vernor Vinge, "The Peace War"
%
- U X
+ U X
e dUdX, e dX, cosine, secant, tangent, sine, 3.14159...
%
* UNIX is a Trademark of Bell Laboratories.
@@ -5647,7 +5653,7 @@ into doubt.
%
... when fits of creativity run strong, more than one programmer or writer
has been known to abandon the desktop for the more spacious floor.
- -- Fred Brooks
+ -- Frederick Brooks, Jr.
%
... which reminds me of the Carrot family: Ma Carrot, Pa Carrot, and Baby
Carrot. One fine spring day they decided to go out for a picnic. They all
@@ -5708,20 +5714,20 @@ QED: A sheet of paper is a lazy dog.
10. The city does not employ so called "Wallet Inspectors".
-- David Letterman, "Top Ten New York City Pedestrian Tips"
%
-[1] Alexander the Great was a great general.
-[2] Great generals are forewarned.
-[3] Forewarned is forearmed.
-[4] Four is an even number.
-[5] Four is certainly an odd number of arms for a man to have.
-[6] The only number that is both even and odd is infinity.
+(1) Alexander the Great was a great general.
+(2) Great generals are forewarned.
+(3) Forewarned is forearmed.
+(4) Four is an even number.
+(5) Four is certainly an odd number of arms for a man to have.
+(6) The only number that is both even and odd is infinity.
Therefore, Alexander the Great had an infinite number of arms.
%
-[1] Alexander the Great was a great general.
-[2] Great generals are forewarned.
-[3] Forewarned is forearmed.
-[4] Four is an even number.
-[5] Four is certainly an odd number of arms for a man to have.
-[6] The only number that is both even and odd is infinity.
+(1) Alexander the Great was a great general.
+(2) Great generals are forewarned.
+(3) Forewarned is forearmed.
+(4) Four is an even number.
+(5) Four is certainly an odd number of arms for a man to have.
+(6) The only number that is both even and odd is infinity.
Therefore, all horses are black.
%
1. Avoid fried meats which angry up the blood.
@@ -5792,7 +5798,7 @@ you have to (always catch the buyer hungry and always make him wait).
2. I, David Letterman, will never rent out my farm again.
1. We are stardust. We are golden. We are going to look really stupid to
future generations.
- -- David Letterman, Top Ten Lessons of Woodstock
+ -- David Letterman, "Top Ten Lessons of Woodstock"
%
10 Reasons Why a Beer is Better Than a Woman:
@@ -5801,8 +5807,8 @@ you have to (always catch the buyer hungry and always make him wait).
3. A beer doesn't think baseball is stupid simply because the guys spit.
4. A beer doesn't give a [expletive deleted] if you keep a bunch of
other beers on the side.
- 5. A beer will not call you a sexist pig if you say "doberman" instead of
- "doberperson".
+ 5. A beer will not call you a sexist pig if you say "Doberman" instead of
+ "Doberperson."
6. A beer won't get a job as a DJ and play 5 straight hours of lesbian
folk music on yer fave radio station.
7. A beer understands why The Three Stooges are funny.
@@ -5820,7 +5826,7 @@ FF buckets of bits on the bus
FF buckets of bits on the bus
FF buckets of bits
Take one down, short it to ground
-FE buckets of bits on the bus...
+FE buckets of bits on the bus
ad infinitum...
%
@@ -5932,13 +5938,13 @@ It isn't just a good idea, it's the law!
What 20th Century U.S. President was almost impeached and what
office did he later hold?
%
-3 syncs represent the trinity - init, the child and the eternal zombie
+3 syncs represent the trinity -- init, the child and the eternal zombie
process. In doing 3, you're paying homage to each and I think such
traditions are important in this shallow, mercurial business we find
ourselves in.
-- Jordan K. Hubbard
%
-$3,000,000.
+$3,000,000
%
355/113 --
Not the famous irrational number PI, but an incredible simulation.
@@ -6050,7 +6056,7 @@ A beautiful woman is a blessing from Heaven, but a good cigar is a smoke.
-- Kipling
%
A beautiful woman is a picture which drives all beholders nobly mad.
- -- Emerson
+ -- Ralph Waldo Emerson
%
A beer delayed is a beer denied.
%
@@ -6067,7 +6073,7 @@ A billion hours ago man had not yet walked on earth.
A billion dollars ago was late yesterday afternoon at the U.S. Treasury.
%
A biologist, a statistician, a mathematician and a computer scientist are on
-a photo-safari in Africa. As they're driving along the savanna in their
+a photo-safari in Africa. As they're driving along the savannah in their
jeep, they stop and scout the horizon with their binoculars.
The biologist: "Look! A herd of zebras! And there's a white zebra!
@@ -6203,7 +6209,7 @@ invariably sat silent. The monk had already asked about a bean, a lake,
and a moonlit night. One day he brought to Tortue a piece of string, and
asked the same question. In reply, the Grand Tortue grasped the loop
between his feet and, with a few simple manipulations, created a complex
-string which he proferred wordlessly to the monk. At that moment, the monk
+string which he proffered wordlessly to the monk. At that moment, the monk
was enlightened.
From then on, the monk did not bother Tortue. Instead, he made string after
@@ -6261,9 +6267,10 @@ A city is a large community where people are lonesome together.
%
A clash of doctrine is not a disaster - it is an opportunity.
%
-A classic is something that everyone wants to have read
+A classic is something that everybody wants to have read
and nobody wants to read.
- -- Mark Twain, "The Disappearance of Literature"
+ -- Mark Twain quoting Professor Winchester,
+ "The Disappearance of Literature"
%
A clever prophet makes sure of the event first.
%
@@ -6438,7 +6445,7 @@ damned things is ample.
A couch is as good as a chair.
%
A countryman between two lawyers is like a fish between two cats.
- -- Ben Franklin
+ -- Benjamin Franklin
%
A couple of young fellers were fishing at their special pond off the
beaten track when out of the bushes jumped the Game Warden. Immediately,
@@ -6535,7 +6542,7 @@ A diplomatic husband said to his wife, "How do you expect me to remember
your birthday when you never look any older?"
%
A diplomat's life consists of three things: protocol, Geritol, and alcohol.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
A distraught patient phoned her doctor's office. "Was it true," the woman
inquired, "that the medication the doctor had prescribed was for the rest
@@ -6544,7 +6551,7 @@ of her life?"
the woman proceeded bravely on. "Well, I'm wondering, then, how serious my
condition is. This prescription is marked `NO REFILLS'".
%
-A diva who specializes in risque arias is an off-coloratura soprano.
+A diva who specializes in risqu'e arias is an off-coloratura soprano.
%
A doctor calls his patient to give him the results of his tests. "I have
some bad news," says the doctor, "and some worse news." The bad news is
@@ -6708,7 +6715,7 @@ dimension strictly exceeds the topological dimension.
-- Mandelbrot, "The Fractal Geometry of Nature"
%
A free society is one where it is safe to be unpopular.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
A freelancer is one who gets paid by the word -- per piece or perhaps.
-- Robert Benchley
@@ -6728,11 +6735,11 @@ lawyers more than he hates his wife.
A friend with weed is a friend indeed.
%
A full belly makes a dull brain.
- -- Ben Franklin
+ -- Benjamin Franklin
[and the local candy machine man. Ed]
%
-A 'full' life in my experience is usually full only of other
+A "full" life in my experience is usually full only of other
people's demands.
%
A furore Normanorum libera nos, O Domine!
@@ -6782,7 +6789,7 @@ A gift of a flower will soon be made to you.
A girl and a boy bump into each other -- surely an accident.
A girl and a boy bump and her handkerchief drops -- surely another accident.
But when a girl gives a boy a dead squid -- *_t_h_a_t _h_a_d _t_o _m_e_a_n _s_o_m_e_t_h_i_n_g*.
- -- S. Morganstern, "The Silent Gondoliers"
+ -- S. Morgenstern, "The Silent Gondoliers"
%
A girl with a future avoids the man with a past.
-- Evan Esar, "The Humor of Humor"
@@ -6847,7 +6854,7 @@ then asks the backhoe operator for directions.
A GOOD WAY TO THREATEN somebody is to light a stick of dynamite. Then you
call the guy and hold the burning fuse to the phone. "Hear that?" you say.
"That's dynamite, baby."
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
A gossip is one who talks to you about others, a bore is one who talks to
you about himself; and a brilliant conversationalist is one who talks to
@@ -6867,7 +6874,7 @@ to take it all away.
A grammarian's life is always intense.
%
A great empire, like a great cake, is most easily diminished at the edges.
- -- Ben Franklin
+ -- Benjamin Franklin
%
A great many people think they are thinking
when they are merely rearranging their prejudices.
@@ -6883,7 +6890,7 @@ indicating two directions at once. Full, pursed lips protruded beneath the
bushy black moustache and, at their corners, sank into little folds filled
with disapproval and potato chip crumbs. In the shadow under the green visor
of the cap Ignatius J. Reilly's supercilious blue and yellow eyes looked down
-upon the other people waiting under the clock at the D.H. Holmes department
+upon the other people waiting under the clock at the D. H. Holmes department
store, studying the crowd of people for signs of bad taste in dress. Several
of the outfits, Ignatius noticed, were new enough and expensive enough to be
properly considered offenses against taste and decency. Possession of
@@ -6981,19 +6988,19 @@ Stormtroopers, who can't hit the broad side of a planet?
-- Tom Galloway
%
A is for Amy who fell down the stairs, B is for Basil assaulted by bears.
-C is for Clair who wasted away, D is for Desmond thrown out of the sleigh.
+C is for Clara who wasted away, D is for Desmond thrown out of the sleigh.
E is for Ernest who choked on a peach, F is for Fanny, sucked dry by a leech.
G is for George, smothered under a rug, H is for Hector, done in by a thug.
I is for Ida who drowned in the lake, J is for James who took lye, by mistake.
K is for Kate who was struck with an axe, L is for Leo who swallowed some tacks.
-M is for Maud who was swept out to sea, N is for Nevil who died of ennui.
+M is for Maud who was swept out to sea, N is for Neville who died of ennui.
O is for Olive, run through with an awl, P is for Prue, trampled flat in a brawl
-Q is for Quinton who sank in a mire, R is for Rhoda, consumed by a fire.
-S is for Susan who parished of fits, T is for Titas who flew into bits.
+Q is for Quentin who sank in a mire, R is for Rhoda, consumed by a fire.
+S is for Susan who parished of fits, T is for Titus who flew into bits.
U is for Una who slipped down a drain, V is for Victor, squashed under a train.
-W is for Winie, embedded in ice, X is for Xercies, devoured by mice.
-Y is for Yoric whose head was bashed in, Z is for Zilla who drank too much gin.
- -- Edward Gorey "The Gastly Crumb Tines"
+W is for Winnie, embedded in ice, X is for Xerxes, devoured by mice.
+Y is for Yorick whose head was bashed in, Z is for Zillah who drank too much gin.
+ -- Edward Gorey, "The Gashlycrumb Tinies"
%
A is for Apple.
-- Hester Pryne
@@ -7077,7 +7084,7 @@ The lady, indignant, removed her ear.
%
A language that doesn't affect the way you
think about programming is not worth knowing.
- -- Alan Perlis
+ -- Alan J. Perlis
%
A language that doesn't have everything is
actually easier to program in than some that do.
@@ -7138,7 +7145,7 @@ A lie in time saves nine.
%
A lie is an abomination unto the Lord and a very present help in time of
trouble.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
A life lived in fear is a life half lived.
%
@@ -7160,10 +7167,10 @@ And the clean ones so seldom are comical.
%
A LISP programmer knows the value of
everything, but the cost of nothing.
- -- Alan Perlis
+ -- Alan J. Perlis
%
A list is only as strong as its weakest link.
- -- Don Knuth
+ -- Donald E. Knuth
%
A little experience often upsets a lot of theory.
%
@@ -7171,7 +7178,7 @@ A little inaccuracy saves a world of explanation.
-- C. E. Ayres
%
A little inaccuracy sometimes saves tons of explanation.
- -- H. H. Munro, "Saki"
+ -- H. H. Munroe a.k.a. Saki, "The Square Egg" (1924)
%
A little kid went up to Santa and asked him, "Santa, you know when I'm bad
right?" And Santa says, "Yes, I do." The little kid then asks, "And you
@@ -7185,7 +7192,7 @@ those software systems that have excited passionate fans are those that are
the products of one or a few designing minds, great designers. Consider Unix,
APL, Pascal, Modula, the Smalltalk interface, even Fortran; and contrast them
with Cobol, PL/I, Algol, MVS/370, and MS-DOS.
- -- Fred Brooks
+ -- Frederick Brooks, Jr.
%
A little word of doubtful number,
A foe to rest and peaceful slumber.
@@ -7208,7 +7215,7 @@ A lot of people are afraid of heights. Not me. I'm afraid of widths.
-- Steven Wright
%
A lot of people I know believe in positive thinking,
-and so do I. I believe everything positively stinks.
+and so do I. I believe everything positively stinks.
-- Lew Col
%
A lover without indiscretion is no lover at all.
@@ -7228,7 +7235,7 @@ a beautiful woman. Somewhere, somebody's tired of her.
%
A man always remembers his first love with special
tenderness, but after that begins to bunch them.
- -- Mencken
+ -- H. L. Mencken
%
A man arrived home early to find his wife in the arms of his best friend,
who swore how much they were in love. To quiet the enraged husband, the
@@ -7288,7 +7295,7 @@ staggers up to the door and confronts the head waiter.
"I'm sorry, sir, ties required."
%
A man is known by the company he organizes.
- -- A. Bierce
+ -- Ambrose Bierce
%
A man is like a rusty wheel on a rusty cart,
He sings his song as he rattles along and then he falls apart.
@@ -7366,7 +7373,7 @@ Tell, me who is buried here?"
"My wife's first husband."
%
A man who cannot seduce men cannot save them either.
- -- Soren Kierkegaard
+ -- S. A. Kierkegaard (1813-1855)
%
A man who carries a cat by its tail learns something he can learn
in no other way.
@@ -7444,7 +7451,7 @@ but to protect the writer.
%
A method of solution is perfect if we can foresee from the start,
and even prove, that following that method we shall attain our aim.
- -- Leibnitz
+ -- Gottfried Wilhelm Leibniz
%
A Mexican newspaper reports that bored Royal Air Force pilots stationed
on the Falkland Islands have devised what they consider a marvelous new
@@ -7454,28 +7461,24 @@ along it at the water's edge. Perhaps ten thousand penguins turn their
heads in unison watching the planes go by, and when the pilots turn
around and fly back, the birds turn their heads in the opposite
direction, like spectators at a slow-motion tennis match. Then, the
-paper reports "The pilots fly out to sea and directly to the penguin
+paper reports, "The pilots fly out to sea and directly to the penguin
colony and overfly it. Heads go up, up, up, and ten thousand penguins
fall over gently onto their backs.
- -- Audobon Society Magazine
-
-2001-02-02, from http://news.bbc.co.uk:
-
-For five weeks, a team from the British Antarctic Survey (BAS)
-monitored 1,000 king penguins on the island of South Georgia as
-Lynx helicopters passed overhead.
-
-"Not one king penguin fell over when the helicopters came over,"
-said team leader Dr Richard Stone.
-
-"As the aircraft approached, the birds went quiet and stopped
+ -- Audubon Society Magazine
+
+[From the BBC, 2001-02-02:
+ For five weeks, a team from the British Antarctic Survey (BAS)
+monitored 1,000 king penguins on the island of South Georgia as Lynx
+helicopters passed overhead.
+ "Not one king penguin fell over when the helicopters came over,"
+said team leader Dr. Richard Stone.
+ "As the aircraft approached, the birds went quiet and stopped
calling to each other, and adolescent birds that were not associated
with nests began walking away from the noise. Pure animal instinct,
really."
-
-The conclusion, said Dr Stone, is that flights over 305 metres
-(1,000 feet) caused "only minor and transitory ecological effects"
-on king penguins.
+ The conclusion, said Dr. Stone, is that flights over 305 metres
+(1,000 feet) caused "only minor and transitory ecological effects" on
+king penguins.]
%
A mighty creature is the germ,
Though smaller than the pachyderm.
@@ -7613,7 +7616,7 @@ A nickel ain't worth a dime anymore.
%
A "No" uttered from deepest conviction is better and greater than a
"Yes" merely uttered to please, or what is worse, to avoid trouble.
- -- Mahatma Ghandi
+ -- Mahatma Gandhi
%
A novice of the temple once approached the Chief Priest with a question.
@@ -7684,12 +7687,12 @@ A person who has something looks at all there is and wants all the rest.
%
A person who is more than casually interested in computers should be well
schooled in machine language, since it is a fundamental part of a computer.
- -- Donald Knuth
+ -- Donald E. Knuth
%
A pessimist is a man who has been compelled to live with an optimist.
-- Elbert Hubbard
%
-A physicist is an atoms way of knowing about atoms.
+A physicist is an atom's way of knowing about atoms.
-- George Wald
%
A pickup with three guys in it pulls into the lumber yard. One of the men
@@ -7756,7 +7759,7 @@ paycheck?"
%
A political man can have as his aim the realization of freedom,
but he has no means to realize it other than through violence.
- -- Jean Paul Sartre
+ -- Jean-Paul Sartre
%
A possum must be himself, and being himself he is honest.
-- Walt Kelly
@@ -7764,7 +7767,7 @@ A possum must be himself, and being himself he is honest.
A pound of salt will not sweeten a single cup of tea.
%
A power so great, it can only be used for Good or Evil!
- -- Firesign Theatre, "The Giant Rat of Summatra"
+ -- The Firesign Theatre, "The Giant Rat of Sumatra"
%
A "practical joker" deserves applause for his wit according to its quality.
Bastinado is about right. For exceptional wit one might grant keelhauling.
@@ -7777,7 +7780,7 @@ A prediction is worth twenty explanations.
A pretty foot is one of the greatest gifts of nature... please send me your
last pair of shoes, already worn out in dancing... so I can have something
of yours to press against my heart.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
A pretty woman can do anything; an ugly woman must do everything.
%
@@ -7831,7 +7834,7 @@ when its programs require attention to the irrelevant.
%
A prohibitionist is the sort of man one wouldn't care to
drink with -- even if he drank.
- -- Mencken
+ -- H. L. Mencken
%
A prominent broadcaster, on a big-game safari in Africa, was taken to a
watering hole where the life of the jungle could be observed. As he
@@ -8019,7 +8022,7 @@ die and a new generation grows up that is familiar with it.
%
A sect or party is an elegant incognito devised to save a man from
the vexation of thinking.
- -- Ralph Waldo Emerson, Journals, 1831
+ -- Ralph Waldo Emerson, "Journals" (1831)
%
A sense of desolation and uncertainty, of futility, of the baselessness
of aspirations, of the vanity of endeavor, and a thirst for a life giving
@@ -8197,7 +8200,7 @@ Lord of the Rings LITE(tm)
Some guys take a long vacation to throw a ring into a volcano.
Hamlet LITE(tm)
- -- by Wm. Shakespeare
+ -- by William Shakespeare
A college student on vacation with family problems, a screwy
girl-friend and a mother who won't act her age.
@@ -8210,7 +8213,7 @@ A Tale of Two Cities LITE(tm)
lady who knits.
Crime and Punishment LITE(tm)
- -- by Fyodor Dostoevski
+ -- by Fyodor Dostoyevsky
A man sends a nasty letter to a pawnbroker, but later
feels guilty and apologizes.
@@ -8235,7 +8238,7 @@ of the Alamo, commented, "I'll bet you never had anyone that brave around
help?"
%
A thing is not necessarily true because a man dies for it.
- -- Oscar Wilde, "The Portrait of Mr. W.H."
+ -- Oscar Wilde, "The Portrait of Mr. W. H."
%
A timely marriage: one made before your children start nagging you about it.
-- Diane Duane
@@ -8273,7 +8276,7 @@ drudge for his living at seventy, sooner than work at anything but his art.
-- Shaw
%
A truly great man will neither trample on a worm nor sneak to an emperor.
- -- Ben Franklin
+ -- Benjamin Franklin
%
A truly wise man never plays leapfrog with a unicorn.
%
@@ -8394,7 +8397,7 @@ she follows.
%
A woman may very well form a friendship with a man, but for this to endure,
it must be assisted by a little physical antipathy.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
A woman must be a cute, cuddly, naive little thing -- tender, sweet,
and stupid.
@@ -8505,8 +8508,6 @@ A: "A symphony is a very complex musical form, perhaps you should begin with
Q: "But Herr Mozart, you were writing symphonies when you were 8 years old."
A: "But I never asked anybody how."
%
-A.A.A.A.A.: An organization for drunks who drive.
-%
AAAAAAAAAAAaaaaaaaaaaaaaaaccccccccckkkkkk!!!!!!!!!
You brute! Knock before entering a ladies room!
%
@@ -8561,7 +8562,7 @@ Above all things, reverence yourself.
%
Abraham Lincoln didn't die in vain. He died in Washington, D.C.
%
-Abscond, v:
+Abscond, v.:
To be unexpectedly called away to the bedside of a dying relative
and miss the return train.
%
@@ -8646,7 +8647,7 @@ religion; rejection without proof is the fundamental characteristic of
Western science.
-- Gary Zukav, "The Dancing Wu Li Masters"
%
-Accident:
+Accident, n.:
A condition in which presence of mind is good,
but absence of body is better.
-- Foolish Dictionary
@@ -8712,7 +8713,7 @@ Accordion, n.:
A bagpipe with pleats.
%
Accuracy, n.:
- The vice of being right
+ The vice of being right.
%
Acid -- better living through chemistry.
%
@@ -8739,7 +8740,7 @@ Edward G. Robinson Emmanual Goldenburg
Gene Wilder Gerald Silberman
John Wayne Marion Morrison
Kirk Douglas Issur Danielovitch
-Richard Burton Richard Jenkins Jr.
+Richard Burton Richard Jenkins, Jr.
Roy Rogers Leonard Slye
Woody Allen Allen Stewart Konigsberg
%
@@ -8790,16 +8791,16 @@ Adding features does not necessarily increase
functionality -- it just makes the manuals thicker.
%
Adding manpower to a late software project makes it later.
- -- F. Brooks, "The Mythical Man-Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
Whenever one person is found adequate to the discharge of a duty by
close application thereto, it is worse execute by two persons and
scarcely done at all if three or more are employed therein.
- -- George Washington, 1732-1799
+ -- George Washington (1732-1799)
%
Adding sound to movies would be like
putting lipstick on the Venus de Milo.
- -- actress Mary Pickford, 1925
+ -- Mary Pickford, actress, 1925
%
Adhere to your own act, and congratulate yourself if you have done
something strange and extravagant, and broken the monotony of a
@@ -8821,7 +8822,7 @@ Adopted kids are such a pain -- you have to teach them how to look
like you ...
-- Gilda Radner
%
-Adore, v:
+Adore, v.:
To venerate expectantly.
-- Ambrose Bierce, "The Devil's Dictionary"
%
@@ -8862,7 +8863,7 @@ African violet: Such worth is rare
Apple blossom: Preference
Bachelor's button: Celibacy
Bay leaf: I change but in death
-Camelia: Reflected loveliness
+Camellia: Reflected loveliness
Chrysanthemum, red: I love
Chrysanthemum, white: Truth
Chrysanthemum, other: Slighted love
@@ -9066,7 +9067,7 @@ In works of labour or of skill In books, or work, or healthful play,
I would be busy too; Let my first years be passed,
For Satan finds some mischief still That I may give for every day
For idle hands to do. Some good account at last.
- -- Isaac Watts, 1674-1748
+ -- Isaac Watts (1674-1748)
%
Against stupidity the very gods Themselves contend in vain.
-- Friedrich von Schiller, "The Maid of Orleans", III, 6
@@ -9193,7 +9194,7 @@ ALBRECHT'S LAW:
%
Alcohol, hashish, prussic acid, strychnine are weak dilutions.
The surest poison is time.
- -- Emerson, "Society and Solitude"
+ -- Ralph Waldo Emerson, "Society and Solitude"
%
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
@@ -9206,7 +9207,7 @@ Alden's Laws:
%
Aleph-null bottles of beer on the wall,
Aleph-null bottles of beer,
-You take one down, and pass it around,
+ You take one down, and pass it around,
Aleph-null bottles of beer on the wall.
%
Alex Haley was adopted!
@@ -9263,7 +9264,7 @@ than others.
-- Alan Truscott
%
All business is based on the mutual trust of one of the parts.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
All constants are variables.
%
@@ -9276,7 +9277,7 @@ All Finagle Laws may be bypassed by learning the simple art of doing
without thinking.
%
All flesh is grass.
- -- Isaiah
+ -- Isaiah 40:6
Smoke a friend today.
%
All generalizations are false, including this one.
@@ -9287,7 +9288,7 @@ barely presentable.
-- Fran Lebowitz, "Metropolitan Life"
%
All Gods were immortal.
- -- Stanislaw J. Lem, "Unkempt Thoughts"
+ -- Stanislaw J. Lec, "Unkempt Thoughts"
%
All great discoveries are made by mistake.
-- Young
@@ -9352,13 +9353,13 @@ that said there were eleven countries, in the world this is I think,
that have queens as sovereign rulers. That's probably my best shot.
%
All kings is mostly rapscallions.
- --Mark Twain
+ -- Mark Twain
%
All laws are simulations of reality.
-- John C. Lilly
%
All life evolves by the differential survival of replicating entities.
- -- Dawkins
+ -- Richard Dawkins
%
All men are mortal. Socrates was mortal. Therefore, all men are
Socrates.
@@ -9368,7 +9369,7 @@ All men have the right to wait in line.
%
All men know the utility of useful things;
but they do not know the utility of futility.
- -- Chuang-tzu
+ -- Chuang Tzu
%
All men profess honesty as long as they can.
To believe all men honest would be folly.
@@ -9411,7 +9412,7 @@ of the money in the vault, or I'm marking down everything in the store."
-- Steven Wright
%
All of the true things I am about to tell you are shameless lies.
- -- The Book of Bokonon / Kurt Vonnegut Jr.
+ -- Kurt Vonnegut, Jr., "The Book of Bokonon"
%
All of us should treasure his Oriental wisdom and his preaching of a
Zen-like detachment, as exemplified by his constant reminder to clerks,
@@ -9447,7 +9448,7 @@ goal. Perhaps it is merely that computers are young, programmers are younger,
and the young are always optimists. But however the selection process works,
the result is indisputable: "This time it will surely run," or "I just found
the last bug."
- -- Frederick Brooks, "The Mythical Man Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
%
All programmers are playwrights and all computers are lousy actors.
%
@@ -9558,7 +9559,7 @@ All things are possible, except for skiing through a revolving door.
All things being equal, you are bound to lose.
%
All things that are, are with more spirit chased than enjoyed.
- -- Shakespeare, "Merchant of Venice"
+ -- William Shakespeare, "Merchant of Venice"
%
All this wheeling and dealing around, why, it isn't for money,
it's for fun. Money's just the way we keep score.
@@ -9664,9 +9665,9 @@ apprehending of poachers, ways to control vermin, and other chores and duties
of the professional gamekeeper. Unfortunately, one is obliged to wade
through many pages of extraneous material in order to discover and savour
those sidelights on the management of a midland shooting estate, and in this
-reviewer's opinion the book cannot take the place of J.R. Miller's "Practical
+reviewer's opinion the book cannot take the place of J. R. Miller's "Practical
Gamekeeping."
- -- Ed Zern, "Field and Stream", Nov., 1959
+ -- Ed Zern, "Field and Stream" (Nov. 1959)
%
Always borrow money from a pessimist; he doesn't expect to be paid back.
%
@@ -9733,13 +9734,13 @@ and the scum rises to the top.
-- Utah Phillips
%
America is a stronger nation for the ACLU's uncompromising effort.
- -- President John F. Kennedy
+ -- President John F. Kennedy
The simple rights, the civil liberties from generations of struggle must not
be just fine words for patriotic holidays, words we subvert on weekdays, but
living, honored rules of conduct amongst us...I'm glad the American Civil
Liberties Union gets indignant, and I hope this will always be so.
- -- Senator Adlai E. Stevenson
+ -- Adlai E. Stevenson
The ACLU has stood foursquare against the recurring tides of hysteria that
from time to time threaten freedoms everywhere... Indeed, it is difficult
@@ -9803,7 +9804,7 @@ AMOEBIT:
and divide at the same time.
%
Among all savage beasts, none is found so harmful as woman.
- -- St. John Chrysostom, 304-407
+ -- St. John Chrysostom (304-407)
%
Among the lucky, you are the chosen one.
%
@@ -9814,7 +9815,7 @@ An actor's a guy who if you ain't talkin' about him, ain't listening.
-- Marlon Brando
%
An Ada exception is when a routine gets
-in trouble and says 'Beam me up, Scotty'.
+in trouble and says "Beam me up, Scotty."
%
An adequate bootstrap is a contradiction in terms.
%
@@ -9831,11 +9832,11 @@ An alcoholic is someone you don't like who drinks as much as you do.
-- Dylan Thomas
%
An algorithm must be seen to be believed.
- -- D. E. Knuth
+ -- Donald E. Knuth
%
An ambassador is an honest man sent abroad
to lie and intrigue for the benefit of his country.
- -- Sir Henry Wotton, 1568-1639
+ -- Sir Henry Wotton (1568-1639)
%
An amendment to a motion may be amended, but an amendment to an amendment
to a motion may not be amended. However, a substitute for an amendment to
@@ -9932,7 +9933,7 @@ An economist is a man who would marry
Farrah Fawcett-Majors for her money.
%
An editor is one who separates the wheat from the chaff and prints the chaff.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
An effective way to deal with predators is to taste terrible.
%
@@ -10266,7 +10267,7 @@ The venerable XGP, Has made the Ten dumb,
But his slow artistic hand, Without you, Dover,
Lacks your clean velocity. We're system untounged-
-Theses and papers DRAW Plots and TEXage
+Theses and papers DRAW Plots and TEXage
And code in a queue Have been biding their time,
Dover, oh Dover, With LISP code and programs,
We've been waiting for you. And this crufty rhyme.
@@ -10444,7 +10445,7 @@ cracking secret NATO codes and editing propaganda for your own people all
at the same time with the other! (Well, you really can't, but the Americans
think you can, and that's the point, right?)
%
-Anoint, v:
+Anoint, v.:
To grease a king or other great functionary already sufficiently
slippery.
-- Ambrose Bierce, "The Devil's Dictionary"
@@ -10456,7 +10457,7 @@ Another day, another dollar.
%
Another flaw in the human character is that everybody wants to build
and nobody wants to do maintenance.
- -- Kurt Vonnegut, "Hocus Pocus"
+ -- Kurt Vonnegut, Jr., "Hocus Pocus"
%
Another good night not to sleep in a eucalyptus tree.
%
@@ -10472,7 +10473,7 @@ Another such victory over the Romans, and we are undone.
-- Pyrrhus
%
Answer a fool according to his folly, lest he be wise in his own conceit.
- -- Proverbs, 26:5
+ -- Proverbs 26:5
%
Anthony's Law of Force:
Don't force it; get a larger hammer.
@@ -10578,7 +10579,7 @@ requires a heroism which is transcendent.
-- Henry Ward Beecher
%
Any man who hates dogs and babies can't be all bad.
- -- Leo Rosten, on W.C. Fields
+ -- Leo Rosten, on W. C. Fields
%
Any member introducing a dog into the Society's premises shall be
liable to a fine of one pound. Any animal leading a blind person shall
@@ -10674,7 +10675,6 @@ Anyone stupid enough to be caught by the police is probably guilty.
%
Anyone taking offence at fortune(s) is desperately lacking beer, in my
extremely humble opinion.
-
-- Philip Paeps
%
Anyone who cannot cope with mathematics is not fully human. At best he
@@ -10683,7 +10683,7 @@ make messes in the house.
-- Lazarus Long, "Time Enough for Love"
%
Anyone who considers protocol unimportant has never dealt with a cat.
- -- R. Heinlein
+ -- Robert A. Heinlein
%
Anyone who describes Islam as a religion as intolerant encourages violence.
-- Tasnim Aslam, Spokesman for Pakistani Foreign Ministry
@@ -10767,9 +10767,9 @@ APHASIA:
Loss of speech in social scientists when asked
at parties, "But of what use is your research?"
%
-aphorism, n.:
+Aphorism, n.:
A concise, clever statement.
-afterism, n.:
+Afterism, n.:
A concise, clever statement you don't think of until too late.
-- James Alexander Thom
%
@@ -10782,7 +10782,7 @@ of coding bums.
%
APL is a natural extension of assembler language programming;
...and is best for educational purposes.
- -- A. Perlis
+ -- Alan J. Perlis
%
APL is a write-only language. I can write programs
in APL, but I can't read any of them.
@@ -10804,7 +10804,7 @@ April is the cruelest month...
Aquadextrous, adj.:
Possessing the ability to turn the bathtub
faucet on and off with your toes.
- -- Rich Hall, "Sniglets"
+ -- Rich Hall & Friends, "Sniglets"
%
AQUARIUS (Jan 20 - Feb 18)
You have an inventive mind and are inclined to be progressive.
@@ -10971,7 +10971,7 @@ ARITHMETIC:
Arithmetic is being able to count up to twenty without taking off your shoes.
-- Mickey Mouse
%
-ARMADILLO:
+Armadillo, v.:
To provide weapons to a Spanish pickle.
%
Armenians and Azerbaijanis in Stepanakert, capital of the Nagorno-Karabakh
@@ -10987,9 +10987,9 @@ Armstrong's Collection Law:
it is surely made out to someone else.
%
Arnold's Laws of Documentation:
- 1.) If it should exist, it doesn't.
- 2.) If it does exist, it's out of date.
- 3.) Only documentation for useless programs transcends the
+ (1) If it should exist, it doesn't.
+ (2) If it does exist, it's out of date.
+ (3) Only documentation for useless programs transcends the
first two laws.
%
Around computers it is difficult to find the correct unit of time to
@@ -11031,14 +11031,14 @@ Art is Nature speeded up and God slowed down.
-- Chazal
%
"Art" is the ability to separate the significant from the insignificant.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
Art is the tree of life. Science is the tree of death.
%
Arthur's Laws of Love:
- 1. People to whom you are attracted invariably think you
+ (1) People to whom you are attracted invariably think you
remind them of someone else.
- 2. The love letter you finally got the courage to send will
+ (2) The love letter you finally got the courage to send will
be delayed in the mail long enough for you to make a fool
of yourself in person.
%
@@ -11106,7 +11106,7 @@ As far as we know, our computer has never had an undetected error.
-- Weisert
%
As flies to wanton boys are we to the gods; they kill us for their sport.
- -- Shakespeare, "King Lear"
+ -- William Shakespeare, "King Lear"
%
As for the women, though we scorn and flout 'em,
We may live with, but cannot live without 'em.
@@ -11198,7 +11198,7 @@ industries are secure. We hear about constitutional rights, free speech
and the free press. Every time I hear these words I say to myself, "That
man is a Red, that man is a Communist". You never hear a real American
talk like that.
- -- Frank Hague, 1896-1956
+ -- Frank Hague (1896-1956)
%
As long as the answer is right, who cares if the question is wrong?
%
@@ -11331,7 +11331,7 @@ or putatively less buggy. The replacement of a working component by a new
version requires the same systematic testing procedure that adding a new
component does, although it should require less time, for more complete and
efficient test cases will usually be available.
- -- Frederick Brooks Jr., "The Mythical Man Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
%
As the trials of life continue to take their toll, remember that there
is always a future in Computer Maintenance.
@@ -11395,7 +11395,7 @@ Do not give up to the great distance:
It's by going that you will reach your aim.
Be not discouraged by human frailty:
You will overcome it if you try to.
- -- Chinggis (Genghis) Khan
+ -- Chinggis (Genghis) Khan
%
ASCII:
The control code for all beginning programmers and those who would
@@ -11421,7 +11421,7 @@ will pay only the station-to-station rate.
%
Ask not for whom the <CONTROL-G> tolls.
%
-Ask not for whom the telephone bell tolls...
+Ask not for whom the telephone bell tolls ...
if thou art in the bathtub, it tolls for thee.
%
Ask not what's inside your head, but what your head's inside of.
@@ -11611,8 +11611,7 @@ Atlee is a very modest man. And with reason.
%
Attempting to stop MySQL by buying companies around it is like trying
to kill a dolphin by drinking the ocean.
-
- -- Mårten Mickos
+ -- Marten Mickos
%
Attorney General Edwin Meese III explained why the Supreme Court's Miranda
decision (holding that subjects have a right to remain silent and have a
@@ -11621,13 +11620,13 @@ suspects who are innocent of a crime. That's contradictory. If a person
is innocent of a crime, then he is not a suspect."
-- U.S. News and World Report, 10/14/85
%
-AUCTION:
+Auction, n.:
A gyp off the old block.
%
Audacity, and again, audacity, and always audacity.
-- G. J. Danton
%
-audiophile, n:
+Audiophile, n.:
Someone who listens to the equipment instead of the music.
%
Auribus teneo lupum.
@@ -11815,7 +11814,7 @@ BASIC is the Computer Science equivalent of "Scientific Creationism."
BASIC is to computer programming as QWERTY is to typing.
-- Seymour Papert
%
-Basic, n.:
+BASIC, n.:
A programming language. Related to certain social diseases in
that those who have it will not admit it in polite company.
%
@@ -11923,10 +11922,12 @@ Be valiant, but not too venturous.
Let thy attire be comely, but not costly.
-- John Lyly
%
-beachhead:
-In marketing: a small piece of a market over which you gain control and
-from which you go out to control other pieces of the market.
-In war: where soldiers die.
+Beachhead, n.:
+ In marketing: A small piece of a market over which you gain
+ control and from which you go out to control other pieces of
+ the market.
+
+ In war: Where soldiers die.
%
Beam me up, Scotty!
%
@@ -12072,9 +12073,9 @@ seven or eight periods now and it's beginning to worry me."
Being conservative has never been regarded as old-fashioned. But
if you fight for a sensible step in the right direction which others
has deserted you will be branded "reactionary".
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
-"Being disintegrated makes me ve-ry an-gry!" <huff, huff>
+"Being disintegrated makes me ve-ry an-gry!" <huff, huff>
%
Being frustrated is disagreeable, but the real
disasters in life begin when you get what you want.
@@ -12098,14 +12099,14 @@ standing next to a lamp post infested with pigeons.
%
Being ugly isn't illegal. Yet.
%
-belief, n:
+Belief, n.:
Something you do not believe.
%
Believe everything you hear about the world; nothing is too
impossibly bad.
- -- Honore DeBalzac
+ -- Honore de Balzac
%
-Bell Labs Unix - Reach out and grep someone.
+Bell Labs Unix -- Reach out and grep someone.
%
Ben, why didn't you tell me?
-- Luke Skywalker
@@ -12134,7 +12135,7 @@ none of his friends like him either.
%
Bernard was a young eighty-three, not a gomer, and able to talk. He'd been
transferred from MBH (Man's Best Hospital), the House's Rival. Founded in
-Colonial times by the WASPs, the insemination fo MBH by non-WASPs had taken
+Colonial times by the WASPs, the insemination of MBH by non-WASPs had taken
place only mid-twentieth century with the token multidextrous Oriental
surgeon, and finally, with the token red-hot internal-medicine Jew. Yet,
MBH was still Brooks Brothers, while the House was still the Garment District.
@@ -12205,7 +12206,7 @@ clearly visible on one of the leading characters.
Best of all is never to have been born.
Second best is to die soon.
%
-beta test, v:
+Beta test, v.:
To voluntarily entrust one's data, one's livelihood and one's
sanity to hardware or software intended to destroy all three.
In earlier days, virgins were often selected to beta test volcanos.
@@ -12236,7 +12237,7 @@ ncheck list
ncheck list
cat list | grep naughty >nogiftlist
cat list | grep nice >giftlist
-santa claus <north pole > town
+santa claus <north pole >town
who | grep sleeping
who | grep awake
@@ -12303,7 +12304,7 @@ Beware of Bigfoot!
%
Beware of bugs in the above code; I have only proved it correct, not
tried it.
- -- Donald Knuth
+ -- Donald E. Knuth
%
Beware of computerized fortune-tellers!
%
@@ -12337,7 +12338,7 @@ Beware the new TTY code!
%
Beware the one behind you.
%
-bi, n:
+Bi, n.:
When *everybody* thinks you're a pervert.
%
Bierman's Laws of Contracts:
@@ -12406,7 +12407,7 @@ time, so it is now realized that numbers are not absolute, but depend
on the observer's movement in restaurants.
-- Douglas Adams, "Life, The Universe and Everything"
%
-bit, n:
+Bit, n.:
A unit of measure applied to color. Twenty-four-bit color
refers to expensive $3 color as opposed to the cheaper 25
cent, or two-bit, color that use to be available a few years
@@ -12462,7 +12463,7 @@ Blame Saint Andreas -- it's all his fault.
%
Blessed are the forgetful: for they
get the better even of their blunders.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
Blessed are the meek for they shall inhibit the earth.
%
@@ -12493,9 +12494,9 @@ abstains from giving wordy evidence of the fact.
Blinding speed can compensate for a lot of deficiencies.
-- David Nichols
%
-BLISS is ignorance
+BLISS is ignorance.
%
-Blithwapping, v:
+Blithwapping, v.:
Using anything BUT a hammer to hammer a nail into the
wall, such as shoes, lamp bases, doorstops, etc.
-- Rich Hall & Friends, "Sniglets"
@@ -12561,13 +12562,13 @@ Boren's Laws:
(2) When in trouble, delegate.
(3) When in doubt, mumble.
%
-Boss, n:
+Boss, n.:
According to the Oxford English Dictionary, in the Middle Ages the
words "boss" and "botch" were largely synonymous, except that boss,
in addition to meaning "a supervisor of workers" also meant "an
ornamental stud."
%
-Boston:
+Boston, n.:
An outdoor Betty Ford Clinic.
%
Boston, n.:
@@ -12610,10 +12611,10 @@ And get the maximum pleasure from a minimum of love.
Boy, I sure wish that I could be in the
'Advanced Systems Development' group!
%
-Boy, life takes a long time to live
+Boy, life takes a long time to live.
-- Steven Wright
%
-boy, n:
+Boy, n.:
A noise with dirt on it.
%
Boy, that crayon sure did hurt!
@@ -12637,7 +12638,7 @@ Everybody tends to drift toward Bozoness. It has Oz in it. They mean
well. They're straight-looking except they've got inflatable shoes. They
like their comforts. The Bozos have learned to enjoy their free time,
which is all the time.
- -- Firesign Theatre, "If Bees Lived Inside Your Head"
+ -- The Firesign Theatre, "If Bees Lived Inside Your Head"
%
Brace yourselves. We're about to try something that borders on the
unique: an actually rather serious technical book which is not only
@@ -12661,14 +12662,14 @@ Brain, n.:
The apparatus with which we think that we think.
-- Ambrose Bierce, "The Devil's Dictionary"
%
-Brain, v: [as in "to brain"]
+Brain, v. [as in "to brain"]:
To rebuke bluntly, but not pointedly; to dispel a source
of error in an opponent.
-- Ambrose Bierce, "The Devil's Dictionary"
%
brain-damaged, generalization of "Honeywell Brain Damage" (HBD), a
theoretical disease invented to explain certain utter cretinisms in
-Multics, adj:
+Multics, adj.:
Obviously wrong; cretinous; demented. There is an implication
that the person responsible must have suffered brain damage,
because he/she should have known better. Calling something
@@ -12725,7 +12726,7 @@ Bride, n.:
%
Bridge ahead. Pay troll.
%
-briefcase, n:
+Briefcase, n.:
A trial where the jury gets together and forms a lynching party.
%
Briefly stated, the findings are that when presented with an array of
@@ -12777,14 +12778,14 @@ believe that if you sleep with your head under the pillow a fairy will come
and take all your teeth.
-- Mike Harding, "The Armchair Anarchist's Almanac"
%
-broad-mindedness, n:
+Broad-mindedness, n.:
The result of flattening high-mindedness out.
%
Brogan's Constant:
People tend to congregate in the back
of the church and the front of the bus.
%
-brokee, n:
+Brokee, n.:
Someone who buys stocks on the advice of a broker.
%
Brontosaurus Principle:
@@ -12801,7 +12802,7 @@ Brooke's Law:
Brooks' Law:
Adding manpower to a late software project makes it later
%
-Brucify, v:
+Brucify, v.:
1: Kill by nailing onto style(9); "David O'Brien was brucified"
2: Annoy constantly by reminding of potential improvements
[syn: {torment}, {rag}, {tantalize}, {bedevil}, {dun},
@@ -12842,7 +12843,7 @@ wrote the program.
Fortunately, the second-to-last bug has just been fixed.
-- Ray Simard
%
-Bug, n:
+Bug, n.:
An elusive creature living in a program that makes it incorrect.
The activity of "debugging", or removing bugs from a program, ends
when people get tired of doing it, not when the bugs are removed.
@@ -12859,7 +12860,7 @@ BULLWINKLE: "You just leave that to my pal. He's the brains of the
outfit."
GENERAL: "What does that make YOU?"
BULLWINKLE: "What else? An executive..."
- -- Jay Ward
+ -- Jay Ward, "Rocky and Bullwinkle"
%
Bumper sticker:
All the parts falling off this car are
@@ -12868,7 +12869,7 @@ Bumper sticker:
Bunker's Admonition:
You cannot buy beer; you can only rent it.
%
-Burbulation, v:
+Burbulation, v.:
The obsessive act of opening and closing a refrigerator door in
an attempt to catch it before the automatic light comes on.
-- Rich Hall & Friends, "Sniglets"
@@ -12878,14 +12879,14 @@ Bureau Termination, Law of:
the number of employees in that bureau will double within
12 months after the decision is made.
%
-bureaucracy, n:
+Bureaucracy, n.:
A method for transforming energy into solid waste.
%
Bureaucrat, n.:
A person who cuts red tape sideways.
-- J. McCabe
%
-bureaucrat, n:
+Bureaucrat, n.:
A politician who has tenure.
%
Burke's Postulates:
@@ -13045,7 +13046,7 @@ But you shall not escape my iambics.
But you who live on dreams, you are better pleased with the sophistical
reasoning and frauds of talkers about great and uncertain matters than
those who speak of certain and natural matters, not of such lofty nature.
- -- Leonardo Da Vinci, "The Codex on the Flight of Birds"
+ -- Leonardo da Vinci, "The Codex on the Flight of Birds"
%
Buzz off, Banana Nose; Relieve mine eyes
Of hateful soreness, purge mine ears of corn;
@@ -13062,7 +13063,7 @@ Thy cheer, like thy complexion, is the pits.
Be off, I say; go bug somebody new,
Scram, beat it, get thee hence, and nuts to you.
%
-buzzword, n:
+Buzzword, n.:
The fly in the ointment of computer literacy.
%
By doing just a little every day, you can
@@ -13082,7 +13083,7 @@ by practice, they get to be wide apart.
By necessity, by proclivity, and by delight, we all quote.
In fact, it is as difficult to appropriate the thoughts of others
as it is to invent.
- -- R. Emerson
+ -- Ralph Waldo Emerson
-- Quoted from a fortune cookie program
(whose author claims, "Actually, stealing IS easier.")
[to which I reply, "You think it's easy for me to
@@ -13117,7 +13118,7 @@ By working faithfully eight hours a day,
you may eventually get to be boss and work twelve.
-- Robert Frost
%
-byob, v:
+BYOB, v.:
Believing Your Own Bull
%
Bypasses are devices that allow some people to dash from point A to
@@ -13148,7 +13149,7 @@ C makes it easy for you to shoot yourself in the foot. C++ makes that
harder, but when you do, it blows away your whole leg.
-- Bjarne Stroustrup
%
-C, n:
+C, n.:
A programming language that is sort of like Pascal except more like
assembly except that it isn't very much like either one, or anything
else. It is either the best language available to the art today, or
@@ -13161,7 +13162,7 @@ Cabbage, n.:
-- Ambrose Bierce, "The Devil's Dictionary"
%
Cable is not a luxury, since many areas have poor TV reception.
- -- The mayor of Tucson, Arizona, 1989
+ -- The Mayor of Tucson, Arizona, 1989
%
Cache:
A very expensive part of the memory system of a computer that no one
@@ -13395,7 +13396,7 @@ Did you ever have the measles, and, if so, how many?
%
Center meeting at 4pm in 2C-543.
%
-cerebral atrophy, n:
+Cerebral atrophy, n.:
The phenomena which occurs as brain cells become weak and sick, and
impair the brain's performance. An abundance of these "bad" cells can cause
symptoms related to senility, apathy, depression, and overall poor academic
@@ -13404,7 +13405,7 @@ everyday activity, but large amounts are weakened by intense mental effort
and the assimilation of difficult concepts. Many college students become
victims of this dread disorder due to poor habits such as overstudying.
-cerebral darwinism, n:
+Cerebral darwinism, n.:
The theory that the effects of cerebral atrophy can be reversed
through the purging action of heavy alcohol consumption. Large amounts of
alcohol cause many brain cells to perish due to oxygen deprivation. Through
@@ -13415,7 +13416,7 @@ Thus, the devastating effects of cerebral atrophy are reversed, and academic
performance actually increases beyond previous levels.
%
Cerebus: I'd love to lick apricot brandy out of your navel.
-Jaka: Look, Cerebus-- Jaka has to tell you ... something
+Jaka: Look, Cerebus -- Jaka has to tell you ... something
Cerebus: If Cerebus had a navel, would you lick apricot brandy
out of it?
Jaka: Ugh!
@@ -13443,7 +13444,7 @@ nuts, as would but for this amending Order not qualify as nuts
%
Certainly the game is rigged.
Don't let that stop you; if you don't bet, you can't win.
- -- Robert Heinlein, "Time Enough For Love"
+ -- Robert A. Heinlein, "Time Enough For Love"
%
Certainly there are things in life that money can't buy,
But it's very funny --
@@ -13485,18 +13486,18 @@ a function that would continue to grow, but never reach unity. This equation
can be applied to charging capacitors, over-damped springs, and the human
race in general.
%
-character density, n.:
+Character density, n.:
The number of very weird people in the office.
%
Character is what you are in the dark!
-- Lord John Whorfin
%
-CHARITY:
- A thing that begins at home and usually stays there.
-%
Charity begins at home.
-- Publius Terentius Afer (Terence)
%
+Charity, n.:
+ A thing that begins at home and usually stays there.
+%
Charlie Brown: Why was I put on this earth?
Linus: To make others happy.
Charlie Brown: Why were others put on this earth?
@@ -13513,7 +13514,7 @@ Cheap things are of no value, valuable things are not cheap.
Check me if I'm wrong, Sandy, but if I kill all the golfers...
they're gonna lock me up and throw away the key!
%
-checkuary, n:
+Checkuary, n.:
The thirteenth month of the year. Begins New Year's Day and ends
when a person stops absentmindedly writing the old year on his checks.
%
@@ -13522,7 +13523,7 @@ Cheer Up! Things are getting worse at a slower rate.
Cheese -- milk's leap toward immortality.
-- Clifton Fadiman, "Any Number Can Play"
%
-Chef, n:
+Chef, n.:
Any cook who swears in French.
%
Cheit's Lament:
@@ -13767,7 +13768,7 @@ please?" it asked the bartender.
"Hey, aren't you the string I just threw out of here?"
"No, I'm a frayed knot."
%
-clone, n:
+Clone, n.:
1. An exact duplicate, as in "our product is a clone of their
product." 2. A shoddy, spurious copy, as in "their product
is a clone of our product."
@@ -13992,7 +13993,7 @@ And that you'll be so glad to do,
Because you'll be my POSSLQ.
%
Come, muse, let us sing of rats!
- -- From a poem by James Grainger, 1721-1767
+ -- From a poem by James Grainger (1721-1767)
%
Come quickly, I am tasting stars!
-- Dom Perignon, upon discovering champagne
@@ -14012,7 +14013,7 @@ And pall the in the dunnest smoke of hell,
That my keen knife see not the wound it makes,
Nor heaven peep through the blanket of the dark,
To cry `Hold, hold!'
- -- Lady MacBeth
+ -- Lady Macbeth, "Macbeth"
%
Comedy, like Medicine, was never meant to be practiced by the general public.
%
@@ -14071,7 +14072,7 @@ Common sense is the collection of prejudices acquired by age eighteen.
%
Common sense is the most evenly distributed quantity in the world.
Everyone thinks he has enough.
- -- Descartes, 1637
+ -- Rene Descartes, 1637
%
Commoner's three laws of ecology:
1) No action is without side-effects.
@@ -14112,7 +14113,7 @@ COMPLEX SYSTEM:
COMPLIMENT:
When you say something to another which everyone knows isn't true.
%
-compuberty, n:
+Compuberty, n.:
The uncomfortable period of emotional and hormonal changes a
computer experiences when the operating system is upgraded and
a sun4 is put online sharing files.
@@ -14171,7 +14172,7 @@ Computers will not be perfected until they can compute how much more
than the estimate the job will cost.
%
Conceit causes more conversation than wit.
- -- LaRouchefoucauld
+ -- La Rochefoucauld
%
Concept, n.:
Any "idea" for which an outside consultant billed you more than
@@ -14179,7 +14180,7 @@ Concept, n.:
%
Conceptual integrity in turn dictates that the design must proceed
from one mind, or from a very small number of agreeing resonant minds.
- -- Frederick Brooks Jr., "The Mythical Man Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
%
Condense soup, not books!
%
@@ -14200,7 +14201,7 @@ that a tweed coat is good for dandruff.
%
Confessions may be good for the soul, but they are bad for
the reputation.
- -- Lord Thomas Dewar
+ -- Lord Thomas Robert Dewar
%
Confidant, confidante, n.:
One entrusted by A with the secrets of B, confided to himself by C.
@@ -14226,7 +14227,7 @@ Conformity is the refuge of the unimaginative.
Confucius say too damn much!
%
Confucius say too much.
- -- Recent Chinese Proverb
+ -- Recent Chinese proverb
%
Confusion will be my epitaph
as I walk a cracked and broken path
@@ -14281,10 +14282,10 @@ Conjecture: All odd numbers are prime.
Engineer's Proof:
3 is prime. 5 is prime. 7 is prime. 9 is prime.
11 is prime. 13 is prime ...
- Computer Scientists's Proof:
+ Computer Scientist's Proof:
3 is prime. 3 is prime. 3 is prime. 3 is prime...
%
-Connector Conspiracy, n:
+Connector Conspiracy, n.:
[probably came into prominence with the appearance of the
KL-10, none of whose connectors match anything else] The tendency of
manufacturers (or, by extension, programmers or purveyors of anything)
@@ -14299,7 +14300,7 @@ governing that is hard.
-- Chinggis (Genghis) Khan
%
Conscience doth make cowards of us all.
- -- Shakespeare
+ -- William Shakespeare
%
Conscience is a mother-in-law whose visit never ends.
-- H. L. Mencken
@@ -14380,7 +14381,9 @@ seduction, observable even in the animal kingdom.
%
"Contrariwise," continued Tweedledee, "if it was so, it might be, and
if it were so, it would be; but as it isn't, it ain't. That's logic!"
- -- Lewis Carroll, "Through the Looking Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
Contrary to popular belief, penguins are not the salvation of modern
technology. Neither do they throw parties for the urban proletariat.
@@ -14417,7 +14420,7 @@ Coronation, n.:
-- Ambrose Bierce, "The Devil's Dictionary"
%
Correction does much, but encouragement does more.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
Corrupt, adj.:
In politics, holding an office of trust or profit.
@@ -14457,7 +14460,7 @@ Courage is resistance to fear, mastery of fear -- not absence of fear.
%
Courage is your greatest present need.
%
-court, n.:
+Court, n.:
A place where they dispense with justice.
-- Arthur Train
%
@@ -14556,7 +14559,7 @@ CURSOR:
One whose program will not run.
-- Robb Russon
%
-cursor address, n:
+Cursor address, n.:
"Hello, cursor!"
-- Stan Kelly-Bootle, "The Devil's DP Dictionary"
%
@@ -14599,12 +14602,9 @@ Cutler Webster's Law:
%
Cutting the space budget really restores my faith in humanity. It
eliminates dreams, goals, and ideals and lets us get straight to the
-business of hate, debauchery, and self-annihilation."
+business of hate, debauchery, and self-annihilation.
-- Johnny Hart
%
-CYNIC:
- Experienced.
-%
Cynic, n.:
A blackguard whose faulty vision sees things as they are, not
as they ought to be. Hence the custom among the Scythians of
@@ -14612,6 +14612,9 @@ Cynic, n.:
-- Ambrose Bierce, "The Devil's Dictionary"
%
Cynic, n.:
+ Experienced.
+%
+Cynic, n.:
One who looks through rose-colored glasses with a jaundiced
eye.
%
@@ -15049,7 +15052,7 @@ claim "I've got a deep semantic theory", they are truly blessed.
DEFAULT:
The hardware's, of course.
%
-default, n.:
+Default, n.:
[Possibly from Black English "De fault wid dis system is you,
mon."] The vain attempt to avoid errors by inactivity. "Nothing will
come of nothing: speak again." -- King Lear.
@@ -15102,10 +15105,10 @@ Delay is preferable to error.
-- Thomas Jefferson
%
Delay not, Caesar. Read it instantly.
- -- Shakespeare, "Julius Caesar" 3,1
+ -- William Shakespeare, "Julius Caesar" 3,1
Here is a letter, read it at your leisure.
- -- Shakespeare, "Merchant of Venice" 5,1
+ -- William Shakespeare, "Merchant of Venice" 5,1
[Quoted in "VMS Internals and Data Structures", V4.4, when
referring to I/O system services.]
@@ -15137,7 +15140,7 @@ Deliver yesterday, code today, think tomorrow.
Delores breezed along the surface of her life like a flat stone forever
skipping along smooth water, rippling reality sporadically but oblivious
to it consistently, until she finally lost momentum, sank, and due to an
-overdose of flouride as a child which caused her to suffer from chronic
+overdose of fluoride as a child which caused her to suffer from chronic
apathy, doomed herself to lie forever on the floor of her life as useless
as an appendix and as lonely as a five-hundred pound barbell in a
steroid-free fitness center.
@@ -15154,7 +15157,7 @@ Democracy becomes a government of bullies, tempered by editors.
-- Ralph Waldo Emerson
%
Democracy can only be measured on the existence of an opposition.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
Democracy is a device that insures we shall be governed no better than
we deserve.
@@ -15173,7 +15176,7 @@ don't think.
%
Democracy is a process by which the people are free to choose the man who
will get the blame.
- -- Laurence J. Peter
+ -- Dr. Laurence J. Peter
%
Democracy is also a form of worship.
It is the worship of Jackals by Jackasses.
@@ -15197,7 +15200,7 @@ Democracy is the worst form of government except all those other
forms that have been tried from time to time.
-- Winston Churchill
%
-Democracy, n:
+Democracy, n.:
A government of the masses. Authority derived through mass meeting
or any other form of direct expression. Results in mobocracy. Attitude
toward property is communistic... negating property rights. Attitude toward
@@ -15208,7 +15211,7 @@ agitation, discontent, anarchy.
-- U. S. Army Training Manual No. 2000-25 (1928-1932),
since withdrawn.
%
-Democracy, n:
+Democracy, n.:
In which you say what you like and do what you're told.
-- Gerald Barry
@@ -15242,8 +15245,8 @@ Dentist, n.:
pulls coins out of one's pockets.
-- Ambrose Bierce, "The Devil's Dictionary"
%
-Denver, n:
- A smallish city located just below the `O' in Colorado.
+Denver, n.:
+ A smallish city located just below the "O" in Colorado.
%
Depart in pieces, i.e., split.
%
@@ -15260,7 +15263,7 @@ Deprive a mirror of its silver and even the Czar won't see his face.
Der Horizont vieler Menschen ist ein Kreis mit Radius Null -
und das nennen sie ihren Standpunkt.
%
-design, v:
+Design, v.:
What you regret not doing later on.
%
Desist from enumerating your fowl
@@ -15445,7 +15448,7 @@ Diplomacy is the art of saying "nice doggie" until you can find a rock.
Diplomacy is to do and say, the nastiest thing in the nicest way.
-- Balfour
%
-diplomacy, n:
+Diplomacy, n.:
Lying in state.
%
Dirksen's Three Laws of Politics:
@@ -15455,7 +15458,7 @@ Dirksen's Three Laws of Politics:
3: Don't get mad, get even.
-- Sen. Everett Dirksen
%
-disbar, n:
+Disbar, n.:
As distinguished from some other bar.
%
Disc space -- the final frontier!
@@ -15551,7 +15554,7 @@ Their tastes may not be the same.
Do not drink coffee in early A.M. It will keep you awake until noon.
%
Do not handicap your children by making their lives easy.
- -- Robert Heinlein
+ -- Robert A. Heinlein
%
Do not meddle in the affairs of troff, for it is subtle and quick to anger.
%
@@ -15658,7 +15661,7 @@ between Nixon and the White House.
-- John F. Kennedy, in 1960
%
Do you suffer painful elimination?
- -- Don Knuth, "Structured Programming with Gotos"
+ -- Donald E. Knuth, "Structured Programming with Gotos"
Do you suffer painful recrimination?
-- Nancy Boxer, "Structured Programming with Come-froms"
@@ -15683,7 +15686,7 @@ your business success? Here's a telling test: Look in the mirror. Is
your skin smooth and lovely, your hair gleaming, your make-up glamorous?
Are you slender enough for your height? Do you stand erect, confident?
Yes? Then you are on your way to success as a woman.
- -- Ladies Home Journal, 1947 advertisement
+ -- Ladies' Home Journal, 1947 advertisement
%
Do your otters do the shimmy?
Do they like to shake their tails?
@@ -15728,12 +15731,12 @@ Doing gets it done.
Don
Ameche: I didn't know you had a cousin Penelope, Bill!
Was she pretty?
-W.C.: Well, her face was so wrinkled it looked like seven miles of
+W. C.: Well, her face was so wrinkled it looked like seven miles of
bad road. She had so many gold teeth, Don, she use to have
to sleep with her head in a safe. She died in Bolivia.
Don: Oh Bill, it must be hard to lose a relative.
-W.C.: It's almost impossible.
- -- W.C. Fields, "The Further Adventures of Larson E.
+W. C.: It's almost impossible.
+ -- W. C. Fields, "The Further Adventures of Larson E.
Whipsnade and other Tarradiddles"
%
Don't abandon hope: your Tom Mix decoder ring arrives tomorrow.
@@ -15773,7 +15776,7 @@ with those that take care of themselves.
Don't cook tonight -- starve a rat today!
%
Don't crush that dwarf, hand me the pliers!
- -- Firesign Theatre
+ -- The Firesign Theatre
%
Don't despair; your ideal lover is waiting for you around the corner.
%
@@ -15888,12 +15891,12 @@ Your brains are in it.
Don't make a big deal out of everything; just deal with everything.
%
Don't marry for money; you can borrow it cheaper.
- -- Scottish Proverb
+ -- Scottish proverb
%
Don't mind him; politicians always sound like that.
%
Don't patch bad code -- rewrite it.
- -- "The Elements of Programming Style", Kernighan and Plauger
+ -- Kernighan and Plauger, "The Elements of Programming Style"
%
Don't plan any hasty moves.
You'll be evicted soon anyway.
@@ -15922,7 +15925,7 @@ Don't say "yes" until I finish talking.
Don't shoot until you're sure you both aren't on the same side.
%
Don't shout for help at night. You might wake your neighbors.
- -- Stanislaw J. Lem, "Unkempt Thoughts"
+ -- Stanislaw J. Lec, "Unkempt Thoughts"
%
Don't smoke the next cigarette. Repeat.
%
@@ -16047,7 +16050,7 @@ Double Bucky, I'd like a whole word of you!
be added to terminal codes on 36-bit machines for use
by screen editors. [to the tune of "Rubber Ducky"]
%
-double-blind Experiment, n:
+Double-blind Experiment, n.:
An experiment in which the chief researcher believes he is
fooling both the subject and the lab assistant. Often accompanied
by a strong belief in the tooth fairy.
@@ -16172,7 +16175,7 @@ DROP THE DAMN BEAR!!!
Drop the vase and it will become a Ming of the past.
-- The Adventurer
%
-drug, n:
+Drug, n.:
A substance that, when injected into a rat, produces a scientific
paper.
%
@@ -16232,13 +16235,13 @@ Dustin Farnum: Why, yesterday, I had the audience glued to their seats!
Oliver Herford: Wonderful! Wonderful! Clever of you to think of it!
-- Brian Herbert, "Classic Comebacks"
%
-Duty, n:
+Duty, n.:
What one expects from others.
-- Oscar Wilde
%
Dying is a very dull, dreary affair. My advice to you is to have
nothing whatever to do with it.
- -- W. Somerset Maughm, his last words
+ -- W. Somerset Maugham, his last words
%
Dying is easy. Comedy is difficult.
-- Actor Edmond Gween, on his deathbed
@@ -16351,9 +16354,11 @@ But I'm goin' to heaven in a flash of fire,
Eat as much as you like -- just don't swallow it.
-- Harry Secombe's diet
%
-Eat drink and be merry! Tomorrow you may be in Utah.
+Eat, drink, and be merry! Tomorrow you may be in Utah.
%
-Eat drink and be merry, for tomorrow we diet.
+Eat, drink, and be merry, for tomorrow they may make it illegal.
+%
+Eat, drink, and be merry, for tomorrow we diet.
%
Eat, drink, and be merry, for tomorrow you may work.
%
@@ -16371,8 +16376,8 @@ Eating chocolate is like being in love without the aggravation.
Economics is extremely useful as a form of employment for economists.
-- John Kenneth Galbraith
%
-economics, n.:
- Economics is the study of the value and meaning of J.K. Galbraith.
+Economics, n.:
+ Economics is the study of the value and meaning of J. K. Galbraith.
-- Mike Harding, "The Armchair Anarchist's Almanac"
%
Economies of scale:
@@ -16383,7 +16388,7 @@ Economies of scale:
as an article of faith by those who love small machines and all
those limitations.
%
-economist, n:
+Economist, n.:
Someone who's good with figures, but doesn't have enough
personality to become an accountant.
%
@@ -16424,17 +16429,17 @@ royal-blue chickens.
-- Fran Lebowitz, "Social Studies"
%
Eeny, Meeny, Jelly Beanie, the spirits are about to speak!
- -- Bullwinkle Moose
+ -- Bullwinkle J. Moose
%
Eggheads unite! You have nothing to lose but your yolks.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
Eggnog is a traditional holiday drink invented by the English. Many
people wonder where the word "eggnog" comes from. The first syllable
comes from the English word "egg", meaning "egg". I don't know where
the "nog" comes from.
-To make eggnog, you'll need rum, whiskey, wine gin and, if they are in
+To make eggnog, you'll need rum, whiskey, wine, gin and, if they are in
season, eggs...
%
Ego sum ens omnipotens
@@ -16445,9 +16450,8 @@ to relieve the pain of being a damned fool.
%
Egotism is the anesthetic which numbs the pain of stupidity.
%
-Egotism, n:
+Egotism, n.:
Doing the New York Times crossword puzzle with a pen.
-
%
Egotist, n.:
A person of low taste, more interested in himself than me.
@@ -16456,8 +16460,8 @@ Egotist, n.:
egrep -n '^[a-z].*\(' $ | sort -t':' +2.0
%
Ehrman's Commentary:
- 1. Things will get worse before they get better.
- 2. Who said things would get better?
+ (1) Things will get worse before they get better.
+ (2) Who said things would get better?
%
...eighty years later he could still recall with the young pang of his
original joy his falling in love with Ada.
@@ -16466,12 +16470,12 @@ original joy his falling in love with Ada.
Einstein argued that there must be simplified explanations of nature, because
God is not capricious or arbitrary. No such faith comforts the software
engineer.
- -- Fred Brooks
+ -- Frederick Brooks, Jr.
%
Either I'm dead or my watch has stopped.
-- Groucho Marx' last words
%
-Elbonics, v:
+Elbonics, v.:
The actions of two people maneuvering for one
armrest in a movie theatre.
-- Rich Hall & Friends, "Sniglets"
@@ -16521,13 +16525,13 @@ WARNING:
%
Electrical Engineers do it with less resistance.
%
-Electrocution, n:
+Electrocution, n.:
Burning at the stake with all the modern improvements.
%
Elegance and truth are inversely related.
-- Becker's Razor
%
-Elephant, n:
+Elephant, n.:
A mouse built to government specifications.
%
Elevators smell different to midgets.
@@ -16549,7 +16553,7 @@ Half asleep, Eli murmured,
%
Elliptic paraboloids for sale.
%
-Elliptical, n:
+Elliptical, n.:
The feel of a kiss.
%
Eloquence is logic on fire.
@@ -16557,10 +16561,10 @@ Eloquence is logic on fire.
Elwood: What kind of music do you get here ma'am?
Barmaid: Why, we get both kinds of music, Country and Western.
%
-Emacs, n:
+Emacs, n.:
A slow-moving parody of a text editor.
%
-Emersons' Law of Contrariness:
+Emerson's Law of Contrariness:
Our chief want in life is somebody who shall make us do
what we can. Having found them, we shall then hate them
for it.
@@ -16595,7 +16599,7 @@ Liberal Arts: "Do you want fries with that?"
English literature's performing flea.
-- Sean O'Casey on P. G. Wodehouse
%
-Engram, n:
+Engram, n.:
1. The physical manifestation of human memory -- "the engram."
2. A particular memory in physical form. [Usage note: this term is no longer
in common use. Prior to Wilson and Magruder's historic discovery, the nature
@@ -16610,14 +16614,14 @@ time.]
-- New Century Unabridged English Dictionary,
3rd edition, 2007 A.D.
%
-enhance, v:
+Enhance, v.:
To tamper with an image, usually to its detriment.
%
Enjoy your life; be pleasant and gay, like the birds in May.
%
Enjoy yourself while you're still old.
%
-Entrepreneur, n:
+Entrepreneur, n.:
A high-rolling risk taker who would rather
be a spectacular failure than a dismal success.
%
@@ -16629,7 +16633,7 @@ Entropy requires no maintenance.
Envy is a pain of mind that successful men cause their neighbors.
-- Onasander
%
-Envy, n:
+Envy, n.:
Wishing you'd been born with an unfair advantage,
instead of having to try and acquire one.
%
@@ -16655,7 +16659,9 @@ Es brilig war. Die schlichte Toven
Wirrten und wimmelten in Waben;
Und aller-m"umsige Burggoven
Dir mohmen R"ath ausgraben.
- -- Lewis Carroll, "Through the Looking Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
Eschew obfuscation.
%
@@ -16673,7 +16679,7 @@ Eternity is a terrible thought. I mean, where's it going to end?
Etiquette is for those with no breeding;
fashion for those with no taste.
%
-Etymology, n:
+Etymology, n.:
Some early etymological scholars came up with derivations that
were hard for the public to believe. The term 'etymology' was
formed from the Latin 'etus' ("eaten"), the root 'mal' ("bad"),
@@ -16681,9 +16687,9 @@ Etymology, n:
hard to swallow."
-- Mike Kellen
%
-Euch ist becannt, was wir beduerfen;
+Euch ist bekannt, was wir beduerfen;
Wir wollen stark Getraenke schluerfen.
- -- Goethe, "Faust"
+ -- Johann Wolfgang von Goethe, "Faust"
%
Eudaemonic research proceeded with the casual mania peculiar to this part of
the world. Nude sunbathing on the back deck was combined with phone calls to
@@ -16852,7 +16858,7 @@ Therefore fire engines are red.
Ever wondered about the origins of the term "bugs" as applied to computer
technology? U.S. Navy Capt. Grace Murray Hopper has firsthand explanation.
The 74-year-old captain, who is still on active duty, was a pioneer in
-computer technology during World War II. At the C.W. Post Center of Long
+computer technology during World War II. At the C. W. Post Center of Long
Island University, Hopper told a group of Long Island public school adminis-
trators that the first computer "bug" was a real bug--a moth. At Harvard
one August night in 1945, Hopper and her associates were working on the
@@ -16909,7 +16915,7 @@ spending money alone. It is spending the sweat of its laborers, the
genius of its scientists, the hopes of its children. This is not a way
of life at all in any true sense. Under the clouds of war, it is
humanity hanging on a cross of iron.
- -- Dwight Eisenhower, April 16, 1953
+ -- Dwight D. Eisenhower, April 16, 1953
%
Every Horse has an Infinite Number of Legs (proof by intimidation):
@@ -17090,7 +17096,7 @@ Everybody is given the same amount of hormones, at birth, and
if you want to use yours for growing hair, that's fine with me.
%
Everybody is somebody else's weirdo.
- -- Dykstra
+ -- Edsger W. Dijkstra
%
Everybody knows that the dice are loaded. Everybody rolls with their
fingers crossed. Everybody knows the war is over. Everybody knows the
@@ -17202,7 +17208,7 @@ Everything might be different in the present
if only one thing had been different in the past.
%
Everything new stalls because there is precedence for the old.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
Everything should be built top-down, except the first time.
%
@@ -17306,7 +17312,7 @@ Excess on occasion is exhilarating. It prevents moderation from
acquiring the deadening effect of a habit.
-- W. Somerset Maugham
%
-Excessive login messages is a sure sign of senility.
+Excessive login messages are a sure sign of senility.
%
Excessive login or logout messages are a sure sign of senility.
%
@@ -17332,7 +17338,7 @@ Expect the worst, it's the least you can do.
%
Expedience is the best teacher.
%
-Expense accounts, n:
+Expense accounts, n.:
Corporate food stamps.
%
Experience is a good teacher, but she sends in terrific bills.
@@ -17410,6 +17416,11 @@ F: When into a room I plunge, I
On the poison they're exuding.
-- The Roguelet's ABC
%
+F. Scott Fitzgerald to Hemingway:
+ "Ernest, the rich are different from us."
+Hemingway:
+ "Yes. They have more money."
+%
f u cn rd ths, itn tyg h myxbl cd.
%
f u cn rd ths, u cn gt a gd jb n cmptr prgrmmng.
@@ -17462,7 +17473,7 @@ Faith goes out through the window when beauty comes in at the door.
Faith has never moved as much as a pin-head from the place it
ought to be according to tradition and the scriptures. It is
the doubt that moved all the mountains.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
Faith is the quality that enables you to eat blackberry jam
on a picnic without looking to see whether the seeds move.
@@ -17470,11 +17481,11 @@ on a picnic without looking to see whether the seeds move.
Faith is under the left nipple.
-- Martin Luther
%
-Faith, n:
+Faith, n.:
That quality which enables us to
believe what we know to be untrue.
%
-Fakir, n:
+Fakir, n.:
A psychologist whose charismatic data have inspired almost
religious devotion in his followers, even though the sources
seem to have shinnied up a rope and vanished.
@@ -17603,7 +17614,7 @@ Fear and loathing, my man, fear and loathing.
Fear is the greatest salesman.
-- Robert Klein
%
-feature, n:
+Feature, n.:
A surprising property of a program. Occasionally documented. To
call a property a feature sometimes means the author did not
consider that case, and the program makes an unexpected, though
@@ -17621,7 +17632,7 @@ Feeling amorous, she looked under the sheets and cried, "Oh, no,
it's Microsoft!"
%
Felix Catus is your taxonomic nomenclature,
-An endothermic quadroped, carniverous by nature.
+An endothermic quadruped, carnivorous by nature.
Your visual, olfactory, and auditory senses
Contribute to your hunting skills and natural defenses.
I find myself intrigued by your sub-vocal oscillations,
@@ -17641,7 +17652,7 @@ I nonetheless consider you a true and valued friend.
Fellow programmer, greetings! You are reading a letter which will bring
you luck and good fortune. Just mail (or UUCP) ten copies of this letter
to ten of your friends. Before you make the copies, send a chip or
-other bit of hardware, and 100 lines of 'C' code to the first person on the
+other bit of hardware, and 100 lines of "C" code to the first person on the
list given at the bottom of this letter. Then delete their name and add
yours to the bottom of the list.
@@ -17680,14 +17691,14 @@ Rod: No, the ability to get hung up on them.
Few things are harder to put up with than the annoyance of a good example.
-- Mark Twain
%
-Fidelity, n:
+Fidelity, n.:
A virtue peculiar to those who are about to be betrayed.
%
Fifteen men on a dead man's chest,
Yo-ho-ho and a bottle of rum!
Drink and the devil had done for the rest,
Yo-ho-ho and a bottle of rum!
- -- Stevenson, "Treasure Island"
+ -- Robert Louis Stevenson, "Treasure Island"
%
Fifth Law of Applied Terror:
If you are given an open-book exam, you will forget your book.
@@ -17709,7 +17720,7 @@ Carolina.
File cabinet:
A four drawer, manually activated trash compactor.
%
-filibuster, n:
+Filibuster, n.:
Throwing your wait around.
%
Fill what's empty, empty what's full, scratch where it itches.
@@ -17862,8 +17873,8 @@ and after questioning, released him to be charged on summons.
telephone booths.
-- "Newcastle Morning Herald", NSW Australia, Aug 1980
%
-First things first -- but not necessarily in that order
- -- Dr. Who, "Doctor Who"
+First things first -- but not necessarily in that order.
+ -- The Doctor, "Doctor Who"
%
"First World" nations are the ones where people drive Japanese cars;
"Second World" nations are where First World residents go on vacation;
@@ -17871,7 +17882,7 @@ and "Third World" nations are the ones where people still dive out of
trees to prove their manhood.
-- Dave Barry
%
-Fishbowl, n:
+Fishbowl, n.:
A glass-enclosed isolation cell where newly
promoted managers are kept for observation.
%
@@ -17974,7 +17985,7 @@ catch him there." With that, he jumped on his carbon cycle in an
activated state and sped off along the reaction pathway ...
-- Daniel B. Murphy, "Precipitations"
%
-flowchart, n. & v.:
+Flowchart, n. & v.:
[From flow "to ripple down in rich profusion, as hair" + chart
"a cryptic hidden-treasure map designed to mislead the uninitiated."]
1. n. The solution, if any, to a class of Mascheroni construction
@@ -18002,7 +18013,7 @@ Flying saucers on occasion
Aliens fume, put off invasion
While they brand these tales as lies.
%
-Fog Lamps, n:
+Fog Lamps, n.:
Excessively (often obnoxiously) bright lamps mounted on the fronts
of automobiles; used on dry, clear nights to indicate that the
driver's brain is in a fog. See also "Idiot Lights".
@@ -18037,7 +18048,7 @@ For a good time, call (510) 642-9483
For a holy stint, a moth of the cloth gave up his woolens for lint.
%
For a light heart lives long.
- -- Shakespeare, "Love's Labour's Lost"
+ -- William Shakespeare, "Love's Labour's Lost"
%
For a man to truly understand rejection, he must first be ignored by a
cat.
@@ -18053,7 +18064,7 @@ prejudice, to fear, to miracle, to slavery, to the unknown, and to
misery hereafter. The few have said "Think". The many have said "Believe!"
-- Robert Ingersoll, "Gods"
%
-For an adequate time call 555-3321
+For an adequate time call 555-3321.
%
For an idea to be fashionable is ominous,
since it must afterwards be always old-fashioned.
@@ -18088,7 +18099,7 @@ that glue in math mode varies with the size only when it is an \mskip;
when moving between an mskip and ordinary skip, the conversion factor
1mu=1pt is always used. The meaning of '\mskip\skip12' and
'\baselineskip=\the\thickmskip' should be clear.
- -- Donald Knuth, TeX 82 -- Comparison with TeX80
+ -- Donald E. Knuth, TeX 82 -- Comparison with TeX80
%
For fast-acting relief, try slowing down.
%
@@ -18269,7 +18280,7 @@ Breasts can sell anything. Shiny red latex body suits start
religions.
-- Brian McGroarty <bvmcg@yahoo.com>
%
-For years a secret shame destroyed my peace--
+For years a secret shame destroyed my peace --
I'd not read Eliot, Auden or MacNiece.
But now I think a thought that brings me hope:
Neither had Chaucer, Shakespeare, Milton, Pope.
@@ -18292,13 +18303,13 @@ No, don't force it, get a bigger hammer.
%
FORCE YOURSELF TO RELAX!
%
-Forecast, n:
+Forecast, n.:
A prediction of the future, based on the past, for
which the forecaster demands payment in the present.
%
Forest fires cause Smokey Bears.
%
-Forgetfulness, n:
+Forgetfulness, n.:
A gift of God bestowed upon debtors in compensation for
their destitution of conscience.
%
@@ -18307,7 +18318,7 @@ Forgive and forget.
%
Forgive him,
for he believes that the customs of his tribe are the laws of nature!
- -- G. B. Shaw
+ -- George Bernard Shaw
%
Forgive, O Lord, my little jokes on Thee
And I'll forgive Thy great big one on me.
@@ -18329,7 +18340,7 @@ which is easier to parse using ad hoc techniques.
%
FORTRAN is not a flower but a weed -- it is hardy,
occasionally blooms, and grows in every computer.
- -- A. J. Perlis
+ -- Alan J. Perlis
%
FORTRAN is the language of Powerful Computers.
-- Steven Feiner
@@ -18552,7 +18563,7 @@ CARTABLANCA:
trouble with the local French authorities who would really prefer
wine and the occupying Germans who believe that only their beer is
fit to be sold. Wacky events ensue until the gripping climax in
- which the much-hated German beer distributer is drowned in a vat.
+ which the much-hated German beer distributor is drowned in a vat.
%
FORTUNE DISCUSSES THE OBSCURE FILMS: #11
@@ -18664,52 +18675,52 @@ it carries every reasonable implication of ill-will toward that person.
%
FORTUNE EXPLAINS WHAT JOB REVIEW CATCH PHRASES MEAN: #1
-skilled oral communicator:
+Skilled oral communicator:
Mumbles inaudibly when attempting to speak. Talks to self.
Argues with self. Loses these arguments.
-skilled written communicator:
+Skilled written communicator:
Scribbles well. Memos are invariable illegible, except for
the portions that attribute recent failures to someone else.
-growth potential:
+Growth potential:
With proper guidance, periodic counseling, and remedial training,
the reviewee may, given enough time and close supervision, meet
the minimum requirements expected of him by the company.
-key company figure:
+Key company figure:
Serves as the perfect counter example.
%
FORTUNE EXPLAINS WHAT JOB REVIEW CATCH PHRASES MEAN: #4
-consistent:
+Consistent:
Reviewee hasn't gotten anything right yet, and it is anticipated
that this pattern will continue throughout the coming year.
-an excellent sounding board:
+An excellent sounding board:
Present reviewee with any number of alternatives, and implement
them in the order precisely opposite of his/her specification.
-a planner and organizer:
+A planner and organizer:
Usually manages to put on socks before shoes. Can match the
animal tags on his clothing.
%
FORTUNE EXPLAINS WHAT JOB REVIEW CATCH PHRASES MEAN: #9
-has management potential:
+Has management potential:
Because of his intimate relationship with inanimate objects, the
reviewee has been appointed to the critical position of department
pencil monitor.
-inspirational:
+Inspirational:
A true inspiration to others. ("There, but for the grace of God,
go I.")
-adapts to stress:
+Adapts to stress:
Passes wind, water, or out depending upon the severity of the
situation.
-goal oriented:
+Goal oriented:
Continually sets low goals for himself, and usually fails
to meet them.
%
@@ -18866,7 +18877,7 @@ sword wielding purple fish glued to Harley-Davidson motorcycles.
Oh, and have a nice day!
-- Bryce Nesbitt '84
%
-fortune's Contribution of the Month to the Animal Rights Debate:
+Fortune's Contribution of the Month to the Animal Rights Debate:
I'll stay out of animals' way if they'll stay out of mine.
"Hey you, get off my plate"
@@ -18948,9 +18959,9 @@ Fortune's Fictitious Country Song Title of the Week:
FORTUNE'S FUN FACTS TO KNOW AND TELL: #1
A guinea pig is not from Guinea but a rodent from South America.
A firefly is not a fly, but a beetle.
- A giant panda bear is really a member of the racoon family.
+ A giant panda bear is really a member of the raccoon family.
A black panther is really a leopard that has a solid black coat
- rather then a spotted one.
+ rather than a spotted one.
Peanuts are not really nuts. The majority of nuts grow on trees
while peanuts grow underground. They are classified as a
legume-part of the pea family.
@@ -18962,7 +18973,7 @@ Ruth, but after the oldest daughter of President Grover Cleveland.
%
FORTUNE'S FUN FACTS TO KNOW AND TELL: #37
Can you name the seven seas?
- Antartic, Artic, North Atlantic, South Atlantic, Indian,
+ Antarctic, Arctic, North Atlantic, South Atlantic, Indian,
North Pacific, South Pacific.
Can you name the seven dwarfs from Snow White?
Doc, Dopey, Sneezy, Happy, Grumpy, Sleepy and Bashful.
@@ -19236,7 +19247,7 @@ Three be the things I shall have till I die:
%
Four fifths of the perjury in the world is expended on
tombstones, women and competitors.
- -- Lord Thomas Dewar
+ -- Lord Thomas Robert Dewar
%
Four hours to bury the cat?
Yes, damn thing wouldn't keep still, kept mucking about, 'owling...
@@ -19272,8 +19283,8 @@ Frankly, Scarlett, I don't have a fix.
Fraud is the homage that force pays to reason.
-- Charles Curtis, "A Commonplace Book"
%
-Free Speech Is The Right To Shout 'Theater' In A Crowded Fire.
- -- A Yippie Proverb
+Free Speech Is The Right To Shout "Theater" In A Crowded Fire.
+ -- A Yippie proverb
%
FreeBSD: everything but the fairings
%
@@ -19320,7 +19331,7 @@ Fried's 1st Rule:
Friends may come and go, but enemies accumulate.
-- Thomas Jones
%
-Friends, n:
+Friends, n.:
People who borrow your books and set wet glasses on them.
People who know you well, but like you anyway.
@@ -19339,7 +19350,7 @@ Come I to make this gig at Caesar's laying down.
%
Friendships last when each friend thinks he has a slight superiority
over the other.
- -- Honore DeBalzac
+ -- Honore de Balzac
%
Frisbeetarianism, n.:
The belief that when you die, your soul goes up on the roof and
@@ -19466,11 +19477,6 @@ That dead men rise up never,
That even the weariest river winds somewhere safe to sea.
-- Swinburne
%
-F.S. Fitzgerald to Hemingway:
- "Ernest, the rich are different from us."
-Hemingway:
- "Yes. They have more money."
-%
Fuch's Warning:
If you actually look like your passport photo, you aren't well
enough to travel.
@@ -19497,7 +19503,7 @@ Function reject.
%
Fundamentally, there may be no basis for anything.
%
-Furbling, v:
+Furbling, v.:
Having to wander through a maze of ropes at an airport or bank
even when you are the only person in line.
-- Rich Hall, "Sniglets"
@@ -19511,7 +19517,7 @@ but if we send it by ship, it's cargo.
Future looks spotty. You will spill soup in late evening.
%
Future will arrive by its own means. Progress not so.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
G. B. Shaw to William Douglas Home: "Go on writing plays, my boy. One
of these days a London producer will go into his office and say to his
@@ -19622,11 +19628,11 @@ Genius is the talent of a person who is dead.
Genius may have its limitations, but stupidity is not thus handicapped.
-- Elbert Hubbard
%
-genius, n:
+Genius, n.:
A chemist who discovers a laundry additive that rhymes with
"bright".
%
-genlock, n:
+Genlock, n.:
Why he stays in the bottle.
%
Gentlemen,
@@ -19641,7 +19647,7 @@ Each item and every farthing has been accounted for, with two regrettable
exceptions for which I beg your indulgence.
Unfortunately the sum of one shilling and ninepence remains unaccounted
for in one infantry battalion's petty cash and there has been a hideous
-confusion as the number of jars of raspberry jam issued to one cavalry
+confusion as to the number of jars of raspberry jam issued to one cavalry
regiment during a sandstorm in western Spain. This reprehensible carelessness
may be related to the pressure of circumstance, since we are war with France, a
fact which may come as a bit of a surprise to you gentlemen in Whitehall.
@@ -19772,7 +19778,6 @@ Ginsberg's Theorem:
3. You can't even quit the game.
Freeman's Commentary on Ginsberg's theorem:
-
Every major philosophy that attempts to make life seem
meaningful is based on the negation of one part of Ginsberg's
Theorem. To wit:
@@ -19816,7 +19821,7 @@ Give me chastity and continence, but not just now.
-- St. Augustine
%
Give me enough medals, and I'll win any war.
- -- Napolean
+ -- Napoleon
%
Give me libertines or give me meth.
%
@@ -19967,7 +19972,7 @@ God created woman.
And boredom did indeed cease from that moment --
but many other things ceased as well.
Woman was God's second mistake.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
God did not create the world in seven days; he screwed around for six
days and then pulled an all-nighter.
@@ -20006,7 +20011,7 @@ God help those who do not help themselves.
-- Wilson Mizner
%
God helps them that helps themselves.
- -- Ben Franklin
+ -- Benjamin Franklin
%
God, I ask for patience -- and I want it right now!
%
@@ -20023,7 +20028,7 @@ God is Dead.
Nietzsche is Dead.
-- God
Nietzsche is God.
- -- Dead
+ -- The Dead
%
God is dead and I don't feel all too well either....
-- Ralph Moonen
@@ -20056,12 +20061,12 @@ God made the integers; all else is the work of Man.
%
God made the world in six days, and was arrested on the seventh.
%
-God may be subtle, but he isn't plain mean.
+God may be subtle, but He isn't plain mean.
-- Albert Einstein
%
God must have loved calories, she made so many of them.
%
-God must love the common man; He made so many of them.
+God must love the Common Man; He made so many of them.
%
God rest ye CS students now, The bearings on the drum are gone,
Let nothing you dismay. The disk is wobbling, too.
@@ -20113,7 +20118,7 @@ Going the speed of light is bad for your age.
Going to church does not make a person religious, nor does going to school
make a person educated, any more than going to a garage makes a person a car.
%
-Gold, n:
+Gold, n.:
A soft malleable metal relatively scarce in distribution. It
is mined deep in the earth by poor men who then give it to rich
men who immediately bury it back in the earth in great prisons,
@@ -20159,7 +20164,7 @@ Good advice is one of those insults that ought to be forgiven.
%
Good advice is something a man gives
when he is too old to set a bad example.
- -- La Rouchefoucauld
+ -- La Rochefoucauld
%
Good day for a change of scene. Repaper the bedroom wall.
%
@@ -20243,10 +20248,10 @@ Gordon's Law:
If you think you have the solution, the question was poorly phrased.
%
Gosh that takes me back... or is it forward? That's the trouble with
-time travel, you never can tell."
- -- Dr. Who, "Androids of Tara"
+time travel, you never can tell.
+ -- The Doctor, "Doctor Who: Androids of Tara"
%
-gossip, n:
+Gossip, n.:
Hearing something you like about someone you don't.
-- Earl Wilson
%
@@ -20288,7 +20293,7 @@ Goto, n.:
to complain about unstructured programmers.
-- Ray Simard
%
-Gourmet, n:
+Gourmet, n.:
Anyone whom, when you fail to finish something strange or
revolting, remarks that it's an acquired taste and that you're
leaving the best part.
@@ -20380,7 +20385,7 @@ place of residence.
%
GREAT MOMENTS IN HISTORY (#7): April 2, 1751
-Issac Newton becomes discouraged when he falls up a flight of stairs.
+Isaac Newton becomes discouraged when he falls up a flight of stairs.
%
GREAT MOMENTS IN HISTORY (#7): November 23, 1915
@@ -20493,7 +20498,7 @@ GURU:
a senior vice-president and is ultimately responsible for the
phone call you are about to receive from your boss.
%
-guru, n:
+Guru, n.:
A computer owner who can read the manual.
%
Gyroscope, n.:
@@ -20525,10 +20530,10 @@ Martin's Extension:
[No, those who can't teach, teach here. Ed.]
%
-hacker, n:
+Hacker, n.:
Originally, any person with a knack for coercing stubborn inanimate
things; hence, a person with a happy knack, later contracted by the mythical
-philosopher Frisbee Frobenius to the common usage, 'hack'.
+philosopher Frisbee Frobenius to the common usage, "hack."
In olden times, upon completion of some particularly atrocious body
of coding that happened to work well, culpable programmers would gather in
a small circle around a first edition of Knuth's Best Volume I by candlelight,
@@ -20629,7 +20634,7 @@ But half the bee has got to be, vis-a-vis its entity. See?
But can a bee be said to be or not to be an entire bee,
When half the bee is not a bee, due to some ancient injury?
%
-Half Moon tonight. (At least its better than no Moon at all.)
+Half Moon tonight. (At least it is better than no Moon at all.)
%
Half of being smart is knowing what you're dumb at.
%
@@ -20649,7 +20654,7 @@ Half-done, n.:
Essex (along the park), make your first left onto Hester Street, walk
about fifteen steps, turn ninety degrees left, and stop. Say to the
man, "Let me have a nice half-done." Worth the trouble, wasn't it?
- -- Arthur Naiman
+ -- Arthur Naiman, "Every Goy's Guide to Yiddish"
%
Halley's Comet: It came, we saw, we drank.
%
@@ -20669,7 +20674,7 @@ Hand, n.:
Handel's Proverb:
You can't produce a baby in one month by impregnating 9 women!
%
-handshaking protocol, n:
+Handshaking protocol, n.:
A process employed by hostile hardware devices to initiate a
terse but civil dialogue, which, in turn, is characterized by
occasional misunderstanding, sulking, and name-calling.
@@ -20677,7 +20682,7 @@ handshaking protocol, n:
Hanging on in quiet desperation is the English way.
-- Pink Floyd
%
-hangover, n:
+Hangover, n.:
The wrath of grapes.
%
Hanlon's Razor:
@@ -20718,14 +20723,14 @@ Happiness, n.:
another.
-- Ambrose Bierce, "The Devil's Dictionary"
%
-happiness, n:
+Happiness, n.:
Finding the owner of a lost bikini.
%
Happy feast of the pig!
%
Happy is the child whose father died rich.
%
-hard, adj:
+Hard, adj.:
The quality of your own data; also how it is to believe those
of other people.
%
@@ -20737,14 +20742,14 @@ Hard work may not kill you, but why take the chance?
Hard work never killed anybody, but why take a chance?
-- Charlie McCarthy
%
-hardware, n:
+Hardware, n.:
The parts of a computer system that can be kicked.
%
Hark, Hark, the dogs do bark
The Duke is fond of kittens
He likes to take their insides out
And use them for his mittens
- From "The Thirteen Clocks"
+ -- "The 13 Clocks"
%
Hark, the Herald Tribune sings,
Advertising wondrous things.
@@ -20829,7 +20834,7 @@ Hartley's First Law:
You can lead a horse to water, but if you can
get him to float on his back, you've got something.
%
-HARTLEY'S SECOND LAW:
+Hartley's Second Law:
Never sleep with anyone crazier than yourself.
My corollary:
@@ -20967,7 +20972,7 @@ vigorous grass is a crack in your sidewalk?
%
Have you noticed the way people's intelligence capabilities decline
sharply the minute they start waving guns around?
- -- Dr. Who
+ -- The Doctor, "Doctor Who"
%
Have you reconsidered a computer career?
%
@@ -21073,6 +21078,7 @@ finer than the staple of his argument.
-- William Shakespeare, "Love's Labour's Lost"
%
He flung himself on his horse and rode madly off in all directions.
+ -- Stephen Leacock
%
He gave her a look that you could have poured on a waffle.
%
@@ -21123,7 +21129,7 @@ He is the best of men who dislikes power.
He is truly wise who gains wisdom from another's mishap.
%
He jests at scars who never felt a wound.
- -- Shakespeare, "Romeo and Juliet, II. 2"
+ -- William Shakespeare, "Romeo and Juliet, II. 2"
%
He keeps differentiating, flying off on a tangent.
%
@@ -21162,7 +21168,7 @@ had fallen to the ground.
That my translation must be changed again.
The spirit helps me. Now it is exact.
I write: "In the beginning was the Act."
- -- Goethe's Faust
+ -- Johann Wolfgang von Goethe, "Faust"
%
[He] played the King as if afraid someone else might play the ace.
-- Unattributed review of a performance of King Lear
@@ -21178,7 +21184,7 @@ He played the king as if afraid someone else would play the ace.
%
He tells you when you've got on too much lipstick,
And helps you with your girdle when your hips stick.
- -- O. Nash, on the perfect husband
+ -- Ogden Nash, on the perfect husband
%
He that breaks a thing to find out what it is has left the path of wisdom.
-- J. R. R. Tolkien
@@ -21187,7 +21193,7 @@ He that bringeth a present, findeth the door open.
-- Scottish proverb
%
He that composes himself is wiser than he that composes a book.
- -- Ben Franklin
+ -- Benjamin Franklin
%
He that is giddy thinks the world turns round.
-- William Shakespeare, "The Taming of the Shrew"
@@ -21228,14 +21234,16 @@ told the others, "I'll be waiting for you in heaven -- with a gun."
-- Jack Handey
%
He was a fiddler, and consequently a rogue.
- -- Jonathon Swift
+ -- Jonathan Swift
%
He was a modest, good-humored boy. It was Oxford that made him
insufferable.
%
He was part of my dream, of course --
but then I was part of his dream too.
- -- Lewis Carroll
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
He was so narrow-minded he could see through a keyhole with both eyes.
%
@@ -21249,7 +21257,7 @@ broadcasting industry attacks democracy itself.
-- William S. Paley, chairman of CBS
%
He who dares the wrong, acts right, that's how it happens!
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
He who despairs over an event is a coward, but he who holds hopes for
the human condition is a fool.
@@ -21259,7 +21267,7 @@ He who despises himself nevertheless esteems himself as a self-despiser.
-- Friedrich Nietzsche
%
He who enters his wife's dressing room is a philosopher or a fool.
- -- Balzac
+ -- Honore de Balzac
%
He who fears the unknown may one day flee from his own backside.
-- Sinbad
@@ -21357,10 +21365,10 @@ be the greatest benefactor the world has yet known.
-- Sir Richard Burton
%
He who slings mud generally loses ground.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
He who slings mud loses ground.
- -- Chinese Proverb
+ -- Chinese proverb
%
He who spends a storm beneath a tree, takes life with a grain of TNT.
%
@@ -21441,7 +21449,7 @@ Heaven, n.:
Heavier than air flying machines are impossible.
-- Lord Kelvin, President, Royal Society, c. 1895
%
-heavy, adj:
+Heavy, adj.:
Seduced by the chocolate side of the force.
%
Hedonist for hire... no job too easy!
@@ -21463,7 +21471,7 @@ how are they supposed to know you care?
Hell is empty and all the devils are here.
-- William Shakespeare, "The Tempest"
%
-hell, n:
+Hell, n.:
Truth seen too late.
%
Heller's Law:
@@ -21505,7 +21513,7 @@ Help a swallow land at Capistrano.
%
Help fight continental drift.
%
-HELP!!!! I'm being held prisoner in /usr/share/games/fortune/!
+HELP!!!! I'm being held prisoner in /usr/share/games/fortune!
%
Help me, I'm a prisoner in a Fortune cookie file!
%
@@ -21631,7 +21639,7 @@ Here there by tygers.
HERE'S A GOOD JOKE to do during an earthquake. Straddle a big crack in
the earth and if it opens wider, go, "Whoa! Whoa!" and flap your arms
around as if you're going to fall.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
Here's something to think about: How come you never see a headline like
`Psychic Wins Lottery.'
@@ -21752,7 +21760,7 @@ Call (511) 338-0959 for an immediate appointment.
%
Hier liegt ein Mann ganz ohnegleich;
Im Leibe dick, an Suenden reich.
-Wir haben ihn in das Grab gesteckt, Here lies a man with sundry flaws
+Wir haben ihn ins Grab gesteckt, Here lies a man with sundry flaws
Weil es uns duenkt er sei verreckt. And numerous Sins upon his head;
We buried him today because
As far as we can tell, he's dead.
@@ -21763,12 +21771,9 @@ Weil es uns duenkt er sei verreckt. And numerous Sins upon his head;
%
Higgeldy Piggeldy,
Hamlet of Elsinore
-Ruffled the critics by
-Dropping this bomb:
-"Phooey on Freud and his
-Psychoanalysis,
-Oedipus, Shmoedipus,
-I just loved Mom."
+Ruffled the critics by dropping this bomb:
+"Phooey on Freud and his Psychoanalysis --
+Oedipus, Shmoedipus, I just loved Mom."
%
Higgins: Doolittle, you're either an honest man or a rogue.
Doolittle: A little of both, Guv'nor. Like the rest of us, a
@@ -21937,7 +21942,7 @@ Hitchcock's Staple Principle:
Hitler used methods against white men in Europe, which by tacit
agreement between the cultural European nations were only to be
used against the coloured.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
Hlade's Law:
If you have a difficult task, give it to a lazy person --
@@ -21997,7 +22002,7 @@ HOGAN'S HEROES DRINKING GAME --
plan is impossible.
-- The prisoners capture an important German, and sneak him out the tunnel.
%
-Hollerith, v:
+Hollerith, v.:
What thou doest when thy phone is on the fritzeth.
%
Hollywood is where if you don't have happiness you send out for it.
@@ -22041,7 +22046,7 @@ Honesty pays, but it doesn't seem to pay enough to suit some people.
Honesty's the best policy.
-- Miguel de Cervantes
%
-honeymoon, n:
+Honeymoon, n.:
A short period of doting between dating and debting.
-- Ray C. Bandy
%
@@ -22085,7 +22090,7 @@ Hors d'oeuvres -- a ham sandwich cut into forty pieces.
-- Jack Benny
%
Horse sense is the thing a horse has which keeps it from betting on people.
- -- W.C. Fields
+ -- W. C. Fields
%
HOST SYSTEM NOT RESPONDING, PROBABLY DOWN. DO YOU WANT TO WAIT? (Y/N)
%
@@ -22113,7 +22118,7 @@ How apt the poor are to be proud.
How can you be in two places at once
when you're not anywhere at all?
%
-How can you do 'New Math' problems with an 'Old Math' mind?
+How can you do "New Math" problems with an "Old Math" mind?
-- Schulz
%
How can you govern a nation which has 246 kinds of cheese?
@@ -22194,7 +22199,7 @@ How cheerfully he seems to grin,
How neatly spreads his claws,
And welcomes little fishes in,
With gently smiling jaws!
- -- Lewis Carroll, "Alice in Wonderland"
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
How doth the VAX's C-compiler
Improve its object code.
@@ -22204,7 +22209,7 @@ And even as we speak does it
How patiently it seems to run
And spit out error flags,
While users, with frustration, all
- Tear their clothes to rags.
+ Tear all their clothes to rags.
%
How is the world ruled, and how do wars start? Diplomats tell lies to
journalists, and they believe what they read.
@@ -22277,7 +22282,6 @@ HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
#15 Your pet rock snaps at you.
%
HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
-
#32: You call your answering service and they've never heard of
you.
%
@@ -22443,7 +22447,7 @@ It is never any good to oneself.
-- Oscar Wilde, "An Ideal Husband"
%
I always say beauty is only sin deep.
- -- Saki, "Reginald's Choir Treat"
+ -- H. H. Munro, a.k.a. Saki, "Reginald's Choir Treat"
%
I always turn to the sports pages first, which record people's
accomplishments. The front page has nothing but man's failures.
@@ -22545,7 +22549,7 @@ I am more bored than you could ever possibly be. Go back to work.
I am NOMAD!
%
I am not a crook.
- -- Richard Nixon
+ -- Richard M. Nixon
%
I am not a politician and my other habits are also good.
-- A. Ward
@@ -22560,7 +22564,7 @@ I am not now and never have been a girl friend of Henry Kissinger.
-- Gloria Steinem
%
I am not now, nor have I ever been, a member of the demigodic party.
- -- Dennis Ritchie
+ -- Dennis M. Ritchie
%
I am not sure what this is, but an "F" would only dignify it.
-- English Professor
@@ -22687,13 +22691,13 @@ I bet the human brain is a kludge.
%
I BET WHAT HAPPENED was they discovered fire and invented the wheel on
the same day. Then that night, they burned the wheel.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I BET WHEN NEANDERTHAL KIDS would make a snowman, someone would always
end up saying, "Don't forget the thick heavy brows." Then they would get
embarrassed because they remembered they had the big hunky brows too, and
they'd get mad and eat the snowman.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I bet you have fun chasing the soap around the bathtub.
-- Princess Diana, to a one-armed war veteran during
@@ -22729,7 +22733,7 @@ I came, I saw, I deleted all your files.
%
I came out of twelve years of college and I didn't even know how to sew.
All I could do was account -- I couldn't even account for myself.
- -- Firesign Theatre
+ -- The Firesign Theatre
%
I came to MIT to get an education for myself and a diploma for my mother.
%
@@ -22963,7 +22967,7 @@ comes nearest to it of any.
%
I do not know whether I was then a man dreaming I was a
butterfly, or whether I am now a butterfly dreaming I am a man.
- -- Chuang-tzu
+ -- Chuang Tzu
%
I do not remember ever having seen a sustained argument by an author which,
starting from philosophical premises likely to meet with general acceptance,
@@ -23103,13 +23107,13 @@ he starts to practice law.
%
I DON'T THINK I'M ALONE when I say I'd like to see more and more planets
fall under the ruthless domination of our solar system.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
"I don't think so," said Ren'e Descartes. Just then, he vanished.
%
I don't think they are going to give a shit about the Republican
Committee trying to bug the Democratic Committee's headquarters.
- -- Richard Nixon, 1972
+ -- Richard M. Nixon, 1972
%
"I don't understand," said the scientist, "why you lemmings all rush down
to the sea and drown yourselves."
@@ -23142,7 +23146,7 @@ thinking about eliminating a federal program under which scientists
broadcast signals to alien beings. This would be a large mistake.
Alien beings have nuclear blaster death cannons. You cannot cut off
their federal programs as if they were merely poor people ...
- -- Davy Barry, "THE ALIENS ARE COMING, THE ALIENS ARE
+ -- Dave Barry, "THE ALIENS ARE COMING, THE ALIENS ARE
COMING!"
%
I don't want to bore you, but there's nobody else around for me to bore.
@@ -23182,7 +23186,7 @@ so I woke up from sheer boredom.
%
I figure that if God actually does exist, He's big enough to understand an
honest difference of opinion.
- - Isaac Asimov
+ -- Isaac Asimov
%
I finally went to the eye doctor. I got contacts.
I only need them to read, so I got flip-ups.
@@ -23199,7 +23203,7 @@ I found Rome a city of bricks and left it a city of marble.
%
I gained nothing at all from Supreme Enlightenment, and for that very
reason it is called Supreme Enlightenment.
- -- Gotama Buddha
+ -- Gautama Buddha
%
I gave my love an Apple, that had no core;
I gave my love a building, that had no floor;
@@ -23277,12 +23281,12 @@ human emotions which is freaking out. Another emotion is greed, as when
you kill someone for money or something like that. Another emotion is
generosity, as when you pay someone double what he paid for his stupid
puppet.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I GUESS I'LL NEVER FORGET HER. And maybe I don't want to. Her spirit
was wild, like a wild monkey. Her beauty was like a beautiful horse
being ridden by a wild monkey. I forget her other qualities.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I guess I've been so wrapped up in playing the game that I never took
time enough to figure out where the goal line was -- what it meant to
@@ -23296,14 +23300,14 @@ other people... Certainty is just an emotion.
I GUESS OF ALL MY UNCLES, I liked Uncle Caveman the best. We called him
Uncle Caveman because he lived in a cave and because sometimes he'd eat
one of us. Later, we found out he was a bear.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I guess the Little League is even littler than we thought.
-- D. Cavett
%
I GUESS WE WERE ALL GUILTY, in a way. We shot him, we skinned him, and
we all got a complimentary bumper sticker that said, "I helped skin Bob."
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I had a dream last night...
I dreamt about 1976.
@@ -23423,7 +23427,7 @@ The funniest thing about him is the way he likes to grow--
Not at all like proper children, which is always very slow;
For he sometimes shoots up taller, like an india-rubber ball,
And he sometimes gets so little that there's none of him at all.
- -- Robert L. Stevenson
+ -- Robert Louis Stevenson
%
I have a map of the United States. It's actual size.
I spent last summer folding it.
@@ -23481,9 +23485,9 @@ I tell them the truth and they never believe me.
I have found it impossible to carry the heavy burden of responsibility and
to discharge my duties as king as I would wish to do without the help and
support of the woman I love.
- -- Edward, Duke of Windsor, 1936, announcing his abdication
+ -- Edward, Duke of Windsor, announcing his abdication
of the British throne in order to marry the American
- divorcee Wallis Warfield Simpson.
+ divorcee Wallis Warfield Simpson. (1936)
%
I have found little that is good about human beings. In my experience
most of them are trash.
@@ -23622,7 +23626,7 @@ declare the construction of such machinery impracticable...
And at a period when the progress of physical science is obstructed
by that exhausting intellectual and manual labor, indispensable for its
advancement, which it is the object of the Analytical Engine to relieve, I
-think the application of machinery in aid of the most complicated and abtruse
+think the application of machinery in aid of the most complicated and abstruse
calculations can no longer be deemed unworthy of the attention of the country.
In fact, there is no reason why mental as well as bodily labor should not
be economized by the aid of machinery.
@@ -23927,7 +23931,7 @@ I will not Reason and Compare; my business is to Create.
-- William Blake, "Jerusalem"
%
I must get out of these wet clothes and into a dry Martini.
- -- Alexander Woolcott
+ -- Alexander Woollcott
%
I must have a prodigious quantity of mind; it takes me as much as a
week sometimes to make it up.
@@ -24010,7 +24014,7 @@ I've never seen a purple cow
I never hope to see one
But from the milk we're getting now
There certainly must be one
- -- Odgen Nash
+ -- Ogden Nash
Ah, yes, I wrote "The Purple Cow"
I'm sorry now I wrote it
@@ -24021,7 +24025,7 @@ I'll kill you if you quote it.
I never take work home with me; I always leave it in some bar along the way.
%
I never vote for anyone. I always vote against.
- -- W.C. Fields
+ -- W. C. Fields
%
I often quote myself; it adds spice to my conversation.
-- George Bernard Shaw
@@ -24150,7 +24154,7 @@ But only what I tell it.
I really look with commiseration over the great body of my fellow citizens
who, reading newspapers, live and die in the belief that they have known
something of what has been passing in their time.
- -- Harry S. Truman
+ -- Thomas Jefferson
%
I recognize terror as the finest emotion and so I will try to terrorize the
reader. But if I find that I cannot terrify, I will try to horrify, and if
@@ -24167,7 +24171,7 @@ I remember once being on a station platform in Cleveland at four in the
morning. A black porter was carrying my bags, and as we were waiting for
the train to come in, he said to me: "Excuse me, Mr. Cooke, I don't want to
invade your privacy, but I have a bet with a friend of mine. Who composed
-the opening theme music of 'Omnibus'? My friend said Virgil Thomson." I
+the opening theme music of `Omnibus'? My friend said Virgil Thomson." I
asked him, "What do you say?" He replied, "I say Aaron Copeland." I said,
"You're right." The porter said, "I knew Thomson doesn't write counterpoint
that way." I told that to a network president, and he was deeply unimpressed.
@@ -24233,7 +24237,7 @@ There's a bad moon on the rise.
%
I see a good deal of talk from Washington about lowering taxes. I hope
they do get 'em lowered down enough so people can afford to pay 'em.
- -- The Best of Will Rogers
+ -- Will Rogers
%
I see the eigenvalue in thine eye,
I hear the tender tensor in thy sigh.
@@ -24262,6 +24266,9 @@ I said to him, and I said it plain And when I found the door was shut,
"Is that all?" asked Alice.
"That is all." said Humpty Dumpty. "Goodbye."
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
I sent a message to another time,
But as the days unwind -- this I just can't believe,
@@ -24324,7 +24331,7 @@ Easy. I own Chicago. I own Miami. I own Las Vegas.
-- Sam Giancana, when asked what he did for a living
%
I stick my neck out for nobody.
- -- Humphrey Bogart, "Casablanca"
+ -- Humphrey Bogart, "Casablanca" (1942)
%
I stood on the leading edge,
The eastern seaboard at my feet.
@@ -24338,8 +24345,8 @@ I stopped believing in Santa Claus when I was six. Mother took me to
see him in a department store and he asked for my autograph.
-- Shirley Temple
%
-I suggest a new strategy, Artoo: let the Wookiee win.
- -- CP30
+I suggest a new strategy, R2: let the Wookiee win.
+ -- C-3PO
%
I suggest you locate your hot tub outside your house, so it won't do
too much damage if it catches fire or explodes. First you decide which
@@ -24436,14 +24443,14 @@ I tell ya, I was afraid to go to the bathroom.
-- Rodney Dangerfield
%
I think... I think it's in my basement... Let me go upstairs and check.
- -- Escher
+ -- M. C. Escher
%
I think a relationship is like a shark. It has to constantly move forward
or it dies. Well, what we have on our hands here is a dead shark.
-- Woody Allen
%
I think I'll snatch a kiss and flee.
- -- Shakespeare
+ -- William Shakespeare
%
I think I'm schizophrenic. One half of me's
paranoid and the other half's out to get him.
@@ -24453,13 +24460,13 @@ because I couldn't remember the proof.
-- Baker, Pure Math 351a
%
I THINK MAN INVENTED THE CAR by instinct.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I think sex is better than logic, but I can't prove it.
%
I think she must have been very strictly brought up, she's so
desperately anxious to do the wrong thing correctly.
- -- Saki, "Reginald on Worries"
+ -- H. H. Munro, a.k.a. Saki, "Reginald on Worries"
%
I think that all good, right thinking people in this country are sick
and tired of being told that all good, right thinking people in this
@@ -24490,7 +24497,7 @@ They went this morning with the dawn.
A logging firm from out of town
Came and chopped the trees all down.
But I will trick those dirty skunks
-And write a brand new poem called 'Trunks'.
+And write a brand new poem called "Trunks."
%
I think the sky is blue because it's a shift from black through purple
to blue, and it has to do with where the light is. You know, the
@@ -24518,16 +24525,16 @@ I THINK THERE SHOULD BE SOMETHING in science called the "reindeer effect."
I don't know what it would be, but I think it'd be good to hear someone
say, "Gentlemen, what we have here is a terrifying example of the reindeer
effect."
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I think, therefore I am... I think.
%
I think there's a world market for about five computers.
- -- attr. Thomas J. Watson (Chairman of the Board, IBM), 1943
+ -- attr. Thomas J. Watson, Chairman of the Board, IBM (1943)
%
I THINK THEY SHOULD CONTINUE the policy of not giving a Nobel Prize for
paneling.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I think we are in Rats Alley where the dead men lost their bones.
-- T. S. Eliot
@@ -24544,14 +24551,14 @@ conversation ...
-- Dave Barry, "The Stuff of Etiquette"
%
I think we're all Bozos on this bus.
- -- Firesign Theatre
+ -- The Firesign Theatre
%
I think we're in trouble.
-- Han Solo
%
I think your opinions are reasonable,
except for the one about my mental instability.
- -- Psychology Professor, Farifield University
+ -- Psychology Professor, Fairfield University
%
"I thought that you said you were 20 years old!"
"As a programmer, yes," she replied,
@@ -24578,7 +24585,8 @@ And would not have had fun with the game.
%
I thought there was something fishy about the butler. Probably a Pisces,
working for scale.
- -- Firesign Theatre, "The Further Adventures of Nick Danger"
+ -- The Firesign Theatre,
+ "The Further Adventures of Nick Danger"
%
I thought YOU silenced the guard!
%
@@ -24967,7 +24975,7 @@ we could all take a shot at him and not feel too bad.
%
I WISH I HAD A KRYPTONITE CROSS, because then you could keep both Dracula
and Superman away.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I wish there was a knob on the TV where you could turn up the
intelligence. They've got one called brightness, but it doesn't
@@ -24998,7 +25006,7 @@ I don't know yet and all kinds of adventures and battles."
-- Bastian B. Bux
%
I wonder what the leash and collar set does for excitement?
- -- Tramp, Lady and the Tramp
+ -- Tramp, "Lady and the Tramp"
%
I worked in a health food store once. A guy came in and asked me,
"If I melt dry ice, can I take a bath without getting wet?"
@@ -25015,7 +25023,7 @@ only they won't let me raise my voice.
-- Winkle
%
I would have made a good pope.
- -- Richard Nixon
+ -- Richard M. Nixon
%
I would have promised those terrorists a trip to Disneyland if it would have
gotten the hostages released. I thank God they were satisfied with the
@@ -25036,7 +25044,7 @@ understanding, in mutuality of interest, in concern for the common good,
our tasks will be solved.
-- Warren G. Harding
%
-I would like to electrocute everyone who uses the word 'fair' in connection
+I would like to electrocute everyone who uses the word "fair" in connection
with income tax policies.
-- William F. Buckley
%
@@ -25047,18 +25055,18 @@ And what I was fencing out.
%
I would much rather have men ask why
I have no statue, than why I have one.
- -- Marcus Procius Cato
+ -- Marcus Porcius Cato
%
I would not like to be a political leader in Russia. They never know when
they're being taped.
- -- Richard Nixon
+ -- Richard M. Nixon
I love America. You always hurt the one you love.
-- David Frye impersonating Nixon
%
I would rather be a serf in a poor man's house
and be above ground than reign among the dead.
- -- Achilles, "The Odessey", XI, 489-91
+ -- Achilles, "The Odyssey", XI, 489-91
%
I would rather say that a desire to drive fast
sports cars is what sets man apart from the animals.
@@ -25112,7 +25120,7 @@ IBM:
%
IBM Advanced Systems Group -- a bunch of mindless jerks,
who'll be first against the wall when the revolution comes...
- -- with regrets to D. Adams
+ -- with regrets to Douglas Adams
%
IBM had a PL/I,
Its syntax worse than JOSS;
@@ -25143,7 +25151,7 @@ I'd just as soon kiss a Wookiee.
I'D LIKE TO BE BURIED INDIAN-STYLE, where they put you up on a high rack,
above the ground. That way, you could get hit by meteorites and not even
feel it.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
I'd like to meet the guy who invented beer and see what he's working on now.
%
@@ -25179,7 +25187,7 @@ Yes life is fine when things combine,
Like ham in beef chow mein...
But lord, this time I think I mind,
They've put acid in my rain.
- --- Milo Bloom
+ -- Milo Bloom
%
I'd never join any club that would have the likes of me as a member.
-- Groucho Marx
@@ -25198,7 +25206,7 @@ I'd rather have a free bottle in front of me than a prefrontal lobotomy.
[Also attributed to S. Clay Wilson. Ed.]
%
I'd rather have two girls at 21 each than one girl at 42.
- -- W.C. Fields
+ -- W. C. Fields
%
I'd rather just believe that it's done by little elves running around.
%
@@ -25276,7 +25284,7 @@ is certain to vote acquittal, save in those instances where it votes guilty.
IF A KID ASKS YOU where rain comes from, I think a cute thing to tell him
is, "God is crying." And if he asks why God is crying, another cute thing
to tell him is, "Probably because of something you did."
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
If a listener nods his head when you're
explaining your program, wake him up.
@@ -25360,7 +25368,7 @@ If a thing's worth doing, it is worth doing badly.
-- G. K. Chesterton
%
If a thing's worth having, it's worth cheating for.
- -- W.C. Fields
+ -- W. C. Fields
%
If a train station is a place where a train stops, what's a workstation?
%
@@ -25451,7 +25459,7 @@ If at first you don't succeed, try, try again.
%
If at first you don't succeed, try, try again.
Then quit. No use being a damn fool about it.
- -- W.C. Fields
+ -- W. C. Fields
[Also attributed to Roy Mengot. Ed.]
%
@@ -25511,7 +25519,7 @@ no middleman.
%
If every kid had a funny tooth to bite down on whenever the world disappointed
him, prussic acid could solve our population problems in one generation.
- -- G.C. Edmonson's Albert, "The Man Who Corrupted Earth"
+ -- G. C. Edmonson's Albert, "The Man Who Corrupted Earth"
%
If everybody minded their own business, the world would go
around a deal faster.
@@ -25681,7 +25689,7 @@ If *I* had a hammer, there'd be no more folk singers.
%
IF I HAD A MINE SHAFT, I don't think I would just abandon it. There's
got to be a better way.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
If I had a plantation in Georgia and a home in Hell,
I'd sell the plantation and go home.
@@ -25754,7 +25762,7 @@ I would send a barrel or so to my other generals.
-- Abraham Lincoln, on General Grant
%
If I love you, what business is it of yours?
- -- Johann van Goethe
+ -- Johann Wolfgang von Goethe
%
If I made peace with Russia today, I'd only attack her again tomorrow. I
just couldn't help myself.
@@ -25932,7 +25940,7 @@ be a merrier world.
If once a man indulges himself in murder, very soon he comes to think little
of robbing; and from robbing he next comes to drinking and Sabbath-breaking,
and from that to incivility and procrastination.
- -- Thomas De Quincey (1785 - 1859)
+ -- Thomas De Quincey (1785-1859)
%
If one cannot enjoy reading a book over and
over again, there is no use in reading it at all.
@@ -25949,7 +25957,7 @@ get an unfair advantage.
-- John Dewey, "Democracy in the Schools", 1908
%
If one studies too zealously, one easily loses his pants.
- -- A. Einstein
+ -- Albert Einstein
%
If one tells the truth, one is sure, sooner or later, to be found out.
-- Oscar Wilde,
@@ -26064,7 +26072,7 @@ Their romance might have flourished.
But he built tetrahedral in his shape,
His ions ferric,
Love could not help but die,
-Uncatylised, inert, and undernourished.
+Uncatalyzed, inert, and undernourished.
%
If society fits you comfortably enough, you call it freedom.
-- Robert Frost
@@ -26213,7 +26221,7 @@ of this life.
-- Albert Camus
%
If there is a wrong way to do something, then someone will do it.
- -- Edward A. Murphy Jr.
+ -- Edward A. Murphy, Jr.
%
If there is any realistic deterrent to marriage, it's the fact that you
can't afford divorce.
@@ -26283,7 +26291,7 @@ If two people love each other, there can be no happy end to it.
-- Ernest Hemingway
%
If two wrongs don't make a right, try three.
- -- Laurence J. Peter
+ -- Dr. Laurence J. Peter
%
If value corrupts then absolute value corrupts absolutely.
%
@@ -26349,7 +26357,7 @@ If women are supposed to be less rational and more emotional at the
beginning of our menstrual cycle, when the female hormone is at its
lowest level, then why isn't it logical to say that in those few days
women behave the most like the way men behave all month long?
- -- Gloria Steinham
+ -- Gloria Steinem
%
If women didn't exist, all the money in the world would have no meaning.
-- Aristotle Onassis
@@ -26522,12 +26530,12 @@ If you ever want to get anywhere in politics, my boy, you're going to
have to get a toehold in the public eye.
%
If you ever want to have a lot of fun, I recommend that you go off and program
-an imbedded system. The salient characteristic of an imbedded system is that
+an embedded system. The salient characteristic of an embedded system is that
it cannot be allowed to get into a state from which only direct intervention
-will suffice to remove it. An imbedded system can't permanently trust anything
+will suffice to remove it. An embedded system can't permanently trust anything
it hears from the outside world. It must sniff around, adapt, consider, sniff
around, and adapt again. I'm not talking about ordinary modular programming
-carefulness here. No. Programming an imbedded system calls for undiluted
+carefulness here. No. Programming an embedded system calls for undiluted
raging maniacal paranoia. For example, our ethernet front ends need to know
what network number they are on so that they can address and route PUPs
properly. How do you find out what your network number is? Easy, you ask a
@@ -26746,13 +26754,13 @@ ice, but no cup.
%
If you put garbage in a computer nothing comes out but garbage. But
this garbage, having passed through a very expensive machine, is
-somehow enobled and none dare criticize it.
+somehow ennobled and none dare criticize it.
%
If you put it off long enough, it might go away.
%
If you put tomfoolery into a computer, nothing comes out but tomfoolery.
But this tomfoolery, having passed through a very expensive machine,
-is somehow enobled and no-one dare criticise it.
+is somehow ennobled and no-one dare criticise it.
-- Pierre Gallois
%
If you put your supper dish to your ear you can hear the sounds of a
@@ -26799,8 +26807,8 @@ they taste more like prunes than rhubarb does.
%
If you stick a stock of liquor in your locker,
It is slick to stick a lock upon your stock.
-Or some joker who is slicker,
-Will trick you of your liquor,
+ Or some joker who is slicker,
+ Will trick you of your liquor,
If you fail to lock your liquor with a lock.
%
If you stick your head in the sand,
@@ -26883,7 +26891,7 @@ If you treat people right they will treat you right -- 90% of the time.
If you try to please everyone, somebody is not going to like it.
%
If you understand what you're doing, you're not learning anything.
- -- A. L.
+ -- Abraham Lincoln
%
If you wait long enough, it will go away... after having
done its damage. If it was bad, it will be back.
@@ -26945,7 +26953,7 @@ If you wish to be happy for one hour, get drunk.
If you wish to be happy for three days, get married.
If you wish to be happy for a month, kill your pig and eat it.
If you wish to be happy forever, learn to fish.
- -- Chinese Proverb
+ -- Chinese proverb
%
If you wish to live wisely, ignore sayings -- including this one.
%
@@ -26970,7 +26978,7 @@ If you do that, you are loosening the tendrils that are holding you to the
If you would keep a secret from an enemy, tell it not to a friend.
%
If you would know the value of money, go try to borrow some.
- -- Ben Franklin
+ -- Benjamin Franklin
%
If you would understand your own age, read the works
of fiction produced in it. People in disguise speak freely.
@@ -26985,7 +26993,7 @@ If your bread is stale, make toast.
%
If your enemy is buried in quicksand up to his neck, pull him out.
If he is buried up to his eyes, step on his head.
- -- Niccoli Machiavelli, "The Prince"
+ -- Niccolo Machiavelli, "The Prince"
%
If your happiness depends on what somebody else does,
I guess you do have a problem.
@@ -27086,7 +27094,9 @@ Il brilgue: les t^oves libricilleux
Se gyrent et frillant dans le guave,
Enm^im'es sont les gougebosquex,
Et le m^omerade horgrave.
- -- Lewis Carroll, "Through the Looking Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
Iles's Law:
There is always an easier way to do it. When looking directly
@@ -27173,12 +27183,12 @@ that I could have evolved from man.
-- "Friday's Child", when asked to help the very pregnant
Ellen up a steep incline.
"I'm a doctor, not a bricklayer."
- -- Devil in the Dark", when asked to patch up the Horta
+ -- "Devil in the Dark", when asked to patch up the Horta.
"I'm a doctor, not an engineer."
-- "Mirror, Mirror", when asked by Scotty for help in
- Engineering aboard the ISS Enterprise.
+ Engineering aboard the USS Enterprise.
"I'm a doctor, not a coal miner."
- -- "The Empath", on being beneath the surface of Minara 2
+ -- "The Empath", on being beneath the surface of Minara 2.
"I'm a surgeon, not a psychiatrist."
-- "City on the Edge of Forever", on Edith Keeler's remark
that Kirk talked strangely.
@@ -27195,7 +27205,7 @@ a sports jacket and take off my brain.
I'm a Lisp variable -- bind me!
%
I'm a lucky guy, and I'm happy to be with the Yankees. And I want to
- thank everyone for making this night necessary.
+thank everyone for making this night necessary.
-- Yogi Berra at a dinner in his honor
%
I'm all for computer dating, but I
@@ -27314,7 +27324,7 @@ Please say that you're not mad at me
%
I'm living so far beyond my income that we may almost be said to be
living apart.
- -- E.E. Cummings
+ -- e. e. cummings
%
I'm N-ary the tree, I am,
N-ary the tree, I am, I am.
@@ -27328,7 +27338,7 @@ N-ary the tree I am.
-- Stolen from Paul Revere and the Raiders
%
I'm not a lovable man.
- -- Richard Nixon
+ -- Richard M. Nixon
%
I'm not a real movie star -- I've still got the same wife I started out
with twenty-eight years ago.
@@ -27424,7 +27434,7 @@ I'm willing to sacrifice anything for this cause, even other people's
lives.
%
Imagination is more important than knowledge.
- -- A. Einstein
+ -- Albert Einstein
%
Imagination is the one weapon in the war against reality.
-- Jules de Gaultier
@@ -27493,8 +27503,9 @@ Boss is reading it.
%
Impossible, adj.:
(1) I wouldn't like it and when it happens I won't approve;
-(2) I can't be bothered; (3) God can't be bothered. Meaning (3) may
-perhaps be valid but the others are 101% whaledreck.
+ (2) I can't be bothered;
+ (3) God can't be bothered.
+Meaning (3) may perhaps be valid but the others are 101% whaledreck.
-- Chad C. Mulligan, "The Hipcrime Vocab"
%
In 1869 the waffle iron was invented for people who had wrinkled
@@ -27583,7 +27594,7 @@ this a form of primitive self-expression. In America we call it golf.
%
In America, any boy may become president and I suppose that's just one
of the risks he takes.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
In America today ... we have Woody Allen, whose humor has become so
sophisticated that nobody gets it any more except Mia Farrow. All
@@ -27772,7 +27783,7 @@ which will melt a brass door-knob and weather which will only make it mushy.
-- Mark Twain
%
In Italy, for thirty years under the Borgias, they had warfare, terror,
-murder, and bloodshed, but they produced Michaelangelo, Leonardo da Vinci
+murder, and bloodshed, but they produced Michelangelo, Leonardo da Vinci
and the Renaissance. In Switzerland, they had brotherly love, they had
five hundred years of democracy and peace -- and what did they produce?
The cuckoo-clock.
@@ -27829,7 +27840,7 @@ your left leg, it's modern architecture.
%
IN MY OPINION anyone interested in improving himself should not rule out
becoming pure energy.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
In Nature there are neither rewards nor
punishments, there are consequences.
@@ -27910,8 +27921,8 @@ We shall encounter, counting, face to face.
In San Francisco, Halloween is redundant.
-- Will Durst
%
-In science it often happens that scientists say, 'You know that's a really
-good argument; my position is mistaken,' and then they actually change
+In science it often happens that scientists say, "You know that's a really
+good argument; my position is mistaken," and then they actually change
their minds and you never hear that old view from them again. They really
do it. It doesn't happen as often as it should, because scientists are
human and change is sometimes painful. But it happens every day. I cannot
@@ -27945,7 +27956,7 @@ And that, I think, was the handle -- the sense of inevitable victory
over the forces of Old and Evil. Not in any mean or military sense; we
didn't need that. Our energy would simply `prevail'. There was no
point in fighting -- on our side or theirs. We had all the momentum;
-we were riding the crest of a high and beautiful wave ....
+we were riding the crest of a high and beautiful wave ...
So now, less than five years later, you can go up on a steep hill in
Las Vegas and look West, and with the right kind of eyes you can almost
@@ -27962,7 +27973,7 @@ And still there was nothing, but at least now you could see it.
%
In the beginning was the word.
But by the time the second word was added to it,
-There was trouble.
+there was trouble.
For with it came syntax ...
-- John Simon
%
@@ -28038,7 +28049,7 @@ Sun is driven by the Grateful Dead.
-- Egyptian Book of the Dead
%
In the long run, every program becomes rococo, and then rubble.
- -- Alan Perlis
+ -- Alan J. Perlis
%
In the long run we are all dead.
-- John Maynard Keynes
@@ -28152,7 +28163,7 @@ my advice.
%
In time, every post tends to be occupied by an
employee who is incompetent to carry out its duties.
- -- Dr. L. J. Peter
+ -- Dr. Laurence J. Peter
%
In Tulsa, Oklahoma, it is against the law to open a soda bottle without
the supervision of a licensed engineer.
@@ -28191,7 +28202,7 @@ And there were gardens bright with sinuous rills,
Where blossomed many an incense-bearing tree;
And here were forest ancient as the hills,
Enfolding sunny spots of greenery.
- -- S. T. Coleridge, "Kubla Kahn"
+ -- Samuel T. Coleridge, "Kubla Kahn"
%
In youth, it was a way I had
To do my best to please,
@@ -28315,7 +28326,7 @@ Inglish Spocken Hier: some mangled translations
-- Colin Bowles, San Francisco Chronicle
%
-ingrate, n:
+Ingrate, n.:
A man who bites the hand that feeds him,
and then complains of indigestion.
%
@@ -28405,7 +28416,7 @@ and 8 percent said "Gimme a quarter?"
%
Interfere? Of course we should interfere! Always do what you're
best at, that's what I say.
- -- Doctor Who
+ -- "Doctor Who"
%
Interpreter, n.:
One who enables two persons of different languages to understand
@@ -28479,7 +28490,7 @@ Is knowledge knowable? If not, how do we know that?
Is not marriage an open question, when it is alleged, from the beginning
of the world, that such as are in the institution wish to get out,
and such as are out wish to get in?
- -- Ralph Emerson
+ -- Ralph Waldo Emerson
%
Is sex dirty? Only if it's done right.
-- Woody Allen, "All You Ever Wanted To Know About Sex"
@@ -28500,7 +28511,7 @@ Breakfast in London, dinner in New York, luggage in Brazil.
%
Isn't it conceivable to you that an intelligent
person could harbor two opposing ideas in his mind?
- -- Adlai Stevenson, to reporters
+ -- Adlai E. Stevenson, to reporters
%
Isn't it interesting that the same people who laugh at science fiction
listen to weather forecasts and economists?
@@ -28701,7 +28712,7 @@ to argue with the belly, since it has no ears.
%
It is a lesson which all history teaches
wise men, to put trust in ideas, and not in circumstances.
- -- Emerson
+ -- Ralph Waldo Emerson
%
It is a poor judge who cannot award a prize.
%
@@ -28731,7 +28742,7 @@ but would also be three months late, and of much lower quality. I did, and
it was. He was right on both counts. Moreover, the lack of conceptual
integrity made the system far more costly to build and change, and I would
estimate that it added a year to debugging time.
- -- Frederick Brooks Jr., "The Mythical Man Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
%
It is a wise father that knows his own child.
-- William Shakespeare, "The Merchant of Venice"
@@ -28739,7 +28750,7 @@ It is a wise father that knows his own child.
It is against the grain of modern education to teach children to program.
What fun is there in making plans, acquiring discipline in organizing
thoughts, devoting attention to detail, and learning to be self-critical?
- -- Alan Perlis
+ -- Alan J. Perlis
%
It is against the law for a monster to enter the corporate limits of
Urbana, Illinois.
@@ -28771,7 +28782,7 @@ Curiously enough, the dolphins had long known of the impending
destruction of the of the planet Earth and had made many attempts to
alert mankind to the danger; but most of their communications were
misinterpreted ...
- -- Douglas Adams, "The Hitchhiker's Guide To The Galaxy"
+ -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
%
It is annoying to be honest to no purpose.
-- Publius Ovidius Naso (Ovid)
@@ -28829,7 +28840,7 @@ admit it frankly and try another. But above all, try something.
%
It is contrary to reasoning to say that there
is a vacuum or space in which there is absolutely nothing.
- -- Descartes
+ -- Rene Descartes
%
It is convenient that there be gods, and,
as it is convenient, let us believe there are.
@@ -28914,7 +28925,7 @@ without your help.
It is Fortune, not Wisdom, that rules man's life.
%
It is fruitless:
- to become lacrymose over precipitately departed lactate fluid.
+ to become lachrymose over precipitately departed lactate fluid.
to attempt to indoctrinate a superannuated canine with
innovative maneuvers.
@@ -29002,10 +29013,10 @@ It is not a good omen when goldfish commit suicide.
%
It is not doing the thing we like to do, but liking the thing we have to do,
that makes life blessed.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
It is not enough that I should succeed. Others must fail.
- -- Ray Kroc, Founder of McDonald's
+ -- Ray Kroc, founder of McDonald's
[Also attributed to David Merrick. Ed.]
It is not enough to succeed. Others must fail.
@@ -29034,8 +29045,8 @@ and he who makes haste with his feet misses his way.
It is not necessary to inquire whether a woman would like something for
dessert. The answer is yes, she would like something for dessert, but
she would like you to order it so she can pick at it with your fork. She
-does not want you to call attention to this by saying, 'If you wanted a
-dessert, why didn't you order one?' You must understand, she has the
+does not want you to call attention to this by saying, "If you wanted a
+dessert, why didn't you order one?" You must understand, she has the
dessert she wants. The dessert she wants is contained within yours.
-- Merrill Marcoe, "An Insider's Guide to the American Woman"
%
@@ -29093,7 +29104,7 @@ to be obscene, they could never have dared to be great.
%
It is only with the heart one can see clearly;
what is essential is invisible to the eye.
- -- The Fox, 'The Little Prince"
+ -- The Fox, "The Little Prince"
%
It is perfectly permissible for every system call to fail with [ENOTADUCK]
unless the first five bytes of the caller's address space contain the
@@ -29238,7 +29249,7 @@ a hundred drumsticks, then the guy at Marineland says, "You can't throw
that chicken to the dolphins. They eat fish."
Sure they eat fish if that's all you give them! Man, wise up.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
It [marriage] happens as with cages: the birds without despair
to get in, and those within despair of getting out.
@@ -29398,7 +29409,7 @@ when you're stickin' those artificial stimulants in your arm.
%
It was one of those perfect summer days -- the sun was shining, a breeze
was blowing, the birds were singing, and the lawn mower was broken ...
- --- James Dent
+ -- James Dent
%
It was one time too many
One word too few
@@ -29470,7 +29481,7 @@ the way some people are of everything.
%
It would save me a lot of time if you just gave up and went mad now.
%
-italic, adj:
+Italic, adj.:
Slanted to the right to emphasize key phrases. Unique to
Western alphabets; in Eastern languages, the same phrases
are often slanted to the left.
@@ -29549,7 +29560,7 @@ but why do the rats always have to win?
It's better to be quotable than to be honest.
-- Tom Stoppard
%
-It's better to be wanted for murder that not to be wanted at all.
+It's better to be wanted for murder than not to be wanted at all.
-- Marty Winch
%
It's better to burn out than to fade away.
@@ -29647,9 +29658,9 @@ our's either. It's ours, and likewise yours and theirs.
It's just a jump to the left
And then a step to the right.
Put your hands on your hips
- And pull your knees in tight.
-It's the pelvic thrust
- That really gets you insa-a-a-a-ane
+ You bring your knees in tight.
+But it's the pelvic thrust
+ That really drives you insa-a-a-a-a-ane!
LET'S DO THE TIME WARP AGAIN!
@@ -29779,7 +29790,7 @@ as a warning to others.
%
It's pretty hard to tell what does bring happiness;
poverty and wealth have both failed.
- -- Kim Hubbard
+ -- Kin Hubbard
%
It's raisins that make Post Raisin Bran so raisiny ...
%
@@ -29947,7 +29958,7 @@ bad taste.
-- Keith Richards
%
I've never struck a woman in my life, not even my own mother.
- -- W.C. Fields
+ -- W. C. Fields
%
I've noticed several design suggestions in your code.
%
@@ -29968,7 +29979,7 @@ And from that full meridian of my glory
I haste now to my setting. I shall fall,
Like a bright exhalation in the evening
And no man see me more.
- -- Shakespeare
+ -- William Shakespeare
%
I've tried several varieties of sex. The conventional position makes
me claustrophobic, and the others either give me a stiff neck or lockjaw.
@@ -29996,7 +30007,7 @@ all except ones; the mean
the dead ones kind dirty clean)
all
except the green ones
- -- e e cummings
+ -- e. e. cummings
%
James Joyce -- an essentially private man who wished his total
indifference to public notice to be universally recognized.
@@ -30016,7 +30027,7 @@ television?" and "Good night".
-- Goodman Ace, letter to Groucho Marx, in The Groucho
Letters, 1967
%
-Japan, n:
+Japan, n.:
A fictional place where elves, gnomes and economic imperialists
create electronic equipment and computers using black magic. It
is said that in the capital city of Akihabara, the streets are
@@ -30055,7 +30066,7 @@ JOB INTERVIEW:
The excruciating process during which personnel officers
separate the wheat from the chaff -- then hire the chaff.
%
-job Placement, n:
+Job Placement, n.:
Telling your boss what he can do with your job.
%
Joe Cool always spends the first two weeks at college sailing his Frisbee.
@@ -30073,7 +30084,7 @@ whispered Joe. "I'm the one who poisoned you."
%
Joe's sister puts spaghetti in her shoes!
%
-jogger, n:
+Jogger, n.:
An odd sort of person with a thing for pain.
%
John Dame May Oscar
@@ -30216,7 +30227,7 @@ going to get hit.
Just because the message may never be
received does not mean it is not worth sending.
%
-Just because they are called 'forbidden' transitions does not mean that they
+Just because they are called "forbidden" transitions does not mean that they
are forbidden. They are less allowed than allowed transitions, if you see
what I mean.
-- From a Part 2 Quantum Mechanics lecture
@@ -30230,7 +30241,7 @@ condition doesn't mean he knows what it is.
Just because you're paranoid doesn't mean they AREN'T after you.
%
Just close your eyes, tap your heels together three times,
-and think to yourself, `There's no place like home.'
+and think to yourself, "There's no place like home."
-- Billie Burke as Glinda, "The Wizard of Oz"
%
Just give Alice some pencils and she will stay busy for hours.
@@ -30253,7 +30264,7 @@ What a glorious time to be free.
%
Just once, I wish we would encounter
an alien menace that wasn't immune to bullets.
- -- The Brigader, "Dr. Who"
+ -- The Brigadier, "Doctor Who"
%
Just out of curiosity does this actually mean something or have some
of the few remaining bits of your brain just evaporated?
@@ -30309,7 +30320,7 @@ Justice always prevails ... three times out of seven!
Justice is incidental to law and order.
-- J. Edgar Hoover
%
-Justice, n:
+Justice, n.:
A decision in your favor.
%
K: Cobalt's metal, hard and shining;
@@ -30446,7 +30457,7 @@ Kennedy's Market Theorem:
Kent's Heuristic:
Look for it first where you'd most like to find it.
%
-kern, v:
+Kern, v.:
1. To pack type together as tightly as the kernels on an ear
of corn. 2. In parts of Brooklyn and Queens, N.Y., a small,
metal object used as part of the monetary system.
@@ -30494,13 +30505,13 @@ Kime's Law for the Reward of Meekness:
Turning the other cheek merely ensures two bruised cheeks.
%
Kin, n.:
- An affliction of the blood
+ An affliction of the blood.
%
Kindness is a language which the deaf can hear and the blind can read.
-- Mark Twain
%
Kindness is the beginning of cruelty.
- -- Muad'dib
+ -- Muad'dib, "Dune"
%
Kington's Law of Perforation:
If a straight line of holes is made in a piece of paper, such
@@ -30562,7 +30573,7 @@ Kliban's First Law of Dining:
Klingon phaser attack from front!!!!!
100% Damage to life support!!!!
%
-Kludge, n:
+Kludge, n.:
An ill-assorted collection of poorly-matching parts, forming a
distressing whole.
-- Jackson Granholm, "Datamation"
@@ -30772,11 +30783,11 @@ Lansdale seized on the idea of using Nixon to build support for the
[Vietnamese] elections ... really honest elections, this time. "Oh, sure,
honest, yes, that's right," Nixon said, "so long as you win!" With that
he winked, drove his elbow into Lansdale's arm and slapped his own knee.
- -- Richard Nixon, quoted in "Sideshow" by W. Shawcross
+ -- Richard M. Nixon, quoted in "Sideshow" by W. Shawcross
%
Large increases in cost with questionable increases in
performance can be tolerated only in race horses and women.
- -- Lord Kalvin
+ -- Lord Kelvin
%
Largest Number of Driving Test Failures
By April 1970 Mrs. Miriam Hargrave had failed her test thirty-nine
@@ -30917,7 +30928,7 @@ Lay off the muses, it's a very tough dollar.
-- S. J. Perelman
%
Lay on, MacDuff, and curs'd be him who first cries, "Hold, enough!".
- -- Shakespeare
+ -- William Shakespeare
%
Layers are for cakes, not for software.
-- Bart Smaalders
@@ -31038,7 +31049,7 @@ Let a fool hold his tongue and he will pass for a sage.
Let he who takes the plunge remember to return it by Tuesday.
%
Let him choose out of my files, his projects to accomplish.
- -- Shakespeare, "Coriolanus"
+ -- William Shakespeare, "Coriolanus"
%
Let me assure you that to us here at First National, you're not just a
number. You're two numbers, a dash, three more numbers, another dash and
@@ -31095,7 +31106,7 @@ Let sleeping dogs lie.
-- Charles Dickens
%
Let the machine do the dirty work.
- -- "The Elements of Programming Style", Kernighan and Plauger
+ -- Kernighan and Plauger, "The Elements of Programming Style"
%
Let the meek inherit the earth -- they have it coming to them.
-- James Thurber
@@ -31105,7 +31116,7 @@ Let the people think they govern and they will be governed.
%
Let the worthy citizens of Chicago get their liquor the best way
they can. I'm sick of the job. It's a thankless one and full of grief.
- -- Capone
+ -- Al Capone
%
Let thy maid servant be faithful, strong, and homely.
-- Benjamin Franklin
@@ -31396,7 +31407,7 @@ Life is like a tin of sardines.
We're, all of us, looking for the key.
-- Beyond the Fringe
%
-Life is like an analogy
+Life is like an analogy.
%
Life is like an egg stain on your chin --
you can lick it, but it still won't go away.
@@ -31422,7 +31433,7 @@ Life is one long struggle in the dark.
-- Titus Lucretius Carus
%
Life is the childhood of our immortality.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
Life is the living you do,
Death is the living you don't do.
@@ -31624,7 +31635,7 @@ as you keep the television turned down and don't try to eat any solid foods.
%
Likewise, the national appetizer, brine-cured herring with raw onions,
wins few friends, Germans excepted.
- -- Darwin Porter "Scandinavia On $50 A Day"
+ -- Darwin Porter, "Scandinavia On $50 A Day"
%
Lincoln was elected to Congress in 1846.
Kennedy exactly one hundred years later in 1946.
@@ -31646,7 +31657,7 @@ Kennedy was succeeded by a Southerner named Johnson.
The first Johnson was born in 1808.
The second Johnson was born in 1908.
- -- Alistair Cooke, "Letter From America", 26nov2001
+ -- Alistair Cooke, "Letter From America", Nov. 26, 2001
%
Line Printer paper is strongest at the perforations.
%
@@ -31861,7 +31872,7 @@ from NecroSoft inc., 6502 Charnelhouse Blvd., Cleveland, OH 44101.
Loneliness is a terrible price to pay for independence.
%
Lonely is a man without love.
- -- Englebert Humperdinck
+ -- Engelbert Humperdinck
%
Lonely men seek companionship.
Lonely women sit at home and wait. They never meet.
@@ -32032,7 +32043,7 @@ arms about love you'll find you are left only holding yourself.
%
Love is an ideal thing, marriage a real thing; a confusion of the real
with the ideal never goes unpunished.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
Love is an obsessive delusion that is cured by marriage.
-- Dr. Karl Bowman
@@ -32081,7 +32092,7 @@ Love is the only game that is not called on account of darkness.
-- M. Hirschfield
%
Love is the process of my leading you gently back to yourself.
- -- Saint Exupery
+ -- Antoine de Saint-Exupery
%
Love is the triumph of imagination over intelligence.
-- H. L. Mencken
@@ -32113,7 +32124,7 @@ That's the most ridiculous thing I've ever heard.
Love means nothing to a tennis player.
%
Love tells us many things that are not so.
- -- Krainian Proverb
+ -- Krainian proverb
%
Love the sea? I dote upon it -- from the beach.
%
@@ -32165,7 +32176,7 @@ Luck can't last a lifetime, unless you die young.
Luck, that's when preparation and opportunity meet.
-- P. E. Trudeau
%
-Lucky, adj:
+Lucky, adj.:
When you have a wife and a cigarette
lighter -- both of which work.
%
@@ -32209,7 +32220,7 @@ Machines have less problems. I'd like to be a machine.
Machines that have broken down will work perfectly when the
repairman arrives.
%
-macho, adj.:
+Macho, adj.:
Jogging home from your vasectomy.
%
Macho does not prove mucho.
@@ -32221,14 +32232,14 @@ Mad, adj.:
%
Madam, there's no such thing as a tough child --
if you parboil them first for seven hours, they always come out tender.
- -- W.C. Fields
+ -- W. C. Fields
%
Madison's Inquiry:
If you have to travel on the Titanic, why not go first class?
%
Madness takes its toll.
%
-MAFIA, n:
+MAFIA, n.:
[Acronym for Mechanized Applications in Forced Insurance
Accounting.] An extensive network with many on-line and offshore
subsystems running under OS, DOS, and IOS. MAFIA documentation is
@@ -32276,7 +32287,7 @@ Magpie, n.:
MAIDEN AUNT:
A girl who never had the sense to say "uncle."
%
-Maiden, n:
+Maiden, n.:
A young person of the unfair sex addicted to clewless conduct and
views that madden to crime. The genus has a wide geographical
distribution, being found wherever sought and deplored wherever found.
@@ -32418,7 +32429,7 @@ Man is the only animal that blushes -- or needs to.
%
Man is the only animal that can remain on friendly terms
with the victims he intends to eat until he eats them.
- -- Samuel Butler, 1835-1902
+ -- Samuel Butler (1835-1902)
%
Man is the only animal that laughs and weeps;
for he is the only animal that is struck with the
@@ -32491,12 +32502,12 @@ MANAGER:
Mandrell: "You know what I think?"
Doctor: "Ah, ah that's a catch question. With a brain your size you
don't think, right?"
- -- Dr. Who
+ -- "Doctor Who"
%
-man-hour, n:
+Man-hour, n.:
A sexist, obsolete measure of macho effort, equal to 60 Kiplings.
%
-MANIC-DEPRESSIVE:
+Manic-depressive, n.:
Easy glum, easy glow.
%
Mankind is poised midway between the gods and the beasts.
@@ -32524,7 +32535,7 @@ Man's unique agony as a species consists in his perpetual
conflict between the desire to stand out and the need to blend in.
-- Sydney J. Harris
%
-manual, n:
+Manual, n.:
A unit of documentation. There are always three or more on a given
item. One is on the shelf; someone has the others. The information
you need is in the others.
@@ -32627,10 +32638,10 @@ Many people write memos to tell you they have nothing to say.
Many receive advice, few profit by it.
-- Publilius Syrus
%
-Many years ago in a period commonly know as Next Friday Afternoon,
+Many years ago in a period commonly known as Next Friday Afternoon,
there lived a King who was very Gloomy on Tuesday mornings because he
was so Sad thinking about how Unhappy he had been on Monday and how
-completely Mournful he would be on Wednesday....
+completely Mournful he would be on Wednesday ...
-- Walt Kelly
%
Margaret, are you grieving
@@ -32733,8 +32744,8 @@ chopsticks. It looks easy until you try it.
Marriage is low down, but you spend the rest of your life paying for it.
-- Baskins
%
-Marriage is not merely sharing the fettucine, but sharing the
-burden of finding the fettucine restaurant in the first place.
+Marriage is not merely sharing the fettuccine, but sharing the
+burden of finding the fettuccine restaurant in the first place.
-- Calvin Trillin
%
Marriage is the only adventure open to the cowardly.
@@ -32745,7 +32756,7 @@ kind of man your wife would have preferred.
%
Marriage is the waste-paper basket of the emotions.
%
-Marriage, n:
+Marriage, n.:
The evil aye.
%
Marriages are made in heaven and consummated on earth.
@@ -32757,14 +32768,14 @@ MARTA SAYS THE INTERESTING thing about fly-fishing is that its two lives
connected by a thin strand.
Come on, Marta, grow up.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
MARTA WAS WATCHING THE FOOTBALL GAME with me when she said, "You know most
of these sports are based on the idea of one group protecting its
territory from invasion by another group."
"Yeah," I said, trying not to laugh. Girls are funny.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
Martin was probably ripping them off. That's some family, isn't it?
Incest, prostitution, fanaticism, software.
@@ -32844,7 +32855,7 @@ MATH AND ALCOHOL DON'T MIX!
Math is like love -- a simple idea but it can get complicated.
-- R. Drabek
%
-mathematician, n:
+Mathematician, n.:
Some one who believes imaginary things appear right before your i's.
%
Mathematicians are like Frenchmen: whatever you say to them they translate
@@ -32891,7 +32902,7 @@ Matter will be damaged in direct proportion to its value.
[Maturity consists in the discovery that] there comes a critical moment
where everything is reversed, after which the point becomes to understand
more and more that there is something which cannot be understood.
- -- S. Kierkegaard
+ -- S. A. Kierkegaard (1813-1855)
%
Maturity is only a short break in adolescence.
-- Jules Feiffer
@@ -33009,7 +33020,7 @@ moonlit night, some horrible persona has been jabbing away at, dragging
magnets over, and surging these voodoo boxen. Fortunately, they seem to
have gotten a bit bored and fallen asleep, for it looks like Cynthia may
get to go home. However, she has made note to quickly put together a totem
-of sweaty, sordid static straps, random bits of wire, flecks of once meaniful
+of sweaty, sordid static straps, random bits of wire, flecks of once meaningful
oxide, bus grant cards, gummy worms, and some bits of old pdp backplane to
hang above the machine room. This totem must be blessed by the old and wise
venerable god of unibus at once, before the idolatization of vme, q and pc
@@ -33028,7 +33039,7 @@ Meekness is uncommon patience in planning a worthwhile revenge.
%
Meester, do you vant to buy a duck?
%
-meeting, n:
+Meeting, n.:
An assembly of people coming together to decide what person or
department not represented in the room must solve a problem.
%
@@ -33055,7 +33066,7 @@ played. I remember a bigger, older guy whom we called "Dad." We'd eat
some stuff or not and then I think we went home.
I guess some things never leave you.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
Memory fault -- brain fried
%
@@ -33087,7 +33098,7 @@ thing they marry later; for another thing they die earlier.
%
Men have as exaggerated an idea of their
rights as women have of their wrongs.
- -- E. W. Howe
+ -- Edgar W. Howe
%
Men live for three things, fast cars, fast women and fast food.
%
@@ -33095,7 +33106,7 @@ Men love to wonder, and that is the seed of science.
%
Men never do evil so completely and cheerfully as when they do it
from religious conviction.
- -- Blaise Pascal, "Pensées", 1670
+ -- Blaise Pascal, "Pens'ees", 1670
%
Men never make passes at girls wearing glasses.
-- Dorothy Parker
@@ -33118,7 +33129,7 @@ and tears. ... It is the same thing which makes us mad or delirious,
inspires us with dread and fear, whether by night or by day, brings us
sleeplessness, inopportune mistakes, aimless anxieties, absent-mindedness
and acts that are contrary to habit...
- -- Hippocrates "The Sacred Disease"
+ -- Hippocrates, "The Sacred Disease"
%
Men say of women what pleases them; women do with men what pleases them.
-- DeSegur
@@ -33159,7 +33170,7 @@ Mencken and Nathan's Sixteenth Law of The Average American:
is possessed only by yokels, and no person born in a large city
can never hope to acquire it.
%
-Mene, mene, tekel, upharsen.
+Mene, mene, tekel, upharsin.
%
Mental power tended to corrupt, and absolute intelligence tended to
corrupt absolutely, until the victim eschewed violence entirely in
@@ -33217,7 +33228,8 @@ lylglutamyllysylmethionylleucylalanylalanylleucyllysylvalylphenylalanylvalyl-
glutaminylprolylmethionyllysylalanylalanylthreonylarginylserine, n.:
The chemical name for tryptophan synthetase A protein, a
1,913-letter enzyme with 267 amino acids.
- -- Mrs. Bryne's Dictionary of Unusual, Obscure, and
+ -- Mrs. Byrne's Dictionary of Unusual, Obscure, and
+ Preposterous Words
%
Mickey Mouse wears a Spiro Agnew watch.
%
@@ -33238,7 +33250,7 @@ Mieux vaut tard que jamais!
%
Might as well be frank, monsieur. It would take a miracle to
get you out of Casablanca and the Germans have outlawed miracles.
- -- Casablanca
+ -- Signor Ferrari, "Casablanca" (1942)
%
Mike: "The Fourth Dimension is a shambles?"
Bernie: "Nobody ever empties the ashtrays. People are SO
@@ -33259,7 +33271,7 @@ Military justice is to justice what military music is to music.
Miller's Slogan:
Lose a few, lose a few.
%
-millihelen, adj:
+Millihelen, adj.:
The amount of beauty required to launch one ship.
%
Millions long for immortality who do not know what
@@ -33333,14 +33345,14 @@ Miss, n.:
women to indicate that they are in the market.
-- Ambrose Bierce, "The Devil's Dictionary"
%
-Mistakes are often the stepping stones to utter failure.
-%
Mistakeholder, n.:
- A person who depends on accidental features or
- implementation errors and so now has a vested
+ A person who depends on accidental features or
+ implementation errors and so now has a vested
interest in keeping things from being fixed.
-- Chip Morningstar
%
+Mistakes are often the stepping stones to utter failure.
+%
Mistrust first impulses; they are always right.
%
MIT:
@@ -33359,7 +33371,7 @@ Mix a little foolishness with your serious plans;
it's lovely to be silly at the right moment.
-- Horace
%
-mixed emotions:
+Mixed emotions:
Watching a bus-load of lawyers plunge off a cliff.
With five empty seats.
%
@@ -33388,7 +33400,7 @@ is crisp and golden. Serve warm. Cut into 6 to 8 slices.
Modeling paged and segmented memories is tricky business.
-- P. J. Denning
%
-modem, adj:
+Modem, adj.:
Up-to-date, new-fangled, as in "Thoroughly Modem Millie." An
unfortunate byproduct of kerning.
%
@@ -33558,7 +33570,7 @@ in California ... [it] is also a great place for cock-fighting, gambling
of all sorts, fandangos, and various kinds of amusements and knavery.
-- Richard Henry Dama, "Two Years Before the Mast", 1840
%
-moon, n:
+Moon, n.:
1. A celestial object whose phase is very important to
hackers. See PHASE OF THE MOON. 2. Dave Moon (MOON@MC).
%
@@ -33566,7 +33578,7 @@ Moore's Constant:
Everybody sets out to do something, and everybody
does something, but no one does what he sets out to do.
%
-mophobia, n:
+Mophobia, n.:
Fear of being verbally abused by a Mississippian.
%
More are taken in by hope than by cunning.
@@ -33700,14 +33712,14 @@ Most people don't need a great deal of love
nearly so much as they need a steady supply.
%
Most people eat as though they were fattening themselves for market.
- -- E. W. Howe
+ -- Edgar W. Howe
%
Most people feel that everyone is entitled to their opinion.
%
Most people have a furious itch to talk about themselves and are restrained
only by the disinclination of others to listen. Reserve is an artificial
quality that is developed in most of us as the result of innumerable rebuffs.
- -- W. S. Maugham
+ -- W. Somerset Maugham
%
Most people have a mind that's open by appointment only.
%
@@ -33755,7 +33767,7 @@ Mother is the invention of necessity.
Mother said there would be days like this, but she never said there
would be so many.
%
-Mother told me to be good but she's been wrong before.
+Mother told me to be good, but she's been wrong before.
%
Mothers all want their sons to grow up to be President, but they
don't want them to become politicians in the process.
@@ -34022,7 +34034,7 @@ My father was a saint, I'm not.
%
My favorite sandwich is peanut butter, baloney, cheddar cheese, lettuce
and mayonnaise on toasted bread with catsup on the side.
- -- Senator Hubert Humphrey
+ -- Hubert H. Humphrey
%
My first basename is George "Catfish" Metkovich from our 1952 Pittsburgh
Pirates team, which lost 112 games. After a terrible series against the
@@ -34178,7 +34190,7 @@ Any man who has $10,000 left when he dies is a failure.
%
My rackets are run on strictly American
lines, and they're going to stay that way.
- -- A. Capone
+ -- Al Capone
%
My religion consists of a humble admiration of the illimitable superior
spirit who reveals himself in the slight details we are able to perceive
@@ -34353,7 +34365,7 @@ given them little.
%
Nature is by and large to be found out of doors, a location where, it
cannot be argued, there are never enough comfortable chairs.
- -- Fran Leibowitz
+ -- Fran Lebowitz
%
Nature makes boys and girls lovely to look upon so they can be
tolerated until they acquire some sense.
@@ -34432,7 +34444,7 @@ Nemo me impune lacessit
[No one provokes me with impunity]
-- Motto of the Crown of Scotland
%
-nerd pack, n:
+Nerd pack, n.:
Plastic pouch worn in breast pocket to keep pens from soiling
clothes. Nerd's position in engineering hierarchy can be
measured by number of pens, grease pencils, and rulers bristling
@@ -34454,7 +34466,7 @@ Neutrinos are into physicists.
%
Neutrinos have bad breadth.
%
-neutron bomb, n:
+Neutron bomb, n.:
An explosive device of limited military value because, as
it only destroys people without destroying property, it
must be used in conjunction with bombs that destroy property.
@@ -34558,7 +34570,7 @@ Never keep up with the Joneses. Drag them down to your level.
Never kick a man, unless he's down.
%
Never laugh at live dragons.
- -- Bilbo Baggins
+ -- Bilbo Baggins, "The Hobbit"
%
Never leave anything to chance;
make sure all your crimes are premeditated.
@@ -34663,7 +34675,7 @@ Never trust anyone who says money is no object.
%
Never try to explain computers to a layman. It's easier to explain
sex to a virgin.
- -- Robert Heinlein
+ -- Robert A. Heinlein
(Note, however, that virgins tend to know a lot about computers.)
%
@@ -34679,7 +34691,7 @@ Never underestimate the bandwidth of a station wagon full of tapes.
Never underestimate the power of a small tactical nuclear weapon.
%
Never underestimate the power of human stupidity.
- -- Robert Heinlein
+ -- Robert A. Heinlein
%
Never use "etc." -- it makes people think there is more where
there is not or that there is not space to list it all, etc.
@@ -34691,7 +34703,7 @@ Never worry about theory as long as the
machinery does what it's supposed to do.
-- Robert A. Heinlein
%
-new, adj:
+New, adj.:
Different color from previous model.
%
New crypt. See /usr/news/crypt.
@@ -34756,7 +34768,7 @@ It was. Age 31.
%
Newspaper editors are men who separate the wheat from the chaff, and then
print the chaff.
- -- Adlai Stevenson
+ -- Adlai E. Stevenson
%
Newton's Fourth Law: Every action has an equal and opposite satisfaction.
%
@@ -34850,7 +34862,7 @@ absolutely certain he can hold his own in conversation.
No bird soars too high if he soars with his own wings.
-- William Blake
%
-no brainer:
+No brainer, n.:
A decision which, viewed through the retrospectoscope,
is "obvious" to those who failed to make it originally.
%
@@ -34866,7 +34878,7 @@ No Civil War picture ever made a nickel.
No committee could ever come up with anything as revolutionary as a
camel -- anything as practical and as perfectly designed to perform
effectively under such difficult conditions.
- -- Laurence J. Peter
+ -- Dr. Laurence J. Peter
%
No directory.
%
@@ -34877,8 +34889,8 @@ lectures which are really worth the attending.
No doubt Jack the Ripper excused himself
on the grounds that it was human nature.
%
-No, `Eureka' is Greek for `This bath is too hot.'
- -- Dr. Who
+No, "Eureka" is Greek for "This bath is too hot."
+ -- The Doctor, "Doctor Who"
%
No evil can happen to a good man.
-- Plato
@@ -34908,7 +34920,7 @@ No guts, no glory.
%
No hardware designer should be allowed to produce any piece of hardware
until three software guys have signed off for it.
- -- Andy Tanenbaum
+ -- Andrew S. Tanenbaum
%
No, his mind is not for rent
To any god or government.
@@ -34948,7 +34960,7 @@ doors were sensibly shut; silence lay steadily against the wood and stone
of Hill House, and whatever walked there, walked alone.
-- Shirley Jackson, "The Haunting of Hill House"
%
-no maintenance:
+No maintenance:
Impossible to fix.
%
No man can have a reasonable opinion of women until he has long lost
@@ -34976,7 +34988,7 @@ and if we are loved we are indispensable.
-- Robert Louis Stevenson
%
No man would listen to you talk if he didn't know it was his turn next.
- -- E. W. Howe
+ -- Edgar W. Howe
%
No man's ambition has a right to stand in
the way of performing a simple act of justice.
@@ -35154,7 +35166,7 @@ May beat admission in a thousand years.
%
No self-made man ever did such a good job
that some woman didn't want to make some alterations.
- -- Kim Hubbard
+ -- Kin Hubbard
%
No self-respecting fish would want to be wrapped in that kind of
paper.
@@ -35165,7 +35177,7 @@ No skis take rocks like rental skis!
%
No small art is it to sleep: it is necessary
for that purpose to keep awake all day.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
No snowflake in an avalanche ever feels responsible.
%
@@ -35180,7 +35192,7 @@ No spitting on the Bus!
Thank you, The Management.
%
No television performance takes as much preparation as an off-the-cuff talk.
- -- Richard Nixon
+ -- Richard M. Nixon
%
No two persons ever read the same book.
-- Edmund Wilson
@@ -35196,11 +35208,11 @@ she will or will not be a mother.
-- Margaret H. Sanger
%
No woman can endure a gambling husband, unless he is a steady winner.
- -- Lord Thomas Dewar
+ -- Lord Thomas Robert Dewar
%
No woman ever falls in love with a man unless she has a better opinion of
him than he deserves.
- -- Edgar Watson Howe
+ -- Edgar W. Howe
%
No wonder Clairol makes so much money selling shampoo.
Lather, Rinse, Repeat is an infinite loop!
@@ -35209,29 +35221,6 @@ No wonder you're tired! You understood so much today.
%
No yak too dirty; no dumpster too hollow.
%
-Nobert Weiner was the subject of many dotty professor stories. Weiner was, in
-fact, very absent minded. The following story is told about him: when they
-moved from Cambridge to Newton his wife, knowing that he would be absolutely
-useless on the move, packed him off to MIT while she directed the move. Since
-she was certain that he would forget that they had moved and where they had
-moved to, she wrote down the new address on a piece of paper, and gave it to
-him. Naturally, in the course of the day, an insight occurred to him. He
-reached in his pocket, found a piece of paper on which he furiously scribbled
-some notes, thought it over, decided there was a fallacy in his idea, and
-threw the piece of paper away. At the end of the day he went home (to the
-old address in Cambridge, of course). When he got there he realized that they
-had moved, that he had no idea where they had moved to, and that the piece of
-paper with the address was long gone. Fortunately inspiration struck. There
-was a young girl on the street and he conceived the idea of asking her where
-he had moved to, saying, "Excuse me, perhaps you know me. I'm Norbert Weiner
-and we've just moved. Would you know where we've moved to?" To which the
-young girl replied, "Yes, Daddy, Mommy thought you would forget."
- The capper to the story is that I asked his daughter (the girl in the
-story) about the truth of the story, many years later. She said that it wasn't
-quite true -- that he never forgot who his children were! The rest of it,
-however, was pretty close to what actually happened...
- -- Richard Harter
-%
Nobody can be as agreeable as an uninvited guest.
%
Nobody can be exactly like me. Sometimes even I have trouble doing
@@ -35309,11 +35298,11 @@ Noise proves nothing. Often a hen who has
merely laid an egg cackles as if she laid an asteroid.
-- Mark Twain
%
-nolo contendere:
+Nolo contendere:
A legal term meaning: "I didn't do it, judge, and I'll never do
it again."
%
-nominal egg:
+Nominal egg:
New Yorkerese for expensive.
%
Noncombatant, n.:
@@ -35356,6 +35345,29 @@ No-one would remember the Good Samaritan if he had only had good
intentions. He had money as well.
-- Margaret Thatcher
%
+Norbert Wiener was the subject of many dotty professor stories. Wiener was, in
+fact, very absent minded. The following story is told about him: when they
+moved from Cambridge to Newton his wife, knowing that he would be absolutely
+useless on the move, packed him off to MIT while she directed the move. Since
+she was certain that he would forget that they had moved and where they had
+moved to, she wrote down the new address on a piece of paper, and gave it to
+him. Naturally, in the course of the day, an insight occurred to him. He
+reached in his pocket, found a piece of paper on which he furiously scribbled
+some notes, thought it over, decided there was a fallacy in his idea, and
+threw the piece of paper away. At the end of the day he went home (to the
+old address in Cambridge, of course). When he got there he realized that they
+had moved, that he had no idea where they had moved to, and that the piece of
+paper with the address was long gone. Fortunately inspiration struck. There
+was a young girl on the street and he conceived the idea of asking her where
+he had moved to, saying, "Excuse me, perhaps you know me. I'm Norbert Wiener
+and we've just moved. Would you know where we've moved to?" To which the
+young girl replied, "Yes, Daddy, Mommy thought you would forget."
+ The capper to the story is that I asked his daughter (the girl in the
+story) about the truth of the story, many years later. She said that it wasn't
+quite true -- that he never forgot who his children were! The rest of it,
+however, was pretty close to what actually happened...
+ -- Richard Harter
+%
Norm: Hey, everybody.
All: [silence; everybody is mad at Norm for being rich.]
Norm: [Carries on both sides of the conversation himself.]
@@ -35449,7 +35461,7 @@ All: Anton!
-- Cheers, The Two Faces of Norm
Woody: What's going on, Mr. Peterson?
-Norm: A flashing sign in my gut that says, ``Insert beer here.''
+Norm: A flashing sign in my gut that says, "Insert beer here."
-- Cheers, Call Me, Irresponsible
Sam: What can I get you, Norm?
@@ -35498,11 +35510,11 @@ chipped at it a bit, and everything was just fine ...
-- Stanislaw Lem, "Cyberiad"
%
Not Hercules could have knock'd out his brains, for he had none.
- -- Shakespeare
+ -- William Shakespeare
%
Not only is this incomprehensible, but the ink is
ugly and the paper is from the wrong kind of tree.
- -- Professor, EECS, George Washington University
+ -- Professor W., EECS, George Washington University
I'm looking forward to working with you on this next year.
-- Professor, Harvard, on a senior thesis
@@ -35538,7 +35550,7 @@ and/or frogs falling from the sky.
%
Note: The system panics with a "NULL pointer dereference" message
-Failed due to : SunOS 5.8 is installed.
+Failed due to: SunOS 5.8 is installed.
-- Output of a SunCheckup run on a Solaris 8 machine
%
Note to myself: use real bullets next time.
@@ -35633,7 +35645,7 @@ Nothing, nothing, nothing, no error, no crime is so absolutely
repugnant to God as everything which is official; and why? because
the official is so impersonal and therefore the deepest insult
which can be offered to a personality.
- -- Soren Kierkegaard
+ -- S. A. Kierkegaard (1813-1855)
%
Nothing recedes like success.
-- Walter Winchell
@@ -35680,7 +35692,7 @@ I said oh, you can leave it.
-- Al Stewart, "If It Doesn't Come Naturally, Leave It"
%
Nothing will dispel enthusiasm like a small admission fee.
- -- Kim Hubbard
+ -- Kin Hubbard
%
Nothing will ever be attempted
if all possible objections must be first overcome.
@@ -35696,16 +35708,16 @@ NOTICE:
(The nearest working elevator is in the building across the street.)
%
-Nouvelle cuisine, n:
+Nouvelle cuisine, n.:
French for "not enough food".
-Continental breakfast, n:
+Continental breakfast, n.:
English for "not enough food".
-Tapas, n:
+Tapas, n.:
Spanish for "not enough food".
-Dim Sum, n:
+Dim Sum, n.:
Chinese for more food than you've ever seen in your entire life.
%
November, n.:
@@ -35912,7 +35924,7 @@ O imitators, you slavish herd!
O, it is excellent
To have a giant's strength; but it is tyrannous
To use it like a giant.
- -- Shakespeare, "Measure for Measure", II, 2
+ -- William Shakespeare, "Measure for Measure", II, 2
%
O Lord, grant that we may always be right,
for Thou knowest we will never change our minds.
@@ -36016,7 +36028,7 @@ Of course you have a purpose -- to find a purpose.
Of what you see in books, believe 75%. Of newspapers, believe 50%. And of
TV news, believe 25% -- make that 5% if the anchorman wears a blazer.
%
-Office Automation:
+Office Automation, n.:
The use of computers to improve efficiency in the office
by removing anyone you would want to talk with over coffee.
%
@@ -36085,7 +36097,7 @@ Oh, give me a locus where the gravitons focus
Where the three-body problem is solved,
Where the microwaves play down at three degrees K,
And the cold virus never evolved. (chorus)
-We eat algea pie, our vacuum is high,
+We eat algae pie, our vacuum is high,
Our ball bearings are perfectly round.
Our horizon is curved, our warheads are MIRVed,
And a kilogram weighs half a pound. (chorus)
@@ -36155,7 +36167,7 @@ Shooting up my veins,
Tell you, I've been a-thinkin'
I could drive a shiny Lincoln,
If I dealt in good cocaine.
- -- To 'If I Only Had A Brain' from "The Wizard of Oz"
+ -- To "If I Only Had A Brain" from "The Wizard of Oz"
%
Oh, I don't blame Congress. If I had $600 billion at my disposal, I'd
be irresponsible, too.
@@ -36177,7 +36189,7 @@ Where never lark, or even eagle flew;
And, while with silent, lifting mind I've trod
The high untrespassed sanctity of space,
Put out my hand, and touched the face of God.
- -- John Gillespie Magee Jr., "High Flight"
+ -- John Gillespie Magee, Jr., "High Flight"
%
Oh I'm just a typical American boy
From a typical American town.
@@ -36239,7 +36251,7 @@ Born under one law, to another bound.
Oh, well, I guess this is just going to be one of those lifetimes.
%
Oh what a tangled web we weave, when first we practice to deceive.
- -- Shakespeare
+ -- William Shakespeare
%
Oh, when I was in love with you,
Then I was clean and brave,
@@ -36254,10 +36266,10 @@ And miles around they'll say that I
%
Oh, wow! Look at the moon!
%
-Oh, ya doesn't have ta call me 'Johnson'! Well, you can call me 'Ray', or
-you can call me 'Jay', or you can call me 'R.J.', or you can call me 'Ray
-J.', or you can call me 'R.J.J.', or you can call me 'Ray J. Johnson', or
-you can call me 'R.J. Johnson', but ya DOESN'T have to call me 'Johnson'...
+Oh, ya doesn't have ta call me "Johnson"! Well, you can call me "Ray", or
+you can call me "Jay", or you can call me "R. J.", or you can call me "Ray
+J.", or you can call me "R. J. J.", or you can call me "Ray J. Johnson", or
+you can call me "R. J. Johnson", but ya DOESN'T have to call me "Johnson" ...
%
Oh, yeah, life goes on, long after the thrill of livin' is gone.
-- John Cougar, "Jack and Diane"
@@ -36323,13 +36335,13 @@ Old programmers never die, they just hit account block limit.
%
Old soldiers never die. Young ones do.
%
-Old timer, n:
+Old timer, n.:
One who remembers when charity was a virtue and not an organization.
%
Olivier's Law:
Experience is something you don't get until just after you need it.
%
-omnibiblious, adj.:
+Omnibiblious, adj.:
Indifferent to type of drink. Ex: "Oh, you can get me anything.
I'm omnibiblious."
%
@@ -36394,7 +36406,7 @@ On the subject of C program indentation:
-- Blair P. Houghton
%
On the whole, I'd rather be in Philadelphia.
- -- W.C. Fields' epitaph
+ -- W. C. Fields' epitaph
%
On two occasions I have been asked [by members of Parliament!], "Pray, Mr.
Babbage, if you put into the machine wrong figures, will the right answers
@@ -36404,7 +36416,7 @@ ideas that could provoke such a question.
%
Once ... in the wilds of Afghanistan, I lost my corkscrew,
and we were forced to live on nothing but food and water for days.
- -- W.C. Fields, "My Little Chickadee"
+ -- W. C. Fields, "My Little Chickadee"
%
Once a word has been allowed to escape, it cannot be recalled.
-- Quintus Horatius Flaccus (Horace)
@@ -36457,16 +36469,16 @@ each of us observes, in his own way, by going to the mall of his
choice.
In the old days, it was not called the Holiday Season; the Christians
-called it "Christmas" and went to church; the Jews called it "Hanukka"
+called it "Christmas" and went to church; the Jews called it "Hanukkah"
and went to synagogue; the atheists went to parties and drank. People
passing each other on the street would say "Merry Christmas!" or "Happy
-Hanukka!" or (to the atheists) "Look out for the wall!"
+Hanukkah!" or (to the atheists) "Look out for the wall!"
-- Dave Barry, "Christmas Shopping: A Survivor's Guide"
%
Once at a social gathering, Gladstone said to Disraeli, "I predict,
Sir, that you will die either by hanging or of some vile disease".
Disraeli replied, "That all depends upon whether I embrace your
-principles or your mistress".
+principals or your mistress."
%
Once harm has been done, even a fool understands it.
-- Homer
@@ -36799,7 +36811,7 @@ many ...
-- Anthony Chevins
%
One man's constant is another man's variable.
- -- A. J. Perlis
+ -- Alan J. Perlis
%
One man's folly is another man's wife.
-- Helen Rowland
@@ -36860,7 +36872,7 @@ to get people off their guard, pretending to be stupid because he couldn't
be bothered to think and wanted someone else to do it for him, pretending
to be so outrageously stupid to hide the fact that he actually didn't
understand what was going on, and really being genuinely stupid. He was
-reknowned for being quite clever and quite clearly was so -- but not all the
+renowned for being quite clever and quite clearly was so -- but not all the
time, which obviously worried him, hence the act. He preferred people to be
puzzled rather than contemptuous. This above all appeared to Trillian to be
genuinely stupid, but she could no longer be bothered to argue about.
@@ -36937,9 +36949,6 @@ One planet is all you get.
One possible reason that things aren't going according to plan
is that there never was a plan in the first place.
%
-One possible reason why things aren't going
-according to plan is that there never was a plan.
-%
One promising concept that I came up with right away was that you could
manufacture personal air bags, then get a law passed requiring that
they be installed on congressmen to keep them from taking trips. Let's
@@ -36995,7 +37004,7 @@ cried, but I think that deep down he thought it was a pretty good joke.
I started to drive over to the real Disneyland, but it was getting pretty
late.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
One thing the inventors can't seem to
get the bugs out of is fresh paint.
@@ -37029,7 +37038,7 @@ One would like to stroke and caress human beings, but one dares not do so,
because they bite.
-- Vladimir Lenin
%
-One-Shot Case Study, n:
+One-Shot Case Study, n.:
The scientific equivalent of the four-leaf clover, from which
it is concluded all clovers possess four leaves and are sometimes green.
%
@@ -37040,7 +37049,7 @@ On-line, adj.:
Only a fool has no doubts.
%
Only a mediocre person is always at his best.
- -- Laurence Peter
+ -- Dr. Laurence J. Peter
%
Only adults have difficulty with childproof caps.
%
@@ -37126,7 +37135,7 @@ Oppernockity tunes but once.
Opportunities are usually disguised as hard
work, so most people don't recognize them.
%
-Oprah Winfrey has an incredible talent for getting the wierdest people to
+Oprah Winfrey has an incredible talent for getting the weirdest people to
talk to. And you just HAVE to watch it. "Blind, masochistic minority,
crippled, depressed, government latrine diggers, and the women who love
them too much on the next Oprah Winfrey."
@@ -37134,7 +37143,7 @@ them too much on the next Oprah Winfrey."
Optimism is the content of small men in high places.
-- F. Scott Fitzgerald, "The Crack Up"
%
-Optimism, n:
+Optimism, n.:
The belief that everything is beautiful, including what is ugly, good, bad,
and everything right that is wrong. It is held with greatest tenacity by
those accustomed to falling into adversity, and most acceptably expounded
@@ -37142,11 +37151,7 @@ with the grin that apes a smile. Being a blind faith, it is inaccessible
to the light of disproof -- an intellectual disorder, yielding to no treatment
but death. It is hereditary, but not contagious.
%
-Optimist:
- Someone who goes down to the marriage
- bureau to see if his license has expired.
-%
-Optimist, n:
+Optimist, n.:
A bagpiper with a beeper.
%
Optimist, n.:
@@ -37160,6 +37165,10 @@ would justify them."
something -- the mortality of the optimist."
-- Ambrose Bierce, "The Devil's Dictionary"
%
+Optimist, n.:
+ Someone who goes down to the marriage
+ bureau to see if his license has expired.
+%
Optimization hinders evolution.
%
Oral sex is like being attacked by a giant snail.
@@ -37355,7 +37364,7 @@ move?'
%
Overdrawn? But I still have checks left!
%
-Overflow on /dev/null, please empty the bit bucket.
+Overflow on /dev/null: please empty the bit bucket.
%
Overheard:
"How do I feel? Great! And I kiss pretty good, too!"
@@ -37439,7 +37448,7 @@ panic: kernel trap (ignored)
%
Paprika Measure:
- 2 dashes == 1smidgen
+ 2 dashes == 1 smidgen
2 smidgens == 1 pinch
3 pinches == 1 soupcon
2 soupcons == too much paprika
@@ -37488,7 +37497,7 @@ Parker's Law:
Beauty is only skin deep, but ugly goes clean to the bone.
%
Parkinson's Fifth Law:
- If there is a way to delay in important decision, the good
+ If there is a way to delay an important decision, the good
bureaucracy, public or private, will find it.
%
Parkinson's Fourth Law:
@@ -37554,7 +37563,7 @@ A: No, you SINGE 'em. You SINGE 'em and eat 'em. *I* read about the
P: Squirrels eating squirrels -- my GOD, that's sick!
A: That's sick, SURE. But a MAN eating a squirrel -- that's (heh, heh)
par for the course, Charlie.
- -- Firesign Theatre
+ -- The Firesign Theatre
%
Patageometry, n.:
The study of those mathematical properties that are invariant
@@ -37563,7 +37572,7 @@ under brain transplants.
Patch griefs with proverbs.
-- William Shakespeare, "Much Ado About Nothing"
%
-patent:
+Patent, v.:
A method of publicizing inventions so others can copy them.
%
"Pathetic," he said. "That's what it is. Pathetic."
@@ -37615,7 +37624,7 @@ Pause for storage relocation.
Pay no attention to that man behind the curtain.
-- Frank Morgan as The Wizard, "The Wizard of Oz"
%
-paycheck:
+Paycheck, n.:
The weekly $5.27 that remains after deductions for federal
withholding, state withholding, city withholding, FICA,
medical/dental, long-term disability, unemployment insurance,
@@ -37640,11 +37649,11 @@ Peace be to this house, and all that dwell in it.
%
Peace cannot be kept by force; it
can only be achieved by understanding.
- -- A. Einstein
+ -- Albert Einstein
%
Peace is much more precious than a piece
of land... let there be no more wars.
- -- Mohammed Anwar Sadat, 1918-1981
+ -- Mohammed Anwar Sadat (1918-1981)
%
Peace, n.:
In international affairs, a period of cheating between two
@@ -37707,7 +37716,7 @@ if he didn't understand people; and how could he have done that if people
weren't easy to understand? You show me someone who can't understand
people and I'll show you someone who has built up a false image of himself
-- no offense intended."
- -- Asimov, "Foundation's Edge"
+ -- Isaac Asimov, "Foundation's Edge"
%
Penguin Trivia #46:
Animals who are not penguins can only wish they were.
@@ -37715,7 +37724,7 @@ Penguin Trivia #46:
%
PENGUINICITY!!
%
-pension:
+Pension, n.:
A federally insured chain letter.
%
People (a group that in my opinion has always attracted an undue amount of
@@ -37844,7 +37853,7 @@ or
%
Perfect day for scrubbing the floor and other exciting things.
%
-perfect guest:
+Perfect guest, n.:
One who makes his host feel at home.
%
Perfection is finally attained, not when there is no longer
@@ -37883,7 +37892,7 @@ Periphrasis is the putting of things in a round-about way. "The cost may be
upwards of a figure rather below 10m#." is a periphrasis for The cost may be
nearly 10m#. "In Paris there reigns a complete absence of really reliable
news" is a periphrasis for There is no reliable news in Paris. "Rarely does
-the 'Little Summer' linger until November, but at times its stay has been
+the `Little Summer' linger until November, but at times its stay has been
prolonged until quite late in the year's penultimate month" contains a
periphrasis for November, and another for lingers. "The answer is in the
negative" is a periphrasis for No. "Was made the recipient of" is a
@@ -37914,15 +37923,15 @@ persons attempting to find a moral in it will be banished; persons attempting
to find a plot in it will be shot. By Order of the Author
-- Mark Twain, "Tom Sawyer"
%
-pessimist:
+Pessimist, n.:
A man who spends all his time worrying about how he can keep the
wolf from the door.
-optimist:
+Optimist, n.:
A man who refuses to see the wolf until he seizes the seat of
his pants.
-opportunist:
+Opportunist, n.:
A man who invites the wolf in and appears the next day in a fur coat.
%
Pete: Waiter, this meat is bad.
@@ -37976,10 +37985,10 @@ exciting Camden, New Jersey.
%
Philogyny recapitulates erogeny; erogeny recapitulates philogyny.
%
-philosophy:
+Philosophy, n.:
The ability to bear with calmness the misfortunes of our friends.
%
-philosophy:
+Philosophy, n.:
Unintelligible answers to insoluble problems.
%
Philosophy will clip an angel's wings.
@@ -37987,7 +37996,7 @@ Philosophy will clip an angel's wings.
%
Phone call for chucky-pooh.
%
-Phosflink, v:
+Phosflink, v.:
To flick a bulb on and off when it burns out (as if, somehow,
that will bring it back to life).
-- Rich Hall & Friends, "Sniglets"
@@ -38066,7 +38075,7 @@ So I piped with merry cheer.
So I piped: he wept to hear.
-- William Blake, "Songs of Innocence"
%
-Pipo was born with few complications, but then the doctor accidently dropped
+Pipo was born with few complications, but then the doctor accidentally dropped
the infant on her head provoking her drunken father to drag the physician
outside where he would beat him to death with a live ocelot.
-- Love and Rockets
@@ -38093,7 +38102,7 @@ PISCES (Feb.19 - Mar.20)
Pity the meek, for they shall inherit the earth.
-- Don Marquis
%
-pixel, n:
+Pixel, n.:
A mischievous, magical spirit associated with screen displays.
The computer industry has frequently borrowed from mythology:
Witness the sprites in computer graphics, the demons in artificial
@@ -38246,7 +38255,7 @@ Plus ca change, plus c'est le meme chose.
Pohl's law:
Nothing is so good that somebody, somewhere, will not hate it.
%
-poisoned coffee, n:
+Poisoned coffee, n.:
Grounds for divorce.
%
Poland has gun control.
@@ -38265,7 +38274,7 @@ Host: Oh, the noise. Well that makes sense because there are no guns
Police: No, the neighbors fled inland hours ago. Most of the recent
complaints have come from Pittsburgh. Do you think you could
ask the host to quiet things down?
-Host: No Problem. (At this point, a Volkswagon bug with primitive
+Host: No Problem. (At this point, a Volkswagen bug with primitive
religious symbols drawn on the doors emerges from the living
room and roars down the hall, past the police and onto the
lawn, where it smashes into a tree. Eight guests tumble out
@@ -38453,7 +38462,7 @@ poor people.
-- Don Herold
%
Power and ignorance is a detestable cocktail.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
Power corrupts. Absolute power is kind of neat.
-- John Lehman, Secretary of the Navy, 1981-1987
@@ -38471,7 +38480,7 @@ Power, like a desolating pestilence,
Pollutes whate'er it touches...
-- Percy Bysshe Shelley
%
-Power, n:
+Power, n.:
The only narcotic regulated by the SEC instead of the FDA.
%
Power tends to corrupt, absolute power corrupts absolutely.
@@ -38508,7 +38517,7 @@ Praise the sea; on shore remain.
Pray to God, but keep rowing to shore.
-- Russian Proverb
%
-Pray, v:
+Pray, v.:
To ask that the laws of the universe be annulled on behalf
of a single petitioner confessedly unworthy.
-- Ambrose Bierce, "The Devil's Dictionary"
@@ -38523,7 +38532,7 @@ Prejudice, n.:
-- Ambrose Bierce, "The Devil's Dictionary"
%
Premature optimization is the root of all evil.
- -- D. E. Knuth
+ -- Donald E. Knuth
%
Preserve the old, but know the new.
%
@@ -38619,7 +38628,7 @@ PROGRAM:
"sales program," or "marketing program"), its implementation
always justifies hiring at least three more people.
%
-program, n:
+Program, n.:
A magic spell cast over a computer allowing it to turn one's input
into error messages. tr.v. To engage in a pastime similar to banging
one's head against a wall, but with fewer opportunities for reward.
@@ -38638,7 +38647,6 @@ Programming is an unnatural act.
Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe trying
to produce bigger and better idiots. So far, the Universe is winning.
-
-- Rich Cook
%
PROGRESS:
@@ -38749,11 +38757,11 @@ POPI Punch Operator Immediately
PVLC Punch Variable Length Card
RASC Read And Shred Card
RPM Read Programmers Mind
-RSSC reduce speed, step carefully (for improved accuracy)
-RTAB Rewind tape and break
-RWDSK rewind disk
+RSSC Reduce Speed, Step Carefully (for improved accuracy)
+RTAB Rewind Tape and Break
+RWDSK Rewind Disk
RWOC Read Writing On Card
-SCRBL scribble to disk - faster than a write
+SCRBL Scribble to disk - faster than a write
SLC Search for Lost Chord
SPSW Scramble Program Status Word
SRSD Seek Record and Scar Disk
@@ -38796,7 +38804,7 @@ three friends. If they're OK, you're it.
%
Psychiatry enables us to correct our faults by confessing our parents'
shortcomings.
- -- Laurence J. Peter, "Peter's Principles"
+ -- Dr. Laurence J. Peter, "Peter's Principles"
%
Psychics will soon lead dogs to your body.
%
@@ -38809,7 +38817,7 @@ Psychiatry is the care of the id by the odd.
Show me a sane man and I will cure him for you.
-- Carl G. Jung
%
-psychologist, n:
+Psychologist, n.:
Someone who watches everyone else when an attractive woman walks
into a room.
%
@@ -38866,7 +38874,7 @@ PURITAN:
Puritanism -- the haunting fear that someone, somewhere, may be happy.
-- H. L. Mencken, "A Book of Burlesques"
%
-Purpitation, v:
+Purpitation, v.:
To take something off the grocery shelf, decide you
don't want it, and then put it in another section.
-- Rich Hall & Friends, "Sniglets"
@@ -38966,8 +38974,8 @@ A: The tame way!
%
Q: How do you keep a moron in suspense?
%
-Q. How do you keep an Aggie busy at a terminal?
-A. While he's not looking, switch it to "local".
+Q: How do you keep an Aggie busy at a terminal?
+A: While he's not looking, switch it to "local".
%
Q: How do you know when you're in the <ethnic> section of Vermont?
A: The maple sap buckets are hanging on utility poles.
@@ -39315,8 +39323,8 @@ Q: What do you call a principal female opera singer whose high C
is lower than those of other principal female opera singers?
A: A deep C diva.
%
-Q. What do you call a TV set that fixes itself?
-A. A Christian Science Monitor.
+Q: What do you call a TV set that fixes itself?
+A: A Christian Science Monitor.
%
Q: What do you call a WASP who doesn't work for his father, isn't a
lawyer, and believes in social causes?
@@ -39427,7 +39435,7 @@ Q: What's bruised, bleeding, and lies in a ditch?
A: Somebody who tells Aggie jokes.
%
Q: What's tan and black and looks great on a lawyer?
-A: A doberman.
+A: A Doberman.
%
Q: What's the Blonde's cheer?
A: I'm blonde, I'm blonde, I'm B.L.O.N... ah, oh well..
@@ -39439,8 +39447,8 @@ A: Artificial intelligence.
Q: How do you make a blonde's eyes light up?
A: Shine a flashlight in their ear.
%
-Q. What's the capital of Canada?
-A. American.
+Q: What's the capital of Canada?
+A: American.
%
Q: What's the difference between a dead dog in the road and a dead
lawyer in the road?
@@ -39461,8 +39469,8 @@ A: One more drunk.
Q: What's the difference between Bell Labs and the Boy Scouts of America?
A: The Boy Scouts have adult supervision.
%
-Q. What's the difference between Los Angeles and yogurt?
-A. Yogurt has a living, active culture.
+Q: What's the difference between Los Angeles and yogurt?
+A: Yogurt has a living, active culture.
%
Q: What's the difference between USL and the Graf Zeppelin?
A: The Graf Zeppelin represented cutting edge technology for its time.
@@ -39513,7 +39521,7 @@ Q: Why did the germ cross the microscope?
A: To get to the other slide.
%
Q: Why did the lone ranger kill Tonto?
-A: He found out what "kimosabe" really means.
+A: He found out what "kemosabe" really means.
%
Q: Why did the mathematician name his dog "Cauchy"?
A: Because he left a residue at every pole.
@@ -39589,9 +39597,6 @@ A: It wasn't IBM compatible.
QED.
%
QOTD:
- "It's not the despair... I can stand the despair. It's the hope."
-%
-QOTD:
"A child of 5 could understand this! Fetch me a child of 5."
%
QOTD:
@@ -39650,7 +39655,7 @@ QOTD:
"I ain't broke, but I'm badly bent."
%
QOTD:
- "I am not sure what this is, but an 'F' would only dignify it."
+ "I am not sure what this is, but an `F' would only dignify it."
%
QOTD:
"I don't think they could put him in a mental hospital. On the
@@ -39664,7 +39669,7 @@ QOTD:
%
QOTD:
"I looked out my window, and saw Kyle Pettys' car upside down,
- then I thought 'One of us is in real trouble.'"
+ then I thought `One of us is in real trouble.'"
-- Davey Allison, on a 150 m.p.h. crash
%
QOTD:
@@ -39690,7 +39695,7 @@ QOTD:
horse with one of the horns broken off."
%
QOTD:
- "I treat her like a throughbred, and she's STILL a nag!"
+ "I treat her like a thoroughbred, and she's STILL a nag!"
%
QOTD:
"I tried buying a goat instead of a lawn tractor; had to return
@@ -39796,6 +39801,9 @@ QOTD:
"It's men like him that give the Y chromosome a bad name."
%
QOTD:
+ "It's not the despair... I can stand the despair. It's the hope."
+%
+QOTD:
"It's sort of a threat, you see. I've never been very good at
them myself, but I'm told they can be very effective."
%
@@ -39973,7 +39981,7 @@ QUARK:
Quark! Quark! Beware the quantum duck!
%
question = ( to ) ? be : ! be;
- -- Wm. Shakespeare
+ -- William Shakespeare
%
QUESTION AUTHORITY.
@@ -40020,7 +40028,7 @@ Qvid me anxivs svm?
%
Radicalism:
The conservatism of tomorrow injected into the affairs of today.
- -- A. Bierce
+ -- Ambrose Bierce
%
RADIO SHACK LEVEL II BASIC
READY
@@ -40048,7 +40056,7 @@ realise that you are in a hurry.
%
RAM wasn't built in a day.
%
-Random, n:
+Random, n.:
as in number, predictable.
as in memory access, unpredictable.
%
@@ -40067,7 +40075,7 @@ Do you use the "greasy kid's stuff" to stick down your cowlick?
Do you wear a "nerd-pack" in your shirt pocket to keep the dozen
or so pencils from marking the cloth?
Do you think Mary Jane is somebody's name?
-Is illegal fishing is something only a daring criminal would do?
+Is illegal fishing something only a daring criminal would do?
Is Batman your hero? Superman? Green Lantern? The Shadow?
Do you think girls who kiss on the first date are loose?
@@ -40240,8 +40248,8 @@ Real World, The n.:
be used in the same sentence as FORTRAN, COBOL, RPG, IBM, etc. 2. To
programmers, the location of non-programmers and activities not related
to programming. 3. A universe in which the standard dress is shirt and
-tie and in which a person's working hours are defined as 9 to 5. 4.
-The location of the status quo. 5. Anywhere outside a university.
+tie and in which a person's working hours are defined as 9 to 5.
+4. The location of the status quo. 5. Anywhere outside a university.
"Poor fellow, he's left MIT and gone into the real world." Used
pejoratively by those not in residence there. In conversation, talking
of someone who has entered the real world is not unlike talking about a
@@ -40282,7 +40290,7 @@ cannot be fooled.
%
Really?? What a coincidence, I'm shallow too!!
%
-Reappraisal, n:
+Reappraisal, n.:
An abrupt change of mind after being found out.
%
Rebellion lay in his way, and he found it.
@@ -40308,14 +40316,14 @@ Just then, Karen Carpenter walks in, sits down at the drums, and says:
"'Close to You'. Hit it, boys!"
-- Told by Penn Jillette, of magic/comedy duo Penn and Teller
%
-Reception area, n:
+Reception area, n.:
The purgatory where office visitors are condemned to spend
innumerable hours reading dog-eared back issues of trade
magazines like Modern Plastics, Chain Saw Age, and Chicken World,
while the receptionist blithely reads her own trade magazine --
Cosmopolitan.
%
-Recession is when your neighbor loses his job. Depression is when you
+Recession is when your neighbor loses his job. Depression is when you
lose your job. These economic downturns are very difficult to predict,
but sophisticated econometric modeling houses like Data Resources and
Chase Econometrics have successfully predicted 14 of the last 3 recessions.
@@ -40377,7 +40385,7 @@ knowledge of how to live, nor the smallest instinct about when to die.
has no need to put up a front of any kind.
-- John Ball, "Mark One: the Dummy"
%
-Reliable source, n:
+Reliable source, n.:
The guy you just met.
%
Religion has done love a great service by making it a sin.
@@ -40426,7 +40434,7 @@ the first one.
%
Remember, if it's being done correctly, here or abroad, it's
*not* the U.S. Army doing it!
- -- Good Morning, Vietnam
+ -- "Good Morning, Vietnam"
%
Remember kids, if there's a loaded gun in the room, be sure
that you're the one holding it.
@@ -40524,7 +40532,7 @@ Reporter (to Mahatma Gandhi):
Mr. Gandhi, what do you think of Western Civilization?
Gandhi: I think it would be a good idea.
%
-Reputation, adj:
+Reputation, adj.:
What others are not thinking about you.
%
Research is the best place to be: you work your buns off, and if it works
@@ -40537,7 +40545,7 @@ and think what nobody else has thought.
Research is what I'm doing when I don't know what I'm doing.
-- Wernher von Braun
%
-Research, n:
+Research, n.:
Consider Columbus:
He didn't know where he was going.
When he got there he didn't know where he was.
@@ -40557,7 +40565,7 @@ is to take the blame for your mistakes. If they're smart, that is.
Retirement means that when someone says "Have a nice day", you
actually have a shot at it.
%
-Reunite Gondwondaland!
+Reunite Gondwanaland!
%
Rev. Jim: What does an amber light mean?
Bobby: Slow down.
@@ -40586,14 +40594,14 @@ Review Questions
a pyramid, how soon will Johnson's pyramid be larger than King
Tut's? When will it fall on him? Will he notice?
%
-Revolution, n:
+Revolution, n.:
A form of government abroad.
%
Revolution, n.:
In politics, an abrupt change in the form of misgovernment.
-- Ambrose Bierce, "The Devil's Dictionary"
%
-revolutionary, adj:
+Revolutionary, adj.:
Repackaged.
%
Rhode's Law:
@@ -40627,7 +40635,7 @@ Renault: "I'm shocked! Shocked! To find that gambling is
Croupier (handing money to Renault):
"Your winnings, sir."
Renault: "Oh. Thank you very much."
- -- Casablanca
+ -- "Casablanca" (1942)
%
Riffle West Virginia is so small that the
Boy Scout had to double as the town drunk.
@@ -40647,13 +40655,13 @@ Ritchie's Rule:
(2) Paint splashes last longer than the paint job.
(3) Search and ye shall find -- but make sure it was lost.
%
-Robot, n:
+Robot, n.:
Someone who's been made by a scientist.
%
-Robot, n:
+Robot, n.:
University administrator.
%
-Robustness, adj:
+Robustness, adj.:
Never having to say you're sorry.
%
Rocky's Lemma of Innovation Prevention
@@ -40717,7 +40725,7 @@ Rudin's Second Law:
courses of action, people tend to choose the worst possible
course.
%
-rugby, n:
+Rugby, n.:
Elegant violence.
(Rugby players eat their dead.)
@@ -40798,9 +40806,9 @@ Rules for Good Grammar #4.
12: Proofread your writing to see if you any words out.
13: Correct speling is essential.
14: A preposition is something you never end a sentence with.
-15: While a transcendant vocabulary is laudable, one must be eternally
+15: While a transcendent vocabulary is laudable, one must be eternally
careful so that the calculated objective of communication does not
- become ensconsed in obscurity. In other words, eschew obfuscation.
+ become ensconced in obscurity. In other words, eschew obfuscation.
%
Rules for Writers:
Avoid run-on sentences they are hard to read. Don't use no double
@@ -40834,7 +40842,7 @@ RULES OF EATING -- THE BRONX DIETER'S CREED
can always eat it later.
(10) Avoid any wine with a childproof cap.
(11) Avoid blue food.
- -- Richard Smit, "The Bronx Diet"
+ -- Richard Smith, "The Bronx Diet"
%
Ruling a big country is like cooking a small fish.
-- Lao Tsu
@@ -40883,7 +40891,7 @@ Sacred cows make great hamburgers.
SADISM:
A sadist refusing to whip a masochist.
%
-sadoequinecrophilia, n:
+Sadoequinecrophilia, n.:
Beating a dead horse.
%
Safety Third.
@@ -41175,7 +41183,7 @@ shoulder. His eyebrows are raised, matter-of-factly, as he spies the boy
intently watching him.
Caption:
- "I'm sorry you've seen me, Billy. Now I'll have to kill you.
+ I'm sorry you've seen me, Billy. Now I'll have to kill you.
%
Schapiro's Explanation:
The grass is always greener on the other side --
@@ -41213,12 +41221,12 @@ To the late night, double feature, Picture show.
Science is built up of facts, as a house is with stones. But a
collection of facts is no more a science than a heap of stones
is a house.
- -- Jules Henri Poincare
+ -- Jules Henri Poincar'e
%
Science is facts; just as houses are made of stones, so is science made
of facts; but a pile of stones is not a house and a collection of facts
is not necessarily science.
- -- Henri Poincair'e
+ -- Jules Henri Poincar'e
%
Science is like sex: sometimes something useful comes
out, but that is not the reason we are doing it
@@ -41244,10 +41252,10 @@ To seek a shelter in some happier star?
Hast thou not torn the Naiad from her flood,
The Elfin from the green grass, and from me
The summer dream beneath the tamarind tree?
- -- Edgar Allen Poe, "Science, a Sonnet"
+ -- Edgar Allan Poe, "Science, a Sonnet"
%
Scientists are people who build the Brooklyn Bridge and then buy it.
- -- William Buckley
+ -- William F. Buckley
%
Scientists still know less about what attracts men
@@ -41264,11 +41272,11 @@ was a loud crash, and a bolt of lightning came down from the sky,
struck the computers, and welded all the connections permanently
together. "There is now", came the reply.
%
-Scintilate, scintilate, globule vivific,
+Scintillate, scintillate, globule vivific,
Fain how I pause at your nature specific,
Loftily poised in the ether capacious,
Highly resembling a gem carbonaceous.
-Scintilate, scintilate, globule vivific,
+Scintillate, scintillate, globule vivific,
Fain how I pause at your nature specific.
%
Scintillation is not always identification for an auric substance.
@@ -41317,7 +41325,7 @@ Scribline, n.:
%
Scrubbing floors and emptying bedpans has as much dignity as the
Presidency.
- -- Richard Nixon
+ -- Richard M. Nixon
%
'Scuse me, while I kiss the sky!
-- Robert James Marshall (Jimi) Hendrix
@@ -41343,7 +41351,7 @@ Secrecy is the beginning of tyranny.
Secretary's Revenge:
Filing almost everything under "the".
%
-"Section 2.4.3.5 AWNS (Acceptor Wait for New Cycle State).
+Section 2.4.3.5 AWNS (Acceptor Wait for New Cycle State).
In AWNS the AH function indicates that it has received a
multiline message byte.
In AWNS the RFD message must be sent false and the DAC message
@@ -41352,7 +41360,7 @@ must be sent passive true.
(1) The ANRS if DAV is false
(2) The AIDS if the ATN message is false and neither:
(a) The LADS is active
- (b) Nor LACS is active"
+ (b) Nor LACS is active
-- from the IEEE Standard Digital Interface for
Programmable Instrumentation
@@ -41443,8 +41451,8 @@ register.
bears know yer there so's they can run away ... I'll take one fer black
bears, and one fer them grizzlies. Say, how do you know yer in grizzly
country, anyhow?"
- "Look fer scatt. Grizzly scatt's different from black bear scatt."
- "Well now, what's IN grizzly scatt that's different?"
+ "Look fer scat. Grizzly scat's different from black bear scat."
+ "Well now, what's IN grizzly scat that's different?"
"Bear bells."
%
Seems that a pollster was taking a worldwide opinion poll.
@@ -41631,7 +41639,7 @@ Shannon's Observation
Nothing is so frustrating as a bad situation
that is beginning to improve.
%
-share, n:
+Share, n.:
To give in, endure humiliation.
%
Sharks are as tough as those football fans who take their shirts off
@@ -41699,9 +41707,9 @@ a look that you could have poured on a waffle.
%
She often gave herself very good advice
(though she very seldom followed it).
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
-She ran the gamut of emotions from 'A' to 'B'.
+She ran the gamut of emotions from "A" to "B".
-- Dorothy Parker, on a Kate Hepburn performance
%
She say, Miss Colie, You better hush. God might hear you.
@@ -41966,7 +41974,7 @@ Sink or Swim with Teddy!
Sinners can repent, but stupid is forever.
%
Sir, it's very possible this asteroid is not stable.
- -- CP30
+ -- C-3PO
%
[Sir Stafford Cripps] has all the virtues
I dislike and none of the vices I admire.
@@ -42021,7 +42029,7 @@ for deliverance from chains.
-- Frederick Douglass
%
Sleep -- the most beautiful experience in life -- except drink.
- -- W.C. Fields
+ -- W. C. Fields
%
Sleep is for the weak and sickly.
%
@@ -42085,7 +42093,7 @@ Snacktrek, n.:
The peculiar habit, when searching for a snack, of constantly
returning to the refrigerator in hopes that something new will
have materialized.
- -- Rich Hall, "Sniglets"
+ -- Rich Hall & Friends, "Sniglets"
%
Snakes. Why did it have to be snakes?
%
@@ -42289,7 +42297,7 @@ COMMUNISM:
Give both to the government. The government gives you milk.
CAPITALISM:
You sell one cow and buy a bull.
-FACISM:
+FASCISM:
You have two cows. Give milk to the government.
The government sells it.
NAZISM:
@@ -42351,7 +42359,7 @@ Some husbands are living proof that a woman can take a joke.
Some marriages are made in heaven -- but so are thunder and lightning.
%
Some men are alive simply because it is against the law to kill them.
- -- Ed Howe
+ -- Edgar W. Howe
%
Some men are all right in their place -- if they only the knew the right
places!
@@ -42526,7 +42534,7 @@ Some scholars are like donkeys, they merely carry a lot of books.
Some things have to be believed to be seen.
%
Somebody left the cork out of my lunch.
- -- W.C. Fields
+ -- W. C. Fields
%
Somebody ought to cross ball point pens with coat hangers
so that the pens will multiply instead of disappear.
@@ -42622,7 +42630,7 @@ Something unpleasant is coming when men are anxious to tell the truth.
-- Benjamin Disraeli
%
Something's rotten in the state of Denmark.
- -- Shakespeare
+ -- William Shakespeare
%
Sometime when you least expect it, Love will tap you on the shoulder...
and ask you to move out of the way because it still isn't your turn.
@@ -42675,7 +42683,7 @@ Sometimes love ain't nothing but a misunderstanding between two fools.
SOMETIMES THE BEAUTY OF THE WORLD is so overwhelming, I just want to throw
back my head and gargle. Just gargle and gargle and I don't care who hears
me because I am beautiful.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
Sometimes the best medicine is to stop taking something.
%
@@ -42776,7 +42784,7 @@ For he can thoroughly enjoy
The pepper when he pleases!
Wow! wow! wow!
- -- Lewis Carroll, "Alice in Wonderland"
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
Speak roughly to your little VAX,
And boot it when it crashes;
@@ -42945,7 +42953,7 @@ STANDARDS:
The principles we use to reject other people's code.
%
Standards are different for all things, so the standard set by man is by
-no means the only 'certain' standard. If you mistake what is relative for
+no means the only "certain" standard. If you mistake what is relative for
something certain, you have strayed far from the ultimate truth.
-- Chuang Tzu
%
@@ -42961,7 +42969,7 @@ on, one-by-one or all in a bunch to back it up!
-- Harlan Ellison
%
Start every day off with a smile and get it over with.
- -- W.C. Fields
+ -- W. C. Fields
%
Start the day with a smile.
After that you can be your nasty old self again.
@@ -42988,7 +42996,7 @@ WHERE THE SMART NY WORK FORCE LIVES THE MOST OFTEN MISSPELLED STATE
TEXAS FLORIDA
1-2-3 HIKE ZON KED
- PLAY FOOTBALL OR DIE AMERICA'S DRUG DEALER
+PLAY FOOTBALL OR DIE AMERICA'S DRUG DEALER
%
State license plates we'd like to see:
@@ -43170,7 +43178,7 @@ Style may not be the answer, but at least it's a workable alternative.
Suaviter in modo, fortiter in re.
Se non e vero, e ben trovato.
%
-Substitute 'damn' every time you're inclined to write 'very'; your
+Substitute "damn" every time you're inclined to write "very"; your
editor will delete it and the writing will be just as it should be.
-- Mark Twain
%
@@ -43336,11 +43344,11 @@ Surprise due today. Also the rent.
%
Surprise your boss. Get to work on time.
%
-sushi, n:
+Sushi, n.:
When that-which-may-still-be-alive is put on top of rice and
strapped on with electrical tape.
%
-Sushido, n:
+Sushido, n.:
The way of the tuna.
%
Suspicion always haunts the guilty mind.
@@ -43439,7 +43447,7 @@ Fault: You have fallen forward.
Action Required: See above.
Symptom: Opposite wall covered with acoustic tile and several
- flourescent light strips.
+ fluorescent light strips.
Fault: You have fallen over backward.
Action Required: If your glass is full and no one is standing on your
drinking arm, stay put. If not, get someone to help
@@ -43524,7 +43532,7 @@ TAKE FORCEFUL ACTION:
Do something that should have been done a long time ago.
%
Take heart amid the deepening gloom that your dog is finally getting
-enough cheese
+enough cheese.
-- National Lampoon, "Deteriorata"
%
Take it easy, we're in a hurry.
@@ -43546,7 +43554,7 @@ Take what you can use and let the rest go by.
Take your dying with some seriousness, however.
Laughing on the way to your execution is not generally understood
by less-advanced life-forms, and they'll call you crazy.
- -- Messiah's Handbook: Reminders for the Advanced Soul
+ -- "Messiah's Handbook: Reminders for the Advanced Soul"
%
Take your Senator to lunch this week.
%
@@ -43589,7 +43597,7 @@ All together now...
%
Tart words make no friends; a spoonful of honey
will catch more flies than a gallon of vinegar.
- -- Ben Franklin
+ -- Benjamin Franklin
%
TAURUS (Apr 20 - May 20)
You are practical and persistent. You have a dogged determination
@@ -43652,7 +43660,7 @@ Technicality, n.:
affirm the death of the cook, that being only an inference.
-- Ambrose Bierce, "The Devil's Dictionary"
%
-Technique?" said the programmer turning from his terminal, "What I follow
+"Technique?" said the programmer turning from his terminal, "What I follow
is Tao -- beyond all technique! When I first began to program I would see
before me the whole problem in one mass. After three years I no longer saw
this mass. Instead, I used subroutines. But now I see nothing. My whole
@@ -43662,7 +43670,7 @@ itself. True, sometimes there are difficult problems. I see them coming, I
slow down, I watch silently. Then I change a single line of code and the
difficulties vanish like puffs of idle smoke. I then compile the program.
I sit still and let the joy of the work fill my being. I close my eyes for
-a moment and then log off.
+a moment and then log off."
%
Technological progress has merely provided us
with more efficient means for going backwards.
@@ -43783,7 +43791,7 @@ Come, pipe a tune to dance to, lad.
%
Term, holidays, term, holidays, till we leave
school, and then work, work, work till we die.
- -- C.S. Lewis
+ -- C. S. Lewis
%
Termiter's argument that God is His own grandmother generated a surprising
amount of controversy among Church leaders, who on the one hand considered
@@ -43812,7 +43820,7 @@ Test for paraquat:
bicarbonate and sodium dithionite. If paraquat is present,
the solution will turn blue-green.
%
-Testing can show the presense of bugs, but not their absence.
+Testing can show the presence of bugs, but not their absence.
-- Edsger W. Dijkstra
%
Test-tube babies shouldn't throw stones.
@@ -43930,10 +43938,10 @@ That's life for you, said McDunn. Someone always waiting for someone
who never comes home. Always someone loving something more than that
thing loves them. And after awhile you want to destroy whatever that
thing is, so it can't hurt you no more.
- -- R. Bradbury, "The Fog Horn"
+ -- Ray Bradbury, "The Fog Horn"
%
"That's no answer," Job said, "And for someone who's supposed to be
-omnipotent, let me tell you 'tabernacle' has only one l."
+omnipotent, let me tell you `tabernacle' has only one l."
-- Woody Allen, "Without Feathers"
%
That's no moon...
@@ -44086,7 +44094,7 @@ with which you can threaten your enemies.
%
The Anglo-Saxon conscience does not prevent the Anglo-Saxon from
sinning, it merely prevents him from enjoying his sin.
- --Salvador De Madariaga
+ -- Salvador De Madariaga
%
The angry man always thinks he can do more than he can.
-- Albertano of Brescia
@@ -44098,15 +44106,15 @@ doctors nor lawyers.
The annual meeting of the "You Have To Listen To Experience" Club is now in
session. Our Achievement Awards this year are in the fields of publishing,
advertising and industry. For best consistent contribution in the field of
-publishing our award goes to editor, R.L.K., [...] for his unrivaled alle-
+publishing our award goes to editor, R. L. K., [...] for his unrivaled alle-
giance without variation to the statement: "Personally I'd love to do it,
we'd ALL love to do it. But we're not going to do it. It's not the kind of
book our house knows how to handle." Our superior performance award in the
-field of advertising goes to media executive, E.L.M., [...] for the continu-
+field of advertising goes to media executive, E. L. M., [...] for the continu-
ally creative use of the old favorite: "I think what you've got here could be
very exciting. Why not give it one more try based on the approach I've out-
lined and see if you can come up with something fresh." Our final award for
-courageous holding action in the field of industry goes to supervisor, R.S.,
+courageous holding action in the field of industry goes to supervisor, R. S.,
[...] for her unyielding grip on "I don't care if they fire me, I've been
arguing for a new approach for YEARS but are we SURE that this is the right
time--" I would like to conclude this meeting with a verse written specially
@@ -44205,7 +44213,7 @@ The average woman must inevitably view her actual husband with a certain
disdain; he is anything but her ideal. In consequence, she cannot help
feeling that her children are cruelly handicapped by the fact that he is
their father.
- -- Mencken
+ -- H. L. Mencken
%
The average woman would rather have beauty than brains, because the
average man can see better than he can think.
@@ -44292,11 +44300,10 @@ Pretty good case: Get salary from England, build a house in America,
live with a Chinese wife, and eat Japanese food.
The worst case: Get salary from China, build a house in Japan,
live with a British wife, and eat American food.
-
- --Bungei Shunju, a popular Japanese magazine
+ -- Bungei Shunju, a popular Japanese magazine
%
The best cure for insomnia is to get a lot of sleep.
- -- W.C. Fields
+ -- W. C. Fields
%
The best defense against logic is ignorance.
%
@@ -44388,7 +44395,7 @@ The better part of valor is discretion.
%
The better the state is established, the fainter is humanity.
To make the individual uncomfortable, that is my task.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
The Bible contains six admonishments to homosexuals and 362 admonishments
to heterosexuals. That doesn't mean that God doesn't love heterosexuals.
@@ -44445,7 +44452,7 @@ The bland leadeth the bland and they both shall fall into the kitsch.
The bogosity meter just pegged.
%
The bold youth of today is very lonely.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
The bomb will never go off. I speak as an expert in explosives.
-- Admiral William Leahy, U.S. Atomic Bomb Project
@@ -44566,7 +44573,7 @@ sometimes three.
-- Alexandre Dumas
%
The chicken that clucks the loudest is the one most likely to show up
-at the steam fitters picnic.
+at the steam fitters' picnic.
%
The chief cause of problems is solutions.
-- Eric Sevareid
@@ -44683,7 +44690,7 @@ central power station is to the electrical industry.
The Computer made me do it.
%
The computing field is always in need of new cliches.
- -- Alan Perlis
+ -- Alan J. Perlis
%
The concept seems to be clear by now. It has been
defined several times by examples of what it is not.
@@ -44725,13 +44732,13 @@ talked about.
The cost of feathers has risen, even down is up!
%
The cost of living has just gone up another dollar a quart.
- -- W.C. Fields
+ -- W. C. Fields
%
The cost of living hasn't affected its popularity.
%
The cost of living is going up, and the chance of living is going down.
%
-The countdown had stalled at 'T' minus 69 seconds when Desiree, the first
+The countdown had stalled at "T" minus 69 seconds when Desiree, the first
female ape to go up in space, winked at me slyly and pouted her thick,
rubbery lips unmistakably -- the first of many such advances during what
would prove to be the longest, and most memorable, space voyage of my
@@ -44749,14 +44756,14 @@ ceremoniously handed it to the defendant.
father!"
%
The covers of this book are too far apart.
- -- Book review by Ambrose Bierce
+ -- Ambrose Bierce, reviewing a book
%
The cow is nothing but a machine which makes grass fit for us people to eat.
-- John McNulty
%
The Creation of the Universe was made possible by a grant from Texas
Instruments.
- -- Credits from the PBS program ``The Creation of the Universe''
+ -- Credits from the PBS program "The Creation of the Universe"
%
The Crown is full of it!
-- Nate Harris, 1775
@@ -44768,7 +44775,6 @@ and they are screened at once from scrutiny. ... In war, then, as in peace,
assert the freedom of speech and of the press. Cling to this as the bulwark
of all our rights and privileges.
-- William Ellery Channing
-
%
The curse of the Irish is not that they don't know the
words to a song -- it's that they know them *all*.
@@ -44788,7 +44794,7 @@ The dangerous Lego Bomb, which targets shag rugs and scatters pieces of
plastic that hurt like hell when you step on them is banned entirely....
Hiring David Copperfield to pretend to saw the missiles in half will not
be permitted... In order to reduce risk of accidental war, both sides
-agree to ban the popular but dangerous 'Simon Says' training drill at
+agree to ban the popular but dangerous "Simon Says" training drill at
nuclear launch sites... Under no circumstances will either side reveal
that it hammered out the treaty in one afternoon, but spent the last nine
years arguing the Monty Hall and the three doors problem.
@@ -44891,7 +44897,7 @@ miles is a long distance and the Americans think 100 years is a long time.
%
The difference between art and science is that science is what we
understand well enough to explain to a computer. Art is everything else.
- -- Donald Knuth, "Discover"
+ -- Donald E. Knuth, "Discover"
%
The difference between common-sense and paranoia is that common-sense is
thinking everyone is out to get you. That's normal -- they are. Paranoia
@@ -44912,7 +44918,7 @@ is that reality has so little to recommend it.
%
The difference between science and the fuzzy subjects is that science
requires reasoning while those other subjects merely require scholarship.
- -- Robert Heinlein
+ -- Robert A. Heinlein
%
The difference between sentiment and being sentimental is the following:
Sentiment is when a driver swerves out of the way to avoid hitting a
@@ -44996,7 +45002,7 @@ it to his master.
%
The duration of passion is proportionate with the original resistance
of the woman.
- -- Honore DeBalzac
+ -- Honore de Balzac
%
The eagle may soar, but the weasel never gets sucked into a jet engine.
%
@@ -45049,17 +45055,17 @@ Compute' -- I forget which."
%
The Encyclopaedia Galactica defines a robot as a mechanical apparatus designed
to do the work of a man. The marketing division of Sirius Cybernetics
-Corporation defines a robot as 'Your Plastic Pal Who's Fun To Be With'.
+Corporation defines a robot as "Your Plastic Pal Who's Fun To Be With".
The Hitchhiker's Guide to the Galaxy defines the marketing division of the
-Sirius Cybernetics Corporation as 'a bunch of mindless jerks who'll be the
-first against the wall when the revolution comes', with a footnote to effect
+Sirius Cybernetics Corporation as "a bunch of mindless jerks who'll be the
+first against the wall when the revolution comes", with a footnote to effect
that the editors would welcome applications from anyone interested in taking
over the post of robotics correspondent.
Curiously enough, an edition of the Encyclopaedia Galactica that
had the good fortune to fall through a time warp from a thousand years in
the future defined the marketing division of the Sirius Cybernetics
-Corporation as 'a bunch of mindless jerks who were the first against the
-wall when the revolution came'.
+Corporation as "a bunch of mindless jerks who were the first against the
+wall when the revolution came".
%
The end move in politics is always to pick up a gun.
-- Buckminster Fuller
@@ -45125,7 +45131,7 @@ a substitute for intelligence.
-- Lyman Bryson
%
The eternal feminine draws us upward.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
The executioner is, I hear, very expert, and my neck is very slender.
-- Anne Boleyn
@@ -45197,7 +45203,9 @@ so long as they are Tories.
-- Christopher Booker
%
The faster I go, the behinder I get.
- -- Lewis Carroll
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
The faster we go, the rounder we get.
-- The Grateful Dead
@@ -45234,7 +45242,7 @@ dull and creepy and humorless and war-oriented like the engineers across the
quad. And our most impressive critics have commonly been such English majors,
and they are squeamish about technology to this very day. So it is natural
for them to despise science fiction.
- -- Kurt Vonnegut Jr., "Science Fiction"
+ -- Kurt Vonnegut, Jr., "Science Fiction"
%
The fellow sat down at a bar, ordered a drink and asked the bartender if he
wanted to hear a dumb-jock joke.
@@ -45393,7 +45401,7 @@ The five rules of Socialism:
...the flaw that makes perfection perfect.
%
The flow chart is a most thoroughly oversold piece of program documentation.
- -- Frederick Brooks, "The Mythical Man Month"
+ -- Frederick Brooks, Jr., "The Mythical Man-Month"
%
The flush toilet is the basis of Western civilization.
-- Alan Coult
@@ -45452,7 +45460,7 @@ vinyl.
-- Dave Barry
%
[The French Riviera is] a sunny place for shady people.
- -- Somerset Maugham
+ -- W. Somerset Maugham
%
The full impact of parenthood doesn't hit you until you multiply the
number of your kids by thirty-two teeth.
@@ -45560,7 +45568,7 @@ You can live a life of fun.
The good life was so elusive
It really got me down
I had to regain some confidence
-So I got into camaflouge
+So I got into camouflage
%
The good time is approaching,
The season is at hand.
@@ -45770,7 +45778,7 @@ NOW -- McCLANAHAN!!!
*NOT FOR SISSIES! DON'T COME IF YOU'RE CHICKEN!
A Horrifying Movie of Weird Beauties and Shocking Monsters...
-1001 WIERDEST SCENES EVER!! MOST SHOCKING THRILLER OF THE CENTURY!
+1001 WEIRDEST SCENES EVER!! MOST SHOCKING THRILLER OF THE CENTURY!
-- Teenage Psycho meets Bloody Mary (1964) (Alternate Title:
The Incredibly Strange Creatures Who Stopped Living and
Became Mixed Up Zombies)
@@ -45887,7 +45895,7 @@ SEE Man-Fish Battle Shark-Man-Killer!
See Jane Russell in 3-D; She'll Knock Both Your Eyes Out!
-- The French Line (1954)
-See Jane Russell Shake Her Tamborines... and Drive Cornel WILDE!
+See Jane Russell Shake Her Tambourines... and Drive Cornel WILDE!
-- Hot Blood (1956)
%
The Great Movie Posters:
@@ -45954,7 +45962,7 @@ spokesman said.
The greatest of faults is to be conscious of none.
%
The greatest productive force is human selfishness.
- -- Robert Heinlein
+ -- Robert A. Heinlein
%
The greatest remedy for anger is delay.
%
@@ -45982,7 +45990,7 @@ you put a lot of relatives on the train for home.
The hater of property and of government takes care to have his warranty
deed recorded, and the book written against fame and learning has the
author's name on the title page.
- -- Ralph Waldo Emerson, Journals, 1831
+ -- Ralph Waldo Emerson, "Journals" (1831)
%
The hatred of relatives is the most violent.
-- Tacitus (c.55 - c.117)
@@ -46136,7 +46144,7 @@ no sex, no owner, and a message of importance for every housewife.
The ideas of economists and political philosophers, both when they
are right and when they are wrong, are more powerful than is generally
understood. Indeed, the world is ruled by little else.
- -- John Maynard Keyes
+ -- John Maynard Keynes
%
The identical is equal to itself, since it is different.
-- Franco Spisani
@@ -46174,7 +46182,7 @@ a delight to moralists. That is why they invented hell.
%
The inherent vice of capitalism is the unequal sharing of blessings;
the inherent virtue of socialism is the equal sharing of misery.
- -- Churchill
+ -- Winston Churchill
%
The instruments of science do not in themselves discover truth. And
there are searchings that are not concluded by the coincidence of a
@@ -46628,8 +46636,8 @@ The louder he talked of his honour, the faster we counted our spoons.
The lovely woman-child Kaa was mercilessly chained to the cruel post of
the warrior-chief Beast, with his barbarian tribe now stacking wood at
her nubile feet, when the strong clear voice of the poetic and heroic
-Handsomas roared, 'Flick your Bic, crisp that chick, and you'll feel my
-steel through your last meal!'
+Handsomas roared, "Flick your Bic, crisp that chick, and you'll feel my
+steel through your last meal!"
-- Winning sentence, 1984 Bulwer-Lytton bad fiction contest
%
The luck that is ordained for you will be coveted by others.
@@ -46658,7 +46666,7 @@ The major sin is the sin of being born.
%
The majority of husbands remind me of an orangutan trying to play
the violin.
- -- Honore DeBalzac
+ -- Honore de Balzac
%
The majority of the stupid is invincible and guaranteed for all time.
The terror of their tyranny, however, is alleviated by their lack of
@@ -46763,7 +46771,7 @@ which, when properly cared for, will rust out in two or three years.
The mate for beauty should be a man and not a money chest.
-- Bulwer
%
-The mature bohemian is one whose woman works full time.
+The mature Bohemian is one whose woman works full time.
%
The means-and-ends moralists, or non-doers,
always end up on their ends without any means.
@@ -46795,7 +46803,7 @@ The meek will inherit the earth -- if that's OK with you.
%
The meeting of two personalities is like the contact of two
chemical substances: if there is any reaction, both are transformed.
- -- Carl Jung
+ -- Carl G. Jung
%
[The members of the Chamberlain government] are decided only to be
undecided, resolved to be irresolute, adamant for drift, all-powerful
@@ -46850,7 +46858,7 @@ The Modelski Chain Rule:
thrashing anyway, just to show you mean business.
%
The modern child will answer you back before you've said anything.
- -- Laurence J. Peter
+ -- Dr. Laurence J. Peter
%
"The molars, I'm sure, will be all right, the molars can take care of
themselves," the old man said, no longer to me. "But what will become
@@ -46883,7 +46891,7 @@ lower the mailing cost.
The more I know men the more I like my horse.
%
The more I see of men the more I admire dogs.
- -- Mme De Sevigne, 1626-1696
+ -- Mme De Sevigne (1626-1696)
%
The more I want to get something done, the less I call it work.
-- Richard Bach, "Illusions"
@@ -46977,7 +46985,7 @@ the wineyness of a late sun, the intimate kiss of fertilizing rain, and the
bite of fire. You must slice it thin, almost as thin as this page you hold
in your hands. The making of a ham dinner, like the making of a gentleman,
starts a long, long time before the event.
- -- W.B. Courtney, "Reflections of Maryland Country Ham",
+ -- W. B. Courtney, "Reflections of Maryland Country Ham",
from "Congress Eate It Up"
%
...the most exquisitely squalid hells known to middle-class man:
@@ -46986,7 +46994,7 @@ freshman English at a Midwestern university.
%
The most happy marriage I can imagine to myself would be the union
of a deaf man to a blind woman.
- -- Samuel Taylor Coleridge
+ -- Samuel T. Coleridge
%
The most hopelessly stupid man is he who is not aware that he is wise.
%
@@ -47033,7 +47041,7 @@ an ultimatum which demanded that they disband, this would-be successor to the
radical student movements of the Sixties promptly voted itself out of
existence. As del Borgo and Margaronis put it, "After much chaotic discussion
and a confused voice vote, the convention suspended all its other work and
-broke into regional groups to discuss 'outreach.'"
+broke into regional groups to discuss `outreach.'"
-- Libertarian Agenda, May 1988
%
The most remarkable thing about my mother is that for thirty years she
@@ -47094,7 +47102,7 @@ The Net interprets censorship as damage and routes around it.
The net is like a vast sea of lutefisk with tiny dinosaur brains embedded
in it here and there. Any given spoonful will likely have an IQ of 1, but
occasional spoonfuls may have an IQ more than six times that!
- -- James 'Kibo' Parry
+ -- James "Kibo" Parry
%
The net of law is spread so wide,
No sinner from its sweep may hide.
@@ -47125,7 +47133,7 @@ The New York Times is read by the people who run the country. The
Washington Post is read by the people who think they run the country.
The National Enquirer is read by the people who think Elvis is alive
and running the country ...
- -- Robert J Woodhead
+ -- Robert J. Woodhead
%
The next person to mention spaghetti stacks
to me is going to have his head knocked off.
@@ -47239,7 +47247,7 @@ to hang up the cue. When he did, all the other cues came crashing go the
floor.
"Sorry," he said with a smile.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
The older a man gets, the farther he had to walk to school as a boy.
%
@@ -47261,7 +47269,7 @@ The one L lama, he's a priest
The two L llama, he's a beast
And I will bet my silk pyjama
There isn't any three L lllama.
- -- O. Nash, to which a fire chief replied that occasionally
+ -- Ogden Nash, to which a fire chief replied that occasionally
his department responded to something like a "three L lllama."
%
The One Page Principle:
@@ -47310,15 +47318,15 @@ swift. Thinking of oneself gives little happiness. If, however, one feels
much happiness in this, it is because at bottom one is not thinking of
oneself but of one's ideal. This is far, and only the swift shall reach
it and are delighted.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
The only "ism" Hollywood believes in is plagiarism.
-- Dorothy Parker
%
The only justification for our concepts and systems of concepts is
that they serve to represent the complex of our experiences;
-beyond this they have not legitimacy.
- -- Einstein
+beyond this they have no legitimacy.
+ -- Albert Einstein
%
The only one of your children who does not grow up and move away
is your husband.
@@ -47337,7 +47345,7 @@ The only perfect science is hind-sight.
The only person who always got his work done by Friday was Robinson Crusoe.
%
The only possible interpretation of any research
-whatever in the 'social sciences' is: some do, some don't.
+whatever in the "social sciences" is: some do, some don't.
-- Ernest Rutherford
%
The only problem with being a man of leisure
@@ -47403,7 +47411,7 @@ the lessons that history has to teach.
-- Aldous Huxley
We learn from history that we do not learn from history.
- -- Georg Hegel
+ -- Georg Wilhelm Friedrich Hegel
HISTORY: Papa Hegel he say that all we learn from history is that we learn
nothing from history. I know people who can't even learn from what happened
@@ -47412,7 +47420,7 @@ this morning. Hegel must have been taking the long view.
%
The only thing we learn from history is that we learn nothing from
history.
- -- Hegel
+ -- Georg Wilhelm Friedrich Hegel
I know guys can't learn from yesterday ... Hegel must be taking the
long view.
@@ -47420,7 +47428,7 @@ long view.
%
The only thing which separates man from child is all the values
he has lost over the years.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
The only time a dog gets complimented is when he doesn't do anything.
-- C. Schultz
@@ -47454,7 +47462,7 @@ of a profound truth may well be another profound truth.
-- Niels Bohr
%
The opposite of a profound truth may well be another profound truth.
- -- Bohr
+ -- Niels Bohr
%
The opposite of talking isn't listening. The opposite of talking is
waiting.
@@ -47919,7 +47927,7 @@ The revolution will not be televised.
The reward for working hard is more hard work.
%
The reward of a thing well done is to have done it.
- -- Emerson
+ -- Ralph Waldo Emerson
%
The rhino is a homely beast,
For human eyes he's not a feast.
@@ -47939,7 +47947,7 @@ and to his imagination for his facts.
%
The right to be heard does not automatically include the right to be
taken seriously.
- -- Hubert Humphrey
+ -- Hubert H. Humphrey
%
The right to be let alone is indeed the beginning of all freedom.
-- Justice Douglas
@@ -47971,7 +47979,7 @@ The road to hell is paved with NAND gates.
-- J. Gooding
%
The road to ruin is always in good repair,
-and the travelers pay the expense of it.
+and the travellers pay the expense of it.
-- Josh Billings
%
The Roman Rule
@@ -47991,7 +47999,7 @@ take it too seriously.
-- Mike Harding, "The Armchair Anarchist's Almanac"
%
The rule is, jam to-morrow and jam yesterday, but never jam today.
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
The rule on staying alive as a forecaster is to give 'em a number or
give 'em a date, but never give 'em both at once.
@@ -48000,7 +48008,7 @@ give 'em a date, but never give 'em both at once.
The rules are rather simple to understand: Under democracy you
can defend any view, but only defend it. You can not try to realize
it through power, violence or weapons.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
The rules:
@@ -48036,8 +48044,8 @@ The savior becomes the victim.
%
The scene: in a vast, painted desert, a cowboy faces his horse.
-Cowboy: "Well, you've been a pretty good hoss, I guess. Hardworkin'.
- Not the fastest critter I ever come acrost, but..."
+Cowboy: "Well, you've been a pretty good hoss, I guess. Hardworkin'.
+Not the fastest critter I ever come acrost, but..."
Horse: "No, stupid, not feed*back*. I said I wanted a feed*bag*.
%
@@ -48046,9 +48054,9 @@ Horse: "No, stupid, not feed*back*. I said I wanted a feed*bag*.
The Schwine-Kitzenger Institute study of 47 men over the age of 100
showed that all had these things in common:
- 1) They all had moderate appetites.
- 2) They all came from middle class homes.
- 3) All but two of them were dead.
+ (1) They all had moderate appetites.
+ (2) They all came from middle class homes.
+ (3) All but two of them were dead.
%
The scum also rises.
-- Dr. Hunter S. Thompson
@@ -48131,7 +48139,7 @@ in a direction you did not want. (Goes the wrong way = Goes a long
way.)
-- Dan Roddick
%
-The sixth shiek's sixth sheep's sick.
+The sixth sheik's sixth sheep's sick.
-- [just say that five times...]
%
The sky is blue so we know where to stop mowing.
@@ -48163,7 +48171,7 @@ The so-called "desktop metaphor" of today's workstations is instead an
"airplane-seat" metaphor. Anyone who has shuffled a lap full of papers
while seated between two portly passengers will recognize the difference --
one can see only a very few things at once.
- -- Fred Brooks
+ -- Frederick Brooks, Jr.
%
The so-called lessons of history are for the most part the
rationalizations of the victors. History is written by the survivors.
@@ -48213,7 +48221,7 @@ the table as the children gathered around him.
sir, I know the answer is Jesus, but it sure sounds like a squirrel to me."
%
The sooner all the animals are dead, the sooner we'll find their money.
- -- Ed Bluestone, The National Lampoon
+ -- Ed Bluestone, "The National Lampoon"
%
The sooner you fall behind, the more time you'll have to catch up!
%
@@ -48328,7 +48336,7 @@ that he has the strength to recognize -- and to live with the recognition --
that the world is valueless in itself and that all values are human ones.
He creates himself by fashioning his own values; he has the pride to live
by the values he wills.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
The student in question is performing minimally for his peer group and
is an emerging underachiever.
@@ -48358,7 +48366,9 @@ He did his very best to make
The billows smooth and bright --
And this was very odd, because it was
The middle of the night.
- -- Lewis Carroll, "Through the Looking Glass"
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
The sunlights differ, but there is only one darkness.
-- Ursula K. LeGuin, "The Dispossessed"
@@ -48387,7 +48397,7 @@ The surest sign that a man is in love is when he divorces his wife.
%
The surest way to corrupt a youth is to instruct him to hold in higher
esteem those who think alike than those who think differently.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
The surest way to remain a winner is to
win once, and then not play any more.
@@ -48442,7 +48452,7 @@ it is the gateway to all wizardry.
%
The technician should never forget that he is an artist, the
artist never that he is a technician.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
The telephone is a good way to talk to people without having to offer
them a drink.
@@ -48729,7 +48739,7 @@ And the, um, plains stretch out like my moms girdle, eh?
There's lotsa beers and doughnuts for everyone, eh?
So the last one to be peaceful and everything is a big idiot,
Eh?
-So shut yer face up and dry yer mucklucks by the fire, eh?
+So shut yer face up and dry yer mukluks by the fire, eh?
And dream about girls with their high beams on, eh?
They may be cold, but that's okay! Beer's better that way!
Eh?
@@ -48761,7 +48771,7 @@ The universe is laughing behind your back.
%
The universe is like a safe to which there is a combination -- but the
combination is locked up in the safe.
- -- Peter DeVries
+ -- Peter de Vries
Corollary: The combination is not a problem since we are locked in the
same safe.
@@ -48807,7 +48817,7 @@ regarded as a criminal offence.
-- Edsger W. Dijkstra, SIGPLAN Notices, Volume 17, Number 5
%
The use of money is all the advantage there is to having money.
- -- Ben Franklin
+ -- Benjamin Franklin
%
The value of a program is proportional to the weight of its output.
%
@@ -48827,7 +48837,7 @@ The very powerful and the very stupid have one thing in common.
Instead of altering their views to fit the facts, they alter the facts
to fit their views ... which can be very uncomfortable if you happen to
be one of the facts that needs altering.
- -- Dr. Who, "Face of Evil"
+ -- The Doctor, "Doctor Who: Face of Evil"
%
The very remembrance of my former misfortune proves a new one to me.
-- Miguel de Cervantes
@@ -48914,10 +48924,10 @@ but the leaves are good to smoke!
-- The Shadow
%
The White Rabbit put on his spectacles.
- "Where shall I begin, please your Majesty ?" he asked.
- "Begin at the beginning,", the King said, very gravely,
+ "Where shall I begin, please your Majesty?" he asked.
+ "Begin at the beginning," the King said, very gravely,
"and go on till you come to the end: then stop."
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
The white race is the cancer of history.
-- Susan Sontag
@@ -48950,7 +48960,7 @@ It must have blown through someone's feet,
The wise and intelligent are coming belatedly to realize that alcohol, and
not the dog, is man's best friend. Rover is taking a beating -- and he
should.
- -- W.C. Fields
+ -- W. C. Fields
%
The wise man seeks everything in himself;
the ignorant man tries to get everything from somebody else.
@@ -49015,7 +49025,7 @@ The world wants to be deceived.
-- Sebastian Brant
%
The world's as ugly as sin,
-And almost as delightful
+And almost as delightful.
-- Frederick Locker-Lampson
%
The world's great men have not commonly been great scholars,
@@ -49031,7 +49041,7 @@ pen.
Whether death was by drowning, by fits or by runaway sleigh, the
formula was the same:
Have you heard of the dreadful fate
- Of Mr. P.P. Bliss and wife?
+ Of Mr. P. P. Bliss and wife?
Of their death I will relate,
And also others lost their life
(in the) Ashbula Bridge disaster,
@@ -49099,7 +49109,7 @@ one juror revealed that he was completely deaf and did not have the
remotest clue what was happening.
The judge, Mr. Justice Solomon, asked him if he had heard any
evidence at all and, when there was no reply, dismissed him.
- The excitement which this caused was only equaled when a second
+ The excitement which this caused was only equalled when a second
juror revealed that he spoke not a word of English. A fluent French
speaker, he exhibited great surprised when told, after two days, that he
was hearing a murder trial.
@@ -49207,7 +49217,7 @@ wants and not give in to it, to spend years in silent hurt wondering
if something could have materialized -- and never knowing.
-- David Viscott
%
-The Wright Bothers weren't the first to fly.
+The Wright Brothers weren't the first to fly.
They were just the first not to crash.
%
The yankees, son, are up north.
@@ -49321,7 +49331,7 @@ THEORY:
it will look in print.
%
Theory is gray, but the golden tree of life is green.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
Theory of Selective Supervision:
The one time in the day that you lean back and relax is
@@ -49413,7 +49423,7 @@ There are no accidents whatsoever in the universe.
There are no answers, only cross-references.
-- Weiner
%
-There are no data that cannot be plotted on a straight line if the axis
+There are no data that cannot be plotted on a straight line if the axes
are chosen correctly.
%
There are no emotional victims, only volunteers.
@@ -49484,7 +49494,7 @@ Why don't you go chase them?
There are some micro-organisms that exhibit characteristics of both
plants and animals. When exposed to light they undergo photosynthesis;
and when the lights go out, they turn into animals. But then again,
-don't we all.
+don't we all?
%
There are strange things done in the midnight sun
By the men who moil for gold;
@@ -49507,7 +49517,7 @@ wonder. There are also those who believe that if you stick your fingers up
your nose and blow, it will increase your intelligence.
-- The Teachings of Ebenezum, Volume VII
%
-There are three kinds of lies: lies, damned lies and statistics.
+There are three kinds of lies: Lies, Damned Lies, and Statistics.
-- Benjamin Disraeli
%
There are three kinds of people: men, women, and unix.
@@ -49538,7 +49548,7 @@ long winter evenings.
%
There are three rules for writing a novel.
Unfortunately, no one knows what they are.
- -- Maugham
+ -- W. Somerset Maugham
%
There are three schools of magic. One: State a tautology, then ring the
changes on its corollaries; that's philosophy. Two: Record many facts.
@@ -49558,7 +49568,6 @@ love them, suffer for them, or turn them into literature.
-- Stephen Stills
%
There are three ways to get something done:
-
1: Do it yourself.
2: Hire someone to do it for you.
3: Forbid your kids to do it.
@@ -49591,11 +49600,11 @@ I have *never* heard them sound better. They are *wailing* up here."
"The bad news is that God has this girlfriend that sings..."
%
There are two kinds of fool. One says, "This is old, and therefore good."
-And one says "This is new, and therefore better."
+And one says, "This is new, and therefore better."
-- John Brunner, "The Shockwave Rider"
%
There are two kinds of pedestrians... the quick and the dead.
- -- Lord Thomas Rober Dewar
+ -- Lord Thomas Robert Dewar
%
There are two kinds of solar-heat systems: "passive" systems collect
the sunlight that hits your home, and "active" systems collect the
@@ -49659,7 +49668,7 @@ There cannot be a crisis next week. My schedule is already full.
%
There comes a time in the affairs of a man when he
has to take the bull by the tail and face the situation.
- -- W.C. Fields
+ -- W. C. Fields
%
There comes a time to stop being angry.
-- A Small Circle of Friends
@@ -49710,7 +49719,7 @@ A: The elevator would be full.
There is a certain frame of mind to which a cemetery
is, if not an antidote, at least an alleviation. If
you are in a fit of the blues, go nowhere else.
- -- Robert Louis Stevenson: Immortelles
+ -- Robert Louis Stevenson, "Immortelles"
%
There is a certain impertinence in allowing oneself to be burned for an
opinion.
@@ -49833,7 +49842,7 @@ man who eats Grapenuts on principle.
-- G. K. Chesterton
%
There is more to life than increasing its speed.
- -- Mahatma Mohandis K. Gandhi
+ -- Mohandas K. Gandhi
%
There is much Obi-Wan did not tell you.
-- Darth Vader
@@ -49848,7 +49857,7 @@ is not capable; for in politics there is no honour.
-- Benjamin Disraeli, "Vivian Grey"
%
There is no bad taste. There is only good taste, and that is bad.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
There is no better way of exercising the imagination than the study of law.
No poet ever interpreted nature as freely as a lawyer interprets truth.
@@ -49870,7 +49879,7 @@ There is no cure for birth and death other than to enjoy the interval.
%
There is no delight the equal of dread.
As long as it is somebody else's.
- --Clive Barker
+ -- Clive Barker
%
There is no distinction between any AI program and some existent game.
%
@@ -49879,7 +49888,7 @@ There is no distinctly native American criminal class except Congress.
%
There is no doubt that my lawyer is honest. For example, when he
filed his income tax return last year, he declared half of his salary
-as 'unearned income.'
+as "unearned income."
-- Michael Lara
%
There is no education that is not political. An apolitical
@@ -49998,7 +50007,7 @@ There is not opinion so absurd that some philosopher will not express it.
-- Marcus Tullius Cicero, "Ad familiares"
%
There is nothing more exhilarating than to be shot at without result.
- -- Churchill
+ -- Winston Churchill
%
There is nothing more silly than a silly laugh.
-- Gaius Valerius Catullus
@@ -50046,7 +50055,7 @@ There is only one way to be happy by means of the heart -- to have none.
-- Paul Bourget
%
There is only one way to console a widow. But remember the risk.
- -- Robert Heinlein
+ -- Robert A. Heinlein
%
There is only one way to kill capitalism --
by taxes, taxes, and more taxes.
@@ -50061,7 +50070,7 @@ it would be amusing to know, could we have it authentically communicated.
-- James Boswell
%
There is plenty of time before progress goes too far.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
There is something in the pang of change
More than the heart can bear,
@@ -50084,7 +50093,7 @@ There must be more to life than having everything.
-- Maurice Sendak
%
There never was a good war or a bad peace.
- -- Ben Franklin
+ -- Benjamin Franklin
%
There once was a king who ruled his country long, wisely, and well. The
king had a son whom he hoped would someday rule the land. He also wished
@@ -50110,10 +50119,10 @@ that I had promised."
The king knew that his son would be a great king.
%
There seems no plan because it is all plan.
- -- C.S. Lewis
+ -- C. S. Lewis
%
-There was a boy called Eustace Clarence Scrubb, and he almost deserved it."
- -- C.S. Lewis, "The Chronicles of Narnia"
+There was a boy called Eustace Clarence Scrubb, and he almost deserved it.
+ -- C. S. Lewis, "The Chronicles of Narnia"
%
There was a little girl
Who had a little curl
@@ -50157,7 +50166,7 @@ There was a writer in 'Life' magazine ... who claimed that rabbits have
no memory, which is one of their defensive mechanisms. If they recalled
every close shave they had in the course of just an hour life would become
insupportable.
- -- Kurt Vonnegut
+ -- Kurt Vonnegut, Jr.
%
There was a young man from LeDoux,
Whose limericks stopped at line two.
@@ -50287,7 +50296,7 @@ There's a thrill in store for all for we're about to toast
The corporation that we represent.
We're here to cheer each pioneer and also proudly boast,
Of that man of men our sterling president
-The name of T.J. Watson means
+The name of T. J. Watson means
A courage none can stem
And we feel honored to be here to toast the IBM.
-- Ever Onward, from the 1940 IBM Songbook
@@ -50348,7 +50357,7 @@ There's no justice in this world.
instead)
%
There's no point in being grown up if you can't be childish sometimes.
- -- Dr. Who
+ -- The Doctor, "Doctor Who"
%
There's no real need to do housework -- after four years it doesn't get
any worse.
@@ -50370,7 +50379,7 @@ There's no such thing as an original sin.
%
There's no trick to being a humorist when you have the whole government
working for you.
- -- Will Rodgers
+ -- Will Rogers
%
There's no use in having a dog and doing your own barking.
%
@@ -50468,7 +50477,7 @@ the only significant job that has so far been given to them.
They are cold-blooded. They are completely ruthless about protecting
what they have. The only thing they connect to is the money aspect of
life. Let's face it: That's the American way.
- -- Jeffery M. Johnson, regional chairman of the District
+ -- Jeffrey M. Johnson, regional chairman of the District
of Columbia United Way, speaking of drug dealers.
%
They are ill discoverers that think there is no land,
@@ -50515,7 +50524,7 @@ They make a desert and call it peace.
They say it's the responsibility of the media to look at government --
especially the president -- with a microscope. I don't argue with that,
but when they use a proctoscope, it's going too far.
- -- Richard Nixon
+ -- Richard M. Nixon
%
They seem to have learned the habit of cowering before authority even when
not actually threatened. How very nice for authority. I decided not to
@@ -50596,11 +50605,6 @@ for freedom.
They're giving bank robbing a bad name.
-- John Dillinger, on Bonnie and Clyde
%
-They're just jealous because they don't have three
-wise men and a virgin in the whole organization.
- -- Mayor Vincent J. `Buddy' Cianci, on the
- ACLU's suit to have a city nativity scene removed.
-%
They're only trying to make me LOOK paranoid!
%
They're unfriendly, which is fortunate, really. They'd be difficult
@@ -50612,7 +50616,7 @@ their property that they may more perfectly respect it.
-- G. K. Chesterton, "The Man Who Was Thursday"
%
Things are more like they are today than they ever were before.
- -- Dwight Eisenhower
+ -- Dwight D. Eisenhower
%
Things are more like they used to be than they are now.
%
@@ -50621,7 +50625,7 @@ Things are not always what they seem.
%
Things Charles Darwin did not say:
-Finches, eh ? Seen one, seem 'em all.
+Finches, eh? Seen one, seem 'em all.
%
Things Charles Darwin did not say:
@@ -50712,6 +50716,22 @@ This door is baroquen, please wiggle Handel.
%
This dungeon is owned and operated by Frobazz Magic Co., Ltd.
%
+This email and any files transmitted with it are confidential and
+intended solely for the use of the individual or entity to which they
+are addressed. If you are not the intended recipient of this
+transmission, please delete it immediately.
+
+Obviously, I am the idiot who sent it to you by mistake. Furthermore,
+there is no way I can force you to delete it. Worse, by the time you
+have reached this disclaimer you have already read the document.
+Telling you to forget it would seem absurd. In any event, I have no
+legal right to force you to take any action upon this email anyway.
+
+This entire disclaimer is just a waste of everyone's time and
+bandwidth. Therefore, let us just forget the whole thing and enjoy a
+cold beer instead.
+ -- found on the dovecot mailinglist
+%
This file will self-destruct in five minutes.
%
This Fortue Examined By INSPECTOR NO. 2-14
@@ -50835,7 +50855,7 @@ you forget. Our target is 300 new fortunes by the end of the week.
Don't miss out. All fortunes will be acknowledged. If you contribute
30 fortunes or more, you will receive a free subscription to "The
Fortune Hunter", our monthly program guide. If you contribute 50 or
-more, you will receive a free "Fortune Hunter" coffee mug ....
+more, you will receive a free "Fortune Hunter" coffee mug ...
%
This is supposed to be a happy occasion.
Let's not BICKER and ARGUE over who killed who!
@@ -50846,7 +50866,7 @@ and come alone. I'm serious!
%
This is the first age that's paid much attention to the future,
which is a little ironic since we may not have one.
- -- Arthur Clarke
+ -- Arthur C. Clarke
%
This is the first numerical problem I ever did. It demonstrates the
power of computers:
@@ -50905,7 +50925,7 @@ been called by others the fiddle factor..."
This land is full of trousers!
this land is full of mausers!
And pussycats to eat them when the sun goes down!
- -- Firesign Theater
+ -- The Firesign Theatre
%
This land is made of mountains,
This land is made of mud,
@@ -51019,7 +51039,7 @@ adds happiness in a world in which happiness is always in short supply.
This screen intentionally left blank.
%
This sentence contradicts itself -- no actually it doesn't.
- -- Hofstadter
+ -- Douglas Hofstadter
%
This sentence does in fact not have the property it claims not to have.
%
@@ -51133,7 +51153,7 @@ Those who in quarrels interpose, must often wipe a bloody nose.
%
Those who make peaceful revolution impossible
will make violent revolution inevitable.
- -- John Fitzgerald Kennedy
+ -- John F. Kennedy
%
Those who profess to favor freedom, and yet depreciate agitation, are
men who want rain without thunder and lightning. They want the ocean
@@ -51144,7 +51164,7 @@ Those who sweat in flames of hell, Leaden eared, some thought their bowels
Here's the reason that they fell: Lispeth forth the sweetest vowels.
While on earth they prayed in SAS, These they offered up in praise
PL/1, or other crass, Thinking all this fetid haze
-Vulgar tongue. A rapsody sung.
+Vulgar tongue. A rhapsody sung.
Some the lord did sorely try Jabber of the mindless horde
Assembling all their pleas in hex. Sequel next did mock the lord
@@ -51211,12 +51231,12 @@ all appearing on a quiz program, were asked to complete this sentence:
service station," said the Missourian.
"Wrong."
"Old MacDonald had a farm," said the Iowan.
- "CORRECT!" shouts the quizmaster. "Now for $100,000, spell 'farm.'"
+ "CORRECT!" shouts the quizmaster. "Now for $100,000, spell `farm.'"
"Easy," said the Iowan. "E-I-E-I-O."
%
Three minutes' thought would suffice to find this out; but thought
is irksome and three minutes is a long time.
- -- A. E. Houseman
+ -- A. E. Housman
%
Three o'clock in the afternoon is always just a little too
late or a little too early for anything you want to do.
@@ -51392,7 +51412,7 @@ but I don't always approve of Time's methods.
Time-sharing is the junk-mail part of the computer business.
-- H. R. J. Grosch (attributed)
%
-timesharing, n:
+Timesharing, n.:
An access method whereby one computer abuses many people.
%
Timing must be perfect now.
@@ -51479,7 +51499,7 @@ To add insult to injury.
To announce that there must be no criticism of the president, or that we are
to stand by the president right or wrong, is not only unpatriotic and
servile, but is morally treasonable to the American public."
- -- Theodore Roosevelt
+ -- Theodore Roosevelt
%
To any truly impartial person, it would
be obvious that I am always right.
@@ -51537,7 +51557,7 @@ To be loved is very demoralizing.
To be nobody-but-yourself in a world which is doing its best to,
night and day, to make you everybody else -- means to fight the hardest
battle which any human being can fight; and never stop fighting.
- -- E.E. Cummings, "A Miscellany"
+ -- e. e. cummings, "A Miscellany"
%
To be or not to be.
-- Shakespeare
@@ -51753,7 +51773,7 @@ To many, total abstinence is easier than perfect moderation.
TO ME, CLOWNS AREN'T FUNNY. In fact, they're kinda scary. I've wondered
where this started, and I think it goes back to the time I went to the
circus and a clown killed my dad.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
To one large turkey add one gallon of vermouth and a demijohn of Angostura
bitters. Shake.
@@ -51788,7 +51808,7 @@ There was nothing savage in the act, although the knife was large and keen;
it was a piece of art, high art; there was delicacy of touch, clearness of
tone, skillful handling of the subject, fine shading. It was the triumph of
mind over matter; quite.
- -- Dickens, "Martin Chuzzlewit"
+ -- Charles Dickens, "Martin Chuzzlewit"
%
To see you is to sympathize.
%
@@ -51937,7 +51957,7 @@ Today is the first day of the rest of your lossage.
%
Today is the last day of your life so far.
%
-Today is the tomorrow you worried about yesterday
+Today is the tomorrow you worried about yesterday.
%
Today is what happened to yesterday.
%
@@ -51966,7 +51986,7 @@ Today's weirdness is tomorrow's reason why.
%
Toddlers are the stormtroopers of the Lord of Entropy.
%
-Toilet Toupee, n:
+Toilet Toupee, n.:
Any shag carpet that causes the lid to become top-heavy, thus
creating endless annoyance to male users.
-- Rich Hall, "Sniglets"
@@ -52000,7 +52020,7 @@ driving cabs and cutting hair.
%
TOO BAD YOU CAN'T BUY a voodoo globe so that you could make the earth spin
real fast and freak everybody out.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
Too clever is dumb.
-- Ogden Nash
@@ -52081,7 +52101,7 @@ Follow these simple suggestions:
(2) Use tape, magnets, or glue instead of paperweights.
(3) Give up skiing and skydiving for more horizontal sports like
curling.
-(4) Avoid showers .. take baths instead.
+(4) Avoid showers ... take baths instead.
(5) Don't hang all your clothes in the closet ... Keep them in one big
pile.
(6) Stop flipping pancakes
@@ -52099,7 +52119,7 @@ Top Ten Things Overheard At The ANSI C Draft Committee Meetings:
4: How many times do we have to tell you, "No prior art!"
3: Ha, ha, I can't believe they're actually going to adopt this sucker.
2: Thank you for your generous donation, Mr. Wirth.
- 1: Gee, I wish we hadn't backed down on 'noalias'.
+ 1: Gee, I wish we hadn't backed down on "noalias".
%
Topologists are just plane folks.
Pilots are just plane folks.
@@ -52677,7 +52697,7 @@ And the hunter home from the hill.
Underlying Principle of Socio-Genetics:
Superiority is recessive.
%
-understand, v:
+Understand, v.:
To reach a point, in your investigation of some subject, at which
you cease to examine what is really present, and operate on the
basis of your own internal model instead.
@@ -52712,13 +52732,13 @@ every persuasion. Meanwhile, fears of universal disaster sank to an all-time
low over the world.
-- Isaac Asimov
%
-universe, n:
+Universe, n.:
The problem.
%
Universities are places of knowledge. The freshman each bring a little
in with them, and the seniors take none away, so knowledge accumulates.
%
-UNIVERSITY:
+University, n.:
Like a software house, except the software's free, and it's
usable, and it works, and if it breaks they'll quickly tell
you how to fix it, and...
@@ -52736,7 +52756,7 @@ of more feet, just to be sure.
-- Eric Allman
... We make rope.
- -- Rob Gingell on Sun Microsystem's new virtual memory
+ -- Rob Gingell on Sun Microsystems' new virtual memory
%
Unix is a lot more complicated (than CP/M) of course -- the typical Unix
hacker can never remember what the PRINT command is called this week --
@@ -52759,7 +52779,7 @@ but it's never been everything to anybody.
Unix is the worst operating system; except for all others.
-- Berry Kercheval
%
-Unix, n:
+Unix, n.:
A computer operating system, once thought to be flabby and
impotent, that now shows a surprising interest in making off
with the workstation harem.
@@ -52768,7 +52788,7 @@ unix soit qui mal y pense
%
UNIX was half a billion (500000000) seconds old on
Tue Nov 5 00:53:20 1985 GMT (measuring since the time(2) epoch).
- -- Andy Tannenbaum
+ -- Andrew S. Tanenbaum
%
UNIX was not designed to stop you from doing stupid things, because that
would also stop you from doing clever things.
@@ -52789,7 +52809,7 @@ time waste me.
-- William Shakespeare
%
Unless you love someone, nothing else makes any sense.
- -- E.E. Cummings
+ -- e. e. cummings
%
Unnamed Law:
If it happens, it must be possible.
@@ -52803,7 +52823,7 @@ pays out twice as much in taxes as he formerly got in wages.
-- H. L. Mencken
%
Until Eve arrived, this was a man's world.
- -- Richard Amour
+ -- Richard Armour
%
UNTOLD WEALTH:
What you left out on April 15th.
@@ -52830,10 +52850,10 @@ more labor and less oratory.
%
User hostile.
%
-User n.:
+User, n.:
A programmer who will believe anything you tell him.
%
-user, n:
+User, n.:
The word computer professionals use when they mean "idiot."
-- Dave Barry, "Claw Your Way to the Top"
@@ -52966,7 +52986,7 @@ X:
%
Victory uber allies!
%
-Viking, n:
+Viking, n.:
1. Daring Scandinavian seafarers, explorers, adventurers,
entrepreneurs world-famous for their aggressive, nautical import
business, highly leveraged takeovers and blue eyes.
@@ -52995,7 +53015,7 @@ Violence is a sword that has no handle -- you have to hold the blade.
Violence is molding.
%
Violence is the last refuge of the incompetent.
- -- Salvador Hardin
+ -- Salvor Hardin
%
Violence stinks, no matter which end of it you're on. But now and then
there's nothing left to do but hit the other person over the head with a
@@ -53053,11 +53073,11 @@ Visits always give pleasure: if not on arrival, then on the departure.
Vital papers will demonstrate their vitality by spontaneously moving
from where you left them to where you can't find them.
%
-Vitamin C deficiency is apauling
+Vitamin C deficiency is apauling.
%
VMS is like a nightmare about RSX-11M.
%
-VMS, n:
+VMS, n.:
The world's foremost multi-user adventure game.
%
VMS version 2.0 ==>
@@ -53107,7 +53127,7 @@ Wagner's music is better than it sounds.
Wait for that wisest of all counselors, Time.
-- Pericles
%
-Waiter: "Tea or coffee, gentlemen?"
+Waiter: "Tea or coffee, gentlemen?"
1st customer: "I'll have tea."
2nd customer: "Me, too -- and be sure the glass is clean!"
(Waiter exits, returns)
@@ -53166,11 +53186,11 @@ Wanna tell you all a story 'bout a man named Jed,
A poor mountaineer, barely kept his family fed.
But then one day he was shootin' at some food,
When up through the ground come a bubblin' crude -- oil, that is;
- black gold; 'Texas tea' ...
+ black gold; "Texas tea" ...
Well the next thing ya know, old Jed's a millionaire.
-The kinfolk said, 'Jed, move away from there!'
-They said, 'Californy is the place ya oughta be',
+The kinfolk said, "Jed, move away from there!"
+They said, "Californy is the place ya oughta be",
So they loaded up the truck and they moved to Beverly -- Hills, that is;
swimmin' pools; movie stars.
%
@@ -53328,7 +53348,7 @@ We are all in the gutter, but some of us are looking at the stars.
-- Oscar Wilde
%
We are all so much together and yet we are all dying of loneliness.
- -- A. Schweitzer
+ -- Albert Schweitzer
%
We are all worms. But I do believe I am a glowworm.
-- Winston Churchill
@@ -53343,7 +53363,7 @@ We are confronted with insurmountable opportunities.
-- Walt Kelly, "Pogo"
%
We are drowning in information but starved for knowledge.
- -- John Naisbitt, Megatrends
+ -- John Naisbitt, "Megatrends"
%
We are each entitled to our own opinion, but no one is entitled to his
own facts.
@@ -53392,7 +53412,7 @@ Manual.
We are simple killers of people and destroyers of property.
%
We are so fond of each other because our ailments are the same.
- -- Jonathon Swift
+ -- Jonathan Swift
%
We are sorry. We cannot complete your call as dialed. Please check
the number and dial again or ask your operator for assistance.
@@ -53413,7 +53433,7 @@ to do the unnecessary... for the ungrateful...
%
We are unavoidably drawn towards conservatism and death.
The order is not insignificant.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
We are upping our standards ... so up yours.
-- Pat Paulsen for President, 1988
@@ -53443,11 +53463,11 @@ deceased. My suggestion, therefore, is that you drop dead.
-- James E. Day, Postmaster General
%
We could do that, but it would be wrong, that's for sure.
- -- Richard Nixon
+ -- Richard M. Nixon
%
We could nuke Baghdad into glass, wipe it with Windex, tie fatback on our
feet and go skating.
- -- Fred Reed, Air Force Times columnist.
+ -- Fred Reed, Air Force Times columnist
%
We dedicate this book to our fellow citizens who, for love of truth,
take from their own wants by taxes and gifts, and now and then send
@@ -53524,13 +53544,13 @@ If it's the last thing we ever do.
We had it tough ... I had to get up at 9 o'clock at night, half an
hour before I went to bed, eat a lump of dry poison, work 29 hours down
mill, and when we came home our Dad would kill us, and dance about on
-our grave singing Halleluja ...
+our grave singing Hallelujah ...
-- Monty Python
%
We have an equal opportunity Calculus class -- it's fully integrated.
%
We have art that we do not die of the truth.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
We have ears, earther...FOUR OF THEM!
%
@@ -53590,7 +53610,7 @@ You know the kind of flu I'm talking about.
%
We interrupt this fortune for an important announcement...
%
-"We invented a new protocol and called it Kermit, after Kermit the Frog,
+We invented a new protocol and called it Kermit, after Kermit the Frog,
star of "The Muppet Show." [3]
[3] Why? Mostly because there was a Muppets calendar on the wall when we
@@ -53709,8 +53729,8 @@ We must die because we have known them.
-- Ptah-hotep, 2000 B.C.
%
We must finish once and for all with the neutrality of chess. We must
-condemn once and for all the formula 'chess for the sake of chess,' like
-the formula 'art for art's sake.' We must organize shock-brigades of
+condemn once and for all the formula "chess for the sake of chess," like
+the formula "art for art's sake." We must organize shock-brigades of
chess-players, and begin the immediate realization of a Five-Year Plan
for chess.
-- Nikolai V. Krylenko, People's Commissar for Justice
@@ -53740,7 +53760,7 @@ children smart.
%
We only acknowledge small faults in order
to make it appear that we are free from great ones.
- -- LaRouchefoucauld
+ -- La Rochefoucauld
%
We ought to be very grateful that we have tools. Millions of years ago
people did not have them, and home projects were extremely difficult.
@@ -53775,7 +53795,7 @@ We secure our friends not by accepting favors but by doing them.
%
We seem to have forgotten the simple truth that reason is never perfect.
Only non-sense attains perfection.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
We seldom repent talking too little, but very often talking too much.
-- Jean de la Bruyere
@@ -54054,12 +54074,12 @@ James Bond kills him and his henchmen and makes love to several attractive
women. There, that's it: 24 words. But the guy who wrote the book took
*thousands* of words to say it.
Or consider "The Brothers Karamazov", by the famous Russian alcoholic
-Fyodor Dostoevsky. It's about these two brothers who kill their father.
+Fyodor Dostoyevsky. It's about these two brothers who kill their father.
Or maybe only one of them kills the father. It's impossible to tell because
what they mostly do is talk for nearly a thousand pages. If all Russians talk
as much as the Karamazovs did, I don't see how they found time to become a
major world power.
- I'm told that Dostoevsky wrote "The Brothers Karamazov" to raise
+ I'm told that Dostoyevsky wrote "The Brothers Karamazov" to raise
the question of whether there is a God. So why didn't he just come right
out and say: "Is there a God? It sure beats the heck out of me."
Other famous works could easily have been summarized in a few words:
@@ -54409,7 +54429,7 @@ Cooper and Claudette Colbert, and to be beaten up by both of them!
%
What a misfortune to be a woman! And yet, the worst misfortune is not to
understand what a misfortune it is.
- -- Kierkegaard, 1813-1855
+ -- S. A. Kierkegaard (1813-1855)
%
What a strange game. The only winning move is not to play.
-- WOP, "War Games"
@@ -54480,7 +54500,7 @@ and their young frontiersmen, will require to lead us onward and upward.
-- Dr. Harrison H. Schmidt
%
What does not destroy me, makes me stronger.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
What ever happened to happily ever after?
%
@@ -54501,7 +54521,7 @@ What garlic is to salad, insanity is to art.
What George Washington did for us was to throw out the British, so
that we wouldn't have a fat, insensitive government running our
country. Nice try anyway, George.
- -- D.J. on KSFO/KYA
+ -- Disk Jockey on KSFO/KYA
%
What goes up must come down. But don't expect it to come down
where you can find it. Murphy's Law applied to Newton's.
@@ -54642,7 +54662,7 @@ What is love but a second-hand emotion?
%
What is mind? No matter.
What is matter? Never mind.
- -- Thomas Hewitt Key, 1799-1875
+ -- Thomas Hewitt Key (1799-1875)
%
What is now proved was once only imagin'd.
-- William Blake
@@ -54743,7 +54763,7 @@ What one believes to be true either is true or becomes true.
-- John Lilly
%
What one fool can do, another can.
- -- Ancient Simian Proverb
+ -- Ancient Simian proverb
%
What orators lack in depth they make up in length.
%
@@ -54947,16 +54967,16 @@ What this country needs is a good five cent ANYTHING!
%
What this country needs is a good five cent microcomputer.
%
-What this country needs is a good five dollar plasma weapon.
+What this country needs is a good five cent nickel.
%
-What this country needs is a good five-cent nickel.
+What this country needs is a good five dollar plasma weapon.
%
What time is it?
I don't know, it keeps changing.
%
What upsets me is not that you lied to me,
but that from now on I can no longer believe you.
- -- Nietzsche
+ -- Friedrich Nietzsche
%
What use is magic if it can't save a unicorn?
-- Peter S. Beagle, "The Last Unicorn"
@@ -54968,7 +54988,7 @@ What we cannot speak about we must pass over in silence.
-- Wittgenstein
%
What we do not understand we do not possess.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
What we need in this country, instead of Daylight Savings Time, which
nobody really understands anyway, is a new concept called Weekday
@@ -55059,7 +55079,7 @@ as good. Luckily this is not difficult.
%
Whatever you do will be insignificant,
but it is very important that you do it.
- -- Gandhi
+ -- Mahatma Gandhi
%
Whatever you may be sure of, be sure of this: that you are dreadfully like
other people.
@@ -55094,7 +55114,7 @@ But I think it's your mind.
-- Frank Zappa, 1965
%
What's the use of a good quotation if you can't change it?
- -- Dr. Who
+ -- The Doctor, "Doctor Who"
%
What's this stuff about people being "released on their
own recognizance"? Aren't we all out on own recognizance?
@@ -55109,7 +55129,7 @@ When a cow laughs, does milk come out of its nose?
%
When a fellow says, "It ain't the money but
the principle of the thing," it's the money.
- -- Kim Hubbard
+ -- Kin Hubbard
%
When a fly lands on the ceiling, does it do a half roll or a half
loop?
@@ -55183,7 +55203,7 @@ poor. In that lawsuit, you will lose. If, on the other hand, you kill
him, the most that you can expect is that a relative will bring a wrongful
death action. You will have two advantages: first, there be only your
story; forget Mother Teresa. Second, even if you lose, how much could
-the bum's life be worth anyway? A Lot less than 50 years worth of
+the bum's life be worth anyway? A lot less than 50 years worth of
paralysis. Don't play George Bush and Saddam Hussein. Finish the job.
-- G. Gordon Liddy's Forbes column on personal security
%
@@ -55251,7 +55271,7 @@ that, after assuming the power, we would deny to our adversaries without any
consideration the means which were granted to us in times of our opposition.
-- Josef Goebbels
%
-When Dexter's on the Internet, can Hell be far behind?"
+When Dexter's on the Internet, can Hell be far behind?
%
When does later become never?
%
@@ -55304,7 +55324,7 @@ then sit in my car and count how many people ask me if I'm leaving.
%
When I grow up, I want to be an honest
lawyer so things like that can't happen.
- -- Richard Nixon, as a boy, on the Teapot Dome scandal
+ -- Richard M. Nixon, as a boy, on the Teapot Dome scandal
%
When I have one foot in the grave I will tell the truth about women. I
shall tell it, jump into my coffin, pull the lid over me, and say, "Do
@@ -55338,7 +55358,7 @@ to myself, "I've got to get out of this lane."
When I say the magic word to all these people, they will vanish forever.
I will then say the magic words to you, and you, too, will vanish -- never
to be seen again.
- -- Kurt Vonnegut Jr., "Between Time and Timbuktu"
+ -- Kurt Vonnegut, Jr., "Between Time and Timbuktu"
%
When I sell liquor, it's called bootlegging; when my patrons serve
it on silver trays on Lake Shore Drive, it's called hospitality.
@@ -55543,7 +55563,7 @@ Behind blue eyes.
No one knows what its like to be hated,
to be fated,
To telling only lies.
- -- The Who
+ -- The Who, "Behind Blue Eyes"
%
When my freshman roommate at Cornell found out I was Jewish, she was,
at her request, moved to a different room. She told me she didn't
@@ -55617,7 +55637,7 @@ is away and you get twice as much done.
-- Daniel B. Luten
%
When smashing monuments, save the pedestals -- they always come in handy.
- -- Stanislaw J. Lem, "Unkempt Thoughts"
+ -- Stanislaw J. Lec, "Unkempt Thoughts"
%
When some people decide it's time for everyone to make
big changes, it means that they want you to change first.
@@ -55685,7 +55705,7 @@ When the candles are out all women are fair.
When the cup is full, carry it level.
%
When the doubt vanishes and the issue becomes evident, stupidity reigns.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
When the English language gets in my way, I walk over it.
-- Billy Sunday
@@ -55744,7 +55764,7 @@ When the only tool you have is a hammer, every problem starts to look
like a nail.
%
When the President does it, that means it is not illegal.
- -- Richard Nixon
+ -- Richard M. Nixon
%
When the revolution comes, count your change.
%
@@ -55793,7 +55813,7 @@ is to believe the one in which people appear at their worst.
-- H. Allen Smith, "Let the Crabgrass Grow"
%
When there is an old maid in the house, a watch dog is unnecessary.
- -- Balzac
+ -- Honore de Balzac
%
When things go well, expect something to
explode, erode, collapse or just disappear.
@@ -55850,7 +55870,7 @@ When women kiss it always reminds one of prize fighters shaking hands.
When women love us, they forgive us everything, even our crimes;
when they do not love us, they give us credit for nothing, not
even our virtues.
- -- Balzac
+ -- Honore de Balzac
%
When you are about to die, a wombat is better than no company at all.
-- Roger Zelazny, "Doorways in the Sand"
@@ -55954,7 +55974,7 @@ When you have to kill a man it costs nothing to be polite.
%
When you jump for joy, beware that no-one
moves the ground from beneath your feet.
- -- Stanislaw Lem, "Unkempt Thoughts"
+ -- Stanislaw J. Lec, "Unkempt Thoughts"
%
When you know absolutely nothing about the topic, make your forecast by
asking a carefully selected probability sample of 300 others who don't
@@ -56027,7 +56047,7 @@ You're driving a Beamer.
When you're away, I'm restless, lonely
Wretched, bored, dejected, only
Here's the rub, my darling dear,
-I feel the same when you are hear.
+I feel the same when you are near.
-- Samuel Hoffenstein, "Poems in Praise of Practically Nothing"
%
When you're bored with yourself, marry, and be bored with someone else.
@@ -56053,12 +56073,12 @@ When you're ready to give up the struggle, who can you surrender to?
%
WHEN YOU'RE RIDING IN A TIME MACHINE way far into the future, don't stick
your elbow out the window or it'll turn into a fossil.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
WHENEVER ANYBODY SAYS he's struggling to become a human being I have to
laugh because the apes beat him to it by about a million years. Struggle
to become a parrot or something.
- -- Jack Handey, The New Mexican, 1988
+ -- Jack Handey, "The New Mexican" (1988)
%
Whenever anyone says, "theoretically," they really mean "not really".
-- Dave Parnas
@@ -56166,7 +56186,7 @@ Where there are visible vapors, having their prevenance
in ignited carbonaceous materials, there is conflagration.
%
Where there is much light there is also much shadow.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
Where there's a whip there's a way.
%
@@ -56343,11 +56363,11 @@ Who does not trust enough will not be trusted.
Who goeth a-borrowing goeth a-sorrowing.
-- Thomas Tusser
%
-Who is D.B. Cooper, and where is he now?
+Who is D. B. Cooper, and where is he now?
%
Who is John Galt?
%
-Who is W.O. Baker, and why is he saying those terrible things about me?
+Who is W. O. Baker, and why is he saying those terrible things about me?
%
Who loves me will also love my dog.
-- John Donne
@@ -56396,7 +56416,7 @@ Whoever named it "necking" was a poor judge of anatomy.
%
Whoever tells a lie cannot be pure in heart -- and only the
pure in heart can make a good soup.
- -- Ludwig Van Beethoven
+ -- Ludwig van Beethoven
%
Whoever would lie usefully should lie seldom.
%
@@ -56632,7 +56652,7 @@ you knowing nothing?
%
Why my thoughts are my own, when they are in, but when they are out they
are another's.
- -- Susanna Martin, executed for witchcraft, 1681
+ -- Susanna Martin, executed for witchcraft, 1681
%
Why not? -- What? -- Why not? -- Why should I not send it? -- Why should I
not dispatch it? -- Why not? -- Strange! I don't know why I shouldn't --
@@ -56696,7 +56716,7 @@ Why You Can't Run When There's Trouble in the Office:
No matter where you stand, no matter how far or fast you flee,
when it hits the fan, as much as possible will be propelled in your
direction, and almost none will be returned to the source.
- -- John L. Shelton
+ -- John L. Shelton
%
Why you say you no bunny rabbit when you have little powder-puff tail?
-- The Tasmanian Devil
@@ -56735,7 +56755,7 @@ Mother cried, "Now, William, stop!" I haven't the heart to poke poor Billy.
William with a thirst for gore, Little Willie mean as hell,
Nailed the baby to the door. Threw his sister in the well!
Mother said, with humor quaint: Said his mother when drawing water,
-"Careful, Will, don't mar the paint." 'sure is hard to raise a daughter.'
+"Careful, Will, don't mar the paint." "sure is hard to raise a daughter."
-- Harry Graham, "Ruthless Rhymes for Heartless Homes", 1899
%
Wilner's Observation:
@@ -56874,7 +56894,7 @@ Hundred billion castaways looking for a call.
WOLF:
A man who knows all the ankles.
%
-Woman: "Is Yoo-Hoo hyphenated?"
+Woman: "Is Yoo-Hoo hyphenated?"
Yogi Berra: "No, ma'am, its not even carbonated."
%
Woman inspires us to great things, and prevents us from achieving them.
@@ -56932,7 +56952,7 @@ Women are just like men, only different.
%
Women are like elephants to me: I like to
look at them, but I wouldn't want to own one.
- -- W.C. Fields
+ -- W. C. Fields
%
Women are not much, but they are the best other sex we have.
-- Herold
@@ -56950,7 +56970,7 @@ Women can keep a secret just as well as men,
but it takes more of them to do it.
%
Women come and go, but BSD is forever.
- -- Derek Young
+ -- Derek Young
%
Women complain about sex more than men. Their gripes fall into two
categories: (1) Not enough and (2) Too much.
@@ -56975,7 +56995,7 @@ crying, a little dying -- and a good deal of lying.
Women of genius commonly have masculine faces, figures and manners.
In transplanting brains to an alien soil God leaves a little of the
original earth clinging to the roots.
- -- Bierce
+ -- Ambrose Bierce
%
Women reason with the heart and are much less often wrong
than men who reason with the head.
@@ -56996,15 +57016,15 @@ than being slapped is when you get on your knees and say you're sorry.
%
Women waste men's lives and think they have
indemnified them by a few gracious words.
- -- Balzac
+ -- Honore de Balzac
%
Women, when they are not in love, have all
the cold blood of an experienced attorney.
- -- Balzac
+ -- Honore de Balzac
%
Women, when they have made a sheep of a man,
always tell him that he is a lion with a will of iron.
- -- Balzac
+ -- Honore de Balzac
%
Women who want to be equal to men lack imagination.
%
@@ -57201,7 +57221,7 @@ a valentine.
-- Christopher Plummer
%
World tensions have, if anything, increased in the quarter century
-since H.G. Wells uttered his glum warning: "There is no more evil
+since H. G. Wells uttered his glum warning: "There is no more evil
thing on earth than race prejudice, none at all. I write deliberately
-- it is the worst single thing in life now. It justifies and holds
together more baseness, cruelty and abomination than any other sort of
@@ -57280,7 +57300,7 @@ Write a wise saying and your name will live forever.
%
Write yourself a threatening letter and pen a defiant reply.
%
-write-protect tab, n:
+Write-protect tab, n.:
A small sticker created to cover the unsightly notch carelessly left
by disk manufacturers. The use of the tab creates an error message
once in a while, but its aesthetic value far outweighs the momentary
@@ -57455,7 +57475,7 @@ X windows:
Incompatibility. Shoddiness. Uselessness.
X windows.
%
-Xerox does it again and again and again and...
+Xerox does it again and again and again and ...
%
Xerox never comes up with anything original.
%
@@ -57856,7 +57876,7 @@ And yet you incessantly stand on your head --
"I feared it might injure the brain;
But, now that I'm perfectly sure I have none,
Why, I do it again and again."
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
"You are old," said the youth, "and I'm told by my peers
That your lectures bore people to death.
@@ -57877,7 +57897,7 @@ Yet you finished the goose, with the bones and the beak --
And argued each case with my wife;
And the muscular strength which it gave to my jaw,
Has lasted the rest of my life."
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
"You are old," said the youth, "and your programs don't run,
And there isn't one language you like;
@@ -57898,7 +57918,7 @@ Yet you turned a back-somersault in at the door --
"I kept all my limbs very supple
By the use of this ointment -- one shilling the box --
Allow me to sell you a couple?"
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
"You are old," said the youth, "as I mentioned before,
And make errors few people could bear;
@@ -57919,7 +57939,7 @@ Yet you balanced an eel on the end of your nose --
Said his father. "Don't give yourself airs!
Do you think I can listen all day to such stuff?
Be off, or I'll kick you down stairs!"
- -- Lewis Carroll
+ -- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
%
You are only young once, but you can stay immature indefinitely.
%
@@ -58003,7 +58023,7 @@ They're the ones with arrows sticking out of their backs.
%
You can approach truth, but never capture it.
Lies can be had 'round the corner.
- -- Poul Henningsen [1894-1967]
+ -- Poul Henningsen (1894-1967)
%
You can be replaced by this computer.
%
@@ -58111,7 +58131,7 @@ You can make it illegal, but you can't make it unpopular.
%
You can measure a programmer's perspective by noting his attitude on
the continuing viability of FORTRAN.
- -- Alan Perlis
+ -- Alan J. Perlis
%
You can move the world with an idea,
but you have to think of it first.
@@ -58159,7 +58179,8 @@ You can tell the ideals of a nation by its advertisements.
You can tune a piano, but you can't tuna fish.
%
You can write a small letter to Grandma in the filename.
- -- Forbes Burkowski, CS, University of Washington
+ -- Forbes Burkowski, Computer Science 454,
+ University of Washington
%
You canna change the laws of physics, Captain;
I've got to have thirty minutes!
@@ -58191,14 +58212,14 @@ You can't carve your way to success without cutting remarks.
%
You can't cheat an honest man, never give
a sucker an even break or smarten up a chump.
- -- W.C. Fields
+ -- W. C. Fields
%
You can't cheat the phone company.
%
You can't cross a large chasm in two small jumps.
%
You can't depend on the man who made the mess to clean it up.
- -- Richard Nixon, 1952
+ -- Richard M. Nixon (1952)
%
You can't erase a dream, you can only wake me up.
-- Peter Frampton
@@ -58345,7 +58366,7 @@ form.
%
You first parent of the human race... who ruined yourself for an apple,
what might you have done for a truffled turkey?
- -- Brillat-savarin, "Physiologie du Gout"
+ -- Brillat-Savarin, "Physiologie du go^ut"
%
You get along very well with everyone except animals and people.
%
@@ -58354,7 +58375,7 @@ You get what you pay for.
%
You give me space to belong to myself yet without separating me
from your own life. May it all turn out to your happiness.
- -- Goethe
+ -- Johann Wolfgang von Goethe
%
You go down to the pickup station,
craving warmth and beauty;
@@ -58476,7 +58497,9 @@ You have the power to influence all with whom you come in contact.
%
You have to run as fast as you can just to stay where you are.
If you want to get anywhere, you'll have to run much faster.
- -- Lewis Carroll
+ -- Lewis Carroll,
+ "Through the Looking-Glass,
+ and What Alice Found There" (1871)
%
You humans are all alike.
%
@@ -58523,7 +58546,7 @@ Goodtime Charlie's got the blues.
%
You know, of course, that the Tasmanians, who never committed adultery,
are now extinct.
- -- M. Somerset Maugham
+ -- W. Somerset Maugham
%
You know, the difference between this company and
the Titanic is that the Titanic had paying customers.
@@ -58535,7 +58558,7 @@ you can always change the channel.
%
You know very well that whether you are on page one or page thirty depends
on whether [the press] fear you. It is just as simple as that.
- -- Richard Nixon
+ -- Richard M. Nixon
%
You know what I wish? I wish all the scum of the Earth had one throat
and I had my hands about it.
@@ -58675,7 +58698,7 @@ That a young man married is a young man marred.
%
You may easily play a joke on a man who likes to argue -- agree with
him.
- -- Ed Howe
+ -- Edgar W. Howe
%
You may get an opportunity for advancement today. Watch it!
%
@@ -59301,7 +59324,7 @@ YOUR FOAMY FUTURE
by Miss Fortune
ARIES (March 21 - April 19)
- Matters are not good, where you health is concerned. This Fall, be
+ Matters are not good, where your health is concerned. This Fall, be
sure to "walk groundly, talk profoundly, drink roundly, and sleep soundly"
and you will live all the days of your life.
@@ -59569,15 +59592,15 @@ You've been telling me to relax all the way here,
and now you're telling me just to be myself?
-- The Return of the Secaucus Seven
%
-You've decked the halls with a dozen miles' length of electric lights.
-Your front lawn is a gleaming testament of incandescent wonder. The neighbors
-wear sunglasses 24/7, and orbiting satellites have officially picked up
+You've decked the halls with a dozen miles' length of electric lights.
+Your front lawn is a gleaming testament of incandescent wonder. The neighbors
+wear sunglasses 24/7, and orbiting satellites have officially picked up
and pinpointed your house as the brightest spot on earth.
-
-You've finally put together the Christmas wonderland of your dreams... now
+
+You've finally put together the Christmas wonderland of your dreams... now
if only you could get a good picture of it.
-
-Photographing holiday lights is no easy task.
+
+Photographing holiday lights is no easy task.
-- from an email sent by photojojo.com
%
You've got to have a gimmick if your band sucks.
@@ -59599,7 +59622,7 @@ Zall's Laws:
2: How long a minute is, depends on which side of the bathroom
door you're on.
%
-zeal, n:
+Zeal, n.:
Quality seen in new graduates -- if you're quick.
%
Zero Defects, n.:
@@ -59613,26 +59636,10 @@ Zeus gave Leda the bird.
Zisla's Law:
If you're asked to join a parade, don't march behind the elephants.
%
-Zounds! I was never so bethumped with words
-since I first called my brother's father dad.
+Zounds! I was never so bethump'd with words
+since I first call'd my brother's father dad.
-- William Shakespeare, "King John"
%
Zymurgy's Law of Volunteer Labor:
People are always available for work in the past tense.
%
-This email and any files transmitted with it are confidential and
-intended solely for the use of the individual or entity to which they
-are addressed. If you are not the intended recipient of this
-transmission, please delete it immediately.
-
-Obviously, I am the idiot who sent it to you by mistake. Furthermore,
-there is no way I can force you to delete it. Worse, by the time you
-have reached this disclaimer you have already read the document.
-Telling you to forget it would seem absurd. In any event, I have no
-legal right to force you to take any action upon this email anyway.
-
-This entire disclaimer is just a waste of everyone's time and
-bandwidth. Therefore, let us just forget the whole thing and enjoy a
-cold beer instead.
- -- found on the dovecot mailinglist
-%
diff --git a/games/fortune/datfiles/fortunes-o.real b/games/fortune/datfiles/fortunes-o.real
index 5c89363..3078315 100644
--- a/games/fortune/datfiles/fortunes-o.real
+++ b/games/fortune/datfiles/fortunes-o.real
@@ -57,7 +57,7 @@ Now it even hurts to take a piss.
Oh why did I get syphilis?
Why'd she have VD? I don't know, she wouldn't say.
-I did something wrong, now I long for yesterday ....
+I did something wrong, now I long for yesterday ...
-- To the tune of "Yesterday"
%
My Favorite Drugs [Sung to My Favorite Things]
@@ -111,7 +111,7 @@ Testicles, testicles, said Daddy. A man gets tired of testicles.
%
... But among the children of the Great Society there were
those whose skins were black. And lo! Their portion was niggardly,
-and of the fatted calf they were sucking hind teat....
+and of the fatted calf they were sucking hind teat ...
Now it came to pass that a prophet rose up amongst them, and
they called him King. And he went unto Pharaoh and said, "Let my
people go to the front of the bus."
@@ -201,7 +201,7 @@ you explain a thing like that to a seven-year-old child?"
%
A great American Olympic wrestler was receiving last-minute advice
from his coach about the upcoming match with the Soviet Champion.
- "This Russian guy is really good, very strong and quick. But I think
+ "This Russian guy is really good, very strong and quick. But I think
you can take him. Remember, though, like I've told you before, don't let
him get you in the Pretzel hold. With his strength you'd never get out."
The American leaps onto the mat, and within moments the two behemoths
@@ -215,7 +215,7 @@ scream and the two wrestlers fly apart, the American regaining control and
pinning the Russian. After the match, in the dressing room, the coach
finally gets the winner alone. "Great job! But how the hell did you get out
of the Pretzel Hold? I thought it was over for sure!"
- "Well, I did too. I was in the hold, about to be pinned, when I saw
+ "Well, I did too. I was in the hold, about to be pinned, when I saw
this huge pair of testicles hanging right in front of my eyes. I figured
what the hell, so I stretched forward and bit them as hard as I could. Coach,
you just don't know your own strength 'til you've bitten your own balls!"
@@ -663,13 +663,6 @@ posh hotel.
"Why, yes, young man," said the gentleman. "Would you bring me
a postcard?"
%
- As we know, there are known knowns. There are things we know we
-know. We also know there are known unknowns. That is to say, we know
-there are some things we do not know. But there are also unknown
-unknowns; the ones we don't know we don't know.
- -- United States Secretary of Defense Donald Rumsfeld
- 12 February 2002, Regarding the US invasion of Iraq
-%
"Are pirates an ethnic group? Or are they just people who burn
illegal cds?"
"Arrrr! We prefer to be called Buccaneer-Americans."
@@ -693,6 +686,13 @@ immersible for easy cleaning. SofSqueeze's flesh-toned exterior is finely
textured for a realistic effect. Requires 4K RAM, a DB25 serial port and
limited graphics capability. Comes fully assembled, with 4 AA batteries.
%
+ As we know, there are known knowns. There are things we know we
+know. We also know there are known unknowns. That is to say, we know
+there are some things we do not know. But there are also unknown
+unknowns; the ones we don't know we don't know.
+ -- United States Secretary of Defense Donald Rumsfeld
+ 12 February 2002, Regarding the US invasion of Iraq
+%
At an elegant dinner party, Lady Astor once leaned across the table
to remark, "If you were my husband, Winston, I'd poison your coffee." "And
if you were my wife, I'd beat the shit out of you," came Churchill's
@@ -812,7 +812,7 @@ captured early and spent the duration doing the dishes."
"Wha-wha-wha-what does regret mean?"
"Well, son, a funny thing about regret is that it's better to regret
something you have done, than to regret something you haven't done. And by
-the way, if you see your Mom this weekend, would be you sure and tell her,
+the way, if you see your Mom this weekend, would you be sure and tell her,
`SATAN, SATAN, SATAN!!!'"
-- Butthole Surfers, "Sweat Loaf"
%
@@ -1194,7 +1194,7 @@ man. Mud-as-man alone could speak.
"Certainly," said man.
"Then I leave it to you to think of one for all of this," said God.
And He went away.
- -- Kurt Vonnegut, Between Time and Timbuktu"
+ -- Kurt Vonnegut, Jr., "Between Time and Timbuktu"
%
In the beginning was the DEMO Project. And the Project was
without form. And darkness was upon the staff members thereof. So
@@ -1742,14 +1742,14 @@ I use the tongs."
the week. As he approaches the Jones' house, Mrs. Jones greets him warmly at
the door. "Please come in! We're very grateful for your years of service to
us and our neighborhood. I've prepared something special for you."
- In walks the mailman, to a graciously appointed dining room, where
+ In walks the mailman, to a graciously appointed dining room, where
Mrs. Jones has prepared a sumptuous lunch. After dumping his letter satchel
on the couch, he and Mrs. Jones have a charming meal. As the mailman finished
his last glass of wine, thanking his hostess profusely, she stops him from
leaving and disappears upstairs. She returns in a moment, in a daring
negligee, and takes the astonished postman to the bedroom, where the elaborate
farewell is consummated between the sheets.
- As he's putting his pants on, Mrs. Jones reaches into her nightstand,
+ As he's putting his pants on, Mrs. Jones reaches into her nightstand,
pulls out a dollar bill, and hands it to him. Reacting to his astonished
look, she says, "Well, I told my husband that you were retiring and that
we should do something for you. He said 'Fuck him. Give him a dollar!'"
@@ -1793,12 +1793,12 @@ did to us?"
The Split-Atom Blues
Gimme Twinkies, gimme wine,
- Gimme jeans by Calvin Kline....
+ Gimme jeans by Calvin Klein ...
But if you split those atoms fine,
Mama keep 'em off those genes of mine!
Gimme zits, take my dough,
- Gimme arsenic in my jelly roll....
+ Gimme arsenic in my jelly roll ...
Call the devil and sell my soul,
But Mama keep dem atoms whole!
-- Milo Bloom, "Bloom County"
@@ -2089,7 +2089,7 @@ three days."
%
We were somewhere around Barstow on the edge of the desert when the
drugs began to take hold. I remember saying something like "I feel a bit
-lightheaded; maybe you should drive...." And suddenly there was a terrible
+lightheaded; maybe you should drive ..." And suddenly there was a terrible
roar all around us and the sky was full of what looked like huge bats, all
swooping and screeching and diving around the car, which was going about a
hundred miles an hour with the top down to Las Vegas. And a voice was
@@ -2244,7 +2244,7 @@ obscure such reality.
-- Steve Allen
%
... And then there's the guy who bought 20,000 bras, cut them in half,
-and sold 40,000 yamalchas with chin straps....
+and sold 40,000 yamalchas with chin straps ...
%
... But the reward of a successful collaboration is a thing that cannot
be produced by either of the parties working alone. It is akin to the
@@ -2332,7 +2332,7 @@ your balls.
3. A beer won't even act amazed if you can.
4. You don't have to let a beer win.
5. Just because you have dinner with a beer doesn't mean you have to
- sleep with a beer, too.
+ sleep with it, too.
6. A beer helps with the housework.
7. A beer will never fumble with your bra.
8. A beer will never take the newspaper apart before you've read it.
@@ -2714,9 +2714,9 @@ fought, we noticed 2 more Fokkers coming at us from above and 2 more
Fokkers, fresh from the landing field, come to join the battle".
At this second and third mention of `Fokkers' the class was almost laughing
openly, and the teacher interrupted the story to ask the pilot to explain
-to the class that a 'Fokkers' was a particular type of plane flown by the
+to the class that a `Fokker' was a particular type of plane flown by the
German Air Force.
- He replied, "Ya, dat is true, but these Fokkers were Messerschmidts".
+ He replied, "Ya, dat is true, but these Fokkers were Messerschmitts."
%
A group of scientists discovered an apelike creature in the jungle, which
they hoped would prove to be the missing link. The proof of their theory,
@@ -3231,7 +3231,7 @@ by the propensity to be sexually aroused by the sight of males.
%
A nuclear family is out golfing one day, when it becomes clear that Dad isn't
going to win any trophies, at least on this course. On the 3rd hole, after
-two miserable bogies, he misses a two foot put and exclaims, "Shit!"
+two miserable bogies, he misses a two foot putt and exclaims, "Shit!"
His wife glances over at their sixteen year old daughter and says
nothing.
On the fourth hole Dad tees off with an incredible hook, and, after
@@ -3591,7 +3591,7 @@ A woman who is guided by the head and not by the heart is a social
pestilence: she has all the defects of the passionate and affectionate
woman, with none of her compensations; she is without pity, without
love, without virtue, without sex.
- -- Balzac
+ -- Honore de Balzac
%
A woman who is unfaithful deserves to be shot.
-- Pancho Villa
@@ -3658,9 +3658,10 @@ received a telegram from their sister. It read:
I liked the couch falling apart when we sat on it. I was amused
when the shower went cold five minutes after it started. But I'm
- going to kill whoever put the novacaine into the KY jelly...
+ going to kill whoever put the novocaine into the KY jelly...
%
-A.A.A.A.A.: An organization for drunks who drive.
+A.A.A.A.A., n.:
+ An organization for drunks who drive.
%
Aboard the good ship Venus, The cabin boy, the captain's joy,
The mast it was a penis, A cunning little nipper,
@@ -3837,7 +3838,7 @@ down."
"Algorithms" is an anagram for "Hilt orgasm". Maybe this explains
the popularity of this field of study in computer science.
%
-alimony, n:
+Alimony, n.:
Having an ex you can bank on.
%
All a hacker needs is a tight PUSHJ, a loose pair of UUOs, and a warm
@@ -3930,7 +3931,7 @@ willing that either the history of the content of religion should be taught
in this spirit; while those to whom the scientific standpoint is not merely
a technical device, but is the embodiment of the integrity of mind, must
protest against its being taught in any other spirit.
- -- John Dewey, "Democracy in the Schools", 1908
+ -- John Dewey, "Democracy in the Schools" (1908)
%
Alright, yes, date, and shop, and hang out, and go to school ... and
save the world from unspeakable demons. You know, I want to do girlie
@@ -3967,7 +3968,7 @@ main may!'"
Always talk to your wife while you're
making love... if there's a phone handy.
%
-ambition, n:
+Ambition, n.:
An ant crawling up an elephant's leg with rape on his mind.
%
America ... just a nation of two hundred million used car salesman
@@ -4153,7 +4154,7 @@ open. "What's the matter with you?" he said. "Born in a barn?"
%
And prively he caughte hire by the queynte,
And heeld hire harde by the haunche-bones.
- --Geoffrey Chaucer, The Miller's Tale
+ -- Geoffrey Chaucer, "The Miller's Tale"
%
And so it goes. It is humiliating, when you should know better, to become
victim of the timeless story of the little brown dog running across the
@@ -4214,7 +4215,7 @@ daiquiri. The bartender looks him over with amusement and says: "We don't
serve your kind, buddy, why don't you get out of here before the boys come
in and kick your ass?"
The guy whimpers a little and lisps, "Pleasse misssture I am soooo
-thurstay...."
+thurstay ..."
Well, the bartender feels somewhat sorry for him and hands him a beer
on the house on the condition that he drink it in the back and leave as soon
as he's done. A little while later, a hulking cowboy walks in and up to the
@@ -4284,7 +4285,7 @@ be childless.
The only solid and lasting peace between a man and his wife is,
doubtless, a separation.
- -- Lord Chesterfield, letter to his son, 1763
+ -- Lord Chesterfield, letter to his son (1763)
%
As for Carter being for registration but against the draft, isn't that
sort of being like for putting it in and not taking it out? Even if it
@@ -4466,7 +4467,7 @@ Unless you get a good percentage of her price ...
%
Beat me, bite me, whip me, fuck me, make me write bad checks!
%
-Beauty, n:
+Beauty, n.:
The power by which a woman charms a lover and terrifies a husband.
-- Ambrose Bierce, "The Devil's Dictionary"
%
@@ -4489,7 +4490,7 @@ we are part of the women's liberation movement.
%
Bedfellows make strange politicians.
%
-beef stroganoff, n:
+Beef stroganoff, n.:
A bull masturbating.
%
Behold the unborn fetus and
@@ -4631,7 +4632,7 @@ campus by another religious organization, and the system was first used on
Brother Jim, who suffered a broken rib and numerous small bruises, in
addition to the usual humiliation.
%
-brunette bush, n:
+Brunette bush, n.:
The dark side of the moon.
%
Buffy: Am I repulsive? If there was something repulsive about me, you'd
@@ -4662,7 +4663,7 @@ Xander: Yay.
-- Buffy the Vampire Slayer, "The Prom"
Season 3, Episode 20
%
-bug, n:
+Bug, n.:
A son of a glitch.
%
Build a better mousetrap, the saying goes -- and with the brassiere,
@@ -4709,7 +4710,7 @@ California is proud to be the home of the freeway.
%
Call for Ms. Lingus, Ms. Connie Lingus...
%
-callgirl, n:
+Callgirl, n.:
A negotiable blond.
%
Camille's Axiom:
@@ -4877,7 +4878,7 @@ G's Third Law:
is composed of only two basic substances: magic and bullshit.
H's Dictum:
- There is no magic....
+ There is no magic...
%
Claude believed that only smart attractive people had the right to
fuck, and it sincerely hurt him when he discovered evidence to the
@@ -4886,7 +4887,7 @@ contrary.
%
Cleveland still lives. God MUST be dead.
%
-clitoris, n:
+Clitoris, n.:
A haired trigger.
%
CLONE OF MY OWN (to Home on the Range)
@@ -4921,7 +4922,7 @@ Cocaine: using tomorrow's energy today.
Cocaine's a joke!
(Who's got the next line?)
%
-cock-sucker, n:
+Cock-sucker, n.:
Someone who got caught doing what you got away with.
%
Coffee without caffeine. Beer without alcohol. Milk without fat.
@@ -4930,7 +4931,7 @@ What's next? Bridal suites with bunk beds?
%
Coito ergo sum
%
-coitus interruptus, n:
+Coitus interruptus, n.:
A jerky movement following the words (by either sex partner)
"I want to have your child."
%
@@ -4948,15 +4949,12 @@ And eliminates all the palaver.
COLD:
When the local flashers are handing out written descriptions.
%
-cold, adj:
+Cold, adj.:
When your dog sticks to the fire hydrant.
%
College is like a woman -- you work so hard to get in, and nine months
later you wish you'd never come.
%
-College is like a woman -- you work so hard to get in,
-and nine months later you wish you'd never come.
-%
Come along and sing a song and join our family.
B & D
S & M
@@ -5005,7 +5003,7 @@ Communists do it without class.
%
Computer scientists are programmed to do it by macro insertion.
%
-computerfirm nymphomaniac, n:
+Computerfirm nymphomaniac, n.:
Hot Apple pie.
%
Condoms are like listening to a symphony with cotton in your ears.
@@ -5078,7 +5076,7 @@ BEDLAM:
CHAOS:
Four women plus one luncheon check.
%
-confusion, n:
+Confusion, n.:
Father's Day in San Francisco.
%
Conservative, n.:
@@ -5090,10 +5088,10 @@ Conserve energy -- make love more slowly.
CONSULTANT:
Someone who knows 101 ways to make love, but can't get a date.
%
-continental breakfast, n:
+Continental breakfast, n.:
A roll in bed with some honey.
%
-Coors, n:
+Coors, n.:
Like making love in a canoe -- fucking close to water.
%
Copa-ulation:
@@ -5135,14 +5133,14 @@ If you're not going to sack it, go home and wack it.
Cox's philosophy:
Life's a bitch, then you die.
%
-coyote love, n:
+Coyote love, n.:
Coyote love is a nebulous term. Basically, what it involves is
the taking of a member of the preferred sex home from a singles
bar. Then, when you wake up the next morning, they're sleeping
on your arm. So, rather than wake them up as you escape, you
chew off your arm at the shoulder.
-coyote ugly, adj:
+Coyote ugly, adj.:
When you chew off the other arm 'cause she'll be looking for
a one-armed man!
@@ -5159,7 +5157,7 @@ to a doctrine not only known to be false, but calculated to undermine any
general understanding of science as an enterprise?
-- Stephen Jay Gould, "The Skeptical Inquirer"
%
-crew, n:
+Crew, n.:
Eight big men and their cute little cox.
%
Cried Miss Pratt: "What are you staring at?
@@ -5247,7 +5245,7 @@ Dear Abby:
I just met the most terrific girl and we get along fabulously. I
think she's the one for me. There's just one problem: I can't remember
from our first date if she told me she had TB or VD. What should I do?
- --Confused
+ -- Confused
Dear Confused:
If she coughs, fuck her.
@@ -5329,10 +5327,10 @@ of her husband with his penis inside the pencil sharpener on the counter.
%
Dial 911. Make a cop come.
%
-diaphragm, n:
+Diaphragm, n.:
A childproof cap.
%
-dicker, v:
+Dicker, v.:
What you do to your wife if arguing doesn't work.
%
Did Detroit invent the back seat to destroy the morals of America?
@@ -5410,7 +5408,7 @@ UP PERISCOPE!!!
(Ooops, sorry, wrong fantasy.)
%
-divorce, n:
+Divorce, n.:
A change of wife.
%
Do infants have as much fun in infancy as adults do in adultery?
@@ -5439,7 +5437,7 @@ very good; and when it is bad, it is better than nothing.
-- Dick Brandon
%
Does he treat your breasts like unripe grapefruit? Who needs him?
- -- `J', "The Sensuous Woman"
+ -- J, "The Sensuous Woman"
%
Does it rape elephants?
-- Brent Byer
@@ -5518,7 +5516,7 @@ say, and when he was done, grinned broadly and replied, 'Eat it raw, fuzz
nuts.'"
-- "The Churchill Wit", National Lampoon
%
-dyke, n:
+Dyke, n.:
A woman who kick-starts her vibrator. And rolls her own
tampons.
%
@@ -5572,7 +5570,7 @@ Eleven reasons a cucumber is better than a man:
(11) With a cucumber, the toilet seat is always the way you
left it.
%
-embarrassment, n:
+Embarrassment, n.:
Finding out your German Shepherd has the clap.
%
Equality is not when a female Einstein gets promoted to assistant
@@ -5580,7 +5578,7 @@ professor; equality is when a female schlemiel moves ahead as fast as a
male schlemiel.
-- Ewald Nyquist
%
-Erogenous zone, n:
+Erogenous zone, n.:
The skin you touch to love.
%
Es giebt ein Arbeiter von Tinz,
@@ -5589,7 +5587,7 @@ Er schlaft mit ein Madel von Linz.
Ich hore Mann kommen."
"Jacht, jacht," sagt der Plummer, "Ich binz."
%
-eternity, n:
+Eternity, n.:
The length of time between when you come and he leaves.
%
Ethnologists up with the Sioux
@@ -5680,7 +5678,7 @@ do with ones time. Like lie in the sun and sleep. Or go exploring the world.
Except for 75% of the women, everyone in the whole world wants to have sex.
-- Ellyn Mustard
%
-exotic dancer, n:
+Exotic dancer, n.:
A girl who brings home the bacon a strip at a time.
%
Exuberant Sue from Anjou
@@ -5694,7 +5692,7 @@ Buffy: It didn't suck.
-- Buffy the Vampire Slayer, "Bad Girls"
Season 3, Episode 14
%
-falsie salesman, n:
+Falsie salesman, n.:
Fuller bust man.
%
Famous last words:
@@ -5729,17 +5727,17 @@ Shrieks and screams were heard from Grandma
He had chased her up a tree!
(chorus)
%
-felt tip, v:
+Felt tip, v.:
Past tense for a breast examination!
%
Female ballet dancers are the bravest girls around. Who else would take a
flying leap into the arms of a homosexual and expect to be caught?
-- Rita Rudner
%
-female, n:
+Female, n.:
Life support system for a pussy.
%
-Feminism, n:
+Feminism, n.:
A political position which seeks to rebuild society so that
both men and women are treated as women wish to be treated.
%
@@ -5801,7 +5799,7 @@ He's so neat, he's so cool,
Walks across my swimming pool.
Has anybody...
%
-Flirt, n:
+Flirt, n.:
A girl whose favorite man is the next one.
%
Floating idly one day through the air,
@@ -5844,7 +5842,7 @@ to the heads of unfaithful men. I brought forth destruction and chaos
for the pleasure of the lower beings. I was feared and worshiped across
the mortal globe. And now I'm stuck at Sunnydale High. A mortal.
A child ... and I'm flunking math.
- -- Anya, Buffy the Vampire Slayer, "Dopplegangland"
+ -- Anya, Buffy the Vampire Slayer, "Doppelgangland"
Season 3, Episode 16
%
For a young man, not yet: for an old man, never at all.
@@ -6130,13 +6128,13 @@ It satisfies a normal need. -- I like it.
It turns your spine to fucking jell,
It damns your soul to Eternal Hell! -- I like it.
%
-fuck-me-pumps, n:
+Fuck-me pumps, n.:
Stiletto heels of a certain length, usually black patent leather.
The proper designation is "throw-me-down-and-fuck-me" pumps. Shoes with
heels just high enough to let the frayed tip of a bullwhip trail around
them properly.
%
-fuckoff, n:
+Fuckoff, n.:
The tie breaker at the Miss America Beauty Pageant.
%
Gardeners do it in raised beds.
@@ -6198,7 +6196,7 @@ I'm too hot, too hot for you. I'm the queen of babes supreme,
But you'll only see me in you dreams.
"Well? What'd she say??" I'm too hot, too hot for you.
"Well, she didn't say no..."
- -- Barry and the Bookbinders, "The Worst She Can Say is No"
+ -- Barry and the Bookbinders, "The Worst She Can Say is No"
%
GET OFF THE FUCKING SYSTEM THIS INSTANT, YOU ASSHOLE!!!!
%
@@ -6428,7 +6426,7 @@ or they will stick you in the dock,
and you won't come back.
-- Monty Python, "The Meaning of Life"
%
-good scout, n:
+Good scout, n.:
Someone who knows the lay of the land and will take you to her.
%
Gorbachev woke up early one morning, and felt great. He walked over to his
@@ -6475,7 +6473,7 @@ Gross, adj.:
When your grandmother kisses you goodnight and
slips you some tongue.
%
-Gynecologist, n:
+Gynecologist, n.:
Someone who spends their time spreading old wives' tails.
%
HACKER:
@@ -6498,7 +6496,7 @@ Haggis, n.:
considered by them to be not only a delicacy but fit for human
consumption. The minced heart, liver and lungs of a sheep, calf or
other animal are mixed with oatmeal, sealed and boiled in maw in the sheep's
-intestinal stomach-bag and ... Excuse me a minute....
+intestinal stomach-bag and ... Excuse me a minute ...
%
Half the posts to this group are about masturbation and the other half
are about penis size. And what I want to know is, if all you're doing
@@ -6519,7 +6517,7 @@ Handy hint:
%
Hang gliders come down very slowly.
%
-Hangover, n:
+Hangover, n.:
The burden of proof.
%
HAPPINESS:
@@ -7146,7 +7144,7 @@ And when he did, he dropped stone dead,
'Cause the blasted thing had a left-hand thread!
%
Here's the holiday schedule for Monday's observation of Martin Luther
-King Jr.'s birthday, when the following will be closed:
+King, Jr.'s birthday, when the following will be closed:
* Governmental offices
* Post offices
@@ -7269,7 +7267,7 @@ in jeopardy, why, I'd never have lit one!
HONOR:
Almost as good as in 'er.
%
-horny, adj:
+Horny, adj.:
When your cock gets hard if the wind blows.
%
Horsecrap, little brother. There's always something more to be done.
@@ -7323,13 +7321,13 @@ bush, shoot more often and *always* eat what they shoot.
%
Hypocrisy is the Vaseline of social intercourse.
%
-hypocrite, n:
+Hypocrite, n.:
A man who says he likes cats, but won't eat pussy.
%
I am an atheist, thank God!
%
I believe that Ronald Reagan will someday make this country what it
-once was ... an arctic wilderness
+once was ... an arctic wilderness.
-- Steve Martin
%
I bet you think you're pretty cool driving around without auto insurance.
@@ -7350,7 +7348,7 @@ I've reached the point where I might do *anything* to stop the war. We'll
just slip the word to them that "For God's sake, you know, Nixon is obsessed
about Communism. We can't restrain him when he's angry -- and he has his
hand on the nuclear button."
- -- Richard Nixon
+ -- Richard M. Nixon
%
I came; I saw; I fucked up.
%
@@ -7406,13 +7404,12 @@ I don't care who you are, Fatso. Get those reindeer off my roof.
%
I don't discriminate on the basis of sex.
-- Bisexuality, 101
-
[An equal opportunity lover? Ed.]
%
I don't give a shit what happens. I want you all to stonewall it. Let
them plead the Fifth Amendment, cover up, or anything else if it'll save
the plan.
- -- Richard Nixon
+ -- Richard M. Nixon
%
I don't know why women get so upset, they have half the
money and all the pussy.
@@ -7530,7 +7527,7 @@ By the tricks that he makes his foreskin do.
%
I know what you're up to, you white-feathered fiend!
Go release your bowels on some lesser personage!
- -- W.C. Fields, upon seeing a bird overhead
+ -- W. C. Fields, upon seeing a bird overhead
%
I know why the sun never sets on the British Empire -- God wouldn't trust
an Englishman in the dark.
@@ -7589,7 +7586,6 @@ But I'm already stewed, screwed, and tattooed."
%
I only date queers.
-- Bisexuality, 101
-
[I'm not queer, but my boyfriend is! Ed.]
%
I own my own body, but I share.
@@ -7672,7 +7668,7 @@ I was 15 years old before I found out that "damn yankee" was two words.
%
I was a cock-teaser at Rooster Rama.
I used to enrage the bantams before the big bouts.
- -- Firesign Theatre
+ -- The Firesign Theatre
%
I was having sex just the other night, but she hung up.
%
@@ -7680,12 +7676,12 @@ I was on vacation in Greece last summer, and was being driven round an island
by a Greek cab-driver. He was a friendly man, and as we drove, he told me
about various historic and scenic places he had been involved with.
"See the entrance to that church over there? I built that with my
-two sons. But do they call me `Dimitri the church builder'? Do they hell!"
+two sons. But do they call me `Dimitri the church builder?' Do they hell!"
As we passed a dam, he said, "See that dam? Four of us built that
dam by ourselves! But do they call me `Dimitri the dam builder?' Hell, no!"
As we passed a beautiful cottage, Dimitri started up again -- "See
that house? I built that for my wife with my own two hands! But do they
-call me `Dimitri the home builder'? No! But just one little sheep!"
+call me `Dimitri the home builder?' No! But just one little sheep!"
%
I went to a wild party last night. I tell ya, it was so wild, we played
a new version of Russian roulette. We passed around six girls and one
@@ -7949,7 +7945,7 @@ Will be hailed by all as miraculous!
%
If you're a real good kid, I'll give you a piggy-back ride on a
buzz-saw.
- -- W.C. Fields
+ -- W. C. Fields
%
If you're Catholic you've only got two choices: periodic
abstinence and complete continence; (you know, rhythm and blues).
@@ -8082,10 +8078,10 @@ girlfriend's name. Yeah, I went down to the hall of records. I said, "I'd
like to change it... I'd like to change it to... LYING LITTLE BITCH!"
-- Sam Kinison
%
-I'm unbuttoning your shirt, unzipping your jeans....
+I'm unbuttoning your shirt, unzipping your jeans ...
Oh, I can feel your fingers on the keys, baby,
- I'm getting WARM....
+ I'm getting WARM ...
I am getting there, oh yes,. Oh, my. OH YES... OHHHH!
...!!!rrrrrgh!!!!!
@@ -8110,7 +8106,7 @@ Yes, Socrates, himself, is particularly missed;
A lovely little thinker but a bugger when he's pissed!
-- Monty Python, "The Philosopher's Drinking Song"
%
-impotent loser, n:
+Impotent loser, n.:
Someone who can't even get his hopes up.
%
In 1953, Stalin dies. The politburo holds a special meeting to decide
@@ -8141,7 +8137,7 @@ Legette Hair Fastener Heat Bags; Lady O' Spain Self-Blinding Eye Shadow
with Magic Puncture Pencil; Sanitary Napkin Rings in Little Miss, Moon
Maid and Stuck Pig Strength; and deported Italian Napagel Balls for
soaking or eating; and they're all slash-priced with the lady in mind...
- -- Firesign Theatre
+ -- The Firesign Theatre
%
In days of old, when knights were bold,
And rubbers weren't invented,
@@ -8186,7 +8182,7 @@ And in peaceful submission I lay,
My sweet little night gown of blue.
%
In my world, there are people in chains and we can ride them like ponies.
- -- Evil Willow, Buffy the Vampire Slayer, "Dopplegangland"
+ -- Evil Willow, Buffy the Vampire Slayer, "Doppelgangland"
Season 3, Episode 16
%
In outer space, nobody can hear you fart.
@@ -8242,7 +8238,7 @@ kissing him on the balls.
Incest, n.:
Sibling revelry; a sport the whole family can enjoy.
%
-Infatuation, n:
+Infatuation, n.:
When you're in love, there's a lump in your throat.
When you're infatuated, there's a lump in your pants.
%
@@ -8265,8 +8261,8 @@ Re: S. White
Let it be noted that if she whistles that goddamned song one
more time I'm gonna rip her fuckin' lips off. Have a nice day.
%
-Is it just me, or does anyone else read `bible humpers' every time
-someone writes `bible thumpers?'
+Is it just me, or does anyone else read "bible humpers" every time
+someone writes "bible thumpers?"
-- Joel M. Snyder, jms@mis.arizona.edu
%
Isn't it odd that people who object to "foul" language are always the
@@ -8791,14 +8787,14 @@ Knowledge Engineering:
A combination of:
-Engineering, n:
+Engineering, n.:
The application of science and mathematics by which the properties
of matter and the sources of energy in nature are made useful to man in
structures, machines, products, systems and processes.
and
-Knowledge, n:
+Knowledge, n.:
Sexual intercourse.
See also: Prostitution, Grantsmanship.
@@ -8822,10 +8818,10 @@ left a deep impression on him -- about how faithfully animals respond to
intention movements, that is.
-- The Sciences, May/June, 1988, N.Y. Academy of Science
%
-Kotex, n:
+Kotex, n.:
Not the best thing on earth, but next to the best.
%
-Kumquat, n:
+Kumquat, n.:
Any of several small citrus fruits with sweet spongy rind and
somewhat acidic pulp that are used chiefly for preserves.
Extremely popular in some forms of sexual intercourse. In fact,
@@ -8836,7 +8832,7 @@ Kumquat, n:
Note: this is *not* to be confused with a warning from your
partner that his/her parents are upstairs and probably awake.
%
-Labia majora, n:
+Labia majora, n.:
The curly gates.
%
Lady to Golf Pro: "I was stung by bees on your golf course!"
@@ -8844,7 +8840,7 @@ Pro: "Ummm, well, where?"
Lady: "Between the 1st and 2nd holes."
Pro: "That's going to real tough to treat."
%
-lagnaf, n:
+Lagnaf, n.:
Let's All Get Naked And Fuck!
%
Laissez Faire Economics is the theory that if each acts like a vulture,
@@ -8860,7 +8856,7 @@ I was screwed, if you must know the truth."
%
Last week I saw a girl in a sweater so tight I could hardly breathe.
%
-lawyer, n:
+Lawyer, n.:
Someone who can get a sodomy charge changed to "following too
closely."
%
@@ -8968,7 +8964,7 @@ Lisp hackers
... have DEFUN while doing it.
... have Moby dicks.
%
-Lisp hackers have to be bound (to-do 'it)....
+Lisp hackers have to be bound (to-do 'it) ...
%
Lisp programmers do it deeper and deeper and deeper.
%
@@ -9069,7 +9065,7 @@ was because they wanted to make sure he was dead.
-- Samuel Goldwyn
%
Love comes in spurts.
- --Devo, "Please Please"
+ -- Devo, "Please Please"
%
Love does not make the world go around, just up and down a bit.
%
@@ -9091,18 +9087,18 @@ Love letters no longer they write us,
To their homes they so seldom invite us.
It grieves me to say,
They have learned with dismay,
-We can't cure their `vulva pruritus'.
+We can't cure their "vulva pruritus."
%
-Luser, n:
+Luser, n.:
Someone who picks up a female
hitch-hiker walking home from a date.
%
Ma Bell runs a baudy house.
%
-Macho, adj:
+Macho, adj.:
Jogging home from a vasectomy.
%
-Male, n:
+Male, n.:
Life support system for a cock.
%
Man in stall:
@@ -9207,10 +9203,10 @@ Just look up Mary's ...
Masturbation! The amazing availability of it!
-- James Joyce
%
-masturbation, n:
+Masturbation, n.:
A self-service elevator.
%
-masturbation, n:
+Masturbation, n.:
Coming unscrewed.
%
Math is to physics like masturbation is to sex.
@@ -9239,11 +9235,6 @@ May the fairy god-camel leave a lump on your pillow!
Maybe if the guy who developed Twinkies hadn't had such a low
opinion of himself they would have been an inch or two longer!
%
-Mayor Vincent J. `Buddy' Cianci on the ACLU's suit to have a city
-nativity scene removed:
- "They're just jealous because they don't have three wise men
-and a virgin in the whole organization."
-%
McCoy's a seducer galore,
And of virgins he has quite a score.
He tells them, "My dear,
@@ -9258,7 +9249,7 @@ McQuillan was on the stand. The case involved a railroad and several of
the passengers who were injured.
"You say," thundered the counsel for the railroad, "that you saw
the two trains crash head on while doing sixty miles an hour. What did you
-think when you saw this happen ?"
+think when you saw this happen?"
"I thought," replied the Irishman, "this is one *helluva* way to run
a railroad."
%
@@ -9318,7 +9309,7 @@ Everything they say,
Men will fuck mud.
-- Lenny Bruce
%
-menage a trois, n:
+Menage a trois, n.:
Using both hands to masturbate.
%
Men's magazines often feature pictures of naked ladies. Women's magazines
@@ -9346,7 +9337,7 @@ views, are constantly being shoved out the window head first, without so
much as a pension plan, by younger hotshot cells moving up from below.
-- Dave Barry
%
-Meteorologist, n:
+Meteorologist, n.:
A man who can look in a woman's eyes and predict whether.
%
Mickey Mouse has a long talk one day with a psychiatrist, after which
@@ -9385,10 +9376,10 @@ How does your garden grow?
With silver bells and cockle shells,
And one really fucked-up petunia.
%
-Mistress, n:
+Mistress, n.:
Something between a mister and a mattress.
%
-mixed emotions:
+Mixed emotions:
Watching your mother-in-law back off a cliff...
in your brand new Mercedes.
%
@@ -9581,19 +9572,19 @@ seems he's making it hard for everyone but her.
%
National Sex Week -- don't let your meat loaf.
%
-navel, n:
+Navel, n.:
A place to stash your gum on the way down.
%
Necessity is the mother of strange bedfellows.
Watch who you sleep with.
%
-necrophilia, n:
+Necrophilia, n.:
Dead boring.
-incest, n:
+Incest, n.:
Relatively boring.
%
-necrophilia, n:
+Necrophilia, n.:
Dropping in for a cold one.
%
Negotiate my ass, let's kill something!
@@ -9679,7 +9670,7 @@ Not everyone has a one-track mind.
Not only is God dead, but just try to find a plumber on weekends.
-- Woody Allen
%
-nothing, adj:
+Nothing, adj.:
A man with an erection who walks into a wall and breaks his nose.
%
Nothing is better than Sex.
@@ -10352,7 +10343,7 @@ OPTIMIST:
ORAL CONTRACEPTIVE:
The word "No".
%
-oral sex, n:
+Oral sex, n.:
The taste of things to come.
%
O'Riordan's Theorem:
@@ -10384,7 +10375,7 @@ national emergency... Always there has been some terrible evil to
gobble us up if we did not blindly rally behind it by furnishing the
exorbitant sums demanded. Yet, in retrospect, these disasters seem
never to have happened, seem never to have been quite real.
- -- General Douglas MacArthur, 1957
+ -- General Douglas MacArthur (1957)
%
Our readers ask, "Why don't more WASPs go to orgies?" Well, it's really
quite simple. They don't want to have to write all those thank-you notes.
@@ -10446,7 +10437,7 @@ the bill at the XXX South Trail Cinema featured:
+ Turn Up the Heat, starring Savannah
+ Tiger Shark, starring Raven
%
-penis envy, n:
+Penis envy, n.:
The desire to be pink and wrinkled and about four inches long.
%
People humiliating a salami!
@@ -10473,7 +10464,7 @@ When her summer turned out quite a bummer!
%
Persistence, like perspiration, is 99 percent of the fine art of love.
%
-Philadelphia flying fuck, n:
+Philadelphia flying fuck, n.:
Okay, see, he hangs from a chin-up bar with his feet on the arms
of the rocking chair. She crouches in the rocking chair pleasuring
him orally.
@@ -10490,7 +10481,7 @@ Physicists do it with charm.
Picking up a man in a bar is like a snowstorm, you never know when
he's coming, how many inches you'll get or how long he'll stay.
%
-pile driver, n:
+Pile driver, n.:
Local drink; two parts vodka, one part prune juice.
%
Planned Parenthood:
@@ -10510,11 +10501,11 @@ If you do the things we say, then you'll soon rule the nation.
Kill your foes and enemies and then kill your relations.
Pillage, rape, and loot and burn, but all in moderation.
%
-pocket pool, n:
+Pocket pool, n.:
Well, for guys, it's two-ball in the side pocket.
For women, it's playing the slots.
%
-polish fly, n:
+Polish fly, n.:
You put it in her drink and she begs you to take her bowling.
%
Politicians do it to everyone.
@@ -10574,10 +10565,10 @@ Pregnancy -- the worst sexually transmitted disease of them all.
%
Pregnancy begins with a single sell.
%
-premature ejaculation, n:
+Premature ejaculation, n.:
A spoilspurt.
%
-premature ejaculator, n:
+Premature ejaculator, n.:
Troubled shooter.
%
Premenstrual Syndrome:
@@ -10625,7 +10616,7 @@ both promise to make people feel better, but the prostitute doesn't
make pretensions that the feelings will last once the client walks
out the door.
%
-pubic hair, n:
+Pubic hair, n.:
Organic dental floss.
%
Puff the Jewish dragon lived in Palestine,
@@ -10715,7 +10706,7 @@ A: You stand around in a circle and blaspheme and see who gets struck
%
Q: How do you tell if an elephant has been making love in your
backyard?
-A: If all your trashcan liners are missing....
+A: If all your trashcan liners are missing ...
%
Q: How do you tell if you're making love to a nurse, a schoolteacher,
or an airline stewardess?
@@ -11087,7 +11078,7 @@ Q: Why do Scotsmen wear kilts?
A: Because a sheep can hear the sound of a zipper from fifty feet away.
-- Iain MacKintosh, Glasgow folksinger
%
-Q: Why do WASPs play golf ?
+Q: Why do WASPs play golf?
A: So they can dress like pimps.
%
Q: Why do women have vaginas?
@@ -11267,10 +11258,10 @@ weighing the odds of a slander suit. Mayor Koch could naturally be
reached for comment, but we chose not to listen.
-- Dennis Miller, "Saturday Night Live"
%
-quickie, n:
+Quickie, n.:
A moment's piece.
%
-quickie, n:
+Quickie, n.:
No sooner spread than done.
%
QWERT (kwirt) n. [MW < OW qwertyuiop, a thirteenth] 1. a unit of weight
@@ -11287,7 +11278,7 @@ Lisa: Ralph... get off my back!!
Randel, n.:
A nonsensical poem recited by Irish schoolboys as an apology
for farting at a friend.
- -- Mrs. Byrne's Dictionary of Unusual, Obscure &
+ -- Mrs. Byrne's Dictionary of Unusual, Obscure, and
Preposterous Words
%
Raquel Welch: 36-24-36
@@ -11329,19 +11320,19 @@ you'll never have to worry about those damn bats pestering the neighbors again.
%
Reagan can't _a_c_t, either.
%
-real buddy, n:
+Real buddy, n.:
Someone who'll go downtown and get two blowjobs, and come back
and give you one.
%
-real class, adj:
+Real class, adj.:
When you're by yourself, fart, and say "Excuse me."
%
Real fur: the ultimate sadist symbol.
%
-Reformed, n:
+Reformed, n.:
A synagogue that closes for the Jewish holidays.
%
-rejection, n:
+Rejection, n.:
When you're masturbating and your hand falls asleep.
%
Religion is fine, Churchianity sucks.
@@ -11395,7 +11386,7 @@ phone number!"
Revenge is sleeping with your enemy's wife.
Sweet revenge is the realization that she's a lousy lay.
%
-rodeo fuck, n:
+Rodeo fuck, n.:
When you lean down and whisper in your lover's ear, "Honey, you're
the worst piece of ass I've ever had!". And then try to stay on
for seven seconds...
@@ -11435,7 +11426,7 @@ Roumanian-Yiddish cooking has killed more Jews than Hitler.
%
Rugby is a game played by men with peculiarly shaped balls.
%
-rugby, n:
+Rugby, n.:
A sport requiring leather balls.
%
Rumour has it that the intrepid New Zealanders have finally discovered
@@ -11745,7 +11736,7 @@ Let _P be a constant persuasion;
"Let _V over _P be inverted
With the square root of _M_u inserted
- _N times into _V....
+ _N times into _V ...
The result, Q.E.D.,
Is a relative!" Einstein asserted.
%
@@ -11936,7 +11927,7 @@ production, protects a bunch of pricks and gives everyone a false sense of
security while they're being screwed.
%
Self-abuse is the most certain road to the grave.
- -- Dr. George M. Calhoun, 1855
+ -- Dr. George M. Calhoun (1855)
%
SEMINARS:
From 'semi' and 'arse', hence, any half-assed discussion.
@@ -11957,7 +11948,7 @@ The shit has hit the fan.
-- Warren Zevon
%
Sensible and responsible women do not want to vote.
- -- Grover Cleveland, 1905
+ -- Grover Cleveland (1905)
%
Sex and drugs and UNIX.
%
@@ -11996,7 +11987,7 @@ are unimportant.
-- Henry Miller
%
Sex is the poor man's opera.
- -- G. B. Shaw
+ -- George Bernard Shaw
%
Sex is what women have and men want.
%
@@ -12177,7 +12168,7 @@ Sixteen'll get you twenty.
%
Size counts.
%
-small, adj:
+Small, adj.:
Is it in yet?
%
Smoking a woman is like kissing a fish.
@@ -12313,7 +12304,7 @@ Some women achieve greatness, some have greatness thrust into them.
%
Some women are like musical glasses.
To keep them in tune they must be wet.
- -- Samuel Coleridge
+ -- Samuel T. Coleridge
%
Some women should be beaten regularly, like gongs.
-- Noel Coward
@@ -12376,7 +12367,7 @@ Stockmayer's Theorem:
STRAPLESS EVENING GOWN:
Bust truster.
%
-stress, n:
+Stress, n.:
The confusion created when one's mind overrides the body's
desire to choke the living shit out of some asshole who
desperately needs it.
@@ -12390,7 +12381,7 @@ Success has many fathers, but failure is a bastard.
Success is like a fart -- only your own smells nice.
-- James P. Hogan
%
-successful cunnilingus:
+Successful cunnilingus, n.:
When you wake up the next morning with a face like a
frosted doughnut.
%
@@ -12418,7 +12409,7 @@ you'll eat that stuff, you'll eat anything.
Sure, Reagan has promised to take senility tests. But what if he
forgets?
%
-swallow, v:
+Swallow, v.:
The (blew) bird of birth control.
%
Systems people do it with a small, but clean, interface.
@@ -12461,11 +12452,11 @@ Teaching undergraduates is like herding sheep. And, like the old Basque
sheepherder explained, whenever the livestock starts looking good to you,
it's time to spend a night in town.
%
-tear leather:
+Tear leather:
To become excited, as in the sentence "Robin Hood tore
his leather jerkin' off."
%
-tearing off a quicky:
+Tearing off a quicky:
Gunning the jump.
%
Teddy Kennedy: A Blond in Every Pond!
@@ -12875,11 +12866,6 @@ the older woman pleaded. Reluctantly, he agreed.
"I knew my daughter would have an explanation," she said, a note of triumph
in her voice. "She didn't receive your telegram!"
%
-The Italian entry in the Eurovision Song Contest, "I Can't Get No
-Contraception", has been withdrawn after the Pope advised them to
-pull it out at the last minute.
- -- Not the Nine O'Clock News
-%
The investment community feels very putupon. They feel there is no
reason why they shouldn't earn $1 million to $200 million a year,
and they don't want to be held responsible for the global financial
@@ -12888,6 +12874,11 @@ meltdown.
Barack Obama's financial-industry fundraising party
20 October 2009
%
+The Italian entry in the Eurovision Song Contest, "I Can't Get No
+Contraception", has been withdrawn after the Pope advised them to
+pull it out at the last minute.
+ -- Not the Nine O'Clock News
+%
The king arranged a regal marriage for his daughter -- a bond that would unite
two great kingdoms. Yet, because the young couple seemed so formal to each
other, he posted a spy outside the royal wedding chamber and demanded a full
@@ -13205,7 +13196,7 @@ prohibitive, and the position ridiculous.
-- Disraeli, on sex
%
The plural of spouse is spice.
- -- R.A. Heinlein
+ -- Robert A. Heinlein
%
The police were investigating the mysterious death of a prominent businessman
who had jumped from a window of his 11th story office. His voluptuous private
@@ -13557,7 +13548,7 @@ But had dribbled away all too soon.
%
The woman you buy -- and she is the least expensive -- takes a great
deal of money. The woman who gives herself takes all your time.
- -- Balzac
+ -- Honore de Balzac
%
The word "spine" is, of course, an anagram of "penis". This is true in
almost fifty percent of the languages of the Galaxy, and many people
@@ -13643,7 +13634,7 @@ There are a couple of things about her I greatly admire.
There are also a lot of nice buildings in Haiphong. What their
contributions are to the war effort I don't know, but the desire to
bomb a virgin building is terrific.
- -- Commander Henry Urban Jr.
+ -- Commander Henry Urban, Jr.
%
There are Jews in the world, there are Buddhists, Every sperm is sacred,
there are Hindus and Mormons and then Every sperm is great,
@@ -13935,6 +13926,11 @@ mind raced with fear "Will it stop?". Exhausted, he lay down beside her.
burned as he stared for what seemed an eternity. Finally, his father spoke.
"Son, you ain't supposed to milk the damn cow till mornin'!"
%
+They're just jealous because they don't have three
+wise men and a virgin in the whole organization.
+ -- Mayor Vincent J. "Buddy" Cianci, on the
+ ACLU's suit to have a city nativity scene removed.
+%
This Czech walks into police station in 1968 during the Fraternal Assistance.
Czech: Hey, out there in the street, a Swiss soldier knocked me down and
took my Russian watch.
@@ -14035,7 +14031,7 @@ This limerick is **SO**FILTHY** that it would offend you. So I'll put
Di-dah, di-dah, di-dah di-dah,
Di-dah di-dah di-dah, di-dah;
- di-dah di-dah di-dah?
+ Di-dah di-dah di-dah?
Di-dah di-dah di-dah.
Di-dah di-dah, di-dah di-fuck.
%
@@ -14129,12 +14125,12 @@ the second woman.
"Frankly," murmured the third woman, "I understand the situation,
but I fail to see the problem."
%
-three-bag ugly, adj:
+Three-bag ugly, adj.:
That's when you put one bag over her head, one bag over your
head in case her's falls off, and one over the dog's to keep
it from howling.
-four-bag ugly, adj:
+Four-bag ugly, adj.:
When you leave a bag by the door in case someone drops by.
%
Through a major bureaucratic error, you are made county coroner.
@@ -14174,19 +14170,19 @@ Todays title:
Tonight's piss is tomorrow's Tang.
-- An American astronaut
%
-tourist, n:
+Tourist, n.:
A pretty girl in Oklahoma.
%
Tourist to New Yorker:
"Pardon me, sir, do you know what time it is, or should I
just go fuck myself?"
%
-transvestite, n:
+Transvestite, n.:
Someone who likes to eat, drink, and be Mary.
%
Tri Delts; everyone else has.
%
-trust me:
+Trust me:
Los Angeles for "Fuck you, your mother, and the horse
she rode in on."
%
@@ -14529,10 +14525,10 @@ especially if special features and options are utilized.
vacation;look;find;talk;grep;touch;finger;find;flex;unzip;mount;workbone; \
fsck;yes;gasp;fsck;yes;eject;umount;make clean;zip;split;done;exit
%
-vagina, n:
+Vagina, n.:
The box a penis comes in.
%
-vaginal lubricant, n:
+Vaginal lubricant, n.:
A slitty slicker.
%
Vandalism On The Upswing!
@@ -14543,7 +14539,7 @@ Vandalism On The Upswing!
%
Vatican upholds ban on contraceptives: "To heir is humane," claims the Pope.
%
-Vd, n:
+VD, n.:
The gift that keeps on giving.
%
Vegetarians for oral sex -- "The only meat that's fit to eat"
@@ -14634,7 +14630,7 @@ I need someone to protect But I'm not waiting on a lady
-- Rolling Stones, "Waiting on a Friend"
%
Water? Never touch the stuff! Fish fuck in it.
- -- W.C. Fields
+ -- W. C. Fields
%
We ... make the modern error of dignifying the Individual. We do everything
we can to butter him up. We give him a name, assure him that he has certain
@@ -14993,7 +14989,7 @@ Giles: Controlled circumstances.
-- Buffy the Vampire Slayer, "Bad Girls"
Season 3, Episode 14
%
-wet dream, n:
+Wet dream, n.:
Overnight sensation.
%
We've all heard about the woman who married a Field Service engineer but
@@ -15133,7 +15129,7 @@ Stand up, cop's wife cried, don't take him down,
Rather be dead six feet in the ground.
When you come home, you can eat pork and beans,
I eats more chicken than any man's seen.
- -- Willie Dixon, "Backdoor Man", 1961
+ -- Willie Dixon, "Backdoor Man" (1961)
%
When God created man, She was only testing.
%
@@ -15167,7 +15163,7 @@ Give me a moron My father's out of Harvard
With talented hands My brother's out of Yale
I go bar-hopping Well the guy I took home last night
And they say "Last call" Just got out of jail
-I start shopping The way he grabbed and threw me
+I start shopping The way he grabbed and threw me
For a Neanderthal Oooo, it really got me hot
But the way he growled and bit me
The bigger they come I hoped he had his shots
@@ -15393,7 +15389,7 @@ Winning isn't everything, but losing really sucks.
With a bushel of apples, you can have
a hell of a time with the doctor's wife.
%
-wok, n:
+Wok, n.:
Something to thwow at a wabbit.
%
Woman is: finally screwing and your groin and buttocks and thighs ache like
@@ -15529,7 +15525,7 @@ You can't underestimate the power of fear.
%
You come out of a woman and you spend the rest of your life trying to
get back inside.
- -- Heathcote Williams
+ -- Heathcote Williams
%
You have been bitchy since Tuesday and you'll probably get fired today.
%
diff --git a/games/fortune/datfiles/fortunes.sp.ok b/games/fortune/datfiles/fortunes.sp.ok
index f26b5e3..2ba73ec 100644
--- a/games/fortune/datfiles/fortunes.sp.ok
+++ b/games/fortune/datfiles/fortunes.sp.ok
@@ -205,7 +205,6 @@ Astaire's
asterisked
Asterix
asthma's
-astonishment's
Astro
astrology
Astroturf
@@ -217,7 +216,7 @@ Attila
Auberon
Auden
AUDITME
-Audobon
+Audubon
Auerbach
Aug
Augier
@@ -326,7 +325,6 @@ Beatty
Beaumadine
Beaumarchais
Beauvoir
-becannt
Becker's
Beckett
Beckmann
@@ -550,7 +548,6 @@ Bruton
Brutus
Bruyere
Brylcreem
-Bryne's
Brynner
Bryson
BST
@@ -1020,9 +1017,7 @@ deppart
deregulated
dermis
DeSalvo
-DesCartes
Desiree
-dessicated
deStalinization
destitution
destructure
@@ -1159,7 +1154,6 @@ Dutsky
dwelleth
Dyer's
Dykes
-Dykstra
dyslexic
Dyson
Eagleson
@@ -1240,16 +1234,13 @@ endian
Enesco
Enfolding
England's
-Englebert
Englishman's
ENIACs
enkindles
Enm
Ennius
Ennui
-enobled
ENOTADUCK
-ensconsed
Epcot
Ephron
EPI
@@ -1547,7 +1538,6 @@ Garbers
Gardner's
garnishment
Garp
-Gastly
Gatling
Gaulle
Gauls
@@ -1580,7 +1570,6 @@ getchar
Getraenke
Gettys
gewerken
-Ghandi
gharsley
Ghostbusters
Giancana
@@ -1643,7 +1632,6 @@ Goebbels
goest
Goestheveezl
goeth
-Goethe's
Gold's
Golda
Goldengrove
@@ -1656,7 +1644,6 @@ Goldwyn
Goleta
Gomme's
Gondoliers
-Gondwondaland
gonna
Gonnet
goodbye
@@ -1670,7 +1657,6 @@ Gordon's
Gorey
Gorin
Gossling
-Gotama
Gotlieb
goto
goto's
@@ -2088,7 +2074,6 @@ IRS
Irulan
Isaak
Iso
-Issac
Issawi
Issawi's
Ist
@@ -2150,7 +2135,6 @@ joggers
Jogging
Johnson's
Johnston
-Jonathon
Jone's
Jones's
Jonesboro
@@ -2374,7 +2358,6 @@ Lapwarmer
Lardner
Larkin
Larkinson's
-LaRouchefoucauld
Lascl
laserbeam
Lasorda
@@ -2414,8 +2397,7 @@ Lehrer
Leia
Leibe
Leiber
-Leibnitz
-Leibowitz
+Leibniz
Leibowitz's
Leith
Lem
@@ -2428,7 +2410,6 @@ lerts
les
LeSage
letez
-Letterman's
Lettvin
Levant
Levenson
@@ -2827,7 +2808,6 @@ Moping
moralists
Mordecai
Mordor
-Morganstern
Morley
morons
Morrisey
@@ -2907,7 +2887,6 @@ nanocentury
nanohenry
nanometers
Nansen
-Napolean
Napoleon's
narcolepulacyi
Narnia
@@ -2930,7 +2909,6 @@ Neantical
Nebuchadnezzar
Nebuchadnezzar's
necesas
-necessitas
necessitious
NecroSoft
Nehru
@@ -2984,7 +2962,6 @@ Niven
Nixon's
Noah's
noalias
-Nobert
Noelie
nog
nogiftlist
@@ -3053,7 +3030,6 @@ OCP
Oct
octalthorpe
Octopussy
-Odgen
Oech
Oedipa
Ogborn
@@ -3172,7 +3148,7 @@ Parnas
Parnell
paroxysmally
Parrafin
-parthenon
+Parthenon
passwd
pastureland
Patageometry
@@ -3340,7 +3316,6 @@ PRL
PROCESSORs
Prochnow
proelium
-proferred
profundities
proletarian
Propos
@@ -3455,7 +3430,6 @@ Reichel's
Reinfeld
Reinhart
Reisner's
-reknowned
Relaxen
RENE
Renegades
@@ -3531,7 +3505,6 @@ Rosten
Rotherham
Rothesay
Rothschild
-Rouchefoucauld
Roumania
rousers
Rowlands
@@ -3653,7 +3626,7 @@ Schweitzer
Schwiggle
Schwine
Scientologist
-scintilate
+scintillate
Scintillae
Scott's
Scoville
@@ -3883,7 +3856,6 @@ Steinbach
Steinbach's
Steinbeck
Steinem
-Steinham
Steinman
Stekel
Stenderup's
@@ -3926,7 +3898,7 @@ Sugarcreek
Suggoth
Sulu
Sumeria
-Summatra
+Sumatra
sunbathing
SunCheckup
SUNKIST
@@ -3987,7 +3959,6 @@ Talking's
Tallulah
tamperest
Tanenbaum
-Tannenbaum
tannogallate
tapeworms
tapioca
@@ -4150,7 +4121,6 @@ TYDFS
tyg
typefaces
Tyroon
-tyrranize
tzu
Ubi
UDA
@@ -4168,7 +4138,6 @@ unamerican
unbegot
unbelievers
UNC
-Uncatylised
undemanding
underachiever
Unger
@@ -4273,7 +4242,7 @@ vodkas
Vogon
Vogons
voist
-Volkswagon
+Volkswagen
Vollyballocracy
Voltarine
von
@@ -4373,7 +4342,6 @@ whomped
Whooa
Whoopie
Wickersham
-wierdest
Wiggam
Wihelminalaan
Wiker's
@@ -4391,7 +4359,6 @@ Winchell
Windex
windstorms
Winfrey
-Winie
winnowed
Winny
Winokur
@@ -4423,7 +4390,6 @@ woodlands
Woodstock
Woodward's
Wookiee
-Woolcott
Woolf
Woollcott
worketh
@@ -4446,7 +4412,6 @@ Xaviera
XCVI
xen
xenophobic
-Xercies
XGP
XIIdigitation
XINU
diff --git a/games/fortune/datfiles/limerick b/games/fortune/datfiles/limerick
index 4852840..a0344a8 100644
--- a/games/fortune/datfiles/limerick
+++ b/games/fortune/datfiles/limerick
@@ -827,8 +827,8 @@ And such is the Kingdom of Heaven.
%
A pretty young lady named Vogel
Once sat herself down on a molehill.
- A curious mole
- Nosed into her hole --
+ A curious mole
+ Nosed into her hole --
Ms. Vogel's okay, but the mole's ill.
%
A pretty young maiden from France
@@ -854,7 +854,7 @@ Said, I'm the match for any machine.
My secret's aversion,
To loops and recursion,
Just acres of in-line routine.
- -- W.J. Wilson
+ -- W. J. Wilson
%
A progressive professor named Winners
Held classes each evening for sinners.
@@ -1097,7 +1097,7 @@ Reproached for not acting quite primly
I know sex isn't love,
But it's such an entrancing facsimile."
%
-A water pipe suited miss Hunt;
+A water pipe suited Miss Hunt;
She used it for many a bunt.
But the unlucky wench
Got it caught in her trench ---
@@ -2048,9 +2048,9 @@ Who canoed with a girl in Bermuder.
So McGru took an oar and subduder.
%
There once was a man named McSweeny
-Who spilled lots of gin on his weeney
- So just to be couth
- He added vermouth
+Who spilled lots of gin on his weeney.
+ So just to be couth,
+ He added vermouth,
And slipped his best girl a martini.
%
There once was a man named Parridge
@@ -2259,7 +2259,7 @@ There was a gay countess of Bray,
And you may think it odd when I say,
That in spite of high station,
Rank and education,
-She always spelled cunt with a 'k'.
+She always spelled cunt with a "k."
%
There was a gay dog from Ontario
Who fancied himself a Lothario.
@@ -2564,7 +2564,7 @@ There was a young fellow named Paul
Who confessed, "I have only one ball.
But the size of my prick
Is God's dirtiest trick,
-For my girls always ask, 'Is that all?'"
+For my girls always ask, `Is that all?'"
%
There was a young fellow named Pell
Who didn't like cunt very well.
@@ -3043,7 +3043,7 @@ Who strung himself up with a cord
Said he, of his work
(Ere the rope snapped with a jerk)
"I am leaving because I am bored."
- - E.A. Guest
+ -- E. A. Guest
%
There was a young lad named McFee
Who was stung in the balls by a bee
@@ -4423,7 +4423,7 @@ Who was stung in the arm by a wasp.
When asked, "Does it hurt?"
He replied, "No, it doesn't.
I'm so glad that it wasn't a hornet."
- -- W.S. Gilbert
+ -- W. S. Gilbert
%
There was an old man of Tagore
Whose tool was a yard long or more,
diff --git a/games/fortune/datfiles/startrek b/games/fortune/datfiles/startrek
index f45a0e2..af3f9d4 100644
--- a/games/fortune/datfiles/startrek
+++ b/games/fortune/datfiles/startrek
@@ -507,6 +507,7 @@ The joys of love made her human and the agonies of love destroyed her.
%
The man on tops walks a lonely street; the "chain" of command is often
a noose.
+ -- McCoy, "The Conscience of the King," stardate 2818.9
%
The more complex the mind, the greater the need for the simplicity of
play.
@@ -656,7 +657,7 @@ What kind of love is that? Not to be loved; never to have shown love.
-- Commissioner Nancy Hedford, "Metamorphosis",
stardate 3219.8
%
-When a child is taught ... its programmed with simple instructions --
+When a child is taught ... it's programmed with simple instructions --
and at some point, if its mind develops properly, it exceeds the sum of
what it was taught, thinks independently.
-- Dr. Richard Daystrom, "The Ultimate Computer",
@@ -689,7 +690,7 @@ sheer horror than the male of the species.
-- Spock, "Wolf in the Fold", stardate 3615.4
%
Women professionals do tend to over-compensate.
- -- Dr. Elizabeth Dehaver, "Where No Man Has Gone Before",
+ -- Dr. Elizabeth Dehner, "Where No Man Has Gone Before",
stardate 1312.9.
%
Worlds are conquered, galaxies destroyed -- but a woman is always a
diff --git a/games/fortune/datfiles/zippy b/games/fortune/datfiles/zippy
index a613036..7c43436 100644
--- a/games/fortune/datfiles/zippy
+++ b/games/fortune/datfiles/zippy
@@ -178,7 +178,7 @@ LEFT at th'HOLIDAY INN!! JOIN the CREDIT WORLD!! MAKE me an OFFER!!!
CONGRATULATIONS! Now should I make thinly veiled comments about
DIGNITY, self-esteem and finding TRUE FUN in your RIGHT VENTRICLE??
%
-Content: 80% POLYESTER, 20% DACRONi ... The waitress's UNIFORM sheds
+Content: 80% POLYESTER, 20% DACRON ... The waitress's UNIFORM sheds
TARTAR SAUCE like an 8" by 10" GLOSSY ...
%
Could I have a drug overdose?
@@ -200,7 +200,7 @@ DIDI ... is that a MARTIAN name, or, are we in ISRAEL?
%
Didn't I buy a 1951 Packard from you last March in Cairo?
%
-Disco oil bussing will create a throbbing naugahide pipeline running
+Disco oil bussing will create a throbbing naugahyde pipeline running
straight to the tropics from the rug producing regions and devalue the
dollar!
%
@@ -290,7 +290,7 @@ He is the MELBA-BEING ... the ANGEL CAKE ... XEROX him ... XEROX him --
%
He probably just wants to take over my CELLS and then EXPLODE inside me
like a BARREL of runny CHOPPED LIVER! Or maybe he'd like to
-PSYCHOLIGICALLY TERRORISE ME until I have no objection to a RIGHT-WING
+PSYCHOLOGICALLY TERRORISE ME until I have no objection to a RIGHT-WING
MILITARY TAKEOVER of my apartment!! I guess I should call AL PACINO!
%
Hello? Enema Bondage? I'm calling because I want to be happy, I
@@ -351,7 +351,7 @@ MOUSTACHE ... Have you ever noticed th' way it radiates SINCERITY,
HONESTY & WARMTH? It's a MOUSTACHE you want to take HOME and introduce
to NANCY SINATRA!
%
-How many returned bricklayers from FLORIDA are out purchasing PENCIL
+How many retired bricklayers from FLORIDA are out purchasing PENCIL
SHARPENERS right NOW??
%
How's it going in those MODULAR LOVE UNITS??
@@ -604,7 +604,7 @@ if it GLISTENS, gobble it!!
%
If our behavior is strict, we do not need fun!
%
-If Robert Di Niro assassinates Walter Slezak, will Jodie Foster marry
+If Robert De Niro assassinates Walter Slezak, will Jodie Foster marry
Bonzo??
%
I'll eat ANYTHING that's BRIGHT BLUE!!
@@ -802,7 +802,7 @@ ASHTRAYS ...
%
Let me do my TRIBUTE to FISHNET STOCKINGS ...
%
-Let's all show human CONCERN for REVERAND MOON's legal difficulties!!
+Let's all show human CONCERN for REVEREND MOON's legal difficulties!!
%
Let's send the Russians defective lifestyle accessories!
%
diff --git a/games/pom/pom.6 b/games/pom/pom.6
index e6bc957..60f7b40 100644
--- a/games/pom/pom.6
+++ b/games/pom/pom.6
@@ -34,7 +34,6 @@
.\"
.Dd May 31, 1993
.Dt POM 6
-.UC 7
.Sh NAME
.Nm pom
.Nd display the phase of the moon
diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile
index bfb4d93..18add27 100644
--- a/gnu/usr.bin/Makefile
+++ b/gnu/usr.bin/Makefile
@@ -4,7 +4,6 @@
SUBDIR= ${_binutils} \
${_cc} \
- ${_cpio} \
${_cvs} \
dialog \
diff \
@@ -28,10 +27,6 @@ _groff= groff
.endif
.endif
-.if ${MK_GNU_CPIO} == "yes"
-_cpio= cpio
-.endif
-
.if ${MK_CVS} != "no"
_cvs= cvs
.endif
diff --git a/gnu/usr.bin/binutils/ld/elf32btsmipn32_fbsd.sh b/gnu/usr.bin/binutils/ld/elf32btsmipn32_fbsd.sh
index ef5afbc..2dbfdea 100755
--- a/gnu/usr.bin/binutils/ld/elf32btsmipn32_fbsd.sh
+++ b/gnu/usr.bin/binutils/ld/elf32btsmipn32_fbsd.sh
@@ -1,4 +1,4 @@
# $FreeBSD$
-. ${srcdir}/emulparams/elf32btsmip.sh
+. ${srcdir}/emulparams/elf32btsmipn32.sh
. ${srcdir}/emulparams/elf_fbsd.sh
GENERATE_PIE_SCRIPT=yes
diff --git a/gnu/usr.bin/binutils/ld/elf32ltsmipn32_fbsd.sh b/gnu/usr.bin/binutils/ld/elf32ltsmipn32_fbsd.sh
index 89c13d8..f946aae 100755
--- a/gnu/usr.bin/binutils/ld/elf32ltsmipn32_fbsd.sh
+++ b/gnu/usr.bin/binutils/ld/elf32ltsmipn32_fbsd.sh
@@ -1,4 +1,4 @@
# $FreeBSD$
-. ${srcdir}/emulparams/elf32ltsmip.sh
+. ${srcdir}/emulparams/elf32ltsmipn32.sh
. ${srcdir}/emulparams/elf_fbsd.sh
GENERATE_PIE_SCRIPT=yes
diff --git a/gnu/usr.bin/cc/Makefile.inc b/gnu/usr.bin/cc/Makefile.inc
index d7ed8a8..f797dc7 100644
--- a/gnu/usr.bin/cc/Makefile.inc
+++ b/gnu/usr.bin/cc/Makefile.inc
@@ -30,6 +30,10 @@ CFLAGS+= -DLONG_TYPE_SIZE=${LONG_TYPE_SIZE}
CFLAGS+= -DCROSS_COMPILE
.endif
+.if ${TARGET_ARCH} == "mips" && !defined(TARGET_BIG_ENDIAN)
+CFLAGS += -DTARGET_ENDIAN_DEFAULT=0
+.endif
+
.if defined(WANT_FORCE_OPTIMIZATION_DOWNGRADE)
CFLAGS+= -DFORCE_OPTIMIZATION_DOWNGRADE=${WANT_FORCE_OPTIMIZATION_DOWNGRADE}
.endif
diff --git a/gnu/usr.bin/cpio/Makefile b/gnu/usr.bin/cpio/Makefile
deleted file mode 100644
index 60756ef..0000000
--- a/gnu/usr.bin/cpio/Makefile
+++ /dev/null
@@ -1,79 +0,0 @@
-# $FreeBSD$
-
-CPIODIR= ${.CURDIR}/../../../contrib/cpio
-.PATH: ${CPIODIR}/lib ${CPIODIR}/src ${CPIODIR}/doc
-
-SUBDIR= doc
-
-PROG= gcpio
-SRCS= copyin.c \
- copyout.c \
- copypass.c \
- defer.c \
- dstring.c \
- filemode.c \
- global.c \
- idcache.c \
- main.c \
- makepath.c \
- tar.c \
- userspec.c \
- util.c \
- argp-ba.c \
- argp-eexst.c \
- argp-fmtstream.c \
- argp-fs-xinl.c \
- argp-help.c \
- argp-parse.c \
- argp-pin.c \
- argp-pv.c \
- argp-pvh.c \
- argp-xinl.c \
- basename.c \
- dirname.c \
- error.c \
- exitfail.c \
- fatal.c \
- full-write.c \
- getopt.c \
- getopt1.c \
- hash.c \
- mempcpy.c \
- paxerror.c \
- paxexit.c \
- paxnames.c \
- quote.c \
- quotearg.c \
- rtapelib.c \
- safe-read.c \
- safe-write.c \
- strchrnul.c \
- stripslash.c \
- strndup.c \
- strnlen.c \
- umaxtostr.c \
- utimens.c \
- xalloc-die.c \
- xmalloc.c \
- xstrndup.c \
- alloca.h \
- getopt.h
-
-CLEANFILES+= alloca.h getopt.h
-
-getopt.h: getopt_.h
- ln -fs ${.ALLSRC} ${.TARGET}
-
-alloca.h: alloca_.h
- ln -fs ${.ALLSRC} ${.TARGET}
-
-CFLAGS+=-I${.OBJDIR} -I${.CURDIR} -I${CPIODIR}/lib -I${CPIODIR}/src \
- -DHAVE_CONFIG_H -DHAVE_MKFIFO -DHAVE_SETLOCALE -DHAVE_LSTAT
-
-gcpio.1: ${CPIODIR}/doc/cpio.1
- cat ${CPIODIR}/doc/cpio.1 >gcpio.1
-
-SYMLINKS=gcpio ${BINDIR}/cpio
-MLINKS=gcpio.1 cpio.1
-
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/cpio/config.h b/gnu/usr.bin/cpio/config.h
deleted file mode 100644
index 36a88f0..0000000
--- a/gnu/usr.bin/cpio/config.h
+++ /dev/null
@@ -1,1001 +0,0 @@
-/* $FreeBSD$ */
-
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define this to an absolute name of <dirent.h>. */
-/* #undef ABSOLUTE_DIRENT_H */
-
-/* Define this to an absolute name of <fcntl.h>. */
-#define ABSOLUTE_FCNTL_H "///usr/include/fcntl.h"
-
-/* Define this to an absolute name of <float.h>. */
-/* #undef ABSOLUTE_FLOAT_H */
-
-/* Define this to an absolute name of <inttypes.h>. */
-#define ABSOLUTE_INTTYPES_H "///usr/include/inttypes.h"
-
-/* Define this to an absolute name of <stdint.h>. */
-#define ABSOLUTE_STDINT_H "///usr/include/stdint.h"
-
-/* Define this to an absolute name of <stdio.h>. */
-#define ABSOLUTE_STDIO_H "///usr/include/stdio.h"
-
-/* Define this to an absolute name of <stdlib.h>. */
-#define ABSOLUTE_STDLIB_H "///usr/include/stdlib.h"
-
-/* Define this to an absolute name of <string.h>. */
-#define ABSOLUTE_STRING_H "///usr/include/string.h"
-
-/* Define this to an absolute name of <sysexits.h>. */
-#define ABSOLUTE_SYSEXITS_H "///usr/include/sysexits.h"
-
-/* Define this to an absolute name of <sys/stat.h>. */
-#define ABSOLUTE_SYS_STAT_H "///usr/include/sys/stat.h"
-
-/* Define this to an absolute name of <sys/time.h>. */
-#define ABSOLUTE_SYS_TIME_H "///usr/include/sys/time.h"
-
-/* Define this to an absolute name of <time.h>. */
-#define ABSOLUTE_TIME_H "///usr/include/time.h"
-
-/* Define this to an absolute name of <unistd.h>. */
-#define ABSOLUTE_UNISTD_H "///usr/include/unistd.h"
-
-/* Define this to an absolute name of <wchar.h>. */
-/* #undef ABSOLUTE_WCHAR_H */
-
-/* Define this to an absolute name of <wctype.h>. */
-#define ABSOLUTE_WCTYPE_H "///usr/include/wctype.h"
-
-/* Define to the number of bits in type 'ptrdiff_t'. */
-/* #undef BITSIZEOF_PTRDIFF_T */
-
-/* Define to the number of bits in type 'sig_atomic_t'. */
-/* #undef BITSIZEOF_SIG_ATOMIC_T */
-
-/* Define to the number of bits in type 'size_t'. */
-/* #undef BITSIZEOF_SIZE_T */
-
-/* Define to the number of bits in type 'wchar_t'. */
-/* #undef BITSIZEOF_WCHAR_T */
-
-/* Define to the number of bits in type 'wint_t'. */
-/* #undef BITSIZEOF_WINT_T */
-
-/* Define if chown is not POSIX compliant regarding IDs of -1. */
-/* #undef CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE */
-
-/* Define if chown modifies symlinks. */
-/* #undef CHOWN_MODIFIES_SYMLINK */
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
- systems. This function is required for `alloca.c' support on those systems.
- */
-/* #undef CRAY_STACKSEG_END */
-
-/* Define to 1 if using `alloca.c'. */
-/* #undef C_ALLOCA */
-
-/* Define full file name of rmt program. */
-#define DEFAULT_RMT_COMMAND "/etc/rmt"
-
-/* the name of the file descriptor member of DIR */
-/* #undef DIR_FD_MEMBER_NAME */
-
-#ifdef DIR_FD_MEMBER_NAME
-# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
-#else
-# define DIR_TO_FD(Dir_p) -1
-#endif
-
-
-/* Define to 1 if // is a file system root distinct from /. */
-/* #undef DOUBLE_SLASH_IS_DISTINCT_ROOT */
-
-/* Define if struct dirent has a member d_ino that actually works. */
-#define D_INO_IN_DIRENT 1
-
-/* Define to 1 if translation of program messages to the user's native
- language is requested. */
-/* #undef ENABLE_NLS */
-
-/* Define as good substitute value for EOVERFLOW. */
-/* #undef EOVERFLOW */
-
-/* Define if gnulib's fchdir() replacement is used. */
-/* #undef FCHDIR_REPLACEMENT */
-
-/* Define on systems for which file names may have a so-called `drive letter'
- prefix, define this to compute the length of that prefix, including the
- colon. */
-#define FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0
-
-/* Define if the backslash character may also serve as a file name component
- separator. */
-#define FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0
-
-/* Define if a drive letter prefix denotes a relative path if it is not
- followed by a file name component separator. */
-#define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
-
-/* Define if gettimeofday clobbers the localtime buffer. */
-/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME */
-
-/* Define to 1 when using the gnulib module close-stream. */
-#define GNULIB_CLOSE_STREAM 1
-
-/* Define to 1 when using the gnulib module fcntl-safer. */
-#define GNULIB_FCNTL_SAFER 1
-
-/* Define to 1 to add extern declaration of program_invocation_name to argp.h
- */
-#define GNULIB_PROGRAM_INVOCATION_NAME 1
-
-/* Define to 1 to add extern declaration of program_invocation_short_name to
- argp.h */
-#define GNULIB_PROGRAM_INVOCATION_SHORT_NAME 1
-
-/* Define to 1 if you have the `alarm' function. */
-#define HAVE_ALARM 1
-
-/* Define to 1 if you have 'alloca' after including <alloca.h>, a header that
- may be supplied by this distribution. */
-#define HAVE_ALLOCA 1
-
-/* Define HAVE_ALLOCA_H for backward compatibility with older code that
- includes <alloca.h> only if HAVE_ALLOCA_H is defined. */
-#define HAVE_ALLOCA_H 1
-
-/* Define to 1 if you have the `btowc' function. */
-#define HAVE_BTOWC 1
-
-/* Define to 1 if you have the `canonicalize_file_name' function. */
-/* #undef HAVE_CANONICALIZE_FILE_NAME */
-
-/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
- CoreFoundation framework. */
-/* #undef HAVE_CFLOCALECOPYCURRENT */
-
-/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
- the CoreFoundation framework. */
-/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
-
-/* Define to 1 if your system has a working `chown' function. */
-#define HAVE_CHOWN 1
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#define HAVE_CLOCK_GETTIME 1
-
-/* Define to 1 if you have the `clock_settime' function. */
-#define HAVE_CLOCK_SETTIME 1
-
-/* Define if you have compound literals. */
-/* #undef HAVE_COMPOUND_LITERALS */
-
-/* Define if the GNU dcgettext() function is already present or preinstalled.
- */
-/* #undef HAVE_DCGETTEXT */
-
-/* Define to 1 if you have the declaration of `atoi', and to 0 if you don't.
- */
-#define HAVE_DECL_ATOI 1
-
-/* Define to 1 if you have the declaration of `canonicalize_file_name', and to
- 0 if you don't. */
-#define HAVE_DECL_CANONICALIZE_FILE_NAME 0
-
-/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_CLEARERR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't.
- */
-#define HAVE_DECL_DIRFD 1
-
-/* Define to 1 if you have the declaration of `errno', and to 0 if you don't.
- */
-#define HAVE_DECL_ERRNO 1
-
-/* Define to 1 if you have the declaration of `exit', and to 0 if you don't.
- */
-#define HAVE_DECL_EXIT 1
-
-/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
- don't. */
-#define HAVE_DECL_FEOF_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FERROR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FFLUSH_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FGETS_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FPUTC_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FPUTS_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FREAD_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FWRITE_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_GETCHAR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `getcwd', and to 0 if you don't.
- */
-#define HAVE_DECL_GETCWD 1
-
-/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
- don't. */
-#define HAVE_DECL_GETC_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
- */
-#define HAVE_DECL_GETENV 1
-
-/* Define to 1 if you have the declaration of `getgrgid', and to 0 if you
- don't. */
-#define HAVE_DECL_GETGRGID 1
-
-/* Define to 1 if you have the declaration of `getgrnam', and to 0 if you
- don't. */
-#define HAVE_DECL_GETGRNAM 1
-
-/* Define to 1 if you have the declaration of `getpwnam', and to 0 if you
- don't. */
-#define HAVE_DECL_GETPWNAM 1
-
-/* Define to 1 if you have the declaration of `imaxabs', and to 0 if you
- don't. */
-#define HAVE_DECL_IMAXABS 1
-
-/* Define to 1 if you have the declaration of `imaxdiv', and to 0 if you
- don't. */
-#define HAVE_DECL_IMAXDIV 1
-
-/* Define to 1 if you have the declaration of `isblank', and to 0 if you
- don't. */
-#define HAVE_DECL_ISBLANK 1
-
-/* Define to 1 if you have the declaration of `lchown', and to 0 if you don't.
- */
-#define HAVE_DECL_LCHOWN 1
-
-/* Define to 1 if you have the declaration of `memrchr', and to 0 if you
- don't. */
-#define HAVE_DECL_MEMRCHR 0
-
-/* Define to 1 if you have the declaration of `mkdir', and to 0 if you don't.
- */
-#define HAVE_DECL_MKDIR 1
-
-/* Define if program_invocation_name is declared */
-/* #undef HAVE_DECL_PROGRAM_INVOCATION_NAME */
-
-/* Define if program_invocation_short_name is declared */
-/* #undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME */
-
-/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_PUTCHAR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you
- don't. */
-#define HAVE_DECL_PUTC_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `strdup', and to 0 if you don't.
- */
-#define HAVE_DECL_STRDUP 1
-
-/* Define to 1 if you have the declaration of `strerror', and to 0 if you
- don't. */
-#define HAVE_DECL_STRERROR 1
-
-/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
- don't. */
-#define HAVE_DECL_STRERROR_R 1
-
-/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you
- don't. */
-#define HAVE_DECL_STRNCASECMP 1
-
-/* Define to 1 if you have the declaration of `strndup', and to 0 if you
- don't. */
-#define HAVE_DECL_STRNDUP 0
-
-/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
- don't. */
-#define HAVE_DECL_STRNLEN 0
-
-/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you
- don't. */
-#define HAVE_DECL_STRTOIMAX 1
-
-/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you
- don't. */
-#define HAVE_DECL_STRTOUMAX 1
-
-/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
- */
-/* #undef HAVE_DECL_TZNAME */
-
-/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
- don't. */
-#define HAVE_DECL_VSNPRINTF 1
-
-/* Define to 1 if you have the declaration of `__fpending', and to 0 if you
- don't. */
-#define HAVE_DECL___FPENDING 0
-
-/* Define to 1 if you have the <dirent.h> header file. */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the `dirfd' function. */
-/* #undef HAVE_DIRFD */
-
-/* Define to 1 if you have the `dup2' function. */
-#define HAVE_DUP2 1
-
-/* Define if you have the declaration of environ. */
-/* #undef HAVE_ENVIRON_DECL */
-
-/* Define to 1 if you have the `fchdir' function. */
-#define HAVE_FCHDIR 1
-
-/* Define to 1 if you have the `fchmod' function. */
-#define HAVE_FCHMOD 1
-
-/* Define to 1 if you have the `fchmodat' function. */
-/* #undef HAVE_FCHMODAT */
-
-/* Define to 1 if you have the `fchown' function. */
-#define HAVE_FCHOWN 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `fdopendir' function. */
-/* #undef HAVE_FDOPENDIR */
-
-/* Define to 1 if you have the <features.h> header file. */
-/* #undef HAVE_FEATURES_H */
-
-/* Define to 1 if you have the <float.h> header file. */
-#define HAVE_FLOAT_H 1
-
-/* Define to 1 if you have the `flockfile' function. */
-#define HAVE_FLOCKFILE 1
-
-/* Define to 1 if you have the `funlockfile' function. */
-#define HAVE_FUNLOCKFILE 1
-
-/* Define to 1 if you have the `futimes' function. */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the `futimesat' function. */
-/* #undef HAVE_FUTIMESAT */
-
-/* Define to 1 if you have the `getcwd' function. */
-#define HAVE_GETCWD 1
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#define HAVE_GETOPT_H 1
-
-/* Define to 1 if you have the `getopt_long_only' function. */
-#define HAVE_GETOPT_LONG_ONLY 1
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define if the GNU gettext() function is already present or preinstalled. */
-/* #undef HAVE_GETTEXT */
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* Define if you have the iconv() function and it works. */
-/* #undef HAVE_ICONV */
-
-/* Define to 1 if the compiler supports one of the keywords 'inline',
- '__inline__', '__inline' and effectively inlines functions marked as such.
- */
-#define HAVE_INLINE 1
-
-/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
-#define HAVE_INTMAX_T 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
- declares uintmax_t. */
-#define HAVE_INTTYPES_H_WITH_UINTMAX 1
-
-/* Define to 1 if you have the <io.h> header file. */
-/* #undef HAVE_IO_H */
-
-/* Define to 1 if you have the `iswcntrl' function. */
-#define HAVE_ISWCNTRL 1
-
-/* Define to 1 if you have the `iswctype' function. */
-#define HAVE_ISWCTYPE 1
-
-/* Define to 1 if you have the `lchmod' function. */
-#define HAVE_LCHMOD 1
-
-/* Define to 1 if you have the `lchown' function. */
-#define HAVE_LCHOWN 1
-
-/* Define to 1 if you have the <libintl.h> header file. */
-/* #undef HAVE_LIBINTL_H */
-
-/* Define to 1 if you have the <linewrap.h> header file. */
-/* #undef HAVE_LINEWRAP_H */
-
-/* Define to 1 if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define if you have the 'long long' type. */
-#define HAVE_LONG_LONG 1
-
-/* Define to 1 if the system has the type `long long int'. */
-#define HAVE_LONG_LONG_INT 1
-
-/* Define to 1 if you have the `lstat' function. */
-#define HAVE_LSTAT 1
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#define HAVE_MALLOC 1
-
-/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
-#define HAVE_MBRTOWC 1
-
-/* Define to 1 if you have the `mbsinit' function. */
-#define HAVE_MBSINIT 1
-
-/* Define to 1 if you have the `mbsrtowcs' function. */
-#define HAVE_MBSRTOWCS 1
-
-/* Define to 1 if <wchar.h> declares mbstate_t. */
-#define HAVE_MBSTATE_T 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mempcpy' function. */
-/* #undef HAVE_MEMPCPY */
-
-/* Define to 1 if you have the `memrchr' function. */
-/* #undef HAVE_MEMRCHR */
-
-/* Define to 1 if you have the `mkdirat' function. */
-/* #undef HAVE_MKDIRAT */
-
-/* Define to 1 if you have the `mkfifo' function. */
-#define HAVE_MKFIFO 1
-
-/* Define to 1 if you have the `nanotime' function. */
-/* #undef HAVE_NANOTIME */
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-/* #undef HAVE_NDIR_H */
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <net/errno.h> header file. */
-/* #undef HAVE_NET_ERRNO_H */
-
-/* Define to 1 if libc includes obstacks. */
-/* #undef HAVE_OBSTACK */
-
-/* Define to 1 if you have the `openat' function. */
-/* #undef HAVE_OPENAT */
-
-/* Define to 1 if getcwd works, except it sometimes fails when it shouldn't,
- setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If __GETCWD_PREFIX is not
- defined, it doesn't matter whether HAVE_PARTLY_WORKING_GETCWD is defined.
- */
-#define HAVE_PARTLY_WORKING_GETCWD 1
-
-/* Define to 1 if you have the `pipe' function. */
-#define HAVE_PIPE 1
-
-/* Define if program_invocation_name is defined */
-/* #undef HAVE_PROGRAM_INVOCATION_NAME */
-
-/* Define if program_invocation_short_name is defined */
-/* #undef HAVE_PROGRAM_INVOCATION_SHORT_NAME */
-
-/* Define to 1 if the system has the type `ptrdiff_t'. */
-#define HAVE_PTRDIFF_T 1
-
-/* Define to 1 if you have the `readlink' function. */
-#define HAVE_READLINK 1
-
-/* Define to 1 if you have the <search.h> header file. */
-/* #undef HAVE_SEARCH_H */
-
-/* Define to 1 if you have the `setenv' function. */
-#define HAVE_SETENV 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the <sgtty.h> header file. */
-/* #undef HAVE_SGTTY_H */
-
-/* Define to 1 if 'sig_atomic_t' is a signed integer type. */
-/* #undef HAVE_SIGNED_SIG_ATOMIC_T */
-
-/* Define to 1 if 'wchar_t' is a signed integer type. */
-/* #undef HAVE_SIGNED_WCHAR_T */
-
-/* Define to 1 if 'wint_t' is a signed integer type. */
-/* #undef HAVE_SIGNED_WINT_T */
-
-/* Define to 1 if you have the `sleep' function. */
-#define HAVE_SLEEP 1
-
-/* Define to 1 if you have the `snprintf' function. */
-#define HAVE_SNPRINTF 1
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
- uintmax_t. */
-#define HAVE_STDINT_H_WITH_UINTMAX 1
-
-/* Define to 1 if you have the <stdio_ext.h> header file. */
-/* #undef HAVE_STDIO_EXT_H */
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `stpcpy' function. */
-#define HAVE_STPCPY 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strchrnul' function. */
-/* #undef HAVE_STRCHRNUL */
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the `strerror_r' function. */
-#define HAVE_STRERROR_R 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#define HAVE_STRNCASECMP 1
-
-/* Define if you have the strndup() function and it works. */
-/* #undef HAVE_STRNDUP */
-
-/* Define to 1 if you have the `strtol' function. */
-#define HAVE_STRTOL 1
-
-/* Define to 1 if `st_blksize' is member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-
-/* Define to 1 if `st_blocks' is member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLOCKS 1
-
-/* Define to 1 if `tm_zone' is member of `struct tm'. */
-#define HAVE_STRUCT_TM_TM_ZONE 1
-
-/* Define if struct utimbuf is declared -- usually in <utime.h>. Some systems
- have utime.h but don't declare the struct anywhere. */
-#define HAVE_STRUCT_UTIMBUF 1
-
-/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use
- `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */
-#define HAVE_ST_BLKSIZE 1
-
-/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
- `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
-#define HAVE_ST_BLOCKS 1
-
-/* Define to 1 if you have the <sysexits.h> header file. */
-#define HAVE_SYSEXITS_H 1
-
-/* Define to 1 if you have the <sys/bitypes.h> header file. */
-/* #undef HAVE_SYS_BITYPES_H */
-
-/* Define to 1 if you have the <sys/buf.h> header file. */
-#define HAVE_SYS_BUF_H 1
-
-/* Define to 1 if you have the <sys/device.h> header file. */
-/* #undef HAVE_SYS_DEVICE_H */
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define if your system has sys_errlist global variable */
-#define HAVE_SYS_ERRLIST 1
-
-/* Define to 1 if you have the <sys/gentape.h> header file. */
-/* #undef HAVE_SYS_GENTAPE_H */
-
-/* Define to 1 if you have the <sys/inet.h> header file. */
-/* #undef HAVE_SYS_INET_H */
-
-/* Define to 1 if you have the <sys/inttypes.h> header file. */
-/* #undef HAVE_SYS_INTTYPES_H */
-
-/* Define to 1 if you have the <sys/io/trioctl.h> header file. */
-/* #undef HAVE_SYS_IO_TRIOCTL_H */
-
-/* Define to 1 if you have the <sys/mtio.h> header file. */
-#define HAVE_SYS_MTIO_H 1
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/tape.h> header file. */
-/* #undef HAVE_SYS_TAPE_H */
-
-/* Define to 1 if you have the <sys/timeb.h> header file. */
-/* #undef HAVE_SYS_TIMEB_H */
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/tprintf.h> header file. */
-/* #undef HAVE_SYS_TPRINTF_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define if struct tm has the tm_gmtoff member. */
-#define HAVE_TM_GMTOFF 1
-
-/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
- `HAVE_STRUCT_TM_TM_ZONE' instead. */
-#define HAVE_TM_ZONE 1
-
-/* Define to 1 if you have the `tsearch' function. */
-/* #undef HAVE_TSEARCH */
-
-/* Define to 1 if you don't have `tm_zone' but do have the external array
- `tzname'. */
-/* #undef HAVE_TZNAME */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `unsetenv' function. */
-#define HAVE_UNSETENV 1
-
-/* Define to 1 if the system has the type `unsigned long long int'. */
-#define HAVE_UNSIGNED_LONG_LONG_INT 1
-
-/* Define to 1 if you have the <utime.h> header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if you have the <utmp.h> header file. */
-#define HAVE_UTMP_H 1
-
-/* Define to 1 if you have the `vasnprintf' function. */
-/* #undef HAVE_VASNPRINTF */
-
-/* Define to 1 if you have the `vsnprintf' function. */
-#define HAVE_VSNPRINTF 1
-
-/* Define to 1 if you have the <wchar.h> header file. */
-#define HAVE_WCHAR_H 1
-
-/* Define if you have the 'wchar_t' type. */
-#define HAVE_WCHAR_T 1
-
-/* Define to 1 if you have the `wcslen' function. */
-#define HAVE_WCSLEN 1
-
-/* Define to 1 if you have the <wctype.h> header file. */
-#define HAVE_WCTYPE_H 1
-
-/* Define if you have the 'wint_t' type. */
-#define HAVE_WINT_T 1
-
-/* Define to 1 if you have the `wmemchr' function. */
-#define HAVE_WMEMCHR 1
-
-/* Define to 1 if you have the `wmemcpy' function. */
-#define HAVE_WMEMCPY 1
-
-/* Define to 1 if you have the `wmempcpy' function. */
-/* #undef HAVE_WMEMPCPY */
-
-/* Define to 1 if O_NOATIME works. */
-#define HAVE_WORKING_O_NOATIME 0
-
-/* Define to 1 if O_NOFOLLOW works. */
-#define HAVE_WORKING_O_NOFOLLOW 1
-
-/* Define if utimes works properly. */
-#define HAVE_WORKING_UTIMES 1
-
-/* Define to 1 if the system has the type `_Bool'. */
-#define HAVE__BOOL 1
-
-/* Define to 1 if you have the `_ftime' function. */
-/* #undef HAVE__FTIME */
-
-/* Define to 1 if you have the `__fpending' function. */
-/* #undef HAVE___FPENDING */
-
-#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
-# define ISSLASH(C) ((C) == '/' || (C) == '\\')
-#else
-# define ISSLASH(C) ((C) == '/')
-#endif
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
- */
-/* #undef MAJOR_IN_MKDEV */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
- <sysmacros.h>. */
-/* #undef MAJOR_IN_SYSMACROS */
-
-/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */
-#define MALLOC_0_IS_NONNULL 1
-
-/* Define to mt_model (v.g., for DG/UX), else to mt_type. */
-#define MTIO_CHECK_FIELD mt_type
-
-/* Name of package */
-#define PACKAGE "cpio"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "bug-cpio@gnu.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "GNU cpio"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "GNU cpio 2.8-FreeBSD"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "cpio"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.8-FreeBSD"
-
-/* the number of pending output bytes on stream `fp' */
-#define PENDING_OUTPUT_N_BYTES fp->_p - fp->_bf._base
-
-/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
-/* #undef PRI_MACROS_BROKEN */
-
-/* Define to 1 if the C compiler supports function prototypes. */
-#define PROTOTYPES 1
-
-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
- 'ptrdiff_t'. */
-/* #undef PTRDIFF_T_SUFFIX */
-
-/* Define if vasnprintf exists but is overridden by gnulib. */
-/* #undef REPLACE_VASNPRINTF */
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#define RETSIGTYPE void
-
-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
- 'sig_atomic_t'. */
-/* #undef SIG_ATOMIC_T_SUFFIX */
-
-/* Define as the maximum value of type 'size_t', if the system doesn't define
- it. */
-/* #undef SIZE_MAX */
-
-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
- 'size_t'. */
-/* #undef SIZE_T_SUFFIX */
-
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at runtime.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-/* #undef STACK_DIRECTION */
-
-/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
-/* #undef STAT_MACROS_BROKEN */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if strerror_r returns char *. */
-/* #undef STRERROR_R_CHAR_P */
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-/* #undef TM_IN_SYS_TIME */
-
-/* Define to 1 if you want getc etc. to use unlocked I/O if available.
- Unlocked I/O can improve performance in unithreaded apps, but it is not
- safe for multithreaded apps. */
-#define USE_UNLOCKED_IO 1
-
-/* Version number of package */
-#define VERSION "2.8-FreeBSD"
-
-/* Define if unsetenv() returns void, not int. */
-/* #undef VOID_UNSETENV */
-
-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
- 'wchar_t'. */
-/* #undef WCHAR_T_SUFFIX */
-
-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
- 'wint_t'. */
-/* #undef WINT_T_SUFFIX */
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-/* # undef _ALL_SOURCE */
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Enable extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-
-/* Define to rpl_ if the getopt replacement functions and variables should be
- used. */
-#define __GETOPT_PREFIX rpl_
-
-/* Define to rpl_ if the openat replacement function should be used. */
-#define __OPENAT_PREFIX rpl_
-
-/* Define like PROTOTYPES; this can be used by system headers. */
-#define __PROTOTYPES 1
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to rpl_fchownat if the replacement function should be used. */
-#define fchownat rpl_fchownat
-
-/* Define to a replacement function name for fnmatch(). */
-/* #define fnmatch gnu_fnmatch */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef gid_t */
-
-/* A replacement for va_copy, if needed. */
-#define gl_va_copy(a,b) ((a) = (b))
-
-/* Define to rpl_gmtime if the replacement function should be used. */
-/* #undef gmtime */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to long or long long if <stdint.h> and <inttypes.h> don't define. */
-/* #undef intmax_t */
-
-/* Define to rpl_localtime if the replacement function should be used. */
-/* #undef localtime */
-
-/* Define to rpl_malloc if the replacement function should be used. */
-/* #undef malloc */
-
-/* Define to a type if <wchar.h> does not define. */
-/* #undef mbstate_t */
-
-/* Define to rpl_mktime if the replacement function should be used. */
-#define mktime rpl_mktime
-
-/* Define to `long int' if <sys/types.h> does not define. */
-/* #undef off_t */
-
-/* Define to a replacement function name for realpath(). */
-#define realpath rpl_realpath
-
-/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
- supported. Do not define if restrict is supported directly. */
-/* #undef restrict */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define as a signed type of the same size as size_t. */
-/* #undef ssize_t */
-
-/* Define to rpl_strnlen if the replacement function should be used. */
-#define strnlen rpl_strnlen
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef uid_t */
-
-/* Define as a macro for copying va_list variables. */
-/* #undef va_copy */
diff --git a/gnu/usr.bin/cpio/doc/Makefile b/gnu/usr.bin/cpio/doc/Makefile
deleted file mode 100644
index 220de5f..0000000
--- a/gnu/usr.bin/cpio/doc/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Note that this files is under a "BSD" copyright (c) by David O'Brien 1997,
-# even though it may live in src/gnu/...
-
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../../../contrib/cpio/doc
-
-INFO = cpio
-
-INFOSECTION= "Cpio Documentation"
-INFOENTRY_cpio="* CPIO: (cpio). Making tape (or disk) archives."
-
-SRCDIR= ${.CURDIR}/../../../../contrib/cpio/doc
-
-.include <bsd.info.mk>
diff --git a/gnu/usr.bin/diff/context.c.diff b/gnu/usr.bin/diff/context.c.diff
index ee1ab21..06cfb12 100644
--- a/gnu/usr.bin/diff/context.c.diff
+++ b/gnu/usr.bin/diff/context.c.diff
@@ -15,7 +15,7 @@ $FreeBSD$
INT_STRLEN_BOUND (time_t) + 11)];
struct tm const *tm = localtime (&inf->stat.st_mtime);
- int nsec = TIMESPEC_NS (inf->stat.st_mtim);
-+ long nsec = TIMESPEC_NS (inf->stat.st_mtimespec);
++ long nsec = TIMESPEC_NS (inf->stat.st_mtim);
if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec)))
{
- long int sec = inf->stat.st_mtime;
diff --git a/gnu/usr.bin/diff/diff.c.diff b/gnu/usr.bin/diff/diff.c.diff
index 884a9c4..28b90ab 100644
--- a/gnu/usr.bin/diff/diff.c.diff
+++ b/gnu/usr.bin/diff/diff.c.diff
@@ -49,21 +49,3 @@ $FreeBSD$
output_style = style;
}
}
-@@ -997,7 +1001,7 @@
- #ifdef ST_MTIM_NSEC
-
- # if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
-- if (clock_gettime (CLOCK_REALTIME, &st->st_mtim) == 0)
-+ if (clock_gettime (CLOCK_REALTIME, &st->st_mtimespec) == 0)
- return;
- # endif
-
-@@ -1007,7 +1011,7 @@
- if (gettimeofday (&timeval, 0) == 0)
- {
- st->st_mtime = timeval.tv_sec;
-- st->st_mtim.ST_MTIM_NSEC = timeval.tv_usec * 1000;
-+ st->st_mtimespec.ST_MTIM_NSEC = timeval.tv_usec * 1000;
- return;
- }
- }
diff --git a/gnu/usr.bin/dtc/Makefile b/gnu/usr.bin/dtc/Makefile
index 3bab94e..08f4ad5 100644
--- a/gnu/usr.bin/dtc/Makefile
+++ b/gnu/usr.bin/dtc/Makefile
@@ -4,7 +4,7 @@
DTCDIR= ${.CURDIR}/../../../contrib/dtc
LIBFDTDIR= ${.CURDIR}/../../../sys/contrib/libfdt
-.PATH: ${DTCDIR} ${LIBFDTDIR} ${DTCDIR}/tests
+.PATH: ${DTCDIR} ${LIBFDTDIR}
PROG= dtc
diff --git a/gnu/usr.bin/gdb/Makefile b/gnu/usr.bin/gdb/Makefile
index 81a1d6c..db21e56 100644
--- a/gnu/usr.bin/gdb/Makefile
+++ b/gnu/usr.bin/gdb/Makefile
@@ -2,7 +2,8 @@
SUBDIR= doc libgdb gdb gdbtui kgdb
-.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "arm" || ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "powerpc"
+TARGET_ARCH?= ${MACHINE_ARCH}
+.if exists(${.CURDIR}/gdbserver/reg-${TARGET_ARCH}.c)
SUBDIR+=gdbserver
.endif
diff --git a/gnu/usr.bin/gdb/Makefile.inc b/gnu/usr.bin/gdb/Makefile.inc
index abb5296..0bd4ec4 100644
--- a/gnu/usr.bin/gdb/Makefile.inc
+++ b/gnu/usr.bin/gdb/Makefile.inc
@@ -41,7 +41,7 @@ CFLAGS+= -I${CNTRB_BU}/bfd
GENSRCS+= nm.h tm.h
.if defined(GDB_CROSS_DEBUGGER)
-CFLAGS+= -DCROSS_DEBUGGER
+CFLAGS+= -DCROSS_DEBUGGER -I${BMAKE_ROOT}/../..
GDB_SUFFIX= -${TARGET_ARCH}
NO_MAN=
.endif
diff --git a/gnu/usr.bin/gdb/arch/arm/nm-fbsd.h b/gnu/usr.bin/gdb/arch/arm/nm-fbsd.h
index cf2c64f..8134b1a 100644
--- a/gnu/usr.bin/gdb/arch/arm/nm-fbsd.h
+++ b/gnu/usr.bin/gdb/arch/arm/nm-fbsd.h
@@ -32,4 +32,4 @@
/* We can attach and detach. */
#define ATTACH_DETACH
-#endif /* NM_NBSD_H */
+#endif /* NM_FBSD_H */
diff --git a/gnu/usr.bin/gdb/gdbserver/Makefile b/gnu/usr.bin/gdb/gdbserver/Makefile
index 390ef32..08f25ae 100644
--- a/gnu/usr.bin/gdb/gdbserver/Makefile
+++ b/gnu/usr.bin/gdb/gdbserver/Makefile
@@ -14,20 +14,9 @@ SRCS= inferiors.c mem-break.c regcache.c remote-utils.c \
server.c signals.c target.c utils.c
SRCS+= fbsd-low.c
-.if ${MACHINE_ARCH} == "amd64"
-SRCS+= fbsd-amd64-low.c i387-fp.c reg-x86-64.c
-.endif
-
-.if ${MACHINE_ARCH} == "arm"
-SRCS+= fbsd-arm-low.c reg-arm.c
-.endif
-
-.if ${MACHINE_ARCH} == "i386"
-SRCS+= fbsd-i386-low.c i387-fp.c reg-i386.c
-.endif
-
-.if ${MACHINE_ARCH} == "powerpc"
-SRCS+= fbsd-ppc-low.c reg-ppc.c
+SRCS+= fbsd-${MACHINE_ARCH}-low.c reg-${MACHINE_ARCH}.c
+.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
+SRCS+= i387-fp.c
.endif
#CFLAGS+= -I${.CURDIR}/../arch/${MACHINE_ARCH}
diff --git a/gnu/usr.bin/gdb/gdbserver/fbsd-ppc-low.c b/gnu/usr.bin/gdb/gdbserver/fbsd-powerpc-low.c
index 35f7ac6..35f7ac6 100644
--- a/gnu/usr.bin/gdb/gdbserver/fbsd-ppc-low.c
+++ b/gnu/usr.bin/gdb/gdbserver/fbsd-powerpc-low.c
diff --git a/gnu/usr.bin/gdb/gdbserver/reg-x86-64.c b/gnu/usr.bin/gdb/gdbserver/reg-amd64.c
index 7b0534f..7b0534f 100644
--- a/gnu/usr.bin/gdb/gdbserver/reg-x86-64.c
+++ b/gnu/usr.bin/gdb/gdbserver/reg-amd64.c
diff --git a/gnu/usr.bin/gdb/gdbserver/reg-ppc.c b/gnu/usr.bin/gdb/gdbserver/reg-powerpc.c
index 4704663..4704663 100644
--- a/gnu/usr.bin/gdb/gdbserver/reg-ppc.c
+++ b/gnu/usr.bin/gdb/gdbserver/reg-powerpc.c
diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.1 b/gnu/usr.bin/gdb/kgdb/kgdb.1
index 5b6fea0..4073d70 100644
--- a/gnu/usr.bin/gdb/kgdb/kgdb.1
+++ b/gnu/usr.bin/gdb/kgdb/kgdb.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd October 11, 2006
-.Os
.Dt KGDB 1
+.Os
.Sh NAME
.Nm kgdb
.Nd "kernel debugger"
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
index 4d5cea6..4efa6eb 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
@@ -28,9 +28,16 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#ifdef CROSS_DEBUGGER
+#include <sys/ia64/include/_regset.h>
+#include <sys/ia64/include/frame.h>
+#include <sys/ia64/include/md_var.h>
+#include <sys/ia64/include/pcb.h>
+#else
#include <machine/frame.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
+#endif
#include <err.h>
#include <kvm.h>
#include <string.h>
diff --git a/include/Makefile b/include/Makefile
index c964827..96690ad 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -17,13 +17,13 @@ INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \
ndbm.h netconfig.h \
netdb.h nl_types.h nlist.h nss.h nsswitch.h paths.h \
printf.h proc_service.h pthread.h \
- pthread_np.h pwd.h ranlib.h readpassphrase.h regex.h regexp.h \
+ pthread_np.h pwd.h ranlib.h readpassphrase.h regex.h \
res_update.h resolv.h runetype.h search.h semaphore.h setjmp.h \
signal.h spawn.h stab.h \
stdbool.h stddef.h stdio.h stdlib.h string.h stringlist.h \
strings.h sysexits.h tar.h termios.h tgmath.h \
time.h timeconv.h timers.h ttyent.h \
- ulimit.h unistd.h utime.h utmp.h utmpx.h uuid.h varargs.h vis.h \
+ ulimit.h unistd.h utime.h utmpx.h uuid.h varargs.h vis.h \
wchar.h wctype.h wordexp.h
MHDRS= float.h floatingpoint.h stdarg.h
diff --git a/include/dlfcn.h b/include/dlfcn.h
index de654f7..794fde1 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -113,8 +113,7 @@ typedef struct dl_serinfo {
__BEGIN_DECLS
/* XSI functions first. */
int dlclose(void *);
-const char *
- dlerror(void);
+char *dlerror(void);
void *dlopen(const char *, int);
void *dlsym(void * __restrict, const char * __restrict);
diff --git a/include/inttypes.h b/include/inttypes.h
index 05171a6..9aad660 100644
--- a/include/inttypes.h
+++ b/include/inttypes.h
@@ -32,6 +32,13 @@
#include <machine/_inttypes.h>
#include <sys/stdint.h>
+#ifndef __cplusplus
+#ifndef _WCHAR_T_DECLARED
+typedef __wchar_t wchar_t;
+#define _WCHAR_T_DECLARED
+#endif
+#endif
+
typedef struct {
intmax_t quot; /* Quotient. */
intmax_t rem; /* Remainder. */
@@ -43,10 +50,10 @@ imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2;
intmax_t strtoimax(const char * __restrict, char ** __restrict, int);
uintmax_t strtoumax(const char * __restrict, char ** __restrict, int);
-intmax_t wcstoimax(const __wchar_t * __restrict,
- __wchar_t ** __restrict, int);
-uintmax_t wcstoumax(const __wchar_t * __restrict,
- __wchar_t ** __restrict, int);
+intmax_t wcstoimax(const wchar_t * __restrict,
+ wchar_t ** __restrict, int);
+uintmax_t wcstoumax(const wchar_t * __restrict,
+ wchar_t ** __restrict, int);
__END_DECLS
#endif /* !_INTTYPES_H_ */
diff --git a/include/netdb.h b/include/netdb.h
index 2132044..2c2e4b3 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -82,6 +82,7 @@ typedef __uint32_t uint32_t;
#define _PATH_NETWORKS "/etc/networks"
#define _PATH_PROTOCOLS "/etc/protocols"
#define _PATH_SERVICES "/etc/services"
+#define _PATH_SERVICES_DB "/var/db/services.db"
#define h_errno (*__h_errno())
diff --git a/include/nsswitch.h b/include/nsswitch.h
index 0ff6cf1..1a97cea 100644
--- a/include/nsswitch.h
+++ b/include/nsswitch.h
@@ -58,6 +58,7 @@
* currently implemented sources
*/
#define NSSRC_FILES "files" /* local files */
+#define NSSRC_DB "db" /* database */
#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */
#define NSSRC_NIS "nis" /* YP/NIS */
#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */
diff --git a/include/regexp.h b/include/regexp.h
deleted file mode 100644
index 3a8d325..0000000
--- a/include/regexp.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1986 by University of Toronto.
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley
- * by Henry Spencer.
- *
- * 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.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- *
- * @(#)regexp.h 8.1 (Berkeley) 6/2/93
- * $FreeBSD$
- */
-
-#ifndef _REGEXP_H_
-#define _REGEXP_H_
-
-/*
- * Definitions etc. for regexp(3) routines.
- *
- * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
- * not the System V one.
- */
-#define NSUBEXP 10
-typedef struct regexp {
- char *startp[NSUBEXP];
- char *endp[NSUBEXP];
- char regstart; /* Internal use only. */
- char reganch; /* Internal use only. */
- char *regmust; /* Internal use only. */
- int regmlen; /* Internal use only. */
- char program[1]; /* Unwarranted chumminess with compiler. */
-} regexp;
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-regexp *regcomp(const char *);
-int regexec(const regexp *, const char *);
-void regsub(const regexp *, const char *, char *);
-void regerror(const char *);
-__END_DECLS
-
-#endif /* !_REGEXP_H_ */
diff --git a/include/stdlib.h b/include/stdlib.h
index b8cd1a3..3c48f17 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -155,6 +155,7 @@ void _Exit(int) __dead2;
#if __POSIX_VISIBLE /* >= ??? */
int posix_memalign(void **, size_t, size_t); /* (ADV) */
int rand_r(unsigned *); /* (TSF) */
+char *realpath(const char * __restrict, char * __restrict);
int setenv(const char *, const char *, int);
int unsetenv(const char *);
#endif
@@ -201,7 +202,6 @@ int posix_openpt(int);
char *ptsname(int);
int putenv(char *);
long random(void);
-char *realpath(const char *, char resolved_path[]);
unsigned short
*seed48(unsigned short[3]);
#ifndef _SETKEY_DECLARED
diff --git a/include/utmp.h b/include/utmp.h
deleted file mode 100644
index 8e1363c..0000000
--- a/include/utmp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-#error "<utmp.h> has been replaced by <utmpx.h>"
diff --git a/lib/Makefile b/lib/Makefile
index c661a4b..68f163e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -9,8 +9,8 @@
# csu must be built before all shared libaries for ELF.
# libc must be built before all other shared libraries.
# libbsm must be built before ibauditd.
-# libcom_err must be built before libkrb5 and libpam.
-# libcrypt must be built before libkrb5 and libpam.
+# libcom_err must be built before libpam.
+# libcrypt must be built before libpam.
# libkvm must be built before libdevstat.
# msun must be built before libg++ and libstdc++.
# libmd must be built before libatm, libopie, libradius, and libtacplus.
@@ -26,21 +26,87 @@
# libgssapi must be built before librpcsec_gss
#
# Otherwise, the SUBDIR list should be in alphabetical order.
-
-SUBDIR= ${_csu} libc libbsm libauditd libcom_err libcrypt libelf libkvm msun \
+#
+# Except it appears bind needs to be compiled last
+
+SUBDIR_ORDERED= ${_csu} \
+ libc \
+ libbsm \
+ libauditd \
+ libcom_err \
+ libcrypt \
+ libelf \
+ libkvm \
+ msun \
libmd \
- ncurses ${_libnetgraph} libradius librpcsvc libsbuf \
- libtacplus libutil ${_libypclnt} libalias libarchive \
- ${_libatm} libbegemot ${_libbluetooth} ${_libbsnmp} libbz2 \
- libcalendar libcam libcompat libdevinfo libdevstat libdisk \
- libdwarf libedit ${_libefi} libexpat libfetch libftpio libgeom \
- ${_libgpib} ${_libgssapi} ${_librpcsec_gss} libipsec \
- ${_libipx} libjail libkiconv libmagic libmemstat ${_libmilter} \
- ${_libmp} ${_libncp} ${_libngatm} libopie libpam libpcap \
- ${_libpmc} libproc librt ${_libsdp} ${_libsm} ${_libsmb} \
- ${_libsmdb} ${_libsmutil} libstand \
- ${_libtelnet} ${_libthr} libthread_db libufs libugidfw libulog \
- ${_libusbhid} ${_libusb} ${_libvgl} libwrap liby libz \
+ ncurses \
+ ${_libnetgraph} \
+ libradius \
+ librpcsvc \
+ libsbuf \
+ libtacplus \
+ libutil \
+ ${_libypclnt}
+
+SUBDIR= ${SUBDIR_ORDERED} \
+ libalias \
+ libarchive \
+ ${_libatm} \
+ libbegemot \
+ ${_libbluetooth} \
+ ${_libbsnmp} \
+ libbz2 \
+ libcalendar \
+ libcam \
+ libcompat \
+ libdevinfo \
+ libdevstat \
+ libdisk \
+ libdwarf \
+ libedit \
+ ${_libefi} \
+ libexpat \
+ libfetch \
+ libftpio \
+ libgeom \
+ ${_libgpib} \
+ ${_libgssapi} \
+ ${_librpcsec_gss} \
+ libipsec \
+ ${_libipx} \
+ libjail \
+ libkiconv \
+ libmagic \
+ libmemstat \
+ ${_libmilter} \
+ ${_libmp} \
+ ${_libncp} \
+ ${_libngatm} \
+ libopie \
+ libpam \
+ libpcap \
+ ${_libpkg} \
+ ${_libpmc} \
+ libproc \
+ librt \
+ ${_libsdp} \
+ ${_libsm} \
+ ${_libsmb} \
+ ${_libsmdb} \
+ ${_libsmutil} \
+ libstand \
+ ${_libtelnet} \
+ ${_libthr} \
+ libthread_db \
+ libufs \
+ libugidfw \
+ libulog \
+ ${_libusbhid} \
+ ${_libusb} \
+ ${_libvgl} \
+ libwrap \
+ liby \
+ libz \
${_bind}
.if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf)
@@ -132,6 +198,10 @@ _libmp= libmp
_libpmc= libpmc
.endif
+.if ${MK_PKGTOOLS} != "no"
+_libpkg= libpkg
+.endif
+
.if ${MK_SENDMAIL} != "no"
_libmilter= libmilter
_libsm= libsm
diff --git a/lib/bind/config.h b/lib/bind/config.h
index 1d68450..3038b5b 100644
--- a/lib/bind/config.h
+++ b/lib/bind/config.h
@@ -166,6 +166,12 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
+/* Define to 1 if you have the `EVP_sha256' function. */
+#define HAVE_EVP_SHA256 1
+
+/* Define to 1 if you have the `EVP_sha512' function. */
+#define HAVE_EVP_SHA512 1
+
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
diff --git a/lib/csu/Makefile.inc b/lib/csu/Makefile.inc
index 51e9fdf..078cb9f 100644
--- a/lib/csu/Makefile.inc
+++ b/lib/csu/Makefile.inc
@@ -2,4 +2,4 @@
SSP_CFLAGS=
-WARNS?= 6
+.include "../Makefile.inc"
diff --git a/lib/csu/amd64/crt1.c b/lib/csu/amd64/crt1.c
index 943b07b..3bc4809 100644
--- a/lib/csu/amd64/crt1.c
+++ b/lib/csu/amd64/crt1.c
@@ -43,7 +43,6 @@ typedef void (*fptr)(void);
extern void _fini(void);
extern void _init(void);
extern int main(int, char **, char **);
-extern void _start(char **, void (*)(void));
#ifdef GCRT
extern void _mcleanup(void);
@@ -55,6 +54,8 @@ extern int etext;
char **environ;
const char *__progname = "";
+void _start(char **, void (*)(void));
+
/* The entry function. */
void
_start(char **ap, void (*cleanup)(void))
diff --git a/lib/csu/arm/Makefile b/lib/csu/arm/Makefile
index da0eb12..c018284 100644
--- a/lib/csu/arm/Makefile
+++ b/lib/csu/arm/Makefile
@@ -5,12 +5,9 @@
SRCS= crt1.c crti.S crtn.S
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
OBJS+= Scrt1.o gcrt1.o
-CFLAGS+= -Wall -Wno-unused \
- -I${.CURDIR}/../common \
+CFLAGS+= -I${.CURDIR}/../common \
-I${.CURDIR}/../../libc/include
-WARNS?= 2
-
all: ${OBJS}
CLEANFILES= ${OBJS}
diff --git a/lib/csu/arm/crt1.c b/lib/csu/arm/crt1.c
index 02af3c2..4319f17 100644
--- a/lib/csu/arm/crt1.c
+++ b/lib/csu/arm/crt1.c
@@ -74,6 +74,9 @@ char **environ;
const char *__progname = "";
struct ps_strings *__ps_strings;
+void __start(int, char **, char **, struct ps_strings *,
+ const struct Struct_Obj_Entry *, void (*)(void));
+
/* The entry function. */
__asm(" .text \n"
" .align 0 \n"
diff --git a/lib/csu/i386-elf/Makefile b/lib/csu/i386-elf/Makefile
index 8e6f50d..b4d78c2 100644
--- a/lib/csu/i386-elf/Makefile
+++ b/lib/csu/i386-elf/Makefile
@@ -23,7 +23,7 @@ crt1.o: crt1_c.o crt1_s.o
objcopy --localize-symbol _start1 crt1.o
Scrt1_c.o: crt1_c.c
- ${CC} ${CFLAGS} -DGCRT -fPIC -DPIC -c -o Scrt1_c.o ${.CURDIR}/crt1_c.c
+ ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1_c.o ${.CURDIR}/crt1_c.c
Scrt1.o: Scrt1_c.o crt1_s.o
${LD} ${LDFLAGS} -o Scrt1.o -r crt1_s.o Scrt1_c.o
diff --git a/lib/csu/ia64/Makefile b/lib/csu/ia64/Makefile
index d795103..781c458 100644
--- a/lib/csu/ia64/Makefile
+++ b/lib/csu/ia64/Makefile
@@ -5,8 +5,7 @@
SRCS= crt1.S crti.S crtn.S
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
OBJS+= Scrt1.o gcrt1.o
-CFLAGS+= -Wall -Wno-unused \
- -I${.CURDIR}/../common \
+CFLAGS+= -I${.CURDIR}/../common \
-I${.CURDIR}/../../libc/include
all: ${OBJS}
diff --git a/lib/csu/mips/Makefile b/lib/csu/mips/Makefile
index da0eb12..c018284 100644
--- a/lib/csu/mips/Makefile
+++ b/lib/csu/mips/Makefile
@@ -5,12 +5,9 @@
SRCS= crt1.c crti.S crtn.S
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
OBJS+= Scrt1.o gcrt1.o
-CFLAGS+= -Wall -Wno-unused \
- -I${.CURDIR}/../common \
+CFLAGS+= -I${.CURDIR}/../common \
-I${.CURDIR}/../../libc/include
-WARNS?= 2
-
all: ${OBJS}
CLEANFILES= ${OBJS}
diff --git a/lib/csu/mips/crt1.c b/lib/csu/mips/crt1.c
index 746cee2..fd00258 100644
--- a/lib/csu/mips/crt1.c
+++ b/lib/csu/mips/crt1.c
@@ -66,15 +66,14 @@ extern int etext;
char **environ;
const char *__progname = "";
-void __gccmain(void) {}
-void __main(void) {}
+void __start(char **, void (*)(void), struct Struct_Obj_Entry *, struct ps_strings *);
/* The entry function. */
void
__start(char **ap,
void (*cleanup)(void), /* from shared loader */
- struct Struct_Obj_Entry *obj, /* from shared loader */
- struct ps_strings *ps_strings)
+ struct Struct_Obj_Entry *obj __unused, /* from shared loader */
+ struct ps_strings *ps_strings __unused)
{
int argc;
char **argv;
diff --git a/lib/csu/mips/crti.S b/lib/csu/mips/crti.S
index 1a0d23e..cada08d 100644
--- a/lib/csu/mips/crti.S
+++ b/lib/csu/mips/crti.S
@@ -6,32 +6,45 @@ __FBSDID("$FreeBSD$");
.globl _init
.type _init,%function
_init:
-#ifdef __ABICALLS__
- .set noreorder
- .cpload $25
- .set reorder
- subu sp, sp, 32
- .cprestore 16
- sw ra, 28(sp)
-
+ .set noreorder
+#if defined(__ABICALLS__) && (defined(__mips_o32) || defined(__mips_o64))
+ SETUP_GP
+#endif
+ PTR_ADDU sp, sp, -CALLFRAME_SIZ
+ REG_S ra, CALLFRAME_RA(sp)
+#if defined(__ABICALLS__)
+#if defined(__mips_o32) || defined(__mips_o64)
+ SAVE_GP(CALLFRAME_GP)
#else
- subu sp, sp, 32
- sw ra, 28(sp)
+ SETUP_GP64(CALLFRAME_GP, _init)
+#endif
+#else /* __ABICALLS__ */
+#if defined(__mips_n32) || defined(__mips_n64)
+ REG_S gp, CALLFRAME_GP(sp)
+#endif
#endif
+ .set reorder
.section .fini,"ax",%progbits
.align 4
.globl _fini
.type _fini,%function
_fini:
-#ifdef __ABICALLS__
- .set noreorder
- .cpload $25
- .set reorder
- subu sp, sp, 32
- .cprestore 16
- sw ra, 28(sp)
+ .set noreorder
+#if defined(__ABICALLS__) && (defined(__mips_o32) || defined(__mips_o64))
+ SETUP_GP
+#endif
+ PTR_ADDU sp, sp, -CALLFRAME_SIZ
+ REG_S ra, CALLFRAME_RA(sp)
+#if defined(__ABICALLS__)
+#if defined(__mips_o32) || defined(__mips_o64)
+ SAVE_GP(CALLFRAME_GP)
#else
- subu sp, sp, 32
- sw ra, 28(sp)
+ SETUP_GP64(CALLFRAME_GP, _fini)
+#endif
+#else /* __ABICALLS__ */
+#if defined(__mips_n32) || defined(__mips_n64)
+ REG_S gp, CALLFRAME_GP(sp)
+#endif
#endif
+ .set reorder
diff --git a/lib/csu/mips/crtn.S b/lib/csu/mips/crtn.S
index 4803994..8d190f8 100644
--- a/lib/csu/mips/crtn.S
+++ b/lib/csu/mips/crtn.S
@@ -1,15 +1,24 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
+
.section .init,"ax",%progbits
- lw ra, 28(sp)
- .set noreorder
- j ra
- addu sp, sp, 32
- .set reorder
+ .align 4
+ .set noreorder
+#if defined(__ABICALLS__) && (defined(__mips_n32) || defined(__mips_n64))
+ REG_L gp, CALLFRAME_GP(sp)
+#endif
+ REG_L ra, CALLFRAME_RA(sp)
+ jr ra
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
+ .set reorder
.section .fini,"ax",%progbits
- lw ra, 28(sp)
- .set noreorder
- j ra
- addu sp, sp, 32
- .set reorder
+ .align 4
+ .set noreorder
+#if defined(__ABICALLS__) && (defined(__mips_n32) || defined(__mips_n64))
+ REG_L gp, CALLFRAME_GP(sp)
+#endif
+ REG_L ra, CALLFRAME_RA(sp)
+ jr ra
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
+ .set reorder
diff --git a/lib/csu/powerpc/Makefile b/lib/csu/powerpc/Makefile
index 097f82d..c018284 100644
--- a/lib/csu/powerpc/Makefile
+++ b/lib/csu/powerpc/Makefile
@@ -5,8 +5,7 @@
SRCS= crt1.c crti.S crtn.S
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
OBJS+= Scrt1.o gcrt1.o
-CFLAGS+= -Wall -Wno-unused \
- -I${.CURDIR}/../common \
+CFLAGS+= -I${.CURDIR}/../common \
-I${.CURDIR}/../../libc/include
all: ${OBJS}
diff --git a/lib/csu/powerpc/crt1.c b/lib/csu/powerpc/crt1.c
index 080691c..3a2f6dd 100644
--- a/lib/csu/powerpc/crt1.c
+++ b/lib/csu/powerpc/crt1.c
@@ -59,8 +59,6 @@ extern int _DYNAMIC;
extern void _fini(void);
extern void _init(void);
extern int main(int, char **, char **);
-extern void _start(int, char **, char **, const struct Struct_Obj_Entry *,
- void (*)(void), struct ps_strings *);
#ifdef GCRT
extern void _mcleanup(void);
@@ -73,6 +71,9 @@ char **environ;
const char *__progname = "";
struct ps_strings *__ps_strings;
+void _start(int, char **, char **, const struct Struct_Obj_Entry *,
+ void (*)(void), struct ps_strings *);
+
/* The entry function. */
/*
* First 5 arguments are specified by the PowerPC SVR4 ABI.
diff --git a/lib/csu/sparc64/crt1.c b/lib/csu/sparc64/crt1.c
index 5d8e371..f27c59b 100644
--- a/lib/csu/sparc64/crt1.c
+++ b/lib/csu/sparc64/crt1.c
@@ -50,8 +50,6 @@ extern int _DYNAMIC;
extern void _fini(void);
extern void _init(void);
extern int main(int, char **, char **);
-extern void _start(char **, void (*)(void), struct Struct_Obj_Entry *,
- struct ps_strings *);
extern void __sparc_utrap_setup(void);
#ifdef GCRT
@@ -64,6 +62,9 @@ extern int etext;
char **environ;
const char *__progname = "";
+void _start(char **, void (*)(void), struct Struct_Obj_Entry *,
+ struct ps_strings *);
+
/* The entry function. */
/*
* %o0 holds ps_strings pointer.
diff --git a/lib/libalias/Makefile.inc b/lib/libalias/Makefile.inc
new file mode 100644
index 0000000..265f86d
--- /dev/null
+++ b/lib/libalias/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+.include "../Makefile.inc"
diff --git a/lib/libalias/libalias/Makefile b/lib/libalias/libalias/Makefile
index a3f9889..00b4ed8 100644
--- a/lib/libalias/libalias/Makefile
+++ b/lib/libalias/libalias/Makefile
@@ -8,7 +8,6 @@ SHLIB_MAJOR= 7
MAN= libalias.3
SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_mod.c
INCS= alias.h
-WARNS?= 6
NO_WERROR=
.include <bsd.lib.mk>
diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile
index ab65da3..c721f57 100644
--- a/lib/libarchive/test/Makefile
+++ b/lib/libarchive/test/Makefile
@@ -137,7 +137,6 @@ CFLAGS+= -I${LA_SRCDIR} -I.
# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
#CFLAGS+= -I/usr/local/include -DUSE_DMALLOC
-#WARNS=6
# Build libarchive_test and run it.
check test: libarchive_test
diff --git a/lib/libbsnmp/Makefile.inc b/lib/libbsnmp/Makefile.inc
index 566274c..82f48ac 100644
--- a/lib/libbsnmp/Makefile.inc
+++ b/lib/libbsnmp/Makefile.inc
@@ -1,6 +1,6 @@
# $FreeBSD$
-SHLIB_MAJOR= 5
-WARNS?= 6
NO_WERROR=
INCSDIR= ${INCLUDEDIR}/bsnmp
+
+.include "../Makefile.inc"
diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile
index 91351c0..a0ceecd 100644
--- a/lib/libbsnmp/libbsnmp/Makefile
+++ b/lib/libbsnmp/libbsnmp/Makefile
@@ -5,9 +5,8 @@
CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
.PATH: ${CONTRIB}
-LIB = bsnmp
-SHLIBDIR ?= /lib
-WARNS ?= 6
+LIB= bsnmp
+SHLIBDIR?= /lib
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
diff --git a/lib/libc/arm/gen/makecontext.c b/lib/libc/arm/gen/makecontext.c
index 4fd3953..4b0f92d 100644
--- a/lib/libc/arm/gen/makecontext.c
+++ b/lib/libc/arm/gen/makecontext.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/arm/string/bzero.S b/lib/libc/arm/string/bzero.S
index 008c485..b31358d 100644
--- a/lib/libc/arm/string/bzero.S
+++ b/lib/libc/arm/string/bzero.S
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/arm/string/memcpy_arm.S b/lib/libc/arm/string/memcpy_arm.S
index 005c8c2..b84a32e 100644
--- a/lib/libc/arm/string/memcpy_arm.S
+++ b/lib/libc/arm/string/memcpy_arm.S
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/arm/string/memmove.S b/lib/libc/arm/string/memmove.S
index f65a254..8b8baaf 100644
--- a/lib/libc/arm/string/memmove.S
+++ b/lib/libc/arm/string/memmove.S
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/compat-43/sigpause.2 b/lib/libc/compat-43/sigpause.2
index bf3cf0b..d6271f1 100644
--- a/lib/libc/compat-43/sigpause.2
+++ b/lib/libc/compat-43/sigpause.2
@@ -195,6 +195,7 @@ functions, an attempt was made to catch or ignore
.Dv SIGKILL
or
.Dv SIGSTOP .
+.El
.Sh SEE ALSO
.Xr kill 2 ,
.Xr sigaction 2 ,
diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
index 83d2657..638814c 100644
--- a/lib/libc/db/hash/hash.c
+++ b/lib/libc/db/hash/hash.c
@@ -293,6 +293,8 @@ init_hash(HTAB *hashp, const char *file, const HASHINFO *info)
if (stat(file, &statbuf))
return (NULL);
hashp->BSIZE = statbuf.st_blksize;
+ if (hashp->BSIZE > MAX_BSIZE)
+ hashp->BSIZE = MAX_BSIZE;
hashp->BSHIFT = __log2(hashp->BSIZE);
}
diff --git a/lib/libc/db/hash/hash.h b/lib/libc/db/hash/hash.h
index 8329413..cd11a3a 100644
--- a/lib/libc/db/hash/hash.h
+++ b/lib/libc/db/hash/hash.h
@@ -118,7 +118,7 @@ typedef struct htab { /* Memory resident data structure */
/*
* Constants
*/
-#define MAX_BSIZE 65536 /* 2^16 */
+#define MAX_BSIZE 32768 /* 2^15 but should be 65536 */
#define MIN_BUFFERS 6
#define MINHDRSIZE 512
#define DEF_BUFSIZE 65536 /* 64 K */
diff --git a/lib/libc/db/man/hash.3 b/lib/libc/db/man/hash.3
index 6724042..133885d 100644
--- a/lib/libc/db/man/hash.3
+++ b/lib/libc/db/man/hash.3
@@ -78,7 +78,7 @@ The
element
defines the
.Nm
-table bucket size, and is, by default, 256 bytes.
+table bucket size, and is, by default, 4096 bytes.
It may be preferable to increase the page size for disk-resident tables
and tables with large data items.
.It Va ffactor
diff --git a/lib/libc/gen/__getosreldate.c b/lib/libc/gen/__getosreldate.c
index 69aac07..7e26845 100644
--- a/lib/libc/gen/__getosreldate.c
+++ b/lib/libc/gen/__getosreldate.c
@@ -30,6 +30,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/sysctl.h>
+int __getosreldate(void);
+
/*
* This is private to libc. It is intended for wrapping syscall stubs in order
* to avoid having to put SIGSYS signal handlers in place to test for presence
diff --git a/lib/libc/gen/_spinlock_stub.c b/lib/libc/gen/_spinlock_stub.c
index a130c8e..47bbfeb 100644
--- a/lib/libc/gen/_spinlock_stub.c
+++ b/lib/libc/gen/_spinlock_stub.c
@@ -34,6 +34,11 @@ __FBSDID("$FreeBSD$");
#include "spinlock.h"
+long _atomic_lock_stub(volatile long *);
+void _spinlock_stub(spinlock_t *);
+void _spinunlock_stub(spinlock_t *);
+void _spinlock_debug_stub(spinlock_t *, char *, int);
+
/*
* Declare weak definitions in case the application is not linked
* with libpthread.
@@ -43,12 +48,11 @@ __weak_reference(_spinlock_stub, _spinlock);
__weak_reference(_spinunlock_stub, _spinunlock);
__weak_reference(_spinlock_debug_stub, _spinlock_debug);
-
/*
* This function is a stub for the _atomic_lock function in libpthread.
*/
long
-_atomic_lock_stub(volatile long *lck)
+_atomic_lock_stub(volatile long *lck __unused)
{
return (0L);
}
@@ -58,7 +62,7 @@ _atomic_lock_stub(volatile long *lck)
* This function is a stub for the spinlock function in libpthread.
*/
void
-_spinlock_stub(spinlock_t *lck)
+_spinlock_stub(spinlock_t *lck __unused)
{
}
@@ -66,7 +70,7 @@ _spinlock_stub(spinlock_t *lck)
* This function is a stub for the spinunlock function in libpthread.
*/
void
-_spinunlock_stub(spinlock_t *lck)
+_spinunlock_stub(spinlock_t *lck __unused)
{
}
@@ -74,6 +78,6 @@ _spinunlock_stub(spinlock_t *lck)
* This function is a stub for the debug spinlock function in libpthread.
*/
void
-_spinlock_debug_stub(spinlock_t *lck, char *fname, int lineno)
+_spinlock_debug_stub(spinlock_t *lck __unused, char *fname __unused, int lineno __unused)
{
}
diff --git a/lib/libc/gen/_thread_init.c b/lib/libc/gen/_thread_init.c
index acaf65c..e770ee4 100644
--- a/lib/libc/gen/_thread_init.c
+++ b/lib/libc/gen/_thread_init.c
@@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
+void _thread_init_stub(void);
+
__weak_reference(_thread_init_stub, _thread_init);
__weak_reference(_thread_autoinit_dummy_decl_stub, _thread_autoinit_dummy_decl);
diff --git a/lib/libc/gen/check_utility_compat.3 b/lib/libc/gen/check_utility_compat.3
index 7a96bac..57638e5 100644
--- a/lib/libc/gen/check_utility_compat.3
+++ b/lib/libc/gen/check_utility_compat.3
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd October 27, 2002
-.Os
.Dt CHECK_UTILITY_COMPAT 3
+.Os
.Sh NAME
.Nm check_utility_compat
.Nd "determine whether a utility should be compatible"
diff --git a/lib/libc/gen/confstr.3 b/lib/libc/gen/confstr.3
index e97505f..3066aae 100644
--- a/lib/libc/gen/confstr.3
+++ b/lib/libc/gen/confstr.3
@@ -79,7 +79,6 @@ The copied value is always null terminated.
The available values are as follows:
.Pp
.Bl -tag -width 6n
-.Pp
.It Li _CS_PATH
Return a value for the
.Ev PATH
diff --git a/lib/libc/gen/daemon.c b/lib/libc/gen/daemon.c
index ba2a542..b359a87 100644
--- a/lib/libc/gen/daemon.c
+++ b/lib/libc/gen/daemon.c
@@ -64,6 +64,10 @@ daemon(nochdir, noclose)
case 0:
break;
default:
+ /*
+ * A fine point: _exit(0), not exit(0), to avoid triggering
+ * atexit(3) processing
+ */
_exit(0);
}
diff --git a/lib/libc/gen/dladdr.3 b/lib/libc/gen/dladdr.3
index 414fa49..6566279 100644
--- a/lib/libc/gen/dladdr.3
+++ b/lib/libc/gen/dladdr.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd February 5, 1998
-.Os
.Dt DLADDR 3
+.Os
.Sh NAME
.Nm dladdr
.Nd find the shared object containing a given address
diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c
index 4be8847..a1ca29d 100644
--- a/lib/libc/gen/dlfcn.c
+++ b/lib/libc/gen/dlfcn.c
@@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#include <link.h>
#include <stddef.h>
-static const char sorry[] = "Service unavailable";
+static char sorry[] = "Service unavailable";
/*
* For ELF, the dynamic linker directly resolves references to its
@@ -69,7 +69,7 @@ dlclose(void *handle)
}
#pragma weak dlerror
-const char *
+char *
dlerror(void)
{
return sorry;
diff --git a/lib/libc/gen/dlinfo.3 b/lib/libc/gen/dlinfo.3
index 9433fb6..d00f074 100644
--- a/lib/libc/gen/dlinfo.3
+++ b/lib/libc/gen/dlinfo.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd February 14, 2003
-.Os
.Dt DLINFO 3
+.Os
.Sh NAME
.Nm dlinfo
.Nd information about dynamically loaded object
diff --git a/lib/libc/gen/dllockinit.3 b/lib/libc/gen/dllockinit.3
index 98d1074..be3e2ca 100644
--- a/lib/libc/gen/dllockinit.3
+++ b/lib/libc/gen/dllockinit.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd July 5, 2000
-.Os
.Dt DLLOCKINIT 3
+.Os
.Sh NAME
.Nm dllockinit
.Nd register thread locking methods with the dynamic linker
diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3
index 6488bef..45b0139 100644
--- a/lib/libc/gen/dlopen.3
+++ b/lib/libc/gen/dlopen.3
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd July 7, 2009
-.Os
.Dt DLOPEN 3
+.Os
.Sh NAME
.Nm dlopen ,
.Nm dlsym ,
@@ -52,7 +52,7 @@
.Fn dlsym "void * restrict handle" "const char * restrict symbol"
.Ft dlfunc_t
.Fn dlfunc "void * restrict handle" "const char * restrict symbol"
-.Ft const char *
+.Ft char *
.Fn dlerror "void"
.Ft int
.Fn dlclose "void *handle"
diff --git a/lib/libc/gen/fmtcheck.3 b/lib/libc/gen/fmtcheck.3
index 782526d..2fa587b 100644
--- a/lib/libc/gen/fmtcheck.3
+++ b/lib/libc/gen/fmtcheck.3
@@ -11,13 +11,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -33,8 +26,8 @@
.\"
.\" $FreeBSD$
.Dd October 16, 2002
-.Os
.Dt FMTCHECK 3
+.Os
.Sh NAME
.Nm fmtcheck
.Nd sanitizes user-supplied
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c
index e697bdc..3acbc3b 100644
--- a/lib/libc/gen/fnmatch.c
+++ b/lib/libc/gen/fnmatch.c
@@ -67,7 +67,8 @@ __FBSDID("$FreeBSD$");
#define RANGE_ERROR (-1)
static int rangematch(const char *, wchar_t, int, char **, mbstate_t *);
-static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t);
+static int fnmatch1(const char *, const char *, const char *, int, mbstate_t,
+ mbstate_t);
int
fnmatch(pattern, string, flags)
@@ -76,22 +77,21 @@ fnmatch(pattern, string, flags)
{
static const mbstate_t initial;
- return (fnmatch1(pattern, string, flags, initial, initial));
+ return (fnmatch1(pattern, string, string, flags, initial, initial));
}
static int
-fnmatch1(pattern, string, flags, patmbs, strmbs)
- const char *pattern, *string;
+fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs)
+ const char *pattern, *string, *stringstart;
int flags;
mbstate_t patmbs, strmbs;
{
- const char *stringstart;
char *newp;
char c;
wchar_t pc, sc;
size_t pclen, sclen;
- for (stringstart = string;;) {
+ for (;;) {
pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs);
if (pclen == (size_t)-1 || pclen == (size_t)-2)
return (FNM_NOMATCH);
@@ -145,8 +145,8 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
/* General case, use recursion. */
while (sc != EOS) {
- if (!fnmatch1(pattern, string,
- flags & ~FNM_PERIOD, patmbs, strmbs))
+ if (!fnmatch1(pattern, string, stringstart,
+ flags, patmbs, strmbs))
return (0);
sclen = mbrtowc(&sc, string, MB_LEN_MAX,
&strmbs);
diff --git a/lib/libc/gen/frexp.3 b/lib/libc/gen/frexp.3
index 390da75..ba33d3d 100644
--- a/lib/libc/gen/frexp.3
+++ b/lib/libc/gen/frexp.3
@@ -70,7 +70,7 @@ such that
is a
.Vt double
with magnitude in the interval
-.Bo 1/2 , 1 Pc
+.Eo [ 1/2 , 1 Ec )
or zero, and
.Fa value
equals
diff --git a/lib/libc/gen/ftok.3 b/lib/libc/gen/ftok.3
index 78bfe45..996b2da 100644
--- a/lib/libc/gen/ftok.3
+++ b/lib/libc/gen/ftok.3
@@ -25,8 +25,8 @@
.\"
.\" $FreeBSD$
.Dd July 9, 2009
-.Os
.Dt FTOK 3
+.Os
.Sh NAME
.Nm ftok
.Nd create IPC identifier from path name
diff --git a/lib/libc/gen/getcwd.3 b/lib/libc/gen/getcwd.3
index 12a2bd6..88291c3 100644
--- a/lib/libc/gen/getcwd.3
+++ b/lib/libc/gen/getcwd.3
@@ -28,7 +28,7 @@
.\" @(#)getcwd.3 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd November 24, 1997
+.Dd April 17, 2010
.Dt GETCWD 3
.Os
.Sh NAME
@@ -108,8 +108,6 @@ The
function
will fail if:
.Bl -tag -width Er
-.It Bq Er EACCES
-Read or search permission was denied for a component of the pathname.
.It Bq Er EINVAL
The
.Fa size
@@ -124,6 +122,16 @@ The
argument is greater than zero but smaller than the length of the pathname
plus 1.
.El
+.Pp
+The
+.Fn getcwd
+function
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Read or search permission was denied for a component of the pathname.
+This is only checked in limited cases, depending on implementation details.
+.El
.Sh SEE ALSO
.Xr chdir 2 ,
.Xr fchdir 2 ,
diff --git a/lib/libc/gen/getutxent.3 b/lib/libc/gen/getutxent.3
index 5ab21ee..ccc5d9e 100644
--- a/lib/libc/gen/getutxent.3
+++ b/lib/libc/gen/getutxent.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 8, 2010
-.Os
.Dt GETUTXENT 3
+.Os
.Sh NAME
.Nm endutxent ,
.Nm getutxent ,
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
index b312c89..0c08735 100644
--- a/lib/libc/gen/opendir.c
+++ b/lib/libc/gen/opendir.c
@@ -86,7 +86,7 @@ __opendir2(const char *name, int flags)
errno = ENOTDIR;
return (NULL);
}
- if ((fd = _open(name, O_RDONLY | O_NONBLOCK)) == -1)
+ if ((fd = _open(name, O_RDONLY | O_NONBLOCK | O_DIRECTORY)) == -1)
return (NULL);
return __opendir_common(fd, name, flags);
@@ -200,7 +200,7 @@ __opendir_common(int fd, const char *name, int flags)
*/
if (flags & DTF_REWIND) {
(void)_close(fd);
- if ((fd = _open(name, O_RDONLY)) == -1) {
+ if ((fd = _open(name, O_RDONLY | O_DIRECTORY)) == -1) {
saved_errno = errno;
free(buf);
free(dirp);
diff --git a/lib/libc/gen/setproctitle.3 b/lib/libc/gen/setproctitle.3
index fe9f19a..73dc8c0 100644
--- a/lib/libc/gen/setproctitle.3
+++ b/lib/libc/gen/setproctitle.3
@@ -21,8 +21,8 @@
.\"
.\" The following requests are required for all man pages.
.Dd December 16, 1995
-.Os
.Dt SETPROCTITLE 3
+.Os
.Sh NAME
.Nm setproctitle
.Nd set process title
diff --git a/lib/libc/gen/stringlist.3 b/lib/libc/gen/stringlist.3
index 30dd299..c55b77d 100644
--- a/lib/libc/gen/stringlist.3
+++ b/lib/libc/gen/stringlist.3
@@ -13,13 +13,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -36,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd November 28, 1999
-.Os
.Dt STRINGLIST 3
+.Os
.Sh NAME
.Nm stringlist ,
.Nm sl_init ,
diff --git a/lib/libc/gen/sysconf.3 b/lib/libc/gen/sysconf.3
index b17d8a8..05766cc 100644
--- a/lib/libc/gen/sysconf.3
+++ b/lib/libc/gen/sysconf.3
@@ -60,9 +60,7 @@ Shell programmers who need access to these parameters should use the
utility.
.Pp
The available values are as follows:
-.Pp
.Bl -tag -width 6n
-.Pp
.It Li _SC_ARG_MAX
The maximum bytes of argument to
.Xr execve 2 .
@@ -165,9 +163,7 @@ otherwise \-1.
.El
.Pp
These values also exist, but may not be standard:
-.Pp
.Bl -tag -width 6n
-.Pp
.It Li _SC_PHYS_PAGES
The number of pages of physical memory.
Note that it is possible that the product of this value and the value of
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
index 143be16..9eba624 100644
--- a/lib/libc/gen/sysctl.3
+++ b/lib/libc/gen/sysctl.3
@@ -28,7 +28,7 @@
.\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
-.Dd February 21, 2010
+.Dd April 25, 2010
.Dt SYSCTL 3
.Os
.Sh NAME
@@ -286,7 +286,6 @@ privilege may change the value.
.It "HW_MACHINE_ARCH string no"
.It "HW_REALMEM integer no"
.El
-.Pp
.Bl -tag -width 6n
.It Li HW_MACHINE
The machine class.
@@ -326,7 +325,7 @@ information.
.It "KERN_BOOTFILE string yes"
.It "KERN_BOOTTIME struct timeval no"
.It "KERN_CLOCKRATE struct clockinfo no"
-.It "KERN_FILE struct file no"
+.It "KERN_FILE struct xfile no"
.It "KERN_HOSTID integer yes"
.It "KERN_HOSTUUID string yes"
.It "KERN_HOSTNAME string yes"
@@ -343,16 +342,15 @@ information.
.It "KERN_OSREV integer no"
.It "KERN_OSTYPE string no"
.It "KERN_POSIX1 integer no"
-.It "KERN_PROC struct proc no"
+.It "KERN_PROC node not applicable"
.It "KERN_PROF node not applicable"
.It "KERN_QUANTUM integer yes"
.It "KERN_SAVED_IDS integer no"
.It "KERN_SECURELVL integer raise only"
.It "KERN_UPDATEINTERVAL integer no"
.It "KERN_VERSION string no"
-.It "KERN_VNODE struct vnode no"
+.It "KERN_VNODE struct xvnode no"
.El
-.Pp
.Bl -tag -width 6n
.It Li KERN_ARGMAX
The maximum bytes of argument to
@@ -372,10 +370,8 @@ This structure contains the clock, statistics clock and profiling clock
frequencies, the number of micro-seconds per hz tick and the skew rate.
.It Li KERN_FILE
Return the entire file table.
-The returned data consists of a single
-.Va struct filehead
-followed by an array of
-.Va struct file ,
+The returned data consists of an array of
+.Va struct xfile ,
whose size depends on the current number of such objects in the system.
.It Li KERN_HOSTID
Get or set the host ID.
@@ -527,10 +523,8 @@ Note, the vnode table is not necessarily a consistent snapshot of
the system.
The returned data consists of an array whose size depends on the
current number of such objects in the system.
-Each element of the array contains the kernel address of a vnode
-.Va struct vnode *
-followed by the vnode itself
-.Va struct vnode .
+Each element of the array consists of a
+.Va struct xvnode .
.El
.Ss CTL_NET
The string and integer information available for the CTL_NET level
@@ -543,7 +537,6 @@ privilege may change the value.
.It "PF_INET IPv4 values yes"
.It "PF_INET6 IPv6 values yes"
.El
-.Pp
.Bl -tag -width 6n
.It Li PF_ROUTE
Return the entire routing table or a subset of it.
@@ -650,7 +643,6 @@ privilege may change the value.
.It "USER_TZNAME_MAX integer no"
.El
.Bl -tag -width 6n
-.Pp
.It Li USER_BC_BASE_MAX
The maximum ibase/obase values in the
.Xr bc 1
@@ -740,7 +732,6 @@ privilege may change the value.
.It "VM_V_INACTIVE_TARGET integer yes"
.It "VM_V_PAGEOUT_FREE_MIN integer yes"
.El
-.Pp
.Bl -tag -width 6n
.It Li VM_LOADAVG
Return the load average history.
@@ -859,6 +850,8 @@ An attempt is made to set a read-only value.
A process without appropriate privilege attempts to set a value.
.El
.Sh SEE ALSO
+.Xr confstr 3 ,
+.Xr kvm 3 ,
.Xr sysconf 3 ,
.Xr sysctl 8
.Sh HISTORY
diff --git a/lib/libc/include/reentrant.h b/lib/libc/include/reentrant.h
index 8ab328b..22a2325 100644
--- a/lib/libc/include/reentrant.h
+++ b/lib/libc/include/reentrant.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/locale/isalnum.3 b/lib/libc/locale/isalnum.3
index 624a6e2..038c5cf 100644
--- a/lib/libc/locale/isalnum.3
+++ b/lib/libc/locale/isalnum.3
@@ -59,7 +59,6 @@ or the value of
.Pp
In the ASCII character set, this includes the following characters
(with their numeric values shown in octal):
-.Pp
.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
.It "\&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''"
.It "\&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''"
diff --git a/lib/libc/locale/isalpha.3 b/lib/libc/locale/isalpha.3
index 0bd3cda..689b6cd 100644
--- a/lib/libc/locale/isalpha.3
+++ b/lib/libc/locale/isalpha.3
@@ -59,7 +59,6 @@ or the value of
.Pp
In the ASCII character set, this includes the following characters
(with their numeric values shown in octal):
-.Pp
.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
.It "\&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''"
.It "\&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''"
diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c
index ebb7a7d..3228bdc 100644
--- a/lib/libc/net/getservent.c
+++ b/lib/libc/net/getservent.c
@@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
+#include <db.h>
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#include <nsswitch.h>
@@ -94,6 +96,19 @@ NSS_TLS_HANDLING(files);
static int files_servent(void *, void *, va_list);
static int files_setservent(void *, void *, va_list);
+/* db backend declarations */
+struct db_state
+{
+ DB *db;
+ int stayopen;
+ int keynum;
+};
+static void db_endstate(void *);
+NSS_TLS_HANDLING(db);
+
+static int db_servent(void *, void *, va_list);
+static int db_setservent(void *, void *, va_list);
+
#ifdef YP
/* nis backend declarations */
static int nis_servent(void *, void *, va_list);
@@ -207,6 +222,32 @@ servent_unpack(char *p, struct servent *serv, char **aliases,
return 0;
}
+static int
+parse_result(struct servent *serv, char *buffer, size_t bufsize,
+ char *resultbuf, size_t resultbuflen, int *errnop)
+{
+ char **aliases;
+ int aliases_size;
+
+ if (bufsize <= resultbuflen + _ALIGNBYTES + sizeof(char *)) {
+ *errnop = ERANGE;
+ return (NS_RETURN);
+ }
+ aliases = (char **)_ALIGN(&buffer[resultbuflen + 1]);
+ aliases_size = (buffer + bufsize - (char *)aliases) / sizeof(char *);
+ if (aliases_size < 1) {
+ *errnop = ERANGE;
+ return (NS_RETURN);
+ }
+
+ memcpy(buffer, resultbuf, resultbuflen);
+ buffer[resultbuflen] = '\0';
+
+ if (servent_unpack(buffer, serv, aliases, aliases_size, errnop) != 0)
+ return ((*errnop == 0) ? NS_NOTFOUND : NS_RETURN);
+ return (NS_SUCCESS);
+}
+
/* files backend implementation */
static void
files_endstate(void *p)
@@ -237,6 +278,8 @@ files_servent(void *retval, void *mdata, va_list ap)
{ NULL, 0 }
};
ns_dtab compat_dtab[] = {
+ { NSSRC_DB, db_servent,
+ (void *)((struct servent_mdata *)mdata)->how },
#ifdef YP
{ NSSRC_NIS, nis_servent,
(void *)((struct servent_mdata *)mdata)->how },
@@ -258,8 +301,6 @@ files_servent(void *retval, void *mdata, va_list ap)
size_t bufsize;
int *errnop;
- char **aliases;
- int aliases_size;
size_t linesize;
char *line;
char **cp;
@@ -315,28 +356,8 @@ files_servent(void *retval, void *mdata, va_list ap)
break;
}
- if (*line=='+') {
- if (serv_mdata->compat_mode != 0)
- st->compat_mode_active = 1;
- } else {
- if (bufsize <= linesize + _ALIGNBYTES +
- sizeof(char *)) {
- *errnop = ERANGE;
- rv = NS_RETURN;
- break;
- }
- aliases = (char **)_ALIGN(&buffer[linesize+1]);
- aliases_size = (buffer + bufsize -
- (char *)aliases) / sizeof(char *);
- if (aliases_size < 1) {
- *errnop = ERANGE;
- rv = NS_RETURN;
- break;
- }
-
- memcpy(buffer, line, linesize);
- buffer[linesize] = '\0';
- }
+ if (*line=='+' && serv_mdata->compat_mode != 0)
+ st->compat_mode_active = 1;
}
if (st->compat_mode_active != 0) {
@@ -367,18 +388,12 @@ files_servent(void *retval, void *mdata, va_list ap)
continue;
}
- rv = servent_unpack(buffer, serv, aliases, aliases_size,
+ rv = parse_result(serv, buffer, bufsize, line, linesize,
errnop);
- if (rv !=0 ) {
- if (*errnop == 0) {
- rv = NS_NOTFOUND;
- continue;
- }
- else {
- rv = NS_RETURN;
- break;
- }
- }
+ if (rv == NS_NOTFOUND)
+ continue;
+ if (rv == NS_RETURN)
+ break;
rv = NS_NOTFOUND;
switch (serv_mdata->how) {
@@ -454,6 +469,183 @@ files_setservent(void *retval, void *mdata, va_list ap)
return (NS_UNAVAIL);
}
+/* db backend implementation */
+static void
+db_endstate(void *p)
+{
+ DB *db;
+
+ if (p == NULL)
+ return;
+
+ db = ((struct db_state *)p)->db;
+ if (db != NULL)
+ db->close(db);
+
+ free(p);
+}
+
+static int
+db_servent(void *retval, void *mdata, va_list ap)
+{
+ char buf[BUFSIZ];
+ DBT key, data, *result;
+ DB *db;
+
+ struct db_state *st;
+ int rv;
+ int stayopen;
+
+ enum nss_lookup_type how;
+ char *name;
+ char *proto;
+ int port;
+
+ struct servent *serv;
+ char *buffer;
+ size_t bufsize;
+ int *errnop;
+
+ name = NULL;
+ proto = NULL;
+ how = (enum nss_lookup_type)mdata;
+ switch (how) {
+ case nss_lt_name:
+ name = va_arg(ap, char *);
+ proto = va_arg(ap, char *);
+ break;
+ case nss_lt_id:
+ port = va_arg(ap, int);
+ proto = va_arg(ap, char *);
+ break;
+ case nss_lt_all:
+ break;
+ default:
+ return NS_NOTFOUND;
+ };
+
+ serv = va_arg(ap, struct servent *);
+ buffer = va_arg(ap, char *);
+ bufsize = va_arg(ap, size_t);
+ errnop = va_arg(ap,int *);
+
+ *errnop = db_getstate(&st);
+ if (*errnop != 0)
+ return (NS_UNAVAIL);
+
+ if (how == nss_lt_all && st->keynum < 0)
+ return (NS_NOTFOUND);
+
+ if (st->db == NULL) {
+ st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL);
+ if (st->db == NULL) {
+ *errnop = errno;
+ return (NS_UNAVAIL);
+ }
+ }
+
+ stayopen = (how == nss_lt_all) ? 1 : st->stayopen;
+ db = st->db;
+
+ do {
+ switch (how) {
+ case nss_lt_name:
+ key.data = buf;
+ if (proto == NULL)
+ key.size = snprintf(buf, sizeof(buf),
+ "\376%s", name);
+ else
+ key.size = snprintf(buf, sizeof(buf),
+ "\376%s/%s", name, proto);
+ key.size++;
+ if (db->get(db, &key, &data, 0) != 0 ||
+ db->get(db, &data, &key, 0) != 0) {
+ rv = NS_NOTFOUND;
+ goto db_fin;
+ }
+ result = &key;
+ break;
+ case nss_lt_id:
+ key.data = buf;
+ port = htons(port);
+ if (proto == NULL)
+ key.size = snprintf(buf, sizeof(buf),
+ "\377%d", port);
+ else
+ key.size = snprintf(buf, sizeof(buf),
+ "\377%d/%s", port, proto);
+ key.size++;
+ if (db->get(db, &key, &data, 0) != 0 ||
+ db->get(db, &data, &key, 0) != 0) {
+ rv = NS_NOTFOUND;
+ goto db_fin;
+ }
+ result = &key;
+ break;
+ case nss_lt_all:
+ key.data = buf;
+ key.size = snprintf(buf, sizeof(buf), "%d",
+ st->keynum++);
+ key.size++;
+ if (db->get(db, &key, &data, 0) != 0) {
+ st->keynum = -1;
+ rv = NS_NOTFOUND;
+ goto db_fin;
+ }
+ result = &data;
+ break;
+ }
+
+ rv = parse_result(serv, buffer, bufsize, result->data,
+ result->size - 1, errnop);
+
+ } while (!(rv & NS_TERMINATE) && how == nss_lt_all);
+
+db_fin:
+ if (!stayopen && st->db != NULL) {
+ db->close(db);
+ st->db = NULL;
+ }
+
+ if (rv == NS_SUCCESS && retval != NULL)
+ *(struct servent **)retval = serv;
+
+ return (rv);
+}
+
+static int
+db_setservent(void *retval, void *mdata, va_list ap)
+{
+ DB *db;
+ struct db_state *st;
+ int rv;
+ int f;
+
+ rv = db_getstate(&st);
+ if (rv != 0)
+ return (NS_UNAVAIL);
+
+ switch ((enum constants)mdata) {
+ case SETSERVENT:
+ f = va_arg(ap, int);
+ st->stayopen |= f;
+ st->keynum = 0;
+ break;
+ case ENDSERVENT:
+ db = st->db;
+ if (db != NULL) {
+ db->close(db);
+ st->db = NULL;
+ }
+ st->stayopen = 0;
+ break;
+ default:
+ break;
+ };
+
+ return (NS_UNAVAIL);
+}
+
/* nis backend implementation */
#ifdef YP
static void
@@ -486,9 +678,6 @@ nis_servent(void *retval, void *mdata, va_list ap)
size_t bufsize;
int *errnop;
- char **aliases;
- int aliases_size;
-
name = NULL;
proto = NULL;
how = (enum nss_lookup_type)mdata;
@@ -594,39 +783,8 @@ nis_servent(void *retval, void *mdata, va_list ap)
break;
};
- /* we need a room for additional \n symbol */
- if (bufsize <=
- resultbuflen + 1 + _ALIGNBYTES + sizeof(char *)) {
- *errnop = ERANGE;
- rv = NS_RETURN;
- break;
- }
-
- aliases = (char **)_ALIGN(&buffer[resultbuflen + 2]);
- aliases_size =
- (buffer + bufsize - (char *)aliases) / sizeof(char *);
- if (aliases_size < 1) {
- *errnop = ERANGE;
- rv = NS_RETURN;
- break;
- }
-
- /*
- * servent_unpack expects lines terminated with \n --
- * make it happy
- */
- memcpy(buffer, resultbuf, resultbuflen);
- buffer[resultbuflen] = '\n';
- buffer[resultbuflen + 1] = '\0';
-
- if (servent_unpack(buffer, serv, aliases, aliases_size,
- errnop) != 0) {
- if (*errnop == 0)
- rv = NS_NOTFOUND;
- else
- rv = NS_RETURN;
- } else
- rv = NS_SUCCESS;
+ rv = parse_result(serv, buffer, bufsize, resultbuf,
+ resultbuflen, errnop);
free(resultbuf);
} while (!(rv & NS_TERMINATE) && how == nss_lt_all);
@@ -674,6 +832,7 @@ compat_setservent(void *retval, void *mdata, va_list ap)
{ NULL, 0 }
};
ns_dtab compat_dtab[] = {
+ { NSSRC_DB, db_setservent, mdata },
#ifdef YP
{ NSSRC_NIS, nis_setservent, mdata },
#endif
@@ -960,6 +1119,7 @@ getservbyname_r(const char *name, const char *proto, struct servent *serv,
#endif /* NS_CACHING */
static const ns_dtab dtab[] = {
{ NSSRC_FILES, files_servent, (void *)&mdata },
+ { NSSRC_DB, db_servent, (void *)nss_lt_name },
#ifdef YP
{ NSSRC_NIS, nis_servent, (void *)nss_lt_name },
#endif
@@ -996,6 +1156,7 @@ getservbyport_r(int port, const char *proto, struct servent *serv,
#endif
static const ns_dtab dtab[] = {
{ NSSRC_FILES, files_servent, (void *)&mdata },
+ { NSSRC_DB, db_servent, (void *)nss_lt_id },
#ifdef YP
{ NSSRC_NIS, nis_servent, (void *)nss_lt_id },
#endif
@@ -1031,6 +1192,7 @@ getservent_r(struct servent *serv, char *buffer, size_t bufsize,
#endif
static const ns_dtab dtab[] = {
{ NSSRC_FILES, files_servent, (void *)&mdata },
+ { NSSRC_DB, db_servent, (void *)nss_lt_all },
#ifdef YP
{ NSSRC_NIS, nis_servent, (void *)nss_lt_all },
#endif
@@ -1063,6 +1225,7 @@ setservent(int stayopen)
#endif
static const ns_dtab dtab[] = {
{ NSSRC_FILES, files_setservent, (void *)SETSERVENT },
+ { NSSRC_DB, db_setservent, (void *)SETSERVENT },
#ifdef YP
{ NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
#endif
@@ -1087,6 +1250,7 @@ endservent()
#endif
static const ns_dtab dtab[] = {
{ NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
+ { NSSRC_DB, db_setservent, (void *)ENDSERVENT },
#ifdef YP
{ NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
#endif
diff --git a/lib/libc/net/nsdispatch.3 b/lib/libc/net/nsdispatch.3
index cf15002..8ae7540 100644
--- a/lib/libc/net/nsdispatch.3
+++ b/lib/libc/net/nsdispatch.3
@@ -32,7 +32,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 22, 2007
+.Dd April 4, 2010
.Dt NSDISPATCH 3
.Os
.Sh NAME
@@ -176,6 +176,7 @@ While there is support for arbitrary sources, the following
.Bl -column NSSRC_COMPAT compat -offset indent
.It Sy "#define value"
.It Dv NSSRC_FILES Ta """files""
+.It Dv NSSRC_DB Ta """db""
.It Dv NSSRC_DNS Ta """dns""
.It Dv NSSRC_NIS Ta """nis""
.It Dv NSSRC_COMPAT Ta """compat""
diff --git a/lib/libc/posix1e/acl_add_flag_np.3 b/lib/libc/posix1e/acl_add_flag_np.3
index 18222b6..3acde6b 100644
--- a/lib/libc/posix1e/acl_add_flag_np.3
+++ b/lib/libc/posix1e/acl_add_flag_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_clear_flags_np.3 b/lib/libc/posix1e/acl_clear_flags_np.3
index b2586e1..0780e14 100644
--- a/lib/libc/posix1e/acl_clear_flags_np.3
+++ b/lib/libc/posix1e/acl_clear_flags_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_delete_flag_np.3 b/lib/libc/posix1e/acl_delete_flag_np.3
index 211a97a..a288978 100644
--- a/lib/libc/posix1e/acl_delete_flag_np.3
+++ b/lib/libc/posix1e/acl_delete_flag_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_get_brand_np.3 b/lib/libc/posix1e/acl_get_brand_np.3
index 20f45dd..5caa40c 100644
--- a/lib/libc/posix1e/acl_get_brand_np.3
+++ b/lib/libc/posix1e/acl_get_brand_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_get_entry_type_np.3 b/lib/libc/posix1e/acl_get_entry_type_np.3
index 34d93be..eea4b17 100644
--- a/lib/libc/posix1e/acl_get_entry_type_np.3
+++ b/lib/libc/posix1e/acl_get_entry_type_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_get_flag_np.3 b/lib/libc/posix1e/acl_get_flag_np.3
index 295ee3e..b57fd04 100644
--- a/lib/libc/posix1e/acl_get_flag_np.3
+++ b/lib/libc/posix1e/acl_get_flag_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_get_flagset_np.3 b/lib/libc/posix1e/acl_get_flagset_np.3
index 7e72340..221b93b 100644
--- a/lib/libc/posix1e/acl_get_flagset_np.3
+++ b/lib/libc/posix1e/acl_get_flagset_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_set_entry_type_np.3 b/lib/libc/posix1e/acl_set_entry_type_np.3
index acfa2f5..9f69bab 100644
--- a/lib/libc/posix1e/acl_set_entry_type_np.3
+++ b/lib/libc/posix1e/acl_set_entry_type_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_set_flagset_np.3 b/lib/libc/posix1e/acl_set_flagset_np.3
index d8dd622..386665d 100644
--- a/lib/libc/posix1e/acl_set_flagset_np.3
+++ b/lib/libc/posix1e/acl_set_flagset_np.3
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/lib/libc/posix1e/acl_strip.c b/lib/libc/posix1e/acl_strip.c
index 1dcdfcd..01fc71a 100644
--- a/lib/libc/posix1e/acl_strip.c
+++ b/lib/libc/posix1e/acl_strip.c
@@ -14,14 +14,14 @@
* 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 THE VOICES IN HIS HEAD 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.
+ * 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/lib/libc/posix1e/acl_to_text_nfs4.c b/lib/libc/posix1e/acl_to_text_nfs4.c
index 3adbfb4..5d0aa31 100644
--- a/lib/libc/posix1e/acl_to_text_nfs4.c
+++ b/lib/libc/posix1e/acl_to_text_nfs4.c
@@ -167,7 +167,7 @@ format_additional_id(char *str, size_t size, const acl_entry_t entry)
static int
format_entry(char *str, size_t size, const acl_entry_t entry, int flags)
{
- size_t off = 0, padding_length, maximum_who_field_length = 18;
+ size_t off = 0, min_who_field_length = 18;
acl_permset_t permset;
acl_flagset_t flagset;
int error, len;
@@ -188,12 +188,9 @@ format_entry(char *str, size_t size, const acl_entry_t entry, int flags)
if (error)
return (error);
len = strlen(buf);
- padding_length = maximum_who_field_length - len;
- if (padding_length > 0) {
- memset(str, ' ', padding_length);
- off += padding_length;
- }
- off += snprintf(str + off, size - off, "%s:", buf);
+ if (len < min_who_field_length)
+ len = min_who_field_length;
+ off += snprintf(str + off, size - off, "%*s:", len, buf);
error = _nfs4_format_access_mask(buf, sizeof(buf), *permset,
flags & ACL_TEXT_VERBOSE);
diff --git a/lib/libc/posix1e/mac_prepare.3 b/lib/libc/posix1e/mac_prepare.3
index 1d85229..8e694de 100644
--- a/lib/libc/posix1e/mac_prepare.3
+++ b/lib/libc/posix1e/mac_prepare.3
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd August 22, 2003
-.Os
.Dt MAC_PREPARE 3
+.Os
.Sh NAME
.Nm mac_prepare , mac_prepare_type , mac_prepare_file_label ,
.Nm mac_prepare_ifnet_label , mac_prepare_process_label
diff --git a/lib/libc/powerpc/gen/fpgetmask.c b/lib/libc/powerpc/gen/fpgetmask.c
index aa7623b..b67b1bc 100644
--- a/lib/libc/powerpc/gen/fpgetmask.c
+++ b/lib/libc/powerpc/gen/fpgetmask.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/powerpc/gen/fpgetround.c b/lib/libc/powerpc/gen/fpgetround.c
index 5381378..097e82a 100644
--- a/lib/libc/powerpc/gen/fpgetround.c
+++ b/lib/libc/powerpc/gen/fpgetround.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/powerpc/gen/fpgetsticky.c b/lib/libc/powerpc/gen/fpgetsticky.c
index feb2ccc..57152ac 100644
--- a/lib/libc/powerpc/gen/fpgetsticky.c
+++ b/lib/libc/powerpc/gen/fpgetsticky.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/powerpc/gen/fpsetmask.c b/lib/libc/powerpc/gen/fpsetmask.c
index e1433a5..81cd19e 100644
--- a/lib/libc/powerpc/gen/fpsetmask.c
+++ b/lib/libc/powerpc/gen/fpsetmask.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/powerpc/gen/fpsetround.c b/lib/libc/powerpc/gen/fpsetround.c
index b4f00d4..17f70a0 100644
--- a/lib/libc/powerpc/gen/fpsetround.c
+++ b/lib/libc/powerpc/gen/fpsetround.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/rpc/Symbol.map b/lib/libc/rpc/Symbol.map
index ccf0bfa..4f356de 100644
--- a/lib/libc/rpc/Symbol.map
+++ b/lib/libc/rpc/Symbol.map
@@ -239,10 +239,6 @@ FBSDprivate_1.0 {
__key_encryptsession_pk_LOCAL;
__key_decryptsession_pk_LOCAL;
__key_gendes_LOCAL;
- __tsd_lock; /*
- * Why does usr.bin/rpcinfo/Makefile need rpc_generic.c?
- * Remove this hack if rpcinfo stops building with it.
- */
__svc_clean_idle;
__rpc_gss_unwrap;
__rpc_gss_unwrap_stub;
diff --git a/lib/libc/rpc/clnt_simple.c b/lib/libc/rpc/clnt_simple.c
index 12b6679..ba21d2d 100644
--- a/lib/libc/rpc/clnt_simple.c
+++ b/lib/libc/rpc/clnt_simple.c
@@ -76,7 +76,11 @@ struct rpc_call_private {
char nettype[NETIDLEN]; /* Network type */
};
static struct rpc_call_private *rpc_call_private_main;
+static thread_key_t rpc_call_key;
+static once_t rpc_call_once = ONCE_INITIALIZER;
+static int rpc_call_key_error;
+static void rpc_call_key_init(void);
static void rpc_call_destroy(void *);
static void
@@ -91,6 +95,13 @@ rpc_call_destroy(void *vp)
}
}
+static void
+rpc_call_key_init(void)
+{
+
+ rpc_call_key_error = thr_keycreate(&rpc_call_key, rpc_call_destroy);
+}
+
/*
* This is the simplified interface to the client rpc layer.
* The client handle is not destroyed here and is reused for
@@ -112,17 +123,16 @@ rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
struct rpc_call_private *rcp = (struct rpc_call_private *) 0;
enum clnt_stat clnt_stat;
struct timeval timeout, tottimeout;
- static thread_key_t rpc_call_key;
int main_thread = 1;
if ((main_thread = thr_main())) {
rcp = rpc_call_private_main;
} else {
- if (rpc_call_key == 0) {
- mutex_lock(&tsd_lock);
- if (rpc_call_key == 0)
- thr_keycreate(&rpc_call_key, rpc_call_destroy);
- mutex_unlock(&tsd_lock);
+ if (thr_once(&rpc_call_once, rpc_call_key_init) != 0 ||
+ rpc_call_key_error != 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = rpc_call_key_error;
+ return (rpc_createerr.cf_stat);
}
rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);
}
diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c
index e5db51a..1310e36 100644
--- a/lib/libc/rpc/getnetconfig.c
+++ b/lib/libc/rpc/getnetconfig.c
@@ -130,21 +130,29 @@ static struct netconfig *dup_ncp(struct netconfig *);
static FILE *nc_file; /* for netconfig db */
-static pthread_mutex_t nc_file_lock = PTHREAD_MUTEX_INITIALIZER;
+static mutex_t nc_file_lock = MUTEX_INITIALIZER;
static struct netconfig_info ni = { 0, 0, NULL, NULL};
-static pthread_mutex_t ni_lock = PTHREAD_MUTEX_INITIALIZER;
+static mutex_t ni_lock = MUTEX_INITIALIZER;
+static thread_key_t nc_key;
+static once_t nc_once = ONCE_INITIALIZER;
+static int nc_key_error;
+
+static void
+nc_key_init(void)
+{
+
+ nc_key_error = thr_keycreate(&nc_key, free);
+}
#define MAXNETCONFIGLINE 1000
static int *
__nc_error()
{
- static pthread_mutex_t nc_lock = PTHREAD_MUTEX_INITIALIZER;
- static thread_key_t nc_key = 0;
static int nc_error = 0;
- int error, *nc_addr;
+ int *nc_addr;
/*
* Use the static `nc_error' if we are the main thread
@@ -153,15 +161,8 @@ __nc_error()
*/
if (thr_main())
return (&nc_error);
- if (nc_key == 0) {
- error = 0;
- mutex_lock(&nc_lock);
- if (nc_key == 0)
- error = thr_keycreate(&nc_key, free);
- mutex_unlock(&nc_lock);
- if (error)
- return (&nc_error);
- }
+ if (thr_once(&nc_once, nc_key_init) != 0 || nc_key_error != 0)
+ return (&nc_error);
if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) {
nc_addr = (int *)malloc(sizeof (int));
if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c
index 6cc1139..afb11c8 100644
--- a/lib/libc/rpc/key_call.c
+++ b/lib/libc/rpc/key_call.c
@@ -279,6 +279,9 @@ struct key_call_private {
uid_t uid; /* user-id at last authorization */
};
static struct key_call_private *key_call_private_main = NULL;
+static thread_key_t key_call_key;
+static once_t key_call_once = ONCE_INITIALIZER;
+static int key_call_key_error;
static void
key_call_destroy(void *vp)
@@ -292,6 +295,13 @@ key_call_destroy(void *vp)
}
}
+static void
+key_call_init(void)
+{
+
+ key_call_key_error = thr_keycreate(&key_call_key, key_call_destroy);
+}
+
/*
* Keep the handle cached. This call may be made quite often.
*/
@@ -307,7 +317,6 @@ int vers;
struct utsname u;
int main_thread;
int fd;
- static thread_key_t key_call_key;
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
#define TOTAL_TRIES 5 /* Number of tries */
@@ -315,12 +324,9 @@ int vers;
if ((main_thread = thr_main())) {
kcp = key_call_private_main;
} else {
- if (key_call_key == 0) {
- mutex_lock(&tsd_lock);
- if (key_call_key == 0)
- thr_keycreate(&key_call_key, key_call_destroy);
- mutex_unlock(&tsd_lock);
- }
+ if (thr_once(&key_call_once, key_call_init) != 0 ||
+ key_call_key_error != 0)
+ return ((CLIENT *) NULL);
kcp = (struct key_call_private *)thr_getspecific(key_call_key);
}
if (kcp == (struct key_call_private *)NULL) {
diff --git a/lib/libc/rpc/mt_misc.c b/lib/libc/rpc/mt_misc.c
index 6241611..7abcaed 100644
--- a/lib/libc/rpc/mt_misc.c
+++ b/lib/libc/rpc/mt_misc.c
@@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
#define proglst_lock __proglst_lock
#define rpcsoc_lock __rpcsoc_lock
#define svcraw_lock __svcraw_lock
-#define tsd_lock __tsd_lock
#define xprtlist_lock __xprtlist_lock
/* protects the services list (svc.c) */
@@ -76,33 +75,33 @@ pthread_mutex_t rpcsoc_lock = PTHREAD_MUTEX_INITIALIZER;
/* svc_raw.c serialization */
pthread_mutex_t svcraw_lock = PTHREAD_MUTEX_INITIALIZER;
-/* protects TSD key creation */
-pthread_mutex_t tsd_lock = PTHREAD_MUTEX_INITIALIZER;
-
/* xprtlist (svc_generic.c) */
pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
#undef rpc_createerr
struct rpc_createerr rpc_createerr;
+static thread_key_t rce_key;
+static once_t rce_once = ONCE_INITIALIZER;
+static int rce_key_error;
+
+static void
+rce_key_init(void)
+{
+
+ rce_key_error = thr_keycreate(&rce_key, free);
+}
struct rpc_createerr *
__rpc_createerr()
{
- static thread_key_t rce_key = 0;
struct rpc_createerr *rce_addr = 0;
if (thr_main())
return (&rpc_createerr);
- if ((rce_addr =
- (struct rpc_createerr *)thr_getspecific(rce_key)) != 0) {
- mutex_lock(&tsd_lock);
- if (thr_keycreate(&rce_key, free) != 0) {
- mutex_unlock(&tsd_lock);
- return (&rpc_createerr);
- }
- mutex_unlock(&tsd_lock);
- }
+ if (thr_once(&rce_once, rce_key_init) != 0 || rce_key_error != 0)
+ return (&rpc_createerr);
+ rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key);
if (!rce_addr) {
rce_addr = (struct rpc_createerr *)
malloc(sizeof (struct rpc_createerr));
diff --git a/lib/libc/rpc/mt_misc.h b/lib/libc/rpc/mt_misc.h
index e785c30..9cc2349 100644
--- a/lib/libc/rpc/mt_misc.h
+++ b/lib/libc/rpc/mt_misc.h
@@ -42,7 +42,6 @@
#define proglst_lock __proglst_lock
#define rpcsoc_lock __rpcsoc_lock
#define svcraw_lock __svcraw_lock
-#define tsd_lock __tsd_lock
#define xprtlist_lock __xprtlist_lock
extern pthread_rwlock_t svc_lock;
diff --git a/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c
index 81bd92b..ab259d5 100644
--- a/lib/libc/rpc/rpc_generic.c
+++ b/lib/libc/rpc/rpc_generic.c
@@ -221,6 +221,18 @@ getnettype(nettype)
return (_rpctypelist[i].type);
}
+static thread_key_t tcp_key, udp_key;
+static once_t keys_once = ONCE_INITIALIZER;
+static int tcp_key_error, udp_key_error;
+
+static void
+keys_init(void)
+{
+
+ tcp_key_error = thr_keycreate(&tcp_key, free);
+ udp_key_error = thr_keycreate(&udp_key, free);
+}
+
/*
* For the given nettype (tcp or udp only), return the first structure found.
* This should be freed by calling freenetconfigent()
@@ -236,25 +248,15 @@ __rpc_getconfip(nettype)
static char *netid_udp_main;
struct netconfig *dummy;
int main_thread;
- static thread_key_t tcp_key, udp_key;
if ((main_thread = thr_main())) {
netid_udp = netid_udp_main;
netid_tcp = netid_tcp_main;
} else {
- if (tcp_key == 0) {
- mutex_lock(&tsd_lock);
- if (tcp_key == 0)
- thr_keycreate(&tcp_key, free);
- mutex_unlock(&tsd_lock);
- }
+ if (thr_once(&keys_once, keys_init) != 0 ||
+ tcp_key_error != 0 || udp_key_error != 0)
+ return (NULL);
netid_tcp = (char *)thr_getspecific(tcp_key);
- if (udp_key == 0) {
- mutex_lock(&tsd_lock);
- if (udp_key == 0)
- thr_keycreate(&udp_key, free);
- mutex_unlock(&tsd_lock);
- }
netid_udp = (char *)thr_getspecific(udp_key);
}
if (!netid_udp && !netid_tcp) {
diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c
index 5922063..2568d43 100644
--- a/lib/libc/rpc/rpc_soc.c
+++ b/lib/libc/rpc/rpc_soc.c
@@ -360,6 +360,14 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
*/
static thread_key_t clnt_broadcast_key;
static resultproc_t clnt_broadcast_result_main;
+static once_t clnt_broadcast_once = ONCE_INITIALIZER;
+
+static void
+clnt_broadcast_key_init(void)
+{
+
+ thr_keycreate(&clnt_broadcast_key, free);
+}
/*
* Need to translate the netbuf address into sockaddr_in address.
@@ -402,12 +410,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
if (thr_main())
clnt_broadcast_result_main = eachresult;
else {
- if (clnt_broadcast_key == 0) {
- mutex_lock(&tsd_lock);
- if (clnt_broadcast_key == 0)
- thr_keycreate(&clnt_broadcast_key, free);
- mutex_unlock(&tsd_lock);
- }
+ thr_once(&clnt_broadcast_once, clnt_broadcast_key_init);
thr_setspecific(clnt_broadcast_key, (void *) eachresult);
}
return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers,
diff --git a/lib/libc/softfloat/softfloat-specialize b/lib/libc/softfloat/softfloat-specialize
index c8c8028..e8585ce 100644
--- a/lib/libc/softfloat/softfloat-specialize
+++ b/lib/libc/softfloat/softfloat-specialize
@@ -44,7 +44,11 @@ Underflow tininess-detection mode, statically initialized to default value.
#ifdef SOFTFLOAT_FOR_GCC
static
#endif
+#ifdef __sparc64__
+int8 float_detect_tininess = float_tininess_before_rounding;
+#else
int8 float_detect_tininess = float_tininess_after_rounding;
+#endif
/*
-------------------------------------------------------------------------------
diff --git a/lib/libc/sparc64/fpu/fpu.c b/lib/libc/sparc64/fpu/fpu.c
index 74f07ec..4e92788 100644
--- a/lib/libc/sparc64/fpu/fpu.c
+++ b/lib/libc/sparc64/fpu/fpu.c
@@ -69,9 +69,12 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <errno.h>
-#include <unistd.h>
#include <signal.h>
+#ifdef FPU_DEBUG
+#include <stdio.h>
+#endif
#include <stdlib.h>
+#include <unistd.h>
#include "un-namespace.h"
#include "libc_private.h"
@@ -97,7 +100,7 @@ __FBSDID("$FreeBSD$");
#define X8(x) X4(x),X4(x)
#define X16(x) X8(x),X8(x)
-static char cx_to_trapx[] = {
+static const char cx_to_trapx[] = {
X1(FSR_NX),
X2(FSR_DZ),
X4(FSR_UF),
@@ -113,7 +116,8 @@ int __fpe_debug = 0;
#endif
#endif /* FPU_DEBUG */
-static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, u_long);
+static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t,
+ u_long);
/*
* Need to use an fpstate on the stack; we could switch, so we cannot safely
@@ -169,7 +173,7 @@ __fpu_exception(struct utrapframe *uf)
void
__fpu_dumpfpn(struct fpn *fp)
{
- static char *class[] = {
+ static const char *const class[] = {
"SNAN", "QNAN", "ZERO", "NUM", "INF"
};
@@ -181,15 +185,11 @@ __fpu_dumpfpn(struct fpn *fp)
}
#endif
-static int opmask[] = {0, 0, 1, 3};
+static const int opmask[] = {0, 0, 1, 3, 1};
/* Decode 5 bit register field depending on the type. */
#define RN_DECODE(tp, rn) \
- ((tp == FTYPE_DBL || tp == FTYPE_EXT ? INSFPdq_RN((rn)) : (rn)) & \
- ~opmask[tp])
-
-/* Operand size in 32-bit registers. */
-#define OPSZ(tp) ((tp) == FTYPE_LNG ? 2 : (1 << (tp)))
+ ((tp) >= FTYPE_DBL ? INSFPdq_RN(rn) & ~opmask[tp] : (rn))
/*
* Helper for forming the below case statements. Build only the op3 and opf
@@ -209,8 +209,6 @@ static void
__fpu_mov(struct fpemu *fe, int type, int rd, int rs2, u_int32_t nand,
u_int32_t xor)
{
- u_int64_t tmp64;
- int i;
if (type == FTYPE_INT || type == FTYPE_SNG)
__fpu_setreg(rd, (__fpu_getreg(rs2) & ~nand) ^ xor);
@@ -219,13 +217,10 @@ __fpu_mov(struct fpemu *fe, int type, int rd, int rs2, u_int32_t nand,
* Need to use the double versions to be able to access
* the upper 32 fp registers.
*/
- for (i = 0; i < OPSZ(type); i += 2, rd += 2, rs2 += 2) {
- tmp64 = __fpu_getreg64(rs2);
- if (i == 0)
- tmp64 = (tmp64 & ~((u_int64_t)nand << 32)) ^
- ((u_int64_t)xor << 32);
- __fpu_setreg64(rd, tmp64);
- }
+ __fpu_setreg64(rd, (__fpu_getreg64(rs2) &
+ ~((u_int64_t)nand << 32)) ^ ((u_int64_t)xor << 32));
+ if (type == FTYPE_EXT)
+ __fpu_setreg64(rd + 2, __fpu_getreg64(rs2 + 2));
}
}
@@ -271,17 +266,17 @@ __fpu_cmpck(struct fpemu *fe)
* multiply two integers this way.
*/
static int
-__fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long tstate)
+__fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn,
+ u_long tstate)
{
struct fpn *fp;
int opf, rs1, rs2, rd, type, mask, cx, cond;
u_long reg, fsr;
u_int space[4];
- int i;
/*
* `Decode' and execute instruction. Start with no exceptions.
- * The type of any opf opcode is in the bottom two bits, so we
+ * The type of almost any OPF opcode is in the bottom two bits, so we
* squish them out here.
*/
opf = insn & (IF_MASK(IF_F3_OP3_SHIFT, IF_F3_OP3_BITS) |
@@ -359,7 +354,7 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
__fpu_explode(fe, &fe->fe_f2, type, rs2);
__fpu_compare(fe, 1, IF_F3_CC(insn));
return (__fpu_cmpck(fe));
- case FOP(INS2_FPop1, INSFP1_FMOV): /* these should all be pretty obvious */
+ case FOP(INS2_FPop1, INSFP1_FMOV):
__fpu_mov(fe, type, rd, rs2, 0, 0);
return (0);
case FOP(INS2_FPop1, INSFP1_FNEG):
@@ -410,6 +405,7 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
case FOP(INS2_FPop1, INSFP1_FxTOd):
case FOP(INS2_FPop1, INSFP1_FxTOq):
type = FTYPE_LNG;
+ rs2 = RN_DECODE(type, IF_F3_RS2(insn));
__fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
/* sneaky; depends on instruction encoding */
type = (IF_F3_OPF(insn) >> 2) & 3;
@@ -418,8 +414,7 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
case FOP(INS2_FPop1, INSFP1_FTOx):
__fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
type = FTYPE_LNG;
- mask = 1; /* needs 2 registers */
- rd = IF_F3_RD(insn) & ~mask;
+ rd = RN_DECODE(type, IF_F3_RD(insn));
break;
case FOP(INS2_FPop1, INSFP1_FTOs):
case FOP(INS2_FPop1, INSFP1_FTOd):
@@ -457,10 +452,10 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
if (type == FTYPE_INT || type == FTYPE_SNG)
__fpu_setreg(rd, space[0]);
else {
- for (i = 0; i < OPSZ(type); i += 2) {
- __fpu_setreg64(rd + i, ((u_int64_t)space[i] << 32) |
- space[i + 1]);
- }
+ __fpu_setreg64(rd, ((u_int64_t)space[0] << 32) | space[1]);
+ if (type == FTYPE_EXT)
+ __fpu_setreg64(rd + 2,
+ ((u_int64_t)space[2] << 32) | space[3]);
}
return (0); /* success */
}
diff --git a/lib/libc/sparc64/fpu/fpu_div.c b/lib/libc/sparc64/fpu/fpu_div.c
index c4b8ef6..4748daf 100644
--- a/lib/libc/sparc64/fpu/fpu_div.c
+++ b/lib/libc/sparc64/fpu/fpu_div.c
@@ -167,14 +167,16 @@ __fpu_div(fe)
* return it. Otherwise we have the following cases:
*
* Inf / Inf = NaN, plus NV exception
- * Inf / num = Inf [i.e., return x]
- * Inf / 0 = Inf [i.e., return x]
- * 0 / Inf = 0 [i.e., return x]
- * 0 / num = 0 [i.e., return x]
+ * Inf / num = Inf [i.e., return x #]
+ * Inf / 0 = Inf [i.e., return x #]
+ * 0 / Inf = 0 [i.e., return x #]
+ * 0 / num = 0 [i.e., return x #]
* 0 / 0 = NaN, plus NV exception
- * num / Inf = 0
+ * num / Inf = 0 #
* num / num = num (do the divide)
- * num / 0 = Inf, plus DZ exception
+ * num / 0 = Inf #, plus DZ exception
+ *
+ * # Sign of result is XOR of operand signs.
*/
if (ISNAN(x) || ISNAN(y)) {
ORDER(x, y);
@@ -183,10 +185,10 @@ __fpu_div(fe)
if (ISINF(x) || ISZERO(x)) {
if (x->fp_class == y->fp_class)
return (__fpu_newnan(fe));
+ x->fp_sign ^= y->fp_sign;
return (x);
}
- /* all results at this point use XOR of operand signs */
x->fp_sign ^= y->fp_sign;
if (ISINF(y)) {
x->fp_class = FPC_ZERO;
diff --git a/lib/libc/sparc64/fpu/fpu_emu.h b/lib/libc/sparc64/fpu/fpu_emu.h
index de156e2..0d1d16d 100644
--- a/lib/libc/sparc64/fpu/fpu_emu.h
+++ b/lib/libc/sparc64/fpu/fpu_emu.h
@@ -140,7 +140,7 @@ struct fpn {
#define FTYPE_SNG INSFP_s
#define FTYPE_DBL INSFP_d
#define FTYPE_EXT INSFP_q
-#define FTYPE_LNG -1
+#define FTYPE_LNG 4
/*
* Emulator state.
diff --git a/lib/libc/sparc64/fpu/fpu_explode.c b/lib/libc/sparc64/fpu/fpu_explode.c
index 09cfd5a..474e0df 100644
--- a/lib/libc/sparc64/fpu/fpu_explode.c
+++ b/lib/libc/sparc64/fpu/fpu_explode.c
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
+#ifdef FPU_DEBUG
+#include <stdio.h>
+#endif
+
#include <machine/frame.h>
#include <machine/fp.h>
#include <machine/fsr.h>
@@ -135,9 +139,9 @@ __fpu_xtof(fp, i)
* a signed or unsigned entity.
*/
if (fp->fp_sign && (int64_t)i < 0)
- *((int64_t*)fp->fp_mant) = -i;
+ *((int64_t *)fp->fp_mant) = -i;
else
- *((int64_t*)fp->fp_mant) = i;
+ *((int64_t *)fp->fp_mant) = i;
fp->fp_mant[2] = 0;
fp->fp_mant[3] = 0;
__fpu_norm(fp);
@@ -258,14 +262,12 @@ __fpu_explode(fe, fp, type, reg)
struct fpn *fp;
int type, reg;
{
- u_int32_t s, *sp;
- u_int64_t l[2];
- void *vl = l;
+ u_int64_t l0, l1;
+ u_int32_t s;
if (type == FTYPE_LNG || type == FTYPE_DBL || type == FTYPE_EXT) {
- l[0] = __fpu_getreg64(reg & ~1);
- sp = vl;
- fp->fp_sign = sp[0] >> 31;
+ l0 = __fpu_getreg64(reg & ~1);
+ fp->fp_sign = l0 >> 63;
} else {
s = __fpu_getreg(reg);
fp->fp_sign = s >> 31;
@@ -273,7 +275,7 @@ __fpu_explode(fe, fp, type, reg)
fp->fp_sticky = 0;
switch (type) {
case FTYPE_LNG:
- s = __fpu_xtof(fp, l[0]);
+ s = __fpu_xtof(fp, l0);
break;
case FTYPE_INT:
@@ -285,12 +287,13 @@ __fpu_explode(fe, fp, type, reg)
break;
case FTYPE_DBL:
- s = __fpu_dtof(fp, sp[0], sp[1]);
+ s = __fpu_dtof(fp, l0 >> 32, l0 & 0xffffffff);
break;
case FTYPE_EXT:
- l[1] = __fpu_getreg64((reg & ~1) + 2);
- s = __fpu_qtof(fp, sp[0], sp[1], sp[2], sp[3]);
+ l1 = __fpu_getreg64((reg & ~1) + 2);
+ s = __fpu_qtof(fp, l0 >> 32, l0 & 0xffffffff, l1 >> 32,
+ l1 & 0xffffffff);
break;
default:
diff --git a/lib/libc/sparc64/fpu/fpu_extern.h b/lib/libc/sparc64/fpu/fpu_extern.h
index f22c463..a5fb942 100644
--- a/lib/libc/sparc64/fpu/fpu_extern.h
+++ b/lib/libc/sparc64/fpu/fpu_extern.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -41,7 +34,6 @@
#define _SPARC64_FPU_FPU_EXTERN_H_
struct utrapframe;
-union instr;
struct fpemu;
struct fpn;
@@ -61,9 +53,9 @@ struct fpn *__fpu_div(struct fpemu *);
int __fpu_itof(struct fpn *, u_int);
int __fpu_xtof(struct fpn *, u_int64_t);
int __fpu_stof(struct fpn *, u_int);
-int __fpu_dtof(struct fpn *, u_int, u_int );
-int __fpu_qtof(struct fpn *, u_int, u_int , u_int , u_int );
-void __fpu_explode(struct fpemu *, struct fpn *, int, int );
+int __fpu_dtof(struct fpn *, u_int, u_int);
+int __fpu_qtof(struct fpn *, u_int, u_int, u_int, u_int);
+void __fpu_explode(struct fpemu *, struct fpn *, int, int);
/* fpu_implode.c */
u_int __fpu_ftoi(struct fpemu *, struct fpn *);
diff --git a/lib/libc/sparc64/fpu/fpu_implode.c b/lib/libc/sparc64/fpu/fpu_implode.c
index 5287d2b..2a2a9d0 100644
--- a/lib/libc/sparc64/fpu/fpu_implode.c
+++ b/lib/libc/sparc64/fpu/fpu_implode.c
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
+#ifdef FPU_DEBUG
+#include <stdio.h>
+#endif
+
#include <machine/frame.h>
#include <machine/fp.h>
#include <machine/fsr.h>
@@ -198,7 +202,6 @@ __fpu_ftoi(fe, fp)
sign = fp->fp_sign;
switch (fp->fp_class) {
-
case FPC_ZERO:
return (0);
@@ -248,10 +251,9 @@ __fpu_ftox(fe, fp, res)
sign = fp->fp_sign;
switch (fp->fp_class) {
-
case FPC_ZERO:
- res[1] = 0;
- return (0);
+ i = 0;
+ goto done;
case FPC_NUM:
/*
@@ -275,15 +277,17 @@ __fpu_ftox(fe, fp, res)
break;
if (sign)
i = -i;
- res[1] = (int)i;
- return (i >> 32);
+ goto done;
default: /* Inf, qNaN, sNaN */
break;
}
/* overflow: replace any inexact exception with invalid */
fe->fe_cx = (fe->fe_cx & ~FSR_NX) | FSR_NV;
- return (0x7fffffffffffffffLL + sign);
+ i = 0x7fffffffffffffffLL + sign;
+done:
+ res[1] = i & 0xffffffff;
+ return (i >> 32);
}
/*
@@ -325,8 +329,9 @@ __fpu_ftos(fe, fp)
* right to introduce leading zeroes. Rounding then acts
* differently for normals and subnormals: the largest subnormal
* may round to the smallest normal (1.0 x 2^minexp), or may
- * remain subnormal. In the latter case, signal an underflow
- * if the result was inexact or if underflow traps are enabled.
+ * remain subnormal. A number that is subnormal before rounding
+ * will signal an underflow if the result is inexact or if underflow
+ * traps are enabled.
*
* Rounding a normal, on the other hand, always produces another
* normal (although either way the result might be too big for
@@ -341,8 +346,10 @@ __fpu_ftos(fe, fp)
if ((exp = fp->fp_exp + SNG_EXP_BIAS) <= 0) { /* subnormal */
/* -NG for g,r; -SNG_FRACBITS-exp for fraction */
(void) __fpu_shr(fp, FP_NMANT - FP_NG - SNG_FRACBITS - exp);
- if (fpround(fe, fp) && fp->fp_mant[3] == SNG_EXP(1))
+ if (fpround(fe, fp) && fp->fp_mant[3] == SNG_EXP(1)) {
+ fe->fe_cx |= FSR_UF;
return (sign | SNG_EXP(1) | 0);
+ }
if ((fe->fe_cx & FSR_NX) ||
(fe->fe_fsr & (FSR_UF << FSR_TEM_SHIFT)))
fe->fe_cx |= FSR_UF;
@@ -403,6 +410,7 @@ zero: res[1] = 0;
if ((exp = fp->fp_exp + DBL_EXP_BIAS) <= 0) {
(void) __fpu_shr(fp, FP_NMANT - FP_NG - DBL_FRACBITS - exp);
if (fpround(fe, fp) && fp->fp_mant[2] == DBL_EXP(1)) {
+ fe->fe_cx |= FSR_UF;
res[1] = 0;
return (sign | DBL_EXP(1) | 0);
}
@@ -422,7 +430,7 @@ zero: res[1] = 0;
return (sign | DBL_EXP(DBL_EXP_INFNAN) | 0);
}
res[1] = ~0;
- return (sign | DBL_EXP(DBL_EXP_INFNAN) | DBL_MASK);
+ return (sign | DBL_EXP(DBL_EXP_INFNAN - 1) | DBL_MASK);
}
done:
res[1] = fp->fp_mant[3];
@@ -464,6 +472,7 @@ zero: res[1] = res[2] = res[3] = 0;
if ((exp = fp->fp_exp + EXT_EXP_BIAS) <= 0) {
(void) __fpu_shr(fp, FP_NMANT - FP_NG - EXT_FRACBITS - exp);
if (fpround(fe, fp) && fp->fp_mant[0] == EXT_EXP(1)) {
+ fe->fe_cx |= FSR_UF;
res[1] = res[2] = res[3] = 0;
return (sign | EXT_EXP(1) | 0);
}
@@ -483,7 +492,7 @@ zero: res[1] = res[2] = res[3] = 0;
return (sign | EXT_EXP(EXT_EXP_INFNAN) | 0);
}
res[1] = res[2] = res[3] = ~0;
- return (sign | EXT_EXP(EXT_EXP_INFNAN) | EXT_MASK);
+ return (sign | EXT_EXP(EXT_EXP_INFNAN - 1) | EXT_MASK);
}
done:
res[1] = fp->fp_mant[1];
@@ -504,7 +513,6 @@ __fpu_implode(fe, fp, type, space)
{
switch (type) {
-
case FTYPE_LNG:
space[0] = __fpu_ftox(fe, fp, space);
break;
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
index 5bc4af7..89c0536 100644
--- a/lib/libc/stdio/findfp.c
+++ b/lib/libc/stdio/findfp.c
@@ -61,6 +61,7 @@ int __sdidinit;
._read = __sread, \
._seek = __sseek, \
._write = __swrite, \
+ ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \
}
/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
@@ -96,7 +97,7 @@ moreglue(n)
int n;
{
struct glue *g;
- static FILE empty;
+ static FILE empty = { ._fl_mutex = PTHREAD_MUTEX_INITIALIZER };
FILE *p;
g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE));
@@ -154,7 +155,7 @@ found:
fp->_ub._size = 0;
fp->_lb._base = NULL; /* no line buffer */
fp->_lb._size = 0;
-/* fp->_lock = NULL; */ /* once set always set (reused) */
+/* fp->_fl_mutex = NULL; */ /* once set always set (reused) */
fp->_orientation = 0;
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
return (fp);
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
index 09b3a18..6380b83 100644
--- a/lib/libc/stdio/local.h
+++ b/lib/libc/stdio/local.h
@@ -110,6 +110,14 @@ extern int __sdidinit;
}
/*
+ * Structure initializations for 'fake' FILE objects.
+ */
+#define FAKE_FILE { \
+ ._file = -1, \
+ ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \
+}
+
+/*
* Set the orientation for a stream. If o > 0, the stream has wide-
* orientation. If o < 0, the stream has byte-orientation.
*/
diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
index 8de2bb8..8c1cd28 100644
--- a/lib/libc/stdio/printf.3
+++ b/lib/libc/stdio/printf.3
@@ -891,9 +891,9 @@ in
.Fx 2.2 ,
but were later replaced with a different implementation
from
-.An Todd C. Miller Aq Todd.Miller@courtesan.com
-for
-.Ox 2.3 .
+.Ox 2.3
+by
+.An Todd C. Miller Aq Todd.Miller@courtesan.com .
The
.Fn dprintf
and
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
index 0470a33..e6d7115 100644
--- a/lib/libc/stdio/snprintf.c
+++ b/lib/libc/stdio/snprintf.c
@@ -48,7 +48,7 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
size_t on;
int ret;
va_list ap;
- FILE f;
+ FILE f = FAKE_FILE;
on = n;
if (n != 0)
@@ -56,12 +56,9 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
if (n > INT_MAX)
n = INT_MAX;
va_start(ap, fmt);
- f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
if (on > 0)
*f._p = '\0';
diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c
index 0682b5b..a1b600a 100644
--- a/lib/libc/stdio/vasprintf.c
+++ b/lib/libc/stdio/vasprintf.c
@@ -36,25 +36,19 @@ __FBSDID("$FreeBSD$");
#include "local.h"
int
-vasprintf(str, fmt, ap)
- char **str;
- const char *fmt;
- __va_list ap;
+vasprintf(char **str, const char *fmt, __va_list ap)
{
+ FILE f = FAKE_FILE;
int ret;
- FILE f;
- f._file = -1;
f._flags = __SWR | __SSTR | __SALC;
- f._bf._base = f._p = (unsigned char *)malloc(128);
+ f._bf._base = f._p = malloc(128);
if (f._bf._base == NULL) {
*str = NULL;
errno = ENOMEM;
return (-1);
}
f._bf._size = f._w = 127; /* Leave room for the NUL */
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
if (ret < 0) {
free(f._bf._base);
diff --git a/lib/libc/stdio/vdprintf.c b/lib/libc/stdio/vdprintf.c
index 2703022..3ad273e 100644
--- a/lib/libc/stdio/vdprintf.c
+++ b/lib/libc/stdio/vdprintf.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
int
vdprintf(int fd, const char * __restrict fmt, va_list ap)
{
- FILE f;
+ FILE f = FAKE_FILE;
unsigned char buf[BUFSIZ];
int ret;
@@ -56,8 +56,6 @@ vdprintf(int fd, const char * __restrict fmt, va_list ap)
f._write = __swrite;
f._bf._base = buf;
f._bf._size = sizeof(buf);
- f._orientation = 0;
- bzero(&f._mbstate, sizeof(f._mbstate));
if ((ret = __vfprintf(&f, fmt, ap)) < 0)
return (ret);
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 7e5d7fe..17ad824 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -169,7 +169,7 @@ static int
__sbprintf(FILE *fp, const char *fmt, va_list ap)
{
int ret;
- FILE fake;
+ FILE fake = FAKE_FILE;
unsigned char buf[BUFSIZ];
/* XXX This is probably not needed. */
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
index f990664..70e4c53 100644
--- a/lib/libc/stdio/vsnprintf.c
+++ b/lib/libc/stdio/vsnprintf.c
@@ -47,7 +47,7 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
size_t on;
int ret;
char dummy[2];
- FILE f;
+ FILE f = FAKE_FILE;
on = n;
if (n != 0)
@@ -61,12 +61,9 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
str = dummy;
n = 1;
}
- f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
if (on > 0)
*f._p = '\0';
diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c
index 60d830c..3890af7 100644
--- a/lib/libc/stdio/vsprintf.c
+++ b/lib/libc/stdio/vsprintf.c
@@ -44,14 +44,11 @@ int
vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap)
{
int ret;
- FILE f;
+ FILE f = FAKE_FILE;
- f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = INT_MAX;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfprintf(&f, fmt, ap);
*f._p = 0;
return (ret);
diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
index 22b5d2b..82429c6 100644
--- a/lib/libc/stdio/vsscanf.c
+++ b/lib/libc/stdio/vsscanf.c
@@ -55,16 +55,11 @@ int
vsscanf(const char * __restrict str, const char * __restrict fmt,
__va_list ap)
{
- FILE f;
+ FILE f = FAKE_FILE;
- f._file = -1;
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._r = strlen(str);
f._read = eofread;
- f._ub._base = NULL;
- f._lb._base = NULL;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
return (__svfscanf(&f, fmt, ap));
}
diff --git a/lib/libc/stdio/vswprintf.c b/lib/libc/stdio/vswprintf.c
index 61b8720..2cfe724 100644
--- a/lib/libc/stdio/vswprintf.c
+++ b/lib/libc/stdio/vswprintf.c
@@ -45,7 +45,7 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
{
static const mbstate_t initial;
mbstate_t mbs;
- FILE f;
+ FILE f = FAKE_FILE;
char *mbp;
int ret, sverrno;
size_t nwc;
@@ -55,7 +55,6 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
return (-1);
}
- f._file = -1;
f._flags = __SWR | __SSTR | __SALC;
f._bf._base = f._p = (unsigned char *)malloc(128);
if (f._bf._base == NULL) {
@@ -63,8 +62,6 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
return (-1);
}
f._bf._size = f._w = 127; /* Leave room for the NUL */
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
ret = __vfwprintf(&f, fmt, ap);
if (ret < 0) {
sverrno = errno;
diff --git a/lib/libc/stdio/vswscanf.c b/lib/libc/stdio/vswscanf.c
index 8a70d44..f06fc02 100644
--- a/lib/libc/stdio/vswscanf.c
+++ b/lib/libc/stdio/vswscanf.c
@@ -62,7 +62,7 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
{
static const mbstate_t initial;
mbstate_t mbs;
- FILE f;
+ FILE f = FAKE_FILE;
char *mbstr;
size_t mlen;
int r;
@@ -80,15 +80,10 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
free(mbstr);
return (EOF);
}
- f._file = -1;
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *)mbstr;
f._bf._size = f._r = mlen;
f._read = eofread;
- f._ub._base = NULL;
- f._lb._base = NULL;
- f._orientation = 0;
- memset(&f._mbstate, 0, sizeof(mbstate_t));
r = __vfwscanf(&f, fmt, ap);
free(mbstr);
diff --git a/lib/libc/stdio/xprintf.c b/lib/libc/stdio/xprintf.c
index bb41a9c..0cc8571 100644
--- a/lib/libc/stdio/xprintf.c
+++ b/lib/libc/stdio/xprintf.c
@@ -48,6 +48,7 @@
#include <wchar.h>
#include "un-namespace.h"
+#include "local.h"
#include "printf.h"
#include "fvwrite.h"
@@ -575,7 +576,7 @@ static int
__v3printf(FILE *fp, const char *fmt, int pct, va_list ap)
{
int ret;
- FILE fake;
+ FILE fake = FAKE_FILE;
unsigned char buf[BUFSIZ];
/* copy the important variables */
diff --git a/lib/libc/stdlib/hcreate.3 b/lib/libc/stdlib/hcreate.3
index cd82720..2466c9f 100644
--- a/lib/libc/stdlib/hcreate.3
+++ b/lib/libc/stdlib/hcreate.3
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 6, 2008
-.Os
.Dt HCREATE 3
+.Os
.Sh NAME
.Nm hcreate , hdestroy , hsearch
.Nd manage hash search table
diff --git a/lib/libc/stdlib/ptsname.3 b/lib/libc/stdlib/ptsname.3
index f674a54..48da3bd 100644
--- a/lib/libc/stdlib/ptsname.3
+++ b/lib/libc/stdlib/ptsname.3
@@ -32,8 +32,8 @@
.\" $FreeBSD$
.\"
.Dd August 20, 2008
-.Os
.Dt PTSNAME 3
+.Os
.Sh NAME
.Nm grantpt ,
.Nm ptsname ,
diff --git a/lib/libc/stdlib/reallocf.c b/lib/libc/stdlib/reallocf.c
index 5320926..a85b5a3 100644
--- a/lib/libc/stdlib/reallocf.c
+++ b/lib/libc/stdlib/reallocf.c
@@ -35,7 +35,14 @@ reallocf(void *ptr, size_t size)
void *nptr;
nptr = realloc(ptr, size);
- if (!nptr && ptr)
+
+ /*
+ * When the System V compatibility option (malloc "V" flag) is
+ * in effect, realloc(ptr, 0) frees the memory and returns NULL.
+ * So, to avoid double free, call free() only when size != 0.
+ * realloc(ptr, 0) can't fail when ptr != NULL.
+ */
+ if (!nptr && ptr && size != 0)
free(ptr);
return (nptr);
}
diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3
index 4205a3d..166bb12 100644
--- a/lib/libc/stdlib/realpath.3
+++ b/lib/libc/stdlib/realpath.3
@@ -31,7 +31,7 @@
.\" @(#)realpath.3 8.2 (Berkeley) 2/16/94
.\" $FreeBSD$
.\"
-.Dd February 16, 1994
+.Dd April 19, 2010
.Dt REALPATH 3
.Os
.Sh NAME
@@ -43,7 +43,7 @@
.In sys/param.h
.In stdlib.h
.Ft "char *"
-.Fn realpath "const char *pathname" "char resolved_path[PATH_MAX]"
+.Fn realpath "const char *pathname" "char *resolved_path"
.Sh DESCRIPTION
The
.Fn realpath
@@ -56,15 +56,16 @@ and
in
.Fa pathname ,
and copies the resulting absolute pathname into
-the memory referenced by
+the memory pointed to by
.Fa resolved_path .
The
.Fa resolved_path
argument
.Em must
-refer to a buffer capable of storing at least
+point to a buffer capable of storing at least
.Dv PATH_MAX
-characters.
+characters, or be
+.Dv NULL .
.Pp
The
.Fn realpath
@@ -82,13 +83,22 @@ The
function returns
.Fa resolved_path
on success.
+If the function was supplied
+.Dv NULL
+as
+.Fa resolved_path ,
+and operation did not cause errors, the returned value is
+a null-terminated string in a buffer allocated by a call to
+.Fn malloc 3 .
If an error occurs,
.Fn realpath
returns
.Dv NULL ,
-and
+and if
.Fa resolved_path
-contains the pathname which caused the problem.
+is not
+.Dv NULL ,
+the array that it points to contains the pathname which caused the problem.
.Sh ERRORS
The function
.Fn realpath
@@ -113,6 +123,11 @@ when given a relative
.Fa pathname .
.Sh "SEE ALSO"
.Xr getcwd 3
+.Sh STANDARDS
+The
+.Fn realpath
+function conforms to
+.St -p1003.1-2001 .
.Sh HISTORY
The
.Fn realpath
diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c
index 3082f5f..e75ee4a 100644
--- a/lib/libc/stdlib/realpath.c
+++ b/lib/libc/stdlib/realpath.c
@@ -43,23 +43,37 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
/*
- * char *realpath(const char *path, char resolved[PATH_MAX]);
- *
* Find the real name of path, by removing all ".", ".." and symlink
* components. Returns (resolved) on success, or (NULL) on failure,
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(const char *path, char resolved[PATH_MAX])
+realpath(const char * __restrict path, char * __restrict resolved)
{
struct stat sb;
char *p, *q, *s;
size_t left_len, resolved_len;
unsigned symlinks;
- int serrno, slen;
+ int serrno, slen, m;
char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
+ if (path == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ if (path[0] == '\0') {
+ errno = ENOENT;
+ return (NULL);
+ }
serrno = errno;
+ if (resolved == NULL) {
+ resolved = malloc(PATH_MAX);
+ if (resolved == NULL)
+ return (NULL);
+ m = 1;
+ } else
+ m = 0;
+
symlinks = 0;
if (path[0] == '/') {
resolved[0] = '/';
@@ -70,13 +84,18 @@ realpath(const char *path, char resolved[PATH_MAX])
left_len = strlcpy(left, path + 1, sizeof(left));
} else {
if (getcwd(resolved, PATH_MAX) == NULL) {
- strlcpy(resolved, ".", PATH_MAX);
+ if (m)
+ free(resolved);
+ else
+ strlcpy(resolved, ".", PATH_MAX);
return (NULL);
}
resolved_len = strlen(resolved);
left_len = strlcpy(left, path, sizeof(left));
}
if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+ if (m)
+ free(resolved);
errno = ENAMETOOLONG;
return (NULL);
}
@@ -92,6 +111,8 @@ realpath(const char *path, char resolved[PATH_MAX])
p = strchr(left, '/');
s = p ? p : left + left_len;
if (s - left >= sizeof(next_token)) {
+ if (m)
+ free(resolved);
errno = ENAMETOOLONG;
return (NULL);
}
@@ -102,6 +123,8 @@ realpath(const char *path, char resolved[PATH_MAX])
memmove(left, s + 1, left_len + 1);
if (resolved[resolved_len - 1] != '/') {
if (resolved_len + 1 >= PATH_MAX) {
+ if (m)
+ free(resolved);
errno = ENAMETOOLONG;
return (NULL);
}
@@ -133,6 +156,8 @@ realpath(const char *path, char resolved[PATH_MAX])
*/
resolved_len = strlcat(resolved, next_token, PATH_MAX);
if (resolved_len >= PATH_MAX) {
+ if (m)
+ free(resolved);
errno = ENAMETOOLONG;
return (NULL);
}
@@ -141,16 +166,23 @@ realpath(const char *path, char resolved[PATH_MAX])
errno = serrno;
return (resolved);
}
+ if (m)
+ free(resolved);
return (NULL);
}
if (S_ISLNK(sb.st_mode)) {
if (symlinks++ > MAXSYMLINKS) {
+ if (m)
+ free(resolved);
errno = ELOOP;
return (NULL);
}
slen = readlink(resolved, symlink, sizeof(symlink) - 1);
- if (slen < 0)
+ if (slen < 0) {
+ if (m)
+ free(resolved);
return (NULL);
+ }
symlink[slen] = '\0';
if (symlink[0] == '/') {
resolved[1] = 0;
@@ -171,6 +203,8 @@ realpath(const char *path, char resolved[PATH_MAX])
if (p != NULL) {
if (symlink[slen - 1] != '/') {
if (slen + 1 >= sizeof(symlink)) {
+ if (m)
+ free(resolved);
errno = ENAMETOOLONG;
return (NULL);
}
@@ -179,6 +213,8 @@ realpath(const char *path, char resolved[PATH_MAX])
}
left_len = strlcat(symlink, left, sizeof(left));
if (left_len >= sizeof(left)) {
+ if (m)
+ free(resolved);
errno = ENAMETOOLONG;
return (NULL);
}
diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c
index 860a988..2bc1f2b 100644
--- a/lib/libc/string/strlen.c
+++ b/lib/libc/string/strlen.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Xin LI <delphij@FreeBSD.org>
+ * Copyright (c) 2009, 2010 Xin LI <delphij@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,15 +43,17 @@ __FBSDID("$FreeBSD$");
* ((x - 0x01....01) & ~x & 0x80....80)
*
* would evaluate to a non-zero value iff any of the bytes in the
- * original word is zero. However, we can further reduce ~1/3 of
- * time if we consider that strlen() usually operate on 7-bit ASCII
- * by employing the following expression, which allows false positive
- * when high bit of 1 and use the tail case to catch these case:
+ * original word is zero.
*
- * ((x - 0x01....01) & 0x80....80)
+ * On multi-issue processors, we can divide the above expression into:
+ * a) (x - 0x01....01)
+ * b) (~x & 0x80....80)
+ * c) a & b
*
- * This is more than 5.2 times as fast as the raw implementation on
- * Intel T7300 under long mode for strings longer than word length.
+ * Where, a) and b) can be partially computed in parallel.
+ *
+ * The algorithm above is found on "Hacker's Delight" by
+ * Henry S. Warren, Jr.
*/
/* Magic numbers for the algorithm */
@@ -82,29 +84,47 @@ strlen(const char *str)
{
const char *p;
const unsigned long *lp;
+ long va, vb;
- /* Skip the first few bytes until we have an aligned p */
- for (p = str; (uintptr_t)p & LONGPTR_MASK; p++)
- if (*p == '\0')
- return (p - str);
+ /*
+ * Before trying the hard (unaligned byte-by-byte access) way
+ * to figure out whether there is a nul character, try to see
+ * if there is a nul character is within this accessible word
+ * first.
+ *
+ * p and (p & ~LONGPTR_MASK) must be equally accessible since
+ * they always fall in the same memory page, as long as page
+ * boundaries is integral multiple of word size.
+ */
+ lp = (const unsigned long *)((uintptr_t)str & ~LONGPTR_MASK);
+ va = (*lp - mask01);
+ vb = ((~*lp) & mask80);
+ lp++;
+ if (va & vb)
+ /* Check if we have \0 in the first part */
+ for (p = str; p < (const char *)lp; p++)
+ if (*p == '\0')
+ return (p - str);
/* Scan the rest of the string using word sized operation */
- for (lp = (const unsigned long *)p; ; lp++)
- if ((*lp - mask01) & mask80) {
- p = (const char *)(lp);
- testbyte(0);
- testbyte(1);
- testbyte(2);
- testbyte(3);
+ for (; ; lp++) {
+ va = (*lp - mask01);
+ vb = ((~*lp) & mask80);
+ if (va & vb) {
+ p = (const char *)(lp);
+ testbyte(0);
+ testbyte(1);
+ testbyte(2);
+ testbyte(3);
#if (LONG_BIT >= 64)
- testbyte(4);
- testbyte(5);
- testbyte(6);
- testbyte(7);
+ testbyte(4);
+ testbyte(5);
+ testbyte(6);
+ testbyte(7);
#endif
- }
+ }
+ }
/* NOTREACHED */
return (0);
}
-
diff --git a/lib/libc/sys/mlockall.2 b/lib/libc/sys/mlockall.2
index db4c4a9..d09ce27 100644
--- a/lib/libc/sys/mlockall.2
+++ b/lib/libc/sys/mlockall.2
@@ -15,13 +15,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2
index 4849973..b633cb1 100644
--- a/lib/libc/sys/mmap.2
+++ b/lib/libc/sys/mmap.2
@@ -105,7 +105,7 @@ The file descriptor used for creating
must be \-1.
The
.Fa offset
-argument is ignored.
+argument must be 0.
.\".It Dv MAP_FILE
.\"Mapped from a regular file or character-special device memory.
.It Dv MAP_ANONYMOUS
@@ -316,6 +316,11 @@ was equal to zero.
was specified and the
.Fa fd
argument was not -1.
+.It Bq Er EINVAL
+.Dv MAP_ANON
+was specified and the
+.Fa offset
+argument was not 0.
.It Bq Er ENODEV
.Dv MAP_ANON
has not been specified and
diff --git a/lib/libc/sys/ntp_adjtime.2 b/lib/libc/sys/ntp_adjtime.2
index 5f5185f..65ff8a3 100644
--- a/lib/libc/sys/ntp_adjtime.2
+++ b/lib/libc/sys/ntp_adjtime.2
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
index 3a5979f..04fa0fe 100644
--- a/lib/libc/sys/open.2
+++ b/lib/libc/sys/open.2
@@ -117,6 +117,7 @@ O_SYNC synchronous writes
O_NOFOLLOW do not follow symlinks
O_NOCTTY don't assign controlling terminal
O_TTY_INIT restore default terminal attributes
+O_DIRECTORY error if file is not a directory
.Ed
.Pp
Opening a file with
@@ -222,6 +223,14 @@ The initial call to
on a TTY will always restore default terminal attributes on
.Fx .
.Pp
+.Dv O_DIRECTORY
+may be used to ensure the resulting file descriptor refers to a
+directory.
+This flag can be used to prevent applications with elevated privileges
+from opening files which are even unsafe to open with
+.Dv O_RDONLY ,
+such as device nodes.
+.Pp
If successful,
.Fn open
returns a non-negative integer, termed a file descriptor.
@@ -413,6 +422,9 @@ argument is not an absolute path and
is neither
.Dv AT_FDCWD
nor a file descriptor associated with a directory.
+.It Bq Eq ENOTDIR
+.Dv O_DIRECTORY
+is specified and the file is not a directory.
.El
.Sh SEE ALSO
.Xr chmod 2 ,
diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
index 4c4f18f..3b4f2f0 100644
--- a/lib/libc/sys/sigaction.2
+++ b/lib/libc/sys/sigaction.2
@@ -28,7 +28,7 @@
.\" From: @(#)sigaction.2 8.2 (Berkeley) 4/3/94
.\" $FreeBSD$
.\"
-.Dd June 7, 2004
+.Dd April 18, 2010
.Dt SIGACTION 2
.Os
.Sh NAME
@@ -40,16 +40,11 @@
.In signal.h
.Bd -literal
struct sigaction {
- union {
- void (*__sa_handler)(int);
- void (*__sa_sigaction)(int, struct __siginfo *, void *);
- } __sigaction_u; /* signal handler */
+ void (*sa_handler)(int);
+ void (*sa_sigaction)(int, siginfo_t *, void *);
int sa_flags; /* see signal options below */
sigset_t sa_mask; /* signal mask to apply */
};
-
-#define sa_handler __sigaction_u.__sa_handler
-#define sa_sigaction __sigaction_u.__sa_sigaction
.Ed
.Ft int
.Fo sigaction
@@ -148,6 +143,16 @@ If
is non-zero, the previous handling information for the signal
is returned to the user.
.Pp
+The above declaration of
+.Vt "struct sigaction"
+is not literal.
+It is provided only to list the accessible members.
+See
+.In sys/signal.h
+for the actual definition.
+In particular, the storage occupied by sa_handler and sa_sigaction overlaps,
+and an application can not use both simultaneously.
+.Pp
Once a signal handler is installed, it normally remains installed
until another
.Fn sigaction
diff --git a/lib/libc/sys/stat.2 b/lib/libc/sys/stat.2
index 3085ef0..85f0cf0 100644
--- a/lib/libc/sys/stat.2
+++ b/lib/libc/sys/stat.2
@@ -28,7 +28,7 @@
.\" @(#)stat.2 8.4 (Berkeley) 5/1/95
.\" $FreeBSD$
.\"
-.Dd April 10, 2008
+.Dd March 28, 2010
.Dt STAT 2
.Os
.Sh NAME
@@ -149,8 +149,8 @@ fields together identify the file uniquely within the system.
The time-related fields of
.Vt "struct stat"
are as follows:
-.Bl -tag -width ".Va st_birthtime"
-.It Va st_atime
+.Bl -tag -width ".Va st_birthtim"
+.It Va st_atim
Time when file data last accessed.
Changed by the
.Xr mknod 2 ,
@@ -159,7 +159,7 @@ Changed by the
and
.Xr readv 2
system calls.
-.It Va st_mtime
+.It Va st_mtim
Time when file data last modified.
Changed by the
.Xr mkdir 2 ,
@@ -170,7 +170,7 @@ Changed by the
and
.Xr writev 2
system calls.
-.It Va st_ctime
+.It Va st_ctim
Time when file status was last changed (inode data modification).
Changed by the
.Xr chflags 2 ,
@@ -191,18 +191,24 @@ Changed by the
and
.Xr writev 2
system calls.
-.It Va st_birthtime
+.It Va st_birthtim
Time when the inode was created.
.El
.Pp
-If
-.Dv _POSIX_SOURCE
-is not defined, the time-related fields are defined as:
+The following time-related macros are defined for compatibility:
.Bd -literal
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+#ifndef _POSIX_SOURCE
+#define st_birthtime st_birthtim.tv_sec
+#endif
+
#ifndef _POSIX_SOURCE
-#define st_atime st_atimespec.tv_sec
-#define st_mtime st_mtimespec.tv_sec
-#define st_ctime st_ctimespec.tv_sec
+#define st_atimespec st_atim
+#define st_mtimespec st_mtim
+#define st_ctimespec st_ctim
+#define st_birthtimespec st_birthtim
#endif
.Ed
.Pp
diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2
index 141f3d3..bb27085 100644
--- a/lib/libc/sys/unlink.2
+++ b/lib/libc/sys/unlink.2
@@ -28,7 +28,7 @@
.\" @(#)unlink.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd April 10, 2008
+.Dd April 25, 2010
.Dt UNLINK 2
.Os
.Sh NAME
@@ -167,7 +167,7 @@ argument does not specify an absolute path and the
argument is neither
.Dv AT_FDCWD
nor a valid file descriptor open for searching.
-.It Bq Er EEXIST
+.It Bq Er ENOTEMPTY
The
.Fa flag
parameter has the
diff --git a/lib/libc/sys/utrace.2 b/lib/libc/sys/utrace.2
index a83c185..5177288 100644
--- a/lib/libc/sys/utrace.2
+++ b/lib/libc/sys/utrace.2
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
diff --git a/lib/libcam/cam.3 b/lib/libcam/cam.3
index 539709f..3a857b2 100644
--- a/lib/libcam/cam.3
+++ b/lib/libcam/cam.3
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd October 10, 1998
-.Os
.Dt CAM 3
+.Os
.Sh NAME
.Nm cam_open_device ,
.Nm cam_open_spec_device ,
diff --git a/lib/libcam/cam_cdbparse.3 b/lib/libcam/cam_cdbparse.3
index 891652d..35a5951 100644
--- a/lib/libcam/cam_cdbparse.3
+++ b/lib/libcam/cam_cdbparse.3
@@ -62,8 +62,8 @@
.\"
.\"
.Dd October 13, 1998
-.Os
.Dt CAM_CDBPARSE 3
+.Os
.Sh NAME
.Nm csio_build ,
.Nm csio_build_visit ,
diff --git a/lib/libcompat/4.1/ascftime.c b/lib/libcompat/4.1/ascftime.c
index b3c15e4..cfb90af 100644
--- a/lib/libcompat/4.1/ascftime.c
+++ b/lib/libcompat/4.1/ascftime.c
@@ -41,5 +41,6 @@
int
ascftime(char *s, const char *format, const struct tm *tmptr)
{
- return strftime(s, MAXLEN, format? format: "%C", tmptr);
+
+ return (strftime(s, MAXLEN, format? format: "%C", tmptr));
}
diff --git a/lib/libcompat/4.1/cftime.3 b/lib/libcompat/4.1/cftime.3
index 116f5de..dd21e78 100644
--- a/lib/libcompat/4.1/cftime.3
+++ b/lib/libcompat/4.1/cftime.3
@@ -35,8 +35,8 @@
.\" $FreeBSD$
.\"
.Dd June 15, 1993
-.Os
.Dt CFTIME 3
+.Os
.Sh NAME
.Nm cftime ,
.Nm ascftime
diff --git a/lib/libcompat/4.1/cftime.c b/lib/libcompat/4.1/cftime.c
index 8033e44..41275b6 100644
--- a/lib/libcompat/4.1/cftime.c
+++ b/lib/libcompat/4.1/cftime.c
@@ -41,6 +41,7 @@
int
cftime(char *s, char *format, const time_t *clock)
{
- return strftime(s, MAXLEN, format? format: "%C", localtime(clock));
+
+ return (strftime(s, MAXLEN, format? format: "%C", localtime(clock)));
}
diff --git a/lib/libcompat/4.1/ftime.c b/lib/libcompat/4.1/ftime.c
index cc4a7f9..e7be278 100644
--- a/lib/libcompat/4.1/ftime.c
+++ b/lib/libcompat/4.1/ftime.c
@@ -37,8 +37,7 @@ static char rcsid[] = "$FreeBSD$";
#include <sys/timeb.h>
int
-ftime(tbp)
- struct timeb *tbp;
+ftime(struct timeb *tbp)
{
struct timezone tz;
struct timeval t;
diff --git a/lib/libcompat/4.1/getpw.c b/lib/libcompat/4.1/getpw.c
index d6f4f8b..7c66c8f 100644
--- a/lib/libcompat/4.1/getpw.c
+++ b/lib/libcompat/4.1/getpw.c
@@ -40,13 +40,14 @@
int
getpw(uid_t uid, char *buf)
{
- struct passwd *pw;
+ struct passwd *pw;
- pw = getpwuid(uid);
- endpwent();
+ pw = getpwuid(uid);
+ endpwent();
- if(pw == 0) return -1;
+ if (pw == 0)
+ return (-1);
- strncpy(buf, pw->pw_name, L_cuserid);
- return 0;
+ strncpy(buf, pw->pw_name, L_cuserid);
+ return (0);
}
diff --git a/lib/libcompat/4.3/cfree.c b/lib/libcompat/4.3/cfree.c
index ca51d2e..7a7baad 100644
--- a/lib/libcompat/4.3/cfree.c
+++ b/lib/libcompat/4.3/cfree.c
@@ -39,5 +39,6 @@ static char sccsid[] = "@(#)cfree.c 8.1 (Berkeley) 6/4/93";
void
cfree(void *p)
{
+
free(p);
}
diff --git a/lib/libcompat/4.3/re_comp.3 b/lib/libcompat/4.3/re_comp.3
index e3b595a..4d970fa 100644
--- a/lib/libcompat/4.3/re_comp.3
+++ b/lib/libcompat/4.3/re_comp.3
@@ -100,15 +100,10 @@ returns \-1 for an internal error.
The
.Fn re_comp
function
-returns one of the following strings if an error occurs:
-.Bd -unfilled -offset indent
-No previous regular expression,
-Regular expression too long,
-unmatched \e(,
-missing ],
-too many \e(\e) pairs,
-unmatched \e).
-.Ed
+returns
+.Dq no previous regular expression
+or one of the strings generated by
+.Xr regerror 3 .
.Sh SEE ALSO
.Xr ed 1 ,
.Xr egrep 1 ,
diff --git a/lib/libcompat/4.3/regex.c b/lib/libcompat/4.3/re_comp.c
index 470cab5..dbe57b1 100644
--- a/lib/libcompat/4.3/regex.c
+++ b/lib/libcompat/4.3/re_comp.c
@@ -44,49 +44,49 @@ __FBSDID("$FreeBSD$");
static char sccsid[] = "@(#)regex.c 5.1 (Berkeley) 3/29/92";
#endif /* LIBC_SCCS and not lint */
-#include <sys/types.h>
+#include <regex.h>
#include <stddef.h>
-#include <regexp.h>
-#include <string.h>
-#include <stdlib.h>
-#include <string.h>
+#include <unistd.h>
-static regexp *re_regexp;
-static int re_goterr;
-static char *re_errstr;
+static regex_t re_regexp;
+static int re_gotexp;
+static char re_errstr[100];
char *
-re_comp(char *s)
+re_comp(const char *s)
{
+ int rc;
+
if (s == NULL || *s == '\0') {
- if (re_regexp == NULL)
- return "no previous regular expression";
+ if (!re_gotexp)
+ return __DECONST(char *,
+ "no previous regular expression");
return (NULL);
}
- if (re_regexp)
- free(re_regexp);
- if (re_errstr)
- free(re_errstr);
- re_goterr = 0;
- re_regexp = regcomp(s);
- return (re_goterr ? re_errstr : NULL);
+
+ if (re_gotexp) {
+ regfree(&re_regexp);
+ re_gotexp = 0;
+ }
+
+ rc = regcomp(&re_regexp, s, REG_EXTENDED);
+ if (rc == 0) {
+ re_gotexp = 1;
+ return (NULL);
+ }
+
+ regerror(rc, &re_regexp, re_errstr, sizeof(re_errstr));
+ re_errstr[sizeof(re_errstr) - 1] = '\0';
+ return (re_errstr);
}
int
-re_exec(char *s)
+re_exec(const char *s)
{
int rc;
- re_goterr = 0;
- rc = regexec(re_regexp, s);
- return (re_goterr ? -1 : rc);
-}
-
-void
-regerror(const char *s)
-{
- re_goterr = 1;
- if (re_errstr)
- free(re_errstr);
- re_errstr = strdup(s);
+ if (!re_gotexp)
+ return (-1);
+ rc = regexec(&re_regexp, s, 0, NULL, 0);
+ return (rc == 0 ? 1 : 0);
}
diff --git a/lib/libcompat/4.4/cuserid.3 b/lib/libcompat/4.4/cuserid.3
index 72811d5..addd616 100644
--- a/lib/libcompat/4.4/cuserid.3
+++ b/lib/libcompat/4.4/cuserid.3
@@ -32,8 +32,8 @@
.\" $FreeBSD$
.\"
.Dd April 10, 1995
-.Os
.Dt CUSERID 3
+.Os
.Sh NAME
.Nm cuserid
.Nd get user name associated with effective UID
diff --git a/lib/libcompat/Makefile b/lib/libcompat/Makefile
index 2ca46f0..35ced5f 100644
--- a/lib/libcompat/Makefile
+++ b/lib/libcompat/Makefile
@@ -1,19 +1,15 @@
# @(#)Makefile 8.1 (Berkeley) 6/4/93
# $FreeBSD$
-LIB=compat
+LIB= compat
CFLAGS+=-DLIBC_SCCS -DSYSLIBC_SCCS -I${.CURDIR}/../libc/locale
NO_PIC=
-WARNS?= 1
+WARNS?= 0
-.PATH: ${.CURDIR}/4.1/${MACHINE_ARCH} ${.CURDIR}/4.1 \
- ${.CURDIR}/4.3/${MACHINE_ARCH} ${.CURDIR}/4.3 \
- ${.CURDIR}/4.4/${MACHINE_ARCH} ${.CURDIR}/4.4 \
- ${.CURDIR}/regexp
+.PATH: ${.CURDIR}/4.1 ${.CURDIR}/4.3 ${.CURDIR}/4.4
# compat 4.1 sources
-# XXX MISSING: tell.c
SRCS+= ascftime.c cftime.c ftime.c getpw.c
MAN+= 4.1/ftime.3 4.1/getpw.3
@@ -22,27 +18,15 @@ MAN+= 4.1/cftime.3
MLINKS+=cftime.3 ascftime.3
# compat 4.3 sources
-# XXX MISSING: ecvt.c gcvt.c sibuf.c sobuf.c strout.c
-SRCS+= cfree.c regex.c rexec.c
+SRCS+= cfree.c re_comp.c rexec.c
-# XXX MISSING: ecvt.0
MAN+= 4.3/cfree.3 4.3/re_comp.3 4.3/rexec.3
-# XXX MISSING: ecvt.3, so can't MLINK
-#MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
MLINKS+=re_comp.3 re_exec.3
# compat 4.4 sources
SRCS+= cuserid.c
-MAN+= 4.4/cuserid.3
-
-# regexp sources
-SRCS+= regerror.c regexp.c regsub.c
-MAN+= regexp/regexp.3
-
-# XXX name clash with libc
-# MLINKS+=regexp.3 regcomp.3 regexp.3 regexec.3 regexp.3 regerror.3
-MLINKS+=regexp.3 regsub.3
+MAN+= 4.4/cuserid.3
.include <bsd.lib.mk>
diff --git a/lib/libcompat/regexp/COPYRIGHT b/lib/libcompat/regexp/COPYRIGHT
deleted file mode 100644
index 48b3f43..0000000
--- a/lib/libcompat/regexp/COPYRIGHT
+++ /dev/null
@@ -1,22 +0,0 @@
-This entire subtree is copyright the University of Toronto.
-The following copyright notice applies to all files found here. None of
-these files contain AT&T proprietary source code.
-_____________________________________________________________________________
-
- Copyright (c) 1986 by University of Toronto.
- Written by Henry Spencer. Not derived from licensed software.
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
diff --git a/lib/libcompat/regexp/README b/lib/libcompat/regexp/README
deleted file mode 100644
index 37d6f51..0000000
--- a/lib/libcompat/regexp/README
+++ /dev/null
@@ -1,84 +0,0 @@
-This is a nearly-public-domain reimplementation of the V8 regexp(3) package.
-It gives C programs the ability to use egrep-style regular expressions, and
-does it in a much cleaner fashion than the analogous routines in SysV.
-
- Copyright (c) 1986 by University of Toronto.
- Written by Henry Spencer. Not derived from licensed software.
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
-Barring a couple of small items in the BUGS list, this implementation is
-believed 100% compatible with V8. It should even be binary-compatible,
-sort of, since the only fields in a "struct regexp" that other people have
-any business touching are declared in exactly the same way at the same
-location in the struct (the beginning).
-
-This implementation is *NOT* AT&T/Bell code, and is not derived from licensed
-software. Even though U of T is a V8 licensee. This software is based on
-a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed
-here is a complete rewrite and hence is not covered by AT&T copyright).
-The software was nearly complete at the time of arrival of our V8 tape.
-I haven't even looked at V8 yet, although a friend elsewhere at U of T has
-been kind enough to run a few test programs using the V8 regexp(3) to resolve
-a few fine points. I admit to some familiarity with regular-expression
-implementations of the past, but the only one that this code traces any
-ancestry to is the one published in Kernighan & Plauger (from which this
-one draws ideas but not code).
-
-Simplistically: put this stuff into a source directory, copy regexp.h into
-/usr/include, inspect Makefile for compilation options that need changing
-to suit your local environment, and then do "make r". This compiles the
-regexp(3) functions, compiles a test program, and runs a large set of
-regression tests. If there are no complaints, then put regexp.o, regsub.o,
-and regerror.o into your C library, and regexp.3 into your manual-pages
-directory.
-
-Note that if you don't put regexp.h into /usr/include *before* compiling,
-you'll have to add "-I." to CFLAGS before compiling.
-
-The files are:
-
-Makefile instructions to make everything
-regexp.3 manual page
-regexp.h header file, for /usr/include
-regexp.c source for regcomp() and regexec()
-regsub.c source for regsub()
-regerror.c source for default regerror()
-regmagic.h internal header file
-try.c source for test program
-timer.c source for timing program
-tests test list for try and timer
-
-This implementation uses nondeterministic automata rather than the
-deterministic ones found in some other implementations, which makes it
-simpler, smaller, and faster at compiling regular expressions, but slower
-at executing them. In theory, anyway. This implementation does employ
-some special-case optimizations to make the simpler cases (which do make
-up the bulk of regular expressions actually used) run quickly. In general,
-if you want blazing speed you're in the wrong place. Replacing the insides
-of egrep with this stuff is probably a mistake; if you want your own egrep
-you're going to have to do a lot more work. But if you want to use regular
-expressions a little bit in something else, you're in luck. Note that many
-existing text editors use nondeterministic regular-expression implementations,
-so you're in good company.
-
-This stuff should be pretty portable, given appropriate option settings.
-If your chars have less than 8 bits, you're going to have to change the
-internal representation of the automaton, although knowledge of the details
-of this is fairly localized. There are no "reserved" char values except for
-NUL, and no special significance is attached to the top bit of chars.
-The string(3) functions are used a fair bit, on the grounds that they are
-probably faster than coding the operations in line. Some attempts at code
-tuning have been made, but this is invariably a bit machine-specific.
diff --git a/lib/libcompat/regexp/regerror.c b/lib/libcompat/regexp/regerror.c
deleted file mode 100644
index 6d0077d..0000000
--- a/lib/libcompat/regexp/regerror.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <regexp.h>
-#include <stdio.h>
-
-void
-regerror(s)
-const char *s;
-{
-#ifdef ERRAVAIL
- error("regexp: %s", s);
-#else
-/*
- fprintf(stderr, "regexp(3): %s\n", s);
- exit(1);
-*/
- return; /* let std. egrep handle errors */
-#endif
- /* NOTREACHED */
-}
diff --git a/lib/libcompat/regexp/regexp.3 b/lib/libcompat/regexp/regexp.3
deleted file mode 100644
index 14b3125..0000000
--- a/lib/libcompat/regexp/regexp.3
+++ /dev/null
@@ -1,319 +0,0 @@
-.\" Copyright (c) 1991, 1993
-.\" The Regents of the University of California. 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.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
-.\"
-.\" @(#)regexp.3 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD$
-.\"
-.Dd June 4, 1993
-.Dt REGEXP 3
-.Os
-.Sh NAME
-.Nm regcomp ,
-.Nm regexec ,
-.Nm regsub ,
-.Nm regerror
-.Nd regular expression handlers
-.Sh LIBRARY
-.Lb libcompat
-.Sh SYNOPSIS
-.In regexp.h
-.Ft regexp *
-.Fn regcomp "const char *exp"
-.Ft int
-.Fn regexec "const regexp *prog" "const char *string"
-.Ft void
-.Fn regsub "const regexp *prog" "const char *source" "char *dest"
-.Sh DESCRIPTION
-.Bf Sy
-This interface is made obsolete by
-.Xr regex 3 .
-.Ef
-.Pp
-The
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-functions
-implement
-.Xr egrep 1 Ns -style
-regular expressions and supporting facilities.
-.Pp
-The
-.Fn regcomp
-function
-compiles a regular expression into a structure of type
-.Vt regexp ,
-and returns a pointer to it.
-The space has been allocated using
-.Xr malloc 3
-and may be released by
-.Xr free 3 .
-.Pp
-The
-.Fn regexec
-function
-matches a
-.Dv NUL Ns -terminated
-.Fa string
-against the compiled regular expression
-in
-.Fa prog .
-It returns 1 for success and 0 for failure, and adjusts the contents of
-.Fa prog Ns 's
-.Em startp
-and
-.Em endp
-(see below) accordingly.
-.Pp
-The members of a
-.Vt regexp
-structure include at least the following (not necessarily in order):
-.Bd -literal -offset indent
-char *startp[NSUBEXP];
-char *endp[NSUBEXP];
-.Ed
-.Pp
-where
-.Dv NSUBEXP
-is defined (as 10) in the header file.
-Once a successful
-.Fn regexec
-has been done using the
-.Fn regexp ,
-each
-.Em startp Ns - Em endp
-pair describes one substring
-within the
-.Fa string ,
-with the
-.Em startp
-pointing to the first character of the substring and
-the
-.Em endp
-pointing to the first character following the substring.
-The 0th substring is the substring of
-.Fa string
-that matched the whole
-regular expression.
-The others are those substrings that matched parenthesized expressions
-within the regular expression, with parenthesized expressions numbered
-in left-to-right order of their opening parentheses.
-.Pp
-The
-.Fn regsub
-function
-copies
-.Fa source
-to
-.Fa dest ,
-making substitutions according to the
-most recent
-.Fn regexec
-performed using
-.Fa prog .
-Each instance of `&' in
-.Fa source
-is replaced by the substring
-indicated by
-.Em startp Ns Bq
-and
-.Em endp Ns Bq .
-Each instance of
-.Sq \e Ns Em n ,
-where
-.Em n
-is a digit, is replaced by
-the substring indicated by
-.Em startp Ns Bq Em n
-and
-.Em endp Ns Bq Em n .
-To get a literal `&' or
-.Sq \e Ns Em n
-into
-.Fa dest ,
-prefix it with `\e';
-to get a literal `\e' preceding `&' or
-.Sq \e Ns Em n ,
-prefix it with
-another `\e'.
-.Pp
-The
-.Fn regerror
-function
-is called whenever an error is detected in
-.Fn regcomp ,
-.Fn regexec ,
-or
-.Fn regsub .
-The default
-.Fn regerror
-writes the string
-.Fa msg ,
-with a suitable indicator of origin,
-on the standard
-error output
-and invokes
-.Xr exit 3 .
-The
-.Fn regerror
-function
-can be replaced by the user if other actions are desirable.
-.Sh REGULAR EXPRESSION SYNTAX
-A regular expression is zero or more
-.Em branches ,
-separated by `|'.
-It matches anything that matches one of the branches.
-.Pp
-A branch is zero or more
-.Em pieces ,
-concatenated.
-It matches a match for the first, followed by a match for the second, etc.
-.Pp
-A piece is an
-.Em atom
-possibly followed by `*', `+', or `?'.
-An atom followed by `*' matches a sequence of 0 or more matches of the atom.
-An atom followed by `+' matches a sequence of 1 or more matches of the atom.
-An atom followed by `?' matches a match of the atom, or the null string.
-.Pp
-An atom is a regular expression in parentheses (matching a match for the
-regular expression), a
-.Em range
-(see below), `.'
-(matching any single character), `^' (matching the null string at the
-beginning of the input string), `$' (matching the null string at the
-end of the input string), a `\e' followed by a single character (matching
-that character), or a single character with no other significance
-(matching that character).
-.Pp
-A
-.Em range
-is a sequence of characters enclosed in `[]'.
-It normally matches any single character from the sequence.
-If the sequence begins with `^',
-it matches any single character
-.Em not
-from the rest of the sequence.
-If two characters in the sequence are separated by `\-', this is shorthand
-for the full list of
-.Tn ASCII
-characters between them
-(e.g.\& `[0-9]' matches any decimal digit).
-To include a literal `]' in the sequence, make it the first character
-(following a possible `^').
-To include a literal `\-', make it the first or last character.
-.Sh AMBIGUITY
-If a regular expression could match two different parts of the input string,
-it will match the one which begins earliest.
-If both begin in the same place but match different lengths, or match
-the same length in different ways, life gets messier, as follows.
-.Pp
-In general, the possibilities in a list of branches are considered in
-left-to-right order, the possibilities for `*', `+', and `?' are
-considered longest-first, nested constructs are considered from the
-outermost in, and concatenated constructs are considered leftmost-first.
-The match that will be chosen is the one that uses the earliest
-possibility in the first choice that has to be made.
-If there is more than one choice, the next will be made in the same manner
-(earliest possibility) subject to the decision on the first choice.
-And so forth.
-.Pp
-For example,
-.Sq Li (ab|a)b*c
-could match
-`abc' in one of two ways.
-The first choice is between `ab' and `a'; since `ab' is earlier, and does
-lead to a successful overall match, it is chosen.
-Since the `b' is already spoken for,
-the `b*' must match its last possibility\(emthe empty string\(emsince
-it must respect the earlier choice.
-.Pp
-In the particular case where no `|'s are present and there is only one
-`*', `+', or `?', the net effect is that the longest possible
-match will be chosen.
-So
-.Sq Li ab* ,
-presented with `xabbbby', will match `abbbb'.
-Note that if
-.Sq Li ab* ,
-is tried against `xabyabbbz', it
-will match `ab' just after `x', due to the begins-earliest rule.
-(In effect, the decision on where to start the match is the first choice
-to be made, hence subsequent choices must respect it even if this leads them
-to less-preferred alternatives.)
-.Sh RETURN VALUES
-The
-.Fn regcomp
-function
-returns
-.Dv NULL
-for a failure
-.Pf ( Fn regerror
-permitting),
-where failures are syntax errors, exceeding implementation limits,
-or applying `+' or `*' to a possibly-null operand.
-.Sh SEE ALSO
-.Xr ed 1 ,
-.Xr egrep 1 ,
-.Xr ex 1 ,
-.Xr expr 1 ,
-.Xr fgrep 1 ,
-.Xr grep 1 ,
-.Xr regex 3
-.Sh HISTORY
-Both code and manual page for
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-were written at the University of Toronto
-and appeared in
-.Bx 4.3 tahoe .
-They are intended to be compatible with the Bell V8
-.Xr regexp 3 ,
-but are not derived from Bell code.
-.Sh BUGS
-Empty branches and empty regular expressions are not portable to V8.
-.Pp
-The restriction against
-applying `*' or `+' to a possibly-null operand is an artifact of the
-simplistic implementation.
-.Pp
-Does not support
-.Xr egrep 1 Ns 's
-newline-separated branches;
-neither does the V8
-.Xr regexp 3 ,
-though.
-.Pp
-Due to emphasis on
-compactness and simplicity,
-it is not strikingly fast.
-It does give special attention to handling simple cases quickly.
diff --git a/lib/libcompat/regexp/regexp.c b/lib/libcompat/regexp/regexp.c
deleted file mode 100644
index 8276ffc..0000000
--- a/lib/libcompat/regexp/regexp.c
+++ /dev/null
@@ -1,1337 +0,0 @@
-/*
- * regcomp and regexec -- regsub and regerror are elsewhere
- *
- * Copyright (c) 1986 by University of Toronto.
- * Written by Henry Spencer. Not derived from licensed software.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to redistribute it freely,
- * subject to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of
- * this software, no matter how awful, even if they arise
- * from defects in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
- *** to assist in implementing egrep.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
- *** as in BSD grep and ex.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
- *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
- *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
- *
- * Beware that some of this code is subtly aware of the way operator
- * precedence is structured in regular expressions. Serious changes in
- * regular-expression syntax might require a total rethink.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <limits.h>
-#include <regexp.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include "collate.h"
-#include "regmagic.h"
-
-/*
- * The "internal use only" fields in regexp.h are present to pass info from
- * compile to execute that permits the execute phase to run lots faster on
- * simple cases. They are:
- *
- * regstart char that must begin a match; '\0' if none obvious
- * reganch is the match anchored (at beginning-of-line only)?
- * regmust string (pointer into program) that match must include, or NULL
- * regmlen length of regmust string
- *
- * Regstart and reganch permit very fast decisions on suitable starting points
- * for a match, cutting down the work a lot. Regmust permits fast rejection
- * of lines that cannot possibly match. The regmust tests are costly enough
- * that regcomp() supplies a regmust only if the r.e. contains something
- * potentially expensive (at present, the only such thing detected is * or +
- * at the start of the r.e., which can involve a lot of backup). Regmlen is
- * supplied because the test in regexec() needs it and regcomp() is computing
- * it anyway.
- */
-
-/*
- * Structure for regexp "program". This is essentially a linear encoding
- * of a nondeterministic finite-state machine (aka syntax charts or
- * "railroad normal form" in parsing technology). Each node is an opcode
- * plus a "next" pointer, possibly plus an operand. "Next" pointers of
- * all nodes except BRANCH implement concatenation; a "next" pointer with
- * a BRANCH on both ends of it is connecting two alternatives. (Here we
- * have one of the subtle syntax dependencies: an individual BRANCH (as
- * opposed to a collection of them) is never concatenated with anything
- * because of operator precedence.) The operand of some types of node is
- * a literal string; for others, it is a node leading into a sub-FSM. In
- * particular, the operand of a BRANCH node is the first node of the branch.
- * (NB this is *not* a tree structure: the tail of the branch connects
- * to the thing following the set of BRANCHes.) The opcodes are:
- */
-
-/* definition number opnd? meaning */
-#define END 0 /* no End of program. */
-#define BOL 1 /* no Match "" at beginning of line. */
-#define EOL 2 /* no Match "" at end of line. */
-#define ANY 3 /* no Match any one character. */
-#define ANYOF 4 /* str Match any character in this string. */
-#define ANYBUT 5 /* str Match any character not in this string. */
-#define BRANCH 6 /* node Match this alternative, or the next... */
-#define BACK 7 /* no Match "", "next" ptr points backward. */
-#define EXACTLY 8 /* str Match this string. */
-#define NOTHING 9 /* no Match empty string. */
-#define STAR 10 /* node Match this (simple) thing 0 or more times. */
-#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
-#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */
-#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */
-#define OPEN 20 /* no Mark this point in input as start of #n. */
- /* OPEN+1 is number 1, etc. */
-#define CLOSE 30 /* no Analogous to OPEN. */
-
-/*
- * Opcode notes:
- *
- * BRANCH The set of branches constituting a single choice are hooked
- * together with their "next" pointers, since precedence prevents
- * anything being concatenated to any individual branch. The
- * "next" pointer of the last BRANCH in a choice points to the
- * thing following the whole choice. This is also where the
- * final "next" pointer of each individual branch points; each
- * branch starts with the operand node of a BRANCH node.
- *
- * BACK Normal "next" pointers all implicitly point forward; BACK
- * exists to make loop structures possible.
- *
- * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
- * BRANCH structures using BACK. Simple cases (one character
- * per match) are implemented with STAR and PLUS for speed
- * and to minimize recursive plunges.
- *
- * OPEN,CLOSE ...are numbered at compile time.
- */
-
-/*
- * A node is one char of opcode followed by two chars of "next" pointer.
- * "Next" pointers are stored as two 8-bit pieces, high order first. The
- * value is a positive offset from the opcode of the node containing it.
- * An operand, if any, simply follows the node. (Note that much of the
- * code generation knows about this implicit relationship.)
- *
- * Using two bytes for the "next" pointer is vast overkill for most things,
- * but allows patterns to get big without disasters.
- */
-#define OP(p) (*(p))
-#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
-#define OPERAND(p) ((p) + 3)
-
-/*
- * See regmagic.h for one further detail of program structure.
- */
-
-
-/*
- * Utility definitions.
- */
-#ifndef CHARBITS
-#define UCHARAT(p) ((int)*(unsigned char *)(p))
-#else
-#define UCHARAT(p) ((int)*(p)&CHARBITS)
-#endif
-
-#define FAIL(m) { regerror(m); return(NULL); }
-#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
-
-/*
- * Flags to be passed up and down.
- */
-#define HASWIDTH 01 /* Known never to match null string. */
-#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
-#define SPSTART 04 /* Starts with * or +. */
-#define WORST 0 /* Worst case. */
-
-/*
- * Global work variables for regcomp().
- */
-static char *regparse; /* Input-scan pointer. */
-static int regnpar; /* () count. */
-static char regdummy;
-static char *regcode; /* Code-emit pointer; &regdummy = don't. */
-static long regsize; /* Code size. */
-
-/*
- * Forward declarations for regcomp()'s friends.
- */
-#ifndef STATIC
-#define STATIC static
-#endif
-STATIC char *reg();
-STATIC char *regbranch();
-STATIC char *regpiece();
-STATIC char *regatom();
-STATIC char *regnode();
-STATIC char *regnext();
-STATIC void regc();
-STATIC void reginsert();
-STATIC void regtail();
-STATIC void regoptail();
-#ifdef STRCSPN
-STATIC int strcspn();
-#endif
-
-/*
- - regcomp - compile a regular expression into internal code
- *
- * We can't allocate space until we know how big the compiled form will be,
- * but we can't compile it (and thus know how big it is) until we've got a
- * place to put the code. So we cheat: we compile it twice, once with code
- * generation turned off and size counting turned on, and once "for real".
- * This also means that we don't allocate space until we are sure that the
- * thing really will compile successfully, and we never have to move the
- * code and thus invalidate pointers into it. (Note that it has to be in
- * one piece because free() must be able to free it all.)
- *
- * Beware that the optimization-preparation code in here knows about some
- * of the structure of the compiled regexp.
- */
-regexp *
-regcomp(exp)
-const char *exp;
-{
- regexp *r;
- char *scan;
- char *longest;
- int len;
- int flags;
-
- if (exp == NULL)
- FAIL("NULL argument");
-
- /* First pass: determine size, legality. */
-#ifdef notdef
- if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */
-#endif
- regparse = (char *)exp;
- regnpar = 1;
- regsize = 0L;
- regcode = &regdummy;
- regc(MAGIC);
- if (reg(0, &flags) == NULL)
- return(NULL);
-
- /* Small enough for pointer-storage convention? */
- if (regsize >= 32767L) /* Probably could be 65535L. */
- FAIL("regexp too big");
-
- /* Allocate space. */
- r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
- if (r == NULL)
- FAIL("out of space");
-
- /* Second pass: emit code. */
- regparse = (char *)exp;
- regnpar = 1;
- regcode = r->program;
- regc(MAGIC);
- if (reg(0, &flags) == NULL)
- return(NULL);
-
- /* Dig out information for optimizations. */
- r->regstart = '\0'; /* Worst-case defaults. */
- r->reganch = 0;
- r->regmust = NULL;
- r->regmlen = 0;
- scan = r->program+1; /* First BRANCH. */
- if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
- scan = OPERAND(scan);
-
- /* Starting-point info. */
- if (OP(scan) == EXACTLY)
- r->regstart = *OPERAND(scan);
- else if (OP(scan) == BOL)
- r->reganch++;
-
- /*
- * If there's something expensive in the r.e., find the
- * longest literal string that must appear and make it the
- * regmust. Resolve ties in favor of later strings, since
- * the regstart check works with the beginning of the r.e.
- * and avoiding duplication strengthens checking. Not a
- * strong reason, but sufficient in the absence of others.
- */
- if (flags&SPSTART) {
- longest = NULL;
- len = 0;
- for (; scan != NULL; scan = regnext(scan))
- if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
- longest = OPERAND(scan);
- len = strlen(OPERAND(scan));
- }
- r->regmust = longest;
- r->regmlen = len;
- }
- }
-
- return(r);
-}
-
-/*
- - reg - regular expression, i.e. main body or parenthesized thing
- *
- * Caller must absorb opening parenthesis.
- *
- * Combining parenthesis handling with the base level of regular expression
- * is a trifle forced, but the need to tie the tails of the branches to what
- * follows makes it hard to avoid.
- */
-static char *
-reg(paren, flagp)
-int paren; /* Parenthesized? */
-int *flagp;
-{
- char *ret;
- char *br;
- char *ender;
- int parno;
- int flags;
-
- *flagp = HASWIDTH; /* Tentatively. */
-
- /* Make an OPEN node, if parenthesized. */
- if (paren) {
- if (regnpar >= NSUBEXP)
- FAIL("too many ()");
- parno = regnpar;
- regnpar++;
- ret = regnode(OPEN+parno);
- } else
- ret = NULL;
-
- /* Pick up the branches, linking them together. */
- br = regbranch(&flags);
- if (br == NULL)
- return(NULL);
- if (ret != NULL)
- regtail(ret, br); /* OPEN -> first. */
- else
- ret = br;
- if (!(flags&HASWIDTH))
- *flagp &= ~HASWIDTH;
- *flagp |= flags&SPSTART;
- while (*regparse == '|' || *regparse == '\n') {
- regparse++;
- br = regbranch(&flags);
- if (br == NULL)
- return(NULL);
- regtail(ret, br); /* BRANCH -> BRANCH. */
- if (!(flags&HASWIDTH))
- *flagp &= ~HASWIDTH;
- *flagp |= flags&SPSTART;
- }
-
- /* Make a closing node, and hook it on the end. */
- ender = regnode((paren) ? CLOSE+parno : END);
- regtail(ret, ender);
-
- /* Hook the tails of the branches to the closing node. */
- for (br = ret; br != NULL; br = regnext(br))
- regoptail(br, ender);
-
- /* Check for proper termination. */
- if (paren && *regparse++ != ')') {
- FAIL("unmatched ()");
- } else if (!paren && *regparse != '\0') {
- if (*regparse == ')') {
- FAIL("unmatched ()");
- } else
- FAIL("junk on end"); /* "Can't happen". */
- /* NOTREACHED */
- }
-
- return(ret);
-}
-
-/*
- - regbranch - one alternative of an | operator
- *
- * Implements the concatenation operator.
- */
-static char *
-regbranch(flagp)
-int *flagp;
-{
- char *ret;
- char *chain;
- char *latest;
- int flags;
-
- *flagp = WORST; /* Tentatively. */
-
- ret = regnode(BRANCH);
- chain = NULL;
- while (*regparse != '\0' && *regparse != ')' &&
- *regparse != '\n' && *regparse != '|') {
- latest = regpiece(&flags);
- if (latest == NULL)
- return(NULL);
- *flagp |= flags&HASWIDTH;
- if (chain == NULL) /* First piece. */
- *flagp |= flags&SPSTART;
- else
- regtail(chain, latest);
- chain = latest;
- }
- if (chain == NULL) /* Loop ran zero times. */
- (void) regnode(NOTHING);
-
- return(ret);
-}
-
-/*
- - regpiece - something followed by possible [*+?]
- *
- * Note that the branching code sequences used for ? and the general cases
- * of * and + are somewhat optimized: they use the same NOTHING node as
- * both the endmarker for their branch list and the body of the last branch.
- * It might seem that this node could be dispensed with entirely, but the
- * endmarker role is not redundant.
- */
-static char *
-regpiece(flagp)
-int *flagp;
-{
- char *ret;
- char op;
- char *next;
- int flags;
-
- ret = regatom(&flags);
- if (ret == NULL)
- return(NULL);
-
- op = *regparse;
- if (!ISMULT(op)) {
- *flagp = flags;
- return(ret);
- }
-
- if (!(flags&HASWIDTH) && op != '?')
- FAIL("*+ operand could be empty");
- *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
-
- if (op == '*' && (flags&SIMPLE))
- reginsert(STAR, ret);
- else if (op == '*') {
- /* Emit x* as (x&|), where & means "self". */
- reginsert(BRANCH, ret); /* Either x */
- regoptail(ret, regnode(BACK)); /* and loop */
- regoptail(ret, ret); /* back */
- regtail(ret, regnode(BRANCH)); /* or */
- regtail(ret, regnode(NOTHING)); /* null. */
- } else if (op == '+' && (flags&SIMPLE))
- reginsert(PLUS, ret);
- else if (op == '+') {
- /* Emit x+ as x(&|), where & means "self". */
- next = regnode(BRANCH); /* Either */
- regtail(ret, next);
- regtail(regnode(BACK), ret); /* loop back */
- regtail(next, regnode(BRANCH)); /* or */
- regtail(ret, regnode(NOTHING)); /* null. */
- } else if (op == '?') {
- /* Emit x? as (x|) */
- reginsert(BRANCH, ret); /* Either x */
- regtail(ret, regnode(BRANCH)); /* or */
- next = regnode(NOTHING); /* null. */
- regtail(ret, next);
- regoptail(ret, next);
- }
- regparse++;
- if (ISMULT(*regparse))
- FAIL("nested *?+");
-
- return(ret);
-}
-
-/*
- - regatom - the lowest level
- *
- * Optimization: gobbles an entire sequence of ordinary characters so that
- * it can turn them into a single node, which is smaller to store and
- * faster to run. Backslashed characters are exceptions, each becoming a
- * separate node; the code is simpler that way and it's not worth fixing.
- */
-static char *
-regatom(flagp)
-int *flagp;
-{
- char *ret;
- int flags;
-
- *flagp = WORST; /* Tentatively. */
-
- switch (*regparse++) {
- /* FIXME: these chars only have meaning at beg/end of pat? */
- case '^':
- ret = regnode(BOL);
- break;
- case '$':
- ret = regnode(EOL);
- break;
- case '.':
- ret = regnode(ANY);
- *flagp |= HASWIDTH|SIMPLE;
- break;
- case '[': {
- int class;
- int classend;
- int i;
-
- if (*regparse == '^') { /* Complement of range. */
- ret = regnode(ANYBUT);
- regparse++;
- } else
- ret = regnode(ANYOF);
- if (*regparse == ']' || *regparse == '-')
- regc(*regparse++);
- while (*regparse != '\0' && *regparse != ']') {
- if (*regparse == '-') {
- regparse++;
- if (*regparse == ']' || *regparse == '\0')
- regc('-');
- else {
- class = UCHARAT(regparse-2);
- classend = UCHARAT(regparse);
- if (__collate_load_error) {
- if (class > classend)
- FAIL("invalid [] range");
- for (class++; class <= classend; class++)
- regc(class);
- } else {
- if (__collate_range_cmp(class, classend) > 0)
- FAIL("invalid [] range");
- for (i = 0; i <= UCHAR_MAX; i++)
- if ( i != class
- && __collate_range_cmp(class, i) <= 0
- && __collate_range_cmp(i, classend) <= 0
- )
- regc(i);
- }
- regparse++;
- }
- } else
- regc(*regparse++);
- }
- regc('\0');
- if (*regparse != ']')
- FAIL("unmatched []");
- regparse++;
- *flagp |= HASWIDTH|SIMPLE;
- }
- break;
- case '(':
- ret = reg(1, &flags);
- if (ret == NULL)
- return(NULL);
- *flagp |= flags&(HASWIDTH|SPSTART);
- break;
- case '\0':
- case '|':
- case '\n':
- case ')':
- FAIL("internal urp"); /* Supposed to be caught earlier. */
- break;
- case '?':
- case '+':
- case '*':
- FAIL("?+* follows nothing");
- break;
- case '\\':
- switch (*regparse++) {
- case '\0':
- FAIL("trailing \\");
- break;
- case '<':
- ret = regnode(WORDA);
- break;
- case '>':
- ret = regnode(WORDZ);
- break;
- /* FIXME: Someday handle \1, \2, ... */
- default:
- /* Handle general quoted chars in exact-match routine */
- goto de_fault;
- }
- break;
- de_fault:
- default:
- /*
- * Encode a string of characters to be matched exactly.
- *
- * This is a bit tricky due to quoted chars and due to
- * '*', '+', and '?' taking the SINGLE char previous
- * as their operand.
- *
- * On entry, the char at regparse[-1] is going to go
- * into the string, no matter what it is. (It could be
- * following a \ if we are entered from the '\' case.)
- *
- * Basic idea is to pick up a good char in ch and
- * examine the next char. If it's *+? then we twiddle.
- * If it's \ then we frozzle. If it's other magic char
- * we push ch and terminate the string. If none of the
- * above, we push ch on the string and go around again.
- *
- * regprev is used to remember where "the current char"
- * starts in the string, if due to a *+? we need to back
- * up and put the current char in a separate, 1-char, string.
- * When regprev is NULL, ch is the only char in the
- * string; this is used in *+? handling, and in setting
- * flags |= SIMPLE at the end.
- */
- {
- char *regprev;
- char ch;
-
- regparse--; /* Look at cur char */
- ret = regnode(EXACTLY);
- for ( regprev = 0 ; ; ) {
- ch = *regparse++; /* Get current char */
- switch (*regparse) { /* look at next one */
-
- default:
- regc(ch); /* Add cur to string */
- break;
-
- case '.': case '[': case '(':
- case ')': case '|': case '\n':
- case '$': case '^':
- case '\0':
- /* FIXME, $ and ^ should not always be magic */
- magic:
- regc(ch); /* dump cur char */
- goto done; /* and we are done */
-
- case '?': case '+': case '*':
- if (!regprev) /* If just ch in str, */
- goto magic; /* use it */
- /* End mult-char string one early */
- regparse = regprev; /* Back up parse */
- goto done;
-
- case '\\':
- regc(ch); /* Cur char OK */
- switch (regparse[1]){ /* Look after \ */
- case '\0':
- case '<':
- case '>':
- /* FIXME: Someday handle \1, \2, ... */
- goto done; /* Not quoted */
- default:
- /* Backup point is \, scan * point is after it. */
- regprev = regparse;
- regparse++;
- continue; /* NOT break; */
- }
- }
- regprev = regparse; /* Set backup point */
- }
- done:
- regc('\0');
- *flagp |= HASWIDTH;
- if (!regprev) /* One char? */
- *flagp |= SIMPLE;
- }
- break;
- }
-
- return(ret);
-}
-
-/*
- - regnode - emit a node
- */
-static char * /* Location. */
-regnode(op)
-char op;
-{
- char *ret;
- char *ptr;
-
- ret = regcode;
- if (ret == &regdummy) {
- regsize += 3;
- return(ret);
- }
-
- ptr = ret;
- *ptr++ = op;
- *ptr++ = '\0'; /* Null "next" pointer. */
- *ptr++ = '\0';
- regcode = ptr;
-
- return(ret);
-}
-
-/*
- - regc - emit (if appropriate) a byte of code
- */
-static void
-regc(b)
-char b;
-{
- if (regcode != &regdummy)
- *regcode++ = b;
- else
- regsize++;
-}
-
-/*
- - reginsert - insert an operator in front of already-emitted operand
- *
- * Means relocating the operand.
- */
-static void
-reginsert(op, opnd)
-char op;
-char *opnd;
-{
- char *src;
- char *dst;
- char *place;
-
- if (regcode == &regdummy) {
- regsize += 3;
- return;
- }
-
- src = regcode;
- regcode += 3;
- dst = regcode;
- while (src > opnd)
- *--dst = *--src;
-
- place = opnd; /* Op node, where operand used to be. */
- *place++ = op;
- *place++ = '\0';
- *place++ = '\0';
-}
-
-/*
- - regtail - set the next-pointer at the end of a node chain
- */
-static void
-regtail(p, val)
-char *p;
-char *val;
-{
- char *scan;
- char *temp;
- int offset;
-
- if (p == &regdummy)
- return;
-
- /* Find last node. */
- scan = p;
- for (;;) {
- temp = regnext(scan);
- if (temp == NULL)
- break;
- scan = temp;
- }
-
- if (OP(scan) == BACK)
- offset = scan - val;
- else
- offset = val - scan;
- *(scan+1) = (offset>>8)&0377;
- *(scan+2) = offset&0377;
-}
-
-/*
- - regoptail - regtail on operand of first argument; nop if operandless
- */
-static void
-regoptail(p, val)
-char *p;
-char *val;
-{
- /* "Operandless" and "op != BRANCH" are synonymous in practice. */
- if (p == NULL || p == &regdummy || OP(p) != BRANCH)
- return;
- regtail(OPERAND(p), val);
-}
-
-/*
- * regexec and friends
- */
-
-/*
- * Global work variables for regexec().
- */
-static char *reginput; /* String-input pointer. */
-static char *regbol; /* Beginning of input, for ^ check. */
-static char **regstartp; /* Pointer to startp array. */
-static char **regendp; /* Ditto for endp. */
-
-/*
- * Forwards.
- */
-STATIC int regtry();
-STATIC int regmatch();
-STATIC int regrepeat();
-
-#ifdef DEBUG
-int regnarrate = 0;
-void regdump();
-STATIC char *regprop();
-#endif
-
-/*
- - regexec - match a regexp against a string
- */
-int
-regexec(prog, string)
-const regexp *prog;
-const char *string;
-{
- char *s;
- extern char *strchr();
-
- /* Be paranoid... */
- if (prog == NULL || string == NULL) {
- regerror("NULL parameter");
- return(0);
- }
-
- /* Check validity of program. */
- if (UCHARAT(prog->program) != MAGIC) {
- regerror("corrupted program");
- return(0);
- }
-
- /* If there is a "must appear" string, look for it. */
- if (prog->regmust != NULL) {
- s = (char *)string;
- while ((s = strchr(s, prog->regmust[0])) != NULL) {
- if (strncmp(s, prog->regmust, prog->regmlen) == 0)
- break; /* Found it. */
- s++;
- }
- if (s == NULL) /* Not present. */
- return(0);
- }
-
- /* Mark beginning of line for ^ . */
- regbol = (char *)string;
-
- /* Simplest case: anchored match need be tried only once. */
- if (prog->reganch)
- return(regtry(prog, string));
-
- /* Messy cases: unanchored match. */
- s = (char *)string;
- if (prog->regstart != '\0')
- /* We know what char it must start with. */
- while ((s = strchr(s, prog->regstart)) != NULL) {
- if (regtry(prog, s))
- return(1);
- s++;
- }
- else
- /* We don't -- general case. */
- do {
- if (regtry(prog, s))
- return(1);
- } while (*s++ != '\0');
-
- /* Failure. */
- return(0);
-}
-
-/*
- - regtry - try match at specific point
- */
-static int /* 0 failure, 1 success */
-regtry(prog, string)
-regexp *prog;
-char *string;
-{
- int i;
- char **sp;
- char **ep;
-
- reginput = string;
- regstartp = prog->startp;
- regendp = prog->endp;
-
- sp = prog->startp;
- ep = prog->endp;
- for (i = NSUBEXP; i > 0; i--) {
- *sp++ = NULL;
- *ep++ = NULL;
- }
- if (regmatch(prog->program + 1)) {
- prog->startp[0] = string;
- prog->endp[0] = reginput;
- return(1);
- } else
- return(0);
-}
-
-/*
- - regmatch - main matching routine
- *
- * Conceptually the strategy is simple: check to see whether the current
- * node matches, call self recursively to see whether the rest matches,
- * and then act accordingly. In practice we make some effort to avoid
- * recursion, in particular by going through "ordinary" nodes (that don't
- * need to know whether the rest of the match failed) by a loop instead of
- * by recursion.
- */
-static int /* 0 failure, 1 success */
-regmatch(prog)
-char *prog;
-{
- char *scan; /* Current node. */
- char *next; /* Next node. */
-
- scan = prog;
-#ifdef DEBUG
- if (scan != NULL && regnarrate)
- fprintf(stderr, "%s(\n", regprop(scan));
-#endif
- while (scan != NULL) {
-#ifdef DEBUG
- if (regnarrate)
- fprintf(stderr, "%s...\n", regprop(scan));
-#endif
- next = regnext(scan);
-
- switch (OP(scan)) {
- case BOL:
- if (reginput != regbol)
- return(0);
- break;
- case EOL:
- if (*reginput != '\0')
- return(0);
- break;
- case WORDA:
- /* Must be looking at a letter, digit, or _ */
- if ((!isalnum((unsigned char)*reginput)) && *reginput != '_')
- return(0);
- /* Prev must be BOL or nonword */
- if (reginput > regbol &&
- (isalnum((unsigned char)reginput[-1]) || reginput[-1] == '_'))
- return(0);
- break;
- case WORDZ:
- /* Must be looking at non letter, digit, or _ */
- if (isalnum((unsigned char)*reginput) || *reginput == '_')
- return(0);
- /* We don't care what the previous char was */
- break;
- case ANY:
- if (*reginput == '\0')
- return(0);
- reginput++;
- break;
- case EXACTLY: {
- int len;
- char *opnd;
-
- opnd = OPERAND(scan);
- /* Inline the first character, for speed. */
- if (*opnd != *reginput)
- return(0);
- len = strlen(opnd);
- if (len > 1 && strncmp(opnd, reginput, len) != 0)
- return(0);
- reginput += len;
- }
- break;
- case ANYOF:
- if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
- return(0);
- reginput++;
- break;
- case ANYBUT:
- if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
- return(0);
- reginput++;
- break;
- case NOTHING:
- break;
- case BACK:
- break;
- case OPEN+1:
- case OPEN+2:
- case OPEN+3:
- case OPEN+4:
- case OPEN+5:
- case OPEN+6:
- case OPEN+7:
- case OPEN+8:
- case OPEN+9: {
- int no;
- char *save;
-
- no = OP(scan) - OPEN;
- save = reginput;
-
- if (regmatch(next)) {
- /*
- * Don't set startp if some later
- * invocation of the same parentheses
- * already has.
- */
- if (regstartp[no] == NULL)
- regstartp[no] = save;
- return(1);
- } else
- return(0);
- }
- break;
- case CLOSE+1:
- case CLOSE+2:
- case CLOSE+3:
- case CLOSE+4:
- case CLOSE+5:
- case CLOSE+6:
- case CLOSE+7:
- case CLOSE+8:
- case CLOSE+9: {
- int no;
- char *save;
-
- no = OP(scan) - CLOSE;
- save = reginput;
-
- if (regmatch(next)) {
- /*
- * Don't set endp if some later
- * invocation of the same parentheses
- * already has.
- */
- if (regendp[no] == NULL)
- regendp[no] = save;
- return(1);
- } else
- return(0);
- }
- break;
- case BRANCH: {
- char *save;
-
- if (OP(next) != BRANCH) /* No choice. */
- next = OPERAND(scan); /* Avoid recursion. */
- else {
- do {
- save = reginput;
- if (regmatch(OPERAND(scan)))
- return(1);
- reginput = save;
- scan = regnext(scan);
- } while (scan != NULL && OP(scan) == BRANCH);
- return(0);
- /* NOTREACHED */
- }
- }
- break;
- case STAR:
- case PLUS: {
- char nextch;
- int no;
- char *save;
- int min;
-
- /*
- * Lookahead to avoid useless match attempts
- * when we know what character comes next.
- */
- nextch = '\0';
- if (OP(next) == EXACTLY)
- nextch = *OPERAND(next);
- min = (OP(scan) == STAR) ? 0 : 1;
- save = reginput;
- no = regrepeat(OPERAND(scan));
- while (no >= min) {
- /* If it could work, try it. */
- if (nextch == '\0' || *reginput == nextch)
- if (regmatch(next))
- return(1);
- /* Couldn't or didn't -- back up. */
- no--;
- reginput = save + no;
- }
- return(0);
- }
- break;
- case END:
- return(1); /* Success! */
- break;
- default:
- regerror("memory corruption");
- return(0);
- break;
- }
-
- scan = next;
- }
-
- /*
- * We get here only if there's trouble -- normally "case END" is
- * the terminating point.
- */
- regerror("corrupted pointers");
- return(0);
-}
-
-/*
- - regrepeat - repeatedly match something simple, report how many
- */
-static int
-regrepeat(p)
-char *p;
-{
- int count = 0;
- char *scan;
- char *opnd;
-
- scan = reginput;
- opnd = OPERAND(p);
- switch (OP(p)) {
- case ANY:
- count = strlen(scan);
- scan += count;
- break;
- case EXACTLY:
- while (*opnd == *scan) {
- count++;
- scan++;
- }
- break;
- case ANYOF:
- while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
- count++;
- scan++;
- }
- break;
- case ANYBUT:
- while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
- count++;
- scan++;
- }
- break;
- default: /* Oh dear. Called inappropriately. */
- regerror("internal foulup");
- count = 0; /* Best compromise. */
- break;
- }
- reginput = scan;
-
- return(count);
-}
-
-/*
- - regnext - dig the "next" pointer out of a node
- */
-static char *
-regnext(p)
-char *p;
-{
- int offset;
-
- if (p == &regdummy)
- return(NULL);
-
- offset = NEXT(p);
- if (offset == 0)
- return(NULL);
-
- if (OP(p) == BACK)
- return(p-offset);
- else
- return(p+offset);
-}
-
-#ifdef DEBUG
-
-STATIC char *regprop();
-
-/*
- - regdump - dump a regexp onto stdout in vaguely comprehensible form
- */
-void
-regdump(r)
-regexp *r;
-{
- char *s;
- char op = EXACTLY; /* Arbitrary non-END op. */
- char *next;
- extern char *strchr();
-
-
- s = r->program + 1;
- while (op != END) { /* While that wasn't END last time... */
- op = OP(s);
- printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
- next = regnext(s);
- if (next == NULL) /* Next ptr. */
- printf("(0)");
- else
- printf("(%d)", (s-r->program)+(next-s));
- s += 3;
- if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
- /* Literal string, where present. */
- while (*s != '\0') {
- putchar(*s);
- s++;
- }
- s++;
- }
- putchar('\n');
- }
-
- /* Header fields of interest. */
- if (r->regstart != '\0')
- printf("start `%c' ", r->regstart);
- if (r->reganch)
- printf("anchored ");
- if (r->regmust != NULL)
- printf("must have \"%s\"", r->regmust);
- printf("\n");
-}
-
-/*
- - regprop - printable representation of opcode
- */
-static char *
-regprop(op)
-char *op;
-{
- char *p;
- static char buf[50];
-
- (void) strcpy(buf, ":");
-
- switch (OP(op)) {
- case BOL:
- p = "BOL";
- break;
- case EOL:
- p = "EOL";
- break;
- case ANY:
- p = "ANY";
- break;
- case ANYOF:
- p = "ANYOF";
- break;
- case ANYBUT:
- p = "ANYBUT";
- break;
- case BRANCH:
- p = "BRANCH";
- break;
- case EXACTLY:
- p = "EXACTLY";
- break;
- case NOTHING:
- p = "NOTHING";
- break;
- case BACK:
- p = "BACK";
- break;
- case END:
- p = "END";
- break;
- case OPEN+1:
- case OPEN+2:
- case OPEN+3:
- case OPEN+4:
- case OPEN+5:
- case OPEN+6:
- case OPEN+7:
- case OPEN+8:
- case OPEN+9:
- sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
- p = NULL;
- break;
- case CLOSE+1:
- case CLOSE+2:
- case CLOSE+3:
- case CLOSE+4:
- case CLOSE+5:
- case CLOSE+6:
- case CLOSE+7:
- case CLOSE+8:
- case CLOSE+9:
- sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
- p = NULL;
- break;
- case STAR:
- p = "STAR";
- break;
- case PLUS:
- p = "PLUS";
- break;
- case WORDA:
- p = "WORDA";
- break;
- case WORDZ:
- p = "WORDZ";
- break;
- default:
- regerror("corrupted opcode");
- break;
- }
- if (p != NULL)
- (void) strcat(buf, p);
- return(buf);
-}
-#endif
-
-/*
- * The following is provided for those people who do not have strcspn() in
- * their C libraries. They should get off their butts and do something
- * about it; at least one public-domain implementation of those (highly
- * useful) string routines has been published on Usenet.
- */
-#ifdef STRCSPN
-/*
- * strcspn - find length of initial segment of s1 consisting entirely
- * of characters not from s2
- */
-
-static int
-strcspn(s1, s2)
-char *s1;
-char *s2;
-{
- char *scan1;
- char *scan2;
- int count;
-
- count = 0;
- for (scan1 = s1; *scan1 != '\0'; scan1++) {
- for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
- if (*scan1 == *scan2++)
- return(count);
- count++;
- }
- return(count);
-}
-#endif
diff --git a/lib/libcompat/regexp/regmagic.h b/lib/libcompat/regexp/regmagic.h
deleted file mode 100644
index 5acf447..0000000
--- a/lib/libcompat/regexp/regmagic.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * The first byte of the regexp internal "program" is actually this magic
- * number; the start node begins in the second byte.
- */
-#define MAGIC 0234
diff --git a/lib/libcompat/regexp/regsub.c b/lib/libcompat/regexp/regsub.c
deleted file mode 100644
index 4ab921c..0000000
--- a/lib/libcompat/regexp/regsub.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * regsub
- *
- * Copyright (c) 1986 by University of Toronto.
- * Written by Henry Spencer. Not derived from licensed software.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to redistribute it freely,
- * subject to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of
- * this software, no matter how awful, even if they arise
- * from defects in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <regexp.h>
-#include <stdio.h>
-#include <string.h>
-#include "regmagic.h"
-
-#ifndef CHARBITS
-#define UCHARAT(p) ((int)*(unsigned char *)(p))
-#else
-#define UCHARAT(p) ((int)*(p)&CHARBITS)
-#endif
-
-/*
- - regsub - perform substitutions after a regexp match
- */
-void
-regsub(prog, source, dest)
-const regexp *prog;
-const char *source;
-char *dest;
-{
- char *src;
- char *dst;
- char c;
- int no;
- int len;
- extern char *strncpy();
-
- if (prog == NULL || source == NULL || dest == NULL) {
- regerror("NULL parm to regsub");
- return;
- }
- if (UCHARAT(prog->program) != MAGIC) {
- regerror("damaged regexp fed to regsub");
- return;
- }
-
- src = (char *)source;
- dst = dest;
- while ((c = *src++) != '\0') {
- if (c == '&')
- no = 0;
- else if (c == '\\' && '0' <= *src && *src <= '9')
- no = *src++ - '0';
- else
- no = -1;
- if (no < 0) { /* Ordinary character. */
- if (c == '\\' && (*src == '\\' || *src == '&'))
- c = *src++;
- *dst++ = c;
- } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
- len = prog->endp[no] - prog->startp[no];
- (void) strncpy(dst, prog->startp[no], len);
- dst += len;
- if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
- regerror("damaged match string");
- return;
- }
- }
- }
- *dst++ = '\0';
-}
diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3
index d5dfff5..9794649 100644
--- a/lib/libedit/editline.3
+++ b/lib/libedit/editline.3
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd January 12, 2007
-.Os
.Dt EDITLINE 3
+.Os
.Sh NAME
.Nm editline ,
.Nm el_init ,
diff --git a/lib/libedit/editrc.5 b/lib/libedit/editrc.5
index 4b1d414..2fa1a63 100644
--- a/lib/libedit/editrc.5
+++ b/lib/libedit/editrc.5
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd October 18, 2003
-.Os
.Dt EDITRC 5
+.Os
.Sh NAME
.Nm editrc
.Nd configuration file for editline library
diff --git a/lib/libelf/elf.3 b/lib/libelf/elf.3
index 854e1af..c649efe 100644
--- a/lib/libelf/elf.3
+++ b/lib/libelf/elf.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 21, 2007
-.Os
.Dt ELF 3
+.Os
.Sh NAME
.Nm elf
.Nd API for manipulating ELF objects
diff --git a/lib/libelf/elf_begin.3 b/lib/libelf/elf_begin.3
index c43766f..dac4910 100644
--- a/lib/libelf/elf_begin.3
+++ b/lib/libelf/elf_begin.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 21, 2006
-.Os
.Dt ELF_BEGIN 3
+.Os
.Sh NAME
.Nm elf_begin
.Nd open an ELF file or ar(1) archive
diff --git a/lib/libelf/elf_cntl.3 b/lib/libelf/elf_cntl.3
index 73dca21..5277170 100644
--- a/lib/libelf/elf_cntl.3
+++ b/lib/libelf/elf_cntl.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 9, 2006
-.Os
.Dt ELF_CNTL 3
+.Os
.Sh NAME
.Nm elf_cntl
.Nd control an elf file descriptor
diff --git a/lib/libelf/elf_end.3 b/lib/libelf/elf_end.3
index 0f74a89..3622fb2 100644
--- a/lib/libelf/elf_end.3
+++ b/lib/libelf/elf_end.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 29, 2006
-.Os
.Dt ELF_END 3
+.Os
.Sh NAME
.Nm elf_end
.Nd release an ELF descriptor
diff --git a/lib/libelf/elf_errmsg.3 b/lib/libelf/elf_errmsg.3
index 1ed70bf..f014168 100644
--- a/lib/libelf/elf_errmsg.3
+++ b/lib/libelf/elf_errmsg.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 11, 2006
-.Os
.Dt ELF_ERRMSG 3
+.Os
.Sh NAME
.Nm elf_errmsg ,
.Nm elf_errno
diff --git a/lib/libelf/elf_fill.3 b/lib/libelf/elf_fill.3
index 33446b9..a635b43 100644
--- a/lib/libelf/elf_fill.3
+++ b/lib/libelf/elf_fill.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 11, 2006
-.Os
.Dt ELF_FILL 3
+.Os
.Sh NAME
.Nm elf_fill
.Nd set fill byte for inter-section padding
diff --git a/lib/libelf/elf_flagdata.3 b/lib/libelf/elf_flagdata.3
index 30c1111..b07e524 100644
--- a/lib/libelf/elf_flagdata.3
+++ b/lib/libelf/elf_flagdata.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 22, 2007
-.Os
.Dt ELF_FLAGDATA 3
+.Os
.Sh NAME
.Nm elf_flagdata ,
.Nm elf_flagehdr ,
diff --git a/lib/libelf/elf_getarhdr.3 b/lib/libelf/elf_getarhdr.3
index f78fc80..03f911a 100644
--- a/lib/libelf/elf_getarhdr.3
+++ b/lib/libelf/elf_getarhdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 15, 2006
-.Os
.Dt ELF_GETARHDR 3
+.Os
.Sh NAME
.Nm elf_getarhdr
.Nd retrieve ar(1) header for an archive member
diff --git a/lib/libelf/elf_getarsym.3 b/lib/libelf/elf_getarsym.3
index 1030ea2..44b28c8 100644
--- a/lib/libelf/elf_getarsym.3
+++ b/lib/libelf/elf_getarsym.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 15, 2006
-.Os
.Dt ELF_GETARSYM 3
+.Os
.Sh NAME
.Nm elf_getarsym
.Nd retrieve the symbol table of an archive
diff --git a/lib/libelf/elf_getbase.3 b/lib/libelf/elf_getbase.3
index 30be6c5..be9d103 100644
--- a/lib/libelf/elf_getbase.3
+++ b/lib/libelf/elf_getbase.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 11, 2006
-.Os
.Dt ELF_GETBASE 3
+.Os
.Sh NAME
.Nm elf_getbase
.Nd get the base offset for an object file
diff --git a/lib/libelf/elf_getdata.3 b/lib/libelf/elf_getdata.3
index 64da4ad..10f3763 100644
--- a/lib/libelf/elf_getdata.3
+++ b/lib/libelf/elf_getdata.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 26, 2006
-.Os
.Dt ELF_GETDATA 3
+.Os
.Sh NAME
.Nm elf_getdata ,
.Nm elf_newdata ,
diff --git a/lib/libelf/elf_getident.3 b/lib/libelf/elf_getident.3
index f34ab70..1031e1d 100644
--- a/lib/libelf/elf_getident.3
+++ b/lib/libelf/elf_getident.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd July 3, 2006
-.Os
.Dt ELF_GETIDENT 3
+.Os
.Sh NAME
.Nm elf_getident
.Nd return the initial bytes of a file
diff --git a/lib/libelf/elf_getphnum.3 b/lib/libelf/elf_getphnum.3
index 606ceb0..308f87c 100644
--- a/lib/libelf/elf_getphnum.3
+++ b/lib/libelf/elf_getphnum.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd December 16, 2006
-.Os
.Dt ELF_GETPHNUM 3
+.Os
.Sh NAME
.Nm elf_getphnum
.Nd return the number of program headers in an ELF file
diff --git a/lib/libelf/elf_getscn.3 b/lib/libelf/elf_getscn.3
index 5b9de41..1b1b5f9 100644
--- a/lib/libelf/elf_getscn.3
+++ b/lib/libelf/elf_getscn.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 22, 2007
-.Os
.Dt ELF_GETSCN 3
+.Os
.Sh NAME
.Nm elf_getscn ,
.Nm elf_ndxscn ,
diff --git a/lib/libelf/elf_getshnum.3 b/lib/libelf/elf_getshnum.3
index 10a370c..7c8a04c 100644
--- a/lib/libelf/elf_getshnum.3
+++ b/lib/libelf/elf_getshnum.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 31, 2006
-.Os
.Dt ELF_GETSHNUM 3
+.Os
.Sh NAME
.Nm elf_getshnum
.Nd return the number of sections in an ELF file
diff --git a/lib/libelf/elf_getshstrndx.3 b/lib/libelf/elf_getshstrndx.3
index 115b2da..71df3ac 100644
--- a/lib/libelf/elf_getshstrndx.3
+++ b/lib/libelf/elf_getshstrndx.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 31, 2006
-.Os
.Dt ELF_GETSHSTRNDX 3
+.Os
.Sh NAME
.Nm elf_getshstrndx ,
.Nm elf_setshstrndx
diff --git a/lib/libelf/elf_hash.3 b/lib/libelf/elf_hash.3
index 0209598..0df2804 100644
--- a/lib/libelf/elf_hash.3
+++ b/lib/libelf/elf_hash.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 15, 2006
-.Os
.Dt ELF_HASH 3
+.Os
.Sh NAME
.Nm elf_hash
.Nd compute a hash value for a string
diff --git a/lib/libelf/elf_kind.3 b/lib/libelf/elf_kind.3
index def1582..de74e57 100644
--- a/lib/libelf/elf_kind.3
+++ b/lib/libelf/elf_kind.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 1, 2006
-.Os
.Dt ELF_KIND 3
+.Os
.Sh NAME
.Nm elf_kind
.Nd determine ELF file type
diff --git a/lib/libelf/elf_memory.3 b/lib/libelf/elf_memory.3
index 9af6c5e..83de512 100644
--- a/lib/libelf/elf_memory.3
+++ b/lib/libelf/elf_memory.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 28, 2006
-.Os
.Dt ELF_MEMORY 3
+.Os
.Sh NAME
.Nm elf_memory
.Nd process an ELF or ar(1) archive mapped into memory
diff --git a/lib/libelf/elf_next.3 b/lib/libelf/elf_next.3
index da995fc..184ab9f 100644
--- a/lib/libelf/elf_next.3
+++ b/lib/libelf/elf_next.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 17, 2006
-.Os
.Dt ELF_NEXT 3
+.Os
.Sh NAME
.Nm elf_next
.Nd provide sequential access to the next archive member
diff --git a/lib/libelf/elf_rand.3 b/lib/libelf/elf_rand.3
index 46cec6d..e4d23d7 100644
--- a/lib/libelf/elf_rand.3
+++ b/lib/libelf/elf_rand.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 17, 2006
-.Os
.Dt ELF_RAND 3
+.Os
.Sh NAME
.Nm elf_rand
.Nd provide sequential access to the next archive member
diff --git a/lib/libelf/elf_rawfile.3 b/lib/libelf/elf_rawfile.3
index 76026e7..4458148 100644
--- a/lib/libelf/elf_rawfile.3
+++ b/lib/libelf/elf_rawfile.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd July 3, 2006
-.Os
.Dt ELF_RAWFILE 3
+.Os
.Sh NAME
.Nm elf_rawfile
.Nd return uninterpreted contents of an ELF file
diff --git a/lib/libelf/elf_strptr.3 b/lib/libelf/elf_strptr.3
index bf24cc1..a0a9e64 100644
--- a/lib/libelf/elf_strptr.3
+++ b/lib/libelf/elf_strptr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd December 16, 2006
-.Os
.Dt ELF_STRPTR 3
+.Os
.Sh NAME
.Nm elf_strptr
.Nd retrieve a string pointer in a string table
diff --git a/lib/libelf/elf_update.3 b/lib/libelf/elf_update.3
index 33a14d1..7f6f4f0 100644
--- a/lib/libelf/elf_update.3
+++ b/lib/libelf/elf_update.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd March 19, 2008
-.Os
.Dt ELF_UPDATE 3
+.Os
.Sh NAME
.Nm elf_update
.Nd update an ELF descriptor
diff --git a/lib/libelf/elf_version.3 b/lib/libelf/elf_version.3
index 25ea62b..e918710 100644
--- a/lib/libelf/elf_version.3
+++ b/lib/libelf/elf_version.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 1, 2006
-.Os
.Dt ELF_VERSION 3
+.Os
.Sh NAME
.Nm elf_version
.Nd retrieve or set ELF library operating version
diff --git a/lib/libelf/gelf.3 b/lib/libelf/gelf.3
index 4ab5ff2..d541388 100644
--- a/lib/libelf/gelf.3
+++ b/lib/libelf/gelf.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 1, 2006
-.Os
.Dt GELF 3
+.Os
.Sh NAME
.Nm GElf
.Nd class-independent API for ELF manipulation
diff --git a/lib/libelf/gelf_checksum.3 b/lib/libelf/gelf_checksum.3
index a6f1978..99870f0 100644
--- a/lib/libelf/gelf_checksum.3
+++ b/lib/libelf/gelf_checksum.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_CHECKSUM 3
+.Os
.Sh NAME
.Nm elf32_checksum ,
.Nm elf64_checksum ,
diff --git a/lib/libelf/gelf_fsize.3 b/lib/libelf/gelf_fsize.3
index 915d840..caefae7 100644
--- a/lib/libelf/gelf_fsize.3
+++ b/lib/libelf/gelf_fsize.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd February 5, 2008
-.Os
.Dt GELF_FSIZE 3
+.Os
.Sh NAME
.Nm gelf_fsize ,
.Nm elf32_fsize ,
diff --git a/lib/libelf/gelf_getcap.3 b/lib/libelf/gelf_getcap.3
index f6262d8..e63a263 100644
--- a/lib/libelf/gelf_getcap.3
+++ b/lib/libelf/gelf_getcap.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETCAP 3
+.Os
.Sh NAME
.Nm gelf_getcap ,
.Nm gelf_update_cap
diff --git a/lib/libelf/gelf_getclass.3 b/lib/libelf/gelf_getclass.3
index cab3e24..7f7bc30 100644
--- a/lib/libelf/gelf_getclass.3
+++ b/lib/libelf/gelf_getclass.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd July 3, 2006
-.Os
.Dt GELF_GETCLASS 3
+.Os
.Sh NAME
.Nm gelf_getclass
.Nd retrieve the class of an ELF descriptor
diff --git a/lib/libelf/gelf_getdyn.3 b/lib/libelf/gelf_getdyn.3
index 1124444..a755d63 100644
--- a/lib/libelf/gelf_getdyn.3
+++ b/lib/libelf/gelf_getdyn.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETDYN 3
+.Os
.Sh NAME
.Nm gelf_getdyn ,
.Nm gelf_update_dyn
diff --git a/lib/libelf/gelf_getehdr.3 b/lib/libelf/gelf_getehdr.3
index d4c8cb3..8e71c2d 100644
--- a/lib/libelf/gelf_getehdr.3
+++ b/lib/libelf/gelf_getehdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd December 16, 2006
-.Os
.Dt GELF_GETEHDR 3
+.Os
.Sh NAME
.Nm elf32_getehdr ,
.Nm elf64_getehdr ,
diff --git a/lib/libelf/gelf_getmove.3 b/lib/libelf/gelf_getmove.3
index 11fd9ca..abe398a 100644
--- a/lib/libelf/gelf_getmove.3
+++ b/lib/libelf/gelf_getmove.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETMOVE 3
+.Os
.Sh NAME
.Nm gelf_getmove ,
.Nm gelf_update_move
diff --git a/lib/libelf/gelf_getphdr.3 b/lib/libelf/gelf_getphdr.3
index d6ffb90..53fab17 100644
--- a/lib/libelf/gelf_getphdr.3
+++ b/lib/libelf/gelf_getphdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 21, 2007
-.Os
.Dt GELF_GETPHDR 3
+.Os
.Sh NAME
.Nm elf32_getphdr ,
.Nm elf64_getphdr ,
diff --git a/lib/libelf/gelf_getrel.3 b/lib/libelf/gelf_getrel.3
index 75fa79e..6e650a5 100644
--- a/lib/libelf/gelf_getrel.3
+++ b/lib/libelf/gelf_getrel.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETREL 3
+.Os
.Sh NAME
.Nm gelf_getrel ,
.Nm gelf_update_rel
diff --git a/lib/libelf/gelf_getrela.3 b/lib/libelf/gelf_getrela.3
index d8968f5..dc7e579 100644
--- a/lib/libelf/gelf_getrela.3
+++ b/lib/libelf/gelf_getrela.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETRELA 3
+.Os
.Sh NAME
.Nm gelf_getrela ,
.Nm gelf_update_rela
diff --git a/lib/libelf/gelf_getshdr.3 b/lib/libelf/gelf_getshdr.3
index c1823b5..851f51f 100644
--- a/lib/libelf/gelf_getshdr.3
+++ b/lib/libelf/gelf_getshdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 27, 2006
-.Os
.Dt GELF_GETSHDR 3
+.Os
.Sh NAME
.Nm elf32_getshdr ,
.Nm elf64_getshdr ,
diff --git a/lib/libelf/gelf_getsym.3 b/lib/libelf/gelf_getsym.3
index 4e35133..56a6783 100644
--- a/lib/libelf/gelf_getsym.3
+++ b/lib/libelf/gelf_getsym.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETSYM 3
+.Os
.Sh NAME
.Nm gelf_getsym ,
.Nm gelf_update_sym
diff --git a/lib/libelf/gelf_getsyminfo.3 b/lib/libelf/gelf_getsyminfo.3
index 904e649..12da80f 100644
--- a/lib/libelf/gelf_getsyminfo.3
+++ b/lib/libelf/gelf_getsyminfo.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2006
-.Os
.Dt GELF_GETSYMINFO 3
+.Os
.Sh NAME
.Nm gelf_getsyminfo ,
.Nm gelf_update_syminfo
diff --git a/lib/libelf/gelf_getsymshndx.3 b/lib/libelf/gelf_getsymshndx.3
index c254a43..d79c392 100644
--- a/lib/libelf/gelf_getsymshndx.3
+++ b/lib/libelf/gelf_getsymshndx.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 5, 2006
-.Os
.Dt GELF_GETSYMSHNDX 3
+.Os
.Sh NAME
.Nm gelf_getsymshndx ,
.Nm gelf_update_symshndx
diff --git a/lib/libelf/gelf_newehdr.3 b/lib/libelf/gelf_newehdr.3
index 98820e2..6a2edf8 100644
--- a/lib/libelf/gelf_newehdr.3
+++ b/lib/libelf/gelf_newehdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 22, 2007
-.Os
.Dt GELF_NEWEHDR 3
+.Os
.Sh NAME
.Nm elf32_newehdr ,
.Nm elf64_newehdr ,
diff --git a/lib/libelf/gelf_newphdr.3 b/lib/libelf/gelf_newphdr.3
index 3d669b6..bd13e5d 100644
--- a/lib/libelf/gelf_newphdr.3
+++ b/lib/libelf/gelf_newphdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 22, 2007
-.Os
.Dt GELF_NEWPHDR 3
+.Os
.Sh NAME
.Nm elf32_newphdr ,
.Nm elf64_newphdr ,
diff --git a/lib/libelf/gelf_update_ehdr.3 b/lib/libelf/gelf_update_ehdr.3
index 8209831..df23a0c 100644
--- a/lib/libelf/gelf_update_ehdr.3
+++ b/lib/libelf/gelf_update_ehdr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 27, 2006
-.Os
.Dt GELF_UPDATE_EHDR 3
+.Os
.Sh NAME
.Nm gelf_update_ehdr ,
.Nm gelf_update_phdr ,
diff --git a/lib/libelf/gelf_xlatetof.3 b/lib/libelf/gelf_xlatetof.3
index b769930..453f56f 100644
--- a/lib/libelf/gelf_xlatetof.3
+++ b/lib/libelf/gelf_xlatetof.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 2006
-.Os
.Dt GELF_XLATETOF 3
+.Os
.Sh NAME
.Nm elf32_xlate ,
.Nm elf64_xlate ,
diff --git a/lib/libgssapi/gss_accept_sec_context.3 b/lib/libgssapi/gss_accept_sec_context.3
index 8957831..a4c219c 100644
--- a/lib/libgssapi/gss_accept_sec_context.3
+++ b/lib/libgssapi/gss_accept_sec_context.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_ACCEPT_SEC_CONTEXT 3 PRM
+.Os
.Sh NAME
.Nm gss_accept_sec_context
.Nd Accept a security context initiated by a peer application
diff --git a/lib/libgssapi/gss_acquire_cred.3 b/lib/libgssapi/gss_acquire_cred.3
index c48a468..5de9ea0 100644
--- a/lib/libgssapi/gss_acquire_cred.3
+++ b/lib/libgssapi/gss_acquire_cred.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_ACQUIRE_CRED 3 PRM
+.Os
.Sh NAME
.Nm gss_acquire_cred
.Nd Obtain a GSS-API credential handle for pre-existing credentials
diff --git a/lib/libgssapi/gss_add_cred.3 b/lib/libgssapi/gss_add_cred.3
index 53df140..67ff1c3 100644
--- a/lib/libgssapi/gss_add_cred.3
+++ b/lib/libgssapi/gss_add_cred.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_ADD_CRED 3 PRM
+.Os
.Sh NAME
.Nm gss_add_cred
.Nd Construct credentials incrementally
diff --git a/lib/libgssapi/gss_add_oid_set_member.3 b/lib/libgssapi/gss_add_oid_set_member.3
index fb2119c..5839da6 100644
--- a/lib/libgssapi/gss_add_oid_set_member.3
+++ b/lib/libgssapi/gss_add_oid_set_member.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_ADD_OID_SET_MEMBER 3 PRM
+.Os
.Sh NAME
.Nm gss_add_oid_set_member
.Nd Add an object identifier to a set
diff --git a/lib/libgssapi/gss_canonicalize_name.3 b/lib/libgssapi/gss_canonicalize_name.3
index 86957dc..036c0ef 100644
--- a/lib/libgssapi/gss_canonicalize_name.3
+++ b/lib/libgssapi/gss_canonicalize_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_CANONICALIZE_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_canonicalize_name
.Nd Convert an internal name to an MN
diff --git a/lib/libgssapi/gss_compare_name.3 b/lib/libgssapi/gss_compare_name.3
index 7f69d43..0bafb59 100644
--- a/lib/libgssapi/gss_compare_name.3
+++ b/lib/libgssapi/gss_compare_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_COMPARE_NAME PRM
+.Os
.Sh NAME
.Nm gss_compare_name
.Nd Compare two internal-form names
diff --git a/lib/libgssapi/gss_context_time.3 b/lib/libgssapi/gss_context_time.3
index 9fb43ea..b6b4157 100644
--- a/lib/libgssapi/gss_context_time.3
+++ b/lib/libgssapi/gss_context_time.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_CONTEXT_TIME 3 PRM
+.Os
.Sh NAME
.Nm gss_context_time
.Nd Determine for how long a context will remain valid
diff --git a/lib/libgssapi/gss_create_empty_oid_set.3 b/lib/libgssapi/gss_create_empty_oid_set.3
index 08d82f6..3a84f85 100644
--- a/lib/libgssapi/gss_create_empty_oid_set.3
+++ b/lib/libgssapi/gss_create_empty_oid_set.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_CREATE_EMPTY_OID_SET 3 PRM
+.Os
.Sh NAME
.Nm gss_create_empty_oid_set
.Nd Create a set containing no object identifiers
diff --git a/lib/libgssapi/gss_delete_sec_context.3 b/lib/libgssapi/gss_delete_sec_context.3
index a0c26df..1c4fa7b 100644
--- a/lib/libgssapi/gss_delete_sec_context.3
+++ b/lib/libgssapi/gss_delete_sec_context.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_DELETE_SEC_CONTEXT 3 PRM
+.Os
.Sh NAME
.Nm gss_delete_sec_context
.Nd Discard a security context
diff --git a/lib/libgssapi/gss_display_name.3 b/lib/libgssapi/gss_display_name.3
index 2441eef..4944995 100644
--- a/lib/libgssapi/gss_display_name.3
+++ b/lib/libgssapi/gss_display_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_DISPLAY_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_display_name
.Nd Convert internal-form name to text
diff --git a/lib/libgssapi/gss_display_status.3 b/lib/libgssapi/gss_display_status.3
index 2b1affd..4bf908b 100644
--- a/lib/libgssapi/gss_display_status.3
+++ b/lib/libgssapi/gss_display_status.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_DISPLAY_STATUS 3 PRM
+.Os
.Sh NAME
.Nm gss_display_status
.Nd Convert a GSS-API status code to text
diff --git a/lib/libgssapi/gss_duplicate_name.3 b/lib/libgssapi/gss_duplicate_name.3
index 334a126..5eb4a62 100644
--- a/lib/libgssapi/gss_duplicate_name.3
+++ b/lib/libgssapi/gss_duplicate_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_DUPLICATE_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_duplicate_name
.Nd Create a copy of an internal name
diff --git a/lib/libgssapi/gss_export_name.3 b/lib/libgssapi/gss_export_name.3
index e1feee2..5cbf803 100644
--- a/lib/libgssapi/gss_export_name.3
+++ b/lib/libgssapi/gss_export_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_EXPORT_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_export_name
.Nd Convert an MN to export form
diff --git a/lib/libgssapi/gss_export_sec_context.3 b/lib/libgssapi/gss_export_sec_context.3
index 1f7f01d..7ecbef3 100644
--- a/lib/libgssapi/gss_export_sec_context.3
+++ b/lib/libgssapi/gss_export_sec_context.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_EXPORT_SEC_CONTEXT 3 PRM
+.Os
.Sh NAME
.Nm gss_export_sec_context
.Nd Transfer a security context to another process
diff --git a/lib/libgssapi/gss_get_mic.3 b/lib/libgssapi/gss_get_mic.3
index 8892808..e5d81fa 100644
--- a/lib/libgssapi/gss_get_mic.3
+++ b/lib/libgssapi/gss_get_mic.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_GET_MIC 3 PRM
+.Os
.Sh NAME
.Nm gss_get_mic ,
.Nm gss_sign
diff --git a/lib/libgssapi/gss_import_name.3 b/lib/libgssapi/gss_import_name.3
index 3119f04..aef1ae8 100644
--- a/lib/libgssapi/gss_import_name.3
+++ b/lib/libgssapi/gss_import_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_IMPORT_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_import_name
.Nd Convert a contiguous string name to internal-form
diff --git a/lib/libgssapi/gss_import_sec_context.3 b/lib/libgssapi/gss_import_sec_context.3
index a889e2b..87aaa78 100644
--- a/lib/libgssapi/gss_import_sec_context.3
+++ b/lib/libgssapi/gss_import_sec_context.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_IMPORT_SEC_CONTEXT 3 PRM
+.Os
.Sh NAME
.Nm gss_import_sec_context
.Nd Import a transferred context
diff --git a/lib/libgssapi/gss_indicate_mechs.3 b/lib/libgssapi/gss_indicate_mechs.3
index 26ffaa6..3eec861 100644
--- a/lib/libgssapi/gss_indicate_mechs.3
+++ b/lib/libgssapi/gss_indicate_mechs.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INDICATE_MECHS 3 PRM
+.Os
.Sh NAME
.Nm gss_indicate_mechs
.Nd Determine available underlying authentication mechanisms
diff --git a/lib/libgssapi/gss_init_sec_context.3 b/lib/libgssapi/gss_init_sec_context.3
index 787aff3..9d14859 100644
--- a/lib/libgssapi/gss_init_sec_context.3
+++ b/lib/libgssapi/gss_init_sec_context.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INIT_SEC_CONTEXT 3 PRM
+.Os
.Sh NAME
.Nm gss_init_sec_context
.Nd Initiate a security context with a peer application
@@ -153,7 +153,7 @@ The values of the
.Dv GSS_C_MUTUAL_FLAG ,
.Dv GSS_C_REPLAY_FLAG ,
.Dv GSS_C_SEQUENCE_FLAG ,
-.Fv GSS_C_CONF_FLAG ,
+.Dv GSS_C_CONF_FLAG ,
.Dv GSS_C_INTEG_FLAG and
.Dv GSS_C_ANON_FLAG bits returned via the
.Fa ret_flags
diff --git a/lib/libgssapi/gss_inquire_context.3 b/lib/libgssapi/gss_inquire_context.3
index 51fa18d..ba5d649 100644
--- a/lib/libgssapi/gss_inquire_context.3
+++ b/lib/libgssapi/gss_inquire_context.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INQUIRE_CONTEXT 3 PRM
+.Os
.Sh NAME
.Nm gss_inquire_context
.Nd Obtain information about a security context
diff --git a/lib/libgssapi/gss_inquire_cred.3 b/lib/libgssapi/gss_inquire_cred.3
index 99c20ce..923b373 100644
--- a/lib/libgssapi/gss_inquire_cred.3
+++ b/lib/libgssapi/gss_inquire_cred.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INQUIRE_CRED 3 PRM
+.Os
.Sh NAME
.Nm gss_inquire_cred
.Nd Obtain information about a credential
diff --git a/lib/libgssapi/gss_inquire_cred_by_mech.3 b/lib/libgssapi/gss_inquire_cred_by_mech.3
index 22319bd..c316930 100644
--- a/lib/libgssapi/gss_inquire_cred_by_mech.3
+++ b/lib/libgssapi/gss_inquire_cred_by_mech.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INQUIRE_CRED_BY_MECH 3 PRM
+.Os
.Sh NAME
.Nm gss_inquire_cred_by_mech
.Nd Obtain per-mechanism information about a credential
diff --git a/lib/libgssapi/gss_inquire_mechs_for_name.3 b/lib/libgssapi/gss_inquire_mechs_for_name.3
index b56e663..d8d94ed 100644
--- a/lib/libgssapi/gss_inquire_mechs_for_name.3
+++ b/lib/libgssapi/gss_inquire_mechs_for_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INQUIRE_MECHS_FOR_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_inquire_mechs_for_name
.Nd List mechanisms that support the specified name-type
diff --git a/lib/libgssapi/gss_inquire_names_for_mech.3 b/lib/libgssapi/gss_inquire_names_for_mech.3
index 8b7f069..c1b7528 100644
--- a/lib/libgssapi/gss_inquire_names_for_mech.3
+++ b/lib/libgssapi/gss_inquire_names_for_mech.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_INQUIRE_NAMES_FOR_MECH 3 PRM
+.Os
.Sh NAME
.Nm gss_inquire_names_for_mech
.Nd List the name-types supported by the specified mechanism
diff --git a/lib/libgssapi/gss_process_context_token.3 b/lib/libgssapi/gss_process_context_token.3
index 85e1029..53f5ebf 100644
--- a/lib/libgssapi/gss_process_context_token.3
+++ b/lib/libgssapi/gss_process_context_token.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_PROCESS_CONTEXT_TOKEN 3 PRM
+.Os
.Sh NAME
.Nm gss_process_context_token
.Nd Process a token on a security context from a peer application
diff --git a/lib/libgssapi/gss_release_buffer.3 b/lib/libgssapi/gss_release_buffer.3
index 432d422..259db3b 100644
--- a/lib/libgssapi/gss_release_buffer.3
+++ b/lib/libgssapi/gss_release_buffer.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_RELEASE_BUFFER 3 PRM
+.Os
.Sh NAME
.Nm gss_release_buffer
.Nd Discard a buffer
diff --git a/lib/libgssapi/gss_release_cred.3 b/lib/libgssapi/gss_release_cred.3
index ca99fc4..38fc784 100644
--- a/lib/libgssapi/gss_release_cred.3
+++ b/lib/libgssapi/gss_release_cred.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_RELEASE_CRED 3 PRM
+.Os
.Sh NAME
.Nm gss_release_cred
.Nd Discard a credential handle
diff --git a/lib/libgssapi/gss_release_name.3 b/lib/libgssapi/gss_release_name.3
index 7bf1181..ca737e0 100644
--- a/lib/libgssapi/gss_release_name.3
+++ b/lib/libgssapi/gss_release_name.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_RELEASE_NAME 3 PRM
+.Os
.Sh NAME
.Nm gss_release_name
.Nd Discard an internal-form name
diff --git a/lib/libgssapi/gss_release_oid_set.3 b/lib/libgssapi/gss_release_oid_set.3
index 0142e2f..391ad28 100644
--- a/lib/libgssapi/gss_release_oid_set.3
+++ b/lib/libgssapi/gss_release_oid_set.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_RELEASE_OID_SET 3 PRM
+.Os
.Sh NAME
.Nm gss_release_oid_set
.Nd Discard a set of object identifiers
diff --git a/lib/libgssapi/gss_test_oid_set_member.3 b/lib/libgssapi/gss_test_oid_set_member.3
index 86e06b3..c6dad0f 100644
--- a/lib/libgssapi/gss_test_oid_set_member.3
+++ b/lib/libgssapi/gss_test_oid_set_member.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_TEST_OID_SET_MEMBER 3 PRM
+.Os
.Sh NAME
.Nm gss_test_oid_set_member
.Nd Determines whether an object identifier is a member of a set
diff --git a/lib/libgssapi/gss_unwrap.3 b/lib/libgssapi/gss_unwrap.3
index 4cf3c6d..94537a4 100644
--- a/lib/libgssapi/gss_unwrap.3
+++ b/lib/libgssapi/gss_unwrap.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_UNWRAP 3 PRM
+.Os
.Sh NAME
.Nm gss_unwrap ,
.Nm gss_unseal
@@ -155,6 +155,7 @@ The context_handle parameter did not identify a valid context.
Generic Security Service Application Program Interface Version 2, Update 1
.It RFC 2744
Generic Security Service API Version 2 : C-bindings
+.El
.Sh HISTORY
The
.Nm
diff --git a/lib/libgssapi/gss_verify_mic.3 b/lib/libgssapi/gss_verify_mic.3
index b72f468..e8a4611 100644
--- a/lib/libgssapi/gss_verify_mic.3
+++ b/lib/libgssapi/gss_verify_mic.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_VERIFY_MIC 3 PRM
+.Os
.Sh NAME
.Nm gss_verify_mic ,
.Nm gss_verify
diff --git a/lib/libgssapi/gss_wrap.3 b/lib/libgssapi/gss_wrap.3
index c432b48..5732dd2 100644
--- a/lib/libgssapi/gss_wrap.3
+++ b/lib/libgssapi/gss_wrap.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_WRAP 3 PRM
+.Os
.Sh NAME
.Nm gss_wrap ,
.Nm gss_seal
diff --git a/lib/libgssapi/gss_wrap_size_limit.3 b/lib/libgssapi/gss_wrap_size_limit.3
index c1d40da..7a1cb59 100644
--- a/lib/libgssapi/gss_wrap_size_limit.3
+++ b/lib/libgssapi/gss_wrap_size_limit.3
@@ -28,8 +28,8 @@
.\"
.\" The following commands are required for all man pages.
.Dd January 26, 2010
-.Os
.Dt GSS_WRAP_SIZE_LIMIT 3 PRM
+.Os
.Sh NAME
.Nm gss_wrap_size_limit
.Nd Determine maximum message sizes
diff --git a/lib/libkvm/kvm.3 b/lib/libkvm/kvm.3
index f694fd8..9dcd772 100644
--- a/lib/libkvm/kvm.3
+++ b/lib/libkvm/kvm.3
@@ -32,7 +32,7 @@
.\" @(#)kvm.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd January 29, 2004
+.Dd April 25, 2010
.Dt KVM 3
.Os
.Sh NAME
@@ -46,12 +46,15 @@ The
library provides a uniform interface for accessing kernel virtual memory
images, including live systems and crash dumps.
Access to live systems is via
+.Xr sysctl 3
+for some functions, and
.Xr mem 4
and
.Xr kmem 4
+for other functions,
while crash dumps can be examined via the core file generated by
.Xr savecore 8 .
-The interface behaves identically in both cases.
+The interface behaves similarly in both cases.
Memory can be read and written, kernel symbol addresses can be
looked up efficiently, and information about user processes can
be gathered.
@@ -112,5 +115,6 @@ given descriptor.
.Xr kvm_openfiles 3 ,
.Xr kvm_read 3 ,
.Xr kvm_write 3 ,
+.Xr sysctl 3 ,
.Xr kmem 4 ,
.Xr mem 4
diff --git a/lib/libkvm/kvm_getpcpu.3 b/lib/libkvm/kvm_getpcpu.3
index f2deda9..92036ca 100644
--- a/lib/libkvm/kvm_getpcpu.3
+++ b/lib/libkvm/kvm_getpcpu.3
@@ -96,7 +96,7 @@ will return pointers to that data on the appropriate CPU.
.Sh CACHING
.Fn kvm_getmaxcpu
and
-.Vn kvm_getpcpu
+.Fn kvm_getpcpu
cache the nlist values for various kernel variables which are
reused in successive calls.
You may call either function with
diff --git a/lib/libmemstat/libmemstat.3 b/lib/libmemstat/libmemstat.3
index 82ec53a..9a4877b 100644
--- a/lib/libmemstat/libmemstat.3
+++ b/lib/libmemstat/libmemstat.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd June 27, 2005
-.Os
.Dt LIBMEMSTAT 3
+.Os
.Sh NAME
.Nm libmemstat
.Nd "library interface to retrieve kernel memory allocator statistics"
diff --git a/lib/libpam/Makefile.inc b/lib/libpam/Makefile.inc
index 1fe2f12..1c1e513 100644
--- a/lib/libpam/Makefile.inc
+++ b/lib/libpam/Makefile.inc
@@ -30,3 +30,5 @@ DEBUG_FLAGS+= -DDEBUG
SHLIB_MAJOR= 5
PAM_MOD_DIR= ${LIBDIR}
+
+.include "../Makefile.inc"
diff --git a/lib/libpam/modules/Makefile.inc b/lib/libpam/modules/Makefile.inc
index c352f42..feb5da0 100644
--- a/lib/libpam/modules/Makefile.inc
+++ b/lib/libpam/modules/Makefile.inc
@@ -6,7 +6,6 @@ NO_INSTALLLIB=
NO_PROFILE=
CFLAGS+= -I${PAMDIR}/include -I${.CURDIR}/../../libpam
-WARNS?= 6
# This is nasty.
# For the static case, libpam.a depends on the modules.
diff --git a/lib/libpam/modules/pam_krb5/Makefile b/lib/libpam/modules/pam_krb5/Makefile
index 500801b..85f3421 100644
--- a/lib/libpam/modules/pam_krb5/Makefile
+++ b/lib/libpam/modules/pam_krb5/Makefile
@@ -29,7 +29,7 @@ SRCS= pam_krb5.c
MAN= pam_krb5.8
.if defined(_FREEFALL_CONFIG)
CFLAGS+=-D_FREEFALL_CONFIG
-WARNS= 3
+WARNS?= 3
.endif
DPADD= ${LIBKRB5} ${LIBHX509} ${LIBASN1} ${LIBROKEN} ${LIBCOM_ERR} ${LIBCRYPT} ${LIBCRYPTO}
diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c
index 25c63ca..9d89045 100644
--- a/lib/libpam/modules/pam_ssh/pam_ssh.c
+++ b/lib/libpam/modules/pam_ssh/pam_ssh.c
@@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
#include "authfd.h"
#include "authfile.h"
+#define ssh_add_identity(auth, key, comment) \
+ ssh_add_identity_constrained(auth, key, comment, 0, 0)
+
extern char **environ;
struct pam_ssh_key {
diff --git a/lib/libpkg/Makefile b/lib/libpkg/Makefile
new file mode 100644
index 0000000..8f2b325
--- /dev/null
+++ b/lib/libpkg/Makefile
@@ -0,0 +1,47 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+LIB= pkg
+
+SHLIBDIR?= /usr/lib
+SHLIB_MAJOR= 0
+
+SRCS= deps.c \
+ exec.c \
+ file.c \
+ global.c \
+ match.c \
+ msg.c \
+ pen.c \
+ pkgwrap.c \
+ plist.c \
+ str.c \
+ url.c \
+ version.c
+INCS= pkg.h
+
+CFLAGS+= -DYES_I_KNOW_THE_API_IS_RUBBISH_AND_IS_DOOMED_TO_CHANGE
+
+DPADD= ${LIBFETCH} ${LIBMD} ${LIBUTIL}
+LDADD= -lfetch -lmd -lutil
+
+.if ${MK_OPENSSL} != "no"
+DPADD+= ${LIBSSL} ${LIBCRYPTO}
+LDADD+= -lssl -lcrypto
+.endif
+
+WARNS?= 3
+
+DATE!= grep LIBPKG_VERSION ${.CURDIR}/pkg.h | sed 's|.*[ ]||'
+
+distfile: clean
+ @(cd ${.CURDIR}/..; \
+ cp -r libpkg libpkg-${DATE}; \
+ tar -czf libpkg/libpkg-${DATE}.tar.gz \
+ --exclude .#* --exclude *~ --exclude CVS \
+ --exclude .svn --exclude libpkg-*.tar.gz \
+ libpkg-${DATE}; \
+ rm -rf libpkg-${DATE})
+
+.include <bsd.lib.mk>
diff --git a/usr.sbin/pkg_install/lib/deps.c b/lib/libpkg/deps.c
index 66f44a9..101d046 100644
--- a/usr.sbin/pkg_install/lib/deps.c
+++ b/lib/libpkg/deps.c
@@ -22,7 +22,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <stdio.h>
diff --git a/usr.sbin/pkg_install/lib/exec.c b/lib/libpkg/exec.c
index fc8220c..04891d3 100644
--- a/usr.sbin/pkg_install/lib/exec.c
+++ b/lib/libpkg/exec.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
/*
diff --git a/usr.sbin/pkg_install/lib/file.c b/lib/libpkg/file.c
index 0b74ddf..7c95f99 100644
--- a/usr.sbin/pkg_install/lib/file.c
+++ b/lib/libpkg/file.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <pwd.h>
#include <time.h>
@@ -31,10 +31,13 @@ __FBSDID("$FreeBSD$");
Boolean
fexists(const char *fname)
{
- struct stat dummy;
- if (!lstat(fname, &dummy))
- return TRUE;
- return FALSE;
+ int fd;
+
+ if ((fd = open(fname, O_RDONLY)) == -1)
+ return FALSE;
+
+ close(fd);
+ return TRUE;
}
/* Quick check to see if something is a directory or symlink to a directory */
@@ -279,17 +282,23 @@ copy_file(const char *dir, const char *fname, const char *to)
}
void
-move_file(const char *dir, const char *fname, const char *to)
+move_file(const char *dir, const char *fname, const char *tdir)
{
- char cmd[FILENAME_MAX];
+ char from[FILENAME_MAX];
+ char to[FILENAME_MAX];
if (fname[0] == '/')
- snprintf(cmd, FILENAME_MAX, "/bin/mv %s %s", fname, to);
+ strncpy(from, fname, FILENAME_MAX);
else
- snprintf(cmd, FILENAME_MAX, "/bin/mv %s/%s %s", dir, fname, to);
- if (vsystem(cmd)) {
- cleanup(0);
- errx(2, "%s: could not perform '%s'", __func__, cmd);
+ snprintf(from, FILENAME_MAX, "%s/%s", dir, fname);
+
+ snprintf(to, FILENAME_MAX, "%s/%s", tdir, fname);
+
+ if (rename(from, to) == -1) {
+ if (vsystem("/bin/mv %s %s", from, to)) {
+ cleanup(0);
+ errx(2, "%s: could not move '%s' to '%s'", __func__, from, to);
+ }
}
}
diff --git a/usr.sbin/pkg_install/lib/global.c b/lib/libpkg/global.c
index e136ec8..8103126 100644
--- a/usr.sbin/pkg_install/lib/global.c
+++ b/lib/libpkg/global.c
@@ -22,7 +22,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
/* These are global for all utils */
Boolean Quiet = FALSE;
diff --git a/usr.sbin/pkg_install/lib/match.c b/lib/libpkg/match.c
index 1f8b02a..ba65442 100644
--- a/usr.sbin/pkg_install/lib/match.c
+++ b/lib/libpkg/match.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <fnmatch.h>
#include <fts.h>
@@ -267,7 +267,7 @@ matchallbyorigin(const char **origins, int *retval)
*/
if (isemptydir(tmp))
continue;
- snprintf(tmp, PATH_MAX, "%s/%s", tmp, CONTENTS_FNAME);
+ strncat(tmp, "/" CONTENTS_FNAME, PATH_MAX);
fp = fopen(tmp, "r");
if (fp == NULL) {
warnx("the package info for package '%s' is corrupt", installed[i]);
@@ -292,7 +292,7 @@ matchallbyorigin(const char **origins, int *retval)
break;
}
}
- if (cmd != PLIST_ORIGIN && ( Verbose || 0 != strncmp("bsdpan-", installed[i], 7 ) ) )
+ if (cmd != PLIST_ORIGIN && 0 != strncmp("bsdpan-", installed[i], 7))
warnx("package %s has no origin recorded", installed[i]);
fclose(fp);
}
diff --git a/usr.sbin/pkg_install/lib/msg.c b/lib/libpkg/msg.c
index 5b17624..0d25ad1 100644
--- a/usr.sbin/pkg_install/lib/msg.c
+++ b/lib/libpkg/msg.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <paths.h>
@@ -61,12 +61,7 @@ y_or_n(Boolean def, const char *msg, ...)
else
fprintf(stderr, " [no]? ");
fflush(stderr);
- if (AutoAnswer) {
- ch = (AutoAnswer == YES) ? 'Y' : 'N';
- fprintf(stderr, "%c\n", ch);
- }
- else
- ch = toupper(fgetc(tty));
+ ch = toupper(fgetc(tty));
if (ch == '\n')
ch = (def) ? 'Y' : 'N';
}
diff --git a/usr.sbin/pkg_install/lib/pen.c b/lib/libpkg/pen.c
index 2f7e917..6e30445 100644
--- a/usr.sbin/pkg_install/lib/pen.c
+++ b/lib/libpkg/pen.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <libutil.h>
#include <libgen.h>
@@ -103,7 +103,7 @@ popPen(char *pen)
const char *
make_playpen(char *pen, off_t sz)
{
- char humbuf1[6], humbuf2[6];
+ char humbuf[6];
char cwd[FILENAME_MAX];
if (!find_play_pen(pen, sz))
@@ -113,27 +113,16 @@ make_playpen(char *pen, off_t sz)
cleanup(0);
errx(2, "%s: can't mktemp '%s'", __func__, pen);
}
- if (chmod(pen, 0700) == FAIL) {
- cleanup(0);
- errx(2, "%s: can't mkdir '%s'", __func__, pen);
- }
- if (Verbose) {
- if (sz) {
- humanize_number(humbuf1, sizeof humbuf1, sz, "", HN_AUTOSCALE,
- HN_NOSPACE);
- humanize_number(humbuf2, sizeof humbuf2, min_free(pen),
- "", HN_AUTOSCALE, HN_NOSPACE);
- fprintf(stderr, "Requested space: %s bytes, free space: %s bytes in %s\n", humbuf1, humbuf2, pen);
- }
- }
+ humanize_number(humbuf, sizeof humbuf, sz, "", HN_AUTOSCALE, HN_NOSPACE);
if (min_free(pen) < sz) {
rmdir(pen);
cleanup(0);
errx(2, "%s: not enough free space to create '%s'.\n"
"Please set your PKG_TMPDIR environment variable to a location\n"
- "with more space and\ntry the command again", __func__, pen);
+ "with at least %s and try the command again",
+ __func__, humbuf, pen);
}
if (!getcwd(cwd, FILENAME_MAX)) {
diff --git a/usr.sbin/pkg_install/lib/lib.h b/lib/libpkg/pkg.h
index 4a6c625..12e3562 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/lib/libpkg/pkg.h
@@ -23,11 +23,16 @@
#ifndef _INST_LIB_LIB_H_
#define _INST_LIB_LIB_H_
+#ifndef YES_I_KNOW_THE_API_IS_RUBBISH_AND_IS_DOOMED_TO_CHANGE
+#error "You obviously have no idea what you're doing."
+#endif
+
/* Includes */
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/queue.h>
+#include <sys/utsname.h>
#include <ctype.h>
#include <dirent.h>
#include <stdarg.h>
@@ -51,6 +56,11 @@
#define YES 2
#define NO 1
+/* Some more stat macros. */
+#define S_IRALL 0000444
+#define S_IWALL 0000222
+#define S_IXALL 0000111
+
/* Usually "rm", but often "echo" during debugging! */
#define REMOVE_CMD "/bin/rm"
@@ -84,31 +94,18 @@
#define DISPLAY_FNAME "+DISPLAY"
#define MTREE_FNAME "+MTREE_DIRS"
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000
-#define INDEX_FNAME "INDEX-9"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 800000
-#define INDEX_FNAME "INDEX-8"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 700000
-#define INDEX_FNAME "INDEX-7"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 600000
-#define INDEX_FNAME "INDEX-6"
-#else
-#define INDEX_FNAME "INDEX"
-#endif
-
#define CMD_CHAR '@' /* prefix for extended PLIST cmd */
/* The name of the "prefix" environment variable given to scripts */
#define PKG_PREFIX_VNAME "PKG_PREFIX"
/*
- * Version of the package tools - increase whenever you make a change
+ * Version of the package library - increase whenever you make a change
* in the code that is not cosmetic only.
*/
-#define PKG_INSTALL_VERSION 20100122
+#define LIBPKG_VERSION 20100423
#define PKG_WRAPCONF_FNAME "/var/db/pkg_install.conf"
-#define main(argc, argv) real_main(argc, argv)
/* Version numbers to assist with changes in package file format */
#define PLIST_FMT_VER_MAJOR 1
@@ -220,7 +217,7 @@ Boolean make_preserve_name(char *, int, const char *, const char *);
/* For all */
int pkg_perform(char **);
-int real_main(int, char **);
+void pkg_wrap(long, char **);
/* Query installed packages */
char **matchinstalled(match_t, char **, int *);
@@ -235,6 +232,7 @@ int chkifdepends(const char *, const char *);
int requiredby(const char *, struct reqr_by_head **, Boolean, Boolean);
/* Version */
+int libpkg_version(void);
int verscmp(Package *, int, int);
int version_cmp(const char *, const char *);
diff --git a/lib/libpkg/pkgwrap.c b/lib/libpkg/pkgwrap.c
new file mode 100644
index 0000000..9c8c0c3
--- /dev/null
+++ b/lib/libpkg/pkgwrap.c
@@ -0,0 +1,90 @@
+/*
+ * FreeBSD install - a package for the installation and maintenance
+ * of non-core utilities.
+ *
+ * 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.
+ *
+ * Maxim Sobolev
+ * 8 September 2002
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "pkg.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern char **environ;
+
+void
+pkg_wrap(long curver, char **argv)
+{
+ FILE* f;
+ char ver[9]; /* Format is: 'YYYYMMDD\0' */
+ char buffer[FILENAME_MAX+10]; /* Format is: 'YYYYMMDD <path>' */
+ char cmd[FILENAME_MAX+5]; /* Format is: '<path> -PPq' */
+ char *path, *cp;
+ long ptver, lpver;
+
+ if (getenv("PKG_NOWRAP") != NULL)
+ goto nowrap;
+
+ setenv("PKG_NOWRAP", "1", 1);
+
+ /* Get alternative location for package tools. */
+ if ((f = fopen(PKG_WRAPCONF_FNAME, "r")) == NULL) {
+ goto nowrap;
+ } else {
+ if (get_string(buffer, FILENAME_MAX+9, f) == NULL) {
+ goto nowrap;
+ } else {
+ if ((path = strrchr(buffer, ' ')) == NULL) {
+ goto nowrap;
+ } else {
+ *path++ = '\0';
+ }
+ }
+ }
+
+ if ((cp = strrchr(argv[0], '/')) == NULL) {
+ cp = argv[0];
+ } else {
+ cp++;
+ }
+
+ /* Get version of the other pkg_install and libpkg */
+ snprintf(cmd, FILENAME_MAX+10, "%s/%s -PPq", path, cp);
+ if ((f = popen(cmd, "r")) == NULL) {
+ perror("popen()");
+ goto nowrap;
+ } else {
+ if (get_string(ver, 9, f) == NULL)
+ goto nowrap;
+ else
+ ptver = strtol(ver, NULL, 10);
+ if (get_string(ver, 9, f) == NULL)
+ goto nowrap;
+ else
+ lpver = strtol(ver, NULL, 10);
+ pclose(f);
+ }
+
+ if ((lpver >= LIBPKG_VERSION) && (ptver > curver)) {
+ snprintf(cmd, FILENAME_MAX, "%s/%s", path, cp);
+ execve(cmd, argv, environ);
+ }
+
+nowrap:
+ unsetenv("PKG_NOWRAP");
+}
diff --git a/usr.sbin/pkg_install/lib/plist.c b/lib/libpkg/plist.c
index 3c87d62..b14ac20 100644
--- a/usr.sbin/pkg_install/lib/plist.c
+++ b/lib/libpkg/plist.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <md5.h>
@@ -551,7 +551,7 @@ delete_hierarchy(const char *dir, Boolean ign_err, Boolean nukedirs)
char *cp1, *cp2;
cp1 = cp2 = strdup(dir);
- if (!fexists(dir)) {
+ if (!fexists(dir) && !issymlink(dir)) {
if (!ign_err)
warnx("%s '%s' doesn't exist",
isdir(dir) ? "directory" : "file", dir);
diff --git a/usr.sbin/pkg_install/lib/str.c b/lib/libpkg/str.c
index 0d9e288..c26e6cc 100644
--- a/usr.sbin/pkg_install/lib/str.c
+++ b/lib/libpkg/str.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
char *
strconcat(const char *s1, const char *s2)
diff --git a/usr.sbin/pkg_install/lib/url.c b/lib/libpkg/url.c
index b598c60..4c10849 100644
--- a/usr.sbin/pkg_install/lib/url.c
+++ b/lib/libpkg/url.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
#include <fetch.h>
#include <libgen.h>
@@ -108,6 +108,10 @@ fileGetURL(const char *base, const char *spec, int keep_package)
if ((ftp = fetchGetURL(fname, Verbose ? "v" : NULL)) == NULL) {
printf("Error: Unable to get %s: %s\n",
fname, fetchLastErrString);
+ /* If the fetch fails, yank the package. */
+ if (keep_package && unlink(pkg) < 0) {
+ warnx("failed to remove partially fetched package: %s", pkg);
+ }
return NULL;
}
diff --git a/usr.sbin/pkg_install/lib/version.c b/lib/libpkg/version.c
index d9c4fe7..1b7bb5b 100644
--- a/usr.sbin/pkg_install/lib/version.c
+++ b/lib/libpkg/version.c
@@ -19,10 +19,20 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include "pkg.h"
#include <err.h>
/*
+ * This routine could easily go somewhere else.
+ *
+ */
+int
+libpkg_version(void)
+{
+ return LIBPKG_VERSION;
+}
+
+/*
* Routines to assist with PLIST_FMT_VER numbers in the packing
* lists.
*
diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile
index 09a23e3..fd35fd5 100644
--- a/lib/libpmc/Makefile
+++ b/lib/libpmc/Makefile
@@ -27,11 +27,16 @@ MAN+= pmc.atom.3
MAN+= pmc.core.3
MAN+= pmc.core2.3
MAN+= pmc.iaf.3
+MAN+= pmc.ucf.3
MAN+= pmc.k7.3
MAN+= pmc.k8.3
MAN+= pmc.p4.3
MAN+= pmc.p5.3
MAN+= pmc.p6.3
+MAN+= pmc.corei7.3
+MAN+= pmc.corei7uc.3
+MAN+= pmc.westmere.3
+MAN+= pmc.westmereuc.3
MAN+= pmc.tsc.3
.elif ${MACHINE_ARCH} == "arm" && ${CPUTYPE} == "xscale"
MAN+= pmc.xscale.3
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 5526599..c440aa8 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -54,6 +54,10 @@ static int iaf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
static int iap_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
+static int ucf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
+static int ucp_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
static int k8_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
static int p4_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
@@ -74,6 +78,12 @@ static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif
+#if defined(__mips__)
+static int mips24k_allocate_pmc(enum pmc_event _pe, char* ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
+#endif /* __mips__ */
+
+
#define PMC_CALL(cmd, params) \
syscall(pmc_syscall, PMC_OP_##cmd, (params))
@@ -137,6 +147,8 @@ PMC_CLASSDEP_TABLE(p4, P4);
PMC_CLASSDEP_TABLE(p5, P5);
PMC_CLASSDEP_TABLE(p6, P6);
PMC_CLASSDEP_TABLE(xscale, XSCALE);
+PMC_CLASSDEP_TABLE(mips24k, MIPS24K);
+PMC_CLASSDEP_TABLE(ucf, UCF);
#undef __PMC_EV_ALIAS
#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },
@@ -162,6 +174,21 @@ static const struct pmc_event_descr corei7_event_table[] =
__PMC_EV_ALIAS_COREI7()
};
+static const struct pmc_event_descr westmere_event_table[] =
+{
+ __PMC_EV_ALIAS_WESTMERE()
+};
+
+static const struct pmc_event_descr corei7uc_event_table[] =
+{
+ __PMC_EV_ALIAS_COREI7UC()
+};
+
+static const struct pmc_event_descr westmereuc_event_table[] =
+{
+ __PMC_EV_ALIAS_WESTMEREUC()
+};
+
/*
* PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...)
*
@@ -175,13 +202,15 @@ static const struct pmc_event_descr corei7_event_table[] =
PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC);
PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC);
PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC);
PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC);
PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE);
+PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K);
static const struct pmc_event_descr tsc_event_table[] =
{
@@ -207,6 +236,10 @@ PMC_CLASS_TABLE_DESC(atom, IAP, atom, iap);
PMC_CLASS_TABLE_DESC(core, IAP, core, iap);
PMC_CLASS_TABLE_DESC(core2, IAP, core2, iap);
PMC_CLASS_TABLE_DESC(corei7, IAP, corei7, iap);
+PMC_CLASS_TABLE_DESC(westmere, IAP, westmere, iap);
+PMC_CLASS_TABLE_DESC(ucf, UCF, ucf, ucf);
+PMC_CLASS_TABLE_DESC(corei7uc, UCP, corei7uc, ucp);
+PMC_CLASS_TABLE_DESC(westmereuc, UCP, westmereuc, ucp);
#endif
#if defined(__i386__)
PMC_CLASS_TABLE_DESC(k7, K7, k7, k7);
@@ -226,6 +259,10 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
#endif
+#if defined(__mips__)
+PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips24k);
+#endif /* __mips__ */
+
#undef PMC_CLASS_TABLE_DESC
static const struct pmc_class_descr **pmc_class_table;
@@ -290,7 +327,7 @@ struct pmc_masks {
const uint32_t pm_value;
};
#define PMCMASK(N,V) { .pm_name = #N, .pm_value = (V) }
-#define NULLMASK PMCMASK(NULL,0)
+#define NULLMASK { .pm_name = NULL }
#if defined(__amd64__) || defined(__i386__)
static int
@@ -483,6 +520,8 @@ static struct pmc_event_alias core2_aliases_without_iaf[] = {
#define atom_aliases_without_iaf core2_aliases_without_iaf
#define corei7_aliases core2_aliases
#define corei7_aliases_without_iaf core2_aliases_without_iaf
+#define westmere_aliases core2_aliases
+#define westmere_aliases_without_iaf core2_aliases_without_iaf
#define IAF_KW_OS "os"
#define IAF_KW_USR "usr"
@@ -533,6 +572,7 @@ iaf_allocate_pmc(enum pmc_event pe, char *ctrspec,
#define IAP_KW_SNOOPTYPE "snooptype"
#define IAP_KW_TRANSITION "trans"
#define IAP_KW_USR "usr"
+#define IAP_KW_RSP "rsp"
static struct pmc_masks iap_core_mask[] = {
PMCMASK(all, (0x3 << 14)),
@@ -580,19 +620,38 @@ static struct pmc_masks iap_transition_mask[] = {
NULLMASK
};
+static struct pmc_masks iap_rsp_mask[] = {
+ PMCMASK(DMND_DATA_RD, (1 << 0)),
+ PMCMASK(DMND_RFO, (1 << 1)),
+ PMCMASK(DMND_IFETCH, (1 << 2)),
+ PMCMASK(WB, (1 << 3)),
+ PMCMASK(PF_DATA_RD, (1 << 4)),
+ PMCMASK(PF_RFO, (1 << 5)),
+ PMCMASK(PF_IFETCH, (1 << 6)),
+ PMCMASK(OTHER, (1 << 7)),
+ PMCMASK(UNCORE_HIT, (1 << 8)),
+ PMCMASK(OTHER_CORE_HIT_SNP, (1 << 9)),
+ PMCMASK(OTHER_CORE_HITM, (1 << 10)),
+ PMCMASK(REMOTE_CACHE_FWD, (1 << 12)),
+ PMCMASK(REMOTE_DRAM, (1 << 13)),
+ PMCMASK(LOCAL_DRAM, (1 << 14)),
+ PMCMASK(NON_DRAM, (1 << 15)),
+ NULLMASK
+};
+
static int
iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
struct pmc_op_pmcallocate *pmc_config)
{
char *e, *p, *q;
- uint32_t cachestate, evmask;
+ uint32_t cachestate, evmask, rsp;
int count, n;
pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
PMC_CAP_QUALIFIER);
pmc_config->pm_md.pm_iap.pm_iap_config = 0;
- cachestate = evmask = 0;
+ cachestate = evmask = rsp = 0;
/* Parse additional modifiers if present */
while ((p = strsep(&ctrspec, ",")) != NULL) {
@@ -639,8 +698,7 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
return (-1);
} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM ||
cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2 ||
- cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME ||
- cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7) {
+ cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME) {
if (KWPREFIXMATCH(p, IAP_KW_SNOOPRESPONSE "=")) {
n = pmc_parse_mask(iap_snoopresponse_mask, p,
&evmask);
@@ -649,6 +707,12 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
&evmask);
} else
return (-1);
+ } else if (cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7 ||
+ cpu_info.pm_cputype == PMC_CPU_INTEL_WESTMERE) {
+ if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) {
+ n = pmc_parse_mask(iap_rsp_mask, p, &rsp);
+ } else
+ return (-1);
} else
return (-1);
@@ -681,6 +745,69 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
}
pmc_config->pm_md.pm_iap.pm_iap_config |= cachestate;
+ pmc_config->pm_md.pm_iap.pm_iap_rsp = rsp;
+
+ return (0);
+}
+
+/*
+ * Intel Uncore.
+ */
+
+static int
+ucf_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ (void) pe;
+ (void) ctrspec;
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+ pmc_config->pm_md.pm_ucf.pm_ucf_flags = 0;
+
+ return (0);
+}
+
+#define UCP_KW_CMASK "cmask"
+#define UCP_KW_EDGE "edge"
+#define UCP_KW_INV "inv"
+
+static int
+ucp_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ char *e, *p, *q;
+ int count, n;
+
+ (void) pe;
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
+ PMC_CAP_QUALIFIER);
+ pmc_config->pm_md.pm_ucp.pm_ucp_config = 0;
+
+ /* Parse additional modifiers if present */
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+
+ n = 0;
+ if (KWPREFIXMATCH(p, UCP_KW_CMASK "=")) {
+ q = strchr(p, '=');
+ if (*++q == '\0') /* skip '=' */
+ return (-1);
+ count = strtol(q, &e, 0);
+ if (e == q || *e != '\0')
+ return (-1);
+ pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
+ pmc_config->pm_md.pm_ucp.pm_ucp_config |=
+ UCP_CMASK(count);
+ } else if (KWMATCH(p, UCP_KW_EDGE)) {
+ pmc_config->pm_caps |= PMC_CAP_EDGE;
+ } else if (KWMATCH(p, UCP_KW_INV)) {
+ pmc_config->pm_caps |= PMC_CAP_INVERT;
+ } else
+ return (-1);
+
+ if (n < 0) /* Parsing failed. */
+ return (-1);
+ }
return (0);
}
@@ -2040,6 +2167,45 @@ xscale_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
}
#endif
+#if defined(__mips__)
+
+static struct pmc_event_alias mips24k_aliases[] = {
+ EV_ALIAS("instructions", "INSTR_EXECUTED"),
+ EV_ALIAS("branches", "BRANCH_COMPLETED"),
+ EV_ALIAS("branch-mispredicts", "BRANCH_MISPRED"),
+ EV_ALIAS(NULL, NULL)
+};
+
+#define MIPS24K_KW_OS "os"
+#define MIPS24K_KW_USR "usr"
+#define MIPS24K_KW_ANYTHREAD "anythread"
+
+static int
+mips24k_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
+ struct pmc_op_pmcallocate *pmc_config __unused)
+{
+ char *p;
+
+ (void) pe;
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+ if (KWMATCH(p, MIPS24K_KW_OS))
+ pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+ else if (KWMATCH(p, MIPS24K_KW_USR))
+ pmc_config->pm_caps |= PMC_CAP_USER;
+ else if (KWMATCH(p, MIPS24K_KW_ANYTHREAD))
+ pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM);
+ else
+ return (-1);
+ }
+
+ return (0);
+}
+#endif /* __mips__ */
+
+
/*
* Match an event name `name' with its canonical form.
*
@@ -2341,6 +2507,31 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = corei7_event_table;
count = PMC_EVENT_TABLE_SIZE(corei7);
break;
+ case PMC_CPU_INTEL_WESTMERE:
+ ev = westmere_event_table;
+ count = PMC_EVENT_TABLE_SIZE(westmere);
+ break;
+ }
+ break;
+ case PMC_CLASS_UCF:
+ ev = ucf_event_table;
+ count = PMC_EVENT_TABLE_SIZE(ucf);
+ break;
+ case PMC_CLASS_UCP:
+ /*
+ * Return the most appropriate set of event name
+ * spellings for the current CPU.
+ */
+ switch (cpu_info.pm_cputype) {
+ default:
+ case PMC_CPU_INTEL_COREI7:
+ ev = corei7uc_event_table;
+ count = PMC_EVENT_TABLE_SIZE(corei7uc);
+ break;
+ case PMC_CPU_INTEL_WESTMERE:
+ ev = westmereuc_event_table;
+ count = PMC_EVENT_TABLE_SIZE(westmereuc);
+ break;
}
break;
case PMC_CLASS_TSC:
@@ -2371,6 +2562,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = xscale_event_table;
count = PMC_EVENT_TABLE_SIZE(xscale);
break;
+ case PMC_CLASS_MIPS24K:
+ ev = mips24k_event_table;
+ count = PMC_EVENT_TABLE_SIZE(mips24k);
+ break;
default:
errno = EINVAL;
return (-1);
@@ -2550,8 +2745,15 @@ pmc_init(void)
PMC_MDEP_INIT_INTEL_V2(core2);
break;
case PMC_CPU_INTEL_COREI7:
+ pmc_class_table[n++] = &ucf_class_table_descr;
+ pmc_class_table[n++] = &corei7uc_class_table_descr;
PMC_MDEP_INIT_INTEL_V2(corei7);
break;
+ case PMC_CPU_INTEL_WESTMERE:
+ pmc_class_table[n++] = &ucf_class_table_descr;
+ pmc_class_table[n++] = &westmereuc_class_table_descr;
+ PMC_MDEP_INIT_INTEL_V2(westmere);
+ break;
case PMC_CPU_INTEL_PIV:
PMC_MDEP_INIT(p4);
pmc_class_table[n] = &p4_class_table_descr;
@@ -2563,8 +2765,12 @@ pmc_init(void)
pmc_class_table[n] = &xscale_class_table_descr;
break;
#endif
-
-
+#if defined(__mips__)
+ case PMC_CPU_MIPS_24K:
+ PMC_MDEP_INIT(mips24k);
+ pmc_class_table[n] = &mips24k_class_table_descr;
+ break;
+#endif /* __mips__ */
default:
/*
* Some kind of CPU this version of the library knows nothing
@@ -2660,10 +2866,30 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
ev = corei7_event_table;
evfence = corei7_event_table + PMC_EVENT_TABLE_SIZE(corei7);
break;
+ case PMC_CPU_INTEL_WESTMERE:
+ ev = westmere_event_table;
+ evfence = westmere_event_table + PMC_EVENT_TABLE_SIZE(westmere);
+ break;
+ default: /* Unknown CPU type. */
+ break;
+ }
+ } else if (pe >= PMC_EV_UCF_FIRST && pe <= PMC_EV_UCF_LAST) {
+ ev = ucf_event_table;
+ evfence = ucf_event_table + PMC_EVENT_TABLE_SIZE(ucf);
+ } else if (pe >= PMC_EV_UCP_FIRST && pe <= PMC_EV_UCP_LAST) {
+ switch (cpu) {
+ case PMC_CPU_INTEL_COREI7:
+ ev = corei7uc_event_table;
+ evfence = corei7uc_event_table + PMC_EVENT_TABLE_SIZE(corei7uc);
+ break;
+ case PMC_CPU_INTEL_WESTMERE:
+ ev = westmereuc_event_table;
+ evfence = westmereuc_event_table + PMC_EVENT_TABLE_SIZE(westmereuc);
+ break;
default: /* Unknown CPU type. */
break;
}
- } if (pe >= PMC_EV_K7_FIRST && pe <= PMC_EV_K7_LAST) {
+ } else if (pe >= PMC_EV_K7_FIRST && pe <= PMC_EV_K7_LAST) {
ev = k7_event_table;
evfence = k7_event_table + PMC_EVENT_TABLE_SIZE(k7);
} else if (pe >= PMC_EV_K8_FIRST && pe <= PMC_EV_K8_LAST) {
@@ -2681,6 +2907,10 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
} else if (pe >= PMC_EV_XSCALE_FIRST && pe <= PMC_EV_XSCALE_LAST) {
ev = xscale_event_table;
evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale);
+ } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
+ ev = mips24k_event_table;
+ evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k
+);
} else if (pe == PMC_EV_TSC_TSC) {
ev = tsc_event_table;
evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3
index f48fe79..5e3236b 100644
--- a/lib/libpmc/pmc.3
+++ b/lib/libpmc/pmc.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 24, 2008
-.Os
.Dt PMC 3
+.Os
.Sh NAME
.Nm pmc
.Nd library for accessing hardware performance monitoring counters
diff --git a/lib/libpmc/pmc.atom.3 b/lib/libpmc/pmc.atom.3
index bd081f9..a54d1db 100644
--- a/lib/libpmc/pmc.atom.3
+++ b/lib/libpmc/pmc.atom.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 12, 2008
-.Os
.Dt PMC.ATOM 3
+.Os
.Sh NAME
.Nm pmc.atom
.Nd measurement events for
diff --git a/lib/libpmc/pmc.core.3 b/lib/libpmc/pmc.core.3
index 3c97e09..3feadae 100644
--- a/lib/libpmc/pmc.core.3
+++ b/lib/libpmc/pmc.core.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 12, 2008
-.Os
.Dt PMC.CORE 3
+.Os
.Sh NAME
.Nm pmc.core
.Nd measurement events for
diff --git a/lib/libpmc/pmc.core2.3 b/lib/libpmc/pmc.core2.3
index 41c1675..3dbc0c8 100644
--- a/lib/libpmc/pmc.core2.3
+++ b/lib/libpmc/pmc.core2.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd June 8, 2009
-.Os
.Dt PMC.CORE2 3
+.Os
.Sh NAME
.Nm pmc.core2
.Nd measurement events for
diff --git a/lib/libpmc/pmc.corei7.3 b/lib/libpmc/pmc.corei7.3
new file mode 100644
index 0000000..f90b0d3
--- /dev/null
+++ b/lib/libpmc/pmc.corei7.3
@@ -0,0 +1,1581 @@
+.\" Copyright (c) 2010 Fabien Thomas. 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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
+.Dt PMC.COREI7 3
+.Os
+.Sh NAME
+.Nm pmc.corei7
+.Nd measurement events for
+.Tn Intel
+.Tn Core i7 and Xeon 5500
+family CPUs
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+.Tn Intel
+.Tn "Core i7"
+CPUs contain PMCs conforming to version 2 of the
+.Tn Intel
+performance measurement architecture.
+These CPUs may contain up to three classes of PMCs:
+.Bl -tag -width "Li PMC_CLASS_IAP"
+.It Li PMC_CLASS_IAF
+Fixed-function counters that count only one hardware event per counter.
+.It Li PMC_CLASS_IAP
+Programmable counters that may be configured to count one of a defined
+set of hardware events.
+.El
+.Pp
+The number of PMCs available in each class and their widths need to be
+determined at run time by calling
+.Xr pmc_cpuinfo 3 .
+.Pp
+Intel Core i7 and Xeon 5500 PMCs are documented in
+.Rs
+.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
+.%T "Volume 3B: System Programming Guide, Part 2"
+.%N "Order Number: 253669-033US"
+.%D December 2009
+.%Q "Intel Corporation"
+.Re
+.Ss COREI7 AND XEON 5500 FIXED FUNCTION PMCS
+These PMCs and their supported events are documented in
+.Xr pmc.iaf 3 .
+Not all CPUs in this family implement fixed-function counters.
+.Ss COREI7 AND XEON 5500 PROGRAMMABLE PMCS
+The programmable PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta Yes
+.It PMC_CAP_INTERRUPT Ta Yes
+.It PMC_CAP_INVERT Ta Yes
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta Yes
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta Yes
+.It PMC_CAP_USER Ta Yes
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+Event specifiers for these PMCs support the following common
+qualifiers:
+.Bl -tag -width indent
+.It Li rsp= Ns Ar value
+Configure the Off-core Response bits.
+.Bl -tag -width indent
+.It Li DMND_DATA_RD
+Counts the number of demand and DCU prefetch data reads of full
+and partial cachelines as well as demand data page table entry
+cacheline reads. Does not count L2 data read prefetches or
+instruction fetches.
+.It Li DMND_RFO
+Counts the number of demand and DCU prefetch reads for ownership
+(RFO) requests generated by a write to data cacheline. Does not
+count L2 RFO.
+.It Li DMND_IFETCH
+Counts the number of demand and DCU prefetch instruction cacheline
+reads. Does not count L2 code read prefetches.
+WB
+Counts the number of writeback (modified to exclusive) transactions.
+.It Li PF_DATA_RD
+Counts the number of data cacheline reads generated by L2 prefetchers.
+.It Li PF_RFO
+Counts the number of RFO requests generated by L2 prefetchers.
+.It Li PF_IFETCH
+Counts the number of code reads generated by L2 prefetchers.
+.It Li OTHER
+Counts one of the following transaction types, including L3 invalidate,
+I/O, full or partial writes, WC or non-temporal stores, CLFLUSH, Fences,
+lock, unlock, split lock.
+.It Li UNCORE_HIT
+L3 Hit: local or remote home requests that hit L3 cache in the uncore
+with no coherency actions required (snooping).
+.It Li OTHER_CORE_HIT_SNP
+L3 Hit: local or remote home requests that hit L3 cache in the uncore
+and was serviced by another core with a cross core snoop where no modified
+copies were found (clean).
+.It Li OTHER_CORE_HITM
+L3 Hit: local or remote home requests that hit L3 cache in the uncore
+and was serviced by another core with a cross core snoop where modified
+copies were found (HITM).
+.It Li REMOTE_CACHE_FWD
+L3 Miss: local homed requests that missed the L3 cache and was serviced
+by forwarded data following a cross package snoop where no modified
+copies found. (Remote home requests are not counted)
+.It Li REMOTE_DRAM
+L3 Miss: remote home requests that missed the L3 cache and were serviced
+by remote DRAM.
+.It Li LOCAL_DRAM
+L3 Miss: local home requests that missed the L3 cache and were serviced
+by local DRAM.
+.It Li NON_DRAM
+Non-DRAM requests that were serviced by IOH.
+.El
+.It Li cmask= Ns Ar value
+Configure the PMC to increment only if the number of configured
+events measured in a cycle is greater than or equal to
+.Ar value .
+.It Li edge
+Configure the PMC to count the number of de-asserted to asserted
+transitions of the conditions expressed by the other qualifiers.
+If specified, the counter will increment only once whenever a
+condition becomes true, irrespective of the number of clocks during
+which the condition remains true.
+.It Li inv
+Invert the sense of comparison when the
+.Dq Li cmask
+qualifier is present, making the counter increment when the number of
+events per cycle is less than the value specified by the
+.Dq Li cmask
+qualifier.
+.It Li os
+Configure the PMC to count events happening at processor privilege
+level 0.
+.It Li usr
+Configure the PMC to count events occurring at privilege levels 1, 2
+or 3.
+.El
+.Pp
+If neither of the
+.Dq Li os
+or
+.Dq Li usr
+qualifiers are specified, the default is to enable both.
+.Ss Event Specifiers (Programmable PMCs)
+Core i7 and Xeon 5500 programmable PMCs support the following events:
+.Bl -tag -width indent
+.It Li SB_DRAIN.ANY
+.Pq Event 04H , Umask 07H
+Counts the number of store buffer drains.
+.It Li STORE_BLOCKS.AT_RET
+.Pq Event 06H , Umask 04H
+Counts number of loads delayed with at-Retirement block code. The following
+loads need to be executed at retirement and wait for all senior stores on
+the same thread to be drained: load splitting across 4K boundary (page
+split), load accessing uncacheable (UC or USWC) memory, load lock, and load
+with page table in UC or USWC memory region.
+.It Li STORE_BLOCKS.L1D_BLOCK
+.Pq Event 06H , Umask 08H
+Cacheable loads delayed with L1D block code
+.It Li PARTIAL_ADDRESS_ALIAS
+.Pq Event 07H , Umask 01H
+Counts false dependency due to partial address aliasing
+.It Li DTLB_LOAD_MISSES.ANY
+.Pq Event 08H , Umask 01H
+Counts all load misses that cause a page walk
+.It Li DTLB_LOAD_MISSES.WALK_COMPLETED
+.Pq Event 08H , Umask 02H
+Counts number of completed page walks due to load miss in the STLB.
+.It Li DTLB_LOAD_MISSES.STLB_HIT
+.Pq Event 08H , Umask 10H
+Number of cache load STLB hits
+.It Li DTLB_LOAD_MISSES.PDE_MISS
+.Pq Event 08H , Umask 20H
+Number of DTLB cache load misses where the low part of the linear to
+physical address translation was missed.
+.It Li DTLB_LOAD_MISSES.PDP_MISS
+.Pq Event 08H , Umask 40H
+Number of DTLB cache load misses where the high part of the linear to
+physical address translation was missed.
+.It Li DTLB_LOAD_MISSES.LARGE_WALK_COMPLETED
+.Pq Event 08H , Umask 80H
+Counts number of completed large page walks due to load miss in the STLB.
+.It Li MEM_INST_RETIRED.LOADS
+.Pq Event 0BH , Umask 01H
+Counts the number of instructions with an architecturally-visible store
+retired on the architected path.
+In conjunction with ld_lat facility
+.It Li MEM_INST_RETIRED.STORES
+.Pq Event 0BH , Umask 02H
+Counts the number of instructions with an architecturally-visible store
+retired on the architected path.
+In conjunction with ld_lat facility
+.It Li MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD
+.Pq Event 0BH , Umask 10H
+Counts the number of instructions exceeding the latency specified with
+ld_lat facility.
+In conjunction with ld_lat facility
+.It Li MEM_STORE_RETIRED.DTLB_MISS
+.Pq Event 0CH , Umask 01H
+The event counts the number of retired stores that missed the DTLB. The DTLB
+miss is not counted if the store operation causes a fault. Does not counter
+prefetches. Counts both primary and secondary misses to the TLB
+.It Li UOPS_ISSUED.ANY
+.Pq Event 0EH , Umask 01H
+Counts the number of Uops issued by the Register Allocation Table to the
+Reservation Station, i.e. the UOPs issued from the front end to the back
+end.
+.It Li UOPS_ISSUED.STALLED_CYCLES
+.Pq Event 0EH , Umask 01H
+Counts the number of cycles no Uops issued by the Register Allocation Table
+to the Reservation Station, i.e. the UOPs issued from the front end to the
+back end.
+set invert=1, cmask = 1
+.It Li UOPS_ISSUED.FUSED
+.Pq Event 0EH , Umask 02H
+Counts the number of fused Uops that were issued from the Register
+Allocation Table to the Reservation Station.
+.It Li MEM_UNCORE_RETIRED.L3_DATA_MISS_UNKNOWN
+.Pq Event 0FH , Umask 01H
+Counts number of memory load instructions retired where the memory reference
+missed L3 and data source is unknown.
+Available only for CPUID signature 06_2EH
+.It Li MEM_UNCORE_RETIRED.OTHER_CORE_L2_HITM
+.Pq Event 0FH , Umask 02H
+Counts number of memory load instructions retired where the memory reference
+hit modified data in a sibling core residing on the same socket.
+.It Li MEM_UNCORE_RETIRED.REMOTE_CACHE_LOCAL_HOME_HIT
+.Pq Event 0FH , Umask 08H
+Counts number of memory load instructions retired where the memory reference
+missed the L1, L2 and L3 caches and HIT in a remote socket's cache. Only
+counts locally homed lines.
+.It Li MEM_UNCORE_RETIRED.REMOTE_DRAM
+.Pq Event 0FH , Umask 10H
+Counts number of memory load instructions retired where the memory reference
+missed the L1, L2 and L3 caches and was remotely homed. This includes both
+DRAM access and HITM in a remote socket's cache for remotely homed lines.
+.It Li MEM_UNCORE_RETIRED.LOCAL_DRAM
+.Pq Event 0FH , Umask 20H
+Counts number of memory load instructions retired where the memory reference
+missed the L1, L2 and L3 caches and required a local socket memory
+reference. This includes locally homed cachelines that were in a modified
+state in another socket.
+.It Li MEM_UNCORE_RETIRED.UNCACHEABLE
+.Pq Event 0FH , Umask 80H
+Counts number of memory load instructions retired where the memory reference
+missed the L1, L2 and L3 caches and to perform I/O.
+Available only for CPUID signature 06_2EH
+.It Li FP_COMP_OPS_EXE.X87
+.Pq Event 10H , Umask 01H
+Counts the number of FP Computational Uops Executed. The number of FADD,
+FSUB, FCOM, FMULs, integer MULsand IMULs, FDIVs, FPREMs, FSQRTS, integer
+DIVs, and IDIVs. This event does not distinguish an FADD used in the middle
+of a transcendental flow from a separate FADD instruction.
+.It Li FP_COMP_OPS_EXE.MMX
+.Pq Event 10H , Umask 02H
+Counts number of MMX Uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_FP
+.Pq Event 10H , Umask 04H
+Counts number of SSE and SSE2 FP uops executed.
+.It Li FP_COMP_OPS_EXE.SSE2_INTEGER
+.Pq Event 10H , Umask 08H
+Counts number of SSE2 integer uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_FP_PACKED
+.Pq Event 10H , Umask 10H
+Counts number of SSE FP packed uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_FP_SCALAR
+.Pq Event 10H , Umask 20H
+Counts number of SSE FP scalar uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION
+.Pq Event 10H , Umask 40H
+Counts number of SSE* FP single precision uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION
+.Pq Event 10H , Umask 80H
+Counts number of SSE* FP double precision uops executed.
+.It Li SIMD_INT_128.PACKED_MPY
+.Pq Event 12H , Umask 01H
+Counts number of 128 bit SIMD integer multiply operations.
+.It Li SIMD_INT_128.PACKED_SHIFT
+.Pq Event 12H , Umask 02H
+Counts number of 128 bit SIMD integer shift operations.
+.It Li SIMD_INT_128.PACK
+.Pq Event 12H , Umask 04H
+Counts number of 128 bit SIMD integer pack operations.
+.It Li SIMD_INT_128.UNPACK
+.Pq Event 12H , Umask 08H
+Counts number of 128 bit SIMD integer unpack operations.
+.It Li SIMD_INT_128.PACKED_LOGICAL
+.Pq Event 12H , Umask 10H
+Counts number of 128 bit SIMD integer logical operations.
+.It Li SIMD_INT_128.PACKED_ARITH
+.Pq Event 12H , Umask 20H
+Counts number of 128 bit SIMD integer arithmetic operations.
+.It Li SIMD_INT_128.SHUFFLE_MOVE
+.Pq Event 12H , Umask 40H
+Counts number of 128 bit SIMD integer shuffle and move operations.
+.It Li LOAD_DISPATCH.RS
+.Pq Event 13H , Umask 01H
+Counts number of loads dispatched from the Reservation Station that bypass
+the Memory Order Buffer.
+.It Li LOAD_DISPATCH.RS_DELAYED
+.Pq Event 13H , Umask 02H
+Counts the number of delayed RS dispatches at the stage latch. If an RS
+dispatch can not bypass to LB, it has another chance to dispatch from the
+one-cycle delayed staging latch before it is written into the LB.
+.It Li LOAD_DISPATCH.MOB
+.Pq Event 13H , Umask 04H
+Counts the number of loads dispatched from the Reservation Station to the
+Memory Order Buffer.
+.It Li LOAD_DISPATCH.ANY
+.Pq Event 13H , Umask 07H
+Counts all loads dispatched from the Reservation Station.
+.It Li ARITH.CYCLES_DIV_BUSY
+.Pq Event 14H , Umask 01H
+Counts the number of cycles the divider is busy executing divide or square
+root operations. The divide can be integer, X87 or Streaming SIMD Extensions
+(SSE). The square root operation can be either X87 or SSE.
+Set 'edge =1, invert=1, cmask=1' to count the number of divides.
+Count may be incorrect When SMT is on.
+.It Li ARITH.MUL
+.Pq Event 14H , Umask 02H
+Counts the number of multiply operations executed. This includes integer as
+well as floating point multiply operations but excludes DPPS mul and MPSAD.
+Count may be incorrect When SMT is on
+.It Li INST_QUEUE_WRITES
+.Pq Event 17H , Umask 01H
+Counts the number of instructions written into the instruction queue every
+cycle.
+.It Li INST_DECODED.DEC0
+.Pq Event 18H , Umask 01H
+Counts number of instructions that require decoder 0 to be decoded. Usually,
+this means that the instruction maps to more than 1 uop
+.It Li TWO_UOP_INSTS_DECODED
+.Pq Event 19H , Umask 01H
+An instruction that generates two uops was decoded
+.It Li INST_QUEUE_WRITE_CYCLES
+.Pq Event 1EH , Umask 01H
+This event counts the number of cycles during which instructions are written
+to the instruction queue. Dividing this counter by the number of
+instructions written to the instruction queue (INST_QUEUE_WRITES) yields the
+average number of instructions decoded each cycle. If this number is less
+than four and the pipe stalls, this indicates that the decoder is failing to
+decode enough instructions per cycle to sustain the 4-wide pipeline.
+If SSE* instructions that are 6 bytes or longer arrive one after another,
+then front end throughput may limit execution speed. In such case,
+.It Li LSD_OVERFLOW
+.Pq Event 20H , Umask 01H
+Counts number of loops that cant stream from the instruction queue.
+.It Li L2_RQSTS.LD_HIT
+.Pq Event 24H , Umask 01H
+Counts number of loads that hit the L2 cache. L2 loads include both L1D
+demand misses as well as L1D prefetches. L2 loads can be rejected for
+various reasons. Only non rejected loads are counted.
+.It Li L2_RQSTS.LD_MISS
+.Pq Event 24H , Umask 02H
+Counts the number of loads that miss the L2 cache. L2 loads include both L1D
+demand misses as well as L1D prefetches.
+.It Li L2_RQSTS.LOADS
+.Pq Event 24H , Umask 03H
+Counts all L2 load requests. L2 loads include both L1D demand misses as well
+as L1D prefetches.
+.It Li L2_RQSTS.RFO_HIT
+.Pq Event 24H , Umask 04H
+Counts the number of store RFO requests that hit the L2 cache. L2 RFO
+requests include both L1D demand RFO misses as well as L1D RFO prefetches.
+Count includes WC memory requests, where the data is not fetched but the
+permission to write the line is required.
+.It Li L2_RQSTS.RFO_MISS
+.Pq Event 24H , Umask 08H
+Counts the number of store RFO requests that miss the L2 cache. L2 RFO
+requests include both L1D demand RFO misses as well as L1D RFO prefetches.
+.It Li L2_RQSTS.RFOS
+.Pq Event 24H , Umask 0CH
+Counts all L2 store RFO requests. L2 RFO requests include both L1D demand
+RFO misses as well as L1D RFO prefetches.
+.It Li L2_RQSTS.IFETCH_HIT
+.Pq Event 24H , Umask 10H
+Counts number of instruction fetches that hit the L2 cache. L2 instruction
+fetches include both L1I demand misses as well as L1I instruction
+prefetches.
+.It Li L2_RQSTS.IFETCH_MISS
+.Pq Event 24H , Umask 20H
+Counts number of instruction fetches that miss the L2 cache. L2 instruction
+fetches include both L1I demand misses as well as L1I instruction
+prefetches.
+.It Li L2_RQSTS.IFETCHES
+.Pq Event 24H , Umask 30H
+Counts all instruction fetches. L2 instruction fetches include both L1I
+demand misses as well as L1I instruction prefetches.
+.It Li L2_RQSTS.PREFETCH_HIT
+.Pq Event 24H , Umask 40H
+Counts L2 prefetch hits for both code and data.
+.It Li L2_RQSTS.PREFETCH_MISS
+.Pq Event 24H , Umask 80H
+Counts L2 prefetch misses for both code and data.
+.It Li L2_RQSTS.PREFETCHES
+.Pq Event 24H , Umask C0H
+Counts all L2 prefetches for both code and data.
+.It Li L2_RQSTS.MISS
+.Pq Event 24H , Umask AAH
+Counts all L2 misses for both code and data.
+.It Li L2_RQSTS.REFERENCES
+.Pq Event 24H , Umask FFH
+Counts all L2 requests for both code and data.
+.It Li L2_DATA_RQSTS.DEMAND.I_STATE
+.Pq Event 26H , Umask 01H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the I (invalid) state, i.e. a cache miss. L2 demand loads are both L1D
+demand misses and L1D prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.S_STATE
+.Pq Event 26H , Umask 02H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the S (shared) state. L2 demand loads are both L1D demand misses and L1D
+prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.E_STATE
+.Pq Event 26H , Umask 04H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the E (exclusive) state. L2 demand loads are both L1D demand misses and
+L1D prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.M_STATE
+.Pq Event 26H , Umask 08H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the M (modified) state. L2 demand loads are both L1D demand misses and
+L1D prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.MESI
+.Pq Event 26H , Umask 0FH
+Counts all L2 data demand requests. L2 demand loads are both L1D demand
+misses and L1D prefetches.
+.It Li L2_DATA_RQSTS.PREFETCH.I_STATE
+.Pq Event 26H , Umask 10H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the I (invalid) state, i.e. a cache miss.
+.It Li L2_DATA_RQSTS.PREFETCH.S_STATE
+.Pq Event 26H , Umask 20H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the S (shared) state. A prefetch RFO will miss on an S state line, while
+a prefetch read will hit on an S state line.
+.It Li L2_DATA_RQSTS.PREFETCH.E_STATE
+.Pq Event 26H , Umask 40H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the E (exclusive) state.
+.It Li L2_DATA_RQSTS.PREFETCH.M_STATE
+.Pq Event 26H , Umask 80H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the M (modified) state.
+.It Li L2_DATA_RQSTS.PREFETCH.MESI
+.Pq Event 26H , Umask F0H
+Counts all L2 prefetch requests.
+.It Li L2_DATA_RQSTS.ANY
+.Pq Event 26H , Umask FFH
+Counts all L2 data requests.
+.It Li L2_WRITE.RFO.I_STATE
+.Pq Event 27H , Umask 01H
+Counts number of L2 demand store RFO requests where the cache line to be
+loaded is in the I (invalid) state, i.e, a cache miss. The L1D prefetcher
+does not issue a RFO prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.S_STATE
+.Pq Event 27H , Umask 02H
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in the S (shared) state. The L1D prefetcher does not issue a RFO prefetch,.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.M_STATE
+.Pq Event 27H , Umask 08H
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in the M (modified) state. The L1D prefetcher does not issue a RFO prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.HIT
+.Pq Event 27H , Umask 0EH
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in either the S, E or M states. The L1D prefetcher does not issue a RFO
+prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.MESI
+.Pq Event 27H , Umask 0FH
+Counts all L2 store RFO requests.The L1D prefetcher does not issue a RFO
+prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.LOCK.I_STATE
+.Pq Event 27H , Umask 10H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in the I (invalid) state, i.e. a cache miss.
+.It Li L2_WRITE.LOCK.S_STATE
+.Pq Event 27H , Umask 20H
+Counts number of L2 lock RFO requests where the cache line to be loaded is
+in the S (shared) state.
+.It Li L2_WRITE.LOCK.E_STATE
+.Pq Event 27H , Umask 40H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in the E (exclusive) state.
+.It Li L2_WRITE.LOCK.M_STATE
+.Pq Event 27H , Umask 80H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in the M (modified) state.
+.It Li L2_WRITE.LOCK.HIT
+.Pq Event 27H , Umask E0H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in either the S, E, or M state.
+.It Li L2_WRITE.LOCK.MESI
+.Pq Event 27H , Umask F0H
+Counts all L2 demand lock RFO requests.
+.It Li L1D_WB_L2.I_STATE
+.Pq Event 28H , Umask 01H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the I (invalid) state, i.e. a cache miss.
+.It Li L1D_WB_L2.S_STATE
+.Pq Event 28H , Umask 02H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the S state.
+.It Li L1D_WB_L2.E_STATE
+.Pq Event 28H , Umask 04H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the E (exclusive) state.
+.It Li L1D_WB_L2.M_STATE
+.Pq Event 28H , Umask 08H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the M (modified) state.
+.It Li L1D_WB_L2.MESI
+.Pq Event 28H , Umask 0FH
+Counts all L1 writebacks to the L2.
+.It Li L3_LAT_CACHE.REFERENCE
+.Pq Event 2EH , Umask 4FH
+This event counts requests originating from the core that reference a cache
+line in the last level cache. The event count includes speculative traffic
+but excludes cache line fills due to a L2 hardware-prefetch. Because cache
+hierarchy, cache sizes and other implementation-specific characteristics;
+value comparison to estimate performance differences is not recommended.
+see Table A-1
+.It Li L3_LAT_CACHE.MISS
+.Pq Event 2EH , Umask 41H
+This event counts each cache miss condition for references to the last level
+cache. The event count may include speculative traffic but excludes cache
+line fills due to L2 hardware-prefetches. Because cache hierarchy, cache
+sizes and other implementation-specific characteristics; value comparison to
+estimate performance differences is not recommended.
+see Table A-1
+.It Li CPU_CLK_UNHALTED.THREAD_P
+.Pq Event 3CH , Umask 00H
+Counts the number of thread cycles while the thread is not in a halt state.
+The thread enters the halt state when it is running the HLT instruction. The
+core frequency may change from time to time due to power or thermal
+throttling.
+see Table A-1
+.It Li CPU_CLK_UNHALTED.REF_P
+.Pq Event 3CH , Umask 01H
+Increments at the frequency of TSC when not halted.
+see Table A-1
+.It Li L1D_CACHE_LD.I_STATE
+.Pq Event 40H , Umask 01H
+Counts L1 data cache read requests where the cache line to be loaded is in
+the I (invalid) state, i.e. the read request missed the cache.
+Counter 0, 1 only
+.It Li L1D_CACHE_LD.S_STATE
+.Pq Event 40H , Umask 02H
+Counts L1 data cache read requests where the cache line to be loaded is in
+the S (shared) state.
+Counter 0, 1 only
+.It Li L1D_CACHE_LD.E_STATE
+.Pq Event 40H , Umask 04H
+Counts L1 data cache read requests where the cache line to be loaded is in
+the E (exclusive) state.
+Counter 0, 1 only
+.It Li L1D_CACHE_LD.M_STATE
+.Pq Event 40H , Umask 08H
+Counts L1 data cache read requests where the cache line to be loaded is in
+the M (modified) state.
+Counter 0, 1 only
+.It Li L1D_CACHE_LD.MESI
+.Pq Event 40H , Umask 0FH
+Counts L1 data cache read requests.
+Counter 0, 1 only
+.It Li L1D_CACHE_ST.S_STATE
+.Pq Event 41H , Umask 02H
+Counts L1 data cache store RFO requests where the cache line to be loaded is
+in the S (shared) state.
+Counter 0, 1 only
+.It Li L1D_CACHE_ST.E_STATE
+.Pq Event 41H , Umask 04H
+Counts L1 data cache store RFO requests where the cache line to be loaded is
+in the E (exclusive) state.
+Counter 0, 1 only
+.It Li L1D_CACHE_ST.M_STATE
+.Pq Event 41H , Umask 08H
+Counts L1 data cache store RFO requests where cache line to be loaded is in
+the M (modified) state.
+Counter 0, 1 only
+.It Li L1D_CACHE_LOCK.HIT
+.Pq Event 42H , Umask 01H
+Counts retired load locks that hit in the L1 data cache or hit in an already
+allocated fill buffer. The lock portion of the load lock transaction must
+hit in the L1D.
+The initial load will pull the lock into the L1 data cache. Counter 0, 1
+only
+.It Li L1D_CACHE_LOCK.S_STATE
+.Pq Event 42H , Umask 02H
+Counts L1 data cache retired load locks that hit the target cache line in
+the shared state.
+Counter 0, 1 only
+.It Li L1D_CACHE_LOCK.E_STATE
+.Pq Event 42H , Umask 04H
+Counts L1 data cache retired load locks that hit the target cache line in
+the exclusive state.
+Counter 0, 1 only
+.It Li L1D_CACHE_LOCK.M_STATE
+.Pq Event 42H , Umask 08H
+Counts L1 data cache retired load locks that hit the target cache line in
+the modified state.
+Counter 0, 1 only
+.It Li L1D_ALL_REF.ANY
+.Pq Event 43H , Umask 01H
+Counts all references (uncached, speculated and retired) to the L1 data
+cache, including all loads and stores with any memory types. The event
+counts memory accesses only when they are actually performed. For example, a
+load blocked by unknown store address and later performed is only counted
+once.
+The event does not include non- memory accesses, such as I/O accesses.
+Counter 0, 1 only
+.It Li L1D_ALL_REF.CACHEABLE
+.Pq Event 43H , Umask 02H
+Counts all data reads and writes (speculated and retired) from cacheable
+memory, including locked operations.
+Counter 0, 1 only
+.It Li L1D_PEND_MISS.LOAD_BUFFERS_FULL
+.Pq Event 48H , Umask 02H
+Counts cycles of L1 data cache load fill buffers full.
+Counter 0, 1 only
+.It Li DTLB_MISSES.ANY
+.Pq Event 49H , Umask 01H
+Counts the number of misses in the STLB which causes a page walk.
+.It Li DTLB_MISSES.WALK_COMPLETED
+.Pq Event 49H , Umask 02H
+Counts number of misses in the STLB which resulted in a completed page walk.
+.It Li DTLB_MISSES.STLB_HIT
+.Pq Event 49H , Umask 10H
+Counts the number of DTLB first level misses that hit in the second level
+TLB. This event is only relevant if the core contains multiple DTLB levels.
+.It Li LOAD_HIT_PRE
+.Pq Event 4CH , Umask 01H
+Counts load operations sent to the L1 data cache while a previous SSE
+prefetch instruction to the same cache line has started prefetching but has
+not yet finished.
+.It Li L1D_PREFETCH.REQUESTS
+.Pq Event 4EH , Umask 01H
+Counts number of hardware prefetch requests dispatched out of the prefetch
+FIFO.
+.It Li L1D_PREFETCH.MISS
+.Pq Event 4EH , Umask 02H
+Counts number of hardware prefetch requests that miss the L1D. There are two
+prefetchers in the L1D. A streamer, which predicts lines sequentially after
+this one should be fetched, and the IP prefetcher that remembers access
+patterns for the current instruction. The streamer prefetcher stops on an
+L1D hit, while the IP prefetcher does not.
+.It Li L1D_PREFETCH.TRIGGERS
+.Pq Event 4EH , Umask 04H
+Counts number of prefetch requests triggered by the Finite State Machine and
+pushed into the prefetch FIFO. Some of the prefetch requests are dropped due
+to overwrites or competition between the IP index prefetcher and streamer
+prefetcher. The prefetch FIFO contains 4 entries.
+.It Li L1D.REPL
+.Pq Event 51H , Umask 01H
+Counts the number of lines brought into the L1 data cache.
+Counter 0, 1 only
+.It Li L1D.M_REPL
+.Pq Event 51H , Umask 02H
+Counts the number of modified lines brought into the L1 data cache.
+Counter 0, 1 only
+.It Li L1D.M_EVICT
+.Pq Event 51H , Umask 04H
+Counts the number of modified lines evicted from the L1 data cache due to
+replacement.
+Counter 0, 1 only
+.It Li L1D.M_SNOOP_EVICT
+.Pq Event 51H , Umask 08H
+Counts the number of modified lines evicted from the L1 data cache due to
+snoop HITM intervention.
+Counter 0, 1 only
+.It Li L1D_CACHE_PREFETCH_LOCK_FB_HIT
+.Pq Event 52H , Umask 01H
+Counts the number of cacheable load lock speculated instructions accepted
+into the fill buffer.
+.It Li L1D_CACHE_LOCK_FB_HIT
+.Pq Event 53H , Umask 01H
+Counts the number of cacheable load lock speculated or retired instructions
+accepted into the fill buffer.
+.It Li CACHE_LOCK_CYCLES.L1D_L2
+.Pq Event 63H , Umask 01H
+Cycle count during which the L1D and L2 are locked. A lock is asserted when
+there is a locked memory access, due to uncacheable memory, a locked
+operation that spans two cache lines, or a page walk from an uncacheable
+page table.
+Counter 0, 1 only. L1D and L2 locks have a very high performance penalty and
+it is highly recommended to avoid such accesses.
+.It Li CACHE_LOCK_CYCLES.L1D
+.Pq Event 63H , Umask 02H
+Counts the number of cycles that cacheline in the L1 data cache unit is
+locked.
+Counter 0, 1 only.
+.It Li IO_TRANSACTIONS
+.Pq Event 6CH , Umask 01H
+Counts the number of completed I/O transactions.
+.It Li L1I.HITS
+.Pq Event 80H , Umask 01H
+Counts all instruction fetches that hit the L1 instruction cache.
+.It Li L1I.MISSES
+.Pq Event 80H , Umask 02H
+Counts all instruction fetches that miss the L1I cache. This includes
+instruction cache misses, streaming buffer misses, victim cache misses and
+uncacheable fetches. An instruction fetch miss is counted only once and not
+once for every cycle it is outstanding.
+.It Li L1I.READS
+.Pq Event 80H , Umask 03H
+Counts all instruction fetches, including uncacheable fetches that bypass
+the L1I.
+.It Li L1I.CYCLES_STALLED
+.Pq Event 80H , Umask 04H
+Cycle counts for which an instruction fetch stalls due to a L1I cache miss,
+ITLB miss or ITLB fault.
+.It Li LARGE_ITLB.HIT
+.Pq Event 82H , Umask 01H
+Counts number of large ITLB hits.
+.It Li ITLB_MISSES.ANY
+.Pq Event 85H , Umask 01H
+Counts the number of misses in all levels of the ITLB which causes a page
+walk.
+.It Li ITLB_MISSES.WALK_COMPLETED
+.Pq Event 85H , Umask 02H
+Counts number of misses in all levels of the ITLB which resulted in a
+completed page walk.
+.It Li ILD_STALL.LCP
+.Pq Event 87H , Umask 01H
+Cycles Instruction Length Decoder stalls due to length changing prefixes:
+66, 67 or REX.W (for EM64T) instructions which change the length of the
+decoded instruction.
+.It Li ILD_STALL.MRU
+.Pq Event 87H , Umask 02H
+Instruction Length Decoder stall cycles due to Brand Prediction Unit (PBU)
+Most Recently Used (MRU) bypass.
+.It Li ILD_STALL.IQ_FULL
+.Pq Event 87H , Umask 04H
+Stall cycles due to a full instruction queue.
+.It Li ILD_STALL.REGEN
+.Pq Event 87H , Umask 08H
+Counts the number of regen stalls.
+.It Li ILD_STALL.ANY
+.Pq Event 87H , Umask 0FH
+Counts any cycles the Instruction Length Decoder is stalled.
+.It Li BR_INST_EXEC.COND
+.Pq Event 88H , Umask 01H
+Counts the number of conditional near branch instructions executed, but not
+necessarily retired.
+.It Li BR_INST_EXEC.DIRECT
+.Pq Event 88H , Umask 02H
+Counts all unconditional near branch instructions excluding calls and
+indirect branches.
+.It Li BR_INST_EXEC.INDIRECT_NON_CALL
+.Pq Event 88H , Umask 04H
+Counts the number of executed indirect near branch instructions that are not
+calls.
+.It Li BR_INST_EXEC.NON_CALLS
+.Pq Event 88H , Umask 07H
+Counts all non call near branch instructions executed, but not necessarily
+retired.
+.It Li BR_INST_EXEC.RETURN_NEAR
+.Pq Event 88H , Umask 08H
+Counts indirect near branches that have a return mnemonic.
+.It Li BR_INST_EXEC.DIRECT_NEAR_CALL
+.Pq Event 88H , Umask 10H
+Counts unconditional near call branch instructions, excluding non call
+branch, executed.
+.It Li BR_INST_EXEC.INDIRECT_NEAR_CALL
+.Pq Event 88H , Umask 20H
+Counts indirect near calls, including both register and memory indirect,
+executed.
+.It Li BR_INST_EXEC.NEAR_CALLS
+.Pq Event 88H , Umask 30H
+Counts all near call branches executed, but not necessarily retired.
+.It Li BR_INST_EXEC.TAKEN
+.Pq Event 88H , Umask 40H
+Counts taken near branches executed, but not necessarily retired.
+.It Li BR_INST_EXEC.ANY
+.Pq Event 88H , Umask 7FH
+Counts all near executed branches (not necessarily retired). This includes
+only instructions and not micro-op branches. Frequent branching is not
+necessarily a major performance issue. However frequent branch
+mispredictions may be a problem.
+.It Li BR_MISP_EXEC.COND
+.Pq Event 89H , Umask 01H
+Counts the number of mispredicted conditional near branch instructions
+executed, but not necessarily retired.
+.It Li BR_MISP_EXEC.DIRECT
+.Pq Event 89H , Umask 02H
+Counts mispredicted macro unconditional near branch instructions, excluding
+calls and indirect branches (should always be 0).
+.It Li BR_MISP_EXEC.INDIRECT_NON_CALL
+.Pq Event 89H , Umask 04H
+Counts the number of executed mispredicted indirect near branch instructions
+that are not calls.
+.It Li BR_MISP_EXEC.NON_CALLS
+.Pq Event 89H , Umask 07H
+Counts mispredicted non call near branches executed, but not necessarily
+retired.
+.It Li BR_MISP_EXEC.RETURN_NEAR
+.Pq Event 89H , Umask 08H
+Counts mispredicted indirect branches that have a rear return mnemonic.
+.It Li BR_MISP_EXEC.DIRECT_NEAR_CALL
+.Pq Event 89H , Umask 10H
+Counts mispredicted non-indirect near calls executed, (should always be 0).
+.It Li BR_MISP_EXEC.INDIRECT_NEAR_CALL
+.Pq Event 89H , Umask 20H
+Counts mispredicted indirect near calls exeucted, including both register
+and memory indirect.
+.It Li BR_MISP_EXEC.NEAR_CALLS
+.Pq Event 89H , Umask 30H
+Counts all mispredicted near call branches executed, but not necessarily
+retired.
+.It Li BR_MISP_EXEC.TAKEN
+.Pq Event 89H , Umask 40H
+Counts executed mispredicted near branches that are taken, but not
+necessarily retired.
+.It Li BR_MISP_EXEC.ANY
+.Pq Event 89H , Umask 7FH
+Counts the number of mispredicted near branch instructions that were
+executed, but not necessarily retired.
+.It Li RESOURCE_STALLS.ANY
+.Pq Event A2H , Umask 01H
+Counts the number of Allocator resource related stalls. Includes register
+renaming buffer entries, memory buffer entries. In addition to resource
+related stalls, this event counts some other events. Includes stalls arising
+during branch misprediction recovery, such as if retirement of the
+mispredicted branch is delayed and stalls arising while store buffer is
+draining from synchronizing operations.
+Does not include stalls due to SuperQ (off core) queue full, too many cache
+misses, etc.
+.It Li RESOURCE_STALLS.LOAD
+.Pq Event A2H , Umask 02H
+Counts the cycles of stall due to lack of load buffer for load operation.
+.It Li RESOURCE_STALLS.RS_FULL
+.Pq Event A2H , Umask 04H
+This event counts the number of cycles when the number of instructions in
+the pipeline waiting for execution reaches the limit the processor can
+handle. A high count of this event indicates that there are long latency
+operations in the pipe (possibly load and store operations that miss the L2
+cache, or instructions dependent upon instructions further down the pipeline
+that have yet to retire.
+When RS is full, new instructions can not enter the reservation station and
+start execution.
+.It Li RESOURCE_STALLS.STORE
+.Pq Event A2H , Umask 08H
+This event counts the number of cycles that a resource related stall will
+occur due to the number of store instructions reaching the limit of the
+pipeline, (i.e. all store buffers are used). The stall ends when a store
+instruction commits its data to the cache or memory.
+.It Li RESOURCE_STALLS.ROB_FULL
+.Pq Event A2H , Umask 10H
+Counts the cycles of stall due to re- order buffer full.
+.It Li RESOURCE_STALLS.FPCW
+.Pq Event A2H , Umask 20H
+Counts the number of cycles while execution was stalled due to writing the
+floating-point unit (FPU) control word.
+.It Li RESOURCE_STALLS.MXCSR
+.Pq Event A2H , Umask 40H
+Stalls due to the MXCSR register rename occurring to close to a previous
+MXCSR rename. The MXCSR provides control and status for the MMX registers.
+.It Li RESOURCE_STALLS.OTHER
+.Pq Event A2H , Umask 80H
+Counts the number of cycles while execution was stalled due to other
+resource issues.
+.It Li MACRO_INSTS.FUSIONS_DECODED
+.Pq Event A6H , Umask 01H
+Counts the number of instructions decoded that are macro-fused but not
+necessarily executed or retired.
+.It Li BACLEAR_FORCE_IQ
+.Pq Event A7H , Umask 01H
+Counts number of times a BACLEAR was forced by the Instruction Queue. The IQ
+is also responsible for providing conditional branch prediciton direction
+based on a static scheme and dynamic data provided by the L2 Branch
+Prediction Unit. If the conditional branch target is not found in the Target
+Array and the IQ predicts that the branch is taken, then the IQ will force
+the Branch Address Calculator to issue a BACLEAR. Each BACLEAR asserted by
+the BAC generates approximately an 8 cycle bubble in the instruction fetch
+pipeline.
+.It Li LSD.UOPS
+.Pq Event A8H , Umask 01H
+Counts the number of micro-ops delivered by loop stream detector
+Use cmask=1 and invert to count cycles
+.It Li ITLB_FLUSH
+.Pq Event AEH , Umask 01H
+Counts the number of ITLB flushes
+.It Li OFFCORE_REQUESTS.L1D_WRITEBACK
+.Pq Event B0H , Umask 40H
+Counts number of L1D writebacks to the uncore.
+.It Li UOPS_EXECUTED.PORT0
+.Pq Event B1H , Umask 01H
+Counts number of Uops executed that were issued on port 0. Port 0 handles
+integer arithmetic, SIMD and FP add Uops.
+.It Li UOPS_EXECUTED.PORT1
+.Pq Event B1H , Umask 02H
+Counts number of Uops executed that were issued on port 1. Port 1 handles
+integer arithmetic, SIMD, integer shift, FP multiply and FP divide Uops.
+.It Li UOPS_EXECUTED.PORT2_CORE
+.Pq Event B1H , Umask 04H
+Counts number of Uops executed that were issued on port 2. Port 2 handles
+the load Uops. This is a core count only and can not be collected per
+thread.
+.It Li UOPS_EXECUTED.PORT3_CORE
+.Pq Event B1H , Umask 08H
+Counts number of Uops executed that were issued on port 3. Port 3 handles
+store Uops. This is a core count only and can not be collected per thread.
+.It Li UOPS_EXECUTED.PORT4_CORE
+.Pq Event B1H , Umask 10H
+Counts number of Uops executed that where issued on port 4. Port 4 handles
+the value to be stored for the store Uops issued on port 3. This is a core
+count only and can not be collected per thread.
+.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5
+.Pq Event B1H , Umask 1FH
+Counts cycles when the Uops executed were issued from any ports except port
+5. Use Cmask=1 for active cycles; Cmask=0 for weighted cycles; Use CMask=1,
+Invert=1 to count P0-4 stalled cycles Use Cmask=1, Edge=1, Invert=1 to count
+P0-4 stalls.
+.It Li UOPS_EXECUTED.PORT5
+.Pq Event B1H , Umask 20H
+Counts number of Uops executed that where issued on port 5.
+.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES
+.Pq Event B1H , Umask 3FH
+Counts cycles when the Uops are executing. Use Cmask=1 for active cycles;
+Cmask=0 for weighted cycles; Use CMask=1, Invert=1 to count P0-4 stalled
+cycles Use Cmask=1, Edge=1, Invert=1 to count P0-4 stalls.
+.It Li UOPS_EXECUTED.PORT015
+.Pq Event B1H , Umask 40H
+Counts number of Uops executed that where issued on port 0, 1, or 5.
+use cmask=1, invert=1 to count stall cycles
+.It Li UOPS_EXECUTED.PORT234
+.Pq Event B1H , Umask 80H
+Counts number of Uops executed that where issued on port 2, 3, or 4.
+.It Li OFFCORE_REQUESTS_SQ_FULL
+.Pq Event B2H , Umask 01H
+Counts number of cycles the SQ is full to handle off-core requests.
+.It Li OFF_CORE_RESPONSE_0
+.Pq Event B7H , Umask 01H
+see Section 30.6.1.3, Off-core Response Performance Monitoring in the
+Processor Core
+Requires programming MSR 01A6H
+.It Li SNOOP_RESPONSE.HIT
+.Pq Event B8H , Umask 01H
+Counts HIT snoop response sent by this thread in response to a snoop
+request.
+.It Li SNOOP_RESPONSE.HITE
+.Pq Event B8H , Umask 02H
+Counts HIT E snoop response sent by this thread in response to a snoop
+request.
+.It Li SNOOP_RESPONSE.HITM
+.Pq Event B8H , Umask 04H
+Counts HIT M snoop response sent by this thread in response to a snoop
+request.
+.It Li OFF_CORE_RESPONSE_1
+.Pq Event BBH , Umask 01H
+see Section 30.6.1.3, Off-core Response Performance Monitoring in the
+Processor Core
+Requires programming MSR 01A7H
+.It Li INST_RETIRED.ANY_P
+.Pq Event C0H , Umask 01H
+See Table A-1
+Notes: INST_RETIRED.ANY is counted by a designated fixed counter.
+INST_RETIRED.ANY_P is counted by a programmable counter and is an
+architectural performance event. Event is supported if CPUID.A.EBX[1] = 0.
+Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not
+count as retired instructions.
+.It Li INST_RETIRED.X87
+.Pq Event C0H , Umask 02H
+Counts the number of MMX instructions retired:.
+.It Li INST_RETIRED.MMX
+.Pq Event C0H , Umask 04H
+Counts the number of floating point computational operations retired:
+floating point computational operations executed by the assist handler and
+sub-operations of complex floating point instructions like transcendental
+instructions.
+.It Li UOPS_RETIRED.ANY
+.Pq Event C2H , Umask 01H
+Counts the number of micro-ops retired, (macro-fused=1, micro- fused=2,
+others=1; maximum count of 8 per cycle). Most instructions are composed of
+one or two micro-ops. Some instructions are decoded into longer sequences
+such as repeat instructions, floating point transcendental instructions, and
+assists.
+Use cmask=1 and invert to count active cycles or stalled cycles
+.It Li UOPS_RETIRED.RETIRE_SLOTS
+.Pq Event C2H , Umask 02H
+Counts the number of retirement slots used each cycle
+.It Li UOPS_RETIRED.MACRO_FUSED
+.Pq Event C2H , Umask 04H
+Counts number of macro-fused uops retired.
+.It Li MACHINE_CLEARS.CYCLES
+.Pq Event C3H , Umask 01H
+Counts the cycles machine clear is asserted.
+.It Li MACHINE_CLEARS.MEM_ORDER
+.Pq Event C3H , Umask 02H
+Counts the number of machine clears due to memory order conflicts.
+.It Li MACHINE_CLEARS.SMC
+.Pq Event C3H , Umask 04H
+Counts the number of times that a program writes to a code section.
+Self-modifying code causes a sever penalty in all Intel 64 and IA-32
+processors. The modified cache line is written back to the L2 and L3caches.
+.It Li BR_INST_RETIRED.ALL_BRANCHES
+.Pq Event C4H , Umask 00H
+See Table A-1
+.It Li BR_INST_RETIRED.CONDITIONAL
+.Pq Event C4H , Umask 01H
+Counts the number of conditional branch instructions retired.
+.It Li BR_INST_RETIRED.NEAR_CALL
+.Pq Event C4H , Umask 02H
+Counts the number of direct & indirect near unconditional calls retired
+.It Li BR_INST_RETIRED.ALL_BRANCHES
+.Pq Event C4H , Umask 04H
+Counts the number of branch instructions retired
+.It Li BR_MISP_RETIRED.ALL_BRANCHES
+.Pq Event C5H , Umask 00H
+See Table A-1
+.It Li BR_MISP_RETIRED.NEAR_CALL
+.Pq Event C5H , Umask 02H
+Counts mispredicted direct & indirect near unconditional retired calls.
+.It Li SSEX_UOPS_RETIRED.PACKED_SINGLE
+.Pq Event C7H , Umask 01H
+Counts SIMD packed single-precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.SCALAR_SINGLE
+.Pq Event C7H , Umask 02H
+Counts SIMD calar single-precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.PACKED_DOUBLE
+.Pq Event C7H , Umask 04H
+Counts SIMD packed double- precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.SCALAR_DOUBLE
+.Pq Event C7H , Umask 08H
+Counts SIMD scalar double-precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.VECTOR_INTEGER
+.Pq Event C7H , Umask 10H
+Counts 128-bit SIMD vector integer Uops retired.
+.It Li ITLB_MISS_RETIRED
+.Pq Event C8H , Umask 20H
+Counts the number of retired instructions that missed the ITLB when the
+instruction was fetched.
+.It Li MEM_LOAD_RETIRED.L1D_HIT
+.Pq Event CBH , Umask 01H
+Counts number of retired loads that hit the L1 data cache.
+.It Li MEM_LOAD_RETIRED.L2_HIT
+.Pq Event CBH , Umask 02H
+Counts number of retired loads that hit the L2 data cache.
+.It Li MEM_LOAD_RETIRED.L3_UNSHARED_HIT
+.Pq Event CBH , Umask 04H
+Counts number of retired loads that hit their own, unshared lines in the L3
+cache.
+.It Li MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM
+.Pq Event CBH , Umask 08H
+Counts number of retired loads that hit in a sibling core's L2 (on die
+core). Since the L3 is inclusive of all cores on the package, this is an L3
+hit. This counts both clean or modified hits.
+.It Li MEM_LOAD_RETIRED.L3_MISS
+.Pq Event CBH , Umask 10H
+Counts number of retired loads that miss the L3 cache. The load was
+satisfied by a remote socket, local memory or an IOH.
+.It Li MEM_LOAD_RETIRED.HIT_LFB
+.Pq Event CBH , Umask 40H
+Counts number of retired loads that miss the L1D and the address is located
+in an allocated line fill buffer and will soon be committed to cache. This
+is counting secondary L1D misses.
+.It Li MEM_LOAD_RETIRED.DTLB_MISS
+.Pq Event CBH , Umask 80H
+Counts the number of retired loads that missed the DTLB. The DTLB miss is
+not counted if the load operation causes a fault. This event counts loads
+from cacheable memory only. The event does not count loads by software
+prefetches. Counts both primary and secondary misses to the TLB.
+.It Li FP_MMX_TRANS.TO_FP
+.Pq Event CCH , Umask 01H
+Counts the first floating-point instruction following any MMX instruction.
+You can use this event to estimate the penalties for the transitions between
+floating-point and MMX technology states.
+.It Li FP_MMX_TRANS.TO_MMX
+.Pq Event CCH , Umask 02H
+Counts the first MMX instruction following a floating-point instruction. You
+can use this event to estimate the penalties for the transitions between
+floating-point and MMX technology states.
+.It Li FP_MMX_TRANS.ANY
+.Pq Event CCH , Umask 03H
+Counts all transitions from floating point to MMX instructions and from MMX
+instructions to floating point instructions. You can use this event to
+estimate the penalties for the transitions between floating-point and MMX
+technology states.
+.It Li MACRO_INSTS.DECODED
+.Pq Event D0H , Umask 01H
+Counts the number of instructions decoded, (but not necessarily executed or
+retired).
+.It Li UOPS_DECODED.MS
+.Pq Event D1H , Umask 02H
+Counts the number of Uops decoded by the Microcode Sequencer, MS. The MS
+delivers uops when the instruction is more than 4 uops long or a microcode
+assist is occurring.
+.It Li UOPS_DECODED.ESP_FOLDING
+.Pq Event D1H , Umask 04H
+Counts number of stack pointer (ESP) instructions decoded: push , pop , call
+, ret, etc. ESP instructions do not generate a Uop to increment or decrement
+ESP. Instead, they update an ESP_Offset register that keeps track of the
+delta to the current value of the ESP register.
+.It Li UOPS_DECODED.ESP_SYNC
+.Pq Event D1H , Umask 08H
+Counts number of stack pointer (ESP) sync operations where an ESP
+instruction is corrected by adding the ESP offset register to the current
+value of the ESP register.
+.It Li RAT_STALLS.FLAGS
+.Pq Event D2H , Umask 01H
+Counts the number of cycles during which execution stalled due to several
+reasons, one of which is a partial flag register stall. A partial register
+stall may occur when two conditions are met: 1) an instruction modifies
+some, but not all, of the flags in the flag register and 2) the next
+instruction, which depends on flags, depends on flags that were not modified
+by this instruction.
+.It Li RAT_STALLS.REGISTERS
+.Pq Event D2H , Umask 02H
+This event counts the number of cycles instruction execution latency became
+longer than the defined latency because the instruction used a register that
+was partially written by previous instruction.
+.It Li RAT_STALLS.ROB_READ_PORT
+.Pq Event D2H , Umask 04H
+Counts the number of cycles when ROB read port stalls occurred, which did
+not allow new micro-ops to enter the out-of-order pipeline. Note that, at
+this stage in the pipeline, additional stalls may occur at the same cycle
+and prevent the stalled micro-ops from entering the pipe. In such a case,
+micro-ops retry entering the execution pipe in the next cycle and the
+ROB-read port stall is counted again.
+.It Li RAT_STALLS.SCOREBOARD
+.Pq Event D2H , Umask 08H
+Counts the cycles where we stall due to microarchitecturally required
+serialization. Microcode scoreboarding stalls.
+.It Li RAT_STALLS.ANY
+.Pq Event D2H , Umask 0FH
+Counts all Register Allocation Table stall cycles due to: Cycles when ROB
+read port stalls occurred, which did not allow new micro-ops to enter the
+execution pipe. Cycles when partial register stalls occurred Cycles when
+flag stalls occurred Cycles floating-point unit (FPU) status word stalls
+occurred. To count each of these conditions separately use the events:
+RAT_STALLS.ROB_READ_PORT, RAT_STALLS.PARTIAL, RAT_STALLS.FLAGS, and
+RAT_STALLS.FPSW.
+.It Li SEG_RENAME_STALLS
+.Pq Event D4H , Umask 01H
+Counts the number of stall cycles due to the lack of renaming resources for
+the ES, DS, FS, and GS segment registers. If a segment is renamed but not
+retired and a second update to the same segment occurs, a stall occurs in
+the front-end of the pipeline until the renamed segment retires.
+.It Li ES_REG_RENAMES
+.Pq Event D5H , Umask 01H
+Counts the number of times the ES segment register is renamed.
+.It Li UOP_UNFUSION
+.Pq Event DBH , Umask 01H
+Counts unfusion events due to floating point exception to a fused uop.
+.It Li BR_INST_DECODED
+.Pq Event E0H , Umask 01H
+Counts the number of branch instructions decoded.
+.It Li BPU_MISSED_CALL_RET
+.Pq Event E5H , Umask 01H
+Counts number of times the Branch Prediciton Unit missed predicting a call
+or return branch.
+.It Li BACLEAR.CLEAR
+.Pq Event E6H , Umask 01H
+Counts the number of times the front end is resteered, mainly when the
+Branch Prediction Unit cannot provide a correct prediction and this is
+corrected by the Branch Address Calculator at the front end. This can occur
+if the code has many branches such that they cannot be consumed by the BPU.
+Each BACLEAR asserted by the BAC generates approximately an 8 cycle bubble
+in the instruction fetch pipeline. The effect on total execution time
+depends on the surrounding code.
+.It Li BACLEAR.BAD_TARGET
+.Pq Event E6H , Umask 02H
+Counts number of Branch Address Calculator clears (BACLEAR) asserted due to
+conditional branch instructions in which there was a target hit but the
+direction was wrong. Each BACLEAR asserted by the BAC generates
+approximately an 8 cycle bubble in the instruction fetch pipeline.
+.It Li BPU_CLEARS.EARLY
+.Pq Event E8H , Umask 01H
+Counts early (normal) Branch Prediction Unit clears: BPU predicted a taken
+branch after incorrectly assuming that it was not taken.
+The BPU clear leads to 2 cycle bubble in the Front End.
+.It Li BPU_CLEARS.LATE
+.Pq Event E8H , Umask 02H
+Counts late Branch Prediction Unit clears due to Most Recently Used
+conflicts. The PBU clear leads to a 3 cycle bubble in the Front End.
+.It Li BPU_CLEARS.ANY
+.Pq Event E8H , Umask 03H
+Counts all BPU clears.
+.It Li L2_TRANSACTIONS.LOAD
+.Pq Event F0H , Umask 01H
+Counts L2 load operations due to HW prefetch or demand loads.
+.It Li L2_TRANSACTIONS.RFO
+.Pq Event F0H , Umask 02H
+Counts L2 RFO operations due to HW prefetch or demand RFOs.
+.It Li L2_TRANSACTIONS.IFETCH
+.Pq Event F0H , Umask 04H
+Counts L2 instruction fetch operations due to HW prefetch or demand ifetch.
+.It Li L2_TRANSACTIONS.PREFETCH
+.Pq Event F0H , Umask 08H
+Counts L2 prefetch operations.
+.It Li L2_TRANSACTIONS.L1D_WB
+.Pq Event F0H , Umask 10H
+Counts L1D writeback operations to the L2.
+.It Li L2_TRANSACTIONS.FILL
+.Pq Event F0H , Umask 20H
+Counts L2 cache line fill operations due to load, RFO, L1D writeback or
+prefetch.
+.It Li L2_TRANSACTIONS.WB
+.Pq Event F0H , Umask 40H
+Counts L2 writeback operations to the L3.
+.It Li L2_TRANSACTIONS.ANY
+.Pq Event F0H , Umask 80H
+Counts all L2 cache operations.
+.It Li L2_LINES_IN.S_STATE
+.Pq Event F1H , Umask 02H
+Counts the number of cache lines allocated in the L2 cache in the S (shared)
+state.
+.It Li L2_LINES_IN.E_STATE
+.Pq Event F1H , Umask 04H
+Counts the number of cache lines allocated in the L2 cache in the E
+(exclusive) state.
+.It Li L2_LINES_IN.ANY
+.Pq Event F1H , Umask 07H
+Counts the number of cache lines allocated in the L2 cache.
+.It Li L2_LINES_OUT.DEMAND_CLEAN
+.Pq Event F2H , Umask 01H
+Counts L2 clean cache lines evicted by a demand request.
+.It Li L2_LINES_OUT.DEMAND_DIRTY
+.Pq Event F2H , Umask 02H
+Counts L2 dirty (modified) cache lines evicted by a demand request.
+.It Li L2_LINES_OUT.PREFETCH_CLEAN
+.Pq Event F2H , Umask 04H
+Counts L2 clean cache line evicted by a prefetch request.
+.It Li L2_LINES_OUT.PREFETCH_DIRTY
+.Pq Event F2H , Umask 08H
+Counts L2 modified cache line evicted by a prefetch request.
+.It Li L2_LINES_OUT.ANY
+.Pq Event F2H , Umask 0FH
+Counts all L2 cache lines evicted for any reason.
+.It Li SQ_MISC.SPLIT_LOCK
+.Pq Event F4H , Umask 10H
+Counts the number of SQ lock splits across a cache line.
+.It Li SQ_FULL_STALL_CYCLES
+.Pq Event F6H , Umask 01H
+Counts cycles the Super Queue is full. Neither of the threads on this core
+will be able to access the uncore.
+.It Li FP_ASSIST.ALL
+.Pq Event F7H , Umask 01H
+Counts the number of floating point operations executed that required
+micro-code assist intervention. Assists are required in the following cases:
+SSE instructions, (Denormal input when the DAZ flag is off or Underflow
+result when the FTZ flag is off): x87 instructions, (NaN or denormal are
+loaded to a register or used as input from memory, Division by 0 or
+Underflow output).
+.It Li FP_ASSIST.OUTPUT
+.Pq Event F7H , Umask 02H
+Counts number of floating point micro-code assist when the output value
+(destination register) is invalid.
+.It Li FP_ASSIST.INPUT
+.Pq Event F7H , Umask 04H
+Counts number of floating point micro-code assist when the input value (one
+of the source operands to an FP instruction) is invalid.
+.It Li SIMD_INT_64.PACKED_MPY
+.Pq Event FDH , Umask 01H
+Counts number of SID integer 64 bit packed multiply operations.
+.It Li SIMD_INT_64.PACKED_SHIFT
+.Pq Event FDH , Umask 02H
+Counts number of SID integer 64 bit packed shift operations.
+.It Li SIMD_INT_64.PACK
+.Pq Event FDH , Umask 04H
+Counts number of SID integer 64 bit pack operations.
+.It Li SIMD_INT_64.UNPACK
+.Pq Event FDH , Umask 08H
+Counts number of SID integer 64 bit unpack operations.
+.It Li SIMD_INT_64.PACKED_LOGICAL
+.Pq Event FDH , Umask 10H
+Counts number of SID integer 64 bit logical operations.
+.It Li SIMD_INT_64.PACKED_ARITH
+.Pq Event FDH , Umask 20H
+Counts number of SID integer 64 bit arithmetic operations.
+.It Li SIMD_INT_64.SHUFFLE_MOVE
+.Pq Event FDH , Umask 40H
+Counts number of SID integer 64 bit shift or move operations.
+.El
+.Ss Event Specifiers (Programmable PMCs)
+Core i7 and Xeon 5500 programmable PMCs support the following events as
+June 2009 document (removed in December 2009):
+.Bl -tag -width indent
+.It Li SB_FORWARD.ANY
+.Pq Event 02H , Umask 01H
+Counts the number of store forwards.
+.It Li LOAD_BLOCK.STD
+.Pq Event 03H , Umask 01H
+Counts the number of loads blocked by a preceding store with unknown data.
+.It Li LOAD_BLOCK.ADDRESS_OFFSET
+.Pq Event 03H , Umask 04H
+Counts the number of loads blocked by a preceding store address.
+.It Li LOAD_BLOCK.ADDRESS_OFFSET
+.Pq Event 01H , Umask 04H
+Counts the cycles of store buffer drains.
+.It Li MISALIGN_MEM_REF.LOAD
+.Pq Event 05H , Umask 01H
+Counts the number of misaligned load references
+.It Li MISALIGN_MEM_REF.STORE
+.Pq Event 05H , Umask 02H
+Counts the number of misaligned store references
+.It Li MISALIGN_MEM_REF.ANY
+.Pq Event 05H , Umask 03H
+Counts the number of misaligned memory references
+.It Li STORE_BLOCKS.NOT_STA
+.Pq Event 06H , Umask 01H
+This event counts the number of load operations delayed caused by preceding
+stores whose addresses are known but whose data is unknown, and preceding
+stores that conflict with the load but which incompletely overlap the load.
+.It Li STORE_BLOCKS.STA
+.Pq Event 06H , Umask 02H
+This event counts load operations delayed caused by preceding stores whose
+addresses are unknown (STA block).
+.It Li STORE_BLOCKS.ANY
+.Pq Event 06H , Umask 0FH
+All loads delayed due to store blocks
+.It Li MEMORY_DISAMBIGURATION.RESET
+.Pq Event 09H , Umask 01H
+Counts memory disambiguration reset cycles
+.It Li MEMORY_DISAMBIGURATION.SUCCESS
+.Pq Event 09H , Umask 02H
+Counts the number of loads that memory disambiguration succeeded
+.It Li MEMORY_DISAMBIGURATION.WATCHDOG
+.Pq Event 09H , Umask 04H
+Counts the number of times the memory disambiguration watchdog kicked in.
+.It Li MEMORY_DISAMBIGURATION.WATCH_CYCLES
+.Pq Event 09H , Umask 08H
+Counts the cycles that the memory disambiguration watchdog is active.
+set invert=1, cmask = 1
+.It Li HW_INT.RCV
+.Pq Event 1DH , Umask 01H
+Number of interrupt received
+.It Li HW_INT.CYCLES_MASKED
+.Pq Event 1DH , Umask 02H
+Number of cycles interrupt are masked
+.It Li HW_INT.CYCLES_PENDING_AND_MASKED
+.Pq Event 1DH , Umask 04H
+Number of cycles interrupts are pending and masked
+.It Li HW_INT.CYCLES_PENDING_AND_MASKED
+.Pq Event 04H , Umask 04H
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in the E (exclusive) state. The L1D prefetcher does not issue a RFO
+prefetch.
+This is a demand RFO request
+.It Li HW_INT.CYCLES_PENDING_AND_MASKED
+.Pq Event 27H , Umask 04H
+LONGEST_LAT_CACH E.MISS
+.It Li UOPS_DECODED.DEC0
+.Pq Event 3DH , Umask 01H
+Counts micro-ops decoded by decoder 0.
+.It Li UOPS_DECODED.DEC0
+.Pq Event 01H , Umask 01H
+Counts L1 data cache store RFO requests where the cache line to be loaded is
+in the I state.
+Counter 0, 1 only
+.It Li 0FH
+.Pq Event 41H , Umask 41H
+L1D_CACHE_ST.MESI
+Counts L1 data cache store RFO requests.
+Counter 0, 1 only
+.It Li DTLB_MISSES.PDE_MISS
+.Pq Event 49H , Umask 20H
+Number of DTLB cache misses where the low part of the linear to physical
+address translation was missed.
+.It Li DTLB_MISSES.PDP_MISS
+.Pq Event 49H , Umask 40H
+Number of DTLB misses where the high part of the linear to physical address
+translation was missed.
+.It Li DTLB_MISSES.LARGE_WALK_COMPLETED
+.Pq Event 49H , Umask 80H
+Counts number of completed large page walks due to misses in the STLB.
+.It Li SSE_MEM_EXEC.NTA
+.Pq Event 4BH , Umask 01H
+Counts number of SSE NTA prefetch/weakly-ordered instructions which missed
+the L1 data cache.
+.It Li SSE_MEM_EXEC.STREAMING_STORES
+.Pq Event 4BH , Umask 08H
+Counts number of SSE non temporal stores
+.It Li SFENCE_CYCLES
+.Pq Event 4DH , Umask 01H
+Counts store fence cycles
+.It Li EPT.EPDE_MISS
+.Pq Event 4FH , Umask 02H
+Counts Extended Page Directory Entry misses. The Extended Page Directory
+cache is used by Virtual Machine operating systems while the guest operating
+systems use the standard TLB caches.
+.It Li EPT.EPDPE_HIT
+.Pq Event 4FH , Umask 04H
+Counts Extended Page Directory Pointer Entry hits.
+.It Li EPT.EPDPE_MISS
+.Pq Event 4FH , Umask 08H
+Counts Extended Page Directory Pointer Entry misses. T
+.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA
+.Pq Event 60H , Umask 01H
+Counts weighted cycles of offcore demand data read requests. Does not
+include L2 prefetch requests.
+counter 0
+.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE
+.Pq Event 60H , Umask 02H
+Counts weighted cycles of offcore demand code read requests. Does not
+include L2 prefetch requests.
+counter 0
+.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO
+.Pq Event 60H , Umask 04H
+Counts weighted cycles of offcore demand RFO requests. Does not include L2
+prefetch requests.
+counter 0
+.It Li OFFCORE_REQUESTS_OUTSTANDING.ANY.READ
+.Pq Event 60H , Umask 08H
+Counts weighted cycles of offcore read requests of any kind. Include L2
+prefetch requests.
+counter 0
+.It Li IFU_IVC.FULL
+.Pq Event 81H , Umask 01H
+Instruction Fetche unit victim cache full.
+.It Li IFU_IVC.L1I_EVICTION
+.Pq Event 81H , Umask 02H
+L1 Instruction cache evictions.
+.It Li L1I_OPPORTUNISTIC_HITS
+.Pq Event 83H , Umask 01H
+Opportunistic hits in streaming.
+.It Li ITLB_MISSES.WALK_CYCLES
+.Pq Event 85H , Umask 04H
+Counts ITLB miss page walk cycles.
+.It Li ITLB_MISSES.PMH_BUSY_CYCLES
+.Pq Event 85H , Umask 04H
+Counts PMH busy cycles.
+.It Li ITLB_MISSES.STLB_HIT
+.Pq Event 85H , Umask 10H
+Counts the number of ITLB misses that hit in the second level TLB.
+.It Li ITLB_MISSES.PDE_MISS
+.Pq Event 85H , Umask 20H
+Number of ITLB misses where the low part of the linear to physical address
+translation was missed.
+.It Li ITLB_MISSES.PDP_MISS
+.Pq Event 85H , Umask 40H
+Number of ITLB misses where the high part of the linear to physical address
+translation was missed.
+.It Li ITLB_MISSES.LARGE_WALK_COMPLETED
+.Pq Event 85H , Umask 80H
+Counts number of completed large page walks due to misses in the STLB.
+.It Li ITLB_MISSES.LARGE_WALK_COMPLETED
+.Pq Event 01H , Umask 80H
+Counts number of offcore demand data read requests. Does not count L2
+prefetch requests.
+.It Li OFFCORE_REQUESTS.DEMAND.READ_CODE
+.Pq Event B0H , Umask 02H
+Counts number of offcore demand code read requests. Does not count L2
+prefetch requests.
+.It Li OFFCORE_REQUESTS.DEMAND.RFO
+.Pq Event B0H , Umask 04H
+Counts number of offcore demand RFO requests. Does not count L2 prefetch
+requests.
+.It Li OFFCORE_REQUESTS.ANY.READ
+.Pq Event B0H , Umask 08H
+Counts number of offcore read requests. Includes L2 prefetch requests.
+.It Li OFFCORE_REQUESTS.ANY.RFO
+.Pq Event B0H , Umask 10H
+Counts number of offcore RFO requests. Includes L2 prefetch requests.
+.It Li OFFCORE_REQUESTS.UNCACHED_MEM
+.Pq Event B0H , Umask 20H
+Counts number of offcore uncached memory requests.
+.It Li OFFCORE_REQUESTS.ANY
+.Pq Event B0H , Umask 80H
+Counts all offcore requests.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.DATA
+.Pq Event B3H , Umask 01H
+Counts weighted cycles of snoopq requests for data. Counter 0 only
+Use cmask=1 to count cycles not empty.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE
+.Pq Event B3H , Umask 02H
+Counts weighted cycles of snoopq invalidate requests. Counter 0 only
+Use cmask=1 to count cycles not empty.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.CODE
+.Pq Event B3H , Umask 04H
+Counts weighted cycles of snoopq requests for code. Counter 0 only
+Use cmask=1 to count cycles not empty.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.CODE
+.Pq Event BAH , Umask 04H
+Counts number of TPR reads
+.It Li PIC_ACCESSES.TPR_WRITES
+.Pq Event BAH , Umask 02H
+Counts number of TPR writes
+one or two micro-ops. Some instructions are decoded into longer sequences
+.It Li MACHINE_CLEARS.FUSION_ASSIST
+.Pq Event C3H , Umask 10H
+Counts the number of macro-fusion assists
+Counts SIMD packed single- precision floating point Uops retired.
+.It Li BOGUS_BR
+.Pq Event E4H , Umask 01H
+Counts the number of bogus branches.
+.It Li L2_HW_PREFETCH.HIT
+.Pq Event F3H , Umask 01H
+Count L2 HW prefetcher detector hits
+.It Li L2_HW_PREFETCH.ALLOC
+.Pq Event F3H , Umask 02H
+Count L2 HW prefetcher allocations
+.It Li L2_HW_PREFETCH.DATA_TRIGGER
+.Pq Event F3H , Umask 04H
+Count L2 HW data prefetcher triggered
+.It Li L2_HW_PREFETCH.CODE_TRIGGER
+.Pq Event F3H , Umask 08H
+Count L2 HW code prefetcher triggered
+.It Li L2_HW_PREFETCH.DCA_TRIGGER
+.Pq Event F3H , Umask 10H
+Count L2 HW DCA prefetcher triggered
+.It Li L2_HW_PREFETCH.KICK_START
+.Pq Event F3H , Umask 20H
+Count L2 HW prefetcher kick started
+.It Li SQ_MISC.PROMOTION
+.Pq Event F4H , Umask 01H
+Counts the number of L2 secondary misses that hit the Super Queue.
+.It Li SQ_MISC.PROMOTION_POST_GO
+.Pq Event F4H , Umask 02H
+Counts the number of L2 secondary misses during the Super Queue filling L2.
+.It Li SQ_MISC.LRU_HINTS
+.Pq Event F4H , Umask 04H
+Counts number of Super Queue LRU hints sent to L3.
+.It Li SQ_MISC.FILL_DROPPED
+.Pq Event F4H , Umask 08H
+Counts the number of SQ L2 fills dropped due to L2 busy.
+.It Li SEGMENT_REG_LOADS
+.Pq Event F8H , Umask 01H
+Counts number of segment register loads.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmere 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
diff --git a/lib/libpmc/pmc.corei7uc.3 b/lib/libpmc/pmc.corei7uc.3
new file mode 100644
index 0000000..fc3435b
--- /dev/null
+++ b/lib/libpmc/pmc.corei7uc.3
@@ -0,0 +1,880 @@
+.\" Copyright (c) 2010 Fabien Thomas. 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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
+.Dt PMC.COREI7UC 3
+.Os
+.Sh NAME
+.Nm pmc.corei7uc
+.Nd uncore measurement events for
+.Tn Intel
+.Tn Core i7 and Xeon 5500
+family CPUs
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+.Tn Intel
+.Tn "Core i7"
+CPUs contain PMCs conforming to version 2 of the
+.Tn Intel
+performance measurement architecture.
+These CPUs contain 2 classes of PMCs:
+.Bl -tag -width "Li PMC_CLASS_UCP"
+.It Li PMC_CLASS_UCF
+Fixed-function counters that count only one hardware event per counter.
+.It Li PMC_CLASS_UCP
+Programmable counters that may be configured to count one of a defined
+set of hardware events.
+.El
+.Pp
+The number of PMCs available in each class and their widths need to be
+determined at run time by calling
+.Xr pmc_cpuinfo 3 .
+.Pp
+Intel Core i7 and Xeon 5500 PMCs are documented in
+.Rs
+.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
+.%T "Volume 3B: System Programming Guide, Part 2"
+.%N "Order Number: 253669-033US"
+.%D December 2009
+.%Q "Intel Corporation"
+.Re
+.Ss COREI7 AND XEON 5500 UNCORE FIXED FUNCTION PMCS
+These PMCs and their supported events are documented in
+.Xr pmc.ucf 3 .
+.Ss COREI7 AND XEON 5500 UNCORE PROGRAMMABLE PMCS
+The programmable PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta Yes
+.It PMC_CAP_INTERRUPT Ta \&No
+.It PMC_CAP_INVERT Ta Yes
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta \&No
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta Yes
+.It PMC_CAP_USER Ta \&No
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+Event specifiers for these PMCs support the following common
+qualifiers:
+.Bl -tag -width indent
+.It Li cmask= Ns Ar value
+Configure the PMC to increment only if the number of configured
+events measured in a cycle is greater than or equal to
+.Ar value .
+.It Li edge
+Configure the PMC to count the number of de-asserted to asserted
+transitions of the conditions expressed by the other qualifiers.
+If specified, the counter will increment only once whenever a
+condition becomes true, irrespective of the number of clocks during
+which the condition remains true.
+.It Li inv
+Invert the sense of comparison when the
+.Dq Li cmask
+qualifier is present, making the counter increment when the number of
+events per cycle is less than the value specified by the
+.Dq Li cmask
+qualifier.
+.El
+.Ss Event Specifiers (Programmable PMCs)
+Core i7 and Xeon 5500 uncore programmable PMCs support the following events:
+.Bl -tag -width indent
+.It Li GQ_CYCLES_FULL.READ_TRACKER
+.Pq Event 00H , Umask 01H
+Uncore cycles Global Queue read tracker is full.
+.It Li GQ_CYCLES_FULL.WRITE_TRACKER
+.Pq Event 00H , Umask 02H
+Uncore cycles Global Queue write tracker is full.
+.It Li GQ_CYCLES_FULL.PEER_PROBE_TRACKER
+.Pq Event 00H , Umask 04H
+Uncore cycles Global Queue peer probe tracker is full. The peer probe
+tracker queue tracks snoops from the IOH and remote sockets.
+.It Li GQ_CYCLES_NOT_EMPTY.READ_TRACKER
+.Pq Event 01H , Umask 01H
+Uncore cycles were Global Queue read tracker has at least one valid entry.
+.It Li GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER
+.Pq Event 01H , Umask 02H
+Uncore cycles were Global Queue write tracker has at least one valid entry.
+.It Li GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER
+.Pq Event 01H , Umask 04H
+Uncore cycles were Global Queue peer probe tracker has at least one valid
+entry. The peer probe tracker queue tracks IOH and remote socket snoops.
+.It Li GQ_ALLOC.READ_TRACKER
+.Pq Event 03H , Umask 01H
+Counts the number of tread tracker allocate to deallocate entries. The GQ
+read tracker allocate to deallocate occupancy count is divided by the count
+to obtain the average read tracker latency.
+.It Li GQ_ALLOC.RT_L3_MISS
+.Pq Event 03H , Umask 02H
+Counts the number GQ read tracker entries for which a full cache line read
+has missed the L3. The GQ read tracker L3 miss to fill occupancy count is
+divided by this count to obtain the average cache line read L3 miss latency.
+The latency represents the time after which the L3 has determined that the
+cache line has missed. The time between a GQ read tracker allocation and the
+L3 determining that the cache line has missed is the average L3 hit latency.
+The total L3 cache line read miss latency is the hit latency + L3 miss
+latency.
+.It Li GQ_ALLOC.RT_TO_L3_RESP
+.Pq Event 03H , Umask 04H
+Counts the number of GQ read tracker entries that are allocated in the read
+tracker queue that hit or miss the L3. The GQ read tracker L3 hit occupancy
+count is divided by this count to obtain the average L3 hit latency.
+.It Li GQ_ALLOC.RT_TO_RTID_ACQUIRED
+.Pq Event 03H , Umask 08H
+Counts the number of GQ read tracker entries that are allocated in the read
+tracker, have missed in the L3 and have not acquired a Request Transaction
+ID. The GQ read tracker L3 miss to RTID acquired occupancy count is
+divided by this count to obtain the average latency for a read L3 miss to
+acquire an RTID.
+.It Li GQ_ALLOC.WT_TO_RTID_ACQUIRED
+.Pq Event 03H , Umask 10H
+Counts the number of GQ write tracker entries that are allocated in the
+write tracker, have missed in the L3 and have not acquired a Request
+Transaction ID. The GQ write tracker L3 miss to RTID occupancy count is
+divided by this count to obtain the average latency for a write L3 miss to
+acquire an RTID.
+.It Li GQ_ALLOC.WRITE_TRACKER
+.Pq Event 03H , Umask 20H
+Counts the number of GQ write tracker entries that are allocated in the
+write tracker queue that miss the L3. The GQ write tracker occupancy count
+is divided by the this count to obtain the average L3 write miss latency.
+.It Li GQ_ALLOC.PEER_PROBE_TRACKER
+.Pq Event 03H , Umask 40H
+Counts the number of GQ peer probe tracker (snoop) entries that are
+allocated in the peer probe tracker queue that miss the L3. The GQ peer
+probe occupancy count is divided by this count to obtain the average L3 peer
+probe miss latency.
+.It Li GQ_DATA.FROM_QPI
+.Pq Event 04H , Umask 01H
+Cycles Global Queue Quickpath Interface input data port is busy importing
+data from the Quickpath Interface. Each cycle the input port can transfer 8
+or 16 bytes of data.
+.It Li GQ_DATA.FROM_QMC
+.Pq Event 04H , Umask 02H
+Cycles Global Queue Quickpath Memory Interface input data port is busy
+importing data from the Quickpath Memory Interface. Each cycle the input
+port can transfer 8 or 16 bytes of data.
+.It Li GQ_DATA.FROM_L3
+.Pq Event 04H , Umask 04H
+Cycles GQ L3 input data port is busy importing data from the Last Level
+Cache. Each cycle the input port can transfer 32 bytes of data.
+.It Li GQ_DATA.FROM_CORES_02
+.Pq Event 04H , Umask 08H
+Cycles GQ Core 0 and 2 input data port is busy importing data from processor
+cores 0 and 2. Each cycle the input port can transfer 32 bytes of data.
+.It Li GQ_DATA.FROM_CORES_13
+.Pq Event 04H , Umask 10H
+Cycles GQ Core 1 and 3 input data port is busy importing data from processor
+cores 1 and 3. Each cycle the input port can transfer 32 bytes of data.
+.It Li GQ_DATA.TO_QPI_QMC
+.Pq Event 05H , Umask 01H
+Cycles GQ QPI and QMC output data port is busy sending data to the Quickpath
+Interface or Quickpath Memory Interface. Each cycle the output port can
+transfer 32 bytes of data.
+.It Li GQ_DATA.TO_L3
+.Pq Event 05H , Umask 02H
+Cycles GQ L3 output data port is busy sending data to the Last Level Cache.
+Each cycle the output port can transfer 32 bytes of data.
+.It Li GQ_DATA.TO_CORES
+.Pq Event 05H , Umask 04H
+Cycles GQ Core output data port is busy sending data to the Cores. Each
+cycle the output port can transfer 32 bytes of data.
+.It Li SNP_RESP_TO_LOCAL_HOME.I_STATE
+.Pq Event 06H , Umask 01H
+Number of snoop responses to the local home that L3 does not have the
+referenced cache line.
+.It Li SNP_RESP_TO_LOCAL_HOME.S_STATE
+.Pq Event 06H , Umask 02H
+Number of snoop responses to the local home that L3 has the referenced line
+cached in the S state.
+.It Li SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE
+.Pq Event 06H , Umask 04H
+Number of responses to code or data read snoops to the local home that the
+L3 has the referenced cache line in the E state. The L3 cache line state is
+changed to the S state and the line is forwarded to the local home in the S
+state.
+.It Li SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE
+.Pq Event 06H , Umask 08H
+Number of responses to read invalidate snoops to the local home that the L3
+has the referenced cache line in the M state. The L3 cache line state is
+invalidated and the line is forwarded to the local home in the M state.
+.It Li SNP_RESP_TO_LOCAL_HOME.CONFLICT
+.Pq Event 06H , Umask 10H
+Number of conflict snoop responses sent to the local home.
+.It Li SNP_RESP_TO_LOCAL_HOME.WB
+.Pq Event 06H , Umask 20H
+Number of responses to code or data read snoops to the local home that the
+L3 has the referenced line cached in the M state.
+.It Li SNP_RESP_TO_REMOTE_HOME.I_STATE
+.Pq Event 07H , Umask 01H
+Number of snoop responses to a remote home that L3 does not have the
+referenced cache line.
+.It Li SNP_RESP_TO_REMOTE_HOME.S_STATE
+.Pq Event 07H , Umask 02H
+Number of snoop responses to a remote home that L3 has the referenced line
+cached in the S state.
+.It Li SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE
+.Pq Event 07H , Umask 04H
+Number of responses to code or data read snoops to a remote home that the L3
+has the referenced cache line in the E state. The L3 cache line state is
+changed to the S state and the line is forwarded to the remote home in the S
+state.
+.It Li SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE
+.Pq Event 07H , Umask 08H
+Number of responses to read invalidate snoops to a remote home that the L3
+has the referenced cache line in the M state. The L3 cache line state is
+invalidated and the line is forwarded to the remote home in the M state.
+.It Li SNP_RESP_TO_REMOTE_HOME.CONFLICT
+.Pq Event 07H , Umask 10H
+Number of conflict snoop responses sent to the local home.
+.It Li SNP_RESP_TO_REMOTE_HOME.WB
+.Pq Event 07H , Umask 20H
+Number of responses to code or data read snoops to a remote home that the L3
+has the referenced line cached in the M state.
+.It Li SNP_RESP_TO_REMOTE_HOME.HITM
+.Pq Event 07H , Umask 24H
+Number of HITM snoop responses to a remote home
+.It Li L3_HITS.READ
+.Pq Event 08H , Umask 01H
+Number of code read, data read and RFO requests that hit in the L3
+.It Li L3_HITS.WRITE
+.Pq Event 08H , Umask 02H
+Number of writeback requests that hit in the L3. Writebacks from the cores
+will always result in L3 hits due to the inclusive property of the L3.
+.It Li L3_HITS.PROBE
+.Pq Event 08H , Umask 04H
+Number of snoops from IOH or remote sockets that hit in the L3.
+.It Li L3_HITS.ANY
+.Pq Event 08H , Umask 03H
+Number of reads and writes that hit the L3.
+.It Li L3_MISS.READ
+.Pq Event 09H , Umask 01H
+Number of code read, data read and RFO requests that miss the L3.
+.It Li L3_MISS.WRITE
+.Pq Event 09H , Umask 02H
+Number of writeback requests that miss the L3. Should always be zero as
+writebacks from the cores will always result in L3 hits due to the inclusive
+property of the L3.
+.It Li L3_MISS.PROBE
+.Pq Event 09H , Umask 04H
+Number of snoops from IOH or remote sockets that miss the L3.
+.It Li L3_MISS.ANY
+.Pq Event 09H , Umask 03H
+Number of reads and writes that miss the L3.
+.It Li L3_LINES_IN.M_STATE
+.Pq Event 0AH , Umask 01H
+Counts the number of L3 lines allocated in M state. The only time a cache
+line is allocated in the M state is when the line was forwarded in M state
+is forwarded due to a Snoop Read Invalidate Own request.
+.It Li L3_LINES_IN.E_STATE
+.Pq Event 0AH , Umask 02H
+Counts the number of L3 lines allocated in E state.
+.It Li L3_LINES_IN.S_STATE
+.Pq Event 0AH , Umask 04H
+Counts the number of L3 lines allocated in S state.
+.It Li L3_LINES_IN.F_STATE
+.Pq Event 0AH , Umask 08H
+Counts the number of L3 lines allocated in F state.
+.It Li L3_LINES_IN.ANY
+.Pq Event 0AH , Umask 0FH
+Counts the number of L3 lines allocated in any state.
+.It Li L3_LINES_OUT.M_STATE
+.Pq Event 0BH , Umask 01H
+Counts the number of L3 lines victimized that were in the M state. When the
+victim cache line is in M state, the line is written to its home cache agent
+which can be either local or remote.
+.It Li L3_LINES_OUT.E_STATE
+.Pq Event 0BH , Umask 02H
+Counts the number of L3 lines victimized that were in the E state.
+.It Li L3_LINES_OUT.S_STATE
+.Pq Event 0BH , Umask 04H
+Counts the number of L3 lines victimized that were in the S state.
+.It Li L3_LINES_OUT.I_STATE
+.Pq Event 0BH , Umask 08H
+Counts the number of L3 lines victimized that were in the I state.
+.It Li L3_LINES_OUT.F_STATE
+.Pq Event 0BH , Umask 10H
+Counts the number of L3 lines victimized that were in the F state.
+.It Li L3_LINES_OUT.ANY
+.Pq Event 0BH , Umask 1FH
+Counts the number of L3 lines victimized in any state.
+.It Li QHL_REQUESTS.IOH_READS
+.Pq Event 20H , Umask 01H
+Counts number of Quickpath Home Logic read requests from the IOH.
+.It Li QHL_REQUESTS.IOH_WRITES
+.Pq Event 20H , Umask 02H
+Counts number of Quickpath Home Logic write requests from the IOH.
+.It Li QHL_REQUESTS.REMOTE_READS
+.Pq Event 20H , Umask 04H
+Counts number of Quickpath Home Logic read requests from a remote socket.
+.It Li QHL_REQUESTS.REMOTE_WRITES
+.Pq Event 20H , Umask 08H
+Counts number of Quickpath Home Logic write requests from a remote socket.
+.It Li QHL_REQUESTS.LOCAL_READS
+.Pq Event 20H , Umask 10H
+Counts number of Quickpath Home Logic read requests from the local socket.
+.It Li QHL_REQUESTS.LOCAL_WRITES
+.Pq Event 20H , Umask 20H
+Counts number of Quickpath Home Logic write requests from the local socket.
+.It Li QHL_CYCLES_FULL.IOH
+.Pq Event 21H , Umask 01H
+Counts uclk cycles all entries in the Quickpath Home Logic IOH are full.
+.It Li QHL_CYCLES_FULL.REMOTE
+.Pq Event 21H , Umask 02H
+Counts uclk cycles all entries in the Quickpath Home Logic remote tracker
+are full.
+.It Li QHL_CYCLES_FULL.LOCAL
+.Pq Event 21H , Umask 04H
+Counts uclk cycles all entries in the Quickpath Home Logic local tracker are
+full.
+.It Li QHL_CYCLES_NOT_EMPTY.IOH
+.Pq Event 22H , Umask 01H
+Counts uclk cycles all entries in the Quickpath Home Logic IOH is busy.
+.It Li QHL_CYCLES_NOT_EMPTY.REMOTE
+.Pq Event 22H , Umask 02H
+Counts uclk cycles all entries in the Quickpath Home Logic remote tracker is
+busy.
+.It Li QHL_CYCLES_NOT_EMPTY.LOCAL
+.Pq Event 22H , Umask 04H
+Counts uclk cycles all entries in the Quickpath Home Logic local tracker is
+busy.
+.It Li QHL_OCCUPANCY.IOH
+.Pq Event 23H , Umask 01H
+QHL IOH tracker allocate to deallocate read occupancy.
+.It Li QHL_OCCUPANCY.REMOTE
+.Pq Event 23H , Umask 02H
+QHL remote tracker allocate to deallocate read occupancy.
+.It Li QHL_OCCUPANCY.LOCAL
+.Pq Event 23H , Umask 04H
+QHL local tracker allocate to deallocate read occupancy.
+.It Li QHL_ADDRESS_CONFLICTS.2WAY
+.Pq Event 24H , Umask 02H
+Counts number of QHL Active Address Table (AAT) entries that saw a max of 2
+conflicts. The AAT is a structure that tracks requests that are in conflict.
+The requests themselves are in the home tracker entries. The count is
+reported when an AAT entry deallocates.
+.It Li QHL_ADDRESS_CONFLICTS.3WAY
+.Pq Event 24H , Umask 04H
+Counts number of QHL Active Address Table (AAT) entries that saw a max of 3
+conflicts. The AAT is a structure that tracks requests that are in conflict.
+The requests themselves are in the home tracker entries. The count is
+reported when an AAT entry deallocates.
+.It Li QHL_CONFLICT_CYCLES.IOH
+.Pq Event 25H , Umask 01H
+Counts cycles the Quickpath Home Logic IOH Tracker contains two or more
+requests with an address conflict. A max of 3 requests can be in conflict.
+.It Li QHL_CONFLICT_CYCLES.REMOTE
+.Pq Event 25H , Umask 02H
+Counts cycles the Quickpath Home Logic Remote Tracker contains two or more
+requests with an address conflict. A max of 3 requests can be in conflict.
+.It Li QHL_CONFLICT_CYCLES.LOCAL
+.Pq Event 25H , Umask 04H
+Counts cycles the Quickpath Home Logic Local Tracker contains two or more
+requests with an address conflict. A max of 3 requests can be in conflict.
+.It Li QHL_TO_QMC_BYPASS
+.Pq Event 26H , Umask 01H
+Counts number or requests to the Quickpath Memory Controller that bypass the
+Quickpath Home Logic. All local accesses can be bypassed. For remote
+requests, only read requests can be bypassed.
+.It Li QMC_NORMAL_FULL.READ.CH0
+.Pq Event 27H , Umask 01H
+Uncore cycles all the entries in the DRAM channel 0 medium or low priority
+queue are occupied with read requests.
+.It Li QMC_NORMAL_FULL.READ.CH1
+.Pq Event 27H , Umask 02H
+Uncore cycles all the entries in the DRAM channel 1 medium or low priority
+queue are occupied with read requests.
+.It Li QMC_NORMAL_FULL.READ.CH2
+.Pq Event 27H , Umask 04H
+Uncore cycles all the entries in the DRAM channel 2 medium or low priority
+queue are occupied with read requests.
+.It Li QMC_NORMAL_FULL.WRITE.CH0
+.Pq Event 27H , Umask 08H
+Uncore cycles all the entries in the DRAM channel 0 medium or low priority
+queue are occupied with write requests.
+.It Li QMC_NORMAL_FULL.WRITE.CH1
+.Pq Event 27H , Umask 10H
+Counts cycles all the entries in the DRAM channel 1 medium or low priority
+queue are occupied with write requests.
+.It Li QMC_NORMAL_FULL.WRITE.CH2
+.Pq Event 27H , Umask 20H
+Uncore cycles all the entries in the DRAM channel 2 medium or low priority
+queue are occupied with write requests.
+.It Li QMC_ISOC_FULL.READ.CH0
+.Pq Event 28H , Umask 01H
+Counts cycles all the entries in the DRAM channel 0 high priority queue are
+occupied with isochronous read requests.
+.It Li QMC_ISOC_FULL.READ.CH1
+.Pq Event 28H , Umask 02H
+Counts cycles all the entries in the DRAM channel 1high priority queue are
+occupied with isochronous read requests.
+.It Li QMC_ISOC_FULL.READ.CH2
+.Pq Event 28H , Umask 04H
+Counts cycles all the entries in the DRAM channel 2 high priority queue are
+occupied with isochronous read requests.
+.It Li QMC_ISOC_FULL.WRITE.CH0
+.Pq Event 28H , Umask 08H
+Counts cycles all the entries in the DRAM channel 0 high priority queue are
+occupied with isochronous write requests.
+.It Li QMC_ISOC_FULL.WRITE.CH1
+.Pq Event 28H , Umask 10H
+Counts cycles all the entries in the DRAM channel 1 high priority queue are
+occupied with isochronous write requests.
+.It Li QMC_ISOC_FULL.WRITE.CH2
+.Pq Event 28H , Umask 20H
+Counts cycles all the entries in the DRAM channel 2 high priority queue are
+occupied with isochronous write requests.
+.It Li QMC_BUSY.READ.CH0
+.Pq Event 29H , Umask 01H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+read request to DRAM channel 0.
+.It Li QMC_BUSY.READ.CH1
+.Pq Event 29H , Umask 02H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+read request to DRAM channel 1.
+.It Li QMC_BUSY.READ.CH2
+.Pq Event 29H , Umask 04H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+read request to DRAM channel 2.
+.It Li QMC_BUSY.WRITE.CH0
+.Pq Event 29H , Umask 08H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+write request to DRAM channel 0.
+.It Li QMC_BUSY.WRITE.CH1
+.Pq Event 29H , Umask 10H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+write request to DRAM channel 1.
+.It Li QMC_BUSY.WRITE.CH2
+.Pq Event 29H , Umask 20H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+write request to DRAM channel 2.
+.It Li QMC_OCCUPANCY.CH0
+.Pq Event 2AH , Umask 01H
+IMC channel 0 normal read request occupancy.
+.It Li QMC_OCCUPANCY.CH1
+.Pq Event 2AH , Umask 02H
+IMC channel 1 normal read request occupancy.
+.It Li QMC_OCCUPANCY.CH2
+.Pq Event 2AH , Umask 04H
+IMC channel 2 normal read request occupancy.
+.It Li QMC_ISSOC_OCCUPANCY.CH0
+.Pq Event 2BH , Umask 01H
+IMC channel 0 issoc read request occupancy.
+.It Li QMC_ISSOC_OCCUPANCY.CH1
+.Pq Event 2BH , Umask 02H
+IMC channel 1 issoc read request occupancy.
+.It Li QMC_ISSOC_OCCUPANCY.CH2
+.Pq Event 2BH , Umask 04H
+IMC channel 2 issoc read request occupancy.
+.It Li QMC_ISSOC_READS.ANY
+.Pq Event 2BH , Umask 07H
+IMC issoc read request occupancy.
+.It Li QMC_NORMAL_READS.CH0
+.Pq Event 2CH , Umask 01H
+Counts the number of Quickpath Memory Controller channel 0 medium and low
+priority read requests. The QMC channel 0 normal read occupancy divided by
+this count provides the average QMC channel 0 read latency.
+.It Li QMC_NORMAL_READS.CH1
+.Pq Event 2CH , Umask 02H
+Counts the number of Quickpath Memory Controller channel 1 medium and low
+priority read requests. The QMC channel 1 normal read occupancy divided by
+this count provides the average QMC channel 1 read latency.
+.It Li QMC_NORMAL_READS.CH2
+.Pq Event 2CH , Umask 04H
+Counts the number of Quickpath Memory Controller channel 2 medium and low
+priority read requests. The QMC channel 2 normal read occupancy divided by
+this count provides the average QMC channel 2 read latency.
+.It Li QMC_NORMAL_READS.ANY
+.Pq Event 2CH , Umask 07H
+Counts the number of Quickpath Memory Controller medium and low priority
+read requests. The QMC normal read occupancy divided by this count provides
+the average QMC read latency.
+.It Li QMC_HIGH_PRIORITY_READS.CH0
+.Pq Event 2DH , Umask 01H
+Counts the number of Quickpath Memory Controller channel 0 high priority
+isochronous read requests.
+.It Li QMC_HIGH_PRIORITY_READS.CH1
+.Pq Event 2DH , Umask 02H
+Counts the number of Quickpath Memory Controller channel 1 high priority
+isochronous read requests.
+.It Li QMC_HIGH_PRIORITY_READS.CH2
+.Pq Event 2DH , Umask 04H
+Counts the number of Quickpath Memory Controller channel 2 high priority
+isochronous read requests.
+.It Li QMC_HIGH_PRIORITY_READS.ANY
+.Pq Event 2DH , Umask 07H
+Counts the number of Quickpath Memory Controller high priority isochronous
+read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.CH0
+.Pq Event 2EH , Umask 01H
+Counts the number of Quickpath Memory Controller channel 0 critical priority
+isochronous read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.CH1
+.Pq Event 2EH , Umask 02H
+Counts the number of Quickpath Memory Controller channel 1 critical priority
+isochronous read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.CH2
+.Pq Event 2EH , Umask 04H
+Counts the number of Quickpath Memory Controller channel 2 critical priority
+isochronous read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.ANY
+.Pq Event 2EH , Umask 07H
+Counts the number of Quickpath Memory Controller critical priority
+isochronous read requests.
+.It Li QMC_WRITES.FULL.CH0
+.Pq Event 2FH , Umask 01H
+Counts number of full cache line writes to DRAM channel 0.
+.It Li QMC_WRITES.FULL.CH1
+.Pq Event 2FH , Umask 02H
+Counts number of full cache line writes to DRAM channel 1.
+.It Li QMC_WRITES.FULL.CH2
+.Pq Event 2FH , Umask 04H
+Counts number of full cache line writes to DRAM channel 2.
+.It Li QMC_WRITES.FULL.ANY
+.Pq Event 2FH , Umask 07H
+Counts number of full cache line writes to DRAM.
+.It Li QMC_WRITES.PARTIAL.CH0
+.Pq Event 2FH , Umask 08H
+Counts number of partial cache line writes to DRAM channel 0.
+.It Li QMC_WRITES.PARTIAL.CH1
+.Pq Event 2FH , Umask 10H
+Counts number of partial cache line writes to DRAM channel 1.
+.It Li QMC_WRITES.PARTIAL.CH2
+.Pq Event 2FH , Umask 20H
+Counts number of partial cache line writes to DRAM channel 2.
+.It Li QMC_WRITES.PARTIAL.ANY
+.Pq Event 2FH , Umask 38H
+Counts number of partial cache line writes to DRAM.
+.It Li QMC_CANCEL.CH0
+.Pq Event 30H , Umask 01H
+Counts number of DRAM channel 0 cancel requests.
+.It Li QMC_CANCEL.CH1
+.Pq Event 30H , Umask 02H
+Counts number of DRAM channel 1 cancel requests.
+.It Li QMC_CANCEL.CH2
+.Pq Event 30H , Umask 04H
+Counts number of DRAM channel 2 cancel requests.
+.It Li QMC_CANCEL.ANY
+.Pq Event 30H , Umask 07H
+Counts number of DRAM cancel requests.
+.It Li QMC_PRIORITY_UPDATES.CH0
+.Pq Event 31H , Umask 01H
+Counts number of DRAM channel 0 priority updates. A priority update occurs
+when an ISOC high or critical request is received by the QHL and there is a
+matching request with normal priority that has already been issued to the
+QMC. In this instance, the QHL will send a priority update to QMC to
+expedite the request.
+.It Li QMC_PRIORITY_UPDATES.CH1
+.Pq Event 31H , Umask 02H
+Counts number of DRAM channel 1 priority updates. A priority update occurs
+when an ISOC high or critical request is received by the QHL and there is a
+matching request with normal priority that has already been issued to the
+QMC. In this instance, the QHL will send a priority update to QMC to
+expedite the request.
+.It Li QMC_PRIORITY_UPDATES.CH2
+.Pq Event 31H , Umask 04H
+Counts number of DRAM channel 2 priority updates. A priority update occurs
+when an ISOC high or critical request is received by the QHL and there is a
+matching request with normal priority that has already been issued to the
+QMC. In this instance, the QHL will send a priority update to QMC to
+expedite the request.
+.It Li QMC_PRIORITY_UPDATES.ANY
+.Pq Event 31H , Umask 07H
+Counts number of DRAM priority updates. A priority update occurs when an
+ISOC high or critical request is received by the QHL and there is a matching
+request with normal priority that has already been issued to the QMC. In
+this instance, the QHL will send a priority update to QMC to expedite the
+request.
+.It Li QHL_FRC_ACK_CNFLTS.LOCAL
+.Pq Event 33H , Umask 04H
+Counts number of Force Acknowledge Conflict messages sent by the Quickpath
+Home Logic to the local home.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0
+.Pq Event 40H , Umask 01H
+Counts cycles the Quickpath outbound link 0 HOME virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0
+.Pq Event 40H , Umask 02H
+Counts cycles the Quickpath outbound link 0 SNOOP virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0
+.Pq Event 40H , Umask 04H
+Counts cycles the Quickpath outbound link 0 non-data response virtual
+channel is stalled due to lack of a VNA and VN0 credit. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1
+.Pq Event 40H , Umask 08H
+Counts cycles the Quickpath outbound link 1 HOME virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1
+.Pq Event 40H , Umask 10H
+Counts cycles the Quickpath outbound link 1 SNOOP virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1
+.Pq Event 40H , Umask 20H
+Counts cycles the Quickpath outbound link 1 non-data response virtual
+channel is stalled due to lack of a VNA and VN0 credit. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_0
+.Pq Event 40H , Umask 07H
+Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
+to lack of a VNA and VN0 credit. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_1
+.Pq Event 40H , Umask 38H
+Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
+to lack of a VNA and VN0 credit. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0
+.Pq Event 41H , Umask 01H
+Counts cycles the Quickpath outbound link 0 Data ResponSe virtual channel is
+stalled due to lack of VNA and VN0 credits. Note that this event does not
+filter out when a flit would not have been selected for arbitration because
+another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0
+.Pq Event 41H , Umask 02H
+Counts cycles the Quickpath outbound link 0 Non-Coherent Bypass virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0
+.Pq Event 41H , Umask 04H
+Counts cycles the Quickpath outbound link 0 Non-Coherent Standard virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1
+.Pq Event 41H , Umask 08H
+Counts cycles the Quickpath outbound link 1 Data ResponSe virtual channel is
+stalled due to lack of VNA and VN0 credits. Note that this event does not
+filter out when a flit would not have been selected for arbitration because
+another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1
+.Pq Event 41H , Umask 10H
+Counts cycles the Quickpath outbound link 1 Non-Coherent Bypass virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1
+.Pq Event 41H , Umask 20H
+Counts cycles the Quickpath outbound link 1 Non-Coherent Standard virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_0
+.Pq Event 41H , Umask 07H
+Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
+to lack of VNA and VN0 credits. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_1
+.Pq Event 41H , Umask 38H
+Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
+to lack of VNA and VN0 credits. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_HEADER.BUSY.LINK_0
+.Pq Event 42H , Umask 02H
+Number of cycles that the header buffer in the Quickpath Interface outbound
+link 0 is busy.
+.It Li QPI_TX_HEADER.BUSY.LINK_1
+.Pq Event 42H , Umask 08H
+Number of cycles that the header buffer in the Quickpath Interface outbound
+link 1 is busy.
+.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0
+.Pq Event 43H , Umask 01H
+Number of cycles that snoop packets incoming to the Quickpath Interface link
+0 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
+does not have any available entries.
+.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1
+.Pq Event 43H , Umask 02H
+Number of cycles that snoop packets incoming to the Quickpath Interface link
+1 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
+does not have any available entries.
+.It Li DRAM_OPEN.CH0
+.Pq Event 60H , Umask 01H
+Counts number of DRAM Channel 0 open commands issued either for read or
+write. To read or write data, the referenced DRAM page must first be opened.
+.It Li DRAM_OPEN.CH1
+.Pq Event 60H , Umask 02H
+Counts number of DRAM Channel 1 open commands issued either for read or
+write. To read or write data, the referenced DRAM page must first be opened.
+.It Li DRAM_OPEN.CH2
+.Pq Event 60H , Umask 04H
+Counts number of DRAM Channel 2 open commands issued either for read or
+write. To read or write data, the referenced DRAM page must first be opened.
+.It Li DRAM_PAGE_CLOSE.CH0
+.Pq Event 61H , Umask 01H
+DRAM channel 0 command issued to CLOSE a page due to page idle timer
+expiration. Closing a page is done by issuing a precharge.
+.It Li DRAM_PAGE_CLOSE.CH1
+.Pq Event 61H , Umask 02H
+DRAM channel 1 command issued to CLOSE a page due to page idle timer
+expiration. Closing a page is done by issuing a precharge.
+.It Li DRAM_PAGE_CLOSE.CH2
+.Pq Event 61H , Umask 04H
+DRAM channel 2 command issued to CLOSE a page due to page idle timer
+expiration. Closing a page is done by issuing a precharge.
+.It Li DRAM_PAGE_MISS.CH0
+.Pq Event 62H , Umask 01H
+Counts the number of precharges (PRE) that were issued to DRAM channel 0
+because there was a page miss. A page miss refers to a situation in which a
+page is currently open and another page from the same bank needs to be
+opened. The new page experiences a page miss. Closing of the old page is
+done by issuing a precharge.
+.It Li DRAM_PAGE_MISS.CH1
+.Pq Event 62H , Umask 02H
+Counts the number of precharges (PRE) that were issued to DRAM channel 1
+because there was a page miss. A page miss refers to a situation in which a
+page is currently open and another page from the same bank needs to be
+opened. The new page experiences a page miss. Closing of the old page is
+done by issuing a precharge.
+.It Li DRAM_PAGE_MISS.CH2
+.Pq Event 62H , Umask 04H
+Counts the number of precharges (PRE) that were issued to DRAM channel 2
+because there was a page miss. A page miss refers to a situation in which a
+page is currently open and another page from the same bank needs to be
+opened. The new page experiences a page miss. Closing of the old page is
+done by issuing a precharge.
+.It Li DRAM_READ_CAS.CH0
+.Pq Event 63H , Umask 01H
+Counts the number of times a read CAS command was issued on DRAM channel 0.
+.It Li DRAM_READ_CAS.AUTOPRE_CH0
+.Pq Event 63H , Umask 02H
+Counts the number of times a read CAS command was issued on DRAM channel 0
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_READ_CAS.CH1
+.Pq Event 63H , Umask 04H
+Counts the number of times a read CAS command was issued on DRAM channel 1.
+.It Li DRAM_READ_CAS.AUTOPRE_CH1
+.Pq Event 63H , Umask 08H
+Counts the number of times a read CAS command was issued on DRAM channel 1
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_READ_CAS.CH2
+.Pq Event 63H , Umask 10H
+Counts the number of times a read CAS command was issued on DRAM channel 2.
+.It Li DRAM_READ_CAS.AUTOPRE_CH2
+.Pq Event 63H , Umask 20H
+Counts the number of times a read CAS command was issued on DRAM channel 2
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_WRITE_CAS.CH0
+.Pq Event 64H , Umask 01H
+Counts the number of times a write CAS command was issued on DRAM channel 0.
+.It Li DRAM_WRITE_CAS.AUTOPRE_CH0
+.Pq Event 64H , Umask 02H
+Counts the number of times a write CAS command was issued on DRAM channel 0
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_WRITE_CAS.CH1
+.Pq Event 64H , Umask 04H
+Counts the number of times a write CAS command was issued on DRAM channel 1.
+.It Li DRAM_WRITE_CAS.AUTOPRE_CH1
+.Pq Event 64H , Umask 08H
+Counts the number of times a write CAS command was issued on DRAM channel 1
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_WRITE_CAS.CH2
+.Pq Event 64H , Umask 10H
+Counts the number of times a write CAS command was issued on DRAM channel 2.
+.It Li DRAM_WRITE_CAS.AUTOPRE_CH2
+.Pq Event 64H , Umask 20H
+Counts the number of times a write CAS command was issued on DRAM channel 2
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_REFRESH.CH0
+.Pq Event 65H , Umask 01H
+Counts number of DRAM channel 0 refresh commands. DRAM loses data content
+over time. In order to keep correct data content, the data values have to be
+refreshed periodically.
+.It Li DRAM_REFRESH.CH1
+.Pq Event 65H , Umask 02H
+Counts number of DRAM channel 1 refresh commands. DRAM loses data content
+over time. In order to keep correct data content, the data values have to be
+refreshed periodically.
+.It Li DRAM_REFRESH.CH2
+.Pq Event 65H , Umask 04H
+Counts number of DRAM channel 2 refresh commands. DRAM loses data content
+over time. In order to keep correct data content, the data values have to be
+refreshed periodically.
+.It Li DRAM_PRE_ALL.CH0
+.Pq Event 66H , Umask 01H
+Counts number of DRAM Channel 0 precharge-all (PREALL) commands that close
+all open pages in a rank. PREALL is issued when the DRAM needs to be
+refreshed or needs to go into a power down mode.
+.It Li DRAM_PRE_ALL.CH1
+.Pq Event 66H , Umask 02H
+Counts number of DRAM Channel 1 precharge-all (PREALL) commands that close
+all open pages in a rank. PREALL is issued when the DRAM needs to be
+refreshed or needs to go into a power down mode.
+.It Li DRAM_PRE_ALL.CH2
+.Pq Event 66H , Umask 04H
+Counts number of DRAM Channel 2 precharge-all (PREALL) commands that close
+all open pages in a rank. PREALL is issued when the DRAM needs to be
+refreshed or needs to go into a power down mode.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.westmere 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
diff --git a/lib/libpmc/pmc.iaf.3 b/lib/libpmc/pmc.iaf.3
index c6d01ea..ec9f21c 100644
--- a/lib/libpmc/pmc.iaf.3
+++ b/lib/libpmc/pmc.iaf.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 14, 2008
-.Os
.Dt PMC.IAF 3
+.Os
.Sh NAME
.Nm pmc.iaf
.Nd measurement events for
diff --git a/lib/libpmc/pmc.k7.3 b/lib/libpmc/pmc.k7.3
index 8db9020..2775d4f 100644
--- a/lib/libpmc/pmc.k7.3
+++ b/lib/libpmc/pmc.k7.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 4, 2008
-.Os
.Dt PMC.K7 3
+.Os
.Sh NAME
.Nm pmc.k7
.Nd measurement events for
diff --git a/lib/libpmc/pmc.k8.3 b/lib/libpmc/pmc.k8.3
index 3e4afb1..995bfac 100644
--- a/lib/libpmc/pmc.k8.3
+++ b/lib/libpmc/pmc.k8.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 4, 2008
-.Os
.Dt PMC.K8 3
+.Os
.Sh NAME
.Nm pmc.k8
.Nd measurement events for
diff --git a/lib/libpmc/pmc.mips.3 b/lib/libpmc/pmc.mips.3
new file mode 100644
index 0000000..f9ec1d0
--- /dev/null
+++ b/lib/libpmc/pmc.mips.3
@@ -0,0 +1,410 @@
+.\" Copyright (c) 2010 George Neville-Neil. 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 ``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 George Neville-Neil 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 February 11, 2010
+.Os
+.Dt PMC.MIPS 3
+.Sh NAME
+.Nm pmc.mips
+.Nd measurement events for
+.Tn MIPS
+family CPUs
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+MIPS PMCs are present in MIPS
+.Tn "24k"
+and other processors in the MIPS family.
+.Pp
+There are two counters supported by the hardware and each is 32 bits
+wide.
+.Pp
+MIPS PMCs are documented in
+.Rs
+.%B "MIPS32 24K Processor Core Family Software User's Manual"
+.%D December 2008
+.%Q "MIPS Technologies Inc."
+.Re
+.Ss Event Specifiers (Programmable PMCs)
+MIPS programmable PMCs support the following events:
+.Bl -tag -width indent
+.It Li CYCLE
+.Pq Event 0, Counter 0/1
+Total number of cycles.
+The performance counters are clocked by the
+top-level gated clock.
+If the core is built with that clock gater
+present, none of the counters will increment while the clock is
+stopped - due to a WAIT instruction.
+.It Li INSTR_EXECUTED
+.Pq Event 1, Counter 0/1
+Total number of instructions completed.
+.It Li BRANCH_COMPLETED
+.Pq Event 2, Counter 0
+Total number of branch instructions completed.
+.It Li BRANCH_MISPRED
+.Pq Event 2, Counter 1
+Counts all branch instructions which completed, but were mispredicted.
+.It Li RETURN
+.Pq Event 3, Counter 0
+Counts all JR R31 instructions completed.
+.It Li RETURN_MISPRED
+.Pq Event 3, Counter 1
+Counts all JR $31 instructions which completed, used the RPS for a prediction, but were mispredicted.
+.It Li RETURN_NOT_31
+.Pq Event 4, Counter 0
+Counts all JR $xx (not $31) and JALR instructions (indirect jumps).
+.It Li RETURN_NOTPRED
+.Pq Event 4, Counter 1
+If RPS use is disabled, JR $31 will not be predicted.
+.It Li ITLB_ACCESS
+.Pq Event 5, Counter 0
+Counts ITLB accesses that are due to fetches showing up in the
+instruction fetch stage of the pipeline and which do not use a fixed
+mapping or are not in unmapped space.
+If an address is fetched twice from the pipe (as in the case of a
+cache miss), that instruction willcount as 2 ITLB accesses.
+Since each fetch gets us 2 instructions,there is one access marked per double
+word.
+.It Li ITLB_MISS
+.Pq Event 5, Counter 1
+Counts all misses in the ITLB except ones that are on the back of another
+miss.
+We cannot process back to back misses and thus those are
+ignored.
+They are also ignored if there is some form of address error.
+.It Li DTLB_ACCESS
+.Pq Event 6, Counter 0
+Counts DTLB access including those in unmapped address spaces.
+.It Li DTLB_MISS
+.Pq Event 6, Counter 1
+Counts DTLB misses. Back to back misses that result in only one DTLB
+entry getting refilled are counted as a single miss.
+.It Li JTLB_IACCESS
+.Pq Event 7, Counter 0
+Instruction JTLB accesses are counted exactly the same as ITLB misses.
+.It Li JTLB_IMISS
+.Pq Event 7, Counter 1
+Counts instruction JTLB accesses that result in no match or a match on
+an invalid translation.
+.It Li JTLB_DACCESS
+.Pq Event 8, Counter 0
+Data JTLB accesses.
+.It Li JTLB_DMISS
+.Pq Event 8, Counter 1
+Counts data JTLB accesses that result in no match or a match on an invalid translation.
+.It Li IC_FETCH
+.Pq Event 9, Counter 0
+Counts every time the instruction cache is accessed. All replays,
+wasted fetches etc. are counted.
+For example, following a branch, even though the prediction is taken,
+the fall through access is counted.
+
+.It Li IC_MISS
+.Pq Event 9, Counter 1
+Counts all instruction cache misses that result in a bus request.
+.It Li DC_LOADSTORE
+.Pq Event 10, Counter 0
+Counts cached loads and stores.
+.It Li DC_WRITEBACK
+.Pq Event 10, Counter 1
+Counts cache lines written back to memory due to replacement or cacheops.
+.It Li DC_MISS
+.Pq Event 11, Counter 0/1
+Counts loads and stores that miss in the cache
+.It Li LOAD_MISS
+.Pq Event 13, Counter 0
+Counts number of cacheable loads that miss in the cache.
+.It Li STORE_MISS
+.Pq Event 13, Counter 1
+Counts number of cacheable stores that miss in the cache.
+.It Li INTEGER_COMPLETED
+.Pq Event 14, Counter 0
+Non-floating point, non-Coprocessor 2 instructions.
+.It Li FP_COMPLETED
+.Pq Event 14, Counter 1
+Floating point instructions completed.
+.It Li LOAD_COMPLETED
+.Pq Event 15, Counter 0
+Integer and co-processor loads completed.
+.It Li STORE_COMPLETED
+.Pq Event 15, Counter 1
+Integer and co-porocessor stores completed.
+.It Li BARRIER_COMPLETED
+.Pq Event 16, Counter 0
+Direct jump (and link) instructions completed.
+.It Li MIPS16_COMPLETED
+.Pq Event 16, Counter 1
+MIPS16c instructions completed.
+.It Li NOP_COMPLETED
+.Pq Event 17, Counter 0
+NOPs completed.
+This includes all instructions that normally write to a general
+purpose register, but where the destination register was set to r0.
+.It Li INTEGER_MULDIV_COMPLETED
+.Pq Event 17, Counter 1
+Integer multipy and divide instructions completed. (MULxx, DIVx, MADDx, MSUBx).
+.It Li RF_STALL
+.Pq Event 18, Counter 0
+Counts the total number of cycles where no instructions are issued
+from the IFU to ALU (the RF stage does not advance) which includes
+both of the previous two events.
+The RT_STALL is different than the sum of them though because cycles
+when both stalls are active will only be counted once.
+.It Li INSTR_REFETCH
+.Pq Event 18, Counter 1
+replay traps (other than uTLB)
+.It Li STORE_COND_COMPLETED
+.Pq Event 19, Counter 0
+Conditional stores completed. Counts all events, including failed stores.
+.It Li STORE_COND_FAILED
+.Pq Event 19, Counter 1
+Conditional store instruction that did not update memory.
+Note: While this event and the SC instruction count event can be configured to
+count in specific operating modes, the timing of the events is much
+different and the observed operating mode could change between them,
+causing some inaccuracy in the measured ratio.
+.It Li ICACHE_REQUESTS
+.Pq Event 20, Counter 0
+Note that this only counts PREFs that are actually attempted.
+PREFs to uncached addresses or ones with translation errors are not counted
+.It Li ICACHE_HIT
+.Pq Event 20, Counter 1
+Counts PREF instructions that hit in the cache
+.It Li L2_WRITEBACK
+.Pq Event 21, Counter 0
+Counts cache lines written back to memory due to replacement or cacheops.
+.It Li L2_ACCESS
+.Pq Event 21, Counter 1
+Number of accesses to L2 Cache.
+.It Li L2_MISS
+.Pq Event 22, Counter 0
+Number of accesses that missed in the L2 cache.
+.It Li L2_ERR_CORRECTED
+.Pq Event 22, Counter 1
+Single bit errors in L2 Cache that were detected and corrected.
+.It Li EXCEPTIONS
+.Pq Event 23, Counter 0
+Any type of exception taken.
+.It Li RF_CYCLES_STALLED
+.Pq Event 24, Counter 0
+Counts cycles where the LSU is in fixup and cannot accept a new
+instruction from the ALU.
+Fixups are replays within the LSU that occur when an instruction needs
+to re-access the cache or the DTLB.
+.It Li IFU_CYCLES_STALLED
+.Pq Event 25, Counter 0
+Counts the number of cycles where the fetch unit is not providing a
+valid instruction to the ALU.
+.It Li ALU_CYCLES_STALLED
+.Pq Event 25, Counter 1
+Counts the number of cycles where the ALU pipeline cannot advance.
+.It Li UNCACHED_LOAD
+.Pq Event 33, Counter 0
+Counts uncached and uncached acclerated loads.
+.It Li UNCACHED_STORE
+.Pq Event 33, Counter 1
+Counts uncached and uncached acclerated stores.
+.It Li CP2_REG_TO_REG_COMPLETED
+.Pq Event 35, Counter 0
+Co-processor 2 register to register instructions completed.
+.It Li MFTC_COMPLETED
+.Pq Event 35, Counter 1
+Co-processor 2 move to and from instructions as well as loads and stores.
+.It Li IC_BLOCKED_CYCLES
+.Pq Event 37, Counter 0
+Cycles when IFU stalls because an instruction miss caused the IFU not
+to have any runnable instructions.
+Ignores the stalls due to ITLB misses as well as the 4 cycles
+following a redirect.
+.It Li DC_BLOCKED_CYCLES
+.Pq Event 37, Counter 1
+Counts all cycles where integer pipeline waits on Load return data due
+to a D-cache miss.
+The LSU can signal a "long stall" on a D-cache misses, in which case
+the waiting TC might be rescheduled so other TCs can execute
+instructions till the data returns.
+.It Li L2_IMISS_STALL_CYCLES
+.Pq Event 38, Counter 0
+Cycles where the main pipeline is stalled waiting for a SYNC to complete.
+.It Li L2_DMISS_STALL_CYCLES
+.Pq Event 38, Counter 1
+Cycles where the main pipeline is stalled because of an index conflict
+in the Fill Store Buffer.
+.It Li DMISS_CYCLES
+.Pq Event 39, Counter 0
+Data miss is outstanding, but not necessarily stalling the pipeline.
+The difference between this and D$ miss stall cycles can show the gain
+from non-blocking cache misses.
+.It Li L2_MISS_CYCLES
+.Pq Event 39, Counter 1
+L2 miss is outstanding, but not necessarily stalling the pipeline.
+.It Li UNCACHED_BLOCK_CYCLES
+.Pq Event 40, Counter 0
+Cycles where the processor is stalled on an uncached fetch, load, or store.
+.It Li MDU_STALL_CYCLES
+.Pq Event 41, Counter 0
+Cycles where the processor is stalled on an uncached fetch, load, or store.
+.It Li FPU_STALL_CYCLES
+.Pq Event 41, Counter 1
+Counts all cycles where integer pipeline waits on FPU return data.
+.It Li CP2_STALL_CYCLES
+.Pq Event 42, Counter 0
+Counts all cycles where integer pipeline waits on CP2 return data.
+.It Li COREXTEND_STALL_CYCLES
+.Pq Event 42, Counter 1
+Counts all cycles where integer pipeline waits on CorExtend return data.
+.It Li ISPRAM_STALL_CYCLES
+.Pq Event 43, Counter 0
+Count all pipeline bubbles that are a result of multicycle ISPRAM
+access.
+Pipeline bubbles are defined as all cycles that IFU doesn't present an
+instruction to ALU. The four cycles after a redirect are not counted.
+.It Li DSPRAM_STALL_CYCLES
+.Pq Event 43, Counter 1
+Counts stall cycles created by an instruction waiting for access to DSPRAM.
+.It Li CACHE_STALL_CYCLES
+.Pq Event 44, Counter 0
+Counts all cycles the where pipeline is stalled due to CACHE
+instructions.
+Includes cycles where CACHE instructions themselves are
+stalled in the ALU, and cycles where CACHE instructions cause
+subsequent instructions to be stalled.
+.It Li LOAD_TO_USE_STALLS
+.Pq Event 45, Counter 0
+Counts all cycles where integer pipeline waits on Load return data.
+.It Li BASE_MISPRED_STALLS
+.Pq Event 45, Counter 1
+Counts stall cycles due to skewed ALU where the bypass to the address
+generation takes an extra cycle.
+.It Li CPO_READ_STALLS
+.Pq Event 46, Counter 0
+Counts all cycles where integer pipeline waits on return data from
+MFC0, RDHWR instructions.
+.It Li BRANCH_MISPRED_CYCLES
+.Pq Event 46, Counter 1
+This counts the number of cycles from a mispredicted branch until the
+next non-delay slot instruction executes.
+.It Li IFETCH_BUFFER_FULL
+.Pq Event 48, Counter 0
+Counts the number of times an instruction cache miss was detected, but
+both fill buffers were already allocated.
+.It Li FETCH_BUFFER_ALLOCATED
+.Pq Event 48, Counter 1
+Number of cycles where at least one of the IFU fill buffers is
+allocated (miss pending).
+.It Li EJTAG_ITRIGGER
+.Pq Event 49, Counter 0
+Number of times an EJTAG Instruction Trigger Point condition matched.
+.It Li EJTAG_DTRIGGER
+.Pq Event 49, Counter 1
+Number of times an EJTAG Data Trigger Point condition matched.
+.It Li FSB_LT_QUARTER
+.Pq Event 50, Counter 0
+Fill store buffer less than one quarter full.
+.It Li FSB_QUARTER_TO_HALF
+.Pq Event 50, Counter 1
+Fill store buffer between one quarter and one half full.
+.It Li FSB_GT_HALF
+.Pq Event 51, Counter 0
+Fill store buffer more than half full.
+.It Li FSB_FULL_PIPELINE_STALLS
+.Pq Event 51, Counter 1
+Cycles where the pipeline is stalled because the Fill-Store Buffer in LSU is full.
+.It Li LDQ_LT_QUARTER
+.Pq Event 52, Counter 0
+Load data queue less than one quarter full.
+.It Li LDQ_QUARTER_TO_HALF
+.Pq Event 52, Counter 1
+Load data queue between one quarter and one half full.
+.It Li LDQ_GT_HALF
+.Pq Event 53, Counter 0
+Load data queue more than one half full.
+.It Li LDQ_FULL_PIPELINE_STALLS
+.Pq Event 53, Counter 1
+Cycles where the pipeline is stalled because the Load Data Queue in the LSU is full.
+.It Li WBB_LT_QUARTER
+.Pq Event 54, Counter 0
+Write back buffer less than one quarter full.
+.It Li WBB_QUARTER_TO_HALF
+.Pq Event 54, Counter 1
+Write back buffer between one quarter and one half full.
+.It Li WBB_GT_HALF
+.Pq Event 55, Counter 0
+Write back buffer more than one half full.
+.It Li WBB_FULL_PIPELINE_STALLS
+.Pq Event 55 Counter 1
+Cycles where the pipeline is stalled because the Load Data Queue in the LSU is full.
+.It Li REQUEST_LATENCY
+.Pq Event 61, Counter 0
+Measures latency from miss detection until critical dword of response
+is returned, Only counts for cacheable reads.
+.It Li REQUEST_COUNT
+.Pq Event 61, Counter 1
+Counts number of cacheable read requests used for previous latency counter.
+.El
+.Ss Event Name Aliases
+The following table shows the mapping between the PMC-independent
+aliases supported by
+.Lb libpmc
+and the underlying hardware events used.
+.Bl -column "branch-mispredicts" "cpu_clk_unhalted.core_p"
+.It Em Alias Ta Em Event Ta
+.It Li instructions Ta Li INSTR_EXECUTED Ta
+.It Li branches Ta Li BRANCH_COMPLETED Ta
+.It Li branch-mispredicts Ta Li BRANCH_MISPRED Ta
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh CAVEATS
+The MIPS code does not yet support sampling.
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
+MIPS support was added by
+.An "George Neville-Neil"
+.Aq gnn@FreeBSD.org .
diff --git a/lib/libpmc/pmc.p4.3 b/lib/libpmc/pmc.p4.3
index ecfc628..e13fa6e 100644
--- a/lib/libpmc/pmc.p4.3
+++ b/lib/libpmc/pmc.p4.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 4, 2008
-.Os
.Dt PMC.P4 3
+.Os
.Sh NAME
.Nm pmc.p4
.Nd measurement events for
diff --git a/lib/libpmc/pmc.p5.3 b/lib/libpmc/pmc.p5.3
index 2930f16..36ab917 100644
--- a/lib/libpmc/pmc.p5.3
+++ b/lib/libpmc/pmc.p5.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 4, 2008
-.Os
.Dt PMC 3
+.Os
.Sh NAME
.Nm pmc
.Nd library for accessing hardware performance monitoring counters
diff --git a/lib/libpmc/pmc.p6.3 b/lib/libpmc/pmc.p6.3
index 15a1101..d8cde64 100644
--- a/lib/libpmc/pmc.p6.3
+++ b/lib/libpmc/pmc.p6.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 4, 2008
-.Os
.Dt PMC.P6 3
+.Os
.Sh NAME
.Nm pmc.p6
.Nd measurement events for
diff --git a/lib/libpmc/pmc.tsc.3 b/lib/libpmc/pmc.tsc.3
index 3dd0b88..144ff35 100644
--- a/lib/libpmc/pmc.tsc.3
+++ b/lib/libpmc/pmc.tsc.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd October 4, 2008
-.Os
.Dt PMC.TSC 3
+.Os
.Sh NAME
.Nm pmc.tsc
.Nd measurements using the i386 timestamp counter
diff --git a/lib/libpmc/pmc.ucf.3 b/lib/libpmc/pmc.ucf.3
new file mode 100644
index 0000000..230a110
--- /dev/null
+++ b/lib/libpmc/pmc.ucf.3
@@ -0,0 +1,115 @@
+.\" Copyright (c) 2010 Fabien Thomas. 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 Joseph Koshy ``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 Joseph Koshy 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 March 30, 2010
+.Dt PMC.UCF 3
+.Os
+.Sh NAME
+.Nm pmc.ucf
+.Nd measurement events for
+.Tn Intel
+uncore fixed function performance counters.
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+Each fixed-function PMC measures a specific hardware event.
+The number of fixed-function PMCs implemented in a CPU can vary.
+The number of fixed-function PMCs present can be determined at runtime
+by using function
+.Xr pmc_cpuinfo 3 .
+.Pp
+Intel uncore fixed-function PMCs are documented in
+.Rs
+.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
+.%T "Volume 3B: System Programming Guide, Part 2"
+.%N "Order Number: 253669-033US"
+.%D December 2009
+.%Q "Intel Corporation"
+.Re
+.Pp
+.Ss PMC Capabilities
+Fixed-function PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta \&No
+.It PMC_CAP_INTERRUPT Ta \&No
+.It PMC_CAP_INVERT Ta \&No
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta \&No
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta \&No
+.It PMC_CAP_USER Ta \&No
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Class Name Prefix
+These PMCs are named using a class name prefix of
+.Dq Li ucf- .
+.Ss Event Specifiers (Fixed Function PMCs)
+The fixed function PMCs are selectable using the following
+event names:
+.Bl -tag -width indent
+.It Li UCLOCK
+.Pq Fixed Function Counter 0
+The fixed-function uncore counter increments at the rate of the U-clock.
+The frequency of the uncore clock domain can be determined from the uncore
+clock ratio which is available in the PCI configuration space register at
+offset C0H under device number 0 and Function 0.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.core2 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmere 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
+
+
diff --git a/lib/libpmc/pmc.westmere.3 b/lib/libpmc/pmc.westmere.3
new file mode 100644
index 0000000..98adce6
--- /dev/null
+++ b/lib/libpmc/pmc.westmere.3
@@ -0,0 +1,1329 @@
+.\" Copyright (c) 2010 Fabien Thomas. 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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
+.Dt PMC.WESTMERE 3
+.Os
+.Sh NAME
+.Nm pmc.westmere
+.Nd measurement events for
+.Tn Intel
+.Tn Westmere
+family CPUs
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+.Tn Intel
+.Tn "Westmere"
+CPUs contain PMCs conforming to version 2 of the
+.Tn Intel
+performance measurement architecture.
+These CPUs may contain up to three classes of PMCs:
+.Bl -tag -width "Li PMC_CLASS_IAP"
+.It Li PMC_CLASS_IAF
+Fixed-function counters that count only one hardware event per counter.
+.It Li PMC_CLASS_IAP
+Programmable counters that may be configured to count one of a defined
+set of hardware events.
+.El
+.Pp
+The number of PMCs available in each class and their widths need to be
+determined at run time by calling
+.Xr pmc_cpuinfo 3 .
+.Pp
+Intel Westmere PMCs are documented in
+.Rs
+.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
+.%T "Volume 3B: System Programming Guide, Part 2"
+.%N "Order Number: 253669-033US"
+.%D December 2009
+.%Q "Intel Corporation"
+.Re
+.Ss WESTMERE FIXED FUNCTION PMCS
+These PMCs and their supported events are documented in
+.Xr pmc.iaf 3 .
+.Ss WESTMERE PROGRAMMABLE PMCS
+The programmable PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta Yes
+.It PMC_CAP_INTERRUPT Ta Yes
+.It PMC_CAP_INVERT Ta Yes
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta Yes
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta Yes
+.It PMC_CAP_USER Ta Yes
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+Event specifiers for these PMCs support the following common
+qualifiers:
+.Bl -tag -width indent
+.It Li rsp= Ns Ar value
+Configure the Off-core Response bits.
+.Bl -tag -width indent
+.It Li DMND_DATA_RD
+Counts the number of demand and DCU prefetch data reads of full
+and partial cachelines as well as demand data page table entry
+cacheline reads. Does not count L2 data read prefetches or
+instruction fetches.
+.It Li DMND_RFO
+Counts the number of demand and DCU prefetch reads for ownership
+(RFO) requests generated by a write to data cacheline. Does not
+count L2 RFO.
+.It Li DMND_IFETCH
+Counts the number of demand and DCU prefetch instruction cacheline
+reads. Does not count L2 code read prefetches.
+WB
+Counts the number of writeback (modified to exclusive) transactions.
+.It Li PF_DATA_RD
+Counts the number of data cacheline reads generated by L2 prefetchers.
+.It Li PF_RFO
+Counts the number of RFO requests generated by L2 prefetchers.
+.It Li PF_IFETCH
+Counts the number of code reads generated by L2 prefetchers.
+.It Li OTHER
+Counts one of the following transaction types, including L3 invalidate,
+I/O, full or partial writes, WC or non-temporal stores, CLFLUSH, Fences,
+lock, unlock, split lock.
+.It Li UNCORE_HIT
+L3 Hit: local or remote home requests that hit L3 cache in the uncore
+with no coherency actions required (snooping).
+.It Li OTHER_CORE_HIT_SNP
+L3 Hit: local or remote home requests that hit L3 cache in the uncore
+and was serviced by another core with a cross core snoop where no modified
+copies were found (clean).
+.It Li OTHER_CORE_HITM
+L3 Hit: local or remote home requests that hit L3 cache in the uncore
+and was serviced by another core with a cross core snoop where modified
+copies were found (HITM).
+.It Li REMOTE_CACHE_FWD
+L3 Miss: local homed requests that missed the L3 cache and was serviced
+by forwarded data following a cross package snoop where no modified
+copies found. (Remote home requests are not counted)
+.It Li REMOTE_DRAM
+L3 Miss: remote home requests that missed the L3 cache and were serviced
+by remote DRAM.
+.It Li LOCAL_DRAM
+L3 Miss: local home requests that missed the L3 cache and were serviced
+by local DRAM.
+.It Li NON_DRAM
+Non-DRAM requests that were serviced by IOH.
+.El
+.It Li cmask= Ns Ar value
+Configure the PMC to increment only if the number of configured
+events measured in a cycle is greater than or equal to
+.Ar value .
+.It Li edge
+Configure the PMC to count the number of de-asserted to asserted
+transitions of the conditions expressed by the other qualifiers.
+If specified, the counter will increment only once whenever a
+condition becomes true, irrespective of the number of clocks during
+which the condition remains true.
+.It Li inv
+Invert the sense of comparison when the
+.Dq Li cmask
+qualifier is present, making the counter increment when the number of
+events per cycle is less than the value specified by the
+.Dq Li cmask
+qualifier.
+.It Li os
+Configure the PMC to count events happening at processor privilege
+level 0.
+.It Li usr
+Configure the PMC to count events occurring at privilege levels 1, 2
+or 3.
+.El
+.Pp
+If neither of the
+.Dq Li os
+or
+.Dq Li usr
+qualifiers are specified, the default is to enable both.
+.Ss Event Specifiers (Programmable PMCs)
+Westmere programmable PMCs support the following events:
+.Bl -tag -width indent
+.It Li LOAD_BLOCK.OVERLAP_STORE
+.Pq Event 03H , Umask 02H
+Loads that partially overlap an earlier store
+.It Li SB_DRAIN.ANY
+.Pq Event 04H , Umask 07H
+All Store buffer stall cycles
+.It Li MISALIGN_MEMORY.STORE
+.Pq Event 05H , Umask 02H
+All store referenced with misaligned address
+.It Li STORE_BLOCKS.AT_RET
+.Pq Event 06H , Umask 04H
+Counts number of loads delayed with at-Retirement block code. The following
+loads need to be executed at retirement and wait for all senior stores on
+the same thread to be drained: load splitting across 4K boundary (page
+split), load accessing uncacheable (UC or USWC) memory, load lock, and load
+with page table in UC or USWC memory region.
+.It Li STORE_BLOCKS.L1D_BLOCK
+.Pq Event 06H , Umask 08H
+Cacheable loads delayed with L1D block code
+.It Li PARTIAL_ADDRESS_ALIAS
+.Pq Event 07H , Umask 01H
+Counts false dependency due to partial address aliasing
+.It Li DTLB_LOAD_MISSES.ANY
+.Pq Event 08H , Umask 01H
+Counts all load misses that cause a page walk
+.It Li DTLB_LOAD_MISSES.WALK_COMPLETED
+.Pq Event 08H , Umask 02H
+Counts number of completed page walks due to load miss in the STLB.
+.It Li DTLB_LOAD_MISSES.WALK_CYCLES
+.Pq Event 08H , Umask 04H
+Cycles PMH is busy with a page walk due to a load miss in the STLB.
+.It Li DTLB_LOAD_MISSES.STLB_HIT
+.Pq Event 08H , Umask 10H
+Number of cache load STLB hits
+.It Li DTLB_LOAD_MISSES.PDE_MISS
+.Pq Event 08H , Umask 20H
+Number of DTLB cache load misses where the low part of the linear to
+physical address translation was missed.
+.It Li MEM_INST_RETIRED.LOADS
+.Pq Event 0BH , Umask 01H
+Counts the number of instructions with an architecturally-visible store
+retired on the architected path.
+In conjunction with ld_lat facility
+.It Li MEM_INST_RETIRED.STORES
+.Pq Event 0BH , Umask 02H
+Counts the number of instructions with an architecturally-visible store
+retired on the architected path.
+In conjunction with ld_lat facility
+.It Li MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD
+.Pq Event 0BH , Umask 10H
+Counts the number of instructions exceeding the latency specified with
+ld_lat facility.
+In conjunction with ld_lat facility
+.It Li MEM_STORE_RETIRED.DTLB_MISS
+.Pq Event 0CH , Umask 01H
+The event counts the number of retired stores that missed the DTLB. The DTLB
+miss is not counted if the store operation causes a fault. Does not counter
+prefetches. Counts both primary and secondary misses to the TLB
+.It Li UOPS_ISSUED.ANY
+.Pq Event 0EH , Umask 01H
+Counts the number of Uops issued by the Register Allocation Table to the
+Reservation Station, i.e. the UOPs issued from the front end to the back
+end.
+.It Li UOPS_ISSUED.STALLED_CYCLES
+.Pq Event 0EH , Umask 01H
+Counts the number of cycles no Uops issued by the Register Allocation Table
+to the Reservation Station, i.e. the UOPs issued from the front end to the
+back end.
+set invert=1, cmask = 1
+.It Li UOPS_ISSUED.FUSED
+.Pq Event 0EH , Umask 02H
+Counts the number of fused Uops that were issued from the Register
+Allocation Table to the Reservation Station.
+.It Li MEM_UNCORE_RETIRED.LOCAL_HITM
+.Pq Event 0FH , Umask 02H
+Load instructions retired that HIT modified data in sibling core (Precise
+Event)
+.It Li MEM_UNCORE_RETIRED.LOCAL_DRAM_AND_REMOTE_CACHE_HIT
+.Pq Event 0FH , Umask 08H
+Load instructions retired local dram and remote cache HIT data sources
+(Precise Event)
+.It Li MEM_UNCORE_RETIRED.LOCAL_DRAM
+.Pq Event 0FH , Umask 10H
+Load instructions retired with a data source of local DRAM or locally homed
+remote cache HITM (Precise Event)
+.It Li MEM_UNCORE_RETIRED.REMOTE_DRAM
+.Pq Event 0FH , Umask 20H
+Load instructions retired remote DRAM and remote home-remote cache HITM
+(Precise Event)
+.It Li MEM_UNCORE_RETIRED.UNCACHEABLE
+.Pq Event 0FH , Umask 80H
+Load instructions retired I/O (Precise Event)
+.It Li FP_COMP_OPS_EXE.X87
+.Pq Event 10H , Umask 01H
+Counts the number of FP Computational Uops Executed. The number of FADD,
+FSUB, FCOM, FMULs, integer MULsand IMULs, FDIVs, FPREMs, FSQRTS, integer
+DIVs, and IDIVs. This event does not distinguish an FADD used in the middle
+of a transcendental flow from a separate FADD instruction.
+.It Li FP_COMP_OPS_EXE.MMX
+.Pq Event 10H , Umask 02H
+Counts number of MMX Uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_FP
+.Pq Event 10H , Umask 04H
+Counts number of SSE and SSE2 FP uops executed.
+.It Li FP_COMP_OPS_EXE.SSE2_INTEGER
+.Pq Event 10H , Umask 08H
+Counts number of SSE2 integer uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_FP_PACKED
+.Pq Event 10H , Umask 10H
+Counts number of SSE FP packed uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_FP_SCALAR
+.Pq Event 10H , Umask 20H
+Counts number of SSE FP scalar uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION
+.Pq Event 10H , Umask 40H
+Counts number of SSE* FP single precision uops executed.
+.It Li FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION
+.Pq Event 10H , Umask 80H
+Counts number of SSE* FP double precision uops executed.
+.It Li SIMD_INT_128.PACKED_MPY
+.Pq Event 12H , Umask 01H
+Counts number of 128 bit SIMD integer multiply operations.
+.It Li SIMD_INT_128.PACKED_SHIFT
+.Pq Event 12H , Umask 02H
+Counts number of 128 bit SIMD integer shift operations.
+.It Li SIMD_INT_128.PACK
+.Pq Event 12H , Umask 04H
+Counts number of 128 bit SIMD integer pack operations.
+.It Li SIMD_INT_128.UNPACK
+.Pq Event 12H , Umask 08H
+Counts number of 128 bit SIMD integer unpack operations.
+.It Li SIMD_INT_128.PACKED_LOGICAL
+.Pq Event 12H , Umask 10H
+Counts number of 128 bit SIMD integer logical operations.
+.It Li SIMD_INT_128.PACKED_ARITH
+.Pq Event 12H , Umask 20H
+Counts number of 128 bit SIMD integer arithmetic operations.
+.It Li SIMD_INT_128.SHUFFLE_MOVE
+.Pq Event 12H , Umask 40H
+Counts number of 128 bit SIMD integer shuffle and move operations.
+.It Li LOAD_DISPATCH.RS
+.Pq Event 13H , Umask 01H
+Counts number of loads dispatched from the Reservation Station that bypass
+the Memory Order Buffer.
+.It Li LOAD_DISPATCH.RS_DELAYED
+.Pq Event 13H , Umask 02H
+Counts the number of delayed RS dispatches at the stage latch. If an RS
+dispatch can not bypass to LB, it has another chance to dispatch from the
+one-cycle delayed staging latch before it is written into the LB.
+.It Li LOAD_DISPATCH.MOB
+.Pq Event 13H , Umask 04H
+Counts the number of loads dispatched from the Reservation Station to the
+Memory Order Buffer.
+.It Li LOAD_DISPATCH.ANY
+.Pq Event 13H , Umask 07H
+Counts all loads dispatched from the Reservation Station.
+.It Li ARITH.CYCLES_DIV_BUSY
+.Pq Event 14H , Umask 01H
+Counts the number of cycles the divider is busy executing divide or square
+root operations. The divide can be integer, X87 or Streaming SIMD Extensions
+(SSE). The square root operation can be either X87 or SSE.
+Set 'edge =1, invert=1, cmask=1' to count the number of divides.
+Count may be incorrect When SMT is on
+.It Li ARITH.MUL
+.Pq Event 14H , Umask 02H
+Counts the number of multiply operations executed. This includes integer as
+well as floating point multiply operations but excludes DPPS mul and MPSAD.
+Count may be incorrect When SMT is on
+.It Li INST_QUEUE_WRITES
+.Pq Event 17H , Umask 01H
+Counts the number of instructions written into the instruction queue every
+cycle.
+.It Li INST_DECODED.DEC0
+.Pq Event 18H , Umask 01H
+Counts number of instructions that require decoder 0 to be decoded. Usually,
+this means that the instruction maps to more than 1 uop
+.It Li TWO_UOP_INSTS_DECODED
+.Pq Event 19H , Umask 01H
+An instruction that generates two uops was decoded
+.It Li INST_QUEUE_WRITE_CYCLES
+.Pq Event 1EH , Umask 01H
+This event counts the number of cycles during which instructions are written
+to the instruction queue. Dividing this counter by the number of
+instructions written to the instruction queue (INST_QUEUE_WRITES) yields the
+average number of instructions decoded each cycle. If this number is less
+than four and the pipe stalls, this indicates that the decoder is failing to
+decode enough instructions per cycle to sustain the 4-wide pipeline.
+If SSE* instructions that are 6 bytes or longer arrive one after another,
+then front end throughput may limit execution speed. In such case,
+.It Li LSD_OVERFLOW
+.Pq Event 20H , Umask 01H
+Number of loops that can not stream from the instruction queue.
+.It Li L2_RQSTS.LD_HIT
+.Pq Event 24H , Umask 01H
+Counts number of loads that hit the L2 cache. L2 loads include both L1D
+demand misses as well as L1D prefetches. L2 loads can be rejected for
+various reasons. Only non rejected loads are counted.
+.It Li L2_RQSTS.LD_MISS
+.Pq Event 24H , Umask 02H
+Counts the number of loads that miss the L2 cache. L2 loads include both L1D
+demand misses as well as L1D prefetches.
+.It Li L2_RQSTS.LOADS
+.Pq Event 24H , Umask 03H
+Counts all L2 load requests. L2 loads include both L1D demand misses as well
+as L1D prefetches.
+.It Li L2_RQSTS.RFO_HIT
+.Pq Event 24H , Umask 04H
+Counts the number of store RFO requests that hit the L2 cache. L2 RFO
+requests include both L1D demand RFO misses as well as L1D RFO prefetches.
+Count includes WC memory requests, where the data is not fetched but the
+permission to write the line is required.
+.It Li L2_RQSTS.RFO_MISS
+.Pq Event 24H , Umask 08H
+Counts the number of store RFO requests that miss the L2 cache. L2 RFO
+requests include both L1D demand RFO misses as well as L1D RFO prefetches.
+.It Li L2_RQSTS.RFOS
+.Pq Event 24H , Umask 0CH
+Counts all L2 store RFO requests. L2 RFO requests include both L1D demand
+RFO misses as well as L1D RFO prefetches..
+.It Li L2_RQSTS.IFETCH_HIT
+.Pq Event 24H , Umask 10H
+Counts number of instruction fetches that hit the L2 cache. L2 instruction
+fetches include both L1I demand misses as well as L1I instruction
+prefetches.
+.It Li L2_RQSTS.IFETCH_MISS
+.Pq Event 24H , Umask 20H
+Counts number of instruction fetches that miss the L2 cache. L2 instruction
+fetches include both L1I demand misses as well as L1I instruction
+prefetches.
+.It Li L2_RQSTS.IFETCHES
+.Pq Event 24H , Umask 30H
+Counts all instruction fetches. L2 instruction fetches include both L1I
+demand misses as well as L1I instruction prefetches.
+.It Li L2_RQSTS.PREFETCH_HIT
+.Pq Event 24H , Umask 40H
+Counts L2 prefetch hits for both code and data.
+.It Li L2_RQSTS.PREFETCH_MISS
+.Pq Event 24H , Umask 80H
+Counts L2 prefetch misses for both code and data.
+.It Li L2_RQSTS.PREFETCHES
+.Pq Event 24H , Umask C0H
+Counts all L2 prefetches for both code and data.
+.It Li L2_RQSTS.MISS
+.Pq Event 24H , Umask AAH
+Counts all L2 misses for both code and data.
+.It Li L2_RQSTS.REFERENCES
+.Pq Event 24H , Umask FFH
+Counts all L2 requests for both code and data.
+.It Li L2_DATA_RQSTS.DEMAND.I_STATE
+.Pq Event 26H , Umask 01H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the I (invalid) state, i.e. a cache miss. L2 demand loads are both L1D
+demand misses and L1D prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.S_STATE
+.Pq Event 26H , Umask 02H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the S (shared) state. L2 demand loads are both L1D demand misses and L1D
+prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.E_STATE
+.Pq Event 26H , Umask 04H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the E (exclusive) state. L2 demand loads are both L1D demand misses and
+L1D prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.M_STATE
+.Pq Event 26H , Umask 08H
+Counts number of L2 data demand loads where the cache line to be loaded is
+in the M (modified) state. L2 demand loads are both L1D demand misses and
+L1D prefetches.
+.It Li L2_DATA_RQSTS.DEMAND.MESI
+.Pq Event 26H , Umask 0FH
+Counts all L2 data demand requests. L2 demand loads are both L1D demand
+misses and L1D prefetches.
+.It Li L2_DATA_RQSTS.PREFETCH.I_STATE
+.Pq Event 26H , Umask 10H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the I (invalid) state, i.e. a cache miss.
+.It Li L2_DATA_RQSTS.PREFETCH.S_STATE
+.Pq Event 26H , Umask 20H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the S (shared) state. A prefetch RFO will miss on an S state line, while
+a prefetch read will hit on an S state line.
+.It Li L2_DATA_RQSTS.PREFETCH.E_STATE
+.Pq Event 26H , Umask 40H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the E (exclusive) state.
+.It Li L2_DATA_RQSTS.PREFETCH.M_STATE
+.Pq Event 26H , Umask 80H
+Counts number of L2 prefetch data loads where the cache line to be loaded is
+in the M (modified) state.
+.It Li L2_DATA_RQSTS.PREFETCH.MESI
+.Pq Event 26H , Umask F0H
+Counts all L2 prefetch requests.
+.It Li L2_DATA_RQSTS.ANY
+.Pq Event 26H , Umask FFH
+Counts all L2 data requests.
+.It Li L2_WRITE.RFO.I_STATE
+.Pq Event 27H , Umask 01H
+Counts number of L2 demand store RFO requests where the cache line to be
+loaded is in the I (invalid) state, i.e, a cache miss. The L1D prefetcher
+does not issue a RFO prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.S_STATE
+.Pq Event 27H , Umask 02H
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in the S (shared) state. The L1D prefetcher does not issue a RFO prefetch,.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.M_STATE
+.Pq Event 27H , Umask 08H
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in the M (modified) state. The L1D prefetcher does not issue a RFO prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.HIT
+.Pq Event 27H , Umask 0EH
+Counts number of L2 store RFO requests where the cache line to be loaded is
+in either the S, E or M states. The L1D prefetcher does not issue a RFO
+prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.RFO.MESI
+.Pq Event 27H , Umask 0FH
+Counts all L2 store RFO requests.The L1D prefetcher does not issue a RFO
+prefetch.
+This is a demand RFO request
+.It Li L2_WRITE.LOCK.I_STATE
+.Pq Event 27H , Umask 10H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in the I (invalid) state, i.e. a cache miss.
+.It Li L2_WRITE.LOCK.S_STATE
+.Pq Event 27H , Umask 20H
+Counts number of L2 lock RFO requests where the cache line to be loaded is
+in the S (shared) state.
+.It Li L2_WRITE.LOCK.E_STATE
+.Pq Event 27H , Umask 40H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in the E (exclusive) state.
+.It Li L2_WRITE.LOCK.M_STATE
+.Pq Event 27H , Umask 80H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in the M (modified) state.
+.It Li L2_WRITE.LOCK.HIT
+.Pq Event 27H , Umask E0H
+Counts number of L2 demand lock RFO requests where the cache line to be
+loaded is in either the S, E, or M state.
+.It Li L2_WRITE.LOCK.MESI
+.Pq Event 27H , Umask F0H
+Counts all L2 demand lock RFO requests.
+.It Li L1D_WB_L2.I_STATE
+.Pq Event 28H , Umask 01H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the I (invalid) state, i.e. a cache miss.
+.It Li L1D_WB_L2.S_STATE
+.Pq Event 28H , Umask 02H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the S state.
+.It Li L1D_WB_L2.E_STATE
+.Pq Event 28H , Umask 04H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the E (exclusive) state.
+.It Li L1D_WB_L2.M_STATE
+.Pq Event 28H , Umask 08H
+Counts number of L1 writebacks to the L2 where the cache line to be written
+is in the M (modified) state.
+.It Li L1D_WB_L2.MESI
+.Pq Event 28H , Umask 0FH
+Counts all L1 writebacks to the L2.
+.It Li L3_LAT_CACHE.REFERENCE
+.Pq Event 2EH , Umask 02H
+Counts uncore Last Level Cache references. Because cache hierarchy, cache
+sizes and other implementation-specific characteristics; value comparison to
+estimate performance differences is not recommended.
+see Table A-1
+.It Li L3_LAT_CACHE.MISS
+.Pq Event 2EH , Umask 01H
+Counts uncore Last Level Cache misses. Because cache hierarchy, cache sizes
+and other implementation-specific characteristics; value comparison to
+estimate performance differences is not recommended.
+see Table A-1
+.It Li CPU_CLK_UNHALTED.THREAD_P
+.Pq Event 3CH , Umask 00H
+Counts the number of thread cycles while the thread is not in a halt state.
+The thread enters the halt state when it is running the HLT instruction. The
+core frequency may change from time to time due to power or thermal
+throttling.
+see Table A-1
+.It Li CPU_CLK_UNHALTED.REF_P
+.Pq Event 3CH , Umask 01H
+Increments at the frequency of TSC when not halted.
+see Table A-1
+.It Li DTLB_MISSES.ANY
+.Pq Event 49H , Umask 01H
+Counts the number of misses in the STLB which causes a page walk.
+.It Li DTLB_MISSES.WALK_COMPLETED
+.Pq Event 49H , Umask 02H
+Counts number of misses in the STLB which resulted in a completed page walk.
+.It Li DTLB_MISSES.WALK_CYCLES
+.Pq Event 49H , Umask 04H
+Counts cycles of page walk due to misses in the STLB.
+.It Li DTLB_MISSES.STLB_HIT
+.Pq Event 49H , Umask 10H
+Counts the number of DTLB first level misses that hit in the second level
+TLB. This event is only relevant if the core contains multiple DTLB levels.
+.It Li DTLB_MISSES.LARGE_WALK_COMPLETED
+.Pq Event 49H , Umask 80H
+Counts number of completed large page walks due to misses in the STLB.
+.It Li LOAD_HIT_PRE
+.Pq Event 4CH , Umask 01H
+Counts load operations sent to the L1 data cache while a previous SSE
+prefetch instruction to the same cache line has started prefetching but has
+not yet finished.
+.It Li L1D_PREFETCH.REQUESTS
+.Pq Event 4EH , Umask 01H
+Counts number of hardware prefetch requests dispatched out of the prefetch
+FIFO.
+.It Li L1D_PREFETCH.MISS
+.Pq Event 4EH , Umask 02H
+Counts number of hardware prefetch requests that miss the L1D. There are two
+prefetchers in the L1D. A streamer, which predicts lines sequentially after
+this one should be fetched, and the IP prefetcher that remembers access
+patterns for the current instruction. The streamer prefetcher stops on an
+L1D hit, while the IP prefetcher does not.
+.It Li L1D_PREFETCH.TRIGGERS
+.Pq Event 4EH , Umask 04H
+Counts number of prefetch requests triggered by the Finite State Machine and
+pushed into the prefetch FIFO. Some of the prefetch requests are dropped due
+to overwrites or competition between the IP index prefetcher and streamer
+prefetcher. The prefetch FIFO contains 4 entries.
+.It Li EPT.WALK_CYCLES
+.Pq Event 4FH , Umask 10H
+Counts Extended Page walk cycles.
+.It Li L1D.REPL
+.Pq Event 51H , Umask 01H
+Counts the number of lines brought into the L1 data cache.
+Counter 0, 1 only
+.It Li L1D.M_REPL
+.Pq Event 51H , Umask 02H
+Counts the number of modified lines brought into the L1 data cache.
+Counter 0, 1 only
+.It Li L1D.M_EVICT
+.Pq Event 51H , Umask 04H
+Counts the number of modified lines evicted from the L1 data cache due to
+replacement.
+Counter 0, 1 only
+.It Li L1D.M_SNOOP_EVICT
+.Pq Event 51H , Umask 08H
+Counts the number of modified lines evicted from the L1 data cache due to
+snoop HITM intervention.
+Counter 0, 1 only
+.It Li L1D_CACHE_PREFETCH_LOCK_FB_HIT
+.Pq Event 52H , Umask 01H
+Counts the number of cacheable load lock speculated instructions accepted
+into the fill buffer.
+.It Li L1D_CACHE_LOCK_FB_HIT
+.Pq Event 53H , Umask 01H
+Counts the number of cacheable load lock speculated or retired instructions
+accepted into the fill buffer.
+.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA
+.Pq Event 60H , Umask 01H
+Counts weighted cycles of offcore demand data read requests. Does not
+include L2 prefetch requests.
+counter 0
+.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE
+.Pq Event 60H , Umask 02H
+Counts weighted cycles of offcore demand code read requests. Does not
+include L2 prefetch requests.
+counter 0
+.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO
+.Pq Event 60H , Umask 04H
+Counts weighted cycles of offcore demand RFO requests. Does not include L2
+prefetch requests.
+counter 0
+.It Li OFFCORE_REQUESTS_OUTSTANDING.ANY.READ
+.Pq Event 60H , Umask 08H
+Counts weighted cycles of offcore read requests of any kind. Include L2
+prefetch requests.
+counter 0
+.It Li CACHE_LOCK_CYCLES.L1D_L2
+.Pq Event 63H , Umask 01H
+Cycle count during which the L1D and L2 are locked. A lock is asserted when
+there is a locked memory access, due to uncacheable memory, a locked
+operation that spans two cache lines, or a page walk from an uncacheable
+page table.
+Counter 0, 1 only. L1D and L2 locks have a very high performance penalty and
+it is highly recommended to avoid such accesses.
+.It Li CACHE_LOCK_CYCLES.L1D
+.Pq Event 63H , Umask 02H
+Counts the number of cycles that cacheline in the L1 data cache unit is
+locked.
+Counter 0, 1 only.
+.It Li IO_TRANSACTIONS
+.Pq Event 6CH , Umask 01H
+Counts the number of completed I/O transactions.
+.It Li L1I.HITS
+.Pq Event 80H , Umask 01H
+Counts all instruction fetches that hit the L1 instruction cache.
+.It Li L1I.MISSES
+.Pq Event 80H , Umask 02H
+Counts all instruction fetches that miss the L1I cache. This includes
+instruction cache misses, streaming buffer misses, victim cache misses and
+uncacheable fetches. An instruction fetch miss is counted only once and not
+once for every cycle it is outstanding.
+.It Li L1I.READS
+.Pq Event 80H , Umask 03H
+Counts all instruction fetches, including uncacheable fetches that bypass
+the L1I.
+.It Li L1I.CYCLES_STALLED
+.Pq Event 80H , Umask 04H
+Cycle counts for which an instruction fetch stalls due to a L1I cache miss,
+ITLB miss or ITLB fault.
+.It Li LARGE_ITLB.HIT
+.Pq Event 82H , Umask 01H
+Counts number of large ITLB hits.
+.It Li ITLB_MISSES.ANY
+.Pq Event 85H , Umask 01H
+Counts the number of misses in all levels of the ITLB which causes a page
+walk.
+.It Li ITLB_MISSES.WALK_COMPLETED
+.Pq Event 85H , Umask 02H
+Counts number of misses in all levels of the ITLB which resulted in a
+completed page walk.
+.It Li ITLB_MISSES.WALK_CYCLES
+.Pq Event 85H , Umask 04H
+Counts ITLB miss page walk cycles.
+.It Li ITLB_MISSES.LARGE_WALK_COMPLETED
+.Pq Event 85H , Umask 80H
+Counts number of completed large page walks due to misses in the STLB.
+.It Li ILD_STALL.LCP
+.Pq Event 87H , Umask 01H
+Cycles Instruction Length Decoder stalls due to length changing prefixes:
+66, 67 or REX.W (for EM64T) instructions which change the length of the
+decoded instruction.
+.It Li ILD_STALL.MRU
+.Pq Event 87H , Umask 02H
+Instruction Length Decoder stall cycles due to Brand Prediction Unit (PBU)
+Most Recently Used (MRU) bypass.
+.It Li ILD_STALL.IQ_FULL
+.Pq Event 87H , Umask 04H
+Stall cycles due to a full instruction queue.
+.It Li ILD_STALL.REGEN
+.Pq Event 87H , Umask 08H
+Counts the number of regen stalls.
+.It Li ILD_STALL.ANY
+.Pq Event 87H , Umask 0FH
+Counts any cycles the Instruction Length Decoder is stalled.
+.It Li BR_INST_EXEC.COND
+.Pq Event 88H , Umask 01H
+Counts the number of conditional near branch instructions executed, but not
+necessarily retired.
+.It Li BR_INST_EXEC.DIRECT
+.Pq Event 88H , Umask 02H
+Counts all unconditional near branch instructions excluding calls and
+indirect branches.
+.It Li BR_INST_EXEC.INDIRECT_NON_CALL
+.Pq Event 88H , Umask 04H
+Counts the number of executed indirect near branch instructions that are not
+calls.
+.It Li BR_INST_EXEC.NON_CALLS
+.Pq Event 88H , Umask 07H
+Counts all non call near branch instructions executed, but not necessarily
+retired.
+.It Li BR_INST_EXEC.RETURN_NEAR
+.Pq Event 88H , Umask 08H
+Counts indirect near branches that have a return mnemonic.
+.It Li BR_INST_EXEC.DIRECT_NEAR_CALL
+.Pq Event 88H , Umask 10H
+Counts unconditional near call branch instructions, excluding non call
+branch, executed.
+.It Li BR_INST_EXEC.INDIRECT_NEAR_CALL
+.Pq Event 88H , Umask 20H
+Counts indirect near calls, including both register and memory indirect,
+executed.
+.It Li BR_INST_EXEC.NEAR_CALLS
+.Pq Event 88H , Umask 30H
+Counts all near call branches executed, but not necessarily retired.
+.It Li BR_INST_EXEC.TAKEN
+.Pq Event 88H , Umask 40H
+Counts taken near branches executed, but not necessarily retired.
+.It Li BR_INST_EXEC.ANY
+.Pq Event 88H , Umask 7FH
+Counts all near executed branches (not necessarily retired). This includes
+only instructions and not micro-op branches. Frequent branching is not
+necessarily a major performance issue. However frequent branch
+mispredictions may be a problem.
+.It Li BR_MISP_EXEC.COND
+.Pq Event 89H , Umask 01H
+Counts the number of mispredicted conditional near branch instructions
+executed, but not necessarily retired.
+.It Li BR_MISP_EXEC.DIRECT
+.Pq Event 89H , Umask 02H
+Counts mispredicted macro unconditional near branch instructions, excluding
+calls and indirect branches (should always be 0).
+.It Li BR_MISP_EXEC.INDIRECT_NON_CALL
+.Pq Event 89H , Umask 04H
+Counts the number of executed mispredicted indirect near branch instructions
+that are not calls.
+.It Li BR_MISP_EXEC.NON_CALLS
+.Pq Event 89H , Umask 07H
+Counts mispredicted non call near branches executed, but not necessarily
+retired.
+.It Li BR_MISP_EXEC.RETURN_NEAR
+.Pq Event 89H , Umask 08H
+Counts mispredicted indirect branches that have a rear return mnemonic.
+.It Li BR_MISP_EXEC.DIRECT_NEAR_CALL
+.Pq Event 89H , Umask 10H
+Counts mispredicted non-indirect near calls executed, (should always be 0).
+.It Li BR_MISP_EXEC.INDIRECT_NEAR_CALL
+.Pq Event 89H , Umask 20H
+Counts mispredicted indirect near calls exeucted, including both register
+and memory indirect.
+.It Li BR_MISP_EXEC.NEAR_CALLS
+.Pq Event 89H , Umask 30H
+Counts all mispredicted near call branches executed, but not necessarily
+retired.
+.It Li BR_MISP_EXEC.TAKEN
+.Pq Event 89H , Umask 40H
+Counts executed mispredicted near branches that are taken, but not
+necessarily retired.
+.It Li BR_MISP_EXEC.ANY
+.Pq Event 89H , Umask 7FH
+Counts the number of mispredicted near branch instructions that were
+executed, but not necessarily retired.
+.It Li RESOURCE_STALLS.ANY
+.Pq Event A2H , Umask 01H
+Counts the number of Allocator resource related stalls. Includes register
+renaming buffer entries, memory buffer entries. In addition to resource
+related stalls, this event counts some other events. Includes stalls arising
+during branch misprediction recovery, such as if retirement of the
+mispredicted branch is delayed and stalls arising while store buffer is
+draining from synchronizing operations.
+Does not include stalls due to SuperQ (off core) queue full, too many cache
+misses, etc.
+.It Li RESOURCE_STALLS.LOAD
+.Pq Event A2H , Umask 02H
+Counts the cycles of stall due to lack of load buffer for load operation.
+.It Li RESOURCE_STALLS.RS_FULL
+.Pq Event A2H , Umask 04H
+This event counts the number of cycles when the number of instructions in
+the pipeline waiting for execution reaches the limit the processor can
+handle. A high count of this event indicates that there are long latency
+operations in the pipe (possibly load and store operations that miss the L2
+cache, or instructions dependent upon instructions further down the pipeline
+that have yet to retire.
+When RS is full, new instructions can not enter the reservation station and
+start execution.
+.It Li RESOURCE_STALLS.STORE
+.Pq Event A2H , Umask 08H
+This event counts the number of cycles that a resource related stall will
+occur due to the number of store instructions reaching the limit of the
+pipeline, (i.e. all store buffers are used). The stall ends when a store
+instruction commits its data to the cache or memory.
+.It Li RESOURCE_STALLS.ROB_FULL
+.Pq Event A2H , Umask 10H
+Counts the cycles of stall due to re- order buffer full.
+.It Li RESOURCE_STALLS.FPCW
+.Pq Event A2H , Umask 20H
+Counts the number of cycles while execution was stalled due to writing the
+floating-point unit (FPU) control word.
+.It Li RESOURCE_STALLS.MXCSR
+.Pq Event A2H , Umask 40H
+Stalls due to the MXCSR register rename occurring to close to a previous
+MXCSR rename. The MXCSR provides control and status for the MMX registers.
+.It Li RESOURCE_STALLS.OTHER
+.Pq Event A2H , Umask 80H
+Counts the number of cycles while execution was stalled due to other
+resource issues.
+.It Li MACRO_INSTS.FUSIONS_DECODED
+.Pq Event A6H , Umask 01H
+Counts the number of instructions decoded that are macro-fused but not
+necessarily executed or retired.
+.It Li BACLEAR_FORCE_IQ
+.Pq Event A7H , Umask 01H
+Counts number of times a BACLEAR was forced by the Instruction Queue. The IQ
+is also responsible for providing conditional branch prediciton direction
+based on a static scheme and dynamic data provided by the L2 Branch
+Prediction Unit. If the conditional branch target is not found in the Target
+Array and the IQ predicts that the branch is taken, then the IQ will force
+the Branch Address Calculator to issue a BACLEAR. Each BACLEAR asserted by
+the BAC generates approximately an 8 cycle bubble in the instruction fetch
+pipeline.
+.It Li LSD.UOPS
+.Pq Event A8H , Umask 01H
+Counts the number of micro-ops delivered by loop stream detector
+Use cmask=1 and invert to count cycles
+.It Li ITLB_FLUSH
+.Pq Event AEH , Umask 01H
+Counts the number of ITLB flushes
+.It Li OFFCORE_REQUESTS.DEMAND.READ_DATA
+.Pq Event B0H , Umask 01H
+Counts number of offcore demand data read requests. Does not count L2
+prefetch requests.
+.It Li OFFCORE_REQUESTS.DEMAND.READ_CODE
+.Pq Event B0H , Umask 02H
+Counts number of offcore demand code read requests. Does not count L2
+prefetch requests.
+.It Li OFFCORE_REQUESTS.DEMAND.RFO
+.Pq Event B0H , Umask 04H
+Counts number of offcore demand RFO requests. Does not count L2 prefetch
+requests.
+.It Li OFFCORE_REQUESTS.ANY.READ
+.Pq Event B0H , Umask 08H
+Counts number of offcore read requests. Includes L2 prefetch requests.
+.It Li OFFCORE_REQUESTS.ANY.RFO
+.Pq Event 80H , Umask 10H
+Counts number of offcore RFO requests. Includes L2 prefetch requests.
+.It Li OFFCORE_REQUESTS.L1D_WRITEBACK
+.Pq Event B0H , Umask 40H
+Counts number of L1D writebacks to the uncore.
+.It Li OFFCORE_REQUESTS.ANY
+.Pq Event B0H , Umask 80H
+Counts all offcore requests.
+.It Li UOPS_EXECUTED.PORT0
+.Pq Event B1H , Umask 01H
+Counts number of Uops executed that were issued on port 0. Port 0 handles
+integer arithmetic, SIMD and FP add Uops.
+.It Li UOPS_EXECUTED.PORT1
+.Pq Event B1H , Umask 02H
+Counts number of Uops executed that were issued on port 1. Port 1 handles
+integer arithmetic, SIMD, integer shift, FP multiply and FP divide Uops.
+.It Li UOPS_EXECUTED.PORT2_CORE
+.Pq Event B1H , Umask 04H
+Counts number of Uops executed that were issued on port 2. Port 2 handles
+the load Uops. This is a core count only and can not be collected per
+thread.
+.It Li UOPS_EXECUTED.PORT3_CORE
+.Pq Event B1H , Umask 08H
+Counts number of Uops executed that were issued on port 3. Port 3 handles
+store Uops. This is a core count only and can not be collected per thread.
+.It Li UOPS_EXECUTED.PORT4_CORE
+.Pq Event B1H , Umask 10H
+Counts number of Uops executed that where issued on port 4. Port 4 handles
+the value to be stored for the store Uops issued on port 3. This is a core
+count only and can not be collected per thread.
+.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5
+.Pq Event B1H , Umask 1FH
+Counts number of cycles there are one or more uops being executed and were
+issued on ports 0-4. This is a core count only and can not be collected per
+thread.
+.It Li UOPS_EXECUTED.PORT5
+.Pq Event B1H , Umask 20H
+Counts number of Uops executed that where issued on port 5.
+.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES
+.Pq Event B1H , Umask 3FH
+Counts number of cycles there are one or more uops being executed on any
+ports. This is a core count only and can not be collected per thread.
+.It Li UOPS_EXECUTED.PORT015
+.Pq Event B1H , Umask 40H
+Counts number of Uops executed that where issued on port 0, 1, or 5.
+use cmask=1, invert=1 to count stall cycles
+.It Li UOPS_EXECUTED.PORT234
+.Pq Event B1H , Umask 80H
+Counts number of Uops executed that where issued on port 2, 3, or 4.
+.It Li OFFCORE_REQUESTS_SQ_FULL
+.Pq Event B2H , Umask 01H
+Counts number of cycles the SQ is full to handle off-core requests.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.DATA
+.Pq Event B3H , Umask 01H
+Counts weighted cycles of snoopq requests for data. Counter 0 only
+Use cmask=1 to count cycles not empty.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE
+.Pq Event B3H , Umask 02H
+Counts weighted cycles of snoopq invalidate requests. Counter 0 only
+Use cmask=1 to count cycles not empty.
+.It Li SNOOPQ_REQUESTS_OUTSTANDING.CODE
+.Pq Event B3H , Umask 04H
+Counts weighted cycles of snoopq requests for code. Counter 0 only
+Use cmask=1 to count cycles not empty.
+.It Li SNOOPQ_REQUESTS.CODE
+.Pq Event B4H , Umask 01H
+Counts the number of snoop code requests
+.It Li SNOOPQ_REQUESTS.DATA
+.Pq Event B4H , Umask 02H
+Counts the number of snoop data requests
+.It Li SNOOPQ_REQUESTS.INVALIDATE
+.Pq Event B4H , Umask 04H
+Counts the number of snoop invalidate requests
+.It Li OFF_CORE_RESPONSE_0
+.Pq Event B7H , Umask 01H
+see Section 30.6.1.3, Off-core Response Performance Monitoring in the
+Processor Core.
+Requires programming MSR 01A6H
+.It Li SNOOP_RESPONSE.HIT
+.Pq Event B8H , Umask 01H
+Counts HIT snoop response sent by this thread in response to a snoop
+request.
+.It Li SNOOP_RESPONSE.HITE
+.Pq Event B8H , Umask 02H
+Counts HIT E snoop response sent by this thread in response to a snoop
+request.
+.It Li SNOOP_RESPONSE.HITM
+.Pq Event B8H , Umask 04H
+Counts HIT M snoop response sent by this thread in response to a snoop
+request.
+.It Li OFF_CORE_RESPONSE_1
+.Pq Event BBH , Umask 01H
+see Section 30.6.1.3, Off-core Response Performance Monitoring in the
+Processor Core
+Use MSR 01A7H
+.It Li INST_RETIRED.ANY_P
+.Pq Event C0H , Umask 01H
+See Table A-1
+Notes: INST_RETIRED.ANY is counted by a designated fixed counter.
+INST_RETIRED.ANY_P is counted by a programmable counter and is an
+architectural performance event. Event is supported if CPUID.A.EBX[1] = 0.
+Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not
+count as retired instructions.
+.It Li INST_RETIRED.X87
+.Pq Event C0H , Umask 02H
+Counts the number of floating point computational operations retired:
+floating point computational operations executed by the assist handler and
+sub-operations of complex floating point instructions like transcendental
+instructions.
+.It Li INST_RETIRED.MMX
+.Pq Event C0H , Umask 04H
+Counts the number of retired: MMX instructions.
+.It Li UOPS_RETIRED.ANY
+.Pq Event C2H , Umask 01H
+Counts the number of micro-ops retired, (macro-fused=1, micro- fused=2,
+others=1; maximum count of 8 per cycle). Most instructions are composed of
+one or two micro-ops. Some instructions are decoded into longer sequences
+such as repeat instructions, floating point transcendental instructions, and
+assists.
+Use cmask=1 and invert to count active cycles or stalled cycles
+.It Li UOPS_RETIRED.RETIRE_SLOTS
+.Pq Event C2H , Umask 02H
+Counts the number of retirement slots used each cycle
+.It Li UOPS_RETIRED.MACRO_FUSED
+.Pq Event C2H , Umask 04H
+Counts number of macro-fused uops retired.
+.It Li MACHINE_CLEARS.CYCLES
+.Pq Event C3H , Umask 01H
+Counts the cycles machine clear is asserted.
+.It Li MACHINE_CLEARS.MEM_ORDER
+.Pq Event C3H , Umask 02H
+Counts the number of machine clears due to memory order conflicts.
+.It Li MACHINE_CLEARS.SMC
+.Pq Event C3H , Umask 04H
+Counts the number of times that a program writes to a code section.
+Self-modifying code causes a sever penalty in all Intel 64 and IA-32
+processors. The modified cache line is written back to the L2 and L3caches.
+.It Li BR_INST_RETIRED.ALL_BRANCHES
+.Pq Event C4H , Umask 00H
+See Table A-1
+.It Li BR_INST_RETIRED.CONDITIONAL
+.Pq Event C4H , Umask 01H
+Counts the number of conditional branch instructions retired.
+.It Li BR_INST_RETIRED.NEAR_CALL
+.Pq Event C4H , Umask 02H
+Counts the number of direct & indirect near unconditional calls retired
+.It Li BR_INST_RETIRED.ALL_BRANCHES
+.Pq Event C4H , Umask 04H
+Counts the number of branch instructions retired
+.It Li BR_MISP_RETIRED.ALL_BRANCHES
+.Pq Event C5H , Umask 00H
+See Table A-1
+.It Li BR_MISP_RETIRED.CONDITIONAL
+.Pq Event C5H , Umask 01H
+Counts mispredicted conditional retired calls.
+.It Li BR_MISP_RETIRED.NEAR_CALL
+.Pq Event C5H , Umask 02H
+Counts mispredicted direct & indirect near unconditional retired calls.
+.It Li BR_MISP_RETIRED.ALL_BRANCHES
+.Pq Event C5H , Umask 04H
+Counts all mispredicted retired calls.
+.It Li SSEX_UOPS_RETIRED.PACKED_SINGLE
+.Pq Event C7H , Umask 01H
+Counts SIMD packed single-precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.SCALAR_SINGLE
+.Pq Event C7H , Umask 02H
+Counts SIMD calar single-precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.PACKED_DOUBLE
+.Pq Event C7H , Umask 04H
+Counts SIMD packed double- precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.SCALAR_DOUBLE
+.Pq Event C7H , Umask 08H
+Counts SIMD scalar double-precision floating point Uops retired.
+.It Li SSEX_UOPS_RETIRED.VECTOR_INTEGER
+.Pq Event C7H , Umask 10H
+Counts 128-bit SIMD vector integer Uops retired.
+.It Li ITLB_MISS_RETIRED
+.Pq Event C8H , Umask 20H
+Counts the number of retired instructions that missed the ITLB when the
+instruction was fetched.
+.It Li MEM_LOAD_RETIRED.L1D_HIT
+.Pq Event CBH , Umask 01H
+Counts number of retired loads that hit the L1 data cache.
+.It Li MEM_LOAD_RETIRED.L2_HIT
+.Pq Event CBH , Umask 02H
+Counts number of retired loads that hit the L2 data cache.
+.It Li MEM_LOAD_RETIRED.L3_UNSHARED_HIT
+.Pq Event CBH , Umask 04H
+Counts number of retired loads that hit their own, unshared lines in the L3
+cache.
+.It Li MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM
+.Pq Event CBH , Umask 08H
+Counts number of retired loads that hit in a sibling core's L2 (on die
+core). Since the L3 is inclusive of all cores on the package, this is an L3
+hit. This counts both clean or modified hits.
+.It Li MEM_LOAD_RETIRED.L3_MISS
+.Pq Event CBH , Umask 10H
+Counts number of retired loads that miss the L3 cache. The load was
+satisfied by a remote socket, local memory or an IOH.
+.It Li MEM_LOAD_RETIRED.HIT_LFB
+.Pq Event CBH , Umask 40H
+Counts number of retired loads that miss the L1D and the address is located
+in an allocated line fill buffer and will soon be committed to cache. This
+is counting secondary L1D misses.
+.It Li MEM_LOAD_RETIRED.DTLB_MISS
+.Pq Event CBH , Umask 80H
+Counts the number of retired loads that missed the DTLB. The DTLB miss is
+not counted if the load operation causes a fault. This event counts loads
+from cacheable memory only. The event does not count loads by software
+prefetches. Counts both primary and secondary misses to the TLB.
+.It Li FP_MMX_TRANS.TO_FP
+.Pq Event CCH , Umask 01H
+Counts the first floating-point instruction following any MMX instruction.
+You can use this event to estimate the penalties for the transitions between
+floating-point and MMX technology states.
+.It Li FP_MMX_TRANS.TO_MMX
+.Pq Event CCH , Umask 02H
+Counts the first MMX instruction following a floating-point instruction. You
+can use this event to estimate the penalties for the transitions between
+floating-point and MMX technology states.
+.It Li FP_MMX_TRANS.ANY
+.Pq Event CCH , Umask 03H
+Counts all transitions from floating point to MMX instructions and from MMX
+instructions to floating point instructions. You can use this event to
+estimate the penalties for the transitions between floating-point and MMX
+technology states.
+.It Li MACRO_INSTS.DECODED
+.Pq Event D0H , Umask 01H
+Counts the number of instructions decoded, (but not necessarily executed or
+retired).
+.It Li UOPS_DECODED.STALL_CYCLES
+.Pq Event D1H , Umask 01H
+Counts the cycles of decoder stalls.
+.It Li UOPS_DECODED.MS
+.Pq Event D1H , Umask 02H
+Counts the number of Uops decoded by the Microcode Sequencer, MS. The MS
+delivers uops when the instruction is more than 4 uops long or a microcode
+assist is occurring.
+.It Li UOPS_DECODED.ESP_FOLDING
+.Pq Event D1H , Umask 04H
+Counts number of stack pointer (ESP) instructions decoded: push , pop , call
+, ret, etc. ESP instructions do not generate a Uop to increment or decrement
+ESP. Instead, they update an ESP_Offset register that keeps track of the
+delta to the current value of the ESP register.
+.It Li UOPS_DECODED.ESP_SYNC
+.Pq Event D1H , Umask 08H
+Counts number of stack pointer (ESP) sync operations where an ESP
+instruction is corrected by adding the ESP offset register to the current
+value of the ESP register.
+.It Li RAT_STALLS.FLAGS
+.Pq Event D2H , Umask 01H
+Counts the number of cycles during which execution stalled due to several
+reasons, one of which is a partial flag register stall. A partial register
+stall may occur when two conditions are met: 1) an instruction modifies
+some, but not all, of the flags in the flag register and 2) the next
+instruction, which depends on flags, depends on flags that were not modified
+by this instruction.
+.It Li RAT_STALLS.REGISTERS
+.Pq Event D2H , Umask 02H
+This event counts the number of cycles instruction execution latency became
+longer than the defined latency because the instruction used a register that
+was partially written by previous instruction.
+.It Li RAT_STALLS.ROB_READ_PORT
+.Pq Event D2H , Umask 04H
+Counts the number of cycles when ROB read port stalls occurred, which did
+not allow new micro-ops to enter the out-of-order pipeline. Note that, at
+this stage in the pipeline, additional stalls may occur at the same cycle
+and prevent the stalled micro-ops from entering the pipe. In such a case,
+micro-ops retry entering the execution pipe in the next cycle and the
+ROB-read port stall is counted again.
+.It Li RAT_STALLS.SCOREBOARD
+.Pq Event D2H , Umask 08H
+Counts the cycles where we stall due to microarchitecturally required
+serialization. Microcode scoreboarding stalls.
+.It Li RAT_STALLS.ANY
+.Pq Event D2H , Umask 0FH
+Counts all Register Allocation Table stall cycles due to: Cycles when ROB
+read port stalls occurred, which did not allow new micro-ops to enter the
+execution pipe. Cycles when partial register stalls occurred Cycles when
+flag stalls occurred Cycles floating-point unit (FPU) status word stalls
+occurred. To count each of these conditions separately use the events:
+RAT_STALLS.ROB_READ_PORT, RAT_STALLS.PARTIAL, RAT_STALLS.FLAGS, and
+RAT_STALLS.FPSW.
+.It Li SEG_RENAME_STALLS
+.Pq Event D4H , Umask 01H
+Counts the number of stall cycles due to the lack of renaming resources for
+the ES, DS, FS, and GS segment registers. If a segment is renamed but not
+retired and a second update to the same segment occurs, a stall occurs in
+the front- end of the pipeline until the renamed segment retires.
+.It Li ES_REG_RENAMES
+.Pq Event D5H , Umask 01H
+Counts the number of times the ES segment register is renamed.
+.It Li UOP_UNFUSION
+.Pq Event DBH , Umask 01H
+Counts unfusion events due to floating point exception to a fused uop.
+.It Li BR_INST_DECODED
+.Pq Event E0H , Umask 01H
+Counts the number of branch instructions decoded.
+.It Li BPU_MISSED_CALL_RET
+.Pq Event E5H , Umask 01H
+Counts number of times the Branch Prediciton Unit missed predicting a call
+or return branch.
+.It Li BACLEAR.CLEAR
+.Pq Event E6H , Umask 01H
+Counts the number of times the front end is resteered, mainly when the
+Branch Prediction Unit cannot provide a correct prediction and this is
+corrected by the Branch Address Calculator at the front end. This can occur
+if the code has many branches such that they cannot be consumed by the BPU.
+Each BACLEAR asserted by the BAC generates approximately an 8 cycle bubble
+in the instruction fetch pipeline. The effect on total execution time
+depends on the surrounding code.
+.It Li BACLEAR.BAD_TARGET
+.Pq Event E6H , Umask 02H
+Counts number of Branch Address Calculator clears (BACLEAR) asserted due to
+conditional branch instructions in which there was a target hit but the
+direction was wrong. Each BACLEAR asserted by the BAC generates
+approximately an 8 cycle bubble in the instruction fetch pipeline.
+.It Li BPU_CLEARS.EARLY
+.Pq Event E8H , Umask 01H
+Counts early (normal) Branch Prediction Unit clears: BPU predicted a taken
+branch after incorrectly assuming that it was not taken.
+The BPU clear leads to 2 cycle bubble in the Front End.
+.It Li BPU_CLEARS.LATE
+.Pq Event E8H , Umask 02H
+Counts late Branch Prediction Unit clears due to Most Recently Used
+conflicts. The PBU clear leads to a 3 cycle bubble in the Front End.
+.It Li THREAD_ACTIVE
+.Pq Event ECH , Umask 01H
+Counts cycles threads are active.
+.It Li L2_TRANSACTIONS.LOAD
+.Pq Event F0H , Umask 01H
+Counts L2 load operations due to HW prefetch or demand loads.
+.It Li L2_TRANSACTIONS.RFO
+.Pq Event F0H , Umask 02H
+Counts L2 RFO operations due to HW prefetch or demand RFOs.
+.It Li L2_TRANSACTIONS.IFETCH
+.Pq Event F0H , Umask 04H
+Counts L2 instruction fetch operations due to HW prefetch or demand ifetch.
+.It Li L2_TRANSACTIONS.PREFETCH
+.Pq Event F0H , Umask 08H
+Counts L2 prefetch operations.
+.It Li L2_TRANSACTIONS.L1D_WB
+.Pq Event F0H , Umask 10H
+Counts L1D writeback operations to the L2.
+.It Li L2_TRANSACTIONS.FILL
+.Pq Event F0H , Umask 20H
+Counts L2 cache line fill operations due to load, RFO, L1D writeback or
+prefetch.
+.It Li L2_TRANSACTIONS.WB
+.Pq Event F0H , Umask 40H
+Counts L2 writeback operations to the L3.
+.It Li L2_TRANSACTIONS.ANY
+.Pq Event F0H , Umask 80H
+Counts all L2 cache operations.
+.It Li L2_LINES_IN.S_STATE
+.Pq Event F1H , Umask 02H
+Counts the number of cache lines allocated in the L2 cache in the S (shared)
+state.
+.It Li L2_LINES_IN.E_STATE
+.Pq Event F1H , Umask 04H
+Counts the number of cache lines allocated in the L2 cache in the E
+(exclusive) state.
+.It Li L2_LINES_IN.ANY
+.Pq Event F1H , Umask 07H
+Counts the number of cache lines allocated in the L2 cache.
+.It Li L2_LINES_OUT.DEMAND_CLEAN
+.Pq Event F2H , Umask 01H
+Counts L2 clean cache lines evicted by a demand request.
+.It Li L2_LINES_OUT.DEMAND_DIRTY
+.Pq Event F2H , Umask 02H
+Counts L2 dirty (modified) cache lines evicted by a demand request.
+.It Li L2_LINES_OUT.PREFETCH_CLEAN
+.Pq Event F2H , Umask 04H
+Counts L2 clean cache line evicted by a prefetch request.
+.It Li L2_LINES_OUT.PREFETCH_DIRTY
+.Pq Event F2H , Umask 08H
+Counts L2 modified cache line evicted by a prefetch request.
+.It Li L2_LINES_OUT.ANY
+.Pq Event F2H , Umask 0FH
+Counts all L2 cache lines evicted for any reason.
+.It Li SQ_MISC.LRU_HINTS
+.Pq Event F4H , Umask 04H
+Counts number of Super Queue LRU hints sent to L3.
+.It Li SQ_MISC.SPLIT_LOCK
+.Pq Event F4H , Umask 10H
+Counts the number of SQ lock splits across a cache line.
+.It Li SQ_FULL_STALL_CYCLES
+.Pq Event F6H , Umask 01H
+Counts cycles the Super Queue is full. Neither of the threads on this core
+will be able to access the uncore.
+.It Li FP_ASSIST.ALL
+.Pq Event F7H , Umask 01H
+Counts the number of floating point operations executed that required
+micro-code assist intervention. Assists are required in the following cases:
+SSE instructions, (Denormal input when the DAZ flag is off or Underflow
+result when the FTZ flag is off): x87 instructions, (NaN or denormal are
+loaded to a register or used as input from memory, Division by 0 or
+Underflow output).
+.It Li FP_ASSIST.OUTPUT
+.Pq Event F7H , Umask 02H
+Counts number of floating point micro-code assist when the output value
+(destination register) is invalid.
+.It Li FP_ASSIST.INPUT
+.Pq Event F7H , Umask 04H
+Counts number of floating point micro-code assist when the input value (one
+of the source operands to an FP instruction) is invalid.
+.It Li SIMD_INT_64.PACKED_MPY
+.Pq Event FDH , Umask 01H
+Counts number of SID integer 64 bit packed multiply operations.
+.It Li SIMD_INT_64.PACKED_SHIFT
+.Pq Event FDH , Umask 02H
+Counts number of SID integer 64 bit packed shift operations.
+.It Li SIMD_INT_64.PACK
+.Pq Event FDH , Umask 04H
+Counts number of SID integer 64 bit pack operations.
+.It Li SIMD_INT_64.UNPACK
+.Pq Event FDH , Umask 08H
+Counts number of SID integer 64 bit unpack operations.
+.It Li SIMD_INT_64.PACKED_LOGICAL
+.Pq Event FDH , Umask 10H
+Counts number of SID integer 64 bit logical operations.
+.It Li SIMD_INT_64.PACKED_ARITH
+.Pq Event FDH , Umask 20H
+Counts number of SID integer 64 bit arithmetic operations.
+.It Li SIMD_INT_64.SHUFFLE_MOVE
+.Pq Event FDH , Umask 40H
+Counts number of SID integer 64 bit shift or move operations.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
diff --git a/lib/libpmc/pmc.westmereuc.3 b/lib/libpmc/pmc.westmereuc.3
new file mode 100644
index 0000000..c77ef9b
--- /dev/null
+++ b/lib/libpmc/pmc.westmereuc.3
@@ -0,0 +1,1083 @@
+.\" Copyright (c) 2010 Fabien Thomas. 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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
+.Dt PMC.WESTMEREUC 3
+.Os
+.Sh NAME
+.Nm pmc.westmere
+.Nd uncore measurement events for
+.Tn Intel
+.Tn Westmere
+family CPUs
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+.Tn Intel
+.Tn "Westmere"
+CPUs contain PMCs conforming to version 2 of the
+.Tn Intel
+performance measurement architecture.
+These CPUs contain two classes of PMCs:
+.Bl -tag -width "Li PMC_CLASS_UCP"
+.It Li PMC_CLASS_UCF
+Fixed-function counters that count only one hardware event per counter.
+.It Li PMC_CLASS_UCP
+Programmable counters that may be configured to count one of a defined
+set of hardware events.
+.El
+.Pp
+The number of PMCs available in each class and their widths need to be
+determined at run time by calling
+.Xr pmc_cpuinfo 3 .
+.Pp
+Intel Westmere PMCs are documented in
+.Rs
+.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
+.%T "Volume 3B: System Programming Guide, Part 2"
+.%N "Order Number: 253669-033US"
+.%D December 2009
+.%Q "Intel Corporation"
+.Re
+.Ss WESTMERE UNCORE FIXED FUNCTION PMCS
+These PMCs and their supported events are documented in
+.Xr pmc.ucf 3 .
+Not all CPUs in this family implement fixed-function counters.
+.Ss WESTMERE UNCORE PROGRAMMABLE PMCS
+The programmable PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta Yes
+.It PMC_CAP_INTERRUPT Ta \&No
+.It PMC_CAP_INVERT Ta Yes
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta \&No
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta Yes
+.It PMC_CAP_USER Ta \&No
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+Event specifiers for these PMCs support the following common
+qualifiers:
+.Bl -tag -width indent
+.It Li cmask= Ns Ar value
+Configure the PMC to increment only if the number of configured
+events measured in a cycle is greater than or equal to
+.Ar value .
+.It Li edge
+Configure the PMC to count the number of de-asserted to asserted
+transitions of the conditions expressed by the other qualifiers.
+If specified, the counter will increment only once whenever a
+condition becomes true, irrespective of the number of clocks during
+which the condition remains true.
+.It Li inv
+Invert the sense of comparison when the
+.Dq Li cmask
+qualifier is present, making the counter increment when the number of
+events per cycle is less than the value specified by the
+.Dq Li cmask
+qualifier.
+.El
+.Ss Event Specifiers (Programmable PMCs)
+Westmere uncore programmable PMCs support the following events:
+.Bl -tag -width indent
+.It Li GQ_CYCLES_FULL.READ_TRACKER
+.Pq Event 00H , Umask 01H
+Uncore cycles Global Queue read tracker is full.
+.It Li GQ_CYCLES_FULL.WRITE_TRACKER
+.Pq Event 00H , Umask 02H
+Uncore cycles Global Queue write tracker is full.
+.It Li GQ_CYCLES_FULL.PEER_PROBE_TRACKER
+.Pq Event 00H , Umask 04H
+Uncore cycles Global Queue peer probe tracker is full. The peer probe
+tracker queue tracks snoops from the IOH and remote sockets.
+.It Li GQ_CYCLES_NOT_EMPTY.READ_TRACKER
+.Pq Event 01H , Umask 01H
+Uncore cycles were Global Queue read tracker has at least one valid entry.
+.It Li GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER
+.Pq Event 01H , Umask 02H
+Uncore cycles were Global Queue write tracker has at least one valid entry.
+.It Li GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER
+.Pq Event 01H , Umask 04H
+Uncore cycles were Global Queue peer probe tracker has at least one valid
+entry. The peer probe tracker queue tracks IOH and remote socket snoops.
+.It Li GQ_OCCUPANCY.READ_TRACKER
+.Pq Event 02H , Umask 01H
+Increments the number of queue entries (code read, data read, and RFOs) in
+the tread tracker. The GQ read tracker allocate to deallocate occupancy
+count is divided by the count to obtain the average read tracker latency.
+.It Li GQ_ALLOC.READ_TRACKER
+.Pq Event 03H , Umask 01H
+Counts the number of tread tracker allocate to deallocate entries. The GQ
+read tracker allocate to deallocate occupancy count is divided by the count
+to obtain the average read tracker latency.
+.It Li GQ_ALLOC.RT_L3_MISS
+.Pq Event 03H , Umask 02H
+Counts the number GQ read tracker entries for which a full cache line read
+has missed the L3. The GQ read tracker L3 miss to fill occupancy count is
+divided by this count to obtain the average cache line read L3 miss latency.
+The latency represents the time after which the L3 has determined that the
+cache line has missed. The time between a GQ read tracker allocation and the
+L3 determining that the cache line has missed is the average L3 hit latency.
+The total L3 cache line read miss latency is the hit latency + L3 miss
+latency.
+.It Li GQ_ALLOC.RT_TO_L3_RESP
+.Pq Event 03H , Umask 04H
+Counts the number of GQ read tracker entries that are allocated in the read
+tracker queue that hit or miss the L3. The GQ read tracker L3 hit occupancy
+count is divided by this count to obtain the average L3 hit latency.
+.It Li GQ_ALLOC.RT_TO_RTID_ACQUIRED
+.Pq Event 03H , Umask 08H
+Counts the number of GQ read tracker entries that are allocated in the read
+tracker, have missed in the L3 and have not acquired a Request Transaction
+ID. The GQ read tracker L3 miss to RTID acquired occupancy count is
+divided by this count to obtain the average latency for a read L3 miss to
+acquire an RTID.
+.It Li GQ_ALLOC.WT_TO_RTID_ACQUIRED
+.Pq Event 03H , Umask 10H
+Counts the number of GQ write tracker entries that are allocated in the
+write tracker, have missed in the L3 and have not acquired a Request
+Transaction ID. The GQ write tracker L3 miss to RTID occupancy count is
+divided by this count to obtain the average latency for a write L3 miss to
+acquire an RTID.
+.It Li GQ_ALLOC.WRITE_TRACKER
+.Pq Event 03H , Umask 20H
+Counts the number of GQ write tracker entries that are allocated in the
+write tracker queue that miss the L3. The GQ write tracker occupancy count
+is divided by the this count to obtain the average L3 write miss latency.
+.It Li GQ_ALLOC.PEER_PROBE_TRACKER
+.Pq Event 03H , Umask 40H
+Counts the number of GQ peer probe tracker (snoop) entries that are
+allocated in the peer probe tracker queue that miss the L3. The GQ peer
+probe occupancy count is divided by this count to obtain the average L3 peer
+probe miss latency.
+.It Li GQ_DATA.FROM_QPI
+.Pq Event 04H , Umask 01H
+Cycles Global Queue Quickpath Interface input data port is busy importing
+data from the Quickpath Interface. Each cycle the input port can transfer 8
+or 16 bytes of data.
+.It Li GQ_DATA.FROM_QMC
+.Pq Event 04H , Umask 02H
+Cycles Global Queue Quickpath Memory Interface input data port is busy
+importing data from the Quickpath Memory Interface. Each cycle the input
+port can transfer 8 or 16 bytes of data.
+.It Li GQ_DATA.FROM_L3
+.Pq Event 04H , Umask 04H
+Cycles GQ L3 input data port is busy importing data from the Last Level
+Cache. Each cycle the input port can transfer 32 bytes of data.
+.It Li GQ_DATA.FROM_CORES_02
+.Pq Event 04H , Umask 08H
+Cycles GQ Core 0 and 2 input data port is busy importing data from processor
+cores 0 and 2. Each cycle the input port can transfer 32 bytes of data.
+.It Li GQ_DATA.FROM_CORES_13
+.Pq Event 04H , Umask 10H
+Cycles GQ Core 1 and 3 input data port is busy importing data from processor
+cores 1 and 3. Each cycle the input port can transfer 32 bytes of data.
+.It Li GQ_DATA.TO_QPI_QMC
+.Pq Event 05H , Umask 01H
+Cycles GQ QPI and QMC output data port is busy sending data to the Quickpath
+Interface or Quickpath Memory Interface. Each cycle the output port can
+transfer 32 bytes of data.
+.It Li GQ_DATA.TO_L3
+.Pq Event 05H , Umask 02H
+Cycles GQ L3 output data port is busy sending data to the Last Level Cache.
+Each cycle the output port can transfer 32 bytes of data.
+.It Li GQ_DATA.TO_CORES
+.Pq Event 05H , Umask 04H
+Cycles GQ Core output data port is busy sending data to the Cores. Each
+cycle the output port can transfer 32 bytes of data.
+.It Li SNP_RESP_TO_LOCAL_HOME.I_STATE
+.Pq Event 06H , Umask 01H
+Number of snoop responses to the local home that L3 does not have the
+referenced cache line.
+.It Li SNP_RESP_TO_LOCAL_HOME.S_STATE
+.Pq Event 06H , Umask 02H
+Number of snoop responses to the local home that L3 has the referenced line
+cached in the S state.
+.It Li SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE
+.Pq Event 06H , Umask 04H
+Number of responses to code or data read snoops to the local home that the
+L3 has the referenced cache line in the E state. The L3 cache line state is
+changed to the S state and the line is forwarded to the local home in the S
+state.
+.It Li SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE
+.Pq Event 06H , Umask 08H
+Number of responses to read invalidate snoops to the local home that the L3
+has the referenced cache line in the M state. The L3 cache line state is
+invalidated and the line is forwarded to the local home in the M state.
+.It Li SNP_RESP_TO_LOCAL_HOME.CONFLICT
+.Pq Event 06H , Umask 10H
+Number of conflict snoop responses sent to the local home.
+.It Li SNP_RESP_TO_LOCAL_HOME.WB
+.Pq Event 06H , Umask 20H
+Number of responses to code or data read snoops to the local home that the
+L3 has the referenced line cached in the M state.
+.It Li SNP_RESP_TO_REMOTE_HOME.I_STATE
+.Pq Event 07H , Umask 01H
+Number of snoop responses to a remote home that L3 does not have the
+referenced cache line.
+.It Li SNP_RESP_TO_REMOTE_HOME.S_STATE
+.Pq Event 07H , Umask 02H
+Number of snoop responses to a remote home that L3 has the referenced line
+cached in the S state.
+.It Li SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE
+.Pq Event 07H , Umask 04H
+Number of responses to code or data read snoops to a remote home that the L3
+has the referenced cache line in the E state. The L3 cache line state is
+changed to the S state and the line is forwarded to the remote home in the S
+state.
+.It Li SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE
+.Pq Event 07H , Umask 08H
+Number of responses to read invalidate snoops to a remote home that the L3
+has the referenced cache line in the M state. The L3 cache line state is
+invalidated and the line is forwarded to the remote home in the M state.
+.It Li SNP_RESP_TO_REMOTE_HOME.CONFLICT
+.Pq Event 07H , Umask 10H
+Number of conflict snoop responses sent to the local home.
+.It Li SNP_RESP_TO_REMOTE_HOME.WB
+.Pq Event 07H , Umask 20H
+Number of responses to code or data read snoops to a remote home that the L3
+has the referenced line cached in the M state.
+.It Li SNP_RESP_TO_REMOTE_HOME.HITM
+.Pq Event 07H , Umask 24H
+Number of HITM snoop responses to a remote home
+.It Li L3_HITS.READ
+.Pq Event 08H , Umask 01H
+Number of code read, data read and RFO requests that hit in the L3
+.It Li L3_HITS.WRITE
+.Pq Event 08H , Umask 02H
+Number of writeback requests that hit in the L3. Writebacks from the cores
+will always result in L3 hits due to the inclusive property of the L3.
+.It Li L3_HITS.PROBE
+.Pq Event 08H , Umask 04H
+Number of snoops from IOH or remote sockets that hit in the L3.
+.It Li L3_HITS.ANY
+.Pq Event 08H , Umask 03H
+Number of reads and writes that hit the L3.
+.It Li L3_MISS.READ
+.Pq Event 09H , Umask 01H
+Number of code read, data read and RFO requests that miss the L3.
+.It Li L3_MISS.WRITE
+.Pq Event 09H , Umask 02H
+Number of writeback requests that miss the L3. Should always be zero as
+writebacks from the cores will always result in L3 hits due to the inclusive
+property of the L3.
+.It Li L3_MISS.PROBE
+.Pq Event 09H , Umask 04H
+Number of snoops from IOH or remote sockets that miss the L3.
+.It Li L3_MISS.ANY
+.Pq Event 09H , Umask 03H
+Number of reads and writes that miss the L3.
+.It Li L3_LINES_IN.M_STATE
+.Pq Event 0AH , Umask 01H
+Counts the number of L3 lines allocated in M state. The only time a cache
+line is allocated in the M state is when the line was forwarded in M state
+is forwarded due to a Snoop Read Invalidate Own request.
+.It Li L3_LINES_IN.E_STATE
+.Pq Event 0AH , Umask 02H
+Counts the number of L3 lines allocated in E state.
+.It Li L3_LINES_IN.S_STATE
+.Pq Event 0AH , Umask 04H
+Counts the number of L3 lines allocated in S state.
+.It Li L3_LINES_IN.F_STATE
+.Pq Event 0AH , Umask 08H
+Counts the number of L3 lines allocated in F state.
+.It Li L3_LINES_IN.ANY
+.Pq Event 0AH , Umask 0FH
+Counts the number of L3 lines allocated in any state.
+.It Li L3_LINES_OUT.M_STATE
+.Pq Event 0BH , Umask 01H
+Counts the number of L3 lines victimized that were in the M state. When the
+victim cache line is in M state, the line is written to its home cache agent
+which can be either local or remote.
+.It Li L3_LINES_OUT.E_STATE
+.Pq Event 0BH , Umask 02H
+Counts the number of L3 lines victimized that were in the E state.
+.It Li L3_LINES_OUT.S_STATE
+.Pq Event 0BH , Umask 04H
+Counts the number of L3 lines victimized that were in the S state.
+.It Li L3_LINES_OUT.I_STATE
+.Pq Event 0BH , Umask 08H
+Counts the number of L3 lines victimized that were in the I state.
+.It Li L3_LINES_OUT.F_STATE
+.Pq Event 0BH , Umask 10H
+Counts the number of L3 lines victimized that were in the F state.
+.It Li L3_LINES_OUT.ANY
+.Pq Event 0BH , Umask 1FH
+Counts the number of L3 lines victimized in any state.
+.It Li GQ_SNOOP.GOTO_S
+.Pq Event 0CH , Umask 01H
+Counts the number of remote snoops that have requested a cache line be set
+to the S state.
+.It Li GQ_SNOOP.GOTO_I
+.Pq Event 0CH , Umask 02H
+Counts the number of remote snoops that have requested a cache line be set
+to the I state.
+.It Li GQ_SNOOP.GOTO_S_HIT_E
+.Pq Event 0CH , Umask 04H
+Counts the number of remote snoops that have requested a cache line be set
+to the S state from E state.
+Requires writing MSR 301H with mask = 2H
+.It Li GQ_SNOOP.GOTO_S_HIT_F
+.Pq Event 0CH , Umask 04H
+Counts the number of remote snoops that have requested a cache line be set
+to the S state from F (forward) state.
+Requires writing MSR 301H with mask = 8H
+.It Li GQ_SNOOP.GOTO_S_HIT_M
+.Pq Event 0CH , Umask 04H
+Counts the number of remote snoops that have requested a cache line be set
+to the S state from M state.
+Requires writing MSR 301H with mask = 1H
+.It Li GQ_SNOOP.GOTO_S_HIT_S
+.Pq Event 0CH , Umask 04H
+Counts the number of remote snoops that have requested a cache line be set
+to the S state from S state.
+Requires writing MSR 301H with mask = 4H
+.It Li GQ_SNOOP.GOTO_I_HIT_E
+.Pq Event 0CH , Umask 08H
+Counts the number of remote snoops that have requested a cache line be set
+to the I state from E state.
+Requires writing MSR 301H with mask = 2H
+.It Li GQ_SNOOP.GOTO_I_HIT_F
+.Pq Event 0CH , Umask 08H
+Counts the number of remote snoops that have requested a cache line be set
+to the I state from F (forward) state.
+Requires writing MSR 301H with mask = 8H
+.It Li GQ_SNOOP.GOTO_I_HIT_M
+.Pq Event 0CH , Umask 08H
+Counts the number of remote snoops that have requested a cache line be set
+to the I state from M state.
+Requires writing MSR 301H with mask = 1H
+.It Li GQ_SNOOP.GOTO_I_HIT_S
+.Pq Event 0CH , Umask 08H
+Counts the number of remote snoops that have requested a cache line be set
+to the I state from S state.
+Requires writing MSR 301H with mask = 4H
+.It Li QHL_REQUESTS.IOH_READS
+.Pq Event 20H , Umask 01H
+Counts number of Quickpath Home Logic read requests from the IOH.
+.It Li QHL_REQUESTS.IOH_WRITES
+.Pq Event 20H , Umask 02H
+Counts number of Quickpath Home Logic write requests from the IOH.
+.It Li QHL_REQUESTS.REMOTE_READS
+.Pq Event 20H , Umask 04H
+Counts number of Quickpath Home Logic read requests from a remote socket.
+.It Li QHL_REQUESTS.REMOTE_WRITES
+.Pq Event 20H , Umask 08H
+Counts number of Quickpath Home Logic write requests from a remote socket.
+.It Li QHL_REQUESTS.LOCAL_READS
+.Pq Event 20H , Umask 10H
+Counts number of Quickpath Home Logic read requests from the local socket.
+.It Li QHL_REQUESTS.LOCAL_WRITES
+.Pq Event 20H , Umask 20H
+Counts number of Quickpath Home Logic write requests from the local socket.
+.It Li QHL_CYCLES_FULL.IOH
+.Pq Event 21H , Umask 01H
+Counts uclk cycles all entries in the Quickpath Home Logic IOH are full.
+.It Li QHL_CYCLES_FULL.REMOTE
+.Pq Event 21H , Umask 02H
+Counts uclk cycles all entries in the Quickpath Home Logic remote tracker
+are full.
+.It Li QHL_CYCLES_FULL.LOCAL
+.Pq Event 21H , Umask 04H
+Counts uclk cycles all entries in the Quickpath Home Logic local tracker are
+full.
+.It Li QHL_CYCLES_NOT_EMPTY.IOH
+.Pq Event 22H , Umask 01H
+Counts uclk cycles all entries in the Quickpath Home Logic IOH is busy.
+.It Li QHL_CYCLES_NOT_EMPTY.REMOTE
+.Pq Event 22H , Umask 02H
+Counts uclk cycles all entries in the Quickpath Home Logic remote tracker is
+busy.
+.It Li QHL_CYCLES_NOT_EMPTY.LOCAL
+.Pq Event 22H , Umask 04H
+Counts uclk cycles all entries in the Quickpath Home Logic local tracker is
+busy.
+.It Li QHL_OCCUPANCY.IOH
+.Pq Event 23H , Umask 01H
+QHL IOH tracker allocate to deallocate read occupancy.
+.It Li QHL_OCCUPANCY.REMOTE
+.Pq Event 23H , Umask 02H
+QHL remote tracker allocate to deallocate read occupancy.
+.It Li QHL_OCCUPANCY.LOCAL
+.Pq Event 23H , Umask 04H
+QHL local tracker allocate to deallocate read occupancy.
+.It Li QHL_ADDRESS_CONFLICTS.2WAY
+.Pq Event 24H , Umask 02H
+Counts number of QHL Active Address Table (AAT) entries that saw a max of 2
+conflicts. The AAT is a structure that tracks requests that are in conflict.
+The requests themselves are in the home tracker entries. The count is
+reported when an AAT entry deallocates.
+.It Li QHL_ADDRESS_CONFLICTS.3WAY
+.Pq Event 24H , Umask 04H
+Counts number of QHL Active Address Table (AAT) entries that saw a max of 3
+conflicts. The AAT is a structure that tracks requests that are in conflict.
+The requests themselves are in the home tracker entries. The count is
+reported when an AAT entry deallocates.
+.It Li QHL_CONFLICT_CYCLES.IOH
+.Pq Event 25H , Umask 01H
+Counts cycles the Quickpath Home Logic IOH Tracker contains two or more
+requests with an address conflict. A max of 3 requests can be in conflict.
+.It Li QHL_CONFLICT_CYCLES.REMOTE
+.Pq Event 25H , Umask 02H
+Counts cycles the Quickpath Home Logic Remote Tracker contains two or more
+requests with an address conflict. A max of 3 requests can be in conflict.
+.It Li QHL_CONFLICT_CYCLES.LOCAL
+.Pq Event 25H , Umask 04H
+Counts cycles the Quickpath Home Logic Local Tracker contains two or more
+requests with an address conflict. A max of 3 requests can be in conflict.
+.It Li QHL_TO_QMC_BYPASS
+.Pq Event 26H , Umask 01H
+Counts number or requests to the Quickpath Memory Controller that bypass the
+Quickpath Home Logic. All local accesses can be bypassed. For remote
+requests, only read requests can be bypassed.
+.It Li QMC_ISOC_FULL.READ.CH0
+.Pq Event 28H , Umask 01H
+Counts cycles all the entries in the DRAM channel 0 high priority queue are
+occupied with isochronous read requests.
+.It Li QMC_ISOC_FULL.READ.CH1
+.Pq Event 28H , Umask 02H
+Counts cycles all the entries in the DRAM channel 1high priority queue are
+occupied with isochronous read requests.
+.It Li QMC_ISOC_FULL.READ.CH2
+.Pq Event 28H , Umask 04H
+Counts cycles all the entries in the DRAM channel 2 high priority queue are
+occupied with isochronous read requests.
+.It Li QMC_ISOC_FULL.WRITE.CH0
+.Pq Event 28H , Umask 08H
+Counts cycles all the entries in the DRAM channel 0 high priority queue are
+occupied with isochronous write requests.
+.It Li QMC_ISOC_FULL.WRITE.CH1
+.Pq Event 28H , Umask 10H
+Counts cycles all the entries in the DRAM channel 1 high priority queue are
+occupied with isochronous write requests.
+.It Li QMC_ISOC_FULL.WRITE.CH2
+.Pq Event 28H , Umask 20H
+Counts cycles all the entries in the DRAM channel 2 high priority queue are
+occupied with isochronous write requests.
+.It Li QMC_BUSY.READ.CH0
+.Pq Event 29H , Umask 01H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+read request to DRAM channel 0.
+.It Li QMC_BUSY.READ.CH1
+.Pq Event 29H , Umask 02H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+read request to DRAM channel 1.
+.It Li QMC_BUSY.READ.CH2
+.Pq Event 29H , Umask 04H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+read request to DRAM channel 2.
+.It Li QMC_BUSY.WRITE.CH0
+.Pq Event 29H , Umask 08H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+write request to DRAM channel 0.
+.It Li QMC_BUSY.WRITE.CH1
+.Pq Event 29H , Umask 10H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+write request to DRAM channel 1.
+.It Li QMC_BUSY.WRITE.CH2
+.Pq Event 29H , Umask 20H
+Counts cycles where Quickpath Memory Controller has at least 1 outstanding
+write request to DRAM channel 2.
+.It Li QMC_OCCUPANCY.CH0
+.Pq Event 2AH , Umask 01H
+IMC channel 0 normal read request occupancy.
+.It Li QMC_OCCUPANCY.CH1
+.Pq Event 2AH , Umask 02H
+IMC channel 1 normal read request occupancy.
+.It Li QMC_OCCUPANCY.CH2
+.Pq Event 2AH , Umask 04H
+IMC channel 2 normal read request occupancy.
+.It Li QMC_OCCUPANCY.ANY
+.Pq Event 2AH , Umask 07H
+Normal read request occupancy for any channel.
+.It Li QMC_ISSOC_OCCUPANCY.CH0
+.Pq Event 2BH , Umask 01H
+IMC channel 0 issoc read request occupancy.
+.It Li QMC_ISSOC_OCCUPANCY.CH1
+.Pq Event 2BH , Umask 02H
+IMC channel 1 issoc read request occupancy.
+.It Li QMC_ISSOC_OCCUPANCY.CH2
+.Pq Event 2BH , Umask 04H
+IMC channel 2 issoc read request occupancy.
+.It Li QMC_ISSOC_READS.ANY
+.Pq Event 2BH , Umask 07H
+IMC issoc read request occupancy.
+.It Li QMC_NORMAL_READS.CH0
+.Pq Event 2CH , Umask 01H
+Counts the number of Quickpath Memory Controller channel 0 medium and low
+priority read requests. The QMC channel 0 normal read occupancy divided by
+this count provides the average QMC channel 0 read latency.
+.It Li QMC_NORMAL_READS.CH1
+.Pq Event 2CH , Umask 02H
+Counts the number of Quickpath Memory Controller channel 1 medium and low
+priority read requests. The QMC channel 1 normal read occupancy divided by
+this count provides the average QMC channel 1 read latency.
+.It Li QMC_NORMAL_READS.CH2
+.Pq Event 2CH , Umask 04H
+Counts the number of Quickpath Memory Controller channel 2 medium and low
+priority read requests. The QMC channel 2 normal read occupancy divided by
+this count provides the average QMC channel 2 read latency.
+.It Li QMC_NORMAL_READS.ANY
+.Pq Event 2CH , Umask 07H
+Counts the number of Quickpath Memory Controller medium and low priority
+read requests. The QMC normal read occupancy divided by this count provides
+the average QMC read latency.
+.It Li QMC_HIGH_PRIORITY_READS.CH0
+.Pq Event 2DH , Umask 01H
+Counts the number of Quickpath Memory Controller channel 0 high priority
+isochronous read requests.
+.It Li QMC_HIGH_PRIORITY_READS.CH1
+.Pq Event 2DH , Umask 02H
+Counts the number of Quickpath Memory Controller channel 1 high priority
+isochronous read requests.
+.It Li QMC_HIGH_PRIORITY_READS.CH2
+.Pq Event 2DH , Umask 04H
+Counts the number of Quickpath Memory Controller channel 2 high priority
+isochronous read requests.
+.It Li QMC_HIGH_PRIORITY_READS.ANY
+.Pq Event 2DH , Umask 07H
+Counts the number of Quickpath Memory Controller high priority isochronous
+read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.CH0
+.Pq Event 2EH , Umask 01H
+Counts the number of Quickpath Memory Controller channel 0 critical priority
+isochronous read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.CH1
+.Pq Event 2EH , Umask 02H
+Counts the number of Quickpath Memory Controller channel 1 critical priority
+isochronous read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.CH2
+.Pq Event 2EH , Umask 04H
+Counts the number of Quickpath Memory Controller channel 2 critical priority
+isochronous read requests.
+.It Li QMC_CRITICAL_PRIORITY_READS.ANY
+.Pq Event 2EH , Umask 07H
+Counts the number of Quickpath Memory Controller critical priority
+isochronous read requests.
+.It Li QMC_WRITES.FULL.CH0
+.Pq Event 2FH , Umask 01H
+Counts number of full cache line writes to DRAM channel 0.
+.It Li QMC_WRITES.FULL.CH1
+.Pq Event 2FH , Umask 02H
+Counts number of full cache line writes to DRAM channel 1.
+.It Li QMC_WRITES.FULL.CH2
+.Pq Event 2FH , Umask 04H
+Counts number of full cache line writes to DRAM channel 2.
+.It Li QMC_WRITES.FULL.ANY
+.Pq Event 2FH , Umask 07H
+Counts number of full cache line writes to DRAM.
+.It Li QMC_WRITES.PARTIAL.CH0
+.Pq Event 2FH , Umask 08H
+Counts number of partial cache line writes to DRAM channel 0.
+.It Li QMC_WRITES.PARTIAL.CH1
+.Pq Event 2FH , Umask 10H
+Counts number of partial cache line writes to DRAM channel 1.
+.It Li QMC_WRITES.PARTIAL.CH2
+.Pq Event 2FH , Umask 20H
+Counts number of partial cache line writes to DRAM channel 2.
+.It Li QMC_WRITES.PARTIAL.ANY
+.Pq Event 2FH , Umask 38H
+Counts number of partial cache line writes to DRAM.
+.It Li QMC_CANCEL.CH0
+.Pq Event 30H , Umask 01H
+Counts number of DRAM channel 0 cancel requests.
+.It Li QMC_CANCEL.CH1
+.Pq Event 30H , Umask 02H
+Counts number of DRAM channel 1 cancel requests.
+.It Li QMC_CANCEL.CH2
+.Pq Event 30H , Umask 04H
+Counts number of DRAM channel 2 cancel requests.
+.It Li QMC_CANCEL.ANY
+.Pq Event 30H , Umask 07H
+Counts number of DRAM cancel requests.
+.It Li QMC_PRIORITY_UPDATES.CH0
+.Pq Event 31H , Umask 01H
+Counts number of DRAM channel 0 priority updates. A priority update occurs
+when an ISOC high or critical request is received by the QHL and there is a
+matching request with normal priority that has already been issued to the
+QMC. In this instance, the QHL will send a priority update to QMC to
+expedite the request.
+.It Li QMC_PRIORITY_UPDATES.CH1
+.Pq Event 31H , Umask 02H
+Counts number of DRAM channel 1 priority updates. A priority update occurs
+when an ISOC high or critical request is received by the QHL and there is a
+matching request with normal priority that has already been issued to the
+QMC. In this instance, the QHL will send a priority update to QMC to
+expedite the request.
+.It Li QMC_PRIORITY_UPDATES.CH2
+.Pq Event 31H , Umask 04H
+Counts number of DRAM channel 2 priority updates. A priority update occurs
+when an ISOC high or critical request is received by the QHL and there is a
+matching request with normal priority that has already been issued to the
+QMC. In this instance, the QHL will send a priority update to QMC to
+expedite the request.
+.It Li QMC_PRIORITY_UPDATES.ANY
+.Pq Event 31H , Umask 07H
+Counts number of DRAM priority updates. A priority update occurs when an
+ISOC high or critical request is received by the QHL and there is a matching
+request with normal priority that has already been issued to the QMC. In
+this instance, the QHL will send a priority update to QMC to expedite the
+request.
+.It Li IMC_RETRY.CH0
+.Pq Event 32H , Umask 01H
+Counts number of IMC DRAM channel 0 retries. DRAM retry only occurs when
+configured in RAS mode.
+.It Li IMC_RETRY.CH1
+.Pq Event 32H , Umask 02H
+Counts number of IMC DRAM channel 1 retries. DRAM retry only occurs when
+configured in RAS mode.
+.It Li IMC_RETRY.CH2
+.Pq Event 32H , Umask 04H
+Counts number of IMC DRAM channel 2 retries. DRAM retry only occurs when
+configured in RAS mode.
+.It Li IMC_RETRY.ANY
+.Pq Event 32H , Umask 07H
+Counts number of IMC DRAM retries from any channel. DRAM retry only occurs
+when configured in RAS mode.
+.It Li QHL_FRC_ACK_CNFLTS.IOH
+.Pq Event 33H , Umask 01H
+Counts number of Force Acknowledge Conflict messages sent by the Quickpath
+Home Logic to the IOH.
+.It Li QHL_FRC_ACK_CNFLTS.REMOTE
+.Pq Event 33H , Umask 02H
+Counts number of Force Acknowledge Conflict messages sent by the Quickpath
+Home Logic to the remote home.
+.It Li QHL_FRC_ACK_CNFLTS.LOCAL
+.Pq Event 33H , Umask 04H
+Counts number of Force Acknowledge Conflict messages sent by the Quickpath
+Home Logic to the local home.
+.It Li QHL_FRC_ACK_CNFLTS.ANY
+.Pq Event 33H , Umask 07H
+Counts number of Force Acknowledge Conflict messages sent by the Quickpath
+Home Logic.
+.It Li QHL_SLEEPS.IOH_ORDER
+.Pq Event 34H , Umask 01H
+Counts number of occurrences a request was put to sleep due to IOH ordering
+(write after read) conflicts. While in the sleep state, the request is not
+eligible to be scheduled to the QMC.
+.It Li QHL_SLEEPS.REMOTE_ORDER
+.Pq Event 34H , Umask 02H
+Counts number of occurrences a request was put to sleep due to remote socket
+ordering (write after read) conflicts. While in the sleep state, the request
+is not eligible to be scheduled to the QMC.
+.It Li QHL_SLEEPS.LOCAL_ORDER
+.Pq Event 34H , Umask 04H
+Counts number of occurrences a request was put to sleep due to local socket
+ordering (write after read) conflicts. While in the sleep state, the request
+is not eligible to be scheduled to the QMC.
+.It Li QHL_SLEEPS.IOH_CONFLICT
+.Pq Event 34H , Umask 08H
+Counts number of occurrences a request was put to sleep due to IOH address
+conflicts. While in the sleep state, the request is not eligible to be
+scheduled to the QMC.
+.It Li QHL_SLEEPS.REMOTE_CONFLICT
+.Pq Event 34H , Umask 10H
+Counts number of occurrences a request was put to sleep due to remote socket
+address conflicts. While in the sleep state, the request is not eligible to
+be scheduled to the QMC.
+.It Li QHL_SLEEPS.LOCAL_CONFLICT
+.Pq Event 34H , Umask 20H
+Counts number of occurrences a request was put to sleep due to local socket
+address conflicts. While in the sleep state, the request is not eligible to
+be scheduled to the QMC.
+.It Li ADDR_OPCODE_MATCH.IOH
+.Pq Event 35H , Umask 01H
+Counts number of requests from the IOH, address/opcode of request is
+qualified by mask value written to MSR 396H. The following mask values are
+supported:
+0: NONE 40000000_00000000H:RSPFWDI 40001A00_00000000H:RSPFWDS
+40001D00_00000000H:RSPIWB
+Match opcode/addres s by writing MSR 396H with mask supported mask value
+.It Li ADDR_OPCODE_MATCH.REMOTE
+.Pq Event 35H , Umask 02H
+Counts number of requests from the remote socket, address/opcode of request
+is qualified by mask value written to MSR 396H. The following mask values
+are supported:
+0: NONE 40000000_00000000H:RSPFWDI 40001A00_00000000H:RSPFWDS
+40001D00_00000000H:RSPIWB
+Match opcode/addres s by writing MSR 396H with mask supported mask value
+.It Li ADDR_OPCODE_MATCH.LOCAL
+.Pq Event 35H , Umask 04H
+Counts number of requests from the local socket, address/opcode of request
+is qualified by mask value written to MSR 396H. The following mask values
+are supported:
+0: NONE 40000000_00000000H:RSPFWDI 40001A00_00000000H:RSPFWDS
+40001D00_00000000H:RSPIWB
+Match opcode/addres s by writing MSR 396H with mask supported mask value
+.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0
+.Pq Event 40H , Umask 01H
+Counts cycles the Quickpath outbound link 0 HOME virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0
+.Pq Event 40H , Umask 02H
+Counts cycles the Quickpath outbound link 0 SNOOP virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0
+.Pq Event 40H , Umask 04H
+Counts cycles the Quickpath outbound link 0 non-data response virtual
+channel is stalled due to lack of a VNA and VN0 credit. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1
+.Pq Event 40H , Umask 08H
+Counts cycles the Quickpath outbound link 1 HOME virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1
+.Pq Event 40H , Umask 10H
+Counts cycles the Quickpath outbound link 1 SNOOP virtual channel is stalled
+due to lack of a VNA and VN0 credit. Note that this event does not filter
+out when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1
+.Pq Event 40H , Umask 20H
+Counts cycles the Quickpath outbound link 1 non-data response virtual
+channel is stalled due to lack of a VNA and VN0 credit. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_0
+.Pq Event 40H , Umask 07H
+Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
+to lack of a VNA and VN0 credit. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_1
+.Pq Event 40H , Umask 38H
+Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
+to lack of a VNA and VN0 credit. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0
+.Pq Event 41H , Umask 01H
+Counts cycles the Quickpath outbound link 0 Data ResponSe virtual channel is
+stalled due to lack of VNA and VN0 credits. Note that this event does not
+filter out when a flit would not have been selected for arbitration because
+another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0
+.Pq Event 41H , Umask 02H
+Counts cycles the Quickpath outbound link 0 Non-Coherent Bypass virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0
+.Pq Event 41H , Umask 04H
+Counts cycles the Quickpath outbound link 0 Non-Coherent Standard virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1
+.Pq Event 41H , Umask 08H
+Counts cycles the Quickpath outbound link 1 Data ResponSe virtual channel is
+stalled due to lack of VNA and VN0 credits. Note that this event does not
+filter out when a flit would not have been selected for arbitration because
+another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1
+.Pq Event 41H , Umask 10H
+Counts cycles the Quickpath outbound link 1 Non-Coherent Bypass virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1
+.Pq Event 41H , Umask 20H
+Counts cycles the Quickpath outbound link 1 Non-Coherent Standard virtual
+channel is stalled due to lack of VNA and VN0 credits. Note that this event
+does not filter out when a flit would not have been selected for arbitration
+because another virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_0
+.Pq Event 41H , Umask 07H
+Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
+to lack of VNA and VN0 credits. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_1
+.Pq Event 41H , Umask 38H
+Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
+to lack of VNA and VN0 credits. Note that this event does not filter out
+when a flit would not have been selected for arbitration because another
+virtual channel is getting arbitrated.
+.It Li QPI_TX_HEADER.FULL.LINK_0
+.Pq Event 42H , Umask 01H
+Number of cycles that the header buffer in the Quickpath Interface outbound
+link 0 is full.
+.It Li QPI_TX_HEADER.BUSY.LINK_0
+.Pq Event 42H , Umask 02H
+Number of cycles that the header buffer in the Quickpath Interface outbound
+link 0 is busy.
+.It Li QPI_TX_HEADER.FULL.LINK_1
+.Pq Event 42H , Umask 04H
+Number of cycles that the header buffer in the Quickpath Interface outbound
+link 1 is full.
+.It Li QPI_TX_HEADER.BUSY.LINK_1
+.Pq Event 42H , Umask 08H
+Number of cycles that the header buffer in the Quickpath Interface outbound
+link 1 is busy.
+.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0
+.Pq Event 43H , Umask 01H
+Number of cycles that snoop packets incoming to the Quickpath Interface link
+0 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
+does not have any available entries.
+.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1
+.Pq Event 43H , Umask 02H
+Number of cycles that snoop packets incoming to the Quickpath Interface link
+1 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
+does not have any available entries.
+.It Li DRAM_OPEN.CH0
+.Pq Event 60H , Umask 01H
+Counts number of DRAM Channel 0 open commands issued either for read or
+write. To read or write data, the referenced DRAM page must first be opened.
+.It Li DRAM_OPEN.CH1
+.Pq Event 60H , Umask 02H
+Counts number of DRAM Channel 1 open commands issued either for read or
+write. To read or write data, the referenced DRAM page must first be opened.
+.It Li DRAM_OPEN.CH2
+.Pq Event 60H , Umask 04H
+Counts number of DRAM Channel 2 open commands issued either for read or
+write. To read or write data, the referenced DRAM page must first be opened.
+.It Li DRAM_PAGE_CLOSE.CH0
+.Pq Event 61H , Umask 01H
+DRAM channel 0 command issued to CLOSE a page due to page idle timer
+expiration. Closing a page is done by issuing a precharge.
+.It Li DRAM_PAGE_CLOSE.CH1
+.Pq Event 61H , Umask 02H
+DRAM channel 1 command issued to CLOSE a page due to page idle timer
+expiration. Closing a page is done by issuing a precharge.
+.It Li DRAM_PAGE_CLOSE.CH2
+.Pq Event 61H , Umask 04H
+DRAM channel 2 command issued to CLOSE a page due to page idle timer
+expiration. Closing a page is done by issuing a precharge.
+.It Li DRAM_PAGE_MISS.CH0
+.Pq Event 62H , Umask 01H
+Counts the number of precharges (PRE) that were issued to DRAM channel 0
+because there was a page miss. A page miss refers to a situation in which a
+page is currently open and another page from the same bank needs to be
+opened. The new page experiences a page miss. Closing of the old page is
+done by issuing a precharge.
+.It Li DRAM_PAGE_MISS.CH1
+.Pq Event 62H , Umask 02H
+Counts the number of precharges (PRE) that were issued to DRAM channel 1
+because there was a page miss. A page miss refers to a situation in which a
+page is currently open and another page from the same bank needs to be
+opened. The new page experiences a page miss. Closing of the old page is
+done by issuing a precharge.
+.It Li DRAM_PAGE_MISS.CH2
+.Pq Event 62H , Umask 04H
+Counts the number of precharges (PRE) that were issued to DRAM channel 2
+because there was a page miss. A page miss refers to a situation in which a
+page is currently open and another page from the same bank needs to be
+opened. The new page experiences a page miss. Closing of the old page is
+done by issuing a precharge.
+.It Li DRAM_READ_CAS.CH0
+.Pq Event 63H , Umask 01H
+Counts the number of times a read CAS command was issued on DRAM channel 0.
+.It Li DRAM_READ_CAS.AUTOPRE_CH0
+.Pq Event 63H , Umask 02H
+Counts the number of times a read CAS command was issued on DRAM channel 0
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_READ_CAS.CH1
+.Pq Event 63H , Umask 04H
+Counts the number of times a read CAS command was issued on DRAM channel 1.
+.It Li DRAM_READ_CAS.AUTOPRE_CH1
+.Pq Event 63H , Umask 08H
+Counts the number of times a read CAS command was issued on DRAM channel 1
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_READ_CAS.CH2
+.Pq Event 63H , Umask 10H
+Counts the number of times a read CAS command was issued on DRAM channel 2.
+.It Li DRAM_READ_CAS.AUTOPRE_CH2
+.Pq Event 63H , Umask 20H
+Counts the number of times a read CAS command was issued on DRAM channel 2
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_WRITE_CAS.CH0
+.Pq Event 64H , Umask 01H
+Counts the number of times a write CAS command was issued on DRAM channel 0.
+.It Li DRAM_WRITE_CAS.AUTOPRE_CH0
+.Pq Event 64H , Umask 02H
+Counts the number of times a write CAS command was issued on DRAM channel 0
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_WRITE_CAS.CH1
+.Pq Event 64H , Umask 04H
+Counts the number of times a write CAS command was issued on DRAM channel 1.
+.It Li DRAM_WRITE_CAS.AUTOPRE_CH1
+.Pq Event 64H , Umask 08H
+Counts the number of times a write CAS command was issued on DRAM channel 1
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_WRITE_CAS.CH2
+.Pq Event 64H , Umask 10H
+Counts the number of times a write CAS command was issued on DRAM channel 2.
+.It Li DRAM_WRITE_CAS.AUTOPRE_CH2
+.Pq Event 64H , Umask 20H
+Counts the number of times a write CAS command was issued on DRAM channel 2
+where the command issued used the auto-precharge (auto page close) mode.
+.It Li DRAM_REFRESH.CH0
+.Pq Event 65H , Umask 01H
+Counts number of DRAM channel 0 refresh commands. DRAM loses data content
+over time. In order to keep correct data content, the data values have to be
+refreshed periodically.
+.It Li DRAM_REFRESH.CH1
+.Pq Event 65H , Umask 02H
+Counts number of DRAM channel 1 refresh commands. DRAM loses data content
+over time. In order to keep correct data content, the data values have to be
+refreshed periodically.
+.It Li DRAM_REFRESH.CH2
+.Pq Event 65H , Umask 04H
+Counts number of DRAM channel 2 refresh commands. DRAM loses data content
+over time. In order to keep correct data content, the data values have to be
+refreshed periodically.
+.It Li DRAM_PRE_ALL.CH0
+.Pq Event 66H , Umask 01H
+Counts number of DRAM Channel 0 precharge-all (PREALL) commands that close
+all open pages in a rank. PREALL is issued when the DRAM needs to be
+refreshed or needs to go into a power down mode.
+.It Li DRAM_PRE_ALL.CH1
+.Pq Event 66H , Umask 02H
+Counts number of DRAM Channel 1 precharge-all (PREALL) commands that close
+all open pages in a rank. PREALL is issued when the DRAM needs to be
+refreshed or needs to go into a power down mode.
+.It Li DRAM_PRE_ALL.CH2
+.Pq Event 66H , Umask 04H
+Counts number of DRAM Channel 2 precharge-all (PREALL) commands that close
+all open pages in a rank. PREALL is issued when the DRAM needs to be
+refreshed or needs to go into a power down mode.
+.It Li DRAM_THERMAL_THROTTLED
+.Pq Event 67H , Umask 01H
+Uncore cycles DRAM was throttled due to its temperature being above the
+thermal throttling threshold.
+.It Li THERMAL_THROTTLING_TEMP.CORE_0
+.Pq Event 80H , Umask 01H
+Cycles that the PCU records that core 0 is above the thermal throttling
+threshold temperature.
+.It Li THERMAL_THROTTLING_TEMP.CORE_1
+.Pq Event 80H , Umask 02H
+Cycles that the PCU records that core 1 is above the thermal throttling
+threshold temperature.
+.It Li THERMAL_THROTTLING_TEMP.CORE_2
+.Pq Event 80H , Umask 04H
+Cycles that the PCU records that core 2 is above the thermal throttling
+threshold temperature.
+.It Li THERMAL_THROTTLING_TEMP.CORE_3
+.Pq Event 80H , Umask 08H
+Cycles that the PCU records that core 3 is above the thermal throttling
+threshold temperature.
+.It Li THERMAL_THROTTLED_TEMP.CORE_0
+.Pq Event 81H , Umask 01H
+Cycles that the PCU records that core 0 is in the power throttled state due
+to cores temperature being above the thermal throttling threshold.
+.It Li THERMAL_THROTTLED_TEMP.CORE_1
+.Pq Event 81H , Umask 02H
+Cycles that the PCU records that core 1 is in the power throttled state due
+to cores temperature being above the thermal throttling threshold.
+.It Li THERMAL_THROTTLED_TEMP.CORE_2
+.Pq Event 81H , Umask 04H
+Cycles that the PCU records that core 2 is in the power throttled state due
+to cores temperature being above the thermal throttling threshold.
+.It Li THERMAL_THROTTLED_TEMP.CORE_3
+.Pq Event 81H , Umask 08H
+Cycles that the PCU records that core 3 is in the power throttled state due
+to cores temperature being above the thermal throttling threshold.
+.It Li PROCHOT_ASSERTION
+.Pq Event 82H , Umask 01H
+Number of system assertions of PROCHOT indicating the entire processor has
+exceeded the thermal limit.
+.It Li THERMAL_THROTTLING_PROCHOT.CORE_0
+.Pq Event 83H , Umask 01H
+Cycles that the PCU records that core 0 is a low power state due to the
+system asserting PROCHOT the entire processor has exceeded the thermal
+limit.
+.It Li THERMAL_THROTTLING_PROCHOT.CORE_1
+.Pq Event 83H , Umask 02H
+Cycles that the PCU records that core 1 is a low power state due to the
+system asserting PROCHOT the entire processor has exceeded the thermal
+limit.
+.It Li THERMAL_THROTTLING_PROCHOT.CORE_2
+.Pq Event 83H , Umask 04H
+Cycles that the PCU records that core 2 is a low power state due to the
+system asserting PROCHOT the entire processor has exceeded the thermal
+limit.
+.It Li THERMAL_THROTTLING_PROCHOT.CORE_3
+.Pq Event 83H , Umask 08H
+Cycles that the PCU records that core 3 is a low power state due to the
+system asserting PROCHOT the entire processor has exceeded the thermal
+limit.
+.It Li TURBO_MODE.CORE_0
+.Pq Event 84H , Umask 01H
+Uncore cycles that core 0 is operating in turbo mode.
+.It Li TURBO_MODE.CORE_1
+.Pq Event 84H , Umask 02H
+Uncore cycles that core 1 is operating in turbo mode.
+.It Li TURBO_MODE.CORE_2
+.Pq Event 84H , Umask 04H
+Uncore cycles that core 2 is operating in turbo mode.
+.It Li TURBO_MODE.CORE_3
+.Pq Event 84H , Umask 08H
+Uncore cycles that core 3 is operating in turbo mode.
+.It Li CYCLES_UNHALTED_L3_FLL_ENABLE
+.Pq Event 85H , Umask 02H
+Uncore cycles that at least one core is unhalted and all L3 ways are
+enabled.
+.It Li CYCLES_UNHALTED_L3_FLL_DISABLE
+.Pq Event 86H , Umask 01H
+Uncore cycles that at least one core is unhalted and all L3 ways are
+disabled.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmere 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
diff --git a/lib/libpmc/pmc.xscale.3 b/lib/libpmc/pmc.xscale.3
index fc9d16e..3cb64c3 100644
--- a/lib/libpmc/pmc.xscale.3
+++ b/lib/libpmc/pmc.xscale.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2009 Rui Paulo. All rights reserved.
+.\" Copyright (c) 2009, 2010 Rui Paulo. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -9,7 +9,7 @@
.\" 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 Joseph Koshy ``as is'' and
+.\" This software is provided by Rui Paulo ``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 Joseph Koshy be liable
@@ -37,3 +37,120 @@ family CPUs
.Sh SYNOPSIS
.In pmc.h
.Sh DESCRIPTION
+.Tn Intel XScale
+CPUs are ARM CPUs based on the ARMv5e core.
+.Pp
+Second generation cores have 2 counters, while third generation cores
+have 4 counters.
+Third generation cores also have an increased number of PMC events.
+.Pp
+.Tn Intel XScale
+PMCs are documented in
+.Rs
+.%B "3rd Generation Intel XScale Microarchitecture Developer's Manual"
+.%D May 2007
+.Re
+.Ss Event Specifiers (Programmable PMCs)
+.Tn Intel XScale
+programmable PMCs support the following events:
+.Bl -tag -width indent
+.It Li IC_FETCH
+External memory fetch due to L1 instruction cache miss.
+.It Li IC_MISS
+Instruction cache or TLB miss.
+.It Li DATA_DEPENDENCY_STALLED
+A data dependency stalled
+.It Li ITLB_MISS
+Instruction TLB miss.
+.It Li DTLB_MISS
+Data TLB miss.
+.It Li BRANCH_RETIRED
+Branch instruction retired (executed).
+.It Li BRANCH_MISPRED
+Branch mispredicted.
+.It Li INSTR_RETIRED
+Instructions retired (executed).
+.It Li DC_FULL_CYCLE
+L1 data cache buffer full stall.
+Event occurs on every cycle the
+condition is present.
+.It Li DC_FULL_CONTIG
+L1 data cache buffer full stall.
+Event occurs once for each contiguous sequence of this type of stall.
+.It Li DC_ACCESS
+L1 data cache access, not including cache operations.
+.It Li DC_MISS
+L1 data cache miss, not including cache operations.
+.It Li DC_WRITEBACK
+L1 data cache write-back.
+Occurs for each cache line that's written back from the cache.
+.It Li PC_CHANGE
+Software changed the program counter.
+.It Li BRANCH_RETIRED_ALL
+Branch instruction retired (executed).
+This event counts all branch instructions, indirect or direct.
+.It Li INSTR_CYCLE
+Count the number of microarchitecture cycles each instruction requires
+to issue.
+.It Li CP_STALL
+Coprocessor stalled the instruction pipeline.
+.It Li PC_CHANGE_ALL
+Software changed the program counter (includes exceptions).
+.It Li PIPELINE_FLUSH
+Pipeline flushes due to mispredictions or exceptions.
+.It Li BACKEND_STALL
+Backend stalled the instruction pipeline.
+.It Li MULTIPLIER_USE
+Multiplier used.
+.It Li MULTIPLIER_STALLED
+Multiplier stalled the instruction pipeline.
+.It Li DATA_CACHE_STALLED
+Data cache stalled the instruction pipeline.
+.It Li L2_CACHE_REQ
+L2 cache request, not inclusing cache operations.
+.It Li L2_CACHE_MISS
+L2 cache miss, not including cache operations.
+.It Li ADDRESS_BUS_TRANS
+Address bus transaction.
+.It Li SELF_ADDRESS_BUS_TRANS
+Self initiated address bus transaction.
+.It Li DATA_BUS_TRANS
+Data bus transaction.
+.El
+.Ss Event Name Aliases
+The following table shows the mapping between the PMC-independent
+aliases supported by
+.Lb libpmc
+and the underlying hardware events used.
+.Bl -column "branch-mispredicts" "BRANCH_MISPRED"
+.It Em Alias Ta Em Event Ta
+.It Li branches Ta Li BRANCH_RETIRED Ta
+.It Li branch-mispredicts Ta Li BRANCH_MISPRED Ta
+.It Li dc-misses Ta Li DC_MISS Ta
+.It Li ic-misses Ta Li IC_MISS Ta
+.It Li instructions Ta Li INSTR_RETIRED Ta
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh CAVEATS
+The Intel XScale code does not yet support sampling.
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+Intel XScale support first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
+.Pp
+Intel XScale support was added by
+.An "Rui Paulo"
+.Aq rpaulo@FreeBSD.org .
diff --git a/lib/libpmc/pmc_allocate.3 b/lib/libpmc/pmc_allocate.3
index 03f9078..6a2a6c0 100644
--- a/lib/libpmc/pmc_allocate.3
+++ b/lib/libpmc/pmc_allocate.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 22, 2008
-.Os
.Dt PMC_ALLOCATE 3
+.Os
.Sh NAME
.Nm pmc_allocate ,
.Nm pmc_release
diff --git a/lib/libpmc/pmc_attach.3 b/lib/libpmc/pmc_attach.3
index be340a7..ca72511 100644
--- a/lib/libpmc/pmc_attach.3
+++ b/lib/libpmc/pmc_attach.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 25, 2007
-.Os
.Dt PMC_ATTACH 3
+.Os
.Sh NAME
.Nm pmc_attach ,
.Nm pmc_detach
diff --git a/lib/libpmc/pmc_capabilities.3 b/lib/libpmc/pmc_capabilities.3
index 0d1a99d..6aee17f 100644
--- a/lib/libpmc/pmc_capabilities.3
+++ b/lib/libpmc/pmc_capabilities.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 22, 2008
-.Os
.Dt PMC_CAPABILITIES 3
+.Os
.Sh NAME
.Nm pmc_capabilities ,
.Nm pmc_cpuinfo ,
diff --git a/lib/libpmc/pmc_configure_logfile.3 b/lib/libpmc/pmc_configure_logfile.3
index 95c6c28..a33688c 100644
--- a/lib/libpmc/pmc_configure_logfile.3
+++ b/lib/libpmc/pmc_configure_logfile.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 24, 2007
-.Os
.Dt PMC_CONFIGURE_LOGFILE 3
+.Os
.Sh NAME
.Nm pmc_configure_logfile ,
.Nm pmc_flush_logfile ,
diff --git a/lib/libpmc/pmc_disable.3 b/lib/libpmc/pmc_disable.3
index cd837d3..a6902ff 100644
--- a/lib/libpmc/pmc_disable.3
+++ b/lib/libpmc/pmc_disable.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 22, 2008
-.Os
.Dt PMC_ENABLE 3
+.Os
.Sh NAME
.Nm pmc_disable ,
.Nm pmc_enable
diff --git a/lib/libpmc/pmc_event_names_of_class.3 b/lib/libpmc/pmc_event_names_of_class.3
index fc1c63c..5b2c89d 100644
--- a/lib/libpmc/pmc_event_names_of_class.3
+++ b/lib/libpmc/pmc_event_names_of_class.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 23, 2007
-.Os
.Dt PMC_EVENT_NAMES_OF_CLASS 3
+.Os
.Sh NAME
.Nm pmc_event_names_of_class
.Nd return a list of event names supported by a PMC class.
diff --git a/lib/libpmc/pmc_get_driver_stats.3 b/lib/libpmc/pmc_get_driver_stats.3
index d8bfe23..fa214b3 100644
--- a/lib/libpmc/pmc_get_driver_stats.3
+++ b/lib/libpmc/pmc_get_driver_stats.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 25, 2007
-.Os
.Dt PMC_GET_DRIVER_STATS 3
+.Os
.Sh NAME
.Nm pmc_get_driver_stats
.Nd retrieve driver statistics
diff --git a/lib/libpmc/pmc_get_msr.3 b/lib/libpmc/pmc_get_msr.3
index 6a2b942..6361d3a 100644
--- a/lib/libpmc/pmc_get_msr.3
+++ b/lib/libpmc/pmc_get_msr.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 25, 2007
-.Os
.Dt PMC_GET_MSR 3
+.Os
.Sh NAME
.Nm pmc_get_msr
.Nd x86 architecture-specific PMC operations
diff --git a/lib/libpmc/pmc_init.3 b/lib/libpmc/pmc_init.3
index 5113b4a..655bfb6 100644
--- a/lib/libpmc/pmc_init.3
+++ b/lib/libpmc/pmc_init.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 24, 2007
-.Os
.Dt PMC_INIT 3
+.Os
.Sh NAME
.Nm pmc_init
.Nd initialize library
diff --git a/lib/libpmc/pmc_name_of_capability.3 b/lib/libpmc/pmc_name_of_capability.3
index 53ddfdf..78efeaf 100644
--- a/lib/libpmc/pmc_name_of_capability.3
+++ b/lib/libpmc/pmc_name_of_capability.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 24, 2007
-.Os
.Dt PMC_NAME_OF_CAPABILITY 3
+.Os
.Sh NAME
.Nm pmc_name_of_capability ,
.Nm pmc_name_of_class ,
diff --git a/lib/libpmc/pmc_read.3 b/lib/libpmc/pmc_read.3
index d9fa3ce..8d718ca 100644
--- a/lib/libpmc/pmc_read.3
+++ b/lib/libpmc/pmc_read.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 25, 2007
-.Os
.Dt PMC_READ 3
+.Os
.Sh NAME
.Nm pmc_read ,
.Nm pmc_rw ,
diff --git a/lib/libpmc/pmc_set.3 b/lib/libpmc/pmc_set.3
index a9e438a..e8d6597 100644
--- a/lib/libpmc/pmc_set.3
+++ b/lib/libpmc/pmc_set.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 25, 2007
-.Os
.Dt PMC_SET 3
+.Os
.Sh NAME
.Nm pmc_set
.Nd set the reload count of a sampling PMC
diff --git a/lib/libpmc/pmc_start.3 b/lib/libpmc/pmc_start.3
index 7fb474a..2272122 100644
--- a/lib/libpmc/pmc_start.3
+++ b/lib/libpmc/pmc_start.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 22, 2008
-.Os
.Dt PMC_START 3
+.Os
.Sh NAME
.Nm pmc_start ,
.Nm pmc_stop
diff --git a/lib/libpmc/pmclog.3 b/lib/libpmc/pmclog.3
index 688445a..4438f10 100644
--- a/lib/libpmc/pmclog.3
+++ b/lib/libpmc/pmclog.3
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd March 26, 2006
-.Os
.Dt PMCLOG 3
+.Os
.Sh NAME
.Nm pmclog_open ,
.Nm pmclog_close ,
diff --git a/lib/librpcsec_gss/rpcsec_gss.3 b/lib/librpcsec_gss/rpcsec_gss.3
index dfc95ec..e688afb 100644
--- a/lib/librpcsec_gss/rpcsec_gss.3
+++ b/lib/librpcsec_gss/rpcsec_gss.3
@@ -173,6 +173,7 @@ typedef struct {
#define RPC_GSS_ER_SUCCESS 0 /* no error */
#define RPC_GSS_ER_SYSTEMERROR 1 /* system error */
.Ed
+.El
.Sh INDEX
.Bl -tag -width "MMMM"
.It Xr rpc_gss_seccreate 3
diff --git a/lib/libsm/Makefile b/lib/libsm/Makefile
index ae76e91..ce590d7 100644
--- a/lib/libsm/Makefile
+++ b/lib/libsm/Makefile
@@ -7,6 +7,7 @@ SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail
CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
CFLAGS+=-DNEWDB -DNIS -DMAP_REGEX -DNOT_SENDMAIL
+CFLAGS+=-DHAVE_NANOSLEEP
.if ${MK_INET6_SUPPORT} != "no"
CFLAGS+=-DNETINET6
diff --git a/lib/libstand/assert.c b/lib/libstand/assert.c
index b424358..8eec63a 100644
--- a/lib/libstand/assert.c
+++ b/lib/libstand/assert.c
@@ -35,10 +35,10 @@ void
__assert(const char *func, const char *file, int line, const char *expression)
{
if (func == NULL)
- printf("Assertion failed: (%s), file %s, line %d.\n",
+ panic("Assertion failed: (%s), file %s, line %d.\n",
expression, file, line);
else
- printf("Assertion failed: (%s), function %s, file %s, line "
- "%d.\n", expression, func, file, line);
- exit();
+ panic(
+ "Assertion failed: (%s), function %s, file %s, line %d.\n",
+ expression, func, file, line);
}
diff --git a/lib/libstand/bzipfs.c b/lib/libstand/bzipfs.c
index 1b2e9eb..b017608 100644
--- a/lib/libstand/bzipfs.c
+++ b/lib/libstand/bzipfs.c
@@ -81,14 +81,6 @@ struct fs_ops bzipfs_fsops = {
};
#endif
-#if 0
-void *
-calloc(int items, size_t size)
-{
- return(malloc(items * size));
-}
-#endif
-
static int
bzf_fill(struct bz_file *bzf)
{
diff --git a/lib/libstand/gzipfs.c b/lib/libstand/gzipfs.c
index 9ff7985..9b51e2d 100644
--- a/lib/libstand/gzipfs.c
+++ b/lib/libstand/gzipfs.c
@@ -62,14 +62,6 @@ struct fs_ops gzipfs_fsops = {
null_readdir
};
-#if 0
-void *
-calloc(int items, size_t size)
-{
- return(malloc(items * size));
-}
-#endif
-
static int
zf_fill(struct z_file *zf)
{
diff --git a/lib/libthr/libthr.3 b/lib/libthr/libthr.3
index 87e5e64..696da17 100644
--- a/lib/libthr/libthr.3
+++ b/lib/libthr/libthr.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd October 19, 2007
-.Os
.Dt LIBTHR 3
+.Os
.Sh NAME
.Nm libthr
.Nd "1:1 POSIX threads library"
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile
index c9232ef..1dfc242 100644
--- a/lib/libufs/Makefile
+++ b/lib/libufs/Makefile
@@ -3,7 +3,7 @@
LIB= ufs
SHLIBDIR?= /lib
-SRCS= block.c cgroup.c inode.c sblock.c type.c
+SRCS= block.c cgroup.c inode.c sblock.c type.c ffs_subr.c ffs_tables.c
INCS= libufs.h
MAN= bread.3 cgread.3 libufs.3 sbread.3 ufs_disk_close.3
@@ -16,8 +16,11 @@ MLINKS+= ufs_disk_close.3 ufs_disk_fillout.3
MLINKS+= ufs_disk_close.3 ufs_disk_fillout_blank.3
MLINKS+= ufs_disk_close.3 ufs_disk_write.3
-WARNS?= 3
+.PATH: ${.CURDIR}/../../sys/ufs/ffs
+WARNS?= 2
+
+DEBUG_FLAGS = -g
CFLAGS+= -D_LIBUFS
.if defined(LIBUFS_DEBUG)
CFLAGS+= -D_LIBUFS_DEBUGGING
diff --git a/lib/libufs/cgroup.c b/lib/libufs/cgroup.c
index 28e5ea8..b0cb4a7 100644
--- a/lib/libufs/cgroup.c
+++ b/lib/libufs/cgroup.c
@@ -40,11 +40,143 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libufs.h>
+ufs2_daddr_t
+cgballoc(struct uufsd *disk)
+{
+ u_int8_t *blksfree;
+ struct cg *cgp;
+ struct fs *fs;
+ long bno;
+
+ fs = &disk->d_fs;
+ cgp = &disk->d_cg;
+ blksfree = cg_blksfree(cgp);
+ for (bno = 0; bno < fs->fs_fpg / fs->fs_frag; bno++)
+ if (ffs_isblock(fs, blksfree, bno))
+ goto gotit;
+ return (0);
+gotit:
+ fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--;
+ ffs_clrblock(fs, blksfree, (long)bno);
+ ffs_clusteracct(fs, cgp, bno, -1);
+ cgp->cg_cs.cs_nbfree--;
+ fs->fs_cstotal.cs_nbfree--;
+ fs->fs_fmod = 1;
+ return (cgbase(fs, cgp->cg_cgx) + blkstofrags(fs, bno));
+}
+
+int
+cgbfree(struct uufsd *disk, ufs2_daddr_t bno, long size)
+{
+ u_int8_t *blksfree;
+ struct fs *fs;
+ struct cg *cgp;
+ ufs1_daddr_t fragno, cgbno;
+ int i, cg, blk, frags, bbase;
+
+ fs = &disk->d_fs;
+ cg = dtog(fs, bno);
+ if (cgread1(disk, cg) != 1)
+ return (-1);
+ cgp = &disk->d_cg;
+ cgbno = dtogd(fs, bno);
+ blksfree = cg_blksfree(cgp);
+ if (size == fs->fs_bsize) {
+ fragno = fragstoblks(fs, cgbno);
+ ffs_setblock(fs, blksfree, fragno);
+ ffs_clusteracct(fs, cgp, fragno, 1);
+ cgp->cg_cs.cs_nbfree++;
+ fs->fs_cstotal.cs_nbfree++;
+ fs->fs_cs(fs, cg).cs_nbfree++;
+ } else {
+ bbase = cgbno - fragnum(fs, cgbno);
+ /*
+ * decrement the counts associated with the old frags
+ */
+ blk = blkmap(fs, blksfree, bbase);
+ ffs_fragacct(fs, blk, cgp->cg_frsum, -1);
+ /*
+ * deallocate the fragment
+ */
+ frags = numfrags(fs, size);
+ for (i = 0; i < frags; i++)
+ setbit(blksfree, cgbno + i);
+ cgp->cg_cs.cs_nffree += i;
+ fs->fs_cstotal.cs_nffree += i;
+ fs->fs_cs(fs, cg).cs_nffree += i;
+ /*
+ * add back in counts associated with the new frags
+ */
+ blk = blkmap(fs, blksfree, bbase);
+ ffs_fragacct(fs, blk, cgp->cg_frsum, 1);
+ /*
+ * if a complete block has been reassembled, account for it
+ */
+ fragno = fragstoblks(fs, bbase);
+ if (ffs_isblock(fs, blksfree, fragno)) {
+ cgp->cg_cs.cs_nffree -= fs->fs_frag;
+ fs->fs_cstotal.cs_nffree -= fs->fs_frag;
+ fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag;
+ ffs_clusteracct(fs, cgp, fragno, 1);
+ cgp->cg_cs.cs_nbfree++;
+ fs->fs_cstotal.cs_nbfree++;
+ fs->fs_cs(fs, cg).cs_nbfree++;
+ }
+ }
+ return cgwrite(disk);
+}
+
+ino_t
+cgialloc(struct uufsd *disk)
+{
+ struct ufs2_dinode *dp2;
+ u_int8_t *inosused;
+ struct cg *cgp;
+ struct fs *fs;
+ ino_t ino;
+ int i;
+
+ fs = &disk->d_fs;
+ cgp = &disk->d_cg;
+ inosused = cg_inosused(cgp);
+ for (ino = 0; ino < fs->fs_ipg / NBBY; ino++)
+ if (isclr(inosused, ino))
+ goto gotit;
+ return (0);
+gotit:
+ if (fs->fs_magic == FS_UFS2_MAGIC &&
+ ino + INOPB(fs) > cgp->cg_initediblk &&
+ cgp->cg_initediblk < cgp->cg_niblk) {
+ char block[MAXBSIZE];
+ bzero(block, (int)fs->fs_bsize);
+ dp2 = (struct ufs2_dinode *)&block;
+ for (i = 0; i < INOPB(fs); i++) {
+ dp2->di_gen = arc4random() / 2 + 1;
+ dp2++;
+ }
+ if (bwrite(disk, ino_to_fsba(fs,
+ cgp->cg_cgx * fs->fs_ipg + cgp->cg_initediblk),
+ block, fs->fs_bsize))
+ return (0);
+ cgp->cg_initediblk += INOPB(fs);
+ }
+
+ setbit(inosused, ino);
+ cgp->cg_irotor = ino;
+ cgp->cg_cs.cs_nifree--;
+ fs->fs_cstotal.cs_nifree--;
+ fs->fs_cs(fs, cgp->cg_cgx).cs_nifree--;
+ fs->fs_fmod = 1;
+
+ return (ino + (cgp->cg_cgx * fs->fs_ipg));
+}
+
int
cgread(struct uufsd *disk)
{
@@ -55,14 +187,12 @@ int
cgread1(struct uufsd *disk, int c)
{
struct fs *fs;
- off_t ccg;
fs = &disk->d_fs;
if ((unsigned)c >= fs->fs_ncg) {
return (0);
}
- ccg = fsbtodb(fs, cgtod(fs, c)) * disk->d_bsize;
if (bread(disk, fsbtodb(fs, cgtod(fs, c)), disk->d_cgunion.d_buf,
fs->fs_bsize) == -1) {
ERROR(disk, "unable to read cylinder group");
@@ -73,6 +203,12 @@ cgread1(struct uufsd *disk, int c)
}
int
+cgwrite(struct uufsd *disk)
+{
+ return (cgwrite1(disk, disk->d_lcg));
+}
+
+int
cgwrite1(struct uufsd *disk, int c)
{
struct fs *fs;
diff --git a/lib/libufs/inode.c b/lib/libufs/inode.c
index d8bef61..6d94582 100644
--- a/lib/libufs/inode.c
+++ b/lib/libufs/inode.c
@@ -93,3 +93,19 @@ gotit: switch (disk->d_ufs) {
ERROR(disk, "unknown UFS filesystem type");
return (-1);
}
+
+int
+putino(struct uufsd *disk)
+{
+ struct fs *fs;
+
+ fs = &disk->d_fs;
+ if (disk->d_inoblock == NULL) {
+ ERROR(disk, "No inode block allocated");
+ return (-1);
+ }
+ if (bwrite(disk, fsbtodb(fs, ino_to_fsba(&disk->d_fs, disk->d_inomin)),
+ disk->d_inoblock, disk->d_fs.fs_bsize) <= 0)
+ return (-1);
+ return (0);
+}
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index 42a64f7..c3541a0 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -71,6 +71,7 @@ struct uufsd {
int d_fd; /* raw device file descriptor */
long d_bsize; /* device bsize */
ufs2_daddr_t d_sblock; /* superblock location */
+ struct csum *d_sbcsum; /* Superblock summary info */
caddr_t d_inoblock; /* inode block */
ino_t d_inomin; /* low inode */
ino_t d_inomax; /* high inode */
@@ -109,14 +110,19 @@ int berase(struct uufsd *, ufs2_daddr_t, ufs2_daddr_t);
/*
* cgroup.c
*/
+ufs2_daddr_t cgballoc(struct uufsd *);
+int cgbfree(struct uufsd *, ufs2_daddr_t, long);
+ino_t cgialloc(struct uufsd *);
int cgread(struct uufsd *);
int cgread1(struct uufsd *, int);
+int cgwrite(struct uufsd *);
int cgwrite1(struct uufsd *, int);
/*
* inode.c
*/
int getino(struct uufsd *, void **, ino_t, int *);
+int putino(struct uufsd *);
/*
* sblock.c
@@ -132,6 +138,16 @@ int ufs_disk_fillout(struct uufsd *, const char *);
int ufs_disk_fillout_blank(struct uufsd *, const char *);
int ufs_disk_write(struct uufsd *);
+/*
+ * ffs_subr.c
+ */
+void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
+void ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int);
+void ffs_fragacct(struct fs *, int, int32_t [], int);
+int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
+int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
+void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
+
__END_DECLS
#endif /* __LIBUFS_H__ */
diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c
index 8986290..d6bec3e 100644
--- a/lib/libufs/sblock.c
+++ b/lib/libufs/sblock.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <unistd.h>
#include <libufs.h>
@@ -49,8 +50,11 @@ static int superblocks[] = SBLOCKSEARCH;
int
sbread(struct uufsd *disk)
{
+ uint8_t block[MAXBSIZE];
struct fs *fs;
int sb, superblock;
+ int i, size, blks;
+ uint8_t *space;
ERROR(disk, NULL);
@@ -86,6 +90,34 @@ sbread(struct uufsd *disk)
}
disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1);
disk->d_sblock = superblock / disk->d_bsize;
+ /*
+ * Read in the superblock summary information.
+ */
+ size = fs->fs_cssize;
+ blks = howmany(size, fs->fs_fsize);
+ size += fs->fs_ncg * sizeof(int32_t);
+ space = malloc(size);
+ if (space == NULL) {
+ ERROR(disk, "failed to allocate space for summary information");
+ return (-1);
+ }
+ fs->fs_csp = (struct csum *)space;
+ for (i = 0; i < blks; i += fs->fs_frag) {
+ size = fs->fs_bsize;
+ if (i + fs->fs_frag > blks)
+ size = (blks - i) * fs->fs_fsize;
+ if (bread(disk, fsbtodb(fs, fs->fs_csaddr + i), block, size)
+ == -1) {
+ ERROR(disk, "Failed to read sb summary information");
+ free(fs->fs_csp);
+ return (-1);
+ }
+ bcopy(block, space, size);
+ space += size;
+ }
+ fs->fs_maxcluster = (uint32_t *)space;
+ disk->d_sbcsum = fs->fs_csp;
+
return (0);
}
@@ -93,6 +125,8 @@ int
sbwrite(struct uufsd *disk, int all)
{
struct fs *fs;
+ int blks, size;
+ uint8_t *space;
unsigned i;
ERROR(disk, NULL);
@@ -107,6 +141,22 @@ sbwrite(struct uufsd *disk, int all)
ERROR(disk, "failed to write superblock");
return (-1);
}
+ /*
+ * Write superblock summary information.
+ */
+ blks = howmany(fs->fs_cssize, fs->fs_fsize);
+ space = (uint8_t *)disk->d_sbcsum;
+ for (i = 0; i < blks; i += fs->fs_frag) {
+ size = fs->fs_bsize;
+ if (i + fs->fs_frag > blks)
+ size = (blks - i) * fs->fs_fsize;
+ if (bwrite(disk, fsbtodb(fs, fs->fs_csaddr + i), space, size)
+ == -1) {
+ ERROR(disk, "Failed to write sb summary information");
+ return (-1);
+ }
+ space += size;
+ }
if (all) {
for (i = 0; i < fs->fs_ncg; i++)
if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)),
diff --git a/lib/libufs/type.c b/lib/libufs/type.c
index 8a553be..05904b9 100644
--- a/lib/libufs/type.c
+++ b/lib/libufs/type.c
@@ -66,6 +66,10 @@ ufs_disk_close(struct uufsd *disk)
free((char *)(uintptr_t)disk->d_name);
disk->d_name = NULL;
}
+ if (disk->d_sbcsum != NULL) {
+ free(disk->d_sbcsum);
+ disk->d_sbcsum = NULL;
+ }
return (0);
}
@@ -156,6 +160,7 @@ again: if ((ret = stat(name, &st)) < 0) {
disk->d_mine = 0;
disk->d_ufs = 0;
disk->d_error = NULL;
+ disk->d_sbcsum = NULL;
if (oname != name) {
name = strdup(name);
diff --git a/lib/libugidfw/bsde_get_rule.3 b/lib/libugidfw/bsde_get_rule.3
index a3b6691..1f37b62 100644
--- a/lib/libugidfw/bsde_get_rule.3
+++ b/lib/libugidfw/bsde_get_rule.3
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd February 24, 2004
-.Os
.Dt BSDE_GET_RULE 3
+.Os
.Sh NAME
.Nm bsde_add_rule ,
.Nm bsde_get_rule ,
diff --git a/lib/libugidfw/bsde_get_rule_count.3 b/lib/libugidfw/bsde_get_rule_count.3
index bf441e1..2ca965f 100644
--- a/lib/libugidfw/bsde_get_rule_count.3
+++ b/lib/libugidfw/bsde_get_rule_count.3
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd January 7, 2003
-.Os
.Dt BSDE_GET_RULE_COUNT 3
+.Os
.Sh NAME
.Nm bsde_get_rule_count ,
.Nm bsde_get_rule_slots
diff --git a/lib/libugidfw/bsde_parse_rule.3 b/lib/libugidfw/bsde_parse_rule.3
index d510cab..4b177af 100644
--- a/lib/libugidfw/bsde_parse_rule.3
+++ b/lib/libugidfw/bsde_parse_rule.3
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd January 7, 2003
-.Os
.Dt BSDE_PARSE_RULE 3
+.Os
.Sh NAME
.Nm bsde_parse_rule ,
.Nm bsde_parse_rule_string
diff --git a/lib/libugidfw/bsde_rule_to_string.3 b/lib/libugidfw/bsde_rule_to_string.3
index 4414406..6279dcf 100644
--- a/lib/libugidfw/bsde_rule_to_string.3
+++ b/lib/libugidfw/bsde_rule_to_string.3
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd January 7, 2003
-.Os
.Dt BSDE_RULE_TO_STRING 3
+.Os
.Sh NAME
.Nm bsde_rule_to_string
.Nd "convert a ugidfw rule into its text representation"
diff --git a/lib/libugidfw/libugidfw.3 b/lib/libugidfw/libugidfw.3
index 3ff407c..42d23c6 100644
--- a/lib/libugidfw/libugidfw.3
+++ b/lib/libugidfw/libugidfw.3
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd February 25, 2004
-.Os
.Dt LIBUGIDFW 3
+.Os
.Sh NAME
.Nm libugidfw
.Nd "library interface to the file system firewall MAC policy"
diff --git a/lib/libulog/ulog_login.3 b/lib/libulog/ulog_login.3
index ec397c8..451a4f7 100644
--- a/lib/libulog/ulog_login.3
+++ b/lib/libulog/ulog_login.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 5, 2009
-.Os
.Dt ULOG_LOGIN 3
+.Os
.Sh NAME
.Nm ulog_login ,
.Nm ulog_login_pseudo ,
diff --git a/lib/libulog/utempter_add_record.3 b/lib/libulog/utempter_add_record.3
index 1553d68..cd8e8f1 100644
--- a/lib/libulog/utempter_add_record.3
+++ b/lib/libulog/utempter_add_record.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 6, 2009
-.Os
.Dt UTEMPTER_ADD_RECORD 3
+.Os
.Sh NAME
.Nm utempter_add_record ,
.Nm utempter_remove_added_record ,
diff --git a/lib/libusbhid/data.c b/lib/libusbhid/data.c
index d278ddb..049c88b 100644
--- a/lib/libusbhid/data.c
+++ b/lib/libusbhid/data.c
@@ -29,6 +29,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
#include <assert.h>
#include <stdlib.h>
#include "usbhid.h"
@@ -36,18 +37,27 @@ __FBSDID("$FreeBSD$");
int
hid_get_data(const void *p, const hid_item_t *h)
{
- const unsigned char *buf;
- unsigned int hpos;
- unsigned int hsize;
- int data;
+ const uint8_t *buf;
+ uint32_t hpos;
+ uint32_t hsize;
+ uint32_t data;
int i, end, offs;
buf = p;
+
+ /* Skip report ID byte. */
+ if (h->report_ID > 0)
+ buf++;
+
hpos = h->pos; /* bit position of data */
hsize = h->report_size; /* bit length of data */
+ /* Range check and limit */
if (hsize == 0)
return (0);
+ if (hsize > 32)
+ hsize = 32;
+
offs = hpos / 8;
end = (hpos + hsize) / 8 - offs;
data = 0;
@@ -66,12 +76,17 @@ hid_get_data(const void *p, const hid_item_t *h)
void
hid_set_data(void *p, const hid_item_t *h, int data)
{
- unsigned char *buf;
- unsigned int hpos;
- unsigned int hsize;
+ uint8_t *buf;
+ uint32_t hpos;
+ uint32_t hsize;
int i, end, offs, mask;
buf = p;
+
+ /* Set report ID byte. */
+ if (h->report_ID > 0)
+ *buf++ = h->report_ID & 0xff;
+
hpos = h->pos; /* bit position of data */
hsize = h->report_size; /* bit length of data */
@@ -90,5 +105,5 @@ hid_set_data(void *p, const hid_item_t *h, int data)
for (i = 0; i <= end; i++)
buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) |
- ((data >> (i*8)) & 0xff);
+ ((data >> (i*8)) & 0xff);
}
diff --git a/lib/libusbhid/descr.c b/lib/libusbhid/descr.c
index 2ce1bf0..a5c033a 100644
--- a/lib/libusbhid/descr.c
+++ b/lib/libusbhid/descr.c
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
-
#include <dev/usb/usb_ioctl.h>
#include "usbhid.h"
@@ -59,9 +58,30 @@ hid_set_immed(int fd, int enable)
int
hid_get_report_id(int fd)
{
+ report_desc_t rep;
+ hid_data_t d;
+ hid_item_t h;
+ int kindset;
int temp = -1;
int ret;
+ if ((rep = hid_get_report_desc(fd)) == NULL)
+ goto use_ioctl;
+ kindset = 1 << hid_input | 1 << hid_output | 1 << hid_feature;
+ for (d = hid_start_parse(rep, kindset, 0); hid_get_item(d, &h); ) {
+ /* Return the first report ID we met. */
+ if (h.report_ID != 0) {
+ temp = h.report_ID;
+ break;
+ }
+ }
+ hid_end_parse(d);
+ hid_dispose_report_desc(rep);
+
+ if (temp > 0)
+ return (temp);
+
+use_ioctl:
ret = ioctl(fd, USB_GET_REPORT_ID, &temp);
#ifdef HID_COMPAT7
if (ret < 0)
diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c
index 3abc036..ce034b1 100644
--- a/lib/libusbhid/parse.c
+++ b/lib/libusbhid/parse.c
@@ -40,42 +40,43 @@ __FBSDID("$FreeBSD$");
#include "usbhid.h"
#include "usbvar.h"
-#define MAXUSAGE 100
-struct hid_data {
- u_char *start;
- u_char *end;
- u_char *p;
- hid_item_t cur;
- unsigned int usages[MAXUSAGE];
- int nusage;
- int minset;
- int logminsize;
- int multi;
- int multimax;
- int kindset;
- int reportid;
-
- /*
- * The start of collection item has no report ID set, so save
- * it until we know the ID.
- */
- hid_item_t savedcoll;
- u_char hassavedcoll;
- /*
- * Absolute data position (bits) for input/output/feature.
- * Assumes that hid_input, hid_output and hid_feature have
- * values 0, 1 and 2.
- */
- unsigned int kindpos[3];
-};
+#define MAXUSAGE 100
+#define MAXPUSH 4
+#define MAXID 64
-static int min(int x, int y) { return x < y ? x : y; }
+struct hid_pos_data {
+ int32_t rid;
+ uint32_t pos;
+};
-static int hid_get_item_raw(hid_data_t s, hid_item_t *h);
+struct hid_data {
+ const uint8_t *start;
+ const uint8_t *end;
+ const uint8_t *p;
+ struct hid_item cur[MAXPUSH];
+ struct hid_pos_data last_pos[MAXID];
+ int32_t usages_min[MAXUSAGE];
+ int32_t usages_max[MAXUSAGE];
+ int32_t usage_last; /* last seen usage */
+ uint32_t loc_size; /* last seen size */
+ uint32_t loc_count; /* last seen count */
+ uint8_t kindset; /* we have 5 kinds so 8 bits are enough */
+ uint8_t pushlevel; /* current pushlevel */
+ uint8_t ncount; /* end usage item count */
+ uint8_t icount; /* current usage item count */
+ uint8_t nusage; /* end "usages_min/max" index */
+ uint8_t iusage; /* current "usages_min/max" index */
+ uint8_t ousage; /* current "usages_min/max" offset */
+ uint8_t susage; /* usage set flags */
+};
+/*------------------------------------------------------------------------*
+ * hid_clear_local
+ *------------------------------------------------------------------------*/
static void
hid_clear_local(hid_item_t *c)
{
+
c->usage = 0;
c->usage_minimum = 0;
c->usage_maximum = 0;
@@ -88,8 +89,61 @@ hid_clear_local(hid_item_t *c)
c->set_delimiter = 0;
}
+static void
+hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID)
+{
+ uint8_t i;
+
+ /* check for same report ID - optimise */
+
+ if (c->report_ID == next_rID)
+ return;
+
+ /* save current position for current rID */
+
+ if (c->report_ID == 0) {
+ i = 0;
+ } else {
+ for (i = 1; i != MAXID; i++) {
+ if (s->last_pos[i].rid == c->report_ID)
+ break;
+ if (s->last_pos[i].rid == 0)
+ break;
+ }
+ }
+ if (i != MAXID) {
+ s->last_pos[i].rid = c->report_ID;
+ s->last_pos[i].pos = c->pos;
+ }
+
+ /* store next report ID */
+
+ c->report_ID = next_rID;
+
+ /* lookup last position for next rID */
+
+ if (next_rID == 0) {
+ i = 0;
+ } else {
+ for (i = 1; i != MAXID; i++) {
+ if (s->last_pos[i].rid == next_rID)
+ break;
+ if (s->last_pos[i].rid == 0)
+ break;
+ }
+ }
+ if (i != MAXID) {
+ s->last_pos[i].rid = next_rID;
+ c->pos = s->last_pos[i].pos;
+ } else
+ c->pos = 0; /* Out of RID entries. */
+}
+
+/*------------------------------------------------------------------------*
+ * hid_start_parse
+ *------------------------------------------------------------------------*/
hid_data_t
-hid_start_parse(report_desc_t d, int kindset, int id)
+hid_start_parse(report_desc_t d, int kindset, int id __unused)
{
struct hid_data *s;
@@ -98,213 +152,207 @@ hid_start_parse(report_desc_t d, int kindset, int id)
s->start = s->p = d->data;
s->end = d->data + d->size;
s->kindset = kindset;
- s->reportid = id;
- s->hassavedcoll = 0;
return (s);
}
+/*------------------------------------------------------------------------*
+ * hid_end_parse
+ *------------------------------------------------------------------------*/
void
hid_end_parse(hid_data_t s)
{
- while (s->cur.next) {
- hid_item_t *hi = s->cur.next->next;
- free(s->cur.next);
- s->cur.next = hi;
- }
+
+ if (s == NULL)
+ return;
+
free(s);
}
-int
-hid_get_item(hid_data_t s, hid_item_t *h)
+/*------------------------------------------------------------------------*
+ * get byte from HID descriptor
+ *------------------------------------------------------------------------*/
+static uint8_t
+hid_get_byte(struct hid_data *s, const uint16_t wSize)
{
- int r;
+ const uint8_t *ptr;
+ uint8_t retval;
- for (;;) {
- r = hid_get_item_raw(s, h);
- if (r <= 0)
- break;
- if (h->report_ID == s->reportid || s->reportid == -1)
- break;
- }
- return (r);
+ ptr = s->p;
+
+ /* check if end is reached */
+ if (ptr == s->end)
+ return (0);
+
+ /* read out a byte */
+ retval = *ptr;
+
+ /* check if data pointer can be advanced by "wSize" bytes */
+ if ((s->end - ptr) < wSize)
+ ptr = s->end;
+ else
+ ptr += wSize;
+
+ /* update pointer */
+ s->p = ptr;
+
+ return (retval);
}
-#define REPORT_SAVED_COLL \
- do { \
- if (s->hassavedcoll) { \
- *h = s->savedcoll; \
- h->report_ID = c->report_ID; \
- s->hassavedcoll = 0; \
- return (1); \
- } \
- } while(/*LINTED*/ 0)
-
-static int
-hid_get_item_raw(hid_data_t s, hid_item_t *h)
+/*------------------------------------------------------------------------*
+ * hid_get_item
+ *------------------------------------------------------------------------*/
+int
+hid_get_item(hid_data_t s, hid_item_t *h)
{
hid_item_t *c;
- unsigned int bTag = 0, bType = 0, bSize;
- unsigned char *data;
- int dval;
- unsigned char *p;
- hid_item_t *hi;
- hid_item_t nc;
- int i;
- hid_kind_t retkind;
+ unsigned int bTag, bType, bSize;
+ uint32_t oldpos;
+ int32_t mask;
+ int32_t dval;
+
+ if (s == NULL)
+ return (0);
- c = &s->cur;
+ c = &s->cur[s->pushlevel];
top:
- if (s->multimax) {
- REPORT_SAVED_COLL;
- if (c->logical_minimum >= c->logical_maximum) {
- if (s->logminsize == 1)
- c->logical_minimum =(int8_t)c->logical_minimum;
- else if (s->logminsize == 2)
- c->logical_minimum =(int16_t)c->logical_minimum;
+ /* check if there is an array of items */
+ if (s->icount < s->ncount) {
+ /* get current usage */
+ if (s->iusage < s->nusage) {
+ dval = s->usages_min[s->iusage] + s->ousage;
+ c->usage = dval;
+ s->usage_last = dval;
+ if (dval == s->usages_max[s->iusage]) {
+ s->iusage ++;
+ s->ousage = 0;
+ } else {
+ s->ousage ++;
+ }
+ } else {
+ /* Using last usage */
+ dval = s->usage_last;
}
- if (s->multi < s->multimax) {
- c->usage = s->usages[min(s->multi, s->nusage-1)];
- s->multi++;
+ s->icount ++;
+ /*
+ * Only copy HID item, increment position and return
+ * if correct kindset!
+ */
+ if (s->kindset & (1 << c->kind)) {
*h = *c;
- /*
- * 'multimax' is only non-zero if the current
- * item kind is input/output/feature
- */
- h->pos = s->kindpos[c->kind];
- s->kindpos[c->kind] += c->report_size;
- h->next = 0;
+ c->pos += c->report_size * c->report_count;
return (1);
- } else {
- c->report_count = s->multimax;
- s->multimax = 0;
- s->nusage = 0;
- hid_clear_local(c);
}
}
- for (;;) {
- p = s->p;
- if (p >= s->end)
- return (0);
- bSize = *p++;
+ /* reset state variables */
+ s->icount = 0;
+ s->ncount = 0;
+ s->iusage = 0;
+ s->nusage = 0;
+ s->susage = 0;
+ s->ousage = 0;
+ hid_clear_local(c);
+
+ /* get next item */
+ while (s->p != s->end) {
+
+ bSize = hid_get_byte(s, 1);
if (bSize == 0xfe) {
/* long item */
- bSize = *p++;
- bSize |= *p++ << 8;
- bTag = *p++;
- data = p;
- p += bSize;
+ bSize = hid_get_byte(s, 1);
+ bSize |= hid_get_byte(s, 1) << 8;
+ bTag = hid_get_byte(s, 1);
+ bType = 0xff; /* XXX what should it be */
} else {
/* short item */
bTag = bSize >> 4;
bType = (bSize >> 2) & 3;
bSize &= 3;
- if (bSize == 3) bSize = 4;
- data = p;
- p += bSize;
+ if (bSize == 3)
+ bSize = 4;
}
- s->p = p;
- /*
- * The spec is unclear if the data is signed or unsigned.
- */
+
switch(bSize) {
case 0:
dval = 0;
+ mask = 0;
break;
case 1:
- dval = *data++;
+ dval = (int8_t)hid_get_byte(s, 1);
+ mask = 0xFF;
break;
case 2:
- dval = *data++;
- dval |= *data++ << 8;
+ dval = hid_get_byte(s, 1);
+ dval |= hid_get_byte(s, 1) << 8;
+ dval = (int16_t)dval;
+ mask = 0xFFFF;
break;
case 4:
- dval = *data++;
- dval |= *data++ << 8;
- dval |= *data++ << 16;
- dval |= *data++ << 24;
+ dval = hid_get_byte(s, 1);
+ dval |= hid_get_byte(s, 1) << 8;
+ dval |= hid_get_byte(s, 1) << 16;
+ dval |= hid_get_byte(s, 1) << 24;
+ mask = 0xFFFFFFFF;
break;
default:
- return (-1);
+ dval = hid_get_byte(s, bSize);
+ continue;
}
switch (bType) {
- case 0: /* Main */
+ case 0: /* Main */
switch (bTag) {
- case 8: /* Input */
- retkind = hid_input;
- ret:
- if (!(s->kindset & (1 << retkind))) {
- /* Drop the items of this kind */
- s->nusage = 0;
- continue;
- }
- c->kind = retkind;
+ case 8: /* Input */
+ c->kind = hid_input;
c->flags = dval;
+ ret:
+ c->report_count = s->loc_count;
+ c->report_size = s->loc_size;
+
if (c->flags & HIO_VARIABLE) {
- s->multimax = c->report_count;
- s->multi = 0;
+ /* range check usage count */
+ if (c->report_count > 255) {
+ s->ncount = 255;
+ } else
+ s->ncount = c->report_count;
+
+ /*
+ * The "top" loop will return
+ * one and one item:
+ */
c->report_count = 1;
- if (s->minset) {
- for (i = c->usage_minimum;
- i <= c->usage_maximum;
- i++) {
- s->usages[s->nusage] = i;
- if (s->nusage < MAXUSAGE-1)
- s->nusage++;
- }
- c->usage_minimum = 0;
- c->usage_maximum = 0;
- s->minset = 0;
- }
- goto top;
} else {
- if (s->minset)
- c->usage = c->usage_minimum;
- *h = *c;
- h->next = 0;
- h->pos = s->kindpos[c->kind];
- s->kindpos[c->kind] +=
- c->report_size * c->report_count;
- hid_clear_local(c);
- s->minset = 0;
- return (1);
+ s->ncount = 1;
}
- case 9: /* Output */
- retkind = hid_output;
+ goto top;
+
+ case 9: /* Output */
+ c->kind = hid_output;
+ c->flags = dval;
goto ret;
case 10: /* Collection */
c->kind = hid_collection;
c->collection = dval;
c->collevel++;
- nc = *c;
- hid_clear_local(c);
- /*c->report_ID = NO_REPORT_ID;*/
- s->nusage = 0;
- if (s->hassavedcoll) {
- *h = s->savedcoll;
- h->report_ID = nc.report_ID;
- s->savedcoll = nc;
- return (1);
- } else {
- s->hassavedcoll = 1;
- s->savedcoll = nc;
- }
- break;
+ c->usage = s->usage_last;
+ *h = *c;
+ return (1);
case 11: /* Feature */
- retkind = hid_feature;
+ c->kind = hid_feature;
+ c->flags = dval;
goto ret;
case 12: /* End collection */
- REPORT_SAVED_COLL;
c->kind = hid_endcollection;
+ if (c->collevel == 0) {
+ /* Invalid end collection. */
+ return (0);
+ }
c->collevel--;
*h = *c;
- /*hid_clear_local(c);*/
- s->nusage = 0;
return (1);
default:
- return (-2);
+ break;
}
break;
@@ -315,13 +363,12 @@ hid_get_item_raw(hid_data_t s, hid_item_t *h)
break;
case 1:
c->logical_minimum = dval;
- s->logminsize = bSize;
break;
case 2:
c->logical_maximum = dval;
break;
case 3:
- c->physical_maximum = dval;
+ c->physical_minimum = dval;
break;
case 4:
c->physical_maximum = dval;
@@ -333,45 +380,97 @@ hid_get_item_raw(hid_data_t s, hid_item_t *h)
c->unit = dval;
break;
case 7:
- c->report_size = dval;
+ /* mask because value is unsigned */
+ s->loc_size = dval & mask;
break;
case 8:
- c->report_ID = dval;
- s->kindpos[hid_input] =
- s->kindpos[hid_output] =
- s->kindpos[hid_feature] = 0;
+ hid_switch_rid(s, c, dval);
break;
case 9:
- c->report_count = dval;
+ /* mask because value is unsigned */
+ s->loc_count = dval & mask;
break;
- case 10: /* Push */
- hi = malloc(sizeof *hi);
- *hi = s->cur;
- c->next = hi;
+ case 10: /* Push */
+ s->pushlevel ++;
+ if (s->pushlevel < MAXPUSH) {
+ s->cur[s->pushlevel] = *c;
+ /* store size and count */
+ c->report_size = s->loc_size;
+ c->report_count = s->loc_count;
+ /* update current item pointer */
+ c = &s->cur[s->pushlevel];
+ }
break;
- case 11: /* Pop */
- hi = c->next;
- s->cur = *hi;
- free(hi);
+ case 11: /* Pop */
+ s->pushlevel --;
+ if (s->pushlevel < MAXPUSH) {
+ /* preserve position */
+ oldpos = c->pos;
+ c = &s->cur[s->pushlevel];
+ /* restore size and count */
+ s->loc_size = c->report_size;
+ s->loc_count = c->report_count;
+ /* set default item location */
+ c->pos = oldpos;
+ c->report_size = 0;
+ c->report_count = 0;
+ }
break;
default:
- return (-3);
+ break;
}
break;
case 2: /* Local */
switch (bTag) {
case 0:
- c->usage = c->_usage_page | dval;
- if (s->nusage < MAXUSAGE)
- s->usages[s->nusage++] = c->usage;
+ if (bSize != 4)
+ dval = (dval & mask) | c->_usage_page;
+
+ /* set last usage, in case of a collection */
+ s->usage_last = dval;
+
+ if (s->nusage < MAXUSAGE) {
+ s->usages_min[s->nusage] = dval;
+ s->usages_max[s->nusage] = dval;
+ s->nusage ++;
+ }
/* else XXX */
+
+ /* clear any pending usage sets */
+ s->susage = 0;
break;
case 1:
- s->minset = 1;
- c->usage_minimum = c->_usage_page | dval;
- break;
+ s->susage |= 1;
+
+ if (bSize != 4)
+ dval = (dval & mask) | c->_usage_page;
+ c->usage_minimum = dval;
+
+ goto check_set;
case 2:
- c->usage_maximum = c->_usage_page | dval;
+ s->susage |= 2;
+
+ if (bSize != 4)
+ dval = (dval & mask) | c->_usage_page;
+ c->usage_maximum = dval;
+
+ check_set:
+ if (s->susage != 3)
+ break;
+
+ /* sanity check */
+ if ((s->nusage < MAXUSAGE) &&
+ (c->usage_minimum <= c->usage_maximum)) {
+ /* add usage range */
+ s->usages_min[s->nusage] =
+ c->usage_minimum;
+ s->usages_max[s->nusage] =
+ c->usage_maximum;
+ s->nusage ++;
+ }
+ /* else XXX */
+
+ s->susage = 0;
break;
case 3:
c->designator_index = dval;
@@ -395,40 +494,63 @@ hid_get_item_raw(hid_data_t s, hid_item_t *h)
c->set_delimiter = dval;
break;
default:
- return (-4);
+ break;
}
break;
default:
- return (-5);
+ break;
}
}
+ return (0);
}
int
hid_report_size(report_desc_t r, enum hid_kind k, int id)
{
struct hid_data *d;
- hid_item_t h;
- int size;
+ struct hid_item h;
+ uint32_t temp;
+ uint32_t hpos;
+ uint32_t lpos;
+
+ hpos = 0;
+ lpos = 0xFFFFFFFF;
memset(&h, 0, sizeof h);
- size = 0;
- for (d = hid_start_parse(r, 1<<k, id); hid_get_item(d, &h); ) {
+ for (d = hid_start_parse(r, 1 << k, id); hid_get_item(d, &h); ) {
if (h.report_ID == id && h.kind == k) {
- size = d->kindpos[k];
+ /* compute minimum */
+ if (lpos > h.pos)
+ lpos = h.pos;
+ /* compute end position */
+ temp = h.pos + (h.report_size * h.report_count);
+ /* compute maximum */
+ if (hpos < temp)
+ hpos = temp;
}
}
hid_end_parse(d);
- return ((size + 7) / 8);
+
+ /* safety check - can happen in case of currupt descriptors */
+ if (lpos > hpos)
+ temp = 0;
+ else
+ temp = hpos - lpos;
+
+ if (id)
+ temp += 8;
+
+ /* return length in bytes rounded up */
+ return ((temp + 7) / 8);
}
int
hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k,
hid_item_t *h, int id)
{
- hid_data_t d;
+ struct hid_data *d;
- for (d = hid_start_parse(desc, 1<<k, id); hid_get_item(d, h); ) {
+ for (d = hid_start_parse(desc, 1 << k, id); hid_get_item(d, h); ) {
if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) {
hid_end_parse(d);
return (1);
diff --git a/lib/libusbhid/usage.c b/lib/libusbhid/usage.c
index 280ef69..eeff818 100644
--- a/lib/libusbhid/usage.c
+++ b/lib/libusbhid/usage.c
@@ -29,6 +29,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
#include <assert.h>
#include <ctype.h>
#include <err.h>
diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h
index b8751cd..d1d3bf0 100644
--- a/lib/libusbhid/usbhid.h
+++ b/lib/libusbhid/usbhid.h
@@ -29,52 +29,48 @@
*
*/
-#include <sys/cdefs.h>
+#include <sys/types.h>
typedef struct report_desc *report_desc_t;
typedef struct hid_data *hid_data_t;
typedef enum hid_kind {
- hid_input = 0,
- hid_output = 1,
- hid_feature = 2,
- hid_collection,
- hid_endcollection
+ hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
} hid_kind_t;
typedef struct hid_item {
/* Global */
- unsigned int _usage_page;
- int logical_minimum;
- int logical_maximum;
- int physical_minimum;
- int physical_maximum;
- int unit_exponent;
- int unit;
- int report_size;
- int report_ID;
+ uint32_t _usage_page;
+ int32_t logical_minimum;
+ int32_t logical_maximum;
+ int32_t physical_minimum;
+ int32_t physical_maximum;
+ int32_t unit_exponent;
+ int32_t unit;
+ int32_t report_size;
+ int32_t report_ID;
#define NO_REPORT_ID 0
- int report_count;
+ int32_t report_count;
/* Local */
- unsigned int usage;
- int usage_minimum;
- int usage_maximum;
- int designator_index;
- int designator_minimum;
- int designator_maximum;
- int string_index;
- int string_minimum;
- int string_maximum;
- int set_delimiter;
+ uint32_t usage;
+ int32_t usage_minimum;
+ int32_t usage_maximum;
+ int32_t designator_index;
+ int32_t designator_minimum;
+ int32_t designator_maximum;
+ int32_t string_index;
+ int32_t string_minimum;
+ int32_t string_maximum;
+ int32_t set_delimiter;
/* Misc */
- int collection;
- int collevel;
+ int32_t collection;
+ int collevel;
enum hid_kind kind;
- unsigned int flags;
- /* Absolute data position (bits) */
- unsigned int pos;
- /* */
+ uint32_t flags;
+ /* Location */
+ uint32_t pos;
+ /* unused */
struct hid_item *next;
} hid_item_t;
@@ -95,7 +91,8 @@ hid_data_t hid_start_parse(report_desc_t d, int kindset, int id);
void hid_end_parse(hid_data_t s);
int hid_get_item(hid_data_t s, hid_item_t *h);
int hid_report_size(report_desc_t d, enum hid_kind k, int id);
-int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h, int id);
+int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k,
+ hid_item_t *h, int id);
/* Conversion to/from usage names, usage.c: */
const char *hid_usage_page(int i);
diff --git a/lib/libusbhid/usbvar.h b/lib/libusbhid/usbvar.h
index d437005..9605106 100644
--- a/lib/libusbhid/usbvar.h
+++ b/lib/libusbhid/usbvar.h
@@ -30,8 +30,8 @@
*/
struct report_desc {
- unsigned int size;
- unsigned char data[1];
+ uint32_t size;
+ uint8_t data[1];
};
/* internal backwards compatibility functions */
diff --git a/lib/libutil/_secure_path.3 b/lib/libutil/_secure_path.3
index fe23d12..cf89315 100644
--- a/lib/libutil/_secure_path.3
+++ b/lib/libutil/_secure_path.3
@@ -20,8 +20,8 @@
.\" $FreeBSD$
.\"
.Dd May 2, 1997
-.Os
.Dt _SECURE_PATH 3
+.Os
.Sh NAME
.Nm _secure_path
.Nd determine if a file appears to be secure
diff --git a/lib/libutil/auth.3 b/lib/libutil/auth.3
index 3a1bb4d..247a098 100644
--- a/lib/libutil/auth.3
+++ b/lib/libutil/auth.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd October 7, 1998
-.Os
.Dt AUTH_GETVAL 3
+.Os
.Sh NAME
.Nm auth_getval
.Nd functions for reading values from
diff --git a/lib/libutil/hexdump.3 b/lib/libutil/hexdump.3
index cc004f6..8e997ac 100644
--- a/lib/libutil/hexdump.3
+++ b/lib/libutil/hexdump.3
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 1, 2008
-.Os
.Dt HEXDUMP 3
+.Os
.Sh NAME
.Nm hexdump
.Nd "dump a block of bytes to standard out in hexadecimal form"
diff --git a/lib/libutil/humanize_number.3 b/lib/libutil/humanize_number.3
index 76d5677..a4c3140 100644
--- a/lib/libutil/humanize_number.3
+++ b/lib/libutil/humanize_number.3
@@ -15,13 +15,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/lib/libutil/kinfo_getfile.3 b/lib/libutil/kinfo_getfile.3
index 5705bf7..c0b0b02 100644
--- a/lib/libutil/kinfo_getfile.3
+++ b/lib/libutil/kinfo_getfile.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 6, 2008
-.Os
.Dt KINFO_GETFILE 3
+.Os
.Sh NAME
.Nm kinfo_getfile
.Nd function for getting per-process file descriptor information
diff --git a/lib/libutil/kinfo_getvmmap.3 b/lib/libutil/kinfo_getvmmap.3
index 0f12b67..7aa46fc 100644
--- a/lib/libutil/kinfo_getvmmap.3
+++ b/lib/libutil/kinfo_getvmmap.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 6, 2008
-.Os
.Dt KINFO_GETVMMAP 3
+.Os
.Sh NAME
.Nm kinfo_getvmmap
.Nd function for getting per-process memory map information
diff --git a/lib/libutil/kld.3 b/lib/libutil/kld.3
index cc34fa1..6b77c47 100644
--- a/lib/libutil/kld.3
+++ b/lib/libutil/kld.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd February 18, 2006
-.Os
.Dt KLD 3
+.Os
.Sh NAME
.Nm kld_isloaded ,
.Nm kld_load
diff --git a/lib/libutil/login_auth.3 b/lib/libutil/login_auth.3
index 3750bd6..003f6e9 100644
--- a/lib/libutil/login_auth.3
+++ b/lib/libutil/login_auth.3
@@ -20,8 +20,8 @@
.\" $FreeBSD$
.\"
.Dd December 29, 1996
-.Os
.Dt LOGIN_AUTH 3
+.Os
.Sh NAME
.\" .Nm authenticate
.\" .Nm auth_script
diff --git a/lib/libutil/login_cap.3 b/lib/libutil/login_cap.3
index 7ecefff..bdab56e 100644
--- a/lib/libutil/login_cap.3
+++ b/lib/libutil/login_cap.3
@@ -20,8 +20,8 @@
.\" $FreeBSD$
.\"
.Dd June 14, 2007
-.Os
.Dt LOGIN_CAP 3
+.Os
.Sh NAME
.Nm login_close ,
.Nm login_getcapbool ,
diff --git a/lib/libutil/login_class.3 b/lib/libutil/login_class.3
index 75ccccc..083e942 100644
--- a/lib/libutil/login_class.3
+++ b/lib/libutil/login_class.3
@@ -20,8 +20,8 @@
.\" $FreeBSD$
.\"
.Dd October 20, 2008
-.Os
.Dt LOGIN_CLASS 3
+.Os
.Sh NAME
.Nm setclasscontext ,
.Nm setclasscpumask ,
diff --git a/lib/libutil/login_ok.3 b/lib/libutil/login_ok.3
index 1bb6236c..9022ff5 100644
--- a/lib/libutil/login_ok.3
+++ b/lib/libutil/login_ok.3
@@ -20,8 +20,8 @@
.\" $FreeBSD$
.\"
.Dd January 2, 1997
-.Os
.Dt LOGIN_OK 3
+.Os
.Sh NAME
.Nm auth_ttyok ,
.Nm auth_hostok ,
diff --git a/lib/libutil/login_times.3 b/lib/libutil/login_times.3
index a144484..9d1f88d 100644
--- a/lib/libutil/login_times.3
+++ b/lib/libutil/login_times.3
@@ -20,8 +20,8 @@
.\" $FreeBSD$
.\"
.Dd October 20, 2008
-.Os
.Dt LOGIN_TIMES 3
+.Os
.Sh NAME
.Nm parse_lt ,
.Nm in_lt ,
diff --git a/lib/libutil/login_tty.3 b/lib/libutil/login_tty.3
index 6303d68..907b97c 100644
--- a/lib/libutil/login_tty.3
+++ b/lib/libutil/login_tty.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd December 29, 1996
-.Os
.Dt LOGIN_TTY 3
+.Os
.Sh NAME
.Nm login_tty
.Nd prepare a tty for a new login session
diff --git a/lib/libutil/property.3 b/lib/libutil/property.3
index 61eb153..51f7e14 100644
--- a/lib/libutil/property.3
+++ b/lib/libutil/property.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd October 7, 1998
-.Os
.Dt PROPERTIES 3
+.Os
.Sh NAME
.Nm properties_read ,
.Nm propery_find ,
diff --git a/lib/libutil/pty.3 b/lib/libutil/pty.3
index 08a5985..f71cc53 100644
--- a/lib/libutil/pty.3
+++ b/lib/libutil/pty.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd December 29, 1996
-.Os
.Dt PTY 3
+.Os
.Sh NAME
.Nm openpty ,
.Nm forkpty
diff --git a/lib/libutil/realhostname.3 b/lib/libutil/realhostname.3
index fd64d4c..9f5a6c5 100644
--- a/lib/libutil/realhostname.3
+++ b/lib/libutil/realhostname.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd April 6, 1999
-.Os
.Dt REALHOSTNAME 3
+.Os
.Sh NAME
.Nm realhostname
.Nd "convert an IP number to the real host name"
diff --git a/lib/libutil/realhostname_sa.3 b/lib/libutil/realhostname_sa.3
index 9f7f0df..3fd44a4 100644
--- a/lib/libutil/realhostname_sa.3
+++ b/lib/libutil/realhostname_sa.3
@@ -52,8 +52,8 @@
.\" $FreeBSD$
.\"
.Dd January 11, 2000
-.Os
.Dt REALHOSTNAME_SA 3
+.Os
.Sh NAME
.Nm realhostname_sa
.Nd "convert a"
diff --git a/lib/libutil/trimdomain.3 b/lib/libutil/trimdomain.3
index f01e884..8d600c0 100644
--- a/lib/libutil/trimdomain.3
+++ b/lib/libutil/trimdomain.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd April 7, 1999
-.Os
.Dt TRIMDOMAIN 3
+.Os
.Sh NAME
.Nm trimdomain
.Nd "trim the current domain name from a host name"
diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3
index 5f75c7f..5d8647d 100644
--- a/lib/libutil/uucplock.3
+++ b/lib/libutil/uucplock.3
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd March 30, 1997
-.Os
.Dt UUCPLOCK 3
+.Os
.Sh NAME
.Nm uu_lock ,
.Nm uu_unlock ,
diff --git a/lib/libz/ChangeLog b/lib/libz/ChangeLog
index 7f6869d..f310bb0 100644
--- a/lib/libz/ChangeLog
+++ b/lib/libz/ChangeLog
@@ -1,6 +1,359 @@
ChangeLog file for zlib
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+ Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+ _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling error in zlib.h [Willem]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+ binary compatibility -- a normal version and a 64-bit offset version,
+ per the Large File Support Extension when _LARGEFILE64_SOURCE is
+ defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+ is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+ [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+ trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+ gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+ Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+ the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+ for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+ doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+ that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+ un-versioned, the patch adds versioning only for symbols introduced in
+ zlib-1.2.0 or later. It also declares as local those symbols which are
+ not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+ NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
Changes in 1.2.3 (18 July 2005)
- Apply security vulnerability fixes to contrib/infback9 as well
- Clean up some text files (carriage returns, trailing space)
@@ -13,7 +366,7 @@ Changes in 1.2.2.4 (11 July 2005)
compile
- Fix some spelling errors in comments [Betts]
- Correct inflateInit2() error return documentation in zlib.h
-- Added zran.c example of compressed data random access to examples
+- Add zran.c example of compressed data random access to examples
directory, shows use of inflatePrime()
- Fix cast for assignments to strm->state in inflate.c and infback.c
- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
diff --git a/lib/libz/FAQ b/lib/libz/FAQ
index 441d910..1a22750 100644
--- a/lib/libz/FAQ
+++ b/lib/libz/FAQ
@@ -3,8 +3,8 @@
If your question is not there, please check the zlib home page
-http://www.zlib.org which may have more recent information.
-The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
1. Is zlib Y2K-compliant?
@@ -13,54 +13,51 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
2. Where can I get a Windows DLL version?
- The zlib sources can be compiled without change to produce a DLL.
- See the file win32/DLL_FAQ.txt in the zlib distribution.
- Pointers to the precompiled DLL are found in the zlib web site at
- http://www.zlib.org.
+ The zlib sources can be compiled without change to produce a DLL. See the
+ file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
+ precompiled DLL are found in the zlib web site at http://zlib.net/ .
3. Where can I get a Visual Basic interface to zlib?
See
- * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
- * contrib/visual-basic.txt in the zlib distribution
+ * http://marknelson.us/1997/01/01/zlib-engine/
* win32/DLL_FAQ.txt in the zlib distribution
4. compress() returns Z_BUF_ERROR.
- Make sure that before the call of compress, the length of the compressed
- buffer is equal to the total size of the compressed buffer and not
- zero. For Visual Basic, check that this parameter is passed by reference
+ Make sure that before the call of compress(), the length of the compressed
+ buffer is equal to the available size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
("as any"), not by value ("as long").
5. deflate() or inflate() returns Z_BUF_ERROR.
- Before making the call, make sure that avail_in and avail_out are not
- zero. When setting the parameter flush equal to Z_FINISH, also make sure
- that avail_out is big enough to allow processing all pending input.
- Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
- inflate() can be made with more input or output space. A Z_BUF_ERROR
- may in fact be unavoidable depending on how the functions are used, since
- it is not possible to tell whether or not there is more output pending
- when strm.avail_out returns with zero.
+ Before making the call, make sure that avail_in and avail_out are not zero.
+ When setting the parameter flush equal to Z_FINISH, also make sure that
+ avail_out is big enough to allow processing all pending input. Note that a
+ Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+ made with more input or output space. A Z_BUF_ERROR may in fact be
+ unavoidable depending on how the functions are used, since it is not
+ possible to tell whether or not there is more output pending when
+ strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
+ heavily annotated example.
6. Where's the zlib documentation (man pages, etc.)?
- It's in zlib.h for the moment, and Francis S. Lin has converted it to a
- web page zlib.html. Volunteers to transform this to Unix-style man pages,
- please contact us (zlib@gzip.org). Examples of zlib usage are in the files
- example.c and minigzip.c.
+ It's in zlib.h . Examples of zlib usage are in the files example.c and
+ minigzip.c, with more in examples/ .
7. Why don't you use GNU autoconf or libtool or ...?
- Because we would like to keep zlib as a very small and simple
- package. zlib is rather portable and doesn't need much configuration.
+ Because we would like to keep zlib as a very small and simple package.
+ zlib is rather portable and doesn't need much configuration.
8. I found a bug in zlib.
- Most of the time, such problems are due to an incorrect usage of
- zlib. Please try to reproduce the problem with a small program and send
- the corresponding source to us at zlib@gzip.org . Do not send
- multi-megabyte data files without prior agreement.
+ Most of the time, such problems are due to an incorrect usage of zlib.
+ Please try to reproduce the problem with a small program and send the
+ corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
+ data files without prior agreement.
9. Why do I get "undefined reference to gzputc"?
@@ -82,7 +79,7 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
12. Can zlib handle .Z files?
- No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
the code of uncompress on your own.
13. How can I make a Unix shared library?
@@ -99,8 +96,10 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
However, many flavors of Unix come with a shared zlib already installed.
Before going to the trouble of compiling a shared version of zlib and
- trying to install it, you may want to check if it's already there! If you
- can #include <zlib.h>, it's there. The -lz option will probably link to it.
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to
+ it. You can check the version at the top of zlib.h or with the
+ ZLIB_VERSION symbol defined in zlib.h .
15. I have a question about OttoPDF.
@@ -109,8 +108,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
16. Can zlib decode Flate data in an Adobe PDF file?
- Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
- To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+ Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+ http://sourceforge.net/projects/acroformtool/ .
17. Why am I getting this "register_frame_info not found" error on Solaris?
@@ -121,67 +120,67 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
symbol __register_frame_info: referenced symbol not found
The symbol __register_frame_info is not part of zlib, it is generated by
- the C compiler (cc or gcc). You must recompile applications using zlib
- which have this problem. This problem is specific to Solaris. See
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
http://www.sunfreeware.com for Solaris versions of zlib and applications
using zlib.
18. Why does gzip give an error on a file I make with compress/deflate?
The compress and deflate functions produce data in the zlib format, which
- is different and incompatible with the gzip format. The gz* functions in
- zlib on the other hand use the gzip format. Both the zlib and gzip
- formats use the same compressed data format internally, but have different
- headers and trailers around the compressed data.
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip formats
+ use the same compressed data format internally, but have different headers
+ and trailers around the compressed data.
19. Ok, so why are there two different formats?
- The gzip format was designed to retain the directory information about
- a single file, such as the name and last modification date. The zlib
- format on the other hand was designed for in-memory and communication
- channel applications, and has a much more compact header and trailer and
- uses a faster integrity check than gzip.
+ The gzip format was designed to retain the directory information about a
+ single file, such as the name and last modification date. The zlib format
+ on the other hand was designed for in-memory and communication channel
+ applications, and has a much more compact header and trailer and uses a
+ faster integrity check than gzip.
20. Well that's nice, but how do I make a gzip file in memory?
You can request that deflate write the gzip format instead of the zlib
- format using deflateInit2(). You can also request that inflate decode
- the gzip format using inflateInit2(). Read zlib.h for more details.
+ format using deflateInit2(). You can also request that inflate decode the
+ gzip format using inflateInit2(). Read zlib.h for more details.
21. Is zlib thread-safe?
- Yes. However any library routines that zlib uses and any application-
- provided memory allocation routines must also be thread-safe. zlib's gz*
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
functions use stdio library routines, and most of zlib's functions use the
- library memory allocation routines by default. zlib's Init functions allow
- for the application to provide custom memory allocation routines.
+ library memory allocation routines by default. zlib's *Init* functions
+ allow for the application to provide custom memory allocation routines.
Of course, you should only operate on any given zlib or gzip stream from a
single thread at a time.
22. Can I use zlib in my commercial application?
- Yes. Please read the license in zlib.h.
+ Yes. Please read the license in zlib.h.
23. Is zlib under the GNU license?
- No. Please read the license in zlib.h.
+ No. Please read the license in zlib.h.
24. The license says that altered source versions must be "plainly marked". So
what exactly do I need to do to meet that requirement?
- You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
particular, the final version number needs to be changed to "f", and an
- identification string should be appended to ZLIB_VERSION. Version numbers
+ identification string should be appended to ZLIB_VERSION. Version numbers
x.x.x.f are reserved for modifications to zlib by others than the zlib
- maintainers. For example, if the version of the base zlib you are altering
+ maintainers. For example, if the version of the base zlib you are altering
is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
- ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
update the version strings in deflate.c and inftrees.c.
For altered source distributions, you should also note the origin and
nature of the changes in zlib.h, as well as in ChangeLog and README, along
- with the dates of the alterations. The origin should include at least your
+ with the dates of the alterations. The origin should include at least your
name (or your company's name), and an email address to contact for help or
issues with the library.
@@ -197,105 +196,112 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
26. Will zlib work on a 64-bit machine?
- It should. It has been tested on 64-bit machines, and has no dependence
- on any data types being limited to 32-bits in length. If you have any
+ Yes. It has been tested on 64-bit machines, and has no dependence on any
+ data types being limited to 32-bits in length. If you have any
difficulties, please provide a complete problem report to zlib@gzip.org
27. Will zlib decompress data from the PKWare Data Compression Library?
- No. The PKWare DCL uses a completely different compressed data format
- than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ No. The PKWare DCL uses a completely different compressed data format than
+ does PKZIP and zlib. However, you can look in zlib's contrib/blast
directory for a possible solution to your problem.
28. Can I access data randomly in a compressed stream?
- No, not without some preparation. If when compressing you periodically
- use Z_FULL_FLUSH, carefully write all the pending data at those points,
- and keep an index of those locations, then you can start decompression
- at those points. You have to be careful to not use Z_FULL_FLUSH too
- often, since it can significantly degrade compression.
+ No, not without some preparation. If when compressing you periodically use
+ Z_FULL_FLUSH, carefully write all the pending data at those points, and
+ keep an index of those locations, then you can start decompression at those
+ points. You have to be careful to not use Z_FULL_FLUSH too often, since it
+ can significantly degrade compression. Alternatively, you can scan a
+ deflate stream once to generate an index, and then use that index for
+ random access. See examples/zran.c .
29. Does zlib work on MVS, OS/390, CICS, etc.?
- We don't know for sure. We have heard occasional reports of success on
- these systems. If you do use it on one of these, please provide us with
- a report, instructions, and patches that we can reference when we get
- these questions. Thanks.
+ It has in the past, but we have not heard of any recent evidence. There
+ were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+ If you know of recent, successful applications of zlib on these operating
+ systems, please let us know. Thanks.
-30. Is there some simpler, easier to read version of inflate I can look at
- to understand the deflate format?
+30. Is there some simpler, easier to read version of inflate I can look at to
+ understand the deflate format?
- First off, you should read RFC 1951. Second, yes. Look in zlib's
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
contrib/puff directory.
31. Does zlib infringe on any patents?
- As far as we know, no. In fact, that was originally the whole point behind
- zlib. Look here for some more information:
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
http://www.gzip.org/#faq11
32. Can zlib work with greater than 4 GB of data?
- Yes. inflate() and deflate() will process any amount of data correctly.
+ Yes. inflate() and deflate() will process any amount of data correctly.
Each call of inflate() or deflate() is limited to input and output chunks
of the maximum value that can be stored in the compiler's "unsigned int"
- type, but there is no limit to the number of chunks. Note however that the
- strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
counters are provided as a convenience and are not used internally by
- inflate() or deflate(). The application can easily set up its own counters
+ inflate() or deflate(). The application can easily set up its own counters
updated after each call of inflate() or deflate() to count beyond 4 GB.
compress() and uncompress() may be limited to 4 GB, since they operate in a
- single call. gzseek() and gztell() may be limited to 4 GB depending on how
- zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
- The word "may" appears several times above since there is a 4 GB limit
- only if the compiler's "long" type is 32 bits. If the compiler's "long"
- type is 64 bits, then the limit is 16 exabytes.
+ The word "may" appears several times above since there is a 4 GB limit only
+ if the compiler's "long" type is 32 bits. If the compiler's "long" type is
+ 64 bits, then the limit is 16 exabytes.
33. Does zlib have any security vulnerabilities?
- The only one that we are aware of is potentially in gzprintf(). If zlib
- is compiled to use sprintf() or vsprintf(), then there is no protection
- against a buffer overflow of a 4K string space, other than the caller of
- gzprintf() assuring that the output will not exceed 4K. On the other
- hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
- normally be the case, then there is no vulnerability. The ./configure
- script will display warnings if an insecure variation of sprintf() will
- be used by gzprintf(). Also the zlibCompileFlags() function will return
- information on what variant of sprintf() is used by gzprintf().
+ The only one that we are aware of is potentially in gzprintf(). If zlib is
+ compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of an 8K string space (or other value as set by
+ gzbuffer()), other than the caller of gzprintf() assuring that the output
+ will not exceed 8K. On the other hand, if zlib is compiled to use
+ snprintf() or vsnprintf(), which should normally be the case, then there is
+ no vulnerability. The ./configure script will display warnings if an
+ insecure variation of sprintf() will be used by gzprintf(). Also the
+ zlibCompileFlags() function will return information on what variant of
+ sprintf() is used by gzprintf().
If you don't have snprintf() or vsnprintf() and would like one, you can
find a portable implementation here:
http://www.ijs.si/software/snprintf/
- Note that you should be using the most recent version of zlib. Versions
- 1.1.3 and before were subject to a double-free vulnerability.
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability, and versions
+ 1.2.1 and 1.2.2 were subject to an access exception when decompressing
+ invalid compressed data.
34. Is there a Java version of zlib?
Probably what you want is to use zlib in Java. zlib is already included
as part of the Java SDK in the java.util.zip package. If you really want
a version of zlib written in the Java language, look on the zlib home
- page for links: http://www.zlib.org/
+ page for links: http://zlib.net/ .
35. I get this or that compiler or source-code scanner warning when I crank it
up to maximally-pedantic. Can't you guys write proper code?
Many years ago, we gave up attempting to avoid warnings on every compiler
- in the universe. It just got to be a waste of time, and some compilers
- were downright silly. So now, we simply make sure that the code always
- works.
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly as well as contradicted each other. So now, we simply
+ make sure that the code always works.
36. Valgrind (or some similar memory access checker) says that deflate is
performing a conditional jump that depends on an uninitialized value.
Isn't that a bug?
- No. That is intentional for performance reasons, and the output of
- deflate is not affected. This only started showing up recently since
- zlib 1.2.x uses malloc() by default for allocations, whereas earlier
- versions used calloc(), which zeros out the allocated memory.
+ No. That is intentional for performance reasons, and the output of deflate
+ is not affected. This only started showing up recently since zlib 1.2.x
+ uses malloc() by default for allocations, whereas earlier versions used
+ calloc(), which zeros out the allocated memory. Even though the code was
+ correct, versions 1.2.4 and later was changed to not stimulate these
+ checkers.
37. Will zlib read the (insert any ancient or arcane format here) compressed
data format?
@@ -305,20 +311,21 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
38. How can I encrypt/decrypt zip files with zlib?
- zlib doesn't support encryption. The original PKZIP encryption is very weak
- and can be broken with freely available programs. To get strong encryption,
- use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
- For PKZIP compatible "encryption", look at http://www.info-zip.org/
+ zlib doesn't support encryption. The original PKZIP encryption is very
+ weak and can be broken with freely available programs. To get strong
+ encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+ compression. For PKZIP compatible "encryption", look at
+ http://www.info-zip.org/
39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
- "gzip" is the gzip format, and "deflate" is the zlib format. They should
- probably have called the second one "zlib" instead to avoid confusion
- with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion with
+ the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
correctly points to the zlib specification in RFC 1950 for the "deflate"
transfer encoding, there have been reports of servers and browsers that
incorrectly produce or expect raw deflate data per the deflate
- specficiation in RFC 1951, most notably Microsoft. So even though the
+ specficiation in RFC 1951, most notably Microsoft. So even though the
"deflate" transfer encoding using the zlib format would be the more
efficient approach (and in fact exactly what the zlib format was designed
for), using the "gzip" transfer encoding is probably more reliable due to
@@ -328,12 +335,32 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
40. Does zlib support the new "Deflate64" format introduced by PKWare?
- No. PKWare has apparently decided to keep that format proprietary, since
- they have not documented it as they have previous compression formats.
- In any case, the compression improvements are so modest compared to other
- more modern approaches, that it's not worth the effort to implement.
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats. In
+ any case, the compression improvements are so modest compared to other more
+ modern approaches, that it's not worth the effort to implement.
-41. Can you please sign these lengthy legal documents and fax them back to us
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+ There are no zip functions in zlib. You are probably using minizip by
+ Giles Vollant, which is found in the contrib directory of zlib. It is not
+ part of zlib. In fact none of the stuff in contrib is part of zlib. The
+ files in there are not supported by the zlib authors. You need to contact
+ the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+ Since it's part of zlib, doesn't that mean that all of zlib falls under the
+ GNU GPL?
+
+ No. The files in contrib are not part of zlib. They were contributed by
+ other authors and are provided as a convenience to the user within the zlib
+ distribution. Each item in contrib has its own license.
+
+43. Is zlib subject to export controls? What is its ECCN?
+
+ zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
so that we can use your software in our product?
No. Go away. Shoo.
diff --git a/lib/libz/Makefile b/lib/libz/Makefile
index 595b4f3..8835e0d 100644
--- a/lib/libz/Makefile
+++ b/lib/libz/Makefile
@@ -4,21 +4,53 @@
LIB= z
SHLIBDIR?= /lib
+SHLIB_MAJOR= 6
MAN= zlib.3
-#CFLAGS+= -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS+= -g -DDEBUG
-#CFLAGS+= -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-# -Wstrict-prototypes -Wmissing-prototypes
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+= -DHAS_snprintf -DHAS_vsnprintf
+CFLAGS+= -DHAS_snprintf -DHAS_vsnprintf -I${.CURDIR}
WARNS?= 3
CLEANFILES+= example.o example foo.gz minigzip.o minigzip
-SRCS = adler32.c compress.c crc32.c gzio.c uncompr.c deflate.c trees.c \
- zutil.c inflate.c inftrees.c inffast.c zopen.c infback.c
+SRCS+= adler32.c
+SRCS+= compress.c
+SRCS+= crc32.c
+SRCS+= deflate.c
+SRCS+= gzclose.c
+SRCS+= gzlib.c
+SRCS+= gzread.c
+SRCS+= gzwrite.c
+SRCS+= infback.c
+SRCS+= inffast.c
+SRCS+= inflate.c
+SRCS+= inftrees.c
+SRCS+= trees.c
+SRCS+= uncompr.c
+SRCS+= zopen.c
+SRCS+= zutil.c
+
+.if ${MACHINE_ARCH} == "i386" && ${MACHINE_CPU:M*i686*}
+.PATH: ${.CURDIR}/contrib/asm686
+SRCS+= match.S
+CFLAGS+= -DASMV -DNO_UNDERLINE
+.endif
+
+.if ${MACHINE_ARCH} == "amd64"
+.PATH: ${.CURDIR}/contrib/gcc_gvmat64
+SRCS+= gvmat64.S
+CFLAGS+= -DASMV -DNO_UNDERLINE
+.endif
+
+VERSION_DEF= ${.CURDIR}/Versions.def
+SYMBOL_MAPS= ${.CURDIR}/Symbol.map
+CFLAGS+= -DSYMBOL_VERSIONING
+
INCS= zconf.h zlib.h
minigzip: all minigzip.o
diff --git a/lib/libz/README b/lib/libz/README
index 758cc50..d4219bf 100644
--- a/lib/libz/README
+++ b/lib/libz/README
@@ -1,56 +1,52 @@
ZLIB DATA COMPRESSION LIBRARY
-zlib 1.2.3 is a general purpose data compression library. All the code is
+zlib 1.2.5 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
-and rfc1952.txt (gzip format). These documents are also available in other
-formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+and rfc1952.txt (gzip format).
All functions of the compression library are documented in the file zlib.h
-(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
of the library is given in the file example.c which also tests that the library
-is working correctly. Another example is given in the file minigzip.c. The
+is working correctly. Another example is given in the file minigzip.c. The
compression library itself is composed of all source files except example.c and
minigzip.c.
To compile all files and run the test program, follow the instructions given at
-the top of Makefile. In short "make test; make install" should work for most
-machines. For Unix: "./configure; make test; make install". For MSDOS, use one
-of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
+the top of Makefile.in. In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix. For Windows, use one
+of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
-<info@winimage.com> for the Windows DLL version. The zlib home page is
-http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
-please check this site to verify that you have the latest version of zlib;
-otherwise get the latest version and check whether the problem still exists or
-not.
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
-PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
-for help.
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
-Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
-issue of Dr. Dobb's Journal; a copy of the article is available in
-http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
-The changes made in version 1.2.3 are documented in the file ChangeLog.
+The changes made in version 1.2.5 are documented in the file ChangeLog.
-Unsupported third party contributions are provided in directory "contrib".
+Unsupported third party contributions are provided in directory contrib/ .
-A Java implementation of zlib is available in the Java Development Kit
-http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
-See the zlib home page http://www.zlib.org for details.
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
-A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
-CPAN (Comprehensive Perl Archive Network) sites
-http://www.cpan.org/modules/by-module/Compress/
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
-http://www.python.org/doc/lib/module-zlib.html
+http://www.python.org/doc/lib/module-zlib.html .
-A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
-availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant <info@winimage.com>, is available in the
@@ -74,25 +70,21 @@ Notes for some targets:
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
other compilers. Use "make test" to check your compiler.
-- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+- gzdopen is not supported on RISCOS or BEOS.
- For PalmOs, see http://palmzlib.sourceforge.net/
-- When building a shared, i.e. dynamic library on Mac OS X, the library must be
- installed before testing (do "make install" before "make test"), since the
- library location is specified in the library.
-
Acknowledgments:
- The deflate format used by zlib was defined by Phil Katz. The deflate
- and zlib specifications were written by L. Peter Deutsch. Thanks to all the
- people who reported problems and suggested various improvements in zlib;
- they are too numerous to cite here.
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
Copyright notice:
- (C) 1995-2004 Jean-loup Gailly and Mark Adler
+ (C) 1995-2010 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -113,13 +105,11 @@ Copyright notice:
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
-If you use the zlib library in a product, we would appreciate *not*
-receiving lengthy legal documents to sign. The sources are provided
-for free but without warranty of any kind. The library has been
-entirely written by Jean-loup Gailly and Mark Adler; it does not
-include third-party code.
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
-If you redistribute modified sources, we would appreciate that you include
-in the file ChangeLog history information documenting your changes. Please
-read the FAQ for more information on the distribution of modified source
-versions.
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/lib/libz/Symbol.map b/lib/libz/Symbol.map
new file mode 100644
index 0000000..2651efc
--- /dev/null
+++ b/lib/libz/Symbol.map
@@ -0,0 +1,96 @@
+/*
+ * $FreeBSD$
+ */
+
+ZLIB_1.2.4.0 {
+ adler32;
+ adler32_combine;
+ adler32_combine64;
+ compress;
+ compress2;
+ compressBound;
+ crc32;
+ crc32_combine;
+ crc32_combine64;
+ deflate;
+ deflateBound;
+ deflateCopy;
+ deflateEnd;
+ deflateInit2_;
+ deflateInit_;
+ deflateParams;
+ deflatePrime;
+ deflateReset;
+ deflateSetDictionary;
+ deflateSetHeader;
+ deflateTune;
+ get_crc_table;
+ gzbuffer;
+ gzclearerr;
+ gzclose;
+ gzclose_r;
+ gzclose_w;
+ gzdirect;
+ gzdopen;
+ gzeof;
+ gzerror;
+ gzflush;
+ gzgetc;
+ gzgets;
+ gzoffset;
+ gzoffset64;
+ gzopen;
+ gzopen64;
+ gzprintf;
+ gzputc;
+ gzputs;
+ gzread;
+ gzrewind;
+ gzseek;
+ gzseek64;
+ gzsetparams;
+ gztell;
+ gztell64;
+ gzungetc;
+ gzwrite;
+ inflate;
+ inflateBack;
+ inflateBackEnd;
+ inflateBackInit_;
+ inflateCopy;
+ inflateEnd;
+ inflateGetHeader;
+ inflateInit2_;
+ inflateInit_;
+ inflateMark;
+ inflatePrime;
+ inflateReset;
+ inflateReset2;
+ inflateSetDictionary;
+ inflateSync;
+ inflateSyncPoint;
+ inflateUndermine;
+ uncompress;
+ zError;
+ zlibCompileFlags;
+ zlibVersion;
+};
+
+FBSD_1.2 {
+ zopen;
+};
+
+ZLIBprivate_1.0 {
+ _tr_align;
+ _tr_flush_block;
+ _tr_init;
+ _tr_stored_block;
+ _tr_tally;
+ gz_error;
+ inflate_fast;
+ inflate_table;
+ longest_match;
+ match_init;
+ zcalloc;
+ zcfree;
+};
diff --git a/lib/libz/Versions.def b/lib/libz/Versions.def
new file mode 100644
index 0000000..fe413a4
--- /dev/null
+++ b/lib/libz/Versions.def
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+ZLIB_1.2.4.0 {
+};
+
+FBSD_1.2 {
+} ZLIB_1.2.4.0;
+
+ZLIBprivate_1.0 {
+} ZLIB_1.2.4.0;
+
diff --git a/lib/libz/adler32.c b/lib/libz/adler32.c
index 007ba26..65ad6a5 100644
--- a/lib/libz/adler32.c
+++ b/lib/libz/adler32.c
@@ -1,12 +1,15 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2007 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
-#define ZLIB_INTERNAL
-#include "zlib.h"
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
#define BASE 65521UL /* largest prime smaller than 65536 */
#define NMAX 5552
@@ -125,10 +128,10 @@ uLong ZEXPORT adler32(adler, buf, len)
}
/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+local uLong adler32_combine_(adler1, adler2, len2)
uLong adler1;
uLong adler2;
- z_off_t len2;
+ z_off64_t len2;
{
unsigned long sum1;
unsigned long sum2;
@@ -141,9 +144,26 @@ uLong ZEXPORT adler32_combine(adler1, adler2, len2)
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/lib/libz/compress.c b/lib/libz/compress.c
index df04f01..ea4dfbe 100644
--- a/lib/libz/compress.c
+++ b/lib/libz/compress.c
@@ -1,5 +1,5 @@
/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -75,5 +75,6 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
uLong ZEXPORT compressBound (sourceLen)
uLong sourceLen;
{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13;
}
diff --git a/lib/libz/contrib/README.contrib b/lib/libz/contrib/README.contrib
new file mode 100644
index 0000000..dd2285d
--- /dev/null
+++ b/lib/libz/contrib/README.contrib
@@ -0,0 +1,77 @@
+All files under this contrib directory are UNSUPPORTED. There were
+provided by users of zlib and were not tested by the authors of zlib.
+Use at your own risk. Please contact the authors of the contributions
+for help about these, not the zlib authors. Thanks.
+
+
+ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
+ Support for Ada
+ See http://zlib-ada.sourceforge.net/
+
+amd64/ by Mikhail Teterin <mi@ALDAN.algebra.com>
+ asm code for AMD64
+ See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
+
+asm686/ by Brian Raiter <breadbox@muppetlabs.com>
+ asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+blast/ by Mark Adler <madler@alumni.caltech.edu>
+ Decompressor for output of PKWare Data Compression Library (DCL)
+
+delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ Support for Delphi and C++ Builder
+
+dotzlib/ by Henrik Ravn <henrik@ravn.com>
+ Support for Microsoft .Net and Visual C++ .Net
+
+gcc_gvmat64/by Gilles Vollant <info@winimage.com>
+ GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
+ assembler to replace longest_match() and inflate_fast()
+
+infback9/ by Mark Adler <madler@alumni.caltech.edu>
+ Unsupported diffs to infback to decode the deflate64 format
+
+inflate86/ by Chris Anderson <christop@charm.net>
+ Tuned x86 gcc asm code to replace inflate_fast()
+
+iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+
+iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+
+iostream3/ by Ludwig Schwardt <schwardt@sun.ac.za>
+ and Kevin Ruland <kevin@rodin.wustl.edu>
+ Yet another C++ I/O streams interface
+
+masmx64/ by Gilles Vollant <info@winimage.com>
+ x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
+ replace longest_match() and inflate_fast(), also masm x86
+ 64-bits translation of Chris Anderson inflate_fast()
+
+masmx86/ by Gilles Vollant <info@winimage.com>
+ x86 asm code to replace longest_match() and inflate_fast(),
+ for Visual C++ and MASM (32 bits).
+ Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
+
+minizip/ by Gilles Vollant <info@winimage.com>
+ Mini zip and unzip based on zlib
+ Includes Zip64 support by Mathias Svensson <mathias@result42.com>
+ See http://www.winimage.com/zLibDll/unzip.html
+
+pascal/ by Bob Dellaca <bobdl@xtra.co.nz> et al.
+ Support for Pascal
+
+puff/ by Mark Adler <madler@alumni.caltech.edu>
+ Small, low memory usage inflate. Also serves to provide an
+ unambiguous description of the deflate format.
+
+testzlib/ by Gilles Vollant <info@winimage.com>
+ Example of the use of zlib
+
+untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+
+vstudio/ by Gilles Vollant <info@winimage.com>
+ Building a minizip-enhanced zlib with Microsoft Visual Studio
diff --git a/lib/libz/contrib/asm686/README.686 b/lib/libz/contrib/asm686/README.686
new file mode 100644
index 0000000..a0bf3be
--- /dev/null
+++ b/lib/libz/contrib/asm686/README.686
@@ -0,0 +1,51 @@
+This is a patched version of zlib, modified to use
+Pentium-Pro-optimized assembly code in the deflation algorithm. The
+files changed/added by this patch are:
+
+README.686
+match.S
+
+The speedup that this patch provides varies, depending on whether the
+compiler used to build the original version of zlib falls afoul of the
+PPro's speed traps. My own tests show a speedup of around 10-20% at
+the default compression level, and 20-30% using -9, against a version
+compiled using gcc 2.7.2.3. Your mileage may vary.
+
+Note that this code has been tailored for the PPro/PII in particular,
+and will not perform particuarly well on a Pentium.
+
+If you are using an assembler other than GNU as, you will have to
+translate match.S to use your assembler's syntax. (Have fun.)
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 1998
+
+
+Added for zlib 1.1.3:
+
+The patches come from
+http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+To compile zlib with this asm file, copy match.S to the zlib directory
+then do:
+
+CFLAGS="-O3 -DASMV" ./configure
+make OBJA=match.o
+
+
+Update:
+
+I've been ignoring these assembly routines for years, believing that
+gcc's generated code had caught up with it sometime around gcc 2.95
+and the major rearchitecting of the Pentium 4. However, I recently
+learned that, despite what I believed, this code still has some life
+in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
+faster than the code produced by gcc 4.1.
+
+In acknowledgement of its continuing usefulness, I've altered the
+license to match that of the rest of zlib. Share and Enjoy!
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 2007
diff --git a/lib/libz/contrib/asm686/match.S b/lib/libz/contrib/asm686/match.S
new file mode 100644
index 0000000..06817e1
--- /dev/null
+++ b/lib/libz/contrib/asm686/match.S
@@ -0,0 +1,343 @@
+/* match.S -- x86 assembly version of the zlib longest_match() function.
+ * Optimized for the Intel 686 chips (PPro and later).
+ *
+ * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef NO_UNDERLINE
+#define match_init _match_init
+#define longest_match _longest_match
+#endif
+
+#define MAX_MATCH (258)
+#define MIN_MATCH (3)
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+
+#define chainlenwmask 0 /* high word: current chain len */
+ /* low word: s->wmask */
+#define window 4 /* local copy of s->window */
+#define windowbestlen 8 /* s->window + bestlen */
+#define scanstart 16 /* first two bytes of string */
+#define scanend 12 /* last two bytes of string */
+#define scanalign 20 /* dword-misalignment of string */
+#define nicematch 24 /* a good enough match size */
+#define bestlen 28 /* size of best match so far */
+#define scan 32 /* ptr to string wanting match */
+
+#define LocalVarsSize (36)
+/* saved ebx 36 */
+/* saved edi 40 */
+/* saved esi 44 */
+/* saved ebp 48 */
+/* return address 52 */
+#define deflatestate 56 /* the function arguments */
+#define curmatch 60
+
+/* All the +zlib1222add offsets are due to the addition of fields
+ * in zlib in the deflate_state structure since the asm code was first written
+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+ */
+
+#define zlib1222add (8)
+
+#define dsWSize (36+zlib1222add)
+#define dsWMask (44+zlib1222add)
+#define dsWindow (48+zlib1222add)
+#define dsPrev (56+zlib1222add)
+#define dsMatchLen (88+zlib1222add)
+#define dsPrevMatch (92+zlib1222add)
+#define dsStrStart (100+zlib1222add)
+#define dsMatchStart (104+zlib1222add)
+#define dsLookahead (108+zlib1222add)
+#define dsPrevLen (112+zlib1222add)
+#define dsMaxChainLen (116+zlib1222add)
+#define dsGoodMatch (132+zlib1222add)
+#define dsNiceMatch (136+zlib1222add)
+
+
+.file "match.S"
+
+.globl match_init, longest_match
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+
+longest_match:
+
+/* Save registers that the compiler may be using, and adjust %esp to */
+/* make room for our stack frame. */
+
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ subl $LocalVarsSize, %esp
+
+/* Retrieve the function arguments. %ecx will hold cur_match */
+/* throughout the entire function. %edx will hold the pointer to the */
+/* deflate_state structure during the function's setup (before */
+/* entering the main loop). */
+
+ movl deflatestate(%esp), %edx
+ movl curmatch(%esp), %ecx
+
+/* uInt wmask = s->w_mask; */
+/* unsigned chain_length = s->max_chain_length; */
+/* if (s->prev_length >= s->good_match) { */
+/* chain_length >>= 2; */
+/* } */
+
+ movl dsPrevLen(%edx), %eax
+ movl dsGoodMatch(%edx), %ebx
+ cmpl %ebx, %eax
+ movl dsWMask(%edx), %eax
+ movl dsMaxChainLen(%edx), %ebx
+ jl LastMatchGood
+ shrl $2, %ebx
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can */
+/* use the sign flag instead of the zero flag for the exit test. */
+/* It is then shifted into the high word, to make room for the wmask */
+/* value, which it will always accompany. */
+
+ decl %ebx
+ shll $16, %ebx
+ orl %eax, %ebx
+ movl %ebx, chainlenwmask(%esp)
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
+
+ movl dsNiceMatch(%edx), %eax
+ movl dsLookahead(%edx), %ebx
+ cmpl %eax, %ebx
+ jl LookaheadLess
+ movl %eax, %ebx
+LookaheadLess: movl %ebx, nicematch(%esp)
+
+/* register Bytef *scan = s->window + s->strstart; */
+
+ movl dsWindow(%edx), %esi
+ movl %esi, window(%esp)
+ movl dsStrStart(%edx), %ebp
+ lea (%esi,%ebp), %edi
+ movl %edi, scan(%esp)
+
+/* Determine how many bytes the scan ptr is off from being */
+/* dword-aligned. */
+
+ movl %edi, %eax
+ negl %eax
+ andl $3, %eax
+ movl %eax, scanalign(%esp)
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
+
+ movl dsWSize(%edx), %eax
+ subl $MIN_LOOKAHEAD, %eax
+ subl %eax, %ebp
+ jg LimitPositive
+ xorl %ebp, %ebp
+LimitPositive:
+
+/* int best_len = s->prev_length; */
+
+ movl dsPrevLen(%edx), %eax
+ movl %eax, bestlen(%esp)
+
+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
+
+ addl %eax, %esi
+ movl %esi, windowbestlen(%esp)
+
+/* register ush scan_start = *(ushf*)scan; */
+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
+/* Posf *prev = s->prev; */
+
+ movzwl (%edi), %ebx
+ movl %ebx, scanstart(%esp)
+ movzwl -1(%edi,%eax), %ebx
+ movl %ebx, scanend(%esp)
+ movl dsPrev(%edx), %edi
+
+/* Jump into the main loop. */
+
+ movl chainlenwmask(%esp), %edx
+ jmp LoopEntry
+
+.balign 16
+
+/* do {
+ * match = s->window + cur_match;
+ * if (*(ushf*)(match+best_len-1) != scan_end ||
+ * *(ushf*)match != scan_start) continue;
+ * [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ * && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ *
+ * Within this loop:
+ * %ebx = scanend
+ * %ecx = curmatch
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+ * %esi = windowbestlen - i.e., (window + bestlen)
+ * %edi = prev
+ * %ebp = limit
+ */
+LookupLoop:
+ andl %edx, %ecx
+ movzwl (%edi,%ecx,2), %ecx
+ cmpl %ebp, %ecx
+ jbe LeaveNow
+ subl $0x00010000, %edx
+ js LeaveNow
+LoopEntry: movzwl -1(%esi,%ecx), %eax
+ cmpl %ebx, %eax
+ jnz LookupLoop
+ movl window(%esp), %eax
+ movzwl (%eax,%ecx), %eax
+ cmpl scanstart(%esp), %eax
+ jnz LookupLoop
+
+/* Store the current value of chainlen. */
+
+ movl %edx, chainlenwmask(%esp)
+
+/* Point %edi to the string under scrutiny, and %esi to the string we */
+/* are hoping to match it up with. In actuality, %esi and %edi are */
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
+/* initialized to -(MAX_MATCH_8 - scanalign). */
+
+ movl window(%esp), %esi
+ movl scan(%esp), %edi
+ addl %ecx, %esi
+ movl scanalign(%esp), %eax
+ movl $(-MAX_MATCH_8), %edx
+ lea MAX_MATCH_8(%edi,%eax), %edi
+ lea MAX_MATCH_8(%esi,%eax), %esi
+
+/* Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %edx so that it is offset to the exact byte that mismatched.
+ *
+ * We already know at this point that the first three bytes of the
+ * strings match each other, and they can be safely passed over before
+ * starting the compare loop. So what this code does is skip over 0-3
+ * bytes, as much as necessary in order to dword-align the %edi
+ * pointer. (%esi will still be misaligned three times out of four.)
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance.
+ */
+LoopCmps:
+ movl (%esi,%edx), %eax
+ xorl (%edi,%edx), %eax
+ jnz LeaveLoopCmps
+ movl 4(%esi,%edx), %eax
+ xorl 4(%edi,%edx), %eax
+ jnz LeaveLoopCmps4
+ addl $8, %edx
+ jnz LoopCmps
+ jmp LenMaximum
+LeaveLoopCmps4: addl $4, %edx
+LeaveLoopCmps: testl $0x0000FFFF, %eax
+ jnz LenLower
+ addl $2, %edx
+ shrl $16, %eax
+LenLower: subb $1, %al
+ adcl $0, %edx
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
+/* then automatically accept it as the best possible match and leave. */
+
+ lea (%edi,%edx), %eax
+ movl scan(%esp), %edi
+ subl %edi, %eax
+ cmpl $MAX_MATCH, %eax
+ jge LenMaximum
+
+/* If the length of the match is not longer than the best match we */
+/* have so far, then forget it and return to the lookup loop. */
+
+ movl deflatestate(%esp), %edx
+ movl bestlen(%esp), %ebx
+ cmpl %ebx, %eax
+ jg LongerMatch
+ movl windowbestlen(%esp), %esi
+ movl dsPrev(%edx), %edi
+ movl scanend(%esp), %ebx
+ movl chainlenwmask(%esp), %edx
+ jmp LookupLoop
+
+/* s->match_start = cur_match; */
+/* best_len = len; */
+/* if (len >= nice_match) break; */
+/* scan_end = *(ushf*)(scan+best_len-1); */
+
+LongerMatch: movl nicematch(%esp), %ebx
+ movl %eax, bestlen(%esp)
+ movl %ecx, dsMatchStart(%edx)
+ cmpl %ebx, %eax
+ jge LeaveNow
+ movl window(%esp), %esi
+ addl %eax, %esi
+ movl %esi, windowbestlen(%esp)
+ movzwl -1(%edi,%eax), %ebx
+ movl dsPrev(%edx), %edi
+ movl %ebx, scanend(%esp)
+ movl chainlenwmask(%esp), %edx
+ jmp LookupLoop
+
+/* Accept the current string, with the maximum possible length. */
+
+LenMaximum: movl deflatestate(%esp), %edx
+ movl $MAX_MATCH, bestlen(%esp)
+ movl %ecx, dsMatchStart(%edx)
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
+/* return s->lookahead; */
+
+LeaveNow:
+ movl deflatestate(%esp), %edx
+ movl bestlen(%esp), %ebx
+ movl dsLookahead(%edx), %eax
+ cmpl %eax, %ebx
+ jg LookaheadRet
+ movl %ebx, %eax
+LookaheadRet:
+
+/* Restore the stack and return from whence we came. */
+
+ addl $LocalVarsSize, %esp
+ popl %ebx
+ popl %esi
+ popl %edi
+ popl %ebp
+match_init: ret
diff --git a/lib/libz/contrib/gcc_gvmat64/gvmat64.S b/lib/libz/contrib/gcc_gvmat64/gvmat64.S
new file mode 100644
index 0000000..23309fa
--- /dev/null
+++ b/lib/libz/contrib/gcc_gvmat64/gvmat64.S
@@ -0,0 +1,574 @@
+/*
+;uInt longest_match_x64(
+; deflate_state *s,
+; IPos cur_match); // current match
+
+; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64
+; (AMD64 on Athlon 64, Opteron, Phenom
+; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+; from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+; and by taking inspiration on asm686 with masm, optimised assembly code
+; from Brian Raiter, written 1998
+;
+; This software is provided 'as-is', without any express or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not be
+; misrepresented as being the original software
+; 3. This notice may not be removed or altered from any source distribution.
+;
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for zLib, I use option:
+; gcc -c -arch x86_64 gvmat64.S
+
+
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; // current match /
+;
+; with XCode for Mac, I had strange error with some jump on intel syntax
+; this is why BEFORE_JMP and AFTER_JMP are used
+ */
+
+
+#define BEFORE_JMP .att_syntax
+#define AFTER_JMP .intel_syntax noprefix
+
+#ifndef NO_UNDERLINE
+# define match_init _match_init
+# define longest_match _longest_match
+#endif
+
+.intel_syntax noprefix
+
+.globl match_init, longest_match
+.text
+longest_match:
+
+
+
+#define LocalVarsSize 96
+/*
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register : r14,r15
+; register can be saved : rsp
+*/
+
+#define chainlenwmask (rsp + 8 - LocalVarsSize)
+#define nicematch (rsp + 16 - LocalVarsSize)
+
+#define save_rdi (rsp + 24 - LocalVarsSize)
+#define save_rsi (rsp + 32 - LocalVarsSize)
+#define save_rbx (rsp + 40 - LocalVarsSize)
+#define save_rbp (rsp + 48 - LocalVarsSize)
+#define save_r12 (rsp + 56 - LocalVarsSize)
+#define save_r13 (rsp + 64 - LocalVarsSize)
+#define save_r14 (rsp + 72 - LocalVarsSize)
+#define save_r15 (rsp + 80 - LocalVarsSize)
+
+
+/*
+; all the +4 offsets are due to the addition of pending_buf_size (in zlib
+; in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, remove the +4).
+; Note : these value are good with a 8 bytes boundary pack structure
+*/
+
+#define MAX_MATCH 258
+#define MIN_MATCH 3
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+
+/*
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+*/
+
+
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+*/
+
+#define dsWSize 68
+#define dsWMask 76
+#define dsWindow 80
+#define dsPrev 96
+#define dsMatchLen 144
+#define dsPrevMatch 148
+#define dsStrStart 156
+#define dsMatchStart 160
+#define dsLookahead 164
+#define dsPrevLen 168
+#define dsMaxChainLen 172
+#define dsGoodMatch 188
+#define dsNiceMatch 192
+
+#define window_size [ rcx + dsWSize]
+#define WMask [ rcx + dsWMask]
+#define window_ad [ rcx + dsWindow]
+#define prev_ad [ rcx + dsPrev]
+#define strstart [ rcx + dsStrStart]
+#define match_start [ rcx + dsMatchStart]
+#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip
+#define prev_length [ rcx + dsPrevLen]
+#define max_chain_length [ rcx + dsMaxChainLen]
+#define good_match [ rcx + dsGoodMatch]
+#define nice_match [ rcx + dsNiceMatch]
+
+/*
+; windows:
+; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+;
+; gcc on macosx-linux:
+; see http://www.x86-64.org/documentation/abi-0.99.pdf
+; param 1 in rdi, param 2 in rsi
+; rbx, rsp, rbp, r12 to r15 must be preserved
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+; mac: param 1 in rdi, param 2 rsi
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+*/
+ mov [save_rbx],rbx
+ mov [save_rbp],rbp
+
+
+ mov rcx,rdi
+
+ mov r8d,esi
+
+
+ mov [save_r12],r12
+ mov [save_r13],r13
+ mov [save_r14],r14
+ mov [save_r15],r15
+
+
+//;;; uInt wmask = s->w_mask;
+//;;; unsigned chain_length = s->max_chain_length;
+//;;; if (s->prev_length >= s->good_match) {
+//;;; chain_length >>= 2;
+//;;; }
+
+
+ mov edi, prev_length
+ mov esi, good_match
+ mov eax, WMask
+ mov ebx, max_chain_length
+ cmp edi, esi
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+
+//;;; chainlen is decremented once beforehand so that the function can
+//;;; use the sign flag instead of the zero flag for the exit test.
+//;;; It is then shifted into the high word, to make room for the wmask
+//;;; value, which it will always accompany.
+
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+
+//;;; on zlib only
+//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+
+
+ mov eax, nice_match
+ mov [chainlenwmask], ebx
+ mov r10d, Lookahead
+ cmp r10d, eax
+ cmovnl r10d, eax
+ mov [nicematch],r10d
+
+
+
+//;;; register Bytef *scan = s->window + s->strstart;
+ mov r10, window_ad
+ mov ebp, strstart
+ lea r13, [r10 + rbp]
+
+//;;; Determine how many bytes the scan ptr is off from being
+//;;; dword-aligned.
+
+ mov r9,r13
+ neg r13
+ and r13,3
+
+//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+//;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+
+ mov eax, window_size
+ sub eax, MIN_LOOKAHEAD
+
+
+ xor edi,edi
+ sub ebp, eax
+
+ mov r11d, prev_length
+
+ cmovng ebp,edi
+
+//;;; int best_len = s->prev_length;
+
+
+//;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+ lea rsi,[r10+r11]
+
+//;;; register ush scan_start = *(ushf*)scan;
+//;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+//;;; Posf *prev = s->prev;
+
+ movzx r12d,word ptr [r9]
+ movzx ebx, word ptr [r9 + r11 - 1]
+
+ mov rdi, prev_ad
+
+//;;; Jump into the main loop.
+
+ mov edx, [chainlenwmask]
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+
+
+LookupLoop1:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+
+
+
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry1:
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jz LookupLoopIsZero
+ AFTER_JMP
+
+LookupLoop2:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry2:
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jz LookupLoopIsZero
+ AFTER_JMP
+
+LookupLoop4:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry4:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jnz LookupLoop1
+ jmp LookupLoopIsZero
+ AFTER_JMP
+/*
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+*/
+.balign 16
+LookupLoop:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jnz LookupLoop1
+ AFTER_JMP
+LookupLoopIsZero:
+ cmp r12w, word ptr [r10 + r8]
+ BEFORE_JMP
+ jnz LookupLoop1
+ AFTER_JMP
+
+
+//;;; Store the current value of chainlen.
+ mov [chainlenwmask], edx
+/*
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+*/
+ lea rsi,[r8+r10]
+ mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)
+ lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]
+ lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]
+
+ prefetcht1 [rsi+rdx]
+ prefetcht1 [rdi+rdx]
+
+/*
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+*/
+
+LoopCmps:
+ mov rax, [rsi + rdx]
+ xor rax, [rdi + rdx]
+ jnz LeaveLoopCmps
+
+ mov rax, [rsi + rdx + 8]
+ xor rax, [rdi + rdx + 8]
+ jnz LeaveLoopCmps8
+
+
+ mov rax, [rsi + rdx + 8+8]
+ xor rax, [rdi + rdx + 8+8]
+ jnz LeaveLoopCmps16
+
+ add rdx,8+8+8
+
+ BEFORE_JMP
+ jnz LoopCmps
+ jmp LenMaximum
+ AFTER_JMP
+
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+ test eax, 0x0000FFFF
+ jnz LenLower
+
+ test eax,0xffffffff
+
+ jnz LenLower32
+
+ add rdx,4
+ shr rax,32
+ or ax,ax
+ BEFORE_JMP
+ jnz LenLower
+ AFTER_JMP
+
+LenLower32:
+ shr eax,16
+ add rdx,2
+
+LenLower:
+ sub al, 1
+ adc rdx, 0
+//;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+//;;; then automatically accept it as the best possible match and leave.
+
+ lea rax, [rdi + rdx]
+ sub rax, r9
+ cmp eax, MAX_MATCH
+ BEFORE_JMP
+ jge LenMaximum
+ AFTER_JMP
+/*
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+*/
+ cmp eax, r11d
+ jg LongerMatch
+
+ lea rsi,[r10+r11]
+
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ BEFORE_JMP
+ jmp LookupLoop
+ AFTER_JMP
+/*
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+*/
+LongerMatch:
+ mov r11d, eax
+ mov match_start, r8d
+ cmp eax, [nicematch]
+ BEFORE_JMP
+ jge LeaveNow
+ AFTER_JMP
+
+ lea rsi,[r10+rax]
+
+ movzx ebx, word ptr [r9 + rax - 1]
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ BEFORE_JMP
+ jmp LookupLoop
+ AFTER_JMP
+
+//;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+ mov r11d,MAX_MATCH
+ mov match_start, r8d
+
+//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+//;;; return s->lookahead;
+
+LeaveNow:
+ mov eax, Lookahead
+ cmp r11d, eax
+ cmovng eax, r11d
+
+
+
+//;;; Restore the stack and return from whence we came.
+
+
+// mov rsi,[save_rsi]
+// mov rdi,[save_rdi]
+ mov rbx,[save_rbx]
+ mov rbp,[save_rbp]
+ mov r12,[save_r12]
+ mov r13,[save_r13]
+ mov r14,[save_r14]
+ mov r15,[save_r15]
+
+
+ ret 0
+//; please don't remove this string !
+//; Your can freely use gvmat64 in any free or commercial app
+//; but it is far better don't remove the string in the binary!
+ // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+
+
+match_init:
+ ret 0
+
+
diff --git a/lib/libz/crc32.c b/lib/libz/crc32.c
index f658a9e..91be372 100644
--- a/lib/libz/crc32.c
+++ b/lib/libz/crc32.c
@@ -1,5 +1,5 @@
/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2006, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
@@ -53,7 +53,7 @@
/* Definitions for doing the crc four data bytes at a time. */
#ifdef BYFOUR
-# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned));
@@ -68,6 +68,8 @@
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
+
#ifdef DYNAMIC_CRC_TABLE
@@ -219,7 +221,7 @@ const unsigned long FAR * ZEXPORT get_crc_table()
unsigned long ZEXPORT crc32(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
- unsigned len;
+ uInt len;
{
if (buf == Z_NULL) return 0UL;
@@ -367,22 +369,22 @@ local void gf2_matrix_square(square, mat)
}
/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+local uLong crc32_combine_(crc1, crc2, len2)
uLong crc1;
uLong crc2;
- z_off_t len2;
+ z_off64_t len2;
{
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
- /* degenerate case */
- if (len2 == 0)
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
return crc1;
/* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
@@ -421,3 +423,20 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2)
crc1 ^= crc2;
return crc1;
}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/lib/libz/deflate.c b/lib/libz/deflate.c
index 29ce1f6..5c4022f 100644
--- a/lib/libz/deflate.c
+++ b/lib/libz/deflate.c
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -52,7 +52,7 @@
#include "deflate.h"
const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
+ " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -79,19 +79,18 @@ local block_state deflate_fast OF((deflate_state *s, int flush));
#ifndef FASTEST
local block_state deflate_slow OF((deflate_state *s, int flush));
#endif
+local block_state deflate_rle OF((deflate_state *s, int flush));
+local block_state deflate_huff OF((deflate_state *s, int flush));
local void lm_init OF((deflate_state *s));
local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_streamp strm));
local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifndef FASTEST
#ifdef ASMV
void match_init OF((void)); /* asm code initialization */
uInt longest_match OF((deflate_state *s, IPos cur_match));
#else
local uInt longest_match OF((deflate_state *s, IPos cur_match));
#endif
-#endif
-local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
#ifdef DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match,
@@ -110,11 +109,6 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
#endif
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
/* Values for max_lazy_match, good_match and max_chain_length, depending on
* the desired pack level (0..9). The values given below have been tuned to
* exclude worst case performance for pathological files. Better values may be
@@ -288,6 +282,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+ s->high_water = 0; /* nothing written to s->window yet */
+
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
@@ -332,8 +328,8 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
strm->adler = adler32(strm->adler, dictionary, dictLength);
if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
+ if (length > s->w_size) {
+ length = s->w_size;
dictionary += dictLength - length; /* use the tail of the dictionary */
}
zmemcpy(s->window, dictionary, length);
@@ -435,9 +431,10 @@ int ZEXPORT deflateParams(strm, level, strategy)
}
func = configuration_table[s->level].func;
- if (func != configuration_table[level].func && strm->total_in != 0) {
+ if ((strategy != s->strategy || func != configuration_table[level].func) &&
+ strm->total_in != 0) {
/* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
+ err = deflate(strm, Z_BLOCK);
}
if (s->level != level) {
s->level = level;
@@ -481,33 +478,66 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
* resulting from using fixed blocks instead of stored blocks, which deflate
* can emit on compressed data for some combinations of the parameters.
*
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel. But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
deflate_state *s;
- uLong destLen;
+ uLong complen, wraplen;
+ Bytef *str;
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+ /* conservative upper bound for compressed data */
+ complen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
- /* if can't get parameters, return conservative bound */
+ /* if can't get parameters, return conservative bound plus zlib wrapper */
if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
+ return complen + 6;
- /* if not default parameters, return conservative bound */
+ /* compute wrapper length */
s = strm->state;
+ switch (s->wrap) {
+ case 0: /* raw deflate */
+ wraplen = 0;
+ break;
+ case 1: /* zlib wrapper */
+ wraplen = 6 + (s->strstart ? 4 : 0);
+ break;
+ case 2: /* gzip wrapper */
+ wraplen = 18;
+ if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
+ if (s->gzhead->extra != Z_NULL)
+ wraplen += 2 + s->gzhead->extra_len;
+ str = s->gzhead->name;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ str = s->gzhead->comment;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ if (s->gzhead->hcrc)
+ wraplen += 2;
+ }
+ break;
+ default: /* for compiler happiness */
+ wraplen = 6;
+ }
+
+ /* if not default parameters, return conservative bound */
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
+ return complen + wraplen;
/* default settings: return tight bound for that case */
- return compressBound(sourceLen);
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13 - 6 + wraplen;
}
/* =========================================================================
@@ -557,7 +587,7 @@ int ZEXPORT deflate (strm, flush)
deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
+ flush > Z_BLOCK || flush < 0) {
return Z_STREAM_ERROR;
}
s = strm->state;
@@ -581,7 +611,7 @@ int ZEXPORT deflate (strm, flush)
put_byte(s, 31);
put_byte(s, 139);
put_byte(s, 8);
- if (s->gzhead == NULL) {
+ if (s->gzhead == Z_NULL) {
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
@@ -608,7 +638,7 @@ int ZEXPORT deflate (strm, flush)
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
+ if (s->gzhead->extra != Z_NULL) {
put_byte(s, s->gzhead->extra_len & 0xff);
put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
}
@@ -650,7 +680,7 @@ int ZEXPORT deflate (strm, flush)
}
#ifdef GZIP
if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
+ if (s->gzhead->extra != Z_NULL) {
uInt beg = s->pending; /* start of bytes to update crc */
while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
@@ -678,7 +708,7 @@ int ZEXPORT deflate (strm, flush)
s->status = NAME_STATE;
}
if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
+ if (s->gzhead->name != Z_NULL) {
uInt beg = s->pending; /* start of bytes to update crc */
int val;
@@ -709,7 +739,7 @@ int ZEXPORT deflate (strm, flush)
s->status = COMMENT_STATE;
}
if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
+ if (s->gzhead->comment != Z_NULL) {
uInt beg = s->pending; /* start of bytes to update crc */
int val;
@@ -787,7 +817,9 @@ int ZEXPORT deflate (strm, flush)
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
block_state bstate;
- bstate = (*(configuration_table[s->level].func))(s, flush);
+ bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+ (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+ (*(configuration_table[s->level].func))(s, flush));
if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE;
@@ -808,13 +840,17 @@ int ZEXPORT deflate (strm, flush)
if (bstate == block_done) {
if (flush == Z_PARTIAL_FLUSH) {
_tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
+ } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
_tr_stored_block(s, (char*)0, 0L, 0);
/* For a full flush, this empty block will be recognized
* as a special marker by inflate_sync().
*/
if (flush == Z_FULL_FLUSH) {
CLEAR_HASH(s); /* forget history */
+ if (s->lookahead == 0) {
+ s->strstart = 0;
+ s->block_start = 0L;
+ }
}
}
flush_pending(strm);
@@ -1167,12 +1203,13 @@ local uInt longest_match(s, cur_match)
return s->lookahead;
}
#endif /* ASMV */
-#endif /* FASTEST */
+
+#else /* FASTEST */
/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
+ * Optimized version for FASTEST only
*/
-local uInt longest_match_fast(s, cur_match)
+local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
@@ -1225,6 +1262,8 @@ local uInt longest_match_fast(s, cur_match)
return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
}
+#endif /* FASTEST */
+
#ifdef DEBUG
/* ===========================================================================
* Check that the match at match_start is indeed a match.
@@ -1303,7 +1342,6 @@ local void fill_window(s)
later. (Using level 0 permanently is not an optimal usage of
zlib, so we don't care about this pathological case.)
*/
- /* %%% avoid this when Z_RLE */
n = s->hash_size;
p = &s->head[n];
do {
@@ -1355,27 +1393,61 @@ local void fill_window(s)
*/
} while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+ /* If the WIN_INIT bytes after the end of the current data have never been
+ * written, then zero those bytes in order to avoid memory check reports of
+ * the use of uninitialized (or uninitialised as Julian writes) bytes by
+ * the longest match routines. Update the high water mark for the next
+ * time through here. WIN_INIT is set to MAX_MATCH since the longest match
+ * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+ */
+ if (s->high_water < s->window_size) {
+ ulg curr = s->strstart + (ulg)(s->lookahead);
+ ulg init;
+
+ if (s->high_water < curr) {
+ /* Previous high water mark below current data -- zero WIN_INIT
+ * bytes or up to end of window, whichever is less.
+ */
+ init = s->window_size - curr;
+ if (init > WIN_INIT)
+ init = WIN_INIT;
+ zmemzero(s->window + curr, (unsigned)init);
+ s->high_water = curr + init;
+ }
+ else if (s->high_water < (ulg)curr + WIN_INIT) {
+ /* High water mark at or above current data, but below current data
+ * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+ * to end of window, whichever is less.
+ */
+ init = (ulg)curr + WIN_INIT - s->high_water;
+ if (init > s->window_size - s->high_water)
+ init = s->window_size - s->high_water;
+ zmemzero(s->window + s->high_water, (unsigned)init);
+ s->high_water += init;
+ }
+ }
}
/* ===========================================================================
* Flush the current block, with given end-of-file flag.
* IN assertion: strstart is set to the end of the current match.
*/
-#define FLUSH_BLOCK_ONLY(s, eof) { \
+#define FLUSH_BLOCK_ONLY(s, last) { \
_tr_flush_block(s, (s->block_start >= 0L ? \
(charf *)&s->window[(unsigned)s->block_start] : \
(charf *)Z_NULL), \
(ulg)((long)s->strstart - s->block_start), \
- (eof)); \
+ (last)); \
s->block_start = s->strstart; \
flush_pending(s->strm); \
Tracev((stderr,"[FLUSH]")); \
}
/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+#define FLUSH_BLOCK(s, last) { \
+ FLUSH_BLOCK_ONLY(s, last); \
+ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
}
/* ===========================================================================
@@ -1449,7 +1521,7 @@ local block_state deflate_fast(s, flush)
deflate_state *s;
int flush;
{
- IPos hash_head = NIL; /* head of the hash chain */
+ IPos hash_head; /* head of the hash chain */
int bflush; /* set if current block must be flushed */
for (;;) {
@@ -1469,6 +1541,7 @@ local block_state deflate_fast(s, flush)
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
+ hash_head = NIL;
if (s->lookahead >= MIN_MATCH) {
INSERT_STRING(s, s->strstart, hash_head);
}
@@ -1481,19 +1554,8 @@ local block_state deflate_fast(s, flush)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
-#ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#endif
- /* longest_match() or longest_match_fast() sets match_start */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
}
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length);
@@ -1555,7 +1617,7 @@ local block_state deflate_slow(s, flush)
deflate_state *s;
int flush;
{
- IPos hash_head = NIL; /* head of hash chain */
+ IPos hash_head; /* head of hash chain */
int bflush; /* set if current block must be flushed */
/* Process the input block. */
@@ -1576,6 +1638,7 @@ local block_state deflate_slow(s, flush)
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
+ hash_head = NIL;
if (s->lookahead >= MIN_MATCH) {
INSERT_STRING(s, s->strstart, hash_head);
}
@@ -1591,12 +1654,8 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED
#if TOO_FAR <= 32767
@@ -1674,7 +1733,6 @@ local block_state deflate_slow(s, flush)
}
#endif /* FASTEST */
-#if 0
/* ===========================================================================
* For Z_RLE, simply look for runs of bytes, generate matches only of distance
* one. Do not maintain a hash table. (It will be regenerated if this run of
@@ -1684,11 +1742,9 @@ local block_state deflate_rle(s, flush)
deflate_state *s;
int flush;
{
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
+ int bflush; /* set if current block must be flushed */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan, *strend; /* scan goes up to strend for length of run */
for (;;) {
/* Make sure that we always have enough lookahead, except
@@ -1704,23 +1760,33 @@ local block_state deflate_rle(s, flush)
}
/* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ s->match_length = 0;
+ if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
+ prev = *scan;
+ if (prev == *++scan && prev == *++scan && prev == *++scan) {
+ strend = s->window + s->strstart + MAX_MATCH;
+ do {
+ } while (prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ scan < strend);
+ s->match_length = MAX_MATCH - (int)(strend - scan);
+ if (s->match_length > s->lookahead)
+ s->match_length = s->lookahead;
+ }
}
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+ _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+ s->strstart += s->match_length;
+ s->match_length = 0;
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart]));
@@ -1733,4 +1799,36 @@ local block_state deflate_rle(s, flush)
FLUSH_BLOCK(s, flush == Z_FINISH);
return flush == Z_FINISH ? finish_done : block_done;
}
-#endif
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we have a literal to write. */
+ if (s->lookahead == 0) {
+ fill_window(s);
+ if (s->lookahead == 0) {
+ if (flush == Z_NO_FLUSH)
+ return need_more;
+ break; /* flush the current block */
+ }
+ }
+
+ /* Output a literal byte */
+ s->match_length = 0;
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/lib/libz/deflate.h b/lib/libz/deflate.h
index 05a5ab3..cbf0d1e 100644
--- a/lib/libz/deflate.h
+++ b/lib/libz/deflate.h
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
- * Copyright (C) 1995-2004 Jean-loup Gailly
+ * Copyright (C) 1995-2010 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -260,6 +260,13 @@ typedef struct internal_state {
* are always zero.
*/
+ ulg high_water;
+ /* High water mark offset in window for initialized bytes -- bytes above
+ * this are set to zero in order to avoid memory check warnings when
+ * longest match routines access bytes past the input. This is then
+ * updated to the new high water mark.
+ */
+
} FAR deflate_state;
/* Output a byte on the stream.
@@ -278,14 +285,18 @@ typedef struct internal_state {
* distances are limited to MAX_DIST instead of WSIZE.
*/
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+ memory checker errors from longest match routines */
+
/* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
@@ -298,11 +309,11 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
+ extern uch ZLIB_INTERNAL _length_code[];
+ extern uch ZLIB_INTERNAL _dist_code[];
#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
+ extern const uch ZLIB_INTERNAL _length_code[];
+ extern const uch ZLIB_INTERNAL _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
diff --git a/lib/libz/algorithm.txt b/lib/libz/doc/algorithm.txt
index b022dde..34960bd 100644
--- a/lib/libz/algorithm.txt
+++ b/lib/libz/doc/algorithm.txt
@@ -121,7 +121,7 @@ At least for deflate's output that generates new trees every several 10's of
kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
would take too long if you're only decoding several thousand symbols. At the
other extreme, you could make a new table for every bit in the code. In fact,
-that's essentially a Huffman tree. But then you spend two much time
+that's essentially a Huffman tree. But then you spend too much time
traversing the tree while decoding, even for short symbols.
So the number of bits for the first lookup table is a trade of the time to
diff --git a/lib/libz/doc/rfc1950.txt b/lib/libz/doc/rfc1950.txt
new file mode 100644
index 0000000..ce6428a
--- /dev/null
+++ b/lib/libz/doc/rfc1950.txt
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group P. Deutsch
+Request for Comments: 1950 Aladdin Enterprises
+Category: Informational J-L. Gailly
+ Info-ZIP
+ May 1996
+
+
+ ZLIB Compressed Data Format Specification version 3.3
+
+Status of This Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+IESG Note:
+
+ The IESG takes no position on the validity of any Intellectual
+ Property Rights statements contained in this document.
+
+Notices
+
+ Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
+
+ Permission is granted to copy and distribute this document for any
+ purpose and without charge, including translations into other
+ languages and incorporation into compilations, provided that the
+ copyright notice and this notice are preserved, and that any
+ substantive changes or deletions from the original are clearly
+ marked.
+
+ A pointer to the latest version of this and related documentation in
+ HTML format can be found at the URL
+ <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+ This specification defines a lossless compressed data format. The
+ data can be produced or consumed, even for an arbitrarily long
+ sequentially presented input data stream, using only an a priori
+ bounded amount of intermediate storage. The format presently uses
+ the DEFLATE compression method but can be easily extended to use
+ other compression methods. It can be implemented readily in a manner
+ not covered by patents. This specification also defines the ADLER-32
+ checksum (an extension and improvement of the Fletcher checksum),
+ used for detection of data corruption, and provides an algorithm for
+ computing it.
+
+
+
+
+Deutsch & Gailly Informational [Page 1]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 2
+ 1.1. Purpose ................................................... 2
+ 1.2. Intended audience ......................................... 3
+ 1.3. Scope ..................................................... 3
+ 1.4. Compliance ................................................ 3
+ 1.5. Definitions of terms and conventions used ................ 3
+ 1.6. Changes from previous versions ............................ 3
+ 2. Detailed specification ......................................... 3
+ 2.1. Overall conventions ....................................... 3
+ 2.2. Data format ............................................... 4
+ 2.3. Compliance ................................................ 7
+ 3. References ..................................................... 7
+ 4. Source code .................................................... 8
+ 5. Security Considerations ........................................ 8
+ 6. Acknowledgements ............................................... 8
+ 7. Authors' Addresses ............................................. 8
+ 8. Appendix: Rationale ............................................ 9
+ 9. Appendix: Sample code ..........................................10
+
+1. Introduction
+
+ 1.1. Purpose
+
+ The purpose of this specification is to define a lossless
+ compressed data format that:
+
+ * Is independent of CPU type, operating system, file system,
+ and character set, and hence can be used for interchange;
+
+ * Can be produced or consumed, even for an arbitrarily long
+ sequentially presented input data stream, using only an a
+ priori bounded amount of intermediate storage, and hence can
+ be used in data communications or similar structures such as
+ Unix filters;
+
+ * Can use a number of different compression methods;
+
+ * Can be implemented readily in a manner not covered by
+ patents, and hence can be practiced freely.
+
+ The data format defined by this specification does not attempt to
+ allow random access to compressed data.
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 2]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ 1.2. Intended audience
+
+ This specification is intended for use by implementors of software
+ to compress data into zlib format and/or decompress data from zlib
+ format.
+
+ The text of the specification assumes a basic background in
+ programming at the level of bits and other primitive data
+ representations.
+
+ 1.3. Scope
+
+ The specification specifies a compressed data format that can be
+ used for in-memory compression of a sequence of arbitrary bytes.
+
+ 1.4. Compliance
+
+ Unless otherwise indicated below, a compliant decompressor must be
+ able to accept and decompress any data set that conforms to all
+ the specifications presented here; a compliant compressor must
+ produce data sets that conform to all the specifications presented
+ here.
+
+ 1.5. Definitions of terms and conventions used
+
+ byte: 8 bits stored or transmitted as a unit (same as an octet).
+ (For this specification, a byte is exactly 8 bits, even on
+ machines which store a character on a number of bits different
+ from 8.) See below, for the numbering of bits within a byte.
+
+ 1.6. Changes from previous versions
+
+ Version 3.1 was the first public release of this specification.
+ In version 3.2, some terminology was changed and the Adler-32
+ sample code was rewritten for clarity. In version 3.3, the
+ support for a preset dictionary was introduced, and the
+ specification was converted to RFC style.
+
+2. Detailed specification
+
+ 2.1. Overall conventions
+
+ In the diagrams below, a box like this:
+
+ +---+
+ | | <-- the vertical bars might be missing
+ +---+
+
+
+
+
+Deutsch & Gailly Informational [Page 3]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ represents one byte; a box like this:
+
+ +==============+
+ | |
+ +==============+
+
+ represents a variable number of bytes.
+
+ Bytes stored within a computer do not have a "bit order", since
+ they are always treated as a unit. However, a byte considered as
+ an integer between 0 and 255 does have a most- and least-
+ significant bit, and since we write numbers with the most-
+ significant digit on the left, we also write bytes with the most-
+ significant bit on the left. In the diagrams below, we number the
+ bits of a byte so that bit 0 is the least-significant bit, i.e.,
+ the bits are numbered:
+
+ +--------+
+ |76543210|
+ +--------+
+
+ Within a computer, a number may occupy multiple bytes. All
+ multi-byte numbers in the format described here are stored with
+ the MOST-significant byte first (at the lower memory address).
+ For example, the decimal number 520 is stored as:
+
+ 0 1
+ +--------+--------+
+ |00000010|00001000|
+ +--------+--------+
+ ^ ^
+ | |
+ | + less significant byte = 8
+ + more significant byte = 2 x 256
+
+ 2.2. Data format
+
+ A zlib stream has the following structure:
+
+ 0 1
+ +---+---+
+ |CMF|FLG| (more-->)
+ +---+---+
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 4]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ (if FLG.FDICT set)
+
+ 0 1 2 3
+ +---+---+---+---+
+ | DICTID | (more-->)
+ +---+---+---+---+
+
+ +=====================+---+---+---+---+
+ |...compressed data...| ADLER32 |
+ +=====================+---+---+---+---+
+
+ Any data which may appear after ADLER32 are not part of the zlib
+ stream.
+
+ CMF (Compression Method and flags)
+ This byte is divided into a 4-bit compression method and a 4-
+ bit information field depending on the compression method.
+
+ bits 0 to 3 CM Compression method
+ bits 4 to 7 CINFO Compression info
+
+ CM (Compression method)
+ This identifies the compression method used in the file. CM = 8
+ denotes the "deflate" compression method with a window size up
+ to 32K. This is the method used by gzip and PNG (see
+ references [1] and [2] in Chapter 3, below, for the reference
+ documents). CM = 15 is reserved. It might be used in a future
+ version of this specification to indicate the presence of an
+ extra field before the compressed data.
+
+ CINFO (Compression info)
+ For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
+ size, minus eight (CINFO=7 indicates a 32K window size). Values
+ of CINFO above 7 are not allowed in this version of the
+ specification. CINFO is not defined in this specification for
+ CM not equal to 8.
+
+ FLG (FLaGs)
+ This flag byte is divided as follows:
+
+ bits 0 to 4 FCHECK (check bits for CMF and FLG)
+ bit 5 FDICT (preset dictionary)
+ bits 6 to 7 FLEVEL (compression level)
+
+ The FCHECK value must be such that CMF and FLG, when viewed as
+ a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
+ is a multiple of 31.
+
+
+
+
+Deutsch & Gailly Informational [Page 5]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ FDICT (Preset dictionary)
+ If FDICT is set, a DICT dictionary identifier is present
+ immediately after the FLG byte. The dictionary is a sequence of
+ bytes which are initially fed to the compressor without
+ producing any compressed output. DICT is the Adler-32 checksum
+ of this sequence of bytes (see the definition of ADLER32
+ below). The decompressor can use this identifier to determine
+ which dictionary has been used by the compressor.
+
+ FLEVEL (Compression level)
+ These flags are available for use by specific compression
+ methods. The "deflate" method (CM = 8) sets these flags as
+ follows:
+
+ 0 - compressor used fastest algorithm
+ 1 - compressor used fast algorithm
+ 2 - compressor used default algorithm
+ 3 - compressor used maximum compression, slowest algorithm
+
+ The information in FLEVEL is not needed for decompression; it
+ is there to indicate if recompression might be worthwhile.
+
+ compressed data
+ For compression method 8, the compressed data is stored in the
+ deflate compressed data format as described in the document
+ "DEFLATE Compressed Data Format Specification" by L. Peter
+ Deutsch. (See reference [3] in Chapter 3, below)
+
+ Other compressed data formats are not specified in this version
+ of the zlib specification.
+
+ ADLER32 (Adler-32 checksum)
+ This contains a checksum value of the uncompressed data
+ (excluding any dictionary data) computed according to Adler-32
+ algorithm. This algorithm is a 32-bit extension and improvement
+ of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+ standard. See references [4] and [5] in Chapter 3, below)
+
+ Adler-32 is composed of two sums accumulated per byte: s1 is
+ the sum of all bytes, s2 is the sum of all s1 values. Both sums
+ are done modulo 65521. s1 is initialized to 1, s2 to zero. The
+ Adler-32 checksum is stored as s2*65536 + s1 in most-
+ significant-byte first (network) order.
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 6]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ 2.3. Compliance
+
+ A compliant compressor must produce streams with correct CMF, FLG
+ and ADLER32, but need not support preset dictionaries. When the
+ zlib data format is used as part of another standard data format,
+ the compressor may use only preset dictionaries that are specified
+ by this other data format. If this other format does not use the
+ preset dictionary feature, the compressor must not set the FDICT
+ flag.
+
+ A compliant decompressor must check CMF, FLG, and ADLER32, and
+ provide an error indication if any of these have incorrect values.
+ A compliant decompressor must give an error indication if CM is
+ not one of the values defined in this specification (only the
+ value 8 is permitted in this version), since another value could
+ indicate the presence of new features that would cause subsequent
+ data to be interpreted incorrectly. A compliant decompressor must
+ give an error indication if FDICT is set and DICTID is not the
+ identifier of a known preset dictionary. A decompressor may
+ ignore FLEVEL and still be compliant. When the zlib data format
+ is being used as a part of another standard format, a compliant
+ decompressor must support all the preset dictionaries specified by
+ the other format. When the other format does not use the preset
+ dictionary feature, a compliant decompressor must reject any
+ stream in which the FDICT flag is set.
+
+3. References
+
+ [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
+ available in ftp://ftp.uu.net/graphics/png/documents/
+
+ [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [4] Fletcher, J. G., "An Arithmetic Checksum for Serial
+ Transmissions," IEEE Transactions on Communications, Vol. COM-30,
+ No. 1, January 1982, pp. 247-252.
+
+ [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
+ November, 1993, pp. 144, 145. (Available from
+ gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 7]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+4. Source code
+
+ Source code for a C language implementation of a "zlib" compliant
+ library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+5. Security Considerations
+
+ A decoder that fails to check the ADLER32 checksum value may be
+ subject to undetected data corruption.
+
+6. Acknowledgements
+
+ Trademarks cited in this document are the property of their
+ respective owners.
+
+ Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
+ the related software described in this specification. Glenn
+ Randers-Pehrson converted this document to RFC and HTML format.
+
+7. Authors' Addresses
+
+ L. Peter Deutsch
+ Aladdin Enterprises
+ 203 Santa Margarita Ave.
+ Menlo Park, CA 94025
+
+ Phone: (415) 322-0103 (AM only)
+ FAX: (415) 322-1734
+ EMail: <ghost@aladdin.com>
+
+
+ Jean-Loup Gailly
+
+ EMail: <gzip@prep.ai.mit.edu>
+
+ Questions about the technical content of this specification can be
+ sent by email to
+
+ Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+ Mark Adler <madler@alumni.caltech.edu>
+
+ Editorial comments on this specification can be sent by email to
+
+ L. Peter Deutsch <ghost@aladdin.com> and
+ Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 8]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+8. Appendix: Rationale
+
+ 8.1. Preset dictionaries
+
+ A preset dictionary is specially useful to compress short input
+ sequences. The compressor can take advantage of the dictionary
+ context to encode the input in a more compact manner. The
+ decompressor can be initialized with the appropriate context by
+ virtually decompressing a compressed version of the dictionary
+ without producing any output. However for certain compression
+ algorithms such as the deflate algorithm this operation can be
+ achieved without actually performing any decompression.
+
+ The compressor and the decompressor must use exactly the same
+ dictionary. The dictionary may be fixed or may be chosen among a
+ certain number of predefined dictionaries, according to the kind
+ of input data. The decompressor can determine which dictionary has
+ been chosen by the compressor by checking the dictionary
+ identifier. This document does not specify the contents of
+ predefined dictionaries, since the optimal dictionaries are
+ application specific. Standard data formats using this feature of
+ the zlib specification must precisely define the allowed
+ dictionaries.
+
+ 8.2. The Adler-32 algorithm
+
+ The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+ still provides an extremely low probability of undetected errors.
+
+ The modulo on unsigned long accumulators can be delayed for 5552
+ bytes, so the modulo operation time is negligible. If the bytes
+ are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+ and order sensitive, unlike the first sum, which is just a
+ checksum. That 65521 is prime is important to avoid a possible
+ large class of two-byte errors that leave the check unchanged.
+ (The Fletcher checksum uses 255, which is not prime and which also
+ makes the Fletcher check insensitive to single byte changes 0 <->
+ 255.)
+
+ The sum s1 is initialized to 1 instead of zero to make the length
+ of the sequence part of s2, so that the length does not have to be
+ checked separately. (Any sequence of zeroes has a Fletcher
+ checksum of zero.)
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 9]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+9. Appendix: Sample code
+
+ The following C code computes the Adler-32 checksum of a data buffer.
+ It is written for clarity, not for speed. The sample code is in the
+ ANSI C programming language. Non C users may find it easier to read
+ with these hints:
+
+ & Bitwise AND operator.
+ >> Bitwise right shift operator. When applied to an
+ unsigned quantity, as here, right shift inserts zero bit(s)
+ at the left.
+ << Bitwise left shift operator. Left shift inserts zero
+ bit(s) at the right.
+ ++ "n++" increments the variable n.
+ % modulo operator: a % b is the remainder of a divided by b.
+
+ #define BASE 65521 /* largest prime smaller than 65536 */
+
+ /*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1]
+ and return the updated checksum. The Adler-32 checksum should be
+ initialized to 1.
+
+ Usage example:
+
+ unsigned long adler = 1L;
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = update_adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+ */
+ unsigned long update_adler32(unsigned long adler,
+ unsigned char *buf, int len)
+ {
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int n;
+
+ for (n = 0; n < len; n++) {
+ s1 = (s1 + buf[n]) % BASE;
+ s2 = (s2 + s1) % BASE;
+ }
+ return (s2 << 16) + s1;
+ }
+
+ /* Return the adler32 of the bytes buf[0..len-1] */
+
+
+
+
+Deutsch & Gailly Informational [Page 10]
+
+RFC 1950 ZLIB Compressed Data Format Specification May 1996
+
+
+ unsigned long adler32(unsigned char *buf, int len)
+ {
+ return update_adler32(1L, buf, len);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch & Gailly Informational [Page 11]
+
diff --git a/lib/libz/doc/rfc1951.txt b/lib/libz/doc/rfc1951.txt
new file mode 100644
index 0000000..403c8c7
--- /dev/null
+++ b/lib/libz/doc/rfc1951.txt
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group P. Deutsch
+Request for Comments: 1951 Aladdin Enterprises
+Category: Informational May 1996
+
+
+ DEFLATE Compressed Data Format Specification version 1.3
+
+Status of This Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+IESG Note:
+
+ The IESG takes no position on the validity of any Intellectual
+ Property Rights statements contained in this document.
+
+Notices
+
+ Copyright (c) 1996 L. Peter Deutsch
+
+ Permission is granted to copy and distribute this document for any
+ purpose and without charge, including translations into other
+ languages and incorporation into compilations, provided that the
+ copyright notice and this notice are preserved, and that any
+ substantive changes or deletions from the original are clearly
+ marked.
+
+ A pointer to the latest version of this and related documentation in
+ HTML format can be found at the URL
+ <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+ This specification defines a lossless compressed data format that
+ compresses data using a combination of the LZ77 algorithm and Huffman
+ coding, with efficiency comparable to the best currently available
+ general-purpose compression methods. The data can be produced or
+ consumed, even for an arbitrarily long sequentially presented input
+ data stream, using only an a priori bounded amount of intermediate
+ storage. The format can be implemented readily in a manner not
+ covered by patents.
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 1]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 2
+ 1.1. Purpose ................................................... 2
+ 1.2. Intended audience ......................................... 3
+ 1.3. Scope ..................................................... 3
+ 1.4. Compliance ................................................ 3
+ 1.5. Definitions of terms and conventions used ................ 3
+ 1.6. Changes from previous versions ............................ 4
+ 2. Compressed representation overview ............................. 4
+ 3. Detailed specification ......................................... 5
+ 3.1. Overall conventions ....................................... 5
+ 3.1.1. Packing into bytes .................................. 5
+ 3.2. Compressed block format ................................... 6
+ 3.2.1. Synopsis of prefix and Huffman coding ............... 6
+ 3.2.2. Use of Huffman coding in the "deflate" format ....... 7
+ 3.2.3. Details of block format ............................. 9
+ 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
+ 3.2.5. Compressed blocks (length and distance codes) ...... 11
+ 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
+ 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
+ 3.3. Compliance ............................................... 14
+ 4. Compression algorithm details ................................. 14
+ 5. References .................................................... 16
+ 6. Security Considerations ....................................... 16
+ 7. Source code ................................................... 16
+ 8. Acknowledgements .............................................. 16
+ 9. Author's Address .............................................. 17
+
+1. Introduction
+
+ 1.1. Purpose
+
+ The purpose of this specification is to define a lossless
+ compressed data format that:
+ * Is independent of CPU type, operating system, file system,
+ and character set, and hence can be used for interchange;
+ * Can be produced or consumed, even for an arbitrarily long
+ sequentially presented input data stream, using only an a
+ priori bounded amount of intermediate storage, and hence
+ can be used in data communications or similar structures
+ such as Unix filters;
+ * Compresses data with efficiency comparable to the best
+ currently available general-purpose compression methods,
+ and in particular considerably better than the "compress"
+ program;
+ * Can be implemented readily in a manner not covered by
+ patents, and hence can be practiced freely;
+
+
+
+Deutsch Informational [Page 2]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ * Is compatible with the file format produced by the current
+ widely used gzip utility, in that conforming decompressors
+ will be able to read data produced by the existing gzip
+ compressor.
+
+ The data format defined by this specification does not attempt to:
+
+ * Allow random access to compressed data;
+ * Compress specialized data (e.g., raster graphics) as well
+ as the best currently available specialized algorithms.
+
+ A simple counting argument shows that no lossless compression
+ algorithm can compress every possible input data set. For the
+ format defined here, the worst case expansion is 5 bytes per 32K-
+ byte block, i.e., a size increase of 0.015% for large data sets.
+ English text usually compresses by a factor of 2.5 to 3;
+ executable files usually compress somewhat less; graphical data
+ such as raster images may compress much more.
+
+ 1.2. Intended audience
+
+ This specification is intended for use by implementors of software
+ to compress data into "deflate" format and/or decompress data from
+ "deflate" format.
+
+ The text of the specification assumes a basic background in
+ programming at the level of bits and other primitive data
+ representations. Familiarity with the technique of Huffman coding
+ is helpful but not required.
+
+ 1.3. Scope
+
+ The specification specifies a method for representing a sequence
+ of bytes as a (usually shorter) sequence of bits, and a method for
+ packing the latter bit sequence into bytes.
+
+ 1.4. Compliance
+
+ Unless otherwise indicated below, a compliant decompressor must be
+ able to accept and decompress any data set that conforms to all
+ the specifications presented here; a compliant compressor must
+ produce data sets that conform to all the specifications presented
+ here.
+
+ 1.5. Definitions of terms and conventions used
+
+ Byte: 8 bits stored or transmitted as a unit (same as an octet).
+ For this specification, a byte is exactly 8 bits, even on machines
+
+
+
+Deutsch Informational [Page 3]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ which store a character on a number of bits different from eight.
+ See below, for the numbering of bits within a byte.
+
+ String: a sequence of arbitrary bytes.
+
+ 1.6. Changes from previous versions
+
+ There have been no technical changes to the deflate format since
+ version 1.1 of this specification. In version 1.2, some
+ terminology was changed. Version 1.3 is a conversion of the
+ specification to RFC style.
+
+2. Compressed representation overview
+
+ A compressed data set consists of a series of blocks, corresponding
+ to successive blocks of input data. The block sizes are arbitrary,
+ except that non-compressible blocks are limited to 65,535 bytes.
+
+ Each block is compressed using a combination of the LZ77 algorithm
+ and Huffman coding. The Huffman trees for each block are independent
+ of those for previous or subsequent blocks; the LZ77 algorithm may
+ use a reference to a duplicated string occurring in a previous block,
+ up to 32K input bytes before.
+
+ Each block consists of two parts: a pair of Huffman code trees that
+ describe the representation of the compressed data part, and a
+ compressed data part. (The Huffman trees themselves are compressed
+ using Huffman encoding.) The compressed data consists of a series of
+ elements of two types: literal bytes (of strings that have not been
+ detected as duplicated within the previous 32K input bytes), and
+ pointers to duplicated strings, where a pointer is represented as a
+ pair <length, backward distance>. The representation used in the
+ "deflate" format limits distances to 32K bytes and lengths to 258
+ bytes, but does not limit the size of a block, except for
+ uncompressible blocks, which are limited as noted above.
+
+ Each type of value (literals, distances, and lengths) in the
+ compressed data is represented using a Huffman code, using one code
+ tree for literals and lengths and a separate code tree for distances.
+ The code trees for each block appear in a compact form just before
+ the compressed data for that block.
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 4]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+3. Detailed specification
+
+ 3.1. Overall conventions In the diagrams below, a box like this:
+
+ +---+
+ | | <-- the vertical bars might be missing
+ +---+
+
+ represents one byte; a box like this:
+
+ +==============+
+ | |
+ +==============+
+
+ represents a variable number of bytes.
+
+ Bytes stored within a computer do not have a "bit order", since
+ they are always treated as a unit. However, a byte considered as
+ an integer between 0 and 255 does have a most- and least-
+ significant bit, and since we write numbers with the most-
+ significant digit on the left, we also write bytes with the most-
+ significant bit on the left. In the diagrams below, we number the
+ bits of a byte so that bit 0 is the least-significant bit, i.e.,
+ the bits are numbered:
+
+ +--------+
+ |76543210|
+ +--------+
+
+ Within a computer, a number may occupy multiple bytes. All
+ multi-byte numbers in the format described here are stored with
+ the least-significant byte first (at the lower memory address).
+ For example, the decimal number 520 is stored as:
+
+ 0 1
+ +--------+--------+
+ |00001000|00000010|
+ +--------+--------+
+ ^ ^
+ | |
+ | + more significant byte = 2 x 256
+ + less significant byte = 8
+
+ 3.1.1. Packing into bytes
+
+ This document does not address the issue of the order in which
+ bits of a byte are transmitted on a bit-sequential medium,
+ since the final data format described here is byte- rather than
+
+
+
+Deutsch Informational [Page 5]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ bit-oriented. However, we describe the compressed block format
+ in below, as a sequence of data elements of various bit
+ lengths, not a sequence of bytes. We must therefore specify
+ how to pack these data elements into bytes to form the final
+ compressed byte sequence:
+
+ * Data elements are packed into bytes in order of
+ increasing bit number within the byte, i.e., starting
+ with the least-significant bit of the byte.
+ * Data elements other than Huffman codes are packed
+ starting with the least-significant bit of the data
+ element.
+ * Huffman codes are packed starting with the most-
+ significant bit of the code.
+
+ In other words, if one were to print out the compressed data as
+ a sequence of bytes, starting with the first byte at the
+ *right* margin and proceeding to the *left*, with the most-
+ significant bit of each byte on the left as usual, one would be
+ able to parse the result from right to left, with fixed-width
+ elements in the correct MSB-to-LSB order and Huffman codes in
+ bit-reversed order (i.e., with the first bit of the code in the
+ relative LSB position).
+
+ 3.2. Compressed block format
+
+ 3.2.1. Synopsis of prefix and Huffman coding
+
+ Prefix coding represents symbols from an a priori known
+ alphabet by bit sequences (codes), one code for each symbol, in
+ a manner such that different symbols may be represented by bit
+ sequences of different lengths, but a parser can always parse
+ an encoded string unambiguously symbol-by-symbol.
+
+ We define a prefix code in terms of a binary tree in which the
+ two edges descending from each non-leaf node are labeled 0 and
+ 1 and in which the leaf nodes correspond one-for-one with (are
+ labeled with) the symbols of the alphabet; then the code for a
+ symbol is the sequence of 0's and 1's on the edges leading from
+ the root to the leaf labeled with that symbol. For example:
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 6]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ /\ Symbol Code
+ 0 1 ------ ----
+ / \ A 00
+ /\ B B 1
+ 0 1 C 011
+ / \ D 010
+ A /\
+ 0 1
+ / \
+ D C
+
+ A parser can decode the next symbol from an encoded input
+ stream by walking down the tree from the root, at each step
+ choosing the edge corresponding to the next input bit.
+
+ Given an alphabet with known symbol frequencies, the Huffman
+ algorithm allows the construction of an optimal prefix code
+ (one which represents strings with those symbol frequencies
+ using the fewest bits of any possible prefix codes for that
+ alphabet). Such a code is called a Huffman code. (See
+ reference [1] in Chapter 5, references for additional
+ information on Huffman codes.)
+
+ Note that in the "deflate" format, the Huffman codes for the
+ various alphabets must not exceed certain maximum code lengths.
+ This constraint complicates the algorithm for computing code
+ lengths from symbol frequencies. Again, see Chapter 5,
+ references for details.
+
+ 3.2.2. Use of Huffman coding in the "deflate" format
+
+ The Huffman codes used for each alphabet in the "deflate"
+ format have two additional rules:
+
+ * All codes of a given bit length have lexicographically
+ consecutive values, in the same order as the symbols
+ they represent;
+
+ * Shorter codes lexicographically precede longer codes.
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 7]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ We could recode the example above to follow this rule as
+ follows, assuming that the order of the alphabet is ABCD:
+
+ Symbol Code
+ ------ ----
+ A 10
+ B 0
+ C 110
+ D 111
+
+ I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
+ lexicographically consecutive.
+
+ Given this rule, we can define the Huffman code for an alphabet
+ just by giving the bit lengths of the codes for each symbol of
+ the alphabet in order; this is sufficient to determine the
+ actual codes. In our example, the code is completely defined
+ by the sequence of bit lengths (2, 1, 3, 3). The following
+ algorithm generates the codes as integers, intended to be read
+ from most- to least-significant bit. The code lengths are
+ initially in tree[I].Len; the codes are produced in
+ tree[I].Code.
+
+ 1) Count the number of codes for each code length. Let
+ bl_count[N] be the number of codes of length N, N >= 1.
+
+ 2) Find the numerical value of the smallest code for each
+ code length:
+
+ code = 0;
+ bl_count[0] = 0;
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ code = (code + bl_count[bits-1]) << 1;
+ next_code[bits] = code;
+ }
+
+ 3) Assign numerical values to all codes, using consecutive
+ values for all codes of the same length with the base
+ values determined at step 2. Codes that are never used
+ (which have a bit length of zero) must not be assigned a
+ value.
+
+ for (n = 0; n <= max_code; n++) {
+ len = tree[n].Len;
+ if (len != 0) {
+ tree[n].Code = next_code[len];
+ next_code[len]++;
+ }
+
+
+
+Deutsch Informational [Page 8]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ }
+
+ Example:
+
+ Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
+ 3, 2, 4, 4). After step 1, we have:
+
+ N bl_count[N]
+ - -----------
+ 2 1
+ 3 5
+ 4 2
+
+ Step 2 computes the following next_code values:
+
+ N next_code[N]
+ - ------------
+ 1 0
+ 2 0
+ 3 2
+ 4 14
+
+ Step 3 produces the following code values:
+
+ Symbol Length Code
+ ------ ------ ----
+ A 3 010
+ B 3 011
+ C 3 100
+ D 3 101
+ E 3 110
+ F 2 00
+ G 4 1110
+ H 4 1111
+
+ 3.2.3. Details of block format
+
+ Each block of compressed data begins with 3 header bits
+ containing the following data:
+
+ first bit BFINAL
+ next 2 bits BTYPE
+
+ Note that the header bits do not necessarily begin on a byte
+ boundary, since a block does not necessarily occupy an integral
+ number of bytes.
+
+
+
+
+
+Deutsch Informational [Page 9]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ BFINAL is set if and only if this is the last block of the data
+ set.
+
+ BTYPE specifies how the data are compressed, as follows:
+
+ 00 - no compression
+ 01 - compressed with fixed Huffman codes
+ 10 - compressed with dynamic Huffman codes
+ 11 - reserved (error)
+
+ The only difference between the two compressed cases is how the
+ Huffman codes for the literal/length and distance alphabets are
+ defined.
+
+ In all cases, the decoding algorithm for the actual data is as
+ follows:
+
+ do
+ read block header from input stream.
+ if stored with no compression
+ skip any remaining bits in current partially
+ processed byte
+ read LEN and NLEN (see next section)
+ copy LEN bytes of data to output
+ otherwise
+ if compressed with dynamic Huffman codes
+ read representation of code trees (see
+ subsection below)
+ loop (until end of block code recognized)
+ decode literal/length value from input stream
+ if value < 256
+ copy value (literal byte) to output stream
+ otherwise
+ if value = end of block (256)
+ break from loop
+ otherwise (value = 257..285)
+ decode distance from input stream
+
+ move backwards distance bytes in the output
+ stream, and copy length bytes from this
+ position to the output stream.
+ end loop
+ while not last block
+
+ Note that a duplicated string reference may refer to a string
+ in a previous block; i.e., the backward distance may cross one
+ or more block boundaries. However a distance cannot refer past
+ the beginning of the output stream. (An application using a
+
+
+
+Deutsch Informational [Page 10]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ preset dictionary might discard part of the output stream; a
+ distance can refer to that part of the output stream anyway)
+ Note also that the referenced string may overlap the current
+ position; for example, if the last 2 bytes decoded have values
+ X and Y, a string reference with <length = 5, distance = 2>
+ adds X,Y,X,Y,X to the output stream.
+
+ We now specify each compression method in turn.
+
+ 3.2.4. Non-compressed blocks (BTYPE=00)
+
+ Any bits of input up to the next byte boundary are ignored.
+ The rest of the block consists of the following information:
+
+ 0 1 2 3 4...
+ +---+---+---+---+================================+
+ | LEN | NLEN |... LEN bytes of literal data...|
+ +---+---+---+---+================================+
+
+ LEN is the number of data bytes in the block. NLEN is the
+ one's complement of LEN.
+
+ 3.2.5. Compressed blocks (length and distance codes)
+
+ As noted above, encoded data blocks in the "deflate" format
+ consist of sequences of symbols drawn from three conceptually
+ distinct alphabets: either literal bytes, from the alphabet of
+ byte values (0..255), or <length, backward distance> pairs,
+ where the length is drawn from (3..258) and the distance is
+ drawn from (1..32,768). In fact, the literal and length
+ alphabets are merged into a single alphabet (0..285), where
+ values 0..255 represent literal bytes, the value 256 indicates
+ end-of-block, and values 257..285 represent length codes
+ (possibly in conjunction with extra bits following the symbol
+ code) as follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 11]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ Extra Extra Extra
+ Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
+ ---- ---- ------ ---- ---- ------- ---- ---- -------
+ 257 0 3 267 1 15,16 277 4 67-82
+ 258 0 4 268 1 17,18 278 4 83-98
+ 259 0 5 269 2 19-22 279 4 99-114
+ 260 0 6 270 2 23-26 280 4 115-130
+ 261 0 7 271 2 27-30 281 5 131-162
+ 262 0 8 272 2 31-34 282 5 163-194
+ 263 0 9 273 3 35-42 283 5 195-226
+ 264 0 10 274 3 43-50 284 5 227-257
+ 265 1 11,12 275 3 51-58 285 0 258
+ 266 1 13,14 276 3 59-66
+
+ The extra bits should be interpreted as a machine integer
+ stored with the most-significant bit first, e.g., bits 1110
+ represent the value 14.
+
+ Extra Extra Extra
+ Code Bits Dist Code Bits Dist Code Bits Distance
+ ---- ---- ---- ---- ---- ------ ---- ---- --------
+ 0 0 1 10 4 33-48 20 9 1025-1536
+ 1 0 2 11 4 49-64 21 9 1537-2048
+ 2 0 3 12 5 65-96 22 10 2049-3072
+ 3 0 4 13 5 97-128 23 10 3073-4096
+ 4 1 5,6 14 6 129-192 24 11 4097-6144
+ 5 1 7,8 15 6 193-256 25 11 6145-8192
+ 6 2 9-12 16 7 257-384 26 12 8193-12288
+ 7 2 13-16 17 7 385-512 27 12 12289-16384
+ 8 3 17-24 18 8 513-768 28 13 16385-24576
+ 9 3 25-32 19 8 769-1024 29 13 24577-32768
+
+ 3.2.6. Compression with fixed Huffman codes (BTYPE=01)
+
+ The Huffman codes for the two alphabets are fixed, and are not
+ represented explicitly in the data. The Huffman code lengths
+ for the literal/length alphabet are:
+
+ Lit Value Bits Codes
+ --------- ---- -----
+ 0 - 143 8 00110000 through
+ 10111111
+ 144 - 255 9 110010000 through
+ 111111111
+ 256 - 279 7 0000000 through
+ 0010111
+ 280 - 287 8 11000000 through
+ 11000111
+
+
+
+Deutsch Informational [Page 12]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ The code lengths are sufficient to generate the actual codes,
+ as described above; we show the codes in the table for added
+ clarity. Literal/length values 286-287 will never actually
+ occur in the compressed data, but participate in the code
+ construction.
+
+ Distance codes 0-31 are represented by (fixed-length) 5-bit
+ codes, with possible additional bits as shown in the table
+ shown in Paragraph 3.2.5, above. Note that distance codes 30-
+ 31 will never actually occur in the compressed data.
+
+ 3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
+
+ The Huffman codes for the two alphabets appear in the block
+ immediately after the header bits and before the actual
+ compressed data, first the literal/length code and then the
+ distance code. Each code is defined by a sequence of code
+ lengths, as discussed in Paragraph 3.2.2, above. For even
+ greater compactness, the code length sequences themselves are
+ compressed using a Huffman code. The alphabet for code lengths
+ is as follows:
+
+ 0 - 15: Represent code lengths of 0 - 15
+ 16: Copy the previous code length 3 - 6 times.
+ The next 2 bits indicate repeat length
+ (0 = 3, ... , 3 = 6)
+ Example: Codes 8, 16 (+2 bits 11),
+ 16 (+2 bits 10) will expand to
+ 12 code lengths of 8 (1 + 6 + 5)
+ 17: Repeat a code length of 0 for 3 - 10 times.
+ (3 bits of length)
+ 18: Repeat a code length of 0 for 11 - 138 times
+ (7 bits of length)
+
+ A code length of 0 indicates that the corresponding symbol in
+ the literal/length or distance alphabet will not occur in the
+ block, and should not participate in the Huffman code
+ construction algorithm given earlier. If only one distance
+ code is used, it is encoded using one bit, not zero bits; in
+ this case there is a single code length of one, with one unused
+ code. One distance code of zero bits means that there are no
+ distance codes used at all (the data is all literals).
+
+ We can now define the format of the block:
+
+ 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
+ 5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
+ 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
+
+
+
+Deutsch Informational [Page 13]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ (HCLEN + 4) x 3 bits: code lengths for the code length
+ alphabet given just above, in the order: 16, 17, 18,
+ 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+
+ These code lengths are interpreted as 3-bit integers
+ (0-7); as above, a code length of 0 means the
+ corresponding symbol (literal/length or distance code
+ length) is not used.
+
+ HLIT + 257 code lengths for the literal/length alphabet,
+ encoded using the code length Huffman code
+
+ HDIST + 1 code lengths for the distance alphabet,
+ encoded using the code length Huffman code
+
+ The actual compressed data of the block,
+ encoded using the literal/length and distance Huffman
+ codes
+
+ The literal/length symbol 256 (end of data),
+ encoded using the literal/length Huffman code
+
+ The code length repeat codes can cross from HLIT + 257 to the
+ HDIST + 1 code lengths. In other words, all code lengths form
+ a single sequence of HLIT + HDIST + 258 values.
+
+ 3.3. Compliance
+
+ A compressor may limit further the ranges of values specified in
+ the previous section and still be compliant; for example, it may
+ limit the range of backward pointers to some value smaller than
+ 32K. Similarly, a compressor may limit the size of blocks so that
+ a compressible block fits in memory.
+
+ A compliant decompressor must accept the full range of possible
+ values defined in the previous section, and must accept blocks of
+ arbitrary size.
+
+4. Compression algorithm details
+
+ While it is the intent of this document to define the "deflate"
+ compressed data format without reference to any particular
+ compression algorithm, the format is related to the compressed
+ formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
+ since many variations of LZ77 are patented, it is strongly
+ recommended that the implementor of a compressor follow the general
+ algorithm presented here, which is known not to be patented per se.
+ The material in this section is not part of the definition of the
+
+
+
+Deutsch Informational [Page 14]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+ specification per se, and a compressor need not follow it in order to
+ be compliant.
+
+ The compressor terminates a block when it determines that starting a
+ new block with fresh trees would be useful, or when the block size
+ fills up the compressor's block buffer.
+
+ The compressor uses a chained hash table to find duplicated strings,
+ using a hash function that operates on 3-byte sequences. At any
+ given point during compression, let XYZ be the next 3 input bytes to
+ be examined (not necessarily all different, of course). First, the
+ compressor examines the hash chain for XYZ. If the chain is empty,
+ the compressor simply writes out X as a literal byte and advances one
+ byte in the input. If the hash chain is not empty, indicating that
+ the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
+ same hash function value) has occurred recently, the compressor
+ compares all strings on the XYZ hash chain with the actual input data
+ sequence starting at the current point, and selects the longest
+ match.
+
+ The compressor searches the hash chains starting with the most recent
+ strings, to favor small distances and thus take advantage of the
+ Huffman encoding. The hash chains are singly linked. There are no
+ deletions from the hash chains; the algorithm simply discards matches
+ that are too old. To avoid a worst-case situation, very long hash
+ chains are arbitrarily truncated at a certain length, determined by a
+ run-time parameter.
+
+ To improve overall compression, the compressor optionally defers the
+ selection of matches ("lazy matching"): after a match of length N has
+ been found, the compressor searches for a longer match starting at
+ the next input byte. If it finds a longer match, it truncates the
+ previous match to a length of one (thus producing a single literal
+ byte) and then emits the longer match. Otherwise, it emits the
+ original match, and, as described above, advances N bytes before
+ continuing.
+
+ Run-time parameters also control this "lazy match" procedure. If
+ compression ratio is most important, the compressor attempts a
+ complete second search regardless of the length of the first match.
+ In the normal case, if the current match is "long enough", the
+ compressor reduces the search for a longer match, thus speeding up
+ the process. If speed is most important, the compressor inserts new
+ strings in the hash table only when no match was found, or when the
+ match is not "too long". This degrades the compression ratio but
+ saves time since there are both fewer insertions and fewer searches.
+
+
+
+
+
+Deutsch Informational [Page 15]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+5. References
+
+ [1] Huffman, D. A., "A Method for the Construction of Minimum
+ Redundancy Codes", Proceedings of the Institute of Radio
+ Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
+
+ [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
+ Compression", IEEE Transactions on Information Theory, Vol. 23,
+ No. 3, pp. 337-343.
+
+ [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
+ available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
+
+ [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
+ encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
+
+ [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
+ Comm. ACM, 33,4, April 1990, pp. 449-459.
+
+6. Security Considerations
+
+ Any data compression method involves the reduction of redundancy in
+ the data. Consequently, any corruption of the data is likely to have
+ severe effects and be difficult to correct. Uncompressed text, on
+ the other hand, will probably still be readable despite the presence
+ of some corrupted bytes.
+
+ It is recommended that systems using this data format provide some
+ means of validating the integrity of the compressed data. See
+ reference [3], for example.
+
+7. Source code
+
+ Source code for a C language implementation of a "deflate" compliant
+ compressor and decompressor is available within the zlib package at
+ ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+8. Acknowledgements
+
+ Trademarks cited in this document are the property of their
+ respective owners.
+
+ Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
+ Adler wrote the related software described in this specification.
+ Glenn Randers-Pehrson converted this document to RFC and HTML format.
+
+
+
+Deutsch Informational [Page 16]
+
+RFC 1951 DEFLATE Compressed Data Format Specification May 1996
+
+
+9. Author's Address
+
+ L. Peter Deutsch
+ Aladdin Enterprises
+ 203 Santa Margarita Ave.
+ Menlo Park, CA 94025
+
+ Phone: (415) 322-0103 (AM only)
+ FAX: (415) 322-1734
+ EMail: <ghost@aladdin.com>
+
+ Questions about the technical content of this specification can be
+ sent by email to:
+
+ Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+ Mark Adler <madler@alumni.caltech.edu>
+
+ Editorial comments on this specification can be sent by email to:
+
+ L. Peter Deutsch <ghost@aladdin.com> and
+ Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 17]
+
diff --git a/lib/libz/doc/rfc1952.txt b/lib/libz/doc/rfc1952.txt
new file mode 100644
index 0000000..a8e51b4
--- /dev/null
+++ b/lib/libz/doc/rfc1952.txt
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+Network Working Group P. Deutsch
+Request for Comments: 1952 Aladdin Enterprises
+Category: Informational May 1996
+
+
+ GZIP file format specification version 4.3
+
+Status of This Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+IESG Note:
+
+ The IESG takes no position on the validity of any Intellectual
+ Property Rights statements contained in this document.
+
+Notices
+
+ Copyright (c) 1996 L. Peter Deutsch
+
+ Permission is granted to copy and distribute this document for any
+ purpose and without charge, including translations into other
+ languages and incorporation into compilations, provided that the
+ copyright notice and this notice are preserved, and that any
+ substantive changes or deletions from the original are clearly
+ marked.
+
+ A pointer to the latest version of this and related documentation in
+ HTML format can be found at the URL
+ <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+ This specification defines a lossless compressed data format that is
+ compatible with the widely used GZIP utility. The format includes a
+ cyclic redundancy check value for detecting data corruption. The
+ format presently uses the DEFLATE method of compression but can be
+ easily extended to use other compression methods. The format can be
+ implemented readily in a manner not covered by patents.
+
+
+
+
+
+
+
+
+
+
+Deutsch Informational [Page 1]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+Table of Contents
+
+ 1. Introduction ................................................... 2
+ 1.1. Purpose ................................................... 2
+ 1.2. Intended audience ......................................... 3
+ 1.3. Scope ..................................................... 3
+ 1.4. Compliance ................................................ 3
+ 1.5. Definitions of terms and conventions used ................. 3
+ 1.6. Changes from previous versions ............................ 3
+ 2. Detailed specification ......................................... 4
+ 2.1. Overall conventions ....................................... 4
+ 2.2. File format ............................................... 5
+ 2.3. Member format ............................................. 5
+ 2.3.1. Member header and trailer ........................... 6
+ 2.3.1.1. Extra field ................................... 8
+ 2.3.1.2. Compliance .................................... 9
+ 3. References .................................................. 9
+ 4. Security Considerations .................................... 10
+ 5. Acknowledgements ........................................... 10
+ 6. Author's Address ........................................... 10
+ 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
+ 8. Appendix: Sample CRC Code .................................. 11
+
+1. Introduction
+
+ 1.1. Purpose
+
+ The purpose of this specification is to define a lossless
+ compressed data format that:
+
+ * Is independent of CPU type, operating system, file system,
+ and character set, and hence can be used for interchange;
+ * Can compress or decompress a data stream (as opposed to a
+ randomly accessible file) to produce another data stream,
+ using only an a priori bounded amount of intermediate
+ storage, and hence can be used in data communications or
+ similar structures such as Unix filters;
+ * Compresses data with efficiency comparable to the best
+ currently available general-purpose compression methods,
+ and in particular considerably better than the "compress"
+ program;
+ * Can be implemented readily in a manner not covered by
+ patents, and hence can be practiced freely;
+ * Is compatible with the file format produced by the current
+ widely used gzip utility, in that conforming decompressors
+ will be able to read data produced by the existing gzip
+ compressor.
+
+
+
+
+Deutsch Informational [Page 2]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ The data format defined by this specification does not attempt to:
+
+ * Provide random access to compressed data;
+ * Compress specialized data (e.g., raster graphics) as well as
+ the best currently available specialized algorithms.
+
+ 1.2. Intended audience
+
+ This specification is intended for use by implementors of software
+ to compress data into gzip format and/or decompress data from gzip
+ format.
+
+ The text of the specification assumes a basic background in
+ programming at the level of bits and other primitive data
+ representations.
+
+ 1.3. Scope
+
+ The specification specifies a compression method and a file format
+ (the latter assuming only that a file can store a sequence of
+ arbitrary bytes). It does not specify any particular interface to
+ a file system or anything about character sets or encodings
+ (except for file names and comments, which are optional).
+
+ 1.4. Compliance
+
+ Unless otherwise indicated below, a compliant decompressor must be
+ able to accept and decompress any file that conforms to all the
+ specifications presented here; a compliant compressor must produce
+ files that conform to all the specifications presented here. The
+ material in the appendices is not part of the specification per se
+ and is not relevant to compliance.
+
+ 1.5. Definitions of terms and conventions used
+
+ byte: 8 bits stored or transmitted as a unit (same as an octet).
+ (For this specification, a byte is exactly 8 bits, even on
+ machines which store a character on a number of bits different
+ from 8.) See below for the numbering of bits within a byte.
+
+ 1.6. Changes from previous versions
+
+ There have been no technical changes to the gzip format since
+ version 4.1 of this specification. In version 4.2, some
+ terminology was changed, and the sample CRC code was rewritten for
+ clarity and to eliminate the requirement for the caller to do pre-
+ and post-conditioning. Version 4.3 is a conversion of the
+ specification to RFC style.
+
+
+
+Deutsch Informational [Page 3]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+2. Detailed specification
+
+ 2.1. Overall conventions
+
+ In the diagrams below, a box like this:
+
+ +---+
+ | | <-- the vertical bars might be missing
+ +---+
+
+ represents one byte; a box like this:
+
+ +==============+
+ | |
+ +==============+
+
+ represents a variable number of bytes.
+
+ Bytes stored within a computer do not have a "bit order", since
+ they are always treated as a unit. However, a byte considered as
+ an integer between 0 and 255 does have a most- and least-
+ significant bit, and since we write numbers with the most-
+ significant digit on the left, we also write bytes with the most-
+ significant bit on the left. In the diagrams below, we number the
+ bits of a byte so that bit 0 is the least-significant bit, i.e.,
+ the bits are numbered:
+
+ +--------+
+ |76543210|
+ +--------+
+
+ This document does not address the issue of the order in which
+ bits of a byte are transmitted on a bit-sequential medium, since
+ the data format described here is byte- rather than bit-oriented.
+
+ Within a computer, a number may occupy multiple bytes. All
+ multi-byte numbers in the format described here are stored with
+ the least-significant byte first (at the lower memory address).
+ For example, the decimal number 520 is stored as:
+
+ 0 1
+ +--------+--------+
+ |00001000|00000010|
+ +--------+--------+
+ ^ ^
+ | |
+ | + more significant byte = 2 x 256
+ + less significant byte = 8
+
+
+
+Deutsch Informational [Page 4]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ 2.2. File format
+
+ A gzip file consists of a series of "members" (compressed data
+ sets). The format of each member is specified in the following
+ section. The members simply appear one after another in the file,
+ with no additional information before, between, or after them.
+
+ 2.3. Member format
+
+ Each member has the following structure:
+
+ +---+---+---+---+---+---+---+---+---+---+
+ |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+ +---+---+---+---+---+---+---+---+---+---+
+
+ (if FLG.FEXTRA set)
+
+ +---+---+=================================+
+ | XLEN |...XLEN bytes of "extra field"...| (more-->)
+ +---+---+=================================+
+
+ (if FLG.FNAME set)
+
+ +=========================================+
+ |...original file name, zero-terminated...| (more-->)
+ +=========================================+
+
+ (if FLG.FCOMMENT set)
+
+ +===================================+
+ |...file comment, zero-terminated...| (more-->)
+ +===================================+
+
+ (if FLG.FHCRC set)
+
+ +---+---+
+ | CRC16 |
+ +---+---+
+
+ +=======================+
+ |...compressed blocks...| (more-->)
+ +=======================+
+
+ 0 1 2 3 4 5 6 7
+ +---+---+---+---+---+---+---+---+
+ | CRC32 | ISIZE |
+ +---+---+---+---+---+---+---+---+
+
+
+
+
+Deutsch Informational [Page 5]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ 2.3.1. Member header and trailer
+
+ ID1 (IDentification 1)
+ ID2 (IDentification 2)
+ These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
+ (0x8b, \213), to identify the file as being in gzip format.
+
+ CM (Compression Method)
+ This identifies the compression method used in the file. CM
+ = 0-7 are reserved. CM = 8 denotes the "deflate"
+ compression method, which is the one customarily used by
+ gzip and which is documented elsewhere.
+
+ FLG (FLaGs)
+ This flag byte is divided into individual bits as follows:
+
+ bit 0 FTEXT
+ bit 1 FHCRC
+ bit 2 FEXTRA
+ bit 3 FNAME
+ bit 4 FCOMMENT
+ bit 5 reserved
+ bit 6 reserved
+ bit 7 reserved
+
+ If FTEXT is set, the file is probably ASCII text. This is
+ an optional indication, which the compressor may set by
+ checking a small amount of the input data to see whether any
+ non-ASCII characters are present. In case of doubt, FTEXT
+ is cleared, indicating binary data. For systems which have
+ different file formats for ascii text and binary data, the
+ decompressor can use FTEXT to choose the appropriate format.
+ We deliberately do not specify the algorithm used to set
+ this bit, since a compressor always has the option of
+ leaving it cleared and a decompressor always has the option
+ of ignoring it and letting some other program handle issues
+ of data conversion.
+
+ If FHCRC is set, a CRC16 for the gzip header is present,
+ immediately before the compressed data. The CRC16 consists
+ of the two least significant bytes of the CRC32 for all
+ bytes of the gzip header up to and not including the CRC16.
+ [The FHCRC bit was never set by versions of gzip up to
+ 1.2.4, even though it was documented with a different
+ meaning in gzip 1.2.4.]
+
+ If FEXTRA is set, optional extra fields are present, as
+ described in a following section.
+
+
+
+Deutsch Informational [Page 6]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ If FNAME is set, an original file name is present,
+ terminated by a zero byte. The name must consist of ISO
+ 8859-1 (LATIN-1) characters; on operating systems using
+ EBCDIC or any other character set for file names, the name
+ must be translated to the ISO LATIN-1 character set. This
+ is the original name of the file being compressed, with any
+ directory components removed, and, if the file being
+ compressed is on a file system with case insensitive names,
+ forced to lower case. There is no original file name if the
+ data was compressed from a source other than a named file;
+ for example, if the source was stdin on a Unix system, there
+ is no file name.
+
+ If FCOMMENT is set, a zero-terminated file comment is
+ present. This comment is not interpreted; it is only
+ intended for human consumption. The comment must consist of
+ ISO 8859-1 (LATIN-1) characters. Line breaks should be
+ denoted by a single line feed character (10 decimal).
+
+ Reserved FLG bits must be zero.
+
+ MTIME (Modification TIME)
+ This gives the most recent modification time of the original
+ file being compressed. The time is in Unix format, i.e.,
+ seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this
+ may cause problems for MS-DOS and other systems that use
+ local rather than Universal time.) If the compressed data
+ did not come from a file, MTIME is set to the time at which
+ compression started. MTIME = 0 means no time stamp is
+ available.
+
+ XFL (eXtra FLags)
+ These flags are available for use by specific compression
+ methods. The "deflate" method (CM = 8) sets these flags as
+ follows:
+
+ XFL = 2 - compressor used maximum compression,
+ slowest algorithm
+ XFL = 4 - compressor used fastest algorithm
+
+ OS (Operating System)
+ This identifies the type of file system on which compression
+ took place. This may be useful in determining end-of-line
+ convention for text files. The currently defined values are
+ as follows:
+
+
+
+
+
+
+Deutsch Informational [Page 7]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
+ 1 - Amiga
+ 2 - VMS (or OpenVMS)
+ 3 - Unix
+ 4 - VM/CMS
+ 5 - Atari TOS
+ 6 - HPFS filesystem (OS/2, NT)
+ 7 - Macintosh
+ 8 - Z-System
+ 9 - CP/M
+ 10 - TOPS-20
+ 11 - NTFS filesystem (NT)
+ 12 - QDOS
+ 13 - Acorn RISCOS
+ 255 - unknown
+
+ XLEN (eXtra LENgth)
+ If FLG.FEXTRA is set, this gives the length of the optional
+ extra field. See below for details.
+
+ CRC32 (CRC-32)
+ This contains a Cyclic Redundancy Check value of the
+ uncompressed data computed according to CRC-32 algorithm
+ used in the ISO 3309 standard and in section 8.1.1.6.2 of
+ ITU-T recommendation V.42. (See http://www.iso.ch for
+ ordering ISO documents. See gopher://info.itu.ch for an
+ online version of ITU-T V.42.)
+
+ ISIZE (Input SIZE)
+ This contains the size of the original (uncompressed) input
+ data modulo 2^32.
+
+ 2.3.1.1. Extra field
+
+ If the FLG.FEXTRA bit is set, an "extra field" is present in
+ the header, with total length XLEN bytes. It consists of a
+ series of subfields, each of the form:
+
+ +---+---+---+---+==================================+
+ |SI1|SI2| LEN |... LEN bytes of subfield data ...|
+ +---+---+---+---+==================================+
+
+ SI1 and SI2 provide a subfield ID, typically two ASCII letters
+ with some mnemonic value. Jean-Loup Gailly
+ <gzip@prep.ai.mit.edu> is maintaining a registry of subfield
+ IDs; please send him any subfield ID you wish to use. Subfield
+ IDs with SI2 = 0 are reserved for future use. The following
+ IDs are currently defined:
+
+
+
+Deutsch Informational [Page 8]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ SI1 SI2 Data
+ ---------- ---------- ----
+ 0x41 ('A') 0x70 ('P') Apollo file type information
+
+ LEN gives the length of the subfield data, excluding the 4
+ initial bytes.
+
+ 2.3.1.2. Compliance
+
+ A compliant compressor must produce files with correct ID1,
+ ID2, CM, CRC32, and ISIZE, but may set all the other fields in
+ the fixed-length part of the header to default values (255 for
+ OS, 0 for all others). The compressor must set all reserved
+ bits to zero.
+
+ A compliant decompressor must check ID1, ID2, and CM, and
+ provide an error indication if any of these have incorrect
+ values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
+ at least so it can skip over the optional fields if they are
+ present. It need not examine any other part of the header or
+ trailer; in particular, a decompressor may ignore FTEXT and OS
+ and always produce binary output, and still be compliant. A
+ compliant decompressor must give an error indication if any
+ reserved bit is non-zero, since such a bit could indicate the
+ presence of a new field that would cause subsequent data to be
+ interpreted incorrectly.
+
+3. References
+
+ [1] "Information Processing - 8-bit single-byte coded graphic
+ character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
+ The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
+ ASCII. Files defining this character set are available as
+ iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
+
+ [2] ISO 3309
+
+ [3] ITU-T recommendation V.42
+
+ [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+ available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+ [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
+ ftp://prep.ai.mit.edu/pub/gnu/
+
+ [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
+ Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
+
+
+
+
+Deutsch Informational [Page 9]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
+ pp.118-133.
+
+ [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
+ describing the CRC concept.
+
+4. Security Considerations
+
+ Any data compression method involves the reduction of redundancy in
+ the data. Consequently, any corruption of the data is likely to have
+ severe effects and be difficult to correct. Uncompressed text, on
+ the other hand, will probably still be readable despite the presence
+ of some corrupted bytes.
+
+ It is recommended that systems using this data format provide some
+ means of validating the integrity of the compressed data, such as by
+ setting and checking the CRC-32 check value.
+
+5. Acknowledgements
+
+ Trademarks cited in this document are the property of their
+ respective owners.
+
+ Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
+ the related software described in this specification. Glenn
+ Randers-Pehrson converted this document to RFC and HTML format.
+
+6. Author's Address
+
+ L. Peter Deutsch
+ Aladdin Enterprises
+ 203 Santa Margarita Ave.
+ Menlo Park, CA 94025
+
+ Phone: (415) 322-0103 (AM only)
+ FAX: (415) 322-1734
+ EMail: <ghost@aladdin.com>
+
+ Questions about the technical content of this specification can be
+ sent by email to:
+
+ Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+ Mark Adler <madler@alumni.caltech.edu>
+
+ Editorial comments on this specification can be sent by email to:
+
+ L. Peter Deutsch <ghost@aladdin.com> and
+ Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+Deutsch Informational [Page 10]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+7. Appendix: Jean-Loup Gailly's gzip utility
+
+ The most widely used implementation of gzip compression, and the
+ original documentation on which this specification is based, were
+ created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>. Since this
+ implementation is a de facto standard, we mention some more of its
+ features here. Again, the material in this section is not part of
+ the specification per se, and implementations need not follow it to
+ be compliant.
+
+ When compressing or decompressing a file, gzip preserves the
+ protection, ownership, and modification time attributes on the local
+ file system, since there is no provision for representing protection
+ attributes in the gzip file format itself. Since the file format
+ includes a modification time, the gzip decompressor provides a
+ command line switch that assigns the modification time from the file,
+ rather than the local modification time of the compressed input, to
+ the decompressed output.
+
+8. Appendix: Sample CRC Code
+
+ The following sample code represents a practical implementation of
+ the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
+ for a formal specification.)
+
+ The sample code is in the ANSI C programming language. Non C users
+ may find it easier to read with these hints:
+
+ & Bitwise AND operator.
+ ^ Bitwise exclusive-OR operator.
+ >> Bitwise right shift operator. When applied to an
+ unsigned quantity, as here, right shift inserts zero
+ bit(s) at the left.
+ ! Logical NOT operator.
+ ++ "n++" increments the variable n.
+ 0xNNN 0x introduces a hexadecimal (base 16) constant.
+ Suffix L indicates a long value (at least 32 bits).
+
+ /* Table of CRCs of all 8-bit messages. */
+ unsigned long crc_table[256];
+
+ /* Flag: has the table been computed? Initially false. */
+ int crc_table_computed = 0;
+
+ /* Make the table for a fast CRC. */
+ void make_crc_table(void)
+ {
+ unsigned long c;
+
+
+
+Deutsch Informational [Page 11]
+
+RFC 1952 GZIP File Format Specification May 1996
+
+
+ int n, k;
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long) n;
+ for (k = 0; k < 8; k++) {
+ if (c & 1) {
+ c = 0xedb88320L ^ (c >> 1);
+ } else {
+ c = c >> 1;
+ }
+ }
+ crc_table[n] = c;
+ }
+ crc_table_computed = 1;
+ }
+
+ /*
+ Update a running crc with the bytes buf[0..len-1] and return
+ the updated crc. The crc should be initialized to zero. Pre- and
+ post-conditioning (one's complement) is performed within this
+ function so it shouldn't be done by the caller. Usage example:
+
+ unsigned long crc = 0L;
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = update_crc(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+ */
+ unsigned long update_crc(unsigned long crc,
+ unsigned char *buf, int len)
+ {
+ unsigned long c = crc ^ 0xffffffffL;
+ int n;
+
+ if (!crc_table_computed)
+ make_crc_table();
+ for (n = 0; n < len; n++) {
+ c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
+ }
+ return c ^ 0xffffffffL;
+ }
+
+ /* Return the CRC of the bytes buf[0..len-1]. */
+ unsigned long crc(unsigned char *buf, int len)
+ {
+ return update_crc(0L, buf, len);
+ }
+
+
+
+
+Deutsch Informational [Page 12]
+
diff --git a/lib/libz/doc/txtvsbin.txt b/lib/libz/doc/txtvsbin.txt
new file mode 100644
index 0000000..3d0f063
--- /dev/null
+++ b/lib/libz/doc/txtvsbin.txt
@@ -0,0 +1,107 @@
+A Fast Method for Identifying Plain Text Files
+==============================================
+
+
+Introduction
+------------
+
+Given a file coming from an unknown source, it is sometimes desirable
+to find out whether the format of that file is plain text. Although
+this may appear like a simple task, a fully accurate detection of the
+file type requires heavy-duty semantic analysis on the file contents.
+It is, however, possible to obtain satisfactory results by employing
+various heuristics.
+
+Previous versions of PKZip and other zip-compatible compression tools
+were using a crude detection scheme: if more than 80% (4/5) of the bytes
+found in a certain buffer are within the range [7..127], the file is
+labeled as plain text, otherwise it is labeled as binary. A prominent
+limitation of this scheme is the restriction to Latin-based alphabets.
+Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
+the bytes within the range [128..255], and texts using these alphabets
+are most often misidentified by this scheme; in other words, the rate
+of false negatives is sometimes too high, which means that the recall
+is low. Another weakness of this scheme is a reduced precision, due to
+the false positives that may occur when binary files containing large
+amounts of textual characters are misidentified as plain text.
+
+In this article we propose a new, simple detection scheme that features
+a much increased precision and a near-100% recall. This scheme is
+designed to work on ASCII, Unicode and other ASCII-derived alphabets,
+and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
+and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings
+(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
+
+
+The Algorithm
+-------------
+
+The algorithm works by dividing the set of bytecodes [0..255] into three
+categories:
+- The white list of textual bytecodes:
+ 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
+- The gray list of tolerated bytecodes:
+ 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
+- The black list of undesired, non-textual bytecodes:
+ 0 (NUL) to 6, 14 to 31.
+
+If a file contains at least one byte that belongs to the white list and
+no byte that belongs to the black list, then the file is categorized as
+plain text; otherwise, it is categorized as binary. (The boundary case,
+when the file is empty, automatically falls into the latter category.)
+
+
+Rationale
+---------
+
+The idea behind this algorithm relies on two observations.
+
+The first observation is that, although the full range of 7-bit codes
+[0..127] is properly specified by the ASCII standard, most control
+characters in the range [0..31] are not used in practice. The only
+widely-used, almost universally-portable control codes are 9 (TAB),
+10 (LF) and 13 (CR). There are a few more control codes that are
+recognized on a reduced range of platforms and text viewers/editors:
+7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
+codes are rarely (if ever) used alone, without being accompanied by
+some printable text. Even the newer, portable text formats such as
+XML avoid using control characters outside the list mentioned here.
+
+The second observation is that most of the binary files tend to contain
+control characters, especially 0 (NUL). Even though the older text
+detection schemes observe the presence of non-ASCII codes from the range
+[128..255], the precision rarely has to suffer if this upper range is
+labeled as textual, because the files that are genuinely binary tend to
+contain both control characters and codes from the upper range. On the
+other hand, the upper range needs to be labeled as textual, because it
+is used by virtually all ASCII extensions. In particular, this range is
+used for encoding non-Latin scripts.
+
+Since there is no counting involved, other than simply observing the
+presence or the absence of some byte values, the algorithm produces
+consistent results, regardless what alphabet encoding is being used.
+(If counting were involved, it could be possible to obtain different
+results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
+
+There is an extra category of plain text files that are "polluted" with
+one or more black-listed codes, either by mistake or by peculiar design
+considerations. In such cases, a scheme that tolerates a small fraction
+of black-listed codes would provide an increased recall (i.e. more true
+positives). This, however, incurs a reduced precision overall, since
+false positives are more likely to appear in binary files that contain
+large chunks of textual data. Furthermore, "polluted" plain text should
+be regarded as binary by general-purpose text detection schemes, because
+general-purpose text processing algorithms might not be applicable.
+Under this premise, it is safe to say that our detection method provides
+a near-100% recall.
+
+Experiments have been run on many files coming from various platforms
+and applications. We tried plain text files, system logs, source code,
+formatted office documents, compiled object code, etc. The results
+confirm the optimistic assumptions about the capabilities of this
+algorithm.
+
+
+--
+Cosmin Truta
+Last updated: 2006-May-28
diff --git a/lib/libz/example.c b/lib/libz/example.c
index 6c8a0ee..604736f 100644
--- a/lib/libz/example.c
+++ b/lib/libz/example.c
@@ -1,12 +1,12 @@
/* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2006 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
-#include <stdio.h>
#include "zlib.h"
+#include <stdio.h>
#ifdef STDC
# include <string.h>
diff --git a/lib/libz/gzclose.c b/lib/libz/gzclose.c
new file mode 100644
index 0000000..caeb99a
--- /dev/null
+++ b/lib/libz/gzclose.c
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+ That way the other gzclose functions can be used instead to avoid linking in
+ unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+ gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+ gz_statep state;
+
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+ return gzclose_r(file);
+#endif
+}
diff --git a/lib/libz/gzguts.h b/lib/libz/gzguts.h
new file mode 100644
index 0000000..0f8fb79
--- /dev/null
+++ b/lib/libz/gzguts.h
@@ -0,0 +1,132 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+# ifndef _LARGEFILE_SOURCE
+# define _LARGEFILE_SOURCE 1
+# endif
+# ifdef _FILE_OFFSET_BITS
+# undef _FILE_OFFSET_BITS
+# endif
+#endif
+
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+# include <limits.h>
+#endif
+#include <fcntl.h>
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#ifdef _MSC_VER
+# include <io.h>
+# define vsnprintf _vsnprintf
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+ extern voidp malloc OF((uInt size));
+ extern void free OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+# include <windows.h>
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+# ifdef STDC
+# include <errno.h>
+# define zstrerror() strerror(errno)
+# else
+# define zstrerror() "stdio error (consult errno)"
+# endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default i/o buffer size -- double this for output when reading */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0 /* look for a gzip header */
+#define COPY 1 /* copy input directly */
+#define GZIP 2 /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+ /* used for both reading and writing */
+ int mode; /* see gzip modes above */
+ int fd; /* file descriptor */
+ char *path; /* path or fd for error messages */
+ z_off64_t pos; /* current position in uncompressed data */
+ unsigned size; /* buffer size, zero if not allocated yet */
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */
+ unsigned char *in; /* input buffer */
+ unsigned char *out; /* output buffer (double-sized when reading) */
+ unsigned char *next; /* next output data to deliver or write */
+ /* just for reading */
+ unsigned have; /* amount of output data unused at next */
+ int eof; /* true if end of input file reached */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ z_off64_t raw; /* where the raw data started, for seeking */
+ int how; /* 0: get header, 1: copy, 2: decompress */
+ int direct; /* true if last read direct, false if gzip */
+ /* just for writing */
+ int level; /* compression level */
+ int strategy; /* compression strategy */
+ /* seek request */
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */
+ int seek; /* true if seek request pending */
+ /* error information */
+ int err; /* error code */
+ char *msg; /* error message */
+ /* zlib inflate or deflate stream */
+ z_stream strm; /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+ value -- needed when comparing unsigned to z_off64_t, which is signed
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/lib/libz/gzio.c b/lib/libz/gzio.c
deleted file mode 100644
index 0aa03e9..0000000
--- a/lib/libz/gzio.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-#ifdef NO_DEFLATE /* for compatibility with old definition */
-# define NO_GZCOMPRESS
-#endif
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#ifdef __MVS__
-# pragma map (fdopen , "\174\174FDOPEN")
- FILE *fdopen(int, const char *);
-#endif
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- z_off_t start; /* start of compressed data in file (header skipped) */
- z_off_t in; /* bytes into deflate or inflate */
- z_off_t out; /* bytes out of deflate or inflate */
- int back; /* one character push-back */
- int last; /* true if push-back is last character */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->in = 0;
- s->out = 0;
- s->back = EOF;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else if (*p == 'R') {
- strategy = Z_RLE;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->start = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * start anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->start = ftell(s->file) - s->stream.avail_in;
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[46]; /* allow for up to 128-bit integers */
-
- if (fd < 0) return (gzFile)Z_NULL;
- snprintf(name, sizeof(name), "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Assure two bytes in the buffer so we can peek ahead -- handle case
- where first byte of header is at the end of the buffer after the last
- gzip segment */
- len = s->stream.avail_in;
- if (len < 2) {
- if (len) s->inbuf[0] = s->stream.next_in[0];
- errno = 0;
- len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
- if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
- s->stream.avail_in += len;
- s->stream.next_in = s->inbuf;
- if (s->stream.avail_in < 2) {
- s->transparent = s->stream.avail_in;
- return;
- }
- }
-
- /* Peek ahead to check the gzip magic header */
- if (s->stream.next_in[0] != gz_magic[0] ||
- s->stream.next_in[1] != gz_magic[1]) {
- s->transparent = 1;
- return;
- }
- s->stream.avail_in -= 2;
- s->stream.next_in += 2;
-
- /* Check the rest of the gzip header */
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- if (s->stream.avail_out && s->back != EOF) {
- *next_out++ = s->back;
- s->stream.next_out++;
- s->stream.avail_out--;
- s->back = EOF;
- s->out++;
- start++;
- if (s->last) {
- s->z_err = Z_STREAM_END;
- return 1;
- }
- }
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -=
- (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
- }
- len -= s->stream.avail_out;
- s->in += len;
- s->out += len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may be
- * different from s->out in case of concatenated .gz files.
- * Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- inflateReset(&(s->stream));
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- if (len == s->stream.avail_out &&
- (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
- return -1;
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Push one byte back onto the stream.
-*/
-int ZEXPORT gzungetc(c, file)
- int c;
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
- s->back = c;
- s->out--;
- s->last = (s->z_err == Z_STREAM_END);
- if (s->last) s->z_err = Z_OK;
- s->z_eof = 0;
- return c;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_GZCOMPRESS
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- voidpc buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- buf[sizeof(buf) - 1] = 0;
- va_start(va, format);
-#ifdef NO_vsnprintf
-# ifdef HAS_vsprintf_void
- (void)vsprintf(buf, format, va);
- va_end(va);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = vsprintf(buf, format, va);
- va_end(va);
-# endif
-#else
-# ifdef HAS_vsnprintf_void
- (void)vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
- len = strlen(buf);
-# else
- len = vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-# endif
-#endif
- if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
- buf[sizeof(buf) - 1] = 0;
-#ifdef NO_snprintf
-# ifdef HAS_sprintf_void
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#else
-# ifdef HAS_snprintf_void
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(buf);
-# else
- len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#endif
- if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), flush);
- s->out -= s->stream.avail_out;
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_GZCOMPRESS */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- if (s->inbuf == Z_NULL) return -1L;
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return s->in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->in = s->out = offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if (offset >= s->out) {
- offset -= s->out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- if (s->outbuf == Z_NULL) return -1L;
- }
- if (offset && s->back != EOF) {
- s->back = EOF;
- s->out++;
- offset--;
- if (s->last) s->z_err = Z_STREAM_END;
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return s->out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
- if (!s->transparent) (void)inflateReset(&s->stream);
- s->in = 0;
- s->out = 0;
- return fseek(s->file, s->start, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- /* With concatenated compressed files that can have embedded
- * crc trailers, z_eof is no longer the only/best indicator of EOF
- * on a gz_stream. Handle end-of-stream error explicitly here.
- */
- if (s == NULL || s->mode != 'r') return 0;
- if (s->z_eof) return 1;
- return s->z_err == Z_STREAM_END;
-}
-
-/* ===========================================================================
- Returns 1 if reading and doing so transparently, otherwise zero.
-*/
-int ZEXPORT gzdirect (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return 0;
- return s->transparent;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return Z_STREAM_ERROR;
-#else
- if (do_flush (file, Z_FINISH) != Z_OK)
- return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, (uLong)(s->in & 0xffffffff));
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-#ifdef STDC
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-/* ===========================================================================
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char * ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
-
-/* ===========================================================================
- Clear the error and end-of-file flags, and do the same for the real file.
-*/
-void ZEXPORT gzclearerr (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return;
- if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
- s->z_eof = 0;
- clearerr(s->file);
-}
diff --git a/lib/libz/gzlib.c b/lib/libz/gzlib.c
new file mode 100644
index 0000000..999455d
--- /dev/null
+++ b/lib/libz/gzlib.c
@@ -0,0 +1,540 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $FreeBSD$ */
+
+#include "gzguts.h"
+#include "zutil.h"
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define LSEEK lseek64
+#else
+# define LSEEK lseek
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const char *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+ string and return a pointer to it. Typically, the values for ERROR come
+ from GetLastError.
+
+ The string pointed to shall not be modified by the application, but may be
+ overwritten by a subsequent call to gz_strwinerror
+
+ The gz_strwinerror function does not change the current setting of
+ GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+ gz_statep state;
+{
+ if (state->mode == GZ_READ) { /* for reading ... */
+ state->have = 0; /* no output data available */
+ state->eof = 0; /* not at end of file */
+ state->how = LOOK; /* look for gzip header */
+ state->direct = 1; /* default for empty file */
+ }
+ state->seek = 0; /* no seek request pending */
+ gz_error(state, Z_OK, NULL); /* clear error */
+ state->pos = 0; /* no uncompressed data yet */
+ state->strm.avail_in = 0; /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+ const char *path;
+ int fd;
+ const char *mode;
+{
+ gz_statep state;
+
+ /* allocate gzFile structure to return */
+ state = malloc(sizeof(gz_state));
+ if (state == NULL)
+ return NULL;
+ state->size = 0; /* no buffers allocated yet */
+ state->want = GZBUFSIZE; /* requested buffer size */
+ state->msg = NULL; /* no error message yet */
+
+ /* interpret mode */
+ state->mode = GZ_NONE;
+ state->level = Z_DEFAULT_COMPRESSION;
+ state->strategy = Z_DEFAULT_STRATEGY;
+ while (*mode) {
+ if (*mode >= '0' && *mode <= '9')
+ state->level = *mode - '0';
+ else
+ switch (*mode) {
+ case 'r':
+ state->mode = GZ_READ;
+ break;
+#ifndef NO_GZCOMPRESS
+ case 'w':
+ state->mode = GZ_WRITE;
+ break;
+ case 'a':
+ state->mode = GZ_APPEND;
+ break;
+#endif
+ case '+': /* can't read and write at the same time */
+ free(state);
+ return NULL;
+ case 'b': /* ignore -- will request binary anyway */
+ break;
+ case 'f':
+ state->strategy = Z_FILTERED;
+ break;
+ case 'h':
+ state->strategy = Z_HUFFMAN_ONLY;
+ break;
+ case 'R':
+ state->strategy = Z_RLE;
+ break;
+ case 'F':
+ state->strategy = Z_FIXED;
+ default: /* could consider as an error, but just ignore */
+ ;
+ }
+ mode++;
+ }
+
+ /* must provide an "r", "w", or "a" */
+ if (state->mode == GZ_NONE) {
+ free(state);
+ return NULL;
+ }
+
+ /* save the path name for error messages */
+ state->path = malloc(strlen(path) + 1);
+ if (state->path == NULL) {
+ free(state);
+ return NULL;
+ }
+ strcpy(state->path, path);
+
+ /* open the file with the appropriate mode (or just use fd) */
+ state->fd = fd != -1 ? fd :
+ open(path,
+#ifdef O_LARGEFILE
+ O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+ O_BINARY |
+#endif
+ (state->mode == GZ_READ ?
+ O_RDONLY :
+ (O_WRONLY | O_CREAT | (
+ state->mode == GZ_WRITE ?
+ O_TRUNC :
+ O_APPEND))),
+ 0666);
+ if (state->fd == -1) {
+ free(state->path);
+ free(state);
+ return NULL;
+ }
+ if (state->mode == GZ_APPEND)
+ state->mode = GZ_WRITE; /* simplify later checks */
+
+ /* save the current position for rewinding (only if reading) */
+ if (state->mode == GZ_READ) {
+ state->start = LSEEK(state->fd, 0, SEEK_CUR);
+ if (state->start == -1) state->start = 0;
+ }
+
+ /* initialize stream */
+ gz_reset(state);
+
+ /* return stream */
+ return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+ int fd;
+ const char *mode;
+{
+ char *path; /* identifier for error messages */
+ gzFile gz;
+
+ if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
+ return NULL;
+ sprintf(path, "<fd:%d>", fd); /* for debugging */
+ gz = gz_open(path, fd, mode);
+ free(path);
+ return gz;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+ gzFile file;
+ unsigned size;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* make sure we haven't already allocated memory */
+ if (state->size != 0)
+ return -1;
+
+ /* check and set requested size */
+ if (size == 0)
+ return -1;
+ state->want = size;
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ || state->err != Z_OK)
+ return -1;
+
+ /* back up and start over */
+ if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+ return -1;
+ gz_reset(state);
+ return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+ gzFile file;
+ z_off64_t offset;
+ int whence;
+{
+ unsigned n;
+ z_off64_t ret;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* check that there's no error */
+ if (state->err != Z_OK)
+ return -1;
+
+ /* can only seek from start or relative to current position */
+ if (whence != SEEK_SET && whence != SEEK_CUR)
+ return -1;
+
+ /* normalize offset to a SEEK_CUR specification */
+ if (whence == SEEK_SET)
+ offset -= state->pos;
+ else if (state->seek)
+ offset += state->skip;
+ state->seek = 0;
+
+ /* if within raw area while reading, just go there */
+ if (state->mode == GZ_READ && state->how == COPY &&
+ state->pos + offset >= state->raw) {
+ ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
+ if (ret == -1)
+ return -1;
+ state->have = 0;
+ state->eof = 0;
+ state->seek = 0;
+ gz_error(state, Z_OK, NULL);
+ state->strm.avail_in = 0;
+ state->pos += offset;
+ return state->pos;
+ }
+
+ /* calculate skip amount, rewinding if needed for back seek when reading */
+ if (offset < 0) {
+ if (state->mode != GZ_READ) /* writing -- can't go backwards */
+ return -1;
+ offset += state->pos;
+ if (offset < 0) /* before start of file! */
+ return -1;
+ if (gzrewind(file) == -1) /* rewind, then skip to offset */
+ return -1;
+ }
+
+ /* if reading, skip what's in output buffer (one less gzgetc() check) */
+ if (state->mode == GZ_READ) {
+ n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
+ (unsigned)offset : state->have;
+ state->have -= n;
+ state->next += n;
+ state->pos += n;
+ offset -= n;
+ }
+
+ /* request skip (if not zero) */
+ if (offset) {
+ state->seek = 1;
+ state->skip = offset;
+ }
+ return state->pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ z_off64_t ret;
+
+ ret = gzseek64(file, (z_off64_t)offset, whence);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* return position */
+ return state->pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gztell64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+ gzFile file;
+{
+ z_off64_t offset;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* compute and return effective offset in file */
+ offset = LSEEK(state->fd, 0, SEEK_CUR);
+ if (offset == -1)
+ return -1;
+ if (state->mode == GZ_READ) /* reading */
+ offset -= state->strm.avail_in; /* don't count buffered input */
+ return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gzoffset64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return 0;
+
+ /* return end-of-file state */
+ return state->mode == GZ_READ ?
+ (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return NULL;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return NULL;
+
+ /* return error information */
+ if (errnum != NULL)
+ *errnum = state->err;
+ return state->msg == NULL ? "" : state->msg;
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return;
+
+ /* clear error and end-of-file */
+ if (state->mode == GZ_READ)
+ state->eof = 0;
+ gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+ state->msg accordingly. Free any previous error message already there. Do
+ not try to free or allocate space if the error is Z_MEM_ERROR (out of
+ memory). Simply save the error message as a static string. If there is an
+ allocation failure constructing the error message, then convert the error to
+ out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+ gz_statep state;
+ int err;
+ const char *msg;
+{
+ /* free previously allocated message and clear */
+ if (state->msg != NULL) {
+ if (state->err != Z_MEM_ERROR)
+ free(state->msg);
+ state->msg = NULL;
+ }
+
+ /* set error code, and if no message, then done */
+ state->err = err;
+ if (msg == NULL)
+ return;
+
+ /* for an out of memory error, save as static string */
+ if (err == Z_MEM_ERROR) {
+ state->msg = (char *)msg;
+ return;
+ }
+
+ /* construct error message with path */
+ if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
+ state->err = Z_MEM_ERROR;
+ state->msg = (char *)"out of memory";
+ return;
+ }
+ strcpy(state->msg, state->path);
+ strcat(state->msg, ": ");
+ strcat(state->msg, msg);
+ return;
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+ available) -- we need to do this to cover cases where 2's complement not
+ used, since C standard permits 1's complement and sign-bit representations,
+ otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+ unsigned p, q;
+
+ p = 1;
+ do {
+ q = p;
+ p <<= 1;
+ p++;
+ } while (p > q);
+ return q >> 1;
+}
+#endif
diff --git a/lib/libz/gzread.c b/lib/libz/gzread.c
new file mode 100644
index 0000000..5c37bab
--- /dev/null
+++ b/lib/libz/gzread.c
@@ -0,0 +1,656 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $FreeBSD$ */
+
+#include "gzguts.h"
+#include <unistd.h>
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_next4 OF((gz_statep, unsigned long *));
+local int gz_head OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_make OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
+ state->fd, and update state->eof, state->err, and state->msg as appropriate.
+ This function needs to loop on read(), since read() is not guaranteed to
+ read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+ gz_statep state;
+ unsigned char *buf;
+ unsigned len;
+ unsigned *have;
+{
+ int ret;
+
+ *have = 0;
+ do {
+ ret = read(state->fd, buf + *have, len - *have);
+ if (ret <= 0)
+ break;
+ *have += ret;
+ } while (*have < len);
+ if (ret < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (ret == 0)
+ state->eof = 1;
+ return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+ error, 0 otherwise. Note that the eof flag is set when the end of the input
+ file is reached, even though there may be unused data in the buffer. Once
+ that data has been used, no more attempts will be made to read the file.
+ gz_avail() assumes that strm->avail_in == 0. */
+local int gz_avail(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ if (state->err != Z_OK)
+ return -1;
+ if (state->eof == 0) {
+ if (gz_load(state, state->in, state->size,
+ (unsigned *)&(strm->avail_in)) == -1)
+ return -1;
+ strm->next_in = state->in;
+ }
+ return 0;
+}
+
+/* Get next byte from input, or -1 if end or error. */
+#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
+ (strm->avail_in == 0 ? -1 : \
+ (strm->avail_in--, *(strm->next_in)++)))
+
+/* Get a four-byte little-endian integer and return 0 on success and the value
+ in *ret. Otherwise -1 is returned and *ret is not modified. */
+local int gz_next4(state, ret)
+ gz_statep state;
+ unsigned long *ret;
+{
+ int ch;
+ unsigned long val;
+ z_streamp strm = &(state->strm);
+
+ val = NEXT();
+ val += (unsigned)NEXT() << 8;
+ val += (unsigned long)NEXT() << 16;
+ ch = NEXT();
+ if (ch == -1)
+ return -1;
+ val += (unsigned long)ch << 24;
+ *ret = val;
+ return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy. state->have must be zero.
+ If this is the first time in, allocate required memory. state->how will be
+ left unchanged if there is no more input data available, will be set to COPY
+ if there is no gzip header and direct copying will be performed, or it will
+ be set to GZIP for decompression, and the gzip header will be skipped so
+ that the next available input data is the raw deflate stream. If direct
+ copying, then leftover input data from the input buffer will be copied to
+ the output buffer. In that case, all further file reads will be directly to
+ either the output buffer or a user buffer. If decompressing, the inflate
+ state and the check value will be initialized. gz_head() will return 0 on
+ success or -1 on failure. Failures may include read errors or gzip header
+ errors. */
+local int gz_head(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+ int flags;
+ unsigned len;
+
+ /* allocate read buffers and inflate memory */
+ if (state->size == 0) {
+ /* allocate buffers */
+ state->in = malloc(state->want);
+ state->out = malloc(state->want << 1);
+ if (state->in == NULL || state->out == NULL) {
+ if (state->out != NULL)
+ free(state->out);
+ if (state->in != NULL)
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ state->size = state->want;
+
+ /* allocate inflate memory */
+ state->strm.zalloc = Z_NULL;
+ state->strm.zfree = Z_NULL;
+ state->strm.opaque = Z_NULL;
+ state->strm.avail_in = 0;
+ state->strm.next_in = Z_NULL;
+ if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
+ free(state->out);
+ free(state->in);
+ state->size = 0;
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ }
+
+ /* get some data in the input buffer */
+ if (strm->avail_in == 0) {
+ if (gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0)
+ return 0;
+ }
+
+ /* look for the gzip magic header bytes 31 and 139 */
+ if (strm->next_in[0] == 31) {
+ strm->avail_in--;
+ strm->next_in++;
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in && strm->next_in[0] == 139) {
+ /* we have a gzip header, woo hoo! */
+ strm->avail_in--;
+ strm->next_in++;
+
+ /* skip rest of header */
+ if (NEXT() != 8) { /* compression method */
+ gz_error(state, Z_DATA_ERROR, "unknown compression method");
+ return -1;
+ }
+ flags = NEXT();
+ if (flags & 0xe0) { /* reserved flag bits */
+ gz_error(state, Z_DATA_ERROR, "unknown header flags set");
+ return -1;
+ }
+ NEXT(); /* modification time */
+ NEXT();
+ NEXT();
+ NEXT();
+ NEXT(); /* extra flags */
+ NEXT(); /* operating system */
+ if (flags & 4) { /* extra field */
+ len = (unsigned)NEXT();
+ len += (unsigned)NEXT() << 8;
+ while (len--)
+ if (NEXT() < 0)
+ break;
+ }
+ if (flags & 8) /* file name */
+ while (NEXT() > 0)
+ ;
+ if (flags & 16) /* comment */
+ while (NEXT() > 0)
+ ;
+ if (flags & 2) { /* header crc */
+ NEXT();
+ NEXT();
+ }
+ /* an unexpected end of file is not checked for here -- it will be
+ noticed on the first request for uncompressed data */
+
+ /* set up for decompression */
+ inflateReset(strm);
+ strm->adler = crc32(0L, Z_NULL, 0);
+ state->how = GZIP;
+ state->direct = 0;
+ return 0;
+ }
+ else {
+ /* not a gzip file -- save first byte (31) and fall to raw i/o */
+ state->out[0] = 31;
+ state->have = 1;
+ }
+ }
+
+ /* doing raw i/o, save start of raw data for seeking, copy any leftover
+ input to output -- this assumes that the output buffer is larger than
+ the input buffer, which also assures space for gzungetc() */
+ state->raw = state->pos;
+ state->next = state->out;
+ if (strm->avail_in) {
+ memcpy(state->next + state->have, strm->next_in, strm->avail_in);
+ state->have += strm->avail_in;
+ strm->avail_in = 0;
+ }
+ state->how = COPY;
+ state->direct = 1;
+ return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+ If the end of the compressed data is reached, then verify the gzip trailer
+ check value and length (modulo 2^32). state->have and state->next are set
+ to point to the just decompressed data, and the crc is updated. If the
+ trailer is verified, state->how is reset to LOOK to look for the next gzip
+ stream or raw data, once state->have is depleted. Returns 0 on success, -1
+ on failure. Failures may include invalid compressed data or a failed gzip
+ trailer verification. */
+local int gz_decomp(state)
+ gz_statep state;
+{
+ int ret;
+ unsigned had;
+ unsigned long crc, len;
+ z_streamp strm = &(state->strm);
+
+ /* fill output buffer up to end of deflate stream */
+ had = strm->avail_out;
+ do {
+ /* get more input for inflate() */
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0) {
+ gz_error(state, Z_DATA_ERROR, "unexpected end of file");
+ return -1;
+ }
+
+ /* decompress and handle errors */
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: inflate stream corrupt");
+ return -1;
+ }
+ if (ret == Z_MEM_ERROR) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
+ gz_error(state, Z_DATA_ERROR,
+ strm->msg == NULL ? "compressed data error" : strm->msg);
+ return -1;
+ }
+ } while (strm->avail_out && ret != Z_STREAM_END);
+
+ /* update available output and crc check value */
+ state->have = had - strm->avail_out;
+ state->next = strm->next_out - state->have;
+ strm->adler = crc32(strm->adler, state->next, state->have);
+
+ /* check gzip trailer if at end of deflate stream */
+ if (ret == Z_STREAM_END) {
+ if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
+ gz_error(state, Z_DATA_ERROR, "unexpected end of file");
+ return -1;
+ }
+ if (crc != strm->adler) {
+ gz_error(state, Z_DATA_ERROR, "incorrect data check");
+ return -1;
+ }
+ if (len != (strm->total_out & 0xffffffffL)) {
+ gz_error(state, Z_DATA_ERROR, "incorrect length check");
+ return -1;
+ }
+ state->how = LOOK; /* ready for next stream, once have is 0 (leave
+ state->direct unchanged to remember how) */
+ }
+
+ /* good decompression */
+ return 0;
+}
+
+/* Make data and put in the output buffer. Assumes that state->have == 0.
+ Data is either copied from the input file or decompressed from the input
+ file depending on state->how. If state->how is LOOK, then a gzip header is
+ looked for (and skipped if found) to determine wither to copy or decompress.
+ Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
+ or GZIP unless the end of the input file has been reached and all data has
+ been processed. */
+local int gz_make(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ if (state->how == LOOK) { /* look for gzip header */
+ if (gz_head(state) == -1)
+ return -1;
+ if (state->have) /* got some data from gz_head() */
+ return 0;
+ }
+ if (state->how == COPY) { /* straight copy */
+ if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
+ return -1;
+ state->next = state->out;
+ }
+ else if (state->how == GZIP) { /* decompress */
+ strm->avail_out = state->size << 1;
+ strm->next_out = state->out;
+ if (gz_decomp(state) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ unsigned n;
+
+ /* skip over len bytes or reach end-of-file, whichever comes first */
+ while (len)
+ /* skip over whatever is in output buffer */
+ if (state->have) {
+ n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
+ (unsigned)len : state->have;
+ state->have -= n;
+ state->next += n;
+ state->pos += n;
+ len -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0)
+ break;
+
+ /* need more data to skip -- load up output buffer */
+ else {
+ /* get more output, looking for header if required */
+ if (gz_make(state) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ unsigned got, n;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ || state->err != Z_OK)
+ return -1;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids the flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
+ return -1;
+ }
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* get len bytes to buf, or less than len if at the end */
+ got = 0;
+ do {
+ /* first just try copying data from the output buffer */
+ if (state->have) {
+ n = state->have > len ? len : state->have;
+ memcpy(buf, state->next, n);
+ state->next += n;
+ state->have -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && strm->avail_in == 0)
+ break;
+
+ /* need output data -- for small len or new stream load up our output
+ buffer */
+ else if (state->how == LOOK || len < (state->size << 1)) {
+ /* get more output, looking for header if required */
+ if (gz_make(state) == -1)
+ return -1;
+ continue; /* no progress yet -- go back to memcpy() above */
+ /* the copy above assures that we will leave with space in the
+ output buffer, allowing at least one gzungetc() to succeed */
+ }
+
+ /* large len -- read directly into user buffer */
+ else if (state->how == COPY) { /* read directly */
+ if (gz_load(state, buf, len, &n) == -1)
+ return -1;
+ }
+
+ /* large len -- decompress directly into user buffer */
+ else { /* state->how == GZIP */
+ strm->avail_out = len;
+ strm->next_out = buf;
+ if (gz_decomp(state) == -1)
+ return -1;
+ n = state->have;
+ state->have = 0;
+ }
+
+ /* update progress */
+ len -= n;
+ buf = (char *)buf + n;
+ got += n;
+ state->pos += n;
+ } while (len);
+
+ /* return number of bytes read into user buffer (will fit in int) */
+ return (int)got;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ int ret;
+ unsigned char buf[1];
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ || state->err != Z_OK)
+ return -1;
+
+ /* try output buffer (no need to check for skip request) */
+ if (state->have) {
+ state->have--;
+ state->pos++;
+ return *(state->next)++;
+ }
+
+ /* nothing there -- try gzread() */
+ ret = gzread(file, buf, 1);
+ return ret < 1 ? -1 : buf[0];
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ || state->err != Z_OK)
+ return -1;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* can't push EOF */
+ if (c < 0)
+ return -1;
+
+ /* if output buffer empty, put byte at end (allows more pushing) */
+ if (state->have == 0) {
+ state->have = 1;
+ state->next = state->out + (state->size << 1) - 1;
+ state->next[0] = c;
+ state->pos--;
+ return c;
+ }
+
+ /* if no room, give up (must have already done a gzungetc()) */
+ if (state->have == (state->size << 1)) {
+ gz_error(state, Z_BUF_ERROR, "out of room to push characters");
+ return -1;
+ }
+
+ /* slide output data if needed and insert byte before existing data */
+ if (state->next == state->out) {
+ unsigned char *src = state->out + state->have;
+ unsigned char *dest = state->out + (state->size << 1);
+ while (src > state->out)
+ *--dest = *--src;
+ state->next = dest;
+ }
+ state->have++;
+ state->next--;
+ state->next[0] = c;
+ state->pos--;
+ return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ unsigned left, n;
+ char *str;
+ unsigned char *eol;
+ gz_statep state;
+
+ /* check parameters and get internal structure */
+ if (file == NULL || buf == NULL || len < 1)
+ return NULL;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ || state->err != Z_OK)
+ return NULL;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return NULL;
+ }
+
+ /* copy output bytes up to new line or len - 1, whichever comes first --
+ append a terminating zero to the string (we don't check for a zero in
+ the contents, let the user worry about that) */
+ str = buf;
+ left = (unsigned)len - 1;
+ if (left) do {
+ /* assure that something is in the output buffer */
+ if (state->have == 0) {
+ if (gz_make(state) == -1)
+ return NULL; /* error */
+ if (state->have == 0) { /* end of file */
+ if (buf == str) /* got bupkus */
+ return NULL;
+ break; /* got something -- return it */
+ }
+ }
+
+ /* look for end-of-line in current output buffer */
+ n = state->have > left ? left : state->have;
+ eol = memchr(state->next, '\n', n);
+ if (eol != NULL)
+ n = (unsigned)(eol - state->next) + 1;
+
+ /* copy through end-of-line, or remainder if not found */
+ memcpy(buf, state->next, n);
+ state->have -= n;
+ state->next += n;
+ state->pos += n;
+ left -= n;
+ buf += n;
+ } while (left && eol == NULL);
+
+ /* found end-of-line or out of space -- terminate string and return it */
+ buf[0] = 0;
+ return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're reading */
+ if (state->mode != GZ_READ)
+ return 0;
+
+ /* if the state is not known, but we can find out, then do so (this is
+ mainly for right after a gzopen() or gzdopen()) */
+ if (state->how == LOOK && state->have == 0)
+ (void)gz_head(state);
+
+ /* return 1 if reading direct, 0 if decompressing a gzip stream */
+ return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+ gzFile file;
+{
+ int ret;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're reading */
+ if (state->mode != GZ_READ)
+ return Z_STREAM_ERROR;
+
+ /* free memory and close file */
+ if (state->size) {
+ inflateEnd(&(state->strm));
+ free(state->out);
+ free(state->in);
+ }
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ ret = close(state->fd);
+ free(state);
+ return ret ? Z_ERRNO : Z_OK;
+}
diff --git a/lib/libz/gzwrite.c b/lib/libz/gzwrite.c
new file mode 100644
index 0000000..0f14731
--- /dev/null
+++ b/lib/libz/gzwrite.c
@@ -0,0 +1,532 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+#include <unistd.h>
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+
+/* Initialize state for writing a gzip file. Mark initialization by setting
+ state->size to non-zero. Return -1 on failure or 0 on success. */
+local int gz_init(state)
+ gz_statep state;
+{
+ int ret;
+ z_streamp strm = &(state->strm);
+
+ /* allocate input and output buffers */
+ state->in = malloc(state->want);
+ state->out = malloc(state->want);
+ if (state->in == NULL || state->out == NULL) {
+ if (state->out != NULL)
+ free(state->out);
+ if (state->in != NULL)
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* allocate deflate memory, set up for gzip compression */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+ ret = deflateInit2(strm, state->level, Z_DEFLATED,
+ 15 + 16, 8, state->strategy);
+ if (ret != Z_OK) {
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* mark state as initialized */
+ state->size = state->want;
+
+ /* initialize write buffer */
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->next = strm->next_out;
+ return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+ Return -1 if there is an error writing to the output file, otherwise 0.
+ flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
+ then the deflate() state is reset to start a new gzip stream. */
+local int gz_comp(state, flush)
+ gz_statep state;
+ int flush;
+{
+ int ret, got;
+ unsigned have;
+ z_streamp strm = &(state->strm);
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return -1;
+
+ /* run deflate() on provided input until it produces no more output */
+ ret = Z_OK;
+ do {
+ /* write out current buffer contents if full, or if flushing, but if
+ doing Z_FINISH then don't write until we get to Z_STREAM_END */
+ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+ (flush != Z_FINISH || ret == Z_STREAM_END))) {
+ have = (unsigned)(strm->next_out - state->next);
+ if (have && ((got = write(state->fd, state->next, have)) < 0 ||
+ (unsigned)got != have)) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (strm->avail_out == 0) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ }
+ state->next = strm->next_out;
+ }
+
+ /* compress */
+ have = strm->avail_out;
+ ret = deflate(strm, flush);
+ if (ret == Z_STREAM_ERROR) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: deflate stream corrupt");
+ return -1;
+ }
+ have -= strm->avail_out;
+ } while (have);
+
+ /* if that completed a deflate stream, allow another to start */
+ if (flush == Z_FINISH)
+ deflateReset(strm);
+
+ /* all done, no errors */
+ return 0;
+}
+
+/* Compress len zeros to output. Return -1 on error, 0 on success. */
+local int gz_zero(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ int first;
+ unsigned n;
+ z_streamp strm = &(state->strm);
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+
+ /* compress len zeros (len guaranteed > 0) */
+ first = 1;
+ while (len) {
+ n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+ (unsigned)len : state->size;
+ if (first) {
+ memset(state->in, 0, n);
+ first = 0;
+ }
+ strm->avail_in = n;
+ strm->next_in = state->in;
+ state->pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+ len -= n;
+ }
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ unsigned put = len;
+ unsigned n;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids the flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
+ return 0;
+ }
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* for small len, copy to input buffer, otherwise compress directly */
+ if (len < state->size) {
+ /* copy to input buffer, compress when full */
+ do {
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ n = state->size - strm->avail_in;
+ if (n > len)
+ n = len;
+ memcpy(strm->next_in + strm->avail_in, buf, n);
+ strm->avail_in += n;
+ state->pos += n;
+ buf = (char *)buf + n;
+ len -= n;
+ if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ } while (len);
+ }
+ else {
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* directly compress user buffer to file */
+ strm->avail_in = len;
+ strm->next_in = (voidp)buf;
+ state->pos += len;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ }
+
+ /* input was all buffered or compressed (put will fit in int) */
+ return (int)put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned char buf[1];
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* try writing to input buffer for speed (state->size == 0 if buffer not
+ initialized) */
+ if (strm->avail_in < state->size) {
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ strm->next_in[strm->avail_in++] = c;
+ state->pos++;
+ return c;
+ }
+
+ /* no room in buffer or not initialized, use gz_write() */
+ buf[0] = c;
+ if (gzwrite(file, buf, 1) != 1)
+ return -1;
+ return c;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+ gzFile file;
+ const char *str;
+{
+ int ret;
+ unsigned len;
+
+ /* write string */
+ len = (unsigned)strlen(str);
+ ret = gzwrite(file, str, len);
+ return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#ifdef STDC
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
+{
+ int size, len;
+ gz_statep state;
+ z_streamp strm;
+ va_list va;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* do the printf() into the input buffer, put length in len */
+ size = (int)(state->size);
+ state->in[size - 1] = 0;
+ va_start(va, format);
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(state->in, format, va);
+ va_end(va);
+ for (len = 0; len < size; len++)
+ if (state->in[len] == 0) break;
+# else
+ len = vsprintf(state->in, format, va);
+ va_end(va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(state->in, size, format, va);
+ va_end(va);
+ len = strlen(state->in);
+# else
+ len = vsnprintf((char *)(state->in), size, format, va);
+ va_end(va);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, defer compression until needed */
+ strm->avail_in = (unsigned)len;
+ strm->next_in = state->in;
+ state->pos += len;
+ return len;
+}
+
+#else /* !STDC */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ int size, len;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* do the printf() into the input buffer, put length in len */
+ size = (int)(state->size);
+ state->in[size - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < size; len++)
+ if (state->in[len] == 0) break;
+# else
+ len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(state->in);
+# else
+ len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, defer compression until needed */
+ strm->avail_in = (unsigned)len;
+ strm->next_in = state->in;
+ state->pos += len;
+ return len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* check flush parameter */
+ if (flush < 0 || flush > Z_FINISH)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* compress remaining data with requested flush */
+ gz_comp(state, flush);
+ return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* if no change is requested, then do nothing */
+ if (level == state->level && strategy == state->strategy)
+ return Z_OK;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* change compression parameters for subsequent input */
+ if (state->size) {
+ /* flush previous input with previous parameters before changing */
+ if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
+ return state->err;
+ deflateParams(strm, level, strategy);
+ }
+ state->level = level;
+ state->strategy = strategy;
+ return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+ gzFile file;
+{
+ int ret = 0;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing */
+ if (state->mode != GZ_WRITE)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ ret += gz_zero(state, state->skip);
+ }
+
+ /* flush, free memory, and close file */
+ ret += gz_comp(state, Z_FINISH);
+ (void)deflateEnd(&(state->strm));
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ ret += close(state->fd);
+ free(state);
+ return ret ? Z_ERRNO : Z_OK;
+}
diff --git a/lib/libz/infback.c b/lib/libz/infback.c
index 455dbc9..af3a8c9 100644
--- a/lib/libz/infback.c
+++ b/lib/libz/infback.c
@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2009 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -55,7 +55,7 @@ int stream_size;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
- state->write = 0;
+ state->wnext = 0;
state->whave = 0;
return Z_OK;
}
@@ -253,7 +253,7 @@ void FAR *out_desc;
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
+ code here; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
@@ -389,19 +389,19 @@ void FAR *out_desc;
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
+ if (here.val < 16) {
+ NEEDBITS(here.bits);
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
}
else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
@@ -411,16 +411,16 @@ void FAR *out_desc;
copy = 3 + BITS(2);
DROPBITS(2);
}
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
@@ -438,7 +438,16 @@ void FAR *out_desc;
/* handle error breaks in while */
if (state->mode == BAD) break;
- /* build code tables */
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
@@ -474,28 +483,28 @@ void FAR *out_desc;
/* get a literal, length, or end-of-block code */
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->lencode[last.val +
+ here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
+ DROPBITS(here.bits);
+ state->length = (unsigned)here.val;
/* process literal */
- if (this.op == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
+ "inflate: literal 0x%02x\n", here.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
@@ -504,21 +513,21 @@ void FAR *out_desc;
}
/* process end of block */
- if (this.op & 32) {
+ if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
- if (this.op & 64) {
+ if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
+ state->extra = (unsigned)(here.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
@@ -528,30 +537,30 @@ void FAR *out_desc;
/* get distance code */
for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if ((this.op & 0xf0) == 0) {
- last = this;
+ if ((here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->distcode[last.val +
+ here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
- DROPBITS(this.bits);
- if (this.op & 64) {
+ DROPBITS(here.bits);
+ if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
- state->offset = (unsigned)this.val;
+ state->offset = (unsigned)here.val;
/* get distance extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
+ state->extra = (unsigned)(here.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
diff --git a/lib/libz/inffast.c b/lib/libz/inffast.c
index bbee92e..2f1d60b 100644
--- a/lib/libz/inffast.c
+++ b/lib/libz/inffast.c
@@ -1,5 +1,5 @@
/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2008, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -64,7 +64,7 @@
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
-void inflate_fast(strm, start)
+void ZLIB_INTERNAL inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
@@ -79,7 +79,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
+ unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
@@ -87,7 +87,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
+ code here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
@@ -106,7 +106,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
#endif
wsize = state->wsize;
whave = state->whave;
- write = state->write;
+ wnext = state->wnext;
window = state->window;
hold = state->hold;
bits = state->bits;
@@ -124,20 +124,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
- this = lcode[hold & lmask];
+ here = lcode[hold & lmask];
dolen:
- op = (unsigned)(this.bits);
+ op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
- op = (unsigned)(this.op);
+ op = (unsigned)(here.op);
if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
+ "inflate: literal 0x%02x\n", here.val));
+ PUP(out) = (unsigned char)(here.val);
}
else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
+ len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
@@ -155,14 +155,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
- this = dcode[hold & dmask];
+ here = dcode[hold & dmask];
dodist:
- op = (unsigned)(this.bits);
+ op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
- op = (unsigned)(this.op);
+ op = (unsigned)(here.op);
if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
+ dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
@@ -187,12 +187,34 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
+ if (state->sane) {
+ strm->msg =
+ (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (len <= op - whave) {
+ do {
+ PUP(out) = 0;
+ } while (--len);
+ continue;
+ }
+ len -= op - whave;
+ do {
+ PUP(out) = 0;
+ } while (--op > whave);
+ if (op == 0) {
+ from = out - dist;
+ do {
+ PUP(out) = PUP(from);
+ } while (--len);
+ continue;
+ }
+#endif
}
from = window - OFF;
- if (write == 0) { /* very common case */
+ if (wnext == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
@@ -202,17 +224,17 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
from = out - dist; /* rest from output */
}
}
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
len -= op;
do {
PUP(out) = PUP(from);
@@ -222,7 +244,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
else { /* contiguous in window */
- from += write - op;
+ from += wnext - op;
if (op < len) { /* some from window */
len -= op;
do {
@@ -259,7 +281,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
@@ -269,7 +291,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
@@ -305,7 +327,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
+ - Three separate decoding do-loops for direct, window, and wnext == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
diff --git a/lib/libz/inffast.h b/lib/libz/inffast.h
index 1e88d2d..e5c1aa4 100644
--- a/lib/libz/inffast.h
+++ b/lib/libz/inffast.h
@@ -1,5 +1,5 @@
/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2003, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,4 +8,4 @@
subject to change. Applications should only use zlib.h.
*/
-void inflate_fast OF((z_streamp strm, unsigned start));
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/lib/libz/inflate.c b/lib/libz/inflate.c
index 792fdee..a8431ab 100644
--- a/lib/libz/inflate.c
+++ b/lib/libz/inflate.c
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -45,7 +45,7 @@
* - Rearrange window copies in inflate_fast() for speed and simplification
* - Unroll last copy for window match in inflate_fast()
* - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
* - Make op and len in inflate_fast() unsigned for consistency
* - Add FAR to lcode and dcode declarations in inflate_fast()
* - Simplified bad distance check in inflate_fast()
@@ -117,28 +117,52 @@ z_streamp strm;
state->head = Z_NULL;
state->wsize = 0;
state->whave = 0;
- state->write = 0;
+ state->wnext = 0;
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
+ state->sane = 1;
+ state->back = -1;
Tracev((stderr, "inflate: reset\n"));
return Z_OK;
}
-int ZEXPORT inflatePrime(strm, bits, value)
+int ZEXPORT inflateReset2(strm, windowBits)
z_streamp strm;
-int bits;
-int value;
+int windowBits;
{
+ int wrap;
struct inflate_state FAR *state;
+ /* get the state */
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48)
+ windowBits &= 15;
+#endif
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return Z_STREAM_ERROR;
+ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+ ZFREE(strm, state->window);
+ state->window = Z_NULL;
+ }
+
+ /* update state and reset the rest of it */
+ state->wrap = wrap;
+ state->wbits = (unsigned)windowBits;
+ return inflateReset(strm);
}
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
@@ -147,6 +171,7 @@ int windowBits;
const char *version;
int stream_size;
{
+ int ret;
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
@@ -164,24 +189,13 @@ int stream_size;
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
-#endif
- }
- if (windowBits < 8 || windowBits > 15) {
+ state->window = Z_NULL;
+ ret = inflateReset2(strm, windowBits);
+ if (ret != Z_OK) {
ZFREE(strm, state);
strm->state = Z_NULL;
- return Z_STREAM_ERROR;
}
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
+ return ret;
}
int ZEXPORT inflateInit_(strm, version, stream_size)
@@ -192,6 +206,27 @@ int stream_size;
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
}
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits < 0) {
+ state->hold = 0;
+ state->bits = 0;
+ return Z_OK;
+ }
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
@@ -340,7 +375,7 @@ unsigned out;
/* if window not in use yet, initialize */
if (state->wsize == 0) {
state->wsize = 1U << state->wbits;
- state->write = 0;
+ state->wnext = 0;
state->whave = 0;
}
@@ -348,22 +383,22 @@ unsigned out;
copy = out - strm->avail_out;
if (copy >= state->wsize) {
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
+ state->wnext = 0;
state->whave = state->wsize;
}
else {
- dist = state->wsize - state->write;
+ dist = state->wsize - state->wnext;
if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
copy -= dist;
if (copy) {
zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
+ state->wnext = copy;
state->whave = state->wsize;
}
else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
if (state->whave < state->wsize) state->whave += dist;
}
}
@@ -564,7 +599,7 @@ int flush;
unsigned in, out; /* save starting available input and output */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
+ code here; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
@@ -619,7 +654,9 @@ int flush;
}
DROPBITS(4);
len = BITS(4) + 8;
- if (len > state->wbits) {
+ if (state->wbits == 0)
+ state->wbits = len;
+ else if (len > state->wbits) {
strm->msg = (char *)"invalid window size";
state->mode = BAD;
break;
@@ -771,7 +808,7 @@ int flush;
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = TYPE;
case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
+ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
case TYPEDO:
if (state->last) {
BYTEBITS();
@@ -791,7 +828,11 @@ int flush;
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
+ state->mode = LEN_; /* decode codes */
+ if (flush == Z_TREES) {
+ DROPBITS(2);
+ goto inf_leave;
+ }
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
@@ -816,6 +857,9 @@ int flush;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
+ state->mode = COPY_;
+ if (flush == Z_TREES) goto inf_leave;
+ case COPY_:
state->mode = COPY;
case COPY:
copy = state->length;
@@ -876,19 +920,19 @@ int flush;
case CODELENS:
while (state->have < state->nlen + state->ndist) {
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
+ if (here.val < 16) {
+ NEEDBITS(here.bits);
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
}
else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
@@ -898,16 +942,16 @@ int flush;
copy = 3 + BITS(2);
DROPBITS(2);
}
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
@@ -925,7 +969,16 @@ int flush;
/* handle error breaks in while */
if (state->mode == BAD) break;
- /* build code tables */
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
@@ -946,88 +999,102 @@ int flush;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN_;
+ if (flush == Z_TREES) goto inf_leave;
+ case LEN_:
state->mode = LEN;
case LEN:
if (have >= 6 && left >= 258) {
RESTORE();
inflate_fast(strm, out);
LOAD();
+ if (state->mode == TYPE)
+ state->back = -1;
break;
}
+ state->back = 0;
for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->lencode[last.val +
+ here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
+ state->back += last.bits;
}
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
- if ((int)(this.op) == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ state->length = (unsigned)here.val;
+ if ((int)(here.op) == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
+ "inflate: literal 0x%02x\n", here.val));
state->mode = LIT;
break;
}
- if (this.op & 32) {
+ if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
+ state->back = -1;
state->mode = TYPE;
break;
}
- if (this.op & 64) {
+ if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
- state->extra = (unsigned)(this.op) & 15;
+ state->extra = (unsigned)(here.op) & 15;
state->mode = LENEXT;
case LENEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
+ state->back += state->extra;
}
Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->was = state->length;
state->mode = DIST;
case DIST:
for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
- if ((this.op & 0xf0) == 0) {
- last = this;
+ if ((here.op & 0xf0) == 0) {
+ last = here;
for (;;) {
- this = state->distcode[last.val +
+ here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
+ state->back += last.bits;
}
- DROPBITS(this.bits);
- if (this.op & 64) {
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
- state->offset = (unsigned)this.val;
- state->extra = (unsigned)(this.op) & 15;
+ state->offset = (unsigned)here.val;
+ state->extra = (unsigned)(here.op) & 15;
state->mode = DISTEXT;
case DISTEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
+ state->back += state->extra;
}
#ifdef INFLATE_STRICT
if (state->offset > state->dmax) {
@@ -1036,11 +1103,6 @@ int flush;
break;
}
#endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
Tracevv((stderr, "inflate: distance %u\n", state->offset));
state->mode = MATCH;
case MATCH:
@@ -1048,12 +1110,32 @@ int flush;
copy = out - left;
if (state->offset > copy) { /* copy from window */
copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
+ if (copy > state->whave) {
+ if (state->sane) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ Trace((stderr, "inflate.c too far\n"));
+ copy -= state->whave;
+ if (copy > state->length) copy = state->length;
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = 0;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+#endif
+ }
+ if (copy > state->wnext) {
+ copy -= state->wnext;
from = state->window + (state->wsize - copy);
}
else
- from = state->window + (state->write - copy);
+ from = state->window + (state->wnext - copy);
if (copy > state->length) copy = state->length;
}
else { /* copy from output */
@@ -1146,7 +1228,8 @@ int flush;
strm->adler = state->check =
UPDATE(state->check, strm->next_out - out, out);
strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
+ (state->mode == TYPE ? 128 : 0) +
+ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
ret = Z_BUF_ERROR;
return ret;
@@ -1366,3 +1449,32 @@ z_streamp source;
dest->state = (struct internal_state FAR *)copy;
return Z_OK;
}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ return Z_OK;
+#else
+ state->sane = 1;
+ return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+ state = (struct inflate_state FAR *)strm->state;
+ return ((long)(state->back) << 16) +
+ (state->mode == COPY ? state->length :
+ (state->mode == MATCH ? state->was - state->length : 0));
+}
diff --git a/lib/libz/inflate.h b/lib/libz/inflate.h
index 07bd3e7..95f4986 100644
--- a/lib/libz/inflate.h
+++ b/lib/libz/inflate.h
@@ -1,5 +1,5 @@
/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2009 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -32,11 +32,13 @@ typedef enum {
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
+ COPY_, /* i/o: same as COPY below, but only first time in */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
+ LEN_, /* i: same as LEN below, but only first time in */
+ LEN, /* i: waiting for length/lit/eob code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
@@ -53,19 +55,21 @@ typedef enum {
/*
State transitions between above modes -
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
+ (most modes can go to BAD or MEM on error -- not shown for clarity)
Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
+ HEAD -> (gzip) or (zlib) or (raw)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+ HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
+ (raw) -> TYPEDO
Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
+ TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+ STORED -> COPY_ -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN_
+ LEN_ -> LEN
+ Read deflate codes in fixed or dynamic block:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
@@ -73,7 +77,7 @@ typedef enum {
CHECK -> LENGTH -> DONE
*/
-/* state maintained between inflate() calls. Approximately 7K bytes. */
+/* state maintained between inflate() calls. Approximately 10K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
@@ -88,7 +92,7 @@ struct inflate_state {
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
+ unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
@@ -112,4 +116,7 @@ struct inflate_state {
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
+ int sane; /* if false, allow invalid distance too far */
+ int back; /* bits back of last unprocessed length/lit */
+ unsigned was; /* initial length of match */
};
diff --git a/lib/libz/inftrees.c b/lib/libz/inftrees.c
index 8a9c13f..11e9c52 100644
--- a/lib/libz/inftrees.c
+++ b/lib/libz/inftrees.c
@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
+ " inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -29,7 +29,7 @@ const char inflate_copyright[] =
table index bits. It will differ if the request is greater than the
longest code or if it is less than the shortest code.
*/
-int inflate_table(type, lens, codes, table, bits, work)
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
codetype type;
unsigned short FAR *lens;
unsigned codes;
@@ -50,7 +50,7 @@ unsigned short FAR *work;
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
+ code here; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -115,15 +115,15 @@ unsigned short FAR *work;
if (count[max] != 0) break;
if (root > max) root = max;
if (max == 0) { /* no symbols to code at all */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)1;
- this.val = (unsigned short)0;
- *(*table)++ = this; /* make a table to force an error */
- *(*table)++ = this;
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)1;
+ here.val = (unsigned short)0;
+ *(*table)++ = here; /* make a table to force an error */
+ *(*table)++ = here;
*bits = 1;
return 0; /* no symbols, but wait for decoding to report error */
}
- for (min = 1; min <= MAXBITS; min++)
+ for (min = 1; min < max; min++)
if (count[min] != 0) break;
if (root < min) root = min;
@@ -166,11 +166,10 @@ unsigned short FAR *work;
entered in the tables.
used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
sym increments through all symbols, and the loop terminates when
all codes of length max, i.e. all codes, have been processed. This
@@ -209,24 +208,25 @@ unsigned short FAR *work;
mask = used - 1; /* mask for comparing low */
/* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS))
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
- this.bits = (unsigned char)(len - drop);
+ here.bits = (unsigned char)(len - drop);
if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
+ here.op = (unsigned char)0;
+ here.val = work[sym];
}
else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
+ here.op = (unsigned char)(extra[work[sym]]);
+ here.val = base[work[sym]];
}
else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
+ here.op = (unsigned char)(32 + 64); /* end of block */
+ here.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
@@ -235,7 +235,7 @@ unsigned short FAR *work;
min = fill; /* save offset to next table */
do {
fill -= incr;
- next[(huff >> drop) + fill] = this;
+ next[(huff >> drop) + fill] = here;
} while (fill != 0);
/* backwards increment the len-bit code huff */
@@ -277,7 +277,8 @@ unsigned short FAR *work;
/* check for enough space */
used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS))
return 1;
/* point entry in root table to sub-table */
@@ -295,20 +296,20 @@ unsigned short FAR *work;
through high index bits. When the current sub-table is filled, the loop
drops back to the root table to fill in any remaining entries there.
*/
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
while (huff != 0) {
/* when done with sub-table, drop back to root table */
if (drop != 0 && (huff & mask) != low) {
drop = 0;
len = root;
next = *table;
- this.bits = (unsigned char)len;
+ here.bits = (unsigned char)len;
}
/* put invalid code marker in table */
- next[huff >> drop] = this;
+ next[huff >> drop] = here;
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
diff --git a/lib/libz/inftrees.h b/lib/libz/inftrees.h
index b1104c8..baa53a0 100644
--- a/lib/libz/inftrees.h
+++ b/lib/libz/inftrees.h
@@ -1,5 +1,5 @@
/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2005, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -35,21 +35,28 @@ typedef struct {
01000000 - invalid code
*/
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
-/* Type of code to build for inftable() */
+/* Type of code to build for inflate_table() */
typedef enum {
CODES,
LENS,
DISTS
} codetype;
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));
diff --git a/lib/libz/minigzip.c b/lib/libz/minigzip.c
index b29d14a..9825ccc 100644
--- a/lib/libz/minigzip.c
+++ b/lib/libz/minigzip.c
@@ -1,5 +1,5 @@
/* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2006, 2010 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -13,11 +13,10 @@
* or in pipe mode.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+/* @(#) $Id$ */
-#include <stdio.h>
#include "zlib.h"
+#include <stdio.h>
#ifdef STDC
# include <string.h>
@@ -33,6 +32,9 @@ __FBSDID("$FreeBSD$");
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
+# ifdef UNDER_CE
+# include <stdlib.h>
+# endif
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
@@ -51,9 +53,75 @@ __FBSDID("$FreeBSD$");
# include <unix.h> /* for fileno */
#endif
+#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
extern int unlink OF((const char *));
#endif
+#endif
+
+#if defined(UNDER_CE)
+# include <windows.h>
+# define perror(s) pwinerror(s)
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+ message string and return a pointer to it. Typically, the values
+ for ERROR come from GetLastError.
+
+ The string pointed to shall not be modified by the application,
+ but may be overwritten by a subsequent call to strwinerror
+
+ The strwinerror function does not change the current setting
+ of GetLastError. */
+
+static char *strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+static void pwinerror (s)
+ const char *s;
+{
+ if (s && *s)
+ fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
+ else
+ fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
+}
+
+#endif /* UNDER_CE */
#ifndef GZ_SUFFIX
# define GZ_SUFFIX ".gz"
@@ -201,9 +269,9 @@ void file_compress(file, mode)
if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
fprintf(stderr, "%s: filename too long\n", prog);
- exit(1);
+ exit(1);
}
-
+
strcpy(outfile, file);
strcat(outfile, GZ_SUFFIX);
@@ -237,7 +305,7 @@ void file_uncompress(file)
if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
fprintf(stderr, "%s: filename too long\n", prog);
- exit(1);
+ exit(1);
}
strcpy(buf, file);
@@ -304,9 +372,9 @@ int main(argc, argv)
while (argc > 0) {
if (strcmp(*argv, "-c") == 0)
- copyout = 1;
+ copyout = 1;
else if (strcmp(*argv, "-d") == 0)
- uncompr = 1;
+ uncompr = 1;
else if (strcmp(*argv, "-f") == 0)
outmode[3] = 'f';
else if (strcmp(*argv, "-h") == 0)
@@ -335,36 +403,36 @@ int main(argc, argv)
gz_compress(stdin, file);
}
} else {
- if (copyout) {
- SET_BINARY_MODE(stdout);
- }
+ if (copyout) {
+ SET_BINARY_MODE(stdout);
+ }
do {
if (uncompr) {
- if (copyout) {
- file = gzopen(*argv, "rb");
- if (file == NULL)
- fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
- else
- gz_uncompress(file, stdout);
- } else {
- file_uncompress(*argv);
- }
+ if (copyout) {
+ file = gzopen(*argv, "rb");
+ if (file == NULL)
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
+ else
+ gz_uncompress(file, stdout);
+ } else {
+ file_uncompress(*argv);
+ }
} else {
- if (copyout) {
- FILE * in = fopen(*argv, "rb");
-
- if (in == NULL) {
- perror(*argv);
- } else {
- file = gzdopen(fileno(stdout), outmode);
- if (file == NULL) error("can't gzdopen stdout");
-
- gz_compress(in, file);
- }
-
- } else {
- file_compress(*argv, outmode);
- }
+ if (copyout) {
+ FILE * in = fopen(*argv, "rb");
+
+ if (in == NULL) {
+ perror(*argv);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+
+ gz_compress(in, file);
+ }
+
+ } else {
+ file_compress(*argv, outmode);
+ }
}
} while (argv++, --argc);
}
diff --git a/lib/libz/trees.c b/lib/libz/trees.c
index 395e4e1..56e9bb1 100644
--- a/lib/libz/trees.c
+++ b/lib/libz/trees.c
@@ -1,5 +1,6 @@
/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
+ * Copyright (C) 1995-2010 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -152,7 +153,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
int blcodes));
local void compress_block OF((deflate_state *s, ct_data *ltree,
ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
+local int detect_data_type OF((deflate_state *s));
local unsigned bi_reverse OF((unsigned value, int length));
local void bi_windup OF((deflate_state *s));
local void bi_flush OF((deflate_state *s));
@@ -203,12 +204,12 @@ local void send_bits(s, value, length)
* unused bits in value.
*/
if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
+ s->bi_buf |= (ush)value << s->bi_valid;
put_short(s, s->bi_buf);
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
s->bi_valid += length - Buf_size;
} else {
- s->bi_buf |= value << s->bi_valid;
+ s->bi_buf |= (ush)value << s->bi_valid;
s->bi_valid += length;
}
}
@@ -218,12 +219,12 @@ local void send_bits(s, value, length)
{ int len = length;\
if (s->bi_valid > (int)Buf_size - len) {\
int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
+ s->bi_buf |= (ush)val << s->bi_valid;\
put_short(s, s->bi_buf);\
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
s->bi_valid += len - Buf_size;\
} else {\
- s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_buf |= (ush)(value) << s->bi_valid;\
s->bi_valid += len;\
}\
}
@@ -250,11 +251,13 @@ local void tr_static_init()
if (static_init_done) return;
/* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
static_l_desc.static_tree = static_ltree;
static_l_desc.extra_bits = extra_lbits;
static_d_desc.static_tree = static_dtree;
static_d_desc.extra_bits = extra_dbits;
static_bl_desc.extra_bits = extra_blbits;
+#endif
/* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0;
@@ -348,13 +351,14 @@ void gen_trees_header()
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
}
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
for (i = 0; i < DIST_CODE_LEN; i++) {
fprintf(header, "%2u%s", _dist_code[i],
SEPARATOR(i, DIST_CODE_LEN-1, 20));
}
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ fprintf(header,
+ "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
fprintf(header, "%2u%s", _length_code[i],
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
@@ -379,7 +383,7 @@ void gen_trees_header()
/* ===========================================================================
* Initialize the tree data structures for a new zlib stream.
*/
-void _tr_init(s)
+void ZLIB_INTERNAL _tr_init(s)
deflate_state *s;
{
tr_static_init();
@@ -864,13 +868,13 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
/* ===========================================================================
* Send a stored block
*/
-void _tr_stored_block(s, buf, stored_len, eof)
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
deflate_state *s;
charf *buf; /* input block */
ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
+ int last; /* one if this is the last block for a file */
{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+ send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
#ifdef DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
s->compressed_len += (stored_len + 4) << 3;
@@ -889,7 +893,7 @@ void _tr_stored_block(s, buf, stored_len, eof)
* To simplify the code, we assume the worst case of last real code encoded
* on one bit only.
*/
-void _tr_align(s)
+void ZLIB_INTERNAL _tr_align(s)
deflate_state *s;
{
send_bits(s, STATIC_TREES<<1, 3);
@@ -918,11 +922,11 @@ void _tr_align(s)
* Determine the best encoding for the current block: dynamic trees, static
* trees or store, and output the encoded block to the zip file.
*/
-void _tr_flush_block(s, buf, stored_len, eof)
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
deflate_state *s;
charf *buf; /* input block, or NULL if too old */
ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
+ int last; /* one if this is the last block for a file */
{
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
int max_blindex = 0; /* index of last bit length code of non zero freq */
@@ -931,8 +935,8 @@ void _tr_flush_block(s, buf, stored_len, eof)
if (s->level > 0) {
/* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
+ if (s->strm->data_type == Z_UNKNOWN)
+ s->strm->data_type = detect_data_type(s);
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -978,20 +982,20 @@ void _tr_flush_block(s, buf, stored_len, eof)
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
* transform a block into a stored block.
*/
- _tr_stored_block(s, buf, stored_len, eof);
+ _tr_stored_block(s, buf, stored_len, last);
#ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */
#else
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ send_bits(s, (STATIC_TREES<<1)+last, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
#ifdef DEBUG
s->compressed_len += 3 + s->static_len;
#endif
} else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_bits(s, (DYN_TREES<<1)+last, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1);
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
@@ -1005,21 +1009,21 @@ void _tr_flush_block(s, buf, stored_len, eof)
*/
init_block(s);
- if (eof) {
+ if (last) {
bi_windup(s);
#ifdef DEBUG
s->compressed_len += 7; /* align on byte boundary */
#endif
}
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
+ s->compressed_len-7*last));
}
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
-int _tr_tally (s, dist, lc)
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
deflate_state *s;
unsigned dist; /* distance of matched string */
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
@@ -1118,24 +1122,45 @@ local void compress_block(s, ltree, dtree)
}
/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ * a) There are no non-portable control characters belonging to the
+ * "black list" (0..6, 14..25, 28..31).
+ * b) There is at least one printable character belonging to the
+ * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ * "gray list" that is ignored in this detection algorithm:
+ * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
* IN assertion: the fields Freq of dyn_ltree are set.
*/
-local void set_data_type(s)
+local int detect_data_type(s)
deflate_state *s;
{
+ /* black_mask is the bit mask of black-listed bytes
+ * set bits 0..6, 14..25, and 28..31
+ * 0xf3ffc07f = binary 11110011111111111100000001111111
+ */
+ unsigned long black_mask = 0xf3ffc07fUL;
int n;
- for (n = 0; n < 9; n++)
+ /* Check for non-textual ("black-listed") bytes. */
+ for (n = 0; n <= 31; n++, black_mask >>= 1)
+ if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ return Z_BINARY;
+
+ /* Check for textual ("white-listed") bytes. */
+ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+ || s->dyn_ltree[13].Freq != 0)
+ return Z_TEXT;
+ for (n = 32; n < LITERALS; n++)
if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+ return Z_TEXT;
+
+ /* There are no "black-listed" or "white-listed" bytes:
+ * this stream either is empty or has tolerated ("gray-listed") bytes only.
+ */
+ return Z_BINARY;
}
/* ===========================================================================
diff --git a/lib/libz/trees.h b/lib/libz/trees.h
index 72facf9..d35639d 100644
--- a/lib/libz/trees.h
+++ b/lib/libz/trees.h
@@ -70,7 +70,7 @@ local const ct_data static_dtree[D_CODES] = {
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
};
-const uch _dist_code[DIST_CODE_LEN] = {
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
@@ -99,7 +99,7 @@ const uch _dist_code[DIST_CODE_LEN] = {
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
diff --git a/lib/libz/uncompr.c b/lib/libz/uncompr.c
index b59e3d0..ad98be3 100644
--- a/lib/libz/uncompr.c
+++ b/lib/libz/uncompr.c
@@ -1,5 +1,5 @@
/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -16,8 +16,6 @@
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
diff --git a/lib/libz/zconf.h b/lib/libz/zconf.h
index 205db95..4efd6b2 100644
--- a/lib/libz/zconf.h
+++ b/lib/libz/zconf.h
@@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -11,52 +11,124 @@
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
*/
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
+# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
+# define inflateUndermine z_inflateUndermine
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
# define zError z_zError
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
# define alloc_func z_alloc_func
+# define charf z_charf
# define free_func z_free_func
+# define gzFile z_gzFile
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
# define in_func z_in_func
+# define intf z_intf
# define out_func z_out_func
-# define Byte z_Byte
# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
# define uIntf z_uIntf
+# define uLong z_uLong
# define uLongf z_uLongf
-# define voidpf z_voidpf
# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
@@ -284,14 +356,34 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
+#if 0 /* was set to #if 0 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+# include <sys/types.h> /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
-# include <unixio.h> /* for off_t */
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
# endif
-# define z_off_t off_t
#endif
+
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
@@ -299,43 +391,46 @@ typedef uLong FAR uLongf;
#endif
/*
- * This is hard-configured for FreeBSD, since zlib doesn't actually support
- * using the system off_t for offsets unless off_t is no longer than long.
- * To minimize the diff, we just "undef z_off_t" rather than modifying
- * the following lines.
+ * This is hard-configured for FreeBSD.
*/
-#undef z_off_t
+#define z_off_t off_t
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
#ifndef z_off_t
# define z_off_t long
#endif
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define z_off64_t off64_t
+#else
+# define z_off64_t z_off_t
+#endif
+
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */
diff --git a/lib/libz/zlib.3 b/lib/libz/zlib.3
index 90b8162..27adc4c 100644
--- a/lib/libz/zlib.3
+++ b/lib/libz/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "18 July 2005"
+.TH ZLIB 3 "19 Apr 2010"
.SH NAME
zlib \- compression/decompression library
.SH SYNOPSIS
@@ -9,15 +9,15 @@ for full description]
The
.I zlib
library is a general purpose data compression library.
-The code is thread safe.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
It provides in-memory compression and decompression functions,
including integrity checks of the uncompressed data.
This version of the library supports only one compression method (deflation)
-but other algorithms will be added later
-and will have the same stream interface.
+but other algorithms may be added later
+with the same stream interface.
.LP
Compression can be done in a single step if the buffers are large enough
-(for example if an input file is mmap'ed),
or can be done by repeated calls of the compression function.
In the latter case,
the application must provide more input and/or consume the output
@@ -30,7 +30,7 @@ with an interface similar to that of stdio.
.LP
The library does not install any signal handler.
The decoder checks the consistency of the compressed data,
-so the library should never crash even in case of corrupted input.
+so the library should never crash even in the case of corrupted input.
.LP
All functions of the compression library are documented in the file
.IR zlib.h .
@@ -38,18 +38,19 @@ The distribution source includes examples of use of the library
in the files
.I example.c
and
-.IR minigzip.c .
+.IR minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
.LP
Changes to this version are documented in the file
.I ChangeLog
-that accompanies the source,
-and are concerned primarily with bug fixes and portability enhancements.
+that accompanies the source.
.LP
-A Java implementation of
.I zlib
-is available in the Java Development Kit 1.1:
+is available in Java using the java.util.zip package:
.IP
-http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+http://java.sun.com/developer/technicalArticles/Programming/compression/
.LP
A Perl interface to
.IR zlib ,
@@ -57,7 +58,7 @@ written by Paul Marquess (pmqs@cpan.org),
is available at CPAN (Comprehensive Perl Archive Network) sites,
including:
.IP
-http://www.cpan.org/modules/by-module/Compress/
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/
.LP
A Python interface to
.IR zlib ,
@@ -66,14 +67,11 @@ is available in Python 1.5 and later versions:
.IP
http://www.python.org/doc/lib/module-zlib.html
.LP
-A
.I zlib
-binding for
-.IR tcl (1),
-written by Andreas Kupries (a.kupries@westend.com),
-is availlable at:
+is built into
+.IR tcl:
.IP
-http://www.westend.com/~kupries/doc/trf/man/man.html
+http://wiki.tcl.tk/4610
.LP
An experimental package to read and write files in .zip format,
written on top of
@@ -81,40 +79,34 @@ written on top of
by Gilles Vollant (info@winimage.com),
is available at:
.IP
-http://www.winimage.com/zLibDll/unzip.html
+http://www.winimage.com/zLibDll/minizip.html
and also in the
.I contrib/minizip
directory of the main
.I zlib
-web site.
+source distribution.
.SH "SEE ALSO"
The
.I zlib
-web site can be found at either of these locations:
+web site can be found at:
.IP
-http://www.zlib.org
-.br
-http://www.gzip.org/zlib/
+http://zlib.net/
.LP
The data format used by the zlib library is described by RFC
(Request for Comments) 1950 to 1952 in the files:
.IP
-http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
+http://www.ietf.org/rfc/rfc1950.txt (for the zlib header and trailer format)
.br
-http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
+http://www.ietf.org/rfc/rfc1951.txt (for the deflate compressed data format)
.br
-http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
-.LP
-These documents are also available in other formats from:
-.IP
-ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+http://www.ietf.org/rfc/rfc1952.txt (for the gzip header and trailer format)
.LP
-Mark Nelson (markn@ieee.org) wrote an article about
+Mark Nelson wrote an article about
.I zlib
for the Jan. 1997 issue of Dr. Dobb's Journal;
a copy of the article is available at:
.IP
-http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+http://marknelson.us/1997/01/01/zlib-engine/
.SH "REPORTING PROBLEMS"
Before reporting a problem,
please check the
@@ -127,14 +119,14 @@ Please read the
.I zlib
FAQ at:
.IP
-http://www.gzip.org/zlib/zlib_faq.html
+http://zlib.net/zlib_faq.html
.LP
before asking for help.
Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
.SH AUTHORS
-Version 1.2.3
-Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org)
+Version 1.2.5
+Copyright (C) 1995-2010 Jean-loup Gailly (jloup@gzip.org)
and Mark Adler (madler@alumni.caltech.edu).
.LP
This software is provided "as-is,"
diff --git a/lib/libz/zlib.h b/lib/libz/zlib.h
index 0228179..bfbba83 100644
--- a/lib/libz/zlib.h
+++ b/lib/libz/zlib.h
@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
+ version 1.2.5, April 19th, 2010
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+ Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -37,41 +37,44 @@
extern "C" {
#endif
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
+#define ZLIB_VERSION "1.2.5"
+#define ZLIB_VERNUM 0x1250
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_SUBREVISION 0
/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
(providing more output space) before each call.
- The compressed data format used by default by the in-memory functions is
+ The compressed data format used by default by the in-memory functions is
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
around a deflate stream, which is itself documented in RFC 1951.
- The library also supports reading and writing files in gzip (.gz) format
+ The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio using the functions that start
with "gz". The gzip format is different from the zlib format. gzip is a
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
- This library can optionally read and write gzip streams in memory as well.
+ This library can optionally read and write gzip streams in memory as well.
- The zlib format was designed to be compact and fast for use in memory
+ The zlib format was designed to be compact and fast for use in memory
and on communications channels. The gzip format was designed for single-
file compression on file systems, has a larger header than zlib to maintain
directory information, and uses a different, slower check method than zlib.
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
*/
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
@@ -126,45 +129,45 @@ typedef struct gz_header_s {
typedef gz_header FAR *gz_headerp;
/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
opaque value.
- zalloc must return Z_NULL if there is not enough memory for the object.
+ zalloc must return Z_NULL if there is not enough memory for the object.
If zlib is used in a multi-threaded application, zalloc and zfree must be
thread safe.
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
*/
/* constants */
#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_PARTIAL_FLUSH 1
#define Z_SYNC_FLUSH 2
#define Z_FULL_FLUSH 3
#define Z_FINISH 4
#define Z_BLOCK 5
+#define Z_TREES 6
/* Allowed flush values; see deflate() and inflate() below for details */
#define Z_OK 0
@@ -176,8 +179,8 @@ typedef gz_header FAR *gz_headerp;
#define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5)
#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
*/
#define Z_NO_COMPRESSION 0
@@ -207,119 +210,140 @@ typedef gz_header FAR *gz_headerp;
#define zlib_version zlibVersion()
/* for compatibility with versions < 1.0.2 */
+
/* basic functions */
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
*/
/*
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
/*
deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
forced to flush.
- The detailed semantics are as follows. deflate performs one or both of the
+ The detailed semantics are as follows. deflate performs one or both of the
following actions:
- Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
+ accordingly. If not all input can be processed (because there is not
enough room in the output buffer), next_in and avail_in are updated and
processing will resume at this point for the next call of deflate().
- Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
+ accordingly. This action is forced if the parameter flush is non zero.
Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
+ decide how much data to accumulate before producing output, in order to
maximize compression.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
If flush is set to Z_FULL_FLUSH, all output is flushed as with
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
compression.
If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated
avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
avail_out is greater than six to avoid repeated flush markers due to
avail_out == 0 on return.
If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). If deflate does not return
Z_STREAM_END, then it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes).
deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
deflate() returns Z_OK if some progress has been made (more input
processed or more output produced), Z_STREAM_END if all input has been
consumed and all output has been produced (only when flush is set to
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
fatal, and deflate() can be called again with more input and more output
space to continue compressing.
*/
@@ -328,13 +352,13 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
+ This function discards any unprocessed input and does not flush any pending
+ output.
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
deallocated).
*/
@@ -342,10 +366,10 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
- Initializes the internal stream state for decompression. The fields
+ Initializes the internal stream state for decompression. The fields
next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
compression method from the zlib header and allocates all data structures
accordingly; otherwise the allocation will be deferred to the first call of
inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
@@ -353,95 +377,108 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
*/
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
/*
inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
+ buffer becomes empty or the output buffer becomes full. It may introduce
some output latency (reading input without producing any output) except when
forced to flush.
- The detailed semantics are as follows. inflate performs one or both of the
+ The detailed semantics are as follows. inflate performs one or both of the
following actions:
- Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
- Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all the uncompressed data. (The size
+ of the uncompressed data may have been saved by the compressor for this
+ purpose.) The next operation on this stream must be inflateEnd to deallocate
+ the decompression state. The use of Z_FINISH is never required, but can be
+ used to inform inflate that a faster approach may be used for the single
+ inflate() call.
In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
+ first call. So the only effect of the flush parameter in this implementation
is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
+ because Z_BLOCK or Z_TREES is used.
If a preset dictionary is needed after this call (see inflateSetDictionary
below), inflate sets strm->adler to the adler32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the adler32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
+ below. At the end of the stream, inflate() checks that its computed adler32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
only if the checksum is correct.
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer.
inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has
@@ -449,27 +486,28 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
corrupted (input stream not conforming to the zlib format or incorrect check
value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
*/
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
+ This function discards any unprocessed input and does not flush any pending
+ output.
inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
+ was inconsistent. In the error case, msg may be set but then points to a
static string (which must not be deallocated).
*/
+
/* Advanced functions */
/*
@@ -484,55 +522,57 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
int memLevel,
int strategy));
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
- The method parameter is the compression method. It must be Z_DEFLATED in
+ The method parameter is the compression method. It must be Z_DEFLATED in
this version of the library.
The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
deflateInit is used instead.
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
with no zlib header or trailer, and will not compute an adler32 check value.
- windowBits can also be greater than 15 for optional gzip encoding. Add
+ windowBits can also be greater than 15 for optional gzip encoding. Add
16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
gzip stream is being written, strm->adler is a crc32 instead of an adler32.
The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
- The strategy parameter is used to tune the compression algorithm. Use the
+ The strategy parameter is used to tune the compression algorithm. Use the
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
@@ -540,37 +580,37 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any call
+ of deflate. The compressor and decompressor must use exactly the same
dictionary (see inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
+ used strings preferably put towards the end of the dictionary. Using a
dictionary is most useful when the data to be compressed is short and can be
predicted with good accuracy; the data can then be compressed better than
with the default empty dictionary.
Depending on the size of the compression data structures selected by
deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
Upon return of this function, strm->adler is set to the adler32 value
of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
+ which dictionary has been used by the compressor. (The adler32 value
applies to the whole dictionary even if only a subset of the dictionary is
actually used by the compressor.) If a raw deflate was requested, then the
adler32 value is not computed and strm->adler is not set.
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
+ or if the compression method is bsort). deflateSetDictionary does not
perform any compression: this will be done by deflate().
*/
@@ -581,26 +621,26 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
This function can be useful when several compression strategies will be
tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
+ data with a filter. The streams that will be discarded should then be freed
by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
/*
This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
*/
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
@@ -610,18 +650,18 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
Dynamically update the compression level and compression strategy. The
interpretation of level and strategy is as in deflateInit2. This can be
used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
*/
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
@@ -645,9 +685,10 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
/*
deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate().
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
@@ -655,21 +696,21 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int value));
/*
deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
gz_headerp head));
/*
- deflateSetHeader() provides gzip header information for when a gzip
+ deflateSetHeader() provides gzip header information for when a gzip
stream is requested by deflateInit2(). deflateSetHeader() may be called
after deflateInit2() or deflateReset() and before the first call of
deflate(). The text, time, os, extra field, name, and comment information
@@ -682,11 +723,11 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
1.3.x) do not support header crc's, and will report that it is a "multi-part
gzip file" and give up.
- If deflateSetHeader is not used, the default gzip header has text false,
+ If deflateSetHeader is not used, the default gzip header has text false,
the time set to zero, and os set to 255, with no extra, name, or comment
fields. The gzip header is returned to the default state by deflateReset().
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
@@ -694,43 +735,50 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
- This is another version of inflateInit with an extra parameter. The
+ This is another version of inflateInit with an extra parameter. The
fields next_in, avail_in, zalloc, zfree and opaque must be initialized
before by the caller.
The windowBits parameter is the base two logarithm of the maximum window
size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
+ deflateInit2() was not used. If a compressed stream with a larger window
size is given as input, inflate() will return with the error code
Z_DATA_ERROR instead of trying to allocate a larger window.
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
+ looking for any check values for comparison at the end of the stream. This
is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
+ such as zip. Those formats provide their own check values. If a custom
format is developed using the raw deflate format for compressed data, it is
recommended that a check value such as an adler32 or a crc32 be applied to
the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
+ most applications, the zlib format should be used as is. Note that comments
above on the use in deflateInit2() applies to the magnitude of windowBits.
- windowBits can also be greater than 15 for optional gzip decoding. Add
+ windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
*/
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
@@ -738,8 +786,8 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the adler32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see
deflateSetDictionary). For raw inflate, this function can be called
@@ -748,26 +796,26 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
dictionary that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
+ expected one (incorrect adler32 value). inflateSetDictionary does not
perform any decompression: this will be done by subsequent calls of
inflate().
*/
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been
+ found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
+ success case, the application may save the current current value of total_in
+ which indicates where valid compressed data was found. In the error case,
+ the application may repeatedly call inflateSync, providing more input each
+ time, until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@@ -782,18 +830,30 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
/*
This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
*/
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
@@ -801,54 +861,87 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
int value));
/*
This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
gz_headerp head));
/*
- inflateGetHeader() requests that gzip header information be stored in the
+ inflateGetHeader() requests that gzip header information be stored in the
provided gz_header structure. inflateGetHeader() may be called after
inflateInit2() or inflateReset(), and before the first call of inflate().
As inflate() processes the gzip stream, head->done is zero until the header
is completed, at which time head->done is set to one. If a zlib stream is
being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
- The text, time, xflags, and os fields are filled in with the gzip header
+ The text, time, xflags, and os fields are filled in with the gzip header
contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
contains the maximum number of bytes to write to extra. Once done is true,
extra_len contains the actual extra field length, and extra contains the
extra field, or that field truncated if extra_max is less than extra_len.
If name is not Z_NULL, then up to name_max characters are written there,
terminated with a zero unless the length is greater than name_max. If
comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
absence. This allows the use of deflateSetHeader() with the returned
structure to duplicate the header. However if those fields are set to
allocated memory, then the application will need to save those pointers
elsewhere so that they can be eventually freed.
- If inflateGetHeader is not used, then the header information is simply
+ If inflateGetHeader is not used, then the header information is simply
discarded. The header is always checked for validity, including the header
CRC if present. inflateReset() will reset the process to discard the header
information. The application would need to call inflateGetHeader() again to
retrieve the header from the next gzip stream.
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
@@ -869,9 +962,9 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
*/
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
@@ -891,15 +984,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
A raw deflate stream is one with no zlib or gzip header or trailer.
This routine would normally be used in a utility that reads zip or gzip
files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
trailer around the deflate stream.
inflateBack() uses two subroutines supplied by the caller that are then
@@ -925,7 +1018,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
The in_desc and out_desc parameters of inflateBack() is passed as the
first parameter of in() and out() respectively when they are called. These
@@ -935,15 +1028,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
On return, inflateBack() will set strm->next_in and strm->avail_in to
pass back any unused input that was provided by the last in() call. The
return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
*/
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
@@ -999,23 +1092,22 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
/* utility functions */
/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
*/
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
+
compress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer.
@@ -1025,11 +1117,11 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
/*
- Compresses the source buffer into the destination buffer. The level
+ Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
+ length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
@@ -1040,22 +1132,20 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/*
compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
*/
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
@@ -1063,136 +1153,199 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
*/
-typedef voidp gzFile;
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef voidp gzFile; /* opaque gzip file descriptor */
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) Also "a"
+ can be used instead of "w" to request that the gzip stream that will be
+ written be appended to the file. "+" will result in an error, since reading
+ and writing to the same gzip file is not supported.
gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression.
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
*/
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
/*
- Dynamically update the compression level or strategy. See the description
+ Dynamically update the compression level or strategy. See the description
of deflateInit2 for the meaning of these parameters.
+
gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
opened for writing.
*/
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file was not in gzip format, gzread copies the given number of
+ bytes into the buffer.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream, or failing that, reading the rest
+ of the input file directly without decompression. The entire input file
+ will be read if gzread is called until it returns less than the requested
+ len.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
/*
Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
*/
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
*/
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
/*
- Writes the given null-terminated string to the compressed file, excluding
+ Writes the given null-terminated string to the compressed file, excluding
the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
+
+ gzputs returns the number of characters written, or -1 in case of error.
*/
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
*/
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
*/
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error.
*/
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
*/
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
*/
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
the value SEEK_END is not supported.
+
If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
+ extremely slow. If the file is opened for writing, only forward seeks are
supported; gzseek then compresses a sequence of zeroes up to the new
starting position.
- gzseek returns the resulting offset location as measured in bytes from
+ gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error, in
particular if the file is opened for writing and the new starting position
would be before the current position.
@@ -1202,68 +1355,127 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
/*
Rewinds the given file. This function is supported only for reading.
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
*/
+/*
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
*/
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
*/
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed. This state can change from
+ false to true while reading the input file if the end of a gzip stream is
+ reached, but is followed by data that is not another gzip stream.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
*/
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
*/
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
file that is being written concurrently.
*/
+
/* checksum functions */
/*
These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
+ anyway because they might be useful in applications using the compression
+ library.
*/
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
uLong adler = adler32(0L, Z_NULL, 0);
@@ -1273,9 +1485,10 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
if (adler != original_adler) error();
*/
+/*
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
z_off_t len2));
-/*
+
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
@@ -1285,9 +1498,11 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the for the crc. Pre- and post-conditioning (one's
+ complement) is performed within this function so it shouldn't be done by the
+ application.
+
Usage example:
uLong crc = crc32(0L, Z_NULL, 0);
@@ -1298,9 +1513,9 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error();
*/
+/*
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-/*
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
@@ -1339,16 +1554,57 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
#define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
+ ZLIB_VERSION, sizeof(z_stream))
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# ifdef _LARGEFILE64_SOURCE
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+/* hack for buggy compilers */
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
+ struct internal_state {int dummy;};
#endif
+/* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
#ifdef __cplusplus
}
diff --git a/lib/libz/zutil.c b/lib/libz/zutil.c
index d55f594..898ed34 100644
--- a/lib/libz/zutil.c
+++ b/lib/libz/zutil.c
@@ -1,5 +1,5 @@
/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -34,25 +34,25 @@ uLong ZEXPORT zlibCompileFlags()
uLong flags;
flags = 0;
- switch (sizeof(uInt)) {
+ switch ((int)(sizeof(uInt))) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
- switch (sizeof(uLong)) {
+ switch ((int)(sizeof(uLong))) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
- switch (sizeof(voidpf)) {
+ switch ((int)(sizeof(voidpf))) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
- switch (sizeof(z_off_t)) {
+ switch ((int)(sizeof(z_off_t))) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
@@ -117,9 +117,9 @@ uLong ZEXPORT zlibCompileFlags()
# ifndef verbose
# define verbose 0
# endif
-int z_verbose = verbose;
+int ZLIB_INTERNAL z_verbose = verbose;
-void z_error (m)
+void ZLIB_INTERNAL z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
@@ -146,7 +146,7 @@ const char * ZEXPORT zError(err)
#ifndef HAVE_MEMCPY
-void zmemcpy(dest, source, len)
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
@@ -157,7 +157,7 @@ void zmemcpy(dest, source, len)
} while (--len != 0);
}
-int zmemcmp(s1, s2, len)
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
const Bytef* s1;
const Bytef* s2;
uInt len;
@@ -170,7 +170,7 @@ int zmemcmp(s1, s2, len)
return 0;
}
-void zmemzero(dest, len)
+void ZLIB_INTERNAL zmemzero(dest, len)
Bytef* dest;
uInt len;
{
@@ -213,7 +213,7 @@ local ptr_table table[MAX_PTR];
* a protected system like OS/2. Use Microsoft C instead.
*/
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
{
voidpf buf = opaque; /* just to make some compilers happy */
ulg bsize = (ulg)items*size;
@@ -237,7 +237,7 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
return buf;
}
-void zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
int n;
if (*(ush*)&ptr != 0) { /* object < 64K */
@@ -272,13 +272,13 @@ void zcfree (voidpf opaque, voidpf ptr)
# define _hfree hfree
#endif
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
{
if (opaque) opaque = 0; /* to make compiler happy */
return _halloc((long)items, size);
}
-void zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
if (opaque) opaque = 0; /* to make compiler happy */
_hfree(ptr);
@@ -297,7 +297,7 @@ extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
-voidpf zcalloc (opaque, items, size)
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
@@ -307,7 +307,7 @@ voidpf zcalloc (opaque, items, size)
(voidpf)calloc(items, size);
}
-void zcfree (opaque, ptr)
+void ZLIB_INTERNAL zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
diff --git a/lib/libz/zutil.h b/lib/libz/zutil.h
index b7d5eff..258fa88 100644
--- a/lib/libz/zutil.h
+++ b/lib/libz/zutil.h
@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -13,31 +13,21 @@
#ifndef ZUTIL_H
#define ZUTIL_H
-#define ZLIB_INTERNAL
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
#include "zlib.h"
#ifdef STDC
-# ifndef _WIN32_WCE
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h>
# endif
# include <string.h>
# include <stdlib.h>
#endif
-#ifdef NO_ERRNO_H
-# ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
-# define errno z_errno
-# endif
- extern int errno;
-#else
-# ifndef _WIN32_WCE
-# include <errno.h>
-# endif
-#endif
#ifndef local
# define local static
@@ -89,7 +79,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
@@ -118,7 +108,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#ifdef OS2
# define OS_CODE 0x06
# ifdef M_I86
- #include <malloc.h>
+# include <malloc.h>
# endif
#endif
@@ -151,7 +141,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
# if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
@@ -163,6 +153,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# endif
#endif
+#if defined(__BORLANDC__)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
/* common defaults */
#ifndef OS_CODE
@@ -197,7 +199,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# ifdef WIN32
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# define vsnprintf _vsnprintf
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
# endif
# endif
# ifdef __SASC
@@ -232,16 +236,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
#endif
/* Diagnostic functions */
#ifdef DEBUG
# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
@@ -258,8 +262,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#endif
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
+voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
diff --git a/lib/msun/man/cimag.3 b/lib/msun/man/cimag.3
index 18fefc4..6661ad2 100644
--- a/lib/msun/man/cimag.3
+++ b/lib/msun/man/cimag.3
@@ -118,4 +118,4 @@ functions first appeared in
The
.Fn cproj
functions appeared in
-.Fx 8.0.
+.Fx 8.0 .
diff --git a/libexec/fingerd/fingerd.8 b/libexec/fingerd/fingerd.8
index 232771a..e28164c 100644
--- a/libexec/fingerd/fingerd.8
+++ b/libexec/fingerd/fingerd.8
@@ -32,7 +32,7 @@
.\" @(#)fingerd.8 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd April 1, 2010
.Dt FINGERD 8
.Os
.Sh NAME
@@ -40,6 +40,8 @@
.Nd remote user information server
.Sh SYNOPSIS
.Nm
+.Op Fl d
+.Op Fl k
.Op Fl s
.Op Fl l
.Op Fl p Ar filename
@@ -106,6 +108,25 @@ The following options may be passed to
as server program arguments in
.Pa /etc/inetd.conf :
.Bl -tag -width indent
+.It Fl d
+Enable debugging mode.
+In debugging mode,
+.Nm
+will not attempt any network-related operations on
+.Va stdin ,
+and it will print the full
+.Nm finger
+command line
+to
+.Va stderr
+before executing it.
+.It Fl k
+Suppress login information.
+See the description of the
+.Fl k
+option in
+.Xr finger 1
+for details.
.It Fl s
Enable secure mode.
Queries without a user name are rejected and
diff --git a/libexec/fingerd/fingerd.c b/libexec/fingerd/fingerd.c
index 7d2a754..0225d94 100644
--- a/libexec/fingerd/fingerd.c
+++ b/libexec/fingerd/fingerd.c
@@ -72,17 +72,23 @@ main(int argc, char *argv[])
char *lp;
struct sockaddr_storage ss;
socklen_t sval;
- int p[2], logging, pflag, secure;
+ int p[2], debug, kflag, logging, pflag, secure;
#define ENTRIES 50
char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog;
char rhost[MAXHOSTNAMELEN];
prog = _PATH_FINGER;
- logging = pflag = secure = 0;
+ debug = logging = kflag = pflag = secure = 0;
openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON);
opterr = 0;
- while ((ch = getopt(argc, argv, "lp:s")) != -1)
+ while ((ch = getopt(argc, argv, "dklp:s")) != -1)
switch (ch) {
+ case 'd':
+ debug = 1;
+ break;
+ case 'k':
+ kflag = 1;
+ break;
case 'l':
logging = 1;
break;
@@ -101,7 +107,7 @@ main(int argc, char *argv[])
/*
* Enable server-side Transaction TCP.
*/
- {
+ if (!debug) {
int one = 1;
if (setsockopt(STDOUT_FILENO, IPPROTO_TCP, TCP_NOPUSH, &one,
sizeof one) < 0) {
@@ -112,7 +118,7 @@ main(int argc, char *argv[])
if (!fgets(line, sizeof(line), stdin))
exit(1);
- if (logging || pflag) {
+ if (!debug && (logging || pflag)) {
sval = sizeof(ss);
if (getpeername(0, (struct sockaddr *)&ss, &sval) < 0)
logerr("getpeername: %s", strerror(errno));
@@ -143,12 +149,14 @@ main(int argc, char *argv[])
syslog(LOG_NOTICE, "query from %s: `%s'", rhost, t);
}
- comp = &av[1];
- av[2] = "--";
- for (lp = line, ap = &av[3];;) {
+ comp = &av[2];
+ av[3] = "--";
+ if (kflag)
+ *comp-- = "-k";
+ for (lp = line, ap = &av[4];;) {
*ap = strtok(lp, " \t\r\n");
if (!*ap) {
- if (secure && ap == &av[3]) {
+ if (secure && ap == &av[4]) {
puts("must provide username\r\n");
exit(1);
}
@@ -161,8 +169,7 @@ main(int argc, char *argv[])
/* RFC742: "/[Ww]" == "-l" */
if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) {
- av[1] = "-l";
- comp = &av[0];
+ *comp-- = "-l";
}
else if (++ap == av + ENTRIES) {
*ap = NULL;
@@ -178,6 +185,13 @@ main(int argc, char *argv[])
if (pipe(p) < 0)
logerr("pipe: %s", strerror(errno));
+ if (debug) {
+ fprintf(stderr, "%s", prog);
+ for (ap = comp; *ap != NULL; ++ap)
+ fprintf(stderr, " %s", *ap);
+ fprintf(stderr, "\n");
+ }
+
switch(vfork()) {
case 0:
(void)close(p[0]);
diff --git a/libexec/ftpd/popen.c b/libexec/ftpd/popen.c
index 3c187b9..8a739dc 100644
--- a/libexec/ftpd/popen.c
+++ b/libexec/ftpd/popen.c
@@ -110,10 +110,11 @@ ftpd_popen(char *program, char *type)
flags |= GLOB_LIMIT;
if (glob(argv[argc], flags, NULL, &gl))
gargv[gargc++] = strdup(argv[argc]);
- else
+ else if (gl.gl_pathc > 0) {
for (pop = gl.gl_pathv; *pop && gargc < (MAXGLOBARGS-1);
pop++)
gargv[gargc++] = strdup(*pop);
+ }
globfree(&gl);
}
gargv[gargc] = NULL;
diff --git a/libexec/rtld-elf/mips/reloc.c b/libexec/rtld-elf/mips/reloc.c
index dd64644..b58e3fe 100644
--- a/libexec/rtld-elf/mips/reloc.c
+++ b/libexec/rtld-elf/mips/reloc.c
@@ -1,5 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.23 2003/07/26 15:04:38 mrg Exp $ */
-/* $NetBSD: mips_reloc.c,v 1.53 2008/07/24 04:39:25 matt Exp $ */
+/* $NetBSD: mips_reloc.c,v 1.58 2010/01/14 11:57:06 skrll Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
@@ -31,66 +30,102 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/endian.h>
+
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
+
#include "debug.h"
#include "rtld.h"
void
init_pltgot(Obj_Entry *obj)
-{
+{
if (obj->pltgot != NULL) {
obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
+ /* XXX only if obj->pltgot[1] & 0x80000000 ?? */
obj->pltgot[1] |= (Elf_Addr) obj;
}
}
-int
+int
do_copy_relocations(Obj_Entry *dstobj)
{
/* Do nothing */
- return 0;
+ return 0;
}
-void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
-int open();
-int _open();
-
/*
* It is possible for the compiler to emit relocations for unaligned data.
* We handle this situation with these inlines.
*/
-#define RELOC_ALIGNED_P(x) \
- (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
-
-static __inline Elf_Addr
-load_ptr(void *where)
+#if ELFSIZE == 64
+/*
+ * ELF64 MIPS encodes the relocs uniquely. The first 32-bits of info contain
+ * the symbol index. The top 32-bits contain three relocation types encoded
+ * in big-endian integer with first relocation in LSB. This means for little
+ * endian we have to byte swap that interger (r_type).
+ */
+#define Elf_Sxword Elf64_Sxword
+#define ELF_R_NXTTYPE_64_P(r_type) ((((r_type) >> 8) & 0xff) == R_TYPE(64))
+#if BYTE_ORDER == LITTLE_ENDIAN
+#undef ELF_R_SYM
+#undef ELF_R_TYPE
+#define ELF_R_SYM(r_info) ((r_info) & 0xffffffff)
+#define ELF_R_TYPE(r_info) bswap32((r_info) >> 32)
+#endif
+#else
+#define ELF_R_NXTTYPE_64_P(r_type) (0)
+#define Elf_Sxword Elf32_Sword
+#endif
+
+static __inline Elf_Sxword
+load_ptr(void *where, size_t len)
{
- if (__predict_true(RELOC_ALIGNED_P(where)))
- return *(Elf_Addr *)where;
- else {
- Elf_Addr res;
-
- (void)memcpy(&res, where, sizeof(res));
- return res;
+ Elf_Sxword val;
+
+ if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) {
+#if ELFSIZE == 64
+ if (len == sizeof(Elf_Sxword))
+ return *(Elf_Sxword *)where;
+#endif
+ return *(Elf_Sword *)where;
}
+
+ val = 0;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ (void)memcpy(&val, where, len);
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ (void)memcpy((uint8_t *)((&val)+1) - len, where, len);
+#endif
+ return (len == sizeof(Elf_Sxword)) ? val : (Elf_Sword)val;
}
static __inline void
-store_ptr(void *where, Elf_Addr val)
+store_ptr(void *where, Elf_Sxword val, size_t len)
{
- if (__predict_true(RELOC_ALIGNED_P(where)))
- *(Elf_Addr *)where = val;
- else
- (void)memcpy(where, &val, sizeof(val));
+ if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) {
+#if ELFSIZE == 64
+ if (len == sizeof(Elf_Sxword)) {
+ *(Elf_Sxword *)where = val;
+ return;
+ }
+#endif
+ *(Elf_Sword *)where = val;
+ return;
+ }
+#if BYTE_ORDER == LITTLE_ENDIAN
+ (void)memcpy(where, &val, len);
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ (void)memcpy(where, (const uint8_t *)((&val)+1) - len, len);
+#endif
}
void
@@ -102,7 +137,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
Elf_Addr *where;
Elf_Addr *got = NULL;
Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0;
- int i;
+ size_t i;
for (; dynp->d_tag != DT_NULL; dynp++) {
switch (dynp->d_tag) {
@@ -134,7 +169,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
/* Relocate the local GOT entries */
got += i;
for (; i < local_gotno; i++) {
- *got++ += relocbase;
+ *got++ += relocbase;
}
sym = symtab + gotsym;
@@ -147,19 +182,41 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
for (; rel < rellim; rel++) {
+ Elf_Word r_symndx, r_type;
+
where = (void *)(relocbase + rel->r_offset);
- switch (ELF_R_TYPE(rel->r_info)) {
- case R_TYPE(NONE):
+ r_symndx = ELF_R_SYM(rel->r_info);
+ r_type = ELF_R_TYPE(rel->r_info);
+
+ switch (r_type & 0xff) {
+ case R_TYPE(REL32): {
+ const size_t rlen =
+ ELF_R_NXTTYPE_64_P(r_type)
+ ? sizeof(Elf_Sxword)
+ : sizeof(Elf_Sword);
+ Elf_Sxword old = load_ptr(where, rlen);
+ Elf_Sxword val = old;
+#if ELFSIZE == 64
+ assert(r_type == R_TYPE(REL32)
+ || r_type == (R_TYPE(REL32)|(R_TYPE(64) << 8)));
+#endif
+ assert(r_symndx < gotsym);
+ sym = symtab + r_symndx;
+ assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL);
+ val += relocbase;
+ store_ptr(where, val, sizeof(Elf_Sword));
+ dbg("REL32/L(%p) %p -> %p in <self>",
+ where, (void *)old, (void *)val);
+ store_ptr(where, val, rlen);
break;
+ }
- case R_TYPE(REL32):
- assert(ELF_R_SYM(rel->r_info) < gotsym);
- sym = symtab + ELF_R_SYM(rel->r_info);
- assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL);
- store_ptr(where, load_ptr(where) + relocbase);
+ case R_TYPE(GPREL32):
+ case R_TYPE(NONE):
break;
+
default:
abort();
break;
@@ -189,9 +246,6 @@ _mips_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
return (Elf_Addr)target;
}
-/*
- * Process non-PLT relocations
- */
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
{
@@ -200,12 +254,24 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
Elf_Addr *got = obj->pltgot;
const Elf_Sym *sym, *def;
const Obj_Entry *defobj;
- int i;
+ Elf_Word i;
+#ifdef SUPPORT_OLD_BROKEN_LD
+ int broken;
+#endif
/* The relocation for the dynamic loader has already been done. */
if (obj == obj_rtld)
return (0);
+#ifdef SUPPORT_OLD_BROKEN_LD
+ broken = 0;
+ sym = obj->symtab;
+ for (i = 1; i < 12; i++)
+ if (sym[i].st_info == ELF_ST_INFO(STB_LOCAL, STT_NOTYPE))
+ broken = 1;
+ dbg("%s: broken=%d", obj->path, broken);
+#endif
+
i = (got[1] & 0x80000000) ? 2 : 1;
/* Relocate the local GOT entries */
@@ -213,16 +279,39 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
dbg("got:%p for %d entries adding %x",
got, obj->local_gotno, (uint32_t)obj->relocbase);
for (; i < obj->local_gotno; i++) {
- *got += (Elf_Addr)obj->relocbase;
- got++;
+ *got += (Elf_Addr)obj->relocbase;
+ got++;
}
sym = obj->symtab + obj->gotsym;
-
dbg("got:%p for %d entries",
got, obj->symtabno);
/* Now do the global GOT entries */
for (i = obj->gotsym; i < obj->symtabno; i++) {
+ dbg(" doing got %d sym %p (%s, %lx)", i - obj->gotsym, sym,
+ sym->st_name + obj->strtab, (u_long) *got);
+
+#ifdef SUPPORT_OLD_BROKEN_LD
+ if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
+ broken && sym->st_shndx == SHN_UNDEF) {
+ /*
+ * XXX DANGER WILL ROBINSON!
+ * You might think this is stupid, as it intentionally
+ * defeats lazy binding -- and you'd be right.
+ * Unfortunately, for lazy binding to work right, we
+ * need to a way to force the GOT slots used for
+ * function pointers to be resolved immediately. This
+ * is supposed to be done automatically by the linker,
+ * by not outputting a PLT slot and setting st_value
+ * to 0 if there are non-PLT references, but older
+ * versions of GNU ld do not do this.
+ */
+ def = find_symdef(i, obj, &defobj, false, NULL);
+ if (def == NULL)
+ return -1;
+ *got = def->st_value + (Elf_Addr)defobj->relocbase;
+ } else
+#endif
if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
sym->st_value != 0 && sym->st_shndx == SHN_UNDEF) {
/*
@@ -242,81 +331,118 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
*/
*got = sym->st_value + (Elf_Addr)obj->relocbase;
if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
- dbg("Warning2, i:%d maps to relocbase address:%x",
- i, (uint32_t)obj->relocbase);
+ dbg("Warning2, i:%d maps to relocbase address:%x",
+ i, (uint32_t)obj->relocbase);
}
} else if (sym->st_info == ELF_ST_INFO(STB_GLOBAL, STT_SECTION)) {
/* Symbols with index SHN_ABS are not relocated. */
- if (sym->st_shndx != SHN_ABS) {
+ if (sym->st_shndx != SHN_ABS) {
*got = sym->st_value +
(Elf_Addr)obj->relocbase;
if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
- dbg("Warning3, i:%d maps to relocbase address:%x",
- i, (uint32_t)obj->relocbase);
+ dbg("Warning3, i:%d maps to relocbase address:%x",
+ i, (uint32_t)obj->relocbase);
}
}
} else {
/* TODO: add cache here */
def = find_symdef(i, obj, &defobj, false, NULL);
if (def == NULL) {
- dbg("Warning4, cant find symbole %d", i);
+ dbg("Warning4, cant find symbole %d", i);
return -1;
}
*got = def->st_value + (Elf_Addr)defobj->relocbase;
if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
- dbg("Warning4, i:%d maps to relocbase address:%x",
- i, (uint32_t)obj->relocbase);
- dbg("via first obj symbol %s",
- obj->strtab + obj->symtab[i].st_name);
- dbg("found in obj %p:%s",
- defobj, defobj->path);
- }
+ dbg("Warning4, i:%d maps to relocbase address:%x",
+ i, (uint32_t)obj->relocbase);
+ dbg("via first obj symbol %s",
+ obj->strtab + obj->symtab[i].st_name);
+ dbg("found in obj %p:%s",
+ defobj, defobj->path);
+ }
}
+
+ dbg(" --> now %lx", (u_long) *got);
++sym;
++got;
}
+
got = obj->pltgot;
rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
for (rel = obj->rel; rel < rellim; rel++) {
+ Elf_Word r_symndx, r_type;
void *where;
- Elf_Addr tmp;
- unsigned long symnum;
where = obj->relocbase + rel->r_offset;
- symnum = ELF_R_SYM(rel->r_info);
- switch (ELF_R_TYPE(rel->r_info)) {
+ r_symndx = ELF_R_SYM(rel->r_info);
+ r_type = ELF_R_TYPE(rel->r_info);
+
+ switch (r_type & 0xff) {
case R_TYPE(NONE):
break;
- case R_TYPE(REL32):
+ case R_TYPE(REL32): {
/* 32-bit PC-relative reference */
- def = obj->symtab + symnum;
- if (symnum >= obj->gotsym) {
- tmp = load_ptr(where);
- tmp += got[obj->local_gotno + symnum - obj->gotsym];
- store_ptr(where, tmp);
- break;
+ const size_t rlen =
+ ELF_R_NXTTYPE_64_P(r_type)
+ ? sizeof(Elf_Sxword)
+ : sizeof(Elf_Sword);
+ Elf_Sxword old = load_ptr(where, rlen);
+ Elf_Sxword val = old;
+
+ def = obj->symtab + r_symndx;
+
+ if (r_symndx >= obj->gotsym) {
+ val += got[obj->local_gotno + r_symndx - obj->gotsym];
+ dbg("REL32/G(%p) %p --> %p (%s) in %s",
+ where, (void *)old, (void *)val,
+ obj->strtab + def->st_name,
+ obj->path);
} else {
- tmp = load_ptr(where);
+ /*
+ * XXX: ABI DIFFERENCE!
+ *
+ * Old NetBSD binutils would generate shared
+ * libs with section-relative relocations being
+ * already adjusted for the start address of
+ * the section.
+ *
+ * New binutils, OTOH, generate shared libs
+ * with the same relocations being based at
+ * zero, so we need to add in the start address
+ * of the section.
+ *
+ * --rkb, Oct 6, 2001
+ */
if (def->st_info ==
ELF_ST_INFO(STB_LOCAL, STT_SECTION)
+#ifdef SUPPORT_OLD_BROKEN_LD
+ && !broken
+#endif
)
- tmp += (Elf_Addr)def->st_value;
+ val += (Elf_Addr)def->st_value;
+
+ val += (Elf_Addr)obj->relocbase;
- tmp += (Elf_Addr)obj->relocbase;
- store_ptr(where, tmp);
+ dbg("REL32/L(%p) %p -> %p (%s) in %s",
+ where, (void *)old, (void *)val,
+ obj->strtab + def->st_name, obj->path);
}
+ store_ptr(where, val, rlen);
break;
+ }
+
default:
dbg("sym = %lu, type = %lu, offset = %p, "
"contents = %p, symbol = %s",
- symnum, (u_long)ELF_R_TYPE(rel->r_info),
- (void *)rel->r_offset, (void *)load_ptr(where),
- obj->strtab + obj->symtab[symnum].st_name);
+ (u_long)r_symndx, (u_long)ELF_R_TYPE(rel->r_info),
+ (void *)rel->r_offset,
+ (void *)load_ptr(where, sizeof(Elf_Sword)),
+ obj->strtab + obj->symtab[r_symndx].st_name);
_rtld_error("%s: Unsupported relocation type %ld "
- "in non-PLT relocations\n",
+ "in non-PLT relocations",
obj->path, (u_long) ELF_R_TYPE(rel->r_info));
return -1;
}
@@ -331,6 +457,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
int
reloc_plt(Obj_Entry *obj)
{
+#if 0
const Elf_Rel *rellim;
const Elf_Rel *rel;
@@ -345,6 +472,8 @@ reloc_plt(Obj_Entry *obj)
*where += (Elf_Addr )obj->relocbase;
}
+#endif
+ /* PLT fixups were done above in the GOT relocation. */
return (0);
}
diff --git a/libexec/rtld-elf/mips/rtld_start.S b/libexec/rtld-elf/mips/rtld_start.S
index 138729d..b4b7079 100644
--- a/libexec/rtld-elf/mips/rtld_start.S
+++ b/libexec/rtld-elf/mips/rtld_start.S
@@ -1,5 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.9 2002/10/05 11:59:05 mycroft Exp $ */
-/* $FreeBSD$ */
+/* $NetBSD: rtld_start.S,v 1.10 2009/12/14 00:41:19 matt Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
@@ -27,6 +26,8 @@
* 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 <machine/asm.h>
@@ -34,94 +35,126 @@
.globl _C_LABEL(_rtld_relocate_nonplt_self)
.globl _C_LABEL(_rtld)
+#define PTR_SIZE (1<<PTR_SCALESHIFT)
+
+/*
+ * a0 stack pointer
+ * a1 rtld cleanup (filled in by dynamic loader)
+ * a2 rtld object (filled in by dynamic loader)
+ * a3 ps_strings
+ */
LEAF(rtld_start)
- .abicalls
+ .frame sp, 4*PTR_SIZE, ra
+ .mask 0x10090000,-PTR_SIZE
.set noreorder
+ SETUP_GP
+ PTR_SUBU sp, 4*PTR_SIZE /* adjust stack pointer */
+ SETUP_GP64(s4, rtld_start)
+ SAVE_GP(0)
+ /* -> 1*PTR_SIZE(sp) for atexit */
+ /* -> 2*PTR_SIZE(sp) for obj_main */
+ move s0, a0 /* save stack pointer from a0 */
+ move s3, a3 /* save ps_strings pointer */
- .cpload t9
- addu sp, sp, -16 /* adjust stack pointer */
- /* keep it aligned */
- .cprestore 0 /* -> 0(sp) for gp */
- /* -> 4(sp) for atexit */
- /* -> 8(sp) for obj_main */
- move s0,a0 /* save stack pointer from a0 */
- move s1,a3 /* save ps_strings pointer */
-
- la a1, 1f
+ PTR_LA a1, 1f
bal 1f
- nop
-1: subu a1, ra, a1 /* relocbase */
- la t9,_C_LABEL(_rtld_relocate_nonplt_self)
- move s2,a1
- la a0,_DYNAMIC
- addu t9, a1, t9
- jalr t9
- addu a0, a1, a0 /* &_DYNAMIC */
-
+ PTR_LA t0, _C_LABEL(_rtld_relocate_nonplt_self)
+1: PTR_SUBU a1, ra, a1 /* relocbase */
+ PTR_LA a0, _DYNAMIC
+ PTR_ADDU t9, a1, t0
+ jalr t9 /* _rtld_relocate_nonplt_self(dynp, relocabase) */
+ PTR_ADDU a0, a1, a0 /* &_DYNAMIC */
- move a0, s0 /* stack pointer */
- addu a1, sp, 4 /* &exit_proc */
- addu a2, sp, 8 /* &objp */
- addu sp, sp, -16 /* arguments slot */
- jal _C_LABEL(_rtld) /* v0 = _rtld(sp, exit_proc, objp) */
- nop
- addu sp, sp, 16
+ move a0, s0 /* sp */
+ PTR_ADDU a1, sp, 2*PTR_SIZE /* &our atexit function */
+ PTR_ADDU a2, sp, 3*PTR_SIZE /* obj_main entry */
+ jal _C_LABEL(_rtld) /* v0 = _rtld(sp, cleanup, objp) */
+ nop
- move a0, s0 /* arguments pointer */
- move a3, s1 /* arguments pointer */
- lw a1, 4(sp) /* our atexit function */
- lw a2, 8(sp) /* obj_main entry */
- addu sp, sp, 16 /* readjust stack */
- move t9,v0
- move a2,s1 /* restore ps_strings */
- jr t9 /* _start(ap, cleanup, obj, ps_strings); */
- nop
+ PTR_L a1, 2*PTR_SIZE(sp) /* our atexit function */
+ PTR_L a2, 3*PTR_SIZE(sp) /* obj_main entry */
+ PTR_ADDU sp, 4*PTR_SIZE /* readjust stack */
+ move a0, s0 /* stack pointer */
+ move t9, v0
+ jr t9 /* _start(sp, cleanup, obj); */
+ move a3, s3 /* restore ps_strings */
END(rtld_start)
+#define XCALLFRAME_SIZ (12*SZREG)
+#define XCALLFRAME_RA (10*SZREG)
+#define XCALLFRAME_GP (9*SZREG)
+#define XCALLFRAME_S0 (8*SZREG)
+#define XCALLFRAME_A3 (7*SZREG)
+#define XCALLFRAME_A2 (6*SZREG)
+#define XCALLFRAME_A1 (5*SZREG)
+#define XCALLFRAME_A0 (4*SZREG)
+#if defined(__mips_n32) || defined(__mips_n64)
+#define XCALLFRAME_A7 (3*SZREG)
+#define XCALLFRAME_A6 (2*SZREG)
+#define XCALLFRAME_A5 (1*SZREG)
+#define XCALLFRAME_A4 (0*SZREG)
+#endif
+
.globl _rtld_bind_start
.ent _rtld_bind_start
_rtld_bind_start:
- /* ABI conventions for stubs:
- * t8 contains symbol index
- * t7 contains return address
- */
- .frame sp, 0, ra /* satisfy compiler */
+ .frame sp, XCALLFRAME_SIZ, $15
+ move v1, gp /* save old GP */
+#if defined(__mips_o32) || defined(__mips_o64)
+ PTR_ADDU t9, 8 /* modify T9 to point at .cpload */
+#endif
+ SETUP_GP
+ PTR_SUBU sp, XCALLFRAME_SIZ /* save arguments and sp value in stack */
+ SETUP_GP64(XCALLFRAME_GP, _rtld_bind_start)
+ SAVE_GP(XCALLFRAME_GP)
+#if defined(__mips_n32) || defined(__mips_n64)
+ REG_S a4, XCALLFRAME_A4(sp)
+ REG_S a5, XCALLFRAME_A5(sp)
+ REG_S a6, XCALLFRAME_A6(sp)
+ REG_S a7, XCALLFRAME_A7(sp)
+#endif
+ REG_S a0, XCALLFRAME_A0(sp)
+ REG_S a1, XCALLFRAME_A1(sp)
+ REG_S a2, XCALLFRAME_A2(sp)
+ REG_S a3, XCALLFRAME_A3(sp)
+ REG_S $15, XCALLFRAME_RA(sp) /* ra is in t7/t3 */
+ REG_S s0, XCALLFRAME_S0(sp)
+ move s0, sp
- move v1,gp /* save old GP */
- add t9,8 /* modify T9 to point at .cpload */
- .cpload t9
- subu sp,48 /* save arguments and sp value */
- .cprestore 36
- sw a0,16(sp)
- sw a1,20(sp)
- sw a2,24(sp)
- sw a3,28(sp)
- sw s0,32(sp)
- sw t7,40(sp)
- move s0,sp
- move a0,v1 /* old GP */
- subu a0,a0,0x7ff0 /* The offset of $gp from the */
- /* beginning of the .got section: */
+ move a0, v1 /* old GP */
+ subu a0, a0, 0x7ff0 /* The offset of $gp from the */
+ /* beginning of the .got section: */
/* $gp = .got + 0x7ff0, so */
/* .got = $gp - 0x7ff0 */
/* Simple math as you can see. */
+#if defined(__mips_n64)
+ ld a0, 8(a0) /* object = pltgot[1] & 0x7fffffff */
+#else
+ lw a0, 4(a0) /* object = pltgot[1] & 0x7fffffff */
+#endif
+ and a0, a0, 0x7fffffff
+ move a1, t8 /* symbol index */
- lw a0,4(a0) /* object = pltgot[1] & 0x7fffffff */
- and a0,a0,0x7fffffff
- move a1,t8 /* symbol index */
-
jal _C_LABEL(_mips_rtld_bind)
- nop
- move sp,s0
- lw ra,40(sp)
- lw a0,16(sp)
- lw a1,20(sp)
- lw a2,24(sp)
- lw a3,28(sp)
- lw s0,32(sp)
- addu sp,48
- move t9,v0
+ nop
+
+ move sp, s0
+ REG_L ra, XCALLFRAME_RA(sp)
+ REG_L s0, XCALLFRAME_S0(sp)
+ REG_L a0, XCALLFRAME_A0(sp)
+ REG_L a1, XCALLFRAME_A1(sp)
+ REG_L a2, XCALLFRAME_A2(sp)
+ REG_L a3, XCALLFRAME_A3(sp)
+#if defined(__mips_n32) || defined(__mips_n64)
+ REG_L a4, XCALLFRAME_A4(sp)
+ REG_L a5, XCALLFRAME_A5(sp)
+ REG_L a6, XCALLFRAME_A6(sp)
+ REG_L a7, XCALLFRAME_A7(sp)
+#endif
+ RESTORE_GP64
+ PTR_ADDU sp, XCALLFRAME_SIZ
+ move t9, v0
jr t9
- nop
- .end _rtld_bind_start
+ nop
+END(_rtld_bind_start)
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index d91dcee..cb1002c 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -1961,7 +1961,7 @@ dlclose(void *handle)
return 0;
}
-const char *
+char *
dlerror(void)
{
char *msg = error_message;
diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8
index 5eb124f..f9d7aec 100644
--- a/libexec/tftpd/tftpd.8
+++ b/libexec/tftpd/tftpd.8
@@ -240,7 +240,7 @@ and the
and
.Fl W
options were introduced in
-.Fx 7 .
+.Fx 8.0 .
.Pp
.Sh BUGS
Files larger than 33488896 octets (65535 blocks) cannot be transferred
diff --git a/release/Makefile b/release/Makefile
index 53b53a7..6144fdd 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -171,7 +171,7 @@ NOPORTSATALL= YES
#
# Doing 'make index' in /usr/ports requires Perl.
-MAKEINDEXPORTS= lang/perl5.8
+MAKEINDEXPORTS= lang/perl5.10
DOCPORTS= textproc/docproj
# Set this to wherever the distfiles required by release procedures.
.if defined(DOCDISTFILES)
@@ -575,7 +575,7 @@ release rerelease:
echo " for i in ${MAKEINDEXPORTS}" >> ${_MK}
echo " do" >> ${_MK}
echo " cd /usr/ports/\$${i}" >> ${_MK}
- echo " env -i FTP_PASSIVE_MODE=$${FTP_PASSIVE_MODE:-no} PATH=$${PATH} \\" >> ${_MK}
+ echo " env -i HTTP_PROXY=$${HTTP_PROXY} FTP_PROXY=$${FTP_PROXY} FTP_PASSIVE_MODE=$${FTP_PASSIVE_MODE:-no} PATH=$${PATH} \\" >> ${_MK}
echo " make all install clean BATCH=yes FORCE_PKG_REGISTER=yes" >> ${_MK}
echo " done" >> ${_MK}
echo " cd /usr/ports" >> ${_MK}
diff --git a/release/Makefile.inc.docports b/release/Makefile.inc.docports
index 723103c..610fae3 100644
--- a/release/Makefile.inc.docports
+++ b/release/Makefile.inc.docports
@@ -81,5 +81,5 @@ MINIMALDOCPORTS+= \
ports/textproc/p5-PodParser
.else
MINIMALDOCPORTS+= \
- ports/lang/perl5.8
+ ports/lang/perl5.10
.endif
diff --git a/release/powerpc/boot_crunch.conf b/release/powerpc/boot_crunch.conf
index 9f7a301..4868519 100644
--- a/release/powerpc/boot_crunch.conf
+++ b/release/powerpc/boot_crunch.conf
@@ -15,6 +15,7 @@ srcdirs /usr/src/sbin
progs camcontrol
progs dhclient
progs fsck_ffs
+progs geom
progs ifconfig
progs mount_msdosfs
progs mount_nfs
@@ -25,6 +26,8 @@ progs rtsol
progs tunefs
ln fsck_ffs fsck_4.2bsd
ln fsck_ffs fsck_ufs
+ln geom glabel
+ln geom gpart
srcdirs /usr/src/usr.bin
progs cpio
@@ -43,4 +46,4 @@ progs usbconfig
libs -ll -ledit -lutil -lmd -lcrypt -lftpio -lz -lnetgraph
libs -ldialog -lncurses -ldisk -lcam -lkiconv -lsbuf -lufs
-libs -lbsdxml -larchive -lbz2 -lusb -ljail
+libs -lgeom -lbsdxml -larchive -lbz2 -lusb -ljail
diff --git a/sbin/ddb/Makefile b/sbin/ddb/Makefile
index b9189c1..c556be1 100644
--- a/sbin/ddb/Makefile
+++ b/sbin/ddb/Makefile
@@ -3,7 +3,7 @@
PROG= ddb
SRCS= ddb.c ddb_capture.c ddb_script.c
MAN= ddb.8
-WARNS= 3
+WARNS?= 3
DPADD= ${LIBKVM}
LDADD= -lkvm
diff --git a/sbin/devd/devd.conf.5 b/sbin/devd/devd.conf.5
index f7efefb..17c5e09 100644
--- a/sbin/devd/devd.conf.5
+++ b/sbin/devd/devd.conf.5
@@ -250,18 +250,40 @@ CIS-vendor.
Device class.
.It Li device
Device ID.
+.It Li devclass
+Device Class (USB)
+.It Li devsubclass
+Device Sub-class (USB)
.It Li device-name
Name of attached/detached device.
+.It Li endpoints
+Endpoint count (USB)
.It Li function
Card functions.
+.It Li interface
+Interface ID (USB)
+.It Li intclass
+Interface Class (USB)
+.It Li intprotocol
+Interface Protocol (USB)
+.It Li intsubclass
+Interface Sub-class (USB)
.It Li manufacturer
Manufacturer ID (pccard).
+.It Li mode
+Peripheral mode (USB)
.It Li notify
Match the value of the
.Dq Li notify
variable.
+.It Li parent
+Parent device
+.It Li port
+Hub port number (USB)
.It Li product
-Product ID (pccard).
+Product ID (pccard/USB).
+.It Li release
+Hardware revision (USB)
.It Li serial
Serial Number (USB).
.It Li slot
@@ -342,6 +364,27 @@ The
node is destroyed.
.El
.El
+.It Li USB
+Events related to the USB subsystem.
+.Bl -tag -width ".Sy Subsystem" -compact
+.It Sy Subsystem
+.It Li DEVICE
+.Bl -tag -width ".Li DETACH" -compact
+.It Sy Type
+.It Li ATTACH
+USB device is attached to the system.
+.It Li DETACH
+USB device is detached from the system.
+.El
+.It Li INTERFACE
+.Bl -tag -width ".Li DETACH" -compact
+.It Sy Type
+.It Li ATTACH
+USB interface is attached from a device.
+.It Li DETACH
+USB interface is detached from a device.
+.El
+.El
.It Li coretemp
Events related to the
.Xr coretemp 4
@@ -461,6 +504,17 @@ notify 0 {
};
#
+# Match a USB device type
+#
+notify 0 {
+ match "system" "USB";
+ match "subsystem" "INTERFACE";
+ match "type" "ATTACH";
+ match "intclass" "0x0e";
+ action "logger USB video device attached";
+};
+
+#
# Try to configure ath and wi devices with pccard_ether
# as they are attached.
#
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c
index e4b5995..38c05f6 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -238,7 +238,7 @@ dumpfs(const char *name)
if (fsflags & FS_UNCLEAN)
printf("unclean ");
if (fsflags & FS_DOSOFTDEP)
- printf("soft-updates ");
+ printf("soft-updates%s ", (fsflags & FS_SUJ) ? "+journal" : "");
if (fsflags & FS_NEEDSFSCK)
printf("needs fsck run ");
if (fsflags & FS_INDEXDIRS)
@@ -255,7 +255,7 @@ dumpfs(const char *name)
printf("nfsv4acls ");
fsflags &= ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS |
FS_ACLS | FS_MULTILABEL | FS_GJOURNAL | FS_FLAGS_UPDATED |
- FS_NFS4ACLS);
+ FS_NFS4ACLS | FS_SUJ);
if (fsflags != 0)
printf("unknown flags (%#x)", fsflags);
putchar('\n');
diff --git a/sbin/fsck_ffs/Makefile b/sbin/fsck_ffs/Makefile
index aaae685..db2930b 100644
--- a/sbin/fsck_ffs/Makefile
+++ b/sbin/fsck_ffs/Makefile
@@ -7,8 +7,7 @@ LINKS+= ${BINDIR}/fsck_ffs ${BINDIR}/fsck_4.2bsd
MAN= fsck_ffs.8
MLINKS= fsck_ffs.8 fsck_ufs.8 fsck_ffs.8 fsck_4.2bsd.8
SRCS= dir.c ea.c fsutil.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c \
- pass4.c pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c gjournal.c \
- getmntopts.c
+ pass4.c pass5.c setup.c suj.c utilities.c gjournal.c getmntopts.c
DPADD= ${LIBUFS}
LDADD= -lufs
WARNS?= 2
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index ad7fe13..08f9ef5 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -60,6 +60,9 @@
* $FreeBSD$
*/
+#ifndef _FSCK_H_
+#define _FSCK_H_
+
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
@@ -347,10 +350,6 @@ void direrror(ino_t ino, const char *errmesg);
int dirscan(struct inodesc *);
int dofix(struct inodesc *, const char *msg);
int eascan(struct inodesc *, struct ufs2_dinode *dp);
-void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
-void ffs_fragacct(struct fs *, int, int32_t [], int);
-int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
-void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
void fileerror(ino_t cwd, ino_t ino, const char *errmesg);
int findino(struct inodesc *);
int findname(struct inodesc *);
@@ -392,3 +391,6 @@ void sblock_init(void);
void setinodebuf(ino_t);
int setup(char *dev);
void gjournal_check(const char *filesys);
+int suj_check(const char *filesys);
+
+#endif /* !_FSCK_H_ */
diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c
index bd887ca..10c32c0 100644
--- a/sbin/fsck_ffs/gjournal.c
+++ b/sbin/fsck_ffs/gjournal.c
@@ -96,27 +96,6 @@ struct ufs2_dinode ufs2_zino;
static void putcgs(void);
/*
- * Write current block of inodes.
- */
-static int
-putino(struct uufsd *disk, ino_t inode)
-{
- caddr_t inoblock;
- struct fs *fs;
- ssize_t ret;
-
- fs = &disk->d_fs;
- inoblock = disk->d_inoblock;
-
- assert(inoblock != NULL);
- assert(inode >= disk->d_inomin && inode <= disk->d_inomax);
- ret = bwrite(disk, fsbtodb(fs, ino_to_fsba(fs, inode)), inoblock,
- fs->fs_bsize);
-
- return (ret == -1 ? -1 : 0);
-}
-
-/*
* Return cylinder group from the cache or load it if it is not in the
* cache yet.
* Don't cache more than MAX_CACHED_CGS cylinder groups.
@@ -242,13 +221,11 @@ cancelcgs(void)
#endif
/*
- * Open the given provider, load statistics.
+ * Open the given provider, load superblock.
*/
static void
-getdisk(void)
+opendisk(void)
{
- int i;
-
if (disk != NULL)
return;
disk = malloc(sizeof(*disk));
@@ -259,24 +236,6 @@ getdisk(void)
disk->d_error);
}
fs = &disk->d_fs;
- fs->fs_csp = malloc((size_t)fs->fs_cssize);
- if (fs->fs_csp == NULL)
- err(1, "malloc(%zu)", (size_t)fs->fs_cssize);
- bzero(fs->fs_csp, (size_t)fs->fs_cssize);
- for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize) {
- if (bread(disk, fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
- (void *)(((char *)fs->fs_csp) + i),
- (size_t)(fs->fs_cssize - i < fs->fs_bsize ? fs->fs_cssize - i : fs->fs_bsize)) == -1) {
- err(1, "bread: %s", disk->d_error);
- }
- }
- if (fs->fs_contigsumsize > 0) {
- fs->fs_maxcluster = malloc(fs->fs_ncg * sizeof(int32_t));
- if (fs->fs_maxcluster == NULL)
- err(1, "malloc(%zu)", fs->fs_ncg * sizeof(int32_t));
- for (i = 0; i < fs->fs_ncg; i++)
- fs->fs_maxcluster[i] = fs->fs_contigsumsize;
- }
}
/*
@@ -286,11 +245,6 @@ static void
closedisk(void)
{
- free(fs->fs_csp);
- if (fs->fs_contigsumsize > 0) {
- free(fs->fs_maxcluster);
- fs->fs_maxcluster = NULL;
- }
fs->fs_clean = 1;
if (sbwrite(disk, 0) == -1)
err(1, "sbwrite(%s)", devnam);
@@ -301,227 +255,6 @@ closedisk(void)
fs = NULL;
}
-/*
- * Write the statistics back, call closedisk().
- */
-static void
-putdisk(void)
-{
- int i;
-
- assert(disk != NULL && fs != NULL);
- for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize) {
- if (bwrite(disk, fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
- (void *)(((char *)fs->fs_csp) + i),
- (size_t)(fs->fs_cssize - i < fs->fs_bsize ? fs->fs_cssize - i : fs->fs_bsize)) == -1) {
- err(1, "bwrite: %s", disk->d_error);
- }
- }
- closedisk();
-}
-
-#if 0
-/*
- * Free memory, close the disk, but don't write anything back.
- */
-static void
-canceldisk(void)
-{
- int i;
-
- assert(disk != NULL && fs != NULL);
- free(fs->fs_csp);
- if (fs->fs_contigsumsize > 0)
- free(fs->fs_maxcluster);
- if (ufs_disk_close(disk) == -1)
- err(1, "ufs_disk_close(%s)", devnam);
- free(disk);
- disk = NULL;
- fs = NULL;
-}
-#endif
-
-static int
-isblock(unsigned char *cp, ufs1_daddr_t h)
-{
- unsigned char mask;
-
- switch ((int)fs->fs_frag) {
- case 8:
- return (cp[h] == 0xff);
- case 4:
- mask = 0x0f << ((h & 0x1) << 2);
- return ((cp[h >> 1] & mask) == mask);
- case 2:
- mask = 0x03 << ((h & 0x3) << 1);
- return ((cp[h >> 2] & mask) == mask);
- case 1:
- mask = 0x01 << (h & 0x7);
- return ((cp[h >> 3] & mask) == mask);
- default:
- assert(!"isblock: invalid number of fragments");
- }
- return (0);
-}
-
-/*
- * put a block into the map
- */
-static void
-setblock(unsigned char *cp, ufs1_daddr_t h)
-{
-
- switch ((int)fs->fs_frag) {
- case 8:
- cp[h] = 0xff;
- return;
- case 4:
- cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
- return;
- case 2:
- cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
- return;
- case 1:
- cp[h >> 3] |= (0x01 << (h & 0x7));
- return;
- default:
- assert(!"setblock: invalid number of fragments");
- }
-}
-
-/*
- * check if a block is free
- */
-static int
-isfreeblock(u_char *cp, ufs1_daddr_t h)
-{
-
- switch ((int)fs->fs_frag) {
- case 8:
- return (cp[h] == 0);
- case 4:
- return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
- case 2:
- return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
- case 1:
- return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
- default:
- assert(!"isfreeblock: invalid number of fragments");
- }
- return (0);
-}
-
-/*
- * Update the frsum fields to reflect addition or deletion
- * of some frags.
- */
-void
-fragacct(int fragmap, int32_t fraglist[], int cnt)
-{
- int inblk;
- int field, subfield;
- int siz, pos;
-
- inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
- fragmap <<= 1;
- for (siz = 1; siz < fs->fs_frag; siz++) {
- if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
- continue;
- field = around[siz];
- subfield = inside[siz];
- for (pos = siz; pos <= fs->fs_frag; pos++) {
- if ((fragmap & field) == subfield) {
- fraglist[siz] += cnt;
- pos += siz;
- field <<= siz;
- subfield <<= siz;
- }
- field <<= 1;
- subfield <<= 1;
- }
- }
-}
-
-static void
-clusteracct(struct cg *cgp, ufs1_daddr_t blkno)
-{
- int32_t *sump;
- int32_t *lp;
- u_char *freemapp, *mapp;
- int i, start, end, forw, back, map, bit;
-
- if (fs->fs_contigsumsize <= 0)
- return;
- freemapp = cg_clustersfree(cgp);
- sump = cg_clustersum(cgp);
- /*
- * Clear the actual block.
- */
- setbit(freemapp, blkno);
- /*
- * Find the size of the cluster going forward.
- */
- start = blkno + 1;
- end = start + fs->fs_contigsumsize;
- if (end >= cgp->cg_nclusterblks)
- end = cgp->cg_nclusterblks;
- mapp = &freemapp[start / NBBY];
- map = *mapp++;
- bit = 1 << (start % NBBY);
- for (i = start; i < end; i++) {
- if ((map & bit) == 0)
- break;
- if ((i & (NBBY - 1)) != (NBBY - 1)) {
- bit <<= 1;
- } else {
- map = *mapp++;
- bit = 1;
- }
- }
- forw = i - start;
- /*
- * Find the size of the cluster going backward.
- */
- start = blkno - 1;
- end = start - fs->fs_contigsumsize;
- if (end < 0)
- end = -1;
- mapp = &freemapp[start / NBBY];
- map = *mapp--;
- bit = 1 << (start % NBBY);
- for (i = start; i > end; i--) {
- if ((map & bit) == 0)
- break;
- if ((i & (NBBY - 1)) != 0) {
- bit >>= 1;
- } else {
- map = *mapp--;
- bit = 1 << (NBBY - 1);
- }
- }
- back = start - i;
- /*
- * Account for old cluster and the possibly new forward and
- * back clusters.
- */
- i = back + forw + 1;
- if (i > fs->fs_contigsumsize)
- i = fs->fs_contigsumsize;
- sump[i]++;
- if (back > 0)
- sump[back]--;
- if (forw > 0)
- sump[forw]--;
- /*
- * Update cluster summary information.
- */
- lp = &sump[fs->fs_contigsumsize];
- for (i = fs->fs_contigsumsize; i > 0; i--)
- if (*lp-- > 0)
- break;
- fs->fs_maxcluster[cgp->cg_cgx] = i;
-}
-
static void
blkfree(ufs2_daddr_t bno, long size)
{
@@ -539,10 +272,10 @@ blkfree(ufs2_daddr_t bno, long size)
blksfree = cg_blksfree(cgp);
if (size == fs->fs_bsize) {
fragno = fragstoblks(fs, cgbno);
- if (!isfreeblock(blksfree, fragno))
+ if (!ffs_isfreeblock(fs, blksfree, fragno))
assert(!"blkfree: freeing free block");
- setblock(blksfree, fragno);
- clusteracct(cgp, fragno);
+ ffs_setblock(fs, blksfree, fragno);
+ ffs_clusteracct(fs, cgp, fragno, 1);
cgp->cg_cs.cs_nbfree++;
fs->fs_cstotal.cs_nbfree++;
fs->fs_cs(fs, cg).cs_nbfree++;
@@ -552,7 +285,7 @@ blkfree(ufs2_daddr_t bno, long size)
* decrement the counts associated with the old frags
*/
blk = blkmap(fs, blksfree, bbase);
- fragacct(blk, cgp->cg_frsum, -1);
+ ffs_fragacct(fs, blk, cgp->cg_frsum, -1);
/*
* deallocate the fragment
*/
@@ -569,16 +302,16 @@ blkfree(ufs2_daddr_t bno, long size)
* add back in counts associated with the new frags
*/
blk = blkmap(fs, blksfree, bbase);
- fragacct(blk, cgp->cg_frsum, 1);
+ ffs_fragacct(fs, blk, cgp->cg_frsum, 1);
/*
* if a complete block has been reassembled, account for it
*/
fragno = fragstoblks(fs, bbase);
- if (isblock(blksfree, fragno)) {
+ if (ffs_isblock(fs, blksfree, fragno)) {
cgp->cg_cs.cs_nffree -= fs->fs_frag;
fs->fs_cstotal.cs_nffree -= fs->fs_frag;
fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag;
- clusteracct(cgp, fragno);
+ ffs_clusteracct(fs, cgp, fragno, 1);
cgp->cg_cs.cs_nbfree++;
fs->fs_cstotal.cs_nbfree++;
fs->fs_cs(fs, cg).cs_nbfree++;
@@ -599,7 +332,7 @@ freeindir(ufs2_daddr_t blk, int level)
if (bread(disk, fsbtodb(fs, blk), (void *)&sblks, (size_t)fs->fs_bsize) == -1)
err(1, "bread: %s", disk->d_error);
blks = (ufs2_daddr_t *)&sblks;
- for (i = 0; i < howmany(fs->fs_bsize, sizeof(ufs2_daddr_t)); i++) {
+ for (i = 0; i < NINDIR(fs); i++) {
if (blks[i] == 0)
break;
if (level == 0)
@@ -671,7 +404,7 @@ gjournal_check(const char *filesys)
int cg, mode;
devnam = filesys;
- getdisk();
+ opendisk();
/* Are there any unreferenced inodes in this file system? */
if (fs->fs_unrefs == 0) {
//printf("No unreferenced inodes.\n");
@@ -747,7 +480,7 @@ gjournal_check(const char *filesys)
/* Zero-fill the inode. */
*dino = ufs2_zino;
/* Write the inode back. */
- if (putino(disk, ino) == -1)
+ if (putino(disk) == -1)
err(1, "putino(cg=%d ino=%d)", cg, ino);
if (cgp->cg_unrefs == 0) {
//printf("No more unreferenced inodes in cg=%d.\n", cg);
@@ -772,5 +505,5 @@ gjournal_check(const char *filesys)
/* Write back modified cylinder groups. */
putcgs();
/* Write back updated statistics and super-block. */
- putdisk();
+ closedisk();
}
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index 66edd63..e9a9704 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -242,8 +242,9 @@ checkfilesys(char *filesys)
if ((fsreadfd = open(filesys, O_RDONLY)) < 0 || readsb(0) == 0)
exit(3); /* Cannot read superblock */
close(fsreadfd);
- if (sblock.fs_flags & FS_NEEDSFSCK)
- exit(4); /* Earlier background failed */
+ /* Earlier background failed or journaled */
+ if (sblock.fs_flags & (FS_NEEDSFSCK | FS_SUJ))
+ exit(4);
if ((sblock.fs_flags & FS_DOSOFTDEP) == 0)
exit(5); /* Not running soft updates */
size = MIBSIZE;
@@ -299,7 +300,7 @@ checkfilesys(char *filesys)
pfatal("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
} else if ((fsreadfd = open(filesys, O_RDONLY)) >= 0) {
if (readsb(0) != 0) {
- if (sblock.fs_flags & FS_NEEDSFSCK) {
+ if (sblock.fs_flags & (FS_NEEDSFSCK | FS_SUJ)) {
bkgrdflag = 0;
pfatal("UNEXPECTED INCONSISTENCY, %s\n",
"CANNOT RUN IN BACKGROUND\n");
@@ -384,6 +385,26 @@ checkfilesys(char *filesys)
sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize);
return (0);
}
+ /*
+ * Determine if we can and should do journal recovery.
+ */
+ if ((sblock.fs_flags & (FS_SUJ | FS_NEEDSFSCK)) == FS_SUJ) {
+ if (preen || reply("USE JOURNAL?")) {
+ if (suj_check(filesys) == 0) {
+ if (chkdoreload(mntp) == 0)
+ exit(0);
+ exit(4);
+ }
+ /* suj_check failed, fall through. */
+ }
+ printf("** Skipping journal, falling through to full fsck\n");
+ /*
+ * Write the superblock so we don't try to recover the
+ * journal on another pass.
+ */
+ sblock.fs_mtime = time(NULL);
+ sbdirty();
+ }
/*
* Cleared if any questions answered no. Used to decide if
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 173156e..639ce0f 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <inttypes.h>
#include <limits.h>
#include <string.h>
+#include <libufs.h>
#include "fsck.h"
diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c
new file mode 100644
index 0000000..f0240bd
--- /dev/null
+++ b/sbin/fsck_ffs/suj.c
@@ -0,0 +1,2634 @@
+/*-
+ * Copyright 2009, 2010 Jeffrey W. Roberson <jeff@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 AUTHORS 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 AUTHORS 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 <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <ufs/ufs/ufsmount.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <libufs.h>
+#include <string.h>
+#include <strings.h>
+#include <err.h>
+#include <assert.h>
+
+#include "fsck.h"
+
+#define DOTDOT_OFFSET DIRECTSIZ(1)
+#define SUJ_HASHSIZE 2048
+#define SUJ_HASHMASK (SUJ_HASHSIZE - 1)
+#define SUJ_HASH(x) ((x * 2654435761) & SUJ_HASHMASK)
+
+struct suj_seg {
+ TAILQ_ENTRY(suj_seg) ss_next;
+ struct jsegrec ss_rec;
+ uint8_t *ss_blk;
+};
+
+struct suj_rec {
+ TAILQ_ENTRY(suj_rec) sr_next;
+ union jrec *sr_rec;
+};
+TAILQ_HEAD(srechd, suj_rec);
+
+struct suj_ino {
+ LIST_ENTRY(suj_ino) si_next;
+ struct srechd si_recs;
+ struct srechd si_newrecs;
+ struct srechd si_movs;
+ struct jtrncrec *si_trunc;
+ ino_t si_ino;
+ char si_skipparent;
+ char si_hasrecs;
+ char si_blkadj;
+ char si_linkadj;
+ int si_mode;
+ nlink_t si_nlinkadj;
+ nlink_t si_nlink;
+ nlink_t si_dotlinks;
+};
+LIST_HEAD(inohd, suj_ino);
+
+struct suj_blk {
+ LIST_ENTRY(suj_blk) sb_next;
+ struct srechd sb_recs;
+ ufs2_daddr_t sb_blk;
+};
+LIST_HEAD(blkhd, suj_blk);
+
+struct data_blk {
+ LIST_ENTRY(data_blk) db_next;
+ uint8_t *db_buf;
+ ufs2_daddr_t db_blk;
+ int db_size;
+ int db_dirty;
+};
+
+struct ino_blk {
+ LIST_ENTRY(ino_blk) ib_next;
+ uint8_t *ib_buf;
+ int ib_dirty;
+ ufs2_daddr_t ib_blk;
+};
+LIST_HEAD(iblkhd, ino_blk);
+
+struct suj_cg {
+ LIST_ENTRY(suj_cg) sc_next;
+ struct blkhd sc_blkhash[SUJ_HASHSIZE];
+ struct inohd sc_inohash[SUJ_HASHSIZE];
+ struct iblkhd sc_iblkhash[SUJ_HASHSIZE];
+ struct ino_blk *sc_lastiblk;
+ struct suj_ino *sc_lastino;
+ struct suj_blk *sc_lastblk;
+ uint8_t *sc_cgbuf;
+ struct cg *sc_cgp;
+ int sc_dirty;
+ int sc_cgx;
+};
+
+LIST_HEAD(cghd, suj_cg) cghash[SUJ_HASHSIZE];
+LIST_HEAD(dblkhd, data_blk) dbhash[SUJ_HASHSIZE];
+struct suj_cg *lastcg;
+struct data_blk *lastblk;
+
+TAILQ_HEAD(seghd, suj_seg) allsegs;
+uint64_t oldseq;
+static struct uufsd *disk = NULL;
+static struct fs *fs = NULL;
+ino_t sujino;
+
+/*
+ * Summary statistics.
+ */
+uint64_t freefrags;
+uint64_t freeblocks;
+uint64_t freeinos;
+uint64_t freedir;
+uint64_t jbytes;
+uint64_t jrecs;
+
+typedef void (*ino_visitor)(ino_t, ufs_lbn_t, ufs2_daddr_t, int);
+static void ino_trunc(ino_t, off_t);
+static void ino_decr(ino_t);
+static void ino_adjust(struct suj_ino *);
+static void ino_build(struct suj_ino *);
+static int blk_isfree(ufs2_daddr_t);
+
+static void *
+errmalloc(size_t n)
+{
+ void *a;
+
+ a = malloc(n);
+ if (a == NULL)
+ errx(1, "malloc(%zu)", n);
+ return (a);
+}
+
+/*
+ * Open the given provider, load superblock.
+ */
+static void
+opendisk(const char *devnam)
+{
+ if (disk != NULL)
+ return;
+ disk = malloc(sizeof(*disk));
+ if (disk == NULL)
+ errx(1, "malloc(%zu)", sizeof(*disk));
+ if (ufs_disk_fillout(disk, devnam) == -1) {
+ err(1, "ufs_disk_fillout(%s) failed: %s", devnam,
+ disk->d_error);
+ }
+ fs = &disk->d_fs;
+}
+
+/*
+ * Mark file system as clean, write the super-block back, close the disk.
+ */
+static void
+closedisk(const char *devnam)
+{
+ struct csum *cgsum;
+ int i;
+
+ /*
+ * Recompute the fs summary info from correct cs summaries.
+ */
+ bzero(&fs->fs_cstotal, sizeof(struct csum_total));
+ for (i = 0; i < fs->fs_ncg; i++) {
+ cgsum = &fs->fs_cs(fs, i);
+ fs->fs_cstotal.cs_nffree += cgsum->cs_nffree;
+ fs->fs_cstotal.cs_nbfree += cgsum->cs_nbfree;
+ fs->fs_cstotal.cs_nifree += cgsum->cs_nifree;
+ fs->fs_cstotal.cs_ndir += cgsum->cs_ndir;
+ }
+ fs->fs_pendinginodes = 0;
+ fs->fs_pendingblocks = 0;
+ fs->fs_clean = 1;
+ fs->fs_time = time(NULL);
+ fs->fs_mtime = time(NULL);
+ if (sbwrite(disk, 0) == -1)
+ err(1, "sbwrite(%s)", devnam);
+ if (ufs_disk_close(disk) == -1)
+ err(1, "ufs_disk_close(%s)", devnam);
+ free(disk);
+ disk = NULL;
+ fs = NULL;
+}
+
+/*
+ * Lookup a cg by number in the hash so we can keep track of which cgs
+ * need stats rebuilt.
+ */
+static struct suj_cg *
+cg_lookup(int cgx)
+{
+ struct cghd *hd;
+ struct suj_cg *sc;
+
+ if (cgx < 0 || cgx >= fs->fs_ncg) {
+ abort();
+ errx(1, "Bad cg number %d", cgx);
+ }
+ if (lastcg && lastcg->sc_cgx == cgx)
+ return (lastcg);
+ hd = &cghash[SUJ_HASH(cgx)];
+ LIST_FOREACH(sc, hd, sc_next)
+ if (sc->sc_cgx == cgx) {
+ lastcg = sc;
+ return (sc);
+ }
+ sc = errmalloc(sizeof(*sc));
+ bzero(sc, sizeof(*sc));
+ sc->sc_cgbuf = errmalloc(fs->fs_bsize);
+ sc->sc_cgp = (struct cg *)sc->sc_cgbuf;
+ sc->sc_cgx = cgx;
+ LIST_INSERT_HEAD(hd, sc, sc_next);
+ if (bread(disk, fsbtodb(fs, cgtod(fs, sc->sc_cgx)), sc->sc_cgbuf,
+ fs->fs_bsize) == -1)
+ err(1, "Unable to read cylinder group %d", sc->sc_cgx);
+
+ return (sc);
+}
+
+/*
+ * Lookup an inode number in the hash and allocate a suj_ino if it does
+ * not exist.
+ */
+static struct suj_ino *
+ino_lookup(ino_t ino, int creat)
+{
+ struct suj_ino *sino;
+ struct inohd *hd;
+ struct suj_cg *sc;
+
+ sc = cg_lookup(ino_to_cg(fs, ino));
+ if (sc->sc_lastino && sc->sc_lastino->si_ino == ino)
+ return (sc->sc_lastino);
+ hd = &sc->sc_inohash[SUJ_HASH(ino)];
+ LIST_FOREACH(sino, hd, si_next)
+ if (sino->si_ino == ino)
+ return (sino);
+ if (creat == 0)
+ return (NULL);
+ sino = errmalloc(sizeof(*sino));
+ bzero(sino, sizeof(*sino));
+ sino->si_ino = ino;
+ TAILQ_INIT(&sino->si_recs);
+ TAILQ_INIT(&sino->si_newrecs);
+ TAILQ_INIT(&sino->si_movs);
+ LIST_INSERT_HEAD(hd, sino, si_next);
+
+ return (sino);
+}
+
+/*
+ * Lookup a block number in the hash and allocate a suj_blk if it does
+ * not exist.
+ */
+static struct suj_blk *
+blk_lookup(ufs2_daddr_t blk, int creat)
+{
+ struct suj_blk *sblk;
+ struct suj_cg *sc;
+ struct blkhd *hd;
+
+ sc = cg_lookup(dtog(fs, blk));
+ if (sc->sc_lastblk && sc->sc_lastblk->sb_blk == blk)
+ return (sc->sc_lastblk);
+ hd = &sc->sc_blkhash[SUJ_HASH(fragstoblks(fs, blk))];
+ LIST_FOREACH(sblk, hd, sb_next)
+ if (sblk->sb_blk == blk)
+ return (sblk);
+ if (creat == 0)
+ return (NULL);
+ sblk = errmalloc(sizeof(*sblk));
+ bzero(sblk, sizeof(*sblk));
+ sblk->sb_blk = blk;
+ TAILQ_INIT(&sblk->sb_recs);
+ LIST_INSERT_HEAD(hd, sblk, sb_next);
+
+ return (sblk);
+}
+
+static struct data_blk *
+dblk_lookup(ufs2_daddr_t blk)
+{
+ struct data_blk *dblk;
+ struct dblkhd *hd;
+
+ hd = &dbhash[SUJ_HASH(fragstoblks(fs, blk))];
+ if (lastblk && lastblk->db_blk == blk)
+ return (lastblk);
+ LIST_FOREACH(dblk, hd, db_next)
+ if (dblk->db_blk == blk)
+ return (dblk);
+ /*
+ * The inode block wasn't located, allocate a new one.
+ */
+ dblk = errmalloc(sizeof(*dblk));
+ bzero(dblk, sizeof(*dblk));
+ LIST_INSERT_HEAD(hd, dblk, db_next);
+ dblk->db_blk = blk;
+ return (dblk);
+}
+
+static uint8_t *
+dblk_read(ufs2_daddr_t blk, int size)
+{
+ struct data_blk *dblk;
+
+ dblk = dblk_lookup(blk);
+ /*
+ * I doubt size mismatches can happen in practice but it is trivial
+ * to handle.
+ */
+ if (size != dblk->db_size) {
+ if (dblk->db_buf)
+ free(dblk->db_buf);
+ dblk->db_buf = errmalloc(size);
+ dblk->db_size = size;
+ if (bread(disk, fsbtodb(fs, blk), dblk->db_buf, size) == -1)
+ err(1, "Failed to read data block %jd", blk);
+ }
+ return (dblk->db_buf);
+}
+
+static void
+dblk_dirty(ufs2_daddr_t blk)
+{
+ struct data_blk *dblk;
+
+ dblk = dblk_lookup(blk);
+ dblk->db_dirty = 1;
+}
+
+static void
+dblk_write(void)
+{
+ struct data_blk *dblk;
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++) {
+ LIST_FOREACH(dblk, &dbhash[i], db_next) {
+ if (dblk->db_dirty == 0 || dblk->db_size == 0)
+ continue;
+ if (bwrite(disk, fsbtodb(fs, dblk->db_blk),
+ dblk->db_buf, dblk->db_size) == -1)
+ err(1, "Unable to write block %jd",
+ dblk->db_blk);
+ }
+ }
+}
+
+static union dinode *
+ino_read(ino_t ino)
+{
+ struct ino_blk *iblk;
+ struct iblkhd *hd;
+ struct suj_cg *sc;
+ ufs2_daddr_t blk;
+ int off;
+
+ blk = ino_to_fsba(fs, ino);
+ sc = cg_lookup(ino_to_cg(fs, ino));
+ iblk = sc->sc_lastiblk;
+ if (iblk && iblk->ib_blk == blk)
+ goto found;
+ hd = &sc->sc_iblkhash[SUJ_HASH(fragstoblks(fs, blk))];
+ LIST_FOREACH(iblk, hd, ib_next)
+ if (iblk->ib_blk == blk)
+ goto found;
+ /*
+ * The inode block wasn't located, allocate a new one.
+ */
+ iblk = errmalloc(sizeof(*iblk));
+ bzero(iblk, sizeof(*iblk));
+ iblk->ib_buf = errmalloc(fs->fs_bsize);
+ iblk->ib_blk = blk;
+ LIST_INSERT_HEAD(hd, iblk, ib_next);
+ if (bread(disk, fsbtodb(fs, blk), iblk->ib_buf, fs->fs_bsize) == -1)
+ err(1, "Failed to read inode block %jd", blk);
+found:
+ sc->sc_lastiblk = iblk;
+ off = ino_to_fsbo(fs, ino);
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ return (union dinode *)&((struct ufs1_dinode *)iblk->ib_buf)[off];
+ else
+ return (union dinode *)&((struct ufs2_dinode *)iblk->ib_buf)[off];
+}
+
+static void
+ino_dirty(ino_t ino)
+{
+ struct ino_blk *iblk;
+ struct iblkhd *hd;
+ struct suj_cg *sc;
+ ufs2_daddr_t blk;
+
+ blk = ino_to_fsba(fs, ino);
+ sc = cg_lookup(ino_to_cg(fs, ino));
+ iblk = sc->sc_lastiblk;
+ if (iblk && iblk->ib_blk == blk) {
+ iblk->ib_dirty = 1;
+ return;
+ }
+ hd = &sc->sc_iblkhash[SUJ_HASH(fragstoblks(fs, blk))];
+ LIST_FOREACH(iblk, hd, ib_next) {
+ if (iblk->ib_blk == blk) {
+ iblk->ib_dirty = 1;
+ return;
+ }
+ }
+ ino_read(ino);
+ ino_dirty(ino);
+}
+
+static void
+iblk_write(struct ino_blk *iblk)
+{
+
+ if (iblk->ib_dirty == 0)
+ return;
+ if (bwrite(disk, fsbtodb(fs, iblk->ib_blk), iblk->ib_buf,
+ fs->fs_bsize) == -1)
+ err(1, "Failed to write inode block %jd", iblk->ib_blk);
+}
+
+static int
+blk_overlaps(struct jblkrec *brec, ufs2_daddr_t start, int frags)
+{
+ ufs2_daddr_t bstart;
+ ufs2_daddr_t bend;
+ ufs2_daddr_t end;
+
+ end = start + frags;
+ bstart = brec->jb_blkno + brec->jb_oldfrags;
+ bend = bstart + brec->jb_frags;
+ if (start < bend && end > bstart)
+ return (1);
+ return (0);
+}
+
+static int
+blk_equals(struct jblkrec *brec, ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t start,
+ int frags)
+{
+
+ if (brec->jb_ino != ino || brec->jb_lbn != lbn)
+ return (0);
+ if (brec->jb_blkno + brec->jb_oldfrags != start)
+ return (0);
+ if (brec->jb_frags != frags)
+ return (0);
+ return (1);
+}
+
+static void
+blk_setmask(struct jblkrec *brec, int *mask)
+{
+ int i;
+
+ for (i = brec->jb_oldfrags; i < brec->jb_oldfrags + brec->jb_frags; i++)
+ *mask |= 1 << i;
+}
+
+/*
+ * Determine whether a given block has been reallocated to a new location.
+ * Returns a mask of overlapping bits if any frags have been reused or
+ * zero if the block has not been re-used and the contents can be trusted.
+ *
+ * This is used to ensure that an orphaned pointer due to truncate is safe
+ * to be freed. The mask value can be used to free partial blocks.
+ */
+static int
+blk_freemask(ufs2_daddr_t blk, ino_t ino, ufs_lbn_t lbn, int frags)
+{
+ struct suj_blk *sblk;
+ struct suj_rec *srec;
+ struct jblkrec *brec;
+ int mask;
+ int off;
+
+ /*
+ * To be certain we're not freeing a reallocated block we lookup
+ * this block in the blk hash and see if there is an allocation
+ * journal record that overlaps with any fragments in the block
+ * we're concerned with. If any fragments have ben reallocated
+ * the block has already been freed and re-used for another purpose.
+ */
+ mask = 0;
+ sblk = blk_lookup(blknum(fs, blk), 0);
+ if (sblk == NULL)
+ return (0);
+ off = blk - sblk->sb_blk;
+ TAILQ_FOREACH(srec, &sblk->sb_recs, sr_next) {
+ brec = (struct jblkrec *)srec->sr_rec;
+ /*
+ * If the block overlaps but does not match
+ * exactly it's a new allocation. If it matches
+ * exactly this record refers to the current
+ * location.
+ */
+ if (blk_overlaps(brec, blk, frags) == 0)
+ continue;
+ if (blk_equals(brec, ino, lbn, blk, frags) == 1)
+ mask = 0;
+ else
+ blk_setmask(brec, &mask);
+ }
+ if (debug)
+ printf("blk_freemask: blk %jd sblk %jd off %d mask 0x%X\n",
+ blk, sblk->sb_blk, off, mask);
+ return (mask >> off);
+}
+
+/*
+ * Determine whether it is safe to follow an indirect. It is not safe
+ * if any part of the indirect has been reallocated or the last journal
+ * entry was an allocation. Just allocated indirects may not have valid
+ * pointers yet and all of their children will have their own records.
+ * It is also not safe to follow an indirect if the cg bitmap has been
+ * cleared as a new allocation may write to the block prior to the journal
+ * being written.
+ *
+ * Returns 1 if it's safe to follow the indirect and 0 otherwise.
+ */
+static int
+blk_isindir(ufs2_daddr_t blk, ino_t ino, ufs_lbn_t lbn)
+{
+ struct suj_blk *sblk;
+ struct jblkrec *brec;
+
+ sblk = blk_lookup(blk, 0);
+ if (sblk == NULL)
+ return (1);
+ if (TAILQ_EMPTY(&sblk->sb_recs))
+ return (1);
+ brec = (struct jblkrec *)TAILQ_LAST(&sblk->sb_recs, srechd)->sr_rec;
+ if (blk_equals(brec, ino, lbn, blk, fs->fs_frag))
+ if (brec->jb_op == JOP_FREEBLK)
+ return (!blk_isfree(blk));
+ return (0);
+}
+
+/*
+ * Clear an inode from the cg bitmap. If the inode was already clear return
+ * 0 so the caller knows it does not have to check the inode contents.
+ */
+static int
+ino_free(ino_t ino, int mode)
+{
+ struct suj_cg *sc;
+ uint8_t *inosused;
+ struct cg *cgp;
+ int cg;
+
+ cg = ino_to_cg(fs, ino);
+ ino = ino % fs->fs_ipg;
+ sc = cg_lookup(cg);
+ cgp = sc->sc_cgp;
+ inosused = cg_inosused(cgp);
+ /*
+ * The bitmap may never have made it to the disk so we have to
+ * conditionally clear. We can avoid writing the cg in this case.
+ */
+ if (isclr(inosused, ino))
+ return (0);
+ freeinos++;
+ clrbit(inosused, ino);
+ if (ino < cgp->cg_irotor)
+ cgp->cg_irotor = ino;
+ cgp->cg_cs.cs_nifree++;
+ if ((mode & IFMT) == IFDIR) {
+ freedir++;
+ cgp->cg_cs.cs_ndir--;
+ }
+ sc->sc_dirty = 1;
+
+ return (1);
+}
+
+/*
+ * Free 'frags' frags starting at filesystem block 'bno' skipping any frags
+ * set in the mask.
+ */
+static void
+blk_free(ufs2_daddr_t bno, int mask, int frags)
+{
+ ufs1_daddr_t fragno, cgbno;
+ struct suj_cg *sc;
+ struct cg *cgp;
+ int i, cg;
+ uint8_t *blksfree;
+
+ if (debug)
+ printf("Freeing %d frags at blk %jd\n", frags, bno);
+ cg = dtog(fs, bno);
+ sc = cg_lookup(cg);
+ cgp = sc->sc_cgp;
+ cgbno = dtogd(fs, bno);
+ blksfree = cg_blksfree(cgp);
+
+ /*
+ * If it's not allocated we only wrote the journal entry
+ * and never the bitmaps. Here we unconditionally clear and
+ * resolve the cg summary later.
+ */
+ if (frags == fs->fs_frag && mask == 0) {
+ fragno = fragstoblks(fs, cgbno);
+ ffs_setblock(fs, blksfree, fragno);
+ freeblocks++;
+ } else {
+ /*
+ * deallocate the fragment
+ */
+ for (i = 0; i < frags; i++)
+ if ((mask & (1 << i)) == 0 && isclr(blksfree, cgbno +i)) {
+ freefrags++;
+ setbit(blksfree, cgbno + i);
+ }
+ }
+ sc->sc_dirty = 1;
+}
+
+/*
+ * Returns 1 if the whole block starting at 'bno' is marked free and 0
+ * otherwise.
+ */
+static int
+blk_isfree(ufs2_daddr_t bno)
+{
+ struct suj_cg *sc;
+
+ sc = cg_lookup(dtog(fs, bno));
+ return ffs_isblock(fs, cg_blksfree(sc->sc_cgp), dtogd(fs, bno));
+}
+
+/*
+ * Fetch an indirect block to find the block at a given lbn. The lbn
+ * may be negative to fetch a specific indirect block pointer or positive
+ * to fetch a specific block.
+ */
+static ufs2_daddr_t
+indir_blkatoff(ufs2_daddr_t blk, ino_t ino, ufs_lbn_t cur, ufs_lbn_t lbn)
+{
+ ufs2_daddr_t *bap2;
+ ufs2_daddr_t *bap1;
+ ufs_lbn_t lbnadd;
+ ufs_lbn_t base;
+ int level;
+ int i;
+
+ if (blk == 0)
+ return (0);
+ level = lbn_level(cur);
+ if (level == -1)
+ errx(1, "Invalid indir lbn %jd", lbn);
+ if (level == 0 && lbn < 0)
+ errx(1, "Invalid lbn %jd", lbn);
+ bap2 = (void *)dblk_read(blk, fs->fs_bsize);
+ bap1 = (void *)bap2;
+ lbnadd = 1;
+ base = -(cur + level);
+ for (i = level; i > 0; i--)
+ lbnadd *= NINDIR(fs);
+ if (lbn > 0)
+ i = (lbn - base) / lbnadd;
+ else
+ i = (-lbn - base) / lbnadd;
+ if (i < 0 || i >= NINDIR(fs))
+ errx(1, "Invalid indirect index %d produced by lbn %jd",
+ i, lbn);
+ if (level == 0)
+ cur = base + (i * lbnadd);
+ else
+ cur = -(base + (i * lbnadd)) - (level - 1);
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ blk = bap1[i];
+ else
+ blk = bap2[i];
+ if (cur == lbn)
+ return (blk);
+ if (level == 0) {
+ abort();
+ errx(1, "Invalid lbn %jd at level 0", lbn);
+ }
+ return indir_blkatoff(blk, ino, cur, lbn);
+}
+
+/*
+ * Finds the disk block address at the specified lbn within the inode
+ * specified by ip. This follows the whole tree and honors di_size and
+ * di_extsize so it is a true test of reachability. The lbn may be
+ * negative if an extattr or indirect block is requested.
+ */
+static ufs2_daddr_t
+ino_blkatoff(union dinode *ip, ino_t ino, ufs_lbn_t lbn, int *frags)
+{
+ ufs_lbn_t tmpval;
+ ufs_lbn_t cur;
+ ufs_lbn_t next;
+ int i;
+
+ /*
+ * Handle extattr blocks first.
+ */
+ if (lbn < 0 && lbn >= -NXADDR) {
+ lbn = -1 - lbn;
+ if (lbn > lblkno(fs, ip->dp2.di_extsize - 1))
+ return (0);
+ *frags = numfrags(fs, sblksize(fs, ip->dp2.di_extsize, lbn));
+ return (ip->dp2.di_extb[lbn]);
+ }
+ /*
+ * Now direct and indirect.
+ */
+ if (DIP(ip, di_mode) == IFLNK &&
+ DIP(ip, di_size) < fs->fs_maxsymlinklen)
+ return (0);
+ if (lbn >= 0 && lbn < NDADDR) {
+ *frags = numfrags(fs, sblksize(fs, DIP(ip, di_size), lbn));
+ return (DIP(ip, di_db[lbn]));
+ }
+ *frags = fs->fs_frag;
+
+ for (i = 0, tmpval = NINDIR(fs), cur = NDADDR; i < NIADDR; i++,
+ tmpval *= NINDIR(fs), cur = next) {
+ next = cur + tmpval;
+ if (lbn == -cur - i)
+ return (DIP(ip, di_ib[i]));
+ /*
+ * Determine whether the lbn in question is within this tree.
+ */
+ if (lbn < 0 && -lbn >= next)
+ continue;
+ if (lbn > 0 && lbn >= next)
+ continue;
+ return indir_blkatoff(DIP(ip, di_ib[i]), ino, -cur - i, lbn);
+ }
+ errx(1, "lbn %jd not in ino", lbn);
+}
+
+/*
+ * Determine whether a block exists at a particular lbn in an inode.
+ * Returns 1 if found, 0 if not. lbn may be negative for indirects
+ * or ext blocks.
+ */
+static int
+blk_isat(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int *frags)
+{
+ union dinode *ip;
+ ufs2_daddr_t nblk;
+
+ ip = ino_read(ino);
+
+ if (DIP(ip, di_nlink) == 0 || DIP(ip, di_mode) == 0)
+ return (0);
+ nblk = ino_blkatoff(ip, ino, lbn, frags);
+
+ return (nblk == blk);
+}
+
+/*
+ * Determines whether a pointer to an inode exists within a directory
+ * at a specified offset. Returns the mode of the found entry.
+ */
+static int
+ino_isat(ino_t parent, off_t diroff, ino_t child, int *mode, int *isdot)
+{
+ union dinode *dip;
+ struct direct *dp;
+ ufs2_daddr_t blk;
+ uint8_t *block;
+ ufs_lbn_t lbn;
+ int blksize;
+ int frags;
+ int dpoff;
+ int doff;
+
+ *isdot = 0;
+ dip = ino_read(parent);
+ *mode = DIP(dip, di_mode);
+ if ((*mode & IFMT) != IFDIR) {
+ if (debug) {
+ /*
+ * This can happen if the parent inode
+ * was reallocated.
+ */
+ if (*mode != 0)
+ printf("Directory %d has bad mode %o\n",
+ parent, *mode);
+ else
+ printf("Directory %d zero inode\n", parent);
+ }
+ return (0);
+ }
+ lbn = lblkno(fs, diroff);
+ doff = blkoff(fs, diroff);
+ blksize = sblksize(fs, DIP(dip, di_size), lbn);
+ if (diroff + DIRECTSIZ(1) > DIP(dip, di_size) || doff >= blksize) {
+ if (debug)
+ printf("ino %d absent from %d due to offset %jd"
+ " exceeding size %jd\n",
+ child, parent, diroff, DIP(dip, di_size));
+ return (0);
+ }
+ blk = ino_blkatoff(dip, parent, lbn, &frags);
+ if (blk <= 0) {
+ if (debug)
+ printf("Sparse directory %d", parent);
+ return (0);
+ }
+ block = dblk_read(blk, blksize);
+ /*
+ * Walk through the records from the start of the block to be
+ * certain we hit a valid record and not some junk in the middle
+ * of a file name. Stop when we reach or pass the expected offset.
+ */
+ dpoff = (doff / DIRBLKSIZ) * DIRBLKSIZ;
+ do {
+ dp = (struct direct *)&block[dpoff];
+ if (dpoff == doff)
+ break;
+ if (dp->d_reclen == 0)
+ break;
+ dpoff += dp->d_reclen;
+ } while (dpoff <= doff);
+ if (dpoff > fs->fs_bsize)
+ errx(1, "Corrupt directory block in dir ino %d", parent);
+ /* Not found. */
+ if (dpoff != doff) {
+ if (debug)
+ printf("ino %d not found in %d, lbn %jd, dpoff %d\n",
+ child, parent, lbn, dpoff);
+ return (0);
+ }
+ /*
+ * We found the item in question. Record the mode and whether it's
+ * a . or .. link for the caller.
+ */
+ if (dp->d_ino == child) {
+ if (child == parent)
+ *isdot = 1;
+ else if (dp->d_namlen == 2 &&
+ dp->d_name[0] == '.' && dp->d_name[1] == '.')
+ *isdot = 1;
+ *mode = DTTOIF(dp->d_type);
+ return (1);
+ }
+ if (debug)
+ printf("ino %d doesn't match dirent ino %d in parent %d\n",
+ child, dp->d_ino, parent);
+ return (0);
+}
+
+#define VISIT_INDIR 0x0001
+#define VISIT_EXT 0x0002
+#define VISIT_ROOT 0x0004 /* Operation came via root & valid pointers. */
+
+/*
+ * Read an indirect level which may or may not be linked into an inode.
+ */
+static void
+indir_visit(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, uint64_t *frags,
+ ino_visitor visitor, int flags)
+{
+ ufs2_daddr_t *bap2;
+ ufs1_daddr_t *bap1;
+ ufs_lbn_t lbnadd;
+ ufs2_daddr_t nblk;
+ ufs_lbn_t nlbn;
+ int level;
+ int i;
+
+ /*
+ * Don't visit indirect blocks with contents we can't trust. This
+ * should only happen when indir_visit() is called to complete a
+ * truncate that never finished and not when a pointer is found via
+ * an inode.
+ */
+ if (blk == 0)
+ return;
+ level = lbn_level(lbn);
+ if (level == -1)
+ errx(1, "Invalid level for lbn %jd", lbn);
+ if ((flags & VISIT_ROOT) == 0 && blk_isindir(blk, ino, lbn) == 0) {
+ if (debug)
+ printf("blk %jd ino %d lbn %jd(%d) is not indir.\n",
+ blk, ino, lbn, level);
+ goto out;
+ }
+ lbnadd = 1;
+ for (i = level; i > 0; i--)
+ lbnadd *= NINDIR(fs);
+ bap1 = (void *)dblk_read(blk, fs->fs_bsize);
+ bap2 = (void *)bap1;
+ for (i = 0; i < NINDIR(fs); i++) {
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ nblk = *bap1++;
+ else
+ nblk = *bap2++;
+ if (nblk == 0)
+ continue;
+ if (level == 0) {
+ nlbn = -lbn + i * lbnadd;
+ (*frags) += fs->fs_frag;
+ visitor(ino, nlbn, nblk, fs->fs_frag);
+ } else {
+ nlbn = (lbn + 1) - (i * lbnadd);
+ indir_visit(ino, nlbn, nblk, frags, visitor, flags);
+ }
+ }
+out:
+ if (flags & VISIT_INDIR) {
+ (*frags) += fs->fs_frag;
+ visitor(ino, lbn, blk, fs->fs_frag);
+ }
+}
+
+/*
+ * Visit each block in an inode as specified by 'flags' and call a
+ * callback function. The callback may inspect or free blocks. The
+ * count of frags found according to the size in the file is returned.
+ * This is not valid for sparse files but may be used to determine
+ * the correct di_blocks for a file.
+ */
+static uint64_t
+ino_visit(union dinode *ip, ino_t ino, ino_visitor visitor, int flags)
+{
+ ufs_lbn_t nextlbn;
+ ufs_lbn_t tmpval;
+ ufs_lbn_t lbn;
+ uint64_t size;
+ uint64_t fragcnt;
+ int mode;
+ int frags;
+ int i;
+
+ size = DIP(ip, di_size);
+ mode = DIP(ip, di_mode) & IFMT;
+ fragcnt = 0;
+ if ((flags & VISIT_EXT) &&
+ fs->fs_magic == FS_UFS2_MAGIC && ip->dp2.di_extsize) {
+ for (i = 0; i < NXADDR; i++) {
+ if (ip->dp2.di_extb[i] == 0)
+ continue;
+ frags = sblksize(fs, ip->dp2.di_extsize, i);
+ frags = numfrags(fs, frags);
+ fragcnt += frags;
+ visitor(ino, -1 - i, ip->dp2.di_extb[i], frags);
+ }
+ }
+ /* Skip datablocks for short links and devices. */
+ if (mode == IFBLK || mode == IFCHR ||
+ (mode == IFLNK && size < fs->fs_maxsymlinklen))
+ return (fragcnt);
+ for (i = 0; i < NDADDR; i++) {
+ if (DIP(ip, di_db[i]) == 0)
+ continue;
+ frags = sblksize(fs, size, i);
+ frags = numfrags(fs, frags);
+ fragcnt += frags;
+ visitor(ino, i, DIP(ip, di_db[i]), frags);
+ }
+ /*
+ * We know the following indirects are real as we're following
+ * real pointers to them.
+ */
+ flags |= VISIT_ROOT;
+ for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR; i++,
+ lbn = nextlbn) {
+ nextlbn = lbn + tmpval;
+ tmpval *= NINDIR(fs);
+ if (DIP(ip, di_ib[i]) == 0)
+ continue;
+ indir_visit(ino, -lbn - i, DIP(ip, di_ib[i]), &fragcnt, visitor,
+ flags);
+ }
+ return (fragcnt);
+}
+
+/*
+ * Null visitor function used when we just want to count blocks and
+ * record the lbn.
+ */
+ufs_lbn_t visitlbn;
+static void
+null_visit(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
+{
+ if (lbn > 0)
+ visitlbn = lbn;
+}
+
+/*
+ * Recalculate di_blocks when we discover that a block allocation or
+ * free was not successfully completed. The kernel does not roll this back
+ * because it would be too expensive to compute which indirects were
+ * reachable at the time the inode was written.
+ */
+static void
+ino_adjblks(struct suj_ino *sino)
+{
+ union dinode *ip;
+ uint64_t blocks;
+ uint64_t frags;
+ off_t isize;
+ off_t size;
+ ino_t ino;
+
+ ino = sino->si_ino;
+ ip = ino_read(ino);
+ /* No need to adjust zero'd inodes. */
+ if (DIP(ip, di_mode) == 0)
+ return;
+ /*
+ * Visit all blocks and count them as well as recording the last
+ * valid lbn in the file. If the file size doesn't agree with the
+ * last lbn we need to truncate to fix it. Otherwise just adjust
+ * the blocks count.
+ */
+ visitlbn = 0;
+ frags = ino_visit(ip, ino, null_visit, VISIT_INDIR | VISIT_EXT);
+ blocks = fsbtodb(fs, frags);
+ /*
+ * We assume the size and direct block list is kept coherent by
+ * softdep. For files that have extended into indirects we truncate
+ * to the size in the inode or the maximum size permitted by
+ * populated indirects.
+ */
+ if (visitlbn >= NDADDR) {
+ isize = DIP(ip, di_size);
+ size = lblktosize(fs, visitlbn + 1);
+ if (isize > size)
+ isize = size;
+ /* Always truncate to free any unpopulated indirects. */
+ ino_trunc(sino->si_ino, isize);
+ return;
+ }
+ if (blocks == DIP(ip, di_blocks))
+ return;
+ if (debug)
+ printf("ino %d adjusting block count from %jd to %jd\n",
+ ino, DIP(ip, di_blocks), blocks);
+ DIP_SET(ip, di_blocks, blocks);
+ ino_dirty(ino);
+}
+
+static void
+blk_free_visit(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
+{
+ int mask;
+
+ mask = blk_freemask(blk, ino, lbn, frags);
+ if (debug)
+ printf("blk %jd freemask 0x%X\n", blk, mask);
+ blk_free(blk, mask, frags);
+}
+
+/*
+ * Free a block or tree of blocks that was previously rooted in ino at
+ * the given lbn. If the lbn is an indirect all children are freed
+ * recursively.
+ */
+static void
+blk_free_lbn(ufs2_daddr_t blk, ino_t ino, ufs_lbn_t lbn, int frags, int follow)
+{
+ uint64_t resid;
+ int mask;
+
+ mask = blk_freemask(blk, ino, lbn, frags);
+ if (debug)
+ printf("blk %jd freemask 0x%X\n", blk, mask);
+ resid = 0;
+ if (lbn <= -NDADDR && follow && mask == 0)
+ indir_visit(ino, lbn, blk, &resid, blk_free_visit, VISIT_INDIR);
+ else
+ blk_free(blk, mask, frags);
+}
+
+static void
+ino_setskip(struct suj_ino *sino, ino_t parent)
+{
+ int isdot;
+ int mode;
+
+ if (ino_isat(sino->si_ino, DOTDOT_OFFSET, parent, &mode, &isdot))
+ sino->si_skipparent = 1;
+}
+
+/*
+ * Free the children of a directory when the directory is discarded.
+ */
+static void
+ino_free_children(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
+{
+ struct suj_ino *sino;
+ struct suj_rec *srec;
+ struct jrefrec *rrec;
+ struct direct *dp;
+ off_t diroff;
+ uint8_t *block;
+ int skipparent;
+ int isparent;
+ int dpoff;
+ int size;
+
+ sino = ino_lookup(ino, 0);
+ if (sino)
+ skipparent = sino->si_skipparent;
+ else
+ skipparent = 0;
+ size = lfragtosize(fs, frags);
+ block = dblk_read(blk, size);
+ dp = (struct direct *)&block[0];
+ for (dpoff = 0; dpoff < size && dp->d_reclen; dpoff += dp->d_reclen) {
+ dp = (struct direct *)&block[dpoff];
+ if (dp->d_ino == 0 || dp->d_ino == WINO)
+ continue;
+ if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+ continue;
+ isparent = dp->d_namlen == 2 && dp->d_name[0] == '.' &&
+ dp->d_name[1] == '.';
+ if (isparent && skipparent == 1)
+ continue;
+ if (debug)
+ printf("Directory %d removing ino %d name %s\n",
+ ino, dp->d_ino, dp->d_name);
+ /*
+ * Lookup this inode to see if we have a record for it.
+ * If not, we've already adjusted it assuming this path
+ * was valid and we have to adjust once more.
+ */
+ sino = ino_lookup(dp->d_ino, 0);
+ if (sino == NULL || sino->si_hasrecs == 0) {
+ ino_decr(ino);
+ continue;
+ }
+ /*
+ * Use ino_adjust() so if we lose the last non-dot reference
+ * to a directory it can be discarded.
+ */
+ if (sino->si_linkadj) {
+ sino->si_nlink--;
+ if (isparent)
+ sino->si_dotlinks--;
+ ino_adjust(sino);
+ }
+ /*
+ * Tell any child directories we've already removed their
+ * parent. Don't try to adjust our link down again.
+ */
+ if (isparent == 0)
+ ino_setskip(sino, ino);
+ /*
+ * If we haven't yet processed this inode we need to make
+ * sure we will successfully discover the lost path. If not
+ * use nlinkadj to remember.
+ */
+ diroff = lblktosize(fs, lbn) + dpoff;
+ TAILQ_FOREACH(srec, &sino->si_recs, sr_next) {
+ rrec = (struct jrefrec *)srec->sr_rec;
+ if (rrec->jr_parent == ino &&
+ rrec->jr_diroff == diroff)
+ break;
+ }
+ if (srec == NULL)
+ sino->si_nlinkadj++;
+ }
+}
+
+/*
+ * Reclaim an inode, freeing all blocks and decrementing all children's
+ * link counts. Free the inode back to the cg.
+ */
+static void
+ino_reclaim(union dinode *ip, ino_t ino, int mode)
+{
+ uint32_t gen;
+
+ if (ino == ROOTINO)
+ errx(1, "Attempting to free ROOTINO");
+ if (debug)
+ printf("Truncating and freeing ino %d, nlink %d, mode %o\n",
+ ino, DIP(ip, di_nlink), DIP(ip, di_mode));
+
+ /* We are freeing an inode or directory. */
+ if ((DIP(ip, di_mode) & IFMT) == IFDIR)
+ ino_visit(ip, ino, ino_free_children, 0);
+ DIP_SET(ip, di_nlink, 0);
+ ino_visit(ip, ino, blk_free_visit, VISIT_EXT | VISIT_INDIR);
+ /* Here we have to clear the inode and release any blocks it holds. */
+ gen = DIP(ip, di_gen);
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ bzero(ip, sizeof(struct ufs1_dinode));
+ else
+ bzero(ip, sizeof(struct ufs2_dinode));
+ DIP_SET(ip, di_gen, gen);
+ ino_dirty(ino);
+ ino_free(ino, mode);
+ return;
+}
+
+/*
+ * Adjust an inode's link count down by one when a directory goes away.
+ */
+static void
+ino_decr(ino_t ino)
+{
+ union dinode *ip;
+ int reqlink;
+ int nlink;
+ int mode;
+
+ ip = ino_read(ino);
+ nlink = DIP(ip, di_nlink);
+ mode = DIP(ip, di_mode);
+ if (nlink < 1)
+ errx(1, "Inode %d link count %d invalid", ino, nlink);
+ if (mode == 0)
+ errx(1, "Inode %d has a link of %d with 0 mode.", ino, nlink);
+ nlink--;
+ if ((mode & IFMT) == IFDIR)
+ reqlink = 2;
+ else
+ reqlink = 1;
+ if (nlink < reqlink) {
+ if (debug)
+ printf("ino %d not enough links to live %d < %d\n",
+ ino, nlink, reqlink);
+ ino_reclaim(ip, ino, mode);
+ return;
+ }
+ DIP_SET(ip, di_nlink, nlink);
+ ino_dirty(ino);
+}
+
+/*
+ * Adjust the inode link count to 'nlink'. If the count reaches zero
+ * free it.
+ */
+static void
+ino_adjust(struct suj_ino *sino)
+{
+ struct jrefrec *rrec;
+ struct suj_rec *srec;
+ struct suj_ino *stmp;
+ union dinode *ip;
+ nlink_t nlink;
+ int reqlink;
+ int mode;
+ ino_t ino;
+
+ nlink = sino->si_nlink;
+ ino = sino->si_ino;
+ /*
+ * If it's a directory with no real names pointing to it go ahead
+ * and truncate it. This will free any children.
+ */
+ if ((sino->si_mode & IFMT) == IFDIR &&
+ nlink - sino->si_dotlinks == 0) {
+ sino->si_nlink = nlink = 0;
+ /*
+ * Mark any .. links so they know not to free this inode
+ * when they are removed.
+ */
+ TAILQ_FOREACH(srec, &sino->si_recs, sr_next) {
+ rrec = (struct jrefrec *)srec->sr_rec;
+ if (rrec->jr_diroff == DOTDOT_OFFSET) {
+ stmp = ino_lookup(rrec->jr_parent, 0);
+ if (stmp)
+ ino_setskip(stmp, ino);
+ }
+ }
+ }
+ ip = ino_read(ino);
+ mode = DIP(ip, di_mode) & IFMT;
+ if (nlink > LINK_MAX)
+ errx(1,
+ "ino %d nlink manipulation error, new link %d, old link %d",
+ ino, nlink, DIP(ip, di_nlink));
+ if (debug)
+ printf("Adjusting ino %d, nlink %d, old link %d lastmode %o\n",
+ ino, nlink, DIP(ip, di_nlink), sino->si_mode);
+ if (mode == 0) {
+ if (debug)
+ printf("ino %d, zero inode freeing bitmap\n", ino);
+ ino_free(ino, sino->si_mode);
+ return;
+ }
+ /* XXX Should be an assert? */
+ if (mode != sino->si_mode && debug)
+ printf("ino %d, mode %o != %o\n", ino, mode, sino->si_mode);
+ if ((mode & IFMT) == IFDIR)
+ reqlink = 2;
+ else
+ reqlink = 1;
+ /* If the inode doesn't have enough links to live, free it. */
+ if (nlink < reqlink) {
+ if (debug)
+ printf("ino %d not enough links to live %d < %d\n",
+ ino, nlink, reqlink);
+ ino_reclaim(ip, ino, mode);
+ return;
+ }
+ /* If required write the updated link count. */
+ if (DIP(ip, di_nlink) == nlink) {
+ if (debug)
+ printf("ino %d, link matches, skipping.\n", ino);
+ return;
+ }
+ DIP_SET(ip, di_nlink, nlink);
+ ino_dirty(ino);
+}
+
+/*
+ * Truncate some or all blocks in an indirect, freeing any that are required
+ * and zeroing the indirect.
+ */
+static void
+indir_trunc(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, ufs_lbn_t lastlbn)
+{
+ ufs2_daddr_t *bap2;
+ ufs1_daddr_t *bap1;
+ ufs_lbn_t lbnadd;
+ ufs2_daddr_t nblk;
+ ufs_lbn_t next;
+ ufs_lbn_t nlbn;
+ int dirty;
+ int level;
+ int i;
+
+ if (blk == 0)
+ return;
+ dirty = 0;
+ level = lbn_level(lbn);
+ if (level == -1)
+ errx(1, "Invalid level for lbn %jd", lbn);
+ lbnadd = 1;
+ for (i = level; i > 0; i--)
+ lbnadd *= NINDIR(fs);
+ bap1 = (void *)dblk_read(blk, fs->fs_bsize);
+ bap2 = (void *)bap1;
+ for (i = 0; i < NINDIR(fs); i++) {
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ nblk = *bap1++;
+ else
+ nblk = *bap2++;
+ if (nblk == 0)
+ continue;
+ if (level != 0) {
+ nlbn = (lbn + 1) - (i * lbnadd);
+ /*
+ * Calculate the lbn of the next indirect to
+ * determine if any of this indirect must be
+ * reclaimed.
+ */
+ next = -(lbn + level) + ((i+1) * lbnadd);
+ if (next <= lastlbn)
+ continue;
+ indir_trunc(ino, nlbn, nblk, lastlbn);
+ /* If all of this indirect was reclaimed, free it. */
+ nlbn = next - lbnadd;
+ if (nlbn < lastlbn)
+ continue;
+ } else {
+ nlbn = -lbn + i * lbnadd;
+ if (nlbn < lastlbn)
+ continue;
+ }
+ dirty = 1;
+ blk_free(nblk, 0, fs->fs_frag);
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ *(bap1 - 1) = 0;
+ else
+ *(bap2 - 1) = 0;
+ }
+ if (dirty)
+ dblk_dirty(blk);
+}
+
+/*
+ * Truncate an inode to the minimum of the given size or the last populated
+ * block after any over size have been discarded. The kernel would allocate
+ * the last block in the file but fsck does not and neither do we. This
+ * code never extends files, only shrinks them.
+ */
+static void
+ino_trunc(ino_t ino, off_t size)
+{
+ union dinode *ip;
+ ufs2_daddr_t bn;
+ uint64_t totalfrags;
+ ufs_lbn_t nextlbn;
+ ufs_lbn_t lastlbn;
+ ufs_lbn_t tmpval;
+ ufs_lbn_t lbn;
+ ufs_lbn_t i;
+ int frags;
+ off_t cursize;
+ off_t off;
+ int mode;
+
+ ip = ino_read(ino);
+ mode = DIP(ip, di_mode) & IFMT;
+ cursize = DIP(ip, di_size);
+ if (debug)
+ printf("Truncating ino %d, mode %o to size %jd from size %jd\n",
+ ino, mode, size, cursize);
+
+ /* Skip datablocks for short links and devices. */
+ if (mode == 0 || mode == IFBLK || mode == IFCHR ||
+ (mode == IFLNK && cursize < fs->fs_maxsymlinklen))
+ return;
+ /* Don't extend. */
+ if (size > cursize)
+ size = cursize;
+ lastlbn = lblkno(fs, blkroundup(fs, size));
+ for (i = lastlbn; i < NDADDR; i++) {
+ if (DIP(ip, di_db[i]) == 0)
+ continue;
+ frags = sblksize(fs, cursize, i);
+ frags = numfrags(fs, frags);
+ blk_free(DIP(ip, di_db[i]), 0, frags);
+ DIP_SET(ip, di_db[i], 0);
+ }
+ /*
+ * Follow indirect blocks, freeing anything required.
+ */
+ for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR; i++,
+ lbn = nextlbn) {
+ nextlbn = lbn + tmpval;
+ tmpval *= NINDIR(fs);
+ /* If we're not freeing any in this indirect range skip it. */
+ if (lastlbn >= nextlbn)
+ continue;
+ if (DIP(ip, di_ib[i]) == 0)
+ continue;
+ indir_trunc(ino, -lbn - i, DIP(ip, di_ib[i]), lastlbn);
+ /* If we freed everything in this indirect free the indir. */
+ if (lastlbn > lbn)
+ continue;
+ blk_free(DIP(ip, di_ib[i]), 0, frags);
+ DIP_SET(ip, di_ib[i], 0);
+ }
+ ino_dirty(ino);
+ /*
+ * Now that we've freed any whole blocks that exceed the desired
+ * truncation size, figure out how many blocks remain and what the
+ * last populated lbn is. We will set the size to this last lbn
+ * rather than worrying about allocating the final lbn as the kernel
+ * would've done. This is consistent with normal fsck behavior.
+ */
+ visitlbn = 0;
+ totalfrags = ino_visit(ip, ino, null_visit, VISIT_INDIR | VISIT_EXT);
+ if (size > lblktosize(fs, visitlbn + 1))
+ size = lblktosize(fs, visitlbn + 1);
+ /*
+ * If we're truncating direct blocks we have to adjust frags
+ * accordingly.
+ */
+ if (visitlbn < NDADDR && totalfrags) {
+ long oldspace, newspace;
+
+ bn = DIP(ip, di_db[visitlbn]);
+ if (bn == 0)
+ errx(1, "Bad blk at ino %d lbn %jd\n", ino, visitlbn);
+ oldspace = sblksize(fs, cursize, visitlbn);
+ newspace = sblksize(fs, size, visitlbn);
+ if (oldspace != newspace) {
+ bn += numfrags(fs, newspace);
+ frags = numfrags(fs, oldspace - newspace);
+ blk_free(bn, 0, frags);
+ totalfrags -= frags;
+ }
+ }
+ DIP_SET(ip, di_blocks, fsbtodb(fs, totalfrags));
+ DIP_SET(ip, di_size, size);
+ /*
+ * If we've truncated into the middle of a block or frag we have
+ * to zero it here. Otherwise the file could extend into
+ * uninitialized space later.
+ */
+ off = blkoff(fs, size);
+ if (off) {
+ uint8_t *buf;
+ long clrsize;
+
+ bn = ino_blkatoff(ip, ino, visitlbn, &frags);
+ if (bn == 0)
+ errx(1, "Block missing from ino %d at lbn %jd\n",
+ ino, visitlbn);
+ clrsize = frags * fs->fs_fsize;
+ buf = dblk_read(bn, clrsize);
+ clrsize -= off;
+ buf += off;
+ bzero(buf, clrsize);
+ dblk_dirty(bn);
+ }
+ return;
+}
+
+/*
+ * Process records available for one inode and determine whether the
+ * link count is correct or needs adjusting.
+ */
+static void
+ino_check(struct suj_ino *sino)
+{
+ struct suj_rec *srec;
+ struct jrefrec *rrec;
+ nlink_t dotlinks;
+ int newlinks;
+ int removes;
+ int nlink;
+ ino_t ino;
+ int isdot;
+ int isat;
+ int mode;
+
+ if (sino->si_hasrecs == 0)
+ return;
+ ino = sino->si_ino;
+ rrec = (struct jrefrec *)TAILQ_FIRST(&sino->si_recs)->sr_rec;
+ nlink = rrec->jr_nlink;
+ newlinks = 0;
+ dotlinks = 0;
+ removes = sino->si_nlinkadj;
+ TAILQ_FOREACH(srec, &sino->si_recs, sr_next) {
+ rrec = (struct jrefrec *)srec->sr_rec;
+ isat = ino_isat(rrec->jr_parent, rrec->jr_diroff,
+ rrec->jr_ino, &mode, &isdot);
+ if (isat && (mode & IFMT) != (rrec->jr_mode & IFMT))
+ errx(1, "Inode mode/directory type mismatch %o != %o",
+ mode, rrec->jr_mode);
+ if (debug)
+ printf("jrefrec: op %d ino %d, nlink %d, parent %d, "
+ "diroff %jd, mode %o, isat %d, isdot %d\n",
+ rrec->jr_op, rrec->jr_ino, rrec->jr_nlink,
+ rrec->jr_parent, rrec->jr_diroff, rrec->jr_mode,
+ isat, isdot);
+ mode = rrec->jr_mode & IFMT;
+ if (rrec->jr_op == JOP_REMREF)
+ removes++;
+ newlinks += isat;
+ if (isdot)
+ dotlinks += isat;
+ }
+ /*
+ * The number of links that remain are the starting link count
+ * subtracted by the total number of removes with the total
+ * links discovered back in. An incomplete remove thus
+ * makes no change to the link count but an add increases
+ * by one.
+ */
+ if (debug)
+ printf("ino %d nlink %d newlinks %d removes %d dotlinks %d\n",
+ ino, nlink, newlinks, removes, dotlinks);
+ nlink += newlinks;
+ nlink -= removes;
+ sino->si_linkadj = 1;
+ sino->si_nlink = nlink;
+ sino->si_dotlinks = dotlinks;
+ sino->si_mode = mode;
+ ino_adjust(sino);
+}
+
+/*
+ * Process records available for one block and determine whether it is
+ * still allocated and whether the owning inode needs to be updated or
+ * a free completed.
+ */
+static void
+blk_check(struct suj_blk *sblk)
+{
+ struct suj_rec *srec;
+ struct jblkrec *brec;
+ struct suj_ino *sino;
+ ufs2_daddr_t blk;
+ int mask;
+ int frags;
+ int isat;
+
+ /*
+ * Each suj_blk actually contains records for any fragments in that
+ * block. As a result we must evaluate each record individually.
+ */
+ sino = NULL;
+ TAILQ_FOREACH(srec, &sblk->sb_recs, sr_next) {
+ brec = (struct jblkrec *)srec->sr_rec;
+ frags = brec->jb_frags;
+ blk = brec->jb_blkno + brec->jb_oldfrags;
+ isat = blk_isat(brec->jb_ino, brec->jb_lbn, blk, &frags);
+ if (sino == NULL || sino->si_ino != brec->jb_ino) {
+ sino = ino_lookup(brec->jb_ino, 1);
+ sino->si_blkadj = 1;
+ }
+ if (debug)
+ printf("op %d blk %jd ino %d lbn %jd frags %d isat %d (%d)\n",
+ brec->jb_op, blk, brec->jb_ino, brec->jb_lbn,
+ brec->jb_frags, isat, frags);
+ /*
+ * If we found the block at this address we still have to
+ * determine if we need to free the tail end that was
+ * added by adding contiguous fragments from the same block.
+ */
+ if (isat == 1) {
+ if (frags == brec->jb_frags)
+ continue;
+ mask = blk_freemask(blk, brec->jb_ino, brec->jb_lbn,
+ brec->jb_frags);
+ mask >>= frags;
+ blk += frags;
+ frags = brec->jb_frags - frags;
+ blk_free(blk, mask, frags);
+ continue;
+ }
+ /*
+ * The block wasn't found, attempt to free it. It won't be
+ * freed if it was actually reallocated. If this was an
+ * allocation we don't want to follow indirects as they
+ * may not be written yet. Any children of the indirect will
+ * have their own records. If it's a free we need to
+ * recursively free children.
+ */
+ blk_free_lbn(blk, brec->jb_ino, brec->jb_lbn, brec->jb_frags,
+ brec->jb_op == JOP_FREEBLK);
+ }
+}
+
+/*
+ * Walk the list of inode records for this cg and resolve moved and duplicate
+ * inode references now that we have a complete picture.
+ */
+static void
+cg_build(struct suj_cg *sc)
+{
+ struct suj_ino *sino;
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(sino, &sc->sc_inohash[i], si_next)
+ ino_build(sino);
+}
+
+/*
+ * Handle inodes requiring truncation. This must be done prior to
+ * looking up any inodes in directories.
+ */
+static void
+cg_trunc(struct suj_cg *sc)
+{
+ struct suj_ino *sino;
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(sino, &sc->sc_inohash[i], si_next)
+ if (sino->si_trunc) {
+ ino_trunc(sino->si_ino,
+ sino->si_trunc->jt_size);
+ sino->si_trunc = NULL;
+ }
+}
+
+/*
+ * Free any partially allocated blocks and then resolve inode block
+ * counts.
+ */
+static void
+cg_check_blk(struct suj_cg *sc)
+{
+ struct suj_ino *sino;
+ struct suj_blk *sblk;
+ int i;
+
+
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(sblk, &sc->sc_blkhash[i], sb_next)
+ blk_check(sblk);
+ /*
+ * Now that we've freed blocks which are not referenced we
+ * make a second pass over all inodes to adjust their block
+ * counts.
+ */
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(sino, &sc->sc_inohash[i], si_next)
+ if (sino->si_blkadj)
+ ino_adjblks(sino);
+}
+
+/*
+ * Walk the list of inode records for this cg, recovering any
+ * changes which were not complete at the time of crash.
+ */
+static void
+cg_check_ino(struct suj_cg *sc)
+{
+ struct suj_ino *sino;
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(sino, &sc->sc_inohash[i], si_next)
+ ino_check(sino);
+}
+
+/*
+ * Write a potentially dirty cg. Recalculate the summary information and
+ * update the superblock summary.
+ */
+static void
+cg_write(struct suj_cg *sc)
+{
+ ufs1_daddr_t fragno, cgbno, maxbno;
+ u_int8_t *blksfree;
+ struct cg *cgp;
+ int blk;
+ int i;
+
+ if (sc->sc_dirty == 0)
+ return;
+ /*
+ * Fix the frag and cluster summary.
+ */
+ cgp = sc->sc_cgp;
+ cgp->cg_cs.cs_nbfree = 0;
+ cgp->cg_cs.cs_nffree = 0;
+ bzero(&cgp->cg_frsum, sizeof(cgp->cg_frsum));
+ maxbno = fragstoblks(fs, fs->fs_fpg);
+ if (fs->fs_contigsumsize > 0) {
+ for (i = 1; i <= fs->fs_contigsumsize; i++)
+ cg_clustersum(cgp)[i] = 0;
+ bzero(cg_clustersfree(cgp), howmany(maxbno, CHAR_BIT));
+ }
+ blksfree = cg_blksfree(cgp);
+ for (cgbno = 0; cgbno < maxbno; cgbno++) {
+ if (ffs_isfreeblock(fs, blksfree, cgbno))
+ continue;
+ if (ffs_isblock(fs, blksfree, cgbno)) {
+ ffs_clusteracct(fs, cgp, cgbno, 1);
+ cgp->cg_cs.cs_nbfree++;
+ continue;
+ }
+ fragno = blkstofrags(fs, cgbno);
+ blk = blkmap(fs, blksfree, fragno);
+ ffs_fragacct(fs, blk, cgp->cg_frsum, 1);
+ for (i = 0; i < fs->fs_frag; i++)
+ if (isset(blksfree, fragno + i))
+ cgp->cg_cs.cs_nffree++;
+ }
+ /*
+ * Update the superblock cg summary from our now correct values
+ * before writing the block.
+ */
+ fs->fs_cs(fs, sc->sc_cgx) = cgp->cg_cs;
+ if (bwrite(disk, fsbtodb(fs, cgtod(fs, sc->sc_cgx)), sc->sc_cgbuf,
+ fs->fs_bsize) == -1)
+ err(1, "Unable to write cylinder group %d", sc->sc_cgx);
+}
+
+/*
+ * Write out any modified inodes.
+ */
+static void
+cg_write_inos(struct suj_cg *sc)
+{
+ struct ino_blk *iblk;
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(iblk, &sc->sc_iblkhash[i], ib_next)
+ if (iblk->ib_dirty)
+ iblk_write(iblk);
+}
+
+static void
+cg_apply(void (*apply)(struct suj_cg *))
+{
+ struct suj_cg *scg;
+ int i;
+
+ for (i = 0; i < SUJ_HASHSIZE; i++)
+ LIST_FOREACH(scg, &cghash[i], sc_next)
+ apply(scg);
+}
+
+/*
+ * Process the unlinked but referenced file list. Freeing all inodes.
+ */
+static void
+ino_unlinked(void)
+{
+ union dinode *ip;
+ uint16_t mode;
+ ino_t inon;
+ ino_t ino;
+
+ ino = fs->fs_sujfree;
+ fs->fs_sujfree = 0;
+ while (ino != 0) {
+ ip = ino_read(ino);
+ mode = DIP(ip, di_mode) & IFMT;
+ inon = DIP(ip, di_freelink);
+ DIP_SET(ip, di_freelink, 0);
+ /*
+ * XXX Should this be an errx?
+ */
+ if (DIP(ip, di_nlink) == 0) {
+ if (debug)
+ printf("Freeing unlinked ino %d mode %o\n",
+ ino, mode);
+ ino_reclaim(ip, ino, mode);
+ } else if (debug)
+ printf("Skipping ino %d mode %o with link %d\n",
+ ino, mode, DIP(ip, di_nlink));
+ ino = inon;
+ }
+}
+
+/*
+ * Append a new record to the list of records requiring processing.
+ */
+static void
+ino_append(union jrec *rec)
+{
+ struct jrefrec *refrec;
+ struct jmvrec *mvrec;
+ struct suj_ino *sino;
+ struct suj_rec *srec;
+
+ mvrec = &rec->rec_jmvrec;
+ refrec = &rec->rec_jrefrec;
+ if (debug && mvrec->jm_op == JOP_MVREF)
+ printf("ino move: ino %d, parent %d, diroff %jd, oldoff %jd\n",
+ mvrec->jm_ino, mvrec->jm_parent, mvrec->jm_newoff,
+ mvrec->jm_oldoff);
+ else if (debug &&
+ (refrec->jr_op == JOP_ADDREF || refrec->jr_op == JOP_REMREF))
+ printf("ino ref: op %d, ino %d, nlink %d, "
+ "parent %d, diroff %jd\n",
+ refrec->jr_op, refrec->jr_ino, refrec->jr_nlink,
+ refrec->jr_parent, refrec->jr_diroff);
+ /*
+ * Lookup the ino and clear truncate if one is found. Partial
+ * truncates are always done synchronously so if we discover
+ * an operation that requires a lock the truncation has completed
+ * and can be discarded.
+ */
+ sino = ino_lookup(((struct jrefrec *)rec)->jr_ino, 1);
+ sino->si_trunc = NULL;
+ sino->si_hasrecs = 1;
+ srec = errmalloc(sizeof(*srec));
+ srec->sr_rec = rec;
+ TAILQ_INSERT_TAIL(&sino->si_newrecs, srec, sr_next);
+}
+
+/*
+ * Add a reference adjustment to the sino list and eliminate dups. The
+ * primary loop in ino_build_ref() checks for dups but new ones may be
+ * created as a result of offset adjustments.
+ */
+static void
+ino_add_ref(struct suj_ino *sino, struct suj_rec *srec)
+{
+ struct jrefrec *refrec;
+ struct suj_rec *srn;
+ struct jrefrec *rrn;
+
+ refrec = (struct jrefrec *)srec->sr_rec;
+ /*
+ * We walk backwards so that the oldest link count is preserved. If
+ * an add record conflicts with a remove keep the remove. Redundant
+ * removes are eliminated in ino_build_ref. Otherwise we keep the
+ * oldest record at a given location.
+ */
+ for (srn = TAILQ_LAST(&sino->si_recs, srechd); srn;
+ srn = TAILQ_PREV(srn, srechd, sr_next)) {
+ rrn = (struct jrefrec *)srn->sr_rec;
+ if (rrn->jr_parent != refrec->jr_parent ||
+ rrn->jr_diroff != refrec->jr_diroff)
+ continue;
+ if (rrn->jr_op == JOP_REMREF || refrec->jr_op == JOP_ADDREF) {
+ rrn->jr_mode = refrec->jr_mode;
+ return;
+ }
+ /*
+ * Adding a remove.
+ *
+ * Replace the record in place with the old nlink in case
+ * we replace the head of the list. Abandon srec as a dup.
+ */
+ refrec->jr_nlink = rrn->jr_nlink;
+ srn->sr_rec = srec->sr_rec;
+ return;
+ }
+ TAILQ_INSERT_TAIL(&sino->si_recs, srec, sr_next);
+}
+
+/*
+ * Create a duplicate of a reference at a previous location.
+ */
+static void
+ino_dup_ref(struct suj_ino *sino, struct jrefrec *refrec, off_t diroff)
+{
+ struct jrefrec *rrn;
+ struct suj_rec *srn;
+
+ rrn = errmalloc(sizeof(*refrec));
+ *rrn = *refrec;
+ rrn->jr_op = JOP_ADDREF;
+ rrn->jr_diroff = diroff;
+ srn = errmalloc(sizeof(*srn));
+ srn->sr_rec = (union jrec *)rrn;
+ ino_add_ref(sino, srn);
+}
+
+/*
+ * Add a reference to the list at all known locations. We follow the offset
+ * changes for a single instance and create duplicate add refs at each so
+ * that we can tolerate any version of the directory block. Eliminate
+ * removes which collide with adds that are seen in the journal. They should
+ * not adjust the link count down.
+ */
+static void
+ino_build_ref(struct suj_ino *sino, struct suj_rec *srec)
+{
+ struct jrefrec *refrec;
+ struct jmvrec *mvrec;
+ struct suj_rec *srp;
+ struct suj_rec *srn;
+ struct jrefrec *rrn;
+ off_t diroff;
+
+ refrec = (struct jrefrec *)srec->sr_rec;
+ /*
+ * Search for a mvrec that matches this offset. Whether it's an add
+ * or a remove we can delete the mvref after creating a dup record in
+ * the old location.
+ */
+ if (!TAILQ_EMPTY(&sino->si_movs)) {
+ diroff = refrec->jr_diroff;
+ for (srn = TAILQ_LAST(&sino->si_movs, srechd); srn; srn = srp) {
+ srp = TAILQ_PREV(srn, srechd, sr_next);
+ mvrec = (struct jmvrec *)srn->sr_rec;
+ if (mvrec->jm_parent != refrec->jr_parent ||
+ mvrec->jm_newoff != diroff)
+ continue;
+ diroff = mvrec->jm_oldoff;
+ TAILQ_REMOVE(&sino->si_movs, srn, sr_next);
+ ino_dup_ref(sino, refrec, diroff);
+ }
+ }
+ /*
+ * If a remove wasn't eliminated by an earlier add just append it to
+ * the list.
+ */
+ if (refrec->jr_op == JOP_REMREF) {
+ ino_add_ref(sino, srec);
+ return;
+ }
+ /*
+ * Walk the list of records waiting to be added to the list. We
+ * must check for moves that apply to our current offset and remove
+ * them from the list. Remove any duplicates to eliminate removes
+ * with corresponding adds.
+ */
+ TAILQ_FOREACH_SAFE(srn, &sino->si_newrecs, sr_next, srp) {
+ switch (srn->sr_rec->rec_jrefrec.jr_op) {
+ case JOP_ADDREF:
+ /*
+ * This should actually be an error we should
+ * have a remove for every add journaled.
+ */
+ rrn = (struct jrefrec *)srn->sr_rec;
+ if (rrn->jr_parent != refrec->jr_parent ||
+ rrn->jr_diroff != refrec->jr_diroff)
+ break;
+ TAILQ_REMOVE(&sino->si_newrecs, srn, sr_next);
+ break;
+ case JOP_REMREF:
+ /*
+ * Once we remove the current iteration of the
+ * record at this address we're done.
+ */
+ rrn = (struct jrefrec *)srn->sr_rec;
+ if (rrn->jr_parent != refrec->jr_parent ||
+ rrn->jr_diroff != refrec->jr_diroff)
+ break;
+ TAILQ_REMOVE(&sino->si_newrecs, srn, sr_next);
+ ino_add_ref(sino, srec);
+ return;
+ case JOP_MVREF:
+ /*
+ * Update our diroff based on any moves that match
+ * and remove the move.
+ */
+ mvrec = (struct jmvrec *)srn->sr_rec;
+ if (mvrec->jm_parent != refrec->jr_parent ||
+ mvrec->jm_oldoff != refrec->jr_diroff)
+ break;
+ ino_dup_ref(sino, refrec, mvrec->jm_oldoff);
+ refrec->jr_diroff = mvrec->jm_newoff;
+ TAILQ_REMOVE(&sino->si_newrecs, srn, sr_next);
+ break;
+ default:
+ errx(1, "ino_build_ref: Unknown op %d",
+ srn->sr_rec->rec_jrefrec.jr_op);
+ }
+ }
+ ino_add_ref(sino, srec);
+}
+
+/*
+ * Walk the list of new records and add them in-order resolving any
+ * dups and adjusted offsets.
+ */
+static void
+ino_build(struct suj_ino *sino)
+{
+ struct suj_rec *srec;
+
+ while ((srec = TAILQ_FIRST(&sino->si_newrecs)) != NULL) {
+ TAILQ_REMOVE(&sino->si_newrecs, srec, sr_next);
+ switch (srec->sr_rec->rec_jrefrec.jr_op) {
+ case JOP_ADDREF:
+ case JOP_REMREF:
+ ino_build_ref(sino, srec);
+ break;
+ case JOP_MVREF:
+ /*
+ * Add this mvrec to the queue of pending mvs.
+ */
+ TAILQ_INSERT_TAIL(&sino->si_movs, srec, sr_next);
+ break;
+ default:
+ errx(1, "ino_build: Unknown op %d",
+ srec->sr_rec->rec_jrefrec.jr_op);
+ }
+ }
+ if (TAILQ_EMPTY(&sino->si_recs))
+ sino->si_hasrecs = 0;
+}
+
+/*
+ * Modify journal records so they refer to the base block number
+ * and a start and end frag range. This is to facilitate the discovery
+ * of overlapping fragment allocations.
+ */
+static void
+blk_build(struct jblkrec *blkrec)
+{
+ struct suj_rec *srec;
+ struct suj_blk *sblk;
+ struct jblkrec *blkrn;
+ struct suj_ino *sino;
+ ufs2_daddr_t blk;
+ off_t foff;
+ int frag;
+
+ if (debug)
+ printf("blk_build: op %d blkno %jd frags %d oldfrags %d "
+ "ino %d lbn %jd\n",
+ blkrec->jb_op, blkrec->jb_blkno, blkrec->jb_frags,
+ blkrec->jb_oldfrags, blkrec->jb_ino, blkrec->jb_lbn);
+
+ /*
+ * Look up the inode and clear the truncate if any lbns after the
+ * truncate lbn are freed or allocated.
+ */
+ sino = ino_lookup(blkrec->jb_ino, 0);
+ if (sino && sino->si_trunc) {
+ foff = lblktosize(fs, blkrec->jb_lbn);
+ foff += lfragtosize(fs, blkrec->jb_frags);
+ if (foff > sino->si_trunc->jt_size)
+ sino->si_trunc = NULL;
+ }
+ blk = blknum(fs, blkrec->jb_blkno);
+ frag = fragnum(fs, blkrec->jb_blkno);
+ sblk = blk_lookup(blk, 1);
+ /*
+ * Rewrite the record using oldfrags to indicate the offset into
+ * the block. Leave jb_frags as the actual allocated count.
+ */
+ blkrec->jb_blkno -= frag;
+ blkrec->jb_oldfrags = frag;
+ if (blkrec->jb_oldfrags + blkrec->jb_frags > fs->fs_frag)
+ errx(1, "Invalid fragment count %d oldfrags %d",
+ blkrec->jb_frags, frag);
+ /*
+ * Detect dups. If we detect a dup we always discard the oldest
+ * record as it is superseded by the new record. This speeds up
+ * later stages but also eliminates free records which are used
+ * to indicate that the contents of indirects can be trusted.
+ */
+ TAILQ_FOREACH(srec, &sblk->sb_recs, sr_next) {
+ blkrn = (struct jblkrec *)srec->sr_rec;
+ if (blkrn->jb_ino != blkrec->jb_ino ||
+ blkrn->jb_lbn != blkrec->jb_lbn ||
+ blkrn->jb_blkno != blkrec->jb_blkno ||
+ blkrn->jb_frags != blkrec->jb_frags ||
+ blkrn->jb_oldfrags != blkrec->jb_oldfrags)
+ continue;
+ if (debug)
+ printf("Removed dup.\n");
+ /* Discard the free which is a dup with an alloc. */
+ if (blkrec->jb_op == JOP_FREEBLK)
+ return;
+ TAILQ_REMOVE(&sblk->sb_recs, srec, sr_next);
+ free(srec);
+ break;
+ }
+ srec = errmalloc(sizeof(*srec));
+ srec->sr_rec = (union jrec *)blkrec;
+ TAILQ_INSERT_TAIL(&sblk->sb_recs, srec, sr_next);
+}
+
+static void
+ino_build_trunc(struct jtrncrec *rec)
+{
+ struct suj_ino *sino;
+
+ if (debug)
+ printf("ino_build_trunc: ino %d, size %jd\n",
+ rec->jt_ino, rec->jt_size);
+ sino = ino_lookup(rec->jt_ino, 1);
+ sino->si_trunc = rec;
+}
+
+/*
+ * Build up tables of the operations we need to recover.
+ */
+static void
+suj_build(void)
+{
+ struct suj_seg *seg;
+ union jrec *rec;
+ int off;
+ int i;
+
+ TAILQ_FOREACH(seg, &allsegs, ss_next) {
+ if (debug)
+ printf("seg %jd has %d records, oldseq %jd.\n",
+ seg->ss_rec.jsr_seq, seg->ss_rec.jsr_cnt,
+ seg->ss_rec.jsr_oldest);
+ off = 0;
+ rec = (union jrec *)seg->ss_blk;
+ for (i = 0; i < seg->ss_rec.jsr_cnt; off += JREC_SIZE, rec++) {
+ /* skip the segrec. */
+ if ((off % DEV_BSIZE) == 0)
+ continue;
+ switch (rec->rec_jrefrec.jr_op) {
+ case JOP_ADDREF:
+ case JOP_REMREF:
+ case JOP_MVREF:
+ ino_append(rec);
+ break;
+ case JOP_NEWBLK:
+ case JOP_FREEBLK:
+ blk_build((struct jblkrec *)rec);
+ break;
+ case JOP_TRUNC:
+ ino_build_trunc((struct jtrncrec *)rec);
+ break;
+ default:
+ errx(1, "Unknown journal operation %d (%d)",
+ rec->rec_jrefrec.jr_op, off);
+ }
+ i++;
+ }
+ }
+}
+
+/*
+ * Prune the journal segments to those we care about based on the
+ * oldest sequence in the newest segment. Order the segment list
+ * based on sequence number.
+ */
+static void
+suj_prune(void)
+{
+ struct suj_seg *seg;
+ struct suj_seg *segn;
+ uint64_t newseq;
+ int discard;
+
+ if (debug)
+ printf("Pruning up to %jd\n", oldseq);
+ /* First free the expired segments. */
+ TAILQ_FOREACH_SAFE(seg, &allsegs, ss_next, segn) {
+ if (seg->ss_rec.jsr_seq >= oldseq)
+ continue;
+ TAILQ_REMOVE(&allsegs, seg, ss_next);
+ free(seg->ss_blk);
+ free(seg);
+ }
+ /* Next ensure that segments are ordered properly. */
+ seg = TAILQ_FIRST(&allsegs);
+ if (seg == NULL) {
+ if (debug)
+ printf("Empty journal\n");
+ return;
+ }
+ newseq = seg->ss_rec.jsr_seq;
+ for (;;) {
+ seg = TAILQ_LAST(&allsegs, seghd);
+ if (seg->ss_rec.jsr_seq >= newseq)
+ break;
+ TAILQ_REMOVE(&allsegs, seg, ss_next);
+ TAILQ_INSERT_HEAD(&allsegs, seg, ss_next);
+ newseq = seg->ss_rec.jsr_seq;
+
+ }
+ if (newseq != oldseq)
+ errx(1, "Journal file sequence mismatch %jd != %jd",
+ newseq, oldseq);
+ /*
+ * The kernel may asynchronously write segments which can create
+ * gaps in the sequence space. Throw away any segments after the
+ * gap as the kernel guarantees only those that are contiguously
+ * reachable are marked as completed.
+ */
+ discard = 0;
+ TAILQ_FOREACH_SAFE(seg, &allsegs, ss_next, segn) {
+ if (!discard && newseq++ == seg->ss_rec.jsr_seq) {
+ jrecs += seg->ss_rec.jsr_cnt;
+ jbytes += seg->ss_rec.jsr_blocks * DEV_BSIZE;
+ continue;
+ }
+ discard = 1;
+ if (debug)
+ printf("Journal order mismatch %jd != %jd pruning\n",
+ newseq-1, seg->ss_rec.jsr_seq);
+ TAILQ_REMOVE(&allsegs, seg, ss_next);
+ free(seg->ss_blk);
+ free(seg);
+ }
+ if (debug)
+ printf("Processing journal segments from %jd to %jd\n",
+ oldseq, newseq-1);
+}
+
+/*
+ * Verify the journal inode before attempting to read records.
+ */
+static int
+suj_verifyino(union dinode *ip)
+{
+
+ if (DIP(ip, di_nlink) != 1) {
+ printf("Invalid link count %d for journal inode %d\n",
+ DIP(ip, di_nlink), sujino);
+ return (-1);
+ }
+
+ if ((DIP(ip, di_flags) & (SF_IMMUTABLE | SF_NOUNLINK)) !=
+ (SF_IMMUTABLE | SF_NOUNLINK)) {
+ printf("Invalid flags 0x%X for journal inode %d\n",
+ DIP(ip, di_flags), sujino);
+ return (-1);
+ }
+
+ if (DIP(ip, di_mode) != (IFREG | IREAD)) {
+ printf("Invalid mode %o for journal inode %d\n",
+ DIP(ip, di_mode), sujino);
+ return (-1);
+ }
+
+ if (DIP(ip, di_size) < SUJ_MIN || DIP(ip, di_size) > SUJ_MAX) {
+ printf("Invalid size %jd for journal inode %d\n",
+ DIP(ip, di_size), sujino);
+ return (-1);
+ }
+
+ if (DIP(ip, di_modrev) != fs->fs_mtime) {
+ printf("Journal timestamp does not match fs mount time\n");
+ return (-1);
+ }
+
+ return (0);
+}
+
+struct jblocks {
+ struct jextent *jb_extent; /* Extent array. */
+ int jb_avail; /* Available extents. */
+ int jb_used; /* Last used extent. */
+ int jb_head; /* Allocator head. */
+ int jb_off; /* Allocator extent offset. */
+};
+struct jextent {
+ ufs2_daddr_t je_daddr; /* Disk block address. */
+ int je_blocks; /* Disk block count. */
+};
+
+struct jblocks *suj_jblocks;
+
+static struct jblocks *
+jblocks_create(void)
+{
+ struct jblocks *jblocks;
+ int size;
+
+ jblocks = errmalloc(sizeof(*jblocks));
+ jblocks->jb_avail = 10;
+ jblocks->jb_used = 0;
+ jblocks->jb_head = 0;
+ jblocks->jb_off = 0;
+ size = sizeof(struct jextent) * jblocks->jb_avail;
+ jblocks->jb_extent = errmalloc(size);
+ bzero(jblocks->jb_extent, size);
+
+ return (jblocks);
+}
+
+/*
+ * Return the next available disk block and the amount of contiguous
+ * free space it contains.
+ */
+static ufs2_daddr_t
+jblocks_next(struct jblocks *jblocks, int bytes, int *actual)
+{
+ struct jextent *jext;
+ ufs2_daddr_t daddr;
+ int freecnt;
+ int blocks;
+
+ blocks = bytes / DEV_BSIZE;
+ jext = &jblocks->jb_extent[jblocks->jb_head];
+ freecnt = jext->je_blocks - jblocks->jb_off;
+ if (freecnt == 0) {
+ jblocks->jb_off = 0;
+ if (++jblocks->jb_head > jblocks->jb_used)
+ return (0);
+ jext = &jblocks->jb_extent[jblocks->jb_head];
+ freecnt = jext->je_blocks;
+ }
+ if (freecnt > blocks)
+ freecnt = blocks;
+ *actual = freecnt * DEV_BSIZE;
+ daddr = jext->je_daddr + jblocks->jb_off;
+
+ return (daddr);
+}
+
+/*
+ * Advance the allocation head by a specified number of bytes, consuming
+ * one journal segment.
+ */
+static void
+jblocks_advance(struct jblocks *jblocks, int bytes)
+{
+
+ jblocks->jb_off += bytes / DEV_BSIZE;
+}
+
+static void
+jblocks_destroy(struct jblocks *jblocks)
+{
+
+ free(jblocks->jb_extent);
+ free(jblocks);
+}
+
+static void
+jblocks_add(struct jblocks *jblocks, ufs2_daddr_t daddr, int blocks)
+{
+ struct jextent *jext;
+ int size;
+
+ jext = &jblocks->jb_extent[jblocks->jb_used];
+ /* Adding the first block. */
+ if (jext->je_daddr == 0) {
+ jext->je_daddr = daddr;
+ jext->je_blocks = blocks;
+ return;
+ }
+ /* Extending the last extent. */
+ if (jext->je_daddr + jext->je_blocks == daddr) {
+ jext->je_blocks += blocks;
+ return;
+ }
+ /* Adding a new extent. */
+ if (++jblocks->jb_used == jblocks->jb_avail) {
+ jblocks->jb_avail *= 2;
+ size = sizeof(struct jextent) * jblocks->jb_avail;
+ jext = errmalloc(size);
+ bzero(jext, size);
+ bcopy(jblocks->jb_extent, jext,
+ sizeof(struct jextent) * jblocks->jb_used);
+ free(jblocks->jb_extent);
+ jblocks->jb_extent = jext;
+ }
+ jext = &jblocks->jb_extent[jblocks->jb_used];
+ jext->je_daddr = daddr;
+ jext->je_blocks = blocks;
+
+ return;
+}
+
+/*
+ * Add a file block from the journal to the extent map. We can't read
+ * each file block individually because the kernel treats it as a circular
+ * buffer and segments may span mutliple contiguous blocks.
+ */
+static void
+suj_add_block(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
+{
+
+ jblocks_add(suj_jblocks, fsbtodb(fs, blk), fsbtodb(fs, frags));
+}
+
+static void
+suj_read(void)
+{
+ uint8_t block[1 * 1024 * 1024];
+ struct suj_seg *seg;
+ struct jsegrec *recn;
+ struct jsegrec *rec;
+ ufs2_daddr_t blk;
+ int readsize;
+ int blocks;
+ int recsize;
+ int size;
+ int i;
+
+ /*
+ * Read records until we exhaust the journal space. If we find
+ * an invalid record we start searching for a valid segment header
+ * at the next block. This is because we don't have a head/tail
+ * pointer and must recover the information indirectly. At the gap
+ * between the head and tail we won't necessarily have a valid
+ * segment.
+ */
+restart:
+ for (;;) {
+ size = sizeof(block);
+ blk = jblocks_next(suj_jblocks, size, &readsize);
+ if (blk == 0)
+ return;
+ size = readsize;
+ /*
+ * Read 1MB at a time and scan for records within this block.
+ */
+ if (bread(disk, blk, &block, size) == -1)
+ err(1, "Error reading journal block %jd",
+ (intmax_t)blk);
+ for (rec = (void *)block; size; size -= recsize,
+ rec = (struct jsegrec *)((uintptr_t)rec + recsize)) {
+ recsize = DEV_BSIZE;
+ if (rec->jsr_time != fs->fs_mtime) {
+ if (debug)
+ printf("Rec time %jd != fs mtime %jd\n",
+ rec->jsr_time, fs->fs_mtime);
+ jblocks_advance(suj_jblocks, recsize);
+ continue;
+ }
+ if (rec->jsr_cnt == 0) {
+ if (debug)
+ printf("Found illegal count %d\n",
+ rec->jsr_cnt);
+ jblocks_advance(suj_jblocks, recsize);
+ continue;
+ }
+ blocks = rec->jsr_blocks;
+ recsize = blocks * DEV_BSIZE;
+ if (recsize > size) {
+ /*
+ * We may just have run out of buffer, restart
+ * the loop to re-read from this spot.
+ */
+ if (size < fs->fs_bsize &&
+ size != readsize &&
+ recsize <= fs->fs_bsize)
+ goto restart;
+ if (debug)
+ printf("Found invalid segsize %d > %d\n",
+ recsize, size);
+ recsize = DEV_BSIZE;
+ jblocks_advance(suj_jblocks, recsize);
+ continue;
+ }
+ /*
+ * Verify that all blocks in the segment are present.
+ */
+ for (i = 1; i < blocks; i++) {
+ recn = (void *)
+ ((uintptr_t)rec) + i * DEV_BSIZE;
+ if (recn->jsr_seq == rec->jsr_seq &&
+ recn->jsr_time == rec->jsr_time)
+ continue;
+ if (debug)
+ printf("Incomplete record %jd (%d)\n",
+ rec->jsr_seq, i);
+ recsize = i * DEV_BSIZE;
+ jblocks_advance(suj_jblocks, recsize);
+ goto restart;
+ }
+ seg = errmalloc(sizeof(*seg));
+ seg->ss_blk = errmalloc(recsize);
+ seg->ss_rec = *rec;
+ bcopy((void *)rec, seg->ss_blk, recsize);
+ if (rec->jsr_oldest > oldseq)
+ oldseq = rec->jsr_oldest;
+ TAILQ_INSERT_TAIL(&allsegs, seg, ss_next);
+ jblocks_advance(suj_jblocks, recsize);
+ }
+ }
+}
+
+/*
+ * Search a directory block for the SUJ_FILE.
+ */
+static void
+suj_find(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
+{
+ char block[MAXBSIZE];
+ struct direct *dp;
+ int bytes;
+ int off;
+
+ if (sujino)
+ return;
+ bytes = lfragtosize(fs, frags);
+ if (bread(disk, fsbtodb(fs, blk), block, bytes) <= 0)
+ err(1, "Failed to read ROOTINO directory block %jd", blk);
+ for (off = 0; off < bytes; off += dp->d_reclen) {
+ dp = (struct direct *)&block[off];
+ if (dp->d_reclen == 0)
+ break;
+ if (dp->d_ino == 0)
+ continue;
+ if (dp->d_namlen != strlen(SUJ_FILE))
+ continue;
+ if (bcmp(dp->d_name, SUJ_FILE, dp->d_namlen) != 0)
+ continue;
+ sujino = dp->d_ino;
+ return;
+ }
+}
+
+/*
+ * Orchestrate the verification of a filesystem via the softupdates journal.
+ */
+int
+suj_check(const char *filesys)
+{
+ union dinode *jip;
+ union dinode *ip;
+ uint64_t blocks;
+
+ opendisk(filesys);
+ TAILQ_INIT(&allsegs);
+ /*
+ * Find the journal inode.
+ */
+ ip = ino_read(ROOTINO);
+ sujino = 0;
+ ino_visit(ip, ROOTINO, suj_find, 0);
+ if (sujino == 0)
+ errx(1, "Journal inode removed. Use tunefs to re-create.");
+ /*
+ * Fetch the journal inode and verify it.
+ */
+ jip = ino_read(sujino);
+ printf("** SU+J Recovering %s\n", filesys);
+ if (suj_verifyino(jip) != 0)
+ return (-1);
+ /*
+ * Build a list of journal blocks in jblocks before parsing the
+ * available journal blocks in with suj_read().
+ */
+ printf("** Reading %jd byte journal from inode %d.\n",
+ DIP(jip, di_size), sujino);
+ suj_jblocks = jblocks_create();
+ blocks = ino_visit(jip, sujino, suj_add_block, 0);
+ if (blocks != numfrags(fs, DIP(jip, di_size)))
+ errx(1, "Sparse journal inode %d.\n", sujino);
+ suj_read();
+ jblocks_destroy(suj_jblocks);
+ suj_jblocks = NULL;
+ if (preen || reply("RECOVER")) {
+ printf("** Building recovery table.\n");
+ suj_prune();
+ suj_build();
+ cg_apply(cg_build);
+ printf("** Resolving unreferenced inode list.\n");
+ ino_unlinked();
+ printf("** Processing journal entries.\n");
+ cg_apply(cg_trunc);
+ cg_apply(cg_check_blk);
+ cg_apply(cg_check_ino);
+ }
+ if (preen == 0 && reply("WRITE CHANGES") == 0)
+ return (0);
+ /*
+ * To remain idempotent with partial truncations the free bitmaps
+ * must be written followed by indirect blocks and lastly inode
+ * blocks. This preserves access to the modified pointers until
+ * they are freed.
+ */
+ cg_apply(cg_write);
+ dblk_write();
+ cg_apply(cg_write_inos);
+ /* Write back superblock. */
+ closedisk(filesys);
+ printf("** %jd journal records in %jd bytes for %.2f%% utilization\n",
+ jrecs, jbytes, ((float)jrecs / (float)(jbytes / JREC_SIZE)) * 100);
+ printf("** Freed %jd inodes (%jd dirs) %jd blocks, and %jd frags.\n",
+ freeinos, freedir, freeblocks, freefrags);
+
+ return (0);
+}
diff --git a/sbin/fsdb/fsdb.c b/sbin/fsdb/fsdb.c
index f7354e8..5622cbb 100644
--- a/sbin/fsdb/fsdb.c
+++ b/sbin/fsdb/fsdb.c
@@ -396,7 +396,8 @@ const char *typename[] = {
"unregistered #13",
"whiteout",
};
-
+
+int diroff;
int slot;
int
@@ -404,9 +405,10 @@ scannames(struct inodesc *idesc)
{
struct direct *dirp = idesc->id_dirp;
- printf("slot %d ino %d reclen %d: %s, `%.*s'\n",
- slot++, dirp->d_ino, dirp->d_reclen, typename[dirp->d_type],
- dirp->d_namlen, dirp->d_name);
+ printf("slot %d off %d ino %d reclen %d: %s, `%.*s'\n",
+ slot++, diroff, dirp->d_ino, dirp->d_reclen,
+ typename[dirp->d_type], dirp->d_namlen, dirp->d_name);
+ diroff += dirp->d_reclen;
return (KEEPON);
}
@@ -416,6 +418,7 @@ CMDFUNCSTART(ls)
checkactivedir(); /* let it go on anyway */
slot = 0;
+ diroff = 0;
idesc.id_number = curinum;
idesc.id_func = scannames;
idesc.id_type = DATA;
diff --git a/sbin/fsdb/fsdbutil.c b/sbin/fsdb/fsdbutil.c
index d50c6c0..2c5710a 100644
--- a/sbin/fsdb/fsdbutil.c
+++ b/sbin/fsdb/fsdbutil.c
@@ -52,7 +52,7 @@ static const char rcsid[] =
#include "fsck.h"
static int charsperline(void);
-static int printindir(ufs2_daddr_t blk, int level, char *bufp);
+static void printindir(ufs2_daddr_t blk, int level, char *bufp);
static void printblocks(ino_t inum, union dinode *dp);
char **
@@ -226,7 +226,7 @@ charsperline(void)
/*
* Recursively print a list of indirect blocks.
*/
-static int
+static void
printindir(ufs2_daddr_t blk, int level, char *bufp)
{
struct bufarea buf, *bp;
@@ -234,6 +234,9 @@ printindir(ufs2_daddr_t blk, int level, char *bufp)
int i, j, cpl, charssofar;
ufs2_daddr_t blkno;
+ if (blk == 0)
+ return;
+ printf("%jd (%d) =>\n", (intmax_t)blk, level);
if (level == 0) {
/* for the final indirect level, don't use the cache */
bp = &buf;
@@ -251,11 +254,8 @@ printindir(ufs2_daddr_t blk, int level, char *bufp)
blkno = bp->b_un.b_indir1[i];
else
blkno = bp->b_un.b_indir2[i];
- if (blkno == 0) {
- if (level == 0)
- putchar('\n');
- return 0;
- }
+ if (blkno == 0)
+ continue;
j = sprintf(tempbuf, "%jd", (intmax_t)blkno);
if (level == 0) {
charssofar += j;
@@ -270,13 +270,14 @@ printindir(ufs2_daddr_t blk, int level, char *bufp)
charssofar += 2;
} else {
printf(" =>\n");
- if (printindir(blkno, level - 1, bufp) == 0)
- return 0;
+ printindir(blkno, level - 1, bufp);
+ printf("\n");
+ charssofar = 0;
}
}
if (level == 0)
putchar('\n');
- return 1;
+ return;
}
@@ -309,7 +310,7 @@ printblocks(ino_t inum, union dinode *dp)
}
}
putchar('\n');
- if (DIP(dp, di_ib[0]) == 0)
+ if (ndb == 0)
return;
bufp = malloc((unsigned int)sblock.fs_bsize);
@@ -317,8 +318,7 @@ printblocks(ino_t inum, union dinode *dp)
errx(EEXIT, "cannot allocate indirect block buffer");
printf("Indirect blocks:\n");
for (i = 0; i < NIADDR; i++)
- if (printindir(DIP(dp, di_ib[i]), i, bufp) == 0)
- break;
+ printindir(DIP(dp, di_ib[i]), i, bufp);
free(bufp);
}
diff --git a/sbin/geom/class/Makefile b/sbin/geom/class/Makefile
index 591f79f..0611cdd 100644
--- a/sbin/geom/class/Makefile
+++ b/sbin/geom/class/Makefile
@@ -15,6 +15,7 @@ SUBDIR+=multipath
SUBDIR+=nop
SUBDIR+=part
SUBDIR+=raid3
+SUBDIR+=sched
SUBDIR+=shsec
SUBDIR+=stripe
SUBDIR+=virstor
diff --git a/sbin/geom/class/cache/gcache.8 b/sbin/geom/class/cache/gcache.8
index d3f782c..b9f03bd 100644
--- a/sbin/geom/class/cache/gcache.8
+++ b/sbin/geom/class/cache/gcache.8
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/sbin/geom/class/mountver/gmountver.8 b/sbin/geom/class/mountver/gmountver.8
index c7a8f04..02d77db 100644
--- a/sbin/geom/class/mountver/gmountver.8
+++ b/sbin/geom/class/mountver/gmountver.8
@@ -14,14 +14,14 @@
.\" 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 THE VOICES IN HIS HEAD 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.
+.\" 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$
.\"
diff --git a/sbin/geom/class/multipath/geom_multipath.c b/sbin/geom/class/multipath/geom_multipath.c
index 4319d04..288492c 100644
--- a/sbin/geom/class/multipath/geom_multipath.c
+++ b/sbin/geom/class/multipath/geom_multipath.c
@@ -48,6 +48,7 @@ uint32_t version = G_MULTIPATH_VERSION;
static void mp_main(struct gctl_req *, unsigned int);
static void mp_label(struct gctl_req *);
static void mp_clear(struct gctl_req *);
+static void mp_add(struct gctl_req *);
struct g_command class_commands[] = {
{
@@ -55,6 +56,10 @@ struct g_command class_commands[] = {
NULL, "[-v] name prov ..."
},
{
+ "add", G_FLAG_VERBOSE | G_FLAG_LOADKLD, mp_main, G_NULL_OPTS,
+ NULL, "[-v] name prov ..."
+ },
+ {
"destroy", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
NULL, "[-v] prov ..."
},
@@ -62,6 +67,14 @@ struct g_command class_commands[] = {
"clear", G_FLAG_VERBOSE, mp_main, G_NULL_OPTS,
NULL, "[-v] prov ..."
},
+ {
+ "rotate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+ NULL, "[-v] prov ..."
+ },
+ {
+ "getactive", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+ NULL, "[-v] prov ..."
+ },
G_CMD_SENTINEL
};
@@ -77,6 +90,8 @@ mp_main(struct gctl_req *req, unsigned int flags __unused)
}
if (strcmp(name, "label") == 0) {
mp_label(req);
+ } else if (strcmp(name, "add") == 0) {
+ mp_add(req);
} else if (strcmp(name, "clear") == 0) {
mp_clear(req);
} else {
@@ -93,7 +108,7 @@ mp_label(struct gctl_req *req)
char *ptr;
uuid_t uuid;
uint32_t secsize = 0, ssize, status;
- const char *name;
+ const char *name, *mpname;
int error, i, nargs;
nargs = gctl_get_int(req, "nargs");
@@ -148,8 +163,8 @@ mp_label(struct gctl_req *req)
*/
strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
md.md_version = G_MULTIPATH_VERSION;
- name = gctl_get_ascii(req, "arg0");
- strlcpy(md.md_name, name, sizeof(md.md_name));
+ mpname = gctl_get_ascii(req, "arg0");
+ strlcpy(md.md_name, mpname, sizeof(md.md_name));
md.md_size = disksiz;
md.md_sectorsize = secsize;
uuid_create(&uuid, &status);
@@ -166,46 +181,44 @@ mp_label(struct gctl_req *req)
free(ptr);
/*
- * Clear last sector first for each provider to spoil anything extant
+ * Clear metadata on initial provider first.
*/
- for (i = 1; i < nargs; i++) {
- name = gctl_get_ascii(req, "arg%d", i);
- error = g_metadata_clear(name, NULL);
- if (error != 0) {
- gctl_error(req, "cannot clear metadata on %s: %s.",
- name, strerror(error));
- return;
- }
+ name = gctl_get_ascii(req, "arg1");
+ error = g_metadata_clear(name, NULL);
+ if (error != 0) {
+ gctl_error(req, "cannot clear metadata on %s: %s.", name, strerror(error));
+ return;
}
+ /*
+ * encode the metadata
+ */
multipath_metadata_encode(&md, sector);
/*
- * Ok, store metadata.
+ * Store metadata on the initial provider.
*/
- for (i = 1; i < nargs; i++) {
- name = gctl_get_ascii(req, "arg%d", i);
- error = g_metadata_store(name, sector, secsize);
- if (error != 0) {
- fprintf(stderr, "Can't store metadata on %s: %s.\n",
- name, strerror(error));
- goto fail;
- }
+ error = g_metadata_store(name, sector, secsize);
+ if (error != 0) {
+ gctl_error(req, "cannot store metadata on %s: %s.", name, strerror(error));
+ return;
}
- return;
-fail:
/*
- * Clear last sector first for each provider to spoil anything extant
+ * Now add the rest of the providers.
*/
- for (i = 1; i < nargs; i++) {
- name = gctl_get_ascii(req, "arg%d", i);
- error = g_metadata_clear(name, NULL);
- if (error != 0) {
- gctl_error(req, "cannot clear metadata on %s: %s.",
- name, strerror(error));
+ error = gctl_change_param(req, "verb", -1, "add");
+ if (error) {
+ gctl_error(req, "unable to change verb to \"add\": %s.", strerror(error));
+ return;
+ }
+ for (i = 2; i < nargs; i++) {
+ error = gctl_change_param(req, "arg1", -1, gctl_get_ascii(req, "arg%d", i));
+ if (error) {
+ gctl_error(req, "unable to add %s to %s: %s.", gctl_get_ascii(req, "arg%d", i), mpname, strerror(error));
continue;
}
+ mp_add(req);
}
}
@@ -213,22 +226,23 @@ static void
mp_clear(struct gctl_req *req)
{
const char *name;
- int error, i, nargs;
+ int error;
- nargs = gctl_get_int(req, "nargs");
- if (nargs < 1) {
- gctl_error(req, "Too few arguments.");
- return;
+ name = gctl_get_ascii(req, "arg1");
+ error = g_metadata_clear(name, G_MULTIPATH_MAGIC);
+ if (error != 0) {
+ fprintf(stderr, "Can't clear metadata on %s: %s.\n", name, strerror(error));
+ gctl_error(req, "Not fully done.");
}
+}
- for (i = 0; i < nargs; i++) {
- name = gctl_get_ascii(req, "arg%d", i);
- error = g_metadata_clear(name, G_MULTIPATH_MAGIC);
- if (error != 0) {
- fprintf(stderr, "Can't clear metadata on %s: %s.\n",
- name, strerror(error));
- gctl_error(req, "Not fully done.");
- continue;
- }
- }
+static void
+mp_add(struct gctl_req *req)
+{
+ const char *errstr;
+
+ errstr = gctl_issue(req);
+ if (errstr != NULL && errstr[0] != '\0') {
+ gctl_error(req, "%s", errstr);
+ }
}
diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c
index e2a045e..3ddbd7a 100644
--- a/sbin/geom/class/part/geom_part.c
+++ b/sbin/geom/class/part/geom_part.c
@@ -133,6 +133,13 @@ struct g_command PUBSYM(class_commands)[] = {
G_OPT_SENTINEL },
"geom", NULL
},
+ { "resize", 0, gpart_issue, {
+ { 's', "size", autofill, G_TYPE_ASCLBA },
+ { 'i', index_param, NULL, G_TYPE_ASCNUM },
+ { 'f', "flags", flags, G_TYPE_STRING },
+ G_OPT_SENTINEL },
+ "geom", NULL
+ },
G_CMD_SENTINEL
};
@@ -243,6 +250,99 @@ fmtattrib(struct gprovider *pp)
}
static int
+gpart_autofill_resize(struct gctl_req *req)
+{
+ struct gmesh mesh;
+ struct gclass *cp;
+ struct ggeom *gp;
+ struct gprovider *pp;
+ unsigned long long last, size, start, new_size;
+ unsigned long long lba, new_lba;
+ const char *s;
+ char *val;
+ int error, idx;
+
+ s = gctl_get_ascii(req, "size");
+ if (*s == '*')
+ new_size = (unsigned long long)atoll(s);
+ else
+ return (0);
+
+ s = gctl_get_ascii(req, index_param);
+ idx = strtol(s, &val, 10);
+ if (idx < 1 || *s == '\0' || *val != '\0')
+ errx(EXIT_FAILURE, "invalid partition index");
+
+ error = geom_gettree(&mesh);
+ if (error)
+ return (error);
+ s = gctl_get_ascii(req, "class");
+ if (s == NULL)
+ abort();
+ cp = find_class(&mesh, s);
+ if (cp == NULL)
+ errx(EXIT_FAILURE, "Class %s not found.", s);
+ s = gctl_get_ascii(req, "geom");
+ if (s == NULL)
+ abort();
+ gp = find_geom(cp, s);
+ if (gp == NULL)
+ errx(EXIT_FAILURE, "No such geom: %s.", s);
+ last = atoll(find_geomcfg(gp, "last"));
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ s = find_provcfg(pp, "index");
+ if (s == NULL)
+ continue;
+ if (atoi(s) == idx)
+ break;
+ }
+ if (pp == NULL)
+ errx(EXIT_FAILURE, "invalid partition index");
+
+ s = find_provcfg(pp, "start");
+ if (s == NULL) {
+ s = find_provcfg(pp, "offset");
+ start = atoll(s) / pp->lg_sectorsize;
+ } else
+ start = atoll(s);
+ s = find_provcfg(pp, "end");
+ if (s == NULL) {
+ s = find_provcfg(pp, "length");
+ lba = start + atoll(s) / pp->lg_sectorsize;
+ } else
+ lba = atoll(s) + 1;
+
+ if (lba > last)
+ return (ENOSPC);
+ size = lba - start;
+ pp = find_provider(gp, lba);
+ if (pp == NULL)
+ new_size = last - start + 1;
+ else {
+ s = find_provcfg(pp, "start");
+ if (s == NULL) {
+ s = find_provcfg(pp, "offset");
+ new_lba = atoll(s) / pp->lg_sectorsize;
+ } else
+ new_lba = atoll(s);
+ /* Is there any free space between current and
+ * next providers?
+ */
+ if (new_lba > lba)
+ new_size = new_lba - start;
+ else
+ return (ENOSPC);
+ }
+ asprintf(&val, "%llu", new_size);
+ if (val == NULL)
+ return (ENOMEM);
+ gctl_change_param(req, "size", -1, val);
+
+ return (0);
+}
+
+static int
gpart_autofill(struct gctl_req *req)
{
struct gmesh mesh;
@@ -257,6 +357,8 @@ gpart_autofill(struct gctl_req *req)
int error, has_size, has_start;
s = gctl_get_ascii(req, "verb");
+ if (strcmp(s, "resize") == 0)
+ return gpart_autofill_resize(req);
if (strcmp(s, "add") != 0)
return (0);
diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8
index 3de658c..66557f3 100644
--- a/sbin/geom/class/part/gpart.8
+++ b/sbin/geom/class/part/gpart.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 18, 2008
+.Dd April 22, 2010
.Dt GPART 8
.Os
.Sh NAME
@@ -37,6 +37,7 @@ lines in your kernel configuration file:
.Bd -ragged -offset indent
.Cd "options GEOM_PART_APM"
.Cd "options GEOM_PART_BSD"
+.Cd "options GEOM_PART_EBR"
.Cd "options GEOM_PART_GPT"
.Cd "options GEOM_PART_MBR"
.Cd "options GEOM_PART_PC98"
@@ -53,6 +54,10 @@ option adds support for the traditional
.Bx
disklabel.
The
+.Dv GEOM_PART_EBR
+option adds support for the Extended Boot Record (EBR),
+which is used to define a logical partition.
+The
.Dv GEOM_PART_GPT
option adds support for the GUID Partition Table (GPT)
found on Intel Itanium computers and Intel-based Macintosh computers.
@@ -120,6 +125,13 @@ utility:
.Op Fl t Ar type
.Op Fl f Ar flags
.Ar geom
+.\" ==== RESIZE ====
+.Nm
+.Cm resize
+.Fl i Ar index
+.Op Fl s Ar size
+.Op Fl f Ar flags
+.Ar geom
.\" ==== SET ====
.Nm
.Cm set
@@ -325,6 +337,30 @@ See the section entitled
below for a discussion
about its use.
.El
+.\" ==== RESIZE ====
+.It Cm resize
+Resize a partition from geom
+.Ar geom
+and further identified by the
+.Fl i Ar index
+option. New partition size is expressed in logical block
+numbers and can be given by the
+.Fl s Ar size
+option. If
+.Fl s
+option is ommited then new size is automatically calculated
+to maximum available from given geom
+.Ar geom .
+.Pp
+Additional options include:
+.Bl -tag -width 10n
+.It Fl f Ar flags
+Additional operational flags.
+See the section entitled
+.Sx "OPERATIONAL FLAGS"
+below for a discussion
+about its use.
+.El
.\" ==== SET ====
.It Cm set
Set the named attribute on the partition entry.
diff --git a/sbin/geom/class/sched/Makefile b/sbin/geom/class/sched/Makefile
new file mode 100644
index 0000000..6656cdd
--- /dev/null
+++ b/sbin/geom/class/sched/Makefile
@@ -0,0 +1,18 @@
+# GEOM_LIBRARY_PATH
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../misc
+#CFLAGS += -I/usr/src/sbin/geom
+
+CLASS=sched
+
+WARNS?= 6
+CLASS_DIR?=/lib/geom
+
+SHLIBDIR?=${CLASS_DIR}
+SHLIB_NAME?=geom_${CLASS}.so
+LINKS= ${BINDIR}/geom ${BINDIR}/g${CLASS}
+MAN= g${CLASS}.8
+SRCS+= geom_${CLASS}.c subr.c
+
+.include <bsd.lib.mk>
diff --git a/sbin/geom/class/sched/geom_sched.c b/sbin/geom/class/sched/geom_sched.c
new file mode 100644
index 0000000..ca05350
--- /dev/null
+++ b/sbin/geom/class/sched/geom_sched.c
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2009 Fabio Checconi
+ * Copyright (c) 2010 Luigi Rizzo, Universita` di Pisa
+ * 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 AUTHORS 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 AUTHORS 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.
+ */
+
+/*
+ * $Id$
+ * $FreeBSD$
+ *
+ * This file implements the userspace library used by the 'geom'
+ * command to load and manipulate disk schedulers.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <libgeom.h>
+
+#include "core/geom.h"
+#include "misc/subr.h"
+
+#define G_SCHED_VERSION 0
+
+uint32_t lib_version = G_LIB_VERSION;
+uint32_t version = G_SCHED_VERSION;
+
+/*
+ * storage for parameters used by this geom class.
+ * Right now only the scheduler name is used.
+ */
+static char algo[] = "rr"; /* default scheduler */
+
+/*
+ * Adapt to differences in geom library.
+ * in V1 struct g_command misses gc_argname, eld, and G_BOOL is undefined
+ */
+#if G_LIB_VERSION == 1
+#define G_ARGNAME
+#define G_TYPE_BOOL G_TYPE_NUMBER
+#else
+#define G_ARGNAME NULL,
+#endif
+
+static void
+gcmd_createinsert(struct gctl_req *req, unsigned flags __unused)
+{
+ const char *reqalgo;
+ char name[64];
+
+ if (gctl_has_param(req, "algo"))
+ reqalgo = gctl_get_ascii(req, "algo");
+ else
+ reqalgo = algo;
+
+ snprintf(name, sizeof(name), "gsched_%s", reqalgo);
+ /*
+ * Do not complain about errors here, gctl_issue()
+ * will fail anyway.
+ */
+ if (modfind(name) < 0)
+ kldload(name);
+ gctl_issue(req);
+}
+
+struct g_command class_commands[] = {
+ { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, gcmd_createinsert,
+ {
+ { 'a', "algo", algo, G_TYPE_STRING },
+ G_OPT_SENTINEL
+ },
+ G_ARGNAME "[-v] [-a algorithm_name] dev ..."
+ },
+ { "insert", G_FLAG_VERBOSE | G_FLAG_LOADKLD, gcmd_createinsert,
+ {
+ { 'a', "algo", algo, G_TYPE_STRING },
+ G_OPT_SENTINEL
+ },
+ G_ARGNAME "[-v] [-a algorithm_name] dev ..."
+ },
+ { "configure", G_FLAG_VERBOSE, NULL,
+ {
+ { 'a', "algo", algo, G_TYPE_STRING },
+ G_OPT_SENTINEL
+ },
+ G_ARGNAME "[-v] [-a algorithm_name] prov ..."
+ },
+ { "destroy", G_FLAG_VERBOSE, NULL,
+ {
+ { 'f', "force", NULL, G_TYPE_BOOL },
+ G_OPT_SENTINEL
+ },
+ G_ARGNAME "[-fv] prov ..."
+ },
+ { "reset", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
+ G_ARGNAME "[-v] prov ..."
+ },
+ G_CMD_SENTINEL
+};
diff --git a/sbin/geom/class/sched/gsched.8 b/sbin/geom/class/sched/gsched.8
new file mode 100644
index 0000000..cde9485
--- /dev/null
+++ b/sbin/geom/class/sched/gsched.8
@@ -0,0 +1,163 @@
+.\" Copyright (c) 2009-2010 Fabio Checconi
+.\" Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
+.\" 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 AUTHORS 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 AUTHORS 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 April 12, 2010
+.Dt GSCHED 8
+.Os
+.Sh NAME
+.Nm gsched
+.Nd "control utility for disk scheduler GEOM class"
+.Sh SYNOPSIS
+.Nm
+.Cm create
+.Op Fl v
+.Op Fl a Ar algorithm
+.Ar provider ...
+.Nm
+.Cm insert
+.Op Fl v
+.Op Fl a Ar algorithm
+.Ar provider ...
+.Nm
+.Cm configure
+.Op Fl v
+.Op Fl a Ar algorithm
+.Ar node ...
+.Nm
+.Cm destroy
+.Op Fl fv
+.Ar node ...
+.Nm
+.Cm reset
+.Op Fl v
+.Ar node ...
+.Nm
+.Cm { list | status | load | unload }
+.Sh DESCRIPTION
+The
+.Nm
+utility (also callable as
+.Nm geom sched ... )
+changes the scheduling policy of the requests going to a provider.
+.Pp
+The first argument to
+.Nm
+indicates an action to be performed:
+.Bl -tag -width ".Cm configure"
+.It Cm create
+Create a new provider and geom node using the specified scheduling algorithm.
+.Ar algorithm
+is the name of the scheduling algorithm used for the provider.
+Available algorithms include:
+.Ar rr ,
+which implements anticipatory scheduling with round robin service
+among clients;
+.Ar as ,
+which implements a simple form of anticipatory scheduling with
+no per-client queue.
+.Pp
+If the operation succeeds, the new provider should appear with name
+.Pa /dev/ Ns Ao Ar dev Ac Ns Pa .sched. .
+The kernel module
+.Pa geom_sched.ko
+will be loaded if it is not loaded already.
+.It Cm insert
+Operates as "create", but the insertion is "transparent",
+i.e. the existing provider is rerouted to the newly created geom,
+which in turn forwards requests to the existing geom.
+This operation allows one to start/stop a scheduling service
+on an already existing provider.
+.Pp
+A subsequent 'destroy' will remove the newly created geom and
+hook the provider back to the original geom.
+.Ar algorithm
+.It Cm configure
+Configure existing scheduling provider. It supports the same options
+as the
+.Nm create
+command.
+.It Cm destroy
+Destroy the geom specified in the parameter.
+.It Cm reset
+Do nothing.
+.It Cm list | status | load | unload
+See
+.Xr geom 8 .
+.El
+.Pp
+Additional options:
+.Bl -tag -width ".Fl f"
+.It Fl f
+Force the removal of the specified provider.
+.It Fl v
+Be more verbose.
+.El
+.Sh SYSCTL VARIABLES
+The following
+.Xr sysctl 8
+variables can be used to control the behavior of the
+.Nm SCHED
+GEOM class.
+The default value is shown next to each variable.
+.Bl -tag -width indent
+.It Va kern.geom.sched.debug : No 0
+Debug level of the
+.Nm SCHED
+GEOM class.
+This can be set to a number between 0 and 2 inclusive.
+If set to 0 minimal debug information is printed, and if set to 2 the
+maximum amount of debug information is printed.
+.El
+.Sh EXIT STATUS
+Exit status is 0 on success, and 1 if the command fails.
+.Sh EXAMPLES
+The following example shows how to create a scheduling provider for disk
+.Pa /dev/da0
+, and how to destroy it.
+.Bd -literal -offset indent
+# Load the geom_sched module:
+kldload geom_sched
+# Load some scheduler classes used by geom_sched:
+kldload gsched_rr gsched_as
+# Configure device ad0 to use scheduler 'rr':
+geom sched insert -s rr ad0
+# Now provider ad0 uses the 'rr' algorithm;
+# the new geom is ad0.sched.
+# Remove the scheduler on the device:
+geom sched destroy -v ad0.sched.
+.Ed
+.Pp
+.Sh SEE ALSO
+.Xr geom 4 ,
+.Xr geom 8
+.Sh HISTORY
+The
+.Nm
+utility appeared in April 2010.
+.Sh AUTHORS
+.An Fabio Checconi Aq fabio@FreeBSD.org
+.An Luigi Rizzo Aq luigi@FreeBSD.org
diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c
index 64df7c6..21deac8 100644
--- a/sbin/geom/misc/subr.c
+++ b/sbin/geom/misc/subr.c
@@ -236,6 +236,7 @@ g_metadata_store(const char *name, u_char *md, size_t size)
error = errno;
goto out;
}
+ (void)ioctl(fd, DIOCGFLUSH, NULL);
out:
if (sector != NULL)
free(sector);
@@ -293,6 +294,7 @@ g_metadata_clear(const char *name, const char *magic)
error = errno;
goto out;
}
+ (void)ioctl(fd, DIOCGFLUSH, NULL);
out:
if (sector != NULL)
free(sector);
diff --git a/sbin/gvinum/gvinum.c b/sbin/gvinum/gvinum.c
index 7f97f9d..041f140 100644
--- a/sbin/gvinum/gvinum.c
+++ b/sbin/gvinum/gvinum.c
@@ -83,8 +83,9 @@ void printconfig(FILE *, char *);
char *create_drive(char *);
void create_volume(int, char **, char *);
char *find_name(const char *, int, int);
-char *find_drive(const char *);
char *find_pattern(char *, char *);
+void copy_device(struct gv_drive *, const char *);
+#define find_drive() find_name("gvinumdrive", GV_TYPE_DRIVE, GV_MAXDRIVENAME)
int
main(int argc, char **argv)
@@ -424,7 +425,7 @@ create_drive(char *device)
drives = 1;
dname = NULL;
- drivename = find_drive(device);
+ drivename = find_drive();
if (drivename == NULL)
return (NULL);
@@ -436,7 +437,7 @@ create_drive(char *device)
err(1, "unable to allocate for gv_drive object");
strlcpy(d->name, drivename, sizeof(d->name));
- strlcpy(d->device, device, sizeof(d->device));
+ copy_device(d, device);
gctl_ro_param(req, "drive0", sizeof(*d), d);
gctl_ro_param(req, "flags", sizeof(int), &flags);
gctl_ro_param(req, "drives", sizeof(int), &drives);
@@ -626,14 +627,13 @@ find_name(const char *prefix, int type, int namelen)
return (NULL);
}
-char *
-find_drive(const char *device)
+void
+copy_device(struct gv_drive *d, const char *device)
{
-
- /* Strip possible /dev/ in front. */
if (strncmp(device, "/dev/", 5) == 0)
- device += 5;
- return (find_name("gvinumdrive", GV_TYPE_DRIVE, GV_MAXDRIVENAME));
+ strlcpy(d->device, (device + 5), sizeof(d->device));
+ else
+ strlcpy(d->device, device, sizeof(d->device));
}
/* Detach a plex or subdisk from its parent. */
@@ -1275,7 +1275,7 @@ gvinum_grow(int argc, char **argv)
return;
}
/* Lookup device and set an appropriate drive name. */
- drive = find_drive(argv[2]);
+ drive = find_drive();
if (drive == NULL) {
warn("unable to find an appropriate drive name");
free(s);
@@ -1283,10 +1283,8 @@ gvinum_grow(int argc, char **argv)
return;
}
strlcpy(d->name, drive, sizeof(d->name));
- if (strncmp(argv[2], "/dev/", 5) == 0)
- strlcpy(d->device, (argv[2] + 5), sizeof(d->device));
- else
- strlcpy(d->device, argv[2], sizeof(d->device));
+ copy_device(d, argv[2]);
+
drives = 1;
/* We try to use the plex name as basis for the subdisk name. */
diff --git a/sbin/hastctl/Makefile b/sbin/hastctl/Makefile
index 43c8c20..301493c 100644
--- a/sbin/hastctl/Makefile
+++ b/sbin/hastctl/Makefile
@@ -15,7 +15,6 @@ SRCS+= proto.c proto_common.c proto_tcp4.c proto_uds.c
SRCS+= token.l
SRCS+= subr.c
SRCS+= y.tab.h
-WARNS?= 6
MAN= hastctl.8
CFLAGS+=-I${.CURDIR}/../hastd
@@ -26,8 +25,13 @@ CFLAGS+=-DINET6
# This is needed to have WARNS > 1.
CFLAGS+=-DYY_NO_UNPUT
-DPADD= ${LIBCRYPTO} ${LIBL}
-LDADD= -lcrypto -ll
+DPADD= ${LIBL}
+LDADD= -ll
+.if ${MK_OPENSSL} != "no"
+DPADD+= ${LIBCRYPTO}
+LDADD+= -lcrypto
+CFLAGS+=-DHAVE_CRYPTO
+.endif
YFLAGS+=-v
diff --git a/sbin/hastd/Makefile b/sbin/hastd/Makefile
index 4311807..bfb62f4 100644
--- a/sbin/hastd/Makefile
+++ b/sbin/hastd/Makefile
@@ -16,7 +16,6 @@ SRCS+= rangelock.c
SRCS+= subr.c
SRCS+= token.l
SRCS+= y.tab.h
-WARNS?= 6
MAN= hastd.8 hast.conf.5
CFLAGS+=-I${.CURDIR}
@@ -27,9 +26,13 @@ CFLAGS+=-DINET6
# This is needed to have WARNS > 1.
CFLAGS+=-DYY_NO_UNPUT
-DPADD= ${LIBCRYPTO} ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBL} \
- ${LIBPTHREAD} ${LIBUTIL}
-LDADD= -lcrypto -lgeom -lbsdxml -lsbuf -ll -lpthread -lutil
+DPADD= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBL} ${LIBPTHREAD} ${LIBUTIL}
+LDADD= -lgeom -lbsdxml -lsbuf -ll -lpthread -lutil
+.if ${MK_OPENSSL} != "no"
+DPADD+= ${LIBCRYPTO}
+LDADD+= -lcrypto
+CFLAGS+=-DHAVE_CRYPTO
+.endif
YFLAGS+=-v
diff --git a/sbin/hastd/hast_proto.c b/sbin/hastd/hast_proto.c
index 6e66006..348dfc8 100644
--- a/sbin/hastd/hast_proto.c
+++ b/sbin/hastd/hast_proto.c
@@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <strings.h>
+#ifdef HAVE_CRYPTO
#include <openssl/sha.h>
+#endif
#include <hast.h>
#include <ebuf.h>
@@ -67,14 +69,18 @@ static int compression_send(struct hast_resource *res, struct nv *nv,
void **datap, size_t *sizep, bool *freedatap);
static int compression_recv(struct hast_resource *res, struct nv *nv,
void **datap, size_t *sizep, bool *freedatap);
+#ifdef HAVE_CRYPTO
static int checksum_send(struct hast_resource *res, struct nv *nv,
void **datap, size_t *sizep, bool *freedatap);
static int checksum_recv(struct hast_resource *res, struct nv *nv,
void **datap, size_t *sizep, bool *freedatap);
+#endif
static struct hast_pipe_stage pipeline[] = {
{ "compression", compression_send, compression_recv },
+#ifdef HAVE_CRYPTO
{ "checksum", checksum_send, checksum_recv }
+#endif
};
static int
@@ -161,6 +167,7 @@ compression_recv(struct hast_resource *res, struct nv *nv, void **datap,
return (0);
}
+#ifdef HAVE_CRYPTO
static int
checksum_send(struct hast_resource *res, struct nv *nv, void **datap,
size_t *sizep, bool *freedatap __unused)
@@ -221,6 +228,7 @@ checksum_recv(struct hast_resource *res, struct nv *nv, void **datap,
return (0);
}
+#endif /* HAVE_CRYPTO */
/*
* Send the given nv structure via conn.
diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c
index 19f0893..957885d 100644
--- a/sbin/hastd/hastd.c
+++ b/sbin/hastd/hastd.c
@@ -137,6 +137,7 @@ child_exit(void)
pjdlog_error("Worker process failed (pid=%u, status=%d).",
(unsigned int)pid, WEXITSTATUS(status));
}
+ proto_close(res->hr_ctrl);
res->hr_workerpid = 0;
if (res->hr_role == HAST_ROLE_PRIMARY) {
sleep(1);
diff --git a/sbin/hastd/pjdlog.c b/sbin/hastd/pjdlog.c
index 38c5539..9f8b3f4 100644
--- a/sbin/hastd/pjdlog.c
+++ b/sbin/hastd/pjdlog.c
@@ -228,7 +228,7 @@ pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt,
len = snprintf(log, sizeof(log), "%s", pjdlog_prefix);
if ((size_t)len < sizeof(log))
- len = vsnprintf(log + len, sizeof(log) - len, fmt, ap);
+ len += vsnprintf(log + len, sizeof(log) - len, fmt, ap);
if (error != -1 && (size_t)len < sizeof(log)) {
(void)snprintf(log + len, sizeof(log) - len, ": %s.",
strerror(error));
diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c
index ed6e91c..0915154 100644
--- a/sbin/hastd/primary.c
+++ b/sbin/hastd/primary.c
@@ -460,9 +460,11 @@ init_local(struct hast_resource *res)
exit(EX_NOINPUT);
}
-static void
-init_remote(struct hast_resource *res)
+static bool
+init_remote(struct hast_resource *res, struct proto_conn **inp,
+ struct proto_conn **outp)
{
+ struct proto_conn *in, *out;
struct nv *nvout, *nvin;
const unsigned char *token;
unsigned char *map;
@@ -472,13 +474,17 @@ init_remote(struct hast_resource *res)
uint32_t mapsize;
size_t size;
+ assert((inp == NULL && outp == NULL) || (inp != NULL && outp != NULL));
+
+ in = out = NULL;
+
/* Prepare outgoing connection with remote node. */
- if (proto_client(res->hr_remoteaddr, &res->hr_remoteout) < 0) {
+ if (proto_client(res->hr_remoteaddr, &out) < 0) {
primary_exit(EX_OSERR, "Unable to create connection to %s",
res->hr_remoteaddr);
}
/* Try to connect, but accept failure. */
- if (proto_connect(res->hr_remoteout) < 0) {
+ if (proto_connect(out) < 0) {
pjdlog_errno(LOG_WARNING, "Unable to connect to %s",
res->hr_remoteaddr);
goto close;
@@ -496,7 +502,7 @@ init_remote(struct hast_resource *res)
nv_free(nvout);
goto close;
}
- if (hast_proto_send(res, res->hr_remoteout, nvout, NULL, 0) < 0) {
+ if (hast_proto_send(res, out, nvout, NULL, 0) < 0) {
pjdlog_errno(LOG_WARNING,
"Unable to send handshake header to %s",
res->hr_remoteaddr);
@@ -504,7 +510,7 @@ init_remote(struct hast_resource *res)
goto close;
}
nv_free(nvout);
- if (hast_proto_recv_hdr(res->hr_remoteout, &nvin) < 0) {
+ if (hast_proto_recv_hdr(out, &nvin) < 0) {
pjdlog_errno(LOG_WARNING,
"Unable to receive handshake header from %s",
res->hr_remoteaddr);
@@ -536,12 +542,12 @@ init_remote(struct hast_resource *res)
* Second handshake step.
* Setup incoming connection with remote node.
*/
- if (proto_client(res->hr_remoteaddr, &res->hr_remotein) < 0) {
+ if (proto_client(res->hr_remoteaddr, &in) < 0) {
pjdlog_errno(LOG_WARNING, "Unable to create connection to %s",
res->hr_remoteaddr);
}
/* Try to connect, but accept failure. */
- if (proto_connect(res->hr_remotein) < 0) {
+ if (proto_connect(in) < 0) {
pjdlog_errno(LOG_WARNING, "Unable to connect to %s",
res->hr_remoteaddr);
goto close;
@@ -560,7 +566,7 @@ init_remote(struct hast_resource *res)
nv_free(nvout);
goto close;
}
- if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) < 0) {
+ if (hast_proto_send(res, in, nvout, NULL, 0) < 0) {
pjdlog_errno(LOG_WARNING,
"Unable to send handshake header to %s",
res->hr_remoteaddr);
@@ -568,7 +574,7 @@ init_remote(struct hast_resource *res)
goto close;
}
nv_free(nvout);
- if (hast_proto_recv_hdr(res->hr_remoteout, &nvin) < 0) {
+ if (hast_proto_recv_hdr(out, &nvin) < 0) {
pjdlog_errno(LOG_WARNING,
"Unable to receive handshake header from %s",
res->hr_remoteaddr);
@@ -611,7 +617,7 @@ init_remote(struct hast_resource *res)
* Remote node have some dirty extents on its own, lets
* download its activemap.
*/
- if (hast_proto_recv_data(res, res->hr_remoteout, nvin, map,
+ if (hast_proto_recv_data(res, out, nvin, map,
mapsize) < 0) {
pjdlog_errno(LOG_ERR,
"Unable to receive remote activemap");
@@ -631,18 +637,29 @@ init_remote(struct hast_resource *res)
(void)hast_activemap_flush(res);
}
pjdlog_info("Connected to %s.", res->hr_remoteaddr);
+ if (inp != NULL && outp != NULL) {
+ *inp = in;
+ *outp = out;
+ } else {
+ res->hr_remotein = in;
+ res->hr_remoteout = out;
+ }
+ return (true);
+close:
+ proto_close(out);
+ if (in != NULL)
+ proto_close(in);
+ return (false);
+}
+
+static void
+sync_start(void)
+{
+
mtx_lock(&sync_lock);
sync_inprogress = true;
mtx_unlock(&sync_lock);
cv_signal(&sync_cond);
- return;
-close:
- proto_close(res->hr_remoteout);
- res->hr_remoteout = NULL;
- if (res->hr_remotein != NULL) {
- proto_close(res->hr_remotein);
- res->hr_remotein = NULL;
- }
}
static void
@@ -665,7 +682,7 @@ init_ggate(struct hast_resource *res)
ggiocreate.gctl_mediasize = res->hr_datasize;
ggiocreate.gctl_sectorsize = res->hr_local_sectorsize;
ggiocreate.gctl_flags = 0;
- ggiocreate.gctl_maxcount = 128;
+ ggiocreate.gctl_maxcount = G_GATE_MAX_QUEUE_SIZE;
ggiocreate.gctl_timeout = 0;
ggiocreate.gctl_unit = G_GATE_NAME_GIVEN;
snprintf(ggiocreate.gctl_name, sizeof(ggiocreate.gctl_name), "hast/%s",
@@ -735,7 +752,8 @@ hastd_primary(struct hast_resource *res)
setproctitle("%s (primary)", res->hr_name);
init_local(res);
- init_remote(res);
+ if (init_remote(res, NULL, NULL))
+ sync_start();
init_ggate(res);
init_environment(res);
error = pthread_create(&td, NULL, ggate_recv_thread, res);
@@ -1695,6 +1713,7 @@ static void *
guard_thread(void *arg)
{
struct hast_resource *res = arg;
+ struct proto_conn *in, *out;
unsigned int ii, ncomps;
int timeout;
@@ -1738,26 +1757,31 @@ guard_thread(void *arg)
* connected.
*/
rw_unlock(&hio_remote_lock[ii]);
- rw_wlock(&hio_remote_lock[ii]);
- assert(res->hr_remotein == NULL);
- assert(res->hr_remoteout == NULL);
pjdlog_debug(2,
"remote_guard: Reconnecting to %s.",
res->hr_remoteaddr);
- init_remote(res);
- if (ISCONNECTED(res, ii)) {
+ in = out = NULL;
+ if (init_remote(res, &in, &out)) {
+ rw_wlock(&hio_remote_lock[ii]);
+ assert(res->hr_remotein == NULL);
+ assert(res->hr_remoteout == NULL);
+ assert(in != NULL && out != NULL);
+ res->hr_remotein = in;
+ res->hr_remoteout = out;
+ rw_unlock(&hio_remote_lock[ii]);
pjdlog_info("Successfully reconnected to %s.",
res->hr_remoteaddr);
+ sync_start();
} else {
/* Both connections should be NULL. */
assert(res->hr_remotein == NULL);
assert(res->hr_remoteout == NULL);
+ assert(in == NULL && out == NULL);
pjdlog_debug(2,
"remote_guard: Reconnect to %s failed.",
res->hr_remoteaddr);
timeout = RECONNECT_SLEEP;
}
- rw_unlock(&hio_remote_lock[ii]);
}
}
(void)cv_timedwait(&hio_guard_cond, &hio_guard_lock, timeout);
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index aebcdc0..aa96175 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -881,7 +881,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
#define IFCAPBITS \
"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
"\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \
-"\21VLAN_HWFILTER\23VLAN_HWTSO"
+"\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE"
/*
* Print the status of the interface. If an address family was
@@ -922,19 +922,20 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
ifr.ifr_buffer.buffer = descr;
ifr.ifr_buffer.length = descrlen;
if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
- if (strlen(descr) > 0)
- printf("\tdescription: %s\n", descr);
- break;
- } else if (errno == ENAMETOOLONG)
- descrlen = ifr.ifr_buffer.length;
- else
- break;
- } else {
+ if (ifr.ifr_buffer.buffer == descr) {
+ if (strlen(descr) > 0)
+ printf("\tdescription: %s\n",
+ descr);
+ } else if (ifr.ifr_buffer.length > descrlen) {
+ descrlen = ifr.ifr_buffer.length;
+ continue;
+ }
+ }
+ } else
warn("unable to allocate memory for interface"
"description");
- break;
- }
- };
+ break;
+ }
if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
if (ifr.ifr_curcap != 0) {
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index 0709242..6cb4d2c 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -4509,6 +4509,7 @@ end:
} else {
LINE_BREAK();
list_roam(s);
+ LINE_BREAK();
}
}
diff --git a/sbin/ipf/ipftest/Makefile b/sbin/ipf/ipftest/Makefile
index 8903f25..d089b2b 100644
--- a/sbin/ipf/ipftest/Makefile
+++ b/sbin/ipf/ipftest/Makefile
@@ -1,7 +1,5 @@
# $FreeBSD$
-WARNS=0
-
PROG= ipftest
SRCS= ${GENHDRS} ipftest.c fil.c ip_frag.c ip_state.c ip_nat.c \
ip_proxy.c ip_auth.c ip_htable.c ip_lookup.c \
@@ -10,6 +8,7 @@ SRCS= ${GENHDRS} ipftest.c fil.c ip_frag.c ip_state.c ip_nat.c \
ipf_l.c ipnat_y.c ipnat_l.c md5.c radix.c bpf_filter.c
MAN= ipftest.1
+WARNS?= 0
CFLAGS+= -DIPFILTER_LOG -DIPFILTER_COMPILED -DIPFILTER_LOOKUP \
-DIPFILTER_SCAN -DIPFILTER_SYNC -DIPFILTER_CKSUM -I.
diff --git a/sbin/ipfw/altq.c b/sbin/ipfw/altq.c
index b00a1e0..8cf19e5 100644
--- a/sbin/ipfw/altq.c
+++ b/sbin/ipfw/altq.c
@@ -39,6 +39,7 @@
#include <net/if.h> /* IFNAMSIZ */
#include <net/pfvar.h>
+#include <netinet/in.h> /* in_addr */
#include <netinet/ip_fw.h>
/*
diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c
index 490aa53..19d52a4 100644
--- a/sbin/ipfw/dummynet.c
+++ b/sbin/ipfw/dummynet.c
@@ -1,10 +1,5 @@
/*
- * Copyright (c) 2002-2003 Luigi Rizzo
- * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Idea and grammar partially left from:
- * Copyright (c) 1993 Daniel Boulet
+ * Copyright (c) 2002-2003,2010 Luigi Rizzo
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
@@ -15,8 +10,6 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * NEW command line interface for IP firewall facility
- *
* $FreeBSD$
*
* dummynet support
@@ -24,7 +17,6 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/queue.h>
/* XXX there are several sysctl leftover here */
#include <sys/sysctl.h>
@@ -46,6 +38,7 @@
#include <netinet/ip_dummynet.h>
#include <arpa/inet.h> /* inet_ntoa */
+
static struct _s_x dummynet_params[] = {
{ "plr", TOK_PLR },
{ "noerror", TOK_NOERROR },
@@ -56,27 +49,59 @@ static struct _s_x dummynet_params[] = {
{ "src-port", TOK_SRCPORT },
{ "proto", TOK_PROTO },
{ "weight", TOK_WEIGHT },
+ { "lmax", TOK_LMAX },
+ { "maxlen", TOK_LMAX },
{ "all", TOK_ALL },
- { "mask", TOK_MASK },
+ { "mask", TOK_MASK }, /* alias for both */
+ { "sched_mask", TOK_SCHED_MASK },
+ { "flow_mask", TOK_FLOW_MASK },
{ "droptail", TOK_DROPTAIL },
{ "red", TOK_RED },
{ "gred", TOK_GRED },
{ "bw", TOK_BW },
{ "bandwidth", TOK_BW },
{ "delay", TOK_DELAY },
+ { "link", TOK_LINK },
{ "pipe", TOK_PIPE },
{ "queue", TOK_QUEUE },
+ { "flowset", TOK_FLOWSET },
+ { "sched", TOK_SCHED },
+ { "pri", TOK_PRI },
+ { "priority", TOK_PRI },
+ { "type", TOK_TYPE },
{ "flow-id", TOK_FLOWID},
{ "dst-ipv6", TOK_DSTIP6},
{ "dst-ip6", TOK_DSTIP6},
{ "src-ipv6", TOK_SRCIP6},
{ "src-ip6", TOK_SRCIP6},
- { "profile", TOK_PIPE_PROFILE},
+ { "profile", TOK_PROFILE},
{ "burst", TOK_BURST},
{ "dummynet-params", TOK_NULL },
{ NULL, 0 } /* terminator */
};
+#define O_NEXT(p, len) ((void *)((char *)p + len))
+
+static void
+oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
+{
+ oid->len = len;
+ oid->type = type;
+ oid->subtype = 0;
+ oid->id = id;
+}
+
+/* make room in the buffer and move the pointer forward */
+static void *
+o_next(struct dn_id **o, int len, int type)
+{
+ struct dn_id *ret = *o;
+ oid_fill(ret, len, type, 0);
+ *o = O_NEXT(*o, len);
+ return ret;
+}
+
+#if 0
static int
sort_q(void *arg, const void *pa, const void *pb)
{
@@ -108,117 +133,84 @@ sort_q(void *arg, const void *pa, const void *pb)
res = 1;
return (int)(rev ? res : -res);
}
+#endif
+/* print a mask and header for the subsequent list of flows */
static void
-list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
+print_mask(struct ipfw_flow_id *id)
+{
+ if (!IS_IP6_FLOW_ID(id)) {
+ printf(" "
+ "mask: %s 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
+ id->extra ? "queue," : "",
+ id->proto,
+ id->src_ip, id->src_port,
+ id->dst_ip, id->dst_port);
+
+ printf("BKT Prot ___Source IP/port____ "
+ "____Dest. IP/port____ "
+ "Tot_pkt/bytes Pkt/Byte Drp\n");
+ } else {
+ char buf[255];
+ printf("\n mask: %sproto: 0x%02x, flow_id: 0x%08x, ",
+ id->extra ? "queue," : "",
+ id->proto, id->flow_id6);
+ inet_ntop(AF_INET6, &(id->src_ip6), buf, sizeof(buf));
+ printf("%s/0x%04x -> ", buf, id->src_port);
+ inet_ntop(AF_INET6, &(id->dst_ip6), buf, sizeof(buf));
+ printf("%s/0x%04x\n", buf, id->dst_port);
+
+ printf("BKT ___Prot___ _flow-id_ "
+ "______________Source IPv6/port_______________ "
+ "_______________Dest. IPv6/port_______________ "
+ "Tot_pkt/bytes Pkt/Byte Drp\n");
+ }
+}
+
+static void
+list_flow(struct dn_flow *ni)
{
- int l;
- int index_printed, indexes = 0;
char buff[255];
struct protoent *pe;
+ struct in_addr ina;
+ struct ipfw_flow_id *id = &ni->fid;
- if (fs->rq_elements == 0)
- return;
-
- if (co.do_sort != 0)
- qsort_r(q, fs->rq_elements, sizeof *q, NULL, sort_q);
-
- /* Print IPv4 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- struct in_addr ina;
-
+ pe = getprotobynumber(id->proto);
/* XXX: Should check for IPv4 flows */
- if (IS_IP6_FLOW_ID(&(q[l].id)))
- continue;
-
- if (!index_printed) {
- index_printed = 1;
- if (indexes > 0) /* currently a no-op */
- printf("\n");
- indexes++;
- printf(" "
- "mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
- fs->flow_mask.proto,
- fs->flow_mask.src_ip, fs->flow_mask.src_port,
- fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
-
- printf("BKT Prot ___Source IP/port____ "
- "____Dest. IP/port____ "
- "Tot_pkt/bytes Pkt/Byte Drp\n");
- }
-
- printf("%3d ", q[l].hash_slot);
- pe = getprotobynumber(q[l].id.proto);
+ printf("%3u%c", (ni->oid.id) & 0xff,
+ id->extra ? '*' : ' ');
+ if (!IS_IP6_FLOW_ID(id)) {
if (pe)
printf("%-4s ", pe->p_name);
else
- printf("%4u ", q[l].id.proto);
- ina.s_addr = htonl(q[l].id.src_ip);
+ printf("%4u ", id->proto);
+ ina.s_addr = htonl(id->src_ip);
printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.src_port);
- ina.s_addr = htonl(q[l].id.dst_ip);
+ inet_ntoa(ina), id->src_port);
+ ina.s_addr = htonl(id->dst_ip);
printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.dst_port);
- printf("%4llu %8llu %2u %4u %3u\n",
- align_uint64(&q[l].tot_pkts),
- align_uint64(&q[l].tot_bytes),
- q[l].len, q[l].len_bytes, q[l].drops);
- if (co.verbose)
- printf(" S %20llu F %20llu\n",
- align_uint64(&q[l].S), align_uint64(&q[l].F));
- }
-
- /* Print IPv6 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- if (!IS_IP6_FLOW_ID(&(q[l].id)))
- continue;
-
- if (!index_printed) {
- index_printed = 1;
- if (indexes > 0)
- printf("\n");
- indexes++;
- printf("\n mask: proto: 0x%02x, flow_id: 0x%08x, ",
- fs->flow_mask.proto, fs->flow_mask.flow_id6);
- inet_ntop(AF_INET6, &(fs->flow_mask.src_ip6),
- buff, sizeof(buff));
- printf("%s/0x%04x -> ", buff, fs->flow_mask.src_port);
- inet_ntop( AF_INET6, &(fs->flow_mask.dst_ip6),
- buff, sizeof(buff) );
- printf("%s/0x%04x\n", buff, fs->flow_mask.dst_port);
-
- printf("BKT ___Prot___ _flow-id_ "
- "______________Source IPv6/port_______________ "
- "_______________Dest. IPv6/port_______________ "
- "Tot_pkt/bytes Pkt/Byte Drp\n");
- }
- printf("%3d ", q[l].hash_slot);
- pe = getprotobynumber(q[l].id.proto);
+ inet_ntoa(ina), id->dst_port);
+ } else {
+ /* Print IPv6 flows */
if (pe != NULL)
printf("%9s ", pe->p_name);
else
- printf("%9u ", q[l].id.proto);
- printf("%7d %39s/%-5d ", q[l].id.flow_id6,
- inet_ntop(AF_INET6, &(q[l].id.src_ip6), buff, sizeof(buff)),
- q[l].id.src_port);
+ printf("%9u ", id->proto);
+ printf("%7d %39s/%-5d ", id->flow_id6,
+ inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)),
+ id->src_port);
printf(" %39s/%-5d ",
- inet_ntop(AF_INET6, &(q[l].id.dst_ip6), buff, sizeof(buff)),
- q[l].id.dst_port);
- printf(" %4llu %8llu %2u %4u %3u\n",
- align_uint64(&q[l].tot_pkts),
- align_uint64(&q[l].tot_bytes),
- q[l].len, q[l].len_bytes, q[l].drops);
- if (co.verbose)
- printf(" S %20llu F %20llu\n",
- align_uint64(&q[l].S),
- align_uint64(&q[l].F));
+ inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)),
+ id->dst_port);
}
+ pr_u64(&ni->tot_pkts, 4);
+ pr_u64(&ni->tot_bytes, 8);
+ printf("%2u %4u %3u\n",
+ ni->length, ni->len_bytes, ni->drops);
}
static void
-print_flowset_parms(struct dn_flow_set *fs, char *prefix)
+print_flowset_parms(struct dn_fs *fs, char *prefix)
{
int l;
char qs[30];
@@ -226,7 +218,7 @@ print_flowset_parms(struct dn_flow_set *fs, char *prefix)
char red[90]; /* Display RED parameters */
l = fs->qsize;
- if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
+ if (fs->flags & DN_QSIZE_BYTES) {
if (l >= 8192)
sprintf(qs, "%d KB", l / 1024);
else
@@ -237,23 +229,34 @@ print_flowset_parms(struct dn_flow_set *fs, char *prefix)
sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
else
plr[0] = '\0';
- if (fs->flags_fs & DN_IS_RED) /* RED parameters */
+
+ if (fs->flags & DN_IS_RED) /* RED parameters */
sprintf(red,
"\n\t %cRED w_q %f min_th %d max_th %d max_p %f",
- (fs->flags_fs & DN_IS_GENTLE_RED) ? 'G' : ' ',
+ (fs->flags & DN_IS_GENTLE_RED) ? 'G' : ' ',
1.0 * fs->w_q / (double)(1 << SCALE_RED),
- SCALE_VAL(fs->min_th),
- SCALE_VAL(fs->max_th),
+ fs->min_th,
+ fs->max_th,
1.0 * fs->max_p / (double)(1 << SCALE_RED));
else
sprintf(red, "droptail");
- printf("%s %s%s %d queues (%d buckets) %s\n",
- prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
+ if (prefix[0]) {
+ printf("%s %s%s %d queues (%d buckets) %s\n",
+ prefix, qs, plr, fs->oid.id, fs->buckets, red);
+ prefix[0] = '\0';
+ } else {
+ printf("q%05d %s%s %d flows (%d buckets) sched %d "
+ "weight %d lmax %d pri %d %s\n",
+ fs->fs_nr, qs, plr, fs->oid.id, fs->buckets,
+ fs->sched_nr, fs->par[0], fs->par[1], fs->par[2], red);
+ if (fs->flags & DN_HAVE_MASK)
+ print_mask(&fs->flow_mask);
+ }
}
static void
-print_extra_delay_parms(struct dn_pipe *p)
+print_extra_delay_parms(struct dn_profile *p)
{
double loss;
if (p->samples_no <= 0)
@@ -265,105 +268,126 @@ print_extra_delay_parms(struct dn_pipe *p)
p->name, loss, p->samples_no);
}
-void
-ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[])
+static void
+flush_buf(char *buf)
{
- int rulenum;
- void *next = data;
- struct dn_pipe *p = (struct dn_pipe *) data;
- struct dn_flow_set *fs;
- struct dn_flow_queue *q;
- int l;
-
- if (ac > 0)
- rulenum = strtoul(*av++, NULL, 10);
- else
- rulenum = 0;
- for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) {
- double b = p->bandwidth;
- char buf[30];
- char prefix[80];
- char burst[5 + 7];
-
- if (SLIST_NEXT(p, next) != (struct dn_pipe *)DN_IS_PIPE)
- break; /* done with pipes, now queues */
-
- /*
- * compute length, as pipe have variable size
- */
- l = sizeof(*p) + p->fs.rq_elements * sizeof(*q);
- next = (char *)p + l;
- nbytes -= l;
-
- if ((rulenum != 0 && rulenum != p->pipe_nr) || co.do_pipe == 2)
- continue;
-
- /*
- * Print rate (or clocking interface)
- */
- if (p->if_name[0] != '\0')
- sprintf(buf, "%s", p->if_name);
- else if (b == 0)
- sprintf(buf, "unlimited");
- else if (b >= 1000000)
- sprintf(buf, "%7.3f Mbit/s", b/1000000);
- else if (b >= 1000)
- sprintf(buf, "%7.3f Kbit/s", b/1000);
- else
- sprintf(buf, "%7.3f bit/s ", b);
-
- sprintf(prefix, "%05d: %s %4d ms ",
- p->pipe_nr, buf, p->delay);
-
- print_flowset_parms(&(p->fs), prefix);
-
- if (humanize_number(burst, sizeof(burst), p->burst,
- "Byte", HN_AUTOSCALE, 0) < 0 || co.verbose)
- printf("\t burst: %ju Byte\n", p->burst);
- else
- printf("\t burst: %s\n", burst);
-
- print_extra_delay_parms(p);
-
- q = (struct dn_flow_queue *)(p+1);
- list_queues(&(p->fs), q);
- }
- for (fs = next; nbytes >= sizeof *fs; fs = next) {
- char prefix[80];
-
- if (SLIST_NEXT(fs, next) != (struct dn_flow_set *)DN_IS_QUEUE)
- break;
- l = sizeof(*fs) + fs->rq_elements * sizeof(*q);
- next = (char *)fs + l;
- nbytes -= l;
-
- if (rulenum != 0 && ((rulenum != fs->fs_nr && co.do_pipe == 2) ||
- (rulenum != fs->parent_nr && co.do_pipe == 1))) {
- continue;
- }
-
- q = (struct dn_flow_queue *)(fs+1);
- sprintf(prefix, "q%05d: weight %d pipe %d ",
- fs->fs_nr, fs->weight, fs->parent_nr);
- print_flowset_parms(fs, prefix);
- list_queues(fs, q);
+ if (buf[0])
+ printf("%s\n", buf);
+ buf[0] = '\0';
+}
+
+/*
+ * generic list routine. We expect objects in a specific order, i.e.
+ * PIPES AND SCHEDULERS:
+ * link; scheduler; internal flowset if any; instances
+ * we can tell a pipe from the number.
+ *
+ * FLOWSETS:
+ * flowset; queues;
+ * link i (int queue); scheduler i; si(i) { flowsets() : queues }
+ */
+static void
+list_pipes(struct dn_id *oid, struct dn_id *end)
+{
+ char buf[160]; /* pending buffer */
+
+ buf[0] = '\0';
+ for (; oid != end; oid = O_NEXT(oid, oid->len)) {
+ if (oid->len < sizeof(*oid))
+ errx(1, "invalid oid len %d\n", oid->len);
+
+ switch (oid->type) {
+ default:
+ flush_buf(buf);
+ printf("unrecognized object %d size %d\n", oid->type, oid->len);
+ break;
+ case DN_TEXT: /* list of attached flowsets */
+ {
+ int i, l;
+ struct {
+ struct dn_id id;
+ uint32_t p[0];
+ } *d = (void *)oid;
+ l = (oid->len - sizeof(*oid))/sizeof(d->p[0]);
+ if (l == 0)
+ break;
+ printf(" Children flowsets: ");
+ for (i = 0; i < l; i++)
+ printf("%u ", d->p[i]);
+ printf("\n");
+ break;
+ }
+ case DN_CMD_GET:
+ if (co.verbose)
+ printf("answer for cmd %d, len %d\n", oid->type, oid->id);
+ break;
+ case DN_SCH: {
+ struct dn_sch *s = (struct dn_sch *)oid;
+ flush_buf(buf);
+ printf(" sched %d type %s flags 0x%x %d buckets %d active\n",
+ s->sched_nr,
+ s->name, s->flags, s->buckets, s->oid.id);
+ if (s->flags & DN_HAVE_MASK)
+ print_mask(&s->sched_mask);
+ }
+ break;
+
+ case DN_FLOW:
+ list_flow((struct dn_flow *)oid);
+ break;
+
+ case DN_LINK: {
+ struct dn_link *p = (struct dn_link *)oid;
+ double b = p->bandwidth;
+ char bwbuf[30];
+ char burst[5 + 7];
+
+ /* This starts a new object so flush buffer */
+ flush_buf(buf);
+ /* data rate */
+ if (b == 0)
+ sprintf(bwbuf, "unlimited ");
+ else if (b >= 1000000)
+ sprintf(bwbuf, "%7.3f Mbit/s", b/1000000);
+ else if (b >= 1000)
+ sprintf(bwbuf, "%7.3f Kbit/s", b/1000);
+ else
+ sprintf(bwbuf, "%7.3f bit/s ", b);
+
+ if (humanize_number(burst, sizeof(burst), p->burst,
+ "", HN_AUTOSCALE, 0) < 0 || co.verbose)
+ sprintf(burst, "%d", (int)p->burst);
+ sprintf(buf, "%05d: %s %4d ms burst %s",
+ p->link_nr % DN_MAX_ID, bwbuf, p->delay, burst);
+ }
+ break;
+
+ case DN_FS:
+ print_flowset_parms((struct dn_fs *)oid, buf);
+ break;
+ case DN_PROFILE:
+ flush_buf(buf);
+ print_extra_delay_parms((struct dn_profile *)oid);
}
+ flush_buf(buf); // XXX does it really go here ?
+ }
}
/*
- * Delete pipe or queue i
+ * Delete pipe, queue or scheduler i
*/
int
-ipfw_delete_pipe(int pipe_or_queue, int i)
+ipfw_delete_pipe(int do_pipe, int i)
{
- struct dn_pipe p;
-
- memset(&p, 0, sizeof p);
- if (pipe_or_queue == 1)
- p.pipe_nr = i; /* pipe */
- else
- p.fs.fs_nr = i; /* queue */
- i = do_cmd(IP_DUMMYNET_DEL, &p, sizeof p);
+ struct {
+ struct dn_id oid;
+ uintptr_t a[1]; /* add more if we want a list */
+ } cmd;
+ oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
+ cmd.oid.subtype = (do_pipe == 1) ? DN_LINK :
+ ( (do_pipe == 2) ? DN_FS : DN_SCH);
+ cmd.a[0] = i;
+ i = do_cmd(IP_DUMMYNET3, &cmd, cmd.oid.len);
if (i) {
i = 1;
warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i);
@@ -400,7 +424,7 @@ ipfw_delete_pipe(int pipe_or_queue, int i)
* The empirical curve may have both vertical and horizontal lines.
* Vertical lines represent constant delay for a range of
* probabilities; horizontal lines correspond to a discontinuty
- * in the delay distribution: the pipe will use the largest delay
+ * in the delay distribution: the link will use the largest delay
* for a given probability.
*
* To pass the curve to dummynet, we must store the parameters
@@ -490,9 +514,12 @@ static void
read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
{
if (*bandwidth != -1)
- warn("duplicate token, override bandwidth value!");
+ warnx("duplicate token, override bandwidth value!");
if (arg[0] >= 'a' && arg[0] <= 'z') {
+ if (!if_name) {
+ errx(1, "no if support");
+ }
if (namelen >= IFNAMSIZ)
warn("interface name truncated");
namelen--;
@@ -508,7 +535,7 @@ read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
if (*end == 'K' || *end == 'k') {
end++;
bw *= 1000;
- } else if (*end == 'M') {
+ } else if (*end == 'M' || *end == 'm') {
end++;
bw *= 1000000;
}
@@ -521,7 +548,8 @@ read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
errx(EX_DATAERR, "bandwidth too large");
*bandwidth = bw;
- if_name[0] = '\0';
+ if (if_name)
+ if_name[0] = '\0';
}
}
@@ -551,7 +579,8 @@ compare_points(const void *vp1, const void *vp2)
#define ED_EFMT(s) EX_DATAERR,"error in %s at line %d: "#s,filename,lineno
static void
-load_extra_delays(const char *filename, struct dn_pipe *p)
+load_extra_delays(const char *filename, struct dn_profile *p,
+ struct dn_link *link)
{
char line[ED_MAX_LINE_LEN];
FILE *f;
@@ -566,6 +595,9 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
struct point points[ED_MAX_SAMPLES_NO];
int points_no = 0;
+ /* XXX link never NULL? */
+ p->link_nr = link->link_nr;
+
profile_name[0] = '\0';
f = fopen(filename, "r");
if (f == NULL)
@@ -606,7 +638,8 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
ED_MAX_SAMPLES_NO);
do_points = 0;
} else if (!strcasecmp(name, ED_TOK_BW)) {
- read_bandwidth(arg, &p->bandwidth, p->if_name, sizeof(p->if_name));
+ char buf[IFNAMSIZ];
+ read_bandwidth(arg, &link->bandwidth, buf, sizeof(buf));
} else if (!strcasecmp(name, ED_TOK_LOSS)) {
if (loss != -1.0)
errx(ED_EFMT("duplicated token: %s"), name);
@@ -676,17 +709,17 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
double y2 = points[i+1].prob * samples;
double x2 = points[i+1].delay;
- int index = y1;
+ int ix = y1;
int stop = y2;
if (x1 == x2) {
- for (; index<stop; ++index)
- p->samples[index] = x1;
+ for (; ix<stop; ++ix)
+ p->samples[ix] = x1;
} else {
double m = (y2-y1)/(x2-x1);
double c = y1 - m*x1;
- for (; index<stop ; ++index)
- p->samples[index] = (index - c)/m;
+ for (; ix<stop ; ++ix)
+ p->samples[ix] = (ix - c)/m;
}
}
p->samples_no = samples;
@@ -694,27 +727,120 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
strncpy(p->name, profile_name, sizeof(p->name));
}
+/*
+ * configuration of pipes, schedulers, flowsets.
+ * When we configure a new scheduler, an empty pipe is created, so:
+ *
+ * do_pipe = 1 -> "pipe N config ..." only for backward compatibility
+ * sched N+Delta type fifo sched_mask ...
+ * pipe N+Delta <parameters>
+ * flowset N+Delta pipe N+Delta (no parameters)
+ * sched N type wf2q+ sched_mask ...
+ * pipe N <parameters>
+ *
+ * do_pipe = 2 -> flowset N config
+ * flowset N parameters
+ *
+ * do_pipe = 3 -> sched N config
+ * sched N parameters (default no pipe)
+ * optional Pipe N config ...
+ * pipe ==>
+ */
void
ipfw_config_pipe(int ac, char **av)
{
- int samples[ED_MAX_SAMPLES_NO];
- struct dn_pipe p;
- int i;
+ int i, j;
char *end;
void *par = NULL;
-
- memset(&p, 0, sizeof p);
- p.bandwidth = -1;
+ struct dn_id *buf, *base;
+ struct dn_sch *sch = NULL;
+ struct dn_link *p = NULL;
+ struct dn_fs *fs = NULL;
+ struct dn_profile *pf = NULL;
+ struct ipfw_flow_id *mask = NULL;
+ int lmax;
+ uint32_t _foo = 0, *flags = &_foo , *buckets = &_foo;
+
+ /*
+ * allocate space for 1 header,
+ * 1 scheduler, 1 link, 1 flowset, 1 profile
+ */
+ lmax = sizeof(struct dn_id); /* command header */
+ lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
+ sizeof(struct dn_fs) + sizeof(struct dn_profile);
av++; ac--;
/* Pipe number */
if (ac && isdigit(**av)) {
i = atoi(*av); av++; ac--;
- if (co.do_pipe == 1)
- p.pipe_nr = i;
- else
- p.fs.fs_nr = i;
+ } else
+ i = -1;
+ if (i <= 0)
+ errx(EX_USAGE, "need a pipe/flowset/sched number");
+ base = buf = safe_calloc(1, lmax);
+ /* all commands start with a 'CONFIGURE' and a version */
+ o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
+ base->id = DN_API_VERSION;
+
+ switch (co.do_pipe) {
+ case 1: /* "pipe N config ..." */
+ /* Allocate space for the WF2Q+ scheduler, its link
+ * and the FIFO flowset. Set the number, but leave
+ * the scheduler subtype and other parameters to 0
+ * so the kernel will use appropriate defaults.
+ * XXX todo: add a flag to record if a parameter
+ * is actually configured.
+ * If we do a 'pipe config' mask -> sched_mask.
+ * The FIFO scheduler and link are derived from the
+ * WF2Q+ one in the kernel.
+ */
+ sch = o_next(&buf, sizeof(*sch), DN_SCH);
+ p = o_next(&buf, sizeof(*p), DN_LINK);
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+
+ sch->sched_nr = i;
+ sch->oid.subtype = 0; /* defaults to WF2Q+ */
+ mask = &sch->sched_mask;
+ flags = &sch->flags;
+ buckets = &sch->buckets;
+ *flags |= DN_PIPE_CMD;
+
+ p->link_nr = i;
+
+ /* This flowset is only for the FIFO scheduler */
+ fs->fs_nr = i + 2*DN_MAX_ID;
+ fs->sched_nr = i + DN_MAX_ID;
+ break;
+
+ case 2: /* "queue N config ... " */
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+ fs->fs_nr = i;
+ mask = &fs->flow_mask;
+ flags = &fs->flags;
+ buckets = &fs->buckets;
+ break;
+
+ case 3: /* "sched N config ..." */
+ sch = o_next(&buf, sizeof(*sch), DN_SCH);
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+ sch->sched_nr = i;
+ mask = &sch->sched_mask;
+ flags = &sch->flags;
+ buckets = &sch->buckets;
+ /* fs is used only with !MULTIQUEUE schedulers */
+ fs->fs_nr = i + DN_MAX_ID;
+ fs->sched_nr = i;
+ break;
}
+ /* set to -1 those fields for which we want to reuse existing
+ * values from the kernel.
+ * Also, *_nr and subtype = 0 mean reuse the value from the kernel.
+ * XXX todo: support reuse of the mask.
+ */
+ if (p)
+ p->bandwidth = -1;
+ for (j = 0; j < sizeof(fs->par)/sizeof(fs->par[0]); j++)
+ fs->par[j] = -1;
while (ac > 0) {
double d;
int tok = match_token(dummynet_params, *av);
@@ -722,41 +848,48 @@ ipfw_config_pipe(int ac, char **av)
switch(tok) {
case TOK_NOERROR:
- p.fs.flags_fs |= DN_NOERROR;
+ NEED(fs, "noerror is only for pipes");
+ fs->flags |= DN_NOERROR;
break;
case TOK_PLR:
+ NEED(fs, "plr is only for pipes");
NEED1("plr needs argument 0..1\n");
d = strtod(av[0], NULL);
if (d > 1)
d = 1;
else if (d < 0)
d = 0;
- p.fs.plr = (int)(d*0x7fffffff);
+ fs->plr = (int)(d*0x7fffffff);
ac--; av++;
break;
case TOK_QUEUE:
+ NEED(fs, "queue is only for pipes or flowsets");
NEED1("queue needs queue size\n");
end = NULL;
- p.fs.qsize = strtoul(av[0], &end, 0);
+ fs->qsize = strtoul(av[0], &end, 0);
if (*end == 'K' || *end == 'k') {
- p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
- p.fs.qsize *= 1024;
+ fs->flags |= DN_QSIZE_BYTES;
+ fs->qsize *= 1024;
} else if (*end == 'B' ||
_substrcmp2(end, "by", "bytes") == 0) {
- p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
+ fs->flags |= DN_QSIZE_BYTES;
}
ac--; av++;
break;
case TOK_BUCKETS:
+ NEED(fs, "buckets is only for pipes or flowsets");
NEED1("buckets needs argument\n");
- p.fs.rq_size = strtoul(av[0], NULL, 0);
+ *buckets = strtoul(av[0], NULL, 0);
ac--; av++;
break;
+ case TOK_FLOW_MASK:
+ case TOK_SCHED_MASK:
case TOK_MASK:
+ NEED(mask, "tok_mask");
NEED1("mask needs mask specifier\n");
/*
* per-flow queue, mask is dst_ip, dst_port,
@@ -764,7 +897,7 @@ ipfw_config_pipe(int ac, char **av)
*/
par = NULL;
- bzero(&p.fs.flow_mask, sizeof(p.fs.flow_mask));
+ bzero(mask, sizeof(*mask));
end = NULL;
while (ac >= 1) {
@@ -780,44 +913,55 @@ ipfw_config_pipe(int ac, char **av)
case TOK_ALL:
/*
* special case, all bits significant
+ * except 'extra' (the queue number)
*/
- p.fs.flow_mask.dst_ip = ~0;
- p.fs.flow_mask.src_ip = ~0;
- p.fs.flow_mask.dst_port = ~0;
- p.fs.flow_mask.src_port = ~0;
- p.fs.flow_mask.proto = ~0;
- n2mask(&(p.fs.flow_mask.dst_ip6), 128);
- n2mask(&(p.fs.flow_mask.src_ip6), 128);
- p.fs.flow_mask.flow_id6 = ~0;
- p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
+ mask->dst_ip = ~0;
+ mask->src_ip = ~0;
+ mask->dst_port = ~0;
+ mask->src_port = ~0;
+ mask->proto = ~0;
+ n2mask(&mask->dst_ip6, 128);
+ n2mask(&mask->src_ip6, 128);
+ mask->flow_id6 = ~0;
+ *flags |= DN_HAVE_MASK;
+ goto end_mask;
+
+ case TOK_QUEUE:
+ mask->extra = ~0;
+ *flags |= DN_HAVE_MASK;
goto end_mask;
case TOK_DSTIP:
- p32 = &p.fs.flow_mask.dst_ip;
+ mask->addr_type = 4;
+ p32 = &mask->dst_ip;
break;
case TOK_SRCIP:
- p32 = &p.fs.flow_mask.src_ip;
+ mask->addr_type = 4;
+ p32 = &mask->src_ip;
break;
case TOK_DSTIP6:
- pa6 = &(p.fs.flow_mask.dst_ip6);
+ mask->addr_type = 6;
+ pa6 = &mask->dst_ip6;
break;
case TOK_SRCIP6:
- pa6 = &(p.fs.flow_mask.src_ip6);
+ mask->addr_type = 6;
+ pa6 = &mask->src_ip6;
break;
case TOK_FLOWID:
- p20 = &p.fs.flow_mask.flow_id6;
+ mask->addr_type = 6;
+ p20 = &mask->flow_id6;
break;
case TOK_DSTPORT:
- p16 = &p.fs.flow_mask.dst_port;
+ p16 = &mask->dst_port;
break;
case TOK_SRCPORT:
- p16 = &p.fs.flow_mask.src_port;
+ p16 = &mask->src_port;
break;
case TOK_PROTO:
@@ -857,10 +1001,10 @@ ipfw_config_pipe(int ac, char **av)
if (a > 0xFF)
errx(EX_DATAERR,
"proto mask must be 8 bit");
- p.fs.flow_mask.proto = (uint8_t)a;
+ mask->proto = (uint8_t)a;
}
if (a != 0)
- p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
+ *flags |= DN_HAVE_MASK;
ac--; av++;
} /* end while, config masks */
end_mask:
@@ -869,9 +1013,9 @@ end_mask:
case TOK_RED:
case TOK_GRED:
NEED1("red/gred needs w_q/min_th/max_th/max_p\n");
- p.fs.flags_fs |= DN_IS_RED;
+ fs->flags |= DN_IS_RED;
if (tok == TOK_GRED)
- p.fs.flags_fs |= DN_IS_GENTLE_RED;
+ fs->flags |= DN_IS_GENTLE_RED;
/*
* the format for parameters is w_q/min_th/max_th/max_p
*/
@@ -879,82 +1023,108 @@ end_mask:
double w_q = strtod(end, NULL);
if (w_q > 1 || w_q <= 0)
errx(EX_DATAERR, "0 < w_q <= 1");
- p.fs.w_q = (int) (w_q * (1 << SCALE_RED));
+ fs->w_q = (int) (w_q * (1 << SCALE_RED));
}
if ((end = strsep(&av[0], "/"))) {
- p.fs.min_th = strtoul(end, &end, 0);
+ fs->min_th = strtoul(end, &end, 0);
if (*end == 'K' || *end == 'k')
- p.fs.min_th *= 1024;
+ fs->min_th *= 1024;
}
if ((end = strsep(&av[0], "/"))) {
- p.fs.max_th = strtoul(end, &end, 0);
+ fs->max_th = strtoul(end, &end, 0);
if (*end == 'K' || *end == 'k')
- p.fs.max_th *= 1024;
+ fs->max_th *= 1024;
}
if ((end = strsep(&av[0], "/"))) {
double max_p = strtod(end, NULL);
if (max_p > 1 || max_p <= 0)
errx(EX_DATAERR, "0 < max_p <= 1");
- p.fs.max_p = (int)(max_p * (1 << SCALE_RED));
+ fs->max_p = (int)(max_p * (1 << SCALE_RED));
}
ac--; av++;
break;
case TOK_DROPTAIL:
- p.fs.flags_fs &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
+ NEED(fs, "droptail is only for flowsets");
+ fs->flags &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
break;
case TOK_BW:
+ NEED(p, "bw is only for links");
NEED1("bw needs bandwidth or interface\n");
- if (co.do_pipe != 1)
- errx(EX_DATAERR, "bandwidth only valid for pipes");
- read_bandwidth(av[0], &p.bandwidth, p.if_name, sizeof(p.if_name));
+ read_bandwidth(av[0], &p->bandwidth, NULL, 0);
ac--; av++;
break;
case TOK_DELAY:
- if (co.do_pipe != 1)
- errx(EX_DATAERR, "delay only valid for pipes");
+ NEED(p, "delay is only for links");
NEED1("delay needs argument 0..10000ms\n");
- p.delay = strtoul(av[0], NULL, 0);
+ p->delay = strtoul(av[0], NULL, 0);
+ ac--; av++;
+ break;
+
+ case TOK_TYPE: {
+ int l;
+ NEED(sch, "type is only for schedulers");
+ NEED1("type needs a string");
+ l = strlen(av[0]);
+ if (l == 0 || l > 15)
+ errx(1, "type %s too long\n", av[0]);
+ strcpy(sch->name, av[0]);
+ sch->oid.subtype = 0; /* use string */
ac--; av++;
break;
+ }
case TOK_WEIGHT:
- if (co.do_pipe == 1)
- errx(EX_DATAERR,"weight only valid for queues");
- NEED1("weight needs argument 0..100\n");
- p.fs.weight = strtoul(av[0], &end, 0);
+ NEED(fs, "weight is only for flowsets");
+ NEED1("weight needs argument\n");
+ fs->par[0] = strtol(av[0], &end, 0);
+ ac--; av++;
+ break;
+
+ case TOK_LMAX:
+ NEED(fs, "lmax is only for flowsets");
+ NEED1("lmax needs argument\n");
+ fs->par[1] = strtol(av[0], &end, 0);
ac--; av++;
break;
+ case TOK_PRI:
+ NEED(fs, "priority is only for flowsets");
+ NEED1("priority needs argument\n");
+ fs->par[2] = strtol(av[0], &end, 0);
+ ac--; av++;
+ break;
+
+ case TOK_SCHED:
case TOK_PIPE:
- if (co.do_pipe == 1)
- errx(EX_DATAERR,"pipe only valid for queues");
- NEED1("pipe needs pipe_number\n");
- p.fs.parent_nr = strtoul(av[0], &end, 0);
+ NEED(fs, "pipe/sched");
+ NEED1("pipe/link/sched needs number\n");
+ fs->sched_nr = strtoul(av[0], &end, 0);
ac--; av++;
break;
- case TOK_PIPE_PROFILE:
- if (co.do_pipe != 1)
- errx(EX_DATAERR, "extra delay only valid for pipes");
+ case TOK_PROFILE:
+ NEED((!pf), "profile already set");
+ NEED(p, "profile");
+ {
NEED1("extra delay needs the file name\n");
- p.samples = &samples[0];
- load_extra_delays(av[0], &p);
+ pf = o_next(&buf, sizeof(*pf), DN_PROFILE);
+ load_extra_delays(av[0], pf, p); //XXX can't fail?
--ac; ++av;
+ }
break;
case TOK_BURST:
- if (co.do_pipe != 1)
- errx(EX_DATAERR, "burst only valid for pipes");
+ NEED(p, "burst");
NEED1("burst needs argument\n");
errno = 0;
- if (expand_number(av[0], (int64_t *)&p.burst) < 0)
+ if (expand_number(av[0], (int64_t *)&p->burst) < 0)
if (errno != ERANGE)
errx(EX_DATAERR,
"burst: invalid argument");
- if (errno || p.burst > (1ULL << 48) - 1)
+ if (errno || p->burst > (1ULL << 48) - 1)
errx(EX_DATAERR,
"burst: out of range (0..2^48-1)");
ac--; av++;
@@ -964,26 +1134,17 @@ end_mask:
errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]);
}
}
- if (co.do_pipe == 1) {
- if (p.pipe_nr == 0)
- errx(EX_DATAERR, "pipe_nr must be > 0");
- if (p.delay > 10000)
- errx(EX_DATAERR, "delay must be < 10000");
- } else { /* co.do_pipe == 2, queue */
- if (p.fs.parent_nr == 0)
- errx(EX_DATAERR, "pipe must be > 0");
- if (p.fs.weight >100)
- errx(EX_DATAERR, "weight must be <= 100");
- }
- /* check for bandwidth value */
- if (p.bandwidth == -1) {
- p.bandwidth = 0;
- if (p.samples_no > 0)
- errx(EX_DATAERR, "profile requires a bandwidth limit");
+ /* check validity of parameters */
+ if (p) {
+ if (p->delay > 10000)
+ errx(EX_DATAERR, "delay must be < 10000");
+ if (p->bandwidth == -1)
+ p->bandwidth = 0;
}
-
- if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) {
+ if (fs) {
+ /* XXX accept a 0 scheduler to keep the default */
+ if (fs->flags & DN_QSIZE_BYTES) {
size_t len;
long limit;
@@ -991,9 +1152,9 @@ end_mask:
if (sysctlbyname("net.inet.ip.dummynet.pipe_byte_limit",
&limit, &len, NULL, 0) == -1)
limit = 1024*1024;
- if (p.fs.qsize > limit)
+ if (fs->qsize > limit)
errx(EX_DATAERR, "queue size must be < %ldB", limit);
- } else {
+ } else {
size_t len;
long limit;
@@ -1001,27 +1162,25 @@ end_mask:
if (sysctlbyname("net.inet.ip.dummynet.pipe_slot_limit",
&limit, &len, NULL, 0) == -1)
limit = 100;
- if (p.fs.qsize > limit)
+ if (fs->qsize > limit)
errx(EX_DATAERR, "2 <= queue size <= %ld", limit);
- }
- if (p.fs.flags_fs & DN_IS_RED) {
+ }
+
+ if (fs->flags & DN_IS_RED) {
size_t len;
int lookup_depth, avg_pkt_size;
- double s, idle, weight, w_q;
- struct clockinfo ck;
- int t;
+ double w_q;
- if (p.fs.min_th >= p.fs.max_th)
+ if (fs->min_th >= fs->max_th)
errx(EX_DATAERR, "min_th %d must be < than max_th %d",
- p.fs.min_th, p.fs.max_th);
- if (p.fs.max_th == 0)
+ fs->min_th, fs->max_th);
+ if (fs->max_th == 0)
errx(EX_DATAERR, "max_th must be > 0");
len = sizeof(int);
if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth",
&lookup_depth, &len, NULL, 0) == -1)
- errx(1, "sysctlbyname(\"%s\")",
- "net.inet.ip.dummynet.red_lookup_depth");
+ lookup_depth = 256;
if (lookup_depth == 0)
errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth"
" must be greater than zero");
@@ -1029,18 +1188,13 @@ end_mask:
len = sizeof(int);
if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
&avg_pkt_size, &len, NULL, 0) == -1)
+ avg_pkt_size = 512;
- errx(1, "sysctlbyname(\"%s\")",
- "net.inet.ip.dummynet.red_avg_pkt_size");
if (avg_pkt_size == 0)
errx(EX_DATAERR,
"net.inet.ip.dummynet.red_avg_pkt_size must"
" be greater than zero");
- len = sizeof(struct clockinfo);
- if (sysctlbyname("kern.clockrate", &ck, &len, NULL, 0) == -1)
- errx(1, "sysctlbyname(\"%s\")", "kern.clockrate");
-
/*
* Ticks needed for sending a medium-sized packet.
* Unfortunately, when we are configuring a WF2Q+ queue, we
@@ -1050,38 +1204,181 @@ end_mask:
* correct. But on the other hand, why do we want RED with
* WF2Q+ ?
*/
+#if 0
if (p.bandwidth==0) /* this is a WF2Q+ queue */
s = 0;
else
s = (double)ck.hz * avg_pkt_size * 8 / p.bandwidth;
-
+#endif
/*
* max idle time (in ticks) before avg queue size becomes 0.
* NOTA: (3/w_q) is approx the value x so that
* (1-w_q)^x < 10^-3.
*/
- w_q = ((double)p.fs.w_q) / (1 << SCALE_RED);
+ w_q = ((double)fs->w_q) / (1 << SCALE_RED);
+#if 0 // go in kernel
idle = s * 3. / w_q;
- p.fs.lookup_step = (int)idle / lookup_depth;
- if (!p.fs.lookup_step)
- p.fs.lookup_step = 1;
+ fs->lookup_step = (int)idle / lookup_depth;
+ if (!fs->lookup_step)
+ fs->lookup_step = 1;
weight = 1 - w_q;
- for (t = p.fs.lookup_step; t > 1; --t)
+ for (t = fs->lookup_step; t > 1; --t)
weight *= 1 - w_q;
- p.fs.lookup_weight = (int)(weight * (1 << SCALE_RED));
+ fs->lookup_weight = (int)(weight * (1 << SCALE_RED));
+#endif
+ }
}
- if (p.samples_no <= 0) {
- i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p);
- } else {
- struct dn_pipe_max pm;
- int len = sizeof(pm);
- memcpy(&pm.pipe, &p, sizeof(pm.pipe));
- memcpy(&pm.samples, samples, sizeof(pm.samples));
-
- i = do_cmd(IP_DUMMYNET_CONFIGURE, &pm, len);
- }
+ i = do_cmd(IP_DUMMYNET3, base, (char *)buf - (char *)base);
if (i)
err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
}
+
+void
+dummynet_flush(void)
+{
+ struct dn_id oid;
+ oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
+ do_cmd(IP_DUMMYNET3, &oid, oid.len);
+}
+
+/* Parse input for 'ipfw [pipe|sched|queue] show [range list]'
+ * Returns the number of ranges, and possibly stores them
+ * in the array v of size len.
+ */
+static int
+parse_range(int ac, char *av[], uint32_t *v, int len)
+{
+ int n = 0;
+ char *endptr, *s;
+ uint32_t base[2];
+
+ if (v == NULL || len < 2) {
+ v = base;
+ len = 2;
+ }
+
+ for (s = *av; s != NULL; av++, ac--) {
+ v[0] = strtoul(s, &endptr, 10);
+ v[1] = (*endptr != '-') ? v[0] :
+ strtoul(endptr+1, &endptr, 10);
+ if (*endptr == '\0') { /* prepare for next round */
+ s = (ac > 0) ? *(av+1) : NULL;
+ } else {
+ if (*endptr != ',') {
+ warn("invalid number: %s", s);
+ s = ++endptr;
+ continue;
+ }
+ /* continue processing from here */
+ s = ++endptr;
+ ac++;
+ av--;
+ }
+ if (v[1] < v[0] ||
+ v[1] < 0 || v[1] >= DN_MAX_ID-1 ||
+ v[0] < 0 || v[1] >= DN_MAX_ID-1) {
+ continue; /* invalid entry */
+ }
+ n++;
+ /* translate if 'pipe list' */
+ if (co.do_pipe == 1) {
+ v[0] += DN_MAX_ID;
+ v[1] += DN_MAX_ID;
+ }
+ v = (n*2 < len) ? v + 2 : base;
+ }
+ return n;
+}
+
+/* main entry point for dummynet list functions. co.do_pipe indicates
+ * which function we want to support.
+ * av may contain filtering arguments, either individual entries
+ * or ranges, or lists (space or commas are valid separators).
+ * Format for a range can be n1-n2 or n3 n4 n5 ...
+ * In a range n1 must be <= n2, otherwise the range is ignored.
+ * A number 'n4' is translate in a range 'n4-n4'
+ * All number must be > 0 and < DN_MAX_ID-1
+ */
+void
+dummynet_list(int ac, char *av[], int show_counters)
+{
+ struct dn_id *oid, *x = NULL;
+ int ret, i, l;
+ int n; /* # of ranges */
+ int buflen;
+ int max_size; /* largest obj passed up */
+
+ ac--;
+ av++; /* skip 'list' | 'show' word */
+
+ n = parse_range(ac, av, NULL, 0); /* Count # of ranges. */
+
+ /* Allocate space to store ranges */
+ l = sizeof(*oid) + sizeof(uint32_t) * n * 2;
+ oid = safe_calloc(1, l);
+ oid_fill(oid, l, DN_CMD_GET, DN_API_VERSION);
+
+ if (n > 0) /* store ranges in idx */
+ parse_range(ac, av, (uint32_t *)(oid + 1), n*2);
+ /*
+ * Compute the size of the largest object returned. If the
+ * response leaves at least this much spare space in the
+ * buffer, then surely the response is complete; otherwise
+ * there might be a risk of truncation and we will need to
+ * retry with a larger buffer.
+ * XXX don't bother with smaller structs.
+ */
+ max_size = sizeof(struct dn_fs);
+ if (max_size < sizeof(struct dn_sch))
+ max_size = sizeof(struct dn_sch);
+ if (max_size < sizeof(struct dn_flow))
+ max_size = sizeof(struct dn_flow);
+
+ switch (co.do_pipe) {
+ case 1:
+ oid->subtype = DN_LINK; /* list pipe */
+ break;
+ case 2:
+ oid->subtype = DN_FS; /* list queue */
+ break;
+ case 3:
+ oid->subtype = DN_SCH; /* list sched */
+ break;
+ }
+
+ /*
+ * Ask the kernel an estimate of the required space (result
+ * in oid.id), unless we are requesting a subset of objects,
+ * in which case the kernel does not give an exact answer.
+ * In any case, space might grow in the meantime due to the
+ * creation of new queues, so we must be prepared to retry.
+ */
+ if (n > 0) {
+ buflen = 4*1024;
+ } else {
+ ret = do_cmd(-IP_DUMMYNET3, oid, (uintptr_t)&l);
+ if (ret != 0 || oid->id <= sizeof(*oid))
+ goto done;
+ buflen = oid->id + max_size;
+ oid->len = sizeof(*oid); /* restore */
+ }
+ /* Try a few times, until the buffer fits */
+ for (i = 0; i < 20; i++) {
+ l = buflen;
+ x = safe_realloc(x, l);
+ bcopy(oid, x, oid->len);
+ ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l);
+ if (ret != 0 || x->id <= sizeof(*oid))
+ goto done; /* no response */
+ if (l + max_size <= buflen)
+ break; /* ok */
+ buflen *= 2; /* double for next attempt */
+ }
+ list_pipes(x, O_NEXT(x, l));
+done:
+ if (x)
+ free(x);
+ free(oid);
+}
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index fc83ecc..01dad12 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,13 +1,15 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 24, 2009
+.Dd March 20, 2010
.Dt IPFW 8
.Os
.Sh NAME
.Nm ipfw
-.Nd IP firewall and traffic shaper control program
+.Nd User interface for firewall, traffic shaper, packet scheduler,
+in-kernel NAT.
.Sh SYNOPSIS
+.Ss FIREWALL CONFIGURATION
.Nm
.Op Fl cq
.Cm add
@@ -26,12 +28,6 @@
.Op Cm set Ar N
.Brq Cm delete | zero | resetlog
.Op Ar number ...
-.Nm
-.Cm enable
-.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
-.Nm
-.Cm disable
-.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
.Pp
.Nm
.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
@@ -43,8 +39,17 @@
.Cm set swap Ar number number
.Nm
.Cm set show
+.Ss SYSCTL SHORTCUTS
.Pp
.Nm
+.Cm enable
+.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
+.Nm
+.Cm disable
+.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
+.Pp
+.Ss LOOKUP TABLES
+.Nm
.Cm table Ar number Cm add Ar addr Ns Oo / Ns Ar masklen Oc Op Ar value
.Nm
.Cm table Ar number Cm delete Ar addr Ns Op / Ns Ar masklen
@@ -57,17 +62,19 @@
.Brq Ar number | all
.Cm list
.Pp
+.Ss DUMMYNET CONFIGURATION (TRAFFIC SHAPER AND PACKET SCHEDULER)
.Nm
-.Brq Cm pipe | queue
+.Brq Cm pipe | queue | sched
.Ar number
.Cm config
.Ar config-options
.Nm
.Op Fl s Op Ar field
-.Brq Cm pipe | queue
+.Brq Cm pipe | queue | sched
.Brq Cm delete | list | show
.Op Ar number ...
.Pp
+.Ss IN-KERNEL NAT
.Nm
.Op Fl q
.Cm nat
@@ -89,28 +96,27 @@ The
.Nm
utility is the user interface for controlling the
.Xr ipfw 4
-firewall and the
+firewall, the
.Xr dummynet 4
-traffic shaper in
-.Fx .
+traffic shaper/packet scheduler, and the
+in-kernel NAT services.
.Pp
-An
-.Nm
-configuration, or
+A firewall configuration, or
.Em ruleset ,
is made of a list of
.Em rules
numbered from 1 to 65535.
-Packets are passed to
-.Nm
+Packets are passed to the firewall
from a number of different places in the protocol stack
(depending on the source and destination of the packet,
-it is possible that
-.Nm
-is invoked multiple times on the same packet).
+it is possible for the firewall to be
+invoked multiple times on the same packet).
The packet passed to the firewall is compared
-against each of the rules in the firewall
-.Em ruleset .
+against each of the rules in the
+.Em ruleset ,
+in rule-number order
+(multiple rules with the same number are permitted, in which case
+they are processed in order of insertion).
When a match is found, the action corresponding to the
matching rule is performed.
.Pp
@@ -118,9 +124,7 @@ Depending on the action and certain system settings, packets
can be reinjected into the firewall at some rule after the
matching one for further processing.
.Pp
-An
-.Nm
-ruleset always includes a
+A ruleset always includes a
.Em default
rule (numbered 65535) which cannot be modified or deleted,
and matches all packets.
@@ -137,14 +141,14 @@ If the ruleset includes one or more rules with the
or
.Cm limit
option,
-.Nm
-will have a
+the firewall will have a
.Em stateful
-behaviour, i.e., upon a match it will create dynamic rules matching
-the exact parameters (source and destination addresses and ports)
-of the matching packet.
-.Pp
-These dynamic rules, which have a limited lifetime, are checked
+behaviour, i.e., upon a match it will create
+.Em dynamic rules ,
+i.e. rules that match packets with the same 5-tuple
+(protocol, source and destination addresses and ports)
+as the packet which caused their creation.
+Dynamic rules, which have a limited lifetime, are checked
at the first occurrence of a
.Cm check-state ,
.Cm keep-state
@@ -283,6 +287,7 @@ When listing, show last match timestamp as seconds from the epoch.
This form can be more convenient for postprocessing by scripts.
.El
.Pp
+.Ss LIST OF RULES AND PREPROCESSING
To ease configuration, rules can be put into a file which is
processed using
.Nm
@@ -322,14 +327,16 @@ This allows for flexible configuration files (like conditionalizing
them on the local hostname) and the use of macros to centralize
frequently required arguments like IP addresses.
.Pp
+.Ss TRAFFIC SHAPER CONFIGURATION
The
.Nm
-.Cm pipe
+.Cm pipe , queue
and
-.Cm queue
-commands are used to configure the traffic shaper, as shown in the
+.Cm sched
+commands are used to configure the traffic shaper and packet scheduler.
+See the
.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
-Section below.
+Section below for details.
.Pp
If the world and the kernel get out of sync the
.Nm
@@ -362,7 +369,7 @@ have this picture in mind in order to design a correct ruleset.
| to devices |
.Ed
.Pp
-As can be noted from the above picture, the number of
+The number of
times the same packet goes through the firewall can
vary between 0 and 4 depending on packet source and
destination, and system configuration.
@@ -421,9 +428,9 @@ Keywords are case-sensitive, whereas arguments may
or may not be case-sensitive depending on their nature
(e.g.\& uid's are, hostnames are not).
.Pp
-In
-.Nm ipfw2
-you can introduce spaces after commas ',' to make
+Some arguments (e.g. port or address lists) are comma-separated
+lists of values.
+In this case, spaces after commas ',' are allowed to make
the line more readable.
You can also put the entire
command (including flags) into a single argument.
@@ -434,9 +441,7 @@ ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8
ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8"
.Ed
.Sh RULE FORMAT
-The format of
-.Nm
-rules is the following:
+The format of firewall rules is the following:
.Bd -ragged -offset indent
.Bk -words
.Op Ar rule_number
@@ -496,7 +501,7 @@ in future forwarding decisions.
.El
.Pp
Note that some of the above information, e.g.\& source MAC or IP addresses and
-TCP/UDP ports, could easily be spoofed, so filtering on those fields
+TCP/UDP ports, can be easily spoofed, so filtering on those fields
alone might not guarantee the desired results.
.Bl -tag -width indent
.It Ar rule_number
@@ -1399,7 +1404,7 @@ If not found, the match fails.
Otherwise, the match succeeds and
.Cm tablearg
is set to the value extracted from the table.
-.Br
+.Pp
This option can be useful to quickly dispatch traffic based on
certain packet fields.
See the
@@ -1496,7 +1501,7 @@ is invalid) whenever
.Cm xmit
is used.
.Pp
-A packet may not have a receive or transmit interface: packets
+A packet might not have a receive or transmit interface: packets
originating from the local host have no receive interface,
while packets destined for the local host have no transmit
interface.
@@ -1643,15 +1648,17 @@ because it engages only on packets with source addresses of directly
connected networks instead of all source addresses.
.El
.Sh LOOKUP TABLES
-Lookup tables are useful to handle large sparse address sets,
-typically from a hundred to several thousands of entries.
+Lookup tables are useful to handle large sparse sets of
+addresses or other search keys (e.g. ports, jail IDs).
+In the rest of this section we will use the term ``address''
+to mean any unsigned value of up to 32-bit.
There may be up to 128 different lookup tables, numbered 0 to 127.
.Pp
Each entry is represented by an
.Ar addr Ns Op / Ns Ar masklen
and will match all addresses with base
.Ar addr
-(specified as an IP address or a hostname)
+(specified as an IP address, a hostname or an unsigned integer)
and mask width of
.Ar masklen
bits.
@@ -1669,9 +1676,9 @@ is not specified, it defaults to 0.
.Pp
An entry can be added to a table
.Pq Cm add ,
-removed from a table
-.Pq Cm delete ,
-a table can be examined
+or removed from a table
+.Pq Cm delete .
+A table can be examined
.Pq Cm list
or flushed
.Pq Cm flush .
@@ -1680,7 +1687,7 @@ Internally, each table is stored in a Radix tree, the same way as
the routing table (see
.Xr route 4 ) .
.Pp
-Lookup tables currently support IPv4 addresses only.
+Lookup tables currently support only ports, jail IDs and IPv4 addresses.
.Pp
The
.Cm tablearg
@@ -1838,9 +1845,9 @@ for more examples on how to use dynamic rules.
.Nm
is also the user interface for the
.Nm dummynet
-traffic shaper and network emulator, a subsystem that
+traffic shaper, packet scheduler and network emulator, a subsystem that
can artificially queue, delay or drop packets
-emulator the behaviour of certain network links
+emulating the behaviour of certain network links
or queueing systems.
.Pp
.Nm dummynet
@@ -1852,26 +1859,33 @@ Matching packets are then passed to either of two
different objects, which implement the traffic regulation:
.Bl -hang -offset XXXX
.It Em pipe
-A pipe emulates a link with given bandwidth, propagation delay,
+A
+.Em pipe
+emulates a
+.Em link
+with given bandwidth and propagation delay,
+driven by a FIFO scheduler and a single queue with programmable
queue size and packet loss rate.
-Packets are queued in front of the pipe as they come out from the classifier,
-and then transferred to the pipe according to the pipe's parameters.
+Packets are appended to the queue as they come out from
+.Nm ipfw ,
+and then transferred in FIFO order to the link at the desired rate.
.It Em queue
-A queue
-is an abstraction used to implement the WF2Q+
-(Worst-case Fair Weighted Fair Queueing) policy, which is
-an efficient variant of the WFQ policy.
-.Pp
-The queue associates a
-.Em weight
-and a reference pipe to each flow (a flow is a set of packets
-with the same addresses and ports after masking).
-All backlogged flows (i.e., those
-with packets queued) linked to the same pipe share the pipe's
-bandwidth proportionally to their weights.
-Note that weights are not priorities; a flow with a lower weight
-is still guaranteed to get its fraction of the bandwidth even if a
-flow with a higher weight is permanently backlogged.
+A
+.Em queue
+is an abstraction used to implement packet scheduling
+using one of several packet scheduling algorithms.
+Packets sent to a
+.Em queue
+are first grouped into flows according to a mask on the 5-tuple.
+Flows are then passed to the scheduler associated to the
+.Em queue ,
+and each flow uses scheduling parameters (weight and others)
+as configured in the
+.Em queue
+itself.
+A scheduler in turn is connected to an emulated link,
+and arbitrates the link's bandwidth among backlogged flows according to
+weights and to the features of the scheduling algorithm in use.
.El
.Pp
In practice,
@@ -1880,6 +1894,52 @@ can be used to set hard limits to the bandwidth that a flow can use, whereas
.Em queues
can be used to determine how different flows share the available bandwidth.
.Pp
+A graphical representation of the binding of queues,
+flows, schedulers and links is below.
+.Bd -literal -offset indent
+ (flow_mask|sched_mask) sched_mask
+ +---------+ weight Wx +-------------+
+ | |->-[flow]-->--| |-+
+ -->--| QUEUE x | ... | | |
+ | |->-[flow]-->--| SCHEDuler N | |
+ +---------+ | | |
+ ... | +--[LINK N]-->--
+ +---------+ weight Wy | | +--[LINK N]-->--
+ | |->-[flow]-->--| | |
+ -->--| QUEUE y | ... | | |
+ | |->-[flow]-->--| | |
+ +---------+ +-------------+ |
+ +-------------+
+.Ed
+It is important to understand the role of the SCHED_MASK
+and FLOW_MASK, which are configured through the commands
+.Dl "ipfw sched N config mask SCHED_MASK ..."
+and
+.Dl "ipfw queue X config mask FLOW_MASK ..." .
+.Pp
+The SCHED_MASK is used to assign flows to one or more
+scheduler instances, one for each
+value of the packet's 5-fuple after applying SCHED_MASK.
+As an example, using ``src-ip 0xffffff00'' creates one instance
+for each /24 destination subnet.
+.Pp
+The FLOW_MASK, together with the SCHED_MASK, is used to split
+packets into flows. As an example, using
+``src-ip 0x000000ff''
+together with the previous SCHED_MASK makes a flow for
+each individual source address. In turn, flows for each /24
+subnet will be sent to the same scheduler instance.
+.Pp
+The above diagram holds even for the
+.Em pipe
+case, with the only restriction that a
+.Em pipe
+only supports a SCHED_MASK, and forces the use of a FIFO
+scheduler (these are for backward compatibility reasons;
+in fact, internally, a
+.Nm dummynet's
+pipe is implemented exactly as above).
+.Pp
There are two modes of
.Nm dummynet
operation:
@@ -1911,16 +1971,19 @@ mode can be enabled by setting the
.Xr sysctl 8
variable to a non-zero value.
.Pp
-.Ss PIPE AND QUEUE CONFIGURATION
+.Ss PIPE, QUEUE AND SCHEDULER CONFIGURATION
The
-.Em pipe
-and
+.Em pipe ,
.Em queue
+and
+.Em scheduler
configuration commands are the following:
.Bd -ragged -offset indent
.Cm pipe Ar number Cm config Ar pipe-configuration
.Pp
.Cm queue Ar number Cm config Ar queue-configuration
+.Pp
+.Cm sched Ar number Cm config Ar sched-configuration
.Ed
.Pp
The following parameters can be configured for a pipe:
@@ -2073,6 +2136,41 @@ Specifies the weight to be used for flows matching this queue.
The weight must be in the range 1..100, and defaults to 1.
.El
.Pp
+The following parameters can be configured for a scheduler:
+.Pp
+.Bl -tag -width indent -compact
+.It Cm type Ar {fifo | wf2qp | rr | qfq}
+specifies the scheduling algorithm to use.
+.Bl -tag -width indent -compact
+.It cm fifo
+is just a FIFO scheduler (which means that all packets
+are stored in the same queue as they arrive to the scheduler).
+FIFO has O(1) per-packet time complexity, with very low
+constants (estimate 60-80ns on a 2Ghz desktop machine)
+but gives no service guarantees.
+.It Cm wf2qp
+implements the WF2Q+ algorithm, which is a Weighted Fair Queueing
+algorithm which permits flows to share bandwidth according to
+their weights. Note that weights are not priorities; even a flow
+with a minuscule weight will never starve.
+WF2Q+ has O(log N) per-packet processing cost, where N is the number
+of flows, and is the default algorithm used by previous versions
+dummynet's queues.
+.It Cm rr
+implements the Deficit Round Robin algorithm, which has O(1) processing
+costs (roughly, 100-150ns per packet)
+and permits bandwidth allocation according to weights, but
+with poor service guarantees.
+.It Cm qfq
+implements the QFQ algorithm, which is a very fast variant of
+WF2Q+, with similar service guarantees and O(1) processing
+costs (roughly, 200-250ns per packet).
+.El
+.El
+.Pp
+In addition to the type, all parameters allowed for a pipe can also
+be specified for a scheduler.
+.Pp
Finally, the following parameters can be configured for both
pipes and queues:
.Pp
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index d4740c9..f313b51 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -57,7 +57,7 @@ struct cmdline_opts co; /* global options */
int resvd_set_number = RESVD_SET;
#define GET_UINT_ARG(arg, min, max, tok, s_x) do { \
- if (!ac) \
+ if (!av[0]) \
errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \
if (_substrcmp(*av, "tablearg") == 0) { \
arg = IP_FW_TABLEARG; \
@@ -65,23 +65,23 @@ int resvd_set_number = RESVD_SET;
} \
\
{ \
- long val; \
+ long _xval; \
char *end; \
\
- val = strtol(*av, &end, 10); \
+ _xval = strtol(*av, &end, 10); \
\
- if (!isdigit(**av) || *end != '\0' || (val == 0 && errno == EINVAL)) \
+ if (!isdigit(**av) || *end != '\0' || (_xval == 0 && errno == EINVAL)) \
errx(EX_DATAERR, "%s: invalid argument: %s", \
match_value(s_x, tok), *av); \
\
- if (errno == ERANGE || val < min || val > max) \
+ if (errno == ERANGE || _xval < min || _xval > max) \
errx(EX_DATAERR, "%s: argument is out of range (%u..%u): %s", \
match_value(s_x, tok), min, max, *av); \
\
- if (val == IP_FW_TABLEARG) \
+ if (_xval == IP_FW_TABLEARG) \
errx(EX_DATAERR, "%s: illegal argument value: %s", \
match_value(s_x, tok), *av); \
- arg = val; \
+ arg = _xval; \
} \
} while (0)
@@ -231,7 +231,7 @@ static struct _s_x rule_action_params[] = {
*/
static int lookup_key[] = {
TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT,
- TOK_UID, TOK_JAIL, -1 };
+ TOK_UID, TOK_JAIL, TOK_DSCP, -1 };
static struct _s_x rule_options[] = {
{ "tagged", TOK_TAGGED },
@@ -258,6 +258,7 @@ static struct _s_x rule_options[] = {
{ "iplen", TOK_IPLEN },
{ "ipid", TOK_IPID },
{ "ipprecedence", TOK_IPPRECEDENCE },
+ { "dscp", TOK_DSCP },
{ "iptos", TOK_IPTOS },
{ "ipttl", TOK_IPTTL },
{ "ipversion", TOK_IPVER },
@@ -313,22 +314,29 @@ static struct _s_x rule_options[] = {
{ NULL, 0 } /* terminator */
};
-/*
- * The following is used to generate a printable argument for
- * 64-bit numbers, irrespective of platform alignment and bit size.
- * Because all the printf in this program use %llu as a format,
- * we just return an unsigned long long, which is larger than
- * we need in certain cases, but saves the hassle of using
- * PRIu64 as a format specifier.
- * We don't care about inlining, this is not performance critical code.
+/*
+ * Helper routine to print a possibly unaligned uint64_t on
+ * various platform. If width > 0, print the value with
+ * the desired width, followed by a space;
+ * otherwise, return the required width.
*/
-unsigned long long
-align_uint64(const uint64_t *pll)
+int
+pr_u64(uint64_t *pd, int width)
{
- uint64_t ret;
-
- bcopy (pll, &ret, sizeof(ret));
- return ret;
+#ifdef TCC
+#define U64_FMT "I64"
+#else
+#define U64_FMT "llu"
+#endif
+ uint64_t u;
+ unsigned long long d;
+
+ bcopy (pd, &u, sizeof(u));
+ d = u;
+ return (width > 0) ?
+ printf("%*" U64_FMT " ", width, d) :
+ snprintf(NULL, 0, "%" U64_FMT, d) ;
+#undef U64_FMT
}
void *
@@ -353,6 +361,7 @@ safe_realloc(void *ptr, size_t size)
/*
* conditionally runs the command.
+ * Selected options or negative -> getsockopt
*/
int
do_cmd(int optname, void *optval, uintptr_t optlen)
@@ -372,11 +381,15 @@ do_cmd(int optname, void *optval, uintptr_t optlen)
optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST ||
optname == IP_FW_TABLE_GETSIZE ||
optname == IP_FW_NAT_GET_CONFIG ||
- optname == IP_FW_NAT_GET_LOG)
+ optname < 0 ||
+ optname == IP_FW_NAT_GET_LOG) {
+ if (optname < 0)
+ optname = -optname;
i = getsockopt(s, IPPROTO_IP, optname, optval,
(socklen_t *)optlen);
- else
+ } else {
i = setsockopt(s, IPPROTO_IP, optname, optval, optlen);
+ }
return i;
}
@@ -749,7 +762,7 @@ static void
print_ip(ipfw_insn_ip *cmd, char const *s)
{
struct hostent *he = NULL;
- int len = F_LEN((ipfw_insn *)cmd);
+ uint32_t len = F_LEN((ipfw_insn *)cmd);
uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) {
@@ -915,9 +928,9 @@ print_icmptypes(ipfw_insn_u32 *cmd)
#define HAVE_DSTIP 0x0004
#define HAVE_PROTO4 0x0008
#define HAVE_PROTO6 0x0010
+#define HAVE_IP 0x0100
#define HAVE_OPTIONS 0x8000
-#define HAVE_IP (HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP)
static void
show_prerequisites(int *flags, int want, int cmd __unused)
{
@@ -967,9 +980,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
}
printf("%05u ", rule->rulenum);
- if (pcwidth>0 || bcwidth>0)
- printf("%*llu %*llu ", pcwidth, align_uint64(&rule->pcnt),
- bcwidth, align_uint64(&rule->bcnt));
+ if (pcwidth > 0 || bcwidth > 0) {
+ pr_u64(&rule->pcnt, pcwidth);
+ pr_u64(&rule->bcnt, bcwidth);
+ }
if (co.do_time == 2)
printf("%10u ", rule->timestamp);
@@ -1018,7 +1032,9 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
switch(cmd->opcode) {
case O_CHECK_STATE:
printf("check-state");
- flags = HAVE_IP; /* avoid printing anything else */
+ /* avoid printing anything else */
+ flags = HAVE_PROTO | HAVE_SRCIP |
+ HAVE_DSTIP | HAVE_IP;
break;
case O_ACCEPT:
@@ -1126,9 +1142,11 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
else
printf(" log");
}
+#ifndef NO_ALTQ
if (altqptr) {
print_altq_cmd(altqptr);
}
+#endif
if (tagptr) {
if (tagptr->len & F_NOT)
PRINT_UINT_ARG(" untag ", tagptr->arg1);
@@ -1156,7 +1174,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
show_prerequisites(&flags, HAVE_PROTO, 0);
printf(" from any to any");
}
- flags |= HAVE_IP | HAVE_OPTIONS;
+ flags |= HAVE_IP | HAVE_OPTIONS | HAVE_PROTO |
+ HAVE_SRCIP | HAVE_DSTIP;
}
if (co.comment_only)
@@ -1245,9 +1264,12 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
break;
case O_IP_DSTPORT:
- show_prerequisites(&flags, HAVE_IP, 0);
+ show_prerequisites(&flags,
+ HAVE_PROTO | HAVE_SRCIP |
+ HAVE_DSTIP | HAVE_IP, 0);
case O_IP_SRCPORT:
- show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0);
+ show_prerequisites(&flags,
+ HAVE_PROTO | HAVE_SRCIP, 0);
if ((cmd->len & F_OR) && !or_block)
printf(" {");
if (cmd->len & F_NOT)
@@ -1268,7 +1290,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
if ((flags & (HAVE_PROTO4 | HAVE_PROTO6)) &&
!(flags & HAVE_PROTO))
show_prerequisites(&flags,
- HAVE_IP | HAVE_OPTIONS, 0);
+ HAVE_PROTO | HAVE_IP | HAVE_SRCIP |
+ HAVE_DSTIP | HAVE_OPTIONS, 0);
if (flags & HAVE_OPTIONS)
printf(" proto");
if (pe)
@@ -1286,7 +1309,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
((cmd->opcode == O_IP4) &&
(flags & HAVE_PROTO4)))
break;
- show_prerequisites(&flags, HAVE_IP | HAVE_OPTIONS, 0);
+ show_prerequisites(&flags, HAVE_PROTO | HAVE_SRCIP |
+ HAVE_DSTIP | HAVE_IP | HAVE_OPTIONS, 0);
if ((cmd->len & F_OR) && !or_block)
printf(" {");
if (cmd->len & F_NOT && cmd->opcode != O_IN)
@@ -1540,7 +1564,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
or_block = 0;
}
}
- show_prerequisites(&flags, HAVE_IP, 0);
+ show_prerequisites(&flags, HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP
+ | HAVE_IP, 0);
if (comment)
printf(" // %s", comment);
printf("\n");
@@ -1560,10 +1585,12 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth)
}
bcopy(&d->rule, &rulenum, sizeof(rulenum));
printf("%05d", rulenum);
- if (pcwidth>0 || bcwidth>0)
- printf(" %*llu %*llu (%ds)", pcwidth,
- align_uint64(&d->pcnt), bcwidth,
- align_uint64(&d->bcnt), d->expire);
+ if (pcwidth > 0 || bcwidth > 0) {
+ printf(" ");
+ pr_u64(&d->pcnt, pcwidth);
+ pr_u64(&d->bcnt, bcwidth);
+ printf("(%ds)", d->expire);
+ }
switch (d->dyn_type) {
case O_LIMIT_PARENT:
printf(" PARENT %d", d->count);
@@ -1606,26 +1633,33 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth)
* ipfw set move rule X to Y
*/
void
-ipfw_sets_handler(int ac, char *av[])
+ipfw_sets_handler(char *av[])
{
uint32_t set_disable, masks[2];
int i, nbytes;
uint16_t rulenum;
uint8_t cmd, new_set;
- ac--;
av++;
- if (!ac)
+ if (av[0] == NULL)
errx(EX_USAGE, "set needs command");
if (_substrcmp(*av, "show") == 0) {
- void *data;
+ void *data = NULL;
char const *msg;
+ int nalloc;
+
+ nalloc = nbytes = sizeof(struct ip_fw);
+ while (nbytes >= nalloc) {
+ if (data)
+ free(data);
+ nalloc = nalloc * 2 + 200;
+ nbytes = nalloc;
+ data = safe_calloc(1, nbytes);
+ if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0)
+ err(EX_OSERR, "getsockopt(IP_FW_GET)");
+ }
- nbytes = sizeof(struct ip_fw);
- data = safe_calloc(1, nbytes);
- if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0)
- err(EX_OSERR, "getsockopt(IP_FW_GET)");
bcopy(&((struct ip_fw *)data)->next_rule,
&set_disable, sizeof(set_disable));
@@ -1642,8 +1676,8 @@ ipfw_sets_handler(int ac, char *av[])
}
printf("\n");
} else if (_substrcmp(*av, "swap") == 0) {
- ac--; av++;
- if (ac != 2)
+ av++;
+ if ( av[0] == NULL || av[1] == NULL )
errx(EX_USAGE, "set swap needs 2 set numbers\n");
rulenum = atoi(av[0]);
new_set = atoi(av[1]);
@@ -1654,13 +1688,14 @@ ipfw_sets_handler(int ac, char *av[])
masks[0] = (4 << 24) | (new_set << 16) | (rulenum);
i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t));
} else if (_substrcmp(*av, "move") == 0) {
- ac--; av++;
- if (ac && _substrcmp(*av, "rule") == 0) {
+ av++;
+ if (av[0] && _substrcmp(*av, "rule") == 0) {
cmd = 2;
- ac--; av++;
+ av++;
} else
cmd = 3;
- if (ac != 3 || _substrcmp(av[1], "to") != 0)
+ if (av[0] == NULL || av[1] == NULL || av[2] == NULL ||
+ av[3] != NULL || _substrcmp(av[1], "to") != 0)
errx(EX_USAGE, "syntax: set move [rule] X to Y\n");
rulenum = atoi(av[0]);
new_set = atoi(av[2]);
@@ -1675,10 +1710,10 @@ ipfw_sets_handler(int ac, char *av[])
_substrcmp(*av, "enable") == 0 ) {
int which = _substrcmp(*av, "enable") == 0 ? 1 : 0;
- ac--; av++;
+ av++;
masks[0] = masks[1] = 0;
- while (ac) {
+ while (av[0]) {
if (isdigit(**av)) {
i = atoi(*av);
if (i < 0 || i > RESVD_SET)
@@ -1692,7 +1727,7 @@ ipfw_sets_handler(int ac, char *av[])
else
errx(EX_DATAERR,
"invalid set command %s\n", *av);
- av++; ac--;
+ av++;
}
if ( (masks[0] & masks[1]) != 0 )
errx(EX_DATAERR,
@@ -1706,16 +1741,17 @@ ipfw_sets_handler(int ac, char *av[])
}
void
-ipfw_sysctl_handler(int ac, char *av[], int which)
+ipfw_sysctl_handler(char *av[], int which)
{
- ac--;
av++;
- if (ac == 0) {
+ if (av[0] == NULL) {
warnx("missing keyword to enable/disable\n");
} else if (_substrcmp(*av, "firewall") == 0) {
sysctlbyname("net.inet.ip.fw.enable", NULL, 0,
&which, sizeof(which));
+ sysctlbyname("net.inet6.ip6.fw.enable", NULL, 0,
+ &which, sizeof(which));
} else if (_substrcmp(*av, "one_pass") == 0) {
sysctlbyname("net.inet.ip.fw.one_pass", NULL, 0,
&which, sizeof(which));
@@ -1728,8 +1764,10 @@ ipfw_sysctl_handler(int ac, char *av[], int which)
} else if (_substrcmp(*av, "dyn_keepalive") == 0) {
sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0,
&which, sizeof(which));
+#ifndef NO_ALTQ
} else if (_substrcmp(*av, "altq") == 0) {
altq_set_enabled(which);
+#endif
} else {
warnx("unrecognize enable/disable keyword: %s\n", *av);
}
@@ -1762,6 +1800,10 @@ ipfw_list(int ac, char *av[], int show_counters)
fprintf(stderr, "Testing only, list disabled\n");
return;
}
+ if (co.do_pipe) {
+ dummynet_list(ac, av, show_counters);
+ return;
+ }
ac--;
av++;
@@ -1778,11 +1820,6 @@ ipfw_list(int ac, char *av[], int show_counters)
co.do_pipe ? "DUMMYNET" : "FW");
}
- if (co.do_pipe) {
- ipfw_list_pipes(data, nbytes, ac, av);
- goto done;
- }
-
/*
* Count static rules. They have variable size so we
* need to scan the list to count them.
@@ -1810,14 +1847,12 @@ ipfw_list(int ac, char *av[], int show_counters)
continue;
/* packet counter */
- width = snprintf(NULL, 0, "%llu",
- align_uint64(&r->pcnt));
+ width = pr_u64(&r->pcnt, 0);
if (width > pcwidth)
pcwidth = width;
/* byte counter */
- width = snprintf(NULL, 0, "%llu",
- align_uint64(&r->bcnt));
+ width = pr_u64(&r->bcnt, 0);
if (width > bcwidth)
bcwidth = width;
}
@@ -1831,13 +1866,11 @@ ipfw_list(int ac, char *av[], int show_counters)
if (set != co.use_set - 1)
continue;
}
- width = snprintf(NULL, 0, "%llu",
- align_uint64(&d->pcnt));
+ width = pr_u64(&d->pcnt, 0);
if (width > pcwidth)
pcwidth = width;
- width = snprintf(NULL, 0, "%llu",
- align_uint64(&d->bcnt));
+ width = pr_u64(&d->bcnt, 0);
if (width > bcwidth)
bcwidth = width;
}
@@ -2130,7 +2163,7 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
return;
}
/* A single IP can be stored in an optimized format */
- if (d[1] == ~0 && av == NULL && len == 0) {
+ if (d[1] == (uint32_t)~0 && av == NULL && len == 0) {
cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32);
return;
}
@@ -2199,29 +2232,28 @@ fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode,
void
-ipfw_delete(int ac, char *av[])
+ipfw_delete(char *av[])
{
uint32_t rulenum;
int i;
int exitval = EX_OK;
int do_set = 0;
-
- av++; ac--;
+ av++;
NEED1("missing rule specification");
- if (ac > 0 && _substrcmp(*av, "set") == 0) {
+ if ( *av && _substrcmp(*av, "set") == 0) {
/* Do not allow using the following syntax:
* ipfw set N delete set M
*/
if (co.use_set)
errx(EX_DATAERR, "invalid syntax");
do_set = 1; /* delete set */
- ac--; av++;
+ av++;
}
/* Rule number */
- while (ac && isdigit(**av)) {
- i = atoi(*av); av++; ac--;
+ while (*av && isdigit(**av)) {
+ i = atoi(*av); av++;
if (co.do_nat) {
exitval = do_cmd(IP_FW_NAT_DEL, &i, sizeof i);
if (exitval) {
@@ -2275,7 +2307,8 @@ fill_iface(ipfw_insn_if *cmd, char *arg)
static void
get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
{
- int i, l;
+ int i;
+ size_t l;
char *ap, *ptr, *optr;
struct ether_addr *mac;
const char *macset = "0123456789abcdefABCDEF:";
@@ -2297,11 +2330,11 @@ get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
if (ptr != NULL) { /* we have mask? */
if (p[ptr - optr - 1] == '/') { /* mask len */
- l = strtol(ptr, &ap, 10);
- if (*ap != 0 || l > ETHER_ADDR_LEN * 8 || l < 0)
+ long ml = strtol(ptr, &ap, 10);
+ if (*ap != 0 || ml > ETHER_ADDR_LEN * 8 || ml < 0)
errx(EX_DATAERR, "Incorrect mask length");
- for (i = 0; l > 0 && i < ETHER_ADDR_LEN; l -= 8, i++)
- mask[i] = (l >= 8) ? 0xff: (~0) << (8 - l);
+ for (i = 0; ml > 0 && i < ETHER_ADDR_LEN; ml -= 8, i++)
+ mask[i] = (ml >= 8) ? 0xff: (~0) << (8 - ml);
} else { /* mask */
l = strlen(ptr);
if (strspn(ptr, macset) != l ||
@@ -2336,7 +2369,7 @@ next_cmd(ipfw_insn *cmd)
* Takes arguments and copies them into a comment
*/
static void
-fill_comment(ipfw_insn *cmd, int ac, char **av)
+fill_comment(ipfw_insn *cmd, char **av)
{
int i, l;
char *p = (char *)(cmd + 1);
@@ -2345,7 +2378,7 @@ fill_comment(ipfw_insn *cmd, int ac, char **av)
cmd->len = (cmd->len & (F_NOT | F_OR));
/* Compute length of comment string. */
- for (i = 0, l = 0; i < ac; i++)
+ for (i = 0, l = 0; av[i] != NULL; i++)
l += strlen(av[i]) + 1;
if (l == 0)
return;
@@ -2354,7 +2387,7 @@ fill_comment(ipfw_insn *cmd, int ac, char **av)
"comment too long (max 80 chars)");
l = 1 + (l+3)/4;
cmd->len = (cmd->len & (F_NOT | F_OR)) | l;
- for (i = 0; i < ac; i++) {
+ for (i = 0; av[i] != NULL; i++) {
strcpy(p, av[i]);
p += strlen(av[i]);
*p++ = ' ';
@@ -2379,11 +2412,11 @@ fill_cmd(ipfw_insn *cmd, enum ipfw_opcodes opcode, int flags, uint16_t arg)
* two microinstructions, and returns the pointer to the last one.
*/
static ipfw_insn *
-add_mac(ipfw_insn *cmd, int ac, char *av[])
+add_mac(ipfw_insn *cmd, char *av[])
{
ipfw_insn_mac *mac;
- if (ac < 2)
+ if ( ( av[0] == NULL ) || ( av[1] == NULL ) )
errx(EX_DATAERR, "MAC dst src");
cmd->opcode = O_MACADDR2;
@@ -2397,9 +2430,9 @@ add_mac(ipfw_insn *cmd, int ac, char *av[])
}
static ipfw_insn *
-add_mactype(ipfw_insn *cmd, int ac, char *av)
+add_mactype(ipfw_insn *cmd, char *av)
{
- if (ac < 1)
+ if (!av)
errx(EX_DATAERR, "missing MAC type");
if (strcmp(av, "any") != 0) { /* we have a non-null type */
fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE);
@@ -2507,6 +2540,7 @@ add_dstip(ipfw_insn *cmd, char *av)
static ipfw_insn *
add_ports(ipfw_insn *cmd, char *av, u_char proto, int opcode)
{
+ /* XXX "any" is trapped before. Perhaps "to" */
if (_substrcmp(av, "any") == 0) {
return NULL;
} else if (fill_newports((ipfw_insn_u16 *)cmd, av, proto)) {
@@ -2530,11 +2564,11 @@ add_src(ipfw_insn *cmd, char *av, u_char proto)
*ch = '\0';
if (proto == IPPROTO_IPV6 || strcmp(av, "me6") == 0 ||
- inet_pton(AF_INET6, host, &a))
+ inet_pton(AF_INET6, host, &a) == 1)
ret = add_srcip6(cmd, av);
/* XXX: should check for IPv4, not !IPv6 */
if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
- !inet_pton(AF_INET6, host, &a)))
+ inet_pton(AF_INET6, host, &a) != 1))
ret = add_srcip(cmd, av);
if (ret == NULL && strcmp(av, "any") != 0)
ret = cmd;
@@ -2556,11 +2590,11 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto)
*ch = '\0';
if (proto == IPPROTO_IPV6 || strcmp(av, "me6") == 0 ||
- inet_pton(AF_INET6, host, &a))
+ inet_pton(AF_INET6, host, &a) == 1)
ret = add_dstip6(cmd, av);
/* XXX: should check for IPv4, not !IPv6 */
if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
- !inet_pton(AF_INET6, host, &a)))
+ inet_pton(AF_INET6, host, &a) != 1))
ret = add_dstip(cmd, av);
if (ret == NULL && strcmp(av, "any") != 0)
ret = cmd;
@@ -2582,7 +2616,7 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto)
*
*/
void
-ipfw_add(int ac, char *av[])
+ipfw_add(char *av[])
{
/*
* rules are added into the 'rulebuf' and then copied in
@@ -2621,37 +2655,36 @@ ipfw_add(int ac, char *av[])
cmd = (ipfw_insn *)cmdbuf;
action = (ipfw_insn *)actbuf;
- av++; ac--;
+ av++;
/* [rule N] -- Rule number optional */
- if (ac && isdigit(**av)) {
+ if (av[0] && isdigit(**av)) {
rule->rulenum = atoi(*av);
av++;
- ac--;
}
/* [set N] -- set number (0..RESVD_SET), optional */
- if (ac > 1 && _substrcmp(*av, "set") == 0) {
+ if (av[0] && av[1] && _substrcmp(*av, "set") == 0) {
int set = strtoul(av[1], NULL, 10);
if (set < 0 || set > RESVD_SET)
errx(EX_DATAERR, "illegal set %s", av[1]);
rule->set = set;
- av += 2; ac -= 2;
+ av += 2;
}
/* [prob D] -- match probability, optional */
- if (ac > 1 && _substrcmp(*av, "prob") == 0) {
+ if (av[0] && av[1] && _substrcmp(*av, "prob") == 0) {
match_prob = strtod(av[1], NULL);
if (match_prob <= 0 || match_prob > 1)
errx(EX_DATAERR, "illegal match prob. %s", av[1]);
- av += 2; ac -= 2;
+ av += 2;
}
/* action -- mandatory */
NEED1("missing action");
i = match_token(rule_actions, *av);
- ac--; av++;
+ av++;
action->len = 1; /* default */
switch(i) {
case TOK_CHECKSTATE:
@@ -2687,14 +2720,14 @@ ipfw_add(int ac, char *av[])
action->opcode = O_REJECT;
NEED1("missing reject code");
fill_reject_code(&action->arg1, *av);
- ac--; av++;
+ av++;
break;
case TOK_UNREACH6:
action->opcode = O_UNREACH6;
NEED1("missing unreach code");
fill_unreach6_code(&action->arg1, *av);
- ac--; av++;
+ av++;
break;
case TOK_COUNT:
@@ -2727,7 +2760,7 @@ ipfw_add(int ac, char *av[])
case TOK_TEE:
action->opcode = O_TEE;
chkarg:
- if (!ac)
+ if (!av[0])
errx(EX_USAGE, "missing argument for %s", *(av - 1));
if (isdigit(**av)) {
action->arg1 = strtoul(*av, NULL, 10);
@@ -2746,7 +2779,7 @@ chkarg:
errx(EX_DATAERR, "illegal divert/tee port");
} else
errx(EX_DATAERR, "illegal argument for %s", *(av - 1));
- ac--; av++;
+ av++;
break;
case TOK_FORWARD: {
@@ -2784,13 +2817,13 @@ chkarg:
p->sa.sin_addr.s_addr = INADDR_ANY;
else
lookup_host(*av, &(p->sa.sin_addr));
- ac--; av++;
+ av++;
break;
}
case TOK_COMMENT:
/* pretend it is a 'count' rule followed by the comment */
action->opcode = O_COUNT;
- ac++; av--; /* go back... */
+ av--; /* go back... */
break;
case TOK_SETFIB:
@@ -2805,7 +2838,7 @@ chkarg:
errx(EX_DATAERR, "fibs not suported.\n");
if (action->arg1 >= numfibs) /* Temporary */
errx(EX_DATAERR, "fib too large.\n");
- ac--; av++;
+ av++;
break;
}
@@ -2825,8 +2858,8 @@ chkarg:
* If they exist, it go first in the cmdbuf, but then it is
* skipped in the copy section to the end of the buffer.
*/
- while (ac != 0 && (i = match_token(rule_action_params, *av)) != -1) {
- ac--; av++;
+ while (av[0] != NULL && (i = match_token(rule_action_params, *av)) != -1) {
+ av++;
switch (i) {
case TOK_LOG:
{
@@ -2839,15 +2872,15 @@ chkarg:
have_log = (ipfw_insn *)c;
cmd->len = F_INSN_SIZE(ipfw_insn_log);
cmd->opcode = O_LOG;
- if (ac && _substrcmp(*av, "logamount") == 0) {
- ac--; av++;
+ if (av[0] && _substrcmp(*av, "logamount") == 0) {
+ av++;
NEED1("logamount requires argument");
l = atoi(*av);
if (l < 0)
errx(EX_DATAERR,
"logamount must be positive");
c->max_log = l;
- ac--; av++;
+ av++;
} else {
len = sizeof(c->max_log);
if (sysctlbyname("net.inet.ip.fw.verbose_limit",
@@ -2858,6 +2891,7 @@ chkarg:
}
break;
+#ifndef NO_ALTQ
case TOK_ALTQ:
{
ipfw_insn_altq *a = (ipfw_insn_altq *)cmd;
@@ -2870,9 +2904,10 @@ chkarg:
cmd->len = F_INSN_SIZE(ipfw_insn_altq);
cmd->opcode = O_ALTQ;
a->qid = altq_name_to_qid(*av);
- ac--; av++;
+ av++;
}
break;
+#endif
case TOK_TAG:
case TOK_UNTAG: {
@@ -2885,7 +2920,7 @@ chkarg:
rule_action_params);
have_tag = cmd;
fill_cmd(cmd, O_TAG, (i == TOK_TAG) ? 0: F_NOT, tag);
- ac--; av++;
+ av++;
break;
}
@@ -2899,13 +2934,13 @@ chkarg:
goto done;
#define OR_START(target) \
- if (ac && (*av[0] == '(' || *av[0] == '{')) { \
+ if (av[0] && (*av[0] == '(' || *av[0] == '{')) { \
if (open_par) \
errx(EX_USAGE, "nested \"(\" not allowed\n"); \
prev = NULL; \
open_par = 1; \
if ( (av[0])[1] == '\0') { \
- ac--; av++; \
+ av++; \
} else \
(*av)++; \
} \
@@ -2914,30 +2949,30 @@ chkarg:
#define CLOSE_PAR \
if (open_par) { \
- if (ac && ( \
+ if (av[0] && ( \
strcmp(*av, ")") == 0 || \
strcmp(*av, "}") == 0)) { \
prev = NULL; \
open_par = 0; \
- ac--; av++; \
+ av++; \
} else \
errx(EX_USAGE, "missing \")\"\n"); \
}
#define NOT_BLOCK \
- if (ac && _substrcmp(*av, "not") == 0) { \
+ if (av[0] && _substrcmp(*av, "not") == 0) { \
if (cmd->len & F_NOT) \
errx(EX_USAGE, "double \"not\" not allowed\n"); \
cmd->len |= F_NOT; \
- ac--; av++; \
+ av++; \
}
#define OR_BLOCK(target) \
- if (ac && _substrcmp(*av, "or") == 0) { \
+ if (av[0] && _substrcmp(*av, "or") == 0) { \
if (prev == NULL || open_par == 0) \
errx(EX_DATAERR, "invalid OR block"); \
prev->len |= F_OR; \
- ac--; av++; \
+ av++; \
goto target; \
} \
CLOSE_PAR;
@@ -2954,15 +2989,15 @@ chkarg:
NEED1("missing protocol");
if (_substrcmp(*av, "MAC") == 0 ||
_substrcmp(*av, "mac") == 0) {
- ac--; av++; /* the "MAC" keyword */
- add_mac(cmd, ac, av); /* exits in case of errors */
+ av++; /* the "MAC" keyword */
+ add_mac(cmd, av); /* exits in case of errors */
cmd = next_cmd(cmd);
- ac -= 2; av += 2; /* dst-mac and src-mac */
+ av += 2; /* dst-mac and src-mac */
NOT_BLOCK;
NEED1("missing mac type");
- if (add_mactype(cmd, ac, av[0]))
+ if (add_mactype(cmd, av[0]))
cmd = next_cmd(cmd);
- ac--; av++; /* any or mac-type */
+ av++; /* any or mac-type */
goto read_options;
}
#endif
@@ -2974,7 +3009,7 @@ chkarg:
NOT_BLOCK;
NEED1("missing protocol");
if (add_proto_compat(cmd, *av, &proto)) {
- av++; ac--;
+ av++;
if (F_LEN(cmd) != 0) {
prev = cmd;
cmd = next_cmd(cmd);
@@ -2988,9 +3023,9 @@ chkarg:
/*
* "from", mandatory
*/
- if (!ac || _substrcmp(*av, "from") != 0)
+ if ((av[0] == NULL) || _substrcmp(*av, "from") != 0)
errx(EX_USAGE, "missing ``from''");
- ac--; av++;
+ av++;
/*
* source IP, mandatory
@@ -2999,7 +3034,7 @@ chkarg:
NOT_BLOCK; /* optional "not" */
NEED1("missing source address");
if (add_src(cmd, *av, proto)) {
- ac--; av++;
+ av++;
if (F_LEN(cmd) != 0) { /* ! any */
prev = cmd;
cmd = next_cmd(cmd);
@@ -3012,10 +3047,10 @@ chkarg:
* source ports, optional
*/
NOT_BLOCK; /* optional "not" */
- if (ac) {
+ if ( av[0] != NULL ) {
if (_substrcmp(*av, "any") == 0 ||
add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
- ac--; av++;
+ av++;
if (F_LEN(cmd) != 0)
cmd = next_cmd(cmd);
}
@@ -3024,9 +3059,9 @@ chkarg:
/*
* "to", mandatory
*/
- if (!ac || _substrcmp(*av, "to") != 0)
+ if ( (av[0] == NULL) || _substrcmp(*av, "to") != 0 )
errx(EX_USAGE, "missing ``to''");
- av++; ac--;
+ av++;
/*
* destination, mandatory
@@ -3035,7 +3070,7 @@ chkarg:
NOT_BLOCK; /* optional "not" */
NEED1("missing dst address");
if (add_dst(cmd, *av, proto)) {
- ac--; av++;
+ av++;
if (F_LEN(cmd) != 0) { /* ! any */
prev = cmd;
cmd = next_cmd(cmd);
@@ -3048,17 +3083,17 @@ chkarg:
* dest. ports, optional
*/
NOT_BLOCK; /* optional "not" */
- if (ac) {
+ if (av[0]) {
if (_substrcmp(*av, "any") == 0 ||
add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
- ac--; av++;
+ av++;
if (F_LEN(cmd) != 0)
cmd = next_cmd(cmd);
}
}
read_options:
- if (ac && first_cmd == cmd) {
+ if (av[0] && first_cmd == cmd) {
/*
* nothing specified so far, store in the rule to ease
* printout later.
@@ -3066,7 +3101,7 @@ read_options:
rule->_pad = 1;
}
prev = NULL;
- while (ac) {
+ while ( av[0] != NULL ) {
char *s;
ipfw_insn_u32 *cmd32; /* alias for cmd */
@@ -3080,7 +3115,7 @@ read_options:
s++;
}
i = match_token(rule_options, s);
- ac--; av++;
+ av++;
switch(i) {
case TOK_NOT:
if (cmd->len & F_NOT)
@@ -3142,7 +3177,7 @@ read_options:
NEED1("recv, xmit, via require interface name"
" or address");
fill_iface((ipfw_insn_if *)cmd, av[0]);
- ac--; av++;
+ av++;
if (F_LEN(cmd) == 0) /* not a valid address */
break;
if (i == TOK_XMIT)
@@ -3156,13 +3191,13 @@ read_options:
case TOK_ICMPTYPES:
NEED1("icmptypes requires list of types");
fill_icmptypes((ipfw_insn_u32 *)cmd, *av);
- av++; ac--;
+ av++;
break;
case TOK_ICMP6TYPES:
NEED1("icmptypes requires list of types");
fill_icmp6types((ipfw_insn_icmp6 *)cmd, *av);
- av++; ac--;
+ av++;
break;
case TOK_IPTTL:
@@ -3172,7 +3207,7 @@ read_options:
errx(EX_DATAERR, "invalid ipttl %s", *av);
} else
fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_IPID:
@@ -3182,7 +3217,7 @@ read_options:
errx(EX_DATAERR, "invalid ipid %s", *av);
} else
fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_IPLEN:
@@ -3192,32 +3227,32 @@ read_options:
errx(EX_DATAERR, "invalid ip len %s", *av);
} else
fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_IPVER:
NEED1("ipver requires version");
fill_cmd(cmd, O_IPVER, 0, strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_IPPRECEDENCE:
NEED1("ipprecedence requires value");
fill_cmd(cmd, O_IPPRECEDENCE, 0,
(strtoul(*av, NULL, 0) & 7) << 5);
- ac--; av++;
+ av++;
break;
case TOK_IPOPTS:
NEED1("missing argument for ipoptions");
fill_flags(cmd, O_IPOPT, f_ipopts, *av);
- ac--; av++;
+ av++;
break;
case TOK_IPTOS:
NEED1("missing argument for iptos");
fill_flags(cmd, O_IPTOS, f_iptos, *av);
- ac--; av++;
+ av++;
break;
case TOK_UID:
@@ -3234,7 +3269,7 @@ read_options:
errx(EX_DATAERR, "uid \"%s\" nonexistent", *av);
cmd32->d[0] = pwd->pw_uid;
cmd->len |= F_INSN_SIZE(ipfw_insn_u32);
- ac--; av++;
+ av++;
}
break;
@@ -3252,7 +3287,7 @@ read_options:
errx(EX_DATAERR, "gid \"%s\" nonexistent", *av);
cmd32->d[0] = grp->gr_gid;
cmd->len |= F_INSN_SIZE(ipfw_insn_u32);
- ac--; av++;
+ av++;
}
break;
@@ -3268,7 +3303,7 @@ read_options:
errx(EX_DATAERR, "jail requires prison ID");
cmd32->d[0] = (uint32_t)jid;
cmd->len |= F_INSN_SIZE(ipfw_insn_u32);
- ac--; av++;
+ av++;
}
break;
@@ -3289,13 +3324,13 @@ read_options:
} else
fill_cmd(cmd, O_TCPDATALEN, 0,
strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_TCPOPTS:
NEED1("missing argument for tcpoptions");
fill_flags(cmd, O_TCPOPTS, f_tcpopts, *av);
- ac--; av++;
+ av++;
break;
case TOK_TCPSEQ:
@@ -3304,21 +3339,21 @@ read_options:
cmd->len = F_INSN_SIZE(ipfw_insn_u32);
cmd->opcode = (i == TOK_TCPSEQ) ? O_TCPSEQ : O_TCPACK;
cmd32->d[0] = htonl(strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_TCPWIN:
NEED1("tcpwin requires length");
fill_cmd(cmd, O_TCPWIN, 0,
htons(strtoul(*av, NULL, 0)));
- ac--; av++;
+ av++;
break;
case TOK_TCPFLAGS:
NEED1("missing argument for tcpflags");
cmd->opcode = O_TCPFLAGS;
fill_flags(cmd, O_TCPFLAGS, f_tcpflags, *av);
- ac--; av++;
+ av++;
break;
case TOK_KEEPSTATE:
@@ -3348,11 +3383,11 @@ read_options:
cmd->opcode = O_LIMIT;
c->limit_mask = c->conn_limit = 0;
- while (ac > 0) {
+ while ( av[0] != NULL ) {
if ((val = match_token(limit_masks, *av)) <= 0)
break;
c->limit_mask |= val;
- ac--; av++;
+ av++;
}
if (c->limit_mask == 0)
@@ -3361,14 +3396,14 @@ read_options:
GET_UINT_ARG(c->conn_limit, IPFW_ARG_MIN, IPFW_ARG_MAX,
TOK_LIMIT, rule_options);
- ac--; av++;
+ av++;
break;
}
case TOK_PROTO:
NEED1("missing protocol");
if (add_proto(cmd, *av, &proto)) {
- ac--; av++;
+ av++;
} else
errx(EX_DATAERR, "invalid protocol ``%s''",
*av);
@@ -3377,28 +3412,28 @@ read_options:
case TOK_SRCIP:
NEED1("missing source IP");
if (add_srcip(cmd, *av)) {
- ac--; av++;
+ av++;
}
break;
case TOK_DSTIP:
NEED1("missing destination IP");
if (add_dstip(cmd, *av)) {
- ac--; av++;
+ av++;
}
break;
case TOK_SRCIP6:
NEED1("missing source IP6");
if (add_srcip6(cmd, *av)) {
- ac--; av++;
+ av++;
}
break;
case TOK_DSTIP6:
NEED1("missing destination IP6");
if (add_dstip6(cmd, *av)) {
- ac--; av++;
+ av++;
}
break;
@@ -3406,7 +3441,7 @@ read_options:
NEED1("missing source port");
if (_substrcmp(*av, "any") == 0 ||
add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
- ac--; av++;
+ av++;
} else
errx(EX_DATAERR, "invalid source port %s", *av);
break;
@@ -3415,23 +3450,22 @@ read_options:
NEED1("missing destination port");
if (_substrcmp(*av, "any") == 0 ||
add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
- ac--; av++;
+ av++;
} else
errx(EX_DATAERR, "invalid destination port %s",
*av);
break;
case TOK_MAC:
- if (add_mac(cmd, ac, av)) {
- ac -= 2; av += 2;
- }
+ if (add_mac(cmd, av))
+ av += 2;
break;
case TOK_MACTYPE:
NEED1("missing mac type");
- if (!add_mactype(cmd, ac, *av))
+ if (!add_mactype(cmd, *av))
errx(EX_DATAERR, "invalid mac type %s", *av);
- ac--; av++;
+ av++;
break;
case TOK_VERREVPATH:
@@ -3460,7 +3494,7 @@ read_options:
case TOK_EXT6HDR:
fill_ext6hdr( cmd, *av );
- ac--; av++;
+ av++;
break;
case TOK_FLOWID:
@@ -3468,17 +3502,16 @@ read_options:
errx( EX_USAGE, "flow-id filter is active "
"only for ipv6 protocol\n");
fill_flow6( (ipfw_insn_u32 *) cmd, *av );
- ac--; av++;
+ av++;
break;
case TOK_COMMENT:
- fill_comment(cmd, ac, av);
- av += ac;
- ac = 0;
+ fill_comment(cmd, av);
+ av[0]=NULL;
break;
case TOK_TAGGED:
- if (ac > 0 && strpbrk(*av, "-,")) {
+ if (av[0] && strpbrk(*av, "-,")) {
if (!add_ports(cmd, *av, 0, O_TAGGED))
errx(EX_DATAERR, "tagged: invalid tag"
" list: %s", *av);
@@ -3490,13 +3523,13 @@ read_options:
TOK_TAGGED, rule_options);
fill_cmd(cmd, O_TAGGED, 0, tag);
}
- ac--; av++;
+ av++;
break;
case TOK_FIB:
NEED1("fib requires fib number");
fill_cmd(cmd, O_FIB, 0, strtoul(*av, NULL, 0));
- ac--; av++;
+ av++;
break;
case TOK_LOOKUP: {
@@ -3504,7 +3537,7 @@ read_options:
char *p;
int j;
- if (ac < 2)
+ if (!av[0] || !av[1])
errx(EX_USAGE, "format: lookup argument tablenum");
cmd->opcode = O_IP_DST_LOOKUP;
cmd->len |= F_INSN_SIZE(ipfw_insn) + 2;
@@ -3516,11 +3549,11 @@ read_options:
if (lookup_key[j] <= 0)
errx(EX_USAGE, "format: cannot lookup on %s", *av);
c->d[1] = j; // i converted to option
- ac--; av++;
+ av++;
cmd->arg1 = strtoul(*av, &p, 0);
if (p && *p)
errx(EX_USAGE, "format: lookup argument tablenum");
- ac--; av++;
+ av++;
}
break;
@@ -3698,6 +3731,10 @@ ipfw_flush(int force)
if (c == 'N') /* user said no */
return;
}
+ if (co.do_pipe) {
+ dummynet_flush();
+ return;
+ }
/* `ipfw set N flush` - is the same that `ipfw delete set N` */
if (co.use_set) {
uint32_t arg = ((co.use_set - 1) & 0xffff) | (1 << 24);
@@ -3811,14 +3848,14 @@ ipfw_table_handler(int ac, char *av[])
}
}
} else if (_substrcmp(*av, "flush") == 0) {
- a = is_all ? tables_max : (ent.tbl + 1);
+ a = is_all ? tables_max : (uint32_t)(ent.tbl + 1);
do {
if (do_cmd(IP_FW_TABLE_FLUSH, &ent.tbl,
sizeof(ent.tbl)) < 0)
err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)");
} while (++ent.tbl < a);
} else if (_substrcmp(*av, "list") == 0) {
- a = is_all ? tables_max : (ent.tbl + 1);
+ a = is_all ? tables_max : (uint32_t)(ent.tbl + 1);
do {
table_list(ent, is_all);
} while (++ent.tbl < a);
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index b393a7d..8566cde 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -35,7 +35,7 @@ struct cmdline_opts {
int do_resolv; /* try to resolve all ip to names */
int do_time; /* Show time stamps */
int do_quiet; /* Be quiet in add and flush */
- int do_pipe; /* this cmd refers to a pipe */
+ int do_pipe; /* this cmd refers to a pipe/queue/sched */
int do_nat; /* this cmd refers to a nat config */
int do_dynamic; /* display dynamic rules */
int do_expired; /* display expired dynamic rules */
@@ -82,7 +82,10 @@ enum tokens {
TOK_ACCEPT,
TOK_COUNT,
TOK_PIPE,
+ TOK_LINK,
TOK_QUEUE,
+ TOK_FLOWSET,
+ TOK_SCHED,
TOK_DIVERT,
TOK_TEE,
TOK_NETGRAPH,
@@ -122,6 +125,7 @@ enum tokens {
TOK_IPLEN,
TOK_IPID,
TOK_IPPRECEDENCE,
+ TOK_DSCP,
TOK_IPTOS,
TOK_IPTTL,
TOK_IPVER,
@@ -151,15 +155,23 @@ enum tokens {
TOK_SRCPORT,
TOK_ALL,
TOK_MASK,
+ TOK_FLOW_MASK,
+ TOK_SCHED_MASK,
TOK_BW,
TOK_DELAY,
- TOK_PIPE_PROFILE,
+ TOK_PROFILE,
TOK_BURST,
TOK_RED,
TOK_GRED,
TOK_DROPTAIL,
TOK_PROTO,
+ /* dummynet tokens */
TOK_WEIGHT,
+ TOK_LMAX,
+ TOK_PRI,
+ TOK_TYPE,
+ TOK_SLOTSIZE,
+
TOK_IP,
TOK_IF,
TOK_ALOG,
@@ -192,9 +204,10 @@ enum tokens {
* the following macro returns an error message if we run out of
* arguments.
*/
-#define NEED1(msg) {if (!ac) errx(EX_USAGE, msg);}
+#define NEED(_p, msg) {if (!_p) errx(EX_USAGE, msg);}
+#define NEED1(msg) {if (!(*av)) errx(EX_USAGE, msg);}
-unsigned long long align_uint64(const uint64_t *pll);
+int pr_u64(uint64_t *pd, int width);
/* memory allocation support */
void *safe_calloc(size_t number, size_t size);
@@ -236,14 +249,14 @@ struct _ipfw_insn_icmp6;
extern int resvd_set_number;
/* first-level command handlers */
-void ipfw_add(int ac, char *av[]);
+void ipfw_add(char *av[]);
void ipfw_show_nat(int ac, char **av);
void ipfw_config_pipe(int ac, char **av);
void ipfw_config_nat(int ac, char **av);
-void ipfw_sets_handler(int ac, char *av[]);
+void ipfw_sets_handler(char *av[]);
void ipfw_table_handler(int ac, char *av[]);
-void ipfw_sysctl_handler(int ac, char *av[], int which);
-void ipfw_delete(int ac, char *av[]);
+void ipfw_sysctl_handler(char *av[], int which);
+void ipfw_delete(char *av[]);
void ipfw_flush(int force);
void ipfw_zero(int ac, char *av[], int optname);
void ipfw_list(int ac, char *av[], int show_counters);
@@ -255,7 +268,8 @@ u_int32_t altq_name_to_qid(const char *name);
void print_altq_cmd(struct _ipfw_insn_altq *altqptr);
/* dummynet.c */
-void ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[]);
+void dummynet_list(int ac, char *av[], int show_counters);
+void dummynet_flush(void);
int ipfw_delete_pipe(int pipe_or_queue, int n);
/* ipv6.c */
diff --git a/sbin/ipfw/main.c b/sbin/ipfw/main.c
index 3916057..43693e0 100644
--- a/sbin/ipfw/main.c
+++ b/sbin/ipfw/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2003 Luigi Rizzo
+ * Copyright (c) 2002-2003,2010 Luigi Rizzo
* Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
* Copyright (c) 1994 Ugen J.S.Antsilevich
*
@@ -80,31 +80,27 @@ help(void)
}
/*
- * Free a the (locally allocated) copy of command line arguments.
- */
-static void
-free_args(int ac, char **av)
-{
- int i;
-
- for (i=0; i < ac; i++)
- free(av[i]);
- free(av);
-}
-
-/*
* Called with the arguments, including program name because getopt
* wants it to be present.
* Returns 0 if successful, 1 if empty command, errx() in case of errors.
+ * First thing we do is process parameters creating an argv[] array
+ * which includes the program name and a NULL entry at the end.
+ * If we are called with a single string, we split it on whitespace.
+ * Also, arguments with a trailing ',' are joined to the next one.
+ * The pointers (av[]) and data are in a a single chunk of memory.
+ * av[0] points to the original program name, all other entries
+ * point into the allocated chunk.
*/
static int
ipfw_main(int oldac, char **oldav)
{
- int ch, ac, save_ac;
+ int ch, ac;
const char *errstr;
char **av, **save_av;
int do_acct = 0; /* Show packet/byte count */
int try_next = 0; /* set if pipe cmd not found */
+ int av_size; /* compute the av size */
+ char *av_p; /* used to build the av list */
#define WHITESP " \t\f\v\n\r"
if (oldac < 2)
@@ -112,10 +108,9 @@ ipfw_main(int oldac, char **oldav)
if (oldac == 2) {
/*
- * If we are called with a single string, try to split it into
- * arguments for subsequent parsing.
- * But first, remove spaces after a ',', by copying the string
- * in-place.
+ * If we are called with one argument, try to split it into
+ * words for subsequent parsing. Spaces after a ',' are
+ * removed by copying the string in-place.
*/
char *arg = oldav[1]; /* The string is the first arg. */
int l = strlen(arg);
@@ -150,31 +145,59 @@ ipfw_main(int oldac, char **oldav)
ac++;
/*
- * Allocate the argument list, including one entry for
- * the program name because getopt expects it.
+ * Allocate the argument list structure as a single block
+ * of memory, containing pointers and the argument
+ * strings. We include one entry for the program name
+ * because getopt expects it, and a NULL at the end
+ * to simplify further parsing.
*/
- av = safe_calloc(ac + 1, sizeof(char *));
+ ac++; /* add 1 for the program name */
+ av_size = (ac+1) * sizeof(char *) + l + 1;
+ av = safe_calloc(av_size, 1);
/*
- * Second, copy arguments from arg[] to av[]. For each one,
+ * Init the argument pointer to the end of the array
+ * and copy arguments from arg[] to av[]. For each one,
* j is the initial character, i is the one past the end.
*/
- for (ac = 1, i = j = 0; i < l; i++)
+ av_p = (char *)&av[ac+1];
+ for (ac = 1, i = j = 0; i < l; i++) {
if (index(WHITESP, arg[i]) != NULL || i == l-1) {
if (i == l-1)
i++;
- av[ac] = safe_calloc(i-j+1, 1);
- bcopy(arg+j, av[ac], i-j);
+ bcopy(arg+j, av_p, i-j);
+ av[ac] = av_p;
+ av_p += i-j; /* the lenght of the string */
+ *av_p++ = '\0';
ac++;
j = i + 1;
}
+ }
} else {
/*
* If an argument ends with ',' join with the next one.
*/
- int first, i, l;
+ int first, i, l=0;
+
+ /*
+ * Allocate the argument list structure as a single block
+ * of memory, containing both pointers and the argument
+ * strings. We include some space for the program name
+ * because getopt expects it.
+ * We add an extra pointer to the end of the array,
+ * to make simpler further parsing.
+ */
+ for (i=0; i<oldac; i++)
+ l += strlen(oldav[i]);
- av = safe_calloc(oldac, sizeof(char *));
+ av_size = (oldac+1) * sizeof(char *) + l + oldac;
+ av = safe_calloc(av_size, 1);
+
+ /*
+ * Init the argument pointer to the end of the array
+ * and copy arguments from arg[] to av[]
+ */
+ av_p = (char *)&av[oldac+1];
for (first = i = ac = 1, l = 0; i < oldac; i++) {
char *arg = oldav[i];
int k = strlen(arg);
@@ -182,11 +205,12 @@ ipfw_main(int oldac, char **oldav)
l += k;
if (arg[k-1] != ',' || i == oldac-1) {
/* Time to copy. */
- av[ac] = safe_calloc(l+1, 1);
+ av[ac] = av_p;
for (l=0; first <= i; first++) {
- strcat(av[ac]+l, oldav[first]);
- l += strlen(oldav[first]);
+ strcat(av_p, oldav[first]);
+ av_p += strlen(oldav[first]);
}
+ *av_p++ = '\0';
ac++;
l = 0;
first = i+1;
@@ -194,13 +218,47 @@ ipfw_main(int oldac, char **oldav)
}
}
- av[0] = strdup(oldav[0]); /* copy progname from the caller */
+ /*
+ * set the progname pointer to the original string
+ * and terminate the array with null
+ */
+ av[0] = oldav[0];
+ av[ac] = NULL;
+
/* Set the force flag for non-interactive processes */
if (!co.do_force)
co.do_force = !isatty(STDIN_FILENO);
+#ifdef EMULATE_SYSCTL /* sysctl emulation */
+ if ( ac >= 2 && !strcmp(av[1], "sysctl")) {
+ char *s;
+ int i;
+
+ if (ac != 3) {
+ printf( "sysctl emulation usage:\n"
+ " ipfw sysctl name[=value]\n"
+ " ipfw sysctl -a\n");
+ return 0;
+ }
+ s = index(av[2], '=');
+ if (s == NULL) {
+ s = !strcmp(av[2], "-a") ? NULL : av[2];
+ sysctlbyname(s, NULL, NULL, NULL, 0);
+ } else { /* ipfw sysctl x.y.z=value */
+ /* assume an INT value, will extend later */
+ if (s[1] == '\0') {
+ printf("ipfw sysctl: missing value\n\n");
+ return 0;
+ }
+ *s = '\0';
+ i = strtol(s+1, NULL, 0);
+ sysctlbyname(av[2], NULL, NULL, &i, sizeof(int));
+ }
+ return 0;
+ }
+#endif
+
/* Save arguments for final freeing of memory. */
- save_ac = ac;
save_av = av;
optind = optreset = 1; /* restart getopt() */
@@ -232,7 +290,7 @@ ipfw_main(int oldac, char **oldav)
break;
case 'h': /* help */
- free_args(save_ac, save_av);
+ free(save_av);
help();
break; /* NOTREACHED */
@@ -273,7 +331,7 @@ ipfw_main(int oldac, char **oldav)
break;
default:
- free_args(save_ac, save_av);
+ free(save_av);
return 1;
}
@@ -304,6 +362,10 @@ ipfw_main(int oldac, char **oldav)
co.do_pipe = 1;
else if (_substrcmp(*av, "queue") == 0)
co.do_pipe = 2;
+ else if (_substrcmp(*av, "flowset") == 0)
+ co.do_pipe = 2;
+ else if (_substrcmp(*av, "sched") == 0)
+ co.do_pipe = 3;
else if (!strncmp(*av, "set", strlen(*av))) {
if (ac > 1 && isdigit(av[1][0])) {
co.use_set = strtonum(av[1], 0, resvd_set_number,
@@ -335,7 +397,7 @@ ipfw_main(int oldac, char **oldav)
if (co.use_set == 0) {
if (_substrcmp(*av, "add") == 0)
- ipfw_add(ac, av);
+ ipfw_add(av);
else if (co.do_nat && _substrcmp(*av, "show") == 0)
ipfw_show_nat(ac, av);
else if (co.do_pipe && _substrcmp(*av, "config") == 0)
@@ -343,20 +405,20 @@ ipfw_main(int oldac, char **oldav)
else if (co.do_nat && _substrcmp(*av, "config") == 0)
ipfw_config_nat(ac, av);
else if (_substrcmp(*av, "set") == 0)
- ipfw_sets_handler(ac, av);
+ ipfw_sets_handler(av);
else if (_substrcmp(*av, "table") == 0)
ipfw_table_handler(ac, av);
else if (_substrcmp(*av, "enable") == 0)
- ipfw_sysctl_handler(ac, av, 1);
+ ipfw_sysctl_handler(av, 1);
else if (_substrcmp(*av, "disable") == 0)
- ipfw_sysctl_handler(ac, av, 0);
+ ipfw_sysctl_handler(av, 0);
else
try_next = 1;
}
if (co.use_set || try_next) {
if (_substrcmp(*av, "delete") == 0)
- ipfw_delete(ac, av);
+ ipfw_delete(av);
else if (_substrcmp(*av, "flush") == 0)
ipfw_flush(co.do_force);
else if (_substrcmp(*av, "zero") == 0)
@@ -373,7 +435,7 @@ ipfw_main(int oldac, char **oldav)
}
/* Free memory allocated in the argument parsing. */
- free_args(save_ac, save_av);
+ free(save_av);
return 0;
}
@@ -491,11 +553,11 @@ ipfw_readfile(int ac, char *av[])
}
while (fgets(buf, BUFSIZ, f)) { /* read commands */
- char linename[10];
+ char linename[20];
char *args[2];
lineno++;
- sprintf(linename, "Line %d", lineno);
+ snprintf(linename, sizeof(linename), "Line %d", lineno);
setprogname(linename); /* XXX */
args[0] = progname;
args[1] = buf;
@@ -521,6 +583,20 @@ ipfw_readfile(int ac, char *av[])
int
main(int ac, char *av[])
{
+#if defined(_WIN32) && defined(TCC)
+ {
+ WSADATA wsaData;
+ int ret=0;
+ unsigned short wVersionRequested = MAKEWORD(2, 2);
+ ret = WSAStartup(wVersionRequested, &wsaData);
+ if (ret != 0) {
+ /* Tell the user that we could not find a usable */
+ /* Winsock DLL. */
+ printf("WSAStartup failed with error: %d\n", ret);
+ return 1;
+ }
+ }
+#endif
/*
* If the last argument is an absolute pathname, interpret it
* as a file to be preprocessed.
diff --git a/sbin/iscontrol/iscsi.conf.5 b/sbin/iscontrol/iscsi.conf.5
index 2edcd35..0de5122 100644
--- a/sbin/iscontrol/iscsi.conf.5
+++ b/sbin/iscontrol/iscsi.conf.5
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd June 5, 2007
-.Os
.Dt ISCSI.CONF 5
+.Os
.Sh NAME
.Nm iscsi.conf
.Nd key options to be negotiated in an iSCSI session
diff --git a/sbin/mca/mca.c b/sbin/mca/mca.c
index 0c4e1a0..9934454 100644
--- a/sbin/mca/mca.c
+++ b/sbin/mca/mca.c
@@ -53,10 +53,12 @@ __FBSDID("$FreeBSD$");
#define BCD(x) ((x >> 4) * 10 + (x & 15))
+#define HW_MCA_MAX_CPUID 255
+
static char hw_mca_count[] = "hw.mca.count";
static char hw_mca_first[] = "hw.mca.first";
static char hw_mca_last[] = "hw.mca.last";
-static char hw_mca_recid[] = "hw.mca.%d";
+static char hw_mca_recid[] = "hw.mca.%lu.%u";
static char default_dumpfile[] = "/var/log/mca.log";
@@ -372,10 +374,13 @@ show_section(struct mca_section_header *sh)
}
static void
-show(char *data)
+show(char *data, const char *mib)
{
size_t reclen, seclen;
+ if (mib != NULL)
+ printf("<!-- MIB: %s -->\n", mib);
+
printf("<record>\n");
reclen = show_header((void*)data) - sizeof(struct mca_record_header);
data += sizeof(struct mca_record_header);
@@ -402,7 +407,7 @@ showall(char *buf, size_t buflen)
if (buflen < reclen)
return;
- show(buf);
+ show(buf, NULL);
buf += reclen;
buflen -= reclen;
@@ -442,7 +447,7 @@ main(int argc, char **argv)
char *buf;
size_t len;
int ch, error, fd;
- int count, first, last;
+ int count, first, last, cpuid;
while ((ch = getopt(argc, argv, "df:")) != -1) {
switch(ch) {
@@ -481,12 +486,19 @@ main(int argc, char **argv)
if (error)
err(1, hw_mca_last);
+ cpuid = 0;
while (count && first <= last) {
- sprintf(mib, hw_mca_recid, first);
- len = 0;
- error = sysctlbyname(mib, NULL, &len, NULL, 0);
- if (error == ENOENT) {
+ do {
+ sprintf(mib, hw_mca_recid, first, cpuid);
+ len = 0;
+ error = sysctlbyname(mib, NULL, &len, NULL, 0);
+ if (error != ENOENT)
+ break;
+ cpuid++;
+ } while (cpuid <= HW_MCA_MAX_CPUID);
+ if (error == ENOENT && cpuid > HW_MCA_MAX_CPUID) {
first++;
+ cpuid = 0;
continue;
}
if (error)
@@ -503,11 +515,15 @@ main(int argc, char **argv)
if (fl_dump)
dump(buf);
else
- show(buf);
+ show(buf, mib);
free(buf);
- first++;
count--;
+ if (cpuid == HW_MCA_MAX_CPUID) {
+ first++;
+ cpuid = 0;
+ } else
+ cpuid++;
}
} else {
fd = open(file, O_RDONLY);
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 907f754..b39a7d1 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -91,7 +91,7 @@ char *flags2opts(int);
/* Map from mount options to printable formats. */
static struct opt {
- int o_opt;
+ uint64_t o_opt;
const char *o_name;
} optnames[] = {
{ MNT_ASYNC, "asynchronous" },
@@ -612,7 +612,7 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags,
void
prmount(struct statfs *sfp)
{
- int flags;
+ uint64_t flags;
unsigned int i;
struct opt *o;
struct passwd *pw;
@@ -621,7 +621,7 @@ prmount(struct statfs *sfp)
sfp->f_fstypename);
flags = sfp->f_flags & MNT_VISFLAGMASK;
- for (o = optnames; flags && o->o_opt; o++)
+ for (o = optnames; flags != 0 && o->o_opt != 0; o++)
if (flags & o->o_opt) {
(void)printf(", %s", o->o_name);
flags &= ~o->o_opt;
diff --git a/sbin/newfs/Makefile b/sbin/newfs/Makefile
index f89499e..d45143b 100644
--- a/sbin/newfs/Makefile
+++ b/sbin/newfs/Makefile
@@ -4,8 +4,8 @@
.PATH: ${.CURDIR}/../../sys/geom
PROG= newfs
-DPADD= ${LIBUFS}
-LDADD= -lufs
+DPADD= ${LIBUFS} ${LIBUTIL}
+LDADD= -lufs -lutil
SRCS= newfs.c mkfs.c geom_bsd_enc.c
WARNS?= 3
diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8
index 9aea040..ec9bcd8 100644
--- a/sbin/newfs/newfs.8
+++ b/sbin/newfs/newfs.8
@@ -78,10 +78,10 @@ The following options define the general layout policies:
.It Fl E
Erase the content of the disk before making the filesystem.
The reserved area in front of the superblock (for bootcode) will not be erased.
-
+.Pp
This is a relevant option for flash based storage devices that use
wear levelling algorithms.
-
+.Pp
NB: Erasing may take as long time as writing every sector on the disk.
.It Fl J
Enable journaling on the new file system via gjournal.
diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c
index 8867306..e5a42c0 100644
--- a/sbin/newfs/newfs.c
+++ b/sbin/newfs/newfs.c
@@ -77,6 +77,8 @@ __FBSDID("$FreeBSD$");
#include <syslog.h>
#include <unistd.h>
+#include <libutil.h>
+
#include "newfs.h"
int Eflag; /* Erase previous disk contents */
@@ -117,6 +119,7 @@ static void getfssize(intmax_t *, const char *p, intmax_t, intmax_t);
static struct disklabel *getdisklabel(char *s);
static void rewritelabel(char *s, struct disklabel *lp);
static void usage(void);
+static int expand_number_int(const char *buf, int *num);
ufs2_daddr_t part_ofs; /* partition offset in blocks, used with files */
@@ -129,7 +132,7 @@ main(int argc, char *argv[])
struct stat st;
char *cp, *special;
intmax_t reserved;
- int ch, i;
+ int ch, i, rval;
off_t mediasize;
char part_name; /* partition name, default to full disk */
@@ -169,7 +172,8 @@ main(int argc, char *argv[])
Rflag = 1;
break;
case 'S':
- if ((sectorsize = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &sectorsize);
+ if (rval < 0 || sectorsize <= 0)
errx(1, "%s: bad sector size", optarg);
break;
case 'T':
@@ -182,12 +186,17 @@ main(int argc, char *argv[])
Xflag++;
break;
case 'a':
- if ((maxcontig = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &maxcontig);
+ if (rval < 0 || maxcontig <= 0)
errx(1, "%s: bad maximum contiguous blocks",
optarg);
break;
case 'b':
- if ((bsize = atoi(optarg)) < MINBSIZE)
+ rval = expand_number_int(optarg, &bsize);
+ if (rval < 0)
+ errx(1, "%s: bad block size",
+ optarg);
+ if (bsize < MINBSIZE)
errx(1, "%s: block size too small, min is %d",
optarg, MINBSIZE);
if (bsize > MAXBSIZE)
@@ -195,33 +204,40 @@ main(int argc, char *argv[])
optarg, MAXBSIZE);
break;
case 'c':
- if ((maxblkspercg = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &maxblkspercg);
+ if (rval < 0 || maxblkspercg <= 0)
errx(1, "%s: bad blocks per cylinder group",
optarg);
break;
case 'd':
- if ((maxbsize = atoi(optarg)) < MINBSIZE)
+ rval = expand_number_int(optarg, &maxbsize);
+ if (rval < 0 || maxbsize < MINBSIZE)
errx(1, "%s: bad extent block size", optarg);
break;
case 'e':
- if ((maxbpg = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &maxbpg);
+ if (rval < 0 || maxbpg <= 0)
errx(1, "%s: bad blocks per file in a cylinder group",
optarg);
break;
case 'f':
- if ((fsize = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &fsize);
+ if (rval < 0 || fsize <= 0)
errx(1, "%s: bad fragment size", optarg);
break;
case 'g':
- if ((avgfilesize = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &avgfilesize);
+ if (rval < 0 || avgfilesize <= 0)
errx(1, "%s: bad average file size", optarg);
break;
case 'h':
- if ((avgfilesperdir = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &avgfilesperdir);
+ if (rval < 0 || avgfilesperdir <= 0)
errx(1, "%s: bad average files per dir", optarg);
break;
case 'i':
- if ((density = atoi(optarg)) <= 0)
+ rval = expand_number_int(optarg, &density);
+ if (rval < 0 || density <= 0)
errx(1, "%s: bad bytes per inode", optarg);
break;
case 'l':
@@ -481,3 +497,20 @@ usage()
fprintf(stderr, "\t-s file system size (sectors)\n");
exit(1);
}
+
+static int
+expand_number_int(const char *buf, int *num)
+{
+ int64_t num64;
+ int rval;
+
+ rval = expand_number(buf, &num64);
+ if (rval < 0)
+ return (rval);
+ if (num64 > INT_MAX || num64 < INT_MIN) {
+ errno = ERANGE;
+ return (-1);
+ }
+ *num = (int)num64;
+ return (0);
+}
diff --git a/sbin/nos-tun/Makefile b/sbin/nos-tun/Makefile
index e128b62..9f1024f 100644
--- a/sbin/nos-tun/Makefile
+++ b/sbin/nos-tun/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
PROG= nos-tun
-WARNS?= 0
MAN= nos-tun.8
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/sbin/nos-tun/nos-tun.c b/sbin/nos-tun/nos-tun.c
index 9966840..83e7144 100644
--- a/sbin/nos-tun/nos-tun.c
+++ b/sbin/nos-tun/nos-tun.c
@@ -89,7 +89,8 @@ int tun; /* tunnel descriptor */
static void usage(void);
-int Set_address(char *addr, struct sockaddr_in *sin)
+static int
+Set_address(char *addr, struct sockaddr_in *sin)
{
struct hostent *hp;
@@ -107,15 +108,16 @@ int Set_address(char *addr, struct sockaddr_in *sin)
return 0;
}
-int tun_open(char *devname, struct sockaddr *ouraddr, char *theiraddr)
+static int
+tun_open(char *dev_name, struct sockaddr *ouraddr, char *theiraddr)
{
int s;
struct sockaddr_in *sin;
/* Open tun device */
- tun = open (devname, O_RDWR);
+ tun = open(dev_name, O_RDWR);
if (tun < 0) {
- syslog(LOG_ERR,"can't open %s - %m",devname);
+ syslog(LOG_ERR,"can't open %s - %m", dev_name);
return(1);
}
@@ -125,8 +127,8 @@ int tun_open(char *devname, struct sockaddr *ouraddr, char *theiraddr)
bzero((char *)&ifra, sizeof(ifra));
bzero((char *)&ifrq, sizeof(ifrq));
- strncpy(ifrq.ifr_name, devname+5, IFNAMSIZ);
- strncpy(ifra.ifra_name, devname+5, IFNAMSIZ);
+ strncpy(ifrq.ifr_name, dev_name+5, IFNAMSIZ);
+ strncpy(ifra.ifra_name, dev_name+5, IFNAMSIZ);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
@@ -189,7 +191,8 @@ tunc_return:
return(1);
}
-void Finish(int signum)
+static void
+Finish(int signum)
{
int s;
@@ -238,7 +241,7 @@ int main (int argc, char **argv)
{
int c, len, ipoff;
- char *devname = NULL;
+ char *dev_name = NULL;
char *point_to = NULL;
char *to_point = NULL;
char *target;
@@ -268,7 +271,7 @@ int main (int argc, char **argv)
point_to = optarg;
break;
case 't':
- devname = optarg;
+ dev_name = optarg;
break;
case 'p':
protocol = optarg;
@@ -278,7 +281,7 @@ int main (int argc, char **argv)
argc -= optind;
argv += optind;
- if ((argc != 1 && argc != 2) || (devname == NULL) ||
+ if ((argc != 1 && argc != 2) || (dev_name == NULL) ||
(point_to == NULL) || (to_point == NULL)) {
usage();
}
@@ -302,7 +305,7 @@ int main (int argc, char **argv)
exit(2);
}
- if(tun_open(devname, &t_laddr, to_point)) {
+ if(tun_open(dev_name, &t_laddr, to_point)) {
closelog();
exit(3);
}
@@ -386,7 +389,7 @@ int main (int argc, char **argv)
}
static void
-usage()
+usage(void)
{
fprintf(stderr,
"usage: nos-tun -t tunnel -s source -d destination -p protocol_number [source] target\n");
diff --git a/sbin/ping6/ping6.8 b/sbin/ping6/ping6.8
index 3897a90..3298dea 100644
--- a/sbin/ping6/ping6.8
+++ b/sbin/ping6/ping6.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 27, 2008
+.Dd April 20, 2010
.Dt PING6 8
.Os
.Sh NAME
@@ -40,9 +40,9 @@ packets to network hosts
.Sh SYNOPSIS
.Nm
.\" without ipsec, or new ipsec
-.Op Fl dfHmnNoqrRtvwW
+.Op Fl DdfHmnNoqrRtvwW
.\" old ipsec
-.\" .Op Fl AdEfmnNqRtvwW
+.\" .Op Fl ADdEfmnNqRtvwW
.Bk -words
.Op Fl a Ar addrtype
.Ek
@@ -141,6 +141,8 @@ Stop after sending
.Ar count
.Tn ECHO_RESPONSE
packets.
+.It Fl D
+Disable IPv6 fragmentation.
.It Fl d
Set the
.Dv SO_DEBUG
diff --git a/sbin/ping6/ping6.c b/sbin/ping6/ping6.c
index f7dba27..69a98b2 100644
--- a/sbin/ping6/ping6.c
+++ b/sbin/ping6/ping6.c
@@ -191,6 +191,7 @@ struct tv32 {
#define F_ONCE 0x200000
#define F_AUDIBLE 0x400000
#define F_MISSED 0x800000
+#define F_DONTFRAG 0x1000000
#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
u_int options;
@@ -349,7 +350,7 @@ main(argc, argv)
#endif /*IPSEC_POLICY_IPSEC*/
#endif
while ((ch = getopt(argc, argv,
- "a:b:c:dfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
+ "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
#undef ADDOPTS
switch (ch) {
case 'a':
@@ -415,6 +416,9 @@ main(argc, argv)
errx(1,
"illegal number of packets -- %s", optarg);
break;
+ case 'D':
+ options |= F_DONTFRAG;
+ break;
case 'd':
options |= F_SO_DEBUG;
break;
@@ -742,7 +746,11 @@ main(argc, argv)
for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t))
*((u_int32_t *)&nonce[i]) = arc4random();
#endif
-
+ optval = 1;
+ if (options & F_DONTFRAG)
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
+ &optval, sizeof(optval)) == -1)
+ err(1, "IPV6_DONTFRAG");
hold = 1;
if (options & F_SO_DEBUG)
@@ -2780,7 +2788,7 @@ usage()
"A"
#endif
"usage: ping6 [-"
- "d"
+ "Dd"
#if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC)
"E"
#endif
diff --git a/sbin/quotacheck/quotacheck.8 b/sbin/quotacheck/quotacheck.8
index e8f4d9c..1c34cd3 100644
--- a/sbin/quotacheck/quotacheck.8
+++ b/sbin/quotacheck/quotacheck.8
@@ -100,7 +100,7 @@ is zero, parallel passes are run as per
.Xr fsck 8 .
This option is deprecated and parallel passes are always run
as per
-.Xf fsck 8.
+.Xr fsck 8 .
.It Fl u
Only user quotas listed in
.Pa /etc/fstab
diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8
index ffb9115..c66860f 100644
--- a/sbin/setkey/setkey.8
+++ b/sbin/setkey/setkey.8
@@ -674,7 +674,7 @@ add 10.0.11.41 10.0.11.33 esp 0x10001
-A hmac-md5 "authentication!!" ;
.Ed
-Get the SA information assocaited with first example above:
+Get the SA information associated with first example above:
.Bd -literal -offset
get 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 ;
diff --git a/sbin/spppcontrol/spppcontrol.8 b/sbin/spppcontrol/spppcontrol.8
index 4389c8f..4d948a6 100644
--- a/sbin/spppcontrol/spppcontrol.8
+++ b/sbin/spppcontrol/spppcontrol.8
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 30, 2001
-.Os
.Dt SPPPCONTROL 8
+.Os
.Sh NAME
.Nm spppcontrol
.Nd display or set parameters for an sppp interface
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 5d0025b..d96450b 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -382,6 +382,7 @@ S_timeval(int l2, void *p)
if (*p2 == '\n')
*p2 = '\0';
fputs(p1, stdout);
+ free(p1);
return (0);
}
diff --git a/sbin/tunefs/Makefile b/sbin/tunefs/Makefile
index d501d10..d5313c4 100644
--- a/sbin/tunefs/Makefile
+++ b/sbin/tunefs/Makefile
@@ -6,4 +6,6 @@ DPADD= ${LIBUFS}
LDADD= -lufs
MAN= tunefs.8
+WARNS= 3
+
.include <bsd.prog.mk>
diff --git a/sbin/tunefs/tunefs.8 b/sbin/tunefs/tunefs.8
index 53e463c..a883cd4 100644
--- a/sbin/tunefs/tunefs.8
+++ b/sbin/tunefs/tunefs.8
@@ -28,7 +28,7 @@
.\" @(#)tunefs.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd October 21, 2009
+.Dd March 6, 2010
.Dt TUNEFS 8
.Os
.Sh NAME
@@ -40,6 +40,7 @@
.Op Fl a Cm enable | disable
.Op Fl e Ar maxbpg
.Op Fl f Ar avgfilesize
+.Op Fl j Cm enable | disable
.Op Fl J Cm enable | disable
.Op Fl L Ar volname
.Op Fl l Cm enable | disable
@@ -49,6 +50,7 @@
.Op Fl o Cm space | time
.Op Fl p
.Op Fl s Ar avgfpdir
+.Op Fl S Ar size
.Ar special | filesystem
.Sh DESCRIPTION
The
@@ -89,6 +91,8 @@ For file systems with exclusively large files,
this parameter should be set higher.
.It Fl f Ar avgfilesize
Specify the expected average file size.
+.It Fl j Cm enable | disable
+Turn on/off soft updates journaling.
.It Fl J Cm enable | disable
Turn on/off gjournal flag.
.It Fl L Ar volname
@@ -136,6 +140,9 @@ obtained from the
utility.
.It Fl s Ar avgfpdir
Specify the expected number of files per directory.
+.It Fl S Ar size
+Specify the softdep journal size in bytes.
+The minimum is 4M.
.El
.Pp
At least one of the above flags is required.
diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c
index e4adb52..a10b35d 100644
--- a/sbin/tunefs/tunefs.c
+++ b/sbin/tunefs/tunefs.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
+#include <ufs/ufs/dir.h>
#include <ctype.h>
#include <err.h>
@@ -61,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <unistd.h>
@@ -72,16 +74,20 @@ struct uufsd disk;
void usage(void);
void printfs(void);
+int journal_alloc(int64_t size);
+void journal_clear(void);
+void sbdirty(void);
int
main(int argc, char *argv[])
{
- char *avalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
+ char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue;
const char *special, *on;
const char *name;
int active;
- int Aflag, aflag, eflag, evalue, fflag, fvalue, Jflag, Lflag, lflag;
- int mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag, svalue;
+ int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, Lflag;
+ int lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag;
+ int svalue, Sflag, Svalue;
int ch, found_arg, i;
const char *chg[2];
struct ufs_args args;
@@ -89,13 +95,13 @@ main(int argc, char *argv[])
if (argc < 3)
usage();
- Aflag = aflag = eflag = fflag = Jflag = Lflag = lflag = mflag = 0;
- Nflag = nflag = oflag = pflag = sflag = 0;
- avalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
- evalue = fvalue = mvalue = ovalue = svalue = 0;
+ Aflag = aflag = eflag = fflag = jflag = Jflag = Lflag = lflag = 0;
+ mflag = Nflag = nflag = oflag = pflag = sflag = 0;
+ avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL;
+ evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0;
active = 0;
found_arg = 0; /* At least one arg is required. */
- while ((ch = getopt(argc, argv, "Aa:e:f:J:L:l:m:N:n:o:ps:")) != -1)
+ while ((ch = getopt(argc, argv, "Aa:e:f:j:J:L:l:m:N:n:o:ps:S:")) != -1)
switch (ch) {
case 'A':
@@ -135,6 +141,18 @@ main(int argc, char *argv[])
fflag = 1;
break;
+ case 'j':
+ found_arg = 1;
+ name = "softdep journaled file system";
+ jvalue = optarg;
+ if (strcmp(jvalue, "enable") &&
+ strcmp(jvalue, "disable")) {
+ errx(10, "bad %s (options are %s)",
+ name, "`enable' or `disable'");
+ }
+ jflag = 1;
+ break;
+
case 'J':
found_arg = 1;
name = "gjournaled file system";
@@ -240,6 +258,16 @@ main(int argc, char *argv[])
sflag = 1;
break;
+ case 'S':
+ found_arg = 1;
+ name = "Softdep Journal Size";
+ Svalue = atoi(optarg);
+ if (Svalue < SUJ_MIN)
+ errx(10, "%s must be >= %d (was %s)",
+ name, SUJ_MIN, optarg);
+ Sflag = 1;
+ break;
+
default:
usage();
}
@@ -310,6 +338,33 @@ main(int argc, char *argv[])
sblock.fs_avgfilesize = fvalue;
}
}
+ if (jflag) {
+ name = "soft updates journaling";
+ if (strcmp(jvalue, "enable") == 0) {
+ if ((sblock.fs_flags & (FS_DOSOFTDEP | FS_SUJ)) ==
+ (FS_DOSOFTDEP | FS_SUJ)) {
+ warnx("%s remains unchanged as enabled", name);
+ } else if (sblock.fs_clean == 0) {
+ warnx("%s cannot be enabled until fsck is run",
+ name);
+ } else if (journal_alloc(Svalue) != 0) {
+ warnx("%s can not be enabled", name);
+ } else {
+ sblock.fs_flags |= FS_DOSOFTDEP | FS_SUJ;
+ warnx("%s set", name);
+ }
+ } else if (strcmp(jvalue, "disable") == 0) {
+ if ((~sblock.fs_flags & FS_SUJ) == FS_SUJ) {
+ warnx("%s remains unchanged as disabled", name);
+ } else {
+ journal_clear();
+ sblock.fs_flags &= ~(FS_DOSOFTDEP | FS_SUJ);
+ sblock.fs_sujfree = 0;
+ warnx("%s cleared, "
+ "remove .sujournal to reclaim space", name);
+ }
+ }
+ }
if (Jflag) {
name = "gjournal";
if (strcmp(Jvalue, "enable") == 0) {
@@ -456,6 +511,500 @@ err:
}
void
+sbdirty(void)
+{
+ disk.d_fs.fs_flags |= FS_UNCLEAN | FS_NEEDSFSCK;
+ disk.d_fs.fs_clean = 0;
+}
+
+int blocks;
+static char clrbuf[MAXBSIZE];
+
+static ufs2_daddr_t
+journal_balloc(void)
+{
+ ufs2_daddr_t blk;
+ struct cg *cgp;
+ int valid;
+ static int contig = 1;
+
+ cgp = &disk.d_cg;
+ for (;;) {
+ blk = cgballoc(&disk);
+ if (blk > 0)
+ break;
+ /*
+ * If we failed to allocate a block from this cg, move to
+ * the next.
+ */
+ if (cgwrite(&disk) < 0) {
+ warn("Failed to write updated cg");
+ return (-1);
+ }
+ while ((valid = cgread(&disk)) == 1) {
+ /*
+ * Try to minimize fragmentation by requiring a minimum
+ * number of blocks present.
+ */
+ if (cgp->cg_cs.cs_nbfree > blocks / 8)
+ break;
+ if (contig == 0 && cgp->cg_cs.cs_nbfree)
+ break;
+ }
+ if (valid)
+ continue;
+ /*
+ * Try once through looking only for large contiguous regions
+ * and again taking any space we can find.
+ */
+ if (contig) {
+ contig = 0;
+ disk.d_ccg = 0;
+ warnx("Journal file fragmented.");
+ continue;
+ }
+ warnx("Failed to find sufficient free blocks for the journal");
+ return -1;
+ }
+ if (bwrite(&disk, fsbtodb(&sblock, blk), clrbuf,
+ sblock.fs_bsize) <= 0) {
+ warn("Failed to initialize new block");
+ return -1;
+ }
+ return (blk);
+}
+
+/*
+ * Search a directory block for the SUJ_FILE.
+ */
+static ino_t
+dir_search(ufs2_daddr_t blk, int bytes)
+{
+ char block[MAXBSIZE];
+ struct direct *dp;
+ int off;
+
+ if (bread(&disk, fsbtodb(&sblock, blk), block, bytes) <= 0) {
+ warn("Failed to read dir block");
+ return (-1);
+ }
+ for (off = 0; off < bytes; off += dp->d_reclen) {
+ dp = (struct direct *)&block[off];
+ if (dp->d_reclen == 0)
+ break;
+ if (dp->d_ino == 0)
+ continue;
+ if (dp->d_namlen != strlen(SUJ_FILE))
+ continue;
+ if (bcmp(dp->d_name, SUJ_FILE, dp->d_namlen) != 0)
+ continue;
+ return (dp->d_ino);
+ }
+
+ return (0);
+}
+
+/*
+ * Search in the ROOTINO for the SUJ_FILE. If it exists we can not enable
+ * journaling.
+ */
+static ino_t
+journal_findfile(void)
+{
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+ ino_t ino;
+ int mode;
+ void *ip;
+ int i;
+
+ if (getino(&disk, &ip, ROOTINO, &mode) != 0) {
+ warn("Failed to get root inode");
+ return (-1);
+ }
+ dp2 = ip;
+ dp1 = ip;
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ if ((off_t)dp1->di_size >= lblktosize(&sblock, NDADDR)) {
+ warnx("ROOTINO extends beyond direct blocks.");
+ return (-1);
+ }
+ for (i = 0; i < NDADDR; i++) {
+ if (dp1->di_db[i] == 0)
+ break;
+ if ((ino = dir_search(dp1->di_db[i],
+ sblksize(&sblock, (off_t)dp1->di_size, i))) != 0)
+ return (ino);
+ }
+ } else {
+ if ((off_t)dp1->di_size >= lblktosize(&sblock, NDADDR)) {
+ warnx("ROOTINO extends beyond direct blocks.");
+ return (-1);
+ }
+ for (i = 0; i < NDADDR; i++) {
+ if (dp2->di_db[i] == 0)
+ break;
+ if ((ino = dir_search(dp2->di_db[i],
+ sblksize(&sblock, (off_t)dp2->di_size, i))) != 0)
+ return (ino);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Insert the journal at inode 'ino' into directory blk 'blk' at the first
+ * free offset of 'off'. DIRBLKSIZ blocks after off are initialized as
+ * empty.
+ */
+static int
+dir_insert(ufs2_daddr_t blk, off_t off, ino_t ino)
+{
+ struct direct *dp;
+ char block[MAXBSIZE];
+
+ if (bread(&disk, fsbtodb(&sblock, blk), block, sblock.fs_bsize) <= 0) {
+ warn("Failed to read dir block");
+ return (-1);
+ }
+ bzero(&block[off], sblock.fs_bsize - off);
+ dp = (struct direct *)&block[off];
+ dp->d_ino = ino;
+ dp->d_reclen = DIRBLKSIZ;
+ dp->d_type = DT_REG;
+ dp->d_namlen = strlen(SUJ_FILE);
+ bcopy(SUJ_FILE, &dp->d_name, strlen(SUJ_FILE));
+ off += DIRBLKSIZ;
+ for (; off < sblock.fs_bsize; off += DIRBLKSIZ) {
+ dp = (struct direct *)&block[off];
+ dp->d_ino = 0;
+ dp->d_reclen = DIRBLKSIZ;
+ dp->d_type = DT_UNKNOWN;
+ }
+ if (bwrite(&disk, fsbtodb(&sblock, blk), block, sblock.fs_bsize) <= 0) {
+ warn("Failed to write dir block");
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Extend a directory block in 'blk' by copying it to a full size block
+ * and inserting the new journal inode into .sujournal.
+ */
+static int
+dir_extend(ufs2_daddr_t blk, ufs2_daddr_t nblk, off_t size, ino_t ino)
+{
+ char block[MAXBSIZE];
+
+ if (bread(&disk, fsbtodb(&sblock, blk), block, size) <= 0) {
+ warn("Failed to read dir block");
+ return (-1);
+ }
+ if (bwrite(&disk, fsbtodb(&sblock, nblk), block, size) <= 0) {
+ warn("Failed to write dir block");
+ return (-1);
+ }
+
+ return dir_insert(nblk, size, ino);
+}
+
+/*
+ * Insert the journal file into the ROOTINO directory. We always extend the
+ * last frag
+ */
+static int
+journal_insertfile(ino_t ino)
+{
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+ void *ip;
+ ufs2_daddr_t nblk;
+ ufs2_daddr_t blk;
+ ufs_lbn_t lbn;
+ int size;
+ int mode;
+ int off;
+
+ if (getino(&disk, &ip, ROOTINO, &mode) != 0) {
+ warn("Failed to get root inode");
+ sbdirty();
+ return (-1);
+ }
+ dp2 = ip;
+ dp1 = ip;
+ blk = 0;
+ size = 0;
+ nblk = journal_balloc();
+ if (nblk <= 0)
+ return (-1);
+ /*
+ * For simplicity sake we aways extend the ROOTINO into a new
+ * directory block rather than searching for space and inserting
+ * into an existing block. However, if the rootino has frags
+ * have to free them and extend the block.
+ */
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ lbn = lblkno(&sblock, dp1->di_size);
+ off = blkoff(&sblock, dp1->di_size);
+ blk = dp1->di_db[lbn];
+ size = sblksize(&sblock, (off_t)dp1->di_size, lbn);
+ } else {
+ lbn = lblkno(&sblock, dp2->di_size);
+ off = blkoff(&sblock, dp2->di_size);
+ blk = dp2->di_db[lbn];
+ size = sblksize(&sblock, (off_t)dp2->di_size, lbn);
+ }
+ if (off != 0) {
+ if (dir_extend(blk, nblk, off, ino) == -1)
+ return (-1);
+ } else {
+ blk = 0;
+ if (dir_insert(nblk, 0, ino) == -1)
+ return (-1);
+ }
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ dp1->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE;
+ dp1->di_db[lbn] = nblk;
+ dp1->di_size = lblktosize(&sblock, lbn+1);
+ } else {
+ dp2->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE;
+ dp2->di_db[lbn] = nblk;
+ dp2->di_size = lblktosize(&sblock, lbn+1);
+ }
+ if (putino(&disk) < 0) {
+ warn("Failed to write root inode");
+ return (-1);
+ }
+ if (cgwrite(&disk) < 0) {
+ warn("Failed to write updated cg");
+ sbdirty();
+ return (-1);
+ }
+ if (blk) {
+ if (cgbfree(&disk, blk, size) < 0) {
+ warn("Failed to write cg");
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+indir_fill(ufs2_daddr_t blk, int level, int *resid)
+{
+ char indirbuf[MAXBSIZE];
+ ufs1_daddr_t *bap1;
+ ufs2_daddr_t *bap2;
+ ufs2_daddr_t nblk;
+ int ncnt;
+ int cnt;
+ int i;
+
+ bzero(indirbuf, sizeof(indirbuf));
+ bap1 = (ufs1_daddr_t *)indirbuf;
+ bap2 = (void *)bap1;
+ cnt = 0;
+ for (i = 0; i < NINDIR(&sblock) && *resid != 0; i++) {
+ nblk = journal_balloc();
+ if (nblk <= 0)
+ return (-1);
+ cnt++;
+ if (sblock.fs_magic == FS_UFS1_MAGIC)
+ *bap1++ = nblk;
+ else
+ *bap2++ = nblk;
+ if (level != 0) {
+ ncnt = indir_fill(nblk, level - 1, resid);
+ if (ncnt <= 0)
+ return (-1);
+ cnt += ncnt;
+ } else
+ (*resid)--;
+ }
+ if (bwrite(&disk, fsbtodb(&sblock, blk), indirbuf,
+ sblock.fs_bsize) <= 0) {
+ warn("Failed to write indirect");
+ return (-1);
+ }
+ return (cnt);
+}
+
+/*
+ * Clear the flag bits so the journal can be removed.
+ */
+void
+journal_clear(void)
+{
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+ ino_t ino;
+ int mode;
+ void *ip;
+
+ ino = journal_findfile();
+ if (ino == (ino_t)-1 || ino == 0) {
+ warnx("Journal file does not exist");
+ return;
+ }
+ printf("Clearing journal flags from inode %d\n", ino);
+ if (getino(&disk, &ip, ino, &mode) != 0) {
+ warn("Failed to get journal inode");
+ return;
+ }
+ dp2 = ip;
+ dp1 = ip;
+ if (sblock.fs_magic == FS_UFS1_MAGIC)
+ dp1->di_flags = 0;
+ else
+ dp2->di_flags = 0;
+ if (putino(&disk) < 0) {
+ warn("Failed to write journal inode");
+ return;
+ }
+}
+
+int
+journal_alloc(int64_t size)
+{
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+ ufs2_daddr_t blk;
+ void *ip;
+ struct cg *cgp;
+ int resid;
+ ino_t ino;
+ int blks;
+ int mode;
+ int i;
+
+ cgp = &disk.d_cg;
+ ino = 0;
+
+ /*
+ * If the journal file exists we can't allocate it.
+ */
+ ino = journal_findfile();
+ if (ino == (ino_t)-1)
+ return (-1);
+ if (ino > 0) {
+ warnx("Journal file %s already exists, please remove.",
+ SUJ_FILE);
+ return (-1);
+ }
+ /*
+ * If the user didn't supply a size pick one based on the filesystem
+ * size constrained with hardcoded MIN and MAX values. We opt for
+ * 1/1024th of the filesystem up to MAX but not exceeding one CG and
+ * not less than the MIN.
+ */
+ if (size == 0) {
+ size = (sblock.fs_size * sblock.fs_bsize) / 1024;
+ size = MIN(SUJ_MAX, size);
+ if (size / sblock.fs_fsize > sblock.fs_fpg)
+ size = sblock.fs_fpg * sblock.fs_fsize;
+ size = MAX(SUJ_MIN, size);
+ }
+ resid = blocks = size / sblock.fs_bsize;
+ if (sblock.fs_cstotal.cs_nbfree < blocks) {
+ warn("Insufficient free space for %jd byte journal", size);
+ return (-1);
+ }
+ /*
+ * Find a cg with enough blocks to satisfy the journal
+ * size. Presently the journal does not span cgs.
+ */
+ while (cgread(&disk) == 1) {
+ if (cgp->cg_cs.cs_nifree == 0)
+ continue;
+ ino = cgialloc(&disk);
+ if (ino <= 0)
+ break;
+ printf("Using inode %d in cg %d for %jd byte journal\n",
+ ino, cgp->cg_cgx, size);
+ if (getino(&disk, &ip, ino, &mode) != 0) {
+ warn("Failed to get allocated inode");
+ sbdirty();
+ goto out;
+ }
+ /*
+ * We leave fields unrelated to the number of allocated
+ * blocks and size uninitialized. This causes legacy
+ * fsck implementations to clear the inode.
+ */
+ dp2 = ip;
+ dp1 = ip;
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ bzero(dp1, sizeof(*dp1));
+ dp1->di_size = size;
+ dp1->di_mode = IFREG | IREAD;
+ dp1->di_nlink = 1;
+ dp1->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP;
+ } else {
+ bzero(dp2, sizeof(*dp2));
+ dp2->di_size = size;
+ dp2->di_mode = IFREG | IREAD;
+ dp2->di_nlink = 1;
+ dp2->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP;
+ }
+ for (i = 0; i < NDADDR && resid; i++, resid--) {
+ blk = journal_balloc();
+ if (blk <= 0)
+ goto out;
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ dp1->di_db[i] = blk;
+ dp1->di_blocks++;
+ } else {
+ dp2->di_db[i] = blk;
+ dp2->di_blocks++;
+ }
+ }
+ for (i = 0; i < NIADDR && resid; i++) {
+ blk = journal_balloc();
+ if (blk <= 0)
+ goto out;
+ blks = indir_fill(blk, i, &resid) + 1;
+ if (blks <= 0) {
+ sbdirty();
+ goto out;
+ }
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ dp1->di_ib[i] = blk;
+ dp1->di_blocks += blks;
+ } else {
+ dp2->di_ib[i] = blk;
+ dp2->di_blocks += blks;
+ }
+ }
+ if (sblock.fs_magic == FS_UFS1_MAGIC)
+ dp1->di_blocks *= sblock.fs_bsize / disk.d_bsize;
+ else
+ dp2->di_blocks *= sblock.fs_bsize / disk.d_bsize;
+ if (putino(&disk) < 0) {
+ warn("Failed to write inode");
+ sbdirty();
+ return (-1);
+ }
+ if (cgwrite(&disk) < 0) {
+ warn("Failed to write updated cg");
+ sbdirty();
+ return (-1);
+ }
+ if (journal_insertfile(ino) < 0) {
+ sbdirty();
+ return (-1);
+ }
+ sblock.fs_sujfree = 0;
+ return (0);
+ }
+ warnx("Insufficient free space for the journal.");
+out:
+ return (-1);
+}
+
+void
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n",
@@ -477,6 +1026,8 @@ printfs(void)
(sblock.fs_flags & FS_MULTILABEL)? "enabled" : "disabled");
warnx("soft updates: (-n) %s",
(sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled");
+ warnx("soft update journaling: (-j) %s",
+ (sblock.fs_flags & FS_SUJ)? "enabled" : "disabled");
warnx("gjournal: (-J) %s",
(sblock.fs_flags & FS_GJOURNAL)? "enabled" : "disabled");
warnx("maximum blocks per file in a cylinder group: (-e) %d",
diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc
index 4da2d8b..d91a26a 100644
--- a/secure/lib/libcrypto/Makefile.inc
+++ b/secure/lib/libcrypto/Makefile.inc
@@ -2,6 +2,10 @@
.include <bsd.own.mk>
+# OpenSSL version used for manual page generation
+OPENSSL_VER= 0.9.8n
+OPENSSL_DATE= 2010-03-24
+
LCRYPTO_SRC= ${.CURDIR}/../../../crypto/openssl
LCRYPTO_DOC= ${.CURDIR}/../../../crypto/openssl/doc
@@ -34,7 +38,8 @@ man-update:
@(sec=${manpage:E}; \
pod=${manpage:R}.pod; \
cp ${LCRYPTO_DOC}/${_docs}/$$pod .; \
- pod2man --section=$$sec --release="0.9.8k" --center="OpenSSL" \
+ pod2man --section=$$sec --release="${OPENSSL_VER}" \
+ --date="${OPENSSL_DATE}" --center="OpenSSL" \
$$pod > ${.CURDIR}/man/${manpage}; \
rm -f $$pod; \
${ECHO} ${manpage})
diff --git a/secure/lib/libcrypto/Makefile.man b/secure/lib/libcrypto/Makefile.man
index e6cc9b8..58ebff1 100644
--- a/secure/lib/libcrypto/Makefile.man
+++ b/secure/lib/libcrypto/Makefile.man
@@ -708,6 +708,72 @@ MLINKS+= mdc2.3 MDC2_Init.3
MLINKS+= mdc2.3 MDC2_Update.3
MLINKS+= mdc2.3 MDC2_Final.3
MLINKS+= pem.3 PEM.3
+MLINKS+= pem.3 PEM_read_bio_PrivateKey.3
+MLINKS+= pem.3 PEM_read_PrivateKey.3
+MLINKS+= pem.3 PEM_write_bio_PrivateKey.3
+MLINKS+= pem.3 PEM_write_PrivateKey.3
+MLINKS+= pem.3 PEM_write_bio_PKCS8PrivateKey.3
+MLINKS+= pem.3 PEM_write_PKCS8PrivateKey.3
+MLINKS+= pem.3 PEM_write_bio_PKCS8PrivateKey_nid.3
+MLINKS+= pem.3 PEM_write_PKCS8PrivateKey_nid.3
+MLINKS+= pem.3 PEM_read_bio_PUBKEY.3
+MLINKS+= pem.3 PEM_read_PUBKEY.3
+MLINKS+= pem.3 PEM_write_bio_PUBKEY.3
+MLINKS+= pem.3 PEM_write_PUBKEY.3
+MLINKS+= pem.3 PEM_read_bio_RSAPrivateKey.3
+MLINKS+= pem.3 PEM_read_RSAPrivateKey.3
+MLINKS+= pem.3 PEM_write_bio_RSAPrivateKey.3
+MLINKS+= pem.3 PEM_write_RSAPrivateKey.3
+MLINKS+= pem.3 PEM_read_bio_RSAPublicKey.3
+MLINKS+= pem.3 PEM_read_RSAPublicKey.3
+MLINKS+= pem.3 PEM_write_bio_RSAPublicKey.3
+MLINKS+= pem.3 PEM_write_RSAPublicKey.3
+MLINKS+= pem.3 PEM_read_bio_RSA_PUBKEY.3
+MLINKS+= pem.3 PEM_read_RSA_PUBKEY.3
+MLINKS+= pem.3 PEM_write_bio_RSA_PUBKEY.3
+MLINKS+= pem.3 PEM_write_RSA_PUBKEY.3
+MLINKS+= pem.3 PEM_read_bio_DSAPrivateKey.3
+MLINKS+= pem.3 PEM_read_DSAPrivateKey.3
+MLINKS+= pem.3 PEM_write_bio_DSAPrivateKey.3
+MLINKS+= pem.3 PEM_write_DSAPrivateKey.3
+MLINKS+= pem.3 PEM_read_bio_DSA_PUBKEY.3
+MLINKS+= pem.3 PEM_read_DSA_PUBKEY.3
+MLINKS+= pem.3 PEM_write_bio_DSA_PUBKEY.3
+MLINKS+= pem.3 PEM_write_DSA_PUBKEY.3
+MLINKS+= pem.3 PEM_read_bio_DSAparams.3
+MLINKS+= pem.3 PEM_read_DSAparams.3
+MLINKS+= pem.3 PEM_write_bio_DSAparams.3
+MLINKS+= pem.3 PEM_write_DSAparams.3
+MLINKS+= pem.3 PEM_read_bio_DHparams.3
+MLINKS+= pem.3 PEM_read_DHparams.3
+MLINKS+= pem.3 PEM_write_bio_DHparams.3
+MLINKS+= pem.3 PEM_write_DHparams.3
+MLINKS+= pem.3 PEM_read_bio_X509.3
+MLINKS+= pem.3 PEM_read_X509.3
+MLINKS+= pem.3 PEM_write_bio_X509.3
+MLINKS+= pem.3 PEM_write_X509.3
+MLINKS+= pem.3 PEM_read_bio_X509_AUX.3
+MLINKS+= pem.3 PEM_read_X509_AUX.3
+MLINKS+= pem.3 PEM_write_bio_X509_AUX.3
+MLINKS+= pem.3 PEM_write_X509_AUX.3
+MLINKS+= pem.3 PEM_read_bio_X509_REQ.3
+MLINKS+= pem.3 PEM_read_X509_REQ.3
+MLINKS+= pem.3 PEM_write_bio_X509_REQ.3
+MLINKS+= pem.3 PEM_write_X509_REQ.3
+MLINKS+= pem.3 PEM_write_bio_X509_REQ_NEW.3
+MLINKS+= pem.3 PEM_write_X509_REQ_NEW.3
+MLINKS+= pem.3 PEM_read_bio_X509_CRL.3
+MLINKS+= pem.3 PEM_read_X509_CRL.3
+MLINKS+= pem.3 PEM_write_bio_X509_CRL.3
+MLINKS+= pem.3 PEM_write_X509_CRL.3
+MLINKS+= pem.3 PEM_read_bio_PKCS7.3
+MLINKS+= pem.3 PEM_read_PKCS7.3
+MLINKS+= pem.3 PEM_write_bio_PKCS7.3
+MLINKS+= pem.3 PEM_write_PKCS7.3
+MLINKS+= pem.3 PEM_read_bio_NETSCAPE_CERT_SEQUENCE.3
+MLINKS+= pem.3 PEM_read_NETSCAPE_CERT_SEQUENCE.3
+MLINKS+= pem.3 PEM_write_bio_NETSCAPE_CERT_SEQUENCE.3
+MLINKS+= pem.3 PEM_write_NETSCAPE_CERT_SEQUENCE.3
MLINKS+= rc4.3 RC4_set_key.3
MLINKS+= rc4.3 RC4.3
MLINKS+= ripemd.3 RIPEMD160.3
diff --git a/secure/lib/libcrypto/man/ASN1_OBJECT_new.3 b/secure/lib/libcrypto/man/ASN1_OBJECT_new.3
index 044ead9..3aed309 100644
--- a/secure/lib/libcrypto/man/ASN1_OBJECT_new.3
+++ b/secure/lib/libcrypto/man/ASN1_OBJECT_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_OBJECT_new 3"
-.TH ASN1_OBJECT_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ASN1_OBJECT_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ASN1_OBJECT_new, ASN1_OBJECT_free, \- object allocation functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ASN1_STRING_length.3 b/secure/lib/libcrypto/man/ASN1_STRING_length.3
index c835a4a..a5c33a1 100644
--- a/secure/lib/libcrypto/man/ASN1_STRING_length.3
+++ b/secure/lib/libcrypto/man/ASN1_STRING_length.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_STRING_length 3"
-.TH ASN1_STRING_length 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ASN1_STRING_length 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ASN1_STRING_dup, ASN1_STRING_cmp, ASN1_STRING_set, ASN1_STRING_length,
ASN1_STRING_length_set, ASN1_STRING_type, ASN1_STRING_data \-
diff --git a/secure/lib/libcrypto/man/ASN1_STRING_new.3 b/secure/lib/libcrypto/man/ASN1_STRING_new.3
index 3a5b7b3..7f153c1 100644
--- a/secure/lib/libcrypto/man/ASN1_STRING_new.3
+++ b/secure/lib/libcrypto/man/ASN1_STRING_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_STRING_new 3"
-.TH ASN1_STRING_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ASN1_STRING_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ASN1_STRING_new, ASN1_STRING_type_new, ASN1_STRING_free \-
ASN1_STRING allocation functions
diff --git a/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3 b/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3
index bf6137e..1016250 100644
--- a/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3
+++ b/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_STRING_print_ex 3"
-.TH ASN1_STRING_print_ex 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ASN1_STRING_print_ex 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ASN1_STRING_print_ex, ASN1_STRING_print_ex_fp \- ASN1_STRING output routines.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ASN1_generate_nconf.3 b/secure/lib/libcrypto/man/ASN1_generate_nconf.3
index 60fbd8e..09dc95e 100644
--- a/secure/lib/libcrypto/man/ASN1_generate_nconf.3
+++ b/secure/lib/libcrypto/man/ASN1_generate_nconf.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_generate_nconf 3"
-.TH ASN1_generate_nconf 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ASN1_generate_nconf 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ASN1_generate_nconf, ASN1_generate_v3 \- ASN1 generation functions
.SH "SYNOPSIS"
@@ -277,7 +277,7 @@ An IA5String explicitly tagged using \s-1APPLICATION\s0 tagging:
A \s-1BITSTRING\s0 with bits 1 and 5 set and all others zero:
.PP
.Vb 1
-\& FORMAT=BITLIST,BITSTRING:1,5
+\& FORMAT:BITLIST,BITSTRING:1,5
.Ve
.PP
A more complex example using a config file to produce a
diff --git a/secure/lib/libcrypto/man/BIO_ctrl.3 b/secure/lib/libcrypto/man/BIO_ctrl.3
index d7d7708..8162c1c 100644
--- a/secure/lib/libcrypto/man/BIO_ctrl.3
+++ b/secure/lib/libcrypto/man/BIO_ctrl.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_ctrl 3"
-.TH BIO_ctrl 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_ctrl 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset,
BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close,
diff --git a/secure/lib/libcrypto/man/BIO_f_base64.3 b/secure/lib/libcrypto/man/BIO_f_base64.3
index 7ebf925..3bc9ff1 100644
--- a/secure/lib/libcrypto/man/BIO_f_base64.3
+++ b/secure/lib/libcrypto/man/BIO_f_base64.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_base64 3"
-.TH BIO_f_base64 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_f_base64 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_f_base64 \- base64 BIO filter
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_f_buffer.3 b/secure/lib/libcrypto/man/BIO_f_buffer.3
index f3df03d..5218fcc 100644
--- a/secure/lib/libcrypto/man/BIO_f_buffer.3
+++ b/secure/lib/libcrypto/man/BIO_f_buffer.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_buffer 3"
-.TH BIO_f_buffer 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_f_buffer 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_f_buffer \- buffering BIO
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_f_cipher.3 b/secure/lib/libcrypto/man/BIO_f_cipher.3
index 5ecee25..4991bf0 100644
--- a/secure/lib/libcrypto/man/BIO_f_cipher.3
+++ b/secure/lib/libcrypto/man/BIO_f_cipher.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_cipher 3"
-.TH BIO_f_cipher 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_f_cipher 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_f_cipher, BIO_set_cipher, BIO_get_cipher_status, BIO_get_cipher_ctx \- cipher BIO filter
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_f_md.3 b/secure/lib/libcrypto/man/BIO_f_md.3
index 7593cb3..da877f6 100644
--- a/secure/lib/libcrypto/man/BIO_f_md.3
+++ b/secure/lib/libcrypto/man/BIO_f_md.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_md 3"
-.TH BIO_f_md 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_f_md 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_f_md, BIO_set_md, BIO_get_md, BIO_get_md_ctx \- message digest BIO filter
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_f_null.3 b/secure/lib/libcrypto/man/BIO_f_null.3
index b97ff09..dcb3242 100644
--- a/secure/lib/libcrypto/man/BIO_f_null.3
+++ b/secure/lib/libcrypto/man/BIO_f_null.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_null 3"
-.TH BIO_f_null 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_f_null 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_f_null \- null filter
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_f_ssl.3 b/secure/lib/libcrypto/man/BIO_f_ssl.3
index 6d167d7..8d2909d 100644
--- a/secure/lib/libcrypto/man/BIO_f_ssl.3
+++ b/secure/lib/libcrypto/man/BIO_f_ssl.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_ssl 3"
-.TH BIO_f_ssl 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_f_ssl 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_f_ssl, BIO_set_ssl, BIO_get_ssl, BIO_set_ssl_mode, BIO_set_ssl_renegotiate_bytes,
BIO_get_num_renegotiates, BIO_set_ssl_renegotiate_timeout, BIO_new_ssl,
diff --git a/secure/lib/libcrypto/man/BIO_find_type.3 b/secure/lib/libcrypto/man/BIO_find_type.3
index 7f0f54d..2990660 100644
--- a/secure/lib/libcrypto/man/BIO_find_type.3
+++ b/secure/lib/libcrypto/man/BIO_find_type.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_find_type 3"
-.TH BIO_find_type 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_find_type 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_find_type, BIO_next \- BIO chain traversal
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_new.3 b/secure/lib/libcrypto/man/BIO_new.3
index 3c673e9..84085cc 100644
--- a/secure/lib/libcrypto/man/BIO_new.3
+++ b/secure/lib/libcrypto/man/BIO_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_new 3"
-.TH BIO_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_new, BIO_set, BIO_free, BIO_vfree, BIO_free_all \- BIO allocation and freeing functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_push.3 b/secure/lib/libcrypto/man/BIO_push.3
index b20fcc0..6e614c6 100644
--- a/secure/lib/libcrypto/man/BIO_push.3
+++ b/secure/lib/libcrypto/man/BIO_push.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_push 3"
-.TH BIO_push 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_push 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_push, BIO_pop \- add and remove BIOs from a chain.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_read.3 b/secure/lib/libcrypto/man/BIO_read.3
index 03f5544..32e4edc 100644
--- a/secure/lib/libcrypto/man/BIO_read.3
+++ b/secure/lib/libcrypto/man/BIO_read.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_read 3"
-.TH BIO_read 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_read 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_read, BIO_write, BIO_gets, BIO_puts \- BIO I/O functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_s_accept.3 b/secure/lib/libcrypto/man/BIO_s_accept.3
index 13fa94d..7989a10 100644
--- a/secure/lib/libcrypto/man/BIO_s_accept.3
+++ b/secure/lib/libcrypto/man/BIO_s_accept.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_accept 3"
-.TH BIO_s_accept 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_accept 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_accept, BIO_set_accept_port, BIO_get_accept_port,
BIO_set_nbio_accept, BIO_set_accept_bios, BIO_set_bind_mode,
diff --git a/secure/lib/libcrypto/man/BIO_s_bio.3 b/secure/lib/libcrypto/man/BIO_s_bio.3
index 4e9727b..34345d1 100644
--- a/secure/lib/libcrypto/man/BIO_s_bio.3
+++ b/secure/lib/libcrypto/man/BIO_s_bio.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_bio 3"
-.TH BIO_s_bio 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_bio 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_bio, BIO_make_bio_pair, BIO_destroy_bio_pair, BIO_shutdown_wr,
BIO_set_write_buf_size, BIO_get_write_buf_size, BIO_new_bio_pair,
diff --git a/secure/lib/libcrypto/man/BIO_s_connect.3 b/secure/lib/libcrypto/man/BIO_s_connect.3
index ff45678..d214f55 100644
--- a/secure/lib/libcrypto/man/BIO_s_connect.3
+++ b/secure/lib/libcrypto/man/BIO_s_connect.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_connect 3"
-.TH BIO_s_connect 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_connect 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_connect, BIO_set_conn_hostname, BIO_set_conn_port,
BIO_set_conn_ip, BIO_set_conn_int_port, BIO_get_conn_hostname,
diff --git a/secure/lib/libcrypto/man/BIO_s_fd.3 b/secure/lib/libcrypto/man/BIO_s_fd.3
index 124b6ed..0159e38 100644
--- a/secure/lib/libcrypto/man/BIO_s_fd.3
+++ b/secure/lib/libcrypto/man/BIO_s_fd.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_fd 3"
-.TH BIO_s_fd 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_fd 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_fd, BIO_set_fd, BIO_get_fd, BIO_new_fd \- file descriptor BIO
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_s_file.3 b/secure/lib/libcrypto/man/BIO_s_file.3
index 3e200df..d0cd64f 100644
--- a/secure/lib/libcrypto/man/BIO_s_file.3
+++ b/secure/lib/libcrypto/man/BIO_s_file.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_file 3"
-.TH BIO_s_file 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_file 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_file, BIO_new_file, BIO_new_fp, BIO_set_fp, BIO_get_fp,
BIO_read_filename, BIO_write_filename, BIO_append_filename,
diff --git a/secure/lib/libcrypto/man/BIO_s_mem.3 b/secure/lib/libcrypto/man/BIO_s_mem.3
index 5ce453f..737a6f0 100644
--- a/secure/lib/libcrypto/man/BIO_s_mem.3
+++ b/secure/lib/libcrypto/man/BIO_s_mem.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_mem 3"
-.TH BIO_s_mem 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_mem 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_mem, BIO_set_mem_eof_return, BIO_get_mem_data, BIO_set_mem_buf,
BIO_get_mem_ptr, BIO_new_mem_buf \- memory BIO
diff --git a/secure/lib/libcrypto/man/BIO_s_null.3 b/secure/lib/libcrypto/man/BIO_s_null.3
index da1ca33..62774d0 100644
--- a/secure/lib/libcrypto/man/BIO_s_null.3
+++ b/secure/lib/libcrypto/man/BIO_s_null.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_null 3"
-.TH BIO_s_null 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_null 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_null \- null data sink
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_s_socket.3 b/secure/lib/libcrypto/man/BIO_s_socket.3
index 5bad5e2..eef61cc 100644
--- a/secure/lib/libcrypto/man/BIO_s_socket.3
+++ b/secure/lib/libcrypto/man/BIO_s_socket.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_socket 3"
-.TH BIO_s_socket 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_s_socket 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_s_socket, BIO_new_socket \- socket BIO
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BIO_set_callback.3 b/secure/lib/libcrypto/man/BIO_set_callback.3
index bc7b323..18f2dd8 100644
--- a/secure/lib/libcrypto/man/BIO_set_callback.3
+++ b/secure/lib/libcrypto/man/BIO_set_callback.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_set_callback 3"
-.TH BIO_set_callback 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_set_callback 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_set_callback, BIO_get_callback, BIO_set_callback_arg, BIO_get_callback_arg,
BIO_debug_callback \- BIO callback functions
diff --git a/secure/lib/libcrypto/man/BIO_should_retry.3 b/secure/lib/libcrypto/man/BIO_should_retry.3
index 7603d9b..77e6ba6 100644
--- a/secure/lib/libcrypto/man/BIO_should_retry.3
+++ b/secure/lib/libcrypto/man/BIO_should_retry.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_should_retry 3"
-.TH BIO_should_retry 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BIO_should_retry 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BIO_should_retry, BIO_should_read, BIO_should_write,
BIO_should_io_special, BIO_retry_type, BIO_should_retry,
diff --git a/secure/lib/libcrypto/man/BN_BLINDING_new.3 b/secure/lib/libcrypto/man/BN_BLINDING_new.3
index a918738..16935b0 100644
--- a/secure/lib/libcrypto/man/BN_BLINDING_new.3
+++ b/secure/lib/libcrypto/man/BN_BLINDING_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_BLINDING_new 3"
-.TH BN_BLINDING_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_BLINDING_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_BLINDING_new, BN_BLINDING_free, BN_BLINDING_update, BN_BLINDING_convert,
BN_BLINDING_invert, BN_BLINDING_convert_ex, BN_BLINDING_invert_ex,
diff --git a/secure/lib/libcrypto/man/BN_CTX_new.3 b/secure/lib/libcrypto/man/BN_CTX_new.3
index 17167a1..3e03cb7 100644
--- a/secure/lib/libcrypto/man/BN_CTX_new.3
+++ b/secure/lib/libcrypto/man/BN_CTX_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_CTX_new 3"
-.TH BN_CTX_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_CTX_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_CTX_new, BN_CTX_init, BN_CTX_free \- allocate and free BN_CTX structures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_CTX_start.3 b/secure/lib/libcrypto/man/BN_CTX_start.3
index 998f414..4a1b931 100644
--- a/secure/lib/libcrypto/man/BN_CTX_start.3
+++ b/secure/lib/libcrypto/man/BN_CTX_start.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_CTX_start 3"
-.TH BN_CTX_start 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_CTX_start 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_CTX_start, BN_CTX_get, BN_CTX_end \- use temporary BIGNUM variables
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_add.3 b/secure/lib/libcrypto/man/BN_add.3
index 33ac39a..35eac8a 100644
--- a/secure/lib/libcrypto/man/BN_add.3
+++ b/secure/lib/libcrypto/man/BN_add.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_add 3"
-.TH BN_add 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_add 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_add, BN_sub, BN_mul, BN_sqr, BN_div, BN_mod, BN_nnmod, BN_mod_add,
BN_mod_sub, BN_mod_mul, BN_mod_sqr, BN_exp, BN_mod_exp, BN_gcd \-
diff --git a/secure/lib/libcrypto/man/BN_add_word.3 b/secure/lib/libcrypto/man/BN_add_word.3
index 15fffef..84cd93f 100644
--- a/secure/lib/libcrypto/man/BN_add_word.3
+++ b/secure/lib/libcrypto/man/BN_add_word.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_add_word 3"
-.TH BN_add_word 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_add_word 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_add_word, BN_sub_word, BN_mul_word, BN_div_word, BN_mod_word \- arithmetic
functions on BIGNUMs with integers
diff --git a/secure/lib/libcrypto/man/BN_bn2bin.3 b/secure/lib/libcrypto/man/BN_bn2bin.3
index 43643f9..ca7e709 100644
--- a/secure/lib/libcrypto/man/BN_bn2bin.3
+++ b/secure/lib/libcrypto/man/BN_bn2bin.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_bn2bin 3"
-.TH BN_bn2bin 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_bn2bin 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_bn2bin, BN_bin2bn, BN_bn2hex, BN_bn2dec, BN_hex2bn, BN_dec2bn,
BN_print, BN_print_fp, BN_bn2mpi, BN_mpi2bn \- format conversions
diff --git a/secure/lib/libcrypto/man/BN_cmp.3 b/secure/lib/libcrypto/man/BN_cmp.3
index d53a4a9..2bd3faf 100644
--- a/secure/lib/libcrypto/man/BN_cmp.3
+++ b/secure/lib/libcrypto/man/BN_cmp.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_cmp 3"
-.TH BN_cmp 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_cmp 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_cmp, BN_ucmp, BN_is_zero, BN_is_one, BN_is_word, BN_is_odd \- BIGNUM comparison and test functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_copy.3 b/secure/lib/libcrypto/man/BN_copy.3
index cdc1d3f..85185cc 100644
--- a/secure/lib/libcrypto/man/BN_copy.3
+++ b/secure/lib/libcrypto/man/BN_copy.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_copy 3"
-.TH BN_copy 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_copy 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_copy, BN_dup \- copy BIGNUMs
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_generate_prime.3 b/secure/lib/libcrypto/man/BN_generate_prime.3
index 1309ff8..314cf62 100644
--- a/secure/lib/libcrypto/man/BN_generate_prime.3
+++ b/secure/lib/libcrypto/man/BN_generate_prime.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_generate_prime 3"
-.TH BN_generate_prime 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_generate_prime 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_generate_prime, BN_is_prime, BN_is_prime_fasttest \- generate primes and test for primality
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_mod_inverse.3 b/secure/lib/libcrypto/man/BN_mod_inverse.3
index ef3c52d..7b796de 100644
--- a/secure/lib/libcrypto/man/BN_mod_inverse.3
+++ b/secure/lib/libcrypto/man/BN_mod_inverse.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_mod_inverse 3"
-.TH BN_mod_inverse 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_mod_inverse 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_mod_inverse \- compute inverse modulo n
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3 b/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3
index 247af91..c7bda25 100644
--- a/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3
+++ b/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_mod_mul_montgomery 3"
-.TH BN_mod_mul_montgomery 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_mod_mul_montgomery 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_mod_mul_montgomery, BN_MONT_CTX_new, BN_MONT_CTX_init,
BN_MONT_CTX_free, BN_MONT_CTX_set, BN_MONT_CTX_copy,
diff --git a/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3 b/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3
index 4147339..4d1bc01 100644
--- a/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3
+++ b/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_mod_mul_reciprocal 3"
-.TH BN_mod_mul_reciprocal 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_mod_mul_reciprocal 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_mod_mul_reciprocal, BN_div_recp, BN_RECP_CTX_new, BN_RECP_CTX_init,
BN_RECP_CTX_free, BN_RECP_CTX_set \- modular multiplication using
diff --git a/secure/lib/libcrypto/man/BN_new.3 b/secure/lib/libcrypto/man/BN_new.3
index 7a2a6c6..6e7b7f5 100644
--- a/secure/lib/libcrypto/man/BN_new.3
+++ b/secure/lib/libcrypto/man/BN_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_new 3"
-.TH BN_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_new, BN_init, BN_clear, BN_free, BN_clear_free \- allocate and free BIGNUMs
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_num_bytes.3 b/secure/lib/libcrypto/man/BN_num_bytes.3
index 75bab91..ed3654c 100644
--- a/secure/lib/libcrypto/man/BN_num_bytes.3
+++ b/secure/lib/libcrypto/man/BN_num_bytes.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_num_bytes 3"
-.TH BN_num_bytes 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_num_bytes 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_num_bits, BN_num_bytes, BN_num_bits_word \- get BIGNUM size
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_rand.3 b/secure/lib/libcrypto/man/BN_rand.3
index 85dd0b9..f2eadf2 100644
--- a/secure/lib/libcrypto/man/BN_rand.3
+++ b/secure/lib/libcrypto/man/BN_rand.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_rand 3"
-.TH BN_rand 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_rand 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_rand, BN_pseudo_rand \- generate pseudo\-random number
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_set_bit.3 b/secure/lib/libcrypto/man/BN_set_bit.3
index 5c50113..9d66bf9 100644
--- a/secure/lib/libcrypto/man/BN_set_bit.3
+++ b/secure/lib/libcrypto/man/BN_set_bit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_set_bit 3"
-.TH BN_set_bit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_set_bit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_set_bit, BN_clear_bit, BN_is_bit_set, BN_mask_bits, BN_lshift,
BN_lshift1, BN_rshift, BN_rshift1 \- bit operations on BIGNUMs
diff --git a/secure/lib/libcrypto/man/BN_swap.3 b/secure/lib/libcrypto/man/BN_swap.3
index 3d0f3e8..e68a81b 100644
--- a/secure/lib/libcrypto/man/BN_swap.3
+++ b/secure/lib/libcrypto/man/BN_swap.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_swap 3"
-.TH BN_swap 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_swap 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_swap \- exchange BIGNUMs
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/BN_zero.3 b/secure/lib/libcrypto/man/BN_zero.3
index 12a709b..74b654b 100644
--- a/secure/lib/libcrypto/man/BN_zero.3
+++ b/secure/lib/libcrypto/man/BN_zero.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BN_zero 3"
-.TH BN_zero 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH BN_zero 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BN_zero, BN_one, BN_value_one, BN_set_word, BN_get_word \- BIGNUM assignment
operations
diff --git a/secure/lib/libcrypto/man/CONF_modules_free.3 b/secure/lib/libcrypto/man/CONF_modules_free.3
index f0c0f3f..5a5e279 100644
--- a/secure/lib/libcrypto/man/CONF_modules_free.3
+++ b/secure/lib/libcrypto/man/CONF_modules_free.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CONF_modules_free 3"
-.TH CONF_modules_free 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CONF_modules_free 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
.Vb 2
\& CONF_modules_free, CONF_modules_finish, CONF_modules_unload -
diff --git a/secure/lib/libcrypto/man/CONF_modules_load_file.3 b/secure/lib/libcrypto/man/CONF_modules_load_file.3
index 333b067..15ec32c 100644
--- a/secure/lib/libcrypto/man/CONF_modules_load_file.3
+++ b/secure/lib/libcrypto/man/CONF_modules_load_file.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CONF_modules_load_file 3"
-.TH CONF_modules_load_file 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CONF_modules_load_file 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
.Vb 1
\& CONF_modules_load_file, CONF_modules_load - OpenSSL configuration functions
diff --git a/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3 b/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3
index e88ba13..338309e 100644
--- a/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3
+++ b/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CRYPTO_set_ex_data 3"
-.TH CRYPTO_set_ex_data 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CRYPTO_set_ex_data 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
CRYPTO_set_ex_data, CRYPTO_get_ex_data \- internal application specific data functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DH_generate_key.3 b/secure/lib/libcrypto/man/DH_generate_key.3
index 17a5dcf..a5126e0 100644
--- a/secure/lib/libcrypto/man/DH_generate_key.3
+++ b/secure/lib/libcrypto/man/DH_generate_key.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DH_generate_key 3"
-.TH DH_generate_key 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DH_generate_key 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DH_generate_key, DH_compute_key \- perform Diffie\-Hellman key exchange
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DH_generate_parameters.3 b/secure/lib/libcrypto/man/DH_generate_parameters.3
index 92e5a7a..fd9cae0 100644
--- a/secure/lib/libcrypto/man/DH_generate_parameters.3
+++ b/secure/lib/libcrypto/man/DH_generate_parameters.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DH_generate_parameters 3"
-.TH DH_generate_parameters 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DH_generate_parameters 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DH_generate_parameters, DH_check \- generate and check Diffie\-Hellman parameters
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DH_get_ex_new_index.3 b/secure/lib/libcrypto/man/DH_get_ex_new_index.3
index ffd68a7..05f15c3 100644
--- a/secure/lib/libcrypto/man/DH_get_ex_new_index.3
+++ b/secure/lib/libcrypto/man/DH_get_ex_new_index.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DH_get_ex_new_index 3"
-.TH DH_get_ex_new_index 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DH_get_ex_new_index 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DH_get_ex_new_index, DH_set_ex_data, DH_get_ex_data \- add application specific data to DH structures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DH_new.3 b/secure/lib/libcrypto/man/DH_new.3
index 96ec9c1..6ea4af5 100644
--- a/secure/lib/libcrypto/man/DH_new.3
+++ b/secure/lib/libcrypto/man/DH_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DH_new 3"
-.TH DH_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DH_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DH_new, DH_free \- allocate and free DH objects
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DH_set_method.3 b/secure/lib/libcrypto/man/DH_set_method.3
index 20cff8e..1c1f5ae 100644
--- a/secure/lib/libcrypto/man/DH_set_method.3
+++ b/secure/lib/libcrypto/man/DH_set_method.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DH_set_method 3"
-.TH DH_set_method 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DH_set_method 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DH_set_default_method, DH_get_default_method,
DH_set_method, DH_new_method, DH_OpenSSL \- select DH method
diff --git a/secure/lib/libcrypto/man/DH_size.3 b/secure/lib/libcrypto/man/DH_size.3
index 61da06e..015c45b 100644
--- a/secure/lib/libcrypto/man/DH_size.3
+++ b/secure/lib/libcrypto/man/DH_size.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DH_size 3"
-.TH DH_size 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DH_size 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DH_size \- get Diffie\-Hellman prime size
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_SIG_new.3 b/secure/lib/libcrypto/man/DSA_SIG_new.3
index 851c42b..e199ae9 100644
--- a/secure/lib/libcrypto/man/DSA_SIG_new.3
+++ b/secure/lib/libcrypto/man/DSA_SIG_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_SIG_new 3"
-.TH DSA_SIG_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_SIG_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_SIG_new, DSA_SIG_free \- allocate and free DSA signature objects
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_do_sign.3 b/secure/lib/libcrypto/man/DSA_do_sign.3
index 822ef04..83dec82 100644
--- a/secure/lib/libcrypto/man/DSA_do_sign.3
+++ b/secure/lib/libcrypto/man/DSA_do_sign.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_do_sign 3"
-.TH DSA_do_sign 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_do_sign 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_do_sign, DSA_do_verify \- raw DSA signature operations
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_dup_DH.3 b/secure/lib/libcrypto/man/DSA_dup_DH.3
index dff1b77..3798303 100644
--- a/secure/lib/libcrypto/man/DSA_dup_DH.3
+++ b/secure/lib/libcrypto/man/DSA_dup_DH.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_dup_DH 3"
-.TH DSA_dup_DH 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_dup_DH 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_dup_DH \- create a DH structure out of DSA structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_generate_key.3 b/secure/lib/libcrypto/man/DSA_generate_key.3
index 3f85594..64edcc0 100644
--- a/secure/lib/libcrypto/man/DSA_generate_key.3
+++ b/secure/lib/libcrypto/man/DSA_generate_key.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_generate_key 3"
-.TH DSA_generate_key 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_generate_key 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_generate_key \- generate DSA key pair
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_generate_parameters.3 b/secure/lib/libcrypto/man/DSA_generate_parameters.3
index de158d7..4458e68 100644
--- a/secure/lib/libcrypto/man/DSA_generate_parameters.3
+++ b/secure/lib/libcrypto/man/DSA_generate_parameters.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_generate_parameters 3"
-.TH DSA_generate_parameters 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_generate_parameters 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_generate_parameters \- generate DSA parameters
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_get_ex_new_index.3 b/secure/lib/libcrypto/man/DSA_get_ex_new_index.3
index 195e127..11916e1 100644
--- a/secure/lib/libcrypto/man/DSA_get_ex_new_index.3
+++ b/secure/lib/libcrypto/man/DSA_get_ex_new_index.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_get_ex_new_index 3"
-.TH DSA_get_ex_new_index 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_get_ex_new_index 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_get_ex_new_index, DSA_set_ex_data, DSA_get_ex_data \- add application specific data to DSA structures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_new.3 b/secure/lib/libcrypto/man/DSA_new.3
index 4a5c79f..fe6827c 100644
--- a/secure/lib/libcrypto/man/DSA_new.3
+++ b/secure/lib/libcrypto/man/DSA_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_new 3"
-.TH DSA_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_new, DSA_free \- allocate and free DSA objects
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_set_method.3 b/secure/lib/libcrypto/man/DSA_set_method.3
index a8383f8..b412c25 100644
--- a/secure/lib/libcrypto/man/DSA_set_method.3
+++ b/secure/lib/libcrypto/man/DSA_set_method.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_set_method 3"
-.TH DSA_set_method 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_set_method 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_set_default_method, DSA_get_default_method,
DSA_set_method, DSA_new_method, DSA_OpenSSL \- select DSA method
diff --git a/secure/lib/libcrypto/man/DSA_sign.3 b/secure/lib/libcrypto/man/DSA_sign.3
index 2361f9b..2ee5fc7 100644
--- a/secure/lib/libcrypto/man/DSA_sign.3
+++ b/secure/lib/libcrypto/man/DSA_sign.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_sign 3"
-.TH DSA_sign 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_sign 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_sign, DSA_sign_setup, DSA_verify \- DSA signatures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/DSA_size.3 b/secure/lib/libcrypto/man/DSA_size.3
index 96c1ad6..4ee9d75 100644
--- a/secure/lib/libcrypto/man/DSA_size.3
+++ b/secure/lib/libcrypto/man/DSA_size.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_size 3"
-.TH DSA_size 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA_size 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DSA_size \- get DSA signature size
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ERR_GET_LIB.3 b/secure/lib/libcrypto/man/ERR_GET_LIB.3
index e9a5b43..d45ce92 100644
--- a/secure/lib/libcrypto/man/ERR_GET_LIB.3
+++ b/secure/lib/libcrypto/man/ERR_GET_LIB.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_GET_LIB 3"
-.TH ERR_GET_LIB 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_GET_LIB 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_GET_LIB, ERR_GET_FUNC, ERR_GET_REASON \- get library, function and
reason code
diff --git a/secure/lib/libcrypto/man/ERR_clear_error.3 b/secure/lib/libcrypto/man/ERR_clear_error.3
index 4658694..ea36493 100644
--- a/secure/lib/libcrypto/man/ERR_clear_error.3
+++ b/secure/lib/libcrypto/man/ERR_clear_error.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_clear_error 3"
-.TH ERR_clear_error 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_clear_error 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_clear_error \- clear the error queue
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ERR_error_string.3 b/secure/lib/libcrypto/man/ERR_error_string.3
index 95cdf0f..245a3f4 100644
--- a/secure/lib/libcrypto/man/ERR_error_string.3
+++ b/secure/lib/libcrypto/man/ERR_error_string.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_error_string 3"
-.TH ERR_error_string 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_error_string 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_error_string, ERR_error_string_n, ERR_lib_error_string,
ERR_func_error_string, ERR_reason_error_string \- obtain human\-readable
diff --git a/secure/lib/libcrypto/man/ERR_get_error.3 b/secure/lib/libcrypto/man/ERR_get_error.3
index 45be04d..cb92641 100644
--- a/secure/lib/libcrypto/man/ERR_get_error.3
+++ b/secure/lib/libcrypto/man/ERR_get_error.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_get_error 3"
-.TH ERR_get_error 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_get_error 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_get_error, ERR_peek_error, ERR_peek_last_error,
ERR_get_error_line, ERR_peek_error_line, ERR_peek_last_error_line,
diff --git a/secure/lib/libcrypto/man/ERR_load_crypto_strings.3 b/secure/lib/libcrypto/man/ERR_load_crypto_strings.3
index 8d0fec6..e9b53e0 100644
--- a/secure/lib/libcrypto/man/ERR_load_crypto_strings.3
+++ b/secure/lib/libcrypto/man/ERR_load_crypto_strings.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_load_crypto_strings 3"
-.TH ERR_load_crypto_strings 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_load_crypto_strings 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_load_crypto_strings, SSL_load_error_strings, ERR_free_strings \-
load and free error strings
diff --git a/secure/lib/libcrypto/man/ERR_load_strings.3 b/secure/lib/libcrypto/man/ERR_load_strings.3
index 0c4d5be..90681b6 100644
--- a/secure/lib/libcrypto/man/ERR_load_strings.3
+++ b/secure/lib/libcrypto/man/ERR_load_strings.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_load_strings 3"
-.TH ERR_load_strings 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_load_strings 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_load_strings, ERR_PACK, ERR_get_next_error_library \- load
arbitrary error strings
diff --git a/secure/lib/libcrypto/man/ERR_print_errors.3 b/secure/lib/libcrypto/man/ERR_print_errors.3
index 770521e..56be8db 100644
--- a/secure/lib/libcrypto/man/ERR_print_errors.3
+++ b/secure/lib/libcrypto/man/ERR_print_errors.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_print_errors 3"
-.TH ERR_print_errors 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_print_errors 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_print_errors, ERR_print_errors_fp \- print error messages
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ERR_put_error.3 b/secure/lib/libcrypto/man/ERR_put_error.3
index 0eb440b..a705395 100644
--- a/secure/lib/libcrypto/man/ERR_put_error.3
+++ b/secure/lib/libcrypto/man/ERR_put_error.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_put_error 3"
-.TH ERR_put_error 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_put_error 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_put_error, ERR_add_error_data \- record an error
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ERR_remove_state.3 b/secure/lib/libcrypto/man/ERR_remove_state.3
index 2de6922..b562fd9 100644
--- a/secure/lib/libcrypto/man/ERR_remove_state.3
+++ b/secure/lib/libcrypto/man/ERR_remove_state.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_remove_state 3"
-.TH ERR_remove_state 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_remove_state 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_remove_state \- free a thread's error queue
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ERR_set_mark.3 b/secure/lib/libcrypto/man/ERR_set_mark.3
index de498eb..459de55 100644
--- a/secure/lib/libcrypto/man/ERR_set_mark.3
+++ b/secure/lib/libcrypto/man/ERR_set_mark.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_set_mark 3"
-.TH ERR_set_mark 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERR_set_mark 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ERR_set_mark, ERR_pop_to_mark \- set marks and pop errors until mark
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/EVP_BytesToKey.3 b/secure/lib/libcrypto/man/EVP_BytesToKey.3
index dc068e8..bc391be 100644
--- a/secure/lib/libcrypto/man/EVP_BytesToKey.3
+++ b/secure/lib/libcrypto/man/EVP_BytesToKey.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_BytesToKey 3"
-.TH EVP_BytesToKey 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_BytesToKey 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_BytesToKey \- password based encryption routine
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/EVP_DigestInit.3 b/secure/lib/libcrypto/man/EVP_DigestInit.3
index 85238e3..5db018f 100644
--- a/secure/lib/libcrypto/man/EVP_DigestInit.3
+++ b/secure/lib/libcrypto/man/EVP_DigestInit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_DigestInit 3"
-.TH EVP_DigestInit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_DigestInit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_DigestInit_ex, EVP_DigestUpdate,
EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE,
@@ -214,9 +214,9 @@ EVP digest routines
.IX Header "DESCRIPTION"
The \s-1EVP\s0 digest routines are a high level interface to message digests.
.PP
-\&\fIEVP_MD_CTX_init()\fR initializes digest contet \fBctx\fR.
+\&\fIEVP_MD_CTX_init()\fR initializes digest context \fBctx\fR.
.PP
-\&\fIEVP_MD_CTX_create()\fR allocates, initializes and returns a digest contet.
+\&\fIEVP_MD_CTX_create()\fR allocates, initializes and returns a digest context.
.PP
\&\fIEVP_DigestInit_ex()\fR sets up digest context \fBctx\fR to use a digest
\&\fBtype\fR from \s-1ENGINE\s0 \fBimpl\fR. \fBctx\fR must be initialized before calling this
@@ -252,7 +252,7 @@ the passed context \fBctx\fR does not have to be initialized, and it always
uses the default digest implementation.
.PP
\&\fIEVP_DigestFinal()\fR is similar to \fIEVP_DigestFinal_ex()\fR except the digest
-contet \fBctx\fR is automatically cleaned up.
+context \fBctx\fR is automatically cleaned up.
.PP
\&\fIEVP_MD_CTX_copy()\fR is similar to \fIEVP_MD_CTX_copy_ex()\fR except the destination
\&\fBout\fR does not have to be initialized.
diff --git a/secure/lib/libcrypto/man/EVP_EncryptInit.3 b/secure/lib/libcrypto/man/EVP_EncryptInit.3
index 03314c1..850aed4 100644
--- a/secure/lib/libcrypto/man/EVP_EncryptInit.3
+++ b/secure/lib/libcrypto/man/EVP_EncryptInit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_EncryptInit 3"
-.TH EVP_EncryptInit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_EncryptInit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_CIPHER_CTX_init, EVP_EncryptInit_ex, EVP_EncryptUpdate,
EVP_EncryptFinal_ex, EVP_DecryptInit_ex, EVP_DecryptUpdate,
diff --git a/secure/lib/libcrypto/man/EVP_OpenInit.3 b/secure/lib/libcrypto/man/EVP_OpenInit.3
index a44a84ee..963d9b5 100644
--- a/secure/lib/libcrypto/man/EVP_OpenInit.3
+++ b/secure/lib/libcrypto/man/EVP_OpenInit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_OpenInit 3"
-.TH EVP_OpenInit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_OpenInit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_OpenInit, EVP_OpenUpdate, EVP_OpenFinal \- EVP envelope decryption
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/EVP_PKEY_new.3 b/secure/lib/libcrypto/man/EVP_PKEY_new.3
index b533194..a67ab61 100644
--- a/secure/lib/libcrypto/man/EVP_PKEY_new.3
+++ b/secure/lib/libcrypto/man/EVP_PKEY_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_PKEY_new 3"
-.TH EVP_PKEY_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_PKEY_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_PKEY_new, EVP_PKEY_free \- private key allocation functions.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3 b/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3
index ad3e58a..67d208d 100644
--- a/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3
+++ b/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_PKEY_set1_RSA 3"
-.TH EVP_PKEY_set1_RSA 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_PKEY_set1_RSA 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY,
EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
diff --git a/secure/lib/libcrypto/man/EVP_SealInit.3 b/secure/lib/libcrypto/man/EVP_SealInit.3
index 1d11cc3..da472cb 100644
--- a/secure/lib/libcrypto/man/EVP_SealInit.3
+++ b/secure/lib/libcrypto/man/EVP_SealInit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_SealInit 3"
-.TH EVP_SealInit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_SealInit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_SealInit, EVP_SealUpdate, EVP_SealFinal \- EVP envelope encryption
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/EVP_SignInit.3 b/secure/lib/libcrypto/man/EVP_SignInit.3
index b758841..bdc1d07 100644
--- a/secure/lib/libcrypto/man/EVP_SignInit.3
+++ b/secure/lib/libcrypto/man/EVP_SignInit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_SignInit 3"
-.TH EVP_SignInit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_SignInit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_SignInit, EVP_SignUpdate, EVP_SignFinal \- EVP signing functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/EVP_VerifyInit.3 b/secure/lib/libcrypto/man/EVP_VerifyInit.3
index b669928..602701f 100644
--- a/secure/lib/libcrypto/man/EVP_VerifyInit.3
+++ b/secure/lib/libcrypto/man/EVP_VerifyInit.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_VerifyInit 3"
-.TH EVP_VerifyInit 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EVP_VerifyInit 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
EVP_VerifyInit, EVP_VerifyUpdate, EVP_VerifyFinal \- EVP signature verification functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/OBJ_nid2obj.3 b/secure/lib/libcrypto/man/OBJ_nid2obj.3
index eb4ff37..ed46f9c 100644
--- a/secure/lib/libcrypto/man/OBJ_nid2obj.3
+++ b/secure/lib/libcrypto/man/OBJ_nid2obj.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OBJ_nid2obj 3"
-.TH OBJ_nid2obj 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OBJ_nid2obj 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OBJ_nid2obj, OBJ_nid2ln, OBJ_nid2sn, OBJ_obj2nid, OBJ_txt2nid, OBJ_ln2nid, OBJ_sn2nid,
OBJ_cmp, OBJ_dup, OBJ_txt2obj, OBJ_obj2txt, OBJ_create, OBJ_cleanup \- ASN1 object utility
diff --git a/secure/lib/libcrypto/man/OPENSSL_Applink.3 b/secure/lib/libcrypto/man/OPENSSL_Applink.3
index 86fa29b..6dda200 100644
--- a/secure/lib/libcrypto/man/OPENSSL_Applink.3
+++ b/secure/lib/libcrypto/man/OPENSSL_Applink.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_Applink 3"
-.TH OPENSSL_Applink 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OPENSSL_Applink 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OPENSSL_Applink \- glue between OpenSSL BIO and Win32 compiler run\-time
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3 b/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3
index eb4bd34..4e9e7e1 100644
--- a/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3
+++ b/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_VERSION_NUMBER 3"
-.TH OPENSSL_VERSION_NUMBER 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OPENSSL_VERSION_NUMBER 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OPENSSL_VERSION_NUMBER, SSLeay, SSLeay_version \- get OpenSSL version number
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/OPENSSL_config.3 b/secure/lib/libcrypto/man/OPENSSL_config.3
index 60db42d..d89c9c3 100644
--- a/secure/lib/libcrypto/man/OPENSSL_config.3
+++ b/secure/lib/libcrypto/man/OPENSSL_config.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_config 3"
-.TH OPENSSL_config 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OPENSSL_config 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OPENSSL_config, OPENSSL_no_config \- simple OpenSSL configuration functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/OPENSSL_ia32cap.3 b/secure/lib/libcrypto/man/OPENSSL_ia32cap.3
index cb9137b..51a96d4 100644
--- a/secure/lib/libcrypto/man/OPENSSL_ia32cap.3
+++ b/secure/lib/libcrypto/man/OPENSSL_ia32cap.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_ia32cap 3"
-.TH OPENSSL_ia32cap 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OPENSSL_ia32cap 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OPENSSL_ia32cap \- finding the IA\-32 processor capabilities
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3 b/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3
index 8e57e98..570f5c2 100644
--- a/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3
+++ b/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_load_builtin_modules 3"
-.TH OPENSSL_load_builtin_modules 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OPENSSL_load_builtin_modules 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OPENSSL_load_builtin_modules \- add standard configuration modules
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3 b/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3
index f0d1188..1a66839 100644
--- a/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3
+++ b/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OpenSSL_add_all_algorithms 3"
-.TH OpenSSL_add_all_algorithms 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OpenSSL_add_all_algorithms 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
OpenSSL_add_all_algorithms, OpenSSL_add_all_ciphers, OpenSSL_add_all_digests \-
add algorithms to internal table
diff --git a/secure/lib/libcrypto/man/PKCS12_create.3 b/secure/lib/libcrypto/man/PKCS12_create.3
index dafc12b..fc65672 100644
--- a/secure/lib/libcrypto/man/PKCS12_create.3
+++ b/secure/lib/libcrypto/man/PKCS12_create.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS12_create 3"
-.TH PKCS12_create 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS12_create 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
PKCS12_create \- create a PKCS#12 structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/PKCS12_parse.3 b/secure/lib/libcrypto/man/PKCS12_parse.3
index b61b9eb..c8ace76 100644
--- a/secure/lib/libcrypto/man/PKCS12_parse.3
+++ b/secure/lib/libcrypto/man/PKCS12_parse.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS12_parse 3"
-.TH PKCS12_parse 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS12_parse 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
PKCS12_parse \- parse a PKCS#12 structure
.SH "SYNOPSIS"
@@ -148,23 +148,29 @@ If successful the private key will be written to \fB*pkey\fR, the corresponding
certificate to \fB*cert\fR and any additional certificates to \fB*ca\fR.
.SH "NOTES"
.IX Header "NOTES"
-The parameters \fBpkey\fR and \fBcert\fR cannot be \fB\s-1NULL\s0\fR. \fBca\fR can be <\s-1NULL\s0>
-in which case additional certificates will be discarded. \fB*ca\fR can also
-be a valid \s-1STACK\s0 in which case additional certificates are appended to
-\&\fB*ca\fR. If \fB*ca\fR is \fB\s-1NULL\s0\fR a new \s-1STACK\s0 will be allocated.
+The parameters \fBpkey\fR and \fBcert\fR cannot be \fB\s-1NULL\s0\fR. \fBca\fR can be <\s-1NULL\s0> in
+which case additional certificates will be discarded. \fB*ca\fR can also be a
+valid \s-1STACK\s0 in which case additional certificates are appended to \fB*ca\fR. If
+\&\fB*ca\fR is \fB\s-1NULL\s0\fR a new \s-1STACK\s0 will be allocated.
.PP
-The \fBfriendlyName\fR and \fBlocalKeyID\fR attributes (if present) on each certificate
-will be stored in the \fBalias\fR and \fBkeyid\fR attributes of the \fBX509\fR structure.
+The \fBfriendlyName\fR and \fBlocalKeyID\fR attributes (if present) on each
+certificate will be stored in the \fBalias\fR and \fBkeyid\fR attributes of the
+\&\fBX509\fR structure.
+.SH "RETURN VALUES"
+.IX Header "RETURN VALUES"
+\&\fIPKCS12_parse()\fR returns 1 for success and zero if an error occurred.
+.PP
+The error can be obtained from \fIERR_get_error\fR\|(3)
.SH "BUGS"
.IX Header "BUGS"
-Only a single private key and corresponding certificate is returned by this function.
-More complex PKCS#12 files with multiple private keys will only return the first
-match.
+Only a single private key and corresponding certificate is returned by this
+function. More complex PKCS#12 files with multiple private keys will only
+return the first match.
.PP
-Only \fBfriendlyName\fR and \fBlocalKeyID\fR attributes are currently stored in certificates.
-Other attributes are discarded.
+Only \fBfriendlyName\fR and \fBlocalKeyID\fR attributes are currently stored in
+certificates. Other attributes are discarded.
.PP
-Attributes currently cannot be store in the private key \fB\s-1EVP_PKEY\s0\fR structure.
+Attributes currently cannot be stored in the private key \fB\s-1EVP_PKEY\s0\fR structure.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fId2i_PKCS12\fR\|(3)
diff --git a/secure/lib/libcrypto/man/PKCS7_decrypt.3 b/secure/lib/libcrypto/man/PKCS7_decrypt.3
index 07f892e..bb3a991 100644
--- a/secure/lib/libcrypto/man/PKCS7_decrypt.3
+++ b/secure/lib/libcrypto/man/PKCS7_decrypt.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_decrypt 3"
-.TH PKCS7_decrypt 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS7_decrypt 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
PKCS7_decrypt \- decrypt content from a PKCS#7 envelopedData structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/PKCS7_encrypt.3 b/secure/lib/libcrypto/man/PKCS7_encrypt.3
index e46068d..a2acd0d 100644
--- a/secure/lib/libcrypto/man/PKCS7_encrypt.3
+++ b/secure/lib/libcrypto/man/PKCS7_encrypt.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_encrypt 3"
-.TH PKCS7_encrypt 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS7_encrypt 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
PKCS7_encrypt \- create a PKCS#7 envelopedData structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/PKCS7_sign.3 b/secure/lib/libcrypto/man/PKCS7_sign.3
index ea7cdc1..994a3f4 100644
--- a/secure/lib/libcrypto/man/PKCS7_sign.3
+++ b/secure/lib/libcrypto/man/PKCS7_sign.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_sign 3"
-.TH PKCS7_sign 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS7_sign 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
PKCS7_sign \- create a PKCS#7 signedData structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/PKCS7_verify.3 b/secure/lib/libcrypto/man/PKCS7_verify.3
index 99a7124..cec4d97 100644
--- a/secure/lib/libcrypto/man/PKCS7_verify.3
+++ b/secure/lib/libcrypto/man/PKCS7_verify.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_verify 3"
-.TH PKCS7_verify 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS7_verify 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
PKCS7_verify \- verify a PKCS#7 signedData structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RAND_add.3 b/secure/lib/libcrypto/man/RAND_add.3
index fef1909..9329c02 100644
--- a/secure/lib/libcrypto/man/RAND_add.3
+++ b/secure/lib/libcrypto/man/RAND_add.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_add 3"
-.TH RAND_add 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND_add 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RAND_add, RAND_seed, RAND_status, RAND_event, RAND_screen \- add
entropy to the PRNG
diff --git a/secure/lib/libcrypto/man/RAND_bytes.3 b/secure/lib/libcrypto/man/RAND_bytes.3
index 1795a6e..91db1a6 100644
--- a/secure/lib/libcrypto/man/RAND_bytes.3
+++ b/secure/lib/libcrypto/man/RAND_bytes.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_bytes 3"
-.TH RAND_bytes 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND_bytes 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RAND_bytes, RAND_pseudo_bytes \- generate random data
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RAND_cleanup.3 b/secure/lib/libcrypto/man/RAND_cleanup.3
index 78aab30..5decd57 100644
--- a/secure/lib/libcrypto/man/RAND_cleanup.3
+++ b/secure/lib/libcrypto/man/RAND_cleanup.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_cleanup 3"
-.TH RAND_cleanup 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND_cleanup 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RAND_cleanup \- erase the PRNG state
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RAND_egd.3 b/secure/lib/libcrypto/man/RAND_egd.3
index 09ea99e..29acfd8a3 100644
--- a/secure/lib/libcrypto/man/RAND_egd.3
+++ b/secure/lib/libcrypto/man/RAND_egd.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_egd 3"
-.TH RAND_egd 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND_egd 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RAND_egd \- query entropy gathering daemon
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RAND_load_file.3 b/secure/lib/libcrypto/man/RAND_load_file.3
index 1f154c7..48af178 100644
--- a/secure/lib/libcrypto/man/RAND_load_file.3
+++ b/secure/lib/libcrypto/man/RAND_load_file.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_load_file 3"
-.TH RAND_load_file 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND_load_file 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RAND_load_file, RAND_write_file, RAND_file_name \- PRNG seed file
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RAND_set_rand_method.3 b/secure/lib/libcrypto/man/RAND_set_rand_method.3
index 98794445..fcd3432 100644
--- a/secure/lib/libcrypto/man/RAND_set_rand_method.3
+++ b/secure/lib/libcrypto/man/RAND_set_rand_method.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_set_rand_method 3"
-.TH RAND_set_rand_method 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND_set_rand_method 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay \- select RAND method
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_blinding_on.3 b/secure/lib/libcrypto/man/RSA_blinding_on.3
index 8ec3182..fafa985 100644
--- a/secure/lib/libcrypto/man/RSA_blinding_on.3
+++ b/secure/lib/libcrypto/man/RSA_blinding_on.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_blinding_on 3"
-.TH RSA_blinding_on 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_blinding_on 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_blinding_on, RSA_blinding_off \- protect the RSA operation from timing attacks
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_check_key.3 b/secure/lib/libcrypto/man/RSA_check_key.3
index c5712c1..5ffe6d8 100644
--- a/secure/lib/libcrypto/man/RSA_check_key.3
+++ b/secure/lib/libcrypto/man/RSA_check_key.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_check_key 3"
-.TH RSA_check_key 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_check_key 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_check_key \- validate private RSA keys
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_generate_key.3 b/secure/lib/libcrypto/man/RSA_generate_key.3
index 1609d36..347fdc6 100644
--- a/secure/lib/libcrypto/man/RSA_generate_key.3
+++ b/secure/lib/libcrypto/man/RSA_generate_key.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_generate_key 3"
-.TH RSA_generate_key 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_generate_key 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_generate_key \- generate RSA key pair
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_get_ex_new_index.3 b/secure/lib/libcrypto/man/RSA_get_ex_new_index.3
index 7d71517..778a45c 100644
--- a/secure/lib/libcrypto/man/RSA_get_ex_new_index.3
+++ b/secure/lib/libcrypto/man/RSA_get_ex_new_index.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_get_ex_new_index 3"
-.TH RSA_get_ex_new_index 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_get_ex_new_index 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_get_ex_new_index, RSA_set_ex_data, RSA_get_ex_data \- add application specific data to RSA structures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_new.3 b/secure/lib/libcrypto/man/RSA_new.3
index cad145c..1572bd3 100644
--- a/secure/lib/libcrypto/man/RSA_new.3
+++ b/secure/lib/libcrypto/man/RSA_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_new 3"
-.TH RSA_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_new, RSA_free \- allocate and free RSA objects
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3 b/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3
index 31ba3be..bd9a6cc 100644
--- a/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3
+++ b/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_padding_add_PKCS1_type_1 3"
-.TH RSA_padding_add_PKCS1_type_1 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_padding_add_PKCS1_type_1 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_padding_add_PKCS1_type_1, RSA_padding_check_PKCS1_type_1,
RSA_padding_add_PKCS1_type_2, RSA_padding_check_PKCS1_type_2,
diff --git a/secure/lib/libcrypto/man/RSA_print.3 b/secure/lib/libcrypto/man/RSA_print.3
index 3e15d26..b4ceb07 100644
--- a/secure/lib/libcrypto/man/RSA_print.3
+++ b/secure/lib/libcrypto/man/RSA_print.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_print 3"
-.TH RSA_print 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_print 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_print, RSA_print_fp,
DSAparams_print, DSAparams_print_fp, DSA_print, DSA_print_fp,
diff --git a/secure/lib/libcrypto/man/RSA_private_encrypt.3 b/secure/lib/libcrypto/man/RSA_private_encrypt.3
index 4e74fa6..f36b43f 100644
--- a/secure/lib/libcrypto/man/RSA_private_encrypt.3
+++ b/secure/lib/libcrypto/man/RSA_private_encrypt.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_private_encrypt 3"
-.TH RSA_private_encrypt 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_private_encrypt 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_private_encrypt, RSA_public_decrypt \- low level signature operations
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_public_encrypt.3 b/secure/lib/libcrypto/man/RSA_public_encrypt.3
index fda7464..0646d92 100644
--- a/secure/lib/libcrypto/man/RSA_public_encrypt.3
+++ b/secure/lib/libcrypto/man/RSA_public_encrypt.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_public_encrypt 3"
-.TH RSA_public_encrypt 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_public_encrypt 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_public_encrypt, RSA_private_decrypt \- RSA public key cryptography
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_set_method.3 b/secure/lib/libcrypto/man/RSA_set_method.3
index dc7f380..1a5fd94 100644
--- a/secure/lib/libcrypto/man/RSA_set_method.3
+++ b/secure/lib/libcrypto/man/RSA_set_method.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_set_method 3"
-.TH RSA_set_method 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_set_method 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_set_default_method, RSA_get_default_method, RSA_set_method,
RSA_get_method, RSA_PKCS1_SSLeay, RSA_null_method, RSA_flags,
diff --git a/secure/lib/libcrypto/man/RSA_sign.3 b/secure/lib/libcrypto/man/RSA_sign.3
index 455e226..5c6352c 100644
--- a/secure/lib/libcrypto/man/RSA_sign.3
+++ b/secure/lib/libcrypto/man/RSA_sign.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_sign 3"
-.TH RSA_sign 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_sign 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_sign, RSA_verify \- RSA signatures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3 b/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3
index 39fd387..a32f3ca 100644
--- a/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3
+++ b/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_sign_ASN1_OCTET_STRING 3"
-.TH RSA_sign_ASN1_OCTET_STRING 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_sign_ASN1_OCTET_STRING 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_sign_ASN1_OCTET_STRING, RSA_verify_ASN1_OCTET_STRING \- RSA signatures
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/RSA_size.3 b/secure/lib/libcrypto/man/RSA_size.3
index a2f9075..f5cc15a 100644
--- a/secure/lib/libcrypto/man/RSA_size.3
+++ b/secure/lib/libcrypto/man/RSA_size.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_size 3"
-.TH RSA_size 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA_size 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RSA_size \- get RSA modulus size
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/SMIME_read_PKCS7.3 b/secure/lib/libcrypto/man/SMIME_read_PKCS7.3
index aeb3b51..e4e8fd34 100644
--- a/secure/lib/libcrypto/man/SMIME_read_PKCS7.3
+++ b/secure/lib/libcrypto/man/SMIME_read_PKCS7.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SMIME_read_PKCS7 3"
-.TH SMIME_read_PKCS7 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SMIME_read_PKCS7 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SMIME_read_PKCS7 \- parse S/MIME message.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/SMIME_write_PKCS7.3 b/secure/lib/libcrypto/man/SMIME_write_PKCS7.3
index b44c81a..54c9c36 100644
--- a/secure/lib/libcrypto/man/SMIME_write_PKCS7.3
+++ b/secure/lib/libcrypto/man/SMIME_write_PKCS7.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SMIME_write_PKCS7 3"
-.TH SMIME_write_PKCS7 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SMIME_write_PKCS7 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SMIME_write_PKCS7 \- convert PKCS#7 structure to S/MIME format.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3 b/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3
index fc16b7d..4558e1f 100644
--- a/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3
+++ b/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_ENTRY_get_object 3"
-.TH X509_NAME_ENTRY_get_object 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509_NAME_ENTRY_get_object 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
X509_NAME_ENTRY_get_object, X509_NAME_ENTRY_get_data,
X509_NAME_ENTRY_set_object, X509_NAME_ENTRY_set_data,
diff --git a/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3 b/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3
index e8335a4..274a7d0 100644
--- a/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3
+++ b/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_add_entry_by_txt 3"
-.TH X509_NAME_add_entry_by_txt 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509_NAME_add_entry_by_txt 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
X509_NAME_add_entry_by_txt, X509_NAME_add_entry_by_OBJ, X509_NAME_add_entry_by_NID,
X509_NAME_add_entry, X509_NAME_delete_entry \- X509_NAME modification functions
diff --git a/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 b/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3
index 7124982..7b7e852 100644
--- a/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3
+++ b/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_get_index_by_NID 3"
-.TH X509_NAME_get_index_by_NID 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509_NAME_get_index_by_NID 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
X509_NAME_get_index_by_NID, X509_NAME_get_index_by_OBJ, X509_NAME_get_entry,
X509_NAME_entry_count, X509_NAME_get_text_by_NID, X509_NAME_get_text_by_OBJ \-
diff --git a/secure/lib/libcrypto/man/X509_NAME_print_ex.3 b/secure/lib/libcrypto/man/X509_NAME_print_ex.3
index 932458a..ed7d1dd 100644
--- a/secure/lib/libcrypto/man/X509_NAME_print_ex.3
+++ b/secure/lib/libcrypto/man/X509_NAME_print_ex.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_print_ex 3"
-.TH X509_NAME_print_ex 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509_NAME_print_ex 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
X509_NAME_print_ex, X509_NAME_print_ex_fp, X509_NAME_print,
X509_NAME_oneline \- X509_NAME printing routines.
diff --git a/secure/lib/libcrypto/man/X509_new.3 b/secure/lib/libcrypto/man/X509_new.3
index 5d6c941..dacfe34 100644
--- a/secure/lib/libcrypto/man/X509_new.3
+++ b/secure/lib/libcrypto/man/X509_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509_new 3"
-.TH X509_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
X509_new, X509_free \- X509 certificate ASN1 allocation functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/bio.3 b/secure/lib/libcrypto/man/bio.3
index a939abb..f1db62e 100644
--- a/secure/lib/libcrypto/man/bio.3
+++ b/secure/lib/libcrypto/man/bio.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "bio 3"
-.TH bio 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH bio 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
bio \- I/O abstraction
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/blowfish.3 b/secure/lib/libcrypto/man/blowfish.3
index a64ac54..f8cc9c5 100644
--- a/secure/lib/libcrypto/man/blowfish.3
+++ b/secure/lib/libcrypto/man/blowfish.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "blowfish 3"
-.TH blowfish 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH blowfish 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
blowfish, BF_set_key, BF_encrypt, BF_decrypt, BF_ecb_encrypt, BF_cbc_encrypt,
BF_cfb64_encrypt, BF_ofb64_encrypt, BF_options \- Blowfish encryption
diff --git a/secure/lib/libcrypto/man/bn.3 b/secure/lib/libcrypto/man/bn.3
index 8e6e22c..45477e6 100644
--- a/secure/lib/libcrypto/man/bn.3
+++ b/secure/lib/libcrypto/man/bn.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "bn 3"
-.TH bn 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH bn 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
bn \- multiprecision integer arithmetics
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/bn_internal.3 b/secure/lib/libcrypto/man/bn_internal.3
index fa6fb93..da2f141 100644
--- a/secure/lib/libcrypto/man/bn_internal.3
+++ b/secure/lib/libcrypto/man/bn_internal.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "bn_internal 3"
-.TH bn_internal 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH bn_internal 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
bn_mul_words, bn_mul_add_words, bn_sqr_words, bn_div_words,
bn_add_words, bn_sub_words, bn_mul_comba4, bn_mul_comba8,
@@ -212,14 +212,20 @@ debugging and extending the library. They are \fInot\fR to be used by
applications.
.Sh "The \s-1BIGNUM\s0 structure"
.IX Subsection "The BIGNUM structure"
-.Vb 7
-\& typedef struct bignum_st
+.Vb 1
+\& typedef struct bignum_st BIGNUM;
+.Ve
+.PP
+.Vb 9
+\& struct bignum_st
\& {
-\& int top; /* number of words used in d */
-\& BN_ULONG *d; /* pointer to an array containing the integer value */
-\& int max; /* size of the d array */
-\& int neg; /* sign */
-\& } BIGNUM;
+\& BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
+\& int top; /* Index of last used d +1. */
+\& /* The next are internal book keeping for bn_expand. */
+\& int dmax; /* Size of the d array. */
+\& int neg; /* one if the number is negative */
+\& int flags;
+\& };
.Ve
.PP
The integer value is stored in \fBd\fR, a \fImalloc()\fRed array of words (\fB\s-1BN_ULONG\s0\fR),
@@ -227,11 +233,16 @@ least significant word first. A \fB\s-1BN_ULONG\s0\fR can be either 16, 32 or 64
in size, depending on the 'number of bits' (\fB\s-1BITS2\s0\fR) specified in
\&\f(CW\*(C`openssl/bn.h\*(C'\fR.
.PP
-\&\fBmax\fR is the size of the \fBd\fR array that has been allocated. \fBtop\fR
+\&\fBdmax\fR is the size of the \fBd\fR array that has been allocated. \fBtop\fR
is the number of words being used, so for a value of 4, bn.d[0]=4 and
bn.top=1. \fBneg\fR is 1 if the number is negative. When a \fB\s-1BIGNUM\s0\fR is
\&\fB0\fR, the \fBd\fR field can be \fB\s-1NULL\s0\fR and \fBtop\fR == \fB0\fR.
.PP
+\&\fBflags\fR is a bit field of flags which are defined in \f(CW\*(C`openssl/bn.h\*(C'\fR. The
+flags begin with \fB\s-1BN_FLG_\s0\fR. The macros BN_set_flags(b,n) and
+BN_get_flags(b,n) exist to enable or fetch flag(s) \fBn\fR from \fB\s-1BIGNUM\s0\fR
+structure \fBb\fR.
+.PP
Various routines in this library require the use of temporary
\&\fB\s-1BIGNUM\s0\fR variables during their execution. Since dynamic memory
allocation to create \fB\s-1BIGNUM\s0\fRs is rather expensive when used in
@@ -348,12 +359,12 @@ significant non-zero word plus one when \fBa\fR has shrunk.
.Sh "Debugging"
.IX Subsection "Debugging"
\&\fIbn_check_top()\fR verifies that \f(CW\*(C`((a)\->top >= 0 && (a)\->top
-<= (a)\->max)\*(C'\fR. A violation will cause the program to abort.
+<= (a)\->dmax)\*(C'\fR. A violation will cause the program to abort.
.PP
\&\fIbn_print()\fR prints \fBa\fR to stderr. \fIbn_dump()\fR prints \fBn\fR words at \fBd\fR
(in reverse order, i.e. most significant word first) to stderr.
.PP
-\&\fIbn_set_max()\fR makes \fBa\fR a static number with a \fBmax\fR of its current size.
+\&\fIbn_set_max()\fR makes \fBa\fR a static number with a \fBdmax\fR of its current size.
This is used by \fIbn_set_low()\fR and \fIbn_set_high()\fR to make \fBr\fR a read-only
\&\fB\s-1BIGNUM\s0\fR that contains the \fBn\fR low or high words of \fBa\fR.
.PP
diff --git a/secure/lib/libcrypto/man/buffer.3 b/secure/lib/libcrypto/man/buffer.3
index f46a6f6..a700528 100644
--- a/secure/lib/libcrypto/man/buffer.3
+++ b/secure/lib/libcrypto/man/buffer.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "buffer 3"
-.TH buffer 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH buffer 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
BUF_MEM_new, BUF_MEM_free, BUF_MEM_grow, BUF_strdup \- simple
character arrays structure
diff --git a/secure/lib/libcrypto/man/crypto.3 b/secure/lib/libcrypto/man/crypto.3
index 932f79f..31819e2 100644
--- a/secure/lib/libcrypto/man/crypto.3
+++ b/secure/lib/libcrypto/man/crypto.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "crypto 3"
-.TH crypto 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH crypto 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
crypto \- OpenSSL cryptographic library
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3 b/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3
index 32b5e36..05e55f7 100644
--- a/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3
+++ b/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_ASN1_OBJECT 3"
-.TH d2i_ASN1_OBJECT 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_ASN1_OBJECT 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_ASN1_OBJECT, i2d_ASN1_OBJECT \- ASN1 OBJECT IDENTIFIER functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/d2i_DHparams.3 b/secure/lib/libcrypto/man/d2i_DHparams.3
index 433c2fb..f6a410f 100644
--- a/secure/lib/libcrypto/man/d2i_DHparams.3
+++ b/secure/lib/libcrypto/man/d2i_DHparams.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_DHparams 3"
-.TH d2i_DHparams 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_DHparams 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_DHparams, i2d_DHparams \- PKCS#3 DH parameter functions.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/d2i_DSAPublicKey.3 b/secure/lib/libcrypto/man/d2i_DSAPublicKey.3
index e809465..1d3142a 100644
--- a/secure/lib/libcrypto/man/d2i_DSAPublicKey.3
+++ b/secure/lib/libcrypto/man/d2i_DSAPublicKey.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_DSAPublicKey 3"
-.TH d2i_DSAPublicKey 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_DSAPublicKey 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_DSAPublicKey, i2d_DSAPublicKey, d2i_DSAPrivateKey, i2d_DSAPrivateKey,
d2i_DSA_PUBKEY, i2d_DSA_PUBKEY, d2i_DSA_SIG, i2d_DSA_SIG \- DSA key encoding
diff --git a/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3 b/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3
index 35f5a20..f8cbcaa 100644
--- a/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3
+++ b/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_PKCS8PrivateKey 3"
-.TH d2i_PKCS8PrivateKey 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_PKCS8PrivateKey 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_PKCS8PrivateKey_bio, d2i_PKCS8PrivateKey_fp,
i2d_PKCS8PrivateKey_bio, i2d_PKCS8PrivateKey_fp,
diff --git a/secure/lib/libcrypto/man/d2i_RSAPublicKey.3 b/secure/lib/libcrypto/man/d2i_RSAPublicKey.3
index ff0b015..d02b5c7 100644
--- a/secure/lib/libcrypto/man/d2i_RSAPublicKey.3
+++ b/secure/lib/libcrypto/man/d2i_RSAPublicKey.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_RSAPublicKey 3"
-.TH d2i_RSAPublicKey 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_RSAPublicKey 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey,
d2i_RSA_PUBKEY, i2d_RSA_PUBKEY, i2d_Netscape_RSA,
diff --git a/secure/lib/libcrypto/man/d2i_X509.3 b/secure/lib/libcrypto/man/d2i_X509.3
index 1f4dafe..3945c98 100644
--- a/secure/lib/libcrypto/man/d2i_X509.3
+++ b/secure/lib/libcrypto/man/d2i_X509.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509 3"
-.TH d2i_X509 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_X509 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio,
i2d_X509_fp \- X509 encode and decode functions
@@ -150,8 +150,8 @@ i2d_X509_fp \- X509 encode and decode functions
.Ve
.PP
.Vb 2
-\& int i2d_X509_bio(X509 *x, BIO *bp);
-\& int i2d_X509_fp(X509 *x, FILE *fp);
+\& int i2d_X509_bio(BIO *bp, X509 *x);
+\& int i2d_X509_fp(FILE *fp, X509 *x);
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
@@ -406,11 +406,11 @@ always succeed.
or \fB\s-1NULL\s0\fR if an error occurs. The error code that can be obtained by
\&\fIERR_get_error\fR\|(3).
.PP
-\&\fIi2d_X509()\fR, \fIi2d_X509_bio()\fR and \fIi2d_X509_fp()\fR return a the number of bytes
-successfully encoded or a negative value if an error occurs. The error code
-can be obtained by \fIERR_get_error\fR\|(3).
+\&\fIi2d_X509()\fR returns the number of bytes successfully encoded or a negative
+value if an error occurs. The error code can be obtained by
+\&\fIERR_get_error\fR\|(3).
.PP
-\&\fIi2d_X509_bio()\fR and \fIi2d_X509_fp()\fR returns 1 for success and 0 if an error
+\&\fIi2d_X509_bio()\fR and \fIi2d_X509_fp()\fR return 1 for success and 0 if an error
occurs The error code can be obtained by \fIERR_get_error\fR\|(3).
.SH "SEE ALSO"
.IX Header "SEE ALSO"
diff --git a/secure/lib/libcrypto/man/d2i_X509_ALGOR.3 b/secure/lib/libcrypto/man/d2i_X509_ALGOR.3
index fda5526..ca37dbb 100644
--- a/secure/lib/libcrypto/man/d2i_X509_ALGOR.3
+++ b/secure/lib/libcrypto/man/d2i_X509_ALGOR.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_ALGOR 3"
-.TH d2i_X509_ALGOR 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_X509_ALGOR 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_X509_ALGOR, i2d_X509_ALGOR \- AlgorithmIdentifier functions.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/d2i_X509_CRL.3 b/secure/lib/libcrypto/man/d2i_X509_CRL.3
index ab843d9..b6a1e55 100644
--- a/secure/lib/libcrypto/man/d2i_X509_CRL.3
+++ b/secure/lib/libcrypto/man/d2i_X509_CRL.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_CRL 3"
-.TH d2i_X509_CRL 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_X509_CRL 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_X509_CRL, i2d_X509_CRL, d2i_X509_CRL_bio, d2i_509_CRL_fp,
i2d_X509_CRL_bio, i2d_X509_CRL_fp \- PKCS#10 certificate request functions.
@@ -150,8 +150,8 @@ i2d_X509_CRL_bio, i2d_X509_CRL_fp \- PKCS#10 certificate request functions.
.Ve
.PP
.Vb 2
-\& int i2d_X509_CRL_bio(X509_CRL *x, BIO *bp);
-\& int i2d_X509_CRL_fp(X509_CRL *x, FILE *fp);
+\& int i2d_X509_CRL_bio(BIO *bp, X509_CRL *x);
+\& int i2d_X509_CRL_fp(FILE *fp, X509_CRL *x);
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
diff --git a/secure/lib/libcrypto/man/d2i_X509_NAME.3 b/secure/lib/libcrypto/man/d2i_X509_NAME.3
index 55d17e4..bda457f 100644
--- a/secure/lib/libcrypto/man/d2i_X509_NAME.3
+++ b/secure/lib/libcrypto/man/d2i_X509_NAME.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_NAME 3"
-.TH d2i_X509_NAME 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_X509_NAME 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_X509_NAME, i2d_X509_NAME \- X509_NAME encoding functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/d2i_X509_REQ.3 b/secure/lib/libcrypto/man/d2i_X509_REQ.3
index dd02813..65c3060 100644
--- a/secure/lib/libcrypto/man/d2i_X509_REQ.3
+++ b/secure/lib/libcrypto/man/d2i_X509_REQ.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_REQ 3"
-.TH d2i_X509_REQ 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_X509_REQ 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_X509_REQ, i2d_X509_REQ, d2i_X509_REQ_bio, d2i_X509_REQ_fp,
i2d_X509_REQ_bio, i2d_X509_REQ_fp \- PKCS#10 certificate request functions.
@@ -150,8 +150,8 @@ i2d_X509_REQ_bio, i2d_X509_REQ_fp \- PKCS#10 certificate request functions.
.Ve
.PP
.Vb 2
-\& int i2d_X509_REQ_bio(X509_REQ *x, BIO *bp);
-\& int i2d_X509_REQ_fp(X509_REQ *x, FILE *fp);
+\& int i2d_X509_REQ_bio(BIO *bp, X509_REQ *x);
+\& int i2d_X509_REQ_fp(FILE *fp, X509_REQ *x);
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
diff --git a/secure/lib/libcrypto/man/d2i_X509_SIG.3 b/secure/lib/libcrypto/man/d2i_X509_SIG.3
index ad2f316..28c2557 100644
--- a/secure/lib/libcrypto/man/d2i_X509_SIG.3
+++ b/secure/lib/libcrypto/man/d2i_X509_SIG.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_SIG 3"
-.TH d2i_X509_SIG 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_X509_SIG 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_X509_SIG, i2d_X509_SIG \- DigestInfo functions.
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/des.3 b/secure/lib/libcrypto/man/des.3
index c9d7f6c..cc1d20e 100644
--- a/secure/lib/libcrypto/man/des.3
+++ b/secure/lib/libcrypto/man/des.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "des 3"
-.TH des 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH des 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
DES_random_key, DES_set_key, DES_key_sched, DES_set_key_checked,
DES_set_key_unchecked, DES_set_odd_parity, DES_is_weak_key,
diff --git a/secure/lib/libcrypto/man/dh.3 b/secure/lib/libcrypto/man/dh.3
index 8999991..754cf5b 100644
--- a/secure/lib/libcrypto/man/dh.3
+++ b/secure/lib/libcrypto/man/dh.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "dh 3"
-.TH dh 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH dh 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
dh \- Diffie\-Hellman key agreement
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/dsa.3 b/secure/lib/libcrypto/man/dsa.3
index 21dd785..3adcacf 100644
--- a/secure/lib/libcrypto/man/dsa.3
+++ b/secure/lib/libcrypto/man/dsa.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "dsa 3"
-.TH dsa 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH dsa 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
dsa \- Digital Signature Algorithm
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ecdsa.3 b/secure/lib/libcrypto/man/ecdsa.3
index f145a50..fbc987b 100644
--- a/secure/lib/libcrypto/man/ecdsa.3
+++ b/secure/lib/libcrypto/man/ecdsa.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ecdsa 3"
-.TH ecdsa 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ecdsa 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ecdsa \- Elliptic Curve Digital Signature Algorithm
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/engine.3 b/secure/lib/libcrypto/man/engine.3
index cdf7a01..f0a63883 100644
--- a/secure/lib/libcrypto/man/engine.3
+++ b/secure/lib/libcrypto/man/engine.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "engine 3"
-.TH engine 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH engine 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
engine \- ENGINE cryptographic module support
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/err.3 b/secure/lib/libcrypto/man/err.3
index 9fd235f..13e8516 100644
--- a/secure/lib/libcrypto/man/err.3
+++ b/secure/lib/libcrypto/man/err.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "err 3"
-.TH err 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH err 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
err \- error codes
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/evp.3 b/secure/lib/libcrypto/man/evp.3
index 21873e9..ff53aff 100644
--- a/secure/lib/libcrypto/man/evp.3
+++ b/secure/lib/libcrypto/man/evp.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "evp 3"
-.TH evp 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH evp 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
evp \- high\-level cryptographic functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/hmac.3 b/secure/lib/libcrypto/man/hmac.3
index 99d4066..41a13a7 100644
--- a/secure/lib/libcrypto/man/hmac.3
+++ b/secure/lib/libcrypto/man/hmac.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "hmac 3"
-.TH hmac 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH hmac 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
HMAC, HMAC_Init, HMAC_Update, HMAC_Final, HMAC_cleanup \- HMAC message
authentication code
@@ -178,8 +178,6 @@ If \fBmd\fR is \s-1NULL\s0, the digest is placed in a static array. The size of
the output is placed in \fBmd_len\fR, unless it is \fB\s-1NULL\s0\fR.
.PP
\&\fBevp_md\fR can be \fIEVP_sha1()\fR, \fIEVP_ripemd160()\fR etc.
-\&\fBkey\fR and \fBevp_md\fR may be \fB\s-1NULL\s0\fR if a key and hash function have
-been set in a previous call to \fIHMAC_Init()\fR for that \fB\s-1HMAC_CTX\s0\fR.
.PP
\&\fIHMAC_CTX_init()\fR initialises a \fB\s-1HMAC_CTX\s0\fR before first use. It must be
called.
diff --git a/secure/lib/libcrypto/man/lh_stats.3 b/secure/lib/libcrypto/man/lh_stats.3
index 355c547..50aa703 100644
--- a/secure/lib/libcrypto/man/lh_stats.3
+++ b/secure/lib/libcrypto/man/lh_stats.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "lh_stats 3"
-.TH lh_stats 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH lh_stats 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
lh_stats, lh_node_stats, lh_node_usage_stats, lh_stats_bio,
lh_node_stats_bio, lh_node_usage_stats_bio \- LHASH statistics
diff --git a/secure/lib/libcrypto/man/lhash.3 b/secure/lib/libcrypto/man/lhash.3
index d875abd..29eaed4 100644
--- a/secure/lib/libcrypto/man/lhash.3
+++ b/secure/lib/libcrypto/man/lhash.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "lhash 3"
-.TH lhash 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH lhash 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error \- dynamic hash table
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/md5.3 b/secure/lib/libcrypto/man/md5.3
index f6d2e33..4b46840 100644
--- a/secure/lib/libcrypto/man/md5.3
+++ b/secure/lib/libcrypto/man/md5.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "md5 3"
-.TH md5 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH md5 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
MD2, MD4, MD5, MD2_Init, MD2_Update, MD2_Final, MD4_Init, MD4_Update,
MD4_Final, MD5_Init, MD5_Update, MD5_Final \- MD2, MD4, and MD5 hash functions
diff --git a/secure/lib/libcrypto/man/mdc2.3 b/secure/lib/libcrypto/man/mdc2.3
index 8594a80..d076122 100644
--- a/secure/lib/libcrypto/man/mdc2.3
+++ b/secure/lib/libcrypto/man/mdc2.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "mdc2 3"
-.TH mdc2 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH mdc2 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
MDC2, MDC2_Init, MDC2_Update, MDC2_Final \- MDC2 hash function
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/pem.3 b/secure/lib/libcrypto/man/pem.3
index aa1a5b6..f8c01c7 100644
--- a/secure/lib/libcrypto/man/pem.3
+++ b/secure/lib/libcrypto/man/pem.3
@@ -129,9 +129,9 @@
.\" ========================================================================
.\"
.IX Title "pem 3"
-.TH pem 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH pem 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
-PEM \- PEM routines
+PEM, PEM_read_bio_PrivateKey, PEM_read_PrivateKey, PEM_write_bio_PrivateKey, PEM_write_PrivateKey, PEM_write_bio_PKCS8PrivateKey, PEM_write_PKCS8PrivateKey, PEM_write_bio_PKCS8PrivateKey_nid, PEM_write_PKCS8PrivateKey_nid, PEM_read_bio_PUBKEY, PEM_read_PUBKEY, PEM_write_bio_PUBKEY, PEM_write_PUBKEY, PEM_read_bio_RSAPrivateKey, PEM_read_RSAPrivateKey, PEM_write_bio_RSAPrivateKey, PEM_write_RSAPrivateKey, PEM_read_bio_RSAPublicKey, PEM_read_RSAPublicKey, PEM_write_bio_RSAPublicKey, PEM_write_RSAPublicKey, PEM_read_bio_RSA_PUBKEY, PEM_read_RSA_PUBKEY, PEM_write_bio_RSA_PUBKEY, PEM_write_RSA_PUBKEY, PEM_read_bio_DSAPrivateKey, PEM_read_DSAPrivateKey, PEM_write_bio_DSAPrivateKey, PEM_write_DSAPrivateKey, PEM_read_bio_DSA_PUBKEY, PEM_read_DSA_PUBKEY, PEM_write_bio_DSA_PUBKEY, PEM_write_DSA_PUBKEY, PEM_read_bio_DSAparams, PEM_read_DSAparams, PEM_write_bio_DSAparams, PEM_write_DSAparams, PEM_read_bio_DHparams, PEM_read_DHparams, PEM_write_bio_DHparams, PEM_write_DHparams, PEM_read_bio_X509, PEM_read_X509, PEM_write_bio_X509, PEM_write_X509, PEM_read_bio_X509_AUX, PEM_read_X509_AUX, PEM_write_bio_X509_AUX, PEM_write_X509_AUX, PEM_read_bio_X509_REQ, PEM_read_X509_REQ, PEM_write_bio_X509_REQ, PEM_write_X509_REQ, PEM_write_bio_X509_REQ_NEW, PEM_write_X509_REQ_NEW, PEM_read_bio_X509_CRL, PEM_read_X509_CRL, PEM_write_bio_X509_CRL, PEM_write_X509_CRL, PEM_read_bio_PKCS7, PEM_read_PKCS7, PEM_write_bio_PKCS7, PEM_write_PKCS7, PEM_read_bio_NETSCAPE_CERT_SEQUENCE, PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE, PEM_write_NETSCAPE_CERT_SEQUENCE \- PEM routines
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
diff --git a/secure/lib/libcrypto/man/rand.3 b/secure/lib/libcrypto/man/rand.3
index cfbb63c..83aa152 100644
--- a/secure/lib/libcrypto/man/rand.3
+++ b/secure/lib/libcrypto/man/rand.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "rand 3"
-.TH rand 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH rand 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
rand \- pseudo\-random number generator
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/rc4.3 b/secure/lib/libcrypto/man/rc4.3
index c207785..9fc697d 100644
--- a/secure/lib/libcrypto/man/rc4.3
+++ b/secure/lib/libcrypto/man/rc4.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "rc4 3"
-.TH rc4 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH rc4 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RC4_set_key, RC4 \- RC4 encryption
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/ripemd.3 b/secure/lib/libcrypto/man/ripemd.3
index 4729a35..cfbef7e 100644
--- a/secure/lib/libcrypto/man/ripemd.3
+++ b/secure/lib/libcrypto/man/ripemd.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ripemd 3"
-.TH ripemd 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ripemd 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
RIPEMD160, RIPEMD160_Init, RIPEMD160_Update, RIPEMD160_Final \-
RIPEMD\-160 hash function
diff --git a/secure/lib/libcrypto/man/rsa.3 b/secure/lib/libcrypto/man/rsa.3
index b723ff4..f703b12 100644
--- a/secure/lib/libcrypto/man/rsa.3
+++ b/secure/lib/libcrypto/man/rsa.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "rsa 3"
-.TH rsa 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH rsa 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
rsa \- RSA public key cryptosystem
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/sha.3 b/secure/lib/libcrypto/man/sha.3
index 5339576..e45afd5 100644
--- a/secure/lib/libcrypto/man/sha.3
+++ b/secure/lib/libcrypto/man/sha.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "sha 3"
-.TH sha 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH sha 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SHA1, SHA1_Init, SHA1_Update, SHA1_Final \- Secure Hash Algorithm
.SH "SYNOPSIS"
diff --git a/secure/lib/libcrypto/man/threads.3 b/secure/lib/libcrypto/man/threads.3
index d9ef8cf..091a9ff 100644
--- a/secure/lib/libcrypto/man/threads.3
+++ b/secure/lib/libcrypto/man/threads.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "threads 3"
-.TH threads 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH threads 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
CRYPTO_set_locking_callback, CRYPTO_set_id_callback, CRYPTO_num_locks,
CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
diff --git a/secure/lib/libcrypto/man/ui.3 b/secure/lib/libcrypto/man/ui.3
index 35da394..0e6e9dc 100644
--- a/secure/lib/libcrypto/man/ui.3
+++ b/secure/lib/libcrypto/man/ui.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ui 3"
-.TH ui 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ui 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
UI_new, UI_new_method, UI_free, UI_add_input_string, UI_dup_input_string,
UI_add_verify_string, UI_dup_verify_string, UI_add_input_boolean,
diff --git a/secure/lib/libcrypto/man/ui_compat.3 b/secure/lib/libcrypto/man/ui_compat.3
index f0237c4..a392705 100644
--- a/secure/lib/libcrypto/man/ui_compat.3
+++ b/secure/lib/libcrypto/man/ui_compat.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ui_compat 3"
-.TH ui_compat 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ui_compat 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
des_read_password, des_read_2passwords, des_read_pw_string, des_read_pw \-
Compatibility user interface functions
diff --git a/secure/lib/libcrypto/man/x509.3 b/secure/lib/libcrypto/man/x509.3
index b4cacf5..b7d0fa5 100644
--- a/secure/lib/libcrypto/man/x509.3
+++ b/secure/lib/libcrypto/man/x509.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "x509 3"
-.TH x509 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH x509 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
x509 \- X.509 certificate handling
.SH "SYNOPSIS"
diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile
index 32b5069..d50b8d1 100644
--- a/secure/lib/libssh/Makefile
+++ b/secure/lib/libssh/Makefile
@@ -12,8 +12,9 @@ SRCS= acss.c authfd.c authfile.c bufaux.c bufbn.c buffer.c \
readpass.c rsa.c ttymodes.c xmalloc.c addrmatch.c \
atomicio.c key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \
monitor_fdpass.c rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c \
- kexgex.c kexdhc.c kexgexc.c scard.c msg.c progressmeter.c dns.c \
- entropy.c scard-opensc.c umac.c jpake.c schnorr.c
+ kexgex.c kexdhc.c kexgexc.c msg.c progressmeter.c dns.c \
+ entropy.c umac.c jpake.c schnorr.c \
+ ssh-pkcs11.c
# gss-genr.c should be in $SRCS but causes linking problems, so it is
# compiled directly into sshd instead.
diff --git a/secure/lib/libssl/Makefile b/secure/lib/libssl/Makefile
index 5dad969..c8cc554 100644
--- a/secure/lib/libssl/Makefile
+++ b/secure/lib/libssl/Makefile
@@ -17,7 +17,7 @@ SRCS= bio_ssl.c d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \
s3_both.c s3_clnt.c s3_enc.c s3_lib.c s3_meth.c s3_pkt.c \
s3_srvr.c ssl_algs.c ssl_asn1.c ssl_cert.c ssl_ciph.c \
ssl_err.c ssl_err2.c ssl_lib.c ssl_rsa.c ssl_sess.c ssl_stat.c \
- ssl_txt.c t1_clnt.c t1_enc.c t1_lib.c t1_meth.c t1_srvr.c \
+ ssl_txt.c t1_clnt.c t1_enc.c t1_lib.c t1_meth.c t1_reneg.c t1_srvr.c
INCS= dtls1.h kssl.h ssl.h ssl2.h ssl23.h ssl3.h tls1.h
INCSDIR=${INCLUDEDIR}/openssl
diff --git a/secure/lib/libssl/Makefile.man b/secure/lib/libssl/Makefile.man
index 77d1aed..8219687 100644
--- a/secure/lib/libssl/Makefile.man
+++ b/secure/lib/libssl/Makefile.man
@@ -135,8 +135,11 @@ MLINKS+= SSL_CTX_set_msg_callback.3 SSL_CTX_set_msg_callback_arg.3
MLINKS+= SSL_CTX_set_msg_callback.3 SSL_set_msg_callback.3
MLINKS+= SSL_CTX_set_msg_callback.3 SSL_get_msg_callback_arg.3
MLINKS+= SSL_CTX_set_options.3 SSL_set_options.3
+MLINKS+= SSL_CTX_set_options.3 SSL_CTX_clear_options.3
+MLINKS+= SSL_CTX_set_options.3 SSL_clear_options.3
MLINKS+= SSL_CTX_set_options.3 SSL_CTX_get_options.3
MLINKS+= SSL_CTX_set_options.3 SSL_get_options.3
+MLINKS+= SSL_CTX_set_options.3 SSL_get_secure_renegotiation_support.3
MLINKS+= SSL_CTX_set_quiet_shutdown.3 SSL_CTX_get_quiet_shutdown.3
MLINKS+= SSL_CTX_set_quiet_shutdown.3 SSL_set_quiet_shutdown.3
MLINKS+= SSL_CTX_set_quiet_shutdown.3 SSL_get_quiet_shutdown.3
diff --git a/secure/lib/libssl/man/SSL_CIPHER_get_name.3 b/secure/lib/libssl/man/SSL_CIPHER_get_name.3
index 0910a66..2f70b34 100644
--- a/secure/lib/libssl/man/SSL_CIPHER_get_name.3
+++ b/secure/lib/libssl/man/SSL_CIPHER_get_name.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CIPHER_get_name 3"
-.TH SSL_CIPHER_get_name 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CIPHER_get_name 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CIPHER_get_name, SSL_CIPHER_get_bits, SSL_CIPHER_get_version, SSL_CIPHER_description \- get SSL_CIPHER properties
.SH "SYNOPSIS"
@@ -142,7 +142,7 @@ SSL_CIPHER_get_name, SSL_CIPHER_get_bits, SSL_CIPHER_get_version, SSL_CIPHER_des
\& const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
\& int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *alg_bits);
\& char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
-\& char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int size);
+\& char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int size);
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
diff --git a/secure/lib/libssl/man/SSL_COMP_add_compression_method.3 b/secure/lib/libssl/man/SSL_COMP_add_compression_method.3
index 0df7050..2af197e 100644
--- a/secure/lib/libssl/man/SSL_COMP_add_compression_method.3
+++ b/secure/lib/libssl/man/SSL_COMP_add_compression_method.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_COMP_add_compression_method 3"
-.TH SSL_COMP_add_compression_method 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_COMP_add_compression_method 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_COMP_add_compression_method \- handle SSL/TLS integrated compression methods
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3 b/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3
index adf5fd1..2a0b640 100644
--- a/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3
+++ b/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_add_extra_chain_cert 3"
-.TH SSL_CTX_add_extra_chain_cert 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_add_extra_chain_cert 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_add_extra_chain_cert \- add certificate to chain
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_add_session.3 b/secure/lib/libssl/man/SSL_CTX_add_session.3
index fc1f522..8186a2e 100644
--- a/secure/lib/libssl/man/SSL_CTX_add_session.3
+++ b/secure/lib/libssl/man/SSL_CTX_add_session.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_add_session 3"
-.TH SSL_CTX_add_session 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_add_session 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_add_session, SSL_add_session, SSL_CTX_remove_session, SSL_remove_session \- manipulate session cache
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_ctrl.3 b/secure/lib/libssl/man/SSL_CTX_ctrl.3
index ad723a2..a8936f4 100644
--- a/secure/lib/libssl/man/SSL_CTX_ctrl.3
+++ b/secure/lib/libssl/man/SSL_CTX_ctrl.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_ctrl 3"
-.TH SSL_CTX_ctrl 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_ctrl 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_ctrl, SSL_CTX_callback_ctrl, SSL_ctrl, SSL_callback_ctrl \- internal handling functions for SSL_CTX and SSL objects
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_flush_sessions.3 b/secure/lib/libssl/man/SSL_CTX_flush_sessions.3
index f5d2bbd..8660dbe 100644
--- a/secure/lib/libssl/man/SSL_CTX_flush_sessions.3
+++ b/secure/lib/libssl/man/SSL_CTX_flush_sessions.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_flush_sessions 3"
-.TH SSL_CTX_flush_sessions 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_flush_sessions 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_flush_sessions, SSL_flush_sessions \- remove expired sessions
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_free.3 b/secure/lib/libssl/man/SSL_CTX_free.3
index 25678d3..38cd8be 100644
--- a/secure/lib/libssl/man/SSL_CTX_free.3
+++ b/secure/lib/libssl/man/SSL_CTX_free.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_free 3"
-.TH SSL_CTX_free 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_free 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_free \- free an allocated SSL_CTX object
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3
index 3ee3512..e3652c7 100644
--- a/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3
+++ b/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_get_ex_new_index 3"
-.TH SSL_CTX_get_ex_new_index 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_get_ex_new_index 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_get_ex_new_index, SSL_CTX_set_ex_data, SSL_CTX_get_ex_data \- internal application specific data functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3 b/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3
index b7b4f44..98c4b59 100644
--- a/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3
+++ b/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_get_verify_mode 3"
-.TH SSL_CTX_get_verify_mode 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_get_verify_mode 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_get_verify_mode, SSL_get_verify_mode, SSL_CTX_get_verify_depth, SSL_get_verify_depth, SSL_get_verify_callback, SSL_CTX_get_verify_callback \- get currently set verification parameters
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3 b/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3
index e601485..f11e6f0 100644
--- a/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3
+++ b/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_load_verify_locations 3"
-.TH SSL_CTX_load_verify_locations 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_load_verify_locations 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_load_verify_locations \- set default locations for trusted CA
certificates
diff --git a/secure/lib/libssl/man/SSL_CTX_new.3 b/secure/lib/libssl/man/SSL_CTX_new.3
index 5447b4e..8be542b 100644
--- a/secure/lib/libssl/man/SSL_CTX_new.3
+++ b/secure/lib/libssl/man/SSL_CTX_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_new 3"
-.TH SSL_CTX_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_new \- create a new SSL_CTX object as framework for TLS/SSL enabled functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_sess_number.3 b/secure/lib/libssl/man/SSL_CTX_sess_number.3
index 4ba9d45..e023466 100644
--- a/secure/lib/libssl/man/SSL_CTX_sess_number.3
+++ b/secure/lib/libssl/man/SSL_CTX_sess_number.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sess_number 3"
-.TH SSL_CTX_sess_number 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_sess_number 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_sess_number, SSL_CTX_sess_connect, SSL_CTX_sess_connect_good, SSL_CTX_sess_connect_renegotiate, SSL_CTX_sess_accept, SSL_CTX_sess_accept_good, SSL_CTX_sess_accept_renegotiate, SSL_CTX_sess_hits, SSL_CTX_sess_cb_hits, SSL_CTX_sess_misses, SSL_CTX_sess_timeouts, SSL_CTX_sess_cache_full \- obtain session cache statistics
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3 b/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3
index 4f44d72..daed365 100644
--- a/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3
+++ b/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sess_set_cache_size 3"
-.TH SSL_CTX_sess_set_cache_size 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_sess_set_cache_size 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_sess_set_cache_size, SSL_CTX_sess_get_cache_size \- manipulate session cache size
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3 b/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3
index 8cee8d4..d262bf3 100644
--- a/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3
+++ b/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sess_set_get_cb 3"
-.TH SSL_CTX_sess_set_get_cb 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_sess_set_get_cb 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_remove_cb, SSL_CTX_sess_set_get_cb, SSL_CTX_sess_get_new_cb, SSL_CTX_sess_get_remove_cb, SSL_CTX_sess_get_get_cb \- provide callback functions for server side external session caching
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_sessions.3 b/secure/lib/libssl/man/SSL_CTX_sessions.3
index 864967c..ead4830 100644
--- a/secure/lib/libssl/man/SSL_CTX_sessions.3
+++ b/secure/lib/libssl/man/SSL_CTX_sessions.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sessions 3"
-.TH SSL_CTX_sessions 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_sessions 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_sessions \- access internal session cache
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_store.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_store.3
index 2cde65d..bc4d842 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_cert_store.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_cert_store.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_cert_store 3"
-.TH SSL_CTX_set_cert_store 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_cert_store 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_cert_store, SSL_CTX_get_cert_store \- manipulate X509 certificate verification storage
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3
index 6478cc2..dcfff6b 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_cert_verify_callback 3"
-.TH SSL_CTX_set_cert_verify_callback 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_cert_verify_callback 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_cert_verify_callback \- set peer certificate verification procedure
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3 b/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3
index 4e44b75..4f09254 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_cipher_list 3"
-.TH SSL_CTX_set_cipher_list 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_cipher_list 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_cipher_list, SSL_set_cipher_list \- choose list of available SSL_CIPHERs
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3 b/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3
index ab2a299..ad37514 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_client_CA_list 3"
-.TH SSL_CTX_set_client_CA_list 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_client_CA_list 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_client_CA_list, SSL_set_client_CA_list, SSL_CTX_add_client_CA,
SSL_add_client_CA \- set list of CAs sent to the client when requesting a
diff --git a/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3
index 2c1d115..89e269a 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_client_cert_cb 3"
-.TH SSL_CTX_set_client_cert_cb 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_client_cert_cb 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_client_cert_cb, SSL_CTX_get_client_cert_cb \- handle client certificate callback function
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3
index 1f827ae..6d48405 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_default_passwd_cb 3"
-.TH SSL_CTX_set_default_passwd_cb 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_default_passwd_cb 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_default_passwd_cb, SSL_CTX_set_default_passwd_cb_userdata \- set passwd callback for encrypted PEM file handling
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3 b/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3
index 9c77d36..8bb75a3 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_generate_session_id 3"
-.TH SSL_CTX_set_generate_session_id 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_generate_session_id 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, SSL_has_matching_session_id \- manipulate generation of SSL session IDs (server only)
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_info_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_info_callback.3
index 490f36b..4b81c68 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_info_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_info_callback.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_info_callback 3"
-.TH SSL_CTX_set_info_callback 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_info_callback 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_info_callback, SSL_CTX_get_info_callback, SSL_set_info_callback, SSL_get_info_callback \- handle information callback for SSL connections
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3 b/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3
index 71bb784..16ff5b1 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_max_cert_list 3"
-.TH SSL_CTX_set_max_cert_list 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_max_cert_list 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_max_cert_list, SSL_CTX_get_max_cert_list, SSL_set_max_cert_list, SSL_get_max_cert_list, \- manipulate allowed for the peer's certificate chain
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_mode.3 b/secure/lib/libssl/man/SSL_CTX_set_mode.3
index 78426f0..6608a78 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_mode.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_mode.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_mode 3"
-.TH SSL_CTX_set_mode 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_mode 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_mode, SSL_set_mode, SSL_CTX_get_mode, SSL_get_mode \- manipulate SSL engine mode
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3
index a801dbc..36f047f 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_msg_callback 3"
-.TH SSL_CTX_set_msg_callback 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_msg_callback 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_msg_callback, SSL_CTX_set_msg_callback_arg, SSL_set_msg_callback, SSL_get_msg_callback_arg \- install callback for observing protocol messages
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_options.3 b/secure/lib/libssl/man/SSL_CTX_set_options.3
index 39c5397..2fe105b 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_options.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_options.3
@@ -129,9 +129,9 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_options 3"
-.TH SSL_CTX_set_options 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_options 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
-SSL_CTX_set_options, SSL_set_options, SSL_CTX_get_options, SSL_get_options \- manipulate SSL engine options
+SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options, SSL_clear_options, SSL_CTX_get_options, SSL_get_options, SSL_get_secure_renegotiation_support \- manipulate SSL options
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
@@ -144,25 +144,44 @@ SSL_CTX_set_options, SSL_set_options, SSL_CTX_get_options, SSL_get_options \- ma
.Ve
.PP
.Vb 2
+\& long SSL_CTX_clear_options(SSL_CTX *ctx, long options);
+\& long SSL_clear_options(SSL *ssl, long options);
+.Ve
+.PP
+.Vb 2
\& long SSL_CTX_get_options(SSL_CTX *ctx);
\& long SSL_get_options(SSL *ssl);
.Ve
+.PP
+.Vb 1
+\& long SSL_get_secure_renegotiation_support(SSL *ssl);
+.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
+Note: all these functions are implemented using macros.
+.PP
\&\fISSL_CTX_set_options()\fR adds the options set via bitmask in \fBoptions\fR to \fBctx\fR.
Options already set before are not cleared!
.PP
\&\fISSL_set_options()\fR adds the options set via bitmask in \fBoptions\fR to \fBssl\fR.
Options already set before are not cleared!
.PP
+\&\fISSL_CTX_clear_options()\fR clears the options set via bitmask in \fBoptions\fR
+to \fBctx\fR.
+.PP
+\&\fISSL_clear_options()\fR clears the options set via bitmask in \fBoptions\fR to \fBssl\fR.
+.PP
\&\fISSL_CTX_get_options()\fR returns the options set for \fBctx\fR.
.PP
\&\fISSL_get_options()\fR returns the options set for \fBssl\fR.
+.PP
+\&\fISSL_get_secure_renegotiation_support()\fR indicates whether the peer supports
+secure renegotiation.
.SH "NOTES"
.IX Header "NOTES"
The behaviour of the \s-1SSL\s0 library can be changed by setting several options.
The options are coded as bitmasks and can be combined by a logical \fBor\fR
-operation (|). Options can only be added but can never be reset.
+operation (|).
.PP
\&\fISSL_CTX_set_options()\fR and \fISSL_set_options()\fR affect the (external)
protocol behaviour of the \s-1SSL\s0 library. The (internal) behaviour of
@@ -302,7 +321,7 @@ Do not use the TLSv1 protocol.
.IX Item "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION"
When performing renegotiation as a server, always start a new session
(i.e., session resumption requests are only accepted in the initial
-handshake). This option is not needed for clients.
+handshake). This option is not needed for clients.
.IP "\s-1SSL_OP_NO_TICKET\s0" 4
.IX Item "SSL_OP_NO_TICKET"
Normally clients and servers will, where possible, transparently make use
@@ -311,12 +330,98 @@ is explicitly set when OpenSSL is compiled.
.Sp
If this option is set this functionality is disabled and tickets will
not be used by clients or servers.
+.IP "\s-1SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\s0" 4
+.IX Item "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION"
+Allow legacy insecure renegotiation between OpenSSL and unpatched clients or
+servers. See the \fB\s-1SECURE\s0 \s-1RENEGOTIATION\s0\fR section for more details.
+.IP "\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0" 4
+.IX Item "SSL_OP_LEGACY_SERVER_CONNECT"
+Allow legacy insecure renegotiation between OpenSSL and unpatched servers
+\&\fBonly\fR: this option is currently set by default. See the
+\&\fB\s-1SECURE\s0 \s-1RENEGOTIATION\s0\fR section for more details.
+.SH "SECURE RENEGOTIATION"
+.IX Header "SECURE RENEGOTIATION"
+OpenSSL 0.9.8m and later always attempts to use secure renegotiation as
+described in \s-1RFC5746\s0. This counters the prefix attack described in
+\&\s-1CVE\-2009\-3555\s0 and elsewhere.
+.PP
+The deprecated and highly broken SSLv2 protocol does not support
+renegotiation at all: its use is \fBstrongly\fR discouraged.
+.PP
+This attack has far reaching consequences which application writers should be
+aware of. In the description below an implementation supporting secure
+renegotiation is referred to as \fIpatched\fR. A server not supporting secure
+renegotiation is referred to as \fIunpatched\fR.
+.PP
+The following sections describe the operations permitted by OpenSSL's secure
+renegotiation implementation.
+.Sh "Patched client and server"
+.IX Subsection "Patched client and server"
+Connections and renegotiation are always permitted by OpenSSL implementations.
+.Sh "Unpatched client and patched OpenSSL server"
+.IX Subsection "Unpatched client and patched OpenSSL server"
+The initial connection suceeds but client renegotiation is denied by the
+server with a \fBno_renegotiation\fR warning alert if \s-1TLS\s0 v1.0 is used or a fatal
+\&\fBhandshake_failure\fR alert in \s-1SSL\s0 v3.0.
+.PP
+If the patched OpenSSL server attempts to renegotiate a fatal
+\&\fBhandshake_failure\fR alert is sent. This is because the server code may be
+unaware of the unpatched nature of the client.
+.PP
+If the option \fB\s-1SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\s0\fR is set then
+renegotiation \fBalways\fR succeeds.
+.PP
+\&\fB\s-1NB:\s0\fR a bug in OpenSSL clients earlier than 0.9.8m (all of which are
+unpatched) will result in the connection hanging if it receives a
+\&\fBno_renegotiation\fR alert. OpenSSL versions 0.9.8m and later will regard
+a \fBno_renegotiation\fR alert as fatal and respond with a fatal
+\&\fBhandshake_failure\fR alert. This is because the OpenSSL \s-1API\s0 currently has
+no provision to indicate to an application that a renegotiation attempt
+was refused.
+.Sh "Patched OpenSSL client and unpatched server."
+.IX Subsection "Patched OpenSSL client and unpatched server."
+If the option \fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR or
+\&\fB\s-1SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\s0\fR is set then initial connections
+and renegotiation between patched OpenSSL clients and unpatched servers
+succeeds. If neither option is set then initial connections to unpatched
+servers will fail.
+.PP
+The option \fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR is currently set by default even
+though it has security implications: otherwise it would be impossible to
+connect to unpatched servers (i.e. all of them initially) and this is clearly
+not acceptable. Renegotiation is permitted because this does not add any
+additional security issues: during an attack clients do not see any
+renegotiations anyway.
+.PP
+As more servers become patched the option \fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR will
+\&\fBnot\fR be set by default in a future version of OpenSSL.
+.PP
+OpenSSL client applications wishing to ensure they can connect to unpatched
+servers should always \fBset\fR \fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR
+.PP
+OpenSSL client applications that want to ensure they can \fBnot\fR connect to
+unpatched servers (and thus avoid any security issues) should always \fBclear\fR
+\&\fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR using \fISSL_CTX_clear_options()\fR or
+\&\fISSL_clear_options()\fR.
+.PP
+The difference between the \fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR and
+\&\fB\s-1SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\s0\fR options is that
+\&\fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR enables initial connections and secure
+renegotiation between OpenSSL clients and unpatched servers \fBonly\fR, while
+\&\fB\s-1SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\s0\fR allows initial connections
+and renegotiation between OpenSSL and unpatched clients or servers.
.SH "RETURN VALUES"
.IX Header "RETURN VALUES"
\&\fISSL_CTX_set_options()\fR and \fISSL_set_options()\fR return the new options bitmask
after adding \fBoptions\fR.
.PP
+\&\fISSL_CTX_clear_options()\fR and \fISSL_clear_options()\fR return the new options bitmask
+after clearing \fBoptions\fR.
+.PP
\&\fISSL_CTX_get_options()\fR and \fISSL_get_options()\fR return the current bitmask.
+.PP
+\&\fISSL_get_secure_renegotiation_support()\fR returns 1 is the peer supports
+secure renegotiation and 0 if it does not.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fIssl\fR\|(3), \fISSL_new\fR\|(3), \fISSL_clear\fR\|(3),
@@ -337,3 +442,10 @@ and must be explicitly set.
Versions up to OpenSSL 0.9.6c do not include the countermeasure that
can be disabled with this option (in OpenSSL 0.9.6d, it was always
enabled).
+.PP
+\&\fISSL_CTX_clear_options()\fR and \fISSL_clear_options()\fR were first added in OpenSSL
+0.9.8m.
+.PP
+\&\fB\s-1SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\s0\fR, \fB\s-1SSL_OP_LEGACY_SERVER_CONNECT\s0\fR
+and the function \fISSL_get_secure_renegotiation_support()\fR were first added in
+OpenSSL 0.9.8m.
diff --git a/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3 b/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3
index c5b0151..8804a8c 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_quiet_shutdown 3"
-.TH SSL_CTX_set_quiet_shutdown 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_quiet_shutdown 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_quiet_shutdown, SSL_CTX_get_quiet_shutdown, SSL_set_quiet_shutdown, SSL_get_quiet_shutdown \- manipulate shutdown behaviour
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3 b/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3
index eb8205a..670fb21 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_session_cache_mode 3"
-.TH SSL_CTX_set_session_cache_mode 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_session_cache_mode 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_session_cache_mode, SSL_CTX_get_session_cache_mode \- enable/disable session caching
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3 b/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3
index 5da9e80..8be1e1f 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_session_id_context 3"
-.TH SSL_CTX_set_session_id_context 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_session_id_context 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_session_id_context, SSL_set_session_id_context \- set context within which session can be reused (server side only)
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3 b/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3
index aa50cae..da9d5ea 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_ssl_version 3"
-.TH SSL_CTX_set_ssl_version 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_ssl_version 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_ssl_version, SSL_set_ssl_method, SSL_get_ssl_method
\&\- choose a new TLS/SSL method
diff --git a/secure/lib/libssl/man/SSL_CTX_set_timeout.3 b/secure/lib/libssl/man/SSL_CTX_set_timeout.3
index e03e28d..4a712d4 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_timeout.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_timeout.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_timeout 3"
-.TH SSL_CTX_set_timeout 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_timeout 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_timeout, SSL_CTX_get_timeout \- manipulate timeout values for session caching
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3
index 0814ca3..ec556c9 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_tmp_dh_callback 3"
-.TH SSL_CTX_set_tmp_dh_callback 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_tmp_dh_callback 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_tmp_dh_callback, SSL_CTX_set_tmp_dh, SSL_set_tmp_dh_callback, SSL_set_tmp_dh \- handle DH keys for ephemeral key exchange
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3
index f55199c..4a2806b 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_tmp_rsa_callback 3"
-.TH SSL_CTX_set_tmp_rsa_callback 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_tmp_rsa_callback 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_tmp_rsa_callback, SSL_CTX_set_tmp_rsa, SSL_CTX_need_tmp_rsa, SSL_set_tmp_rsa_callback, SSL_set_tmp_rsa, SSL_need_tmp_rsa \- handle RSA keys for ephemeral key exchange
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_set_verify.3 b/secure/lib/libssl/man/SSL_CTX_set_verify.3
index 9c2f4c8..7a472f9 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_verify.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_verify.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_verify 3"
-.TH SSL_CTX_set_verify 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_set_verify 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_set_verify, SSL_set_verify, SSL_CTX_set_verify_depth, SSL_set_verify_depth \- set peer certificate verification parameters
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_CTX_use_certificate.3 b/secure/lib/libssl/man/SSL_CTX_use_certificate.3
index 06ecb49..1a7c577 100644
--- a/secure/lib/libssl/man/SSL_CTX_use_certificate.3
+++ b/secure/lib/libssl/man/SSL_CTX_use_certificate.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_use_certificate 3"
-.TH SSL_CTX_use_certificate 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_CTX_use_certificate 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_CTX_use_certificate, SSL_CTX_use_certificate_ASN1, SSL_CTX_use_certificate_file, SSL_use_certificate, SSL_use_certificate_ASN1, SSL_use_certificate_file, SSL_CTX_use_certificate_chain_file, SSL_CTX_use_PrivateKey, SSL_CTX_use_PrivateKey_ASN1, SSL_CTX_use_PrivateKey_file, SSL_CTX_use_RSAPrivateKey, SSL_CTX_use_RSAPrivateKey_ASN1, SSL_CTX_use_RSAPrivateKey_file, SSL_use_PrivateKey_file, SSL_use_PrivateKey_ASN1, SSL_use_PrivateKey, SSL_use_RSAPrivateKey, SSL_use_RSAPrivateKey_ASN1, SSL_use_RSAPrivateKey_file, SSL_CTX_check_private_key, SSL_check_private_key \- load certificate and key data
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_SESSION_free.3 b/secure/lib/libssl/man/SSL_SESSION_free.3
index 664f90b..5b25df1 100644
--- a/secure/lib/libssl/man/SSL_SESSION_free.3
+++ b/secure/lib/libssl/man/SSL_SESSION_free.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_SESSION_free 3"
-.TH SSL_SESSION_free 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_SESSION_free 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_SESSION_free \- free an allocated SSL_SESSION structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3
index ca23644..3be7e70 100644
--- a/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3
+++ b/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_SESSION_get_ex_new_index 3"
-.TH SSL_SESSION_get_ex_new_index 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_SESSION_get_ex_new_index 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_SESSION_get_ex_new_index, SSL_SESSION_set_ex_data, SSL_SESSION_get_ex_data \- internal application specific data functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_SESSION_get_time.3 b/secure/lib/libssl/man/SSL_SESSION_get_time.3
index 9ae31ce..5d4f72c 100644
--- a/secure/lib/libssl/man/SSL_SESSION_get_time.3
+++ b/secure/lib/libssl/man/SSL_SESSION_get_time.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_SESSION_get_time 3"
-.TH SSL_SESSION_get_time 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_SESSION_get_time 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_SESSION_get_time, SSL_SESSION_set_time, SSL_SESSION_get_timeout, SSL_SESSION_set_timeout \- retrieve and manipulate session time and timeout settings
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_accept.3 b/secure/lib/libssl/man/SSL_accept.3
index 8ae9950..c8e7ca1 100644
--- a/secure/lib/libssl/man/SSL_accept.3
+++ b/secure/lib/libssl/man/SSL_accept.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_accept 3"
-.TH SSL_accept 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_accept 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_accept \- wait for a TLS/SSL client to initiate a TLS/SSL handshake
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_alert_type_string.3 b/secure/lib/libssl/man/SSL_alert_type_string.3
index 32c64e9..9ea9096 100644
--- a/secure/lib/libssl/man/SSL_alert_type_string.3
+++ b/secure/lib/libssl/man/SSL_alert_type_string.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_alert_type_string 3"
-.TH SSL_alert_type_string 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_alert_type_string 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_alert_type_string, SSL_alert_type_string_long, SSL_alert_desc_string, SSL_alert_desc_string_long \- get textual description of alert information
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_clear.3 b/secure/lib/libssl/man/SSL_clear.3
index 8494ed4..96d2299 100644
--- a/secure/lib/libssl/man/SSL_clear.3
+++ b/secure/lib/libssl/man/SSL_clear.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_clear 3"
-.TH SSL_clear 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_clear 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_clear \- reset SSL object to allow another connection
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_connect.3 b/secure/lib/libssl/man/SSL_connect.3
index bdb9d8a..72579f2 100644
--- a/secure/lib/libssl/man/SSL_connect.3
+++ b/secure/lib/libssl/man/SSL_connect.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_connect 3"
-.TH SSL_connect 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_connect 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_connect \- initiate the TLS/SSL handshake with an TLS/SSL server
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_do_handshake.3 b/secure/lib/libssl/man/SSL_do_handshake.3
index a3ce636..551e0e3 100644
--- a/secure/lib/libssl/man/SSL_do_handshake.3
+++ b/secure/lib/libssl/man/SSL_do_handshake.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_do_handshake 3"
-.TH SSL_do_handshake 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_do_handshake 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_do_handshake \- perform a TLS/SSL handshake
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_free.3 b/secure/lib/libssl/man/SSL_free.3
index 06473cb..1ac635e 100644
--- a/secure/lib/libssl/man/SSL_free.3
+++ b/secure/lib/libssl/man/SSL_free.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_free 3"
-.TH SSL_free 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_free 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_free \- free an allocated SSL structure
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_SSL_CTX.3 b/secure/lib/libssl/man/SSL_get_SSL_CTX.3
index 1059651..62d5875 100644
--- a/secure/lib/libssl/man/SSL_get_SSL_CTX.3
+++ b/secure/lib/libssl/man/SSL_get_SSL_CTX.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_SSL_CTX 3"
-.TH SSL_get_SSL_CTX 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_SSL_CTX 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_SSL_CTX \- get the SSL_CTX from which an SSL is created
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_ciphers.3 b/secure/lib/libssl/man/SSL_get_ciphers.3
index 8bbee12..ddb1055 100644
--- a/secure/lib/libssl/man/SSL_get_ciphers.3
+++ b/secure/lib/libssl/man/SSL_get_ciphers.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_ciphers 3"
-.TH SSL_get_ciphers 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_ciphers 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_ciphers, SSL_get_cipher_list \- get list of available SSL_CIPHERs
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_client_CA_list.3 b/secure/lib/libssl/man/SSL_get_client_CA_list.3
index 8158f72..9b51e10 100644
--- a/secure/lib/libssl/man/SSL_get_client_CA_list.3
+++ b/secure/lib/libssl/man/SSL_get_client_CA_list.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_client_CA_list 3"
-.TH SSL_get_client_CA_list 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_client_CA_list 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_client_CA_list, SSL_CTX_get_client_CA_list \- get list of client CAs
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_current_cipher.3 b/secure/lib/libssl/man/SSL_get_current_cipher.3
index a21ffdc..91fc087 100644
--- a/secure/lib/libssl/man/SSL_get_current_cipher.3
+++ b/secure/lib/libssl/man/SSL_get_current_cipher.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_current_cipher 3"
-.TH SSL_get_current_cipher 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_current_cipher 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_current_cipher, SSL_get_cipher, SSL_get_cipher_name,
SSL_get_cipher_bits, SSL_get_cipher_version \- get SSL_CIPHER of a connection
diff --git a/secure/lib/libssl/man/SSL_get_default_timeout.3 b/secure/lib/libssl/man/SSL_get_default_timeout.3
index a927b94..64e7d25 100644
--- a/secure/lib/libssl/man/SSL_get_default_timeout.3
+++ b/secure/lib/libssl/man/SSL_get_default_timeout.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_default_timeout 3"
-.TH SSL_get_default_timeout 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_default_timeout 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_default_timeout \- get default session timeout value
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_error.3 b/secure/lib/libssl/man/SSL_get_error.3
index 788c1a8..8f60e42 100644
--- a/secure/lib/libssl/man/SSL_get_error.3
+++ b/secure/lib/libssl/man/SSL_get_error.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_error 3"
-.TH SSL_get_error 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_error 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_error \- obtain result code for TLS/SSL I/O operation
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 b/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3
index 8dcdeeb..a6acd5e 100644
--- a/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3
+++ b/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_ex_data_X509_STORE_CTX_idx 3"
-.TH SSL_get_ex_data_X509_STORE_CTX_idx 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_ex_data_X509_STORE_CTX_idx 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_ex_data_X509_STORE_CTX_idx \- get ex_data index to access SSL structure
from X509_STORE_CTX
diff --git a/secure/lib/libssl/man/SSL_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_get_ex_new_index.3
index c5498ae..ba5a86f 100644
--- a/secure/lib/libssl/man/SSL_get_ex_new_index.3
+++ b/secure/lib/libssl/man/SSL_get_ex_new_index.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_ex_new_index 3"
-.TH SSL_get_ex_new_index 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_ex_new_index 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_ex_new_index, SSL_set_ex_data, SSL_get_ex_data \- internal application specific data functions
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_fd.3 b/secure/lib/libssl/man/SSL_get_fd.3
index f4eeebf..935bc4a 100644
--- a/secure/lib/libssl/man/SSL_get_fd.3
+++ b/secure/lib/libssl/man/SSL_get_fd.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_fd 3"
-.TH SSL_get_fd 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_fd 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_fd \- get file descriptor linked to an SSL object
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_peer_cert_chain.3 b/secure/lib/libssl/man/SSL_get_peer_cert_chain.3
index a290a94..65fd9be 100644
--- a/secure/lib/libssl/man/SSL_get_peer_cert_chain.3
+++ b/secure/lib/libssl/man/SSL_get_peer_cert_chain.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_peer_cert_chain 3"
-.TH SSL_get_peer_cert_chain 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_peer_cert_chain 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_peer_cert_chain \- get the X509 certificate chain of the peer
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_peer_certificate.3 b/secure/lib/libssl/man/SSL_get_peer_certificate.3
index 1243227..9ce3a9a 100644
--- a/secure/lib/libssl/man/SSL_get_peer_certificate.3
+++ b/secure/lib/libssl/man/SSL_get_peer_certificate.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_peer_certificate 3"
-.TH SSL_get_peer_certificate 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_peer_certificate 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_peer_certificate \- get the X509 certificate of the peer
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_rbio.3 b/secure/lib/libssl/man/SSL_get_rbio.3
index c91b7d7..f441d54 100644
--- a/secure/lib/libssl/man/SSL_get_rbio.3
+++ b/secure/lib/libssl/man/SSL_get_rbio.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_rbio 3"
-.TH SSL_get_rbio 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_rbio 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_rbio \- get BIO linked to an SSL object
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_session.3 b/secure/lib/libssl/man/SSL_get_session.3
index 454acdc..04b9bd5 100644
--- a/secure/lib/libssl/man/SSL_get_session.3
+++ b/secure/lib/libssl/man/SSL_get_session.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_session 3"
-.TH SSL_get_session 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_session 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_session \- retrieve TLS/SSL session data
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_verify_result.3 b/secure/lib/libssl/man/SSL_get_verify_result.3
index 4629d96..34afe38 100644
--- a/secure/lib/libssl/man/SSL_get_verify_result.3
+++ b/secure/lib/libssl/man/SSL_get_verify_result.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_verify_result 3"
-.TH SSL_get_verify_result 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_verify_result 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_verify_result \- get result of peer certificate verification
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_get_version.3 b/secure/lib/libssl/man/SSL_get_version.3
index fb4b55c..8e8aca1 100644
--- a/secure/lib/libssl/man/SSL_get_version.3
+++ b/secure/lib/libssl/man/SSL_get_version.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_version 3"
-.TH SSL_get_version 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_get_version 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_get_version \- get the protocol version of a connection.
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_library_init.3 b/secure/lib/libssl/man/SSL_library_init.3
index ae8cbb8..76f8302 100644
--- a/secure/lib/libssl/man/SSL_library_init.3
+++ b/secure/lib/libssl/man/SSL_library_init.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_library_init 3"
-.TH SSL_library_init 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_library_init 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_library_init, OpenSSL_add_ssl_algorithms, SSLeay_add_ssl_algorithms
\&\- initialize SSL library by registering algorithms
diff --git a/secure/lib/libssl/man/SSL_load_client_CA_file.3 b/secure/lib/libssl/man/SSL_load_client_CA_file.3
index d5fc18d..f449ffdf5 100644
--- a/secure/lib/libssl/man/SSL_load_client_CA_file.3
+++ b/secure/lib/libssl/man/SSL_load_client_CA_file.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_load_client_CA_file 3"
-.TH SSL_load_client_CA_file 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_load_client_CA_file 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_load_client_CA_file \- load certificate names from file
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_new.3 b/secure/lib/libssl/man/SSL_new.3
index 3f5785e..95ce218 100644
--- a/secure/lib/libssl/man/SSL_new.3
+++ b/secure/lib/libssl/man/SSL_new.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_new 3"
-.TH SSL_new 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_new 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_new \- create a new SSL structure for a connection
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_pending.3 b/secure/lib/libssl/man/SSL_pending.3
index a46d13e..b136be7 100644
--- a/secure/lib/libssl/man/SSL_pending.3
+++ b/secure/lib/libssl/man/SSL_pending.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_pending 3"
-.TH SSL_pending 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_pending 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_pending \- obtain number of readable bytes buffered in an SSL object
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_read.3 b/secure/lib/libssl/man/SSL_read.3
index afccb5b..ad2fdd8 100644
--- a/secure/lib/libssl/man/SSL_read.3
+++ b/secure/lib/libssl/man/SSL_read.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_read 3"
-.TH SSL_read 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_read 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_read \- read bytes from a TLS/SSL connection.
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_rstate_string.3 b/secure/lib/libssl/man/SSL_rstate_string.3
index 4d3751b..6a7940c 100644
--- a/secure/lib/libssl/man/SSL_rstate_string.3
+++ b/secure/lib/libssl/man/SSL_rstate_string.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_rstate_string 3"
-.TH SSL_rstate_string 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_rstate_string 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_rstate_string, SSL_rstate_string_long \- get textual description of state of an SSL object during read operation
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_session_reused.3 b/secure/lib/libssl/man/SSL_session_reused.3
index 9190b51..38dfa52 100644
--- a/secure/lib/libssl/man/SSL_session_reused.3
+++ b/secure/lib/libssl/man/SSL_session_reused.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_session_reused 3"
-.TH SSL_session_reused 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_session_reused 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_session_reused \- query whether a reused session was negotiated during handshake
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_set_bio.3 b/secure/lib/libssl/man/SSL_set_bio.3
index 017702a..18ea424 100644
--- a/secure/lib/libssl/man/SSL_set_bio.3
+++ b/secure/lib/libssl/man/SSL_set_bio.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_bio 3"
-.TH SSL_set_bio 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_set_bio 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_set_bio \- connect the SSL object with a BIO
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_set_connect_state.3 b/secure/lib/libssl/man/SSL_set_connect_state.3
index bee903a..3979808 100644
--- a/secure/lib/libssl/man/SSL_set_connect_state.3
+++ b/secure/lib/libssl/man/SSL_set_connect_state.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_connect_state 3"
-.TH SSL_set_connect_state 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_set_connect_state 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_set_connect_state, SSL_get_accept_state \- prepare SSL object to work in client or server mode
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_set_fd.3 b/secure/lib/libssl/man/SSL_set_fd.3
index b4e9108..bae9a12 100644
--- a/secure/lib/libssl/man/SSL_set_fd.3
+++ b/secure/lib/libssl/man/SSL_set_fd.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_fd 3"
-.TH SSL_set_fd 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_set_fd 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_set_fd \- connect the SSL object with a file descriptor
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_set_session.3 b/secure/lib/libssl/man/SSL_set_session.3
index 0b604b5..edc5e6b 100644
--- a/secure/lib/libssl/man/SSL_set_session.3
+++ b/secure/lib/libssl/man/SSL_set_session.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_session 3"
-.TH SSL_set_session 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_set_session 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_set_session \- set a TLS/SSL session to be used during TLS/SSL connect
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_set_shutdown.3 b/secure/lib/libssl/man/SSL_set_shutdown.3
index a42df5f..f1b8c77 100644
--- a/secure/lib/libssl/man/SSL_set_shutdown.3
+++ b/secure/lib/libssl/man/SSL_set_shutdown.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_shutdown 3"
-.TH SSL_set_shutdown 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_set_shutdown 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_set_shutdown, SSL_get_shutdown \- manipulate shutdown state of an SSL connection
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_set_verify_result.3 b/secure/lib/libssl/man/SSL_set_verify_result.3
index 10aa118..1367f02 100644
--- a/secure/lib/libssl/man/SSL_set_verify_result.3
+++ b/secure/lib/libssl/man/SSL_set_verify_result.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_verify_result 3"
-.TH SSL_set_verify_result 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_set_verify_result 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_set_verify_result \- override result of peer certificate verification
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_shutdown.3 b/secure/lib/libssl/man/SSL_shutdown.3
index 14a0677..23d1800 100644
--- a/secure/lib/libssl/man/SSL_shutdown.3
+++ b/secure/lib/libssl/man/SSL_shutdown.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_shutdown 3"
-.TH SSL_shutdown 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_shutdown 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_shutdown \- shut down a TLS/SSL connection
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_state_string.3 b/secure/lib/libssl/man/SSL_state_string.3
index 863db41..6726eb4 100644
--- a/secure/lib/libssl/man/SSL_state_string.3
+++ b/secure/lib/libssl/man/SSL_state_string.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_state_string 3"
-.TH SSL_state_string 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_state_string 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_state_string, SSL_state_string_long \- get textual description of state of an SSL object
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_want.3 b/secure/lib/libssl/man/SSL_want.3
index 8724bb1..bc65e36 100644
--- a/secure/lib/libssl/man/SSL_want.3
+++ b/secure/lib/libssl/man/SSL_want.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_want 3"
-.TH SSL_want 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_want 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_want, SSL_want_nothing, SSL_want_read, SSL_want_write, SSL_want_x509_lookup \- obtain state information TLS/SSL I/O operation
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/SSL_write.3 b/secure/lib/libssl/man/SSL_write.3
index 5553f26..6a2b347 100644
--- a/secure/lib/libssl/man/SSL_write.3
+++ b/secure/lib/libssl/man/SSL_write.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_write 3"
-.TH SSL_write 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SSL_write 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL_write \- write bytes to a TLS/SSL connection.
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/d2i_SSL_SESSION.3 b/secure/lib/libssl/man/d2i_SSL_SESSION.3
index 3a64080..0b7d316 100644
--- a/secure/lib/libssl/man/d2i_SSL_SESSION.3
+++ b/secure/lib/libssl/man/d2i_SSL_SESSION.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_SSL_SESSION 3"
-.TH d2i_SSL_SESSION 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH d2i_SSL_SESSION 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
d2i_SSL_SESSION, i2d_SSL_SESSION \- convert SSL_SESSION object from/to ASN1 representation
.SH "SYNOPSIS"
diff --git a/secure/lib/libssl/man/ssl.3 b/secure/lib/libssl/man/ssl.3
index bc2ed1d..c102751 100644
--- a/secure/lib/libssl/man/ssl.3
+++ b/secure/lib/libssl/man/ssl.3
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ssl 3"
-.TH ssl 3 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ssl 3 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
SSL \- OpenSSL SSL/TLS library
.SH "SYNOPSIS"
diff --git a/secure/libexec/Makefile b/secure/libexec/Makefile
index 1c3ee01..0c680e4 100644
--- a/secure/libexec/Makefile
+++ b/secure/libexec/Makefile
@@ -4,7 +4,7 @@
SUBDIR=
.if ${MK_OPENSSH} != "no"
-SUBDIR+=sftp-server ssh-keysign
+SUBDIR+=sftp-server ssh-keysign ssh-pkcs11-helper
.endif
.include <bsd.subdir.mk>
diff --git a/secure/libexec/ssh-pkcs11-helper/Makefile b/secure/libexec/ssh-pkcs11-helper/Makefile
new file mode 100644
index 0000000..f575a08
--- /dev/null
+++ b/secure/libexec/ssh-pkcs11-helper/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PROG= ssh-pkcs11-helper
+SRCS= ssh-pkcs11.c ssh-pkcs11-helper.c
+SRCS+= roaming_dummy.c
+MAN= ssh-pkcs11-helper.8
+CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
+
+DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
+LDADD= -lssh -lcrypt -lcrypto -lz
+
+.include <bsd.prog.mk>
+
+.PATH: ${SSHDIR}
+
+${OBJS} ${POBJS} ${SOBJS}: ssh_namespace.h
diff --git a/secure/usr.bin/openssl/man/CA.pl.1 b/secure/usr.bin/openssl/man/CA.pl.1
index 18102ab..eb38939 100644
--- a/secure/usr.bin/openssl/man/CA.pl.1
+++ b/secure/usr.bin/openssl/man/CA.pl.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CA.PL 1"
-.TH CA.PL 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CA.PL 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
CA.pl \- friendlier interface for OpenSSL certificate programs
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/asn1parse.1 b/secure/usr.bin/openssl/man/asn1parse.1
index a9a9fb5..7ca585d 100644
--- a/secure/usr.bin/openssl/man/asn1parse.1
+++ b/secure/usr.bin/openssl/man/asn1parse.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1PARSE 1"
-.TH ASN1PARSE 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ASN1PARSE 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
asn1parse \- ASN.1 parsing tool
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/ca.1 b/secure/usr.bin/openssl/man/ca.1
index 5643a1e..d4fd31a 100644
--- a/secure/usr.bin/openssl/man/ca.1
+++ b/secure/usr.bin/openssl/man/ca.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CA 1"
-.TH CA 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CA 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ca \- sample minimal CA application
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/ciphers.1 b/secure/usr.bin/openssl/man/ciphers.1
index 691a5e7..3f80cc6 100644
--- a/secure/usr.bin/openssl/man/ciphers.1
+++ b/secure/usr.bin/openssl/man/ciphers.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CIPHERS 1"
-.TH CIPHERS 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CIPHERS 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ciphers \- SSL cipher display and cipher list tool.
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/crl.1 b/secure/usr.bin/openssl/man/crl.1
index 37d56de..098f51c 100644
--- a/secure/usr.bin/openssl/man/crl.1
+++ b/secure/usr.bin/openssl/man/crl.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CRL 1"
-.TH CRL 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CRL 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
crl \- CRL utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/crl2pkcs7.1 b/secure/usr.bin/openssl/man/crl2pkcs7.1
index b1a7f35..09012c8 100644
--- a/secure/usr.bin/openssl/man/crl2pkcs7.1
+++ b/secure/usr.bin/openssl/man/crl2pkcs7.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "CRL2PKCS7 1"
-.TH CRL2PKCS7 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH CRL2PKCS7 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
crl2pkcs7 \- Create a PKCS#7 structure from a CRL and certificates.
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/dgst.1 b/secure/usr.bin/openssl/man/dgst.1
index 3e19b9c..31ba4d8 100644
--- a/secure/usr.bin/openssl/man/dgst.1
+++ b/secure/usr.bin/openssl/man/dgst.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DGST 1"
-.TH DGST 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DGST 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
dgst, md5, md4, md2, sha1, sha, mdc2, ripemd160 \- message digests
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/dhparam.1 b/secure/usr.bin/openssl/man/dhparam.1
index 9b03326..cd0f30a 100644
--- a/secure/usr.bin/openssl/man/dhparam.1
+++ b/secure/usr.bin/openssl/man/dhparam.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DHPARAM 1"
-.TH DHPARAM 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DHPARAM 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
dhparam \- DH parameter manipulation and generation
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/dsa.1 b/secure/usr.bin/openssl/man/dsa.1
index b8d0210..24350cc 100644
--- a/secure/usr.bin/openssl/man/dsa.1
+++ b/secure/usr.bin/openssl/man/dsa.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSA 1"
-.TH DSA 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSA 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
dsa \- DSA key processing
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/dsaparam.1 b/secure/usr.bin/openssl/man/dsaparam.1
index 3e2d9a7..a0bca74 100644
--- a/secure/usr.bin/openssl/man/dsaparam.1
+++ b/secure/usr.bin/openssl/man/dsaparam.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "DSAPARAM 1"
-.TH DSAPARAM 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH DSAPARAM 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
dsaparam \- DSA parameter manipulation and generation
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/ec.1 b/secure/usr.bin/openssl/man/ec.1
index cefd8d8..347023c 100644
--- a/secure/usr.bin/openssl/man/ec.1
+++ b/secure/usr.bin/openssl/man/ec.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EC 1"
-.TH EC 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH EC 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ec \- EC key processing
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/ecparam.1 b/secure/usr.bin/openssl/man/ecparam.1
index acd10ce..c7c2a28 100644
--- a/secure/usr.bin/openssl/man/ecparam.1
+++ b/secure/usr.bin/openssl/man/ecparam.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ECPARAM 1"
-.TH ECPARAM 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ECPARAM 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ecparam \- EC parameter manipulation and generation
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/enc.1 b/secure/usr.bin/openssl/man/enc.1
index f18d207..1760a59 100644
--- a/secure/usr.bin/openssl/man/enc.1
+++ b/secure/usr.bin/openssl/man/enc.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ENC 1"
-.TH ENC 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ENC 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
enc \- symmetric cipher routines
.SH "SYNOPSIS"
@@ -171,14 +171,12 @@ the password source. For more information about the format of \fBarg\fR
see the \fB\s-1PASS\s0 \s-1PHRASE\s0 \s-1ARGUMENTS\s0\fR section in \fIopenssl\fR\|(1).
.IP "\fB\-salt\fR" 4
.IX Item "-salt"
-use a salt in the key derivation routines. This option should \fB\s-1ALWAYS\s0\fR
-be used unless compatibility with previous versions of OpenSSL or SSLeay
-is required. This option is only present on OpenSSL versions 0.9.5 or
-above.
+use a salt in the key derivation routines. This is the default.
.IP "\fB\-nosalt\fR" 4
.IX Item "-nosalt"
-don't use a salt in the key derivation routines. This is the default for
-compatibility with previous versions of OpenSSL and SSLeay.
+don't use a salt in the key derivation routines. This option \fB\s-1SHOULD\s0 \s-1NOT\s0\fR be
+used except for test purposes or compatibility with ancient versions of OpenSSL
+and SSLeay.
.IP "\fB\-e\fR" 4
.IX Item "-e"
encrypt the input data: this is the default.
diff --git a/secure/usr.bin/openssl/man/errstr.1 b/secure/usr.bin/openssl/man/errstr.1
index 536595d..0f9c075 100644
--- a/secure/usr.bin/openssl/man/errstr.1
+++ b/secure/usr.bin/openssl/man/errstr.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "ERRSTR 1"
-.TH ERRSTR 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH ERRSTR 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
errstr \- lookup error codes
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/gendsa.1 b/secure/usr.bin/openssl/man/gendsa.1
index 3b0a02e..f8a472d 100644
--- a/secure/usr.bin/openssl/man/gendsa.1
+++ b/secure/usr.bin/openssl/man/gendsa.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "GENDSA 1"
-.TH GENDSA 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH GENDSA 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
gendsa \- generate a DSA private key from a set of parameters
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/genrsa.1 b/secure/usr.bin/openssl/man/genrsa.1
index a744a48..4be978d 100644
--- a/secure/usr.bin/openssl/man/genrsa.1
+++ b/secure/usr.bin/openssl/man/genrsa.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "GENRSA 1"
-.TH GENRSA 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH GENRSA 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
genrsa \- generate an RSA private key
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/nseq.1 b/secure/usr.bin/openssl/man/nseq.1
index b859103..b239d58 100644
--- a/secure/usr.bin/openssl/man/nseq.1
+++ b/secure/usr.bin/openssl/man/nseq.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "NSEQ 1"
-.TH NSEQ 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH NSEQ 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
nseq \- create or examine a netscape certificate sequence
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/ocsp.1 b/secure/usr.bin/openssl/man/ocsp.1
index b977601..5f18173 100644
--- a/secure/usr.bin/openssl/man/ocsp.1
+++ b/secure/usr.bin/openssl/man/ocsp.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OCSP 1"
-.TH OCSP 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OCSP 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
ocsp \- Online Certificate Status Protocol utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/openssl.1 b/secure/usr.bin/openssl/man/openssl.1
index c5f0010..b097a96 100644
--- a/secure/usr.bin/openssl/man/openssl.1
+++ b/secure/usr.bin/openssl/man/openssl.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL 1"
-.TH OPENSSL 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH OPENSSL 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
openssl \- OpenSSL command line tool
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/passwd.1 b/secure/usr.bin/openssl/man/passwd.1
index ea26bdb..3937bd2 100644
--- a/secure/usr.bin/openssl/man/passwd.1
+++ b/secure/usr.bin/openssl/man/passwd.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PASSWD 1"
-.TH PASSWD 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PASSWD 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
passwd \- compute password hashes
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/pkcs12.1 b/secure/usr.bin/openssl/man/pkcs12.1
index fa53df6..d468c69 100644
--- a/secure/usr.bin/openssl/man/pkcs12.1
+++ b/secure/usr.bin/openssl/man/pkcs12.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS12 1"
-.TH PKCS12 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS12 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
pkcs12 \- PKCS#12 file utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/pkcs7.1 b/secure/usr.bin/openssl/man/pkcs7.1
index fc0a081..79b134e 100644
--- a/secure/usr.bin/openssl/man/pkcs7.1
+++ b/secure/usr.bin/openssl/man/pkcs7.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7 1"
-.TH PKCS7 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS7 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
pkcs7 \- PKCS#7 utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/pkcs8.1 b/secure/usr.bin/openssl/man/pkcs8.1
index 66953e3..bb07c73 100644
--- a/secure/usr.bin/openssl/man/pkcs8.1
+++ b/secure/usr.bin/openssl/man/pkcs8.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS8 1"
-.TH PKCS8 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH PKCS8 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
pkcs8 \- PKCS#8 format private key conversion tool
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/rand.1 b/secure/usr.bin/openssl/man/rand.1
index a7929ed..279bc04 100644
--- a/secure/usr.bin/openssl/man/rand.1
+++ b/secure/usr.bin/openssl/man/rand.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RAND 1"
-.TH RAND 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RAND 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
rand \- generate pseudo\-random bytes
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/req.1 b/secure/usr.bin/openssl/man/req.1
index 7476a97..e8b1f83 100644
--- a/secure/usr.bin/openssl/man/req.1
+++ b/secure/usr.bin/openssl/man/req.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "REQ 1"
-.TH REQ 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH REQ 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
req \- PKCS#10 certificate request and certificate generating utility.
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/rsa.1 b/secure/usr.bin/openssl/man/rsa.1
index 1b3ee49..03ed5aa 100644
--- a/secure/usr.bin/openssl/man/rsa.1
+++ b/secure/usr.bin/openssl/man/rsa.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSA 1"
-.TH RSA 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSA 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
rsa \- RSA key processing tool
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/rsautl.1 b/secure/usr.bin/openssl/man/rsautl.1
index ab83550..f4ae4db 100644
--- a/secure/usr.bin/openssl/man/rsautl.1
+++ b/secure/usr.bin/openssl/man/rsautl.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "RSAUTL 1"
-.TH RSAUTL 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH RSAUTL 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
rsautl \- RSA utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/s_client.1 b/secure/usr.bin/openssl/man/s_client.1
index 9885d95..ff2b640 100644
--- a/secure/usr.bin/openssl/man/s_client.1
+++ b/secure/usr.bin/openssl/man/s_client.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "S_CLIENT 1"
-.TH S_CLIENT 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH S_CLIENT 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
s_client \- SSL/TLS client program
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/s_server.1 b/secure/usr.bin/openssl/man/s_server.1
index 27400a0..467f7b0 100644
--- a/secure/usr.bin/openssl/man/s_server.1
+++ b/secure/usr.bin/openssl/man/s_server.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "S_SERVER 1"
-.TH S_SERVER 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH S_SERVER 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
s_server \- SSL/TLS server program
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/s_time.1 b/secure/usr.bin/openssl/man/s_time.1
index daa6c77..9642134 100644
--- a/secure/usr.bin/openssl/man/s_time.1
+++ b/secure/usr.bin/openssl/man/s_time.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "S_TIME 1"
-.TH S_TIME 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH S_TIME 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
s_time \- SSL/TLS performance timing program
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/sess_id.1 b/secure/usr.bin/openssl/man/sess_id.1
index d692006..134cdb2 100644
--- a/secure/usr.bin/openssl/man/sess_id.1
+++ b/secure/usr.bin/openssl/man/sess_id.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SESS_ID 1"
-.TH SESS_ID 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SESS_ID 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
sess_id \- SSL/TLS session handling utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/smime.1 b/secure/usr.bin/openssl/man/smime.1
index eb062ac..a10fdfe 100644
--- a/secure/usr.bin/openssl/man/smime.1
+++ b/secure/usr.bin/openssl/man/smime.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SMIME 1"
-.TH SMIME 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SMIME 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
smime \- S/MIME utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/speed.1 b/secure/usr.bin/openssl/man/speed.1
index 1d7b117..5b0b299 100644
--- a/secure/usr.bin/openssl/man/speed.1
+++ b/secure/usr.bin/openssl/man/speed.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SPEED 1"
-.TH SPEED 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SPEED 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
speed \- test library performance
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/spkac.1 b/secure/usr.bin/openssl/man/spkac.1
index 5ca95aa..1d749b4 100644
--- a/secure/usr.bin/openssl/man/spkac.1
+++ b/secure/usr.bin/openssl/man/spkac.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "SPKAC 1"
-.TH SPKAC 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH SPKAC 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
spkac \- SPKAC printing and generating utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/verify.1 b/secure/usr.bin/openssl/man/verify.1
index 93bd934..51bb25d 100644
--- a/secure/usr.bin/openssl/man/verify.1
+++ b/secure/usr.bin/openssl/man/verify.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "VERIFY 1"
-.TH VERIFY 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH VERIFY 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
verify \- Utility to verify certificates.
.SH "SYNOPSIS"
@@ -182,6 +182,10 @@ of the current certificate. This shows why each candidate issuer
certificate was rejected. However the presence of rejection messages
does not itself imply that anything is wrong: during the normal
verify process several rejections may take place.
+.IP "\fB\-check_ss_sig\fR" 4
+.IX Item "-check_ss_sig"
+Verify the signature on the self-signed root \s-1CA\s0. This is disabled by default
+because it doesn't add any security.
.IP "\fB\-\fR" 4
.IX Item "-"
marks the last option. All arguments following this are assumed to be
@@ -274,8 +278,8 @@ as \*(L"unused\*(R".
the operation was successful.
.IP "\fB2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate\fR" 4
.IX Item "2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate"
-the issuer certificate could not be found: this occurs if the issuer certificate
-of an untrusted certificate cannot be found.
+the issuer certificate of a looked up certificate could not be found. This
+normally means the list of trusted certificates is not complete.
.IP "\fB3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate \s-1CRL\s0\fR" 4
.IX Item "3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL"
the \s-1CRL\s0 of a certificate could not be found. Unused.
@@ -334,8 +338,8 @@ the certificate chain could be built up using the untrusted certificates but the
be found locally.
.IP "\fB20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate\fR" 4
.IX Item "20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate"
-the issuer certificate of a locally looked up certificate could not be found. This normally means
-the list of trusted certificates is not complete.
+the issuer certificate could not be found: this occurs if the issuer
+certificate of an untrusted certificate cannot be found.
.IP "\fB21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate\fR" 4
.IX Item "21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate"
no signatures could be verified because the chain contains only one certificate and it is not
@@ -394,6 +398,10 @@ the certificates in the file will be recognised.
.PP
Previous versions of OpenSSL assume certificates with matching subject name are identical and
mishandled them.
+.PP
+Previous versions of this documentation swapped the meaning of the
+\&\fBX509_V_ERR_UNABLE_TO_GET_ISSUER_CERT\fR and
+\&\fB20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY\fR error codes.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fIx509\fR\|(1)
diff --git a/secure/usr.bin/openssl/man/version.1 b/secure/usr.bin/openssl/man/version.1
index 49dcfd8..a4ca356 100644
--- a/secure/usr.bin/openssl/man/version.1
+++ b/secure/usr.bin/openssl/man/version.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "VERSION 1"
-.TH VERSION 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH VERSION 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
version \- print OpenSSL version information
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/x509.1 b/secure/usr.bin/openssl/man/x509.1
index 4e35ff0..3238a83 100644
--- a/secure/usr.bin/openssl/man/x509.1
+++ b/secure/usr.bin/openssl/man/x509.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509 1"
-.TH X509 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
x509 \- Certificate display and signing utility
.SH "SYNOPSIS"
diff --git a/secure/usr.bin/openssl/man/x509v3_config.1 b/secure/usr.bin/openssl/man/x509v3_config.1
index b94a3d7..20705e7 100644
--- a/secure/usr.bin/openssl/man/x509v3_config.1
+++ b/secure/usr.bin/openssl/man/x509v3_config.1
@@ -129,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "X509V3_CONFIG 1"
-.TH X509V3_CONFIG 1 "2009-06-14" "0.9.8k" "OpenSSL"
+.TH X509V3_CONFIG 1 "2010-03-24" "0.9.8n" "OpenSSL"
.SH "NAME"
x509v3_config \- X509 V3 certificate extension configuration format
.SH "DESCRIPTION"
diff --git a/secure/usr.bin/ssh/Makefile b/secure/usr.bin/ssh/Makefile
index 6944ac5..f85784e 100644
--- a/secure/usr.bin/ssh/Makefile
+++ b/secure/usr.bin/ssh/Makefile
@@ -11,7 +11,7 @@ MLINKS= ssh.1 slogin.1
SRCS= ssh.c readconf.c clientloop.c sshtty.c \
sshconnect.c sshconnect1.c sshconnect2.c mux.c \
- roaming_common.c
+ roaming_common.c roaming_client.c
# gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile
SRCS+= gss-genr.c
diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile
index d7a37a3..b0b8bb7 100644
--- a/secure/usr.sbin/sshd/Makefile
+++ b/secure/usr.sbin/sshd/Makefile
@@ -15,7 +15,7 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
auth2-gss.c gss-serv.c gss-serv-krb5.c \
loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \
audit.c audit-bsm.c platform.c sftp-server.c sftp-common.c \
- roaming_common.c
+ roaming_common.c roaming_serv.c
# gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile
SRCS+= gss-genr.c
diff --git a/share/dict/web2 b/share/dict/web2
index c25589d..16924e0 100644
--- a/share/dict/web2
+++ b/share/dict/web2
@@ -112025,6 +112025,7 @@ masquerader
Mass
mass
massa
+Massachusetts
massacre
massacrer
massage
diff --git a/share/examples/Makefile b/share/examples/Makefile
index 99d92c0..7d011e3 100644
--- a/share/examples/Makefile
+++ b/share/examples/Makefile
@@ -15,6 +15,7 @@ LDIRS= BSD_daemon \
find_interface \
hast \
ibcs2 \
+ indent \
ipfw \
kld \
libvgl \
@@ -77,6 +78,7 @@ XFILES= BSD_daemon/FreeBSD.pfa \
hast/vip-up.sh \
ibcs2/README \
ibcs2/hello.uu \
+ indent/indent.pro \
ipfw/change_rules.sh \
kld/Makefile \
kld/cdev/Makefile \
diff --git a/share/examples/autofs/driver/Makefile b/share/examples/autofs/driver/Makefile
index 7a0f159..d577668 100644
--- a/share/examples/autofs/driver/Makefile
+++ b/share/examples/autofs/driver/Makefile
@@ -1,11 +1,11 @@
# $Id: Makefile,v 1.5 2004/09/08 08:27:12 bright Exp $
# $FreeBSD$
-PROG=autodriver
+PROG= autodriver
+NO_MAN=
SRCS= autodriver.c
-NO_MAN=
-WARNS= 4
+WARNS?= 4
CFLAGS+= -g
BINDIR?= /sbin
diff --git a/share/examples/indent/indent.pro b/share/examples/indent/indent.pro
new file mode 100644
index 0000000..c85bfda
--- /dev/null
+++ b/share/examples/indent/indent.pro
@@ -0,0 +1,46 @@
+-TFILE
+-Tfd_mask
+-Tfd_set
+-Tlinker_sym_tT
+-Tu_char
+-Tu_int
+-Tu_long
+-Tu_short
+-TTAILQ_HEAD
+-TTAILQ_ENTRY
+-TLIST_HEAD
+-TLIST_ENTRY
+-TSTAILQ_HEAD
+-TSTAILQ_ENTRY
+-TSLIST_HEAD
+-TSLIST_ENTRY
+-bad
+-bap
+-nbbb
+-nbc
+-br
+-nbs
+-c41
+-cd41
+-cdb
+-ce
+-ci4
+-cli0
+-d0
+-di8
+-ndj
+-ei
+-nfc1
+-nfcb
+-i8
+-ip8
+-l79
+-lc77
+-ldi0
+-nlp
+-npcs
+-psl
+-sc
+-nsob
+-ta
+-nv
diff --git a/share/man/man1/builtin.1 b/share/man/man1/builtin.1
index 0a93c21..3f2dc17 100644
--- a/share/man/man1/builtin.1
+++ b/share/man/man1/builtin.1
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 14, 2006
+.Dd April 25, 2010
.Dt BUILTIN 1
.Os
.Sh NAME
@@ -36,6 +36,7 @@
.Nm \&. ,
.Nm \&: ,
.Nm @ ,
+.Nm \&[ ,
.Nm { ,
.Nm } ,
.Nm alias ,
@@ -195,11 +196,12 @@ but are implemented as scripts using a builtin command of the same name.
.It Xo
.Em "Command External" Ta Xr csh 1 Ta Xr sh 1
.Xc
-.It Ic ! Ta \&No Ta \&No Ta Yes
+.It Ic \&! Ta \&No Ta \&No Ta Yes
.It Ic % Ta \&No Ta Yes Ta \&No
-.It Ic . Ta \&No Ta \&No Ta Yes
-.It Ic : Ta \&No Ta Yes Ta Yes
+.It Ic \&. Ta \&No Ta \&No Ta Yes
+.It Ic \&: Ta \&No Ta Yes Ta Yes
.It Ic @ Ta \&No Ta Yes Ta Yes
+.It Ic \&[ Ta Yes Ta \&No Ta Yes
.It Ic { Ta \&No Ta \&No Ta Yes
.It Ic } Ta \&No Ta \&No Ta Yes
.It Ic alias Ta No** Ta Yes Ta Yes
@@ -243,7 +245,7 @@ but are implemented as scripts using a builtin command of the same name.
.It Ic getopts Ta No** Ta \&No Ta Yes
.It Ic glob Ta \&No Ta Yes Ta \&No
.It Ic goto Ta \&No Ta Yes Ta \&No
-.It Ic hash Ta \&No Ta \&No Ta Yes
+.It Ic hash Ta No** Ta \&No Ta Yes
.It Ic hashstat Ta \&No Ta Yes Ta \&No
.It Ic history Ta \&No Ta Yes Ta \&No
.It Ic hup Ta \&No Ta Yes Ta \&No
@@ -288,8 +290,8 @@ but are implemented as scripts using a builtin command of the same name.
.It Ic times Ta \&No Ta \&No Ta Yes
.It Ic trap Ta \&No Ta \&No Ta Yes
.It Ic true Ta Yes Ta \&No Ta Yes
-.It Ic type Ta \&No Ta \&No Ta Yes
-.It Ic ulimit Ta \&No Ta \&No Ta Yes
+.It Ic type Ta No** Ta \&No Ta Yes
+.It Ic ulimit Ta No** Ta \&No Ta Yes
.It Ic umask Ta No** Ta Yes Ta Yes
.It Ic unalias Ta No** Ta Yes Ta Yes
.It Ic uncomplete Ta \&No Ta Yes Ta \&No
diff --git a/share/man/man3/pthread_affinity_np.3 b/share/man/man3/pthread_affinity_np.3
index a04ba97..95128c8 100644
--- a/share/man/man3/pthread_affinity_np.3
+++ b/share/man/man3/pthread_affinity_np.3
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 12, 2010
+.Dd March 23, 2010
.Dt PTHREAD_AFFINITY_NP 3
.Os
.Sh NAME
@@ -125,8 +125,8 @@ operation.
.Xr cpuset_setid 2 ,
.Xr CPU_SET 3 ,
.Xr pthread 3 ,
-.Xr pthread_attr_get_affinity_np 3 ,
-.Xr pthread_attr_set_affinity_np 3
+.Xr pthread_attr_getaffinity_np 3 ,
+.Xr pthread_attr_setaffinity_np 3
.Sh STANDARDS
The
.Nm pthread_getaffinity_np
diff --git a/share/man/man3/sysexits.3 b/share/man/man3/sysexits.3
index 4661c9d..2ef3407 100644
--- a/share/man/man3/sysexits.3
+++ b/share/man/man3/sysexits.3
@@ -27,8 +27,8 @@
.\"
.\" "
.Dd March 31, 1996
-.Os
.Dt SYSEXITS 3
+.Os
.Sh NAME
.Nm sysexits
.Nd preferable exit codes for programs
diff --git a/share/man/man3/tgmath.3 b/share/man/man3/tgmath.3
index 4957c9b..f8faf26 100644
--- a/share/man/man3/tgmath.3
+++ b/share/man/man3/tgmath.3
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd August 14, 2004
-.Os
.Dt TGMATH 3
+.Os
.Sh NAME
.Nm tgmath
.Nd "type-generic macros"
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 4c49984..c71a097 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -350,6 +350,7 @@ MAN= aac.4 \
sem.4 \
ses.4 \
sf.4 \
+ sge.4 \
si.4 \
siba.4 \
sio.4 \
diff --git a/share/man/man4/acpi.4 b/share/man/man4/acpi.4
index a1fef87..69c1837 100644
--- a/share/man/man4/acpi.4
+++ b/share/man/man4/acpi.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 8, 2009
+.Dd March 9, 2010
.Dt ACPI 4
.Os
.Sh NAME
@@ -62,6 +62,10 @@ used to modify or monitor
.Nm
behavior.
.Bl -tag -width indent
+.It Va debug.acpi.enable_debug_objects
+Enable dumping Debug objects without
+.Cd "options ACPI_DEBUG" .
+Default is 0, ignore Debug objects.
.It Va hw.acpi.acline
AC line state (1 means online, 0 means on battery power).
.It Va hw.acpi.cpu.cx_usage
@@ -197,6 +201,9 @@ Enables loading of a custom ACPI DSDT.
Name of the DSDT table to load, if loading is enabled.
.It Va debug.acpi.disabled
Selectively disables portions of ACPI for debugging purposes.
+.It Va debug.acpi.interpreter_slack
+Enable less strict ACPI implementations.
+Default is 1, ignore common BIOS mistakes.
.It Va debug.acpi.max_threads
Specify the number of task threads that are started on boot.
Limiting this to 1 may help work around various BIOSes that cannot
diff --git a/share/man/man4/acpi_wmi.4 b/share/man/man4/acpi_wmi.4
index cc61527..6d93ff9 100644
--- a/share/man/man4/acpi_wmi.4
+++ b/share/man/man4/acpi_wmi.4
@@ -57,7 +57,7 @@ information about GUIDs found in the system.
WMI status device.
.El
.Sh EXAMPLES
-.Bd Literal
+.Bd -literal
# cat /dev/wmistat
GUID INST EXPE METH STR EVENT OID
{5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA
diff --git a/share/man/man4/ada.4 b/share/man/man4/ada.4
index 65cd53f..cba892b 100644
--- a/share/man/man4/ada.4
+++ b/share/man/man4/ada.4
@@ -127,6 +127,7 @@ ATA device nodes
.Sh SEE ALSO
.Xr ad 4 ,
.Xr ahci 4 ,
+.Xr cam 4 ,
.Xr da 4 ,
.Xr siis 4
.Sh HISTORY
diff --git a/share/man/man4/ahci.4 b/share/man/man4/ahci.4
index 675bab6..e279963 100644
--- a/share/man/man4/ahci.4
+++ b/share/man/man4/ahci.4
@@ -139,10 +139,10 @@ such as JMicron JMB36x and Marvell 88SX61xx.
.Sh SEE ALSO
.Xr ada 4 ,
.Xr ata 4 ,
+.Xr cam 4 ,
.Xr cd 4 ,
.Xr da 4 ,
-.Xr sa 4 ,
-.Xr scsi 4
+.Xr sa 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/altq.4 b/share/man/man4/altq.4
index 55fb8c1..a618c96 100644
--- a/share/man/man4/altq.4
+++ b/share/man/man4/altq.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 26, 2009
+.Dd April 14, 2010
.Dt ALTQ 4
.Os
.Sh NAME
@@ -121,7 +121,7 @@ They have been applied to the following hardware drivers:
.Xr an 4 ,
.Xr ath 4 ,
.Xr aue 4 ,
-.Xt axe 4 ,
+.Xr axe 4 ,
.Xr bce 4 ,
.Xr bfe 4 ,
.Xr bge 4 ,
@@ -151,6 +151,7 @@ They have been applied to the following hardware drivers:
.Xr rl 4 ,
.Xr rum 4 ,
.Xr sf 4 ,
+.Xr sge 4 ,
.Xr sis 4 ,
.Xr sk 4 ,
.Xr ste 4 ,
diff --git a/share/man/man4/amdtemp.4 b/share/man/man4/amdtemp.4
index fb6fc77..6d1ca7c 100644
--- a/share/man/man4/amdtemp.4
+++ b/share/man/man4/amdtemp.4
@@ -75,6 +75,5 @@ The
driver first appeared in
.Fx 7.1 .
.Sh AUTHORS
-.An
.An Rui Paulo Aq rpaulo@FreeBSD.org
.An Norikatsu Shigemura Aq nork@FreeBSD.org
diff --git a/share/man/man4/ata.4 b/share/man/man4/ata.4
index 303e632..3e5c5c1 100644
--- a/share/man/man4/ata.4
+++ b/share/man/man4/ata.4
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 23, 2009
+.Dd March 3, 2010
.Dt ATA 4
.Os
.Sh NAME
@@ -81,6 +81,13 @@ To support ATAPI floppy drives:
To support ATAPI tape drives:
.Cd device atapist
.Pp
+To turn
+.Xr ata 4
+subsystem controller drivers into cam(4) interface modules (disables all native
+.Xr ata 4
+APIs and periperal drivers):
+.Cd options ATA_CAM
+.Pp
The following tunables are settable from the loader:
.Bl -ohang
.It Va hw.ata.ata_dma
@@ -125,7 +132,7 @@ The currently supported ATA/SATA controller chips are:
.It Acard:
ATP850P, ATP860A, ATP860R, ATP865A, ATP865R.
.It ALI:
-M5229, M5281, M5287, M5288, M5289.
+M5228, M5229, M5281, M5283, M5287, M5288, M5289.
.It AMD:
AMD756, AMD766, AMD768, AMD8111, CS5536.
.It ATI:
@@ -139,7 +146,8 @@ Cyrix 5530.
.It HighPoint:
HPT302, HPT366, HPT368, HPT370, HPT371, HPT372, HPT372N, HPT374.
.It Intel:
-6300ESB, 31244, PIIX, PIIX3, PIIX4, ESB2, ICH, ICH0, ICH2, ICH3, ICH4, ICH5, ICH6, ICH7, ICH8, ICH9, ICH10.
+6300ESB, 31244, PIIX, PIIX3, PIIX4, ESB2, ICH, ICH0, ICH2, ICH3, ICH4, ICH5,
+ICH6, ICH7, ICH8, ICH9, ICH10, SCH, PCH.
.It ITE:
IT8211F, IT8212F, IT8213F.
.It JMicron:
@@ -163,7 +171,9 @@ SiI0680, SiI3112, SiI3114, SiI3124, SiI3132, SiI3512.
.It SiS:
SIS180, SIS181, SIS182, SIS5513, SIS530, SIS540, SIS550, SIS620, SIS630, SIS630S, SIS633, SIS635, SIS730, SIS733, SIS735, SIS745, SIS961, SIS962, SIS963, SIS964, SIS965.
.It VIA:
-VT6410, VT6420, VT6421, VT82C586, VT82C586B, VT82C596, VT82C596B, VT82C686, VT82C686A, VT82C686B, VT8231, VT8233, VT8233A, VT8233C, VT8235, VT8237, VT8237A, VT8237S, VT8251.
+VT6410, VT6420, VT6421, VT82C586, VT82C586B, VT82C596, VT82C596B, VT82C686,
+VT82C686A, VT82C686B, VT8231, VT8233, VT8233A, VT8233C, VT8235, VT8237,
+VT8237A, VT8237S, VT8251, CX700, VX800, VX855.
.El
.Pp
Unknown ATA chipsets are supported in PIO modes, and if the standard
@@ -246,9 +256,12 @@ and not depend on attach order.
.Pp
Native Command Queuing (NCQ) on SATA drives is not yet supported.
.Sh SEE ALSO
+.Xr ahci 4 ,
+.Xr cam 4 ,
.Xr ataraid 4 ,
.Xr atacontrol 8 ,
-.Xr burncd 8
+.Xr burncd 8 ,
+.Xr siis 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/ath.4 b/share/man/man4/ath.4
index c2344cb..6905166 100644
--- a/share/man/man4/ath.4
+++ b/share/man/man4/ath.4
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"/
-.Dd July 8, 2009
+.Dd March 21, 2010
.Dt ATH 4
.Os
.Sh NAME
@@ -145,15 +145,6 @@ except those that are based on the AR5005VL chipset.
A list of cards that are supported can be found at
.Pa http://customerproducts.atheros.com/customerproducts/default.asp .
.Sh EXAMPLES
-Join an existing BSS network (ie: connect to an access point):
-.Pp
-.Dl "ifconfig ath0 inet 192.168.0.20 netmask 0xffffff00"
-.Pp
-Join a specific BSS network with network name
-.Dq Li my_net :
-.Pp
-.Dl "ifconfig ath0 inet 192.168.0.20 netmask 0xffffff00 ssid my_net"
-.Pp
Join a specific BSS network with WEP encryption:
.Bd -literal -offset indent
ifconfig wlan0 create wlandev ath0
diff --git a/share/man/man4/audit.4 b/share/man/man4/audit.4
index 82bb23f..167248c 100644
--- a/share/man/man4/audit.4
+++ b/share/man/man4/audit.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd May 31, 2009
-.Os
.Dt AUDIT 4
+.Os
.Sh NAME
.Nm audit
.Nd Security Event Audit
diff --git a/share/man/man4/auditpipe.4 b/share/man/man4/auditpipe.4
index 7ba35af..19db856 100644
--- a/share/man/man4/auditpipe.4
+++ b/share/man/man4/auditpipe.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd May 5, 2006
-.Os
.Dt AUDITPIPE 4
+.Os
.Sh NAME
.Nm auditpipe
.Nd "pseudo-device for live audit event tracking"
diff --git a/share/man/man4/cd.4 b/share/man/man4/cd.4
index ec16751..ed88535 100644
--- a/share/man/man4/cd.4
+++ b/share/man/man4/cd.4
@@ -496,8 +496,8 @@ devices
.Sh DIAGNOSTICS
None.
.Sh SEE ALSO
+.Xr cam 4 ,
.Xr da 4 ,
-.Xr scsi 4 ,
.Xr disklabel 5 ,
.Xr disklabel 8 ,
.Xr cd 9
diff --git a/share/man/man4/ch.4 b/share/man/man4/ch.4
index 03e293a..6bd2df4 100644
--- a/share/man/man4/ch.4
+++ b/share/man/man4/ch.4
@@ -325,6 +325,7 @@ If the media changer does not support features requested by the
driver, it will produce both console error messages and failure return
codes to the ioctls described here.
.Sh SEE ALSO
+.Xr cam 4 ,
.Xr chio 1 ,
.Xr cd 4 ,
.Xr da 4 ,
diff --git a/share/man/man4/coda.4 b/share/man/man4/coda.4
index 9fd6cbb..94b12ae 100644
--- a/share/man/man4/coda.4
+++ b/share/man/man4/coda.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 21, 2008
-.Os
.Dt CODA 4
+.Os
.Sh NAME
.Nm coda
.Nd Coda Distributed File System
diff --git a/share/man/man4/cxgb.4 b/share/man/man4/cxgb.4
index 155df38..97f72b5 100644
--- a/share/man/man4/cxgb.4
+++ b/share/man/man4/cxgb.4
@@ -92,8 +92,6 @@ Tunables can be set at the
.Xr loader 8
prompt before booting the kernel or stored in
.Xr loader.conf 5 .
-.Bl -tag -width indent
-.El
.Sh DIAGNOSTICS
.Bl -diag
.It "cxgb%d: Unable to allocate bus resource: memory"
diff --git a/share/man/man4/da.4 b/share/man/man4/da.4
index 2ba8096..cf56934 100644
--- a/share/man/man4/da.4
+++ b/share/man/man4/da.4
@@ -196,6 +196,7 @@ SCSI disk device nodes
None.
.Sh SEE ALSO
.Xr ad 4 ,
+.Xr cam 4 ,
.Xr geom 4 ,
.Xr bsdlabel 8 ,
.Xr fdisk 8
diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4
index 89bfcc4..6f7412e 100644
--- a/share/man/man4/ddb.4
+++ b/share/man/man4/ddb.4
@@ -697,7 +697,7 @@ Show information from the local APIC registers for this CPU.
.It Ic show Cm lock Ar addr
Show lock structure.
The output format is as follows:
-.Bl -tag -offset 0 -width "flags"
+.Bl -tag -width "flags"
.It Ic class:
Class of the lock.
Possible types include
diff --git a/share/man/man4/ehci.4 b/share/man/man4/ehci.4
index 57d47db..f849ed3 100644
--- a/share/man/man4/ehci.4
+++ b/share/man/man4/ehci.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/gbde.4 b/share/man/man4/gbde.4
index e3bc6c7..edac1a0 100644
--- a/share/man/man4/gbde.4
+++ b/share/man/man4/gbde.4
@@ -32,8 +32,8 @@
.\" $FreeBSD$
.\"
.Dd October 19, 2002
-.Os
.Dt GBDE 4
+.Os
.Sh NAME
.Nm gbde
.Nd Geom Based Disk Encryption
diff --git a/share/man/man4/gem.4 b/share/man/man4/gem.4
index 314d95f..3a3f081 100644
--- a/share/man/man4/gem.4
+++ b/share/man/man4/gem.4
@@ -11,13 +11,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4
index 3857389..0a1b24e 100644
--- a/share/man/man4/geom.4
+++ b/share/man/man4/geom.4
@@ -35,8 +35,8 @@
.\" $FreeBSD$
.\"
.Dd May 25, 2006
-.Os
.Dt GEOM 4
+.Os
.Sh NAME
.Nm GEOM
.Nd "modular disk I/O request transformation framework"
diff --git a/share/man/man4/geom_fox.4 b/share/man/man4/geom_fox.4
index 588e1d7..8e262b9 100644
--- a/share/man/man4/geom_fox.4
+++ b/share/man/man4/geom_fox.4
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd January 2, 2005
-.Os
.Dt GEOM_FOX 4
+.Os
.Sh NAME
.Nm geom_fox
.Nd "GEOM based basic disk multipathing"
diff --git a/share/man/man4/geom_linux_lvm.4 b/share/man/man4/geom_linux_lvm.4
index e41703a4..30b875e 100644
--- a/share/man/man4/geom_linux_lvm.4
+++ b/share/man/man4/geom_linux_lvm.4
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd February 20, 2008
-.Os
.Dt GEOM_LINUX_LVM 4
+.Os
.Sh NAME
.Nm geom_linux_lvm
.Nd "GEOM based Linux LVM logical volume mapping"
diff --git a/share/man/man4/geom_uzip.4 b/share/man/man4/geom_uzip.4
index 30d5ab0..7275029 100644
--- a/share/man/man4/geom_uzip.4
+++ b/share/man/man4/geom_uzip.4
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd October 9, 2006
-.Os
.Dt GEOM_UZIP 4
+.Os
.Sh NAME
.Nm geom_uzip
.Nd "GEOM based compressed disk images"
diff --git a/share/man/man4/gre.4 b/share/man/man4/gre.4
index 9052eea..60bdbfb 100644
--- a/share/man/man4/gre.4
+++ b/share/man/man4/gre.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of the The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/hme.4 b/share/man/man4/hme.4
index 47a27c9..2bdc72a 100644
--- a/share/man/man4/hme.4
+++ b/share/man/man4/hme.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/ipw.4 b/share/man/man4/ipw.4
index 30293f0..060058a 100644
--- a/share/man/man4/ipw.4
+++ b/share/man/man4/ipw.4
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd April 13, 2008
-.Os
.Dt IPW 4
+.Os
.Sh NAME
.Nm ipw
.Nd "Intel PRO/Wireless 2100 IEEE 802.11 driver"
diff --git a/share/man/man4/iscsi_initiator.4 b/share/man/man4/iscsi_initiator.4
index 1697b2f..b6c47f0 100644
--- a/share/man/man4/iscsi_initiator.4
+++ b/share/man/man4/iscsi_initiator.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd February 23, 2007
-.Os
.Dt ISCSI_INITIATOR 4
+.Os
.Sh NAME
.Nm iscsi_initiator
.Nd kernel driver for the iSCSI protocol
@@ -73,7 +73,7 @@ is the IP address of the target of session
.Em n .
.It Va net.iscsi.n.stats
are some statistics for session
-.EM n
+.Em n
.It Va net.iscsi.n.pid
is the
.Em "process id"
diff --git a/share/man/man4/iwi.4 b/share/man/man4/iwi.4
index 3c9bdd4..64f5c0ed 100644
--- a/share/man/man4/iwi.4
+++ b/share/man/man4/iwi.4
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd April 13, 2008
-.Os
.Dt IWI 4
+.Os
.Sh NAME
.Nm iwi
.Nd "Intel PRO/Wireless 2200BG/2225BG/2915ABG IEEE 802.11 driver"
diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4
index b73331a..a229e57 100644
--- a/share/man/man4/iwn.4
+++ b/share/man/man4/iwn.4
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd February 8, 2010
-.Os
.Dt IWN 4
+.Os
.Sh NAME
.Nm iwn
.Nd Intel Wireless WiFi Link 4965/1000/5000/5150/5300/6000/6050
diff --git a/share/man/man4/kbdmux.4 b/share/man/man4/kbdmux.4
index e29f8cd..f92fa45 100644
--- a/share/man/man4/kbdmux.4
+++ b/share/man/man4/kbdmux.4
@@ -2,8 +2,8 @@
.\" $FreeBSD$
.\"
.Dd July 12, 2005
-.Os
.Dt KBDMUX 4
+.Os
.Sh NAME
.Nm kbdmux
.Nd "keyboard multiplexer"
diff --git a/share/man/man4/ktr.4 b/share/man/man4/ktr.4
index 89f5305..7da4e37 100644
--- a/share/man/man4/ktr.4
+++ b/share/man/man4/ktr.4
@@ -122,7 +122,7 @@ option sets the flag to one.
The KTR buffer can be examined from within
.Xr ddb 4
via the
-.Ic show ktr Op Cm /v
+.Ic show ktr Op Cm /vV
command.
This command displays the contents of the trace buffer one page at a time.
At the
@@ -136,6 +136,10 @@ If the
.Cm /v
modifier is specified, then they are displayed in addition to the normal
output.
+If the
+.Cm /V
+modifier is specified, then just the timestamp is displayed in
+addition to the normal output.
Note that the events are displayed in reverse chronological order.
That is, the most recent events are displayed first.
.Ss Logging ktr to Disk
@@ -167,7 +171,9 @@ the next invocation.
enables logging of
.Nm
entries to disk if it is set to one.
-Setting this to 0 will terminate logging.
+Setting this to 0 will terminate logging to disk and revert to
+logging to the normal ktr ring buffer.
+Data is not sent to the ring buffer while logging to disk.
.It Va debug.ktr.alq_max
is the maximum number of entries that will be recorded to disk, or 0 for
infinite.
diff --git a/share/man/man4/lp.4 b/share/man/man4/lp.4
index 6976101..f5b628e 100644
--- a/share/man/man4/lp.4
+++ b/share/man/man4/lp.4
@@ -35,8 +35,8 @@
.\" $FreeBSD$
.\"
.Dd March 4, 1996
-.Os
.Dt LP 4
+.Os
.Sh NAME
.Nm lp
.Nd printer port Internet Protocol driver
diff --git a/share/man/man4/mac.4 b/share/man/man4/mac.4
index 82d7a16..b1ff1d9 100644
--- a/share/man/man4/mac.4
+++ b/share/man/man4/mac.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd October 30, 2007
-.Os
.Dt MAC 4
+.Os
.Sh NAME
.Nm mac
.Nd Mandatory Access Control
diff --git a/share/man/man4/mac_biba.4 b/share/man/man4/mac_biba.4
index 20a6661..265f571 100644
--- a/share/man/man4/mac_biba.4
+++ b/share/man/man4/mac_biba.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd November 18, 2002
-.Os
.Dt MAC_BIBA 4
+.Os
.Sh NAME
.Nm mac_biba
.Nd "Biba data integrity policy"
diff --git a/share/man/man4/mac_bsdextended.4 b/share/man/man4/mac_bsdextended.4
index 899990c..23b89c0 100644
--- a/share/man/man4/mac_bsdextended.4
+++ b/share/man/man4/mac_bsdextended.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd May 21, 2005
-.Os
.Dt MAC_BSDEXTENDED 4
+.Os
.Sh NAME
.Nm mac_bsdextended
.Nd "file system firewall policy"
diff --git a/share/man/man4/mac_ifoff.4 b/share/man/man4/mac_ifoff.4
index ede13b0..87c73b2 100644
--- a/share/man/man4/mac_ifoff.4
+++ b/share/man/man4/mac_ifoff.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 10, 2002
-.Os
.Dt MAC_IFOFF 4
+.Os
.Sh NAME
.Nm mac_ifoff
.Nd "interface silencing policy"
diff --git a/share/man/man4/mac_lomac.4 b/share/man/man4/mac_lomac.4
index 8133ad8..8ae8875 100644
--- a/share/man/man4/mac_lomac.4
+++ b/share/man/man4/mac_lomac.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 11, 2002
-.Os
.Dt MAC_LOMAC 4
+.Os
.Sh NAME
.Nm mac_lomac
.Nd "Low-watermark Mandatory Access Control data integrity policy"
diff --git a/share/man/man4/mac_mls.4 b/share/man/man4/mac_mls.4
index 921781a..b314fb5 100644
--- a/share/man/man4/mac_mls.4
+++ b/share/man/man4/mac_mls.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 1, 2002
-.Os
.Dt MAC_MLS 4
+.Os
.Sh NAME
.Nm mac_mls
.Nd "Multi-Level Security confidentiality policy"
diff --git a/share/man/man4/mac_none.4 b/share/man/man4/mac_none.4
index 159151e..8f46029 100644
--- a/share/man/man4/mac_none.4
+++ b/share/man/man4/mac_none.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 1, 2002
-.Os
.Dt MAC_NONE 4
+.Os
.Sh NAME
.Nm mac_none
.Nd "null MAC policy module"
diff --git a/share/man/man4/mac_partition.4 b/share/man/man4/mac_partition.4
index 54abee5..296635e 100644
--- a/share/man/man4/mac_partition.4
+++ b/share/man/man4/mac_partition.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 9, 2002
-.Os
.Dt MAC_PARTITION 4
+.Os
.Sh NAME
.Nm mac_partition
.Nd "process partition policy"
diff --git a/share/man/man4/mac_seeotheruids.4 b/share/man/man4/mac_seeotheruids.4
index 4eeb7bb..c870ca0 100644
--- a/share/man/man4/mac_seeotheruids.4
+++ b/share/man/man4/mac_seeotheruids.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd October 6, 2005
-.Os
.Dt MAC_SEEOTHERUIDS 4
+.Os
.Sh NAME
.Nm mac_seeotheruids
.Nd "simple policy controlling whether users see other users"
diff --git a/share/man/man4/mac_stub.4 b/share/man/man4/mac_stub.4
index ded95e2..79326df 100644
--- a/share/man/man4/mac_stub.4
+++ b/share/man/man4/mac_stub.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 1, 2002
-.Os
.Dt MAC_STUB 4
+.Os
.Sh NAME
.Nm mac_stub
.Nd "MAC policy stub module"
diff --git a/share/man/man4/mac_test.4 b/share/man/man4/mac_test.4
index dde7445..e86d4bd 100644
--- a/share/man/man4/mac_test.4
+++ b/share/man/man4/mac_test.4
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd December 1, 2002
-.Os
.Dt MAC_TEST 4
+.Os
.Sh NAME
.Nm mac_test
.Nd MAC framework testing policy
diff --git a/share/man/man4/man4.sparc64/sbus.4 b/share/man/man4/man4.sparc64/sbus.4
index d85c85c..7955727 100644
--- a/share/man/man4/man4.sparc64/sbus.4
+++ b/share/man/man4/man4.sparc64/sbus.4
@@ -13,13 +13,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/miibus.4 b/share/man/man4/miibus.4
index ec93967..5a38595 100644
--- a/share/man/man4/miibus.4
+++ b/share/man/man4/miibus.4
@@ -8,7 +8,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 14, 2009
+.Dd April 14, 2010
.Dt MIIBUS 4
.Os
.Sh NAME
@@ -97,6 +97,8 @@ RealTek 8129/8139
RealTek RTL8150 USB To Fast Ethernet
.It Xr sf 4
Adaptec AIC-6915
+.It Xr sge 4
+Silicon Integrated Systems SiS190/191 Ethernet
.It Xr sis 4
Silicon Integrated Systems SiS 900/SiS 7016
.It Xr sk 4
@@ -158,6 +160,7 @@ but as a result are not well behaved newbus device drivers.
.Xr rl 4 ,
.Xr rue 4 ,
.Xr sf 4 ,
+.Xr sge 4 ,
.Xr sis 4 ,
.Xr sk 4 ,
.Xr ste 4 ,
diff --git a/share/man/man4/ndis.4 b/share/man/man4/ndis.4
index 71377ad..874a843 100644
--- a/share/man/man4/ndis.4
+++ b/share/man/man4/ndis.4
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 8, 2010
+.Dd March 14, 2010
.Dt NDIS 4
.Os
.Sh NAME
@@ -133,8 +133,10 @@ before a timeout expired.
.Xr netintro 4 ,
.Xr ng_ether 4 ,
.Xr ifconfig 8 ,
+.Xr ndis_events 8 ,
.Xr ndiscvt 8 ,
-.Xr ndisgen 8
+.Xr ndisgen 8 ,
+.Xr wpa_supplicant 8
.Rs
.%T "NDIS 5.1 specification"
.%U http://www.microsoft.com
diff --git a/share/man/man4/netintro.4 b/share/man/man4/netintro.4
index 348a13e..3e98940 100644
--- a/share/man/man4/netintro.4
+++ b/share/man/man4/netintro.4
@@ -32,7 +32,7 @@
.\" @(#)netintro.4 8.2 (Berkeley) 11/30/93
.\" $FreeBSD$
.\"
-.Dd January 26, 2010
+.Dd April 14, 2010
.Dt NETINTRO 4
.Os
.Sh NAME
@@ -292,8 +292,11 @@ field of
struct passed in as parameter, and the length would include
the terminating nul character.
If there is not enough space to hold the interface length,
-no copy would be done and an
-error would be returned.
+no copy would be done and the
+.Va buffer
+field of
+.Va ifru_buffer
+would be set to NULL.
The kernel will store the buffer length in the
.Va length
field upon return, regardless whether the buffer itself is
diff --git a/share/man/man4/ng_netflow.4 b/share/man/man4/ng_netflow.4
index d1ef204..5c5c8e0 100644
--- a/share/man/man4/ng_netflow.4
+++ b/share/man/man4/ng_netflow.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd October 8, 2008
-.Os
.Dt NG_NETFLOW 4
+.Os
.Sh NAME
.Nm ng_netflow
.Nd Cisco's NetFlow implementation
diff --git a/share/man/man4/ohci.4 b/share/man/man4/ohci.4
index ee56861..7f92617 100644
--- a/share/man/man4/ohci.4
+++ b/share/man/man4/ohci.4
@@ -9,21 +9,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. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/orm.4 b/share/man/man4/orm.4
index 2ef54a0..2922cb6 100644
--- a/share/man/man4/orm.4
+++ b/share/man/man4/orm.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 15, 2000
-.Os
.Dt ORM 4
+.Os
.Sh NAME
.Nm orm
.Nd ISA I/O space option ROM(s) driver
diff --git a/share/man/man4/pass.4 b/share/man/man4/pass.4
index b96d6ba..7819ea3 100644
--- a/share/man/man4/pass.4
+++ b/share/man/man4/pass.4
@@ -104,6 +104,7 @@ CAM subsystem.
None.
.Sh SEE ALSO
.Xr cam 3 ,
+.Xr cam 4 ,
.Xr cam_cdbparse 3 ,
.Xr xpt 4 ,
.Xr camcontrol 8
diff --git a/share/man/man4/pt.4 b/share/man/man4/pt.4
index 170956e..b45ae5a 100644
--- a/share/man/man4/pt.4
+++ b/share/man/man4/pt.4
@@ -84,7 +84,7 @@ the
.Ar N Ns th processor device.
.El
.Sh SEE ALSO
-.Xr scsi 4
+.Xr cam 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/ral.4 b/share/man/man4/ral.4
index 2fd8e33..25fb343 100644
--- a/share/man/man4/ral.4
+++ b/share/man/man4/ral.4
@@ -16,8 +16,8 @@
.\" $FreeBSD$
.\"
.Dd July 8, 2009
-.Os
.Dt RAL 4
+.Os
.Sh NAME
.Nm ral
.Nd "Ralink Technology IEEE 802.11 wireless network driver"
diff --git a/share/man/man4/rp.4 b/share/man/man4/rp.4
index 8f0f425..a894f12 100644
--- a/share/man/man4/rp.4
+++ b/share/man/man4/rp.4
@@ -3,8 +3,8 @@
.\"
.\" $FreeBSD$
.Dd November 15, 1995
-.Os
.Dt RP 4
+.Os
.Sh NAME
.Nm rp
.Nd "driver for Comtrol RocketPort Intelligent Serial Port Cards"
diff --git a/share/man/man4/rum.4 b/share/man/man4/rum.4
index cbbbcd0..82e25f5 100644
--- a/share/man/man4/rum.4
+++ b/share/man/man4/rum.4
@@ -17,8 +17,8 @@
.\" $FreeBSD$
.\"
.Dd April 13, 2008
-.Os
.Dt RUM 4
+.Os
.Sh NAME
.Nm rum
.Nd Ralink Technology USB IEEE 802.11a/b/g wireless network device
diff --git a/share/man/man4/run.4 b/share/man/man4/run.4
index e613649..a7c6f4d 100644
--- a/share/man/man4/run.4
+++ b/share/man/man4/run.4
@@ -17,8 +17,8 @@
.\" $FreeBSD$
.\"
.Dd January 29, 2010
-.Os
.Dt RUN 4
+.Os
.Sh NAME
.Nm run
.Nd Ralink Technology USB IEEE 802.11a/g/n wireless network device
diff --git a/share/man/man4/sa.4 b/share/man/man4/sa.4
index 0a6da7c..eae3bf5 100644
--- a/share/man/man4/sa.4
+++ b/share/man/man4/sa.4
@@ -200,8 +200,8 @@ accessing the device, e.g.).
.Sh DIAGNOSTICS
None.
.Sh SEE ALSO
-.Xr mt 1 ,
-.Xr scsi 4
+.Xr cam 4 ,
+.Xr mt 1
.Sh AUTHORS
.An -nosplit
The
diff --git a/share/man/man4/sched_4bsd.4 b/share/man/man4/sched_4bsd.4
index 9533cae..a02c40e 100644
--- a/share/man/man4/sched_4bsd.4
+++ b/share/man/man4/sched_4bsd.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 21, 2008
-.Os
.Dt SCHED_4BSD 4
+.Os
.Sh NAME
.Nm sched_4bsd
.Nd "4.4BSD scheduler"
diff --git a/share/man/man4/sched_ule.4 b/share/man/man4/sched_ule.4
index c5ce58b..fdb96f1 100644
--- a/share/man/man4/sched_ule.4
+++ b/share/man/man4/sched_ule.4
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 21, 2008
-.Os
.Dt SCHED_ULE 4
+.Os
.Sh NAME
.Nm sched_ule
.Nd ULE scheduler
diff --git a/share/man/man4/scsi.4 b/share/man/man4/scsi.4
index fccb935..ad52663 100644
--- a/share/man/man4/scsi.4
+++ b/share/man/man4/scsi.4
@@ -24,15 +24,15 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
-.Dd October 15, 1998
-.Dt SCSI 4
+.Dd March 4, 2010
+.Dt CAM 4
.Os
.Sh NAME
-.Nm SCSI ,
.Nm CAM
-.Nd CAM SCSI subsystem
+.Nd Common Access Method SCSI/ATA subsystem
.Sh SYNOPSIS
.Cd "device scbus"
+.Cd "device ada"
.Cd "device cd"
.Cd "device ch"
.Cd "device da"
@@ -49,31 +49,32 @@
.Cd "options SCSI_NO_OP_STRINGS"
.Cd "options SCSI_DELAY=8000"
.Sh DESCRIPTION
-The CAM
-.Tn SCSI
+The
+.Nm
subsystem provides a uniform and modular system for the implementation
of drivers to control various
.Tn SCSI
+and
+.Tn ATA
devices, and to utilize different
.Tn SCSI
+and
+.Tn ATA
host adapters through host adapter drivers.
-When the system probes the
-.Tn SCSI
-busses, it attaches any devices it finds to the appropriate
-drivers.
+When the system probes busses, it attaches any devices it finds to the
+appropriate drivers.
The
.Xr pass 4
-driver, if it is configured in the kernel, will attach to all
-.Tn SCSI
-devices.
+driver, if it is configured in the kernel, will attach to all devices.
.Sh KERNEL CONFIGURATION
There are a number of generic kernel configuration options for the
-CAM
-.Tn SCSI
+.Nm
subsystem:
.Bl -tag -width SCSI_NO_SENSE_STRINGS
.It Dv CAMDEBUG
-This option enables the CAM debugging printf code.
+This option enables the
+.Nm
+debugging printf code.
This will not actually
cause any debugging information to be printed out when included by itself.
Enabling printouts requires additional configuration.
@@ -82,12 +83,11 @@ See below for details.
This sets the maximum allowable number of concurrent "high power" commands.
A "high power" command is a command that takes more electrical power than
most to complete.
-An example of this (and the only command currently
-tagged as "high power") is the
+An example of this is the
.Tn SCSI
START UNIT command.
-Starting a SCSI disk often takes significantly more
-electrical power than normal operation of the disk.
+Starting a disk often takes significantly more electrical power than normal
+operation.
This option allows the
user to specify how many concurrent high power commands may be outstanding
without overloading the power supply on his computer.
@@ -120,7 +120,9 @@ problems.
This is the
.Tn SCSI
"bus settle delay."
-In CAM, it is specified in
+In
+.Nm ,
+it is specified in
.Em milliseconds ,
not seconds like the old
.Tn SCSI
@@ -148,7 +150,7 @@ In that case, the
will be reset to 100ms.
.El
.Pp
-All devices and the SCSI busses support boot time allocation so that
+All devices and busses support dynamic allocation so that
an upper number of devices and controllers does not need to be configured;
.Cd "device da"
will suffice for any number of disk drivers.
@@ -204,7 +206,9 @@ hint.da.0.unit="0"
This assigns
.Em da0
to target 0, unit (lun) 0 of scbus 0.
-Omitting the target or unit hints will instruct CAM to treat them as wildcards
+Omitting the target or unit hints will instruct
+.Nm
+to treat them as wildcards
and use the first respective counted instances.
These examples can be combined together to allow a peripheral device to be
wired to any particular controller, bus, target, and/or unit instance.
@@ -221,7 +225,9 @@ The system allows common device drivers to work through many different
types of adapters.
The adapters take requests from the upper layers and do
all IO between the
-.Em SCSI
+.Tn SCSI
+or
+.Tn ATA
bus and the system.
The maximum size of a transfer is governed by the
adapter.
@@ -233,7 +239,8 @@ Some adapters support
in which the system is capable of operating as a device, responding to
operations initiated by another system.
Target mode is supported for
-some adapters, but is not yet complete for this version of the CAM
+some adapters, but is not yet complete for this version of the
+.Nm
.Tn SCSI
subsystem.
.Sh FILES
@@ -278,7 +285,9 @@ Users can enable debugging from their kernel config file, by using
the following kernel config options:
.Bl -tag -width CAM_DEBUG_TARGET
.It Dv CAMDEBUG
-This enables CAM debugging.
+This enables
+.Nm
+debugging.
Without this option, users will not even be able
to turn on debugging from userland via
.Xr camcontrol 8 .
@@ -313,9 +322,12 @@ See
.Xr camcontrol 8
for details.
.Sh SEE ALSO
+.Xr ada 4 ,
.Xr aha 4 ,
.Xr ahb 4 ,
.Xr ahc 4 ,
+.Xr ahci 4 ,
+.Xr ata 4 ,
.Xr bt 4 ,
.Xr cd 4 ,
.Xr ch 4 ,
@@ -326,15 +338,26 @@ for details.
.Xr xpt 4 ,
.Xr camcontrol 8
.Sh HISTORY
-The CAM
+The
+.Nm
.Tn SCSI
subsystem first appeared in
.Fx 3.0 .
+The
+.Nm
+ATA support was added in
+.Fx 8.0 .
.Sh AUTHORS
.An -nosplit
-The CAM
+The
+.Nm
.Tn SCSI
subsystem was written by
.An Justin Gibbs
and
.An Kenneth Merry .
+The
+.Nm
+.Tn ATA
+support was added by
+.An Alexander Motin Aq mav@FreeBSD.org .
diff --git a/share/man/man4/sge.4 b/share/man/man4/sge.4
new file mode 100644
index 0000000..a3d057d
--- /dev/null
+++ b/share/man/man4/sge.4
@@ -0,0 +1,120 @@
+.\" Copyright (c) 2010 Pyun YongHyeon
+.\" 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$
+.\"
+.Dd April 14, 2010
+.Dt SGE 4
+.Os
+.Sh NAME
+.Nm sge
+.Nd Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet driver
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device miibus"
+.Cd "device sge"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+if_sge="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+device driver provides support for SiS190 Fast Ethernet
+controllers and SiS191 Fast/Gigabit Ethernet controllers.
+.Pp
+All LOMs supported by the
+.Nm
+driver have TCP/UDP/IP checksum offload for transmit and receive.
+Due to lack of documentation more offloading features like TCP
+segmentation offload (TSO), hardware VLAN tag stripping/insertion
+features, Wake On Lan (WOL), Jumbo frame and an interrupt moderation
+mechanism are not supported yet.
+.Pp
+The
+.Nm
+driver supports the following media types:
+.Bl -tag -width ".Cm 10baseT/UTP"
+.It Cm autoselect
+Enable autoselection of the media type and options.
+The user can manually override
+the autoselected mode by adding media options to
+.Xr rc.conf 5 .
+.It Cm 10baseT/UTP
+Set 10Mbps operation.
+.It Cm 100baseTX
+Set 100Mbps (Fast Ethernet) operation.
+.It Cm 1000baseTX
+Set 1000baseTX operation over twisted pair.
+.El
+.Pp
+The
+.Nm
+driver supports the following media options:
+.Bl -tag -width ".Cm full-duplex"
+.It Cm full-duplex
+Force full duplex operation.
+.It Cm half-duplex
+Force half duplex operation.
+.El
+.Pp
+For more information on configuring this device, see
+.Xr ifconfig 8 .
+.Sh HARDWARE
+The
+.Nm
+device driver provides support for the following Ethernet controllers:
+.Pp
+.Bl -bullet -compact
+.It
+SiS190 Fast Ethernet controller
+.It
+SiS191 Fast/Gigabit Ethernet controller
+.El
+.Sh SEE ALSO
+.Xr altq 4 ,
+.Xr arp 4 ,
+.Xr miibus 4 ,
+.Xr netintro 4 ,
+.Xr ng_ether 4 ,
+.Xr vlan 4 ,
+.Xr ifconfig 8
+.Sh HISTORY
+The
+.Nm
+driver was written by
+.An Alexander Pohoyda
+.Aq alexander.pohoyda@gmx.net .
+And enhanced by
+.An Nikolay Denev
+.Aq ndenev@gmail.com .
+It first appeared in
+.Fx 8.1 .
diff --git a/share/man/man4/si.4 b/share/man/man4/si.4
index 65176bd..5eb7629 100644
--- a/share/man/man4/si.4
+++ b/share/man/man4/si.4
@@ -1,7 +1,7 @@
.\" $FreeBSD$
.Dd September 16, 1995
-.Os
.Dt SI 4
+.Os
.Sh NAME
.Nm si
.Nd "driver for Specialix International SI/XIO or SX intelligent serial card"
diff --git a/share/man/man4/siis.4 b/share/man/man4/siis.4
index 8f70839..7480f70 100644
--- a/share/man/man4/siis.4
+++ b/share/man/man4/siis.4
@@ -113,10 +113,10 @@ SiI3531
.Sh SEE ALSO
.Xr ada 4 ,
.Xr ata 4 ,
+.Xr cam 4 ,
.Xr cd 4 ,
.Xr da 4 ,
-.Xr sa 4 ,
-.Xr scsi 4
+.Xr sa 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/snd_uaudio.4 b/share/man/man4/snd_uaudio.4
index d05019c..e620777 100644
--- a/share/man/man4/snd_uaudio.4
+++ b/share/man/man4/snd_uaudio.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/splash.4 b/share/man/man4/splash.4
index 36ba883..165366a 100644
--- a/share/man/man4/splash.4
+++ b/share/man/man4/splash.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 15, 2006
+.Dd April 7, 2010
.Dt SPLASH 4
.Os
.Sh NAME
@@ -99,10 +99,16 @@ Currently the following screen saver modules are available:
.Bl -tag -width splash_module.ko -compact
.It Pa blank_saver.ko
This screen saver simply blanks the screen.
+.It Pa beastie_saver.ko
+Animated graphical
+.Bx
+Daemon.
.It Pa daemon_saver.ko
Animated
.Bx
Daemon screen saver.
+.It Pa dragon_saver.ko
+Draws a random dragon curve.
.It Pa fade_saver.ko
The screen will gradually fade away.
.It Pa fire_saver.ko
@@ -111,8 +117,8 @@ A fire which becomes higher as load increases.
If the monitor supports power saving mode, it will be turned off.
.It Pa logo_saver.ko
Animated graphical
-.Bx
-Daemon.
+.Fx
+logo.
.It Pa rain_saver.ko
Draws a shower on the screen.
.It Pa snake_saver.ko
diff --git a/share/man/man4/stge.4 b/share/man/man4/stge.4
index a3ff67a..d9c75ef 100644
--- a/share/man/man4/stge.4
+++ b/share/man/man4/stge.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/sysmouse.4 b/share/man/man4/sysmouse.4
index 50392a1..e3972fe 100644
--- a/share/man/man4/sysmouse.4
+++ b/share/man/man4/sysmouse.4
@@ -94,18 +94,18 @@ Right button status; cleared if pressed, otherwise set.
.El
.It Byte 2
The first half of horizontal movement count in two's complement;
--128 through 127.
+\-128 through 127.
.It Byte 3
The first half of vertical movement count in two's complement;
--128 through 127.
+\-128 through 127.
.It Byte 4
The second half of the horizontal movement count in two's complement;
--128 through 127.
+\-128 through 127.
To obtain the full horizontal movement count, add
the byte 2 and 4.
.It Byte 5
The second half of the vertical movement count in two's complement;
--128 through 127.
+\-128 through 127.
To obtain the full vertical movement count, add
the byte 3 and 5.
.El
@@ -148,7 +148,7 @@ These commands manipulate the operation level of the mouse driver.
Returns the hardware information of the attached device in the following
structure.
Only the
-.Dv iftype
+.Va iftype
field is guaranteed to be filled with the correct value in the current
version of the
.Nm
@@ -164,16 +164,16 @@ typedef struct mousehw {
.Ed
.Pp
The
-.Dv buttons
+.Va buttons
field holds the number of buttons detected by the driver.
.Pp
The
-.Dv iftype
+.Va iftype
is always
.Dv MOUSE_IF_SYSMOUSE .
.Pp
The
-.Dv type
+.Va type
tells the device type:
.Dv MOUSE_MOUSE ,
.Dv MOUSE_TRACKBALL ,
@@ -183,7 +183,7 @@ or
.Dv MOUSE_UNKNOWN .
.Pp
The
-.Dv model
+.Va model
is always
.Dv MOUSE_MODEL_GENERIC
at the operation level 0.
@@ -194,7 +194,7 @@ or one of
constants at higher operation levels.
.Pp
The
-.Dv hwid
+.Va hwid
is always zero.
.Pp
.It Dv MOUSE_GETMODE Ar mousemode_t *mode
@@ -213,7 +213,7 @@ typedef struct mousemode {
.Ed
.Pp
The
-.Dv protocol
+.Va protocol
field tells the format in which the device status is returned
when the mouse data is read by the user program.
It is
@@ -223,19 +223,19 @@ at the operation level zero.
at the operation level one.
.Pp
The
-.Dv rate
-is always set to -1.
+.Va rate
+is always set to \-1.
.Pp
The
-.Dv resolution
-is always set to -1.
+.Va resolution
+is always set to \-1.
.Pp
The
-.Dv accelfactor
+.Va accelfactor
is always 0.
.Pp
The
-.Dv packetsize
+.Va packetsize
field specifies the length of the data packet.
It depends on the
operation level.
@@ -248,13 +248,13 @@ operation level.
.El
.Pp
The array
-.Dv syncmask
+.Va syncmask
holds a bit mask and pattern to detect the first byte of the
data packet.
-.Dv syncmask[0]
+.Va syncmask[0]
is the bit mask to be ANDed with a byte.
If the result is equal to
-.Dv syncmask[1] ,
+.Va syncmask[1] ,
the byte is likely to be the first byte of the data packet.
Note that this method of detecting the first byte is not 100% reliable;
thus, it should be taken only as an advisory measure.
@@ -264,7 +264,7 @@ The command changes the current operation parameters of the mouse driver
as specified in
.Ar mode .
Only
-.Dv level
+.Va level
may be modifiable.
Setting values in the other field does not generate
error and has no effect.
@@ -323,7 +323,7 @@ struct mouse_info {
.Ed
.Pp
.Bl -tag -width operation -compact
-.It Dv operation
+.It Va operation
This can be one of
.Pp
.Bl -tag -width MOUSE_MOVEABS -compact
@@ -333,21 +333,21 @@ Enables and displays mouse cursor.
Disables and hides mouse cursor.
.It Dv MOUSE_MOVEABS
Moves mouse cursor to position supplied in
-.Dv u.data .
+.Va u.data .
.It Dv MOUSE_MOVEREL
Adds position supplied in
-.Dv u.data
+.Va u.data
to current position.
.It Dv MOUSE_GETINFO
Returns current mouse position in the current virtual console
and button status in
-.Dv u.data .
+.Va u.data .
.It Dv MOUSE_MODE
This sets the
.Xr signal 3
to be delivered to the current process when a button is pressed.
The signal to be delivered is set in
-.Dv u.mode .
+.Va u.mode .
.El
.Pp
The above operations are for virtual consoles.
@@ -360,7 +360,7 @@ to pass mouse data to the console driver.
.It Dv MOUSE_ACTION
.It Dv MOUSE_MOTION_EVENT
These operations take the information in
-.Dv u.data
+.Va u.data
and act upon it.
Mouse data will be sent to the
.Nm
@@ -370,7 +370,7 @@ also processes button press actions and sends signal to the process if
requested or performs cut and paste operations
if the current console is a text interface.
.It Dv MOUSE_BUTTON_EVENT
-.Dv u.data
+.Va u.data
specifies a button and its click count.
The console driver will
use this information for signal delivery if requested or
@@ -385,11 +385,11 @@ They are intended to replace functions performed by
.Dv MOUSE_ACTION
alone.
.Pp
-.It Dv Sq u
+.It Va u
This union is one of
.Pp
.Bl -tag -width data -compact
-.It Dv data
+.It Va data
.Bd -literal
struct mouse_data {
int x;
@@ -399,18 +399,17 @@ struct mouse_data {
};
.Ed
.Pp
-.Dv x ,
-.Dv y
+.Va x , y
and
-.Dv z
+.Va z
represent movement of the mouse along respective directions.
-.Dv buttons
+.Va buttons
tells the state of buttons.
It encodes up to 31 buttons in the bit 0 though
the bit 30.
If a button is held down, the corresponding bit is set.
.Pp
-.It Dv mode
+.It Va mode
.Bd -literal
struct mouse_mode {
int mode;
@@ -419,16 +418,16 @@ struct mouse_mode {
.Ed
.Pp
The
-.Dv signal
+.Va signal
field specifies the signal to be delivered to the process.
It must be
one of the values defined in
.In signal.h .
The
-.Dv mode
+.Va mode
field is currently unused.
.Pp
-.It Dv event
+.It Va event
.Bd -literal
struct mouse_event {
int id;
@@ -437,12 +436,12 @@ struct mouse_event {
.Ed
.Pp
The
-.Dv id
+.Va id
field specifies a button number as in
-.Dv u.data.buttons .
+.Va u.data.buttons .
Only one bit/button is set.
The
-.Dv value
+.Va value
field
holds the click count: the number of times the user has clicked the button
successively.
diff --git a/share/man/man4/tap.4 b/share/man/man4/tap.4
index 9f04725..a306108 100644
--- a/share/man/man4/tap.4
+++ b/share/man/man4/tap.4
@@ -2,8 +2,8 @@
.\" Based on PR#2411
.\"
.Dd September 8, 2008
-.Os
.Dt TAP 4
+.Os
.Sh NAME
.Nm tap
.Nd Ethernet tunnel software network interface
diff --git a/share/man/man4/textdump.4 b/share/man/man4/textdump.4
index 4b12fe9..9c45f0f 100644
--- a/share/man/man4/textdump.4
+++ b/share/man/man4/textdump.4
@@ -74,7 +74,7 @@ May be disabled by clearing the
sysctl.
.It Pa config.txt
Kernel configuration, if
-.Od options INCLUDE_CONFIG_FILE
+.Cd options INCLUDE_CONFIG_FILE
has been compiled into the kernel.
May be disabled by clearing the
.Dv debug.ddb.textdump.do_config
diff --git a/share/man/man4/uart.4 b/share/man/man4/uart.4
index 7bd4732..644c37d 100644
--- a/share/man/man4/uart.4
+++ b/share/man/man4/uart.4
@@ -46,7 +46,6 @@ In
.Cd hint.uart.0.baud="38400"
.Cd hint.uart.0.port="0x3f8"
.Cd hint.uart.0.flags="0x10"
-.Ed
.Pp
With
.Ar flags
diff --git a/share/man/man4/ubsa.4 b/share/man/man4/ubsa.4
index 1870e45..a9c47f8 100644
--- a/share/man/man4/ubsa.4
+++ b/share/man/man4/ubsa.4
@@ -13,13 +13,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/ucom.4 b/share/man/man4/ucom.4
index c060cac..1f39847 100644
--- a/share/man/man4/ucom.4
+++ b/share/man/man4/ucom.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/udbp.4 b/share/man/man4/udbp.4
index accb474..45afd79 100644
--- a/share/man/man4/udbp.4
+++ b/share/man/man4/udbp.4
@@ -9,21 +9,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. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/ufm.4 b/share/man/man4/ufm.4
index f852d6d..7ae11bd 100644
--- a/share/man/man4/ufm.4
+++ b/share/man/man4/ufm.4
@@ -10,17 +10,17 @@
.\" 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 FREEBSD AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/uftdi.4 b/share/man/man4/uftdi.4
index 0037666..c20c594 100644
--- a/share/man/man4/uftdi.4
+++ b/share/man/man4/uftdi.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/ugen.4 b/share/man/man4/ugen.4
index f74752c..9b149fb 100644
--- a/share/man/man4/ugen.4
+++ b/share/man/man4/ugen.4
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/uhci.4 b/share/man/man4/uhci.4
index 089fafb..584176a 100644
--- a/share/man/man4/uhci.4
+++ b/share/man/man4/uhci.4
@@ -9,21 +9,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. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/uhid.4 b/share/man/man4/uhid.4
index b830512..b6274ba 100644
--- a/share/man/man4/uhid.4
+++ b/share/man/man4/uhid.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/uhso.4 b/share/man/man4/uhso.4
index 7f10c62..e4d6df5 100644
--- a/share/man/man4/uhso.4
+++ b/share/man/man4/uhso.4
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd January 14, 2010
-.Os
.Dt UHSO 4
+.Os
.Sh NAME
.Nm uhso
.Nd support for several HSxPA devices from Option N.V.
diff --git a/share/man/man4/ukbd.4 b/share/man/man4/ukbd.4
index 5d94cef..71ee348 100644
--- a/share/man/man4/ukbd.4
+++ b/share/man/man4/ukbd.4
@@ -9,21 +9,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. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/ulpt.4 b/share/man/man4/ulpt.4
index 229145d..e0f5eb6 100644
--- a/share/man/man4/ulpt.4
+++ b/share/man/man4/ulpt.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/umass.4 b/share/man/man4/umass.4
index 56094cd..18ffde3 100644
--- a/share/man/man4/umass.4
+++ b/share/man/man4/umass.4
@@ -9,21 +9,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. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/umodem.4 b/share/man/man4/umodem.4
index d034eb7..cb3a2e3 100644
--- a/share/man/man4/umodem.4
+++ b/share/man/man4/umodem.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/ums.4 b/share/man/man4/ums.4
index b56a72f..6c052a1 100644
--- a/share/man/man4/ums.4
+++ b/share/man/man4/ums.4
@@ -9,21 +9,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. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/upgt.4 b/share/man/man4/upgt.4
index 39dee55..06c5eb5 100644
--- a/share/man/man4/upgt.4
+++ b/share/man/man4/upgt.4
@@ -50,8 +50,8 @@
.\" SUCH DAMAGE.
.\"
.Dd April 17, 2008
-.Os
.Dt UPGT 4
+.Os
.Sh NAME
.Nm upgt
.Nd Conexant/Intersil PrismGT SoftMAC USB IEEE 802.11b/g wireless network
diff --git a/share/man/man4/uplcom.4 b/share/man/man4/uplcom.4
index 5304885..672e619 100644
--- a/share/man/man4/uplcom.4
+++ b/share/man/man4/uplcom.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/ural.4 b/share/man/man4/ural.4
index 053ae70..3825166 100644
--- a/share/man/man4/ural.4
+++ b/share/man/man4/ural.4
@@ -16,8 +16,8 @@
.\" $FreeBSD$
.\"
.Dd April 13, 2008
-.Os
.Dt URAL 4
+.Os
.Sh NAME
.Nm ural
.Nd "Ralink Technology RT2500USB IEEE 802.11 driver"
diff --git a/share/man/man4/urio.4 b/share/man/man4/urio.4
index 7620deb..68a4964 100644
--- a/share/man/man4/urio.4
+++ b/share/man/man4/urio.4
@@ -1,5 +1,5 @@
-.\" Copyright (c) 2000 Dirk-Willem van Gulik
-.\" <dirkx@webweaving.org>. All rights reserved.
+.\" Copyright (c) 2000 Dirk-Willem van Gulik <dirkx@webweaving.org>
+.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -9,24 +9,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 Bill Paul.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS ``AS IS'' AND
+.\" 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
+.\" 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$
.\"
diff --git a/share/man/man4/usb.4 b/share/man/man4/usb.4
index e2b236a..2ecfbce 100644
--- a/share/man/man4/usb.4
+++ b/share/man/man4/usb.4
@@ -1,30 +1,4 @@
-.\" Copyright (c) 1997, 1998
-.\" Nick Hibma <n_hibma@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.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY NICK HIBMA 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 NICK HIBMA OR THE VOICES IN HIS HEAD
-.\" 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.
-.\"
+.\" Copyright (c) 1997, 1998 Nick Hibma <n_hibma@FreeBSD.org>
.\" Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
diff --git a/share/man/man4/uvisor.4 b/share/man/man4/uvisor.4
index ceffa89..081df4e 100644
--- a/share/man/man4/uvisor.4
+++ b/share/man/man4/uvisor.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/uvscom.4 b/share/man/man4/uvscom.4
index 269667b..dfa87e7 100644
--- a/share/man/man4/uvscom.4
+++ b/share/man/man4/uvscom.4
@@ -14,13 +14,6 @@
.\" 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 acknowledgment:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man4/vkbd.4 b/share/man/man4/vkbd.4
index bdaa941..079688f 100644
--- a/share/man/man4/vkbd.4
+++ b/share/man/man4/vkbd.4
@@ -2,8 +2,8 @@
.\" $FreeBSD$
.\"
.Dd August 12, 2004
-.Os
.Dt VKBD 4
+.Os
.Sh NAME
.Nm vkbd
.Nd the virtual AT keyboard interface
diff --git a/share/man/man4/vlan.4 b/share/man/man4/vlan.4
index 149d4bc..f7f7807 100644
--- a/share/man/man4/vlan.4
+++ b/share/man/man4/vlan.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 14, 2009
+.Dd April 14, 2010
.Dt VLAN 4
.Os
.Sh NAME
@@ -172,6 +172,7 @@ natively:
.Xr nve 4 ,
.Xr rl 4 ,
.Xr sf 4 ,
+.Xr sge 4 ,
.Xr sis 4 ,
.Xr sk 4 ,
.Xr ste 4 ,
diff --git a/share/man/man4/wpi.4 b/share/man/man4/wpi.4
index f424d74..07e8816 100644
--- a/share/man/man4/wpi.4
+++ b/share/man/man4/wpi.4
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd October 5, 2008
-.Os
.Dt WPI 4
+.Os
.Sh NAME
.Nm wpi
.Nd "Intel 3945ABG Wireless LAN IEEE 802.11 driver"
diff --git a/share/man/man5/ar.5 b/share/man/man5/ar.5
index 58d2d78..dc802ce 100644
--- a/share/man/man5/ar.5
+++ b/share/man/man5/ar.5
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 7, 2007
-.Os
.Dt AR 5
+.Os
.Sh NAME
.Nm ar
.Nd format of archives managed by ar(1) and ranlib(1)
diff --git a/share/man/man5/core.5 b/share/man/man5/core.5
index 2a1e16b..b2b57f1 100644
--- a/share/man/man5/core.5
+++ b/share/man/man5/core.5
@@ -68,13 +68,27 @@ the core image to.
This filename can be absolute, or relative (which
will resolve to the current working directory of the program
generating it).
-Any sequence of
-.Em \&%N
-in this filename template will be replaced by the process name,
-.Em \&%P
-by the processes PID, and
-.Em \&%U
-by the UID.
+.Pp
+The following format specifiers may be used in the
+.Va kern.corefile
+sysctl to insert additional information into the resulting core file
+name:
+.Bl -tag -width "1234567890" -compact -offset "12345"
+.It Em \&%H
+Machine hostname.
+.It Em \&%I
+An index starting at zero until the sysctl
+.Em debug.num_cores
+is reached. This can be useful for limiting the number of corefiles
+generated by a particular process.
+.It Em \&%N
+process name.
+.It Em \&%P
+processes PID.
+.It Em \&%U
+process UID.
+.El
+.Pp
The name defaults to
.Em \&%N.core ,
yielding the traditional
@@ -89,6 +103,26 @@ changed to generate a core dump by setting the
variable
.Va kern.sugid_coredump
to 1.
+.Pp
+Corefiles can be compressed by the kernel if the following items
+are included in the kernel configuration file:
+.Bl -tag -width "1234567890" -compact -offset "12345"
+.It options
+COMPRESS_USER_CORES
+.It devices
+gzio
+.El
+.Pp
+When COMPRESS_USER_CORES is included the following sysctls can control
+if core files will be compressed:
+.Bl -tag -width "kern.compress_user_cores_gzlevel" -compact -offset "12345"
+.It Em kern.compress_user_cores_gzlevel
+Gzip compression level. Defaults to -1.
+.It Em kern.compress_user_cores
+Actually compress user cores. Core files will have the suffix
+.Em .gz
+appended to them.
+.El
.Sh EXAMPLES
In order to store all core images in per-user private areas under
.Pa /var/coredumps ,
diff --git a/share/man/man5/nsswitch.conf.5 b/share/man/man5/nsswitch.conf.5
index f6940bd..c28720b 100644
--- a/share/man/man5/nsswitch.conf.5
+++ b/share/man/man5/nsswitch.conf.5
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 23, 2008
+.Dd April 4, 2010
.Dt NSSWITCH.CONF 5
.Os
.Sh NAME
@@ -72,6 +72,8 @@ Local files, such as
.Pa /etc/hosts ,
and
.Pa /etc/passwd .
+.It db
+Local database.
.It dns
Internet Domain Name System.
.Dq hosts
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 96f64d3..734e7a3 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 12, 2010
+.Dd April 27, 2010
.Dt RC.CONF 5
.Os
.Sh NAME
@@ -427,27 +427,11 @@ the
kernel module will be loaded.
See also
.Va ipfilter_enable .
-.It Va ipv6_firewall_enable
-.Pq Vt bool
-The IPv6 equivalent of
-.Va firewall_enable .
-Set to
-.Dq Li YES
-to load IPv6 firewall rules at startup.
-If the kernel was not built with
-.Cd "options IPV6FIREWALL" ,
-the
-.Pa ipfw.ko
-kernel module will be loaded.
.It Va firewall_script
.Pq Vt str
This variable specifies the full path to the firewall script to run.
The default is
.Pa /etc/rc.firewall .
-.It Va ipv6_firewall_script
-.Pq Vt str
-The IPv6 equivalent of
-.Va firewall_script .
.It Va firewall_type
.Pq Vt str
Names the firewall type from the selection in
@@ -471,19 +455,11 @@ basic protection for a LAN.
.Pp
If a filename is specified, the full path
must be given.
-.It Va ipv6_firewall_type
-.Pq Vt str
-The IPv6 equivalent of
-.Va firewall_type .
.It Va firewall_quiet
.Pq Vt bool
Set to
.Dq Li YES
to disable the display of firewall rules on the console during boot.
-.It Va ipv6_firewall_quiet
-.Pq Vt bool
-The IPv6 equivalent of
-.Va firewall_quiet .
.It Va firewall_logging
.Pq Vt bool
Set to
@@ -492,10 +468,6 @@ to enable firewall event logging.
This is equivalent to the
.Dv IPFIREWALL_VERBOSE
kernel option.
-.It Va ipv6_firewall_logging
-.Pq Vt bool
-The IPv6 equivalent of
-.Va firewall_logging .
.It Va firewall_flags
.Pq Vt str
Flags passed to
@@ -503,10 +475,6 @@ Flags passed to
if
.Va firewall_type
specifies a filename.
-.It Va ipv6_firewall_flags
-.Pq Vt str
-The IPv6 equivalent of
-.Va firewall_flags .
.It Va firewall_coscripts
.Pq Vt str
List of executables and/or rc scripts to run after firewall starts/stops.
@@ -1292,79 +1260,105 @@ It is also possible to rename an interface by doing:
ifconfig_ed0_name="net0"
ifconfig_net0="inet 192.0.2.1 netmask 0xffffff00"
.Ed
+.\" Remove in FreeBSD 10.x
.It Va ipv6_enable
.Pq Vt bool
-If the variable is
-.Dq Li YES ,
-.Dq Li inet6 accept_rtadv
-is added to all of
-.Va ifconfig_ Ns Ao Ar interface Ac Ns _ipv6
-and the
-.Va ipv6_prefer
-is defined as
-.Dq Li YES .
.Pp
-This variable is deprecated. Use
-.Va ipv6_prefer
-and
-.Va ifconfig_ Ns Ao Ar interface Ac Ns _ipv6 .
-.It Va ipv6_prefer
-.Pq Vt bool
-This variable does the following:
+This option is deprecated.
.Pp
If the variable is
-.Dq Li YES ,
-the default policy of the source address selection set by
-.Xr ip6addrctl 8
-will be IPv6-preferred.
+.Dq Li YES
+it has no effect.
+To configure IPv6 for an interface see
+.Va ipv6_network_interfaces
+below.
.Pp
If the variable is
-.Dq Li NO ,
-the default policy of the source address selection set by
-.Xr ip6addrctl 8
-will be IPv4-preferred, and all of interfaces which does not have the
-corrsponding
-.Va ifconfig_ Ns Ao Ar interface Ac Ns _ipv6
-variable will be marked as
-.Dq Li IFDISABLED .
-This means only IPv6 functionality on that interface is completely
-disabled. For more details of
-.Dq Li IFDISABLED
-flag and keywords
-.Dq Li inet6 ifdisabled ,
-see
-.Xr ifconfig 8 .
-.Pp
+.Dq Li NO
+then other than
+.Dq Li lo0
+IPv6 will be disabled for each interface,
+however the same effect can be achieved by
+not configuring the interface.
.It Va ipv6_network_interfaces
.Pq Vt str
This is the IPv6 equivalent of
.Va network_interfaces .
-Normally manual configuration of this variable is not needed.
+Normally configuration of this variable is not needed,
+the value should be left as
+.Dq Li AUTO .
+.Pp
+If
+.Dq Li INET6
+is configured in the kernel configuration for the
+.Dq Li lo0
+interface will always be performed.
+It is not necessary to list it in
+.Va ipv6_network_interfaces .
+.Pp
+Example configuration to accept Router Advertisements (RA) for the
+.Dq Li ed0
+interface:
+.Bd -literal
+ifconfig_ed0_ipv6="RTADV"
+.Ed
+.Pp
+To configure only a link-local address on the
+.Dq Li ed0
+interface:
+.Bd -literal
+ifconfig_ed0_ipv6="inet6 auto_linklocal"
+.Ed
+.Pp
+To disable RA the
+.Dq Li NORTADV
+option is available, although not required if manual
+configuration is performed as described below.
+.Pp
+An IPv6 interface can be configured manually with
+.Va ifconfig_ Ns Ao Ar interface Ac Ns _ipv6 .
+For example:
+.Bd -literal
+ifconfig_ed0_ipv6="inet6 2001:db8:1::1 prefixlen 64"
+.Ed
+.Pp
+Manual configuration of an IPv6 address will also
+require configuration of the
+.Va ipv6_defaultrouter
+option.
.Pp
-IPv6 functionality on an interface should be configured by
-.Va ifconfig_ Ns Ao Ar interface Ac Ns _ipv6 ,
-instead of setting ifconfig parameters in
-.Va ifconfig_ Ns Aq Ar interface .
Aliases should be set by
.Va ifconfig_ Ns Ao Ar interface Ac Ns Va _alias Ns Aq Ar n
-with
+with the
.Dq Li inet6
-keyword. For example:
+keyword.
+For example:
+.Pp
.Bd -literal
-ifconfig_ed0_ipv6="inet6 2001:db8:1::1 prefixlen 64"
ifconfig_ed0_alias0="inet6 2001:db8:2::1 prefixlen 64"
.Ed
.Pp
-Interfaces that have an
-.Dq Li inet6 accept_rtadv
-keyword in
-.Va ifconfig_ Ns Ao Ar interface Ac Ns _ipv6
-setting will be automatically configured by
-.Xr rtsol 8 .
-Note that this automatic configuration is disabled if the
-.Va ipv6_gateway_enable
-is set to
-.Dq Li YES .
+.It Va ipv6_prefer
+.Pq Vt bool
+If the variable is
+.Dq Li YES ,
+the default policy of the source address selection set by
+.Xr ip6addrctl 8
+will be IPv6-preferred.
+.Pp
+If the variable is
+.Dq Li NO ,
+the default policy of the source address selection set by
+.Xr ip6addrctl 8
+will be IPv4-preferred.
+.Pp
+.It Va ipv6_privacy
+.Pq Vt bool
+If the variable is
+.Dq Li YES
+privacy addresses will be generated for each IPv6
+interface as described in RFC 4193.
+.Pp
.It Va ipv6_prefix_ Ns Aq Ar interface
.Pq Vt str
If one or more prefixes are defined in
@@ -1376,7 +1370,7 @@ configured on that interface.
If not set to
.Dq Li NO ,
this is the default output interface for scoped addresses.
-Now this works only for IPv6 link local multicast addresses.
+This works only with ipv6_gateway_enable="NO".
.It Va ip6addrctl_enable
.Pq Vt bool
If set to
@@ -3497,6 +3491,11 @@ indicates that the highest frequency (less power savings) should be used.
If set to
.Dq Li NO ,
any configured jails will not be started.
+.It jail_parallel_start
+.Pq Vt bool
+If set to
+.Dq Li YES
+all configured jails will be started in the background (= in parallel).
.It Va jail_list
.Pq Vt str
A space separated list of names for jails.
@@ -4244,6 +4243,26 @@ if it should register Dial-Up Networking service on the speficied
RFCOMM channel.
Default
.Dq Li NO .
+.It Va ubthidhci_enable
+.Pq Vt bool
+If set to
+.Dq Li YES ,
+change the USB Bluetooth controller from HID mode to HCI mode.
+You also need to specify the location of USB Bluetooth controller with the
+.Va ubthidhci_busnum
+and
+.Va ubthidhci_addr
+variables.
+.It Va ubthidhci_busnum
+Bus number where the USB Bluetooth controller is located.
+Check the output of
+.Xr usbconfig 1
+on your system to find this information.
+.It Va ubthidhci_addr
+Bus address of the USB Bluetooth controller.
+Check the output of
+.Xr usbconfig 1
+on your system to find this information.
.El
.Sh FILES
.Bl -tag -width ".Pa /etc/defaults/rc.conf" -compact
@@ -4259,6 +4278,7 @@ Default
.Xr kbdcontrol 1 ,
.Xr makewhatis 1 ,
.Xr sh 1 ,
+.Xr usbconfig 1 ,
.Xr vi 1 ,
.Xr vidcontrol 1 ,
.Xr bridge 4 ,
diff --git a/share/man/man5/services.5 b/share/man/man5/services.5
index 40320f9..55e0c9d 100644
--- a/share/man/man5/services.5
+++ b/share/man/man5/services.5
@@ -32,7 +32,7 @@
.\" @(#)services.5 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd June 5, 1993
+.Dd April 4, 2010
.Dt SERVICES 5
.Os
.Sh NAME
@@ -65,6 +65,18 @@ not interpreted by the routines which search the file.
Service names may contain any printable
character other than a field delimiter, newline,
or comment character.
+.Pp
+If
+.Dq db
+is specified as source in the
+.Xr nsswitch.conf 5 ,
+.Pa /var/db/services.db
+is searched.
+The database in
+.Pa /var/db/services.db
+needs to be updated with
+.Xr services_mkdb 8
+after changes to the services file have been applied.
.Sh NIS INTERACTION
Access to the NIS
.Pa services.byname
@@ -84,6 +96,8 @@ file resides in
.El
.Sh SEE ALSO
.Xr getservent 3
+.Xr nsswitch.conf 5
+.Xr services_mkdb 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 241d101..8720a72 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,7 +1,7 @@
.\" DO NOT EDIT-- this file is automatically generated.
.\" from FreeBSD: head/tools/build/options/makeman 188848 2009-02-20 11:09:55Z mtm
.\" $FreeBSD$
-.Dd January 16, 2010
+.Dd March 26, 2010
.Dt SRC.CONF 5
.Os
.Sh NAME
@@ -339,13 +339,6 @@ When set, it also enforces the following options:
.It
.Va WITHOUT_GNU_SUPPORT
.El
-.It Va WITH_GNU_CPIO
-.\" from FreeBSD: head/tools/build/options/WITH_GNU_CPIO 179813 2008-06-16 05:48:15Z dougb
-Set to build GNU cpio as a part of the base system,
-and symlink
-.Pa /usr/bin/cpio
-to this version.
-(This will override the symlink to the BSD version.)
.It Va WITHOUT_GNU_GREP
.\" from FreeBSD: head/tools/build/options/WITHOUT_GNU_GREP 179813 2008-06-16 05:48:15Z dougb
Set to not build GNU grep as a part of the base system.
diff --git a/share/man/man7/build.7 b/share/man/man7/build.7
index 28151b6..67a2445 100644
--- a/share/man/man7/build.7
+++ b/share/man/man7/build.7
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 15, 2009
+.Dd April 02, 2010
.Dt BUILD 7
.Os
.Sh NAME
@@ -311,6 +311,20 @@ should be set as with
.Sh ENVIRONMENT
Variables that influence all builds include:
.Bl -tag -width ".Va MAKEOBJDIRPREFIX"
+.It Va DEBUG_FLAGS
+Defines a set of debugging flags that will be used to build all userland
+binaries under
+.Pa /usr/src .
+When
+.Va DEBUG_FLAGS
+is defined, the
+.Cm install
+and
+.Cm installworld
+targets install binaries from the current
+.Va MAKEOBJDIRPREFIX
+without stripping,
+so that debugging information is retained in the installed binaries.
.It Va DESTDIR
The directory hierarchy prefix where built objects will be installed.
If not set,
@@ -327,6 +341,15 @@ or the command line.
.It Va NO_WERROR
If defined, compiler warnings will not cause the build to halt,
even if the makefile says otherwise.
+.It Va WITH_CTF
+If defined, the build process will run the DTrace CTF conversion
+tools on built objects.
+Please note that this WITH_ option is handled differently than all
+other WITH_ options (there is no
+.Va WITHOUT_CTF ,
+or corresponding
+.Va MK_CTF
+in the build system).
.El
.Pp
Additionally, builds in
diff --git a/share/man/man7/clocks.7 b/share/man/man7/clocks.7
index 700a79f..6927968 100644
--- a/share/man/man7/clocks.7
+++ b/share/man/man7/clocks.7
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\" "
.Dd January 18, 2008
-.Os
.Dt CLOCKS 7
+.Os
.Sh NAME
.Nm clocks
.Nd various system timers
diff --git a/share/man/man7/maclabel.7 b/share/man/man7/maclabel.7
index 05c3654..0648fb5 100644
--- a/share/man/man7/maclabel.7
+++ b/share/man/man7/maclabel.7
@@ -34,8 +34,8 @@
.\" $FreeBSD$
.\"
.Dd October 25, 2002
-.Os
.Dt MACLABEL 7
+.Os
.Sh NAME
.Nm maclabel
.Nd Mandatory Access Control label format
diff --git a/share/man/man8/picobsd.8 b/share/man/man8/picobsd.8
index 1ce50b3..c6c6c94 100644
--- a/share/man/man8/picobsd.8
+++ b/share/man/man8/picobsd.8
@@ -1,8 +1,8 @@
.\" -*- nroff-fill -*-
.\" $FreeBSD$
.Dd June 25, 2009
-.Os
.Dt PICOBSD 8
+.Os
.Sh NAME
.Nm picobsd
.Nd building small FreeBSD disk images
diff --git a/share/man/man8/rescue.8 b/share/man/man8/rescue.8
index 685827f..2921887 100644
--- a/share/man/man8/rescue.8
+++ b/share/man/man8/rescue.8
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd July 23, 2003
-.Os
.Dt RESCUE 8
+.Os
.Sh NAME
.Nm rescue
.Nd rescue utilities in
diff --git a/share/man/man9/CTASSERT.9 b/share/man/man9/CTASSERT.9
index db1ad49..4885d42 100644
--- a/share/man/man9/CTASSERT.9
+++ b/share/man/man9/CTASSERT.9
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd September 5, 2008
-.Os
.Dt CTASSERT 9
+.Os
.Sh NAME
.Nm CTASSERT
.Nd compile time assertion macro
diff --git a/share/man/man9/DELAY.9 b/share/man/man9/DELAY.9
index ac6231c..58b2a07 100644
--- a/share/man/man9/DELAY.9
+++ b/share/man/man9/DELAY.9
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd November 21, 2000
-.Os
.Dt DELAY 9
+.Os
.Sh NAME
.Nm DELAY
.Nd busy loop for an interval
diff --git a/share/man/man9/KASSERT.9 b/share/man/man9/KASSERT.9
index e53e9b6..62c97c4 100644
--- a/share/man/man9/KASSERT.9
+++ b/share/man/man9/KASSERT.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd January 14, 2000
-.Os
.Dt KASSERT 9
+.Os
.Sh NAME
.Nm KASSERT
.Nd kernel expression verification macro
diff --git a/share/man/man9/VFS.9 b/share/man/man9/VFS.9
index 30f8918..ca3109b 100644
--- a/share/man/man9/VFS.9
+++ b/share/man/man9/VFS.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd February 9, 2010
-.Os
.Dt VFS 9
+.Os
.Sh NAME
.Nm VFS
.Nd kernel interface to file systems
diff --git a/share/man/man9/VFS_CHECKEXP.9 b/share/man/man9/VFS_CHECKEXP.9
index 92afda8..62d545c 100644
--- a/share/man/man9/VFS_CHECKEXP.9
+++ b/share/man/man9/VFS_CHECKEXP.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 4, 2010
-.Os
.Dt VFS_CHECKEXP 9
+.Os
.Sh NAME
.Nm VFS_CHECKEXP
.Nd check if a file system is exported to a client
diff --git a/share/man/man9/VFS_FHTOVP.9 b/share/man/man9/VFS_FHTOVP.9
index f6f88d2..39a6168 100644
--- a/share/man/man9/VFS_FHTOVP.9
+++ b/share/man/man9/VFS_FHTOVP.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd January 4, 2010
-.Os
.Dt VFS_FHTOVP 9
+.Os
.Sh NAME
.Nm VFS_FHTOVP
.Nd turn an NFS filehandle into a vnode
diff --git a/share/man/man9/VFS_MOUNT.9 b/share/man/man9/VFS_MOUNT.9
index 4856dc4..e46c71a 100644
--- a/share/man/man9/VFS_MOUNT.9
+++ b/share/man/man9/VFS_MOUNT.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd May 23, 2009
-.Os
.Dt VFS_MOUNT 9
+.Os
.Sh NAME
.Nm VFS_MOUNT
.Nd mount a file system
diff --git a/share/man/man9/VFS_QUOTACTL.9 b/share/man/man9/VFS_QUOTACTL.9
index 48ff866..fded4d6 100644
--- a/share/man/man9/VFS_QUOTACTL.9
+++ b/share/man/man9/VFS_QUOTACTL.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd May 23, 2009
-.Os
.Dt VFS_QUOTACTL 9
+.Os
.Sh NAME
.Nm VFS_QUOTACTL
.Nd manipulate file system quotas
diff --git a/share/man/man9/VFS_ROOT.9 b/share/man/man9/VFS_ROOT.9
index 2490cfc..f81a500 100644
--- a/share/man/man9/VFS_ROOT.9
+++ b/share/man/man9/VFS_ROOT.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd May 23, 2009
-.Os
.Dt VFS_ROOT 9
+.Os
.Sh NAME
.Nm VFS_ROOT
.Nd return the root vnode of a file system
diff --git a/share/man/man9/VFS_STATFS.9 b/share/man/man9/VFS_STATFS.9
index 80d0d66..7a7e371 100644
--- a/share/man/man9/VFS_STATFS.9
+++ b/share/man/man9/VFS_STATFS.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd May 23, 2009
-.Os
.Dt VFS_STATFS 9
+.Os
.Sh NAME
.Nm VFS_STATFS
.Nd return file system status
diff --git a/share/man/man9/VFS_SYNC.9 b/share/man/man9/VFS_SYNC.9
index 60947a2..ed510dd 100644
--- a/share/man/man9/VFS_SYNC.9
+++ b/share/man/man9/VFS_SYNC.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd May 23, 2009
-.Os
.Dt VFS_SYNC 9
+.Os
.Sh NAME
.Nm VFS_SYNC
.Nd flush unwritten data
diff --git a/share/man/man9/VFS_UNMOUNT.9 b/share/man/man9/VFS_UNMOUNT.9
index 676685d..59113ee 100644
--- a/share/man/man9/VFS_UNMOUNT.9
+++ b/share/man/man9/VFS_UNMOUNT.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd May 23, 2009
-.Os
.Dt VFS_UNMOUNT 9
+.Os
.Sh NAME
.Nm VFS_UNMOUNT
.Nd unmount a file system
diff --git a/share/man/man9/VFS_VGET.9 b/share/man/man9/VFS_VGET.9
index 02b5536..22c902f 100644
--- a/share/man/man9/VFS_VGET.9
+++ b/share/man/man9/VFS_VGET.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd January 7, 2005
-.Os
.Dt VFS_VGET 9
+.Os
.Sh NAME
.Nm VFS_VGET
.Nd convert an inode number to a vnode
diff --git a/share/man/man9/VOP_ACCESS.9 b/share/man/man9/VOP_ACCESS.9
index 927c118..005f2e2 100644
--- a/share/man/man9/VOP_ACCESS.9
+++ b/share/man/man9/VOP_ACCESS.9
@@ -30,8 +30,8 @@
.\" $FreeBSD$
.\"
.Dd September 18, 2009
-.Os
.Dt VOP_ACCESS 9
+.Os
.Sh NAME
.Nm VOP_ACCESS ,
.Nm VOP_ACCESSX
diff --git a/share/man/man9/VOP_ACLCHECK.9 b/share/man/man9/VOP_ACLCHECK.9
index 6210228..3638112 100644
--- a/share/man/man9/VOP_ACLCHECK.9
+++ b/share/man/man9/VOP_ACLCHECK.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 23, 1999
-.Os
.Dt VOP_ACLCHECK 9
+.Os
.Sh NAME
.Nm VOP_ACLCHECK
.Nd check an access control list for a vnode
diff --git a/share/man/man9/VOP_ADVLOCK.9 b/share/man/man9/VOP_ADVLOCK.9
index bdb00b7..3dabc59 100644
--- a/share/man/man9/VOP_ADVLOCK.9
+++ b/share/man/man9/VOP_ADVLOCK.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd June 30, 1999
-.Os
.Dt VOP_ADVLOCK 9
+.Os
.Sh NAME
.Nm VOP_ADVLOCK
.Nd advisory record locking
diff --git a/share/man/man9/VOP_ATTRIB.9 b/share/man/man9/VOP_ATTRIB.9
index f14b1a5..e48e4eb 100644
--- a/share/man/man9/VOP_ATTRIB.9
+++ b/share/man/man9/VOP_ATTRIB.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd August 29, 2008
-.Os
.Dt VOP_ATTRIB 9
+.Os
.Sh NAME
.Nm VOP_GETATTR ,
.Nm VOP_SETATTR
diff --git a/share/man/man9/VOP_BWRITE.9 b/share/man/man9/VOP_BWRITE.9
index 0b8f7e0..d2ee510 100644
--- a/share/man/man9/VOP_BWRITE.9
+++ b/share/man/man9/VOP_BWRITE.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_BWRITE 9
+.Os
.Sh NAME
.Nm VOP_BWRITE
.Nd write a file system buffer
diff --git a/share/man/man9/VOP_CREATE.9 b/share/man/man9/VOP_CREATE.9
index 2f30328..b86a88d 100644
--- a/share/man/man9/VOP_CREATE.9
+++ b/share/man/man9/VOP_CREATE.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_CREATE 9
+.Os
.Sh NAME
.Nm VOP_CREATE ,
.Nm VOP_MKNOD ,
diff --git a/share/man/man9/VOP_FSYNC.9 b/share/man/man9/VOP_FSYNC.9
index 5439813..e457f84 100644
--- a/share/man/man9/VOP_FSYNC.9
+++ b/share/man/man9/VOP_FSYNC.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_FSYNC 9
+.Os
.Sh NAME
.Nm VOP_FSYNC
.Nd flush file system buffers for a file
diff --git a/share/man/man9/VOP_GETACL.9 b/share/man/man9/VOP_GETACL.9
index ba81908..d230340 100644
--- a/share/man/man9/VOP_GETACL.9
+++ b/share/man/man9/VOP_GETACL.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 23, 1999
-.Os
.Dt VOP_GETACL 9
+.Os
.Sh NAME
.Nm VOP_GETACL
.Nd retrieve access control list for a vnode
diff --git a/share/man/man9/VOP_GETEXTATTR.9 b/share/man/man9/VOP_GETEXTATTR.9
index 0971c27..cf00d26 100644
--- a/share/man/man9/VOP_GETEXTATTR.9
+++ b/share/man/man9/VOP_GETEXTATTR.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 23, 1999
-.Os
.Dt VOP_GETEXTATTR 9
+.Os
.Sh NAME
.Nm VOP_GETEXTATTR
.Nd retrieve named extended attribute from a vnode
diff --git a/share/man/man9/VOP_GETPAGES.9 b/share/man/man9/VOP_GETPAGES.9
index ffac609..ab0afe8 100644
--- a/share/man/man9/VOP_GETPAGES.9
+++ b/share/man/man9/VOP_GETPAGES.9
@@ -30,8 +30,8 @@
.\" $FreeBSD$
.\"
.Dd September 27, 2003
-.Os
.Dt VOP_GETPAGES 9
+.Os
.Sh NAME
.Nm VOP_GETPAGES ,
.Nm VOP_PUTPAGES
diff --git a/share/man/man9/VOP_GETVOBJECT.9 b/share/man/man9/VOP_GETVOBJECT.9
index e2e0ba4..2490da7 100644
--- a/share/man/man9/VOP_GETVOBJECT.9
+++ b/share/man/man9/VOP_GETVOBJECT.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd September 10, 2000
-.Os
.Dt VOP_CREATEVOBJECT 9
+.Os
.Sh NAME
.Nm VOP_CREATEVOBJECT ,
.Nm VOP_DESTROYVOBJECT ,
diff --git a/share/man/man9/VOP_INACTIVE.9 b/share/man/man9/VOP_INACTIVE.9
index 75bd53b..2f1e4ed 100644
--- a/share/man/man9/VOP_INACTIVE.9
+++ b/share/man/man9/VOP_INACTIVE.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_INACTIVE 9
+.Os
.Sh NAME
.Nm VOP_INACTIVE ,
.Nm VOP_RECLAIM
diff --git a/share/man/man9/VOP_IOCTL.9 b/share/man/man9/VOP_IOCTL.9
index 7b45484..ba12081 100644
--- a/share/man/man9/VOP_IOCTL.9
+++ b/share/man/man9/VOP_IOCTL.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_IOCTL 9
+.Os
.Sh NAME
.Nm VOP_IOCTL
.Nd device specific control
diff --git a/share/man/man9/VOP_LINK.9 b/share/man/man9/VOP_LINK.9
index b7fbb7b..f5b7c68 100644
--- a/share/man/man9/VOP_LINK.9
+++ b/share/man/man9/VOP_LINK.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_LINK 9
+.Os
.Sh NAME
.Nm VOP_LINK
.Nd create a new name for a file
diff --git a/share/man/man9/VOP_LISTEXTATTR.9 b/share/man/man9/VOP_LISTEXTATTR.9
index 4c8b744..cca875d 100644
--- a/share/man/man9/VOP_LISTEXTATTR.9
+++ b/share/man/man9/VOP_LISTEXTATTR.9
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd August 19, 2005
-.Os
.Dt VOP_LISTEXTATTR 9
+.Os
.Sh NAME
.Nm VOP_LISTEXTATTR
.Nd retrieve a list of named extended attribute from a vnode
diff --git a/share/man/man9/VOP_LOCK.9 b/share/man/man9/VOP_LOCK.9
index 6c54a38..b4fdc7a 100644
--- a/share/man/man9/VOP_LOCK.9
+++ b/share/man/man9/VOP_LOCK.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd February 25, 2008
-.Os
.Dt VOP_LOCK 9
+.Os
.Sh NAME
.Nm VOP_LOCK ,
.Nm VOP_UNLOCK ,
diff --git a/share/man/man9/VOP_LOOKUP.9 b/share/man/man9/VOP_LOOKUP.9
index ba5a260..64023f4 100644
--- a/share/man/man9/VOP_LOOKUP.9
+++ b/share/man/man9/VOP_LOOKUP.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd November 24, 1997
-.Os
.Dt VOP_LOOKUP 9
+.Os
.Sh NAME
.Nm VOP_LOOKUP
.Nd lookup a component of a pathname
diff --git a/share/man/man9/VOP_OPENCLOSE.9 b/share/man/man9/VOP_OPENCLOSE.9
index 7430da7..5442e32 100644
--- a/share/man/man9/VOP_OPENCLOSE.9
+++ b/share/man/man9/VOP_OPENCLOSE.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd December 2, 2009
-.Os
.Dt VOP_OPEN 9
+.Os
.Sh NAME
.Nm VOP_OPEN ,
.Nm VOP_CLOSE
diff --git a/share/man/man9/VOP_PATHCONF.9 b/share/man/man9/VOP_PATHCONF.9
index 056f647..38fed83 100644
--- a/share/man/man9/VOP_PATHCONF.9
+++ b/share/man/man9/VOP_PATHCONF.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_PATHCONF 9
+.Os
.Sh NAME
.Nm VOP_PATHCONF
.Nd return POSIX pathconf information
diff --git a/share/man/man9/VOP_PRINT.9 b/share/man/man9/VOP_PRINT.9
index 2da85f9..c8188fc 100644
--- a/share/man/man9/VOP_PRINT.9
+++ b/share/man/man9/VOP_PRINT.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_PRINT 9
+.Os
.Sh NAME
.Nm VOP_PRINT
.Nd print debugging information
diff --git a/share/man/man9/VOP_RDWR.9 b/share/man/man9/VOP_RDWR.9
index b010523..eb1af78 100644
--- a/share/man/man9/VOP_RDWR.9
+++ b/share/man/man9/VOP_RDWR.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_RDWR 9
+.Os
.Sh NAME
.Nm VOP_READ ,
.Nm VOP_WRITE
diff --git a/share/man/man9/VOP_READDIR.9 b/share/man/man9/VOP_READDIR.9
index 5b94438..057600e 100644
--- a/share/man/man9/VOP_READDIR.9
+++ b/share/man/man9/VOP_READDIR.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_READDIR 9
+.Os
.Sh NAME
.Nm VOP_READDIR
.Nd read contents of a directory
diff --git a/share/man/man9/VOP_READLINK.9 b/share/man/man9/VOP_READLINK.9
index f98222f..c1883c1 100644
--- a/share/man/man9/VOP_READLINK.9
+++ b/share/man/man9/VOP_READLINK.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_READLINK 9
+.Os
.Sh NAME
.Nm VOP_READLINK
.Nd read the target of a symbolic link
diff --git a/share/man/man9/VOP_REALLOCBLKS.9 b/share/man/man9/VOP_REALLOCBLKS.9
index 9209844..d38caf1 100644
--- a/share/man/man9/VOP_REALLOCBLKS.9
+++ b/share/man/man9/VOP_REALLOCBLKS.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_REALLOCBLKS 9
+.Os
.Sh NAME
.Nm VOP_REALLOCBLKS
.Nd rearrange blocks in a file to be contiguous
diff --git a/share/man/man9/VOP_REMOVE.9 b/share/man/man9/VOP_REMOVE.9
index 0a10ed2..38e3b06 100644
--- a/share/man/man9/VOP_REMOVE.9
+++ b/share/man/man9/VOP_REMOVE.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_REMOVE 9
+.Os
.Sh NAME
.Nm VOP_REMOVE ,
.Nm VOP_RMDIR
diff --git a/share/man/man9/VOP_RENAME.9 b/share/man/man9/VOP_RENAME.9
index 8797585..76bb0dc 100644
--- a/share/man/man9/VOP_RENAME.9
+++ b/share/man/man9/VOP_RENAME.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_RENAME 9
+.Os
.Sh NAME
.Nm VOP_RENAME
.Nd rename a file
diff --git a/share/man/man9/VOP_REVOKE.9 b/share/man/man9/VOP_REVOKE.9
index 6e04014..3557ce1 100644
--- a/share/man/man9/VOP_REVOKE.9
+++ b/share/man/man9/VOP_REVOKE.9
@@ -35,8 +35,8 @@
.\" $FreeBSD$
.\"
.Dd February 5, 2002
-.Os
.Dt VOP_REVOKE 9
+.Os
.Sh NAME
.Nm VOP_REVOKE
.Nd "revoke access to a device and its aliases"
diff --git a/share/man/man9/VOP_SETACL.9 b/share/man/man9/VOP_SETACL.9
index b6a7003..482d289 100644
--- a/share/man/man9/VOP_SETACL.9
+++ b/share/man/man9/VOP_SETACL.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 23, 1999
-.Os
.Dt VOP_SETACL 9
+.Os
.Sh NAME
.Nm VOP_SETACL
.Nd set the access control list for a vnode
diff --git a/share/man/man9/VOP_SETEXTATTR.9 b/share/man/man9/VOP_SETEXTATTR.9
index ccb8aaa..4bc5387 100644
--- a/share/man/man9/VOP_SETEXTATTR.9
+++ b/share/man/man9/VOP_SETEXTATTR.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 23, 1999
-.Os
.Dt VOP_SETEXTATTR 9
+.Os
.Sh NAME
.Nm VOP_SETEXTATTR
.Nd set named extended attribute for a vnode
diff --git a/share/man/man9/VOP_STRATEGY.9 b/share/man/man9/VOP_STRATEGY.9
index 8c4fbac..33d9fb8 100644
--- a/share/man/man9/VOP_STRATEGY.9
+++ b/share/man/man9/VOP_STRATEGY.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VOP_STRATEGY 9
+.Os
.Sh NAME
.Nm VOP_STRATEGY
.Nd read or write a file system buffer
diff --git a/share/man/man9/VOP_VPTOCNP.9 b/share/man/man9/VOP_VPTOCNP.9
index 892b4a6..7858215 100644
--- a/share/man/man9/VOP_VPTOCNP.9
+++ b/share/man/man9/VOP_VPTOCNP.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd December 7, 2008
-.Os
.Dt VOP_VPTOCNP 9
+.Os
.Sh NAME
.Nm VOP_VPTOCNP
.Nd translate a vnode to its component name
diff --git a/share/man/man9/VOP_VPTOFH.9 b/share/man/man9/VOP_VPTOFH.9
index 36e703d..3619a7b 100644
--- a/share/man/man9/VOP_VPTOFH.9
+++ b/share/man/man9/VOP_VPTOFH.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd February 16, 2007
-.Os
.Dt VOP_VPTOFH 9
+.Os
.Sh NAME
.Nm VOP_VPTOFH
.Nd turn a vnode into an NFS filehandle
diff --git a/share/man/man9/accept_filter.9 b/share/man/man9/accept_filter.9
index 4a7d239..3f89a0c 100644
--- a/share/man/man9/accept_filter.9
+++ b/share/man/man9/accept_filter.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd June 25, 2000
-.Os
.Dt ACCEPT_FILTER 9
+.Os
.Sh NAME
.Nm accept_filter ,
.Nm accept_filt_add ,
diff --git a/share/man/man9/accf_data.9 b/share/man/man9/accf_data.9
index 836deba..2d3b7a2 100644
--- a/share/man/man9/accf_data.9
+++ b/share/man/man9/accf_data.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd November 15, 2000
-.Os
.Dt ACCF_DATA 9
+.Os
.Sh NAME
.Nm accf_data
.Nd buffer incoming connections until data arrives
diff --git a/share/man/man9/accf_dns.9 b/share/man/man9/accf_dns.9
index f4b1563..4a2dad2 100644
--- a/share/man/man9/accf_dns.9
+++ b/share/man/man9/accf_dns.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd July 16, 2008
-.Os
.Dt ACCF_DNS 9
+.Os
.Sh NAME
.Nm accf_dns
.Nd buffer incoming DNS requests until the whole first request is present
diff --git a/share/man/man9/accf_http.9 b/share/man/man9/accf_http.9
index a75321c..2a34060 100644
--- a/share/man/man9/accf_http.9
+++ b/share/man/man9/accf_http.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\" "
.Dd November 15, 2000
-.Os
.Dt ACCF_HTTP 9
+.Os
.Sh NAME
.Nm accf_http
.Nd "buffer incoming connections until a certain complete HTTP requests arrive"
diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9
index c5192fc..21640bd 100644
--- a/share/man/man9/acl.9
+++ b/share/man/man9/acl.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd September 18, 2009
-.Os
.Dt ACL 9
+.Os
.Sh NAME
.Nm acl
.Nd virtual file system access control lists
diff --git a/share/man/man9/alq.9 b/share/man/man9/alq.9
index ec6ef26..65c2d07 100644
--- a/share/man/man9/alq.9
+++ b/share/man/man9/alq.9
@@ -1,7 +1,13 @@
.\"
.\" Copyright (c) 2003 Hiten Pandya <hmp@FreeBSD.org>
+.\" Copyright (c) 2009-2010 The FreeBSD Foundation
.\" All rights reserved.
.\"
+.\" Portions of this software were developed at the Centre for Advanced
+.\" Internet Architectures, Swinburne University of Technology, Melbourne,
+.\" Australia by Lawrence Stewart under sponsorship from the FreeBSD
+.\" Foundation.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
@@ -25,21 +31,34 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 16, 2003
+.Dd April 26, 2010
.Dt ALQ 9
.Os
.Sh NAME
.Nm alq ,
+.Nm alq_open_flags ,
.Nm alq_open ,
+.Nm alq_writen ,
.Nm alq_write ,
.Nm alq_flush ,
.Nm alq_close ,
+.Nm alq_getn ,
.Nm alq_get ,
+.Nm alq_post_flags ,
.Nm alq_post
.Nd Asynchronous Logging Queues
.Sh SYNOPSIS
.In sys/alq.h
.Ft int
+.Fo alq_open_flags
+.Fa "struct alq **app"
+.Fa "const char *file"
+.Fa "struct ucred *cred"
+.Fa "int cmode"
+.Fa "int size"
+.Fa "int flags"
+.Fc
+.Ft int
.Fo alq_open
.Fa "struct alq **app"
.Fa "const char *file"
@@ -49,19 +68,25 @@
.Fa "int count"
.Fc
.Ft int
-.Fn alq_write "struct alq *alq" "void *data" "int waitok"
+.Fn alq_writen "struct alq *alq" "void *data" "int len" "int flags"
+.Ft int
+.Fn alq_write "struct alq *alq" "void *data" "int flags"
.Ft void
.Fn alq_flush "struct alq *alq"
.Ft void
.Fn alq_close "struct alq *alq"
.Ft struct ale *
-.Fn alq_get "struct alq *alq" "int waitok"
+.Fn alq_getn "struct alq *alq" "int len" "int flags"
+.Ft struct ale *
+.Fn alq_get "struct alq *alq" "int flags"
+.Ft void
+.Fn alq_post_flags "struct alq *alq" "struct ale *ale" "int flags"
.Ft void
.Fn alq_post "struct alq *alq" "struct ale *ale"
.Sh DESCRIPTION
The
.Nm
-facility provides an asynchronous fixed length recording
+facility provides an asynchronous fixed or variable length recording
mechanism, known as Asynchronous Logging Queues.
It can record to any
.Xr vnode 9 ,
@@ -81,26 +106,37 @@ is defined as
which has the following members:
.Bd -literal -offset indent
struct ale {
- struct ale *ae_next; /* Next Entry */
- char *ae_data; /* Entry buffer */
- int ae_flags; /* Entry flags */
+ intptr_t ae_bytesused; /* # bytes written to ALE. */
+ char *ae_data; /* Write ptr. */
+ int ae_pad; /* Unused, compat. */
};
.Ed
.Pp
-The
-.Va ae_flags
-field is for internal use, clients of the
+An
.Nm
-interface should not modify this field.
-Behaviour is undefined if this field is modified.
+can be created in either fixed or variable length mode.
+A variable length
+.Nm
+accommodates writes of varying length using
+.Fn alq_writen
+and
+.Fn alq_getn .
+A fixed length
+.Nm
+accommodates a fixed number of writes using
+.Fn alq_write
+and
+.Fn alq_get ,
+each of fixed size (set at queue creation time).
+Fixed length mode is deprecated in favour of variable length mode.
.Sh FUNCTIONS
The
-.Fn alq_open
-function creates a new logging queue.
+.Fn alq_open_flags
+function creates a new variable length asynchronous logging queue.
The
.Fa file
-argument is the name of the file to open for logging; if the file does not
-yet exist,
+argument is the name of the file to open for logging.
+If the file does not yet exist,
.Fn alq_open
will attempt to create it.
The
@@ -112,33 +148,99 @@ as the requested creation mode, to be used if the file will be created by
Consumers of this API may wish to pass
.Dv ALQ_DEFAULT_CMODE ,
a default creation mode suitable for most applications.
-The argument
+The
.Fa cred
-specifies the credentials to use when opening and performing I/O on the file.
-The size of each entry in the queue is determined by
-.Fa size .
+argument specifies the credentials to use when opening and performing I/O on the file.
The
+.Fa size
+argument sets the size (in bytes) of the underlying queue.
+The ALQ_ORDERED flag may be passed in via
+.Fa flags
+to indicate that the ordering of writer threads waiting for a busy
+.Nm
+to free up resources should be preserved.
+.Pp
+The deprecated
+.Fn alq_open
+function is implemented as a wrapper around
+.Fn alq_open_flags
+to provide backwards compatibility to consumers that have not been updated to
+utilise the newer
+.Fn alq_open_flags
+function.
+It passes all arguments through to
+.Fn alq_open_flags
+untouched except for
+.Fa size
+and
+.Fa count ,
+and sets
+.Fa flags
+to 0.
+To create a variable length mode
+.Nm ,
+the
+.Fa size
+argument should be set to the size (in bytes) of the underlying queue and the
+.Fa count
+argument should be set to 0.
+To create a fixed length mode
+.Nm ,
+the
+.Fa size
+argument should be set to the size (in bytes) of each write and the
.Fa count
-argument determines the number of items to be stored in the
-asynchronous queue over an approximate period of a disk
-write operation.
+argument should be set to the number of
+.Fa size
+byte chunks to reserve capacity for.
.Pp
The
-.Fn alq_write
+.Fn alq_writen
function writes
+.Fa len
+bytes from
.Fa data
-to the designated queue,
+to the designated variable length mode queue
.Fa alq .
-In the event that
-.Fn alq_write
-could not write the entry immediately, and
+If
+.Fn alq_writen
+could not write the entry immediately and
.Dv ALQ_WAITOK
-is passed to
-.Fa waitok ,
-then
+is set in
+.Fa flags ,
+the function will be allowed to
+.Xr msleep_spin 9
+with the
+.Dq Li alqwnord
+or
+.Dq Li alqwnres
+wait message.
+A write will automatically schedule the queue
+.Fa alq
+to be flushed to disk.
+This behaviour can be controlled by passing ALQ_NOACTIVATE via
+.Fa flags
+to indicate that the write should not schedule
+.Fa alq
+to be flushed to disk.
+.Pp
+The deprecated
+.Fn alq_write
+function is implemented as a wrapper around
+.Fn alq_writen
+to provide backwards compatibility to consumers that have not been updated to
+utilise variable length mode queues.
+The function will write
+.Fa size
+bytes of data (where
+.Fa size
+was specified at queue creation time) from the
+.Fa data
+buffer to the
+.Fa alq .
+Note that it is an error to call
.Fn alq_write
-will be allowed to
-.Xr tsleep 9 .
+on a variable length mode queue.
.Pp
The
.Fn alq_flush
@@ -146,61 +248,136 @@ function is used for flushing
.Fa alq
to the log medium that was passed to
.Fn alq_open .
+If
+.Fa alq
+has data to flush and is not already in the process of being flushed, the
+function will block doing IO.
+Otherwise, the function will return immediately.
.Pp
The
.Fn alq_close
-function will close the asynchronous logging queue,
-.Fa alq ,
+function will close the asynchronous logging queue
+.Fa alq
and flush all pending write requests to the log medium.
It will free all resources that were previously allocated.
.Pp
The
-.Fn alq_get
-function returns the next available asynchronous logging entry
-from the queue,
-.Fa alq .
-This function leaves the queue in a locked state, until a subsequent
+.Fn alq_getn
+function returns an asynchronous log entry from
+.Fa alq ,
+initialised to point at a buffer capable of receiving
+.Fa len
+bytes of data.
+This function leaves
+.Fa alq
+in a locked state, until a subsequent
.Fn alq_post
+or
+.Fn alq_post_flags
call is made.
-In the event that
-.Fn alq_get
-could not retrieve an entry immediately, it will
-.Xr tsleep 9
+If
+.Fn alq_getn
+could not obtain
+.Fa len
+bytes of buffer immediately and
+.Dv ALQ_WAITOK
+is set in
+.Fa flags ,
+the function will be allowed to
+.Xr msleep_spin 9
with the
-.Dq Li alqget
+.Dq Li alqgnord
+or
+.Dq Li alqgnres
wait message.
+The caller can choose to write less than
+.Fa len
+bytes of data to the returned asynchronous log entry by setting the entry's
+ae_bytesused field to the number of bytes actually written.
+This must be done prior to calling
+.Fn alq_post .
.Pp
-The
-.Fn alq_post
-function schedules the asynchronous logging entry,
-.Fa ale ,
-which is retrieved using the
+The deprecated
.Fn alq_get
-function,
-for writing to the asynchronous logging queue,
+function is implemented as a wrapper around
+.Fn alq_getn
+to provide backwards compatibility to consumers that have not been updated to
+utilise variable length mode queues.
+The asynchronous log entry returned will be initialised to point at a buffer
+capable of receiving
+.Fa size
+bytes of data (where
+.Fa size
+was specified at queue creation time).
+Note that it is an error to call
+.Fn alq_get
+on a variable length mode queue.
+.Pp
+The
+.Fn alq_post_flags
+function schedules the asynchronous log entry
+.Fa ale
+(obtained from
+.Fn alq_getn
+or
+.Fn alq_get )
+for writing to
.Fa alq .
-This function leaves the queue,
-.Fa alq ,
+The ALQ_NOACTIVATE flag may be passed in via
+.Fa flags
+to indicate that the queue should not be immediately scheduled to be flushed to
+disk.
+This function leaves
+.Fa alq
in an unlocked state.
+.Pp
+The
+.Fn alq_post
+function is implemented as a wrapper around
+.Fn alq_post_flags
+to provide backwards compatibility to consumers that have not been updated to
+utilise the newer
+.Fn alq_post_flags
+function.
+It simply passes all arguments through to
+.Fn alq_post_flags
+untouched, and sets
+.Fa flags
+to 0.
.Sh IMPLEMENTATION NOTES
The
+.Fn alq_writen
+and
.Fn alq_write
-function is a wrapper around the
+functions both perform a
+.Xr bcopy 3
+from the supplied
+.Fa data
+buffer into the underlying
+.Nm
+buffer.
+Performance critical code paths may wish to consider using
+.Fn alq_getn
+(variable length queues) or
+.Fn alq_get
+(fixed length queues) to avoid the extra memory copy. Note that a queue
+remains locked between calls to
+.Fn alq_getn
+or
.Fn alq_get
and
.Fn alq_post
-functions; by using these functions separately, a call
-to
-.Fn bcopy
-can be avoided for performance critical code paths.
+or
+.Fn alq_post_flags ,
+so this method of writing to a queue is unsuitable for situations where the
+time between calls may be substantial.
.Sh LOCKING
-Each asynchronous queue is protected by a spin mutex.
+Each asynchronous logging queue is protected by a spin mutex.
.Pp
Functions
-.Fn alq_flush ,
-.Fn alq_open
+.Fn alq_flush
and
-.Fn alq_post
+.Fn alq_open
may attempt to acquire an internal sleep mutex, and should
consequently not be used in contexts where sleeping is
not allowed.
@@ -214,32 +391,36 @@ if it fails to open
or else it returns 0.
.Pp
The
+.Fn alq_writen
+and
.Fn alq_write
-function returns
+functions return
.Er EWOULDBLOCK
if
.Dv ALQ_NOWAIT
-was provided as a value to
-.Fa waitok
-and either the queue is full, or when the system is shutting down.
+was set in
+.Fa flags
+and either the queue is full or the system is shutting down.
.Pp
The
+.Fn alq_getn
+and
.Fn alq_get
-function returns
-.Dv NULL ,
+functions return
+.Dv NULL
if
.Dv ALQ_NOWAIT
-was provided as a value to
-.Fa waitok
-and either the queue is full, or when the system is shutting down.
+was set in
+.Fa flags
+and either the queue is full or the system is shutting down.
.Pp
NOTE: invalid arguments to non-void functions will result in
undefined behaviour.
.Sh SEE ALSO
-.Xr syslog 3 ,
-.Xr kthread 9 ,
+.Xr kproc 9 ,
.Xr ktr 9 ,
-.Xr tsleep 9 ,
+.Xr msleep_spin 9 ,
+.Xr syslog 3 ,
.Xr vnode 9
.Sh HISTORY
The
@@ -250,7 +431,11 @@ Asynchronous Logging Queues (ALQ) facility first appeared in
The
.Nm
facility was written by
-.An Jeffrey Roberson Aq jeff@FreeBSD.org .
+.An Jeffrey Roberson Aq jeff@FreeBSD.org
+and extended by
+.An Lawrence Stewart Aq lstewart@freebsd.org .
.Pp
This manual page was written by
-.An Hiten Pandya Aq hmp@FreeBSD.org .
+.An Hiten Pandya Aq hmp@FreeBSD.org
+and revised by
+.An Lawrence Stewart Aq lstewart@freebsd.org .
diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9
index 0bc567c..94c4ba4 100644
--- a/share/man/man9/atomic.9
+++ b/share/man/man9/atomic.9
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd September 27, 2005
-.Os
.Dt ATOMIC 9
+.Os
.Sh NAME
.Nm atomic_add ,
.Nm atomic_clear ,
diff --git a/share/man/man9/cr_cansee.9 b/share/man/man9/cr_cansee.9
index 53823c1..c4cc2d4 100644
--- a/share/man/man9/cr_cansee.9
+++ b/share/man/man9/cr_cansee.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd November 19, 2006
-.Os
.Dt CR_CANSEE 9
+.Os
.Sh NAME
.Nm cr_cansee
.Nd "determine visibility of objects given their user credentials"
diff --git a/share/man/man9/cr_seeothergids.9 b/share/man/man9/cr_seeothergids.9
index 1f5f4ee..87fd139 100644
--- a/share/man/man9/cr_seeothergids.9
+++ b/share/man/man9/cr_seeothergids.9
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd November 11, 2003
-.Os
.Dt CR_SEEOTHERGIDS 9
+.Os
.Sh NAME
.Nm cr_seeothergids
.Nd determine visibility of objects given their group memberships
diff --git a/share/man/man9/cr_seeotheruids.9 b/share/man/man9/cr_seeotheruids.9
index e79363f..2066c40 100644
--- a/share/man/man9/cr_seeotheruids.9
+++ b/share/man/man9/cr_seeotheruids.9
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd November 11, 2003
-.Os
.Dt CR_SEEOTHERUIDS 9
+.Os
.Sh NAME
.Nm cr_seeotheruids
.Nd determine visibility of objects given their user credentials
diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9
index 0896d4d..fcdc5c4 100644
--- a/share/man/man9/devfs_set_cdevpriv.9
+++ b/share/man/man9/devfs_set_cdevpriv.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd September 8, 2008
-.Os
.Dt DEVFS_CDEVPRIV
+.Os
.Sh NAME
.Nm devfs_set_cdevpriv ,
.Nm devfs_get_cdevpriv ,
diff --git a/share/man/man9/devtoname.9 b/share/man/man9/devtoname.9
index 9a62a5e..f93e77b 100644
--- a/share/man/man9/devtoname.9
+++ b/share/man/man9/devtoname.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd September 25, 1999
-.Os
.Dt DEVTONAME 9
+.Os
.Sh NAME
.Nm devtoname
.Nd "converts dev_t data into a string indicating the device name"
diff --git a/share/man/man9/driver.9 b/share/man/man9/driver.9
index 0030915..960c9ae 100644
--- a/share/man/man9/driver.9
+++ b/share/man/man9/driver.9
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 16, 1998
+.Dd March 3, 2010
.Dt DRIVER 9
.Os
.Sh NAME
@@ -37,7 +37,9 @@
.Sh SYNOPSIS
.Bd -literal
#include <sys/param.h>
+#include <sys/kernel.h>
#include <sys/bus.h>
+#include <sys/module.h>
static int foo_probe(device_t);
static int foo_attach(device_t);
@@ -59,7 +61,7 @@ static device_method_t foo_methods[] = {
{ 0, 0 }
};
-static driver_t foo_driver {
+static driver_t foo_driver = {
"foo",
foo_methods,
sizeof(struct foo_softc)
@@ -67,7 +69,7 @@ static driver_t foo_driver {
static devclass_t foo_devclass;
-DRIVER_MODULE(foo, bogo, foo_driver, foo_devclass, 0, 0);
+DRIVER_MODULE(foo, bogo, foo_driver, foo_devclass, NULL, NULL);
.Ed
.Sh DESCRIPTION
Each driver in the kernel is described by a
diff --git a/share/man/man9/extattr.9 b/share/man/man9/extattr.9
index 9c74a60..bf79487 100644
--- a/share/man/man9/extattr.9
+++ b/share/man/man9/extattr.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 23, 1999
-.Os
.Dt EXTATTR 9
+.Os
.Sh NAME
.Nm extattr
.Nd virtual file system named extended attributes
diff --git a/share/man/man9/fail.9 b/share/man/man9/fail.9
index ce43346..81292f5 100644
--- a/share/man/man9/fail.9
+++ b/share/man/man9/fail.9
@@ -84,7 +84,7 @@ below.
The remaining
.Fn KFAIL_POINT_*
macros are wrappers around common error injection paths:
-.Bl -tag -width 8
+.Bl -inset
.It Fn KFAIL_POINT_RETURN parent name
is the equivalent of
.Sy KFAIL_POINT_CODE(..., return RETURN_VALUE)
@@ -96,8 +96,7 @@ is the equivalent of
.Sy KFAIL_POINT_CODE(..., error_var = RETURN_VALUE)
.It Fn KFAIL_POINT_GOTO parent name error_var label
is the equivalent of
-.Sy KFAIL_POINT_CODE(...,
- { error_var = RETURN_VALUE; goto label;})
+.Sy KFAIL_POINT_CODE(..., { error_var = RETURN_VALUE; goto label;})
.El
.Sh SYSCTL VARIABLES
The
diff --git a/share/man/man9/firmware.9 b/share/man/man9/firmware.9
index 87d43e3..5254f24 100644
--- a/share/man/man9/firmware.9
+++ b/share/man/man9/firmware.9
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 2, 2008
-.Os
.Dt FIRMWARE 9
+.Os
.Sh NAME
.Nm firmware_register ,
.Nm firmware_unregister ,
diff --git a/share/man/man9/hexdump.9 b/share/man/man9/hexdump.9
index 656299c..a731ab5 100644
--- a/share/man/man9/hexdump.9
+++ b/share/man/man9/hexdump.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd December 7, 2003
-.Os
.Dt HEXDUMP 9
+.Os
.Sh NAME
.Nm hexdump
.Nd "dump a block of bytes to the console in hexadecimal form"
diff --git a/share/man/man9/ieee80211.9 b/share/man/man9/ieee80211.9
index ba0137d..ae92d5e 100644
--- a/share/man/man9/ieee80211.9
+++ b/share/man/man9/ieee80211.9
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 4, 2009
+.Dd March 29, 2010
.Dt NET80211 9
.Os
.Sh NAME
@@ -551,11 +551,18 @@ Device supports Reduced Inter Frame Spacing (RIFS).
.Sh SEE ALSO
.Xr ioctl 2 ,
.Xr ndis 4 ,
+.Xr ieee80211_amrr 9 ,
+.Xr ieee80211_beacon 9 ,
+.Xr ieee80211_bmiss 9 ,
+.Xr ieee80211_crypto 9 ,
+.Xr ieee80211_ddb 9 ,
.Xr ieee80211_input 9 ,
-.Xr ieee80211_input_all 9 ,
-.Xr ieee80211_scan_next 9 ,
-.Xr ieee80211_recv_action 9 ,
-.Xr ieee80211_send_action 9 ,
-.Xr ieee80211_radiotap_attach 9 ,
+.Xr ieee80211_node 9 ,
+.Xr ieee80211_output 9 ,
+.Xr ieee80211_proto 9 ,
+.Xr ieee80211_radiotap 9 ,
+.Xr ieee80211_regdomain 9 ,
+.Xr ieee80211_scan 9 ,
+.Xr ieee80211_vap 9 ,
.Xr ifnet 9 ,
.Xr malloc 9
diff --git a/share/man/man9/ieee80211_crypto.9 b/share/man/man9/ieee80211_crypto.9
index 92fe6bb..e21bc26 100644
--- a/share/man/man9/ieee80211_crypto.9
+++ b/share/man/man9/ieee80211_crypto.9
@@ -27,7 +27,7 @@
.\" $FreeBSD$
.\" $Id: ieee80211_crypto.9,v 1.3 2004/03/04 10:42:56 bruce Exp $
.\"
-.Dd August 4, 2009
+.Dd March 29, 2010
.Dt IEEE80211_CRYPTO 9
.Os
.Sh NAME
@@ -253,6 +253,7 @@ and
These calls also synchronize hardware key state update
when receive traffic is active.
.Sh SEE ALSO
+.Xr ieee80211 9 ,
.Xr ioctl 2 ,
.Xr wlan_ccmp 4 ,
.Xr wlan_tkip 4 ,
diff --git a/share/man/man9/ieee80211_node.9 b/share/man/man9/ieee80211_node.9
index 5d9d4ad..be0b506 100644
--- a/share/man/man9/ieee80211_node.9
+++ b/share/man/man9/ieee80211_node.9
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 4, 2009
+.Dd March 29, 2010
.Dt IEEE80211_NODE 9
.Os
.Sh NAME
@@ -246,6 +246,6 @@ If the specified index is
.Dv IEEE80211_KEYIX_NONE
then a normal lookup is done without a table update.
.Sh SEE ALSO
-.Xr ddb 9
+.Xr ddb 9 ,
.Xr ieee80211 9 ,
.Xr ieee80211_proto 9
diff --git a/share/man/man9/ieee80211_output.9 b/share/man/man9/ieee80211_output.9
index 61e4800..82393bd 100644
--- a/share/man/man9/ieee80211_output.9
+++ b/share/man/man9/ieee80211_output.9
@@ -27,7 +27,7 @@
.\" $FreeBSD$
.\" $Id: ieee80211_output.9,v 1.5 2004/03/04 12:31:18 bruce Exp $
.\"
-.Dd August 4, 2009
+.Dd March 29, 2010
.Dt IEEE80211_OUTPUT 9
.Os
.Sh NAME
@@ -189,6 +189,6 @@ a device may not report if an ACK frame is received and/or a device may queue
transmit requests in its hardware and only report status on whether
the frame was successfully queued.
.Sh SEE ALSO
-.Xr bpf 4
+.Xr bpf 4 ,
.Xr ieee80211 9 ,
.Xr ifnet 9
diff --git a/share/man/man9/ieee80211_scan.9 b/share/man/man9/ieee80211_scan.9
index 018f70f..b2b77cf 100644
--- a/share/man/man9/ieee80211_scan.9
+++ b/share/man/man9/ieee80211_scan.9
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 20, 2010
+.Dd March 29, 2010
.Dt IEEE80211_SCAN 9
.Os
.Sh NAME
@@ -346,5 +346,5 @@ applications through the
request.
.Sh SEE ALSO
.Xr ioctl 2 ,
-.Xr ieee80211 9 .
+.Xr ieee80211 9 ,
.Xr ieee80211_proto 9
diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9
index 7a3a3d9..55e7541 100644
--- a/share/man/man9/ifnet.9
+++ b/share/man/man9/ifnet.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd December 1, 2009
-.Os
.Dt IFNET 9
+.Os
.Sh NAME
.Nm ifnet ,
.Nm ifaddr ,
diff --git a/share/man/man9/kernacc.9 b/share/man/man9/kernacc.9
index 8a28b080..f6d60dc 100644
--- a/share/man/man9/kernacc.9
+++ b/share/man/man9/kernacc.9
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man9/make_dev.9 b/share/man/man9/make_dev.9
index b39ca8b..50f7d46 100644
--- a/share/man/man9/make_dev.9
+++ b/share/man/man9/make_dev.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd September 28, 2008
-.Os
.Dt MAKE_DEV 9
+.Os
.Sh NAME
.Nm make_dev ,
.Nm make_dev_cred ,
diff --git a/share/man/man9/malloc.9 b/share/man/man9/malloc.9
index 76aa83a..ff6b4d2 100644
--- a/share/man/man9/malloc.9
+++ b/share/man/man9/malloc.9
@@ -13,13 +13,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man9/mi_switch.9 b/share/man/man9/mi_switch.9
index fe97bc5..2f82b5a 100644
--- a/share/man/man9/mi_switch.9
+++ b/share/man/man9/mi_switch.9
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man9/namei.9 b/share/man/man9/namei.9
index 0325c36..33f753f 100644
--- a/share/man/man9/namei.9
+++ b/share/man/man9/namei.9
@@ -34,8 +34,8 @@
.\" $FreeBSD$
.\"
.Dd September 21, 2005
-.Os
.Dt NAMEI 9
+.Os
.Sh NAME
.Nm namei ,
.Nm NDINIT ,
diff --git a/share/man/man9/p_candebug.9 b/share/man/man9/p_candebug.9
index 2127fbc..6249a4d 100644
--- a/share/man/man9/p_candebug.9
+++ b/share/man/man9/p_candebug.9
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd November 19, 2006
-.Os
.Dt P_CANDEBUG 9
+.Os
.Sh NAME
.Nm p_candebug
.Nd determine debuggability of a process
diff --git a/share/man/man9/p_cansee.9 b/share/man/man9/p_cansee.9
index 92ffeea..fafe9d3 100644
--- a/share/man/man9/p_cansee.9
+++ b/share/man/man9/p_cansee.9
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd November 19, 2006
-.Os
.Dt P_CANSEE 9
+.Os
.Sh NAME
.Nm p_cansee
.Nd determine visibility of a process
diff --git a/share/man/man9/pfind.9 b/share/man/man9/pfind.9
index 58adab3..dfd15b8 100644
--- a/share/man/man9/pfind.9
+++ b/share/man/man9/pfind.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd July 11, 2001
-.Os
.Dt PFIND 9
+.Os
.Sh NAME
.Nm pfind , zpfind
.Nd locate a process by number
diff --git a/share/man/man9/pgfind.9 b/share/man/man9/pgfind.9
index 96abd0a..a304987 100644
--- a/share/man/man9/pgfind.9
+++ b/share/man/man9/pgfind.9
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd August 8, 2001
-.Os
.Dt PGFIND 9
+.Os
.Sh NAME
.Nm pgfind
.Nd "locate a process group by number"
diff --git a/share/man/man9/physio.9 b/share/man/man9/physio.9
index c4f24a8..7d7174e 100644
--- a/share/man/man9/physio.9
+++ b/share/man/man9/physio.9
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man9/prison_check.9 b/share/man/man9/prison_check.9
index a8ba040..68e90fb 100644
--- a/share/man/man9/prison_check.9
+++ b/share/man/man9/prison_check.9
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd December 11, 2003
-.Os
.Dt PRISON_CHECK 9
+.Os
.Sh NAME
.Nm prison_check
.Nd determine if two credentials belong to the same jail
diff --git a/share/man/man9/psignal.9 b/share/man/man9/psignal.9
index 16575f1..dd282a6 100644
--- a/share/man/man9/psignal.9
+++ b/share/man/man9/psignal.9
@@ -12,13 +12,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man9/random.9 b/share/man/man9/random.9
index 426774e..1d7c7da 100644
--- a/share/man/man9/random.9
+++ b/share/man/man9/random.9
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\" "
.Dd September 25, 2000
-.Os
.Dt RANDOM 9
+.Os
.Sh NAME
.Nm arc4rand ,
.Nm arc4random ,
diff --git a/share/man/man9/rijndael.9 b/share/man/man9/rijndael.9
index 5ee4239..48b402b 100644
--- a/share/man/man9/rijndael.9
+++ b/share/man/man9/rijndael.9
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\" "
.Dd February 6, 2002
-.Os
.Dt RIJNDAEL 9
+.Os
.Sh NAME
.Nm rijndael_makeKey ,
.Nm rijndael_cipherInit ,
diff --git a/share/man/man9/rtalloc.9 b/share/man/man9/rtalloc.9
index cbd2c5e..31d5ebb 100644
--- a/share/man/man9/rtalloc.9
+++ b/share/man/man9/rtalloc.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd December 11, 2008
-.Os
.Dt RTALLOC 9
+.Os
.Sh NAME
.Nm rtalloc ,
.Nm rtalloc_ign ,
diff --git a/share/man/man9/rtentry.9 b/share/man/man9/rtentry.9
index 0e25b21..d7e6953 100644
--- a/share/man/man9/rtentry.9
+++ b/share/man/man9/rtentry.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd December 11, 2008
-.Os
.Dt RTENTRY 9
+.Os
.Sh NAME
.Nm rtentry
.Nd structure of an entry in the kernel routing table
diff --git a/share/man/man9/sleep.9 b/share/man/man9/sleep.9
index 8fb7f88..91a2121 100644
--- a/share/man/man9/sleep.9
+++ b/share/man/man9/sleep.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd December 12, 2009
-.Os
.Dt SLEEP 9
+.Os
.Sh NAME
.Nm msleep ,
.Nm msleep_spin ,
diff --git a/share/man/man9/spl.9 b/share/man/man9/spl.9
index fe4bec2..95a5fc2 100644
--- a/share/man/man9/spl.9
+++ b/share/man/man9/spl.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd July 21, 1996
-.Os
.Dt SPL 9
+.Os
.Sh NAME
.Nm splbio ,
.Nm splclock ,
diff --git a/share/man/man9/stack.9 b/share/man/man9/stack.9
index 6567641..2c2b762 100644
--- a/share/man/man9/stack.9
+++ b/share/man/man9/stack.9
@@ -34,7 +34,7 @@
.Nm stack
.Nd kernel thread stack tracing routines
.Sh SYNOPSIS
-.In sys/param.h>
+.In sys/param.h
.In sys/stack.h
In the kernel configuration file:
.Cd "options DDB"
diff --git a/share/man/man9/timeout.9 b/share/man/man9/timeout.9
index e6d911d..b936087 100644
--- a/share/man/man9/timeout.9
+++ b/share/man/man9/timeout.9
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/man/man9/uio.9 b/share/man/man9/uio.9
index b23e9fd..0ddb2d3 100644
--- a/share/man/man9/uio.9
+++ b/share/man/man9/uio.9
@@ -25,9 +25,9 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 30, 2007
-.Os
+.Dd March 21, 2010
.Dt UIO 9
+.Os
.Sh NAME
.Nm uio ,
.Nm uiomove
@@ -41,7 +41,7 @@ struct uio {
struct iovec *uio_iov; /* scatter/gather list */
int uio_iovcnt; /* length of scatter/gather list */
off_t uio_offset; /* offset in target object */
- int uio_resid; /* remaining bytes to copy */
+ ssize_t uio_resid; /* remaining bytes to copy */
enum uio_seg uio_segflg; /* address space */
enum uio_rw uio_rw; /* operation */
struct thread *uio_td; /* owner */
diff --git a/share/man/man9/usbdi.9 b/share/man/man9/usbdi.9
index 100c53c..a26e026 100644
--- a/share/man/man9/usbdi.9
+++ b/share/man/man9/usbdi.9
@@ -25,8 +25,8 @@
.\"
.\" $FreeBSD$
.Dd June 24, 2009
-.Os
.Dt USBDI 9
+.Os
.Sh NAME
.Nm usb_fifo_alloc_buffer ,
.Nm usb_fifo_attach ,
diff --git a/share/man/man9/vaccess.9 b/share/man/man9/vaccess.9
index a2e2ec5..4bf3774 100644
--- a/share/man/man9/vaccess.9
+++ b/share/man/man9/vaccess.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd September 18, 2009
-.Os
.Dt VACCESS 9
+.Os
.Sh NAME
.Nm vaccess
.Nd generate an access control decision using vnode parameters
diff --git a/share/man/man9/vaccess_acl_nfs4.9 b/share/man/man9/vaccess_acl_nfs4.9
index 32cbdb3..27b4cfa 100644
--- a/share/man/man9/vaccess_acl_nfs4.9
+++ b/share/man/man9/vaccess_acl_nfs4.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd September 18, 2009
-.Os
.Dt VACCESS_ACL_NFS4 9
+.Os
.Sh NAME
.Nm vaccess_acl_nfs4
.Nd generate a NFSv4 ACL access control decision using vnode parameters
diff --git a/share/man/man9/vaccess_acl_posix1e.9 b/share/man/man9/vaccess_acl_posix1e.9
index 0610511..dc857a8 100644
--- a/share/man/man9/vaccess_acl_posix1e.9
+++ b/share/man/man9/vaccess_acl_posix1e.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd August 22, 2001
-.Os
.Dt VACCESS_ACL_POSIX1E 9
+.Os
.Sh NAME
.Nm vaccess_acl_posix1e
.Nd generate a POSIX.1e ACL access control decision using vnode parameters
diff --git a/share/man/man9/vcount.9 b/share/man/man9/vcount.9
index 610891b..41263b9 100644
--- a/share/man/man9/vcount.9
+++ b/share/man/man9/vcount.9
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd February 6, 2001
-.Os
.Dt VCOUNT 9
+.Os
.Sh NAME
.Nm vcount ,
.Nm count_dev
diff --git a/share/man/man9/vfs_mount.9 b/share/man/man9/vfs_mount.9
index b64698c..47f6048 100644
--- a/share/man/man9/vfs_mount.9
+++ b/share/man/man9/vfs_mount.9
@@ -127,8 +127,7 @@ this call relies on a large number of other kernel services
whose errors it returns so this list may not be exhaustive.
.Sh SEE ALSO
.Xr mount 2 ,
-.Xr mount 8 ,
-.Xr vfs_mountedon 9
+.Xr mount 8
.Pp
.Va vfs.usermount
.Sh AUTHORS
diff --git a/share/man/man9/vget.9 b/share/man/man9/vget.9
index ef8fb10..1a7d16c 100644
--- a/share/man/man9/vget.9
+++ b/share/man/man9/vget.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VGET 9
+.Os
.Sh NAME
.Nm vget
.Nd get a vnode from the free list
diff --git a/share/man/man9/vm_map_entry_resize_free.9 b/share/man/man9/vm_map_entry_resize_free.9
index b037bcb..eaaec65 100644
--- a/share/man/man9/vm_map_entry_resize_free.9
+++ b/share/man/man9/vm_map_entry_resize_free.9
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd August 17, 2004
-.Os
.Dt VM_MAP_ENTRY_RESIZE_FREE 9
+.Os
.Sh NAME
.Nm vm_map_entry_resize_free
.Nd "vm map free space algorithm"
diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9
index 49a2cc7..cfc6f7d 100644
--- a/share/man/man9/vnode.9
+++ b/share/man/man9/vnode.9
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd February 13, 2010
-.Os
.Dt VNODE 9
+.Os
.Sh NAME
.Nm vnode
.Nd internal representation of a file or directory
diff --git a/share/man/man9/vput.9 b/share/man/man9/vput.9
index 47bee09..d915539 100644
--- a/share/man/man9/vput.9
+++ b/share/man/man9/vput.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VPUT 9
+.Os
.Sh NAME
.Nm vput
.Nd "decrement the use count for a vnode and unlock it"
diff --git a/share/man/man9/vref.9 b/share/man/man9/vref.9
index d979fb3..f21b9f2 100644
--- a/share/man/man9/vref.9
+++ b/share/man/man9/vref.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VREF 9
+.Os
.Sh NAME
.Nm vref
.Nd increment the use count for a vnode
diff --git a/share/man/man9/vrefcnt.9 b/share/man/man9/vrefcnt.9
index fbf43df..de7af26 100644
--- a/share/man/man9/vrefcnt.9
+++ b/share/man/man9/vrefcnt.9
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd February 10, 2008
-.Os
.Dt VREFCNT 9
+.Os
.Sh NAME
.Nm vrefcnt
.Nd returns the use count of a vnode
diff --git a/share/man/man9/vrele.9 b/share/man/man9/vrele.9
index 2491149..be5d5f7 100644
--- a/share/man/man9/vrele.9
+++ b/share/man/man9/vrele.9
@@ -29,8 +29,8 @@
.\" $FreeBSD$
.\"
.Dd July 24, 1996
-.Os
.Dt VRELE 9
+.Os
.Sh NAME
.Nm vrele
.Nd decrement the use count for a vnode
diff --git a/share/man/man9/vslock.9 b/share/man/man9/vslock.9
index fdab0eb..23c4127 100644
--- a/share/man/man9/vslock.9
+++ b/share/man/man9/vslock.9
@@ -14,13 +14,6 @@
.\" 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 the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree
index 6fb2742..685667f 100644
--- a/share/misc/bsd-family-tree
+++ b/share/misc/bsd-family-tree
@@ -228,14 +228,14 @@ FreeBSD 5.2 | | | |
| FreeBSD 7.1 | | | |
| | | | | DragonFly 2.2.0
| FreeBSD 7.2 | NetBSD 5.0 OpenBSD 4.5 |
- | | | | | |
- | | | | | DragonFly 2.4.0
- | V | | OpenBSD 4.6 |
- | | | | |
- *--FreeBSD | | | |
- | 8.0 | | | |
- | | | | | |
- | V | | | |
+ | \ | | | |
+ | | | | | DragonFly 2.4.0
+ | | | | OpenBSD 4.6 |
+ | | | | | |
+ *--FreeBSD | | | | |
+ | 8.0 | | | | |
+ | | FreeBSD | | | |
+ | V 7.3 | | | |
| | | | |
FreeBSD 9 -current | NetBSD -current OpenBSD -current |
| | | | |
@@ -511,6 +511,7 @@ FreeBSD 7.2 2009-05-04 [FBD]
DragonFly 2.4.0 2009-09-16 [DFB]
OpenBSD 4.6 2009-10-18 [OBD]
FreeBSD 8.0 2009-11-26 [FBD]
+FreeBSD 7.3 2010-03-23 [FBD]
Bibliography
------------------------
diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot
index d5db227..873ca24 100644
--- a/share/misc/committers-ports.dot
+++ b/share/misc/committers-ports.dot
@@ -67,6 +67,7 @@ cperciva [label="Colin Percival\ncperciva@FreeBSD.org\n2006/01/31"]
daichi [label="Daichi Goto\ndaichi@FreeBSD.org\n2002/10/17"]
danfe [label="Alexey Dokuchaev\ndanfe@FreeBSD.org\n2004/08/20"]
db [label="Diane Bruce\ndb@FreeBSD.org\n2007/01/18"]
+decke [label="Bernhard Froehlich\ndecke@FreeBSD.org\n2010/03/21"]
delphij [label="Xin Li\ndelphij@FreeBSD.org\n2006/05/01"]
demon [label="Dmitry Sivachenko\ndemon@FreeBSD.org\n2000/11/13"]
dryice [label="Dryice Dong Liu\ndryice@FreeBSD.org\n2006/12/25"]
@@ -76,6 +77,7 @@ eik [label="Oliver Eikemeier\neik@FreeBSD.org\n2003/11/12"]
erwin [label="Erwin Lansing\nerwin@FreeBSD.org\n2003/06/04"]
farrokhi [label="Babak Farrokhi\nfarrokhi@FreeBSD.org\n2006/11/07"]
fjoe [label="Max Khon\nfjoe@FreeBSD.org\n2001/08/06"]
+fluffy [label="Dima Panov\nfluffy@FreeBSD.org\n2009/08/10"]
flz [label="Florent Thoumie\nflz@FreeBSD.org\n2005/03/01"]
gabor [label="Gabor Kovesdan\ngabor@FreeBSD.org\n2006/12/05"]
gahr [label="Pietro Cerutti\ngahr@FreeBSD.org\n2008/02/20"]
@@ -85,6 +87,7 @@ glewis [label="Greg Lewis\nglewis@FreeBSD.org\n2002/04/08"]
hq [label="Herve Quiroz\nhq@FreeBSD.org\n2004/08/05"]
ijliao [label="Ying-Chieh Liao\nijliao@FreeBSD.org\n2001/01/20"]
itetcu [label="Ion-Mihai Tetcu\nitetcu@FreeBSD.org\n2006/06/07"]
+jacula [label="Giuseppe Pilichi\njacula@FreeBSD.org\n2010/04/05"]
jadawin [label="Philippe Audeoud\njadawin@FreeBSD.org\n2008/03/02"]
jkim [label="Jung-uk Kim\njkim@FreeBSD.org\n2007/09/12"]
jmelo [label="Jean Milanez Melo\njmelo@FreeBSD.org\n2006/03/31"]
@@ -134,8 +137,10 @@ pgj [label="Gabor Pali\npgj@FreeBSD.org\n2009/04/12"]
philip [label="Philip Paeps\nphilip@FreeBSD.org\n2005/10/19"]
pgollucci [label="Philip M. Gollucci\npgollucci@FreeBSD.org\n2008/07/21"]
rafan [label="Rong-En Fan\nrafan@FreeBSD.org\n2006/06/23"]
+rene [label="Rene Ladan\nrene@FreeBSD.org\n2010/04/11"]
rnoland [label="Robert Noland\nrnoland@FreeBSD.org\n2008/07/21"]
romain [label="Romain Tartiere\nromain@FreeBSD.org\n2010/01/24"]
+sahil [label="Sahil Tandon\nsahil@FreeBSD.org\n2010/04/11"]
sat [label="Andrew Pantyukhin\nsat@FreeBSD.org\n2006/05/06"]
sem [label="Sergey Matveychuk\nsem@FreeBSD.org\n2004/07/07"]
sergei [label="Sergei Kolobov\nsergei@FreeBSD.org\n2003/10/21"]
@@ -181,6 +186,8 @@ arved -> stefan
asami -> obrien
+beat -> decke
+
beech -> glarkin
beech -> mva
@@ -245,6 +252,7 @@ ijliao -> leeym
itetcu -> araujo
itetcu -> dryice
+itetcu -> sahil
joerg -> netchild
@@ -283,7 +291,9 @@ mezz -> tmclaugh
miwi -> amdmi3
miwi -> avilla
miwi -> beat
+miwi -> decke
miwi -> farrokhi
+miwi -> fluffy
miwi -> gahr
miwi -> makc
miwi -> mandree
@@ -312,6 +322,8 @@ pav -> josef
pav -> kwm
pav -> mnag
+pgj -> jacula
+
philip -> koitsu
rafan -> chinsan
@@ -337,8 +349,11 @@ steve -> netchild
tabthorpe -> avilla
tabthorpe -> avl
+tabthorpe -> fluffy
+tabthorpe -> jacula
tabthorpe -> jadawin
tabthorpe -> pgj
+tabthorpe -> rene
thierry -> jadawin
@@ -347,6 +362,7 @@ tmclaugh -> xride
will -> lioux
+wxs -> sahil
wxs -> skreuzer
}
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index a52aa27..ebecb35 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -55,6 +55,7 @@ node [color=lightblue2, style=filled, bgcolor=black];
ache [label="Andrey Chernov\nache@FreeBSD.org\n1993/10/31"]
akiyama [label="Shunsuke Akiyama\nakiyama@FreeBSD.org\n2000/06/19"]
ambrisko [label="Doug Ambrisko\nambrisko@FreeBSD.org\n2001/12/19"]
+anchie [label="Ana Kukec\nanchie@FreeBSD.org\n2010/04/14"]
andre [label="Andre Oppermann\nandre@FreeBSD.org\n2003/11/12"]
anholt [label="Eric Anholt\nanholt@FreeBSD.org\n2002/04/22"]
antoine [label="Antoine Brodin\nantoine@FreeBSD.org\n2008/02/03"]
@@ -161,6 +162,7 @@ pjd [label="Pawel Jakub Dawidek\npjd@FreeBSD.org\n2004/02/02"]
ps [label="Paul Saab\nps@FreeBSD.org\n2000/02/23"]
qingli [label="Qing Li\nqingli@FreeBSD.org\n2005/04/13"]
rafan [label="Rong-En Fan\nrafan@FreeBSD.org\n2007/01/31"]
+randi [label="Randi Harper\nrandi@FreeBSD.org\n2010/04/20"]
remko [label="Remko Lodder\nremko@FreeBSD.org\n2007/02/23"]
rik [label="Roman Kurakin\nrik@FreeBSD.org\n2003/12/18"]
rink [label="Rink Springer\nrink@FreeBSD.org\n2006/01/16"]
@@ -169,6 +171,7 @@ roberto [label="Ollivier Robert\nroberto@FreeBSD.org\n1995/02/22"]
rpaulo [label="Rui Paulo\nrpaulo@FreeBSD.org\n2007/09/25"]
rrs [label="Randall R Stewart\nrrs@FreeBSD.org\n2007/02/08"]
rse [label="Ralf S. Engelschall\nrse@FreeBSD.org\n1997/07/31"]
+rstone [label="Ryan Stone\nrstone@FreeBSD.org\n2010/04/19"]
ru [label="Ruslan Ermilov\nru@FreeBSD.org\n1999/05/27"]
rwatson [label="Robert N. M. Watson\nrwatson@FreeBSD.org\n1999/12/16"]
sam [label="Sam Leffler\nsam@FreeBSD.org\n2002/07/02"]
@@ -238,10 +241,12 @@ brian -> joe
brooks -> bushman
brooks -> jamie
+bz -> anchie
bz -> jamie
bz -> syrinx
cperciva -> flz
+cperciva -> randi
cperciva -> simon
csjp -> bushman
@@ -269,6 +274,8 @@ ed -> uqs
eivind -> des
eivind -> rwatson
+emaste -> rstone
+
emax -> markus
gallatin -> ticso
@@ -340,6 +347,7 @@ jkh -> yar
jkoshy -> kaiw
jkoshy -> fabient
+jkoshy -> rstone
jlemon -> bmilekic
jlemon -> brooks
diff --git a/share/misc/pci_vendors b/share/misc/pci_vendors
index 2c42fc6..75420e4 100644
--- a/share/misc/pci_vendors
+++ b/share/misc/pci_vendors
@@ -18,7 +18,7 @@
4001 WinTV PVR-250 (v1)
4009 WinTV PVR-250
4801 WinTV PVR-250 MCE
- 6800 Hauppage Nova -TD-500 DVB-T Tuner Device
+ 6800 Hauppage Nova -TD-500 DVB-T Tuner Device ( PCIVEN_1131&DEV_7130&SUBSYS_40510000&REV_014&3B)
0071 Nebula Electronics Ltd
0100 Ncipher Corp Ltd
0123 General Dynamics
@@ -44,6 +44,10 @@
8519 OV519 series
05E3 CyberDoor
0701 CBD516
+064E SUYIN Corporation
+ A101 Acer Crystal Eye Webcam (suYin)
+ A103 WebCam (SuYin)
+ D101 Web Cam (SuYin)
066F Sigmatel Inc
3410 SMTP3410
3500 SMTP3500
@@ -54,6 +58,8 @@
1704 ISDN Adapter (PCI Bus, D, C)
067B Prolific Technology Inc
2303 PL-2303 USB-to-Serial Converter
+ 2305 USB-to-Printer Bridge Controller (PL-2305)
+ 2393 prolific (prolific)
3507 PL-3507 Hi-Speed USB & IEEE 1394 Combo to IDE Bridge Controller
069D Hughes Network Systems (HNS)
0700 Stream Machine
@@ -70,7 +76,7 @@
09C1 Arris
0704 CM 200E Cable Modem
0A5C Broadcom Corporation
- 0201 Broadcom USB iLine10(tm) Network Adapter
+ 0201 Broadcom USB iLine10(tm) Network Adapter (Broadcom NetXtreme BCM5782 Gigabie Ethernet Contro)
2000 Broadcom Bluetooth Firmware Upgrade Device
2009 Broadcom Bluetooth Controller
200A Broadcom Bluetooth Controller
@@ -84,17 +90,17 @@
2038 Broadcom Blutonium Device Firmware Downloader (BCM2038)
2039 BROADCOM Bluetooth Device
2045 Broadcom Bluetooth Controller
- 2046 Broadcom USB Bluetooth Device
+ 2046 Broadcom USB Bluetooth Device ( 5738z)
2047 Broadcom USB Bluetooth Device
205E Broadcom Bluetooth Firmware Upgrade Device
- 2100 Broadcom Bluetooth 2.0+eDR USB dongle
- 2101 Broadcom Bluetooth 2.0+EDR USB dongle
- 2102 ANYCOM Blue USB-200/250
+ 2100 Broadcom Bluetooth 2.0+eDR USB dongle (BT 50)
+ 2101 Broadcom Bluetooth 2.0+EDR USB dongle ( 5&11BBCF3F&0&2)
+ 2102 ANYCOM Blue USB-200/250 ( USBVID_04B4&PID_21025&38CD4C16&0&6)
2110 Broadcom Bluetooth Controller
2111 ANYCOM Blue USB-UHE 200/250
2120 Broadcom 2045 Bluetooth 2.0 USB-UHE Device with trace filter ( 2045)
2121 Broadcom 2045 Bluetooth 2.0 USB Device with trace filter
- 2122 Broadcom Bluetooth 2.0+EDR USB dongle
+ 2122 Broadcom Bluetooth 2.0+EDR USB dongle ( BCM92045B3)
2124 2045B3ROM Bluetooth Dongle
2130 Broadcom 2045 Bluetooth 2.0 USB-UHE Device with trace filter
2131 Broadcom 2045 Bluetooth 2.0 USB Device with trace filter
@@ -104,7 +110,7 @@
2143 2046 Flash non UHE Class 1
2144 2046 Flash non UHE module Class 2
2145 Broadcom BCM9204MD LENO Module
- 2146 Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
+ 2146 Broadcom 2045 Bluetooth 2.1 USB UHE Dongle
2147 Broadcom 2046 Bluetooth 2.1 USB Dongle
2148 Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
2149 Broadcom 2046 Bluetooth 2.1 USB Dongle
@@ -122,8 +128,9 @@
2155 Broadcom Bluetooth USB Dongle
2157 BCM2046 B1 USB 500
2158 Broadcom 2046 Bluetooth 2.1 Device
- 4502 USB Human Interface Device
- 4503 USB Human Interface Device
+ 4500 Broadcom 2046 Bluetooth 2.1 USB Dongle (BCM2046B1)
+ 4502 Broadcom 2046 Bluetooth 2.1 USB Dongle (BCM2046B1)
+ 4503 Broadcom 2046 Bluetooth 2.1 USB Dongle ( BCM2046B1)
5800 Unified Security Hub
6300 Pirelli ISB Remote NDIS Device
0A89 BREA Technologies Inc
@@ -144,17 +151,22 @@
0A06 RCB672FXX 672-channel modular analog telphony card
0B49 ASCII Corporation
064F Trance Vibrator
+0C45 Microdia Ltd.
+ 602D USB Webcam (7&2BE7B8E3&0&4)
+ 6130 USB CAMERA (5&3512B308&0&1)
0E11 Compaq Computer Corp (Now owned by Hewlett-Packard)
0001 PCI to EISA Bridge
- 0002 PCI to ISA Bridge
+ 0002 PCI to ISA Bridge (ISA Bridge)
000F StorageWorks Library Adapter (HVD) (CPQB1A9)
0012 686P7 (686P7)
- 0046 Smart Array 64xx/6i Controller
+ 0046 Smart Array 6400 Controller (N/A)
0049 Gigabit Upgrade Module (NC7132)
004A Gigabit Server Adapter (NC6136)
+ 005A HP Remote Insight Lights-Out II Board (PowerPC 405GP processor at 200MHz [3305103C])
007C NC7770 1000BaseTX
007D NC6770 1000BaseTX
0085 NC7780 1000BaseTX
+ 00B1 HP Remote Insight Lights-Out II PCI Device (3305103C)
00BB NC7760
00C0 AIC-7899G 64-bit, 66MHz Dual Channel Wide Ultra3 SCSI Controller
00CA NC7771
@@ -201,8 +213,8 @@
AE29 PCI to ISA Bridge (MIS-L)
AE2A CPU to PCI Bridge (MPC)
AE2B PCI to ISA PnP Bridge (MIS-E)
- AE31 System Management Controller (1002&DEV-4385&SUBSY)
- AE32 Netelligent 10/100 TX PCI UTP TLAN 2.3
+ AE31 System Management Controller (1002&DEV-5653&SUBSYS)
+ AE32 Netelligent 10/100 TX PCI UTP TLAN 2.3 (950)
AE33 Dual EIDE Controller (Triflex)
AE34 Netelligent 10 T PCI UTP TLAN 2.3
AE35 Integrated NetFlex-3/P TLAN 2.3
@@ -321,70 +333,70 @@
0017 PROTO-3 PCI, digital I/O with chipselect (ispLSI1032E)
0020 Universal digital I/O PCI-Interface (ispLSI1032E)
1002 ATI Technologies Inc. / Advanced Micro Devices, Inc.
- 0B12 ati 1900 (ati 1900)
+ 0B12 ATI Radeon X1900 (R580)
1002 0F2A1787 (0F2A1787)
- 3150 Radeon Mobility X600 (M24 1P)
- 3151 FIREMV 2400
- 3152 Mobility Radeon X300
- 3154 Mobility FireGL V3200
- 3171 FireMV 2400 Secondary
- 3E50 Radeon X600/X650 Series
- 3E54 FireGL V3200 (RV380)
- 3E70 Radeon X600 Series Secondary
- 3E74 FIREGL V3200 Secondary
+ 3150 ATI MOBILITY /ATI RADEON X600 (M24)
+ 3151 ATI FireMV 2400 (RV380)
+ 3152 ATI MOBILITY /ATI RADEON X300 (M24)
+ 3154 ATI MOBILITY FireGL V3200 (M24GL)
+ 3171 ATI FireMV 2400 Secondary (RV380)
+ 3E50 ATI RADEON X600/X550 Series (RV380)
+ 3E54 ATI FireGL V3200 (RV380GL)
+ 3E70 ATI RADEON X600/X550 Series Secondary (RV380)
+ 3E74 ATI FireGL V3200 Secondary (RV380GL)
4136 Radeon IGP 320 (A3)
4137 Radeon IGP 340 (RS200)
4144 Radeon 9500 Series (R300)
4145 Radeon 9200 (M+X) (R300)
- 4146 Radeon 9700 (R300)
+ 4146 ATI RADEON 9600TX (R300)
4147 Fire GL Z1 AGP/Pro Video Accelerator (128 MB, 4P)
- 4148 Radeon 9800 SE (R350)
- 4149 Radeon 9500 Family
+ 4148 ATI RADEON 9800 SE (R350)
+ 4149 ATI RADEON 9500 (R350)
414A Radeon 9800 Family
414B Fire GL X2
- 4150 Radeon 9600 Series (V350)
- 4151 Radeon 9600 (RV350)
- 4152 Radeon 9600 XT (RV360)
- 4153 Radeon 9550 (RV350)
- 4154 Fire GL T2
- 4155 Fire GL T2
+ 4150 ATI RADEON 9600 Series (RV350)
+ 4151 ATI RADEON 9600 Series (RV350)
+ 4152 ATI RADEON 9600 Series (RV360)
+ 4153 ATI RADEON 9550/X1050 Series (RV350)
+ 4154 ATI FireGL T2 (RV350GL)
+ 4155 ATI RADEON 9600 Series (RV350)
4156 Fire GL T2
4157 Fire GL T2
- 4158 vga video (4c59h)
- 4164 R300 (128bit mem bus) (Radeon 9500 Series, secondary)
+ 4158 Mach32 (68800AX)
+ 4164 Radeon 9500 Series (R300) - Secondary
4165 Radeon 9700 Pro (R300 AE) - Secondary
- 4166 Radeon 9600TX - Secondary
+ 4166 ATI RADEON 9600TX Secondary (R300)
4167 Fire GL Z1 AGP/Pro Secondary Video Accelerator (128 MB, 4P)
- 4168 Radeon 9800 SE - Secondary (R350)
- 4169 Radeon 9500 Family - Secondary
- 4170 Radeon 9600 - Secondary (RV350)
- 4171 Radeon 9600 (RV350) - Secondary
- 4172 Radeon 9600 XT - Secondary (RV360)
- 4173 Radeon 9550 - Secondary (RV350)
- 4174 FireGL T2 - Seocndary
- 4175 Radeon 9600 Series Secondary
+ 4168 ATI RADEON 9800 SE Secondary (R350)
+ 4169 ATI RADEON 9500 Secondary (R350)
+ 4170 ATI RADEON 9600 Series Secondary (RV350)
+ 4171 ATI RADEON 9600 Series Secondary (RV350)
+ 4172 ATI RADEON 9600 Series Secondary (RV360)
+ 4173 ATI RADEON 9550/X1050 Series Secondary (RV350)
+ 4174 ATI FireGL T2 Secondary (RV350GL)
+ 4175 ATI RADEON 9600 Series Secondary (RV350)
4237 Radeon 7000 IGP
4242 All-In-Wonder 8500DV (R200AIW)
4243 Radeon 8500 DV OHCI FireWire Controller
4336 Radeon IGP 320M (rs200)
4337 Mobility M6 (U2) (RS200M)
- 4341 AC'97 Audio Controller (AD1981)
- 4342 HUB Bridge (IXP 150)
- 4345 EHCI USB Controller (IXP 150)
- 4347 OHCI USB Controller *1 (IXP 150)
- 4348 OHCI USB Controller *2 (IXP 150)
- 4349 PATA 100 Controller (IXP 1xx/2xx)
- 434C LPC Controller (IXP 150)
- 434D Agere Systems AC'97 Modem device (a75-s226)
+ 4341 AC'97 Audio Controller (SB200)
+ 4342 PCI-PCI Bridge (SB200)
+ 4345 EHCI USB Controller (SB200)
+ 4347 OHCI USB Controller *1
+ 4348 OHCI USB Controller *2
+ 4349 PATA-100 IDE Controller (SB200)
+ 434C PCI-ISA Bridge (SB200)
+ 434D AC'97 Modem Controller (SB200)
4353 IXP SB200 SMBUS Controller
- 4354 mach64 ct pci (215r2qzua21)
- 4358 Mach64 CX (216l0sas25)
+ 4354 Mach64 CT (215CT222)
+ 4358 Mach64 CX (210888CX)
4361 AC'97 Audio Controller
4363 IXP SB300 SMBUS Controller
4369 PATA 133 Controller (IXP 3xx)
436D IXP SB300 AC'97 Modem Controller
436E IXP SB300 Serial ATA Controller
- 4370 IXP AC'97 Audio Controller (IXP_AUDIO_400)
+ 4370 IXP SB400 AC'97 Audio Controller
4371 IXP SB400 PCI-PCI Bridge
4372 ATI SMBus (x200)
4373 IXP SB400 EHCI USB 2.0 Controller
@@ -395,7 +407,7 @@
4378 IXP SB400 AC'97 Modem Controller
4379 IXP SB400 Serial ATA Controller
437A IXP SB400 Serial ATA Controller
- 437B IXP SB450 High Definition Audio Controller (Intel Corporation)
+ 437B IXP SB450 High Definition Audio Controller
4380 IXP SB600 Serial ATA Controller
4381 IXP SB600 Serial ATA RAID Controller
4382 IXP SB600 AC'97 Audio Controller
@@ -409,9 +421,9 @@
438A IXP SB600 USB Controller (OHCI3)
438B IXP SB600 USB Controller (OHCI4)
438C ATI RD600/RS600 IDE Controller (RD600/RS600)
- 438D ATK0110 ACPI Utility (1043.4.0.0)
+ 438D IXP SB600 PCI to LPC Bridge
438E IXP SB600 AC'97 Modem Controller
- 4390 SB700 SATA Controller [IDE mode]
+ 4390 Integrated SATA II Controller (SB700)
4391 SB700 SATA Controller [AHCI mode]
4392 SB700 SATA Controller [Non-RAID5 mode]
4393 SB700 SATA Controller [RAID5 mode]
@@ -419,16 +431,16 @@
4395 SB SATA Controller [AHCI mode with HyperFlash-PCIE]
4396 SB700 USB EHCI Controller
4397 SB700 USB OHCI0 Controller
- 4398 SB700 USB OHCI1 Controller
+ 4398 Standard OpenHCD USB-Hostcontroller (SB700)
4399 SB700 USB OHCI2 Controller
439C PATA 133 Controller (SB7xx)
439D SB700 LPC host controller
4437 Radeon Mobility 7000 IGP
4554 Mach64 ET
4654 113--34004-104 (Mach64 VT)
- 4742 ATI 3D Rage Pro AGP 2X 8mb (gt-c2u2) ((GT-C2U2))
+ 4742 3D Rage Pro AGP 1X/2X ((GT-C2U2))
4744 Rage 3D Pro AGP 2x (Rage 3D Pro AGP 2x)
- 4747 GT-C2U2 (Rage 3D Pro)
+ 4747 Rage 3D Pro (GT-C2U2)
4749 ATI ALL IN WONDER PRO (8MB) (RAGE PRO TURBO AGP 2X)
474C k7 som+ (Rage XC PCI-66)
474D SLAT (Rage XL AGP 2x)
@@ -442,7 +454,7 @@
4755 3d rage 2 + dvd (Rage 3D II+pci)
4756 Rage 3D IIC PCI [Mach64 GT IIC] (PQFP Package)
4757 Rage 3D IIC AGP (BGA Package)
- 4758 Mach 64 GT (210888GXControladores ATI 210888GX [Mach64 GX])
+ 4758 Mach64 GX (210888GX)
4759 m3d agp card on agp slot (215r2qzua21)
475A Rage 3D IIC AGP (PQFP Package)
4964 Radeon 9000 Series (RV250 Id)
@@ -451,33 +463,33 @@
4967 Radeon 9000 (RV250)
496E Radeon 9000/9000 Pro - Secondary (RV250)
496F Radeon 9000 (RV250) - Secondary
- 4A48 Radeon X800 Series (R420 JH)
- 4A49 Radeon X800 gt (R423)
- 4A4A Radeon X800 Series
- 4A4B RADEON X800 XT (R420)
- 4A4C Radeon X800 Series (R420 JL)
- 4A4D FireGL X3 (R420 JM)
- 4A4E Radeon Mobility 9800 (M18 JN)
- 4A4F Radeon X800 SE
- 4A50 Radeon X800 XT Platinum
- 4A54 Radeon X800 VE (R420)
- 4A68 Radeon X800 Series Secondary
- 4A69 Radeon X800 Series - Secondary
- 4A6A Radeon X800 Series - Secondary
- 4A6B RADEON X800 XT Secondary (R420)
- 4A6C Radeon X800 Series Secondary
- 4A6D FIREGL X3-256 Secondary
- 4A6F Radeon X800 SE Secondary
- 4A70 Radeon X800 XT Platinum - Secondary
- 4A74 Radeon X800 VE (R420) (Secondary)
- 4B49 Radeon X850XT
+ 4A48 ATI RADEON X800 Series (R420)
+ 4A49 ATI RADEON X800 PRO (R420)
+ 4A4A ATI RADEON X800 Series (R420)
+ 4A4B ATI RADEON X800 XT (R420)
+ 4A4C ATI RADEON X800 Series (R420)
+ 4A4D ATI FireGL X3-256 (R420GL)
+ 4A4E ATI MOBILITY /ATI RADEON 9800 (M18)
+ 4A4F ATI RADEON X800 SE (R420)
+ 4A50 ATI RADEON X800 XT Platinum Edition (R420)
+ 4A54 ATI RADEON X800 VE (R420)
+ 4A68 ATI RADEON X800 Series Secondary (R420)
+ 4A69 ATI RADEON X800 PRO Secondary (R420)
+ 4A6A ATI RADEON X800 Series Secondary (R420)
+ 4A6B ATI RADEON X800 XT Secondary (R420)
+ 4A6C ATI RADEON X800 Series Secondary (R420)
+ 4A6D ATI FireGL X3-256 Secondary (R420GL)
+ 4A6F ATI RADEON X800 SE Secondary (R420)
+ 4A70 ATI RADEON X800 XT Platinum Edition Secondary (R420)
+ 4A74 ATI RADEON X800 VE Secondary (R420)
+ 4B49 ATI RADEON X850 XT (R481)
4B4A Radeon X850 SE
- 4B4B Radeon X850 PRO
- 4B4C Radeon X850XT-PE
- 4B69 Radeon X850XT secondary
- 4B6A Radeon X850 SE Secondary
- 4B6B Radeon X850 PRO secondary
- 4B6C Radeon X850XT-PE Secondary
+ 4B4B ATI RADEON X850 PRO (R481)
+ 4B4C ATI RADEON X850 XT Platinum Edition (R481)
+ 4B69 ATI RADEON X850 XT Secondary (R481)
+ 4B6A ATI RADEON X850 SE Secondary (R481)
+ 4B6B ATI RADEON X850 PRO Secondary (R481)
+ 4B6C ATI RADEON X850 XT Platinum Edition Secondary (R481)
4C42 Rage 3D LT Pro AGP 133MHz (BGA-312 Package)
4C44 Rage 3D LT Pro AGP 133 MHz (Rage 3D LT Pro AGP)
4C45 Rage Mobility M3 AGP
@@ -486,18 +498,18 @@
4C49 Rage 3D LT Pro PCI (BGA-312 Package)
4C4D Rage P/M Mobility AGP 2x (01541014)
4C4E Rage Mobility l (216lo sasa25)
- 4C50 Rage 3D LT Pro PCI (VEN_1002&DEV_4C50&SUBSYS_4C501002&REV_DC)
+ 4C50 Rage 3D LT Pro PCI (BGA-256 Package)
4C51 Rage 3D LT Pro PCI (BGA-256 Package, Limited 3D)
4C52 Rage P/M Mobility PCI
4C53 Rage L Mobility PCI (216L0SASA25)
4C54 Mach64 LT (264LT)
- 4C57 Mobility Radeon 7500 (fdds)
+ 4C57 Mobility Radeon 7500 (M7 [LW])
4C58 FireGL Mobility
4C59 Radeon Mobility M6 Series (Mobility 6)
4C5A Radeon Mobility M6 LZ
4C64 Radeon Mobility M9-GL
4C65 Radeon Mobility 9000 (R250 Le)
- 4C66 Radeon Mobility 9000 series (ATI MOBILITY RADEON 9000 (Microsoft Corporation -)
+ 4C66 MOBILITY RADEON 9000 (M9) (R250)
4C67 Radeon Mobility 9000 (R250 Lg)
4C6E Radeon Mobility 9000 - Secondary (R250 Ln)
4D46 Rage Mobility 128 AGP 4x (ATI mobility128)
@@ -507,27 +519,27 @@
4D52 ATI Theater 550 Pro (ATI Theater 550 Pro)
4D53 Unified AVStream Driver
4E44 Radeon 9700/Pro, 9500 Series (R300)
- 4E45 Radeon 9700/9500 Series (R300)
- 4E46 Radeon 9600TX (R300)
+ 4E45 ATI RADEON 9500 PRO / 9700 (R300)
+ 4E46 ATI RADEON 9600 TX (R300)
4E47 Fire GL X1/Z1 AGP/Pro Video Accelerator (R300-WS)
- 4E48 Radeon 9800 Pro (R350)
+ 4E48 ATI RADEON 9800 PRO (R350)
4E49 Radeon 9800 (R350) (??)
- 4E4A Radeon 9800 XT (R350)
- 4E4B ATI FIREGL X2-256T (FGL9800XT)
- 4E50 Mobility Radeon 9700 (M10 NP) (RV350)
- 4E51 Mobility Radeon 9600 (M10 NQ)
+ 4E4A ATI RADEON 9800 XT (R360)
+ 4E4B ATI FireGL X2-256/X2-256t (R350GL)
+ 4E50 ATI MOBILITY /ATI RADEON 9600/9700 Series (M10)
+ 4E51 ATI RADEON 9600 Series (RV350)
4E52 Mobility Radeon 9500/9600 (M10) (RV350)
4E53 Radeon Mobility 9600 (M10 NS)
- 4E54 Radeon Mobility M10 NT (RV350-WS)
- 4E56 FireGL Mobility T2e (M11 NV)
+ 4E54 ATI MOBILITY FIRE GL T2/T2e (M10GL)
+ 4E56 ATI MOBILITY /ATI RADEON 9550 (M12)
4E64 Radeon 9700/Pro, 9500 (R300) Series - Secondary
- 4E65 Radeon 9700/9500 Series (R300) - Secondary
- 4E66 Radeon 9600TX (R300) - Secondary
+ 4E65 ATI RADEON 9500 PRO / 9700 Secondary (R300)
+ 4E66 ATI RADEON 9600 TX Secondary (R300)
4E67 Fire GL X1/Z1 AGP/Pro Secondary Video Accelerator
- 4E68 Radeon 9800 Pro (R350) - Secondary
- 4E69 Radeon 9800 (R350) - Secondary
- 4E6A Radeon 9800 XT (R350) - Secondary
- 4E6B ATI FIREGL X2-256T Secondary (FGL9800XT)
+ 4E68 ATI RADEON 9800 PRO Secondary (R350)
+ 4E69 ATI RADEON 9800 Secondary (R350)
+ 4E6A ATI RADEON 9800 XT Secondary (R360)
+ 4E6B ATI FireGL X2-256/X2-256t Secondary (R350GL)
4E71 Radeon Mobility 9600 (M10 NQ) (secondary)
4F72 Radeon 9000 Series (RV250)
4F73 Radeon 9000 Series (RV250) (Secondary)
@@ -538,8 +550,8 @@
5045 Rage 128 PE/Pro AGP 2x (TMDS)
5046 Rage 128 PF/Pro AGP 4x (TMDS)
5047 3d Rage pro agp 2x (215R3BUA22)
- 5048 Rage 128 Pro PH AGP 2x (Rage 128 Pro PH AGP)
- 5049 Rage 128 Pro PI AGP 4x (bk2.0.2.vr001.001.002.002.004.025.prt3.ty.t)
+ 5048 Rage 128 Pro PH AGP 2x (8212104D)
+ 5049 Rage 128 Pro PI AGP 4x (R128)
504A Rage 128 Pro PJ PCI (TMDS) (Rage 128 Pro PJ PCI)
504B Rage 128 Pro PK AGP 2x (TMDS) (Rage 128 Pro PK AGP)
504C 4x (TMDS) (Rage 128 Pro PL AGP)
@@ -583,7 +595,7 @@
516D Radeon 9100 Series (R200) - Secondary
5245 Rage 128 GL PCI (215R46ASA22)
5246 Rage 32MB (Rage 128 PRO)
- 5247 Rage 128 RG
+ 5247 Rage 128 RG (Rage 32MB)
524B Rage 128 VR RK PCI (g01080-108)
524C Rage 128 RL/VR AGP 2x
5345 Rage 128 SE/4x PCI
@@ -595,68 +607,68 @@
534D Rage 128 4x SM AGP 4x (Rage 128 SM AGP 4x)
534E Rage 128 4x
5354 Mach 64 ST
- 5446 Video Controller (VGA Compatible) (ewmewm)
+ 5446 Rage 128 Pro Ultra TF (unknown)
544C Rage 128 Pro TL
5452 Rage 128 Pro TR
5453 Rage 128 Pro Ultra TS
5454 Rage 128 Pro Ultra TT
5455 Rade 128 Pro Ultra TU
- 5460 Radeon X300 Mobility (M22) (RV370)
- 5461 Mobility Radeon X300
- 5462 Mobility Radeon X600 SE
- 5464 FireGL GL (M22)
- 5548 Radeon X800 (R423 UH)
- 5549 Radeon X800 Pro
- 554A Radeon X800 XT Platinum
- 554B Primary (X800GT)
+ 5460 ATI MOBILITY /ATI RADEON X300 (M22)
+ 5461 ATI MOBILITY /ATI RADEON X300 (M22)
+ 5462 ATI MOBILITY /ATI RADEON X600 SE (M24C)
+ 5464 ATI MOBILITY FireGL V3100 (M22GL)
+ 5548 ATI RADEON X800 Series (R423)
+ 5549 ATI RADEON X800 GTO (R423)
+ 554A ATI RADEON X800 XT Platinum Edition (R423)
+ 554B ATI RADEON X800 GT (R423)
554C R430 XTP
- 554D Radeon X800 XL (R430)
- 554E Radeon X800 Series
- 554F Radeon X800 Series
- 5550 FireGL V7100 (R423)
- 5551 ATI FIREGL V5100 PCI-EX Primary (R423GL-SE)
+ 554D ATI RADEON X800 CrossFire Edition (R430)
+ 554E ATI RADEON X800 GT (R430)
+ 554F ATI RADEON X800 GTO (R430)
+ 5550 ATI FireGL V7100 (R423GL)
+ 5551 ATI FireGL V5100 (R423GL)
5552 FireGL V5100 (R423 UR)
5554 FireGL V7100 (R423 UT)
- 5568 Radeon X800 Series Secondary
- 5569 Radeon X800 Pro - Secondary
- 556A Radeon X800 XT Platinum - Secondary
- 556B Radeon X800 SE - Secondary
+ 5568 ATI RADEON X800 Series Secondary (R423)
+ 5569 ATI RADEON X800 GTO Secondary (R423)
+ 556A ATI RADEON X800 XT Platinum Edition Secondary (R423)
+ 556B ATI RADEON X800 GT Secondary (R423)
556C R430 XTP Secondary
- 556D Radeon X800 XL - Secondary (R430)
- 556E Radeon X800 Series - Secondary
- 556F Radeon X800 Series - Secondary
- 5570 FIREGL V7100 Secondary
- 5571 ATI FIREGL V5100 PCI-EX Secondary (R423GL-SE)
- 564A Mobility FIREGL V5000 (M26)
- 564B Mobility FIREGL V5000
- 564F Mobility Radeon X700 XL PCIe (M26)
- 5652 Mobility Radeon X700
- 5653 Mobility Radeon X700
- 5654 Mach 64 VT VIDEO XPRESSION (215VT2CA42)
+ 556D ATI RADEON X800 CrossFire Edition Secondary (R430)
+ 556E ATI RADEON X800 GT Secondary (R430)
+ 556F ATI RADEON X800 GTO Secondary (R430)
+ 5570 ATI FireGL V7100 Secondary (R423GL)
+ 5571 FireGL V5100 PCIe (R423GL-SE) - Secondary
+ 564A ATI MOBILITY FireGL V5000 (M26GL)
+ 564B ATI MOBILITY FireGL V5000 (M26GL)
+ 564F ATI MOBILITY /ATI RADEON X700 XL (M26)
+ 5652 ATI MOBILITY /ATI RADEON X700 (M26)
+ 5653 ATI MOBILITY/ATI RADEON X700 (RV410)
+ 5654 Mach64 VT (215VT22200)
5655 Mach 64 VT3
5656 Mach 64 VT4 PCI (Mach 64 VT4 PCI)
- 5657 Radeon X550/X700 Series
+ 5657 ATI RADEON X550/X700 Series (RV410)
566F RADEON X700 SERIES SECONDARY
- 5673 Mobility Radeon X700 Secondary
- 5677 Radeon X550/X700 Series Secondary
+ 5673 ATI MOBILITY /ATI RADEON X700 Secondary (M26)
+ 5677 ATI RADEON X550/X700 Series Secondary (RV410)
5830 RS300/100 Host Bridge
5831 RS300/133 Host Bridge
5832 RS300/166 Host Bridge
- 5833 Radeon IGP9100 RS300/200 Host Bridge
+ 5833 ATI Radeon 9000/9100 IGP Chipset - Host-PCI Bridge (RS300M)
5834 Radeon 9100 IGP (RS300)
- 5835 Mobility Radeon 9100 IGP (RS300M AGP)
- 5838 AGP Bridge (Radeon 9100 IGP)
+ 5835 Mobilitiy Radeon 9100 IGP AGP (RS300M)
+ 5838 ATI Radeon 9000/9100 IGP Chipset - AGP Controller (RS300M)
5854 Radeon XPRESS 200 Series Secondary
5874 Radeon XPRESS 200 Series Secondary
- 5940 www.ati.comRadeon 9200 Pro - Secondary (RV280)
+ 5940 Radeon 9200 Pro Secondary (RV280)
5941 ATI Radeon 9200 - Secondary (RV280)
5942 Radeon 9000U Family - Secondary
5944 Radeon 9200SE PCI (RV280)
5950 RS480 Host Bridge
5951 Radeon Xpress 200 (RS480/RS482/RX480/RX482) Host bridge
5952 CrossFire Xpress 3200 (RD580) Chipset Host Bridge
- 5954 ATI Radeon Xpress 200 Series - RS480 (na)
- 5955 Mobility Radeon XPRESS 200
+ 5954 ATI RADEON Xpress Series (RS480)
+ 5955 ATI RADEON Xpress Series (RS480M)
5956 RD790 GFX Dual Slot
5957 RX790 GFX Single Slot
5958 RD780 GFX Dual Slot
@@ -664,10 +676,10 @@
5961 ATI RADEON 9200 se agp (RV280)
5962 Radeon 9000U Family
5964 Radeon 9200 SE Series (Radeon 9200)
- 5965 FireMV 2200 (Nvidia)
+ 5965 FireMV 2200 (unknown)
5969 ES1000
- 5974 Radeon XPRESS 200 Series
- 5975 ATI Radeon X1100 (Radeon Xpress 1100)
+ 5974 ATI RADEON Xpress Series (RS482)
+ 5975 ATI RADEON Xpress Series (RS482M)
5978 RD790 PCI to PCI bridge (external gfx0 port A)
5979 RD790 PCI to PCI bridge (external gfx0 port B)
597A RD790 PCI to PCI bridge (PCIe gpp port A)
@@ -696,7 +708,7 @@
5A1E RD890 PCI to PCI bridge (external gfx1 port B)
5A1F RD890 PCI to PCI bridge (NB-SB link)
5A30 RS400/100 Host Bridge
- 5A31 RS400/133 Host Bridge
+ 5A31 Host Bridge (RS400/133)
5A32 RS400/166 Host Bridge
5A33 Northbridge: Radeon Xpress 200 (RC410)
5A34 RS480 PCI-X Root Port
@@ -705,211 +717,220 @@
5A38 RS480 PCI Bridge
5A39 RS480 PCI Bridge
5A3F RS480 PCI Bridge
- 5A41 Radeon XPRESS 200
- 5A42 SUBSYS_11821043&REV_004&1CF2FBB4&0&2808 (X200M)
+ 5A41 ATI RADEON Xpress Series (RS400)
+ 5A42 ATI RADEON Xpress Series (RS400M)
5A43 Radeon XPRESS 200 Series Secondary
- 5A61 Radeon Xpress 200 (RC410) VGA card (Radeon XPress 200 (RC410))
- 5A62 ATI RADEON XPRESS 1100 (RC410M)
+ 5A61 ATI RADEON Xpress Series (RC410)
+ 5A62 ATI RADEON Xpress Series (RC410M)
5A63 Radeon XPRESS 200 Series Secondary
- 5B60 ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)] (Radeon X300)
+ 5B60 ATI RADEON X300/X550/X1050 Series (RV370)
5B61 RV371
- 5B62 RADEON X600 Series 265MB (RV380)
- 5B63 ATI Radoen X1050 (Unknown)
- 5B64 FireGL V3100 (RV370 5B64)
+ 5B62 ATI RADEON X600 Series (RV380x)
+ 5B63 ATI RADEON X300/X550/X1050 Series (RV370)
+ 5B64 ATI FireGL V3100 (RV370GL)
5B65 FireGL D1100 (RV370 5B65)
5B66 RV370X
- 5B70 Radeon X300/X550/X1050 Series - Secondary
+ 5B70 ATI RADEON X300/X550/X1050 Series Secondary (RV370)
5B71 RV371 Secondary
- 5B72 Radeon X600 Series - Secondary
- 5B73 Radeon X550 Series - Secondary
- 5B74 ATI 128MB PCI Express x16 ATI FireGL V3100 (FireGL V3100)
- 5B75 FIREMV 2200 Secondary
+ 5B72 ATI RADEON X600 Series Secondary (RV380x)
+ 5B73 ATI RADEON X300/X550/X1050 Series Secondary (RV370)
+ 5B74 ATI FireGL V3100 Secondary (RV370GL)
+ 5B75 ATI FireMV 2200 Secondary (RV370)
5B76 RV370X Secondary
5C61 Mobility Radeon 9200 (bk-ati ver008.016m.085.006)
5C63 Mobility Radeon 9200 (RV280 (M9+))
5D44 Radeon 9200 SE Series - Secondary (RV280)
5D45 ATI FireMV 2200 PCI Secondary (RV280)
- 5D48 Mobility Radeon X800 XT
- 5D49 Mobility FireGL V5100
- 5D4A PCI-E Graphics adapter from Clevo D900T notebook (Mobility Radeon X800)
+ 5D48 ATI MOBILITY/ATI RADEON X800 XT (M28)
+ 5D49 ATI MOBILITY FireGL V5100 (M28GL)
+ 5D4A ATI MOBILITY /ATI RADEON X800 (M28)
5D4C R480 CONSUMER 4P
- 5D4D Radeon XT850 (Radeon XT850)
+ 5D4D ATI RADEON X850 XT Platinum Edition (R480)
5D4E Radeon X800 GT
- 5D4F x800gto 256 pci-e (r480)
- 5D50 FIREGL V7200
- 5D52 Radeon X850XT (PCIE) Primary (R480)
- 5D57 Radeon X800 XT
+ 5D4F ATI RADEON X800 GTO (R480)
+ 5D50 ATI FireGL V7200 (R480GL)
+ 5D52 ATI RADEON X850 XT (R480)
+ 5D57 ATI RADEON X800 XT (R423)
5D6C R480 CONSUMER 4P Secondary
- 5D6D Radeon X850 Series - Secondary
+ 5D6D ATI RADEON X850 XT Platinum Edition Secondary (R480)
5D6E Radeon X800 GT Secondary
- 5D6F Radeon X850 Pro 256M (01131002)
- 5D70 FIREGL V7200 Secondary
- 5D72 Radeon X850 Series - Secondary
- 5D77 Radeon X800 XT - Secondary
- 5E48 FireGL V5000 (RV410)
+ 5D6F ATI RADEON X800 GTO Secondary (R480)
+ 5D70 ATI FireGL V7200 Secondary (R480GL)
+ 5D72 ATI RADEON X850 XT Secondary (R480)
+ 5D77 ATI RADEON X800 XT Secondary (R423)
+ 5E48 ATI FireGL V5000 (RV410GL)
5E49 FireGL V3300 (RV410)
- 5E4A Radeon X700 Series
- 5E4B Radeon X700 Series
- 5E4C Radeon X700 Series
- 5E4D Radeon X700 Series
- 5E4F Radeon X700 SE
- 5E68 FIREGL V5000 Secondary
- 5E6A Radeon X700 Series - Secondary
- 5E6B Radeon X700 Series - Secondary
- 5E6C Radeon X700 Series - Secondary
- 5E6D Radeon X700 Series - Secondary
- 5E6F Radeon X700 SE - Secondary
+ 5E4A ATI RADEON X700 XT (RV410)
+ 5E4B ATI RADEON X700 PRO (RV410)
+ 5E4C ATI RADEON X700 SE (RV410)
+ 5E4D ATI RADEON X700 (RV410)
+ 5E4F ATI RADEON X700/X550 Series (RV410)
+ 5E68 ATI FireGL V5000 Secondary (RV410GL)
+ 5E6A ATI RADEON X700 XT Secondary (RV410)
+ 5E6B ATI RADEON X700 PRO Secondary (RV410)
+ 5E6C ATI RADEON X700 SE Secondary (RV410)
+ 5E6D ATI RADEON X700 Secondary (RV410)
+ 5E6F ATI RADEON X700/X550 Series Secondary (RV410)
5F57 Radeon X800XT PCIe (R423)
+ 6898 ATI Radeon HD 5800 Series (EG CYPRESS XT)
+ 6899 ATI Radeon HD 5800 Series (EG CYPRESS PRO)
+ 68A0 ATI Mobility Radeon HD 5800 Series (EG BROADWAY XT)
+ 68A1 ATI Mobility Radeon HD 5800 Series (EG BROADWAY PRO/LP)
+ 68B0 ATI Mobility Radeon HD 5800 Series (EG BROADWAY XT)
+ 68B8 ATI Radeon HD 5700 Series (EG JUNIPER XT)
+ 68BE ATI Radeon HD 5700 Series (EG JUNIPER LE)
700F PCI to AGP Bridge (A3/U1)
7010 PCI to AGP Bridge (RS200)
- 7100 Radeon X1800 Series
- 7101 Mobility Radeon X1800 XT
- 7102 Radeon Mobility X1800
- 7103 Mobility FireGL V7200
- 7104 ATI FireGL 7200 or 3200
- 7105 R520 [FireGL]
- 7106 Mobility FireGL V7100
- 7108 Radeon Mobility X1800
+ 7100 ATI RADEON X1800 Series (R520)
+ 7101 ATI MOBILITY /ATI RADEON X1800 XT (M58)
+ 7102 ATI MOBILITY /ATI RADEON X1800 (M58)
+ 7103 ATI MOBILITY FireGL V7200 (M58GL)
+ 7104 ATI FireGL V7200 (R520GL)
+ 7105 ATI FireGL V5300 (R520GL)
+ 7106 ATI MOBILITY FireGL V7100 (M58GL)
+ 7108 ATI RADEON X1800 Series (R520)
7109 Radeon X1800 Series - Secondary
- 710A Radeon X1800 GTO
- 710B Radeon X1800
- 710C Radeon X1800
- 710E FIREGL V7300
- 710F ATI FireGL (V7350)
- 7120 Radeon X1800 Series Secondary
- 7124 FireGL V7200 (R520 GL) - Secondary
- 7125 Radeon X1800 Series Secondary
- 7128 Radeon X1800 Series Secondary
- 7129 Radeon X1800 Series - Secondary
- 712A Radeon X1800 GTO - Secondary
- 712B Radeon X1800 Series Secondary
- 712C Radeon X1800 Series Secondary
- 712E FIREGL V7300 Secondary
- 712F ATI FireGL (V 7350 Secondary)
- 7140 Radeon X1300 Series
+ 710A ATI RADEON X1800 Series (R520)
+ 710B ATI RADEON X1800 Series (R520)
+ 710C ATI RADEON X1800 Series (R520)
+ 710E ATI FireGL V7300 (R520GL)
+ 710F ATI FireGL V7350 (R520GL)
+ 7120 ATI RADEON X1800 Series Secondary (R520)
+ 7124 ATI FireGL V7200 Secondary (R520GL)
+ 7125 ATI FireGL V5300 Secondary (R520GL)
+ 7128 ATI RADEON X1800 Series Secondary (R520)
+ 7129 ATI RADEON X1800 Series Secondary (R520)
+ 712A ATI RADEON X1800 Series Secondary (R520)
+ 712B ATI RADEON X1800 Series Secondary (R520)
+ 712C ATI RADEON X1800 Series Secondary (R520)
+ 712E ATI FireGL V7300 Secondary (R520GL)
+ 712F ATI FireGL V7350 Secondary (R520GL)
+ 7140 ATI RADEON X1600 Series (RV515)
7141 RV505
- 7142 Radeon X1300 Pro or X1550 (rv515)
- 7143 Radeon X1550 Series (RV505)
- 7145 PCIVEN_104C&DEV_803B&SUBSYS_FF101179&REV_00 (x1400)
- 7146 Radeon X1300 XGE (N/A)
- 7147 Radeon X1550 64-bit (RV505)
- 7149 ATI Mobility Radeon X1300, M52-64 (216CZJAKA12FAG)
- 714A Mobility Radeon X1300
- 714B Mobility Radeon X1300
- 714C Mobility Radeon X1300
- 714D Radeon X1300 (RV515)
- 714E Radeon X1300 (RV515)
+ 7142 ATI RADEON X1300/X1550 Series (RV515)
+ 7143 ATI RADEON X1550 Series (RV515)
+ 7145 ATI MOBILITY /ATI RADEON X1400 (M54)
+ 7146 ATI RADEON X1300 / X1550 Series (RV515)
+ 7147 ATI RADEON X1550 64-bit (RV515)
+ 7149 ATI MOBILITY /ATI RADEON X1300 (M52)
+ 714A ATI MOBILITY /ATI RADEON X1300 (M52)
+ 714B ATI MOBILITY /ATI RADEON X1300 (M52)
+ 714C ATI MOBILITY /ATI RADEON X1300 (M52)
+ 714D ATI RADEON X1300 Series (RV515)
+ 714E ATI RADEON X1300 Series (RV515PCI)
714F RV505
7151 RV505
- 7152 HP Fire GL v3300 (Fire GL v3300)
- 7153 FireGL V3350 (RV515GL)
- 715E Radeon X1300 Series
- 715F Radeon X1300 Series
- 7160 Radeon X1300 Series - Secondary
+ 7152 ATI FireGL V3300 (RV515GL)
+ 7153 ATI FireGL V3350 (RV515GL)
+ 715E ATI RADEON X1300 Series (RV515)
+ 715F ATI RADEON X1550 64-bit (RV515)
+ 7160 ATI RADEON X1600 Series Secondary (RV515)
7161 RV505 Secondary
- 7162 Radeon X1300 Series - Secondary
- 7163 Radeon X1300 PRO Secondary
- 7166 Radeon X1300 Series - Secondary
- 7167 Radeon X1300 Series Secondary
+ 7162 ATI RADEON X1300/X1550 Series Secondary (RV515)
+ 7163 ATI RADEON X1550 Series Secondary (RV515)
+ 7166 ATI RADEON X1300 / X1550 Series Secondary (RV515)
+ 7167 ATI RADEON X1550 64-bit Secondary (RV515)
7169 M52 Secondary
- 716D Radeon X1300 Series Secondary
- 716E Radeon X1300 Series Secondary
+ 716D ATI RADEON X1300 Series Secondary (RV515)
+ 716E ATI RADEON X1300 Series Secondary (RV515PCI)
716F RV505 Secondary
7171 RV505 Secondary
- 7172 FireGL V3300 (RV515GL) Secondary
- 7173 FireGL V3350 (RV515GL) Secondary
- 717E Radeon X1300 Series Secondary
- 717F Radeon X1300 Series Secondary
- 7180 Radeon X1300 Series
- 7181 Radeon X1600 Series (RV516XT)
- 7183 Radeon X1300/X1550 Series (RV505)
- 7186 PCIVEN_1002&DEV_7186&SUBSYS_12311043&REV_004&2D404BB6&0&0008 (Mobility Radeon X1450)
- 7187 Radeon 1300 (Radeon 1300)
- 7188 ATI Mobility Radeon X2300 (Mobility X2300)
- 718A Mobility Radeon X2300 Series
- 718B Mobility Radeon X1350
- 718C Mobility Radeon X1350
- 718D Mobility Radeon X1450
- 718F Radeon X1300 Series
- 7193 Radeon X1550 Series
- 7196 Mobility Radeon X1350
- 719B FireMV 2250
- 719F Radeon X1550 Series
- 71A0 Radeon X1300 Series Secondary
- 71A1 Radeon X1600 Series (RV516XT) Secondary
- 71A3 Radeon X1300 Series Secondary
- 71A7 Radeon 1300 Secondary (Radeon 1300)
- 71B3 Radeon X1550 Series Secondary
- 71BB FireMV 2250 Secondary
- 71C0 Radeon X1600 Series
- 71C1 Radeon X1650 Pro (RV535)
- 71C2 ATI X1600 Pro PCI-E (ATI X1600 Pro PCI-E)
- 71C3 Radeon X1600 Series
- 71C4 Mobility FIREGL V5200
- 71C5 Radeon X1600 Mobility (RV530?)
- 71C6 Radeon X1650 Series (RV530 LE)
- 71C7 RADEON X1650 SERIES
- 71CD Radeon X1600 Series
- 71CE Radeon X1600 PRO / X1300XT (RV530 VE)
- 71D2 FireGL V3400 (RV530GL)
- 71D4 Mobility FireGL V5250 (M56GL)
- 71D5 Mobility Radeon X1700 (M66-P)
- 71D6 Mobility Radeon X1700 (M66-XT)
- 71DA FIREGL V5200
- 71DE Ati Radeon X2500 (Uknown)
- 71E0 Radeon X1600 Series Secondary
- 71E1 Radeon X1650 Series Secondary
- 71E2 Radeon X1600 Series Secondary
- 71E3 Radeon X1600 Series Secondary
+ 7172 ATI FireGL V3300 Secondary (RV515GL)
+ 7173 ATI FireGL V3350 Secondary (RV515GL)
+ 717E ATI RADEON X1300 Series Secondary (RV515)
+ 717F ATI RADEON X1550 64-bit Secondary (RV515)
+ 7180 ATI RADEON X1300/X1550 Series (RV515)
+ 7181 ATI RADEON X1600 Series (RV515)
+ 7183 ATI RADEON X1300/X1550 Series (RV515)
+ 7186 ATI MOBILITY /ATI RADEON X1450 (M54)
+ 7187 ATI RADEON X1300/X1550 Series (RV515)
+ 7188 ATI MOBILITY /ATI RADEON X2300 (M54)
+ 718A ATI MOBILITY /ATI RADEON X2300 (M54)
+ 718B ATI MOBILITY /ATI RADEON X1350 (M52)
+ 718C ATI MOBILITY /ATI RADEON X1350 (M52)
+ 718D ATI MOBILITY /ATI RADEON X1450 (M54)
+ 718F ATI RADEON X1300 Series (RV515PCI)
+ 7193 ATI RADEON X1550 Series (RV515)
+ 7196 ATI MOBILITY /ATI RADEON X1350 (M52)
+ 719B ATI FireMV 2250 (RV515)
+ 719F ATI RADEON X1550 64-bit (RV515)
+ 71A0 ATI RADEON X1300/X1550 Series Secondary (RV515)
+ 71A1 ATI RADEON X1600 Series Secondary (RV515)
+ 71A3 ATI RADEON X1300/X1550 Series Secondary (RV515)
+ 71A7 ATI RADEON X1300/X1550 Series Secondary (RV515)
+ 71AF ATI RADEON X1300 Series Secondary (RV515PCI)
+ 71B3 ATI RADEON X1550 Series Secondary (RV515)
+ 71BB ATI FireMV 2250 Secondary (RV515)
+ 71C0 ATI RADEON X1600 Series (RV530)
+ 71C1 ATI RADEON X1650 Series (RV535)
+ 71C2 ATI RADEON X1600 Series (RV530)
+ 71C3 ATI RADEON X1300 Series (RV535)
+ 71C4 ATI MOBILITY FireGL V5200 (M56GL)
+ 71C5 ATI MOBILITY /ATI RADEON X1600 (M56)
+ 71C6 ATI RADEON X1650 Series (RV530)
+ 71C7 ATI RADEON X1650 Series (RV535)
+ 71CD ATI RADEON X1600 Series (RV530)
+ 71CE ATI RADEON X1600 Pro / ATI RADEON X1300 XT (RV530)
+ 71D2 ATI FireGL V3400 (RV530GL)
+ 71D4 ATI MOBILITY FireGL V5250 (M56GL)
+ 71D5 ATI MOBILITY /ATI RADEON X1700 (M56)
+ 71D6 ATI MOBILITY /ATI RADEON X1700 XT (M56)
+ 71DA ATI FireGL V5200 (RV530GL)
+ 71DE ATI MOBILITY /ATI RADEON X1700 (M56)
+ 71E0 ATI RADEON X1600 Series Secondary (RV530)
+ 71E1 ATI RADEON X1650 Series Secondary (RV535)
+ 71E2 ATI RADEON X1600 Series Secondary (RV530)
+ 71E3 ATI RADEON X1300 Series Secondary (RV535)
71E5 M56 Secondary
- 71E6 Radeon X1650 Series Secondary (RV530 LE)
- 71E7 RADEON X1650 SERIES SECONDARY
- 71ED Radeon X1600 Series Secondary
- 71EE Radeon X1600 PRO / X1300XT Secondary (RV530 VE)
+ 71E6 ATI RADEON X1600 Series Secondary (RV530)
+ 71E7 ATI RADEON X1650 Series Secondary (RV535)
+ 71ED ATI RADEON X1600 Series Secondary (RV530)
+ 71EE ATI RADEON X1600 Pro / ATI RADEON X1300 XT Secondary (RV530)
71F2 ATI FireGL V3400 Secondary (RV530GL)
- 71FA FIREGL V5200 Secondary
+ 71FA ATI FireGL V5200 Secondary (RV530GL)
71FE RV530 SE Secondary
7205 S3G Unichrome IGP KM400/KN400 (1106)
- 7210 Mobility Radeon X2100
- 7211 Mobility Radeon X2100 Secondary
- 7240 Radeon X1900 (R580)
+ 7210 ATI MOBILITY /ATI RADEON HD 2300 (M71)
+ 7211 ATI MOBILITY /ATI RADEON HD 2300 (M71)
+ 7240 ATI RADEON X1950 Series (R580)
7241 Radeon X1900 (R580)
7242 Radeon X1900 (R580)
- 7243 Radeon X1900 (R580)
- 7244 Radeon X1950XT Series
- 7245 Radeon X1900 (R580)
- 7246 Radeon X1900 (R580)
- 7247 Radeon X1900 (R580)
- 7248 Radeon X1900 (R580)
- 7249 Radeon X1900 Series
- 724A Radeon X1900 (R580)
- 724B R580LE (180636911721)
- 724C Radeon X1900 (R580)
- 724D Radeon X1900 (R580)
+ 7243 ATI RADEON X1900 Series (R580)
+ 7244 ATI RADEON X1950 Series (R580)
+ 7245 ATI RADEON X1900 Series (R580)
+ 7246 ATI RADEON X1900 Series (R580)
+ 7247 ATI RADEON X1900 Series (R580)
+ 7248 ATI RADEON X1900 Series (R580)
+ 7249 ATI RADEON X1900 Series (R580)
+ 724A ATI RADEON X1900 Series (R580)
+ 724B ATI RADEON X1900 Series (R580)
+ 724C ATI RADEON X1900 Series (R580)
+ 724D ATI RADEON X1900 Series (R580)
724E FireGL V7300/V7350 PCIe (R580)
- 724F Radeon X1900 Series
- 7260 Radeon X1950 Series Secondary
- 7263 Radeon X1900 Series Secondary
- 7264 Radeon X1950XT Series Secondary
- 7265 Radeon X1900 Series Secondary
- 7266 Radeon X1900 Series Secondary
- 7267 Radeon X1900 Series Secondary
- 7268 Radeon X1950 Series Secondary
- 7269 Radeon X1900 Series Secondary
- 726A Radeon X1900 Series Secondary
- 726B Radeon X1900 Secondary
- 726C Radeon X1900 Series Secondary
- 726D Radeon X1900 Series Secondary
+ 724F ATI RADEON X1900 Series (R580)
+ 7260 ATI RADEON X1950 Series Secondary (R580)
+ 7263 ATI RADEON X1900 Series Secondary (R580)
+ 7264 ATI RADEON X1950 Series Secondary (R580)
+ 7265 ATI RADEON X1900 Series Secondary (R580)
+ 7266 ATI RADEON X1900 Series Secondary (R580)
+ 7267 ATI RADEON X1900 Series Secondary (R580)
+ 7268 ATI RADEON X1900 Series Secondary (R580)
+ 7269 ATI RADEON X1900 Series Secondary (R580)
+ 726A ATI RADEON X1900 Series Secondary (R580)
+ 726B ATI RADEON X1900 Series Secondary (R580)
+ 726C ATI RADEON X1900 Series Secondary (R580)
+ 726D ATI RADEON X1900 Series Secondary (R580)
726E FireGL V7300/V7350 PCIe (R580) - Secondary
- 726F Radeon X1900 Series Secondary
- 7280 Radeon X1950 Pro Series AGP (0x7280) (Radeon X1950 Pro)
- 7288 Radeon X1950 GT
- 7291 Radeon X1650 XT (PCIe)
- 7293 Radeon X1650 Series
- 72A0 Radeon X1950 Pro Series AGP (0x72A0) (Radeon X1950 Pro Secondary)
- 72A8 Radeon X1950 GT (Secondary)
- 72B1 Radeon X1650 XT (Secondary) (PCIe)
- 72B3 Radeon X1650 Series (Secondary)
+ 726F ATI RADEON X1900 Series Secondary (R580)
+ 7280 ATI RADEON X1950 Series (R580)
+ 7284 ATI MOBILITY /ATI RADEON X1900 (M58)
+ 7288 ATI RADEON X1950 GT (R580)
+ 7291 ATI RADEON X1650 Series (R580)
+ 7293 ATI RADEON X1650 Series (R580)
+ 72A0 ATI RADEON X1950 Series Secondary (R580)
+ 72A8 ATI RADEON X1950 GT Secondary (R580)
+ 72B1 ATI RADEON X1650 Series Secondary (R580)
+ 72B3 ATI RADEON X1650 Series Secondary (R580)
7800 ?
7830 RS350/100 Host Bridge
7831 RS350/133 Host Bridge
@@ -923,60 +944,136 @@
7916 RS690 PCI to PCI Bridge (PCI Express Port 2)
7917 RS690 PCI to PCI Bridge (PCI Express Port 3)
7919 Radeon X1200 Series Audio Controller
- 791E ATI xpress 1250 (303017AA)
- 791F ATI Mobility Radeon x1250 (RS690)
+ 791A HDMI Audio (791A)
+ 791E ATI RADEON X1200 Series (RS690)
+ 791F ATI Mobility Radeon x1100 (RS690M)
7930 RS600(M) Chipset - Host Bridge
7933 RS600(M) Chipset - PCI Express Graphics Port 0
7935 RS600(M) Chipset - PCI Express Port 1
7937 ATI Technoligies Inc (Samsung R25P)
- 793F Radeon X1200 Series (Secondary)
- 7941 Radeon XPRESS 1300
- 7942 ATI XPress 1250M (1002)
- 796E ATI RADEON 2100 (RS740)
+ 793F ATI RADEON Xpress 1200 Series (RS600)
+ 7941 ATI RADEON Xpress 1200 Series (RS600)
+ 7942 ATI RADEON Xpress 1200 Series (RS600M)
+ 796E ATI RADEON 2100 (RS690)
7C37 Radeon 9600 SE (RV350 AQ)
9400 ATI Radeon HD 2900 XT (R600)
- 9401 Radeon HD 2900 XT
- 9402 Radeon HD 2900 XT
- 9403 Radeon HD 2900 PRO
- 9405 Radeon HD 2900 GT
- 940A FireGL V8650
- 940B FireGL V8600
- 940F FireGL V7600
- 9440 Graphics adapter (Radeon 4870)
- 94C1 ATI Radeon HD 2400 PRO (REV_00)
- 94C3 ATI Radeon HD 2400 PRO (RV610)
- 94C4 ATI Radeon HD 3470 PRO AGP (RV610)
- 94C5 RADEON HD 2400 LE
- 94C7 RADEON HD 2350
- 94C8 Mobility Radeon HD 2400 XT
- 94C9 Mobility Radeon HD 2400
- 94CB Radeon E2400
- 94CC ATI Radeon HD 2400 Series (ATI Radeon HD 4670 Series)
- 9501 ATI Radeon HD 3870 (RV670)
- 9505 Radeon HD 3850
- 9515 ATI Radeon HD3850 AGP
- 9581 ATI Mobility Radeon HD2600 (600458)
- 9583 Mobility Radeon HD 2600 XT
- 9586 Radeon HD 2600 XT AGP
- 9587 Radeon hd 2600 pro (agp) ( Radeon hd 2600 pro (agp))
- 9588 ATI Radeon HD 2600 XT (RV530)
- 9589 ATI Radeon HD 2600 PRO (RV630)
+ 9401 ATI RADEON HD 2900 XT (R600)
+ 9402 ATI RADEON HD 2900 XT (R600)
+ 9403 ATI RADEON HD 2900 PRO (R600)
+ 9405 ATI RADEON HD 2900 GT (R600)
+ 940A ATI FireGL V8650 (R600GL)
+ 940B ATI FireGL V8600 (R600GL)
+ 940F ATI FireGL V7600 (R600GL)
+ 9440 ATI Radeon HD 4870 (RV770)
+ 9441 ATI Radeon HD 4870 X2 (R700)
+ 9442 ATI Radeon HD 4800 Series (RV770)
+ 9443 ATI Radeon HD 4850 X2 (R700)
+ 9444 ATI FirePro V8750 (FireGL) (RV770)
+ 9446 ATI FirePro V7770 (FireGL) (RV770)
+ 9447 ATI FirePro V8700 Duo (FireGL) (R700)
+ 944A ATI Mobility Radeon HD 4850 (M98)
+ 944B ATI Mobility Radeon HD 4850 X2 (M98)
+ 944C ATI Radeon HD 4800 Series (RV770)
+ 944E ATI Radeon HD 4700 Series (RV770)
+ 9450 AMD FireStream 9270 (RV770)
+ 9452 AMD FireStream 9250 (RV770)
+ 9456 ATI FirePro V8700 (FireGL) (RV770)
+ 945A ATI Mobility Radeon HD 4870 (M98)
+ 9460 ATI Radeon HD 4800 Series (RV790)
+ 9462 ATI Radeon HD 5000 Series (RV790)
+ 9480 ATI Mobility Radeon HD 4650 (M96)
+ 9487 ATI Radeon Graphics Processor (RV730)
+ 9488 ATI Mobility Radeon HD 4670 (M96)
+ 948F ATI Radeon Graphics Processor (RV730)
+ 9490 ATI Radeon HD 4600 Series (RV730)
+ 9491 ATI Radeon E4600 (M96)
+ 9495 ATI RADEON HD4650 (RV730)
+ 9498 ATI Radeon HD 4650 (RV730)
+ 949C ATI FirePro V7750 (FireGL) (RV730)
+ 949E ATI FirePro V5700 (FireGL) (RV730)
+ 949F ATI FirePro V3750 (FireGL) (RV730)
+ 94A0 ATI Mobility Radeon HD 4830 (M97)
+ 94A1 ATI Mobility Radeon HD 4860 (M97)
+ 94A3 ATI FirePro M7740 (M97)
+ 94B1 ATI Radeon Graphics Processor (RV740)
+ 94B3 ATI Radeon HD 4770 (RV740)
+ 94B4 ATI Radeon HD 4700 Series (RV740)
+ 94B5 ATI Radeon HD 4770 (RV740)
+ 94C1 ATI Radeon HD 2400 XT (RV610-DT (Pro))
+ 94C3 ATI Radeon HD 2400 PRO (RV610-DT (LE))
+ 94C4 ATI Radeon HD 2400 PRO AGP (RV610LE)
+ 94C5 ATI RADEON HD 2400 LE (RV610)
+ 94C7 ATI RADEON HD 2350 (RV610)
+ 94C8 ATI MOBILITY /ATI RADEON HD 2400 XT (M72)
+ 94C9 ATI MOBILITY /ATI RADEON HD 2400 (M72)
+ 94CB ATI RADEON E2400 (M72)
+ 94CC ATI RADEON HD 2400 (RV610)
+ 9501 ATI Radeon HD 3870 (RV670 XT)
+ 9504 ATI MOBILITY /ATI RADEON HD 3850 (M76)
+ 9505 ATI RADEON HD 3850 (RV630)
+ 9506 ATI MOBILITY /ATI RADEON HD 3850 X2 (M76)
+ 9507 ATI Radeon HD 3830 (RV670)
+ 9508 ATI MOBILITY /ATI RADEON HD 3870 (M76)
+ 9509 ATI MOBILITY /ATI RADEON HD 3870 X2 (M76)
+ 950F ATI RADEON HD 3870 X2 (RV630)
+ 9511 ATI FireGL V7700 (RV630GL)
+ 9513 ATI Radeon HD 3850 X2 (R680)
+ 9515 ATI Radeon HD 3850 AGP (RV670 AGP)
+ 9519 AMD FireStream 9170 (RV670)
+ 9540 ATI Radeon HD 4550 (RV710)
+ 9541 ATI Radeon Graphics Processor (RV710)
+ 954E ATI Radeon Graphics Processor (RV710)
+ 954F ATI Radeon HD 4350 (RV710)
+ 9552 ATI Mobility Radeon HD 4330 Series (M92)
+ 9553 ATI Mobility Radeon HD 4570 Series (M92)
+ 9555 ATI Mobility Radeon HD 4500 Series (M93)
+ 9557 ATI FirePro RG220 (M93)
+ 9581 ATI Mobility Radeon HD 2600 (M76M)
+ 9583 ATI MOBILITY /ATI RADEON HD 2600 XT (M76)
+ 9586 ATI RADEON HD 2600 XT AGP (RV630)
+ 9587 ATI Radeon HD 2600 Pro AGP (RV630 PRO)
+ 9588 ATI Radeon HD 2600 XT (RV630 XT)
+ 9589 ATI Radeon HD 2600 Pro (RV630 PRO)
958A RADEON HD 2600 X2 SERIES
- 958B Mobility Radeon HD 2600 XT Gemini
- 958C FireGL V5600
- 958D FireGL V3600
- 958E Radeon HD 2600 LE
- 9591 ATI RADEON MOBILITY HD 3650 (16331043)
- 9596 Sapphire HD3650 AGP (HD3650)
- 9598 RADEON HD 3600 SERIES
- 95C4 ATI Mobility Radeon HD 3450 (ATI Mobility Radeon HD 3450)
- 95C5 HD 3400 Series (Radeon)
- 9610 Radeon HD 3200 Integrated Graphics Processor (780G)
- 9611 ATI Radeon 3100 Graphics (780V)
- 9612 ATI RADEON HD 3200 Graphics (3200)
+ 958B ATI MOBILITY / ATI RADEON HD 2600 XT Gemini (M76)
+ 958C ATI FireGL V5600 (RV630GL)
+ 958D ATI FireGL V3600 (RV630GL)
+ 958E ATI RADEON HD 2600 LE (RV630)
+ 958F ATI Mobility FireGL Graphics Processor (M76)
+ 9590 ATI RADEON HD 3650 Series (RV630)
+ 9591 ATI Mobility Radeon HD 3650 (M86-M)
+ 9593 ATI Mobility Radeon HD 3670 (M86)
+ 9595 ATI Mobility FireGL V5700 (M86)
+ 9596 ATI RADEON HD 3600 Series (RV630)
+ 9597 ATI RADEON HD 3600 Series (RV630)
+ 9598 ATI RADEON HD 3600 Series (RV630)
+ 9599 ATI RADEON HD 3600 Series (RV630)
+ 959B ATI Mobility FireGL Graphics Processor (M86)
+ 95C0 ATI RADEON HD 3470 (RV610)
+ 95C2 ATI MOBILITY /ATI RADEON HD 3430 (M72)
+ 95C4 ATI Mobility Radeon HD 3450 (M82-S)
+ 95C5 ATI Radeon HD 3450 (RV620 LE)
+ 95C6 ATI Radeon HD 3450 (RV620)
+ 95C7 ATI RADEON HD 3430 (RV610)
+ 95C9 ATI Radeon HD 3450 (RV620)
+ 95CC ATI FirePRO V3700 (RV620)
+ 95CD ATI FireMV 2450 (RV610)
+ 95CE ATI FireMV 2260 (RV610)
+ 95CF ATI FireMV 2260 (RV610)
+ 9610 ATI Radeon HD 3200 Graphics (RS780)
+ 9611 ATI RADEON 3100 Graphics (RS780)
+ 9612 ATI RADEON HD 3200 Graphics (RS780M)
+ 9613 ATI RADEON 3100 Graphics (RS780M)
+ 9614 ATI RADEON HD 3300 Graphics (RS780)
+ 9615 AMD 780E (RS780)
+ 9616 AMD 760G (RS780)
+ 9710 ATI Radeon HD 4200 (RS880)
+ 9711 ATI Radeon 4100 (RS880)
+ 9712 ATI Mobility Radeon HD 4200 (RS880)
+ 9713 ATI Mobility Radeon 4100 (RS880)
9876 ATI 3D Rage Pro AGP 2X (ATI GTC (GT-C2U2))
AA01 Ati Mobility Radeon HD 2600 (Ati Function driver for high definition audio - AT)
- AA08 HD Audio Codec
+ AA08 High Definition Audio Device (All with HDMI support)
AA10 HDMI Audio Support
AA20 ATI Radeon HD 3600 Series (RV630)
AA28 Radeon HD 3400 Series (3400)
@@ -1127,7 +1224,7 @@
6001 CrystalClear SoundFusion PCI Audio Accelerator (CS4610/4611)
6003 Crystal CS4610/14/22/24/30 SoundFusion PCI Audio Accelerator
6004 Crystal CS4615 SoundFusion PCI Audio Accelerator
- 6005 Crystal CS4281 SoundFusion PCI Audio Accelerator
+ 6005 Crystal Soundfusion(tm) CS 4281 WDM Audio (CS4281)
9876 SoundFusion PCI Audio Accelerator (cirrus logic crystal CS 4614)
1014 International Business Machines Corp.
0002 MCA Bridge (MCA Bridge)
@@ -1186,7 +1283,7 @@
0104 Gigabit Ethernet-SX Adapter
0105 PCI-32 Bridge (CPC710)
010F Remote Supervisor+Serial Port+Mouse/Keyboard
- 011B Raid controller
+ 011B Raid controller (cbeh3w)
0142 Video Compositor Input (Yotta)
0144 Video Compositor Output (Yotta)
0153 ?
@@ -1214,6 +1311,7 @@
0268 Gigabit Ethernet-SX Adapter (PCI-X)
0269 10/100/1000 Base-TX Ethernet Adapter (PCI-X)
027F Embedded PowerPC CPU (440GX)
+ 0289 2-Port 10/100/1000 Base-TX PCI-X Adapter (14108902) (2-Port 10/100/1000 Base-TX PCI-X Adapter (14108902)
028C Citrine chipset SCSI Controller
0295 IBM SurePOS Riser Card Function 0 (NECSCE 11508082)
0297 IBM SurePOS Riser Card Function 1 (UARTs) (NECSCE 11508082)
@@ -1255,9 +1353,9 @@
9031 EIDE Controller
9032 EIDE & SCSI Controller
9033 SCSI Controller (I960)
- 9040 Multimedia Card
+ 9040 Multimedia card (amd sempron(tm)2200+)
9060 Ultra GT RAID Controller (MegaRAID 434)
- 9063 MegaRAC Controller
+ 9063 Remote Assistant (MegaRAC 780)
101F PictureTel Corp
1020 Hitachi Computer Electronics
1021 Oki Electric Industry
@@ -1357,7 +1455,7 @@
8500 Via Tech VT8361/VT8601 Graphics Controller (VT8361)
8520 Windows xp (Trident Video Accelerator CyberBlade i1)
8620 trident (CyberBlade-i1)
- 8820 zczxzczx (CyberBlade XP)
+ 8820 TRIDENT DISPLAY CONTROLER (Ai1)
9320 32-bit GUI Accelerator (TGUI9320)
9350 32-bit GUI Accelerator (TGUI9350)
9360 Flat panel GUI Accelerator
@@ -1483,8 +1581,8 @@
051B MGA-2164W Millennium II PCI
051E MGA-1164SG Mystique 220 AGP
051F MGA-2164WA Millennium II AGP
- 0520 Eclipse/Calao (Matrox lnc MGA-G200B)
- 0521 Eclipse/Calao (Matrox lnc MGA-G200B)
+ 0520 AGP (Matrox lnc MGA-G200B)
+ 0521 102B (Matrox lnc MGA-G200B)
0522 Matrox G200e (ServerEngines) - English (G200e)
0525 Chip of G450 graphics card (MGA G450 Dual Head)
0527 Parhelia AGP
@@ -1608,7 +1706,7 @@
0182 Raid Controller(?Mode Raid0+1)
0183 ?SATA (?SIS965)
0186 ?
- 0190 SiS LAN Ethernet ( SiS966L, SiS965L, SiS966, SiS965, SiS968)
+ 0190 SiS191 Gigabit LAN & SiS190 LAN (SiS968, SiS965, SiS966, SiS965L, SiS966L)
0191 SIS190 (SIS190)
0200 Onboard Graphics Controller (SiS5597/98)
0204 PCI1 (SiS 6215)
@@ -1664,7 +1762,7 @@
0963 SiS963 PCI to ISA Bridge (LPC Bridge)
0964 LPC Bridge (SiS964)
0999 pciven_1039&subsys_200b163&rev_a03&61aaa010&17 (sis950)
- 1039 SiS5597 SVGA (SiS5597)
+ 1039 SiS5597 SVGAa (SiS5597a)
1040 ?
10EC ?
1182 SiS965/966 182/1182 RAID Controller
@@ -1690,39 +1788,40 @@
5630 Host-to-PCI Bridge (SiS630)
5811 ?
6204 SiS6204 Video decoder & MPEG interface
- 6205 PCI VGA Controller (SiS6206)
+ 6205 PCI VGA Controller (SiS6215)
6225 PCI Graphics & Video Accelerator (SiS 950 m2284dxs)
6236 SiS6236 AGP GUI Accelerator+3D
6300 GUI Accelerator+3D (SiS630/730)
6306 Integrated 3D SVGA Controller (SiS530/620)
- 6325 Sis 650 Integrated GFX Controller (IGP) (VEN_1039&DEV_6325)
+ 6325 Sis 650 Integrated GFX Controller (IGP) (pc&*305;VEN_1039&DEV_6330)
6326 SiS6326 GUI Accelerator
6330 GUI 2D/3D Accelerator (SiS661FX/M661FX/760/741/M760/M741)
6342 SiS662/760GX/761/761GX
6351 IGP Graphics Drivers (SIS 651)
6972 ?
7001 SiS5597/8 Universal Serial Bus Controller
- 7002 USB 2.0 Enhanced Host Controller (SiS7001)
+ 7002 USB 2.0 Enhanced Host Controller (SiS 7001 PCI to USB Open Host Controller)
7005 SiS551/552 Memory Stick Controller
7007 OHCI Compliant FireWire Controller (1039)
- 7012 PCI Audio Accelerator (SiS7012)
+ 7012 PCI Audio Accelerator (SiS7012 + Realtek AC97 audio)
7013 Smart Link 56K Voice Modem (SiS7013)
7015 Software Audio dd (SiS550 dd)
7016 10/100 Ethernet Adapter (SiS7016)
7018 AC97(CMI973X) ..AUDIO Drivers (SiS7018)
7019 Hardware Audio (SiS550/1/2)
7300 GUI Accelerator+3D (SiS7013)
- 7502 audio drivers
- 8139 ?
+ 7502 Realtek HDA Audio Driver.
+ 8139 2012 (2012)
9876 pci vga card for winxp & win2k (sis6215)
103A Seiko Epson Corp
103B Tatung Corp Of America
103C Hewlett-Packard Company
0024 Standard Vista USB Keyboard
+ 0A01 HP Scanjet 2400 (HP2400)
1005 Visialize EG (A4977A)
1008 001 (Donner GFX)
100A Hewlett-Packard VisualizeFX Series Video (hpVisualizeFX)
- 1028 Tachyon TL Fibre Channel Adapter
+ 1028 Tachyon TL Fibre Channel Adapter (ACPI/HPQ0006)
1029 Tachyon XL2 Fibre Channel Adapter (HPFC-5200B)
102A Tachyon TS Fibre Channel Host Adapter (Tach TS)
1030 DeskDirect 10/100VG LAN Adapter (J2585B)
@@ -1764,7 +1863,11 @@
1302 HP Management Shared Memory Device (1302103C)
1303 RMP-3 (Remote Management Processor)
1361 BCM4312 802.11a/b/g WLAN Controller
+ 137A Atheros AR5007 (AR5007)
+ 1411 HP PSC 750 (HPOJ750)
+ 1F1D 3G Broadband device
201D 3G Broadband device
+ 231D 3G Broadband device
2910 PCI Bus Exerciser (E2910A)
2920 Fast Host Interface
2924 PCI Host Interface Adapter (E2924A)
@@ -1790,11 +1893,11 @@
3237 Smart Array Controller
3238 Smart Array E200/E200i SAS/SATA Controller
3239 Smart Array Controller
- 323A Smart Array Controller
+ 323A Smart Array P410i Controller (Smart Array P410i Controller)
323B Smart Array Controller
323C Smart Array Controller
3300 Proliant iLO2 virtual USB controller
- 3302 Proliant iLO2 virtual UART
+ 3302 Integrated Lights Out 2.0 (3305103C)
3305 Proliant iLO2 [Integrated Lights Out] controller
4030 zx2 System Bus Adapter
4031 zx2 I/O Controller
@@ -1817,12 +1920,13 @@
3130 Samurai-DDR AGP Controller
1043 Asustek Computer Inc.
0675 Crestline (GML GL960)
- 1969 ?
+ 1969 Attansic L1 Gigabit Ethernet 10/100/1000Base-T Adapter (P5LD2 - EAYZ)
5653 ATI Radeon Graphics Processor x700 Mobility [M26-X] (M26-X)
+ 82C6 Gigabit Ethernet NIC(NDIS 6.0) (RTL8168/8111)
1044 Adaptec (Formerly: Distributed Processing Technology (DPT))
1012 RAID Engine (Domino)
A400 DPT 2124/9X SmartCache III/RAID SCSI Controller
- A500 PCI Bridge
+ A500 PCI Bridge (unknown)
A501 I2O SmartRAID V Controller
A511 SmartRAID Controller (Raptor)
1045 OPTi Inc.
@@ -1865,6 +1969,7 @@
0008 diamond (STG 2000X)
0009 STG 1764X
0010 PowerVR KYRO series 3 graphics processor (STG4000)
+ 0123 SPEAr1300 (V65204)
0209 STPC Consumer/Industrial North/South Bridge
020A STPC Atlas/Consumer-S/Consumer-II/Elite North Bridge
0210 ISA Bridge (STPC Atlas)
@@ -1877,6 +1982,31 @@
1746 STG 1764X
2774 STE10/100A PCI 10/100 Ethernet Controller with PHY
3520 MPEG-II Video Decoder
+ CC00 ConneXt I/O Hub multifunction device (STA2X11)
+ CC01 ConneXt I/O Hub multifunction device (STA2X11)
+ CC02 ConneXt I/O Hub multifunction device (STA2X11)
+ CC03 ConneXt I/O Hub multifunction device (STA2X11)
+ CC04 ConneXt I/O Hub multifunction device (STA2X11)
+ CC05 ConneXt I/O Hub multifunction device (STA2X11)
+ CC06 ConneXt I/O Hub multifunction device (STA2X11)
+ CC07 ConneXt I/O Hub multifunction device (STA2X11)
+ CC08 ConneXt I/O Hub multifunction device (STA2X11)
+ CC09 ConneXt I/O Hub multifunction device (STA2X11)
+ CC0A ConneXt I/O Hub multifunction device (STA2X11)
+ CC0B ConneXt I/O Hub multifunction device (STA2X11)
+ CC0C ConneXt I/O Hub multifunction device (STA2X11)
+ CC0D ConneXt I/O Hub multifunction device (STA2X11)
+ CC0E ConneXt I/O Hub multifunction device (STA2X11)
+ CC0F ConneXt I/O Hub multifunction device (STA2X11)
+ CC10 ConneXt I/O Hub multifunction device (STA2X11)
+ CC11 ConneXt I/O Hub multifunction device (STA2X11)
+ CC12 ConneXt I/O Hub multifunction device (STA2X11)
+ CC13 ConneXt I/O Hub multifunction device (STA2X11)
+ CC14 ConneXt I/O Hub multifunction device (STA2X11)
+ CC15 ConneXt I/O Hub multifunction device (STA2X11)
+ CC16 ConneXt I/O Hub multifunction device (STA2X11)
+ CC17 ConneXt I/O Hub multifunction device (STA2X11)
+ CD00 SPEAr1300 (V65204)
104B Mylex / Buslogic
0140 BT-946C PCI-SCSI-2 MultiMaster
1040 BA80c30 PCI-SCSI MultiMaster
@@ -1912,10 +2042,10 @@
8034 SDA Standard Compliant SD Host Controller (10981734)
8035 PCI GemCore based SmartCard controller (N/A)
8036 Texas Instruments PCIxxx12 Cardbus Controller (PCI6515)
- 8038 Texas Instruments PCI GemCore SmartCard (ff101179)
+ 8038 Texas Instruments PCI GemCore SmartCard (FF001179)
8039 PCIxx12 Cardbus Controller
803A OHCI Compliant IEEE 1394 Host controller (PCIxx12)
- 803B Texas Instruments PCIxx12 Integrated FlashMedia Controller (PCIVEN_104C&DEV_803B&SUBSYS_81E6104D&REV_00 )
+ 803B Texas Instruments an Integrated FlashMedia Controller (PCIVEN_104C&DEV_803B&SUBSYS_207C17AA&REV_00)
803C SDA Standard Compliant SD Host Controller (PCIxx12)
803D Texas Instruments PCI GemCore based SmartCard controller (0780)
8119 iRDA Compatible Controller (na)
@@ -1937,8 +2067,8 @@
A828 PCI-to-PCI Bridge (PCI2050BPDV)
AC10 PC Card Controller (PCI1050)
AC11 PC Card Controller (PCI1030/1053)
- AC12 PC card CardBus Controller (PCI1130)
- AC13 PCIVEN_104C&DEV_803B&SUBSYS_8212104D&REV_004&6B16D5B&0&1AF0 (PCI9440)
+ AC12 PC card CardBus Controller (PCI1131)
+ AC13 PCIVEN_0180&DEV_0822&SUBSYS_01270025&REV_22 (PCI9066)
AC15 PCI1131 PC Card CardBus Controller
AC16 PC Card CardBus Controller (PCI1250)
AC17 PCI1220 PC Card CardBus Controller
@@ -2063,8 +2193,8 @@
18C0 PowerQUICC II PCI Bridge (MPC8265A/66)
18C1 MPC8271/MPC8272
3052 MotorolaSM56Modem_PCI device (0644dfea15)
- 3055 Motorola SM56 Data Fax Modem (SM56)
- 3057 Modem Device on High Definition Audio Bus (HDAUDIOFUNC_02&VEN_1057&DEV_3057&SUBSYS_00010001&)
+ 3055 Motorola SM56 Data Fax Modem - amilo pi 1536 (SM56)
+ 3057 Modem Device on High Definition Audio Bus (HDAUDIOFUNC_02om&VEN_1057&DEV_3057&SUBSYS_0001000)
3410 Digital Signal Processor (DSP56361)
3421 Modem (56IVMR/Phoenix 56ISM)
4801 PowerPC Chipset (Raven)
@@ -2106,7 +2236,7 @@
3D18 Promise SATAII150 518 (tm) IDE Controller
3D73 SATAII 300 TX2+ (PDC40775)
3D75 PDC20575 SATAII150 TX2plus
- 3F19 FastTrak TX2650/4650/4652
+ 3F19 FastTrak TX2650/4650/4652 (scsi)
3F20 FastTrak TX2650(3F21)/4650(3F22)/PDC42819(3716) (PDC42819)
4302 SuperTrak EX Series (tm) Controller
4D30 FastTrack100 on Intel MB SE7500CW2 (PDC20267)
@@ -2184,7 +2314,7 @@
1063 Ocean Office Automation
1064 Alcatel CIT
1065 Texas Microsystems
- 8139 Realtek 8139C Network Card
+ 8139 Realtek 8139C Network Card (nic)
1066 Picopower Technology (A division of National)
0000 VL Bridge (PT80C826)
0001 Vesuvius V1-LS System Controller (PT86C521)
@@ -2216,6 +2346,7 @@
0003 Control Video
0004 Video-in (PlanB)
0007 I/O Controller (OHare)
+ 0009 BCM5703X (BCM5703X)
000C DOS on Mac
000E Mac I/O Controller (Hydra)
0010 Mac I/O Controller (Heathrow)
@@ -2272,6 +2403,7 @@
0069 Intrepid2 ATA/100
006A Intrepid2 Firewire
006B Intrepid2 GMAC (Sun GEM)
+ 008A Mac Pro RAID Card (Apple RAID Controller)
1645 Tigon3 Gigabit Ethernet NIC (BCM5701)
106C Hyundai Electronics America
8801 Dual Pentium ISA/PCI Motherboard
@@ -2323,6 +2455,7 @@
2322 QLA2322 Fibre Channel Adapter
2422 QLogic PCI to Fibre Channel Host Adapter for QLA2460 (ISP2422)
2432 Dual Channel 4G PCIe Fibre Channel Adapter (ISP2432)
+ 2532 8Gb PCIe x8 Single/Dual Fibre Channel HBA (ISP2532)
3010 QLA3010 Network Adapter
3022 QLA3022 Network Adapter
4000 QLA4000 SANblade 4000 iSCSI Adapter
@@ -2515,13 +2648,15 @@
2A60 PCI-6023E
2A70 Multifunction Data Acquisition Card (PCI-6024E)
2A80 Multifunction Data Acquisition Card (PCI-6025E)
- 2B20 ?
+ 2B20 PCI-6527
2C80 PCI-6035E
2CA0 PCI-6034E Multifunction DAQ
70A9 PCI-6528 Digital I/O at 60V
70AF 16-Bit, 250 kS/s, 16 Analog Inputs (PCI-6221)
70B8 PCI-6251 M Series High Speed Multifunction DAQ
+ 710E GPIB Controller Interface Board (PCIe-GPIB)
715D IMAQ-PCI-1426
+ 71BC 16-Bit, 250 kS/s, 16 Analog Inputs (DSUB37) (PCI-6221 )
B001 IMAQ-PCI-1408
B011 IMAQ-PXI-1408
B021 IMAQ-PCI-1424
@@ -2555,7 +2690,7 @@
0670 USB0670 USB Controller
0673 USB0673 USB Controller
0680 SiI 0680 (Was: PCI-0680) Ultra ATA133 EIDE Controller
- 1392 INTEL HDMI AUDIO
+ 1392 High Definition Audio HDMI output (1390/1392)
2455 SATALink 4-Port PCI-X Host Controller (SI3124)
3112 SATA/Raid controller(2XSATA150) (SIL3112)
3114 SATALink/SATARaid Controller (Sil 3114)
@@ -2565,6 +2700,7 @@
3531 SiI 3531 SATA Controller
1096 Alacron
1106 0x47204005&RE (0x3059)
+ 3059 South Bridge (VT8235)
1097 Appian Technology (ETMA)
0038 EIDE Controller (Single FIFO)
1098 Quantum Designs H.K. Ltd
@@ -2572,7 +2708,7 @@
0002 EIDE Controller (QD8580)
1099 Samsung Electronics Co Ltd
109A Packard Bell
- 8280 0x8280 (0x8280)
+ 8280 4 channel video digitizer card (0x036e)
109B Gemlight Computer Ltd
109C Megachips Corp
109D Zida Technologies Ltd
@@ -2583,12 +2719,12 @@
036C Bt879(??) Video Capture
036E Bt878/Fusion 878A Mediastream Controller
036F Video Capturee (Bt878)
- 0370 Video Capture (10 bit High qualtiy cap) (Bt880)
- 0878 TV Video Capture: Hercules Smart TV 2 (7610144D&REV_024&1F7DBC9F&0&09F0)
+ 0370 Video Capture (10 bit High qualtiy cap) (Bt880B)
+ 0878 TV Video Capture: Hauppauge WinTV GO (SUBSYS_13EB0070&REV_11)
0879 Video Capture (Audio Section) (Bt879khf)
0880 Video Capture (Audio Section) (Bt880)
109E Multimedia Video Controller (Brooktree Corp BT848 SVR-2000 V1.02)
- 2115 BtV Mediastream Controller 9x (BtV 2115 Mera Lun)
+ 2115 BtV Mediastream Controller 9x (BtV 2115)
2125 BtV Mediastream Controller (BtV 2125)
2164 Display Adapter (BtV 2164)
2165 MediaStream Controller (BtV 2165)
@@ -2596,7 +2732,8 @@
8471 Bt8471 32 Channel HDLC Controller
8472 32/64-channel HDLC Controllers (Bt8471/72)
8474 128-channel HDLC Controller (Bt8474)
-109F Trigem Computer Inc
+109F Trigem Computer Inc.
+ 036F Video Capturee (Bt878)
10A0 Meidensha Corp
10A1 Juko Electronics Inc Ltd
10A2 Quantum Corp
@@ -2680,6 +2817,7 @@
2021 PCI9080 used in Daktronics VMax Quad Tansmitter Card
2288 Chrislin Industries Memory
2724 Thales PCSM Security Card
+ 2748 TPCX Transientrecorder Card (9054)
3001 PCI9030RDK-LITE PCI Reference Design Kit for PCI 9030
30C1 cPCI9030RDK-LITE CompactPCI Reference Design Kit for PCI 9030
5406 PCI Reference Design Kit for PLX PCI 9054 (PCI RDK9054-LITE)
@@ -2714,6 +2852,7 @@
8533 PEX 8533 32-lane, 6-port PCI Express Switch
8547 PEX 8547 48-lane, 3-port PCI Express Switch
8548 PEX 8548 48-lane, 9-port PCI Express Switch
+ 8664 64-Lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch, 35 x 35mm FCBGA (PEX 8664)
9030 PCI SMARTarget I/O Accelerator (PCI 9030)
9036 Interface chip - value 1k (PCI9036)
9050 Target PCI Interface Chip - value 1k (PCI 9050)
@@ -2831,7 +2970,7 @@
0111 C-Media Audio Device (OEM) (CMI8738/C3DX)
0780 Multi-IO Card
0782 Multi-IO Card
- 10B9 0513 TS05 CKA90961000B (ALI M5273 A1)
+ 10B9 0402t505 CK46828100B (ALI M5273 A1)
1435 ALI M1435 VL to PCI Bridge
1445 ALI M1445 VL to PCI Bridge & Enhanced IDE Adapter
1449 ALI M1449 PCI to ISA Bridge
@@ -2945,7 +3084,7 @@
8920 KS8920 Fast Ethernet Adapter
8925 KS8925 Fast Ethernet Adapter (??)
10C4 Award Software International Inc
- 8363 pci pnp686 (s/n124102160)
+ 8363 s/n124102160
10C5 Xerox Corp
10C6 Rambus Inc
10C7 Media Vision
@@ -2989,6 +3128,7 @@
2011 MPEG2 R-Engine (MPEG2 Hardware Encoder)
2019 Coral-P Graphics Chip (MB86295)
201E Coral-PA Graphics Chip (MB86296)
+ 202B Carmine Graphisc adapter (mb86297)
10D0 Fujitsu Ltd
10D1 FuturePlus Systems
10D2 Molex Incorporated
@@ -3032,22 +3172,22 @@
10DD Evans & Sutherland
0001 3D Graphics Processor (?? Freedom GBbus??)
0100 Lightning 1200
-10DE Nvidia Corp
+10DE NVIDIA Corporation
0001 SoundMAX Integrated Digital Audio (Lucent 0x00da)
0003 nVIDIA High Definition Audio/HDMI (It seems to be Realtek ALC888/9)
- 0006 realtec based HD Audio (unknown)
+ 0006 realtec based HD Audio (nvidia)
0008 NV1 EDGE 3D Accelerator [NV1]
0009 NV1 EDGE 3D Multimedia [NV1]
0010 Mutara V08 [NV2]
0018 Riva 128 Graphics Accelerator [NV3]
0019 Riva 128ZX GUI+3D Accelerator [NV3]
0020 Riva TNT GUI+3D Accelerator [NV4]
- 0028 TNT2 / TNT2 Pro (NV5)
- 0029 RIVA TNT2 Ultra [NVULTRA]
+ 0028 NVIDIA RIVA TNT2/TNT2 Pro (NV05)
+ 0029 NVIDIA RIVA TNT 2 Ultra (NV05)
002A Riva TNT2 [NV5]
002B Riva TNT2 [NV5]
- 002C VANTA / VANTA LT [NVVANTA]
- 002D TNT2 Model 64 / TNT2 Model 64 Pro (NV5)
+ 002C NVIDIA Vanta/Vanta LT (NV05)
+ 002D NVIDIA RIVA TNT2 Model 64/Model 64 Pro (NV05)
002E Vanta [NV6]
002F Vanta [NV6]
0030 nForce4 Intel Edition LPC Bridge
@@ -3062,18 +3202,18 @@
003D MCP04 PCI Bridge
003E nForce4 Intel Edition Serial ATA Controller
003F nForce4 Intel Edition HyperTransport Registers
- 0040 GeForce 6800 Ultra [NV40.0]
- 0041 GeForce 6800 [NV40.1]
- 0042 GeForce 6800 LE [NV40.2]
- 0043 GeForce 6800 XE [NV40.3]
- 0044 GeForce 6800 XT
- 0045 GeForce 6800 GT [NV40.5]
- 0046 GeForce 6800 GT
- 0047 GeForce 6800 GS
- 0048 GeForce 6800 XT
- 0049 ??? (NV40GL)
- 004D Quadro FX 4000 [NV40GL]
- 004E Quadro FX 4000 [NV40GL]
+ 0040 NVIDIA GeForce 6800 Ultra (NV40)
+ 0041 NVIDIA GeForce 6800 (NV40)
+ 0042 NVIDIA GeForce 6800 LE (NV40)
+ 0043 NVIDIA GeForce 6800 XE (NV40)
+ 0044 NVIDIA GeForce 6800 XT (NV40)
+ 0045 NVIDIA GeForce 6800 GT (NV40)
+ 0046 NVIDIA GeForce 6800 GT (NV45)
+ 0047 NVIDIA GeForce 6800 GS (NV40)
+ 0048 NVIDIA GeForce 6800 XT (NV40)
+ 0049 NVIDIA NV40GL (NV40)
+ 004D NVIDIA Quadro FX 3400 (NV40)
+ 004E NVIDIA Quadro FX 4000 (NV40)
0050 nForce4 PCI to ISA Bridge
0051 nForce4 ISA Bridge
0052 nForce4 SMBus
@@ -3081,23 +3221,23 @@
0054 CK804 SATA/RAID Controller (CK804)
0055 CK804 SATA/RAID Controller (CK804)
0056 nForce4 Ethernet Controller
- 0057 NVidia Network Bus Enumerator Description du priphriquenVIDIA nForce4 SLI (CK8-04) - LAN Controll (nForce4 Ultra)
+ 0057 NVIDIA Network Bus Enumerator (CK804)
0058 nForce4 AC'97 Modem
- 0059 Realtek AC'97 Audio (Realtek ALC850)
+ 0059 nForce Audio Controller (unknown)
005A nForce4 USB Controller
005B nForce4 USB 2.0 Controller
005C nForce4 PCI Bridge
005D nForce4 PCIe Bridge
005E nForce4 Memory Controller
005F nForce4 Memory Controller
- 0060 ISA Bridge (nForce MCP2)
- 0064 SMBus Controller (nForce MCP-T)
+ 0060 PCI to ISA Bridge (MCP2)
+ 0064 nForce 2 SMBus Controller (MCP)
0065 PATA Controller (nForce MCP2/MCP2-T/MCP2-U)
- 0066 Ethernet Adapter Chip 10/100/HD/FD-Autosense (nForce MCP-T)
- 0067 OpenHCI USB Controller (nForce MCP2)
- 0068 EHCI USB 2.0 Controller (nForce MCP2)
+ 0066 nForce 2 Networking Controller (MCP2)
+ 0067 Nvidia 7050 chipset HDMI Audio (MCP2)
+ 0068 nForce2 EHCI USB 2.0 Controller
0069 nForce AC'97 Modem
- 006A Audio Codec Interface (nForce MCP2)
+ 006A nForce AC97 Audio Controller (MCP2)
006B Audio Processing Unit (Dolby Digital) (nForce MCP-T?)
006C nForce MCP-T CPU to PCI Bridge
006D Audio Codec Interface (nForce MCP-T)
@@ -3125,39 +3265,41 @@
008B nforce MCP2A PCI Bridge
008C Single-Port 10/100M Fast Ethernet PHYceiver (RLT8201BL)
008E nForce MCP2S Serial ATA Compatible Controller
- 0090 GeForce 7800 GTX
- 0091 GeForce 7800 GTX (G70)
- 0092 GeForce 7800GT (NV47 (20x1,7vp))
- 0093 GeForce 7800 GS
- 0095 GeForce 7800 SLI
- 0098 GeForce Go 7800
- 0099 GeForce Go 7800 GTX
- 009C Quadro FX 350M (G70.1)
- 009D NVIDIA GPU Quadro FX 4500
+ 0090 NVIDIA GeForce 7800 GTX (G70)
+ 0091 NVIDIA GeForce 7800 GTX (G70)
+ 0092 NVIDIA GeForce 7800 GT (G70)
+ 0093 NVIDIA GeForce 7800 GS (G70)
+ 0094 NVIDIA GeForce 7800SE/XT/LE/LT/ZT (G70)
+ 0095 NVIDIA GeForce 7800 SLI (G70)
+ 0098 NVIDIA GeForce Go 7800 (G70)
+ 0099 NVIDIA GeForce Go 7800 GTX (G70)
+ 009C NVIDIA Quadro FX 350M (G70)
+ 009D NVIDIA Quadro FX 4500 (G70)
+ 009E NVIDIA G70GL (G70)
00A0 RIVA TNT2 Aladdin [NVA0]
00B4 nForce4 Intel Edition Memory Registers
- 00C0 GeForce 6800 GS [NV41.0]
- 00C1 NVIDIA GeForce 6800 (NV41.1)
- 00C2 GeForce 6800 LE [NV41.2]
- 00C3 GeForce 6800 XT
- 00C8 GeForce FX 6800 Go (NV41)
- 00C9 GeForce FX 6800 Ultra Go (NV41)
- 00CC Quadro FX 1400 Go (NV41)
- 00CD Quadro FX 3450/4000 SDI (NV41GL)
- 00CE NVIDIA Quadro FX1400 (NV41GL)
+ 00C0 NVIDIA GeForce 6800 GS (NV41)
+ 00C1 NVIDIA GeForce 6800 (NV41)
+ 00C2 NVIDIA GeForce 6800 LE (NV41)
+ 00C3 NVIDIA GeForce 6800 XT (NV41)
+ 00C8 NVIDIA GeForce Go 6800 (NV41.8)
+ 00C9 NVIDIA GeForce Go 6800 Ultra (NV41)
+ 00CC NVIDIA Quadro FX Go 1400 (NV41)
+ 00CD NVIDIA Quadro FX 3450/4000 SDI (NV41)
+ 00CE NVIDIA Quadro FX 1400 (NV41)
00D0 LPC Bridge (nForce 3)
00D1 Host Bridge (nForce 3)
00D2 PCI-to-PCI Bridge (nForce 3?)
00D3 nForce4 Memory Controller
- 00D4 SMBus Controller (nForce MCp2)
+ 00D4 nForce MCP3 SMBus Controller
00D5 CK8 PATA 133/PATA to SATA Bridge (nForce3-150)
- 00D6 Networking Controller (nForce MCP3?)
+ 00D6 nForce 3 Networking Controller (MCP3)
00D7 OpenHCD USB Host Controller (nForce MCP3?)
00D8 Enhanced PCI to USB Host Controller (nForce MCP3?)
00D9 Agere System PCI Soft Modem (nForce 3)
- 00DA SoundMAX Integrated Digital Audio (Lucent)
+ 00DA nForce MCP3 Audio Codec Interface
00DD PCI-to-PCI Bridge (nForce MCP3?)
- 00DF Network adapter (Marvell 88E1111)
+ 00DF nForce 7 Networking Controller (MCP73)
00E0 LPC Interface Bridge (nForce3 250)
00E1 Host/PCI Bridge (nForce3 250)
00E2 AGP Host to PCI Bridge (nForce3 250)
@@ -3171,91 +3313,97 @@
00EA nForce3 AC'97 Audio Codec Interface
00ED PCI-PCI Bridge (nForce3 250)
00EE CK8S SATA/RAID Controller (nForce 250)
- 00F0 ??? (NVBR02)
- 00F1 GeForce 6600 GT AGP (NV43+BR02)
- 00F2 GeForce 6600 [NV43]
- 00F3 GeForce 6200
- 00F4 GeForce 6600 LE
- 00F5 GeForce 7800 GS (G70)
- 00F6 Geforce 6800GS (NV41)
- 00F8 NVIDIA Quadro FX 3400/4400 (NVBR02)
- 00F9 GeForce 6800 Series GPU [BR02.1]
- 00FA GeForce PCX 5750 (NVBR02.2)
- 00FB GeForce PCX 5900 (NVBR02.3)
- 00FC GeForce PCX 5300 (NVBR02.4)
- 00FD Quadro NVS 280 PCI-E (NVBR02GL)
- 00FE Quadro FX 1300 (NVBR02GL)
- 00FF GeForce PCX 4300 (NVBR02.7)
- 0100 GeForce 256 [NV10]
+ 00F0 NVIDIA Device (BR02)
+ 00F1 NVIDIA GeForce 6600 GT (BR02)
+ 00F2 NVIDIA GeForce 6600 (BR02)
+ 00F3 NVIDIA GeForce 6200 (BR02)
+ 00F4 NVIDIA GeForce 6600 LE (BR02)
+ 00F5 NVIDIA GeForce 7800 GS (BR02)
+ 00F6 NVIDIA GeForce 6800 GS/XT (BR02)
+ 00F8 NVIDIA Quadro FX 3400/4400 (BR02)
+ 00F9 NVIDIA GeForce 6800 Series GPU (BR02)
+ 00FA NVIDIA GeForce PCX 5750 (BR02)
+ 00FB NVIDIA GeForce PCX 5900 (BR02)
+ 00FC NVIDIA GeForce PCX 5300 (BR02)
+ 00FD NVIDIA Quadro PCI-E Series (BR02)
+ 00FE NVIDIA Quadro FX 1300 (BR02)
+ 00FF NVIDIA GeForce PCX 4300 (BR02)
+ 0100 NVIDIA GeForce 256 (NV10)
0101 GeForce 256 DDR [NV10DDR]
0102 GeForce 256 Ultra [NV10]
0103 Quadro (GeForce 256 GL) [NV10GL]
- 0110 GeForce2 MX / MX 400 (NV11)
- 0111 GeForce2 MX 100/200 (DDR) (NV11DDR)
- 0112 GeForce2 Go / MX Ultra (NV11)
- 0113 Quadro2 MXR / EX / Go (NV11GL)
- 0140 GeForce 6600 GT
+ 0110 NVIDIA GeForce2 MX/MX 400 (NV11)
+ 0111 GeForce2 MX 100/200 (DDR) [NV11DDR]
+ 0112 GeForce2 Go/MX Ultra [NV11]
+ 0113 NVIDIA Quadro2 MXR/EX (NV11)
+ 0140 NVIDIA GeForce 6600 GT (NV43)
0141 NVIDIA GeForce 6600 (NV43)
- 0142 GeForce 6600 LE
- 0143 GeForce 6600 VE
- 0144 GeForce 6600 GO
+ 0142 NVIDIA GeForce 6600 LE (NV43)
+ 0143 NVIDIA GeForce 6600 VE (NV43)
+ 0144 NVIDIA GeForce Go 6600 (NV43)
0145 NVIDIA GeForce 6610 XL (NV43)
- 0146 Geforce Go 6600TE/6200TE [NV43]
- 0147 GeForce 6700 XL
- 0148 GeForce Go 6600 (unknown)
- 0149 GeForce Go 6600 [NV43]
- 014A Quadro NVS 440
- 014C Quadro FX 540 MXM
- 014D NVIDIA Quadro FX 5500 (unknown)
+ 0146 NVIDIA GeForce Go 6200 TE/6600 TE (NV43)
+ 0147 NVIDIA GeForce 6700 XL (NV43)
+ 0148 NVIDIA GeForce Go 6600 (NV43)
+ 0149 NVIDIA GeForce Go 6600 GT (NV43)
+ 014A NVIDIA Quadro NVS 440 (NV43)
+ 014B NVIDIA NV43 (NV43)
+ 014C NVIDIA Quadro FX 540M (NV43)
+ 014D NVIDIA Quadro FX 550 (NV43)
014E NVIDIA Quadro FX 540 (NV43)
014F NVIDIA GeForce 6200 (NV43)
- 0150 GeForce2 GTS / Pro (NV15)
+ 0150 NVIDIA GeForce2 GTS/GeForce2 Pro (NV15)
0151 GeForce2 Ti (DDR) [NV15DDR]
0152 GeForce2 Ultra (BladeRunner) [NV15BR]
- 0153 Quadro2 Pro [NV15GL]
- 0160 GPU 6500 (NV44 (Code Name))
- 0161 GeForce 6200 TurboCache(TM)
- 0162 GeForce 6200SE TurboCache (NV44?)
- 0163 Geforce 6200 LE (00)
- 0164 GeForce FX 6200 Go (NV44?)
- 0165 Quadro NVS 285 (NVS285)
- 0166 GeForce Go 6400 [NV43]
- 0167 GeForce Go 6200/6400
- 0168 GeForce Go 6200/6400 [NV43]
- 0169 GeForce 6250
- 016A VGA (NVidia GeForce 7100 GS)
- 0170 GeForce4 MX 460 [NV17.1]
- 0171 GeForce4 MX 440 [NV17.2]
- 0172 GeForce4 MX 420 [NV17.3]
- 0173 GeForce4 MX 440-SE [NV17.4]
- 0174 GeForce4 440 Go 64MB (NV17M)
- 0175 GeForce4 420 Go [NV17M]
- 0176 GeForce4 420 Go 32M [NV17M]
- 0177 GeForce4 460 Go [NV17M]
- 0178 Quadro4 500/550 XGL (NV17GL.1)
- 0179 GeForce4 440 Go 64M [NV17M]
- 017A Quadro4 200/400 NVS (NV17GL.2)
+ 0153 NVIDIA Quadro2 Pro (NV15)
+ 0160 NVIDIA GeForce 6500 (NV44)
+ 0161 NVIDIA GeForce 6200 TurboCache(TM) (NV44)
+ 0162 NVIDIA GeForce 6200SE TurboCache(TM) (NV44)
+ 0163 NVIDIA GeForce 6200 LE (NV44)
+ 0164 GeForce Go 6200 [NV44]
+ 0165 NVIDIA Quadro NVS 285 (NV44)
+ 0166 NVIDIA GeForce Go 6250 (NV44)
+ 0167 NVIDIA GeForce Go 6200 (NV44)
+ 0168 NVIDIA GeForce Go 6400 (NV44)
+ 0169 NVIDIA GeForce 6250 (NV44)
+ 016A NVIDIA GeForce 7100 GS (NV44)
+ 016B NVIDIA NV44GLM (NV44)
+ 016C NVIDIA NV44GLM (NV44)
+ 016D NVIDIA NV44GLM (NV44)
+ 016E NVIDIA NV44GL (NV44)
+ 0170 NVIDIA GeForce4 MX 460 (NV17)
+ 0171 NVIDIA GeForce4 MX 440 (NV17)
+ 0172 NVIDIA GeForce4 MX 420 (NV17)
+ 0173 NVIDIA GeForce4 MX 440-SE (NV17)
+ 0174 NVIDIA GeForce4 MX 440 Go (NV17)
+ 0175 NVIDIA GeForce4 MX 420 Go (NV17)
+ 0176 NVIDIA GeForce4 MX 420 Go 32M (NV17)
+ 0177 NVIDIA GeForce4 460 Go (NV17)
+ 0178 NVIDIA Quadro4 550 XGL (NV17)
+ 0179 NVIDIA GeForce4 MX 440 Go 64M (NV17)
+ 017A NVIDIA Quadro NVS (NV17)
017B Quadro4 550 XGL [NV17GL.3]
- 017C Quadro4 500 Go GL [NV17M-GL]
- 017D GeForce4 410 Go [NV17]
+ 017C NVIDIA Quadro4 500 Go GL (NV17)
+ 017D NVIDIA GeForce4 410 Go 16M (NV17)
0180 GeForce4 MX 440 with AGP 8X [NV18]
- 0181 NVIDIA GeForce MX440 with AGP8X (NV18B)
- 0182 GeForce4 MX 440SE with AGP 8X [NV18.3]
- 0183 GeForce4 MX 420 with AGP 8X [NV18.4]
+ 0181 NVIDIA GeForce4 MX 440 with AGP8X (NV18)
+ 0182 NVIDIA GeForce4 MX 440SE with AGP8X (NV18)
+ 0183 NVIDIA GeForce4 MX 420 with AGP8X (NV18)
0184 GeForce4 MX [NV18]
- 0185 GeForce4 MX 4000 (NV18.6)
- 0186 GeForce4 448 Go [NV18M]
- 0187 Geforce4 488 Go (nv18m)
- 0188 Quadro4 580 XGL [NV18GL.1]
- 018A Quadro NVS with AGP8X (Quadro NVS)
- 018B Quadro4 380 XGL [NV18GL.3]
- 018C Quadro NVS 50 PCI
- 018D GeForce4 448 Go [NV18M]
- 0191 Geforce 8800GTX 768MB (G80)
+ 0185 NVIDIA GeForce4 MX 4000 (NV18)
+ 0186 NVIDIA GeForce4 448 Go (NV18)
+ 0187 NVIDIA GeForce4 488 Go (NV18)
+ 0188 NVIDIA Quadro4 580 XGL (NV18)
+ 018A NVIDIA Quadro NVS with AGP8X (NV18)
+ 018B NVIDIA Quadro4 380 XGL (NV18)
+ 018C NVIDIA Quadro NVS 50 PCI (NV18)
+ 018D NVIDIA GeForce4 448 Go (NV18)
+ 0191 NVIDIA GeForce 8800 GTX (G80)
0193 NVIDIA GeForce 8800 GTS (G80)
- 0194 Geforce 8800 ULTRA (G80)
- 019D Nvidia Quadro FX 5600 (G80)
- 019E Nvidia Quadro FX4600 (G80)
+ 0194 NVIDIA GeForce 8800 Ultra (G80)
+ 0197 NVIDIA Tesla C870 (G80)
+ 019D NVIDIA Quadro FX 5600 (G80)
+ 019E NVIDIA Quadro FX 4600 (G80)
01A0 GeForce2 Integrated Graphics [NVCrush11]
01A4 AGP Controller (nForce)
01A5 AGP Controller (nForce)
@@ -3266,28 +3414,30 @@
01AB Memory Controller (DDR) (nForce 415/420/430)
01AC nForce 220/230/415/420/430 Memory Controller
01AD nForce 220/230/415/420/430 Memory Controller
- 01B0 Audio Processing Unit (Dolby Digital) (nForce MCP)
- 01B1 Audio Codec Interface (nForce MCP-S)
+ 01B0 nForce MCP Audio Processing Unit (Dolby Digital)
+ 01B1 nForce AC'97 Audio Controller (MCP)
01B2 HUB Interface (nForce)
- 01B4 SMBus Controller (nForce MCP)
+ 01B4 nForce 1/2 SMBus Controller (MCP)
01B7 AGP Bridge (nForce)
01B8 PCI Bridge (nForce)
- 01BC ATA Controller (nForce MCP)
+ 01BC nForce IDE/ATA Controller (MCP)
01C1 nForce PC97 Modem (Intel 537)
- 01C2 OHCI USB Controller (nForce MCP)
- 01C3 Networking Adapter (nForce MCP)
- 01D0 GeForce 7350 LE
- 01D1 NVIDIA GeForce 7300 LE (unknown)
- 01D3 nVidia GeForce 7300 SE (nVidia)
+ 01C2 nForce OHCI USB Controller
+ 01C3 nForce Networking Controller (MCP)
+ 01D0 NVIDIA GeForce 7350 LE (G72)
+ 01D1 NVIDIA GeForce 7300 LE (G72)
+ 01D2 NVIDIA GeForce 7550 LE (G72)
+ 01D3 NVIDIA GeForce 7300 SE/7200 GS (G72)
+ 01D5 NVIDIA GeForce 7300 LE (G72)
01D6 GeForce Go 7200
01D7 Quadro NVS 110M / GeForce Go 7300
01D8 Quadro NVS 120M / GeForce Go 7400
01DA Quadro NVS 110M
- 01DB Quadro NVS 120M
- 01DC NVIDIA Quadro FX 350M (nvidia mobile graphics)
- 01DD GeForce 7500 LE
- 01DE Quadro FX 350
- 01DF GeForce 7300 GS
+ 01DB NVIDIA Quadro NVS 120M (G72)
+ 01DC NVIDIA Quadro FX 350M (G72)
+ 01DD NVIDIA GeForce 7500 LE (G72)
+ 01DE NVIDIA Quadro FX 350 (G72)
+ 01DF NVIDIA GeForce 7300 GS (G72)
01E0 AGP Controller (nForce2)
01E1 AGP Controller (nForce2)
01E8 AGP Host to PCI Bridge (nForce2)
@@ -3297,40 +3447,43 @@
01ED Memory Controller 3 (nForce2)
01EE Memory Controller 4 (nForce2)
01EF Memory Controller 5 (nForce2)
- 01F0 GeForce4 MX Integrated GPU
- 0200 GeForce3 [NV20]
- 0201 GeForce3 Ti200 [NV20.1]
- 0202 GeForce3 Ti 500 (NV20BR)
- 0203 Quadro DCC [NV20DCC]
- 0211 GeForce 6800
- 0212 GeForce 6800 LE
- 0215 GeForce 6800 GT
- 0218 GeForce 6800 XT
- 0221 NVIDIA GeForce 6200 (unknown)
- 0222 GeForce 6200 A-LE
- 0240 GeForce 6150
- 0241 nVidia GForce 6150, build in DELL Optiplex 740 (AMD Processor) (NVS 210S)
- 0242 NVIDIA GeForce 6100 (unknown)
- 0243 C51 PCIe Bridge
+ 01F0 NVIDIA GeForce4 MX Integrated GPU (CR17)
+ 0200 NVIDIA GeForce3 (NV20)
+ 0201 NVIDIA GeForce3 Ti 200 (NV20)
+ 0202 NVIDIA GeForce3 Ti 500 (NV20)
+ 0203 NVIDIA Quadro DCC (NV20)
+ 0210 NVIDIA NV48 (NV48)
+ 0211 NVIDIA GeForce 6800 (NV48)
+ 0212 NVIDIA GeForce 6800 LE (NV48)
+ 0215 NVIDIA GeForce 6800 GT (NV48)
+ 0218 NVIDIA GeForce 6800 XT (NV48)
+ 0220 NVIDIA NV44 (NV44)
+ 0221 NVIDIA GeForce 6200 (NV44)
+ 0222 NVIDIA GeForce 6200 A-LE (NV44)
+ 0228 NVIDIA NV44M (NV44)
+ 0240 NVIDIA GeForce 6150 (C51)
+ 0241 NVIDIA GeForce 6150 LE (C51)
+ 0242 NVIDIA GeForce 6100 (C51)
+ 0243 PCI Express Bridge (C51)
0244 Geforce Go 6150 (Geforce Go 6150)
- 0245 Quadro NVS 210S/GeForce 6150LE
- 0246 C51 PCIe Bridge
- 0247 GeForce Go 6100
- 0248 C51 PCIe Bridge
- 0249 C51 PCIe Bridge
- 024A C51 PCIe Bridge
- 024B C51 PCIe Bridge
- 024C C51 PCIe Bridge
- 024D C51 PCIe Bridge
- 024E C51 PCIe Bridge
- 024F C51 PCIe Bridge
- 0250 GeForce4 Ti 4600 [NV25.1]
- 0251 GeForce4 Ti 4400 [NV25.2]
- 0252 GeForce3 [NV25.3]
- 0253 Geforce4 TI 4200 128 Mo (NVIDIA Corporation)
- 0258 Quadro4 900 XGL [NV25GL.1]
- 0259 Quadro4 750 XGL [NV25GL.2]
- 025B Quadro4 700 XGL [NV25GL.4]
+ 0245 NVIDIA Quadro NVS 210S / NVIDIA GeForce 6150LE (C51)
+ 0246 PCI Express Bridge (C51)
+ 0247 Geforce 6100 Go (C51)
+ 0248 PCI Express Bridge (C51)
+ 0249 PCI Express Bridge (C51)
+ 024A PCI Express Bridge (C51)
+ 024B PCI Express Bridge (C51)
+ 024C PCI Express Bridge (C51)
+ 024D PCI Express Bridge (C51)
+ 024E PCI Express Bridge (C51)
+ 024F PCI Express Bridge (C51)
+ 0250 NVIDIA GeForce4 Ti 4600 (NV25)
+ 0251 NVIDIA GeForce4 Ti 4400 (NV25)
+ 0252 NVIDIA GeForce4 Ti (NV25)
+ 0253 NVIDIA GeForce4 Ti 4200 (NV25)
+ 0258 NVIDIA Quadro4 900 XGL (NV25)
+ 0259 NVIDIA Quadro4 750 XGL (NV25)
+ 025B NVIDIA Quadro4 700 XGL (NV25)
0260 MCP51 LPC Bridge
0261 MCP51 LPC Bridge
0262 MCP51 LPC Bridge
@@ -3339,47 +3492,47 @@
0265 MCP51 Parallel ATA Controller
0266 NVIDIA nForce 430/410 Serial ATA Controller (MCP51S)
0267 NVIDIA nForce 430/410 Serial ATA Controller (MCP51S)
- 0268 NVIDIA nForce Networking Controller (430)
- 0269 MCP51 Ethernet Controller (2A34103C)
+ 0268 NVIDIA nForce Networking Controller (MCP51)
+ 0269 MCP51 Network Bus Enumerator
026A MCP51 MCI
- 026B MCP51 AC'97 Audio Controller
- 026C MCP51 High Definition Audio
+ 026B MCP51 AC'97 Audio Controller (MCP51)
+ 026C High Definition Audio Controller (MCP51)
026D MCP51 USB Controller
026E MCP51 USB Controller
026F MCP51 PCI Bridge
0270 MCP51 Host Bridge
- 0271 Coprocessor (unknown)
+ 0271 Coprocessor (nForce System Management Controller) (MCP51)
0272 MCP51 Memory Controller 0
027E C51 Memory Controller 2
027F C51 Memory Controller 3
- 0280 GeForce4 Ti 4800 [NV28.1]
- 0281 GeForce4 Ti 4200 with AGP 8x [NV28.2]
- 0282 GeForce4 Ti 4800 SE [NV28.3]
+ 0280 NVIDIA GeForce4 Ti 4800 (NV28)
+ 0281 NVIDIA GeForce4 Ti 4200 with AGP8X (NV28)
+ 0282 NVIDIA GeForce4 Ti 4800 SE (NV28)
0286 GeForce4 Ti 4200 Go AGP 8x [NV28]
- 0288 Quadro4 980 XGL [NV28GL.1]
- 0289 Quadro4 780 XGL [NV28GL.2]
- 028C Quadro4 700 GoGL (NV28GL)
- 0290 GeForce 7900 GTX
- 0291 BLISS GeForce 7900 GT bios (0x0401)
- 0292 GeForce 7900 GS
- 0293 NVIDIA GeForce 7900 GTX DUO (0x0293)
- 0294 GeForce 7950 GX2
- 0295 GeForce 7950 GT
+ 0288 NVIDIA Quadro4 980 XGL (NV28)
+ 0289 NVIDIA Quadro4 780 XGL (NV28)
+ 028C NVIDIA Quadro4 700 Go GL (NV28)
+ 0290 NVIDIA GeForce 7900 GTX (G71)
+ 0291 NVIDIA GeForce 7900 GT/GTO (G71)
+ 0292 NVIDIA GeForce 7900 GS (G71)
+ 0293 NVIDIA GeForce 7950 GX2 (G71)
+ 0294 NVIDIA GeForce 7950 GX2 (G71)
+ 0295 NVIDIA GeForce 7950 GT (G71)
0297 NVIDIA GeForce Go 7950 GTX (G71)
- 0298 GeForce Go 7900 GS
- 0299 GeForce Go 7900 GTX
+ 0298 NVIDIA GeForce Go 7900 GS (G71)
+ 0299 NVIDIA GeForce Go 7900 GTX (G71)
029A Quadro FX 2500M
029B Quadro FX 1500M
- 029C Nvidia Quadro FX 5500 (G71)
- 029D Quadro FX 3500 (G71)
- 029E Quadro FX 1500
- 029F Quadro FX 4500 X2
- 02A0 XBOX GeForce3 Integrated GPU [NV2A]
- 02E0 GeForce 7600 GT
- 02E1 GeForce 7600 GS
- 02E2 Video Card GPU BFG 7300 512MB GT
- 02E3 GeForce 7900 GS
- 02E4 GeForce 7950 GT
+ 029C NVIDIA Quadro FX 5500 (G71)
+ 029D NVIDIA Quadro FX 3500 (G71)
+ 029E NVIDIA Quadro FX 1500 (G71)
+ 029F NVIDIA Quadro FX 4500 X2 (G71)
+ 02A0 NVIDIA NV2A GeForce 3 Integrated (XBOX) (NV20)
+ 02E0 NVIDIA GeForce 7600 GT (BR02)
+ 02E1 NVIDIA GeForce 7600 GS (BR02)
+ 02E2 NVIDIA GeForce 7300 GT (BR02)
+ 02E3 NVIDIA GeForce 7900 GS (BR02)
+ 02E4 NVIDIA GeForce 7950 GT (BR02)
02F0 C51 Host Bridge
02F1 C51 Host Bridge
02F2 C51 Host Bridge
@@ -3397,59 +3550,59 @@
02FE C51 Memory Controller 1
02FF C51 Host Bridge
0300 GeForce FX [NV30.1]
- 0301 GeForce FX 5800 Ultra [NV30.2]
- 0302 GeForce FX 5800 [NV30.3]
- 0308 Quadro FX 2000 [NV30GL.1]
- 0309 Quadro FX 1000 [NV30GL.2]
- 030A ICE FX 2000 (NV30GL)
- 0311 GeForce FX 5600 Ultra [NV31.1]
- 0312 GeForce FX 5600 [NV31.2]
- 0313 ??? (NV31?)
- 0314 GeForce FX 5600XT [NV31.4]
- 0316 NV31
- 0317 NV31
- 0318 ??? (NV31GL.1)
- 0319 ??? (NV31GL.2)
- 031A NVIDIA NV31GL (NV31GL)
- 031B NVIDIA GeForce FX Go5600 (NV31B)
- 031C NVIDIA Quadro FX Go700 (NV31C)
- 031D NV31
- 031E NV31
- 031F NV31
- 0320 GeForce FX 5200
- 0321 GeForce FX 5200 Ultra [NV34.2]
- 0322 GeForce FX 5200 [NV34.3]
- 0323 GeForce FX 5200LE [NV34.3]
- 0324 nVidia GeForce FX Go 5200, 128MB (NV)
- 0325 GeForce FX Go 5700 (nv36m)
- 0326 GeForce FX 5500 [NV34.6]
- 0327 GeForce FX 5100 [NV34.7]
- 0328 GeForce FX Go 5200 32M/64M
+ 0301 NVIDIA GeForce FX 5800 Ultra (NV30)
+ 0302 NVIDIA GeForce FX 5800 (NV30)
+ 0308 NVIDIA Quadro FX 2000 (NV30)
+ 0309 NVIDIA Quadro FX 1000 (NV30)
+ 030A NVIDIA ICE FX 2000 (NV30)
+ 0311 NVIDIA GeForce FX 5600 Ultra (NV31)
+ 0312 NVIDIA GeForce FX 5600 (NV31)
+ 0313 NVIDIA NV31 (NV31)
+ 0314 NVIDIA GeForce FX 5600XT (NV31)
+ 0316 NVIDIA NV31M (NV31)
+ 0317 NVIDIA NV31M Pro (NV31)
+ 0318 NVIDIA NV31GL (NV31)
+ 0319 NVIDIA NV31GL (NV31)
+ 031A NVIDIA GeForce FX Go 5600 (NV31)
+ 031B NVIDIA GeForce FX Go 5650 (NV31)
+ 031C NVIDIA Quadro FX Go 700 (NV31)
+ 031D NVIDIA NV31GLM (NV31)
+ 031E NVIDIA NV31GLM Pro (NV31)
+ 031F NVIDIA NV31GLM Pro (NV31)
+ 0320 NVIDIA GeForce FX 5200 (NV34)
+ 0321 NVIDIA GeForce FX 5200 Ultra (NV34)
+ 0322 NVIDIA GeForce FX 5200 (NV34)
+ 0323 NVIDIA GeForce FX 5200LE (NV34)
+ 0324 NVIDIA GeForce FX Go 5200 (NV34)
+ 0325 NVIDIA GeForce FX Go 5250/5500 (NV34)
+ 0326 NVIDIA GeForce FX 5500 (NV34)
+ 0327 NVIDIA GeForce FX 5100 (NV34)
+ 0328 NVIDIA GeForce FX Go 5200 32/64M (NV34)
0329 GeForce FX Go 5200 [NV34M]
- 032A Quadro NVS 280 PCI [NV34GL.3]
- 032B Quadro FX 500/600 [NV34GL.4]
- 032C NVIDIA NV34GL (NV34GL)
- 032D GeForce FX Go5100 [NV34M]
- 032F ??? (NV34GL)
- 0330 GeForce FX 5900 Ultra [NV35.0]
- 0331 GeForce FX 5900 [NV35.1]
- 0332 GeForce FX 5900XT [NV35.2]
- 0333 GeForce FX 5950 Ultra [NV35.3]
- 0334 GeForce FX 5900ZT [NV35.4]
- 0338 Quadro FX 3000 [NV35GL]
- 033F Quadro FX 700 [NV35GL]
- 0341 GeForce FX 5700 Ultra [NV36.1]
- 0342 GeForce FX 5700 [NV36.2]
- 0343 GeForce FX 5700LE [NV36.3]
- 0344 GeForce FX 5700VE [NV36.4]
- 0345 ??? (NV36.5)
- 0347 GeForce FX Go 5700 [NV36]
- 0348 GeForce FX Go 5600 [NV36M]
- 0349 NV36
- 034B NV36
- 034C Quadro FX Go1000 [NV36]
- 034E Quadro FX 1100 [NV36GL]
- 034F ??? (NV36GL?)
+ 032A NVIDIA Quadro NVS 55/280 PCI (NV34)
+ 032B NVIDIA Quadro FX 500/FX 600 (NV34)
+ 032C NVIDIA GeForce FX Go 53x0 (NV34)
+ 032D NVIDIA GeForce FX Go 5100 (NV34)
+ 032F NVIDIA NV34GL (NV34)
+ 0330 NVIDIA GeForce FX 5900 Ultra (NV35)
+ 0331 NVIDIA GeForce FX 5900 (NV35)
+ 0332 NVIDIA GeForce FX 5900XT (NV35)
+ 0333 NVIDIA GeForce FX 5950 Ultra (NV35)
+ 0334 NVIDIA GeForce FX 5900ZT (NV35)
+ 0338 NVIDIA Quadro FX 3000 (NV35)
+ 033F NVIDIA Quadro FX 700 (NV35)
+ 0341 NVIDIA GeForce FX 5700 Ultra (NV36)
+ 0342 NVIDIA GeForce FX 5700 (NV36)
+ 0343 NVIDIA GeForce FX 5700LE (NV36)
+ 0344 NVIDIA GeForce FX 5700VE (NV36)
+ 0345 NVIDIA NV36 (NV36)
+ 0347 NVIDIA GeForce FX Go 5700 (NV36)
+ 0348 NVIDIA GeForce FX Go 5700 (NV36)
+ 0349 NVIDIA NV36M Pro (NV36)
+ 034B NVIDIA NV36MAP (NV36)
+ 034C NVIDIA Quadro FX Go 1000 (NV36)
+ 034E NVIDIA Quadro FX 1100 (NV36)
+ 034F NVIDIA NV36GL (NV36)
0360 MCP55 LPC Bridge
0361 MCP55 LPC Bridge
0362 MCP55 LPC Bridge
@@ -3458,7 +3611,7 @@
0365 MCP55 LPC Bridge
0366 MCP55 LPC Bridge
0367 MCP55 LPC Bridge
- 0368 MCP55 SMBus
+ 0368 SMBus controller ((0xCB84 integrated chip nForce Pro 3400))
0369 MCP55 Memory Controller
036A MCP55 Memory Controller
036B MCP55 SMU
@@ -3467,7 +3620,7 @@
036E MCP55 PATA Controller (MCP55)
036F MCP55 SATA/RAID Controller (MCP55)
0370 MCP55 PCI bridge
- 0371 MCP55 High Definition Audio (ADI 1988)
+ 0371 High Definition Audio Controller (MCP55)
0372 MCP55 Ethernet
0373 MCP55 Ethernet
0374 MCP55 PCIe bridge
@@ -3479,18 +3632,19 @@
037C GeForce 7800 GS (MCP55??)
037E MCP55 SATA/RAID Controller (MCP55)
037F MCP55 SATA/RAID Controller (MCP55S)
- 0390 GeForce 7650 GS
- 0391 Ge-Force 7600GT (G73 B1)
- 0392 NVIDIA GeForce 7600 GS (NVIDIA GeForce 7600 GS)
- 0393 NVIDIA GeForce 7300GT (UNKOWN)
- 0394 GeForce 7600 LE
- 0395 GeForce 7300 GT
+ 038B NVIDIA GeForce 7650 GS (G73)
+ 0390 NVIDIA GeForce 7650 GS (G73)
+ 0391 NVIDIA GeForce 7600 GT (G73)
+ 0392 NVIDIA GeForce 7600 GS (G73)
+ 0393 NVIDIA GeForce 7300 GT (G73)
+ 0394 NVIDIA GeForce 7600 LE (G73)
+ 0395 NVIDIA GeForce 7300 GT (G73)
0397 GeForce Go 7700
0398 NVIDIA GeForce Go 7600 (G73)
0399 GeForce Go 7600 GT
039B GeForce Go 7900 SE
039C Quadro FX 550M
- 039E Quadro FX 560 (Quadro FX 560)
+ 039E NVIDIA Quadro FX 560 (G73)
03A0 C55 Host Bridge
03A1 C55 Host Bridge
03A2 C55 Host Bridge
@@ -3520,10 +3674,10 @@
03BA C55 Memory Controller
03BB C55 PCIe bridge
03BC C55 Memory Controller
- 03D0 NVIDIA GeForce 6100 nForce 430 (unknown)
- 03D1 GeForce 6100 nForce 405
- 03D2 GeForce 6100 nForce 400
- 03D5 GeForce 6100 nForce 420
+ 03D0 NVIDIA GeForce 6150SE nForce 430 (C61)
+ 03D1 NVIDIA GeForce 6100 nForce 405 (C61)
+ 03D2 NVIDIA GeForce 6100 nForce 400 (C61)
+ 03D5 NVIDIA GeForce 6100 nForce 420 (C61)
03E0 PCI standard ISA bridge (nForce 430)
03E1 nForce 430 (MCP61) LPC Bridge
03E2 nForce 430 (MCP61) LPC Bridge
@@ -3535,7 +3689,7 @@
03E8 nForce 430 (MCP61) PCIe bridge
03E9 nForce 430 (MCP61) PCIe bridge
03EA nForce 430 (MCP61) Memory Controller
- 03EB nForce 430 (MCP61) SMBus
+ 03EB NVIDIA nForce PCI System Management (MCP61)
03EC nForce 430 (MCP61) IDE Controller
03EE nForce 430 (MCP61) Ethernet
03EF Nvidia Networking Card (nForce 405)
@@ -3547,33 +3701,36 @@
03F5 nForce 430 (MCP61) Memory Controller
03F6 nForce 430 (MCP61) SATA Controller
03F7 nForce 430 (MCP61) SATA Controller
- 0400 GeForce 8600 GTS
- 0402 gainward bliss 8600 gt 512mo silent fx pcx (0407)
- 0403 GeForce 8600GS
- 0404 GeForce 8400 GS (G98)
+ 0400 NVIDIA GeForce 8600 GTS (G84)
+ 0401 NVIDIA GeForce 8600 GT (G84)
+ 0402 NVIDIA GeForce 8600 GT (G84)
+ 0403 NVIDIA GeForce 8600GS (G84)
+ 0404 NVIDIA GeForce 8400 GS (G84)
0405 GeForce 9500m GS (unknown)
+ 0406 NVIDIA GeForce 8300 GS (G84)
0407 NVIDIA GeForce 8600M GT (NVIDIA GeForce 8600M GT)
0409 GeForce 8800M GS
- 040A quadro fx370 (nv17)
+ 040A NVIDIA Quadro FX 370 (G84)
040B Quadro NVS 320M
040C Mobile Quadro FX/NVS video card (NVIDIA Quadro NVS 570M)
040D Quadro FX 1600M
- 040E Quadro FX 570
- 040F Quadro FX 1700 (NV1700)
- 0420 GeForce 8400 SE
- 0421 GeForce 8500 GT (G86)
- 0422 GeForce 8400 GS
- 0423 NVIDIA Geforce 8300 GS (G86)
- 0424 GeForce 8400 GS
- 0425 GeForce 8600M GS
+ 040E NVIDIA Quadro FX 570 (G84)
+ 040F NVIDIA Quadro FX 1700 (G84)
+ 0420 NVIDIA GeForce 8400 SE (G86)
+ 0421 NVIDIA GeForce 8500 GT (G86)
+ 0422 NVIDIA GeForce 8400 GS (G86)
+ 0423 NVIDIA GeForce 8300 GS (G86)
+ 0424 NVIDIA GeForce 8400 GS (G86)
+ 0425 NVIDIA 8600m GS (NVIDIA 8600m GS)
0426 Geforce 8400M GT GPU (G86M)
0427 Geforce 8400M GS (unknown)
0428 NVIDIA GeForce 8400M G (NVIDIA GeForce 8400M G)
0429 nVidia Quadro NVS 135M or Quadro NVS 140M (Unknown)
042A Quadro NVS 130M
042B NVIDIA Quadro NVS 135M (8400 ??)
+ 042C NVIDIA GeForce 9400 GT (G86)
042D Quadro FX 360 M (Mobile) (Quadro FX 360 M)
- 042F NVIDIA Quadro NVS 290 (NVS 290)
+ 042F NVIDIA Quadro NVS 290 (G86)
0440 MCP65 LPC Bridge
0441 MCP65 LPC Bridge
0442 MCP65 LPC Bridge
@@ -3607,14 +3764,14 @@
045F MCP65 SATA Controller
0531 GeForce 7150M
0533 nVidia GeForce 7000M / nForce 610M
- 053A GeForce 7050 PV / nForce 630a
- 053B GeForce 7050 PV / nForce 630a
- 053E GeForce 7025 / nForce 630a
+ 053A NVIDIA GeForce 7050 PV / NVIDIA nForce 630a (C68)
+ 053B NVIDIA GeForce 7050 PV / NVIDIA nForce 630a (C68)
+ 053E NVIDIA GeForce 7025 / NVIDIA nForce 630a (C68)
0542 nForce PCI System Management
0543 nForce System Management Controller
0547 MCP67 Memory Controller
- 0548 MCP67 ISA Bridge
- 054C MCP67 Ethernet
+ 0548 ENE0100 (ENE0100)
+ 054C MCP67 Ethernet (MCP67)
0550 MCP67 SATA Controller(IDE mode) (MCP67)
0554 MCP67 AHCI Controller
0555 MCP67 AHCI (MCP67)
@@ -3631,39 +3788,79 @@
0563 MCP67 PCI Express Bridge
056C MCP73 PATA (MCP73)
05E0 GeForce GTX 295 (GT200b)
- 05E1 GeForce GTX 280 (GT200b)
- 05E2 GeForce GTX 260 (GT200b)
+ 05E1 NVIDIA GeForce GTX 280 (GT200)
+ 05E2 NVIDIA GeForce GTX 260 (GT200)
05E3 GeForce GTX 285 (GT200b)
- 0600 GeForce 8800 GTS 512
+ 05E6 NVIDIA GeForce GTX 275 (GT200)
+ 05E7 NVIDIA Tesla C1060 (GT200)
+ 05F8 NVIDIA Quadroplex 2200 S4 (GT200)
+ 05F9 NVIDIA Quadro CX (GT200)
+ 05FD NVIDIA Quadro FX 5800 (GT200)
+ 05FE NVIDIA Quadro FX 4800 (GT200)
+ 0600 NVIDIA GeForce 8800 GTS 512 (G92)
+ 0601 NVIDIA GeForce 9800 GT (G92)
+ 0602 NVIDIA GeForce 8800 GT (G92)
+ 0604 NVIDIA GeForce 9800 GX2 (G92)
+ 0605 NVIDIA GeForce 9800 GT (G92)
+ 0606 NVIDIA GeForce 8800 GS (G92)
0609 GeForce 8800M GTS
060B GeForce 9800M GT (G92)
060C GeForce 8800M GTX
- 0611 Alphadog edition from XFX (8800 GT)
+ 060D NVIDIA GeForce 8800 GS (G92)
+ 0610 NVIDIA GeForce 9600 GSO (G92)
+ 0611 NVIDIA GeForce 8800 GT (G92)
+ 0612 NVIDIA GeForce 9800 GTX/9800 GTX+ (G92)
+ 0613 NVIDIA GeForce 9800 GTX+ (G92)
+ 0614 NVIDIA GeForce 9800 GT (G92)
0615 GeForce GTS 250 (G92+)
- 061A Quadro FX 3700
- 0622 nVidia (nVidia GeForce 9600GT)
- 0640 Nvidia 9500GT graphic controller (G96-300-A1)
- 0641 9400 GT (G96)
- 0644 GeForce 9500 GS (G96)
- 0645 GeForce 9500 GS (G96)
+ 0619 NVIDIA Quadro FX 4700 X2 (G92)
+ 061A NVIDIA Quadro FX 3700 (G92)
+ 061B NVIDIA Quadro VX 200 (G92)
+ 0622 NVIDIA GeForce 9600 GT (G94)
+ 0623 NVIDIA GeForce 9600 GS (G94)
+ 0625 NVIDIA GeForce 9600 GSO 512 (G94)
+ 062D NVIDIA GeForce 9600 GT (G94)
+ 062E NVIDIA GeForce 9600 GT (G94)
+ 0637 NVIDIA GeForce 9600 GT (G94)
+ 0638 NVIDIA Quadro FX 1800 (0638)
+ 0640 NVIDIA GeForce 9500 GT (G96)
+ 0641 NVIDIA GeForce 9400 GT (G96)
+ 0642 NVIDIA GeForce 8400 GS (G96)
+ 0643 NVIDIA GeForce 9500 GT (G96)
+ 0644 NVIDIA GeForce 9500 GS (G96)
+ 0645 NVIDIA GeForce 9500 GS (G96)
0646 Geforce 9500GS (G95)
+ 0648 NVIDIA GeForce 9600M GS (G96)
0649 nVidia GeForce 9600M GT (G96)
- 06E2 GeForce 8400
- 06E4 GeForce 8400 GS
+ 064A GeForce 9700M GT (G96)
+ 0652 Ge Force GT 130M (G96M)
+ 065C Quadro FX 770M (unkown)
+ 06E0 NVIDIA GeForce 9300 GE (G98)
+ 06E1 NVIDIA GeForce 9300 GS (G98)
+ 06E2 NVIDIA GeForce 8400 (G98)
+ 06E3 NVIDIA GeForce 8300 GS (G98)
+ 06E4 NVIDIA GeForce 8400 GS (G98)
06E6 nVidia G100 (G100)
+ 06E7 NVIDIA GeForce 9300 SE (G98)
+ 06E9 NVIDIA GeForce 9300M GS (G98)
06EA nvidia quadro nvs 150m (unknown)
06EB Quadro NVS 160M (unknown)
+ 06F8 NVIDIA Quadro NVS 420 (G98)
+ 06F9 NVIDIA Quadro FX 370 LP (G98)
+ 06FA NVIDIA Quadro NVS 450 (G98)
+ 06FD NVidia NVS 295 (NVS 295)
+ 0753 NVIDIA nForce System Management Controller (8100)
0760 NForce Network Controller (MCP78 NIC)
0768 AHCI Controller (MCP ?)
07B5 MCP72 AHCI (MCP72)
07B9 MCP72 RAID (MCP72)
07D8 nForce 7100-630i (MCP73PV) (nForce 7100-630i (MCP73PV))
- 07DC nForce 7100-630i (MCP73PV) (nForce 7100-630i (MCP73PV))
- 07E0 GeForce 7150 / nForce 630i
- 07E1 GeForce 7100 / nForce 630i
- 07E2 GeForce 7050 / nForce 630i
- 07E3 NVidia GeForce 7050/Nvidia nForce 610i (nv4_C73)
- 07E5 GeForce 7100 / nForce 620i
+ 07DC nForce 7100-630i (MCP73PV)asdf (nForce 7100-630i (MCP73PV)asdf)
+ 07E0 NVIDIA GeForce 7150 / NVIDIA nForce 630i (C73)
+ 07E1 NVIDIA GeForce 7100 / NVIDIA nForce 630i (C73)
+ 07E2 NVIDIA GeForce 7050 / NVIDIA nForce 630i (C73)
+ 07E3 NVIDIA GeForce 7050 / NVIDIA nForce 610i (C73)
+ 07E5 NVIDIA GeForce 7050 / NVIDIA nForce 620i (C73)
07F0 MCP73 SATA(IDE mode) (MCP73)
07F4 MCP73 AHCI1 (MCP73)
07F5 MCP73 AHCI2 (MCP73)
@@ -3673,8 +3870,28 @@
07F9 MCP73 RAID2 (MCP73)
07FA MCP73 RAID3 (MCP73)
07FB MCP73 RAID4 (MCP73)
- 0863 GeForce 9400M (GeForce 9x)
- 0AA3 NVIDIA nForce System Management Controller (nForce)
+ 07FC High Definition Audio Bus (Possibly nForce 610i)
+ 0848 NVIDIA GeForce 8300 (C73)
+ 0849 NVIDIA GeForce 8200 (C77)
+ 084A NVIDIA nForce 730a (C77)
+ 084B NVIDIA GeForce 8200 (C77)
+ 084C NVIDIA nForce 780a SLI (C77)
+ 084D NVIDIA nForce 750a SLI (C77)
+ 084F NVIDIA GeForce 8100 / nForce 720a (C77)
+ 0860 NVIDIA GeForce 9300 (C79)
+ 0861 NVIDIA GeForce 9400 (C79)
+ 0863 NVIDIA GeForce 9400M (C79)
+ 0864 NVIDIA GeForce 9300 (C79)
+ 0865 NVIDIA GeForce 9300 (C79)
+ 0868 NVIDIA nForce 760i SLI (C79)
+ 086A NVIDIA GeForce 9400 (C79)
+ 086C NVIDIA GeForce 9300 / nForce 730i (C79)
+ 086D NVIDIA GeForce 9200 (C79)
+ 086F GeForce 8200M G (MCP79MVL)
+ 0871 NVIDIA GeForce 9200 (C79)
+ 087A NVIDIA Quadro FX 470 (C79)
+ 0A65 Nvidia 200 Series (GeForce 210)
+ 0AA3 nForce 730i SMBus Controller (MCP7A)
0AB0 ID0A80 (NForce 9300)
0AB8 MCP79 AHCI1 (MCP79)
0AB9 MCP79 AHCI2 (MCP79)
@@ -3685,9 +3902,11 @@
0BC5 AHCI Controller (MCP?)
0BCC Raid Controller (MCP?)
0BCD Raid Controller (MCP?)
- 10DE Riva 128 (NV3)
+ 10DE Riva 128 (NV34)
+ 10F0 PCI DEVICE (NV3)
1112 Gateway Solo 9550 NVIDIA Geforce 2 GO 32 MB (0x1112)
8001 nVidia MCP73 HDMI Audio Driver (MCP73)
+ 9876 GeForce2 MX / MX 400 (NV11)
10DF Emulex Corporation
10DF Fibre Channel Adapter (Light Pulse)
1AE5 LP6000 LightPulse Fibre Channel Host Adapter
@@ -3709,7 +3928,7 @@
F0F5 Neptune LightPulse Fibre Channel Host Adapter
F0F6 LPX000 Fibre Channel Storport Driver
F0F7 LPX000 Fibre Channel Storport Driver
- F100 LP11000e Fibre Channel Host Adapter
+ F100 8Gb PCIe Single / Dual port Fibre Channel Adapter (LPe12000 / LPe12002)
F700 LP7000 LightPulse Fibre Channel Host Adapter
F701 LP7000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
F800 LP8000 LightPulse Fibre Channel Host Adapter
@@ -3779,7 +3998,7 @@
8089 Kingsberg Spacetec Serial Output Board (SOB)
809C Traquair HEPC3 (S5933)
80B1 Active ISDN Controller (Data Fire Basic 4MB PCI)
- 80B9 Some sort of Bridge? (PCI MATCHMAKER S5933QC)
+ 80B9 Some sort of Bridge? (PCI MATCHMAKER S5935QF)
80D7 Data Acquisition Card (ADLINK) (PCI-9112)
80D8 40MB/s 32-channels Digital I/O card (ADLINK) (PCI-7200)
80D9 Data Acquisition Card (ADLINK) (PCI-9118)
@@ -3787,7 +4006,7 @@
80FC APCI1500 Signal processing controller (16 dig. inputs + 16 dig. outputs)
811A PCI-IEEE1355-DS-DE interface (PCI-DSlink)
814C Fastcom ESCC-PCI (Commtech, Inc)
- 8170 Matchmaker PCI Chipset Development Tool (S5933Q)
+ 8170 Matchmaker PCI Chipset Development Tool (S5933QF)
81B7 S5933 AJAVideo NTV ITU-R.601 Video stillstore
81E6 Multimedia video controller
828D APCI3001 Signal processing controller (up to 16 analog inputs)
@@ -3803,7 +4022,8 @@
8406 PCIcanx/PCIcan CAN interface [Kvaser AB]
8407 PCIcan II CAN interface (A1021, PCB-07, PCB-08) [Kvaser AB]
8851 S5933 on Innes Corp FM Radio Capture card
-10E9 Alps Electric Corp Ltd
+10E9 Alps Electronic Corp. Ltd.
+ 10E9 no (VID_044E&PID_3017)
10EA Tvia Inc (Was: InterGraphics Systems (IGS))
1680 svga (IGA-1680)
1682 video (IGA-1682)
@@ -3819,36 +4039,42 @@
8111 Frame Grabber (Twist3)
10EC Realtek Semiconductor
0139 ethernet 10/100 (rtl8139B)
+ 0158 Realtek 5121 Driver Disk (Realtek 5121)
0260 Driver MS UAA for HD Audio (RTL260)
0261 261 High Definition Audio
0262 Realtek High Definition Audio (ALC882)
- 0268 Audio Device on High Definition Audio Bus (Realtek ALC268)
+ 0268 Realtek 2+2 High Definition Audio (Realtek ALC268)
+ 0269 Realtek High Definition Audio (I don't know about chip number)
0280 280 High Definition Audio
0660 High Definition Audio (Realtek HD Audio)
- 0662 Realtek ALC662 HD Audio (ALC662)
- 0861 861 High Definition Audio
+ 0662 Realtek 5.1 High Definition Audio (ALC662)
+ 0861 Realtek High Definition Audio (ALC660)
0862 862 High Definition Audio
- 0880 880 High Definition Audio
- 0883 Realtek High Definition Audio (alc888S)
- 0885 7.1+2 Channel High-Performance HDA Codec with Content Protection (ALC885)
- 0888 Realtek Azak lia chipset (realtek high definition audio)
+ 0880 Realtek 7.1 High Definition Audio (ALC880)
+ 0882 Realtek 7.1+2 High Definition Audio (ALC882)
+ 0883 Realtek 7.1+2 High Definition Audio (ALC883)
+ 0885 8-channel High Definition Audio (ALC885)
+ 0888 Realtek 7.1+2 High Definition Audio (ALC888)
8021 NIC (RTL8029AS)
- 8029 windot XPse (RTL8029(as)pci ethernet nic)
+ 8029 PCI Full-Duplex Ethernet Controller with PnP Function (RTL8029)
8119 32BIT Card Bus 10/100 (10EC-8119) (10)
8129 RT8129/8130 Fast Ethernet Adapter
- 8131 LFE8139ATX
- 8136 RTL8100E/RTL8101E/RTL8102E-GR (RTL8100-8101E-8102E-PCIEXPRESS)
+ 8131 ethernet controller (LFE8139ATX)
+ 8136 Realtek 10/100/1000 PCI-E NIC Family all in one NDIS Driver v5.728.0604.2009 06/04/2009 (Rtl8023)
8138 RT8139 (B/C) CardBus Fast Ethernet Adapter
- 8139 Realtek RTL8139 Family PCI Fast Ethernet NIC (RTL-8139/8139C/8139C)
- 8167 RTL8169/8110 Family Gigabit Ethernet NIC
- 8168 Gigabit Ethernet NIC(NDIS 6.0) (RTL8168/8111)
- 8169 Single Gigabit LOM Ethernet Controller (RTL8119)
+ 8139 Realtek RTL8139 Family PCI Fast Ethernet NIC (RTL-8139/8139C/8139D)
+ 8167 Realtek RTL8169/8110 Family Gigabit Ethernet NIC (RTL8169 / RTL8111B / RTL8111C)
+ 8168 Gigabit Ethernet NIC(NDIS 6.0) (RTL8168/8111/8111c)
+ 8169 Single Gigabit LOM Ethernet Controller (RTL8110)
+ 8172 Realtek RTL8191SE wireless LAN 802.11N PCI-E NIC (RTL8191SE ?)
8180 RTL8180L IEEE 802.11b Wireless MAC and Baseband Processor
8185 IEEE 802.11a/b/g Wireless LAN Controller (rev 20) (RTL-8185)
8186 PCI Express Gigabit Ethernet controller (RTL8111/8168B)
+ 8192 - (0280)
8197 Wireless 802.11b/g 54Mbps USB 2.0 Network Adapter (8187B)
8199 Single-Chip IEEE 802.11b/g WLAN Controller w/PCI Express Interface (RTL8187SE)
9876 GIGABIT ETHERNET LOM (RTL 8168/8111)
+ 9877 GIGABIT ETHERNET LOM (RTL 8168/8111)
10ED Ascii Corporation
7310 VGA Video Overlay Adapter (V7310)
10EE Xilinx Corporation
@@ -3942,18 +4168,18 @@
0003 AWE64D OEM (CT4600) (EMU8008)
0004 Audigy Audio Processor (Creative SB Audigy 2 ZS (WDM))
0005 SoundBlaster X-FI XtremeMusic (SB0460)
- 0006 Soundblaster Live! 5.1 (emu10k1x)
+ 0006 Soundblaster Live! 5.1 (SB0200) (emu10k1x)
0007 Device ID same for both, but Subsystem ID = 0x1012 - Extreme Audio, 0x100A - Audigy SE 7.1 (C6SB0410515017656A)
0008 sound blaster Audigy 2 (ca0108)
- 1017 3D Blaster Banshee PCI CT6760 (CT6760)
+ 1017 3D Blaster Banshee PCI CT6760 (ct4830)
1020 3D Blaster RIVA TNT2 (NV5)
1047 3D Blaster Annihilator 2 (EV1938)
1371 ?
2898 es56t-p1 (es2898)
4001 Audigy IEEE1394a Firewire Controller (EMU10K1)
647D AC'97 Audio Device
- 7002 GamePort (EMU10000)
- 7003 Creative Labs SB Audigy MIDI/Game port (EMU10K2 (for Vista 32 bit))
+ 7002 GamePort (EMU10K1)
+ 7003 Creative Labs SB Audigy MIDI/Game port (EMU10K2 )
7004 Game port for SB Live! Series
7005 Audigy LS Series Game Port
7802 Environmental Audio (SB Live) (EMU1OK1-NGF)
@@ -3962,7 +4188,7 @@
9838 Ectiva EV1938
1103 Triones Technologies Inc. (HighPoint)
0003 HPT343/5/6,HPT363 UDMA EIDE Controller
- 0004 ATA Raid Controller (HPT366/368/370/370A)
+ 0004 ATA Raid Controller/ATA 100 (HPT366/368/370/370A/372)
0005 PATA133 Raid Controller (HPT372/372N)
0006 HPT302N UDMA/ATA133 RAID Controller
0007 HPT371/N UDMA/ATA133 EIDE Controller
@@ -4006,7 +4232,8 @@
8485 EM8485 REALmagic DVD/MPEG-4 A/V Decoder
8486 EM8486 REALmagic DVD/MPEG-4 A/V Decoder
C622 EM8622L MPEG-4.10 (H.264) and SMPTE 421M (VC-1) A/V Decoder
-1106 VIA Technologies Inc
+ C623 Media Decoder SoC (EM8623L)
+1106 VIA Technologies, Inc.
0102 Embedded VIA Ethernet Controller
0130 VIA Fire 1394.A OHCI Link Layer Ctrlr (VT6305)
0198 P4X600 CPU to PCI Bridge
@@ -4014,7 +4241,7 @@
0208 PT890 Standard Host Bridge
0238 CPU to PCI Bridge (K8T890)
0258 PT880 CPU to PCI Bridge
- 0259 PM880 CPU to PCI Bridge
+ 0259 Host Bridge (CN400/PM880)
0269 CPU to PCI Bridge (KT880)
0282 CPU to PCI Bridge (K8T880Pro)
0290 K8M890 Standard Host Bridge
@@ -4030,6 +4257,7 @@
0351 VT3351 Host Bridge
0364 P4M900 Host Bridge
0391 VT8371 KX133 System Controller
+ 0397 VIA High Definition Audio (VT1708S)
0501 VT8501 Apollo MVP4 System Controller
0505 VLB to PCI Bridge (82C505)
0561 VT82C570 MV IDE Controller (Single FIFO)
@@ -4053,7 +4281,7 @@
0698 VT82C693A Apollo Pro133 AGP
0926 VT86C926 Amazon NE2000-Compatible PCI Ethernet Controller
1000 VT82C570 MV System Controller
- 1106 ISA Bridge w/IDE (060000A1106060000A ISA Bridge w/IDE)
+ 1106 VIA Sound VIA AC97 in VT82C686A/B, VIA AC97 in VT8233/AC, VT8235 & VT8237/R, VIA Vinyl audio VT1612A (060000A1106)
1107 ISA Bridge w/IDE (060000A)
1204 K8M400 CPU to PCI Bridge
1208 PT890 Standard Host Bridge
@@ -4076,14 +4304,14 @@
1401 ISA Bridge w/IDE (060000A)
1571 IDE Controller (VT82C416)
1595 VT82C595 Apollo VP2,VP2-97 System Controller
- 1708 VEN_1106&DEV_1708 (0x1708)
+ 1708 High Definition Audio controller (VIA VT1708 )
2006 VIA Rhine III VT6105M Fast Ethernet controller (VT6105M)
2106 VT6105 Rhine Family Fast Ethernet Adapter
2204 K8M400 CPU to PCI Bridge
2208 PT890 Standard Host Bridge
2238 CPU to PCI Bridge (K8T890)
2258 PT880 CPU to PCI Bridge
- 2259 PM880 CPU to PCI Bridge
+ 2259 Host Bridge (CN400/PM880)
2269 CPU to PCI Bridge (KT880)
2282 CPU to PCI Bridge (K8T880Pro)
2290 K8M890 Standard Host Bridge
@@ -4112,10 +4340,10 @@
3051 Power Management Controller
3053 Rhine III Management Adapter (VT6105M)
3057 ACPI Power Management Controller (VT82C686A/B)
- 3058 AC97 Audio Codec (All VIA Chipsets) (VT8237r)
- 3059 This is really a C-media AC97 audio device. The VIA driver would never install on this system. (VT8237)
- 3065 Rhine II PCI Fast Ethernet Controller||Used by GERICOM in laptop Webengine Advanced (VT6102)
- 3068 PCIVEN_1106&DEV_3068&SUBSYS_0C041019&REV_803&61AAA01&0&8E (PCIVEN_1106&DEV_3068&SUBSYS_0C041019&REV_803&61A)
+ 3058 AC97 Audio Codec (All VIA Chipsets) (VT8275)
+ 3059 VT8233/A AC'97 Enhanced Audio Controller
+ 3065 Rhine II PCI Fast Ethernet Controller (VT6103)
+ 3068 VIA MC97 controller for AC-Link modems (PCIVEN_1106&DEV_3068&SUBSYS_100B14FF&REV_803&267)
3074 PCI to ISA Bridge (VT8233)
3086 VT82C686 Power Management Controller (??)
3091 VT8633 Apollo Pro 266 CPU to PCI Bridge
@@ -4126,7 +4354,7 @@
3104 VT6202/12 USB 2.0 Enhanced Host Controller
3106 Rhine III PCI Fast Ethernet Controller (VT6105M/LOM)
3107 PCI to ISA Bridge (VT8233/A AC97' Enhance Audio Controller)
- 3108 Via Unichrome S3 VGA - part of a VIA Northbridge (Unknown)
+ 3108 Via Unichrome S3 VGA - part of a VIA Northbridge (8380)
3109 PCI to ISA Bridge (VT8233/A AC97' Enhance Audio Controller)
3112 VT8361 Apollo KLE133 System Controller
3113 VPX/VPX2 PCI to PCI Bridge
@@ -4141,7 +4369,7 @@
3148 VT8751 ProSavageDDR P4M266 System Controller
3149 SATA RAID Controller (VT8237 Family/ VT6420)
3156 VT8372 ProSavageDDR PN266/KN266 CPU to PCI Bridge
- 3157 CX700M2 UniChrome PRO II Graphics
+ 3157 VIA/S3G Unichrome Pro IAGP (VIA VT8237)
3158 ProSavageDDR P4N266 CPU to PCI Bridge
3164 VIA VT6410 PATA/PATA RAID Controller (VT6410)
3168 P4X400 Host Controller/AGP Bridge (VT8374)
@@ -4152,13 +4380,13 @@
3198 CPU-to-PCI Bridge (VEN_1106&DEV_B198&SUBSYS_00000000&REV_00)
3202 K8N400 CPU to PCI Bridge
3204 CPU to PCI Bridge (1394 i2c)
- 3205 KM400 CPU to PCI Bridge
+ 3205 CPU to PCI Bridge (PCIVEN_1106&DEV_3205&SUBSYS_00000000&REV_003&61A)
3208 CPU to PCI Bridge (PT890)
3209 P4M400 CPU to PCI Bridge
3213 VPX/VPX2 PCI to PCI Bridge
3218 K8T800M CPU to PCI Bridge
3227 PCI-to-ISA Bridge (VT8237)
- 3230 Integrated Graphics (K8N890CE Display Driver)
+ 3230 Integrated Graphics (K8M890CE & K8N890CE Display Driver)
3238 CPU-to-PCI Bridge (K8T890)
3249 VIA VT6421 RAID Controller - Windows XP 32.bit (VT6421)
324A CX700 PCI to PCI Bridge
@@ -4170,7 +4398,7 @@
3269 CPU to PCI Bridge (KT880)
3282 CPU to PCI Bridge (K8T880Pro)
3287 VT8251 Standard PCI to ISA Bridge
- 3288 VIA VT8251/8237A High Definition Audio Controller - HDA Codec Realtek ALC660 (040300)
+ 3288 HDA Codec Realtek ALC660 (040300)
3290 K8M890 Standard Host Bridge
3296 P4M800 Standard Host Bridge
3324 CX700 Host Bridge
@@ -4178,8 +4406,8 @@
3336 K8M890CE Host Bridge
3337 VT8237A Standard PCI to ISA Bridge
3340 PT900 Host Bridge
- 3343 VIA/S3G UniChromePro IGP
- 3344 VIA/S3G UniChrome Pro IGP (P4M800PRO&8237R)
+ 3343 VIA S3G UniChrome Family (81CE1043)
+ 3344 VIA/S3G UniChrome Pro IGP (VT3314)
3349 VIA VT8251 AHCI RAID Controller (VT8251)
3351 VT3351 Host Bridge
3364 P4M900 Host Bridge
@@ -4283,7 +4511,7 @@
B133 CPU to AGP Controller (vt686b)
B148 VT8751 ProSavageDDR P4M266 CPU to AGP Bridge
B156 VT8372 ProSavageDDR PN266/KN266 PCI to AGP Bridge
- B158 ProSavageDDR P4N266 PCI to AGP Bridge
+ B158 PCI-to-PCI Bridge (AGP) (VIA Technologies Inc)
B168 ProSavageDDR P4X333 CPU to AGP 2.0/3.0 Bridge
B188 PCI-to-PCI Bridge (AGP 2.0/3.0) (3200+)
B198 ProSavageDDR P4X600,Apollo KT400/A/600 CPU to AGP Bridge
@@ -4341,7 +4569,7 @@
110B CHROMATIC Research Inc / Xenon Microsystems
0001 Media Processor (Mpact)
0002 MPACT DVD decoder. (GM90C7110VX)
- 0004 Mpact2 3DVD Media Processor
+ 0004 Integrated video card (Mpact)
110C Mini-Max Technology Inc
110D ZNyX Corp
110E CPU Technology
@@ -4356,7 +4584,7 @@
2340 4 Port Fast Ethernet Adapter
2400 ATM adapter (2400)
1113 Accton Technology Corporation
- 1211 EN-1207D Fast Ethernet Adapter
+ 1211 Ethernet Controller 10/100 MBit (EN5030, EN5038)
1216 EN-5251 Based Fast Ethernet Adapter
1217 Ethernet Adapter (EN-2242)
5105 10Mbps Network Card
@@ -4420,7 +4648,7 @@
0137 Disk Array Controller (GDT 6x23RS)
0138 GDT 6118RS/6518RS/6618RS
0139 GDT 6128RS/6528RS/6628RS
- 013A GDT 6538RS/6638RS
+ 013A IBM IXA - Integrated xSeries Adapter (GDT 6x38RS)
013B GDT 6558RS/6658RS
013C GDT 6533RS/6633RS
013D GDT 6543RS/6643RS
@@ -4464,8 +4692,12 @@
0003 MICRO ABR SAR PCI ATM Controller (IDT77222/252)
0004 MICRO ABR SAR PCI ATM Controller (IDT77V252)
7608 IDT High Definition Audio CODEC (IDT Audio CODEC)
+ 7618 SigmaTel High Definition Audio CODEC (STAC9227)
+ 7634 IDT/Sigmae HDl Audio Driver v6.10.5939.0 05/06/2008 (IDT_Audiov5939)
+ 7662 IDT/Sigmae HDl Audio Driver v6.10.5939.0 05/06/2008 (IDT_Audiov5939)
7675 92HD73C1 (92HD73C1)
76B2 IDT Audio (92HD71B7)
+ 76D5 0x3649 (0x76D5)
111E Eldec Corp
111F Precision Digital Images
4A47 Video engine interface (Precision MX)
@@ -4497,8 +4729,8 @@
0001 Video Frame Grabber / Processor
1130 Computervision
F211 USB Audio Sound Card (0x010)
-1131 Philips Semiconductors
- 1001 BlueTooth Adapter (bm05e )
+1131 Animation Technologies Inc
+ 1001 BlueTooth Adapter ISSCBTA [Tripper USB Dongle] (bm05e )
1131 01384E42y8
1201 VPN IPSEC coprocessor (PTD3000)
1234 EHCI USB 2.0 Controller
@@ -4510,12 +4742,13 @@
5400 Multimedia processor (TriMedia TM1000/1100)
5402 Media Processor (TriMedia TM-1300EH)
5406 TriMedia PNX1700
- 7130 Philips SAA7135HL Multimedia Capture Device (73c0a1434628)
+ 7130 PCI video broadcast decoder (SAA7130HL)
7133 Phillips TV7131 WDM video capture (Phillips TV7131 WDM video capture)
- 7134 Tevion MD-9717 TV Tuner Card (TV7134RF) (SAA7130HL)
+ 7134 SAA7134HL Multimedia Capture Device
7135 SAA???? Multimedia Device(??)
7145 SAA7145 Multimedia PCI Bridge
- 7146 SAA7146 Multimedia Bridge Scaler
+ 7146 PCIVEN_1131&DEV_7130&SUBSYS_D1091461&REV_013&61AAA01&0&60 (saa7146)
+ 7160 PCIVEN_13D0&DEV_2103&SUBSYS_210313D0&REV_024&1AF1648C&0&10F0 (Philips SAA7134E, TDA10046 and TDA8275A)
7162 SAA7162 Hybrid Capture Device
9730 Ethernet controller (SAA9730)
1132 Mitel Corp
@@ -4557,7 +4790,7 @@
E015 Diva Server PRI-30M PCI v.2
E016 Diva Server Voice 4BRI PCI
E017 Diva Server Voice 4BRI PCI Rev 2
- E018 DIVA Server BRI-2M/-2F
+ E018 DIVA Server BRI-2M/-2F (00)
E019 DIVA Server Voice PRI 2.0 PCI
E01A Diva Server 2FX
E01B Diva Server BRI-2M Voice Revision 2
@@ -4570,8 +4803,9 @@
E02A Diva Server IPM-300
E02C Diva Server IPM-600
1134 Mercury Computer Systems Inc.
- 0001 Raceway Bridge
+ 0001 audio driver (3059)
0002 Dual PCI to RapidIO Bridge (DPRB)
+ 9876 aodio driver (3059)
1135 Fuji Xerox Co Ltd
0001 Printer Controller
1136 Momentum Data Systems
@@ -4658,7 +4892,7 @@
114F Digi International
0002 AccelePort EPC/X
0003 RightSwitch SE-6
- 0004 AccelePort Xem
+ 0004 driver (AccelePort Xem)
0005 AccelePort Xr EIA-232
0006 AccelePort C/X
0007 Digi Data Fire PCI 1 S/T (DataFire PCI 1 S/T)
@@ -4746,7 +4980,7 @@
0076 Xircom MPCI3B-56G (Lucent SCORPIO) Soft
00D3 Xircom MPCI Modem 56
00D4 Modem 56k (MPCI)
- 0101 CardBus 56k Modem
+ 0101 CardBus 56k Modem (Ms0612006303)
0103 CardBus Ethernet + 56k Modem
0104 RealPort2 CardBus Modem 56
115E Peer Protocols Inc
@@ -4779,7 +5013,7 @@
0031 HT1100 HPX0 HT Host Bridge
0036 HT1000 PCI/PCI-X bridge
0101 CIOB-X2
- 0103 Broadcom dual gigabit, pci bridge (BCM5715)
+ 0103 EPB PCIe to PCI-X Bridge
0104 HT1000 PCI/PCI-X bridge
0110 I/O Bridge with Gigabit Ethernet ServerWorks Grand Champion (CIOB-E)
0130 HT1000 PCI-X bridge
@@ -4812,7 +5046,7 @@
0240 K2 SATA
0241 8-Channel RAIDCore SATA RAID Host Bus Adapter (BC4852)
0242 RAIDCore BC4000
- 024A BCM5785 (HT1000) SATA Native SATA Mode
+ 024A Broadcom/Serverworks HT1000 SATA Controller (HT1000)
024B BCM5785 (HT1000) PATA/IDE Mode
0406 HT1100 PCI-X Bridge
0408 HT1100 Legacy Device
@@ -4851,7 +5085,9 @@
1171 Loughborough Sound Images
1172 Altera Corporation
0001 S CCA5000243A (EPF6016ATC144-2)
- 0004 Multi-serial card
+ 0004 Multi-serial card (-epf6016qc240-2)
+ 0007 Altera FPGA board (StratixIIGX)
+ D4AA Arria GX (EP1AGX90EF1152C6N)
1173 Adobe Systems
1174 Bridgeport Machines
1175 Mitron Computer Inc
@@ -4880,7 +5116,7 @@
0618 CPU to PCI and PCI to ISA Bridge
0701 PCI Communication Device (vt82c693)
0804 Toshiba Smart Media Host Controller (0x0804)
- 0805 SD Card Controller (PCIVEN_1180&DEV_0592&SUBSYS_828D1033&REV_064&5A9)
+ 0805 SD Card Controller (PCIVEN_1179&DEV_0805&SUBSYS_FF001179&REV_03 )
0D01 FIR Port Type-O (0x0D01)
13A8 Multi-channel PCI UART (XR17C158/154/152)
117A A-Trend Technology
@@ -4892,7 +5128,7 @@
117E T/R Systems
0001 Printer Host
117F Integrated Circuit Systems
-1180 Ricoh Company, Ltd.
+1180 Ricoh Co Ltd
0465 RL5c465 CardBus Controller
0466 RL5c466 CardBus Controller
0475 Cardbus Controller (RL5c592)
@@ -4906,14 +5142,16 @@
0554 R5C554
0575 SD Bus Host Adapter
0576 SD Bus Host Adapter
- 0592 Ricoh Memory Stick Host Controller (13871043)
+ 0592 Ricoh Memory Stick Host Controller (13171043)
0811 R5C811
- 0822 SDA Standard Compliant SD Host Controller (R5C832, R5C843)
+ 0822 SDA Standard Compliant SD Host Controller (R5C832)
0832 IEEE 1394 (4 pin firewire) chip) (30CF103C)
0841 R5C841 CardBus/SD/SDIO/MMC/MS/MSPro/xD/IEEE1394
0843 Ricoh SD/MMC Host Controller (R5C853)
- 0852 Ricoh xD-Picture Card Host Controller (01cf1028)
+ 0852 http://driverzone.com/device.php?id=51441 (01cf1028)
5551 IEEE 1394 Controller (Unknown)
+ E230 Ricoh PCIe Memory Stick Host Controller (R5U230)
+ E832 Ricoh PCIe IEEE1394 Fireware Host Controller (R5U832)
1181 Telmatics International
1183 Fujikura Ltd
1184 Forks Inc
@@ -4928,12 +5166,12 @@
1100 Fast Ethernet Adapter (driv16c003206)
1300 DFE-528TX/530TX+/538TX Fast Ethernet Adapter (DL 10038C Chipset)
1301 Fast Ethernet Adapter (DGE-528T )
- 1340 DFE-690TXD CardBus Fast Ethernet Adapter
+ 1340 Fast Ethernet CardBus PC Card (DFE-690TXD)
1405 DFE-520TX Fast Ethernet PCI Adapter
1541 DFE-680TXD CardBus PC Card
1561 CardBus PC Card (DRP-32TXD)
2027 DWL-G520 AirPlus Xtreme G Adapter
- 3065 D-Link DFE-500Tx PCI fast Ethernet adapter Rev.A (14001186)
+ 3065 D-Link DFE-500Tx PCI fast Ethernet adapter Re v.A (14001186)
3106 Fast Ethernet Adapter (DFE 530TX+ rev E1)
3203 DWL-G520 AirPlus Xtreme G Adapter
3300 IEEE 802.11g PCI card (D-Link Air Wireless Network (DWL-G510))
@@ -4953,7 +5191,7 @@
3C09 Ralink RT61 (DWL-G510 Version C1)
4000 Gigabit Ethernet Adapter (DL2000)
4001 D Link Fast Ethernet PCMCIA Card (DFE-650TX)
- 4300 Used on DGE-528T Gigabit adaptor (dlg10028)
+ 4300 Used on DGE-528T Gigabit adaptor (dlg10086)
4346 DGE-560SX Single Fiber Gigabit Ethernet PCI-E Adapter V.A1
4B00 DGE-560T PCIe Gigabit Ethernet Adapter
4B01 DGE-530T V.B1 Gigabit Ethernet Adapter (rev 11)
@@ -5090,6 +5328,7 @@
4354 Marvell Yukon 88E8040 PCI-E Fast Ethernet Controller (88E8040)
4355 Marvell Yukon 88E8040T PCI-E Fast Ethernet Controller (88E8040T)
4356 Yukon 88EC033 PCI-E Fast Ethernet Controller
+ 4357 marvell ethernet lan (0)
4360 Yukon PCI-E ASF Gigabit Ethernet Controller (88E8050)
4361 Yukon 88E8050 PCI-E ASF Gigabit Ethernet Controller
4362 Marvell Yukon 88E8053 PCI-E Gigabit Ethernet Controller (88E8053)
@@ -5103,7 +5342,7 @@
436A Yukon 88E8058 PCI-E Gigabit Ethernet Controller
436B Yukon 88E8071 PCI-E Gigabit Ethernet Controller
436C Marvell 8072 Ethernet Nic (88E8072)
- 4380 Marvell Yukon 88E8057 PCI-E Gigabit Ethernet Controller (88E8057)
+ 4380 Marvell Yukon 88E8057 PCI-E Gigabit Ethernet Controller (88e8057)
4611 System Controller (GT-64115)
4620 System Controller for R5000 & R7000 (64-bit PCI) (GT-64120)
4801 GT-48001 8-port Switched Ethernet Controller
@@ -5198,8 +5437,10 @@
0001 PCI FDDI (NPI NuCard)
11BD Pinnacle Systems Inc
0015 rob2d (660806-2.0)
- BEBE pinnacle, bendino V1.0A | Studio MovieBoard 500-PCI V.10 (51011810)
- BEDE MB87J3560 (51015777)
+ 1158 spcialit lectronique et informatique
+ 11BD maintenance informatique
+ BEBE MAINTENANCE INFORMATIQUE VENTE DE CONSOMABLE (51015777)
+ BEDE MB87J3560 (51011810)
11BE International Microcircuits Inc
11BF Astrodesign Inc
11C0 Hewlett Packard
@@ -5207,11 +5448,11 @@
0420 CardBus 56k Modem
0440 Data+Fax+Voice+DSVD (LT Winmodem 56k)
0441 LT WinModem 56k Data+Fax
- 0442 LT WinModem 56K Data+Fax (1648T00)
+ 0442 LT WinModem 56K Data+Fax (1646T00)
0443 1646T00 (LT Winmodem)
0444 845G (LT Winmodem)
0445 LT WinModem
- 0446 LT WinModem
+ 0446 PCIVEN_10DE&DEV_0446&SUBSYS_73691462&REV_A13&267A616A&0&09 (LT Winmodem)
0447 windowsme (LT Winmodem)
0448 SV2P2 (LT Winmodem 56k)
0449 0449144F (LT Winmodem 56k)
@@ -5240,14 +5481,16 @@
0464 Lucent Wildwire v.90 + DSL modem (This is NOT a Riptide! (as previously stated))
0480 56k.V90/ADSL Wildfire Modem (Venus Winmodem)
048B creative modem blaster di5733-1 (1648T00)
- 048C creative modem blaster di5733-1 (1648c-tv5)
+ 048C net-comm modem (1648c-tv5)
+ 048D 9m56pml-g (lt winmodem)
048E 56k V.92modem (svp92pl-t00)
048F Agere PCI Soft Modem. SV92PL (SV92P-T00)
0540 ?
0600 SV92P-T00 Agere PCI Soft Modem. SV92PL (sv92p2)
- 0620 Agere PCI Soft Modem for linux unbuntu (SV92PP)
- 1040 VEN_11C1&DEV_1040&SUBSYS_103C137E&REV_1002 (Prespa)
- 3026 Agere Systems HDA Modem (0x11c13026)
+ 0620 Agere PCI Soft Modem (SV92PP)
+ 1040 VEN_11C1&DEV_1040&SUBSYS_11790001 (Prespa)
+ 11C1 VEN_11C1&DEV_0620&SUBSYS_11790001&REV_1002 (Prespa)
+ 3026 Agere Systems HDA Modem (0x11c11040)
5400 FPSC FPGA with 32/64bit, 33/66MHz core (OR3TP12)
5801 USB Open Host Controller
5802 2-port PCI-to-USB OpenHCI Host Ctrlr (USS-312MC)
@@ -5261,7 +5504,7 @@
AB11 WL60040 Multimode Wireles LAN MAC
AB20 PCI Wireless LAN Adapter (WaveLAN)
AB21 Wireless PCI Adapter
- AB30 Mini-PCI WaveLAN a/b/g (Hermes2?)
+ AB30 Mini-PCI WaveLAN a/b/g (wlsam48d)
ED00 ET-131x PCI-E Gigabit Ethernet Adapter
ED01 ET-1301 PCI-E Fast Ethernet Adapter
11C2 Sand Microelectronics
@@ -5304,11 +5547,13 @@
1807 56k Winmodem Chip
1884 SoundMAX Integrated Digital HD Audio (AD1884HD)
1889 Sound Chip (AD1980)
+ 194A SoundMAX Integrated Digital Audio (AD1984A)
1981 SoundMAX Integrated Digital Audio (8086)
1983 SoundMAX Integrated Digital HD Audio (AD1983HD)
1984 Analog Devices ADI 198x Integrated HD Audio (Analog Devices ADI 198x)
1986 SoundMAX Integrated Digital HD Audio (AD198b)
- 198B AD1988B HD Audio CODEC (AD1988B)
+ 1988 HD Audio Codec (AD1988A)
+ 198B AD1988B HD (AD1988B)
2192 DSP Microcomputer (function *0) (ADSP-2192)
219A DSP Microcomputer (function *1) (ADSP-2192)
219E DSP Microcomputer (function *2) (ADSP-2192)
@@ -5324,6 +5569,7 @@
11D8 Image Technologies Development
11D9 TEC Corp
11DA Novell
+ 2000 Virtual-Bus / AlacrityVM bridge
11DB SEGA Enterprises Ltd
1234 Dreamcast Broadband Adapter
11DC Questra Corp
@@ -5355,7 +5601,7 @@
11EF Nicolet Technologies B.V.
11F0 Compu-Shack GmbH
4231 FDDI Network Card
- 4232 FASTline UTP Quattro
+ 4232 PCIVEN_8086&DEV_4232&subsys_12018086&rev_004&b04cce1&0&00e1 (FASTline UTP Quattro)
4233 FASTline FO
4234 FASTline UTP
4235 FASTline-II UTP
@@ -5454,7 +5700,7 @@
0300 PC300 RX 2
0301 PC300 RX 1
0302 PC300 TE 2
- 0303 PC300 TE 1
+ 0303 teclado (PC300 TE 1)
0310 PC300 TE 2
0311 PC300 TE 1
0320 PC300/TE-M (2 ports)
@@ -5469,7 +5715,7 @@
1214 Performance Technologies Inc
1215 Interware Co Ltd
1216 Purup Prepress A/S
- 0003 PTM400 PCI Taxi Module
+ 0003 PTM400 PCI Taxi Module (188A2L432B)
1217 O2 Micro Inc
00F7 1394 Open Host Controller Interface (0x00f71217)
6729 PCI to PCMCIA Bridge (OZ6729)
@@ -5485,9 +5731,10 @@
7113 SmartCardBus Contoller (0Z711EC1)
7114 OZ711M1 SmartCardBus MultiMediaBay Controller
7120 O2Micro Integrated MMC/SD controller (Unknown device)
- 7130 Integrated MMC/SD/MS/xD/SM Controller (OZ711M3)
+ 7130 O2Micro Integrated MMC/SD/MS/xD/SM Controller (0000000A)
7134 MemoryCardBus Controller 6-in-1 (OZ711MP1/MS1)
7135 MemoryCardBus Contoller (OZ711EZ1)
+ 7136 O2Micro CardBus Controller (OZ711SP1)
71E2 OZ711E2 SmartCardBus Controller
7212 OZ711M2 SmartCardBus MultiMediaBay Controller
7213 OZ6933E CardBus Controller
@@ -5664,7 +5911,7 @@
199B Maestro-3.COMM PCI Voice+audio (ES1938/41/46 solo audio)
2808 PCI Fax Modem (later model) (ES336H)
2828 TeleDrive (ES2828S)
- 2838 ES2838/2839 SuperLink Modem
+ 2838 Data Fax Modem (ES56H-PI4555)
2839 Superlink Modem/V.92 chipset 56K
2843 ES2838/2839 SuperLink-MLP Voice Modem
2847 ES2838/2839 SuperLink-MLP 10 Voice Modem
@@ -5715,7 +5962,8 @@
1270 Olympus Optical Co Ltd
1271 GW Instruments
1025 SoftV90 Data Fax Modem
-1272 Telematics
+1272 Telematics International
+ 0780 PCIVEN_1272&DEV_0780&SUBSYS_00000008&REV_7A3&61AAA01&0&58 (PCIVEN_1272&DEV_0780&SUBSYS_00000008&REV_7A3&61A)
1273 Hughes Network systems
0002 t9p17af-01 (DirecPC)
1274 Creative (Was: Ensoniq)
@@ -5723,7 +5971,7 @@
1371 ES1371, ES1373 AudioPCI
1373 Sound Blaster Audio(PCI) (ES1373)
5000 AudioPCI (ES1371)
- 5880 Soundblaster (5880x)
+ 5880 Soundblaster (CT4750) (5880x)
9876 ?
1275 Network Appliance Corp
1276 Switched Network Technologies Inc
@@ -5799,7 +6047,7 @@
9100 DM9100 Ethernet Controller
9102 10/100 Mbps Fast Ethernet Controller (DM9102/A/AF)
1283 Integrated Technology Express (ITE) Inc
- 0801 IT8152F/G & IT8172G Audio Digital Controller
+ 0801 Audio Digital Controller (Audio Digital Controller)
673A IT8330G PCI EIDE Controller
8152 Advanced RISC-to-PCI Companion Chip (IT8152F/G)
8172 Ultra RISC (MIPS, SH4) Companion Chip (IT8172G)
@@ -6021,6 +6269,7 @@
71E2 3 Port PCI to PCI bridge (PI7C7300)
8150 2-Port PCI to PCI Bridge (PI7C8150)
8152 2-Port PCI-To-PCI Bridge (PI7C8152)
+ A404 PCIe Packet Switch (PI7C9X20404SL)
E130 PCI-X Bridge (PI7C9X130)
12D9 Acculab PLC
12DA True Time
@@ -6067,7 +6316,7 @@
12F1 Sorensen Vision Inc
12F2 Gammagraphix Inc
1002 Grapics Radeon X850 (215RAAGCGA11F)
- 3059 AC97 Enhanced Audio Controller - the 8251 controller is different (VT8237)
+ 3059 AC97 Enhanced Audio Controller - the 8251 controller is different (VT8235)
12F3 Radstone Technology / XING Inc
12F4 Megatel
12F5 Forks Inc
@@ -6119,7 +6368,7 @@
000D PCI-PDISO16
000F PCI-DAS1200
0010 PCI-DAS1602/12
- 0014 PCI-DIO24H
+ 0014 24 Bit Digital Input/Output Board (PCI-DIO24H)
0015 PCI-DIO24H/CTR3
0016 PCI-DIO24H/CTR15
0017 PCI-DIO96H
@@ -6141,7 +6390,7 @@
0027 PCI-DAC04/16-HS
0028 24 Bit Digital Input/Output Board (PCI-DIO24)
0029 PCI-DAS08
- 002C PCI-INT32
+ 002C PCI-INT32 (PCI-INT32)
0033 PCI-DUAL-AC5
0034 PCI-DAS-TC
0035 PCI-DAS64/M1/16
@@ -6196,7 +6445,7 @@
1318 Packet Engines, Inc.
0911 1000BT Network Interface Card (G-NIC II)
1319 ForteMedia Inc
- 0801 PCI Card MediaForte made in singapore (FM0801-a1)
+ 0801 PCI Card MediaForte made in singapore (driver - ftp://ftp.terratec.net/Audio/OEM/Integra/Driver/Inte (FM0801-au)
0802 Xwave PCI Joystick (FM801-as)
1000 FM801 PCI Audio Device
1001 FM801 PCI Joystick
@@ -6232,7 +6481,7 @@
2012 Duet 1S(16850)+1P
2020 Communication controller (SIIG cyber8000)
2021 CyberParallel (2-port)
- 2030 Unknown (Unknown)
+ 2030 SIIG Cyber Serial Dual PCI Board (SIIG CyberSerial PCI 16C550)
2031 CyberSerial (2-port) 16650
2032 CyberSerial (2-port) 16850
2040 Trio 1S(16550)+2P
@@ -6241,7 +6490,7 @@
2050 Siig Inc CyberSerial (4-port) 16550 (Siig Inc CyberSerial (4-port) 16550)
2051 CyberSerial (4-port) 16650
2052 CyberSerial (4-port) 16850
- 2060 Trio 2S(16550)+1P
+ 2060 Trio 2S(16550)+1P (JJ_P21022-B)
2061 Trio 2S(16650)+1P
2062 Trio 2S(16850)+1P
1320 Crypto AG
@@ -6636,6 +6885,7 @@
1003 SATA2 Raid Controller (9550SX/9590SE Series)
1004 PCI-Express SATA2 Raid Controller (9650SE Series)
1005 PCI-Express SATA2/SAS Raid Controller (9690SA Series)
+ 1010 PCI-Express2 SAS2/SATA2 Raid Controller (9750 Series)
13C2 Technotrend Systemtechnik GmbH
000E Technotrend/Hauppauge DVB card rev2.3
13C3 Janz Computer AG
@@ -6672,7 +6922,7 @@
13D5 Media 100 Inc
13D6 K.I. Technology Co Inc
13D7 Toshiba Engineering Corporation
- 8086 toshiba (8086)
+ 8086 toshiba (6205)
13D8 Phobos Corporation
1000 XaQti 1000Mbit/sec Gbit Ethernet Controller (XQ11800FP)
13D9 Apex PC Solutions Inc
@@ -6706,8 +6956,9 @@
0200 Encorest Ethernet PCI Ad ENL832-TX-ICNT Faapter (0x0200)
0201 Fast Ehternet Adapter (ST201)
0300 Network Adapter (NX1001)
+ 1021 Tamarack 9021A Gigabit Ethernet adapter (Tamarack 9021A)
1023 IC Plus IP1000 Family Gigabit Ethernet Adapter
- 13F0 ST201 Fast Ethernet Adapter (-PCIVEN_13F0&DEV_1023&SUBSYS_81801043&REV_414&BC)
+ 13F0 ST201 Fast Ethernet Adapter (-PCIVEN_13F0&DEV_0200&SUBSYS_82121043&REV_313&61)
13F1 Oce' - Technologies B.V.
13F2 Ford Microelectronics Inc
13F3 McData Corp
@@ -6717,9 +6968,10 @@
13F6 C-Media Electronics Inc.
0100 CMI8338/C3DX PCI Audio Device
0101 PCI Audio Device (CMI8338-031)
- 0111 C-Media Audio Controller (CMI873x)
+ 0111 C-Media Audio Controller (CMI8738)
0112 PCI Audio Chip (CMI-8378B/PCI-6CH)
- 0211 HSP56 MICROMODEM (PCIVEN_13F6&DEV_0111&SUBSYS_011113F6&REV_10)
+ 0191 CMI 8768 8CH Sound Card (PCIVEN_13F6&DEV_0191&REV_10)
+ 0211 HSP56 MICROMODEM (PCIVEN_13F6&DEV_0111&SUBSYS_011113F6&REV_10_13F6&)
0300 pci audio driver (0x4005)
8788 C-Media Oxygen HD (CMI8788/PCI-8CH)
13F7 Wildfire Communications
@@ -6730,12 +6982,15 @@
13FC Computer Peripherals International
13FD Micro Science Inc
160E a (a)
+ 161F s (1D59CB92)
+ 1840 USB Harddisk adapter (don't know what you mean... :-()
13FE Advantech Co., Ltd.
1240 4-Axis Stepping/Servo Motor Card (NOVA MCX314)
1600 PCI-16xx series PCI multiport serial board (function 0)
1680 2-port CAN UniversalPCI Communication Card with Isolation (PCI-1680U-A)
16FF PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD)
1713 32-channel Isolated Analog Input Card (PCI-1713)
+ 1723 16-bit, 8-ch Analog Output PCI Card with 16-ch Digital I/O (PCI-1723)
1724 14-bit, 32-channel Isolated Analog Output Card (PCI-1724)
1733 PCI-1733 32-channel isolated digital input card
1750 PCI-1750 Opto Isolated Digital I/O Card w/Counter
@@ -6743,6 +6998,9 @@
1754 PCI-1754
1756 PCI-1756
1760 ?
+ 1761 8-channel relay actuator and 8-channel isolated input card (PCI-1761)
+ 1A00 0x0200 (0x03)
+ 3730 16Bit dig. I/O Board (PCM-3730I)
13FF Silicon Spice Inc
1400 ARTX Inc
0001 ArtX1 AGP System Controller
@@ -6763,7 +7021,7 @@
0101 Lava Quattro PCI A/B
0102 Lava Quattro PCI C/D
0110 Lava DSerial PCI Port A (0110)
- 0111 Lava DSerial PCI Port B
+ 0111 Lava DSerial PCI Port B (nep5p)
0180 Lava Octopus PCI Ports 1-4
0181 Lava Octopus PCI Ports 5-8
0200 LavaPort Dual-650 PCI
@@ -6772,7 +7030,7 @@
0220 LavaPort Quad-650 PCI A/B
0221 LavaPort Quad-650 PCI C/D
0400 Lava 8255 PIO PCI
- 0500 Lava Single Serial 550 PCI
+ 0500 Lava Single Serial 550 PCI (P4)
0510 Lava SP Serial 550 PCI
0511 Lava SP BIDIR Parallel PCI
0520 Lava RS422 SS-PCI
@@ -6782,7 +7040,7 @@
8001 Lava Dual Parallel port A
8002 Lava Dual Parallel port A
8003 Lava Dual Parallel port B
- 8800 BOCA Research IOPPAR
+ 8800 BOCA Research IOPPAR (2003)
1408 Aloka Co Ltd
1409 Timedia Technology Co Ltd
7168 PCI / ISA Asynchronous UART Signal Chips Solution (40371409)
@@ -6801,7 +7059,7 @@
1724 Envy24PT/HT PCI Multi-Channel Audio Controller (VT1720/24)
1413 Addonics
1414 Microsoft Corp
-1415 Oxford Semiconductor Ltd
+1415 Oxford Semiconductor Ltd - now part of PLX Technology
8401 PCI Interface to local bus (OX9162)
8403 OX12PCI840/OX9162 Integrated Parallel Port
9500 Quad UART (disabled) (OX16PCI954)
@@ -6816,6 +7074,12 @@
9513 OX9160/OX16PCI954 Parallel Port
9521 OX16PCI952 Integrated Dual UART
9523 Integrated Parallel Port (OX16PCI952)
+ C158 2 native UARTs (function 0) (OXPCIe952)
+ C15D 2 native UARTs (function 1) (OXPCIe952)
+ C208 Quad UARTs (OXPCIe954)
+ C20D Quad UARTs (function 1) (OXPCIe954)
+ C308 Octo UARTs (OXPCIe958)
+ C30D Octo UARTs (function 1) (OXPCIe958)
1416 Multiwave Innovation Pte Ltd
1417 Convergenet Technologies Inc
1418 Kyushu Electronics Systems Inc
@@ -6990,6 +7254,7 @@
148E OSI Plus Corp
148F Plant Equipment Inc.
2573 802.11 bg (1192Af7b)
+ 2870 802.11 n WLAN (1.0)
1490 Stone Microsystems Pty Ltd
1491 Zeal Corp
1492 TIME LOGIC Corp
@@ -7127,9 +7392,9 @@
2111 PCI IO 1S1P-650
2112 PCI IO 1S1P-850
2120 PCI IO 1P, TK9902, Avlab P005
- 2121 PCI IO 2P
+ 2121 Avlab Technology PCI IO 2P (PCI IO 2P)
2130 2 Port PCI Serial Card (PCI IO 2S)
- 2131 PCI IO 2S-650
+ 2131 pci serial port (PCI IO 2S-650)
2132 PCI IO 2S-850
2140 PCI IO 2P1S
2141 PCI IO 2P1S-650
@@ -7168,6 +7433,7 @@
14E3 Amtelco
14E4 Broadcom Corporation
034F ??? (NV36GL?)
+ 04B5 Broadcom 54bg Wireless (BCM4312)
0800 Sentry5 Chipcommon I/O Controller (BCM33xx/47xx)
0804 Sentry5 PCI Bridge (BCM33xx/47xx)
0805 Sentry5 MIPS32 CPU (BCM33xx/47xx)
@@ -7179,6 +7445,7 @@
14E4 802.11b/g Wireless Lan Controller (BCM5787M)
1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express (BCM5752)
1601 NetXtreme BCM5752M Gigabit Ethernet PCIe
+ 1612 Broadcom Video Decoder/Accelerator (BCM70010/BCM70012)
1639 NetXtreme II Gigabit Ethernet (BCM5709)
163A NetXtreme II BCM5709S Gigabit Ethernet
1644 BCM5700 NetXtreme Gigabit Ethernet Controller
@@ -7206,7 +7473,7 @@
1672 NetXtreme BCM5754M Gigabit Ethernet PCIe
1673 NetXtreme BCM5755M Gigabit Ethernet PCIe
1674 NetXtreme BCM5756ME Gigabit Ethernet PCIe
- 1676 BCM5750A1 NetXtreme Gigabit Ethernet
+ 1676 NetXtreme Gigabit Ethernet (BCM5750A1)
1677 NetXtreme Gigabit Ethernet PCI Express (BCM5750A1)
1678 BCM5715C 10/100/100 PCIe Ethernet Controller
1679 NetXtreme 5715S Gigabit Ethernet
@@ -7216,10 +7483,11 @@
167D Broadcom NetXtreme Gigabit Ethernet (BCM5751M)
167E BCM5751F NetXtreme Fast Ethernet PCIe
167F NetLink BCM5787F Fast Ethernet PCIe
- 1684 Broadcom NetXtreme Gigabit Ethernet
+ 1681 Broadcom 57XX Gigabit Integrated Controller (BCM5761)
+ 1684 Broadcom NetXtreme Gigabit Ethernet (BCM5764)
1693 Ethernet Controller Broadcom Netlink Gigabit (BCM5787A)
- 1696 Broadcom NetXtreme Gigabit Ethernet - http://www.broadcom.com/support/ethernet_nic/netxtreme_desktop (BCM5782)
- 1698 NetLink (BCM5784M)
+ 1696 Broadcom NetXtreme Gigabit Ethernet - http://www.broadcom.com/support/ethernet_nic/downloaddrivers.p (BCM5782)
+ 1698 NetLink (BCM5786gigabit ethernet pcie)
169A NetLink BCM5786 Gigabit Ethernet PCIe
169B NetLink BCM5787 Gigabit Ethernet PCIe
169C Broadcom NetLink (TM) Gigabit Ethernet (BCM5788)
@@ -7248,17 +7516,17 @@
4211 BCM4211 iLine10 HomeHPNA 2.0 10Mb/s NIC
4212 56k Modem (BCM V.90)
4220 802-11b/g Wireless PCI controller
- 4301 Dell Truemobile 1180 802.11b MiniPCI (Broadcom BCM4301 802.11b Wireless LAN Controller)
+ 4301 Dell Truemobile 1180 802.11g MiniPCI (Broadcom BCM4301 802.11g Wireless LAN Controller)
4303 BCM4301 802.11b802.11b Wireless LAN Controller (BCM4303)
4305 V.90 56k Modem (BCM4307)
4306 Unknown device 4306 (rev 02) (BCM4306)
- 4307 802.11b Wireless LAN Controller (BCM4307)
+ 4307 802.11b Wireless LAN Controller (BCM4306)
4310 BCM4301 802.11bChipcommon I/O Controller (BCM4310)
4311 Broadcom Corporation Dell Wireless 1390 WLAN Mini-PCI Card (BCM4311)
4312 BCM4310 UART (Wireless Ethernet Adapter)
- 4313 usb controller, wireless network card (BCM4310)
+ 4313 wireless network card (BCM4310)
4315 Broadcom Wireless b/g (BCM4315/BCM22062000)
- 4318 Broadcom 802.11b/g (BCM43XX)
+ 4318 Broadcom 802.11b/g (BCM4318)
4319 Dell Wireless 1470 DualBand WLAN
431A 802.11a Network Adapter
4320 802.11b/g Wireless LAN Controller (BCM4309)
@@ -7271,9 +7539,10 @@
4328 Broadcom 432AGN 802.11a/b/g/draft-n Wi-Fi Solution (BCM4321KFBG)
4329 BCM43XNG 802.11n Network Adapter
432A 802.11n Network Adapter
+ 432B WIRELESS for Hp pavilion, Wireless for macbook pro (late 2009 model), Wireless for Dell e6500 , Ali
4344 EDGE/GPRS data and 802.11b/g combo cardbus [GC89]
4401 10/100 Integrated Ethernet Controller (BCM4401)
- 4402 10/100 Integrated Ethernet Controller (BCM4402)
+ 4402 10/100 Integrated Ethernet Controller (BCM440)
4403 V.90 56k Modem (BCM4402)
4410 BCM4410 iLine32(tm) Network Adapter
4411 V.90 56k Modem (BCM4212)
@@ -7346,7 +7615,8 @@
14EE Maspro Kenkoh Corp
14EF Carry Computer Engineering Co Ltd
14F0 Canon Reseach Centre France
-14F1 Conexant Systems
+14F1 Conexant Systems, Inc.
+ 0F00 ..........
1002 HCF 56k Modem
1003 HCF 56k Modem
1004 HCF 56k Modem
@@ -7362,7 +7632,7 @@
1033 HCF 56K Winmodem
1034 HCF 56k DFVS Modem
1035 PCI Modem Enumerator
- 1036 PCI Modem Enumerator
+ 1036 unknown (Conexant RH56D/SP-PCI)
1052 HCF 56k Data/Fax Modem (Worldwide)
1053 HCF 56k Data/Fax Modem (Worldwide)
1054 HCF 56k Data/Fax/Voice Modem (Worldwide)
@@ -7377,7 +7647,7 @@
1066 HCF 56k Data/Fax/Voice/Spkp Modem
1085 CX11250 SmartHSF Mobile Modem host side device
10B3 HCF Data/Fax
- 10B4 HCF Data/Fax/Remote TAM
+ 10B4 All Conextant HFC Modems (PCI) (Conextant HFC)
10B5 HCF Data/Fax/Voice/Spkp
10B6 Conexant HCF PCI Soft modem (unknown)
1433 HCF 56k Data/Fax Modem
@@ -7388,8 +7658,10 @@
1454 HCF 56k Data/Fax/Voice Modem
1455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
1456 HCF 56k Data/Fax/Voice/Spkp Modem
+ 14F1 Conextant High Definition Audio_Venice5051 (14F12F30)
1610 ADSL AccessRunner PCI Arbitration Device
1611 AccessRunner PCI ADSL Interface Device
+ 1612 8
1620 ADSL AccessRunner V2 PCI Arbitration Device
1621 AccessRunner V2 PCI ADSL Interface Device
1622 AccessRunner V2 PCI ADSL Yukon WAN Adapter
@@ -7445,9 +7717,9 @@
2464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
2465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
- 2702 HSFp or Soft V92 Data Fax Modem (cx11252-15)
+ 2702 HSFp or Soft V92 Data Fax Modem (cx11252-11)
2BFA HDA D100 MDC v.92 Modem (Unknown)
- 2C06 HDAUDIO Soft Data fax Modem with SmartPC (1003)
+ 2C06 CXT - Network - HDAUDIO Soft Data Fax Modem with SmartCP
2F00 HSF 56k HSFi Churchill Data/Fax Modem
2F01 missing driver for pci simple communications controller (0x0780)
2F02 HSF 56k HSFi Churchill Data/Fax Modem
@@ -7459,13 +7731,14 @@
2F13 HSF Data/Fax (USA)
2F14 US Robotics 56K PCI Software Modem
2F15 US Robotics 56K Fax Host Int
- 2F20 CX11256 Software data fax modem with SmartCP
- 2F30 Zyxel OMNI 56K PCI Plus Rev.3 (01)
+ 2F20 SoftV92 Data Fax Modem with SmartCP (CX11256)
+ 2F30 PCI SoftV92 Modem (CX11252-41z)
2F40 Conexant Modem RD02-D490 (71030277)
+ 2F50 unknown (205F14F1)
2F82 Conexant PCI-E Soft Data/Fax Modem with SmartCP (cx9510-11z)
- 5045 HDAUDIO Soft Data fax Modem with SmartPC / Conexant High Definition SmartAudio HD2 (4.0.3.1)
+ 5045 HDAUDIO Soft Data Fax Modem with SmartCP / Conexant High Definition Audio (SmartAudio HD2) (4.0.3.1)
5051 Audio (4.0.1.6)
- 5B7A Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder (Belived to be a CX23418)
+ 5B7A Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder (Belived to be a CX23416)
8234 RS8234 ATM SAR Controller [ServiceSAR Plus]
8237 CN8237 ATM OC2 ServiceSAR+ Controller with BR Traffic Management
8471 CN8471A 32 Channel HDLC Controller
@@ -7481,7 +7754,8 @@
8803 CX2388x TV Capture Chip
8804 CX2388x TV Capture Chip
8811 CX2388x TV Capture Chip
- 8852 CX23881-21 (0x7717)
+ 8852 CX23881-21 (cx23885)
+ 8880 PCI Express Video and Broadcast Audio Decoder (CX23888)
14F2 Mobility Electronics, Inc.
0001 Moselle Split Bridge
0002 Capilano Split Bridge
@@ -7555,7 +7829,7 @@
1519 Telefon Aktiebolaget LM Ericsson
2004 PCI Interface bus (0x1)
151A Globetek Inc.
- 1002 4370 (PCI-1002)
+ 1002 4370 (PCI-1002 5A62)
1004 PCI-1004
1008 PCI-1008
151B Combox Ltd
@@ -7565,6 +7839,7 @@
0003 Prodif T 2496
4000 Prodif 88
151D Fujitsu Computer Products Of America
+ 9876 ?
151E Matrix Corp
151F Topic Semiconductor Corp
0000 TP560 D/F/V 56k Modem
@@ -7593,6 +7868,7 @@
1420 CardBus Controller (CB-1420)
1421 CB-720/722/724 CardBus Controller
1422 CB-722/724 CardBus Controller
+ FC10 pci device (card bus)
1525 Impact Technologies
1526 ISS Inc
1527 Solectron
@@ -7642,7 +7918,8 @@
1548 Jet Propulsion Laboratory
1549 Interconnect Systems Solutions
80FF PCI/ISA Bus Bridge (PCI-ISA-001)
-154A Max Technologies Inc
+154A Max Technologies Inc.
+ 9016 USB DVB-T Device AF9015 (AF9015)
154B Computex Co Ltd
154C Visual Technology Inc
154D Pan International Industrial Corp
@@ -7810,7 +8087,7 @@
6274 MT25204 InfiniHost III Lx HCA
6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
6279 MT25208 InfiniHost III Ex HCA Flash Recovery
- 6282 MT25208 InfiniHost III Ex
+ 6282 MT25218 [InfiniHost III Ex] (MT25218)
6340 MT25408 [ConnectX IB SDR]
634A MT25418 [ConnectX IB DDR, PCIe 2.0 2.5GT/s]
6354 MT25428 [ConnectX IB QDR]
@@ -7881,11 +8158,13 @@
15DD Sigmatel Inc.
7664 idt high audio (vgn-ar71mr)
7680 SIGMATEL STAC 92XX C-Major HD Audio
- 7690 9200 HD Audio CODEC (9200)
+ 7690 9200 HD Audio CODEC (10F70000)
8384 IDT High Definition Audio CODEC (*2UF1a)
+ 9876 1
15DE Malleable Technologies Inc
15DF Infinilink Corp
15E0 Cacheflow Inc
+ 7134 01 (01385168)
15E1 Voice Technologies Group Inc
15E2 Quicknet Technologies Inc
0500 Internet PhoneJack PCI Card
@@ -8017,7 +8296,7 @@
163B Glotrex Co Ltd
163C Smart Link
3052 RS56/HSP-PCI (R6793-11)
- FF02 SMART LINK 56K VOICE V.92 MODEM (SL2800 PCI)
+ FF02 Intel Chipset (82945G)
163D Heidelberg Digital LLC
163E 3dpower
163F Renishaw PLC
@@ -8100,6 +8379,8 @@
4C32 L2B PCI Board
5344 FOB-SD Card
5443 FOB-TDC Card
+ F0B2 ibaFOB-2io-D (ibaFOB-2io-D)
+ F0B4 ibaFOB-4io-D (ibaFOB-4io-D)
1680 Dunti Corp
1681 Hercules
0050 Hercules WiFi PCI 802.11G (HWGPCI-54)
@@ -8109,24 +8390,27 @@
168A Utimaco Safeware AG
168B Circut Assembly Corp (Ca)
168C Atheros Communications Inc.
- 0007 802.11a Wireless Adapter (AR5005)
+ 0007 802.11a Wireless Adapter (AR5007)
0011 802.11a Wireless Adapter (AR5bmb5)
0012 802.11a/b/g Mini-PCI Wireless Adapter (AR5211)
- 0013 802.11a/b/g Wireless Adapter (AR5212)
+ 0013 802.11a/b/g Wireless Adapter (AR2312)
0014 Wireless Network Adapter
0015 Wireless Network Adapter
0016 Wireless Network Adapter
0017 Wireless Network Adapter
0018 Wireless Network Adapter
0019 Wireless Network Adapter
- 001A Atheros AR5005G 802.11abg NIC Chipset / TP-Link (TL-WN551G) (Atheros AR5005G)
+ 001A http://cr.am/framed.php?url=http%3A%2F%2Fwww.tp%2Dlink.com%2Fsupport%2Fdownload.asp&ref=driverguide (Atheros AR5005G)
001B AR5006 family 802.11abg Wireless NIC
- 001C HDAUDIOFUNC_01&VEN_1095&DEV_1392&SUBSYS_10280242&REV_1000 (USBVID_147E&PID_20165&B71A446&0&1)
+ 001C AR5006 family 802.11abg Wireless NIC
+ 001D PCIVEN_168C&DEV_001D&SUBSYS_2055168C&REV_013&267A616A&0&50 (TP-Link TL-WN350GD)
0020 AR5005VL 802.11bg Wireless NIC
0023 802.11a/b/g/n Wireless PCI Adapter (AR5416)
0024 Atheros 802.11a/b/g/n (pre-N) radio (AR5008)
002A Atheros AR5B91 Wireless Network Adapter (0001)
- 1014 Atheros AR5212 802.11abg wireless (AR5212)
+ 002B Atheros AR9285 Wireless LAN 802.11 a/b/g/n Controller (AR928x)
+ 1014 Atheros AR5212 802.11abg wireless Drivers (AR5212)
+ 14F1 PCIVEN_14f1&DEV_10b6&SUBSYS_10b614f&REV_89 (nForce6100-430 )
FF19 AR5006X Wireless Network Adapter
FF1C AR5008 Wireless Network Adapter
FF1D AR5008 Wireless Network Adapter
@@ -8269,6 +8553,7 @@
170E SanValley Systems Inc
170F Cyberdyne Inc
1710 Pelago Networks
+ 9835 2 serial, 1 LPT port PCI Card
1711 Netscreen Technologies Inc
1712 Nice Systems
1713 Topcon Corp
@@ -8341,6 +8626,7 @@
7C12 RADEON 9200 ATLANTIS - Secondary (RV280)
7C13 RADEON 9200 ATLANTIS (RV280)
9501 ATI Radeon HD 3870 (RV670 )
+ E131 ATI 4870 (RV770)
174C Intelitek
174D WellX Telecom
174E Xi'an Tongshi Data Co Ltd
@@ -8535,12 +8821,19 @@
17F0 Velio Communications Inc
17F1 Interactive Silicon Inc
17F2 Albatron Corp
-17F3 RDC Semiconductor Co Ltd
+17F3 RDC Semiconductor Co., Ltd.
+ 1010 IDE Controller (D1010)
+ 1011 Standard IDE Controller (D1011)
+ 1030 PCI to PCI-E Bridge (M1030)
+ 2010 GPU (VGA ) (M2010)
+ 3010 HD Audio (M3010)
6020 R6020 North Bridge
+ 6021 Host Bridge
6030 R6030 ISA Bridge
+ 6036 PCI to ISA Bridge
6040 R6040 MAC Controller
6060 R6060 USB 1.1 Controller
- 6061 R6061 USB 2.0 Controller
+ 6061 USB 2.0 Controller (EHCI)
17F4 MicroPlex Printware AG
17F5 Cymer Inc
17F6 Leopard Logic Inc
@@ -8577,15 +8870,18 @@
3059 AC97 Enhanced Audio Controller - the 8251 controller is different (VT8237)
4000 intel V.92 HaM Modem (MD5628D-L-A)
4100 Intel HaM V.92 Modem (Ambient MD8820)
-1814 Ralink Technology, Corp
+1814 Ralink Technology, Corp.
+ 0001 ...I don't know (...B742000)
0101 RT2460 802.11b Baseband/MAC integrated chip (2460 802.11b)
0200 RT2500 802.11g PCI
- 0201 Ralink Chipset 802.11b/g WLAN Card ( PCIVEN_1814&DEV_0201&SUBSYS_68331460&REV_013&)
+ 0201 Ralink Chipset 802.11b/g WLAN Card ( RT2560F)
0300 Wireless Adapter Canyon CN-WF511
0301 Edimax 54 MBit WLan 802.11g rt 2500 (b8341462)
0302 wireless a/b (RT2525 2.4GHz transceiver + RT2560 MAC/BBP)
- 0401 RT2600 802.11 MIMO
+ 0401 Ralink MIMO RT 2661 Wireless 54 Mbps (RT 2661)
+ 0601 b/g/n Wlan (RT2860T)
0781 Wireless (RT2860/RT2890)
+ 9876 Edimax 54 MBit WLan 802.11g rt 2500 (b8341462)
E932 RT2560F 802.11 b/g PCI
1815 Devolo AG
1816 Pro Team Computer Corporation
@@ -8734,7 +9030,7 @@
2021 Framegrabber (Colory)
3011 Video Output Board (Valentino)
18CA XGI Technology Inc
- 0020 Volari Z7
+ 0020 XGI Compatible Super VGA (Volari Z9s) controller (Volari Z9s)
0040 Volari Family (8085)
0047 Volari 8300 (chip: XP10, codename: XG47)
18D0 Kobian Pte Ltd
@@ -8824,6 +9120,8 @@
1969 Attansic (Now owned by Atheros)
1026 PCI-E ETHERNET CONTROLLER (AR8121/AR8113 )
1048 Gigabit Ethernet 10/100/1000 Base-T Controller (Atheros L1)
+ 1062 Atheros AR8132 PCI-E Fast Ethernet Controller (AR8132)
+ 1063 Atheros AR8131 PCI-E Gigabit Ethernet Controller (AR8131)
2048 Fast Ethernet 10/100 Base-T Controller (Atheros L2)
196A Sensory Networks Inc
0101 NodalCore C-1000 Content Classification Accelerator
@@ -8836,13 +9134,18 @@
1021 AGEIA PhysX 200 Series PCI Express Card
1975 DVG64 family
197B JMicron Technology Corp.
+ 0250 JMC250 PCI Express Gigabit Ethernet (JMC2XX)
+ 0256 JMC260 PCI Express Fast Ethernet (JMC2XX)
+ 0260 JMC260 PCI Express Fast Ethernet (JMC2XX)
+ 197B JMB38X SD/MMC Host Controller (JMB38X)
2360 JMicron 20360/20363 AHCI Controller
- 2361 JMB361 AHCI/IDE
- 2363 JMB36X PCIe-to-SATA-300/IDE RAID Controller
+ 2361 PCI Express to SATA II and PATA Host Controller (JMB363)
+ 2363 JMicron JMB362/JMB363 AHCI Controller (JMB36X)
2365 JMB365 AHCI/IDE
- 2366 JMB366 AHCI/IDE
- 2368 JMB368 IDE Controller
- 2382 JMB38X SD/MMC Host Controller (JMB38X)
+ 2366 JMicron JMB366 AHCI/IDE Controller (JMB36X)
+ 2368 IDE Comtroller (JMB368)
+ 2380 IEEE 1394 Host Controller (JMB38X)
+ 2382 JMB38X SD/MMC Host Controller (JMB38X)
2383 JMB38X MS Host Controller (JMB38X)
2384 JMB38X xD Host Controller (JMB38X)
1982 Distant Early Warning Communications Inc
@@ -8851,6 +9154,19 @@
1989 Montilio Inc
0001 RapidFile Bridge
8001 RapidFile Bridge
+198A Nallatech
+ 0210 XMC-210
+ 0220 XMC-220
+ 0230 XMC-230
+ 0240 XMC-240
+ 1180 PCIe-180 ( pm 965)
+ 1280 PCIe-280
+ 402F BenNUEY PCIX
+ 4030 H100-PCIX
+ 4031 BenNUEY PCI-104-V4
+ 4032 BenONE-PCIe
+ 4033 BenONE-Xilinx-Kit-ROHS
+ 4034 BenNUEY PCIX RoHS
1993 Innominate Security Technologies AG
199A Pulse-LINK Inc
19A2 ServerEngines LLC
@@ -8866,6 +9182,8 @@
19D4 Quixant Limited
19DE Pico Computing
19E2 Vector Informatik GmbH
+19E3 DDRdrive LLC
+ DD52 DDRdrive X1
19E7 NET (Network Equipment Technologies)
1001 STIX DSP Card
1002 STIX - 1 Port T1/E1 Card
@@ -8980,7 +9298,7 @@
0007 Permedia II 2D+3D Accelerator (3D Extreme)
0008 GLINT Gamma G1
0009 2d+3d chipset, integrated ramdac (Permedia2v)
- 000A Permedia 3
+ 000A Driver Ethernet Pci Ven 1969 (Permedia 3)
000C Permedia 3
000D 3D Accelerator (GLINT R4)
000E GLINT Gamma G2
@@ -9001,7 +9319,7 @@
4005 Avance Logic Inc.
0300 ALS300 PCI Audio Device
0308 PCI Audio Device + modem (3220)
- 0309 PCI Input Controller (ALS300+)
+ 0309 PCI Input Controller (ALS300 )
1064 GUI Accelerator (ALG2064)
2064 ALG-2032/64i GUI Accelerator
2128 GUI Accelerator (ALG2364A)
@@ -9306,7 +9624,7 @@
0372 Segment-B PCI Express-to-PCI Express Bridge (80333)
0373 B-Bus IOAPIC (80333)
0374 Address Translation Unit (80333)
- 0482 PCI-EISA Bridge (PCEB) (82375MB)
+ 0482 PCI-EISA Bridge (PCEB)hp dx 7300 microwave tower (82375MB)
0483 82424TX/ZX (Saturn) Cache/DRAM Controller
0484 82378ZB/IB,82379AB PCI to ISA Bridge, System I/O
0486 82420EX/ZX 486 PCIset System, ISA Bridge & EIDE Controller
@@ -9317,7 +9635,7 @@
0502 Scalability Port 0 (E8870)
0503 E8870 Scalability Port 1 / Global Performance Monitoring
0510 E8870IO Hub Interface Port 0 (8-bit Compatibility)
- 0511 Hub Interface Port 1 (E8870IO)
+ 0511 Hub Interface Port 2 (E8870IO)
0512 Hub Interface Port 2 (E8870IO)
0513 Hub Interface Port 3 (E8870IO)
0514 Hub Interface Port 4 (E8870IO)
@@ -9334,6 +9652,7 @@
0600 Storage RAID Controller (01af8086)
0601 RAID Controller
061F 80303 I/O Processor
+ 0800 pci/ven_8086&dev_27da&subsys_30b2103c&rev_023&b1bfb68&0&fb (10B01734)
0960 i960 RP Microprocessor/Bridge (80960RP)
0962 i960RM/RN Microprocessor/Bridge (80960RM/RN)
0964 i960 RP Microprocessor Bridge (80960RP)
@@ -9380,7 +9699,7 @@
103C 82801DB/DBL (ICH4/ICH4-L) PRO/100 VM Network Connection
103D 82801DB (ICH4) PRO/100 VE Network Connection
103E 82801DB (ICH4) PRO/100 VM Network Connection
- 1040 V.92 PCI (DSP) Data Fax Modem (536EP)
+ 1040 V.92 PCI (DSP) Data Fax Modema (536EP)
1042 PRO/Wireless 2011 LAN PCI Card
1043 Intel(R) PRO/Wireless 2100 LAN Card Driver (82801)
1048 10 Gigabit Ethernet Controller (82597EX)
@@ -9472,12 +9791,14 @@
10C5 82562G 10/100 Network Connection
10C6 82598EB 10 Gigabit AF Dual Port Network Connection
10C7 82598EB 10 Gigabit AF Network Connection
+ 10CE Intel 82567V-2 Gigabit Network Connection (82567V-2)
+ 10D3 Intel 82574L Gigabit Ethernet Controller (82574L)
10D5 82571PT Gigabit PT Quad Port Server ExpressModule
10D6 82575GB Gigabit Network Connection
10D9 82571EB Dual Port Gigabit Mezzanine Adapter
10DA 82571EB Quad Port Gigabit Mezzanine Adapter
10DD 82598EB 10 Gigabit AT CX4 Network Connection
- 10DE Intel Gigabit network connection (83567LM-3 )
+ 10DE Intel Gigabit network connection (82567LM-3 )
10E2 82575GB Gigabit Network Connection
10E8 Unknown (Unknown)
10F5 Intel 82567LM-2 Gigabit Network Connection (82567LM)
@@ -9502,7 +9823,7 @@
1223 Video Controller (SAA 7116 H)
1225 82452KX/GX Orion Extended Express Processor to PCI Bridge
1226 82596 EtherExpress PRO/10
- 1227 LAN Controller with 82562EM/EX PHYPCI (82801db ich8)
+ 1227 LAN Controller with 82562EM/EX PHYPCI (82801db ich4)
1228 Intelligent 10/100 Fast Ethernet Adapter (EE PRO/100 Smart)
1229 82550/1/7/8/9 EtherExpress PRO/100(B) Ethernet Adapter
122D 82437FX 430FX (Triton) Cache/DRAM Controller
@@ -9597,7 +9918,7 @@
24C2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller *1
24C3 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
24C4 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller *2
- 24C5 Realtek AC97 Audio (82801DBM SoundMAXController (ICH4-M B0 step))
+ 24C5 Realtek AC97 Audio (82801DBM SoundMAXController (ICH4-M B0 step))
24C6 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
24C7 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller *3
24CA 82801DBM (ICH4-M) UltraATA/100 EIDE Controller
@@ -9609,7 +9930,7 @@
24D2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller *1
24D3 82801EB/ER (ICH5/ICH5R) SMBus Controller
24D4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller *2
- 24D5 multimedia audio device (codec AC97) SoundMAX or VIA (8086)
+ 24D5 ADI SoundMAX Audio Device Driver, Version 5.12.1.3622 for the Microsoft Windows XP Operating Sys (8086)
24D6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
24D7 82801EB/ER (ICH5/ICH5R) USB UHCI Controller *3
24DB 82801EB/ER (ICH5/ICH5R) EIDE Controller
@@ -9673,7 +9994,7 @@
258A E7221 Integrated Graphics Controller
2590 Mobile Intel(R) 915GM/PM/GMS/910GML Express Processor to DRAM Controller (915GM)
2591 82915PM/GM PCIe Graphics Port
- 2592 you can be found in www.intelcom (Intel 82852/82855 Graphic controller family)
+ 2592 82915GM/GMS, 82910GML Integrated Graphics Device
25A1 6300ESB LPC Inteface Controller
25A2 IDE Controller (6300ESB)
25A3 6300ESB Serial ATA Controller
@@ -9760,8 +10081,8 @@
2669 jkn (2028026)
266A 82801FB (ICH6) SMBus Controller
266C LAN Controller (82801FB/FR/FW/FRW)
- 266D Intel 82801GB ICH7 - High Definition Audio Controller [A-1] (82801I)
- 266E AC '97 Audio Controller/ Sigmatel (SoundMAX Integrated Digital Audio) (Intel Corporation 82830M/MG SDRAM Controller / Ho)
+ 266D hp/Compal - http://service.marasst.com/Compal/DL75/HDL75%20driver%20Ver%2002/Modem.zip (czc82809kr)
+ 266E VIA AC97 codec incorporated into VT82C686A/B, VT8231, VT8233/A/C, VT8235, VT8237/R, VT8251 Southbrid (VIA Technologies Vinyl AC'97 Codec Combo Driver (W)
266F PATA100 Controller - 266F (82801FB/FBM/FW/FR/FRW)
2670 LPC Interface Controller (631xESB/6321ESB/3100 )
2680 631xESB/632xESB/3100 Serial ATA Storage Controller
@@ -9825,8 +10146,8 @@
27D2 82801G (ICH7 Family) PCIe Root Port
27D4 82801G (ICH7 Family) PCIe Root Port
27D6 82801G (ICH7 Family) PCIe Root Port
- 27D8 82801G (ICH7 Family) High Definition Audio
- 27DA 82801G (ICH7 Family) SMBus Controller
+ 27D8 IDT High Definition Audio Driver (BA101897)
+ 27DA Intel[R] 82801G (ICH7 Family) C- 27DA (82801G)
27DC Intel PRO/100 VE Desktop Adapter (GF)
27DD 82801GB I/O Controller Hub AC'97 Modem
27DE 82801GB I/O Controller Hub AC'97 Audio
@@ -9843,7 +10164,7 @@
2821 82801 (ICH8R) SATA AHCI Controller
2822 Raid Controller (82801HR/HH/HO&82801IR/IH/IO(AIE=0)/ICH10R)
2824 82801HR/HO/HH (ICH8R/DO/DH) SATA AHCI Controller
- 2825 SATA IDE Controller:2 port (82801HB/HR/HH/HO)
+ 2825 82801H (ICH8 Family) 2 port SATA Controller
2828 82801 (ICH8M) 3 port SATA Controller
2829 Mobile SATA AHCI Controller
282A Raid Controller (ICH8ME/9ME)
@@ -9854,7 +10175,7 @@
2835 82801H (ICH8 Family) USB UHCI *5
2836 82801H (ICH8 Family) USB2 EHCI *1
283A ICH8 Enhanced USB2 Enhanced Host Controller (81EC1043 (?))
- 283E 82801H (ICH8 Family) SMBus Controller
+ 283E SM Bus Controller (PCIVEN_8086&DEV_283E&SUBSYS_FF641179&REV_033&B1B)
283F 82801H (ICH8 Family) PCIe Port 1
2841 82801H (ICH8 Family) PCIe Port 2
2843 82801H (ICH8 Family) PCIe Port 3
@@ -9890,7 +10211,7 @@
292C 82801IB/IR/IH (ICH9 Family) Mobile SATA RAID Controller
292D 82801IB/IR/IH (ICH9 Family) Mobile 2 port Serial ATA Storage Controller 2
292E 82801IB/IR/IH (ICH9 Family) Mobile 1 port Serial ATA Storage Controller 2
- 2930 82801IB/IR/IH (ICH9 Family) SMBus Controller
+ 2930 Intel(R) ICH9 Family SMBus Controller working fine with http://download.cnet.com/Chipset-Driver-Inte (8086)
2932 82801IB/IR/IH (ICH9 Family) Thermal Subsystem
2934 82801IB/IR/IH (ICH9 Family) USB Universal Host Controller
2935 82801IB/IR/IH (ICH9 Family) USB Universal Host Controller
@@ -9932,9 +10253,9 @@
2987 Active Management Technology - SOL
2990 Q963/Q965 Memory Controller Hub
2991 Q963/Q965 PCIe Root Port
- 2992 Q963/Q965 Integrated Graphics Controller
+ 2992 Intel(R) Express Chipset video (Q965/Q963)
2993 Q963/Q965 Integrated Graphics Controller
- 2994 PCIVEN_8086&DEV_283T&SUBSYS_30D9103C&REV_0338B1FB68&0&FB (0x8086)
+ 2994 intel management engine interface (0x8086)
2995 Q963/Q965 HECI Controller
2996 Q963/Q965 PT IDER Controller
2997 Intel PCI Serial Port (Q965/Q963)
@@ -9942,7 +10263,7 @@
29A1 Intel P965/G965 PCI Express Root Port (?(82Q965, 82G965, 82P965))
29A2 G965 Integrated Graphics Controller
29A3 G965 Integrated Graphics Controller
- 29A4 The Intel Management Engine provides thermal management for Intel Desktop Boards. (Intel DP965LT)
+ 29A4 The Intel Management Engine provides thermal management for Intel Desktop Boards. (Intel DG965SS)
29A5 P965/G965 HECI Controller
29A6 P965/G965 PT IDER Controller
29A7 P965/G965 KT Controller
@@ -9958,7 +10279,7 @@
29C1 P35/G33 (Bearlake) PCIe Root Port
29C2 P35/G33 (Bearlake) Integrated Graphics Controller
29C3 P35/G33 (Bearlake) Integrated Graphics Controller
- 29C4 P35/G33 (Bearlake) HECI Controller
+ 29C4 Intel ME: Management Engine Interface (Intel DG33fb)
29C5 P35/G33 (Bearlake) HECI Controller
29C6 P35/G33 (Bearlake) PT IDER Controller
29C7 P35/G33 (Bearlake) Serial KT Controller
@@ -10041,6 +10362,10 @@
2E05 HECI Controller
2E06 PT IDER Controller
2E07 Serial KT Controller
+ 2E14 Intel Active Client Manager HECI Device (PCIVEN_8086&DEV_2E14&SUBSYS_3035103C&REV_03B1B68)
+ 2E17 Intel PCI Serial Port (CC_0700)
+ 2E24 Intel Management Engine Interface (PCIVEN_8086&DEV_2E24&SUBSYS_028A1028&REV_03)
+ 2E32 Intel G41 express graphics (PCIVEN_8086&DEV_2E32&SUBSYS_31031565&REV_033&115)
2F00 multimedia audio device (codec AC97) SoundMAX or VIA (815B104D)
3092 I2O 1.5 RAID Controller (SRCU32)
3200 31244 PCI-X to Serial ATA Controller
@@ -10179,7 +10504,7 @@
3A39 USB UHCI Controller *6
3A3A USB EHCI Controller *1
3A3C USB EHCI Controller *2
- 3A3E HD Audio Controller
+ 3A3E Microsoft UAA Bus Driver for High Definition Audio (Microsoft UAA Bus Driver for High Definition Audio)
3A40 PCI Express Port 1
3A42 PCI Express Port 2
3A44 PCI Express Port 3
@@ -10209,7 +10534,7 @@
3A7C Gigabit Ethernet Controller
3B20 IBEX SATA Controller
3B21 IBEX SATA Controller
- 3B22 IBEX AHCI Controller(6Port)
+ 3B22 IBEX AHCI Controller(6Port) (Intel Q57 Express)
3B23 IBEX AHCI Controller(4Port)
3B26 IBEX SATA Controller
3B28 IBEX SATA Controller
@@ -10251,9 +10576,12 @@
4233 Intel Wireless WiFi Link 4965AGN (Intel 4965AGN)
4235 Intel WiFi Link 5300 AGN (5300AGN)
4237 Intel (R) WiFi Link 5100 AGN (5100 AGN)
+ 4318 Dell Wireless 1370 WLAN Mini-PCI Card (1370 (0280))
444D Flash Cache Logic Chip
444E Intel TurboMemory (TurboMemory)
- 5001 Modem - PPP (PRO/DSL 2100)
+ 4813 Dell Wireless 1370 WLAN Mini-PCI Card (1370 (0280))
+ 4888 intel 3945abg wireless lan controller
+ 5001 Modem - PPP (Device0000004c)
5002 LE80578 Graphics Processor Unit
5005 Modem - PPPoA (PRO/DSL 2200)
5009 LE80578 Video Display Controller
@@ -10335,7 +10663,7 @@
7111 PIIX4/4E/4M IDE Controller (82371AB/EB/MB)
7112 PIIX4/4E/4M USB Interface (82371AB/EB/MB)
7113 PIIX4/4E/4M Power Management Controller (82371AB/EB/MB)
- 7120 Host-Hub Interface Bridge / DRAM Ctrlr (82810)
+ 7120 Host-Hub Interface Bridge / DRAM Ctrlr (Intel(R) 82801IMB)
7121 82810 810 Chipset Graphics Controller
7122 Host-Hub Interface Bridge / DRAM Ctrlr (82810-DC100)
7123 Intel 82810 Graphics Controller (82810-DC100)
@@ -10370,7 +10698,8 @@
7800 Intel740 AGP Graphics Accelerator
8002 Trusted Execution Technology
8003 Trusted Execution Technology Registers
- 8086 lsdurjlk (park55)
+ 803B 0x81ef (0x104d)
+ 8086 PRO/100 VE Network Connection (24D0)
811A Atom SCH PATA (Atom SCH)
84C4 82454KX/GX 450KX/GX Orion System Controller
84C5 450KX/GX Memory Controller (Orion) (82453KX/GX)
@@ -10404,6 +10733,9 @@
96A1 SRCU31L I2O 1.5 RAID Controller (F/W<6.0)
9874 AUDIO CONTROLLER (AC97)
9876 intel brokdale (i845)
+ 9877 1
+ 9888 HDAUDIOFUNC_01&VEN_8086&DEV_2802&REV_1000 (HDAUDIOFUNC_01&VEN_8086&DEV_2802&SUBSYS_80860101&)
+ 9999 Interface chip (pci30b2103c)
A01F PRO/10GbE LR Server Adapter retail verson
A11F PRO/10GbE LR Server Adapter OEM version
A620 6400/6402 Advanced Memory Buffer (AMB)
@@ -10573,7 +10905,7 @@
8090 HostRAID SCSI Controller (ASC-39320)
8091 HostRAID SCSI Controller (ASC-39320D)
8092 HostRAID SCSI Controller (ASC-29320)
- 8093 HostRAID SCSI Controller (ASC-29320B)
+ 8093 HostRAID SCSI Controller (ASC-29320LPE)
8094 HostRAID SCSI Controller (ASC-29320LP)
8095 HostRAID SCSI Controller (ASC-39320)
8096 HostRAID SCSI Controller (ASC-39320A)
diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk
index 35661b3..86f9aed 100644
--- a/share/mk/bsd.cpu.mk
+++ b/share/mk/bsd.cpu.mk
@@ -9,7 +9,7 @@ _CPUCFLAGS =
. if ${MACHINE_ARCH} == "i386"
MACHINE_CPU = i486
. elif ${MACHINE_ARCH} == "amd64"
-MACHINE_CPU = amd64 sse2 sse
+MACHINE_CPU = amd64 sse2 sse mmx
. elif ${MACHINE_ARCH} == "ia64"
MACHINE_CPU = itanium
. elif ${MACHINE_ARCH} == "powerpc"
diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk
index 470d9d4..67a09d7 100644
--- a/share/mk/bsd.lib.mk
+++ b/share/mk/bsd.lib.mk
@@ -33,6 +33,11 @@ CFLAGS+= -DNDEBUG
NO_WERROR=
.endif
+# Enable CTF conversion on request.
+.if defined(WITH_CTF)
+.undef NO_CTF
+.endif
+
.if defined(DEBUG_FLAGS)
CFLAGS+= ${DEBUG_FLAGS}
@@ -68,15 +73,11 @@ PO_FLAG=-pg
.c.po:
${CC} ${PO_FLAG} ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.c.So:
${CC} ${PICFLAG} -DPIC ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.cc.po .C.po .cpp.po .cxx.po:
${CXX} ${PO_FLAG} ${PO_CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@@ -86,58 +87,40 @@ PO_FLAG=-pg
.f.po:
${FC} -pg ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.f.So:
${FC} ${PICFLAG} -DPIC ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.m.po:
${OBJC} ${OBJCFLAGS} -pg -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.m.So:
${OBJC} ${PICFLAG} -DPIC ${OBJCFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.s.po .s.So:
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.asm.po:
${CC} -x assembler-with-cpp -DPROF ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.asm.So:
${CC} -x assembler-with-cpp ${PICFLAG} -DPIC ${CFLAGS} \
-c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.S.po:
${CC} -DPROF ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.S.So:
${CC} ${PICFLAG} -DPIC ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
all: objwarn
@@ -208,9 +191,7 @@ ${SHLIB_NAME}: ${SOBJS}
-o ${.TARGET} -Wl,-soname,${SONAME} \
`NM='${NM}' lorder ${SOBJS} | tsort -q` ${LDADD}
.endif
-.if defined(CTFMERGE)
- ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SOBJS}
-.endif
+ @[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SOBJS}
.endif
.if defined(INSTALL_PIC_ARCHIVE) && defined(LIB) && !empty(LIB) && ${MK_TOOLCHAIN} != "no"
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index c80fe23..70f9c06 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -128,6 +128,7 @@ MINUSLPAM+= -lypclnt
LIBPANEL?= ${DESTDIR}${LIBDIR}/libpanel.a
LIBPCAP?= ${DESTDIR}${LIBDIR}/libpcap.a
+LIBPKG?= ${DESTDIR}${LIBDIR}/libpkg.a
LIBPMC?= ${DESTDIR}${LIBDIR}/libpmc.a
LIBPROC?= ${DESTDIR}${LIBDIR}/libproc.a
LIBPTHREAD?= ${DESTDIR}${LIBDIR}/libpthread.a
diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk
index 84ae433..777ff36 100644
--- a/share/mk/bsd.own.mk
+++ b/share/mk/bsd.own.mk
@@ -407,7 +407,6 @@ MK_${var}:= yes
BIND_LIBS \
BIND_SIGCHASE \
BIND_XML \
- GNU_CPIO \
HESIOD \
IDEA
.if defined(WITH_${var}) && defined(WITHOUT_${var})
diff --git a/share/mk/bsd.port.mk b/share/mk/bsd.port.mk
index 99374a5..87e4935 100644
--- a/share/mk/bsd.port.mk
+++ b/share/mk/bsd.port.mk
@@ -7,5 +7,10 @@ BSDPORTMK?= ${PORTSDIR}/Mk/bsd.port.mk
# and setting MK_* variables when building ports.
_WITHOUT_SRCCONF=
+# Enable CTF conversion on request.
+.if defined(WITH_CTF)
+.undef NO_CTF
+.endif
+
.include <bsd.own.mk>
.include "${BSDPORTMK}"
diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk
index 4de78cb..810a83b 100644
--- a/share/mk/bsd.prog.mk
+++ b/share/mk/bsd.prog.mk
@@ -15,6 +15,11 @@ CFLAGS+= -DNDEBUG
NO_WERROR=
.endif
+# Enable CTF conversion on request.
+.if defined(WITH_CTF)
+.undef NO_CTF
+.endif
+
.if defined(DEBUG_FLAGS)
CFLAGS+=${DEBUG_FLAGS}
CXXFLAGS+=${DEBUG_FLAGS}
@@ -61,9 +66,7 @@ ${PROG}: ${OBJS}
.else
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
.endif
-.if defined(CTFMERGE)
- ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
-.endif
+ @[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.else # !defined(SRCS)
@@ -87,9 +90,7 @@ ${PROG}: ${OBJS}
.else
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
.endif
-.if defined(CTFMERGE)
- ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
-.endif
+ @[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.endif
.endif
diff --git a/share/mk/sys.mk b/share/mk/sys.mk
index 51ec039..80ad3fa 100644
--- a/share/mk/sys.mk
+++ b/share/mk/sys.mk
@@ -55,14 +55,14 @@ NO_CTF = 1
# C Type Format data is required for DTrace
CTFFLAGS ?= -L VERSION
-.if !defined(NO_CTF)
CTFCONVERT ?= ctfconvert
CTFMERGE ?= ctfmerge
.if defined(CFLAGS) && (${CFLAGS:M-g} != "")
CTFFLAGS += -g
.else
-CFLAGS += -g
-.endif
+# XXX: What to do here? Is removing the CFLAGS part completely ok here?
+# For now comment it out to not compile with -g unconditionally.
+#CFLAGS += -g
.endif
CXX ?= c++
@@ -144,15 +144,11 @@ YFLAGS ?= -d
# SINGLE SUFFIX RULES
.c:
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.f:
${FC} ${FFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.sh:
cp ${.IMPSRC} ${.TARGET}
@@ -162,33 +158,25 @@ YFLAGS ?= -d
.c.o:
${CC} ${CFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.f.o:
${FC} ${FFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.y.o:
${YACC} ${YFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} -c y.tab.c
rm -f y.tab.c
mv y.tab.o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.l.o:
${LEX} ${LFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.y.c:
${YACC} ${YFLAGS} ${.IMPSRC}
@@ -226,15 +214,11 @@ YFLAGS ?= -d
.c:
${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.c.o:
${CC} ${CFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.cc .cpp .cxx .C:
${CXX} ${CXXFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
@@ -244,15 +228,11 @@ YFLAGS ?= -d
.m.o:
${OBJC} ${OBJCFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.p.o:
${PC} ${PFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.e .r .F .f:
${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} \
@@ -263,38 +243,28 @@ YFLAGS ?= -d
.S.o:
${CC} ${CFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.asm.o:
${CC} -x assembler-with-cpp ${CFLAGS} -c ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.s.o:
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
# XXX not -j safe
.y.o:
${YACC} ${YFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} -c y.tab.c -o ${.TARGET}
rm -f y.tab.c
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.l.o:
${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c
${CC} ${CFLAGS} -c ${.PREFIX}.tmp.c -o ${.TARGET}
rm -f ${.PREFIX}.tmp.c
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
# XXX not -j safe
.y.c:
@@ -306,34 +276,26 @@ YFLAGS ?= -d
.s.out .c.out .o.out:
${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.f.out .F.out .r.out .e.out:
${FC} ${EFLAGS} ${RFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} \
${LDLIBS} -o ${.TARGET}
rm -f ${.PREFIX}.o
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
# XXX not -j safe
.y.out:
${YACC} ${YFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} ${LDFLAGS} y.tab.c ${LDLIBS} -ly -o ${.TARGET}
rm -f y.tab.c
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.l.out:
${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c
${CC} ${CFLAGS} ${LDFLAGS} ${.PREFIX}.tmp.c ${LDLIBS} -ll -o ${.TARGET}
rm -f ${.PREFIX}.tmp.c
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
# FreeBSD build pollution. Hide it in the non-POSIX part of the ifdef.
__MAKE_CONF?=/etc/make.conf
diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c
index 7e7a01a..8c66696 100644
--- a/sys/amd64/acpica/acpi_machdep.c
+++ b/sys/amd64/acpica/acpi_machdep.c
@@ -627,8 +627,10 @@ map_table(vm_paddr_t pa, int offset, const char *sig)
if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
if (bootverbose)
printf("ACPI: Failed checksum for table %s\n", sig);
+#if (ACPI_CHECKSUM_ABORT)
table_unmap(table, length);
return (NULL);
+#endif
}
return (table);
}
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index cebafc8..df94a47 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -104,6 +104,18 @@ IDTVEC(timerint)
MEXITCOUNT
jmp doreti
+/*
+ * Local APIC error interrupt handler.
+ */
+ .text
+ SUPERALIGN_TEXT
+IDTVEC(errorint)
+ PUSH_FRAME
+ FAKE_MCOUNT(TF_RIP(%rsp))
+ call lapic_handle_error
+ MEXITCOUNT
+ jmp doreti
+
#ifdef SMP
/*
* Global address space TLB shootdown.
diff --git a/sys/amd64/amd64/bpf_jit_machdep.c b/sys/amd64/amd64/bpf_jit_machdep.c
index 6a5793e..fe861d2 100644
--- a/sys/amd64/amd64/bpf_jit_machdep.c
+++ b/sys/amd64/amd64/bpf_jit_machdep.c
@@ -419,62 +419,77 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size)
break;
case BPF_JMP|BPF_JA:
- JMP(stream.refs[stream.bpf_pc + ins->k] -
- stream.refs[stream.bpf_pc]);
+ JUMP(ins->k);
break;
case BPF_JMP|BPF_JGT|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPid(ins->k, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPid(ins->k, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPid(ins->k, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
TESTid(ins->k, EAX);
JCC(JNE, JE);
break;
case BPF_JMP|BPF_JGT|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPrd(EDX, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPrd(EDX, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPrd(EDX, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
TESTrd(EDX, EAX);
JCC(JNE, JE);
break;
diff --git a/sys/amd64/amd64/bpf_jit_machdep.h b/sys/amd64/amd64/bpf_jit_machdep.h
index aa7f342..01c251f 100644
--- a/sys/amd64/amd64/bpf_jit_machdep.h
+++ b/sys/amd64/amd64/bpf_jit_machdep.h
@@ -473,4 +473,10 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n);
} \
} while (0)
+#define JUMP(off) do { \
+ if ((off) != 0) \
+ JMP(stream.refs[stream.bpf_pc + (off)] - \
+ stream.refs[stream.bpf_pc]); \
+} while (0)
+
#endif /* _BPF_JIT_MACHDEP_H_ */
diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
index 73ffac5..cba90f2 100644
--- a/sys/amd64/amd64/db_trace.c
+++ b/sys/amd64/amd64/db_trace.c
@@ -319,7 +319,7 @@ db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td)
frame_type = INTERRUPT;
else if (strcmp(name, "Xfast_syscall") == 0)
frame_type = SYSCALL;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
else if (strcmp(name, "Xint0x80_syscall") == 0)
frame_type = SYSCALL;
#endif
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 16d50c5..0d5a50d 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -572,7 +572,7 @@ ENTRY(fork_trampoline)
* included.
*/
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
.data
.p2align 4
.text
@@ -668,7 +668,8 @@ ld_fs: movw %ax,%fs
movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx
- wrmsr
+ .globl ld_fsbase
+ld_fsbase: wrmsr
1:
/* Restore %gs and gsbase */
movw TF_GS(%rsp),%si
@@ -685,7 +686,8 @@ ld_gs: movw %si,%gs
movl $MSR_KGSBASE,%ecx
movl PCB_GSBASE(%r8),%eax
movl PCB_GSBASE+4(%r8),%edx
- wrmsr
+ .globl ld_gsbase
+ld_gsbase: wrmsr
1: .globl ld_es
ld_es: movw TF_ES(%rsp),%es
.globl ld_ds
@@ -798,6 +800,29 @@ gs_load_fault:
call trap
movw $KUG32SEL,TF_GS(%rsp)
jmp doreti
+
+ ALIGN_TEXT
+ .globl fsbase_load_fault
+fsbase_load_fault:
+ movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ movq %rsp, %rdi
+ call trap
+ movq PCPU(CURTHREAD),%r8
+ movq TD_PCB(%r8),%r8
+ movq $0,PCB_FSBASE(%r8)
+ jmp doreti
+
+ ALIGN_TEXT
+ .globl gsbase_load_fault
+gsbase_load_fault:
+ movl $T_PROTFLT,TF_TRAPNO(%rsp)
+ movq %rsp, %rdi
+ call trap
+ movq PCPU(CURTHREAD),%r8
+ movq TD_PCB(%r8),%r8
+ movq $0,PCB_GSBASE(%r8)
+ jmp doreti
+
#ifdef HWPMC_HOOKS
ENTRY(end_exceptions)
#endif
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index aecec7a..c23102a 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -187,7 +187,9 @@ printcpuinfo(void)
if (cpu_vendor_id == CPU_VENDOR_INTEL ||
cpu_vendor_id == CPU_VENDOR_AMD ||
cpu_vendor_id == CPU_VENDOR_CENTAUR) {
- printf(" Stepping = %u", cpu_id & 0xf);
+ printf(" Family = %x", CPUID_TO_FAMILY(cpu_id));
+ printf(" Model = %x", CPUID_TO_MODEL(cpu_id));
+ printf(" Stepping = %u", cpu_id & CPUID_STEPPING);
if (cpu_high > 0) {
/*
diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index 0d04bbd..c8f60f0 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#ifdef KDTRACE_HOOKS
#include <sys/dtrace_bsd.h>
-cyclic_clock_func_t lapic_cyclic_clock_func[MAXCPU];
+cyclic_clock_func_t cyclic_clock_func[MAXCPU];
#endif
/* Sanity checks on IDT vectors. */
@@ -115,14 +115,12 @@ struct lapic {
int la_ioint_irqs[APIC_NUM_IOINTS + 1];
} static lapics[MAX_APIC_ID + 1];
-/* XXX: should thermal be an NMI? */
-
/* Global defaults for local APIC LVT entries. */
static struct lvt lvts[LVT_MAX + 1] = {
{ 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 }, /* LINT0: masked ExtINT */
{ 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT }, /* Timer */
- { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */
+ { 1, 1, 0, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */
{ 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT }, /* Thermal */
};
@@ -149,6 +147,7 @@ extern inthand_t IDTVEC(rsvd);
volatile lapic_t *lapic;
vm_paddr_t lapic_paddr;
static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz;
+static enum lapic_clock clockcoverage;
static void lapic_enable(void);
static void lapic_resume(struct pic *pic);
@@ -160,9 +159,6 @@ static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value);
struct pic lapic_pic = { .pic_resume = lapic_resume };
-static int lapic_allclocks;
-TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
-
static uint32_t
lvt_mode(struct lapic *la, u_int pin, uint32_t value)
{
@@ -227,7 +223,10 @@ lapic_init(vm_paddr_t addr)
/* Local APIC timer interrupt. */
setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYSIGT, SEL_KPL, 0);
- /* XXX: error/thermal interrupts */
+ /* Local APIC error interrupt. */
+ setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_SYSIGT, SEL_KPL, 0);
+
+ /* XXX: Thermal interrupt */
}
/*
@@ -280,7 +279,7 @@ lapic_dump(const char* str)
lapic->id, lapic->version, lapic->ldr, lapic->dfr);
printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n",
lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
- printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pcm: 0x%08x\n",
+ printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n",
lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error,
lapic->lvt_pcint);
}
@@ -328,7 +327,11 @@ lapic_setup(int boot)
lapic_timer_enable_intr();
}
- /* XXX: Error and thermal LVTs */
+ /* Program error LVT and clear any existing errors. */
+ lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error);
+ lapic->esr = 0;
+
+ /* XXX: Thermal LVT */
intr_restore(eflags);
}
@@ -423,17 +426,20 @@ lapic_disable_pmc(void)
* local APIC only for the hardclock and 0 if none of them can be handled.
*/
enum lapic_clock
-lapic_setup_clock(void)
+lapic_setup_clock(enum lapic_clock srcsdes)
{
u_long value;
int i;
- /* Can't drive the timer without a local APIC. */
- if (lapic == NULL)
- return (LAPIC_CLOCK_NONE);
+ /* lapic_setup_clock() should not be called with LAPIC_CLOCK_NONE. */
+ MPASS(srcsdes != LAPIC_CLOCK_NONE);
- if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)
- return (LAPIC_CLOCK_NONE);
+ /* Can't drive the timer without a local APIC. */
+ if (lapic == NULL ||
+ (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) {
+ clockcoverage = LAPIC_CLOCK_NONE;
+ return (clockcoverage);
+ }
/* Start off with a divisor of 2 (power on reset default). */
lapic_timer_divisor = 2;
@@ -469,7 +475,7 @@ lapic_setup_clock(void)
* Please note that stathz and profhz are set only if all the
* clocks are handled through the local APIC.
*/
- if (lapic_allclocks != 0) {
+ if (srcsdes == LAPIC_CLOCK_ALL) {
if (hz >= 1500)
lapic_timer_hz = hz;
else if (hz >= 750)
@@ -479,7 +485,7 @@ lapic_setup_clock(void)
} else
lapic_timer_hz = hz;
lapic_timer_period = value / lapic_timer_hz;
- if (lapic_allclocks != 0) {
+ if (srcsdes == LAPIC_CLOCK_ALL) {
if (lapic_timer_hz < 128)
stathz = lapic_timer_hz;
else
@@ -493,7 +499,8 @@ lapic_setup_clock(void)
*/
lapic_timer_periodic(lapic_timer_period);
lapic_timer_enable_intr();
- return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL);
+ clockcoverage = srcsdes;
+ return (srcsdes);
}
void
@@ -723,18 +730,6 @@ lapic_eoi(void)
lapic->eoi = 0;
}
-/*
- * Read the contents of the error status register. We have to write
- * to the register first before reading from it.
- */
-u_int
-lapic_error(void)
-{
-
- lapic->esr = 0;
- return (lapic->esr);
-}
-
void
lapic_handle_intr(int vector, struct trapframe *frame)
{
@@ -783,8 +778,8 @@ lapic_handle_timer(struct trapframe *frame)
* timers.
*/
int cpu = PCPU_GET(cpuid);
- if (lapic_cyclic_clock_func[cpu] != NULL)
- (*lapic_cyclic_clock_func[cpu])(frame);
+ if (cyclic_clock_func[cpu] != NULL)
+ (*cyclic_clock_func[cpu])(frame);
#endif
/* Fire hardclock at hz. */
@@ -796,7 +791,7 @@ lapic_handle_timer(struct trapframe *frame)
else
hardclock_cpu(TRAPF_USERMODE(frame));
}
- if (lapic_allclocks != 0) {
+ if (clockcoverage == LAPIC_CLOCK_ALL) {
/* Fire statclock at stathz. */
la->la_stat_ticks += stathz;
@@ -861,6 +856,24 @@ lapic_timer_enable_intr(void)
lapic->lvt_timer = value;
}
+void
+lapic_handle_error(void)
+{
+ u_int32_t esr;
+
+ /*
+ * Read the contents of the error status register. Write to
+ * the register first before reading from it to force the APIC
+ * to update its value to indicate any errors that have
+ * occurred since the previous write to the register.
+ */
+ lapic->esr = 0;
+ esr = lapic->esr;
+
+ printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr);
+ lapic_eoi();
+}
+
u_int
apic_cpuid(u_int apic_id)
{
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 2318975..b65b679 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -424,13 +424,14 @@ sigreturn(td, uap)
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0) {
- printf("sigreturn (pid %d): copyin failed\n", p->p_pid);
+ uprintf("pid %d (%s): sigreturn copyin failed\n",
+ p->p_pid, td->td_name);
return (error);
}
ucp = &uc;
if ((ucp->uc_mcontext.mc_flags & ~_MC_FLAG_MASK) != 0) {
- printf("sigreturn (pid %d): mc_flags %x\n", p->p_pid,
- ucp->uc_mcontext.mc_flags);
+ uprintf("pid %d (%s): sigreturn mc_flags %x\n", p->p_pid,
+ td->td_name, ucp->uc_mcontext.mc_flags);
return (EINVAL);
}
regs = td->td_frame;
@@ -449,8 +450,8 @@ sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
- printf("sigreturn (pid %d): rflags = 0x%lx\n", p->p_pid,
- rflags);
+ uprintf("pid %d (%s): sigreturn rflags = 0x%lx\n", p->p_pid,
+ td->td_name, rflags);
return (EINVAL);
}
@@ -461,7 +462,8 @@ sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
- printf("sigreturn (pid %d): cs = 0x%x\n", p->p_pid, cs);
+ uprintf("pid %d (%s): sigreturn cs = 0x%x\n", p->p_pid,
+ td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@@ -473,7 +475,8 @@ sigreturn(td, uap)
ret = set_fpcontext(td, &ucp->uc_mcontext);
if (ret != 0) {
- printf("sigreturn (pid %d): set_fpcontext\n", p->p_pid);
+ uprintf("pid %d (%s): sigreturn set_fpcontext err %d\n",
+ p->p_pid, td->td_name, ret);
return (ret);
}
bcopy(&ucp->uc_mcontext.mc_rdi, regs, sizeof(*regs));
@@ -841,11 +844,7 @@ SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
* Reset registers to default values on exec.
*/
void
-exec_setregs(td, entry, stack, ps_strings)
- struct thread *td;
- u_long entry;
- u_long stack;
- u_long ps_strings;
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *regs = td->td_frame;
struct pcb *pcb = td->td_pcb;
@@ -863,7 +862,7 @@ exec_setregs(td, entry, stack, ps_strings)
pcb->pcb_full_iret = 1;
bzero((char *)regs, sizeof(struct trapframe));
- regs->tf_rip = entry;
+ regs->tf_rip = imgp->entry_addr;
regs->tf_rsp = ((stack - 8) & ~0xFul) + 8;
regs->tf_rdi = stack; /* argv */
regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c
index b0e842a..ccbab17 100644
--- a/sys/amd64/amd64/mca.c
+++ b/sys/amd64/amd64/mca.c
@@ -60,11 +60,20 @@ static int mca_count; /* Number of records stored. */
SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture");
-static int mca_enabled = 0;
+static int mca_enabled = 1;
TUNABLE_INT("hw.mca.enabled", &mca_enabled);
SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0,
"Administrative toggle for machine check support");
+static int amd10h_L1TP = 1;
+TUNABLE_INT("hw.mca.amd10h_L1TP", &amd10h_L1TP);
+SYSCTL_INT(_hw_mca, OID_AUTO, amd10h_L1TP, CTLFLAG_RDTUN, &amd10h_L1TP, 0,
+ "Administrative toggle for logging of level one TLB parity (L1TP) errors");
+
+int workaround_erratum383;
+SYSCTL_INT(_hw_mca, OID_AUTO, erratum383, CTLFLAG_RD, &workaround_erratum383, 0,
+ "Is the workaround for Erratum 383 on AMD Family 10h processors enabled?");
+
static STAILQ_HEAD(, mca_internal) mca_records;
static struct callout mca_timer;
static int mca_ticks = 3600; /* Check hourly by default. */
@@ -177,19 +186,46 @@ mca_error_request(uint16_t mca_error)
return ("???");
}
+static const char *
+mca_error_mmtype(uint16_t mca_error)
+{
+
+ switch ((mca_error & 0x70) >> 4) {
+ case 0x0:
+ return ("GEN");
+ case 0x1:
+ return ("RD");
+ case 0x2:
+ return ("WR");
+ case 0x3:
+ return ("AC");
+ case 0x4:
+ return ("MS");
+ }
+ return ("???");
+}
+
/* Dump details about a single machine check. */
static void __nonnull(1)
mca_log(const struct mca_record *rec)
{
uint16_t mca_error;
- printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank,
+ printf("MCA: Bank %d, Status 0x%016llx\n", rec->mr_bank,
(long long)rec->mr_status);
- printf("MCA: CPU %d ", rec->mr_apic_id);
+ printf("MCA: Global Cap 0x%016llx, Status 0x%016llx\n",
+ (long long)rec->mr_mcg_cap, (long long)rec->mr_mcg_status);
+ printf("MCA: Vendor \"%s\", ID 0x%x, APIC ID %d\n", cpu_vendor,
+ rec->mr_cpu_id, rec->mr_apic_id);
+ printf("MCA: CPU %d ", rec->mr_cpu);
if (rec->mr_status & MC_STATUS_UC)
printf("UNCOR ");
- else
+ else {
printf("COR ");
+ if (rec->mr_mcg_cap & MCG_CAP_TES_P)
+ printf("(%lld) ", ((long long)rec->mr_status &
+ MC_STATUS_COR_COUNT) >> 38);
+ }
if (rec->mr_status & MC_STATUS_PCC)
printf("PCC ");
if (rec->mr_status & MC_STATUS_OVER)
@@ -212,6 +248,9 @@ mca_log(const struct mca_record *rec)
case 0x0004:
printf("FRC error");
break;
+ case 0x0005:
+ printf("internal parity error");
+ break;
case 0x0400:
printf("internal timer error");
break;
@@ -236,6 +275,17 @@ mca_log(const struct mca_record *rec)
break;
}
+ /* Memory controller error. */
+ if ((mca_error & 0xef80) == 0x0080) {
+ printf("%s channel ", mca_error_mmtype(mca_error));
+ if ((mca_error & 0x000f) != 0x000f)
+ printf("%d", mca_error & 0x000f);
+ else
+ printf("??");
+ printf(" memory error");
+ break;
+ }
+
/* Cache error. */
if ((mca_error & 0xef00) == 0x0100) {
printf("%sCACHE %s %s error",
@@ -313,6 +363,11 @@ mca_check_status(int bank, struct mca_record *rec)
rec->mr_misc = rdmsr(MSR_MC_MISC(bank));
rec->mr_tsc = rdtsc();
rec->mr_apic_id = PCPU_GET(apic_id);
+ rec->mr_mcg_cap = rdmsr(MSR_MCG_CAP);
+ rec->mr_mcg_status = rdmsr(MSR_MCG_STATUS);
+ rec->mr_cpu_id = cpu_id;
+ rec->mr_cpu_vendor_id = cpu_vendor_id;
+ rec->mr_cpu = PCPU_GET(cpuid);
/*
* Clear machine check. Don't do this for uncorrectable
@@ -481,7 +536,7 @@ void
mca_init(void)
{
uint64_t mcg_cap;
- uint64_t ctl;
+ uint64_t ctl, mask;
int skip;
int i;
@@ -489,6 +544,15 @@ mca_init(void)
if (!mca_enabled || !(cpu_feature & CPUID_MCE))
return;
+ /*
+ * On AMD Family 10h processors, unless logging of level one TLB
+ * parity (L1TP) errors is disabled, enable the recommended workaround
+ * for Erratum 383.
+ */
+ if (cpu_vendor_id == CPU_VENDOR_AMD &&
+ CPUID_TO_FAMILY(cpu_id) == 0x10 && amd10h_L1TP)
+ workaround_erratum383 = 1;
+
if (cpu_feature & CPUID_MCA) {
if (PCPU_GET(cpuid) == 0)
mca_setup();
@@ -499,6 +563,19 @@ mca_init(void)
/* Enable MCA features. */
wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE);
+ /*
+ * Disable logging of level one TLB parity (L1TP) errors by
+ * the data cache as an alternative workaround for AMD Family
+ * 10h Erratum 383. Unlike the recommended workaround, there
+ * is no performance penalty to this workaround. However,
+ * L1TP errors will go unreported.
+ */
+ if (cpu_vendor_id == CPU_VENDOR_AMD &&
+ CPUID_TO_FAMILY(cpu_id) == 0x10 && !amd10h_L1TP) {
+ mask = rdmsr(MSR_MC0_CTL_MASK);
+ if ((mask & (1UL << 5)) == 0)
+ wrmsr(MSR_MC0_CTL_MASK, mask | (1UL << 5));
+ }
for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) {
/* By default enable logging of all errors. */
ctl = 0xffffffffffffffffUL;
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 07db5d1..d07292d 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -7,7 +7,7 @@
* All rights reserved.
* Copyright (c) 2003 Peter Wemm
* All rights reserved.
- * Copyright (c) 2005-2008 Alan L. Cox <alc@cs.rice.edu>
+ * Copyright (c) 2005-2010 Alan L. Cox <alc@cs.rice.edu>
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -152,7 +152,7 @@ __FBSDID("$FreeBSD$");
#if !defined(DIAGNOSTIC)
#ifdef __GNUC_GNU_INLINE__
-#define PMAP_INLINE inline
+#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
#else
#define PMAP_INLINE extern inline
#endif
@@ -236,6 +236,7 @@ static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte);
static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte);
static void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva);
static boolean_t pmap_is_modified_pvh(struct md_page *pvh);
+static boolean_t pmap_is_referenced_pvh(struct md_page *pvh);
static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode);
static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va);
static void pmap_pde_attr(pd_entry_t *pde, int cache_bits);
@@ -255,6 +256,9 @@ static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m);
static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
vm_page_t m);
+static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
+ pd_entry_t newpde);
+static void pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde);
static vm_page_t pmap_allocpde(pmap_t pmap, vm_offset_t va, int flags);
static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags);
@@ -280,7 +284,7 @@ pmap_kmem_choose(vm_offset_t addr)
vm_offset_t newaddr = addr;
newaddr = (addr + (NBPDR - 1)) & ~(NBPDR - 1);
- return newaddr;
+ return (newaddr);
}
/********************/
@@ -291,7 +295,7 @@ pmap_kmem_choose(vm_offset_t addr)
static __inline vm_pindex_t
pmap_pde_pindex(vm_offset_t va)
{
- return va >> PDRSHIFT;
+ return (va >> PDRSHIFT);
}
@@ -350,7 +354,7 @@ pmap_pdpe(pmap_t pmap, vm_offset_t va)
pml4e = pmap_pml4e(pmap, va);
if ((*pml4e & PG_V) == 0)
- return NULL;
+ return (NULL);
return (pmap_pml4e_to_pdpe(pml4e, va));
}
@@ -372,7 +376,7 @@ pmap_pde(pmap_t pmap, vm_offset_t va)
pdpe = pmap_pdpe(pmap, va);
if (pdpe == NULL || (*pdpe & PG_V) == 0)
- return NULL;
+ return (NULL);
return (pmap_pdpe_to_pde(pdpe, va));
}
@@ -394,12 +398,27 @@ pmap_pte(pmap_t pmap, vm_offset_t va)
pde = pmap_pde(pmap, va);
if (pde == NULL || (*pde & PG_V) == 0)
- return NULL;
+ return (NULL);
if ((*pde & PG_PS) != 0) /* compat with i386 pmap_pte() */
return ((pt_entry_t *)pde);
return (pmap_pde_to_pte(pde, va));
}
+static __inline void
+pmap_resident_count_inc(pmap_t pmap, int count)
+{
+
+ PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+ pmap->pm_stats.resident_count += count;
+}
+
+static __inline void
+pmap_resident_count_dec(pmap_t pmap, int count)
+{
+
+ PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+ pmap->pm_stats.resident_count -= count;
+}
PMAP_INLINE pt_entry_t *
vtopte(vm_offset_t va)
@@ -573,8 +592,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
virtual_avail = va;
- invltlb();
-
/* Initialize the PAT MSR. */
pmap_init_pat();
}
@@ -686,13 +703,13 @@ pmap_init(void)
pv_entry_high_water = 9 * (pv_entry_max / 10);
/*
- * Disable large page mappings by default if the kernel is running in
- * a virtual machine on an AMD Family 10h processor. This is a work-
- * around for Erratum 383.
+ * If the kernel is running in a virtual machine on an AMD Family 10h
+ * processor, then it must assume that MCA is enabled by the virtual
+ * machine monitor.
*/
if (vm_guest == VM_GUEST_VM && cpu_vendor_id == CPU_VENDOR_AMD &&
CPUID_TO_FAMILY(cpu_id) == 0x10)
- pg_ps_enabled = 0;
+ workaround_erratum383 = 1;
/*
* Are large page mappings enabled?
@@ -848,6 +865,45 @@ pmap_cache_bits(int mode, boolean_t is_pde)
cache_bits |= PG_NC_PWT;
return (cache_bits);
}
+
+/*
+ * After changing the page size for the specified virtual address in the page
+ * table, flush the corresponding entries from the processor's TLB. Only the
+ * calling processor's TLB is affected.
+ *
+ * The calling thread must be pinned to a processor.
+ */
+static void
+pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde)
+{
+ u_long cr4;
+
+ if ((newpde & PG_PS) == 0)
+ /* Demotion: flush a specific 2MB page mapping. */
+ invlpg(va);
+ else if ((newpde & PG_G) == 0)
+ /*
+ * Promotion: flush every 4KB page mapping from the TLB
+ * because there are too many to flush individually.
+ */
+ invltlb();
+ else {
+ /*
+ * Promotion: flush every 4KB page mapping from the TLB,
+ * including any global (PG_G) mappings.
+ */
+ cr4 = rcr4();
+ load_cr4(cr4 & ~CR4_PGE);
+ /*
+ * Although preemption at this point could be detrimental to
+ * performance, it would not lead to an error. PG_G is simply
+ * ignored if CR4.PGE is clear. Moreover, in case this block
+ * is re-entered, the load_cr4() either above or below will
+ * modify CR4.PGE flushing the TLB.
+ */
+ load_cr4(cr4 | CR4_PGE);
+ }
+}
#ifdef SMP
/*
* For SMP, these functions have to use the IPI mechanism for coherence.
@@ -944,6 +1000,69 @@ pmap_invalidate_cache(void)
smp_cache_flush();
sched_unpin();
}
+
+struct pde_action {
+ cpumask_t store; /* processor that updates the PDE */
+ cpumask_t invalidate; /* processors that invalidate their TLB */
+ vm_offset_t va;
+ pd_entry_t *pde;
+ pd_entry_t newpde;
+};
+
+static void
+pmap_update_pde_action(void *arg)
+{
+ struct pde_action *act = arg;
+
+ if (act->store == PCPU_GET(cpumask))
+ pde_store(act->pde, act->newpde);
+}
+
+static void
+pmap_update_pde_teardown(void *arg)
+{
+ struct pde_action *act = arg;
+
+ if ((act->invalidate & PCPU_GET(cpumask)) != 0)
+ pmap_update_pde_invalidate(act->va, act->newpde);
+}
+
+/*
+ * Change the page size for the specified virtual address in a way that
+ * prevents any possibility of the TLB ever having two entries that map the
+ * same virtual address using different page sizes. This is the recommended
+ * workaround for Erratum 383 on AMD Family 10h processors. It prevents a
+ * machine check exception for a TLB state that is improperly diagnosed as a
+ * hardware error.
+ */
+static void
+pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
+{
+ struct pde_action act;
+ cpumask_t active, cpumask;
+
+ sched_pin();
+ cpumask = PCPU_GET(cpumask);
+ if (pmap == kernel_pmap)
+ active = all_cpus;
+ else
+ active = pmap->pm_active;
+ if ((active & PCPU_GET(other_cpus)) != 0) {
+ act.store = cpumask;
+ act.invalidate = active;
+ act.va = va;
+ act.pde = pde;
+ act.newpde = newpde;
+ smp_rendezvous_cpus(cpumask | active,
+ smp_no_rendevous_barrier, pmap_update_pde_action,
+ pmap_update_pde_teardown, &act);
+ } else {
+ pde_store(pde, newpde);
+ if ((active & cpumask) != 0)
+ pmap_update_pde_invalidate(va, newpde);
+ }
+ sched_unpin();
+}
#else /* !SMP */
/*
* Normal, non-SMP, invalidation functions.
@@ -981,6 +1100,15 @@ pmap_invalidate_cache(void)
wbinvd();
}
+
+static void
+pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
+{
+
+ pde_store(pde, newpde);
+ if (pmap == kernel_pmap || pmap->pm_active)
+ pmap_update_pde_invalidate(va, newpde);
+}
#endif /* !SMP */
static void
@@ -994,7 +1122,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
if (cpu_feature & CPUID_SS)
; /* If "Self Snoop" is supported, do nothing. */
- else if (cpu_feature & CPUID_CLFSH) {
+ else if ((cpu_feature & CPUID_CLFSH) != 0 &&
+ eva - sva < 2 * 1024 * 1024) {
/*
* Otherwise, do per-cache line flush. Use the mfence
@@ -1011,7 +1140,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
/*
* No targeted cache flush methods are supported by CPU,
- * globally invalidate cache as a last resort.
+ * or the supplied range is bigger than 2MB.
+ * Globally invalidate cache.
*/
pmap_invalidate_cache();
}
@@ -1122,7 +1252,7 @@ pmap_kextract(vm_offset_t va)
pa = (pa & PG_FRAME) | (va & PAGE_MASK);
}
}
- return pa;
+ return (pa);
}
/***************************************************
@@ -1352,9 +1482,9 @@ pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t *free)
--m->wire_count;
if (m->wire_count == 0)
- return _pmap_unwire_pte_hold(pmap, va, m, free);
+ return (_pmap_unwire_pte_hold(pmap, va, m, free));
else
- return 0;
+ return (0);
}
static int
@@ -1362,6 +1492,7 @@ _pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m,
vm_page_t *free)
{
+ PMAP_LOCK_ASSERT(pmap, MA_OWNED);
/*
* unmap the page table page
*/
@@ -1381,7 +1512,7 @@ _pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m,
pd = pmap_pde(pmap, va);
*pd = 0;
}
- --pmap->pm_stats.resident_count;
+ pmap_resident_count_dec(pmap, 1);
if (m->pindex < NUPDE) {
/* We just released a PT, unhold the matching PD */
vm_page_t pdpg;
@@ -1410,7 +1541,7 @@ _pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m,
*/
pmap_add_delayed_free_list(m, free, TRUE);
- return 1;
+ return (1);
}
/*
@@ -1423,10 +1554,10 @@ pmap_unuse_pt(pmap_t pmap, vm_offset_t va, pd_entry_t ptepde, vm_page_t *free)
vm_page_t mpte;
if (va >= VM_MAXUSER_ADDRESS)
- return 0;
+ return (0);
KASSERT(ptepde != 0, ("pmap_unuse_pt: ptepde != 0"));
mpte = PHYS_TO_VM_PAGE(ptepde & PG_FRAME);
- return pmap_unwire_pte_hold(pmap, va, mpte, free);
+ return (pmap_unwire_pte_hold(pmap, va, mpte, free));
}
void
@@ -1498,6 +1629,7 @@ _pmap_allocpte(pmap_t pmap, vm_pindex_t ptepindex, int flags)
(flags & (M_NOWAIT | M_WAITOK)) == M_WAITOK,
("_pmap_allocpte: flags is neither M_NOWAIT nor M_WAITOK"));
+ PMAP_LOCK_ASSERT(pmap, MA_OWNED);
/*
* Allocate a page table page.
*/
@@ -1615,9 +1747,9 @@ _pmap_allocpte(pmap_t pmap, vm_pindex_t ptepindex, int flags)
*pd = VM_PAGE_TO_PHYS(m) | PG_U | PG_RW | PG_V | PG_A | PG_M;
}
- pmap->pm_stats.resident_count++;
+ pmap_resident_count_inc(pmap, 1);
- return m;
+ return (m);
}
static vm_page_t
@@ -1922,7 +2054,7 @@ pmap_collect(pmap_t locked_pmap, struct vpgqueues *vpq)
PMAP_LOCK(pmap);
else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap))
continue;
- pmap->pm_stats.resident_count--;
+ pmap_resident_count_dec(pmap, 1);
pde = pmap_pde(pmap, va);
KASSERT((*pde & PG_PS) == 0, ("pmap_collect: found"
" a 2mpage in page %p's pv list", m));
@@ -2323,7 +2455,7 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
return (FALSE);
}
if (va < VM_MAXUSER_ADDRESS)
- pmap->pm_stats.resident_count++;
+ pmap_resident_count_inc(pmap, 1);
}
mptepa = VM_PAGE_TO_PHYS(mpte);
firstpte = (pt_entry_t *)PHYS_TO_DMAP(mptepa);
@@ -2361,7 +2493,10 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
* processor changing the setting of PG_A and/or PG_M between
* the read above and the store below.
*/
- pde_store(pde, newpde);
+ if (workaround_erratum383)
+ pmap_update_pde(pmap, va, pde, newpde);
+ else
+ pde_store(pde, newpde);
/*
* Invalidate a stale recursive mapping of the page table page.
@@ -2412,7 +2547,7 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
*/
if (oldpde & PG_G)
pmap_invalidate_page(kernel_pmap, sva);
- pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
+ pmap_resident_count_dec(pmap, NBPDR / PAGE_SIZE);
if (oldpde & PG_MANAGED) {
pvh = pa_to_pvh(oldpde & PG_PS_FRAME);
pmap_pvh_free(pvh, pmap, sva);
@@ -2435,7 +2570,7 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
mpte = pmap_lookup_pt_page(pmap, sva);
if (mpte != NULL) {
pmap_remove_pt_page(pmap, mpte);
- pmap->pm_stats.resident_count--;
+ pmap_resident_count_dec(pmap, 1);
KASSERT(mpte->wire_count == NPTEPG,
("pmap_remove_pde: pte page wire count error"));
mpte->wire_count = 0;
@@ -2466,7 +2601,7 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va,
*/
if (oldpte & PG_G)
pmap_invalidate_page(kernel_pmap, va);
- pmap->pm_stats.resident_count -= 1;
+ pmap_resident_count_dec(pmap, 1);
if (oldpte & PG_MANAGED) {
m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME);
if ((oldpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
@@ -2658,9 +2793,9 @@ pmap_remove_all(vm_page_t m)
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
while ((pv = TAILQ_FIRST(&pvh->pv_list)) != NULL) {
- va = pv->pv_va;
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
+ va = pv->pv_va;
pde = pmap_pde(pmap, va);
(void)pmap_demote_pde(pmap, pde, va);
PMAP_UNLOCK(pmap);
@@ -2668,7 +2803,7 @@ pmap_remove_all(vm_page_t m)
while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
- pmap->pm_stats.resident_count--;
+ pmap_resident_count_dec(pmap, 1);
pde = pmap_pde(pmap, pv->pv_va);
KASSERT((*pde & PG_PS) == 0, ("pmap_remove_all: found"
" a 2mpage in page %p's pv list", m));
@@ -2715,18 +2850,9 @@ retry:
if (oldpde & PG_MANAGED) {
eva = sva + NBPDR;
for (va = sva, m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME);
- va < eva; va += PAGE_SIZE, m++) {
- /*
- * In contrast to the analogous operation on a 4KB page
- * mapping, the mapping's PG_A flag is not cleared and
- * the page's PG_REFERENCED flag is not set. The
- * reason is that pmap_demote_pde() expects that a 2MB
- * page mapping with a stored page table page has PG_A
- * set.
- */
+ va < eva; va += PAGE_SIZE, m++)
if ((oldpde & (PG_M | PG_RW)) == (PG_M | PG_RW))
vm_page_dirty(m);
- }
}
if ((prot & VM_PROT_WRITE) == 0)
newpde &= ~(PG_RW | PG_M);
@@ -2835,23 +2961,15 @@ retry:
obits = pbits = *pte;
if ((pbits & PG_V) == 0)
continue;
- if (pbits & PG_MANAGED) {
- m = NULL;
- if (pbits & PG_A) {
+
+ if ((prot & VM_PROT_WRITE) == 0) {
+ if ((pbits & (PG_MANAGED | PG_M | PG_RW)) ==
+ (PG_MANAGED | PG_M | PG_RW)) {
m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
- vm_page_flag_set(m, PG_REFERENCED);
- pbits &= ~PG_A;
- }
- if ((pbits & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
- if (m == NULL)
- m = PHYS_TO_VM_PAGE(pbits &
- PG_FRAME);
vm_page_dirty(m);
}
- }
-
- if ((prot & VM_PROT_WRITE) == 0)
pbits &= ~(PG_RW | PG_M);
+ }
if ((prot & VM_PROT_EXECUTE) == 0)
pbits |= pg_nx;
@@ -2977,7 +3095,10 @@ setpte:
/*
* Map the superpage.
*/
- pde_store(pde, PG_PS | newpde);
+ if (workaround_erratum383)
+ pmap_update_pde(pmap, va, pde, PG_PS | newpde);
+ else
+ pde_store(pde, PG_PS | newpde);
pmap_pde_promotions++;
CTR2(KTR_PMAP, "pmap_promote_pde: success for va %#lx"
@@ -3088,7 +3209,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
" va: 0x%lx", va));
}
} else
- pmap->pm_stats.resident_count++;
+ pmap_resident_count_inc(pmap, 1);
/*
* Enter on the PV list if part of our managed memory.
@@ -3222,7 +3343,7 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
/*
* Increment counters.
*/
- pmap->pm_stats.resident_count += NBPDR / PAGE_SIZE;
+ pmap_resident_count_inc(pmap, NBPDR / PAGE_SIZE);
/*
* Map the superpage.
@@ -3376,7 +3497,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
/*
* Increment counters
*/
- pmap->pm_stats.resident_count++;
+ pmap_resident_count_inc(pmap, 1);
pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 0);
if ((prot & VM_PROT_EXECUTE) == 0)
@@ -3389,7 +3510,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
pte_store(pte, pa | PG_V | PG_U);
else
pte_store(pte, pa | PG_V | PG_U | PG_MANAGED);
- return mpte;
+ return (mpte);
}
/*
@@ -3481,8 +3602,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
if ((*pde & PG_V) == 0) {
pde_store(pde, pa | PG_PS | PG_M | PG_A |
PG_U | PG_RW | PG_V);
- pmap->pm_stats.resident_count += NBPDR /
- PAGE_SIZE;
+ pmap_resident_count_inc(pmap, NBPDR / PAGE_SIZE);
pmap_pde_mappings++;
} else {
/* Continue on if the PDE is already valid. */
@@ -3549,8 +3669,6 @@ out:
PMAP_UNLOCK(pmap);
}
-
-
/*
* Copy the range specified by src_addr/len
* from the source map to the range dst_addr/len
@@ -3625,8 +3743,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
pmap_pv_insert_pde(dst_pmap, addr, srcptepaddr &
PG_PS_FRAME))) {
*pde = srcptepaddr & ~PG_W;
- dst_pmap->pm_stats.resident_count +=
- NBPDR / PAGE_SIZE;
+ pmap_resident_count_inc(dst_pmap, NBPDR / PAGE_SIZE);
} else
dstmpde->wire_count--;
continue;
@@ -3669,7 +3786,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
*/
*dst_pte = ptetemp & ~(PG_W | PG_M |
PG_A);
- dst_pmap->pm_stats.resident_count++;
+ pmap_resident_count_inc(dst_pmap, 1);
} else {
free = NULL;
if (pmap_unwire_pte_hold(dst_pmap,
@@ -3766,12 +3883,12 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
int loops = 0;
if (m->flags & PG_FICTITIOUS)
- return FALSE;
+ return (FALSE);
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
if (PV_PMAP(pv) == pmap) {
- return TRUE;
+ return (TRUE);
}
loops++;
if (loops >= 16)
@@ -3942,7 +4059,7 @@ pmap_remove_pages(pmap_t pmap)
pv_entry_count--;
pc->pc_map[field] |= bitmask;
if ((tpte & PG_PS) != 0) {
- pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
+ pmap_resident_count_dec(pmap, NBPDR / PAGE_SIZE);
pvh = pa_to_pvh(tpte & PG_PS_FRAME);
TAILQ_REMOVE(&pvh->pv_list, pv, pv_list);
if (TAILQ_EMPTY(&pvh->pv_list)) {
@@ -3953,7 +4070,7 @@ pmap_remove_pages(pmap_t pmap)
mpte = pmap_lookup_pt_page(pmap, pv->pv_va);
if (mpte != NULL) {
pmap_remove_pt_page(pmap, mpte);
- pmap->pm_stats.resident_count--;
+ pmap_resident_count_dec(pmap, 1);
KASSERT(mpte->wire_count == NPTEPG,
("pmap_remove_pages: pte page wire count error"));
mpte->wire_count = 0;
@@ -3961,7 +4078,7 @@ pmap_remove_pages(pmap_t pmap)
atomic_subtract_int(&cnt.v_wire_count, 1);
}
} else {
- pmap->pm_stats.resident_count--;
+ pmap_resident_count_dec(pmap, 1);
TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
if (TAILQ_EMPTY(&m->md.pv_list)) {
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
@@ -4058,6 +4175,49 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
}
/*
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+ if (m->flags & PG_FICTITIOUS)
+ return (FALSE);
+ if (pmap_is_referenced_pvh(&m->md))
+ return (TRUE);
+ return (pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m))));
+}
+
+/*
+ * Returns TRUE if any of the given mappings were referenced and FALSE
+ * otherwise. Both page and 2mpage mappings are supported.
+ */
+static boolean_t
+pmap_is_referenced_pvh(struct md_page *pvh)
+{
+ pv_entry_t pv;
+ pt_entry_t *pte;
+ pmap_t pmap;
+ boolean_t rv;
+
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ rv = FALSE;
+ TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+ pmap = PV_PMAP(pv);
+ PMAP_LOCK(pmap);
+ pte = pmap_pte(pmap, pv->pv_va);
+ rv = (*pte & (PG_A | PG_V)) == (PG_A | PG_V);
+ PMAP_UNLOCK(pmap);
+ if (rv)
+ break;
+ }
+ return (rv);
+}
+
+/*
* Clear the write and modified bits in each of the given page's mappings.
*/
void
@@ -4076,9 +4236,9 @@ pmap_remove_write(vm_page_t m)
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_list, next_pv) {
- va = pv->pv_va;
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
+ va = pv->pv_va;
pde = pmap_pde(pmap, va);
if ((*pde & PG_RW) != 0)
(void)pmap_demote_pde(pmap, pde, va);
@@ -4134,9 +4294,9 @@ pmap_ts_referenced(vm_page_t m)
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_list, pvn) {
- va = pv->pv_va;
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
+ va = pv->pv_va;
pde = pmap_pde(pmap, va);
oldpde = *pde;
if ((oldpde & PG_A) != 0) {
@@ -4206,9 +4366,9 @@ pmap_clear_modify(vm_page_t m)
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_list, next_pv) {
- va = pv->pv_va;
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
+ va = pv->pv_va;
pde = pmap_pde(pmap, va);
oldpde = *pde;
if ((oldpde & PG_RW) != 0) {
@@ -4271,9 +4431,9 @@ pmap_clear_reference(vm_page_t m)
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_list, next_pv) {
- va = pv->pv_va;
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
+ va = pv->pv_va;
pde = pmap_pde(pmap, va);
oldpde = *pde;
if ((oldpde & PG_A) != 0) {
@@ -4744,7 +4904,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
if (pte != 0) {
val |= MINCORE_INCORE;
if ((pte & PG_MANAGED) == 0)
- return val;
+ return (val);
m = PHYS_TO_VM_PAGE(pa);
@@ -4773,14 +4933,12 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
*/
vm_page_lock_queues();
if ((m->flags & PG_REFERENCED) ||
- pmap_ts_referenced(m)) {
+ pmap_is_referenced(m))
val |= MINCORE_REFERENCED_OTHER;
- vm_page_flag_set(m, PG_REFERENCED);
- }
vm_page_unlock_queues();
}
}
- return val;
+ return (val);
}
void
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index bd7ee63..8acde03 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -303,7 +303,7 @@ trap(struct trapframe *frame)
* enabled later.
*/
if (ISPL(frame->tf_cs) == SEL_UPL)
- printf(
+ uprintf(
"pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curthread->td_name, type);
else if (type != T_NMI && type != T_BPTFLT &&
@@ -566,6 +566,14 @@ trap(struct trapframe *frame)
frame->tf_gs = _ugssel;
goto out;
}
+ if (frame->tf_rip == (long)ld_gsbase) {
+ frame->tf_rip = (long)gsbase_load_fault;
+ goto out;
+ }
+ if (frame->tf_rip == (long)ld_fsbase) {
+ frame->tf_rip = (long)fsbase_load_fault;
+ goto out;
+ }
if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
frame->tf_rip =
(long)PCPU_GET(curpcb)->pcb_onfault;
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 2c670a4..3f7d76a 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -439,7 +439,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
*/
cpu_thread_clean(td);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
/*
* Set the trap frame to point at the beginning of the uts
@@ -490,7 +490,7 @@ cpu_set_user_tls(struct thread *td, void *tls_base)
if ((u_int64_t)tls_base >= VM_MAXUSER_ADDRESS)
return (EINVAL);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
td->td_pcb->pcb_gsbase = (register_t)tls_base;
return (0);
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index a9eb19c..b5a1930 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -44,8 +44,7 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
-options COMPAT_IA32 # Compatible with i386 binaries
+options COMPAT_FREEBSD32 # Compatible with i386 binaries
options COMPAT_FREEBSD4 # Compatible with FreeBSD4
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options COMPAT_FREEBSD6 # Compatible with FreeBSD6
@@ -225,6 +224,7 @@ device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le')
device re # RealTek 8139C+/8169/8169S/8110S
device rl # RealTek 8129/8139
device sf # Adaptec AIC-6915 (``Starfire'')
+device sge # Silicon Integrated Systems SiS190/191
device sis # Silicon Integrated Systems SiS 900/SiS 7016
device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet
device ste # Sundance ST201 (D-Link DFE-550TX)
@@ -281,6 +281,7 @@ device firmware # firmware assist module
device bpf # Berkeley packet filter
# USB support
+options USB_DEBUG # enable debug msgs
device uhci # UHCI PCI->USB interface
device ohci # OHCI PCI->USB interface
device ehci # EHCI PCI->USB interface (USB 2.0)
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index 8b56e54..dbd689c 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -483,7 +483,7 @@ options PMAP_SHPGPERPROC=201
#XXX these 32 bit binaries is added.
# Enable 32-bit runtime support for FreeBSD/i386 binaries.
-options COMPAT_IA32
+options COMPAT_FREEBSD32
# Enable iBCS2 runtime support for SCO and ISC binaries
#XXX#options IBCS2
@@ -494,7 +494,7 @@ options COMPAT_IA32
# Enable Linux ABI emulation
#XXX#options COMPAT_LINUX
-# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_IA32)
+# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_FREEBSD32)
options COMPAT_LINUX32
# Enable the linux-like proc filesystem support (requires COMPAT_LINUX32
diff --git a/sys/amd64/conf/XENHVM b/sys/amd64/conf/XENHVM
index 7bfb8e2..51f1256 100644
--- a/sys/amd64/conf/XENHVM
+++ b/sys/amd64/conf/XENHVM
@@ -45,8 +45,7 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
-options COMPAT_IA32 # Compatible with i386 binaries
+options COMPAT_FREEBSD32 # Compatible with i386 binaries
options COMPAT_FREEBSD4 # Compatible with FreeBSD4
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options COMPAT_FREEBSD6 # Compatible with FreeBSD6
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index 10ec641..859b9923 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -141,9 +141,11 @@ ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
mcp->mc_esi = tp->tf_rsi;
mcp->mc_ebp = tp->tf_rbp;
mcp->mc_isp = tp->tf_rsp;
+ mcp->mc_eflags = tp->tf_rflags;
if (flags & GET_MC_CLEAR_RET) {
mcp->mc_eax = 0;
mcp->mc_edx = 0;
+ mcp->mc_eflags &= ~PSL_C;
} else {
mcp->mc_eax = tp->tf_rax;
mcp->mc_edx = tp->tf_rdx;
@@ -152,7 +154,6 @@ ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
mcp->mc_ecx = tp->tf_rcx;
mcp->mc_eip = tp->tf_rip;
mcp->mc_cs = tp->tf_cs;
- mcp->mc_eflags = tp->tf_rflags;
mcp->mc_esp = tp->tf_rsp;
mcp->mc_ss = tp->tf_ss;
mcp->mc_len = sizeof(*mcp);
@@ -565,7 +566,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
- printf("freebsd4_freebsd32_sigreturn: eflags = 0x%x\n", eflags);
+ uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, eflags);
return (EINVAL);
}
@@ -576,7 +578,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
- printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
+ uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@@ -647,7 +650,8 @@ freebsd32_sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
- printf("freebsd32_sigreturn: eflags = 0x%x\n", eflags);
+ uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, eflags);
return (EINVAL);
}
@@ -658,7 +662,8 @@ freebsd32_sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
- printf("sigreturn: cs = 0x%x\n", cs);
+ uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@@ -701,11 +706,7 @@ freebsd32_sigreturn(td, uap)
* Clear registers on exec
*/
void
-ia32_setregs(td, entry, stack, ps_strings)
- struct thread *td;
- u_long entry;
- u_long stack;
- u_long ps_strings;
+ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *regs = td->td_frame;
struct pcb *pcb = td->td_pcb;
@@ -721,12 +722,12 @@ ia32_setregs(td, entry, stack, ps_strings)
pcb->pcb_initial_fpucw = __INITIAL_FPUCW_I386__;
bzero((char *)regs, sizeof(struct trapframe));
- regs->tf_rip = entry;
+ regs->tf_rip = imgp->entry_addr;
regs->tf_rsp = stack;
regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
regs->tf_ss = _udatasel;
regs->tf_cs = _ucode32sel;
- regs->tf_rbx = ps_strings;
+ regs->tf_rbx = imgp->ps_strings;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
regs->tf_fs = _ufssel;
diff --git a/sys/amd64/include/_inttypes.h b/sys/amd64/include/_inttypes.h
index e6b2536..a7cbea5 100644
--- a/sys/amd64/include/_inttypes.h
+++ b/sys/amd64/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 8f15d84..91bba99 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
@@ -179,7 +179,8 @@ struct apic_enumerator {
inthand_t
IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
- IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
+ IDTVEC(apic_isr7), IDTVEC(errorint), IDTVEC(spuriousint),
+ IDTVEC(timerint);
extern vm_paddr_t lapic_paddr;
extern int apic_cpuids[];
@@ -211,13 +212,13 @@ void lapic_disable_pmc(void);
void lapic_dump(const char *str);
int lapic_enable_pmc(void);
void lapic_eoi(void);
-u_int lapic_error(void);
int lapic_id(void);
void lapic_init(vm_paddr_t addr);
int lapic_intr_pending(u_int vector);
void lapic_ipi_raw(register_t icrlo, u_int dest);
void lapic_ipi_vectored(u_int vector, int dest);
int lapic_ipi_wait(int delay);
+void lapic_handle_error(void);
void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(struct trapframe *frame);
void lapic_reenable_pmc(void);
@@ -230,7 +231,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
enum intr_trigger trigger);
void lapic_set_tpr(u_int vector);
void lapic_setup(int boot);
-enum lapic_clock lapic_setup_clock(void);
+enum lapic_clock lapic_setup_clock(enum lapic_clock srcsdes);
#endif /* !LOCORE */
#endif /* _MACHINE_APICVAR_H_ */
diff --git a/sys/amd64/include/elf.h b/sys/amd64/include/elf.h
index 88f4398..678f5d3 100644
--- a/sys/amd64/include/elf.h
+++ b/sys/amd64/include/elf.h
@@ -42,6 +42,7 @@
#include <sys/elf_generic.h>
#define ELF_ARCH EM_X86_64
+#define ELF_ARCH32 EM_386
#define ELF_MACHINE_OK(x) ((x) == EM_X86_64)
diff --git a/sys/amd64/include/mca.h b/sys/amd64/include/mca.h
index ddc3aeb..bc09480 100644
--- a/sys/amd64/include/mca.h
+++ b/sys/amd64/include/mca.h
@@ -37,6 +37,11 @@ struct mca_record {
uint64_t mr_tsc;
int mr_apic_id;
int mr_bank;
+ uint64_t mr_mcg_cap;
+ uint64_t mr_mcg_status;
+ int mr_cpu_id;
+ int mr_cpu_vendor_id;
+ int mr_cpu;
};
#ifdef _KERNEL
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index 15df851..88f3e1d 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -61,6 +61,7 @@ extern char sigcode[];
extern int szsigcode;
extern uint64_t *vm_page_dump;
extern int vm_page_dump_size;
+extern int workaround_erratum383;
extern int _udatasel;
extern int _ucodesel;
extern int _ucode32sel;
@@ -82,10 +83,14 @@ void ld_ds(void) __asm(__STRING(ld_ds));
void ld_es(void) __asm(__STRING(ld_es));
void ld_fs(void) __asm(__STRING(ld_fs));
void ld_gs(void) __asm(__STRING(ld_gs));
+void ld_fsbase(void) __asm(__STRING(ld_fsbase));
+void ld_gsbase(void) __asm(__STRING(ld_gsbase));
void ds_load_fault(void) __asm(__STRING(ds_load_fault));
void es_load_fault(void) __asm(__STRING(es_load_fault));
void fs_load_fault(void) __asm(__STRING(fs_load_fault));
void gs_load_fault(void) __asm(__STRING(gs_load_fault));
+void fsbase_load_fault(void) __asm(__STRING(fsbase_load_fault));
+void gsbase_load_fault(void) __asm(__STRING(gsbase_load_fault));
void dump_add_page(vm_paddr_t);
void dump_drop_page(vm_paddr_t);
void initializecpu(void);
diff --git a/sys/amd64/include/pmc_mdep.h b/sys/amd64/include/pmc_mdep.h
index f233a51..4f16485 100644
--- a/sys/amd64/include/pmc_mdep.h
+++ b/sys/amd64/include/pmc_mdep.h
@@ -43,17 +43,20 @@ struct pmc_mdep;
#include <dev/hwpmc/hwpmc_core.h>
#include <dev/hwpmc/hwpmc_piv.h>
#include <dev/hwpmc/hwpmc_tsc.h>
+#include <dev/hwpmc/hwpmc_uncore.h>
/*
* Intel processors implementing V2 and later of the Intel performance
* measurement architecture have PMCs of the following classes: TSC,
- * IAF and IAP.
+ * IAF, IAP, UCF and UCP.
*/
#define PMC_MDEP_CLASS_INDEX_TSC 0
#define PMC_MDEP_CLASS_INDEX_K8 1
#define PMC_MDEP_CLASS_INDEX_P4 1
#define PMC_MDEP_CLASS_INDEX_IAP 1
#define PMC_MDEP_CLASS_INDEX_IAF 2
+#define PMC_MDEP_CLASS_INDEX_UCP 3
+#define PMC_MDEP_CLASS_INDEX_UCF 4
/*
* On the amd64 platform we support the following PMCs.
@@ -63,12 +66,16 @@ struct pmc_mdep;
* PIV Intel P4/HTT and P4/EMT64
* IAP Intel Core/Core2/Atom CPUs in 64 bits mode.
* IAF Intel fixed-function PMCs in Core2 and later CPUs.
+ * UCP Intel Uncore programmable PMCs.
+ * UCF Intel Uncore fixed-function PMCs.
*/
union pmc_md_op_pmcallocate {
struct pmc_md_amd_op_pmcallocate pm_amd;
struct pmc_md_iaf_op_pmcallocate pm_iaf;
struct pmc_md_iap_op_pmcallocate pm_iap;
+ struct pmc_md_ucf_op_pmcallocate pm_ucf;
+ struct pmc_md_ucp_op_pmcallocate pm_ucp;
struct pmc_md_p4_op_pmcallocate pm_p4;
uint64_t __pad[4];
};
@@ -83,6 +90,8 @@ union pmc_md_pmc {
struct pmc_md_amd_pmc pm_amd;
struct pmc_md_iaf_pmc pm_iaf;
struct pmc_md_iap_pmc pm_iap;
+ struct pmc_md_ucf_pmc pm_ucf;
+ struct pmc_md_ucp_pmc pm_ucp;
struct pmc_md_p4_pmc pm_p4;
};
diff --git a/sys/amd64/include/proc.h b/sys/amd64/include/proc.h
index 33d5181..126412c 100644
--- a/sys/amd64/include/proc.h
+++ b/sys/amd64/include/proc.h
@@ -53,6 +53,9 @@ struct mdproc {
struct system_segment_descriptor md_ldt_sd;
};
+#define KINFO_PROC_SIZE 1088
+#define KINFO_PROC32_SIZE 768
+
#ifdef _KERNEL
/* Get the current kernel thread stack usage. */
diff --git a/sys/amd64/include/reg.h b/sys/amd64/include/reg.h
index 89211a3..5920843 100644
--- a/sys/amd64/include/reg.h
+++ b/sys/amd64/include/reg.h
@@ -37,6 +37,10 @@
#ifndef _MACHINE_REG_H_
#define _MACHINE_REG_H_
+#if defined(_KERNEL) && !defined(_STANDALONE)
+#include "opt_compat.h"
+#endif
+
/*
* Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS.
*/
@@ -105,7 +109,7 @@ struct dbreg {
#define DBREG_DR7_EXEC 0x00 /* break on execute */
#define DBREG_DR7_WRONLY 0x01 /* break on write */
#define DBREG_DR7_RDWR 0x03 /* break on read or write */
-#define DBREG_DR7_MASK(i) ((u_long)0xf << ((i) * 4 + 16) | 0x3 << (i) * 2)
+#define DBREG_DR7_MASK(i) (0xful << ((i) * 4 + 16) | 0x3 << (i) * 2)
#define DBREG_DR7_SET(i, len, access, enable) \
((u_long)((len) << 2 | (access)) << ((i) * 4 + 16) | (enable) << (i) * 2)
#define DBREG_DR7_GD 0x2000
@@ -116,6 +120,11 @@ struct dbreg {
#define DBREG_DRX(d,x) ((d)->dr[(x)]) /* reference dr0 - dr15 by
register number */
+#ifdef COMPAT_FREEBSD32
+#include <machine/fpu.h>
+#include <compat/ia32/ia32_reg.h>
+#endif
+
#ifdef _KERNEL
/*
* XXX these interfaces are MI, so they should be declared in a MI place.
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index 8cadbcd..86a08ce 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -267,6 +267,7 @@
#define MSR_MTRR16kBase 0x258
#define MSR_MTRR4kBase 0x268
#define MSR_PAT 0x277
+#define MSR_MC0_CTL2 0x280
#define MSR_MTRRdefType 0x2ff
#define MSR_MC0_CTL 0x400
#define MSR_MC0_STATUS 0x401
@@ -320,16 +321,16 @@
#define MTRR_N64K 8 /* numbers of fixed-size entries */
#define MTRR_N16K 16
#define MTRR_N4K 64
-#define MTRR_CAP_WC 0x0000000000000400UL
-#define MTRR_CAP_FIXED 0x0000000000000100UL
-#define MTRR_CAP_VCNT 0x00000000000000ffUL
-#define MTRR_DEF_ENABLE 0x0000000000000800UL
-#define MTRR_DEF_FIXED_ENABLE 0x0000000000000400UL
-#define MTRR_DEF_TYPE 0x00000000000000ffUL
-#define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000UL
-#define MTRR_PHYSBASE_TYPE 0x00000000000000ffUL
-#define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000UL
-#define MTRR_PHYSMASK_VALID 0x0000000000000800UL
+#define MTRR_CAP_WC 0x0000000000000400
+#define MTRR_CAP_FIXED 0x0000000000000100
+#define MTRR_CAP_VCNT 0x00000000000000ff
+#define MTRR_DEF_ENABLE 0x0000000000000800
+#define MTRR_DEF_FIXED_ENABLE 0x0000000000000400
+#define MTRR_DEF_TYPE 0x00000000000000ff
+#define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000
+#define MTRR_PHYSBASE_TYPE 0x00000000000000ff
+#define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000
+#define MTRR_PHYSMASK_VALID 0x0000000000000800
/* Performance Control Register (5x86 only). */
#define PCR0 0x20
@@ -352,27 +353,38 @@
#define MCG_CAP_COUNT 0x000000ff
#define MCG_CAP_CTL_P 0x00000100
#define MCG_CAP_EXT_P 0x00000200
+#define MCG_CAP_CMCI_P 0x00000400
#define MCG_CAP_TES_P 0x00000800
#define MCG_CAP_EXT_CNT 0x00ff0000
+#define MCG_CAP_SER_P 0x01000000
#define MCG_STATUS_RIPV 0x00000001
#define MCG_STATUS_EIPV 0x00000002
#define MCG_STATUS_MCIP 0x00000004
-#define MCG_CTL_ENABLE 0xffffffffffffffffUL
-#define MCG_CTL_DISABLE 0x0000000000000000UL
+#define MCG_CTL_ENABLE 0xffffffffffffffff
+#define MCG_CTL_DISABLE 0x0000000000000000
#define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4)
#define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4)
#define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4)
#define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4)
-#define MC_STATUS_MCA_ERROR 0x000000000000ffffUL
-#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000UL
-#define MC_STATUS_OTHER_INFO 0x01ffffff00000000UL
-#define MC_STATUS_PCC 0x0200000000000000UL
-#define MC_STATUS_ADDRV 0x0400000000000000UL
-#define MC_STATUS_MISCV 0x0800000000000000UL
-#define MC_STATUS_EN 0x1000000000000000UL
-#define MC_STATUS_UC 0x2000000000000000UL
-#define MC_STATUS_OVER 0x4000000000000000UL
-#define MC_STATUS_VAL 0x8000000000000000UL
+#define MSR_MC_CTL2(x) (MSR_MC0_CTL2 + (x)) /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_MCA_ERROR 0x000000000000ffff
+#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000
+#define MC_STATUS_OTHER_INFO 0x01ffffff00000000
+#define MC_STATUS_COR_COUNT 0x001fffc000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_TES_STATUS 0x0060000000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_AR 0x0080000000000000 /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_S 0x0100000000000000 /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_PCC 0x0200000000000000
+#define MC_STATUS_ADDRV 0x0400000000000000
+#define MC_STATUS_MISCV 0x0800000000000000
+#define MC_STATUS_EN 0x1000000000000000
+#define MC_STATUS_UC 0x2000000000000000
+#define MC_STATUS_OVER 0x4000000000000000
+#define MC_STATUS_VAL 0x8000000000000000
+#define MC_MISC_RA_LSB 0x000000000000003f /* If MCG_CAP_SER_P */
+#define MC_MISC_ADDRESS_MODE 0x00000000000001c0 /* If MCG_CAP_SER_P */
+#define MC_CTL2_THRESHOLD 0x0000000000003fff
+#define MC_CTL2_CMCI_EN 0x0000000040000000
/*
* The following four 3-byte registers control the non-cacheable regions.
@@ -494,6 +506,7 @@
#define MSR_TOP_MEM 0xc001001a /* boundary for ram below 4G */
#define MSR_TOP_MEM2 0xc001001d /* boundary for ram above 4G */
#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */
+#define MSR_MC0_CTL_MASK 0xc0010044
/* VIA ACE crypto featureset: for via_feature_rng */
#define VIA_HAS_RNG 1 /* cpu has RNG */
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 350e773..239412c 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -203,9 +203,9 @@ struct l_newstat {
l_ulong st_size;
l_ulong st_blksize;
l_ulong st_blocks;
- struct l_timespec st_atimespec;
- struct l_timespec st_mtimespec;
- struct l_timespec st_ctimespec;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
l_ulong __unused4;
l_ulong __unused5;
} __packed;
@@ -219,9 +219,9 @@ struct l_stat {
l_ushort st_gid;
l_ushort st_rdev;
l_long st_size;
- struct l_timespec st_atimespec;
- struct l_timespec st_mtimespec;
- struct l_timespec st_ctimespec;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
l_long st_blksize;
l_long st_blocks;
l_ulong st_flags;
@@ -242,9 +242,9 @@ struct l_stat64 {
l_ulong st_blksize;
l_ulong st_blocks;
l_ulong __pad4;
- struct l_timespec st_atimespec;
- struct l_timespec st_mtimespec;
- struct l_timespec st_ctimespec;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
l_ulonglong st_ino;
} __packed;
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index 6e3e326..06f1e97 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -34,8 +34,8 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
-#ifndef COMPAT_IA32
-#error "Unable to compile Linux-emulator due to missing COMPAT_IA32 option!"
+#ifndef COMPAT_FREEBSD32
+#error "Unable to compile Linux-emulator due to missing COMPAT_FREEBSD32 option!"
#endif
#define __ELF_WORD_SIZE 32
@@ -124,8 +124,8 @@ static register_t *linux_copyout_strings(struct image_params *imgp);
static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
caddr_t *params);
static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
-static void exec_linux_setregs(struct thread *td, u_long entry,
- u_long stack, u_long ps_strings);
+static void exec_linux_setregs(struct thread *td,
+ struct image_params *imgp, u_long stack);
static void linux32_fixlimit(struct rlimit *rl, int which);
static boolean_t linux32_trans_osrel(const Elf_Note *note, int32_t *osrel);
@@ -828,11 +828,7 @@ exec_linux_imgact_try(struct image_params *imgp)
* XXX copied from ia32_signal.c.
*/
static void
-exec_linux_setregs(td, entry, stack, ps_strings)
- struct thread *td;
- u_long entry;
- u_long stack;
- u_long ps_strings;
+exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *regs = td->td_frame;
struct pcb *pcb = td->td_pcb;
@@ -852,7 +848,7 @@ exec_linux_setregs(td, entry, stack, ps_strings)
pcb->pcb_initial_fpucw = __LINUX_NPXCW__;
bzero((char *)regs, sizeof(struct trapframe));
- regs->tf_rip = entry;
+ regs->tf_rip = imgp->entry_addr;
regs->tf_rsp = stack;
regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
regs->tf_gs = _ugssel;
@@ -862,7 +858,7 @@ exec_linux_setregs(td, entry, stack, ps_strings)
regs->tf_ss = _udatasel;
regs->tf_flags = TF_HASSEGS;
regs->tf_cs = _ucode32sel;
- regs->tf_rbx = ps_strings;
+ regs->tf_rbx = imgp->ps_strings;
td->td_pcb->pcb_full_iret = 1;
load_cr0(rcr0() | CR0_MP | CR0_TS);
fpstate_drop(td);
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index 7080671..b7aa14f 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -649,7 +649,8 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
KASSERT(map->allocbuffer == vaddr,
("Trying to freeing the wrong DMA buffer"));
vaddr = map->origbuffer;
- arm_unmap_nocache(map->allocbuffer, dmat->maxsize);
+ arm_unmap_nocache(map->allocbuffer,
+ dmat->maxsize + ((vm_offset_t)vaddr & PAGE_MASK));
}
if (dmat->maxsize <= PAGE_SIZE &&
dmat->alignment < dmat->maxsize &&
diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c
index 55e342f..6d2a0f0 100644
--- a/sys/arm/arm/identcpu.c
+++ b/sys/arm/arm/identcpu.c
@@ -329,6 +329,7 @@ const struct cpu_classtab cpu_classes[] = {
{ "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */
{ "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */
{ "ARM11J", "CPU_ARM11" }, /* CPU_CLASS_ARM11J */
+ { "Marvell", "CPU_MARVELL" }, /* CPU_CLASS_MARVELL */
};
/*
@@ -404,6 +405,7 @@ identify_arm_cpu(void)
case CPU_CLASS_SA1:
case CPU_CLASS_XSCALE:
case CPU_CLASS_ARM11J:
+ case CPU_CLASS_MARVELL:
if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
printf(" DC disabled");
else
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 49af8e2..088d225 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -516,15 +516,15 @@ spinlock_exit(void)
* Clear registers on exec
*/
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf = td->td_frame;
memset(tf, 0, sizeof(*tf));
tf->tf_usr_sp = stack;
- tf->tf_usr_lr = entry;
+ tf->tf_usr_lr = imgp->entry_addr;
tf->tf_svc_lr = 0x77777777;
- tf->tf_pc = entry;
+ tf->tf_pc = imgp->entry_addr;
tf->tf_spsr = PSR_USR32_MODE;
}
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index ce4efae..366b43f 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -1605,10 +1605,11 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve, pmap_t pm,
pve->pv_flags = PVF_WRITE | PVF_UNMAN;
pg->md.pv_kva = 0;
+ if (!(km = PMAP_OWNED(pmap_kernel())))
+ PMAP_LOCK(pmap_kernel());
TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);
- TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist);
- if ((km = PMAP_OWNED(pmap_kernel())))
- PMAP_UNLOCK(pmap_kernel());
+ TAILQ_INSERT_HEAD(&pve->pv_pmap->pm_pvlist, pve, pv_plist);
+ PMAP_UNLOCK(pmap_kernel());
vm_page_unlock_queues();
if ((pve = pmap_get_pv_entry()) == NULL)
panic("pmap_kenter_internal: no pv entries");
@@ -1712,6 +1713,7 @@ pmap_nuke_pv(struct vm_page *pg, pmap_t pm, struct pv_entry *pve)
pv = TAILQ_FIRST(&pg->md.pv_list);
if (pv != NULL && (pv->pv_flags & PVF_UNMAN) &&
TAILQ_NEXT(pv, pv_list) == NULL) {
+ pm = kernel_pmap;
pg->md.pv_kva = pv->pv_va;
/* a recursive pmap_nuke_pv */
TAILQ_REMOVE(&pg->md.pv_list, pv, pv_list);
@@ -4491,6 +4493,20 @@ pmap_clear_modify(vm_page_t m)
/*
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+ return ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0 &&
+ (m->md.pvh_attrs & PVF_REF) != 0);
+}
+
+/*
* pmap_clear_reference:
*
* Clear the reference bit on the specified physical page.
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 95b9ca8..9b530ab 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -171,6 +171,9 @@ sf_buf_free(struct sf_buf *sf)
if (sf->ref_count == 0) {
TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
nsfbufsused--;
+ pmap_kremove(sf->kva);
+ sf->m = NULL;
+ LIST_REMOVE(sf, list_entry);
if (sf_buf_alloc_want > 0)
wakeup_one(&sf_buf_freelist);
}
@@ -502,9 +505,12 @@ arm_unmap_nocache(void *addr, vm_size_t size)
size = round_page(size);
i = (raddr - arm_nocache_startaddr) / (PAGE_SIZE);
- for (; size > 0; size -= PAGE_SIZE, i++)
+ for (; size > 0; size -= PAGE_SIZE, i++) {
arm_nocache_allocated[i / BITS_PER_INT] &= ~(1 << (i %
BITS_PER_INT));
+ pmap_kremove(raddr);
+ raddr += PAGE_SIZE;
+ }
}
#ifdef ARM_USE_SMALL_ALLOC
diff --git a/sys/arm/conf/BWCT.hints b/sys/arm/conf/BWCT.hints
index 105409d..0a520c3 100644
--- a/sys/arm/conf/BWCT.hints
+++ b/sys/arm/conf/BWCT.hints
@@ -4,6 +4,6 @@
hint.ds1672_rtc.0.at="iicbus0"
hint.ds1672_rtc.0.addr=0xd0
-# NAtional Semiconductor LM75 temperature sensor sitting on the I2C bus
+# National Semiconductor LM75 temperature sensor sitting on the I2C bus
hint.lm75.0.at="iicbus0"
hint.lm75.0.addr=0x9e
diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX
index 939ae2b..b82f118 100644
--- a/sys/arm/conf/DB-78XXX
+++ b/sys/arm/conf/DB-78XXX
@@ -67,6 +67,7 @@ device e1000phy
device bpf
# USB
+options USB_DEBUG # enable debug msgs
device usb
device ehci
device umass
diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX
index 41f32b1..edb5fe8 100644
--- a/sys/arm/conf/DB-88F5XXX
+++ b/sys/arm/conf/DB-88F5XXX
@@ -74,6 +74,7 @@ device iicbus
device ds133x
# USB
+options USB_DEBUG # enable debug msgs
device usb
device ehci
device umass
diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX
index c0857fd..1b4b7fd 100644
--- a/sys/arm/conf/DB-88F6XXX
+++ b/sys/arm/conf/DB-88F6XXX
@@ -67,6 +67,7 @@ device e1000phy
device bpf
# USB
+options USB_DEBUG # enable debug msgs
device usb
device ehci
device umass
diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200
index f50f64c..dd46a61 100644
--- a/sys/arm/conf/HL200
+++ b/sys/arm/conf/HL200
@@ -95,6 +95,7 @@ device icee
device bpf
# USB support
+options USB_DEBUG # enable debug msgs
device ohci # OHCI localbus->USB interface
device usb # USB Bus (required)
#device udbp # USB Double Bulk Pipe devices
diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X
index 8d5274d..f47e9ac 100644
--- a/sys/arm/conf/KB920X
+++ b/sys/arm/conf/KB920X
@@ -24,7 +24,7 @@ include "../at91/std.kb920x"
# The AT91 platform doesn't use /boot/loader, so we have to statically wire
# hints.
hints "KB920X.hints"
-makeoptions MODULES_OVERRIDE=""
+#makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options DDB
@@ -96,6 +96,7 @@ device icee
device bpf
# USB support
+options USB_DEBUG # enable debug msgs
device ohci # OHCI localbus->USB interface
device usb # USB Bus (required)
#device udbp # USB Double Bulk Pipe devices
diff --git a/sys/arm/conf/LN2410SBC b/sys/arm/conf/LN2410SBC
new file mode 100644
index 0000000..e4f3a54
--- /dev/null
+++ b/sys/arm/conf/LN2410SBC
@@ -0,0 +1,88 @@
+# LN2410SBC -- Custom kernel configuration for the LN2410SBC
+#
+# For more information on this file, please read the handbook section on
+# Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+machine arm
+ident LN2410SBC
+
+include "../s3c2xx0/std.ln2410sbc"
+#To statically compile in device wiring instead of /boot/device.hints
+#hints "GENERIC.hints" #Default places to look for devices.
+makeoptions MODULES_OVERRIDE=""
+
+device board_ln2410sbc
+
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+options HZ=100
+options DDB
+options KDB
+
+options SCHED_4BSD #4BSD scheduler
+options INET #InterNETworking
+#options INET6 #IPv6 communications protocols
+options FFS #Berkeley Fast Filesystem
+#options SOFTUPDATES #Enable FFS soft updates support
+#options UFS_ACL #Support for access control lists
+#options UFS_DIRHASH #Improve performance on big directories
+#options MD_ROOT #MD is a potential root device
+#options MD_ROOT_SIZE=4096 # 4MB ram disk
+options ROOTDEVNAME=\"ufs:da0s1\"
+
+#options BOOTP
+#options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info
+#options NFSCLIENT #Network File System client
+#options NFS_ROOT #NFS usable as root device
+
+options PSEUDOFS #Pseudo-filesystem framework
+#options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI
+options KTRACE #ktrace(1) support
+options SYSVSHM #SYSV-style shared memory
+options SYSVMSG #SYSV-style message queues
+options SYSVSEM #SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+
+options MUTEX_NOINLINE
+options RWLOCK_NOINLINE
+options SX_NOINLINE
+
+options NO_FFS_SNAPSHOT
+options NO_SWAPPING
+device random
+device pty
+
+device loop
+device ether
+device bpf
+
+device uart
+
+# Debugging for use in -current
+options INVARIANTS #Enable calls of extra sanity checking
+options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS
+options WITNESS #Enable checks to detect deadlocks and cycles
+options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed
+
+device md
+
+options USB_DEBUG # enable debug msgs
+device usb
+device ohci
+device umass
+device scbus # SCSI bus (required for da)
+device da # Direct Access (disks)
+
diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG
index d11b34d..dcd82e5 100644
--- a/sys/arm/conf/SHEEVAPLUG
+++ b/sys/arm/conf/SHEEVAPLUG
@@ -61,6 +61,7 @@ options DEVICE_POLLING
device vlan
# USB
+options USB_DEBUG # enable debug msgs
device usb
device ehci
device umass
diff --git a/sys/arm/include/bus.h b/sys/arm/include/bus.h
index 4080c33..cabf1f7 100644
--- a/sys/arm/include/bus.h
+++ b/sys/arm/include/bus.h
@@ -721,6 +721,8 @@ bs_c_8_proto(f);
#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
#define BUS_SPACE_MAXSIZE 0xFFFFFFFF
+#define BUS_SPACE_UNRESTRICTED (~0)
+
#include <machine/bus_dma.h>
#endif /* _MACHINE_BUS_H_ */
diff --git a/sys/arm/include/proc.h b/sys/arm/include/proc.h
index c7b2a4e..37051bf 100644
--- a/sys/arm/include/proc.h
+++ b/sys/arm/include/proc.h
@@ -60,4 +60,6 @@ struct mdproc {
void *md_sigtramp;
};
+#define KINFO_PROC_SIZE 792
+
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/arm/mv/common.c b/sys/arm/mv/common.c
index d31e081..a142259 100644
--- a/sys/arm/mv/common.c
+++ b/sys/arm/mv/common.c
@@ -261,6 +261,8 @@ soc_identify(void)
rev = "Z0";
else if (r == 2)
rev = "A0";
+ else if (r == 3)
+ rev = "A1";
break;
case MV_DEV_MV78100_Z0:
dev = "Marvell MV78100 Z0";
diff --git a/sys/arm/mv/kirkwood/kirkwood.c b/sys/arm/mv/kirkwood/kirkwood.c
index 1be6d45..cc60afe2 100644
--- a/sys/arm/mv/kirkwood/kirkwood.c
+++ b/sys/arm/mv/kirkwood/kirkwood.c
@@ -176,11 +176,11 @@ get_tclk(void)
/*
* On Kirkwood TCLK is not configurable and depends on silicon
* revision:
- * - A0 has TCLK hardcoded to 200 MHz.
+ * - A0 and A1 have TCLK hardcoded to 200 MHz.
* - Z0 and others have TCLK hardcoded to 166 MHz.
*/
soc_id(&dev, &rev);
- if (dev == MV_DEV_88F6281 && rev == 2)
+ if (dev == MV_DEV_88F6281 && (rev == 2 || rev == 3))
return (TCLK_200MHZ);
return (TCLK_166MHZ);
diff --git a/sys/arm/mv/mv_sata.c b/sys/arm/mv/mv_sata.c
index 01713da..a607298 100644
--- a/sys/arm/mv/mv_sata.c
+++ b/sys/arm/mv/mv_sata.c
@@ -600,7 +600,12 @@ sata_channel_begin_transaction(struct ata_request *request)
crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8;
crqb->crqb_ata_lba_high = request->u.ata.lba >> 16;
crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6);
+ crqb->crqb_ata_lba_low_p = request->u.ata.lba >> 24;
+ crqb->crqb_ata_lba_mid_p = request->u.ata.lba >> 32;
+ crqb->crqb_ata_lba_high_p = request->u.ata.lba >> 40;
+ crqb->crqb_ata_feature_p = request->u.ata.feature >> 8;
crqb->crqb_ata_count = request->u.ata.count;
+ crqb->crqb_ata_count_p = request->u.ata.count >> 8;
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
diff --git a/sys/ia64/include/nexusvar.h b/sys/arm/s3c2xx0/board_ln2410sbc.c
index be38f33..5f5ac90 100644
--- a/sys/ia64/include/nexusvar.h
+++ b/sys/arm/s3c2xx0/board_ln2410sbc.c
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org>
+/*
+ * Copyright (C) 2009 Andrew Turner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,21 +23,23 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
*/
-#ifndef _MACHINE_NEXUSVAR_H_
-#define _MACHINE_NEXUSVAR_H_ 1
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/systm.h>
-enum nexus_device_ivars {
- NEXUS_IVAR_PCIBUS
-};
+#include <arm/s3c2xx0/s3c2410reg.h>
+#include <arm/s3c2xx0/s3c2xx0board.h>
-#define NEXUS_ACCESSOR(var, ivar, type) \
- __BUS_ACCESSOR(nexus, var, NEXUS, ivar, type)
+extern vm_offset_t s3c2410_uart_vaddr;
-NEXUS_ACCESSOR(pcibus, PCIBUS, u_int32_t)
+long
+board_init(void)
+{
+ s3c2410_uart_vaddr = S3C24X0_UART_BASE(0);
-#undef NEXUS_ACCESSOR
+ return (64 * 1024 * 1024);
+}
-#endif /* !_MACHINE_NEXUSVAR_H_ */
diff --git a/sys/arm/s3c2xx0/files.s3c2xx0 b/sys/arm/s3c2xx0/files.s3c2xx0
new file mode 100644
index 0000000..113f9dd
--- /dev/null
+++ b/sys/arm/s3c2xx0/files.s3c2xx0
@@ -0,0 +1,13 @@
+# $FreeBSD$
+arm/arm/cpufunc_asm_arm9.S standard
+arm/arm/irq_dispatch.S standard
+arm/s3c2xx0/board_ln2410sbc.c optional board_ln2410sbc
+arm/s3c2xx0/s3c24x0_machdep.c standard
+arm/s3c2xx0/s3c24x0.c standard
+arm/s3c2xx0/s3c2xx0_space.c standard
+arm/s3c2xx0/s3c24x0_clk.c standard
+arm/s3c2xx0/uart_bus_s3c2410.c optional uart
+arm/s3c2xx0/uart_cpu_s3c2410.c optional uart
+arm/s3c2xx0/uart_dev_s3c2410.c optional uart
+
+dev/usb/controller/ohci_s3c24x0.c optional ohci
diff --git a/sys/arm/s3c2xx0/s3c2410reg.h b/sys/arm/s3c2xx0/s3c2410reg.h
new file mode 100644
index 0000000..31bb857
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c2410reg.h
@@ -0,0 +1,96 @@
+/* $NetBSD: s3c2410reg.h,v 1.6 2004/02/12 03:52:46 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2004 Genetec corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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$
+ */
+
+
+/*
+ * Samsung S3C2410X processor is ARM920T based integrated CPU
+ *
+ * Reference:
+ * S3C2410X User's Manual
+ */
+#ifndef _ARM_S3C2XX0_S3C2410REG_H_
+#define _ARM_S3C2XX0_S3C2410REG_H_
+
+/* common definitions for S3C2410 and S3C2440 */
+#include <arm/s3c2xx0/s3c24x0reg.h>
+
+/*
+ * Memory Map
+ */
+#define S3C2410_BANK_SIZE 0x08000000
+#define S3C2410_BANK_START(n) (S3C2410_BANK_SIZE*(n))
+#define S3C2410_SDRAM_START S3C2410_BANK_START(6)
+
+
+/* interrupt control */
+#define S3C2410_SUBIRQ_MAX (S3C24X0_SUBIRQ_MIN+10)
+
+/* Clock control */
+/* CLKMAN_CLKCON */
+#define S3C2410_CLKCON_SM (1<<0) /* 1=transition to SPECIAL mode */
+/* CLKMAN_CLKDIVN */
+#define S3C2410_CLKDIVN_HDIVN (1<<1) /* hclk=fclk/2 */
+
+/* NAND Flash controller */
+#define S3C2410_NANDFC_SIZE 0x18
+/* NANDFC_NFCONF */
+#define S3C2410_NFCONF_ENABLE (1<<15) /* NAND controller enabled */
+#define S3C2410_NFCONF_ECC (1<<12) /* Initialize ECC decoder/encoder */
+#define S3C2410_NFCONF_FCE (1<<11) /* Flash chip enabled */
+#define S3C2410_NFCONF_TACLS (7<<8) /* CLE and ALE duration */
+#define S3C2410_NFCONF_TWRPH0 (7<<4) /* TWRPH0 duration */
+#define S3C2410_NFCONF_TWRPH1 (7<<0) /* TWRPH1 duration */
+#define S3C2410_NANDFC_NFCMD 0x04 /* command */
+#define S3C2410_NANDFC_NFADDR 0x08 /* address */
+#define S3C2410_NANDFC_NFDATA 0x0c /* data */
+#define S3C2410_NANDFC_NFSTAT 0x10 /* operation status */
+#define S3C2410_NANDFC_NFECC 0x14 /* ecc */
+
+/* MMC/SD */
+/* SDI_CON */
+#define S3C2410_CON_FIFO_RESET (1<<1)
+
+/* GPIO */
+#define S3C2410_GPIO_SIZE 0xb4
+
+/* SD interface */
+#define S3C2410_SDI_SIZE 0x44
+#define DCON_STOP (1<<14) /* Force the transfer to stop */
+#define S3C2410_SDI_DAT 0x3c
+#define S3C2410_SDI_IMSK 0x40 /* Interrupt mask */
+#define S3C2410_SDI_IMASK_ALL 0x3ffdf
+
+/* ADC */
+#define S3C2410_ADC_SIZE 0x14
+
+#endif /* _ARM_S3C2XX0_S3C2410REG_H_ */
diff --git a/sys/arm/s3c2xx0/s3c2410var.h b/sys/arm/s3c2xx0/s3c2410var.h
new file mode 100644
index 0000000..b17784d
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c2410var.h
@@ -0,0 +1,49 @@
+/* $NetBSD: s3c2410var.h,v 1.2 2003/08/29 12:57:50 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003 Genetec corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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 _ARM_S3C2410VAR_H_
+#define _ARM_S3C2410VAR_H_
+
+#include <arm/s3c2xx0/s3c24x0var.h>
+
+int s3c2410_sscom_cnattach(bus_space_tag_t, int, int, int, tcflag_t);
+int s3c2410_sscom_kgdb_attach(bus_space_tag_t, int, int, int, tcflag_t);
+void s3c2410_intr_init(struct s3c24x0_softc *);
+void s3c2410_softreset(void);
+
+void s3c2410_mask_subinterrupts(int);
+void s3c2410_unmask_subinterrupts(int);
+
+void *s3c2410_extint_establish(int, int, int, int (*)(void *), void *);
+void s3c2410_setup_extint(int, int);
+#endif /* _ARM_S3C2410VAR_H_ */
diff --git a/sys/arm/s3c2xx0/s3c2440reg.h b/sys/arm/s3c2xx0/s3c2440reg.h
new file mode 100644
index 0000000..418557d
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c2440reg.h
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (C) 2009 Andrew Turner
+ * 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$
+ */
+
+/*
+ * Samsung S3C2440X processor is ARM920T based integrated CPU
+ *
+ * Reference:
+ * S3C2440A/S3C2442B User's Manual
+ */
+#ifndef _ARM_S3C2XX0_S3C2440REG_H_
+#define _ARM_S3C2XX0_S3C2440REG_H_
+
+/* common definitions for S3C2410 and S3C2440 */
+#include <arm/s3c2xx0/s3c24x0reg.h>
+
+/*
+ * Memory Map
+ */
+#define S3C2440_BANK_SIZE 0x08000000
+#define S3C2440_BANK_START(n) (S3C2410_BANK_SIZE*(n))
+#define S3C2440_SDRAM_START S3C2410_BANK_START(6)
+
+
+/* interrupt control */
+#define S3C2440_SUBIRQ_MAX (S3C24X0_SUBIRQ_MIN+10)
+
+/* Clock control */
+/* CLKMAN_CLKCON */
+#define S3C2440_CLKCON_STOP (1<<0) /* 1=transition to STOP mode */
+/* CLKMAN_CLKDIVN */
+#define S3C2440_CLKDIVN_HDIVN (3<<1) /* hclk */
+#define S3C2440_CLKMAN_CAMDIVN 0x18
+#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
+#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
+
+/* NAND Flash controller */
+#define S3C2440_NANDFC_SIZE 0x40
+
+#define S3C2440_NANDFC_NFCONT 0x04
+#define S3C2440_NFCONT_LOCK_TIGHT (1<<13) /* Lock part of the NAND */
+#define S3C2440_NFCONT_SOFT_LOCK (1<<12) /* Soft lock part of the NAND */
+#define S3C2440_NFCONT_ILLEGAL_ACC_INT (1<<10) /* Illegal access interrupt */
+#define S3C2440_NFCONT_RNB_INT (1<<9) /* RnB transition interrupt */
+#define S3C2440_NFCONT_RNB_TRANS_MODE (1<<8) /* RnB transition mode */
+#define S3C2440_NFCONT_SPARE_ECC_LOCK (1<<6) /* Lock spare ECC generation */
+#define S3C2440_NFCONT_MAIN_ECC_LOCK (1<<5) /* Lock main ECC generation */
+#define S3C2440_NFCONT_INIT_ECC (1<<4) /* Init ECC encoder/decoder */
+#define S3C2440_NFCONT_NCE (1<<1) /* NAND Chip select */
+#define S3C2440_NFCONT_ENABLE (1<<0) /* Enable the controller */
+#define S3C2440_NANDFC_NFCMMD 0x08
+#define S3C2440_NANDFC_NFADDR 0x0c
+#define S3C2440_NANDFC_NFDATA 0x10
+#define S3C2440_NANDFC_NFSTAT 0x20
+
+/* MMC/SD */
+/* SDI_CON */
+#define S3C2440_CON_RESET (1<<8)
+#define S3C2440_CON_CLOCK_TYPE (1<<5)
+/* SDI_FSTA */
+#define S3c2440_FSTA_RESET (1<<16)
+#define S3C2440_FSTA_FAIL_ERROR_MSK (3<<14)
+#define S3C2440_FSTA_FAIL_NONE (0<<14)
+#define S3C2440_FSTA_FAIL_FIFO (1<<14)
+#define S3C2440_FSTA_FAIL_LAST_TRANS (2<<14)
+
+/* GPIO */
+#define S3C2440_GPIO_SIZE 0xd0
+
+/* SD interface */
+#define S3C2410_SDI_SIZE 0x44
+#define DCON_START (1<<14) /* Start the data transfer */
+#define S3C2440_SDI_IMSK 0x3c /* Interrupt mask */
+#define S3C2440_SDI_IMASK_ALL 0x3C7C0
+#define S3C2440_SDI_DAT 0x40
+
+/* ADC */
+#define ADCTSC_UD_SEN (1<<8)
+#define S3C2440_ADC_SIZE 0x18
+
+/* UART */
+#define S3C2440_UFSTAT_TXCOUNT (0x3f << 8)
+#define S3C2440_UFSTAT_RXCOUNT (0x3f << 0)
+
+#endif /* _ARM_S3C2XX0_S3C2440REG_H_ */
diff --git a/sys/arm/s3c2xx0/s3c24x0.c b/sys/arm/s3c2xx0/s3c24x0.c
new file mode 100644
index 0000000..b0e338a
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c24x0.c
@@ -0,0 +1,648 @@
+/* $NetBSD: s3c2410.c,v 1.4 2003/08/27 03:46:05 bsh Exp $ */
+
+/*
+ * Copyright (c) 2003 Genetec corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/reboot.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/cpu.h>
+#include <machine/bus.h>
+
+#include <machine/cpufunc.h>
+#include <machine/intr.h>
+#include <arm/s3c2xx0/s3c2410reg.h>
+#include <arm/s3c2xx0/s3c2440reg.h>
+#include <arm/s3c2xx0/s3c24x0var.h>
+#include <sys/rman.h>
+
+#define S3C2XX0_XTAL_CLK 12000000
+
+#define IPL_LEVELS 13
+u_int irqmasks[IPL_LEVELS];
+
+static struct {
+ uint32_t idcode;
+ const char *name;
+ s3c2xx0_cpu cpu;
+} s3c2x0_cpu_id[] = {
+ { CHIPID_S3C2410A, "S3C2410A", CPU_S3C2410 },
+ { CHIPID_S3C2440A, "S3C2440A", CPU_S3C2440 },
+ { CHIPID_S3C2442B, "S3C2442B", CPU_S3C2440 },
+
+ { 0, NULL }
+};
+
+static struct {
+ const char *name;
+ int prio;
+ int unit;
+ struct {
+ int type;
+ u_long start;
+ u_long count;
+ } res[2];
+} s3c24x0_children[] = {
+ { "timer", 0, -1, { { 0 }, } },
+ { "uart", 1, 0, {
+ { SYS_RES_IRQ, S3C24X0_INT_UART0, 1 },
+ { SYS_RES_IOPORT, S3C24X0_UART_BASE(0),
+ S3C24X0_UART_BASE(1) - S3C24X0_UART_BASE(0) },
+ } },
+ { "uart", 1, 1, {
+ { SYS_RES_IRQ, S3C24X0_INT_UART1, 1 },
+ { SYS_RES_IOPORT, S3C24X0_UART_BASE(1),
+ S3C24X0_UART_BASE(2) - S3C24X0_UART_BASE(1) },
+ } },
+ { "uart", 1, 2, {
+ { SYS_RES_IRQ, S3C24X0_INT_UART2, 1 },
+ { SYS_RES_IOPORT, S3C24X0_UART_BASE(2),
+ S3C24X0_UART_BASE(3) - S3C24X0_UART_BASE(2) },
+ } },
+ { "ohci", 0, -1, {
+ { SYS_RES_IRQ, S3C24X0_INT_USBH, 0 },
+ { SYS_RES_IOPORT, S3C24X0_USBHC_BASE, S3C24X0_USBHC_SIZE },
+ } },
+ { NULL },
+};
+
+
+/* prototypes */
+static device_t s3c24x0_add_child(device_t, int, const char *, int);
+
+static int s3c24x0_probe(device_t);
+static int s3c24x0_attach(device_t);
+static void s3c24x0_identify(driver_t *, device_t);
+static int s3c24x0_setup_intr(device_t, device_t, struct resource *, int,
+ driver_filter_t *, driver_intr_t *, void *, void **);
+static int s3c24x0_teardown_intr(device_t, device_t, struct resource *,
+ void *);
+static struct resource *s3c24x0_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int s3c24x0_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int s3c24x0_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static struct resource_list *s3c24x0_get_resource_list(device_t, device_t);
+
+static void s3c24x0_identify_cpu(device_t);
+
+static device_method_t s3c24x0_methods[] = {
+ DEVMETHOD(device_probe, s3c24x0_probe),
+ DEVMETHOD(device_attach, s3c24x0_attach),
+ DEVMETHOD(device_identify, s3c24x0_identify),
+ DEVMETHOD(bus_setup_intr, s3c24x0_setup_intr),
+ DEVMETHOD(bus_teardown_intr, s3c24x0_teardown_intr),
+ DEVMETHOD(bus_alloc_resource, s3c24x0_alloc_resource),
+ DEVMETHOD(bus_activate_resource, s3c24x0_activate_resource),
+ DEVMETHOD(bus_release_resource, s3c24x0_release_resource),
+ DEVMETHOD(bus_get_resource_list,s3c24x0_get_resource_list),
+ DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
+ {0, 0},
+};
+
+static driver_t s3c24x0_driver = {
+ "s3c24x0",
+ s3c24x0_methods,
+ sizeof(struct s3c24x0_softc),
+};
+static devclass_t s3c24x0_devclass;
+
+DRIVER_MODULE(s3c24x0, nexus, s3c24x0_driver, s3c24x0_devclass, 0, 0);
+
+struct s3c2xx0_softc *s3c2xx0_softc = NULL;
+
+static device_t
+s3c24x0_add_child(device_t bus, int prio, const char *name, int unit)
+{
+ device_t child;
+ struct s3c2xx0_ivar *ivar;
+
+ child = device_add_child_ordered(bus, prio, name, unit);
+ if (child == NULL)
+ return (NULL);
+
+ ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (ivar == NULL) {
+ device_delete_child(bus, child);
+ printf("Can't add alloc ivar\n");
+ return (NULL);
+ }
+ device_set_ivars(child, ivar);
+ resource_list_init(&ivar->resources);
+
+ return (child);
+}
+
+static int
+s3c24x0_setup_intr(device_t dev, device_t child,
+ struct resource *ires, int flags, driver_filter_t *filt,
+ driver_intr_t *intr, void *arg, void **cookiep)
+{
+ int error, irq;
+
+ error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
+ intr, arg, cookiep);
+ if (error != 0)
+ return (error);
+
+ for (irq = rman_get_start(ires); irq <= rman_get_end(ires); irq++) {
+ arm_unmask_irq(irq);
+ }
+ return (0);
+}
+
+static int
+s3c24x0_teardown_intr(device_t dev, device_t child, struct resource *res,
+ void *cookie)
+{
+ return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static struct resource *
+s3c24x0_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource_list_entry *rle;
+ struct s3c2xx0_ivar *ivar = device_get_ivars(child);
+ struct resource_list *rl = &ivar->resources;
+ struct resource *res = NULL;
+
+ if (device_get_parent(child) != bus)
+ return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
+ type, rid, start, end, count, flags));
+
+ rle = resource_list_find(rl, type, *rid);
+ if (rle != NULL) {
+ /* There is a resource list. Use it */
+ if (rle->res)
+ panic("Resource rid %d type %d already in use", *rid,
+ type);
+ if (start == 0UL && end == ~0UL) {
+ start = rle->start;
+ count = ulmax(count, rle->count);
+ end = ulmax(rle->end, start + count - 1);
+ }
+ /*
+ * When allocating an irq with children irq's really
+ * allocate the children as it is those we are interested
+ * in receiving, not the parent.
+ */
+ if (type == SYS_RES_IRQ && start == end) {
+ switch (start) {
+ case S3C24X0_INT_ADCTC:
+ start = S3C24X0_INT_TC;
+ end = S3C24X0_INT_ADC;
+ break;
+#ifdef S3C2440_INT_CAM
+ case S3C2440_INT_CAM:
+ start = S3C2440_INT_CAM_C;
+ end = S3C2440_INT_CAM_P;
+ break;
+#endif
+ default:
+ break;
+ }
+ count = end - start + 1;
+ }
+ }
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ res = rman_reserve_resource(
+ &s3c2xx0_softc->s3c2xx0_irq_rman, start, end,
+ count, flags, child);
+ break;
+
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ res = rman_reserve_resource(
+ &s3c2xx0_softc->s3c2xx0_mem_rman,
+ start, end, count, flags, child);
+ rman_set_bustag(res, &s3c2xx0_bs_tag);
+ rman_set_bushandle(res, start);
+ break;
+ }
+
+ if (res != NULL) {
+ rman_set_rid(res, *rid);
+ if (rle != NULL) {
+ rle->res = res;
+ rle->start = rman_get_start(res);
+ rle->end = rman_get_end(res);
+ rle->count = count;
+ }
+ }
+
+ return (res);
+}
+
+static int
+s3c24x0_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+static int
+s3c24x0_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct s3c2xx0_ivar *ivar = device_get_ivars(child);
+ struct resource_list *rl = &ivar->resources;
+ struct resource_list_entry *rle;
+
+ if (rl == NULL)
+ return (EINVAL);
+
+ rle = resource_list_find(rl, type, rid);
+ if (rle == NULL)
+ return (EINVAL);
+
+ rman_release_resource(r);
+ rle->res = NULL;
+
+ return 0;
+}
+
+static struct resource_list *
+s3c24x0_get_resource_list(device_t dev, device_t child)
+{
+ struct s3c2xx0_ivar *ivar;
+
+ ivar = device_get_ivars(child);
+ return (&(ivar->resources));
+}
+
+void
+s3c24x0_identify(driver_t *driver, device_t parent)
+{
+
+ BUS_ADD_CHILD(parent, 0, "s3c24x0", 0);
+}
+
+int
+s3c24x0_probe(device_t dev)
+{
+ return 0;
+}
+
+int
+s3c24x0_attach(device_t dev)
+{
+ struct s3c24x0_softc *sc = device_get_softc(dev);
+ bus_space_tag_t iot;
+ device_t child;
+ unsigned int i, j;
+
+ s3c2xx0_softc = &(sc->sc_sx);
+ sc->sc_sx.sc_iot = iot = &s3c2xx0_bs_tag;
+
+ if (bus_space_map(iot,
+ S3C24X0_INTCTL_PA_BASE, S3C24X0_INTCTL_SIZE,
+ BUS_SPACE_MAP_LINEAR, &sc->sc_sx.sc_intctl_ioh))
+ panic("Cannot map the interrupt controller");
+
+ /* Map the GPIO registers */
+ if (bus_space_map(iot, S3C24X0_GPIO_PA_BASE, S3C2410_GPIO_SIZE,
+ 0, &sc->sc_sx.sc_gpio_ioh))
+ panic("Cannot map the GPIO");
+ /* Clock manager */
+ if (bus_space_map(iot, S3C24X0_CLKMAN_PA_BASE,
+ S3C24X0_CLKMAN_SIZE, 0, &sc->sc_sx.sc_clkman_ioh))
+ panic("cannot map the clock");
+
+ if (bus_space_map(iot, S3C24X0_TIMER_PA_BASE,
+ S3C24X0_TIMER_SIZE, 0, &sc->sc_timer_ioh))
+ panic("cannot map the TIMER");
+
+ if (bus_space_map(iot, S3C24X0_USBHC_PA_BASE,
+ S3C24X0_USBHC_SIZE, 0, &sc->sc_sx.sc_ohci_ioh))
+ panic("cannot map the USB Host");
+
+ if (bus_space_map(iot, S3C24X0_WDT_PA_BASE,
+ S3C24X0_WDT_SIZE, 0, &sc->sc_sx.sc_wdt_ioh))
+ panic("cannot map the watchdog timer");
+
+ /*
+ * Identify the CPU
+ */
+ s3c24x0_identify_cpu(dev);
+
+ /* calculate current clock frequency */
+ s3c24x0_clock_freq(&sc->sc_sx);
+ device_printf(dev, "fclk %d MHz hclk %d MHz pclk %d MHz\n",
+ sc->sc_sx.sc_fclk / 1000000, sc->sc_sx.sc_hclk / 1000000,
+ sc->sc_sx.sc_pclk / 1000000);
+
+ /*
+ * Attach children devices
+ */
+ s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY;
+ s3c2xx0_softc->s3c2xx0_irq_rman.rm_descr = "S3C24X0 IRQs";
+ s3c2xx0_softc->s3c2xx0_mem_rman.rm_type = RMAN_ARRAY;
+ s3c2xx0_softc->s3c2xx0_mem_rman.rm_descr = "S3C24X0 Memory";
+ if (rman_init(&s3c2xx0_softc->s3c2xx0_irq_rman) != 0 ||
+ rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman, 0,
+ S3C2410_SUBIRQ_MAX) != 0)
+ panic("s3c24x0_attach: failed to set up IRQ rman");
+ /* Manage the registor memory space */
+ if ((rman_init(&s3c2xx0_softc->s3c2xx0_mem_rman) != 0) ||
+ (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+ S3C24X0_DEV_VA_OFFSET,
+ S3C24X0_DEV_VA_OFFSET + S3C24X0_DEV_VA_SIZE) != 0))
+ panic("s3c24x0_attach: failed to set up register rman");
+
+ for (i = 0; s3c24x0_children[i].name != NULL; i++) {
+ child = s3c24x0_add_child(dev, s3c24x0_children[i].prio,
+ s3c24x0_children[i].name, s3c24x0_children[i].unit);
+ for (j = 0; j < sizeof(s3c24x0_children[i].res) /
+ sizeof(s3c24x0_children[i].res[0]) &&
+ s3c24x0_children[i].res[j].type != 0; j++) {
+ bus_set_resource(child,
+ s3c24x0_children[i].res[j].type, 0,
+ s3c24x0_children[i].res[j].start,
+ s3c24x0_children[i].res[j].count);
+ }
+ }
+
+ bus_generic_probe(dev);
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static void
+s3c24x0_identify_cpu(device_t dev)
+{
+ struct s3c24x0_softc *sc = device_get_softc(dev);
+ uint32_t idcode;
+ int i;
+
+ idcode = bus_space_read_4(sc->sc_sx.sc_iot, sc->sc_sx.sc_gpio_ioh,
+ GPIO_GSTATUS1);
+
+ for (i = 0; s3c2x0_cpu_id[i].name != NULL; i++) {
+ if (s3c2x0_cpu_id[i].idcode == idcode)
+ break;
+ }
+ if (s3c2x0_cpu_id[i].name == NULL)
+ panic("Unknown CPU detected ((Chip ID: %#X)", idcode);
+ device_printf(dev, "Found %s CPU (Chip ID: %#X)\n",
+ s3c2x0_cpu_id[i].name, idcode);
+ sc->sc_sx.sc_cpu = s3c2x0_cpu_id[i].cpu;
+}
+
+/*
+ * fill sc_pclk, sc_hclk, sc_fclk from values of clock controller register.
+ *
+ * s3c24{1,4}0_clock_freq2() is meant to be called from kernel startup routines.
+ * s3c24x0_clock_freq() is for after kernel initialization is done.
+ *
+ * Because they can be called before bus_space is available we need to use
+ * volatile pointers rather than bus_space_read.
+ */
+void
+s3c2410_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk)
+{
+ uint32_t pllcon, divn;
+ unsigned int mdiv, pdiv, sdiv;
+ unsigned int f, h, p;
+
+ pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON);
+ divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN);
+
+ mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
+ pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
+ sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
+
+ f = ((mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv));
+ h = f;
+ if (divn & S3C2410_CLKDIVN_HDIVN)
+ h /= 2;
+ p = h;
+ if (divn & CLKDIVN_PDIVN)
+ p /= 2;
+
+ if (fclk) *fclk = f;
+ if (hclk) *hclk = h;
+ if (pclk) *pclk = p;
+}
+
+void
+s3c2440_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk)
+{
+ uint32_t pllcon, divn, camdivn;
+ unsigned int mdiv, pdiv, sdiv;
+ unsigned int f, h, p;
+
+ pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON);
+ divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN);
+ camdivn = *(volatile uint32_t *)(clkman_base + S3C2440_CLKMAN_CAMDIVN);
+
+ mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
+ pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
+ sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
+
+ f = (2 * (mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv));
+ h = f;
+ switch((divn >> 1) & 3) {
+ case 0:
+ break;
+ case 1:
+ h /= 2;
+ break;
+ case 2:
+ if ((camdivn & S3C2440_CAMDIVN_HCLK4_HALF) ==
+ S3C2440_CAMDIVN_HCLK4_HALF)
+ h /= 8;
+ else
+ h /= 4;
+ break;
+ case 3:
+ if ((camdivn & S3C2440_CAMDIVN_HCLK3_HALF) ==
+ S3C2440_CAMDIVN_HCLK3_HALF)
+ h /= 6;
+ else
+ h /= 3;
+ break;
+ }
+ p = h;
+ if (divn & CLKDIVN_PDIVN)
+ p /= 2;
+
+ if (fclk) *fclk = f;
+ if (hclk) *hclk = h;
+ if (pclk) *pclk = p;
+}
+
+void
+s3c24x0_clock_freq(struct s3c2xx0_softc *sc)
+{
+ vm_offset_t va;
+
+ va = sc->sc_clkman_ioh;
+ switch(sc->sc_cpu) {
+ case CPU_S3C2410:
+ s3c2410_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk,
+ &sc->sc_pclk);
+ break;
+ case CPU_S3C2440:
+ s3c2440_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk,
+ &sc->sc_pclk);
+ break;
+ }
+}
+
+void
+cpu_reset(void)
+{
+ (void) disable_interrupts(I32_bit|F32_bit);
+
+ bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_wdt_ioh, WDT_WTCON,
+ WTCON_ENABLE | WTCON_CLKSEL_16 | WTCON_ENRST);
+ for(;;);
+}
+
+void
+s3c24x0_sleep(int mode __unused)
+{
+ int reg;
+
+ reg = bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_clkman_ioh,
+ CLKMAN_CLKCON);
+ bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_clkman_ioh,
+ CLKMAN_CLKCON, reg | CLKCON_IDLE);
+}
+
+
+int
+arm_get_next_irq(int last __unused)
+{
+ uint32_t intpnd;
+ int irq, subirq;
+
+ if ((irq = bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTOFFSET)) != 0) {
+
+ /* Clear the pending bit */
+ intpnd = bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTPND);
+ bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh,
+ INTCTL_SRCPND, intpnd);
+ bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh,
+ INTCTL_INTPND, intpnd);
+
+ switch (irq) {
+ case S3C24X0_INT_ADCTC:
+ case S3C24X0_INT_UART0:
+ case S3C24X0_INT_UART1:
+ case S3C24X0_INT_UART2:
+ /* Find the sub IRQ */
+ subirq = 0x7ff;
+ subirq &= bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_SUBSRCPND);
+ subirq &= ~(bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK));
+ if (subirq == 0)
+ return (irq);
+
+ subirq = ffs(subirq) - 1;
+
+ /* Clear the sub irq pending bit */
+ bus_space_write_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_SUBSRCPND,
+ (1 << subirq));
+
+ /*
+ * Return the parent IRQ for UART
+ * as it is all we ever need
+ */
+ if (subirq <= 8)
+ return (irq);
+
+ return (S3C24X0_SUBIRQ_MIN + subirq);
+ }
+
+ return (irq);
+ }
+ return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t irq)
+{
+ u_int32_t mask;
+
+ if (irq < S3C24X0_SUBIRQ_MIN) {
+ mask = bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK);
+ mask |= (1 << irq);
+ bus_space_write_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK, mask);
+ } else {
+ mask = bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK);
+ mask |= (1 << (irq - S3C24X0_SUBIRQ_MIN));
+ bus_space_write_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK, mask);
+ }
+}
+
+void
+arm_unmask_irq(uintptr_t irq)
+{
+ u_int32_t mask;
+
+ if (irq < S3C24X0_SUBIRQ_MIN) {
+ mask = bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK);
+ mask &= ~(1 << irq);
+ bus_space_write_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK, mask);
+ } else {
+ mask = bus_space_read_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK);
+ mask &= ~(1 << (irq - S3C24X0_SUBIRQ_MIN));
+ bus_space_write_4(&s3c2xx0_bs_tag,
+ s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK, mask);
+ }
+}
diff --git a/sys/arm/s3c2xx0/s3c24x0_clk.c b/sys/arm/s3c2xx0/s3c24x0_clk.c
new file mode 100644
index 0000000..33b7ae2
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c24x0_clk.c
@@ -0,0 +1,287 @@
+/* $NetBSD: s3c24x0_clk.c,v 1.6 2005/12/24 20:06:52 perry Exp $ */
+
+/*
+ * Copyright (c) 2003 Genetec corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/s3c2xx0/s3c24x0reg.h>
+#include <arm/s3c2xx0/s3c24x0var.h>
+
+struct s3c24x0_timer_softc {
+ device_t dev;
+} timer_softc;
+
+static unsigned s3c24x0_timer_get_timecount(struct timecounter *tc);
+
+static struct timecounter s3c24x0_timer_timecounter = {
+ s3c24x0_timer_get_timecount, /* get_timecount */
+ NULL, /* no poll_pps */
+ ~0u, /* counter_mask */
+ 3686400, /* frequency */
+ "s3c24x0 timer", /* name */
+ 1000 /* quality */
+};
+
+static int
+s3c24x0_timer_probe(device_t dev)
+{
+
+ device_set_desc(dev, "s3c24x0 timer");
+ return (0);
+}
+
+static int
+s3c24x0_timer_attach(device_t dev)
+{
+ timer_softc.dev = dev;
+
+ /* We need to do this here for devices that expect DELAY to work */
+ return (0);
+}
+
+static device_method_t s3c24x0_timer_methods[] = {
+ DEVMETHOD(device_probe, s3c24x0_timer_probe),
+ DEVMETHOD(device_attach, s3c24x0_timer_attach),
+ {0, 0},
+};
+
+static driver_t s3c24x0_timer_driver = {
+ "timer",
+ s3c24x0_timer_methods,
+ sizeof(struct s3c24x0_timer_softc),
+};
+static devclass_t s3c24x0_timer_devclass;
+
+DRIVER_MODULE(s3c24x0timer, s3c24x0, s3c24x0_timer_driver,
+ s3c24x0_timer_devclass, 0, 0);
+
+#define TIMER_FREQUENCY(pclk) ((pclk)/16) /* divider=1/16 */
+
+static unsigned int timer4_reload_value;
+static unsigned int timer4_prescaler;
+static unsigned int timer4_mseccount;
+static volatile uint32_t s3c24x0_base;
+
+#define usec_to_counter(t) \
+ ((timer4_mseccount*(t))/1000)
+
+#define counter_to_usec(c,pclk) \
+ (((c)*timer4_prescaler*1000)/(TIMER_FREQUENCY(pclk)/1000))
+
+static inline int
+read_timer(struct s3c24x0_softc *sc)
+{
+ int count;
+
+ do {
+ count = bus_space_read_2(sc->sc_sx.sc_iot, sc->sc_timer_ioh,
+ TIMER_TCNTO(4));
+ } while ( __predict_false(count > timer4_reload_value) );
+
+ return count;
+}
+
+static unsigned
+s3c24x0_timer_get_timecount(struct timecounter *tc)
+{
+ struct s3c24x0_softc *sc = (struct s3c24x0_softc *)s3c2xx0_softc;
+ int value;
+
+ value = bus_space_read_2(sc->sc_sx.sc_iot, sc->sc_timer_ioh,
+ TIMER_TCNTO(4));
+ return (s3c24x0_base - value);
+}
+
+static int
+clock_intr(void *arg)
+{
+ struct trapframe *fp = arg;
+
+ atomic_add_32(&s3c24x0_base, timer4_reload_value);
+
+ hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
+ return (FILTER_HANDLED);
+}
+
+void
+cpu_initclocks(void)
+{
+ struct s3c24x0_softc *sc = (struct s3c24x0_softc *)s3c2xx0_softc;
+ long tc;
+ struct resource *irq;
+ int rid = 0;
+ void *ihl;
+ int err, prescaler;
+ int pclk = s3c2xx0_softc->sc_pclk;
+ bus_space_tag_t iot = sc->sc_sx.sc_iot;
+ bus_space_handle_t ioh = sc->sc_timer_ioh;
+ uint32_t reg;
+ device_t dev = timer_softc.dev;
+
+ /* We have already been initialized */
+ if (timer4_reload_value != 0)
+ return;
+
+#define time_constant(hz) (TIMER_FREQUENCY(pclk) /(hz)/ prescaler)
+#define calc_time_constant(hz) \
+ do { \
+ prescaler = 1; \
+ do { \
+ ++prescaler; \
+ tc = time_constant(hz); \
+ } while( tc > 65536 ); \
+ } while(0)
+
+
+ /* Use the channels 4 and 3 for hardclock and statclock, respectively */
+
+ /* stop all timers */
+ bus_space_write_4(iot, ioh, TIMER_TCON, 0);
+
+ /* calc suitable prescaler value */
+ calc_time_constant(hz);
+
+ timer4_prescaler = prescaler;
+ timer4_reload_value = TIMER_FREQUENCY(pclk) / hz / prescaler;
+ timer4_mseccount = TIMER_FREQUENCY(pclk)/timer4_prescaler/1000 ;
+
+ bus_space_write_4(iot, ioh, TIMER_TCNTB(4),
+ ((prescaler - 1) << 16) | (timer4_reload_value - 1));
+
+ printf("clock: hz=%d PCLK=%d prescaler=%d tc=%ld\n",
+ hz, pclk, prescaler, tc);
+
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, S3C24X0_INT_TIMER4,
+ S3C24X0_INT_TIMER4, 1, RF_ACTIVE);
+ if (!irq)
+ panic("Unable to allocate the clock irq handler.\n");
+
+ err = bus_setup_intr(dev, irq, INTR_TYPE_CLK | INTR_FAST,
+ clock_intr, NULL, NULL, &ihl);
+ if (err != 0)
+ panic("Unable to setup the clock irq handler.\n");
+
+ /* set prescaler1 */
+ reg = bus_space_read_4(iot, ioh, TIMER_TCFG0);
+ bus_space_write_4(iot, ioh, TIMER_TCFG0,
+ (reg & ~0xff00) | ((prescaler-1) << 8));
+
+ /* divider 1/16 for ch #4 */
+ reg = bus_space_read_4(iot, ioh, TIMER_TCFG1);
+ bus_space_write_4(iot, ioh, TIMER_TCFG1,
+ (reg & ~(TCFG1_MUX_MASK(4))) |
+ (TCFG1_MUX_DIV16 << TCFG1_MUX_SHIFT(4)) );
+
+
+ /* start timers */
+ reg = bus_space_read_4(iot, ioh, TIMER_TCON);
+ reg &= ~(TCON_MASK(4));
+
+ /* load the time constant */
+ bus_space_write_4(iot, ioh, TIMER_TCON, reg | TCON_MANUALUPDATE(4));
+ /* set auto reload and start */
+ bus_space_write_4(iot, ioh, TIMER_TCON, reg |
+ TCON_AUTORELOAD(4) | TCON_START(4) );
+
+ s3c24x0_timer_timecounter.tc_frequency = TIMER_FREQUENCY(pclk) /
+ timer4_prescaler;
+ tc_init(&s3c24x0_timer_timecounter);
+}
+
+/*
+ * DELAY:
+ *
+ * Delay for at least N microseconds.
+ */
+void
+DELAY(int n)
+{
+ struct s3c24x0_softc *sc = (struct s3c24x0_softc *) s3c2xx0_softc;
+ int v0, v1, delta;
+ u_int ucnt;
+
+ if (timer4_reload_value == 0) {
+ /* not initialized yet */
+ while ( n-- > 0 ){
+ int m;
+
+ for (m = 0; m < 100; ++m )
+ ;
+ }
+ return;
+ }
+
+ /* read down counter */
+ v0 = read_timer(sc);
+
+ ucnt = usec_to_counter(n);
+
+ while( ucnt > 0 ) {
+ v1 = read_timer(sc);
+ delta = v0 - v1;
+ if ( delta < 0 )
+ delta += timer4_reload_value;
+
+ if((u_int)delta < ucnt){
+ ucnt -= (u_int)delta;
+ v0 = v1;
+ }
+ else {
+ ucnt = 0;
+ }
+ }
+}
+
+void
+cpu_startprofclock(void)
+{
+}
+
+void
+cpu_stopprofclock(void)
+{
+}
diff --git a/sys/arm/s3c2xx0/s3c24x0_machdep.c b/sys/arm/s3c2xx0/s3c24x0_machdep.c
new file mode 100644
index 0000000..2c73842
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c24x0_machdep.c
@@ -0,0 +1,467 @@
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created : 17/09/94
+ */
+
+#include "opt_msgbuf.h"
+#include "opt_ddb.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_map.h>
+#include <vm/vnode_pager.h>
+#include <machine/pmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <sys/reboot.h>
+
+#include <arm/s3c2xx0/s3c24x0var.h>
+#include <arm/s3c2xx0/s3c2410reg.h>
+#include <arm/s3c2xx0/s3c2xx0board.h>
+
+/* Page table for mapping proc0 zero page */
+#define KERNEL_PT_SYS 0
+#define KERNEL_PT_KERN 1
+#define KERNEL_PT_KERN_NUM 44
+/* L2 table for mapping after kernel */
+#define KERNEL_PT_AFKERNEL KERNEL_PT_KERN + KERNEL_PT_KERN_NUM
+#define KERNEL_PT_AFKERNEL_NUM 5
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+/* Define various stack sizes in pages */
+#define IRQ_STACK_SIZE 1
+#define ABT_STACK_SIZE 1
+#define UND_STACK_SIZE 1
+
+extern int s3c2410_pclk;
+
+extern u_int data_abort_handler_address;
+extern u_int prefetch_abort_handler_address;
+extern u_int undefined_handler_address;
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+extern void *_end;
+
+extern int *end;
+
+struct pcpu __pcpu;
+struct pcpu *pcpup = &__pcpu;
+
+/* Physical and virtual addresses for some global pages */
+
+vm_paddr_t phys_avail[10];
+vm_paddr_t dump_avail[4];
+vm_offset_t physical_pages;
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+
+static struct trapframe proc0_tf;
+
+#define _A(a) ((a) & ~L1_S_OFFSET)
+#define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
+
+/* Static device mappings. */
+static const struct pmap_devmap s3c24x0_devmap[] = {
+ {
+ _A(S3C24X0_CLKMAN_BASE),
+ _A(S3C24X0_CLKMAN_PA_BASE),
+ _S(S3C24X0_CLKMAN_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_GPIO_BASE),
+ _A(S3C24X0_GPIO_PA_BASE),
+ _S(S3C2410_GPIO_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_IIC_BASE),
+ _A(S3C24X0_IIC_PA_BASE),
+ _S(S3C24X0_IIC_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_INTCTL_BASE),
+ _A(S3C24X0_INTCTL_PA_BASE),
+ _S(S3C24X0_INTCTL_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_LCDC_BASE),
+ _A(S3C24X0_LCDC_PA_BASE),
+ _S(S3C24X0_LCDC_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_SDI_BASE),
+ _A(S3C24X0_SDI_PA_BASE),
+ _S(S3C2410_SDI_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_UART0_BASE),
+ _A(S3C24X0_UART0_PA_BASE),
+ _S(S3C24X0_UART_PA_BASE(3) - S3C24X0_UART0_PA_BASE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_USBHC_BASE),
+ _A(S3C24X0_USBHC_PA_BASE),
+ _S(S3C24X0_USBHC_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ _A(S3C24X0_WDT_BASE),
+ _A(S3C24X0_WDT_PA_BASE),
+ _S(S3C24X0_WDT_SIZE),
+ VM_PROT_READ|VM_PROT_WRITE,
+ PTE_NOCACHE,
+ },
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }
+};
+
+#undef _A
+#undef _S
+
+#define ioreg_read32(a) (*(volatile uint32_t *)(a))
+#define ioreg_write32(a,v) (*(volatile uint32_t *)(a)=(v))
+
+#ifdef DDB
+extern vm_offset_t ksym_start, ksym_end;
+#endif
+
+struct arm32_dma_range s3c24x0_range = {
+ .dr_sysbase = 0,
+ .dr_busbase = 0,
+ .dr_len = 0,
+};
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+ if (s3c24x0_range.dr_len == 0) {
+ s3c24x0_range.dr_sysbase = dump_avail[0];
+ s3c24x0_range.dr_busbase = dump_avail[0];
+ s3c24x0_range.dr_len = dump_avail[1] - dump_avail[0];
+ }
+ return (&s3c24x0_range);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+ return (1);
+}
+
+void *
+initarm(void *arg, void *arg2)
+{
+ struct pv_addr kernel_l1pt;
+ int loop;
+ u_int l1pagetable;
+ vm_offset_t freemempos;
+ vm_offset_t afterkern;
+ vm_offset_t lastaddr;
+
+ int i;
+ uint32_t memsize;
+
+ i = 0;
+
+ boothowto = 0;
+
+ set_cpufuncs();
+ cpufuncs.cf_sleep = s3c24x0_sleep;
+ lastaddr = fake_preload_metadata();
+
+ pcpu_init(pcpup, 0, sizeof(struct pcpu));
+ PCPU_SET(curthread, &thread0);
+
+#define KERNEL_TEXT_BASE (KERNBASE)
+ freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
+ /* Define a macro to simplify memory allocation */
+#define valloc_pages(var, np) \
+ alloc_pages((var).pv_va, (np)); \
+ (var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR);
+
+#define alloc_pages(var, np) \
+ (var) = freemempos; \
+ freemempos += (np * PAGE_SIZE); \
+ memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+ while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+ freemempos += PAGE_SIZE;
+ valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+ for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+ if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+ valloc_pages(kernel_pt_table[loop],
+ L2_TABLE_SIZE / PAGE_SIZE);
+ } else {
+ kernel_pt_table[loop].pv_va = freemempos -
+ (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+ L2_TABLE_SIZE_REAL;
+ kernel_pt_table[loop].pv_pa =
+ kernel_pt_table[loop].pv_va - KERNVIRTADDR +
+ KERNPHYSADDR;
+ }
+ }
+ /*
+ * Allocate a page for the system page mapped to V0x00000000
+ * This page will just contain the system vectors and can be
+ * shared by all processes.
+ */
+ valloc_pages(systempage, 1);
+
+ /* Allocate stacks for all modes */
+ valloc_pages(irqstack, IRQ_STACK_SIZE);
+ valloc_pages(abtstack, ABT_STACK_SIZE);
+ valloc_pages(undstack, UND_STACK_SIZE);
+ valloc_pages(kernelstack, KSTACK_PAGES);
+ valloc_pages(msgbufpv, round_page(MSGBUF_SIZE) / PAGE_SIZE);
+ /*
+ * Now we start construction of the L1 page table
+ * We start by mapping the L2 page tables into the L1.
+ * This means that we can replace L1 mappings later on if necessary
+ */
+ l1pagetable = kernel_l1pt.pv_va;
+
+ /* Map the L2 pages tables in the L1 page table */
+ pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
+ &kernel_pt_table[KERNEL_PT_SYS]);
+ for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
+ pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
+ &kernel_pt_table[KERNEL_PT_KERN + i]);
+ pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
+ (((uint32_t)(lastaddr) - KERNBASE) + PAGE_SIZE) & ~(PAGE_SIZE - 1),
+ VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ afterkern = round_page((lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
+ - 1));
+ for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+ pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
+ &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+ }
+
+ /* Map the vector page. */
+ pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+ VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ /* Map the stack pages */
+ pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
+ IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
+ ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
+ UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
+ KSTACK_PAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+ pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
+ L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+ pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
+ MSGBUF_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+
+ for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+ pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
+ kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
+ VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+ }
+
+ pmap_devmap_bootstrap(l1pagetable, s3c24x0_devmap);
+
+ cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+ setttb(kernel_l1pt.pv_pa);
+ cpu_tlb_flushID();
+ cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+
+ /*
+ * Pages were allocated during the secondary bootstrap for the
+ * stacks for different CPU modes.
+ * We must now set the r13 registers in the different CPU modes to
+ * point to these stacks.
+ * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+ * of the stack memory.
+ */
+
+ cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
+ set_stackptr(PSR_IRQ32_MODE,
+ irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
+ set_stackptr(PSR_ABT32_MODE,
+ abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
+ set_stackptr(PSR_UND32_MODE,
+ undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
+
+ /*
+ * We must now clean the cache again....
+ * Cleaning may be done by reading new data to displace any
+ * dirty data in the cache. This will have happened in setttb()
+ * but since we are boot strapping the addresses used for the read
+ * may have just been remapped and thus the cache could be out
+ * of sync. A re-clean after the switch will cure this.
+ * After booting there are no gross reloations of the kernel thus
+ * this problem will not occur after initarm().
+ */
+ cpu_idcache_wbinv_all();
+
+ /* Disable all peripheral interrupts */
+ ioreg_write32(S3C24X0_INTCTL_BASE + INTCTL_INTMSK, ~0);
+ memsize = board_init();
+ /* Find pclk for uart */
+ switch(ioreg_read32(S3C24X0_GPIO_BASE + GPIO_GSTATUS1) >> 16) {
+ case 0x3241:
+ s3c2410_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL,
+ &s3c2410_pclk);
+ break;
+ case 0x3244:
+ s3c2440_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL,
+ &s3c2410_pclk);
+ break;
+ }
+ cninit();
+
+ /* Set stack for exception handlers */
+ data_abort_handler_address = (u_int)data_abort_handler;
+ prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
+ undefined_handler_address = (u_int)undefinedinstruction_bounce;
+ undefined_init();
+
+ proc_linkup(&proc0, &thread0);
+ thread0.td_kstack = kernelstack.pv_va;
+ thread0.td_pcb = (struct pcb *)
+ (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+ thread0.td_pcb->pcb_flags = 0;
+ thread0.td_frame = &proc0_tf;
+ pcpup->pc_curpcb = thread0.td_pcb;
+
+ arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+ pmap_curmaxkvaddr = afterkern + 0x100000 * (KERNEL_PT_KERN_NUM - 1);
+ /*
+ * ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
+ * calling pmap_bootstrap.
+ */
+ dump_avail[0] = PHYSADDR;
+ dump_avail[1] = PHYSADDR + memsize;
+ dump_avail[2] = 0;
+ dump_avail[3] = 0;
+
+ pmap_bootstrap(freemempos,
+ KERNVIRTADDR + 3 * memsize,
+ &kernel_l1pt);
+ msgbufp = (void*)msgbufpv.pv_va;
+ msgbufinit(msgbufp, MSGBUF_SIZE);
+ mutex_init();
+
+ physmem = memsize / PAGE_SIZE;
+
+ phys_avail[0] = virtual_avail - KERNVIRTADDR + KERNPHYSADDR;
+ phys_avail[1] = PHYSADDR + memsize;
+ phys_avail[2] = 0;
+ phys_avail[3] = 0;
+
+ /* Do basic tuning, hz etc */
+ init_param1();
+ init_param2(physmem);
+ kdb_init();
+
+ return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+ sizeof(struct pcb)));
+}
diff --git a/sys/arm/s3c2xx0/s3c24x0reg.h b/sys/arm/s3c2xx0/s3c24x0reg.h
new file mode 100644
index 0000000..3b8dc6e
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c24x0reg.h
@@ -0,0 +1,672 @@
+/* $NetBSD: s3c24x0reg.h,v 1.7 2004/02/12 03:52:46 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003 Genetec corporation All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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$
+ */
+
+
+/*
+ * Samsung S3C2410X/2400 processor is ARM920T based integrated CPU
+ *
+ * Reference:
+ * S3C2410X User's Manual
+ * S3C2400 User's Manual
+ */
+#ifndef _ARM_S3C2XX0_S3C24X0REG_H_
+#define _ARM_S3C2XX0_S3C24X0REG_H_
+
+/* common definitions for S3C2800, S3C2410 and S3C2440 */
+#include <arm/s3c2xx0/s3c2xx0reg.h>
+
+/*
+ * Map the device registers into kernel space
+ */
+#define S3C24X0_DEV_START 0x48000000
+#define S3C24X0_DEV_STOP 0x60000000
+#define S3C24X0_DEV_VA_OFFSET 0xD0000000
+#define S3C24X0_DEV_VA_SIZE (S3C24X0_DEV_STOP - S3C24X0_DEV_START)
+#define S3C24X0_DEV_PA_TO_VA(x) (x - S3C24X0_DEV_START + S3C24X0_DEV_VA_OFFSET)
+
+/*
+ * Physical address of integrated peripherals
+ */
+#define S3C24X0_MEMCTL_PA_BASE 0x48000000 /* memory controller */
+#define S3C24X0_MEMCTL_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_MEMCTL_PA_BASE)
+#define S3C24X0_USBHC_PA_BASE 0x49000000 /* USB Host controller */
+#define S3C24X0_USBHC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_USBHC_PA_BASE)
+#define S3C24X0_INTCTL_PA_BASE 0x4a000000 /* Interrupt controller */
+#define S3C24X0_INTCTL_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_INTCTL_PA_BASE)
+#define S3C24X0_INTCTL_SIZE 0x20
+#define S3C24X0_DMAC_PA_BASE 0x4b000000
+#define S3C24X0_DMAC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_DMAC_PA_BASE)
+#define S3C24X0_DMAC_SIZE 0xe4
+#define S3C24X0_CLKMAN_PA_BASE 0x4c000000 /* clock & power management */
+#define S3C24X0_CLKMAN_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_CLKMAN_PA_BASE)
+#define S3C24X0_LCDC_PA_BASE 0x4d000000 /* LCD controller */
+#define S3C24X0_LCDC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_LCDC_PA_BASE)
+#define S3C24X0_LCDC_SIZE 0x64
+#define S3C24X0_NANDFC_PA_BASE 0x4e000000 /* NAND Flash controller */
+#define S3C24X0_NANDFC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_NANDFC_PA_BASE)
+#define S3C24X0_UART0_PA_BASE 0x50000000
+#define S3C24X0_UART0_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_UART0_PA_BASE)
+#define S3C24X0_UART_PA_BASE(n) (S3C24X0_UART0_PA_BASE+0x4000*(n))
+#define S3C24X0_UART_BASE(n) S3C24X0_DEV_PA_TO_VA(S3C24X0_UART_PA_BASE(n))
+#define S3C24X0_TIMER_PA_BASE 0x51000000
+#define S3C24X0_TIMER_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_TIMER_PA_BASE)
+#define S3C24X0_USBDC_PA_BASE 0x5200140
+#define S3C24X0_USBDC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_USBDC_PA_BASE)
+#define S3C24X0_USBDC_SIZE 0x130
+#define S3C24X0_WDT_PA_BASE 0x53000000
+#define S3C24X0_WDT_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_WDT_PA_BASE)
+#define S3C24X0_IIC_PA_BASE 0x54000000
+#define S3C24X0_IIC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_IIC_PA_BASE)
+#define S3C24X0_IIS_PA_BASE 0x55000000
+#define S3C24X0_IIS_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_IIS_PA_BASE)
+#define S3C24X0_GPIO_PA_BASE 0x56000000
+#define S3C24X0_GPIO_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_GPIO_PA_BASE)
+#define S3C24X0_ADC_PA_BASE 0x58000000
+#define S3C24X0_ADC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_ADC_PA_BASE)
+#define S3C24X0_SPI0_PA_BASE 0x59000000
+#define S3C24X0_SPI0_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_SPI0_PA_BASE)
+#define S3C24X0_SPI1_PA_BASE 0x59000020
+#define S3C24X0_SPI1_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_SPI1_PA_BASE)
+#define S3C24X0_SDI_PA_BASE 0x5a000000 /* SD Interface */
+#define S3C24X0_SDI_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_SDI_PA_BASE)
+
+#define S3C24X0_REG_BASE 0x48000000
+#define S3C24X0_REG_SIZE 0x13000000
+
+/* Memory controller */
+#define MEMCTL_BWSCON 0x00 /* Bus width and wait status */
+#define BWSCON_DW0_SHIFT 1 /* bank0 is odd */
+#define BWSCON_BANK_SHIFT(n) (4*(n)) /* for bank 1..7 */
+#define BWSCON_DW_MASK 0x03
+#define BWSCON_DW_8 0
+#define BWSCON_DW_16 1
+#define BWSCON_DW_32 2
+#define BWSCON_WS 0x04 /* WAIT enable for the bank */
+#define BWSCON_ST 0x08 /* SRAM use UB/LB for the bank */
+
+#define MEMCTL_BANKCON0 0x04 /* Boot ROM control */
+#define MEMCTL_BANKCON(n) (0x04+4*(n)) /* BANKn control */
+#define BANKCON_MT_SHIFT 15
+#define BANKCON_MT_ROM (0<<BANKCON_MT_SHIFT)
+#define BANKCON_MT_DRAM (3<<BANKCON_MT_SHIFT)
+#define BANKCON_TACS_SHIFT 13 /* address set-up time to nGCS */
+#define BANKCON_TCOS_SHIFT 11 /* CS set-up to nOE */
+#define BANKCON_TACC_SHIFT 8 /* CS set-up to nOE */
+#define BANKCON_TOCH_SHIFT 6 /* CS hold time from OE */
+#define BANKCON_TCAH_SHIFT 4 /* address hold time from OE */
+#define BANKCON_TACP_SHIFT 2 /* page mode access cycle */
+#define BANKCON_TACP_2 (0<<BANKCON_TACP_SHIFT)
+#define BANKCON_TACP_3 (1<<BANKCON_TACP_SHIFT)
+#define BANKCON_TACP_4 (2<<BANKCON_TACP_SHIFT)
+#define BANKCON_TACP_6 (3<<BANKCON_TACP_SHIFT)
+#define BANKCON_PMC_4 (1<<0)
+#define BANKCON_PMC_8 (2<<0)
+#define BANKCON_PMC_16 (3<<0)
+#define BANKCON_TRCD_SHIFT 2 /* RAS to CAS delay */
+#define BANKCON_TRCD_2 (0<<2)
+#define BANKCON_TRCD_3 (1<<2)
+#define BANKCON_TRCD_4 (2<<2)
+#define BANKCON_SCAN_8 (0<<0) /* Column address number */
+#define BANKCON_SCAN_9 (1<<0)
+#define BANKCON_SCAN_10 (2<<0)
+#define MEMCTL_REFRESH 0x24 /* DRAM?SDRAM Refresh */
+#define REFRESH_REFEN (1<<23)
+#define REFRESH_TREFMD (1<<22) /* 1=self refresh */
+#define REFRESH_TRP_2 (0<<20)
+#define REFRESH_TRP_3 (1<<20)
+#define REFRESH_TRP_4 (2<<20)
+#define REFRESH_TRC_4 (0<<18)
+#define REFRESH_TRC_5 (1<<18)
+#define REFRESH_TRC_6 (2<<18)
+#define REFRESH_TRC_7 (3<<18)
+#define REFRESH_COUNTER_MASK 0x3ff
+#define MEMCTL_BANKSIZE 0x28 /* Flexible Bank size */
+#define MEMCTL_MRSRB6 0x2c /* SDRAM Mode register */
+#define MEMCTL_MRSRB7 0x30
+#define MRSR_CL_SHIFT 4 /* CAS Latency */
+
+#define S3C24X0_MEMCTL_SIZE 0x34
+
+/* USB Host controller */
+#define S3C24X0_USBHC_SIZE 0x5c
+
+/* Interrupt controller */
+#define INTCTL_PRIORITY 0x0c /* IRQ Priority control */
+#define INTCTL_INTPND 0x10 /* Interrupt request status */
+#define INTCTL_INTOFFSET 0x14 /* Interrupt request source */
+#define INTCTL_SUBSRCPND 0x18 /* sub source pending */
+#define INTCTL_INTSUBMSK 0x1c /* sub mask */
+
+/* Interrupt source */
+#define S3C24X0_INT_ADCTC 31 /* ADC (and TC for 2410) */
+#define S3C24X0_INT_RTC 30 /* RTC alarm */
+#define S3C24X0_INT_SPI1 29 /* SPI 1 */
+#define S3C24X0_INT_UART0 28 /* UART0 */
+#define S3C24X0_INT_IIC 27
+#define S3C24X0_INT_USBH 26 /* USB Host */
+#define S3C24X0_INT_USBD 25 /* USB Device */
+#define S3C24X0_INT_UART1 23 /* UART0 (2410 only) */
+#define S3C24X0_INT_SPI0 22 /* SPI 0 */
+#define S3C24X0_INT_SDI 21
+#define S3C24X0_INT_DMA3 20
+#define S3C24X0_INT_DMA2 19
+#define S3C24X0_INT_DMA1 18
+#define S3C24X0_INT_DMA0 17
+#define S3C24X0_INT_LCD 16
+
+#define S3C24X0_INT_UART2 15 /* UART2 int (2410) */
+#define S3C24X0_INT_TIMER4 14
+#define S3C24X0_INT_TIMER3 13
+#define S3C24X0_INT_TIMER2 12
+#define S3C24X0_INT_TIMER1 11
+#define S3C24X0_INT_TIMER0 10
+#define S3C24X0_INT_TIMER(n) (10+(n)) /* timer interrupt [4:0] */
+#define S3C24X0_INT_WDT 9 /* Watch dog timer */
+#define S3C24X0_INT_TICK 8
+#define S3C24X0_INT_BFLT 7 /* Battery fault */
+#define S3C24X0_INT_8_23 5 /* Ext int 8..23 */
+#define S3C24X0_INT_4_7 4 /* Ext int 4..7 */
+#define S3C24X0_INT_EXT(n) (n) /* External interrupt [3:0] for 24{1,4}0 */
+
+/* 24{1,4}0 has more than 32 interrupt sources. These are sub-sources
+ * that are OR-ed into main interrupt sources, and controlled via
+ * SUBSRCPND and SUBSRCMSK registers */
+#define S3C24X0_SUBIRQ_MIN 32
+
+/* cascaded to INT_ADCTC */
+#define S3C24X0_INT_ADC (S3C24X0_SUBIRQ_MIN+10) /* AD converter */
+#define S3C24X0_INT_TC (S3C24X0_SUBIRQ_MIN+9) /* Touch screen */
+/* cascaded to INT_UART2 */
+#define S3C24X0_INT_ERR2 (S3C24X0_SUBIRQ_MIN+8) /* UART2 Error */
+#define S3C24X0_INT_TXD2 (S3C24X0_SUBIRQ_MIN+7) /* UART2 Tx */
+#define S3C24X0_INT_RXD2 (S3C24X0_SUBIRQ_MIN+6) /* UART2 Rx */
+/* cascaded to INT_UART1 */
+#define S3C24X0_INT_ERR1 (S3C24X0_SUBIRQ_MIN+5) /* UART1 Error */
+#define S3C24X0_INT_TXD1 (S3C24X0_SUBIRQ_MIN+4) /* UART1 Tx */
+#define S3C24X0_INT_RXD1 (S3C24X0_SUBIRQ_MIN+3) /* UART1 Rx */
+/* cascaded to INT_UART0 */
+#define S3C24X0_INT_ERR0 (S3C24X0_SUBIRQ_MIN+2) /* UART0 Error */
+#define S3C24X0_INT_TXD0 (S3C24X0_SUBIRQ_MIN+1) /* UART0 Tx */
+#define S3C24X0_INT_RXD0 (S3C24X0_SUBIRQ_MIN+0) /* UART0 Rx */
+
+/* DMA controller */
+/* XXX */
+
+/* Clock & power manager */
+#define CLKMAN_LOCKTIME 0x00 /* PLL lock time */
+#define CLKMAN_MPLLCON 0x04 /* MPLL control */
+#define CLKMAN_UPLLCON 0x08 /* UPLL control */
+#define PLLCON_MDIV_SHIFT 12
+#define PLLCON_MDIV_MASK (0xff<<PLLCON_MDIV_SHIFT)
+#define PLLCON_PDIV_SHIFT 4
+#define PLLCON_PDIV_MASK (0x3f<<PLLCON_PDIV_SHIFT)
+#define PLLCON_SDIV_SHIFT 0
+#define PLLCON_SDIV_MASK (0x03<<PLLCON_SDIV_SHIFT)
+#define CLKMAN_CLKCON 0x0c
+#define CLKCON_SPI (1<<18)
+#define CLKCON_IIS (1<<17)
+#define CLKCON_IIC (1<<16)
+#define CLKCON_ADC (1<<15)
+#define CLKCON_RTC (1<<14)
+#define CLKCON_GPIO (1<<13)
+#define CLKCON_UART2 (1<<12)
+#define CLKCON_UART1 (1<<11)
+#define CLKCON_UART0 (1<<10) /* PCLK to UART0 */
+#define CLKCON_SDI (1<<9)
+#define CLKCON_TIMER (1<<8) /* PCLK to TIMER */
+#define CLKCON_USBD (1<<7) /* PCLK to USB device controller */
+#define CLKCON_USBH (1<<6) /* PCLK to USB host controller */
+#define CLKCON_LCDC (1<<5) /* PCLK to LCD controller */
+#define CLKCON_NANDFC (1<<4) /* PCLK to NAND Flash controller */
+#define CLKCON_IDLE (1<<2) /* 1=transition to IDLE mode */
+#define CLKMAN_CLKSLOW 0x10
+#define CLKMAN_CLKDIVN 0x14
+#define CLKDIVN_PDIVN (1<<0) /* pclk=hclk/2 */
+
+#define CLKMAN_CLKSLOW 0x10 /* slow clock controll */
+#define CLKSLOW_UCLK (1<<7) /* 1=UPLL off */
+#define CLKSLOW_MPLL (1<<5) /* 1=PLL off */
+#define CLKSLOW_SLOW (1<<4) /* 1: Enable SLOW mode */
+#define CLKSLOW_VAL_MASK 0x0f /* divider value for slow clock */
+
+#define CLKMAN_CLKDIVN 0x14 /* Software reset control */
+#define CLKDIVN_PDIVN (1<<0)
+
+#define S3C24X0_CLKMAN_SIZE 0x18
+
+/* LCD controller */
+#define LCDC_LCDCON1 0x00 /* control 1 */
+#define LCDCON1_ENVID (1<<0) /* enable video */
+#define LCDCON1_BPPMODE_SHIFT 1
+#define LCDCON1_BPPMODE_MASK (0x0f<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_STN1 (0x0<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_STN2 (0x1<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_STN4 (0x2<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_STN8 (0x3<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_STN12 (0x4<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFT1 (0x8<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFT2 (0x9<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFT4 (0xa<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFT8 (0xb<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFT16 (0xc<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFT24 (0xd<<LCDCON1_BPPMODE_SHIFT)
+#define LCDCON1_BPPMODE_TFTX (0x8<<LCDCON1_BPPMODE_SHIFT)
+
+#define LCDCON1_PNRMODE_SHIFT 5
+#define LCDCON1_PNRMODE_MASK (0x3<<LCDCON1_PNRMODE_SHIFT)
+#define LCDCON1_PNRMODE_DUALSTN4 (0x0<<LCDCON1_PNRMODE_SHIFT)
+#define LCDCON1_PNRMODE_SINGLESTN4 (0x1<<LCDCON1_PNRMODE_SHIFT)
+#define LCDCON1_PNRMODE_SINGLESTN8 (0x2<<LCDCON1_PNRMODE_SHIFT)
+#define LCDCON1_PNRMODE_TFT (0x3<<LCDCON1_PNRMODE_SHIFT)
+
+#define LCDCON1_MMODE (1<<7) /* VM toggle rate */
+#define LCDCON1_CLKVAL_SHIFT 8
+#define LCDCON1_CLKVAL_MASK (0x3ff<<LCDCON1_CLKVAL_SHIFT)
+#define LCDCON1_LINCNT_SHIFT 18
+#define LCDCON1_LINCNT_MASK (0x3ff<<LCDCON1_LINCNT_SHIFT)
+
+#define LCDC_LCDCON2 0x04 /* control 2 */
+#define LCDCON2_VPSW_SHIFT 0 /* TFT Vsync pulse width */
+#define LCDCON2_VPSW_MASK (0x3f<<LCDCON2_VPSW_SHIFT)
+#define LCDCON2_VFPD_SHIFT 6 /* TFT V front porch */
+#define LCDCON2_VFPD_MASK (0xff<<LCDCON2_VFPD_SHIFT)
+#define LCDCON2_LINEVAL_SHIFT 14 /* Vertical size */
+#define LCDCON2_LINEVAL_MASK (0x3ff<<LCDCON2_LINEVAL_SHIFT)
+#define LCDCON2_VBPD_SHIFT 24 /* TFT V back porch */
+#define LCDCON2_VBPD_MASK (0xff<<LCDCON2_VBPD_SHIFT)
+
+#define LCDC_LCDCON3 0x08 /* control 2 */
+#define LCDCON3_HFPD_SHIFT 0 /* TFT H front porch */
+#define LCDCON3_HFPD_MASK (0xff<<LCDCON3_VPFD_SHIFT)
+#define LCDCON3_LINEBLANK_SHIFT 0 /* STN H blank time */
+#define LCDCON3_LINEBLANK_MASK (0xff<<LCDCON3_LINEBLANK_SHIFT)
+#define LCDCON3_HOZVAL_SHIFT 8 /* Horizontal size */
+#define LCDCON3_HOZVAL_MASK (0x7ff<<LCDCON3_HOZVAL_SHIFT)
+#define LCDCON3_HBPD_SHIFT 19 /* TFT H back porch */
+#define LCDCON3_HBPD_MASK (0x7f<<LCDCON3_HPBD_SHIFT)
+#define LCDCON3_WDLY_SHIFT 19 /* STN vline delay */
+#define LCDCON3_WDLY_MASK (0x03<<LCDCON3_WDLY_SHIFT)
+#define LCDCON3_WDLY_16 (0x00<<LCDCON3_WDLY_SHIFT)
+#define LCDCON3_WDLY_32 (0x01<<LCDCON3_WDLY_SHIFT)
+#define LCDCON3_WDLY_64 (0x02<<LCDCON3_WDLY_SHIFT)
+#define LCDCON3_WDLY_128 (0x03<<LCDCON3_WDLY_SHIFT)
+
+#define LCDC_LCDCON4 0x0c /* control 4 */
+#define LCDCON4_HPSW_SHIFT 0 /* TFT Hsync pulse width */
+#define LCDCON4_HPSW_MASK (0xff<<LCDCON4_HPSW_SHIFT)
+#define LCDCON4_WLH_SHIFT 0 /* STN VLINE high width */
+#define LCDCON4_WLH_MASK (0x03<<LCDCON4_WLH_SHIFT)
+#define LCDCON4_WLH_16 (0x00<<LCDCON4_WLH_SHIFT)
+#define LCDCON4_WLH_32 (0x01<<LCDCON4_WLH_SHIFT)
+#define LCDCON4_WLH_64 (0x02<<LCDCON4_WLH_SHIFT)
+#define LCDCON4_WLH_128 (0x03<<LCDCON4_WLH_SHIFT)
+
+#define LCDCON4_MVAL_SHIFT 8 /* STN VM toggle rate */
+#define LCDCON4_MVAL_MASK (0xff<<LCDCON4_MVAL_SHIFT)
+
+#define LCDC_LCDCON5 0x10 /* control 5 */
+#define LCDCON5_HWSWP (1<<0) /* half-word swap */
+#define LCDCON5_BSWP (1<<1) /* byte swap */
+#define LCDCON5_ENLEND (1<<2) /* TFT: enable LEND signal */
+#define LCDCON5_PWREN (1<<3) /* enable PWREN signale */
+#define LCDCON5_INVLEND (1<<4) /* TFT: LEND signal polarity */
+#define LCDCON5_INVPWREN (1<<5) /* PWREN signal polarity */
+#define LCDCON5_INVVDEN (1<<6) /* VDEN signal polarity */
+#define LCDCON5_INVVD (1<<7) /* video data signal polarity */
+#define LCDCON5_INVVFRAME (1<<8) /* VFRAME/VSYNC signal polarity */
+#define LCDCON5_INVVLINE (1<<9) /* VLINE/HSYNC signal polarity */
+#define LCDCON5_INVVCLK (1<<10) /* VCLK signal polarity */
+#define LCDCON5_INVVCLK_RISING LCDCON5_INVVCLK
+#define LCDCON5_INVVCLK_FALLING 0
+#define LCDCON5_FRM565 (1<<11) /* RGB:565 format*/
+#define LCDCON5_FRM555I 0 /* RGBI:5551 format */
+#define LCDCON5_BPP24BL (1<<12) /* bit order for bpp24 */
+
+#define LCDCON5_HSTATUS_SHIFT 17 /* TFT: horizontal status */
+#define LCDCON5_HSTATUS_MASK (0x03<<LCDCON5_HSTATUS_SHIFT)
+#define LCDCON5_HSTATUS_HSYNC (0x00<<LCDCON5_HSTATUS_SHIFT)
+#define LCDCON5_HSTATUS_BACKP (0x01<<LCDCON5_HSTATUS_SHIFT)
+#define LCDCON5_HSTATUS_ACTIVE (0x02<<LCDCON5_HSTATUS_SHIFT)
+#define LCDCON5_HSTATUS_FRONTP (0x03<<LCDCON5_HSTATUS_SHIFT)
+
+#define LCDCON5_VSTATUS_SHIFT 19 /* TFT: vertical status */
+#define LCDCON5_VSTATUS_MASK (0x03<<LCDCON5_VSTATUS_SHIFT)
+#define LCDCON5_VSTATUS_HSYNC (0x00<<LCDCON5_VSTATUS_SHIFT)
+#define LCDCON5_VSTATUS_BACKP (0x01<<LCDCON5_VSTATUS_SHIFT)
+#define LCDCON5_VSTATUS_ACTIVE (0x02<<LCDCON5_VSTATUS_SHIFT)
+#define LCDCON5_VSTATUS_FRONTP (0x03<<LCDCON5_VSTATUS_SHIFT)
+
+#define LCDC_LCDSADDR1 0x14 /* frame buffer start address */
+#define LCDC_LCDSADDR2 0x18
+#define LCDC_LCDSADDR3 0x1c
+#define LCDSADDR3_OFFSIZE_SHIFT 11
+#define LCDSADDR3_PAGEWIDTH_SHIFT 0
+
+#define LCDC_REDLUT 0x20 /* STN: red lookup table */
+#define LCDC_GREENLUT 0x24 /* STN: green lookup table */
+#define LCDC_BLUELUT 0x28 /* STN: blue lookup table */
+#define LCDC_DITHMODE 0x4c /* STN: dithering mode */
+
+#define LCDC_TPAL 0x50 /* TFT: temporary palette */
+#define TPAL_TPALEN (1<<24)
+#define TPAL_RED_SHIFT 16
+#define TPAL_GREEN_SHIFT 8
+#define TPAL_BLUE_SHIFT 0
+
+#define LCDC_LCDINTPND 0x54
+#define LCDC_LCDSRCPND 0x58
+#define LCDC_LCDINTMSK 0x5c
+#define LCDINT_FICNT (1<<0) /* FIFO trigger interrupt pending */
+#define LCDINT_FRSYN (1<<1) /* frame sync interrupt pending */
+#define LCDINT_FIWSEL (1<<2) /* FIFO trigger level: 1=8 words, 0=4 words*/
+
+#define LCDC_LPCSEL 0x60 /* LPC3600 mode */
+#define LPCSEL_LPC_EN (1<<0) /* enable LPC3600 mode */
+#define LPCSEL_RES_SEL (1<<1) /* 1=240x320 0=320x240 */
+#define LPCSEL_MODE_SEL (1<<2)
+#define LPCSEL_CPV_SEL (1<<3)
+
+
+#define LCDC_PALETTE 0x0400
+#define LCDC_PALETTE_SIZE 0x0400
+
+/* NAND Flash controller */
+#define NANDFC_NFCONF 0x00 /* Configuration */
+/* NANDFC_NFSTAT */
+#define NFSTAT_READY (1<<0) /* NAND flash memory ready/busy status */
+
+
+/* MMC/SD */
+#define SDI_CON 0x00
+#define CON_BYTEORDER (1<<4)
+#define CON_SDIO_INTR (1<<3)
+#define CON_READWAIT_EN (1<<2)
+#define CON_CLOCK_EN (1<<0)
+#define SDI_PRE 0x04
+#define SDI_CARG 0x08
+#define SDI_CCON 0x0c
+#define CCON_ABORDCMD (1<<12) /* Abort SDIO CMD12/52 */
+#define CCON_WITHDATA (1<<11) /* CMD with data */
+#define CCON_LONGRSP (1<<10) /* 136 bit response */
+#define CCON_WAITRSP (1<<9) /* Host waits for response */
+#define CCON_CMD_START (1<<8)
+#define CCON_CMDINDEX_MASK (0x7F) /* Command number index */
+#define SDI_CSTA 0x10
+#define CSTA_RSPCRCFAIL (1<<12)
+#define CSTA_CMDSENT (1<<11)
+#define CSTA_CMDTOUT (1<<10)
+#define CSTA_RSPFIN (1<<9)
+/* All the bits to be cleared */
+#define CSTA_ALL_CLEAR (CSTA_RSPCRCFAIL | CSTA_CMDSENT | \
+ CSTA_CMDTOUT | CSTA_RSPFIN)
+#define CSTA_ERROR (CSTA_RSPCRCFAIL | CSTA_CMDTOUT)
+#define CSTA_CMDON (1<<8)
+#define SDI_RSP0 0x14
+#define SDI_RSP1 0x18
+#define SDI_RSP2 0x1c
+#define SDI_RSP3 0x20
+#define SDI_DTIMER 0x24
+#define SDI_BSIZE 0x28
+#define SDI_DCON 0x2c
+#define DCON_PRDTYPE (1<<21)
+#define DCON_TARSP (1<<20) /* Transmit after response */
+#define DCON_RACMD (1<<19) /* Receive after command */
+#define DCON_BACMD (1<<18) /* Busy after command */
+#define DCON_BLKMODE (1<<17) /* Stream/Block mode */
+#define DCON_WIDEBUS (1<<16) /* Standard/Wide bus */
+#define DCON_ENDMA (1<<15) /* DMA Enable */
+/* Determine the direction of the data transfer */
+#define DCON_DATA_READY (0<<12) /* No transfer */
+#define DCON_ONLYBUST (1<<12) /* Check if busy */
+#define DCON_DATA_RECEIVE (2<<12) /* Receive data from SD */
+#define DCON_DATA_TRANSMIT (3<<12) /* Send data to SD */
+#define DCON_BLKNUM_MASK (0x7FF) /* Block number */
+#define SDI_DCNT 0x30
+#define SDI_DSTA 0x34
+#define SDI_FSTA 0x38
+#define FSTA_TX_AVAIL (1<<13)
+#define FSTA_RX_AVAIL (1<<12)
+#define FSTA_TX_FIFO_HALF_FULL (1<<11)
+#define FSTA_TX_FIFO_EMPTY (1<<10)
+#define FSTA_RX_FIFO_LAST_DATA (1<<9)
+#define FSTA_RX_FIFO_FULL (1<<8)
+#define FSTA_RX_FIFO_HALF_FULL (1<<7)
+#define FSTA_FIFO_COUNT_MSK (0x7F)
+
+/* Timer */
+#define TIMER_TCFG0 0x00 /* Timer configuration */
+#define TIMER_TCFG1 0x04
+#define TCFG1_MUX_SHIFT(n) (4*(n))
+#define TCFG1_MUX_MASK(n) (0x0f << TCFG1_MUX_SHIFT(n))
+#define TCFG1_MUX_DIV2 0
+#define TCFG1_MUX_DIV4 1
+#define TCFG1_MUX_DIV8 2
+#define TCFG1_MUX_DIV16 3
+#define TCFG1_MUX_EXT 4
+#define TIMER_TCON 0x08 /* control */
+#define TCON_SHIFT(n) (4 * ((n)==0 ? 0 : (n)+1))
+#define TCON_START(n) (1 << TCON_SHIFT(n))
+#define TCON_MANUALUPDATE(n) (1 << (TCON_SHIFT(n) + 1))
+#define TCON_INVERTER(n) (1 << (TCON_SHIFT(n) + 2))
+#define __TCON_AUTORELOAD(n) (1 << (TCON_SHIFT(n) + 3)) /* n=0..3 */
+#define TCON_AUTORELOAD4 (1<<22) /* stupid hardware design */
+#define TCON_AUTORELOAD(n) \
+ ((n)==4 ? TCON_AUTORELOAD4 : __TCON_AUTORELOAD(n))
+#define TCON_MASK(n) (0x0f << TCON_SHIFT(n))
+#define TIMER_TCNTB(n) (0x0c+0x0c*(n)) /* count buffer */
+#define TIMER_TCMPB(n) (0x10+0x0c*(n)) /* compare buffer */
+#define __TIMER_TCNTO(n) (0x14+0x0c*(n)) /* count observation */
+#define TIMER_TCNTO4 0x40
+#define TIMER_TCNTO(n) ((n)==4 ? TIMER_TCNTO4 : __TIMER_TCNTO(n))
+
+#define S3C24X0_TIMER_SIZE 0x44
+
+/* UART */
+/* diffs to s3c2800 */
+/* SSCOM_UMCON */
+#define UMCON_AFC (1<<4) /* auto flow control */
+/* SSCOM_UMSTAT */
+#define UMSTAT_DCTS (1<<2) /* CTS change */
+/* SSCOM_UMSTAT */
+#define ULCON_IR (1<<6)
+#define ULCON_PARITY_SHIFT 3
+
+#define S3C24X0_UART_SIZE 0x2c
+
+/* USB device */
+/* XXX */
+
+/* Watch dog timer */
+#define WDT_WTCON 0x00 /* WDT mode */
+#define WTCON_PRESCALE_SHIFT 8
+#define WTCON_PRESCALE (0xff<<WTCON_PRESCALE_SHIFT)
+#define WTCON_ENABLE (1<<5)
+#define WTCON_CLKSEL (3<<3)
+#define WTCON_CLKSEL_16 (0<<3)
+#define WTCON_CLKSEL_32 (1<<3)
+#define WTCON_CLKSEL_64 (2<<3)
+#define WTCON_CLKSEL_128 (3<<3)
+#define WTCON_ENINT (1<<2)
+#define WTCON_ENRST (1<<0)
+
+#define WTCON_WDTSTOP 0
+
+#define WDT_WTDAT 0x04 /* timer data */
+#define WDT_WTCNT 0x08 /* timer count */
+
+#define S3C24X0_WDT_SIZE 0x0c
+
+/* IIC */
+#define S3C24X0_IIC_SIZE 0x0c
+
+
+/* IIS */
+#define S3C24X0_IIS_SIZE 0x14
+
+/* GPIO */
+#define GPIO_PACON 0x00 /* port A configuration */
+#define GPIO_PADAT 0x04 /* port A data */
+
+#define GPIO_PBCON 0x10
+/* These are only used on port B-H on 2410 & B-H,J on 2440 */
+#define PCON_INPUT 0 /* Input port */
+#define PCON_OUTPUT 1 /* Output port */
+#define PCON_ALTFUN 2 /* Alternate function */
+#define PCON_ALTFUN2 3 /* Alternate function */
+#define GPIO_PBDAT 0x14
+/* This is different between 2440 and 2442 (pull up vs pull down): */
+#define GPIO_PBUP 0x18 /* 2410 & 2440 */
+#define GPIO_PBDOWN 0x18 /* 2442 */
+
+#define GPIO_PCCON 0x20
+#define GPIO_PCDAT 0x24
+#define GPIO_PCUP 0x28 /* 2410 & 2440 */
+#define GPIO_PCDOWN 0x28 /* 2442 */
+
+#define GPIO_PDCON 0x30
+#define GPIO_PDDAT 0x34
+#define GPIO_PDUP 0x38 /* 2410 & 2440 */
+#define GPIO_PDDOWN 0x38 /* 2442 */
+
+#define GPIO_PECON 0x40
+#define PECON_INPUT(x) (0<<((x)*2)) /* Pin is used for input */
+#define PECON_OUTPUT(x) (1<<((x)*2)) /* Pin is used for output */
+#define PECON_FUNC_A(x) (2<<((x)*2)) /* Pin is used for function 'A' */
+#define PECON_FUNC_B(x) (3<<((x)*2)) /* Pin is used for function 'B' */
+#define PECON_MASK(x) (3<<((x)*2))
+#define GPIO_PEDAT 0x44
+#define GPIO_PEUP 0x48 /* 2410 & 2440 */
+#define GPIO_PEDOWN 0x48 /* 2442 */
+#define PEUD_ENABLE(x) (~(1<<(x))) /* Enable the pull Up/Down */
+#define PEUD_DISABLE(x) (1<<(x)) /* Disable the pull Up/Down */
+
+#define GPIO_PFCON 0x50
+#define GPIO_PFDAT 0x54
+#define GPIO_PFUP 0x58 /* 2410 & 2440 */
+#define GPIO_PFDOWN 0x58 /* 2442 */
+
+#define GPIO_PGCON 0x60
+#define GPIO_PGDAT 0x64
+#define GPIO_PGUP 0x68 /* 2410 & 2440 */
+#define GPIO_PGDOWN 0x68 /* 2442 */
+
+#define GPIO_PHCON 0x70
+#define GPIO_PHDAT 0x74
+#define GPIO_PHUP 0x78 /* 2410 & 2440 */
+#define GPIO_PHDOWN 0x78 /* 2442 */
+
+#define GPIO_MISCCR 0x80 /* miscellaneous control */
+#define GPIO_DCLKCON 0x84 /* DCLK 0/1 */
+#define GPIO_EXTINT(n) (0x88+4*(n)) /* external int control 0/1/2 */
+#define GPIO_EINTFLT(n) (0x94+4*(n)) /* external int filter control 0..3 */
+#define EXTINTR_LOW 0x00
+#define EXTINTR_HIGH 0x01
+#define EXTINTR_FALLING 0x02
+#define EXTINTR_RISING 0x04
+#define EXTINTR_BOTH 0x06
+#define GPIO_EINTMASK 0xa4
+#define GPIO_EINTPEND 0xa8
+#define GPIO_GSTATUS0 0xac /* external pin status */
+#define GPIO_GSTATUS1 0xb0 /* Chip ID */
+#define CHIPID_S3C2410A 0x32410002
+#define CHIPID_S3C2440A 0x32440001
+#define CHIPID_S3C2442B 0x32440AAB
+#define GPIO_GSTATUS2 0xb4 /* Reset status */
+#define GPIO_GSTATUS3 0xb8
+#define GPIO_GSTATUS4 0xbc
+
+#define GPIO_SET_FUNC(v,port,func) \
+ (((v) & ~(3<<(2*(port))))|((func)<<(2*(port))))
+
+/* ADC */
+#define ADC_ADCCON 0x00
+#define ADCCON_ENABLE_START (1<<0)
+#define ADCCON_READ_START (1<<1)
+#define ADCCON_STDBM (1<<2)
+#define ADCCON_SEL_MUX_SHIFT 3
+#define ADCCON_SEL_MUX_MASK (0x7<<ADCCON_SEL_MUX_SHIFT)
+#define ADCCON_PRSCVL_SHIFT 6
+#define ADCCON_PRSCVL_MASK (0xff<<ADCCON_PRSCVL_SHIFT)
+#define ADCCON_PRSCEN (1<<14)
+#define ADCCON_ECFLG (1<<15)
+
+#define ADC_ADCTSC 0x04
+#define ADCTSC_XY_PST 0x03
+#define ADCTSC_AUTO_PST (1<<2)
+#define ADCTSC_PULL_UP (1<<3)
+#define ADCTSC_XP_SEN (1<<4)
+#define ADCTSC_XM_SEN (1<<5)
+#define ADCTSC_YP_SEN (1<<6)
+#define ADCTSC_YM_SEN (1<<7)
+#define ADC_ADCDLY 0x08
+#define ADC_ADCDAT0 0x0c
+#define ADC_ADCDAT1 0x10
+
+#define ADCDAT_DATAMASK 0x3ff
+
+/* RTC */ /* XXX */
+
+/* SPI */
+#define S3C24X0_SPI_SIZE 0x20
+
+#define SPI_SPCON 0x00
+#define SPCON_TAGD (1<<0) /* Tx auto garbage */
+#define SPCON_CPHA (1<<1)
+#define SPCON_CPOL (1<<2)
+#define SPCON_IDLELOW_RISING (0|0)
+#define SPCON_IDLELOW_FALLING (0|SPCON_CPHA)
+#define SPCON_IDLEHIGH_FALLING (SPCON_CPOL|0)
+#define SPCON_IDLEHIGH_RISING (SPCON_CPOL|SPCON_CPHA)
+#define SPCON_MSTR (1<<3)
+#define SPCON_ENSCK (1<<4)
+#define SPCON_SMOD_SHIFT 5
+#define SPCON_SMOD_MASK (0x03<<SPCON_SMOD_SHIFT)
+#define SPCON_SMOD_POLL (0x00<<SPCON_SMOD_SHIFT)
+#define SPCON_SMOD_INT (0x01<<SPCON_SMOD_SHIFT)
+#define SPCON_SMOD_DMA (0x02<<SPCON_SMOD_SHIFT)
+
+#define SPI_SPSTA 0x04 /* status register */
+#define SPSTA_REDY (1<<0) /* ready */
+#define SPSTA_MULF (1<<1) /* multi master error */
+#define SPSTA_DCOL (1<<2) /* Data collision error */
+
+#define SPI_SPPIN 0x08
+#define SPPIN_KEEP (1<<0)
+#define SPPIN_ENMUL (1<<2) /* multi master error detect */
+
+#define SPI_SPPRE 0x0c /* prescaler */
+#define SPI_SPTDAT 0x10 /* tx data */
+#define SPI_SPRDAT 0x14 /* rx data */
+
+
+#endif /* _ARM_S3C2XX0_S3C24X0REG_H_ */
diff --git a/sys/arm/s3c2xx0/s3c24x0var.h b/sys/arm/s3c2xx0/s3c24x0var.h
new file mode 100644
index 0000000..5209da8
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c24x0var.h
@@ -0,0 +1,51 @@
+/* $NetBSD: s3c24x0var.h,v 1.1 2003/07/31 19:49:44 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003 Genetec corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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 _ARM_S3C24X0VAR_H_
+#define _ARM_S3C24X0VAR_H_
+
+#include <arm/s3c2xx0/s3c2xx0var.h>
+
+struct s3c24x0_softc {
+ struct s3c2xx0_softc sc_sx;
+
+ bus_space_handle_t sc_timer_ioh; /* Timer control registers */
+};
+
+void s3c24x0_clock_freq(struct s3c2xx0_softc *);
+void s3c2410_clock_freq2(vm_offset_t, int *, int *, int *);
+void s3c2440_clock_freq2(vm_offset_t, int *, int *, int *);
+
+void s3c24x0_sleep(int);
+
+#endif /* _ARM_S3C24X0VAR_H_ */
diff --git a/sys/arm/s3c2xx0/s3c2xx0_space.c b/sys/arm/s3c2xx0/s3c2xx0_space.c
new file mode 100644
index 0000000..2349672
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c2xx0_space.c
@@ -0,0 +1,252 @@
+/* $NetBSD: s3c2xx0_space.c,v 1.7 2005/11/24 13:08:32 yamt Exp $ */
+
+/*
+ * Copyright (c) 2002 Fujitsu Component Limited
+ * Copyright (c) 2002 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ * Genetec corporation may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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.
+ */
+/* derived from sa11x0_io.c */
+
+/*
+ * Copyright (c) 1997 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Ichiro FUKUHARA.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Brinicombe.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ */
+
+/*
+ * bus_space functions for Samsung S3C2800/2400/2410.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(s3c2xx0);
+bs_protos(generic);
+bs_protos(generic_armv4);
+
+struct bus_space s3c2xx0_bs_tag = {
+ /* cookie */
+ (void *) 0,
+
+ /* mapping/unmapping */
+ s3c2xx0_bs_map,
+ s3c2xx0_bs_unmap,
+ s3c2xx0_bs_subregion,
+
+ /* allocation/deallocation */
+ s3c2xx0_bs_alloc, /* not implemented */
+ s3c2xx0_bs_free, /* not implemented */
+
+ /* barrier */
+ s3c2xx0_bs_barrier,
+
+ /* read (single) */
+ generic_bs_r_1,
+ generic_armv4_bs_r_2,
+ generic_bs_r_4,
+ NULL,
+
+ /* read multiple */
+ generic_bs_rm_1,
+ generic_armv4_bs_rm_2,
+ generic_bs_rm_4,
+ NULL,
+
+ /* read region */
+ generic_bs_rr_1,
+ generic_armv4_bs_rr_2,
+ generic_bs_rr_4,
+ NULL,
+
+ /* write (single) */
+ generic_bs_w_1,
+ generic_armv4_bs_w_2,
+ generic_bs_w_4,
+ NULL,
+
+ /* write multiple */
+ generic_bs_wm_1,
+ generic_armv4_bs_wm_2,
+ generic_bs_wm_4,
+ NULL,
+
+ /* write region */
+ generic_bs_wr_1,
+ generic_armv4_bs_wr_2,
+ generic_bs_wr_4,
+ NULL,
+
+ /* set multiple */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ /* set region */
+ generic_bs_sr_1,
+ generic_armv4_bs_sr_2,
+ NULL,
+ NULL,
+
+ /* copy */
+ NULL,
+ generic_armv4_bs_c_2,
+ NULL,
+ NULL,
+};
+
+int
+s3c2xx0_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
+ int flag, bus_space_handle_t * bshp)
+{
+ u_long startpa, endpa, pa;
+ vm_offset_t va;
+ pt_entry_t *pte;
+ const struct pmap_devmap *pd;
+
+ if ((pd = pmap_devmap_find_pa(bpa, size)) != NULL) {
+ /* Device was statically mapped. */
+ *bshp = pd->pd_va + (bpa - pd->pd_pa);
+ return 0;
+ }
+
+ startpa = trunc_page(bpa);
+ endpa = round_page(bpa + size);
+
+ /* XXX use extent manager to check duplicate mapping */
+
+ va = kmem_alloc(kernel_map, endpa - startpa);
+ if (!va)
+ return (ENOMEM);
+
+ *bshp = (bus_space_handle_t) (va + (bpa - startpa));
+
+ for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
+ pmap_kenter(va, pa);
+ pte = vtopte(va);
+ if ((flag & BUS_SPACE_MAP_CACHEABLE) == 0)
+ *pte &= ~L2_S_CACHE_MASK;
+ }
+ return (0);
+}
+
+void
+s3c2xx0_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size)
+{
+ vm_offset_t va, endva;
+
+ if (pmap_devmap_find_va((vm_offset_t)t, size) != NULL) {
+ /* Device was statically mapped; nothing to do. */
+ return;
+ }
+
+ endva = round_page((vm_offset_t)t + size);
+ va = trunc_page((vm_offset_t)t);
+
+ while (va < endva) {
+ pmap_kremove(va);
+ va += PAGE_SIZE;
+ }
+ kmem_free(kernel_map, va, endva - va);
+}
+
+int
+s3c2xx0_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t size, bus_space_handle_t * nbshp)
+{
+
+ *nbshp = bsh + offset;
+ return (0);
+}
+
+void
+s3c2xx0_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t len, int flags)
+{
+
+ /* Nothing to do. */
+}
+
+int
+s3c2xx0_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
+ bus_size_t size, bus_size_t alignment, bus_size_t boundary,
+ int flags, bus_addr_t * bpap, bus_space_handle_t * bshp)
+{
+
+ panic("s3c2xx0_io_bs_alloc(): not implemented\n");
+}
+
+void
+s3c2xx0_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
+{
+ panic("s3c2xx0_io_bs_free(): not implemented\n");
+}
diff --git a/sys/mips/include/segments.h b/sys/arm/s3c2xx0/s3c2xx0board.h
index 406b965..8a2c631 100644
--- a/sys/mips/include/segments.h
+++ b/sys/arm/s3c2xx0/s3c2xx0board.h
@@ -1,10 +1,5 @@
/*-
- * Copyright (c) 1989, 1990 William F. Jolitz
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
+ * Copyright (c) 2008 Warner Losh. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,14 +9,11 @@
* 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.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL 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)
@@ -29,12 +21,16 @@
* 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.
- *
- * from: @(#)segments.h 7.1 (Berkeley) 5/9/91
- * $FreeBSD$
*/
-#ifndef _MACHINE_SEGMENTS_H_
-#define _MACHINE_SEGMENTS_H_
+/* $FreeBSD$ */
+
+#ifndef _ARM_S3C2XX0_S3C2XX0BOARD_H_
+#define _ARM_S3C2XX0_S3C2XX0BOARD_H_
+
+/*
+ * These routines are expected to be provided by the board files.
+ */
+long board_init(void);
-#endif /* !_MACHINE_SEGMENTS_H_ */
+#endif /* _ARM_S3C2XX0_S3C2XX0BOARD_H_ */
diff --git a/sys/arm/s3c2xx0/s3c2xx0reg.h b/sys/arm/s3c2xx0/s3c2xx0reg.h
new file mode 100644
index 0000000..627c3ca
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c2xx0reg.h
@@ -0,0 +1,139 @@
+/* $NetBSD: s3c2xx0reg.h,v 1.4 2004/02/12 03:47:29 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ * Genetec corporation may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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$
+ */
+
+
+/*
+ * Register definitions common to S3C2800 and S3C24[01]0
+ */
+#ifndef _ARM_S3C2XX0_S3C2XX0REG_H_
+#define _ARM_S3C2XX0_S3C2XX0REG_H_
+
+/* UART */
+/*
+ * S3C2800, 2410 and 2400 have a common built-in UART block. However,
+ * there are small diffs in bit position of some registers.
+ * Following definitions can be foune in s3c{2800,24x0}reg.h for
+ * that reason.
+ *
+ * ULCON_IR (Infra-red mode)
+ * ULCON_PARITY_SHIFT (Parity mode bit position)
+ * UMCON_AFC (Auto flow control)
+ * UMSTAT_DCTS (CTS change)
+ */
+
+#define SSCOM_ULCON 0x00 /* UART line control */
+/* ULCON_PARITY_SHIFT and ULCON_IR is defined in s3c{2800,24x0}reg.h */
+#define ULCON_PARITY_NONE (0<<ULCON_PARITY_SHIFT)
+#define ULCON_PARITY_ODD (4<<ULCON_PARITY_SHIFT)
+#define ULCON_PARITY_EVEN (5<<ULCON_PARITY_SHIFT)
+#define ULCON_PARITY_ONE (6<<ULCON_PARITY_SHIFT)
+#define ULCON_PARITY_ZERO (7<<ULCON_PARITY_SHIFT)
+#define ULCON_STOP (1<<2)
+#define ULCON_LENGTH_5 0
+#define ULCON_LENGTH_6 1
+#define ULCON_LENGTH_7 2
+#define ULCON_LENGTH_8 3
+#define SSCOM_UCON 0x04 /* UART control */
+#define UCON_TXINT_TYPE (1<<9) /* Tx interrupt. 0=pulse,1=level */
+#define UCON_TXINT_TYPE_LEVEL UCON_TXINT_TYPE
+#define UCON_TXINT_TYPE_PULSE 0
+#define UCON_RXINT_TYPE (1<<8) /* Rx interrupt */
+#define UCON_RXINT_TYPE_LEVEL UCON_RXINT_TYPE
+#define UCON_RXINT_TYPE_PULSE 0
+#define UCON_TOINT (1<<7) /* Rx timeout interrupt */
+#define UCON_ERRINT (1<<6) /* receive error interrupt */
+#define UCON_LOOP (1<<5) /* loopback */
+#define UCON_SBREAK (1<<4) /* send break */
+#define UCON_TXMODE_DISABLE (0<<2)
+#define UCON_TXMODE_INT (1<<2)
+#define UCON_TXMODE_DMA (2<<2)
+#define UCON_TXMODE_MASK (3<<2)
+#define UCON_RXMODE_DISABLE (0<<0)
+#define UCON_RXMODE_INT (1<<0)
+#define UCON_RXMODE_DMA (2<<0)
+#define UCON_RXMODE_MASK (3<<0)
+#define SSCOM_UFCON 0x08 /* FIFO control */
+#define UFCON_TXTRIGGER_0 (0<<6)
+#define UFCON_TXTRIGGER_4 (1<<6)
+#define UFCON_TXTRIGGER_8 (2<<6)
+#define UFCON_TXTRIGGER_16 (3<<6)
+#define UFCON_RXTRIGGER_4 (0<<4)
+#define UFCON_RXTRIGGER_8 (1<<4)
+#define UFCON_RXTRIGGER_12 (2<<4)
+#define UFCON_RXTRIGGER_16 (3<<4)
+#define UFCON_TXFIFO_RESET (1<<2)
+#define UFCON_RXFIFO_RESET (1<<1)
+#define UFCON_FIFO_ENABLE (1<<0)
+#define SSCOM_UMCON 0x0c /* MODEM control */
+/* UMCON_AFC is defined in s3c{2800,24x0}reg.h */
+#define UMCON_RTS (1<<0) /* Request to send */
+#define SSCOM_UTRSTAT 0x10 /* Status register */
+#define UTRSTAT_TXSHIFTER_EMPTY (1<<2)
+#define UTRSTAT_TXEMPTY (1<<1) /* TX fifo or buffer empty */
+#define UTRSTAT_RXREADY (1<<0) /* RX fifo or buffer is not empty */
+#define SSCOM_UERSTAT 0x14 /* Error status register */
+#define UERSTAT_BREAK (1<<3) /* Break signal, not 2410 */
+#define UERSTAT_FRAME (1<<2) /* Frame error */
+#define UERSTAT_PARITY (1<<1) /* Parity error, not 2410 */
+#define UERSTAT_OVERRUN (1<<0) /* Overrun */
+#define UERSTAT_ALL_ERRORS \
+ (UERSTAT_OVERRUN|UERSTAT_BREAK|UERSTAT_FRAME|UERSTAT_PARITY)
+#define SSCOM_UFSTAT 0x18 /* Fifo status register */
+#define UFSTAT_TXFULL (1<<9) /* Tx fifo full */
+#define UFSTAT_RXFULL (1<<8) /* Rx fifo full */
+#define UFSTAT_TXCOUNT_SHIFT 4 /* TX FIFO count */
+#define UFSTAT_TXCOUNT (0x0f<<UFSTAT_TXCOUNT_SHIFT)
+#define UFSTAT_RXCOUNT_SHIFT 0 /* RX FIFO count */
+#define UFSTAT_RXCOUNT (0x0f<<UFSTAT_RXCOUNT_SHIFT)
+#define SSCOM_UMSTAT 0x1c /* Modem status register */
+/* UMSTAT_DCTS is defined in s3c{2800,24x0}reg.h */
+#define UMSTAT_CTS (1<<0) /* Clear to send */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define SSCOM_UTXH 0x20 /* Transmit data register */
+#define SSCOM_URXH 0x24 /* Receive data register */
+#else
+#define SSCOM_UTXH 0x23 /* Transmit data register */
+#define SSCOM_URXH 0x27 /* Receive data register */
+#endif
+#define SSCOM_UBRDIV 0x28 /* baud-reate divisor */
+#define SSCOM_SIZE 0x2c
+
+/* Interrupt controller (Common to S3c2800/2400X/2410X) */
+#define INTCTL_SRCPND 0x00 /* Interrupt request status */
+#define INTCTL_INTMOD 0x04 /* Interrupt mode (FIQ/IRQ) */
+#define INTCTL_INTMSK 0x08 /* Interrupt mask */
+
+#endif /* _ARM_S3C2XX0_S3C2XX0REG_H_ */
diff --git a/sys/arm/s3c2xx0/s3c2xx0var.h b/sys/arm/s3c2xx0/s3c2xx0var.h
new file mode 100644
index 0000000..fea800e
--- /dev/null
+++ b/sys/arm/s3c2xx0/s3c2xx0var.h
@@ -0,0 +1,89 @@
+/* $NetBSD: s3c2xx0var.h,v 1.3 2003/08/05 11:26:54 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002 Fujitsu Component Limited
+ * Copyright (c) 2002 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ * Genetec corporation may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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 _ARM_S3C2XX0VAR_H_
+#define _ARM_S3C2XX0VAR_H_
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+typedef enum {
+ CPU_S3C2410,
+ CPU_S3C2440,
+} s3c2xx0_cpu;
+
+struct s3c2xx0_softc {
+ device_t sc_dev;
+
+ s3c2xx0_cpu sc_cpu;
+
+ bus_space_tag_t sc_iot;
+
+ bus_space_handle_t sc_intctl_ioh;
+ bus_space_handle_t sc_clkman_ioh; /* Clock manager */
+ bus_space_handle_t sc_gpio_ioh; /* GPIO */
+ bus_space_handle_t sc_lcd_ioh; /* LCD */
+ bus_space_handle_t sc_rtc_ioh; /* real time clock */
+ bus_space_handle_t sc_mci_ioh; /* MMC/SD */
+ bus_space_handle_t sc_iic_ioh; /* IIC */
+ bus_space_handle_t sc_ohci_ioh; /* USB/OHCI */
+ bus_space_handle_t sc_wdt_ioh; /* Watchdog Timer */
+
+ bus_dma_tag_t sc_dmat;
+
+ /* clock frequency */
+ int sc_fclk; /* CPU clock */
+ int sc_hclk; /* AHB bus clock */
+ int sc_pclk; /* peripheral clock */
+
+ struct rman s3c2xx0_irq_rman;
+ struct rman s3c2xx0_mem_rman;
+};
+
+struct s3c2xx0_ivar {
+ struct resource_list resources;
+};
+
+typedef void *s3c2xx0_chipset_tag_t;
+
+extern struct bus_space s3c2xx0_bs_tag;
+extern struct s3c2xx0_softc *s3c2xx0_softc;
+extern struct arm32_bus_dma_tag s3c2xx0_bus_dma;
+
+/* Platform needs to provide this */
+bus_dma_tag_t s3c2xx0_bus_dma_init(struct arm32_bus_dma_tag *);
+
+#endif /* _ARM_S3C2XX0VAR_H_ */
diff --git a/sys/arm/s3c2xx0/std.ln2410sbc b/sys/arm/s3c2xx0/std.ln2410sbc
new file mode 100644
index 0000000..e066fc2
--- /dev/null
+++ b/sys/arm/s3c2xx0/std.ln2410sbc
@@ -0,0 +1,10 @@
+#$FreeBSD$
+include "../s3c2xx0/std.s3c2410"
+
+makeoptions KERNPHYSADDR=0x30408000
+makeoptions KERNVIRTADDR=0xc0408000
+options KERNPHYSADDR=0x30408000
+options KERNVIRTADDR=0xc0408000
+options PHYSADDR=0x30000000
+options STARTUP_PAGETABLE_ADDR=0x30800000
+
diff --git a/sys/arm/s3c2xx0/std.s3c2410 b/sys/arm/s3c2xx0/std.s3c2410
new file mode 100644
index 0000000..31ec680
--- /dev/null
+++ b/sys/arm/s3c2xx0/std.s3c2410
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+files "../s3c2xx0/files.s3c2xx0"
+cpu CPU_ARM9
+
+makeoptions CONF_CFLAGS=-mcpu=arm920t
diff --git a/sys/arm/s3c2xx0/uart_bus_s3c2410.c b/sys/arm/s3c2xx0/uart_bus_s3c2410.c
new file mode 100644
index 0000000..974b3d9
--- /dev/null
+++ b/sys/arm/s3c2xx0/uart_bus_s3c2410.c
@@ -0,0 +1,59 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/s3c2xx0/s3c24x0reg.h>
+
+#include "uart_if.h"
+
+static int uart_s3c2410_probe(device_t dev);
+
+static device_method_t uart_s3c2410_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, uart_s3c2410_probe),
+ DEVMETHOD(device_attach, uart_bus_attach),
+ DEVMETHOD(device_detach, uart_bus_detach),
+ { 0, 0 }
+};
+
+static driver_t uart_s3c2410_driver = {
+ uart_driver_name,
+ uart_s3c2410_methods,
+ sizeof(struct uart_softc),
+};
+
+extern struct uart_class uart_s3c2410_class;
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+static int
+uart_s3c2410_probe(device_t dev)
+{
+ struct uart_devinfo *sysdev;
+ struct uart_softc *sc;
+ int unit;
+
+ sc = device_get_softc(dev);
+ sc->sc_class = &uart_s3c2410_class;
+
+ unit = device_get_unit(dev);
+ sysdev = SLIST_FIRST(&uart_sysdevs);
+ if (S3C24X0_UART_BASE(unit) == sysdev->bas.bsh) {
+ sc->sc_sysdev = sysdev;
+ bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+ }
+ return(uart_bus_probe(dev, 0, 0, 0, unit));
+}
+
+DRIVER_MODULE(uart, s3c24x0, uart_s3c2410_driver, uart_devclass, 0, 0);
diff --git a/sys/arm/s3c2xx0/uart_cpu_s3c2410.c b/sys/arm/s3c2xx0/uart_cpu_s3c2410.c
new file mode 100644
index 0000000..835604b
--- /dev/null
+++ b/sys/arm/s3c2xx0/uart_cpu_s3c2410.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2007 Andrew Turner
+ * 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 ``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 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/s3c2xx0/s3c2xx0var.h>
+
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+extern struct uart_ops uart_s3c2410_ops;
+
+vm_offset_t s3c2410_uart_vaddr;
+unsigned int s3c2410_pclk;
+
+extern struct uart_class uart_s3c2410_class;
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+ return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+ if (devtype != UART_DEV_CONSOLE)
+ return (ENXIO);
+
+ di->ops = uart_getops(&uart_s3c2410_class);
+ di->bas.chan = 0;
+ di->bas.bst = &s3c2xx0_bs_tag;
+ di->bas.bsh = s3c2410_uart_vaddr;
+ di->bas.regshft = 0;
+ di->bas.rclk = s3c2410_pclk;
+ di->baudrate = 115200;
+ di->databits = 8;
+ di->stopbits = 1;
+ di->parity = UART_PARITY_NONE;
+ uart_bus_space_io = &s3c2xx0_bs_tag;
+ uart_bus_space_mem = NULL;
+
+ return (0);
+}
diff --git a/sys/arm/s3c2xx0/uart_dev_s3c2410.c b/sys/arm/s3c2xx0/uart_dev_s3c2410.c
new file mode 100644
index 0000000..9bd9c4b
--- /dev/null
+++ b/sys/arm/s3c2xx0/uart_dev_s3c2410.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2007-2009 Andrew Turner
+ * 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 ``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 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/tty.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_bus.h>
+#include <arm/s3c2xx0/s3c2440reg.h>
+#include <arm/s3c2xx0/uart_dev_s3c2410.h>
+#include <arm/s3c2xx0/s3c2xx0reg.h>
+#include <arm/s3c2xx0/s3c2xx0var.h>
+#include "uart_if.h"
+
+/* Finds the subirq from the parent */
+#define get_sub_irq(parent, offset) \
+ ((parent == S3C24X0_INT_UART0) ? S3C24X0_SUBIRQ_MIN + offset : \
+ ((parent == S3C24X0_INT_UART1) ? S3C24X0_SUBIRQ_MIN + 3 + offset : \
+ S3C24X0_SUBIRQ_MIN + 6 + offset))
+#define RX_OFF 0
+#define TX_OFF 1
+#define ERR_OFF 2
+
+extern unsigned int s3c2410_pclk;
+
+static int sscomspeed(long, long);
+static int s3c24x0_uart_param(struct uart_bas *, int, int, int, int);
+
+/*
+ * Low-level UART interface.
+ */
+static int s3c2410_probe(struct uart_bas *bas);
+static void s3c2410_init(struct uart_bas *bas, int, int, int, int);
+static void s3c2410_term(struct uart_bas *bas);
+static void s3c2410_putc(struct uart_bas *bas, int);
+static int s3c2410_rxready(struct uart_bas *bas);
+static int s3c2410_getc(struct uart_bas *bas, struct mtx *mtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+sscomspeed(long speed, long frequency)
+{
+ int x;
+
+ if (speed <= 0 || frequency <= 0)
+ return -1;
+ x = (frequency / 16) / speed;
+ return x-1;
+}
+
+static int
+s3c24x0_uart_param(struct uart_bas *bas, int baudrate, int databits,
+ int stopbits, int parity)
+{
+ int brd, ulcon;
+
+ ulcon = 0;
+
+ switch(databits) {
+ case 5:
+ ulcon |= ULCON_LENGTH_5;
+ break;
+ case 6:
+ ulcon |= ULCON_LENGTH_6;
+ break;
+ case 7:
+ ulcon |= ULCON_LENGTH_7;
+ break;
+ case 8:
+ ulcon |= ULCON_LENGTH_8;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ switch (parity) {
+ case UART_PARITY_NONE:
+ ulcon |= ULCON_PARITY_NONE;
+ break;
+ case UART_PARITY_ODD:
+ ulcon |= ULCON_PARITY_ODD;
+ break;
+ case UART_PARITY_EVEN:
+ ulcon |= ULCON_PARITY_EVEN;
+ break;
+ case UART_PARITY_MARK:
+ case UART_PARITY_SPACE:
+ default:
+ return (EINVAL);
+ }
+
+ if (stopbits == 2)
+ ulcon |= ULCON_STOP;
+
+ uart_setreg(bas, SSCOM_ULCON, ulcon);
+
+ brd = sscomspeed(baudrate, bas->rclk);
+ uart_setreg(bas, SSCOM_UBRDIV, brd);
+
+ return (0);
+}
+
+struct uart_ops uart_s3c2410_ops = {
+ .probe = s3c2410_probe,
+ .init = s3c2410_init,
+ .term = s3c2410_term,
+ .putc = s3c2410_putc,
+ .rxready = s3c2410_rxready,
+ .getc = s3c2410_getc,
+};
+
+static int
+s3c2410_probe(struct uart_bas *bas)
+{
+ return (0);
+}
+
+static void
+s3c2410_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+ int parity)
+{
+ if (bas->rclk == 0)
+ bas->rclk = s3c2410_pclk;
+ KASSERT(bas->rclk != 0, ("s3c2410_init: Invalid rclk"));
+
+ uart_setreg(bas, SSCOM_UCON, 0);
+ uart_setreg(bas, SSCOM_UFCON,
+ UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
+ UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
+ UFCON_FIFO_ENABLE);
+ s3c24x0_uart_param(bas, baudrate, databits, stopbits, parity);
+
+ /* Enable UART. */
+ uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT |
+ UCON_TOINT);
+ uart_setreg(bas, SSCOM_UMCON, UMCON_RTS);
+}
+
+static void
+s3c2410_term(struct uart_bas *bas)
+{
+ /* XXX */
+}
+
+static void
+s3c2410_putc(struct uart_bas *bas, int c)
+{
+ while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) &
+ UFSTAT_TXFULL) == UFSTAT_TXFULL)
+ continue;
+
+ uart_setreg(bas, SSCOM_UTXH, c);
+}
+
+static int
+s3c2410_rxready(struct uart_bas *bas)
+{
+ return ((uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_RXREADY) ==
+ UTRSTAT_RXREADY);
+}
+
+static int
+s3c2410_getc(struct uart_bas *bas, struct mtx *mtx)
+{
+ while (!sscom_rxrdy(bas->bst, bas->bsh))
+ continue;
+
+ return sscom_getc(bas->bst, bas->bsh);
+}
+
+static int s3c2410_bus_probe(struct uart_softc *sc);
+static int s3c2410_bus_attach(struct uart_softc *sc);
+static int s3c2410_bus_flush(struct uart_softc *, int);
+static int s3c2410_bus_getsig(struct uart_softc *);
+static int s3c2410_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int s3c2410_bus_ipend(struct uart_softc *);
+static int s3c2410_bus_param(struct uart_softc *, int, int, int, int);
+static int s3c2410_bus_receive(struct uart_softc *);
+static int s3c2410_bus_setsig(struct uart_softc *, int);
+static int s3c2410_bus_transmit(struct uart_softc *);
+
+static kobj_method_t s3c2410_methods[] = {
+ KOBJMETHOD(uart_probe, s3c2410_bus_probe),
+ KOBJMETHOD(uart_attach, s3c2410_bus_attach),
+ KOBJMETHOD(uart_flush, s3c2410_bus_flush),
+ KOBJMETHOD(uart_getsig, s3c2410_bus_getsig),
+ KOBJMETHOD(uart_ioctl, s3c2410_bus_ioctl),
+ KOBJMETHOD(uart_ipend, s3c2410_bus_ipend),
+ KOBJMETHOD(uart_param, s3c2410_bus_param),
+ KOBJMETHOD(uart_receive, s3c2410_bus_receive),
+ KOBJMETHOD(uart_setsig, s3c2410_bus_setsig),
+ KOBJMETHOD(uart_transmit, s3c2410_bus_transmit),
+
+ {0, 0 }
+};
+
+int
+s3c2410_bus_probe(struct uart_softc *sc)
+{
+ return (0);
+}
+
+static int
+s3c2410_bus_attach(struct uart_softc *sc)
+{
+ uintptr_t irq;
+
+ switch(s3c2xx0_softc->sc_cpu) {
+ case CPU_S3C2410:
+ sc->sc_txfifosz = 16;
+ sc->sc_rxfifosz = 16;
+ break;
+ case CPU_S3C2440:
+ sc->sc_txfifosz = 64;
+ sc->sc_rxfifosz = 64;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ sc->sc_hwiflow = 0;
+ sc->sc_hwoflow = 0;
+
+ irq = rman_get_start(sc->sc_ires);
+ arm_unmask_irq(irq);
+ arm_unmask_irq(get_sub_irq(irq, RX_OFF));
+ arm_unmask_irq(get_sub_irq(irq, TX_OFF));
+ arm_unmask_irq(get_sub_irq(irq, ERR_OFF));
+
+ return (0);
+}
+
+static int
+s3c2410_bus_transmit(struct uart_softc *sc)
+{
+ uintptr_t irq;
+
+ uart_lock(sc->sc_hwmtx);
+
+ for (int i = 0; i < sc->sc_txdatasz; i++) {
+ s3c2410_putc(&sc->sc_bas, sc->sc_txbuf[i]);
+ uart_barrier(&sc->sc_bas);
+ }
+
+ sc->sc_txbusy = 1;
+
+ uart_unlock(sc->sc_hwmtx);
+
+ irq = rman_get_start(sc->sc_ires);
+ arm_unmask_irq(get_sub_irq(irq, TX_OFF));
+
+ return (0);
+}
+
+static int
+s3c2410_bus_setsig(struct uart_softc *sc, int sig)
+{
+ return (0);
+}
+
+static int
+s3c2410_bus_receive(struct uart_softc *sc)
+{
+
+ uart_rx_put(sc, uart_getreg(&sc->sc_bas, SSCOM_URXH));
+ return (0);
+}
+
+static int
+s3c2410_bus_param(struct uart_softc *sc, int baudrate, int databits,
+ int stopbits, int parity)
+{
+ int error;
+
+ if (sc->sc_bas.rclk == 0)
+ sc->sc_bas.rclk = s3c2410_pclk;
+ KASSERT(sc->sc_bas.rclk != 0, ("s3c2410_init: Invalid rclk"));
+
+ uart_lock(sc->sc_hwmtx);
+ error = s3c24x0_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
+ parity);
+ uart_unlock(sc->sc_hwmtx);
+
+ return (error);
+}
+
+static int
+s3c2410_bus_ipend(struct uart_softc *sc)
+{
+ uint32_t ufstat, txmask, rxmask;
+ uintptr_t irq;
+ int ipend = 0;
+
+ uart_lock(sc->sc_hwmtx);
+ ufstat = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UFSTAT);
+ uart_unlock(sc->sc_hwmtx);
+
+ txmask = rxmask = 0;
+ switch (s3c2xx0_softc->sc_cpu) {
+ case CPU_S3C2410:
+ txmask = UFSTAT_TXCOUNT;
+ rxmask = UFSTAT_RXCOUNT;
+ break;
+ case CPU_S3C2440:
+ txmask = S3C2440_UFSTAT_TXCOUNT;
+ rxmask = S3C2440_UFSTAT_RXCOUNT;
+ break;
+ }
+ if ((ufstat & txmask) == 0) {
+ if (sc->sc_txbusy != 0)
+ ipend |= SER_INT_TXIDLE;
+ irq = rman_get_start(sc->sc_ires);
+ arm_mask_irq(get_sub_irq(irq, TX_OFF));
+ }
+ if ((ufstat & rxmask) > 0) {
+ ipend |= SER_INT_RXREADY;
+ }
+
+ return (ipend);
+}
+
+static int
+s3c2410_bus_flush(struct uart_softc *sc, int what)
+{
+ return (0);
+}
+
+static int
+s3c2410_bus_getsig(struct uart_softc *sc)
+{
+ return (0);
+}
+
+static int
+s3c2410_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+ return (EINVAL);
+}
+
+struct uart_class uart_s3c2410_class = {
+ "s3c2410 class",
+ s3c2410_methods,
+ 1,
+ .uc_ops = &uart_s3c2410_ops,
+ .uc_range = 8,
+ .uc_rclk = 0,
+};
diff --git a/sys/arm/s3c2xx0/uart_dev_s3c2410.h b/sys/arm/s3c2xx0/uart_dev_s3c2410.h
new file mode 100644
index 0000000..5479796
--- /dev/null
+++ b/sys/arm/s3c2xx0/uart_dev_s3c2410.h
@@ -0,0 +1,88 @@
+/* $NetBSD: sscom_var.h,v 1.5 2003/08/04 12:28:49 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ * Genetec corporation may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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.
+ */
+/* derived from sys/dev/ic/comvar.h */
+
+/*-
+ * Copyright (c) 1996 Christopher G. Demetriou. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _ARM_S3C2XX0_SSCOM_VAR_H
+#define _ARM_S3C2XX0_SSCOM_VAR_H
+
+
+/* Hardware flag masks */
+#define SSCOM_HW_FLOW 0x02
+#define SSCOM_HW_DEV_OK 0x04
+#define SSCOM_HW_CONSOLE 0x08
+#define SSCOM_HW_KGDB 0x10
+#define SSCOM_HW_TXINT 0x20
+#define SSCOM_HW_RXINT 0x40
+
+/* Buffer size for character buffer */
+#define SSCOM_RING_SIZE 2048
+
+#define sscom_rxrdy(iot,ioh) \
+ (bus_space_read_1((iot), (ioh), SSCOM_UTRSTAT) & UTRSTAT_RXREADY)
+#define sscom_getc(iot,ioh) bus_space_read_1((iot), (ioh), SSCOM_URXH)
+#define sscom_geterr(iot,ioh) bus_space_read_1((iot), (ioh), SSCOM_UERSTAT)
+
+#endif /* _ARM_S3C2XX0_SSCOM_VAR_H */
diff --git a/sys/arm/xscale/ixp425/cambria_fled.c b/sys/arm/xscale/ixp425/cambria_fled.c
index 7f678c8..c2f214d 100644
--- a/sys/arm/xscale/ixp425/cambria_fled.c
+++ b/sys/arm/xscale/ixp425/cambria_fled.c
@@ -74,7 +74,7 @@ fled_attach(device_t dev)
sc->sc_led = led_create(fled_cb, dev, "front");
- fled_cb(sc, 1); /* Turn on LED */
+ fled_cb(dev, 1); /* Turn on LED */
return 0;
}
diff --git a/sys/boot/arm/at91/boot2/bwct_board.c b/sys/boot/arm/at91/boot2/bwct_board.c
index 20f4140..fffdd2a 100644
--- a/sys/boot/arm/at91/boot2/bwct_board.c
+++ b/sys/boot/arm/at91/boot2/bwct_board.c
@@ -21,7 +21,7 @@ static void DS1672_Init();
static void
DS1672_Init() {
- uint8_t buf[] = {0x00, 0xa9};
+ char buf[] = {0x00, 0xa9};
EEWrite(0xd0, buf, sizeof(buf));
}
@@ -90,7 +90,11 @@ board_init(void)
printf("BWCT FSB-A920-1\n");
printf("http://www.bwct.de\n");
printf("\n");
- printf("AT92RM9200 180MHz\n");
+#if defined(SDRAM_128M)
+ printf("AT92RM9200 180MHz 128MB\n");
+#else
+ printf("AT92RM9200 180MHz 64MB\n");
+#endif
printf("Initialising USART0\n");
USART0_Init();
printf("Initialising USART1\n");
diff --git a/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c b/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c
index 77c1124..fb9d9c6 100644
--- a/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c
+++ b/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c
@@ -136,7 +136,7 @@ _init(void)
AT91C_BASE_EBI->EBI_CSA = value;
AT91C_BASE_SDRC->SDRC_CR =
-#ifdef KB9202_B
+#if defined(KB9202_B) || defined(SDRAM_128M)
AT91C_SDRC_NC_10 |
#else
AT91C_SDRC_NC_9 |
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
index d7f1323..e0e4409 100644
--- a/sys/boot/forth/loader.conf
+++ b/sys/boot/forth/loader.conf
@@ -271,6 +271,7 @@ if_rl_load="NO" # RealTek 8129/8139
if_rue_load="NO" # RealTek RTL8150 USB to Fast Ethernet
if_sbni_load="NO" # Granch SBNI12 leased line adapters
if_sf_load="NO" # Adaptec Duralink PCI (AIC-6915 "starfire")
+if_sge_load="NO" # Silicon Integrated Systems SiS190/191
if_sis_load="NO" # Silicon Integrated Systems SiS 900/7016
if_sk_load="NO" # SysKonnect SK-984x series PCI Gigabit Ethernet
if_sn_load="NO" # SMC 91Cxx
diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c
index 58f2175..f521fd7 100644
--- a/sys/boot/i386/boot2/boot2.c
+++ b/sys/boot/i386/boot2/boot2.c
@@ -283,7 +283,7 @@ main(void)
for (;;) {
if (!autoboot || !OPT_CHECK(RBX_QUIET))
- printf("\nFreeBSD/i386 boot\n"
+ printf("\nFreeBSD/x86 boot\n"
"Default: %u:%s(%u,%c)%s\n"
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
diff --git a/sys/boot/i386/efi/Makefile b/sys/boot/i386/efi/Makefile
new file mode 100644
index 0000000..2d11046
--- /dev/null
+++ b/sys/boot/i386/efi/Makefile
@@ -0,0 +1,69 @@
+# $FreeBSD$
+
+NO_MAN=
+WITHOUT_SSP=
+BUILDING_EFI=
+
+.include <bsd.own.mk>
+
+PROG= loader.sym
+INTERNALPROG=
+
+# architecture-specific loader code
+SRCS= main.c exec.c conf.c vers.c reloc.c start.S elf32_freebsd.c
+SRCS+= i386_copy.c bootinfo.c autoload.c devicename.c efimd.c
+
+CFLAGS+= -I${.CURDIR}/../../efi/include
+CFLAGS+= -I${.CURDIR}/../../efi/include/i386
+
+.if ${MK_FORTH} != "no"
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH
+CFLAGS+= -I${.CURDIR}/../../ficl
+CFLAGS+= -I${.CURDIR}/../../ficl/i386
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.endif
+
+# Include bcache code.
+HAVE_BCACHE= yes
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../common
+
+FILES= loader.efi
+FILESMODE_loader.efi= ${BINMODE}
+
+LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_ARCH}
+LDFLAGS= -Wl,-T${LDSCRIPT} -shared -symbolic
+
+${PROG}: ${LDSCRIPT}
+
+CLEANFILES= vers.c loader.efi
+
+NEWVERSWHAT= "EFI loader" ${MACHINE_ARCH}
+
+vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+
+OBJCOPY?= objcopy
+OBJDUMP?= objdump
+
+loader.efi: loader.sym
+ if [ `${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*' | wc -l` != 0 ]; then \
+ ${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
+ exit 1; \
+ fi
+ ${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
+ -j .rel.dyn -j .reloc -j .sdata -j .text -j set_Xcommand_set \
+ --target=efi-app-ia32 ${.ALLSRC} ${.TARGET}
+
+LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a
+CFLAGS+= -I${.CURDIR}/../libi386
+CFLAGS+= -I${.CURDIR}/../btx/lib
+
+DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBEFI} -lstand
+
+.include <bsd.prog.mk>
diff --git a/crypto/openssh/scard.h b/sys/boot/i386/efi/autoload.c
index 82efe48..26370d6 100644
--- a/crypto/openssh/scard.h
+++ b/sys/boot/i386/efi/autoload.c
@@ -1,11 +1,11 @@
-/* $OpenBSD: scard.h,v 1.14 2006/08/03 03:34:42 deraadt Exp $ */
-
-/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@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
@@ -24,16 +24,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SCARD_H
-#define SCARD_H
-
-#define SCARD_ERROR_FAIL -1
-#define SCARD_ERROR_NOCARD -2
-#define SCARD_ERROR_APPLET -3
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
-Key **sc_get_keys(const char *, const char *);
-void sc_close(void);
-int sc_put_key(Key *, const char *);
-char *sc_get_key_label(Key *);
+int
+i386_autoload(void)
+{
-#endif
+ return (0);
+}
diff --git a/sys/boot/i386/efi/bootinfo.c b/sys/boot/i386/efi/bootinfo.c
new file mode 100644
index 0000000..b3a3fa9
--- /dev/null
+++ b/sys/boot/i386/efi/bootinfo.c
@@ -0,0 +1,297 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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 <stand.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "libi386.h"
+#include <machine/bootinfo.h>
+
+/*
+ * Return a 'boothowto' value corresponding to the kernel arguments in
+ * (kargs) and any relevant environment variables.
+ */
+static struct
+{
+ const char *ev;
+ int mask;
+} howto_names[] = {
+ { "boot_askname", RB_ASKNAME},
+ { "boot_cdrom", RB_CDROM},
+ { "boot_ddb", RB_KDB},
+ { "boot_dfltroot", RB_DFLTROOT},
+ { "boot_gdb", RB_GDB},
+ { "boot_multicons", RB_MULTIPLE},
+ { "boot_mute", RB_MUTE},
+ { "boot_pause", RB_PAUSE},
+ { "boot_serial", RB_SERIAL},
+ { "boot_single", RB_SINGLE},
+ { "boot_verbose", RB_VERBOSE},
+ { NULL, 0}
+};
+
+static const char howto_switches[] = "aCdrgDmphsv";
+static int howto_masks[] = {
+ RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
+ RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
+};
+
+int
+bi_getboothowto(char *kargs)
+{
+ const char *sw;
+ char *opts;
+ int howto, i;
+
+ howto = 0;
+
+ /* Get the boot options from the environment first. */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ }
+
+ /* Parse kargs */
+ if (kargs == NULL)
+ return (howto);
+
+ opts = strchr(kargs, '-');
+ while (opts != NULL) {
+ while (*(++opts) != '\0') {
+ sw = strchr(howto_switches, *opts);
+ if (sw == NULL)
+ break;
+ howto |= howto_masks[sw - howto_switches];
+ }
+ opts = strchr(opts, '-');
+ }
+
+ return (howto);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+bi_copyenv(vm_offset_t start)
+{
+ struct env_var *ep;
+ vm_offset_t addr, last;
+ size_t len;
+
+ addr = last = start;
+
+ /* Traverse the environment. */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ len = strlen(ep->ev_name);
+ if (i386_copyin(ep->ev_name, addr, len) != len)
+ break;
+ addr += len;
+ if (i386_copyin("=", addr, 1) != 1)
+ break;
+ addr++;
+ if (ep->ev_value != NULL) {
+ len = strlen(ep->ev_value);
+ if (i386_copyin(ep->ev_value, addr, len) != len)
+ break;
+ addr += len;
+ }
+ if (i386_copyin("", addr, 1) != 1)
+ break;
+ last = ++addr;
+ }
+
+ if (i386_copyin("", last++, 1) != 1)
+ last = start;
+ return(last);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a) { \
+ u_int32_t x = (v); \
+ i386_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s) { \
+ COPY32(t, a); \
+ COPY32(strlen(s) + 1, a); \
+ i386_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
+}
+
+#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
+#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
+#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s)
+
+#define MOD_VAR(t, a, s) { \
+ COPY32(t, a); \
+ COPY32(sizeof(s), a); \
+ i386_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_int64_t)); \
+}
+
+#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
+#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
+
+#define MOD_METADATA(a, mm) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a); \
+ COPY32(mm->md_size, a); \
+ i386_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_int64_t));\
+}
+
+#define MOD_END(a) { \
+ COPY32(MODINFO_END, a); \
+ COPY32(0, a); \
+}
+
+vm_offset_t
+bi_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+
+ /* Start with the first module on the list, should be the kernel. */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+ /* The name field must come first. */
+ MOD_NAME(addr, fp->f_name);
+ MOD_TYPE(addr, fp->f_type);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args);
+ MOD_ADDR(addr, fp->f_addr);
+ MOD_SIZE(addr, fp->f_size);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next) {
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md);
+ }
+ }
+ MOD_END(addr);
+ return(addr);
+}
+
+/*
+ * Load the information expected by the kernel.
+ *
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(struct preloaded_file *fp, uint64_t *bi_addr)
+{
+ struct bootinfo bi;
+ struct preloaded_file *xp;
+ struct file_metadata *md;
+ struct devdesc *rootdev;
+ char *rootdevname;
+ vm_offset_t addr, ssym, esym;
+
+ bzero(&bi, sizeof(struct bootinfo));
+ bi.bi_version = 1;
+// bi.bi_boothowto = bi_getboothowto(fp->f_args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied
+ * device. This should perhaps go to MI code and/or have $rootdev
+ * tested/set by MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ i386_getdev((void**)&rootdev, rootdevname, NULL);
+ if (rootdev != NULL) {
+ /* Try reading /etc/fstab to select the root device. */
+ getrootmount(i386_fmtdev(rootdev));
+ free(rootdev);
+ }
+
+ md = file_findmetadata(fp, MODINFOMD_SSYM);
+ ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
+ md = file_findmetadata(fp, MODINFOMD_ESYM);
+ esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
+ if (ssym != 0 && esym != 0) {
+ bi.bi_symtab = ssym;
+ bi.bi_esymtab = esym;
+ }
+
+ /* Find the last module in the chain. */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+
+ addr = (addr + 15) & ~15;
+
+ /* Copy module list and metadata. */
+ bi.bi_modulep = addr;
+ addr = bi_copymodules(addr);
+ if (addr <= bi.bi_modulep) {
+ addr = bi.bi_modulep;
+ bi.bi_modulep = 0;
+ }
+
+ addr = (addr + 15) & ~15;
+
+ /* Copy our environment. */
+ bi.bi_envp = addr;
+ addr = bi_copyenv(addr);
+ if (addr <= bi.bi_envp) {
+ addr = bi.bi_envp;
+ bi.bi_envp = 0;
+ }
+
+ addr = (addr + PAGE_MASK) & ~PAGE_MASK;
+ bi.bi_kernend = addr;
+
+ return (ldr_bootinfo(&bi, bi_addr));
+}
diff --git a/sys/boot/i386/efi/conf.c b/sys/boot/i386/efi/conf.c
new file mode 100644
index 0000000..13c2145
--- /dev/null
+++ b/sys/boot/i386/efi/conf.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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 ``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 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 <stand.h>
+#include <bootstrap.h>
+#include <efi.h>
+#include <efilib.h>
+
+struct devsw *devsw[] = {
+ &efipart_dev,
+ &efinet_dev,
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+ &dosfs_fsops,
+ &ufs_fsops,
+ &cd9660_fsops,
+ &nfs_fsops,
+ &gzipfs_fsops,
+ NULL
+};
+
+struct netif_driver *netif_drivers[] = {
+ &efinetif,
+ NULL
+};
+
+#ifdef notyet
+extern struct file_format amd64_elf;
+extern struct file_format amd64_elf_obj;
+#endif
+extern struct file_format i386_elf;
+extern struct file_format i386_elf_obj;
+
+struct file_format *file_formats[] = {
+#ifdef notyet
+ &amd64_elf,
+ &amd64_elf_obj,
+#endif
+ &i386_elf,
+ &i386_elf_obj,
+ NULL
+};
+
+extern struct console efi_console;
+
+struct console *consoles[] = {
+ &efi_console,
+ NULL
+};
diff --git a/sys/boot/i386/efi/devicename.c b/sys/boot/i386/efi/devicename.c
new file mode 100644
index 0000000..c3d9062
--- /dev/null
+++ b/sys/boot/i386/efi/devicename.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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 <stand.h>
+#include <string.h>
+#include <sys/disklabel.h>
+#include "bootstrap.h"
+
+#include <efi.h>
+#include <efilib.h>
+
+static int i386_parsedev(struct devdesc **, const char *, const char **);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+i386_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct devdesc **dev = (struct devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no device, then
+ * use the current device instead.
+ */
+ if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
+ rv = i386_parsedev(dev, getenv("currdev"), NULL);
+ if (rv == 0 && path != NULL)
+ *path = devspec;
+ return (rv);
+ }
+
+ /* Parse the device name off the beginning of the devspec. */
+ return (i386_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * fs<unit>:
+ */
+static int
+i386_parsedev(struct devdesc **dev, const char *devspec, const char **path)
+{
+ struct devdesc *idev;
+ struct devsw *dv;
+ char *cp;
+ const char *np;
+ int i, err;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return (EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0; devsw[i] != NULL; i++) {
+ dv = devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
+ break;
+ }
+ if (devsw[i] == NULL)
+ return (ENOENT);
+
+ idev = malloc(sizeof(struct devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
+
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ idev->d_unit = -1;
+
+ err = 0;
+ np = devspec + strlen(dv->dv_name);
+ if (*np != '\0' && *np != ':') {
+ idev->d_unit = strtol(np, &cp, 0);
+ if (cp == np) {
+ idev->d_unit = -1;
+ free(idev);
+ return (EUNIT);
+ }
+ }
+ if (*cp != '\0' && *cp != ':') {
+ free(idev);
+ return (EINVAL);
+ }
+
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ if (dev != NULL)
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+}
+
+char *
+i386_fmtdev(void *vdev)
+{
+ struct devdesc *dev = (struct devdesc *)vdev;
+ static char buf[32]; /* XXX device length constant? */
+
+ switch(dev->d_type) {
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+ default:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+ }
+
+ return(buf);
+}
+
+/*
+ * Set currdev to suit the value being supplied in (value)
+ */
+int
+i386_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct devdesc *ncurr;
+ int rv;
+
+ rv = i386_parsedev(&ncurr, value, NULL);
+ if (rv != 0)
+ return(rv);
+
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (0);
+}
diff --git a/sys/boot/i386/efi/efimd.c b/sys/boot/i386/efi/efimd.c
new file mode 100644
index 0000000..01905e6
--- /dev/null
+++ b/sys/boot/i386/efi/efimd.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2004, 2006 Marcel Moolenaar
+ * 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 ``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 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 <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <libi386.h>
+#include <machine/bootinfo.h>
+
+#define EFI_INTEL_FPSWA \
+ {0xc41b6531,0x97b9,0x11d3,{0x9a,0x29,0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+
+static EFI_GUID fpswa_guid = EFI_INTEL_FPSWA;
+
+/* DIG64 Headless Console & Debug Port Table. */
+#define HCDP_TABLE_GUID \
+ {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+
+static EFI_GUID hcdp_guid = HCDP_TABLE_GUID;
+
+static UINTN mapkey;
+
+uint64_t
+ldr_alloc(vm_offset_t va)
+{
+
+ return (0);
+}
+
+int
+ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
+{
+ VOID *fpswa;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_HANDLE handle;
+ EFI_STATUS status;
+ size_t bisz;
+ UINTN mmsz, pages, sz;
+ UINT32 mmver;
+
+ bi->bi_systab = (uint64_t)ST;
+ bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);
+
+ sz = sizeof(EFI_HANDLE);
+ status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
+ if (status == 0)
+ status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
+ bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;
+
+ bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;
+
+ /*
+ * Allocate enough pages to hold the bootinfo block and the memory
+ * map EFI will return to us. The memory map has an unknown size,
+ * so we have to determine that first. Note that the AllocatePages
+ * call can itself modify the memory map, so we have to take that
+ * into account as well. The changes to the memory map are caused
+ * by splitting a range of free memory into two (AFAICT), so that
+ * one is marked as being loader data.
+ */
+ sz = 0;
+ BS->GetMemoryMap(&sz, NULL, &mapkey, &mmsz, &mmver);
+ sz += mmsz;
+ sz = (sz + 15) & ~15;
+ pages = EFI_SIZE_TO_PAGES(sz + bisz);
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
+ &addr);
+ if (EFI_ERROR(status)) {
+ printf("%s: AllocatePages() returned 0x%lx\n", __func__,
+ (long)status);
+ return (ENOMEM);
+ }
+
+ /*
+ * Read the memory map and stash it after bootinfo. Align the
+ * memory map on a 16-byte boundary (the bootinfo block is page
+ * aligned).
+ */
+ *bi_addr = addr;
+ mm = (void *)(addr + bisz);
+ sz = (EFI_PAGE_SIZE * pages) - bisz;
+ status = BS->GetMemoryMap(&sz, mm, &mapkey, &mmsz, &mmver);
+ if (EFI_ERROR(status)) {
+ printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+ bi->bi_memmap = (uint64_t)mm;
+ bi->bi_memmap_size = sz;
+ bi->bi_memdesc_size = mmsz;
+ bi->bi_memdesc_version = mmver;
+
+ bcopy(bi, (void *)(*bi_addr), sizeof(*bi));
+ return (0);
+}
+
+int
+ldr_enter(const char *kernel)
+{
+ EFI_STATUS status;
+
+ status = BS->ExitBootServices(IH, mapkey);
+ if (EFI_ERROR(status)) {
+ printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+
+ return (0);
+}
diff --git a/sys/boot/i386/efi/elf32_freebsd.c b/sys/boot/i386/efi/elf32_freebsd.c
new file mode 100644
index 0000000..f193735
--- /dev/null
+++ b/sys/boot/i386/efi/elf32_freebsd.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@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 <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include "bootstrap.h"
+#include "../libi386/libi386.h"
+#include "../btx/lib/btxv86.h"
+
+extern void __exec(caddr_t addr, ...);
+
+
+static int elf32_exec(struct preloaded_file *amp);
+static int elf32_obj_exec(struct preloaded_file *amp);
+
+struct file_format i386_elf = { elf32_loadfile, elf32_exec };
+struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec };
+
+/*
+ * There is an ELF kernel and one or more ELF modules loaded.
+ * We wish to start executing the kernel image, so make such
+ * preparations as are required, and do so.
+ */
+static int
+elf32_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t entry, bootinfop, modulep, kernend;
+ int boothowto, err, bootdev;
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+ entry = ehdr->e_entry & 0xffffff;
+
+ printf("Start @ 0x%lx ...\n", entry);
+
+ ldr_enter(fp->f_name);
+
+ dev_cleanup();
+ __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend);
+
+ panic("exec returned");
+}
+
+static int
+elf32_obj_exec(struct preloaded_file *fp)
+{
+ return (EFTYPE);
+}
diff --git a/sys/boot/i386/efi/exec.c b/sys/boot/i386/efi/exec.c
new file mode 100644
index 0000000..fefbf0b
--- /dev/null
+++ b/sys/boot/i386/efi/exec.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@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 ``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 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 <stand.h>
+#include <machine/elf.h>
+#include "../btx/lib/btxv86.h"
+
+#include "../../common/bootstrap.h"
+
+uint32_t __base;
+struct __v86 __v86;
+
+void
+__v86int()
+{
+ printf("%s\n", __func__);
+ exit(1);
+}
+
+void
+__exec(caddr_t addr, ...)
+{
+ /* XXX this is wrong */
+ __asm __volatile("movl %cr0, %eax");
+ __asm __volatile("andl $0x7fffffff, %eax");
+ __asm __volatile("mov %eax, %cr0");
+ __asm __volatile("xorl %eax, %eax");
+ __asm __volatile("mov %eax, %cr3");
+ __asm __volatile("movl %cr0, %eax");
+ __asm __volatile("andl $0xfffffffe, %eax");
+ __asm __volatile("movl %eax, %cr0");
+ __asm __volatile("jmp %0" :: "r" (addr));
+}
diff --git a/sys/boot/i386/efi/i386_copy.c b/sys/boot/i386/efi/i386_copy.c
new file mode 100644
index 0000000..43c26ce
--- /dev/null
+++ b/sys/boot/i386/efi/i386_copy.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@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$");
+
+/*
+ * MD primitives supporting placement of module data
+ *
+ * XXX should check load address/size against memory top.
+ */
+#include <stand.h>
+
+#include "libi386.h"
+#include "btxv86.h"
+
+ssize_t
+i386_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+ bcopy(src, PTOV(dest), len);
+ return(len);
+}
+
+ssize_t
+i386_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+ bcopy(PTOV(src), dest, len);
+ return(len);
+}
+
+
+ssize_t
+i386_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+ return (read(fd, PTOV(dest), len));
+}
diff --git a/sys/boot/i386/efi/ldscript.amd64 b/sys/boot/i386/efi/ldscript.amd64
new file mode 100644
index 0000000..9c5a29b
--- /dev/null
+++ b/sys/boot/i386/efi/ldscript.amd64
@@ -0,0 +1,75 @@
+/* $FreeBSD$ */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ ImageBase = .;
+ . = SIZEOF_HEADERS;
+ . = ALIGN(4096);
+ .eh_frame : {
+ *(.eh_frame)
+ }
+ .text : {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.plt)
+ } =0x00300000010070000002000001000400
+ . = ALIGN(4096);
+ .data : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ *(.opd)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.plabel)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ set_Xcommand_set : {
+ __start_set_Xcommand_set = .;
+ *(set_Xcommand_set)
+ __stop_set_Xcommand_set = .;
+ }
+ . = ALIGN(4096);
+ __gp = .;
+ .sdata : {
+ *(.got.plt .got)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ *(dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rel.dyn : {
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.got)
+ *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ *(.rel.plt)
+ *(.relset_*)
+ *(.rel.dyn .rel.dyn.*)
+ }
+ . = ALIGN(4096);
+ .reloc : { *(.reloc) }
+ . = ALIGN(4096);
+ .hash : { *(.hash) }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+}
diff --git a/sys/boot/i386/efi/ldscript.i386 b/sys/boot/i386/efi/ldscript.i386
new file mode 100644
index 0000000..fdfda0a
--- /dev/null
+++ b/sys/boot/i386/efi/ldscript.i386
@@ -0,0 +1,72 @@
+/* $FreeBSD$ */
+OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ ImageBase = .;
+ . = SIZEOF_HEADERS;
+ . = ALIGN(4096);
+ .text : {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.plt)
+ } =0x00300000010070000002000001000400
+ . = ALIGN(4096);
+ .data : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ *(.opd)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.plabel)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ set_Xcommand_set : {
+ __start_set_Xcommand_set = .;
+ *(set_Xcommand_set)
+ __stop_set_Xcommand_set = .;
+ }
+ . = ALIGN(4096);
+ __gp = .;
+ .sdata : {
+ *(.got.plt .got)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ *(dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rel.dyn : {
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.got)
+ *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ *(.rel.plt)
+ *(.relset_*)
+ *(.rel.dyn .rel.dyn.*)
+ }
+ . = ALIGN(4096);
+ .reloc : { *(.reloc) }
+ . = ALIGN(4096);
+ .hash : { *(.hash) }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+}
diff --git a/sys/boot/i386/efi/main.c b/sys/boot/i386/efi/main.c
new file mode 100644
index 0000000..1ea5c24
--- /dev/null
+++ b/sys/boot/i386/efi/main.c
@@ -0,0 +1,371 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo
+ * Copyright (c) 2006 Marcel Moolenaar
+ * 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 ``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 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 <stand.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <bootstrap.h>
+#include "../libi386/libi386.h"
+
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+
+struct devdesc currdev; /* our current device */
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+EFI_GUID acpi = ACPI_TABLE_GUID;
+EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
+EFI_GUID devid = DEVICE_PATH_PROTOCOL;
+EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
+EFI_GUID mps = MPS_TABLE_GUID;
+EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
+EFI_GUID smbios = SMBIOS_TABLE_GUID;
+
+EFI_STATUS
+main(int argc, CHAR16 *argv[])
+{
+ char vendor[128];
+ EFI_LOADED_IMAGE *img;
+ int i;
+
+ /*
+ * XXX Chicken-and-egg problem; we want to have console output
+ * early, but some console attributes may depend on reading from
+ * eg. the boot device, which we can't do yet. We can use
+ * printf() etc. once this is done.
+ */
+ cons_probe();
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+
+ /* Get our loaded image protocol interface structure. */
+ BS->HandleProtocol(IH, &imgid, (VOID**)&img);
+
+ printf("Image base: 0x%lx\n", (u_long)img->ImageBase);
+ printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
+ ST->Hdr.Revision & 0xffff);
+ printf("EFI Firmware: ");
+ /* printf doesn't understand EFI Unicode */
+ ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor);
+ printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16,
+ ST->FirmwareRevision & 0xffff);
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+
+ efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
+ currdev.d_type = currdev.d_dev->dv_type;
+
+ /*
+ * Disable the watchdog timer. By default the boot manager sets
+ * the timer to 5 minutes before invoking a boot option. If we
+ * want to return to the boot manager, we have to disable the
+ * watchdog timer and since we're an interactive program, we don't
+ * want to wait until the user types "quit". The timer may have
+ * fired by then. We don't care if this fails. It does not prevent
+ * normal functioning in any way...
+ */
+ BS->SetWatchdogTimer(0, 0, 0, NULL);
+
+ env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev),
+ i386_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset,
+ env_nounset);
+
+ setenv("LINES", "24", 1); /* optional */
+
+ archsw.arch_autoload = i386_autoload;
+ archsw.arch_getdev = i386_getdev;
+ archsw.arch_copyin = i386_copyin;
+ archsw.arch_copyout = i386_copyout;
+ archsw.arch_readin = i386_readin;
+
+ interact(); /* doesn't return */
+
+ return (EFI_SUCCESS); /* keep compiler happy */
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; devsw[i] != NULL; ++i)
+ if (devsw[i]->dv_cleanup != NULL)
+ (devsw[i]->dv_cleanup)();
+
+ RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 23,
+ (CHAR16 *)"Reboot from the loader");
+
+ /* NOTREACHED */
+ return (CMD_ERROR);
+}
+
+COMMAND_SET(quit, "quit", "exit the loader", command_quit);
+
+static int
+command_quit(int argc, char *argv[])
+{
+ exit(0);
+ return (CMD_OK);
+}
+
+COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
+
+static int
+command_memmap(int argc, char *argv[])
+{
+ UINTN sz;
+ EFI_MEMORY_DESCRIPTOR *map, *p;
+ UINTN key, dsz;
+ UINT32 dver;
+ EFI_STATUS status;
+ int i, ndesc;
+ static char *types[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode"
+ };
+
+ sz = 0;
+ status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ printf("Can't determine memory map size\n");
+ return CMD_ERROR;
+ }
+ map = malloc(sz);
+ status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
+ if (EFI_ERROR(status)) {
+ printf("Can't read memory map\n");
+ return CMD_ERROR;
+ }
+
+ ndesc = sz / dsz;
+ printf("%23s %12s %12s %8s %4s\n",
+ "Type", "Physical", "Virtual", "#Pages", "Attr");
+
+ for (i = 0, p = map; i < ndesc;
+ i++, p = NextMemoryDescriptor(p, dsz)) {
+ printf("%23s %012lx %012lx %08lx ",
+ types[p->Type],
+ p->PhysicalStart,
+ p->VirtualStart,
+ p->NumberOfPages);
+ if (p->Attribute & EFI_MEMORY_UC)
+ printf("UC ");
+ if (p->Attribute & EFI_MEMORY_WC)
+ printf("WC ");
+ if (p->Attribute & EFI_MEMORY_WT)
+ printf("WT ");
+ if (p->Attribute & EFI_MEMORY_WB)
+ printf("WB ");
+ if (p->Attribute & EFI_MEMORY_UCE)
+ printf("UCE ");
+ if (p->Attribute & EFI_MEMORY_WP)
+ printf("WP ");
+ if (p->Attribute & EFI_MEMORY_RP)
+ printf("RP ");
+ if (p->Attribute & EFI_MEMORY_XP)
+ printf("XP ");
+ printf("\n");
+ }
+
+ return CMD_OK;
+}
+
+COMMAND_SET(configuration, "configuration",
+ "print configuration tables", command_configuration);
+
+static const char *
+guid_to_string(EFI_GUID *guid)
+{
+ static char buf[40];
+
+ sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
+ guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
+ guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+ return (buf);
+}
+
+static int
+command_configuration(int argc, char *argv[])
+{
+ int i;
+
+ printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
+ for (i = 0; i < ST->NumberOfTableEntries; i++) {
+ EFI_GUID *guid;
+
+ printf(" ");
+ guid = &ST->ConfigurationTable[i].VendorGuid;
+ if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
+ printf("MPS Table");
+ else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
+ printf("ACPI Table");
+ else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
+ printf("ACPI 2.0 Table");
+ else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
+ printf("SMBIOS Table");
+ else
+ printf("Unknown Table (%s)", guid_to_string(guid));
+ printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
+ }
+
+ return CMD_OK;
+}
+
+
+COMMAND_SET(mode, "mode", "change or display text modes", command_mode);
+
+static int
+command_mode(int argc, char *argv[])
+{
+ unsigned int cols, rows, mode;
+ int i;
+ char *cp;
+ char rowenv[8];
+ EFI_STATUS status;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+
+ conout = ST->ConOut;
+
+ if (argc > 1) {
+ mode = strtol(argv[1], &cp, 0);
+ if (cp[0] != '\0') {
+ printf("Invalid mode\n");
+ return (CMD_ERROR);
+ }
+ status = conout->QueryMode(conout, mode, &cols, &rows);
+ if (EFI_ERROR(status)) {
+ printf("invalid mode %d\n", mode);
+ return (CMD_ERROR);
+ }
+ status = conout->SetMode(conout, mode);
+ if (EFI_ERROR(status)) {
+ printf("couldn't set mode %d\n", mode);
+ return (CMD_ERROR);
+ }
+ sprintf(rowenv, "%d", rows);
+ setenv("LINES", rowenv, 1);
+
+ return (CMD_OK);
+ }
+
+ for (i = 0; ; i++) {
+ status = conout->QueryMode(conout, i, &cols, &rows);
+ if (EFI_ERROR(status))
+ break;
+ printf("Mode %d: %d columns, %d rows\n", i, cols, rows);
+ }
+
+ if (i != 0)
+ printf("Choose the mode with \"col <mode number>\"\n");
+
+ return (CMD_OK);
+}
+
+
+COMMAND_SET(nvram, "nvram", "get or set NVRAM variables", command_nvram);
+
+static int
+command_nvram(int argc, char *argv[])
+{
+ CHAR16 var[128];
+ CHAR16 *data;
+ EFI_STATUS status;
+ EFI_GUID varguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
+ unsigned int varsz;
+ unsigned int datasz;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+ int i;
+
+ conout = ST->ConOut;
+
+ /* Initiate the search */
+ status = RS->GetNextVariableName(&varsz, NULL, NULL);
+
+ for (; status != EFI_NOT_FOUND; ) {
+ status = RS->GetNextVariableName(&varsz, var,
+ &varguid);
+ //if (EFI_ERROR(status))
+ //break;
+
+ conout->OutputString(conout, var);
+ printf("=");
+ datasz = 0;
+ status = RS->GetVariable(var, &varguid, NULL, &datasz,
+ NULL);
+ /* XXX: check status */
+ data = malloc(datasz);
+ status = RS->GetVariable(var, &varguid, NULL, &datasz,
+ data);
+ if (EFI_ERROR(status))
+ printf("<error retrieving variable>");
+ else {
+ for (i = 0; i < datasz; i++) {
+ if (isalnum(data[i]) || isspace(data[i]))
+ printf("%c", data[i]);
+ else
+ printf("\\x%02x", data[i]);
+ }
+ }
+ /* XXX */
+ pager_output("\n");
+ free(data);
+ }
+
+ return (CMD_OK);
+}
diff --git a/sys/boot/i386/efi/reloc.c b/sys/boot/i386/efi/reloc.c
new file mode 100644
index 0000000..24eed0a
--- /dev/null
+++ b/sys/boot/i386/efi/reloc.c
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo@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 <sys/types.h>
+#include <sys/elf32.h>
+#include <efi.h>
+
+/*
+ * XXX: we can't include sys/systm.h.
+ */
+#ifndef CTASSERT /* Allow lint to override */
+#define CTASSERT(x) _CTASSERT(x, __LINE__)
+#define _CTASSERT(x, y) __CTASSERT(x, y)
+#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
+#endif
+
+
+/*
+ * A simple relocator for IA32 EFI binaries.
+ */
+EFI_STATUS
+_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle,
+ EFI_SYSTEM_TABLE *system_table)
+{
+ unsigned long relsz, relent;
+ unsigned long *newaddr;
+ Elf32_Rel *rel;
+ Elf32_Dyn *dynp;
+
+ /*
+ * Find the relocation address, its size and the relocation entry.
+ */
+ relsz = 0;
+ relent = 0;
+ for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_REL:
+ rel = (Elf32_Rel *) ((unsigned long) dynp->d_un.d_ptr +
+ ImageBase);
+ break;
+ case DT_RELSZ:
+ relsz = dynp->d_un.d_val;
+ break;
+ case DT_RELENT:
+ relent = dynp->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Perform the actual relocation.
+ * XXX: We are reusing code for the amd64 version of this, but
+ * we must make sure the relocation types are the same.
+ */
+ CTASSERT(R_386_NONE == R_X86_64_NONE);
+ CTASSERT(R_386_RELATIVE == R_X86_64_RELATIVE);
+ for (; relsz > 0; relsz -= relent) {
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_386_NONE:
+ /* No relocation needs be performed. */
+ break;
+ case R_386_RELATIVE:
+ /* Address relative to the base address. */
+ newaddr = (unsigned long *)(ImageBase + rel->r_offset);
+ *newaddr += ImageBase;
+ break;
+ default:
+ /* XXX: do we need other relocations ? */
+ return (EFI_LOAD_ERROR);
+ }
+ rel = (Elf32_Rel *) ((caddr_t) rel + relent);
+ }
+
+ return (EFI_SUCCESS);
+}
diff --git a/sys/mips/include/psl.h b/sys/boot/i386/efi/start.S
index f02a1a9..ea4597f 100644
--- a/sys/mips/include/psl.h
+++ b/sys/boot/i386/efi/start.S
@@ -1,11 +1,6 @@
-/* $OpenBSD: psl.h,v 1.2 1998/01/28 13:46:25 pefo Exp $ */
-
/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -15,14 +10,11 @@
* 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.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * 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)
@@ -31,20 +23,48 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)psl.h 8.1 (Berkeley) 6/10/93
- * JNPR: psl.h,v 1.1 2006/08/07 05:38:57 katta
- * $FreeBSD$
+ * $FreeBSD$
*/
-#ifndef _MACHINE_PSL_H_
-#define _MACHINE_PSL_H_
+ .text
-#include <machine/cpu.h>
+#include <machine/asm.h>
+
+#define EFI_SUCCESS 0
/*
- * Macros to decode processor status word.
+ * EFI entry point.
+ * _start(EFI_IMAGE image_handle, EFI_SYSTEM_TABLE *system_table);
+ *
+ * We calculate the base address along with _DYNAMIC, relocate us and finally
+ * pass control to efi_main.
*/
-#define USERMODE(ps) (((ps) & SR_KSU_MASK) == SR_KSU_USER)
-#define BASEPRI(ps) (((ps) & (INT_MASK | SR_INT_ENA_PREV)) \
- == (INT_MASK | SR_INT_ENA_PREV))
-#endif /* _MACHINE_PSL_H_ */
+
+ENTRY(_start)
+ pushl %ebp
+ movl %esp, %ebp
+
+ pushl 12(%ebp) /* image_handle */
+ pushl 8(%ebp) /* system_table */
+ call 0f
+0: popl %eax
+ movl %eax, %ebx
+ addl $ImageBase-0b, %eax
+ addl $_DYNAMIC-0b, %ebx
+ pushl %ebx /* dynamic */
+ pushl %eax /* ImageBase */
+ call _reloc
+ cmpl $EFI_SUCCESS, %eax
+ jne 1f
+ popl %ebx /* remove ImageBase from the stack */
+ popl %ebx /* remove dynamic from the stack */
+ call efi_main
+1: leave
+ ret
+END(_start)
+
+ .data
+ .section .reloc, "a"
+ .long 0
+ .long 10
+ .word 0
diff --git a/sys/boot/i386/efi/version b/sys/boot/i386/efi/version
new file mode 100644
index 0000000..3a4c47c
--- /dev/null
+++ b/sys/boot/i386/efi/version
@@ -0,0 +1,7 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.1: Keep in sync with i386 version.
+0.1: Initial i386 version. Derived from ia64.
diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c
index 96efea6..6939556 100644
--- a/sys/boot/i386/gptboot/gptboot.c
+++ b/sys/boot/i386/gptboot/gptboot.c
@@ -281,7 +281,7 @@ main(void)
for (;;) {
if (!autoboot || !OPT_CHECK(RBX_QUIET))
- printf("\nFreeBSD/i386 boot\n"
+ printf("\nFreeBSD/x86 boot\n"
"Default: %u:%s(%up%u)%s\n"
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c
index 07ade3a..d312b2a 100644
--- a/sys/boot/i386/zfsboot/zfsboot.c
+++ b/sys/boot/i386/zfsboot/zfsboot.c
@@ -730,7 +730,7 @@ main(void)
for (;;) {
if (!autoboot || !OPT_CHECK(RBX_QUIET))
- printf("\nFreeBSD/i386 boot\n"
+ printf("\nFreeBSD/x86 boot\n"
"Default: %s:%s\n"
"boot: ",
spa->spa_name, kname);
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 6cb4f2e..6eff691 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -686,14 +686,10 @@ adaregister(struct cam_periph *periph, void *arg)
else
softc->quirks = ADA_Q_NONE;
- /* Check if the SIM does not want queued commands */
bzero(&cpi, sizeof(cpi));
xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE);
cpi.ccb_h.func_code = XPT_PATH_INQ;
xpt_action((union ccb *)&cpi);
- if (cpi.ccb_h.status != CAM_REQ_CMP ||
- (cpi.hba_inquiry & PI_TAG_ABLE) == 0)
- softc->flags &= ~ADA_FLAG_CAN_NCQ;
TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index d5e0b32..3bf9c1e 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -766,6 +766,7 @@ noerror:
}
case PROBE_IDENTIFY:
{
+ struct ccb_pathinq cpi;
int16_t *ptr;
ident_buf = &softc->ident_data;
@@ -840,16 +841,24 @@ noerror:
ata_find_quirk(path->device);
if (path->device->mintags != 0 &&
path->bus->sim->max_tagged_dev_openings != 0) {
- /* Report SIM which tags are allowed. */
- bzero(&cts, sizeof(cts));
- xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
- cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
- cts.type = CTS_TYPE_CURRENT_SETTINGS;
- cts.xport_specific.sata.tags = path->device->maxtags;
- cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS;
- xpt_action((union ccb *)&cts);
- /* Reconfigure queues for tagged queueing. */
- xpt_start_tags(path);
+ /* Check if the SIM does not want queued commands. */
+ bzero(&cpi, sizeof(cpi));
+ xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
+ cpi.ccb_h.func_code = XPT_PATH_INQ;
+ xpt_action((union ccb *)&cpi);
+ if (cpi.ccb_h.status == CAM_REQ_CMP &&
+ (cpi.hba_inquiry & PI_TAG_ABLE)) {
+ /* Report SIM which tags are allowed. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
+ cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ cts.xport_specific.sata.tags = path->device->maxtags;
+ cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS;
+ xpt_action((union ccb *)&cts);
+ /* Reconfigure queues for tagged queueing. */
+ xpt_start_tags(path);
+ }
}
ata_device_transport(path);
PROBE_SET_ACTION(softc, PROBE_SETMODE);
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 4871e85..1812edb 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -2380,6 +2380,7 @@ xpt_action_default(union ccb *start_ccb)
if (start_ccb->ccb_h.func_code == XPT_ATA_IO) {
start_ccb->ataio.resid = 0;
}
+ /* FALLTHROUGH */
case XPT_RESET_DEV:
case XPT_ENG_EXEC:
{
@@ -2888,6 +2889,9 @@ xpt_action_default(union ccb *start_ccb)
case XPT_ENG_INQ:
/* XXX Implement */
start_ccb->ccb_h.status = CAM_PROVIDE_FAIL;
+ if (start_ccb->ccb_h.func_code & XPT_FC_DEV_QUEUED) {
+ xpt_done(start_ccb);
+ }
break;
}
}
@@ -3930,7 +3934,7 @@ xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus,
struct cam_et *target, struct cam_ed *device,
void *async_arg)
{
- printf("xpt_dev_async called\n");
+ printf("%s called\n", __func__);
}
u_int32_t
@@ -4919,4 +4923,3 @@ camisr_runqueue(void *V_queue)
(*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);
}
}
-
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index 029b2cc..d6b6e81 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -170,6 +170,8 @@ struct scsi_mode_sense_6
#define SMS_PAGE_CODE 0x3F
#define SMS_VENDOR_SPECIFIC_PAGE 0x00
#define SMS_DISCONNECT_RECONNECT_PAGE 0x02
+#define SMS_FORMAT_DEVICE_PAGE 0x03
+#define SMS_GEOMETRY_PAGE 0x04
#define SMS_CACHE_PAGE 0x08
#define SMS_PERIPHERAL_DEVICE_PAGE 0x09
#define SMS_CONTROL_MODE_PAGE 0x0A
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 1e5be3c..d09d129 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -2773,8 +2773,12 @@ cdcheckmedia(struct cam_periph *periph)
softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC);
cdprevent(periph, PR_ALLOW);
return (error);
- } else
+ } else {
softc->flags |= CD_FLAG_VALID_MEDIA;
+ softc->disk->d_sectorsize = softc->params.blksize;
+ softc->disk->d_mediasize =
+ (off_t)softc->params.blksize * softc->params.disksize;
+ }
/*
* Now we check the table of contents. This (currently) is only
@@ -2863,9 +2867,6 @@ cdcheckmedia(struct cam_periph *periph)
}
softc->flags |= CD_FLAG_VALID_TOC;
- softc->disk->d_sectorsize = softc->params.blksize;
- softc->disk->d_mediasize =
- (off_t)softc->params.blksize * softc->params.disksize;
bailout:
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 77652b2..377275a 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -997,6 +997,11 @@ dacleanup(struct cam_periph *periph)
xpt_print(periph->path, "can't remove sysctl context\n");
}
+ /*
+ * Nullify our periph pointer here to try and catch
+ * race conditions in callbacks/downcalls.
+ */
+ softc->disk->d_drv1 = NULL;
disk_destroy(softc->disk);
callout_drain(&softc->sendordered_c);
free(softc, M_DEVBUF);
diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c
index d47e6e9..8ec0189 100644
--- a/sys/cam/scsi/scsi_sg.c
+++ b/sys/cam/scsi/scsi_sg.c
@@ -586,7 +586,7 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
{
struct sg_scsi_id id;
- id.host_no = 0; /* XXX */
+ id.host_no = cam_sim_path(xpt_path_sim(periph->path));
id.channel = xpt_path_path_id(periph->path);
id.scsi_id = xpt_path_target_id(periph->path);
id.lun = xpt_path_lun_id(periph->path);
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
index 584be24..1e3b1ef 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
@@ -52,9 +52,9 @@ static void
system_taskq_init(void *arg)
{
- system_taskq = (taskq_t *)taskqueue_thread;
taskq_zone = uma_zcreate("taskq_zone", sizeof(struct ostask),
NULL, NULL, NULL, NULL, 0, 0);
+ system_taskq = taskq_create("system_taskq", mp_ncpus, 0, 0, 0, 0);
}
SYSINIT(system_taskq_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_init, NULL);
@@ -62,6 +62,7 @@ static void
system_taskq_fini(void *arg)
{
+ taskq_destroy(system_taskq);
uma_zdestroy(taskq_zone);
}
SYSUNINIT(system_taskq_fini, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_fini, NULL);
@@ -72,10 +73,8 @@ taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused,
{
taskq_t *tq;
- if ((flags & TASKQ_THREADS_CPU_PCT) != 0) {
- /* TODO: Calculate number od threads. */
- printf("%s: TASKQ_THREADS_CPU_PCT\n", __func__);
- }
+ if ((flags & TASKQ_THREADS_CPU_PCT) != 0)
+ nthreads = MAX((mp_ncpus * nthreads) / 100, 1);
tq = kmem_alloc(sizeof(*tq), KM_SLEEP);
tq->tq_queue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue,
@@ -85,6 +84,14 @@ taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused,
return ((taskq_t *)tq);
}
+taskq_t *
+taskq_create_proc(const char *name, int nthreads, pri_t pri, int minalloc,
+ int maxalloc, proc_t *proc __unused, uint_t flags)
+{
+
+ return (taskq_create(name, nthreads, pri, minalloc, maxalloc, flags));
+}
+
void
taskq_destroy(taskq_t *tq)
{
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
index 83a4c97..ceb4c87 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -186,6 +186,11 @@ SYSCTL_QUAD(_vfs_zfs, OID_AUTO, arc_min, CTLFLAG_RDTUN, &zfs_arc_min, 0,
SYSCTL_INT(_vfs_zfs, OID_AUTO, mdcomp_disable, CTLFLAG_RDTUN,
&zfs_mdcomp_disable, 0, "Disable metadata compression");
+#ifdef ZIO_USE_UMA
+extern kmem_cache_t *zio_buf_cache[];
+extern kmem_cache_t *zio_data_buf_cache[];
+#endif
+
/*
* Note that buffers can be in one of 6 states:
* ARC_anon - anonymous (discussed below)
@@ -218,13 +223,31 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, mdcomp_disable, CTLFLAG_RDTUN,
* second level ARC benefit from these fast lookups.
*/
+#define ARCS_LOCK_PAD CACHE_LINE_SIZE
+struct arcs_lock {
+ kmutex_t arcs_lock;
+#ifdef _KERNEL
+ unsigned char pad[(ARCS_LOCK_PAD - sizeof (kmutex_t))];
+#endif
+};
+
+/*
+ * must be power of two for mask use to work
+ *
+ */
+#define ARC_BUFC_NUMDATALISTS 16
+#define ARC_BUFC_NUMMETADATALISTS 16
+#define ARC_BUFC_NUMLISTS (ARC_BUFC_NUMMETADATALISTS + ARC_BUFC_NUMDATALISTS)
+
typedef struct arc_state {
- list_t arcs_list[ARC_BUFC_NUMTYPES]; /* list of evictable buffers */
uint64_t arcs_lsize[ARC_BUFC_NUMTYPES]; /* amount of evictable data */
uint64_t arcs_size; /* total amount of data in this state */
- kmutex_t arcs_mtx;
+ list_t arcs_lists[ARC_BUFC_NUMLISTS]; /* list of evictable buffers */
+ struct arcs_lock arcs_locks[ARC_BUFC_NUMLISTS] __aligned(CACHE_LINE_SIZE);
} arc_state_t;
+#define ARCS_LOCK(s, i) (&((s)->arcs_locks[(i)].arcs_lock))
+
/* The 6 states: */
static arc_state_t ARC_anon;
static arc_state_t ARC_mru;
@@ -248,7 +271,9 @@ typedef struct arc_stats {
kstat_named_t arcstat_mru_ghost_hits;
kstat_named_t arcstat_mfu_hits;
kstat_named_t arcstat_mfu_ghost_hits;
+ kstat_named_t arcstat_allocated;
kstat_named_t arcstat_deleted;
+ kstat_named_t arcstat_stolen;
kstat_named_t arcstat_recycle_miss;
kstat_named_t arcstat_mutex_miss;
kstat_named_t arcstat_evict_skip;
@@ -280,6 +305,19 @@ typedef struct arc_stats {
kstat_named_t arcstat_l2_size;
kstat_named_t arcstat_l2_hdr_size;
kstat_named_t arcstat_memory_throttle_count;
+ kstat_named_t arcstat_l2_write_trylock_fail;
+ kstat_named_t arcstat_l2_write_passed_headroom;
+ kstat_named_t arcstat_l2_write_spa_mismatch;
+ kstat_named_t arcstat_l2_write_in_l2;
+ kstat_named_t arcstat_l2_write_hdr_io_in_progress;
+ kstat_named_t arcstat_l2_write_not_cacheable;
+ kstat_named_t arcstat_l2_write_full;
+ kstat_named_t arcstat_l2_write_buffer_iter;
+ kstat_named_t arcstat_l2_write_pios;
+ kstat_named_t arcstat_l2_write_bytes_written;
+ kstat_named_t arcstat_l2_write_buffer_bytes_scanned;
+ kstat_named_t arcstat_l2_write_buffer_list_iter;
+ kstat_named_t arcstat_l2_write_buffer_list_null_iter;
} arc_stats_t;
static arc_stats_t arc_stats = {
@@ -297,7 +335,9 @@ static arc_stats_t arc_stats = {
{ "mru_ghost_hits", KSTAT_DATA_UINT64 },
{ "mfu_hits", KSTAT_DATA_UINT64 },
{ "mfu_ghost_hits", KSTAT_DATA_UINT64 },
+ { "allocated", KSTAT_DATA_UINT64 },
{ "deleted", KSTAT_DATA_UINT64 },
+ { "stolen", KSTAT_DATA_UINT64 },
{ "recycle_miss", KSTAT_DATA_UINT64 },
{ "mutex_miss", KSTAT_DATA_UINT64 },
{ "evict_skip", KSTAT_DATA_UINT64 },
@@ -328,7 +368,20 @@ static arc_stats_t arc_stats = {
{ "l2_io_error", KSTAT_DATA_UINT64 },
{ "l2_size", KSTAT_DATA_UINT64 },
{ "l2_hdr_size", KSTAT_DATA_UINT64 },
- { "memory_throttle_count", KSTAT_DATA_UINT64 }
+ { "memory_throttle_count", KSTAT_DATA_UINT64 },
+ { "l2_write_trylock_fail", KSTAT_DATA_UINT64 },
+ { "l2_write_passed_headroom", KSTAT_DATA_UINT64 },
+ { "l2_write_spa_mismatch", KSTAT_DATA_UINT64 },
+ { "l2_write_in_l2", KSTAT_DATA_UINT64 },
+ { "l2_write_io_in_progress", KSTAT_DATA_UINT64 },
+ { "l2_write_not_cacheable", KSTAT_DATA_UINT64 },
+ { "l2_write_full", KSTAT_DATA_UINT64 },
+ { "l2_write_buffer_iter", KSTAT_DATA_UINT64 },
+ { "l2_write_pios", KSTAT_DATA_UINT64 },
+ { "l2_write_bytes_written", KSTAT_DATA_UINT64 },
+ { "l2_write_buffer_bytes_scanned", KSTAT_DATA_UINT64 },
+ { "l2_write_buffer_list_iter", KSTAT_DATA_UINT64 },
+ { "l2_write_buffer_list_null_iter", KSTAT_DATA_UINT64 }
};
#define ARCSTAT(stat) (arc_stats.stat.value.ui64)
@@ -336,7 +389,7 @@ static arc_stats_t arc_stats = {
#define ARCSTAT_INCR(stat, val) \
atomic_add_64(&arc_stats.stat.value.ui64, (val));
-#define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1)
+#define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1)
#define ARCSTAT_BUMPDOWN(stat) ARCSTAT_INCR(stat, -1)
#define ARCSTAT_MAX(stat, val) { \
@@ -370,7 +423,7 @@ static arc_stats_t arc_stats = {
}
kstat_t *arc_ksp;
-static arc_state_t *arc_anon;
+static arc_state_t *arc_anon;
static arc_state_t *arc_mru;
static arc_state_t *arc_mru_ghost;
static arc_state_t *arc_mfu;
@@ -514,7 +567,7 @@ static void arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes);
* Hash table routines
*/
-#define HT_LOCK_PAD 128
+#define HT_LOCK_PAD CACHE_LINE_SIZE
struct ht_lock {
kmutex_t ht_lock;
@@ -527,7 +580,7 @@ struct ht_lock {
typedef struct buf_hash_table {
uint64_t ht_mask;
arc_buf_hdr_t **ht_table;
- struct ht_lock ht_locks[BUF_LOCKS];
+ struct ht_lock ht_locks[BUF_LOCKS] __aligned(CACHE_LINE_SIZE);
} buf_hash_table_t;
static buf_hash_table_t buf_hash_table;
@@ -541,13 +594,19 @@ static buf_hash_table_t buf_hash_table;
uint64_t zfs_crc64_table[256];
+#ifdef ZIO_USE_UMA
+extern kmem_cache_t *zio_buf_cache[];
+extern kmem_cache_t *zio_data_buf_cache[];
+#endif
+
/*
* Level 2 ARC
*/
-#define L2ARC_WRITE_SIZE (8 * 1024 * 1024) /* initial write max */
-#define L2ARC_HEADROOM 4 /* num of writes */
+#define L2ARC_WRITE_SIZE (64 * 1024 * 1024) /* initial write max */
+#define L2ARC_HEADROOM 128 /* num of writes */
#define L2ARC_FEED_SECS 1 /* caching interval */
+#define L2ARC_FEED_SECS_SHIFT 1 /* caching interval shift */
#define l2arc_writes_sent ARCSTAT(arcstat_l2_writes_sent)
#define l2arc_writes_done ARCSTAT(arcstat_l2_writes_done)
@@ -559,7 +618,66 @@ uint64_t l2arc_write_max = L2ARC_WRITE_SIZE; /* default max write size */
uint64_t l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra write during warmup */
uint64_t l2arc_headroom = L2ARC_HEADROOM; /* number of dev writes */
uint64_t l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */
-boolean_t l2arc_noprefetch = B_TRUE; /* don't cache prefetch bufs */
+uint64_t l2arc_feed_secs_shift = L2ARC_FEED_SECS_SHIFT; /* interval seconds shift */
+boolean_t l2arc_noprefetch = B_FALSE; /* don't cache prefetch bufs */
+
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_write_max, CTLFLAG_RW,
+ &l2arc_write_max, 0, "max write size");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_write_boost, CTLFLAG_RW,
+ &l2arc_write_boost, 0, "extra write during warmup");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_headroom, CTLFLAG_RW,
+ &l2arc_headroom, 0, "number of dev writes");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_feed_secs, CTLFLAG_RW,
+ &l2arc_feed_secs, 0, "interval seconds");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_feed_secs_shift, CTLFLAG_RW,
+ &l2arc_feed_secs_shift, 0, "power of 2 division of feed seconds");
+
+SYSCTL_INT(_vfs_zfs, OID_AUTO, l2arc_noprefetch, CTLFLAG_RW,
+ &l2arc_noprefetch, 0, "don't cache prefetch bufs");
+
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_size, CTLFLAG_RD,
+ &ARC_anon.arcs_size, 0, "size of anonymous state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_metadata_lsize, CTLFLAG_RD,
+ &ARC_anon.arcs_lsize[ARC_BUFC_METADATA], 0, "size of anonymous state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_data_lsize, CTLFLAG_RD,
+ &ARC_anon.arcs_lsize[ARC_BUFC_DATA], 0, "size of anonymous state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_size, CTLFLAG_RD,
+ &ARC_mru.arcs_size, 0, "size of mru state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_metadata_lsize, CTLFLAG_RD,
+ &ARC_mru.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mru state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_data_lsize, CTLFLAG_RD,
+ &ARC_mru.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mru state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_size, CTLFLAG_RD,
+ &ARC_mru_ghost.arcs_size, 0, "size of mru ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_metadata_lsize, CTLFLAG_RD,
+ &ARC_mru_ghost.arcs_lsize[ARC_BUFC_METADATA], 0,
+ "size of metadata in mru ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_data_lsize, CTLFLAG_RD,
+ &ARC_mru_ghost.arcs_lsize[ARC_BUFC_DATA], 0,
+ "size of data in mru ghost state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_size, CTLFLAG_RD,
+ &ARC_mfu.arcs_size, 0, "size of mfu state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_metadata_lsize, CTLFLAG_RD,
+ &ARC_mfu.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mfu state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_data_lsize, CTLFLAG_RD,
+ &ARC_mfu.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mfu state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_size, CTLFLAG_RD,
+ &ARC_mfu_ghost.arcs_size, 0, "size of mfu ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_metadata_lsize, CTLFLAG_RD,
+ &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_METADATA], 0,
+ "size of metadata in mfu ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_data_lsize, CTLFLAG_RD,
+ &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_DATA], 0,
+ "size of data in mfu ghost state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2c_only_size, CTLFLAG_RD,
+ &ARC_l2c_only.arcs_size, 0, "size of mru state");
/*
* L2ARC Internals
@@ -953,18 +1071,38 @@ arc_buf_freeze(arc_buf_t *buf)
}
static void
+get_buf_info(arc_buf_hdr_t *ab, arc_state_t *state, list_t **list, kmutex_t **lock)
+{
+ uint64_t buf_hashid = buf_hash(ab->b_spa, &ab->b_dva, ab->b_birth);
+
+ if (ab->b_type == ARC_BUFC_METADATA)
+ buf_hashid &= (ARC_BUFC_NUMMETADATALISTS - 1);
+ else {
+ buf_hashid &= (ARC_BUFC_NUMDATALISTS - 1);
+ buf_hashid += ARC_BUFC_NUMMETADATALISTS;
+ }
+
+ *list = &state->arcs_lists[buf_hashid];
+ *lock = ARCS_LOCK(state, buf_hashid);
+}
+
+
+static void
add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag)
{
+
ASSERT(MUTEX_HELD(hash_lock));
if ((refcount_add(&ab->b_refcnt, tag) == 1) &&
(ab->b_state != arc_anon)) {
uint64_t delta = ab->b_size * ab->b_datacnt;
- list_t *list = &ab->b_state->arcs_list[ab->b_type];
uint64_t *size = &ab->b_state->arcs_lsize[ab->b_type];
+ list_t *list;
+ kmutex_t *lock;
- ASSERT(!MUTEX_HELD(&ab->b_state->arcs_mtx));
- mutex_enter(&ab->b_state->arcs_mtx);
+ get_buf_info(ab, ab->b_state, &list, &lock);
+ ASSERT(!MUTEX_HELD(lock));
+ mutex_enter(lock);
ASSERT(list_link_active(&ab->b_arc_node));
list_remove(list, ab);
if (GHOST_STATE(ab->b_state)) {
@@ -975,7 +1113,7 @@ add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag)
ASSERT(delta > 0);
ASSERT3U(*size, >=, delta);
atomic_add_64(size, -delta);
- mutex_exit(&ab->b_state->arcs_mtx);
+ mutex_exit(lock);
/* remove the prefetch flag if we get a reference */
if (ab->b_flags & ARC_PREFETCH)
ab->b_flags &= ~ARC_PREFETCH;
@@ -994,14 +1132,17 @@ remove_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag)
if (((cnt = refcount_remove(&ab->b_refcnt, tag)) == 0) &&
(state != arc_anon)) {
uint64_t *size = &state->arcs_lsize[ab->b_type];
+ list_t *list;
+ kmutex_t *lock;
- ASSERT(!MUTEX_HELD(&state->arcs_mtx));
- mutex_enter(&state->arcs_mtx);
+ get_buf_info(ab, state, &list, &lock);
+ ASSERT(!MUTEX_HELD(lock));
+ mutex_enter(lock);
ASSERT(!list_link_active(&ab->b_arc_node));
- list_insert_head(&state->arcs_list[ab->b_type], ab);
+ list_insert_head(list, ab);
ASSERT(ab->b_datacnt > 0);
atomic_add_64(size, ab->b_size * ab->b_datacnt);
- mutex_exit(&state->arcs_mtx);
+ mutex_exit(lock);
}
return (cnt);
}
@@ -1016,6 +1157,8 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock)
arc_state_t *old_state = ab->b_state;
int64_t refcnt = refcount_count(&ab->b_refcnt);
uint64_t from_delta, to_delta;
+ list_t *list;
+ kmutex_t *lock;
ASSERT(MUTEX_HELD(hash_lock));
ASSERT(new_state != old_state);
@@ -1030,14 +1173,16 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock)
*/
if (refcnt == 0) {
if (old_state != arc_anon) {
- int use_mutex = !MUTEX_HELD(&old_state->arcs_mtx);
+ int use_mutex;
uint64_t *size = &old_state->arcs_lsize[ab->b_type];
+ get_buf_info(ab, old_state, &list, &lock);
+ use_mutex = !MUTEX_HELD(lock);
if (use_mutex)
- mutex_enter(&old_state->arcs_mtx);
+ mutex_enter(lock);
ASSERT(list_link_active(&ab->b_arc_node));
- list_remove(&old_state->arcs_list[ab->b_type], ab);
+ list_remove(list, ab);
/*
* If prefetching out of the ghost cache,
@@ -1052,16 +1197,18 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock)
atomic_add_64(size, -from_delta);
if (use_mutex)
- mutex_exit(&old_state->arcs_mtx);
+ mutex_exit(lock);
}
if (new_state != arc_anon) {
- int use_mutex = !MUTEX_HELD(&new_state->arcs_mtx);
+ int use_mutex;
uint64_t *size = &new_state->arcs_lsize[ab->b_type];
+ get_buf_info(ab, new_state, &list, &lock);
+ use_mutex = !MUTEX_HELD(lock);
if (use_mutex)
- mutex_enter(&new_state->arcs_mtx);
+ mutex_enter(lock);
- list_insert_head(&new_state->arcs_list[ab->b_type], ab);
+ list_insert_head(list, ab);
/* ghost elements have a ghost size */
if (GHOST_STATE(new_state)) {
@@ -1072,7 +1219,7 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock)
atomic_add_64(size, to_delta);
if (use_mutex)
- mutex_exit(&new_state->arcs_mtx);
+ mutex_exit(lock);
}
}
@@ -1462,21 +1609,48 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle,
{
arc_state_t *evicted_state;
uint64_t bytes_evicted = 0, skipped = 0, missed = 0;
+ int64_t bytes_remaining;
arc_buf_hdr_t *ab, *ab_prev = NULL;
- list_t *list = &state->arcs_list[type];
+ list_t *evicted_list, *list, *evicted_list_start, *list_start;
+ kmutex_t *lock, *evicted_lock;
kmutex_t *hash_lock;
boolean_t have_lock;
void *stolen = NULL;
+ static int evict_metadata_offset, evict_data_offset;
+ int i, idx, offset, list_count, count;
ASSERT(state == arc_mru || state == arc_mfu);
evicted_state = (state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost;
- mutex_enter(&state->arcs_mtx);
- mutex_enter(&evicted_state->arcs_mtx);
+ if (type == ARC_BUFC_METADATA) {
+ offset = 0;
+ list_count = ARC_BUFC_NUMMETADATALISTS;
+ list_start = &state->arcs_lists[0];
+ evicted_list_start = &evicted_state->arcs_lists[0];
+ idx = evict_metadata_offset;
+ } else {
+ offset = ARC_BUFC_NUMMETADATALISTS;
+ list_start = &state->arcs_lists[offset];
+ evicted_list_start = &evicted_state->arcs_lists[offset];
+ list_count = ARC_BUFC_NUMDATALISTS;
+ idx = evict_data_offset;
+ }
+ bytes_remaining = evicted_state->arcs_lsize[type];
+ count = 0;
+
+evict_start:
+ list = &list_start[idx];
+ evicted_list = &evicted_list_start[idx];
+ lock = ARCS_LOCK(state, (offset + idx));
+ evicted_lock = ARCS_LOCK(evicted_state, (offset + idx));
+
+ mutex_enter(lock);
+ mutex_enter(evicted_lock);
for (ab = list_tail(list); ab; ab = ab_prev) {
ab_prev = list_prev(list, ab);
+ bytes_remaining -= (ab->b_size * ab->b_datacnt);
/* prefetch buffers have a minimum lifespan */
if (HDR_IO_IN_PROGRESS(ab) ||
(spa && ab->b_spa != spa) ||
@@ -1536,17 +1710,35 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle,
mutex_exit(hash_lock);
if (bytes >= 0 && bytes_evicted >= bytes)
break;
+ if (bytes_remaining > 0) {
+ mutex_exit(evicted_lock);
+ mutex_exit(lock);
+ idx = ((idx + 1) & (list_count - 1));
+ count++;
+ goto evict_start;
+ }
} else {
missed += 1;
}
}
- mutex_exit(&evicted_state->arcs_mtx);
- mutex_exit(&state->arcs_mtx);
+ mutex_exit(evicted_lock);
+ mutex_exit(lock);
- if (bytes_evicted < bytes)
- dprintf("only evicted %lld bytes from %x",
- (longlong_t)bytes_evicted, state);
+ idx = ((idx + 1) & (list_count - 1));
+ count++;
+
+ if (bytes_evicted < bytes) {
+ if (count < list_count)
+ goto evict_start;
+ else
+ dprintf("only evicted %lld bytes from %x",
+ (longlong_t)bytes_evicted, state);
+ }
+ if (type == ARC_BUFC_METADATA)
+ evict_metadata_offset = idx;
+ else
+ evict_data_offset = idx;
if (skipped)
ARCSTAT_INCR(arcstat_evict_skip, skipped);
@@ -1574,6 +1766,8 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle,
arc_evict_ghost(arc_mfu_ghost, NULL, todelete);
}
}
+ if (stolen)
+ ARCSTAT_BUMP(arcstat_stolen);
return (stolen);
}
@@ -1586,14 +1780,28 @@ static void
arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes)
{
arc_buf_hdr_t *ab, *ab_prev;
- list_t *list = &state->arcs_list[ARC_BUFC_DATA];
- kmutex_t *hash_lock;
+ list_t *list, *list_start;
+ kmutex_t *hash_lock, *lock;
uint64_t bytes_deleted = 0;
uint64_t bufs_skipped = 0;
+ static int evict_offset;
+ int list_count, idx = evict_offset;
+ int offset, count = 0;
ASSERT(GHOST_STATE(state));
-top:
- mutex_enter(&state->arcs_mtx);
+
+ /*
+ * data lists come after metadata lists
+ */
+ list_start = &state->arcs_lists[ARC_BUFC_NUMMETADATALISTS];
+ list_count = ARC_BUFC_NUMDATALISTS;
+ offset = ARC_BUFC_NUMMETADATALISTS;
+
+evict_start:
+ list = &list_start[idx];
+ lock = ARCS_LOCK(state, idx + offset);
+
+ mutex_enter(lock);
for (ab = list_tail(list); ab; ab = ab_prev) {
ab_prev = list_prev(list, ab);
if (spa && ab->b_spa != spa)
@@ -1623,20 +1831,31 @@ top:
break;
} else {
if (bytes < 0) {
- mutex_exit(&state->arcs_mtx);
+ /*
+ * we're draining the ARC, retry
+ */
+ mutex_exit(lock);
mutex_enter(hash_lock);
mutex_exit(hash_lock);
- goto top;
+ goto evict_start;
}
bufs_skipped += 1;
}
}
- mutex_exit(&state->arcs_mtx);
+ mutex_exit(lock);
+ idx = ((idx + 1) & (ARC_BUFC_NUMDATALISTS - 1));
+ count++;
- if (list == &state->arcs_list[ARC_BUFC_DATA] &&
+ if (count < list_count)
+ goto evict_start;
+
+ evict_offset = idx;
+ if ((uintptr_t)list > (uintptr_t)&state->arcs_lists[ARC_BUFC_NUMMETADATALISTS] &&
(bytes < 0 || bytes_deleted < bytes)) {
- list = &state->arcs_list[ARC_BUFC_METADATA];
- goto top;
+ list_start = &state->arcs_lists[0];
+ list_count = ARC_BUFC_NUMMETADATALISTS;
+ offset = count = 0;
+ goto evict_start;
}
if (bufs_skipped) {
@@ -1718,7 +1937,7 @@ arc_do_user_evicts(void)
/*
* Move list over to avoid LOR
*/
-restart:
+restart:
mutex_enter(&arc_eviction_mtx);
tmp_arc_eviction_list = arc_eviction_list;
arc_eviction_list = NULL;
@@ -1750,22 +1969,22 @@ restart:
void
arc_flush(spa_t *spa)
{
- while (list_head(&arc_mru->arcs_list[ARC_BUFC_DATA])) {
+ while (arc_mru->arcs_lsize[ARC_BUFC_DATA]) {
(void) arc_evict(arc_mru, spa, -1, FALSE, ARC_BUFC_DATA);
if (spa)
break;
}
- while (list_head(&arc_mru->arcs_list[ARC_BUFC_METADATA])) {
+ while (arc_mru->arcs_lsize[ARC_BUFC_METADATA]) {
(void) arc_evict(arc_mru, spa, -1, FALSE, ARC_BUFC_METADATA);
if (spa)
break;
}
- while (list_head(&arc_mfu->arcs_list[ARC_BUFC_DATA])) {
+ while (arc_mfu->arcs_lsize[ARC_BUFC_DATA]) {
(void) arc_evict(arc_mfu, spa, -1, FALSE, ARC_BUFC_DATA);
if (spa)
break;
}
- while (list_head(&arc_mfu->arcs_list[ARC_BUFC_METADATA])) {
+ while (arc_mfu->arcs_lsize[ARC_BUFC_METADATA]) {
(void) arc_evict(arc_mfu, spa, -1, FALSE, ARC_BUFC_METADATA);
if (spa)
break;
@@ -1829,7 +2048,7 @@ arc_reclaim_needed(void)
return (0);
/*
- * If pages are needed or we're within 2048 pages
+ * If pages are needed or we're within 2048 pages
* of needing to page need to reclaim
*/
if (vm_pages_needed || (vm_paging_target() > -2048))
@@ -1896,8 +2115,6 @@ arc_kmem_reap_now(arc_reclaim_strategy_t strat)
size_t i;
kmem_cache_t *prev_cache = NULL;
kmem_cache_t *prev_data_cache = NULL;
- extern kmem_cache_t *zio_buf_cache[];
- extern kmem_cache_t *zio_data_buf_cache[];
#endif
#ifdef _KERNEL
@@ -2203,6 +2420,7 @@ out:
arc_anon->arcs_size + arc_mru->arcs_size > arc_p)
arc_p = MIN(arc_c, arc_p + size);
}
+ ARCSTAT_BUMP(arcstat_allocated);
}
/*
@@ -2502,7 +2720,6 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf,
uint32_t *arc_flags, const zbookmark_t *zb)
{
int err;
- arc_buf_hdr_t *hdr = pbuf->b_hdr;
ASSERT(!refcount_is_zero(&pbuf->b_hdr->b_refcnt));
ASSERT3U((char *)bp - (char *)pbuf->b_data, <, pbuf->b_hdr->b_size);
@@ -2510,8 +2727,6 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf,
err = arc_read_nolock(pio, spa, bp, done, private, priority,
zio_flags, arc_flags, zb);
-
- ASSERT3P(hdr, ==, pbuf->b_hdr);
rw_exit(&pbuf->b_lock);
return (err);
}
@@ -2728,7 +2943,7 @@ top:
* released by l2arc_read_done().
*/
rzio = zio_read_phys(pio, vd, addr, size,
- buf->b_data, ZIO_CHECKSUM_OFF,
+ buf->b_data, ZIO_CHECKSUM_OFF,
l2arc_read_done, cb, priority, zio_flags |
ZIO_FLAG_DONT_CACHE | ZIO_FLAG_CANFAIL |
ZIO_FLAG_DONT_PROPAGATE |
@@ -2823,6 +3038,8 @@ arc_buf_evict(arc_buf_t *buf)
arc_buf_hdr_t *hdr;
kmutex_t *hash_lock;
arc_buf_t **bufp;
+ list_t *list, *evicted_list;
+ kmutex_t *lock, *evicted_lock;
rw_enter(&buf->b_lock, RW_WRITER);
hdr = buf->b_hdr;
@@ -2871,16 +3088,18 @@ arc_buf_evict(arc_buf_t *buf)
evicted_state =
(old_state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost;
- mutex_enter(&old_state->arcs_mtx);
- mutex_enter(&evicted_state->arcs_mtx);
+ get_buf_info(hdr, old_state, &list, &lock);
+ get_buf_info(hdr, evicted_state, &evicted_list, &evicted_lock);
+ mutex_enter(lock);
+ mutex_enter(evicted_lock);
arc_change_state(evicted_state, hdr, hash_lock);
ASSERT(HDR_IN_HASH_TABLE(hdr));
hdr->b_flags |= ARC_IN_HASH_TABLE;
hdr->b_flags &= ~ARC_BUF_AVAILABLE;
- mutex_exit(&evicted_state->arcs_mtx);
- mutex_exit(&old_state->arcs_mtx);
+ mutex_exit(evicted_lock);
+ mutex_exit(lock);
}
mutex_exit(hash_lock);
rw_exit(&buf->b_lock);
@@ -3426,7 +3645,8 @@ void
arc_init(void)
{
int prefetch_tunable_set = 0;
-
+ int i;
+
mutex_init(&arc_reclaim_thr_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&arc_reclaim_thr_cv, NULL, CV_DEFAULT, NULL);
mutex_init(&arc_lowmem_lock, NULL, MUTEX_DEFAULT, NULL);
@@ -3494,33 +3714,33 @@ arc_init(void)
arc_l2c_only = &ARC_l2c_only;
arc_size = 0;
- mutex_init(&arc_anon->arcs_mtx, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&arc_mru->arcs_mtx, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&arc_mru_ghost->arcs_mtx, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&arc_mfu->arcs_mtx, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&arc_mfu_ghost->arcs_mtx, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&arc_l2c_only->arcs_mtx, NULL, MUTEX_DEFAULT, NULL);
-
- list_create(&arc_mru->arcs_list[ARC_BUFC_METADATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mru->arcs_list[ARC_BUFC_DATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mfu->arcs_list[ARC_BUFC_METADATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mfu->arcs_list[ARC_BUFC_DATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
- list_create(&arc_l2c_only->arcs_list[ARC_BUFC_DATA],
- sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ for (i = 0; i < ARC_BUFC_NUMLISTS; i++) {
+ mutex_init(&arc_anon->arcs_locks[i].arcs_lock,
+ NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&arc_mru->arcs_locks[i].arcs_lock,
+ NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&arc_mru_ghost->arcs_locks[i].arcs_lock,
+ NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&arc_mfu->arcs_locks[i].arcs_lock,
+ NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&arc_mfu_ghost->arcs_locks[i].arcs_lock,
+ NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&arc_l2c_only->arcs_locks[i].arcs_lock,
+ NULL, MUTEX_DEFAULT, NULL);
+
+ list_create(&arc_mru->arcs_lists[i],
+ sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ list_create(&arc_mru_ghost->arcs_lists[i],
+ sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ list_create(&arc_mfu->arcs_lists[i],
+ sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ list_create(&arc_mfu_ghost->arcs_lists[i],
+ sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ list_create(&arc_mfu_ghost->arcs_lists[i],
+ sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ list_create(&arc_l2c_only->arcs_lists[i],
+ sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node));
+ }
buf_init();
@@ -3557,7 +3777,7 @@ arc_init(void)
#ifdef _KERNEL
if (TUNABLE_INT_FETCH("vfs.zfs.prefetch_disable", &zfs_prefetch_disable))
prefetch_tunable_set = 1;
-
+
#ifdef __i386__
if (prefetch_tunable_set == 0) {
printf("ZFS NOTICE: Prefetch is disabled by default on i386 "
@@ -3566,7 +3786,7 @@ arc_init(void)
"to /boot/loader.conf.\n");
zfs_prefetch_disable=1;
}
-#else
+#else
if ((((uint64_t)physmem * PAGESIZE) < (1ULL << 32)) &&
prefetch_tunable_set == 0) {
printf("ZFS NOTICE: Prefetch is disabled by default if less "
@@ -3575,7 +3795,7 @@ arc_init(void)
"to /boot/loader.conf.\n");
zfs_prefetch_disable=1;
}
-#endif
+#endif
/* Warn about ZFS memory and address space requirements. */
if (((uint64_t)physmem * PAGESIZE) < (256 + 128 + 64) * (1 << 20)) {
printf("ZFS WARNING: Recommended minimum RAM size is 512MB; "
@@ -3594,6 +3814,7 @@ arc_init(void)
void
arc_fini(void)
{
+ int i;
mutex_enter(&arc_reclaim_thr_lock);
arc_thread_exit = 1;
@@ -3615,20 +3836,20 @@ arc_fini(void)
mutex_destroy(&arc_reclaim_thr_lock);
cv_destroy(&arc_reclaim_thr_cv);
- list_destroy(&arc_mru->arcs_list[ARC_BUFC_METADATA]);
- list_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA]);
- list_destroy(&arc_mfu->arcs_list[ARC_BUFC_METADATA]);
- list_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA]);
- list_destroy(&arc_mru->arcs_list[ARC_BUFC_DATA]);
- list_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA]);
- list_destroy(&arc_mfu->arcs_list[ARC_BUFC_DATA]);
- list_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA]);
-
- mutex_destroy(&arc_anon->arcs_mtx);
- mutex_destroy(&arc_mru->arcs_mtx);
- mutex_destroy(&arc_mru_ghost->arcs_mtx);
- mutex_destroy(&arc_mfu->arcs_mtx);
- mutex_destroy(&arc_mfu_ghost->arcs_mtx);
+ for (i = 0; i < ARC_BUFC_NUMLISTS; i++) {
+ list_destroy(&arc_mru->arcs_lists[i]);
+ list_destroy(&arc_mru_ghost->arcs_lists[i]);
+ list_destroy(&arc_mfu->arcs_lists[i]);
+ list_destroy(&arc_mfu_ghost->arcs_lists[i]);
+ list_destroy(&arc_l2c_only->arcs_lists[i]);
+
+ mutex_destroy(&arc_anon->arcs_locks[i].arcs_lock);
+ mutex_destroy(&arc_mru->arcs_locks[i].arcs_lock);
+ mutex_destroy(&arc_mru_ghost->arcs_locks[i].arcs_lock);
+ mutex_destroy(&arc_mfu->arcs_locks[i].arcs_lock);
+ mutex_destroy(&arc_mfu_ghost->arcs_locks[i].arcs_lock);
+ mutex_destroy(&arc_l2c_only->arcs_locks[i].arcs_lock);
+ }
mutex_destroy(&zfs_write_limit_lock);
@@ -4024,26 +4245,27 @@ static list_t *
l2arc_list_locked(int list_num, kmutex_t **lock)
{
list_t *list;
-
- ASSERT(list_num >= 0 && list_num <= 3);
-
- switch (list_num) {
- case 0:
- list = &arc_mfu->arcs_list[ARC_BUFC_METADATA];
- *lock = &arc_mfu->arcs_mtx;
- break;
- case 1:
- list = &arc_mru->arcs_list[ARC_BUFC_METADATA];
- *lock = &arc_mru->arcs_mtx;
- break;
- case 2:
- list = &arc_mfu->arcs_list[ARC_BUFC_DATA];
- *lock = &arc_mfu->arcs_mtx;
- break;
- case 3:
- list = &arc_mru->arcs_list[ARC_BUFC_DATA];
- *lock = &arc_mru->arcs_mtx;
- break;
+ int idx;
+
+ ASSERT(list_num >= 0 && list_num < 2 * ARC_BUFC_NUMLISTS);
+
+ if (list_num < ARC_BUFC_NUMMETADATALISTS) {
+ idx = list_num;
+ list = &arc_mfu->arcs_lists[idx];
+ *lock = ARCS_LOCK(arc_mfu, idx);
+ } else if (list_num < ARC_BUFC_NUMMETADATALISTS * 2) {
+ idx = list_num - ARC_BUFC_NUMMETADATALISTS;
+ list = &arc_mru->arcs_lists[idx];
+ *lock = ARCS_LOCK(arc_mru, idx);
+ } else if (list_num < (ARC_BUFC_NUMMETADATALISTS * 2 +
+ ARC_BUFC_NUMDATALISTS)) {
+ idx = list_num - ARC_BUFC_NUMMETADATALISTS;
+ list = &arc_mfu->arcs_lists[idx];
+ *lock = ARCS_LOCK(arc_mfu, idx);
+ } else {
+ idx = list_num - ARC_BUFC_NUMLISTS;
+ list = &arc_mru->arcs_lists[idx];
+ *lock = ARCS_LOCK(arc_mru, idx);
}
ASSERT(!(MUTEX_HELD(*lock)));
@@ -4210,13 +4432,15 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
head = kmem_cache_alloc(hdr_cache, KM_PUSHPAGE);
head->b_flags |= ARC_L2_WRITE_HEAD;
+ ARCSTAT_BUMP(arcstat_l2_write_buffer_iter);
/*
* Copy buffers for L2ARC writing.
*/
mutex_enter(&l2arc_buflist_mtx);
- for (try = 0; try <= 3; try++) {
+ for (try = 0; try < 2 * ARC_BUFC_NUMLISTS; try++) {
list = l2arc_list_locked(try, &list_lock);
passed_sz = 0;
+ ARCSTAT_BUMP(arcstat_l2_write_buffer_list_iter);
/*
* L2ARC fast warmup.
@@ -4229,52 +4453,65 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
ab = list_head(list);
else
ab = list_tail(list);
+ if (ab == NULL)
+ ARCSTAT_BUMP(arcstat_l2_write_buffer_list_null_iter);
for (; ab; ab = ab_prev) {
if (arc_warm == B_FALSE)
ab_prev = list_next(list, ab);
else
ab_prev = list_prev(list, ab);
+ ARCSTAT_INCR(arcstat_l2_write_buffer_bytes_scanned, ab->b_size);
hash_lock = HDR_LOCK(ab);
have_lock = MUTEX_HELD(hash_lock);
if (!have_lock && !mutex_tryenter(hash_lock)) {
+ ARCSTAT_BUMP(arcstat_l2_write_trylock_fail);
/*
* Skip this buffer rather than waiting.
*/
continue;
}
+ if (ab->b_l2hdr != NULL) {
+ /*
+ * Already in L2ARC.
+ */
+ mutex_exit(hash_lock);
+ ARCSTAT_BUMP(arcstat_l2_write_in_l2);
+ continue;
+ }
+
passed_sz += ab->b_size;
if (passed_sz > headroom) {
/*
* Searched too far.
*/
mutex_exit(hash_lock);
+ ARCSTAT_BUMP(arcstat_l2_write_passed_headroom);
break;
}
if (ab->b_spa != spa) {
mutex_exit(hash_lock);
+ ARCSTAT_BUMP(arcstat_l2_write_spa_mismatch);
continue;
}
- if (ab->b_l2hdr != NULL) {
- /*
- * Already in L2ARC.
- */
+ if (HDR_IO_IN_PROGRESS(ab)) {
mutex_exit(hash_lock);
+ ARCSTAT_BUMP(arcstat_l2_write_hdr_io_in_progress);
continue;
}
-
- if (HDR_IO_IN_PROGRESS(ab) || !HDR_L2CACHE(ab)) {
+ if (!HDR_L2CACHE(ab)) {
mutex_exit(hash_lock);
+ ARCSTAT_BUMP(arcstat_l2_write_not_cacheable);
continue;
}
-
if ((write_sz + ab->b_size) > target_sz) {
full = B_TRUE;
mutex_exit(hash_lock);
+ ARCSTAT_BUMP(arcstat_l2_write_full);
break;
}
@@ -4298,8 +4535,10 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
cb->l2wcb_head = head;
pio = zio_root(spa, l2arc_write_done, cb,
ZIO_FLAG_CANFAIL);
+ ARCSTAT_BUMP(arcstat_l2_write_pios);
}
+ ARCSTAT_INCR(arcstat_l2_write_bytes_written, ab->b_size);
/*
* Create and add a new L2ARC header.
*/
@@ -4395,7 +4634,7 @@ l2arc_feed_thread(void *dummy __unused)
*/
CALLB_CPR_SAFE_BEGIN(&cpr);
(void) cv_timedwait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock,
- hz * l2arc_feed_secs);
+ hz * l2arc_feed_secs >> l2arc_feed_secs_shift);
CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock);
/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
index 2494c1e..3bf0939 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
@@ -2210,9 +2210,6 @@ dbuf_write_ready(zio_t *zio, arc_buf_t *buf, void *vdb)
for (i = db->db.db_size >> SPA_BLKPTRSHIFT; i > 0; i--, ibp++) {
if (BP_IS_HOLE(ibp))
continue;
- ASSERT3U(BP_GET_LSIZE(ibp), ==,
- db->db_level == 1 ? dn->dn_datablksz :
- (1<<dn->dn_phys->dn_indblkshift));
fill += ibp->blk_fill;
}
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c
index cddc64d..5cc56a9 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c
@@ -49,11 +49,11 @@ uint32_t zfetch_block_cap = 256;
uint64_t zfetch_array_rd_sz = 1024 * 1024;
SYSCTL_DECL(_vfs_zfs);
-SYSCTL_INT(_vfs_zfs, OID_AUTO, prefetch_disable, CTLFLAG_RDTUN,
+SYSCTL_INT(_vfs_zfs, OID_AUTO, prefetch_disable, CTLFLAG_RW,
&zfs_prefetch_disable, 0, "Disable prefetch");
SYSCTL_NODE(_vfs_zfs, OID_AUTO, zfetch, CTLFLAG_RW, 0, "ZFS ZFETCH");
TUNABLE_INT("vfs.zfs.zfetch.max_streams", &zfetch_max_streams);
-SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, max_streams, CTLFLAG_RDTUN,
+SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, max_streams, CTLFLAG_RW,
&zfetch_max_streams, 0, "Max # of streams per zfetch");
TUNABLE_INT("vfs.zfs.zfetch.min_sec_reap", &zfetch_min_sec_reap);
SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, min_sec_reap, CTLFLAG_RDTUN,
@@ -338,8 +338,10 @@ top:
reset = !prefetched && zs->zst_len > 1;
- mutex_enter(&zs->zst_lock);
-
+ if (mutex_tryenter(&zs->zst_lock) == 0) {
+ rc = 1;
+ goto out;
+ }
if (zh->zst_offset != zs->zst_offset + zs->zst_len) {
mutex_exit(&zs->zst_lock);
goto top;
@@ -363,8 +365,10 @@ top:
reset = !prefetched && zs->zst_len > 1;
- mutex_enter(&zs->zst_lock);
-
+ if (mutex_tryenter(&zs->zst_lock) == 0) {
+ rc = 1;
+ goto out;
+ }
if (zh->zst_offset != zs->zst_offset - zh->zst_len) {
mutex_exit(&zs->zst_lock);
goto top;
@@ -391,8 +395,10 @@ top:
zs->zst_len) && (zs->zst_len != zs->zst_stride)) {
/* strided forward access */
- mutex_enter(&zs->zst_lock);
-
+ if (mutex_tryenter(&zs->zst_lock) == 0) {
+ rc = 1;
+ goto out;
+ }
if ((zh->zst_offset - zs->zst_offset - zs->zst_stride >=
zs->zst_len) || (zs->zst_len == zs->zst_stride)) {
mutex_exit(&zs->zst_lock);
@@ -408,8 +414,10 @@ top:
zs->zst_len) && (zs->zst_len != zs->zst_stride)) {
/* strided reverse access */
- mutex_enter(&zs->zst_lock);
-
+ if (mutex_tryenter(&zs->zst_lock) == 0) {
+ rc = 1;
+ goto out;
+ }
if ((zh->zst_offset - zs->zst_offset + zs->zst_stride >=
zs->zst_len) || (zs->zst_len == zs->zst_stride)) {
mutex_exit(&zs->zst_lock);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index d5c57e7..819473e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -29,6 +29,7 @@
#include <sys/bio.h>
#include <sys/disk.h>
#include <sys/spa.h>
+#include <sys/spa_impl.h>
#include <sys/vdev_impl.h>
#include <sys/fs/zfs.h>
#include <sys/zio.h>
@@ -505,17 +506,26 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
if ((owned = mtx_owned(&Giant)))
mtx_unlock(&Giant);
error = 0;
- cp = vdev_geom_open_by_path(vd, 1);
- if (cp == NULL) {
- /*
- * The device at vd->vdev_path doesn't have the expected guid.
- * The disks might have merely moved around so try all other
- * geom providers to find one with the right guid.
- */
- cp = vdev_geom_open_by_guid(vd);
- }
- if (cp == NULL)
+
+ /*
+ * If we're creating pool, just find GEOM provider by its name
+ * and ignore GUID mismatches.
+ */
+ if (vd->vdev_spa->spa_load_state == SPA_LOAD_NONE)
cp = vdev_geom_open_by_path(vd, 0);
+ else {
+ cp = vdev_geom_open_by_path(vd, 1);
+ if (cp == NULL) {
+ /*
+ * The device at vd->vdev_path doesn't have the
+ * expected guid. The disks might have merely
+ * moved around so try all other GEOM providers
+ * to find one with the right guid.
+ */
+ cp = vdev_geom_open_by_guid(vd);
+ }
+ }
+
if (cp == NULL) {
ZFS_LOG(1, "Provider %s not found.", vd->vdev_path);
error = ENOENT;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
index eb93721..9825d83 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
@@ -2235,11 +2235,24 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
return (EPERM);
}
+#ifdef sun
if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
(zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
*check_privs = B_FALSE;
return (EPERM);
}
+#else
+ /*
+ * In FreeBSD we allow to modify directory's content is ZFS_NOUNLINK
+ * (sunlnk) is set. We just don't allow directory removal, which is
+ * handled in zfs_zaccess_delete().
+ */
+ if ((v4_mode & ACE_DELETE) &&
+ (zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
+ *check_privs = B_FALSE;
+ return (EPERM);
+ }
+#endif
if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
(zp->z_phys->zp_flags & ZFS_AV_QUARANTINED))) {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index ad8165b..07c9b61 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -868,13 +868,15 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
ZFS_ENTER_NOERROR(zfsvfs);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
+
+ ZFS_EXIT(zfsvfs);
+
if (error == 0) {
*vpp = ZTOV(rootzp);
error = vn_lock(*vpp, flags);
(*vpp)->v_vflag |= VV_ROOT;
}
- ZFS_EXIT(zfsvfs);
return (error);
}
@@ -1143,13 +1145,13 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
VN_RELE(ZTOV(zp));
err = EINVAL;
}
+ ZFS_EXIT(zfsvfs);
if (err != 0)
*vpp = NULL;
else {
*vpp = ZTOV(zp);
vn_lock(*vpp, flags);
}
- ZFS_EXIT(zfsvfs);
return (err);
}
@@ -1237,8 +1239,8 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
} else {
VN_HOLD(*vpp);
}
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
ZFS_EXIT(zfsvfs);
+ vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
return (0);
}
@@ -1259,10 +1261,11 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
return (EINVAL);
}
+ ZFS_EXIT(zfsvfs);
+
*vpp = ZTOV(zp);
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
vnode_create_vobject(*vpp, zp->z_phys->zp_size, curthread);
- ZFS_EXIT(zfsvfs);
return (0);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index 4f61f5f..59a58dd 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -1209,15 +1209,17 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
ltype = VOP_ISLOCKED(dvp);
VOP_UNLOCK(dvp, 0);
}
+ ZFS_EXIT(zfsvfs);
error = vn_lock(*vpp, cnp->cn_lkflags);
if (cnp->cn_flags & ISDOTDOT)
vn_lock(dvp, ltype | LK_RETRY);
if (error != 0) {
VN_RELE(*vpp);
*vpp = NULL;
- ZFS_EXIT(zfsvfs);
return (error);
}
+ } else {
+ ZFS_EXIT(zfsvfs);
}
#ifdef FREEBSD_NAMECACHE
@@ -1237,8 +1239,6 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
}
#endif
- ZFS_EXIT(zfsvfs);
-
return (error);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
index 4650d42..e7227f2 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -91,13 +91,6 @@ zio_init(void)
#ifdef ZIO_USE_UMA
size_t c;
#endif
-#if 0
- vmem_t *data_alloc_arena = NULL;
-
-#ifdef _KERNEL
- data_alloc_arena = zio_alloc_arena;
-#endif
-#endif
zio_cache = kmem_cache_create("zio_cache", sizeof (zio_t), 0,
NULL, NULL, NULL, NULL, NULL, 0);
@@ -132,8 +125,7 @@ zio_init(void)
(void) sprintf(name, "zio_data_buf_%lu", (ulong_t)size);
zio_data_buf_cache[c] = kmem_cache_create(name, size,
- align, NULL, NULL, NULL, NULL, data_alloc_arena,
- KMC_NODEBUG);
+ align, NULL, NULL, NULL, NULL, NULL, KMC_NODEBUG);
}
}
diff --git a/sys/cddl/dev/cyclic/amd64/cyclic_machdep.c b/sys/cddl/dev/cyclic/amd64/cyclic_machdep.c
deleted file mode 100644
index 9a15b2c..0000000
--- a/sys/cddl/dev/cyclic/amd64/cyclic_machdep.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * Copyright 2007 John Birrell <jb@FreeBSD.org>
- *
- * 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 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 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$
- *
- */
-
-static void enable(cyb_arg_t);
-static void disable(cyb_arg_t);
-static void reprogram(cyb_arg_t, hrtime_t);
-static void xcall(cyb_arg_t, cpu_t *, cyc_func_t, void *);
-
-static cyc_backend_t be = {
- NULL, /* cyb_configure */
- NULL, /* cyb_unconfigure */
- enable,
- disable,
- reprogram,
- xcall,
- NULL /* cyb_arg_t cyb_arg */
-};
-
-static void
-cyclic_ap_start(void *dummy)
-{
- /* Initialise the rest of the CPUs. */
- cyclic_mp_init();
-}
-
-SYSINIT(cyclic_ap_start, SI_SUB_SMP, SI_ORDER_ANY, cyclic_ap_start, NULL);
-
-/*
- * Machine dependent cyclic subsystem initialisation.
- */
-static void
-cyclic_machdep_init(void)
-{
- /* Register the cyclic backend. */
- cyclic_init(&be);
-}
-
-static void
-cyclic_machdep_uninit(void)
-{
- int i;
-
- for (i = 0; i <= mp_maxid; i++)
- /* Reset the cyclic clock callback hook. */
- lapic_cyclic_clock_func[i] = NULL;
-
- /* De-register the cyclic backend. */
- cyclic_uninit();
-}
-
-static hrtime_t exp_due[MAXCPU];
-
-/*
- * This function is the one registered by the machine dependent
- * initialiser as the callback for high speed timer events.
- */
-static void
-cyclic_clock(struct trapframe *frame)
-{
- cpu_t *c = &solaris_cpu[curcpu];
-
- if (c->cpu_cyclic != NULL && gethrtime() >= exp_due[curcpu]) {
- if (TRAPF_USERMODE(frame)) {
- c->cpu_profile_pc = 0;
- c->cpu_profile_upc = TRAPF_PC(frame);
- } else {
- c->cpu_profile_pc = TRAPF_PC(frame);
- c->cpu_profile_upc = 0;
- }
-
- c->cpu_intr_actv = 1;
-
- /* Fire any timers that are due. */
- cyclic_fire(c);
-
- c->cpu_intr_actv = 0;
- }
-}
-
-static void enable(cyb_arg_t arg)
-{
- /* Register the cyclic clock callback function. */
- lapic_cyclic_clock_func[curcpu] = cyclic_clock;
-}
-
-static void disable(cyb_arg_t arg)
-{
- /* Reset the cyclic clock callback function. */
- lapic_cyclic_clock_func[curcpu] = NULL;
-}
-
-static void reprogram(cyb_arg_t arg, hrtime_t exp)
-{
- exp_due[curcpu] = exp;
-}
-
-static void xcall(cyb_arg_t arg, cpu_t *c, cyc_func_t func, void *param)
-{
- /*
- * If the target CPU is the current one, just call the
- * function. This covers the non-SMP case.
- */
- if (c == &solaris_cpu[curcpu])
- (*func)(param);
- else
- smp_rendezvous_cpus((cpumask_t) (1 << c->cpuid), NULL,
- func, smp_no_rendevous_barrier, param);
-}
diff --git a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
index fa40db9..0b6ab59 100644
--- a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
+++ b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
@@ -67,7 +67,7 @@ cyclic_machdep_uninit(void)
for (i = 0; i <= mp_maxid; i++)
/* Reset the cyclic clock callback hook. */
- lapic_cyclic_clock_func[i] = NULL;
+ cyclic_clock_func[i] = NULL;
/* De-register the cyclic backend. */
cyclic_uninit();
@@ -105,13 +105,13 @@ cyclic_clock(struct trapframe *frame)
static void enable(cyb_arg_t arg)
{
/* Register the cyclic clock callback function. */
- lapic_cyclic_clock_func[curcpu] = cyclic_clock;
+ cyclic_clock_func[curcpu] = cyclic_clock;
}
static void disable(cyb_arg_t arg)
{
/* Reset the cyclic clock callback function. */
- lapic_cyclic_clock_func[curcpu] = NULL;
+ cyclic_clock_func[curcpu] = NULL;
}
static void reprogram(cyb_arg_t arg, hrtime_t exp)
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index 84e832c..aad550e 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -29,6 +29,10 @@
#ifndef _COMPAT_FREEBSD32_FREEBSD32_H_
#define _COMPAT_FREEBSD32_FREEBSD32_H_
+#include <sys/procfs.h>
+#include <sys/socket.h>
+#include <sys/user.h>
+
#define PTRIN(v) (void *)(uintptr_t) (v)
#define PTROUT(v) (u_int32_t)(uintptr_t) (v)
@@ -140,15 +144,15 @@ struct stat32 {
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
- struct timespec32 st_atimespec;
- struct timespec32 st_mtimespec;
- struct timespec32 st_ctimespec;
+ struct timespec32 st_atim;
+ struct timespec32 st_mtim;
+ struct timespec32 st_ctim;
off_t st_size;
int64_t st_blocks;
u_int32_t st_blksize;
u_int32_t st_flags;
u_int32_t st_gen;
- struct timespec32 st_birthtimespec;
+ struct timespec32 st_birthtim;
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
};
@@ -197,4 +201,114 @@ struct i386_ldt_args32 {
uint32_t num;
};
+/*
+ * Alternative layouts for <sys/procfs.h>
+ */
+struct prstatus32 {
+ int pr_version;
+ u_int pr_statussz;
+ u_int pr_gregsetsz;
+ u_int pr_fpregsetsz;
+ int pr_osreldate;
+ int pr_cursig;
+ pid_t pr_pid;
+ struct reg32 pr_reg;
+};
+
+struct prpsinfo32 {
+ int pr_version;
+ u_int pr_psinfosz;
+ char pr_fname[PRFNAMESZ+1];
+ char pr_psargs[PRARGSZ+1];
+};
+
+struct mq_attr32 {
+ int mq_flags;
+ int mq_maxmsg;
+ int mq_msgsize;
+ int mq_curmsgs;
+ int __reserved[4];
+};
+
+struct kinfo_proc32 {
+ int ki_structsize;
+ int ki_layout;
+ uint32_t ki_args;
+ uint32_t ki_paddr;
+ uint32_t ki_addr;
+ uint32_t ki_tracep;
+ uint32_t ki_textvp;
+ uint32_t ki_fd;
+ uint32_t ki_vmspace;
+ uint32_t ki_wchan;
+ pid_t ki_pid;
+ pid_t ki_ppid;
+ pid_t ki_pgid;
+ pid_t ki_tpgid;
+ pid_t ki_sid;
+ pid_t ki_tsid;
+ short ki_jobc;
+ short ki_spare_short1;
+ dev_t ki_tdev;
+ sigset_t ki_siglist;
+ sigset_t ki_sigmask;
+ sigset_t ki_sigignore;
+ sigset_t ki_sigcatch;
+ uid_t ki_uid;
+ uid_t ki_ruid;
+ uid_t ki_svuid;
+ gid_t ki_rgid;
+ gid_t ki_svgid;
+ short ki_ngroups;
+ short ki_spare_short2;
+ gid_t ki_groups[KI_NGROUPS];
+ uint32_t ki_size;
+ int32_t ki_rssize;
+ int32_t ki_swrss;
+ int32_t ki_tsize;
+ int32_t ki_dsize;
+ int32_t ki_ssize;
+ u_short ki_xstat;
+ u_short ki_acflag;
+ fixpt_t ki_pctcpu;
+ u_int ki_estcpu;
+ u_int ki_slptime;
+ u_int ki_swtime;
+ int ki_spareint1;
+ u_int64_t ki_runtime;
+ struct timeval32 ki_start;
+ struct timeval32 ki_childtime;
+ int ki_flag;
+ int ki_kiflag;
+ int ki_traceflag;
+ char ki_stat;
+ signed char ki_nice;
+ char ki_lock;
+ char ki_rqindex;
+ u_char ki_oncpu;
+ u_char ki_lastcpu;
+ char ki_ocomm[OCOMMLEN+1];
+ char ki_wmesg[WMESGLEN+1];
+ char ki_login[LOGNAMELEN+1];
+ char ki_lockname[LOCKNAMELEN+1];
+ char ki_comm[COMMLEN+1];
+ char ki_emul[KI_EMULNAMELEN+1];
+ char ki_sparestrings[68];
+ int ki_spareints[KI_NSPARE_INT];
+ u_int ki_cr_flags;
+ int ki_jid;
+ int ki_numthreads;
+ lwpid_t ki_tid;
+ struct priority ki_pri;
+ struct rusage32 ki_rusage;
+ struct rusage32 ki_rusage_ch;
+ uint32_t ki_pcb;
+ uint32_t ki_kstack;
+ uint32_t ki_udata;
+ uint32_t ki_spareptrs[KI_NSPARE_PTR]; /* spare room for growth */
+ int ki_sparelongs[KI_NSPARE_LONG];
+ int ki_sflag;
+ int ki_tdflags;
+};
+
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
diff --git a/sys/compat/freebsd32/freebsd32_ipc.h b/sys/compat/freebsd32/freebsd32_ipc.h
index 2b07494..320a63f 100644
--- a/sys/compat/freebsd32/freebsd32_ipc.h
+++ b/sys/compat/freebsd32/freebsd32_ipc.h
@@ -147,6 +147,14 @@ struct shmid_ds32_old {
int32_t shm_ctime;
uint32_t shm_internal;
};
+
+void freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32,
+ struct ipc_perm *ip);
+void freebsd32_ipcperm_old_out(struct ipc_perm *ip,
+ struct ipc_perm32_old *ip32);
#endif
+void freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip);
+void freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32);
+
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_IPC_H_ */
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 75b290b..f0fde2b 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
+#define __ELF_WORD_SIZE 32
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/clock.h>
@@ -44,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/file.h> /* Must come after sys/malloc.h */
+#include <sys/imgact.h>
#include <sys/mbuf.h>
#include <sys/mman.h>
#include <sys/module.h>
@@ -91,6 +94,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <machine/cpu.h>
+#include <machine/elf.h>
#include <security/audit/audit.h>
@@ -115,6 +119,38 @@ CTASSERT(sizeof(struct sigaction32) == 24);
static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
+#if BYTE_ORDER == BIG_ENDIAN
+#define PAIR32TO64(type, name) ((name ## 2) | ((type)(name ## 1) << 32))
+#define RETVAL_HI 0
+#define RETVAL_LO 1
+#else
+#define PAIR32TO64(type, name) ((name ## 1) | ((type)(name ## 2) << 32))
+#define RETVAL_HI 1
+#define RETVAL_LO 0
+#endif
+
+void
+freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
+{
+
+ TV_CP(*s, *s32, ru_utime);
+ TV_CP(*s, *s32, ru_stime);
+ CP(*s, *s32, ru_maxrss);
+ CP(*s, *s32, ru_ixrss);
+ CP(*s, *s32, ru_idrss);
+ CP(*s, *s32, ru_isrss);
+ CP(*s, *s32, ru_minflt);
+ CP(*s, *s32, ru_majflt);
+ CP(*s, *s32, ru_nswap);
+ CP(*s, *s32, ru_inblock);
+ CP(*s, *s32, ru_oublock);
+ CP(*s, *s32, ru_msgsnd);
+ CP(*s, *s32, ru_msgrcv);
+ CP(*s, *s32, ru_nsignals);
+ CP(*s, *s32, ru_nvcsw);
+ CP(*s, *s32, ru_nivcsw);
+}
+
int
freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
{
@@ -132,22 +168,7 @@ freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
if (uap->status != NULL)
error = copyout(&status, uap->status, sizeof(status));
if (uap->rusage != NULL && error == 0) {
- TV_CP(ru, ru32, ru_utime);
- TV_CP(ru, ru32, ru_stime);
- CP(ru, ru32, ru_maxrss);
- CP(ru, ru32, ru_ixrss);
- CP(ru, ru32, ru_idrss);
- CP(ru, ru32, ru_isrss);
- CP(ru, ru32, ru_minflt);
- CP(ru, ru32, ru_majflt);
- CP(ru, ru32, ru_nswap);
- CP(ru, ru32, ru_inblock);
- CP(ru, ru32, ru_oublock);
- CP(ru, ru32, ru_msgsnd);
- CP(ru, ru32, ru_msgrcv);
- CP(ru, ru32, ru_nsignals);
- CP(ru, ru32, ru_nvcsw);
- CP(ru, ru32, ru_nivcsw);
+ freebsd32_rusage_out(&ru, &ru32);
error = copyout(&ru32, uap->rusage, sizeof(ru32));
}
return (error);
@@ -426,8 +447,7 @@ freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
int prot = uap->prot;
int flags = uap->flags;
int fd = uap->fd;
- off_t pos = (uap->poslo
- | ((off_t)uap->poshi << 32));
+ off_t pos = PAIR32TO64(off_t,uap->pos);
#ifdef __ia64__
vm_size_t pageoff;
int error;
@@ -523,8 +543,8 @@ freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *
ap.prot = uap->prot;
ap.flags = uap->flags;
ap.fd = uap->fd;
- ap.poslo = uap->poslo;
- ap.poshi = uap->poshi;
+ ap.pos1 = uap->pos1;
+ ap.pos2 = uap->pos2;
return (freebsd32_mmap(td, &ap));
}
@@ -586,7 +606,6 @@ freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
} else
tvp = NULL;
/*
- * XXX big-endian needs to convert the fd_sets too.
* XXX Do pointers need PTRIN()?
*/
return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
@@ -620,7 +639,6 @@ freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
} else
uset = NULL;
/*
- * XXX big-endian needs to convert the fd_sets too.
* XXX Do pointers need PTRIN()?
*/
error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
@@ -744,22 +762,7 @@ freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
if (error)
return (error);
if (uap->rusage != NULL) {
- TV_CP(s, s32, ru_utime);
- TV_CP(s, s32, ru_stime);
- CP(s, s32, ru_maxrss);
- CP(s, s32, ru_ixrss);
- CP(s, s32, ru_idrss);
- CP(s, s32, ru_isrss);
- CP(s, s32, ru_minflt);
- CP(s, s32, ru_majflt);
- CP(s, s32, ru_nswap);
- CP(s, s32, ru_inblock);
- CP(s, s32, ru_oublock);
- CP(s, s32, ru_msgsnd);
- CP(s, s32, ru_msgrcv);
- CP(s, s32, ru_nsignals);
- CP(s, s32, ru_nvcsw);
- CP(s, s32, ru_nivcsw);
+ freebsd32_rusage_out(&s, &s32);
error = copyout(&s32, uap->rusage, sizeof(s32));
}
return (error);
@@ -843,7 +846,7 @@ freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
if (error)
return (error);
- error = kern_preadv(td, uap->fd, auio, uap->offset);
+ error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
free(auio, M_IOV);
return (error);
}
@@ -857,12 +860,12 @@ freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
if (error)
return (error);
- error = kern_pwritev(td, uap->fd, auio, uap->offset);
+ error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
free(auio, M_IOV);
return (error);
}
-static int
+int
freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
int error)
{
@@ -1389,591 +1392,6 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
}
#endif
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
-static void
-freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip)
-{
-
- CP(*ip32, *ip, cuid);
- CP(*ip32, *ip, cgid);
- CP(*ip32, *ip, uid);
- CP(*ip32, *ip, gid);
- CP(*ip32, *ip, mode);
- CP(*ip32, *ip, seq);
- CP(*ip32, *ip, key);
-}
-
-static void
-freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32)
-{
-
- CP(*ip, *ip32, cuid);
- CP(*ip, *ip32, cgid);
- CP(*ip, *ip32, uid);
- CP(*ip, *ip32, gid);
- CP(*ip, *ip32, mode);
- CP(*ip, *ip32, seq);
- CP(*ip, *ip32, key);
-}
-#endif
-
-static void
-freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
-{
-
- CP(*ip32, *ip, cuid);
- CP(*ip32, *ip, cgid);
- CP(*ip32, *ip, uid);
- CP(*ip32, *ip, gid);
- CP(*ip32, *ip, mode);
- CP(*ip32, *ip, seq);
- CP(*ip32, *ip, key);
-}
-
-static void
-freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
-{
-
- CP(*ip, *ip32, cuid);
- CP(*ip, *ip32, cgid);
- CP(*ip, *ip32, uid);
- CP(*ip, *ip32, gid);
- CP(*ip, *ip32, mode);
- CP(*ip, *ip32, seq);
- CP(*ip, *ip32, key);
-}
-
-int
-freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
-{
-
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
- switch (uap->which) {
- case 0:
- return (freebsd7_freebsd32_semctl(td,
- (struct freebsd7_freebsd32_semctl_args *)&uap->a2));
- default:
- return (semsys(td, (struct semsys_args *)uap));
- }
-#else
- return (nosys(td, NULL));
-#endif
-}
-
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
-int
-freebsd7_freebsd32_semctl(struct thread *td,
- struct freebsd7_freebsd32_semctl_args *uap)
-{
- struct semid_ds32_old dsbuf32;
- struct semid_ds dsbuf;
- union semun semun;
- union semun32 arg;
- register_t rval;
- int error;
-
- switch (uap->cmd) {
- case SEM_STAT:
- case IPC_SET:
- case IPC_STAT:
- case GETALL:
- case SETVAL:
- case SETALL:
- error = copyin(uap->arg, &arg, sizeof(arg));
- if (error)
- return (error);
- break;
- }
-
- switch (uap->cmd) {
- case SEM_STAT:
- case IPC_STAT:
- semun.buf = &dsbuf;
- break;
- case IPC_SET:
- error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
- if (error)
- return (error);
- freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
- PTRIN_CP(dsbuf32, dsbuf, sem_base);
- CP(dsbuf32, dsbuf, sem_nsems);
- CP(dsbuf32, dsbuf, sem_otime);
- CP(dsbuf32, dsbuf, sem_ctime);
- semun.buf = &dsbuf;
- break;
- case GETALL:
- case SETALL:
- semun.array = PTRIN(arg.array);
- break;
- case SETVAL:
- semun.val = arg.val;
- break;
- }
-
- error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
- &rval);
- if (error)
- return (error);
-
- switch (uap->cmd) {
- case SEM_STAT:
- case IPC_STAT:
- bzero(&dsbuf32, sizeof(dsbuf32));
- freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
- PTROUT_CP(dsbuf, dsbuf32, sem_base);
- CP(dsbuf, dsbuf32, sem_nsems);
- CP(dsbuf, dsbuf32, sem_otime);
- CP(dsbuf, dsbuf32, sem_ctime);
- error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
- break;
- }
-
- if (error == 0)
- td->td_retval[0] = rval;
- return (error);
-}
-#endif
-
-int
-freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
-{
- struct semid_ds32 dsbuf32;
- struct semid_ds dsbuf;
- union semun semun;
- union semun32 arg;
- register_t rval;
- int error;
-
- switch (uap->cmd) {
- case SEM_STAT:
- case IPC_SET:
- case IPC_STAT:
- case GETALL:
- case SETVAL:
- case SETALL:
- error = copyin(uap->arg, &arg, sizeof(arg));
- if (error)
- return (error);
- break;
- }
-
- switch (uap->cmd) {
- case SEM_STAT:
- case IPC_STAT:
- semun.buf = &dsbuf;
- break;
- case IPC_SET:
- error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
- if (error)
- return (error);
- freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
- PTRIN_CP(dsbuf32, dsbuf, sem_base);
- CP(dsbuf32, dsbuf, sem_nsems);
- CP(dsbuf32, dsbuf, sem_otime);
- CP(dsbuf32, dsbuf, sem_ctime);
- semun.buf = &dsbuf;
- break;
- case GETALL:
- case SETALL:
- semun.array = PTRIN(arg.array);
- break;
- case SETVAL:
- semun.val = arg.val;
- break;
- }
-
- error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
- &rval);
- if (error)
- return (error);
-
- switch (uap->cmd) {
- case SEM_STAT:
- case IPC_STAT:
- bzero(&dsbuf32, sizeof(dsbuf32));
- freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
- PTROUT_CP(dsbuf, dsbuf32, sem_base);
- CP(dsbuf, dsbuf32, sem_nsems);
- CP(dsbuf, dsbuf32, sem_otime);
- CP(dsbuf, dsbuf32, sem_ctime);
- error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
- break;
- }
-
- if (error == 0)
- td->td_retval[0] = rval;
- return (error);
-}
-
-int
-freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
-{
-
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
- switch (uap->which) {
- case 0:
- return (freebsd7_freebsd32_msgctl(td,
- (struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
- case 2:
- return (freebsd32_msgsnd(td,
- (struct freebsd32_msgsnd_args *)&uap->a2));
- case 3:
- return (freebsd32_msgrcv(td,
- (struct freebsd32_msgrcv_args *)&uap->a2));
- default:
- return (msgsys(td, (struct msgsys_args *)uap));
- }
-#else
- return (nosys(td, NULL));
-#endif
-}
-
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
-int
-freebsd7_freebsd32_msgctl(struct thread *td,
- struct freebsd7_freebsd32_msgctl_args *uap)
-{
- struct msqid_ds msqbuf;
- struct msqid_ds32_old msqbuf32;
- int error;
-
- if (uap->cmd == IPC_SET) {
- error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
- if (error)
- return (error);
- freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
- PTRIN_CP(msqbuf32, msqbuf, msg_first);
- PTRIN_CP(msqbuf32, msqbuf, msg_last);
- CP(msqbuf32, msqbuf, msg_cbytes);
- CP(msqbuf32, msqbuf, msg_qnum);
- CP(msqbuf32, msqbuf, msg_qbytes);
- CP(msqbuf32, msqbuf, msg_lspid);
- CP(msqbuf32, msqbuf, msg_lrpid);
- CP(msqbuf32, msqbuf, msg_stime);
- CP(msqbuf32, msqbuf, msg_rtime);
- CP(msqbuf32, msqbuf, msg_ctime);
- }
- error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
- if (error)
- return (error);
- if (uap->cmd == IPC_STAT) {
- bzero(&msqbuf32, sizeof(msqbuf32));
- freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
- PTROUT_CP(msqbuf, msqbuf32, msg_first);
- PTROUT_CP(msqbuf, msqbuf32, msg_last);
- CP(msqbuf, msqbuf32, msg_cbytes);
- CP(msqbuf, msqbuf32, msg_qnum);
- CP(msqbuf, msqbuf32, msg_qbytes);
- CP(msqbuf, msqbuf32, msg_lspid);
- CP(msqbuf, msqbuf32, msg_lrpid);
- CP(msqbuf, msqbuf32, msg_stime);
- CP(msqbuf, msqbuf32, msg_rtime);
- CP(msqbuf, msqbuf32, msg_ctime);
- error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
- }
- return (error);
-}
-#endif
-
-int
-freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
-{
- struct msqid_ds msqbuf;
- struct msqid_ds32 msqbuf32;
- int error;
-
- if (uap->cmd == IPC_SET) {
- error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
- if (error)
- return (error);
- freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
- PTRIN_CP(msqbuf32, msqbuf, msg_first);
- PTRIN_CP(msqbuf32, msqbuf, msg_last);
- CP(msqbuf32, msqbuf, msg_cbytes);
- CP(msqbuf32, msqbuf, msg_qnum);
- CP(msqbuf32, msqbuf, msg_qbytes);
- CP(msqbuf32, msqbuf, msg_lspid);
- CP(msqbuf32, msqbuf, msg_lrpid);
- CP(msqbuf32, msqbuf, msg_stime);
- CP(msqbuf32, msqbuf, msg_rtime);
- CP(msqbuf32, msqbuf, msg_ctime);
- }
- error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
- if (error)
- return (error);
- if (uap->cmd == IPC_STAT) {
- freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
- PTROUT_CP(msqbuf, msqbuf32, msg_first);
- PTROUT_CP(msqbuf, msqbuf32, msg_last);
- CP(msqbuf, msqbuf32, msg_cbytes);
- CP(msqbuf, msqbuf32, msg_qnum);
- CP(msqbuf, msqbuf32, msg_qbytes);
- CP(msqbuf, msqbuf32, msg_lspid);
- CP(msqbuf, msqbuf32, msg_lrpid);
- CP(msqbuf, msqbuf32, msg_stime);
- CP(msqbuf, msqbuf32, msg_rtime);
- CP(msqbuf, msqbuf32, msg_ctime);
- error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
- }
- return (error);
-}
-
-int
-freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
-{
- const void *msgp;
- long mtype;
- int32_t mtype32;
- int error;
-
- msgp = PTRIN(uap->msgp);
- if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
- return (error);
- mtype = mtype32;
- return (kern_msgsnd(td, uap->msqid,
- (const char *)msgp + sizeof(mtype32),
- uap->msgsz, uap->msgflg, mtype));
-}
-
-int
-freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
-{
- void *msgp;
- long mtype;
- int32_t mtype32;
- int error;
-
- msgp = PTRIN(uap->msgp);
- if ((error = kern_msgrcv(td, uap->msqid,
- (char *)msgp + sizeof(mtype32), uap->msgsz,
- uap->msgtyp, uap->msgflg, &mtype)) != 0)
- return (error);
- mtype32 = (int32_t)mtype;
- return (copyout(&mtype32, msgp, sizeof(mtype32)));
-}
-
-int
-freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
-{
-
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
- switch (uap->which) {
- case 0: { /* shmat */
- struct shmat_args ap;
-
- ap.shmid = uap->a2;
- ap.shmaddr = PTRIN(uap->a3);
- ap.shmflg = uap->a4;
- return (sysent[SYS_shmat].sy_call(td, &ap));
- }
- case 2: { /* shmdt */
- struct shmdt_args ap;
-
- ap.shmaddr = PTRIN(uap->a2);
- return (sysent[SYS_shmdt].sy_call(td, &ap));
- }
- case 3: { /* shmget */
- struct shmget_args ap;
-
- ap.key = uap->a2;
- ap.size = uap->a3;
- ap.shmflg = uap->a4;
- return (sysent[SYS_shmget].sy_call(td, &ap));
- }
- case 4: { /* shmctl */
- struct freebsd7_freebsd32_shmctl_args ap;
-
- ap.shmid = uap->a2;
- ap.cmd = uap->a3;
- ap.buf = PTRIN(uap->a4);
- return (freebsd7_freebsd32_shmctl(td, &ap));
- }
- case 1: /* oshmctl */
- default:
- return (EINVAL);
- }
-#else
- return (nosys(td, NULL));
-#endif
-}
-
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
-int
-freebsd7_freebsd32_shmctl(struct thread *td,
- struct freebsd7_freebsd32_shmctl_args *uap)
-{
- int error = 0;
- union {
- struct shmid_ds shmid_ds;
- struct shm_info shm_info;
- struct shminfo shminfo;
- } u;
- union {
- struct shmid_ds32_old shmid_ds32;
- struct shm_info32 shm_info32;
- struct shminfo32 shminfo32;
- } u32;
- size_t sz;
-
- if (uap->cmd == IPC_SET) {
- if ((error = copyin(uap->buf, &u32.shmid_ds32,
- sizeof(u32.shmid_ds32))))
- goto done;
- freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
- &u.shmid_ds.shm_perm);
- CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
- CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
- CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
- CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
- CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
- CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
- CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
- }
-
- error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
- if (error)
- goto done;
-
- /* Cases in which we need to copyout */
- switch (uap->cmd) {
- case IPC_INFO:
- CP(u.shminfo, u32.shminfo32, shmmax);
- CP(u.shminfo, u32.shminfo32, shmmin);
- CP(u.shminfo, u32.shminfo32, shmmni);
- CP(u.shminfo, u32.shminfo32, shmseg);
- CP(u.shminfo, u32.shminfo32, shmall);
- error = copyout(&u32.shminfo32, uap->buf,
- sizeof(u32.shminfo32));
- break;
- case SHM_INFO:
- CP(u.shm_info, u32.shm_info32, used_ids);
- CP(u.shm_info, u32.shm_info32, shm_rss);
- CP(u.shm_info, u32.shm_info32, shm_tot);
- CP(u.shm_info, u32.shm_info32, shm_swp);
- CP(u.shm_info, u32.shm_info32, swap_attempts);
- CP(u.shm_info, u32.shm_info32, swap_successes);
- error = copyout(&u32.shm_info32, uap->buf,
- sizeof(u32.shm_info32));
- break;
- case SHM_STAT:
- case IPC_STAT:
- freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm,
- &u32.shmid_ds32.shm_perm);
- if (u.shmid_ds.shm_segsz > INT32_MAX)
- u32.shmid_ds32.shm_segsz = INT32_MAX;
- else
- CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
- CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
- CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
- CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
- CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
- CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
- CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
- u32.shmid_ds32.shm_internal = 0;
- error = copyout(&u32.shmid_ds32, uap->buf,
- sizeof(u32.shmid_ds32));
- break;
- }
-
-done:
- if (error) {
- /* Invalidate the return value */
- td->td_retval[0] = -1;
- }
- return (error);
-}
-#endif
-
-int
-freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
-{
- int error = 0;
- union {
- struct shmid_ds shmid_ds;
- struct shm_info shm_info;
- struct shminfo shminfo;
- } u;
- union {
- struct shmid_ds32 shmid_ds32;
- struct shm_info32 shm_info32;
- struct shminfo32 shminfo32;
- } u32;
- size_t sz;
-
- if (uap->cmd == IPC_SET) {
- if ((error = copyin(uap->buf, &u32.shmid_ds32,
- sizeof(u32.shmid_ds32))))
- goto done;
- freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
- &u.shmid_ds.shm_perm);
- CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
- CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
- CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
- CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
- CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
- CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
- CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
- }
-
- error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
- if (error)
- goto done;
-
- /* Cases in which we need to copyout */
- switch (uap->cmd) {
- case IPC_INFO:
- CP(u.shminfo, u32.shminfo32, shmmax);
- CP(u.shminfo, u32.shminfo32, shmmin);
- CP(u.shminfo, u32.shminfo32, shmmni);
- CP(u.shminfo, u32.shminfo32, shmseg);
- CP(u.shminfo, u32.shminfo32, shmall);
- error = copyout(&u32.shminfo32, uap->buf,
- sizeof(u32.shminfo32));
- break;
- case SHM_INFO:
- CP(u.shm_info, u32.shm_info32, used_ids);
- CP(u.shm_info, u32.shm_info32, shm_rss);
- CP(u.shm_info, u32.shm_info32, shm_tot);
- CP(u.shm_info, u32.shm_info32, shm_swp);
- CP(u.shm_info, u32.shm_info32, swap_attempts);
- CP(u.shm_info, u32.shm_info32, swap_successes);
- error = copyout(&u32.shm_info32, uap->buf,
- sizeof(u32.shm_info32));
- break;
- case SHM_STAT:
- case IPC_STAT:
- freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
- &u32.shmid_ds32.shm_perm);
- if (u.shmid_ds.shm_segsz > INT32_MAX)
- u32.shmid_ds32.shm_segsz = INT32_MAX;
- else
- CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
- CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
- CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
- CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
- CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
- CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
- CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
- error = copyout(&u32.shmid_ds32, uap->buf,
- sizeof(u32.shmid_ds32));
- break;
- }
-
-done:
- if (error) {
- /* Invalidate the return value */
- td->td_retval[0] = -1;
- }
- return (error);
-}
-
int
freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
{
@@ -1982,7 +1400,7 @@ freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
ap.fd = uap->fd;
ap.buf = uap->buf;
ap.nbyte = uap->nbyte;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
return (pread(td, &ap));
}
@@ -1994,7 +1412,7 @@ freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
ap.fd = uap->fd;
ap.buf = uap->buf;
ap.nbyte = uap->nbyte;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
return (pwrite(td, &ap));
}
@@ -2006,13 +1424,13 @@ freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
off_t pos;
ap.fd = uap->fd;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
ap.whence = uap->whence;
error = lseek(td, &ap);
/* Expand the quad return into two parts for eax and edx */
pos = *(off_t *)(td->td_retval);
- td->td_retval[0] = pos & 0xffffffff; /* %eax */
- td->td_retval[1] = pos >> 32; /* %edx */
+ td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
+ td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
return error;
}
@@ -2022,7 +1440,7 @@ freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
struct truncate_args ap;
ap.path = uap->path;
- ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
+ ap.length = PAIR32TO64(off_t,uap->length);
return (truncate(td, &ap));
}
@@ -2032,7 +1450,7 @@ freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
struct ftruncate_args ap;
ap.fd = uap->fd;
- ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
+ ap.length = PAIR32TO64(off_t,uap->length);
return (ftruncate(td, &ap));
}
@@ -2064,7 +1482,7 @@ freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args
ap.fd = uap->fd;
ap.buf = uap->buf;
ap.nbyte = uap->nbyte;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
return (pread(td, &ap));
}
@@ -2076,7 +1494,7 @@ freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_ar
ap.fd = uap->fd;
ap.buf = uap->buf;
ap.nbyte = uap->nbyte;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
return (pwrite(td, &ap));
}
@@ -2088,13 +1506,13 @@ freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args
off_t pos;
ap.fd = uap->fd;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
ap.whence = uap->whence;
error = lseek(td, &ap);
/* Expand the quad return into two parts for eax and edx */
pos = *(off_t *)(td->td_retval);
- td->td_retval[0] = pos & 0xffffffff; /* %eax */
- td->td_retval[1] = pos >> 32; /* %edx */
+ td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
+ td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
return error;
}
@@ -2104,7 +1522,7 @@ freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncat
struct truncate_args ap;
ap.path = uap->path;
- ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
+ ap.length = PAIR32TO64(off_t,uap->length);
return (truncate(td, &ap));
}
@@ -2114,7 +1532,7 @@ freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftrunc
struct ftruncate_args ap;
ap.fd = uap->fd;
- ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
+ ap.length = PAIR32TO64(off_t,uap->length);
return (ftruncate(td, &ap));
}
#endif /* COMPAT_FREEBSD6 */
@@ -2141,7 +1559,7 @@ freebsd32_do_sendfile(struct thread *td,
ap.fd = uap->fd;
ap.s = uap->s;
- ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
+ ap.offset = PAIR32TO64(off_t,uap->offset);
ap.nbytes = uap->nbytes;
ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */
ap.sbytes = uap->sbytes;
@@ -2208,9 +1626,9 @@ copy_stat( struct stat *in, struct stat32 *out)
CP(*in, *out, st_uid);
CP(*in, *out, st_gid);
CP(*in, *out, st_rdev);
- TS_CP(*in, *out, st_atimespec);
- TS_CP(*in, *out, st_mtimespec);
- TS_CP(*in, *out, st_ctimespec);
+ TS_CP(*in, *out, st_atim);
+ TS_CP(*in, *out, st_mtim);
+ TS_CP(*in, *out, st_ctim);
CP(*in, *out, st_size);
CP(*in, *out, st_blocks);
CP(*in, *out, st_blksize);
@@ -2879,7 +2297,7 @@ freebsd32_cpuset_setid(struct thread *td,
struct cpuset_setid_args ap;
ap.which = uap->which;
- ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
+ ap.id = PAIR32TO64(id_t,uap->id);
ap.setid = uap->setid;
return (cpuset_setid(td, &ap));
@@ -2893,7 +2311,7 @@ freebsd32_cpuset_getid(struct thread *td,
ap.level = uap->level;
ap.which = uap->which;
- ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
+ ap.id = PAIR32TO64(id_t,uap->id);
ap.setid = uap->setid;
return (cpuset_getid(td, &ap));
@@ -2907,7 +2325,7 @@ freebsd32_cpuset_getaffinity(struct thread *td,
ap.level = uap->level;
ap.which = uap->which;
- ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
+ ap.id = PAIR32TO64(id_t,uap->id);
ap.cpusetsize = uap->cpusetsize;
ap.mask = uap->mask;
@@ -2922,7 +2340,7 @@ freebsd32_cpuset_setaffinity(struct thread *td,
ap.level = uap->level;
ap.which = uap->which;
- ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
+ ap.id = PAIR32TO64(id_t,uap->id);
ap.cpusetsize = uap->cpusetsize;
ap.mask = uap->mask;
@@ -3072,3 +2490,153 @@ syscall32_module_handler(struct module *mod, int what, void *arg)
return (error);
}
}
+
+int
+syscall32_helper_register(struct syscall_helper_data *sd)
+{
+ struct syscall_helper_data *sd1;
+ int error;
+
+ for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
+ error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
+ &sd1->old_sysent);
+ if (error != 0) {
+ syscall32_helper_unregister(sd);
+ return (error);
+ }
+ sd1->registered = 1;
+ }
+ return (0);
+}
+
+int
+syscall32_helper_unregister(struct syscall_helper_data *sd)
+{
+ struct syscall_helper_data *sd1;
+
+ for (sd1 = sd; sd1->registered != 0; sd1++) {
+ syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent);
+ sd1->registered = 0;
+ }
+ return (0);
+}
+
+register_t *
+freebsd32_copyout_strings(struct image_params *imgp)
+{
+ int argc, envc;
+ u_int32_t *vectp;
+ char *stringp, *destp;
+ u_int32_t *stack_base;
+ struct freebsd32_ps_strings *arginfo;
+ size_t execpath_len;
+ int szsigcode;
+
+ /*
+ * Calculate string base and vector table pointers.
+ * Also deal with signal trampoline code for this exec type.
+ */
+ if (imgp->execpath != NULL && imgp->auxargs != NULL)
+ execpath_len = strlen(imgp->execpath) + 1;
+ else
+ execpath_len = 0;
+ arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
+ szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
+ destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
+ roundup(execpath_len, sizeof(char *)) -
+ roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+
+ /*
+ * install sigcode
+ */
+ if (szsigcode)
+ copyout(imgp->proc->p_sysent->sv_sigcode,
+ ((caddr_t)arginfo - szsigcode), szsigcode);
+
+ /*
+ * Copy the image path for the rtld.
+ */
+ if (execpath_len != 0) {
+ imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len;
+ copyout(imgp->execpath, (void *)imgp->execpathp,
+ execpath_len);
+ }
+
+ /*
+ * If we have a valid auxargs ptr, prepare some room
+ * on the stack.
+ */
+ if (imgp->auxargs) {
+ /*
+ * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
+ * lower compatibility.
+ */
+ imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
+ : (AT_COUNT * 2);
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets,and imgp->auxarg_size is room
+ * for argument of Runtime loader.
+ */
+ vectp = (u_int32_t *) (destp - (imgp->args->argc +
+ imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
+ sizeof(u_int32_t));
+ } else
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets
+ */
+ vectp = (u_int32_t *)
+ (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
+
+ /*
+ * vectp also becomes our initial stack base
+ */
+ stack_base = vectp;
+
+ stringp = imgp->args->begin_argv;
+ argc = imgp->args->argc;
+ envc = imgp->args->envc;
+ /*
+ * Copy out strings - arguments and environment.
+ */
+ copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
+
+ /*
+ * Fill in "ps_strings" struct for ps, w, etc.
+ */
+ suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
+ suword32(&arginfo->ps_nargvstr, argc);
+
+ /*
+ * Fill in argument portion of vector table.
+ */
+ for (; argc > 0; --argc) {
+ suword32(vectp++, (u_int32_t)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* a null vector table pointer separates the argp's from the envp's */
+ suword32(vectp++, 0);
+
+ suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
+ suword32(&arginfo->ps_nenvstr, envc);
+
+ /*
+ * Fill in environment portion of vector table.
+ */
+ for (; envc > 0; --envc) {
+ suword32(vectp++, (u_int32_t)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* end of vector table is a null pointer */
+ suword32(vectp, 0);
+
+ return ((register_t *)stack_base);
+}
+
diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h
index 7418dbd..7134040 100644
--- a/sys/compat/freebsd32/freebsd32_proto.h
+++ b/sys/compat/freebsd32/freebsd32_proto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 200111 2009-12-04 21:52:31Z kib
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 205325 2010-03-19 11:10:24Z kib
*/
#ifndef _FREEBSD32_SYSPROTO_H_
@@ -32,6 +32,9 @@ struct thread;
#define PADR_(t) 0
#endif
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
struct freebsd32_wait4_args {
char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)];
char status_l_[PADL_(int *)]; int * status; char status_r_[PADR_(int *)];
@@ -223,13 +226,15 @@ struct freebsd32_preadv_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
- char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
};
struct freebsd32_pwritev_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
- char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
};
struct freebsd32_modstat_args {
char modid_l_[PADL_(int)]; int modid; char modid_r_[PADR_(int)];
@@ -294,13 +299,24 @@ struct freebsd32_nmount_args {
struct freebsd32_sendfile_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
char nbytes_l_[PADL_(size_t)]; size_t nbytes; char nbytes_r_[PADR_(size_t)];
char hdtr_l_[PADL_(struct sf_hdtr32 *)]; struct sf_hdtr32 * hdtr; char hdtr_r_[PADR_(struct sf_hdtr32 *)];
char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
+struct freebsd32_ksem_init_args {
+ char idp_l_[PADL_(semid_t *)]; semid_t * idp; char idp_r_[PADR_(semid_t *)];
+ char value_l_[PADL_(unsigned int)]; unsigned int value; char value_r_[PADR_(unsigned int)];
+};
+struct freebsd32_ksem_open_args {
+ char idp_l_[PADL_(semid_t *)]; semid_t * idp; char idp_r_[PADR_(semid_t *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char oflag_l_[PADL_(int)]; int oflag; char oflag_r_[PADR_(int)];
+ char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)];
+ char value_l_[PADL_(unsigned int)]; unsigned int value; char value_r_[PADR_(unsigned int)];
+};
struct freebsd32_sigaction_args {
char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
char act_l_[PADL_(struct sigaction32 *)]; struct sigaction32 * act; char act_r_[PADR_(struct sigaction32 *)];
@@ -325,6 +341,10 @@ struct freebsd32_umtx_lock_args {
struct freebsd32_umtx_unlock_args {
char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)];
};
+struct freebsd32_ksem_timedwait_args {
+ char id_l_[PADL_(semid_t)]; semid_t id; char id_r_[PADR_(semid_t)];
+ char abstime_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abstime; char abstime_r_[PADR_(const struct timespec32 *)];
+};
struct freebsd32_thr_suspend_args {
char timeout_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * timeout; char timeout_r_[PADR_(const struct timespec32 *)];
};
@@ -339,23 +359,95 @@ struct freebsd32_thr_new_args {
char param_l_[PADL_(struct thr_param32 *)]; struct thr_param32 * param; char param_r_[PADR_(struct thr_param32 *)];
char param_size_l_[PADL_(int)]; int param_size; char param_size_r_[PADR_(int)];
};
+struct freebsd32_kmq_open_args {
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)];
+ char attr_l_[PADL_(const struct mq_attr32 *)]; const struct mq_attr32 * attr; char attr_r_[PADR_(const struct mq_attr32 *)];
+};
+struct freebsd32_kmq_setattr_args {
+ char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)];
+ char attr_l_[PADL_(const struct mq_attr32 *)]; const struct mq_attr32 * attr; char attr_r_[PADR_(const struct mq_attr32 *)];
+ char oattr_l_[PADL_(struct mq_attr32 *)]; struct mq_attr32 * oattr; char oattr_r_[PADR_(struct mq_attr32 *)];
+};
+struct freebsd32_kmq_timedreceive_args {
+ char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)];
+ char msg_ptr_l_[PADL_(char *)]; char * msg_ptr; char msg_ptr_r_[PADR_(char *)];
+ char msg_len_l_[PADL_(size_t)]; size_t msg_len; char msg_len_r_[PADR_(size_t)];
+ char msg_prio_l_[PADL_(unsigned *)]; unsigned * msg_prio; char msg_prio_r_[PADR_(unsigned *)];
+ char abs_timeout_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abs_timeout; char abs_timeout_r_[PADR_(const struct timespec32 *)];
+};
+struct freebsd32_kmq_timedsend_args {
+ char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)];
+ char msg_ptr_l_[PADL_(const char *)]; const char * msg_ptr; char msg_ptr_r_[PADR_(const char *)];
+ char msg_len_l_[PADL_(size_t)]; size_t msg_len; char msg_len_r_[PADR_(size_t)];
+ char msg_prio_l_[PADL_(unsigned)]; unsigned msg_prio; char msg_prio_r_[PADR_(unsigned)];
+ char abs_timeout_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abs_timeout; char abs_timeout_r_[PADR_(const struct timespec32 *)];
+};
struct freebsd32_aio_fsync_args {
char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
char aiocbp_l_[PADL_(struct aiocb32 *)]; struct aiocb32 * aiocbp; char aiocbp_r_[PADR_(struct aiocb32 *)];
};
+#ifdef PAD64_REQUIRED
+struct freebsd32_pread_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
+ char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+};
+struct freebsd32_pwrite_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
+ char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+};
+struct freebsd32_mmap_args {
+ char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
+ char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+ char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
+ char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
+};
+struct freebsd32_lseek_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
+};
+struct freebsd32_truncate_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
+ char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+};
+struct freebsd32_ftruncate_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
+ char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+};
+#else
struct freebsd32_pread_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
};
struct freebsd32_pwrite_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
};
struct freebsd32_mmap_args {
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
@@ -363,51 +455,62 @@ struct freebsd32_mmap_args {
char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char poslo_l_[PADL_(u_int32_t)]; u_int32_t poslo; char poslo_r_[PADR_(u_int32_t)];
- char poshi_l_[PADL_(u_int32_t)]; u_int32_t poshi; char poshi_r_[PADR_(u_int32_t)];
+ char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
+ char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
};
struct freebsd32_lseek_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
};
struct freebsd32_truncate_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
- char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
+ char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
};
struct freebsd32_ftruncate_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
- char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
+ char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
};
+#endif
+#ifdef PAD64_REQUIRED
struct freebsd32_cpuset_setid_args {
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
- char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
+ char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
char setid_l_[PADL_(cpusetid_t)]; cpusetid_t setid; char setid_r_[PADR_(cpusetid_t)];
};
+#else
+struct freebsd32_cpuset_setid_args {
+ char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
+ char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
+ char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
+ char setid_l_[PADL_(cpusetid_t)]; cpusetid_t setid; char setid_r_[PADR_(cpusetid_t)];
+};
+#endif
struct freebsd32_cpuset_getid_args {
char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
- char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
+ char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
+ char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
char setid_l_[PADL_(cpusetid_t *)]; cpusetid_t * setid; char setid_r_[PADR_(cpusetid_t *)];
};
struct freebsd32_cpuset_getaffinity_args {
char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
- char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
+ char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
+ char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
char cpusetsize_l_[PADL_(size_t)]; size_t cpusetsize; char cpusetsize_r_[PADR_(size_t)];
char mask_l_[PADL_(cpuset_t *)]; cpuset_t * mask; char mask_r_[PADR_(cpuset_t *)];
};
struct freebsd32_cpuset_setaffinity_args {
char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
- char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
+ char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
+ char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
char cpusetsize_l_[PADL_(size_t)]; size_t cpusetsize; char cpusetsize_r_[PADR_(size_t)];
char mask_l_[PADL_(const cpuset_t *)]; const cpuset_t * mask; char mask_r_[PADR_(const cpuset_t *)];
};
@@ -461,6 +564,9 @@ struct freebsd32_pselect_args {
char ts_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * ts; char ts_r_[PADR_(const struct timespec32 *)];
char sm_l_[PADL_(const sigset_t *)]; const sigset_t * sm; char sm_r_[PADR_(const sigset_t *)];
};
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
int freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *);
int freebsd32_recvmsg(struct thread *, struct freebsd32_recvmsg_args *);
int freebsd32_sendmsg(struct thread *, struct freebsd32_sendmsg_args *);
@@ -515,6 +621,8 @@ int freebsd32_aio_waitcomplete(struct thread *, struct freebsd32_aio_waitcomplet
int freebsd32_kevent(struct thread *, struct freebsd32_kevent_args *);
int freebsd32_nmount(struct thread *, struct freebsd32_nmount_args *);
int freebsd32_sendfile(struct thread *, struct freebsd32_sendfile_args *);
+int freebsd32_ksem_init(struct thread *, struct freebsd32_ksem_init_args *);
+int freebsd32_ksem_open(struct thread *, struct freebsd32_ksem_open_args *);
int freebsd32_sigaction(struct thread *, struct freebsd32_sigaction_args *);
int freebsd32_sigreturn(struct thread *, struct freebsd32_sigreturn_args *);
int freebsd32_getcontext(struct thread *, struct freebsd32_getcontext_args *);
@@ -522,17 +630,35 @@ int freebsd32_setcontext(struct thread *, struct freebsd32_setcontext_args *);
int freebsd32_swapcontext(struct thread *, struct freebsd32_swapcontext_args *);
int freebsd32_umtx_lock(struct thread *, struct freebsd32_umtx_lock_args *);
int freebsd32_umtx_unlock(struct thread *, struct freebsd32_umtx_unlock_args *);
+int freebsd32_ksem_timedwait(struct thread *, struct freebsd32_ksem_timedwait_args *);
int freebsd32_thr_suspend(struct thread *, struct freebsd32_thr_suspend_args *);
int freebsd32_umtx_op(struct thread *, struct freebsd32_umtx_op_args *);
int freebsd32_thr_new(struct thread *, struct freebsd32_thr_new_args *);
+int freebsd32_kmq_open(struct thread *, struct freebsd32_kmq_open_args *);
+int freebsd32_kmq_setattr(struct thread *, struct freebsd32_kmq_setattr_args *);
+int freebsd32_kmq_timedreceive(struct thread *, struct freebsd32_kmq_timedreceive_args *);
+int freebsd32_kmq_timedsend(struct thread *, struct freebsd32_kmq_timedsend_args *);
int freebsd32_aio_fsync(struct thread *, struct freebsd32_aio_fsync_args *);
+#ifdef PAD64_REQUIRED
+int freebsd32_pread(struct thread *, struct freebsd32_pread_args *);
+int freebsd32_pwrite(struct thread *, struct freebsd32_pwrite_args *);
+int freebsd32_mmap(struct thread *, struct freebsd32_mmap_args *);
+int freebsd32_lseek(struct thread *, struct freebsd32_lseek_args *);
+int freebsd32_truncate(struct thread *, struct freebsd32_truncate_args *);
+int freebsd32_ftruncate(struct thread *, struct freebsd32_ftruncate_args *);
+#else
int freebsd32_pread(struct thread *, struct freebsd32_pread_args *);
int freebsd32_pwrite(struct thread *, struct freebsd32_pwrite_args *);
int freebsd32_mmap(struct thread *, struct freebsd32_mmap_args *);
int freebsd32_lseek(struct thread *, struct freebsd32_lseek_args *);
int freebsd32_truncate(struct thread *, struct freebsd32_truncate_args *);
int freebsd32_ftruncate(struct thread *, struct freebsd32_ftruncate_args *);
+#endif
+#ifdef PAD64_REQUIRED
+int freebsd32_cpuset_setid(struct thread *, struct freebsd32_cpuset_setid_args *);
+#else
int freebsd32_cpuset_setid(struct thread *, struct freebsd32_cpuset_setid_args *);
+#endif
int freebsd32_cpuset_getid(struct thread *, struct freebsd32_cpuset_getid_args *);
int freebsd32_cpuset_getaffinity(struct thread *, struct freebsd32_cpuset_getaffinity_args *);
int freebsd32_cpuset_setaffinity(struct thread *, struct freebsd32_cpuset_setaffinity_args *);
@@ -548,6 +674,9 @@ int freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *);
#ifdef COMPAT_43
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
struct ofreebsd32_sigaction_args {
char signum_l_[PADL_(int)]; int signum; char signum_r_[PADR_(int)];
char nsa_l_[PADL_(struct osigaction32 *)]; struct osigaction32 * nsa; char nsa_r_[PADR_(struct osigaction32 *)];
@@ -575,6 +704,12 @@ struct ofreebsd32_sigstack_args {
char nss_l_[PADL_(struct sigstack32 *)]; struct sigstack32 * nss; char nss_r_[PADR_(struct sigstack32 *)];
char oss_l_[PADL_(struct sigstack32 *)]; struct sigstack32 * oss; char oss_r_[PADR_(struct sigstack32 *)];
};
+#ifdef PAD64_REQUIRED
+#else
+#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int ofreebsd32_sigaction(struct thread *, struct ofreebsd32_sigaction_args *);
int ofreebsd32_sigprocmask(struct thread *, struct ofreebsd32_sigprocmask_args *);
int ofreebsd32_sigpending(struct thread *, struct ofreebsd32_sigpending_args *);
@@ -589,6 +724,9 @@ int ofreebsd32_sigstack(struct thread *, struct ofreebsd32_sigstack_args *);
#ifdef COMPAT_FREEBSD4
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
struct freebsd4_freebsd32_getfsstat_args {
char buf_l_[PADL_(struct statfs32 *)]; struct statfs32 * buf; char buf_r_[PADR_(struct statfs32 *)];
char bufsize_l_[PADL_(long)]; long bufsize; char bufsize_r_[PADR_(long)];
@@ -609,8 +747,8 @@ struct freebsd4_freebsd32_fhstatfs_args {
struct freebsd4_freebsd32_sendfile_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
char nbytes_l_[PADL_(size_t)]; size_t nbytes; char nbytes_r_[PADR_(size_t)];
char hdtr_l_[PADL_(struct sf_hdtr32 *)]; struct sf_hdtr32 * hdtr; char hdtr_r_[PADR_(struct sf_hdtr32 *)];
char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
@@ -624,6 +762,12 @@ struct freebsd4_freebsd32_sigaction_args {
struct freebsd4_freebsd32_sigreturn_args {
char sigcntxp_l_[PADL_(const struct freebsd4_freebsd32_ucontext *)]; const struct freebsd4_freebsd32_ucontext * sigcntxp; char sigcntxp_r_[PADR_(const struct freebsd4_freebsd32_ucontext *)];
};
+#ifdef PAD64_REQUIRED
+#else
+#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd4_freebsd32_getfsstat(struct thread *, struct freebsd4_freebsd32_getfsstat_args *);
int freebsd4_freebsd32_statfs(struct thread *, struct freebsd4_freebsd32_statfs_args *);
int freebsd4_freebsd32_fstatfs(struct thread *, struct freebsd4_freebsd32_fstatfs_args *);
@@ -637,21 +781,24 @@ int freebsd4_freebsd32_sigreturn(struct thread *, struct freebsd4_freebsd32_sigr
#ifdef COMPAT_FREEBSD6
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
struct freebsd6_freebsd32_pread_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
};
struct freebsd6_freebsd32_pwrite_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
};
struct freebsd6_freebsd32_mmap_args {
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
@@ -660,28 +807,34 @@ struct freebsd6_freebsd32_mmap_args {
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char poslo_l_[PADL_(u_int32_t)]; u_int32_t poslo; char poslo_r_[PADR_(u_int32_t)];
- char poshi_l_[PADL_(u_int32_t)]; u_int32_t poshi; char poshi_r_[PADR_(u_int32_t)];
+ char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
+ char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
};
struct freebsd6_freebsd32_lseek_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
- char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
+ char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
};
struct freebsd6_freebsd32_truncate_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
- char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
+ char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
};
struct freebsd6_freebsd32_ftruncate_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
- char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
+ char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
};
+#ifdef PAD64_REQUIRED
+#else
+#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd6_freebsd32_pread(struct thread *, struct freebsd6_freebsd32_pread_args *);
int freebsd6_freebsd32_pwrite(struct thread *, struct freebsd6_freebsd32_pwrite_args *);
int freebsd6_freebsd32_mmap(struct thread *, struct freebsd6_freebsd32_mmap_args *);
@@ -694,6 +847,9 @@ int freebsd6_freebsd32_ftruncate(struct thread *, struct freebsd6_freebsd32_ftru
#ifdef COMPAT_FREEBSD7
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
struct freebsd7_freebsd32_semctl_args {
char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)];
char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)];
@@ -710,6 +866,12 @@ struct freebsd7_freebsd32_shmctl_args {
char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
char buf_l_[PADL_(struct shmid_ds32_old *)]; struct shmid_ds32_old * buf; char buf_r_[PADR_(struct shmid_ds32_old *)];
};
+#ifdef PAD64_REQUIRED
+#else
+#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd7_freebsd32_semctl(struct thread *, struct freebsd7_freebsd32_semctl_args *);
int freebsd7_freebsd32_msgctl(struct thread *, struct freebsd7_freebsd32_msgctl_args *);
int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_args *);
@@ -794,6 +956,8 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
#define FREEBSD32_SYS_AUE_freebsd32_kevent AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_nmount AUE_NMOUNT
#define FREEBSD32_SYS_AUE_freebsd32_sendfile AUE_SENDFILE
+#define FREEBSD32_SYS_AUE_freebsd32_ksem_init AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_ksem_open AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_sigaction AUE_SIGACTION
#define FREEBSD32_SYS_AUE_freebsd32_sigreturn AUE_SIGRETURN
#define FREEBSD32_SYS_AUE_freebsd32_getcontext AUE_NULL
@@ -801,9 +965,14 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
#define FREEBSD32_SYS_AUE_freebsd32_swapcontext AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_umtx_lock AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_umtx_unlock AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_ksem_timedwait AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_thr_suspend AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_umtx_op AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_thr_new AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_kmq_open AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_kmq_setattr AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_kmq_timedreceive AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_kmq_timedsend AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_aio_fsync AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_pread AUE_PREAD
#define FREEBSD32_SYS_AUE_freebsd32_pwrite AUE_PWRITE
@@ -811,6 +980,13 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
#define FREEBSD32_SYS_AUE_freebsd32_lseek AUE_LSEEK
#define FREEBSD32_SYS_AUE_freebsd32_truncate AUE_TRUNCATE
#define FREEBSD32_SYS_AUE_freebsd32_ftruncate AUE_FTRUNCATE
+#define FREEBSD32_SYS_AUE_freebsd32_pread AUE_PREAD
+#define FREEBSD32_SYS_AUE_freebsd32_pwrite AUE_PWRITE
+#define FREEBSD32_SYS_AUE_freebsd32_mmap AUE_MMAP
+#define FREEBSD32_SYS_AUE_freebsd32_lseek AUE_LSEEK
+#define FREEBSD32_SYS_AUE_freebsd32_truncate AUE_TRUNCATE
+#define FREEBSD32_SYS_AUE_freebsd32_ftruncate AUE_FTRUNCATE
+#define FREEBSD32_SYS_AUE_freebsd32_cpuset_setid AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_cpuset_setid AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_cpuset_getid AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_cpuset_getaffinity AUE_NULL
diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
index abd87eb..c4bff69 100644
--- a/sys/compat/freebsd32/freebsd32_syscall.h
+++ b/sys/compat/freebsd32/freebsd32_syscall.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 200111 2009-12-04 21:52:31Z kib
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 205325 2010-03-19 11:10:24Z kib
*/
#define FREEBSD32_SYS_syscall 0
@@ -303,6 +303,15 @@
#define FREEBSD32_SYS_statfs 396
#define FREEBSD32_SYS_fstatfs 397
#define FREEBSD32_SYS_fhstatfs 398
+#define FREEBSD32_SYS_ksem_close 400
+#define FREEBSD32_SYS_ksem_post 401
+#define FREEBSD32_SYS_ksem_wait 402
+#define FREEBSD32_SYS_ksem_trywait 403
+#define FREEBSD32_SYS_freebsd32_ksem_init 404
+#define FREEBSD32_SYS_freebsd32_ksem_open 405
+#define FREEBSD32_SYS_ksem_unlink 406
+#define FREEBSD32_SYS_ksem_getvalue 407
+#define FREEBSD32_SYS_ksem_destroy 408
#define FREEBSD32_SYS_extattr_set_link 412
#define FREEBSD32_SYS_extattr_get_link 413
#define FREEBSD32_SYS_extattr_delete_link 414
@@ -325,6 +334,7 @@
#define FREEBSD32_SYS_extattr_list_fd 437
#define FREEBSD32_SYS_extattr_list_file 438
#define FREEBSD32_SYS_extattr_list_link 439
+#define FREEBSD32_SYS_freebsd32_ksem_timedwait 441
#define FREEBSD32_SYS_freebsd32_thr_suspend 442
#define FREEBSD32_SYS_thr_wake 443
#define FREEBSD32_SYS_kldunloadf 444
@@ -340,6 +350,12 @@
#define FREEBSD32_SYS_freebsd32_umtx_op 454
#define FREEBSD32_SYS_freebsd32_thr_new 455
#define FREEBSD32_SYS_sigqueue 456
+#define FREEBSD32_SYS_freebsd32_kmq_open 457
+#define FREEBSD32_SYS_freebsd32_kmq_setattr 458
+#define FREEBSD32_SYS_freebsd32_kmq_timedreceive 459
+#define FREEBSD32_SYS_freebsd32_kmq_timedsend 460
+#define FREEBSD32_SYS_kmq_notify 461
+#define FREEBSD32_SYS_kmq_unlink 462
#define FREEBSD32_SYS_abort2 463
#define FREEBSD32_SYS_thr_set_name 464
#define FREEBSD32_SYS_freebsd32_aio_fsync 465
@@ -354,11 +370,18 @@
#define FREEBSD32_SYS_freebsd32_lseek 478
#define FREEBSD32_SYS_freebsd32_truncate 479
#define FREEBSD32_SYS_freebsd32_ftruncate 480
+#define FREEBSD32_SYS_freebsd32_pread 475
+#define FREEBSD32_SYS_freebsd32_pwrite 476
+#define FREEBSD32_SYS_freebsd32_mmap 477
+#define FREEBSD32_SYS_freebsd32_lseek 478
+#define FREEBSD32_SYS_freebsd32_truncate 479
+#define FREEBSD32_SYS_freebsd32_ftruncate 480
#define FREEBSD32_SYS_thr_kill2 481
#define FREEBSD32_SYS_shm_open 482
#define FREEBSD32_SYS_shm_unlink 483
#define FREEBSD32_SYS_cpuset 484
#define FREEBSD32_SYS_freebsd32_cpuset_setid 485
+#define FREEBSD32_SYS_freebsd32_cpuset_setid 485
#define FREEBSD32_SYS_freebsd32_cpuset_getid 486
#define FREEBSD32_SYS_freebsd32_cpuset_getaffinity 487
#define FREEBSD32_SYS_freebsd32_cpuset_setaffinity 488
diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
index 2949d1b..b5e6b6b 100644
--- a/sys/compat/freebsd32/freebsd32_syscalls.c
+++ b/sys/compat/freebsd32/freebsd32_syscalls.c
@@ -3,10 +3,13 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 200111 2009-12-04 21:52:31Z kib
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 205325 2010-03-19 11:10:24Z kib
*/
const char *freebsd32_syscallnames[] = {
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
"syscall", /* 0 = syscall */
"exit", /* 1 = exit */
"fork", /* 2 = fork */
@@ -407,15 +410,15 @@ const char *freebsd32_syscallnames[] = {
"fstatfs", /* 397 = fstatfs */
"fhstatfs", /* 398 = fhstatfs */
"#399", /* 399 = nosys */
- "#400", /* 400 = ksem_close */
- "#401", /* 401 = ksem_post */
- "#402", /* 402 = ksem_wait */
- "#403", /* 403 = ksem_trywait */
- "#404", /* 404 = ksem_init */
- "#405", /* 405 = ksem_open */
- "#406", /* 406 = ksem_unlink */
- "#407", /* 407 = ksem_getvalue */
- "#408", /* 408 = ksem_destroy */
+ "ksem_close", /* 400 = ksem_close */
+ "ksem_post", /* 401 = ksem_post */
+ "ksem_wait", /* 402 = ksem_wait */
+ "ksem_trywait", /* 403 = ksem_trywait */
+ "freebsd32_ksem_init", /* 404 = freebsd32_ksem_init */
+ "freebsd32_ksem_open", /* 405 = freebsd32_ksem_open */
+ "ksem_unlink", /* 406 = ksem_unlink */
+ "ksem_getvalue", /* 407 = ksem_getvalue */
+ "ksem_destroy", /* 408 = ksem_destroy */
"#409", /* 409 = __mac_get_pid */
"#410", /* 410 = __mac_get_link */
"#411", /* 411 = __mac_set_link */
@@ -448,7 +451,7 @@ const char *freebsd32_syscallnames[] = {
"extattr_list_file", /* 438 = extattr_list_file */
"extattr_list_link", /* 439 = extattr_list_link */
"#440", /* 440 = kse_switchin */
- "#441", /* 441 = ksem_timedwait */
+ "freebsd32_ksem_timedwait", /* 441 = freebsd32_ksem_timedwait */
"freebsd32_thr_suspend", /* 442 = freebsd32_thr_suspend */
"thr_wake", /* 443 = thr_wake */
"kldunloadf", /* 444 = kldunloadf */
@@ -464,12 +467,12 @@ const char *freebsd32_syscallnames[] = {
"freebsd32_umtx_op", /* 454 = freebsd32_umtx_op */
"freebsd32_thr_new", /* 455 = freebsd32_thr_new */
"sigqueue", /* 456 = sigqueue */
- "#457", /* 457 = kmq_open */
- "#458", /* 458 = kmq_setattr */
- "#459", /* 459 = kmq_timedreceive */
- "#460", /* 460 = kmq_timedsend */
- "#461", /* 461 = kmq_notify */
- "#462", /* 462 = kmq_unlink */
+ "freebsd32_kmq_open", /* 457 = freebsd32_kmq_open */
+ "freebsd32_kmq_setattr", /* 458 = freebsd32_kmq_setattr */
+ "freebsd32_kmq_timedreceive", /* 459 = freebsd32_kmq_timedreceive */
+ "freebsd32_kmq_timedsend", /* 460 = freebsd32_kmq_timedsend */
+ "kmq_notify", /* 461 = kmq_notify */
+ "kmq_unlink", /* 462 = kmq_unlink */
"abort2", /* 463 = abort2 */
"thr_set_name", /* 464 = thr_set_name */
"freebsd32_aio_fsync", /* 465 = freebsd32_aio_fsync */
@@ -482,17 +485,30 @@ const char *freebsd32_syscallnames[] = {
"sctp_generic_sendmsg", /* 472 = sctp_generic_sendmsg */
"sctp_generic_sendmsg_iov", /* 473 = sctp_generic_sendmsg_iov */
"sctp_generic_recvmsg", /* 474 = sctp_generic_recvmsg */
+#ifdef PAD64_REQUIRED
"freebsd32_pread", /* 475 = freebsd32_pread */
"freebsd32_pwrite", /* 476 = freebsd32_pwrite */
"freebsd32_mmap", /* 477 = freebsd32_mmap */
"freebsd32_lseek", /* 478 = freebsd32_lseek */
"freebsd32_truncate", /* 479 = freebsd32_truncate */
"freebsd32_ftruncate", /* 480 = freebsd32_ftruncate */
+#else
+ "freebsd32_pread", /* 475 = freebsd32_pread */
+ "freebsd32_pwrite", /* 476 = freebsd32_pwrite */
+ "freebsd32_mmap", /* 477 = freebsd32_mmap */
+ "freebsd32_lseek", /* 478 = freebsd32_lseek */
+ "freebsd32_truncate", /* 479 = freebsd32_truncate */
+ "freebsd32_ftruncate", /* 480 = freebsd32_ftruncate */
+#endif
"thr_kill2", /* 481 = thr_kill2 */
"shm_open", /* 482 = shm_open */
"shm_unlink", /* 483 = shm_unlink */
"cpuset", /* 484 = cpuset */
+#ifdef PAD64_REQUIRED
+ "freebsd32_cpuset_setid", /* 485 = freebsd32_cpuset_setid */
+#else
"freebsd32_cpuset_setid", /* 485 = freebsd32_cpuset_setid */
+#endif
"freebsd32_cpuset_getid", /* 486 = freebsd32_cpuset_getid */
"freebsd32_cpuset_getaffinity", /* 487 = freebsd32_cpuset_getaffinity */
"freebsd32_cpuset_setaffinity", /* 488 = freebsd32_cpuset_setaffinity */
diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
index 479c921..445e7de 100644
--- a/sys/compat/freebsd32/freebsd32_sysent.c
+++ b/sys/compat/freebsd32/freebsd32_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 200111 2009-12-04 21:52:31Z kib
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 205325 2010-03-19 11:10:24Z kib
*/
#include "opt_compat.h"
@@ -44,6 +44,9 @@
/* The casts are bogus but will do for now. */
struct sysent freebsd32_sysent[] = {
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 0 = syscall */
{ AS(sys_exit_args), (sy_call_t *)sys_exit, AUE_EXIT, NULL, 0, 0, 0 }, /* 1 = exit */
{ 0, (sy_call_t *)fork, AUE_FORK, NULL, 0, 0, 0 }, /* 2 = fork */
@@ -213,9 +216,9 @@ struct sysent freebsd32_sysent[] = {
{ AS(rtprio_args), (sy_call_t *)rtprio, AUE_RTPRIO, NULL, 0, 0, 0 }, /* 166 = rtprio */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 167 = nosys */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 168 = nosys */
- { AS(freebsd32_semsys_args), (sy_call_t *)freebsd32_semsys, AUE_SEMSYS, NULL, 0, 0, 0 }, /* 169 = freebsd32_semsys */
- { AS(freebsd32_msgsys_args), (sy_call_t *)freebsd32_msgsys, AUE_MSGSYS, NULL, 0, 0, 0 }, /* 170 = freebsd32_msgsys */
- { AS(freebsd32_shmsys_args), (sy_call_t *)freebsd32_shmsys, AUE_SHMSYS, NULL, 0, 0, 0 }, /* 171 = freebsd32_shmsys */
+ { AS(freebsd32_semsys_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 169 = freebsd32_semsys */
+ { AS(freebsd32_msgsys_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 170 = freebsd32_msgsys */
+ { AS(freebsd32_shmsys_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 171 = freebsd32_shmsys */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 172 = nosys */
{ compat6(AS(freebsd6_freebsd32_pread_args),freebsd32_pread), AUE_PREAD, NULL, 0, 0, 0 }, /* 173 = freebsd6 freebsd32_pread */
{ compat6(AS(freebsd6_freebsd32_pwrite_args),freebsd32_pwrite), AUE_PWRITE, NULL, 0, 0, 0 }, /* 174 = freebsd6 freebsd32_pwrite */
@@ -264,18 +267,18 @@ struct sysent freebsd32_sysent[] = {
{ AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 217 = lkmnosys */
{ AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 218 = lkmnosys */
{ AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 }, /* 219 = lkmnosys */
- { compat7(AS(freebsd7_freebsd32_semctl_args),freebsd32_semctl), AUE_SEMCTL, NULL, 0, 0, 0 }, /* 220 = freebsd7 freebsd32_semctl */
- { AS(semget_args), (sy_call_t *)semget, AUE_SEMGET, NULL, 0, 0, 0 }, /* 221 = semget */
- { AS(semop_args), (sy_call_t *)semop, AUE_SEMOP, NULL, 0, 0, 0 }, /* 222 = semop */
+ { 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 220 = freebsd7 freebsd32_semctl */
+ { AS(semget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 221 = semget */
+ { AS(semop_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 222 = semop */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 223 = semconfig */
- { compat7(AS(freebsd7_freebsd32_msgctl_args),freebsd32_msgctl), AUE_MSGCTL, NULL, 0, 0, 0 }, /* 224 = freebsd7 freebsd32_msgctl */
- { AS(msgget_args), (sy_call_t *)msgget, AUE_MSGGET, NULL, 0, 0, 0 }, /* 225 = msgget */
- { AS(freebsd32_msgsnd_args), (sy_call_t *)freebsd32_msgsnd, AUE_MSGSND, NULL, 0, 0, 0 }, /* 226 = freebsd32_msgsnd */
- { AS(freebsd32_msgrcv_args), (sy_call_t *)freebsd32_msgrcv, AUE_MSGRCV, NULL, 0, 0, 0 }, /* 227 = freebsd32_msgrcv */
- { AS(shmat_args), (sy_call_t *)shmat, AUE_SHMAT, NULL, 0, 0, 0 }, /* 228 = shmat */
- { compat7(AS(freebsd7_freebsd32_shmctl_args),freebsd32_shmctl), AUE_SHMCTL, NULL, 0, 0, 0 }, /* 229 = freebsd7 freebsd32_shmctl */
- { AS(shmdt_args), (sy_call_t *)shmdt, AUE_SHMDT, NULL, 0, 0, 0 }, /* 230 = shmdt */
- { AS(shmget_args), (sy_call_t *)shmget, AUE_SHMGET, NULL, 0, 0, 0 }, /* 231 = shmget */
+ { 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 224 = freebsd7 freebsd32_msgctl */
+ { AS(msgget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 225 = msgget */
+ { AS(freebsd32_msgsnd_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 226 = freebsd32_msgsnd */
+ { AS(freebsd32_msgrcv_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 227 = freebsd32_msgrcv */
+ { AS(shmat_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 228 = shmat */
+ { 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 229 = freebsd7 freebsd32_shmctl */
+ { AS(shmdt_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 230 = shmdt */
+ { AS(shmget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 231 = shmget */
{ AS(freebsd32_clock_gettime_args), (sy_call_t *)freebsd32_clock_gettime, AUE_NULL, NULL, 0, 0, 0 }, /* 232 = freebsd32_clock_gettime */
{ AS(freebsd32_clock_settime_args), (sy_call_t *)freebsd32_clock_settime, AUE_CLOCK_SETTIME, NULL, 0, 0, 0 }, /* 233 = freebsd32_clock_settime */
{ AS(freebsd32_clock_getres_args), (sy_call_t *)freebsd32_clock_getres, AUE_NULL, NULL, 0, 0, 0 }, /* 234 = freebsd32_clock_getres */
@@ -444,15 +447,15 @@ struct sysent freebsd32_sysent[] = {
{ AS(fstatfs_args), (sy_call_t *)fstatfs, AUE_FSTATFS, NULL, 0, 0, 0 }, /* 397 = fstatfs */
{ AS(fhstatfs_args), (sy_call_t *)fhstatfs, AUE_FHSTATFS, NULL, 0, 0, 0 }, /* 398 = fhstatfs */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 399 = nosys */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 400 = ksem_close */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 401 = ksem_post */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 402 = ksem_wait */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 403 = ksem_trywait */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 404 = ksem_init */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 405 = ksem_open */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 406 = ksem_unlink */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 407 = ksem_getvalue */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 408 = ksem_destroy */
+ { AS(ksem_close_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 400 = ksem_close */
+ { AS(ksem_post_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 401 = ksem_post */
+ { AS(ksem_wait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 402 = ksem_wait */
+ { AS(ksem_trywait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 403 = ksem_trywait */
+ { AS(freebsd32_ksem_init_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 404 = freebsd32_ksem_init */
+ { AS(freebsd32_ksem_open_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 405 = freebsd32_ksem_open */
+ { AS(ksem_unlink_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 406 = ksem_unlink */
+ { AS(ksem_getvalue_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 407 = ksem_getvalue */
+ { AS(ksem_destroy_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 408 = ksem_destroy */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 409 = __mac_get_pid */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 410 = __mac_get_link */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 411 = __mac_set_link */
@@ -485,7 +488,7 @@ struct sysent freebsd32_sysent[] = {
{ AS(extattr_list_file_args), (sy_call_t *)extattr_list_file, AUE_EXTATTR_LIST_FILE, NULL, 0, 0, 0 }, /* 438 = extattr_list_file */
{ AS(extattr_list_link_args), (sy_call_t *)extattr_list_link, AUE_EXTATTR_LIST_LINK, NULL, 0, 0, 0 }, /* 439 = extattr_list_link */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 440 = kse_switchin */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 441 = ksem_timedwait */
+ { AS(freebsd32_ksem_timedwait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 441 = freebsd32_ksem_timedwait */
{ AS(freebsd32_thr_suspend_args), (sy_call_t *)freebsd32_thr_suspend, AUE_NULL, NULL, 0, 0, 0 }, /* 442 = freebsd32_thr_suspend */
{ AS(thr_wake_args), (sy_call_t *)thr_wake, AUE_NULL, NULL, 0, 0, 0 }, /* 443 = thr_wake */
{ AS(kldunloadf_args), (sy_call_t *)kldunloadf, AUE_MODUNLOAD, NULL, 0, 0, 0 }, /* 444 = kldunloadf */
@@ -501,12 +504,12 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_umtx_op_args), (sy_call_t *)freebsd32_umtx_op, AUE_NULL, NULL, 0, 0, 0 }, /* 454 = freebsd32_umtx_op */
{ AS(freebsd32_thr_new_args), (sy_call_t *)freebsd32_thr_new, AUE_NULL, NULL, 0, 0, 0 }, /* 455 = freebsd32_thr_new */
{ AS(sigqueue_args), (sy_call_t *)sigqueue, AUE_NULL, NULL, 0, 0, 0 }, /* 456 = sigqueue */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 457 = kmq_open */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 458 = kmq_setattr */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 459 = kmq_timedreceive */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 460 = kmq_timedsend */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 461 = kmq_notify */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 462 = kmq_unlink */
+ { AS(freebsd32_kmq_open_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 457 = freebsd32_kmq_open */
+ { AS(freebsd32_kmq_setattr_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 458 = freebsd32_kmq_setattr */
+ { AS(freebsd32_kmq_timedreceive_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 459 = freebsd32_kmq_timedreceive */
+ { AS(freebsd32_kmq_timedsend_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 460 = freebsd32_kmq_timedsend */
+ { AS(kmq_notify_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 461 = kmq_notify */
+ { AS(kmq_unlink_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 462 = kmq_unlink */
{ AS(abort2_args), (sy_call_t *)abort2, AUE_NULL, NULL, 0, 0, 0 }, /* 463 = abort2 */
{ AS(thr_set_name_args), (sy_call_t *)thr_set_name, AUE_NULL, NULL, 0, 0, 0 }, /* 464 = thr_set_name */
{ AS(freebsd32_aio_fsync_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 465 = freebsd32_aio_fsync */
@@ -519,17 +522,30 @@ struct sysent freebsd32_sysent[] = {
{ AS(sctp_generic_sendmsg_args), (sy_call_t *)sctp_generic_sendmsg, AUE_NULL, NULL, 0, 0, 0 }, /* 472 = sctp_generic_sendmsg */
{ AS(sctp_generic_sendmsg_iov_args), (sy_call_t *)sctp_generic_sendmsg_iov, AUE_NULL, NULL, 0, 0, 0 }, /* 473 = sctp_generic_sendmsg_iov */
{ AS(sctp_generic_recvmsg_args), (sy_call_t *)sctp_generic_recvmsg, AUE_NULL, NULL, 0, 0, 0 }, /* 474 = sctp_generic_recvmsg */
+#ifdef PAD64_REQUIRED
+ { AS(freebsd32_pread_args), (sy_call_t *)freebsd32_pread, AUE_PREAD, NULL, 0, 0, 0 }, /* 475 = freebsd32_pread */
+ { AS(freebsd32_pwrite_args), (sy_call_t *)freebsd32_pwrite, AUE_PWRITE, NULL, 0, 0, 0 }, /* 476 = freebsd32_pwrite */
+ { AS(freebsd32_mmap_args), (sy_call_t *)freebsd32_mmap, AUE_MMAP, NULL, 0, 0, 0 }, /* 477 = freebsd32_mmap */
+ { AS(freebsd32_lseek_args), (sy_call_t *)freebsd32_lseek, AUE_LSEEK, NULL, 0, 0, 0 }, /* 478 = freebsd32_lseek */
+ { AS(freebsd32_truncate_args), (sy_call_t *)freebsd32_truncate, AUE_TRUNCATE, NULL, 0, 0, 0 }, /* 479 = freebsd32_truncate */
+ { AS(freebsd32_ftruncate_args), (sy_call_t *)freebsd32_ftruncate, AUE_FTRUNCATE, NULL, 0, 0, 0 }, /* 480 = freebsd32_ftruncate */
+#else
{ AS(freebsd32_pread_args), (sy_call_t *)freebsd32_pread, AUE_PREAD, NULL, 0, 0, 0 }, /* 475 = freebsd32_pread */
{ AS(freebsd32_pwrite_args), (sy_call_t *)freebsd32_pwrite, AUE_PWRITE, NULL, 0, 0, 0 }, /* 476 = freebsd32_pwrite */
{ AS(freebsd32_mmap_args), (sy_call_t *)freebsd32_mmap, AUE_MMAP, NULL, 0, 0, 0 }, /* 477 = freebsd32_mmap */
{ AS(freebsd32_lseek_args), (sy_call_t *)freebsd32_lseek, AUE_LSEEK, NULL, 0, 0, 0 }, /* 478 = freebsd32_lseek */
{ AS(freebsd32_truncate_args), (sy_call_t *)freebsd32_truncate, AUE_TRUNCATE, NULL, 0, 0, 0 }, /* 479 = freebsd32_truncate */
{ AS(freebsd32_ftruncate_args), (sy_call_t *)freebsd32_ftruncate, AUE_FTRUNCATE, NULL, 0, 0, 0 }, /* 480 = freebsd32_ftruncate */
+#endif
{ AS(thr_kill2_args), (sy_call_t *)thr_kill2, AUE_KILL, NULL, 0, 0, 0 }, /* 481 = thr_kill2 */
{ AS(shm_open_args), (sy_call_t *)shm_open, AUE_SHMOPEN, NULL, 0, 0, 0 }, /* 482 = shm_open */
{ AS(shm_unlink_args), (sy_call_t *)shm_unlink, AUE_SHMUNLINK, NULL, 0, 0, 0 }, /* 483 = shm_unlink */
{ AS(cpuset_args), (sy_call_t *)cpuset, AUE_NULL, NULL, 0, 0, 0 }, /* 484 = cpuset */
+#ifdef PAD64_REQUIRED
{ AS(freebsd32_cpuset_setid_args), (sy_call_t *)freebsd32_cpuset_setid, AUE_NULL, NULL, 0, 0, 0 }, /* 485 = freebsd32_cpuset_setid */
+#else
+ { AS(freebsd32_cpuset_setid_args), (sy_call_t *)freebsd32_cpuset_setid, AUE_NULL, NULL, 0, 0, 0 }, /* 485 = freebsd32_cpuset_setid */
+#endif
{ AS(freebsd32_cpuset_getid_args), (sy_call_t *)freebsd32_cpuset_getid, AUE_NULL, NULL, 0, 0, 0 }, /* 486 = freebsd32_cpuset_getid */
{ AS(freebsd32_cpuset_getaffinity_args), (sy_call_t *)freebsd32_cpuset_getaffinity, AUE_NULL, NULL, 0, 0, 0 }, /* 487 = freebsd32_cpuset_getaffinity */
{ AS(freebsd32_cpuset_setaffinity_args), (sy_call_t *)freebsd32_cpuset_setaffinity, AUE_NULL, NULL, 0, 0, 0 }, /* 488 = freebsd32_cpuset_setaffinity */
@@ -554,9 +570,9 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_jail_set_args), (sy_call_t *)freebsd32_jail_set, AUE_NULL, NULL, 0, 0, 0 }, /* 507 = freebsd32_jail_set */
{ AS(jail_remove_args), (sy_call_t *)jail_remove, AUE_NULL, NULL, 0, 0, 0 }, /* 508 = jail_remove */
{ AS(closefrom_args), (sy_call_t *)closefrom, AUE_CLOSEFROM, NULL, 0, 0, 0 }, /* 509 = closefrom */
- { AS(freebsd32_semctl_args), (sy_call_t *)freebsd32_semctl, AUE_SEMCTL, NULL, 0, 0, 0 }, /* 510 = freebsd32_semctl */
- { AS(freebsd32_msgctl_args), (sy_call_t *)freebsd32_msgctl, AUE_MSGCTL, NULL, 0, 0, 0 }, /* 511 = freebsd32_msgctl */
- { AS(freebsd32_shmctl_args), (sy_call_t *)freebsd32_shmctl, AUE_SHMCTL, NULL, 0, 0, 0 }, /* 512 = freebsd32_shmctl */
+ { AS(freebsd32_semctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 510 = freebsd32_semctl */
+ { AS(freebsd32_msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 511 = freebsd32_msgctl */
+ { AS(freebsd32_shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 512 = freebsd32_shmctl */
{ AS(lpathconf_args), (sy_call_t *)lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0 }, /* 513 = lpathconf */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 514 = cap_new */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 515 = cap_getrights */
diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
index 6536b2c..3ac676d 100644
--- a/sys/compat/freebsd32/freebsd32_util.h
+++ b/sys/compat/freebsd32/freebsd32_util.h
@@ -61,7 +61,7 @@ static struct syscall_module_data name##_syscall32_mod = { \
}; \
\
static moduledata_t name##32_mod = { \
- #name, \
+ "sys32/" #name, \
syscall32_module_handler, \
&name##_syscall32_mod \
}; \
@@ -78,9 +78,28 @@ SYSCALL32_MODULE(syscallname, \
& syscallname##_syscall32, & syscallname##_sysent32,\
NULL, NULL);
+#define SYSCALL32_INIT_HELPER(syscallname) { \
+ .new_sysent = { \
+ .sy_narg = (sizeof(struct syscallname ## _args ) \
+ / sizeof(register_t)), \
+ .sy_call = (sy_call_t *)& syscallname, \
+ }, \
+ .syscall_no = FREEBSD32_SYS_##syscallname \
+}
+
int syscall32_register(int *offset, struct sysent *new_sysent,
struct sysent *old_sysent);
int syscall32_deregister(int *offset, struct sysent *old_sysent);
int syscall32_module_handler(struct module *mod, int what, void *arg);
+int syscall32_helper_register(struct syscall_helper_data *sd);
+int syscall32_helper_unregister(struct syscall_helper_data *sd);
+
+struct iovec32;
+struct rusage32;
+register_t *freebsd32_copyout_strings(struct image_params *imgp);
+int freebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt,
+ struct iovec **iov, int error);
+void freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32);
+
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 3abd6e7..1afe586 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -52,6 +52,10 @@
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_proto.h>
+#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
+#define PAD64_REQUIRED
+#endif
+
; Reserved/unimplemented system calls in the range 0-150 inclusive
; are reserved for use in future Berkeley releases.
; Additional system calls implemented in vendor and other
@@ -194,7 +198,6 @@
93 AUE_SELECT STD { int freebsd32_select(int nd, fd_set *in, \
fd_set *ou, fd_set *ex, \
struct timeval32 *tv); }
-; XXX need to override for big-endian - little-endian should work fine.
94 AUE_NULL UNIMPL setdopt
95 AUE_FSYNC NOPROTO { int fsync(int fd); }
96 AUE_SETPRIORITY NOPROTO { int setpriority(int which, int who, \
@@ -306,21 +309,19 @@
struct rtprio *rtp); }
167 AUE_NULL UNIMPL nosys
168 AUE_NULL UNIMPL nosys
-169 AUE_SEMSYS STD { int freebsd32_semsys(int which, int a2, \
+169 AUE_SEMSYS NOSTD { int freebsd32_semsys(int which, int a2, \
int a3, int a4, int a5); }
-170 AUE_MSGSYS STD { int freebsd32_msgsys(int which, int a2, \
+170 AUE_MSGSYS NOSTD { int freebsd32_msgsys(int which, int a2, \
int a3, int a4, int a5, int a6); }
-171 AUE_SHMSYS STD { int freebsd32_shmsys(uint32_t which, uint32_t a2, \
+171 AUE_SHMSYS NOSTD { int freebsd32_shmsys(uint32_t which, uint32_t a2, \
uint32_t a3, uint32_t a4); }
172 AUE_NULL UNIMPL nosys
173 AUE_PREAD COMPAT6 { ssize_t freebsd32_pread(int fd, void *buf, \
size_t nbyte, int pad, \
- u_int32_t offsetlo, u_int32_t offsethi); }
-; XXX note - bigendian is different
+ u_int32_t offset1, u_int32_t offset2); }
174 AUE_PWRITE COMPAT6 { ssize_t freebsd32_pwrite(int fd, \
const void *buf, size_t nbyte, int pad, \
- u_int32_t offsetlo, u_int32_t offsethi); }
-; XXX note - bigendian is different
+ u_int32_t offset1, u_int32_t offset2); }
175 AUE_NULL UNIMPL nosys
176 AUE_NTP_ADJTIME NOPROTO { int ntp_adjtime(struct timex *tp); }
177 AUE_NULL UNIMPL sfork (BSD/OS 2.x)
@@ -355,21 +356,17 @@
char *buf, u_int count, int32_t *basep); }
197 AUE_MMAP COMPAT6 { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
- int pad, u_int32_t poslo, \
- u_int32_t poshi); }
+ int pad, u_int32_t pos1, u_int32_t pos2); }
198 AUE_NULL NOPROTO { int nosys(void); } __syscall \
__syscall_args int
-; XXX note - bigendian is different
199 AUE_LSEEK COMPAT6 { off_t freebsd32_lseek(int fd, int pad, \
- u_int32_t offsetlo, u_int32_t offsethi, \
+ u_int32_t offset1, u_int32_t offset2, \
int whence); }
-; XXX note - bigendian is different
200 AUE_TRUNCATE COMPAT6 { int freebsd32_truncate(char *path, \
- int pad, u_int32_t lengthlo, \
- u_int32_t lengthhi); }
-; XXX note - bigendian is different
+ int pad, u_int32_t length1, \
+ u_int32_t length2); }
201 AUE_FTRUNCATE COMPAT6 { int freebsd32_ftruncate(int fd, int pad, \
- u_int32_t lengthlo, u_int32_t lengthhi); }
+ u_int32_t length1, u_int32_t length2); }
202 AUE_SYSCTL STD { int freebsd32_sysctl(int *name, \
u_int namelen, void *old, \
u_int32_t *oldlenp, void *new, \
@@ -402,28 +399,31 @@
;
; The following were introduced with NetBSD/4.4Lite-2
-; They are initialized by thier respective modules/sysinits
+; They are initialized by their respective modules/sysinits
; XXX PROBLEM!!
-220 AUE_SEMCTL COMPAT7 { int freebsd32_semctl(int semid, int semnum, \
+220 AUE_SEMCTL COMPAT7|NOSTD { int freebsd32_semctl( \
+ int semid, int semnum, \
int cmd, union semun32 *arg); }
-221 AUE_SEMGET NOPROTO { int semget(key_t key, int nsems, \
+221 AUE_SEMGET NOSTD|NOPROTO { int semget(key_t key, int nsems, \
int semflg); }
-222 AUE_SEMOP NOPROTO { int semop(int semid, struct sembuf *sops, \
- u_int nsops); }
+222 AUE_SEMOP NOSTD|NOPROTO { int semop(int semid, \
+ struct sembuf *sops, u_int nsops); }
223 AUE_NULL UNIMPL semconfig
-224 AUE_MSGCTL COMPAT7 { int freebsd32_msgctl(int msqid, int cmd, \
+224 AUE_MSGCTL COMPAT7|NOSTD { int freebsd32_msgctl( \
+ int msqid, int cmd, \
struct msqid_ds32_old *buf); }
-225 AUE_MSGGET NOPROTO { int msgget(key_t key, int msgflg); }
-226 AUE_MSGSND STD { int freebsd32_msgsnd(int msqid, void *msgp, \
+225 AUE_MSGGET NOSTD|NOPROTO { int msgget(key_t key, int msgflg); }
+226 AUE_MSGSND NOSTD { int freebsd32_msgsnd(int msqid, void *msgp, \
size_t msgsz, int msgflg); }
-227 AUE_MSGRCV STD { int freebsd32_msgrcv(int msqid, void *msgp, \
+227 AUE_MSGRCV NOSTD { int freebsd32_msgrcv(int msqid, void *msgp, \
size_t msgsz, long msgtyp, int msgflg); }
-228 AUE_SHMAT NOPROTO { int shmat(int shmid, void *shmaddr, \
+228 AUE_SHMAT NOSTD|NOPROTO { int shmat(int shmid, void *shmaddr, \
int shmflg); }
-229 AUE_SHMCTL COMPAT7 { int freebsd32_shmctl(int shmid, int cmd, \
+229 AUE_SHMCTL COMPAT7|NOSTD { int freebsd32_shmctl( \
+ int shmid, int cmd, \
struct shmid_ds32_old *buf); }
-230 AUE_SHMDT NOPROTO { int shmdt(void *shmaddr); }
-231 AUE_SHMGET NOPROTO { int shmget(key_t key, int size, \
+230 AUE_SHMDT NOSTD|NOPROTO { int shmdt(void *shmaddr); }
+231 AUE_SHMGET NOSTD|NOPROTO { int shmget(key_t key, int size, \
int shmflg); }
;
232 AUE_NULL STD { int freebsd32_clock_gettime(clockid_t clock_id, \
@@ -503,12 +503,12 @@
; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
289 AUE_PREADV STD { ssize_t freebsd32_preadv(int fd, \
struct iovec32 *iovp, \
- u_int iovcnt, off_t offset); }
-; XXX note - bigendian is different
+ u_int iovcnt, \
+ u_int32_t offset1, u_int32_t offset2); }
290 AUE_PWRITEV STD { ssize_t freebsd32_pwritev(int fd, \
struct iovec32 *iovp, \
- u_int iovcnt, off_t offset); }
-; XXX note - bigendian is different
+ u_int iovcnt, \
+ u_int32_t offset1, u_int32_t offset2); }
291 AUE_NULL UNIMPL nosys
292 AUE_NULL UNIMPL nosys
293 AUE_NULL UNIMPL nosys
@@ -581,9 +581,8 @@
334 AUE_NULL NOPROTO { int sched_rr_get_interval (pid_t pid, \
struct timespec *interval); }
335 AUE_NULL NOPROTO { int utrace(const void *addr, size_t len); }
-; XXX note - bigendian is different
336 AUE_SENDFILE COMPAT4 { int freebsd32_sendfile(int fd, int s, \
- u_int32_t offsetlo, u_int32_t offsethi, \
+ u_int32_t offset1, u_int32_t offset2, \
size_t nbytes, struct sf_hdtr32 *hdtr, \
off_t *sbytes, int flags); }
337 AUE_NULL NOPROTO { int kldsym(int fileid, int cmd, \
@@ -686,7 +685,7 @@
392 AUE_NULL NOPROTO { int uuidgen(struct uuid *store, \
int count); }
393 AUE_SENDFILE STD { int freebsd32_sendfile(int fd, int s, \
- u_int32_t offsetlo, u_int32_t offsethi, \
+ u_int32_t offset1, u_int32_t offset2, \
size_t nbytes, struct sf_hdtr32 *hdtr, \
off_t *sbytes, int flags); }
394 AUE_NULL UNIMPL mac_syscall
@@ -698,16 +697,19 @@
398 AUE_FHSTATFS NOPROTO { int fhstatfs(const struct fhandle *u_fhp, \
struct statfs *buf); }
399 AUE_NULL UNIMPL nosys
-; XXX implement these?
-400 AUE_NULL UNIMPL ksem_close
-401 AUE_NULL UNIMPL ksem_post
-402 AUE_NULL UNIMPL ksem_wait
-403 AUE_NULL UNIMPL ksem_trywait
-404 AUE_NULL UNIMPL ksem_init
-405 AUE_NULL UNIMPL ksem_open
-406 AUE_NULL UNIMPL ksem_unlink
-407 AUE_NULL UNIMPL ksem_getvalue
-408 AUE_NULL UNIMPL ksem_destroy
+400 AUE_NULL NOSTD|NOPROTO { int ksem_close(semid_t id); }
+401 AUE_NULL NOSTD|NOPROTO { int ksem_post(semid_t id); }
+402 AUE_NULL NOSTD|NOPROTO { int ksem_wait(semid_t id); }
+403 AUE_NULL NOSTD|NOPROTO { int ksem_trywait(semid_t id); }
+404 AUE_NULL NOSTD { int freebsd32_ksem_init(semid_t *idp, \
+ unsigned int value); }
+405 AUE_NULL NOSTD { int freebsd32_ksem_open(semid_t *idp, \
+ const char *name, int oflag, \
+ mode_t mode, unsigned int value); }
+406 AUE_NULL NOSTD|NOPROTO { int ksem_unlink(const char *name); }
+407 AUE_NULL NOSTD|NOPROTO { int ksem_getvalue(semid_t id, \
+ int *val); }
+408 AUE_NULL NOSTD|NOPROTO { int ksem_destroy(semid_t id); }
409 AUE_NULL UNIMPL __mac_get_pid
410 AUE_NULL UNIMPL __mac_get_link
411 AUE_NULL UNIMPL __mac_set_link
@@ -766,7 +768,8 @@
const char *path, int attrnamespace, \
void *data, size_t nbytes); }
440 AUE_NULL UNIMPL kse_switchin
-441 AUE_NULL UNIMPL ksem_timedwait
+441 AUE_NULL NOSTD { int freebsd32_ksem_timedwait(semid_t id, \
+ const struct timespec32 *abstime); }
442 AUE_NULL STD { int freebsd32_thr_suspend( \
const struct timespec32 *timeout); }
443 AUE_NULL NOPROTO { int thr_wake(long id); }
@@ -794,12 +797,23 @@
int param_size); }
456 AUE_NULL NOPROTO { int sigqueue(pid_t pid, int signum, \
void *value); }
-457 AUE_NULL UNIMPL kmq_open
-458 AUE_NULL UNIMPL kmq_setattr
-459 AUE_NULL UNIMPL kmq_timedreceive
-460 AUE_NULL UNIMPL kmq_timedsend
-461 AUE_NULL UNIMPL kmq_notify
-462 AUE_NULL UNIMPL kmq_unlink
+457 AUE_NULL NOSTD { int freebsd32_kmq_open( \
+ const char *path, int flags, mode_t mode, \
+ const struct mq_attr32 *attr); }
+458 AUE_NULL NOSTD { int freebsd32_kmq_setattr(int mqd, \
+ const struct mq_attr32 *attr, \
+ struct mq_attr32 *oattr); }
+459 AUE_NULL NOSTD { int freebsd32_kmq_timedreceive(int mqd, \
+ char *msg_ptr, size_t msg_len, \
+ unsigned *msg_prio, \
+ const struct timespec32 *abs_timeout); }
+460 AUE_NULL NOSTD { int freebsd32_kmq_timedsend(int mqd, \
+ const char *msg_ptr, size_t msg_len,\
+ unsigned msg_prio, \
+ const struct timespec32 *abs_timeout);}
+461 AUE_NULL NOPROTO|NOSTD { int kmq_notify(int mqd, \
+ const struct sigevent *sigev); }
+462 AUE_NULL NOPROTO|NOSTD { int kmq_unlink(const char *path); }
463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, void **args); }
464 AUE_NULL NOPROTO { int thr_set_name(long id, const char *name); }
465 AUE_NULL NOSTD { int freebsd32_aio_fsync(int op, \
@@ -820,42 +834,74 @@
474 AUE_NULL NOPROTO { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
struct sockaddr * from, __socklen_t *fromlenaddr, \
struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+#ifdef PAD64_REQUIRED
475 AUE_PREAD STD { ssize_t freebsd32_pread(int fd, \
void *buf,size_t nbyte, \
- u_int32_t offsetlo, u_int32_t offsethi); }
+ int pad, \
+ u_int32_t offset1, u_int32_t offset2); }
476 AUE_PWRITE STD { ssize_t freebsd32_pwrite(int fd, \
const void *buf, size_t nbyte, \
- u_int32_t offsetlo, u_int32_t offsethi); }
+ int pad, \
+ u_int32_t offset1, u_int32_t offset2); }
477 AUE_MMAP STD { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
- u_int32_t poslo, u_int32_t poshi); }
+ int pad, \
+ u_int32_t pos1, u_int32_t pos2); }
478 AUE_LSEEK STD { off_t freebsd32_lseek(int fd, \
- u_int32_t offsetlo, u_int32_t offsethi, \
+ int pad, \
+ u_int32_t offset1, u_int32_t offset2, \
int whence); }
479 AUE_TRUNCATE STD { int freebsd32_truncate(char *path, \
- u_int32_t lengthlo, u_int32_t lengthhi); }
+ int pad, \
+ u_int32_t length1, u_int32_t length2); }
480 AUE_FTRUNCATE STD { int freebsd32_ftruncate(int fd, \
- u_int32_t lengthlo, u_int32_t lengthhi); }
+ int pad, \
+ u_int32_t length1, u_int32_t length2); }
+#else
+475 AUE_PREAD STD { ssize_t freebsd32_pread(int fd, \
+ void *buf,size_t nbyte, \
+ u_int32_t offset1, u_int32_t offset2); }
+476 AUE_PWRITE STD { ssize_t freebsd32_pwrite(int fd, \
+ const void *buf, size_t nbyte, \
+ u_int32_t offset1, u_int32_t offset2); }
+477 AUE_MMAP STD { caddr_t freebsd32_mmap(caddr_t addr, \
+ size_t len, int prot, int flags, int fd, \
+ u_int32_t pos1, u_int32_t pos2); }
+478 AUE_LSEEK STD { off_t freebsd32_lseek(int fd, \
+ u_int32_t offset1, u_int32_t offset2, \
+ int whence); }
+479 AUE_TRUNCATE STD { int freebsd32_truncate(char *path, \
+ u_int32_t length1, u_int32_t length2); }
+480 AUE_FTRUNCATE STD { int freebsd32_ftruncate(int fd, \
+ u_int32_t length1, u_int32_t length2); }
+#endif
481 AUE_KILL NOPROTO { int thr_kill2(pid_t pid, long id, int sig); }
482 AUE_SHMOPEN NOPROTO { int shm_open(const char *path, int flags, \
mode_t mode); }
483 AUE_SHMUNLINK NOPROTO { int shm_unlink(const char *path); }
484 AUE_NULL NOPROTO { int cpuset(cpusetid_t *setid); }
+#ifdef PAD64_REQUIRED
+485 AUE_NULL STD { int freebsd32_cpuset_setid(cpuwhich_t which, \
+ int pad, \
+ u_int32_t id1, u_int32_t id2, \
+ cpusetid_t setid); }
+#else
485 AUE_NULL STD { int freebsd32_cpuset_setid(cpuwhich_t which, \
- uint32_t idlo, uint32_t idhi, \
+ u_int32_t id1, u_int32_t id2, \
cpusetid_t setid); }
+#endif
486 AUE_NULL STD { int freebsd32_cpuset_getid(cpulevel_t level, \
cpuwhich_t which, \
- uint32_t idlo, uint32_t idhi, \
+ u_int32_t id1, u_int32_t id2, \
cpusetid_t *setid); }
487 AUE_NULL STD { int freebsd32_cpuset_getaffinity( \
cpulevel_t level, cpuwhich_t which, \
- uint32_t idlo, uint32_t idhi, \
+ u_int32_t id1, u_int32_t id2, \
size_t cpusetsize, \
cpuset_t *mask); }
488 AUE_NULL STD { int freebsd32_cpuset_setaffinity( \
cpulevel_t level, cpuwhich_t which, \
- uint32_t idlo, uint32_t idhi, \
+ u_int32_t id1, u_int32_t id2, \
size_t cpusetsize, \
const cpuset_t *mask); }
489 AUE_FACCESSAT NOPROTO { int faccessat(int fd, char *path, int mode, \
@@ -897,11 +943,11 @@
unsigned int iovcnt, int flags); }
508 AUE_NULL NOPROTO { int jail_remove(int jid); }
509 AUE_CLOSEFROM NOPROTO { int closefrom(int lowfd); }
-510 AUE_SEMCTL STD { int freebsd32_semctl(int semid, int semnum, \
+510 AUE_SEMCTL NOSTD { int freebsd32_semctl(int semid, int semnum, \
int cmd, union semun32 *arg); }
-511 AUE_MSGCTL STD { int freebsd32_msgctl(int msqid, int cmd, \
+511 AUE_MSGCTL NOSTD { int freebsd32_msgctl(int msqid, int cmd, \
struct msqid_ds32 *buf); }
-512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
+512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds32 *buf); }
513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); }
514 AUE_CAP_NEW UNIMPL cap_new
diff --git a/sys/compat/ia32/ia32_reg.h b/sys/compat/ia32/ia32_reg.h
index 5a9cdf2..b930197 100644
--- a/sys/compat/ia32/ia32_reg.h
+++ b/sys/compat/ia32/ia32_reg.h
@@ -105,29 +105,6 @@ struct save87 {
u_char sv_pad[64]; /* padding; used by emulators */
};
-
-/*
- * Alternative layouts for <sys/procfs.h>
- * Used in core dumps, the reason for this file existing.
- */
-struct prstatus32 {
- int pr_version;
- u_int pr_statussz;
- u_int pr_gregsetsz;
- u_int pr_fpregsetsz;
- int pr_osreldate;
- int pr_cursig;
- pid_t pr_pid;
- struct reg32 pr_reg;
-};
-
-struct prpsinfo32 {
- int pr_version;
- u_int pr_psinfosz;
- char pr_fname[PRFNAMESZ+1];
- char pr_psargs[PRARGSZ+1];
-};
-
/*
* Wrappers and converters.
*/
diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h
index 6ebb0de..717ae74 100644
--- a/sys/compat/ia32/ia32_signal.h
+++ b/sys/compat/ia32/ia32_signal.h
@@ -180,10 +180,11 @@ struct ia32_sigframe3 {
#endif
struct ksiginfo;
+struct image_params;
extern char ia32_sigcode[];
extern char freebsd4_ia32_sigcode[];
extern int sz_ia32_sigcode;
extern int sz_freebsd4_ia32_sigcode;
extern void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *);
-extern void ia32_setregs(struct thread *td, u_long entry, u_long stack,
- u_long ps_strings);
+extern void ia32_setregs(struct thread *td, struct image_params *imgp,
+ u_long stack);
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index cb8d33d..79448a5 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -93,7 +93,6 @@ CTASSERT(sizeof(struct ia32_ucontext4) == 324);
CTASSERT(sizeof(struct ia32_sigframe4) == 408);
#endif
-static register_t *ia32_copyout_strings(struct image_params *imgp);
static void ia32_fixlimit(struct rlimit *rl, int which);
SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode");
@@ -132,7 +131,7 @@ struct sysentvec ia32_freebsd_sysvec = {
.sv_usrstack = FREEBSD32_USRSTACK,
.sv_psstrings = FREEBSD32_PS_STRINGS,
.sv_stackprot = VM_PROT_ALL,
- .sv_copyout_strings = ia32_copyout_strings,
+ .sv_copyout_strings = freebsd32_copyout_strings,
.sv_setregs = ia32_setregs,
.sv_fixlimit = ia32_fixlimit,
.sv_maxssiz = &ia32_maxssiz,
@@ -194,127 +193,6 @@ elf32_dump_thread(struct thread *td __unused, void *dst __unused,
{
}
-
-/* XXX may be freebsd32 MI */
-static register_t *
-ia32_copyout_strings(struct image_params *imgp)
-{
- int argc, envc;
- u_int32_t *vectp;
- char *stringp, *destp;
- u_int32_t *stack_base;
- struct freebsd32_ps_strings *arginfo;
- size_t execpath_len;
- int szsigcode;
-
- /*
- * Calculate string base and vector table pointers.
- * Also deal with signal trampoline code for this exec type.
- */
- if (imgp->execpath != NULL && imgp->auxargs != NULL)
- execpath_len = strlen(imgp->execpath) + 1;
- else
- execpath_len = 0;
- arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
- szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
- destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
- roundup(execpath_len, sizeof(char *)) -
- roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
-
- /*
- * install sigcode
- */
- if (szsigcode)
- copyout(imgp->proc->p_sysent->sv_sigcode,
- ((caddr_t)arginfo - szsigcode), szsigcode);
-
- /*
- * Copy the image path for the rtld.
- */
- if (execpath_len != 0) {
- imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len;
- copyout(imgp->execpath, (void *)imgp->execpathp,
- execpath_len);
- }
-
- /*
- * If we have a valid auxargs ptr, prepare some room
- * on the stack.
- */
- if (imgp->auxargs) {
- /*
- * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
- * lower compatibility.
- */
- imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
- : (AT_COUNT * 2);
- /*
- * The '+ 2' is for the null pointers at the end of each of
- * the arg and env vector sets,and imgp->auxarg_size is room
- * for argument of Runtime loader.
- */
- vectp = (u_int32_t *) (destp - (imgp->args->argc +
- imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
- sizeof(u_int32_t));
- } else
- /*
- * The '+ 2' is for the null pointers at the end of each of
- * the arg and env vector sets
- */
- vectp = (u_int32_t *)
- (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
-
- /*
- * vectp also becomes our initial stack base
- */
- stack_base = vectp;
-
- stringp = imgp->args->begin_argv;
- argc = imgp->args->argc;
- envc = imgp->args->envc;
- /*
- * Copy out strings - arguments and environment.
- */
- copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
-
- /*
- * Fill in "ps_strings" struct for ps, w, etc.
- */
- suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
- suword32(&arginfo->ps_nargvstr, argc);
-
- /*
- * Fill in argument portion of vector table.
- */
- for (; argc > 0; --argc) {
- suword32(vectp++, (u_int32_t)(intptr_t)destp);
- while (*stringp++ != 0)
- destp++;
- destp++;
- }
-
- /* a null vector table pointer separates the argp's from the envp's */
- suword32(vectp++, 0);
-
- suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
- suword32(&arginfo->ps_nenvstr, envc);
-
- /*
- * Fill in environment portion of vector table.
- */
- for (; envc > 0; --envc) {
- suword32(vectp++, (u_int32_t)(intptr_t)destp);
- while (*stringp++ != 0)
- destp++;
- destp++;
- }
-
- /* end of vector table is a null pointer */
- suword32(vectp, 0);
-
- return ((register_t *)stack_base);
-}
-
static void
ia32_fixlimit(struct rlimit *rl, int which)
{
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 541db2f..58d897e 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -110,12 +110,14 @@ __FBSDID("$FreeBSD$");
/*
* Various conversion macros
*/
-#define T2J(x) (((x) * 100UL) / (stathz ? stathz : hz)) /* ticks to jiffies */
+#define T2J(x) ((long)(((x) * 100ULL) / (stathz ? stathz : hz))) /* ticks to jiffies */
+#define T2CS(x) ((unsigned long)(((x) * 100ULL) / (stathz ? stathz : hz))) /* ticks to centiseconds */
#define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */
#define B2K(x) ((x) >> 10) /* bytes to kbytes */
#define B2P(x) ((x) >> PAGE_SHIFT) /* bytes to pages */
#define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */
#define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */
+#define TV2J(x) ((x)->tv_sec * 100UL + (x)->tv_usec / 10000)
/**
* @brief Mapping of ki_stat in struct kinfo_proc to the linux state
@@ -272,7 +274,7 @@ linprocfs_docpuinfo(PFS_FILL_ARGS)
"cpu family\t: %d\n"
"model\t\t: %d\n"
"model name\t: %s\n"
- "stepping\t: %d\n",
+ "stepping\t: %d\n\n",
i, cpu_vendor, class, cpu, model, cpu_id & 0xf);
/* XXX per-cpu vendor / class / model / id? */
}
@@ -505,9 +507,10 @@ linprocfs_douptime(PFS_FILL_ARGS)
getmicrouptime(&tv);
read_cpu_time(cp_time);
- sbuf_printf(sb, "%lld.%02ld %ld.%02ld\n",
+ sbuf_printf(sb, "%lld.%02ld %ld.%02lu\n",
(long long)tv.tv_sec, tv.tv_usec / 10000,
- T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100);
+ T2S(cp_time[CP_IDLE] / mp_ncpus),
+ T2CS(cp_time[CP_IDLE] / mp_ncpus) % 100);
return (0);
}
@@ -613,9 +616,17 @@ linprocfs_doprocstat(PFS_FILL_ARGS)
struct kinfo_proc kp;
char state;
static int ratelimit = 0;
+ vm_offset_t startcode, startdata;
PROC_LOCK(p);
fill_kinfo_proc(p, &kp);
+ if (p->p_vmspace) {
+ startcode = (vm_offset_t)p->p_vmspace->vm_taddr;
+ startdata = (vm_offset_t)p->p_vmspace->vm_daddr;
+ } else {
+ startcode = 0;
+ startdata = 0;
+ };
sbuf_printf(sb, "%d", p->p_pid);
#define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg)
PS_ADD("comm", "(%s)", p->p_comm);
@@ -634,30 +645,27 @@ linprocfs_doprocstat(PFS_FILL_ARGS)
PS_ADD("pgrp", "%d", p->p_pgid);
PS_ADD("session", "%d", p->p_session->s_sid);
PROC_UNLOCK(p);
- PS_ADD("tty", "%d", 0); /* XXX */
+ PS_ADD("tty", "%d", kp.ki_tdev);
PS_ADD("tpgid", "%d", kp.ki_tpgid);
PS_ADD("flags", "%u", 0); /* XXX */
PS_ADD("minflt", "%lu", kp.ki_rusage.ru_minflt);
PS_ADD("cminflt", "%lu", kp.ki_rusage_ch.ru_minflt);
PS_ADD("majflt", "%lu", kp.ki_rusage.ru_majflt);
PS_ADD("cmajflt", "%lu", kp.ki_rusage_ch.ru_majflt);
- PS_ADD("utime", "%ld", T2J(tvtohz(&kp.ki_rusage.ru_utime)));
- PS_ADD("stime", "%ld", T2J(tvtohz(&kp.ki_rusage.ru_stime)));
- PS_ADD("cutime", "%ld", T2J(tvtohz(&kp.ki_rusage_ch.ru_utime)));
- PS_ADD("cstime", "%ld", T2J(tvtohz(&kp.ki_rusage_ch.ru_stime)));
+ PS_ADD("utime", "%ld", TV2J(&kp.ki_rusage.ru_utime));
+ PS_ADD("stime", "%ld", TV2J(&kp.ki_rusage.ru_stime));
+ PS_ADD("cutime", "%ld", TV2J(&kp.ki_rusage_ch.ru_utime));
+ PS_ADD("cstime", "%ld", TV2J(&kp.ki_rusage_ch.ru_stime));
PS_ADD("priority", "%d", kp.ki_pri.pri_user);
PS_ADD("nice", "%d", kp.ki_nice); /* 19 (nicest) to -19 */
PS_ADD("0", "%d", 0); /* removed field */
PS_ADD("itrealvalue", "%d", 0); /* XXX */
- /* XXX: starttime is not right, it is the _same_ for _every_ process.
- It should be the number of jiffies between system boot and process
- start. */
- PS_ADD("starttime", "%lu", T2J(tvtohz(&kp.ki_start)));
+ PS_ADD("starttime", "%lu", TV2J(&kp.ki_start) - TV2J(&boottime));
PS_ADD("vsize", "%ju", P2K((uintmax_t)kp.ki_size));
PS_ADD("rss", "%ju", (uintmax_t)kp.ki_rssize);
PS_ADD("rlim", "%lu", kp.ki_rusage.ru_maxrss);
- PS_ADD("startcode", "%u", (unsigned)0);
- PS_ADD("endcode", "%u", 0); /* XXX */
+ PS_ADD("startcode", "%ju", (uintmax_t)startcode);
+ PS_ADD("endcode", "%ju", (uintmax_t)startdata);
PS_ADD("startstack", "%u", 0); /* XXX */
PS_ADD("kstkesp", "%u", 0); /* XXX */
PS_ADD("kstkeip", "%u", 0); /* XXX */
@@ -800,7 +808,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
*/
sbuf_printf(sb, "VmSize:\t%8ju kB\n", B2K((uintmax_t)kp.ki_size));
sbuf_printf(sb, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */
- sbuf_printf(sb, "VmRss:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize));
+ sbuf_printf(sb, "VmRSS:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize));
sbuf_printf(sb, "VmData:\t%8ju kB\n", P2K((uintmax_t)kp.ki_dsize));
sbuf_printf(sb, "VmStk:\t%8ju kB\n", P2K((uintmax_t)kp.ki_ssize));
sbuf_printf(sb, "VmExe:\t%8ju kB\n", P2K((uintmax_t)kp.ki_tsize));
@@ -1227,6 +1235,24 @@ linprocfs_docmdline(PFS_FILL_ARGS)
return (0);
}
+/*
+ * Filler function for proc/filesystems
+ */
+static int
+linprocfs_dofilesystems(PFS_FILL_ARGS)
+{
+ struct vfsconf *vfsp;
+
+ mtx_lock(&Giant);
+ TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) {
+ if (vfsp->vfc_flags & VFCF_SYNTHETIC)
+ sbuf_printf(sb, "nodev");
+ sbuf_printf(sb, "\t%s\n", vfsp->vfc_name);
+ }
+ mtx_unlock(&Giant);
+ return(0);
+}
+
#if 0
/*
* Filler function for proc/modules
@@ -1245,6 +1271,20 @@ linprocfs_domodules(PFS_FILL_ARGS)
#endif
/*
+ * Filler function for proc/pid/fd
+ */
+static int
+linprocfs_dofdescfs(PFS_FILL_ARGS)
+{
+
+ if (p == curproc)
+ sbuf_printf(sb, "/dev/fd");
+ else
+ sbuf_printf(sb, "unknown");
+ return (0);
+}
+
+/*
* Constructor
*/
static int
@@ -1262,6 +1302,8 @@ linprocfs_init(PFS_INIT_ARGS)
NULL, NULL, NULL, PFS_RD);
pfs_create_file(root, "devices", &linprocfs_dodevices,
NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(root, "filesystems", &linprocfs_dofilesystems,
+ NULL, NULL, NULL, PFS_RD);
pfs_create_file(root, "loadavg", &linprocfs_doloadavg,
NULL, NULL, NULL, PFS_RD);
pfs_create_file(root, "meminfo", &linprocfs_domeminfo,
@@ -1312,6 +1354,8 @@ linprocfs_init(PFS_INIT_ARGS)
NULL, NULL, NULL, PFS_RD);
pfs_create_file(dir, "status", &linprocfs_doprocstatus,
NULL, NULL, NULL, PFS_RD);
+ pfs_create_link(dir, "fd", &linprocfs_dofdescfs,
+ NULL, NULL, NULL, 0);
/* /proc/scsi/... */
dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0);
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 4e33eaa..9ff1cf0 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -128,6 +128,8 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod
bsd_flags |= O_DIRECT;
if (l_flags & LINUX_O_NOFOLLOW)
bsd_flags |= O_NOFOLLOW;
+ if (l_flags & LINUX_O_DIRECTORY)
+ bsd_flags |= O_DIRECTORY;
/* XXX LINUX_O_NOATIME: unable to be easily implemented. */
error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode);
@@ -154,12 +156,6 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod
PROC_UNLOCK(p);
sx_sunlock(&proctree_lock);
}
- if (l_flags & LINUX_O_DIRECTORY) {
- if (fp->f_type != DTYPE_VNODE ||
- fp->f_vnode->v_type != VDIR) {
- error = ENOTDIR;
- }
- }
fdrop(fp, td);
/*
* XXX as above, fdrop()/kern_close() pair is racy.
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index c457d12..6600976 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -2711,7 +2711,7 @@ linux_v4l_clip_copy(void *lvc, struct video_clip **ppvc)
/* XXX: If there can be no concurrency: s/M_NOWAIT/M_WAITOK/ */
if ((*ppvc = malloc(sizeof(**ppvc), M_LINUX, M_NOWAIT)) == NULL)
return (ENOMEM); /* XXX: linux has no ENOMEM here */
- memcpy(&vclip, *ppvc, sizeof(vclip));
+ memcpy(*ppvc, &vclip, sizeof(vclip));
(*ppvc)->next = NULL;
return (0);
}
@@ -2726,6 +2726,8 @@ linux_v4l_cliplist_free(struct video_window *vw)
ppvc_next = &((*ppvc)->next);
free(*ppvc, M_LINUX);
}
+ vw->clips = NULL;
+
return (0);
}
diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c
index 8e8936c..907d201 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -173,9 +173,12 @@ newstat_copyout(struct stat *buf, void *ubuf)
tbuf.st_gid = buf->st_gid;
tbuf.st_rdev = buf->st_rdev;
tbuf.st_size = buf->st_size;
- tbuf.st_atime = buf->st_atime;
- tbuf.st_mtime = buf->st_mtime;
- tbuf.st_ctime = buf->st_ctime;
+ tbuf.st_atim.tv_sec = buf->st_atim.tv_sec;
+ tbuf.st_atim.tv_nsec = buf->st_atim.tv_nsec;
+ tbuf.st_mtim.tv_sec = buf->st_mtim.tv_sec;
+ tbuf.st_mtim.tv_nsec = buf->st_mtim.tv_nsec;
+ tbuf.st_ctim.tv_sec = buf->st_ctim.tv_sec;
+ tbuf.st_ctim.tv_nsec = buf->st_ctim.tv_nsec;
tbuf.st_blksize = buf->st_blksize;
tbuf.st_blocks = buf->st_blocks;
@@ -260,9 +263,12 @@ stat_copyout(struct stat *buf, void *ubuf)
lbuf.st_size = buf->st_size;
else
lbuf.st_size = -2;
- lbuf.st_atime = buf->st_atime;
- lbuf.st_mtime = buf->st_mtime;
- lbuf.st_ctime = buf->st_ctime;
+ lbuf.st_atim.tv_sec = buf->st_atim.tv_sec;
+ lbuf.st_atim.tv_nsec = buf->st_atim.tv_nsec;
+ lbuf.st_mtim.tv_sec = buf->st_mtim.tv_sec;
+ lbuf.st_mtim.tv_nsec = buf->st_mtim.tv_nsec;
+ lbuf.st_ctim.tv_sec = buf->st_ctim.tv_sec;
+ lbuf.st_ctim.tv_nsec = buf->st_ctim.tv_nsec;
lbuf.st_blksize = buf->st_blksize;
lbuf.st_blocks = buf->st_blocks;
lbuf.st_flags = buf->st_flags;
@@ -498,9 +504,12 @@ stat64_copyout(struct stat *buf, void *ubuf)
lbuf.st_gid = buf->st_gid;
lbuf.st_rdev = buf->st_rdev;
lbuf.st_size = buf->st_size;
- lbuf.st_atime = buf->st_atime;
- lbuf.st_mtime = buf->st_mtime;
- lbuf.st_ctime = buf->st_ctime;
+ lbuf.st_atim.tv_sec = buf->st_atim.tv_sec;
+ lbuf.st_atim.tv_nsec = buf->st_atim.tv_nsec;
+ lbuf.st_mtim.tv_sec = buf->st_mtim.tv_sec;
+ lbuf.st_mtim.tv_nsec = buf->st_mtim.tv_nsec;
+ lbuf.st_ctim.tv_sec = buf->st_ctim.tv_sec;
+ lbuf.st_ctim.tv_nsec = buf->st_ctim.tv_nsec;
lbuf.st_blksize = buf->st_blksize;
lbuf.st_blocks = buf->st_blocks;
diff --git a/sys/compat/svr4/svr4_stat.c b/sys/compat/svr4/svr4_stat.c
index cfb8276..cc84396 100644
--- a/sys/compat/svr4/svr4_stat.c
+++ b/sys/compat/svr4/svr4_stat.c
@@ -106,9 +106,9 @@ bsd_to_svr4_stat(st, st4)
st4->st_gid = st->st_gid;
st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
st4->st_size = st->st_size;
- st4->st_atim = st->st_atimespec.tv_sec;
- st4->st_mtim = st->st_mtimespec.tv_sec;
- st4->st_ctim = st->st_ctimespec.tv_sec;
+ st4->st_atim = st->st_atim.tv_sec;
+ st4->st_mtim = st->st_mtim.tv_sec;
+ st4->st_ctim = st->st_ctim.tv_sec;
}
#endif
@@ -127,9 +127,9 @@ bsd_to_svr4_xstat(st, st4)
st4->st_gid = st->st_gid;
st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
st4->st_size = st->st_size;
- st4->st_atim = st->st_atimespec;
- st4->st_mtim = st->st_mtimespec;
- st4->st_ctim = st->st_ctimespec;
+ st4->st_atim = st->st_atim;
+ st4->st_mtim = st->st_mtim;
+ st4->st_ctim = st->st_ctim;
st4->st_blksize = st->st_blksize;
st4->st_blocks = st->st_blocks;
strcpy(st4->st_fstype, "unknown");
@@ -150,9 +150,9 @@ bsd_to_svr4_stat64(st, st4)
st4->st_gid = st->st_gid;
st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
st4->st_size = st->st_size;
- st4->st_atim = st->st_atimespec;
- st4->st_mtim = st->st_mtimespec;
- st4->st_ctim = st->st_ctimespec;
+ st4->st_atim = st->st_atim;
+ st4->st_mtim = st->st_mtim;
+ st4->st_ctim = st->st_ctim;
st4->st_blksize = st->st_blksize;
st4->st_blocks = st->st_blocks;
strcpy(st4->st_fstype, "unknown");
diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c
index 34da07c..d5512fc 100644
--- a/sys/compat/x86bios/x86bios.c
+++ b/sys/compat/x86bios/x86bios.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2009 Alex Keda <admin@lissyara.su>
- * Copyright (c) 2009 Jung-uk Kim <jkim@FreeBSD.org>
+ * Copyright (c) 2009-2010 Jung-uk Kim <jkim@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,9 +60,9 @@ __FBSDID("$FreeBSD$");
#define X86BIOS_IVT_BASE 0x00000000
#define X86BIOS_RAM_BASE 0x00001000
-#define X86BIOS_ROM_BASE 0x000a0000 /* XXX EBDA? */
+#define X86BIOS_ROM_BASE 0x000a0000
-#define X86BIOS_ROM_SIZE (X86BIOS_MEM_SIZE - X86BIOS_ROM_BASE)
+#define X86BIOS_ROM_SIZE (X86BIOS_MEM_SIZE - (uint32_t)x86bios_rom_phys)
#define X86BIOS_PAGES (X86BIOS_MEM_SIZE / X86BIOS_PAGE_SIZE)
@@ -79,8 +79,14 @@ static void *x86bios_seg;
static vm_offset_t *x86bios_map;
+static vm_paddr_t x86bios_rom_phys;
static vm_paddr_t x86bios_seg_phys;
+static int x86bios_fault;
+static uint32_t x86bios_fault_addr;
+static uint16_t x86bios_fault_cs;
+static uint16_t x86bios_fault_ip;
+
SYSCTL_NODE(_debug, OID_AUTO, x86bios, CTLFLAG_RD, NULL, "x86bios debugging");
static int x86bios_trace_call;
TUNABLE_INT("debug.x86bios.call", &x86bios_trace_call);
@@ -91,18 +97,30 @@ TUNABLE_INT("debug.x86bios.int", &x86bios_trace_int);
SYSCTL_INT(_debug_x86bios, OID_AUTO, int, CTLFLAG_RW, &x86bios_trace_int, 0,
"Trace software interrupt handlers");
+static void
+x86bios_set_fault(struct x86emu *emu, uint32_t addr)
+{
+
+ x86bios_fault = 1;
+ x86bios_fault_addr = addr;
+ x86bios_fault_cs = emu->x86.R_CS;
+ x86bios_fault_ip = emu->x86.R_IP;
+ x86emu_halt_sys(emu);
+}
+
static void *
x86bios_get_pages(uint32_t offset, size_t size)
{
- int i;
+ vm_offset_t page;
- if (offset + size > X86BIOS_MEM_SIZE)
+ if (offset + size > X86BIOS_MEM_SIZE + X86BIOS_IVT_SIZE)
return (NULL);
- i = offset / X86BIOS_PAGE_SIZE;
- if (x86bios_map[i] != 0)
- return ((void *)(x86bios_map[i] + offset -
- i * X86BIOS_PAGE_SIZE));
+ if (offset >= X86BIOS_MEM_SIZE)
+ offset -= X86BIOS_MEM_SIZE;
+ page = x86bios_map[offset / X86BIOS_PAGE_SIZE];
+ if (page != 0)
+ return ((void *)(page + offset % X86BIOS_PAGE_SIZE));
return (NULL);
}
@@ -124,7 +142,7 @@ x86bios_emu_rdb(struct x86emu *emu, uint32_t addr)
va = x86bios_get_pages(addr, sizeof(*va));
if (va == NULL)
- x86emu_halt_sys(emu);
+ x86bios_set_fault(emu, addr);
return (*va);
}
@@ -136,8 +154,13 @@ x86bios_emu_rdw(struct x86emu *emu, uint32_t addr)
va = x86bios_get_pages(addr, sizeof(*va));
if (va == NULL)
- x86emu_halt_sys(emu);
+ x86bios_set_fault(emu, addr);
+#ifndef __NO_STRICT_ALIGNMENT
+ if ((addr & 1) != 0)
+ return (le16dec(va));
+ else
+#endif
return (le16toh(*va));
}
@@ -148,8 +171,13 @@ x86bios_emu_rdl(struct x86emu *emu, uint32_t addr)
va = x86bios_get_pages(addr, sizeof(*va));
if (va == NULL)
- x86emu_halt_sys(emu);
+ x86bios_set_fault(emu, addr);
+#ifndef __NO_STRICT_ALIGNMENT
+ if ((addr & 3) != 0)
+ return (le32dec(va));
+ else
+#endif
return (le32toh(*va));
}
@@ -160,7 +188,7 @@ x86bios_emu_wrb(struct x86emu *emu, uint32_t addr, uint8_t val)
va = x86bios_get_pages(addr, sizeof(*va));
if (va == NULL)
- x86emu_halt_sys(emu);
+ x86bios_set_fault(emu, addr);
*va = val;
}
@@ -172,8 +200,13 @@ x86bios_emu_wrw(struct x86emu *emu, uint32_t addr, uint16_t val)
va = x86bios_get_pages(addr, sizeof(*va));
if (va == NULL)
- x86emu_halt_sys(emu);
+ x86bios_set_fault(emu, addr);
+#ifndef __NO_STRICT_ALIGNMENT
+ if ((addr & 1) != 0)
+ le16enc(va, val);
+ else
+#endif
*va = htole16(val);
}
@@ -184,8 +217,13 @@ x86bios_emu_wrl(struct x86emu *emu, uint32_t addr, uint32_t val)
va = x86bios_get_pages(addr, sizeof(*va));
if (va == NULL)
- x86emu_halt_sys(emu);
+ x86bios_set_fault(emu, addr);
+#ifndef __NO_STRICT_ALIGNMENT
+ if ((addr & 3) != 0)
+ le32enc(va, val);
+ else
+#endif
*va = htole32(val);
}
@@ -267,8 +305,8 @@ x86bios_emu_get_intr(struct x86emu *emu, int intno)
sp[2] = htole16(emu->x86.R_FLG);
iv = x86bios_get_intr(intno);
- emu->x86.R_IP = iv & 0x000f;
- emu->x86.R_CS = (iv >> 12) & 0xffff;
+ emu->x86.R_IP = iv & 0xffff;
+ emu->x86.R_CS = (iv >> 16) & 0xffff;
emu->x86.R_FLG &= ~(F_IF | F_TF);
}
@@ -281,7 +319,7 @@ x86bios_alloc(uint32_t *offset, size_t size)
return (NULL);
vaddr = contigmalloc(size, M_DEVBUF, M_NOWAIT, X86BIOS_RAM_BASE,
- X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0);
+ x86bios_rom_phys, X86BIOS_PAGE_SIZE, 0);
if (vaddr != NULL) {
*offset = vtophys(vaddr);
x86bios_set_pages((vm_offset_t)vaddr, *offset, size);
@@ -299,7 +337,7 @@ x86bios_free(void *addr, size_t size)
return;
paddr = vtophys(addr);
- if (paddr < X86BIOS_RAM_BASE || paddr >= X86BIOS_ROM_BASE ||
+ if (paddr < X86BIOS_RAM_BASE || paddr >= x86bios_rom_phys ||
paddr % X86BIOS_PAGE_SIZE != 0)
return;
@@ -313,7 +351,8 @@ x86bios_init_regs(struct x86regs *regs)
{
bzero(regs, sizeof(*regs));
- regs->X86BIOS_R_DS = regs->X86BIOS_R_SS = x86bios_seg_phys >> 4;
+ regs->X86BIOS_R_DS = 0x40;
+ regs->X86BIOS_R_SS = x86bios_seg_phys >> 4;
}
void
@@ -331,15 +370,21 @@ x86bios_call(struct x86regs *regs, uint16_t seg, uint16_t off)
mtx_lock_spin(&x86bios_lock);
memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
+ x86bios_fault = 0;
x86emu_exec_call(&x86bios_emu, seg, off);
memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
mtx_unlock_spin(&x86bios_lock);
- if (x86bios_trace_call)
+ if (x86bios_trace_call) {
printf("Exiting 0x%05x (ax=0x%04x bx=0x%04x "
"cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
(seg << 4) + off, regs->R_AX, regs->R_BX, regs->R_CX,
regs->R_DX, regs->R_ES, regs->R_DI);
+ if (x86bios_fault)
+ printf("Page fault at 0x%05x from 0x%04x:0x%04x.\n",
+ x86bios_fault_addr, x86bios_fault_cs,
+ x86bios_fault_ip);
+ }
}
uint32_t
@@ -370,15 +415,21 @@ x86bios_intr(struct x86regs *regs, int intno)
mtx_lock_spin(&x86bios_lock);
memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
+ x86bios_fault = 0;
x86emu_exec_intr(&x86bios_emu, intno);
memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
mtx_unlock_spin(&x86bios_lock);
- if (x86bios_trace_int)
+ if (x86bios_trace_int) {
printf("Exiting int 0x%x (ax=0x%04x bx=0x%04x "
"cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
intno, regs->R_AX, regs->R_BX, regs->R_CX,
regs->R_DX, regs->R_ES, regs->R_DI);
+ if (x86bios_fault)
+ printf("Page fault at 0x%05x from 0x%04x:0x%04x.\n",
+ x86bios_fault_addr, x86bios_fault_cs,
+ x86bios_fault_ip);
+ }
}
void *
@@ -433,6 +484,12 @@ x86bios_match_device(uint32_t offset, device_t dev)
return (1);
}
+#if defined(__amd64__) || (defined(__i386__) && !defined(PC98))
+#define PROBE_EBDA 1
+#else
+#define PROBE_EBDA 0
+#endif
+
static __inline int
x86bios_map_mem(void)
{
@@ -440,18 +497,63 @@ x86bios_map_mem(void)
x86bios_ivt = pmap_mapbios(X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE);
if (x86bios_ivt == NULL)
return (1);
- x86bios_rom = pmap_mapdev(X86BIOS_ROM_BASE, X86BIOS_ROM_SIZE);
+
+#if PROBE_EBDA
+ /* Probe EBDA via BDA. */
+ x86bios_rom_phys = *(uint16_t *)((vm_offset_t)x86bios_ivt + 0x40e);
+ x86bios_rom_phys = le16toh(x86bios_rom_phys) << 4;
+ if (x86bios_rom_phys != 0 && x86bios_rom_phys < X86BIOS_ROM_BASE &&
+ X86BIOS_ROM_BASE - x86bios_rom_phys <= 128 * 1024)
+ x86bios_rom_phys =
+ rounddown(x86bios_rom_phys, X86BIOS_PAGE_SIZE);
+ else
+#endif
+ x86bios_rom_phys = X86BIOS_ROM_BASE;
+ x86bios_rom = pmap_mapdev(x86bios_rom_phys, X86BIOS_ROM_SIZE);
if (x86bios_rom == NULL) {
pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE);
return (1);
}
+#if PROBE_EBDA
+ /* Change attribute for EBDA. */
+ if (x86bios_rom_phys < X86BIOS_ROM_BASE &&
+ pmap_change_attr((vm_offset_t)x86bios_rom,
+ X86BIOS_ROM_BASE - x86bios_rom_phys, PAT_WRITE_BACK) != 0) {
+ pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE);
+ pmap_unmapdev((vm_offset_t)x86bios_rom, X86BIOS_ROM_SIZE);
+ return (1);
+ }
+#endif
+
x86bios_seg = contigmalloc(X86BIOS_SEG_SIZE, M_DEVBUF, M_WAITOK,
- X86BIOS_RAM_BASE, X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0);
+ X86BIOS_RAM_BASE, x86bios_rom_phys, X86BIOS_PAGE_SIZE, 0);
x86bios_seg_phys = vtophys(x86bios_seg);
+ if (bootverbose) {
+ printf("x86bios: IVT 0x%06x-0x%06x at %p\n",
+ X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE + X86BIOS_IVT_BASE - 1,
+ x86bios_ivt);
+ printf("x86bios: SSEG 0x%06x-0x%06x at %p\n",
+ (uint32_t)x86bios_seg_phys,
+ X86BIOS_SEG_SIZE + (uint32_t)x86bios_seg_phys - 1,
+ x86bios_seg);
+#if PROBE_EBDA
+ if (x86bios_rom_phys < X86BIOS_ROM_BASE)
+ printf("x86bios: EBDA 0x%06x-0x%06x at %p\n",
+ (uint32_t)x86bios_rom_phys, X86BIOS_ROM_BASE - 1,
+ x86bios_rom);
+#endif
+ printf("x86bios: ROM 0x%06x-0x%06x at %p\n",
+ X86BIOS_ROM_BASE, X86BIOS_MEM_SIZE - X86BIOS_SEG_SIZE - 1,
+ (void *)((vm_offset_t)x86bios_rom + X86BIOS_ROM_BASE -
+ (vm_offset_t)x86bios_rom_phys));
+ }
+
return (0);
}
+#undef PROBE_EBDA
+
static __inline void
x86bios_unmap_mem(void)
{
@@ -475,7 +577,7 @@ x86bios_init(void *arg __unused)
M_WAITOK | M_ZERO);
x86bios_set_pages((vm_offset_t)x86bios_ivt, X86BIOS_IVT_BASE,
X86BIOS_IVT_SIZE);
- x86bios_set_pages((vm_offset_t)x86bios_rom, X86BIOS_ROM_BASE,
+ x86bios_set_pages((vm_offset_t)x86bios_rom, x86bios_rom_phys,
X86BIOS_ROM_SIZE);
x86bios_set_pages((vm_offset_t)x86bios_seg, x86bios_seg_phys,
X86BIOS_SEG_SIZE);
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index f7ab101..f0cc9a0 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -122,10 +122,10 @@ options BLKDEV_IOSIZE=8192
#
# MAXPHYS and DFLTPHYS
#
-# These are the max and default 'raw' I/O block device access sizes.
-# Reads and writes will be split into DFLTPHYS chunks. Some applications
-# have better performance with larger raw I/O access sizes. Typically
-# MAXPHYS should be twice the size of DFLTPHYS. Note that certain VM
+# These are the maximal and safe 'raw' I/O block device access sizes.
+# Reads and writes will be split into MAXPHYS chunks for known good
+# devices and DFLTPHYS for the rest. Some applications have better
+# performance with larger raw I/O access sizes. Note that certain VM
# parameters are derived from these values and making them too large
# can make an an unbootable kernel.
#
@@ -1886,6 +1886,7 @@ device xmphy # XaQti XMAC II
# the Netgear GA302T, the SysKonnect SK-9D21 and SK-9D41, and
# the embedded gigE NICs on Dell PowerEdge 2550 servers.
# bwi: Broadcom BCM430* and BCM431* family of wireless adapters.
+# bwn: Broadcom BCM43xx family of wireless adapters.
# cas: Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn
# cm: Arcnet SMC COM90c26 / SMC COM90c56
# (and SMC COM90c66 in '56 compatibility mode) adapters.
@@ -1951,6 +1952,7 @@ device xmphy # XaQti XMAC II
# This includes dual and quad port cards, as well as one 100baseFX card.
# Most of these are 64-bit PCI devices, except for one single port
# card which is 32-bit.
+# sge: Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet adapter
# sis: Support for NICs based on the Silicon Integrated Systems SiS 900,
# SiS 7016 and NS DP83815 PCI fast ethernet controller chips.
# sk: Support for the SysKonnect SK-984x series PCI gigabit ethernet NICs.
@@ -2045,6 +2047,7 @@ device re # RealTek 8139C+/8169/8169S/8110S
device rl # RealTek 8129/8139
device pcn # AMD Am79C97x PCI 10/100 NICs
device sf # Adaptec AIC-6915 (``Starfire'')
+device sge # Silicon Integrated Systems SiS190/191
device sis # Silicon Integrated Systems SiS 900/SiS 7016
device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet
device ste # Sundance ST201 (D-Link DFE-550TX)
@@ -2090,8 +2093,10 @@ device ath_hal # pci/cardbus chip support
options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors
#device ath_ar9160 # AR9160 chips
#device ath_ar9280 # AR9280 chips
+#device ath_ar9285 # AR9285 chips
device ath_rate_sample # SampleRate tx rate control for ath
device bwi # Broadcom BCM430* BCM431*
+device bwn # Broadcom BCM43xx
device ral # Ralink Technology RT2500 wireless NICs.
# Use "private" jumbo buffers allocated exclusively for the ti(4) driver.
@@ -2816,6 +2821,11 @@ options SHMMNI=33
# a single process at one time.
options SHMSEG=9
+# Compress user core dumps.
+options COMPRESS_USER_CORES
+# required to compress file output from kernel for COMPRESS_USER_CORES.
+device gzio
+
# Set the amount of time (in seconds) the system will wait before
# rebooting automatically when a kernel panic occurs. If set to (-1),
# the system will wait indefinitely until a key is pressed on the
diff --git a/sys/conf/files b/sys/conf/files
index e723775..6bb1355 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -184,6 +184,7 @@ contrib/dev/acpica/events/evxfregn.c optional acpi
contrib/dev/acpica/executer/exconfig.c optional acpi
contrib/dev/acpica/executer/exconvrt.c optional acpi
contrib/dev/acpica/executer/excreate.c optional acpi
+contrib/dev/acpica/executer/exdebug.c optional acpi
contrib/dev/acpica/executer/exdump.c optional acpi
contrib/dev/acpica/executer/exfield.c optional acpi
contrib/dev/acpica/executer/exfldio.c optional acpi
@@ -771,6 +772,7 @@ dev/bwi/bwiphy.c optional bwi
dev/bwi/bwirf.c optional bwi
dev/bwi/if_bwi.c optional bwi
dev/bwi/if_bwi_pci.c optional bwi pci
+dev/bwn/if_bwn.c optional bwn siba_bwn
dev/cardbus/cardbus.c optional cardbus
dev/cardbus/cardbus_cis.c optional cardbus
dev/cardbus/cardbus_device.c optional cardbus
@@ -910,6 +912,8 @@ dev/eisa/eisa_if.m standard
dev/eisa/eisaconf.c optional eisa
dev/e1000/if_em.c optional em inet \
compile-with "${NORMAL_C} -I$S/dev/e1000"
+dev/e1000/if_lem.c optional em inet \
+ compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/if_igb.c optional igb inet \
compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/e1000_80003es2lan.c optional em | igb \
@@ -1186,7 +1190,7 @@ iwn6000fw.fwo optional iwn6000fw | iwnfw \
clean "iwn6000fw.fwo"
iwn6000.fw optional iwn6000fw | iwnfw \
dependency ".PHONY" \
- compile-with "uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu" \
+ compile-with "uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu" \
no-obj no-implicit-rule \
clean "iwn6000.fw"
dev/ixgb/if_ixgb.c optional ixgb
@@ -1486,12 +1490,15 @@ dev/scd/scd.c optional scd isa
dev/scd/scd_isa.c optional scd isa
dev/sdhci/sdhci.c optional sdhci pci
dev/sf/if_sf.c optional sf pci
+dev/sge/if_sge.c optional sge pci
dev/si/si.c optional si
dev/si/si2_z280.c optional si
dev/si/si3_t225.c optional si
dev/si/si_eisa.c optional si eisa
dev/si/si_isa.c optional si isa
dev/si/si_pci.c optional si pci
+dev/siba/siba_bwn.c optional siba_bwn pci
+dev/siba/siba_core.c optional siba_bwn pci
dev/siis/siis.c optional siis pci
dev/sis/if_sis.c optional sis pci
dev/sk/if_sk.c optional sk pci inet
@@ -2316,7 +2323,7 @@ net/if_ethersubr.c optional ether \
net/if_faith.c optional faith
net/if_fddisubr.c optional fddi
net/if_fwsubr.c optional fwip
-net/if_gif.c optional gif
+net/if_gif.c optional gif | netgraph_gif
net/if_gre.c optional gre inet
net/if_iso88025subr.c optional token
net/if_lagg.c optional lagg
@@ -2345,14 +2352,14 @@ net/slcompress.c optional netgraph_vjc | sppp | \
net/vnet.c optional vimage
net/zlib.c optional crypto | geom_uzip | ipsec | \
mxge | netgraph_deflate | \
- ddb_ctf | zlib
+ ddb_ctf | gzio
net80211/ieee80211.c optional wlan
net80211/ieee80211_acl.c optional wlan wlan_acl
net80211/ieee80211_action.c optional wlan
net80211/ieee80211_ageq.c optional wlan
net80211/ieee80211_adhoc.c optional wlan
net80211/ieee80211_ageq.c optional wlan
-net80211/ieee80211_amrr.c optional wlan wlan_amrr
+net80211/ieee80211_amrr.c optional wlan | wlan_amrr
net80211/ieee80211_crypto.c optional wlan
net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp
net80211/ieee80211_crypto_none.c optional wlan
@@ -2374,6 +2381,7 @@ net80211/ieee80211_phy.c optional wlan
net80211/ieee80211_power.c optional wlan
net80211/ieee80211_proto.c optional wlan
net80211/ieee80211_radiotap.c optional wlan
+net80211/ieee80211_ratectl.c optional wlan
net80211/ieee80211_regdomain.c optional wlan
net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt
net80211/ieee80211_scan.c optional wlan
@@ -2479,7 +2487,7 @@ netinet/if_ether.c optional inet ether
netinet/igmp.c optional inet
netinet/in.c optional inet
netinet/ip_carp.c optional inet carp | inet6 carp
-netinet/in_gif.c optional gif inet
+netinet/in_gif.c optional gif inet | netgraph_gif inet
netinet/ip_gre.c optional gre inet
netinet/ip_id.c optional inet
netinet/in_mcast.c optional inet
@@ -2488,7 +2496,15 @@ netinet/in_proto.c optional inet \
compile-with "${NORMAL_C} -I$S/contrib/pf"
netinet/in_rmx.c optional inet
netinet/ip_divert.c optional inet ipdivert ipfirewall
+netinet/ipfw/dn_heap.c optional inet dummynet
+netinet/ipfw/dn_sched_fifo.c optional inet dummynet
+netinet/ipfw/dn_sched_prio.c optional inet dummynet
+netinet/ipfw/dn_sched_qfq.c optional inet dummynet
+netinet/ipfw/dn_sched_rr.c optional inet dummynet
+netinet/ipfw/dn_sched_wf2q.c optional inet dummynet
netinet/ipfw/ip_dummynet.c optional inet dummynet
+netinet/ipfw/ip_dn_io.c optional inet dummynet
+netinet/ipfw/ip_dn_glue.c optional inet dummynet
netinet/ip_ecn.c optional inet | inet6
netinet/ip_encap.c optional inet | inet6
netinet/ip_fastfwd.c optional inet
@@ -2546,7 +2562,7 @@ netinet6/frag6.c optional inet6
netinet6/icmp6.c optional inet6
netinet6/in6.c optional inet6
netinet6/in6_cksum.c optional inet6
-netinet6/in6_gif.c optional gif inet6
+netinet6/in6_gif.c optional gif inet6 | netgraph_gif inet6
netinet6/in6_ifattach.c optional inet6
netinet6/in6_mcast.c optional inet6
netinet6/in6_pcb.c optional inet6
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 9300f89..ae5170a 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -198,6 +198,7 @@ dev/hptrr/hptrr_config.c optional hptrr
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_intel.c optional hwpmc
dev/hwpmc/hwpmc_core.c optional hwpmc
+dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_tsc.c optional hwpmc
dev/hwpmc/hwpmc_x86.c optional hwpmc
@@ -227,20 +228,20 @@ kern/link_elf_obj.c standard
#
# IA32 binary support
#
-#amd64/ia32/ia32_exception.S optional compat_ia32
-amd64/ia32/ia32_reg.c optional compat_ia32
-amd64/ia32/ia32_signal.c optional compat_ia32
-amd64/ia32/ia32_sigtramp.S optional compat_ia32
-amd64/ia32/ia32_syscall.c optional compat_ia32
-amd64/ia32/ia32_misc.c optional compat_ia32
-compat/freebsd32/freebsd32_ioctl.c optional compat_ia32
-compat/freebsd32/freebsd32_misc.c optional compat_ia32
-compat/freebsd32/freebsd32_syscalls.c optional compat_ia32
-compat/freebsd32/freebsd32_sysent.c optional compat_ia32
-compat/ia32/ia32_sysvec.c optional compat_ia32
+#amd64/ia32/ia32_exception.S optional compat_freebsd32
+amd64/ia32/ia32_reg.c optional compat_freebsd32
+amd64/ia32/ia32_signal.c optional compat_freebsd32
+amd64/ia32/ia32_sigtramp.S optional compat_freebsd32
+amd64/ia32/ia32_syscall.c optional compat_freebsd32
+amd64/ia32/ia32_misc.c optional compat_freebsd32
+compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32
+compat/freebsd32/freebsd32_misc.c optional compat_freebsd32
+compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32
+compat/freebsd32/freebsd32_sysent.c optional compat_freebsd32
+compat/ia32/ia32_sysvec.c optional compat_freebsd32
compat/linprocfs/linprocfs.c optional linprocfs
compat/linsysfs/linsysfs.c optional linsysfs
-kern/imgact_elf32.c optional compat_ia32
+kern/imgact_elf32.c optional compat_freebsd32
#
# Linux/i386 binary support
#
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index a61dca2..b0c68b5 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -179,6 +179,7 @@ dev/hptrr/hptrr_config.c optional hptrr
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_intel.c optional hwpmc
dev/hwpmc/hwpmc_core.c optional hwpmc
+dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_pentium.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_ppro.c optional hwpmc
diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64
index 86ca963..33d93ac 100644
--- a/sys/conf/files.ia64
+++ b/sys/conf/files.ia64
@@ -28,11 +28,11 @@ ukbdmap.h optional ukbd_dflt_keymap \
no-obj no-implicit-rule before-depend \
clean "ukbdmap.h"
#
-compat/freebsd32/freebsd32_ioctl.c optional compat_ia32
-compat/freebsd32/freebsd32_misc.c optional compat_ia32
-compat/freebsd32/freebsd32_syscalls.c optional compat_ia32
-compat/freebsd32/freebsd32_sysent.c optional compat_ia32
-compat/ia32/ia32_sysvec.c optional compat_ia32
+compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32
+compat/freebsd32/freebsd32_misc.c optional compat_freebsd32
+compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32
+compat/freebsd32/freebsd32_sysent.c optional compat_freebsd32
+compat/ia32/ia32_sysvec.c optional compat_freebsd32
contrib/ia64/libuwx/src/uwx_bstream.c standard
contrib/ia64/libuwx/src/uwx_context.c standard
contrib/ia64/libuwx/src/uwx_env.c standard
@@ -68,10 +68,10 @@ ia64/acpica/madt.c optional acpi
ia64/disasm/disasm_decode.c standard
ia64/disasm/disasm_extract.c standard
ia64/disasm/disasm_format.c standard
-ia64/ia32/ia32_misc.c optional compat_ia32
-ia64/ia32/ia32_reg.c optional compat_ia32
-ia64/ia32/ia32_signal.c optional compat_ia32
-ia64/ia32/ia32_trap.c optional compat_ia32
+ia64/ia32/ia32_misc.c optional compat_freebsd32
+ia64/ia32/ia32_reg.c optional compat_freebsd32
+ia64/ia32/ia32_signal.c optional compat_freebsd32
+ia64/ia32/ia32_trap.c optional compat_freebsd32
ia64/ia64/autoconf.c standard
ia64/ia64/bus_machdep.c standard
ia64/ia64/busdma_machdep.c standard
@@ -117,7 +117,7 @@ ia64/isa/isa_dma.c optional isa
ia64/pci/pci_cfgreg.c optional pci
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
-kern/imgact_elf32.c optional compat_ia32
+kern/imgact_elf32.c optional compat_freebsd32
libkern/bcmp.c standard
libkern/ffsl.c standard
libkern/fls.c standard
diff --git a/sys/conf/files.mips b/sys/conf/files.mips
index 4b6c54a..f88949c 100644
--- a/sys/conf/files.mips
+++ b/sys/conf/files.mips
@@ -50,7 +50,6 @@ mips/mips/bus_space_generic.c standard
mips/mips/busdma_machdep.c standard
mips/mips/cache.c standard
mips/mips/cache_mipsNN.c standard
-#mips/mips/copystr.S standard
mips/mips/db_disasm.c optional ddb
mips/mips/db_interface.c optional ddb
mips/mips/db_trace.c optional ddb
@@ -101,3 +100,6 @@ dev/siba/siba_cc.c optional siba
dev/siba/siba_core.c optional siba
dev/siba/siba_pcib.c optional siba pci
#mips/sentry5/siba_mips.c optional siba # not yet
+
+dev/hwpmc/hwpmc_mips.c optional hwpmc
+dev/hwpmc/hwpmc_mips24k.c optional hwpmc
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 314b16e..b24faae 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -99,6 +99,7 @@ dev/fe/if_fe_cbus.c optional fe isa
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_intel.c optional hwpmc
dev/hwpmc/hwpmc_core.c optional hwpmc
+dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_pentium.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_ppro.c optional hwpmc
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64
index 1f8c4a3..63ee2c5 100644
--- a/sys/conf/files.sparc64
+++ b/sys/conf/files.sparc64
@@ -22,7 +22,7 @@ ukbdmap.h optional ukbd_dflt_keymap \
no-obj no-implicit-rule before-depend \
clean "ukbdmap.h"
#
-crypto/blowfish/bf_enc.c optional crypto | ipsec
+crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/atkbdc/atkbd.c optional atkbd atkbdc
dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc
@@ -42,11 +42,11 @@ dev/kbd/kbd.c optional atkbd | sc | ukbd
dev/le/if_le_lebuffer.c optional le sbus
dev/le/if_le_ledma.c optional le sbus
dev/le/lebuffer_sbus.c optional le sbus
-dev/ofw/ofw_if.m standard
dev/ofw/ofw_bus_if.m standard
dev/ofw/ofw_bus_subr.c standard
-dev/ofw/ofw_standard.c standard
dev/ofw/ofw_console.c optional ofw_console
+dev/ofw/ofw_if.m standard
+dev/ofw/ofw_standard.c standard
dev/ofw/openfirm.c standard
dev/ofw/openfirmio.c standard
dev/ofw/openpromio.c standard
@@ -79,6 +79,7 @@ sparc64/pci/ofw_pcib.c optional pci
sparc64/pci/ofw_pcib_subr.c optional pci
sparc64/pci/ofw_pcibus.c optional pci
sparc64/pci/psycho.c optional pci
+sparc64/pci/sbbc.c optional sbbc uart
sparc64/pci/schizo.c optional pci
sparc64/sbus/dma_sbus.c optional sbus
sparc64/sbus/sbus.c optional sbus
diff --git a/sys/conf/files.sun4v b/sys/conf/files.sun4v
index 5964f56..62e9e9b 100644
--- a/sys/conf/files.sun4v
+++ b/sys/conf/files.sun4v
@@ -18,12 +18,12 @@ ukbdmap.h optional ukbd_dflt_keymap \
clean "ukbdmap.h"
#
#
-crypto/blowfish/bf_enc.c optional crypto | ipsec
+crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/ofw/ofw_bus_if.m standard
-dev/ofw/ofw_if.m standard
dev/ofw/ofw_bus_subr.c standard
dev/ofw/ofw_console.c optional ofw_console
+dev/ofw/ofw_if.m standard
dev/ofw/ofw_standard.c standard
dev/ofw/openfirm.c standard
dev/ofw/openfirmio.c standard
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
index 0f5cd66..7e23a80 100644
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -108,3 +108,11 @@ CFLAGS+= -restrict
${MACHINE_ARCH} != "arm" && ${MACHINE_ARCH} != "mips"
CFLAGS+= -fstack-protector
.endif
+
+#
+# Enable CTF conversation on request.
+#
+.if defined(WITH_CTF)
+.undef NO_CTF
+.endif
+
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
index ed56568..c5c9c34 100644
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -15,6 +15,14 @@ MKMODULESENV+= DESTDIR="${DESTDIR}"
SYSDIR?= ${S:C;^[^/];${.CURDIR}/&;}
MKMODULESENV+= KERNBUILDDIR="${.CURDIR}" SYSDIR="${SYSDIR}"
+.if defined(CONF_CFLAGS)
+MKMODULESENV+= CONF_CFLAGS="${CONF_CFLAGS}"
+.endif
+
+.if defined(WITH_CTF)
+MKMODULESENV+= WITH_CTF="${WITH_CTF}"
+.endif
+
.MAIN: all
.for target in all clean cleandepend cleandir clobber depend install \
@@ -86,9 +94,7 @@ ${FULLKERNEL}: ${SYSTEM_DEP} vers.o
@rm -f ${.TARGET}
@echo linking ${.TARGET}
${SYSTEM_LD}
-.if defined(CTFMERGE)
- ${SYSTEM_CTFMERGE}
-.endif
+ @${SYSTEM_CTFMERGE}
.if !defined(DEBUG)
${OBJCOPY} --strip-debug ${.TARGET}
.endif
@@ -236,9 +242,7 @@ kernel-reinstall:
config.o env.o hints.o vers.o vnode_if.o:
${NORMAL_C}
-.if defined(CTFCONVERT)
- ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.endif
+ @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
config.ln env.ln hints.ln vers.ln vnode_if.ln:
${NORMAL_LINT}
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index ee74a9e..b70f5f1 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -128,11 +128,8 @@ NORMAL_C_NOWERROR= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
NORMAL_M= ${AWK} -f $S/tools/makeobjops.awk ${.IMPSRC} -c ; \
${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.PREFIX}.c
-.if defined(CTFCONVERT)
-NORMAL_CTFCONVERT= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
-.else
-NORMAL_CTFCONVERT=
-.endif
+NORMAL_CTFCONVERT= [ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
+ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
NORMAL_LINT= ${LINT} ${LINTFLAGS} ${CFLAGS:M-[DIU]*} ${.IMPSRC}
@@ -142,10 +139,7 @@ SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
SYSTEM_OBJS= locore.o ${MDOBJS} ${OBJS}
SYSTEM_OBJS+= ${SYSTEM_CFILES:.c=.o}
SYSTEM_OBJS+= hack.So
-.if defined(CTFMERGE)
-SYSTEM_CTFMERGE= ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
-LD+= -g
-.endif
+SYSTEM_CTFMERGE= [ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
SYSTEM_LD= @${LD} -Bdynamic -T ${LDSCRIPT} \
-warn-common -export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index 6d543e4..18bfbb1 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -69,6 +69,11 @@ OBJCOPY?= objcopy
.error "Do not use KMODDEPS on 5.0+; use MODULE_VERSION/MODULE_DEPEND"
.endif
+# Enable CTF conversion on request.
+.if defined(WITH_CTF)
+.undef NO_CTF
+.endif
+
.include <bsd.init.mk>
.SUFFIXES: .out .o .c .cc .cxx .C .y .l .s .S
@@ -132,6 +137,10 @@ CFLAGS+= -mlongcall -fno-omit-frame-pointer
CFLAGS+= -G0 -fno-pic -mno-abicalls -mlong-calls
.endif
+.if defined(DEBUG) || defined(DEBUG_FLAGS)
+CTFFLAGS+= -g
+.endif
+
.if defined(FIRMWS)
.if !exists(@)
${KMOD:S/$/.c/}: @
@@ -197,6 +206,7 @@ ${KMOD}.kld: ${OBJS}
${FULLPROG}: ${OBJS}
.endif
${LD} ${LDFLAGS} -r -d -o ${.TARGET} ${OBJS}
+ @[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.if defined(EXPORT_SYMS)
.if ${EXPORT_SYMS} != YES
.if ${EXPORT_SYMS} == NO
@@ -325,6 +335,9 @@ ${_src}:
.endfor
.endif
+# Respect configuration-specific C flags.
+CFLAGS+= ${CONF_CFLAGS}
+
MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m \
dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \
dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \
diff --git a/sys/conf/ldscript.mips.octeon1.32 b/sys/conf/ldscript.mips.octeon1.32
index d3b3c41..3d1d91c 100644
--- a/sys/conf/ldscript.mips.octeon1.32
+++ b/sys/conf/ldscript.mips.octeon1.32
@@ -1,13 +1,15 @@
-/*
- * This product includes software developed by the University of
- * California, Berkeley and its contributors."
-*/
+/* $FreeBSD$ */
+
+TARGET(elf32-tradbigmips)
OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
+ __DYNAMIC = 0;
+PROVIDE (_DYNAMIC = 0);
SECTIONS {
. = KERNLOADADDR + SIZEOF_HEADERS;
+
.text . : {
*(.text)
*(.dynamic)
diff --git a/sys/conf/ldscript.mips.octeon1.64 b/sys/conf/ldscript.mips.octeon1.64
index b476abf..aaef945 100644
--- a/sys/conf/ldscript.mips.octeon1.64
+++ b/sys/conf/ldscript.mips.octeon1.64
@@ -1,23 +1,22 @@
+/* $FreeBSD$ */
+
TARGET(elf64-tradbigmips)
OUTPUT_FORMAT("elf64-tradbigmips", "elf64-tradbigmips", "elf64-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
-/* __DYNAMIC = 0;
+ __DYNAMIC = 0;
PROVIDE (_DYNAMIC = 0);
-*/
-PHDRS {
- text PT_LOAD FLAGS ( 5 ) ;
-}
SECTIONS {
+ . = KERNLOADADDR + SIZEOF_HEADERS;
- .text _start : {
+ .text . : {
*(.text)
- /*(.dynamic)*/
+ *(.dynamic)
etext = .;
_etext = .;
. = ALIGN(0x2000);
- } : text
+ }
.rodata ALIGN(0x2000) : {
_fdata = .;
diff --git a/sys/conf/ldscript.mips.octeon1.n32 b/sys/conf/ldscript.mips.octeon1.n32
index 4eb3224..62af8b9 100644
--- a/sys/conf/ldscript.mips.octeon1.n32
+++ b/sys/conf/ldscript.mips.octeon1.n32
@@ -1,3 +1,5 @@
+/* $FreeBSD$ */
+
TARGET(elf32-ntradbigmips)
OUTPUT_FORMAT("elf32-ntradbigmips", "elf32-ntradbigmips", "elf32-ntradlittlemips")
OUTPUT_ARCH(mips)
@@ -6,6 +8,7 @@ ENTRY(_start)
PROVIDE (_DYNAMIC = 0);
SECTIONS {
+ . = KERNLOADADDR + SIZEOF_HEADERS;
.text . : {
*(.text)
diff --git a/sys/conf/options b/sys/conf/options
index 7869add..fabc0bf 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -437,6 +437,7 @@ SCTP_MBCNT_LOGGING opt_sctp.h # Log to KTR mbcnt activity
SCTP_PACKET_LOGGING opt_sctp.h # Log to a packet buffer last N packets
SCTP_LTRACE_CHUNKS opt_sctp.h # Log to KTR chunks processed
SCTP_LTRACE_ERRORS opt_sctp.h # Log to KTR error returns.
+SCTP_USE_PERCPU_STAT opt_sctp.h # Use per cpu stats.
#
#
#
diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
index 5617da4..20a49a1 100644
--- a/sys/conf/options.amd64
+++ b/sys/conf/options.amd64
@@ -11,7 +11,7 @@ MP_WATCHDOG
# Options for emulators. These should only be used at config time, so
# they are handled like options for static filesystems
# (see src/sys/conf/options), except for broken debugging options.
-COMPAT_IA32 opt_compat.h
+COMPAT_FREEBSD32 opt_compat.h
#IBCS2 opt_dontuse.h
#COMPAT_LINUX opt_dontuse.h
COMPAT_LINUX32 opt_compat.h
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index 83f8286..333ec6a 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -12,6 +12,7 @@ I586_PMC_GUPROF opt_i586_guprof.h
MAXMEM
MPTABLE_FORCE_HTT
MP_WATCHDOG
+NKPT opt_pmap.h
PERFMON
PMAP_SHPGPERPROC opt_pmap.h
POWERFAIL_NMI opt_trap.h
diff --git a/sys/conf/options.ia64 b/sys/conf/options.ia64
index 7a292ed..603c5ed 100644
--- a/sys/conf/options.ia64
+++ b/sys/conf/options.ia64
@@ -9,7 +9,7 @@ LOG2_PAGE_SIZE opt_global.h
UWX_TRACE_ENABLE opt_global.h
-COMPAT_IA32 opt_compat.h
+COMPAT_FREEBSD32 opt_compat.h
EXCEPTION_TRACING opt_xtrace.h
diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt
index 60620ce..d2c8c0e 100644
--- a/sys/contrib/dev/acpica/changes.txt
+++ b/sys/contrib/dev/acpica/changes.txt
@@ -1,4 +1,132 @@
----------------------------------------
+31 March 2010. Summary of changes for version 20100331:
+
+1) ACPI CA Core Subsystem:
+
+Completed a major update for the GPE support in order to improve support for
+shared GPEs and to simplify both host OS and ACPICA code. Added a reference
+count mechanism to support shared GPEs that require multiple device drivers.
+Several external interfaces have changed. One external interface has been
+removed. One new external interface was added. Most of the GPE external
+interfaces now use the GPE spinlock instead of the events mutex (and the
+Flags parameter for many GPE interfaces has been removed.) See the updated
+ACPICA Programmer Reference for details. Matthew Garrett, Bob Moore, Rafael
+Wysocki. ACPICA BZ 831.
+
+Changed:
+ AcpiEnableGpe, AcpiDisableGpe, AcpiClearGpe, AcpiGetGpeStatus
+Removed:
+ AcpiSetGpeType
+New:
+ AcpiSetGpe
+
+Implemented write support for DataTable operation regions. These regions are
+defined via the DataTableRegion() operator. Previously, only read support was
+implemented. The ACPI specification allows DataTableRegions to be read/write,
+however.
+
+Implemented a new subsystem option to force a copy of the DSDT to local
+memory. Optionally copy the entire DSDT to local memory (instead of simply
+mapping it.) There are some (albeit very rare) BIOSs that corrupt or replace
+the original DSDT, creating the need for this option. Default is FALSE, do
+not copy the DSDT.
+
+Implemented detection of a corrupted or replaced DSDT. This change adds
+support to detect a DSDT that has been corrupted and/or replaced from outside
+the OS (by firmware). This is typically catastrophic for the system, but has
+been seen on some machines. Once this problem has been detected, the DSDT
+copy option can be enabled via system configuration. Lin Ming, Bob Moore.
+
+Fixed two problems with AcpiReallocateRootTable during the root table copy.
+When copying the root table to the new allocation, the length used was
+incorrect. The new size was used instead of the current table size, meaning
+too much data was copied. Also, the count of available slots for ACPI tables
+was not set correctly. Alexey Starikovskiy, Bob Moore.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 87.5K Code, 18.4K Data, 105.9K Total
+ Debug Version: 163.4K Code, 51.1K Data, 214.5K Total
+ Current Release:
+ Non-Debug Version: 87.9K Code, 18.6K Data, 106.5K Total
+ Debug Version: 163.5K Code, 51.3K Data, 214.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implement limited typechecking for values returned from predefined
+control methods. The type of any returned static (unnamed) object is now
+validated. For example, Return(1). ACPICA BZ 786.
+
+iASL: Fixed a predefined name object verification regression. Fixes a problem
+introduced in version 20100304. An error is incorrectly generated if a
+predefined name is declared as a static named object with a value defined
+using the keywords "Zero", "One", or "Ones". Lin Ming.
+
+iASL: Added Windows 7 support for the -g option (get local ACPI tables) by
+reducing the requested registry access rights. ACPICA BZ 842.
+
+Disassembler: fixed a possible fault when generating External() statements.
+Introduced in commit ae7d6fd: Properly handle externals with parent-prefix
+(carat). Fixes a string length allocation calculation. Lin Ming.
+
+----------------------------------------
+04 March 2010. Summary of changes for version 20100304:
+
+1) ACPI CA Core Subsystem:
+
+Fixed a possible problem with the AML Mutex handling function
+AcpiExReleaseMutex where the function could fault under the very rare
+condition when the interpreter has blocked, the interpreter lock is released,
+the interpreter is then reentered via the same thread, and attempts to
+acquire an AML mutex that was previously acquired. FreeBSD report 140979. Lin
+Ming.
+
+Implemented additional configuration support for the AML "Debug Object".
+Output from the debug object can now be enabled via a global variable,
+AcpiGbl_EnableAmlDebugObject. This will assist with remote machine debugging.
+This debug output is now available in the release version of ACPICA instead
+of just the debug version. Also, the entire debug output module can now be
+configured out of the ACPICA build if desired. One new file added,
+executer/exdebug.c. Lin Ming, Bob Moore.
+
+Added header support for the ACPI MCHI table (Management Controller Host
+Interface Table). This table was added in ACPI 4.0, but the defining document
+has only recently become available.
+
+Standardized output of integer values for ACPICA warnings/errors. Always use
+0x prefix for hex output, always use %u for unsigned integer decimal output.
+Affects ACPI_INFO, ACPI_ERROR, ACPI_EXCEPTION, and ACPI_WARNING (about 400
+invocations.) These invocations were converted from the original
+ACPI_DEBUG_PRINT invocations and were not consistent. ACPICA BZ 835.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 87.1K Code, 18.0K Data, 105.1K Total
+ Debug Version: 163.5K Code, 50.9K Data, 214.4K Total
+ Current Release:
+ Non-Debug Version: 87.5K Code, 18.4K Data, 105.9K Total
+ Debug Version: 163.4K Code, 51.1K Data, 214.5K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implemented typechecking support for static (non-control method)
+predefined named objects that are declared with the Name() operator. For
+example, the type of this object is now validated to be of type Integer:
+Name(_BBN, 1). This change migrates the compiler to using the core predefined
+name table instead of maintaining a local version. Added a new file,
+aslpredef.c. ACPICA BZ 832.
+
+Disassembler: Added support for the ACPI 4.0 MCHI table.
+
+----------------------------------------
21 January 2010. Summary of changes for version 20100121:
1) ACPI CA Core Subsystem:
diff --git a/sys/contrib/dev/acpica/common/dmextern.c b/sys/contrib/dev/acpica/common/dmextern.c
index 943a3c2..8d95571 100644
--- a/sys/contrib/dev/acpica/common/dmextern.c
+++ b/sys/contrib/dev/acpica/common/dmextern.c
@@ -270,6 +270,15 @@ AcpiDmNormalizeParentPrefix (
}
Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
+ if (ParentPath[1])
+ {
+ /*
+ * If ParentPath is not just a simple '\', increment the length
+ * for the required dot separator (ParentPath.Path)
+ */
+ Length++;
+ }
+
Fullpath = ACPI_ALLOCATE_ZEROED (Length);
if (!Fullpath)
{
@@ -374,7 +383,7 @@ AcpiDmAddToExternalList (
(NextExternal->Value != Value))
{
ACPI_ERROR ((AE_INFO,
- "Argument count mismatch for method %s %d %d",
+ "Argument count mismatch for method %s %u %u",
NextExternal->Path, NextExternal->Value, Value));
}
diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c
index 7085891..4b96575 100644
--- a/sys/contrib/dev/acpica/common/dmtable.c
+++ b/sys/contrib/dev/acpica/common/dmtable.c
@@ -262,6 +262,7 @@ static ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, "I/O Virtualization Reporting Structure"},
{ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, "Multiple APIC Description Table"},
{ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, "Memory Mapped Configuration table"},
+ {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, "Management Controller Host Interface table"},
{ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, "Maximum System Characteristics Table"},
{ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, "Root System Description Table"},
{ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, "Smart Battery Specification Table"},
@@ -911,7 +912,7 @@ AcpiDmDumpTable (
default:
ACPI_ERROR ((AE_INFO,
- "**** Invalid table opcode [%X] ****\n", Info->Opcode));
+ "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
return (AE_SUPPORT);
}
}
diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c
index 2c9725d..143cf5b 100644
--- a/sys/contrib/dev/acpica/common/dmtbdump.c
+++ b/sys/contrib/dev/acpica/common/dmtbdump.c
@@ -363,7 +363,7 @@ AcpiDmDumpAsf (
break;
default:
- AcpiOsPrintf ("\n**** Unknown ASF sub-table type %X\n", SubTable->Header.Type);
+ AcpiOsPrintf ("\n**** Unknown ASF sub-table type 0x%X\n", SubTable->Header.Type);
return;
}
@@ -561,7 +561,7 @@ AcpiDmDumpDmar (
ScopeOffset = sizeof (ACPI_DMAR_RHSA);
break;
default:
- AcpiOsPrintf ("\n**** Unknown DMAR sub-table type %X\n\n", SubTable->Type);
+ AcpiOsPrintf ("\n**** Unknown DMAR sub-table type 0x%X\n\n", SubTable->Type);
return;
}
@@ -809,7 +809,7 @@ AcpiDmDumpHest (
default:
/* Cannot continue on unknown type - no length */
- AcpiOsPrintf ("\n**** Unknown HEST sub-table type %X\n", SubTable->Type);
+ AcpiOsPrintf ("\n**** Unknown HEST sub-table type 0x%X\n", SubTable->Type);
return;
}
@@ -916,7 +916,7 @@ AcpiDmDumpIvrs (
InfoTable = AcpiDmTableInfoIvrs1;
break;
default:
- AcpiOsPrintf ("\n**** Unknown IVRS sub-table type %X\n",
+ AcpiOsPrintf ("\n**** Unknown IVRS sub-table type 0x%X\n",
SubTable->Type);
/* Attempt to continue */
@@ -1002,7 +1002,7 @@ AcpiDmDumpIvrs (
InfoTable = AcpiDmTableInfoIvrs4;
AcpiOsPrintf (
"\n**** Unknown IVRS device entry type/length: "
- "%.2X/%X at offset %.4X: (header below)\n",
+ "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
EntryType, EntryLength, EntryOffset);
break;
}
@@ -1110,7 +1110,7 @@ AcpiDmDumpMadt (
InfoTable = AcpiDmTableInfoMadt10;
break;
default:
- AcpiOsPrintf ("\n**** Unknown MADT sub-table type %X\n\n", SubTable->Type);
+ AcpiOsPrintf ("\n**** Unknown MADT sub-table type 0x%X\n\n", SubTable->Type);
/* Attempt to continue */
@@ -1378,7 +1378,7 @@ AcpiDmDumpSrat (
InfoTable = AcpiDmTableInfoSrat2;
break;
default:
- AcpiOsPrintf ("\n**** Unknown SRAT sub-table type %X\n", SubTable->Type);
+ AcpiOsPrintf ("\n**** Unknown SRAT sub-table type 0x%X\n", SubTable->Type);
/* Attempt to continue */
diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c
index 6d3b500..e3f91d9 100644
--- a/sys/contrib/dev/acpica/common/dmtbinfo.c
+++ b/sys/contrib/dev/acpica/common/dmtbinfo.c
@@ -142,6 +142,7 @@
#define ACPI_IVRS_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_IVRS,f)
#define ACPI_MADT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MADT,f)
#define ACPI_MCFG_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MCFG,f)
+#define ACPI_MCHI_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MCHI,f)
#define ACPI_MSCT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MSCT,f)
#define ACPI_SBST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SBST,f)
#define ACPI_SLIT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SLIT,f)
@@ -1226,6 +1227,30 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[] =
/*******************************************************************************
*
+ * MCHI - Management Controller Host Interface table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[] =
+{
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (InterfaceType), "Interface Type"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (Protocol), "Protocol"},
+ {ACPI_DMT_UINT64, ACPI_MCHI_OFFSET (ProtocolData), "Protocol Data"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (InterruptType), "Interrupt Type"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (Gpe), "Gpe"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciDeviceFlag), "Pci Device Flag"},
+ {ACPI_DMT_UINT32, ACPI_MCHI_OFFSET (GlobalInterrupt), "Global Interrupt"},
+ {ACPI_DMT_GAS, ACPI_MCHI_OFFSET (ControlRegister), "Control Register"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciSegment), "Pci Segment"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciBus), "Pci Bus"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciDevice), "Pci Device"},
+ {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciFunction), "Pci Function"},
+ {ACPI_DMT_EXIT, 0, NULL}
+};
+
+
+/*******************************************************************************
+ *
* MSCT - Maximum System Characteristics Table (ACPI 4.0)
*
******************************************************************************/
diff --git a/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c
index 46a6db0..608f6e5 100644
--- a/sys/contrib/dev/acpica/compiler/aslanalyze.c
+++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c
@@ -143,16 +143,6 @@ AnGetBtype (
ACPI_PARSE_OBJECT *Op);
static UINT32
-AnCheckForReservedName (
- ACPI_PARSE_OBJECT *Op,
- char *Name);
-
-static void
-AnCheckForReservedMethod (
- ACPI_PARSE_OBJECT *Op,
- ASL_METHOD_INFO *MethodInfo);
-
-static UINT32
AnMapObjTypeToBtype (
ACPI_PARSE_OBJECT *Op);
@@ -598,219 +588,6 @@ AnGetBtype (
/*******************************************************************************
*
- * FUNCTION: AnCheckForReservedName
- *
- * PARAMETERS: Op - A parse node
- * Name - NameSeg to check
- *
- * RETURN: None
- *
- * DESCRIPTION: Check a NameSeg against the reserved list.
- *
- ******************************************************************************/
-
-static UINT32
-AnCheckForReservedName (
- ACPI_PARSE_OBJECT *Op,
- char *Name)
-{
- UINT32 i;
-
-
- if (Name[0] == 0)
- {
- AcpiOsPrintf ("Found a null name, external = %s\n",
- Op->Asl.ExternalName);
- }
-
- /* All reserved names are prefixed with a single underscore */
-
- if (Name[0] != '_')
- {
- return (ACPI_NOT_RESERVED_NAME);
- }
-
- /* Check for a standard reserved method name */
-
- for (i = 0; ReservedMethods[i].Name; i++)
- {
- if (ACPI_COMPARE_NAME (Name, ReservedMethods[i].Name))
- {
- if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
- {
- AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
- Op->Asl.ExternalName);
- return (ACPI_PREDEFINED_NAME);
- }
- else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
- {
- AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
- Op->Asl.ExternalName);
- return (ACPI_PREDEFINED_NAME);
- }
-
- /* Return index into reserved array */
-
- return i;
- }
- }
-
- /*
- * Now check for the "special" reserved names --
- * GPE: _Lxx
- * GPE: _Exx
- * EC: _Qxx
- */
- if ((Name[1] == 'L') ||
- (Name[1] == 'E') ||
- (Name[1] == 'Q'))
- {
- /* The next two characters must be hex digits */
-
- if ((isxdigit ((int) Name[2])) &&
- (isxdigit ((int) Name[3])))
- {
- return (ACPI_EVENT_RESERVED_NAME);
- }
- }
-
-
- /* Check for the names reserved for the compiler itself: _T_x */
-
- else if ((Op->Asl.ExternalName[1] == 'T') &&
- (Op->Asl.ExternalName[2] == '_'))
- {
- /* Ignore if actually emitted by the compiler */
-
- if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
- {
- return (ACPI_NOT_RESERVED_NAME);
- }
-
- /*
- * Was not actually emitted by the compiler. This is a special case,
- * however. If the ASL code being compiled was the result of a
- * dissasembly, it may possibly contain valid compiler-emitted names
- * of the form "_T_x". We don't want to issue an error or even a
- * warning and force the user to manually change the names. So, we
- * will issue a remark instead.
- */
- AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
- return (ACPI_COMPILER_RESERVED_NAME);
- }
-
- /*
- * The name didn't match any of the known reserved names. Flag it as a
- * warning, since the entire namespace starting with an underscore is
- * reserved by the ACPI spec.
- */
- AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
- Op->Asl.ExternalName);
-
- return (ACPI_NOT_RESERVED_NAME);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AnCheckForReservedMethod
- *
- * PARAMETERS: Op - A parse node of type "METHOD".
- * MethodInfo - Saved info about this method
- *
- * RETURN: None
- *
- * DESCRIPTION: If method is a reserved name, check that the number of arguments
- * and the return type (returns a value or not) is correct.
- *
- ******************************************************************************/
-
-static void
-AnCheckForReservedMethod (
- ACPI_PARSE_OBJECT *Op,
- ASL_METHOD_INFO *MethodInfo)
-{
- UINT32 Index;
- UINT32 RequiredArgsCurrent;
- UINT32 RequiredArgsOld;
-
-
- /* Check for a match against the reserved name list */
-
- Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
-
- switch (Index)
- {
- case ACPI_NOT_RESERVED_NAME:
- case ACPI_PREDEFINED_NAME:
- case ACPI_COMPILER_RESERVED_NAME:
-
- /* Just return, nothing to do */
- break;
-
-
- case ACPI_EVENT_RESERVED_NAME:
-
- Gbl_ReservedMethods++;
-
- /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
-
- if (MethodInfo->NumArguments != 0)
- {
- sprintf (MsgBuffer, "%s requires %d",
- Op->Asl.ExternalName, 0);
-
- AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
- }
- break;
-
-
- default:
-
- Gbl_ReservedMethods++;
-
- /*
- * Matched a reserved method name
- *
- * Validate the ASL-defined argument count. Allow two different legal
- * arg counts.
- */
- RequiredArgsCurrent = ReservedMethods[Index].NumArguments & 0x0F;
- RequiredArgsOld = ReservedMethods[Index].NumArguments >> 4;
-
- if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
- (MethodInfo->NumArguments != RequiredArgsOld))
- {
- sprintf (MsgBuffer, "%s requires %d",
- ReservedMethods[Index].Name,
- RequiredArgsCurrent);
-
- if (MethodInfo->NumArguments > RequiredArgsCurrent)
- {
- AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
- MsgBuffer);
- }
- else
- {
- AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
- MsgBuffer);
- }
- }
-
- if (MethodInfo->NumReturnNoValue &&
- ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
- {
- sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
-
- AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
- }
- break;
- }
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AnMapObjTypeToBtype
*
* PARAMETERS: Op - A parse node
@@ -1187,7 +964,7 @@ AnMethodAnalysisWalkBegin (
* The first operand is a name to be created in the namespace.
* Check against the reserved list.
*/
- i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
+ i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
if (i < ACPI_VALID_RESERVED_NAME_MAX)
{
AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
@@ -1197,51 +974,29 @@ AnMethodAnalysisWalkBegin (
case PARSEOP_NAME:
- i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
- if (i < ACPI_VALID_RESERVED_NAME_MAX)
+ /* Typecheck any predefined names statically defined with Name() */
+
+ ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
+
+ /* Special typechecking for _HID */
+
+ if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg))
{
- if (ReservedMethods[i].NumArguments > 0)
+ Next = Op->Asl.Child->Asl.Next;
+ if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
{
/*
- * This reserved name must be a control method because
- * it must have arguments
+ * _HID is a string, all characters must be alphanumeric.
+ * One of the things we want to catch here is the use of
+ * a leading asterisk in the string.
*/
- AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
- "with arguments");
- }
-
- /* Typechecking for _HID */
-
- else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
- {
- /* Examine the second operand to typecheck it */
-
- Next = Op->Asl.Child->Asl.Next;
-
- if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
- (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
+ for (i = 0; Next->Asl.Value.String[i]; i++)
{
- /* _HID must be a string or an integer */
-
- AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next,
- "String or Integer");
- }
-
- if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
- {
- /*
- * _HID is a string, all characters must be alphanumeric.
- * One of the things we want to catch here is the use of
- * a leading asterisk in the string.
- */
- for (i = 0; Next->Asl.Value.String[i]; i++)
+ if (!isalnum ((int) Next->Asl.Value.String[i]))
{
- if (!isalnum ((int) Next->Asl.Value.String[i]))
- {
- AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
- Next, Next->Asl.Value.String);
- break;
- }
+ AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
+ Next, Next->Asl.Value.String);
+ break;
}
}
}
@@ -1394,7 +1149,7 @@ AnMethodAnalysisWalkEnd (
* Check predefined method names for correct return behavior
* and correct number of arguments
*/
- AnCheckForReservedMethod (Op, MethodInfo);
+ ApCheckForPredefinedMethod (Op, MethodInfo);
ACPI_FREE (MethodInfo);
break;
@@ -1402,6 +1157,12 @@ AnMethodAnalysisWalkEnd (
case PARSEOP_RETURN:
/*
+ * If the parent is a predefined method name, attempt to typecheck
+ * the return value. Only static types can be validated.
+ */
+ ApCheckPredefinedReturnValue (Op, MethodInfo);
+
+ /*
* The parent block does not "exit" and continue execution -- the
* method is terminated here with the Return() statement.
*/
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h
index 16b5f72..dbc2709 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h
@@ -452,8 +452,32 @@ ACPI_OBJECT_TYPE
AslMapNamedOpcodeToDataType (
UINT16 Opcode);
+
+/*
+ * aslpredef - ACPI predefined names support
+ */
+void
+ApCheckForPredefinedMethod (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
+void
+ApCheckPredefinedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
+UINT32
+ApCheckForPredefinedName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
+void
+ApCheckForPredefinedObject (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
void
-MpDisplayReservedNames (
+ApDisplayReservedNames (
void);
diff --git a/sys/contrib/dev/acpica/compiler/aslglobal.h b/sys/contrib/dev/acpica/compiler/aslglobal.h
index 69fcf84..01ab931 100644
--- a/sys/contrib/dev/acpica/compiler/aslglobal.h
+++ b/sys/contrib/dev/acpica/compiler/aslglobal.h
@@ -261,7 +261,6 @@ ASL_EXTERN FILE *AcpiGbl_DebugFile; /* Placeholder for oswin
ASL_EXTERN ASL_ANALYSIS_WALK_INFO AnalysisWalkInfo;
ASL_EXTERN ACPI_TABLE_HEADER TableHeader;
-extern const ASL_RESERVED_INFO ReservedMethods[];
/* Event timing */
diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c
index 9b9e956..e8b0c45 100644
--- a/sys/contrib/dev/acpica/compiler/aslmain.c
+++ b/sys/contrib/dev/acpica/compiler/aslmain.c
@@ -570,7 +570,7 @@ AslDoOptions (
case 'r':
/* reserved names */
- MpDisplayReservedNames ();
+ ApDisplayReservedNames ();
exit (0);
default:
diff --git a/sys/contrib/dev/acpica/compiler/aslmap.c b/sys/contrib/dev/acpica/compiler/aslmap.c
index be43b22..4027a62 100644
--- a/sys/contrib/dev/acpica/compiler/aslmap.c
+++ b/sys/contrib/dev/acpica/compiler/aslmap.c
@@ -114,7 +114,6 @@
*
*****************************************************************************/
-
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include <contrib/dev/acpica/include/amlcode.h>
#include <contrib/dev/acpica/include/acparser.h>
@@ -171,322 +170,6 @@ AslMapNamedOpcodeToDataType (
/*******************************************************************************
*
- * FUNCTION: MpDisplayReservedNames
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Print the table above
- *
- ******************************************************************************/
-
-void
-MpDisplayReservedNames (
- void)
-{
- UINT32 i;
-
- printf ("Reserved name information\n\n");
-
- for (i = 0; ReservedMethods[i].Name; i++)
- {
- printf ("%s ", ReservedMethods[i].Name);
-
- if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
- {
- printf ("Reserved scope name\n");
- }
- else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
- {
- printf ("Resource data type reserved field name\n");
- }
- else
- {
- printf ("Method with %d arguments, ",
- ReservedMethods[i].NumArguments & 0x0F);
-
- if (ReservedMethods[i].Flags & ASL_RSVD_RETURN_VALUE)
- {
- printf ("must return a value\n");
- }
- else
- {
- printf ("no return value\n");
- }
- }
- }
-}
-
-
-/*******************************************************************************
- *
- * DATA STRUCTURE: ReservedMethods
- *
- * DESCRIPTION: Contains all reserved methods and names as defined in the
- * ACPI specification. Used during the analysis phase to
- * ensure that reserved methods have the required number of
- * arguments and the proper return type.
- *
- * Each entry in the table contains the following items:
- *
- * Name - The ACPI reserved name
- * Args - Number of arguments to the method
- * Flags - Whether this method must return a value or not. Or if the
- * name is a resource descriptor label.
- *
- ******************************************************************************/
-
-const ASL_RESERVED_INFO ReservedMethods[] = {
- {"_AC0", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC1", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC2", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC3", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC4", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC5", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC6", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC7", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC8", 0, ASL_RSVD_RETURN_VALUE},
- {"_AC9", 0, ASL_RSVD_RETURN_VALUE},
- {"_ADR", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL0", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL1", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL2", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL3", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL4", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL5", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL6", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL7", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL8", 0, ASL_RSVD_RETURN_VALUE},
- {"_AL9", 0, ASL_RSVD_RETURN_VALUE},
- {"_ALC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_ALI", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_ALN", 0, ASL_RSVD_RESOURCE_NAME},
- {"_ALP", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_ALR", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_ALT", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_ART", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_ASI", 0, ASL_RSVD_RESOURCE_NAME},
- {"_ASZ", 0, ASL_RSVD_RESOURCE_NAME},
- {"_BAS", 0, ASL_RSVD_RESOURCE_NAME},
- {"_BBN", 0, ASL_RSVD_RETURN_VALUE},
- {"_BCL", 0, ASL_RSVD_RETURN_VALUE},
- {"_BCM", 1, 0},
- {"_BCT", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_BDN", 0, ASL_RSVD_RETURN_VALUE},
- {"_BFS", 1, 0},
- {"_BIF", 0, ASL_RSVD_RETURN_VALUE},
- {"_BIX", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_BLT", 3, 0}, /* Acpi 3.0 */
- {"_BM_", 0, ASL_RSVD_RESOURCE_NAME},
- {"_BMA", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_BMC", 1, 0}, /* Acpi 3.0 */
- {"_BMD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_BMS", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_BQC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_BST", 0, ASL_RSVD_RETURN_VALUE},
- {"_BTM", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_BTP", 1, 0},
- {"_CBA", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_CDM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_CID", 0, ASL_RSVD_RETURN_VALUE},
- {"_CRS", 0, ASL_RSVD_RETURN_VALUE},
- {"_CRT", 0, ASL_RSVD_RETURN_VALUE},
- {"_CSD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_CST", 0, ASL_RSVD_RETURN_VALUE},
- {"_DCK", 1, ASL_RSVD_RETURN_VALUE},
- {"_DCS", 0, ASL_RSVD_RETURN_VALUE},
- {"_DDC", 1, ASL_RSVD_RETURN_VALUE},
- {"_DDN", 0, 0},
- {"_DEC", 0, ASL_RSVD_RESOURCE_NAME},
- {"_DGS", 0, ASL_RSVD_RETURN_VALUE},
- {"_DIS", 0, 0},
- {"_DMA", 0, ASL_RSVD_RETURN_VALUE},
- {"_DOD", 0, ASL_RSVD_RETURN_VALUE},
- {"_DOS", 1, 0},
- {"_DSM", 4, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_DSS", 1, 0},
- {"_DSW", 3, 0}, /* Acpi 3.0 */
- {"_DTI", 1, 0}, /* Acpi 4.0 */
- {"_EC_", 0, ASL_RSVD_RETURN_VALUE},
- {"_EDL", 0, ASL_RSVD_RETURN_VALUE},
- {"_EJ0", 1, 0},
- {"_EJ1", 1, 0},
- {"_EJ2", 1, 0},
- {"_EJ3", 1, 0},
- {"_EJ4", 1, 0},
- {"_EJD", 0, ASL_RSVD_RETURN_VALUE},
- {"_ERR", 3, ASL_RSVD_RETURN_VALUE},
- {"_FDE", 0, ASL_RSVD_RETURN_VALUE},
- {"_FDI", 0, ASL_RSVD_RETURN_VALUE},
- {"_FDM", 1, 0},
- {"_FIF", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_FIX", 0, ASL_RSVD_RETURN_VALUE},
- {"_FPS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_FSL", 1, 0}, /* Acpi 4.0 */
- {"_FST", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_GAI", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_GHL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_GL_", 0, ASL_RSVD_RETURN_VALUE},
- {"_GLK", 0, ASL_RSVD_RETURN_VALUE},
- {"_GPD", 0, ASL_RSVD_RETURN_VALUE},
- {"_GPE", 0, ASL_RSVD_RETURN_VALUE},
- {"_GRA", 0, ASL_RSVD_RESOURCE_NAME},
- {"_GSB", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_GTF", 0, ASL_RSVD_RETURN_VALUE},
- {"_GTM", 0, ASL_RSVD_RETURN_VALUE},
- {"_GTS", 1, 0},
- {"_HE_", 0, ASL_RSVD_RESOURCE_NAME},
- {"_HID", 0, ASL_RSVD_RETURN_VALUE},
- {"_HOT", 0, ASL_RSVD_RETURN_VALUE},
- {"_HPP", 0, ASL_RSVD_RETURN_VALUE},
- {"_HPX", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_IFT", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_INI", 0, 0},
- {"_INT", 0, ASL_RSVD_RESOURCE_NAME},
- {"_IRC", 0, 0},
- {"_LCK", 1, 0},
- {"_LEN", 0, ASL_RSVD_RESOURCE_NAME},
- {"_LID", 0, ASL_RSVD_RETURN_VALUE},
- {"_LL_", 0, ASL_RSVD_RESOURCE_NAME},
- {"_MAF", 0, ASL_RSVD_RESOURCE_NAME},
- {"_MAT", 0, ASL_RSVD_RETURN_VALUE},
- {"_MAX", 0, ASL_RSVD_RESOURCE_NAME},
- {"_MBM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_MEM", 0, ASL_RSVD_RESOURCE_NAME},
- {"_MIF", 0, ASL_RSVD_RESOURCE_NAME},
- {"_MIN", 0, ASL_RSVD_RESOURCE_NAME},
- {"_MLS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_MSG", 1, 0},
- {"_MSM", 4, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_MTP", 0, ASL_RSVD_RESOURCE_NAME},
- {"_NTT", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_OFF", 0, 0},
- {"_ON_", 0, 0},
- {"_OS_", 0, ASL_RSVD_RETURN_VALUE},
- {"_OSC", 4, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_OSI", 1, ASL_RSVD_RETURN_VALUE},
- {"_OST", 3, 0}, /* Acpi 3.0 */
- {"_PAI", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PCL", 0, ASL_RSVD_RETURN_VALUE},
- {"_PCT", 0, ASL_RSVD_RETURN_VALUE},
- {"_PDC", 1, 0},
- {"_PDL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PIC", 1, 0},
- {"_PIF", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PLD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_PMC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PMD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PMM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PPC", 0, ASL_RSVD_RETURN_VALUE},
- {"_PPE", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_PR0", 0, ASL_RSVD_RETURN_VALUE},
- {"_PR1", 0, ASL_RSVD_RETURN_VALUE},
- {"_PR2", 0, ASL_RSVD_RETURN_VALUE},
- {"_PR3", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PRL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PRS", 0, ASL_RSVD_RETURN_VALUE},
- {"_PRT", 0, ASL_RSVD_RETURN_VALUE},
- {"_PRW", 0, ASL_RSVD_RETURN_VALUE},
- {"_PS0", 0, 0},
- {"_PS1", 0, 0},
- {"_PS2", 0, 0},
- {"_PS3", 0, 0},
- {"_PSC", 0, ASL_RSVD_RETURN_VALUE},
- {"_PSD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_PSL", 0, ASL_RSVD_RETURN_VALUE},
- {"_PSR", 0, ASL_RSVD_RETURN_VALUE},
- {"_PSS", 0, ASL_RSVD_RETURN_VALUE},
- {"_PSV", 0, ASL_RSVD_RETURN_VALUE},
- {"_PSW", 1, 0},
- {"_PTC", 0, ASL_RSVD_RETURN_VALUE},
- {"_PTP", 2, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PTS", 1, 0},
- {"_PUR", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_PXM", 0, ASL_RSVD_RETURN_VALUE},
- {"_RBO", 0, ASL_RSVD_RESOURCE_NAME},
- {"_RBW", 0, ASL_RSVD_RESOURCE_NAME},
- {"_REG", 2, 0},
- {"_REV", 0, ASL_RSVD_RETURN_VALUE},
- {"_RMV", 0, ASL_RSVD_RETURN_VALUE},
- {"_RNG", 0, ASL_RSVD_RESOURCE_NAME},
- {"_ROM", 2, ASL_RSVD_RETURN_VALUE},
- {"_RT_", 0, ASL_RSVD_RESOURCE_NAME}, /* Acpi 3.0 */
- {"_RTV", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_RW_", 0, ASL_RSVD_RESOURCE_NAME},
- {"_S0_", 0, ASL_RSVD_RETURN_VALUE},
- {"_S1_", 0, ASL_RSVD_RETURN_VALUE},
- {"_S2_", 0, ASL_RSVD_RETURN_VALUE},
- {"_S3_", 0, ASL_RSVD_RETURN_VALUE},
- {"_S4_", 0, ASL_RSVD_RETURN_VALUE},
- {"_S5_", 0, ASL_RSVD_RETURN_VALUE},
- {"_S1D", 0, ASL_RSVD_RETURN_VALUE},
- {"_S2D", 0, ASL_RSVD_RETURN_VALUE},
- {"_S3D", 0, ASL_RSVD_RETURN_VALUE},
- {"_S4D", 0, ASL_RSVD_RETURN_VALUE},
- {"_S0W", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_S1W", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_S2W", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_S3W", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_S4W", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_SB_", 0, ASL_RSVD_SCOPE},
- {"_SBS", 0, ASL_RSVD_RETURN_VALUE},
- {"_SCP", 0x13, 0}, /* Acpi 1.0 - one arg; Acpi 3.0 - three args */
- {"_SDD", 1, 0}, /* Acpi 3.0 */
- {"_SEG", 0, ASL_RSVD_RETURN_VALUE},
- {"_SHL", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_SHR", 0, ASL_RSVD_RESOURCE_NAME},
- {"_SI_", 0, ASL_RSVD_SCOPE},
- {"_SIZ", 0, ASL_RSVD_RESOURCE_NAME},
- {"_SLI", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_SPD", 1, ASL_RSVD_RETURN_VALUE},
- {"_SRS", 1, 0},
- {"_SRV", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_SST", 1, 0},
- {"_STA", 0, ASL_RSVD_RETURN_VALUE},
- {"_STM", 3, 0},
- {"_STP", 2, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_STR", 0, ASL_RSVD_RETURN_VALUE},
- {"_STV", 2, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_SUN", 0, ASL_RSVD_RETURN_VALUE},
- {"_SWS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TC1", 0, ASL_RSVD_RETURN_VALUE},
- {"_TC2", 0, ASL_RSVD_RETURN_VALUE},
- {"_TDL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0b */
- {"_TIP", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_TIV", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */
- {"_TMP", 0, ASL_RSVD_RETURN_VALUE},
- {"_TPC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TPT", 1, 0}, /* Acpi 3.0 */
- {"_TRA", 0, ASL_RSVD_RESOURCE_NAME},
- {"_TRS", 0, ASL_RSVD_RESOURCE_NAME},
- {"_TRT", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TSD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TSF", 0, ASL_RSVD_RESOURCE_NAME}, /* Acpi 3.0 */
- {"_TSP", 0, ASL_RSVD_RETURN_VALUE},
- {"_TSS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TST", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TTP", 0, ASL_RSVD_RESOURCE_NAME},
- {"_TTS", 1, 0}, /* Acpi 3.0 */
- {"_TYP", 0, ASL_RSVD_RESOURCE_NAME},
- {"_TZ_", 0, ASL_RSVD_SCOPE},
- {"_TZD", 0, ASL_RSVD_RETURN_VALUE},
- {"_TZM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_TZP", 0, ASL_RSVD_RETURN_VALUE},
- {"_UID", 0, ASL_RSVD_RETURN_VALUE},
- {"_UPC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_UPD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_UPP", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */
- {"_VPO", 0, ASL_RSVD_RETURN_VALUE},
- {"_WAK", 1, ASL_RSVD_RETURN_VALUE},
- {"_WDG", 0, ASL_RSVD_RETURN_VALUE}, /* MS Extension */
- {"_WED", 1, ASL_RSVD_RETURN_VALUE}, /* MS Extension */
- {NULL, 0, 0},
-};
-
-
-/*******************************************************************************
- *
* DATA STRUCTURE: AslKeywordMapping
*
* DESCRIPTION: Maps the ParseOpcode to the actual AML opcode. The parse
diff --git a/sys/contrib/dev/acpica/compiler/aslpredef.c b/sys/contrib/dev/acpica/compiler/aslpredef.c
new file mode 100644
index 0000000..b9632f9
--- /dev/null
+++ b/sys/contrib/dev/acpica/compiler/aslpredef.c
@@ -0,0 +1,799 @@
+/******************************************************************************
+ *
+ * Module Name: aslpredef - support for ACPI predefined names
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#define ACPI_CREATE_PREDEFINED_TABLE
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#include "aslcompiler.y.h"
+#include <contrib/dev/acpica/include/amlcode.h>
+#include <contrib/dev/acpica/include/acparser.h>
+#include <contrib/dev/acpica/include/acpredef.h>
+
+
+#define _COMPONENT ACPI_COMPILER
+ ACPI_MODULE_NAME ("aslpredef")
+
+
+/* Local prototypes */
+
+static UINT32
+ApCheckForSpecialName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name);
+
+static void
+ApCheckObjectType (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 ExpectedBtypes);
+
+static void
+ApGetExpectedTypes (
+ char *Buffer,
+ UINT32 ExpectedBtypes);
+
+
+/*
+ * Names for the types that can be returned by the predefined objects.
+ * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
+ */
+static const char *AcpiRtypeNames[] =
+{
+ "/Integer",
+ "/String",
+ "/Buffer",
+ "/Package",
+ "/Reference",
+};
+
+/*
+ * Predefined names for use in Resource Descriptors. These names do not
+ * appear in the global Predefined Name table (since these names never
+ * appear in actual AML byte code, only in the original ASL)
+ */
+static const ACPI_PREDEFINED_INFO ResourceNames[] = {
+ {{"_ALN", 0, 0}},
+ {{"_ASI", 0, 0}},
+ {{"_ASZ", 0, 0}},
+ {{"_ATT", 0, 0}},
+ {{"_BAS", 0, 0}},
+ {{"_BM_", 0, 0}},
+ {{"_DEC", 0, 0}},
+ {{"_GRA", 0, 0}},
+ {{"_HE_", 0, 0}},
+ {{"_INT", 0, 0}},
+ {{"_LEN", 0, 0}},
+ {{"_LL_", 0, 0}},
+ {{"_MAF", 0, 0}},
+ {{"_MAX", 0, 0}},
+ {{"_MEM", 0, 0}},
+ {{"_MIF", 0, 0}},
+ {{"_MIN", 0, 0}},
+ {{"_MTP", 0, 0}},
+ {{"_RBO", 0, 0}},
+ {{"_RBW", 0, 0}},
+ {{"_RNG", 0, 0}},
+ {{"_RT_", 0, 0}}, /* Acpi 3.0 */
+ {{"_RW_", 0, 0}},
+ {{"_SHR", 0, 0}},
+ {{"_SIZ", 0, 0}},
+ {{"_TRA", 0, 0}},
+ {{"_TRS", 0, 0}},
+ {{"_TSF", 0, 0}}, /* Acpi 3.0 */
+ {{"_TTP", 0, 0}},
+ {{"_TYP", 0, 0}},
+ {{{0,0,0,0}, 0, 0}} /* Table terminator */
+};
+
+static const ACPI_PREDEFINED_INFO ScopeNames[] = {
+ {{"_SB_", 0, 0}},
+ {{"_SI_", 0, 0}},
+ {{"_TZ_", 0, 0}},
+ {{{0,0,0,0}, 0, 0}} /* Table terminator */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForPredefinedMethod
+ *
+ * PARAMETERS: Op - A parse node of type "METHOD".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If method is a predefined name, check that the number of
+ * arguments and the return type (returns a value or not)
+ * is correct.
+ *
+ ******************************************************************************/
+
+void
+ApCheckForPredefinedMethod (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ UINT32 Index;
+ UINT32 RequiredArgsCurrent;
+ UINT32 RequiredArgsOld;
+
+
+ /* Check for a match against the predefined name list */
+
+ Index = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
+
+ switch (Index)
+ {
+ case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
+ case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
+ case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
+
+ /* Just return, nothing to do */
+ break;
+
+
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx, _Exx, and _Qxx methods */
+
+ Gbl_ReservedMethods++;
+
+ /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
+
+ if (MethodInfo->NumArguments != 0)
+ {
+ sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName, 0);
+
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
+ MsgBuffer);
+ }
+ break;
+
+
+ default:
+ /*
+ * Matched a predefined method name
+ *
+ * Validate the ASL-defined argument count. Allow two different legal
+ * arg counts.
+ */
+ Gbl_ReservedMethods++;
+
+ RequiredArgsCurrent = PredefinedNames[Index].Info.ParamCount & 0x0F;
+ RequiredArgsOld = PredefinedNames[Index].Info.ParamCount >> 4;
+
+ if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
+ (MethodInfo->NumArguments != RequiredArgsOld))
+ {
+ sprintf (MsgBuffer, "%4.4s requires %d",
+ PredefinedNames[Index].Info.Name, RequiredArgsCurrent);
+
+ if (MethodInfo->NumArguments > RequiredArgsCurrent)
+ {
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
+ MsgBuffer);
+ }
+ else
+ {
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
+ MsgBuffer);
+ }
+ }
+
+ /*
+ * Check if method returns no value, but the predefined name is
+ * required to return a value
+ */
+ if (MethodInfo->NumReturnNoValue &&
+ PredefinedNames[Index].Info.ExpectedBtypes)
+ {
+ ApGetExpectedTypes (StringBuffer,
+ PredefinedNames[Index].Info.ExpectedBtypes);
+
+ sprintf (MsgBuffer, "%s required for %4.4s",
+ StringBuffer, PredefinedNames[Index].Info.Name);
+
+ AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
+ MsgBuffer);
+ }
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckPredefinedReturnValue
+ *
+ * PARAMETERS: Op - A parse node of type "RETURN".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If method is a predefined name, attempt to validate the return
+ * value. Only "static" types can be validated - a simple return
+ * of an integer/string/buffer/package or a named reference to
+ * a static object. Values such as a Localx or Argx or a control
+ * method invocation are not checked.
+ *
+ ******************************************************************************/
+
+void
+ApCheckPredefinedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ UINT32 Index;
+ ACPI_PARSE_OBJECT *ReturnValueOp;
+
+
+ /* Check parent method for a match against the predefined name list */
+
+ Index = ApCheckForPredefinedName (MethodInfo->Op,
+ MethodInfo->Op->Asl.NameSeg);
+
+ switch (Index)
+ {
+ case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
+ case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
+ case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx, _Exx, and _Qxx methods */
+
+ /* Just return, nothing to do */
+ return;
+
+ default: /* a real predefined ACPI name */
+
+ /* Exit if no return value expected */
+
+ if (!PredefinedNames[Index].Info.ExpectedBtypes)
+ {
+ return;
+ }
+
+ /* Get the object returned, it is the next argument */
+
+ ReturnValueOp = Op->Asl.Child;
+ switch (ReturnValueOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_ZERO:
+ case PARSEOP_ONE:
+ case PARSEOP_ONES:
+ case PARSEOP_INTEGER:
+ case PARSEOP_STRING_LITERAL:
+ case PARSEOP_BUFFER:
+ case PARSEOP_PACKAGE:
+
+ /* Static data return object - check against expected type */
+
+ ApCheckObjectType (ReturnValueOp,
+ PredefinedNames[Index].Info.ExpectedBtypes);
+ break;
+
+ default:
+
+ /*
+ * All other ops are very difficult or impossible to typecheck at
+ * compile time. These include all Localx, Argx, and method
+ * invocations. Also, NAMESEG and NAMESTRING because the type of
+ * any named object can be changed at runtime (for example,
+ * CopyObject will change the type of the target object.)
+ */
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForPredefinedObject
+ *
+ * PARAMETERS: Op - A parse node
+ * Name - The ACPI name to be checked
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for a predefined name for a static object (created via
+ * the ASL Name operator). If it is a predefined ACPI name, ensure
+ * that the name does not require any arguments (which would
+ * require a control method implemenation of the name), and that
+ * the type of the object is one of the expected types for the
+ * predefined name.
+ *
+ ******************************************************************************/
+
+void
+ApCheckForPredefinedObject (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+ UINT32 Index;
+
+
+ /*
+ * Check for a real predefined name -- not a resource descriptor name
+ * or a predefined scope name
+ */
+ Index = ApCheckForPredefinedName (Op, Name);
+ if (Index > ACPI_VALID_RESERVED_NAME_MAX)
+ {
+ return;
+ }
+
+ /*
+ * We found a matching predefind name.
+ * Check if this predefined name requires input arguments
+ */
+ if (PredefinedNames[Index].Info.ParamCount > 0)
+ {
+ /*
+ * This predefined name must always be defined as a control
+ * method because it is required to have input arguments.
+ */
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
+ "with arguments");
+ }
+
+ /* Typecheck the actual object, it is the next argument */
+
+ ApCheckObjectType (Op->Asl.Child->Asl.Next,
+ PredefinedNames[Index].Info.ExpectedBtypes);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForPredefinedName
+ *
+ * PARAMETERS: Op - A parse node
+ * Name - NameSeg to check
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check a NameSeg against the reserved list.
+ *
+ ******************************************************************************/
+
+UINT32
+ApCheckForPredefinedName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+ UINT32 i;
+
+
+ if (Name[0] == 0)
+ {
+ AcpiOsPrintf ("Found a null name, external = %s\n",
+ Op->Asl.ExternalName);
+ }
+
+ /* All reserved names are prefixed with a single underscore */
+
+ if (Name[0] != '_')
+ {
+ return (ACPI_NOT_RESERVED_NAME);
+ }
+
+ /* Check for a standard predefined method name */
+
+ for (i = 0; PredefinedNames[i].Info.Name[0]; i++)
+ {
+ if (ACPI_COMPARE_NAME (Name, PredefinedNames[i].Info.Name))
+ {
+ /* Return index into predefined array */
+ return (i);
+ }
+ }
+
+ /* Check for resource names and predefined scope names */
+
+ for (i = 0; ResourceNames[i].Info.Name[0]; i++)
+ {
+ if (ACPI_COMPARE_NAME (Name, ResourceNames[i].Info.Name))
+ {
+ return (ACPI_PREDEFINED_NAME);
+ }
+ }
+
+ for (i = 0; ScopeNames[i].Info.Name[0]; i++)
+ {
+ if (ACPI_COMPARE_NAME (Name, ScopeNames[i].Info.Name))
+ {
+ return (ACPI_PREDEFINED_NAME);
+ }
+ }
+
+ /* Check for _Lxx, _Exx, _Qxx, _T_x. Warning if unknown predefined name */
+
+ return (ApCheckForSpecialName (Op, Name));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckForSpecialName
+ *
+ * PARAMETERS: Op - A parse node
+ * Name - NameSeg to check
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check for the "special" predefined names -
+ * _Lxx, _Exx, _Qxx, and _T_x
+ *
+ ******************************************************************************/
+
+static UINT32
+ApCheckForSpecialName (
+ ACPI_PARSE_OBJECT *Op,
+ char *Name)
+{
+
+ /*
+ * Check for the "special" predefined names. We know the first char is an
+ * underscore already.
+ * GPE: _Lxx
+ * GPE: _Exx
+ * EC: _Qxx
+ */
+ if ((Name[1] == 'L') ||
+ (Name[1] == 'E') ||
+ (Name[1] == 'Q'))
+ {
+ /* The next two characters must be hex digits */
+
+ if ((isxdigit ((int) Name[2])) &&
+ (isxdigit ((int) Name[3])))
+ {
+ return (ACPI_EVENT_RESERVED_NAME);
+ }
+ }
+
+ /* Check for the names reserved for the compiler itself: _T_x */
+
+ else if ((Op->Asl.ExternalName[1] == 'T') &&
+ (Op->Asl.ExternalName[2] == '_'))
+ {
+ /* Ignore if actually emitted by the compiler */
+
+ if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
+ {
+ return (ACPI_NOT_RESERVED_NAME);
+ }
+
+ /*
+ * Was not actually emitted by the compiler. This is a special case,
+ * however. If the ASL code being compiled was the result of a
+ * dissasembly, it may possibly contain valid compiler-emitted names
+ * of the form "_T_x". We don't want to issue an error or even a
+ * warning and force the user to manually change the names. So, we
+ * will issue a remark instead.
+ */
+ AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
+ return (ACPI_COMPILER_RESERVED_NAME);
+ }
+
+ /*
+ * The name didn't match any of the known predefined names. Flag it as a
+ * warning, since the entire namespace starting with an underscore is
+ * reserved by the ACPI spec.
+ */
+ AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
+ Op->Asl.ExternalName);
+
+ return (ACPI_NOT_RESERVED_NAME);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApCheckObjectType
+ *
+ * PARAMETERS: Op - Current parse node
+ * ExpectedBtypes - Bitmap of expected return type(s)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check if the object type is one of the types that is expected
+ * by the predefined name. Only a limited number of object types
+ * can be returned by the predefined names.
+ *
+ ******************************************************************************/
+
+static void
+ApCheckObjectType (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 ExpectedBtypes)
+{
+ UINT32 ReturnBtype;
+
+
+ switch (Op->Asl.ParseOpcode)
+ {
+ case PARSEOP_ZERO:
+ case PARSEOP_ONE:
+ case PARSEOP_ONES:
+ case PARSEOP_INTEGER:
+ ReturnBtype = ACPI_RTYPE_INTEGER;
+ break;
+
+ case PARSEOP_BUFFER:
+ ReturnBtype = ACPI_RTYPE_BUFFER;
+ break;
+
+ case PARSEOP_STRING_LITERAL:
+ ReturnBtype = ACPI_RTYPE_STRING;
+ break;
+
+ case PARSEOP_PACKAGE:
+ ReturnBtype = ACPI_RTYPE_PACKAGE;
+ break;
+
+ default:
+ /* Not one of the supported object types */
+
+ goto TypeErrorExit;
+ }
+
+ /* Exit if the object is one of the expected types */
+
+ if (ReturnBtype & ExpectedBtypes)
+ {
+ return;
+ }
+
+
+TypeErrorExit:
+
+ /* Format the expected types and emit an error message */
+
+ ApGetExpectedTypes (StringBuffer, ExpectedBtypes);
+
+ sprintf (MsgBuffer, "found %s, requires %s",
+ UtGetOpName (Op->Asl.ParseOpcode), StringBuffer);
+
+ AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op,
+ MsgBuffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApDisplayReservedNames
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump information about the ACPI predefined names and predefined
+ * resource descriptor names.
+ *
+ ******************************************************************************/
+
+void
+ApDisplayReservedNames (
+ void)
+{
+ const ACPI_PREDEFINED_INFO *ThisName;
+ char TypeBuffer[48]; /* Room for 5 types */
+ UINT32 Count;
+
+
+ /*
+ * Predefined names/methods
+ */
+ printf ("\nPredefined Name Information\n\n");
+
+ Count = 0;
+ ThisName = PredefinedNames;
+ while (ThisName->Info.Name[0])
+ {
+ printf ("%4.4s Requires %d arguments, ",
+ ThisName->Info.Name, ThisName->Info.ParamCount & 0x0F);
+
+ if (ThisName->Info.ExpectedBtypes)
+ {
+ ApGetExpectedTypes (TypeBuffer, ThisName->Info.ExpectedBtypes);
+ printf ("Must return: %s\n", TypeBuffer);
+ }
+ else
+ {
+ printf ("No return value\n");
+ }
+
+ /*
+ * Skip next entry in the table if this name returns a Package
+ * (next entry contains the package info)
+ */
+ if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
+ {
+ ThisName++;
+ }
+
+ Count++;
+ ThisName++;
+ }
+
+ printf ("%u Predefined Names are recognized\n", Count);
+
+ /*
+ * Resource Descriptor names
+ */
+ printf ("\nResource Descriptor Predefined Names\n\n");
+
+ Count = 0;
+ ThisName = ResourceNames;
+ while (ThisName->Info.Name[0])
+ {
+ printf ("%4.4s Resource Descriptor\n", ThisName->Info.Name);
+ Count++;
+ ThisName++;
+ }
+
+ printf ("%u Resource Descriptor Names are recognized\n", Count);
+
+ /*
+ * Predefined scope names
+ */
+ printf ("\nPredefined Scope Names\n\n");
+
+ ThisName = ScopeNames;
+ while (ThisName->Info.Name[0])
+ {
+ printf ("%4.4s Scope\n", ThisName->Info.Name);
+ ThisName++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ApGetExpectedTypes
+ *
+ * PARAMETERS: Buffer - Where the formatted string is returned
+ * ExpectedBTypes - Bitfield of expected data types
+ *
+ * RETURN: None, formatted string
+ *
+ * DESCRIPTION: Format the expected object types into a printable string.
+ *
+ ******************************************************************************/
+
+static void
+ApGetExpectedTypes (
+ char *Buffer,
+ UINT32 ExpectedBtypes)
+{
+ UINT32 ThisRtype;
+ UINT32 i;
+ UINT32 j;
+
+
+ j = 1;
+ Buffer[0] = 0;
+ ThisRtype = ACPI_RTYPE_INTEGER;
+
+ for (i = 0; i < ACPI_NUM_RTYPES; i++)
+ {
+ /* If one of the expected types, concatenate the name of this type */
+
+ if (ExpectedBtypes & ThisRtype)
+ {
+ ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
+ j = 0; /* Use name separator from now on */
+ }
+ ThisRtype <<= 1; /* Next Rtype */
+ }
+}
+
diff --git a/sys/contrib/dev/acpica/compiler/aslstubs.c b/sys/contrib/dev/acpica/compiler/aslstubs.c
index ebc0a7d..b2fb69a 100644
--- a/sys/contrib/dev/acpica/compiler/aslstubs.c
+++ b/sys/contrib/dev/acpica/compiler/aslstubs.c
@@ -243,11 +243,13 @@ AcpiEvInitializeRegion (
return (AE_OK);
}
-ACPI_STATUS
-AcpiEvCheckForWakeOnlyGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo)
+void
+AcpiExDoDebugObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ UINT32 Level,
+ UINT32 Index)
{
- return (AE_OK);
+ return;
}
ACPI_STATUS
@@ -276,7 +278,6 @@ AcpiExLoadTableOp (
return (AE_SUPPORT);
}
-
ACPI_STATUS
AcpiExUnloadTable (
ACPI_OPERAND_OBJECT *DdbHandle)
diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h
index 9e1d426..30b8fdf 100644
--- a/sys/contrib/dev/acpica/compiler/asltypes.h
+++ b/sys/contrib/dev/acpica/compiler/asltypes.h
@@ -188,21 +188,6 @@ typedef struct asl_mapping_entry
} ASL_MAPPING_ENTRY;
-/* An entry in the Reserved Name information table */
-
-#define ASL_RSVD_RETURN_VALUE 0x01
-#define ASL_RSVD_RESOURCE_NAME 0x02
-#define ASL_RSVD_SCOPE 0x04
-
-typedef struct asl_reserved_info
-{
- char *Name;
- UINT8 NumArguments;
- UINT8 Flags;
-
-} ASL_RESERVED_INFO;
-
-
/* Parse tree walk info structure */
typedef struct asl_walk_info
@@ -522,7 +507,7 @@ char *AslMessages [] = {
/* ASL_MSG_RESERVED_ARG_COUNT_HI */ "Reserved method has too many arguments",
/* ASL_MSG_RESERVED_ARG_COUNT_LO */ "Reserved method has too few arguments",
/* ASL_MSG_RESERVED_METHOD */ "Reserved name must be a control method",
-/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid operand type for reserved name, must be",
+/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name",
/* ASL_MSG_RESERVED_RETURN_VALUE */ "Reserved method must return a value",
/* ASL_MSG_RESERVED_USE */ "Invalid use of reserved name",
/* ASL_MSG_RESERVED_WORD */ "Use of reserved name",
diff --git a/sys/contrib/dev/acpica/debugger/dbdisply.c b/sys/contrib/dev/acpica/debugger/dbdisply.c
index 179f6f6..4109489 100644
--- a/sys/contrib/dev/acpica/debugger/dbdisply.c
+++ b/sys/contrib/dev/acpica/debugger/dbdisply.c
@@ -848,13 +848,12 @@ AcpiDbDisplayGpes (
Block, GpeBlock, GpeBlock->Node, Buffer);
AcpiOsPrintf (" Registers: %u (%u GPEs)\n",
- GpeBlock->RegisterCount,
- ACPI_MUL_8 (GpeBlock->RegisterCount));
+ GpeBlock->RegisterCount, GpeBlock->GpeCount);
- AcpiOsPrintf (" GPE range: 0x%X to 0x%X\n",
+ AcpiOsPrintf (" GPE range: 0x%X to 0x%X on interrupt %u\n",
GpeBlock->BlockBaseNumber,
- GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8) -1);
+ GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1),
+ GpeXruptInfo->InterruptNumber);
AcpiOsPrintf (
" RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n",
@@ -871,9 +870,12 @@ AcpiDbDisplayGpes (
GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
AcpiOsPrintf (
- " Reg %u: WakeEnable %2.2X, RunEnable %2.2X Status %8.8X%8.8X Enable %8.8X%8.8X\n",
- i, GpeRegisterInfo->EnableForWake,
+ " Reg %u: (GPE %.2X-%.2X) RunEnable %2.2X WakeEnable %2.2X"
+ " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+ i, GpeRegisterInfo->BaseGpeNumber,
+ GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo->EnableForWake,
ACPI_FORMAT_UINT64 (GpeRegisterInfo->StatusAddress.Address),
ACPI_FORMAT_UINT64 (GpeRegisterInfo->EnableAddress.Address));
@@ -886,17 +888,19 @@ AcpiDbDisplayGpes (
if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
{
- /* This GPE is not used (no method or handler) */
+ /* This GPE is not used (no method or handler), ignore it */
continue;
}
AcpiOsPrintf (
- " GPE %.3X: %p Flags %2.2X: ",
- GpeBlock->BlockBaseNumber + GpeIndex,
- GpeEventInfo,
+ " GPE %.2X: %p RunRefs %2.2X WakeRefs %2.2X Flags %2.2X (",
+ GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
+ GpeEventInfo->RuntimeCount, GpeEventInfo->WakeupCount,
GpeEventInfo->Flags);
+ /* Decode the flags byte */
+
if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED)
{
AcpiOsPrintf ("Level, ");
@@ -906,38 +910,13 @@ AcpiDbDisplayGpes (
AcpiOsPrintf ("Edge, ");
}
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
- {
- case ACPI_GPE_TYPE_WAKE:
- AcpiOsPrintf ("WakeOnly: ");
- break;
- case ACPI_GPE_TYPE_RUNTIME:
- AcpiOsPrintf (" RunOnly: ");
- break;
- case ACPI_GPE_TYPE_WAKE_RUN:
- AcpiOsPrintf (" WakeRun: ");
- break;
- default:
- AcpiOsPrintf (" NotUsed: ");
- break;
- }
-
- if (GpeEventInfo->Flags & ACPI_GPE_WAKE_ENABLED)
- {
- AcpiOsPrintf ("[Wake 1 ");
- }
- else
- {
- AcpiOsPrintf ("[Wake 0 ");
- }
-
- if (GpeEventInfo->Flags & ACPI_GPE_RUN_ENABLED)
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
- AcpiOsPrintf ("Run 1], ");
+ AcpiOsPrintf ("CanWake, ");
}
else
{
- AcpiOsPrintf ("Run 0], ");
+ AcpiOsPrintf ("RunOnly, ");
}
switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
@@ -957,7 +936,7 @@ AcpiDbDisplayGpes (
break;
}
- AcpiOsPrintf ("\n");
+ AcpiOsPrintf (")\n");
}
}
Block++;
diff --git a/sys/contrib/dev/acpica/dispatcher/dsfield.c b/sys/contrib/dev/acpica/dispatcher/dsfield.c
index e33d6a8..d0240b0 100644
--- a/sys/contrib/dev/acpica/dispatcher/dsfield.c
+++ b/sys/contrib/dev/acpica/dispatcher/dsfield.c
@@ -424,7 +424,7 @@ AcpiDsGetFieldNames (
default:
ACPI_ERROR ((AE_INFO,
- "Invalid opcode in field list: %X", Arg->Common.AmlOpcode));
+ "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
return_ACPI_STATUS (AE_AML_BAD_OPCODE);
}
diff --git a/sys/contrib/dev/acpica/dispatcher/dsmethod.c b/sys/contrib/dev/acpica/dispatcher/dsmethod.c
index e54bb60..37cb867 100644
--- a/sys/contrib/dev/acpica/dispatcher/dsmethod.c
+++ b/sys/contrib/dev/acpica/dispatcher/dsmethod.c
@@ -318,7 +318,7 @@ AcpiDsBeginMethodExecution (
(WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
{
ACPI_ERROR ((AE_INFO,
- "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%d)",
+ "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
AcpiUtGetNodeName (MethodNode),
WalkState->Thread->CurrentSyncLevel));
diff --git a/sys/contrib/dev/acpica/dispatcher/dsmthdat.c b/sys/contrib/dev/acpica/dispatcher/dsmthdat.c
index 8d2342f..593695e 100644
--- a/sys/contrib/dev/acpica/dispatcher/dsmthdat.c
+++ b/sys/contrib/dev/acpica/dispatcher/dsmthdat.c
@@ -363,7 +363,7 @@ AcpiDsMethodDataGetNode (
if (Index > ACPI_METHOD_MAX_LOCAL)
{
ACPI_ERROR ((AE_INFO,
- "Local index %d is invalid (max %d)",
+ "Local index %u is invalid (max %u)",
Index, ACPI_METHOD_MAX_LOCAL));
return_ACPI_STATUS (AE_AML_INVALID_INDEX);
}
@@ -378,7 +378,7 @@ AcpiDsMethodDataGetNode (
if (Index > ACPI_METHOD_MAX_ARG)
{
ACPI_ERROR ((AE_INFO,
- "Arg index %d is invalid (max %d)",
+ "Arg index %u is invalid (max %u)",
Index, ACPI_METHOD_MAX_ARG));
return_ACPI_STATUS (AE_AML_INVALID_INDEX);
}
@@ -389,7 +389,7 @@ AcpiDsMethodDataGetNode (
break;
default:
- ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type));
+ ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
return_ACPI_STATUS (AE_TYPE);
}
@@ -540,7 +540,7 @@ AcpiDsMethodDataGetValue (
case ACPI_REFCLASS_ARG:
ACPI_ERROR ((AE_INFO,
- "Uninitialized Arg[%d] at node %p",
+ "Uninitialized Arg[%u] at node %p",
Index, Node));
return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
@@ -555,7 +555,7 @@ AcpiDsMethodDataGetValue (
default:
- ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type));
+ ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
}
diff --git a/sys/contrib/dev/acpica/dispatcher/dsobject.c b/sys/contrib/dev/acpica/dispatcher/dsobject.c
index 3e1c45e..9669ca9 100644
--- a/sys/contrib/dev/acpica/dispatcher/dsobject.c
+++ b/sys/contrib/dev/acpica/dispatcher/dsobject.c
@@ -365,7 +365,7 @@ AcpiDsBuildInternalBufferObj (
if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
{
ACPI_ERROR ((AE_INFO,
- "Expecting bytelist, got AML opcode %X in op %p",
+ "Expecting bytelist, found AML opcode 0x%X in op %p",
ByteList->Common.AmlOpcode, ByteList));
AcpiUtRemoveReference (ObjDesc);
@@ -599,7 +599,7 @@ AcpiDsBuildInternalPackageObj (
}
ACPI_INFO ((AE_INFO,
- "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n",
+ "Actual Package length (%u) is larger than NumElements field (%u), truncated\n",
i, ElementCount));
}
else if (i < ElementCount)
@@ -609,7 +609,7 @@ AcpiDsBuildInternalPackageObj (
* Note: this is not an error, the package is padded out with NULLs.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n",
+ "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
i, ElementCount));
}
@@ -804,7 +804,7 @@ AcpiDsInitObjectFromOp (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown constant opcode %X", Opcode));
+ "Unknown constant opcode 0x%X", Opcode));
Status = AE_AML_OPERAND_TYPE;
break;
}
@@ -821,7 +821,7 @@ AcpiDsInitObjectFromOp (
default:
- ACPI_ERROR ((AE_INFO, "Unknown Integer type %X",
+ ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
OpInfo->Type));
Status = AE_AML_OPERAND_TYPE;
break;
@@ -902,7 +902,7 @@ AcpiDsInitObjectFromOp (
default:
ACPI_ERROR ((AE_INFO,
- "Unimplemented reference type for AML opcode: %4.4X", Opcode));
+ "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
break;
@@ -912,7 +912,7 @@ AcpiDsInitObjectFromOp (
default:
- ACPI_ERROR ((AE_INFO, "Unimplemented data type: %X",
+ ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
ObjDesc->Common.Type));
Status = AE_AML_OPERAND_TYPE;
diff --git a/sys/contrib/dev/acpica/dispatcher/dsopcode.c b/sys/contrib/dev/acpica/dispatcher/dsopcode.c
index b1c6dc3..5c6004f 100644
--- a/sys/contrib/dev/acpica/dispatcher/dsopcode.c
+++ b/sys/contrib/dev/acpica/dispatcher/dsopcode.c
@@ -395,7 +395,7 @@ AcpiDsGetBufferArguments (
if (!Node)
{
ACPI_ERROR ((AE_INFO,
- "No pointer back to NS node in buffer obj %p", ObjDesc));
+ "No pointer back to namespace node in buffer object %p", ObjDesc));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -444,7 +444,7 @@ AcpiDsGetPackageArguments (
if (!Node)
{
ACPI_ERROR ((AE_INFO,
- "No pointer back to NS node in package %p", ObjDesc));
+ "No pointer back to namespace node in package %p", ObjDesc));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -678,7 +678,7 @@ AcpiDsInitBufferField (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown field creation opcode %02x",
+ "Unknown field creation opcode 0x%02X",
AmlOpcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
@@ -690,7 +690,7 @@ AcpiDsInitBufferField (
(8 * (UINT32) BufferDesc->Buffer.Length))
{
ACPI_ERROR ((AE_INFO,
- "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
+ "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
AcpiUtGetNodeName (ResultDesc),
BitOffset + BitCount,
AcpiUtGetNodeName (BufferDesc->Buffer.Node),
@@ -806,7 +806,7 @@ AcpiDsEvalBufferFieldOperands (
ACPI_WALK_OPERANDS, WalkState);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR ((AE_INFO, "(%s) bad operand(s) (%X)",
+ ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
return_ACPI_STATUS (Status);
@@ -1607,7 +1607,7 @@ AcpiDsExecEndControlOp (
default:
- ACPI_ERROR ((AE_INFO, "Unknown control opcode=%X Op=%p",
+ ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
Op->Common.AmlOpcode, Op));
Status = AE_AML_BAD_OPCODE;
diff --git a/sys/contrib/dev/acpica/dispatcher/dswexec.c b/sys/contrib/dev/acpica/dispatcher/dswexec.c
index cad6f51..61a7e1c 100644
--- a/sys/contrib/dev/acpica/dispatcher/dswexec.c
+++ b/sys/contrib/dev/acpica/dispatcher/dswexec.c
@@ -227,7 +227,7 @@ AcpiDsGetPredicateValue (
if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
{
ACPI_ERROR ((AE_INFO,
- "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
+ "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
ObjDesc, WalkState, ObjDesc->Common.Type));
Status = AE_AML_OPERAND_TYPE;
@@ -463,7 +463,7 @@ AcpiDsExecEndOp (
if (OpClass == AML_CLASS_UNKNOWN)
{
- ACPI_ERROR ((AE_INFO, "Unknown opcode %X", Op->Common.AmlOpcode));
+ ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
}
@@ -783,7 +783,7 @@ AcpiDsExecEndOp (
default:
ACPI_ERROR ((AE_INFO,
- "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p",
+ "Unimplemented opcode, class=0x%X type=0x%X Opcode=-0x%X Op=%p",
OpClass, OpType, Op->Common.AmlOpcode, Op));
Status = AE_NOT_IMPLEMENTED;
diff --git a/sys/contrib/dev/acpica/dispatcher/dswstate.c b/sys/contrib/dev/acpica/dispatcher/dswstate.c
index 19bb45b..622aef2 100644
--- a/sys/contrib/dev/acpica/dispatcher/dswstate.c
+++ b/sys/contrib/dev/acpica/dispatcher/dswstate.c
@@ -277,7 +277,7 @@ AcpiDsResultPush (
if (!Object)
{
ACPI_ERROR ((AE_INFO,
- "Null Object! Obj=%p State=%p Num=%X",
+ "Null Object! Obj=%p State=%p Num=%u",
Object, WalkState, WalkState->ResultCount));
return (AE_BAD_PARAMETER);
}
@@ -323,7 +323,7 @@ AcpiDsResultStackPush (
if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
ACPI_RESULTS_OBJ_NUM_MAX)
{
- ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%X",
+ ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
WalkState, WalkState->ResultSize));
return (AE_STACK_OVERFLOW);
}
@@ -426,7 +426,7 @@ AcpiDsObjStackPush (
if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
{
ACPI_ERROR ((AE_INFO,
- "Object stack overflow! Obj=%p State=%p #Ops=%X",
+ "Object stack overflow! Obj=%p State=%p #Ops=%u",
Object, WalkState, WalkState->NumOperands));
return (AE_STACK_OVERFLOW);
}
@@ -480,7 +480,7 @@ AcpiDsObjStackPop (
if (WalkState->NumOperands == 0)
{
ACPI_ERROR ((AE_INFO,
- "Object stack underflow! Count=%X State=%p #Ops=%X",
+ "Object stack underflow! Count=%X State=%p #Ops=%u",
PopCount, WalkState, WalkState->NumOperands));
return (AE_STACK_UNDERFLOW);
}
@@ -491,7 +491,7 @@ AcpiDsObjStackPop (
WalkState->Operands [WalkState->NumOperands] = NULL;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
PopCount, WalkState, WalkState->NumOperands));
return (AE_OK);
diff --git a/sys/contrib/dev/acpica/events/evevent.c b/sys/contrib/dev/acpica/events/evevent.c
index 2c41639..d743051 100644
--- a/sys/contrib/dev/acpica/events/evevent.c
+++ b/sys/contrib/dev/acpica/events/evevent.c
@@ -415,7 +415,7 @@ AcpiEvFixedEventDispatch (
ACPI_DISABLE_EVENT);
ACPI_ERROR ((AE_INFO,
- "No installed handler for fixed event [%08X]",
+ "No installed handler for fixed event [0x%08X]",
Event));
return (ACPI_INTERRUPT_NOT_HANDLED);
diff --git a/sys/contrib/dev/acpica/events/evgpe.c b/sys/contrib/dev/acpica/events/evgpe.c
index 4835568..0ece12c 100644
--- a/sys/contrib/dev/acpica/events/evgpe.c
+++ b/sys/contrib/dev/acpica/events/evgpe.c
@@ -134,71 +134,20 @@ AcpiEvAsynchEnableGpe (
/*******************************************************************************
*
- * FUNCTION: AcpiEvSetGpeType
- *
- * PARAMETERS: GpeEventInfo - GPE to set
- * Type - New type
- *
- * RETURN: Status
- *
- * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvSetGpeType (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- UINT8 Type)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (EvSetGpeType);
-
-
- /* Validate type and update register enable masks */
-
- switch (Type)
- {
- case ACPI_GPE_TYPE_WAKE:
- case ACPI_GPE_TYPE_RUNTIME:
- case ACPI_GPE_TYPE_WAKE_RUN:
- break;
-
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- /* Disable the GPE if currently enabled */
-
- Status = AcpiEvDisableGpe (GpeEventInfo);
-
- /* Clear the type bits and insert the new Type */
-
- GpeEventInfo->Flags &= ~ACPI_GPE_TYPE_MASK;
- GpeEventInfo->Flags |= Type;
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiEvUpdateGpeEnableMasks
*
* PARAMETERS: GpeEventInfo - GPE to update
- * Type - What to do: ACPI_GPE_DISABLE or
- * ACPI_GPE_ENABLE
*
* RETURN: Status
*
- * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ * DESCRIPTION: Updates GPE register enable masks based upon whether there are
+ * references (either wake or run) to this GPE
*
******************************************************************************/
ACPI_STATUS
AcpiEvUpdateGpeEnableMasks (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- UINT8 Type)
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
UINT8 RegisterBit;
@@ -216,36 +165,21 @@ AcpiEvUpdateGpeEnableMasks (
RegisterBit = (UINT8)
(1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
- /* 1) Disable case. Simply clear all enable bits */
+ /* Clear the wake/run bits up front */
- if (Type == ACPI_GPE_DISABLE)
- {
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- return_ACPI_STATUS (AE_OK);
- }
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- /* 2) Enable case. Set/Clear the appropriate enable bits */
+ /* Set the mask bits only if there are references to this GPE */
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+ if (GpeEventInfo->RuntimeCount)
{
- case ACPI_GPE_TYPE_WAKE:
- ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- break;
-
- case ACPI_GPE_TYPE_RUNTIME:
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- break;
-
- case ACPI_GPE_TYPE_WAKE_RUN:
- ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- break;
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
+ }
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (GpeEventInfo->WakeupCount)
+ {
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
}
return_ACPI_STATUS (AE_OK);
@@ -257,19 +191,19 @@ AcpiEvUpdateGpeEnableMasks (
* FUNCTION: AcpiEvEnableGpe
*
* PARAMETERS: GpeEventInfo - GPE to enable
- * WriteToHardware - Enable now, or just mark data structs
- * (WAKE GPEs should be deferred)
*
* RETURN: Status
*
- * DESCRIPTION: Enable a GPE based on the GPE type
+ * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
+ * of type or number of references.
+ *
+ * Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
ACPI_STATUS
AcpiEvEnableGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- BOOLEAN WriteToHardware)
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_STATUS Status;
@@ -277,54 +211,37 @@ AcpiEvEnableGpe (
ACPI_FUNCTION_TRACE (EvEnableGpe);
- /* Make sure HW enable masks are updated */
+ /*
+ * We will only allow a GPE to be enabled if it has either an
+ * associated method (_Lxx/_Exx) or a handler. Otherwise, the
+ * GPE will be immediately disabled by AcpiEvGpeDispatch the
+ * first time it fires.
+ */
+ if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
+ {
+ return_ACPI_STATUS (AE_NO_HANDLER);
+ }
+
+ /* Ensure the HW enable masks are current */
- Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE);
+ Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- /* Mark wake-enabled or HW enable, or both */
+ /* Clear the GPE (of stale events) */
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+ Status = AcpiHwClearGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
{
- case ACPI_GPE_TYPE_WAKE:
-
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
- break;
-
- case ACPI_GPE_TYPE_WAKE_RUN:
-
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-
- /*lint -fallthrough */
-
- case ACPI_GPE_TYPE_RUNTIME:
-
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
-
- if (WriteToHardware)
- {
- /* Clear the GPE (of stale events), then enable it */
-
- Status = AcpiHwClearGpe (GpeEventInfo);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- /* Enable the requested runtime GPE */
-
- Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
- }
- break;
-
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS (Status);
}
- return_ACPI_STATUS (AE_OK);
+ /* Enable the requested GPE */
+
+ Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
+ return_ACPI_STATUS (Status);
}
@@ -336,7 +253,10 @@ AcpiEvEnableGpe (
*
* RETURN: Status
*
- * DESCRIPTION: Disable a GPE based on the GPE type
+ * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
+ * regardless of the type or number of references.
+ *
+ * Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
@@ -356,40 +276,14 @@ AcpiEvDisableGpe (
* the GPE behind our back.
*/
- /* Make sure HW enable masks are updated */
+ /* Ensure the HW enable masks are current */
- Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
+ Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- /* Clear the appropriate enabled flags for this GPE */
-
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
- {
- case ACPI_GPE_TYPE_WAKE:
-
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
- break;
-
- case ACPI_GPE_TYPE_WAKE_RUN:
-
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-
- /*lint -fallthrough */
-
- case ACPI_GPE_TYPE_RUNTIME:
-
- /* Disable the requested runtime GPE */
-
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
- break;
-
- default:
- break;
- }
-
/*
* Always H/W disable this GPE, even if we don't know the GPE type.
* Simply clear the enable bit for this particular GPE, but do not
@@ -405,6 +299,49 @@ AcpiEvDisableGpe (
/*******************************************************************************
*
+ * FUNCTION: AcpiEvLowGetGpeInfo
+ *
+ * PARAMETERS: GpeNumber - Raw GPE number
+ * GpeBlock - A GPE info block
+ *
+ * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
+ * is not within the specified GPE block)
+ *
+ * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
+ * the low-level implementation of EvGetGpeEventInfo.
+ *
+ ******************************************************************************/
+
+ACPI_GPE_EVENT_INFO *
+AcpiEvLowGetGpeInfo (
+ UINT32 GpeNumber,
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ UINT32 GpeIndex;
+
+
+ /*
+ * Validate that the GpeNumber is within the specified GpeBlock.
+ * (Two steps)
+ */
+ if (!GpeBlock ||
+ (GpeNumber < GpeBlock->BlockBaseNumber))
+ {
+ return (NULL);
+ }
+
+ GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
+ if (GpeIndex >= GpeBlock->GpeCount)
+ {
+ return (NULL);
+ }
+
+ return (&GpeBlock->EventInfo[GpeIndex]);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiEvGetGpeEventInfo
*
* PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
@@ -426,7 +363,7 @@ AcpiEvGetGpeEventInfo (
UINT32 GpeNumber)
{
ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_EVENT_INFO *GpeInfo;
UINT32 i;
@@ -441,16 +378,11 @@ AcpiEvGetGpeEventInfo (
for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
{
- GpeBlock = AcpiGbl_GpeFadtBlocks[i];
- if (GpeBlock)
+ GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
+ AcpiGbl_GpeFadtBlocks[i]);
+ if (GpeInfo)
{
- if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
- (GpeNumber < GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8)))
- {
- return (&GpeBlock->EventInfo[GpeNumber -
- GpeBlock->BlockBaseNumber]);
- }
+ return (GpeInfo);
}
}
@@ -468,15 +400,7 @@ AcpiEvGetGpeEventInfo (
return (NULL);
}
- GpeBlock = ObjDesc->Device.GpeBlock;
-
- if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
- (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))
- {
- return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]);
- }
-
- return (NULL);
+ return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
}
@@ -654,9 +578,9 @@ AcpiEvAsynchExecuteGpeMethod (
return_VOID;
}
- /* Set the GPE flags for return to enabled state */
+ /* Update the GPE register masks for return to enabled state */
- (void) AcpiEvEnableGpe (GpeEventInfo, FALSE);
+ (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
/*
* Take a snapshot of the GPE info for this level - we copy the info to
@@ -803,7 +727,7 @@ AcpiEvGpeDispatch (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to clear GPE[%2X]", GpeNumber));
+ "Unable to clear GPE[0x%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
}
@@ -836,7 +760,7 @@ AcpiEvGpeDispatch (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to clear GPE[%2X]", GpeNumber));
+ "Unable to clear GPE[0x%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
}
@@ -852,7 +776,7 @@ AcpiEvGpeDispatch (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to disable GPE[%2X]", GpeNumber));
+ "Unable to disable GPE[0x%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
@@ -865,28 +789,31 @@ AcpiEvGpeDispatch (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to queue handler for GPE[%2X] - event disabled",
+ "Unable to queue handler for GPE[0x%2X] - event disabled",
GpeNumber));
}
break;
default:
- /* No handler or method to run! */
-
+ /*
+ * No handler or method to run!
+ * 03/2010: This case should no longer be possible. We will not allow
+ * a GPE to be enabled if it has no handler or method.
+ */
ACPI_ERROR ((AE_INFO,
- "No handler or method for GPE[%2X], disabling event",
+ "No handler or method for GPE[0x%2X], disabling event",
GpeNumber));
/*
- * Disable the GPE. The GPE will remain disabled until the ACPICA
- * Core Subsystem is restarted, or a handler is installed.
+ * Disable the GPE. The GPE will remain disabled a handler
+ * is installed or ACPICA is restarted.
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to disable GPE[%2X]", GpeNumber));
+ "Unable to disable GPE[0x%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
break;
diff --git a/sys/contrib/dev/acpica/events/evgpeblk.c b/sys/contrib/dev/acpica/events/evgpeblk.c
index fe55162..29b0e71 100644
--- a/sys/contrib/dev/acpica/events/evgpeblk.c
+++ b/sys/contrib/dev/acpica/events/evgpeblk.c
@@ -124,7 +124,7 @@
/* Local prototypes */
static ACPI_STATUS
-AcpiEvSaveMethodInfo (
+AcpiEvMatchGpeMethod (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *ObjDesc,
@@ -194,8 +194,7 @@ AcpiEvValidGpeEvent (
while (GpeBlock)
{
if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
- (&GpeBlock->EventInfo[((ACPI_SIZE)
- GpeBlock->RegisterCount) * 8] > GpeEventInfo))
+ (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo))
{
return (TRUE);
}
@@ -328,7 +327,7 @@ AcpiEvDeleteGpeHandlers (
/*******************************************************************************
*
- * FUNCTION: AcpiEvSaveMethodInfo
+ * FUNCTION: AcpiEvMatchGpeMethod
*
* PARAMETERS: Callback from WalkNamespace
*
@@ -340,8 +339,7 @@ AcpiEvDeleteGpeHandlers (
* information for quick lookup during GPE dispatch
*
* The name of each GPE control method is of the form:
- * "_Lxx" or "_Exx"
- * Where:
+ * "_Lxx" or "_Exx", where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* xx - is the GPE number [in HEX]
@@ -349,38 +347,44 @@ AcpiEvDeleteGpeHandlers (
******************************************************************************/
static ACPI_STATUS
-AcpiEvSaveMethodInfo (
+AcpiEvMatchGpeMethod (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *ObjDesc,
void **ReturnValue)
{
+ ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
UINT32 GpeNumber;
char Name[ACPI_NAME_SIZE + 1];
UINT8 Type;
- ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (EvSaveMethodInfo);
+ ACPI_FUNCTION_TRACE (EvMatchGpeMethod);
/*
- * _Lxx and _Exx GPE method support
+ * Match and decode the _Lxx and _Exx GPE method names
*
- * 1) Extract the name from the object and convert to a string
+ * 1) Extract the method name and null terminate it
*/
- ACPI_MOVE_32_TO_32 (
- Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
+ ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer);
Name[ACPI_NAME_SIZE] = 0;
+ /* 2) Name must begin with an underscore */
+
+ if (Name[0] != '_')
+ {
+ return_ACPI_STATUS (AE_OK); /* Ignore this method */
+ }
+
/*
- * 2) Edge/Level determination is based on the 2nd character
+ * 3) Edge/Level determination is based on the 2nd character
* of the method name
*
- * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
- * if a _PRW object is found that points to this GPE.
+ * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
+ * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
*/
switch (Name[1])
{
@@ -393,16 +397,15 @@ AcpiEvSaveMethodInfo (
break;
default:
- /* Unknown method type, just ignore it! */
+ /* Unknown method type, just ignore it */
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Ignoring unknown GPE method type: %s "
- "(name not of form _Lxx or _Exx)",
- Name));
+ "(name not of form _Lxx or _Exx)", Name));
return_ACPI_STATUS (AE_OK);
}
- /* Convert the last two characters of the name to the GPE Number */
+ /* 4) The last two characters of the name are the hex GPE Number */
GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
if (GpeNumber == ACPI_UINT32_MAX)
@@ -411,45 +414,34 @@ AcpiEvSaveMethodInfo (
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Could not extract GPE number from name: %s "
- "(name is not of form _Lxx or _Exx)",
- Name));
+ "(name is not of form _Lxx or _Exx)", Name));
return_ACPI_STATUS (AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
- if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
- (GpeNumber >= (GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8))))
+ GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
+ if (!GpeEventInfo)
{
/*
- * Not valid for this GPE block, just ignore it. However, it may be
- * valid for a different GPE block, since GPE0 and GPE1 methods both
- * appear under \_GPE.
+ * This GpeNumber is not valid for this GPE block, just ignore it.
+ * However, it may be valid for a different GPE block, since GPE0
+ * and GPE1 methods both appear under \_GPE.
*/
return_ACPI_STATUS (AE_OK);
}
/*
- * Now we can add this information to the GpeEventInfo block for use
- * during dispatch of this GPE. Default type is RUNTIME, although this may
- * change when the _PRW methods are executed later.
+ * Add the GPE information from above to the GpeEventInfo block for
+ * use during dispatch of this GPE.
*/
- GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
-
- GpeEventInfo->Flags = (UINT8)
- (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
-
- GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;
-
- /* Update enable mask, but don't enable the HW GPE as of yet */
-
- Status = AcpiEvEnableGpe (GpeEventInfo, FALSE);
+ GpeEventInfo->Flags = (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD);
+ GpeEventInfo->Dispatch.MethodNode = MethodNode;
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n",
Name, GpeNumber));
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_OK);
}
@@ -464,7 +456,7 @@ AcpiEvSaveMethodInfo (
*
* DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
* Device. Run the _PRW method. If present, extract the GPE
- * number and mark the GPE as a WAKE GPE.
+ * number and mark the GPE as a CAN_WAKE GPE.
*
******************************************************************************/
@@ -495,7 +487,7 @@ AcpiEvMatchPrwAndGpe (
ACPI_BTYPE_PACKAGE, &PkgDesc);
if (ACPI_FAILURE (Status))
{
- /* Ignore all errors from _PRW, we don't want to abort the subsystem */
+ /* Ignore all errors from _PRW, we don't want to abort the walk */
return_ACPI_STATUS (AE_OK);
}
@@ -561,25 +553,17 @@ AcpiEvMatchPrwAndGpe (
* 2) The GPE index(number) is within the range of the Gpe Block
* associated with the GPE device.
*/
- if ((GpeDevice == TargetGpeDevice) &&
- (GpeNumber >= GpeBlock->BlockBaseNumber) &&
- (GpeNumber < GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8)))
+ if (GpeDevice != TargetGpeDevice)
{
- GpeEventInfo = &GpeBlock->EventInfo[GpeNumber -
- GpeBlock->BlockBaseNumber];
-
- /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
-
- GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+ goto Cleanup;
+ }
- Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
+ GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
+ if (GpeEventInfo)
+ {
+ /* This GPE can wake the system */
- Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
+ GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
}
Cleanup:
@@ -880,7 +864,7 @@ AcpiEvDeleteGpeBlock (
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
}
- AcpiCurrentGpeCount -= GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH;
+ AcpiCurrentGpeCount -= GpeBlock->GpeCount;
/* Free the GpeBlock */
@@ -925,8 +909,8 @@ AcpiEvCreateGpeInfoBlocks (
/* Allocate the GPE register information block */
GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
- (ACPI_SIZE) GpeBlock->RegisterCount *
- sizeof (ACPI_GPE_REGISTER_INFO));
+ (ACPI_SIZE) GpeBlock->RegisterCount *
+ sizeof (ACPI_GPE_REGISTER_INFO));
if (!GpeRegisterInfo)
{
ACPI_ERROR ((AE_INFO,
@@ -938,10 +922,8 @@ AcpiEvCreateGpeInfoBlocks (
* Allocate the GPE EventInfo block. There are eight distinct GPEs
* per register. Initialization to zeros is sufficient.
*/
- GpeEventInfo = ACPI_ALLOCATE_ZEROED (
- ((ACPI_SIZE) GpeBlock->RegisterCount *
- ACPI_GPE_REGISTER_WIDTH) *
- sizeof (ACPI_GPE_EVENT_INFO));
+ GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
+ sizeof (ACPI_GPE_EVENT_INFO));
if (!GpeEventInfo)
{
ACPI_ERROR ((AE_INFO,
@@ -1080,6 +1062,7 @@ AcpiEvCreateGpeBlock (
/* Initialize the new GPE block */
GpeBlock->Node = GpeDevice;
+ GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
GpeBlock->RegisterCount = RegisterCount;
GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
@@ -1110,7 +1093,7 @@ AcpiEvCreateGpeBlock (
Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
- AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL);
+ AcpiEvMatchGpeMethod, NULL, GpeBlock, NULL);
/* Return the new block */
@@ -1122,15 +1105,13 @@ AcpiEvCreateGpeBlock (
ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
"GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
(UINT32) GpeBlock->BlockBaseNumber,
- (UINT32) (GpeBlock->BlockBaseNumber +
- ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
- GpeDevice->Name.Ascii,
- GpeBlock->RegisterCount,
+ (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
+ GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
InterruptNumber));
/* Update global count of currently available GPEs */
- AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH;
+ AcpiCurrentGpeCount += GpeBlock->GpeCount;
return_ACPI_STATUS (AE_OK);
}
@@ -1161,6 +1142,8 @@ AcpiEvInitializeGpeBlock (
ACPI_GPE_WALK_INFO GpeInfo;
UINT32 WakeGpeCount;
UINT32 GpeEnabledCount;
+ UINT32 GpeIndex;
+ UINT32 GpeNumber;
UINT32 i;
UINT32 j;
@@ -1193,39 +1176,65 @@ AcpiEvInitializeGpeBlock (
Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods"));
+ }
}
/*
- * Enable all GPEs in this block that have these attributes:
- * 1) are "runtime" or "run/wake" GPEs, and
- * 2) have a corresponding _Lxx or _Exx method
- *
- * Any other GPEs within this block must be enabled via the
- * AcpiEnableGpe() external interface.
+ * Enable all GPEs that have a corresponding method and are not
+ * capable of generating wakeups. Any other GPEs within this block
+ * must be enabled via the AcpiEnableGpe interface.
*/
WakeGpeCount = 0;
GpeEnabledCount = 0;
+ if (GpeDevice == AcpiGbl_FadtGpeDevice)
+ {
+ GpeDevice = NULL;
+ }
+
for (i = 0; i < GpeBlock->RegisterCount; i++)
{
- for (j = 0; j < 8; j++)
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
{
/* Get the info block for this particular GPE */
- GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
+ GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
+
+ /* Ignore GPEs that can wake the system */
- if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD) &&
- (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
- GpeEnabledCount++;
+ WakeGpeCount++;
+ if (AcpiGbl_LeaveWakeGpesDisabled)
+ {
+ continue;
+ }
}
- if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
+ /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
+
+ if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
{
- WakeGpeCount++;
+ continue;
+ }
+
+ /* Enable this GPE */
+
+ GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber;
+ Status = AcpiEnableGpe (GpeDevice, GpeNumber,
+ ACPI_GPE_TYPE_RUNTIME);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Could not enable GPE 0x%02X", GpeNumber));
+ continue;
}
+
+ GpeEnabledCount++;
}
}
@@ -1233,16 +1242,7 @@ AcpiEvInitializeGpeBlock (
"Found %u Wake, Enabled %u Runtime GPEs in this block\n",
WakeGpeCount, GpeEnabledCount));
- /* Enable all valid runtime GPEs found above */
-
- Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL);
- if (ACPI_FAILURE (Status))
- {
- ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",
- GpeBlock));
- }
-
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_OK);
}
@@ -1337,8 +1337,8 @@ AcpiEvGpeInitialize (
(GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))
{
ACPI_ERROR ((AE_INFO,
- "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
- "(GPE %d to %d) - Ignoring GPE1",
+ "GPE0 block (GPE 0 to %u) overlaps the GPE1 block "
+ "(GPE %u to %u) - Ignoring GPE1",
GpeNumberMax, AcpiGbl_FADT.Gpe1Base,
AcpiGbl_FADT.Gpe1Base +
((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
diff --git a/sys/contrib/dev/acpica/events/evmisc.c b/sys/contrib/dev/acpica/events/evmisc.c
index 1ee7f9d..eff26cb 100644
--- a/sys/contrib/dev/acpica/events/evmisc.c
+++ b/sys/contrib/dev/acpica/events/evmisc.c
@@ -696,7 +696,7 @@ AcpiEvTerminate (
if (ACPI_FAILURE (Status))
{
ACPI_ERROR ((AE_INFO,
- "Could not disable fixed event %d", (UINT32) i));
+ "Could not disable fixed event %u", (UINT32) i));
}
}
diff --git a/sys/contrib/dev/acpica/events/evxface.c b/sys/contrib/dev/acpica/events/evxface.c
index abffad6..3067fa8 100644
--- a/sys/contrib/dev/acpica/events/evxface.c
+++ b/sys/contrib/dev/acpica/events/evxface.c
@@ -232,7 +232,7 @@ AcpiInstallFixedEventHandler (
Status = AcpiEnableEvent (Event, 0);
if (ACPI_FAILURE (Status))
{
- ACPI_WARNING ((AE_INFO, "Could not enable fixed event %X", Event));
+ ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event));
/* Remove the handler */
@@ -303,7 +303,7 @@ AcpiRemoveFixedEventHandler (
if (ACPI_FAILURE (Status))
{
ACPI_WARNING ((AE_INFO,
- "Could not write to fixed event enable register %X", Event));
+ "Could not write to fixed event enable register 0x%X", Event));
}
else
{
@@ -705,7 +705,7 @@ AcpiInstallGpeHandler (
/* Parameter validation */
- if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK))
+ if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
diff --git a/sys/contrib/dev/acpica/events/evxfevnt.c b/sys/contrib/dev/acpica/events/evxfevnt.c
index 92b6d4d..333e0e5 100644
--- a/sys/contrib/dev/acpica/events/evxfevnt.c
+++ b/sys/contrib/dev/acpica/events/evxfevnt.c
@@ -307,30 +307,43 @@ ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
/*******************************************************************************
*
- * FUNCTION: AcpiSetGpeType
+ * FUNCTION: AcpiEnableGpe
*
- * PARAMETERS: GpeDevice - Parent GPE Device
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
- * Type - New GPE type
+ * GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
+ * or both
*
* RETURN: Status
*
- * DESCRIPTION: Set the type of an individual GPE
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled (for runtime GPEs), or the GPE register mask
+ * is updated (for wake GPEs).
*
******************************************************************************/
ACPI_STATUS
-AcpiSetGpeType (
+AcpiEnableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT8 Type)
+ UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableGpe);
+
+ /* Parameter validation */
- ACPI_FUNCTION_TRACE (AcpiSetGpeType);
+ if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@@ -341,61 +354,101 @@ AcpiSetGpeType (
goto UnlockAndExit;
}
- if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type)
+ if (GpeType & ACPI_GPE_TYPE_RUNTIME)
{
- return_ACPI_STATUS (AE_OK);
+ if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
+ {
+ Status = AE_LIMIT; /* Too many references */
+ goto UnlockAndExit;
+ }
+
+ GpeEventInfo->RuntimeCount++;
+ if (GpeEventInfo->RuntimeCount == 1)
+ {
+ Status = AcpiEvEnableGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount--;
+ goto UnlockAndExit;
+ }
+ }
}
- /* Set the new type (will disable GPE if currently enabled) */
+ if (GpeType & ACPI_GPE_TYPE_WAKE)
+ {
+ /* The GPE must have the ability to wake the system */
- Status = AcpiEvSetGpeType (GpeEventInfo, Type);
+ if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
+ {
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
+
+ if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX)
+ {
+ Status = AE_LIMIT; /* Too many references */
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Update the enable mask on the first wakeup reference. Wake GPEs
+ * are only hardware-enabled just before sleeping.
+ */
+ GpeEventInfo->WakeupCount++;
+ if (GpeEventInfo->WakeupCount == 1)
+ {
+ (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
+ }
+ }
UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
-ACPI_EXPORT_SYMBOL (AcpiSetGpeType)
+ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
/*******************************************************************************
*
- * FUNCTION: AcpiEnableGpe
+ * FUNCTION: AcpiDisableGpe
*
- * PARAMETERS: GpeDevice - Parent GPE Device
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
- * Flags - Just enable, or also wake enable?
- * Called from ISR or not
+ * GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
+ * or both
*
* RETURN: Status
*
- * DESCRIPTION: Enable an ACPI event (general purpose)
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ * removed, only then is the GPE disabled (for runtime GPEs), or
+ * the GPE mask bit disabled (for wake GPEs)
*
******************************************************************************/
ACPI_STATUS
-AcpiEnableGpe (
+AcpiDisableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags)
+ UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
- ACPI_FUNCTION_TRACE (AcpiEnableGpe);
+ ACPI_FUNCTION_TRACE (AcpiDisableGpe);
- /* Use semaphore lock if not executing at interrupt level */
+ /* Parameter validation */
- if (Flags & ACPI_NOT_ISR)
+ if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
{
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
@@ -405,59 +458,92 @@ AcpiEnableGpe (
goto UnlockAndExit;
}
- /* Perform the enable */
+ /* Hardware-disable a runtime GPE on removal of the last reference */
+
+ if (GpeType & ACPI_GPE_TYPE_RUNTIME)
+ {
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ Status = AE_LIMIT; /* There are no references to remove */
+ goto UnlockAndExit;
+ }
- Status = AcpiEvEnableGpe (GpeEventInfo, TRUE);
+ GpeEventInfo->RuntimeCount--;
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ Status = AcpiEvDisableGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount++;
+ goto UnlockAndExit;
+ }
+ }
+ }
-UnlockAndExit:
- if (Flags & ACPI_NOT_ISR)
+ /*
+ * Update masks for wake GPE on removal of the last reference.
+ * No need to hardware-disable wake GPEs here, they are not currently
+ * enabled.
+ */
+ if (GpeType & ACPI_GPE_TYPE_WAKE)
{
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ if (!GpeEventInfo->WakeupCount)
+ {
+ Status = AE_LIMIT; /* There are no references to remove */
+ goto UnlockAndExit;
+ }
+
+ GpeEventInfo->WakeupCount--;
+ if (!GpeEventInfo->WakeupCount)
+ {
+ (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
+ }
}
+
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
-ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
+ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
/*******************************************************************************
*
- * FUNCTION: AcpiDisableGpe
+ * FUNCTION: AcpiSetGpe
*
- * PARAMETERS: GpeDevice - Parent GPE Device
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
- * Flags - Just disable, or also wake disable?
- * Called from ISR or not
+ * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
*
* RETURN: Status
*
- * DESCRIPTION: Disable an ACPI event (general purpose)
+ * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
+ * the reference count mechanism used in the AcpiEnableGpe and
+ * AcpiDisableGpe interfaces -- and should be used with care.
+ *
+ * Note: Typically used to disable a runtime GPE for short period of time,
+ * then re-enable it, without disturbing the existing reference counts. This
+ * is useful, for example, in the Embedded Controller (EC) driver.
*
******************************************************************************/
ACPI_STATUS
-AcpiDisableGpe (
+AcpiSetGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags)
+ UINT8 Action)
{
- ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
- ACPI_FUNCTION_TRACE (AcpiDisableGpe);
-
+ ACPI_FUNCTION_TRACE (AcpiSetGpe);
- /* Use semaphore lock if not executing at interrupt level */
- if (Flags & ACPI_NOT_ISR)
- {
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- }
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@@ -468,17 +554,29 @@ AcpiDisableGpe (
goto UnlockAndExit;
}
- Status = AcpiEvDisableGpe (GpeEventInfo);
+ /* Perform the action */
-UnlockAndExit:
- if (Flags & ACPI_NOT_ISR)
+ switch (Action)
{
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ case ACPI_GPE_ENABLE:
+ Status = AcpiEvEnableGpe (GpeEventInfo);
+ break;
+
+ case ACPI_GPE_DISABLE:
+ Status = AcpiEvDisableGpe (GpeEventInfo);
+ break;
+
+ default:
+ Status = AE_BAD_PARAMETER;
+ break;
}
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
-ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
+ACPI_EXPORT_SYMBOL (AcpiSetGpe)
/*******************************************************************************
@@ -592,9 +690,8 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
*
* FUNCTION: AcpiClearGpe
*
- * PARAMETERS: GpeDevice - Parent GPE Device
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
- * Flags - Called from an ISR or not
*
* RETURN: Status
*
@@ -605,26 +702,17 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
ACPI_STATUS
AcpiClearGpe (
ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- UINT32 Flags)
+ UINT32 GpeNumber)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiClearGpe);
- /* Use semaphore lock if not executing at interrupt level */
-
- if (Flags & ACPI_NOT_ISR)
- {
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- }
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@@ -638,10 +726,7 @@ AcpiClearGpe (
Status = AcpiHwClearGpe (GpeEventInfo);
UnlockAndExit:
- if (Flags & ACPI_NOT_ISR)
- {
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
- }
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
@@ -700,9 +785,8 @@ ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
*
* FUNCTION: AcpiGetGpeStatus
*
- * PARAMETERS: GpeDevice - Parent GPE Device
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
- * Flags - Called from an ISR or not
* EventStatus - Where the current status of the event will
* be returned
*
@@ -716,26 +800,17 @@ ACPI_STATUS
AcpiGetGpeStatus (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags,
ACPI_EVENT_STATUS *EventStatus)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
- /* Use semaphore lock if not executing at interrupt level */
-
- if (Flags & ACPI_NOT_ISR)
- {
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- }
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@@ -751,10 +826,7 @@ AcpiGetGpeStatus (
Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
UnlockAndExit:
- if (Flags & ACPI_NOT_ISR)
- {
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
- }
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
@@ -823,21 +895,15 @@ AcpiInstallGpeBlock (
goto UnlockAndExit;
}
- /* Run the _PRW methods and enable the GPEs */
-
- Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
-
- /* Get the DeviceObject attached to the node */
+ /* Install block in the DeviceObject attached to the node */
ObjDesc = AcpiNsGetAttachedObject (Node);
if (!ObjDesc)
{
- /* No object, create a new one */
-
+ /*
+ * No object, create a new one (Device nodes do not always have
+ * an attached object)
+ */
ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
if (!ObjDesc)
{
@@ -850,17 +916,20 @@ AcpiInstallGpeBlock (
/* Remove local reference to the object */
AcpiUtRemoveReference (ObjDesc);
-
if (ACPI_FAILURE (Status))
{
goto UnlockAndExit;
}
}
- /* Install the GPE block in the DeviceObject */
+ /* Now install the GPE block in the DeviceObject */
ObjDesc->Device.GpeBlock = GpeBlock;
+ /* Run the _PRW methods and enable the runtime GPEs in the new block */
+
+ Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
+
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
@@ -1018,8 +1087,7 @@ AcpiEvGetGpeDevice (
/* Increment Index by the number of GPEs in this block */
- Info->NextBlockBaseIndex +=
- (GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH);
+ Info->NextBlockBaseIndex += GpeBlock->GpeCount;
if (Info->Index < Info->NextBlockBaseIndex)
{
diff --git a/sys/contrib/dev/acpica/executer/exconvrt.c b/sys/contrib/dev/acpica/executer/exconvrt.c
index a67122c..c8e66a6 100644
--- a/sys/contrib/dev/acpica/executer/exconvrt.c
+++ b/sys/contrib/dev/acpica/executer/exconvrt.c
@@ -786,7 +786,7 @@ AcpiExConvertToTargetType (
default:
- ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: %X",
+ ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: 0x%X",
DestinationType));
Status = AE_AML_INTERNAL;
break;
@@ -803,7 +803,7 @@ AcpiExConvertToTargetType (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown Target type ID 0x%X AmlOpcode %X DestType %s",
+ "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
Status = AE_AML_INTERNAL;
diff --git a/sys/contrib/dev/acpica/executer/excreate.c b/sys/contrib/dev/acpica/executer/excreate.c
index f6c2700..a2f3ed0 100644
--- a/sys/contrib/dev/acpica/executer/excreate.c
+++ b/sys/contrib/dev/acpica/executer/excreate.c
@@ -402,11 +402,11 @@ AcpiExCreateRegion (
if ((RegionSpace >= ACPI_NUM_PREDEFINED_REGIONS) &&
(RegionSpace < ACPI_USER_REGION_BEGIN))
{
- ACPI_ERROR ((AE_INFO, "Invalid AddressSpace type %X", RegionSpace));
+ ACPI_ERROR ((AE_INFO, "Invalid AddressSpace type 0x%X", RegionSpace));
return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n",
AcpiUtGetRegionName (RegionSpace), RegionSpace));
/* Create the region descriptor */
diff --git a/sys/contrib/dev/acpica/executer/exdebug.c b/sys/contrib/dev/acpica/executer/exdebug.c
new file mode 100644
index 0000000..084c6cb
--- /dev/null
+++ b/sys/contrib/dev/acpica/executer/exdebug.c
@@ -0,0 +1,350 @@
+/******************************************************************************
+ *
+ * Module Name: exdebug - Support for stores to the AML Debug Object
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#define __EXDEBUG_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acinterp.h>
+
+
+#define _COMPONENT ACPI_EXECUTER
+ ACPI_MODULE_NAME ("exdebug")
+
+
+#ifndef ACPI_NO_ERROR_MESSAGES
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExDoDebugObject
+ *
+ * PARAMETERS: SourceDesc - Object to be output to "Debug Object"
+ * Level - Indentation level (used for packages)
+ * Index - Current package element, zero if not pkg
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Handles stores to the AML Debug Object. For example:
+ * Store(INT1, Debug)
+ *
+ * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
+ *
+ * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or
+ * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal
+ * operational case, stores to the debug object are ignored but can be easily
+ * enabled if necessary.
+ *
+ ******************************************************************************/
+
+void
+AcpiExDoDebugObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ UINT32 Level,
+ UINT32 Index)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
+
+
+ /* Output must be enabled via the DebugObject global or the DbgLevel */
+
+ if (!AcpiGbl_EnableAmlDebugObject &&
+ !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT))
+ {
+ return_VOID;
+ }
+
+ /*
+ * Print line header as long as we are not in the middle of an
+ * object display
+ */
+ if (!((Level > 0) && Index == 0))
+ {
+ AcpiOsPrintf ("[ACPI Debug] %*s", Level, " ");
+ }
+
+ /* Display the index for package output only */
+
+ if (Index > 0)
+ {
+ AcpiOsPrintf ("(%.2u) ", Index-1);
+ }
+
+ if (!SourceDesc)
+ {
+ AcpiOsPrintf ("[Null Object]\n");
+ return_VOID;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc));
+
+ if (!AcpiUtValidInternalObject (SourceDesc))
+ {
+ AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
+ return_VOID;
+ }
+ }
+ else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf ("%s: %p\n",
+ AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
+ SourceDesc);
+ return_VOID;
+ }
+ else
+ {
+ return_VOID;
+ }
+
+ /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
+
+ switch (SourceDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ /* Output correct integer width */
+
+ if (AcpiGbl_IntegerByteWidth == 4)
+ {
+ AcpiOsPrintf ("0x%8.8X\n",
+ (UINT32) SourceDesc->Integer.Value);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
+ AcpiUtDumpBuffer2 (SourceDesc->Buffer.Pointer,
+ (SourceDesc->Buffer.Length < 256) ?
+ SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("[0x%.2X] \"%s\"\n",
+ SourceDesc->String.Length, SourceDesc->String.Pointer);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("[Contains 0x%.2X Elements]\n",
+ SourceDesc->Package.Count);
+
+ /* Output the entire contents of the package */
+
+ for (i = 0; i < SourceDesc->Package.Count; i++)
+ {
+ AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
+ Level+4, i+1);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));
+
+ /* Decode the reference */
+
+ switch (SourceDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_INDEX:
+
+ AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
+ break;
+
+ case ACPI_REFCLASS_TABLE:
+
+ /* Case for DdbHandle */
+
+ AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
+ return;
+
+ default:
+ break;
+ }
+
+ AcpiOsPrintf (" ");
+
+ /* Check for valid node first, then valid object */
+
+ if (SourceDesc->Reference.Node)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
+ ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf (" %p - Not a valid namespace node\n",
+ SourceDesc->Reference.Node);
+ }
+ else
+ {
+ AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
+ (SourceDesc->Reference.Node)->Name.Ascii);
+
+ switch ((SourceDesc->Reference.Node)->Type)
+ {
+ /* These types have no attached object */
+
+ case ACPI_TYPE_DEVICE:
+ AcpiOsPrintf ("Device\n");
+ break;
+
+ case ACPI_TYPE_THERMAL:
+ AcpiOsPrintf ("Thermal Zone\n");
+ break;
+
+ default:
+ AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
+ Level+4, 0);
+ break;
+ }
+ }
+ }
+ else if (SourceDesc->Reference.Object)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
+ ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
+ SourceDesc->Reference.Object)->Object,
+ Level+4, 0);
+ }
+ else
+ {
+ AcpiExDoDebugObject (SourceDesc->Reference.Object,
+ Level+4, 0);
+ }
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf ("%p\n", SourceDesc);
+ break;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+ return_VOID;
+}
+#endif
+
+
diff --git a/sys/contrib/dev/acpica/executer/exfield.c b/sys/contrib/dev/acpica/executer/exfield.c
index 0e06eef..c016014 100644
--- a/sys/contrib/dev/acpica/executer/exfield.c
+++ b/sys/contrib/dev/acpica/executer/exfield.c
@@ -382,7 +382,7 @@ AcpiExWriteDataToField (
if (SourceDesc->Buffer.Length < Length)
{
ACPI_ERROR ((AE_INFO,
- "SMBus or IPMI write requires Buffer of length %X, found length %X",
+ "SMBus or IPMI write requires Buffer of length %u, found length %u",
Length, SourceDesc->Buffer.Length));
return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
diff --git a/sys/contrib/dev/acpica/executer/exfldio.c b/sys/contrib/dev/acpica/executer/exfldio.c
index 8fbc992..b23b643 100644
--- a/sys/contrib/dev/acpica/executer/exfldio.c
+++ b/sys/contrib/dev/acpica/executer/exfldio.c
@@ -181,7 +181,7 @@ AcpiExSetupRegion (
if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
{
- ACPI_ERROR ((AE_INFO, "Needed Region, found type %X (%s)",
+ ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
RgnDesc->Common.Type,
AcpiUtGetObjectTypeName (RgnDesc)));
@@ -262,7 +262,7 @@ AcpiExSetupRegion (
* byte, and a field with Dword access specified.
*/
ACPI_ERROR ((AE_INFO,
- "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)",
+ "Field [%4.4s] access width (%u bytes) too large for region [%4.4s] (length %u)",
AcpiUtGetNodeName (ObjDesc->CommonField.Node),
ObjDesc->CommonField.AccessByteWidth,
AcpiUtGetNodeName (RgnDesc->Region.Node),
@@ -274,7 +274,7 @@ AcpiExSetupRegion (
* exceeds region length, indicate an error
*/
ACPI_ERROR ((AE_INFO,
- "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)",
+ "Field [%4.4s] Base+Offset+Width %u+%u+%u is beyond end of region [%4.4s] (length %u)",
AcpiUtGetNodeName (ObjDesc->CommonField.Node),
ObjDesc->CommonField.BaseByteOffset,
FieldDatumByteOffset, ObjDesc->CommonField.AccessByteWidth,
@@ -371,14 +371,14 @@ AcpiExAccessRegion (
if (Status == AE_NOT_IMPLEMENTED)
{
ACPI_ERROR ((AE_INFO,
- "Region %s(%X) not implemented",
+ "Region %s(0x%X) not implemented",
AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
RgnDesc->Region.SpaceId));
}
else if (Status == AE_NOT_EXIST)
{
ACPI_ERROR ((AE_INFO,
- "Region %s(%X) has no handler",
+ "Region %s(0x%X) has no handler",
AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
RgnDesc->Region.SpaceId));
}
@@ -633,7 +633,7 @@ AcpiExFieldDatumIo (
default:
- ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %X",
+ ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
ObjDesc->Common.Type));
Status = AE_AML_INTERNAL;
break;
@@ -743,7 +743,7 @@ AcpiExWriteWithUpdateRule (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown UpdateRule value: %X",
+ "Unknown UpdateRule value: 0x%X",
(ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)));
return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
}
@@ -806,7 +806,7 @@ AcpiExExtractFromField (
ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
{
ACPI_ERROR ((AE_INFO,
- "Field size %X (bits) is too large for buffer (%X)",
+ "Field size %u (bits) is too large for buffer (%u)",
ObjDesc->CommonField.BitLength, BufferLength));
return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
diff --git a/sys/contrib/dev/acpica/executer/exmisc.c b/sys/contrib/dev/acpica/executer/exmisc.c
index a639afb..9d01e03 100644
--- a/sys/contrib/dev/acpica/executer/exmisc.c
+++ b/sys/contrib/dev/acpica/executer/exmisc.c
@@ -183,7 +183,7 @@ AcpiExGetObjectReference (
default:
- ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
+ ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
ObjDesc->Reference.Class));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -201,7 +201,7 @@ AcpiExGetObjectReference (
default:
- ACPI_ERROR ((AE_INFO, "Invalid descriptor type %X",
+ ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
return_ACPI_STATUS (AE_TYPE);
}
@@ -373,7 +373,7 @@ AcpiExDoConcatenate (
break;
default:
- ACPI_ERROR ((AE_INFO, "Invalid object type: %X",
+ ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
Operand0->Common.Type));
Status = AE_AML_INTERNAL;
}
@@ -475,7 +475,7 @@ AcpiExDoConcatenate (
/* Invalid object type, should not happen here */
- ACPI_ERROR ((AE_INFO, "Invalid object type: %X",
+ ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
Operand0->Common.Type));
Status =AE_AML_INTERNAL;
goto Cleanup;
diff --git a/sys/contrib/dev/acpica/executer/exmutex.c b/sys/contrib/dev/acpica/executer/exmutex.c
index 0bd66b3..315ad10 100644
--- a/sys/contrib/dev/acpica/executer/exmutex.c
+++ b/sys/contrib/dev/acpica/executer/exmutex.c
@@ -168,10 +168,10 @@ AcpiExUnlinkMutex (
(ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
/*
- * Migrate the previous sync level associated with this mutex to the
- * previous mutex on the list so that it may be preserved. This handles
- * the case where several mutexes have been acquired at the same level,
- * but are not released in opposite order.
+ * Migrate the previous sync level associated with this mutex to
+ * the previous mutex on the list so that it may be preserved.
+ * This handles the case where several mutexes have been acquired
+ * at the same level, but are not released in opposite order.
*/
(ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
ObjDesc->Mutex.OriginalSyncLevel;
@@ -187,8 +187,8 @@ AcpiExUnlinkMutex (
*
* FUNCTION: AcpiExLinkMutex
*
- * PARAMETERS: ObjDesc - The mutex to be linked
- * Thread - Current executing thread object
+ * PARAMETERS: ObjDesc - The mutex to be linked
+ * Thread - Current executing thread object
*
* RETURN: None
*
@@ -228,9 +228,9 @@ AcpiExLinkMutex (
*
* FUNCTION: AcpiExAcquireMutexObject
*
- * PARAMETERS: TimeDesc - Timeout in milliseconds
+ * PARAMETERS: Timeout - Timeout in milliseconds
* ObjDesc - Mutex object
- * Thread - Current thread state
+ * ThreadId - Current thread state
*
* RETURN: Status
*
@@ -337,11 +337,12 @@ AcpiExAcquireMutex (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- /* Must have a valid thread ID */
+ /* Must have a valid thread state struct */
if (!WalkState->Thread)
{
- ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info",
+ ACPI_ERROR ((AE_INFO,
+ "Cannot acquire Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -353,7 +354,7 @@ AcpiExAcquireMutex (
if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
{
ACPI_ERROR ((AE_INFO,
- "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)",
+ "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
WalkState->Thread->CurrentSyncLevel));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
@@ -471,6 +472,7 @@ AcpiExReleaseMutex (
{
ACPI_STATUS Status = AE_OK;
UINT8 PreviousSyncLevel;
+ ACPI_THREAD_STATE *OwnerThread;
ACPI_FUNCTION_TRACE (ExReleaseMutex);
@@ -481,11 +483,14 @@ AcpiExReleaseMutex (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ OwnerThread = ObjDesc->Mutex.OwnerThread;
+
/* The mutex must have been previously acquired in order to release it */
- if (!ObjDesc->Mutex.OwnerThread)
+ if (!OwnerThread)
{
- ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",
+ ACPI_ERROR ((AE_INFO,
+ "Cannot release Mutex [%4.4s], not acquired",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
}
@@ -494,7 +499,8 @@ AcpiExReleaseMutex (
if (!WalkState->Thread)
{
- ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
+ ACPI_ERROR ((AE_INFO,
+ "Cannot release Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -503,14 +509,14 @@ AcpiExReleaseMutex (
* The Mutex is owned, but this thread must be the owner.
* Special case for Global Lock, any thread can release
*/
- if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
+ if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
(ObjDesc != AcpiGbl_GlobalLockMutex))
{
ACPI_ERROR ((AE_INFO,
"Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
ACPI_CAST_PTR (void, WalkState->Thread->ThreadId),
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
- ACPI_CAST_PTR (void, ObjDesc->Mutex.OwnerThread->ThreadId)));
+ ACPI_CAST_PTR (void, OwnerThread->ThreadId)));
return_ACPI_STATUS (AE_AML_NOT_OWNER);
}
@@ -521,10 +527,10 @@ AcpiExReleaseMutex (
* different level can only mean that the mutex ordering rule is being
* violated. This behavior is clarified in ACPI 4.0 specification.
*/
- if (ObjDesc->Mutex.SyncLevel != WalkState->Thread->CurrentSyncLevel)
+ if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
{
ACPI_ERROR ((AE_INFO,
- "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
+ "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
@@ -536,7 +542,7 @@ AcpiExReleaseMutex (
* acquired, but are not released in reverse order.
*/
PreviousSyncLevel =
- WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
+ OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
Status = AcpiExReleaseMutexObject (ObjDesc);
if (ACPI_FAILURE (Status))
@@ -548,8 +554,9 @@ AcpiExReleaseMutex (
{
/* Restore the previous SyncLevel */
- WalkState->Thread->CurrentSyncLevel = PreviousSyncLevel;
+ OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
}
+
return_ACPI_STATUS (Status);
}
@@ -558,7 +565,7 @@ AcpiExReleaseMutex (
*
* FUNCTION: AcpiExReleaseAllMutexes
*
- * PARAMETERS: Thread - Current executing thread object
+ * PARAMETERS: Thread - Current executing thread object
*
* RETURN: Status
*
@@ -617,5 +624,3 @@ AcpiExReleaseAllMutexes (
Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
}
}
-
-
diff --git a/sys/contrib/dev/acpica/executer/exnames.c b/sys/contrib/dev/acpica/executer/exnames.c
index 7134c62..bd884cb8 100644
--- a/sys/contrib/dev/acpica/executer/exnames.c
+++ b/sys/contrib/dev/acpica/executer/exnames.c
@@ -189,7 +189,7 @@ AcpiExAllocateNameString (
if (!NameString)
{
ACPI_ERROR ((AE_INFO,
- "Could not allocate size %d", SizeNeeded));
+ "Could not allocate size %u", SizeNeeded));
return_PTR (NULL);
}
@@ -325,7 +325,7 @@ AcpiExNameSegment (
*/
Status = AE_AML_BAD_NAME;
ACPI_ERROR ((AE_INFO,
- "Bad character %02x in name, at %p",
+ "Bad character 0x%02x in name, at %p",
*AmlAddress, AmlAddress));
}
diff --git a/sys/contrib/dev/acpica/executer/exoparg1.c b/sys/contrib/dev/acpica/executer/exoparg1.c
index dff76c6..550980f 100644
--- a/sys/contrib/dev/acpica/executer/exoparg1.c
+++ b/sys/contrib/dev/acpica/executer/exoparg1.c
@@ -193,7 +193,7 @@ AcpiExOpcode_0A_0T_1R (
default: /* Unknown opcode */
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
break;
@@ -286,7 +286,7 @@ AcpiExOpcode_1A_0T_0R (
default: /* Unknown opcode */
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
break;
@@ -332,7 +332,7 @@ AcpiExOpcode_1A_1T_0R (
default: /* Unknown opcode */
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
@@ -514,7 +514,7 @@ AcpiExOpcode_1A_1T_1R (
if (Digit > 0)
{
ACPI_ERROR ((AE_INFO,
- "Integer too large to convert to BCD: %8.8X%8.8X",
+ "Integer too large to convert to BCD: 0x%8.8X%8.8X",
ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
Status = AE_AML_NUMERIC_OVERFLOW;
goto Cleanup;
@@ -664,7 +664,7 @@ AcpiExOpcode_1A_1T_1R (
default: /* Unknown opcode */
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
@@ -1116,7 +1116,7 @@ AcpiExOpcode_1A_0T_1R (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown Index TargetType %X in reference object %p",
+ "Unknown Index TargetType 0x%X in reference object %p",
Operand[0]->Reference.TargetType, Operand[0]));
Status = AE_AML_OPERAND_TYPE;
goto Cleanup;
@@ -1143,7 +1143,7 @@ AcpiExOpcode_1A_0T_1R (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown class in reference(%p) - %2.2X",
+ "Unknown class in reference(%p) - 0x%2.2X",
Operand[0], Operand[0]->Reference.Class));
Status = AE_TYPE;
@@ -1155,7 +1155,7 @@ AcpiExOpcode_1A_0T_1R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
diff --git a/sys/contrib/dev/acpica/executer/exoparg2.c b/sys/contrib/dev/acpica/executer/exoparg2.c
index b6e8478..2bedf5a 100644
--- a/sys/contrib/dev/acpica/executer/exoparg2.c
+++ b/sys/contrib/dev/acpica/executer/exoparg2.c
@@ -206,33 +206,6 @@ AcpiExOpcode_2A_0T_0R (
break;
}
-#ifdef ACPI_GPE_NOTIFY_CHECK
- /*
- * GPE method wake/notify check. Here, we want to ensure that we
- * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
- * GPE method during system runtime. If we do, the GPE is marked
- * as "wake-only" and disabled.
- *
- * 1) Is the Notify() value == DeviceWake?
- * 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
- * 3) Did the original GPE happen at system runtime?
- * (versus during wake)
- *
- * If all three cases are true, this is a wake-only GPE that should
- * be disabled at runtime.
- */
- if (Value == 2) /* DeviceWake */
- {
- Status = AcpiEvCheckForWakeOnlyGpe (WalkState->GpeEventInfo);
- if (ACPI_FAILURE (Status))
- {
- /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
-
- return_ACPI_STATUS (AE_OK)
- }
- }
-#endif
-
/*
* Dispatch the notify to the appropriate handler
* NOTE: the request is queued for execution after this method
@@ -246,7 +219,7 @@ AcpiExOpcode_2A_0T_0R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
}
@@ -319,7 +292,7 @@ AcpiExOpcode_2A_2T_1R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
@@ -555,7 +528,7 @@ AcpiExOpcode_2A_1T_1R (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Index (%X%8.8X) is beyond end of object",
+ "Index (0x%8.8X%8.8X) is beyond end of object",
ACPI_FORMAT_UINT64 (Index)));
goto Cleanup;
}
@@ -579,7 +552,7 @@ AcpiExOpcode_2A_1T_1R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
break;
@@ -702,7 +675,7 @@ AcpiExOpcode_2A_0T_1R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
diff --git a/sys/contrib/dev/acpica/executer/exoparg3.c b/sys/contrib/dev/acpica/executer/exoparg3.c
index c94a26d..9c640c5 100644
--- a/sys/contrib/dev/acpica/executer/exoparg3.c
+++ b/sys/contrib/dev/acpica/executer/exoparg3.c
@@ -206,7 +206,7 @@ AcpiExOpcode_3A_0T_0R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
@@ -345,7 +345,7 @@ AcpiExOpcode_3A_1T_1R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
diff --git a/sys/contrib/dev/acpica/executer/exoparg6.c b/sys/contrib/dev/acpica/executer/exoparg6.c
index d13e9f6..3d06fa1 100644
--- a/sys/contrib/dev/acpica/executer/exoparg6.c
+++ b/sys/contrib/dev/acpica/executer/exoparg6.c
@@ -337,7 +337,7 @@ AcpiExOpcode_6A_0T_1R (
if (Index >= Operand[0]->Package.Count)
{
ACPI_ERROR ((AE_INFO,
- "Index (%X%8.8X) beyond package end (%X)",
+ "Index (0x%8.8X%8.8X) beyond package end (0x%X)",
ACPI_FORMAT_UINT64 (Index), Operand[0]->Package.Count));
Status = AE_AML_PACKAGE_LIMIT;
goto Cleanup;
@@ -411,7 +411,7 @@ AcpiExOpcode_6A_0T_1R (
default:
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
WalkState->Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
diff --git a/sys/contrib/dev/acpica/executer/exprep.c b/sys/contrib/dev/acpica/executer/exprep.c
index b60e09c..3eb5a65 100644
--- a/sys/contrib/dev/acpica/executer/exprep.c
+++ b/sys/contrib/dev/acpica/executer/exprep.c
@@ -362,7 +362,7 @@ AcpiExDecodeFieldAccess (
/* Invalid field access type */
ACPI_ERROR ((AE_INFO,
- "Unknown field access type %X",
+ "Unknown field access type 0x%X",
Access));
return_UINT32 (0);
}
@@ -533,7 +533,7 @@ AcpiExPrepFieldValue (
if (Type != ACPI_TYPE_REGION)
{
ACPI_ERROR ((AE_INFO,
- "Needed Region, found type %X (%s)",
+ "Needed Region, found type 0x%X (%s)",
Type, AcpiUtGetTypeName (Type)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
diff --git a/sys/contrib/dev/acpica/executer/exregion.c b/sys/contrib/dev/acpica/executer/exregion.c
index 3969c58..77a500c 100644
--- a/sys/contrib/dev/acpica/executer/exregion.c
+++ b/sys/contrib/dev/acpica/executer/exregion.c
@@ -188,7 +188,7 @@ AcpiExSystemMemorySpaceHandler (
break;
default:
- ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %d",
+ ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
BitWidth));
return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
}
@@ -265,7 +265,7 @@ AcpiExSystemMemorySpaceHandler (
if (!MemInfo->MappedLogicalAddress)
{
ACPI_ERROR ((AE_INFO,
- "Could not map memory at %8.8X%8.8X, size %X",
+ "Could not map memory at 0x%8.8X%8.8X, size %u",
ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength));
MemInfo->MappedLength = 0;
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -608,8 +608,10 @@ AcpiExDataTableSpaceHandler (
ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
- /* Perform the memory read or write */
-
+ /*
+ * Perform the memory read or write. The BitWidth was already
+ * validated.
+ */
switch (Function)
{
case ACPI_READ:
@@ -619,9 +621,14 @@ AcpiExDataTableSpaceHandler (
break;
case ACPI_WRITE:
+
+ ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
+ ACPI_DIV_8 (BitWidth));
+ break;
+
default:
- return_ACPI_STATUS (AE_SUPPORT);
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
}
return_ACPI_STATUS (AE_OK);
diff --git a/sys/contrib/dev/acpica/executer/exresnte.c b/sys/contrib/dev/acpica/executer/exresnte.c
index 9a45afd..7b28f85 100644
--- a/sys/contrib/dev/acpica/executer/exresnte.c
+++ b/sys/contrib/dev/acpica/executer/exresnte.c
@@ -344,7 +344,7 @@ AcpiExResolveNodeToValue (
/* No named references are allowed here */
ACPI_ERROR ((AE_INFO,
- "Unsupported Reference type %X",
+ "Unsupported Reference type 0x%X",
SourceDesc->Reference.Class));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
@@ -357,7 +357,7 @@ AcpiExResolveNodeToValue (
/* Default case is for unknown types */
ACPI_ERROR ((AE_INFO,
- "Node %p - Unknown object type %X",
+ "Node %p - Unknown object type 0x%X",
Node, EntryType));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
diff --git a/sys/contrib/dev/acpica/executer/exresolv.c b/sys/contrib/dev/acpica/executer/exresolv.c
index e587bd1..8b19b54 100644
--- a/sys/contrib/dev/acpica/executer/exresolv.c
+++ b/sys/contrib/dev/acpica/executer/exresolv.c
@@ -326,7 +326,7 @@ AcpiExResolveObjectToValue (
/* Invalid reference object */
ACPI_ERROR ((AE_INFO,
- "Unknown TargetType %X in Index/Reference object %p",
+ "Unknown TargetType 0x%X in Index/Reference object %p",
StackDesc->Reference.TargetType, StackDesc));
Status = AE_AML_INTERNAL;
break;
@@ -367,7 +367,7 @@ AcpiExResolveObjectToValue (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown Reference type %X in %p", RefType, StackDesc));
+ "Unknown Reference type 0x%X in %p", RefType, StackDesc));
Status = AE_AML_INTERNAL;
break;
}
@@ -503,7 +503,7 @@ AcpiExResolveMultiple (
if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
{
ACPI_ERROR ((AE_INFO,
- "Not a NS node %p [%s]",
+ "Not a namespace node %p [%s]",
Node, AcpiUtGetDescriptorName (Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -605,7 +605,7 @@ AcpiExResolveMultiple (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown Reference Class %2.2X", ObjDesc->Reference.Class));
+ "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
}
diff --git a/sys/contrib/dev/acpica/executer/exresop.c b/sys/contrib/dev/acpica/executer/exresop.c
index 22dd558..211e1d9 100644
--- a/sys/contrib/dev/acpica/executer/exresop.c
+++ b/sys/contrib/dev/acpica/executer/exresop.c
@@ -243,7 +243,7 @@ AcpiExResolveOperands (
ArgTypes = OpInfo->RuntimeArgs;
if (ArgTypes == ARGI_INVALID_OPCODE)
{
- ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
+ ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
Opcode));
return_ACPI_STATUS (AE_AML_INTERNAL);
@@ -309,7 +309,7 @@ AcpiExResolveOperands (
if (!AcpiUtValidObjectType (ObjectType))
{
ACPI_ERROR ((AE_INFO,
- "Bad operand object type [%X]", ObjectType));
+ "Bad operand object type [0x%X]", ObjectType));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
@@ -342,7 +342,7 @@ AcpiExResolveOperands (
default:
ACPI_ERROR ((AE_INFO,
- "Unknown Reference Class %2.2X in %p",
+ "Unknown Reference Class 0x%2.2X in %p",
ObjDesc->Reference.Class, ObjDesc));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
@@ -773,7 +773,7 @@ AcpiExResolveOperands (
/* Unknown type */
ACPI_ERROR ((AE_INFO,
- "Internal - Unknown ARGI (required operand) type %X",
+ "Internal - Unknown ARGI (required operand) type 0x%X",
ThisArgType));
return_ACPI_STATUS (AE_BAD_PARAMETER);
diff --git a/sys/contrib/dev/acpica/executer/exstore.c b/sys/contrib/dev/acpica/executer/exstore.c
index ff9b940..c78e106 100644
--- a/sys/contrib/dev/acpica/executer/exstore.c
+++ b/sys/contrib/dev/acpica/executer/exstore.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exstore - AML Interpreter object store support
@@ -129,12 +128,6 @@
/* Local prototypes */
-static void
-AcpiExDoDebugObject (
- ACPI_OPERAND_OBJECT *SourceDesc,
- UINT32 Level,
- UINT32 Index);
-
static ACPI_STATUS
AcpiExStoreObjectToIndex (
ACPI_OPERAND_OBJECT *ValDesc,
@@ -144,218 +137,6 @@ AcpiExStoreObjectToIndex (
/*******************************************************************************
*
- * FUNCTION: AcpiExDoDebugObject
- *
- * PARAMETERS: SourceDesc - Value to be stored
- * Level - Indentation level (used for packages)
- * Index - Current package element, zero if not pkg
- *
- * RETURN: None
- *
- * DESCRIPTION: Handles stores to the Debug Object.
- *
- ******************************************************************************/
-
-static void
-AcpiExDoDebugObject (
- ACPI_OPERAND_OBJECT *SourceDesc,
- UINT32 Level,
- UINT32 Index)
-{
- UINT32 i;
-
-
- ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
-
-
- /* Print line header as long as we are not in the middle of an object display */
-
- if (!((Level > 0) && Index == 0))
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
- Level, " "));
- }
-
- /* Display index for package output only */
-
- if (Index > 0)
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
- "(%.2u) ", Index -1));
- }
-
- if (!SourceDesc)
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
- return_VOID;
- }
-
- if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s ",
- AcpiUtGetObjectTypeName (SourceDesc)));
-
- if (!AcpiUtValidInternalObject (SourceDesc))
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
- "%p, Invalid Internal Object!\n", SourceDesc));
- return_VOID;
- }
- }
- else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
- AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
- SourceDesc));
- return_VOID;
- }
- else
- {
- return_VOID;
- }
-
- /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
-
- switch (SourceDesc->Common.Type)
- {
- case ACPI_TYPE_INTEGER:
-
- /* Output correct integer width */
-
- if (AcpiGbl_IntegerByteWidth == 4)
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
- (UINT32) SourceDesc->Integer.Value));
- }
- else
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value)));
- }
- break;
-
- case ACPI_TYPE_BUFFER:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
- (UINT32) SourceDesc->Buffer.Length));
- ACPI_DUMP_BUFFER (SourceDesc->Buffer.Pointer,
- (SourceDesc->Buffer.Length < 256) ? SourceDesc->Buffer.Length : 256);
- break;
-
- case ACPI_TYPE_STRING:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
- SourceDesc->String.Length, SourceDesc->String.Pointer));
- break;
-
- case ACPI_TYPE_PACKAGE:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Contains 0x%.2X Elements]\n",
- SourceDesc->Package.Count));
-
- /* Output the entire contents of the package */
-
- for (i = 0; i < SourceDesc->Package.Count; i++)
- {
- AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
- Level+4, i+1);
- }
- break;
-
- case ACPI_TYPE_LOCAL_REFERENCE:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s] ",
- AcpiUtGetReferenceName (SourceDesc)));
-
- /* Decode the reference */
-
- switch (SourceDesc->Reference.Class)
- {
- case ACPI_REFCLASS_INDEX:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
- SourceDesc->Reference.Value));
- break;
-
- case ACPI_REFCLASS_TABLE:
-
- /* Case for DdbHandle */
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Table Index 0x%X\n",
- SourceDesc->Reference.Value));
- return;
-
- default:
- break;
- }
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, " "));
-
- /* Check for valid node first, then valid object */
-
- if (SourceDesc->Reference.Node)
- {
- if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
- ACPI_DESC_TYPE_NAMED)
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
- " %p - Not a valid namespace node\n",
- SourceDesc->Reference.Node));
- }
- else
- {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Node %p [%4.4s] ",
- SourceDesc->Reference.Node, (SourceDesc->Reference.Node)->Name.Ascii));
-
- switch ((SourceDesc->Reference.Node)->Type)
- {
- /* These types have no attached object */
-
- case ACPI_TYPE_DEVICE:
- AcpiOsPrintf ("Device\n");
- break;
-
- case ACPI_TYPE_THERMAL:
- AcpiOsPrintf ("Thermal Zone\n");
- break;
-
- default:
- AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
- Level+4, 0);
- break;
- }
- }
- }
- else if (SourceDesc->Reference.Object)
- {
- if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
- ACPI_DESC_TYPE_NAMED)
- {
- AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
- SourceDesc->Reference.Object)->Object,
- Level+4, 0);
- }
- else
- {
- AcpiExDoDebugObject (SourceDesc->Reference.Object, Level+4, 0);
- }
- }
- break;
-
- default:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
- SourceDesc));
- break;
- }
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
- return_VOID;
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiExStore
*
* PARAMETERS: *SourceDesc - Value to be stored
@@ -487,13 +268,13 @@ AcpiExStore (
"**** Write to Debug Object: Object %p %s ****:\n\n",
SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
- AcpiExDoDebugObject (SourceDesc, 0, 0);
+ ACPI_DEBUG_OBJECT (SourceDesc, 0, 0);
break;
default:
- ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
+ ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
RefDesc->Reference.Class));
ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);
diff --git a/sys/contrib/dev/acpica/executer/exsystem.c b/sys/contrib/dev/acpica/executer/exsystem.c
index c9f746a..96e3063 100644
--- a/sys/contrib/dev/acpica/executer/exsystem.c
+++ b/sys/contrib/dev/acpica/executer/exsystem.c
@@ -265,7 +265,7 @@ AcpiExSystemDoStall (
* (ACPI specifies 100 usec as max, but this gives some slack in
* order to support existing BIOSs)
*/
- ACPI_ERROR ((AE_INFO, "Time parameter is too large (%d)",
+ ACPI_ERROR ((AE_INFO, "Time parameter is too large (%u)",
HowLong));
Status = AE_AML_OPERAND_VALUE;
}
diff --git a/sys/contrib/dev/acpica/hardware/hwregs.c b/sys/contrib/dev/acpica/hardware/hwregs.c
index 26ee462..050f5b3 100644
--- a/sys/contrib/dev/acpica/hardware/hwregs.c
+++ b/sys/contrib/dev/acpica/hardware/hwregs.c
@@ -412,7 +412,7 @@ AcpiHwGetBitRegisterInfo (
if (RegisterId > ACPI_BITREG_MAX)
{
- ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: %X", RegisterId));
+ ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
return (NULL);
}
@@ -539,7 +539,7 @@ AcpiHwRegisterRead (
default:
- ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X",
+ ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
RegisterId));
Status = AE_BAD_PARAMETER;
break;
@@ -682,7 +682,7 @@ AcpiHwRegisterWrite (
default:
- ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X",
+ ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
RegisterId));
Status = AE_BAD_PARAMETER;
break;
diff --git a/sys/contrib/dev/acpica/hardware/hwsleep.c b/sys/contrib/dev/acpica/hardware/hwsleep.c
index 7026c69..913deb3 100644
--- a/sys/contrib/dev/acpica/hardware/hwsleep.c
+++ b/sys/contrib/dev/acpica/hardware/hwsleep.c
@@ -320,7 +320,7 @@ AcpiEnterSleepState (
if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) ||
(AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX))
{
- ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=%X B=%X",
+ ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB));
return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
}
@@ -474,13 +474,16 @@ AcpiEnterSleepState (
return_ACPI_STATUS (Status);
}
- /*
- * Some BIOSs don't set WAK_STS at all. Give up waiting after
- * 1000 retries if it still isn't set.
- */
- if (Retry-- == 0)
+ if (AcpiGbl_EnableInterpreterSlack)
{
- break;
+ /*
+ * Some BIOSs don't set WAK_STS at all. Give up waiting after
+ * 1000 retries if it still isn't set.
+ */
+ if (Retry-- == 0)
+ {
+ break;
+ }
}
/* Spin until we wake */
diff --git a/sys/contrib/dev/acpica/hardware/hwvalid.c b/sys/contrib/dev/acpica/hardware/hwvalid.c
index 8c369b1..a715053 100644
--- a/sys/contrib/dev/acpica/hardware/hwvalid.c
+++ b/sys/contrib/dev/acpica/hardware/hwvalid.c
@@ -237,7 +237,7 @@ AcpiHwValidateIoRequest (
if (LastAddress > ACPI_UINT16_MAX)
{
ACPI_ERROR ((AE_INFO,
- "Illegal I/O port address/length above 64K: 0x%p/%X",
+ "Illegal I/O port address/length above 64K: %p/0x%X",
ACPI_CAST_PTR (void, Address), ByteWidth));
return_ACPI_STATUS (AE_LIMIT);
}
diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h
index 6c61f84..6d119aa 100644
--- a/sys/contrib/dev/acpica/include/acdisasm.h
+++ b/sys/contrib/dev/acpica/include/acdisasm.h
@@ -286,6 +286,7 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadtHdr[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoMsct[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp1[];
diff --git a/sys/contrib/dev/acpica/include/acevents.h b/sys/contrib/dev/acpica/include/acevents.h
index 567ac1e..4d945ef 100644
--- a/sys/contrib/dev/acpica/include/acevents.h
+++ b/sys/contrib/dev/acpica/include/acevents.h
@@ -171,13 +171,11 @@ AcpiEvQueueNotifyRequest (
*/
ACPI_STATUS
AcpiEvUpdateGpeEnableMasks (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- UINT8 Type);
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
ACPI_STATUS
AcpiEvEnableGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- BOOLEAN WriteToHardware);
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
ACPI_STATUS
AcpiEvDisableGpe (
@@ -188,6 +186,11 @@ AcpiEvGetGpeEventInfo (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber);
+ACPI_GPE_EVENT_INFO *
+AcpiEvLowGetGpeInfo (
+ UINT32 GpeNumber,
+ ACPI_GPE_BLOCK_INFO *GpeBlock);
+
/*
* evgpeblk
@@ -235,15 +238,6 @@ AcpiEvGpeDetect (
ACPI_GPE_XRUPT_INFO *GpeXruptList);
ACPI_STATUS
-AcpiEvSetGpeType (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- UINT8 Type);
-
-ACPI_STATUS
-AcpiEvCheckForWakeOnlyGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo);
-
-ACPI_STATUS
AcpiEvGpeInitialize (
void);
diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h
index 89fe5c6..a46de7d 100644
--- a/sys/contrib/dev/acpica/include/acexcep.h
+++ b/sys/contrib/dev/acpica/include/acexcep.h
@@ -162,7 +162,7 @@
#define AE_NO_GLOBAL_LOCK (ACPI_STATUS) (0x0017 | AE_CODE_ENVIRONMENTAL)
#define AE_ABORT_METHOD (ACPI_STATUS) (0x0018 | AE_CODE_ENVIRONMENTAL)
#define AE_SAME_HANDLER (ACPI_STATUS) (0x0019 | AE_CODE_ENVIRONMENTAL)
-#define AE_WAKE_ONLY_GPE (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_HANDLER (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
#define AE_OWNER_ID_LIMIT (ACPI_STATUS) (0x001B | AE_CODE_ENVIRONMENTAL)
#define AE_CODE_ENV_MAX 0x001B
diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h
index 4469ee3..4f0769e 100644
--- a/sys/contrib/dev/acpica/include/acglobal.h
+++ b/sys/contrib/dev/acpica/include/acglobal.h
@@ -186,6 +186,19 @@ UINT8 ACPI_INIT_GLOBAL (AcpiGbl_LeaveWakeGpesDisabled, TRUE);
*/
UINT8 ACPI_INIT_GLOBAL (AcpiGbl_UseDefaultRegisterWidths, TRUE);
+/*
+ * Optionally enable output from the AML Debug Object.
+ */
+UINT8 ACPI_INIT_GLOBAL (AcpiGbl_EnableAmlDebugObject, FALSE);
+
+/*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+UINT8 ACPI_INIT_GLOBAL (AcpiGbl_CopyDsdtLocally, FALSE);
+
/* AcpiGbl_FADT is a local copy of the FADT, converted to a common format. */
@@ -218,6 +231,11 @@ ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1aEnable;
ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bStatus;
ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bEnable;
+/* DSDT information. Used to check for DSDT corruption */
+
+ACPI_EXTERN ACPI_TABLE_HEADER *AcpiGbl_DSDT;
+ACPI_EXTERN ACPI_TABLE_HEADER AcpiGbl_OriginalDsdtHeader;
+
/*
* Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is
* determined by the revision of the DSDT: If the DSDT revision is less than
diff --git a/sys/contrib/dev/acpica/include/acinterp.h b/sys/contrib/dev/acpica/include/acinterp.h
index de7dbf8..67142c8 100644
--- a/sys/contrib/dev/acpica/include/acinterp.h
+++ b/sys/contrib/dev/acpica/include/acinterp.h
@@ -203,6 +203,16 @@ AcpiExConvertToTargetType (
/*
+ * exdebug - AML debug object
+ */
+void
+AcpiExDoDebugObject (
+ ACPI_OPERAND_OBJECT *SourceDesc,
+ UINT32 Level,
+ UINT32 Index);
+
+
+/*
* exfield - ACPI AML (p-code) execution - field manipulation
*/
ACPI_STATUS
diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h
index 0aeacff..8818a6e 100644
--- a/sys/contrib/dev/acpica/include/aclocal.h
+++ b/sys/contrib/dev/acpica/include/aclocal.h
@@ -561,6 +561,8 @@ typedef struct acpi_gpe_event_info
struct acpi_gpe_register_info *RegisterInfo; /* Backpointer to register info */
UINT8 Flags; /* Misc info about this GPE */
UINT8 GpeNumber; /* This GPE */
+ UINT8 RuntimeCount; /* References to a run GPE */
+ UINT8 WakeupCount; /* References to a wake GPE */
} ACPI_GPE_EVENT_INFO;
@@ -590,6 +592,7 @@ typedef struct acpi_gpe_block_info
ACPI_GPE_EVENT_INFO *EventInfo; /* One for each GPE */
ACPI_GENERIC_ADDRESS BlockAddress; /* Base address of the block */
UINT32 RegisterCount; /* Number of register pairs in block */
+ UINT16 GpeCount; /* Number of individual GPEs in block */
UINT8 BlockBaseNumber;/* Base GPE number for this block */
} ACPI_GPE_BLOCK_INFO;
diff --git a/sys/contrib/dev/acpica/include/acoutput.h b/sys/contrib/dev/acpica/include/acoutput.h
index 8018fed..8fca0de 100644
--- a/sys/contrib/dev/acpica/include/acoutput.h
+++ b/sys/contrib/dev/acpica/include/acoutput.h
@@ -281,6 +281,7 @@
#define ACPI_WARNING(plist) AcpiWarning plist
#define ACPI_EXCEPTION(plist) AcpiException plist
#define ACPI_ERROR(plist) AcpiError plist
+#define ACPI_DEBUG_OBJECT(obj,l,i) AcpiExDoDebugObject(obj,l,i)
#else
@@ -290,6 +291,7 @@
#define ACPI_WARNING(plist)
#define ACPI_EXCEPTION(plist)
#define ACPI_ERROR(plist)
+#define ACPI_DEBUG_OBJECT(obj,l,i)
#endif /* ACPI_NO_ERROR_MESSAGES */
diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h
index 7111984..5562fa0 100644
--- a/sys/contrib/dev/acpica/include/acpixf.h
+++ b/sys/contrib/dev/acpica/include/acpixf.h
@@ -120,7 +120,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20100121
+#define ACPI_CA_VERSION 0x20100331
#include <contrib/dev/acpica/include/actypes.h>
#include <contrib/dev/acpica/include/actbl.h>
@@ -145,6 +145,8 @@ extern UINT8 AcpiGbl_LeaveWakeGpesDisabled;
extern UINT8 AcpiGbl_UseDefaultRegisterWidths;
extern ACPI_NAME AcpiGbl_TraceMethodName;
extern UINT32 AcpiGbl_TraceFlags;
+extern UINT8 AcpiGbl_EnableAmlDebugObject;
+extern UINT8 AcpiGbl_CopyDsdtLocally;
/*
@@ -462,34 +464,32 @@ AcpiGetEventStatus (
* GPE Interfaces
*/
ACPI_STATUS
-AcpiSetGpeType (
+AcpiSetGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT8 Type);
+ UINT8 Action);
ACPI_STATUS
AcpiEnableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags);
+ UINT8 GpeType);
ACPI_STATUS
AcpiDisableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags);
+ UINT8 GpeType);
ACPI_STATUS
AcpiClearGpe (
ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- UINT32 Flags);
+ UINT32 GpeNumber);
ACPI_STATUS
AcpiGetGpeStatus (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags,
ACPI_EVENT_STATUS *EventStatus);
ACPI_STATUS
diff --git a/sys/contrib/dev/acpica/include/actables.h b/sys/contrib/dev/acpica/include/actables.h
index 54fdaae..9f1c4f0 100644
--- a/sys/contrib/dev/acpica/include/actables.h
+++ b/sys/contrib/dev/acpica/include/actables.h
@@ -231,6 +231,14 @@ AcpiTbVerifyChecksum (
UINT32 Length);
void
+AcpiTbCheckDsdtHeader (
+ void);
+
+ACPI_TABLE_HEADER *
+AcpiTbCopyDsdt (
+ UINT32 TableIndex);
+
+void
AcpiTbInstallTable (
ACPI_PHYSICAL_ADDRESS Address,
char *Signature,
diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h
index c96715d..7f6ecf8 100644
--- a/sys/contrib/dev/acpica/include/actbl2.h
+++ b/sys/contrib/dev/acpica/include/actbl2.h
@@ -143,6 +143,7 @@
#define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */
#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */
+#define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */
#define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */
#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */
#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */
@@ -864,6 +865,35 @@ typedef struct acpi_mcfg_allocation
/*******************************************************************************
*
+ * MCHI - Management Controller Host Interface Table
+ * Version 1
+ *
+ * Conforms to "Management Component Transport Protocol (MCTP) Host
+ * Interface Specification", Revision 1.0.0a, October 13, 2009
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_mchi
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 InterfaceType;
+ UINT8 Protocol;
+ UINT64 ProtocolData;
+ UINT8 InterruptType;
+ UINT8 Gpe;
+ UINT8 PciDeviceFlag;
+ UINT32 GlobalInterrupt;
+ ACPI_GENERIC_ADDRESS ControlRegister;
+ UINT8 PciSegment;
+ UINT8 PciBus;
+ UINT8 PciDevice;
+ UINT8 PciFunction;
+
+} ACPI_TABLE_MCHI;
+
+
+/*******************************************************************************
+ *
* SPCR - Serial Port Console Redirection table
* Version 1
*
diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h
index 8d0d06a..3c0626a 100644
--- a/sys/contrib/dev/acpica/include/actypes.h
+++ b/sys/contrib/dev/acpica/include/actypes.h
@@ -742,53 +742,42 @@ typedef UINT32 ACPI_EVENT_STATUS;
#define ACPI_GPE_MAX 0xFF
#define ACPI_NUM_GPE 256
+/* Actions for AcpiSetGpe */
+
#define ACPI_GPE_ENABLE 0
#define ACPI_GPE_DISABLE 1
+/* GpeTypes for AcpiEnableGpe and AcpiDisableGpe */
+
+#define ACPI_GPE_TYPE_WAKE (UINT8) 0x01
+#define ACPI_GPE_TYPE_RUNTIME (UINT8) 0x02
+#define ACPI_GPE_TYPE_WAKE_RUN (UINT8) 0x03
/*
* GPE info flags - Per GPE
- * +-+-+-+---+---+-+
- * |7|6|5|4:3|2:1|0|
- * +-+-+-+---+---+-+
- * | | | | | |
- * | | | | | +--- Interrupt type: Edge or Level Triggered
- * | | | | +--- Type: Wake-only, Runtime-only, or wake/runtime
- * | | | +--- Type of dispatch -- to method, handler, or none
- * | | +--- Enabled for runtime?
- * | +--- Enabled for wake?
- * +--- Unused
+ * +-------+---+-+-+
+ * | 7:4 |3:2|1|0|
+ * +-------+---+-+-+
+ * | | | |
+ * | | | +--- Interrupt type: edge or level triggered
+ * | | +----- GPE can wake the system
+ * | +-------- Type of dispatch:to method, handler, or none
+ * +-------------- <Reserved>
*/
#define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x01
#define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x01
#define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00
-#define ACPI_GPE_TYPE_MASK (UINT8) 0x06
-#define ACPI_GPE_TYPE_WAKE_RUN (UINT8) 0x06
-#define ACPI_GPE_TYPE_WAKE (UINT8) 0x02
-#define ACPI_GPE_TYPE_RUNTIME (UINT8) 0x04 /* Default */
-
-#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x18
-#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x08
-#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x10
-#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00 /* Default */
+#define ACPI_GPE_CAN_WAKE (UINT8) 0x02
-#define ACPI_GPE_RUN_ENABLE_MASK (UINT8) 0x20
-#define ACPI_GPE_RUN_ENABLED (UINT8) 0x20
-#define ACPI_GPE_RUN_DISABLED (UINT8) 0x00 /* Default */
-
-#define ACPI_GPE_WAKE_ENABLE_MASK (UINT8) 0x40
-#define ACPI_GPE_WAKE_ENABLED (UINT8) 0x40
-#define ACPI_GPE_WAKE_DISABLED (UINT8) 0x00 /* Default */
-
-#define ACPI_GPE_ENABLE_MASK (UINT8) 0x60 /* Both run/wake */
+#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x0C
+#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x04
+#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x08
+#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00
/*
* Flags for GPE and Lock interfaces
*/
-#define ACPI_EVENT_WAKE_ENABLE 0x2 /* AcpiGpeEnable */
-#define ACPI_EVENT_WAKE_DISABLE 0x2 /* AcpiGpeDisable */
-
#define ACPI_NOT_ISR 0x1
#define ACPI_ISR 0x0
diff --git a/sys/contrib/dev/acpica/include/platform/acfreebsd.h b/sys/contrib/dev/acpica/include/platform/acfreebsd.h
index 20ec3a2..c835aaf 100644
--- a/sys/contrib/dev/acpica/include/platform/acfreebsd.h
+++ b/sys/contrib/dev/acpica/include/platform/acfreebsd.h
@@ -114,7 +114,7 @@
*****************************************************************************/
#ifndef __ACFREEBSD_H__
-#define __ACFREEBSD_H__
+#define __ACFREEBSD_H__
/* FreeBSD uses GCC */
@@ -123,11 +123,11 @@
#include <sys/types.h>
#include <machine/acpica_machdep.h>
-#define ACPI_UINTPTR_T uintptr_t
+#define ACPI_UINTPTR_T uintptr_t
-#define ACPI_USE_DO_WHILE_0
-#define ACPI_USE_LOCAL_CACHE
-#define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_USE_DO_WHILE_0
+#define ACPI_USE_LOCAL_CACHE
+#define ACPI_USE_SYSTEM_CLIBRARY
#ifdef _KERNEL
@@ -139,18 +139,18 @@
#include "opt_acpi.h"
-#define ACPI_THREAD_ID lwpid_t
-#define ACPI_MUTEX_TYPE ACPI_OSL_MUTEX
+#define ACPI_THREAD_ID lwpid_t
+#define ACPI_MUTEX_TYPE ACPI_OSL_MUTEX
#ifdef ACPI_DEBUG
-#define ACPI_DEBUG_OUTPUT /* for backward compatibility */
-#define ACPI_DISASSEMBLER
+#define ACPI_DEBUG_OUTPUT /* for backward compatibility */
+#define ACPI_DISASSEMBLER
#endif
#ifdef ACPI_DEBUG_OUTPUT
#include "opt_ddb.h"
#ifdef DDB
-#define ACPI_DEBUGGER
+#define ACPI_DEBUGGER
#endif /* DDB */
#endif /* ACPI_DEBUG_OUTPUT */
@@ -158,7 +158,7 @@
#undef DEBUGGER_THREADING
#endif /* DEBUGGER_THREADING */
-#define DEBUGGER_THREADING 0 /* integrated with DDB */
+#define DEBUGGER_THREADING 0 /* integrated with DDB */
#else /* _KERNEL */
@@ -166,12 +166,12 @@
#include <ctype.h>
#endif
-#define ACPI_THREAD_ID pthread_t
+#define ACPI_THREAD_ID pthread_t
-#define ACPI_USE_STANDARD_HEADERS
+#define ACPI_USE_STANDARD_HEADERS
-#define ACPI_FLUSH_CPU_CACHE()
-#define __cdecl
+#define ACPI_FLUSH_CPU_CACHE()
+#define __cdecl
#endif /* _KERNEL */
diff --git a/sys/contrib/dev/acpica/namespace/nsaccess.c b/sys/contrib/dev/acpica/namespace/nsaccess.c
index e360e28..0ee1fae 100644
--- a/sys/contrib/dev/acpica/namespace/nsaccess.c
+++ b/sys/contrib/dev/acpica/namespace/nsaccess.c
@@ -306,7 +306,7 @@ AcpiNsRootInitialize (
default:
- ACPI_ERROR ((AE_INFO, "Unsupported initial type value %X",
+ ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X",
InitVal->Type));
AcpiUtRemoveReference (ObjDesc);
ObjDesc = NULL;
diff --git a/sys/contrib/dev/acpica/namespace/nsdump.c b/sys/contrib/dev/acpica/namespace/nsdump.c
index a1ae96e..2d37135 100644
--- a/sys/contrib/dev/acpica/namespace/nsdump.c
+++ b/sys/contrib/dev/acpica/namespace/nsdump.c
@@ -314,7 +314,7 @@ AcpiNsDumpOneObject (
if (Type > ACPI_TYPE_LOCAL_MAX)
{
- ACPI_WARNING ((AE_INFO, "Invalid ACPI Object Type %08X", Type));
+ ACPI_WARNING ((AE_INFO, "Invalid ACPI Object Type 0x%08X", Type));
}
AcpiOsPrintf ("%4.4s", AcpiUtGetNodeName (ThisNode));
diff --git a/sys/contrib/dev/acpica/namespace/nsnames.c b/sys/contrib/dev/acpica/namespace/nsnames.c
index c23e6de..6f26f01 100644
--- a/sys/contrib/dev/acpica/namespace/nsnames.c
+++ b/sys/contrib/dev/acpica/namespace/nsnames.c
@@ -191,7 +191,7 @@ AcpiNsBuildExternalPath (
if (Index != 0)
{
ACPI_ERROR ((AE_INFO,
- "Could not construct external pathname; index=%X, size=%X, Path=%s",
+ "Could not construct external pathname; index=%u, size=%u, Path=%s",
(UINT32) Index, (UINT32) Size, &NameBuffer[Size]));
return (AE_BAD_PARAMETER);
diff --git a/sys/contrib/dev/acpica/namespace/nssearch.c b/sys/contrib/dev/acpica/namespace/nssearch.c
index b583fab..2467300 100644
--- a/sys/contrib/dev/acpica/namespace/nssearch.c
+++ b/sys/contrib/dev/acpica/namespace/nssearch.c
@@ -397,7 +397,7 @@ AcpiNsSearchAndEnter (
if (!Node || !TargetName || !ReturnNode)
{
ACPI_ERROR ((AE_INFO,
- "Null parameter: Node %p Name %X ReturnNode %p",
+ "Null parameter: Node %p Name 0x%X ReturnNode %p",
Node, TargetName, ReturnNode));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
diff --git a/sys/contrib/dev/acpica/namespace/nsutils.c b/sys/contrib/dev/acpica/namespace/nsutils.c
index cc42f68..7a464c1 100644
--- a/sys/contrib/dev/acpica/namespace/nsutils.c
+++ b/sys/contrib/dev/acpica/namespace/nsutils.c
@@ -389,7 +389,7 @@ AcpiNsLocal (
{
/* Type code out of range */
- ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type));
+ ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
return_UINT32 (ACPI_NS_NORMAL);
}
@@ -965,7 +965,7 @@ AcpiNsOpensScope (
{
/* type code out of range */
- ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type));
+ ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
return_UINT32 (ACPI_NS_NORMAL);
}
diff --git a/sys/contrib/dev/acpica/parser/psargs.c b/sys/contrib/dev/acpica/parser/psargs.c
index 275993d..609e642 100644
--- a/sys/contrib/dev/acpica/parser/psargs.c
+++ b/sys/contrib/dev/acpica/parser/psargs.c
@@ -577,7 +577,7 @@ AcpiPsGetNextSimpleArg (
default:
- ACPI_ERROR ((AE_INFO, "Invalid ArgType %X", ArgType));
+ ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
return_VOID;
}
@@ -883,7 +883,7 @@ AcpiPsGetNextArg (
default:
- ACPI_ERROR ((AE_INFO, "Invalid ArgType: %X", ArgType));
+ ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
Status = AE_AML_OPERAND_TYPE;
break;
}
diff --git a/sys/contrib/dev/acpica/parser/psloop.c b/sys/contrib/dev/acpica/parser/psloop.c
index 73bfdf8..36b4c9a 100644
--- a/sys/contrib/dev/acpica/parser/psloop.c
+++ b/sys/contrib/dev/acpica/parser/psloop.c
@@ -228,7 +228,7 @@ AcpiPsGetAmlOpcode (
/* The opcode is unrecognized. Just skip unknown opcodes */
ACPI_ERROR ((AE_INFO,
- "Found unknown opcode %X at AML address %p offset %X, ignoring",
+ "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring",
WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));
ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128);
@@ -1149,7 +1149,6 @@ AcpiPsParseLoop (
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Invoked method did not return a value"));
-
}
ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
diff --git a/sys/contrib/dev/acpica/parser/psxface.c b/sys/contrib/dev/acpica/parser/psxface.c
index e9fc45d..52a53c9 100644
--- a/sys/contrib/dev/acpica/parser/psxface.c
+++ b/sys/contrib/dev/acpica/parser/psxface.c
@@ -120,6 +120,7 @@
#include <contrib/dev/acpica/include/acparser.h>
#include <contrib/dev/acpica/include/acdispat.h>
#include <contrib/dev/acpica/include/acinterp.h>
+#include <contrib/dev/acpica/include/actables.h>
#include <contrib/dev/acpica/include/amlcode.h>
@@ -334,6 +335,10 @@ AcpiPsExecuteMethod (
ACPI_FUNCTION_TRACE (PsExecuteMethod);
+ /* Quick validation of DSDT header */
+
+ AcpiTbCheckDsdtHeader ();
+
/* Validate the Info and method Node */
if (!Info || !Info->ResolvedNode)
diff --git a/sys/contrib/dev/acpica/resources/rscreate.c b/sys/contrib/dev/acpica/resources/rscreate.c
index 8e460d2..b5a5f62 100644
--- a/sys/contrib/dev/acpica/resources/rscreate.c
+++ b/sys/contrib/dev/acpica/resources/rscreate.c
@@ -301,7 +301,7 @@ AcpiRsCreatePciRoutingTable (
if ((*TopObjectList)->Common.Type != ACPI_TYPE_PACKAGE)
{
ACPI_ERROR ((AE_INFO,
- "(PRT[%X]) Need sub-package, found %s",
+ "(PRT[%u]) Need sub-package, found %s",
Index, AcpiUtGetObjectTypeName (*TopObjectList)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
@@ -311,7 +311,7 @@ AcpiRsCreatePciRoutingTable (
if ((*TopObjectList)->Package.Count != 4)
{
ACPI_ERROR ((AE_INFO,
- "(PRT[%X]) Need package of length 4, found length %d",
+ "(PRT[%u]) Need package of length 4, found length %u",
Index, (*TopObjectList)->Package.Count));
return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
}
@@ -328,7 +328,7 @@ AcpiRsCreatePciRoutingTable (
ObjDesc = SubObjectList[0];
if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
{
- ACPI_ERROR ((AE_INFO, "(PRT[%X].Address) Need Integer, found %s",
+ ACPI_ERROR ((AE_INFO, "(PRT[%u].Address) Need Integer, found %s",
Index, AcpiUtGetObjectTypeName (ObjDesc)));
return_ACPI_STATUS (AE_BAD_DATA);
}
@@ -340,7 +340,7 @@ AcpiRsCreatePciRoutingTable (
ObjDesc = SubObjectList[1];
if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
{
- ACPI_ERROR ((AE_INFO, "(PRT[%X].Pin) Need Integer, found %s",
+ ACPI_ERROR ((AE_INFO, "(PRT[%u].Pin) Need Integer, found %s",
Index, AcpiUtGetObjectTypeName (ObjDesc)));
return_ACPI_STATUS (AE_BAD_DATA);
}
@@ -378,7 +378,7 @@ AcpiRsCreatePciRoutingTable (
if (ObjDesc->Reference.Class != ACPI_REFCLASS_NAME)
{
ACPI_ERROR ((AE_INFO,
- "(PRT[%X].Source) Need name, found Reference Class %X",
+ "(PRT[%u].Source) Need name, found Reference Class 0x%X",
Index, ObjDesc->Reference.Class));
return_ACPI_STATUS (AE_BAD_DATA);
}
@@ -426,7 +426,7 @@ AcpiRsCreatePciRoutingTable (
default:
ACPI_ERROR ((AE_INFO,
- "(PRT[%X].Source) Need Ref/String/Integer, found %s",
+ "(PRT[%u].Source) Need Ref/String/Integer, found %s",
Index, AcpiUtGetObjectTypeName (ObjDesc)));
return_ACPI_STATUS (AE_BAD_DATA);
}
@@ -442,7 +442,7 @@ AcpiRsCreatePciRoutingTable (
if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
{
ACPI_ERROR ((AE_INFO,
- "(PRT[%X].SourceIndex) Need Integer, found %s",
+ "(PRT[%u].SourceIndex) Need Integer, found %s",
Index, AcpiUtGetObjectTypeName (ObjDesc)));
return_ACPI_STATUS (AE_BAD_DATA);
}
diff --git a/sys/contrib/dev/acpica/resources/rslist.c b/sys/contrib/dev/acpica/resources/rslist.c
index 1b73cf2..b665147 100644
--- a/sys/contrib/dev/acpica/resources/rslist.c
+++ b/sys/contrib/dev/acpica/resources/rslist.c
@@ -174,7 +174,7 @@ AcpiRsConvertAmlToResources (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Could not convert AML resource (Type %X)", *Aml));
+ "Could not convert AML resource (Type 0x%X)", *Aml));
return_ACPI_STATUS (Status);
}
@@ -232,7 +232,7 @@ AcpiRsConvertResourcesToAml (
if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
{
ACPI_ERROR ((AE_INFO,
- "Invalid descriptor type (%X) in resource list",
+ "Invalid descriptor type (0x%X) in resource list",
Resource->Type));
return_ACPI_STATUS (AE_BAD_DATA);
}
@@ -245,7 +245,7 @@ AcpiRsConvertResourcesToAml (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Could not convert resource (type %X) to AML",
+ "Could not convert resource (type 0x%X) to AML",
Resource->Type));
return_ACPI_STATUS (Status);
}
diff --git a/sys/contrib/dev/acpica/resources/rsmisc.c b/sys/contrib/dev/acpica/resources/rsmisc.c
index 37c1a05..445dea4 100644
--- a/sys/contrib/dev/acpica/resources/rsmisc.c
+++ b/sys/contrib/dev/acpica/resources/rsmisc.c
@@ -171,7 +171,7 @@ AcpiRsConvertAmlToResource (
/* Each internal resource struct is expected to be 32-bit aligned */
ACPI_WARNING ((AE_INFO,
- "Misaligned resource pointer (get): %p Type %2.2X Len %X",
+ "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
Resource, Resource->Type, Resource->Length));
}
@@ -659,7 +659,7 @@ Exit:
* "IRQ Format"), so 0x00 and 0x09 are illegal.
*/
ACPI_ERROR ((AE_INFO,
- "Invalid interrupt polarity/trigger in resource list, %X",
+ "Invalid interrupt polarity/trigger in resource list, 0x%X",
Aml->Irq.Flags));
return_ACPI_STATUS (AE_BAD_DATA);
}
diff --git a/sys/contrib/dev/acpica/tables/tbfadt.c b/sys/contrib/dev/acpica/tables/tbfadt.c
index 7f2ae36..af7d068 100644
--- a/sys/contrib/dev/acpica/tables/tbfadt.c
+++ b/sys/contrib/dev/acpica/tables/tbfadt.c
@@ -388,7 +388,7 @@ AcpiTbCreateLocalFadt (
{
ACPI_WARNING ((AE_INFO,
"FADT (revision %u) is longer than ACPI 2.0 version, "
- "truncating length 0x%X to 0x%X",
+ "truncating length %u to %u",
Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
}
@@ -521,7 +521,7 @@ AcpiTbConvertFadt (
(Address64->Address != (UINT64) Address32))
{
ACPI_ERROR ((AE_INFO,
- "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+ "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
FadtInfoTable[i].Name, Address32,
ACPI_FORMAT_UINT64 (Address64->Address)));
}
@@ -582,7 +582,7 @@ AcpiTbValidateFadt (
{
ACPI_WARNING ((AE_INFO,
"32/64X FACS address mismatch in FADT - "
- "%8.8X/%8.8X%8.8X, using 32",
+ "0x%8.8X/0x%8.8X%8.8X, using 32",
AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
@@ -593,7 +593,7 @@ AcpiTbValidateFadt (
{
ACPI_WARNING ((AE_INFO,
"32/64X DSDT address mismatch in FADT - "
- "%8.8X/%8.8X%8.8X, using 32",
+ "0x%8.8X/0x%8.8X%8.8X, using 32",
AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
@@ -621,7 +621,7 @@ AcpiTbValidateFadt (
(Address64->BitWidth != ACPI_MUL_8 (Length)))
{
ACPI_WARNING ((AE_INFO,
- "32/64X length mismatch in %s: %d/%d",
+ "32/64X length mismatch in %s: %u/%u",
Name, ACPI_MUL_8 (Length), Address64->BitWidth));
}
@@ -635,7 +635,7 @@ AcpiTbValidateFadt (
{
ACPI_ERROR ((AE_INFO,
"Required field %s has zero address and/or length:"
- " %8.8X%8.8X/%X",
+ " 0x%8.8X%8.8X/0x%X",
Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
}
}
@@ -651,7 +651,7 @@ AcpiTbValidateFadt (
{
ACPI_WARNING ((AE_INFO,
"Optional field %s has zero address or length: "
- "%8.8X%8.8X/%X",
+ "0x%8.8X%8.8X/0x%X",
Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
}
}
@@ -702,7 +702,7 @@ AcpiTbSetupFadtRegisters (
(FadtInfoTable[i].DefaultLength != Target64->BitWidth))
{
ACPI_WARNING ((AE_INFO,
- "Invalid length for %s: %d, using default %d",
+ "Invalid length for %s: %u, using default %u",
FadtInfoTable[i].Name, Target64->BitWidth,
FadtInfoTable[i].DefaultLength));
diff --git a/sys/contrib/dev/acpica/tables/tbutils.c b/sys/contrib/dev/acpica/tables/tbutils.c
index 25b0652..916c04e 100644
--- a/sys/contrib/dev/acpica/tables/tbutils.c
+++ b/sys/contrib/dev/acpica/tables/tbutils.c
@@ -349,7 +349,7 @@ AcpiTbVerifyChecksum (
if (Checksum)
{
ACPI_WARNING ((AE_INFO,
- "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
+ "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
Table->Signature, Table->Checksum,
(UINT8) (Table->Checksum - Checksum)));
@@ -395,6 +395,88 @@ AcpiTbChecksum (
/*******************************************************************************
*
+ * FUNCTION: AcpiTbCheckDsdtHeader
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
+ * if the DSDT has been replaced from outside the OS and/or if
+ * the DSDT header has been corrupted.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbCheckDsdtHeader (
+ void)
+{
+
+ /* Compare original length and checksum to current values */
+
+ if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
+ AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "The DSDT has been corrupted or replaced - old, new headers below"));
+ AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
+ AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
+
+ /* Disable further error messages */
+
+ AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
+ AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCopyDsdt
+ *
+ * PARAMETERS: TableDesc - Installed table to copy
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
+ * Some very bad BIOSs are known to either corrupt the DSDT or
+ * install a new, bad DSDT. This copy works around the problem.
+ *
+ ******************************************************************************/
+
+ACPI_TABLE_HEADER *
+AcpiTbCopyDsdt (
+ UINT32 TableIndex)
+{
+ ACPI_TABLE_HEADER *NewTable;
+ ACPI_TABLE_DESC *TableDesc;
+
+
+ TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
+
+ NewTable = ACPI_ALLOCATE (TableDesc->Length);
+ if (!NewTable)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
+ TableDesc->Length));
+ return (NULL);
+ }
+
+ ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
+ AcpiTbDeleteTable (TableDesc);
+ TableDesc->Pointer = NewTable;
+ TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+
+ ACPI_INFO ((AE_INFO,
+ "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
+ NewTable->Length));
+
+ return (NewTable);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiTbInstallTable
*
* PARAMETERS: Address - Physical address of DSDT or FACS
@@ -567,7 +649,7 @@ AcpiTbGetRootTableEntry (
/* Will truncate 64-bit address to 32 bits, issue warning */
ACPI_WARNING ((AE_INFO,
- "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+ "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
" truncating",
ACPI_FORMAT_UINT64 (Address64)));
}
diff --git a/sys/contrib/dev/acpica/tables/tbxface.c b/sys/contrib/dev/acpica/tables/tbxface.c
index 26f9472..e2eeb2e 100644
--- a/sys/contrib/dev/acpica/tables/tbxface.c
+++ b/sys/contrib/dev/acpica/tables/tbxface.c
@@ -265,6 +265,7 @@ AcpiReallocateRootTable (
{
ACPI_TABLE_DESC *Tables;
ACPI_SIZE NewSize;
+ ACPI_SIZE CurrentSize;
ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
@@ -279,9 +280,15 @@ AcpiReallocateRootTable (
return_ACPI_STATUS (AE_SUPPORT);
}
- NewSize = ((ACPI_SIZE) AcpiGbl_RootTableList.Count +
- ACPI_ROOT_TABLE_SIZE_INCREMENT) *
- sizeof (ACPI_TABLE_DESC);
+ /*
+ * Get the current size of the root table and add the default
+ * increment to create the new table size.
+ */
+ CurrentSize = (ACPI_SIZE)
+ AcpiGbl_RootTableList.Count * sizeof (ACPI_TABLE_DESC);
+
+ NewSize = CurrentSize +
+ (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC));
/* Create new array and copy the old array */
@@ -291,10 +298,16 @@ AcpiReallocateRootTable (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, NewSize);
+ ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize);
- AcpiGbl_RootTableList.Size = AcpiGbl_RootTableList.Count;
+ /*
+ * Update the root table descriptor. The new size will be the current
+ * number of tables plus the increment, independent of the reserved
+ * size of the original table list.
+ */
AcpiGbl_RootTableList.Tables = Tables;
+ AcpiGbl_RootTableList.Size =
+ AcpiGbl_RootTableList.Count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
AcpiGbl_RootTableList.Flags =
ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
@@ -534,6 +547,7 @@ AcpiTbLoadNamespace (
{
ACPI_STATUS Status;
UINT32 i;
+ ACPI_TABLE_HEADER *NewDsdt;
ACPI_FUNCTION_TRACE (TbLoadNamespace);
@@ -542,30 +556,50 @@ AcpiTbLoadNamespace (
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
/*
- * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
- * are optional.
+ * Load the namespace. The DSDT is required, but any SSDT and
+ * PSDT tables are optional. Verify the DSDT.
*/
if (!AcpiGbl_RootTableList.Count ||
!ACPI_COMPARE_NAME (
&(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
ACPI_SIG_DSDT) ||
- ACPI_FAILURE (AcpiTbVerifyTable (
+ ACPI_FAILURE (AcpiTbVerifyTable (
&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
{
Status = AE_NO_ACPI_TABLES;
goto UnlockAndExit;
}
- /* A valid DSDT is required */
+ /*
+ * Save the DSDT pointer for simple access. This is the mapped memory
+ * address. We must take care here because the address of the .Tables
+ * array can change dynamically as tables are loaded at run-time. Note:
+ * .Pointer field is not validated until after call to AcpiTbVerifyTable.
+ */
+ AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
- Status = AcpiTbVerifyTable (
- &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]);
- if (ACPI_FAILURE (Status))
+ /*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+ if (AcpiGbl_CopyDsdtLocally)
{
- Status = AE_NO_ACPI_TABLES;
- goto UnlockAndExit;
+ NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
+ if (NewDsdt)
+ {
+ AcpiGbl_DSDT = NewDsdt;
+ }
}
+ /*
+ * Save the original DSDT header for detection of table corruption
+ * and/or replacement of the DSDT from outside the OS.
+ */
+ ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
+ sizeof (ACPI_TABLE_HEADER));
+
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
/* Load and parse tables */
diff --git a/sys/contrib/dev/acpica/tables/tbxfroot.c b/sys/contrib/dev/acpica/tables/tbxfroot.c
index 021e2b6..9f955e8 100644
--- a/sys/contrib/dev/acpica/tables/tbxfroot.c
+++ b/sys/contrib/dev/acpica/tables/tbxfroot.c
@@ -227,7 +227,7 @@ AcpiFindRootPointer (
if (!TablePtr)
{
ACPI_ERROR ((AE_INFO,
- "Could not map memory at %8.8X for length %X",
+ "Could not map memory at 0x%8.8X for length %u",
ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -254,7 +254,7 @@ AcpiFindRootPointer (
if (!TablePtr)
{
ACPI_ERROR ((AE_INFO,
- "Could not map memory at %8.8X for length %X",
+ "Could not map memory at 0x%8.8X for length %u",
PhysicalAddress, ACPI_EBDA_WINDOW_SIZE));
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -284,7 +284,7 @@ AcpiFindRootPointer (
if (!TablePtr)
{
ACPI_ERROR ((AE_INFO,
- "Could not map memory at %8.8X for length %X",
+ "Could not map memory at 0x%8.8X for length %u",
ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
return_ACPI_STATUS (AE_NO_MEMORY);
diff --git a/sys/contrib/dev/acpica/utilities/utalloc.c b/sys/contrib/dev/acpica/utilities/utalloc.c
index 8c6ed0b..82f8124 100644
--- a/sys/contrib/dev/acpica/utilities/utalloc.c
+++ b/sys/contrib/dev/acpica/utilities/utalloc.c
@@ -438,7 +438,7 @@ AcpiUtAllocate (
/* Report allocation error */
ACPI_WARNING ((Module, Line,
- "Could not allocate size %X", (UINT32) Size));
+ "Could not allocate size %u", (UINT32) Size));
return_PTR (NULL);
}
diff --git a/sys/contrib/dev/acpica/utilities/utdelete.c b/sys/contrib/dev/acpica/utilities/utdelete.c
index bd6490d..f726cf9 100644
--- a/sys/contrib/dev/acpica/utilities/utdelete.c
+++ b/sys/contrib/dev/acpica/utilities/utdelete.c
@@ -539,7 +539,7 @@ AcpiUtUpdateRefCount (
default:
- ACPI_ERROR ((AE_INFO, "Unknown action (%X)", Action));
+ ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action));
break;
}
@@ -550,7 +550,7 @@ AcpiUtUpdateRefCount (
if (Count > ACPI_MAX_REFERENCE_COUNT)
{
ACPI_WARNING ((AE_INFO,
- "Large Reference Count (%X) in object %p", Count, Object));
+ "Large Reference Count (0x%X) in object %p", Count, Object));
}
}
diff --git a/sys/contrib/dev/acpica/utilities/uteval.c b/sys/contrib/dev/acpica/utilities/uteval.c
index be1e45e..c0790b4 100644
--- a/sys/contrib/dev/acpica/utilities/uteval.c
+++ b/sys/contrib/dev/acpica/utilities/uteval.c
@@ -381,7 +381,7 @@ AcpiUtEvaluateObject (
PrefixNode, Path, AE_TYPE);
ACPI_ERROR ((AE_INFO,
- "Type returned from %s was incorrect: %s, expected Btypes: %X",
+ "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
Path, AcpiUtGetObjectTypeName (Info->ReturnObject),
ExpectedReturnBtypes));
diff --git a/sys/contrib/dev/acpica/utilities/utglobal.c b/sys/contrib/dev/acpica/utilities/utglobal.c
index df32fc0..85a93fe 100644
--- a/sys/contrib/dev/acpica/utilities/utglobal.c
+++ b/sys/contrib/dev/acpica/utilities/utglobal.c
@@ -916,6 +916,7 @@ AcpiUtInitGlobals (
/* Miscellaneous variables */
+ AcpiGbl_DSDT = NULL;
AcpiGbl_CmSingleStep = FALSE;
AcpiGbl_DbTerminateThreads = FALSE;
AcpiGbl_Shutdown = FALSE;
diff --git a/sys/contrib/dev/acpica/utilities/utmisc.c b/sys/contrib/dev/acpica/utilities/utmisc.c
index 3bef62c..1075b0e 100644
--- a/sys/contrib/dev/acpica/utilities/utmisc.c
+++ b/sys/contrib/dev/acpica/utilities/utmisc.c
@@ -308,7 +308,7 @@ AcpiUtAllocateOwnerId (
if (*OwnerId)
{
- ACPI_ERROR ((AE_INFO, "Owner ID [%2.2X] already exists", *OwnerId));
+ ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId));
return_ACPI_STATUS (AE_ALREADY_EXISTS);
}
@@ -427,7 +427,7 @@ AcpiUtReleaseOwnerId (
if (OwnerId == 0)
{
- ACPI_ERROR ((AE_INFO, "Invalid OwnerId: %2.2X", OwnerId));
+ ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId));
return_VOID;
}
@@ -457,7 +457,7 @@ AcpiUtReleaseOwnerId (
else
{
ACPI_ERROR ((AE_INFO,
- "Release of non-allocated OwnerId: %2.2X", OwnerId + 1));
+ "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1));
}
(void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
diff --git a/sys/contrib/dev/acpica/utilities/utmutex.c b/sys/contrib/dev/acpica/utilities/utmutex.c
index d0d47d4..2231ab6 100644
--- a/sys/contrib/dev/acpica/utilities/utmutex.c
+++ b/sys/contrib/dev/acpica/utilities/utmutex.c
@@ -374,7 +374,7 @@ AcpiUtAcquireMutex (
else
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Thread %p could not acquire Mutex [%X]",
+ "Thread %p could not acquire Mutex [0x%X]",
ACPI_CAST_PTR (void, ThisThreadId), MutexId));
}
@@ -419,7 +419,7 @@ AcpiUtReleaseMutex (
if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
{
ACPI_ERROR ((AE_INFO,
- "Mutex [%X] is not acquired, cannot release", MutexId));
+ "Mutex [0x%X] is not acquired, cannot release", MutexId));
return (AE_NOT_ACQUIRED);
}
diff --git a/sys/contrib/dev/acpica/utilities/utobject.c b/sys/contrib/dev/acpica/utilities/utobject.c
index f3ec792..f83c86b 100644
--- a/sys/contrib/dev/acpica/utilities/utobject.c
+++ b/sys/contrib/dev/acpica/utilities/utobject.c
@@ -354,7 +354,7 @@ AcpiUtCreateBufferObject (
Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
if (!Buffer)
{
- ACPI_ERROR ((AE_INFO, "Could not allocate size %X",
+ ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
(UINT32) BufferSize));
AcpiUtRemoveReference (BufferDesc);
return_PTR (NULL);
@@ -413,7 +413,7 @@ AcpiUtCreateStringObject (
String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
if (!String)
{
- ACPI_ERROR ((AE_INFO, "Could not allocate size %X",
+ ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
(UINT32) StringSize));
AcpiUtRemoveReference (StringDesc);
return_PTR (NULL);
@@ -671,7 +671,7 @@ AcpiUtGetSimpleObjectSize (
* required eventually.
*/
ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
- "unsupported Reference Class [%s] %X in object %p",
+ "unsupported Reference Class [%s] 0x%X in object %p",
AcpiUtGetReferenceName (InternalObject),
InternalObject->Reference.Class, InternalObject));
Status = AE_TYPE;
@@ -683,7 +683,7 @@ AcpiUtGetSimpleObjectSize (
default:
ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
- "unsupported type [%s] %X in object %p",
+ "unsupported type [%s] 0x%X in object %p",
AcpiUtGetObjectTypeName (InternalObject),
InternalObject->Common.Type, InternalObject));
Status = AE_TYPE;
diff --git a/sys/contrib/dev/acpica/utilities/uttrack.c b/sys/contrib/dev/acpica/utilities/uttrack.c
index 5c48544..ddb35ef 100644
--- a/sys/contrib/dev/acpica/utilities/uttrack.c
+++ b/sys/contrib/dev/acpica/utilities/uttrack.c
@@ -282,7 +282,7 @@ AcpiUtAllocateZeroedAndTrack (
/* Report allocation error */
ACPI_ERROR ((Module, Line,
- "Could not allocate size %X", (UINT32) Size));
+ "Could not allocate size %u", (UINT32) Size));
return (NULL);
}
@@ -715,7 +715,7 @@ AcpiUtDumpAllocations (
else
{
ACPI_ERROR ((AE_INFO,
- "%d(%X) Outstanding allocations",
+ "%d(0x%X) Outstanding allocations",
NumOutstanding, NumOutstanding));
}
diff --git a/sys/contrib/dev/iwn/LICENSE b/sys/contrib/dev/iwn/LICENSE
index 74a3f7e..82165b8 100644
--- a/sys/contrib/dev/iwn/LICENSE
+++ b/sys/contrib/dev/iwn/LICENSE
@@ -1,39 +1,39 @@
-Copyright (c) 2006-2009, Intel Corporation.
+Copyright (c) 2006-2010, Intel Corporation.
All rights reserved.
-Redistribution. Redistribution and use in binary form, without
-modification, are permitted provided that the following conditions are
+Redistribution. Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
met:
-* Redistributions must reproduce the above copyright notice and the
- following disclaimer in the documentation and/or other materials
- provided with the distribution.
-* Neither the name of Intel Corporation nor the names of its suppliers
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-* No reverse engineering, decompilation, or disassembly of this software
+* Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
is permitted.
-Limited patent license. Intel Corporation grants a world-wide,
-royalty-free, non-exclusive license under patents it now or hereafter
-owns or controls to make, have made, use, import, offer to sell and
-sell ("Utilize") this software, but solely to the extent that any
-such patent is necessary to Utilize the software alone, or in
-combination with an operating system licensed under an approved Open
-Source license as listed by the Open Source Initiative at
-http://opensource.org/licenses. The patent license shall not apply to
-any other combinations which include this software. No hardware per
+Limited patent license. Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses. The patent license shall not apply to
+any other combinations which include this software. No hardware per
se is licensed hereunder.
-DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
-COPYRIGHT OWNER 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
+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+COPYRIGHT OWNER 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.
diff --git a/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu b/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
deleted file mode 100644
index 636a7ba..0000000
--- a/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
+++ /dev/null
@@ -1,8112 +0,0 @@
-Copyright (c) 2006-2009, Intel Corporation.
-All rights reserved.
-
-Redistribution. Redistribution and use in binary form, without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions must reproduce the above copyright notice and the
- following disclaimer in the documentation and/or other materials
- provided with the distribution.
-* Neither the name of Intel Corporation nor the names of its suppliers
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-* No reverse engineering, decompilation, or disassembly of this software
- is permitted.
-
-Limited patent license. Intel Corporation grants a world-wide,
-royalty-free, non-exclusive license under patents it now or hereafter
-owns or controls to make, have made, use, import, offer to sell and
-sell ("Utilize") this software, but solely to the extent that any
-such patent is necessary to Utilize the software alone, or in
-combination with an operating system licensed under an approved Open
-Source license as listed by the Open Source Initiative at
-http://opensource.org/licenses. The patent license shall not apply to
-any other combinations which include this software. No hardware per
-se is licensed hereunder.
-
-DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
-COPYRIGHT OWNER 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.
-begin-base64 644 iwlwifi-6000-9.176.4.1.fw.uu
-AQSwCds9AAAUQwIAAEABAKhBAgAAQAEAAAAAACAggA8AAEAAaSAAAGkgQABpIAAAaSBAACAggA8A
-AOgAaSAAAGkgQABpIAAAaSBAACAggA8AAHgGaSAAAGkgQABpIAAASiAAAEohAABKIgAASiMAAEok
-AABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBKJgAQSicAEEogACBKIQAgSiIA
-IEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/gQAAQEEsnDBALJwwQiQcNAoigD+AADBr
-CiMAN/4PAABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgABkBEB4ICBAhwAAAAAAAAAAAADh
-wOHB4cLPcKAAyB8WEAGGz3KAAJh/IKISEAGGIaITEAGGIqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8A
-uP9WoYoh/w8SGFiAExhYgBQYWIAVGFiAJBhYgMHCwcHBwCAgQIcMyM9yoADIHw4aGIANyA8aGIAO
-yBAaGIAPEgE2AcgkeBEaGIAQyC0aGIDgfuHE/BzIvvwcSL7hwOHB4cLhw/wcCLH8HEix/ByIsfwc
-yLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDhxPHAz3CgANAbFIDPcYAAYAQEIICPz1EE
-4QChCvIvKQEAz3CAAOQN8CBAAEB42v/RwMHEayTAEMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0
-BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZAfsHEaySAFMHEICBAhwzIh7gMGhgwDcib
-uA0aGDAOyA4aGDAPyIe4DxoYMBDIEBoYMOB+4HjxwAzIlbgMGhgwDcibuA0aGDAPyIq4jbiQuA8a
-GDDPcIAAHA8YiIHgC/QPyM9xAAC0DKy4DxoYMFYOIAAP2GfYNgsgAYohBgrRwOB+8cDPcIAAsK8A
-gIYg/oEJ9A/IBSCADwAAANQPGhgwof+KIFUFBgsgAYohRg7o8eB4z3EDAEANz3CgAKggLaDPcYAA
-jARAgQFqAKHPcKAAOC4FgAQggA/AAAAA13DAAAAACvJI2M9xnwC4/xqhW6Fp2Bi4GaHPcIAAeAgl
-gCOBIIHHcQAAiBMNA8AJ4HjPcIAAeAidAsAJ4HjxwB4MAAGA4M93gABgBIh1BfKB4AX0AdgC8ADY
-C6+A4QXygeEF9AHYAvAA2AqvgOIF8oHiBfQB2ALwANgMrwDYz3agAMgfGB4YkAuPgOCKIRAAD/II
-j4DgC/LPcAMAQA1FHhgQMKYC2BgeGJAC8DGmCo+A4BnyCY+A4Bfyz3ACABRDIB4YkM9wgAAoACEe
-GJDPcIAAXAQiHhiQGBYAlkUgAAMYHhiQDI+A4AjyGBYAloUgAQQYHhiQgeMH9BgWAJaIuBgeGJDP
-cIAAMHQAkI7gzCCiggb0GBYAloC4GB4YkIDlGfIA2JS4z3WAAIAEAKVx2Aa4Zg0gAfzZIIXPcAAA
-TBxaDSABn7kYFgCWhbgYHhiQdQMAAeB4z3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFp
-IEAA/vHgePHApcFBwELBDBwAMRAcQDHPcYAAfGw0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8bCAY
-QAvPcIAAfGwcGAALz3CAAHxsGBjACs9wgAB8bBQYgArPcIAAfGwQGMAIz3CAAHxsDBiACM9wgAB8
-bAgYQAjPcYAAAGyAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
-QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
-ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
-gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybF
-Nde6AebTvsSgUyPABAUmjh/Q/gAA1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYw
-GgggARAUBzDPcKAAtA+8oM9xoADIOy6Bsg/gAH3YMg9AAboLIAGpcAjYANlmCyABmbnPcIAAMHQA
-kI7gzCCigsoggQ/gAMQxyiEhAJAIYQHPIaEF/QXP//HA1gggAXvYag/gAOHZz3GAAHxsNBnADzAZ
-AA8sGcAOKBmADiQZQA7PcIAAfGwgGEALz3CAAHxsHBgAC89wgAB8bBgYwArPcIAAfGwUGIAKz3CA
-AHxsEBjACM9wgAB8bAwYgAjPcIAAfGwIGEAIz3GAAABsgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAH
-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
-AAuEGkALz3CgAMgcCICIGgAAz3CAAIAFAICMGgAAqCCAAvAiQwDPcJ8AuP8B4XagmQAAAPwciLb8
-HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wciLP8HEiz4H7geATc
-ON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/DgeATcIN0p8OB4BNwc
-3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4BNwE3RnwNBQaMDAU
-GTAsFBgwKBQXMCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHGsCRNM7AkHzPgfvHAz3GA
-AJAMEKHgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjRwOB+
-4HjhxeHGQCkNAiV9QC0DFIjipXsIdZD3UyV+kAbyAR1SEGG6+/FBKo4AwbpCJk6QBB3QEP31gOIK
-8i8kiXDgeKgggAEBHVIQ4HjBxuB/wcXgeChyANnW8eB48cCuDs//ocEId892oACsLxmGBCCAD3AA
-AADXcCAAAAAB2MB4LyYH8Ch1GnIT9IogSQb2DO//iiFNBDmG6gzv/4ogCQaKIAkG3gzv/6lxANgk
-8BHMABxEM08gwQMB4BB4BCCADwAA/7+PuAIcRDARGhwwRgmgD0AnABIH5wQnjx8AAPz/BScAFJ24
-n7jscQChAMHscCCgAdh5Bu//ocDgeCK5BvDscmCiBOBhuYHhYIA69wDZz3CgANQLbaDPcKAARB01
-oOB+4HjxwO4Nz/8Idih1KHBIcWhyyv+B4MoggQPAD+H/yiFBAzkGz//hxc9ygACwBKSKgOXPcp8A
-uP8G8s9z0Lr+yn6iGqI7ooDlDvLPcKAAOC4FgAQggA/AAAAA13DAAAAA9vNp2Bi4GaLgf8HF4Hjx
-wH4Nz/8Id89xgACwBAWJAN6A4KnBQMZD9AHdpanPcYAAgHbPcKAAzCstoADYj7gRGhwwIRqCM34I
-IA2LcCoJAAjPcAEAsAlBwIogUABCwM9wgAD8YgCIZMUC3REcAjAAwBIcQjMTHAIwz3CAAFQQRcDP
-cIAAwA9GwM9wgACABQCAQ8Yg2QHaR8BIx4HAPdsXu8H/CNgB2cj/BBpYM0kF7/+pwAPaz3GgABQE
-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
-8cAAFgBBz3KAAARLBrIAFgVBQCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOCDwAAcwBEBaLvyiQi
-AADaB/AAFgBBFCGMAAC0AeIvIEIBEHK39lIMz/DRwOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
-4HjgfuB44H7geOB+4HjPcIAA6AfgfwCA4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
-eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
-4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY4H7geOB+4Hjg
-fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB48cD+Do/w
-GnHPd4AAREsgj1EhAIBG8s9xgADwByCJgOHMICGgPvKB4Ab0z3CAALicoYAD8ADdjuUD94DlAvQA
-3c9xgAC4nBiJgOAE9IDlBPQA3gTwooEE3oogEwEaDa/wqXGKIFMBEg2v8Mlxz3CAABwPGIiD4Mwg
-IoHMIOKBzCAiggjyiiATAe4Mr/Cl2QrwCpcQdQj0C5cQdswgIaAE9ADYIfAB2M9xoADIHw2hz3CA
-APAHAYjLt6q3BL4QuMV9BX2KIBMBsgyv8LzZiiATAaYMr/Cpcc9woADIH38YWIMB2IEGj/DgePHA
-Gg6v8AhxxP+A4DzyIN3PdqAAyB+wpjLYQx4YEADY8gnv8I24saawph7YQx4YEADY4gnv8I24saZ/
-Fg+WiiATAUEvDRTEvUYMr/Dm2YogEwE+DK/w6XGKIBMBMgyv8Klxz3GAAPAHAYkB2hB1wiKKAIDl
-QKnI9gDYDaaB4gT0BNgBqf0Fj/Dhxc9ygABESyCKAN3guWTYyiBBA+G5z3OgAMAdBqIJ8gzYAKMB
-ggOiAoIEogTwoKOjoqSiz3CAABwPCYBRIECB0SGigATyAIOAuACj4H/BxfHA4cUA3c9woADAHaCg
-qXCpcYz/z3CAAERLo6CkoJ0Fr/CmoIDgz3GAAERLBPRAIQADBPBAIQAEAIDPcaAAwB1RIACAAIHP
-IOIA0CDhAACh4H7gePHA8gyv8APZz3aAAERLdgnv8MlwoI5EJUARheAM9AohwA/rcgXYadtKJEAA
-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
-QgITMAQowBEPFBUiAQAVJg9yEyIIAMwRD0QAIgoAAEAAQABwDgAAYQAAEyUCABMk7BzAEQ92EyIY
-CMoRCQATQBwIyhEJABNAIAjKEQ94EyIEAMoRAAABJAAAASUGAABhD3YTIixIxxEPeBMiAADGEQMA
-ASQAAAElAAATJcIsEyQEKMARAkYTJAQowBHCXxMkBCjAEQ9FACIAXAA5JwAAZAAAEyQBABMlOBzA
-EQ93EyLgHMARDwETIgQIwBEPAhMiBCjAEQ8HEyIEKMARDwQTIgQowBECAHFwBwAAYf8AEyUCEBMk
-BCjAEQAAEyUAABMkyEnHEQYAAGEAABMlAhATJAQowBEAABMlSQATJMhJxxEPcBMiAQATMAQowBED
-ABMkAAATJQQIwBEAABMkOEXAEQ8DEyIYKMARBAAAYQAAWDgAABMkAQATJTgcwBEAAAAhnGuAgQAA
-wBY8BMARMAWAgQAAwBYEARtiEATAEAMAGyRUBMARJATAEQgEwBBca4CBAADAFwgEwBA4a4CBAADA
-FwAAGyUDHBtiQAAbJDAcwBEFAABhNAWAgQAAwBYPGxkiCASggTjwxIAAABskAgAbJTgcwBEAAAAh
-MAWAgQAAwBZMBMARNAWAgQAAwBYPGxkiSASggTjwxIAAABskAgAbJTgcwBEAAAAhAAAAhTAFgIEA
-AMAWDxsEIhAEG2YPARtoFBzAEAoAG0AEABtuAwAAYQ8cHSIBAB0m+Q8AYWQMABAAwAYRAQAEJ/wA
-BGQAABskAgAbJTgcwBEAAAAhAAAbJUAAGyQwHMARAAAAIQ8cHSIYAR0mGADHEPySgIEAAMAXIADH
-EASTgIEAAMAXAAAAIXwxgIECAFxuEQAAYfhBxBAPGwkiAAsJOQIACmIDAQpiBAIKYgAACUAEAABh
-CQAJQAIAAGEKAAlAAAAAYQIACUEACRooAADAFgEAGyYAAMAXBAAdJgEACCfpAAhkAAAAIQAAAACM
-AQAAAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsOQAAODsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAABSEgAAAAAAAAAAAAAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-wACQANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAADIkoAAAAAAAAAAAABAl4AA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAiJyAACycAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMisgACY9gEAAAAA
-AAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIkoAAhP8BAAAAAADIkoAA
-UAYCAAAAAAAAAAAAyJKAAOgHAgAAAAAAAAAAAAAAAADIkoAAAAAAAAAAAAAAAAAA/wAAAAAHAAAA
-AAAAAAAAABgbAgAYGwIAGBsCABwbAgAAAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAQIECAAIECAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADECAAAFQAAANQtgAA4KwAAOCsAADgrAAAMQgAA
-OCsAADgrAABYPQAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAArB4AAFwgAAB0
-IAAA5CEAAGwiAADoIQAAOCsAADgrAACATgAASFAAADRRAAA4KwAAOCsAADgrAAD8TAAAFGQAABBk
-AABoZAAAOCsAADgrAAA4KwAAGEQAADgrAABMZAAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsA
-ADgrAAAQQgAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAA
-OCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAAIRQAAOCsAADgrAAA4
-KwAAOCsAADgrAADwRQAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgr
-AABQawAAOCsAAHhsAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAACBvAAA4KwAAOCsA
-ADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAAMyAAQAkhAEAOCsAAHiGAQA4KwAA
-KIgBABRUAQA4KwAAOCsAAABSAAA4KwAAOCsAADgrAAA4KwAAOCsAADzeAQDE8QEAOCsAADgrAAA4
-KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAACsGAIAOCsAADgrAAA4KwAA2P0BADgr
-AADUAQIAOCsAAPwpAgA4KwAAoCUAAKQlAAA4KwAAOCsAAIgSAgBMcgAAOCsAADgrAAA4KwAAfPsB
-ADgrAAA4KwAAWE0BAAygAQA4KwAAOCsAADgrAAD8qAEANFUBADgrAAA4KwAAOCsAADgrAAA4KwAA
-OCsAALSzAQA4KwAAgA8CAIQPAgCQDwIAlA8CAIgPAgCMDwIAmA8CADgrAAA4KwAAOCsAADgrAAA4
-KwAAOCsAADgrAAA4KwAAOCsAAPBTAAA4KwAAOCsAADgrAAA4KwAAOCsAANQOAgAkDwIAEEgAADgr
-AAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsA
-ADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAA
-OCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAACQSQAAGEoAAKxKAABgSwAAJIEAADhLAAA4
-KwAAOCsAADgrAAA4KwAAOCsAAIhJAACMSQAAOCsAADgrAAAwUgAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwM
-AACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwA
-AIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAAC8DQAAAAAAALxaAQCMDAAAnAkAAIwMAACMDAAA
-jAwAAMwJAADoPAEAZIMAAIwMAACMDAAABAoAAAQKAAAECgAABAoAAAQKAAAECgAABAoAAIwMAACM
-DAAAjAwAAIwMAAD8CwAAjAwAAIwMAACMDAAAjAwAAIwMAADADQAAjAwAAIwMAACACQAAAwAAAJwM
-AgACAAAA6GgBAAQAAACcaQEABQAAANwNAAAGAAAAIDQAAAgAAAAADwIAEwAAACz4AQAJAAAAgAMC
-AAoAAACcDwIADgAAABSdAQAPAAAAYIoBABAAAACYigEAGAAAACRaAQANAAAAEIIBABcAAABIcgAA
-EQAAAKSBAAASAAAAWEwBAAEAAABY/QEAFAAAAMCwAQAVAAAAQKABAAcAAACQbwAAFgAAAOwpAgAZ
-AAAAvA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAA
-ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e
-4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7hPDw8PDw8PDw8PDw8PDw8PDw8PDw8
-PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8
-PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8
-PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAA
-kAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQ
-BgAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMF
-AAAx+q8AQwUAADH6rwAAAAAA3sMJAAAAAAAAAAAAAAAAALQqAQABAAAAlC2AAAAAAAAAAAAAAAAA
-AFQrAQAVAAAA1C2AAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAAAwjBEAIL8CAAAAAADIKwEA
-cCwBAHQtAQAgLwEAdC0BACAvAQDQMAEAWDEBALgxAQCAgICAgICAgAGAAoCAgICAAAAAALg3AQC4
-NwEAAAAAAAAAAAAAAAAAAAAAALg3AQC4NwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJQt
-gACULYAApCCgADggoAABAAAA/P///wAAAAAAAAAAtC2AALQtgACoIKAAPCCgAAgAAADz////AAAA
-AAAAAADULYAA1C2AAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
-AAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAbE0BAAUAAADULYAAwFIBAAD/AwDgUgEAAP8FAMxTAQAA
-/y0A8FMBAAD/PQCoUwEAAP8EAIxTAQAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAABgWQEABgAAAJQtgAAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAAAAAA
-vGABALxhAQA4YgEAQF0BAGhcAQBoYwEA8GMBADRkAQCIZAEAAAAAAAMAAAACAAAAAwAAAAMAAAAD
-AAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAbGoBAAoAAACULYAAAAAAAAAAAAAAAAAA+GoBAAoA
-AACULYAAAAAAAAAAAAAAAAAArGsBAAoAAACULYAAAAAAAAAAAAAAAAAAzGwBAAoAAACULYAAAAAA
-AAAAAAAAAAAAMGsBAAoAAACULYAAAAAAAAAAAAAAAAAARGwBAAoAAACULYAAAAAAABAAAAAAgAAA
-AACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAK
-AAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAA
-AAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAA
-APg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAA
-lC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAA
-AAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAASGAQAKAAAAlC2AAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4jQEAhI4BAHCRAQAklAEApJYBACiaAQA0kAEARAWAAJCS
-gAAYAAAAUJKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvJwBAAYAAACULYAA/////wAAAAD/////////
-/wAAAAAAAAAAAAAAAJyfAQAFAAAA1C2AAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDAAKAA
-UACAAL4AUAF9AD4AAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIBAQACAQABAgICAAEB
-AAIBAgECAAIAAQID//8AALkB3wCxABsAFgEbAHwBGwCvABsAFAEbAHoBGwBsAKAA0QCgADcBoABv
-AIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDUAQYA0AEAAH4APADjADwASQE8AHgA
-SQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABABAQB1AT8AdgEBAHkAagDeAGoARAFq
-AKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEBAAQACACcAcwAnQHMAJ4BzACfAcwA
-1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIAoQCIAAYBiABsAYgAlAAAAJUAAACY
-AMAAmQCgAJYAkACXAAAAlAABAJUAAQCYAMAAmQCgAJYAkACXAAAAlAACAJUAAwCYAMAAmQCgAJYA
-kACXAAAAlAADAJUABwCYAMAAmQCgAJYAkACXAAAA+gAAAPkAAAACAZAAAwHTAAABgwD+ABMA/AAz
-AP0AdwD6AAEA+QABAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAgD5AAMAAgGQAAMB0wAAAYMA
-/gATAPwAMwD9AHcA+gADAPkABwACAZIAAwHTAAABgwD+ABMA/AAzAP0AdwBfAQAAYQEAAGgBkABp
-AdMAZgGDAGQBEwBiATMAYwF3AF8BAQBhAQEAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcAXwECAGEB
-AwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQMAYQEHAGgBkABpAdMAZgGDAGQBEwBiATMAYwF3
-AIUAAACGAAAAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQABAIYAAQCHAFAAiAAAAIkAoACKAAAA
-iwDQAIwAAACFAAIAhgADAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAIUAAwCGAAcAhwBQAIgAAACJ
-AKAAigAAAIsA0ACMAAAA6wAAAOoAAADsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAEA6gABAOwA
-UADtAAAA7gCgAO8AAADwANAA8QAAAOsAAgDqAAMA7ABQAO0AAADuAKAA7wAAAPAA0ADxAAAA6wAD
-AOoABwDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAABRAQAAUAEAAFIBUABTAQAAVAGgAFUBAABWAdAA
-VwEAAFEBAQBQAQEAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQECAFABAwBSAVAAUwEAAFQBoABV
-AQAAVgHQAFcBAABRAQMAUAEHAFIBUABTAQAAVAGgAFUBAABWAdAAVwEAAPv/AAD//wAAuQHfALEA
-GwAWARsAfAEbAK8AGwAUARsAegEbAGwAoADRAKAANwGgAG8AgwBxAIMAdgCDAHMAMwBuADMAcAAz
-AHIAMwDXADMAPQEzANQBBgDQAQAAfgA8AOMAPABJATwAeABJAN0ASQBDAUkAfwBaAOQAWgBKAVoA
-qgA/AKsAAQAPAT8AEAEBAHUBPwB2AQEAeQBqAN4AagBEAWoAqAAAAA0BAABzAQAApgA3AKcAAQAL
-ATcADAEBAHEBNwByAQEABAAIAJwBzACdAcwAngHMAJ8BiADVAcwA1gHMANcBzAC0AEcAGQFHAIAB
-RwCQACIA9QAiAFsBIgChAIgABgGIAGwBiAD6AAAA+QAAAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3
-APoAAQD5AAEAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gACAPkAAwACAZcAAwHQAAABjQD+ABEA
-/AAzAP0AdwD6AAMA+QAHAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3AF8BAABhAQAAaAGXAGkB0ABm
-AY0AZAERAGIBMwBjAXcAXwEBAGEBAQBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQIAYQEDAGgB
-lwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAwBhAQcAaAGXAGkB0ABmAY0AZAERAGIBMwBjAXcA6wAA
-AOoAAADsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAEA6gABAOwAVQDtAAAA7gCqAO8AAADwAN0A
-8QAAAOsAAgDqAAMA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAA6wADAOoABwDsAFUA7QAAAO4AqgDv
-AAAA8ADdAPEAAABRAQAAUAEAAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAQBQAQEAUgFVAFMB
-AABUAaoAVQEAAFYB3QBXAQAAUQECAFABAwBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABRAQMAUAEH
-AFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAPv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAcswEAINQBAPScgABABQAAAAAAAByzAQBItAEANKKAAPgBAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAD42AEA/NYBACykgABUAAAAAAAAAByzAQAs1wEArKSAAFABAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAEAAAAcswEAQNMBAEA/gABQAQAAAAAAAByzAQBY1QEA8AaAAAIAAAAAAAAA
-HLMBALDVAQD0BoAABAAAAAAAAAD02AEASLQBAICkgAAqAAAAAAAAAByzAQBM1gEAAAAAAAAAAAAA
-AAAAHLMBAAzWAQD4BoAABAAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkA
-CgAKAAsADAAMAA0ADgAOAA8AJgAnACgAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBq
-AGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAdAB0AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA
-dQB1AHUAdQB1AHUADwA/AAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAK
-AAoACwAkACQAJQAmACYAJwBEAEQARQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBqAGoAawBsAGwA
-bQBuAG4AbwBwAHAAcQByAHIAcwB0AHQAdQB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2
-AHYAdgB2AHYADgA/AESmAQAS0gAAAAAAAP//DwBwwgEAtgAAAAAAAAD/AAAAcMIBALcAAAAAAAAA
-/wAAAHDCAQC4AAAAAAAAAP8AAABwwgEAuQAAAAAAAAD/AAAAcMIBALoAAAAAAAAA/wAAAHDCAQC7
-AAAAAAAAAP8AAABwwgEAvQAAAAAAAAD/AAAAcMIBAL4AAAAAAAAA/wAAAHDCAQC/AAAAAAAAAP8A
-AABwwgEAwAAAAAAAAAD/AAAAcMIBAMEAAAAAAAAA/wAAAHDCAQDCAAAAAAAAAP8AAABEpgEAE9IA
-AAAAAAD//w8AcMIBABsBAAAAAAAA/wAAAHDCAQAcAQAAAAAAAP8AAABwwgEAHQEAAAAAAAD/AAAA
-cMIBAB4BAAAAAAAA/wAAAHDCAQAfAQAAAAAAAP8AAABwwgEAIAEAAAAAAAD/AAAAcMIBACIBAAAA
-AAAA/wAAAHDCAQAjAQAAAAAAAP8AAABwwgEAJAEAAAAAAAD/AAAAcMIBACUBAAAAAAAA/wAAAHDC
-AQAmAQAAAAAAAP8AAABwwgEAJwEAAAAAAAD/AAAARKYBABTSAAAAAAAA//8PAHDCAQCCAQAAAAAA
-AP8AAABwwgEAgwEAAAAAAAD/AAAAcMIBAIQBAAAAAAAA/wAAAHDCAQCFAQAAAAAAAP8AAABwwgEA
-hgEAAAAAAAD/AAAAcMIBAIcBAAAAAAAA/wAAAHDCAQCJAQAAAAAAAP8AAABwwgEAigEAAAAAAAD/
-AAAAcMIBAIsBAAAAAAAA/wAAAHDCAQCMAQAAAAAAAP8AAABwwgEAjQEAAAAAAAD/AAAAcMIBAI4B
-AAAAAAAA/wAAAESmAQAI0gAAAAAAAP//AwCEpgEAAIIAAAAAAAD/AQAAhKYBAAGCAAAAAAAA/wEA
-AESmAQAJ0gAAAAAAAP//AwCEpgEAAoIAAAAAAAD/AQAAhKYBAAOCAAAAAAAA/wEAAESmAQAK0gAA
-AAAAAP//AwCEpgEABIIAAAAAAAD/AQAAhKYBAAWCAAAAAAAA/wEAAESmAQAG0gAAAAAAAP8BAABE
-pgEAB9IAAAAAAAD/AwAARKYBAAbSAAAJAAAAAP4DAESmAQAH0gAACgAAAAD8DwBEpgEABtIAABIA
-AAAAAPwHRKYBAAfSAAAUAAAAAADwP0SmAQAV0gAAAAAAAP8DAABEpgEADNIAAAAAAAD/AQAARKYB
-ABXSAAAKAAAAAPwPAESmAQAM0gAACQAAAAD+AwBEpgEAFdIAABQAAAAAAPA/RKYBAAzSAAASAAAA
-AAD8BzCAAACqqqqqMYAAAKqqqqoygAAAAKqqqjOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaAAAAA
-AAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAAAKqq
-CgA+gAAAqqqqqj+AAACqqqqqQIAAAAAAAAAwgAAAqqqqqjGAAACqqqqqMoAAAACqqqozgAAAAAAA
-ADSAAAAAAAAANYAAAAAAAAA2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAAAAAA
-O4AAAAAAAAA8gAAAAAAAAD2AAACqqgoAPoAAAKqqqqo/gAAAqqqqqkCAAAAAAAAAMIAAAAAAAAAx
-gAAAAAAAADKAAAAAAAAAM4AAAAAAAAA0gAAAqqqqqjWAAACqqqqqNoAAAAAAAAA3gAAAAAAAADiA
-AAAAAAAAOYAAAAAAAAA6gAAAqqqqCjuAAACqqqqqPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAAP4AA
-AAAAAABAgAAAAAAAADCAAAAAAAAAMYAAAAAAAAAygAAAAAAAADOAAAAAAAAANIAAAKqqqqo1gAAA
-qqqqqjaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAKqqqgo7gAAAqqqqqjyAAAAA
-AAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAAQIAAAAAAAABEBYAAkJKAABgAAABQkoAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAsPMBAAYAAACULYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAABEBYAAkJKAABgAAABQkoAAAAAAAAAAAAAAAAAAAAAAAAAAAABU
-/wEABgAAAJQtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAEQFgACQkoAAGAAAAFCSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2A
-AAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAA
-AAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAE
-AAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAA
-AAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAA
-AKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAA
-lC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAEQFgACQ
-koAAGAAAAFCSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAFAUAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQEBQYH
-CAgICAgJCgsMDQAAAAUGBwgNDg8QFRYXGBkAAAoNERQKDREUGRkZGQoKAAAAAAAABgYGBgkJCQkA
-BgAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bitoK2IrXCtuKmgqYipcKm4paCliKVwpbhtoG2Ib
-XBtuGmgaYhpcGm4ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24WaBZiFlwWbhVoFWIVXBVuFGgUYhRc
-FG4TaBNiE1wTbhJoEmISXBJuEWgRYhFcEW4QaBBiEFwQVxBSEE0QSRBuAWgBYgFcAW4AaABiAFwA
-bjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChu
-J2gnYidcJ24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24G
-aAZiBlwGbgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAAAAA
-AAAAAAAAAAAALCwCAAgAAADULYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAA/////////wAB//8CA////wT//////////////////////wX/Bv8H/wj/Cf8K/wv/
-DP///w3///8O////D////xD//////////////////////////////////////////////xH///8S
-////E////xT///8V////Fv///xf///8Y////Gf///xr///8b/////xz///8d////Hv///x////8g
-////If//////////////////////IiMk/yUmJ///KP///yn/////////////////////////////
-/////////////////////////////////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQA
-BgkFAAcKBgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUAABAJBAQQDQgIEBEMDBAVEBAQG
-RQUEB0YGBAhHBwQJSAgEtxMiALgUIwC5FSQAuxYlALwXJgC9GCcAwBkoAMQaKQAHGwAACBwBAAsd
-AgAMHgMAEB8EACIhBQAkIgYAJiMHACgkCAAqJQkALCYKAC4nCwAwKAwANCkNADgqDgA8Kw8AQCwQ
-AGQuEQBoLxIAbDATAHAxFAB0MhUAeDMWAHw0FwCANRgAhDYZAIg3GgCMOBsAkTocAJU7HQCZPB4A
-nT0fAKE+IAClPyEAJEkGAixKCgI0Sw0BPEwPAWRNEQFsThMBdE8VAXxQFwGEURkBlVIdAZ1THwEA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQYCBgYGAwYGBgYGBgYEAAAAAAPAD8AAQAA
-AA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAgAAAA8APwABAAAA
-AAAAAAEAAAACAAAAAwAAAAAAAAAEAAAAAgAAAAUAAAAPFBkeKAoFALAJAaUAPDg0MCwoJCAcGBQQ
-DAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQCCAAOAAAADgEBAAECAQEBAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClxoT4me6N9g3/vdax3lSRUGADAqnOfVYZ52K1
-5k2a7EWPnR9AiYf6Fe/rssmOC/vsQWez/V/qRb8j91OW5FubwnUc4a49akxabEF+AvVPg1xo9FE0
-0Qj5k+Jzq1NiPyoMCFKVZUZenSgwoTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsSnh10WC40LTay3O60
-+1v2pE12YbfOfXtSPt1xXpcT9aZouQAALMFgQB/jyHnttr7URo3ZZ0ty3pTUmOiwSoVruyrF5U8W
-7cWG15pVZpQRz4oQ6QYEgf7woER4uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3da9jQjAgGuUO/W2/
-TIEUGDUmL8PhvqI1zIg5LleT8lWC/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSrO4MLyowpx9NrPCh5
-p+K8HRZ2rTvbVmROdB4U25IKDGxI5Lhdn26970OmxKg5pDE304vyMtVDi1lut9qMAWSx0pzgSbTY
-+qwH8yXPr8qO9OlHGBDVb4jwb0pyXCQ48VfHc1GXI8t8oZzoIT7dltxhhg2FD5DgQnzEcarM2JAF
-BgH3Ehyjwl9q+a7QaZEXWJknOrknONkT67MrMyK70nCpiQenM7YtIjySFSDJSYf/qnhQeqWPA/hZ
-gAkXGtplMdfGhLjQw4KwKXdaER7Le/yo1m06LAEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwQEBAQE
-BAQEAQICAgICAgMDAwMDAwMDAwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAEBAgEC
-AgN//wcPHz8BAwEDDwcBBw8fP3///wUABwIDBAYGdNFFF+iiiy4NDwUHCQsBAwoUN25VVVUBS2gv
-AVVVVQXjOI4DqqqqAnEcxwGqqqoKx3EcBw8PDwcGBwIDBAUAAQgJCwooACgAMAAsACwAKAA8ADQA
-KAAoADQAMAAsACwARAA8AEAAPACMAGwAWABIAPQAsAAsACwAPAA0ADAALABUAEQAVABUAGwAYABc
-AFQAjAB4ADoBAgHVAN8A2gCiAHUAfwBqARoB2QDoAAoBugB5AIgAigUqAzkBqAGKBcoC2QBIAcoB
-SgHiAPkAygHqAIIAmQD0AkQCtQHVAZQChAH1AEECrACQAIQAgAB4AHgAeAB0AGbmAACd2ImdTuzE
-TjRIgzQndmInGqRBGhM7sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3YCQiMwAgHfuAH
-NEiDNBqkQRoRGIERDdIgDQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJBmmQBsRO7AQE
-RmAEAz/wA6qqqqoapEEaEzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N0iANC7RACwu0
-QAuJndgJDdIgDQqogAoKqIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3SIA0LtEALiZ3Y
-CQiMwAiJndgJCIzACAd+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQBrCy1QUGaZAG
-sLLVBQVUQAUFVEAF1h3GBEADgAbACQANgBMAGkAdgCCABgANgBMAGgAnADSAOgBBwAmAE0AdACeA
-OgBOwFeAYZkDMwfZCnMOphXmHIAgGSQzB3MOphXmHFkrzDkAQTNI2QqmFYAgWSsAQaZWgGFZbDAA
-AAA2AAAADAAAABIAAAAYAAAAJAAAAAYAAAAJAAAAAAAAAAAAAAAYIBQUDg4UFAUGAQIDBAAAAAEB
-AgECAgMEDAwIBAwEBEAAAACAAAAAAAEAAAACAABAAAAAAAQAAEAAAABAAAAAEBESExQVFhcYGRob
-HB0eHyAhIiMkJSYnKCkqKywtLi9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNk
-ZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/MxMAAAAHBw8HDw8XLQAPIADwYQAAAAAAAAAAAAAB
-AgQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAADA5OjUyOjE5AAAAAE8usABqsKKwkrBjAAGtrXsArZOcra1gAAkAAAACAAAAAAAA
-AAAAAAAJAAAAAgAAAAAAAAAAAAAACQAAAAMAAAABAAAACQAAAAkAAAACAAAAAgAAAAkAAAABAgEC
-AwQAAAUGBwgJCgAAAAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBA
-QAUFQEAMDEANDAwBAQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAF
-BQVABUAFBQUFBQQAAAAcEQAAHDIAABwzAAAEAAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAA
-AGQAAAAAkAEACgAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAQAAABAAAAAAAAAA
-AQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAALx8AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAEAAAAFAAAAAAQAAGQAAABQgwEAWIMBAGCDAQC4gwEAwIMBAMiDAQAHBwcHBwcH
-BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcGBgYGBgUF
-BQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAolQ8BOfJgABxctYDQAAAAEDgkdLTcAAAQOCR0sOwABEAAB
-AAAAAoAAAUIGAhAAAiAAAAPAAAFDBgMQAALAAAADwAABQwYEEAACQAAAAoAAAUQGBREAAEAAAAPA
-AAFFBgYRAADgAAADwAABRQYHEQABAAAAAoAAAUYGCBEAAiAAAAPAAAFHBgkRAALAAAADwAABRwYK
-EQACQAAAAoAAAUgGCxIAAEAAAAPAAAFJBgwSAADgAAADwAABSQYNEgABAAAAAoAAAUoGDhIAAgAA
-AAKAAAFMBgAAIhYAAIAAAAMAAAFZACQWAAEAAAADAAABWgAmFgACAAAABAAAAVoAKBYAAgAAAAMA
-AAFbACoWAAKAAAADAAABXAAsFwAAAAAABAAAAVwALhcAAIAAAAMAAAFdADAXAAEAAAADAAABXgA0
-FwACAAAAAwAAAV8ANhcAAoAAAAMAAAFgADgYAAAAAAAEAAABYAA8GAABAAAAAwAAAWIAPhgAAgAA
-AAQAAAFiAEAYAAIAAAADAAABYwBkGwACAAAAAwAAAW8BZhsAAoAAAAMAAAFwAWgcAAAAAAAEAAAB
-cAFsHAABAAAAAwAAAXIBbhwAAgAAAAQAAAFyAXAcAAIAAAADAAABcwJ0HQAAAAAABAAAAXQCdh0A
-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
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAPAABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADo
-AGkgAABpIEAAaSAAAGkgQAAgIIAPAABkBmkgAABpIEAAaSAAAEogAABKIQAASiIAAEojAABKJAAA
-SiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBK
-IwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4EAAEBBLJwwQCycMEIkHDQKIoA/gAA4cwoj
-ADfmDwAASiYAcGkgQABKJgBwSiYAcEomAHBKJgBwABYAcIAAZARAeCAgQIcAAAAAAAAAAAAA4cDh
-weHCz3CgAMgfFhABhs9ygACYhyCiEhABhiGiExABhiKiFBABhiOiFRABhiSiJBABhiaiz3GfALj/
-VqGKIf8PEhhYgBMYWIAUGFiAFRhYgCQYWIDBwsHBwcAgIECHDMjPcqAAyB8OGhiADcgPGhiADsgQ
-GhiADxIBNgHIJHgRGhiAEMgtGhiA4H7hxPwcyL78HEi+4cDhweHC4cP8HAix/BxIsfwciLH8HMix
-/BwIsvwcSLL8HIiy/BzIsvwcCL9qJIAQ4cRqJMAQ4cTxwM9woADQGxSAz3GAAGAEBCCAj89RBOEA
-oQryLykBAM9wgAA0D/AgQABAeNr/0cDBxGskwBDBxGskgBDBxJ90BBQLNAQUCjQEFAk0BBQINAQU
-BzQEFAY0BBQFNAQUBDTBw8HCwcHBwMHERSx+EAomQH7BxGskgBTBxCAgQIcMyIe4DBoYMA3Im7gN
-GhgwDsgOGhgwD8iHuA8aGDAQyBAaGDDgfuB48cAMyJW4DBoYMA3Im7gNGhgwD8iKuI24kLgPGhgw
-z3CAAGwQGIgbCFEAD8jPcQAAiAysuA8aGDA+DiAAD9hn2IYKIAGKIQYK0cDgfvHAz3CAALy1AICG
-IP6BCfQPyAUggA8AAADUDxoYMKH/iiBVBVYKIAGKIUYO6PHgeM9xAwBADc9woACoIC2gz3GAAIwE
-QIEBagChz3CgADguBYAEIIAPwAAAAB0IgA/AAAAASNjPcZ8AuP8aoVuhadgYuBmhz3CAAMgJJYAj
-gSCBx3EAAIgT5QLACeB4z3CAAMgJeQLACeB48cBuCwABz3eAAGAEiHUG6A0IUQAB2APwANgLrwXp
-DwlRAAHYAvAA2AqvBuoNClEAAdgD8ADYDK8A2M92oADIHxgeGJALj4ohEAAO6AiPDOjPcAMAQA1F
-HhgQMKYC2BgeGJAD8DGmCo8Y6AmPFujPcAIApkEgHhiQz3CAACgAIR4YkM9wgABcBCIeGJAYFgCW
-RSAAAxgeGJAMjwjoGBYAloUgAQQYHhiQDwtRABgWAJaIuBgeGJDPcIAAMHwAkI7gzCCiggb0GBYA
-loC4GB4YkBjtANiUuM91gACABAClcdgGuMYMIAH82SCFz3AAAEwctgwgAZ+5GBYAloW4GB4YkNUC
-AAHPcaqqu7vPcJ8AuP82oDagNqA2oM9xoADIOw6BiLgOoWkgQAD+8eB48cClwUHAQsEMHAAxEBxA
-Mc9xgAB8dDQZwA8wGQAPLBnADigZgA4kGUAOz3CAAHx0IBhAC89wgAB8dBwYAAvPcIAAfHQYGMAK
-z3CAAHx0FBiACs9wgAB8dBAYwAjPcIAAfHQMGIAIz3CAAHx0CBhACM9xgAAAdIAZAAh8GcAHeBmA
-B3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE
-76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkA
-AGoggALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAA
-aiCAAcwZAADQ2J+4z3GfALj/HaHPcIAAAADEgFMlxDVTJsU117oB5tO+xKBTI8AEBSaOH9D+AADW
-oQUggA+w/gAAFqEYgVMnzjUA3ZS4GKFAwwHAAsHJcwwUBjB+D+AAEBQHMM9woAC0D7ygz3GgAMg7
-LoEWD+AAfdhaDkABFgsgAalwCNgA2cYKIAGZuc9wgAAwfACQjuDMIKKCyiCBD+AAxDHKISEA4A8h
-Ac8hoQX9Bc//8cA6CCABe9jODuAA4dnPcYAAfHQ0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8dCAY
-QAvPcIAAfHQcGAALz3CAAHx0GBjACs9wgAB8dBQYgArPcIAAfHQQGMAIz3CAAHx0DBiACM9wgAB8
-dAgYQAjPcYAAAHSAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
-QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
-ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
-gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA63bPdaAAyB8ZFRGWz3AAAEQccg8gAQogwC9a
-cM9wgABsKiOAz3OfALj/z3eAAAAABIcB4NO4IukZFQKWQQreAF2DQN6fvt2jBKcFIIAP0P4AABaj
-WBuAByEVAJYiFQCWBCGBD/8A/P8AgRajCNgZHRiQVqNdo9EGwADQ2Z+5PaMEpwUggA/Q/gAAFqPP
-cIAAgAQAgAsggIQI8lgbgAR+CUACDNgt8IwhBKAm8owhAaAi8kIhQSBFCRUEMyZBcIAAAFxAJwBy
-NHgAeEohQCAN2BfwSiGAIATYE/AT2EohACEP8EohACIU2AvwSiEAJBXYB/AW2AXwF9gD8A/Yz3OA
-AOANcIMKcclyCiRABOUD7/8KJYAE4HhFAs//8cDGDMAAddiCDOAAiiEKA64MAAACDoACYf6iCAAA
-CiHAD+tyBtiKI0oHSiQAAKkD7/8KJQAB4HjxwATpGQgSCAohwA/rcgXY49tKJEAAiQPv/7hzz3KA
-ADQPFXogotHA4H7geADZnrkZec9ygAAsDwGCJXjgfwGiANmeuRl5z3KAACwPAYImeOB/AaIA2Z65
-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
-GYYUHQARDKWgFgAQZKUNpaQWABAMHUASDqWoFgAQCB2AEg+lz3ABALAJEKUuCWAAKNgRpSYJYAAA
-2BKlUyfAdROlAshUHQAXFqUSFgCWUB0AFxelExYAls9ygAAQERilFBYAlkokQHkZpRUWAJYA2Rql
-JBYAlhulFhYAlhylz3CAAOANEIAdpc9wgAAQEXgYgArPcIAAEBF8GMAKz3CAAIwRBBgAC4QaQAvP
-cKAAyBwIgIgaAADPcIAAgAUAgIwaAACoIIAC8CJDAM9wnwC4/wHhdqCZAAAA/ByItvwcSLb8HAi2
-/BzItfwciLX8HEi1/BwItfwcyLT8HIi0/BxItPwcCLT8HMiz/ByIs/wcSLPgfuB4BNw43TXw4HgE
-3DTdM/DgeATcMN0x8OB4BNws3S/w4HgE3CjdLfDgeATcJN0r8OB4BNwg3Snw4HgE3BzdJ/DgeATc
-GN0l8OB4BNwU3SPw4HgE3BDdIfDgeATcDN0f8OB4BNwI3Rzw4HgE3ATdGfA0FBowMBQZMCwUGDAo
-FBcwJBQWMCAUFTAcFBQwGBQTMBQUEjAQFBEwDBQQMALHAcawJE0zsCQfM+B+8cDPcYAA4A0QoeB4
-4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeNHA4H7geOHF4cZA
-KQ0CJX1ALQMUpXslCjQCCHVTJX6QBvIBHVIQYbr78UEqjgDBukImTpAEHdAQ/fUJ6i8kiXDgeKgg
-QAEBHVIQ4HjBxuB/wcUocgDZ2PHgePHAsg7P/6HBCHfPdqAArC8ZhgQggA9wAAAA13AgAAAAAdjA
-eC8mB/AodRpyE/SKIEkG+gzv/4ohTQQ5hu4M7/+KIAkGiiAJBuIM7/+pcQDYJPARzAAcRDNPIMED
-AeAQeAQggA8AAP+/j7gCHEQwERocMN4JoA9AJwASB+cEJ48fAAD8/wUnABSduJ+47HEAoQDB7HAg
-oAHYfQbv/6HA4HgiuQbw7HJgogTgYbn5CbWAYIAA2c9woADUC22gz3CgAEQdNaDgfuB48cDyDc//
-CHYodShwSHFocsr/geDKIIEDwA/h/8ohQQM9Bs//4cXPcoAAsASkis9ynwC4/wXtz3PQuv7KfqIa
-ojuiDu3PcKAAOC4FgAQggA/AAAAA8QiAj8AAAABp2Bi4GaLgf8HF4HjxwIYNz/8Id89xgACwBAWJ
-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
-HgLPcIAAAGAyIEACDwiSAM9wpgDo/w2AA/AA2AamBaYA2EokgHAG2o26qCBAAynbErvwI48AQCYD
-HxV7AeLgowHgAJE4HgARVSZBFBq2z3CAAGCXBgyv/gjaGxUAls9xpQDYyxmmHBUAlhqmHRUAlhum
-DoEcpg+BHaYmFQCWHqbPcKQAkH8cgAUHb/4fpuB48cCGDm/+ANvPcaAAyB9AEQAGz3egANAPGRcA
-ls9yoADEJ08SDoa4gc9wgAD4tKigEczPdYAAFJELDgAQH4ULCJ4AAd4E8BEanDNodlISEIYVEhOG
-G9gWGhiAEQvfIFEgQKBKIgAgB/QdhQHeWnaEuB2lDQseIVQVgBAE6ADYBvAdhYW4HaUB2DpwTCIA
-oMwhIaBY8s9ynwC4/1gaAAgQh89wgADAEA+IFqIA2s9woAD8RJ66QaBloB6FsLgepagVABBk4B6h
-ENgOoQHYFRkYgLYJr/4J2BcIX0fPcYAA4A0LgQHgUg9gAguhvgpAAhsJECDPcYAARH0FgQHgegtg
-AgWhOQIAAM91gAAUkccKECAdhYS4HaXPcIAARH0RC94gIoAB4SKgiiCFCQfwIYAB4SGgiiDFCNYL
-T/7aDkACS/BCEgCGBCC+jwDAAABD8gG1HoV7CN4EiiCEDrILb/6KIRADJgiABwCVhiD8AIwgAoAx
-9IoOQAev6APYEh8YkOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
-4HjgeOB44HjgeOB44HjgeOB44HgSHxiQE8wRGhwwBfAAla4LoAg0lawVARAI6ZcVgBAAqQDYrB0A
-EFQVgBAh6M92oAD8JTSGAdrPc4AARH0GgzhgBqMF6c9xgACZCUCpU4Yng1lhJ6M+hQHenwgQAJsJ
-3gEB2c9wgACEBSCgRfAhCB4gAdnPcIAAmQkgqM9xgABEfQOBAeADoT6F6/ED2c9woADUCzGg4Hjg
-eOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
-4HjgeDGgE8wRGhwwGQoRIB2Fz3GAAER9grgdpQSBAeAEoQHeHoUXCB4ElRWAEKQVARCpcg4P4AIB
-2wPwdgpAAx+FDwgeAM9wgADgl44OgATPd4AACJ0ZhwbougoABADYGaeGCUACz3CAAGwQCIAjCN4C
-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
-HgmgAItxgsZqcBYJoADJcUpwDgmgAITBqXAGCaAAhsGIxelw+gigAKlxKnDyCKAAisEKcOoIoACM
-walwisFOCaAAkMKLcMlxQgmgAJLCyXCEwToJoACUwobAqXEuCaAAlsKYxpDAksHCCKAAyXKax5TA
-lsG2CKAA6XLJcOlxDgmgAJzCnMCeweIIoACOwp/FhgigAARtjsCWCaAAJG23CBAAhsCKwaYIoABA
-JQITi3CEwZoIoABAJQIVlMBAJQETagigAMlykMBAJQEVXgigAOlyyXDpcbYIoACcwozAnMFKCKAA
-yXLCCKAAyXDJcI7BegigAEAlAheSwEAlARMuCKAAyXKWwEAlARUiCKAA6XLJcOlxdgigAJzCjMCc
-wQ4IoADJcslwjsFCCKAAQCUCGTYIoABAJQAXz3GAAPwHGKEmCKAAQCUAGc9xgAD8BxmhB/AA2c9w
-gAD8BzigOaCZAi/ygCQCOuB48cBSCi/yCtqqwQh2dg8v8otxBtguCmAAAcEI2CYKYAABwQnYHgpg
-AAHBEBQEMMlwAMECwgolgA+t3u++og1gAAPDyXBd/38I0ADPdYAA/AcchRgUBDASpR2FAMEKJYAP
-rd7vvgLCFaXJcHYNYAAFw8lwUv9PCNAAHIUgFAQwE6UdhQDBCiWAD63e774CwhalyXBODWAAB8PJ
-cEj/JwjQAHyFdBUGEMlwVBUEEFgVBRB0pSQUBzAyhVwdgBFThW3/ANj9AS/yqsDxwG4JL/IM2Lpx
-OnLPd4AA/AeEFxMQfBcQEADdmnDPcIAADE3wIFIDanDSC6/6SnECcBN4xguv+oohDwoIdogXABC6
-C6/6SnGAFwEQOGATeKoLr/qKIQ8KumVUekAtwSA2eVlhx3GAAEywDQkRIMSpBakJ8AsJUSDGqQep
-A/DIqQmpQiRAIJkIdYAB5TEBL/IA2OB48cDKCA/yp8G6cADfRsdKJ8AgSiSAIUojwCRKIIA1z3aA
-APwH66bpcVp3gOHKIoEvAAAI0sojISXKIOE1yifhJMokoSWB4coigS8AAAnSyiMhJcog4TXKJ2El
-yiQhJoLhyiKBLwAACtIT2cojQSDKIKEFyiABMMokASDKJ0EgANkH2EXAz3WAABxMNX0AhdpxAdmO
-4MIhTgAqpoDhyiHBJcohwiSA4cogASXKIAImogtAAM9xgAA4TMlwA9oKCmAAAtsKhiuGCtqt/s9w
-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
-AQQOGkQBTCWAhMohwg/KIsIHyiBiAcojgg8AAHMA6ANi78okIgAA2gfwABYAQRQhjAAAtAHiLyBC
-AfMKAoBSCo/w0cDgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4z3CAADwJ
-4H8AgOB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
-eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
-4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8B2OB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
-fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY8cDPcIAA
-RL56Ca/wA9kyCY/w0cDgfuB4AtjPcaAAwB0NoSHYBqEB2Aeh4H4A2c9woADAHSegJqAtoOB+z3GA
-AEQJDQhRAAHYAKkBqQCJgeDKIIEPAADECcoggg8AAIAA4H8BoQDYz3KAAEQJAaoAqs9xgAAwfAaJ
-COgHiQboAJEJCJEDAdgAqgDY2vHxwOHFCHXPcIAAwBABiCsIUQAH8IIIT+8KDW/wT9jPcKAA1AsY
-gADZQiAACIDgyiBMAOUIRIOtBE/w4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjxwAohwA/rcgXY
-JttKJAAAxQFv7wolAAHxwAohwA/rcgXYK9tKJAAArQFv7wolAAHPcAIAKBvPcYAATAkAoc9wAgAk
-GwGhz3ACACwbAqHPcAIAMBvgfwOhz3ACAKgaz3GAAEwJAKEBoQKhz3ACAKwa4H8DoeB+4HjgfuB4
-4H7geOB+4HjxwJYLb/Bq2KLBi3EB2sII4ABIc43oCiHAD+tyBdiKI88LiiSBCi0Bb+9KJQAAgcFE
-2AHamgjgAEhzjugKIcAP63IF2IojzwyKJAEBBQFv70olAAAEFAAxXwiCDwAAMgRAJIEwa9gB2mYI
-4ABIc47oCiHAD+tyBdiKI88PiiTBCtEAb+9KJQAAAhQAMc92gABcCRt4QSjFAEwlAIoEHkAR0fYK
-IcAP63IF2Ioj0AClAG/viiTBCh3Yz3aAAFwJAaa4cAAUADHPdYAAXL5ALYIAqXH+D6AAAduN6AAU
-BDEEFgUQCiHAD+tyBdhpAG/viiNQA0GGJQpyAADYFiUBEGCJhiP/DSO7DwtRAGGJA+tiu2GpAeDn
-CIKAANjpAm/wosDxwG4Kb/CKIgQKocHPdYAArAkAlc92gAD4v8lxSiAAIAAcBDSKD6AAAduP6AAV
-BBEKIcAP63IF2M9zAAACDPUHL++KJQQKAI6E4Mohyw/KIssHyiBrAcojiw8AAAcMyiQLBNAHK+/K
-JcsAXgqv8DTYbQgeBJv/D+gKIcAP63IF2M9zAAAODEokAACpBy/vCiUAAYtxRdgB2hYPoAAB24Dg
-yiHBD8oiwQfKIGEByiOBDwAAEQzKJIEPAABFAHQHIe/KJQEEABQAMQHZhiD+D8DgwHnPcIAAXAki
-qBvwz3CAAK4JAJDPcYAASMIO2lTgEHi+DqAAAduA4MohwQ/KIsEHyiOBDwAAGQzKIGEBvfPFAW/w
-ocAOeCx4KWoA2A8gQAAncFp44H8OIMAA4HjxwEYJT/DPcIAAXAkdiAXwQCdAAA94+HDPcIAAXAke
-iIkIwgEA2QfYRCk+B1lwL3AZcYQvAwEncM9xgAD4vwAhBAAfFMQAGWEeEcUAOXAA3gAhjR+AAPi/
-1X3njYhxBdrpcAUVwxDh/0AogRA0eYQvAQUncdR5x3GAAGTC2HEAqelwqHEH2gYVwxDY/wHmz37B
-DrKRAR4CAEIiQBBAIEEQiQh1gC95tvEFAU/wl+iMIcKNAdpX9kokgHGoIEAEz3OAANnARCo+BzIj
-Qw4XC0MAB+sTCpABAeJPegDaA/Bhuk964H9IcOB48cBSCE/wGnA6cpEJcgAA31pxFSDAI6CIAogb
-CRAgz3aAAMBSFX4CuBR4x3CAAFRVCvDPdoAA+FIVfgK4FHjHcIAA/FUhiEsJHgAFEMEAIq4GEMAA
-A64qcKlx2/8AroDgzCBigMogIQAS8kQoPgcAIYB/gAD4v8UQggDhEIEAAiWAEBB4B7hOCu/4QnkB
-rkIiQSCBCXWAAecVAE/w8cDPcIAAMHwGgM9xgABcCQLaEwhRAFypANgdqQHYHqkL8A0IkQBcqQHY
-BfAD2BypANgdqV6pR/+R/89xgAAkayCBz3CAAPRYAdrH/89xgAAoayCBz3CAAFBZANrC/9HA4H7g
-ePHAuHEtCFEACQ1SABcN0gMKIcAP63IF2IojkgQBBS/vmHNALYAAZLjHcIAAwFIb8M9wgAD0VzIg
-QQGMIcOPyiHBD8oiwQfKIGEByiOBDwAAmATMBCHvyiTBAM9wgAD4UjV4zfECeS15THlWIQFyR7k4
-YOB/D3jgePHA4g4P8Ah2KHVIdxpzT3kQuQ94CLgFeYogRwg+DS/wpXnPcIAAXAkBiIDg8AECAIDn
-zCAioAnyLG0vec9wgABcCT+oBvDPcIAAXAm/qKlxz3KAAFwJIBpCAyEaggMiGsIDIxoCBMlwyP8A
-EIcA4YjPcIAAXAndiB6IEHaWAQkARC8+By9xhC4DEQokQA4AIU0Oz3CAAPy/HWVAL4IAVHqELgEV
-CiVADgAiQA4AIIgPgABkwgAmgx+AAHgJTCcAgMwnYoAl9BoVwBAA2QyrGxXAEEokgHEQqxiNFKuo
-IAAGFCBAEEGIc250ezV7x3OAAFjDABDAAEirFSVCEAmrARLAAAHhCqsAii95C6t68AEVwBCY6ADa
-TKtQq1SrSiSAcQDZqCDAAxNuFHg1eMdwgABYw0ioSahKqEuoAeEveWLwbLoAIkABfLkAJEQAACCG
-D4AAZMIAJIAPgAD8vxqIOo3pcqP/DKsAJIAPgAD8vxuIO43pcp7/EKvPcoAA/L8AJIAAGIg4jQAk
-hQDpcpj/FKsA20ohgBEUJssAFCDEEAETgBABFIEA6XKR/zNuNHl1eQAhig+AAFjDCBoCEAATgBAA
-FIEA6XKK/wkaAhAVJcsAFSXEEAETgBABFIEA6XKE/woaAhAAE4AQABSBAOlygP8LGgIQQiFJEAHj
-nwl1kG97AebPcIAAXAkeiM9+EHZ0Bsz/ANnPcIAAXAkgqCkFD/DxwLYMD/CnwRpwWnFIdTpzCiMA
-IYtwz3GAAAhrZg1v9Rraz3GAAFwJAYEA3qkIdACYcAIRhQBMIICjAdrPcYAAXL4WIYMDAIvCIowA
-RCCPAP1/fwrBAw0LUSBBiw0KAARvCxEgQYu16kQgAgIjumMNgRAzDVEARCACAUEqgoAH9EQgDwRB
-Lz6RCvIRClEARCACBCS6CQpQAADaA/AB2k96B/BEIAIEJLqA4gHawHojClEATCEApgHawiKKAIYg
-/w4iuBsIgACA4swlYZAH8gHmZw4EkYog/w8R8DIkQDQRCFEAQnHWeQIRwAAJ8AsIkQAGE8AAA/AH
-E8AAFQQv8KfA8cDCCy/wSiRAAAh2GnFId2h1vP+MIP+PEfTJcApx6XKpcwDdmHW3/4wg/48H9Iog
-BwoKCi/wyXGpcO0DD/DgePjglvbPc4AAoFMGixcKAAAHixMKAAAOiwsKAAAPixEKAQCB4cwhooAB
-2APyANjgfvHARgsv8IoghwjPdoAAXAm6CS/wP44Bju8IEQDPcIAAeAlCIBAHIRaAED+O8/7PcYAA
-tIcgFoAQVokYFtMQHQoBACEWgBA0iREIQQAZFsAQCSDABC8jBSAejv2OqwjCAwDdSiKAIxqOEehE
-L74TACVAHhgWwhDPcYAAkMOZIQIKGWGWIcIKQKk08EgjQCAvIQUgz3CAALxTq2AfjulxIhaCELz/
-CSBBBC15ACDAI89ygADMU6piMBCAAEJ4CSBBAEQvvhMAJUQeH44AJIUPgACQwxgdQgDpcalyvv8A
-JIEPgACQwxgRwQACeS15GB1CAEIiUiAB5XMKdaCvfQHnHo7vf2EIw4OZAg/w4HjhxeHGABHNAAkN
-ExAA3aCpEejU5YP3U92gqc9wgACUVBQgTgOgjqCqABHBADR4AYgQ8NTlg/dT3aCpz3CAAOxTFCBO
-A6COoKoAEcEANHgBiACrwcbgf8HF8cDyCS/wuHIIdyh1z3CAALSHz3aAAFwJIBaDEDaIo8EA2scJ
-wQA0iCEWgBC7CQEAExaGEAsOEACD70WmNfBTJYCQBPJjCFIBCQ0SFAkNEhYA2gPwAdoRDhAAIhaA
-EIDgANgD8gHYz3GAAKBTqWHPc4AAkMNEL74TmSMCCidxO2MzI4QPAABYBRQiwQPZYWyJAdlAwUHA
-QCYAFULAANgIcWYK4AD4dwK9tH3HdYAAbJgihQrvIQ9QED8PkRDRuQWGErgQ8AWGBCGBD/8HAP4F
-eSKlE/AFhgQhgQ/8B/8BCbgFeSKlCfAA2QK9tH0AJYAfgAB0mCCgcg/v74oglA1dAS/wo8ChwfHA
-6ggP8KHBZcIIdih1z3CAAMoGhcGLckAkQzAAiKH/RC6+FgAlQB4UFMEwz3eAAKC/WSePGvhgViDA
-CnkNMxYgqFMlgBBNCFMBRiXNEa99HfABFIAwACaBH4AAbJhSbVR6WWEgwgCpRC6+FgAlQB5EqRQU
-wTD4YFYgwAogqMlwqXGe/wHlr31TJYAQyQhSgSDwARSCMBJtFHgAJoEfgABsmDhgQKggwkSoyXCp
-cZP/EPBCJQAWD3gBFIEwx3aAAISZArgUeB5mIMAorgyuCNyHAC/wocDxwAYID/ChwRpwiiAHCX4O
-7+8Kcc9wgABcCQGIgOBKIQAgtPTPcIAAoFMyIBMEz3CAAFwJ3YgeiBB2UAEJACp3CiJAJALwOnVE
-Lr4TACNALs9xgACQw5khAgoZYTMhjQ8AAFgFu30xCDMmrX3PcYAAnCoagTuBJHgdCB4Cz3CAAFwJ
-E4iLc8lxYgjgAKlyAMACfa19z3CAAHgJfLjYYCwQwQDPcoAAoAYAigXaqXOD/UokgHEA3aggQAVz
-bnR7tXvPcoAAWMN5YimJemIK6SMJAAApCEIAMQ1TEQHlr30L8EIlkhAvIockYb2vfRDwCxLPAADZ
-KnUN8IDlSiIAIMolYRAG8kIlUhAvIockAdkt6XNudHsVI0EDz3eAAFjDOmcAJ0UQFSODBHlnKYlJ
-in9nNQmjAOuPAiJEAAsVggAEv/B/IngEui8kCAECJ4MQbHgvIEYONgmv+IhxDngCfwjn7n9Ev+1/
-CwgSJgrn7X/JcApx6XJt/wHmz3CAAFwJHojPfhB2wgbM/9UG7++hwOB48cCCDs/vz3CgALQPcBAQ
-AIogxwjPcYAAoAbiDO/vIIHPd4AAXAkBjwDdr+jPcKAAtA+8oD6PHY8jCQIAz3OAAIS/f9oUIA4A
-fmZYrrmuAeAPeAXa7wkjgFquAN0O3s9wgAC8U6hgg/9hvgHl8w51kK99z3CAAKAGAIDPcaAAtA8J
-p3AZAARhBs/v4HgIcQUhgQ+t3gAAZQTv74oghwngePHA4cXPdYAAoAaKIMcJTgzv7yCFz3GAAFwJ
-AYmL6ACFKYFNaDBywCBsAcwhDIA0D8n/LQbP7+B4z3EAAK3eHQTv74oghwngePHAABaAQM9xgABc
-CRipABaEQAAWgEBQJL6BGakAFoBAyiHCD8oiwgfKIGIByiOCDwAA8QooA+LuyiXCAFEkgIEA2Mog
-YQAbqc9wgADIBgCQA+h+/rH/kgkP8OMFj//gePHAPg3P7wh1z3aAAFwJCY4odw0NARAIjkEPABCp
-cEAmgRR6CaAAQCbCFBKOr3ozjhi6CLgFeoogVA16C+/vRXkyjkAmABPGDKAAU44SjvYLoAAzjqmu
-6K5NBc/v8cC4cS0IUQAJDVIAFQ3SAwohwA/rcgXYl9uJAu/umHNALYAAFHhsuMdwgABUVRzwz3CA
-APRXMiBAAYwgw4/KIcEPyiLBB8ogYQHKI4EPAACdAFAC4e7KJMEAArgUeMdwgAD8VdHA4H7xwHoM
-z+/PdoAAygYAjs93gADIBiCP4f9BiM91gACYCSCXEQreAAHYAK2KIMcDQ/ACgAboANgArZC5O/Bf
-Ch4Bz3KAALSHFopTCQEAAJZ0iksIwQDPcIAAzAYAiFKKPwoBAM9wgABsEAmAMwheAUGFANsO6s9w
-oAAsIBCAQngRCIUPMQEALQHaQK0E8GCtANoQuoogRwNFeQ3wAY0G6AHYAK2KIAcDB/AA2ACtkbmK
-IAcEPgrP7y0E7+8AjfHAj+i2/89xoAAsIDCBx3FJawDSIqAeCu/viiCHBZLx8cDYcYnorv8A2SKg
-iiDHBQIK7+/IcYbx8cDhxc91gACYCYogRwbuCe/vKY0E2OYKr/sB2QiNKY3q/90Dz+/gePHAz3GA
-AJgJiiDHBsYJ7+8pic9wgAA8VUoKj/hi8eB44cVTIA0AoKkEIIEPAAYAAEIhAYAEIIAPQAAAAMoh
-YgAgqtdwQAAAAAHYwHgAq+B/wcXgePHADgvv79hxCiaAkIh1zCMigAbyQiYGAS8mhwHIcYP/z3GA
-AJgJA6Ef7iSIArk0eUOIA+ECEIUAGwofAAohwA/rcgXYiiNIBJhzgQDv7golgAEIYRcIXwAKIcAP
-63IF2IojSAXy8QEQhQBRJQCAyiHBD8oiwQfKI4EPAAAiAsogYQHk8+G90SUigcohwg/KIsIHyiBi
-Acojgg8AACkCLADi7sokggEnDR4QUSXAgMohwQ/KIsEHyiBhAcojgQ8AADACCADh7sokgQGxAs/v
-4HjxwDIKz++hwQh2KHcacgDdz3CgALQPcBARAIogxwCSCO/vyXHPcKAAtA+8oItxQCRCMEAkgzDp
-cLH/DQgRIEokAAAJ8M9wgACMnwGI+ehKJIAAIMABFIIwyXECFIMwtf/PcIAAmAkpiIDhzCZCkAXy
-I4CqqKKhMQ9eEc9xgAC0h1aJJQ6BEFSJUycDEBkLgQAEJ48fAAYAAIDnAdoyicB6CwpAAKKooaCg
-qIogxwACCO/vyXHPcaAAtA9wGUAE1QHv76HA8cB6Ce/viiAHBs92gACYCdoPr+8khhXdBIYyaAHg
-NHnHcYAA/FUEpgKBEujPc6AALCBwg2J413BJawDSANrI90KhiiDHBaYPr+8giQSGCwiUCgDYBKZh
-vcENVZCJAc/v8cDPcYAAoAaKIIcBfg+v7yCB5P/PcIAAyAYAkIDggAzC/3kEz//gePHA6gjv79hx
-ocEacItxQCRCMEAkgzDIcGb/ARSAMAnoAhSAMAXoQiAQIS8gByQgwApx9/4BFIEwA+miiALwoYiK
-IMcBHg+v78hxQCgAJkAtAhQFegEUgDACFIEwCLgFeoogxwH+Dq/vRXnhvdEl4pAD8h0NHhEKIcAP
-63IF2IojTQGYcykGr+4KJQAEwQDv76HA4HjxwOHFPv/PcIAAbBAYiM91gACMnxcIEQGKIA8Ksg6v
-74ohigICjSGF0f8CjSGFAdp8/6EAz+/geBEIHgIEIL6PAAAAGAHYA/QA2OB/AKngePHAAgjP76HB
-GnAA3s9woAC0D3AQEQDPcKAAtA/coIogRwFeDq/vCnGEKAYvACGNf4AA4KAh8EAlABcWIIQDBRSA
-AIYg/ocY8gSFi3FAJIMwQCRPMOlyHv+oFQAQ6XHj/yDABBSBAAEUgjACFIMwSiTAACT/AeYMlb8O
-BJCKIEcB/g2v7wpxz3GgALQPcBlABP8Fz/+EKAsMACGBf4AAZLgoEYAAKIEtBe//ANrxwJL/dgnP
-/9kCz//PcYAAtIfPcIAAyAYAkFaJKwoBAM9wgADKBgCQVIkfCgEAz3CAAMwGAIgyiQ8JAQDPcYAA
-mAkBiQKp4H7xwBIPj+8acM9xgAC0h892gADIBgCWVonPdYAAmAknCgEAz3CAAMoGAJBUiRcKAQDP
-cIAAzAYAiDKJCwkBAAKNAvAA2AGtlv7PcIAAzAZAiM9xgADKBgCJII6A4gHawHoKcwDfmHfq/gOF
-AYgglhEIHgEB2AOtiiBHAwXw462KIIcDCg2P7/EGj+/gePHAhg6P76HBCHUA3s9woAC0D3AQEADP
-cKAAtA/coOONiiAHAdoMr+/pcQSVi3FAJIMwgOAB2MB4LycAAAWFQCRCMMP+CoVAJEEwiP83D3QQ
-lSVDHlYlABzwIIADqXGAIQgA1HnAuAUgwAEvJAcAIIkgwAEUgjACFIMwwv4B5tkOxJOKIAcBegyv
-7+lxz3GgALQPcBkABJUFz//gePHA6g2P789wgABsECgQkACogIogBwJODK/vCnFTJQAQCnE7/gGI
-USAAgcohwg/KIsIHyiBiAcojgg8AAFoDyiTCAGwDou7KJQIEBQaP7+B4z3CgACwgMIDPcIAAmAng
-fyGg4HjxwOHFz3WAAJgJAI2P6EH+jeiKIEcEAN3mC6/vqXGQ2ZC5A8igGEAAE/ADjRDoz3CgAAAE
-LIiMIQKAAN0I9MILr++KIIcEkdmQue3xAd21Ba/vqXDxwDYNj+/PdoAAeJ4UjicIUQAE2JYMb/sB
-2c9wgADKBgCIz3GAAMgGIIlU/gDYFK4t8PaOK+/PdYAAmAkKjWG4MQ8AEGX+z3CAADxVz3GAAKie
-JYFBbwUpvgBCDG/4L3GKIIcGz3GAAMgGQguv7yCRz3CAAMoGAJDqrQitz3CAAMgGAJAJrQDYFq41
-jgjpz3CAAMoGAIhB/gDYFa4BBa/vAdjgeIDg8cD02Aj03gzP71AgAQD02Afw0gzP7whx9NiAua4O
-j+/RwOB+4HiA4PHANNgH9LYMz+9QIEEEBfCuDM/vTyBBBIoOr+802O3x4HjxwEIMj+8acJIM7+8w
-2JhwKbhRIACAyiHCD8oiwgfKIGIByiOCDwAAzwDcAaLuyiUiACzYSg6v70AogSAB34ogDwoacFYM
-7+8w2JhwKbgxCB4AjCcPmjXyIN3PdqAAyB+wpgHYQx4YEADYzg+v7424saZCIEAgzwh1gAHnHgzv
-7zTYTyABBZW59g2v7zTYDgzv7yzYCHUGDO/vNNg1CF4FR9gaCq/vAtkKIcAP63IF2OvbSiQAAFEB
-r+4KJQABCiHAD+tyBdjb2z0Br+5KJQAA9LjKIIIPAABHAOAJou/KIWIAxQOv70EtABTgePHAWguv
-7zTYpgvP7893gADUwycIHgQA3slwrP8B2LX/iiUQEMlwvP8UJ4wTYb0AtPUNdZAB5o0Dj+/gePHA
-Hguv7zTYocEA3kDGAN9iC+/vjL8zCB4EEg7v8QHYA90KvfhmEHiLcV4P7/EB2s9xgADUy9R5Yb0A
-sekNdZAB5nIID/JBA6/vocDPcaAAYB0SsRSR4H7xwMIKj+8Idih1SHcacw4L7+802BsIHwRhv4wn
-/58X8slw9f8CHRQQAebQfvbxDwgQIM9xgADUwwTwz3GAANTL+3rUeT4L7/SpcN0Cr+8B2PHAagqP
-71pwGnE6cmhwvgwv+ArZoWi2Cu/vSnAEIEAEBCEBJCsIQAAg3892oADIH/CmCthDHhgQANguDq/v
-jbjxpmG9jCX/nyf2ANgC8AHYdQKP7/HA07hPIAEGmbmOCe/viiARAp4J7++KIBEEmwXP/+B48cDh
-xUh1QCkCBlMgwQSKIBEBZgnv70V5iiARA1oJ7++pcVkCj+/gePHA3gmP7wh2KHXs/whyyXAD2aZ6
-8f81Ao/v4HjxwMIJj+8Idih15f8IcslwA9mleur/GQKP7+B48cDMuBC4TyCBAJ+5zguv7/TY9NgC
-2c9zAQCghihyxP+A4MogIQAPBc//4HjxwHoJr+8k2KYLr+8E2STYAdnPcwAAqGEocrr/gODKIcEP
-yiLBB8ogYQHKI4EPAAACAcokIQAAB2HuyiUBAc9wAAAMMADZmrnc/yDez3WgAMgf0KUK2EMdGBAA
-2AoNr++NuNGlz3AAAAwwANmaucz/iiAJBDoLr+9vIUMAaQGP7/HA7giv7wDZB9gacTpwAN5AKAAh
-FHjHcIAAaK0VII0DAJWMIAKNAN+E9owghYLJ9v/YALWKIBEDMg9v7wDZAZ0LCFMPjCA/gUf24bWK
-IBEDGg9v7wDZAebPfrkOEpNCIUAgQCBBIKcIdYAveeEAj+/xwOHFz3CAAKwJAJDPcYAAaK2o2gHd
-gCBECxB4pg3v/6lzgODKIcEPyiLBB8ogYQHKI4EPAADAAMokIQAIBmHuyiUBAdP/z3CAAMw+sQCv
-77Sg4HjxwDYIj+8SDc//z3aAAKwJZtgibgHaWg3v/0hziegKIcAP63IF2M3biiSBCTPwAhYFEUwl
-AIDMJYKPAAD//wv0CiHAD+tyBdjQ26kFb+6KJIEJZ9jJcQHaFg3v/0hziugKIcAP63IF2NPbiiTB
-CRPwAZYkbgHaAeAQePYM7/9Ic6GWjegKIcAP63IF2NbbQCVEEGEFb+5KJQAAAm0QeCZuAdrODO//
-SHOK6AohwA/rcqGWBdjZ20AlhBDt8eUHT+/xwFoPT++hwRpwOnJodrcJcgAA2JpxFSANIM9xgACs
-CQAVkxACFZIQunDjjSGRAY0B2jhgEHiLcXYM7/9IcxLoABQAMUAqgiAEIIEPAAAA/0e5VHotCRAg
-x3KAAFRVFfDPcIAArAnBkKGNCiHAD+tyBdj22wAmRBO5BG/uCiVABcdygAD8VQAawgQE7gKqA/AB
-qicIHgAN7gOKgLgDqhJvFHgbYmOLWGCBu2Oo5KoE7iaqA/AlqkIkQSBdCXWAQCVAIOkGb++hwPHA
-z3CAAPRYDtkB2gDby//PcIAALFkJ2QHaSHPH/89wgABQWSrZANoA28T/z3CAAPhZC9kA2gHbwP/R
-wOB+4HjxwI7/7/+mDg//DggAAHb/9fHgePHASg5P76PBSiEAIItxKnBKIAAhCnJ+C+//KnOA4Moh
-wQ/KIsEHyiBhAcojgQ8AAO4AyiRBBOADYe7KJQEEABSFMM9xgAC0CQAZQgFMJQCAyiHLD8oiywfK
-IGsByiOLDwAA9gCwA2vuyiTLAADAQSgCAkEoDgNTIsQAUybFEAIZAgEDGUIBTCTAgMwl7IDKIckP
-yiLJB8ojiQ8AAPwAeANp7sogaQFBKAIEUyLGAAQZggFBKAIFUyLFAAUZQgFMJkCAzCXhgMohwg/K
-IsIHyiBiAcojgg8AAAIBPANi7sokggFBKAIGUyLEAAYZAgFBKAUHBxlCAUwkQIDMJWyAyiHJD8oi
-yQfKI4kPAAAIAQgDae7KIGkBBBSFMIwlAYSsACwAARlCAQohwA/rcgXYiiNEA+UCb+6Yc891gADU
-4wDfA/AB5+9/QSgBAsO5aQ9DEADeE/BAKYEgNHkKFIAwFSFBAQHmz34UeblhABkEBIAgAiMvIAgk
-AMBBKAEGw7kB4cMOQ5CCwQpwAtoKCu//ANsLFIQwLygBAU4ghQcvJUcBtQ3SgAohwA/rcgXYaQJv
-7oojRAtAIVEgLyFHJEEoAQTDuX8JQqAE8HEOU4BBKAEFw7kKdaUJcgBKIAAgSiIAIAXwQCJSIC8i
-hyRBKAEDw7l3CkMgSiEAIBTwAr7UfgoUgDAVJk4RQCFRIC8hRyQUfgAmgB+AANTjoLCAJQITsH0A
-wEEoAQcB4bsJQ6AwuMO4ACAOBILBqXAC2loJ7/8A2wsUhDAvKAEBTiCFBy8lRwGrDfKAz34KIcAP
-63IF2LkBb+6KI4UBQCBQIC8gByRBKAEFw7lpCEKg09kIuQDYA97Pc4AA1OMA2rJoVH19ZTi1AeJP
-elYhAQjxCrKAMHlhvgHg5w51kA94/QNv76PA4HjxwBUIcgC4cA0N0wMA2ACpAKoT8A8NkgiMJQGA
-yiBsAPf2jCUBiYv2jCUCgwf2AtgAqQHYAKrRwOB+jCVChIb2jCVCiQPY9vYKIcAP63IF2IojxgER
-AW/umHPgeOHF4cbPc4AAtAlGk1MiTYAW8jENkRARqwWTMKvEgyndEr0VJQwQwKQoiwfpViABCDB5
-NX3ApQHgBbME8BOrMqsB4kazwcbgf8HF4Hi4cFYhAALxwA0IcgCYcYwgAoCK9gohwA/rcgXYoQBv
-7oojRwfPcIAANGsUIAABgBABAQQpfgEvcsAQQAdCKgMEwbtSugQofgEvcUIpAATBuFK5gePAImkA
-geDAIWkAiCI+AH/cCSIAA4ghPgCJIcEPgODWICsIgOHWISsIzv+J8fHAXgpP76LBQMBBwkAoFAVA
-KRcFAN1AKhMFQCsSBQHeSiWAIal3BPAKdcp3AMAVuBN4FCDABb4M7/cH2QIgUAMCIEAjrgzv9w7Z
-zH4KIUAuBCk+cC9wrH4AIQ11HWUBwBW4E3gUIIAEigzv9wfZAiDWAwImwCN+DO/3DtkEKH4EL3Hs
-fgAhwHQZYUItABVUubz/QiVVIAHmkQ11oM9+CQJv76LA8cDWCU/vCHYacc91gAC0CeaVCvDMfzoM
-7/dAKUBxRbgKca//JpWMIRCAtvYNAk/v8cCaCU/vocE6cQDfgODKIcEPyiLBB8ogYQHKI4EPAABx
-AsokwQBEByHuyiXBA89xgAC0CUWx5rFMIQCgyiXOE2AALgDKJs4TGndadwTwyXcadWpwQCBTAItx
-AdqKDq//ANsAFA0xLyPIJKl2Kb3Ivr/l2SUpFEwiAKDKIMIDyiGCA8oiAgSoDuL/yiNCA8lwqXGH
-/0IhUSC3CXWgQCJSIMlwqXHL/00Bb++hwPHA6ghP75pwGnHPdYAAtAnFjQSNHmaSdsohzA/KIswH
-yiBsAcojjA8AANICyiQMBYwGLO7KJYwDAN8A3iLwANgIrWpwitkqcsP/CI1TJ8EQGLnDuBy4BXnP
-eBC4BXmKIFQNEg8v7wUhgQQvIcgEELmKIFQN/g4v7wUhQQQB5s9+ACUCFEaKAWo1DgMQQCyAIBR4
-9XjUeM9zgADU4xBjCiIAoDJv7PNAIJMALyPIJNR5O2MwExEBxeoB2MTxAefvf3sP0pB5AE/v8cAm
-CE/vocEIdXpxGnLPcYAAtAnFiQSJHmZydsohzA/KIswHyiBsAcojjA8AABsDyiTMBMAFLO7KJYwD
-AN8A3h/wARSAMAEdEhAGEYEgARSAMITpAR0SECDAAxSCMAEUgTAYuBS6BXoCFIAwELgFeooglA02
-Di/vRXkB5s9+z3GAALQJACEABAaIAeBzDiMQACERBEArgCAUePV41HjPcYAA1OM0IRIAUyfAEBi4
-z3kQuQV5iiCUDfINL+8FIYEEANkvChAgi3FKcALapgyv/wDbcwgRgAohwA/rcgXYiiMMDAokgAQR
-BS/uSiWAAAEdUhAGEYAgw+gBHVIQv/EB5+9/Pw/SkBfx8cDhxQDdoKOB4MwhIYAX8gsKEwigowDY
-CfDA4gbYBvZCIgAIQ7gC4ACjUHkQuRB9iiCUDW4NL++leW0HD+/gePHA4g4v7wDYocFIdohyCiJA
-IQohgCEKwQogwCFMJkCAAKHMJmyQzCCsoM72CiHAD+tyBdiKI04LCiRABHEEL+4KJQAETCFAoMwg
-IaDKIcEPyiLBB8ojgQ8AALMDBdju82hwhiD8A0S4ZN+EKAEJL3WAJQ8aw7t7Y3V7KMBEKr4MfWUC
-JU0eGwhRAFt6TXqLcypwCnHL/wDAFXgVeAJ9qXDCCO/3ZNnseAIlRB6J4MogagLKIgoASfaA4Mog
-KwDKIgsAg/ZBaEAozyD1f89zgAAwcxUnARBVf3lh+2MbCREghu6oEQ6GqBMAhhHwihEOhooTAIYL
-8IfukBEOgJATAIAF8BgRDoAYEwCAKcGB4Yoh/gDAJkEQwCBBAMJ4iHEseC9wQgjv92TZuGDYYDYI
-7/cK2SjgSCABAIwhQ4LKIYoPAADIAM9wgAAcbpkgQQc1eMAQAAaMIkKgJbgQeET2jCIBoA72CiHA
-D+tyBdiKI1ENiiRCADkDL+4KJYAEz3GAACxsWSHBDxUhgQSAEQEGLbkweSx4CsBCKYR1jCTHjwAY
-AAHKIc0PyiLNB8ogbQHKI40PAACUBPgCLe7KJQ0EiiCUDaILL++IcXUFL++hwAAAAAAAAAAAAAAA
-AAAAAQAAAAAAAAAQEYAApBGAAAB0gAAQAIAAjASAAAQIwBAKABNkbAWAgQAAwBYEARNiD1wAIgoA
-AEAABgBwGgAAYQAAEyQAABMlAADAF8ggwBBwRcAQEAjAEAAAEyQAABMlBAjAEQ8UFSIEABUm+/8w
-MgMAEyQYCMARHAjAEQ8UFSIBABUmBAAwMDAAEyTsHMARAwATJFAUwBEEGMARAAATJBBFwBEYCMAR
-D3wTIggAzBEAABMlAAATJDRIxxEPexMiAQATMAQowBEPFBUiBAAVJvQGgIEAAMAWwiwTJAQowBEC
-RhMkBCjAEcJfEyQEKMARD00TIgQQxRECABMk8BzAEQEAEyTsHMARAAATJHAAEyUQHMARAAATJQAA
-EyTgHMARAQATJCQQwBEAAAAhAAATJQAAEyQPRQAiAFwAOQMAAGICYABiAABYOF0AAGEkEMARAIAT
-JDgcwBEPcxMiggETMAQowBEPdBMiAgITMAQowBEPdRMiQgITMAQowBEPFBUiAQAVJg9yEyIIAMwR
-D0QAIgoAAEAAQABwDgAAYQAAEyUCABMk7BzAEQ92EyIYCMoRCQATQBwIyhEJABNAIAjKEQ94EyIE
-AMoRAAABJAAAASUGAABhD3YTIixIxxEPeBMiAADGEQMAASQAAAElAAATJcIsEyQEKMARAkYTJAQo
-wBHCXxMkBCjAEQ9FACIAXAA5JwAAZAAAEyQBABMlOBzAEQ93EyLgHMARDwETIgQIwBEPAhMiBCjA
-EQ8HEyIEKMARDwQTIgQowBECAHFwBwAAYf8AEyUCEBMkBCjAEQAAEyUAABMkyEnHEQYAAGEAABMl
-AhATJAQowBEAABMlSQATJMhJxxEPcBMiAQATMAQowBEDABMkAAATJQQIwBEAABMkOEXAEQ8DEyIY
-KMARBAAAYQAAWDgAABMkAQATJTgcwBEAAAAhpHOAgQAAwBY8BMARMAWAgQAAwBYEARtiEATAEAMA
-GyRUBMARJATAEQgEwBBkc4CBAADAFwgEwBBAc4CBAADAFwAAGyUDHBtiQAAbJDAcwBEFAABhNAWA
-gQAAwBYPGxkiCASggTjwxIAAABskAgAbJTgcwBEAAAAhMAWAgQAAwBZMBMARNAWAgQAAwBYPGxki
-SASggTjwxIAAABskAgAbJTgcwBEAAAAhAAAAhTAFgIEAAMAWDxsEIhAEG2YPARtoFBzAEAoAG0AE
-ABtuAwAAYQ8cHSIBAB0m+Q8AYWQMABAAwAYRAQAEJ/wABGQAABskAgAbJTgcwBEAAAAhAAAbJUAA
-GyQwHMARAAAAIQ8cHSIYAR0mGADHEPyagIEAAMAXIADHEASbgIEAAMAXAAAAIbQygIECAFxuEQAA
-YfhBxBAPGwkiAAsJOQIACmIDAQpiBAIKYgAACUAEAABhCQAJQAIAAGEKAAlAAAAAYQIACUEACRoo
-AADAFgEAGyYAAMAXBAAdJgEACCfpAAhkAAAAIQAAAACMAQAAAQEBAQEAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AABoOAAALDoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSMgAAAAAAAAAAA
-AAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwACQANAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAMAAADImoAAAAAAAAAAAABAn4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiKSAAOSZAQAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAA
-AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEBAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAABAAIAAAAAAAAABwAAAAcAAAAHAAAAAgAAAAIAAACDAAAAkgAAAOgA
-AAD3AAAATgEAAF0BAAAAAAEAAgAAAAYACAAJAAAABwAAAAAAAAACAAAAAgAAAIMAAACSAAAA6AAA
-APcAAABOAQAAXQEAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAgwAAAJIAAADo
-AAAA9wAAAE4BAABdAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiagAD8/wEAAAAAAMiagACgBgIAAAAAAAAAAADI
-moAAOAgCAAAAAAAAAAAAAAAAAMiagAAAAAAAAAAAAAEADwBkAAEAHAmAAAAAAAAAAAAABwAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAKgaAgCoGgIAqBoCAKwaAgAAAAAAHQAA
-AAAAAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIECAAIECAAAAAA
-AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs
-CAAAFQAAAAwvgACAKgAAgCoAAIAqAAC8QAAAgCoAAIAqAABAPAAAgCoAAIAqAACAKgAAgCoAAIAq
-AACAKgAAgCoAAIAqAACAKgAAIB4AAMgfAADgHwAATCEAAMwhAABQIQAAgCoAAIAqAAAETQAAxE4A
-AKxPAACAKgAAgCoAAIAqAACISwAA7GEAAOhhAABAYgAAgCoAAIAqAACAKgAAyEIAAIAqAAAkYgAA
-gCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAADAQAAAgCoAAIAqAACAKgAAgCoAAIAqAACA
-KgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAq
-AACAKgAAgCoAAIAqAAC0QwAAgCoAAIAqAACAKgAAgCoAAIAqAACYRAAAgCoAAIAqAACAKgAAgCoA
-AIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAAAYaQAAgCoAADxqAACAKgAAgCoAAIAqAACAKgAA
-gCoAAIAqAACAKgAAgCoAANRsAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACA
-KgAAgCoAAAh/AQBYggEAgCoAAKSEAQCAKgAAUIYBAHRTAQCAKgAAgCoAAHBQAACAKgAAgCoAAIAq
-AACAKgAAgCoAAID4AQDU+AEAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoA
-AIAqAABodAAAgCoAAIAqAACAKgAAWP4BAIAqAABAAgIAgCoAACgpAgCAKgAA8CQAAPQkAACAKgAA
-gCoAANAZAgAodwAAgCoAAIAqAACAKgAADPwBAIAqAACAKgAA3EwBALCdAQCAKgAAgCoAAIAqAAB4
-pgEAkFQBAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAGypAQCAKgAAyBgCAMwYAgDYGAIA3BgCANAY
-AgDUGAIA4BgCAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAGBSAACAKgAAgCoA
-AIAqAACAKgAAgCoAABwYAgBsGAIArEYAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAA
-gCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACA
-KgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAq
-AAAkSAAArEgAADxJAADwSQAA3IUAAMhJAACAKgAAgCoAAIAqAACAKgAAgCoAABxIAAAgSAAAgCoA
-AIAqAACgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAMAABgDAAAYAwA
-AGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAA
-YAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAACQ
-DQAAAAAAAORZAQBgDAAAhAkAAGAMAABgDAAAYAwAALQJAADMPAEA/IcAAGAMAABgDAAA6AkAAOgJ
-AADoCQAA6AkAAOgJAADoCQAA6AkAAGAMAABgDAAAYAwAAGAMAADQCwAAYAwAAGAMAABgDAAAYAwA
-AGAMAACUDQAAYAwAAGAMAABoCQAAAwAAAOQMAgACAAAAyGcBAAQAAAB4aAEABQAAALANAAAGAAAA
-NDMAAAgAAABIGAIAEwAAAGT5AQAJAAAA3AMCAAoAAADkGAIADgAAAMyaAQAPAAAAfIgBABAAAAC0
-iAEAGAAAAExZAQANAAAATIABABcAAAAkdwAAEQAAAFCGAAASAAAA5EsBAAEAAADc/QEAFAAAALin
-AQAVAAAA4J0BAAcAAABEbQAAFgAAABgpAgAZAAAAkA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
-////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAA4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e
-4eEDDh7hPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAA
-AAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUV
-PDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8
-PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6
-rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqv
-AEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwAAAAAA3sMJAAAAAAAAAAAA
-AAAAAIwrAQABAAAAzC6AAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAAAwjBEAIL8CAAAAAAD8
-KwEAoCwBAKQtAQBMLwEApC0BAEwvAQD8MAEAhDEBAOQxAQCAgICAgICAgAGAAoCAgICAAAAAALQ3
-AQC0NwEAAAAAAAAAAAAAAAAAAAAAALQ3AQC0NwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AMwugADMLoAApCCgADggoAABAAAA/P///wAAAAAAAAAA7C6AAOwugACoIKAAPCCgAAgAAADz////
-AAAAAAAAAAAML4AADC+AAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA
-AAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAA8EwBAAUAAAAML4AAKFIBAAD/AwBIUgEAAP8FACxT
-AQAA/y0AUFMBAAD/PQAIUwEAAP8EAOxSAQAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAACUWAEABgAAAMwugAAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAA
-AAAAxF8BAMBgAQA4YQEAWFwBAIhbAQBkYgEA6GIBACxjAQB8YwEAAAAAAAMAAAACAAAAAwAAAAMA
-AAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAARGkBAAoAAADMLoAAAAAAAAAAAAAAAAAA0GkB
-AAoAAADMLoAAAAAAAAAAAAAAAAAAhGoBAAoAAADMLoAAAAAAAAAAAAAAAAAApGsBAAoAAADMLoAA
-AAAAAAAAAAAAAAAACGoBAAoAAADMLoAAAAAAAAAAAAAAAAAAHGsBAAoAAADMLoAAAAAAABAAAAAA
-gAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+
-AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6A
-AAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAA
-AAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAK
-AAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAA
-AAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAADCEAQAKAAAAzC6AAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMiwEAkIwBAGCPAQAMkgEAhJQBAOiXAQA0jgEARAWA
-AJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdJoBAAYAAADMLoAA/////wAAAAD/////
-/////wAAAAAAAAAAAAAAAECdAQAFAAAADC+AAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDA
-AKAAUACAAL4AUAF9AD4AAAAAAAEBAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA///
-AAC5Ad8AsQAbABYBGwB8ARsArwAbABQBGwB6ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAz
-AG4AMwBwADMAcgAzANcAMwA9ATMA1AEGANABAAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA
-5ABaAEoBWgCqAD8AqwABAA8BPwAQAQEAdQE/AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACm
-ADcApwABAAsBNwAMAQEAcQE3AHIBAQAEAAgAnAHMAJ0BzACeAcwAnwHMANUBzADWAcwA1wHMALQA
-RwAZAUcAgAFHAJAAIgD1ACIAWwEiAKEAiAAGAYgAbAGIAJQAAACVAAAAmADAAJkAoACWAJAAlwAA
-AJQAAQCVAAEAmADAAJkAoACWAJAAlwAAAJQAAgCVAAMAmADAAJkAoACWAJAAlwAAAJQAAwCVAAcA
-mADAAJkAoACWAJAAlwAAAPoAAAD5AAAAAgGQAAMB0wAAAYMA/gATAPwAMwD9AHcA+gABAPkAAQAC
-AZAAAwHTAAABgwD+ABMA/AAzAP0AdwD6AAIA+QADAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoA
-AwD5AAcAAgGSAAMB0wAAAYMA/gATAPwAMwD9AHcAXwEAAGEBAABoAZAAaQHTAGYBgwBkARMAYgEz
-AGMBdwBfAQEAYQEBAGgBkABpAdMAZgGDAGQBEwBiATMAYwF3AF8BAgBhAQMAaAGQAGkB0wBmAYMA
-ZAETAGIBMwBjAXcAXwEDAGEBBwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwCFAAAAhgAAAIcAUACI
-AAAAiQCgAIoAAACLANAAjAAAAIUAAQCGAAEAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQACAIYA
-AwCHAFAAiAAAAIkAoACKAAAAiwDQAIwAAACFAAMAhgAHAIcAUACIAAAAiQCgAIoAAACLANAAjAAA
-AOsAAADqAAAA7ABQAO0AAADuAKAA7wAAAPAA0ADxAAAA6wABAOoAAQDsAFAA7QAAAO4AoADvAAAA
-8ADQAPEAAADrAAIA6gADAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAwDqAAcA7ABQAO0AAADu
-AKAA7wAAAPAA0ADxAAAAUQEAAFABAABSAVAAUwEAAFQBoABVAQAAVgHQAFcBAABRAQEAUAEBAFIB
-UABTAQAAVAGgAFUBAABWAdAAVwEAAFEBAgBQAQMAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQED
-AFABBwBSAVAAUwEAAFQBoABVAQAAVgHQAFcBAAD7/wAA//8AALkB3wCxABsAFgEbAHwBGwCvABsA
-FAEbAHoBGwBsAKAA0QCgADcBoABvAIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDU
-AQYA0AEAAH4APADjADwASQE8AHgASQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABAB
-AQB1AT8AdgEBAHkAagDeAGoARAFqAKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEB
-AAQACACcAcwAnQHMAJ4BzACfAYgA1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIA
-oQCIAAYBiABsAYgA+gAAAPkAAAACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAEA+QABAAIBlwAD
-AdAAAAGNAP4AEQD8ADMA/QB3APoAAgD5AAMAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gADAPkA
-BwACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwBfAQAAYQEAAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3
-AF8BAQBhAQEAaAGXAGkB0ABmAY0AZAERAGIBMwBjAXcAXwECAGEBAwBoAZcAaQHQAGYBjQBkAREA
-YgEzAGMBdwBfAQMAYQEHAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AOsAAADqAAAA7ABVAO0AAADu
-AKoA7wAAAPAA3QDxAAAA6wABAOoAAQDsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAIA6gADAOwA
-VQDtAAAA7gCqAO8AAADwAN0A8QAAAOsAAwDqAAcA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAAUQEA
-AFABAABSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABRAQEAUAEBAFIBVQBTAQAAVAGqAFUBAABWAd0A
-VwEAAFEBAgBQAQMAUgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEDAFABBwBSAVUAUwEAAFQBqgBV
-AQAAVgHdAFcBAAD7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KgB
-AJDJAQCwpYAAQAUAAAAAAADcqAEA/KkBAPCqgAD4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-XM4BAGjMAQDorIAAVAAAAAAAAADcqAEAlMwBAGitgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
-AAAA3KgBALDIAQC8P4AAUAEAAAAAAADcqAEAyMoBAPgGgAACAAAAAAAAANyoAQAgywEA/AaAAAQA
-AAAAAAAAWM4BAPypAQA8rYAAKgAAAAAAAADcqAEAvMsBAAAAAAAAAAAAAAAAANyoAQB8ywEAAAeA
-AAQAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALAAwADAANAA4A
-DgAPACYAJwAoACgAKQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwAbABtAG4AbgBv
-AHAAcABxAHIAcgBzAHQAdAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA8A
-PwAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAKAAsAJAAkACUAJgAm
-ACcARABEAEUARgBGAEcASABIAEkASgBKAEsATABMAE0AagBqAGsAbABsAG0AbgBuAG8AcABwAHEA
-cgByAHMAdAB0AHUAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AA4APwDE
-owEAEtIAAAAAAAD//w8A6LcBALYAAAAAAAAA/wAAAOi3AQC3AAAAAAAAAP8AAADotwEAuAAAAAAA
-AAD/AAAA6LcBALkAAAAAAAAA/wAAAOi3AQC6AAAAAAAAAP8AAADotwEAuwAAAAAAAAD/AAAA6LcB
-AL0AAAAAAAAA/wAAAOi3AQC+AAAAAAAAAP8AAADotwEAvwAAAAAAAAD/AAAA6LcBAMAAAAAAAAAA
-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
-ENIC0gHSA9Ib0gvSAIAF0hLSE9IU0gRDCNIJ0grSHNIG0gfScNIAAAEAAAAAAAAAAAAAAAAAAAAD
-AAAABAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAALUAGgGBAQQADwCDAOgATgGSAPcAXQEGAAgACQAKAAsADAAFAAAAAAAAACwAAQAA
-AAAAAAAAAAAAAAAAAAAAAAABAAEAAQAAAP////8AAAAALQEAAN0BAABaAgAAugIAAAoDAABNAwAA
-hwMAALoDAADoAwAAEQQAADcEAABZBAAAegQAAJgEAAC0BAAAzgQAAOcEAAD+BAAAFQUAACoFAAA+
-BQAAUQUAAGQFAAB1BQAAhgUAAJcFAACnBQAAtgUAAMUFAADTBQAA4QUAAO4FAAD7BQAACAYAABQG
-AAAgBgAAKwYAADcGAABCBgAATAYAAFcGAABhBgAAawYAAHUGAAB+BgAAiAYAAJEGAACaBgAAogYA
-AKsGAAC0BgAAvAYAAMQGAADMBgAA1AYAANsGAADjBgAA6gYAAPIGAAD5BgAAAAcAAAcHAAAOBwAA
-FAcAABsHAAAiBwAAKAcAAC4HAAA1BwAAOwcAAEEHAABHBwAATQcAAFMHAABYBwAAXgcAAGQHAABp
-BwAAbwcAAHQHAAB5BwAAfwcAAIQHAACJBwAAjgcAAJMHAACYBwAAnQcAAKIHAACnBwAAqwcAALAH
-AAC1BwAAuQcAAL4HAADCBwAAxwcAAMsHAADQBwAA1AcAANgHAADcBwAA4QcAAOUHAADpBwAA7QcA
-APEHAAD1BwAA+QcAAP0HAAABCAAABQgAAAgIAAAMCAAAEAgAABQIAAAXCAAAGwgAAB8IAAAiCAAA
-JggAACkIAAAtCAAAMAgAADQIAAA3CAAAOwgAAD4IAABBCAAARQgAAEgIAABLCAAATwgAAFIIAABV
-CAAAWAgAAFsIAABfCAAAYggAAGUIAABoCAAAawgAAG4IAABxCAAAdAgAAHcIAAB6CAAAfQgAAIAI
-AACCCAAAhQgAAIgIAACLCAAAjggAAJEIAACTCAAAlggAAJkIAAA4AAAAaAAAAHQAAACAAAAAjAAA
-AJ0AAAAHAAAAAAAAAAAAAAAKAAAADdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIEQwjSCdIK0hzS
-BtIH0nDSAAABAAAAAAAAAAAAAAAAAAAAAwAAAAQAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAA
-AAAA/wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1ABoBgQEEAA8AgwDoAE4BkgD3AF0B
-BgAIAAkACgALAAwABQAAAAAAAAAsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAADfAAAAGQEA
-AGIBAAC+AQAAMgIAAMMCAAB7AwAAYgQAAIQFAADyBgAAvggAAAILAAABAAAAAgAAAAAAAAAL0g7S
-DdII0gnSCtIS0hPSFNIR0hDSAtIB0gPSAIAF0gRDG9Ic0gTSAEUw0jHSAAAAAAAAAQAAAAEAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAADAAAABAAAAAMAAAAAAAAA/wMAAAMA
-AAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAALUAGgGBAQUABAAPABAACgALAAwATgAA
-AAAAAAAAAAAALAABAAAAAQABAAEAAAAAAAAAAAABAAEAAgACAAIAAwADAAQABAAFAAUABgAGAAcA
-BwAIAAgACQAJAAoACgALAAsADAAMAA0ADQAOAA4ADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQFgACQmoAAGAAAAFCagAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAMz/AQAGAAAAzC6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAARAWAAJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADM
-LoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAA
-AAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAwAoC
-AAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADMLoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAA
-AAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADMLoAAAAAAAAAAAAAA
-AAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYA
-AADMLoAARAWAAJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMEBAQEBAUGBwgICAgICQoLDA0AAAAFBgcI
-DQ4PEBUWFxgZAAAKDREUCg0RFBkZGRkKCgAAAAAAAAYGBgYJCQkJAAYAAG47aDtiO1w7bjpoOmI6
-XDpuOWg5YjlcOW4raCtiK1wrbipoKmIqXCpuKWgpYilcKW4baBtiG1wbbhpoGmIaXBpuGWgZYhlc
-GW4YaBhiGFwYbhdoF2IXXBduFmgWYhZcFm4VaBViFVwVbhRoFGIUXBRuE2gTYhNcE24SaBJiElwS
-bhFoEWIRXBFuEGgQYhBcEFcQUhBNEEkQbgFoAWIBXAFuAGgAYgBcAG47aDtiO1w7bjpoOmI6XDpu
-OWg5YjlcOW44aDhiOFw4bjdoN2I3XDduKWgpYilcKW4oaChiKFwobidoJ2InXCduGWgZYhlcGW4Y
-aBhiGFwYbhdoF2IXXBduCWgJYglcCW4IaAhiCFwIbgdoB2IHXAduBmgGYgZcBm4FaAViBVwFbgRo
-BGIEXARuA2gDYgNcA24CaAJiAlwCbgFoAWIBXAFuAGgAYgBcAAAAAAAAAAAAAAAAAEArAgAIAAAA
-DC+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////8A
-Af//AgP///8E//////////////////////8F/wb/B/8I/wn/Cv8L/wz///8N////Dv///w////8Q
-//////////////////////////////////////////////8R////Ev///xP///8U////Ff///xb/
-//8X////GP///xn///8a////G/////8c////Hf///x7///8f////IP///yH/////////////////
-/////yIjJP8lJif//yj///8p////////////////////////////////////////////////////
-//////////////////////////8BBAAAAgUBAAMGAgAEBwMABQgEAAYJBQAHCgYACAsHAAkMCAAK
-DQkACw4KAAwPCwANEAwADhENAAFAAAQCQQEEA0ICBARDAwQFRAQEBkUFBAdGBgQIRwcECUgIBLcT
-IgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUAJCIG
-ACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBwMRQA
-dDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJBgIs
-SgoCNEsNATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAABBgIGBgYDBgYGBgYGBgQAAAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/
-AAEAAAAPAD8AAQAAAA8APwACAAAADwA/AAEAAAAAAAAAAQAAAAIAAAADAAAAAAAAAAQAAAACAAAA
-BQAAAA8UGR4oCgUAsAkBpQA8ODQwLCgkIBwYFBAMCAQADAgEADw4NDAsKCQgHBgUEAwIBAIIAA4A
-AAAOAQEAAQIBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AKXGhPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pF
-vyP3U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8J
-DjYkmxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBA
-H+PIee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+
-XcCAigWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6
-KzKV5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3v
-Q6bEqDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dz
-UZcjy3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsysz
-IrvScKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTos
-AQEBAQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQE
-BAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgME
-BgZ00UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8P
-BwYHAgMEBQABCAkLCigAKAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA
-9ACwACwALAA8ADQAMAAsAFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZ
-AOgACgG6AHkAiACKBSoDOQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUA
-QQKsAJAAhACAAHgAeAB4AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzE
-Tid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUF
-BVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN
-0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4
-gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiA
-CgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAa
-QB2AIIAGAA2AEwAaACcANIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6m
-FeYcWSvMOQBBM0jZCqYVgCBZKwBBplaAYVlsMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkA
-AAAAAAAAAAAAABggFBQODhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIA
-AEAAAAAABAAAQAAAAEAAAAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZH
-SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8z
-EwAAAAcHDwcPDxctAA8gAPBhAAAAAAAAAAAAAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDk6NDk6MDkAAAAATi2uAGmu
-oK6QrmIAAaysegCskpusrF8ACQAAAAIAAAAAAAAAAAAAAAkAAAACAAAAAAAAAAAAAAAJAAAAAwAA
-AAEAAAAJAAAACQAAAAIAAAACAAAACQAAAAECAQIDBAAABQYHCAkKAAAABQYAAgQABQAAAAAABQcB
-AwQABQEAAABAI0AlISEhIUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARA
-QEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFBAAAABwRAAAcMgAAHDMAAAQA
-AAAcFQAAAgAXAGwAcAR0CHQMAAQEBgAAAAAAAAAAZAAAAACQAQAKAAAAAAAAAAAAAAAAAAAA/wAA
-AAAAAAAAAAAAAAAAAAAAAAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAA
-HHsBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAABAAAZAAAAIyB
-AQCUgQEAnIEBAPCBAQD4gQEAAIIBAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
-BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACiVDvU56
-lQAHFCdZLgAAAAQOCR0tNwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAA
-AAPAAAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAAB
-RgYIEQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIA
-AOAAAAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYAAQAA
-AAMAAAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAEAAAB
-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
-9JcGAKGEBgCHcQYApl4GAPtLBgCHOQYASicGAEEVBgBuAwYAz/EFAGPgBQArzwUAJb4FAFGtBQCu
-nAUAPIwFAPp7BQDoawUABVwFAFBMBQDKPAUAcS0FAEQeBQBFDwUAcQAFAMnxBABM4wQA+dQEANDG
-BADRuAQA+qoEAE2dBADHjwQAaYIEADJ1BAAiaAQAOFsEAHROBADVQQQAXDUEAAYpBADWHAQAyBAE
-AN4EBAAX+QMAc+0DAPHhAwCQ1gMAUcsDADLAAwA0tQMAV6oDAJmfAwD7lAMAfIoDABuAAwDZdQMA
-tmsDAK9hAwDHVwMA+00DAExEAwC5OgMAQjEDAOgnAwCoHgMAhBUDAHoMAwCLAwMAtvoCAPvxAgBZ
-6QIA0eACAGLYAgAM0AIAzscCAKi/AgCatwIAo68CAMSnAgD8nwIAS5gCALCQAgAsiQIAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAA5////87///+1////nP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AOf////O////tf///5z///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn////zv///7X///+c////
-EwEAAOEAAACvAAAAfQAAAH0AAACvAAAAyAAAAMgAAADIAAAAyAAAABMBAADhAAAArwAAAH0AAAB9
-AAAArwAAAMgAAADIAAAAyAAAAMgAAAATAQAA4QAAAK8AAAB9AAAAfQAAAK8AAADIAAAAyAAAAMgA
-AADIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJYAAACWAAAAlgAA
-AJYAAACWAAAAfQAAAH0AAAB9AAAAfQAAAH0AAACWAAAAlgAAAJYAAACWAAAAlgAAAH0AAAB9AAAA
-fQAAAH0AAAB9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF4BAAAs
-AQAAEwEAAPoAAADhAAAAyAAAAK8AAAB9AAAAZAAAAGQAAABeAQAALAEAABMBAAD6AAAA4QAAAMgA
-AACvAAAAfQAAAGQAAABkAAAAAAAAAP////8AAAAAAAAAAAEAAAAAAAAAYAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAA
-AAAAAAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0AAAAGAAAABAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAA=
-====
diff --git a/sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu b/sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu
new file mode 100644
index 0000000..2cfa6cc
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu
@@ -0,0 +1,8152 @@
+Copyright (c) 2006-2010, Intel Corporation.
+All rights reserved.
+
+Redistribution. Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+ is permitted.
+
+Limited patent license. Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses. The patent license shall not apply to
+any other combinations which include this software. No hardware per
+se is licensed hereunder.
+
+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+COPYRIGHT OWNER 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.
+begin-base64 644 iwlwifi-6000-9.193.4.1.fw.uu
+AQTBCf5MAAAUSAIAAEABAJhFAgAAQAEAAAAAACAggA8AAEAAaSAAAGkgQABpIAAAaSBAACAggA8A
+AOgAaSAAAGkgQABpIAAAaSBAACAggA8AAHgGaSAAAGkgQABpIAAASiAAAEohAABKIgAASiMAAEok
+AABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBKJgAQSicAEEogACBKIQAgSiIA
+IEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/gQAAQEEsnDBALJwwQiQcNAoigD+AADCD
+CiMANz4IQABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgABkBEB4ICBAhwAAAAAAAAAAAADh
+wOHB4cLPcKAAyB8WEAGGz3KAAJiXIKISEAGGIaITEAGGIqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8A
+uP9WoYoh/w8SGFiAExhYgBQYWIAVGFiAJBhYgMHCwcHBwCAgQIcMyM9yoADIHw4aGIANyA8aGIAO
+yBAaGIAPEgE2AcgkeBEaGIAQyC0aGIDgfuHE/BzIvvwcSL7hwOHB4cLhw/wcCLH8HEix/ByIsfwc
+yLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDhxPHAz3CgANAbFIDPcYAAYAQEIICPz1EE
+4QChCvIvKQEAz3CAANwN8CBAAEB42v/RwMHEayTAEMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0
+BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZAfsHEaySAFMHEICBAhwzIh7gMGhgwDcib
+uA0aGDAOyA4aGDAPyIe4DxoYMBDIEBoYMOB+4HjxwAzIlbgMGhgwDcibuA0aGDAPyIq4jbiQuA8a
+GDDPcIAAHA8YiIHgC/QPyM9xAAD0DKy4DxoYMJYOIAAP2GfYdgsgAYohRwbRwOB+8cDPcIAAsMcA
+gIYg/oEJ9A/IBSCADwAAANQPGhgwof+KIFUFRgsgAYohhwro8eB4z3EDAEANz3CgAKggLaDPcYAA
+jARAgQFqAKHPcKAAOC4FgAQggA/AAAAA13DAAAAACvJI2M9xnwC4/xqhW6Fp2Bi4GaHPcIAAaAgl
+gCOBIIHHcQAAiBNFBsAJ4HjPcIAAaAjVBcAJ4HjxwLIMAAGA4M93gABgBIh1BfKB4AX0AdgC8ADY
+C6+A4QXygeEF9AHYAvAA2AqvgOIF8oHiBfQB2ALwANgMrwDYz3agAMgfGB4YkAuPgOCKIRAAD/II
+j4DgC/LPcAMAQA1FHhgQMKYC2BgeGJAC8DGmCo+A4BnyCY+A4Bfyz3ACABJIIB4YkM9wgAAoACEe
+GJDPcIAAXAQiHhiQGBYAlkUgAAMYHhiQDI+A4AjyGBYAloUgAQQYHhiQgeMH9BgWAJaIuBgeGJDP
+cIAAMIwAkI7gzCCiggb0GBYAloC4GB4YkIDlGfIA2JS4z3WAAIAEAKVx2Aa4+g0gAfzZIIXPcAAA
+TBzuDSABn7kYFgCWhbgYHhiQCQQAAeB4z3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFp
+IEAA/vHgePHApcFBwELBDBwAMRAcQDHPcYAAfIQ0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8hCAY
+QAvPcIAAfIQcGAALz3CAAHyEGBjACs9wgAB8hBQYgArPcIAAfIQQGMAIz3CAAHyEDBiACM9wgAB8
+hAgYQAjPcYAAAISAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
+QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
+ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
+gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybF
+Nde6AebTvsSgUyPABAUmjh/Q/gAA1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYw
+WgggARAUBzDPcKAAtA+8oM9xoADIOy6B8g/gAH3YcgiAAU4MIAGpcAjYANn6CyABmbnPcIAAMIwA
+kI7gzCCigsoggQ/gAMQxyiEhACQJYQHPIaEF/QXP//HAagkgAXvYqg/gAPDZz3GAAHyENBnADzAZ
+AA8sGcAOKBmADiQZQA7PcIAAfIQgGEALz3CAAHyEHBgAC89wgAB8hBgYwArPcIAAfIQUGIAKz3CA
+AHyEEBjACM9wgAB8hAwYgAjPcIAAfIQIGEAIz3GAAACEgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAH
+aBmABmQZQAZgGQAGXBnABVgZgAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIo
+GYACJBlAAiAZAAIcGcABGBmAARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAB
+yBkAAGogAAHEGQAAaiDAAMAZAABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAAAogwCfP
+daAAyB8ZFRKWz3AAAEQcvghgAQohwC96cM9wgAAcQSOAz3afALj/z3CAAAAARICA4QHiUyLDBCTy
+GRUCllEiwIAe8l2GQN+fv/2mZKAFI4MP0P4AAHamWB6AFyEVAJYiFQCWBCGBD/8A/P8AgRamCNgZ
+HRiQVqZdpvkHwADQ2Z+5PaZkoAUjgw/Q/gAAdqYH2DoIYAEKuFMgQQcH2PoJIAEKuM9woADUCxiA
+QiAACEggAADPd4AAgAzPcYAAgAQggdQfABALIcCEyiUiE8ogYgAy9EwigKAP9FEjgKUJ8oDgB/RB
+K00lwL0c5QHYJPAE3SHwjCIEoBzyTCIAohTyCvZMIkCgDvJMIgChFPQT3RPwTCIApAryjCIBoAz0
+Ft0L8A3dCfAU3QfwFd0F8BfdA/AP3QDYgeAG9FgewBSyCkACcYepcCpxCnIKJIAEnQPv/wolwATt
+Ac//8cBeDcAAddgaDeAAiiFKD8IMAAAaCMACS/6iCAAACiHAD+tyBtiKI4sDSiQAAGUD7/8KJQAB
+4HiA4fHAA/Kg4Iv2CiHAD+tyBdj020okQABBA+//uHPPcoAA3A0VeiCi0cDgfgDZnrkZec9ygADU
+DQGCJXjgfwGiANmeuRl5z3KAANQNAYImeOB/AaIA2Z65GXnPcIAA1A0BgCR4QiAAgOB/yiBiAOB4
+z3CAANQNAYDgfy8oAQDgePHAog+P/+B44HjgeOB4aSCAAW8hPwBpIAAA9/HxwGrYSgzgAIohBAYA
+2I24NglgBQoaGDAUzIYg/4oJ8s9wgAAYBQCIgOCcDkIFsPHxwMIOQAXPcYAAgAjwIQAAQHjPcKAA
+0BuA2lCgz3CAAAAAAIBRIACCANkG8s9wnwC4/z2glPHgePHAxg3AAM9xgAAAAACBUSDAgBvyAYFR
+IMCAQNjPIOIHyiCBDwAA0ADPIOEHz3KfALj/HaIEgQHg07gEoQUggA/Q/gAAFqLPcIAAYASggM9w
+gAAcDwiABCWNHw8AAODruAHeBvT+CwAMgOAO9M9xoAC0RwDYSxkYgHcZmIMA2J64VBkYgM9ygACY
+BCCC4YIEJYQfAQAAAEAsgACkeAQlgx8AAABAB3kDuyCipHsEeWd/BiVAEOGiBCWBHwAAAIAvIgIB
+RXkCueR7BCWNHwIAAABmeKR5JngvKAEATiBBBM9wgAB0g/AgQgDPcIAATM2EKgsMMCBADlMgQIAb
+GlgwLfTPcJ8AuP84oIbhGfTPcoAAiJYJkoDgDPIbGpgzyXHPcoAAgAwcggHgHKIX8AySgOAT8gTZ
+GxpYMPPxhOHMIWKAC/TPcIAAiJYOkIDgBfIG2RsaWDDl8c9yoAAUBCqiz3CAAOQHAIiB4AX0CYK4
+4ADYgvcB2IDgCPTPcKAAiCA1eMCgOfDPcYAAIAUA2AChANmRuc9woADIHxMYWIDPcIAA0AIQeM91
+oAC0R0kdGJDPcYAAZKbPcIAAJAUgoG8nQxBUHdiTGg8gBQoamDOWCgAMgOAR9ADYkbjPcaAAyB8T
+GRiAz3CAAAAEEHhJHRiQVB3Ykz0EwADgePHAzgvAAM9xgABYDYARAADPdaAAyB8vLgEQz3ADAEAN
+n+ZFHRgQAN8f8s9ygAAAAACC8rgZ8gGC8rhA288j4gfKI4EPAADQAM8j4QfPcJ8AuP99oGSCAePT
+u2SiBSODD9D+AAB2oPAhgANAeJ/mDPLPcIAAAAAAgPK4BvLPcJ8AuP/9oIDYFR0YkK0DwADgePHA
+z3GAAGAEfNhWCeAAIIEKIcAP63IF2IojhANKJAAArQev/wolAAHxwOHFz3CAAGAEoIBr2AQljR8P
+AADgIgngAIohCAgvKEEDGgjgD04gQAQKJQCAyiHCD8oiwgfKIGIByiOCDwAAJgJkB6L/yiRiAH/Y
+CrjPcaAA0BsToX/YEKE1A8AA4HjxwOHFz3WAAAAAAIXvuBryAYXvuEDYzyDiB8oggQ8AANAAzyDh
+B89xnwC4/x2hBIUB4NO4BKUFIIAP0P4AABaha9iWCOAAiiHIDJIPoA8E2AolAIDKIcIPyiLCB8og
+YgHKI4IPAAA1AtwGov/KJGIAAIXvuAbyANnPcJ8AuP89oK0CwABKJAB2ANmoIMADz3CAAFwONnhh
+gECAz3CAAFgNAeFVeGCg4H7gfuB4USFAxwXyDci9uA0aGDAA2Z25z3CgANAbMaDgfuB+4HjxwIHg
+zCCigAX0z3KAABwPBPDPcoAAYMrPcYAAtJeB4Mwg4oAp9GiCYKFpgmGhfIpoqX2KaakqEoMAaqkr
+EoMAa6ksEoMAbKl0knapbZJnsXeSaLFogsC7dKloggQjgw8ABgAAgOMB28B7cqmEEgIAVBmYABzw
+YIFoomGBaaJoiXyqaYl9qmqJKhrCAGuJKxrCAGyJLBrCAHaJdLJnkW2yaJF3slQRAwaEGsAAguAG
+9O4MIAFAIQAG0cDgfs9wgABgyiCAz3KgAIAlJqIikCeiIoAqoiaQK6LPcYAAsMcggVEhQIAggBX0
+KKIikCmiIoAxoiaQMqIigDeiJpA4oiKAO6ImkDyiIIA5oiKQOqIggDWiIpA2olkEABDgePHAzgjA
+AM9wgAB4rgDe1KjPcIAAsMcAgFEgQIAT8gjfyXWA5cwlopDMJSKRzCVikdgI4gXKIEIDYb+A5wHl
+M/cc8IokAXHPcYAAiJaoIEABBBmQA+B4ANlKJAByz3KAAOCYqCAAAxYiQAB2kM9wgAAAlzR4AeFg
+sM91gABgys93gADwqkAlABIkb9IN4AAG2qlwQCeBEsYN4AAG2kAlABJAJwEUtg3gAAbaGI2E4A/0
+iiAPCjoOoACKIdoMKBWAEK4LIBEohTIKwA8JhVEgQIEJ8ooghw4aDqAAiiGbAn4PwAnPcIAAsMcA
+gFEgQIBgDoEDz3EAAP//z3CAAKSnLKAroAUamDOn/y0AwADxwMIPoAAA2oQoCwwAIYN/gABgyrUb
+mADPdoAAAGy0aLpmUoIChgAhgX+AAFzMz3eAAASZuhuYAGGG3BnAAGWG4BkAAAaG5BnAAOgZAAAW
+J4AQFiaBEAjgBOGyDeAFCNrdZRSFFn4Wf0AnABIkbp4N4AUI2rUHgADxwADY4f82D+AFANjPcIAA
+rEVKCYAJz3CAAOxFPgmACcIJAAb2C0AEAdgA2YIOIA+A2uoPQAzyD4APSg7ACY4IAAuWDUAKANha
+DCAQCHHPcIAAXGMAiFEggIAI8s9xoADAHQCBoLgAoXoIAA0KDwAKqQXP//HA4cUA3c9wgABMBaCg
+z3CAAFyurLBqCSAKqXCiCY//SgqgDKlwMgxABvoLwAWqD0ALzgrgDKlwmgrADBEHgADxwJoOgACC
+4KPBBvTPdYAAHA8I8IQoCwwAIY1/gABgyoLgBvTPdoAArLQJ8M9xgAAozYQoCwwAIU4OLZU8eihw
+hiHxD0e5wrqGIP4DJHpEuFBxyiHCD8oiwgfKIGIByiOCDwAAUATKJCIAvAKi/8olAgFIhTu6UyIC
+gECuTZXAukGuDPJ3lYYj/wlDu2eud5WGI/4HRbtoroDiEvLPcoAA9E4VIgMAAIs1egKuAYsDrgKL
+BK4DiwWuA4oL8AHZKa4C2AKuI64A2ASuA9gFrgaui3DJcQoM4AUM2gDAAcGiCyANAsKLcMlx9gvg
+BQzaAMABwQ4MIA0Cws9xgADABgChDZVEuOC4ANkvpQXyiiEIAC+l4bgD8ou5L6VRIICABPKNuS+l
+4QWgAKPA4HjxwGoNoACYcIQoCwwAIYB/gABgylUgRgoogFUgxQtRIcCAiiEIAMohIQDYGEQASiQA
+cgDZqCCAD891gABYcPyILmXkfi8qgQNOIoMHz3KAAHxwb2IAJkMA4KtUEI8A5H4vLoETTiaPF+5i
+yKvIgFEmwJAP8l2IhuHTIqYALyqBAE4ijQfPcoAAhHCqYhDwz3aAAGxwLmbOZbyIxH1sEI4AxH0v
+LUETTiWOF8piUKsB4UokAHIA2qgggQDciM9zgABkcE9jz3WAAHxw5H4vKYEDTiGPB+9lACaBAPyp
+VBCPAOR+Ly6BE04mjxfuZSQZggPIgFEmwJAP8n2IgOLTI6EALyvBAE4jjQfPc4AAhHCrYxHwgOID
+8slqAvBIds5jfIjEe2wQjgDEey8rwQBOI44Hy2UsGcIAAeJKJABxANqoIEAFz3GAAGBwfYhJYQAl
+jAAB4mR5LylBAE4hgwfPcYAAhHBpYSCsJgjgCIhwZQSAAPHA+guAAILgBfTPcYAAHA8H8IQoCwwA
+IYF/gABgyumBWIlBL8MQwLsXu8dzAACAHOS/zyMiBuC/Tt3PI6IAyiWCHwAATgGG4s8lYRLlvyz0
+z3KAALSXFhKFAM9ygABszUaSsHLPdoAAYMrFFgQWDPTEFgIWUyIFAM9ygAC0l1SKsHIL8kEsQgFR
+IgCABfJJhlEiQIEJ9FEkQIEG9EmGUSJAgQPygbvPcoAAVM1UiofizyPhAFEnAJLPI6IFguCIGcAA
+jBlAAwb0z3GAABwPCPCEKAsMACGBf4AAYMppEYMAThEOAQ4jgg8AADoBCbpifkV+WpFiehK6RX5b
+kWJ6QCrNBcV9BCW+nwDwAADKIcIPyiLCB8ogYgHKI4IPAADqAM8j4gLKJMIAYAdi/8olQgOC4JAZ
+QAMG9M91gAAcDwjwhCgLDAAhjX+AAGDKz3CAADCMAJCO4MwgooIq8gfYDgvgAAq4BCCADwcAAAAw
+uIfgZAANADMmAHCAAGRsQCcBchR5AHmKIAQAlB0AEB7wiiAQAJQdABAa8ADYi7iUHQAQFPAA2Iy4
+lB0AEBDwANiNuJQdABAK8APYDLiUHQAQBvAA2I64lB0AEIIgAQGVAqAAlB0AEAohwA/rcgXYz3MA
+AB8JSiQAAKUGb/8KJQAB4HjxwAoKgACC4Ah1BvTPdoAAHA8I8IQtCxwAIY5/gABgygHZaB5CEADf
+gB7AE0zYTh4EEAXYEKYK2Bu2ENgathTYTB4EEC3YUB4EECbYUh4EEEokAHLpcKgggA3PcoAAuHD0
+IgMAz3KAALyoFHpgss9ygADIcPQiAwDPcoAAzKgUemCyz3KAANhw9CIDAM9ygADcqBR6YLLPcoAA
+6HD0IgMAz3KAAOyoFHpgss9ygAD4cPQiAwDPcoAA/KgUegHgYLIIhuW4BfIE2mIeghAD8GIewhPk
+uAryCdlqHkQQLtpdtgLaaR6CEArwFNpqHoQQMtpdtmkeQhAU2VmOUSAAgFlhMHlqHkQQGuE8tgry
+CthkHgQQBthmHgQQB9gI8BDYZB4EEGYexBMF2BCmqXCS/jyOKHBUHkIQhiADAOa5bB4CEMoiQQAL
+8lAhwwFvelQewhBQIMMBb3hsHsIQ5bkH8khzhiMDAG96VB7CEOS5BPKluGweAhBRIcCABPKkulQe
+ghCC5RjyqXDH/s9wgAA0zYQtCxwwIEAOUSBAgPHYwCgiAcoggQ8AAJMAwCghAaAeABAY2I24F6YI
+hlEgwIDPcIAAYMoG8r4QgACJuATwpRCAABamz3CgAKwvGYAwuMC4Ng8gEFUeAhAIhgQgvo8ABgAA
+C/I2uMC4G3gB4G4eBBAC2IAeABAD8G4exBMA2BymHaapcAD/KIYB2khzQSkABTW5UiAAAFIhAQDA
+uMC5Lgtv/5hyQQCAAOB4z3CAABwPCIDPcaQAHEDAuBN4wbgSoeB+8cDhxc91gAAcD1eVz3GAAMQG
+4LpX2AChA/Jf2ACh4roD8oW4AKFRIkCABPKHuAChz3GAAKy0QIkA2YDiyiBBAM9xpQDoDwahz3Gg
+AKQwAYGA4s8g4gDQIOEAAaGmDEANMIXPcKAAyBwooBIOoA0PhcEHQADhxc9wgAAcDymARCGDgADa
+JPSQ4ooABgAAIo0PgACYQwCNoLgArYAVgBCguIAdAhBAFYAQoLhAHQIQEI2guBCtkBWAEKC4kB0C
+EFAVgBCguFAdAhAB4t/xkOJGAAYAACKND4AAmEMAjYC4AK2AFYAQgLiAHQIQQBWAEIC4QB0CEBCN
+gLgQrZAVgBCAuJAdAhBQFYAQgLhQHQIQAeLe8ea5EPLPcoAAmEMIioC4CKqIEoAAgLiIGgIASBKA
+AIC4EvCA4xL0z3KAAJhDCIqguAiqiBKAAKC4iBoCAEgSgACguEgaAgBRIQCAANge8kokAHTgeKgg
+QAbiuBTyACCDD4AAmEMgE4EAgLkgG0IAoBOBAIC5oBtCAGATgQCAuWAbQgAB4B3wSiQAdOB4qCBA
+BuK4FPIAIIMPgACYQyATggCguiAbggCgE4IAoLqgG4IAYBOCAKC6YBuCAAHg4H/BxeB48cDmDWAA
+B9rPdqAAyB9IHpiQz3WAABwPgBUAEM9xqwCg/0weGJAA2BmhWqEYoYogBAAPpmoVABHPd4AAMIyw
+HgAQtB4AEB/YCLgOpgiFUSAAgADYi7gV8hCmVgzAD89xoACkMAGBhLgBoQSXheAa9ADZlLnPcKAA
+BEQloBLwEaZ+DMAPz3GgAKQwAYGkuAGhBJeF4Ab0z3GgAAREANgFoc9wgADMBACA4LgK8oYg/w4i
+uBS4z3GgAAREBaFW/8oJAA1b/3f/z3AAAFVVWh4YkAHYWR4YkAiFz3GmACgA87gG8gDYD6GaDAAQ
+BPAB2A+hbhUBEc9wpgDoByag/g/ABM4PoAwNlQePgOAL8oog2An2CmAAAdm+CSADAtgE8JIO4AQB
+2IgVABDPcaAAxCcPGRiAjBUCEM9woAAwEESgz3CAALShEHiPGRiAz3KAAGSiUHiWIgIAELpFeJAZ
+GICKIAQAkhkYgJAVABBAl0AZAIDPcIAAmENTGRiADxEAho7in7gPGRiAzCKiggj0CBEAgIUghAAI
+GQCAiuIH9AgRAICKuAgZAIAP2BAZAICUFQAQHBkYgAiF/bgN8rYPoA8A2LoPoA8B2M9xpgD0zwHY
+EqED8KIPgA95BEAA4HjxwAYMQAAKJQCQz3CAAGDKGnEF9MUQAQYC8CmAJblRIQCAKPLPcoAAtJfP
+cYAAbM0mkXaKMHMI9MQQAQZUisC5UHEL8sUQAQZRIUCBBfIpgFEhQIEO9AohwA/rcgXYz3MAADYJ
+SiQAADEAb/8KJQABhC0LHC93z3aAABwP+GDJccoIoAAp2s9xgACstAAngB+AACjNAgmgAAzaz3Cg
+ALQPAN/8oEiGUyIAADIJYAw0lkIIAANc/4DlVArhDMogYQAEyFEggIAF8roPAAML8ADZnrnPcKAA
+/EQhoM9woAC0D/ygTCAAoGQJ4g/KIGIAz3WAAKAEDI2A4AX0AguADQHYDK1pA0AA4HjxwPYKQAAK
+JQCQAdgR8gTIUSCAgAz0CiHAD+tyBdiKIwgDSiQAAG0HL/+4cwDYhC0LHM92gABgygAmTx6EKAsM
+QCYBGTAhQA5JhyW4JbpTIBEAUyISAOlwPg9gAA3Zyg+gEKlwCYeA5SW4UyAQAAb0A9gq/HD8BPBa
+D4APTCAAoB7yTCIAoMohwg/KIsIHyiOCDwAALwLKIGIBxfXuD0AIHgngAAHYTCEAoM93gACwxwX0
+LgnACjIJwAoX8AIJ4AAA2IDlz3eAALDHBPS7/Anw/g6ADwCHUSBAgAQPgg9MIQCgTAuB/6lwBP6+
+C6ABqXBMIQCgBNgEGhgwMfTPcYAAtJfPcIAAbM0GkFaJEHII9MQWABY0icC4MHAP8sUWABZRIECB
+CfIJhlEgQIEF8gCHUSBAgBP0qXAKcXD/f9kRuc9woACwHzSgkglACA/IBSCADwEAAPwPGhgwAIdR
+IECAIPLPcYAAtJfPcIAAbM0GkFaJEHIH9MQWABY0icC4MHAJ8sUWABZRIECBCYbRIGKBCPQYjs9x
+gAAcDxipCYYJoQHe9gwgDMlwz3CAAKEGDgsgDMCogeUM9M9wgABUzRSIh+AG9EwgAKB0DoIPSg6A
+D0IPQAh+DUAAugugAgDYdQFAAOB48cAA2Ib/hgsP/89xgAC0lxaJNgigEDSJ1QdP//HA/ghAAIHg
+z3aAAGDKGnAD9KmGA/DFFg0WJb2EKAssACZPHgmHwL1RIECByiHBD8oiwQfKIGEByiOBDwAAwQLK
+JCEATAUh/8olAQTPcIAAcA9MIACgAYjMcTT0QIHPcYAAtJdAoQAWA0CA4GGhABaDQGipABaDQGmp
+ABYAQQPyD7YAFoBABCKCDwAGAAAKqQAWgECA4gupABaAQAHaDKkAFoBAABYAQcB6B7EAFgBBCLEA
+FgBAUqliDm//BNg58CCBz3KAAFjOxB5YEAAWAUCA4MUeWBAAFoFAFBpCgAAWgUAVGkKAzHAH8iCQ
+z3CAAGzNIbAC8ACQABaAQM9xgABcziIaAoAAFoBAIxoCgAAWgEAkGgKAABaAQAAWAEEOGQSAABYA
+QSIZBIAAFgBALyAHBHL9cgmgAQpwz3GAALSXFomA5c9ygABszUaSHvRQcAf0xBYAFjSJwLgwcBHy
+xRYAFlEgQIEN8gmGUSBAgQnyz3CAALDHAIBRIECABvQphwpwJbnAud3+jgyAD8YLQADRBwAA8cAA
+2Jr/z3GAALSXFomKDmAQNIkpBk//8cAA2c9woAC0DzygkgwADeoJQA2WDgAM/g1gDQDY/9nPcKsA
+oP85oALYfgtgAAQaGDD1BU//4HiEKAsMACGAf4AAXMzgEAIAz3GAALCZ3BADAGAZgIDkEAIA6BAA
+AFwZwIBsGYCA4H9wGQCA8cDiDiAAEtmpwQh2Vg1gAItwSiQAcQDaqCCAAhYkgDAoiIHhw/ZhuSio
+AeIBwgLBhC4LHAAhgH+AAFzM3BiAAAXC4BhAAAbBtG7kGIAAx3WAAABsSBUREOgYQADPcIAABJkK
+IEAuFiBABAjgg8HGDGAFCNr0hc9wgAAEmYfB9ngI4LIMYAUI2gDAACCNL4AAYMpRIACAtR0YEAjy
+uh3YE7sVABaAuAfwuh1YFLsVABaguLsdGBDPcIAANMpUiDaIRCo+CwAhgH+AAJDINXgGiBB2/A7h
+/8oggQO1FQAWUSBAgPHYwCgiAcoggQ8AAJMAwCghAUYKYACgHQAQRQYgAKnA4HgA2H7x8cClwYtw
+cgpgAAXZAMLguhPyz3CAABwPGIiB4A30ANiauM9xoADIHw+hAcCkGQAAw9gauA6hUSKAgBbyBhIC
+NgDZSiQAcuB4qCCAA7hxg3EoiREiQIAAIkAxZBhCAAnyQCVBAM4JQAClwNHA4H4KIcAP63IF2Ioj
+jwj5AS//SiRAAOB48cDPcIAAHA8JgFEgQIHKIcIPyiLCB8ogYgHKI4IPAAApB8okYgDIASL/yiXC
+AMoOQAzWD2AJAdjPcIAAVM0UiIfgI/TPcIAASM0LgFEgQIEb8s9wgADcyAqQz3GAAKiuJYEKuDBw
+yiHCD8oiwgfKIGIByiOCDwAAMwfKJCIAcAEi/8olwgDCD8/+agggDADYQg7ACxoJQACVA0//8cAC
+2K38tv2JA0//8cC2DAAAAN7PdaAAtA/cpXYKIAxod/j/ogugDOlwBMhRIICABPIKCQADCfAA2Z65
+z3CgAPxEIaDcpeUEAADgeIQoCwzPcYAASM0wIUIOz3CAAOCYVnh2kM9xgAC0l8QZ3AAXkM9zgACw
+mcUZHADPcIAABJlWeAyIkBsCgADY4H/HGRwA8cDqDE//+giAD1YNT//1Ak//4HjxwCIMIABE2s91
+gAAAbMRtz3GAAAiZlglgAKlwSiSAcADZqCCACBRp2GBxgIQpCwwAIYJ/gABgygAhgH+AAFzMuhrY
+AADbtRrYAGGFQoUB4dwYwABlheAYgABGheQYwADoGIAAKQQAAM9wgAC0l/kEIACKIQUF4HjxwKIL
+IAAA2qHBQMIAFo5AABaNQAAWg0AAFpBAgOUd8ql3z3GAANS0I4mGJ/wXRb/DveZ54LnKIkIDYMLh
+ucoiQgPKIiEAARyCMFEhgIDKJSEQAhxCM4DgJPTPcIAAtJe2iPSIsXPMJsGTEfIKIcAP63JAKwQE
+EL4F2Ioj3gIFJEQDtQfv/gUmxRMAxUAgDgbPd4AAYMpUGFgDhB9AEyHwz3CAAGzNBpAQcwr0z3eA
+AGDKxBcAFsC4EHYN8gohwA/rcgXYiiMeBZhzbQfv/kolAAAAxc92gAD8yN0fWBNAIEEgSSEBBjR5
+Ug8gAMlwQiDAJUggAACA4ADby/cA2gAWAUAB4oPivfcB4xBzuPdWJgAZKg8gAAbZz3CAALDHAIBR
+IECAGvLPcYAAtJfPcIAAbM0GkFaJEHIH9MQXABY0icC4EHEK8sUXABZRIECBBvIJh1EgQIEO9AIO
+YADJcM9wgACYD6KgiiASDV4IIACpcYYOAACRAiAAocDgeADYQvHxwKHBi3C2DiAAAdkAFAUwTCUA
+gMohwQ/KIsEHyiBhAcojgQ8AAMwHjAbh/sokYQDPcIAA1LRCDiAAAxhCAaHA0cDgfvHA4gkAAM9z
+gABUEEODAN/PdaAALCCwhdJq1H5+ZqWmBKYB4owiEIAmpkOjhfcCg+OjAeACoxUCAADgeADYz3Gg
+AMgfGKEZoQHYDqHgfuB48cBqCQAACHe6cdpy+nMKIgAhCiNAIQohgCHPcAAAyBviCWAACiDAIRtw
+z3AAAMwb0glAADtwz3AAAAQcxglAAM92oADIH5pwAdgTpgXYz3WAAMAPAKXhpQ7AIB0AFAmlFYYc
+HUAUCqUYhhgdwBQLpRmGFB2AFAyloBYAEBAdwBUNpaQWABAMHYAVDqWoFgAQCB1AFQ+lz3ABAMEJ
+EKVmCWAAKNgRpV4JYAAA2BKlUyfAdROlAshUHQAXFqUSFgCWUB0AFxelExYAls9ygADADxilFBYA
+llMkASMZpRUWAJYQuRqlJBYAlkokQHkbpRYWAJYcpc9wgACADBGAHaXPcIAAwA94GIAKz3CAAMAP
+fBjACs9wgAA8EAQYAAuEGkALz3CgAMgcCICIGgAAz3CAAHAFAICMGgAALyAHBgi4BXkvIEcGJXiQ
+GgAAANioIEAC8CIDAM9xnwC4/wHgdqFNAAAA4Hj8HIi2/BxItvwcCLb8HMi1/ByItfwcSLX8HAi1
+/BzItPwciLT8HEi0/BwItPwcyLP8HIiz/BxIs+B+4HgE3DjdNfDgeATcNN0z8OB4BNww3THw4HgE
+3CzdL/DgeATcKN0t8OB4BNwk3Svw4HgE3CDdKfDgeATcHN0n8OB4BNwY3SXw4HgE3BTdI/DgeATc
+EN0h8OB4BNwM3R/w4HgE3AjdHPDgeATcBN0Z8DQUGjAwFBkwLBQYMCgUFzAkFBYwIBQVMBwUFDAY
+FBMwFBQSMBAUETAMFBAwAscBxrAkTTOwJB8z4H7xwM9xgACADBGh4HjgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB40cDgfuB44cXhxkApDQIlfUAtAxSI4qV7CHWQ
+91MlfpAG8gEdUhBhuvvxQSqOAMG6QiZOkAQd0BD99YDiCvIvJIlw4HioIIABAR1SEOB4wcbgf8HF
+4HgocgDZ1vHgePHArg7P/6HBCHfPdqAArC8ZhgQggA9wAAAA13AgAAAAAdjAeC8mB/AodRpyE/SK
+IEkGogzv/4ohTQg5hpYM7/+KIAkGiiAJBooM7/+pcQDYJPARzAAcRDNPIMEDAeAQeAQggA8AAP+/
+j7gCHEQwERocMJ4NoA9AJwASB+cEJ48fAAD8/wUnABSduJ+47HEAoQDB7HAgoAHYeQbv/6HA4Hgi
+uQbw7HJgogTgYbmB4WCAOvcA2c9woADUC22gz3CgAEQdNaDgfuB48cDuDc//CHYodShwSHFocsr/
+geDKIIEDwA/h/8ohQQM5Bs//4cXPcoAAsASkioDlz3KfALj/BvLPc9C6/sp+ohqiO6KA5Q7yz3Cg
+ADguBYAEIIAPwAAAANdwwAAAAPbzadgYuBmi4H/BxeB48cB+Dc//CHfPcYAAsAQFiQDegOCpwUDG
+Q/QB3aWpz3GAAICOz3CgAMwrLaAA2I+4ERocMCEagjMSDCANi3CeCwAIz3ABAMEJQcCKIFAAQsDP
+cIAA/HoAiGTFAt0RHAIwAMASHEIzExwCMM9wgABUEEXAz3CAAMAPRsDPcIAAcAUAgEPGINkB2kfA
+SMeBwD3bF7vB/wjYAdnI/wQaWDNJBe//qcAD2s9xoAAUBEWhz3GgANQLDaHgfvHA4cXPcqAA1AsD
+3bGiANtwogUSAjfXcgAAAEAB2sIiigAXusdyAA4AAEUiAgadup+67HVApQLaIBqCMAgSDTbscqCi
+ERICNwHiERqcMOxyAKICEgI27HBAoOxwIKAB2M91oADIHxOlOIXscCCgGYXf/3Qd2JDPcaAAyDsO
+gYi4DqG9BM//4HjxwADYCBKBMNz/CBKFMAohwA/rcgfYiiPRCLUA7/5KJAAA4HgA2gPwAeJBKIEA
+MHK89+B+z3GAAIAMRBnAB89xoADIH1yBnbieuE0ZGIDgeOB44HjgeOB44HjgeOB4HIHgfuB4A9rP
+caAAFARFoc9xoAD8Cwyp4H4D2s9xoAAUBEWhz3GgAAgMALHgfgXMANrXcAAAAEAB2MIgCgAXuMdw
+AA4AAE8ggQCduZ+57HAgoM9woAAUBAPZJaACEgE2z3CgANQLLaDPcKAARB1VoOB+gOFU8kAhwgPD
+uY/hnAAtACS6MyZBcIAAcGxAJ4NyNHsAewAWAUAEGFAAABYBQAQYUAAAFgFABBhQAAAWAUAEGFAA
+ABYBQAQYUAAAFgFABBhQAAAWAUAEGFAAABYBQAQYUAAAFgFABBhQAAAWAUAEGFAAABYBQAQYUAAA
+FgFABBhQAAAWAUAEGFAAABYBQAQYUAAAFgFABBhQAAAWAUBCIkKABBhQAL/14H7geIDi4cUi8mNq
+wbqD4jwALQAiuzMmgnCAAIBsQCeNclR9AH0EEAIEBBmQAAQQAgQEGZAABBACBAQZkABCI0OABBAC
+BAQZkADv9fcEz/+A4uHFU/JAIsMDw7qP4p4ALQAkuzMmgnCAAIRsQCcNclR9AH0BEIIEARmSAAEQ
+ggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCC
+BAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgBCI0OA
+ARCCBAEZkgC+9UsEz//gePHAygnP/yh2RiHNAB1lIrmS/8G+geYO8oLmCPKD5g30ABaAQAEdEhAA
+FoBAAR0SEAAWgEAArQECz//geIDhyiRNcOB46CCtAQAWAUECGFQA4H7geIDhyiRNcOB46CCtAQAW
+gUABGFIA4H7gePHAXgnv/1MhQgBOIg0Bz3KgABQEyYIA2w4mgh8AAAAGUHHKIcYPyiLGB8ogZgHK
+I4YPAAAMAsokZgCwBab+yiXGAIDhyiRNcMoizQDoIC0CTmDPcaAAOAQB4sipgeUO8oLlCPKD5Q70
+z3CgADgEaKjPcKAAOARoqM9woAA4BGioSQHP/+HFANoP8KCADXOgo6GADXOgo6KADXOgo6OADXOg
+oxDgAeJBKQMBcHKv9wDbBvAEEA0EDXKgogHjUyHCACK6UHO39wDbBvABEI0EDXKgqgHjUyFCAFBz
+uff7As//ANvPcp8AuP8aonuiPqLPcABsBAAZouB+8cBeCO//ANqhwRpwz3DUuv7KQMDPcZ8AuP9o
+GQAEBNgboYtwHqGdus9woADQG1Ggz3AAbQAQGaEF8OII7/+KIEkFUSFAx/vzABQFMAwlgI/Uuv7K
+OvQg3c9zoADIH7CjAdhDGxgAANiNuPz+saPPcZ8AuP9oGQAEBNgboYtwHqEA2J24ExsYgM9wAG0A
+EBmhBfCKCO//iiAJClEhQMf78wAUBTAMJYCP1Lr+ysohwQ/KIsEHyiBhAcojgQ8AAGwCMASh/sok
+AQSBAe//qHDgeM9xgACwBGSJgOPPcp8AuP8F8s9x0Lr+yj6iGqKA4w7yz3CgADguBYAEIIAPwAAA
+ANdwwAAAAPbzatgYuBmiHILgfuB48cBSD6//mHAodkh17P8GIIEDiHCleV3+pQeP/89xoAA0HwSh
+AdgHoQiBgOD+9QWB4H7gePHAGg+v/0okAAIA3c93AAAEHal2FSKAMxwQAQYA2M9yoAAUBMqiqKIn
+ogSiPWWI4Wi5yiEOAOlwR/5CJEQATCQAgCDnAeYo9zkHj/9BKYGACvIvJElw4HioIIABBBACBOxx
+QKHgfuB48cC2Do//CHUodgYOYA9AIQACBczXcAAAAEAB2MIgCgAXuAAggQ8ADgAAB24EIIAPAAD8
+/yV4nbifuOxxAKECEgE27HAgoCK+BfDscQChBOVhvoHmAIU792D+yQaP/+B4B9nPcqAA1AcaGliA
+gOAO8hkSAYYJIEMADxIBhgIgwIB5YQ8aWID29eB+4HihwfHABRICN9dyAAAAQAHawiKKABe6x3IA
+DgAAg7rsc0Cj7HIAoihwSf7RwOB/ocDxwOHFz3CAADCMJoiA4TDyJ4iA4SzyoJBPbYfiCfczJoJw
+gACUbEAngXJUeQB5ANkR8CSQB92A4QHZwHkL8CSQCN2F4QHZwHkF8CSQhOEB2cB5geEM8ggQBQEK
+IcAP63IQ2IojzwkhAq/+mHUBBo//ocHxwIINj//PcoAA/QdAioDiRMCO8oDhDPQKIcAP63IF2Ioj
+Tw1KJEAA7QGv/rhzYIGA4wTyQYGA4gn0z3KAAKyYcIJgoVGCQaEkxoDmyiHBD8oiwQfKI4EPAAD/
+A8ogYQHj84DiyiHBD8oiwQfKI4EPAAAABMogYQHX8+m4F/IEIIAPAQAAwC64z3KAAFBwCGJJIIAA
+YbgCuBR4x3CAAASqaqAhgSugRPDouBvyoObKJYITyiUhEAQggg8BAADAz3eAAABwzmcEIIAPBgAA
+ADG4LroeZs9wgABQcEhgwngS8FMgwgBdes91gAAwc01lBCCADwEAAMAuuM9ygABQcAhiYbgWfRJt
+FHjHcIAADKlgoJjlIYEhoIz3CiHAD+tyBdiKI5AHiiSDD+0Ar/64dQjcvwSP/+B44cXhxs9xgAD9
+ByCJgOEm8gDbSiQAds9ygAAMqagggAMyazR5JWA+YqCmPWChhRlhoaYigQHjIqZIEAEGSBpYAEkQ
+AQZJGlgASxABBksaWABMEAAGTBoYADUFj//xwPYLr/+4cc9ygAAohQS5MCJEAFEkQIOiwQbyz3OA
+APTNBfDPc4AABMtAIwIGQCMBB1EkQILKIcIPyiLCB8ojgg8AAEUEPACi/sogYgHPdoAAMIhALY0B
+pmbovkDGIMUE8sK9qmEP8FEmQJIH8kQlARxEuSpiiboF8FMlwRA8eSpjz3GAADCHFiFBASKJDrlF
+eSCgzQOv/6LA4HjlAeAHCNjgePHATguv/4ogVw7PdYAAdEBeCa//IIWKIBcHz3GAACxBTgmv/yGB
+AN7ApRDfSiSAc8lxqCAAAhYlQBDhoMKgAeHPcIAA6EBSDK//ENnPcIAA+EBGDK//JNnPcIAALEE6
+DK//INnPcYAAZEDAoeGhAdgIqQmpxbHDoYoglwfyCK//iiFOBs9xgAAQRcChwaEI2AWhxqEC2AKh
+A9gDocShz3ARADCMB6HPcAIAIL8JA6//CKHgePHAngqv/wHZz3CAAGRAIKAA3c92gAC4BBYmQBMD
+gIDg4iACAEAlTZD48+oLr/4G2NkCj//xwGoKj/8Idc9wgABkQKCgz3aAABBFiiBXC24Ir/8ghoog
+VwtiCK//JYaiC6/+BtiC5Q/yAN3PdoAAuAQWJkATBICA4OIgAgBAJU2Q+POJAo//4HjxwBYKj/8I
+doog1wwmCK//yXHPdYAAZEA+DmACw6UDhYDgLPKB4BfyguA39CYOQALPcAAAJDrPcYAAuAQAoc9w
+AAAAPAGhANjZ/1oI4AcF2CPwz3AAABQ6z3GAALgEAKHPcAAAxDwBocT/5g1AAtINQAIA2AmtEfDG
+DUACz3AAABQ6z3GAALgEAKHPcAAAxDwBoQDYxv/tAY//4HjxwIogVweSD2//gNmH/wDY1f/RwOB+
+4HjxwM9wgABkQAOAguDgD6EHyiChAvPx4HjxwOHFCHWKIBcKXg9v/6lxz3GAAGRAA4GC4CD0gOXP
+cIAALEEAgA70IrjAuAmpAtjPcYAAEEUCoQPYA6EA2A3wI7jAuAmpBNjPcYAAEEUCoQXYA6EG2ASh
+ZQGP//HA7giP/891gABkQAOFguAN8hASBDYKIcAP63IF2IojRQlZBW/+SiUAAM4MQALODGACCHaB
+5gHYCK0W9M9wgACMQ8oMQAKSDcAHCHWKINcKug5v/6lxieXMJaKQHA+iB8ogQgP1AI//8cC6DEAC
+z3CAAEyZIIjPcIAAgEPPcoAAZEAhqCiKwLkiqADZI6iCDGACIaKSDEACANmbuc9woADQGzGgcfHg
+ePHAz3CAAGRAA4CC4A30iiBXB1IOb/+KIUYJANi4/wDYb//o/zT/XfHxwM9xgABkQCOBguHMICGA
+mA6hB8ogoQFP8eB48cDPcYAAZEAjgYLhzCAhgHwOoQfKIOEBQfHgePHACiQAgMohwg/KIsIHyiBi
+Acojgg8AANkDWARi/solwgDPcIAAuAQWIAABI6BEoCfx4HjxwK4PT/8IdoogmADCDW//yXHPdYAA
+ZECKIBcOsg1v/yGFIYUA35DhBPQB38GlyXGB5xPyz3CAAEyZFSCCAzV4IIhgijBzCfYBiCGKEHEF
+9gCFgOAN9IogVwd2DW//iiHJDsGl2g2gBwPYAdgC8ADYpQdP//HA4cUIcRDYANtKJIBzz3WAAEyZ
+mHOoIAAHESEAgRTyz3KAAHRAFiICAQQSBQBMJQCEUPcVJUIRQIpQc8ogSwHKI4sAQCREAC8kBwFl
+B0//CiHAD+tyBdhxA2/+iiPHDfHA2g5v/whxz3aAAGRABBYFEEwlAISM9wohwA/rcgXYiiOKBkUD
+b/6KJIMPzgxv/4ogWACKIBcOwgxv/yGGAYbPdYAA6EAJZbIMb/+KIBcHIYYoZYDgigAJAM9wgABM
+mTV44YgQ2AGmz3WAAHRAiiBXDooMb/8ghYogFwd+DG//6XEAhYDgyiAhASnyxf8IcQGmkODKIcEP
+yiLBB8ogYQHKI4EPAAC7AsokwQC8AmH+yiUhAEYMb/+KIBcOIYbPcIAATJk1eAGIEHfL9oogVwcq
+DG//iiGLAAPYkgyAB2UGT//geM9wgABkQAOAgODgf8ogYgDxwNoNT/9acCh3OnJAKAEEiiAYAPIL
+b/9FeUwigKPKIcoPyiLKB8ogagHKI4oPAAD8AsokigRAAmr+yiXKAEwhAKTKIcoPyiLKB8ogagHK
+I4oPAAD9AsokSgQcAmr+yiXKAM92gAB0QBYmjRQEFZAQiiDXDpILb/8KcQwhAKQH9M9wgABkQACA
+XvBMIACkyiBhAELyTCAApMohyg/KIsoHyiBqAcojig8AABEDyiQKBMQBav7KJYoEz3CAAEyZFSAB
+BBUgQARgiECJcHKH9gGIIYkQcUAAKgAA2IogVwcqC2//iiGMBQAggi+AAOhAAIqA4AHZDfQAFgUQ
+CiHAD+tyBdiKI8wGcQFv/gokAARhuACqKHCB4Az0ACGBL4AA6EAAiQQdQBTipQHgAKkAhg8ggAQA
+pipwQf/PcYAAZEAggQO4JXjxBE//8cCeDE//CHUod0h2QCgBBIog2ACqCm//RXnPcYAA+EAgEQQA
+TCQAgcohxg/KIsYHyiBmAcojhg8AAEID8ABm/solJgAWIQABpKjgoMWoQCRAAAihsQRv/wLY4Hjx
+wOHFz3KAAPhACIKA4BPyz3WAALgEYbgIohZ6YIUEiiCCYHtFis9ygAD4QAiCgODz9YkET//gePHA
+AgxP/zpwjuDKIcoPyiLKB8ogagHKI4oPAACyA8okSgR4AGr+yiXKAM92gAB0QBYmTRQEFZAQiiDX
+D+4Jb/8qcYog1w7mCW//CnEA2AKlENgBpQDYDyBABKCGTCAApAZ9oKYt8kwgAKTKIcoPyiLKB8og
+agHKI4oPAADDA8okCgQYAGr+yiVKBAAggS+AAOhAAImA4MohwQ/KIsEHyiBhAcojgQ8AAMQDyiQB
+BOwHIf7KJUEDYbgAqQpwHf+lA0//4HjgfuB44cXhxhDZAN7PdYAATJmfcclzqCAABBEggIMK8hUl
+ghNAilBzyiGLA8ojiwAB5s9+KHDBxuB/wcXxwAYLb/+KIJcPSiAAIM93gAB0QBYJb/8ghw7eCnUA
+hxEgQIML8hYnQBMCgIDgB/JAeAUgAAQvIAcgYb6A5gHlr30v9wDYAKdMIACgAdgdA2//wiAMAOB4
+8cCuCk//CHbPcKAAZC7wII8DGxIQNhsamDP12AW40gxv/8lxG8jPdaAAFAQKpQmFgOCECkIHz3Cg
+AMAvURAAhgsgwIP19c9wAABkHtYKj/8RIICD7fMJhYDg6/UbGhg09dgFuIoMb/8KcRvICqWlAk//
+4HjxwI4OT/+hBg/+4HgAFgFBILAAFoJAUyJBACGgQSrBAFIhAQDAuSioQSqBAMC5KahBKgEBwLkw
+qAAWgUDPcaAAyBwogeB/I6DxwAGAgOAS8oHgGfKC4BnyCiHAD+tyBdiKI8QDSiQAAGUGL/4KJQAB
+AdnPcKAAyBwpoK4Nb/8U2AjwAtn38QHZz3CgAMgcKaDRwOB+gODxwBHygeAS8oLgE/IKIcAP63IF
+2IojBQtKJAAAHQYv/golAAEp2BK4CPAV2BO4BPBPeivYErg1eECg4PHgePHA4cUIdU4Nb/8U2COF
+z3CgAMgcKKDNAU//4HjxwE4JT/+lwYt36XDE/+lw0v8iwIDgGPIAFg5BJMCA4APyABYAQQDdCfAB
+wAAWAkDJcd3/AebQfgHlABQBMTB1tfcU8ADdDfAAFgFBgOIE8gAWAEEBwAAWAkAB5dL/ABQBMTB1
+JMKy9yTAgOAG9FEhAIAE8gAWAEEFzNdwAAAAQAHYwiAKABe4x3AADgAAg7iduJ+47HEAoQISATbs
+cCCg6XDR/9ILb/8B2ADZz3CgAEQdNaABAW//pcDgePHAAYCA4BTygeAQ8oLgEPIKIcAP63IF2Ioj
+BA1KJAAAAQUv/golAAEC2APwAdjPcaAAyBwJoUYMb/8U2FTx4HiA4PHAEfKB4BXyguAW8gohwA/r
+cgXYiiOGB0okAADFBC/+CiUAASnYErjwIEAAAKI68RXYE7j78SvYErj38eB48cASCE//pcGLd+lw
+df/pcNz/ABQBMQXMArnXcAAAAEAB2MIgCgAXuMdwAA4AAAvhBCGBDwAA/P8leJ24n7jscQChAhIB
+NuxwIKAAFAEx7HAgsAkUgDCA4Afyz3CmAJw/GYCB4Pv1IsCA4BfyABYNQSTAgOAD8gAWAEEA3gjw
+7HIBwKlxz/8B5bB9AeYAFAExMHa39xLwAN0L8AAWAUGA4gPyABYAQexyAcDG/wHlABQBMTB1JMKz
+9yTAgOAG9FEhAIAE8gAWAEHpcHj/ggtv/wHYANnPcKAARB01oE7x4HjxwDIPL/8B2AAWgkAAFopA
+ABaJQAAWhkBEJr6DRCKDE8B4CiFAgsohYgAB4YDjyiOBAMojIgCA4MogQgLKICEAQNwEIguTG2Nv
+eyT0BcwB3ddwAAAAQBJrwiVKEwzgF70EIIAPAAD8/8d1AA4AAKV4nbifuOx1AKUCEg027HCgoOx1
+AB2CEuxwYKgA2+xwYLCA4fIALgAA2PhwGXGB4MojgQHKIkECyiOCAkQjgQOC4UolQADCJUIBUiMO
+AMC+RCMADJDgAdvAe6DgAdjAeAUgxAAAFg1AgOFhuk96GPSA4gDf0PcghYDmBOUE9AAWDUBMIwCQ
+A/TscCCgAedQd7T3IIVMIwCQBPTscCCgBiU+gRLygOIA2M33ABYBQIDmIKUE5QT0ABYNQAHgUHC2
+9wAWAEAApQskQIEe8oDiANjT9wAWAUDghYDjA/LneQLw5XkgpYDmBOUE9AAWDUAB4FBwsPcAFgBA
+IIWA4wTyJ3gD8CV4AKVCIEEQgOEgB+3/QCdAAEwjAJAG9NIJb/8B2AfwA9nPcKAAFAQloADZz3Cg
+AEQdNaD1BQ//2QFP//HAhg0v/wDZz3CgANAPNaAAFgNBABYCQem7BcwW8tdwAAAAQAHYwiAKABe4
+ACCNDwAOAABAIgEDz3AAAPz/JHileJ24n7gT8NdwAAAAQAHdwiVKExe9x3UADgAAQCIBA89wAAD8
+/yR4pXjscQChAsjscQCh7HBAsOxxANgAsei7QPIjauO7BCGBDwAA/P8J8s91oAA4BAitAdhhuTB5
+5LsM8qFoCL0Ffc92oAAQBLi2AuAPeGK5MHkA3RTww2gYvuJo738Qv+V+4Wjvfwi/5X4Ffs93oAAU
+BMunBOAPeAHl2mnRdaz3AN4I8M91oAA4BAitAeAPeAHmUyFNALF2t/fluwjyAdnPcKAA0A8RGFiA
+5rsJ8gPYz3GgABQEEKEB2ASh47sG8gAWgUDscCCoYbrkuwnygeLH9wAWAUHscCCwYrpEI4GBQSqA
+ABX0AN4L8M91oAAABOyNABaNQOx14K0B5rJosXZH9+e79PUAFo9A9vGC4RT0ANkK8M91oADUA9yV
+ABYNQex1wLUB4Rt9sXFG9+e78/UAFg5B9/HiuxXygODKJA1w4HjoIO0D57sJ8s9woACYAz2AABYA
+QAPwABYBQOxwIKAA2QbwABaDQOxwYKgB4VMiQAAQcbn30g8v/wHYANjPcaAA0A8RGRiAz3GgABQE
+BKEEyM9xoADQDyK4wLgVoekDD//xwIILL/8A2UokAHLgeKgggAIAFgJAFSJAMBwYmAAB4QAWDUAA
+Fg5APgxP/89woAAUBKygz3CgANQL3KCSDw//rQMP/+HF4cYkiM9ygACcbKaIwrkuYgDZDyGBA4Dl
+z3OAAIyZdhMCBgX0Jnp2G5gAHPBFeXYbWAAliBUjjQN5HVgQJohFiFlhfB1YECCAjCEQgEX3iiEQ
+ACCgI7l3G1gAAIAquHgbGAAA2c9woADwNiygeRMBBiWgfBMBBiagehMBBiegfRMBBiigexMBBimg
+fhMBBiqgdxMBBiugeBMBBi2gdhMBBiSgwcbgf8HF4HjxwOHFosGLdalwGg8v/wLZqXDR/8oOD//t
+Ai//osDgeIDg8cAH9M9wgABkm6oLL/8k2bEAz//gePHAVgov/5hwkODKIcYPyiLGB8ogZgHKI4YP
+AABrA8gG5v3KJSYEANpKJAB0z3aAAMwEqCCAD0AsgwFVe8dzgAAwiCCDz3WAACiFQCwAAd25AGUg
+o/G40SEiggnyoIvPd4AAAHCtZ4HlCvbPdYAAMIcWJQ0RoI1RJQCQBPKeuRbwLbjAuBUmDxDjh1Ih
+TQILJ0CTDfLPdYAAgMqEKAsMMCVAHv647POfuSCjAeIRAg//8cCaCQ//osEAFhFBABYAQUApDiHH
+doAAKIUAhkwhAKQtuFMgEgCO9wohwA/rcgXYiiNUA0okQAD9Be/9CiVABM9wgAAwhxYgQAQacO4N
+L/8C2c9wgACwhxYgQATeDS//AtlAKY0hACWAH4AAMIjODS//ENmLcMYNL/8B2QCGUSBAggfycg0P
+/20BL/+iwAAlgB+AADCIRg2gCxDZARCAIJDgyiHKD8oiygfKI4oPAAA6BYQH6v/KIGoBSiQAdADZ
+qCABChUlQhDPcIAAMIgwIIUABCWDjwAAAAEEHEAxRvIhxs9wgAAAcAQlhA8GAAAAQSxCBM9goOb4
+YtEl4YIx8oDjBPKB5wv2BCWEDwAAACQMJICPAAAAJCPyguJCAA0AguIG9IDjHfKC5xv0gOME8szm
+F/bPcoAAMIxGklB3EfZRJcCCD/LPc4AAgMqEKgssMCNCDgQivo8ABgAAA/QA2wLwAdtvewTwAdgI
+cwQlgg8BAADALrrPdoAAOHNKZlBwAdjCIA0AgOPMICKAEfIB4QIQgCDPcYAAUHAIYYHgHvIKIcAP
+63IF2IojVQQQ8M9zgACAyoQqCywwI0QOCiHAD+tyBdhxBO/9iiOVA0okQABlBO/9SiUAAAMQgCAI
+YYLgyiHCD8oiwgfKI4IPAABTBQXY7vUqcFf/z3CAALCHFiBABECQz3EAABgVCSJBACCwOvHgePHA
+kg/v/gLZz3CAAMwE/g0P/89wgADMBECAz3agAOwnz3egAAREz3WAADCM4Lo+8iuGRCKAAIYi/w4i
+uqG5FLq0uQV6BSGDAAQhgQ8QAAIABCKCDxAAAgBrpiV6RacolYfhzCGigRD0gODPcaAAyBwG8gHY
+HqFaD8ALBvAA2B6hvg/ACwSVheAv9M9wgADMBACAUSDAgCnyBNnPcKAARB0loCOgJKAh8M9woADI
+HAHZPqALhoG4C6YWD8ALBJWF4A70z3CAABwPCIBRIACACPIA2JS4BacLhpS4BvAA2AWnC4a0uAum
+/goP/xEHz/7geOHFNGjPcoAAKIUhYi25wLmEKQsMACGBf4AAYMpIgVEiAIDPcoAA1LRBggnyPImA
+4cUigQ8AAAoCA/JFIkIDSiQAdADbqCCAAjZodXkAIY0PgAAwiEClAeMA3c9zgAAwhxYjAgCgqqGq
+AdkiqgPZI6pKJABxqXGoIMABemEWeqSqAeHgf8HF4HjdA4//2QOP//HAABYAQIHgz3GAABxBAKEN
+9AAWAEAMuAQggA8BAADwAaEAFgBAAqER8ILgABYAQAv0RiDCAEOhABYAQM9woADQG16gA/AAFgBA
+BczXcAAAAEAB2MIgCgAXuMdwAA4AAIO4nbifuOxxAKECEgE27HAgoMoIL/8B2ADZz3CgAEQdNaDl
+A4//4HjxwAAWAkChwUDCARSAMFEgAIAG8s9xgABQqAXwz3GAAGioQKFgiQHaB/AAFgBAFSGMAACk
+AeJ9eBBy+fdRIwCACfIAFgBBA/AA2BUhjAAApAHiheL69wXM13AAAABAAdjCIAoAF7jHcAAOAACD
+uJ24n7jscgCiAhICNuxwQKA2CS//AokA2c9woABEHTWgocDRwOB+8cDhxQAWA0DPcYAAAABgoQAW
+AkAA3UGhABYAQP+7AqEAFgBAA6GkoRDy/7pA2M8g4gfKIIEPAADQAM8g4QfPcZ8AuP8doQbwz3Cf
+ALj/vaAFzNdwAAAAQAHYwiAKABe4x3AADgAAg7iduJ+47HEAoQISATbscCCgpg/v/gHYz3CgAEQd
+taDpBM/+4HjxwOHFz3WAAMwEBG2aCi//CNkBhc9xoAC4HgKhAoUDoZoID/+9BM/+8cDhxaHBAN1A
+xQAWAUAAFgBAgeEa8gXM13AAAABAAdjCIAoAF7jHcAAOAABFIAADnbifuOxxAKECEgE27HAgoOxw
+oKCpcCDwxgogDItwBcwB2ddwAAAAQAHYwiAKABe4x3AADgAAhLiduJ+47HIAogISAjbscECg7HAg
+oADB7HAgoAHY5g7P/s9woABEHbWgKQTv/qHA4HjxwKILz/4KJgCQOnFQ8i8ogQNOII0H2tiyCe/+
+qXEbGlgzQCUAFEogACAPIBAg9dgFuLYN7/6pcRvIz3egABQECqfPcaAAZC7wIQEACYeA4BH0z3Cg
+AMAvURAAhgsgQIAJ9M9wAACwHrILD/8LIACEFfTa2FYJ7/6KIdoHKYdOCe/+2tjPcaAAwC9REQGG
+Pgnv/trYrgzgBipwTgvgA6lwANgPIEADBiYOkLP1z3GAAFAFAIEH2ofgGxqYMB3yz3CgADguBYAE
+IIAPwAAAANdwwAAAAA3y9dgFuM9znwC4/xqjW6Np2Bi4GaMB2ALwANiB4AP0QKHPcKAAFARKoAUD
+z/7gePHA4cUCEg02ABYAQQAWAUHFuIK5uv/iDu/+AhpYMwEDz/7gePHAdgrv/oDYz3egAMAvpRcS
+lhQXEZYA3qUfmJPPcqAAZC4UH5iTLysBAE4jgQfwIkMAZX4A2w8jQwAGIMCA9fVPJsAWpB8YkKQX
+AJb/uP7zoxcAlgQggA8AAAAPjCAQgPjz89gFuIDZVgzv/p+5GxIQNvXYBbgH3UYM7/6pcc9woAAU
+BKqgGxpYMwfwA9nPcKAAFAQloM9woAAUBKmAgOUe8oDl9PNBLYCQCvIvJAlw4HioIIABABYAQOB4
+UyVNkAnyLyRJc+B4qCBAAQAWgEDgeM9woAAUBKmA5fHz2BYKL/8FuP+43/X12AW40gvv/gpxz3Gg
+ABQEKBkABIDmGxoYNCTyLyiBA04ggQeU4coiRQCF9yhygCLCAc9woAAYLPAggwCU4coiRQCF9yhy
+gCLCBM9woABoLFV4YKAA2A8gQAAGJg6Q4PWA2c9woADQGzCgpR+YlBQfWJR5Ac/+4HjxwBYJ7/4X
+2bfBi3eqDe/+6XAjwEohQCBTINIAhiD+A0wiAKRCKBABDByCNI32CiHAD+tyBdiKI88BCiRABHUF
+r/0KJYAEEsYtviDAwL5AKg0hx3WAACiFUSAAgACFhiD3Dzf0gODKIcEPyiLBB8ojgQ8AAM4DBdjh
+8wHAAsFKclYJIARmbYDgH/LJcE4K4ABKcQ0UgDCFIMEADRwCMIog/w9TwACFqbgApUpwDgrgAOlx
+z3CAAIQE1XgggA8hgQQgoCp2AvAC3kpwbv4G8IDgyiZBFMomIhKB5ln0E8EAhRLCJnhEeSV4AKUM
+HQIUz3CAAEiGANkWIIAEQIUgoPW6IaAF9ADZi7khoPa6BfIhgIUhAQ4hoCoI4ADpcA0UgTDluQXy
+WBQAMQW14bkE8lAUADECtVEhAIEG8kpwygogBFUUgTANFIAwUSDAgB3yNcFWFAIxSnAmCyAEEsO4
+cIwgAoDKIcEPyiLBB8ogYQHKI4EPAAA7BDwEof3KJGEAUSXAgcomIhFKcFH9BczXcAAAAEAB2MIg
+CgAXuMdwAA4AAIO4nbifuOxxAKECEgE27HAgoJoK7/7JcADZz3CgAEQdNaCxB6/+t8DxwFIPj/6k
+wQHdgcDiC+/+qXEA3k3wgsDWC+/+AtkCwItymg7gAwPBpHgvJQeQQPIAwQDYz3eAACiFDyBAAAS5
+IWcvIQogLblTIRAAz3GAAEwFQIEEIYCgAKEH9IDi5AoiCcogIgggwNYJIAQQ2QDBANiKIwgAVGn6
+YgKyYKKA22iqaarPcoAAhAQVIgIEYIIEI0MEYKLPcoAASIY2egCiAaLPcoAAKIY0egCyAeYhwBB2
+ZgfF/wXM13AAAABAAdjCIAoAF7jHcAAOAACDuJ24n7jscQChAhIBNuxwIKCmCu/+qXDNBq/+pMDg
+ePHAZg3AA7oKz/65BE//4HjxwF4Oj/6EKAsMz3KAAIQE8CINAAAhgX+AAGDKaIEEI4IPgAAAAEQj
+DwIvuga/RX8EI4IPAAEAAEEqTgMsuuV+RX7PcoAAzAQVegOCEHY18gQjvo+AAQAAI/LPcIAAVM0U
+iIfgHfTPcIAAsMcAgFEgQIAX8r67aKFEIwACBrgEI4EPgAAAAC+5JXgEI4MPAAEAAEErQQMleCy7
+BSMOAIDlw6IL8i8pQQNOIYAHECUNENb8gOX49REGj/7gePHAosGLcNoL7/4I2QDAgODPcYAAeAQA
+oQfyBhQAMQOxBBQAMQKxzgnP/qLA0cDgfvHApMGLcKoL7/4Q2QXM13AAAABAAdjCIAoAF7jHcAAO
+AACDuJ24n7jscQChAhIBNuxwIKAAwFEgAIADwAb0AsF2DWAEANoF8NoIIAUBwU4Iz/4A2c9woABE
+HTWgpMDRwOB+4HjB2c9woAAEJSCg4H7xwAYNj/7PcAAARBxmDe/+AN5x2F4N7/4GuM9wAABMHFIN
+7/4I3c9wAADIG0YNz/7PcAAAzBs+Dc/+z3AAAAgcMg3P/s9wAAAEHCoNz/7PcKAA1As4gByAz3Cf
+ALj/WBgACAAmgB8AAMAbCg3v/gTmYb2A5Tf3AN4F3QAmgB8AAAAc8gzv/gTmYb2A5Tf35QSP/uB4
+z3GgANAPGREAhhwRAIbPcKAAyB8VEAKGHoDPcKAAxCcZEAKGnBECABUQAoYtEAKGLhAChi8QAoYw
+EAKGgBECAIQRAgChEAKGkBECAKIQAIaUEQAAmBEAAIwRAACIEQAAGIHPcZ8AuP9YGQAIz3GfALj/
+WBlACM9woADQDzuAOYDPcaYA1AQXEACGLBEAgDARAIA4EQCAz3GgAIgkAIEBgQKBA4EEgQWBBoEH
+gWDx4HjxwOHFz3WAAIibqXBGCO/+A9kBhc9xoACAJQyhAoUNoQCNUSAAgADYjrgE8g+hA/AQod4P
+j/4BBI/+4HjxwH4Lj/7PdYAA4AQAhc92gAC0oeSQ6XHiCqAChiH8A1EgwIAacAXyH4aAuB+mIIUA
+kThgAKVUFoAQgOAV9Olw1gggB4Yg/AOA4AzyUSAAoAvyz3CAABwPCYBRIECABfQfhoK4H6Z9A4/+
+4HjxwBYLj/6iwc9wgAC0oT6ABCGBD///D9AEJYBfAADwLyV4z3WAALSh6gggBx6lgOCEAyEAmB0A
+EM9xgAAAAACB67ga8gGB67hA2M8g4gfKIIEPAADQAM8g4QfPcp8AuP8dogSBAeDTuAShBSCAD9D+
+AAAWolElwNEG8s9wgABwDwKIBvADhfIL4AMkhV6FRCIBDKDhlB0CEAT0gNiUHQIQUSDAgUAoAQZp
+9FEigNOCuRHyRCI+0wz0z3CAALShAYBRIACABPLeCQAHFfDaCgAHEfBFIQAGz3GAAECiKImGIf0P
+UiHBAUW5JXjPcaAAiCQQoc9wgAAIogCIgOAE9FEigNIJ9M9woAAMJBOAUyDAgE3yRCIAU0EogQBN
+cIYg/ANBKAIBUSWA0c9wgAC0oQjyBLlZYcdxgACYQxXwUSVA0wjydGlbYwAjgQ+AANhDC/BRJUDS
+CfIEuTpiACKBD4AAGESsGEAArBACAIDiH/IgipcYQgA82ACqGfCzul6lUSKA08Uhgg8AAAAHRSEA
+Bs9xgABAoiiJhiH9D1IhwQFFuSV4z3GgAIgkEKGKIdYAz3CgAIAlL6DPcaAAxCdBEQCGUSLA088g
+4gLQIOECQRkYgM91gAC0oQCVBCCADwAAzIDXcAAAyIAJ9AuFUSAAgAXytg6AAk/wHoXzuFQVghBp
+8hoRAIaA4gUggA8AAACaGhkYgAfyAdrPcKAA1AtSoATYEBkYgE1xEg9v/oogRA4G8J4Jr/6KIAYC
+USCAxAT0USEAxvjzz3WAALShz3agAMQnLhYBlhaFInhkuBB4hh0EEM9xgAAcD9oIoAcvkRoWAJYE
+IIAP////ABoeGJARFgCW67gJ8gDYi7gTHhiQGtgZHhiQHoVRIICBANmZ8hSVUSBAgZX0z3CgACwg
+D4CA4I/0ENhBwM9wgACwxwCAUSBAgBLyUSVA0xDyAdhAwA3wgOIG8gHaz3CgANQLUqAE2BAZGIDZ
+8UDBK4XPcIAA7MaLcwQhgQ/AAAAAwoA2uREmQJCBwkAgBAsw8uGVx4Bwv/QkQQAIJs4TMHZMAAwA
+lBWBEFEhwIEg9M92oAAsIC+GgOEa9MaGPJUwdsj3z3GAAGSqwoElgDB2EPSA4wTyAtkgoyOAgOKD
+uSOgBPIggqa5IKIBwg7wI4DjuQHCCvIA3p6+z3OgAPxEwaOjuSOgK4UkoCOFJaBUFYAQgOAH8gDA
+guDPImIBAvSHugDBQcJVJUAakgpgAwDbH4WUuB+lHoWQuB6lDfDPcYAAyIwNgQHgDaEQ2c9woACQ
+Iz2gtQdv/qLAz3CkAJBBTYDPcYAAiKBCsRqAUSBAxgOxBCCAD/8AAAAwuASxz3CAAIigANoI8s9x
+gAC0oTGBUSGAggXyQrBDsESw4H9ZsOB48cD+Dm/+mHDPcYAAtKEOkc92gACIoAC2z3CmAOj/C4DP
+daQAtEUDpgwVA5YNFQKWRBGJAC8nxwD/2BC4KXSEJAOcBCMIAAX0USEAkCz0MhUAllMgjwD/ZwG2
+/9j0fwi4739keEAvBRIAJQYAACfHAwUmxgFALwAWBCODDwD/AABALwcUG2MAIMgR/9gFJgYCCLgF
+I4MBBCIGAPpiACZAAQV65bZveAQjgw//AAAAKLtleE96A7ZEtgQVAJYCthGBUSAAgg3yz3CAAABw
+MiBAAoHgx/bPcKYA6P8NgAPwANgGpgWmANhKJIBwBtqNuqggQAMp2xK78COPAEAmAx8VewHi4KMB
+4ACROB4AEVUmQRQats9wgAAAqCYLr/4I2hsVAJbPcaUA2MsZphwVAJYaph0VAJYbpg6BHKYPgR2m
+JhUAlh6mz3CkAJB/HIAZBm/+H6bgePHAmg1v/gDbz3GgAMgfQBEABs93oADQDxkXAJbPcqAAxCdP
+Eg6GuIHPcIAA7MaooBHMEHbPdYAAtKEG8h+FUSCAgATyAd4F8BEanDNodlISEIYVEhOGG9gWGhiA
+USPAoAb0USBAoEoiACAH9B2FAd5adoS4HaVRIwChBvJUFYAQgOAE8gDYBvAdhYW4HaUB2DpwTCIA
+oMwhIaBc8s9ynwC4/1gaAAgQh89wgABwDw+IFqIA2s9woAD8RJ66QaBloB6FsLgepagVABBk4B6h
+ENgOoQHYFRkYgMoIr/4J2FEgQMcK9M9xgACADAuBAeCGD2ABC6HSCkABTCEAoAvyz3GAAESNBYEB
+4JILYAEFoVECAABMIgCgz3WAALShZPIdhVEjwKCEuB2lz3CAAESNCPIigAHhIqCKIIUJB/AhgAHh
+IaCKIMUIhgpP/gYPQAFM8EISAIYEIL6PAMAAAETyAbUehfO4PPKKIIQOYgpv/oohkAfKCYAHAJWG
+IPwAjCACgDL0HgiAB4DgLvQD2BIfGJDgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4Eh8YkBPMERocMAbwAJUqDqAINJWsFQEQgOEI
+8pcVgBAAqQDYrB0AEFQVgBCA4CTyz3agAPwlNIYB2s9zgABEjQaDgOE4YAajBfLPcYAAOQhAqVOG
+J4NZYSejgOA+hQHeUPJRIcCBTvIB2c9wgAB0BSCgSPBRIACgDvIB2c9wgAA5CCCoz3GAAESNA4EB
+4AOhPoXp8QPZz3CgANQLMaDgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB4MaBMIgCgE8wRGhwwC/Qdhc9xgABEjYK4HaUEgQHgBKEB
+3h6F8LgK8pUVgBCkFQEQqXLWD+ABAdsE8MYLQAIfhVEgAIAH8s9wgACAqAoMgATPd4AACK0Zh4Dg
+BfKSD8ADANgZp4oJQAHPcIAAHA8IgOu4EfKA5g/0BCCAL/8AX//g/s9wgACIoKDZxNo924YMb/4X
+ux6F8LhoCAIEz3CAAOzGAICA4OgNog3KIGIAlQJP/vHAOgpP/s9xgABkos9wgADgBCCgANnPcoAA
+MKIpos9wgADsxiSgJaAsos9wAAD/f89xoAAMJAGhG9gEoVEgAMTPdoAAtKEV8h2GhLgdps9wgACQ
+BCCABYEB4AWhiiCFCQoIb/4kgQIIQAFpAgAARBaAEPGGwrgEJ48fAAAACFQWghD7f4Diz3WgAMQn
+ANkV8uDavx2YkJTalR6CEATbz3KAAEgFYKIC2jwdgJDPcoAAZKohogfwQNm/HViQ1NmVHkIQACCR
+D4AAYMrAEYEgACCSD4AAWM64EoCgBSHTA7oIoAEFINADgODoAQEAAdgQHRiQyBGAIM9xgAC8qOV4
+G6ZsFoAQw7gcePQhAABkHsAUXh4EEMASgKDleBymcBaAEMO4HHj0IQAAz3KAANyoYB4EEGQWgBDD
+uBx49CIBAGgeABSKHkQQz3GAAOyo9CEAAI4eBBBoFoAQw7gcePQiAgD0IQAAjB6EEJAeBBAUzIYg
+/4VMC4EBz3CAABwPCIDruIQJwv8c8M9xgABwqgCBY4FDoWZ4AKEEgQwVAZASeCV4DB0AkADYj7gT
+HRiQCBUAkKC4CB0AkBrYGR0YkAYMQAHPdoAAtKEdhlEgwIGC9M91oADEJxEVEJZRIMCjANrV9VEg
+QKId9FEggKMy9FEgAKPm9VEgAKBc9FEgwKBs8gjYEx0YkG4OQAGA4GL0Atg8HQCQI4bPcIAAZKoh
+oNDxK/2gFgAQkRUBlgHgw7kwcKAeABDG9YoiCAATHZiQkRUAlsO4EHG88xIdmJC68ToVAJZRIICA
+H/LPcYAAcKoAgeC4GfSAuAChAdgDoYog/wAEoToVAJaGIP8BA7gBoQwVAJBGIAAPDB0AkAgVAJCA
+uAgdAJAA2I64Ex0YkFElANCQ8wTZz3CgAJAjPaCK8SL9Atg8HQCQI4bPcIAAZKohoB6G87h+8xMd
+GJR2/gTwEx0YlMEHD/5UFoAQgOAJ9EIVAJYEIL6PAMAAAAT0USAAohHyvxUAlqW4vx0YkIogBAAT
+HRiQ+gqADVQWgBCA4Fj1USCAoA70CiHAD+tyBdiKI40GiiSDD7UDL/0KJQAEz3CAAOzGKoDPcKAA
+BEQmoMTx4Hjhxc91gACIoAmlKqV4tUulAdgZteB/wcVKJAB6ANmoIIACANrPcIAAiKA1eECgAeHg
+fuB48cDWDg/+AN7PcYAAAADAoc9yoADIOx2CwqGA4MGhw6ED9ADYCvAEgddwZYchQ/v1iiCEAACh
+AaGA4MShDfLQ2Z+5z3CfALj/PaCC2BSiz3AAgBEUDqKKIMUPz3WgAMgfGR0YkAHYCHEIcghzugkv
+/Zhwz3CAABQA13CAABQADPIKIcAP63IF2GrbiiSDD9kCL/24c893oADQD9WnhdgJuM92oADAL3oe
+GJAGDcAHKg/ACPoMQAtA2c9wnwC4/zKg/g5P/oDZz3CgABQELKAdH1iQkgmAB9YNwAamCKAHANhO
+CwALB9hIHRiQOgoP/soPAArPcIAAMIwAkIfg+A4CCvYJwAoeD4AOKg7ADRWGUiAAAFEgAIAG9FYO
+oAoB3xDwA98Thpq4E6Yg3gXY0KVDHRgQANiaCW/+jbjRpc9wgAAwjACQh+CwDgEKcgkP/oIMQAMC
+CcAD+gsAABYIgAP6CsADJg7ACfIOQAgaDsAM6giADToKgA2WDE/9iiDGDc9xgAAcDw2xA9htGQIA
+G9nPcIAAOE4SCuABMKgyCI//ygiADcILj/6OC8AOJg3ADa4PL/7pcIkFD/7xwAoNL/4B2aXBGnAK
+IoAvgADsBJ4Jb/6LcEwgQKAAFIUwARSRMAb0CiKAL4AA8ARMJQCAxPZMJQCBy/YKIcAP63IF2Kzb
+aQEv/UokQABMJQCAJgEOAKhwABaOQAAWlEBMJACkenCF9owkw68o9AAWAEEAFo9AABaAQAAWAEFM
+JACkfgAKAIDnJfLPcIAA5AQAgEAszSC1fRDguGAWCW/+BNnPcIAA5AQAgEwhQKAdZcwnYZMV9ADY
+jLgU8AohwA/rcgXYt9tKJEAA5QAv/QolAAUKIcAP63IF2MDb9fEA2AC1z3CAAOQEIIBALMAgFXgS
+YRlhBSJABACxBN0G8IHABN2yCG/+qXEAIowjABwCFc9wgACEBPAgAgQe34DiLymBAAInQBAk8s9z
+gAAvhTRoK2MRI4CDCfIAJoEfgACUmxZ5ABkCBQAtgRMLIcCACfIAJoEfgACUmxZ5BBkCBRAiAoAv
+KYEAAidAEOD1QiNAIIDg6AbN//oPD/7lAy/+pcAA2EDx8cDhxa3Bi3WpcCYIb/4N2QDAHXhTIAEA
+RCk+DalwACGBf4AAyIa2CG/+Ddq+Dw/+4QMv/q3A4HjxwAohwA/rcgXYiiOMCIokgw/hB+/8SiUA
+AOB48cDhxSDbz3GgAMgcaaEAFgBAz3KgABAUDKIAFgVAAd1MJQCAyiHBD8oiwQfKIGEByiOBDwAA
+CQGcB+H8yiRBAxgaQAFoGUABA9gPormhaqFGDw/+aQMP/vHA7goP/qQQAQD5uaLBcPQg2c9zoADI
+HCmjpBABAFEhwIEu8jGIz3WgABAUI7nAuQO5BeED2k+lRoVBwo3hEN7KJuIRBhQPMYwnw58I9AQU
+DzHxdswn6pAB3kP2AN6A5ur1xYBFfselsYiGJfwfGL2les91oADMF1qgF/BFgM9xoAAQFEehpBAB
+AFEhgIIJ8jGI17qGIfwPGLlFeTqgz3WgAMwXDdkB2gPhDR2YkA4dWJAmgBkdWJAngBodWJAogBsd
+WJAD2RQdWJBwEAEBEB1YkHAQAQHPdaAA9AcE4SelR6OkEAEAmbmkGEAAaQIv/qLA4HjxwAPIpBAB
+APm5BA/B/wPZz3CgABAUJaDRwOB+ANqA4cokTXDgeOgg7QH/2VxgIKwB4uB+8cDPc4AA7ARocATZ
+9/8EawTZ9v/o8eB48cASCSAKENhv2Qe5z3KgAPAXMaLPcQAA8P84onYKAArW8eB48cDx//b/0vGB
+4M9xgADsBAP0BGkC8ChwBNnK8Q97SLgPeM9ygAAAbvQiAABAKAECSLgFefQiwAAweeB/J3jgePHA
+SgkP/qXBCHYCiyh1mHBkwACLABIGAREcAjB5cAISBwEEEggBEBQAMeSSBhIFAQAgyQMAkS8hSBIH
+IEACEHjn/wAgigEBlS8iiBIHIIACEHjj/wAgxgEClS8miAEHIIABEHje/wAgBwIDlS8nyAEHIMAB
+EHja/wAlBQAElS8lSAEHIEABEHjV/x9nBZXwf+d4EHjS/yaVIXAQeAd5PHoPuSV6UHoAIoECMHkA
+HEQwR5Unelx5D7pFeTB5ACGCAVB6XHkCHIQwD7pFeTB5ACHCAVB6XHkEHIQwD7pFeTB5ACFCAVB6
+XHkGHIQwD7pFeTB5P2fwf/x5CBzEMw+/5XkweThgaXHGuYW5CLkFIcECILYQeCCVChwEMCd4HHgI
+uAUgAAEBtgDAAaYBwAKmAsADpoEAL/6lwOB+4HjxwOHFCHU+iM9wgADkBECAQCUAFAO5NXlZYTYN
+L/4K2qlw9/9hAA/+8cDeD8/9CHbsiAiQz3KAAOwEtG8Ic4Yj8w9CKxECx3WAACiFYIXtu0hxA/Ik
+auu4iiDDLwP0HhaQEE2OUSIAgJzy47g79Ou7FPL/2AetSiQAcQDYqCBAAwphACCDD4AAlJv2e0Sr
+CmEB4A94QKta8EwhAKGN9gohwA/rcgXYiiMLBUokQADxA+/8CiVABO64R40yIUAEACGBL4AAlJv2
+eQjyBKkE2AAoQARFeAetPPAAqQ8iQgRHrV7wTCAApJT2jCDDr8ohwg/KIsIHyiBiAcojgg8AAOgC
+yiRiAJgD4vzKJQIEyXC9/wiW7rgE8gKOCa0E8AGOCK0Aheu4F/IA2UokAHEnragggAMAIYAPgACU
+m/Z4BBgCBAAYAgQB4S95AY4IrQKOCa0o8EwhAKHKIcoPyiLKB8ojig8AAAUDRgfq/wXYCJYAIYEv
+gACUm+64B432eQnyBBkCBATZAClBBCZ4B63g8QAZAgQA2Q8hQQQmeAetAY4IrcUGz/1BiQS4x3CA
+ACiFSKgiieB/KajgeBGI4H/CuOB44H7geOHFz3KAAOwEgODAIiIB/90UaQAggw+AAC+FoKtKJABx
+ANuoIIADbWIAI4APgACUmzZ4pKhtYgHjb3ugqOB/wcXxwAoO7/2YcKXBKHe4cwDeBCOAD/8AAAAY
+ugV6b3kIuf/YCLhkeCi4BXlFeQjd9CSAAyd4RMAQFAAxGf8SFAIxYb1AKAEEBXlHeUTBEBQCMRQk
+gDOA5UCwAeYr91MlwgVApwAUDQEH2QbwEH0UJ0wQALRhuRQkQDC7e0+9AJCle4HhcHt4YDP3BCCA
+DwAAAP8QuAV6XwXv/0Cn4HjxwG4N7/0g2QDaz3WgAMgcKaXPcaAAlBNboc9zgADkBGCD82jPdoAA
+tKEMhvV/UyDEBfBj+2NTII8Ag+ekwYtxGvQehpu4HqY0FoAQ4ovxcAr0KHBAIwEERGtAJgMc8v4N
+2irwHYaRuJK4HabPcKAAzBcr8IXnDvRBKgJSQCMABMG6iHO4/x6GnLgepg3aFPAsuFMgAgAehgO6
+mbgepuSDBeIFJwARAKEFgwGhBoMCoQeDA6ED4s9woADMF89xoACUE1yhAdqA4gf0HoaXuB6mINgK
+pRjwAMED2hgYWIABwRkYWIACwRoYWIADwRsYWIAUGJiAhhYBERAYWIAE2SelFhiYgNEE7/2kwOB4
+4H7gePHAXgzv/QHZocHqCC/+i3AgwM91gAAsQQCliiBXCmIK7/0CEgE2iiBXClYK7/0ghQCFQNlR
+IACAQMEG9NINL/4ocCzwz3CAAEyZUgoP/gDbxIVKJAB05oWoIIAHANjPcYAATJl1eUOJDyDAAOG6
+yiECAMohIQAlfuC6yiECAMohIQAlf1EigIDKICEAJ4UB4yV4B6XmpcSlFggP/gCFJ7jAuEAgRADP
+cIAAZEAMEAUATCUAgAX0mglv/ohwFvBMJICAzCWhgBLyTCRAgMwlYYDKIcIPyiLCB8ojgg8AAHcA
+DADi/MogYgHdA+/9ocDgePHA4cWiwYHgAdjAeEDAiiCXCn4J7/0REgE3iiCXCnIJ7/0AwQDBz3KA
+ACxBZYKA4aGCA4IK9CaCZH2keSZ7QcFloiV4A6IK8CSCBH2keSZ4JXtBwQOiZaKA4Q3yMgnv/Yog
+lwqLcAjZW9oe2xoN7/0Yu3UD7/2iwPHA4cWhwc91gADABKlwfg/v/QHZiiBXCv4I7/0CEgE2QI2K
+IFcKIY0Quu4I7/1Fec9wgABkQACAgeAB2MB4QMCLcAYML/4E2QCNUSAAgAGNBPT+DUAGBPCaDkAG
+EQPv/aHA4HjhxeHGmHDPcoAATEEFgiCCZoLIuBC4yLkFIQGAAYLIuxC7yLgFIwUAZ4ICgsi7ELvI
+uAUjBwBoggOCyLvIuBC7BSMGACTyABQOAC8oQQBOIIMHANgPIMAAEn0EIEMBpH5lfgAcgAPagqR+
+xXt6onmCBCCOAQQgwAGke8V7eaJ4gqR7BCFBg2V4GKLf9cHG4H/BxeB48cD2Cc/9OnAFgaCByLgQ
+uMi9BSUNkAGBJoHIuMi5ELkFIRAAAd4b8gQlgJMU8i8oAQBOIIIH8CGBIIDhAN8PJ48QCfIEJwAU
+QiAAgGB5yiBiAOZ9gOXbfuj1/QHP/eB48cChwQHYUglgDUDAz3CAAExBCoBRIACAyiACB8ohIgHK
+IoIPAABnAMojYg+IC+L9wCviBaHA0cDgfuB4ocHxwFoJz/2jwQh1SMDPdoAATEEahvuGPIYEfyR/
+p39Bx2IPr/2KINgEiiDYBFYPr/2pcYDnFfSA5Wn0sgrv/AfYgOBj8gohwA/rcgXYiiNGD0okAACd
+Ba/8CiUAAQQUATGA4RnyIBQAMQsgQIAN8s9wgAC4BGCAz3EAAJRxDNhgewPaCfCA4Af0z3CAALwE
+IIBgeQzYBhQBMYDhGfIiFAAxCyBAgA3yz3CAALgEYIDPcQAAlHEN2GB7BNoJ8IDgB/TPcIAAvAQg
+gGB5DdgEJ1CTC/LyCe/8B9iKIBgIpg6v/QpxEvCA5RD0iiDYBJYOr/2KIUcK5gnv/AfYiiAYBIIO
+r/3pcbD/vKYI3LcA7/2jwOB48cDhxaPBAdhAwM91gABMQalweg7v/VzZOoUbhSR4PIUEeYHAQcFm
+/wHAO4UEeUHBPg6v/YogWARVJUAfqXGF/89wgADEQkAlARuC/4twUgkv/gTZAcCm/6oPAA0AhYDg
+BfQFhYDgTA7B/10A7/2jwPHA1g+P/aLBAd3PdoAATEE6hhuGJHg8hgQhEADiDa/9iiCYA0wgAKBV
+Jk8XKvID8Lt9BCBAo/7zLygBAE4gkQfwJ0AUXB5AFIDgyiHBD8oiwQfKIGEByiOBDwAAGALKJAEE
+DASh/MolQQRAeIogmAOODa/9KnEA2A8gQAQGIBAgCnB//4ogmAN2Da/9PIapB6/9osDxwEIPj/2m
+wTpxGnJgwADYARwCMAHYAhwCMAMcAjCLcFYOIAuBwQTBCnAjIEAEBcIDwIDgC/QKIcAP63IF2Ozb
+iiTDD5UDr/y4c0B4VQev/abA4HjxwPIOj/0acCh1SHdodjhjZtk92jII7/0XuoHgCfQKcAoIL/6p
+celwvgjv/clxKQeP/eB48cDCDo/9CHYA3Yog2APWDK/9yXHPcIAATEFagDuARHkA2g8iggMEIkMA
+QiMDgMojYgAvJsfwAd/KIEEDBvIcgCR4RXhH/+lw4QaP/eB/ANjxwGoOj/0acCh3OnLPdoAAHA8U
+ls91gABMjBC4IgvgCAClgODKJyIQhSEHKU8hQCefuOxxAKHscQAZAAQIhlEgAIAF8gCFgbgApc9w
+gAC8BgCIgOAE9ACFg7gApc9woAAsIBCAAN5tHRgQSiTAcMlxqCAABs9wgAD+BwCIgOAM2MogIQBE
+Kb4Dz3KAAEzQJ3AzIgAAACGCD4AAzI0B4QCqgOce8gCFYhUPFqlxYxUEFoC4AKUA2Afw7HNAowQZ
+kAMB4PfgQIG6989woADUC02gwKFiHdgTYx0YERDwANmpcgXw7HMAowTiAeH34QCCu/fPcaAA1AsN
+odEFr/3UHYAT8cDhxaHBCHXiDq/8F9jPcIAA9AQAgIDgFfSd2AAcBDARzKlxHtoCHAQwAeAQeAQg
+gA8AAP+/j7gRGhwwAMAYurD/ugrABaUFr/2hwADY2vHxwOHFABYNQAXMAdrXcAAAAEACyMIiigAX
+usdyAA4AAFMlARCj/1ElQJDPcYAA9AQB2MogIQBlBa/9AKHxwOIMr/0A2M9xpwAUSAihR4HPdoAA
+lJ5fplCBz3OnADREgB6AEAehz3LzD//8UKEWoaDZmrn1G1gAz3GlAAgMCBEFAEwlAIDKIcIPyiLC
+B8ogYgHKI4IPAAAbAxgBovzKJCIAz3KkALg9mxIDBs91oADIH3umphIDBiDffKaSEgMGfaajEgMG
+fqZQ22KhmxoYAP/ZphpYAJIaWACjGlgAz3GkAOz/B6HPcAAA//8GoVEVEJYB2FEdGJDwpUMdGBAA
+2B4I7/2NuPGliiDEAM9xoADsJwahCoFoHgQQiiDNAAahCoFqHgQQz3AoAAIBBqGKII0ABqFRHRiU
+TQSP/eB48cDhxQhyAd2A4cohwQ/KIsEHyiBhAcojgQ8AAKIAyiQhAFQAofzKJQEBgOJE9lN6iiX/
+H4DhRPYzebN9FCGAABoIYAY7eax4FQSv/S9w4HjxwH4Lj/16cJpxSHcacwolACEA2s9xqwCg/1mh
+B9gaoVihIN7PdaAAyB/QpQHYQx0YEADYWg+v/Y240aUZ2c9wpwCYRzqgggsgCh7Yz3KnABRIHYK+
+gmwSEQBwEhIAAKcAGEAj97jFIIIPAP8AANMg4QX3vcUlgh8A/wAA0yXhFYohEADL/wh2qXCKIRAA
+yf8IdUApACKKIQgAxv8Id0AqACKKIQgAw//ReRnhLHkvcbF6GeJMei9yMHcAG4AjABxAI4T2ANgF
+8FBwfvYB2AEDr/0AHQIg4HjxwL4Kr/0A2c9zoAC0D7yDPKPPcIAAlJ5oEAIBELpPIk4AiL7PcqAA
+7CfGomoQDgEQvoUmjRDGot+Az3enABRIx6eAEA4A0KfPdqUACAwipvuAz3akALg9mx7YE/yAph7Y
+E/2Akh7YEx6Aox4YEM9wpADs/yagiiCKAAaivKMKDCACAdihAo/98cAOCo/9z3CAADCMB4iA4PQE
+IQCswc9wqwCg/2QQGQBoEBcAYBAYAAfdSv8A2c9wqwCg/zmguqA4oAIMoAkB2M93oADIH1EXAJbP
+dqAA7CdAwAHYUR8YkCDYEKcB2EMfGBAA2MoNr/2NuCDYEafPcacAFEisoQDYDaEOoQ+hz3AAAAEq
+BqbPcKUA6A+noCDYEKcF2EMfGBAA2JYNr/2NuCDYEacB2M9xoAC0Dxyhz3AAAAIvBqbPcAAAwjAG
+ps9wAABCSAamz3AAAAJKBqbPcAAAAmIGps9wAADCYwamSiAAIM9wgAAwjCSQC4hEKb4HGGAVeGq4
+ACBBDhUgACQ4YMdwgABEQwMQlAAEEJUAARCSAAIQlgAgiBC5BSGBDwAAQi0mpiCIELkFIYEPAACC
+RiamAIgQuAUggA8AAEJgBqYg2BCnBdhDHxgQANjiDK/9jbgg2BGnSiEAIBDwz3CAAAiaFiBABEQY
+gAFBhUgYQAFAIVEgV6A4oM9wgAAwjAaQMnDoAg4Az3GnABRIXBlABEAqACRPIEEAh7mJuSamCHGF
+IYsAJqaFIIwABqZMIQCgE/JMIUCgHfJMIYCgJfRALAAkBSCBDwAAgmAmpgUggA8AAEJiGPBALAAk
+BSCBDwAAgi0mpgUggA8AAEIvDPBALAAkBSCBDwAAwkYmpgUggA8AAIJIBqYg2BCnBdhDHxgQANge
+DK/9jbgg2BGngcCCwUAkEzuJworDCiTABB3/K8CA4EbyCcBAKU0hx3WAAIyZAKUKwAGlAcAYpQLA
+GaVALgAkhSCKAAamINgQpwXYQx8YEADYyguv/Y24INgRp4PAhMGJworDCiTABAr/K8CA4CXyCcBM
+IQCgAqUKwAOlA8AapQTAG6Ui8kwhQKAq8kwhgKA09EAtACQFIIEPAACCYCamBSCADwAAQmIn8Aoh
+wA/rcgXYiiNEBabwCiHAD+tyBdiKIwQIoPBALQAkBSCBDwAAgi0mpgUggA8AAEIvDfBALQAkBSCB
+DwAAwkYmpgUggA8AAIJIBqYg2BCnBdhDHxgQANgaC6/9jbgg2BGnhcCGwYnCisMKJMAE3v4rwIDg
+bPIJwAalCsAHpQXAHqUGwB+lINgQpwXYQx8YEADY4gqv/Y24INgRp0AqACSFIIoABqaHwIjBicKK
+wwokwATN/ivAgOBW8gnACMEEpQrAAcMFpQfAHKU9pQPBAiHCAAXDWGACIMWATfJieUx5L3Cocaz+
+A8FAKI0gtH0VJU0UAnnHdYAAlJ4CwATCIaUIwwIiAQAGwDtjAiMFgD3yAnosei9wqHGf/gTCBcMC
+IgEAA8AnpQIjBoA0HYARNPIGwAIghYBsBeL/TB1AEQohwA/rcgXYiiPFBRvwCiHAD+tyBdiKI0QO
+SiQAAK0Cb/wKJQABCiHAD+tyBdiKIwUB9PEKIcAP63IF2IojBQONAm/8iiSDDwohwA/rcgXYiiMF
+BPfxCiHAD+tyBdiKIwUFiiSDD2UCb/wKJYABQCBQIEwggKByBMX/ANjPcaAAtA8cob/+z3GrAKD/
+ZBlABmgZwAVgGQAGSiQAcQDZqCDADChwgCCCDRB4BriBuJe4BqYocIAgQg8QeAa4gbiXuAamKHCA
+IMQGEHgGuIG4l7gGpihwgCCECBB4BriBuJe4BqYocIAghgAQeAa4gbiXuAamKHCAIEYCEHgGuIG4
+l7gGpgHhAMBRHxiQSQVv/azA4HjxwBoNb/2YcKHBz3KAAPgEIIrPc4AAlJ4BgoQTAwCQccwgwYDq
+8nBwBvLPcIAArJ8hiCCqSiTAcEogABCoIMACz3CAAKyfMiAAApBwA/JAIEgQTCDAkKQBBgDPcIAA
+rJ8BiJBwBvQEIQEBLyVHAAbwByAAAS8lBwBhogDbz3CgALQPcBASAHygABoCARTwQCCAIRB4BriB
+uEApASQleAamQCOBETB5BrmBuUAqABQleAamAePPcIAAMIwGkBBzMgEGAADZDyHBAAshQIEB2Mon
+AgAN9AshAIHt889wgACsnwGIkHDn8wonAAKA4xHygeNn8oLjBvSKIIYgiiFGAgzwCiHAD+tyBdiK
+Iw8CZPC22r3ZGnJ5cc92oADsJ0ohACBKJABxCiJAFCp1qCCBAgAgQSNUa0AvAAEUeBpitXrHcoAA
+DJ8IkjB5QCmJAU8hQRAcfxC/5XkmpsC4uHgFIEAELyEIIAAjTxMJkvB/Br9PJ0YQHHlAKRMEBSOB
+ISamwLi4eAUggQIvIkgQRSHAEAamCoaLcQCxCJIvJgEAABQAMdBwFPRFJ88Q5qYKhgCxCZIAFAEx
+HHgwcBT0AeVp8YoixAaKIYQIp/EKIcAP63IF2IojDwdKJAAA4Qcv/AolAAEKIcAP63IF2Iojjwf0
+8c9xoAC0D3AZgAR5A2/9ocDgeADZz3CAAKyfIKghqOB/IqjgfuB48cDuCk/9r8HPcIAAHA8IgM91
+gABEQ8C4QMDPcIAAMIwkkAuIRCm+BxhgFXhquAAgQQ4AwBV4OGAZZSOJQcEZZSSJuGACiELBQ8DP
+cIAAlJ4AgCK4wLhEwM9wgACUnmQQAQHPcIAAuAYAkBBxSiEAICf0z3KAADhOLYrPdoAArJ+GIf8B
+YI5Due6KT4oCIcGAYY6GJ/8RyiFiAEO/DiPDg4Yi/wHKI2IAe3tleXtqQo4OIsKAyiJiAAK6RXkC
+8AfZgOEGBCEARcHPcaAAtEdHEQGGgOHyAwEAz3KAADhOLYrPc4AArJ+GIf8BQ7kgqy6KhiH/AUO5
+IasvioYh/wFDuSKrz3GAAJSeZBkEAADZnrnPcKAAtEdTGFiARv3PdqAAyB9RFg+WAdhRHhiQINgQ
+pgHYQx4YEADY1g1v/Y24INgRps9xgAAwjASRK4nPcqAA7CdEKL4HOWE1eWq5ACFADgDBNXk4YAll
+ELkFIYEPAABCLSaiCWUQuQUhgQ8AAIJGJqIIZRC4BSCADwAAQmAGolEe2JPPcKcAFEgMgM9yDwAA
+/M93gACUnkbAAMACuBR4G2cdZxlnACcEEAAnBRAfZwmHYYOnhQbHIBQEAIDnIoEMFQUAG/QKu0R7
+yb2le891pwAUSG2lCrkkeohxyblFec9ypwAUSC6iQC2BAgQhgQ8PAAD8ybgleBrwCr1Efcm7pXvP
+dacAFEhtpUAsgwJkesm5RXnPcqcAFEguogq4BCCADw8AAPyoccm5JXjPcacAFEgPoUoiACAD2EfA
+CiNAJAXAESCAhDoCAQDPcYAArJ8yIYAEQnFIwc9xoAC0R2AZGIAQuJu4z3GAAKy0IImfuIDhAdnA
+eQ+5JXjPcaAAtEdfGRiABfA6CW/9iiCIA89woAC0R3EQAIYEIIAPDgAAAEEofoTx9QDfAvAB589w
+gAAwjAaQEHfKAQYACMAAiBEgwIP18wDAArgUeEnAAcECwIDnAiBZAM9wpwAUSPegC/KB53vygucL
+9IohhiCKI0YiBfC22L3ZOnB6cUokACGKdUAvWBFhvVEWEJYB2FEeGJAg2BCmAdhDHhgQANjiC2/9
+jbgg2BGmA8A1bSV4EHgQuIUgigDPcaAA7CcGoQAlQBQQeAa4gbiXuAahACXAFBB4BriBuJe4BqFA
+IYAhEHgGuIG4BqFAI4AhEHgGuIG4BqFRHhiUQCQEPorAi8GMwo3D/PwuwIDgDfTPcIAAlJ58EAAG
+z3GAAJSeAeB8GRgACcAGwfV4gOHHcIAAlJ4a9IvCYIKKwSCBisJgoovCIKKNwmCCjMEggYzCYKKN
+wiCiM4A0EBAACfCKIMQGiiGECI3xLYBMEBAAFiBAMwrCACCVD4AAjJkLwPAdgCD0HQAgCCKAD///
+Af8vJkAmBC4+IC9wxPwOIJcPAAAAAQvAiCB8AAQovgUvcApxvvwOIIEPAAAAAQkngC8AAP8BiSHH
+D0ggAABIIQEALsJUHRgggeJVHVggBfIEwoDiDPRUb0AqAyF0e3pitXrHcoAADJ8IsimyQiRUIEwk
+AKCMBs3/F/EHwGG4gOBAIlIguAXt/0fApgxABe78BfAqDy/9iiCIA89woAC0R3EQAIYEIIAPDgAA
+AEEofoTx9WkGL/2vwPHAocGLcIIMb/0E2QDAUSAAgAQMgv8AwFEgQIAYC+L/yiCiAADAUSCAgBAO
+QgoAwFEgwIC4CIIKAMBRIACBUAxCBdIPoAEB2M9xgK7gAexwIKACyOxxAKHPcoAAjJmKJIF9ANmo
+IMAB8CJDAOxwYKAB4QIJb/0A2KHA0cDgfuB48cDKDQ/9z3CAAIQFAICF4LwABQDPdqAArC8ahlIg
+AABRIACAVPTPcYAAjJ8JgQHgCaHPcIAAuLRAgIDiA4AVeQXyCoEB4AqhBPAYgQHgGKEYhs91oADI
+HyDfmrgYpgXY8KVDHRgQANhaCW/9jbjxpYz+GIazuLq4GKZk2PClQx0YEADYPglv/Y248aWyDoAJ
+jgwACUoIwAEF8OoNL/2KIIgDz3CgAHhFAIAEIIAPDgAAAEEofoTz9c9xgAAcD0iBNJFTIgAAUggv
+/QHbdg4v/BHYYQUP/eB48cDyDA/9z3ClAOgPB4DPcqQADEJTIASARCCNAEQgAwECgs92DwAA/Ahx
+ybnEeOOCKrjYd8R/QS+FEuSCUyZGAulyybrkfiq+BvKe4YT3jCFPiMT3ANkD8AHZTCQAgATynuBE
+9wDYBvCMIE+IPPcB2IDlG3gleAXyTCaAh0P3ANkF8IwmT4g99wHZgOUCuQV5BPJMJYCHRPcA2Abw
+jCVPiDz3AdiA4wO4BXkE8p7iRPcA2AbwjCJPiDz3AdiA4wS4BXkE8p7mRPcA2AbwjCZPmDz3AdgF
+uCV4QiAAgH0EL/3KIGIA4H8A2OB+4HjPcKAALCAQgOB/CeDgfuB44H8B2ADZlrnPcKAArC88oOB+
+4HjgfuB44H7geOB+4HjgfuB44H8A2OB+4HjgfuB44H7geOB+4HjgfuB4z3KAAHAPVIpZYTB5QWlQ
+cMT2IngQeAPwAtjPcaAAyB8eoRDYDqEB2BUZGIDgfuB48cCKCw/9AN/PdaAA0A/1pQPeEvDgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeGG+jCb/n+71A9gapc9wgABwD++oAdgVpaUDD/3x
+wDoLL/0F2ADdC7ipcd3/z3GAALShHoHuuGDyHYFRIACAXPL+Dc/7ANmcuc9woADQGzCgAdnPcKQA
+mEA8oAQgvs8wAAAAAeXKJSIQUSMAwCf0USBAxQXyUSGAwyjyUSDAxQ7yUSGAwwryz3CqAAAEAYCG
+ID8Lg+Aa8s7/IN/PdqAAyB/wpgHYQx4YEADYpg4v/Y248aaE5aYHxf8I8MX/z3GAAMCNCYEB4Amh
+USAAxwDZD/IA2s9woADQG5y6UKDPcIAAkARAgBCCAeAQos9wpACYQDygPfBKDc/7USBAxTf0USAA
+xQHlyiUiEFEjAMDPdqAAyB8g3w708KYB2EMeGBAA2C4OL/2NuPGmhOVCAAYA5vHPdaAA0A8A2BWl
+8KYB2EMeGBAA2AoOL/2NuAPY8aYapQDYz3GAAHAPD6nPcYAAwI0JgQHgCaEB2BWlVQIP/eB48cDm
+CQ/9AN/PdqAA0A/1pgPdEvDgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeGG9jCX/n+71
+A9gaps9wgABwD++oAdgVps9xgAC0oR2BgLgdoZX/Hg+AAvEBD/3gePHA4cXPcqAA0A+wgs9wgABw
+Dy+IMHUA2wX0A9k6om+oAvDf/9UBD/0A289yoADEJ4ogGAg8GsCAz3GgAMgfDqGAEQAAUSBAgM9w
+gABkqg3yQhIChgQivo8AwAAABfJBgIDiA/JCoIAZwADgf2Gg4HgUzAQgvo8AAChARfLjuCHyFRIC
+N4DYz3GAAESN67oUGhwwBvIYgQHgGKEF8BCBAeAQoVEiwIAH9ADZz3CgACwgL6AVzEYggALgfxUa
+HDBRIECBF/KKIAQAFBocMM9xgABEjQ+BAeAPoRXMANlGIIACFRocMM9woAAsIC+g4H4E2BQaHDDP
+cYAAgAwfgQHg4H8foeB+8cB+CA/9AN0g2M92gADsp0AmDxXOCWAGAKbPc6AAyB8B2BOjWIM5g1QT
+BAD4EwAAz3OgADAQYYPPc6AADCQCIgKAZ4MDIUEDQaYipgIkAwDPcoAAHA/PcYAAtKFjpkwZRAMU
+klAZRANoggm2z3KlAAgMUyMAAAi2ABIEAE4ZRANTJEUBUyRCAEgZQgGD4sohwQ/KIsEHyiOBDwAA
+Vg1wBOH7yiBhAQQkhQ8AAADgQS1CA5YZggA+ge65FB4AEQzyBLqBukV4CLYH2AfwFScMEKCkA/AE
+2AHgiOC69+u7sAjC/ql3USCAxbrygOe49M9wgAC0oT6ABCGBDwAAAEAEIYBPAAAAQBBxAd/KJyIQ
+yiViEM9xgABwDw+JAeAPeA+pz3GgALQPN4EwcADeCPTPcKAAqCAGgIwgg47M9wDfV//PcIAAkAQg
+gAHdCIEB4AihgOeG8s9xgADspwWBBCCADwAAAOBBKEQDz3CkAJBBdYBWgFEkAIC4ckihz3KAALSh
+Z6EF8kwaxAAI8EwahAMEI4MP//8AAGehUSRAgAXyMLtOGsQABfBOGoQDcHtnoVEkgIAF8lAaRAEI
+8FAahAMEJYMP//8AAGihDYAGoQQggA8AAAD+KbhSGgQAHoLuuCPyz3CqAAAEBIAJoc9wgABQqECI
+gOJAIAQBMvKA4loALgACEIUA9CSDAxXYE7jwIMMAz3CAACio1XgB5lB2YKC09xvwz3CAAGioQIiA
+4kAgBAEW8oDiAhCFAM/39CSDAynYErjwIMMAz3CAACio1XgB5lB2YKCz90GpAhlCAYDnGPQEIL7P
+YAAAABL0z3CAAJAEIIAB3QGBYbgBoQeBAeAHoYoghQcaDO/8FBIBN1EjAMAT8gDfAf+KIMUHBgzv
+/Olxz3CAAJAEIIAB3QGBYbgBoQeBAeAHoYIO7/yKIEQCBCC+z4ABAADMJyKQzCUhkAzzz3CgADAQ
+A4CA4ADZCvLPcIAAkARAgAHdKHcMggHgDKKA5RXyAtnPcKAAyBwqoBz/z3CAALShQNk9oBTMhiD5
+jwX0ANiPuBQaHDDNBe/86XDhxTDbAN3PcKAAyBxpoAPaz3GgAMwXIRmYgE6hp6BqoOB/wcXxwOHF
+z3GAAIAMDoEB4A6hz3GgAMQnGREAhoDgANoF8gLYEBkYgM91oADUC1el//7PcYAAtKEdgYe4HaHo
+/xCFgOAr8gPYEaXgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB4EaUTzBEaHDCx/iEFz/wKIcAP63IF2M9zAAC8CUokAAAhAe/7CiUA
+AVEhAMbxwE30z3CgAAwkB4CA4Efyz3CAADCiC4DPcaAAyB9k4B6hENgOoQHYFRkYgFIIL/0L2FEh
+AMYz9FEgQMcA2iTyz3GgANQLFoE4gSTgMHBP91EhAMYE9FEjAMD881EjAMAS9FEggMQQ9BnwANnP
+cKAA/ESeuSGgRaDPcYAAgAwPgQHgD6HPcJ8AuP9cGMAIz3CfALj/XBgACK3/0cDgfuB48cDmC8/8
+CHXPdoAAtKEdhi8mCPA89OC9EPSCuM9xgACQBECBHaYDggHgA6IggYogRQnWCe/8I4FRJUCQHYYR
+9IS4z3KAAJAEIIIdpgSBAeAEoSCCiiCFCa4J7/wkgc9woAAMJAOAUSDAgB2GEPKEuM9ygACQBCCC
+HaYFgQHgBaEggooghQmCCe/8JYE9hi8mSPAA3w70CiHAD+tyBdjPcwAAEQmKJIMPzQev+0olAADP
+daAA0A8RFQCWgOCF8kQhfoIT8lEhAIAX8s9ygACQBCCCAoEB4AKhIIKKIEUIKgnv/CKBCfBRIQCB
+FfKc/x2GUSDAgWf0z3CgAMQnGRAAhoDgB/IC2c9woACQIz2gPf4b8JP/HYZRIMCBVfQ5helyBfAA
+EQBQAeJPekEpgAAQcrn3ANoF8AARgFAB4k96UyFAABByufcD2BIdGJDgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4Eh0YkBPMERoc
+MFD+HobzuAnyz3CAAJyu66jPcIAAXK7ssM9wAAD/f89xoAAMJAGhG9gEoTL/jQLP/AohwA/rcs9z
+AABYCQXYaPHgePHA4cVQ3QDaz3OgAMgfr6NeowIgQgBeowHaFRuYgEDaTqMEIL7PAAIAECwOgf9Z
+As/84HjxwNoJz/zPcIAAtKExgFEhQIIR8s9xgABwDy6JRBCCAER5USGAgEjayiKBDwAAkAAC8A7a
+ANvPcaAAqCAngagQDQBZYbFxwiVFEMol5hKweArZdP0d/s9wgADcRgCQz3agAMQnUSAAgQTyjCUD
+kgT3AN8V8M9woAC0D3ygz3CrAKD/eqAWCCAKANgZFgCWgOAE8gLYEB4YkAHfGRYAloDgPvRRIQDG
+PPQD2c9woADUCzGg4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44Hjg
+eOB44HjgeOB44HjgeOB44HjgeDGgE8zPcYAAgAxqvREaHDAUgQHgFKEVgbhgFaHGDO/8AdiOCmAB
+Adi3/SUB7/zpcOB48cC2CO/8wNjPdYAA7KdBjSAaAjASakTgz3GgANQL2IEA20ImDhiA5somzBDR
+cEYADgDPcZ8AuP8Ygc9ygACQBJC4GKEYgbC4GKEgggWBAeAFoc9xgAC0oR2Bg7gdoSCCiiDFCHIO
+r/wlgQDYGf8A2D3wz3aAABwPyYYD4AQggA8AAPz/Kr7Avhe+x3YADgAAxXjsdgCmCMjsdgCmEczP
+dqAAiCRKJMBzAeAQeAQggA8AAP+/j7gRGhwwHqYA3qggAALwJY8T7HDgoAHmgOIA3cv3z3CAACio
+8CBOA+xwwKAB5VB1t/dtoQHYNQDP/OB4wdggGgIwz3KAABwPGIoB289xgAC0oYbgFoHCI8EADOAY
+IMAAYhkEAGIRAAED4AQggA8AAPz/nbifuOxzAKMIyOxzAKMYijaBhuAB2MIgAQAYIQEA7HAgoOB/
+AdjxwG4Pr/wb2M92oADEJxUWDZYWHhiQA9nPcKAA1AsxoOB44HjgeOB44HjgeOB44HjgeOB44Hjg
+eOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HgxoBPMERocMIogBAweDa/8
+ANl6/eS9E/LPcIAAkAQggBGBAeARoUD9GRYAloDgBfIC2BAeGJBe/iLwUhYAllMgQQCD4dEl4ZAD
+8rf+GPDPcIAAOQgB2SCoz3CAAJAEQIAGggHgBqLPcIAAtKEegFEgwIEG8s9wgAB0BSCg/QaP/PHA
+jg6v/ADZz3AAAP9/z3WgAMQnEx0YkBvYFh0YkAHYEB0YkM92gAC0oR6G8bgF8qgeQBAI8BGGNoaW
+DmACANqoHgAQb/4dhue4BPIA2CXwLRUBllaGMHIG8oC4HaYA2JH+9vEEJYFfAADwLx6GJXgephEV
+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
+CmLPcIAABMtIYAypgOcG9M9ygADwqgXwz3KAABCrQ6Wk2ACyTCZAoBDYAqUE9KTYjLgAsgzAgODK
+IcEPyiLBB8ogYQHKI4EPAAC4AMokIQCUAaHvyiXBAEwjAKAEphDyAYGYuAGhA4GfuAOhABUBIAQV
+ACAAHoQUIaYCpg4J7/WpcP0Ej/DgeM9wgABoqyiAz3CfALj/ANo2oAjZ7HAgoAPZz3CgABQEJaAC
+yOxxAKHPcKAA1AtNoOB+4HjPcYAA1AfgfwCh4HjPcIAA1AfgfwCA4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H8A2OB/ANjgfuB4ocHgf6HA4HjgfuB44H7gePHA4cUCyM91gAAcYwClBG3O
+CO/wAtnPcYAOBADscCCgUg+v8ACFnQSP8OB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB48cAAFgBBz3KAABxjBrIAFgVBQCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOCDwAAggBY
+AKLvyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIBEHK39voPj/DRwOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjPcIAA2AfgfwCA4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY4H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+8cCmCo/wGnHPd4AAXGMgj1EhAIBG8s9xgADgByCJgOHMICGgPvKB4Ab0z3CAALi0oYAD8ADdjuUD
+94DlAvQA3c9xgAC4tBiJgOAE9IDlBPQA3gTwooEE3oogEwFuCK/wqXGKIFMBZgiv8Mlxz3CAABwP
+GIiD4MwgIoHMIOKBzCAiggjyiiATAUIIr/Cz2QrwCpcQdQj0C5cQdswgIaAE9ADYIfAB2M9xoADI
+Hw2hz3CAAOAHAYjLt6q3BL4QuMV9BX2KIBMBBgiv8MrZiiATAfoPb/Cpcc9woADIH38YWIMB2CkC
+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
+DxwdIgEAHSb5DwBhZAwAEADABhEBAAQn/AAEZAAAGyQCABslOBzAEQAAACEAABslQAAbJDAcwBEA
+AAAhDxwdIhgBHSYYAMcQmKCAgQAAwBcgAMcQoKCAgQAAwBcAAAAhlEmAgQIAXG4RAABh+EHEEA8b
+CSIACwk5AgAKYgMBCmIEAgpiAAAJQAQAAGEJAAlAAgAAYQoACUAAAABhAgAJQQAJGigAAMAWAQAb
+JgAAwBcEAB0mAQAIJ+kACGQAAAAhAAAAAIwBAAABAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQ6AAAA
+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFJyAAAAAAAAAAAAAAAAAAAEA
+AAAHAAAAAAAAAMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAaKuAAAAA
+AAAAAAAAQK+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAIi0gAAYoAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADI
+xIAACPsBAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaKuAAEQE
+AgAAAAAAaKuAADgLAgAAAAAAAAAAAGirgADQDAIAAAAAAAAAAAAAAAAAaKuAAAAAAAAAAAAAAAAA
+AP8AAAAABwAAAAAAAAAAAAAEIAIABCACAAQgAgAIIAIAAAAAAB0AAAAAAAAAAAAAAAAAAAAAAAAA
+f38AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECBAgACBAgAAAAAAAAAAABAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAkAABUAAADsRYAAzCsAAMwr
+AADMKwAAgEIAAMwrAADMKwAAzD0AAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsA
+AOweAACcIAAAtCAAACQiAACsIgAAKCIAAMwrAADMKwAA6E4AALBQAACcUQAAzCsAAMwrAADMKwAA
+ZE0AAHBkAABsZAAAxGQAAMwrAADMKwAAzCsAAIxEAADMKwAAqGQAAMwrAADMKwAAzCsAAMwrAADM
+KwAAzCsAAMwrAADMKwAAhEIAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwr
+AADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAfEUA
+AMwrAADMKwAAzCsAAMwrAADMKwAAZEYAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAA
+zCsAAMwrAADMKwAArGsAAMwrAAAUbQAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAAC8
+bwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAAC4hAEAEIgBAMwr
+AABkigEAzCsAABSMAQCAVwEAzCsAAMwrAABoUgAAzCsAAMwrAADMKwAAzCsAAMwrAACs4gEANPYB
+AMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAmB0CAMwrAADMKwAA
+zCsAAJgCAgDMKwAAuAYCAMwrAADQLgIAzCsAAOAlAADkJQAAzCsAAMwrAAB0FwIA6HIAAMwrAADM
+KwAAzCsAAPD/AQDMKwAAzCsAANBQAQD4owEAzCsAAMwrAADMKwAA6KwBAKBYAQDMKwAAzCsAAMwr
+AADMKwAAzCsAAMwrAACgtwEAzCsAAGwUAgBwFAIAfBQCAIAUAgB0FAIAeBQCAIQUAgDMKwAAzCsA
+AMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAABMVAAAzCsAAMwrAADMKwAAzCsAAMwrAADAEwIA
+EBQCAHhIAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADM
+KwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwr
+AADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAA+EkAAIBKAAAUSwAAyEsA
+AMCBAACgSwAAzCsAAMwrAADMKwAAzCsAAMwrAADwSQAA9EkAAMwrAADMKwAAmFIAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwMAADMDAAAzAwAAMwMAADMDAAA
+zAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADM
+DAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAAD8DQAAAAAAAChe
+AQDMDAAA3AkAAMwMAADMDAAAzAwAAAwKAAAgQAEAAIQAAMwMAADMDAAARAoAAEQKAABECgAARAoA
+AEQKAABECgAARAoAAMwMAADMDAAAzAwAAMwMAAA8DAAAzAwAAMwMAADMDAAAzAwAAMwMAAAADgAA
+zAwAAMwMAADACQAAAwAAAIQRAgACAAAAcGwBAAQAAAAkbQEABQAAABwOAAAGAAAAtDQAAAgAAADs
+EwIAEwAAAJz8AQAJAAAAZAgCAAoAAACIFAIADgAAAAChAQAPAAAATI4BABAAAACEjgEAGQAAAJBd
+AQANAAAA/IUBABcAAADkcgAAEQAAAECCAAASAAAA0E8BAAEAAAAYAgIAFAAAAKy0AQAVAAAALKQB
+AAcAAAAscAAAFgAAAMAuAgAYAAAA+JwAABoAAAD8DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAQAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ
+AAAAAQEAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhAw4e4eEDDh7h
+4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuEAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8
+FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwV
+FRUVPDw8PBUVFRU8PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAACQBgAAMfqvAJAGAAAx+q8AkAYA
+ADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AQwUAADH6rwBDBQAA
+MfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAAAAAADe
+wwkAAAAAAAAAAAAAAAAAvC0BAAEAAACsRYAAAAAAAAAAAAAAAAAAXC4BABUAAADsRYAAAAAAAAAA
+AAACAAAAAwAAAAAAAAAIAAAAAAAAADCMEQAgvwIAAAAAANAuAQB4LwEAhDABADAyAQCEMAEAMDIB
+AAQ0AQCMNAEA8DQBAICAgICAgICAAYACgICAgIAAAAAA8DoBAPA6AQAAAAAAAAAAAAAAAAAAAAAA
+8DoBAPA6AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArEWAAKxFgACkIKAAOCCgAAEAAAD8
+////AAAAAAAAAADMRYAAzEWAAKggoAA8IKAACAAAAPP///8AAAAAAAAAAOxFgADsRYAArCCgAGwg
+oAAwAAAAz////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAA
+AAAAAADkUAEABQAAAOxFgAAsVgEAAP8DAExWAQAA/wUAOFcBAAD/LQBcVwEAAP89ABRXAQAA/wQA
++FYBAAD/JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMxcAQAGAAAArEWAAAAA
+AAAsAQAAXgEAAAEAAAABAAAAAQAAAAEAAAADAAAAAAAAAAAAAAAYZAEAIGUBAJxlAQCsYAEA1F8B
+APBmAQB4ZwEAvGcBABBoAQAAAAAAAwAAAAIAAAADAAAAAwAAAAMAAAABAAAAAAAAAAEAAAAAAAAA
+AAAAAAAAAAD0bQEACgAAAKxFgAAAAAAAAAAAAAAAAACAbgEACgAAAKxFgAAAAAAAAAAAAAAAAAA0
+bwEACgAAAKxFgAAAAAAAAAAAAAAAAABUcAEACgAAAKxFgAAAAAAAAAAAAAAAAAC4bgEACgAAAKxF
+gAAAAAAAAAAAAAAAAADMbwEACgAAAKxFgAAAAAAAEAAAAACAAAAAAKAAECcAAOgDAADoAwAAAAAA
+AAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAA
+MEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACs
+RYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAA
+AAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIB
+AAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAA
+AAAAAAAAAAAAAAAA8IkBAAoAAACsRYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAGSRAQBwkgEAXJUBABCYAQCQmgEAFJ4BACCUAQA0BYAAMKuAABgAAADwqoAAAAAAAAAAAAAA
+AAAAAAAAAAAAAACooAEABgAAAKxFgAD/////AAAAAP//////////AAAAAAAAAAAAAAAAiKMBAAUA
+AADsRYAAbgBuAGkAwACgAFAAgAC+AFABfQA+AG4AbgBpAMAAoABQAIAAvgBQAX0APgAAAAAAAQEA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEBAAIBAAECAgIAAQEAAgECAQIAAgABAgP//wAAuQHf
+ALEAGwAWARsAfAEbAK8AGwAUARsAegEbAGwAoADRAKAANwGgAG8AgwBxAIMAdgCDAHMAMwBuADMA
+cAAzAHIAMwDXADMAPQEzANQBBgDQAQAAfgA8AOMAPABJATwAeABJAN0ASQBDAUkAfwBaAOQAWgBK
+AVoAqgA/AKsAAQAPAT8AEAEBAHUBPwB2AQEAeQBqAN4AagBEAWoAqAAAAA0BAABzAQAApgA3AKcA
+AQALATcADAEBAHEBNwByAQEABAAIAJwBzACdAcwAngHMAJ8BzADVAcwA1gHMANcBzAC0AEcAGQFH
+AIABRwCQACIA9QAiAFsBIgChAIgABgGIAGwBiACUAAAAlQAAAJgAwACZAKAAlgCQAJcAAACUAAEA
+lQABAJgAwACZAKAAlgCQAJcAAACUAAIAlQADAJgAwACZAKAAlgCQAJcAAACUAAMAlQAHAJgAwACZ
+AKAAlgCQAJcAAAD6AAAA+QAAAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAQD5AAEAAgGQAAMB
+0wAAAYMA/gATAPwAMwD9AHcA+gACAPkAAwACAZAAAwHTAAABgwD+ABMA/AAzAP0AdwD6AAMA+QAH
+AAIBkgADAdMAAAGDAP4AEwD8ADMA/QB3AF8BAABhAQAAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcA
+XwEBAGEBAQBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQIAYQEDAGgBkABpAdMAZgGDAGQBEwBi
+ATMAYwF3AF8BAwBhAQcAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcAhQAAAIYAAACHAFAAiAAAAIkA
+oACKAAAAiwDQAIwAAACFAAEAhgABAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAIUAAgCGAAMAhwBQ
+AIgAAACJAKAAigAAAIsA0ACMAAAAhQADAIYABwCHAFAAiAAAAIkAoACKAAAAiwDQAIwAAADrAAAA
+6gAAAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAQDqAAEA7ABQAO0AAADuAKAA7wAAAPAA0ADx
+AAAA6wACAOoAAwDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAMA6gAHAOwAUADtAAAA7gCgAO8A
+AADwANAA8QAAAFEBAABQAQAAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQEBAFABAQBSAVAAUwEA
+AFQBoABVAQAAVgHQAFcBAABRAQIAUAEDAFIBUABTAQAAVAGgAFUBAABWAdAAVwEAAFEBAwBQAQcA
+UgFQAFMBAABUAaAAVQEAAFYB0ABXAQAA+/8AAP//AAC5Ad8AsQAbABYBGwB8ARsArwAbABQBGwB6
+ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAzAG4AMwBwADMAcgAzANcAMwA9ATMA1AEGANAB
+AAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA5ABaAEoBWgCqAD8AqwABAA8BPwAQAQEAdQE/
+AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACmADcApwABAAsBNwAMAQEAcQE3AHIBAQAEAAgA
+nAHMAJ0BzACeAcwAnwGIANUBzADWAcwA1wHMALQARwAZAUcAgAFHAJAAIgD1ACIAWwEiAKEAiAAG
+AYgAbAGIAPoAAAD5AAAAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gABAPkAAQACAZcAAwHQAAAB
+jQD+ABEA/AAzAP0AdwD6AAIA+QADAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3APoAAwD5AAcAAgGX
+AAMB0AAAAY0A/gARAPwAMwD9AHcAXwEAAGEBAABoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQEA
+YQEBAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAgBhAQMAaAGXAGkB0ABmAY0AZAERAGIBMwBj
+AXcAXwEDAGEBBwBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwDrAAAA6gAAAOwAVQDtAAAA7gCqAO8A
+AADwAN0A8QAAAOsAAQDqAAEA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAA6wACAOoAAwDsAFUA7QAA
+AO4AqgDvAAAA8ADdAPEAAADrAAMA6gAHAOwAVQDtAAAA7gCqAO8AAADwAN0A8QAAAFEBAABQAQAA
+UgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEBAFABAQBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABR
+AQIAUAEDAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAwBQAQcAUgFVAFMBAABUAaoAVQEAAFYB
+3QBXAQAA+/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi3AQCU2AEA
+9LSAAEAFAAAAAAAACLcBADS4AQA0uoAA+AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzdAQBw
+2wEALLyAAFQAAAAAAAAACLcBAKDbAQCsvIAAUAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAi3
+AQC01wEAWFeAAFABAAAAAAAACLcBAMzZAQDgBoAAAgAAAAAAAAAItwEAJNoBAOQGgAAEAAAAAAAA
+AGjdAQA0uAEAgLyAACoAAAAAAAAACLcBAMDaAQAAAAAAAAAAAAAAAAAItwEAgNoBAOgGgAAEAAAA
+AAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAOAA4ADwAm
+ACcAKAAoACkAKgBGAEYARwBIAEgASQBKAEoASwBMAGgAaQBqAGoAawBsAGwAbQBuAG4AbwBwAHAA
+cQByAHIAcwB0AHQAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQAPAD8AAAAA
+AAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALACQAJAAlACYAJgAnAEQA
+RABFAEYARgBHAEgASABJAEoASgBLAEwATABNAGoAagBrAGwAbABtAG4AbgBvAHAAcABxAHIAcgBz
+AHQAdAB1AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgAOAD8AMKoBABLS
+AAAAAAAA//8PAPDFAQC2AAAAAAAAAP8AAADwxQEAtwAAAAAAAAD/AAAA8MUBALgAAAAAAAAA/wAA
+APDFAQC5AAAAAAAAAP8AAADwxQEAugAAAAAAAAD/AAAA8MUBALsAAAAAAAAA/wAAAPDFAQC9AAAA
+AAAAAP8AAADwxQEAvgAAAAAAAAD/AAAA8MUBAL8AAAAAAAAA/wAAAPDFAQDAAAAAAAAAAP8AAADw
+xQEAwQAAAAAAAAD/AAAA8MUBAMIAAAAAAAAA/wAAADCqAQAT0gAAAAAAAP//DwDwxQEAGwEAAAAA
+AAD/AAAA8MUBABwBAAAAAAAA/wAAAPDFAQAdAQAAAAAAAP8AAADwxQEAHgEAAAAAAAD/AAAA8MUB
+AB8BAAAAAAAA/wAAAPDFAQAgAQAAAAAAAP8AAADwxQEAIgEAAAAAAAD/AAAA8MUBACMBAAAAAAAA
+/wAAAPDFAQAkAQAAAAAAAP8AAADwxQEAJQEAAAAAAAD/AAAA8MUBACYBAAAAAAAA/wAAAPDFAQAn
+AQAAAAAAAP8AAAAwqgEAFNIAAAAAAAD//w8A8MUBAIIBAAAAAAAA/wAAAPDFAQCDAQAAAAAAAP8A
+AADwxQEAhAEAAAAAAAD/AAAA8MUBAIUBAAAAAAAA/wAAAPDFAQCGAQAAAAAAAP8AAADwxQEAhwEA
+AAAAAAD/AAAA8MUBAIkBAAAAAAAA/wAAAPDFAQCKAQAAAAAAAP8AAADwxQEAiwEAAAAAAAD/AAAA
+8MUBAIwBAAAAAAAA/wAAAPDFAQCNAQAAAAAAAP8AAADwxQEAjgEAAAAAAAD/AAAAMKoBAAjSAAAA
+AAAA//8DAHCqAQAAggAAAAAAAP8BAABwqgEAAYIAAAAAAAD/AQAAMKoBAAnSAAAAAAAA//8DAHCq
+AQACggAAAAAAAP8BAABwqgEAA4IAAAAAAAD/AQAAMKoBAArSAAAAAAAA//8DAHCqAQAEggAAAAAA
+AP8BAABwqgEABYIAAAAAAAD/AQAAMKoBAAbSAAAAAAAA/wEAADCqAQAH0gAAAAAAAP8DAAAwqgEA
+BtIAAAkAAAAA/gMAMKoBAAfSAAAKAAAAAPwPADCqAQAG0gAAEgAAAAAA/AcwqgEAB9IAABQAAAAA
+APA/MKoBABXSAAAAAAAA/wMAADCqAQAM0gAAAAAAAP8BAAAwqgEAFdIAAAoAAAAA/A8AMKoBAAzS
+AAAJAAAAAP4DADCqAQAV0gAAFAAAAAAA8D8wqgEADNIAABIAAAAAAPwHMIAAAKqqqqoxgAAAqqqq
+qjKAAAAAqqqqM4AAAAAAAAA0gAAAAAAAADWAAAAAAAAANoAAAAAAAAA3gAAAAAAAADiAAAAAAAAA
+OYAAAAAAAAA6gAAAAAAAADuAAAAAAAAAPIAAAAAAAAA9gAAAqqoKAD6AAACqqqqqP4AAAKqqqqpA
+gAAAAAAAADCAAACqqqqqMYAAAKqqqqoygAAAAKqqqjOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaA
+AAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAA
+AKqqCgA+gAAAqqqqqj+AAACqqqqqQIAAAAAAAAAwgAAAAAAAADGAAAAAAAAAMoAAAAAAAAAzgAAA
+AAAAADSAAACqqqqqNYAAAKqqqqo2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAACq
+qqoKO4AAAKqqqqo8gAAAAAAAAD2AAAAAAAAAPoAAAAAAAAA/gAAAAAAAAECAAAAAAAAAMIAAAAAA
+AAAxgAAAAAAAADKAAAAAAAAAM4AAAAAAAAA0gAAAqqqqqjWAAACqqqqqNoAAAAAAAAA3gAAAAAAA
+ADiAAAAAAAAAOYAAAAAAAAA6gAAAqqqqCjuAAACqqqqqPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAA
+P4AAAAAAAABAgAAAAAAAADQFgAAwq4AAGAAAAPCqgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg+AEABgAAAKxF
+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ADQFgAAwq4AAGAAAAPCqgAAAAAAAAAAAAAAAAAAAAAAAAAAAABQEAgAGAAAArEWAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAWAADCrgAAY
+AAAA8KqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQA
+AACsRYAAAAAAAAAAAAAAAAAAUBECAAYAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAA
+AAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAAAAAAAAAAAAAA
+iBACAAQAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAAAAAAAAAAAAAAUBECAAYAAACs
+RYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAAAAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAA
+AAAAAAAAUBECAAYAAACsRYAAAAAAAAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAAAAAAAAAAiBAC
+AAQAAACsRYAAAAAAAAAAAAAAAAAAUBECAAYAAACsRYAANAWAADCrgAAYAAAA8KqAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU
+BQAAAAAAAAAAAAAAAAAAAAAA/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwNAAAABQYHCA0O
+DxAVFhcYGQAACg0RFAoNERQZGRkZCgoAAAAAAAAGBgYGCQkJCQAGAABuO2g7YjtcO246aDpiOlw6
+bjloOWI5XDluK2grYitcK24qaCpiKlwqbiloKWIpXCluG2gbYhtcG24aaBpiGlwabhloGWIZXBlu
+GGgYYhhcGG4XaBdiF1wXbhZoFmIWXBZuFWgVYhVcFW4UaBRiFFwUbhNoE2ITXBNuEmgSYhJcEm4R
+aBFiEVwRbhBoEGIQXBBXEFIQTRBJEG4BaAFiAVwBbgBoAGIAXABuO2g7YjtcO246aDpiOlw6bjlo
+OWI5XDluOGg4YjhcOG43aDdiN1w3biloKWIpXCluKGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgY
+YhhcGG4XaBdiF1wXbgloCWIJXAluCGgIYghcCG4HaAdiB1wHbgZoBmIGXAZuBWgFYgVcBW4EaARi
+BFwEbgNoA2IDXANuAmgCYgJcAm4BaAFiAVwBbgBoAGIAXAAAAAAAAAAAAAAAAAAAMQIACAAAAOxF
+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AAH/
+/wID////BP//////////////////////Bf8G/wf/CP8J/wr/C/8M////Df///w7///8P////EP//
+////////////////////////////////////////////Ef///xL///8T////FP///xX///8W////
+F////xj///8Z////Gv///xv/////HP///x3///8e////H////yD///8h////////////////////
+//8iIyT/JSYn//8o////Kf//////////////////////////////////////////////////////
+////////////////////////AQQAAAIFAQADBgIABAcDAAUIBAAGCQUABwoGAAgLBwAJDAgACg0J
+AAsOCgAMDwsADRAMAA4RDQABQAAEAkEBBANCAgQEQwMEBUQEBAZFBQQHRgYECEcHBAlICAS3EyIA
+uBQjALkVJAC7FiUAvBcmAL0YJwDAGSgAxBopAAcbAAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAm
+IwcAKCQIAColCQAsJgoALicLADAoDAA0KQ0AOCoOADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQy
+FQB4MxYAfDQXAIA1GACENhkAiDcaAIw4GwCROhwAlTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoK
+AjRLDQE8TA8BZE0RAWxOEwF0TxUBfFAXAYRRGQGVUh0BnVMfAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwA/AAEAAAAP
+AD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAAA
+AAABAAAAAgAAAAMAAAAAAAAABAAAAAIAAAAFAAAADxQZHigKBQDBCQGlADw4NDAsKCQgHBgUEAwI
+BAAMCAQAPDg0MCwoJCAcGBQQDAgEAggADgAAAA4BAQABAgEBAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKXGhPiZ7o32Df+91rHe
+VJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pFvyP3U5bkW5vCdRzhrj1q
+TFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8JDjYkmxs93ybNaU7Nf5/q
+GxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBAH+PIee22vtRGjdlnS3Le
+lNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+XcCAigWtP7whSHAE8d9j
+wXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6KzKV5qDAmBnRnn+jZkR+
+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3vQ6bEqDmkMTfTi/Iy1UOL
+WW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dzUZcjy3yhnOghPt2W3GGG
+DYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsyszIrvScKmJB6czti0iPJIV
+IMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTosAQEBAQEBAQECAgICAgIC
+AgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQEBAQEBAQEBAQEBAQEBAQE
+BAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ00UUX6KKLLg0PBQcJ
+CwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8PBwYHAgMEBQABCAkLCigA
+KAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA9ACwACwALAA8ADQAMAAs
+AFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZAOgACgG6AHkAiACKBSoD
+OQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUAQQKsAJAAhACAAHgAeAB4
+AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzuxEw3S
+IA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ETDdIg
+DYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP/MAP
+D/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3SIA0L
+tEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4
+gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAaQB2AIIAGAA2AEwAaACcA
+NIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6mFeYcWSvMOQBBM0jZCqYV
+gCBZKwBBplaAYVlsMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkAAAAAAAAAAAAAABggFBQO
+DhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIAAEAAAAAABAAAQAAAAEAA
+AAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZHSElKS0xNTk9QUVJTVFVW
+V1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8zEwAAAAcHDwcPDxctAA8g
+APBhAAAAAAAAAAAAAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTM6MDE6MDkAAAAATy6wAGqworCSsGMAAaiodgCojpeo
+qFsACQAAAAIAAAAAAAAAAAAAAAkAAAACAAAAAAAAAAAAAAAJAAAAAwAAAAEAAAAJAAAACQAAAAIA
+AAACAAAACQAAAAECAQIDBAAABQYHCAkKAAAABQYAAgQABQAAAAAABQcBAwQABQEAAABAI0AlISEh
+IUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARAQEAFQEBAQEAFQEBABQUF
+AQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFBAAAABwRAAAcMgAAHDMAAAQAAAAcFQAAAgAXAGwAcAR0
+CHQMAAQEBgAAAAAAAAAAZAAAAACQAQAKAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA
+AAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAoIABAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAABAAAZAAAADyHAQBEhwEATIcBAKSHAQCs
+hwEAtIcBAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACiVDwE58mAAHFy1gNAAAAAQOCR0t
+NwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAAAAPAAAFDBgQQAAJAAAAC
+gAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAABRgYIEQACIAAAA8AAAUcG
+CREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIAAOAAAAPAAAFJBg0SAAEA
+AAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYAAQAAAAMAAAFaACYWAAIAAAAE
+AAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAEAAABXAAuFwAAgAAAAwAAAV0A
+MBcAAQAAAAMAAAFeADQXAAIAAAADAAABXwA2FwACgAAAAwAAAWAAOBgAAAAAAAQAAAFgADwYAAEA
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAggA8A
+AEAAaSAAAGkgQABpIAAAaSBAACAggA8AAOgAaSAAAGkgQABpIAAAaSBAACAggA8AAGQGaSAAAGkg
+QABpIAAASiAAAEohAABKIgAASiMAAEokAABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQA
+EEolABBKJgAQSicAEEogACBKIQAgSiIAIEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/
+gQAAQEEsnDBALJwwQiQcNAoigD+AADiJCiMANxoIQABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAA
+FgBwgABkBEB4ICBAhwAAAAAAAAAAAADhwOHB4cLPcKAAyB8WEAGGz3KAAJidIKISEAGGIaITEAGG
+IqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8AuP9WoYoh/w8SGFiAExhYgBQYWIAVGFiAJBhYgMHCwcHB
+wCAgQIcMyM9yoADIHw4aGIANyA8aGIAOyBAaGIAPEgE2AcgkeBEaGIAQyC0aGIDgfuHE/BzIvvwc
+SL7hwOHB4cLhw/wcCLH8HEix/ByIsfwcyLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDh
+xPHAz3CgANAbFIDPcYAAYAQEIICPz1EE4QChCvIvKQEAz3CAAAwP8CBAAEB42v/RwMHEayTAEMHE
+aySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZA
+fsHEaySAFMHEICBAhwzIh7gMGhgwDcibuA0aGDAOyA4aGDAPyIe4DxoYMBDIEBoYMOB+4HjxwAzI
+lbgMGhgwDcibuA0aGDAPyIq4jbiQuA8aGDDPcIAATBAYiBsIUQAPyM9xAAC8DKy4DxoYMHIOIAAP
+2GfYtgogAYohRwbRwOB+8cDPcIAAfMcAgIYg/oEJ9A/IBSCADwAAANQPGhgwof+KIFUFhgogAYoh
+hwro8eB4z3EDAEANz3CgAKggLaDPcYAAjARAgQFqAKHPcKAAOC4FgAQggA/AAAAAHQiAD8AAAABI
+2M9xnwC4/xqhW6Fp2Bi4GaHPcIAAmAklgCOBIIHHcQAAiBMBBsAJ4HjPcIAAmAmVBcAJ4HjxwPIL
+AAHPd4AAYASIdQboDQhRAAHYA/AA2AuvBekPCVEAAdgC8ADYCq8G6g0KUQAB2APwANgMrwDYz3ag
+AMgfGB4YkAuPiiEQAA7oCI8M6M9wAwBADUUeGBAwpgLYGB4YkAPwMaYKjxjoCY8W6M9wAgCYRSAe
+GJDPcIAAKAAhHhiQz3CAAFwEIh4YkBgWAJZFIAADGB4YkAyPCOgYFgCWhSABBBgeGJAPC1EAGBYA
+loi4GB4YkM9wgAAwkgCQjuDMIKKCBvQYFgCWgLgYHhiQGO0A2JS4z3WAAIAEAKVx2Aa4Sg0gAfzZ
+IIXPcAAATBw6DSABn7kYFgCWhbgYHhiQWQMAAc9xqqq7u89wnwC4/zagNqA2oDagz3GgAMg7DoGI
+uA6haSBAAP7x4HjxwKXBQcBCwQwcADEQHEAxz3GAAHyKNBnADzAZAA8sGcAOKBmADiQZQA7PcIAA
+fIogGEALz3CAAHyKHBgAC89wgAB8ihgYwArPcIAAfIoUGIAKz3CAAHyKEBjACM9wgAB8igwYgAjP
+cIAAfIoIGEAIz3GAAACKgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnABVgZ
+gAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIoGYACJBlAAiAZAAIcGcABGBmA
+ARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAByBkAAGogAAHEGQAAaiDAAMAZ
+AABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAANDYn7jPcZ8AuP8doc9wgAAAAMSAUyXE
+NVMmxTXXugHm077EoFMjwAQFJo4f0P4AANahBSCAD7D+AAAWoRiBUyfONQDdlLgYoUDDAcACwclz
+DBQGMK4P4AAQFAcwz3CgALQPvKDPcaAAyDsugUYP4AB92IYPQAGaCyABqXAI2ADZSgsgAZm5z3CA
+ADCSAJCO4MwgooLKIIEP4ADEMcohIQBkCGEBzyGhBf0Fz//xwL4IIAF72P4O4ADw2c9xgAB8ijQZ
+wA8wGQAPLBnADigZgA4kGUAOz3CAAHyKIBhAC89wgAB8ihwYAAvPcIAAfIoYGMAKz3CAAHyKFBiA
+Cs9wgAB8ihAYwAjPcIAAfIoMGIAIz3CAAHyKCBhACM9xgAAAioAZAAh8GcAHeBmAB3QZQAdwGQAH
+bBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE76HOoa2hjKEs
+GcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkAAGoggALQGQAA
+aiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAAaiCAAcwZAAAK
+IMAnz3WgAMgfGRUSls9wAABEHPYPIAEKIcAvenDPcIAATEIjgM92nwC4/89wgAAAAESAAeJTIsME
+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
+PYEAGEAg97nFIYIPAP8AANMh4QV1Ai/zIKfgePHABgoP889wgAAwkgeIgOCcAiEAosHPcKAAyB9R
+EBCGAdlRGFiAINkwoAHZQxhYAADYzg0v8424INnPcKAAyB8xoE4P7/4F2M91gABoVg6lw9jPdqAA
+7CcGpgqGz3enABRIALWKIMQABqYKhgG1iiDFAAamCoYCtYogywAGpgqGA7WKIM8ABqYKhgS1z3AA
+AIMNBqYKhgW1z3AAAMMNBqYKhga1z3AAAAMOBqYKhge1CIcEpQ2HBaUOhwalz3CnAJhHPIAnpTeH
+KKU2hymlz3GlAAgMIoEqpc9xqwCg/ziBK6XPcasAoP85gSylz3GrAKD/OoEtpc9xBQDGAyamxtmQ
+uSamz3EsAAIBJqbPcVoAQgEmpoohiwAmps9xQACHDSamz3HRAMINJqbPccAABw4mpgHZKKcA2S2n
+LqfPcVAA/wA8oAHYF6cA2BanUNnPcKUACAwioPzZz3CrAKD/OKBz2TmgGoDPcasAoP+BuBqhz3Aq
+AAIOBqaLcIHBi/8Awc9wgAAAoTSlMqABwS+gz3AaAAIOBqaLcIHBhP8Awc9wgAAAoTWlM6ABwTCg
+z3AmAAIOBqaLcIHBfP8Awc9wgAAAoTSgNqUBwTGgz3CgAMgfURARhgHZURhYgCDZMKAB2UMYWAAA
+2BoML/ONuCDZz3CgAMgfMaABlRC4hSCEAAamApUQuIUghQAGpgOVELiFIIsABqYElRC4hSCPAAam
+BZUQuAUggA8AAIINBqYGlRC4BSCADwAAwg0GpgeVELgFIIAPAAACDgamz3CgAMgfURhYhASFKoUI
+pwWFDacGhQ6nCIUXpwmFFqfPcKUACAwioA3pBBIENgISBTYKIcAP63IF2MkE7/GKI0QCC4XPcasA
+oP8YoQyFGaENhRqhcg7v/g6Fz3CgAMgfURgYhLkH7/KiwOB48cBSD8/yz3CAADCSJojPdYAAaFai
+wQTpB4iG6CEDIABIFQQQA9gacIogkQUA304N7/LpcaYM7/4F2A6lw9jPdqAA7CcGpgqGALWKIMQA
+BqYKhgG1iiDFAAamCoYCtYogywAGpgqGA7WKIM8ABqYKhgS1z3AAAIMNBqYKhgW1z3AAAMMNBqYK
+hga1z3AAAAMOBqYKhge1z3CnABRIKIAkpS2ADoAlpQalz3CnAJhHPIAnpc9xpwAUSFeBNoFIpSml
+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
+QAC8DQn8ZQPP8eB48cDhxQh1BYADgEKFIICKIA8L/gjv8UJ5z3CAAKi0BZAJCFIA+/4D8B3/qXDD
+/zkDz/HgePHAtgrP8c91gADYtA+FSiAAIIDgyiHBD8oiwQfKIGEByiOBDwAAQgDKJAEEyAeh8Mol
+wQAB2s9xgABosWB4SKE8HQAUigzv8APY0QLP8eB48cBKCs/x2nCacfpyCiMAIQoiQCHIdwogwCEK
+IcCDz3CAADSLyiFiAChyBLkoYEwkAKAEuIYg/gMFIJEAyiHMD8oizAfKIGwByiOMDwAAhwDKJGwA
+UAes8MolDAXPdYAAzGIBhQDeyXH6Cu/xONoAhRzZIKABhRDZhC8LHAAhlX+AACzKILBcFQEgMxiC
+A892gAB0BxAYQgSZuSGgQCYBEyKgCiHAgygYAAQxGAIFMhgCBTQYxAXKIWIAig0v8gzgIYUI2BKp
+AYGNuAGhA4EfCF8CDInPcoAAbHbDuBx4CmLPcIAA0MpIYAyphu/PcoAA8LAF8M9ygAAQsUOlpNgA
+shDYAqULDlEgpNiMuACyDMCA4MohwQ/KIsEHyiBhAcojgQ8AALgAyiQhAHwGofDKJcEABKYhCxAg
+AYGYuAGhA4GfuAOhABUBIAQVACAAHoQUIaYCpt4IL/epcDkBz/HgeM9wgABosSiAz3CfALj/ANo2
+oAjZ7HAgoAPZz3CgABQEJaACyOxxAKHPcKAA1AtNoOB+4HjPcYAAiAfgfwCh4HjPcIAAiAfgfwCA
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8A2OB/ANjgfuB4ocHgf6HA4HjgfuB44H7g
+ePHA4cUCyM91gAAUYwClBG0CDe/xAtnPcYAOBADscCCghgvv8QCF2QDP8eB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjgfuB48cAAFgBBz3KAABRjBrIAFgVBQCIBBA4aRAFMJYCEyiHC
+D8oiwgfKIGIByiOCDwAAggBABaLwyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIB8woCgC4Mz/HRwOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjPcIAAjAfgfwCA4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+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
+HHDgfzGw4HjxwD4Pr+8E2qTBGnBqDO/vi3ECwAPDAN2pcQjaSiRAAqYKoABKJUAECHEBwDoLYACp
+cgpwz3Kt3u++1g9gAADBcghv/wpwbQjQAM92gADoCM9wAAAg0lYmQROSC2AABNrPcAAAIdJVJsEW
+ggtgAATaOob7hkEpwAXAuBi4E3gleEEvwRXAuRi5M3klfxqmz3EAAGgf+6a6C2/4CLgcps9xAABo
+H6oLb/hALwASHaapcPEGr++kwOB48cB2Dq/viiAPCoIkAjqacXpyWnOIdah3CiGAIQogwCEOCaAA
+nsGKcAYJoACLcYLGanD+CKAAyXFKcPYIoACEwalw7gigAIbBiMXpcOIIoACpcSpw2gigAIrBCnDS
+CKAAjMGpcIrBNgmgAJDCi3DJcSoJoACSwslwhMEiCaAAlMKGwKlxFgmgAJbCmMaQwJLBqgigAMly
+mseUwJbBngigAOlyyXDpcfYIoACcwpzAnsHKCKAAjsKfxW4IoAAEbY7AfgmgACRttwgQAIbAisGO
+CKAAQCUCE4twhMGCCKAAQCUCFZTAQCUBE1IIoADJcpDAQCUBFUYIoADpcslw6XGeCKAAnMKMwJzB
+MgigAMlyqgigAMlwyXCOwWIIoABAJQIXksBAJQETFgigAMlylsBAJQEVCgigAOlyyXDpcV4IoACc
+wozAnMH2D2AAyXLJcI7BKgigAEAlAhkeCKAAQCUAF89xgADoCBihDgigAEAlABnPcYAA6AgZoQfw
+ANnPcIAA6Ag4oDmgRQWv74AkAjrgePHA/gyv7wraqsEIdiIK7++LcQbYFgpgAAHBCNgOCmAAAcEJ
+2AYKYAABwRAUBDDJcADBAsIKJYAPrd7vvooNYAADw8lwXf9/CNAAz3WAAOgIHIUYFAQwEqUdhQDB
+CiWAD63e774CwhWlyXBeDWAABcPJcFL/TwjQAByFIBQEMBOlHYUAwQolgA+t3u++AsIWpclwNg1g
+AAfDyXBI/ycI0AB8hXQVBhDJcFQVBBBYFQUQdKUkFAcwMoVcHYARU4Vt/wDYqQSv76rA8cAaDK/v
+DNi6cTpyz3eAAOgIhBcTEHwXEBAA3Zpwz3CAAEBw8CBSA2pwFglv+EpxAnATeAoJb/iKIQ8KCHaI
+FwAQ/ghv+EpxgBcBEDhgE3juCG/4iiEPCrplVHpALcEgNnlZYcdxgABs9w0JESDEqQWpCfALCVEg
+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
+AADAFg8bGSJIBKCBOPDEgAAAGyQCABslOBzAEQAAACEAAACFIAWAgQAAwBYPGwQiEAQbZg8BG2gU
+HMAQCgAbQAQAG24DAABhDxwdIgEAHSb5DwBhZAwAEADABhEBAAQn/AAEZAAAGyQCABslOBzAEQAA
+ACEAABslQAAbJDAcwBEAAAAhDxwdIhgBHSYYAMcQmKaAgQAAwBcgAMcQoKaAgQAAwBcAAAAhrEqA
+gQIAXG4RAABh+EHEEA8bCSIACwk5AgAKYgMBCmIEAgpiAAAJQAQAAGEJAAlAAgAAYQoACUAAAABh
+AgAJQQAJGigAAMAWAQAbJgAAwBcEAB0mAQAIJ+kACGQAAAAhAAAAAIwBAAABAQEBAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAABw5AADwOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFKKA
+AAAAAAAAAAAAAAAAAAEAAAAHAAAAAAAAAMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAADAAAAaLGAAAAAAAAAAAAAQLWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAA/wAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIi6gAConQEAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAAAAAAAAAQAA
+AAEAAAAAAAAAAAAAAAAAAAABAQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABosYAAfN8BAAAA
+AABosYAATOYBAAAAAAAAAAAAaLGAAOTnAQAAAAAAAAAAAAAAAABosYAAAAAAAAAAAAAAAAAA/wAA
+AAAAAAAAAAAAUPEBAFDxAQBQ8QEAVPEBAAAAAAAdAAAAAAAAAAAAAAAAAAAAAAAAAH9/AAEAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAABAgQIAAgQIAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAcAAAAHAAAABwAAAAIAAAACAAAAgwAAAJIA
+AADoAAAA9wAAAE4BAABdAQAAAAABAAIAAACDAAAAkgAAAOgAAAD3AAAATgEAAF0BAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQAPAGQAAQDICIAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAEAAgAAAIMAAACSAAAA6AAAAPcAAABOAQAAXQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAOAIAAAVAAAABEeAAAQrAAAEKwAABCsAADBBAAAEKwAABCsAALA8AAAE
+KwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAABQHgAA+B8AABAgAAB8IQAA/CEAAIAh
+AAAEKwAABCsAAGhNAAAoTwAAEFAAAAQrAAAEKwAABCsAAOxLAABEYgAAQGIAAJhiAAAEKwAABCsA
+AAQrAAA8QwAABCsAAHxiAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAADRBAAAEKwAA
+BCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAE
+KwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAChEAAAEKwAABCsAAAQrAAAEKwAABCsAAAxF
+AAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAHBpAAAEKwAA0GoA
+AAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAAaG0AAAQrAAAEKwAABCsAAAQrAAAEKwAA
+BCsAAAQrAAAEKwAABCsAAAQrAAAEKwAAzIIBAByGAQAEKwAAaIgBAAQrAAAUigEAwFYBAAQrAAAE
+KwAA1FAAAAQrAAAEKwAABCsAAAQrAAAEKwAAuNcBAAzYAQAEKwAABCsAAAQrAAAEKwAABCsAAAQr
+AAAEKwAABCsAAAQrAAAEKwAABCsAAPx0AAAEKwAABCsAAAQrAADY3QEABCsAAOjhAQAEKwAAvP8B
+AAQrAAAgJQAAJCUAAAQrAAAEKwAAePABALx3AAAEKwAABCsAAAQrAABE2wEABCsAAAQrAAA0UAEA
+dKEBAAQrAAAEKwAABCsAADyqAQDcVwEABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAAMK0BAAQrAABw
+7wEAdO8BAIDvAQCE7wEAeO8BAHzvAQCI7wEABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQr
+AAAEKwAAuFIAAAQrAAAEKwAABCsAAAQrAAAEKwAAxO4BABTvAQAQRwAABCsAAAQrAAAEKwAABCsA
+AAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAA
+BCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAE
+KwAABCsAAAQrAAAEKwAABCsAAIhIAAAQSQAAoEkAAFRKAABwhgAALEoAAAQrAAAEKwAABCsAAAQr
+AAAEKwAAgEgAAIRIAAAEKwAABCsAAARRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwA
+AJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAA
+lAwAAJQMAACUDAAAlAwAAJQMAACUDAAAxA0AAAAAAAAwXQEAlAwAALgJAACUDAAAlAwAAJQMAADo
+CQAA6D8BAJCIAACUDAAAlAwAABwKAAAcCgAAHAoAABwKAAAcCgAAHAoAABwKAACUDAAAlAwAAJQM
+AACUDAAABAwAAJQMAACUDAAAlAwAAJQMAACUDAAAyA0AAJQMAACUDAAAnAkAAAMAAACQ7AEAAgAA
+ACxrAQAEAAAA3GsBAAUAAADkDQAABgAAALgzAAAIAAAA8O4BABMAAACc2AEACQAAAITjAQAKAAAA
+jO8BAA4AAACQngEADwAAAECMAQAQAAAAeIwBABkAAACYXAEADQAAABCEAQAXAAAAuHcAABEAAADk
+hgAAEgAAADxPAQABAAAAXN0BABQAAAB8qwEAFQAAAKShAQAHAAAA2G0AABYAAACs/wEAGAAAAOSg
+AAAaAAAAxA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAABAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBAAAAAAAAAAAAABAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAABQjwEAVJABACSTAQDQlQEASJgBAKybAQD4kQEANAWAADCxgAAYAAAA8LCA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAOJ4BAAYAAADERoAA/////wAAAAD//////////wAAAAAAAAAA
+AAAAAAShAQAFAAAABEeAAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDAAKAAUACAAL4AUAF9
+AD4AAAAAAAEBAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA///AAC5Ad8AsQAbABYB
+GwB8ARsArwAbABQBGwB6ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAzAG4AMwBwADMAcgAz
+ANcAMwA9ATMA1AEGANABAAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA5ABaAEoBWgCqAD8A
+qwABAA8BPwAQAQEAdQE/AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACmADcApwABAAsBNwAM
+AQEAcQE3AHIBAQAEAAgAnAHMAJ0BzACeAcwAnwHMANUBzADWAcwA1wHMALQARwAZAUcAgAFHAJAA
+IgD1ACIAWwEiAKEAiAAGAYgAbAGIAJQAAACVAAAAmADAAJkAoACWAJAAlwAAAJQAAQCVAAEAmADA
+AJkAoACWAJAAlwAAAJQAAgCVAAMAmADAAJkAoACWAJAAlwAAAJQAAwCVAAcAmADAAJkAoACWAJAA
+lwAAAPoAAAD5AAAAAgGQAAMB0wAAAYMA/gATAPwAMwD9AHcA+gABAPkAAQACAZAAAwHTAAABgwD+
+ABMA/AAzAP0AdwD6AAIA+QADAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAwD5AAcAAgGSAAMB
+0wAAAYMA/gATAPwAMwD9AHcAXwEAAGEBAABoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQEAYQEB
+AGgBkABpAdMAZgGDAGQBEwBiATMAYwF3AF8BAgBhAQMAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcA
+XwEDAGEBBwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwCFAAAAhgAAAIcAUACIAAAAiQCgAIoAAACL
+ANAAjAAAAIUAAQCGAAEAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQACAIYAAwCHAFAAiAAAAIkA
+oACKAAAAiwDQAIwAAACFAAMAhgAHAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAOsAAADqAAAA7ABQ
+AO0AAADuAKAA7wAAAPAA0ADxAAAA6wABAOoAAQDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAIA
+6gADAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAwDqAAcA7ABQAO0AAADuAKAA7wAAAPAA0ADx
+AAAAUQEAAFABAABSAVAAUwEAAFQBoABVAQAAVgHQAFcBAABRAQEAUAEBAFIBUABTAQAAVAGgAFUB
+AABWAdAAVwEAAFEBAgBQAQMAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQEDAFABBwBSAVAAUwEA
+AFQBoABVAQAAVgHQAFcBAAD7/wAA//8AALkB3wCxABsAFgEbAHwBGwCvABsAFAEbAHoBGwBsAKAA
+0QCgADcBoABvAIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDUAQYA0AEAAH4APADj
+ADwASQE8AHgASQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABABAQB1AT8AdgEBAHkA
+agDeAGoARAFqAKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEBAAQACACcAcwAnQHM
+AJ4BzACfAYgA1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIAoQCIAAYBiABsAYgA
++gAAAPkAAAACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAEA+QABAAIBlwADAdAAAAGNAP4AEQD8
+ADMA/QB3APoAAgD5AAMAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gADAPkABwACAZcAAwHQAAAB
+jQD+ABEA/AAzAP0AdwBfAQAAYQEAAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAQBhAQEAaAGX
+AGkB0ABmAY0AZAERAGIBMwBjAXcAXwECAGEBAwBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQMA
+YQEHAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AOsAAADqAAAA7ABVAO0AAADuAKoA7wAAAPAA3QDx
+AAAA6wABAOoAAQDsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAIA6gADAOwAVQDtAAAA7gCqAO8A
+AADwAN0A8QAAAOsAAwDqAAcA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAAUQEAAFABAABSAVUAUwEA
+AFQBqgBVAQAAVgHdAFcBAABRAQEAUAEBAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAgBQAQMA
+UgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEDAFABBwBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAAD7
+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoKwBALTNAQCwu4AAQAUA
+AAAAAACgrAEAwK0BAPDAgAD4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhNIBAIzQAQDowoAA
+VAAAAAAAAACgrAEAuNABAGjDgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAoKwBANTMAQC0
+V4AAUAEAAAAAAACgrAEA7M4BAOgGgAACAAAAAAAAAKCsAQBEzwEA7AaAAAQAAAAAAAAAgNIBAMCt
+AQA8w4AAKgAAAAAAAACgrAEA4M8BAAAAAAAAAAAAAAAAAKCsAQCgzwEA8AaAAAQAAAAAAAAAAAAA
+AAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALAAwADAANAA4ADgAPACYAJwAoACgA
+KQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwAbABtAG4AbgBvAHAAcABxAHIAcgBz
+AHQAdAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA8APwAAAAAAAAAAAAAA
+AAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAKAAsAJAAkACUAJgAmACcARABEAEUARgBG
+AEcASABIAEkASgBKAEsATABMAE0AagBqAGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAdAB0AHUA
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAA0BYAAMLGAABgAAADwsIAAAAAAAAAAAAAAAAAAAAAAAAAAAABM3wEABgAAAMRGgAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQF
+gAAwsYAAGAAAAPCwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAA
+AGzqAQAEAAAAxEaAAAAAAAAAAAAAAAAAAFzsAQAGAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAA
+xEaAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAAxEaAAAAAAAAA
+AAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAAxEaAAAAAAAAAAAAAAAAAAFzs
+AQAGAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAAxEaAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaA
+AAAAAAAAAAAAAAAAAFzsAQAGAAAAxEaAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAA
+AAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAAAFzsAQAGAAAAxEaAADQFgAAwsYAAGAAAAPCwgAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwNAAAABQYHCA0ODxAVFhcYGQAACg0RFAoNERQZGRkZ
+CgoAAAAAAAAGBgYGCQkJCQAGAABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluK2grYitcK24qaCpi
+KlwqbiloKWIpXCluG2gbYhtcG24aaBpiGlwabhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbhZoFmIW
+XBZuFWgVYhVcFW4UaBRiFFwUbhNoE2ITXBNuEmgSYhJcEm4RaBFiEVwRbhBoEGIQXBBXEFIQTRBJ
+EG4BaAFiAVwBbgBoAGIAXABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdiN1w3
+biloKWIpXCluKGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbgloCWIJXAlu
+CGgIYghcCG4HaAdiB1wHbgZoBmIGXAZuBWgFYgVcBW4EaARiBFwEbgNoA2IDXANuAmgCYgJcAm4B
+aAFiAVwBbgBoAGIAXAAAAAAAAAAAAAAAAADUAQIACAAAAARHgAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AAH//wID////BP//////////////////
+////Bf8G/wf/CP8J/wr/C/8M////Df///w7///8P////EP//////////////////////////////
+////////////////Ef///xL///8T////FP///xX///8W////F////xj///8Z////Gv///xv/////
+HP///x3///8e////H////yD///8h//////////////////////8iIyT/JSYn//8o////Kf//////
+////////////////////////////////////////////////////////////////////////AQQA
+AAIFAQADBgIABAcDAAUIBAAGCQUABwoGAAgLBwAJDAgACg0JAAsOCgAMDwsADRAMAA4RDQABQAAE
+AkEBBANCAgQEQwMEBUQEBAZFBQQHRgYECEcHBAlICAS3EyIAuBQjALkVJAC7FiUAvBcmAL0YJwDA
+GSgAxBopAAcbAAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAmIwcAKCQIAColCQAsJgoALicLADAo
+DAA0KQ0AOCoOADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQyFQB4MxYAfDQXAIA1GACENhkAiDca
+AIw4GwCROhwAlTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoKAjRLDQE8TA8BZE0RAWxOEwF0TxUB
+fFAXAYRRGQGVUh0BnVMfARzSDdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIEQwbSB9IE0nDSAAC1
+ABoBgQEFAAQABgAIAAkACgALAAwAgwCSAOgA9wBOAV0BDwAE0g3SEdIQ0gLSAdID0hvSAIAF0gvS
+EtIT0hTSBENw0gAAAAABAAAA////////////////AwAAAAIAAAADAAAAAwAAAAAAAAD/////AAAA
+AAAAAAAAAAAA/wMAAAAAAAC1ABoBgQEEAA8ABgAIAAkACgALAAwAAAAAAAAAAAAsAAEAFQAVABUA
+AQABAAEAAAA4AAAAaAAAAHQAAACAAAAAjAAAAJ0AAAAHAAAABAAAAAgAAAAQAAAAQAAAAIAAAAAg
+AAAAAAAAAAkAAAASAAAAAAAAAAoAAAAUAAAAOAAAAGgAAAB0AAAAgAAAAIwAAACdAAAABwAAAAAA
+AAAAAAAACgAAAA3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMI0gnSCtIc0gbSB9Jw0gAAAQAA
+AAAAAAAAAAAAAAAAAAMAAAAEAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAP8DAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtQAaAYEBBAAPAIMA6ABOAZIA9wBdAQYACAAJAAoACwAM
+AAUAAAAAAAAALAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAAA/////wAAAAAtAQAA3QEAAFoC
+AAC6AgAACgMAAE0DAACHAwAAugMAAOgDAAARBAAANwQAAFkEAAB6BAAAmAQAALQEAADOBAAA5wQA
+AP4EAAAVBQAAKgUAAD4FAABRBQAAZAUAAHUFAACGBQAAlwUAAKcFAAC2BQAAxQUAANMFAADhBQAA
+7gUAAPsFAAAIBgAAFAYAACAGAAArBgAANwYAAEIGAABMBgAAVwYAAGEGAABrBgAAdQYAAH4GAACI
+BgAAkQYAAJoGAACiBgAAqwYAALQGAAC8BgAAxAYAAMwGAADUBgAA2wYAAOMGAADqBgAA8gYAAPkG
+AAAABwAABwcAAA4HAAAUBwAAGwcAACIHAAAoBwAALgcAADUHAAA7BwAAQQcAAEcHAABNBwAAUwcA
+AFgHAABeBwAAZAcAAGkHAABvBwAAdAcAAHkHAAB/BwAAhAcAAIkHAACOBwAAkwcAAJgHAACdBwAA
+ogcAAKcHAACrBwAAsAcAALUHAAC5BwAAvgcAAMIHAADHBwAAywcAANAHAADUBwAA2AcAANwHAADh
+BwAA5QcAAOkHAADtBwAA8QcAAPUHAAD5BwAA/QcAAAEIAAAFCAAACAgAAAwIAAAQCAAAFAgAABcI
+AAAbCAAAHwgAACIIAAAmCAAAKQgAAC0IAAAwCAAANAgAADcIAAA7CAAAPggAAEEIAABFCAAASAgA
+AEsIAABPCAAAUggAAFUIAABYCAAAWwgAAF8IAABiCAAAZQgAAGgIAABrCAAAbggAAHEIAAB0CAAA
+dwgAAHoIAAB9CAAAgAgAAIIIAACFCAAAiAgAAIsIAACOCAAAkQgAAJMIAACWCAAAmQgAADgAAABo
+AAAAdAAAAIAAAACMAAAAnQAAAAcAAAAAAAAAAAAAAAoAAAAN0hHSENIC0gHSA9Ib0gvSAIAF0hLS
+E9IU0gRDCNIJ0grSHNIG0gfScNIAAAEAAAAAAAAAAAAAAAAAAAADAAAABAAAAAMAAAAAAAAAAwAA
+AAAAAAAAAAAAAAAAAAAAAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALUAGgGBAQQA
+DwCDAOgATgGSAPcAXQEGAAgACQAKAAsADAAFAAAAAAAAACwAAQAAAAAAAAAAAAAAAAAAAAAAAAAB
+AAEAAQAAAN8AAAAZAQAAYgEAAL4BAAAyAgAAwwIAAHsDAABiBAAAhAUAAPIGAAC+CAAAAgsAAAEA
+AAACAAAAAAAAAAvSDtIN0gjSCdIK0hLSE9IU0hHSENIC0gHSA9IAgAXSBEMb0hzSBNIARTDSMdIA
+AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAHAAAAAAAAAAMAAAAEAAAA
+AwAAAAAAAAD/AwAAAwAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAtQAaAYEBBQAE
+AA8AEAAKAAsADABOAAAAAAAAAAAAAAAsAAEAAAABAAEAAQAAAAAAAAAAAAEAAQACAAIAAgADAAMA
+BAAEAAUABQAGAAYABwAHAAgACAAJAAkACgAKAAsACwAMAAwADQANAA4ADgAPAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAIA
+AAAPAD8AAQAAAAAAAAABAAAAAgAAAAMAAAAAAAAABAAAAAIAAAAFAAAADxQZHigKBQDBCQGlADw4
+NDAsKCQgHBgUEAwIBAAMCAQAPDg0MCwoJCAcGBQQDAgEAggADgAAAA4BAQABAgEBAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKXG
+hPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pFvyP3
+U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8JDjYk
+mxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBAH+PI
+ee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+XcCA
+igWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6KzKV
+5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3vQ6bE
+qDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dzUZcj
+y3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsyszIrvS
+cKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTosAQEB
+AQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQEBAQE
+BAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ0
+0UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8PBwYH
+AgMEBQABCAkLCigAKAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA9ACw
+ACwALAA8ADQAMAAsAFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZAOgA
+CgG6AHkAiACKBSoDOQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUAQQKs
+AJAAhACAAHgAeAB4AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2
+YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRA
+BSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iAN
+CqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcG
+aZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiM
+wAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAaQB2A
+IIAGAA2AEwAaACcANIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6mFeYc
+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
+iB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/BZcfAALA
+AAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAADAAAABAAA
+AYMFpSEAAEAAAAMAAAGFBQAACxkVGRcAAABY5AEAbOQBANTkAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAABAQEBAQEBAQICAgICAgIC
+AwMDAwMDAwMBAgAADgAAACoAAAAJAAAACwAAABX2Y/aw9vz2RveQ99j3H/hl+Kn47fgv+XD5sPnu
++Sv6Z/qi+tz6FPtL+4H7tvvq+xz8Tfx9/Kv82fwF/TD9Wf2C/an9z/30/Rf+Of5a/nr+mP62/tL+
+7f4G/x7/Nf9L/2D/c/+F/5b/pv+0/8H/zf/Y/+H/6f/w//b/+v/9//////////3/+v/2//D/6f/h
+/9j/zf/B/7T/pv+W/4X/c/9g/0v/Nf8e/wb/7f7S/rb+mP56/lr+Of4X/vT9z/2p/YL9Wf0w/QX9
+2fyr/H38Tfwc/Or7tvuB+0v7FPvc+qL6Z/or+u75sPlw+S/57fip+GX4H/jY95D3Rvf89rD2Y/Zw
+uYO6lruqvL690r7nv/zAEcInwz3EU8VqxoDHl8ivycbK3sv2zA/OJ89A0FnRctKM06bUv9Xa1vTX
+Dtkp2kTbX9x63Zbesd/N4OnhBeMh5D7lWuZ355PosOnN6urrB+0k7kLvX/B98ZryuPPV9PP1Efcv
++Ez5avqI+6b8xP3i/gAAHgE8AloDeASWBbQG0QfvCA0KKwtIDGYNgw6hD74Q3BH5EhYUMxVQFm0X
+iRimGcIa3xv7HBceMx9PIGohhiKhI7wk1yXyJgwoJilBKlordCyOLacuwC/ZMPExCjMiNDo1UTZp
+N4A4ljmtOsM72TzvPQQ/GUAuQUJCVkNqRH1FxQtkElCdGxK/YNUR6jyRESMaTxEb4g4Ryn/QEFjf
+kxAF7lgQGpofENTS5w9WiLEPmat8D1suSQ8YAxcP+hzmDtFvtg4E8IcOjZJaDu5MLg4oFQMOtuHY
+DYGprw3gY4cNjwhgDaiPOQ2d8RMNOSfvDJQpywwU8qcMZnqFDHq8YwyDskIM8VYiDGykAgzVleML
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAA==
+====
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index 31e5b11..35c9f68 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -975,7 +975,6 @@ typedef u_int32_t u_32_t;
# define SPL_NET(x) ;
# define SPL_IMP(x) ;
# define SPL_SCHED(x) ;
-extern int in_cksum __P((struct mbuf *, int));
# else
# define SPL_SCHED(x) x = splhigh()
# endif /* __FreeBSD_version >= 500043 */
diff --git a/sys/contrib/x86emu/x86emu.c b/sys/contrib/x86emu/x86emu.c
index 3e5a06a..280d4f9 100644
--- a/sys/contrib/x86emu/x86emu.c
+++ b/sys/contrib/x86emu/x86emu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x86emu.c,v 1.4 2009/06/18 14:19:21 pirofti Exp $ */
+/* $OpenBSD: x86emu.c,v 1.5 2010/02/17 15:09:47 pirofti Exp $ */
/* $NetBSD: x86emu.c,v 1.7 2009/02/03 19:26:29 joerg Exp $ */
/*
@@ -235,7 +235,8 @@ x86emu_exec(struct x86emu *emu)
for (;;) {
if (emu->x86.intr) {
- if (((emu->x86.intr & INTR_SYNCH) && (emu->x86.intno == 0 || emu->x86.intno == 2)) ||
+ if (((emu->x86.intr & INTR_SYNCH) &&
+ (emu->x86.intno == 0 || emu->x86.intno == 2)) ||
!ACCESS_FLAG(F_IF)) {
x86emu_intr_handle(emu);
}
@@ -796,9 +797,9 @@ decode_rh_seg_register(struct x86emu *emu)
x86emu_halt_sys(emu);
}
}
+
/*
- *
- * return offset from the SIB Byte
+ * Return offset from the SIB Byte.
*/
static uint32_t
decode_sib_address(struct x86emu *emu, int sib, int mod)
@@ -1107,7 +1108,8 @@ common_dec_word_long(struct x86emu *emu, union x86emu_register *reg)
}
static void
-common_binop_byte_rm_r(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
+common_binop_byte_rm_r(struct x86emu *emu,
+ uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
{
uint32_t destoffset;
uint8_t *destreg, srcval;
@@ -1127,7 +1129,8 @@ common_binop_byte_rm_r(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uin
}
static void
-common_binop_ns_byte_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uint8_t, uint8_t))
+common_binop_ns_byte_rm_r(struct x86emu *emu,
+ void (*binop)(struct x86emu *, uint8_t, uint8_t))
{
uint32_t destoffset;
uint8_t destval, srcval;
@@ -1144,7 +1147,8 @@ common_binop_ns_byte_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uin
}
static void
-common_binop_word_rm_r(struct x86emu *emu, uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t))
+common_binop_word_rm_r(struct x86emu *emu,
+ uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t))
{
uint32_t destoffset;
uint16_t destval, *destreg, srcval;
@@ -1163,7 +1167,8 @@ common_binop_word_rm_r(struct x86emu *emu, uint16_t (*binop)(struct x86emu *, ui
}
static void
-common_binop_byte_r_rm(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
+common_binop_byte_r_rm(struct x86emu *emu,
+ uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
{
uint8_t *destreg, srcval;
uint32_t srcoffset;
@@ -1180,7 +1185,8 @@ common_binop_byte_r_rm(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uin
}
static void
-common_binop_long_rm_r(struct x86emu *emu, uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t))
+common_binop_long_rm_r(struct x86emu *emu,
+ uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t))
{
uint32_t destoffset;
uint32_t destval, *destreg, srcval;
@@ -1200,7 +1206,8 @@ common_binop_long_rm_r(struct x86emu *emu, uint32_t (*binop)(struct x86emu *, ui
static void
common_binop_word_long_rm_r(struct x86emu *emu,
- uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t), uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
+ uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t),
+ uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
{
if (emu->x86.mode & SYSMODE_PREFIX_DATA)
common_binop_long_rm_r(emu, binop32);
@@ -1209,7 +1216,8 @@ common_binop_word_long_rm_r(struct x86emu *emu,
}
static void
-common_binop_ns_word_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uint16_t, uint16_t))
+common_binop_ns_word_rm_r(struct x86emu *emu,
+ void (*binop)(struct x86emu *, uint16_t, uint16_t))
{
uint32_t destoffset;
uint16_t destval, srcval;
@@ -1227,7 +1235,8 @@ common_binop_ns_word_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uin
static void
-common_binop_ns_long_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uint32_t, uint32_t))
+common_binop_ns_long_rm_r(struct x86emu *emu,
+ void (*binop)(struct x86emu *, uint32_t, uint32_t))
{
uint32_t destoffset;
uint32_t destval, srcval;
@@ -1245,7 +1254,8 @@ common_binop_ns_long_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uin
static void
common_binop_ns_word_long_rm_r(struct x86emu *emu,
- void (*binop16)(struct x86emu *, uint16_t, uint16_t), void (*binop32)(struct x86emu *, uint32_t, uint32_t))
+ void (*binop16)(struct x86emu *, uint16_t, uint16_t),
+ void (*binop32)(struct x86emu *, uint32_t, uint32_t))
{
if (emu->x86.mode & SYSMODE_PREFIX_DATA)
common_binop_ns_long_rm_r(emu, binop32);
@@ -1254,7 +1264,8 @@ common_binop_ns_word_long_rm_r(struct x86emu *emu,
}
static void
-common_binop_long_r_rm(struct x86emu *emu, uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t))
+common_binop_long_r_rm(struct x86emu *emu,
+ uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t))
{
uint32_t srcoffset;
uint32_t *destreg, srcval;
@@ -1271,7 +1282,8 @@ common_binop_long_r_rm(struct x86emu *emu, uint32_t (*binop)(struct x86emu *, ui
}
static void
-common_binop_word_r_rm(struct x86emu *emu, uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t))
+common_binop_word_r_rm(struct x86emu *emu,
+ uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t))
{
uint32_t srcoffset;
uint16_t *destreg, srcval;
@@ -1289,7 +1301,8 @@ common_binop_word_r_rm(struct x86emu *emu, uint16_t (*binop)(struct x86emu *, ui
static void
common_binop_word_long_r_rm(struct x86emu *emu,
- uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t), uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
+ uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t),
+ uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
{
if (emu->x86.mode & SYSMODE_PREFIX_DATA)
common_binop_long_r_rm(emu, binop32);
@@ -1298,7 +1311,8 @@ common_binop_word_long_r_rm(struct x86emu *emu,
}
static void
-common_binop_byte_imm(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
+common_binop_byte_imm(struct x86emu *emu,
+ uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
{
uint8_t srcval;
@@ -1308,7 +1322,8 @@ common_binop_byte_imm(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint
static void
common_binop_word_long_imm(struct x86emu *emu,
- uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t), uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
+ uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t),
+ uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
{
if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
uint32_t srcval;
@@ -1765,7 +1780,8 @@ x86emuOp_opc80_byte_RM_IMM(struct x86emu *emu)
}
static
-uint16_t(* const opc81_word_operation[]) (struct x86emu *, uint16_t d, uint16_t s) =
+uint16_t(* const opc81_word_operation[])
+ (struct x86emu *, uint16_t d, uint16_t s) =
{
add_word, /* 00 */
or_word, /* 01 */
@@ -1778,7 +1794,8 @@ uint16_t(* const opc81_word_operation[]) (struct x86emu *, uint16_t d, uint16_t
};
static
-uint32_t(* const opc81_long_operation[]) (struct x86emu *, uint32_t d, uint32_t s) =
+uint32_t(* const opc81_long_operation[])
+ (struct x86emu *, uint32_t d, uint32_t s) =
{
add_long, /* 00 */
or_long, /* 01 */
@@ -1840,7 +1857,8 @@ x86emuOp_opc81_word_RM_IMM(struct x86emu *emu)
}
static
-uint8_t(* const opc82_byte_operation[]) (struct x86emu *, uint8_t s, uint8_t d) =
+uint8_t(* const opc82_byte_operation[])
+ (struct x86emu *, uint8_t s, uint8_t d) =
{
add_byte, /* 00 */
or_byte, /* 01 *//* YYY UNUSED ???? */
@@ -1876,7 +1894,8 @@ x86emuOp_opc82_byte_RM_IMM(struct x86emu *emu)
}
static
-uint16_t(* const opc83_word_operation[]) (struct x86emu *, uint16_t s, uint16_t d) =
+uint16_t(* const opc83_word_operation[])
+ (struct x86emu *, uint16_t s, uint16_t d) =
{
add_word, /* 00 */
or_word, /* 01 *//* YYY UNUSED ???? */
@@ -1889,7 +1908,8 @@ uint16_t(* const opc83_word_operation[]) (struct x86emu *, uint16_t s, uint16_t
};
static
-uint32_t(* const opc83_long_operation[]) (struct x86emu *, uint32_t s, uint32_t d) =
+uint32_t(* const opc83_long_operation[])
+ (struct x86emu *, uint32_t s, uint32_t d) =
{
add_long, /* 00 */
or_long, /* 01 *//* YYY UNUSED ???? */
@@ -2603,7 +2623,8 @@ x86emuOp_movs_word(struct x86emu *emu)
store_long(emu, emu->x86.R_ES, emu->x86.R_DI, val);
} else {
val = fetch_data_word(emu, emu->x86.R_SI);
- store_word(emu, emu->x86.R_ES, emu->x86.R_DI, (uint16_t) val);
+ store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
+ (uint16_t) val);
}
emu->x86.R_SI += inc;
emu->x86.R_DI += inc;
@@ -2689,11 +2710,13 @@ x86emuOp_cmps_word(struct x86emu *emu)
while (emu->x86.R_CX != 0) {
if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
val1 = fetch_data_long(emu, emu->x86.R_SI);
- val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val2 = fetch_long(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_long(emu, val1, val2);
} else {
val1 = fetch_data_word(emu, emu->x86.R_SI);
- val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val2 = fetch_word(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
}
emu->x86.R_CX -= 1;
@@ -2709,11 +2732,13 @@ x86emuOp_cmps_word(struct x86emu *emu)
while (emu->x86.R_CX != 0) {
if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
val1 = fetch_data_long(emu, emu->x86.R_SI);
- val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val2 = fetch_long(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_long(emu, val1, val2);
} else {
val1 = fetch_data_word(emu, emu->x86.R_SI);
- val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val2 = fetch_word(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
}
emu->x86.R_CX -= 1;
@@ -2769,7 +2794,8 @@ x86emuOp_stos_byte(struct x86emu *emu)
/* dont care whether REPE or REPNE */
/* move them until CX is ZERO. */
while (emu->x86.R_CX != 0) {
- store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL);
+ store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
+ emu->x86.R_AL);
emu->x86.R_CX -= 1;
emu->x86.R_DI += inc;
}
@@ -2808,9 +2834,11 @@ x86emuOp_stos_word(struct x86emu *emu)
}
while (count--) {
if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
- store_long(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_EAX);
+ store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
+ emu->x86.R_EAX);
} else {
- store_word(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AX);
+ store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
+ emu->x86.R_AX);
}
emu->x86.R_DI += inc;
}
@@ -2948,10 +2976,12 @@ x86emuOp_scas_word(struct x86emu *emu)
/* move them until CX is ZERO. */
while (emu->x86.R_CX != 0) {
if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
- val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val = fetch_long(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_long(emu, emu->x86.R_EAX, val);
} else {
- val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val = fetch_word(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
}
emu->x86.R_CX -= 1;
@@ -2965,10 +2995,12 @@ x86emuOp_scas_word(struct x86emu *emu)
/* move them until CX is ZERO. */
while (emu->x86.R_CX != 0) {
if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
- val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val = fetch_long(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_long(emu, emu->x86.R_EAX, val);
} else {
- val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
+ val = fetch_word(emu, emu->x86.R_ES,
+ emu->x86.R_DI);
cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
}
emu->x86.R_CX -= 1;
@@ -3094,7 +3126,8 @@ x86emuOp_mov_word_DI_IMM(struct x86emu *emu)
}
/* used by opcodes c0, d0, and d2. */
static
-uint8_t(* const opcD0_byte_operation[]) (struct x86emu *, uint8_t d, uint8_t s) =
+uint8_t(* const opcD0_byte_operation[])
+ (struct x86emu *, uint8_t d, uint8_t s) =
{
rol_byte,
ror_byte,
@@ -3128,7 +3161,8 @@ x86emuOp_opcC0_byte_RM_MEM(struct x86emu *emu)
}
/* used by opcodes c1, d1, and d3. */
static
-uint16_t(* const opcD1_word_operation[]) (struct x86emu *, uint16_t s, uint8_t d) =
+uint16_t(* const opcD1_word_operation[])
+ (struct x86emu *, uint16_t s, uint8_t d) =
{
rol_word,
ror_word,
@@ -3141,7 +3175,8 @@ uint16_t(* const opcD1_word_operation[]) (struct x86emu *, uint16_t s, uint8_t d
};
/* used by opcodes c1, d1, and d3. */
static
-uint32_t(* const opcD1_long_operation[]) (struct x86emu *, uint32_t s, uint8_t d) =
+uint32_t(* const opcD1_long_operation[])
+ (struct x86emu *, uint32_t s, uint8_t d) =
{
rol_long,
ror_long,
@@ -3172,13 +3207,15 @@ x86emuOp_opcC1_word_RM_MEM(struct x86emu *emu)
uint32_t destval;
destval = decode_and_fetch_long_imm8(emu, &amt);
- destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, amt);
+ destval = (*opcD1_long_operation[emu->cur_rh])
+ (emu, destval, amt);
write_back_long(emu, destval);
} else {
uint16_t destval;
destval = decode_and_fetch_word_imm8(emu, &amt);
- destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, amt);
+ destval = (*opcD1_word_operation[emu->cur_rh])
+ (emu, destval, amt);
write_back_word(emu, destval);
}
}
@@ -3295,7 +3332,8 @@ x86emuOp_enter(struct x86emu *emu)
if (nesting > 0) {
for (i = 1; i < nesting; i++) {
emu->x86.R_BP -= 2;
- push_word(emu, fetch_word(emu, emu->x86.R_SS, emu->x86.R_BP));
+ push_word(emu, fetch_word(emu, emu->x86.R_SS,
+ emu->x86.R_BP));
}
push_word(emu, frame_pointer);
}
@@ -3413,14 +3451,14 @@ x86emuOp_opcD1_word_RM_1(struct x86emu *emu)
fetch_decode_modrm(emu);
destval = decode_and_fetch_long(emu);
- destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, 1);
+ destval = (*opcD1_long_operation[emu->cur_rh])(emu, destval, 1);
write_back_long(emu, destval);
} else {
uint16_t destval;
fetch_decode_modrm(emu);
destval = decode_and_fetch_word(emu);
- destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, 1);
+ destval = (*opcD1_word_operation[emu->cur_rh])(emu, destval, 1);
write_back_word(emu, destval);
}
}
@@ -3436,7 +3474,8 @@ x86emuOp_opcD2_byte_RM_CL(struct x86emu *emu)
fetch_decode_modrm(emu);
destval = decode_and_fetch_byte(emu);
- destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
+ destval = (*opcD0_byte_operation[emu->cur_rh])
+ (emu, destval, emu->x86.R_CL);
write_back_byte(emu, destval);
}
@@ -3452,14 +3491,16 @@ x86emuOp_opcD3_word_RM_CL(struct x86emu *emu)
fetch_decode_modrm(emu);
destval = decode_and_fetch_long(emu);
- destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
+ destval = (*opcD1_long_operation[emu->cur_rh])
+ (emu, destval, emu->x86.R_CL);
write_back_long(emu, destval);
} else {
uint16_t destval;
fetch_decode_modrm(emu);
destval = decode_and_fetch_word(emu);
- destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
+ destval = (*opcD1_word_operation[emu->cur_rh])
+ (emu, destval, emu->x86.R_CL);
write_back_word(emu, destval);
}
}
@@ -4118,7 +4159,8 @@ x86emuOp_opcFF_word_RM(struct x86emu *emu)
/* Yet another special case instruction. */
fetch_decode_modrm(emu);
- if ((emu->cur_mod == 3 && (emu->cur_rh == 3 || emu->cur_rh == 5)) || emu->cur_rh == 7)
+ if ((emu->cur_mod == 3 && (emu->cur_rh == 3 || emu->cur_rh == 5)) ||
+ emu->cur_rh == 7)
x86emu_halt_sys(emu);
if (emu->cur_rh == 0 || emu->cur_rh == 1 || emu->cur_rh == 6) {
if (emu->x86.mode & SYSMODE_PREFIX_DATA)
@@ -5153,7 +5195,9 @@ common_shift(struct x86emu *emu, int shift_left, int use_cl)
common_shift16(emu, shift_left, use_cl);
}
-/*----------------------------- Implementation ----------------------------*/
+/*
+ * Implementation
+ */
#define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
@@ -5669,18 +5713,21 @@ x86emu_exec_two_byte(struct x86emu * emu)
common_jmp_long(emu, !ACCESS_FLAG(F_PF));
break;
case 0x8c:
- common_jmp_long(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
+ common_jmp_long(emu, xorl(ACCESS_FLAG(F_SF),
+ ACCESS_FLAG(F_OF)));
break;
case 0x8d:
- common_jmp_long(emu, !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))));
+ common_jmp_long(emu, !(xorl(ACCESS_FLAG(F_SF),
+ ACCESS_FLAG(F_OF))));
break;
case 0x8e:
- common_jmp_long(emu,
- (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)));
+ common_jmp_long(emu, (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))
+ || ACCESS_FLAG(F_ZF)));
break;
case 0x8f:
- common_jmp_long(emu,
- !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)));
+ common_jmp_long(emu,
+ !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+ ACCESS_FLAG(F_ZF)));
break;
case 0x90:
@@ -5720,10 +5767,12 @@ x86emu_exec_two_byte(struct x86emu * emu)
common_set_byte(emu, !ACCESS_FLAG(F_PF));
break;
case 0x9c:
- common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
+ common_set_byte(emu, xorl(ACCESS_FLAG(F_SF),
+ ACCESS_FLAG(F_OF)));
break;
case 0x9d:
- common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
+ common_set_byte(emu, xorl(ACCESS_FLAG(F_SF),
+ ACCESS_FLAG(F_OF)));
break;
case 0x9e:
common_set_byte(emu,
@@ -5830,69 +5879,71 @@ x86emu_exec_two_byte(struct x86emu * emu)
}
/*
-* Carry Chain Calculation
-*
-* This represents a somewhat expensive calculation which is
-* apparently required to emulate the setting of the OF and AF flag.
-* The latter is not so important, but the former is. The overflow
-* flag is the XOR of the top two bits of the carry chain for an
-* addition (similar for subtraction). Since we do not want to
-* simulate the addition in a bitwise manner, we try to calculate the
-* carry chain given the two operands and the result.
-*
-* So, given the following table, which represents the addition of two
-* bits, we can derive a formula for the carry chain.
-*
-* a b cin r cout
-* 0 0 0 0 0
-* 0 0 1 1 0
-* 0 1 0 1 0
-* 0 1 1 0 1
-* 1 0 0 1 0
-* 1 0 1 0 1
-* 1 1 0 0 1
-* 1 1 1 1 1
-*
-* Construction of table for cout:
-*
-* ab
-* r \ 00 01 11 10
-* |------------------
-* 0 | 0 1 1 1
-* 1 | 0 0 1 0
-*
-* By inspection, one gets: cc = ab + r'(a + b)
-*
-* That represents alot of operations, but NO CHOICE....
-*
-* Borrow Chain Calculation.
-*
-* The following table represents the subtraction of two bits, from
-* which we can derive a formula for the borrow chain.
-*
-* a b bin r bout
-* 0 0 0 0 0
-* 0 0 1 1 1
-* 0 1 0 1 1
-* 0 1 1 0 1
-* 1 0 0 1 0
-* 1 0 1 0 0
-* 1 1 0 0 0
-* 1 1 1 1 1
-*
-* Construction of table for cout:
-*
-* ab
-* r \ 00 01 11 10
-* |------------------
-* 0 | 0 1 0 0
-* 1 | 1 1 1 0
-*
-* By inspection, one gets: bc = a'b + r(a' + b)
-*
- */
-
-/*------------------------- Global Variables ------------------------------*/
+ * Carry Chain Calculation
+ *
+ * This represents a somewhat expensive calculation which is
+ * apparently required to emulate the setting of the OF and AF flag.
+ * The latter is not so important, but the former is. The overflow
+ * flag is the XOR of the top two bits of the carry chain for an
+ * addition (similar for subtraction). Since we do not want to
+ * simulate the addition in a bitwise manner, we try to calculate the
+ * carry chain given the two operands and the result.
+ *
+ * So, given the following table, which represents the addition of two
+ * bits, we can derive a formula for the carry chain.
+ *
+ * a b cin r cout
+ * 0 0 0 0 0
+ * 0 0 1 1 0
+ * 0 1 0 1 0
+ * 0 1 1 0 1
+ * 1 0 0 1 0
+ * 1 0 1 0 1
+ * 1 1 0 0 1
+ * 1 1 1 1 1
+ *
+ * Construction of table for cout:
+ *
+ * ab
+ * r \ 00 01 11 10
+ * |------------------
+ * 0 | 0 1 1 1
+ * 1 | 0 0 1 0
+ *
+ * By inspection, one gets: cc = ab + r'(a + b)
+ *
+ * That represents alot of operations, but NO CHOICE....
+ *
+ * Borrow Chain Calculation.
+ *
+ * The following table represents the subtraction of two bits, from
+ * which we can derive a formula for the borrow chain.
+ *
+ * a b bin r bout
+ * 0 0 0 0 0
+ * 0 0 1 1 1
+ * 0 1 0 1 1
+ * 0 1 1 0 1
+ * 1 0 0 1 0
+ * 1 0 1 0 0
+ * 1 1 0 0 0
+ * 1 1 1 1 1
+ *
+ * Construction of table for cout:
+ *
+ * ab
+ * r \ 00 01 11 10
+ * |------------------
+ * 0 | 0 1 0 0
+ * 1 | 1 1 1 0
+ *
+ * By inspection, one gets: bc = a'b + r(a' + b)
+ *
+ */
+
+/*
+ * Global Variables
+ */
static uint32_t x86emu_parity_tab[8] =
{
@@ -6654,33 +6705,38 @@ rcl_byte(struct x86emu *emu, uint8_t d, uint8_t s)
* that's inefficient. So the width is 9, and we split into three
* parts:
*
- * The new carry flag (was B_n) the stuff in B_n-1 .. B_0 the stuff in
- * B_7 .. B_n+1
+ * The new carry flag (was B_n) the stuff in B_n-1 .. B_0 the stuff
+ * in B_7 .. B_n+1
*
- * The new rotate is done mod 9, and given this, for a rotation of n bits
- * (mod 9) the new carry flag is then located n bits from the MSB.
+ * The new rotate is done mod 9, and given this, for a rotation of n
+ * bits (mod 9) the new carry flag is then located n bits from the MSB.
* The low part is then shifted up cnt bits, and the high part is or'd
* in. Using CAPS for new values, and lowercase for the original
* values, this can be expressed as:
*
* IF n > 0 1) CF <- b_(8-n) 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
- * 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
+ * 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
+ */
res = d;
if ((cnt = s % 9) != 0) {
/* extract the new CARRY FLAG. */
/* CF <- b_(8-n) */
cf = (d >> (8 - cnt)) & 0x1;
- /* get the low stuff which rotated into the range B_7 .. B_cnt */
- /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
- /* note that the right hand side done by the mask */
+ /*
+ * Get the low stuff which rotated into the range B_7 .. B_cnt
+ * B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
+ * note that the right hand side done by the mask.
+ */
res = (d << cnt) & 0xff;
- /* now the high stuff which rotated around into the positions
- * B_cnt-2 .. B_0 */
- /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
- /* shift it downward, 7-(n-2) = 9-n positions. and mask off
- * the result before or'ing in. */
+ /*
+ * now the high stuff which rotated around into the positions
+ * B_cnt-2 .. B_0
+ * B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
+ * shift it downward, 7-(n-2) = 9-n positions. and mask off
+ * the result before or'ing in.
+ */
mask = (1 << (cnt - 1)) - 1;
res |= (d >> (9 - cnt)) & mask;
@@ -6770,14 +6826,17 @@ rcr_byte(struct x86emu *emu, uint8_t d, uint8_t s)
*
* CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
*
- * The new rotate is done mod 9, and given this, for a rotation of n bits
- * (mod 9) the new carry flag is then located n bits from the LSB.
+ * The new rotate is done mod 9, and given this, for a rotation of n
+ * bits (mod 9) the new carry flag is then located n bits from the LSB.
* The low part is then shifted up cnt bits, and the high part is or'd
* in. Using CAPS for new values, and lowercase for the original
* values, this can be expressed as:
*
- * IF n > 0 1) CF <- b_(n-1) 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
- * 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
+ * IF n > 0
+ * 1) CF <- b_(n-1)
+ * 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
+ * 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
+ */
res = d;
if ((cnt = s % 9) != 0) {
/* extract the new CARRY FLAG. */
@@ -7193,8 +7252,8 @@ shl_long(struct x86emu *emu, uint32_t d, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000)
+ ^ (ACCESS_FLAG(F_CF) != 0)), F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -7505,8 +7564,8 @@ shld_long(struct x86emu *emu, uint32_t d, uint32_t fill, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000)
+ ^ (ACCESS_FLAG(F_CF) != 0)), F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -8232,7 +8291,8 @@ outs(struct x86emu *emu, int size)
case 1:
while (count--) {
(*emu->emu_outb) (emu, emu->x86.R_DX,
- fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI));
+ fetch_byte(emu, emu->x86.R_ES,
+ emu->x86.R_SI));
emu->x86.R_SI += inc;
}
break;
@@ -8240,14 +8300,16 @@ outs(struct x86emu *emu, int size)
case 2:
while (count--) {
(*emu->emu_outw) (emu, emu->x86.R_DX,
- fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI));
+ fetch_word(emu, emu->x86.R_ES,
+ emu->x86.R_SI));
emu->x86.R_SI += inc;
}
break;
case 4:
while (count--) {
(*emu->emu_outl) (emu, emu->x86.R_DX,
- fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI));
+ fetch_long(emu, emu->x86.R_ES,
+ emu->x86.R_SI));
emu->x86.R_SI += inc;
break;
}
diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c
index 99209a8..04af1eb 100644
--- a/sys/ddb/db_sym.c
+++ b/sys/ddb/db_sym.c
@@ -64,12 +64,6 @@ static boolean_t db_line_at_pc(c_db_sym_t, char **, int *, db_expr_t);
static int db_cpu = -1;
#ifdef VIMAGE
-extern uintptr_t *__start_set_vnet;
-extern uintptr_t *__stop_set_vnet;
-
-#define VNET_START (uintptr_t)&__start_set_vnet
-#define VNET_STOP (uintptr_t)&__stop_set_vnet
-
static void *db_vnet = NULL;
#endif
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 363972d..b928dba 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -1880,7 +1880,7 @@ aac_init(struct aac_softc *sc)
ip->InitFlags = 0;
if (sc->flags & AAC_FLAGS_NEW_COMM) {
- ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED;
+ ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
device_printf(sc->aac_dev, "New comm. interface enabled\n");
}
@@ -2004,7 +2004,7 @@ aac_setup_intr(struct aac_softc *sc)
}
if (sc->flags & AAC_FLAGS_NEW_COMM) {
if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
- INTR_MPSAFE|INTR_TYPE_BIO, NULL,
+ INTR_MPSAFE|INTR_TYPE_BIO, NULL,
aac_new_intr, sc, &sc->aac_intr)) {
device_printf(sc->aac_dev, "can't set up interrupt\n");
return (EINVAL);
@@ -3063,7 +3063,143 @@ out:
static int
aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
{
- return (EINVAL);
+ struct aac_command *cm;
+ struct aac_event *event;
+ struct aac_fib *fib;
+ struct aac_srb *srbcmd, *user_srb;
+ struct aac_sg_entry *sge;
+ struct aac_sg_entry64 *sge64;
+ void *srb_sg_address, *ureply;
+ uint32_t fibsize, srb_sg_bytecount;
+ int error, transfer_data;
+
+ fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+ cm = NULL;
+ transfer_data = 0;
+ fibsize = 0;
+ user_srb = (struct aac_srb *)arg;
+
+ mtx_lock(&sc->aac_io_lock);
+ if (aac_alloc_command(sc, &cm)) {
+ event = malloc(sizeof(struct aac_event), M_AACBUF,
+ M_NOWAIT | M_ZERO);
+ if (event == NULL) {
+ error = EBUSY;
+ mtx_unlock(&sc->aac_io_lock);
+ goto out;
+ }
+ event->ev_type = AAC_EVENT_CMFREE;
+ event->ev_callback = aac_ioctl_event;
+ event->ev_arg = &cm;
+ aac_add_event(sc, event);
+ msleep(cm, &sc->aac_io_lock, 0, "aacraw", 0);
+ }
+ mtx_unlock(&sc->aac_io_lock);
+
+ cm->cm_data = NULL;
+ fib = cm->cm_fib;
+ srbcmd = (struct aac_srb *)fib->data;
+ error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t));
+ if (error != 0)
+ goto out;
+ if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) {
+ error = EINVAL;
+ goto out;
+ }
+ error = copyin(user_srb, srbcmd, fibsize);
+ if (error != 0)
+ goto out;
+ srbcmd->function = 0;
+ srbcmd->retry_limit = 0;
+ if (srbcmd->sg_map.SgCount > 1) {
+ error = EINVAL;
+ goto out;
+ }
+
+ /* Retrieve correct SG entries. */
+ if (fibsize == (sizeof(struct aac_srb) +
+ srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
+ sge = srbcmd->sg_map.SgEntry;
+ sge64 = NULL;
+ srb_sg_bytecount = sge->SgByteCount;
+ srb_sg_address = (void *)(uintptr_t)sge->SgAddress;
+ }
+#ifdef __amd64__
+ else if (fibsize == (sizeof(struct aac_srb) +
+ srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
+ sge = NULL;
+ sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
+ srb_sg_bytecount = sge64->SgByteCount;
+ srb_sg_address = (void *)sge64->SgAddress;
+ if (sge64->SgAddress > 0xffffffffull &&
+ (sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
+ error = EINVAL;
+ goto out;
+ }
+ }
+#endif
+ else {
+ error = EINVAL;
+ goto out;
+ }
+ ureply = (char *)arg + fibsize;
+ srbcmd->data_len = srb_sg_bytecount;
+ if (srbcmd->sg_map.SgCount == 1)
+ transfer_data = 1;
+
+ cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
+ if (transfer_data) {
+ cm->cm_datalen = srb_sg_bytecount;
+ cm->cm_data = malloc(cm->cm_datalen, M_AACBUF, M_NOWAIT);
+ if (cm->cm_data == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)
+ cm->cm_flags |= AAC_CMD_DATAIN;
+ if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
+ cm->cm_flags |= AAC_CMD_DATAOUT;
+ error = copyin(srb_sg_address, cm->cm_data,
+ cm->cm_datalen);
+ if (error != 0)
+ goto out;
+ }
+ }
+
+ fib->Header.Size = sizeof(struct aac_fib_header) +
+ sizeof(struct aac_srb);
+ fib->Header.XferState =
+ AAC_FIBSTATE_HOSTOWNED |
+ AAC_FIBSTATE_INITIALISED |
+ AAC_FIBSTATE_EMPTY |
+ AAC_FIBSTATE_FROMHOST |
+ AAC_FIBSTATE_REXPECTED |
+ AAC_FIBSTATE_NORM |
+ AAC_FIBSTATE_ASYNC |
+ AAC_FIBSTATE_FAST_RESPONSE;
+ fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ?
+ ScsiPortCommandU64 : ScsiPortCommand;
+
+ mtx_lock(&sc->aac_io_lock);
+ aac_wait_command(cm);
+ mtx_unlock(&sc->aac_io_lock);
+
+ if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) {
+ error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen);
+ if (error != 0)
+ goto out;
+ }
+ error = copyout(fib->data, ureply, sizeof(struct aac_srb_response));
+out:
+ if (cm != NULL) {
+ if (cm->cm_data != NULL)
+ free(cm->cm_data, M_AACBUF);
+ mtx_lock(&sc->aac_io_lock);
+ aac_release_command(cm);
+ mtx_unlock(&sc->aac_io_lock);
+ }
+ return(error);
}
/*
diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index c1164aa..4bfe0ed 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -395,7 +395,7 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
srb->cdb_len);
/* Set command */
- fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ?
+ fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ?
ScsiPortCommandU64 : ScsiPortCommand;
/* Map the s/g list. XXX 32bit addresses only! */
@@ -512,7 +512,7 @@ aac_cam_complete(struct aac_command *cm)
scsi_sense_len = sizeof(struct scsi_sense_data);
bzero(&ccb->csio.sense_data, scsi_sense_len);
- sense_len = (srbr->sense_len >
+ sense_len = (srbr->sense_len >
scsi_sense_len) ? scsi_sense_len :
srbr->sense_len;
bcopy(&srbr->sense[0], &ccb->csio.sense_data,
diff --git a/sys/dev/aac/aac_debug.c b/sys/dev/aac/aac_debug.c
index 9d79b0b..9cdfd3f 100644
--- a/sys/dev/aac/aac_debug.c
+++ b/sys/dev/aac/aac_debug.c
@@ -62,62 +62,62 @@ aac_print_queues(struct aac_softc *sc)
device_printf(sc->aac_dev, "FIB queue header at %p queues at %p\n",
&sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
&sc->aac_queues->qt_HostNormCmdQueue[0]);
- device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
- AAC_CONSUMER_INDEX],
+ AAC_CONSUMER_INDEX],
AAC_HOST_NORM_CMD_ENTRIES);
- device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
- AAC_CONSUMER_INDEX],
+ AAC_CONSUMER_INDEX],
AAC_HOST_HIGH_CMD_ENTRIES);
- device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
- AAC_CONSUMER_INDEX],
+ AAC_CONSUMER_INDEX],
AAC_ADAP_NORM_CMD_ENTRIES);
- device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
- AAC_CONSUMER_INDEX],
+ AAC_CONSUMER_INDEX],
AAC_ADAP_HIGH_CMD_ENTRIES);
- device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_HOST_NORM_RESP_ENTRIES);
- device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_HOST_HIGH_RESP_ENTRIES);
- device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_ADAP_NORM_RESP_ENTRIES);
- device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
+ device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_ADAP_HIGH_RESP_ENTRIES);
- device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
+ device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
- device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
+ device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
sc->aac_qstat[AACQ_BIO].q_length, sc->aac_qstat[AACQ_BIO].q_max);
- device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
+ device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
sc->aac_qstat[AACQ_READY].q_length,
sc->aac_qstat[AACQ_READY].q_max);
- device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
+ device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
}
@@ -225,8 +225,8 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
if (br->Command == VM_CtBlockRead) {
device_printf(sc->aac_dev,
- " BlockRead: container %d 0x%x/%d\n",
- br->ContainerId, br->BlockNumber,
+ " BlockRead: container %d 0x%x/%d\n",
+ br->ContainerId, br->BlockNumber,
br->ByteCount);
sg = &br->SgMap;
}
@@ -234,7 +234,7 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
device_printf(sc->aac_dev,
" BlockWrite: container %d 0x%x/%d "
"(%s)\n", bw->ContainerId,
- bw->BlockNumber, bw->ByteCount,
+ bw->BlockNumber, bw->ByteCount,
bw->Stable == CSTABLE ? "stable" :
"unstable");
sg = &bw->SgMap;
@@ -267,7 +267,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
switch(aif->data.EN.type) {
case AifEnGeneric: /* Generic notification */
- device_printf(sc->aac_dev, "(Generic) %.*s\n",
+ device_printf(sc->aac_dev, "(Generic) %.*s\n",
(int)sizeof(aif->data.EN.data.EG),
aif->data.EN.data.EG.text);
break;
@@ -281,21 +281,21 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
case AifEnContainerChange: /* Adapter specific container
* configuration change */
device_printf(sc->aac_dev, "(ContainerChange) "
- "container %d,%d\n",
- aif->data.EN.data.ECC.container[0],
+ "container %d,%d\n",
+ aif->data.EN.data.ECC.container[0],
aif->data.EN.data.ECC.container[1]);
break;
case AifEnDeviceFailure: /* SCSI device failed */
device_printf(sc->aac_dev, "(DeviceFailure) "
- "handle %d\n",
+ "handle %d\n",
aif->data.EN.data.EDF.deviceHandle);
break;
case AifEnMirrorFailover: /* Mirror failover started */
device_printf(sc->aac_dev, "(MirrorFailover) "
"container %d failed, "
"migrating from slice %d to %d\n",
- aif->data.EN.data.EMF.container,
- aif->data.EN.data.EMF.failedSlice,
+ aif->data.EN.data.EMF.container,
+ aif->data.EN.data.EMF.failedSlice,
aif->data.EN.data.EMF.creatingSlice);
break;
case AifEnContainerEvent: /* Significant container
@@ -325,7 +325,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
device_printf(sc->aac_dev, "(EnclosureManagement) "
"EMPID %d unit %d "
"event %d\n", aif->data.EN.data.EEE.empID,
- aif->data.EN.data.EEE.unitID,
+ aif->data.EN.data.EEE.unitID,
aif->data.EN.data.EEE.eventType);
break;
case AifEnBatteryEvent: /* Significant NV battery
@@ -348,14 +348,14 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
break;
case AifEnClusterEvent: /* Some cluster event */
- device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
+ device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
aif->data.EN.data.ECLE.eventType);
break;
case AifEnDiskSetEvent: /* A disk set event occured. */
device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
"diskset %jd creator %jd\n",
- aif->data.EN.data.EDS.eventType,
- (intmax_t)aif->data.EN.data.EDS.DsNum,
+ aif->data.EN.data.EDS.eventType,
+ (intmax_t)aif->data.EN.data.EDS.DsNum,
(intmax_t)aif->data.EN.data.EDS.CreatorId);
break;
case AifDenMorphComplete: /* A morph operation
@@ -392,7 +392,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
}
device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
- aif->seqNumber, status,
+ aif->seqNumber, status,
aif->data.PR[0].currentTick,
aif->data.PR[0].finalTick);
switch(aif->data.PR[0].jd.type) {
@@ -418,12 +418,12 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
break;
case AifJobCtrZero: /* Container clear operation */
device_printf(sc->aac_dev,
- "(ContainerZero) container %d\n",
+ "(ContainerZero) container %d\n",
aif->data.PR[0].jd.client.container.src);
break;
case AifJobCtrCopy: /* Container copy operation */
device_printf(sc->aac_dev,
- "(ContainerCopy) container %d to %d\n",
+ "(ContainerCopy) container %d to %d\n",
aif->data.PR[0].jd.client.container.src,
aif->data.PR[0].jd.client.container.dst);
break;
@@ -456,12 +456,12 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
case AifJobCtrScrubRaid5: /* Container Scrub Raid5
* operation */
device_printf(sc->aac_dev,
- "(ContainerScrubRaid5) container %d\n",
+ "(ContainerScrubRaid5) container %d\n",
aif->data.PR[0].jd.client.container.src);
break;
case AifJobCtrMorph: /* Container morph operation */
device_printf(sc->aac_dev,
- "(ContainerMorph) container %d\n",
+ "(ContainerMorph) container %d\n",
aif->data.PR[0].jd.client.container.src);
/* XXX two containers? */
break;
@@ -476,13 +476,13 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
case AifJobCtrRebuildMirror: /* Container Rebuild Mirror
* operation */
device_printf(sc->aac_dev,
- "(ContainerRebuildMirror) container "
+ "(ContainerRebuildMirror) container "
"%d\n",
aif->data.PR[0].jd.client.container.src);
break;
case AifJobCtrCrazyCache: /* crazy cache */
device_printf(sc->aac_dev,
- "(ContainerCrazyCache) container %d\n",
+ "(ContainerCrazyCache) container %d\n",
aif->data.PR[0].jd.client.container.src);
/* XXX two containers? */
break;
diff --git a/sys/dev/aac/aac_disk.c b/sys/dev/aac/aac_disk.c
index 4a1a82b..fa3b66b 100644
--- a/sys/dev/aac/aac_disk.c
+++ b/sys/dev/aac/aac_disk.c
@@ -87,7 +87,7 @@ DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
/*
* Handle open from generic layer.
*
- * This is called by the diskslice code on first open in order to get the
+ * This is called by the diskslice code on first open in order to get the
* basic device geometry paramters.
*/
static int
diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c
index bc99379..6f59e68 100644
--- a/sys/dev/aac/aac_pci.c
+++ b/sys/dev/aac/aac_pci.c
@@ -177,7 +177,7 @@ struct aac_ident
{0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
"IBM ServeRAID 8i"},
{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
- "Adaptec SAS RAID 4000SAS"},
+ "Adaptec RAID 4000"},
{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
"Adaptec SAS RAID 4800SAS"},
{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
@@ -353,7 +353,7 @@ aac_pci_attach(device_t dev)
/* assume failure is 'not configured' */
error = ENXIO;
- /*
+ /*
* Verify that the adapter is correctly set up in PCI space.
*/
command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
@@ -401,7 +401,7 @@ aac_pci_attach(device_t dev)
/*
* Allocate the parent bus DMA tag appropriate for our PCI interface.
- *
+ *
* Note that some of these controllers are 64-bit capable.
*/
if (bus_dma_tag_create(NULL, /* parent */
@@ -419,7 +419,7 @@ aac_pci_attach(device_t dev)
goto out;
}
- /*
+ /*
* Detect the hardware interface version, set up the bus interface
* indirection.
*/
diff --git a/sys/dev/aac/aac_tables.h b/sys/dev/aac/aac_tables.h
index 4a0d0e3..fe687fb 100644
--- a/sys/dev/aac/aac_tables.h
+++ b/sys/dev/aac/aac_tables.h
@@ -34,40 +34,42 @@
* relevant only to FSA operations.
*/
static struct aac_code_lookup aac_command_status_table[] = {
- {"OK", 0},
- {"operation not permitted", 1},
- {"not found", 2},
- {"I/O error", 5},
- {"device not configured", 6},
- {"too big", 7},
- {"permission denied", 13},
- {"file exists", 17},
- {"cross-device link", 18},
- {"operation not supported by device", 19},
- {"not a directory", 20},
- {"is a directory", 21},
- {"invalid argument", 22},
- {"file too large", 27},
- {"no space on device", 28},
- {"readonly filesystem", 30},
- {"too many links", 31},
- {"operation would block", 35},
- {"file name too long", 63},
- {"directory not empty", 66},
- {"quota exceeded", 69},
- {"stale file handle", 70},
- {"too many levels of remote in path", 71},
- {"bad file handle", 10001},
- {"not sync", 10002},
- {"bad cookie", 10003},
- {"operation not supported", 10004},
- {"too small", 10005},
- {"server fault", 10006},
- {"bad type", 10007},
- {"jukebox", 10008},
- {"not mounted", 10009},
- {"in maintenance mode", 10010},
- {"stale ACL", 10011},
+ {"OK", ST_OK},
+ {"operation not permitted", ST_PERM},
+ {"not found", ST_NOENT},
+ {"I/O error", ST_IO},
+ {"device not configured", ST_NXIO},
+ {"too big", ST_E2BIG},
+ {"permission denied", ST_ACCES},
+ {"file exists", ST_EXIST},
+ {"cross-device link", ST_XDEV},
+ {"operation not supported by device", ST_NODEV},
+ {"not a directory", ST_NOTDIR},
+ {"is a directory", ST_ISDIR},
+ {"invalid argument", ST_INVAL},
+ {"file too large", ST_FBIG},
+ {"no space on device", ST_NOSPC},
+ {"readonly filesystem", ST_ROFS},
+ {"too many links", ST_MLINK},
+ {"operation would block", ST_WOULDBLOCK},
+ {"file name too long", ST_NAMETOOLONG},
+ {"directory not empty", ST_NOTEMPTY},
+ {"quota exceeded", ST_DQUOT},
+ {"stale file handle", ST_STALE},
+ {"too many levels of remote in path", ST_REMOTE},
+ {"device busy (spinning up)", ST_NOT_READY},
+ {"bad file handle", ST_BADHANDLE},
+ {"not sync", ST_NOT_SYNC},
+ {"bad cookie", ST_BAD_COOKIE},
+ {"operation not supported", ST_NOTSUPP},
+ {"too small", ST_TOOSMALL},
+ {"server fault", ST_SERVERFAULT},
+ {"bad type", ST_BADTYPE},
+ {"jukebox", ST_JUKEBOX},
+ {"not mounted", ST_NOTMOUNTED},
+ {"in maintenance mode", ST_MAINTMODE},
+ {"stale ACL", ST_STALEACL},
+ {"bus reset - command aborted", ST_BUS_RESET},
{NULL, 0},
{"unknown command status", 0}
};
diff --git a/sys/dev/aac/aacreg.h b/sys/dev/aac/aacreg.h
index 5c84966..ccec8b2 100644
--- a/sys/dev/aac/aacreg.h
+++ b/sys/dev/aac/aacreg.h
@@ -220,20 +220,20 @@ typedef enum {
IsAdapterPaused = 704,
SendHostTime = 705,
RequestSupplementAdapterInfo = 706, /* Supp. Info for set in UCC
- * use only if supported
+ * use only if supported
* (RequestAdapterInfo first) */
LastMiscCommand = 707,
-
- OnLineDiagnostic = 800,
- FduAdapterTest = 801,
+
+ OnLineDiagnostic = 800,
+ FduAdapterTest = 801,
RequestCompatibilityId = 802,
AdapterEnvironmentInfo = 803, /* temp. sensors */
NvsramEventLog = 900,
ResetNvsramEventLogPointers = 901,
EnableEventLog = 902,
DisableEventLog = 903,
- EncryptedKeyTransportFIB= 904,
- KeyableFeaturesFIB= 905
+ EncryptedKeyTransportFIB= 904,
+ KeyableFeaturesFIB= 905
} AAC_FibCommands;
/*
@@ -283,7 +283,7 @@ typedef enum {
#define AAC_ERROR_FIB_DEALLOCATION_FAILED 0x08
/*
- * Adapter Init Structure: this is passed to the adapter with the
+ * Adapter Init Structure: this is passed to the adapter with the
* AAC_MONKER_INITSTRUCT command to point it at our control structures.
*/
struct aac_adapter_init {
@@ -306,7 +306,7 @@ struct aac_adapter_init {
u_int32_t HostElapsedSeconds;
/* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
u_int32_t InitFlags; /* flags for supported features */
-#define INITFLAGS_NEW_COMM_SUPPORTED 1
+#define AAC_INITFLAGS_NEW_COMM_SUPPORTED 1
u_int32_t MaxIoCommands; /* max outstanding commands */
u_int32_t MaxIoSize; /* largest I/O command */
u_int32_t MaxFibSize; /* largest FIB to adapter */
@@ -329,14 +329,14 @@ typedef enum {
CT_MORPH,
CT_PASSTHRU,
CT_RAID4,
- CT_RAID10, /* stripe of mirror */
- CT_RAID00, /* stripe of stripe */
- CT_VOLUME_OF_MIRRORS, /* volume of mirror */
- CT_PSEUDO_RAID3, /* really raid4 */
- CT_RAID50, /* stripe of raid5 */
- CT_RAID5D, /* raid5 distributed hot-sparing */
+ CT_RAID10, /* stripe of mirror */
+ CT_RAID00, /* stripe of stripe */
+ CT_VOLUME_OF_MIRRORS, /* volume of mirror */
+ CT_PSEUDO_RAID3, /* really raid4 */
+ CT_RAID50, /* stripe of raid5 */
+ CT_RAID5D, /* raid5 distributed hot-sparing */
CT_RAID5D0,
- CT_RAID1E, /* extended raid1 mirroring */
+ CT_RAID1E, /* extended raid1 mirroring */
CT_RAID6,
CT_RAID60,
} AAC_FSAVolType;
@@ -345,23 +345,23 @@ typedef enum {
* Host-addressable object types
*/
typedef enum {
- FT_REG = 1, /* regular file */
- FT_DIR, /* directory */
- FT_BLK, /* "block" device - reserved */
- FT_CHR, /* "character special" device - reserved */
- FT_LNK, /* symbolic link */
- FT_SOCK, /* socket */
- FT_FIFO, /* fifo */
- FT_FILESYS, /* ADAPTEC's "FSA"(tm) filesystem */
- FT_DRIVE, /* physical disk - addressable in scsi by b/t/l */
- FT_SLICE, /* virtual disk - raw volume - slice */
- FT_PARTITION, /* FSA partition - carved out of a slice - building
+ FT_REG = 1, /* regular file */
+ FT_DIR, /* directory */
+ FT_BLK, /* "block" device - reserved */
+ FT_CHR, /* "character special" device - reserved */
+ FT_LNK, /* symbolic link */
+ FT_SOCK, /* socket */
+ FT_FIFO, /* fifo */
+ FT_FILESYS, /* ADAPTEC's "FSA"(tm) filesystem */
+ FT_DRIVE, /* physical disk - addressable in scsi by b/t/l */
+ FT_SLICE, /* virtual disk - raw volume - slice */
+ FT_PARTITION, /* FSA partition - carved out of a slice - building
* block for containers */
- FT_VOLUME, /* Container - Volume Set */
- FT_STRIPE, /* Container - Stripe Set */
- FT_MIRROR, /* Container - Mirror Set */
- FT_RAID5, /* Container - Raid 5 Set */
- FT_DATABASE /* Storage object with "foreign" content manager */
+ FT_VOLUME, /* Container - Volume Set */
+ FT_STRIPE, /* Container - Stripe Set */
+ FT_MIRROR, /* Container - Mirror Set */
+ FT_RAID5, /* Container - Raid 5 Set */
+ FT_DATABASE /* Storage object with "foreign" content manager */
} AAC_FType;
/*
@@ -467,7 +467,7 @@ typedef enum {
CPU_MIPS,
CPU_XSCALE,
CPU__last
-} AAC_CpuType;
+} AAC_CpuType;
typedef enum {
CPUI960_JX = 1,
@@ -544,7 +544,7 @@ typedef enum {
* XXX the aac-2622 with no battery present reports PLATFORM_BAT_OPT_PRESENT
*/
typedef enum
-{
+{
PLATFORM_BAT_REQ_PRESENT = 1, /* BATTERY REQUIRED AND PRESENT */
PLATFORM_BAT_REQ_NOTPRESENT, /* BATTERY REQUIRED AND NOT PRESENT */
PLATFORM_BAT_OPT_PRESENT, /* BATTERY OPTIONAL AND PRESENT */
@@ -552,9 +552,9 @@ typedef enum
PLATFORM_BAT_NOT_SUPPORTED /* BATTERY NOT SUPPORTED */
} AAC_BatteryPlatform;
-/*
+/*
* options supported by this board
- * there has to be a one to one mapping of these defines and the ones in
+ * there has to be a one to one mapping of these defines and the ones in
* fsaapi.h, search for FSA_SUPPORT_SNAPSHOT
*/
#define AAC_SUPPORTED_SNAPSHOT 0x01
@@ -577,24 +577,24 @@ typedef enum
#define AAC_SUPPORTED_64BIT_ARRAYSIZE 0x40000
#define AAC_SUPPORTED_HEAT_SENSOR 0x80000
-/*
+/*
* Structure used to respond to a RequestAdapterInfo fib.
*/
struct aac_adapter_info {
- AAC_Platform PlatformBase; /* adapter type */
+ AAC_Platform PlatformBase; /* adapter type */
AAC_CpuType CpuArchitecture; /* adapter CPU type */
- AAC_CpuSubType CpuVariant; /* adapter CPU subtype */
- u_int32_t ClockSpeed; /* adapter CPU clockspeed */
- u_int32_t ExecutionMem; /* adapter Execution Memory
+ AAC_CpuSubType CpuVariant; /* adapter CPU subtype */
+ u_int32_t ClockSpeed; /* adapter CPU clockspeed */
+ u_int32_t ExecutionMem; /* adapter Execution Memory
* size */
- u_int32_t BufferMem; /* adapter Data Memory */
- u_int32_t TotalMem; /* adapter Total Memory */
+ u_int32_t BufferMem; /* adapter Data Memory */
+ u_int32_t TotalMem; /* adapter Total Memory */
struct FsaRevision KernelRevision; /* adapter Kernel Software
* Revision */
struct FsaRevision MonitorRevision; /* adapter Monitor/Diagnostic
* Software Revision */
struct FsaRevision HardwareRevision;/* TBD */
- struct FsaRevision BIOSRevision; /* adapter BIOS Revision */
+ struct FsaRevision BIOSRevision; /* adapter BIOS Revision */
u_int32_t ClusteringEnabled;
u_int32_t ClusterChannelMask;
u_int64_t SerialNumber;
@@ -604,7 +604,7 @@ struct aac_adapter_info {
AAC_OemFlavor OemVariant;
} __packed;
-/*
+/*
* Structure used to respond to a RequestSupplementAdapterInfo fib.
*/
struct vpd_info {
@@ -692,7 +692,7 @@ struct aac_supplement_adapter_info {
#define AAC_KERNEL_PANIC 0x00000100
/*
- * Data types relating to control and monitoring of the NVRAM/WriteCache
+ * Data types relating to control and monitoring of the NVRAM/WriteCache
* subsystem.
*/
@@ -867,7 +867,7 @@ typedef enum {
AifEnGeneric = 1, /* Generic notification */
AifEnTaskComplete, /* Task has completed */
AifEnConfigChange, /* Adapter config change occurred */
- AifEnContainerChange, /* Adapter specific container
+ AifEnContainerChange, /* Adapter specific container
* configuration change */
AifEnDeviceFailure, /* SCSI device failed */
AifEnMirrorFailover, /* Mirror failover started */
@@ -881,7 +881,7 @@ typedef enum {
AifEnBatteryEvent, /* Significant NV battery event */
AifEnAddContainer, /* A new container was created. */
AifEnDeleteContainer, /* A container was deleted. */
- AifEnSMARTEvent, /* SMART Event */
+ AifEnSMARTEvent, /* SMART Event */
AifEnBatteryNeedsRecond, /* The battery needs reconditioning */
AifEnClusterEvent, /* Some cluster event */
AifEnDiskSetEvent, /* A disk set event occured. */
@@ -967,7 +967,7 @@ struct aac_AifEventNotify {
/*
* Adapter Initiated FIB command structures. Start with the adapter
* initiated FIBs that really come from the adapter, and get responded
- * to by the host.
+ * to by the host.
*/
#define AAC_AIF_REPORT_MAX_SIZE 64
@@ -1081,6 +1081,7 @@ typedef enum {
ST_DQUOT = 69,
ST_STALE = 70,
ST_REMOTE = 71,
+ ST_NOT_READY = 72,
ST_BADHANDLE = 10001,
ST_NOT_SYNC = 10002,
ST_BAD_COOKIE = 10003,
@@ -1091,7 +1092,8 @@ typedef enum {
ST_JUKEBOX = 10008,
ST_NOTMOUNTED = 10009,
ST_MAINTMODE = 10010,
- ST_STALEACL = 10011
+ ST_STALEACL = 10011,
+ ST_BUS_RESET = 20001
} AAC_FSAStatus;
/*
@@ -1120,7 +1122,7 @@ typedef enum _VM_COMMANDS {
VM_CtHostRead64,
VM_CtHostWrite64,
VM_DrvErrTblLog, /* drive error table/log type of command */
- VM_NameServe64
+ VM_NameServe64
} AAC_VMCommand;
/*
@@ -1526,7 +1528,7 @@ enum {
/*
* The adapter can request the host print a message by setting the
* DB_PRINTF flag in DOORBELL0. The driver responds by collecting the
- * message from the printf buffer, clearing the DB_PRINTF flag in
+ * message from the printf buffer, clearing the DB_PRINTF flag in
* DOORBELL0 and setting it in DOORBELL1.
* (ODBR and IDBR respectively for the i960Rx adapters)
*/
diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
index 3ecb262..29eb816 100644
--- a/sys/dev/aac/aacvar.h
+++ b/sys/dev/aac/aacvar.h
@@ -56,7 +56,7 @@
*/
/*
- * The firmware interface allows for a 16-bit s/g list length. We limit
+ * The firmware interface allows for a 16-bit s/g list length. We limit
* ourselves to a reasonable maximum and ensure alignment.
*/
#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */
@@ -78,7 +78,7 @@
#define AAC_PRINTF_BUFSIZE 256
/*
- * We wait this many seconds for the adapter to come ready if it is still
+ * We wait this many seconds for the adapter to come ready if it is still
* booting
*/
#define AAC_BOOT_TIMEOUT (3 * 60)
@@ -126,7 +126,7 @@ struct aac_sim
/*
* Per-disk structure
*/
-struct aac_disk
+struct aac_disk
{
device_t ad_dev;
struct aac_softc *ad_controller;
@@ -216,7 +216,7 @@ struct aac_common {
AAC_QUEUE_ALIGN];
/* buffer for text messages from the controller */
- char ac_printf[AAC_PRINTF_BUFSIZE];
+ char ac_printf[AAC_PRINTF_BUFSIZE];
/* fib for synchronous commands */
struct aac_fib ac_sync_fib;
@@ -225,7 +225,7 @@ struct aac_common {
/*
* Interface operations
*/
-struct aac_interface
+struct aac_interface
{
int (*aif_get_fwstatus)(struct aac_softc *sc);
void (*aif_qnotify)(struct aac_softc *sc, int qbit);
@@ -300,7 +300,7 @@ struct aac_fib_context {
/*
* Per-controller structure.
*/
-struct aac_softc
+struct aac_softc
{
/* bus connections */
device_t aac_dev;
@@ -347,7 +347,7 @@ struct aac_softc
struct aac_command *aac_commands;
/* command management */
- TAILQ_HEAD(,aac_command) aac_free; /* command structures
+ TAILQ_HEAD(,aac_command) aac_free; /* command structures
* available for reuse */
TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for
* controller resources */
@@ -416,7 +416,7 @@ struct aac_softc
struct callout aac_daemontime; /* clock daemon callout */
- u_int32_t aac_max_fibs; /* max. FIB count */
+ u_int32_t aac_max_fibs; /* max. FIB count */
u_int32_t aac_max_fibs_alloc; /* max. alloc. per alloc_commands() */
u_int32_t aac_max_fib_size; /* max. FIB size */
u_int32_t aac_sg_tablesize; /* max. sg count from host */
@@ -447,7 +447,7 @@ extern void aac_free(struct aac_softc *sc);
extern int aac_attach(struct aac_softc *sc);
extern int aac_detach(device_t dev);
extern int aac_shutdown(device_t dev);
-extern int aac_suspend(device_t dev);
+extern int aac_suspend(device_t dev);
extern int aac_resume(device_t dev);
extern void aac_new_intr(void *arg);
extern int aac_filter(void *arg);
@@ -561,7 +561,7 @@ aac_dequeue_ ## name (struct aac_softc *sc) \
if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \
if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
printf("command %p not in queue, flags = %#x, " \
- "bit = %#x\n", cm, cm->cm_flags, \
+ "bit = %#x\n", cm, cm->cm_flags, \
AAC_ON_ ## index); \
panic("command not in queue"); \
} \
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 69f0739..64a3318 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -162,6 +162,7 @@ static int acpi_sname2sstate(const char *sname);
static const char *acpi_sstate2sname(int sstate);
static int acpi_supported_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
+static int acpi_debug_objects_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_pm_func(u_long cmd, void *arg, ...);
static int acpi_child_location_str_method(device_t acdev, device_t child,
char *buf, size_t buflen);
@@ -253,6 +254,19 @@ SYSCTL_STRING(_debug_acpi, OID_AUTO, acpi_ca_version, CTLFLAG_RD,
static int acpi_serialize_methods;
TUNABLE_INT("hw.acpi.serialize_methods", &acpi_serialize_methods);
+/* Allow users to dump Debug objects without ACPI debugger. */
+static int acpi_debug_objects;
+TUNABLE_INT("debug.acpi.enable_debug_objects", &acpi_debug_objects);
+SYSCTL_PROC(_debug_acpi, OID_AUTO, enable_debug_objects,
+ CTLFLAG_RW | CTLTYPE_INT, NULL, 0, acpi_debug_objects_sysctl, "I",
+ "Enable Debug objects");
+
+/* Allow the interpreter to ignore common mistakes in BIOS. */
+static int acpi_interpreter_slack = 1;
+TUNABLE_INT("debug.acpi.interpreter_slack", &acpi_interpreter_slack);
+SYSCTL_INT(_debug_acpi, OID_AUTO, interpreter_slack, CTLFLAG_RDTUN,
+ &acpi_interpreter_slack, 1, "Turn on interpreter slack mode.");
+
/* Power devices off and on in suspend and resume. XXX Remove once tested. */
static int acpi_do_powerstate = 1;
TUNABLE_INT("debug.acpi.do_powerstate", &acpi_do_powerstate);
@@ -452,8 +466,17 @@ acpi_attach(device_t dev)
* Set the globals from our tunables. This is needed because ACPI-CA
* uses UINT8 for some values and we have no tunable_byte.
*/
- AcpiGbl_AllMethodsSerialized = acpi_serialize_methods;
- AcpiGbl_EnableInterpreterSlack = TRUE;
+ AcpiGbl_AllMethodsSerialized = acpi_serialize_methods ? TRUE : FALSE;
+ AcpiGbl_EnableInterpreterSlack = acpi_interpreter_slack ? TRUE : FALSE;
+ AcpiGbl_EnableAmlDebugObject = acpi_debug_objects ? TRUE : FALSE;
+
+#ifndef ACPI_DEBUG
+ /*
+ * Disable all debugging layers and levels.
+ */
+ AcpiDbgLayer = 0;
+ AcpiDbgLevel = 0;
+#endif
/* Start up the ACPI CA subsystem. */
status = AcpiInitializeSubsystem();
@@ -2617,25 +2640,6 @@ acpi_resync_clock(struct acpi_softc *sc)
inittodr(time_second + sc->acpi_sleep_delay);
}
-/* Initialize a device's wake GPE. */
-int
-acpi_wake_init(device_t dev, int type)
-{
- struct acpi_prw_data prw;
-
- /* Evaluate _PRW to find the GPE. */
- if (acpi_parse_prw(acpi_get_handle(dev), &prw) != 0)
- return (ENXIO);
-
- /* Set the requested type for the GPE (runtime, wake, or both). */
- if (ACPI_FAILURE(AcpiSetGpeType(prw.gpe_handle, prw.gpe_bit, type))) {
- device_printf(dev, "set GPE type failed\n");
- return (ENXIO);
- }
-
- return (0);
-}
-
/* Enable or disable the device's wake GPE. */
int
acpi_wake_set_enable(device_t dev, int enable)
@@ -2650,14 +2654,16 @@ acpi_wake_set_enable(device_t dev, int enable)
flags = acpi_get_flags(dev);
if (enable) {
- status = AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
+ status = AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit,
+ ACPI_GPE_TYPE_WAKE_RUN);
if (ACPI_FAILURE(status)) {
device_printf(dev, "enable wake failed\n");
return (ENXIO);
}
acpi_set_flags(dev, flags | ACPI_FLAG_WAKE_ENABLED);
} else {
- status = AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
+ status = AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit,
+ ACPI_GPE_TYPE_WAKE);
if (ACPI_FAILURE(status)) {
device_printf(dev, "disable wake failed\n");
return (ENXIO);
@@ -2687,7 +2693,7 @@ acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate)
* and set _PSW.
*/
if (sstate > prw.lowest_wake) {
- AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
+ AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_GPE_TYPE_WAKE);
if (bootverbose)
device_printf(dev, "wake_prep disabled wake for %s (S%d)\n",
acpi_name(handle), sstate);
@@ -2724,7 +2730,7 @@ acpi_wake_run_prep(ACPI_HANDLE handle, int sstate)
* clear _PSW and turn off any power resources it used.
*/
if (sstate > prw.lowest_wake) {
- AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
+ AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_GPE_TYPE_WAKE_RUN);
if (bootverbose)
device_printf(dev, "run_prep re-enabled %s\n", acpi_name(handle));
} else {
@@ -3523,6 +3529,26 @@ SYSCTL_PROC(_debug_acpi, OID_AUTO, level, CTLFLAG_RW | CTLTYPE_STRING,
#endif /* ACPI_DEBUG */
static int
+acpi_debug_objects_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ int old;
+
+ old = acpi_debug_objects;
+ error = sysctl_handle_int(oidp, &acpi_debug_objects, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (old == acpi_debug_objects || (old && acpi_debug_objects))
+ return (0);
+
+ ACPI_SERIAL_BEGIN(acpi);
+ AcpiGbl_EnableAmlDebugObject = acpi_debug_objects ? TRUE : FALSE;
+ ACPI_SERIAL_END(acpi);
+
+ return (0);
+}
+
+static int
acpi_pm_func(u_long cmd, void *arg, ...)
{
int state, acpi_state;
diff --git a/sys/dev/acpica/acpi_button.c b/sys/dev/acpica/acpi_button.c
index 7814c0e..56a1d95 100644
--- a/sys/dev/acpica/acpi_button.c
+++ b/sys/dev/acpica/acpi_button.c
@@ -164,7 +164,6 @@ acpi_button_attach(device_t dev)
}
/* Enable the GPE for wake/runtime. */
- acpi_wake_init(dev, ACPI_GPE_TYPE_WAKE_RUN);
acpi_wake_set_enable(dev, 1);
return_VALUE (0);
diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c
index d4ef019..000658c 100644
--- a/sys/dev/acpica/acpi_ec.c
+++ b/sys/dev/acpica/acpi_ec.c
@@ -518,14 +518,8 @@ acpi_ec_attach(device_t dev)
}
/* Enable runtime GPEs for the handler. */
- Status = AcpiSetGpeType(sc->ec_gpehandle, sc->ec_gpebit,
- ACPI_GPE_TYPE_RUNTIME);
- if (ACPI_FAILURE(Status)) {
- device_printf(dev, "AcpiSetGpeType failed: %s\n",
- AcpiFormatException(Status));
- goto error;
- }
- Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
+ Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit,
+ ACPI_GPE_TYPE_RUNTIME);
if (ACPI_FAILURE(Status)) {
device_printf(dev, "AcpiEnableGpe failed: %s\n",
AcpiFormatException(Status));
@@ -575,7 +569,7 @@ acpi_ec_shutdown(device_t dev)
/* Disable the GPE so we don't get EC events during shutdown. */
sc = device_get_softc(dev);
- AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
+ AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_GPE_TYPE_RUNTIME);
return (0);
}
diff --git a/sys/dev/acpica/acpi_lid.c b/sys/dev/acpica/acpi_lid.c
index 47d5b45..ae29aca 100644
--- a/sys/dev/acpica/acpi_lid.c
+++ b/sys/dev/acpica/acpi_lid.c
@@ -115,7 +115,6 @@ acpi_lid_attach(device_t dev)
acpi_lid_notify_handler, sc);
/* Enable the GPE for wake/runtime. */
- acpi_wake_init(dev, ACPI_GPE_TYPE_WAKE_RUN);
acpi_wake_set_enable(dev, 1);
return (0);
diff --git a/sys/dev/acpica/acpi_video.c b/sys/dev/acpica/acpi_video.c
index 94ef7be..a8625de 100644
--- a/sys/dev/acpica/acpi_video.c
+++ b/sys/dev/acpica/acpi_video.c
@@ -584,8 +584,8 @@ acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
}
if (vo->vo_levels != NULL)
- AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
- acpi_video_vo_notify_handler, vo);
+ AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
+ acpi_video_vo_notify_handler, vo);
ACPI_SERIAL_END(video_output);
}
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index f30ee64..002c11c 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -332,7 +332,6 @@ int acpi_ReqSleepState(struct acpi_softc *sc, int state);
int acpi_AckSleepState(struct apm_clone_data *clone, int error);
ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state);
void acpi_resync_clock(struct acpi_softc *sc);
-int acpi_wake_init(device_t dev, int type);
int acpi_wake_set_enable(device_t dev, int enable);
int acpi_parse_prw(ACPI_HANDLE h, struct acpi_prw_data *prw);
ACPI_STATUS acpi_Startup(void);
diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c
index 3c5a107..15ce0ef 100644
--- a/sys/dev/age/if_age.c
+++ b/sys/dev/age/if_age.c
@@ -1629,22 +1629,8 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
}
m = *m_head;
- /* Configure Tx IP/TCP/UDP checksum offload. */
- if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
- cflags |= AGE_TD_CSUM;
- if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
- cflags |= AGE_TD_TCPCSUM;
- if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
- cflags |= AGE_TD_UDPCSUM;
- /* Set checksum start offset. */
- cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
- /* Set checksum insertion position of TCP/UDP. */
- cflags |= ((poff + m->m_pkthdr.csum_data) <<
- AGE_TD_CSUM_XSUMOFFSET_SHIFT);
- }
-
- /* Configure TSO. */
if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+ /* Configure TSO. */
if (poff + (tcp->th_off << 2) == m->m_pkthdr.len) {
/* Not TSO but IP/TCP checksum offload. */
cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
@@ -1660,6 +1646,18 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
/* Set IP/TCP header size. */
cflags |= ip->ip_hl << AGE_TD_IPHDR_LEN_SHIFT;
cflags |= tcp->th_off << AGE_TD_TSO_TCPHDR_LEN_SHIFT;
+ } else if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
+ /* Configure Tx IP/TCP/UDP checksum offload. */
+ cflags |= AGE_TD_CSUM;
+ if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+ cflags |= AGE_TD_TCPCSUM;
+ if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+ cflags |= AGE_TD_UDPCSUM;
+ /* Set checksum start offset. */
+ cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
+ /* Set checksum insertion position of TCP/UDP. */
+ cflags |= ((poff + m->m_pkthdr.csum_data) <<
+ AGE_TD_CSUM_XSUMOFFSET_SHIFT);
}
/* Configure VLAN hardware tag insertion. */
diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c
index be51bb2..95a9cc4 100644
--- a/sys/dev/agp/agp_i810.c
+++ b/sys/dev/agp/agp_i810.c
@@ -70,6 +70,7 @@ enum {
CHIP_I915, /* 915G/915GM */
CHIP_I965, /* G965 */
CHIP_G33, /* G33/Q33/Q35 */
+ CHIP_IGD, /* Pineview */
CHIP_G4X, /* G45/Q45 */
};
@@ -163,6 +164,10 @@ static const struct agp_i810_match {
"Intel G33 SVGA controller"},
{0x29D28086, CHIP_G33, 0x00020000,
"Intel Q33 SVGA controller"},
+ {0xA0018086, CHIP_IGD, 0x00010000,
+ "Intel Pineview SVGA controller"},
+ {0xA0118086, CHIP_IGD, 0x00010000,
+ "Intel Pineview (M) SVGA controller"},
{0x2A028086, CHIP_I965, 0x00020000,
"Intel GM965 SVGA controller"},
{0x2A128086, CHIP_I965, 0x00020000,
@@ -170,13 +175,17 @@ static const struct agp_i810_match {
{0x2A428086, CHIP_G4X, 0x00020000,
"Intel GM45 SVGA controller"},
{0x2E028086, CHIP_G4X, 0x00020000,
- "Intel 4 Series SVGA controller"},
+ "Intel Eaglelake SVGA controller"},
{0x2E128086, CHIP_G4X, 0x00020000,
"Intel Q45 SVGA controller"},
{0x2E228086, CHIP_G4X, 0x00020000,
"Intel G45 SVGA controller"},
{0x2E328086, CHIP_G4X, 0x00020000,
"Intel G41 SVGA controller"},
+ {0x00428086, CHIP_G4X, 0x00020000,
+ "Intel Ironlake (D) SVGA controller"},
+ {0x00468086, CHIP_G4X, 0x00020000,
+ "Intel Ironlake (M) SVGA controller"},
{0, 0, 0, NULL}
};
@@ -286,6 +295,7 @@ agp_i810_probe(device_t dev)
case CHIP_I915:
case CHIP_I965:
case CHIP_G33:
+ case CHIP_IGD:
case CHIP_G4X:
deven = pci_read_config(bdev, AGP_I915_DEVEN, 4);
if ((deven & AGP_I915_DEVEN_D2F0) ==
@@ -351,6 +361,7 @@ agp_i810_dump_regs(device_t dev)
case CHIP_I915:
case CHIP_I965:
case CHIP_G33:
+ case CHIP_IGD:
case CHIP_G4X:
device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
@@ -386,6 +397,7 @@ agp_i810_attach(device_t dev)
break;
case CHIP_I915:
case CHIP_G33:
+ case CHIP_IGD:
sc->sc_res_spec = agp_i915_res_spec;
agp_set_aperture_resource(dev, AGP_I915_GMADR);
break;
@@ -401,7 +413,8 @@ agp_i810_attach(device_t dev)
return error;
if (sc->chiptype != CHIP_I965 && sc->chiptype != CHIP_G33 &&
- sc->chiptype != CHIP_G4X && ptoa((vm_paddr_t)Maxmem) > 0xfffffffful)
+ sc->chiptype != CHIP_IGD && sc->chiptype != CHIP_G4X &&
+ ptoa((vm_paddr_t)Maxmem) > 0xfffffffful)
{
device_printf(dev, "agp_i810.c does not support physical "
"memory above 4GB.\n");
@@ -485,7 +498,7 @@ agp_i810_attach(device_t dev)
gatt->ag_physical = pgtblctl & ~1;
} else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915 ||
sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 ||
- sc->chiptype == CHIP_G4X) {
+ sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) {
unsigned int gcc1, pgtblctl, stolen, gtt_size;
/* Stolen memory is set up at the beginning of the aperture by
@@ -547,6 +560,7 @@ agp_i810_attach(device_t dev)
return EINVAL;
}
break;
+ case CHIP_IGD:
case CHIP_G4X:
gtt_size = 0;
break;
@@ -581,6 +595,7 @@ agp_i810_attach(device_t dev)
if (sc->chiptype == CHIP_I915 ||
sc->chiptype == CHIP_I965 ||
sc->chiptype == CHIP_G33 ||
+ sc->chiptype == CHIP_IGD ||
sc->chiptype == CHIP_G4X) {
stolen = 48 * 1024;
} else {
@@ -591,6 +606,7 @@ agp_i810_attach(device_t dev)
if (sc->chiptype == CHIP_I915 ||
sc->chiptype == CHIP_I965 ||
sc->chiptype == CHIP_G33 ||
+ sc->chiptype == CHIP_IGD ||
sc->chiptype == CHIP_G4X) {
stolen = 64 * 1024;
} else {
@@ -600,6 +616,7 @@ agp_i810_attach(device_t dev)
case AGP_G33_GCC1_GMS_STOLEN_128M:
if (sc->chiptype == CHIP_I965 ||
sc->chiptype == CHIP_G33 ||
+ sc->chiptype == CHIP_IGD ||
sc->chiptype == CHIP_G4X) {
stolen = 128 * 1024;
} else {
@@ -609,6 +626,7 @@ agp_i810_attach(device_t dev)
case AGP_G33_GCC1_GMS_STOLEN_256M:
if (sc->chiptype == CHIP_I965 ||
sc->chiptype == CHIP_G33 ||
+ sc->chiptype == CHIP_IGD ||
sc->chiptype == CHIP_G4X) {
stolen = 256 * 1024;
} else {
@@ -781,6 +799,7 @@ agp_i810_set_aperture(device_t dev, u_int32_t aperture)
case CHIP_I915:
case CHIP_I965:
case CHIP_G33:
+ case CHIP_IGD:
case CHIP_G4X:
return agp_generic_set_aperture(dev, aperture);
}
@@ -801,7 +820,7 @@ agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical,
pte = (u_int32_t)physical | 1;
if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 ||
- sc->chiptype == CHIP_G4X) {
+ sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) {
pte |= (physical & 0x0000000f00000000ull) >> 28;
} else {
/* If we do actually have memory above 4GB on an older system,
@@ -821,6 +840,7 @@ agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical,
break;
case CHIP_I915:
case CHIP_G33:
+ case CHIP_IGD:
bus_write_4(sc->sc_res[1],
(offset >> AGP_PAGE_SHIFT) * 4, pte);
break;
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index c34bffe..5d39968 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -66,6 +66,7 @@ static void ahci_ch_pm(void *arg);
static void ahci_ch_intr_locked(void *data);
static void ahci_ch_intr(void *data);
static int ahci_ctlr_reset(device_t dev);
+static int ahci_ctlr_setup(device_t dev);
static void ahci_begin_transaction(device_t dev, union ccb *ccb);
static void ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
static void ahci_execute_transaction(struct ahci_slot *slot);
@@ -372,6 +373,9 @@ ahci_attach(device_t dev)
ctlr->caps &= ~AHCI_CAP_SPM;
if (ctlr->quirks & AHCI_Q_NONCQ)
ctlr->caps &= ~AHCI_CAP_SNCQ;
+ if ((ctlr->caps & AHCI_CAP_CCCS) == 0)
+ ctlr->ccc = 0;
+ ahci_ctlr_setup(dev);
/* Setup interrupts. */
if (ahci_setup_interrupt(dev)) {
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
@@ -501,6 +505,13 @@ ahci_ctlr_reset(device_t dev)
}
/* Reenable AHCI mode */
ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
+ return (0);
+}
+
+static int
+ahci_ctlr_setup(device_t dev)
+{
+ struct ahci_controller *ctlr = device_get_softc(dev);
/* Clear interrupts */
ATA_OUTL(ctlr->r_mem, AHCI_IS, ATA_INL(ctlr->r_mem, AHCI_IS));
/* Configure CCC */
@@ -543,6 +554,7 @@ ahci_resume(device_t dev)
if ((res = ahci_ctlr_reset(dev)) != 0)
return (res);
+ ahci_ctlr_setup(dev);
return (bus_generic_resume(dev));
}
@@ -615,7 +627,7 @@ ahci_intr(void *data)
{
struct ahci_controller_irq *irq = data;
struct ahci_controller *ctlr = irq->ctlr;
- u_int32_t is;
+ u_int32_t is, ise = 0;
void *arg;
int unit;
@@ -629,9 +641,14 @@ ahci_intr(void *data)
unit = irq->r_irq_rid - 1;
is = ATA_INL(ctlr->r_mem, AHCI_IS);
}
+ /* CCC interrupt is edge triggered. */
+ if (ctlr->ccc)
+ ise = 1 << ctlr->cccv;
/* Some controllers have edge triggered IS. */
if (ctlr->quirks & AHCI_Q_EDGEIS)
- ATA_OUTL(ctlr->r_mem, AHCI_IS, is);
+ ise |= is;
+ if (ise != 0)
+ ATA_OUTL(ctlr->r_mem, AHCI_IS, ise);
for (; unit < ctlr->channels; unit++) {
if ((is & (1 << unit)) != 0 &&
(arg = ctlr->interrupt[unit].argument)) {
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index e95b044..c685b84 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -1908,28 +1908,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
vtag = (vtag << TD_VLAN_SHIFT) & TD_VLAN_MASK;
cflags |= TD_INS_VLAN_TAG;
}
- /* Configure Tx checksum offload. */
- if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
-#ifdef ALC_USE_CUSTOM_CSUM
- cflags |= TD_CUSTOM_CSUM;
- /* Set checksum start offset. */
- cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
- TD_PLOAD_OFFSET_MASK;
- /* Set checksum insertion position of TCP/UDP. */
- cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
- TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
-#else
- if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
- cflags |= TD_IPCSUM;
- if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
- cflags |= TD_TCPCSUM;
- if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
- cflags |= TD_UDPCSUM;
- /* Set TCP/UDP header offset. */
- cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
- TD_L4HDR_OFFSET_MASK;
-#endif
- } else if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+ if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
/* Request TSO and set MSS. */
cflags |= TD_TSO | TD_TSO_DESCV1;
cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << TD_MSS_SHIFT) &
@@ -1961,6 +1940,27 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
}
/* Handle remaining fragments. */
idx = 1;
+ } else if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
+ /* Configure Tx checksum offload. */
+#ifdef ALC_USE_CUSTOM_CSUM
+ cflags |= TD_CUSTOM_CSUM;
+ /* Set checksum start offset. */
+ cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
+ TD_PLOAD_OFFSET_MASK;
+ /* Set checksum insertion position of TCP/UDP. */
+ cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
+ TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
+#else
+ if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
+ cflags |= TD_IPCSUM;
+ if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+ cflags |= TD_TCPCSUM;
+ if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+ cflags |= TD_UDPCSUM;
+ /* Set TCP/UDP header offset. */
+ cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
+ TD_L4HDR_OFFSET_MASK;
+#endif
}
for (; idx < nsegs; idx++) {
desc = &sc->alc_rdata.alc_tx_ring[prod];
diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c
index 76f1b74..b3e7187 100644
--- a/sys/dev/ale/if_ale.c
+++ b/sys/dev/ale/if_ale.c
@@ -1737,8 +1737,14 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
bus_dmamap_sync(sc->ale_cdata.ale_tx_tag, map, BUS_DMASYNC_PREWRITE);
m = *m_head;
- /* Configure Tx checksum offload. */
- if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
+ if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+ /* Request TSO and set MSS. */
+ cflags |= ALE_TD_TSO;
+ cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
+ /* Set IP/TCP header size. */
+ cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
+ cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
+ } else if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
/*
* AR81xx supports Tx custom checksum offload feature
* that offloads single 16bit checksum computation.
@@ -1769,15 +1775,6 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
ALE_TD_CSUM_XSUMOFFSET_SHIFT);
}
- if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
- /* Request TSO and set MSS. */
- cflags |= ALE_TD_TSO;
- cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
- /* Set IP/TCP header size. */
- cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
- cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
- }
-
/* Configure VLAN hardware tag insertion. */
if ((m->m_flags & M_VLANTAG) != 0) {
vtag = ALE_TX_VLAN_TAG(m->m_pkthdr.ether_vtag);
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 3d5d36e..d7b3f44 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -26,6 +26,8 @@
* $FreeBSD$
*/
+#include "opt_ata.h"
+
#if 0
#define ATA_LEGACY_SUPPORT /* Enable obsolete features that break
* some modern devices */
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index a3b1c4e..4aef471 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -513,9 +513,9 @@ ata_timeout(struct ata_request *request)
request->flags |= ATA_R_TIMEOUT;
if (ch->dma.unload)
ch->dma.unload(request);
-#ifdef ATA_CAM
ch->running = NULL;
ch->state = ATA_IDLE;
+#ifdef ATA_CAM
ata_cam_end_transaction(ch->dev, request);
#endif
mtx_unlock(&ch->state_mtx);
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
index 1e97607..9833678 100644
--- a/sys/dev/ata/ata-raid.c
+++ b/sys/dev/ata/ata-raid.c
@@ -2544,30 +2544,39 @@ ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp)
/* clear out any old info */
for (disk = 0; disk < raid->total_disks; disk++) {
+ u_int disk_idx = map->disk_idx[disk] & 0xffff;
+
raid->disks[disk].dev = NULL;
- bcopy(meta->disk[map->disk_idx[disk]].serial,
+ bcopy(meta->disk[disk_idx].serial,
raid->disks[disk].serial,
sizeof(raid->disks[disk].serial));
raid->disks[disk].sectors =
- meta->disk[map->disk_idx[disk]].sectors;
+ meta->disk[disk_idx].sectors;
raid->disks[disk].flags = 0;
- if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_ONLINE)
+ if (meta->disk[disk_idx].flags & INTEL_F_ONLINE)
raid->disks[disk].flags |= AR_DF_ONLINE;
- if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_ASSIGNED)
+ if (meta->disk[disk_idx].flags & INTEL_F_ASSIGNED)
raid->disks[disk].flags |= AR_DF_ASSIGNED;
- if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_SPARE) {
+ if (meta->disk[disk_idx].flags & INTEL_F_SPARE) {
raid->disks[disk].flags &= ~(AR_DF_ONLINE | AR_DF_ASSIGNED);
raid->disks[disk].flags |= AR_DF_SPARE;
}
- if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_DOWN)
+ if (meta->disk[disk_idx].flags & INTEL_F_DOWN)
raid->disks[disk].flags &= ~AR_DF_ONLINE;
}
}
if (meta->generation >= raid->generation) {
for (disk = 0; disk < raid->total_disks; disk++) {
struct ata_device *atadev = device_get_softc(parent);
+ int len;
- if (!strncmp(raid->disks[disk].serial, atadev->param.serial,
+ for (len = 0; len < sizeof(atadev->param.serial); len++) {
+ if (atadev->param.serial[len] < 0x20)
+ break;
+ }
+ len = (len > sizeof(raid->disks[disk].serial)) ?
+ len - sizeof(raid->disks[disk].serial) : 0;
+ if (!strncmp(raid->disks[disk].serial, atadev->param.serial + len,
sizeof(raid->disks[disk].serial))) {
raid->disks[disk].dev = parent;
raid->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_ONLINE);
@@ -2637,8 +2646,15 @@ ata_raid_intel_write_meta(struct ar_softc *rdp)
device_get_softc(device_get_parent(rdp->disks[disk].dev));
struct ata_device *atadev =
device_get_softc(rdp->disks[disk].dev);
+ int len;
- bcopy(atadev->param.serial, meta->disk[disk].serial,
+ for (len = 0; len < sizeof(atadev->param.serial); len++) {
+ if (atadev->param.serial[len] < 0x20)
+ break;
+ }
+ len = (len > sizeof(rdp->disks[disk].serial)) ?
+ len - sizeof(rdp->disks[disk].serial) : 0;
+ bcopy(atadev->param.serial + len, meta->disk[disk].serial,
sizeof(rdp->disks[disk].serial));
meta->disk[disk].sectors = rdp->disks[disk].sectors;
meta->disk[disk].id = (ch->unit << 16) | atadev->unit;
diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c
index b7f1147..fee9692 100644
--- a/sys/dev/ata/chipsets/ata-acerlabs.c
+++ b/sys/dev/ata/chipsets/ata-acerlabs.c
@@ -184,8 +184,11 @@ ata_ali_ch_attach(device_t dev)
if (ctlr->chip->cfg2 & ALI_NEW && ctlr->chip->chiprev < 0xc7)
ch->flags |= ATA_CHECKS_CABLE;
/* older chips can't do 48bit DMA transfers */
- if (ctlr->chip->chiprev <= 0xc4)
+ if (ctlr->chip->chiprev <= 0xc4) {
ch->flags |= ATA_NO_48BIT_DMA;
+ if (ch->dma.max_iosize > 256 * 512)
+ ch->dma.max_iosize = 256 * 512;
+ }
return 0;
}
diff --git a/sys/dev/ath/ath_hal/ah_debug.h b/sys/dev/ath/ath_hal/ah_debug.h
index e3b15ad..428a2a8 100644
--- a/sys/dev/ath/ath_hal/ah_debug.h
+++ b/sys/dev/ath/ath_hal/ah_debug.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_debug.h,v 1.1 2008/10/12 16:44:34 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_DEBUG_H_
#define _ATH_AH_DEBUG_H_
diff --git a/sys/dev/ath/ath_hal/ah_decode.h b/sys/dev/ath/ath_hal/ah_decode.h
index bd595ae..bc0324d 100644
--- a/sys/dev/ath/ath_hal/ah_decode.h
+++ b/sys/dev/ath/ath_hal/ah_decode.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_decode.h,v 1.4 2008/11/10 04:08:00 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_DECODE_H_
#define _ATH_AH_DECODE_H_
diff --git a/sys/dev/ath/ath_hal/ah_devid.h b/sys/dev/ath/ath_hal/ah_devid.h
index 0844c77..38e187b 100644
--- a/sys/dev/ath/ath_hal/ah_devid.h
+++ b/sys/dev/ath/ath_hal/ah_devid.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_devid.h,v 1.4 2008/10/06 18:32:46 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_DEVID_H_
diff --git a/sys/dev/ath/ath_hal/ah_eeprom.h b/sys/dev/ath/ath_hal/ah_eeprom.h
index 0adfcd1..5e91eb1 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_eeprom.h,v 1.11 2008/11/27 22:32:48 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_EEPROM_H_
#define _ATH_AH_EEPROM_H_
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v1.c b/sys/dev/ath/ath_hal/ah_eeprom_v1.c
index 91f895c..0f9ed36 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v1.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v1.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_eeprom_v1.c,v 1.1 2008/11/11 02:40:11 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v1.h b/sys/dev/ath/ath_hal/ah_eeprom_v1.h
index 2c23589..22fce8a 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v1.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v1.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_eeprom_v1.h,v 1.1 2008/11/11 02:40:11 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_EEPROM_V1_H_
#define _ATH_AH_EEPROM_V1_H_
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v3.h b/sys/dev/ath/ath_hal/ah_eeprom_v3.h
index 9f30c72..cde9a10 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v3.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v3.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_eeprom_v3.h,v 1.2 2008/11/10 04:08:00 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_EEPROM_V3_H_
#define _ATH_AH_EEPROM_V3_H_
diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h
index 8f7ba65..3791639 100644
--- a/sys/dev/ath/ath_hal/ah_internal.h
+++ b/sys/dev/ath/ath_hal/ah_internal.h
@@ -334,6 +334,8 @@ struct ath_hal_private {
(_ah)->ah_configPCIE(_ah, _reset)
#define ath_hal_disablePCIE(_ah) \
(_ah)->ah_disablePCIE(_ah)
+#define ath_hal_setInterrupts(_ah, _mask) \
+ (_ah)->ah_setInterrupts(_ah, _mask)
#define ath_hal_eepromDetach(_ah) do { \
if (AH_PRIVATE(_ah)->ah_eepromDetach != AH_NULL) \
diff --git a/sys/dev/ath/ath_hal/ah_soc.h b/sys/dev/ath/ath_hal/ah_soc.h
index 50fbc62..ca75ae9 100644
--- a/sys/dev/ath/ath_hal/ah_soc.h
+++ b/sys/dev/ath/ath_hal/ah_soc.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_soc.h,v 1.4 2008/11/10 04:08:00 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_SOC_H_
#define _ATH_AH_SOC_H_
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c b/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c
index 680e2de..dbd059e 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210_beacon.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c b/sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c
index 9594ce3..87fb067 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210_keycache.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_power.c b/sys/dev/ath/ath_hal/ar5210/ar5210_power.c
index c2771f2..1c6909b 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_power.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_power.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210_power.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c b/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
index 489c55a..bdb4d57 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210_recv.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210desc.h b/sys/dev/ath/ath_hal/ar5210/ar5210desc.h
index d7d382c..5634480 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210desc.h
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210desc.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210desc.h,v 1.5 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5210DESC_H
#define _DEV_ATH_AR5210DESC_H
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210phy.h b/sys/dev/ath/ath_hal/ar5210/ar5210phy.h
index 6211613..4ab3025 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210phy.h
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210phy.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210phy.h,v 1.4 2008/11/10 01:19:37 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5210PHY_H
#define _DEV_ATH_AR5210PHY_H
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210reg.h b/sys/dev/ath/ath_hal/ar5210/ar5210reg.h
index dc49fcd..894d9bb 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210reg.h
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210reg.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5210reg.h,v 1.4 2008/11/10 01:19:37 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5210REG_H
#define _DEV_ATH_AR5210REG_H
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5k_0007.ini b/sys/dev/ath/ath_hal/ar5210/ar5k_0007.ini
index b0285e9..b536483 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5k_0007.ini
+++ b/sys/dev/ath/ath_hal/ar5210/ar5k_0007.ini
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5k_0007.ini,v 1.2 2008/11/10 01:19:37 sam Exp $
+ * $FreeBSD$
*/
/* crete register init */
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c b/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c
index 74207a3..669b8f6 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211_beacon.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c b/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c
index 61f579a..3e0f922 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211_keycache.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_power.c b/sys/dev/ath/ath_hal/ar5211/ar5211_power.c
index bcfcf7c..776cfb3 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_power.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_power.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211_power.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c b/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
index c5b0e18..733559e 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211_recv.c,v 1.4 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211desc.h b/sys/dev/ath/ath_hal/ar5211/ar5211desc.h
index 9fa6e29..4528447 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211desc.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211desc.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211desc.h,v 1.5 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5211DESC_H
#define _DEV_ATH_AR5211DESC_H
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211phy.h b/sys/dev/ath/ath_hal/ar5211/ar5211phy.h
index 8bd7051..bf5b67e 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211phy.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211phy.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211phy.h,v 1.4 2008/11/10 01:19:38 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5211PHY_H
#define _DEV_ATH_AR5211PHY_H
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211reg.h b/sys/dev/ath/ath_hal/ar5211/ar5211reg.h
index babd565..647f20d 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211reg.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211reg.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5211reg.h,v 1.4 2008/11/10 01:19:38 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5211REG_H
#define _DEV_ATH_AR5211REG_H
diff --git a/sys/dev/ath/ath_hal/ar5211/boss.ini b/sys/dev/ath/ath_hal/ar5211/boss.ini
index a041c44..e054436 100755
--- a/sys/dev/ath/ath_hal/ar5211/boss.ini
+++ b/sys/dev/ath/ath_hal/ar5211/boss.ini
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: boss.ini,v 1.3 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
/* Auto Generated PCI Register Writes. Created: 09/12/02 */
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.ini b/sys/dev/ath/ath_hal/ar5212/ar5212.ini
index d53dbe2..608f91f 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212.ini
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212.ini
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5212.ini,v 1.3 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
/* Auto Generated PCI Register Writes. Created: 09/01/04 */
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c b/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c
index 2dbc0cb..538f8b8 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5212_beacon.c,v 1.6 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_eeprom.c b/sys/dev/ath/ath_hal/ar5212/ar5212_eeprom.c
index d2999fd..f4b6771 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_eeprom.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_eeprom.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5212_eeprom.c,v 1.6 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c b/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
index a1f2dbb..5272349 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5212_keycache.c,v 1.4 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
index ed9de14..8b8a921 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
@@ -54,7 +54,7 @@ ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
/*
* Disable interrupts while futzing with the fifo level.
*/
- omask = ah->ah_setInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
+ omask = ath_hal_setInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
txcfg = OS_REG_READ(ah, AR_TXCFG);
curLevel = MS(txcfg, AR_FTRIG);
@@ -72,7 +72,7 @@ ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
ahp->ah_txTrigLev = newLevel;
/* re-enable chip interrupts */
- ah->ah_setInterrupts(ah, omask);
+ ath_hal_setInterrupts(ah, omask);
return (newLevel != curLevel);
}
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212desc.h b/sys/dev/ath/ath_hal/ar5212/ar5212desc.h
index 9885c9f..c6af68b 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212desc.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212desc.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5212desc.h,v 1.4 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AR5212_DESC_H_
#define _ATH_AR5212_DESC_H_
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212phy.h b/sys/dev/ath/ath_hal/ar5212/ar5212phy.h
index e040ec7..12cd3df 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212phy.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212phy.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5212phy.h,v 1.7 2008/11/19 21:23:01 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5212PHY_H_
#define _DEV_ATH_AR5212PHY_H_
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5311reg.h b/sys/dev/ath/ath_hal/ar5212/ar5311reg.h
index efb8568..b79370e 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5311reg.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5311reg.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5311reg.h,v 1.3 2008/10/06 18:32:50 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5311REG_H_
#define _DEV_ATH_AR5311REG_H_
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c b/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c
index c14b8b2..7a84232 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5312_eeprom.c,v 1.4 2008/11/10 04:08:04 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c b/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c
index c40191e..0a1545c 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5312_interrupts.c,v 1.2 2008/11/10 01:19:39 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_misc.c b/sys/dev/ath/ath_hal/ar5312/ar5312_misc.c
index 7928318..3d85ece 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_misc.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_misc.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5312_misc.c,v 1.4 2008/11/22 07:40:15 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_power.c b/sys/dev/ath/ath_hal/ar5312/ar5312_power.c
index 1cc4ed6..94a0f1c 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_power.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_power.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5312_power.c,v 1.4 2008/11/10 04:08:04 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312phy.h b/sys/dev/ath/ath_hal/ar5312/ar5312phy.h
index 9f867c7..fcb8564 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312phy.h
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312phy.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5312phy.h,v 1.3 2008/10/06 18:32:50 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5312PHY_H_
#define _DEV_ATH_AR5312PHY_H_
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312reg.h b/sys/dev/ath/ath_hal/ar5312/ar5312reg.h
index ff79cd3..bdfeffa 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312reg.h
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312reg.h
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ar5312reg.h,v 1.4 2008/11/10 04:08:04 sam Exp $
+ * $FreeBSD$
*/
#ifndef _DEV_ATH_AR5312REG_H_
#define _DEV_ATH_AR5312REG_H_
diff --git a/sys/dev/ath/ath_hal/ar5416/ar9160.ini b/sys/dev/ath/ath_hal/ar5416/ar9160.ini
index 275aa48..275aa48 100755..100644
--- a/sys/dev/ath/ath_hal/ar5416/ar9160.ini
+++ b/sys/dev/ath/ath_hal/ar5416/ar9160.ini
diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c b/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
index 946133a..ef8c955 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
@@ -378,8 +378,8 @@ ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
case HAL_ANT_VARIABLE:
/* Restore original chainmask settings */
/* XXX */
- ahp->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
- ahp->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
+ ahp->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK;
+ ahp->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK;
break;
}
return AH_TRUE;
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index d1ddb2d..5847489 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -3654,8 +3654,14 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
if (vap->iv_opmode == IEEE80211_M_IBSS &&
vap->iv_state == IEEE80211_S_RUN) {
- uint32_t rstamp = sc->sc_lastrs->rs_tstamp;
- u_int64_t tsf = ath_extend_tsf(rstamp,
+ uint32_t rstamp;
+ uint64_t tsf;
+
+ if (sc->sc_lastrs == NULL)
+ break;
+
+ rstamp = sc->sc_lastrs->rs_tstamp;
+ tsf = ath_extend_tsf(rstamp,
ath_hal_gettsf64(sc->sc_ah));
/*
* Handle ibss merge as needed; check the tsf on the
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 8b6f222..2ad5ab2 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
* David Christensen <davidch@broadcom.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$");
* BCM5708C B1, B2
* BCM5708S B1, B2
* BCM5709C A1, C0
- * BCM5716C C0
+ * BCM5709S A1, C0
+ * BCM5716C C0
+ * BCM5716S C0
*
* The following controllers are not supported by this driver:
* BCM5706C A0, A1 (pre-production)
@@ -46,7 +48,7 @@ __FBSDID("$FreeBSD$");
* BCM5708C A0, B0 (pre-production)
* BCM5708S A0, B0 (pre-production)
* BCM5709C A0 B0, B1, B2 (pre-production)
- * BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
+ * BCM5709S A0, B0, B1, B2 (pre-production)
*/
#include "opt_bce.h"
@@ -275,37 +277,41 @@ static struct flash_spec flash_5709 = {
/****************************************************************************/
/* FreeBSD device entry points. */
/****************************************************************************/
-static int bce_probe (device_t);
-static int bce_attach (device_t);
-static int bce_detach (device_t);
-static int bce_shutdown (device_t);
+static int bce_probe (device_t);
+static int bce_attach (device_t);
+static int bce_detach (device_t);
+static int bce_shutdown (device_t);
/****************************************************************************/
/* BCE Debug Data Structure Dump Routines */
/****************************************************************************/
#ifdef BCE_DEBUG
-static u32 bce_reg_rd (struct bce_softc *, u32);
-static void bce_reg_wr (struct bce_softc *, u32, u32);
-static void bce_reg_wr16 (struct bce_softc *, u32, u16);
-static u32 bce_ctx_rd (struct bce_softc *, u32, u32);
-static void bce_dump_enet (struct bce_softc *, struct mbuf *);
-static void bce_dump_mbuf (struct bce_softc *, struct mbuf *);
+static u32 bce_reg_rd (struct bce_softc *, u32);
+static void bce_reg_wr (struct bce_softc *, u32, u32);
+static void bce_reg_wr16 (struct bce_softc *, u32, u16);
+static u32 bce_ctx_rd (struct bce_softc *, u32, u32);
+static void bce_dump_enet (struct bce_softc *, struct mbuf *);
+static void bce_dump_mbuf (struct bce_softc *, struct mbuf *);
static void bce_dump_tx_mbuf_chain (struct bce_softc *, u16, int);
static void bce_dump_rx_mbuf_chain (struct bce_softc *, u16, int);
#ifdef BCE_JUMBO_HDRSPLIT
static void bce_dump_pg_mbuf_chain (struct bce_softc *, u16, int);
#endif
-static void bce_dump_txbd (struct bce_softc *, int, struct tx_bd *);
-static void bce_dump_rxbd (struct bce_softc *, int, struct rx_bd *);
+static void bce_dump_txbd (struct bce_softc *,
+ int, struct tx_bd *);
+static void bce_dump_rxbd (struct bce_softc *,
+ int, struct rx_bd *);
#ifdef BCE_JUMBO_HDRSPLIT
-static void bce_dump_pgbd (struct bce_softc *, int, struct rx_bd *);
+static void bce_dump_pgbd (struct bce_softc *,
+ int, struct rx_bd *);
#endif
-static void bce_dump_l2fhdr (struct bce_softc *, int, struct l2_fhdr *);
-static void bce_dump_ctx (struct bce_softc *, u16);
-static void bce_dump_ftqs (struct bce_softc *);
+static void bce_dump_l2fhdr (struct bce_softc *,
+ int, struct l2_fhdr *);
+static void bce_dump_ctx (struct bce_softc *, u16);
+static void bce_dump_ftqs (struct bce_softc *);
static void bce_dump_tx_chain (struct bce_softc *, u16, int);
-static void bce_dump_rx_chain (struct bce_softc *, u16, int);
+static void bce_dump_rx_bd_chain (struct bce_softc *, u16, int);
#ifdef BCE_JUMBO_HDRSPLIT
static void bce_dump_pg_chain (struct bce_softc *, u16, int);
#endif
@@ -313,25 +319,26 @@ static void bce_dump_status_block (struct bce_softc *);
static void bce_dump_stats_block (struct bce_softc *);
static void bce_dump_driver_state (struct bce_softc *);
static void bce_dump_hw_state (struct bce_softc *);
-static void bce_dump_mq_regs (struct bce_softc *);
+static void bce_dump_mq_regs (struct bce_softc *);
static void bce_dump_bc_state (struct bce_softc *);
static void bce_dump_txp_state (struct bce_softc *, int);
static void bce_dump_rxp_state (struct bce_softc *, int);
static void bce_dump_tpat_state (struct bce_softc *, int);
static void bce_dump_cp_state (struct bce_softc *, int);
static void bce_dump_com_state (struct bce_softc *, int);
-static void bce_breakpoint (struct bce_softc *);
+static void bce_dump_rv2p_state (struct bce_softc *);
+static void bce_breakpoint (struct bce_softc *);
#endif
/****************************************************************************/
/* BCE Register/Memory Access Routines */
/****************************************************************************/
-static u32 bce_reg_rd_ind (struct bce_softc *, u32);
-static void bce_reg_wr_ind (struct bce_softc *, u32, u32);
-static void bce_shmem_wr (struct bce_softc *, u32, u32);
-static u32 bce_shmem_rd (struct bce_softc *, u32);
-static void bce_ctx_wr (struct bce_softc *, u32, u32, u32);
+static u32 bce_reg_rd_ind (struct bce_softc *, u32);
+static void bce_reg_wr_ind (struct bce_softc *, u32, u32);
+static void bce_shmem_wr (struct bce_softc *, u32, u32);
+static u32 bce_shmem_rd (struct bce_softc *, u32);
+static void bce_ctx_wr (struct bce_softc *, u32, u32, u32);
static int bce_miibus_read_reg (device_t, int, int);
static int bce_miibus_write_reg (device_t, int, int, int);
static void bce_miibus_statchg (device_t);
@@ -343,95 +350,101 @@ static void bce_miibus_statchg (device_t);
static int bce_acquire_nvram_lock (struct bce_softc *);
static int bce_release_nvram_lock (struct bce_softc *);
static void bce_enable_nvram_access (struct bce_softc *);
-static void bce_disable_nvram_access(struct bce_softc *);
+static void bce_disable_nvram_access (struct bce_softc *);
static int bce_nvram_read_dword (struct bce_softc *, u32, u8 *, u32);
-static int bce_init_nvram (struct bce_softc *);
-static int bce_nvram_read (struct bce_softc *, u32, u8 *, int);
-static int bce_nvram_test (struct bce_softc *);
+static int bce_init_nvram (struct bce_softc *);
+static int bce_nvram_read (struct bce_softc *, u32, u8 *, int);
+static int bce_nvram_test (struct bce_softc *);
#ifdef BCE_NVRAM_WRITE_SUPPORT
static int bce_enable_nvram_write (struct bce_softc *);
static void bce_disable_nvram_write (struct bce_softc *);
static int bce_nvram_erase_page (struct bce_softc *, u32);
static int bce_nvram_write_dword (struct bce_softc *, u32, u8 *, u32);
-static int bce_nvram_write (struct bce_softc *, u32, u8 *, int);
+static int bce_nvram_write (struct bce_softc *, u32, u8 *, int);
#endif
/****************************************************************************/
/* */
/****************************************************************************/
-static void bce_get_media (struct bce_softc *);
-static void bce_dma_map_addr (void *, bus_dma_segment_t *, int, int);
-static int bce_dma_alloc (device_t);
-static void bce_dma_free (struct bce_softc *);
+static void bce_get_media (struct bce_softc *);
+static void bce_init_media (struct bce_softc *);
+static void bce_dma_map_addr (void *,
+ bus_dma_segment_t *, int, int);
+static int bce_dma_alloc (device_t);
+static void bce_dma_free (struct bce_softc *);
static void bce_release_resources (struct bce_softc *);
/****************************************************************************/
/* BCE Firmware Synchronization and Load */
/****************************************************************************/
-static int bce_fw_sync (struct bce_softc *, u32);
+static int bce_fw_sync (struct bce_softc *, u32);
static void bce_load_rv2p_fw (struct bce_softc *, u32 *, u32, u32);
-static void bce_load_cpu_fw (struct bce_softc *, struct cpu_reg *, struct fw_info *);
-static void bce_start_cpu (struct bce_softc *, struct cpu_reg *);
-static void bce_halt_cpu (struct bce_softc *, struct cpu_reg *);
-static void bce_start_rxp_cpu (struct bce_softc *);
+static void bce_load_cpu_fw (struct bce_softc *,
+ struct cpu_reg *, struct fw_info *);
+static void bce_start_cpu (struct bce_softc *, struct cpu_reg *);
+static void bce_halt_cpu (struct bce_softc *, struct cpu_reg *);
+static void bce_start_rxp_cpu (struct bce_softc *);
static void bce_init_rxp_cpu (struct bce_softc *);
static void bce_init_txp_cpu (struct bce_softc *);
static void bce_init_tpat_cpu (struct bce_softc *);
-static void bce_init_cp_cpu (struct bce_softc *);
+static void bce_init_cp_cpu (struct bce_softc *);
static void bce_init_com_cpu (struct bce_softc *);
-static void bce_init_cpus (struct bce_softc *);
+static void bce_init_cpus (struct bce_softc *);
static void bce_print_adapter_info (struct bce_softc *);
static void bce_probe_pci_caps (device_t, struct bce_softc *);
-static void bce_stop (struct bce_softc *);
-static int bce_reset (struct bce_softc *, u32);
-static int bce_chipinit (struct bce_softc *);
-static int bce_blockinit (struct bce_softc *);
+static void bce_stop (struct bce_softc *);
+static int bce_reset (struct bce_softc *, u32);
+static int bce_chipinit (struct bce_softc *);
+static int bce_blockinit (struct bce_softc *);
static int bce_init_tx_chain (struct bce_softc *);
static void bce_free_tx_chain (struct bce_softc *);
-static int bce_get_rx_buf (struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
+static int bce_get_rx_buf (struct bce_softc *,
+ struct mbuf *, u16 *, u16 *, u32 *);
static int bce_init_rx_chain (struct bce_softc *);
static void bce_fill_rx_chain (struct bce_softc *);
static void bce_free_rx_chain (struct bce_softc *);
#ifdef BCE_JUMBO_HDRSPLIT
-static int bce_get_pg_buf (struct bce_softc *, struct mbuf *, u16 *, u16 *);
+static int bce_get_pg_buf (struct bce_softc *,
+ struct mbuf *, u16 *, u16 *);
static int bce_init_pg_chain (struct bce_softc *);
static void bce_fill_pg_chain (struct bce_softc *);
static void bce_free_pg_chain (struct bce_softc *);
#endif
-static struct mbuf *bce_tso_setup (struct bce_softc *, struct mbuf **, u16 *);
-static int bce_tx_encap (struct bce_softc *, struct mbuf **);
+static struct mbuf *bce_tso_setup (struct bce_softc *,
+ struct mbuf **, u16 *);
+static int bce_tx_encap (struct bce_softc *, struct mbuf **);
static void bce_start_locked (struct ifnet *);
-static void bce_start (struct ifnet *);
-static int bce_ioctl (struct ifnet *, u_long, caddr_t);
-static void bce_watchdog (struct bce_softc *);
-static int bce_ifmedia_upd (struct ifnet *);
+static void bce_start (struct ifnet *);
+static int bce_ioctl (struct ifnet *, u_long, caddr_t);
+static void bce_watchdog (struct bce_softc *);
+static int bce_ifmedia_upd (struct ifnet *);
static void bce_ifmedia_upd_locked (struct ifnet *);
-static void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *);
-static void bce_init_locked (struct bce_softc *);
-static void bce_init (void *);
+static void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *);
+static void bce_init_locked (struct bce_softc *);
+static void bce_init (void *);
static void bce_mgmt_init_locked (struct bce_softc *sc);
-static void bce_init_ctx (struct bce_softc *);
+static void bce_init_ctx (struct bce_softc *);
static void bce_get_mac_addr (struct bce_softc *);
static void bce_set_mac_addr (struct bce_softc *);
-static void bce_phy_intr (struct bce_softc *);
-static inline u16 bce_get_hw_rx_cons(struct bce_softc *);
-static void bce_rx_intr (struct bce_softc *);
-static void bce_tx_intr (struct bce_softc *);
+static void bce_phy_intr (struct bce_softc *);
+static inline u16 bce_get_hw_rx_cons (struct bce_softc *);
+static void bce_rx_intr (struct bce_softc *);
+static void bce_tx_intr (struct bce_softc *);
static void bce_disable_intr (struct bce_softc *);
-static void bce_enable_intr (struct bce_softc *, int);
+static void bce_enable_intr (struct bce_softc *, int);
-static void bce_intr (void *);
-static void bce_set_rx_mode (struct bce_softc *);
+static void bce_intr (void *);
+static void bce_set_rx_mode (struct bce_softc *);
static void bce_stats_update (struct bce_softc *);
-static void bce_tick (void *);
-static void bce_pulse (void *);
-static void bce_add_sysctls (struct bce_softc *);
+static void bce_tick (void *);
+static void bce_pulse (void *);
+static void bce_add_sysctls (struct bce_softc *);
/****************************************************************************/
@@ -536,15 +549,15 @@ bce_probe(device_t dev)
sdid = pci_get_subdevice(dev);
DBPRINT(sc, BCE_EXTREME_LOAD,
- "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
- "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
+ "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
+ "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
/* Look through the list of known devices for a match. */
while(t->bce_name != NULL) {
if ((vid == t->bce_vid) && (did == t->bce_did) &&
- ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
- ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
+ ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
+ ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
@@ -553,8 +566,8 @@ bce_probe(device_t dev)
/* Print out the device identity. */
snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
- t->bce_name,
- (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
+ t->bce_name, (((pci_read_config(dev,
+ PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
(pci_read_config(dev, PCIR_REVID, 4) & 0xf));
device_set_desc_copy(dev, descbuf);
@@ -586,21 +599,21 @@ bce_print_adapter_info(struct bce_softc *sc)
BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
- ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
+ ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
/* Bus info. */
if (sc->bce_flags & BCE_PCIE_FLAG) {
printf("Bus (PCIe x%d, ", sc->link_width);
switch (sc->link_speed) {
- case 1: printf("2.5Gbps); "); break;
- case 2: printf("5Gbps); "); break;
- default: printf("Unknown link speed); ");
+ case 1: printf("2.5Gbps); "); break;
+ case 2: printf("5Gbps); "); break;
+ default: printf("Unknown link speed); ");
}
} else {
printf("Bus (PCI%s, %s, %dMHz); ",
- ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
- ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
- sc->bus_speed_mhz);
+ ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
+ ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
+ "32-bit" : "64-bit"), sc->bus_speed_mhz);
}
/* Firmware version and device features. */
@@ -608,30 +621,30 @@ bce_print_adapter_info(struct bce_softc *sc)
#ifdef BCE_JUMBO_HDRSPLIT
printf("SPLT");
- i++;
+ i++;
#endif
- if (sc->bce_flags & BCE_USING_MSI_FLAG) {
- if (i > 0) printf("|");
+ if (sc->bce_flags & BCE_USING_MSI_FLAG) {
+ if (i > 0) printf("|");
printf("MSI"); i++;
- }
+ }
- if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
- if (i > 0) printf("|");
+ if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
+ if (i > 0) printf("|");
printf("MSI-X"); i++;
- }
+ }
- if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
- if (i > 0) printf("|");
+ if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
+ if (i > 0) printf("|");
printf("2.5G"); i++;
- }
+ }
- if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
- if (i > 0) printf("|");
- printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
- } else {
- printf(")\n");
- }
+ if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+ if (i > 0) printf("|");
+ printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
+ } else {
+ printf(")\n");
+ }
DBEXIT(BCE_VERBOSE_LOAD);
}
@@ -663,8 +676,8 @@ bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
if (reg != 0) {
u16 link_status = pci_read_config(dev, reg + 0x12, 2);
- DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = 0x%08X\n",
- link_status);
+ DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
+ "0x%08X\n", link_status);
sc->link_speed = link_status & 0xf;
sc->link_width = (link_status >> 4) & 0x3f;
sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
@@ -726,7 +739,7 @@ bce_attach(device_t dev)
if (sc->bce_res_mem == NULL) {
BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENXIO;
goto bce_attach_fail;
}
@@ -797,14 +810,14 @@ bce_attach(device_t dev)
}
sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &rid, RF_SHAREABLE | RF_ACTIVE);
+ &rid, RF_SHAREABLE | RF_ACTIVE);
sc->bce_irq_rid = rid;
/* Report any IRQ allocation errors. */
if (sc->bce_res_irq == NULL) {
BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENXIO;
goto bce_attach_fail;
}
@@ -819,28 +832,28 @@ bce_attach(device_t dev)
* valid until this is done.
*/
pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
- BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
- BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
+ BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+ BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
/* Save ASIC revsion info. */
sc->bce_chipid = REG_RD(sc, BCE_MISC_ID);
/* Weed out any non-production controller revisions. */
switch(BCE_CHIP_ID(sc)) {
- case BCE_CHIP_ID_5706_A0:
- case BCE_CHIP_ID_5706_A1:
- case BCE_CHIP_ID_5708_A0:
- case BCE_CHIP_ID_5708_B0:
- case BCE_CHIP_ID_5709_A0:
- case BCE_CHIP_ID_5709_B0:
- case BCE_CHIP_ID_5709_B1:
- case BCE_CHIP_ID_5709_B2:
- BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
- __FILE__, __LINE__,
- (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
- (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
- rc = ENODEV;
- goto bce_attach_fail;
+ case BCE_CHIP_ID_5706_A0:
+ case BCE_CHIP_ID_5706_A1:
+ case BCE_CHIP_ID_5708_A0:
+ case BCE_CHIP_ID_5708_B0:
+ case BCE_CHIP_ID_5709_A0:
+ case BCE_CHIP_ID_5709_B0:
+ case BCE_CHIP_ID_5709_B1:
+ case BCE_CHIP_ID_5709_B2:
+ BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
+ __FILE__, __LINE__,
+ (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
+ (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
+ rc = ENODEV;
+ goto bce_attach_fail;
}
/*
@@ -862,58 +875,67 @@ bce_attach(device_t dev)
if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
/* Multi-port devices use different offsets in shared memory. */
sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
- (pci_get_function(sc->bce_dev) << 2));
+ (pci_get_function(sc->bce_dev) << 2));
else
sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
- __FUNCTION__, sc->bce_shmem_base);
+ __FUNCTION__, sc->bce_shmem_base);
/* Fetch the bootcode revision. */
- val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
- for (int i = 0, j = 0; i < 3; i++) {
- u8 num;
-
- num = (u8) (val >> (24 - (i * 8)));
- for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
- if (num >= k || !skip0 || k == 1) {
- sc->bce_bc_ver[j++] = (num / k) + '0';
- skip0 = 0;
- }
- }
- if (i != 2)
- sc->bce_bc_ver[j++] = '.';
- }
-
- /* Check if any management firwmare is running. */
- val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
- if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
- sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
-
- /* Allow time for firmware to enter the running state. */
- for (int i = 0; i < 30; i++) {
- val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
- if (val & BCE_CONDITION_MFW_RUN_MASK)
- break;
- DELAY(10000);
- }
- }
-
- /* Check the current bootcode state. */
- val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
- val &= BCE_CONDITION_MFW_RUN_MASK;
- if (val != BCE_CONDITION_MFW_RUN_UNKNOWN &&
- val != BCE_CONDITION_MFW_RUN_NONE) {
- u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
- int i = 0;
-
- for (int j = 0; j < 3; j++) {
- val = bce_reg_rd_ind(sc, addr + j * 4);
- val = bswap32(val);
- memcpy(&sc->bce_mfw_ver[i], &val, 4);
- i += 4;
- }
- }
+ val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
+ for (int i = 0, j = 0; i < 3; i++) {
+ u8 num;
+
+ num = (u8) (val >> (24 - (i * 8)));
+ for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
+ if (num >= k || !skip0 || k == 1) {
+ sc->bce_bc_ver[j++] = (num / k) + '0';
+ skip0 = 0;
+ }
+ }
+
+ if (i != 2)
+ sc->bce_bc_ver[j++] = '.';
+ }
+
+ /* Check if any management firwmare is enabled. */
+ val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
+ if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
+ sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
+
+ /* Allow time for firmware to enter the running state. */
+ for (int i = 0; i < 30; i++) {
+ val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
+ if (val & BCE_CONDITION_MFW_RUN_MASK)
+ break;
+ DELAY(10000);
+ }
+
+ /* Check if management firmware is running. */
+ val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
+ val &= BCE_CONDITION_MFW_RUN_MASK;
+ if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
+ (val != BCE_CONDITION_MFW_RUN_NONE)) {
+ u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
+ int i = 0;
+
+ /* Read the management firmware version string. */
+ for (int j = 0; j < 3; j++) {
+ val = bce_reg_rd_ind(sc, addr + j * 4);
+ val = bswap32(val);
+ memcpy(&sc->bce_mfw_ver[i], &val, 4);
+ i += 4;
+ }
+ } else {
+ /* May cause firmware synchronization timeouts. */
+ BCE_PRINTF("%s(%d): Management firmware enabled "
+ "but not running!\n", __FILE__, __LINE__);
+ strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
+
+ /* ToDo: Any action the driver should take? */
+ }
+ }
/* Get PCI bus information (speed and type). */
val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
@@ -960,10 +982,10 @@ bce_attach(device_t dev)
if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
sc->bce_flags |= BCE_PCI_32BIT_FLAG;
- /* Reset the controller and announce to bootcode that driver is present. */
+ /* Reset controller and announce to bootcode that driver is present. */
if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
BCE_PRINTF("%s(%d): Controller reset failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENXIO;
goto bce_attach_fail;
}
@@ -971,7 +993,7 @@ bce_attach(device_t dev)
/* Initialize the controller. */
if (bce_chipinit(sc)) {
BCE_PRINTF("%s(%d): Controller initialization failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENXIO;
goto bce_attach_fail;
}
@@ -979,7 +1001,7 @@ bce_attach(device_t dev)
/* Perform NVRAM test. */
if (bce_nvram_test(sc)) {
BCE_PRINTF("%s(%d): NVRAM test failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENXIO;
goto bce_attach_fail;
}
@@ -1020,6 +1042,14 @@ bce_attach(device_t dev)
sc->bce_rx_ticks = 18;
#endif
+ /* Not used for L2. */
+ sc->bce_comp_prod_trip_int = 0;
+ sc->bce_comp_prod_trip = 0;
+ sc->bce_com_ticks_int = 0;
+ sc->bce_com_ticks = 0;
+ sc->bce_cmd_ticks_int = 0;
+ sc->bce_cmd_ticks = 0;
+
/* Update statistics once every second. */
sc->bce_stats_ticks = 1000000 & 0xffff00;
@@ -1096,7 +1126,10 @@ bce_attach(device_t dev)
else
ifp->if_baudrate = IF_Mbps(1000);
- /* Check for an MII child bus by probing the PHY. */
+ /* Handle any special PHY initialization for SerDes PHYs. */
+ bce_init_media(sc);
+
+ /* MII child bus by probing the PHY. */
if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
bce_ifmedia_sts)) {
BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
@@ -1500,11 +1533,22 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
/* Make sure we are accessing the correct PHY address. */
if (phy != sc->bce_phy_addr) {
- DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY read!\n", phy);
+ DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
+ "for PHY read!\n", phy);
return(0);
}
- if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
+ /*
+ * The 5709S PHY is an IEEE Clause 45 PHY
+ * with special mappings to work with IEEE
+ * Clause 22 register accesses.
+ */
+ if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+ if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
+ reg += 0x10;
+ }
+
+ if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
@@ -1516,8 +1560,8 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
- BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
- BCE_EMAC_MDIO_COMM_START_BUSY;
+ BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
+ BCE_EMAC_MDIO_COMM_START_BUSY;
REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
@@ -1535,8 +1579,8 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
}
if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
- BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
- __FILE__, __LINE__, phy, reg);
+ BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
+ "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
val = 0x0;
} else {
val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
@@ -1578,12 +1622,23 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
/* Make sure we are accessing the correct PHY address. */
if (phy != sc->bce_phy_addr) {
- DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY write!\n", phy);
+ DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
+ "for PHY write!\n", phy);
return(0);
}
DB_PRINT_PHY_REG(reg, val);
+ /*
+ * The 5709S PHY is an IEEE Clause 45 PHY
+ * with special mappings to work with IEEE
+ * Clause 22 register accesses.
+ */
+ if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+ if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
+ reg += 0x10;
+ }
+
if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
@@ -1595,8 +1650,8 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
}
val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
- BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
- BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
+ BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
+ BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
@@ -1611,7 +1666,7 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
BCE_PRINTF("%s(%d): PHY write timeout!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
@@ -2626,18 +2681,22 @@ bce_get_media(struct bce_softc *sc)
* for Copper or SerDes operation.
*/
if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
- DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for copper.\n");
+ DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
+ "for copper.\n");
goto bce_get_media_exit;
} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
- DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for dual media.\n");
+ DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
+ "for dual media.\n");
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
goto bce_get_media_exit;
}
if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
- strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
+ strap = (val &
+ BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
else
- strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
+ strap = (val &
+ BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
if (pci_get_function(sc->bce_dev) == 0) {
switch (strap) {
@@ -2645,11 +2704,13 @@ bce_get_media(struct bce_softc *sc)
case 0x5:
case 0x6:
DBPRINT(sc, BCE_INFO_LOAD,
- "BCM5709 s/w configured for SerDes.\n");
+ "BCM5709 s/w configured for SerDes.\n");
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
+ break;
default:
DBPRINT(sc, BCE_INFO_LOAD,
- "BCM5709 s/w configured for Copper.\n");
+ "BCM5709 s/w configured for Copper.\n");
+ break;
}
} else {
switch (strap) {
@@ -2657,11 +2718,13 @@ bce_get_media(struct bce_softc *sc)
case 0x2:
case 0x4:
DBPRINT(sc, BCE_INFO_LOAD,
- "BCM5709 s/w configured for SerDes.\n");
+ "BCM5709 s/w configured for SerDes.\n");
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
+ break;
default:
DBPRINT(sc, BCE_INFO_LOAD,
- "BCM5709 s/w configured for Copper.\n");
+ "BCM5709 s/w configured for Copper.\n");
+ break;
}
}
@@ -2669,17 +2732,26 @@ bce_get_media(struct bce_softc *sc)
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
+
sc->bce_flags |= BCE_NO_WOL_FLAG;
+
+ if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
+ sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
+
if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
+ /* 5708S/09S/16S use a separate PHY for SerDes. */
sc->bce_phy_addr = 2;
+
val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
- sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
- DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
+ sc->bce_phy_flags |=
+ BCE_PHY_2_5G_CAPABLE_FLAG;
+ DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
+ "capable adapter\n");
}
}
} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
bce_get_media_exit:
@@ -2691,6 +2763,37 @@ bce_get_media_exit:
/****************************************************************************/
+/* Performs PHY initialization required before MII drivers access the */
+/* device. */
+/* */
+/* Returns: */
+/* Nothing. */
+/****************************************************************************/
+static void
+bce_init_media(struct bce_softc *sc)
+{
+ if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+ /*
+ * Configure 5709S/5716S PHYs to use traditional IEEE
+ * Clause 22 method. Otherwise we have no way to attach
+ * the PHY in mii(4) layer. PHY specific configuration
+ * is done in mii layer.
+ */
+
+ /* Select auto-negotiation MMD of the PHY. */
+ bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+ BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
+ bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+ BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
+
+ /* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
+ bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+ BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+ }
+}
+
+
+/****************************************************************************/
/* Free any DMA memory owned by the driver. */
/* */
/* Scans through each data structre that requires DMA memory and frees */
@@ -2709,7 +2812,7 @@ bce_dma_free(struct bce_softc *sc)
/* Free, unmap, and destroy the status block. */
if (sc->status_block != NULL) {
bus_dmamem_free(
- sc->status_tag,
+ sc->status_tag,
sc->status_block,
sc->status_map);
sc->status_block = NULL;
@@ -2717,7 +2820,7 @@ bce_dma_free(struct bce_softc *sc)
if (sc->status_map != NULL) {
bus_dmamap_unload(
- sc->status_tag,
+ sc->status_tag,
sc->status_map);
bus_dmamap_destroy(sc->status_tag,
sc->status_map);
@@ -2733,7 +2836,7 @@ bce_dma_free(struct bce_softc *sc)
/* Free, unmap, and destroy the statistics block. */
if (sc->stats_block != NULL) {
bus_dmamem_free(
- sc->stats_tag,
+ sc->stats_tag,
sc->stats_block,
sc->stats_map);
sc->stats_block = NULL;
@@ -2741,7 +2844,7 @@ bce_dma_free(struct bce_softc *sc)
if (sc->stats_map != NULL) {
bus_dmamap_unload(
- sc->stats_tag,
+ sc->stats_tag,
sc->stats_map);
bus_dmamap_destroy(sc->stats_tag,
sc->stats_map);
@@ -2760,7 +2863,7 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < sc->ctx_pages; i++ ) {
if (sc->ctx_block[i] != NULL) {
bus_dmamem_free(
- sc->ctx_tag,
+ sc->ctx_tag,
sc->ctx_block[i],
sc->ctx_map[i]);
sc->ctx_block[i] = NULL;
@@ -2768,10 +2871,10 @@ bce_dma_free(struct bce_softc *sc)
if (sc->ctx_map[i] != NULL) {
bus_dmamap_unload(
- sc->ctx_tag,
- sc->ctx_map[i]);
+ sc->ctx_tag,
+ sc->ctx_map[i]);
bus_dmamap_destroy(
- sc->ctx_tag,
+ sc->ctx_tag,
sc->ctx_map[i]);
sc->ctx_map[i] = NULL;
}
@@ -2789,7 +2892,7 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < TX_PAGES; i++ ) {
if (sc->tx_bd_chain[i] != NULL) {
bus_dmamem_free(
- sc->tx_bd_chain_tag,
+ sc->tx_bd_chain_tag,
sc->tx_bd_chain[i],
sc->tx_bd_chain_map[i]);
sc->tx_bd_chain[i] = NULL;
@@ -2797,10 +2900,10 @@ bce_dma_free(struct bce_softc *sc)
if (sc->tx_bd_chain_map[i] != NULL) {
bus_dmamap_unload(
- sc->tx_bd_chain_tag,
- sc->tx_bd_chain_map[i]);
+ sc->tx_bd_chain_tag,
+ sc->tx_bd_chain_map[i]);
bus_dmamap_destroy(
- sc->tx_bd_chain_tag,
+ sc->tx_bd_chain_tag,
sc->tx_bd_chain_map[i]);
sc->tx_bd_chain_map[i] = NULL;
}
@@ -2817,7 +2920,7 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < RX_PAGES; i++ ) {
if (sc->rx_bd_chain[i] != NULL) {
bus_dmamem_free(
- sc->rx_bd_chain_tag,
+ sc->rx_bd_chain_tag,
sc->rx_bd_chain[i],
sc->rx_bd_chain_map[i]);
sc->rx_bd_chain[i] = NULL;
@@ -2825,10 +2928,10 @@ bce_dma_free(struct bce_softc *sc)
if (sc->rx_bd_chain_map[i] != NULL) {
bus_dmamap_unload(
- sc->rx_bd_chain_tag,
- sc->rx_bd_chain_map[i]);
+ sc->rx_bd_chain_tag,
+ sc->rx_bd_chain_map[i]);
bus_dmamap_destroy(
- sc->rx_bd_chain_tag,
+ sc->rx_bd_chain_tag,
sc->rx_bd_chain_map[i]);
sc->rx_bd_chain_map[i] = NULL;
}
@@ -2846,7 +2949,7 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < PG_PAGES; i++ ) {
if (sc->pg_bd_chain[i] != NULL) {
bus_dmamem_free(
- sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_tag,
sc->pg_bd_chain[i],
sc->pg_bd_chain_map[i]);
sc->pg_bd_chain[i] = NULL;
@@ -2854,10 +2957,10 @@ bce_dma_free(struct bce_softc *sc)
if (sc->pg_bd_chain_map[i] != NULL) {
bus_dmamap_unload(
- sc->pg_bd_chain_tag,
- sc->pg_bd_chain_map[i]);
+ sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_map[i]);
bus_dmamap_destroy(
- sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_tag,
sc->pg_bd_chain_map[i]);
sc->pg_bd_chain_map[i] = NULL;
}
@@ -2875,9 +2978,9 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < TOTAL_TX_BD; i++) {
if (sc->tx_mbuf_map[i] != NULL) {
bus_dmamap_unload(sc->tx_mbuf_tag,
- sc->tx_mbuf_map[i]);
+ sc->tx_mbuf_map[i]);
bus_dmamap_destroy(sc->tx_mbuf_tag,
- sc->tx_mbuf_map[i]);
+ sc->tx_mbuf_map[i]);
sc->tx_mbuf_map[i] = NULL;
}
}
@@ -2892,9 +2995,9 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < TOTAL_RX_BD; i++) {
if (sc->rx_mbuf_map[i] != NULL) {
bus_dmamap_unload(sc->rx_mbuf_tag,
- sc->rx_mbuf_map[i]);
+ sc->rx_mbuf_map[i]);
bus_dmamap_destroy(sc->rx_mbuf_tag,
- sc->rx_mbuf_map[i]);
+ sc->rx_mbuf_map[i]);
sc->rx_mbuf_map[i] = NULL;
}
}
@@ -2910,9 +3013,9 @@ bce_dma_free(struct bce_softc *sc)
for (i = 0; i < TOTAL_PG_BD; i++) {
if (sc->pg_mbuf_map[i] != NULL) {
bus_dmamap_unload(sc->pg_mbuf_tag,
- sc->pg_mbuf_map[i]);
+ sc->pg_mbuf_map[i]);
bus_dmamap_destroy(sc->pg_mbuf_tag,
- sc->pg_mbuf_map[i]);
+ sc->pg_mbuf_map[i]);
sc->pg_mbuf_map[i] = NULL;
}
}
@@ -3005,20 +3108,12 @@ bce_dma_alloc(device_t dev)
/*
* Allocate the parent bus DMA tag appropriate for PCI.
*/
- if (bus_dma_tag_create(NULL,
- 1,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- MAXBSIZE,
- BUS_SPACE_UNRESTRICTED,
- BUS_SPACE_MAXSIZE_32BIT,
- 0,
- NULL, NULL,
- &sc->parent_tag)) {
+ if (bus_dma_tag_create(NULL, 1, BCE_DMA_BOUNDARY,
+ sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
+ MAXBSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE_32BIT,
+ 0, NULL, NULL, &sc->parent_tag)) {
BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3028,117 +3123,89 @@ bce_dma_alloc(device_t dev)
* memory, map the memory into DMA space, and fetch the physical
* address of the block.
*/
- if (bus_dma_tag_create(sc->parent_tag,
- BCE_DMA_ALIGN,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- BCE_STATUS_BLK_SZ,
- 1,
- BCE_STATUS_BLK_SZ,
- 0,
- NULL, NULL,
- &sc->status_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate status block DMA tag!\n",
- __FILE__, __LINE__);
+ if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
+ BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
+ NULL, NULL, BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
+ 0, NULL, NULL, &sc->status_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate status block "
+ "DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
- if(bus_dmamem_alloc(sc->status_tag,
- (void **)&sc->status_block,
- BUS_DMA_NOWAIT,
- &sc->status_map)) {
- BCE_PRINTF("%s(%d): Could not allocate status block DMA memory!\n",
- __FILE__, __LINE__);
+ if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
+ BUS_DMA_NOWAIT, &sc->status_map)) {
+ BCE_PRINTF("%s(%d): Could not allocate status block "
+ "DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
- error = bus_dmamap_load(sc->status_tag,
- sc->status_map,
- sc->status_block,
- BCE_STATUS_BLK_SZ,
- bce_dma_map_addr,
- &sc->status_block_paddr,
- BUS_DMA_NOWAIT);
+ error = bus_dmamap_load(sc->status_tag, sc->status_map,
+ sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
+ &sc->status_block_paddr, BUS_DMA_NOWAIT);
if (error) {
- BCE_PRINTF("%s(%d): Could not map status block DMA memory!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Could not map status block "
+ "DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
- __FUNCTION__, (uintmax_t) sc->status_block_paddr);
+ __FUNCTION__, (uintmax_t) sc->status_block_paddr);
/*
* Create a DMA tag for the statistics block, allocate and clear the
* memory, map the memory into DMA space, and fetch the physical
* address of the block.
*/
- if (bus_dma_tag_create(sc->parent_tag,
- BCE_DMA_ALIGN,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- BCE_STATS_BLK_SZ,
- 1,
- BCE_STATS_BLK_SZ,
- 0,
- NULL, NULL,
- &sc->stats_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate statistics block DMA tag!\n",
- __FILE__, __LINE__);
+ if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
+ BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
+ NULL, NULL, BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
+ 0, NULL, NULL, &sc->stats_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate statistics block "
+ "DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
- if (bus_dmamem_alloc(sc->stats_tag,
- (void **)&sc->stats_block,
- BUS_DMA_NOWAIT,
- &sc->stats_map)) {
- BCE_PRINTF("%s(%d): Could not allocate statistics block DMA memory!\n",
- __FILE__, __LINE__);
+ if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
+ BUS_DMA_NOWAIT, &sc->stats_map)) {
+ BCE_PRINTF("%s(%d): Could not allocate statistics block "
+ "DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
- error = bus_dmamap_load(sc->stats_tag,
- sc->stats_map,
- sc->stats_block,
- BCE_STATS_BLK_SZ,
- bce_dma_map_addr,
- &sc->stats_block_paddr,
- BUS_DMA_NOWAIT);
+ error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
+ sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
+ &sc->stats_block_paddr, BUS_DMA_NOWAIT);
if(error) {
- BCE_PRINTF("%s(%d): Could not map statistics block DMA memory!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Could not map statistics block "
+ "DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
- __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
+ __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
/* BCM5709 uses host memory as cache for context memory. */
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
if (sc->ctx_pages == 0)
sc->ctx_pages = 1;
DBRUNIF((sc->ctx_pages > 512),
- BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
- __FILE__, __LINE__, sc->ctx_pages));
+ BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
+ __FILE__, __LINE__, sc->ctx_pages));
/*
* Create a DMA tag for the context pages,
@@ -3146,20 +3213,12 @@ bce_dma_alloc(device_t dev)
* memory into DMA space, and fetch the
* physical address of the block.
*/
- if(bus_dma_tag_create(sc->parent_tag,
- BCM_PAGE_SIZE,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- BCM_PAGE_SIZE,
- 1,
- BCM_PAGE_SIZE,
- 0,
- NULL, NULL,
- &sc->ctx_tag)) {
+ if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
+ BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
+ NULL, NULL, BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
+ 0, NULL, NULL, &sc->ctx_tag)) {
BCE_PRINTF("%s(%d): Could not allocate CTX DMA tag!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3167,34 +3226,30 @@ bce_dma_alloc(device_t dev)
for (i = 0; i < sc->ctx_pages; i++) {
if(bus_dmamem_alloc(sc->ctx_tag,
- (void **)&sc->ctx_block[i],
- BUS_DMA_NOWAIT,
- &sc->ctx_map[i])) {
+ (void **)&sc->ctx_block[i],
+ BUS_DMA_NOWAIT,
+ &sc->ctx_map[i])) {
BCE_PRINTF("%s(%d): Could not allocate CTX "
- "DMA memory!\n", __FILE__, __LINE__);
+ "DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
bzero((char *)sc->ctx_block[i], BCM_PAGE_SIZE);
- error = bus_dmamap_load(sc->ctx_tag,
- sc->ctx_map[i],
- sc->ctx_block[i],
- BCM_PAGE_SIZE,
- bce_dma_map_addr,
- &sc->ctx_paddr[i],
- BUS_DMA_NOWAIT);
+ error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
+ sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
+ &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
if (error) {
- BCE_PRINTF("%s(%d): Could not map CTX DMA memory!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Could not map CTX "
+ "DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
- __FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
+ __FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
}
}
@@ -3203,53 +3258,41 @@ bce_dma_alloc(device_t dev)
* allocate and clear the memory, and fetch the
* physical address of the block.
*/
- if(bus_dma_tag_create(sc->parent_tag,
- BCM_PAGE_SIZE,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- BCE_TX_CHAIN_PAGE_SZ,
- 1,
- BCE_TX_CHAIN_PAGE_SZ,
- 0,
- NULL, NULL,
- &sc->tx_bd_chain_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
- __FILE__, __LINE__);
+ if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
+ sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
+ BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
+ NULL, NULL, &sc->tx_bd_chain_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain "
+ "DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
for (i = 0; i < TX_PAGES; i++) {
- if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
- (void **)&sc->tx_bd_chain[i],
- BUS_DMA_NOWAIT,
- &sc->tx_bd_chain_map[i])) {
+ if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
+ (void **)&sc->tx_bd_chain[i], BUS_DMA_NOWAIT,
+ &sc->tx_bd_chain_map[i])) {
BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
- "chain DMA memory!\n", __FILE__, __LINE__);
+ "chain DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
error = bus_dmamap_load(sc->tx_bd_chain_tag,
- sc->tx_bd_chain_map[i],
- sc->tx_bd_chain[i],
- BCE_TX_CHAIN_PAGE_SZ,
- bce_dma_map_addr,
- &sc->tx_bd_chain_paddr[i],
- BUS_DMA_NOWAIT);
+ sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
+ BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
+ &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
if (error) {
- BCE_PRINTF("%s(%d): Could not map TX descriptor chain DMA memory!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Could not map TX descriptor "
+ "chain DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
- __FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
+ __FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
}
/* Check the required size before mapping to conserve resources. */
@@ -3264,20 +3307,11 @@ bce_dma_alloc(device_t dev)
}
/* Create a DMA tag for TX mbufs. */
- if (bus_dma_tag_create(sc->parent_tag,
- 1,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- max_size,
- max_segments,
- max_seg_size,
- 0,
- NULL, NULL,
- &sc->tx_mbuf_tag)) {
+ if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
+ sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
+ max_segments, max_seg_size, 0, NULL, NULL, &sc->tx_mbuf_tag)) {
BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3286,8 +3320,8 @@ bce_dma_alloc(device_t dev)
for (i = 0; i < TOTAL_TX_BD; i++) {
if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
&sc->tx_mbuf_map[i])) {
- BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA map!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
+ "map!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3298,20 +3332,13 @@ bce_dma_alloc(device_t dev)
* allocate and clear the memory, and fetch the physical
* address of the blocks.
*/
- if (bus_dma_tag_create(sc->parent_tag,
- BCM_PAGE_SIZE,
- BCE_DMA_BOUNDARY,
- BUS_SPACE_MAXADDR,
- sc->max_bus_addr,
- NULL, NULL,
- BCE_RX_CHAIN_PAGE_SZ,
- 1,
- BCE_RX_CHAIN_PAGE_SZ,
- 0,
- NULL, NULL,
- &sc->rx_bd_chain_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
- __FILE__, __LINE__);
+ if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
+ BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
+ sc->max_bus_addr, NULL, NULL,
+ BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
+ 0, NULL, NULL, &sc->rx_bd_chain_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
+ "DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3319,11 +3346,10 @@ bce_dma_alloc(device_t dev)
for (i = 0; i < RX_PAGES; i++) {
if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
- (void **)&sc->rx_bd_chain[i],
- BUS_DMA_NOWAIT,
- &sc->rx_bd_chain_map[i])) {
- BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
- "DMA memory!\n", __FILE__, __LINE__);
+ (void **)&sc->rx_bd_chain[i], BUS_DMA_NOWAIT,
+ &sc->rx_bd_chain_map[i])) {
+ BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
+ "chain DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3331,22 +3357,19 @@ bce_dma_alloc(device_t dev)
bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
error = bus_dmamap_load(sc->rx_bd_chain_tag,
- sc->rx_bd_chain_map[i],
- sc->rx_bd_chain[i],
- BCE_RX_CHAIN_PAGE_SZ,
- bce_dma_map_addr,
- &sc->rx_bd_chain_paddr[i],
- BUS_DMA_NOWAIT);
+ sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
+ BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
+ &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
if (error) {
- BCE_PRINTF("%s(%d): Could not map RX descriptor chain DMA memory!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Could not map RX descriptor "
+ "chain DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
- __FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
+ __FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
}
/*
@@ -3361,23 +3384,14 @@ bce_dma_alloc(device_t dev)
max_segments = 1;
DBPRINT(sc, BCE_INFO, "%s(): Creating rx_mbuf_tag (max size = 0x%jX "
- "max segments = %d, max segment size = 0x%jX)\n", __FUNCTION__,
- (uintmax_t) max_size, max_segments, (uintmax_t) max_seg_size);
-
- if (bus_dma_tag_create(sc->parent_tag,
- 1,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- max_size,
- max_segments,
- max_seg_size,
- 0,
- NULL, NULL,
- &sc->rx_mbuf_tag)) {
+ "max segments = %d, max segment size = 0x%jX)\n", __FUNCTION__,
+ (uintmax_t) max_size, max_segments, (uintmax_t) max_seg_size);
+
+ if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
+ sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
+ max_segments, max_seg_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3385,9 +3399,9 @@ bce_dma_alloc(device_t dev)
/* Create DMA maps for the RX mbuf clusters. */
for (i = 0; i < TOTAL_RX_BD; i++) {
if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
- &sc->rx_mbuf_map[i])) {
- BCE_PRINTF("%s(%d): Unable to create RX mbuf DMA map!\n",
- __FILE__, __LINE__);
+ &sc->rx_mbuf_map[i])) {
+ BCE_PRINTF("%s(%d): Unable to create RX mbuf "
+ "DMA map!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3399,20 +3413,12 @@ bce_dma_alloc(device_t dev)
* allocate and clear the memory, and fetch the physical
* address of the blocks.
*/
- if (bus_dma_tag_create(sc->parent_tag,
- BCM_PAGE_SIZE,
- BCE_DMA_BOUNDARY,
- BUS_SPACE_MAXADDR,
- sc->max_bus_addr,
- NULL, NULL,
- BCE_PG_CHAIN_PAGE_SZ,
- 1,
- BCE_PG_CHAIN_PAGE_SZ,
- 0,
- NULL, NULL,
- &sc->pg_bd_chain_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate page descriptor chain DMA tag!\n",
- __FILE__, __LINE__);
+ if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
+ BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
+ NULL, NULL, BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
+ 0, NULL, NULL, &sc->pg_bd_chain_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate page descriptor "
+ "chain DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3420,56 +3426,44 @@ bce_dma_alloc(device_t dev)
for (i = 0; i < PG_PAGES; i++) {
if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
- (void **)&sc->pg_bd_chain[i],
- BUS_DMA_NOWAIT,
- &sc->pg_bd_chain_map[i])) {
- BCE_PRINTF("%s(%d): Could not allocate page descriptor chain "
- "DMA memory!\n", __FILE__, __LINE__);
+ (void **)&sc->pg_bd_chain[i], BUS_DMA_NOWAIT,
+ &sc->pg_bd_chain_map[i])) {
+ BCE_PRINTF("%s(%d): Could not allocate page "
+ "descriptor chain DMA memory!\n",
+ __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
- error = bus_dmamap_load(sc->pg_bd_chain_tag,
- sc->pg_bd_chain_map[i],
- sc->pg_bd_chain[i],
- BCE_PG_CHAIN_PAGE_SZ,
- bce_dma_map_addr,
- &sc->pg_bd_chain_paddr[i],
- BUS_DMA_NOWAIT);
+ error = bus_dmamap_load(sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
+ BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
+ &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
if (error) {
- BCE_PRINTF("%s(%d): Could not map page descriptor chain DMA memory!\n",
- __FILE__, __LINE__);
+ BCE_PRINTF("%s(%d): Could not map page descriptor "
+ "chain DMA memory!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
- __FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
+ __FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
}
/*
* Create a DMA tag for page mbufs.
*/
max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
- MCLBYTES : sc->pg_bd_mbuf_alloc_size);
-
- if (bus_dma_tag_create(sc->parent_tag,
- 1,
- BCE_DMA_BOUNDARY,
- sc->max_bus_addr,
- BUS_SPACE_MAXADDR,
- NULL, NULL,
- max_size,
- 1,
- max_seg_size,
- 0,
- NULL, NULL,
- &sc->pg_mbuf_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate page mbuf DMA tag!\n",
- __FILE__, __LINE__);
+ MCLBYTES : sc->pg_bd_mbuf_alloc_size);
+
+ if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
+ sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
+ max_size, 1, max_seg_size, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate page mbuf "
+ "DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3477,9 +3471,9 @@ bce_dma_alloc(device_t dev)
/* Create DMA maps for the page mbuf clusters. */
for (i = 0; i < TOTAL_PG_BD; i++) {
if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
- &sc->pg_mbuf_map[i])) {
- BCE_PRINTF("%s(%d): Unable to create page mbuf DMA map!\n",
- __FILE__, __LINE__);
+ &sc->pg_mbuf_map[i])) {
+ BCE_PRINTF("%s(%d): Unable to create page mbuf "
+ "DMA map!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
@@ -3520,7 +3514,7 @@ bce_release_resources(struct bce_softc *sc)
if (sc->bce_res_irq != NULL) {
DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
- sc->bce_res_irq);
+ sc->bce_res_irq);
}
if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
@@ -3530,7 +3524,8 @@ bce_release_resources(struct bce_softc *sc)
if (sc->bce_res_mem != NULL) {
DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
- bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->bce_res_mem);
+ bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
+ sc->bce_res_mem);
}
if (sc->bce_ifp != NULL) {
@@ -3563,7 +3558,7 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
DBENTER(BCE_VERBOSE_RESET);
/* Don't waste any time if we've timed out before. */
- if (sc->bce_fw_timed_out) {
+ if (sc->bce_fw_timed_out == TRUE) {
rc = EBUSY;
goto bce_fw_sync_exit;
}
@@ -3572,8 +3567,8 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
sc->bce_fw_wr_seq++;
msg_data |= sc->bce_fw_wr_seq;
- DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = 0x%08X\n",
- msg_data);
+ DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
+ "0x%08X\n", msg_data);
/* Send the message to the bootcode driver mailbox. */
bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
@@ -3589,18 +3584,17 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
/* If we've timed out, tell the bootcode that we've stopped waiting. */
if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
- ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
+ ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
- "msg_data = 0x%08X\n",
- __FILE__, __LINE__, msg_data);
+ "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
msg_data &= ~BCE_DRV_MSG_CODE;
msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
- sc->bce_fw_timed_out = 1;
+ sc->bce_fw_timed_out = TRUE;
rc = EBUSY;
}
@@ -3728,9 +3722,9 @@ bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
}
}
- /* Clear the pre-fetch instruction and set the FW start address. */
- REG_WR_IND(sc, cpu_reg->inst, 0);
- REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
+ /* Clear the pre-fetch instruction and set the FW start address. */
+ REG_WR_IND(sc, cpu_reg->inst, 0);
+ REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
DBEXIT(BCE_VERBOSE_RESET);
}
@@ -3774,11 +3768,11 @@ bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
DBENTER(BCE_VERBOSE_RESET);
- /* Halt the CPU. */
- val = REG_RD_IND(sc, cpu_reg->mode);
- val |= cpu_reg->mode_value_halt;
- REG_WR_IND(sc, cpu_reg->mode, val);
- REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
+ /* Halt the CPU. */
+ val = REG_RD_IND(sc, cpu_reg->mode);
+ val |= cpu_reg->mode_value_halt;
+ REG_WR_IND(sc, cpu_reg->mode, val);
+ REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
DBEXIT(BCE_VERBOSE_RESET);
}
@@ -4106,7 +4100,7 @@ bce_init_tpat_cpu(struct bce_softc *sc)
DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
bce_load_cpu_fw(sc, &cpu_reg, &fw);
- bce_start_cpu(sc, &cpu_reg);
+ bce_start_cpu(sc, &cpu_reg);
DBEXIT(BCE_VERBOSE_RESET);
}
@@ -4204,7 +4198,7 @@ bce_init_cp_cpu(struct bce_softc *sc)
DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
bce_load_cpu_fw(sc, &cpu_reg, &fw);
- bce_start_cpu(sc, &cpu_reg);
+ bce_start_cpu(sc, &cpu_reg);
DBEXIT(BCE_VERBOSE_RESET);
}
@@ -4302,7 +4296,7 @@ bce_init_com_cpu(struct bce_softc *sc)
DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
bce_load_cpu_fw(sc, &cpu_reg, &fw);
- bce_start_cpu(sc, &cpu_reg);
+ bce_start_cpu(sc, &cpu_reg);
DBEXIT(BCE_VERBOSE_RESET);
}
@@ -4368,7 +4362,7 @@ bce_init_ctx(struct bce_softc *sc)
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
int i, retry_cnt = CTX_INIT_RETRY_COUNT;
u32 val;
@@ -4379,7 +4373,8 @@ bce_init_ctx(struct bce_softc *sc)
* in host memory so prepare the host memory
* for access.
*/
- val = BCE_CTX_COMMAND_ENABLED | BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
+ val = BCE_CTX_COMMAND_ENABLED |
+ BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
val |= (BCM_PAGE_BITS - 8) << 16;
REG_WR(sc, BCE_CTX_COMMAND, val);
@@ -4393,33 +4388,34 @@ bce_init_ctx(struct bce_softc *sc)
/* ToDo: Consider returning an error here. */
DBRUNIF((val & BCE_CTX_COMMAND_MEM_INIT),
- BCE_PRINTF("%s(): Context memory initialization failed!\n",
- __FUNCTION__));
+ BCE_PRINTF("%s(): Context memory initialization "
+ "failed!\n", __FUNCTION__));
for (i = 0; i < sc->ctx_pages; i++) {
int j;
- /* Set the physical address of the context memory cache. */
+ /* Set the physical address of the context memory. */
REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
- BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
- BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
+ BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
+ BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
- BCE_ADDR_HI(sc->ctx_paddr[i]));
+ BCE_ADDR_HI(sc->ctx_paddr[i]));
REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
- BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
+ BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
- /* Verify that the context memory write was successful. */
+ /* Verify the context memory write was successful. */
for (j = 0; j < retry_cnt; j++) {
val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
- if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
+ if ((val &
+ BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
break;
DELAY(5);
}
/* ToDo: Consider returning an error here. */
DBRUNIF((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ),
- BCE_PRINTF("%s(): Failed to initialize context page %d!\n",
- __FUNCTION__, i));
+ BCE_PRINTF("%s(): Failed to initialize "
+ "context page %d!\n", __FUNCTION__, i));
}
} else {
u32 vcid_addr, offset;
@@ -4440,9 +4436,9 @@ bce_init_ctx(struct bce_softc *sc)
REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
- for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
- CTX_WR(sc, 0x00, offset, 0);
- }
+ for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
+ CTX_WR(sc, 0x00, offset, 0);
+ }
REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
@@ -4585,7 +4581,7 @@ bce_stop(struct bce_softc *sc)
ifp->if_flags = itmp;
sc->watchdog_timer = 0;
- sc->bce_link = 0;
+ sc->bce_link_up = FALSE;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
@@ -4622,7 +4618,8 @@ bce_reset(struct bce_softc *sc, u32 reset_code)
}
/* Assume bootcode is running. */
- sc->bce_fw_timed_out = 0;
+ sc->bce_fw_timed_out = FALSE;
+ sc->bce_drv_cardiac_arrest = FALSE;
/* Give the firmware a chance to prepare for the reset. */
rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
@@ -4682,7 +4679,8 @@ bce_reset(struct bce_softc *sc, u32 reset_code)
}
/* Just completed a reset, assume that firmware is running again. */
- sc->bce_fw_timed_out = 0;
+ sc->bce_fw_timed_out = FALSE;
+ sc->bce_drv_cardiac_arrest = FALSE;
/* Wait for the firmware to finish its initialization. */
rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
@@ -4738,9 +4736,9 @@ bce_chipinit(struct bce_softc *sc)
/* Enable the RX_V2P and Context state machines before access. */
REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
- BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
- BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
- BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
+ BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
+ BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
+ BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
/* Initialize context mapping and zero out the quick contexts. */
bce_init_ctx(sc);
@@ -4748,11 +4746,11 @@ bce_chipinit(struct bce_softc *sc)
/* Initialize the on-boards CPUs */
bce_init_cpus(sc);
- /* Enable management frames (NC-SI) to flow to the MCP. */
- if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
- val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
- REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
- }
+ /* Enable management frames (NC-SI) to flow to the MCP. */
+ if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+ val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
+ REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
+ }
/* Prepare NVRAM for access. */
if (bce_init_nvram(sc)) {
@@ -4830,56 +4828,56 @@ bce_blockinit(struct bce_softc *sc)
/* Program the physical address of the status block. */
REG_WR(sc, BCE_HC_STATUS_ADDR_L,
- BCE_ADDR_LO(sc->status_block_paddr));
+ BCE_ADDR_LO(sc->status_block_paddr));
REG_WR(sc, BCE_HC_STATUS_ADDR_H,
- BCE_ADDR_HI(sc->status_block_paddr));
+ BCE_ADDR_HI(sc->status_block_paddr));
/* Program the physical address of the statistics block. */
REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
- BCE_ADDR_LO(sc->stats_block_paddr));
+ BCE_ADDR_LO(sc->stats_block_paddr));
REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
- BCE_ADDR_HI(sc->stats_block_paddr));
+ BCE_ADDR_HI(sc->stats_block_paddr));
/* Program various host coalescing parameters. */
REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
- (sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
+ (sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
- (sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
+ (sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
- (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
+ (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
REG_WR(sc, BCE_HC_TX_TICKS,
- (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
+ (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
REG_WR(sc, BCE_HC_RX_TICKS,
- (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
+ (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
REG_WR(sc, BCE_HC_COM_TICKS,
- (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
+ (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
REG_WR(sc, BCE_HC_CMD_TICKS,
- (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
+ (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
REG_WR(sc, BCE_HC_STATS_TICKS,
- (sc->bce_stats_ticks & 0xffff00));
+ (sc->bce_stats_ticks & 0xffff00));
REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
/* Configure the Host Coalescing block. */
val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
- BCE_HC_CONFIG_COLLECT_STATS;
+ BCE_HC_CONFIG_COLLECT_STATS;
#if 0
/* ToDo: Add MSI-X support. */
if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
- BCE_HC_SB_CONFIG_1;
+ BCE_HC_SB_CONFIG_1;
REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
- BCE_HC_SB_CONFIG_1_ONE_SHOT);
+ BCE_HC_SB_CONFIG_1_ONE_SHOT);
REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
- (sc->tx_quick_cons_trip_int << 16) |
- sc->tx_quick_cons_trip);
+ (sc->tx_quick_cons_trip_int << 16) |
+ sc->tx_quick_cons_trip);
REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
- (sc->tx_ticks_int << 16) | sc->tx_ticks);
+ (sc->tx_ticks_int << 16) | sc->tx_ticks);
val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
}
@@ -4906,49 +4904,53 @@ bce_blockinit(struct bce_softc *sc)
reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
- BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
- __FILE__, __LINE__);
- reg = 0);
+ BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
+ __FILE__, __LINE__);
+ reg = 0);
if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
BCE_DEV_INFO_SIGNATURE_MAGIC) {
BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
- "Expected: 08%08X\n", __FILE__, __LINE__,
- (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
- BCE_DEV_INFO_SIGNATURE_MAGIC);
+ "Expected: 08%08X\n", __FILE__, __LINE__,
+ (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
+ BCE_DEV_INFO_SIGNATURE_MAGIC);
rc = ENODEV;
goto bce_blockinit_exit;
}
/* Enable DMA */
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
}
- /* Allow bootcode to apply any additional fixes before enabling MAC. */
- rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
+ /* Allow bootcode to apply additional fixes before enabling MAC. */
+ rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 |
+ BCE_DRV_MSG_CODE_RESET);
/* Enable link state change interrupt generation. */
REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
- /* Enable the RXP. */
- bce_start_rxp_cpu(sc);
+ /* Enable the RXP. */
+ bce_start_rxp_cpu(sc);
- /* Disable management frames (NC-SI) from flowing to the MCP. */
- if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
- val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
- REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
- }
+ /* Disable management frames (NC-SI) from flowing to the MCP. */
+ if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+ val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) &
+ ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
+ REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
+ }
/* Enable all remaining blocks in the MAC. */
- if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
- REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT_XI);
+ if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
+ REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
+ BCE_MISC_ENABLE_DEFAULT_XI);
else
- REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
+ REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
+ BCE_MISC_ENABLE_DEFAULT);
REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
DELAY(20);
@@ -4971,7 +4973,7 @@ bce_blockinit_exit:
/****************************************************************************/
static int
bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
- u16 *chain_prod, u32 *prod_bseq)
+ u16 *chain_prod, u32 *prod_bseq)
{
bus_dmamap_t map;
bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
@@ -4989,8 +4991,9 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
__FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
- DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
- "prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
+ DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
+ "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
+ *prod, *chain_prod, *prod_bseq);
/* Update some debug statistic counters */
DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
@@ -5002,10 +5005,10 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
/* Simulate an mbuf allocation failure. */
DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
- sc->mbuf_alloc_failed_count++;
- sc->mbuf_alloc_failed_sim_count++;
- rc = ENOBUFS;
- goto bce_get_rx_buf_exit);
+ sc->mbuf_alloc_failed_count++;
+ sc->mbuf_alloc_failed_sim_count++;
+ rc = ENOBUFS;
+ goto bce_get_rx_buf_exit);
/* This is a new mbuf allocation. */
#ifdef BCE_JUMBO_HDRSPLIT
@@ -5014,7 +5017,8 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
else
- m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, sc->rx_bd_mbuf_alloc_size);
+ m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
+ sc->rx_bd_mbuf_alloc_size);
#endif
if (m_new == NULL) {
@@ -5046,7 +5050,7 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
/* Handle any mapping errors. */
if (error) {
BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain (%d)!\n",
- __FILE__, __LINE__, error);
+ __FILE__, __LINE__, error);
sc->dma_map_addr_rx_failed_count++;
m_freem(m_new);
@@ -5059,9 +5063,7 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
/* All mbufs must map to a single segment. */
KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
- __FUNCTION__, nsegs));
-
- /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
+ __FUNCTION__, nsegs));
/* Setup the rx_bd for the segment. */
rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
@@ -5076,11 +5078,12 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
sc->rx_mbuf_ptr[*chain_prod] = m_new;
sc->free_rx_bd -= nsegs;
- DBRUNMSG(BCE_INSANE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod,
- nsegs));
+ DBRUNMSG(BCE_INSANE_RECV,
+ bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
- DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
- "prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
+ DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
+ "chain_prod = 0x%04X, prod_bseq = 0x%08X\n",
+ __FUNCTION__, *prod, *chain_prod, *prod_bseq);
bce_get_rx_buf_exit:
DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
@@ -5091,7 +5094,7 @@ bce_get_rx_buf_exit:
#ifdef BCE_JUMBO_HDRSPLIT
/****************************************************************************/
-/* Encapsulate an mbuf cluster into the page chain. */
+/* Encapsulate an mbuf cluster into the page chain. */
/* */
/* Returns: */
/* 0 for success, positive value for failure. */
@@ -5113,15 +5116,15 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
/* Make sure the inputs are valid. */
DBRUNIF((*prod_idx > MAX_PG_BD),
- BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
- __FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
+ BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
+ __FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
- "chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
+ "chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
/* Update counters if we've hit a new low or run out of pages. */
DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
- sc->pg_low_watermark = sc->free_pg_bd);
+ sc->pg_low_watermark = sc->free_pg_bd);
DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
/* Check whether this is a new mbuf allocation. */
@@ -5129,10 +5132,10 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
/* Simulate an mbuf allocation failure. */
DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
- sc->mbuf_alloc_failed_count++;
- sc->mbuf_alloc_failed_sim_count++;
- rc = ENOBUFS;
- goto bce_get_pg_buf_exit);
+ sc->mbuf_alloc_failed_count++;
+ sc->mbuf_alloc_failed_sim_count++;
+ rc = ENOBUFS;
+ goto bce_get_pg_buf_exit);
/* This is a new mbuf allocation. */
m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
@@ -5156,12 +5159,13 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
/* Map the mbuf cluster into device memory. */
map = sc->pg_mbuf_map[*prod_idx];
error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
- sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, &busaddr, BUS_DMA_NOWAIT);
+ sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr,
+ &busaddr, BUS_DMA_NOWAIT);
/* Handle any mapping errors. */
if (error) {
BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
m_freem(m_new);
DBRUN(sc->debug_pg_mbuf_alloc--);
@@ -5187,11 +5191,11 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
sc->pg_mbuf_ptr[*prod_idx] = m_new;
sc->free_pg_bd--;
- DBRUNMSG(BCE_INSANE_RECV, bce_dump_pg_mbuf_chain(sc, debug_prod_idx,
- 1));
+ DBRUNMSG(BCE_INSANE_RECV,
+ bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
- "prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
+ "prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
bce_get_pg_buf_exit:
DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
@@ -5200,6 +5204,7 @@ bce_get_pg_buf_exit:
}
#endif /* BCE_JUMBO_HDRSPLIT */
+
/****************************************************************************/
/* Initialize the TX context memory. */
/* */
@@ -5217,16 +5222,20 @@ bce_init_tx_context(struct bce_softc *sc)
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
/* Set the CID type to support an L2 connection. */
- val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
+ val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI |
+ BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
- CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE_XI, val);
+ CTX_WR(sc, GET_CID_ADDR(TX_CID),
+ BCE_L2CTX_TX_CMD_TYPE_XI, val);
/* Point the hardware to the first page in the chain. */
val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
- CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
+ CTX_WR(sc, GET_CID_ADDR(TX_CID),
+ BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
- CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
+ CTX_WR(sc, GET_CID_ADDR(TX_CID),
+ BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
} else {
/* Set the CID type to support an L2 connection. */
val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
@@ -5236,9 +5245,11 @@ bce_init_tx_context(struct bce_softc *sc)
/* Point the hardware to the first page in the chain. */
val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
- CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
+ CTX_WR(sc, GET_CID_ADDR(TX_CID),
+ BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
- CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
+ CTX_WR(sc, GET_CID_ADDR(TX_CID),
+ BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
}
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
@@ -5265,7 +5276,7 @@ bce_init_tx_chain(struct bce_softc *sc)
sc->tx_prod_bseq = 0;
sc->used_tx_bd = 0;
sc->max_tx_bd = USABLE_TX_BD;
- DBRUN(sc->tx_hi_watermark = USABLE_TX_BD);
+ DBRUN(sc->tx_hi_watermark = 0);
DBRUN(sc->tx_full_count = 0);
/*
@@ -5320,8 +5331,9 @@ bce_free_tx_chain(struct bce_softc *sc)
for (i = 0; i < TOTAL_TX_BD; i++) {
if (sc->tx_mbuf_ptr[i] != NULL) {
if (sc->tx_mbuf_map[i] != NULL)
- bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
- BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_sync(sc->tx_mbuf_tag,
+ sc->tx_mbuf_map[i],
+ BUS_DMASYNC_POSTWRITE);
m_freem(sc->tx_mbuf_ptr[i]);
sc->tx_mbuf_ptr[i] = NULL;
DBRUN(sc->debug_tx_mbuf_alloc--);
@@ -5332,13 +5344,13 @@ bce_free_tx_chain(struct bce_softc *sc)
for (i = 0; i < TX_PAGES; i++)
bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
- sc->used_tx_bd = 0;
+ sc->used_tx_bd = 0;
/* Check if we lost any mbufs in the process. */
DBRUNIF((sc->debug_tx_mbuf_alloc),
- BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
- "from tx chain!\n",
- __FILE__, __LINE__, sc->debug_tx_mbuf_alloc));
+ BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
+ "from tx chain!\n", __FILE__, __LINE__,
+ sc->debug_tx_mbuf_alloc));
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
}
@@ -5357,10 +5369,10 @@ bce_init_rx_context(struct bce_softc *sc)
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
- /* Initialize the type, size, and BD cache levels for the RX context. */
+ /* Init the type, size, and BD cache levels for the RX context. */
val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
- BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
- (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
+ BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
+ (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
/*
* Set the level for generating pause frames
@@ -5370,7 +5382,7 @@ bce_init_rx_context(struct bce_softc *sc)
* watermark).
*/
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
u32 lo_water, hi_water;
lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
@@ -5391,7 +5403,7 @@ bce_init_rx_context(struct bce_softc *sc)
/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
val = REG_RD(sc, BCE_MQ_MAP_L2_5);
REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
}
@@ -5419,7 +5431,7 @@ bce_init_rx_chain(struct bce_softc *sc)
int i, rc = 0;
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
- BCE_VERBOSE_CTX);
+ BCE_VERBOSE_CTX);
/* Initialize the RX producer and consumer indices. */
sc->rx_prod = 0;
@@ -5427,8 +5439,6 @@ bce_init_rx_chain(struct bce_softc *sc)
sc->rx_prod_bseq = 0;
sc->free_rx_bd = USABLE_RX_BD;
sc->max_rx_bd = USABLE_RX_BD;
- DBRUN(sc->rx_low_watermark = sc->max_rx_bd);
- DBRUN(sc->rx_empty_count = 0);
/* Initialize the RX next pointer chain entries. */
for (i = 0; i < RX_PAGES; i++) {
@@ -5443,13 +5453,17 @@ bce_init_rx_chain(struct bce_softc *sc)
j = i + 1;
/* Setup the chain page pointers. */
- rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
- rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
+ rxbd->rx_bd_haddr_hi =
+ htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
+ rxbd->rx_bd_haddr_lo =
+ htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
}
/* Fill up the RX chain. */
bce_fill_rx_chain(sc);
+ DBRUN(sc->rx_low_watermark = USABLE_RX_BD);
+ DBRUN(sc->rx_empty_count = 0);
for (i = 0; i < RX_PAGES; i++) {
bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -5457,10 +5471,12 @@ bce_init_rx_chain(struct bce_softc *sc)
bce_init_rx_context(sc);
- DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
+ DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD));
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
- BCE_VERBOSE_CTX);
+ BCE_VERBOSE_CTX);
+
/* ToDo: Are there possible failure modes here? */
+
return(rc);
}
@@ -5479,7 +5495,7 @@ bce_fill_rx_chain(struct bce_softc *sc)
u32 prod_bseq;
DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
- BCE_VERBOSE_CTX);
+ BCE_VERBOSE_CTX);
/* Get the RX chain producer indices. */
prod = sc->rx_prod;
@@ -5499,6 +5515,7 @@ bce_fill_rx_chain(struct bce_softc *sc)
sc->rx_prod = prod;
sc->rx_prod_bseq = prod_bseq;
+ /* We should never end up pointing to a next page pointer. */
DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
__FUNCTION__, sc->rx_prod));
@@ -5510,7 +5527,7 @@ bce_fill_rx_chain(struct bce_softc *sc)
sc->rx_prod_bseq);
DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
- BCE_VERBOSE_CTX);
+ BCE_VERBOSE_CTX);
}
@@ -5531,8 +5548,9 @@ bce_free_rx_chain(struct bce_softc *sc)
for (i = 0; i < TOTAL_RX_BD; i++) {
if (sc->rx_mbuf_ptr[i] != NULL) {
if (sc->rx_mbuf_map[i] != NULL)
- bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
- BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(sc->rx_mbuf_tag,
+ sc->rx_mbuf_map[i],
+ BUS_DMASYNC_POSTREAD);
m_freem(sc->rx_mbuf_ptr[i]);
sc->rx_mbuf_ptr[i] = NULL;
DBRUN(sc->debug_rx_mbuf_alloc--);
@@ -5541,14 +5559,17 @@ bce_free_rx_chain(struct bce_softc *sc)
/* Clear each RX chain page. */
for (i = 0; i < RX_PAGES; i++)
- bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
+ if (sc->rx_bd_chain[i] != NULL) {
+ bzero((char *)sc->rx_bd_chain[i],
+ BCE_RX_CHAIN_PAGE_SZ);
+ }
sc->free_rx_bd = sc->max_rx_bd;
/* Check if we lost any mbufs in the process. */
DBRUNIF((sc->debug_rx_mbuf_alloc),
- BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
- __FUNCTION__, sc->debug_rx_mbuf_alloc));
+ BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
+ __FUNCTION__, sc->debug_rx_mbuf_alloc));
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
}
@@ -5763,12 +5784,12 @@ bce_ifmedia_upd_locked(struct ifnet *ifp)
/* Make sure the MII bus has been enumerated. */
if (mii) {
- sc->bce_link = 0;
+ sc->bce_link_up = FALSE;
if (mii->mii_instance) {
struct mii_softc *miisc;
LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
+ mii_phy_reset(miisc);
}
mii_mediachg(mii);
}
@@ -5818,26 +5839,28 @@ bce_phy_intr(struct bce_softc *sc)
DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
+ DBRUN(sc->phy_interrupts++);
+
new_link_state = sc->status_block->status_attn_bits &
- STATUS_ATTN_BITS_LINK_STATE;
+ STATUS_ATTN_BITS_LINK_STATE;
old_link_state = sc->status_block->status_attn_bits_ack &
- STATUS_ATTN_BITS_LINK_STATE;
+ STATUS_ATTN_BITS_LINK_STATE;
/* Handle any changes if the link state has changed. */
if (new_link_state != old_link_state) {
- /* Update the status_attn_bits_ack field in the status block. */
+ /* Update the status_attn_bits_ack field. */
if (new_link_state) {
REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
- STATUS_ATTN_BITS_LINK_STATE);
+ STATUS_ATTN_BITS_LINK_STATE);
DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
- __FUNCTION__);
+ __FUNCTION__);
}
else {
REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
- STATUS_ATTN_BITS_LINK_STATE);
+ STATUS_ATTN_BITS_LINK_STATE);
DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
- __FUNCTION__);
+ __FUNCTION__);
}
/*
@@ -5845,7 +5868,7 @@ bce_phy_intr(struct bce_softc *sc)
* tick routine to update the state
* based on the actual media state.
*/
- sc->bce_link = 0;
+ sc->bce_link_up = FALSE;
callout_stop(&sc->bce_tick_callout);
bce_tick(sc);
}
@@ -5900,8 +5923,8 @@ bce_rx_intr(struct bce_softc *sc)
DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
DBRUN(sc->rx_interrupts++);
DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
- "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
- __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
+ "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
+ __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
/* Prepare the RX chain pages to be accessed by the host CPU. */
for (int i = 0; i < RX_PAGES; i++)
@@ -5939,7 +5962,8 @@ bce_rx_intr(struct bce_softc *sc)
sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
/* Unmap the mbuf from DMA space. */
- bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[sw_rx_cons_idx],
+ bus_dmamap_sync(sc->rx_mbuf_tag,
+ sc->rx_mbuf_map[sw_rx_cons_idx],
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->rx_mbuf_tag,
sc->rx_mbuf_map[sw_rx_cons_idx]);
@@ -5950,29 +5974,30 @@ bce_rx_intr(struct bce_softc *sc)
DBRUN(sc->debug_rx_mbuf_alloc--);
sc->free_rx_bd++;
- if(m0 == NULL) {
- DBPRINT(sc, BCE_EXTREME_RECV, "%s(): Oops! Empty mbuf pointer "
- "found in sc->rx_mbuf_ptr[0x%04X]!\n",
- __FUNCTION__, sw_rx_cons_idx);
- goto bce_rx_int_next_rx;
- }
-
- /*
- * Frames received on the NetXteme II are prepended with an
- * l2_fhdr structure which provides status information about
- * the received frame (including VLAN tags and checksum info).
- * The frames are also automatically adjusted to align the IP
- * header (i.e. two null bytes are inserted before the Ethernet
- * header). As a result the data DMA'd by the controller into
- * the mbuf is as follows:
- *
- * +---------+-----+---------------------+-----+
- * | l2_fhdr | pad | packet data | FCS |
- * +---------+-----+---------------------+-----+
- *
- * The l2_fhdr needs to be checked and skipped and the FCS needs
- * to be stripped before sending the packet up the stack.
- */
+ if(m0 == NULL) {
+ DBPRINT(sc, BCE_EXTREME_RECV,
+ "%s(): Oops! Empty mbuf pointer "
+ "found in sc->rx_mbuf_ptr[0x%04X]!\n",
+ __FUNCTION__, sw_rx_cons_idx);
+ goto bce_rx_int_next_rx;
+ }
+
+ /*
+ * Frames received on the NetXteme II are prepended with an
+ * l2_fhdr structure which provides status information about
+ * the received frame (including VLAN tags and checksum info).
+ * The frames are also automatically adjusted to align the IP
+ * header (i.e. two null bytes are inserted before the Ethernet
+ * header). As a result the data DMA'd by the controller into
+ * the mbuf is as follows:
+ *
+ * +---------+-----+---------------------+-----+
+ * | l2_fhdr | pad | packet data | FCS |
+ * +---------+-----+---------------------+-----+
+ *
+ * The l2_fhdr needs to be checked and skipped and the FCS needs
+ * to be stripped before sending the packet up the stack.
+ */
l2fhdr = mtod(m0, struct l2_fhdr *);
/* Get the packet data + FCS length and the status. */
@@ -6007,8 +6032,8 @@ bce_rx_intr(struct bce_softc *sc)
* in the page chain.
*/
- DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large packet.\n",
- __FUNCTION__);
+ DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
+ "packet.\n", __FUNCTION__);
/*
* When the page chain is enabled and the TCP
@@ -6036,10 +6061,10 @@ bce_rx_intr(struct bce_softc *sc)
/* Unmap the page chain mbuf from DMA space. */
bus_dmamap_sync(sc->pg_mbuf_tag,
- sc->pg_mbuf_map[sw_pg_cons_idx],
- BUS_DMASYNC_POSTREAD);
+ sc->pg_mbuf_map[sw_pg_cons_idx],
+ BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->pg_mbuf_tag,
- sc->pg_mbuf_map[sw_pg_cons_idx]);
+ sc->pg_mbuf_map[sw_pg_cons_idx]);
/* Adjust the mbuf length. */
if (rem_len < m_pg->m_len) {
@@ -6068,8 +6093,8 @@ bce_rx_intr(struct bce_softc *sc)
* 154 bytes or less in size.
*/
- DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small packet.\n",
- __FUNCTION__);
+ DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
+ "packet.\n", __FUNCTION__);
/* Set the total packet length. */
m0->m_pkthdr.len = m0->m_len = pkt_len;
@@ -6085,19 +6110,19 @@ bce_rx_intr(struct bce_softc *sc)
/* Check that the resulting mbuf chain is valid. */
DBRUN(m_sanity(m0, FALSE));
DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
- (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
- BCE_PRINTF("Invalid Ethernet frame size!\n");
- m_print(m0, 128));
+ (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
+ BCE_PRINTF("Invalid Ethernet frame size!\n");
+ m_print(m0, 128));
DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
- BCE_PRINTF("Simulating l2_fhdr status error.\n");
- sc->l2fhdr_error_sim_count++;
- status = status | L2_FHDR_ERRORS_PHY_DECODE);
+ BCE_PRINTF("Simulating l2_fhdr status error.\n");
+ sc->l2fhdr_error_sim_count++;
+ status = status | L2_FHDR_ERRORS_PHY_DECODE);
/* Check the received frame for errors. */
- if (status & (L2_FHDR_ERRORS_BAD_CRC |
- L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
- L2_FHDR_ERRORS_TOO_SHORT | L2_FHDR_ERRORS_GIANT_FRAME)) {
+ if (status & (L2_FHDR_ERRORS_BAD_CRC |
+ L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
+ L2_FHDR_ERRORS_TOO_SHORT | L2_FHDR_ERRORS_GIANT_FRAME)) {
/* Log the error and release the mbuf. */
ifp->if_ierrors++;
@@ -6124,20 +6149,22 @@ bce_rx_intr(struct bce_softc *sc)
/* Check if the IP checksum is valid. */
if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
- m0->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ m0->m_pkthdr.csum_flags |=
+ CSUM_IP_VALID;
}
/* Check for a valid TCP/UDP frame. */
if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
- L2_FHDR_STATUS_UDP_DATAGRAM)) {
+ L2_FHDR_STATUS_UDP_DATAGRAM)) {
/* Check for a good TCP/UDP checksum. */
if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
- L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
+ L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
m0->m_pkthdr.csum_data =
l2fhdr->l2_fhdr_tcp_udp_xsum;
- m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID
- | CSUM_PSEUDO_HDR);
+ m0->m_pkthdr.csum_flags |=
+ (CSUM_DATA_VALID
+ | CSUM_PSEUDO_HDR);
}
}
}
@@ -6228,8 +6255,8 @@ bce_rx_int_next_rx:
#endif
DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
- "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
- __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
+ "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
+ __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
}
@@ -6270,8 +6297,8 @@ bce_tx_intr(struct bce_softc *sc)
DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
DBRUN(sc->tx_interrupts++);
DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
- "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
- __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
+ "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
+ __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
BCE_LOCK_ASSERT(sc);
@@ -6281,7 +6308,7 @@ bce_tx_intr(struct bce_softc *sc)
/* Prevent speculative reads from getting ahead of the status block. */
bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
- BUS_SPACE_BARRIER_READ);
+ BUS_SPACE_BARRIER_READ);
/* Cycle through any completed TX chain page entries. */
while (sw_tx_cons != hw_tx_cons) {
@@ -6291,26 +6318,26 @@ bce_tx_intr(struct bce_softc *sc)
sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
DBPRINT(sc, BCE_INFO_SEND,
- "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
- "sw_tx_chain_cons = 0x%04X\n",
- __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
+ "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
+ "sw_tx_chain_cons = 0x%04X\n",
+ __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
- BCE_PRINTF("%s(%d): TX chain consumer out of range! "
- " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
- (int) MAX_TX_BD);
- bce_breakpoint(sc));
+ BCE_PRINTF("%s(%d): TX chain consumer out of range! "
+ " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
+ (int) MAX_TX_BD);
+ bce_breakpoint(sc));
DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
- [TX_IDX(sw_tx_chain_cons)]);
+ [TX_IDX(sw_tx_chain_cons)]);
DBRUNIF((txbd == NULL),
- BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
- __FILE__, __LINE__, sw_tx_chain_cons);
- bce_breakpoint(sc));
+ BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
+ __FILE__, __LINE__, sw_tx_chain_cons);
+ bce_breakpoint(sc));
DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
- bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
+ bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
/*
* Free the associated mbuf. Remember
@@ -6321,13 +6348,14 @@ bce_tx_intr(struct bce_softc *sc)
/* Validate that this is the last tx_bd. */
DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
- BCE_PRINTF("%s(%d): tx_bd END flag not set but "
- "txmbuf == NULL!\n", __FILE__, __LINE__);
- bce_breakpoint(sc));
+ BCE_PRINTF("%s(%d): tx_bd END flag not set but "
+ "txmbuf == NULL!\n", __FILE__, __LINE__);
+ bce_breakpoint(sc));
DBRUNMSG(BCE_INFO_SEND,
- BCE_PRINTF("%s(): Unloading map/freeing mbuf "
- "from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
+ BCE_PRINTF("%s(): Unloading map/freeing mbuf "
+ "from tx_bd[0x%04X]\n", __FUNCTION__,
+ sw_tx_chain_cons));
/* Unmap the mbuf. */
bus_dmamap_unload(sc->tx_mbuf_tag,
@@ -6347,9 +6375,9 @@ bce_tx_intr(struct bce_softc *sc)
/* Refresh hw_cons to see if there's new work. */
hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
- /* Prevent speculative reads from getting ahead of the status block. */
+ /* Prevent speculative reads of the status block. */
bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
- BUS_SPACE_BARRIER_READ);
+ BUS_SPACE_BARRIER_READ);
}
/* Clear the TX timeout timer. */
@@ -6358,17 +6386,17 @@ bce_tx_intr(struct bce_softc *sc)
/* Clear the tx hardware queue full flag. */
if (sc->used_tx_bd < sc->max_tx_bd) {
DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
- DBPRINT(sc, BCE_INFO_SEND,
- "%s(): Open TX chain! %d/%d (used/total)\n",
- __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
+ DBPRINT(sc, BCE_INFO_SEND,
+ "%s(): Open TX chain! %d/%d (used/total)\n",
+ __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
sc->tx_cons = sw_tx_cons;
DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
- "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
- __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
+ "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
+ __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
}
@@ -6403,11 +6431,11 @@ bce_enable_intr(struct bce_softc *sc, int coal_now)
DBENTER(BCE_VERBOSE_INTR);
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
- BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
- BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
+ BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
- BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
+ BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
/* Force an immediate interrupt (whether there is new data or not). */
if (coal_now)
@@ -6443,19 +6471,19 @@ bce_init_locked(struct bce_softc *sc)
if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
BCE_PRINTF("%s(%d): Controller reset failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
goto bce_init_locked_exit;
}
if (bce_chipinit(sc)) {
BCE_PRINTF("%s(%d): Controller initialization failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
goto bce_init_locked_exit;
}
if (bce_blockinit(sc)) {
BCE_PRINTF("%s(%d): Block initialization failed!\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
goto bce_init_locked_exit;
}
@@ -6468,8 +6496,10 @@ bce_init_locked(struct bce_softc *sc)
* size. Be generous on the receive if we have room.
*/
#ifdef BCE_JUMBO_HDRSPLIT
- if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size))
- ether_mtu = sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size;
+ if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len +
+ sc->pg_bd_mbuf_alloc_size))
+ ether_mtu = sc->rx_bd_mbuf_data_len +
+ sc->pg_bd_mbuf_alloc_size;
#else
if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
ether_mtu = sc->rx_bd_mbuf_data_len;
@@ -6479,29 +6509,29 @@ bce_init_locked(struct bce_softc *sc)
ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
- DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", __FUNCTION__,
- ether_mtu);
+ DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n",
+ __FUNCTION__, ether_mtu);
/* Program the mtu, enabling jumbo frame support if necessary. */
if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
- min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
- BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
+ min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
+ BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
else
REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
DBPRINT(sc, BCE_INFO_LOAD,
- "%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
- "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
- sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
- sc->rx_bd_mbuf_align_pad);
+ "%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
+ "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
+ sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
+ sc->rx_bd_mbuf_align_pad);
/* Program appropriate promiscuous/multicast filtering. */
bce_set_rx_mode(sc);
#ifdef BCE_JUMBO_HDRSPLIT
DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n",
- __FUNCTION__, sc->pg_bd_mbuf_alloc_size);
+ __FUNCTION__, sc->pg_bd_mbuf_alloc_size);
/* Init page buffer descriptor chain. */
bce_init_pg_chain(sc);
@@ -6548,7 +6578,7 @@ bce_mgmt_init_locked(struct bce_softc *sc)
/* Bail out if management firmware is not running. */
if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
DBPRINT(sc, BCE_VERBOSE_SPECIAL,
- "No management firmware running...\n");
+ "No management firmware running...\n");
goto bce_mgmt_init_locked_exit;
}
@@ -6679,7 +6709,7 @@ bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
"ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
- __FUNCTION__, hdr_len, sizeof(struct ether_header), ip_hlen,
+ __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
tcp_hlen, ip_len);
/* Set the LSO flag in the TX BD */
@@ -6717,10 +6747,10 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
DBENTER(BCE_VERBOSE_SEND);
DBPRINT(sc, BCE_INFO_SEND,
- "%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
- "tx_prod_bseq = 0x%08X\n",
- __FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
- sc->tx_prod_bseq);
+ "%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
+ "tx_prod_bseq = 0x%08X\n",
+ __FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
+ sc->tx_prod_bseq);
/* Transfer any checksum offload flags to the bd. */
m0 = *m_head;
@@ -6781,10 +6811,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
rc = error;
goto bce_tx_encap_exit;
} else if (error != 0) {
- /* Still can't map the mbuf, release it and return an error. */
- BCE_PRINTF(
- "%s(%d): Unknown error mapping mbuf into TX chain!\n",
- __FILE__, __LINE__);
+ /* Release it and return an error. */
+ BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
+ "TX chain!\n", __FILE__, __LINE__);
m_freem(m0);
*m_head = NULL;
sc->dma_map_addr_tx_failed_count++;
@@ -6819,9 +6848,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
#endif
DBPRINT(sc, BCE_INFO_SEND,
- "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
- "prod_bseq = 0x%08X\n",
- __FUNCTION__, prod, chain_prod, prod_bseq);
+ "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
+ "prod_bseq = 0x%08X\n",
+ __FUNCTION__, prod, chain_prod, prod_bseq);
/*
* Cycle through each mbuf segment that makes up
@@ -6832,11 +6861,13 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
for (i = 0; i < nsegs ; i++) {
chain_prod = TX_CHAIN_IDX(prod);
- txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
+ txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
+ [TX_IDX(chain_prod)];
txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
- txbd->tx_bd_mss_nbytes = htole32(mss << 16) | htole16(segs[i].ds_len);
+ txbd->tx_bd_mss_nbytes = htole32(mss << 16) |
+ htole16(segs[i].ds_len);
txbd->tx_bd_vlan_tag = htole16(vlan_tag);
txbd->tx_bd_flags = htole16(flags);
prod_bseq += segs[i].ds_len;
@@ -6851,9 +6882,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
DBPRINT(sc, BCE_INFO_SEND,
- "%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
- "prod_bseq = 0x%08X\n",
- __FUNCTION__, prod, chain_prod, prod_bseq);
+ "%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
+ "prod_bseq = 0x%08X\n",
+ __FUNCTION__, prod, chain_prod, prod_bseq);
/*
* Ensure that the mbuf pointer for this transmission
@@ -6869,7 +6900,7 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
/* Update some debug statistic counters */
DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
- sc->tx_hi_watermark = sc->used_tx_bd);
+ sc->tx_hi_watermark = sc->used_tx_bd);
DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
DBRUNIF(sc->debug_tx_mbuf_alloc++);
@@ -6880,10 +6911,10 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
sc->tx_prod_bseq = prod_bseq;
DBPRINT(sc, BCE_INFO_SEND,
- "%s(exit): prod = 0x%04X, chain_prod = %04X, "
- "prod_bseq = 0x%08X\n",
- __FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
- sc->tx_prod_bseq);
+ "%s(exit): prod = 0x%04X, chain_prod = %04X, "
+ "prod_bseq = 0x%08X\n", __FUNCTION__,
+ sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
+ sc->tx_prod_bseq);
bce_tx_encap_exit:
DBEXIT(BCE_VERBOSE_SEND);
@@ -6914,20 +6945,20 @@ bce_start_locked(struct ifnet *ifp)
tx_chain_prod = TX_CHAIN_IDX(tx_prod);
DBPRINT(sc, BCE_INFO_SEND,
- "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
- "tx_prod_bseq = 0x%08X\n",
- __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
+ "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
+ "tx_prod_bseq = 0x%08X\n",
+ __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
/* If there's no link or the transmit queue is empty then just exit. */
- if (!sc->bce_link) {
+ if (sc->bce_link_up == FALSE) {
DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
- __FUNCTION__);
+ __FUNCTION__);
goto bce_start_locked_exit;
}
if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
- __FUNCTION__);
+ __FUNCTION__);
goto bce_start_locked_exit;
}
@@ -6950,13 +6981,12 @@ bce_start_locked(struct ifnet *ifp)
* to wait for the NIC to drain the chain.
*/
if (bce_tx_encap(sc, &m_head)) {
- /* No room, put the frame back on the transmit queue. */
if (m_head != NULL)
IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
DBPRINT(sc, BCE_INFO_SEND,
- "TX chain is closed for business! Total tx_bd used = %d\n",
- sc->used_tx_bd);
+ "TX chain is closed for business! Total "
+ "tx_bd used = %d\n", sc->used_tx_bd);
break;
}
@@ -6968,26 +6998,29 @@ bce_start_locked(struct ifnet *ifp)
/* Exit if no packets were dequeued. */
if (count == 0) {
- DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
- __FUNCTION__);
+ DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
+ "dequeued\n", __FUNCTION__);
goto bce_start_locked_exit;
}
- DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into send queue.\n",
- __FUNCTION__, count);
+ DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
+ "send queue.\n", __FUNCTION__, count);
- REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | BCE_MQ_COMMAND_NO_MAP_ERROR);
+ REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) |
+ BCE_MQ_COMMAND_NO_MAP_ERROR);
/* Write the mailbox and tell the chip about the waiting tx_bd's. */
- DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
- "BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
- __FUNCTION__,
- MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
- REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
- DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
- "BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = 0x%04X\n",
- __FUNCTION__,
- MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
+ DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = "
+ "0x%08X; BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
+ __FUNCTION__, MB_GET_CID_ADDR(TX_CID),
+ BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
+ REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) +
+ BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
+
+ DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = "
+ "0x%08X; BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = "
+ "0x%04X\n", __FUNCTION__, MB_GET_CID_ADDR(TX_CID),
+ BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
/* Set the tx timeout. */
@@ -7041,165 +7074,172 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
switch(command) {
- /* Set the interface MTU. */
- case SIOCSIFMTU:
- /* Check that the MTU setting is supported. */
- if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
- (ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
- error = EINVAL;
- break;
- }
+ /* Set the interface MTU. */
+ case SIOCSIFMTU:
+ /* Check that the MTU setting is supported. */
+ if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
+ (ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
+ error = EINVAL;
+ break;
+ }
- DBPRINT(sc, BCE_INFO_MISC,
- "SIOCSIFMTU: Changing MTU from %d to %d\n",
- (int) ifp->if_mtu, (int) ifr->ifr_mtu);
+ DBPRINT(sc, BCE_INFO_MISC,
+ "SIOCSIFMTU: Changing MTU from %d to %d\n",
+ (int) ifp->if_mtu, (int) ifr->ifr_mtu);
- BCE_LOCK(sc);
- ifp->if_mtu = ifr->ifr_mtu;
- reinit = 0;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- /*
- * Because allocation size is used in RX
- * buffer allocation, stop controller if
- * it is already running.
- */
- bce_stop(sc);
- reinit = 1;
- }
+ BCE_LOCK(sc);
+ ifp->if_mtu = ifr->ifr_mtu;
+ reinit = 0;
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ /*
+ * Because allocation size is used in RX
+ * buffer allocation, stop controller if
+ * it is already running.
+ */
+ bce_stop(sc);
+ reinit = 1;
+ }
#ifdef BCE_JUMBO_HDRSPLIT
- /* No buffer allocation size changes are necessary. */
+ /* No buffer allocation size changes are necessary. */
#else
- /* Recalculate our buffer allocation sizes. */
- if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN) > MCLBYTES) {
- sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
- sc->rx_bd_mbuf_align_pad = roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
- sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
- sc->rx_bd_mbuf_align_pad;
- } else {
- sc->rx_bd_mbuf_alloc_size = MCLBYTES;
- sc->rx_bd_mbuf_align_pad = roundup2(MCLBYTES, 16) - MCLBYTES;
- sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
- sc->rx_bd_mbuf_align_pad;
- }
+ /* Recalculate our buffer allocation sizes. */
+ if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
+ ETHER_CRC_LEN) > MCLBYTES) {
+ sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
+ sc->rx_bd_mbuf_align_pad =
+ roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
+ sc->rx_bd_mbuf_data_len =
+ sc->rx_bd_mbuf_alloc_size -
+ sc->rx_bd_mbuf_align_pad;
+ } else {
+ sc->rx_bd_mbuf_alloc_size = MCLBYTES;
+ sc->rx_bd_mbuf_align_pad =
+ roundup2(MCLBYTES, 16) - MCLBYTES;
+ sc->rx_bd_mbuf_data_len =
+ sc->rx_bd_mbuf_alloc_size -
+ sc->rx_bd_mbuf_align_pad;
+ }
#endif
- if (reinit != 0)
- bce_init_locked(sc);
- BCE_UNLOCK(sc);
- break;
+ if (reinit != 0)
+ bce_init_locked(sc);
+ BCE_UNLOCK(sc);
+ break;
- /* Set interface flags. */
- case SIOCSIFFLAGS:
- DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
+ /* Set interface flags. */
+ case SIOCSIFFLAGS:
+ DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
- BCE_LOCK(sc);
+ BCE_LOCK(sc);
- /* Check if the interface is up. */
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- /* Change promiscuous/multicast flags as necessary. */
- bce_set_rx_mode(sc);
- } else {
- /* Start the HW */
- bce_init_locked(sc);
- }
+ /* Check if the interface is up. */
+ if (ifp->if_flags & IFF_UP) {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ /* Change promiscuous/multicast flags as necessary. */
+ bce_set_rx_mode(sc);
} else {
- /* The interface is down, check if driver is running. */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- bce_stop(sc);
-
- /* If MFW is running, restart the controller a bit. */
- if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
- bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
- bce_chipinit(sc);
- bce_mgmt_init_locked(sc);
- }
- }
+ /* Start the HW */
+ bce_init_locked(sc);
}
+ } else {
+ /* The interface is down, check if driver is running. */
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ bce_stop(sc);
- BCE_UNLOCK(sc);
+ /* If MFW is running, restart the controller a bit. */
+ if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+ bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
+ bce_chipinit(sc);
+ bce_mgmt_init_locked(sc);
+ }
+ }
+ }
- break;
+ BCE_UNLOCK(sc);
+ break;
- /* Add/Delete multicast address */
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCADDMULTI/SIOCDELMULTI\n");
+ /* Add/Delete multicast address */
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ DBPRINT(sc, BCE_VERBOSE_MISC,
+ "Received SIOCADDMULTI/SIOCDELMULTI\n");
- BCE_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- bce_set_rx_mode(sc);
- BCE_UNLOCK(sc);
+ BCE_LOCK(sc);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ bce_set_rx_mode(sc);
+ BCE_UNLOCK(sc);
- break;
+ break;
- /* Set/Get Interface media */
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
- DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
+ /* Set/Get Interface media */
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ DBPRINT(sc, BCE_VERBOSE_MISC,
+ "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
- mii = device_get_softc(sc->bce_miibus);
- error = ifmedia_ioctl(ifp, ifr,
- &mii->mii_media, command);
- break;
+ mii = device_get_softc(sc->bce_miibus);
+ error = ifmedia_ioctl(ifp, ifr,
+ &mii->mii_media, command);
+ break;
- /* Set interface capability */
- case SIOCSIFCAP:
- mask = ifr->ifr_reqcap ^ ifp->if_capenable;
- DBPRINT(sc, BCE_INFO_MISC, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
-
- /* Toggle the TX checksum capabilities enable flag. */
- if (mask & IFCAP_TXCSUM &&
- ifp->if_capabilities & IFCAP_TXCSUM) {
- ifp->if_capenable ^= IFCAP_TXCSUM;
- if (IFCAP_TXCSUM & ifp->if_capenable)
- ifp->if_hwassist |= BCE_IF_HWASSIST;
- else
- ifp->if_hwassist &= ~BCE_IF_HWASSIST;
- }
+ /* Set interface capability */
+ case SIOCSIFCAP:
+ mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+ DBPRINT(sc, BCE_INFO_MISC,
+ "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
+
+ /* Toggle the TX checksum capabilities enable flag. */
+ if (mask & IFCAP_TXCSUM &&
+ ifp->if_capabilities & IFCAP_TXCSUM) {
+ ifp->if_capenable ^= IFCAP_TXCSUM;
+ if (IFCAP_TXCSUM & ifp->if_capenable)
+ ifp->if_hwassist |= BCE_IF_HWASSIST;
+ else
+ ifp->if_hwassist &= ~BCE_IF_HWASSIST;
+ }
- /* Toggle the RX checksum capabilities enable flag. */
- if (mask & IFCAP_RXCSUM &&
- ifp->if_capabilities & IFCAP_RXCSUM)
- ifp->if_capenable ^= IFCAP_RXCSUM;
-
- /* Toggle the TSO capabilities enable flag. */
- if (bce_tso_enable && (mask & IFCAP_TSO4) &&
- ifp->if_capabilities & IFCAP_TSO4) {
- ifp->if_capenable ^= IFCAP_TSO4;
- if (IFCAP_TSO4 & ifp->if_capenable)
- ifp->if_hwassist |= CSUM_TSO;
- else
- ifp->if_hwassist &= ~CSUM_TSO;
- }
+ /* Toggle the RX checksum capabilities enable flag. */
+ if (mask & IFCAP_RXCSUM &&
+ ifp->if_capabilities & IFCAP_RXCSUM)
+ ifp->if_capenable ^= IFCAP_RXCSUM;
+
+ /* Toggle the TSO capabilities enable flag. */
+ if (bce_tso_enable && (mask & IFCAP_TSO4) &&
+ ifp->if_capabilities & IFCAP_TSO4) {
+ ifp->if_capenable ^= IFCAP_TSO4;
+ if (IFCAP_TSO4 & ifp->if_capenable)
+ ifp->if_hwassist |= CSUM_TSO;
+ else
+ ifp->if_hwassist &= ~CSUM_TSO;
+ }
- if (mask & IFCAP_VLAN_HWCSUM &&
- ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
- ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
+ if (mask & IFCAP_VLAN_HWCSUM &&
+ ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
+ ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
- if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
- (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
- ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
- /*
- * Don't actually disable VLAN tag stripping as
- * management firmware (ASF/IPMI/UMP) requires the
- * feature. If VLAN tag stripping is disabled driver
- * will manually reconstruct the VLAN frame by
- * appending stripped VLAN tag.
- */
- if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
- (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
- ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
- if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
- == 0)
- ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
- }
- VLAN_CAPABILITIES(ifp);
- break;
- default:
- /* We don't know how to handle the IOCTL, pass it on. */
- error = ether_ioctl(ifp, command, data);
- break;
+ if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
+ (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
+ ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
+ /*
+ * Don't actually disable VLAN tag stripping as
+ * management firmware (ASF/IPMI/UMP) requires the
+ * feature. If VLAN tag stripping is disabled driver
+ * will manually reconstruct the VLAN frame by
+ * appending stripped VLAN tag.
+ */
+ if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
+ (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
+ ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+ if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
+ == 0)
+ ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
+ }
+ VLAN_CAPABILITIES(ifp);
+ break;
+ default:
+ /* We don't know how to handle the IOCTL, pass it on. */
+ error = ether_ioctl(ifp, command, data);
+ break;
}
DBEXIT(BCE_VERBOSE_MISC);
@@ -7233,15 +7273,15 @@ bce_watchdog(struct bce_softc *sc)
__FILE__, __LINE__);
DBRUNMSG(BCE_INFO,
- bce_dump_driver_state(sc);
- bce_dump_status_block(sc);
- bce_dump_stats_block(sc);
- bce_dump_ftqs(sc);
- bce_dump_txp_state(sc, 0);
- bce_dump_rxp_state(sc, 0);
- bce_dump_tpat_state(sc, 0);
- bce_dump_cp_state(sc, 0);
- bce_dump_com_state(sc, 0));
+ bce_dump_driver_state(sc);
+ bce_dump_status_block(sc);
+ bce_dump_stats_block(sc);
+ bce_dump_ftqs(sc);
+ bce_dump_txp_state(sc, 0);
+ bce_dump_rxp_state(sc, 0);
+ bce_dump_tpat_state(sc, 0);
+ bce_dump_cp_state(sc, 0);
+ bce_dump_com_state(sc, 0));
DBRUN(bce_breakpoint(sc));
@@ -7279,6 +7319,7 @@ bce_intr(void *xsc)
DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
+ DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
BCE_LOCK(sc);
@@ -7295,16 +7336,17 @@ bce_intr(void *xsc)
* interrupt then there's nothing to do.
*/
if ((sc->status_block->status_idx == sc->last_status_idx) &&
- (REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
- DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
- __FUNCTION__);
- goto bce_intr_exit;
+ (REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
+ BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
+ DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
+ __FUNCTION__);
+ goto bce_intr_exit;
}
/* Ack the interrupt and stop others from occuring. */
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
- BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
- BCE_PCICFG_INT_ACK_CMD_MASK_INT);
+ BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
+ BCE_PCICFG_INT_ACK_CMD_MASK_INT);
/* Check if the hardware has finished any work. */
hw_rx_cons = bce_get_hw_rx_cons(sc);
@@ -7315,35 +7357,39 @@ bce_intr(void *xsc)
status_attn_bits = sc->status_block->status_attn_bits;
- DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
- BCE_PRINTF("Simulating unexpected status attention bit set.");
- sc->unexpected_attention_sim_count++;
- status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
+ DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
+ BCE_PRINTF("Simulating unexpected status attention "
+ "bit set.");
+ sc->unexpected_attention_sim_count++;
+ status_attn_bits = status_attn_bits |
+ STATUS_ATTN_BITS_PARITY_ERROR);
/* Was it a link change interrupt? */
if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
- (sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) {
+ (sc->status_block->status_attn_bits_ack &
+ STATUS_ATTN_BITS_LINK_STATE)) {
bce_phy_intr(sc);
- /* Clear any transient status updates during link state change. */
- REG_WR(sc, BCE_HC_COMMAND,
- sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT);
+ /* Clear transient updates during link state change. */
+ REG_WR(sc, BCE_HC_COMMAND, sc->hc_command |
+ BCE_HC_COMMAND_COAL_NOW_WO_INT);
REG_RD(sc, BCE_HC_COMMAND);
}
- /* If any other attention is asserted then the chip is toast. */
+ /* If any other attention is asserted, the chip is toast. */
if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
- (sc->status_block->status_attn_bits_ack &
- ~STATUS_ATTN_BITS_LINK_STATE))) {
+ (sc->status_block->status_attn_bits_ack &
+ ~STATUS_ATTN_BITS_LINK_STATE))) {
- sc->unexpected_attention_count++;
+ sc->unexpected_attention_count++;
- BCE_PRINTF("%s(%d): Fatal attention detected: 0x%08X\n",
- __FILE__, __LINE__, sc->status_block->status_attn_bits);
+ BCE_PRINTF("%s(%d): Fatal attention detected: "
+ "0x%08X\n", __FILE__, __LINE__,
+ sc->status_block->status_attn_bits);
DBRUNMSG(BCE_FATAL,
- if (unexpected_attention_sim_control == 0)
- bce_breakpoint(sc));
+ if (unexpected_attention_sim_control == 0)
+ bce_breakpoint(sc));
bce_init_locked(sc);
goto bce_intr_exit;
@@ -7357,18 +7403,25 @@ bce_intr(void *xsc)
if (hw_tx_cons != sc->hw_tx_cons)
bce_tx_intr(sc);
- /* Save the status block index value for use during the next interrupt. */
+ /* Save status block index value for the next interrupt. */
sc->last_status_idx = sc->status_block->status_idx;
- /* Prevent speculative reads from getting ahead of the status block. */
+ /*
+ * Prevent speculative reads from getting
+ * ahead of the status block.
+ */
bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
- BUS_SPACE_BARRIER_READ);
+ BUS_SPACE_BARRIER_READ);
- /* If there's no work left then exit the interrupt service routine. */
+ /*
+ * If there's no work left then exit the
+ * interrupt service routine.
+ */
hw_rx_cons = bce_get_hw_rx_cons(sc);
hw_tx_cons = bce_get_hw_tx_cons(sc);
- if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons))
+ if ((hw_rx_cons == sc->hw_rx_cons) &&
+ (hw_tx_cons == sc->hw_tx_cons))
break;
}
@@ -7380,7 +7433,8 @@ bce_intr(void *xsc)
bce_enable_intr(sc, 0);
/* Handle any frames that arrived while handling the interrupt. */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+ !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
bce_start_locked(ifp);
bce_intr_exit:
@@ -7413,7 +7467,7 @@ bce_set_rx_mode(struct bce_softc *sc)
/* Initialize receive mode default settings. */
rx_mode = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
- BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
+ BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
/*
@@ -7421,7 +7475,7 @@ bce_set_rx_mode(struct bce_softc *sc)
* be enbled.
*/
if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
- (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
+ (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
/*
@@ -7464,8 +7518,8 @@ bce_set_rx_mode(struct bce_softc *sc)
/* Only make changes if the recive mode has actually changed. */
if (rx_mode != sc->rx_mode) {
- DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: 0x%08X\n",
- rx_mode);
+ DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
+ "0x%08X\n", rx_mode);
sc->rx_mode = rx_mode;
REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
@@ -7506,183 +7560,187 @@ bce_stats_update(struct bce_softc *sc)
*/
if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
!(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
- ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
+ ifp->if_oerrors +=
+ (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
/*
* Update the sysctl statistics from the
* hardware statistics.
*/
sc->stat_IfHCInOctets =
- ((u64) stats->stat_IfHCInOctets_hi << 32) +
- (u64) stats->stat_IfHCInOctets_lo;
+ ((u64) stats->stat_IfHCInOctets_hi << 32) +
+ (u64) stats->stat_IfHCInOctets_lo;
sc->stat_IfHCInBadOctets =
- ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
- (u64) stats->stat_IfHCInBadOctets_lo;
+ ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
+ (u64) stats->stat_IfHCInBadOctets_lo;
sc->stat_IfHCOutOctets =
- ((u64) stats->stat_IfHCOutOctets_hi << 32) +
- (u64) stats->stat_IfHCOutOctets_lo;
+ ((u64) stats->stat_IfHCOutOctets_hi << 32) +
+ (u64) stats->stat_IfHCOutOctets_lo;
sc->stat_IfHCOutBadOctets =
- ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
- (u64) stats->stat_IfHCOutBadOctets_lo;
+ ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
+ (u64) stats->stat_IfHCOutBadOctets_lo;
sc->stat_IfHCInUcastPkts =
- ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
- (u64) stats->stat_IfHCInUcastPkts_lo;
+ ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
+ (u64) stats->stat_IfHCInUcastPkts_lo;
sc->stat_IfHCInMulticastPkts =
- ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
- (u64) stats->stat_IfHCInMulticastPkts_lo;
+ ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
+ (u64) stats->stat_IfHCInMulticastPkts_lo;
sc->stat_IfHCInBroadcastPkts =
- ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
- (u64) stats->stat_IfHCInBroadcastPkts_lo;
+ ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
+ (u64) stats->stat_IfHCInBroadcastPkts_lo;
sc->stat_IfHCOutUcastPkts =
- ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
- (u64) stats->stat_IfHCOutUcastPkts_lo;
+ ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
+ (u64) stats->stat_IfHCOutUcastPkts_lo;
sc->stat_IfHCOutMulticastPkts =
- ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
- (u64) stats->stat_IfHCOutMulticastPkts_lo;
+ ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
+ (u64) stats->stat_IfHCOutMulticastPkts_lo;
sc->stat_IfHCOutBroadcastPkts =
- ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
- (u64) stats->stat_IfHCOutBroadcastPkts_lo;
+ ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
+ (u64) stats->stat_IfHCOutBroadcastPkts_lo;
+
+ /* ToDo: Preserve counters beyond 32 bits? */
+ /* ToDo: Read the statistics from auto-clear regs? */
sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
- stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
+ stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
sc->stat_Dot3StatsCarrierSenseErrors =
- stats->stat_Dot3StatsCarrierSenseErrors;
+ stats->stat_Dot3StatsCarrierSenseErrors;
sc->stat_Dot3StatsFCSErrors =
- stats->stat_Dot3StatsFCSErrors;
+ stats->stat_Dot3StatsFCSErrors;
sc->stat_Dot3StatsAlignmentErrors =
- stats->stat_Dot3StatsAlignmentErrors;
+ stats->stat_Dot3StatsAlignmentErrors;
sc->stat_Dot3StatsSingleCollisionFrames =
- stats->stat_Dot3StatsSingleCollisionFrames;
+ stats->stat_Dot3StatsSingleCollisionFrames;
sc->stat_Dot3StatsMultipleCollisionFrames =
- stats->stat_Dot3StatsMultipleCollisionFrames;
+ stats->stat_Dot3StatsMultipleCollisionFrames;
sc->stat_Dot3StatsDeferredTransmissions =
- stats->stat_Dot3StatsDeferredTransmissions;
+ stats->stat_Dot3StatsDeferredTransmissions;
sc->stat_Dot3StatsExcessiveCollisions =
- stats->stat_Dot3StatsExcessiveCollisions;
+ stats->stat_Dot3StatsExcessiveCollisions;
sc->stat_Dot3StatsLateCollisions =
- stats->stat_Dot3StatsLateCollisions;
+ stats->stat_Dot3StatsLateCollisions;
sc->stat_EtherStatsCollisions =
- stats->stat_EtherStatsCollisions;
+ stats->stat_EtherStatsCollisions;
sc->stat_EtherStatsFragments =
- stats->stat_EtherStatsFragments;
+ stats->stat_EtherStatsFragments;
sc->stat_EtherStatsJabbers =
- stats->stat_EtherStatsJabbers;
+ stats->stat_EtherStatsJabbers;
sc->stat_EtherStatsUndersizePkts =
- stats->stat_EtherStatsUndersizePkts;
+ stats->stat_EtherStatsUndersizePkts;
sc->stat_EtherStatsOversizePkts =
- stats->stat_EtherStatsOversizePkts;
+ stats->stat_EtherStatsOversizePkts;
sc->stat_EtherStatsPktsRx64Octets =
- stats->stat_EtherStatsPktsRx64Octets;
+ stats->stat_EtherStatsPktsRx64Octets;
sc->stat_EtherStatsPktsRx65Octetsto127Octets =
- stats->stat_EtherStatsPktsRx65Octetsto127Octets;
+ stats->stat_EtherStatsPktsRx65Octetsto127Octets;
sc->stat_EtherStatsPktsRx128Octetsto255Octets =
- stats->stat_EtherStatsPktsRx128Octetsto255Octets;
+ stats->stat_EtherStatsPktsRx128Octetsto255Octets;
sc->stat_EtherStatsPktsRx256Octetsto511Octets =
- stats->stat_EtherStatsPktsRx256Octetsto511Octets;
+ stats->stat_EtherStatsPktsRx256Octetsto511Octets;
sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
- stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
+ stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
- stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
+ stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
- stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
+ stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
sc->stat_EtherStatsPktsTx64Octets =
- stats->stat_EtherStatsPktsTx64Octets;
+ stats->stat_EtherStatsPktsTx64Octets;
sc->stat_EtherStatsPktsTx65Octetsto127Octets =
- stats->stat_EtherStatsPktsTx65Octetsto127Octets;
+ stats->stat_EtherStatsPktsTx65Octetsto127Octets;
sc->stat_EtherStatsPktsTx128Octetsto255Octets =
- stats->stat_EtherStatsPktsTx128Octetsto255Octets;
+ stats->stat_EtherStatsPktsTx128Octetsto255Octets;
sc->stat_EtherStatsPktsTx256Octetsto511Octets =
- stats->stat_EtherStatsPktsTx256Octetsto511Octets;
+ stats->stat_EtherStatsPktsTx256Octetsto511Octets;
sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
- stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
+ stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
- stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
+ stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
- stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
+ stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
sc->stat_XonPauseFramesReceived =
- stats->stat_XonPauseFramesReceived;
+ stats->stat_XonPauseFramesReceived;
sc->stat_XoffPauseFramesReceived =
- stats->stat_XoffPauseFramesReceived;
+ stats->stat_XoffPauseFramesReceived;
sc->stat_OutXonSent =
- stats->stat_OutXonSent;
+ stats->stat_OutXonSent;
sc->stat_OutXoffSent =
- stats->stat_OutXoffSent;
+ stats->stat_OutXoffSent;
sc->stat_FlowControlDone =
- stats->stat_FlowControlDone;
+ stats->stat_FlowControlDone;
sc->stat_MacControlFramesReceived =
- stats->stat_MacControlFramesReceived;
+ stats->stat_MacControlFramesReceived;
sc->stat_XoffStateEntered =
- stats->stat_XoffStateEntered;
+ stats->stat_XoffStateEntered;
sc->stat_IfInFramesL2FilterDiscards =
- stats->stat_IfInFramesL2FilterDiscards;
+ stats->stat_IfInFramesL2FilterDiscards;
sc->stat_IfInRuleCheckerDiscards =
- stats->stat_IfInRuleCheckerDiscards;
+ stats->stat_IfInRuleCheckerDiscards;
sc->stat_IfInFTQDiscards =
- stats->stat_IfInFTQDiscards;
+ stats->stat_IfInFTQDiscards;
sc->stat_IfInMBUFDiscards =
- stats->stat_IfInMBUFDiscards;
+ stats->stat_IfInMBUFDiscards;
sc->stat_IfInRuleCheckerP4Hit =
- stats->stat_IfInRuleCheckerP4Hit;
+ stats->stat_IfInRuleCheckerP4Hit;
sc->stat_CatchupInRuleCheckerDiscards =
- stats->stat_CatchupInRuleCheckerDiscards;
+ stats->stat_CatchupInRuleCheckerDiscards;
sc->stat_CatchupInFTQDiscards =
- stats->stat_CatchupInFTQDiscards;
+ stats->stat_CatchupInFTQDiscards;
sc->stat_CatchupInMBUFDiscards =
- stats->stat_CatchupInMBUFDiscards;
+ stats->stat_CatchupInMBUFDiscards;
sc->stat_CatchupInRuleCheckerP4Hit =
- stats->stat_CatchupInRuleCheckerP4Hit;
+ stats->stat_CatchupInRuleCheckerP4Hit;
sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
@@ -7691,26 +7749,26 @@ bce_stats_update(struct bce_softc *sc)
* hardware statistics.
*/
ifp->if_collisions =
- (u_long) sc->stat_EtherStatsCollisions;
+ (u_long) sc->stat_EtherStatsCollisions;
/* ToDo: This method loses soft errors. */
ifp->if_ierrors =
- (u_long) sc->stat_EtherStatsUndersizePkts +
- (u_long) sc->stat_EtherStatsOversizePkts +
- (u_long) sc->stat_IfInMBUFDiscards +
- (u_long) sc->stat_Dot3StatsAlignmentErrors +
- (u_long) sc->stat_Dot3StatsFCSErrors +
- (u_long) sc->stat_IfInRuleCheckerDiscards +
- (u_long) sc->stat_IfInFTQDiscards +
- (u_long) sc->com_no_buffers;
+ (u_long) sc->stat_EtherStatsUndersizePkts +
+ (u_long) sc->stat_EtherStatsOversizePkts +
+ (u_long) sc->stat_IfInMBUFDiscards +
+ (u_long) sc->stat_Dot3StatsAlignmentErrors +
+ (u_long) sc->stat_Dot3StatsFCSErrors +
+ (u_long) sc->stat_IfInRuleCheckerDiscards +
+ (u_long) sc->stat_IfInFTQDiscards +
+ (u_long) sc->com_no_buffers;
/* ToDo: This method loses soft errors. */
ifp->if_oerrors =
- (u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
- (u_long) sc->stat_Dot3StatsExcessiveCollisions +
- (u_long) sc->stat_Dot3StatsLateCollisions;
+ (u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
+ (u_long) sc->stat_Dot3StatsExcessiveCollisions +
+ (u_long) sc->stat_Dot3StatsLateCollisions;
- /* ToDo: Add additional statistics. */
+ /* ToDo: Add additional statistics? */
DBEXIT(BCE_EXTREME_MISC);
}
@@ -7737,6 +7795,33 @@ bce_pulse(void *xsc)
msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
+ /* Update the bootcode condition. */
+ sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
+
+ /* Report whether the bootcode still knows the driver is running. */
+ if (sc->bce_drv_cardiac_arrest == FALSE) {
+ if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
+ sc->bce_drv_cardiac_arrest = TRUE;
+ BCE_PRINTF("%s(): Bootcode lost the driver pulse! "
+ "(bc_state = 0x%08X)\n", __FUNCTION__,
+ sc->bc_state);
+ }
+ } else {
+ /*
+ * Not supported by all bootcode versions.
+ * (v5.0.11+ and v5.2.1+) Older bootcode
+ * will require the driver to reset the
+ * controller to clear this condition.
+ */
+ if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
+ sc->bce_drv_cardiac_arrest = FALSE;
+ BCE_PRINTF("%s(): Bootcode found the driver pulse! "
+ "(bc_state = 0x%08X)\n", __FUNCTION__,
+ sc->bc_state);
+ }
+ }
+
+
/* Schedule the next pulse. */
callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
@@ -7779,7 +7864,7 @@ bce_tick(void *xsc)
bce_watchdog(sc);
/* If link is up already up then we're done. */
- if (sc->bce_link)
+ if (sc->bce_link_up == TRUE)
goto bce_tick_exit;
/* Link is down. Check what the PHY's doing. */
@@ -7789,16 +7874,19 @@ bce_tick(void *xsc)
/* Check if the link has come up. */
if ((mii->mii_media_status & IFM_ACTIVE) &&
(IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
- DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n", __FUNCTION__);
- sc->bce_link++;
+ DBPRINT(sc, BCE_VERBOSE_MISC,
+ "%s(): Link up!\n", __FUNCTION__);
+ sc->bce_link_up = TRUE;
if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
- IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
+ IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
+ IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
bootverbose)
BCE_PRINTF("Gigabit link up!\n");
+
/* Now that link is up, handle any outstanding TX traffic. */
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
- DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found pending TX traffic.\n",
- __FUNCTION__);
+ DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
+ "pending TX traffic.\n", __FUNCTION__);
bce_start_locked(ifp);
}
}
@@ -7819,22 +7907,22 @@ bce_tick_exit:
static int
bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_dump_driver_state(sc);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_driver_state(sc);
+ }
- return error;
+ return error;
}
@@ -7847,22 +7935,78 @@ bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
static int
bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
+
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_hw_state(sc);
+ }
+
+ return error;
+}
+
+
+/****************************************************************************/
+/* Allows the status block to be dumped through the sysctl interface. */
+/* */
+/* Returns: */
+/* 0 for success, positive value for failure. */
+/****************************************************************************/
+static int
+bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ int result;
+ struct bce_softc *sc;
+
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_status_block(sc);
+ }
+
+ return error;
+}
+
+
+/****************************************************************************/
+/* Allows the stats block to be dumped through the sysctl interface. */
+/* */
+/* Returns: */
+/* 0 for success, positive value for failure. */
+/****************************************************************************/
+static int
+bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_dump_hw_state(sc);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_stats_block(sc);
+ }
- return error;
+ return error;
}
@@ -7875,50 +8019,78 @@ bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
static int
bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
+
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_bc_state(sc);
+ }
+
+ return error;
+}
+
+
+/****************************************************************************/
+/* Provides a sysctl interface to allow dumping the RX BD chain. */
+/* */
+/* Returns: */
+/* 0 for success, positive value for failure. */
+/****************************************************************************/
+static int
+bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_dump_bc_state(sc);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD);
+ }
- return error;
+ return error;
}
/****************************************************************************/
-/* Provides a sysctl interface to allow dumping the RX chain. */
+/* Provides a sysctl interface to allow dumping the RX MBUF chain. */
/* */
/* Returns: */
/* 0 for success, positive value for failure. */
/****************************************************************************/
static int
-bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
+bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_dump_rx_chain(sc, 0, TOTAL_RX_BD);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
+ }
- return error;
+ return error;
}
@@ -7931,22 +8103,22 @@ bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
static int
bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
+ }
- return error;
+ return error;
}
@@ -7960,22 +8132,22 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
static int
bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
+ }
- return error;
+ return error;
}
#endif
@@ -8108,22 +8280,22 @@ bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
static int
bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
{
- int error;
- int result;
- struct bce_softc *sc;
+ int error;
+ int result;
+ struct bce_softc *sc;
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
- if (error || !req->newptr)
- return (error);
+ if (error || !req->newptr)
+ return (error);
- if (result == 1) {
- sc = (struct bce_softc *)arg1;
- bce_breakpoint(sc);
- }
+ if (result == 1) {
+ sc = (struct bce_softc *)arg1;
+ bce_breakpoint(sc);
+ }
- return error;
+ return error;
}
#endif
@@ -8147,467 +8319,474 @@ bce_add_sysctls(struct bce_softc *sc)
#ifdef BCE_DEBUG
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "l2fhdr_error_sim_control",
- CTLFLAG_RW, &l2fhdr_error_sim_control,
- 0, "Debug control to force l2fhdr errors");
+ "l2fhdr_error_sim_control",
+ CTLFLAG_RW, &l2fhdr_error_sim_control,
+ 0, "Debug control to force l2fhdr errors");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "l2fhdr_error_sim_count",
- CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
- 0, "Number of simulated l2_fhdr errors");
+ "l2fhdr_error_sim_count",
+ CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
+ 0, "Number of simulated l2_fhdr errors");
#endif
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "l2fhdr_error_count",
- CTLFLAG_RD, &sc->l2fhdr_error_count,
- 0, "Number of l2_fhdr errors");
+ "l2fhdr_error_count",
+ CTLFLAG_RD, &sc->l2fhdr_error_count,
+ 0, "Number of l2_fhdr errors");
#ifdef BCE_DEBUG
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "mbuf_alloc_failed_sim_control",
- CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
- 0, "Debug control to force mbuf allocation failures");
+ "mbuf_alloc_failed_sim_control",
+ CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
+ 0, "Debug control to force mbuf allocation failures");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "mbuf_alloc_failed_sim_count",
- CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
- 0, "Number of simulated mbuf cluster allocation failures");
+ "mbuf_alloc_failed_sim_count",
+ CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
+ 0, "Number of simulated mbuf cluster allocation failures");
#endif
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "mbuf_alloc_failed_count",
- CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
- 0, "Number of mbuf allocation failures");
+ "mbuf_alloc_failed_count",
+ CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
+ 0, "Number of mbuf allocation failures");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "fragmented_mbuf_count",
- CTLFLAG_RD, &sc->fragmented_mbuf_count,
- 0, "Number of fragmented mbufs");
+ "fragmented_mbuf_count",
+ CTLFLAG_RD, &sc->fragmented_mbuf_count,
+ 0, "Number of fragmented mbufs");
#ifdef BCE_DEBUG
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "dma_map_addr_failed_sim_control",
- CTLFLAG_RW, &dma_map_addr_failed_sim_control,
- 0, "Debug control to force DMA mapping failures");
+ "dma_map_addr_failed_sim_control",
+ CTLFLAG_RW, &dma_map_addr_failed_sim_control,
+ 0, "Debug control to force DMA mapping failures");
/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "dma_map_addr_failed_sim_count",
- CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
- 0, "Number of simulated DMA mapping failures");
+ "dma_map_addr_failed_sim_count",
+ CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
+ 0, "Number of simulated DMA mapping failures");
#endif
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "dma_map_addr_rx_failed_count",
- CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
- 0, "Number of RX DMA mapping failures");
+ "dma_map_addr_rx_failed_count",
+ CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
+ 0, "Number of RX DMA mapping failures");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "dma_map_addr_tx_failed_count",
- CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
- 0, "Number of TX DMA mapping failures");
+ "dma_map_addr_tx_failed_count",
+ CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
+ 0, "Number of TX DMA mapping failures");
#ifdef BCE_DEBUG
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "unexpected_attention_sim_control",
- CTLFLAG_RW, &unexpected_attention_sim_control,
- 0, "Debug control to simulate unexpected attentions");
+ "unexpected_attention_sim_control",
+ CTLFLAG_RW, &unexpected_attention_sim_control,
+ 0, "Debug control to simulate unexpected attentions");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "unexpected_attention_sim_count",
- CTLFLAG_RW, &sc->unexpected_attention_sim_count,
- 0, "Number of simulated unexpected attentions");
+ "unexpected_attention_sim_count",
+ CTLFLAG_RW, &sc->unexpected_attention_sim_count,
+ 0, "Number of simulated unexpected attentions");
#endif
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "unexpected_attention_count",
- CTLFLAG_RW, &sc->unexpected_attention_count,
- 0, "Number of unexpected attentions");
+ "unexpected_attention_count",
+ CTLFLAG_RW, &sc->unexpected_attention_count,
+ 0, "Number of unexpected attentions");
#ifdef BCE_DEBUG
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "debug_bootcode_running_failure",
- CTLFLAG_RW, &bootcode_running_failure_sim_control,
- 0, "Debug control to force bootcode running failures");
+ "debug_bootcode_running_failure",
+ CTLFLAG_RW, &bootcode_running_failure_sim_control,
+ 0, "Debug control to force bootcode running failures");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "rx_low_watermark",
- CTLFLAG_RD, &sc->rx_low_watermark,
- 0, "Lowest level of free rx_bd's");
+ "rx_low_watermark",
+ CTLFLAG_RD, &sc->rx_low_watermark,
+ 0, "Lowest level of free rx_bd's");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "rx_empty_count",
- CTLFLAG_RD, &sc->rx_empty_count,
- 0, "Number of times the RX chain was empty");
+ "rx_empty_count",
+ CTLFLAG_RD, &sc->rx_empty_count,
+ 0, "Number of times the RX chain was empty");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "tx_hi_watermark",
- CTLFLAG_RD, &sc->tx_hi_watermark,
- 0, "Highest level of used tx_bd's");
+ "tx_hi_watermark",
+ CTLFLAG_RD, &sc->tx_hi_watermark,
+ 0, "Highest level of used tx_bd's");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "tx_full_count",
- CTLFLAG_RD, &sc->tx_full_count,
- 0, "Number of times the TX chain was full");
+ "tx_full_count",
+ CTLFLAG_RD, &sc->tx_full_count,
+ 0, "Number of times the TX chain was full");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
- "requested_tso_frames",
- CTLFLAG_RD, &sc->requested_tso_frames,
- 0, "Number of TSO frames received");
+ "requested_tso_frames",
+ CTLFLAG_RD, &sc->requested_tso_frames,
+ 0, "Number of TSO frames received");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "rx_interrupts",
- CTLFLAG_RD, &sc->rx_interrupts,
- 0, "Number of RX interrupts");
+ "rx_interrupts",
+ CTLFLAG_RD, &sc->rx_interrupts,
+ 0, "Number of RX interrupts");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "tx_interrupts",
- CTLFLAG_RD, &sc->tx_interrupts,
- 0, "Number of TX interrupts");
-
- SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "rx_intr_time",
- CTLFLAG_RD, &sc->rx_intr_time,
- "RX interrupt time");
-
- SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "tx_intr_time",
- CTLFLAG_RD, &sc->tx_intr_time,
- "TX interrupt time");
+ "tx_interrupts",
+ CTLFLAG_RD, &sc->tx_interrupts,
+ 0, "Number of TX interrupts");
#endif
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHcInOctets",
- CTLFLAG_RD, &sc->stat_IfHCInOctets,
- "Bytes received");
+ "stat_IfHcInOctets",
+ CTLFLAG_RD, &sc->stat_IfHCInOctets,
+ "Bytes received");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCInBadOctets",
- CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
- "Bad bytes received");
+ "stat_IfHCInBadOctets",
+ CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
+ "Bad bytes received");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCOutOctets",
- CTLFLAG_RD, &sc->stat_IfHCOutOctets,
- "Bytes sent");
+ "stat_IfHCOutOctets",
+ CTLFLAG_RD, &sc->stat_IfHCOutOctets,
+ "Bytes sent");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCOutBadOctets",
- CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
- "Bad bytes sent");
+ "stat_IfHCOutBadOctets",
+ CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
+ "Bad bytes sent");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCInUcastPkts",
- CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
- "Unicast packets received");
+ "stat_IfHCInUcastPkts",
+ CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
+ "Unicast packets received");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCInMulticastPkts",
- CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
- "Multicast packets received");
+ "stat_IfHCInMulticastPkts",
+ CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
+ "Multicast packets received");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCInBroadcastPkts",
- CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
- "Broadcast packets received");
+ "stat_IfHCInBroadcastPkts",
+ CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
+ "Broadcast packets received");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCOutUcastPkts",
- CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
- "Unicast packets sent");
+ "stat_IfHCOutUcastPkts",
+ CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
+ "Unicast packets sent");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCOutMulticastPkts",
- CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
- "Multicast packets sent");
+ "stat_IfHCOutMulticastPkts",
+ CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
+ "Multicast packets sent");
SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
- "stat_IfHCOutBroadcastPkts",
- CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
- "Broadcast packets sent");
+ "stat_IfHCOutBroadcastPkts",
+ CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
+ "Broadcast packets sent");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
- CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
- 0, "Internal MAC transmit errors");
+ "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
+ CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
+ 0, "Internal MAC transmit errors");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsCarrierSenseErrors",
- CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
- 0, "Carrier sense errors");
+ "stat_Dot3StatsCarrierSenseErrors",
+ CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
+ 0, "Carrier sense errors");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsFCSErrors",
- CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
- 0, "Frame check sequence errors");
+ "stat_Dot3StatsFCSErrors",
+ CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
+ 0, "Frame check sequence errors");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsAlignmentErrors",
- CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
- 0, "Alignment errors");
+ "stat_Dot3StatsAlignmentErrors",
+ CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
+ 0, "Alignment errors");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsSingleCollisionFrames",
- CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
- 0, "Single Collision Frames");
+ "stat_Dot3StatsSingleCollisionFrames",
+ CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
+ 0, "Single Collision Frames");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsMultipleCollisionFrames",
- CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
- 0, "Multiple Collision Frames");
+ "stat_Dot3StatsMultipleCollisionFrames",
+ CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
+ 0, "Multiple Collision Frames");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsDeferredTransmissions",
- CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
- 0, "Deferred Transmissions");
+ "stat_Dot3StatsDeferredTransmissions",
+ CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
+ 0, "Deferred Transmissions");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsExcessiveCollisions",
- CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
- 0, "Excessive Collisions");
+ "stat_Dot3StatsExcessiveCollisions",
+ CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
+ 0, "Excessive Collisions");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_Dot3StatsLateCollisions",
- CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
- 0, "Late Collisions");
+ "stat_Dot3StatsLateCollisions",
+ CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
+ 0, "Late Collisions");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsCollisions",
- CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
- 0, "Collisions");
+ "stat_EtherStatsCollisions",
+ CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
+ 0, "Collisions");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsFragments",
- CTLFLAG_RD, &sc->stat_EtherStatsFragments,
- 0, "Fragments");
+ "stat_EtherStatsFragments",
+ CTLFLAG_RD, &sc->stat_EtherStatsFragments,
+ 0, "Fragments");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsJabbers",
- CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
- 0, "Jabbers");
+ "stat_EtherStatsJabbers",
+ CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
+ 0, "Jabbers");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsUndersizePkts",
- CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
- 0, "Undersize packets");
+ "stat_EtherStatsUndersizePkts",
+ CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
+ 0, "Undersize packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsOversizePkts",
- CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
- 0, "stat_EtherStatsOversizePkts");
+ "stat_EtherStatsOversizePkts",
+ CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
+ 0, "stat_EtherStatsOversizePkts");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx64Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
- 0, "Bytes received in 64 byte packets");
+ "stat_EtherStatsPktsRx64Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
+ 0, "Bytes received in 64 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx65Octetsto127Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
- 0, "Bytes received in 65 to 127 byte packets");
+ "stat_EtherStatsPktsRx65Octetsto127Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
+ 0, "Bytes received in 65 to 127 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx128Octetsto255Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
- 0, "Bytes received in 128 to 255 byte packets");
+ "stat_EtherStatsPktsRx128Octetsto255Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
+ 0, "Bytes received in 128 to 255 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx256Octetsto511Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
- 0, "Bytes received in 256 to 511 byte packets");
+ "stat_EtherStatsPktsRx256Octetsto511Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
+ 0, "Bytes received in 256 to 511 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx512Octetsto1023Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
- 0, "Bytes received in 512 to 1023 byte packets");
+ "stat_EtherStatsPktsRx512Octetsto1023Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
+ 0, "Bytes received in 512 to 1023 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx1024Octetsto1522Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
- 0, "Bytes received in 1024 t0 1522 byte packets");
+ "stat_EtherStatsPktsRx1024Octetsto1522Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
+ 0, "Bytes received in 1024 t0 1522 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsRx1523Octetsto9022Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
- 0, "Bytes received in 1523 to 9022 byte packets");
+ "stat_EtherStatsPktsRx1523Octetsto9022Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
+ 0, "Bytes received in 1523 to 9022 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx64Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
- 0, "Bytes sent in 64 byte packets");
+ "stat_EtherStatsPktsTx64Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
+ 0, "Bytes sent in 64 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx65Octetsto127Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
- 0, "Bytes sent in 65 to 127 byte packets");
+ "stat_EtherStatsPktsTx65Octetsto127Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
+ 0, "Bytes sent in 65 to 127 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx128Octetsto255Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
- 0, "Bytes sent in 128 to 255 byte packets");
+ "stat_EtherStatsPktsTx128Octetsto255Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
+ 0, "Bytes sent in 128 to 255 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx256Octetsto511Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
- 0, "Bytes sent in 256 to 511 byte packets");
+ "stat_EtherStatsPktsTx256Octetsto511Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
+ 0, "Bytes sent in 256 to 511 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx512Octetsto1023Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
- 0, "Bytes sent in 512 to 1023 byte packets");
+ "stat_EtherStatsPktsTx512Octetsto1023Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
+ 0, "Bytes sent in 512 to 1023 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx1024Octetsto1522Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
- 0, "Bytes sent in 1024 to 1522 byte packets");
+ "stat_EtherStatsPktsTx1024Octetsto1522Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
+ 0, "Bytes sent in 1024 to 1522 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_EtherStatsPktsTx1523Octetsto9022Octets",
- CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
- 0, "Bytes sent in 1523 to 9022 byte packets");
+ "stat_EtherStatsPktsTx1523Octetsto9022Octets",
+ CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
+ 0, "Bytes sent in 1523 to 9022 byte packets");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_XonPauseFramesReceived",
- CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
- 0, "XON pause frames receved");
+ "stat_XonPauseFramesReceived",
+ CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
+ 0, "XON pause frames receved");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_XoffPauseFramesReceived",
- CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
- 0, "XOFF pause frames received");
+ "stat_XoffPauseFramesReceived",
+ CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
+ 0, "XOFF pause frames received");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_OutXonSent",
- CTLFLAG_RD, &sc->stat_OutXonSent,
- 0, "XON pause frames sent");
+ "stat_OutXonSent",
+ CTLFLAG_RD, &sc->stat_OutXonSent,
+ 0, "XON pause frames sent");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_OutXoffSent",
- CTLFLAG_RD, &sc->stat_OutXoffSent,
- 0, "XOFF pause frames sent");
+ "stat_OutXoffSent",
+ CTLFLAG_RD, &sc->stat_OutXoffSent,
+ 0, "XOFF pause frames sent");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_FlowControlDone",
- CTLFLAG_RD, &sc->stat_FlowControlDone,
- 0, "Flow control done");
+ "stat_FlowControlDone",
+ CTLFLAG_RD, &sc->stat_FlowControlDone,
+ 0, "Flow control done");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_MacControlFramesReceived",
- CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
- 0, "MAC control frames received");
+ "stat_MacControlFramesReceived",
+ CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
+ 0, "MAC control frames received");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_XoffStateEntered",
- CTLFLAG_RD, &sc->stat_XoffStateEntered,
- 0, "XOFF state entered");
+ "stat_XoffStateEntered",
+ CTLFLAG_RD, &sc->stat_XoffStateEntered,
+ 0, "XOFF state entered");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_IfInFramesL2FilterDiscards",
- CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
- 0, "Received L2 packets discarded");
+ "stat_IfInFramesL2FilterDiscards",
+ CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
+ 0, "Received L2 packets discarded");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_IfInRuleCheckerDiscards",
- CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
- 0, "Received packets discarded by rule");
+ "stat_IfInRuleCheckerDiscards",
+ CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
+ 0, "Received packets discarded by rule");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_IfInFTQDiscards",
- CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
- 0, "Received packet FTQ discards");
+ "stat_IfInFTQDiscards",
+ CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
+ 0, "Received packet FTQ discards");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_IfInMBUFDiscards",
- CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
- 0, "Received packets discarded due to lack of controller buffer memory");
+ "stat_IfInMBUFDiscards",
+ CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
+ 0, "Received packets discarded due to lack "
+ "of controller buffer memory");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_IfInRuleCheckerP4Hit",
- CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
- 0, "Received packets rule checker hits");
+ "stat_IfInRuleCheckerP4Hit",
+ CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
+ 0, "Received packets rule checker hits");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_CatchupInRuleCheckerDiscards",
- CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
- 0, "Received packets discarded in Catchup path");
+ "stat_CatchupInRuleCheckerDiscards",
+ CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
+ 0, "Received packets discarded in Catchup path");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_CatchupInFTQDiscards",
- CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
- 0, "Received packets discarded in FTQ in Catchup path");
+ "stat_CatchupInFTQDiscards",
+ CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
+ 0, "Received packets discarded in FTQ in Catchup path");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_CatchupInMBUFDiscards",
- CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
- 0, "Received packets discarded in controller buffer memory in Catchup path");
+ "stat_CatchupInMBUFDiscards",
+ CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
+ 0, "Received packets discarded in controller "
+ "buffer memory in Catchup path");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "stat_CatchupInRuleCheckerP4Hit",
- CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
- 0, "Received packets rule checker hits in Catchup path");
+ "stat_CatchupInRuleCheckerP4Hit",
+ CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
+ 0, "Received packets rule checker hits in Catchup path");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
- "com_no_buffers",
- CTLFLAG_RD, &sc->com_no_buffers,
- 0, "Valid packets received but no RX buffers available");
+ "com_no_buffers",
+ CTLFLAG_RD, &sc->com_no_buffers,
+ 0, "Valid packets received but no RX buffers available");
#ifdef BCE_DEBUG
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "driver_state", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_driver_state, "I", "Drive state information");
+ "driver_state", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_driver_state, "I", "Drive state information");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "hw_state", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_hw_state, "I", "Hardware state information");
+ "hw_state", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_hw_state, "I", "Hardware state information");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "bc_state", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_bc_state, "I", "Bootcode state information");
+ "status_block", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_status_block, "I", "Status block");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
+ "stats_block", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_stats_block, "I", "Stats block");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
+ "bc_state", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_bc_state, "I", "Bootcode state information");
+
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
+ "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
+
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
+ "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
+
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
+ "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
#ifdef BCE_JUMBO_HDRSPLIT
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_dump_pg_chain, "I", "Dump page chain");
+ "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_dump_pg_chain, "I", "Dump page chain");
#endif
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_dump_ctx, "I", "Dump context memory");
+ "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_dump_ctx, "I", "Dump context memory");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_breakpoint, "I", "Driver breakpoint");
+ "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_breakpoint, "I", "Driver breakpoint");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "reg_read", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_reg_read, "I", "Register read");
+ "reg_read", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_reg_read, "I", "Register read");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_nvram_read, "I", "NVRAM read");
+ "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_nvram_read, "I", "NVRAM read");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
- "phy_read", CTLTYPE_INT | CTLFLAG_RW,
- (void *)sc, 0,
- bce_sysctl_phy_read, "I", "PHY register read");
+ "phy_read", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)sc, 0,
+ bce_sysctl_phy_read, "I", "PHY register read");
#endif
@@ -8626,7 +8805,7 @@ bce_add_sysctls(struct bce_softc *sc)
/* Returns: */
/* Nothing. */
/****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
bce_freeze_controller(struct bce_softc *sc)
{
u32 val;
@@ -8643,7 +8822,7 @@ bce_freeze_controller(struct bce_softc *sc)
/* Returns: */
/* Nothing. */
/****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
bce_unfreeze_controller(struct bce_softc *sc)
{
u32 val;
@@ -8661,7 +8840,7 @@ bce_unfreeze_controller(struct bce_softc *sc)
/* Returns: */
/* Nothing. */
/****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
{
struct ether_vlan_header *eh;
@@ -8672,10 +8851,10 @@ bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
struct udphdr *uh;
struct arphdr *ah;
- BCE_PRINTF(
- "-----------------------------"
- " Frame Decode "
- "-----------------------------\n");
+ BCE_PRINTF(
+ "-----------------------------"
+ " Frame Decode "
+ "-----------------------------\n");
eh = mtod(m, struct ether_vlan_header *);
@@ -8690,63 +8869,65 @@ bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
/* ToDo: Add VLAN output. */
BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
- eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
+ eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
switch (etype) {
- case ETHERTYPE_IP:
- ip = (struct ip *)(m->m_data + ehlen);
- BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, len = %d bytes, "
- "protocol = 0x%02X, xsum = 0x%04X\n",
- ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
- ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
-
- switch (ip->ip_p) {
- case IPPROTO_TCP:
- th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
- BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
- "flags = 0x%b, csum = 0x%04X\n",
- ntohs(th->th_dport), ntohs(th->th_sport), (th->th_off << 2),
- th->th_flags, "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST\02SYN\01FIN",
- ntohs(th->th_sum));
- break;
- case IPPROTO_UDP:
- uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
- BCE_PRINTF("-udp: dest = %d, src = %d, len = %d bytes, "
- "csum = 0x%04X\n", ntohs(uh->uh_dport), ntohs(uh->uh_sport),
- ntohs(uh->uh_ulen), ntohs(uh->uh_sum));
- break;
- case IPPROTO_ICMP:
- BCE_PRINTF("icmp:\n");
- break;
- default:
- BCE_PRINTF("----: Other IP protocol.\n");
- }
+ case ETHERTYPE_IP:
+ ip = (struct ip *)(m->m_data + ehlen);
+ BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
+ "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
+ ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
+ ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
+
+ switch (ip->ip_p) {
+ case IPPROTO_TCP:
+ th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
+ "flags = 0x%b, csum = 0x%04X\n",
+ ntohs(th->th_dport), ntohs(th->th_sport),
+ (th->th_off << 2), th->th_flags,
+ "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
+ "\02SYN\01FIN", ntohs(th->th_sum));
break;
- case ETHERTYPE_IPV6:
- BCE_PRINTF("ipv6: No decode supported.\n");
+ case IPPROTO_UDP:
+ uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
+ "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport),
+ ntohs(uh->uh_sport), ntohs(uh->uh_ulen),
+ ntohs(uh->uh_sum));
break;
- case ETHERTYPE_ARP:
- BCE_PRINTF("-arp: ");
- ah = (struct arphdr *) (m->m_data + ehlen);
- switch (ntohs(ah->ar_op)) {
- case ARPOP_REVREQUEST:
- printf("reverse ARP request\n");
- break;
- case ARPOP_REVREPLY:
- printf("reverse ARP reply\n");
- break;
- case ARPOP_REQUEST:
- printf("ARP request\n");
- break;
- case ARPOP_REPLY:
- printf("ARP reply\n");
- break;
- default:
- printf("other ARP operation\n");
+ case IPPROTO_ICMP:
+ BCE_PRINTF("icmp:\n");
+ break;
+ default:
+ BCE_PRINTF("----: Other IP protocol.\n");
}
+ break;
+ case ETHERTYPE_IPV6:
+ BCE_PRINTF("ipv6: No decode supported.\n");
+ break;
+ case ETHERTYPE_ARP:
+ BCE_PRINTF("-arp: ");
+ ah = (struct arphdr *) (m->m_data + ehlen);
+ switch (ntohs(ah->ar_op)) {
+ case ARPOP_REVREQUEST:
+ printf("reverse ARP request\n");
+ break;
+ case ARPOP_REVREPLY:
+ printf("reverse ARP reply\n");
+ break;
+ case ARPOP_REQUEST:
+ printf("ARP request\n");
+ break;
+ case ARPOP_REPLY:
+ printf("ARP reply\n");
break;
default:
- BCE_PRINTF("----: Other protocol.\n");
+ printf("other ARP operation\n");
+ }
+ break;
+ default:
+ BCE_PRINTF("----: Other protocol.\n");
}
BCE_PRINTF(
@@ -8773,37 +8954,49 @@ bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
}
while (mp) {
- BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, m_data = %p\n",
- mp, mp->m_len, mp->m_flags,
- "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY",
- mp->m_data);
+ BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
+ "m_data = %p\n", mp, mp->m_len, mp->m_flags,
+ "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
if (mp->m_flags & M_PKTHDR) {
- BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, csum_flags = %b\n",
- mp->m_pkthdr.len, mp->m_flags,
- "\20\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG"
- "\16M_LASTFRAG\21M_VLANTAG\22M_PROMISC\23M_NOFREE",
- mp->m_pkthdr.csum_flags,
- "\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
- "\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
- "\12CSUM_IP_VALID\13CSUM_DATA_VALID\14CSUM_PSEUDO_HDR");
+ BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
+ "csum_flags = %b\n", mp->m_pkthdr.len,
+ mp->m_flags, "\20\12M_BCAST\13M_MCAST\14M_FRAG"
+ "\15M_FIRSTFRAG\16M_LASTFRAG\21M_VLANTAG"
+ "\22M_PROMISC\23M_NOFREE",
+ mp->m_pkthdr.csum_flags,
+ "\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
+ "\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
+ "\12CSUM_IP_VALID\13CSUM_DATA_VALID"
+ "\14CSUM_PSEUDO_HDR");
}
if (mp->m_flags & M_EXT) {
BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
- mp->m_ext.ext_buf, mp->m_ext.ext_size);
+ mp->m_ext.ext_buf, mp->m_ext.ext_size);
switch (mp->m_ext.ext_type) {
- case EXT_CLUSTER: printf("EXT_CLUSTER\n"); break;
- case EXT_SFBUF: printf("EXT_SFBUF\n"); break;
- case EXT_JUMBO9: printf("EXT_JUMBO9\n"); break;
- case EXT_JUMBO16: printf("EXT_JUMBO16\n"); break;
- case EXT_PACKET: printf("EXT_PACKET\n"); break;
- case EXT_MBUF: printf("EXT_MBUF\n"); break;
- case EXT_NET_DRV: printf("EXT_NET_DRV\n"); break;
- case EXT_MOD_TYPE: printf("EXT_MDD_TYPE\n"); break;
- case EXT_DISPOSABLE: printf("EXT_DISPOSABLE\n"); break;
- case EXT_EXTREF: printf("EXT_EXTREF\n"); break;
- default: printf("UNKNOWN\n");
+ case EXT_CLUSTER:
+ printf("EXT_CLUSTER\n"); break;
+ case EXT_SFBUF:
+ printf("EXT_SFBUF\n"); break;
+ case EXT_JUMBO9:
+ printf("EXT_JUMBO9\n"); break;
+ case EXT_JUMBO16:
+ printf("EXT_JUMBO16\n"); break;
+ case EXT_PACKET:
+ printf("EXT_PACKET\n"); break;
+ case EXT_MBUF:
+ printf("EXT_MBUF\n"); break;
+ case EXT_NET_DRV:
+ printf("EXT_NET_DRV\n"); break;
+ case EXT_MOD_TYPE:
+ printf("EXT_MDD_TYPE\n"); break;
+ case EXT_DISPOSABLE:
+ printf("EXT_DISPOSABLE\n"); break;
+ case EXT_EXTREF:
+ printf("EXT_EXTREF\n"); break;
+ default:
+ printf("UNKNOWN\n");
}
}
@@ -8915,60 +9108,109 @@ bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
static __attribute__ ((noinline)) void
bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
{
+ int i = 0;
+
if (idx > MAX_TX_BD)
/* Index out of range. */
BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
/* TX Chain page pointer. */
- BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
- idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
+ BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
+ "pointer\n", idx, txbd->tx_bd_haddr_hi,
+ txbd->tx_bd_haddr_lo);
else {
- /* Normal tx_bd entry. */
- BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
- "vlan tag= 0x%04X, flags = 0x%04X (", idx,
- txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
- txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
- txbd->tx_bd_flags);
-
- if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
- printf(" CONN_FAULT");
-
- if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
- printf(" TCP_UDP_CKSUM");
-
- if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
- printf(" IP_CKSUM");
+ /* Normal tx_bd entry. */
+ BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
+ "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
+ "0x%04X (", idx, txbd->tx_bd_haddr_hi,
+ txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes,
+ txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
+
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
+ if (i>0)
+ printf("|");
+ printf("CONN_FAULT");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
- printf(" VLAN");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
+ if (i>0)
+ printf("|");
+ printf("TCP_UDP_CKSUM");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
- printf(" COAL_NOW");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
+ if (i>0)
+ printf("|");
+ printf("IP_CKSUM");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
- printf(" DONT_GEN_CRC");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
+ if (i>0)
+ printf("|");
+ printf("VLAN");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
- printf(" START");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
+ if (i>0)
+ printf("|");
+ printf("COAL_NOW");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
- printf(" END");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
+ if (i>0)
+ printf("|");
+ printf("DONT_GEN_CRC");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
- printf(" LSO");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
+ if (i>0)
+ printf("|");
+ printf("START");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
- printf(" OPTION_WORD");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
+ if (i>0)
+ printf("|");
+ printf("END");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
- printf(" FLAGS");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
+ if (i>0)
+ printf("|");
+ printf("LSO");
+ i++;
+ }
- if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
- printf(" SNAP");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
+ if (i>0)
+ printf("|");
+ printf("SW_OPTION=%d", ((txbd->tx_bd_flags &
+ TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
+ }
- printf(" )\n");
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
+ if (i>0)
+ printf("|");
+ printf("SW_FLAGS");
+ i++;
}
+ if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
+ if (i>0)
+ printf("|");
+ printf("SNAP)");
+ } else {
+ printf(")\n");
+ }
+ }
}
@@ -8986,14 +9228,15 @@ bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
/* RX Chain page pointer. */
- BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
- idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
+ BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
+ "pointer\n", idx, rxbd->rx_bd_haddr_hi,
+ rxbd->rx_bd_haddr_lo);
else
/* Normal rx_bd entry. */
- BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
- "flags = 0x%08X\n", idx,
- rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
- rxbd->rx_bd_len, rxbd->rx_bd_flags);
+ BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
+ "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi,
+ rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len,
+ rxbd->rx_bd_flags);
}
@@ -9051,104 +9294,117 @@ bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
static __attribute__ ((noinline)) void
bce_dump_ctx(struct bce_softc *sc, u16 cid)
{
- if (cid <= TX_CID) {
- BCE_PRINTF(
- "----------------------------"
- " CTX Data "
- "----------------------------\n");
-
- BCE_PRINTF(" 0x%04X - (CID) Context ID\n", cid);
-
- if (cid == RX_CID) {
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
- "producer index\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host byte sequence\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BSEQ));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
- "descriptor address\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
- "descriptor address\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer index\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDIDX));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
- "producer index\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_PG_BDIDX));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
- "buffer size\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_PG_BUF_SIZE));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
- "chain address\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
- "chain address\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
- BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
- "consumer index\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDIDX));
- } else if (cid == TX_CID) {
- if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE_XI));
- BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx cmd\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE_XI));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) h/w buffer "
- "descriptor address\n", CTX_RD(sc,
- GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) h/w buffer "
- "descriptor address\n", CTX_RD(sc,
- GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) host producer "
- "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
- BCE_L2CTX_TX_HOST_BIDX_XI));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) host byte "
- "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
- BCE_L2CTX_TX_HOST_BSEQ_XI));
- } else {
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
- CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) h/w buffer "
- "descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
- BCE_L2CTX_TX_TBDR_BHADDR_HI));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) h/w buffer "
- "descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
- BCE_L2CTX_TX_TBDR_BHADDR_LO));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host producer "
- "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
- BCE_L2CTX_TX_HOST_BIDX));
- BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
- "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
- BCE_L2CTX_TX_HOST_BSEQ));
- }
- } else
- BCE_PRINTF(" Unknown CID\n");
+ if (cid > TX_CID) {
+ BCE_PRINTF(" Unknown CID\n");
+ return;
+ }
- BCE_PRINTF(
- "----------------------------"
- " Raw CTX "
- "----------------------------\n");
-
- for (int i = 0x0; i < 0x300; i += 0x10) {
- BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
- CTX_RD(sc, GET_CID_ADDR(cid), i),
- CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
- CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
- CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
+ BCE_PRINTF(
+ "----------------------------"
+ " CTX Data "
+ "----------------------------\n");
+
+ BCE_PRINTF(" 0x%04X - (CID) Context ID\n", cid);
+
+ if (cid == RX_CID) {
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
+ "producer index\n",
+ CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
+ "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_HOST_BSEQ));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
+ CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
+ "descriptor address\n",
+ CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
+ "descriptor address\n",
+ CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
+ "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_NX_BDIDX));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
+ "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_HOST_PG_BDIDX));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
+ "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_PG_BUF_SIZE));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
+ "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
+ "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
+ BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
+ "consumer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_RX_NX_PG_BDIDX));
+ } else if (cid == TX_CID) {
+ if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_TYPE_XI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
+ "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_CMD_TYPE_XI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
+ "h/w buffer descriptor address\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
+ "h/w buffer descriptor address\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
+ "host producer index\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_HOST_BIDX_XI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
+ "host byte sequence\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_HOST_BSEQ_XI));
+ } else {
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
+ CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_CMD_TYPE));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
+ "h/w buffer descriptor address\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_TBDR_BHADDR_HI));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
+ "h/w buffer descriptor address\n",
+ CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_TBDR_BHADDR_LO));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
+ "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_HOST_BIDX));
+ BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
+ "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
+ BCE_L2CTX_TX_HOST_BSEQ));
}
+ }
+ BCE_PRINTF(
+ "----------------------------"
+ " Raw CTX "
+ "----------------------------\n");
- BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ for (int i = 0x0; i < 0x300; i += 0x10) {
+ BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
+ CTX_RD(sc, GET_CID_ADDR(cid), i),
+ CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
+ CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
+ CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
}
+
+
+ BCE_PRINTF(
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -9164,36 +9420,38 @@ bce_dump_ftqs(struct bce_softc *sc)
u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
BCE_PRINTF(
- "----------------------------"
- " FTQ Data "
- "----------------------------\n");
+ "----------------------------"
+ " FTQ Data "
+ "----------------------------\n");
- BCE_PRINTF(" FTQ Command Control Depth_Now Max_Depth Valid_Cnt \n");
- BCE_PRINTF(" ------- ---------- ---------- ---------- ---------- ----------\n");
+ BCE_PRINTF(" FTQ Command Control Depth_Now "
+ "Max_Depth Valid_Cnt \n");
+ BCE_PRINTF(" ------- ---------- ---------- ---------- "
+ "---------- ----------\n");
/* Setup the generic statistic counters for the FTQ valid count. */
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT << 16) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT << 8) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT << 16) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT << 8) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT << 24) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT << 16) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT << 8) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT << 16) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT << 8) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT << 24) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT << 16) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT << 8) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT << 16) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT << 8) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT << 24) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT << 16) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT << 8) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT << 16) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT << 8) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
/* Input queue to the Receive Lookup state machine */
@@ -9203,7 +9461,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
BCE_PRINTF(" RLUP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Receive Processor */
cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
@@ -9212,7 +9470,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
BCE_PRINTF(" RXP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Recevie Processor */
cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
@@ -9221,7 +9479,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
BCE_PRINTF(" RXPC 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Receive Virtual to Physical state machine */
cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
@@ -9230,7 +9488,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
BCE_PRINTF(" RV2PP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Recevie Virtual to Physical state machine */
cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
@@ -9239,7 +9497,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
BCE_PRINTF(" RV2PM 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Receive Virtual to Physical state machine */
cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
@@ -9248,7 +9506,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
BCE_PRINTF(" RV2PT 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Receive DMA state machine */
cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
@@ -9257,7 +9515,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
BCE_PRINTF(" RDMA 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Transmit Scheduler state machine */
cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
@@ -9266,7 +9524,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
BCE_PRINTF(" TSCH 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Transmit Buffer Descriptor state machine */
cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
@@ -9275,7 +9533,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
BCE_PRINTF(" TBDR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Transmit Processor */
cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
@@ -9284,7 +9542,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
BCE_PRINTF(" TXP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Transmit DMA state machine */
cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
@@ -9293,7 +9551,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
BCE_PRINTF(" TDMA 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Transmit Patch-Up Processor */
cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
@@ -9302,7 +9560,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
BCE_PRINTF(" TPAT 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Transmit Assembler state machine */
cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
@@ -9311,7 +9569,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
BCE_PRINTF(" TAS 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Completion Processor */
cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
@@ -9320,7 +9578,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
BCE_PRINTF(" COMX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Completion Processor */
cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
@@ -9329,7 +9587,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
BCE_PRINTF(" COMT 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Completion Processor */
cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
@@ -9338,17 +9596,19 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
BCE_PRINTF(" COMX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Setup the generic statistic counters for the FTQ valid count. */
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT << 16) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT << 8) |
- (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT << 8) |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
- if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
- val = val | (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 24);
- REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
+ if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
+ val = val |
+ (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI <<
+ 24);
+ REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
/* Input queue to the Management Control Processor */
cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
@@ -9357,7 +9617,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
BCE_PRINTF(" MCP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Command Processor */
cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
@@ -9366,7 +9626,7 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
BCE_PRINTF(" CP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
/* Input queue to the Completion Scheduler state machine */
cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
@@ -9375,24 +9635,24 @@ bce_dump_ftqs(struct bce_softc *sc)
max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
BCE_PRINTF(" CS 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
- (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
- /* Input queue to the Receive Virtual to Physical Command Scheduler */
+ (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
+ /* Input queue to the RV2P Command Scheduler */
cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
cur_depth = (ctl & 0xFFC00000) >> 22;
max_depth = (ctl & 0x003FF000) >> 12;
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
- cmd, ctl, cur_depth, max_depth, valid_cnt);
+ cmd, ctl, cur_depth, max_depth, valid_cnt);
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -9409,34 +9669,32 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
/* First some info about the tx_bd chain structure. */
BCE_PRINTF(
- "----------------------------"
- " tx_bd chain "
- "----------------------------\n");
+ "----------------------------"
+ " tx_bd chain "
+ "----------------------------\n");
BCE_PRINTF("page size = 0x%08X, tx chain pages = 0x%08X\n",
- (u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
-
+ (u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
- (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
-
+ (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
BCE_PRINTF("total tx_bd = 0x%08X\n", (u32) TOTAL_TX_BD);
BCE_PRINTF(
- "----------------------------"
- " tx_bd data "
- "----------------------------\n");
+ "----------------------------"
+ " tx_bd data "
+ "----------------------------\n");
- /* Now print out the tx_bd's themselves. */
+ /* Now print out a decoded list of TX buffer descriptors. */
for (int i = 0; i < count; i++) {
txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
bce_dump_txbd(sc, tx_prod, txbd);
- tx_prod = NEXT_TX_BD(tx_prod);
+ tx_prod++;
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -9447,28 +9705,28 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
/* Nothing. */
/****************************************************************************/
static __attribute__ ((noinline)) void
-bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
+bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
{
struct rx_bd *rxbd;
/* First some info about the rx_bd chain structure. */
BCE_PRINTF(
- "----------------------------"
- " rx_bd chain "
- "----------------------------\n");
+ "----------------------------"
+ " rx_bd chain "
+ "----------------------------\n");
BCE_PRINTF("page size = 0x%08X, rx chain pages = 0x%08X\n",
- (u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
+ (u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
- (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
+ (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
BCE_PRINTF("total rx_bd = 0x%08X\n", (u32) TOTAL_RX_BD);
BCE_PRINTF(
- "----------------------------"
- " rx_bd data "
- "----------------------------\n");
+ "----------------------------"
+ " rx_bd data "
+ "----------------------------\n");
/* Now print out the rx_bd's themselves. */
for (int i = 0; i < count; i++) {
@@ -9478,9 +9736,9 @@ bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -9498,23 +9756,23 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
/* First some info about the page chain structure. */
BCE_PRINTF(
- "----------------------------"
- " page chain "
- "----------------------------\n");
+ "----------------------------"
+ " page chain "
+ "----------------------------\n");
BCE_PRINTF("page size = 0x%08X, pg chain pages = 0x%08X\n",
- (u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
+ (u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
- (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
+ (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
BCE_PRINTF("total rx_bd = 0x%08X, max_pg_bd = 0x%08X\n",
- (u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
+ (u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
BCE_PRINTF(
- "----------------------------"
- " page data "
- "----------------------------\n");
+ "----------------------------"
+ " page data "
+ "----------------------------\n");
/* Now print out the rx_bd's themselves. */
for (int i = 0; i < count; i++) {
@@ -9524,13 +9782,28 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
#endif
+#define BCE_PRINT_RX_CONS(arg) \
+if (sblk->status_rx_quick_consumer_index##arg) \
+ BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n", \
+ sblk->status_rx_quick_consumer_index##arg, (u16) \
+ RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg), \
+ arg);
+
+
+#define BCE_PRINT_TX_CONS(arg) \
+if (sblk->status_tx_quick_consumer_index##arg) \
+ BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n", \
+ sblk->status_tx_quick_consumer_index##arg, (u16) \
+ TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg), \
+ arg);
+
/****************************************************************************/
/* Prints out the status block from host memory. */
/* */
@@ -9544,107 +9817,55 @@ bce_dump_status_block(struct bce_softc *sc)
sblk = sc->status_block;
- BCE_PRINTF(
- "----------------------------"
- " Status Block "
- "----------------------------\n");
+ BCE_PRINTF(
+ "----------------------------"
+ " Status Block "
+ "----------------------------\n");
+ /* Theses indices are used for normal L2 drivers. */
BCE_PRINTF(" 0x%08X - attn_bits\n",
- sblk->status_attn_bits);
+ sblk->status_attn_bits);
BCE_PRINTF(" 0x%08X - attn_bits_ack\n",
- sblk->status_attn_bits_ack);
-
- BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
- sblk->status_rx_quick_consumer_index0,
- (u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
+ sblk->status_attn_bits_ack);
- BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
- sblk->status_tx_quick_consumer_index0,
- (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
+ BCE_PRINT_RX_CONS(0);
+ BCE_PRINT_TX_CONS(0)
BCE_PRINTF(" 0x%04X - status_idx\n", sblk->status_idx);
/* Theses indices are not used for normal L2 drivers. */
- if (sblk->status_rx_quick_consumer_index1)
- BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
- sblk->status_rx_quick_consumer_index1,
- (u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
-
- if (sblk->status_tx_quick_consumer_index1)
- BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
- sblk->status_tx_quick_consumer_index1,
- (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
-
- if (sblk->status_rx_quick_consumer_index2)
- BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
- sblk->status_rx_quick_consumer_index2,
- (u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
-
- if (sblk->status_tx_quick_consumer_index2)
- BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
- sblk->status_tx_quick_consumer_index2,
- (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
-
- if (sblk->status_rx_quick_consumer_index3)
- BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
- sblk->status_rx_quick_consumer_index3,
- (u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
-
- if (sblk->status_tx_quick_consumer_index3)
- BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
- sblk->status_tx_quick_consumer_index3,
- (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
-
- if (sblk->status_rx_quick_consumer_index4 ||
- sblk->status_rx_quick_consumer_index5)
- BCE_PRINTF("rx_cons4 = 0x%08X, rx_cons5 = 0x%08X\n",
- sblk->status_rx_quick_consumer_index4,
- sblk->status_rx_quick_consumer_index5);
-
- if (sblk->status_rx_quick_consumer_index6 ||
- sblk->status_rx_quick_consumer_index7)
- BCE_PRINTF("rx_cons6 = 0x%08X, rx_cons7 = 0x%08X\n",
- sblk->status_rx_quick_consumer_index6,
- sblk->status_rx_quick_consumer_index7);
-
- if (sblk->status_rx_quick_consumer_index8 ||
- sblk->status_rx_quick_consumer_index9)
- BCE_PRINTF("rx_cons8 = 0x%08X, rx_cons9 = 0x%08X\n",
- sblk->status_rx_quick_consumer_index8,
- sblk->status_rx_quick_consumer_index9);
-
- if (sblk->status_rx_quick_consumer_index10 ||
- sblk->status_rx_quick_consumer_index11)
- BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11 = 0x%08X\n",
- sblk->status_rx_quick_consumer_index10,
- sblk->status_rx_quick_consumer_index11);
-
- if (sblk->status_rx_quick_consumer_index12 ||
- sblk->status_rx_quick_consumer_index13)
- BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13 = 0x%08X\n",
- sblk->status_rx_quick_consumer_index12,
- sblk->status_rx_quick_consumer_index13);
-
- if (sblk->status_rx_quick_consumer_index14 ||
- sblk->status_rx_quick_consumer_index15)
- BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15 = 0x%08X\n",
- sblk->status_rx_quick_consumer_index14,
- sblk->status_rx_quick_consumer_index15);
+ BCE_PRINT_RX_CONS(1); BCE_PRINT_RX_CONS(2); BCE_PRINT_RX_CONS(3);
+ BCE_PRINT_RX_CONS(4); BCE_PRINT_RX_CONS(5); BCE_PRINT_RX_CONS(6);
+ BCE_PRINT_RX_CONS(7); BCE_PRINT_RX_CONS(8); BCE_PRINT_RX_CONS(9);
+ BCE_PRINT_RX_CONS(10); BCE_PRINT_RX_CONS(11); BCE_PRINT_RX_CONS(12);
+ BCE_PRINT_RX_CONS(13); BCE_PRINT_RX_CONS(14); BCE_PRINT_RX_CONS(15);
+
+ BCE_PRINT_TX_CONS(1); BCE_PRINT_TX_CONS(2); BCE_PRINT_TX_CONS(3);
if (sblk->status_completion_producer_index ||
- sblk->status_cmd_consumer_index)
+ sblk->status_cmd_consumer_index)
BCE_PRINTF("com_prod = 0x%08X, cmd_cons = 0x%08X\n",
- sblk->status_completion_producer_index,
- sblk->status_cmd_consumer_index);
+ sblk->status_completion_producer_index,
+ sblk->status_cmd_consumer_index);
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
+#define BCE_PRINT_64BIT_STAT(arg) \
+if (sblk->arg##_lo || sblk->arg##_hi) \
+ BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi, \
+ sblk->arg##_lo, #arg);
+
+#define BCE_PRINT_32BIT_STAT(arg) \
+if (sblk->arg) \
+ BCE_PRINTF(" 0x%08X : %s\n", \
+ sblk->arg, #arg);
+
/****************************************************************************/
/* Prints out the statistics block from host memory. */
/* */
@@ -9659,261 +9880,70 @@ bce_dump_stats_block(struct bce_softc *sc)
sblk = sc->stats_block;
BCE_PRINTF(
- "---------------"
- " Stats Block (All Stats Not Shown Are 0) "
- "---------------\n");
-
- if (sblk->stat_IfHCInOctets_hi
- || sblk->stat_IfHCInOctets_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcInOctets\n",
- sblk->stat_IfHCInOctets_hi,
- sblk->stat_IfHCInOctets_lo);
-
- if (sblk->stat_IfHCInBadOctets_hi
- || sblk->stat_IfHCInBadOctets_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcInBadOctets\n",
- sblk->stat_IfHCInBadOctets_hi,
- sblk->stat_IfHCInBadOctets_lo);
-
- if (sblk->stat_IfHCOutOctets_hi
- || sblk->stat_IfHCOutOctets_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcOutOctets\n",
- sblk->stat_IfHCOutOctets_hi,
- sblk->stat_IfHCOutOctets_lo);
-
- if (sblk->stat_IfHCOutBadOctets_hi
- || sblk->stat_IfHCOutBadOctets_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcOutBadOctets\n",
- sblk->stat_IfHCOutBadOctets_hi,
- sblk->stat_IfHCOutBadOctets_lo);
-
- if (sblk->stat_IfHCInUcastPkts_hi
- || sblk->stat_IfHCInUcastPkts_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcInUcastPkts\n",
- sblk->stat_IfHCInUcastPkts_hi,
- sblk->stat_IfHCInUcastPkts_lo);
-
- if (sblk->stat_IfHCInBroadcastPkts_hi
- || sblk->stat_IfHCInBroadcastPkts_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcInBroadcastPkts\n",
- sblk->stat_IfHCInBroadcastPkts_hi,
- sblk->stat_IfHCInBroadcastPkts_lo);
-
- if (sblk->stat_IfHCInMulticastPkts_hi
- || sblk->stat_IfHCInMulticastPkts_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcInMulticastPkts\n",
- sblk->stat_IfHCInMulticastPkts_hi,
- sblk->stat_IfHCInMulticastPkts_lo);
-
- if (sblk->stat_IfHCOutUcastPkts_hi
- || sblk->stat_IfHCOutUcastPkts_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcOutUcastPkts\n",
- sblk->stat_IfHCOutUcastPkts_hi,
- sblk->stat_IfHCOutUcastPkts_lo);
-
- if (sblk->stat_IfHCOutBroadcastPkts_hi
- || sblk->stat_IfHCOutBroadcastPkts_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcOutBroadcastPkts\n",
- sblk->stat_IfHCOutBroadcastPkts_hi,
- sblk->stat_IfHCOutBroadcastPkts_lo);
-
- if (sblk->stat_IfHCOutMulticastPkts_hi
- || sblk->stat_IfHCOutMulticastPkts_lo)
- BCE_PRINTF("0x%08X:%08X : "
- "IfHcOutMulticastPkts\n",
- sblk->stat_IfHCOutMulticastPkts_hi,
- sblk->stat_IfHCOutMulticastPkts_lo);
-
- if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
- BCE_PRINTF(" 0x%08X : "
- "emac_tx_stat_dot3statsinternalmactransmiterrors\n",
- sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
-
- if (sblk->stat_Dot3StatsCarrierSenseErrors)
- BCE_PRINTF(" 0x%08X : Dot3StatsCarrierSenseErrors\n",
- sblk->stat_Dot3StatsCarrierSenseErrors);
-
- if (sblk->stat_Dot3StatsFCSErrors)
- BCE_PRINTF(" 0x%08X : Dot3StatsFCSErrors\n",
- sblk->stat_Dot3StatsFCSErrors);
-
- if (sblk->stat_Dot3StatsAlignmentErrors)
- BCE_PRINTF(" 0x%08X : Dot3StatsAlignmentErrors\n",
- sblk->stat_Dot3StatsAlignmentErrors);
-
- if (sblk->stat_Dot3StatsSingleCollisionFrames)
- BCE_PRINTF(" 0x%08X : Dot3StatsSingleCollisionFrames\n",
- sblk->stat_Dot3StatsSingleCollisionFrames);
-
- if (sblk->stat_Dot3StatsMultipleCollisionFrames)
- BCE_PRINTF(" 0x%08X : Dot3StatsMultipleCollisionFrames\n",
- sblk->stat_Dot3StatsMultipleCollisionFrames);
-
- if (sblk->stat_Dot3StatsDeferredTransmissions)
- BCE_PRINTF(" 0x%08X : Dot3StatsDeferredTransmissions\n",
- sblk->stat_Dot3StatsDeferredTransmissions);
-
- if (sblk->stat_Dot3StatsExcessiveCollisions)
- BCE_PRINTF(" 0x%08X : Dot3StatsExcessiveCollisions\n",
- sblk->stat_Dot3StatsExcessiveCollisions);
-
- if (sblk->stat_Dot3StatsLateCollisions)
- BCE_PRINTF(" 0x%08X : Dot3StatsLateCollisions\n",
- sblk->stat_Dot3StatsLateCollisions);
-
- if (sblk->stat_EtherStatsCollisions)
- BCE_PRINTF(" 0x%08X : EtherStatsCollisions\n",
- sblk->stat_EtherStatsCollisions);
-
- if (sblk->stat_EtherStatsFragments)
- BCE_PRINTF(" 0x%08X : EtherStatsFragments\n",
- sblk->stat_EtherStatsFragments);
-
- if (sblk->stat_EtherStatsJabbers)
- BCE_PRINTF(" 0x%08X : EtherStatsJabbers\n",
- sblk->stat_EtherStatsJabbers);
-
- if (sblk->stat_EtherStatsUndersizePkts)
- BCE_PRINTF(" 0x%08X : EtherStatsUndersizePkts\n",
- sblk->stat_EtherStatsUndersizePkts);
-
- if (sblk->stat_EtherStatsOversizePkts)
- BCE_PRINTF(" 0x%08X : EtherStatsOverrsizePkts\n",
- sblk->stat_EtherStatsOversizePkts);
-
- if (sblk->stat_EtherStatsPktsRx64Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx64Octets\n",
- sblk->stat_EtherStatsPktsRx64Octets);
-
- if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
- sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
-
- if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
- sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
-
- if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
- sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
-
- if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
- sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
-
- if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
- sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
-
- if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
- sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
-
- if (sblk->stat_EtherStatsPktsTx64Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx64Octets\n",
- sblk->stat_EtherStatsPktsTx64Octets);
-
- if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
- sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
-
- if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
- sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
-
- if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
- sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
-
- if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
- sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
-
- if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
- sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
-
- if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
- BCE_PRINTF(" 0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
- sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
-
- if (sblk->stat_XonPauseFramesReceived)
- BCE_PRINTF(" 0x%08X : XonPauseFramesReceived\n",
- sblk->stat_XonPauseFramesReceived);
-
- if (sblk->stat_XoffPauseFramesReceived)
- BCE_PRINTF(" 0x%08X : XoffPauseFramesReceived\n",
- sblk->stat_XoffPauseFramesReceived);
-
- if (sblk->stat_OutXonSent)
- BCE_PRINTF(" 0x%08X : OutXonSent\n",
- sblk->stat_OutXonSent);
-
- if (sblk->stat_OutXoffSent)
- BCE_PRINTF(" 0x%08X : OutXoffSent\n",
- sblk->stat_OutXoffSent);
-
- if (sblk->stat_FlowControlDone)
- BCE_PRINTF(" 0x%08X : FlowControlDone\n",
- sblk->stat_FlowControlDone);
-
- if (sblk->stat_MacControlFramesReceived)
- BCE_PRINTF(" 0x%08X : MacControlFramesReceived\n",
- sblk->stat_MacControlFramesReceived);
-
- if (sblk->stat_XoffStateEntered)
- BCE_PRINTF(" 0x%08X : XoffStateEntered\n",
- sblk->stat_XoffStateEntered);
-
- if (sblk->stat_IfInFramesL2FilterDiscards)
- BCE_PRINTF(" 0x%08X : IfInFramesL2FilterDiscards\n",
- sblk->stat_IfInFramesL2FilterDiscards);
-
- if (sblk->stat_IfInRuleCheckerDiscards)
- BCE_PRINTF(" 0x%08X : IfInRuleCheckerDiscards\n",
- sblk->stat_IfInRuleCheckerDiscards);
-
- if (sblk->stat_IfInFTQDiscards)
- BCE_PRINTF(" 0x%08X : IfInFTQDiscards\n",
- sblk->stat_IfInFTQDiscards);
-
- if (sblk->stat_IfInMBUFDiscards)
- BCE_PRINTF(" 0x%08X : IfInMBUFDiscards\n",
- sblk->stat_IfInMBUFDiscards);
-
- if (sblk->stat_IfInRuleCheckerP4Hit)
- BCE_PRINTF(" 0x%08X : IfInRuleCheckerP4Hit\n",
- sblk->stat_IfInRuleCheckerP4Hit);
-
- if (sblk->stat_CatchupInRuleCheckerDiscards)
- BCE_PRINTF(" 0x%08X : CatchupInRuleCheckerDiscards\n",
- sblk->stat_CatchupInRuleCheckerDiscards);
-
- if (sblk->stat_CatchupInFTQDiscards)
- BCE_PRINTF(" 0x%08X : CatchupInFTQDiscards\n",
- sblk->stat_CatchupInFTQDiscards);
-
- if (sblk->stat_CatchupInMBUFDiscards)
- BCE_PRINTF(" 0x%08X : CatchupInMBUFDiscards\n",
- sblk->stat_CatchupInMBUFDiscards);
-
- if (sblk->stat_CatchupInRuleCheckerP4Hit)
- BCE_PRINTF(" 0x%08X : CatchupInRuleCheckerP4Hit\n",
- sblk->stat_CatchupInRuleCheckerP4Hit);
+ "---------------"
+ " Stats Block (All Stats Not Shown Are 0) "
+ "---------------\n");
+
+ BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
+ BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
+ BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
+ BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
+ BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
+ BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
+ BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
+ BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
+ BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
+ BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
+ BCE_PRINT_32BIT_STAT(
+ stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
+ BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
+ BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
+ BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
+ BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
+ BCE_PRINT_32BIT_STAT(stat_OutXonSent);
+ BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
+ BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
+ BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
+ BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
+ BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
+ BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
+ BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
+ BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
+ BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
+ BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
+ BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
+ BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
+ BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -9929,146 +9959,142 @@ bce_dump_driver_state(struct bce_softc *sc)
u32 val_hi, val_lo;
BCE_PRINTF(
- "-----------------------------"
- " Driver State "
- "-----------------------------\n");
+ "-----------------------------"
+ " Driver State "
+ "-----------------------------\n");
val_hi = BCE_ADDR_HI(sc);
val_lo = BCE_ADDR_LO(sc);
- BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
+ "address\n", val_hi, val_lo);
val_hi = BCE_ADDR_HI(sc->bce_vhandle);
val_lo = BCE_ADDR_LO(sc->bce_vhandle);
- BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
+ "address\n", val_hi, val_lo);
val_hi = BCE_ADDR_HI(sc->status_block);
val_lo = BCE_ADDR_LO(sc->status_block);
- BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
+ "virtual address\n", val_hi, val_lo);
val_hi = BCE_ADDR_HI(sc->stats_block);
val_lo = BCE_ADDR_LO(sc->stats_block);
- BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
+ "virtual address\n", val_hi, val_lo);
val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
- BCE_PRINTF(
- "0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
+ "virtual adddress\n", val_hi, val_lo);
val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
- BCE_PRINTF(
- "0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
+ "virtual address\n", val_hi, val_lo);
#ifdef BCE_JUMBO_HDRSPLIT
val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
- BCE_PRINTF(
- "0x%08X:%08X - (sc->pg_bd_chain) page chain virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
+ "virtual address\n", val_hi, val_lo);
#endif
val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
- BCE_PRINTF(
- "0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
+ "virtual address\n", val_hi, val_lo);
val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
- BCE_PRINTF(
- "0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
+ "virtual address\n", val_hi, val_lo);
#ifdef BCE_JUMBO_HDRSPLIT
val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
- BCE_PRINTF(
- "0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain virtual address\n",
- val_hi, val_lo);
+ BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
+ "virtual address\n", val_hi, val_lo);
#endif
- BCE_PRINTF(" 0x%08X - (sc->interrupts_generated) h/w intrs\n",
- sc->interrupts_generated);
+ BCE_PRINTF(" 0x%08X - (sc->interrupts_generated) "
+ "h/w intrs\n", sc->interrupts_generated);
- BCE_PRINTF(" 0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
- sc->rx_interrupts);
+ BCE_PRINTF(" 0x%08X - (sc->rx_interrupts) "
+ "rx interrupts handled\n", sc->rx_interrupts);
- BCE_PRINTF(" 0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
- sc->tx_interrupts);
+ BCE_PRINTF(" 0x%08X - (sc->tx_interrupts) "
+ "tx interrupts handled\n", sc->tx_interrupts);
- BCE_PRINTF(" 0x%08X - (sc->last_status_idx) status block index\n",
- sc->last_status_idx);
+ BCE_PRINTF(" 0x%08X - (sc->phy_interrupts) "
+ "phy interrupts handled\n", sc->phy_interrupts);
- BCE_PRINTF(" 0x%04X(0x%04X) - (sc->tx_prod) tx producer index\n",
- sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
+ BCE_PRINTF(" 0x%08X - (sc->last_status_idx) "
+ "status block index\n", sc->last_status_idx);
- BCE_PRINTF(" 0x%04X(0x%04X) - (sc->tx_cons) tx consumer index\n",
- sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
+ BCE_PRINTF(" 0x%04X(0x%04X) - (sc->tx_prod) tx producer "
+ "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
- BCE_PRINTF(" 0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
- sc->tx_prod_bseq);
+ BCE_PRINTF(" 0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
+ "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
- BCE_PRINTF(" 0x%08X - (sc->debug_tx_mbuf_alloc) tx mbufs allocated\n",
- sc->debug_tx_mbuf_alloc);
+ BCE_PRINTF(" 0x%08X - (sc->tx_prod_bseq) tx producer "
+ "byte seq index\n", sc->tx_prod_bseq);
- BCE_PRINTF(" 0x%08X - (sc->used_tx_bd) used tx_bd's\n",
- sc->used_tx_bd);
+ BCE_PRINTF(" 0x%08X - (sc->debug_tx_mbuf_alloc) tx "
+ "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
- BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
- sc->tx_hi_watermark, sc->max_tx_bd);
+ BCE_PRINTF(" 0x%08X - (sc->used_tx_bd) used "
+ "tx_bd's\n", sc->used_tx_bd);
- BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_prod) rx producer index\n",
- sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
+ BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi "
+ "watermark\n", sc->tx_hi_watermark, sc->max_tx_bd);
- BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_cons) rx consumer index\n",
- sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
+ BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_prod) rx producer "
+ "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
- BCE_PRINTF(" 0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
- sc->rx_prod_bseq);
+ BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
+ "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
- BCE_PRINTF(" 0x%08X - (sc->debug_rx_mbuf_alloc) rx mbufs allocated\n",
- sc->debug_rx_mbuf_alloc);
+ BCE_PRINTF(" 0x%08X - (sc->rx_prod_bseq) rx producer "
+ "byte seq index\n", sc->rx_prod_bseq);
- BCE_PRINTF(" 0x%08X - (sc->free_rx_bd) free rx_bd's\n",
- sc->free_rx_bd);
+ BCE_PRINTF(" 0x%08X - (sc->debug_rx_mbuf_alloc) rx "
+ "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
+
+ BCE_PRINTF(" 0x%08X - (sc->free_rx_bd) free "
+ "rx_bd's\n", sc->free_rx_bd);
#ifdef BCE_JUMBO_HDRSPLIT
- BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_prod) page producer index\n",
- sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
+ BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_prod) page producer "
+ "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
- BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_cons) page consumer index\n",
- sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
+ BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_cons) page consumer "
+ "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
- BCE_PRINTF(" 0x%08X - (sc->debug_pg_mbuf_alloc) page mbufs allocated\n",
- sc->debug_pg_mbuf_alloc);
+ BCE_PRINTF(" 0x%08X - (sc->debug_pg_mbuf_alloc) page "
+ "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
- BCE_PRINTF(" 0x%08X - (sc->free_pg_bd) free page rx_bd's\n",
- sc->free_pg_bd);
+ BCE_PRINTF(" 0x%08X - (sc->free_pg_bd) free page "
+ "rx_bd's\n", sc->free_pg_bd);
- BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low watermark\n",
- sc->pg_low_watermark, sc->max_pg_bd);
+ BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low "
+ "watermark\n", sc->pg_low_watermark, sc->max_pg_bd);
#endif
BCE_PRINTF(" 0x%08X - (sc->mbuf_alloc_failed_count) "
- "mbuf alloc failures\n",
- sc->mbuf_alloc_failed_count);
+ "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
- BCE_PRINTF(" 0x%08X - (sc->bce_flags) bce mac flags\n",
- sc->bce_flags);
+ BCE_PRINTF(" 0x%08X - (sc->bce_flags) "
+ "bce mac flags\n", sc->bce_flags);
- BCE_PRINTF(" 0x%08X - (sc->bce_phy_flags) bce phy flags\n",
- sc->bce_phy_flags);
+ BCE_PRINTF(" 0x%08X - (sc->bce_phy_flags) "
+ "bce phy flags\n", sc->bce_phy_flags);
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10085,84 +10111,102 @@ bce_dump_hw_state(struct bce_softc *sc)
u32 val;
BCE_PRINTF(
- "----------------------------"
- " Hardware State "
- "----------------------------\n");
+ "----------------------------"
+ " Hardware State "
+ "----------------------------\n");
BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
- val, BCE_MISC_ENABLE_STATUS_BITS);
+ val, BCE_MISC_ENABLE_STATUS_BITS);
val = REG_RD(sc, BCE_DMA_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", val, BCE_DMA_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) dma_status\n",
+ val, BCE_DMA_STATUS);
val = REG_RD(sc, BCE_CTX_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", val, BCE_CTX_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n",
+ val, BCE_CTX_STATUS);
val = REG_RD(sc, BCE_EMAC_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", val, BCE_EMAC_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) emac_status\n",
+ val, BCE_EMAC_STATUS);
val = REG_RD(sc, BCE_RPM_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n", val, BCE_RPM_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
+ val, BCE_RPM_STATUS);
+ /* ToDo: Create a #define for this constant. */
val = REG_RD(sc, 0x2004);
- BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", val, 0x2004);
+ BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n",
+ val, 0x2004);
val = REG_RD(sc, BCE_RV2P_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", val, BCE_RV2P_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n",
+ val, BCE_RV2P_STATUS);
+ /* ToDo: Create a #define for this constant. */
val = REG_RD(sc, 0x2c04);
- BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", val, 0x2c04);
+ BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n",
+ val, 0x2c04);
val = REG_RD(sc, BCE_TBDR_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n", val, BCE_TBDR_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
+ val, BCE_TBDR_STATUS);
val = REG_RD(sc, BCE_TDMA_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", val, BCE_TDMA_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n",
+ val, BCE_TDMA_STATUS);
val = REG_RD(sc, BCE_HC_STATUS);
- BCE_PRINTF("0x%08X - (0x%06X) hc_status\n", val, BCE_HC_STATUS);
+ BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
+ val, BCE_HC_STATUS);
val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
+ val, BCE_TXP_CPU_STATE);
val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
+ val, BCE_TPAT_CPU_STATE);
val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
+ val, BCE_RXP_CPU_STATE);
val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
+ val, BCE_COM_CPU_STATE);
val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", val, BCE_MCP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n",
+ val, BCE_MCP_CPU_STATE);
val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
+ val, BCE_CP_CPU_STATE);
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
BCE_PRINTF(
- "----------------------------"
- " Register Dump "
- "----------------------------\n");
+ "----------------------------"
+ " Register Dump "
+ "----------------------------\n");
for (int i = 0x400; i < 0x8000; i += 0x10) {
BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
- REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
+ i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
+ REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10176,25 +10220,25 @@ static __attribute__ ((noinline)) void
bce_dump_mq_regs(struct bce_softc *sc)
{
BCE_PRINTF(
- "----------------------------"
- " MQ Regs "
- "----------------------------\n");
+ "----------------------------"
+ " MQ Regs "
+ "----------------------------\n");
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
for (int i = 0x3c00; i < 0x4000; i += 0x10) {
BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
- REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
+ i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
+ REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10210,32 +10254,32 @@ bce_dump_bc_state(struct bce_softc *sc)
u32 val;
BCE_PRINTF(
- "----------------------------"
- " Bootcode State "
- "----------------------------\n");
+ "----------------------------"
+ " Bootcode State "
+ "----------------------------\n");
BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
- val, BCE_BC_RESET_TYPE);
+ val, BCE_BC_RESET_TYPE);
val = bce_shmem_rd(sc, BCE_BC_STATE);
BCE_PRINTF("0x%08X - (0x%06X) state\n",
- val, BCE_BC_STATE);
+ val, BCE_BC_STATE);
val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
BCE_PRINTF("0x%08X - (0x%06X) condition\n",
- val, BCE_BC_STATE_CONDITION);
+ val, BCE_BC_STATE_CONDITION);
val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
- val, BCE_BC_STATE_DEBUG_CMD);
+ val, BCE_BC_STATE_DEBUG_CMD);
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10252,44 +10296,49 @@ bce_dump_txp_state(struct bce_softc *sc, int regs)
u32 fw_version[3];
BCE_PRINTF(
- "----------------------------"
- " TXP State "
- "----------------------------\n");
+ "----------------------------"
+ " TXP State "
+ "----------------------------\n");
for (int i = 0; i < 3; i++)
fw_version[i] = htonl(REG_RD_IND(sc,
- (BCE_TXP_SCRATCH + 0x10 + i * 4)));
+ (BCE_TXP_SCRATCH + 0x10 + i * 4)));
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
- BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", val, BCE_TXP_CPU_MODE);
+ BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n",
+ val, BCE_TXP_CPU_MODE);
val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
+ val, BCE_TXP_CPU_STATE);
val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
- BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", val,
- BCE_TXP_CPU_EVENT_MASK);
+ BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n",
+ val, BCE_TXP_CPU_EVENT_MASK);
if (regs) {
BCE_PRINTF(
- "----------------------------"
- " Register Dump "
- "----------------------------\n");
+ "----------------------------"
+ " Register Dump "
+ "----------------------------\n");
for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
/* Skip the big blank spaces */
if (i < 0x454000 && i > 0x5ffff)
- BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
- REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
+ BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
+ "0x%08X 0x%08X\n", i,
+ REG_RD_IND(sc, i),
+ REG_RD_IND(sc, i + 0x4),
+ REG_RD_IND(sc, i + 0x8),
+ REG_RD_IND(sc, i + 0xC));
}
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10306,44 +10355,50 @@ bce_dump_rxp_state(struct bce_softc *sc, int regs)
u32 fw_version[3];
BCE_PRINTF(
- "----------------------------"
- " RXP State "
- "----------------------------\n");
+ "----------------------------"
+ " RXP State "
+ "----------------------------\n");
for (int i = 0; i < 3; i++)
fw_version[i] = htonl(REG_RD_IND(sc,
- (BCE_RXP_SCRATCH + 0x10 + i * 4)));
+ (BCE_RXP_SCRATCH + 0x10 + i * 4)));
+
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
- BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", val, BCE_RXP_CPU_MODE);
+ BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n",
+ val, BCE_RXP_CPU_MODE);
val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
+ val, BCE_RXP_CPU_STATE);
val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
- BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", val,
- BCE_RXP_CPU_EVENT_MASK);
+ BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n",
+ val, BCE_RXP_CPU_EVENT_MASK);
if (regs) {
BCE_PRINTF(
- "----------------------------"
- " Register Dump "
- "----------------------------\n");
+ "----------------------------"
+ " Register Dump "
+ "----------------------------\n");
for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
/* Skip the big blank sapces */
if (i < 0xc5400 && i > 0xdffff)
- BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
- REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
+ BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
+ "0x%08X 0x%08X\n", i,
+ REG_RD_IND(sc, i),
+ REG_RD_IND(sc, i + 0x4),
+ REG_RD_IND(sc, i + 0x8),
+ REG_RD_IND(sc, i + 0xC));
}
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10360,37 +10415,43 @@ bce_dump_tpat_state(struct bce_softc *sc, int regs)
u32 fw_version[3];
BCE_PRINTF(
- "----------------------------"
- " TPAT State "
- "----------------------------\n");
+ "----------------------------"
+ " TPAT State "
+ "----------------------------\n");
for (int i = 0; i < 3; i++)
fw_version[i] = htonl(REG_RD_IND(sc,
- (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
+ (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
+
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
- BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", val, BCE_TPAT_CPU_MODE);
+ BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n",
+ val, BCE_TPAT_CPU_MODE);
val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
+ val, BCE_TPAT_CPU_STATE);
val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
- BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", val,
- BCE_TPAT_CPU_EVENT_MASK);
+ BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n",
+ val, BCE_TPAT_CPU_EVENT_MASK);
if (regs) {
BCE_PRINTF(
- "----------------------------"
- " Register Dump "
- "----------------------------\n");
+ "----------------------------"
+ " Register Dump "
+ "----------------------------\n");
for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
/* Skip the big blank spaces */
if (i < 0x854000 && i > 0x9ffff)
- BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
- REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
+ BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
+ "0x%08X 0x%08X\n", i,
+ REG_RD_IND(sc, i),
+ REG_RD_IND(sc, i + 0x4),
+ REG_RD_IND(sc, i + 0x8),
+ REG_RD_IND(sc, i + 0xC));
}
}
@@ -10414,44 +10475,50 @@ bce_dump_cp_state(struct bce_softc *sc, int regs)
u32 fw_version[3];
BCE_PRINTF(
- "----------------------------"
- " CP State "
- "----------------------------\n");
+ "----------------------------"
+ " CP State "
+ "----------------------------\n");
for (int i = 0; i < 3; i++)
fw_version[i] = htonl(REG_RD_IND(sc,
- (BCE_CP_SCRATCH + 0x10 + i * 4)));
+ (BCE_CP_SCRATCH + 0x10 + i * 4)));
+
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
- BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", val, BCE_CP_CPU_MODE);
+ BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n",
+ val, BCE_CP_CPU_MODE);
val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
+ val, BCE_CP_CPU_STATE);
val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
- BCE_CP_CPU_EVENT_MASK);
+ BCE_CP_CPU_EVENT_MASK);
if (regs) {
BCE_PRINTF(
- "----------------------------"
- " Register Dump "
- "----------------------------\n");
+ "----------------------------"
+ " Register Dump "
+ "----------------------------\n");
for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
/* Skip the big blank spaces */
if (i < 0x185400 && i > 0x19ffff)
- BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
- REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
+ BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
+ "0x%08X 0x%08X\n", i,
+ REG_RD_IND(sc, i),
+ REG_RD_IND(sc, i + 0x4),
+ REG_RD_IND(sc, i + 0x8),
+ REG_RD_IND(sc, i + 0xC));
}
}
BCE_PRINTF(
- "----------------------------"
- "----------------"
- "----------------------------\n");
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
}
@@ -10465,38 +10532,44 @@ static __attribute__ ((noinline)) void
bce_dump_com_state(struct bce_softc *sc, int regs)
{
u32 val;
- u32 fw_version[3];
+ u32 fw_version[4];
BCE_PRINTF(
- "----------------------------"
- " COM State "
- "----------------------------\n");
+ "----------------------------"
+ " COM State "
+ "----------------------------\n");
for (int i = 0; i < 3; i++)
fw_version[i] = htonl(REG_RD_IND(sc,
- (BCE_COM_SCRATCH + 0x10 + i * 4)));
+ (BCE_COM_SCRATCH + 0x10 + i * 4)));
+
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
- BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", val, BCE_COM_CPU_MODE);
+ BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n",
+ val, BCE_COM_CPU_MODE);
val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
- BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
+ BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
+ val, BCE_COM_CPU_STATE);
val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
- BCE_COM_CPU_EVENT_MASK);
+ BCE_COM_CPU_EVENT_MASK);
if (regs) {
BCE_PRINTF(
- "----------------------------"
- " Register Dump "
- "----------------------------\n");
+ "----------------------------"
+ " Register Dump "
+ "----------------------------\n");
for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
- BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
- i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
- REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
+ BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
+ "0x%08X 0x%08X\n", i,
+ REG_RD_IND(sc, i),
+ REG_RD_IND(sc, i + 0x4),
+ REG_RD_IND(sc, i + 0x8),
+ REG_RD_IND(sc, i + 0xC));
}
}
@@ -10508,12 +10581,80 @@ bce_dump_com_state(struct bce_softc *sc, int regs)
/****************************************************************************/
+/* Prints out the Receive Virtual 2 Physical (RV2P) state. */
+/* */
+/* Returns: */
+/* Nothing. */
+/****************************************************************************/
+static __attribute__ ((noinline)) void
+bce_dump_rv2p_state(struct bce_softc *sc)
+{
+ u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
+
+ BCE_PRINTF(
+ "----------------------------"
+ " RV2P State "
+ "----------------------------\n");
+
+ /* Stall the RV2P processors. */
+ val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
+ val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
+ REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
+
+ /* Read the firmware version. */
+ val = 0x00000001;
+ REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
+ fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
+ fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
+ BCE_RV2P_INSTR_HIGH_HIGH;
+ BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n",
+ fw_ver_high, fw_ver_low);
+
+ val = 0x00000001;
+ REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
+ fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
+ fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
+ BCE_RV2P_INSTR_HIGH_HIGH;
+ BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n",
+ fw_ver_high, fw_ver_low);
+
+ /* Resume the RV2P processors. */
+ val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
+ val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
+ REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
+
+ /* Fetch the program counter value. */
+ val = 0x68007800;
+ REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
+ val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
+ pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
+ pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
+ BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
+ BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
+
+ /* Fetch the program counter value again to see if it is advancing. */
+ val = 0x68007800;
+ REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
+ val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
+ pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
+ pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
+ BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
+ BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
+
+ BCE_PRINTF(
+ "----------------------------"
+ "----------------"
+ "----------------------------\n");
+}
+
+
+/****************************************************************************/
/* Prints out the driver state and then enters the debugger. */
/* */
/* Returns: */
/* Nothing. */
/****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
bce_breakpoint(struct bce_softc *sc)
{
@@ -10525,7 +10666,7 @@ bce_breakpoint(struct bce_softc *sc)
bce_freeze_controller(sc);
bce_unfreeze_controller(sc);
bce_dump_enet(sc, NULL);
- bce_dump_txbd(sc, 0, NULL);
+ bce_dump_txbd(sc, 0, NULL);
bce_dump_rxbd(sc, 0, NULL);
bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
@@ -10533,7 +10674,7 @@ bce_breakpoint(struct bce_softc *sc)
bce_dump_ctx(sc, RX_CID);
bce_dump_ftqs(sc);
bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
- bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
+ bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD);
bce_dump_status_block(sc);
bce_dump_stats_block(sc);
bce_dump_driver_state(sc);
@@ -10544,6 +10685,8 @@ bce_breakpoint(struct bce_softc *sc)
bce_dump_tpat_state(sc, 0);
bce_dump_cp_state(sc, 0);
bce_dump_com_state(sc, 0);
+ bce_dump_rv2p_state(sc);
+
#ifdef BCE_JUMBO_HDRSPLIT
bce_dump_pgbd(sc, 0, NULL);
bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
diff --git a/sys/dev/bce/if_bcefw.h b/sys/dev/bce/if_bcefw.h
index 7f12ac7..c41ff10 100644
--- a/sys/dev/bce/if_bcefw.h
+++ b/sys/dev/bce/if_bcefw.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
* David Christensen <davidch@broadcom.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
index a437686..49bba63 100644
--- a/sys/dev/bce/if_bcereg.h
+++ b/sys/dev/bce/if_bcereg.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
* David Christensen <davidch@broadcom.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -85,9 +85,9 @@
/* Conversion to FreeBSD type definitions. */
/****************************************************************************/
#define u64 uint64_t
-#define u32 uint32_t
-#define u16 uint16_t
-#define u8 uint8_t
+#define u32 uint32_t
+#define u16 uint16_t
+#define u8 uint8_t
#if BYTE_ORDER == BIG_ENDIAN
#define __BIG_ENDIAN 1
@@ -98,385 +98,369 @@
#endif
#define BCE_DWORD_PRINTFB \
- "\020" \
- "\40b31" \
- "\37b30" \
- "\36b29" \
- "\35b28" \
- "\34b27" \
- "\33b26" \
- "\32b25" \
- "\31b24" \
- "\30b23" \
- "\27b22" \
- "\26b21" \
- "\25b20" \
- "\24b19" \
- "\23b18" \
- "\22b17" \
- "\21b16" \
- "\20b15" \
- "\17b14" \
- "\16b13" \
- "\15b12" \
- "\14b11" \
- "\13b10" \
- "\12b9" \
- "\11b8" \
- "\10b7" \
- "\07b6" \
- "\06b5" \
- "\05b4" \
- "\04b3" \
- "\03b2" \
- "\02b1" \
+ "\020" \
+ "\40b31" \
+ "\37b30" \
+ "\36b29" \
+ "\35b28" \
+ "\34b27" \
+ "\33b26" \
+ "\32b25" \
+ "\31b24" \
+ "\30b23" \
+ "\27b22" \
+ "\26b21" \
+ "\25b20" \
+ "\24b19" \
+ "\23b18" \
+ "\22b17" \
+ "\21b16" \
+ "\20b15" \
+ "\17b14" \
+ "\16b13" \
+ "\15b12" \
+ "\14b11" \
+ "\13b10" \
+ "\12b9" \
+ "\11b8" \
+ "\10b7" \
+ "\07b6" \
+ "\06b5" \
+ "\05b4" \
+ "\04b3" \
+ "\03b2" \
+ "\02b1" \
"\01b0"
/* MII Control Register 0x0 */
#define BCE_BMCR_PRINTFB \
- "\020" \
- "\20Reset" \
- "\17Loopback" \
- "\16Spd0" \
- "\15AnegEna" \
- "\14PwrDn" \
- "\13Isolate" \
- "\12RstrtAneg" \
- "\11FD" \
- "\10CollTst" \
- "\07Spd1" \
- "\06Rsrvd" \
- "\05Rsrvd" \
- "\04Rsrvd" \
- "\03Rsrvd" \
- "\02Rsrvd" \
+ "\020" \
+ "\20Reset" \
+ "\17Loopback" \
+ "\16Spd0" \
+ "\15AnegEna" \
+ "\14PwrDn" \
+ "\13Isolate" \
+ "\12RstrtAneg" \
+ "\11FD" \
+ "\10CollTst" \
+ "\07Spd1" \
+ "\06Rsrvd" \
+ "\05Rsrvd" \
+ "\04Rsrvd" \
+ "\03Rsrvd" \
+ "\02Rsrvd" \
"\01Rsrvd"
/* MII Status Register 0x1 */
#define BCE_BMSR_PRINTFB \
- "\020" \
- "\20Cap100T4" \
- "\17Cap100XFD" \
- "\16Cap100XHD" \
- "\15Cap10FD" \
- "\14Cap10HD" \
- "\13Cap100T2FD" \
- "\12Cap100T2HD" \
- "\11ExtStsPrsnt" \
- "\10Rsrvd" \
- "\07PrmblSupp" \
- "\06AnegCmpl" \
- "\05RemFaultDet" \
- "\04AnegCap" \
- "\03LnkUp" \
- "\02JabberDet" \
+ "\020" \
+ "\20Cap100T4" \
+ "\17Cap100XFD" \
+ "\16Cap100XHD" \
+ "\15Cap10FD" \
+ "\14Cap10HD" \
+ "\13Cap100T2FD" \
+ "\12Cap100T2HD" \
+ "\11ExtStsPrsnt" \
+ "\10Rsrvd" \
+ "\07PrmblSupp" \
+ "\06AnegCmpl" \
+ "\05RemFaultDet" \
+ "\04AnegCap" \
+ "\03LnkUp" \
+ "\02JabberDet" \
"\01ExtCapSupp"
/* MII Autoneg Advertisement Register 0x4 */
#define BCE_ANAR_PRINTFB \
- "\020" \
- "\20AdvNxtPg" \
- "\17Rsrvd" \
- "\16AdvRemFault" \
- "\15Rsrvd" \
- "\14AdvAsymPause" \
- "\13AdvPause" \
- "\12Adv100T4" \
- "\11Adv100FD" \
- "\10Adv100HD" \
- "\07Adv10FD" \
- "\06Adv10HD" \
- "\05Rsrvd" \
- "\04Rsrvd" \
- "\03Rsrvd" \
- "\02Rsrvd" \
+ "\020" \
+ "\20AdvNxtPg" \
+ "\17Rsrvd" \
+ "\16AdvRemFault" \
+ "\15Rsrvd" \
+ "\14AdvAsymPause" \
+ "\13AdvPause" \
+ "\12Adv100T4" \
+ "\11Adv100FD" \
+ "\10Adv100HD" \
+ "\07Adv10FD" \
+ "\06Adv10HD" \
+ "\05Rsrvd" \
+ "\04Rsrvd" \
+ "\03Rsrvd" \
+ "\02Rsrvd" \
"\01Adv802.3"
/* MII Autoneg Link Partner Ability Register 0x5 */
#define BCE_ANLPAR_PRINTFB \
- "\020" \
- "\20CapNxtPg" \
- "\17Ack" \
- "\16CapRemFault" \
- "\15Rsrvd" \
- "\14CapAsymPause" \
- "\13CapPause" \
- "\12Cap100T4" \
- "\11Cap100FD" \
- "\10Cap100HD" \
- "\07Cap10FD" \
- "\06Cap10HD" \
- "\05Rsrvd" \
- "\04Rsrvd" \
- "\03Rsrvd" \
- "\02Rsrvd" \
+ "\020" \
+ "\20CapNxtPg" \
+ "\17Ack" \
+ "\16CapRemFault" \
+ "\15Rsrvd" \
+ "\14CapAsymPause" \
+ "\13CapPause" \
+ "\12Cap100T4" \
+ "\11Cap100FD" \
+ "\10Cap100HD" \
+ "\07Cap10FD" \
+ "\06Cap10HD" \
+ "\05Rsrvd" \
+ "\04Rsrvd" \
+ "\03Rsrvd" \
+ "\02Rsrvd" \
"\01Cap802.3"
/* 1000Base-T Control Register 0x09 */
#define BCE_1000CTL_PRINTFB \
- "\020" \
- "\20Test3" \
- "\17Test2" \
- "\16Test1" \
- "\15MasterSlave" \
- "\14ForceMaster" \
- "\13SwitchDev" \
- "\12Adv1000TFD" \
- "\11Adv1000THD" \
- "\10Rsrvd" \
- "\07Rsrvd" \
- "\06Rsrvd" \
- "\05Rsrvd" \
- "\04Rsrvd" \
- "\03Rsrvd" \
- "\02Rsrvd" \
+ "\020" \
+ "\20Test3" \
+ "\17Test2" \
+ "\16Test1" \
+ "\15MasterSlave" \
+ "\14ForceMaster" \
+ "\13SwitchDev" \
+ "\12Adv1000TFD" \
+ "\11Adv1000THD" \
+ "\10Rsrvd" \
+ "\07Rsrvd" \
+ "\06Rsrvd" \
+ "\05Rsrvd" \
+ "\04Rsrvd" \
+ "\03Rsrvd" \
+ "\02Rsrvd" \
"\01Rsrvd"
/* MII 1000Base-T Status Register 0x0a */
#define BCE_1000STS_PRINTFB \
- "\020" \
- "\20MstrSlvFault" \
- "\17Master" \
- "\16LclRcvrOk" \
- "\15RemRcvrOk" \
- "\14Cap1000FD" \
- "\13Cpa1000HD" \
- "\12Rsrvd" \
+ "\020" \
+ "\20MstrSlvFault" \
+ "\17Master" \
+ "\16LclRcvrOk" \
+ "\15RemRcvrOk" \
+ "\14Cap1000FD" \
+ "\13Cpa1000HD" \
+ "\12Rsrvd" \
"\11Rsrvd"
/* MII Extended Status Register 0x0f */
#define BCE_EXTSTS_PRINTFB \
- "\020" \
- "\20b15" \
- "\17b14" \
- "\16b13" \
- "\15b12" \
- "\14Rsrvd" \
- "\13Rsrvd" \
- "\12Rsrvd" \
- "\11Rsrvd" \
- "\10Rsrvd" \
- "\07Rsrvd" \
- "\06Rsrvd" \
- "\05Rsrvd" \
- "\04Rsrvd" \
- "\03Rsrvd" \
- "\02Rsrvd" \
+ "\020" \
+ "\20b15" \
+ "\17b14" \
+ "\16b13" \
+ "\15b12" \
+ "\14Rsrvd" \
+ "\13Rsrvd" \
+ "\12Rsrvd" \
+ "\11Rsrvd" \
+ "\10Rsrvd" \
+ "\07Rsrvd" \
+ "\06Rsrvd" \
+ "\05Rsrvd" \
+ "\04Rsrvd" \
+ "\03Rsrvd" \
+ "\02Rsrvd" \
"\01Rsrvd"
/* MII Autoneg Link Partner Ability Register 0x19 */
#define BCE_AUXSTS_PRINTFB \
- "\020" \
- "\20AnegCmpl" \
- "\17AnegCmplAck" \
- "\16AnegAckDet" \
- "\15AnegAblDet" \
- "\14AnegNextPgWait" \
- "\13HCD" \
- "\12HCD" \
- "\11HCD" \
- "\10PrlDetFault" \
- "\07RemFault" \
- "\06PgRcvd" \
+ "\020" \
+ "\20AnegCmpl" \
+ "\17AnegCmplAck" \
+ "\16AnegAckDet" \
+ "\15AnegAblDet" \
+ "\14AnegNextPgWait" \
+ "\13HCD" \
+ "\12HCD" \
+ "\11HCD" \
+ "\10PrlDetFault" \
+ "\07RemFault" \
+ "\06PgRcvd" \
"\05LnkPrtnrAnegAbl" \
- "\04LnkPrtnrNPAbl" \
- "\03LnkUp" \
- "\02EnaPauseRcv" \
+ "\04LnkPrtnrNPAbl" \
+ "\03LnkUp" \
+ "\02EnaPauseRcv" \
"\01EnaPausXmit"
-/* Remove before release. */
-/* #define BCE_DEBUG 1 */
-/* #define BCE_NVRAM_WRITE_SUPPORT */
+/*
+ * Remove before release:
+ *
+ * #define BCE_DEBUG
+ * #define BCE_NVRAM_WRITE_SUPPORT
+ * #define BCE_JUMBO_HDRSPLIT
+ */
/****************************************************************************/
/* Debugging macros and definitions. */
/****************************************************************************/
-#define BCE_CP_LOAD 0x00000001
-#define BCE_CP_SEND 0x00000002
-#define BCE_CP_RECV 0x00000004
-#define BCE_CP_INTR 0x00000008
-#define BCE_CP_UNLOAD 0x00000010
-#define BCE_CP_RESET 0x00000020
-#define BCE_CP_PHY 0x00000040
-#define BCE_CP_NVRAM 0x00000080
-#define BCE_CP_FIRMWARE 0x00000100
-#define BCE_CP_CTX 0x00000200
-#define BCE_CP_REG 0x00000400
-#define BCE_CP_MISC 0x00400000
-#define BCE_CP_SPECIAL 0x00800000
-#define BCE_CP_ALL 0x00FFFFFF
-
-#define BCE_CP_MASK 0x00FFFFFF
-
-#define BCE_LEVEL_FATAL 0x00000000
-#define BCE_LEVEL_WARN 0x01000000
-#define BCE_LEVEL_INFO 0x02000000
-#define BCE_LEVEL_VERBOSE 0x03000000
-#define BCE_LEVEL_EXTREME 0x04000000
-#define BCE_LEVEL_INSANE 0x05000000
-
-#define BCE_LEVEL_MASK 0xFF000000
-
-#define BCE_WARN_LOAD (BCE_CP_LOAD | BCE_LEVEL_WARN)
-#define BCE_INFO_LOAD (BCE_CP_LOAD | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_LOAD (BCE_CP_LOAD | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_LOAD (BCE_CP_LOAD | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_LOAD (BCE_CP_LOAD | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_SEND (BCE_CP_SEND | BCE_LEVEL_WARN)
-#define BCE_INFO_SEND (BCE_CP_SEND | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_SEND (BCE_CP_SEND | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_SEND (BCE_CP_SEND | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_SEND (BCE_CP_SEND | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_RECV (BCE_CP_RECV | BCE_LEVEL_WARN)
-#define BCE_INFO_RECV (BCE_CP_RECV | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_RECV (BCE_CP_RECV | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_RECV (BCE_CP_RECV | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_RECV (BCE_CP_RECV | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_INTR (BCE_CP_INTR | BCE_LEVEL_WARN)
-#define BCE_INFO_INTR (BCE_CP_INTR | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_INTR (BCE_CP_INTR | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_INTR (BCE_CP_INTR | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_INTR (BCE_CP_INTR | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_WARN)
-#define BCE_INFO_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_RESET (BCE_CP_RESET | BCE_LEVEL_WARN)
-#define BCE_INFO_RESET (BCE_CP_RESET | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_RESET (BCE_CP_RESET | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_RESET (BCE_CP_RESET | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_RESET (BCE_CP_RESET | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_PHY (BCE_CP_PHY | BCE_LEVEL_WARN)
-#define BCE_INFO_PHY (BCE_CP_PHY | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_PHY (BCE_CP_PHY | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_PHY (BCE_CP_PHY | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_PHY (BCE_CP_PHY | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_WARN)
-#define BCE_INFO_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_WARN)
-#define BCE_INFO_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INFO)
+#define BCE_CP_LOAD 0x00000001
+#define BCE_CP_SEND 0x00000002
+#define BCE_CP_RECV 0x00000004
+#define BCE_CP_INTR 0x00000008
+#define BCE_CP_UNLOAD 0x00000010
+#define BCE_CP_RESET 0x00000020
+#define BCE_CP_PHY 0x00000040
+#define BCE_CP_NVRAM 0x00000080
+#define BCE_CP_FIRMWARE 0x00000100
+#define BCE_CP_CTX 0x00000200
+#define BCE_CP_REG 0x00000400
+#define BCE_CP_MISC 0x00400000
+#define BCE_CP_SPECIAL 0x00800000
+#define BCE_CP_ALL 0x00FFFFFF
+
+#define BCE_CP_MASK 0x00FFFFFF
+
+#define BCE_LEVEL_FATAL 0x00000000
+#define BCE_LEVEL_WARN 0x01000000
+#define BCE_LEVEL_INFO 0x02000000
+#define BCE_LEVEL_VERBOSE 0x03000000
+#define BCE_LEVEL_EXTREME 0x04000000
+#define BCE_LEVEL_INSANE 0x05000000
+
+#define BCE_LEVEL_MASK 0xFF000000
+
+#define BCE_WARN_LOAD (BCE_CP_LOAD | BCE_LEVEL_WARN)
+#define BCE_INFO_LOAD (BCE_CP_LOAD | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_LOAD (BCE_CP_LOAD | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_LOAD (BCE_CP_LOAD | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_LOAD (BCE_CP_LOAD | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_SEND (BCE_CP_SEND | BCE_LEVEL_WARN)
+#define BCE_INFO_SEND (BCE_CP_SEND | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_SEND (BCE_CP_SEND | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_SEND (BCE_CP_SEND | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_SEND (BCE_CP_SEND | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_RECV (BCE_CP_RECV | BCE_LEVEL_WARN)
+#define BCE_INFO_RECV (BCE_CP_RECV | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_RECV (BCE_CP_RECV | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_RECV (BCE_CP_RECV | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_RECV (BCE_CP_RECV | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_INTR (BCE_CP_INTR | BCE_LEVEL_WARN)
+#define BCE_INFO_INTR (BCE_CP_INTR | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_INTR (BCE_CP_INTR | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_INTR (BCE_CP_INTR | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_INTR (BCE_CP_INTR | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_WARN)
+#define BCE_INFO_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_RESET (BCE_CP_RESET | BCE_LEVEL_WARN)
+#define BCE_INFO_RESET (BCE_CP_RESET | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_RESET (BCE_CP_RESET | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_RESET (BCE_CP_RESET | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_RESET (BCE_CP_RESET | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_PHY (BCE_CP_PHY | BCE_LEVEL_WARN)
+#define BCE_INFO_PHY (BCE_CP_PHY | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_PHY (BCE_CP_PHY | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_PHY (BCE_CP_PHY | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_PHY (BCE_CP_PHY | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_WARN)
+#define BCE_INFO_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_WARN)
+#define BCE_INFO_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INFO)
#define BCE_VERBOSE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_VERBOSE)
#define BCE_EXTREME_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_CTX (BCE_CP_CTX | BCE_LEVEL_WARN)
-#define BCE_INFO_CTX (BCE_CP_CTX | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_CTX (BCE_CP_CTX | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_CTX (BCE_CP_CTX | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_CTX (BCE_CP_CTX | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_REG (BCE_CP_REG | BCE_LEVEL_WARN)
-#define BCE_INFO_REG (BCE_CP_REG | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_REG (BCE_CP_REG | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_REG (BCE_CP_REG | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_REG (BCE_CP_REG | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_MISC (BCE_CP_MISC | BCE_LEVEL_WARN)
-#define BCE_INFO_MISC (BCE_CP_MISC | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_MISC (BCE_CP_MISC | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_MISC (BCE_CP_MISC | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_MISC (BCE_CP_MISC | BCE_LEVEL_INSANE)
-
-#define BCE_WARN_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_WARN)
-#define BCE_INFO_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INFO)
-#define BCE_VERBOSE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_EXTREME)
-#define BCE_INSANE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INSANE)
-
-#define BCE_FATAL (BCE_CP_ALL | BCE_LEVEL_FATAL)
-#define BCE_WARN (BCE_CP_ALL | BCE_LEVEL_WARN)
-#define BCE_INFO (BCE_CP_ALL | BCE_LEVEL_INFO)
-#define BCE_VERBOSE (BCE_CP_ALL | BCE_LEVEL_VERBOSE)
-#define BCE_EXTREME (BCE_CP_ALL | BCE_LEVEL_EXTREME)
-#define BCE_INSANE (BCE_CP_ALL | BCE_LEVEL_INSANE)
-
-#define BCE_CODE_PATH(cp) ((cp & BCE_CP_MASK) & bce_debug)
-#define BCE_MSG_LEVEL(lv) ((lv & BCE_LEVEL_MASK) <= (bce_debug & BCE_LEVEL_MASK))
-#define BCE_LOG_MSG(m) (BCE_CODE_PATH(m) && BCE_MSG_LEVEL(m))
+#define BCE_INSANE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_CTX (BCE_CP_CTX | BCE_LEVEL_WARN)
+#define BCE_INFO_CTX (BCE_CP_CTX | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_CTX (BCE_CP_CTX | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_CTX (BCE_CP_CTX | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_CTX (BCE_CP_CTX | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_REG (BCE_CP_REG | BCE_LEVEL_WARN)
+#define BCE_INFO_REG (BCE_CP_REG | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_REG (BCE_CP_REG | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_REG (BCE_CP_REG | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_REG (BCE_CP_REG | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_MISC (BCE_CP_MISC | BCE_LEVEL_WARN)
+#define BCE_INFO_MISC (BCE_CP_MISC | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_MISC (BCE_CP_MISC | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_MISC (BCE_CP_MISC | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_MISC (BCE_CP_MISC | BCE_LEVEL_INSANE)
+
+#define BCE_WARN_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_WARN)
+#define BCE_INFO_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INFO)
+#define BCE_VERBOSE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_EXTREME)
+#define BCE_INSANE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INSANE)
+
+#define BCE_FATAL (BCE_CP_ALL | BCE_LEVEL_FATAL)
+#define BCE_WARN (BCE_CP_ALL | BCE_LEVEL_WARN)
+#define BCE_INFO (BCE_CP_ALL | BCE_LEVEL_INFO)
+#define BCE_VERBOSE (BCE_CP_ALL | BCE_LEVEL_VERBOSE)
+#define BCE_EXTREME (BCE_CP_ALL | BCE_LEVEL_EXTREME)
+#define BCE_INSANE (BCE_CP_ALL | BCE_LEVEL_INSANE)
+
+#define BCE_CODE_PATH(cp) ((cp & BCE_CP_MASK) & bce_debug)
+#define BCE_MSG_LEVEL(lv) \
+ ((lv & BCE_LEVEL_MASK) <= (bce_debug & BCE_LEVEL_MASK))
+#define BCE_LOG_MSG(m) (BCE_CODE_PATH(m) && BCE_MSG_LEVEL(m))
#ifdef BCE_DEBUG
-/*
- * Calculate the time delta between two reads
- * of the 25MHz free running clock.
- */
-#define BCE_TIME_DELTA(start, end) (start > end ? (start - end) : \
- (~start + end + 1))
-
/* Print a message based on the logging level and code path. */
-#define DBPRINT(sc, level, format, args...) \
- if (BCE_LOG_MSG(level)) { \
- device_printf(sc->bce_dev, format, ## args); \
+#define DBPRINT(sc, level, format, args...) \
+ if (BCE_LOG_MSG(level)) { \
+ device_printf(sc->bce_dev, format, ## args); \
}
/* Runs a particular command when debugging is enabled. */
-#define DBRUN(args...) \
- do { \
- args; \
+#define DBRUN(args...) \
+ do { \
+ args; \
} while (0)
/* Runs a particular command based on the logging level and code path. */
-#define DBRUNMSG(msg, args...) \
- if (BCE_LOG_MSG(msg)) { \
- args; \
+#define DBRUNMSG(msg, args...) \
+ if (BCE_LOG_MSG(msg)) { \
+ args; \
}
/* Runs a particular command based on the logging level. */
-#define DBRUNLV(level, args...) \
- if (BCE_MSG_LEVEL(level)) { \
- args; \
+#define DBRUNLV(level, args...) \
+ if (BCE_MSG_LEVEL(level)) { \
+ args; \
}
/* Runs a particular command based on the code path. */
-#define DBRUNCP(cp, args...) \
- if (BCE_CODE_PATH(cp)) { \
- args; \
+#define DBRUNCP(cp, args...) \
+ if (BCE_CODE_PATH(cp)) { \
+ args; \
}
/* Runs a particular command based on a condition. */
-#define DBRUNIF(cond, args...) \
- if (cond) { \
- args; \
+#define DBRUNIF(cond, args...) \
+ if (cond) { \
+ args; \
}
/* Announces function entry. */
-#if 0
-#define DBENTER(cond) \
- u32 start_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN); \
- u32 end_time; \
- DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__);
-#endif
-
-#define DBENTER(cond) \
+#define DBENTER(cond) \
DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__)
/* Announces function exit. */
-#if 0
-#define DBEXIT(cond, val) \
- end_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN); \
- val += (u64) BCE_TIME_DELTA(start_time, end_time); \
- DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__);
-#endif
-
-#define DBEXIT(cond) \
+#define DBEXIT(cond) \
DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__)
/* Temporarily override the debug level. */
-#define DBPUSH(cond) \
- u32 bce_debug_temp = bce_debug; \
+#define DBPUSH(cond) \
+ u32 bce_debug_temp = bce_debug; \
bce_debug |= cond;
/* Restore the previously overriden debug level. */
@@ -496,43 +480,43 @@
#define DB_OR_RANDOMTRUE(defects) || (random() < defects)
#define DB_AND_RANDOMTRUE(defects) && (random() < defects)
-#define DB_PRINT_PHY_REG(reg, val) \
- switch(reg) { \
- case 0x00: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (BMCR ), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_BMCR_PRINTFB); break; \
- case 0x01: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (BMSR ), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_BMSR_PRINTFB); break; \
- case 0x04: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (ANAR ), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_ANAR_PRINTFB); break; \
- case 0x05: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (ANLPAR ), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_ANLPAR_PRINTFB); break; \
- case 0x09: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (1000CTL), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_1000CTL_PRINTFB); break; \
- case 0x0a: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (1000STS), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_1000STS_PRINTFB); break; \
- case 0x0f: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (EXTSTS ), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_EXTSTS_PRINTFB); break; \
- case 0x19: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X (AUXSTS ), val = 0x%b\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
- BCE_AUXSTS_PRINTFB); break; \
- default: DBPRINT(sc, BCE_INSANE_PHY, \
- "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", \
- __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff); \
+#define DB_PRINT_PHY_REG(reg, val) \
+switch(reg) { \
+case 0x00: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (BMCR ), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_BMCR_PRINTFB); break; \
+case 0x01: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (BMSR ), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_BMSR_PRINTFB); break; \
+case 0x04: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (ANAR ), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_ANAR_PRINTFB); break; \
+case 0x05: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (ANLPAR ), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_ANLPAR_PRINTFB); break; \
+case 0x09: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (1000CTL), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_1000CTL_PRINTFB); break; \
+case 0x0a: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (1000STS), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_1000STS_PRINTFB); break; \
+case 0x0f: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (EXTSTS ), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_EXTSTS_PRINTFB); break; \
+case 0x19: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X (AUXSTS ), val = 0x%b\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \
+ BCE_AUXSTS_PRINTFB); break; \
+default: DBPRINT(sc, BCE_INSANE_PHY, \
+ "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", \
+ __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff); \
}
#else
@@ -574,55 +558,55 @@
/* Device identification definitions. */
/****************************************************************************/
#define BRCM_VENDORID 0x14E4
-#define BRCM_DEVICEID_BCM5706 0x164A
-#define BRCM_DEVICEID_BCM5706S 0x16AA
-#define BRCM_DEVICEID_BCM5708 0x164C
-#define BRCM_DEVICEID_BCM5708S 0x16AC
-#define BRCM_DEVICEID_BCM5709 0x1639
-#define BRCM_DEVICEID_BCM5709S 0x163A
-#define BRCM_DEVICEID_BCM5716 0x163B
+#define BRCM_DEVICEID_BCM5706 0x164A
+#define BRCM_DEVICEID_BCM5706S 0x16AA
+#define BRCM_DEVICEID_BCM5708 0x164C
+#define BRCM_DEVICEID_BCM5708S 0x16AC
+#define BRCM_DEVICEID_BCM5709 0x1639
+#define BRCM_DEVICEID_BCM5709S 0x163A
+#define BRCM_DEVICEID_BCM5716 0x163B
-#define HP_VENDORID 0x103C
+#define HP_VENDORID 0x103C
-#define PCI_ANY_ID (u_int16_t) (~0U)
+#define PCI_ANY_ID (u_int16_t) (~0U)
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
-#define BCE_CHIP_NUM(sc) (((sc)->bce_chipid) & 0xffff0000)
-#define BCE_CHIP_NUM_5706 0x57060000
-#define BCE_CHIP_NUM_5708 0x57080000
-#define BCE_CHIP_NUM_5709 0x57090000
-#define BCE_CHIP_NUM_5716 0x57160000
-
-#define BCE_CHIP_REV(sc) (((sc)->bce_chipid) & 0x0000f000)
-#define BCE_CHIP_REV_Ax 0x00000000
-#define BCE_CHIP_REV_Bx 0x00001000
-#define BCE_CHIP_REV_Cx 0x00002000
-
-#define BCE_CHIP_METAL(sc) (((sc)->bce_chipid) & 0x00000ff0)
-#define BCE_CHIP_BOND(bp) (((sc)->bce_chipid) & 0x0000000f)
-
-#define BCE_CHIP_ID(sc) (((sc)->bce_chipid) & 0xfffffff0)
-#define BCE_CHIP_ID_5706_A0 0x57060000
-#define BCE_CHIP_ID_5706_A1 0x57060010
-#define BCE_CHIP_ID_5706_A2 0x57060020
-#define BCE_CHIP_ID_5706_A3 0x57060030
-#define BCE_CHIP_ID_5708_A0 0x57080000
-#define BCE_CHIP_ID_5708_B0 0x57081000
-#define BCE_CHIP_ID_5708_B1 0x57081010
-#define BCE_CHIP_ID_5708_B2 0x57081020
-#define BCE_CHIP_ID_5709_A0 0x57090000
-#define BCE_CHIP_ID_5709_A1 0x57090010
-#define BCE_CHIP_ID_5709_B0 0x57091000
-#define BCE_CHIP_ID_5709_B1 0x57091010
-#define BCE_CHIP_ID_5709_B2 0x57091020
-#define BCE_CHIP_ID_5709_C0 0x57092000
-#define BCE_CHIP_ID_5716_C0 0x57162000
+#define BCE_CHIP_NUM(sc) (((sc)->bce_chipid) & 0xffff0000)
+#define BCE_CHIP_NUM_5706 0x57060000
+#define BCE_CHIP_NUM_5708 0x57080000
+#define BCE_CHIP_NUM_5709 0x57090000
+#define BCE_CHIP_NUM_5716 0x57160000
+
+#define BCE_CHIP_REV(sc) (((sc)->bce_chipid) & 0x0000f000)
+#define BCE_CHIP_REV_Ax 0x00000000
+#define BCE_CHIP_REV_Bx 0x00001000
+#define BCE_CHIP_REV_Cx 0x00002000
+
+#define BCE_CHIP_METAL(sc) (((sc)->bce_chipid) & 0x00000ff0)
+#define BCE_CHIP_BOND(bp) (((sc)->bce_chipid) & 0x0000000f)
+
+#define BCE_CHIP_ID(sc) (((sc)->bce_chipid) & 0xfffffff0)
+#define BCE_CHIP_ID_5706_A0 0x57060000
+#define BCE_CHIP_ID_5706_A1 0x57060010
+#define BCE_CHIP_ID_5706_A2 0x57060020
+#define BCE_CHIP_ID_5706_A3 0x57060030
+#define BCE_CHIP_ID_5708_A0 0x57080000
+#define BCE_CHIP_ID_5708_B0 0x57081000
+#define BCE_CHIP_ID_5708_B1 0x57081010
+#define BCE_CHIP_ID_5708_B2 0x57081020
+#define BCE_CHIP_ID_5709_A0 0x57090000
+#define BCE_CHIP_ID_5709_A1 0x57090010
+#define BCE_CHIP_ID_5709_B0 0x57091000
+#define BCE_CHIP_ID_5709_B1 0x57091010
+#define BCE_CHIP_ID_5709_B2 0x57091020
+#define BCE_CHIP_ID_5709_C0 0x57092000
+#define BCE_CHIP_ID_5716_C0 0x57162000
#define BCE_CHIP_BOND_ID(sc) (((sc)->bce_chipid) & 0xf)
/* A serdes chip will have the first bit of the bond id set. */
-#define BCE_CHIP_BOND_ID_SERDES_BIT 0x01
+#define BCE_CHIP_BOND_ID_SERDES_BIT 0x01
/* shorthand one */
@@ -637,11 +621,11 @@
#define BCE_CHIPREV_5701_AX 0x00
struct bce_type {
- u_int16_t bce_vid;
- u_int16_t bce_did;
- u_int16_t bce_svid;
- u_int16_t bce_sdid;
- char *bce_name;
+ u_int16_t bce_vid;
+ u_int16_t bce_did;
+ u_int16_t bce_svid;
+ u_int16_t bce_sdid;
+ char *bce_name;
};
/****************************************************************************/
@@ -683,44 +667,43 @@ struct bce_type {
/****************************************************************************/
/* Buffered flash (Atmel: AT45DB011B) specific information */
-#define SEEPROM_PAGE_BITS 2
-#define SEEPROM_PHY_PAGE_SIZE (1 << SEEPROM_PAGE_BITS)
-#define SEEPROM_BYTE_ADDR_MASK (SEEPROM_PHY_PAGE_SIZE-1)
-#define SEEPROM_PAGE_SIZE 4
-#define SEEPROM_TOTAL_SIZE 65536
+#define SEEPROM_PAGE_BITS 2
+#define SEEPROM_PHY_PAGE_SIZE (1 << SEEPROM_PAGE_BITS)
+#define SEEPROM_BYTE_ADDR_MASK (SEEPROM_PHY_PAGE_SIZE-1)
+#define SEEPROM_PAGE_SIZE 4
+#define SEEPROM_TOTAL_SIZE 65536
-#define BUFFERED_FLASH_PAGE_BITS 9
+#define BUFFERED_FLASH_PAGE_BITS 9
#define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS)
#define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1)
-#define BUFFERED_FLASH_PAGE_SIZE 264
-#define BUFFERED_FLASH_TOTAL_SIZE 0x21000
+#define BUFFERED_FLASH_PAGE_SIZE 264
+#define BUFFERED_FLASH_TOTAL_SIZE 0x21000
-#define SAIFUN_FLASH_PAGE_BITS 8
-#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS)
-#define SAIFUN_FLASH_BYTE_ADDR_MASK (SAIFUN_FLASH_PHY_PAGE_SIZE-1)
-#define SAIFUN_FLASH_PAGE_SIZE 256
+#define SAIFUN_FLASH_PAGE_BITS 8
+#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS)
+#define SAIFUN_FLASH_BYTE_ADDR_MASK (SAIFUN_FLASH_PHY_PAGE_SIZE-1)
+#define SAIFUN_FLASH_PAGE_SIZE 256
#define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536
-#define ST_MICRO_FLASH_PAGE_BITS 8
+#define ST_MICRO_FLASH_PAGE_BITS 8
#define ST_MICRO_FLASH_PHY_PAGE_SIZE (1 << ST_MICRO_FLASH_PAGE_BITS)
#define ST_MICRO_FLASH_BYTE_ADDR_MASK (ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
-#define ST_MICRO_FLASH_PAGE_SIZE 256
+#define ST_MICRO_FLASH_PAGE_SIZE 256
#define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536
-#define BCM5709_FLASH_PAGE_BITS 8
-#define BCM5709_FLASH_PHY_PAGE_SIZE (1 << BCM5709_FLASH_PAGE_BITS)
+#define BCM5709_FLASH_PAGE_BITS 8
+#define BCM5709_FLASH_PHY_PAGE_SIZE (1 << BCM5709_FLASH_PAGE_BITS)
#define BCM5709_FLASH_BYTE_ADDR_MASK (BCM5709_FLASH_PHY_PAGE_SIZE-1)
-#define BCM5709_FLASH_PAGE_SIZE 256
+#define BCM5709_FLASH_PAGE_SIZE 256
-#define NVRAM_TIMEOUT_COUNT 30000
-#define BCE_FLASHDESC_MAX 64
+#define NVRAM_TIMEOUT_COUNT 30000
+#define BCE_FLASHDESC_MAX 64
-#define FLASH_STRAP_MASK (BCE_NVM_CFG1_FLASH_MODE | \
- BCE_NVM_CFG1_BUFFER_MODE | \
- BCE_NVM_CFG1_PROTECT_MODE | \
- BCE_NVM_CFG1_FLASH_SIZE)
+#define FLASH_STRAP_MASK (BCE_NVM_CFG1_FLASH_MODE | \
+ BCE_NVM_CFG1_BUFFER_MODE | BCE_NVM_CFG1_PROTECT_MODE | \
+ BCE_NVM_CFG1_FLASH_SIZE)
-#define FLASH_BACKUP_STRAP_MASK (0xf << 26)
+#define FLASH_BACKUP_STRAP_MASK (0xf << 26)
struct flash_spec {
u32 strapping;
@@ -730,7 +713,7 @@ struct flash_spec {
u32 write1;
#define BCE_NV_BUFFERED 0x00000001
#define BCE_NV_TRANSLATE 0x00000002
-#define BCE_NV_WREN 0x00000004
+#define BCE_NV_WREN 0x00000004
u32 flags;
u32 page_bits;
u32 page_size;
@@ -760,50 +743,52 @@ struct flash_spec {
* running and there won't be any firmware-driver synchronization during a
* driver reset.
*/
-#define FW_ACK_TIME_OUT_MS 1000
+#define FW_ACK_TIME_OUT_MS 1000
-#define BCE_DRV_RESET_SIGNATURE 0x00000000
+#define BCE_DRV_RESET_SIGNATURE 0x00000000
#define BCE_DRV_RESET_SIGNATURE_MAGIC 0x4841564b /* HAVK */
-#define BCE_DRV_MB 0x00000004
-#define BCE_DRV_MSG_CODE 0xff000000
-#define BCE_DRV_MSG_CODE_RESET 0x01000000
-#define BCE_DRV_MSG_CODE_UNLOAD 0x02000000
-#define BCE_DRV_MSG_CODE_SHUTDOWN 0x03000000
+#define BCE_DRV_MB 0x00000004
+#define BCE_DRV_MSG_CODE 0xff000000
+#define BCE_DRV_MSG_CODE_RESET 0x01000000
+#define BCE_DRV_MSG_CODE_UNLOAD 0x02000000
+#define BCE_DRV_MSG_CODE_SHUTDOWN 0x03000000
#define BCE_DRV_MSG_CODE_SUSPEND_WOL 0x04000000
-#define BCE_DRV_MSG_CODE_FW_TIMEOUT 0x05000000
-#define BCE_DRV_MSG_CODE_PULSE 0x06000000
-#define BCE_DRV_MSG_CODE_DIAG 0x07000000
+#define BCE_DRV_MSG_CODE_FW_TIMEOUT 0x05000000
+#define BCE_DRV_MSG_CODE_PULSE 0x06000000
+#define BCE_DRV_MSG_CODE_DIAG 0x07000000
#define BCE_DRV_MSG_CODE_SUSPEND_NO_WOL 0x09000000
#define BCE_DRV_MSG_CODE_UNLOAD_LNK_DN 0x0b000000
#define BCE_DRV_MSG_CODE_CMD_SET_LINK 0x10000000
-#define BCE_DRV_MSG_DATA 0x00ff0000
-#define BCE_DRV_MSG_DATA_WAIT0 0x00010000
-#define BCE_DRV_MSG_DATA_WAIT1 0x00020000
-#define BCE_DRV_MSG_DATA_WAIT2 0x00030000
-#define BCE_DRV_MSG_DATA_WAIT3 0x00040000
+#define BCE_DRV_MSG_DATA 0x00ff0000
+#define BCE_DRV_MSG_DATA_WAIT0 0x00010000
+#define BCE_DRV_MSG_DATA_WAIT1 0x00020000
+#define BCE_DRV_MSG_DATA_WAIT2 0x00030000
+#define BCE_DRV_MSG_DATA_WAIT3 0x00040000
-#define BCE_DRV_MSG_SEQ 0x0000ffff
+#define BCE_DRV_MSG_SEQ 0x0000ffff
#define BCE_FW_MB 0x00000008
#define BCE_FW_MSG_ACK 0x0000ffff
#define BCE_FW_MSG_STATUS_MASK 0x00ff0000
#define BCE_FW_MSG_STATUS_OK 0x00000000
+#define BCE_FW_MSG_STATUS_INVALID_ARGS 0x00010000
+#define BCE_FW_MSG_STATUS_DRV_PRSNT 0x00020000
#define BCE_FW_MSG_STATUS_FAILURE 0x00ff0000
-#define BCE_LINK_STATUS 0x0000000c
+#define BCE_LINK_STATUS 0x0000000c
#define BCE_LINK_STATUS_INIT_VALUE 0xffffffff
-#define BCE_LINK_STATUS_LINK_UP 0x1
+#define BCE_LINK_STATUS_LINK_UP 0x1
#define BCE_LINK_STATUS_LINK_DOWN 0x0
#define BCE_LINK_STATUS_SPEED_MASK 0x1e
#define BCE_LINK_STATUS_AN_INCOMPLETE (0<<1)
#define BCE_LINK_STATUS_10HALF (1<<1)
#define BCE_LINK_STATUS_10FULL (2<<1)
-#define BCE_LINK_STATUS_100HALF (3<<1)
+#define BCE_LINK_STATUS_100HALF (3<<1)
#define BCE_LINK_STATUS_100BASE_T4 (4<<1)
-#define BCE_LINK_STATUS_100FULL (5<<1)
+#define BCE_LINK_STATUS_100FULL (5<<1)
#define BCE_LINK_STATUS_1000HALF (6<<1)
#define BCE_LINK_STATUS_1000FULL (7<<1)
#define BCE_LINK_STATUS_2500HALF (8<<1)
@@ -860,9 +845,9 @@ struct flash_spec {
#define BCE_SHARED_HW_CFG_PHY_COPPER 0
#define BCE_SHARED_HW_CFG_PHY_FIBER 0x2
#define BCE_SHARED_HW_CFG_PHY_2_5G 0x20
-#define BCE_SHARED_HW_CFG_PHY_BACKPLANE 0x40
+#define BCE_SHARED_HW_CFG_PHY_BACKPLANE 0x40
#define BCE_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8
-#define BCE_SHARED_HW_CFG_LED_MODE_MASK 0x300
+#define BCE_SHARED_HW_CFG_LED_MODE_MASK 0x300
#define BCE_SHARED_HW_CFG_LED_MODE_MAC 0
#define BCE_SHARED_HW_CFG_LED_MODE_GPHY1 0x100
#define BCE_SHARED_HW_CFG_LED_MODE_GPHY2 0x200
@@ -877,27 +862,27 @@ struct flash_spec {
#define BCE_PORT_HW_CFG_MAC_LOWER 0x00000054
#define BCE_PORT_HW_CFG_CONFIG 0x00000058
-#define BCE_PORT_HW_CFG_CFG_TXCTL3_MASK 0x0000ffff
+#define BCE_PORT_HW_CFG_CFG_TXCTL3_MASK 0x0000ffff
#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000
#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000
#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000
#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_2_5G 0x00040000
-#define BCE_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068
-#define BCE_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c
-#define BCE_PORT_HW_CFG_IMD_MAC_B_UPPER 0x00000070
-#define BCE_PORT_HW_CFG_IMD_MAC_B_LOWER 0x00000074
-#define BCE_PORT_HW_CFG_ISCSI_MAC_UPPER 0x00000078
-#define BCE_PORT_HW_CFG_ISCSI_MAC_LOWER 0x0000007c
+#define BCE_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068
+#define BCE_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c
+#define BCE_PORT_HW_CFG_IMD_MAC_B_UPPER 0x00000070
+#define BCE_PORT_HW_CFG_IMD_MAC_B_LOWER 0x00000074
+#define BCE_PORT_HW_CFG_ISCSI_MAC_UPPER 0x00000078
+#define BCE_PORT_HW_CFG_ISCSI_MAC_LOWER 0x0000007c
#define BCE_DEV_INFO_PER_PORT_HW_CONFIG2 0x000000b4
-#define BCE_DEV_INFO_FORMAT_REV 0x000000c4
+#define BCE_DEV_INFO_FORMAT_REV 0x000000c4
#define BCE_DEV_INFO_FORMAT_REV_MASK 0xff000000
#define BCE_DEV_INFO_FORMAT_REV_ID ('A' << 24)
#define BCE_SHARED_FEATURE 0x000000c8
-#define BCE_SHARED_FEATURE_MASK 0xffffffff
+#define BCE_SHARED_FEATURE_MASK 0xffffffff
#define BCE_PORT_FEATURE 0x000000d8
#define BCE_PORT2_FEATURE 0x00000014c
@@ -905,12 +890,12 @@ struct flash_spec {
#define BCE_PORT_FEATURE_MBA_ENABLED 0x02000000
#define BCE_PORT_FEATURE_ASF_ENABLED 0x04000000
#define BCE_PORT_FEATURE_IMD_ENABLED 0x08000000
-#define BCE_PORT_FEATURE_BAR1_SIZE_MASK 0xf
+#define BCE_PORT_FEATURE_BAR1_SIZE_MASK 0xf
#define BCE_PORT_FEATURE_BAR1_SIZE_DISABLED 0x0
#define BCE_PORT_FEATURE_BAR1_SIZE_64K 0x1
-#define BCE_PORT_FEATURE_BAR1_SIZE_128K 0x2
-#define BCE_PORT_FEATURE_BAR1_SIZE_256K 0x3
-#define BCE_PORT_FEATURE_BAR1_SIZE_512K 0x4
+#define BCE_PORT_FEATURE_BAR1_SIZE_128K 0x2
+#define BCE_PORT_FEATURE_BAR1_SIZE_256K 0x3
+#define BCE_PORT_FEATURE_BAR1_SIZE_512K 0x4
#define BCE_PORT_FEATURE_BAR1_SIZE_1M 0x5
#define BCE_PORT_FEATURE_BAR1_SIZE_2M 0x6
#define BCE_PORT_FEATURE_BAR1_SIZE_4M 0x7
@@ -918,9 +903,9 @@ struct flash_spec {
#define BCE_PORT_FEATURE_BAR1_SIZE_16M 0x9
#define BCE_PORT_FEATURE_BAR1_SIZE_32M 0xa
#define BCE_PORT_FEATURE_BAR1_SIZE_64M 0xb
-#define BCE_PORT_FEATURE_BAR1_SIZE_128M 0xc
-#define BCE_PORT_FEATURE_BAR1_SIZE_256M 0xd
-#define BCE_PORT_FEATURE_BAR1_SIZE_512M 0xe
+#define BCE_PORT_FEATURE_BAR1_SIZE_128M 0xc
+#define BCE_PORT_FEATURE_BAR1_SIZE_256M 0xd
+#define BCE_PORT_FEATURE_BAR1_SIZE_512M 0xe
#define BCE_PORT_FEATURE_BAR1_SIZE_1G 0xf
#define BCE_PORT_FEATURE_WOL 0xdc
@@ -935,12 +920,12 @@ struct flash_spec {
#define BCE_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG 0
#define BCE_PORT_FEATURE_WOL_LINK_SPEED_10HALF 1
#define BCE_PORT_FEATURE_WOL_LINK_SPEED_10FULL 2
-#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3
-#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4
+#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3
+#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4
#define BCE_PORT_FEATURE_WOL_LINK_SPEED_1000HALF 5
#define BCE_PORT_FEATURE_WOL_LINK_SPEED_1000FULL 6
#define BCE_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000 0x40
-#define BCE_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400
+#define BCE_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400
#define BCE_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP 0x800
#define BCE_PORT_FEATURE_MBA 0xe0
@@ -957,9 +942,9 @@ struct flash_spec {
#define BCE_PORT_FEATURE_MBA_LINK_SPEED_10FULL 0x8
#define BCE_PORT_FEATURE_MBA_LINK_SPEED_100HALF 0xc
#define BCE_PORT_FEATURE_MBA_LINK_SPEED_100FULL 0x10
-#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000HALF 0x14
-#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000FULL 0x18
-#define BCE_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x40
+#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000HALF 0x14
+#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000FULL 0x18
+#define BCE_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x40
#define BCE_PORT_FEATURE_MBA_HOTKEY_CTRL_S 0
#define BCE_PORT_FEATURE_MBA_HOTKEY_CTRL_B 0x80
#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS 8
@@ -999,36 +984,37 @@ struct flash_spec {
#define BCE_PORT_FEATURE_MBA_VLAN_TAG_MASK 0xffff
#define BCE_PORT_FEATURE_MBA_VLAN_ENABLE 0x10000
-#define BCE_MFW_VER_PTR 0x00000014c
+#define BCE_MFW_VER_PTR 0x00000014c
-#define BCE_BC_STATE_RESET_TYPE 0x000001c0
+#define BCE_BC_STATE_RESET_TYPE 0x000001c0
#define BCE_BC_STATE_RESET_TYPE_SIG 0x00005254
#define BCE_BC_STATE_RESET_TYPE_SIG_MASK 0x0000ffff
-#define BCE_BC_STATE_RESET_TYPE_NONE (BCE_BC_STATE_RESET_TYPE_SIG | \
- 0x00010000)
-#define BCE_BC_STATE_RESET_TYPE_PCI (BCE_BC_STATE_RESET_TYPE_SIG | \
- 0x00020000)
-#define BCE_BC_STATE_RESET_TYPE_VAUX (BCE_BC_STATE_RESET_TYPE_SIG | \
- 0x00030000)
-#define BCE_BC_STATE_RESET_TYPE_DRV_MASK DRV_MSG_CODE
-#define BCE_BC_STATE_RESET_TYPE_DRV_RESET (BCE_BC_STATE_RESET_TYPE_SIG | \
- DRV_MSG_CODE_RESET)
-#define BCE_BC_STATE_RESET_TYPE_DRV_UNLOAD (BCE_BC_STATE_RESET_TYPE_SIG | \
- DRV_MSG_CODE_UNLOAD)
-#define BCE_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BCE_BC_STATE_RESET_TYPE_SIG | \
- DRV_MSG_CODE_SHUTDOWN)
-#define BCE_BC_STATE_RESET_TYPE_DRV_WOL (BCE_BC_STATE_RESET_TYPE_SIG | \
- DRV_MSG_CODE_WOL)
-#define BCE_BC_STATE_RESET_TYPE_DRV_DIAG (BCE_BC_STATE_RESET_TYPE_SIG | \
- DRV_MSG_CODE_DIAG)
-#define BCE_BC_STATE_RESET_TYPE_VALUE(msg) (BCE_BC_STATE_RESET_TYPE_SIG | \
- (msg))
-
-#define BCE_BC_RESET_TYPE 0x000001c0
-
-#define BCE_BC_STATE 0x000001c4
+
+#define BCE_BC_STATE_RESET_TYPE_NONE \
+ (BCE_BC_STATE_RESET_TYPE_SIG | 0x00010000)
+#define BCE_BC_STATE_RESET_TYPE_PCI \
+ (BCE_BC_STATE_RESET_TYPE_SIG | 0x00020000)
+#define BCE_BC_STATE_RESET_TYPE_VAUX \
+ (BCE_BC_STATE_RESET_TYPE_SIG | 0x00030000)
+#define BCE_BC_STATE_RESET_TYPE_DRV_MASK DRV_MSG_CODE
+#define BCE_BC_STATE_RESET_TYPE_DRV_RESET \
+ (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_RESET)
+#define BCE_BC_STATE_RESET_TYPE_DRV_UNLOAD \
+ (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_UNLOAD)
+#define BCE_BC_STATE_RESET_TYPE_DRV_SHUTDOWN \
+ (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_SHUTDOWN)
+#define BCE_BC_STATE_RESET_TYPE_DRV_WOL \
+ (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_WOL)
+#define BCE_BC_STATE_RESET_TYPE_DRV_DIAG \
+ (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_DIAG)
+#define BCE_BC_STATE_RESET_TYPE_VALUE(msg) \
+ (BCE_BC_STATE_RESET_TYPE_SIG | (msg))
+
+#define BCE_BC_RESET_TYPE 0x000001c0
+
+#define BCE_BC_STATE 0x000001c4
#define BCE_BC_STATE_ERR_MASK 0x0000ff00
-#define BCE_BC_STATE_SIGN 0x42530000
+#define BCE_BC_STATE_SIGN 0x42530000
#define BCE_BC_STATE_SIGN_MASK 0xffff0000
#define BCE_BC_STATE_BC1_START (BCE_BC_STATE_SIGN | 0x1)
#define BCE_BC_STATE_GET_NVM_CFG1 (BCE_BC_STATE_SIGN | 0x2)
@@ -1048,24 +1034,49 @@ struct flash_spec {
#define BCE_BC_STATE_RT_SET_WOL (BCE_BC_STATE_SIGN | 0x87)
#define BCE_BC_STATE_RT_OTHER_FW (BCE_BC_STATE_SIGN | 0x88)
#define BCE_BC_STATE_RT_GOING_D3 (BCE_BC_STATE_SIGN | 0x89)
-#define BCE_BC_STATE_ERR_BAD_VERSION (BCE_BC_STATE_SIGN | 0x0100)
-#define BCE_BC_STATE_ERR_BAD_BC2_CRC (BCE_BC_STATE_SIGN | 0x0200)
+#define BCE_BC_STATE_ERR_BAD_VERSION (BCE_BC_STATE_SIGN | 0x0100)
+#define BCE_BC_STATE_ERR_BAD_BC2_CRC (BCE_BC_STATE_SIGN | 0x0200)
#define BCE_BC_STATE_ERR_BC1_LOOP (BCE_BC_STATE_SIGN | 0x0300)
-#define BCE_BC_STATE_ERR_UNKNOWN_CMD (BCE_BC_STATE_SIGN | 0x0400)
+#define BCE_BC_STATE_ERR_UNKNOWN_CMD (BCE_BC_STATE_SIGN | 0x0400)
#define BCE_BC_STATE_ERR_DRV_DEAD (BCE_BC_STATE_SIGN | 0x0500)
#define BCE_BC_STATE_ERR_NO_RXP (BCE_BC_STATE_SIGN | 0x0600)
-#define BCE_BC_STATE_ERR_TOO_MANY_RBUF (BCE_BC_STATE_SIGN | 0x0700)
-
-#define BCE_BC_STATE_CONDITION 0x000001c8
-#define BCE_CONDITION_MFW_RUN_UNKNOWN 0x00000000
-#define BCE_CONDITION_MFW_RUN_IPMI 0x00002000
-#define BCE_CONDITION_MFW_RUN_UMP 0x00004000
-#define BCE_CONDITION_MFW_RUN_NCSI 0x00006000
+#define BCE_BC_STATE_ERR_TOO_MANY_RBUF (BCE_BC_STATE_SIGN | 0x0700)
+
+#define BCE_BC_STATE_CONDITION 0x000001c8
+#define BCE_CONDITION_INIT_POR 0x00000001
+#define BCE_CONDITION_INIT_VAUX_AVAIL 0x00000002
+#define BCE_CONDITION_INIT_PCI_AVAIL 0x00000004
+#define BCE_CONDITION_INIT_PCI_RESET 0x00000008
+#define BCE_CONDITION_INIT_HD_RESET 0x00000010 /* 5709/16 only */
+#define BCE_CONDITION_DRV_PRESENT 0x00000100
+#define BCE_CONDITION_LOW_POWER_LINK 0x00000200
+#define BCE_CONDITION_CORE_RST_OCCURRED 0x00000400 /* 5709/16 only */
+#define BCE_CONDITION_UNUSED 0x00000800
+#define BCE_CONDITION_BUSY_EXPROM 0x00001000 /* 5706/08 only */
+
+#define BCE_CONDITION_MFW_RUN_UNKNOWN 0x00000000
+#define BCE_CONDITION_MFW_RUN_IPMI 0x00002000
+#define BCE_CONDITION_MFW_RUN_UMP 0x00004000
+#define BCE_CONDITION_MFW_RUN_NCSI 0x00006000
#define BCE_CONDITION_MFW_RUN_NONE 0x0000e000
#define BCE_CONDITION_MFW_RUN_MASK 0x0000e000
-#define BCE_BC_STATE_DEBUG_CMD 0x1dc
-#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000
+/* 5709/16 only */
+#define BCE_CONDITION_PM_STATE_MASK 0x00030000
+#define BCE_CONDITION_PM_STATE_FULL 0x00030000
+#define BCE_CONDITION_PM_STATE_PREP 0x00020000
+#define BCE_CONDITION_PM_STATE_UNPREP 0x00010000
+#define BCE_CONDITION_PM_RESERVED 0x00000000
+
+/* 5709/16 only */
+#define BCE_CONDITION_RXMODE_KEEP_VLAN 0x00040000
+#define BCE_CONDITION_DRV_WOL_ENABLED 0x00080000
+#define BCE_CONDITION_PORT_DISABLED 0x00100000
+#define BCE_CONDITION_DRV_MAYBE_OUT 0x00200000
+#define BCE_CONDITION_DPFW_DEAD 0x00400000
+
+#define BCE_BC_STATE_DEBUG_CMD 0x000001dc
+#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000
#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK 0xffff0000
#define BCE_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK 0xffff
#define BCE_BC_STATE_BC_DBG_CMD_LOOP_INFINITE 0xffff
@@ -1081,40 +1092,51 @@ struct flash_spec {
/****************************************************************************/
/* Convenience definitions. */
/****************************************************************************/
-#define BCE_PRINTF(fmt, args...) device_printf(sc->bce_dev, fmt, ##args)
+#define BCE_PRINTF(fmt, args...) \
+ device_printf(sc->bce_dev, fmt, ##args)
-#define BCE_LOCK_INIT(_sc, _name) mtx_init(&(_sc)->bce_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
-#define BCE_LOCK(_sc) mtx_lock(&(_sc)->bce_mtx)
+#define BCE_LOCK_INIT(_sc, _name) \
+ mtx_init(&(_sc)->bce_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
+#define BCE_LOCK(_sc) mtx_lock(&(_sc)->bce_mtx)
#define BCE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->bce_mtx, MA_OWNED)
-#define BCE_UNLOCK(_sc) mtx_unlock(&(_sc)->bce_mtx)
+#define BCE_UNLOCK(_sc) mtx_unlock(&(_sc)->bce_mtx)
#define BCE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->bce_mtx)
#ifdef BCE_DEBUG
-#define REG_WR(sc, offset, val) bce_reg_wr(sc, offset, val)
-#define REG_WR16(sc, offset, val) bce_reg_wr16(sc, offset, val)
-#define REG_RD(sc, offset) bce_reg_rd(sc, offset)
+#define REG_WR(sc, offset, val) bce_reg_wr(sc, offset, val)
+#define REG_WR16(sc, offset, val) bce_reg_wr16(sc, offset, val)
+#define REG_RD(sc, offset) bce_reg_rd(sc, offset)
#else
-#define REG_WR(sc, offset, val) bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val)
-#define REG_WR16(sc, offset, val) bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val)
-#define REG_RD(sc, offset) bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset)
+#define REG_WR(sc, offset, val) \
+ bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val)
+#define REG_WR16(sc, offset, val) \
+ bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val)
+#define REG_RD(sc, offset) \
+ bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset)
#endif
-#define REG_RD_IND(sc, offset) bce_reg_rd_ind(sc, offset)
-#define REG_WR_IND(sc, offset, val) bce_reg_wr_ind(sc, offset, val)
-#define CTX_WR(sc, cid_addr, offset, val) bce_ctx_wr(sc, cid_addr, offset, val)
-#define CTX_RD(sc, cid_addr, offset) bce_ctx_rd(sc, cid_addr, offset)
-#define BCE_SETBIT(sc, reg, x) REG_WR(sc, reg, (REG_RD(sc, reg) | (x)))
-#define BCE_CLRBIT(sc, reg, x) REG_WR(sc, reg, (REG_RD(sc, reg) & ~(x)))
-#define PCI_SETBIT(dev, reg, x, s) pci_write_config(dev, reg, (pci_read_config(dev, reg, s) | (x)), s)
-#define PCI_CLRBIT(dev, reg, x, s) pci_write_config(dev, reg, (pci_read_config(dev, reg, s) & ~(x)), s)
+#define REG_RD_IND(sc, offset) bce_reg_rd_ind(sc, offset)
+#define REG_WR_IND(sc, offset, val) bce_reg_wr_ind(sc, offset, val)
+#define CTX_WR(sc, cid_addr, offset, val)bce_ctx_wr(sc, cid_addr, offset, val)
+#define CTX_RD(sc, cid_addr, offset) bce_ctx_rd(sc, cid_addr, offset)
+
+#define BCE_SETBIT(sc, reg, x) \
+ REG_WR(sc, reg, (REG_RD(sc, reg) | (x)))
+#define BCE_CLRBIT(sc, reg, x) \
+ REG_WR(sc, reg, (REG_RD(sc, reg) & ~(x)))
+#define PCI_SETBIT(dev, reg, x, s) \
+ pci_write_config(dev, reg, (pci_read_config(dev, reg, s) | (x)), s)
+#define PCI_CLRBIT(dev, reg, x, s) \
+ pci_write_config(dev, reg, (pci_read_config(dev, reg, s) & ~(x)), s)
+
+#define BCE_STATS(x) (u_long) stats->stat_ ## x ## _lo
-#define BCE_STATS(x) (u_long) stats->stat_ ## x ## _lo
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
-#define BCE_ADDR_LO(y) ((u64) (y) & 0xFFFFFFFF)
-#define BCE_ADDR_HI(y) ((u64) (y) >> 32)
+#define BCE_ADDR_LO(y) ((u64) (y) & 0xFFFFFFFF)
+#define BCE_ADDR_HI(y) ((u64) (y) >> 32)
#else
-#define BCE_ADDR_LO(y) ((u32)y)
-#define BCE_ADDR_HI(y) (0)
+#define BCE_ADDR_LO(y) ((u32)y)
+#define BCE_ADDR_HI(y) (0)
#endif
@@ -1180,7 +1202,7 @@ struct status_block {
#define STATUS_ATTN_BITS_TX_PATCHUP_ABORT (1L<<6)
#define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT (1L<<7)
#define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT (1L<<8)
- #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT (1L<<9)
+ #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT (1L<<9)
#define STATUS_ATTN_BITS_RX_MBUF_ABORT (1L<<10)
#define STATUS_ATTN_BITS_RX_LOOKUP_ABORT (1L<<11)
#define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT (1L<<12)
@@ -1383,90 +1405,90 @@ struct l2_fhdr {
};
#define BCE_L2FHDR_PRINTFB \
- "\20" \
- "\40UDP_XSUM_ERR" \
- "\37b30" \
- "\36b29" \
- "\35TCP_XSUM_ERR" \
- "\34b27" \
- "\33b26" \
- "\32b25" \
- "\31b24" \
- "\30b23" \
- "\27b22" \
- "\26GIANT_ERR" \
- "\25SHORT_ERR" \
- "\24ALIGN_ERR" \
- "\23PHY_ERR" \
- "\22CRC_ERR" \
- "\21SPLIT" \
- "\20UDP" \
- "\17TCP" \
- "\16IP" \
- "\15b12" \
- "\14b11" \
- "\13b10" \
- "\12b09" \
- "\11RSS" \
- "\10SNAP" \
- "\07VLAN" \
- "\06P4" \
- "\05P3" \
+ "\20" \
+ "\40UDP_XSUM_ERR" \
+ "\37b30" \
+ "\36b29" \
+ "\35TCP_XSUM_ERR" \
+ "\34b27" \
+ "\33b26" \
+ "\32b25" \
+ "\31b24" \
+ "\30b23" \
+ "\27b22" \
+ "\26GIANT_ERR" \
+ "\25SHORT_ERR" \
+ "\24ALIGN_ERR" \
+ "\23PHY_ERR" \
+ "\22CRC_ERR" \
+ "\21SPLIT" \
+ "\20UDP" \
+ "\17TCP" \
+ "\16IP" \
+ "\15b12" \
+ "\14b11" \
+ "\13b10" \
+ "\12b09" \
+ "\11RSS" \
+ "\10SNAP" \
+ "\07VLAN" \
+ "\06P4" \
+ "\05P3" \
"\04P2"
/*
* l2_tx_context definition (5706 and 5708)
*/
-#define BCE_L2CTX_TX_TYPE 0x00000000
-#define BCE_L2CTX_TX_TYPE_SIZE_L2 ((0xc0/0x20)<<16)
-#define BCE_L2CTX_TX_TYPE_TYPE (0xf<<28)
-#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY (0<<28)
-#define BCE_L2CTX_TX_TYPE_TYPE_L2 (1<<28)
-
-#define BCE_L2CTX_TX_HOST_BIDX 0x00000088
-#define BCE_L2CTX_TX_EST_NBD 0x00000088
-#define BCE_L2CTX_TX_CMD_TYPE 0x00000088
-#define BCE_L2CTX_TX_CMD_TYPE_TYPE (0xf<<24)
-#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 (0<<24)
-#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP (1<<24)
-
-#define BCE_L2CTX_TX_HOST_BSEQ 0x00000090
-#define BCE_L2CTX_TX_TSCH_BSEQ 0x00000094
-#define BCE_L2CTX_TX_TBDR_BSEQ 0x00000098
-#define BCE_L2CTX_TX_TBDR_BOFF 0x0000009c
-#define BCE_L2CTX_TX_TBDR_BIDX 0x0000009c
-#define BCE_L2CTX_TX_TBDR_BHADDR_HI 0x000000a0
-#define BCE_L2CTX_TX_TBDR_BHADDR_LO 0x000000a4
-#define BCE_L2CTX_TX_TXP_BOFF 0x000000a8
-#define BCE_L2CTX_TX_TXP_BIDX 0x000000a8
-#define BCE_L2CTX_TX_TXP_BSEQ 0x000000ac
+#define BCE_L2CTX_TX_TYPE 0x00000000
+#define BCE_L2CTX_TX_TYPE_SIZE_L2 ((0xc0/0x20)<<16)
+#define BCE_L2CTX_TX_TYPE_TYPE (0xf<<28)
+#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY (0<<28)
+#define BCE_L2CTX_TX_TYPE_TYPE_L2 (1<<28)
+
+#define BCE_L2CTX_TX_HOST_BIDX 0x00000088
+#define BCE_L2CTX_TX_EST_NBD 0x00000088
+#define BCE_L2CTX_TX_CMD_TYPE 0x00000088
+#define BCE_L2CTX_TX_CMD_TYPE_TYPE (0xf<<24)
+#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 (0<<24)
+#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP (1<<24)
+
+#define BCE_L2CTX_TX_HOST_BSEQ 0x00000090
+#define BCE_L2CTX_TX_TSCH_BSEQ 0x00000094
+#define BCE_L2CTX_TX_TBDR_BSEQ 0x00000098
+#define BCE_L2CTX_TX_TBDR_BOFF 0x0000009c
+#define BCE_L2CTX_TX_TBDR_BIDX 0x0000009c
+#define BCE_L2CTX_TX_TBDR_BHADDR_HI 0x000000a0
+#define BCE_L2CTX_TX_TBDR_BHADDR_LO 0x000000a4
+#define BCE_L2CTX_TX_TXP_BOFF 0x000000a8
+#define BCE_L2CTX_TX_TXP_BIDX 0x000000a8
+#define BCE_L2CTX_TX_TXP_BSEQ 0x000000ac
/*
* l2_tx_context definition (5709 and 5716)
*/
-#define BCE_L2CTX_TX_TYPE_XI 0x00000080
-#define BCE_L2CTX_TX_TYPE_SIZE_L2_XI ((0xc0/0x20)<<16)
-#define BCE_L2CTX_TX_TYPE_TYPE_XI (0xf<<28)
+#define BCE_L2CTX_TX_TYPE_XI 0x00000080
+#define BCE_L2CTX_TX_TYPE_SIZE_L2_XI ((0xc0/0x20)<<16)
+#define BCE_L2CTX_TX_TYPE_TYPE_XI (0xf<<28)
#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY_XI (0<<28)
-#define BCE_L2CTX_TX_TYPE_TYPE_L2_XI (1<<28)
-
-#define BCE_L2CTX_TX_CMD_TYPE_XI 0x00000240
-#define BCE_L2CTX_TX_CMD_TYPE_TYPE_XI (0xf<<24)
+#define BCE_L2CTX_TX_TYPE_TYPE_L2_XI (1<<28)
+
+#define BCE_L2CTX_TX_CMD_TYPE_XI 0x00000240
+#define BCE_L2CTX_TX_CMD_TYPE_TYPE_XI (0xf<<24)
#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI (0<<24)
#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP_XI (1<<24)
-#define BCE_L2CTX_TX_HOST_BIDX_XI 0x00000240
-#define BCE_L2CTX_TX_HOST_BSEQ_XI 0x00000248
-#define BCE_L2CTX_TX_TBDR_BHADDR_HI_XI 0x00000258
-#define BCE_L2CTX_TX_TBDR_BHADDR_LO_XI 0x0000025c
+#define BCE_L2CTX_TX_HOST_BIDX_XI 0x00000240
+#define BCE_L2CTX_TX_HOST_BSEQ_XI 0x00000248
+#define BCE_L2CTX_TX_TBDR_BHADDR_HI_XI 0x00000258
+#define BCE_L2CTX_TX_TBDR_BHADDR_LO_XI 0x0000025c
/*
* l2_rx_context definition (5706, 5708, 5709, and 5716)
*/
-#define BCE_L2CTX_RX_WATER_MARK 0x00000000
-#define BCE_L2CTX_RX_LO_WATER_MARK_SHIFT 0
+#define BCE_L2CTX_RX_WATER_MARK 0x00000000
+#define BCE_L2CTX_RX_LO_WATER_MARK_SHIFT 0
#define BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT 32
#define BCE_L2CTX_RX_LO_WATER_MARK_SCALE 4
#define BCE_L2CTX_RX_LO_WATER_MARK_DIS 0
@@ -1474,52 +1496,53 @@ struct l2_fhdr {
#define BCE_L2CTX_RX_HI_WATER_MARK_SCALE 16
#define BCE_L2CTX_RX_WATER_MARKS_MSK 0x000000ff
-#define BCE_L2CTX_RX_BD_PRE_READ 0x00000000
+#define BCE_L2CTX_RX_BD_PRE_READ 0x00000000
#define BCE_L2CTX_RX_BD_PRE_READ_SHIFT 8
-#define BCE_L2CTX_RX_CTX_SIZE 0x00000000
-#define BCE_L2CTX_RX_CTX_SIZE_SHIFT 16
-#define BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 ((0x20/20)<<BCE_L2CTX_RX_CTX_SIZE_SHIFT)
+#define BCE_L2CTX_RX_CTX_SIZE 0x00000000
+#define BCE_L2CTX_RX_CTX_SIZE_SHIFT 16
+#define BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 \
+ ((0x20/20)<<BCE_L2CTX_RX_CTX_SIZE_SHIFT)
-#define BCE_L2CTX_RX_CTX_TYPE 0x00000000
-#define BCE_L2CTX_RX_CTX_TYPE_SHIFT 24
+#define BCE_L2CTX_RX_CTX_TYPE 0x00000000
+#define BCE_L2CTX_RX_CTX_TYPE_SHIFT 24
#define BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28)
#define BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28)
#define BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE (1<<28)
-#define BCE_L2CTX_RX_HOST_BDIDX 0x00000004
-#define BCE_L2CTX_RX_HOST_BSEQ 0x00000008
-#define BCE_L2CTX_RX_NX_BSEQ 0x0000000c
-#define BCE_L2CTX_RX_NX_BDHADDR_HI 0x00000010
-#define BCE_L2CTX_RX_NX_BDHADDR_LO 0x00000014
-#define BCE_L2CTX_RX_NX_BDIDX 0x00000018
-
-#define BCE_L2CTX_RX_HOST_PG_BDIDX 0x00000044
-#define BCE_L2CTX_RX_PG_BUF_SIZE 0x00000048
-#define BCE_L2CTX_RX_RBDC_KEY 0x0000004c
-#define BCE_L2CTX_RX_RBDC_JUMBO_KEY 0x3ffe
+#define BCE_L2CTX_RX_HOST_BDIDX 0x00000004
+#define BCE_L2CTX_RX_HOST_BSEQ 0x00000008
+#define BCE_L2CTX_RX_NX_BSEQ 0x0000000c
+#define BCE_L2CTX_RX_NX_BDHADDR_HI 0x00000010
+#define BCE_L2CTX_RX_NX_BDHADDR_LO 0x00000014
+#define BCE_L2CTX_RX_NX_BDIDX 0x00000018
+
+#define BCE_L2CTX_RX_HOST_PG_BDIDX 0x00000044
+#define BCE_L2CTX_RX_PG_BUF_SIZE 0x00000048
+#define BCE_L2CTX_RX_RBDC_KEY 0x0000004c
+#define BCE_L2CTX_RX_RBDC_JUMBO_KEY 0x3ffe
#define BCE_L2CTX_RX_NX_PG_BDHADDR_HI 0x00000050
#define BCE_L2CTX_RX_NX_PG_BDHADDR_LO 0x00000054
-#define BCE_L2CTX_RX_NX_PG_BDIDX 0x00000058
+#define BCE_L2CTX_RX_NX_PG_BDIDX 0x00000058
/*
* l2_mq definitions (5706, 5708, 5709, and 5716)
*/
-#define BCE_L2MQ_RX_HOST_BDIDX 0x00000004
-#define BCE_L2MQ_RX_HOST_BSEQ 0x00000008
-#define BCE_L2MQ_RX_HOST_PG_BDIDX 0x00000044
+#define BCE_L2MQ_RX_HOST_BDIDX 0x00000004
+#define BCE_L2MQ_RX_HOST_BSEQ 0x00000008
+#define BCE_L2MQ_RX_HOST_PG_BDIDX 0x00000044
-#define BCE_L2MQ_TX_HOST_BIDX 0x00000088
-#define BCE_L2MQ_TX_HOST_BSEQ 0x00000090
+#define BCE_L2MQ_TX_HOST_BIDX 0x00000088
+#define BCE_L2MQ_TX_HOST_BSEQ 0x00000090
/*
* pci_config_l definition
* offset: 0000
*/
-#define BCE_PCICFG_MISC_CONFIG 0x00000068
+#define BCE_PCICFG_MISC_CONFIG 0x00000068
#define BCE_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2)
#define BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3)
#define BCE_PCICFG_MISC_CONFIG_CLOCK_CTL_ENA (1L<<5)
@@ -6112,62 +6135,6 @@ struct l2_fhdr {
#define NUM_MC_HASH_REGISTERS 8
-
-/* PHY_ID1: bits 31-16; PHY_ID2: bits 15-0. */
-#define PHY_BCM5706_PHY_ID 0x00206160
-
-#define PHY_ID(id) ((id) & 0xfffffff0)
-#define PHY_REV_ID(id) ((id) & 0xf)
-
-/* 5708 Serdes PHY registers */
-
-#define BCM5708S_UP1 0xb
-
-#define BCM5708S_UP1_2G5 0x1
-
-#define BCM5708S_BLK_ADDR 0x1f
-
-#define BCM5708S_BLK_ADDR_DIG 0x0000
-#define BCM5708S_BLK_ADDR_DIG3 0x0002
-#define BCM5708S_BLK_ADDR_TX_MISC 0x0005
-
-/* Digital Block */
-#define BCM5708S_1000X_CTL1 0x10
-
-#define BCM5708S_1000X_CTL1_FIBER_MODE 0x0001
-#define BCM5708S_1000X_CTL1_AUTODET_EN 0x0010
-
-#define BCM5708S_1000X_CTL2 0x11
-
-#define BCM5708S_1000X_CTL2_PLLEL_DET_EN 0x0001
-
-#define BCM5708S_1000X_STAT1 0x14
-
-#define BCM5708S_1000X_STAT1_SGMII 0x0001
-#define BCM5708S_1000X_STAT1_LINK 0x0002
-#define BCM5708S_1000X_STAT1_FD 0x0004
-#define BCM5708S_1000X_STAT1_SPEED_MASK 0x0018
-#define BCM5708S_1000X_STAT1_SPEED_10 0x0000
-#define BCM5708S_1000X_STAT1_SPEED_100 0x0008
-#define BCM5708S_1000X_STAT1_SPEED_1G 0x0010
-#define BCM5708S_1000X_STAT1_SPEED_2G5 0x0018
-#define BCM5708S_1000X_STAT1_TX_PAUSE 0x0020
-#define BCM5708S_1000X_STAT1_RX_PAUSE 0x0040
-
-/* Digital3 Block */
-#define BCM5708S_DIG_3_0 0x10
-
-#define BCM5708S_DIG_3_0_USE_IEEE 0x0001
-
-/* Tx/Misc Block */
-#define BCM5708S_TX_ACTL1 0x15
-
-#define BCM5708S_TX_ACTL1_DRIVER_VCM 0x30
-
-#define BCM5708S_TX_ACTL3 0x17
-
-#define RX_COPY_THRESH 92
-
#define DMA_READ_CHANS 5
#define DMA_WRITE_CHANS 3
@@ -6176,7 +6143,8 @@ struct l2_fhdr {
#define BCM_PAGE_BITS PAGE_SHIFT
#define BCM_PAGE_SIZE PAGE_SIZE
#define BCM_PAGE_MASK (BCM_PAGE_SIZE - 1)
-#define BCM_PAGES(x) ((((x) + BCM_PAGE_SIZE - 1) & BCM_PAGE_MASK) >> BCM_PAGE_BITS)
+#define BCM_PAGES(x) ((((x) + BCM_PAGE_SIZE - 1) & \
+ BCM_PAGE_MASK) >> BCM_PAGE_BITS)
/*
* Page count must remain a power of 2 for all
@@ -6191,8 +6159,7 @@ struct l2_fhdr {
/* Advance to the next tx_bd, skipping any next page pointers. */
#define NEXT_TX_BD(x) (((x) & USABLE_TX_BD_PER_PAGE) == \
- (USABLE_TX_BD_PER_PAGE - 1)) ? \
- (x) + 2 : (x) + 1
+ (USABLE_TX_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1
#define TX_CHAIN_IDX(x) ((x) & MAX_TX_BD)
@@ -6212,8 +6179,7 @@ struct l2_fhdr {
/* Advance to the next rx_bd, skipping any next page pointers. */
#define NEXT_RX_BD(x) (((x) & USABLE_RX_BD_PER_PAGE) == \
- (USABLE_RX_BD_PER_PAGE - 1)) ? \
- (x) + 2 : (x) + 1
+ (USABLE_RX_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1
#define RX_CHAIN_IDX(x) ((x) & MAX_RX_BD)
@@ -6234,8 +6200,7 @@ struct l2_fhdr {
/* Advance to the next pg_bd, skipping any next page pointers. */
#define NEXT_PG_BD(x) (((x) & USABLE_PG_BD_PER_PAGE) == \
- (USABLE_PG_BD_PER_PAGE - 1)) ? \
- (x) + 2 : (x) + 1
+ (USABLE_PG_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1
#define PG_CHAIN_IDX(x) ((x) & MAX_PG_BD)
@@ -6247,29 +6212,29 @@ struct l2_fhdr {
#define CTX_INIT_RETRY_COUNT 10
/* Context size. */
-#define CTX_SHIFT 7
-#define CTX_SIZE (1 << CTX_SHIFT)
-#define CTX_MASK (CTX_SIZE - 1)
-#define GET_CID_ADDR(_cid) ((_cid) << CTX_SHIFT)
-#define GET_CID(_cid_addr) ((_cid_addr) >> CTX_SHIFT)
-
-#define PHY_CTX_SHIFT 6
-#define PHY_CTX_SIZE (1 << PHY_CTX_SHIFT)
-#define PHY_CTX_MASK (PHY_CTX_SIZE - 1)
-#define GET_PCID_ADDR(_pcid) ((_pcid) << PHY_CTX_SHIFT)
-#define GET_PCID(_pcid_addr) ((_pcid_addr) >> PHY_CTX_SHIFT)
-
-#define MB_KERNEL_CTX_SHIFT 8
-#define MB_KERNEL_CTX_SIZE (1 << MB_KERNEL_CTX_SHIFT)
-#define MB_KERNEL_CTX_MASK (MB_KERNEL_CTX_SIZE - 1)
-#define MB_GET_CID_ADDR(_cid) (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT))
-
-#define MAX_CID_CNT 0x4000
-#define MAX_CID_ADDR (GET_CID_ADDR(MAX_CID_CNT))
-#define INVALID_CID_ADDR 0xffffffff
-
-#define TX_CID 16
-#define RX_CID 0
+#define CTX_SHIFT 7
+#define CTX_SIZE (1 << CTX_SHIFT)
+#define CTX_MASK (CTX_SIZE - 1)
+#define GET_CID_ADDR(_cid) ((_cid) << CTX_SHIFT)
+#define GET_CID(_cid_addr) ((_cid_addr) >> CTX_SHIFT)
+
+#define PHY_CTX_SHIFT 6
+#define PHY_CTX_SIZE (1 << PHY_CTX_SHIFT)
+#define PHY_CTX_MASK (PHY_CTX_SIZE - 1)
+#define GET_PCID_ADDR(_pcid) ((_pcid) << PHY_CTX_SHIFT)
+#define GET_PCID(_pcid_addr) ((_pcid_addr) >> PHY_CTX_SHIFT)
+
+#define MB_KERNEL_CTX_SHIFT 8
+#define MB_KERNEL_CTX_SIZE (1 << MB_KERNEL_CTX_SHIFT)
+#define MB_KERNEL_CTX_MASK (MB_KERNEL_CTX_SIZE - 1)
+#define MB_GET_CID_ADDR(_cid) (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT))
+
+#define MAX_CID_CNT 0x4000
+#define MAX_CID_ADDR (GET_CID_ADDR(MAX_CID_CNT))
+#define INVALID_CID_ADDR 0xffffffff
+
+#define TX_CID 16
+#define RX_CID 0
/****************************************************************************/
/* BCE Processor Firmwware Load Definitions */
@@ -6332,25 +6297,27 @@ struct fw_info {
u32 *rodata;
};
-#define RV2P_PROC1 0
-#define RV2P_PROC2 1
+#define RV2P_PROC1 0
+#define RV2P_PROC2 1
+
+#define BCE_MIREG(x) ((x & 0x1F) << 16)
+#define BCE_MIPHY(x) ((x & 0x1F) << 21)
+#define BCE_PHY_TIMEOUT 50
-#define BCE_MIREG(x) ((x & 0x1F) << 16)
-#define BCE_MIPHY(x) ((x & 0x1F) << 21)
-#define BCE_PHY_TIMEOUT 50
+#define BCE_NVRAM_SIZE 0x200
+#define BCE_NVRAM_MAGIC 0x669955aa
+#define BCE_CRC32_RESIDUAL 0xdebb20e3
-#define BCE_NVRAM_SIZE 0x200
-#define BCE_NVRAM_MAGIC 0x669955aa
-#define BCE_CRC32_RESIDUAL 0xdebb20e3
+#define BCE_TX_TIMEOUT 5
-#define BCE_TX_TIMEOUT 5
+#define BCE_MAX_SEGMENTS 32
+#define BCE_TSO_MAX_SIZE 65536
+#define BCE_TSO_MAX_SEG_SIZE 4096
-#define BCE_MAX_SEGMENTS 32
-#define BCE_TSO_MAX_SIZE 65536
-#define BCE_TSO_MAX_SEG_SIZE 4096
+#define BCE_DMA_ALIGN 8
+#define BCE_DMA_BOUNDARY 0
-#define BCE_DMA_ALIGN 8
-#define BCE_DMA_BOUNDARY 0
+#define BCE_MAX_CONTEXT 4
/* The BCM5708 has a problem with addresses greater that 40bits. */
/* Handle the sizing issue in an architecture agnostic fashion. */
@@ -6372,22 +6339,23 @@ struct fw_info {
#endif
#if __FreeBSD_version < 700000
-#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
- IFCAP_HWCSUM | IFCAP_JUMBO_MTU)
+#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | \
+ IFCAP_VLAN_HWTAGGING | IFCAP_HWCSUM | IFCAP_JUMBO_MTU)
#else
-#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
- IFCAP_HWCSUM | IFCAP_JUMBO_MTU | IFCAP_VLAN_HWCSUM)
+#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | \
+ IFCAP_VLAN_HWTAGGING | IFCAP_HWCSUM | \
+ IFCAP_JUMBO_MTU | IFCAP_VLAN_HWCSUM)
#endif
-#define BCE_MIN_MTU 60
-#define BCE_MIN_ETHER_MTU 64
+#define BCE_MIN_MTU 60
+#define BCE_MIN_ETHER_MTU 64
-#define BCE_MAX_STD_MTU 1500
-#define BCE_MAX_STD_ETHER_MTU 1518
-#define BCE_MAX_STD_ETHER_MTU_VLAN 1522
+#define BCE_MAX_STD_MTU 1500
+#define BCE_MAX_STD_ETHER_MTU 1518
+#define BCE_MAX_STD_ETHER_MTU_VLAN 1522
-#define BCE_MAX_JUMBO_MTU 9000
-#define BCE_MAX_JUMBO_ETHER_MTU 9018
+#define BCE_MAX_JUMBO_MTU 9000
+#define BCE_MAX_JUMBO_ETHER_MTU 9018
#define BCE_MAX_JUMBO_ETHER_MTU_VLAN 9022
// #define BCE_MAX_MTU ETHER_MAX_LEN_JUMBO + ETHER_VLAN_ENCAP_LEN /* 9022 */
@@ -6396,154 +6364,206 @@ struct fw_info {
/* BCE Device State Data Structure */
/****************************************************************************/
-#define BCE_STATUS_BLK_SZ sizeof(struct status_block)
-#define BCE_STATS_BLK_SZ sizeof(struct statistics_block)
+#define BCE_STATUS_BLK_SZ sizeof(struct status_block)
+#define BCE_STATS_BLK_SZ sizeof(struct statistics_block)
#define BCE_TX_CHAIN_PAGE_SZ BCM_PAGE_SIZE
#define BCE_RX_CHAIN_PAGE_SZ BCM_PAGE_SIZE
#define BCE_PG_CHAIN_PAGE_SZ BCM_PAGE_SIZE
struct bce_softc
{
- /* MUST start with ifnet pointer (see definition of miibus_statchg()) */
- struct ifnet *bce_ifp; /* Interface info */
- device_t bce_dev; /* Parent device handle */
- u_int8_t bce_unit; /* Interface number */
- struct resource *bce_res_mem; /* Device resource handle */
- struct ifmedia bce_ifmedia; /* TBI media info */
- bus_space_tag_t bce_btag; /* Device bus tag */
- bus_space_handle_t bce_bhandle; /* Device bus handle */
- vm_offset_t bce_vhandle; /* Device virtual memory handle */
- struct resource *bce_res_irq; /* IRQ Resource Handle */
- struct mtx bce_mtx; /* Mutex */
+ /* Interface info */
+ struct ifnet *bce_ifp;
+
+ /* Parent device handle */
+ device_t bce_dev;
+
+ /* Interface number */
+ u_int8_t bce_unit;
+
+ /* Device resource handle */
+ struct resource *bce_res_mem;
+
+ /* TBI media info */
+ struct ifmedia bce_ifmedia;
+
+ /* Device bus tag */
+ bus_space_tag_t bce_btag;
+
+ /* Device bus handle */
+ bus_space_handle_t bce_bhandle;
+
+ /* Device virtual memory handle */
+ vm_offset_t bce_vhandle;
+
+ /* IRQ Resource Handle */
+ struct resource *bce_res_irq;
+
+ struct mtx bce_mtx;
/* Interrupt handler. */
driver_intr_t *bce_intr;
- void *bce_intrhand;
- int bce_irq_rid;
- int bce_msi_count;
+ void *bce_intrhand;
+ int bce_irq_rid;
+ int bce_msi_count;
/* ASIC Chip ID. */
- u32 bce_chipid;
+ u32 bce_chipid;
/* General controller flags. */
- u32 bce_flags;
-#define BCE_PCIX_FLAG 0x00000001
-#define BCE_PCI_32BIT_FLAG 0x00000002
-#define BCE_ONE_TDMA_FLAG 0x00000004 /* Deprecated */
-#define BCE_NO_WOL_FLAG 0x00000008
-#define BCE_USING_DAC_FLAG 0x00000010
-#define BCE_USING_MSI_FLAG 0x00000020
-#define BCE_MFW_ENABLE_FLAG 0x00000040
+ u32 bce_flags;
+#define BCE_PCIX_FLAG 0x00000001
+#define BCE_PCI_32BIT_FLAG 0x00000002
+#define BCE_RESERVED_FLAG 0x00000004
+#define BCE_NO_WOL_FLAG 0x00000008
+#define BCE_USING_DAC_FLAG 0x00000010
+#define BCE_USING_MSI_FLAG 0x00000020
+#define BCE_MFW_ENABLE_FLAG 0x00000040
#define BCE_ONE_SHOT_MSI_FLAG 0x00000080
-#define BCE_USING_MSIX_FLAG 0x00000100
-#define BCE_PCIE_FLAG 0x00000200
+#define BCE_USING_MSIX_FLAG 0x00000100
+#define BCE_PCIE_FLAG 0x00000200
/* Controller capability flags. */
- u32 bce_cap_flags;
+ u32 bce_cap_flags;
#define BCE_MSI_CAPABLE_FLAG 0x00000001
#define BCE_MSIX_CAPABLE_FLAG 0x00000002
#define BCE_PCIE_CAPABLE_FLAG 0x00000004
#define BCE_PCIX_CAPABLE_FLAG 0x00000008
/* PHY specific flags. */
- u32 bce_phy_flags;
-#define BCE_PHY_SERDES_FLAG 0x00000001
-#define BCE_PHY_CRC_FIX_FLAG 0x00000002
-#define BCE_PHY_PARALLEL_DETECT_FLAG 0x00000004
-#define BCE_PHY_2_5G_CAPABLE_FLAG 0x00000008
-#define BCE_PHY_INT_MODE_MASK_FLAG 0x00000300
-#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG 0x00000100
-#define BCE_PHY_INT_MODE_LINK_READY_FLAG 0x00000200
+ u32 bce_phy_flags;
+#define BCE_PHY_SERDES_FLAG 0x00000001
+#define BCE_PHY_CRC_FIX_FLAG 0x00000002
+#define BCE_PHY_PARALLEL_DETECT_FLAG 0x00000004
+#define BCE_PHY_2_5G_CAPABLE_FLAG 0x00000008
+#define BCE_PHY_INT_MODE_MASK_FLAG 0x00000300
+#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG 0x00000100
+#define BCE_PHY_INT_MODE_LINK_READY_FLAG 0x00000200
+#define BCE_PHY_IEEE_CLAUSE_45_FLAG 0x00000400
/* Values that need to be shared with the PHY driver. */
- u32 bce_shared_hw_cfg;
- u32 bce_port_hw_cfg;
-
- bus_addr_t max_bus_addr;
- u16 bus_speed_mhz; /* PCI bus speed */
- u16 link_width; /* PCIe link width */
- u16 link_speed; /* PCIe link speed */
- struct flash_spec *bce_flash_info; /* Flash NVRAM settings */
- u32 bce_flash_size; /* Flash NVRAM size */
- u32 bce_shmem_base; /* Shared Memory base address */
- char * bce_name; /* Name string */
+ u32 bce_shared_hw_cfg;
+ u32 bce_port_hw_cfg;
+
+ bus_addr_t max_bus_addr;
+
+ /* PCI bus speed */
+ u16 bus_speed_mhz;
+
+ /* PCIe link width */
+ u16 link_width;
+
+ /* PCIe link speed */
+ u16 link_speed;
+
+ /* Flash NVRAM settings */
+ struct flash_spec *bce_flash_info;
+
+ /* Flash NVRAM size */
+ u32 bce_flash_size;
+
+ /* Shared Memory base address */
+ u32 bce_shmem_base;
+
+ /* Name string */
+ char * bce_name;
/* Tracks the version of bootcode firmware. */
- char bce_bc_ver[32];
- char bce_mfw_ver[32];
+ char bce_bc_ver[32];
+
+ /* Tracks the version of management firmware. */
+ char bce_mfw_ver[32];
+
+ /*
+ * Tracks the state of the firmware. 0 = Running while any
+ * other value indicates that the firmware is not responding.
+ */
+ u16 bce_fw_timed_out;
- /* Tracks the state of the firmware. 0 = Running while any */
- /* other value indicates that the firmware is not responding. */
- u16 bce_fw_timed_out;
+ /*
+ * An incrementing sequence used to coordinate messages passed
+ * from the driver to the firmware.
+ */
+ u16 bce_fw_wr_seq;
- /* An incrementing sequence used to coordinate messages passed */
- /* from the driver to the firmware. */
- u16 bce_fw_wr_seq;
+ /*
+ * An incrementing sequence used to let the firmware know that
+ * the driver is still operating. Without the pulse, management
+ * firmware such as IPMI or UMP will operate in OS absent state.
+ */
+ u16 bce_fw_drv_pulse_wr_seq;
- /* An incrementing sequence used to let the firmware know that */
- /* the driver is still operating. Without the pulse, management */
- /* firmware such as IPMI or UMP will operate in OS absent state. */
- u16 bce_fw_drv_pulse_wr_seq;
+ /* Tracks whether firmware has lost the driver's pulse. */
+ u16 bce_drv_cardiac_arrest;
/* Ethernet MAC address. */
- u_char eaddr[6];
-
- /* These setting are used by the host coalescing (HC) block to */
- /* to control how often the status block, statistics block and */
- /* interrupts are generated. */
- u16 bce_tx_quick_cons_trip_int;
- u16 bce_tx_quick_cons_trip;
- u16 bce_rx_quick_cons_trip_int;
- u16 bce_rx_quick_cons_trip;
- u16 bce_comp_prod_trip_int;
- u16 bce_comp_prod_trip;
- u16 bce_tx_ticks_int;
- u16 bce_tx_ticks;
- u16 bce_rx_ticks_int;
- u16 bce_rx_ticks;
- u16 bce_com_ticks_int;
- u16 bce_com_ticks;
- u16 bce_cmd_ticks_int;
- u16 bce_cmd_ticks;
- u32 bce_stats_ticks;
+ u_char eaddr[6];
+
+ /*
+ * These setting are used by the host coalescing (HC) block to
+ * to control how often the status block, statistics block and
+ * interrupts are generated.
+ */
+ u16 bce_tx_quick_cons_trip_int;
+ u16 bce_tx_quick_cons_trip;
+ u16 bce_rx_quick_cons_trip_int;
+ u16 bce_rx_quick_cons_trip;
+ u16 bce_tx_ticks_int;
+ u16 bce_tx_ticks;
+ u16 bce_rx_ticks_int;
+ u16 bce_rx_ticks;
+ u32 bce_stats_ticks;
+
+ /* ToDo: Can these be removed? */
+ u16 bce_comp_prod_trip_int;
+ u16 bce_comp_prod_trip;
+ u16 bce_com_ticks_int;
+ u16 bce_com_ticks;
+ u16 bce_cmd_ticks_int;
+ u16 bce_cmd_ticks;
/* The address of the integrated PHY on the MII bus. */
- int bce_phy_addr;
+ int bce_phy_addr;
/* The device handle for the MII bus child device. */
- device_t bce_miibus;
+ device_t bce_miibus;
/* Driver maintained TX chain pointers and byte counter. */
- u16 rx_prod;
- u16 rx_cons;
- u32 rx_prod_bseq; /* Counts the bytes used. */
- u16 tx_prod;
- u16 tx_cons;
- u32 tx_prod_bseq; /* Counts the bytes used. */
+ u16 rx_prod;
+ u16 rx_cons;
+
+ /* Counts the bytes used in the RX chain. */
+ u32 rx_prod_bseq;
+ u16 tx_prod;
+ u16 tx_cons;
+
+ /* Counts the bytes used in the TX chain. */
+ u32 tx_prod_bseq;
#ifdef BCE_JUMBO_HDRSPLIT
- u16 pg_prod;
- u16 pg_cons;
+ u16 pg_prod;
+ u16 pg_cons;
#endif
- int bce_link;
- struct callout bce_tick_callout;
- struct callout bce_pulse_callout;
+ int bce_link_up;
+ struct callout bce_tick_callout;
+ struct callout bce_pulse_callout;
- int watchdog_timer; /* ticks until chip reset */
+ /* Ticks until chip reset */
+ int watchdog_timer;
/* Frame size and mbuf allocation size for RX frames. */
- u32 max_frame_size;
- int rx_bd_mbuf_alloc_size;
- int rx_bd_mbuf_data_len;
- int rx_bd_mbuf_align_pad;
+ u32 max_frame_size;
+ int rx_bd_mbuf_alloc_size;
+ int rx_bd_mbuf_data_len;
+ int rx_bd_mbuf_align_pad;
#ifdef BCE_JUMBO_HDRSPLIT
- int pg_bd_mbuf_alloc_size;
+ int pg_bd_mbuf_alloc_size;
#endif
/* Receive mode settings (i.e promiscuous, multicast, etc.). */
- u32 rx_mode;
+ u32 rx_mode;
/* Bus tag for the bce controller. */
bus_dma_tag_t parent_tag;
@@ -6552,46 +6572,47 @@ struct bce_softc
bus_dma_tag_t tx_bd_chain_tag;
bus_dmamap_t tx_bd_chain_map[TX_PAGES];
struct tx_bd *tx_bd_chain[TX_PAGES];
- bus_addr_t tx_bd_chain_paddr[TX_PAGES];
+ bus_addr_t tx_bd_chain_paddr[TX_PAGES];
/* H/W maintained RX buffer descriptor chain structure. */
bus_dma_tag_t rx_bd_chain_tag;
bus_dmamap_t rx_bd_chain_map[RX_PAGES];
struct rx_bd *rx_bd_chain[RX_PAGES];
- bus_addr_t rx_bd_chain_paddr[RX_PAGES];
+ bus_addr_t rx_bd_chain_paddr[RX_PAGES];
#ifdef BCE_JUMBO_HDRSPLIT
/* H/W maintained page buffer descriptor chain structure. */
bus_dma_tag_t pg_bd_chain_tag;
bus_dmamap_t pg_bd_chain_map[PG_PAGES];
struct rx_bd *pg_bd_chain[PG_PAGES];
- bus_addr_t pg_bd_chain_paddr[PG_PAGES];
+ bus_addr_t pg_bd_chain_paddr[PG_PAGES];
#endif
/* H/W maintained status block. */
bus_dma_tag_t status_tag;
bus_dmamap_t status_map;
- struct status_block *status_block; /* Virtual address */
- bus_addr_t status_block_paddr; /* Physical address */
+ struct status_block *status_block;
+ bus_addr_t status_block_paddr;
/* Driver maintained status block values. */
- u16 last_status_idx;
- u16 hw_rx_cons;
- u16 hw_tx_cons;
+ u16 last_status_idx;
+ u16 hw_rx_cons;
+ u16 hw_tx_cons;
/* H/W maintained statistics block. */
bus_dma_tag_t stats_tag;
bus_dmamap_t stats_map;
- struct statistics_block *stats_block; /* Virtual address */
- bus_addr_t stats_block_paddr; /* Physical address */
+ struct statistics_block *stats_block;
+ bus_addr_t stats_block_paddr;
/* H/W maintained context block. */
- int ctx_pages;
+ int ctx_pages;
bus_dma_tag_t ctx_tag;
- /* DRC - Fix hard coded value. */
- bus_dmamap_t ctx_map[4];
- void *ctx_block[4]; /* Virtual address */
- bus_addr_t ctx_paddr[4]; /* Physical address */
+
+ /* BCM5709/16 use host memory for context. */
+ bus_dmamap_t ctx_map[BCE_MAX_CONTEXT];
+ void *ctx_block[BCE_MAX_CONTEXT];
+ bus_addr_t ctx_paddr[BCE_MAX_CONTEXT];
/* Bus tag for RX/TX mbufs. */
bus_dma_tag_t rx_mbuf_tag;
@@ -6603,16 +6624,16 @@ struct bce_softc
/* S/W maintained mbuf TX chain structure. */
bus_dmamap_t tx_mbuf_map[TOTAL_TX_BD];
- struct mbuf *tx_mbuf_ptr[TOTAL_TX_BD];
+ struct mbuf *tx_mbuf_ptr[TOTAL_TX_BD];
/* S/W maintained mbuf RX chain structure. */
bus_dmamap_t rx_mbuf_map[TOTAL_RX_BD];
- struct mbuf *rx_mbuf_ptr[TOTAL_RX_BD];
+ struct mbuf *rx_mbuf_ptr[TOTAL_RX_BD];
#ifdef BCE_JUMBO_HDRSPLIT
/* S/W maintained mbuf page chain structure. */
bus_dmamap_t pg_mbuf_map[TOTAL_PG_BD];
- struct mbuf *pg_mbuf_ptr[TOTAL_PG_BD];
+ struct mbuf *pg_mbuf_ptr[TOTAL_PG_BD];
#endif
/* Track the number of buffer descriptors in use. */
@@ -6687,26 +6708,28 @@ struct bce_softc
u32 com_no_buffers;
/* Recoverable failure counters. */
- u32 mbuf_alloc_failed_count;
+ u32 mbuf_alloc_failed_count;
u32 fragmented_mbuf_count;
- u32 unexpected_attention_count;
+ u32 unexpected_attention_count;
u32 l2fhdr_error_count;
u32 dma_map_addr_tx_failed_count;
u32 dma_map_addr_rx_failed_count;
+ /* Host coalescing block command register */
+ u32 hc_command;
+
+ /* Bootcode state */
+ u32 bc_state;
+
#ifdef BCE_DEBUG
/* Simulated recoverable failure counters. */
- u32 mbuf_alloc_failed_sim_count;
+ u32 mbuf_alloc_failed_sim_count;
u32 unexpected_attention_sim_count;
u32 l2fhdr_error_sim_count;
- u32 dma_map_addr_failed_sim_count;
-#endif
+ u32 dma_map_addr_failed_sim_count;
- u32 hc_command;
-
-#ifdef BCE_DEBUG
/* Track the number of enqueued mbufs. */
- int debug_tx_mbuf_alloc;
+ int debug_tx_mbuf_alloc;
int debug_rx_mbuf_alloc;
#ifdef BCE_JUMBO_HDRSPLIT
@@ -6718,23 +6741,35 @@ struct bce_softc
u32 interrupts_handled;
u32 rx_interrupts;
u32 tx_interrupts;
+ u32 phy_interrupts;
/* Track interrupt time (25MHz clock). */
u64 rx_intr_time;
u64 tx_intr_time;
- u32 rx_low_watermark; /* Lowest number of rx_bd's free. */
- u32 rx_empty_count; /* Number of times the RX chain was empty. */
+ /* Lowest number of rx_bd's free. */
+ u32 rx_low_watermark;
+
+ /* Number of times the RX chain was empty. */
+ u32 rx_empty_count;
#ifdef BCE_JUMBO_HDRSPLIT
- u32 pg_low_watermark; /* Lowest number of pages free. */
- u32 pg_empty_count; /* Number of times the page chain was empty. */
+
+ /* Lowest number of pages free. */
+ u32 pg_low_watermark;
+
+ /* Number of times the page chain was empty. */
+ u32 pg_empty_count;
#endif
- u32 tx_hi_watermark; /* Greatest number of tx_bd's used. */
- u32 tx_full_count; /* Number of times the TX chain was full. */
+ /* Greatest number of tx_bd's used. */
+ u32 tx_hi_watermark;
+
+ /* Number of times the TX chain was full. */
+ u32 tx_full_count;
- u32 requested_tso_frames; /* Number of TSO frames enqueued. */
+ /* Number of TSO frames enqueued. */
+ u32 requested_tso_frames;
#endif
};
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 9c47835..5a51d79 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -421,7 +421,6 @@ static uint32_t bge_readreg_ind(struct bge_softc *, int);
#endif
static void bge_writemem_direct(struct bge_softc *, int, int);
static void bge_writereg_ind(struct bge_softc *, int, int);
-static void bge_set_max_readrq(struct bge_softc *);
static int bge_miibus_readreg(device_t, int, int);
static int bge_miibus_writereg(device_t, int, int, int);
@@ -520,7 +519,7 @@ bge_has_eaddr(struct bge_softc *sc)
*/
if (OF_getprop(ofw_bus_get_node(dev), SPARC64_OFW_SUBVENDOR,
&subvendor, sizeof(subvendor)) == sizeof(subvendor) &&
- subvendor == SUN_VENDORID)
+ (subvendor == FJTSU_VENDORID || subvendor == SUN_VENDORID))
return (0);
memset(buf, 0, sizeof(buf));
if (OF_package_to_path(ofw_bus_get_node(dev), buf, sizeof(buf)) > 0) {
@@ -561,32 +560,6 @@ bge_writemem_ind(struct bge_softc *sc, int off, int val)
pci_write_config(dev, BGE_PCI_MEMWIN_BASEADDR, 0, 4);
}
-/*
- * PCI Express only
- */
-static void
-bge_set_max_readrq(struct bge_softc *sc)
-{
- device_t dev;
- uint16_t val;
-
- dev = sc->bge_dev;
-
- val = pci_read_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL, 2);
- if ((val & PCIM_EXP_CTL_MAX_READ_REQUEST) !=
- BGE_PCIE_DEVCTL_MAX_READRQ_4096) {
- if (bootverbose)
- device_printf(dev, "adjust device control 0x%04x ",
- val);
- val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST;
- val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
- pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
- val, 2);
- if (bootverbose)
- printf("-> 0x%04x\n", val);
- }
-}
-
#ifdef notdef
static uint32_t
bge_readreg_ind(struct bge_softc *sc, int off)
@@ -1342,6 +1315,7 @@ static int
bge_chipinit(struct bge_softc *sc)
{
uint32_t dma_rw_ctl;
+ uint16_t val;
int i;
/* Set endianness before we access any non-PCI registers. */
@@ -1362,6 +1336,17 @@ bge_chipinit(struct bge_softc *sc)
i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
BGE_MEMWIN_WRITE(sc, i, 0);
+ if (sc->bge_chiprev == BGE_CHIPREV_5704_BX) {
+ /*
+ * Fix data corruption caused by non-qword write with WB.
+ * Fix master abort in PCI mode.
+ * Fix PCI latency timer.
+ */
+ val = pci_read_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, 2);
+ val |= (1 << 10) | (1 << 12) | (1 << 13);
+ pci_write_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, val, 2);
+ }
+
/*
* Set up the PCI DMA control register.
*/
@@ -1378,6 +1363,15 @@ bge_chipinit(struct bge_softc *sc)
dma_rw_ctl |= (sc->bge_asicrev == BGE_ASICREV_BCM5780) ?
BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL :
BGE_PCIDMARWCTL_ONEDMA_ATONCE_LOCAL;
+ } else if (sc->bge_asicrev == BGE_ASICREV_BCM5703) {
+ /*
+ * In the BCM5703, the DMA read watermark should
+ * be set to less than or equal to the maximum
+ * memory read byte count of the PCI-X command
+ * register.
+ */
+ dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(4) |
+ BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
} else if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
/* 1536 bytes for read, 384 bytes for write. */
dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(7) |
@@ -2674,7 +2668,8 @@ bge_attach(device_t dev)
*/
sc->bge_flags |= BGE_FLAG_PCIE;
sc->bge_expcap = reg;
- bge_set_max_readrq(sc);
+ if (pci_get_max_read_req(dev) != 4096)
+ pci_set_max_read_req(dev, 4096);
} else {
/*
* Check if the device is in PCI-X Mode.
@@ -3158,7 +3153,26 @@ bge_reset(struct bge_softc *sc)
pci_write_config(dev, BGE_PCI_CACHESZ, cachesize, 4);
pci_write_config(dev, BGE_PCI_CMD, command, 4);
write_op(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
-
+ /*
+ * Disable PCI-X relaxed ordering to ensure status block update
+ * comes first then packet buffer DMA. Otherwise driver may
+ * read stale status block.
+ */
+ if (sc->bge_flags & BGE_FLAG_PCIX) {
+ devctl = pci_read_config(dev,
+ sc->bge_pcixcap + PCIXR_COMMAND, 2);
+ devctl &= ~PCIXM_COMMAND_ERO;
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5703) {
+ devctl &= ~PCIXM_COMMAND_MAX_READ;
+ devctl |= PCIXM_COMMAND_MAX_READ_2048;
+ } else if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
+ devctl &= ~(PCIXM_COMMAND_MAX_SPLITS |
+ PCIXM_COMMAND_MAX_READ);
+ devctl |= PCIXM_COMMAND_MAX_READ_2048;
+ }
+ pci_write_config(dev, sc->bge_pcixcap + PCIXR_COMMAND,
+ devctl, 2);
+ }
/* Re-enable MSI, if neccesary, and enable the memory arbiter. */
if (BGE_IS_5714_FAMILY(sc)) {
/* This chip disables MSI on reset. */
diff --git a/sys/dev/bktr/ioctl_bt848.h b/sys/dev/bktr/ioctl_bt848.h
index 3731e7d..6e50b61 100644
--- a/sys/dev/bktr/ioctl_bt848.h
+++ b/sys/dev/bktr/ioctl_bt848.h
@@ -89,9 +89,9 @@
* EEProm stuff
*/
struct eeProm {
- short offset;
- short count;
- u_char bytes[ 256 ];
+ short offset;
+ short count;
+ unsigned char bytes[ 256 ];
};
@@ -147,7 +147,7 @@ struct eeProm {
* b23-b16: i2c addr (write)
* b31-b24: 1 = write, 0 = read
*/
-#define BT848_I2CWR _IOWR('x', 57, u_long) /* i2c read-write */
+#define BT848_I2CWR _IOWR('x', 57, unsigned long) /* i2c read-write */
struct bktr_msp_control {
unsigned char function;
@@ -192,10 +192,10 @@ typedef enum { METEOR_PIXTYPE_RGB, METEOR_PIXTYPE_YUV,
struct meteor_pixfmt {
- u_int index; /* Index in supported pixfmt list */
+ unsigned int index; /* Index in supported pixfmt list */
METEOR_PIXTYPE type; /* What's the board gonna feed us */
- u_int Bpp; /* Bytes per pixel */
- u_long masks[3]; /* R,G,B or Y,U,V masks, respectively */
+ unsigned int Bpp; /* Bytes per pixel */
+ unsigned long masks[3]; /* R,G,B or Y,U,V masks, respectively */
unsigned swap_bytes :1; /* Bytes swapped within shorts */
unsigned swap_shorts:1; /* Shorts swapped within longs */
};
diff --git a/sys/dev/bktr/ioctl_meteor.h b/sys/dev/bktr/ioctl_meteor.h
index 681990a..8e769ec 100644
--- a/sys/dev/bktr/ioctl_meteor.h
+++ b/sys/dev/bktr/ioctl_meteor.h
@@ -50,27 +50,27 @@ struct meteor_capframe {
/* structure for METEOR[GS]ETGEO - get/set geometry */
struct meteor_geomet {
- u_short rows;
- u_short columns;
- u_short frames;
- u_long oformat;
+ unsigned short rows;
+ unsigned short columns;
+ unsigned short frames;
+ unsigned long oformat;
} ;
/* structure for METEORGCOUNT-get count of frames, fifo errors and dma errors */
struct meteor_counts {
- u_long fifo_errors; /* count of fifo errors since open */
- u_long dma_errors; /* count of dma errors since open */
- u_long frames_captured; /* count of frames captured since open */
- u_long even_fields_captured; /* count of even fields captured */
- u_long odd_fields_captured; /* count of odd fields captured */
+ unsigned long fifo_errors; /* count of fifo errors since open */
+ unsigned long dma_errors; /* count of dma errors since open */
+ unsigned long frames_captured; /* count of frames captured since open */
+ unsigned long even_fields_captured; /* count of even fields captured */
+ unsigned long odd_fields_captured; /* count of odd fields captured */
} ;
/* structure for getting and setting direct transfers to vram */
struct meteor_video {
- u_long addr; /* Address of location to dma to */
- u_long width; /* Width of memory area */
- u_long banksize; /* Size of Vram bank */
- u_long ramsize; /* Size of Vram */
+ unsigned long addr; /* Address of location to dma to */
+ unsigned long width; /* Width of memory area */
+ unsigned long banksize; /* Size of Vram bank */
+ unsigned long ramsize; /* Size of Vram */
};
#define METEORCAPTUR _IOW('x', 1, int) /* capture a frame */
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index 2604d83..96c5cc6 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -64,8 +64,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_phy.h>
+#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@@ -112,9 +112,6 @@ static void bwi_set_channel(struct ieee80211com *);
static void bwi_scan_end(struct ieee80211com *);
static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void bwi_updateslot(struct ifnet *);
-static struct ieee80211_node *bwi_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
-static void bwi_newassoc(struct ieee80211_node *, int);
static int bwi_media_change(struct ifnet *);
static void bwi_calibrate(void *);
@@ -525,7 +522,6 @@ bwi_attach(struct bwi_softc *sc)
ic->ic_vap_delete = bwi_vap_delete;
ic->ic_raw_xmit = bwi_raw_xmit;
ic->ic_updateslot = bwi_updateslot;
- ic->ic_node_alloc = bwi_node_alloc;
ic->ic_scan_start = bwi_scan_start;
ic->ic_scan_end = bwi_scan_end;
ic->ic_set_channel = bwi_set_channel;
@@ -621,10 +617,7 @@ bwi_vap_create(struct ieee80211com *ic,
#if 0
vap->iv_update_beacon = bwi_beacon_update;
#endif
- ieee80211_amrr_init(&bvp->bv_amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /*ms*/);
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status);
@@ -637,7 +630,7 @@ bwi_vap_delete(struct ieee80211vap *vap)
{
struct bwi_vap *bvp = BWI_VAP(vap);
- ieee80211_amrr_cleanup(&bvp->bv_amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(bvp, M_80211_VAP);
}
@@ -1831,7 +1824,7 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
#endif
if (vap->iv_opmode == IEEE80211_M_STA) {
/* fake a join to init the tx rate */
- bwi_newassoc(ni, 1);
+ ic->ic_newassoc(ni, 1);
}
callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
@@ -1842,25 +1835,6 @@ back:
return error;
}
-/* ARGUSED */
-static struct ieee80211_node *
-bwi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct bwi_node *bn;
-
- bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return bn != NULL ? &bn->ni : NULL;
-}
-
-static void
-bwi_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&BWI_VAP(vap)->bv_amrr,
- &BWI_NODE(ni)->amn, ni);
-}
-
static int
bwi_media_change(struct ifnet *ifp)
{
@@ -3012,7 +2986,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = rate_fb = tp->ucastrate;
} else {
- rix = ieee80211_amrr_choose(ni, &BWI_NODE(ni)->amn);
+ rix = ieee80211_ratectl_rate(ni, NULL, pkt_len);
rate = ni->ni_txrate;
if (rix > 0) {
@@ -3369,6 +3343,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
struct bwi_txbuf *tb;
int ring_idx, buf_idx;
struct ieee80211_node *ni;
+ struct ieee80211vap *vap;
if (tx_id == 0) {
if_printf(ifp, "%s: zero tx id\n", __func__);
@@ -3394,9 +3369,9 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
ni = tb->tb_ni;
if (tb->tb_ni != NULL) {
- struct bwi_node *bn = (struct bwi_node *) tb->tb_ni;
const struct bwi_txbuf_hdr *hdr =
mtod(tb->tb_mbuf, const struct bwi_txbuf_hdr *);
+ vap = ni->ni_vap;
/* NB: update rate control only for unicast frames */
if (hdr->txh_mac_ctrl & htole32(BWI_TXH_MAC_C_ACK)) {
@@ -3407,8 +3382,9 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
* well so to avoid over-aggressive downshifting we
* treat any number of retries as "1".
*/
- ieee80211_amrr_tx_complete(&bn->amn, acked,
- data_txcnt > 1);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ (data_txcnt > 1) ? IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE, &acked, NULL);
}
/*
diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h
index 22a1b1e..d5f09da 100644
--- a/sys/dev/bwi/if_bwivar.h
+++ b/sys/dev/bwi/if_bwivar.h
@@ -533,15 +533,8 @@ struct bwi_rx_radiotap_hdr {
/* TODO: sq */
};
-struct bwi_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define BWI_NODE(ni) ((struct bwi_node *)(ni))
-
struct bwi_vap {
struct ieee80211vap bv_vap;
- struct ieee80211_amrr bv_amrr;
int (*bv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 7d1e663..5ca5098 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -67,8 +67,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_phy.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/bwn/if_bwnreg.h>
#include <dev/bwn/if_bwnvar.h>
@@ -134,7 +134,7 @@ SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
static int bwn_attach_pre(struct bwn_softc *);
static int bwn_attach_post(struct bwn_softc *);
-static void bwn_sprom_bugfixes(struct siba_softc *);
+static void bwn_sprom_bugfixes(device_t);
static void bwn_init(void *);
static int bwn_init_locked(struct bwn_softc *);
static int bwn_ioctl(struct ifnet *, u_long, caddr_t);
@@ -180,18 +180,14 @@ static void bwn_addchannels(struct ieee80211_channel [], int, int *,
const struct bwn_channelinfo *, int);
static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void bwn_newassoc(struct ieee80211_node *, int);
static void bwn_updateslot(struct ifnet *);
static void bwn_update_promisc(struct ifnet *);
static void bwn_wme_init(struct bwn_mac *);
static int bwn_wme_update(struct ieee80211com *);
-static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
static void bwn_wme_clear(struct bwn_softc *);
static void bwn_wme_load(struct bwn_mac *);
static void bwn_wme_loadparams(struct bwn_mac *,
const struct wmeParams *, uint16_t);
-static void bwn_node_cleanup(struct ieee80211_node *);
static void bwn_scan_start(struct ieee80211com *);
static void bwn_scan_end(struct ieee80211com *);
static void bwn_set_channel(struct ieee80211com *);
@@ -205,7 +201,6 @@ static void bwn_stop_locked(struct bwn_softc *, int);
static int bwn_core_init(struct bwn_mac *);
static void bwn_core_start(struct bwn_mac *);
static void bwn_core_exit(struct bwn_mac *);
-static void bwn_fix_imcfglobug(struct bwn_mac *);
static void bwn_bt_disable(struct bwn_mac *);
static int bwn_chip_init(struct bwn_mac *);
static uint64_t bwn_hf_read(struct bwn_mac *);
@@ -225,7 +220,6 @@ static int bwn_fw_loadinitvals(struct bwn_mac *);
static int bwn_phy_init(struct bwn_mac *);
static void bwn_set_txantenna(struct bwn_mac *, int);
static void bwn_set_opmode(struct bwn_mac *);
-static void bwn_gpio_cleanup(struct bwn_mac *);
static void bwn_rate_write(struct bwn_mac *, uint16_t, int);
static uint8_t bwn_plcp_getcck(const uint8_t);
static uint8_t bwn_plcp_getofdm(const uint8_t);
@@ -910,13 +904,12 @@ static const struct siba_devid bwn_devs[] = {
static int
bwn_probe(device_t dev)
{
- struct siba_dev_softc *sd = device_get_ivars(dev);
int i;
for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
- if (sd->sd_id.sd_vendor == bwn_devs[i].sd_vendor &&
- sd->sd_id.sd_device == bwn_devs[i].sd_device &&
- sd->sd_id.sd_rev == bwn_devs[i].sd_rev)
+ if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
+ siba_get_device(dev) == bwn_devs[i].sd_device &&
+ siba_get_revid(dev) == bwn_devs[i].sd_rev)
return (BUS_PROBE_DEFAULT);
}
@@ -928,12 +921,9 @@ bwn_attach(device_t dev)
{
struct bwn_mac *mac;
struct bwn_softc *sc = device_get_softc(dev);
- struct siba_dev_softc *sd = device_get_ivars(dev);
- struct siba_softc *siba = sd->sd_bus;
int error, i, msic, reg;
sc->sc_dev = dev;
- sc->sc_sd = sd;
#ifdef BWN_DEBUG
sc->sc_debug = bwn_debug;
#endif
@@ -942,14 +932,14 @@ bwn_attach(device_t dev)
error = bwn_attach_pre(sc);
if (error != 0)
return (error);
- bwn_sprom_bugfixes(sd->sd_bus);
+ bwn_sprom_bugfixes(dev);
sc->sc_flags |= BWN_FLAG_ATTACHED;
}
if (!TAILQ_EMPTY(&sc->sc_maclist)) {
- if (siba->siba_pci_did != 0x4313 &&
- siba->siba_pci_did != 0x431a &&
- siba->siba_pci_did != 0x4321) {
+ if (siba_get_pci_device(dev) != 0x4313 &&
+ siba_get_pci_device(dev) != 0x431a &&
+ siba_get_pci_device(dev) != 0x4321) {
device_printf(sc->sc_dev,
"skip 802.11 cores\n");
return (ENODEV);
@@ -961,7 +951,6 @@ bwn_attach(device_t dev)
if (mac == NULL)
return (ENOMEM);
mac->mac_sc = sc;
- mac->mac_sd = sd;
mac->mac_status = BWN_MAC_STATUS_UNINIT;
if (bwn_bfp != 0)
mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
@@ -977,7 +966,7 @@ bwn_attach(device_t dev)
device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
"PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
- sd->sd_bus->siba_chipid, sd->sd_id.sd_rev,
+ siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
mac->mac_phy.rf_rev);
@@ -1065,8 +1054,6 @@ bwn_attach_post(struct bwn_softc *sc)
{
struct ieee80211com *ic;
struct ifnet *ifp = sc->sc_ifp;
- struct siba_dev_softc *sd = sc->sc_sd;
- struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
@@ -1085,24 +1072,22 @@ bwn_attach_post(struct bwn_softc *sc)
| IEEE80211_C_TXPMGT /* capable of txpow mgt */
;
+ ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
+
/* call MI attach routine. */
ieee80211_ifattach(ic,
- bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a :
- sprom->mac_80211bg);
+ bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
+ siba_sprom_get_mac_80211a(sc->sc_dev) :
+ siba_sprom_get_mac_80211bg(sc->sc_dev));
ic->ic_headroom = sizeof(struct bwn_txhdr);
/* override default methods */
ic->ic_raw_xmit = bwn_raw_xmit;
- ic->ic_newassoc = bwn_newassoc;
ic->ic_updateslot = bwn_updateslot;
ic->ic_update_promisc = bwn_update_promisc;
ic->ic_wme.wme_update = bwn_wme_update;
- ic->ic_node_alloc = bwn_node_alloc;
- sc->sc_node_cleanup = ic->ic_node_cleanup;
- ic->ic_node_cleanup = bwn_node_cleanup;
-
ic->ic_scan_start = bwn_scan_start;
ic->ic_scan_end = bwn_scan_end;
ic->ic_set_channel = bwn_set_channel;
@@ -1219,21 +1204,24 @@ fail: BWN_LOCK_DESTROY(sc);
}
static void
-bwn_sprom_bugfixes(struct siba_softc *siba)
+bwn_sprom_bugfixes(device_t dev)
{
#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
- ((siba->siba_pci_vid == PCI_VENDOR_##_vendor) && \
- (siba->siba_pci_did == _device) && \
- (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) && \
- (siba->siba_pci_subdid == _subdevice))
-
- if (siba->siba_board_vendor == PCI_VENDOR_APPLE &&
- siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40)
- siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL;
- if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL &&
- siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74)
- siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST;
- if (siba->siba_type == SIBA_TYPE_PCI) {
+ ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
+ (siba_get_pci_device(dev) == _device) && \
+ (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
+ (siba_get_pci_subdevice(dev) == _subdevice))
+
+ if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
+ siba_get_pci_subdevice(dev) == 0x4e &&
+ siba_get_pci_revid(dev) > 0x40)
+ siba_sprom_set_bf_lo(dev,
+ siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
+ if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
+ siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
+ siba_sprom_set_bf_lo(dev,
+ siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
+ if (siba_get_type(dev) == SIBA_TYPE_PCI) {
if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
@@ -1241,7 +1229,8 @@ bwn_sprom_bugfixes(struct siba_softc *siba)
BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
- siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST;
+ siba_sprom_set_bf_lo(dev,
+ siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
}
#undef BWN_ISDEV
}
@@ -1434,7 +1423,7 @@ bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
tq->tq_free--;
- if (mac->mac_sd->sd_id.sd_rev >= 8) {
+ if (siba_get_revid(sc->sc_dev) >= 8) {
/*
* XXX please removes m_defrag(9)
*/
@@ -1606,17 +1595,15 @@ static int
bwn_attach_core(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
int error, have_bg = 0, have_a = 0;
uint32_t high;
- KASSERT(sd->sd_id.sd_rev >= 5,
- ("unsupported revision %d", sd->sd_id.sd_rev));
+ KASSERT(siba_get_revid(sc->sc_dev) >= 5,
+ ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
- siba_powerup(siba, 0);
+ siba_powerup(sc->sc_dev, 0);
- high = siba_read_4(sd, SIBA_TGSHIGH);
+ high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
bwn_reset_core(mac,
(high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
error = bwn_phy_getinfo(mac, high);
@@ -1625,8 +1612,9 @@ bwn_attach_core(struct bwn_mac *mac)
have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
- if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 &&
- siba->siba_pci_did != 0x4324) {
+ if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
+ siba_get_pci_device(sc->sc_dev) != 0x4319 &&
+ siba_get_pci_device(sc->sc_dev) != 0x4324) {
have_a = have_bg = 0;
if (mac->mac_phy.type == BWN_PHYTYPE_A)
have_a = 1;
@@ -1719,30 +1707,30 @@ bwn_attach_core(struct bwn_mac *mac)
mac->mac_phy.switch_analog(mac, 0);
- siba_dev_down(sd, 0);
+ siba_dev_down(sc->sc_dev, 0);
fail:
- siba_powerdown(siba);
+ siba_powerdown(sc->sc_dev);
return (error);
}
static void
bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
{
- struct siba_dev_softc *sd = mac->mac_sd;
+ struct bwn_softc *sc = mac->mac_sc;
uint32_t low, ctl;
flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
- siba_dev_up(sd, flags);
+ siba_dev_up(sc->sc_dev, flags);
DELAY(2000);
- low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
+ low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
~BWN_TGSLOW_PHYRESET;
- siba_write_4(sd, SIBA_TGSLOW, low);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
+ siba_read_4(sc->sc_dev, SIBA_TGSLOW);
DELAY(1000);
- siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
+ siba_read_4(sc->sc_dev, SIBA_TGSLOW);
DELAY(1000);
if (mac->mac_phy.switch_analog != NULL)
@@ -1759,8 +1747,6 @@ bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_softc *sc = mac->mac_sc;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
uint32_t tmp;
/* PHY */
@@ -1779,10 +1765,10 @@ bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
goto unsupphy;
/* RADIO */
- if (siba->siba_chipid == 0x4317) {
- if (siba->siba_chiprev == 0)
+ if (siba_get_chipid(sc->sc_dev) == 0x4317) {
+ if (siba_get_chiprev(sc->sc_dev) == 0)
tmp = 0x3205017f;
- else if (siba->siba_chiprev == 1)
+ else if (siba_get_chiprev(sc->sc_dev) == 1)
tmp = 0x4205017f;
else
tmp = 0x5205017f;
@@ -1826,7 +1812,6 @@ bwn_chiptest(struct bwn_mac *mac)
#define TESTVAL0 0x55aaaa55
#define TESTVAL1 0xaa5555aa
struct bwn_softc *sc = mac->mac_sc;
- struct siba_dev_softc *sd = mac->mac_sd;
uint32_t v, backup;
BWN_LOCK(sc);
@@ -1842,7 +1827,8 @@ bwn_chiptest(struct bwn_mac *mac)
bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
- if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) {
+ if ((siba_get_revid(sc->sc_dev) >= 3) &&
+ (siba_get_revid(sc->sc_dev) <= 10)) {
BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
@@ -2070,15 +2056,17 @@ bwn_phy_g_attach(struct bwn_mac *mac)
struct bwn_softc *sc = mac->mac_sc;
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
unsigned int i;
- int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1),
- pab2 = (int16_t)(sprom->pa0b2);
+ int16_t pab0, pab1, pab2;
static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
- int8_t bg = (int8_t)sprom->tssi_bg;
+ int8_t bg;
- if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050))
+ bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
+ pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
+ pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
+ pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
+
+ if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
device_printf(sc->sc_dev, "not supported anymore\n");
pg->pg_flags = 0;
@@ -2175,8 +2163,8 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
+ struct bwn_softc *sc = mac->mac_sc;
struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
- struct siba_softc *bus = mac->mac_sd->sd_bus;
static const struct bwn_rfatt rfatt0[] = {
{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
@@ -2204,12 +2192,12 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
/* prepare Radio Attenuation */
pg->pg_rfatt.padmix = 0;
- if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
- bus->siba_board_type == SIBA_BOARD_BCM4309G) {
- if (bus->siba_board_rev < 0x43) {
+ if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
+ siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
+ if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
pg->pg_rfatt.att = 2;
goto done;
- } else if (bus->siba_board_rev < 0x51) {
+ } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
pg->pg_rfatt.att = 3;
goto done;
}
@@ -2228,24 +2216,25 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
goto done;
case 1:
if (phy->type == BWN_PHYTYPE_G) {
- if (bus->siba_board_vendor ==
+ if (siba_get_pci_subvendor(sc->sc_dev) ==
SIBA_BOARDVENDOR_BCM &&
- bus->siba_board_type ==
+ siba_get_pci_subdevice(sc->sc_dev) ==
SIBA_BOARD_BCM4309G &&
- bus->siba_board_rev >= 30)
+ siba_get_pci_revid(sc->sc_dev) >= 30)
pg->pg_rfatt.att = 3;
- else if (bus->siba_board_vendor ==
+ else if (siba_get_pci_subvendor(sc->sc_dev) ==
SIBA_BOARDVENDOR_BCM &&
- bus->siba_board_type == SIBA_BOARD_BU4306)
+ siba_get_pci_subdevice(sc->sc_dev) ==
+ SIBA_BOARD_BU4306)
pg->pg_rfatt.att = 3;
else
pg->pg_rfatt.att = 1;
} else {
- if (bus->siba_board_vendor ==
+ if (siba_get_pci_subvendor(sc->sc_dev) ==
SIBA_BOARDVENDOR_BCM &&
- bus->siba_board_type ==
+ siba_get_pci_subdevice(sc->sc_dev) ==
SIBA_BOARD_BCM4309G &&
- bus->siba_board_rev >= 30)
+ siba_get_pci_revid(sc->sc_dev) >= 30)
pg->pg_rfatt.att = 7;
else
pg->pg_rfatt.att = 6;
@@ -2253,17 +2242,18 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
goto done;
case 2:
if (phy->type == BWN_PHYTYPE_G) {
- if (bus->siba_board_vendor ==
+ if (siba_get_pci_subvendor(sc->sc_dev) ==
SIBA_BOARDVENDOR_BCM &&
- bus->siba_board_type ==
+ siba_get_pci_subdevice(sc->sc_dev) ==
SIBA_BOARD_BCM4309G &&
- bus->siba_board_rev >= 30)
+ siba_get_pci_revid(sc->sc_dev) >= 30)
pg->pg_rfatt.att = 3;
- else if (bus->siba_board_vendor ==
+ else if (siba_get_pci_subvendor(sc->sc_dev) ==
SIBA_BOARDVENDOR_BCM &&
- bus->siba_board_type == SIBA_BOARD_BU4306)
+ siba_get_pci_subdevice(sc->sc_dev) ==
+ SIBA_BOARD_BU4306)
pg->pg_rfatt.att = 5;
- else if (bus->siba_chipid == 0x4320)
+ else if (siba_get_chipid(sc->sc_dev) == 0x4320)
pg->pg_rfatt.att = 4;
else
pg->pg_rfatt.att = 3;
@@ -2547,7 +2537,6 @@ bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
struct bwn_softc *sc = mac->mac_sc;
- struct siba_softc *siba = mac->mac_sd->sd_bus;
unsigned int tssi;
int cck, ofdm;
int power;
@@ -2570,12 +2559,13 @@ bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
pg->pg_avgtssi = tssi;
KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
- max = siba->siba_sprom.maxpwr_bg;
- if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL)
+ max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
max -= 3;
if (max >= 120) {
device_printf(sc->sc_dev, "invalid max TX-power value\n");
- siba->siba_sprom.maxpwr_bg = max = 80;
+ max = 80;
+ siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
}
power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
@@ -2619,9 +2609,8 @@ bwn_phy_g_set_txpwr(struct bwn_mac *mac)
txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
rfatt += 2;
bbatt += 2;
- } else if (mac->mac_sd->sd_bus->siba_sprom.
- bf_lo &
- BWN_BFL_PACTRL) {
+ } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
+ BWN_BFL_PACTRL) {
bbatt += 4 * (rfatt - 2);
rfatt = 2;
}
@@ -2716,9 +2705,10 @@ static void
bwn_phy_g_task_60s(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
+ struct bwn_softc *sc = mac->mac_sc;
uint8_t old = phy->chan;
- if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI))
+ if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
return;
bwn_mac_suspend(mac);
@@ -2773,20 +2763,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
/*
- * Setup driver-specific state for a newly associated node.
- * Note that we're called also on a re-associate, the isnew
- * param tells us if this is the first time or not.
- */
-static void
-bwn_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
- &BWN_NODE(ni)->bn_amn, ni);
-}
-
-/*
* Callback from the 802.11 layer to update the slot time
* based on the current setting. We use it to notify the
* firmware of ERP changes and the f/w takes care of things
@@ -2858,32 +2834,6 @@ bwn_wme_update(struct ieee80211com *ic)
return (0);
}
-static struct ieee80211_node *
-bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct ieee80211com *ic = vap->iv_ic;
- struct bwn_softc *sc = ic->ic_ifp->if_softc;
- const size_t space = sizeof(struct bwn_node);
- struct bwn_node *bn;
-
- bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
- if (bn == NULL) {
- /* XXX stat+msg */
- return (NULL);
- }
- DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
- return (&bn->bn_node);
-}
-
-static void
-bwn_node_cleanup(struct ieee80211_node *ni)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct bwn_softc *sc = ic->ic_ifp->if_softc;
-
- sc->sc_node_cleanup(ni);
-}
-
static void
bwn_scan_start(struct ieee80211com *ic)
{
@@ -3019,10 +2969,7 @@ bwn_vap_create(struct ieee80211com *ic,
/* override max aid so sta's cannot assoc when we're out of sta id's */
vap->iv_max_aid = BWN_STAID_MAX;
- ieee80211_amrr_init(&bvp->bv_amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /*ms*/);
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
@@ -3035,7 +2982,7 @@ bwn_vap_delete(struct ieee80211vap *vap)
{
struct bwn_vap *bvp = BWN_VAP(vap);
- ieee80211_amrr_cleanup(&bvp->bv_amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(bvp, M_80211_VAP);
}
@@ -3182,20 +3129,15 @@ bwn_wme_clear(struct bwn_softc *sc)
static int
bwn_core_init(struct bwn_mac *mac)
{
-#ifdef BWN_DEBUG
struct bwn_softc *sc = mac->mac_sc;
-#endif
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
- struct siba_sprom *sprom = &siba->siba_sprom;
uint64_t hf;
int error;
KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
("%s:%d: fail", __func__, __LINE__));
- siba_powerup(siba, 0);
- if (!siba_dev_isup(sd))
+ siba_powerup(sc->sc_dev, 0);
+ if (!siba_dev_isup(sc->sc_dev))
bwn_reset_core(mac,
mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
@@ -3219,9 +3161,9 @@ bwn_core_init(struct bwn_mac *mac)
mac->mac_phy.init_pre(mac);
- siba_pcicore_intr(&siba->siba_pci, sd);
+ siba_pcicore_intr(sc->sc_dev);
- bwn_fix_imcfglobug(mac);
+ siba_fix_imcfglobug(sc->sc_dev);
bwn_bt_disable(mac);
if (mac->mac_phy.prepare_hw) {
error = mac->mac_phy.prepare_hw(mac);
@@ -3232,11 +3174,11 @@ bwn_core_init(struct bwn_mac *mac)
if (error)
goto fail0;
bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
- mac->mac_sd->sd_id.sd_rev);
+ siba_get_revid(sc->sc_dev));
hf = bwn_hf_read(mac);
if (mac->mac_phy.type == BWN_PHYTYPE_G) {
hf |= BWN_HF_GPHY_SYM_WORKAROUND;
- if (sprom->bf_lo & BWN_BFL_PACTRL)
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
if (mac->mac_phy.rev == 1)
hf |= BWN_HF_GPHY_DC_CANCELFILTER;
@@ -3247,10 +3189,10 @@ bwn_core_init(struct bwn_mac *mac)
if (mac->mac_phy.rf_rev == 6)
hf |= BWN_HF_4318_TSSI;
}
- if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
- if ((siba->siba_type == SIBA_TYPE_PCI) &&
- (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10))
+ if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
+ (siba_get_pcicore_revid(sc->sc_dev) <= 10))
hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
hf &= ~BWN_HF_SKIP_CFP_UPDATE;
bwn_hf_write(mac, hf);
@@ -3267,7 +3209,7 @@ bwn_core_init(struct bwn_mac *mac)
(mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
- if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
+ if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
bwn_pio_init(mac);
else
bwn_dma_init(mac);
@@ -3277,7 +3219,8 @@ bwn_core_init(struct bwn_mac *mac)
bwn_spu_setdelay(mac, 1);
bwn_bt_enable(mac);
- siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW));
+ siba_powerup(sc->sc_dev,
+ !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
bwn_set_macaddr(mac);
bwn_crypt_init(mac);
@@ -3290,7 +3233,7 @@ bwn_core_init(struct bwn_mac *mac)
fail1:
bwn_chip_exit(mac);
fail0:
- siba_powerdown(siba);
+ siba_powerdown(sc->sc_dev);
KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
("%s:%d: fail", __func__, __LINE__));
return (error);
@@ -3305,7 +3248,7 @@ bwn_core_start(struct bwn_mac *mac)
KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
("%s:%d: fail", __func__, __LINE__));
- if (mac->mac_sd->sd_id.sd_rev < 5)
+ if (siba_get_revid(sc->sc_dev) < 5)
return;
while (1) {
@@ -3325,6 +3268,7 @@ bwn_core_start(struct bwn_mac *mac)
static void
bwn_core_exit(struct bwn_mac *mac)
{
+ struct bwn_softc *sc = mac->mac_sc;
uint32_t macctl;
BWN_ASSERT_LOCKED(mac->mac_sc);
@@ -3345,35 +3289,8 @@ bwn_core_exit(struct bwn_mac *mac)
bwn_pio_stop(mac);
bwn_chip_exit(mac);
mac->mac_phy.switch_analog(mac, 0);
- siba_dev_down(mac->mac_sd, 0);
- siba_powerdown(mac->mac_sd->sd_bus);
-}
-
-static void
-bwn_fix_imcfglobug(struct bwn_mac *mac)
-{
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
- uint32_t tmp;
-
- if (siba->siba_pci.spc_dev == NULL)
- return;
- if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI ||
- siba->siba_pci.spc_dev->sd_id.sd_rev > 5)
- return;
-
- tmp = siba_read_4(sd, SIBA_IMCFGLO) &
- ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO);
- switch (siba->siba_type) {
- case SIBA_TYPE_PCI:
- case SIBA_TYPE_PCMCIA:
- tmp |= 0x32;
- break;
- case SIBA_TYPE_SSB:
- tmp |= 0x53;
- break;
- }
- siba_write_4(sd, SIBA_IMCFGLO, tmp);
+ siba_dev_down(sc->sc_dev, 0);
+ siba_powerdown(sc->sc_dev);
}
static void
@@ -3388,6 +3305,7 @@ bwn_bt_disable(struct bwn_mac *mac)
static int
bwn_chip_init(struct bwn_mac *mac)
{
+ struct bwn_softc *sc = mac->mac_sc;
struct bwn_phy *phy = &mac->mac_phy;
uint32_t macctl;
int error;
@@ -3410,13 +3328,13 @@ bwn_chip_init(struct bwn_mac *mac)
error = bwn_fw_loadinitvals(mac);
if (error) {
- bwn_gpio_cleanup(mac);
+ siba_gpio_set(sc->sc_dev, 0);
return (error);
}
phy->switch_analog(mac, 1);
error = bwn_phy_init(mac);
if (error) {
- bwn_gpio_cleanup(mac);
+ siba_gpio_set(sc->sc_dev, 0);
return (error);
}
if (phy->set_im)
@@ -3428,7 +3346,7 @@ bwn_chip_init(struct bwn_mac *mac)
if (phy->type == BWN_PHYTYPE_B)
BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
BWN_WRITE_4(mac, 0x0100, 0x01000000);
- if (mac->mac_sd->sd_id.sd_rev < 5)
+ if (siba_get_revid(sc->sc_dev) < 5)
BWN_WRITE_4(mac, 0x010c, 0x01000000);
BWN_WRITE_4(mac, BWN_MACCTL,
@@ -3438,7 +3356,7 @@ bwn_chip_init(struct bwn_mac *mac)
bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
bwn_set_opmode(mac);
- if (mac->mac_sd->sd_id.sd_rev < 3) {
+ if (siba_get_revid(sc->sc_dev) < 3) {
BWN_WRITE_2(mac, 0x060e, 0x0000);
BWN_WRITE_2(mac, 0x0610, 0x8000);
BWN_WRITE_2(mac, 0x0604, 0x0000);
@@ -3454,10 +3372,9 @@ bwn_chip_init(struct bwn_mac *mac)
BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
- siba_write_4(mac->mac_sd, SIBA_TGSLOW,
- siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000);
- BWN_WRITE_2(mac, BWN_POWERUP_DELAY,
- mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay);
+ siba_write_4(sc->sc_dev, SIBA_TGSLOW,
+ siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
+ BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
return (error);
}
@@ -3619,13 +3536,14 @@ bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
int index)
{
struct bwn_pio_txpkt *tp;
+ struct bwn_softc *sc = mac->mac_sc;
unsigned int i;
tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
tq->tq_index = index;
tq->tq_free = BWN_PIO_MAX_TXPACKETS;
- if (mac->mac_sd->sd_id.sd_rev >= 8)
+ if (siba_get_revid(sc->sc_dev) >= 8)
tq->tq_size = 1920;
else {
tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
@@ -3664,7 +3582,7 @@ bwn_pio_idx2base(struct bwn_mac *mac, int index)
BWN_PIO11_BASE5,
};
- if (mac->mac_sd->sd_id.sd_rev >= 11) {
+ if (siba_get_revid(sc->sc_dev) >= 11) {
if (index >= N(bases_rev11))
device_printf(sc->sc_dev, "%s: warning\n", __func__);
return (bases_rev11[index]);
@@ -3678,9 +3596,10 @@ static void
bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
int index)
{
+ struct bwn_softc *sc = mac->mac_sc;
prq->prq_mac = mac;
- prq->prq_rev = mac->mac_sd->sd_id.sd_rev;
+ prq->prq_rev = siba_get_revid(sc->sc_dev);
prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
bwn_dma_rxdirectfifo(mac, index, 1);
}
@@ -4027,6 +3946,7 @@ bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
int start, int end, int irq)
{
struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
+ struct bwn_softc *sc = dr->dr_mac->mac_sc;
uint32_t addr, addrext, ctl;
int slot;
@@ -4036,7 +3956,7 @@ bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
- addr |= siba_dma_translation(dr->dr_mac->mac_sd);
+ addr |= siba_dma_translation(sc->sc_dev);
ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
if (slot == dr->dr_numslots - 1)
ctl |= BWN_DMA32_DCTL_DTABLEEND;
@@ -4115,6 +4035,7 @@ bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
int start, int end, int irq)
{
struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
+ struct bwn_softc *sc = dr->dr_mac->mac_sc;
int slot;
uint32_t ctl0 = 0, ctl1 = 0;
uint32_t addrlo, addrhi;
@@ -4128,7 +4049,7 @@ bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
30;
- addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1);
+ addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
if (slot == dr->dr_numslots - 1)
ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
if (start)
@@ -4238,9 +4159,10 @@ bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
static void
bwn_dma_setup(struct bwn_dma_ring *dr)
{
+ struct bwn_softc *sc = dr->dr_mac->mac_sc;
uint64_t ring64;
uint32_t addrext, ring32, value;
- uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd);
+ uint32_t trans = siba_dma_translation(sc->sc_dev);
if (dr->dr_tx) {
dr->dr_curslot = -1;
@@ -4536,18 +4458,18 @@ bwn_spu_setdelay(struct bwn_mac *mac, int idle)
static void
bwn_bt_enable(struct bwn_mac *mac)
{
- struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
+ struct bwn_softc *sc = mac->mac_sc;
uint64_t hf;
if (bwn_bluetooth == 0)
return;
- if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0)
+ if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
return;
if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
return;
hf = bwn_hf_read(mac);
- if (sprom->bf_lo & BWN_BFL_BTCMOD)
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
hf |= BWN_HF_BT_COEXISTALT;
else
hf |= BWN_HF_BT_COEXIST;
@@ -4584,25 +4506,25 @@ bwn_clear_keys(struct bwn_mac *mac)
static void
bwn_crypt_init(struct bwn_mac *mac)
{
+ struct bwn_softc *sc = mac->mac_sc;
- mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20;
+ mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
("%s:%d: fail", __func__, __LINE__));
mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
mac->mac_ktp *= 2;
- if (mac->mac_sd->sd_id.sd_rev >= 5) {
- BWN_WRITE_2(mac, BWN_RCMTA_COUNT,
- mac->mac_max_nr_keys - 8);
- }
+ if (siba_get_revid(sc->sc_dev) >= 5)
+ BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
bwn_clear_keys(mac);
}
static void
bwn_chip_exit(struct bwn_mac *mac)
{
+ struct bwn_softc *sc = mac->mac_sc;
bwn_phy_exit(mac);
- bwn_gpio_cleanup(mac);
+ siba_gpio_set(sc->sc_dev, 0);
}
static int
@@ -4622,33 +4544,31 @@ bwn_fw_fillinfo(struct bwn_mac *mac)
static int
bwn_gpio_init(struct bwn_mac *mac)
{
- struct siba_softc *bus = mac->mac_sd->sd_bus;
- struct siba_dev_softc *sd;
- uint32_t mask = 0x0000001f, set = 0x0000000f;
+ struct bwn_softc *sc = mac->mac_sc;
+ uint32_t mask = 0x1f, set = 0xf, value;
BWN_WRITE_4(mac, BWN_MACCTL,
BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
BWN_WRITE_2(mac, BWN_GPIO_MASK,
BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
- if (bus->siba_chipid == 0x4301) {
+ if (siba_get_chipid(sc->sc_dev) == 0x4301) {
mask |= 0x0060;
set |= 0x0060;
}
- if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) {
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
BWN_WRITE_2(mac, BWN_GPIO_MASK,
BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
mask |= 0x0200;
set |= 0x0200;
}
- if (mac->mac_sd->sd_id.sd_rev >= 2)
+ if (siba_get_revid(sc->sc_dev) >= 2)
mask |= 0x0010;
- sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev :
- bus->siba_pci.spc_dev;
- if (sd == NULL)
+
+ value = siba_gpio_get(sc->sc_dev);
+ if (value == -1)
return (0);
- siba_write_4(sd, BWN_GPIOCTL,
- (siba_read_4(sd, BWN_GPIOCTL) & mask) | set);
+ siba_gpio_set(sc->sc_dev, (value & mask) | set);
return (0);
}
@@ -4749,15 +4669,15 @@ bwn_set_opmode(struct bwn_mac *mac)
ctl &= ~BWN_MACCTL_STA;
ctl |= sc->sc_filters;
- if (mac->mac_sd->sd_id.sd_rev <= 4)
+ if (siba_get_revid(sc->sc_dev) <= 4)
ctl |= BWN_MACCTL_PROMISC;
BWN_WRITE_4(mac, BWN_MACCTL, ctl);
cfp_pretbtt = 2;
if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
- if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 &&
- mac->mac_sd->sd_bus->siba_chiprev == 3)
+ if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
+ siba_get_chiprev(sc->sc_dev) == 3)
cfp_pretbtt = 100;
else
cfp_pretbtt = 50;
@@ -4765,19 +4685,6 @@ bwn_set_opmode(struct bwn_mac *mac)
BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
}
-static void
-bwn_gpio_cleanup(struct bwn_mac *mac)
-{
- struct siba_softc *bus = mac->mac_sd->sd_bus;
- struct siba_dev_softc *gpiodev, *pcidev = NULL;
-
- pcidev = bus->siba_pci.spc_dev;
- gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev;
- if (!gpiodev)
- return;
- siba_write_4(gpiodev, BWN_GPIOCTL, 0);
-}
-
static int
bwn_dma_gettype(struct bwn_mac *mac)
{
@@ -4810,6 +4717,7 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
+ struct bwn_softc *sc = mac->mac_sc;
uint16_t i, tmp;
if (phy->rev == 1)
@@ -4872,7 +4780,7 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
(pg->pg_loctl.tx_bias << 12));
}
- if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
else
BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
@@ -4885,7 +4793,7 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
}
- if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
+ if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
for (i = 0; i < 64; i++) {
BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
@@ -4904,8 +4812,8 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
if (phy->rf_rev == 8)
BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
bwn_phy_hwpctl_init(mac);
- if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306
- && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) {
+ if ((siba_get_chipid(sc->sc_dev) == 0x4306
+ && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
}
@@ -4923,16 +4831,16 @@ bwn_has_hwpctl(struct bwn_mac *mac)
static void
bwn_phy_init_b5(struct bwn_mac *mac)
{
- struct siba_softc *bus = mac->mac_sd->sd_bus;
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
+ struct bwn_softc *sc = mac->mac_sc;
uint16_t offset, value;
uint8_t old_channel;
if (phy->analog == 1)
BWN_RF_SET(mac, 0x007a, 0x0050);
- if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) &&
- (bus->siba_board_type != SIBA_BOARD_BU4306)) {
+ if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
+ (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
value = 0x2120;
for (offset = 0x00a8; offset < 0x00c7; offset++) {
BWN_PHY_WRITE(mac, offset, value);
@@ -5021,6 +4929,7 @@ bwn_loopback_calcgain(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
+ struct bwn_softc *sc = mac->mac_sc;
uint16_t backup_phy[16] = { 0 };
uint16_t backup_radio[3];
uint16_t backup_bband;
@@ -5099,7 +5008,7 @@ bwn_loopback_calcgain(struct bwn_mac *mac)
BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
- if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) {
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
if (phy->rev >= 7) {
BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
@@ -5399,6 +5308,7 @@ bwn_phy_init_b6(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
+ struct bwn_softc *sc = mac->mac_sc;
uint16_t offset, val;
uint8_t old_channel;
@@ -5428,7 +5338,7 @@ bwn_phy_init_b6(struct bwn_mac *mac)
BWN_RF_WRITE(mac, 0x5a, 0x88);
BWN_RF_WRITE(mac, 0x5b, 0x6b);
BWN_RF_WRITE(mac, 0x5c, 0x0f);
- if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) {
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
BWN_RF_WRITE(mac, 0x5d, 0xfa);
BWN_RF_WRITE(mac, 0x5e, 0xd8);
} else {
@@ -5509,6 +5419,7 @@ static void
bwn_phy_init_a(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
+ struct bwn_softc *sc = mac->mac_sc;
KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
("%s:%d: fail", __func__, __LINE__));
@@ -5525,7 +5436,7 @@ bwn_phy_init_a(struct bwn_mac *mac)
bwn_wa_init(mac);
if (phy->type == BWN_PHYTYPE_G &&
- (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL))
+ (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
}
@@ -5776,7 +5687,7 @@ static void
bwn_wa_init(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
- struct siba_softc *bus = mac->mac_sd->sd_bus;
+ struct bwn_softc *sc = mac->mac_sc;
KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
@@ -5795,9 +5706,9 @@ bwn_wa_init(struct bwn_mac *mac)
KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
}
- if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM ||
- bus->siba_board_type != SIBA_BOARD_BU4306 ||
- bus->siba_board_rev != 0x17) {
+ if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
+ siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
+ siba_get_pci_revid(sc->sc_dev) != 0x17) {
if (phy->rev < 2) {
bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
0x0002);
@@ -5806,7 +5717,8 @@ bwn_wa_init(struct bwn_mac *mac)
} else {
bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
- if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) &&
+ if ((siba_sprom_get_bf_lo(sc->sc_dev) &
+ BWN_BFL_EXTLNA) &&
(phy->rev >= 7)) {
BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
@@ -5824,7 +5736,7 @@ bwn_wa_init(struct bwn_mac *mac)
}
}
}
- if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) {
+ if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
}
@@ -5882,6 +5794,7 @@ static void
bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
{
struct bwn_phy *phy = &mac->mac_phy;
+ struct bwn_softc *sc = mac->mac_sc;
unsigned int i, max_loop;
uint16_t value;
uint32_t buffer[5] = {
@@ -5903,7 +5816,7 @@ bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
BWN_WRITE_2(mac, 0x0568, 0x0000);
BWN_WRITE_2(mac, 0x07c0,
- (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100);
+ (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
BWN_WRITE_2(mac, 0x050c, value);
if (phy->type == BWN_PHYTYPE_LP)
@@ -5977,6 +5890,7 @@ bwn_lo_calcfeed(struct bwn_mac *mac,
uint16_t lna, uint16_t pga, uint16_t trsw_rx)
{
struct bwn_phy *phy = &mac->mac_phy;
+ struct bwn_softc *sc = mac->mac_sc;
uint16_t rfover;
uint16_t feedthrough;
@@ -5992,8 +5906,8 @@ bwn_lo_calcfeed(struct bwn_mac *mac,
trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
- if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA)
- && phy->rev > 6)
+ if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
+ phy->rev > 6)
rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
@@ -6241,9 +6155,9 @@ bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
static void
bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
{
- struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
+ struct bwn_softc *sc = mac->mac_sc;
struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
struct timespec ts;
uint16_t tmp;
@@ -6281,7 +6195,8 @@ bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
if (phy->type == BWN_PHYTYPE_G) {
if ((phy->rev >= 7) &&
- (sprom->bf_lo & BWN_BFL_EXTLNA)) {
+ (siba_sprom_get_bf_lo(sc->sc_dev) &
+ BWN_BFL_EXTLNA)) {
BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
} else {
BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
@@ -6781,6 +6696,7 @@ bwn_mac_enable(struct bwn_mac *mac)
static void
bwn_psctl(struct bwn_mac *mac, uint32_t flags)
{
+ struct bwn_softc *sc = mac->mac_sc;
int i;
uint16_t ucstat;
@@ -6795,7 +6711,7 @@ bwn_psctl(struct bwn_mac *mac, uint32_t flags)
(BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
~BWN_MACCTL_HWPS);
BWN_READ_4(mac, BWN_MACCTL);
- if (mac->mac_sd->sd_id.sd_rev >= 5) {
+ if (siba_get_revid(sc->sc_dev) >= 5) {
for (i = 0; i < 100; i++) {
ucstat = bwn_shm_read_2(mac, BWN_SHARED,
BWN_SHARED_UCODESTAT);
@@ -6819,14 +6735,14 @@ bwn_nrssi_threshold(struct bwn_mac *mac)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
- struct siba_softc *siba = mac->mac_sd->sd_bus;
+ struct bwn_softc *sc = mac->mac_sc;
int32_t a, b;
int16_t tmp16;
uint16_t tmpu16;
KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
- if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
+ if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
a = 0x13;
b = 0x12;
@@ -7259,18 +7175,18 @@ bwn_set_original_gains(struct bwn_mac *mac)
static void
bwn_phy_hwpctl_init(struct bwn_mac *mac)
{
- struct siba_softc *bus = mac->mac_sd->sd_bus;
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
struct bwn_rfatt old_rfatt, rfatt;
struct bwn_bbatt old_bbatt, bbatt;
+ struct bwn_softc *sc = mac->mac_sc;
uint8_t old_txctl = 0;
KASSERT(phy->type == BWN_PHYTYPE_G,
("%s:%d: fail", __func__, __LINE__));
- if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) &&
- (bus->siba_board_type == SIBA_BOARD_BU4306))
+ if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
+ (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
return;
BWN_PHY_WRITE(mac, 0x0028, 0x8018);
@@ -7407,7 +7323,7 @@ bwn_hwpctl_init_gphy(struct bwn_mac *mac)
static void
bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
{
- struct siba_softc *siba = mac->mac_sd->sd_bus;
+ struct bwn_softc *sc = mac->mac_sc;
if (spu != 0)
bwn_spu_workaround(mac, channel);
@@ -7415,7 +7331,7 @@ bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
if (channel == 14) {
- if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN)
+ if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
bwn_hf_write(mac,
bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
else
@@ -7500,7 +7416,7 @@ bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
{
struct bwn_phy *phy = &mac->mac_phy;
struct bwn_phy_g *pg = &phy->phy_g;
- struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom);
+ struct bwn_softc *sc = mac->mac_sc;
int max_lb_gain;
uint16_t extlna;
uint16_t i;
@@ -7531,7 +7447,8 @@ bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
break;
}
- if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
+ if ((phy->rev < 7) ||
+ !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
if (reg == BWN_PHY_RFOVER) {
return (0x1b3);
} else if (reg == BWN_PHY_RFOVERVAL) {
@@ -7575,7 +7492,7 @@ bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
}
if ((phy->rev < 7) ||
- !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
+ !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
if (reg == BWN_PHY_RFOVER) {
return (0x1b3);
} else if (reg == BWN_PHY_RFOVERVAL) {
@@ -7632,7 +7549,7 @@ bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
{
struct bwn_softc *sc = mac->mac_sc;
struct bwn_fw *fw = &mac->mac_fw;
- const uint8_t rev = mac->mac_sd->sd_id.sd_rev;
+ const uint8_t rev = siba_get_revid(sc->sc_dev);
const char *filename;
uint32_t high;
int error;
@@ -7675,7 +7592,7 @@ bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
}
/* initvals */
- high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH);
+ high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
switch (mac->mac_phy.type) {
case BWN_PHYTYPE_A:
if (rev < 5 || rev > 10)
@@ -8206,6 +8123,7 @@ bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
static void
bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
{
+ struct bwn_softc *sc = mac->mac_sc;
uint32_t addrtmp[2] = { 0, 0 };
uint8_t start = 8;
@@ -8225,7 +8143,7 @@ bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
}
- if (mac->mac_sd->sd_id.sd_rev >= 5) {
+ if (siba_get_revid(sc->sc_dev) >= 5) {
bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
} else {
@@ -8396,14 +8314,14 @@ bwn_rf_turnoff(struct bwn_mac *mac)
static void
bwn_phy_reset(struct bwn_mac *mac)
{
- struct siba_dev_softc *sd = mac->mac_sd;
+ struct bwn_softc *sc = mac->mac_sc;
- siba_write_4(sd, SIBA_TGSLOW,
- ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
+ siba_write_4(sc->sc_dev, SIBA_TGSLOW,
+ ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
DELAY(1000);
- siba_write_4(sd, SIBA_TGSLOW,
- (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
+ siba_write_4(sc->sc_dev, SIBA_TGSLOW,
+ (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
BWN_TGSLOW_PHYRESET);
DELAY(1000);
}
@@ -8486,10 +8404,10 @@ bwn_intr(void *arg)
{
struct bwn_mac *mac = arg;
struct bwn_softc *sc = mac->mac_sc;
- struct siba_softc *siba = mac->mac_sd->sd_bus;
uint32_t reason;
- if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid)
+ if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
+ (sc->sc_flags & BWN_FLAG_INVALID))
return (FILTER_STRAY);
reason = BWN_READ_4(mac, BWN_INTR_REASON);
@@ -8529,12 +8447,12 @@ bwn_intrtask(void *arg, int npending)
struct bwn_mac *mac = arg;
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
- struct siba_softc *siba = mac->mac_sd->sd_bus;
uint32_t merged = 0;
int i, tx = 0, rx = 0;
BWN_LOCK(sc);
- if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) {
+ if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
+ (sc->sc_flags & BWN_FLAG_INVALID)) {
BWN_UNLOCK(sc);
return;
}
@@ -9070,12 +8988,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
struct bwn_dma_ring *dr;
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *meta;
- struct bwn_node *bn;
struct bwn_pio_txqueue *tq;
struct bwn_pio_txpkt *tp = NULL;
struct bwn_softc *sc = mac->mac_sc;
struct bwn_stats *stats = &mac->mac_stats;
struct ieee80211_node *ni;
+ struct ieee80211vap *vap;
int slot;
BWN_ASSERT_LOCKED(mac->mac_sc);
@@ -9104,9 +9022,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
dr->getdesc(dr, slot, &desc, &meta);
if (meta->mt_islast) {
ni = meta->mt_ni;
- bn = (struct bwn_node *)ni;
- ieee80211_amrr_tx_complete(&bn->bn_amn,
- status->ack, 0);
+ vap = ni->ni_vap;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ status->ack ?
+ IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE,
+ NULL, 0);
break;
}
slot = bwn_dma_nextslot(dr, slot);
@@ -9122,8 +9043,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
return;
}
ni = tp->tp_ni;
- bn = (struct bwn_node *)ni;
- ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
+ vap = ni->ni_vap;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ status->ack ?
+ IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE,
+ NULL, 0);
}
bwn_pio_handle_txeof(mac, status);
}
@@ -9176,10 +9101,10 @@ bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
return (1);
ready:
if (prq->prq_rev >= 8)
- siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr),
+ siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
prq->prq_base + BWN_PIO8_RXDATA);
else
- siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr),
+ siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
prq->prq_base + BWN_PIO_RXDATA);
len = le16toh(rxhdr.frame_len);
if (len > 0x700) {
@@ -9208,7 +9133,7 @@ ready:
}
mp = mtod(m, unsigned char *);
if (prq->prq_rev >= 8) {
- siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3),
+ siba_read_multi_4(sc->sc_dev, mp + padding, (len & ~3),
prq->prq_base + BWN_PIO8_RXDATA);
if (len & 3) {
v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
@@ -9225,7 +9150,7 @@ ready:
}
}
} else {
- siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1),
+ siba_read_multi_2(sc->sc_dev, mp + padding, (len & ~1),
prq->prq_base + BWN_PIO_RXDATA);
if (len & 1) {
v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
@@ -9443,6 +9368,8 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
noise = mac->mac_stats.link_noise;
+ ifp->if_ipackets++;
+
BWN_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, wh);
@@ -9578,7 +9505,6 @@ bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
struct bwn_phy *phy = &mac->mac_phy;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct siba_softc *siba = mac->mac_sd->sd_bus;
unsigned long now;
int result;
@@ -9588,8 +9514,8 @@ bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
return;
phy->nexttime = now + 2 * 1000;
- if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
- siba->siba_board_type == SIBA_BOARD_BU4306)
+ if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
+ siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
return;
if (phy->recalc_txpwr != NULL) {
@@ -9709,7 +9635,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = rate_fb = tp->ucastrate;
else {
- rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
+ rix = ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
if (rix > 0)
@@ -9902,14 +9828,15 @@ bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
static uint8_t
bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
{
+ struct bwn_softc *sc = mac->mac_sc;
uint8_t mask;
if (n == 0)
return (0);
if (mac->mac_phy.gmode)
- mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg;
+ mask = siba_sprom_get_ant_bg(sc->sc_dev);
else
- mask = mac->mac_sd->sd_bus->siba_sprom.ant_a;
+ mask = siba_sprom_get_ant_a(sc->sc_dev);
if (!(mask & (1 << (n - 1))))
return (0);
return (n);
@@ -9952,6 +9879,7 @@ static uint32_t
bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
uint32_t ctl, const void *_data, int len)
{
+ struct bwn_softc *sc = mac->mac_sc;
uint32_t value = 0;
const uint8_t *data = _data;
@@ -9959,7 +9887,7 @@ bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
- siba_write_multi_4(mac->mac_sd, data, (len & ~3),
+ siba_write_multi_4(sc->sc_dev, data, (len & ~3),
tq->tq_base + BWN_PIO8_TXDATA);
if (len & 3) {
ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
@@ -9996,12 +9924,13 @@ static uint16_t
bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
uint16_t ctl, const void *_data, int len)
{
+ struct bwn_softc *sc = mac->mac_sc;
const uint8_t *data = _data;
ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
- siba_write_multi_2(mac->mac_sd, data, (len & ~1),
+ siba_write_multi_2(sc->sc_dev, data, (len & ~1),
tq->tq_base + BWN_PIO_TXDATA);
if (len & 1) {
ctl &= ~BWN_PIO_TXCTL_WRITEHI;
@@ -10180,8 +10109,8 @@ bwn_phy_lock(struct bwn_mac *mac)
struct bwn_softc *sc = mac->mac_sc;
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
- ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
+ KASSERT(siba_get_revid(sc->sc_dev) >= 3,
+ ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
bwn_psctl(mac, BWN_PS_AWAKE);
@@ -10193,8 +10122,8 @@ bwn_phy_unlock(struct bwn_mac *mac)
struct bwn_softc *sc = mac->mac_sc;
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
- ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
+ KASSERT(siba_get_revid(sc->sc_dev) >= 3,
+ ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
bwn_psctl(mac, 0);
@@ -10413,7 +10342,7 @@ bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
{
uint32_t low, high;
- KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
+ KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
("%s:%d: fail", __func__, __LINE__));
low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
@@ -10428,15 +10357,13 @@ bwn_dma_attach(struct bwn_mac *mac)
{
struct bwn_dma *dma = &mac->mac_method.dma;
struct bwn_softc *sc = mac->mac_sc;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
bus_addr_t lowaddr = 0;
int error;
- if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
+ if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
return (0);
- KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__));
+ KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
mac->mac_flags |= BWN_MAC_FLAG_DMA;
@@ -10635,7 +10562,6 @@ static void
bwn_led_attach(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct siba_softc *siba = mac->mac_sd->sd_bus;
const uint8_t *led_act = NULL;
uint16_t val[BWN_LED_MAX];
int i;
@@ -10644,7 +10570,8 @@ bwn_led_attach(struct bwn_mac *mac)
sc->sc_led_blink = 1;
for (i = 0; i < N(bwn_vendor_led_act); ++i) {
- if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) {
+ if (siba_get_pci_subvendor(sc->sc_dev) ==
+ bwn_vendor_led_act[i].vid) {
led_act = bwn_vendor_led_act[i].led_act;
break;
}
@@ -10652,10 +10579,10 @@ bwn_led_attach(struct bwn_mac *mac)
if (led_act == NULL)
led_act = bwn_default_led_act;
- val[0] = siba->siba_sprom.gpio0;
- val[1] = siba->siba_sprom.gpio1;
- val[2] = siba->siba_sprom.gpio2;
- val[3] = siba->siba_sprom.gpio3;
+ val[0] = siba_sprom_get_gpio0(sc->sc_dev);
+ val[1] = siba_sprom_get_gpio1(sc->sc_dev);
+ val[2] = siba_sprom_get_gpio2(sc->sc_dev);
+ val[3] = siba_sprom_get_gpio3(sc->sc_dev);
for (i = 0; i < BWN_LED_MAX; ++i) {
struct bwn_led *led = &sc->sc_leds[i];
@@ -10771,82 +10698,82 @@ static void
bwn_led_event(struct bwn_mac *mac, int event)
{
struct bwn_softc *sc = mac->mac_sc;
- struct bwn_led *led = sc->sc_blink_led;
- int rate;
-
- if (event == BWN_LED_EVENT_POLL) {
- if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
- return;
- if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
- return;
- }
-
- sc->sc_led_ticks = ticks;
- if (sc->sc_led_blinking)
- return;
-
- switch (event) {
- case BWN_LED_EVENT_RX:
- rate = sc->sc_rx_rate;
- break;
- case BWN_LED_EVENT_TX:
- rate = sc->sc_tx_rate;
- break;
- case BWN_LED_EVENT_POLL:
- rate = 0;
- break;
- default:
- panic("unknown LED event %d\n", event);
- break;
- }
- bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
- bwn_led_duration[rate].off_dur);
+ struct bwn_led *led = sc->sc_blink_led;
+ int rate;
+
+ if (event == BWN_LED_EVENT_POLL) {
+ if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
+ return;
+ if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
+ return;
+ }
+
+ sc->sc_led_ticks = ticks;
+ if (sc->sc_led_blinking)
+ return;
+
+ switch (event) {
+ case BWN_LED_EVENT_RX:
+ rate = sc->sc_rx_rate;
+ break;
+ case BWN_LED_EVENT_TX:
+ rate = sc->sc_tx_rate;
+ break;
+ case BWN_LED_EVENT_POLL:
+ rate = 0;
+ break;
+ default:
+ panic("unknown LED event %d\n", event);
+ break;
+ }
+ bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
+ bwn_led_duration[rate].off_dur);
}
static void
bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
{
struct bwn_softc *sc = mac->mac_sc;
- struct bwn_led *led = sc->sc_blink_led;
- uint16_t val;
+ struct bwn_led *led = sc->sc_blink_led;
+ uint16_t val;
- val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
- val = bwn_led_onoff(led, val, 1);
- BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
+ val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
+ val = bwn_led_onoff(led, val, 1);
+ BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
- if (led->led_flags & BWN_LED_F_SLOW) {
- BWN_LED_SLOWDOWN(on_dur);
- BWN_LED_SLOWDOWN(off_dur);
- }
+ if (led->led_flags & BWN_LED_F_SLOW) {
+ BWN_LED_SLOWDOWN(on_dur);
+ BWN_LED_SLOWDOWN(off_dur);
+ }
- sc->sc_led_blinking = 1;
- sc->sc_led_blink_offdur = off_dur;
+ sc->sc_led_blinking = 1;
+ sc->sc_led_blink_offdur = off_dur;
- callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
+ callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
}
static void
bwn_led_blink_next(void *arg)
{
struct bwn_mac *mac = arg;
- struct bwn_softc *sc = mac->mac_sc;
- uint16_t val;
+ struct bwn_softc *sc = mac->mac_sc;
+ uint16_t val;
- val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
- val = bwn_led_onoff(sc->sc_blink_led, val, 0);
- BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
+ val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
+ val = bwn_led_onoff(sc->sc_blink_led, val, 0);
+ BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
- callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
- bwn_led_blink_end, mac);
+ callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
+ bwn_led_blink_end, mac);
}
static void
bwn_led_blink_end(void *arg)
{
struct bwn_mac *mac = arg;
- struct bwn_softc *sc = mac->mac_sc;
+ struct bwn_softc *sc = mac->mac_sc;
- sc->sc_led_blinking = 0;
+ sc->sc_led_blinking = 0;
}
static int
@@ -11101,8 +11028,6 @@ bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- device_printf(sc->sc_dev, "correct?\n");
-
return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
}
@@ -11136,31 +11061,25 @@ bwn_phy_lp_readsprom(struct bwn_mac *mac)
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
- struct siba_sprom *sprom = &siba->siba_sprom;
-
- device_printf(sc->sc_dev, "XXX using %dghz\n",
- IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5);
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
- plp->plp_txisoband_m = sprom->tri2g;
- plp->plp_bxarch = sprom->bxa2g;
- plp->plp_rxpwroffset = sprom->rxpo2g;
- plp->plp_rssivf = sprom->rssismf2g;
- plp->plp_rssivc = sprom->rssismc2g;
- plp->plp_rssigs = sprom->rssisav2g;
+ plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
+ plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
+ plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
+ plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
+ plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
+ plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
return;
}
- plp->plp_txisoband_l = sprom->tri5gl;
- plp->plp_txisoband_m = sprom->tri5g;
- plp->plp_txisoband_h = sprom->tri5gh;
- plp->plp_bxarch = sprom->bxa5g;
- plp->plp_rxpwroffset = sprom->rxpo5g;
- plp->plp_rssivf = sprom->rssismf5g;
- plp->plp_rssivc = sprom->rssismc5g;
- plp->plp_rssigs = sprom->rssisav5g;
+ plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
+ plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
+ plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
+ plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
+ plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
+ plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
+ plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
+ plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
}
static void
@@ -11192,8 +11111,6 @@ static void
bwn_phy_lp_calib(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
@@ -11240,7 +11157,7 @@ bwn_phy_lp_calib(struct bwn_mac *mac)
bwn_phy_lp_digflt_restore(mac);
/* do RX IQ Calculation; assumes that noise is true. */
- if (siba->siba_chipid == 0x5354) {
+ if (siba_get_chipid(sc->sc_dev) == 0x5354) {
for (i = 0; i < N(bwn_rxcompco_5354); i++) {
if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
rc = &bwn_rxcompco_5354[i];
@@ -11306,21 +11223,20 @@ static void
bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
{
- if (on) {
- BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
- return;
- }
+ if (on) {
+ BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
+ return;
+ }
- BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
- BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
+ BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
+ BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
}
static int
bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
{
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
static const struct bwn_b206x_chan *bc = NULL;
+ struct bwn_softc *sc = mac->mac_sc;
uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
tmp[6];
uint16_t old, scale, tmp16;
@@ -11351,7 +11267,7 @@ bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
old = BWN_RF_READ(mac, BWN_B2063_COM15);
BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
- freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
+ freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
freqref = freqxtal * 3;
div = (freqxtal <= 26000000 ? 1 : 2);
@@ -11449,11 +11365,10 @@ bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
static int
bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
{
+ struct bwn_softc *sc = mac->mac_sc;
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
const struct bwn_b206x_chan *bc = NULL;
- uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
+ uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
uint32_t tmp[9];
int i;
@@ -11815,8 +11730,6 @@ static void
bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
@@ -11848,7 +11761,7 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
-
+
};
int i;
@@ -11861,7 +11774,7 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
- if (siba->siba_board_rev >= 0x18) {
+ if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
} else {
@@ -11878,7 +11791,8 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
- if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
+ if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
+ (siba_get_chiprev(sc->sc_dev) == 0)) {
BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
} else {
@@ -11887,7 +11801,8 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
}
for (i = 0; i < N(v3); i++)
BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
- if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
+ if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
+ (siba_get_chiprev(sc->sc_dev) == 0)) {
bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
}
@@ -11912,7 +11827,8 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
- if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
+ if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
+ (siba_get_chiprev(sc->sc_dev) == 0)) {
BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
@@ -11925,8 +11841,6 @@ static void
bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
@@ -12009,23 +11923,23 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
0xff00, plp->plp_rxpwroffset);
- if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) &&
+ if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
- (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) {
- siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28);
- siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1);
+ (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
+ siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
+ siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
if (mac->mac_phy.rev == 0)
BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
0xffcf, 0x0010);
bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
} else {
- siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0);
+ siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
}
tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
- if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV)
+ if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
else
BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
@@ -12033,18 +11947,19 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
0xfff9, (plp->plp_bxarch << 1));
if (mac->mac_phy.rev == 1 &&
- (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) {
+ (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
for (i = 0; i < N(v2); i++)
BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
v2[i].set);
} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
- (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) &&
- (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) {
+ (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
+ ((mac->mac_phy.rev == 0) &&
+ (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
for (i = 0; i < N(v3); i++)
BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
v3[i].set);
} else if (mac->mac_phy.rev == 1 ||
- (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) {
+ (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
for (i = 0; i < N(v4); i++)
BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
v4[i].set);
@@ -12054,15 +11969,15 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
v5[i].set);
}
if (mac->mac_phy.rev == 1 &&
- (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) {
+ (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
}
- if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) &&
- (siba->siba_chipid == 0x5354) &&
- (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) {
+ if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
+ (siba_get_chipid(sc->sc_dev) == 0x5354) &&
+ (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
@@ -12112,8 +12027,6 @@ bwn_phy_lp_b2062_init(struct bwn_mac *mac)
#define CALC_CTL19(freq, div) \
((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
@@ -12151,9 +12064,9 @@ bwn_phy_lp_b2062_init(struct bwn_mac *mac)
else
BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
- KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU,
+ KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
("%s:%d: fail", __func__, __LINE__));
- xtalfreq = siba->siba_cc.scc_pmu.freq * 1000;
+ xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
if (xtalfreq <= 30000000) {
@@ -12217,8 +12130,7 @@ bwn_phy_lp_b2063_init(struct bwn_mac *mac)
static void
bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
{
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
+ struct bwn_softc *sc = mac->mac_sc;
static const struct bwn_wpair v1[] = {
{ BWN_B2063_RX_BB_SP8, 0x0 },
{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
@@ -12236,7 +12148,7 @@ bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
};
- uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
+ uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
int i;
uint8_t tmp;
@@ -12435,12 +12347,11 @@ bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
static void
bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
{
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
+ struct bwn_softc *sc = mac->mac_sc;
BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
DELAY(20);
- if (siba->siba_chipid == 0x5354) {
+ if (siba_get_chipid(sc->sc_dev) == 0x5354) {
BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
} else {
@@ -13146,8 +13057,7 @@ bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
static void
bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
{
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
+ struct bwn_softc *sc = mac->mac_sc;
int i;
static const uint16_t noisescale[] = {
0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
@@ -13355,7 +13265,8 @@ bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
- if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
+ if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
+ (siba_get_chiprev(sc->sc_dev) == 0)) {
bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
gainidx_a0);
bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
@@ -13369,8 +13280,6 @@ bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
static void
bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
{
- struct siba_dev_softc *sd = mac->mac_sd;
- struct siba_softc *siba = sd->sd_bus;
struct bwn_softc *sc = mac->mac_sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
@@ -13975,7 +13884,7 @@ bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
};
if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
- if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA)
+ if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
@@ -13987,8 +13896,8 @@ bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
}
if (mac->mac_phy.rev == 0) {
- if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
- (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
+ if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
+ (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
@@ -13999,8 +13908,8 @@ bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
return;
}
- if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
- (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
+ if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
+ (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
@@ -14312,22 +14221,14 @@ bwn_sysctl_node(struct bwn_softc *sc)
#endif
}
-static void
-bwn_identify(driver_t *driver, device_t parent)
-{
-
- BUS_ADD_CHILD(parent, 0, "bwn", -1);
-}
-
static device_method_t bwn_methods[] = {
/* Device interface */
- DEVMETHOD(device_identify, bwn_identify),
DEVMETHOD(device_probe, bwn_probe),
DEVMETHOD(device_attach, bwn_attach),
DEVMETHOD(device_detach, bwn_detach),
DEVMETHOD(device_suspend, bwn_suspend),
DEVMETHOD(device_resume, bwn_resume),
- { 0,0 }
+ KOBJMETHOD_END
};
static driver_t bwn_driver = {
"bwn",
diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
index 61598c2..461587d 100644
--- a/sys/dev/bwn/if_bwnvar.h
+++ b/sys/dev/bwn/if_bwnvar.h
@@ -65,14 +65,16 @@ struct bwn_mac;
((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
#define BWN_DMA_COOKIE(dr, slot) \
((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
-#define BWN_READ_2(mac, o) (siba_read_2(mac->mac_sd, o))
-#define BWN_READ_4(mac, o) (siba_read_4(mac->mac_sd, o))
-#define BWN_WRITE_2(mac, o, v) (siba_write_2(mac->mac_sd, o, v))
-#define BWN_WRITE_4(mac, o, v) (siba_write_4(mac->mac_sd, o, v))
+#define BWN_READ_2(mac, o) (siba_read_2(mac->mac_sc->sc_dev, o))
+#define BWN_READ_4(mac, o) (siba_read_4(mac->mac_sc->sc_dev, o))
+#define BWN_WRITE_2(mac, o, v) \
+ (siba_write_2(mac->mac_sc->sc_dev, o, v))
+#define BWN_WRITE_4(mac, o, v) \
+ (siba_write_4(mac->mac_sc->sc_dev, o, v))
#define BWN_PIO_TXQOFFSET(mac) \
- ((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x18 : 0)
+ ((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
#define BWN_PIO_RXQOFFSET(mac) \
- ((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x38 : 8)
+ ((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
#define BWN_SEC_NEWAPI(mac) (mac->mac_fw.rev >= 351)
#define BWN_SEC_KEY2FW(mac, idx) \
(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
@@ -141,7 +143,7 @@ struct bwn_mac;
(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB || \
rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
#define BWN_ISOFDMRATE(rate) (!BWN_ISCCKRATE(rate))
-#define BWN_BARRIER(mac, flags) siba_barrier(mac->mac_sd, flags)
+#define BWN_BARRIER(mac, flags) siba_barrier(mac->mac_sc->sc_dev, flags)
#define BWN_DMA_READ(dr, offset) \
(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
#define BWN_DMA_WRITE(dr, offset, value) \
@@ -835,7 +837,6 @@ struct bwn_led {
struct bwn_mac {
struct bwn_softc *mac_sc;
- struct siba_dev_softc *mac_sd;
unsigned mac_status;
#define BWN_MAC_STATUS_UNINIT 0
#define BWN_MAC_STATUS_INITED 1
@@ -882,18 +883,11 @@ struct bwn_mac {
TAILQ_ENTRY(bwn_mac) mac_list;
};
-struct bwn_node {
- struct ieee80211_node bn_node; /* must be the first */
- struct ieee80211_amrr_node bn_amn;
-};
-#define BWN_NODE(ni) ((struct bwn_node *)(ni))
-
/*
* Driver-specific vap state.
*/
struct bwn_vap {
struct ieee80211vap bv_vap; /* base class */
- struct ieee80211_amrr bv_amrr;
int (*bv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
@@ -902,7 +896,6 @@ struct bwn_vap {
struct bwn_softc {
device_t sc_dev;
- struct siba_dev_softc *sc_sd;
struct mtx sc_mtx;
struct ifnet *sc_ifp;
unsigned sc_flags;
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 66a046d..7293bb1 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -1353,7 +1353,7 @@ ciss_init_logical(struct ciss_softc *sc)
/* sanity-check reply */
ndrives = (ntohl(cll->list_size) / sizeof(union ciss_device_address));
- if ((ndrives < 0) || (ndrives >= CISS_MAX_LOGICAL)) {
+ if ((ndrives < 0) || (ndrives > CISS_MAX_LOGICAL)) {
ciss_printf(sc, "adapter claims to report absurd number of logical drives (%d > %d)\n",
ndrives, CISS_MAX_LOGICAL);
error = ENXIO;
@@ -2791,7 +2791,7 @@ ciss_cam_init(struct ciss_softc *sc)
* Allocate a devq. We can reuse this for the masked physical
* devices if we decide to export these as well.
*/
- if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests)) == NULL) {
+ if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests - 2)) == NULL) {
ciss_printf(sc, "can't allocate CAM SIM queue\n");
return(ENOMEM);
}
@@ -3065,7 +3065,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
*/
if ((error = ciss_get_request(sc, &cr)) != 0) {
xpt_freeze_simq(sim, 1);
- csio->ccb_h.status |= CAM_RELEASE_SIMQ;
+ sc->ciss_flags |= CISS_FLAG_BUSY;
csio->ccb_h.status |= CAM_REQUEUE_REQ;
return(error);
}
@@ -3275,6 +3275,13 @@ ciss_cam_complete(struct ciss_request *cr)
ciss_cam_complete_fixup(sc, csio);
ciss_release_request(cr);
+ if (sc->ciss_flags & CISS_FLAG_BUSY) {
+ sc->ciss_flags &= ~CISS_FLAG_BUSY;
+ if (csio->ccb_h.status & CAM_RELEASE_SIMQ)
+ xpt_release_simq(xpt_path_sim(csio->ccb_h.path), 0);
+ else
+ csio->ccb_h.status |= CAM_RELEASE_SIMQ;
+ }
xpt_done((union ccb *)csio);
}
diff --git a/sys/dev/ciss/cissvar.h b/sys/dev/ciss/cissvar.h
index 3bad2b3..07d72b7 100644
--- a/sys/dev/ciss/cissvar.h
+++ b/sys/dev/ciss/cissvar.h
@@ -41,7 +41,7 @@ typedef STAILQ_HEAD(, ciss_request) cr_qhead_t;
* commands an adapter may claim to support. Cap it at a reasonable
* value.
*/
-#define CISS_MAX_REQUESTS 256
+#define CISS_MAX_REQUESTS 1024
/*
* Maximum number of logical drives we support.
@@ -251,6 +251,7 @@ struct ciss_softc
#define CISS_FLAG_CONTROL_OPEN (1<<1) /* control device is open */
#define CISS_FLAG_ABORTING (1<<2) /* driver is going away */
#define CISS_FLAG_RUNNING (1<<3) /* driver is running (interrupts usable) */
+#define CISS_FLAG_BUSY (1<<4) /* no free commands */
#define CISS_FLAG_FAKE_SYNCH (1<<16) /* needs SYNCHRONISE_CACHE faked */
#define CISS_FLAG_BMIC_ABORT (1<<17) /* use BMIC command to abort Notify on Event */
diff --git a/sys/dev/cxgb/common/cxgb_ael1002.c b/sys/dev/cxgb/common/cxgb_ael1002.c
index ec5ffe7..fc2e140 100644
--- a/sys/dev/cxgb/common/cxgb_ael1002.c
+++ b/sys/dev/cxgb/common/cxgb_ael1002.c
@@ -446,7 +446,7 @@ static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
return v;
if (v == 0x1)
- return phy_modtype_twinax;
+ goto twinax;
if (v == 0x10)
return phy_modtype_sr;
if (v == 0x20)
@@ -454,6 +454,17 @@ static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
if (v == 0x40)
return phy_modtype_lrm;
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 8);
+ if (v < 0)
+ return v;
+ if (v == 4) {
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 60);
+ if (v < 0)
+ return v;
+ if (v & 0x1)
+ goto twinax;
+ }
+
v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
if (v < 0)
return v;
@@ -465,6 +476,7 @@ static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
return v;
if (v & 0x80) {
+twinax:
v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
if (v < 0)
return v;
@@ -1435,395 +1447,439 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
0xd803, 0x40aa,
0xd804, 0x401c,
0xd805, 0x401e,
- 0xd806, 0x2ff4,
- 0xd807, 0x3dc4,
- 0xd808, 0x2035,
- 0xd809, 0x3035,
- 0xd80a, 0x6524,
- 0xd80b, 0x2cb2,
- 0xd80c, 0x3012,
- 0xd80d, 0x1002,
- 0xd80e, 0x26e2,
- 0xd80f, 0x3022,
- 0xd810, 0x1002,
- 0xd811, 0x27d2,
- 0xd812, 0x3022,
+ 0xd806, 0x20c5,
+ 0xd807, 0x3c05,
+ 0xd808, 0x6536,
+ 0xd809, 0x2fe4,
+ 0xd80a, 0x3dc4,
+ 0xd80b, 0x6624,
+ 0xd80c, 0x2ff4,
+ 0xd80d, 0x3dc4,
+ 0xd80e, 0x2035,
+ 0xd80f, 0x30a5,
+ 0xd810, 0x6524,
+ 0xd811, 0x2ca2,
+ 0xd812, 0x3012,
0xd813, 0x1002,
- 0xd814, 0x2822,
- 0xd815, 0x3012,
+ 0xd814, 0x27e2,
+ 0xd815, 0x3022,
0xd816, 0x1002,
- 0xd817, 0x2492,
+ 0xd817, 0x28d2,
0xd818, 0x3022,
0xd819, 0x1002,
- 0xd81a, 0x2772,
+ 0xd81a, 0x2892,
0xd81b, 0x3012,
0xd81c, 0x1002,
- 0xd81d, 0x23d2,
+ 0xd81d, 0x24e2,
0xd81e, 0x3022,
0xd81f, 0x1002,
- 0xd820, 0x22cd,
- 0xd821, 0x301d,
- 0xd822, 0x27f2,
- 0xd823, 0x3022,
- 0xd824, 0x1002,
- 0xd825, 0x5553,
- 0xd826, 0x0307,
- 0xd827, 0x2522,
- 0xd828, 0x3022,
- 0xd829, 0x1002,
- 0xd82a, 0x2142,
- 0xd82b, 0x3012,
- 0xd82c, 0x1002,
- 0xd82d, 0x4016,
- 0xd82e, 0x5e63,
- 0xd82f, 0x0344,
- 0xd830, 0x2142,
+ 0xd820, 0x27e2,
+ 0xd821, 0x3012,
+ 0xd822, 0x1002,
+ 0xd823, 0x2422,
+ 0xd824, 0x3022,
+ 0xd825, 0x1002,
+ 0xd826, 0x22cd,
+ 0xd827, 0x301d,
+ 0xd828, 0x28f2,
+ 0xd829, 0x3022,
+ 0xd82a, 0x1002,
+ 0xd82b, 0x5553,
+ 0xd82c, 0x0307,
+ 0xd82d, 0x2572,
+ 0xd82e, 0x3022,
+ 0xd82f, 0x1002,
+ 0xd830, 0x21a2,
0xd831, 0x3012,
0xd832, 0x1002,
- 0xd833, 0x400e,
- 0xd834, 0x2522,
- 0xd835, 0x3022,
- 0xd836, 0x1002,
- 0xd837, 0x2b52,
- 0xd838, 0x3012,
- 0xd839, 0x1002,
- 0xd83a, 0x2742,
+ 0xd833, 0x4016,
+ 0xd834, 0x5e63,
+ 0xd835, 0x0344,
+ 0xd836, 0x21a2,
+ 0xd837, 0x3012,
+ 0xd838, 0x1002,
+ 0xd839, 0x400e,
+ 0xd83a, 0x2572,
0xd83b, 0x3022,
0xd83c, 0x1002,
- 0xd83d, 0x25e2,
- 0xd83e, 0x3022,
+ 0xd83d, 0x2b22,
+ 0xd83e, 0x3012,
0xd83f, 0x1002,
- 0xd840, 0x2fa4,
- 0xd841, 0x3dc4,
- 0xd842, 0x6624,
- 0xd843, 0x414b,
- 0xd844, 0x56b3,
- 0xd845, 0x03c6,
- 0xd846, 0x866b,
- 0xd847, 0x400c,
- 0xd848, 0x2712,
- 0xd849, 0x3012,
- 0xd84a, 0x1002,
- 0xd84b, 0x2c4b,
- 0xd84c, 0x309b,
- 0xd84d, 0x56b3,
- 0xd84e, 0x03c3,
- 0xd84f, 0x866b,
- 0xd850, 0x400c,
- 0xd851, 0x2272,
- 0xd852, 0x3022,
- 0xd853, 0x1002,
- 0xd854, 0x2742,
- 0xd855, 0x3022,
- 0xd856, 0x1002,
- 0xd857, 0x25e2,
- 0xd858, 0x3022,
- 0xd859, 0x1002,
- 0xd85a, 0x2fb4,
- 0xd85b, 0x3dc4,
- 0xd85c, 0x6624,
- 0xd85d, 0x56b3,
- 0xd85e, 0x03c3,
- 0xd85f, 0x866b,
- 0xd860, 0x401c,
- 0xd861, 0x2c45,
- 0xd862, 0x3095,
- 0xd863, 0x5b53,
- 0xd864, 0x2372,
- 0xd865, 0x3012,
- 0xd866, 0x13c2,
- 0xd867, 0x5cc3,
- 0xd868, 0x2712,
- 0xd869, 0x3012,
- 0xd86a, 0x1312,
- 0xd86b, 0x2b52,
+ 0xd840, 0x2842,
+ 0xd841, 0x3022,
+ 0xd842, 0x1002,
+ 0xd843, 0x26e2,
+ 0xd844, 0x3022,
+ 0xd845, 0x1002,
+ 0xd846, 0x2fa4,
+ 0xd847, 0x3dc4,
+ 0xd848, 0x6624,
+ 0xd849, 0x2e8b,
+ 0xd84a, 0x303b,
+ 0xd84b, 0x56b3,
+ 0xd84c, 0x03c6,
+ 0xd84d, 0x866b,
+ 0xd84e, 0x400c,
+ 0xd84f, 0x2782,
+ 0xd850, 0x3012,
+ 0xd851, 0x1002,
+ 0xd852, 0x2c4b,
+ 0xd853, 0x309b,
+ 0xd854, 0x56b3,
+ 0xd855, 0x03c3,
+ 0xd856, 0x866b,
+ 0xd857, 0x400c,
+ 0xd858, 0x22a2,
+ 0xd859, 0x3022,
+ 0xd85a, 0x1002,
+ 0xd85b, 0x2842,
+ 0xd85c, 0x3022,
+ 0xd85d, 0x1002,
+ 0xd85e, 0x26e2,
+ 0xd85f, 0x3022,
+ 0xd860, 0x1002,
+ 0xd861, 0x2fb4,
+ 0xd862, 0x3dc4,
+ 0xd863, 0x6624,
+ 0xd864, 0x56b3,
+ 0xd865, 0x03c3,
+ 0xd866, 0x866b,
+ 0xd867, 0x401c,
+ 0xd868, 0x2c45,
+ 0xd869, 0x3095,
+ 0xd86a, 0x5b53,
+ 0xd86b, 0x23d2,
0xd86c, 0x3012,
- 0xd86d, 0x1002,
- 0xd86e, 0x2742,
- 0xd86f, 0x3022,
- 0xd870, 0x1002,
- 0xd871, 0x2582,
- 0xd872, 0x3022,
- 0xd873, 0x1002,
- 0xd874, 0x2142,
- 0xd875, 0x3012,
- 0xd876, 0x1002,
- 0xd877, 0x628f,
- 0xd878, 0x2985,
- 0xd879, 0x33a5,
- 0xd87a, 0x25e2,
- 0xd87b, 0x3022,
- 0xd87c, 0x1002,
- 0xd87d, 0x5653,
- 0xd87e, 0x03d2,
- 0xd87f, 0x401e,
- 0xd880, 0x6f72,
- 0xd881, 0x1002,
- 0xd882, 0x628f,
- 0xd883, 0x2304,
- 0xd884, 0x3c84,
- 0xd885, 0x6436,
- 0xd886, 0xdff4,
- 0xd887, 0x6436,
- 0xd888, 0x2ff5,
- 0xd889, 0x3005,
- 0xd88a, 0x8656,
- 0xd88b, 0xdfba,
- 0xd88c, 0x56a3,
- 0xd88d, 0xd05a,
- 0xd88e, 0x2972,
- 0xd88f, 0x3012,
- 0xd890, 0x1392,
- 0xd891, 0xd05a,
- 0xd892, 0x56a3,
- 0xd893, 0xdfba,
- 0xd894, 0x0383,
- 0xd895, 0x6f72,
- 0xd896, 0x1002,
- 0xd897, 0x2b45,
- 0xd898, 0x3005,
- 0xd899, 0x4178,
- 0xd89a, 0x5653,
- 0xd89b, 0x0384,
- 0xd89c, 0x2a62,
- 0xd89d, 0x3012,
- 0xd89e, 0x1002,
- 0xd89f, 0x2f05,
- 0xd8a0, 0x3005,
- 0xd8a1, 0x41c8,
- 0xd8a2, 0x5653,
- 0xd8a3, 0x0382,
- 0xd8a4, 0x0002,
- 0xd8a5, 0x4218,
- 0xd8a6, 0x2474,
- 0xd8a7, 0x3c84,
- 0xd8a8, 0x6437,
- 0xd8a9, 0xdff4,
- 0xd8aa, 0x6437,
- 0xd8ab, 0x2ff5,
- 0xd8ac, 0x3c05,
- 0xd8ad, 0x8757,
- 0xd8ae, 0xb888,
- 0xd8af, 0x9787,
- 0xd8b0, 0xdff4,
- 0xd8b1, 0x6724,
- 0xd8b2, 0x866a,
- 0xd8b3, 0x6f72,
- 0xd8b4, 0x1002,
- 0xd8b5, 0x2641,
- 0xd8b6, 0x3021,
- 0xd8b7, 0x1001,
- 0xd8b8, 0xc620,
- 0xd8b9, 0x0000,
- 0xd8ba, 0xc621,
- 0xd8bb, 0x0000,
- 0xd8bc, 0xc622,
- 0xd8bd, 0x00ce,
- 0xd8be, 0xc623,
- 0xd8bf, 0x007f,
- 0xd8c0, 0xc624,
- 0xd8c1, 0x0032,
- 0xd8c2, 0xc625,
- 0xd8c3, 0x0000,
- 0xd8c4, 0xc627,
- 0xd8c5, 0x0000,
- 0xd8c6, 0xc628,
- 0xd8c7, 0x0000,
- 0xd8c8, 0xc62c,
+ 0xd86d, 0x13c2,
+ 0xd86e, 0x5cc3,
+ 0xd86f, 0x2782,
+ 0xd870, 0x3012,
+ 0xd871, 0x1312,
+ 0xd872, 0x2b22,
+ 0xd873, 0x3012,
+ 0xd874, 0x1002,
+ 0xd875, 0x2842,
+ 0xd876, 0x3022,
+ 0xd877, 0x1002,
+ 0xd878, 0x2622,
+ 0xd879, 0x3022,
+ 0xd87a, 0x1002,
+ 0xd87b, 0x21a2,
+ 0xd87c, 0x3012,
+ 0xd87d, 0x1002,
+ 0xd87e, 0x628f,
+ 0xd87f, 0x2985,
+ 0xd880, 0x33a5,
+ 0xd881, 0x26e2,
+ 0xd882, 0x3022,
+ 0xd883, 0x1002,
+ 0xd884, 0x5653,
+ 0xd885, 0x03d2,
+ 0xd886, 0x401e,
+ 0xd887, 0x6f72,
+ 0xd888, 0x1002,
+ 0xd889, 0x628f,
+ 0xd88a, 0x2304,
+ 0xd88b, 0x3c84,
+ 0xd88c, 0x6436,
+ 0xd88d, 0xdff4,
+ 0xd88e, 0x6436,
+ 0xd88f, 0x2ff5,
+ 0xd890, 0x3005,
+ 0xd891, 0x8656,
+ 0xd892, 0xdfba,
+ 0xd893, 0x56a3,
+ 0xd894, 0xd05a,
+ 0xd895, 0x29e2,
+ 0xd896, 0x3012,
+ 0xd897, 0x1392,
+ 0xd898, 0xd05a,
+ 0xd899, 0x56a3,
+ 0xd89a, 0xdfba,
+ 0xd89b, 0x0383,
+ 0xd89c, 0x6f72,
+ 0xd89d, 0x1002,
+ 0xd89e, 0x2a64,
+ 0xd89f, 0x3014,
+ 0xd8a0, 0x2005,
+ 0xd8a1, 0x3d75,
+ 0xd8a2, 0xc451,
+ 0xd8a3, 0x29a2,
+ 0xd8a4, 0x3022,
+ 0xd8a5, 0x1002,
+ 0xd8a6, 0x178c,
+ 0xd8a7, 0x1898,
+ 0xd8a8, 0x19a4,
+ 0xd8a9, 0x1ab0,
+ 0xd8aa, 0x1bbc,
+ 0xd8ab, 0x1cc8,
+ 0xd8ac, 0x1dd3,
+ 0xd8ad, 0x1ede,
+ 0xd8ae, 0x1fe9,
+ 0xd8af, 0x20f4,
+ 0xd8b0, 0x21ff,
+ 0xd8b1, 0x0000,
+ 0xd8b2, 0x2741,
+ 0xd8b3, 0x3021,
+ 0xd8b4, 0x1001,
+ 0xd8b5, 0xc620,
+ 0xd8b6, 0x0000,
+ 0xd8b7, 0xc621,
+ 0xd8b8, 0x0000,
+ 0xd8b9, 0xc622,
+ 0xd8ba, 0x00e2,
+ 0xd8bb, 0xc623,
+ 0xd8bc, 0x007f,
+ 0xd8bd, 0xc624,
+ 0xd8be, 0x00ce,
+ 0xd8bf, 0xc625,
+ 0xd8c0, 0x0000,
+ 0xd8c1, 0xc627,
+ 0xd8c2, 0x0000,
+ 0xd8c3, 0xc628,
+ 0xd8c4, 0x0000,
+ 0xd8c5, 0xc90a,
+ 0xd8c6, 0x3a7c,
+ 0xd8c7, 0xc62c,
+ 0xd8c8, 0x0000,
0xd8c9, 0x0000,
- 0xd8ca, 0x0000,
- 0xd8cb, 0x2641,
- 0xd8cc, 0x3021,
- 0xd8cd, 0x1001,
- 0xd8ce, 0xc502,
- 0xd8cf, 0x53ac,
- 0xd8d0, 0xc503,
- 0xd8d1, 0x2cd3,
- 0xd8d2, 0xc600,
- 0xd8d3, 0x2a6e,
- 0xd8d4, 0xc601,
- 0xd8d5, 0x2a2c,
- 0xd8d6, 0xc605,
- 0xd8d7, 0x5557,
- 0xd8d8, 0xc60c,
- 0xd8d9, 0x5400,
- 0xd8da, 0xc710,
- 0xd8db, 0x0700,
- 0xd8dc, 0xc711,
- 0xd8dd, 0x0f06,
- 0xd8de, 0xc718,
- 0xd8df, 0x0700,
- 0xd8e0, 0xc719,
- 0xd8e1, 0x0f06,
- 0xd8e2, 0xc720,
- 0xd8e3, 0x4700,
- 0xd8e4, 0xc721,
- 0xd8e5, 0x0f06,
- 0xd8e6, 0xc728,
- 0xd8e7, 0x0700,
- 0xd8e8, 0xc729,
- 0xd8e9, 0x1207,
- 0xd8ea, 0xc801,
- 0xd8eb, 0x7f50,
- 0xd8ec, 0xc802,
- 0xd8ed, 0x7760,
- 0xd8ee, 0xc803,
- 0xd8ef, 0x7fce,
- 0xd8f0, 0xc804,
- 0xd8f1, 0x520e,
- 0xd8f2, 0xc805,
- 0xd8f3, 0x5c11,
- 0xd8f4, 0xc806,
- 0xd8f5, 0x3c51,
- 0xd8f6, 0xc807,
- 0xd8f7, 0x4061,
- 0xd8f8, 0xc808,
- 0xd8f9, 0x49c1,
- 0xd8fa, 0xc809,
- 0xd8fb, 0x3840,
- 0xd8fc, 0xc80a,
- 0xd8fd, 0x0000,
- 0xd8fe, 0xc821,
- 0xd8ff, 0x0002,
- 0xd900, 0xc822,
- 0xd901, 0x0046,
- 0xd902, 0xc844,
- 0xd903, 0x182f,
- 0xd904, 0xc013,
- 0xd905, 0xf341,
- 0xd906, 0xc084,
- 0xd907, 0x0030,
- 0xd908, 0xc904,
- 0xd909, 0x1401,
- 0xd90a, 0xcb0c,
- 0xd90b, 0x0004,
- 0xd90c, 0xcb0e,
- 0xd90d, 0xa00a,
- 0xd90e, 0xcb0f,
- 0xd90f, 0xc0c0,
- 0xd910, 0xcb10,
- 0xd911, 0xc0c0,
- 0xd912, 0xcb11,
- 0xd913, 0x00a0,
- 0xd914, 0xcb12,
- 0xd915, 0x0007,
- 0xd916, 0xc241,
- 0xd917, 0xa000,
- 0xd918, 0xc243,
- 0xd919, 0x7fe0,
- 0xd91a, 0xc604,
- 0xd91b, 0x000e,
- 0xd91c, 0xc609,
- 0xd91d, 0x00f5,
- 0xd91e, 0xc611,
- 0xd91f, 0x000e,
- 0xd920, 0xc660,
- 0xd921, 0x9600,
- 0xd922, 0xc687,
- 0xd923, 0x0004,
- 0xd924, 0xc60a,
- 0xd925, 0x04f5,
- 0xd926, 0x0000,
- 0xd927, 0x2641,
- 0xd928, 0x3021,
- 0xd929, 0x1001,
- 0xd92a, 0xc620,
- 0xd92b, 0x14e5,
- 0xd92c, 0xc621,
- 0xd92d, 0xc53d,
- 0xd92e, 0xc622,
- 0xd92f, 0x3cbe,
- 0xd930, 0xc623,
- 0xd931, 0x4452,
- 0xd932, 0xc624,
- 0xd933, 0xc5c5,
- 0xd934, 0xc625,
- 0xd935, 0xe01e,
- 0xd936, 0xc627,
- 0xd937, 0x0000,
- 0xd938, 0xc628,
- 0xd939, 0x0000,
- 0xd93a, 0xc62c,
- 0xd93b, 0x0000,
+ 0xd8ca, 0x2741,
+ 0xd8cb, 0x3021,
+ 0xd8cc, 0x1001,
+ 0xd8cd, 0xc502,
+ 0xd8ce, 0x53ac,
+ 0xd8cf, 0xc503,
+ 0xd8d0, 0x2cd3,
+ 0xd8d1, 0xc600,
+ 0xd8d2, 0x2a6e,
+ 0xd8d3, 0xc601,
+ 0xd8d4, 0x2a2c,
+ 0xd8d5, 0xc605,
+ 0xd8d6, 0x5557,
+ 0xd8d7, 0xc60c,
+ 0xd8d8, 0x5400,
+ 0xd8d9, 0xc710,
+ 0xd8da, 0x0700,
+ 0xd8db, 0xc711,
+ 0xd8dc, 0x0f06,
+ 0xd8dd, 0xc718,
+ 0xd8de, 0x700,
+ 0xd8df, 0xc719,
+ 0xd8e0, 0x0f06,
+ 0xd8e1, 0xc720,
+ 0xd8e2, 0x4700,
+ 0xd8e3, 0xc721,
+ 0xd8e4, 0x0f06,
+ 0xd8e5, 0xc728,
+ 0xd8e6, 0x0700,
+ 0xd8e7, 0xc729,
+ 0xd8e8, 0x1207,
+ 0xd8e9, 0xc801,
+ 0xd8ea, 0x7f50,
+ 0xd8eb, 0xc802,
+ 0xd8ec, 0x7760,
+ 0xd8ed, 0xc803,
+ 0xd8ee, 0x7fce,
+ 0xd8ef, 0xc804,
+ 0xd8f0, 0x520e,
+ 0xd8f1, 0xc805,
+ 0xd8f2, 0x5c11,
+ 0xd8f3, 0xc806,
+ 0xd8f4, 0x3c51,
+ 0xd8f5, 0xc807,
+ 0xd8f6, 0x4061,
+ 0xd8f7, 0xc808,
+ 0xd8f8, 0x49c1,
+ 0xd8f9, 0xc809,
+ 0xd8fa, 0x3840,
+ 0xd8fb, 0xc80a,
+ 0xd8fc, 0x0000,
+ 0xd8fd, 0xc821,
+ 0xd8fe, 0x0002,
+ 0xd8ff, 0xc822,
+ 0xd900, 0x0046,
+ 0xd901, 0xc844,
+ 0xd902, 0x182f,
+ 0xd903, 0xc849,
+ 0xd904, 0x0400,
+ 0xd905, 0xc84a,
+ 0xd906, 0x0002,
+ 0xd907, 0xc013,
+ 0xd908, 0xf341,
+ 0xd909, 0xc084,
+ 0xd90a, 0x0030,
+ 0xd90b, 0xc904,
+ 0xd90c, 0x1401,
+ 0xd90d, 0xcb0c,
+ 0xd90e, 0x0004,
+ 0xd90f, 0xcb0e,
+ 0xd910, 0xa00a,
+ 0xd911, 0xcb0f,
+ 0xd912, 0xc0c0,
+ 0xd913, 0xcb10,
+ 0xd914, 0xc0c0,
+ 0xd915, 0xcb11,
+ 0xd916, 0x00a0,
+ 0xd917, 0xcb12,
+ 0xd918, 0x0007,
+ 0xd919, 0xc241,
+ 0xd91a, 0xa000,
+ 0xd91b, 0xc243,
+ 0xd91c, 0x7fe0,
+ 0xd91d, 0xc604,
+ 0xd91e, 0x000e,
+ 0xd91f, 0xc609,
+ 0xd920, 0x00f5,
+ 0xd921, 0xc611,
+ 0xd922, 0x000e,
+ 0xd923, 0xc660,
+ 0xd924, 0x9600,
+ 0xd925, 0xc687,
+ 0xd926, 0x0004,
+ 0xd927, 0xc60a,
+ 0xd928, 0x04f5,
+ 0xd929, 0x0000,
+ 0xd92a, 0x2741,
+ 0xd92b, 0x3021,
+ 0xd92c, 0x1001,
+ 0xd92d, 0xc620,
+ 0xd92e, 0x14e5,
+ 0xd92f, 0xc621,
+ 0xd930, 0xc53d,
+ 0xd931, 0xc622,
+ 0xd932, 0x3cbe,
+ 0xd933, 0xc623,
+ 0xd934, 0x4452,
+ 0xd935, 0xc624,
+ 0xd936, 0xc5c5,
+ 0xd937, 0xc625,
+ 0xd938, 0xe01e,
+ 0xd939, 0xc627,
+ 0xd93a, 0x0000,
+ 0xd93b, 0xc628,
0xd93c, 0x0000,
- 0xd93d, 0x2b84,
- 0xd93e, 0x3c74,
- 0xd93f, 0x6435,
- 0xd940, 0xdff4,
- 0xd941, 0x6435,
- 0xd942, 0x2806,
- 0xd943, 0x3006,
- 0xd944, 0x8565,
- 0xd945, 0x2b24,
- 0xd946, 0x3c24,
- 0xd947, 0x6436,
- 0xd948, 0x1002,
- 0xd949, 0x2b24,
- 0xd94a, 0x3c24,
- 0xd94b, 0x6436,
- 0xd94c, 0x4045,
- 0xd94d, 0x8656,
- 0xd94e, 0x5663,
- 0xd94f, 0x0302,
- 0xd950, 0x401e,
- 0xd951, 0x1002,
- 0xd952, 0x2807,
- 0xd953, 0x31a7,
- 0xd954, 0x20c4,
- 0xd955, 0x3c24,
- 0xd956, 0x6724,
- 0xd957, 0x1002,
- 0xd958, 0x2807,
- 0xd959, 0x3187,
- 0xd95a, 0x20c4,
- 0xd95b, 0x3c24,
- 0xd95c, 0x6724,
- 0xd95d, 0x1002,
- 0xd95e, 0x24f4,
- 0xd95f, 0x3c64,
- 0xd960, 0x6436,
- 0xd961, 0xdff4,
- 0xd962, 0x6436,
- 0xd963, 0x1002,
- 0xd964, 0x2006,
- 0xd965, 0x3d76,
- 0xd966, 0xc161,
- 0xd967, 0x6134,
- 0xd968, 0x6135,
- 0xd969, 0x5443,
- 0xd96a, 0x0303,
- 0xd96b, 0x6524,
- 0xd96c, 0x00fb,
+ 0xd93d, 0xc62c,
+ 0xd93e, 0x0000,
+ 0xd93f, 0xc90a,
+ 0xd940, 0x3a7c,
+ 0xd941, 0x0000,
+ 0xd942, 0x2b84,
+ 0xd943, 0x3c74,
+ 0xd944, 0x6435,
+ 0xd945, 0xdff4,
+ 0xd946, 0x6435,
+ 0xd947, 0x2806,
+ 0xd948, 0x3006,
+ 0xd949, 0x8565,
+ 0xd94a, 0x2b24,
+ 0xd94b, 0x3c24,
+ 0xd94c, 0x6436,
+ 0xd94d, 0x1002,
+ 0xd94e, 0x2b24,
+ 0xd94f, 0x3c24,
+ 0xd950, 0x6436,
+ 0xd951, 0x4045,
+ 0xd952, 0x8656,
+ 0xd953, 0x5663,
+ 0xd954, 0x0302,
+ 0xd955, 0x401e,
+ 0xd956, 0x1002,
+ 0xd957, 0x2807,
+ 0xd958, 0x31a7,
+ 0xd959, 0x20c4,
+ 0xd95a, 0x3c24,
+ 0xd95b, 0x6724,
+ 0xd95c, 0x2ff7,
+ 0xd95d, 0x30f7,
+ 0xd95e, 0x20c4,
+ 0xd95f, 0x3c04,
+ 0xd960, 0x6724,
+ 0xd961, 0x1002,
+ 0xd962, 0x2807,
+ 0xd963, 0x3187,
+ 0xd964, 0x20c4,
+ 0xd965, 0x3c24,
+ 0xd966, 0x6724,
+ 0xd967, 0x2fe4,
+ 0xd968, 0x3dc4,
+ 0xd969, 0x6437,
+ 0xd96a, 0x20c4,
+ 0xd96b, 0x3c04,
+ 0xd96c, 0x6724,
0xd96d, 0x1002,
- 0xd96e, 0x20d4,
- 0xd96f, 0x3c24,
- 0xd970, 0x2025,
- 0xd971, 0x3005,
- 0xd972, 0x6524,
+ 0xd96e, 0x24f4,
+ 0xd96f, 0x3c64,
+ 0xd970, 0x6436,
+ 0xd971, 0xdff4,
+ 0xd972, 0x6436,
0xd973, 0x1002,
- 0xd974, 0xd019,
- 0xd975, 0x2104,
- 0xd976, 0x3c24,
- 0xd977, 0x2105,
- 0xd978, 0x3805,
- 0xd979, 0x6524,
- 0xd97a, 0xdff4,
- 0xd97b, 0x4005,
- 0xd97c, 0x6524,
- 0xd97d, 0x2e8d,
- 0xd97e, 0x303d,
- 0xd97f, 0x2408,
- 0xd980, 0x35d8,
- 0xd981, 0x5dd3,
- 0xd982, 0x0307,
- 0xd983, 0x8887,
- 0xd984, 0x63a7,
- 0xd985, 0x8887,
- 0xd986, 0x63a7,
- 0xd987, 0xdffd,
- 0xd988, 0x00f9,
- 0xd989, 0x1002,
- 0xd98a, 0x0000,
+ 0xd974, 0x2006,
+ 0xd975, 0x3d76,
+ 0xd976, 0xc161,
+ 0xd977, 0x6134,
+ 0xd978, 0x6135,
+ 0xd979, 0x5443,
+ 0xd97a, 0x0303,
+ 0xd97b, 0x6524,
+ 0xd97c, 0x00fb,
+ 0xd97d, 0x1002,
+ 0xd97e, 0x20d4,
+ 0xd97f, 0x3c24,
+ 0xd980, 0x2025,
+ 0xd981, 0x3005,
+ 0xd982, 0x6524,
+ 0xd983, 0x1002,
+ 0xd984, 0xd019,
+ 0xd985, 0x2104,
+ 0xd986, 0x3c24,
+ 0xd987, 0x2105,
+ 0xd988, 0x3805,
+ 0xd989, 0x6524,
+ 0xd98a, 0xdff4,
+ 0xd98b, 0x4005,
+ 0xd98c, 0x6524,
+ 0xd98d, 0x2e8d,
+ 0xd98e, 0x303d,
+ 0xd98f, 0x2408,
+ 0xd990, 0x35d8,
+ 0xd991, 0x5dd3,
+ 0xd992, 0x0307,
+ 0xd993, 0x8887,
+ 0xd994, 0x63a7,
+ 0xd995, 0x8887,
+ 0xd996, 0x63a7,
+ 0xd997, 0xdffd,
+ 0xd998, 0x00f9,
+ 0xd999, 0x1002,
+ 0xd99a, 0x866a,
+ 0xd99b, 0x6138,
+ 0xd99c, 0x5883,
+ 0xd99d, 0x2aa2,
+ 0xd99e, 0x3022,
+ 0xd99f, 0x1302,
+ 0xd9a0, 0x2ff7,
+ 0xd9a1, 0x3007,
+ 0xd9a2, 0x8785,
+ 0xd9a3, 0xb887,
+ 0xd9a4, 0x8786,
+ 0xd9a5, 0xb8c6,
+ 0xd9a6, 0x5a53,
+ 0xd9a7, 0x29b2,
+ 0xd9a8, 0x3022,
+ 0xd9a9, 0x13c2,
+ 0xd9aa, 0x2474,
+ 0xd9ab, 0x3c84,
+ 0xd9ac, 0x64d7,
+ 0xd9ad, 0x64d7,
+ 0xd9ae, 0x2ff5,
+ 0xd9af, 0x3c05,
+ 0xd9b0, 0x8757,
+ 0xd9b1, 0xb886,
+ 0xd9b2, 0x9767,
+ 0xd9b3, 0x67c4,
+ 0xd9b4, 0x6f72,
+ 0xd9b5, 0x1002,
+ 0xd9b6, 0x0000,
};
int i, err;
@@ -1944,10 +2000,14 @@ static struct reg_val ael2020_reset_regs[] = {
{ MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 },
+ { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0x0100 },
+ { MDIO_DEV_PMA_PMD, 0xca22, 0xffff, 0x0100 },
+ { MDIO_DEV_PMA_PMD, 0xca42, 0xffff, 0x0100 },
{ MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 },
{ MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 },
{ MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 },
+ { MDIO_DEV_PMA_PMD, 0xc20d, 0xffff, 0x0002 },
/* end */
{ 0, 0, 0, 0 }
};
@@ -1975,6 +2035,7 @@ static int ael2020_reset(struct cphy *phy, int wait)
err = set_phy_regs(phy, ael2020_reset_regs);
if (err)
return err;
+ msleep(100);
/* determine module type and perform appropriate initialization */
err = ael2020_get_module_type(phy, 0);
@@ -2079,6 +2140,8 @@ int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr,
err = set_phy_regs(phy, ael2020_reset_regs);
if (err)
return err;
+ msleep(100);
+
err = ael2020_get_module_type(phy, 0);
if (err >= 0)
phy->modtype = err;
diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h
index 1d325ae..d523a1a 100644
--- a/sys/dev/cxgb/common/cxgb_common.h
+++ b/sys/dev/cxgb/common/cxgb_common.h
@@ -314,6 +314,7 @@ struct qset_params { /* SGE queue set parameters */
unsigned int rspq_size; /* # of entries in response queue */
unsigned int fl_size; /* # of entries in regular free list */
unsigned int jumbo_size; /* # of entries in jumbo free list */
+ unsigned int jumbo_buf_size; /* buffer size of jumbo entry */
unsigned int txq_size[SGE_TXQ_PER_SET]; /* Tx queue sizes */
unsigned int cong_thres; /* FL congestion threshold */
unsigned int vector; /* Interrupt (line or vector) number */
diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c
index 188e467..4c28a04 100644
--- a/sys/dev/cxgb/common/cxgb_t3_hw.c
+++ b/sys/dev/cxgb/common/cxgb_t3_hw.c
@@ -4467,8 +4467,6 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
if (reset && t3_reset_adapter(adapter))
return -1;
- t3_sge_prep(adapter, &adapter->params.sge);
-
if (adapter->params.vpd.mclk) {
struct tp_params *p = &adapter->params.tp;
@@ -4497,6 +4495,8 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
t3_mc7_size(&adapter->pmtx) &&
t3_mc7_size(&adapter->cm);
+ t3_sge_prep(adapter, &adapter->params.sge);
+
if (is_offload(adapter)) {
adapter->params.mc5.nservers = DEFAULT_NSERVERS;
/* PR 6487. TOE and filtering are mutually exclusive */
diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h
index d4a66d6..d1f5ef6 100644
--- a/sys/dev/cxgb/cxgb_adapter.h
+++ b/sys/dev/cxgb/cxgb_adapter.h
@@ -139,8 +139,10 @@ enum {
#define FL_Q_SIZE 4096
#define JUMBO_Q_SIZE 1024
-#define RSPQ_Q_SIZE 1024
+#define RSPQ_Q_SIZE 2048
#define TX_ETH_Q_SIZE 1024
+#define TX_OFLD_Q_SIZE 1024
+#define TX_CTRL_Q_SIZE 256
enum { TXQ_ETH = 0,
TXQ_OFLD = 1,
@@ -177,6 +179,7 @@ struct sge_rspq {
uint32_t offload_bundles;
uint32_t pure_rsps;
uint32_t unhandled_irqs;
+ uint32_t starved;
bus_addr_t phys_addr;
bus_dma_tag_t desc_tag;
@@ -248,7 +251,6 @@ struct sge_txq {
struct callout txq_timer;
struct callout txq_watchdog;
uint64_t txq_coalesced;
- uint32_t txq_drops;
uint32_t txq_skipped;
uint32_t txq_enqueued;
uint32_t txq_dump_start;
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index 5493b75d..a47284f 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -218,9 +218,9 @@ TUNABLE_INT("hw.cxgb.force_fw_update", &force_fw_update);
SYSCTL_UINT(_hw_cxgb, OID_AUTO, force_fw_update, CTLFLAG_RDTUN, &force_fw_update, 0,
"update firmware even if up to date");
-int cxgb_use_16k_clusters = 1;
+int cxgb_use_16k_clusters = -1;
TUNABLE_INT("hw.cxgb.use_16k_clusters", &cxgb_use_16k_clusters);
-SYSCTL_UINT(_hw_cxgb, OID_AUTO, use_16k_clusters, CTLFLAG_RDTUN,
+SYSCTL_INT(_hw_cxgb, OID_AUTO, use_16k_clusters, CTLFLAG_RDTUN,
&cxgb_use_16k_clusters, 0, "use 16kB clusters for the jumbo queue ");
/*
@@ -378,17 +378,25 @@ upgrade_fw(adapter_t *sc)
{
const struct firmware *fw;
int status;
+ u32 vers;
if ((fw = firmware_get(FW_FNAME)) == NULL) {
device_printf(sc->dev, "Could not find firmware image %s\n", FW_FNAME);
return (ENOENT);
} else
- device_printf(sc->dev, "updating firmware on card\n");
+ device_printf(sc->dev, "installing firmware on card\n");
status = t3_load_fw(sc, (const uint8_t *)fw->data, fw->datasize);
- device_printf(sc->dev, "firmware update returned %s %d\n",
- status == 0 ? "success" : "fail", status);
-
+ if (status != 0) {
+ device_printf(sc->dev, "failed to install firmware: %d\n",
+ status);
+ } else {
+ t3_get_fw_version(sc, &vers);
+ snprintf(&sc->fw_version[0], sizeof(sc->fw_version), "%d.%d.%d",
+ G_FW_VERSION_MAJOR(vers), G_FW_VERSION_MINOR(vers),
+ G_FW_VERSION_MICRO(vers));
+ }
+
firmware_put(fw, FIRMWARE_UNLOAD);
return (status);
@@ -1229,7 +1237,7 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed,
void t3_os_phymod_changed(struct adapter *adap, int port_id)
{
static const char *mod_str[] = {
- NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX", "unknown"
+ NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX-L", "unknown"
};
struct port_info *pi = &adap->port[port_id];
int mod = pi->phy.modtype;
@@ -2390,31 +2398,40 @@ cxgb_tick_handler(void *arg, int count)
if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map)
check_t3b2_mac(sc);
- cause = t3_read_reg(sc, A_SG_INT_CAUSE);
- reset = 0;
- if (cause & F_FLEMPTY) {
+ cause = t3_read_reg(sc, A_SG_INT_CAUSE) & (F_RSPQSTARVE | F_FLEMPTY);
+ if (cause) {
struct sge_qset *qs = &sc->sge.qs[0];
+ uint32_t mask, v;
+
+ v = t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) & ~0xff00;
- i = 0;
- reset |= F_FLEMPTY;
-
- cause = (t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) >>
- S_FL0EMPTY) & 0xffff;
- while (cause) {
- qs->fl[i].empty += (cause & 1);
- if (i)
- qs++;
- i ^= 1;
- cause >>= 1;
+ mask = 1;
+ for (i = 0; i < SGE_QSETS; i++) {
+ if (v & mask)
+ qs[i].rspq.starved++;
+ mask <<= 1;
+ }
+
+ mask <<= SGE_QSETS; /* skip RSPQXDISABLED */
+
+ for (i = 0; i < SGE_QSETS * 2; i++) {
+ if (v & mask) {
+ qs[i / 2].fl[i % 2].empty++;
+ }
+ mask <<= 1;
}
+
+ /* clear */
+ t3_write_reg(sc, A_SG_RSPQ_FL_STATUS, v);
+ t3_write_reg(sc, A_SG_INT_CAUSE, cause);
}
- t3_write_reg(sc, A_SG_INT_CAUSE, reset);
for (i = 0; i < sc->params.nports; i++) {
struct port_info *pi = &sc->port[i];
struct ifnet *ifp = pi->ifp;
struct cmac *mac = &pi->mac;
struct mac_stats *mstats = &mac->stats;
+ int drops, j;
if (!isset(&sc->open_device_map, pi->port_id))
continue;
@@ -2423,34 +2440,20 @@ cxgb_tick_handler(void *arg, int count)
t3_mac_update_stats(mac);
PORT_UNLOCK(pi);
- ifp->if_opackets =
- mstats->tx_frames_64 +
- mstats->tx_frames_65_127 +
- mstats->tx_frames_128_255 +
- mstats->tx_frames_256_511 +
- mstats->tx_frames_512_1023 +
- mstats->tx_frames_1024_1518 +
- mstats->tx_frames_1519_max;
-
- ifp->if_ipackets =
- mstats->rx_frames_64 +
- mstats->rx_frames_65_127 +
- mstats->rx_frames_128_255 +
- mstats->rx_frames_256_511 +
- mstats->rx_frames_512_1023 +
- mstats->rx_frames_1024_1518 +
- mstats->rx_frames_1519_max;
-
+ ifp->if_opackets = mstats->tx_frames;
+ ifp->if_ipackets = mstats->rx_frames;
ifp->if_obytes = mstats->tx_octets;
ifp->if_ibytes = mstats->rx_octets;
ifp->if_omcasts = mstats->tx_mcast_frames;
ifp->if_imcasts = mstats->rx_mcast_frames;
-
- ifp->if_collisions =
- mstats->tx_total_collisions;
-
+ ifp->if_collisions = mstats->tx_total_collisions;
ifp->if_iqdrops = mstats->rx_cong_drops;
-
+
+ drops = 0;
+ for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; j++)
+ drops += sc->sge.qs[j].txq[TXQ_ETH].txq_mr->br_drops;
+ ifp->if_snd.ifq_drops = drops;
+
ifp->if_oerrors =
mstats->tx_excess_collisions +
mstats->tx_underrun +
@@ -2707,7 +2710,9 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
t->cong_thres = q->cong_thres;
t->qnum = i;
- if (sc->flags & USING_MSIX)
+ if ((sc->flags & FULL_INIT_DONE) == 0)
+ t->vector = 0;
+ else if (sc->flags & USING_MSIX)
t->vector = rman_get_start(sc->msix_irq_res[i]);
else
t->vector = rman_get_start(sc->irq_res);
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index 184c5af..9bc36c9 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -30,6 +30,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_inet.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -117,13 +119,9 @@ SYSCTL_UINT(_hw_cxgb, OID_AUTO, tx_reclaim_threshold, CTLFLAG_RW,
* we have an m_ext
*/
static int recycle_enable = 0;
-int cxgb_ext_freed = 0;
-int cxgb_ext_inited = 0;
-int fl_q_size = 0;
-int jumbo_q_size = 0;
extern int cxgb_use_16k_clusters;
-extern int nmbjumbo4;
+extern int nmbjumbop;
extern int nmbjumbo9;
extern int nmbjumbo16;
@@ -530,21 +528,30 @@ t3_sge_err_intr_handler(adapter_t *adapter)
void
t3_sge_prep(adapter_t *adap, struct sge_params *p)
{
- int i, nqsets;
+ int i, nqsets, fl_q_size, jumbo_q_size, use_16k, jumbo_buf_size;
- nqsets = min(SGE_QSETS, mp_ncpus*4);
+ nqsets = min(SGE_QSETS / adap->params.nports, mp_ncpus);
+ nqsets *= adap->params.nports;
fl_q_size = min(nmbclusters/(3*nqsets), FL_Q_SIZE);
while (!powerof2(fl_q_size))
fl_q_size--;
+
+ use_16k = cxgb_use_16k_clusters != -1 ? cxgb_use_16k_clusters :
+ is_offload(adap);
+
#if __FreeBSD_version >= 700111
- if (cxgb_use_16k_clusters)
+ if (use_16k) {
jumbo_q_size = min(nmbjumbo16/(3*nqsets), JUMBO_Q_SIZE);
- else
+ jumbo_buf_size = MJUM16BYTES;
+ } else {
jumbo_q_size = min(nmbjumbo9/(3*nqsets), JUMBO_Q_SIZE);
+ jumbo_buf_size = MJUM9BYTES;
+ }
#else
- jumbo_q_size = min(nmbjumbo4/(3*nqsets), JUMBO_Q_SIZE);
+ jumbo_q_size = min(nmbjumbop/(3*nqsets), JUMBO_Q_SIZE);
+ jumbo_buf_size = MJUMPAGESIZE;
#endif
while (!powerof2(jumbo_q_size))
jumbo_q_size--;
@@ -553,8 +560,7 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p)
device_printf(adap->dev,
"Insufficient clusters and/or jumbo buffers.\n");
- /* XXX Does ETHER_ALIGN need to be accounted for here? */
- p->max_pkt_size = adap->sge.qs[0].fl[1].buf_size - sizeof(struct cpl_rx_data);
+ p->max_pkt_size = jumbo_buf_size - sizeof(struct cpl_rx_data);
for (i = 0; i < SGE_QSETS; ++i) {
struct qset_params *q = p->qset + i;
@@ -572,9 +578,10 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p)
q->rspq_size = RSPQ_Q_SIZE;
q->fl_size = fl_q_size;
q->jumbo_size = jumbo_q_size;
+ q->jumbo_buf_size = jumbo_buf_size;
q->txq_size[TXQ_ETH] = TX_ETH_Q_SIZE;
- q->txq_size[TXQ_OFLD] = 1024;
- q->txq_size[TXQ_CTRL] = 256;
+ q->txq_size[TXQ_OFLD] = is_offload(adap) ? TX_OFLD_Q_SIZE : 16;
+ q->txq_size[TXQ_CTRL] = TX_CTRL_Q_SIZE;
q->cong_thres = 0;
}
}
@@ -1636,12 +1643,9 @@ cxgb_start_locked(struct sge_qset *qs)
{
struct mbuf *m_head = NULL;
struct sge_txq *txq = &qs->txq[TXQ_ETH];
- int avail, txmax;
int in_use_init = txq->in_use;
struct port_info *pi = qs->port;
struct ifnet *ifp = pi->ifp;
- avail = txq->size - txq->in_use - 4;
- txmax = min(TX_START_MAX_DESC, avail);
if (qs->qs_flags & (QS_FLUSHING|QS_TIMEOUT))
reclaim_completed_tx(qs, 0, TXQ_ETH);
@@ -1651,12 +1655,14 @@ cxgb_start_locked(struct sge_qset *qs)
return;
}
TXQ_LOCK_ASSERT(qs);
- while ((txq->in_use - in_use_init < txmax) &&
- !TXQ_RING_EMPTY(qs) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+ while ((txq->in_use - in_use_init < TX_START_MAX_DESC) &&
+ !TXQ_RING_EMPTY(qs) && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
pi->link_config.link_ok) {
reclaim_completed_tx(qs, cxgb_tx_reclaim_threshold, TXQ_ETH);
+ if (txq->size - txq->in_use <= TX_MAX_DESC)
+ break;
+
if ((m_head = cxgb_dequeue(qs)) == NULL)
break;
/*
@@ -1695,7 +1701,7 @@ cxgb_transmit_locked(struct ifnet *ifp, struct sge_qset *qs, struct mbuf *m)
* - there is space in hardware transmit queue
*/
if (check_pkt_coalesce(qs) == 0 &&
- !TXQ_RING_NEEDS_ENQUEUE(qs) && avail > 4) {
+ !TXQ_RING_NEEDS_ENQUEUE(qs) && avail > TX_MAX_DESC) {
if (t3_encap(qs, &m)) {
if (m != NULL &&
(error = drbr_enqueue(ifp, br, m)) != 0)
@@ -2003,15 +2009,13 @@ t3_free_qset(adapter_t *sc, struct sge_qset *q)
int i;
reclaim_completed_tx(q, 0, TXQ_ETH);
- for (i = 0; i < SGE_TXQ_PER_SET; i++) {
- if (q->txq[i].txq_mr != NULL)
- buf_ring_free(q->txq[i].txq_mr, M_DEVBUF);
- if (q->txq[i].txq_ifq != NULL) {
- ifq_delete(q->txq[i].txq_ifq);
- free(q->txq[i].txq_ifq, M_DEVBUF);
- }
+ if (q->txq[TXQ_ETH].txq_mr != NULL)
+ buf_ring_free(q->txq[TXQ_ETH].txq_mr, M_DEVBUF);
+ if (q->txq[TXQ_ETH].txq_ifq != NULL) {
+ ifq_delete(q->txq[TXQ_ETH].txq_ifq);
+ free(q->txq[TXQ_ETH].txq_ifq, M_DEVBUF);
}
-
+
for (i = 0; i < SGE_RXQ_PER_SET; ++i) {
if (q->fl[i].desc) {
mtx_lock_spin(&sc->sge.reg_lock);
@@ -2060,7 +2064,9 @@ t3_free_qset(adapter_t *sc, struct sge_qset *q)
MTX_DESTROY(&q->rspq.lock);
}
+#ifdef INET
tcp_lro_free(&q->lro.ctrl);
+#endif
bzero(q, sizeof(*q));
}
@@ -2546,25 +2552,22 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx,
MTX_INIT(&q->lock, q->namebuf, NULL, MTX_DEF);
q->port = pi;
- for (i = 0; i < SGE_TXQ_PER_SET; i++) {
-
- if ((q->txq[i].txq_mr = buf_ring_alloc(cxgb_txq_buf_ring_size,
- M_DEVBUF, M_WAITOK, &q->lock)) == NULL) {
- device_printf(sc->dev, "failed to allocate mbuf ring\n");
- goto err;
- }
- if ((q->txq[i].txq_ifq =
- malloc(sizeof(struct ifaltq), M_DEVBUF, M_NOWAIT|M_ZERO))
- == NULL) {
- device_printf(sc->dev, "failed to allocate ifq\n");
- goto err;
- }
- ifq_init(q->txq[i].txq_ifq, pi->ifp);
- callout_init(&q->txq[i].txq_timer, 1);
- callout_init(&q->txq[i].txq_watchdog, 1);
- q->txq[i].txq_timer.c_cpu = id % mp_ncpus;
- q->txq[i].txq_watchdog.c_cpu = id % mp_ncpus;
+ if ((q->txq[TXQ_ETH].txq_mr = buf_ring_alloc(cxgb_txq_buf_ring_size,
+ M_DEVBUF, M_WAITOK, &q->lock)) == NULL) {
+ device_printf(sc->dev, "failed to allocate mbuf ring\n");
+ goto err;
+ }
+ if ((q->txq[TXQ_ETH].txq_ifq = malloc(sizeof(struct ifaltq), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ device_printf(sc->dev, "failed to allocate ifq\n");
+ goto err;
}
+ ifq_init(q->txq[TXQ_ETH].txq_ifq, pi->ifp);
+ callout_init(&q->txq[TXQ_ETH].txq_timer, 1);
+ callout_init(&q->txq[TXQ_ETH].txq_watchdog, 1);
+ q->txq[TXQ_ETH].txq_timer.c_cpu = id % mp_ncpus;
+ q->txq[TXQ_ETH].txq_watchdog.c_cpu = id % mp_ncpus;
+
init_qset_cntxt(q, id);
q->idx = id;
if ((ret = alloc_ring(sc, p->fl_size, sizeof(struct rx_desc),
@@ -2629,29 +2632,32 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx,
q->fl[0].buf_size = MCLBYTES;
q->fl[0].zone = zone_pack;
q->fl[0].type = EXT_PACKET;
-#if __FreeBSD_version > 800000
- if (cxgb_use_16k_clusters) {
- q->fl[1].buf_size = MJUM16BYTES;
+
+ if (p->jumbo_buf_size == MJUM16BYTES) {
q->fl[1].zone = zone_jumbo16;
q->fl[1].type = EXT_JUMBO16;
- } else {
- q->fl[1].buf_size = MJUM9BYTES;
+ } else if (p->jumbo_buf_size == MJUM9BYTES) {
q->fl[1].zone = zone_jumbo9;
q->fl[1].type = EXT_JUMBO9;
+ } else if (p->jumbo_buf_size == MJUMPAGESIZE) {
+ q->fl[1].zone = zone_jumbop;
+ q->fl[1].type = EXT_JUMBOP;
+ } else {
+ KASSERT(0, ("can't deal with jumbo_buf_size %d.", p->jumbo_buf_size));
+ ret = EDOOFUS;
+ goto err;
}
-#else
- q->fl[1].buf_size = MJUMPAGESIZE;
- q->fl[1].zone = zone_jumbop;
- q->fl[1].type = EXT_JUMBOP;
-#endif
+ q->fl[1].buf_size = p->jumbo_buf_size;
/* Allocate and setup the lro_ctrl structure */
q->lro.enabled = !!(pi->ifp->if_capenable & IFCAP_LRO);
+#ifdef INET
ret = tcp_lro_init(&q->lro.ctrl);
if (ret) {
printf("error %d from tcp_lro_init\n", ret);
goto err;
}
+#endif
q->lro.ctrl.ifp = pi->ifp;
mtx_lock_spin(&sc->sge.reg_lock);
@@ -3059,8 +3065,11 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
*/
skip_lro = __predict_false(qs->port->ifp != m->m_pkthdr.rcvif);
- if (lro_enabled && lro_ctrl->lro_cnt && !skip_lro &&
- (tcp_lro_rx(lro_ctrl, m, 0) == 0)) {
+ if (lro_enabled && lro_ctrl->lro_cnt && !skip_lro
+#ifdef INET
+ && (tcp_lro_rx(lro_ctrl, m, 0) == 0)
+#endif
+ ) {
/* successfully queue'd for LRO */
} else {
/*
@@ -3081,12 +3090,14 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
+#ifdef INET
/* Flush LRO */
while (!SLIST_EMPTY(&lro_ctrl->lro_active)) {
struct lro_entry *queued = SLIST_FIRST(&lro_ctrl->lro_active);
SLIST_REMOVE_HEAD(&lro_ctrl->lro_active, next);
tcp_lro_flush(lro_ctrl, queued);
}
+#endif
if (sleeping)
check_ring_db(adap, qs, sleeping);
@@ -3575,6 +3586,9 @@ t3_add_configured_sysctls(adapter_t *sc)
SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "credits",
CTLFLAG_RD, &qs->rspq.credits,
0, "#credits");
+ SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "starved",
+ CTLFLAG_RD, &qs->rspq.starved,
+ 0, "#times starved");
SYSCTL_ADD_XLONG(ctx, rspqpoidlist, OID_AUTO, "phys_addr",
CTLFLAG_RD, &qs->rspq.phys_addr,
"physical_address_of the queue");
@@ -3588,10 +3602,9 @@ t3_add_configured_sysctls(adapter_t *sc)
CTLTYPE_STRING | CTLFLAG_RD, &qs->rspq,
0, t3_dump_rspq, "A", "dump of the response queue");
-
- SYSCTL_ADD_INT(ctx, txqpoidlist, OID_AUTO, "dropped",
- CTLFLAG_RD, &qs->txq[TXQ_ETH].txq_drops,
- 0, "#tunneled packets dropped");
+ SYSCTL_ADD_QUAD(ctx, txqpoidlist, OID_AUTO, "dropped",
+ CTLFLAG_RD, &qs->txq[TXQ_ETH].txq_mr->br_drops,
+ "#tunneled packets dropped");
SYSCTL_ADD_INT(ctx, txqpoidlist, OID_AUTO, "sendqlen",
CTLFLAG_RD, &qs->txq[TXQ_ETH].sendq.qlen,
0, "#tunneled packets waiting to be sent");
diff --git a/sys/dev/drm/ati_pcigart.c b/sys/dev/drm/ati_pcigart.c
index e3fecd1..063288e 100644
--- a/sys/dev/drm/ati_pcigart.c
+++ b/sys/dev/drm/ati_pcigart.c
@@ -39,8 +39,9 @@ __FBSDID("$FreeBSD$");
#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
#define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
-#define ATI_PCIE_WRITE 0x4
-#define ATI_PCIE_READ 0x8
+#define ATI_GART_NOSNOOP 0x1
+#define ATI_GART_WRITE 0x4
+#define ATI_GART_READ 0x8
static void
drm_ati_alloc_pcigart_table_cb(void *arg, bus_dma_segment_t *segs,
@@ -196,13 +197,15 @@ drm_ati_pcigart_init(struct drm_device *dev,
case DRM_ATI_GART_IGP:
page_base |=
(upper_32_bits(entry_addr) & 0xff) << 4;
- page_base |= 0xc;
+ page_base |= ATI_GART_READ | ATI_GART_WRITE;
+ page_base |= ATI_GART_NOSNOOP;
break;
case DRM_ATI_GART_PCIE:
page_base >>= 8;
page_base |=
(upper_32_bits(entry_addr) & 0xff) << 24;
- page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
+ page_base |= ATI_GART_READ | ATI_GART_WRITE;
+ page_base |= ATI_GART_NOSNOOP;
break;
default:
case DRM_ATI_GART_PCI:
diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index f89e750..af50893 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -49,6 +49,7 @@ struct drm_file;
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/sglist.h>
#include <sys/stat.h>
#if __FreeBSD_version >= 700000
#include <sys/priv.h>
@@ -68,10 +69,13 @@ struct drm_file;
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <vm/vm_param.h>
+#include <vm/vm_phys.h>
#include <machine/param.h>
#include <machine/pmap.h>
#include <machine/bus.h>
@@ -224,7 +228,7 @@ enum {
#define DRM_MTRR_WC MDF_WRITECOMBINE
#define jiffies ticks
-typedef unsigned long dma_addr_t;
+typedef vm_paddr_t dma_addr_t;
typedef u_int64_t u64;
typedef u_int32_t u32;
typedef u_int16_t u16;
@@ -239,22 +243,22 @@ typedef u_int8_t u8;
#define DRM_MEMORYBARRIER() mb()
#define DRM_READ8(map, offset) \
- *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) + \
+ *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \
(vm_offset_t)(offset))
#define DRM_READ16(map, offset) \
- *(volatile u_int16_t *)(((vm_offset_t)(map)->handle) + \
+ *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \
(vm_offset_t)(offset))
#define DRM_READ32(map, offset) \
- *(volatile u_int32_t *)(((vm_offset_t)(map)->handle) + \
+ *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \
(vm_offset_t)(offset))
#define DRM_WRITE8(map, offset, val) \
- *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) + \
+ *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \
(vm_offset_t)(offset)) = val
#define DRM_WRITE16(map, offset, val) \
- *(volatile u_int16_t *)(((vm_offset_t)(map)->handle) + \
+ *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \
(vm_offset_t)(offset)) = val
#define DRM_WRITE32(map, offset, val) \
- *(volatile u_int32_t *)(((vm_offset_t)(map)->handle) + \
+ *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \
(vm_offset_t)(offset)) = val
#define DRM_VERIFYAREA_READ( uaddr, size ) \
@@ -474,25 +478,26 @@ typedef struct drm_agp_head {
} drm_agp_head_t;
typedef struct drm_sg_mem {
- unsigned long handle;
- void *virtual;
- int pages;
- dma_addr_t *busaddr;
- struct drm_dma_handle *dmah; /* Handle to PCI memory */
+ vm_offset_t vaddr;
+ vm_paddr_t *busaddr;
+ vm_pindex_t pages;
} drm_sg_mem_t;
+#define DRM_MAP_HANDLE_BITS (sizeof(void *) == 4 ? 4 : 24)
+#define DRM_MAP_HANDLE_SHIFT (sizeof(void *) * 8 - DRM_MAP_HANDLE_BITS)
typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t;
typedef struct drm_local_map {
- unsigned long offset; /* Physical address (0 for SAREA)*/
- unsigned long size; /* Physical size (bytes) */
- enum drm_map_type type; /* Type of memory mapped */
- enum drm_map_flags flags; /* Flags */
- void *handle; /* User-space: "Handle" to pass to mmap */
- /* Kernel-space: kernel-virtual address */
- int mtrr; /* Boolean: MTRR used */
- /* Private data */
- int rid; /* PCI resource ID for bus_space */
+ unsigned long offset; /* Physical address (0 for SAREA) */
+ unsigned long size; /* Physical size (bytes) */
+ enum drm_map_type type; /* Type of memory mapped */
+ enum drm_map_flags flags; /* Flags */
+ void *handle; /* User-space: "Handle" to pass to mmap */
+ /* Kernel-space: kernel-virtual address */
+ int mtrr; /* Boolean: MTRR used */
+ /* Private data */
+ int rid; /* PCI resource ID for bus_space */
+ void *virtual; /* Kernel-space: kernel-virtual address */
struct resource *bsr;
bus_space_tag_t bst;
bus_space_handle_t bsh;
@@ -643,6 +648,7 @@ struct drm_device {
/* Linked list of mappable regions. Protected by dev_lock */
drm_map_list_t maplist;
+ struct unrhdr *map_unrhdr;
drm_local_map_t **context_sareas;
int max_context;
@@ -973,17 +979,17 @@ drm_free(void *pt, size_t size, struct malloc_type *area)
static __inline__ void
drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev)
{
- map->handle = drm_ioremap_wc(dev, map);
+ map->virtual = drm_ioremap_wc(dev, map);
}
static __inline__ void
drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev)
{
- map->handle = drm_ioremap(dev, map);
+ map->virtual = drm_ioremap(dev, map);
}
static __inline__ void
drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
{
- if ( map->handle && map->size )
+ if ( map->virtual && map->size )
drm_ioremapfree(map);
}
@@ -994,7 +1000,7 @@ drm_core_findmap(struct drm_device *dev, unsigned long offset)
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
TAILQ_FOREACH(map, &dev->maplist, link) {
- if (map->offset == offset)
+ if (offset == (unsigned long)map->handle)
return map;
}
return NULL;
diff --git a/sys/dev/drm/drm_bufs.c b/sys/dev/drm/drm_bufs.c
index bd31b0a..2d27cd4 100644
--- a/sys/dev/drm/drm_bufs.c
+++ b/sys/dev/drm/drm_bufs.c
@@ -156,10 +156,12 @@ int drm_addmap(struct drm_device * dev, unsigned long offset,
map->size = size;
map->type = type;
map->flags = flags;
+ map->handle = (void *)((unsigned long)alloc_unr(dev->map_unrhdr) <<
+ DRM_MAP_HANDLE_SHIFT);
switch (map->type) {
case _DRM_REGISTERS:
- map->handle = drm_ioremap(dev, map);
+ map->virtual = drm_ioremap(dev, map);
if (!(map->flags & _DRM_WRITE_COMBINING))
break;
/* FALLTHROUGH */
@@ -168,25 +170,25 @@ int drm_addmap(struct drm_device * dev, unsigned long offset,
map->mtrr = 1;
break;
case _DRM_SHM:
- map->handle = malloc(map->size, DRM_MEM_MAPS, M_NOWAIT);
+ map->virtual = malloc(map->size, DRM_MEM_MAPS, M_NOWAIT);
DRM_DEBUG("%lu %d %p\n",
- map->size, drm_order(map->size), map->handle);
- if (!map->handle) {
+ map->size, drm_order(map->size), map->virtual);
+ if (!map->virtual) {
free(map, DRM_MEM_MAPS);
DRM_LOCK();
return ENOMEM;
}
- map->offset = (unsigned long)map->handle;
+ map->offset = (unsigned long)map->virtual;
if (map->flags & _DRM_CONTAINS_LOCK) {
/* Prevent a 2nd X Server from creating a 2nd lock */
DRM_LOCK();
if (dev->lock.hw_lock != NULL) {
DRM_UNLOCK();
- free(map->handle, DRM_MEM_MAPS);
+ free(map->virtual, DRM_MEM_MAPS);
free(map, DRM_MEM_MAPS);
return EBUSY;
}
- dev->lock.hw_lock = map->handle; /* Pointer to lock */
+ dev->lock.hw_lock = map->virtual; /* Pointer to lock */
DRM_UNLOCK();
}
break;
@@ -224,7 +226,8 @@ int drm_addmap(struct drm_device * dev, unsigned long offset,
DRM_LOCK();
return EINVAL;
}
- map->offset += dev->sg->handle;
+ map->virtual = (void *)(dev->sg->vaddr + offset);
+ map->offset = dev->sg->vaddr + offset;
break;
case _DRM_CONSISTENT:
/* Unfortunately, we don't get any alignment specification from
@@ -242,7 +245,7 @@ int drm_addmap(struct drm_device * dev, unsigned long offset,
DRM_LOCK();
return ENOMEM;
}
- map->handle = map->dmah->vaddr;
+ map->virtual = map->dmah->vaddr;
map->offset = map->dmah->busaddr;
break;
default:
@@ -291,11 +294,7 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data,
request->type = map->type;
request->flags = map->flags;
request->mtrr = map->mtrr;
- request->handle = map->handle;
-
- if (request->type != _DRM_SHM) {
- request->handle = (void *)request->offset;
- }
+ request->handle = (void *)map->handle;
return 0;
}
@@ -324,7 +323,7 @@ void drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
}
break;
case _DRM_SHM:
- free(map->handle, DRM_MEM_MAPS);
+ free(map->virtual, DRM_MEM_MAPS);
break;
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
@@ -342,6 +341,12 @@ void drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
map->bsr);
}
+ DRM_UNLOCK();
+ if (map->handle)
+ free_unr(dev->map_unrhdr, (unsigned long)map->handle >>
+ DRM_MAP_HANDLE_SHIFT);
+ DRM_LOCK();
+
free(map, DRM_MEM_MAPS);
}
@@ -739,7 +744,7 @@ static int drm_do_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *reques
buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
- buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+ buf->address = (void *)(agp_offset + offset + dev->sg->vaddr);
buf->next = NULL;
buf->pending = 0;
buf->file_priv = NULL;
@@ -1054,7 +1059,7 @@ int drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
goto done;
}
size = round_page(map->size);
- foff = map->offset;
+ foff = (unsigned long)map->handle;
} else {
size = round_page(dma->byte_count),
foff = 0;
diff --git a/sys/dev/drm/drm_context.c b/sys/dev/drm/drm_context.c
index 398008b..3c13b43 100644
--- a/sys/dev/drm/drm_context.c
+++ b/sys/dev/drm/drm_context.c
@@ -147,7 +147,7 @@ int drm_getsareactx(struct drm_device *dev, void *data,
map = dev->context_sareas[request->ctx_id];
DRM_UNLOCK();
- request->handle = map->handle;
+ request->handle = (void *)map->handle;
return 0;
}
diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c
index c690c34..8d9bc69 100644
--- a/sys/dev/drm/drm_drv.c
+++ b/sys/dev/drm/drm_drv.c
@@ -434,6 +434,12 @@ static int drm_load(struct drm_device *dev)
DRM_DEBUG("\n");
TAILQ_INIT(&dev->maplist);
+ dev->map_unrhdr = new_unrhdr(1, ((1 << DRM_MAP_HANDLE_BITS) - 1), NULL);
+ if (dev->map_unrhdr == NULL) {
+ DRM_ERROR("Couldn't allocate map number allocator\n");
+ return EINVAL;
+ }
+
drm_mem_init();
drm_sysctl_init(dev);
@@ -565,6 +571,7 @@ static void drm_unload(struct drm_device *dev)
}
delete_unrhdr(dev->drw_unrhdr);
+ delete_unrhdr(dev->map_unrhdr);
drm_mem_uninit();
diff --git a/sys/dev/drm/drm_hashtab.c b/sys/dev/drm/drm_hashtab.c
index e98f102..360c02b 100644
--- a/sys/dev/drm/drm_hashtab.c
+++ b/sys/dev/drm/drm_hashtab.c
@@ -46,7 +46,8 @@ int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
ht->size = 1 << order;
ht->order = order;
ht->table = NULL;
- ht->table = hashinit(ht->size, DRM_MEM_HASHTAB, &ht->mask);
+ ht->table = hashinit_flags(ht->size, DRM_MEM_HASHTAB, &ht->mask,
+ HASH_NOWAIT);
if (!ht->table) {
DRM_ERROR("Out of memory for hash table\n");
return -ENOMEM;
diff --git a/sys/dev/drm/drm_memory.c b/sys/dev/drm/drm_memory.c
index 8eaf4d1..415b774 100644
--- a/sys/dev/drm/drm_memory.c
+++ b/sys/dev/drm/drm_memory.c
@@ -83,7 +83,7 @@ void *drm_ioremap(struct drm_device *dev, drm_local_map_t *map)
void drm_ioremapfree(drm_local_map_t *map)
{
- pmap_unmapdev((vm_offset_t) map->handle, map->size);
+ pmap_unmapdev((vm_offset_t) map->virtual, map->size);
}
int
diff --git a/sys/dev/drm/drm_mm.c b/sys/dev/drm/drm_mm.c
index 344436f..bab36c1 100644
--- a/sys/dev/drm/drm_mm.c
+++ b/sys/dev/drm/drm_mm.c
@@ -333,7 +333,8 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
mm->num_unused = 0;
mtx_init(&mm->unused_lock, "drm_unused", NULL, MTX_DEF);
- return drm_mm_create_tail_node(mm, start, size, 0);
+ /* XXX This could be non-atomic but gets called from a locked path */
+ return drm_mm_create_tail_node(mm, start, size, 1);
}
void drm_mm_takedown(struct drm_mm * mm)
diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h
index acebad4..a7575f2 100644
--- a/sys/dev/drm/drm_pciids.h
+++ b/sys/dev/drm/drm_pciids.h
@@ -549,7 +549,9 @@
{0x8086, 0x29B2, CHIP_I9XX|CHIP_I915, "Intel Q35"}, \
{0x8086, 0x29D2, CHIP_I9XX|CHIP_I915, "Intel Q33"}, \
{0x8086, 0x2A42, CHIP_I9XX|CHIP_I965, "Mobile Intel® GM45 Express Chipset"}, \
- {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Integrated Graphics Device"}, \
+ {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Eaglelake"}, \
+ {0x8086, 0xA001, CHIP_I9XX|CHIP_I965, "Intel Pineview"}, \
+ {0x8086, 0xA011, CHIP_I9XX|CHIP_I965, "Intel Pineview (M)"}, \
{0x8086, 0x2E12, CHIP_I9XX|CHIP_I965, "Intel Q45/Q43"}, \
{0x8086, 0x2E22, CHIP_I9XX|CHIP_I965, "Intel G45/G43"}, \
{0x8086, 0x2E32, CHIP_I9XX|CHIP_I965, "Intel G41"}, \
diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c
index b3ab63b..9a1a4b1 100644
--- a/sys/dev/drm/drm_scatter.c
+++ b/sys/dev/drm/drm_scatter.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * Copyright (c) 2009 Robert C. Noland III <rnoland@FreeBSD.org>
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -20,11 +20,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Gareth Hughes <gareth@valinux.com>
- * Eric Anholt <anholt@FreeBSD.org>
- *
*/
#include <sys/cdefs.h>
@@ -32,96 +27,58 @@ __FBSDID("$FreeBSD$");
/** @file drm_scatter.c
* Allocation of memory for scatter-gather mappings by the graphics chip.
- *
* The memory allocated here is then made into an aperture in the card
- * by drm_ati_pcigart_init().
+ * by mapping the pages into the GART.
*/
#include "dev/drm/drmP.h"
-static void drm_sg_alloc_cb(void *arg, bus_dma_segment_t *segs,
- int nsegs, int error);
-
int
drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request)
{
struct drm_sg_mem *entry;
- struct drm_dma_handle *dmah;
- int ret;
+ vm_size_t size;
+ vm_pindex_t pindex;
if (dev->sg)
return EINVAL;
- entry = malloc(sizeof(*entry), DRM_MEM_SGLISTS, M_WAITOK | M_ZERO);
- entry->pages = round_page(request->size) / PAGE_SIZE;
- DRM_DEBUG("sg size=%ld pages=%d\n", request->size, entry->pages);
+ DRM_DEBUG("request size=%ld\n", request->size);
+
+ entry = malloc(sizeof(*entry), DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ size = round_page(request->size);
+ entry->pages = OFF_TO_IDX(size);
entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr),
- DRM_MEM_PAGES, M_WAITOK | M_ZERO);
- dmah = malloc(sizeof(struct drm_dma_handle), DRM_MEM_DMA,
- M_WAITOK | M_ZERO);
- entry->dmah = dmah;
-
- ret = bus_dma_tag_create(NULL, PAGE_SIZE, 0, /* tag, align, boundary */
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */
- NULL, NULL, /* filtfunc, filtfuncargs */
- request->size, entry->pages, /* maxsize, nsegs */
- PAGE_SIZE, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockfuncargs */
- &dmah->tag);
- if (ret != 0) {
- drm_sg_cleanup(entry);
- return ENOMEM;
- }
+ DRM_MEM_SGLISTS, M_WAITOK | M_ZERO);
- ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr,
- BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, &dmah->map);
- if (ret != 0) {
+ entry->vaddr = kmem_alloc_attr(kernel_map, size, M_WAITOK | M_ZERO,
+ 0, BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING);
+ if (entry->vaddr == 0) {
drm_sg_cleanup(entry);
- return ENOMEM;
+ return (ENOMEM);
}
- entry->handle = (unsigned long)dmah->vaddr;
- entry->virtual = dmah->vaddr;
-
- ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr,
- request->size, drm_sg_alloc_cb, entry, BUS_DMA_NOWAIT);
- if (ret != 0) {
- drm_sg_cleanup(entry);
- return ENOMEM;
+ for(pindex = 0; pindex < entry->pages; pindex++) {
+ entry->busaddr[pindex] =
+ vtophys(entry->vaddr + IDX_TO_OFF(pindex));
}
DRM_LOCK();
if (dev->sg) {
DRM_UNLOCK();
drm_sg_cleanup(entry);
- return EINVAL;
+ return (EINVAL);
}
dev->sg = entry;
DRM_UNLOCK();
- DRM_DEBUG("handle=%08lx, kva=%p, contents=%08lx\n", entry->handle,
- entry->virtual, *(unsigned long *)entry->virtual);
+ request->handle = entry->vaddr;
- request->handle = entry->handle;
+ DRM_DEBUG("allocated %ju pages @ 0x%08zx, contents=%08lx\n",
+ entry->pages, entry->vaddr, *(unsigned long *)entry->vaddr);
- return 0;
-}
-
-static void
-drm_sg_alloc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
-{
- struct drm_sg_mem *entry = arg;
- int i;
-
- if (error != 0)
- return;
-
- for(i = 0 ; i < nsegs ; i++) {
- entry->busaddr[i] = segs[i].ds_addr;
- DRM_DEBUG("segment %d @ 0x%016lx\n", i,
- (unsigned long)segs[i].ds_addr);
- }
+ return (0);
}
int
@@ -132,23 +89,22 @@ drm_sg_alloc_ioctl(struct drm_device *dev, void *data,
DRM_DEBUG("\n");
- return drm_sg_alloc(dev, request);
+ return (drm_sg_alloc(dev, request));
}
void
drm_sg_cleanup(struct drm_sg_mem *entry)
{
- struct drm_dma_handle *dmah = entry->dmah;
-
- if (dmah->map != NULL)
- bus_dmamap_unload(dmah->tag, dmah->map);
- if (dmah->vaddr != NULL)
- bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
- if (dmah->tag != NULL)
- bus_dma_tag_destroy(dmah->tag);
- free(dmah, DRM_MEM_DMA);
- free(entry->busaddr, DRM_MEM_PAGES);
- free(entry, DRM_MEM_SGLISTS);
+ if (entry == NULL)
+ return;
+
+ if (entry->vaddr != 0)
+ kmem_free(kernel_map, entry->vaddr, IDX_TO_OFF(entry->pages));
+
+ free(entry->busaddr, DRM_MEM_SGLISTS);
+ free(entry, DRM_MEM_DRIVER);
+
+ return;
}
int
@@ -162,12 +118,12 @@ drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
dev->sg = NULL;
DRM_UNLOCK();
- if (!entry || entry->handle != request->handle)
- return EINVAL;
+ if (!entry || entry->vaddr != request->handle)
+ return (EINVAL);
- DRM_DEBUG("sg free virtual = 0x%lx\n", entry->handle);
+ DRM_DEBUG("free 0x%zx\n", entry->vaddr);
drm_sg_cleanup(entry);
- return 0;
+ return (0);
}
diff --git a/sys/dev/drm/drm_sman.c b/sys/dev/drm/drm_sman.c
index 9f1132c..32f9eb9 100644
--- a/sys/dev/drm/drm_sman.c
+++ b/sys/dev/drm/drm_sman.c
@@ -96,7 +96,8 @@ static void *drm_sman_mm_allocate(void *private, unsigned long size,
if (!tmp) {
return NULL;
}
- tmp = drm_mm_get_block(tmp, size, alignment);
+ /* This could be non-atomic, but we are called from a locked path */
+ tmp = drm_mm_get_block_atomic(tmp, size, alignment);
return tmp;
}
@@ -131,7 +132,7 @@ drm_sman_set_range(struct drm_sman * sman, unsigned int manager,
KASSERT(manager < sman->num_managers, ("Invalid manager"));
sman_mm = &sman->mm[manager];
- mm = malloc(sizeof(*mm), DRM_MEM_MM, M_WAITOK | M_ZERO);
+ mm = malloc(sizeof(*mm), DRM_MEM_MM, M_NOWAIT | M_ZERO);
if (!mm) {
return -ENOMEM;
}
@@ -174,7 +175,7 @@ static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman,
owner_hash);
}
- owner_item = malloc(sizeof(*owner_item), DRM_MEM_MM, M_WAITOK | M_ZERO);
+ owner_item = malloc(sizeof(*owner_item), DRM_MEM_MM, M_NOWAIT | M_ZERO);
if (!owner_item)
goto out;
@@ -206,12 +207,11 @@ struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int man
sman_mm = &sman->mm[manager];
tmp = sman_mm->allocate(sman_mm->private, size, alignment);
-
if (!tmp) {
return NULL;
}
- memblock = malloc(sizeof(*memblock), DRM_MEM_MM, M_WAITOK | M_ZERO);
+ memblock = malloc(sizeof(*memblock), DRM_MEM_MM, M_NOWAIT | M_ZERO);
DRM_DEBUG("allocated mem_block %p\n", memblock);
if (!memblock)
goto out;
diff --git a/sys/dev/drm/drm_sysctl.c b/sys/dev/drm/drm_sysctl.c
index cc33283..4d9b0e8 100644
--- a/sys/dev/drm/drm_sysctl.c
+++ b/sys/dev/drm/drm_sysctl.c
@@ -188,7 +188,7 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
DRM_UNLOCK();
DRM_SYSCTL_PRINT("\nslot offset size "
- "type flags address mtrr\n");
+ "type flags address handle mtrr\n");
for (i = 0; i < mapcount; i++) {
map = &tempmaps[i];
@@ -204,9 +204,11 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
yesno = "yes";
DRM_SYSCTL_PRINT(
- "%4d 0x%016lx 0x%08lx %4.4s 0x%02x 0x%016lx %s\n", i,
- map->offset, map->size, type, map->flags,
- (unsigned long)map->handle, yesno);
+ "%4d 0x%016lx 0x%08lx %4.4s 0x%02x 0x%016lx %6d %s\n",
+ i, map->offset, map->size, type, map->flags,
+ (unsigned long)map->virtual,
+ (unsigned int)((unsigned long)map->handle >>
+ DRM_MAP_HANDLE_SHIFT), yesno);
}
SYSCTL_OUT(req, "", 1);
diff --git a/sys/dev/drm/drm_vm.c b/sys/dev/drm/drm_vm.c
index 8f260fd..7986856 100644
--- a/sys/dev/drm/drm_vm.c
+++ b/sys/dev/drm/drm_vm.c
@@ -54,6 +54,7 @@ int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr,
if (file_priv && !file_priv->authenticated)
return EACCES;
+ DRM_DEBUG("called with offset %016jx\n", offset);
if (dev->dma && offset < ptoa(dev->dma->page_count)) {
drm_device_dma_t *dma = dev->dma;
@@ -72,31 +73,31 @@ int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr,
}
}
- /* A sequential search of a linked list is
- fine here because: 1) there will only be
- about 5-10 entries in the list and, 2) a
- DRI client only has to do this mapping
- once, so it doesn't have to be optimized
- for performance, even if the list was a
- bit longer. */
+ /* A sequential search of a linked list is
+ fine here because: 1) there will only be
+ about 5-10 entries in the list and, 2) a
+ DRI client only has to do this mapping
+ once, so it doesn't have to be optimized
+ for performance, even if the list was a
+ bit longer.
+ */
DRM_LOCK();
TAILQ_FOREACH(map, &dev->maplist, link) {
- if (offset >= map->offset && offset < map->offset + map->size)
+ if (offset >> DRM_MAP_HANDLE_SHIFT ==
+ (unsigned long)map->handle >> DRM_MAP_HANDLE_SHIFT)
break;
}
if (map == NULL) {
- DRM_DEBUG("Can't find map, requested offset = %016lx\n",
- (unsigned long)offset);
+ DRM_DEBUG("Can't find map, request offset = %016jx\n", offset);
TAILQ_FOREACH(map, &dev->maplist, link) {
DRM_DEBUG("map offset = %016lx, handle = %016lx\n",
- (unsigned long)map->offset,
- (unsigned long)map->handle);
+ map->offset, (unsigned long)map->handle);
}
DRM_UNLOCK();
return -1;
}
- if (((map->flags&_DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) {
+ if (((map->flags & _DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) {
DRM_UNLOCK();
DRM_DEBUG("restricted map\n");
return -1;
@@ -104,18 +105,22 @@ int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr,
type = map->type;
DRM_UNLOCK();
+ offset = offset & ((1ULL << DRM_MAP_HANDLE_SHIFT) - 1);
+
switch (type) {
case _DRM_FRAME_BUFFER:
- case _DRM_REGISTERS:
case _DRM_AGP:
- phys = offset;
- break;
- case _DRM_CONSISTENT:
- phys = vtophys((char *)map->handle + (offset - map->offset));
+ *memattr = VM_MEMATTR_WRITE_COMBINING;
+ /* FALLTHROUGH */
+ case _DRM_REGISTERS:
+ phys = map->offset + offset;
break;
case _DRM_SCATTER_GATHER:
+ *memattr = VM_MEMATTR_WRITE_COMBINING;
+ /* FALLTHROUGH */
+ case _DRM_CONSISTENT:
case _DRM_SHM:
- phys = vtophys(offset);
+ phys = vtophys((char *)map->virtual + offset);
break;
default:
DRM_ERROR("bad map type %d\n", type);
diff --git a/sys/dev/drm/i915_dma.c b/sys/dev/drm/i915_dma.c
index 386c058..7f8ddc1 100644
--- a/sys/dev/drm/i915_dma.c
+++ b/sys/dev/drm/i915_dma.c
@@ -151,7 +151,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
if (dev_priv->ring.virtual_start) {
drm_core_ioremapfree(&dev_priv->ring.map, dev);
dev_priv->ring.virtual_start = NULL;
- dev_priv->ring.map.handle = NULL;
+ dev_priv->ring.map.virtual = NULL;
dev_priv->ring.map.size = 0;
}
@@ -174,7 +174,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
}
dev_priv->sarea_priv = (drm_i915_sarea_t *)
- ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
+ ((u8 *) dev_priv->sarea->virtual + init->sarea_priv_offset);
if (init->ring_size != 0) {
if (dev_priv->ring.ring_obj != NULL) {
@@ -195,7 +195,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
drm_core_ioremap_wc(&dev_priv->ring.map, dev);
- if (dev_priv->ring.map.handle == NULL) {
+ if (dev_priv->ring.map.virtual == NULL) {
i915_dma_cleanup(dev);
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
@@ -203,7 +203,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
}
}
- dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
+ dev_priv->ring.virtual_start = dev_priv->ring.map.virtual;
dev_priv->cpp = init->cpp;
dev_priv->back_offset = init->back_offset;
@@ -229,7 +229,7 @@ static int i915_dma_resume(struct drm_device * dev)
return -EINVAL;
}
- if (dev_priv->ring.map.handle == NULL) {
+ if (dev_priv->ring.map.virtual == NULL) {
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
return -ENOMEM;
@@ -823,14 +823,14 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
dev_priv->hws_map.mtrr = 0;
drm_core_ioremap_wc(&dev_priv->hws_map, dev);
- if (dev_priv->hws_map.handle == NULL) {
+ if (dev_priv->hws_map.virtual == NULL) {
i915_dma_cleanup(dev);
dev_priv->status_gfx_addr = 0;
DRM_ERROR("can not ioremap virtual address for"
" G33 hw status page\n");
return -ENOMEM;
}
- dev_priv->hw_status_page = dev_priv->hws_map.handle;
+ dev_priv->hw_status_page = dev_priv->hws_map.virtual;
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
diff --git a/sys/dev/drm/i915_drv.h b/sys/dev/drm/i915_drv.h
index f52ab50..4ae5e5c 100644
--- a/sys/dev/drm/i915_drv.h
+++ b/sys/dev/drm/i915_drv.h
@@ -657,15 +657,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x2E32 || \
IS_GM45(dev))
+#define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
+#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
+#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
+
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
- (dev)->pci_device == 0x29D2)
+ (dev)->pci_device == 0x29D2 || \
+ IS_IGD(dev))
#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
- IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
+ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
+ IS_IGD(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
diff --git a/sys/dev/drm/i915_reg.h b/sys/dev/drm/i915_reg.h
index 1a32c5f..fce9992 100644
--- a/sys/dev/drm/i915_reg.h
+++ b/sys/dev/drm/i915_reg.h
@@ -362,6 +362,7 @@ __FBSDID("$FreeBSD$");
#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */
#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
#define I915_CRC_ERROR_ENABLE (1UL<<29)
@@ -438,6 +439,7 @@ __FBSDID("$FreeBSD$");
*/
#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
+#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15
/* i830, required in DVO non-gang */
#define PLL_P2_DIVIDE_BY_4 (1 << 23)
#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
@@ -504,10 +506,12 @@ __FBSDID("$FreeBSD$");
#define FPB0 0x06048
#define FPB1 0x0604c
#define FP_N_DIV_MASK 0x003f0000
+#define FP_N_IGD_DIV_MASK 0x00ff0000
#define FP_N_DIV_SHIFT 16
#define FP_M1_DIV_MASK 0x00003f00
#define FP_M1_DIV_SHIFT 8
#define FP_M2_DIV_MASK 0x0000003f
+#define FP_M2_IGD_DIV_MASK 0x000000ff
#define FP_M2_DIV_SHIFT 0
#define DPLL_TEST 0x606c
#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
diff --git a/sys/dev/drm/mach64_dma.c b/sys/dev/drm/mach64_dma.c
index 6068c85..9aa0faa 100644
--- a/sys/dev/drm/mach64_dma.c
+++ b/sys/dev/drm/mach64_dma.c
@@ -1078,11 +1078,11 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
}
dev_priv->sarea_priv = (drm_mach64_sarea_t *)
- ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
+ ((u8 *) dev_priv->sarea->virtual + init->sarea_priv_offset);
if (!dev_priv->is_pci) {
drm_core_ioremap(dev_priv->ring_map, dev);
- if (!dev_priv->ring_map->handle) {
+ if (!dev_priv->ring_map->virtual) {
DRM_ERROR("can not ioremap virtual address for"
" descriptor ring\n");
dev->dev_private = (void *)dev_priv;
@@ -1103,7 +1103,7 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
dev_priv->dev_buffers = dev->agp_buffer_map;
drm_core_ioremap(dev->agp_buffer_map, dev);
- if (!dev->agp_buffer_map->handle) {
+ if (!dev->agp_buffer_map->virtual) {
DRM_ERROR("can not ioremap virtual address for"
" dma buffer\n");
dev->dev_private = (void *)dev_priv;
@@ -1147,7 +1147,7 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
}
dev_priv->ring.size = 0x4000; /* 16KB */
- dev_priv->ring.start = dev_priv->ring_map->handle;
+ dev_priv->ring.start = dev_priv->ring_map->virtual;
dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset;
memset(dev_priv->ring.start, 0, dev_priv->ring.size);
diff --git a/sys/dev/drm/mga_dma.c b/sys/dev/drm/mga_dma.c
index e081e2c..71775b6 100644
--- a/sys/dev/drm/mga_dma.c
+++ b/sys/dev/drm/mga_dma.c
@@ -585,11 +585,11 @@ static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
drm_core_ioremap(dev_priv->primary, dev);
drm_core_ioremap(dev->agp_buffer_map, dev);
- if (!dev_priv->warp->handle ||
- !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
+ if (!dev_priv->warp->virtual ||
+ !dev_priv->primary->virtual || !dev->agp_buffer_map->virtual) {
DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n",
- dev_priv->warp->handle, dev_priv->primary->handle,
- dev->agp_buffer_map->handle);
+ dev_priv->warp->virtual, dev_priv->primary->virtual,
+ dev->agp_buffer_map->virtual);
return -ENOMEM;
}
@@ -878,14 +878,14 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
}
dev_priv->sarea_priv =
- (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->virtual +
init->sarea_priv_offset);
- if (!dev_priv->warp->handle ||
- !dev_priv->primary->handle ||
+ if (!dev_priv->warp->virtual ||
+ !dev_priv->primary->virtual ||
((dev_priv->dma_access != 0) &&
((dev->agp_buffer_map == NULL) ||
- (dev->agp_buffer_map->handle == NULL)))) {
+ (dev->agp_buffer_map->virtual == NULL)))) {
DRM_ERROR("failed to ioremap agp regions!\n");
return -ENOMEM;
}
@@ -902,7 +902,7 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
return ret;
}
- dev_priv->prim.status = (u32 *) dev_priv->status->handle;
+ dev_priv->prim.status = (u32 *) dev_priv->status->virtual;
mga_do_wait_for_idle(dev_priv);
@@ -910,8 +910,8 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
*/
MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
- dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
- dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
+ dev_priv->prim.start = (u8 *) dev_priv->primary->virtual;
+ dev_priv->prim.end = ((u8 *) dev_priv->primary->virtual
+ dev_priv->primary->size);
dev_priv->prim.size = dev_priv->primary->size;
diff --git a/sys/dev/drm/mga_warp.c b/sys/dev/drm/mga_warp.c
index dd3e734..98c1615 100644
--- a/sys/dev/drm/mga_warp.c
+++ b/sys/dev/drm/mga_warp.c
@@ -96,7 +96,7 @@ unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
{
- unsigned char *vcbase = dev_priv->warp->handle;
+ unsigned char *vcbase = dev_priv->warp->virtual;
unsigned long pcbase = dev_priv->warp->offset;
memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
@@ -124,7 +124,7 @@ static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
{
- unsigned char *vcbase = dev_priv->warp->handle;
+ unsigned char *vcbase = dev_priv->warp->virtual;
unsigned long pcbase = dev_priv->warp->offset;
memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
diff --git a/sys/dev/drm/r128_cce.c b/sys/dev/drm/r128_cce.c
index c799bd1..2bda4a5 100644
--- a/sys/dev/drm/r128_cce.c
+++ b/sys/dev/drm/r128_cce.c
@@ -327,8 +327,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev,
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
else
#endif
- ring_start = dev_priv->cce_ring->offset -
- (unsigned long)dev->sg->virtual;
+ ring_start = dev_priv->cce_ring->offset - dev->sg->vaddr;
R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET);
@@ -509,7 +508,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
}
dev_priv->sarea_priv =
- (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->virtual +
init->sarea_priv_offset);
#if __OS_HAS_AGP
@@ -517,9 +516,9 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
drm_core_ioremap(dev_priv->cce_ring, dev);
drm_core_ioremap(dev_priv->ring_rptr, dev);
drm_core_ioremap(dev->agp_buffer_map, dev);
- if (!dev_priv->cce_ring->handle ||
- !dev_priv->ring_rptr->handle ||
- !dev->agp_buffer_map->handle) {
+ if (!dev_priv->cce_ring->virtual ||
+ !dev_priv->ring_rptr->virtual ||
+ !dev->agp_buffer_map->virtual) {
DRM_ERROR("Could not ioremap agp regions!\n");
dev->dev_private = (void *)dev_priv;
r128_do_cleanup_cce(dev);
@@ -528,10 +527,11 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
} else
#endif
{
- dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
- dev_priv->ring_rptr->handle =
+ dev_priv->cce_ring->virtual =
+ (void *)dev_priv->cce_ring->offset;
+ dev_priv->ring_rptr->virtual =
(void *)dev_priv->ring_rptr->offset;
- dev->agp_buffer_map->handle =
+ dev->agp_buffer_map->virtual =
(void *)dev->agp_buffer_map->offset;
}
@@ -540,10 +540,10 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
dev_priv->cce_buffers_offset = dev->agp->base;
else
#endif
- dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
+ dev_priv->cce_buffers_offset = dev->sg->vaddr;
- dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle;
- dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle
+ dev_priv->ring.start = (u32 *) dev_priv->cce_ring->virtual;
+ dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->virtual
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
diff --git a/sys/dev/drm/r128_state.c b/sys/dev/drm/r128_state.c
index 6aef11c..9632dec 100644
--- a/sys/dev/drm/r128_state.c
+++ b/sys/dev/drm/r128_state.c
@@ -657,7 +657,7 @@ static void r128_cce_dispatch_indirect(struct drm_device * dev,
*/
if (dwords & 1) {
u32 *data = (u32 *)
- ((char *)dev->agp_buffer_map->handle
+ ((char *)dev->agp_buffer_map->virtual
+ buf->offset + start);
data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);
}
@@ -722,7 +722,7 @@ static void r128_cce_dispatch_indices(struct drm_device * dev,
dwords = (end - start + 3) / sizeof(u32);
- data = (u32 *) ((char *)dev->agp_buffer_map->handle
+ data = (u32 *) ((char *)dev->agp_buffer_map->virtual
+ buf->offset + start);
data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM,
diff --git a/sys/dev/drm/r600_blit.c b/sys/dev/drm/r600_blit.c
index a26f2c4..d3c41ae 100644
--- a/sys/dev/drm/r600_blit.c
+++ b/sys/dev/drm/r600_blit.c
@@ -1290,8 +1290,8 @@ set_shaders(struct drm_device *dev)
DRM_DEBUG("\n");
/* load shaders */
- vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset);
- ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256);
+ vs = (u32 *) ((char *)dev->agp_buffer_map->virtual + dev_priv->blit_vb->offset);
+ ps = (u32 *) ((char *)dev->agp_buffer_map->virtual + dev_priv->blit_vb->offset + 256);
shader_size = sizeof(r6xx_vs) / 4;
for (i= 0; i < shader_size; i++)
@@ -1718,11 +1718,10 @@ r600_blit_copy(struct drm_device *dev,
u64 vb_addr;
u32 *vb;
- vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
+ vb = (u32 *) ((char *)dev->agp_buffer_map->virtual +
dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
- DRM_DEBUG("src=0x%016llx, dst=0x%016llx, size=%d\n",
- (unsigned long long)src_gpu_addr,
- (unsigned long long)dst_gpu_addr, size_bytes);
+ DRM_DEBUG("src=0x%016jx, dst=0x%016jx, size=%d\n",
+ src_gpu_addr, dst_gpu_addr, size_bytes);
if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
max_bytes = 8192;
@@ -1759,7 +1758,7 @@ r600_blit_copy(struct drm_device *dev,
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
- vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
+ vb = (u32 *) ((char *)dev->agp_buffer_map->virtual +
dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
}
@@ -1849,7 +1848,7 @@ r600_blit_copy(struct drm_device *dev,
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
- vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
+ vb = (u32 *) ((char *)dev->agp_buffer_map->virtual +
dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
}
@@ -1928,7 +1927,7 @@ r600_blit_swap(struct drm_device *dev,
return;
set_shaders(dev);
}
- vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
+ vb = (u32 *) ((char *)dev->agp_buffer_map->virtual +
dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
sx2 = sx + w;
diff --git a/sys/dev/drm/r600_cp.c b/sys/dev/drm/r600_cp.c
index 2a4a6bd..c2b8770 100644
--- a/sys/dev/drm/r600_cp.c
+++ b/sys/dev/drm/r600_cp.c
@@ -180,7 +180,7 @@ int r600_page_table_init(struct drm_device *dev)
entry_addr = entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK;
- page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+ page_base |= R600_PTE_VALID | R600_PTE_SYSTEM;
page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
*pci_gart = page_base;
@@ -1670,9 +1670,8 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
} else
#endif
{
- rptr_addr = dev_priv->ring_rptr->offset
- - ((unsigned long) dev->sg->virtual)
- + dev_priv->gart_vm_start;
+ rptr_addr = dev_priv->ring_rptr->offset - dev->sg->vaddr +
+ dev_priv->gart_vm_start;
}
RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
rptr_addr & 0xffffffff);
@@ -1706,9 +1705,8 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
+ dev_priv->gart_vm_start);
} else
#endif
- ring_start = (dev_priv->cp_ring->offset
- - (unsigned long)dev->sg->virtual
- + dev_priv->gart_vm_start);
+ ring_start = dev_priv->cp_ring->offset - dev->sg->vaddr +
+ dev_priv->gart_vm_start;
RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8);
@@ -1914,7 +1912,7 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
}
dev_priv->sarea_priv =
- (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->virtual +
init->sarea_priv_offset);
#if __OS_HAS_AGP
@@ -1923,9 +1921,9 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
drm_core_ioremap_wc(dev_priv->cp_ring, dev);
drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
drm_core_ioremap_wc(dev->agp_buffer_map, dev);
- if (!dev_priv->cp_ring->handle ||
- !dev_priv->ring_rptr->handle ||
- !dev->agp_buffer_map->handle) {
+ if (!dev_priv->cp_ring->virtual ||
+ !dev_priv->ring_rptr->virtual ||
+ !dev->agp_buffer_map->virtual) {
DRM_ERROR("could not find ioremap agp regions!\n");
r600_do_cleanup_cp(dev);
return -EINVAL;
@@ -1933,18 +1931,19 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
} else
#endif
{
- dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
- dev_priv->ring_rptr->handle =
+ dev_priv->cp_ring->virtual =
+ (void *)dev_priv->cp_ring->offset;
+ dev_priv->ring_rptr->virtual =
(void *)dev_priv->ring_rptr->offset;
- dev->agp_buffer_map->handle =
+ dev->agp_buffer_map->virtual =
(void *)dev->agp_buffer_map->offset;
- DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
- dev_priv->cp_ring->handle);
- DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
- dev_priv->ring_rptr->handle);
- DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
- dev->agp_buffer_map->handle);
+ DRM_DEBUG("dev_priv->cp_ring->virtual %p\n",
+ dev_priv->cp_ring->virtual);
+ DRM_DEBUG("dev_priv->ring_rptr->virtual %p\n",
+ dev_priv->ring_rptr->virtual);
+ DRM_DEBUG("dev->agp_buffer_map->virtual %p\n",
+ dev->agp_buffer_map->virtual);
}
dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24;
@@ -2011,9 +2010,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ dev_priv->gart_vm_start);
else
#endif
- dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- - (unsigned long)dev->sg->virtual
- + dev_priv->gart_vm_start);
+ dev_priv->gart_buffers_offset = dev->agp_buffer_map->offset -
+ dev->sg->vaddr + dev_priv->gart_vm_start;
DRM_DEBUG("fb 0x%08x size %d\n",
(unsigned int) dev_priv->fb_location,
@@ -2024,8 +2022,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n",
dev_priv->gart_buffers_offset);
- dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
- dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+ dev_priv->ring.start = (u32 *) dev_priv->cp_ring->virtual;
+ dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->virtual
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
@@ -2064,14 +2062,14 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
dev_priv->gart_info.table_size;
drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
- if (!dev_priv->gart_info.mapping.handle) {
+ if (!dev_priv->gart_info.mapping.virtual) {
DRM_ERROR("ioremap failed.\n");
r600_do_cleanup_cp(dev);
return -EINVAL;
}
dev_priv->gart_info.addr =
- dev_priv->gart_info.mapping.handle;
+ dev_priv->gart_info.mapping.virtual;
DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
dev_priv->gart_info.addr,
@@ -2219,7 +2217,7 @@ int r600_cp_dispatch_indirect(struct drm_device *dev,
*/
while (dwords & 0xf) {
u32 *data = (u32 *)
- ((char *)dev->agp_buffer_map->handle
+ ((char *)dev->agp_buffer_map->virtual
+ buf->offset + start);
data[dwords++] = RADEON_CP_PACKET2;
}
@@ -2343,7 +2341,8 @@ int r600_cp_dispatch_texture(struct drm_device * dev,
/* Dispatch the indirect buffer.
*/
buffer =
- (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+ (u32 *) ((char *)dev->agp_buffer_map->virtual +
+ buf->offset);
if (DRM_COPY_FROM_USER(buffer, data, pass_size)) {
DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size);
diff --git a/sys/dev/drm/radeon_cp.c b/sys/dev/drm/radeon_cp.c
index 2e85f11..0a486af 100644
--- a/sys/dev/drm/radeon_cp.c
+++ b/sys/dev/drm/radeon_cp.c
@@ -53,7 +53,7 @@ u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off)
val = DRM_READ32(dev_priv->ring_rptr, off);
} else {
val = *(((volatile u32 *)
- dev_priv->ring_rptr->handle) +
+ dev_priv->ring_rptr->virtual) +
(off / sizeof(u32)));
val = le32_to_cpu(val);
}
@@ -77,7 +77,7 @@ void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val)
if (dev_priv->flags & RADEON_IS_AGP)
DRM_WRITE32(dev_priv->ring_rptr, off, val);
else
- *(((volatile u32 *) dev_priv->ring_rptr->handle) +
+ *(((volatile u32 *) dev_priv->ring_rptr->virtual) +
(off / sizeof(u32))) = cpu_to_le32(val);
}
@@ -720,9 +720,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+ dev_priv->gart_vm_start);
} else
#endif
- ring_start = (dev_priv->cp_ring->offset
- - (unsigned long)dev->sg->virtual
- + dev_priv->gart_vm_start);
+ ring_start = (dev_priv->cp_ring->offset - dev->sg->vaddr +
+ dev_priv->gart_vm_start);
RADEON_WRITE(RADEON_CP_RB_BASE, ring_start);
@@ -744,9 +743,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
#endif
{
RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
- dev_priv->ring_rptr->offset
- - ((unsigned long) dev->sg->virtual)
- + dev_priv->gart_vm_start);
+ dev_priv->ring_rptr->offset - dev->sg->vaddr +
+ dev_priv->gart_vm_start);
}
/* Set ring buffer size */
@@ -1278,7 +1276,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
}
dev_priv->sarea_priv =
- (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->virtual +
init->sarea_priv_offset);
#if __OS_HAS_AGP
@@ -1286,9 +1284,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
drm_core_ioremap_wc(dev_priv->cp_ring, dev);
drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
drm_core_ioremap_wc(dev->agp_buffer_map, dev);
- if (!dev_priv->cp_ring->handle ||
- !dev_priv->ring_rptr->handle ||
- !dev->agp_buffer_map->handle) {
+ if (!dev_priv->cp_ring->virtual ||
+ !dev_priv->ring_rptr->virtual ||
+ !dev->agp_buffer_map->virtual) {
DRM_ERROR("could not find ioremap agp regions!\n");
radeon_do_cleanup_cp(dev);
return -EINVAL;
@@ -1296,19 +1294,19 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
} else
#endif
{
- dev_priv->cp_ring->handle =
+ dev_priv->cp_ring->virtual =
(void *)(unsigned long)dev_priv->cp_ring->offset;
- dev_priv->ring_rptr->handle =
+ dev_priv->ring_rptr->virtual =
(void *)(unsigned long)dev_priv->ring_rptr->offset;
- dev->agp_buffer_map->handle =
+ dev->agp_buffer_map->virtual =
(void *)(unsigned long)dev->agp_buffer_map->offset;
- DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
- dev_priv->cp_ring->handle);
- DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
- dev_priv->ring_rptr->handle);
- DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
- dev->agp_buffer_map->handle);
+ DRM_DEBUG("dev_priv->cp_ring->virtual %p\n",
+ dev_priv->cp_ring->virtual);
+ DRM_DEBUG("dev_priv->ring_rptr->virtual %p\n",
+ dev_priv->ring_rptr->virtual);
+ DRM_DEBUG("dev->agp_buffer_map->virtual %p\n",
+ dev->agp_buffer_map->virtual);
}
dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
@@ -1377,17 +1375,16 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ dev_priv->gart_vm_start);
else
#endif
- dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- - (unsigned long)dev->sg->virtual
- + dev_priv->gart_vm_start);
+ dev_priv->gart_buffers_offset = dev->agp_buffer_map->offset -
+ dev->sg->vaddr + dev_priv->gart_vm_start;
DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start);
DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n",
dev_priv->gart_buffers_offset);
- dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
- dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+ dev_priv->ring.start = (u32 *) dev_priv->cp_ring->virtual;
+ dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->virtual
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
@@ -1423,7 +1420,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
dev_priv->gart_info.addr =
- dev_priv->gart_info.mapping.handle;
+ dev_priv->gart_info.mapping.virtual;
if (dev_priv->flags & RADEON_IS_PCIE)
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
diff --git a/sys/dev/drm/radeon_cs.c b/sys/dev/drm/radeon_cs.c
index b523126..14fe2fc 100644
--- a/sys/dev/drm/radeon_cs.c
+++ b/sys/dev/drm/radeon_cs.c
@@ -821,7 +821,7 @@ static int r600_ib_get(struct drm_radeon_cs_parser *parser)
}
buf->file_priv = parser->file_priv;
dev_priv->cs_buf = buf;
- parser->ib = (void *)((vm_offset_t)dev->agp_buffer_map->handle +
+ parser->ib = (void *)((vm_offset_t)dev->agp_buffer_map->virtual +
buf->offset);
return 0;
diff --git a/sys/dev/drm/radeon_state.c b/sys/dev/drm/radeon_state.c
index fd8388f..8061501 100644
--- a/sys/dev/drm/radeon_state.c
+++ b/sys/dev/drm/radeon_state.c
@@ -1420,7 +1420,7 @@ static void radeon_cp_dispatch_swap(struct drm_device *dev)
static void radeon_cp_dispatch_flip(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- struct drm_sarea *sarea = (struct drm_sarea *)dev_priv->sarea->handle;
+ struct drm_sarea *sarea = (struct drm_sarea *)dev_priv->sarea->virtual;
int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
@@ -1582,7 +1582,7 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev,
*/
if (dwords & 1) {
u32 *data = (u32 *)
- ((char *)dev->agp_buffer_map->handle
+ ((char *)dev->agp_buffer_map->virtual
+ buf->offset + start);
data[dwords++] = RADEON_CP_PACKET2;
}
@@ -1629,7 +1629,7 @@ static void radeon_cp_dispatch_indices(struct drm_device *dev,
dwords = (prim->finish - prim->start + 3) / sizeof(u32);
- data = (u32 *) ((char *)dev->agp_buffer_map->handle +
+ data = (u32 *) ((char *)dev->agp_buffer_map->virtual +
elt_buf->offset + prim->start);
data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
@@ -1781,7 +1781,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
/* Dispatch the indirect buffer.
*/
buffer =
- (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+ (u32 *) ((char *)dev->agp_buffer_map->virtual + buf->offset);
dwords = size / 4;
#define RADEON_COPY_MT(_buf, _data, _width) \
diff --git a/sys/dev/drm/savage_bci.c b/sys/dev/drm/savage_bci.c
index 4168ddf..0f8d66e 100644
--- a/sys/dev/drm/savage_bci.c
+++ b/sys/dev/drm/savage_bci.c
@@ -376,7 +376,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages);
if (cur + nr_pages < dev_priv->nr_dma_pages) {
- dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
+ dma_ptr = (uint32_t *)dev_priv->cmd_dma->virtual +
cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
if (n < rest)
rest = n;
@@ -392,7 +392,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
dev_priv->dma_pages[i].used = 0;
dev_priv->dma_pages[i].flushed = 0;
}
- dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle;
+ dma_ptr = (uint32_t *)dev_priv->cmd_dma->virtual;
dev_priv->first_dma_page = cur = 0;
}
for (i = cur; nr_pages > 0; ++i, --nr_pages) {
@@ -443,7 +443,7 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
/* pad with noops */
if (pad) {
- uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
+ uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->virtual +
cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
dev_priv->dma_pages[cur].used += pad;
while (pad != 0) {
@@ -517,7 +517,7 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
for (i = dev_priv->first_dma_page;
i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used;
++i) {
- uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
+ uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->virtual +
i * SAVAGE_DMA_PAGE_SIZE;
#if SAVAGE_DMA_DEBUG
/* Sanity check: all pages except the last one must be full. */
@@ -784,7 +784,7 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
return -EINVAL;
}
drm_core_ioremap(dev_priv->cmd_dma, dev);
- if (!dev_priv->cmd_dma->handle) {
+ if (!dev_priv->cmd_dma->virtual) {
DRM_ERROR("failed to ioremap command "
"DMA region!\n");
savage_do_cleanup_bci(dev);
@@ -806,9 +806,9 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
dev_priv->fake_dma.offset = 0;
dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE;
dev_priv->fake_dma.type = _DRM_SHM;
- dev_priv->fake_dma.handle = drm_alloc(SAVAGE_FAKE_DMA_SIZE,
+ dev_priv->fake_dma.virtual = drm_alloc(SAVAGE_FAKE_DMA_SIZE,
DRM_MEM_DRIVER);
- if (!dev_priv->fake_dma.handle) {
+ if (!dev_priv->fake_dma.virtual) {
DRM_ERROR("could not allocate faked DMA buffer!\n");
savage_do_cleanup_bci(dev);
return -ENOMEM;
@@ -818,7 +818,7 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
}
dev_priv->sarea_priv =
- (drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->handle +
+ (drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->virtual +
init->sarea_priv_offset);
/* setup bitmap descriptors */
@@ -857,7 +857,7 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
dev_priv->event_counter = 0;
dev_priv->event_wrap = 0;
dev_priv->bci_ptr = (volatile uint32_t *)
- ((uint8_t *)dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
+ ((uint8_t *)dev_priv->mmio->virtual + SAVAGE_BCI_OFFSET);
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D;
} else {
@@ -865,7 +865,7 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
}
if (dev_priv->status != NULL) {
dev_priv->status_ptr =
- (volatile uint32_t *)dev_priv->status->handle;
+ (volatile uint32_t *)dev_priv->status->virtual;
dev_priv->wait_fifo = savage_bci_wait_fifo_shadow;
dev_priv->wait_evnt = savage_bci_wait_event_shadow;
dev_priv->status_ptr[1023] = dev_priv->event_counter;
@@ -905,16 +905,16 @@ static int savage_do_cleanup_bci(struct drm_device *dev)
drm_savage_private_t *dev_priv = dev->dev_private;
if (dev_priv->cmd_dma == &dev_priv->fake_dma) {
- if (dev_priv->fake_dma.handle)
- drm_free(dev_priv->fake_dma.handle,
+ if (dev_priv->fake_dma.virtual)
+ drm_free(dev_priv->fake_dma.virtual,
SAVAGE_FAKE_DMA_SIZE, DRM_MEM_DRIVER);
- } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle &&
+ } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->virtual &&
dev_priv->cmd_dma->type == _DRM_AGP &&
dev_priv->dma_type == SAVAGE_DMA_AGP)
drm_core_ioremapfree(dev_priv->cmd_dma, dev);
if (dev_priv->dma_type == SAVAGE_DMA_AGP &&
- dev->agp_buffer_map && dev->agp_buffer_map->handle) {
+ dev->agp_buffer_map && dev->agp_buffer_map->virtual) {
drm_core_ioremapfree(dev->agp_buffer_map, dev);
/* make sure the next instance (which may be running
* in PCI mode) doesn't try to use an old
diff --git a/sys/dev/drm/via_dma.c b/sys/dev/drm/via_dma.c
index e1af293..6f435fe 100644
--- a/sys/dev/drm/via_dma.c
+++ b/sys/dev/drm/via_dma.c
@@ -158,6 +158,9 @@ static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
int via_dma_cleanup(struct drm_device * dev)
{
+ drm_via_blitq_t *blitq;
+ int i;
+
if (dev->dev_private) {
drm_via_private_t *dev_priv =
(drm_via_private_t *) dev->dev_private;
@@ -169,6 +172,10 @@ int via_dma_cleanup(struct drm_device * dev)
dev_priv->ring.virtual_start = NULL;
}
+ for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
+ blitq = dev_priv->blit_queues + i;
+ mtx_destroy(&blitq->blit_lock);
+ }
}
return 0;
@@ -206,14 +213,14 @@ static int via_initialize(struct drm_device * dev,
drm_core_ioremap_wc(&dev_priv->ring.map, dev);
- if (dev_priv->ring.map.handle == NULL) {
+ if (dev_priv->ring.map.virtual == NULL) {
via_dma_cleanup(dev);
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
return -ENOMEM;
}
- dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
+ dev_priv->ring.virtual_start = dev_priv->ring.map.virtual;
dev_priv->dma_ptr = dev_priv->ring.virtual_start;
dev_priv->dma_low = 0;
@@ -222,7 +229,7 @@ static int via_initialize(struct drm_device * dev,
dev_priv->dma_offset = init->offset;
dev_priv->last_pause_ptr = NULL;
dev_priv->hw_addr_ptr =
- (volatile uint32_t *)((char *)dev_priv->mmio->handle +
+ (volatile uint32_t *)((char *)dev_priv->mmio->virtual +
init->reg_pause_addr);
via_cmdbuf_start(dev_priv);
diff --git a/sys/dev/drm/via_map.c b/sys/dev/drm/via_map.c
index 5504a6b..687b8be 100644
--- a/sys/dev/drm/via_map.c
+++ b/sys/dev/drm/via_map.c
@@ -59,7 +59,7 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
}
dev_priv->sarea_priv =
- (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->virtual +
init->sarea_priv_offset);
dev_priv->agpAddr = init->agpAddr;
diff --git a/sys/dev/drm/via_mm.c b/sys/dev/drm/via_mm.c
index 9aaee9f..6dc185b 100644
--- a/sys/dev/drm/via_mm.c
+++ b/sys/dev/drm/via_mm.c
@@ -45,7 +45,6 @@ int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_AGP, 0,
agp->size >> VIA_MM_ALIGN_SHIFT);
-
if (ret) {
DRM_ERROR("AGP memory manager initialisation error\n");
return ret;
@@ -66,7 +65,6 @@ int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_VIDEO, 0,
fb->size >> VIA_MM_ALIGN_SHIFT);
-
if (ret) {
DRM_ERROR("VRAM memory manager initialisation error\n");
return ret;
diff --git a/sys/dev/e1000/e1000_80003es2lan.c b/sys/dev/e1000/e1000_80003es2lan.c
index db32f8c..af32ee0 100644
--- a/sys/dev/e1000/e1000_80003es2lan.c
+++ b/sys/dev/e1000/e1000_80003es2lan.c
@@ -231,7 +231,9 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
mac->rar_entry_count = E1000_RAR_ENTRIES;
/* Set if part includes ASF firmware */
mac->asf_firmware_present = TRUE;
- /* Set if manageability features are enabled. */
+ /* FWSM register */
+ mac->has_fwsm = TRUE;
+ /* ARC supported; valid only if manageability features are enabled. */
mac->arc_subsystem_valid =
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
? TRUE : FALSE;
diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c
index 96a3b2f..afeb1a0 100644
--- a/sys/dev/e1000/e1000_82571.c
+++ b/sys/dev/e1000/e1000_82571.c
@@ -313,10 +313,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
mac->rar_entry_count = E1000_RAR_ENTRIES;
/* Set if part includes ASF firmware */
mac->asf_firmware_present = TRUE;
- /* Set if manageability features are enabled. */
- mac->arc_subsystem_valid =
- (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
- ? TRUE : FALSE;
/* Adaptive IFS supported */
mac->adaptive_ifs = TRUE;
@@ -357,6 +353,16 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
mac->ops.set_lan_id = e1000_set_lan_id_single_port;
mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
mac->ops.led_on = e1000_led_on_generic;
+
+ /* FWSM register */
+ mac->has_fwsm = TRUE;
+ /*
+ * ARC supported; valid only if manageability features are
+ * enabled.
+ */
+ mac->arc_subsystem_valid =
+ (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
+ ? TRUE : FALSE;
break;
case e1000_82574:
case e1000_82583:
@@ -367,6 +373,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
default:
mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
mac->ops.led_on = e1000_led_on_generic;
+
+ /* FWSM register */
+ mac->has_fwsm = TRUE;
break;
}
@@ -1076,9 +1085,10 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
/* ...for both queues. */
switch (mac->type) {
case e1000_82573:
+ e1000_enable_tx_pkt_filtering_generic(hw);
+ /* fall through */
case e1000_82574:
case e1000_82583:
- e1000_enable_tx_pkt_filtering_generic(hw);
reg_data = E1000_READ_REG(hw, E1000_GCR);
reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
E1000_WRITE_REG(hw, E1000_GCR, reg_data);
@@ -1364,7 +1374,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
{
u32 ctrl;
- s32 ret_val;
+ s32 ret_val;
DEBUGFUNC("e1000_setup_copper_link_82571");
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index 4227556..65b3ce4 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -289,7 +289,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
/* Set if part includes ASF firmware */
mac->asf_firmware_present = TRUE;
- /* Set if manageability features are enabled. */
+ /* FWSM register */
+ mac->has_fwsm = TRUE;
+ /* ARC supported; valid only if manageability features are enabled. */
mac->arc_subsystem_valid =
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
? TRUE : FALSE;
@@ -1435,13 +1437,12 @@ static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- struct e1000_mac_info *mac = &hw->mac;
if (!(phy->ops.check_reset_block))
return;
/* If the management interface is not enabled, then power down */
- if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
+ if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
e1000_power_down_phy_copper(hw);
return;
@@ -1646,14 +1647,23 @@ out:
**/
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
{
- u32 dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
+ u32 dtxswc;
+
+ switch (hw->mac.type) {
+ case e1000_82576:
+ dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
+ if (enable)
+ dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+ else
+ dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+ E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
+ break;
+ default:
+ /* Currently no other hardware supports loopback */
+ break;
+ }
- if (enable)
- dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
- else
- dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
- E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
}
/**
diff --git a/sys/dev/e1000/e1000_82575.h b/sys/dev/e1000/e1000_82575.h
index 582f4a4..1fc7e26 100644
--- a/sys/dev/e1000/e1000_82575.h
+++ b/sys/dev/e1000/e1000_82575.h
@@ -49,8 +49,8 @@
* For 82576, there are an additional set of RARs that begin at an offset
* separate from the first set of RARs.
*/
-#define E1000_RAR_ENTRIES_82575 16
-#define E1000_RAR_ENTRIES_82576 24
+#define E1000_RAR_ENTRIES_82575 16
+#define E1000_RAR_ENTRIES_82576 24
#define E1000_RAR_ENTRIES_82580 24
#define E1000_SW_SYNCH_MB 0x00000100
#define E1000_STAT_DEV_RST_SET 0x00100000
@@ -425,6 +425,7 @@ struct e1000_adv_tx_context_desc {
#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
+
#define E1000_VLVF_ARRAY_SIZE 32
#define E1000_VLVF_VLANID_MASK 0x00000FFF
#define E1000_VLVF_POOLSEL_SHIFT 12
diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h
index 4c80ca03..7ac5d8b 100644
--- a/sys/dev/e1000/e1000_defines.h
+++ b/sys/dev/e1000/e1000_defines.h
@@ -314,6 +314,11 @@
#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
+#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */
+#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */
+#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */
+#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */
+
/* Receive Control */
#define E1000_RCTL_RST 0x00000001 /* Software reset */
#define E1000_RCTL_EN 0x00000002 /* enable */
@@ -418,6 +423,8 @@
* PHYRST_N pin */
#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external
* LINK_0 and LINK_1 pins */
+#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
+#define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
@@ -953,6 +960,8 @@
#define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
#define E1000_EITR_ITR_INT_MASK 0x0000FFFF
+/* E1000_EITR_CNT_IGNR is only for 82576 and newer */
+#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */
/* Transmit Descriptor Control */
#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
@@ -1380,6 +1389,9 @@
#define PCI_HEADER_TYPE_MULTIFUNC 0x80
#define PCIE_LINK_WIDTH_MASK 0x3F0
#define PCIE_LINK_WIDTH_SHIFT 4
+#define PCIE_LINK_SPEED_MASK 0x0F
+#define PCIE_LINK_SPEED_2500 0x01
+#define PCIE_LINK_SPEED_5000 0x02
#define PCIE_DEVICE_CONTROL2_16ms 0x0005
#ifndef ETH_ADDR_LEN
@@ -1410,7 +1422,7 @@
#define BME1000_E_PHY_ID_R2 0x01410CB1
#define I82577_E_PHY_ID 0x01540050
#define I82578_E_PHY_ID 0x004DD040
-#define I82580_I_PHY_ID 0x015403A0
+#define I82580_I_PHY_ID 0x015403A0
#define IGP04E1000_E_PHY_ID 0x02A80391
#define M88_VENDOR 0x0141
@@ -1507,6 +1519,7 @@
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
+
/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000
diff --git a/sys/dev/e1000/e1000_hw.h b/sys/dev/e1000/e1000_hw.h
index fd30173..ce5dffd 100644
--- a/sys/dev/e1000/e1000_hw.h
+++ b/sys/dev/e1000/e1000_hw.h
@@ -122,6 +122,7 @@ struct e1000_hw;
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
+
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
@@ -682,6 +683,7 @@ struct e1000_mac_info {
u8 forced_speed_duplex;
bool adaptive_ifs;
+ bool has_fwsm;
bool arc_subsystem_valid;
bool asf_firmware_present;
bool autoneg;
diff --git a/sys/dev/e1000/e1000_ich8lan.c b/sys/dev/e1000/e1000_ich8lan.c
index c40085f..6b3c25d 100644
--- a/sys/dev/e1000/e1000_ich8lan.c
+++ b/sys/dev/e1000/e1000_ich8lan.c
@@ -177,6 +177,7 @@ union ich8_hws_flash_regacc {
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
+ u32 ctrl;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_pchlan");
@@ -199,6 +200,35 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+ if ((hw->mac.type == e1000_pchlan) &&
+ (!(E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID))) {
+
+ /*
+ * The MAC-PHY interconnect may still be in SMBus mode
+ * after Sx->S0. Toggle the LANPHYPC Value bit to force
+ * the interconnect to PCIe mode, but only if there is no
+ * firmware present otherwise firmware will have done it.
+ */
+ ctrl = E1000_READ_REG(hw, E1000_CTRL);
+ ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
+ ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
+ E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
+ usec_delay(10);
+ ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
+ E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
+ msec_delay(50);
+ }
+
+ /*
+ * Reset the PHY before any acccess to it. Doing so, ensures that
+ * the PHY is in a known good state before we read/write PHY registers.
+ * The generic reset is sufficient here, because we haven't determined
+ * the PHY type yet.
+ */
+ ret_val = e1000_phy_hw_reset_generic(hw);
+ if (ret_val)
+ goto out;
+
phy->id = e1000_phy_unknown;
ret_val = e1000_get_phy_id(hw);
if (ret_val)
@@ -225,6 +255,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
phy->ops.get_cable_length = e1000_get_cable_length_82577;
phy->ops.get_info = e1000_get_phy_info_82577;
phy->ops.commit = e1000_phy_sw_reset_generic;
+ break;
case e1000_phy_82578:
phy->ops.check_polarity = e1000_check_polarity_m88;
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
@@ -431,8 +462,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
mac->rar_entry_count--;
/* Set if part includes ASF firmware */
mac->asf_firmware_present = TRUE;
- /* Set if manageability features are enabled. */
- mac->arc_subsystem_valid = TRUE;
+ /* FWSM register */
+ mac->has_fwsm = TRUE;
+ /* ARC subsystem not supported */
+ mac->arc_subsystem_valid = FALSE;
/* Adaptive IFS supported */
mac->adaptive_ifs = TRUE;
@@ -764,6 +797,9 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_reset_block_ich8lan");
+ if (hw->phy.reset_disable)
+ return E1000_BLK_PHY_RESET;
+
fwsm = E1000_READ_REG(hw, E1000_FWSM);
return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS
@@ -2684,6 +2720,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
DEBUGOUT("Auto Read Done did not complete\n");
}
}
+ /* Dummy read to clear the phy wakeup bit after lcd reset */
if (hw->mac.type == e1000_pchlan)
hw->phy.ops.read_reg(hw, BM_WUC, &reg);
@@ -2857,6 +2894,14 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_STATUS, reg);
}
+ /*
+ * work-around descriptor data corruption issue during nfs v2 udp
+ * traffic, just disable the nfs filtering capability
+ */
+ reg = E1000_READ_REG(hw, E1000_RFCTL);
+ reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
+ E1000_WRITE_REG(hw, E1000_RFCTL, reg);
+
return;
}
diff --git a/sys/dev/e1000/e1000_ich8lan.h b/sys/dev/e1000/e1000_ich8lan.h
index cc8ba16..f26b7b9 100644
--- a/sys/dev/e1000/e1000_ich8lan.h
+++ b/sys/dev/e1000/e1000_ich8lan.h
@@ -167,6 +167,9 @@
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
#define HV_KMRN_MDIO_SLOW 0x0400
+/* PHY Power Management Control */
+#define HV_PM_CTRL PHY_REG(770, 17)
+
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
/*
@@ -192,7 +195,6 @@
#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000
#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000
-
void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
diff --git a/sys/dev/e1000/e1000_mac.c b/sys/dev/e1000/e1000_mac.c
index 3c525c1..d4d2bec 100644
--- a/sys/dev/e1000/e1000_mac.c
+++ b/sys/dev/e1000/e1000_mac.c
@@ -225,17 +225,30 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_get_bus_info_pcie_generic");
bus->type = e1000_bus_type_pci_express;
- bus->speed = e1000_bus_speed_2500;
ret_val = e1000_read_pcie_cap_reg(hw,
PCIE_LINK_STATUS,
&pcie_link_status);
- if (ret_val)
+ if (ret_val) {
bus->width = e1000_bus_width_unknown;
- else
+ bus->speed = e1000_bus_speed_unknown;
+ } else {
+ switch (pcie_link_status & PCIE_LINK_SPEED_MASK) {
+ case PCIE_LINK_SPEED_2500:
+ bus->speed = e1000_bus_speed_2500;
+ break;
+ case PCIE_LINK_SPEED_5000:
+ bus->speed = e1000_bus_speed_5000;
+ break;
+ default:
+ bus->speed = e1000_bus_speed_unknown;
+ break;
+ }
+
bus->width = (enum e1000_bus_width)((pcie_link_status &
PCIE_LINK_WIDTH_MASK) >>
PCIE_LINK_WIDTH_SHIFT);
+ }
mac->ops.set_lan_id(hw);
diff --git a/sys/dev/e1000/e1000_manage.c b/sys/dev/e1000/e1000_manage.c
index 2cd85b3..0b295f8 100644
--- a/sys/dev/e1000/e1000_manage.c
+++ b/sys/dev/e1000/e1000_manage.c
@@ -78,6 +78,12 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_mng_enable_host_if_generic");
+ if (!(hw->mac.arc_subsystem_valid)) {
+ DEBUGOUT("ARC subsystem not valid.\n");
+ ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
+ goto out;
+ }
+
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if ((hicr & E1000_HICR_EN) == 0) {
@@ -365,7 +371,7 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
if (!(manc & E1000_MANC_RCV_TCO_EN))
goto out;
- if (hw->mac.arc_subsystem_valid) {
+ if (hw->mac.has_fwsm) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
factps = E1000_READ_REG(hw, E1000_FACTPS);
@@ -375,12 +381,23 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
ret_val = TRUE;
goto out;
}
- } else {
- if ((manc & E1000_MANC_SMBUS_EN) &&
- !(manc & E1000_MANC_ASF_EN)) {
+ } else if ((hw->mac.type == e1000_82574) ||
+ (hw->mac.type == e1000_82583)) {
+ u16 data;
+
+ factps = E1000_READ_REG(hw, E1000_FACTPS);
+ e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+
+ if (!(factps & E1000_FACTPS_MNGCG) &&
+ ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
+ (e1000_mng_mode_pt << 13))) {
ret_val = TRUE;
goto out;
}
+ } else if ((manc & E1000_MANC_SMBUS_EN) &&
+ !(manc & E1000_MANC_ASF_EN)) {
+ ret_val = TRUE;
+ goto out;
}
out:
diff --git a/sys/dev/e1000/e1000_phy.c b/sys/dev/e1000/e1000_phy.c
index dbc422a..24ca36f 100644
--- a/sys/dev/e1000/e1000_phy.c
+++ b/sys/dev/e1000/e1000_phy.c
@@ -3402,9 +3402,7 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw)
* e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
* @hw: pointer to the HW structure
*
- * Calls the PHY setup function to force speed and duplex. Clears the
- * auto-crossover to force MDI manually. Waits for link and returns
- * successful if link up is successful, else -E1000_ERR_PHY (-2).
+ * Calls the PHY setup function to force speed and duplex.
**/
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
{
@@ -3425,23 +3423,6 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
if (ret_val)
goto out;
- /*
- * Clear Auto-Crossover to force MDI manually. 82577 requires MDI
- * forced whenever speed and duplex are forced.
- */
- ret_val = phy->ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data);
- if (ret_val)
- goto out;
-
- phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX;
- phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX;
-
- ret_val = phy->ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data);
- if (ret_val)
- goto out;
-
- DEBUGOUT1("I82577_PHY_CTRL_2: %X\n", phy_data);
-
usec_delay(1);
if (phy->autoneg_wait_to_complete) {
diff --git a/sys/dev/e1000/e1000_regs.h b/sys/dev/e1000/e1000_regs.h
index 56418a6..b2a477e 100644
--- a/sys/dev/e1000/e1000_regs.h
+++ b/sys/dev/e1000/e1000_regs.h
@@ -65,7 +65,7 @@
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
#define E1000_SVCR 0x000F0
-#define E1000_SVT 0x000F4
+#define E1000_SVT 0x000F4
#define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
@@ -282,6 +282,17 @@
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */
+/* Virtualization statistical counters */
+#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n)))
+#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n)))
+#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n)))
+#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n)))
+#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n)))
+#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n)))
+#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n)))
+#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n)))
+#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n)))
+
#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */
@@ -386,6 +397,7 @@
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
+#define E1000_MDEF(_n) (0x05890 + (4 * (_n))) /* Mngmt Decision Filters */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index b45e478..1db9012 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -35,7 +35,6 @@
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_device_polling.h"
#include "opt_inet.h"
-#include "opt_altq.h"
#endif
#include <sys/param.h>
@@ -55,9 +54,7 @@
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
-#if __FreeBSD_version >= 700029
#include <sys/eventhandler.h>
-#endif
#include <machine/bus.h>
#include <machine/resource.h>
@@ -80,6 +77,7 @@
#include <netinet/udp.h>
#include <machine/in_cksum.h>
+#include <dev/led/led.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -95,7 +93,7 @@ int em_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char em_driver_version[] = "6.9.25";
+char em_driver_version[] = "7.0.5";
/*********************************************************************
@@ -111,51 +109,6 @@ char em_driver_version[] = "6.9.25";
static em_vendor_info_t em_vendor_info_array[] =
{
/* Intel(R) PRO/1000 Network Connection */
- { 0x8086, E1000_DEV_ID_82540EM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EM_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EP, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EP_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EP_LP, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82541EI, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541ER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541ER_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541GI, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541GI_LF, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541GI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82542, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82543GC_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82543GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82544EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82544EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82544GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82544GC_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82545EM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545EM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545GM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545GM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545GM_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82546EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_PCIE, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3,
- PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82547EI, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82547EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82547GI, PCI_ANY_ID, PCI_ANY_ID, 0},
-
{ 0x8086, E1000_DEV_ID_82571EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_82571EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_82571EB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
@@ -238,10 +191,11 @@ static int em_shutdown(device_t);
static int em_suspend(device_t);
static int em_resume(device_t);
static void em_start(struct ifnet *);
-static void em_start_locked(struct ifnet *ifp);
-#if __FreeBSD_version >= 800000
+static void em_start_locked(struct ifnet *, struct tx_ring *);
+#ifdef EM_MULTIQUEUE
static int em_mq_start(struct ifnet *, struct mbuf *);
-static int em_mq_start_locked(struct ifnet *, struct mbuf *);
+static int em_mq_start_locked(struct ifnet *,
+ struct tx_ring *, struct mbuf *);
static void em_qflush(struct ifnet *);
#endif
static int em_ioctl(struct ifnet *, u_long, caddr_t);
@@ -252,55 +206,49 @@ static void em_media_status(struct ifnet *, struct ifmediareq *);
static int em_media_change(struct ifnet *);
static void em_identify_hardware(struct adapter *);
static int em_allocate_pci_resources(struct adapter *);
-static int em_allocate_legacy(struct adapter *adapter);
-static int em_allocate_msix(struct adapter *adapter);
+static int em_allocate_legacy(struct adapter *);
+static int em_allocate_msix(struct adapter *);
+static int em_allocate_queues(struct adapter *);
static int em_setup_msix(struct adapter *);
static void em_free_pci_resources(struct adapter *);
static void em_local_timer(void *);
-static int em_hardware_init(struct adapter *);
+static void em_reset(struct adapter *);
static void em_setup_interface(device_t, struct adapter *);
+
static void em_setup_transmit_structures(struct adapter *);
static void em_initialize_transmit_unit(struct adapter *);
+static int em_allocate_transmit_buffers(struct tx_ring *);
+static void em_free_transmit_structures(struct adapter *);
+static void em_free_transmit_buffers(struct tx_ring *);
+
static int em_setup_receive_structures(struct adapter *);
+static int em_allocate_receive_buffers(struct rx_ring *);
static void em_initialize_receive_unit(struct adapter *);
+static void em_free_receive_structures(struct adapter *);
+static void em_free_receive_buffers(struct rx_ring *);
+
static void em_enable_intr(struct adapter *);
static void em_disable_intr(struct adapter *);
-static void em_free_transmit_structures(struct adapter *);
-static void em_free_receive_structures(struct adapter *);
static void em_update_stats_counters(struct adapter *);
-static void em_txeof(struct adapter *);
-static void em_tx_purge(struct adapter *);
-static int em_allocate_receive_structures(struct adapter *);
-static int em_allocate_transmit_structures(struct adapter *);
-static int em_rxeof(struct adapter *, int);
+static bool em_txeof(struct tx_ring *);
+static int em_rxeof(struct rx_ring *, int);
#ifndef __NO_STRICT_ALIGNMENT
-static int em_fixup_rx(struct adapter *);
+static int em_fixup_rx(struct rx_ring *);
#endif
-static void em_receive_checksum(struct adapter *, struct e1000_rx_desc *,
- struct mbuf *);
-static void em_transmit_checksum_setup(struct adapter *, struct mbuf *,
- u32 *, u32 *);
-#if __FreeBSD_version >= 700000
-static bool em_tso_setup(struct adapter *, struct mbuf *,
+static void em_receive_checksum(struct e1000_rx_desc *, struct mbuf *);
+static void em_transmit_checksum_setup(struct tx_ring *, struct mbuf *,
u32 *, u32 *);
-#endif /* FreeBSD_version >= 700000 */
+static bool em_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *);
static void em_set_promisc(struct adapter *);
static void em_disable_promisc(struct adapter *);
static void em_set_multi(struct adapter *);
static void em_print_hw_stats(struct adapter *);
static void em_update_link_status(struct adapter *);
-static int em_get_buf(struct adapter *, int);
-#if __FreeBSD_version >= 700029
+static void em_refresh_mbufs(struct rx_ring *, int);
static void em_register_vlan(void *, struct ifnet *, u16);
static void em_unregister_vlan(void *, struct ifnet *, u16);
static void em_setup_vlan_hw_support(struct adapter *);
-#endif
-static int em_xmit(struct adapter *, struct mbuf **);
-static void em_smartspeed(struct adapter *);
-static int em_82547_fifo_workaround(struct adapter *, int);
-static void em_82547_update_fifo_head(struct adapter *, int);
-static int em_82547_tx_fifo_reset(struct adapter *);
-static void em_82547_move_tail(void *);
+static int em_xmit(struct tx_ring *, struct mbuf **);
static int em_dma_malloc(struct adapter *, bus_size_t,
struct em_dma_alloc *, int);
static void em_dma_free(struct adapter *, struct em_dma_alloc *);
@@ -309,8 +257,6 @@ static void em_print_nvm_info(struct adapter *);
static int em_is_valid_ether_addr(u8 *);
static int em_sysctl_stats(SYSCTL_HANDLER_ARGS);
static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
-static u32 em_fill_descriptors (bus_addr_t address, u32 length,
- PDESC_ARRAY desc_array);
static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
static void em_add_int_delay_sysctl(struct adapter *, const char *,
const char *, struct em_int_delay_info *, int, int);
@@ -322,28 +268,20 @@ static void em_release_hw_control(struct adapter *);
static void em_get_wakeup(device_t);
static void em_enable_wakeup(device_t);
static int em_enable_phy_wakeup(struct adapter *);
+static void em_led_func(void *, int);
-#ifdef EM_LEGACY_IRQ
-static void em_intr(void *);
-#else /* FAST IRQ */
-#if __FreeBSD_version < 700000
-static void em_irq_fast(void *);
-#else
static int em_irq_fast(void *);
-#endif
/* MSIX handlers */
static void em_msix_tx(void *);
static void em_msix_rx(void *);
static void em_msix_link(void *);
-static void em_handle_rx(void *context, int pending);
static void em_handle_tx(void *context, int pending);
-
-static void em_handle_rxtx(void *context, int pending);
+static void em_handle_rx(void *context, int pending);
static void em_handle_link(void *context, int pending);
+
static void em_add_rx_process_limit(struct adapter *, const char *,
const char *, int *, int);
-#endif /* ~EM_LEGACY_IRQ */
#ifdef DEVICE_POLLING
static poll_handler_t em_poll;
@@ -368,7 +306,7 @@ static driver_t em_driver = {
"em", em_methods, sizeof(struct adapter),
};
-static devclass_t em_devclass;
+devclass_t em_devclass;
DRIVER_MODULE(em, pci, em_driver, em_devclass, 0, 0);
MODULE_DEPEND(em, pci, 1, 1, 1);
MODULE_DEPEND(em, ether, 1, 1, 1);
@@ -388,31 +326,35 @@ MODULE_DEPEND(em, ether, 1, 1, 1);
static int em_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
static int em_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
-static int em_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
-static int em_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV);
-static int em_rxd = EM_DEFAULT_RXD;
-static int em_txd = EM_DEFAULT_TXD;
-static int em_smart_pwr_down = FALSE;
-/* Controls whether promiscuous also shows bad packets */
-static int em_debug_sbp = FALSE;
-/* Local switch for MSI/MSIX */
-static int em_enable_msi = TRUE;
-
TUNABLE_INT("hw.em.tx_int_delay", &em_tx_int_delay_dflt);
TUNABLE_INT("hw.em.rx_int_delay", &em_rx_int_delay_dflt);
+
+static int em_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
+static int em_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV);
TUNABLE_INT("hw.em.tx_abs_int_delay", &em_tx_abs_int_delay_dflt);
TUNABLE_INT("hw.em.rx_abs_int_delay", &em_rx_abs_int_delay_dflt);
+
+static int em_rxd = EM_DEFAULT_RXD;
+static int em_txd = EM_DEFAULT_TXD;
TUNABLE_INT("hw.em.rxd", &em_rxd);
TUNABLE_INT("hw.em.txd", &em_txd);
+
+static int em_smart_pwr_down = FALSE;
TUNABLE_INT("hw.em.smart_pwr_down", &em_smart_pwr_down);
+
+/* Controls whether promiscuous also shows bad packets */
+static int em_debug_sbp = FALSE;
TUNABLE_INT("hw.em.sbp", &em_debug_sbp);
-TUNABLE_INT("hw.em.enable_msi", &em_enable_msi);
-#ifndef EM_LEGACY_IRQ
+/* Local controls for MSI/MSIX */
+static int em_enable_msix = TRUE;
+static int em_msix_queues = 2; /* for 82574, can be 1 or 2 */
+TUNABLE_INT("hw.em.enable_msix", &em_enable_msix);
+TUNABLE_INT("hw.em.msix_queues", &em_msix_queues);
+
/* How many packets rxeof tries to clean at a time */
static int em_rx_process_limit = 100;
TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit);
-#endif
/* Flow control setting - default to FULL */
static int em_fc_setting = e1000_fc_full;
@@ -494,7 +436,6 @@ static int
em_attach(device_t dev)
{
struct adapter *adapter;
- int tsize, rsize;
int error = 0;
INIT_DEBUGOUT("em_attach: begin");
@@ -502,8 +443,6 @@ em_attach(device_t dev)
adapter = device_get_softc(dev);
adapter->dev = adapter->osdep.dev = dev;
EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
- EM_TX_LOCK_INIT(adapter, device_get_nameunit(dev));
- EM_RX_LOCK_INIT(adapter, device_get_nameunit(dev));
/* SYSCTL stuff */
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
@@ -517,7 +456,6 @@ em_attach(device_t dev)
em_sysctl_stats, "I", "Statistics");
callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
- callout_init_mtx(&adapter->tx_fifo_timer, &adapter->tx_mtx, 0);
/* Determine hardware and mac info */
em_identify_hardware(adapter);
@@ -571,25 +509,21 @@ em_attach(device_t dev)
em_add_int_delay_sysctl(adapter, "tx_int_delay",
"transmit interrupt delay in usecs", &adapter->tx_int_delay,
E1000_REGISTER(&adapter->hw, E1000_TIDV), em_tx_int_delay_dflt);
- if (adapter->hw.mac.type >= e1000_82540) {
- em_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
- "receive interrupt delay limit in usecs",
- &adapter->rx_abs_int_delay,
- E1000_REGISTER(&adapter->hw, E1000_RADV),
- em_rx_abs_int_delay_dflt);
- em_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
- "transmit interrupt delay limit in usecs",
- &adapter->tx_abs_int_delay,
- E1000_REGISTER(&adapter->hw, E1000_TADV),
- em_tx_abs_int_delay_dflt);
- }
+ em_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
+ "receive interrupt delay limit in usecs",
+ &adapter->rx_abs_int_delay,
+ E1000_REGISTER(&adapter->hw, E1000_RADV),
+ em_rx_abs_int_delay_dflt);
+ em_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
+ "transmit interrupt delay limit in usecs",
+ &adapter->tx_abs_int_delay,
+ E1000_REGISTER(&adapter->hw, E1000_TADV),
+ em_tx_abs_int_delay_dflt);
-#ifndef EM_LEGACY_IRQ
/* Sysctls for limiting the amount of work done in the taskqueue */
em_add_rx_process_limit(adapter, "rx_processing_limit",
"max number of rx packets to process", &adapter->rx_process_limit,
em_rx_process_limit);
-#endif
/*
* Validate number of transmit and receive descriptors. It
@@ -597,18 +531,15 @@ em_attach(device_t dev)
* of E1000_DBA_ALIGN.
*/
if (((em_txd * sizeof(struct e1000_tx_desc)) % EM_DBA_ALIGN) != 0 ||
- (adapter->hw.mac.type >= e1000_82544 && em_txd > EM_MAX_TXD) ||
- (adapter->hw.mac.type < e1000_82544 && em_txd > EM_MAX_TXD_82543) ||
- (em_txd < EM_MIN_TXD)) {
+ (em_txd > EM_MAX_TXD) || (em_txd < EM_MIN_TXD)) {
device_printf(dev, "Using %d TX descriptors instead of %d!\n",
EM_DEFAULT_TXD, em_txd);
adapter->num_tx_desc = EM_DEFAULT_TXD;
} else
adapter->num_tx_desc = em_txd;
+
if (((em_rxd * sizeof(struct e1000_rx_desc)) % EM_DBA_ALIGN) != 0 ||
- (adapter->hw.mac.type >= e1000_82544 && em_rxd > EM_MAX_RXD) ||
- (adapter->hw.mac.type < e1000_82544 && em_rxd > EM_MAX_RXD_82543) ||
- (em_rxd < EM_MIN_RXD)) {
+ (em_rxd > EM_MAX_RXD) || (em_rxd < EM_MIN_RXD)) {
device_printf(dev, "Using %d RX descriptors instead of %d!\n",
EM_DEFAULT_RXD, em_rxd);
adapter->num_rx_desc = EM_DEFAULT_RXD;
@@ -618,10 +549,6 @@ em_attach(device_t dev)
adapter->hw.mac.autoneg = DO_AUTO_NEG;
adapter->hw.phy.autoneg_wait_to_complete = FALSE;
adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
- adapter->rx_buffer_len = 2048;
-
- e1000_init_script_state_82541(&adapter->hw, TRUE);
- e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE);
/* Copper options */
if (adapter->hw.phy.media_type == e1000_media_type_copper) {
@@ -643,29 +570,13 @@ em_attach(device_t dev)
*/
adapter->hw.mac.report_tx_early = 1;
- tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
- EM_DBA_ALIGN);
-
- /* Allocate Transmit Descriptor ring */
- if (em_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
- device_printf(dev, "Unable to allocate tx_desc memory\n");
- error = ENOMEM;
- goto err_tx_desc;
- }
- adapter->tx_desc_base =
- (struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
-
- rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
- EM_DBA_ALIGN);
-
- /* Allocate Receive Descriptor ring */
- if (em_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
- device_printf(dev, "Unable to allocate rx_desc memory\n");
+ /*
+ ** Get queue/ring memory
+ */
+ if (em_allocate_queues(adapter)) {
error = ENOMEM;
- goto err_rx_desc;
+ goto err_pci;
}
- adapter->rx_desc_base =
- (struct e1000_rx_desc *)adapter->rxdma.dma_vaddr;
/*
** Start from a known state, this is
@@ -685,7 +596,7 @@ em_attach(device_t dev)
device_printf(dev,
"The EEPROM Checksum Is Not Valid\n");
error = EIO;
- goto err_hw_init;
+ goto err_late;
}
}
@@ -694,45 +605,24 @@ em_attach(device_t dev)
device_printf(dev, "EEPROM read error while reading MAC"
" address\n");
error = EIO;
- goto err_hw_init;
+ goto err_late;
}
if (!em_is_valid_ether_addr(adapter->hw.mac.addr)) {
device_printf(dev, "Invalid MAC address\n");
error = EIO;
- goto err_hw_init;
- }
-
- /* Initialize the hardware */
- if (em_hardware_init(adapter)) {
- device_printf(dev, "Unable to initialize the hardware\n");
- error = EIO;
- goto err_hw_init;
- }
-
- /* Allocate transmit descriptors and buffers */
- if (em_allocate_transmit_structures(adapter)) {
- device_printf(dev, "Could not setup transmit structures\n");
- error = ENOMEM;
- goto err_tx_struct;
- }
-
- /* Allocate receive descriptors and buffers */
- if (em_allocate_receive_structures(adapter)) {
- device_printf(dev, "Could not setup receive structures\n");
- error = ENOMEM;
- goto err_rx_struct;
+ goto err_late;
}
/*
** Do interrupt configuration
*/
- if (adapter->msi > 1) /* Do MSI/X */
+ if (adapter->msix > 1) /* Do MSIX */
error = em_allocate_msix(adapter);
else /* MSI or Legacy */
error = em_allocate_legacy(adapter);
if (error)
- goto err_rx_struct;
+ goto err_late;
/*
* Get Wake-on-Lan and Management info for later use
@@ -742,6 +632,8 @@ em_attach(device_t dev)
/* Setup OS specific network interface */
em_setup_interface(dev, adapter);
+ em_reset(adapter);
+
/* Initialize statistics */
em_update_stats_counters(adapter);
@@ -753,20 +645,11 @@ em_attach(device_t dev)
device_printf(dev,
"PHY reset is blocked due to SOL/IDER session.\n");
- /* Do we need workaround for 82544 PCI-X adapter? */
- if (adapter->hw.bus.type == e1000_bus_type_pcix &&
- adapter->hw.mac.type == e1000_82544)
- adapter->pcix_82544 = TRUE;
- else
- adapter->pcix_82544 = FALSE;
-
-#if __FreeBSD_version >= 700029
/* Register for VLAN events */
adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
em_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
em_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
-#endif
/* Non-AMT based hardware can now take control from firmware */
if (adapter->has_manage && !adapter->has_amt)
@@ -775,23 +658,19 @@ em_attach(device_t dev)
/* Tell the stack that the interface is not active */
adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ adapter->led_dev = led_create(em_led_func, adapter,
+ device_get_nameunit(dev));
+
INIT_DEBUGOUT("em_attach: end");
return (0);
-err_rx_struct:
+err_late:
em_free_transmit_structures(adapter);
-err_tx_struct:
-err_hw_init:
+ em_free_receive_structures(adapter);
em_release_hw_control(adapter);
- em_dma_free(adapter, &adapter->rxdma);
-err_rx_desc:
- em_dma_free(adapter, &adapter->txdma);
-err_tx_desc:
err_pci:
em_free_pci_resources(adapter);
- EM_TX_LOCK_DESTROY(adapter);
- EM_RX_LOCK_DESTROY(adapter);
EM_CORE_LOCK_DESTROY(adapter);
return (error);
@@ -816,11 +695,7 @@ em_detach(device_t dev)
INIT_DEBUGOUT("em_detach: begin");
/* Make sure VLANS are not using driver */
-#if __FreeBSD_version >= 700000
if (adapter->ifp->if_vlantrunk != NULL) {
-#else
- if (adapter->ifp->if_nvlans != 0) {
-#endif
device_printf(dev,"Vlan in use, detach first\n");
return (EBUSY);
}
@@ -831,27 +706,24 @@ em_detach(device_t dev)
#endif
EM_CORE_LOCK(adapter);
- EM_TX_LOCK(adapter);
adapter->in_detach = 1;
em_stop(adapter);
+ EM_CORE_UNLOCK(adapter);
+ EM_CORE_LOCK_DESTROY(adapter);
+
e1000_phy_hw_reset(&adapter->hw);
em_release_manageability(adapter);
+ em_release_hw_control(adapter);
- EM_TX_UNLOCK(adapter);
- EM_CORE_UNLOCK(adapter);
-
-#if __FreeBSD_version >= 700029
/* Unregister VLAN events */
if (adapter->vlan_attach != NULL)
EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
if (adapter->vlan_detach != NULL)
EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
-#endif
ether_ifdetach(adapter->ifp);
callout_drain(&adapter->timer);
- callout_drain(&adapter->tx_fifo_timer);
em_free_pci_resources(adapter);
bus_generic_detach(dev);
@@ -860,22 +732,7 @@ em_detach(device_t dev)
em_free_transmit_structures(adapter);
em_free_receive_structures(adapter);
- /* Free Transmit Descriptor ring */
- if (adapter->tx_desc_base) {
- em_dma_free(adapter, &adapter->txdma);
- adapter->tx_desc_base = NULL;
- }
-
- /* Free Receive Descriptor ring */
- if (adapter->rx_desc_base) {
- em_dma_free(adapter, &adapter->rxdma);
- adapter->rx_desc_base = NULL;
- }
-
em_release_hw_control(adapter);
- EM_TX_LOCK_DESTROY(adapter);
- EM_RX_LOCK_DESTROY(adapter);
- EM_CORE_LOCK_DESTROY(adapter);
return (0);
}
@@ -917,6 +774,9 @@ em_resume(device_t dev)
struct adapter *adapter = device_get_softc(dev);
struct ifnet *ifp = adapter->ifp;
+ if (adapter->led_dev != NULL)
+ led_destroy(adapter->led_dev);
+
EM_CORE_LOCK(adapter);
em_init_locked(adapter);
em_init_manageability(adapter);
@@ -937,71 +797,60 @@ em_resume(device_t dev)
* the packet is requeued.
**********************************************************************/
-#if __FreeBSD_version >= 800000
+#ifdef EM_MULTIQUEUE
static int
-em_mq_start_locked(struct ifnet *ifp, struct mbuf *m)
+em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
{
- struct adapter *adapter = ifp->if_softc;
- struct mbuf *next;
- int error = E1000_SUCCESS;
+ struct adapter *adapter = txr->adapter;
+ struct mbuf *next;
+ int err = 0, enq = 0;
- EM_TX_LOCK_ASSERT(adapter);
- /* To allow being called from a tasklet */
- if (m == NULL)
- goto process;
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING || adapter->link_active == 0) {
+ if (m != NULL)
+ err = drbr_enqueue(ifp, txr->br, m);
+ return (err);
+ }
- if (((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING)
- || (!adapter->link_active)) {
- error = drbr_enqueue(ifp, adapter->br, m);
- return (error);
- } else if (!drbr_needs_enqueue(ifp, adapter->br) &&
- (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) {
- if ((error = em_xmit(adapter, &m)) != 0) {
- if (m)
- error = drbr_enqueue(ifp, adapter->br, m);
- return (error);
- } else {
- /*
- * We've bypassed the buf ring so we need to update
- * ifp directly
- */
- drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
- /*
- ** Send a copy of the frame to the BPF
- ** listener and set the watchdog on.
- */
- ETHER_BPF_MTAP(ifp, m);
- adapter->watchdog_check = TRUE;
- }
- } else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0)
- return (error);
-
-process:
- if (drbr_empty(ifp, adapter->br))
- return(error);
- /* Process the queue */
- while (TRUE) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- break;
- next = drbr_dequeue(ifp, adapter->br);
- if (next == NULL)
- break;
- if ((error = em_xmit(adapter, &next)) != 0) {
- if (next != NULL)
- error = drbr_enqueue(ifp, adapter->br, next);
+ /* Call cleanup if number of TX descriptors low */
+ if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
+ em_txeof(txr);
+
+ enq = 0;
+ if (m == NULL) {
+ next = drbr_dequeue(ifp, txr->br);
+ } else if (drbr_needs_enqueue(ifp, txr->br)) {
+ if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
+ return (err);
+ next = drbr_dequeue(ifp, txr->br);
+ } else
+ next = m;
+
+ /* Process the queue */
+ while (next != NULL) {
+ if ((err = em_xmit(txr, &next)) != 0) {
+ if (next != NULL)
+ err = drbr_enqueue(ifp, txr->br, next);
break;
}
+ enq++;
drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
- ETHER_BPF_MTAP(ifp, next);
- /* Set the watchdog */
- adapter->watchdog_check = TRUE;
- }
-
- if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ ETHER_BPF_MTAP(ifp, next);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
+ if (txr->tx_avail < EM_MAX_SCATTER) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+ next = drbr_dequeue(ifp, txr->br);
+ }
- return (error);
+ if (enq > 0) {
+ /* Set the watchdog */
+ txr->watchdog_check = TRUE;
+ txr->watchdog_time = ticks;
+ }
+ return (err);
}
/*
@@ -1011,50 +860,72 @@ process:
static int
em_mq_start(struct ifnet *ifp, struct mbuf *m)
{
-
- struct adapter *adapter = ifp->if_softc;
- int error = 0;
+ struct adapter *adapter = ifp->if_softc;
+ struct tx_ring *txr;
+ int i, error = 0;
+
+ /* Which queue to use */
+ if ((m->m_flags & M_FLOWID) != 0)
+ i = m->m_pkthdr.flowid % adapter->num_queues;
+ else
+ i = curcpu % adapter->num_queues;
+
+ txr = &adapter->tx_rings[i];
- if (EM_TX_TRYLOCK(adapter)) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- error = em_mq_start_locked(ifp, m);
- EM_TX_UNLOCK(adapter);
+ if (EM_TX_TRYLOCK(txr)) {
+ error = em_mq_start_locked(ifp, txr, m);
+ EM_TX_UNLOCK(txr);
} else
- error = drbr_enqueue(ifp, adapter->br, m);
+ error = drbr_enqueue(ifp, txr->br, m);
return (error);
}
+/*
+** Flush all ring buffers
+*/
static void
em_qflush(struct ifnet *ifp)
{
- struct mbuf *m;
- struct adapter *adapter = (struct adapter *)ifp->if_softc;
+ struct adapter *adapter = ifp->if_softc;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct mbuf *m;
- EM_TX_LOCK(adapter);
- while ((m = buf_ring_dequeue_sc(adapter->br)) != NULL)
- m_freem(m);
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ EM_TX_LOCK(txr);
+ while ((m = buf_ring_dequeue_sc(txr->br)) != NULL)
+ m_freem(m);
+ EM_TX_UNLOCK(txr);
+ }
if_qflush(ifp);
- EM_TX_UNLOCK(adapter);
}
-#endif /* FreeBSD_version */
+
+#endif /* EM_MULTIQUEUE */
static void
-em_start_locked(struct ifnet *ifp)
+em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
{
struct adapter *adapter = ifp->if_softc;
struct mbuf *m_head;
- EM_TX_LOCK_ASSERT(adapter);
+ EM_TX_LOCK_ASSERT(txr);
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING)
return;
+
if (!adapter->link_active)
return;
- while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ /* Call cleanup if number of TX descriptors low */
+ if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
+ em_txeof(txr);
+ while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ if (txr->tx_avail < EM_MAX_SCATTER) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL)
break;
@@ -1062,7 +933,7 @@ em_start_locked(struct ifnet *ifp)
* Encapsulation can modify our pointer, and or make it
* NULL on failure. In that event, we can't requeue.
*/
- if (em_xmit(adapter, &m_head)) {
+ if (em_xmit(txr, &m_head)) {
if (m_head == NULL)
break;
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
@@ -1074,10 +945,9 @@ em_start_locked(struct ifnet *ifp)
ETHER_BPF_MTAP(ifp, m_head);
/* Set timeout in case hardware has problems transmitting. */
- adapter->watchdog_check = TRUE;
+ txr->watchdog_time = ticks;
+ txr->watchdog_check = TRUE;
}
- if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return;
}
@@ -1085,12 +955,15 @@ em_start_locked(struct ifnet *ifp)
static void
em_start(struct ifnet *ifp)
{
- struct adapter *adapter = ifp->if_softc;
+ struct adapter *adapter = ifp->if_softc;
+ struct tx_ring *txr = adapter->tx_rings;
- EM_TX_LOCK(adapter);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- em_start_locked(ifp);
- EM_TX_UNLOCK(adapter);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ EM_TX_LOCK(txr);
+ em_start_locked(ifp, txr);
+ EM_TX_UNLOCK(txr);
+ }
+ return;
}
/*********************************************************************
@@ -1140,37 +1013,23 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
case SIOCSIFMTU:
{
int max_frame_size;
- u16 eeprom_data = 0;
IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
EM_CORE_LOCK(adapter);
switch (adapter->hw.mac.type) {
- case e1000_82573:
- /*
- * 82573 only supports jumbo frames
- * if ASPM is disabled.
- */
- e1000_read_nvm(&adapter->hw,
- NVM_INIT_3GIO_3, 1, &eeprom_data);
- if (eeprom_data & NVM_WORD1A_ASPM_MASK) {
- max_frame_size = ETHER_MAX_LEN;
- break;
- }
- /* Allow Jumbo frames - fall thru */
case e1000_82571:
case e1000_82572:
case e1000_ich9lan:
case e1000_ich10lan:
case e1000_82574:
- case e1000_80003es2lan: /* Limit Jumbo Frame size */
+ case e1000_80003es2lan: /* 9K Jumbo Frame size */
max_frame_size = 9234;
break;
case e1000_pchlan:
max_frame_size = 4096;
break;
/* Adapters that do not support jumbo frames */
- case e1000_82542:
case e1000_82583:
case e1000_ich8lan:
max_frame_size = ETHER_MAX_LEN;
@@ -1206,11 +1065,8 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
} else
em_init_locked(adapter);
} else
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- EM_TX_LOCK(adapter);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
em_stop(adapter);
- EM_TX_UNLOCK(adapter);
- }
adapter->if_flags = ifp->if_flags;
EM_CORE_UNLOCK(adapter);
break;
@@ -1221,10 +1077,6 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
EM_CORE_LOCK(adapter);
em_disable_intr(adapter);
em_set_multi(adapter);
- if (adapter->hw.mac.type == e1000_82542 &&
- adapter->hw.revision_id == E1000_REVISION_2) {
- em_initialize_receive_unit(adapter);
- }
#ifdef DEVICE_POLLING
if (!(ifp->if_capenable & IFCAP_POLLING))
#endif
@@ -1278,22 +1130,18 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_capenable ^= IFCAP_HWCSUM;
reinit = 1;
}
-#if __FreeBSD_version >= 700000
if (mask & IFCAP_TSO4) {
ifp->if_capenable ^= IFCAP_TSO4;
reinit = 1;
}
-#endif
if (mask & IFCAP_VLAN_HWTAGGING) {
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
reinit = 1;
}
-
if (mask & IFCAP_VLAN_HWFILTER) {
ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
reinit = 1;
}
-
if ((mask & IFCAP_WOL) &&
(ifp->if_capabilities & IFCAP_WOL) != 0) {
if (mask & IFCAP_WOL_MCAST)
@@ -1301,12 +1149,9 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (mask & IFCAP_WOL_MAGIC)
ifp->if_capenable ^= IFCAP_WOL_MAGIC;
}
-
if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING))
em_init(adapter);
-#if __FreeBSD_version >= 700000
VLAN_CAPABILITIES(ifp);
-#endif
break;
}
@@ -1341,33 +1186,15 @@ em_init_locked(struct adapter *adapter)
EM_CORE_LOCK_ASSERT(adapter);
- EM_TX_LOCK(adapter);
- em_stop(adapter);
- EM_TX_UNLOCK(adapter);
+ em_disable_intr(adapter);
+ callout_stop(&adapter->timer);
/*
* Packet Buffer Allocation (PBA)
* Writing PBA sets the receive portion of the buffer
* the remainder is used for the transmit buffer.
- *
- * Devices before the 82547 had a Packet Buffer of 64K.
- * Default allocation: PBA=48K for Rx, leaving 16K for Tx.
- * After the 82547 the buffer was reduced to 40K.
- * Default allocation: PBA=30K for Rx, leaving 10K for Tx.
- * Note: default does not leave enough room for Jumbo Frame >10k.
*/
switch (adapter->hw.mac.type) {
- case e1000_82547:
- case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */
- if (adapter->max_frame_size > 8192)
- pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */
- else
- pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */
- adapter->tx_fifo_head = 0;
- adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT;
- adapter->tx_fifo_size =
- (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT;
- break;
/* Total Packet Buffer on these is 48K */
case e1000_82571:
case e1000_82572:
@@ -1390,7 +1217,6 @@ em_init_locked(struct adapter *adapter)
pba = E1000_PBA_8K;
break;
default:
- /* Devices before 82547 had a Packet Buffer of 64K. */
if (adapter->max_frame_size > 8192)
pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
else
@@ -1420,14 +1246,13 @@ em_init_locked(struct adapter *adapter)
}
/* Initialize the hardware */
- if (em_hardware_init(adapter)) {
- device_printf(dev, "Unable to initialize the hardware\n");
- return;
- }
+ em_reset(adapter);
em_update_link_status(adapter);
/* Setup VLAN support, basic and offload if available */
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
+
+ /* Use real VLAN Filter support? */
if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
/* Use real VLAN Filter support */
@@ -1442,14 +1267,10 @@ em_init_locked(struct adapter *adapter)
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
- if (adapter->hw.mac.type >= e1000_82543) {
- if (ifp->if_capenable & IFCAP_TXCSUM)
- ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
-#if __FreeBSD_version >= 700000
- if (ifp->if_capenable & IFCAP_TSO4)
- ifp->if_hwassist |= CSUM_TSO;
-#endif
- }
+ if (ifp->if_capenable & IFCAP_TXCSUM)
+ ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
+ if (ifp->if_capenable & IFCAP_TSO4)
+ ifp->if_hwassist |= CSUM_TSO;
/* Configure for OS presence */
em_init_manageability(adapter);
@@ -1464,9 +1285,7 @@ em_init_locked(struct adapter *adapter)
/* Prepare receive descriptors and buffers */
if (em_setup_receive_structures(adapter)) {
device_printf(dev, "Could not setup receive structures\n");
- EM_TX_LOCK(adapter);
em_stop(adapter);
- EM_TX_UNLOCK(adapter);
return;
}
em_initialize_receive_unit(adapter);
@@ -1486,14 +1305,8 @@ em_init_locked(struct adapter *adapter)
tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
tmp |= E1000_CTRL_EXT_PBA_CLR;
E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp);
- /*
- ** Set the IVAR - interrupt vector routing.
- ** Each nibble represents a vector, high bit
- ** is enable, other 3 bits are the MSIX table
- ** entry, we map RXQ0 to 0, TXQ0 to 1, and
- ** Link (other) to 2, hence the magic number.
- */
- E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908);
+ /* Set the IVAR - interrupt vector routing. */
+ E1000_WRITE_REG(&adapter->hw, E1000_IVAR, adapter->ivars);
}
#ifdef DEVICE_POLLING
@@ -1529,13 +1342,15 @@ em_init(void *arg)
#ifdef DEVICE_POLLING
/*********************************************************************
*
- * Legacy polling routine
+ * Legacy polling routine: note this only works with single queue
*
*********************************************************************/
static int
em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
struct adapter *adapter = ifp->if_softc;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct rx_ring *rxr = adapter->rx_rings;
u32 reg_icr, rx_done = 0;
EM_CORE_LOCK(adapter);
@@ -1546,147 +1361,42 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
if (cmd == POLL_AND_CHECK_STATUS) {
reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
- /* Link status change */
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ callout_stop(&adapter->timer);
adapter->hw.mac.get_link_status = 1;
em_update_link_status(adapter);
+ callout_reset(&adapter->timer, hz,
+ em_local_timer, adapter);
}
- if (reg_icr & E1000_ICR_RXO)
- adapter->rx_overruns++;
}
EM_CORE_UNLOCK(adapter);
- rx_done = em_rxeof(adapter, count);
+ EM_RX_LOCK(rxr);
+ rx_done = em_rxeof(rxr, count);
+ EM_RX_UNLOCK(rxr);
- EM_TX_LOCK(adapter);
- em_txeof(adapter);
-#if __FreeBSD_version >= 800000
- if (!drbr_empty(ifp, adapter->br))
- em_mq_start_locked(ifp, NULL);
+ EM_TX_LOCK(txr);
+ em_txeof(txr);
+#ifdef EM_MULTIQUEUE
+ if (!drbr_empty(ifp, txr->br))
+ em_mq_start_locked(ifp, txr, NULL);
#else
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- em_start_locked(ifp);
+ em_start_locked(ifp, txr);
#endif
- EM_TX_UNLOCK(adapter);
+ EM_TX_UNLOCK(txr);
+
return (rx_done);
}
#endif /* DEVICE_POLLING */
-#ifdef EM_LEGACY_IRQ
-/*********************************************************************
- *
- * Legacy Interrupt Service routine
- *
- *********************************************************************/
-
-static void
-em_intr(void *arg)
-{
- struct adapter *adapter = arg;
- struct ifnet *ifp = adapter->ifp;
- u32 reg_icr;
-
-
- if (ifp->if_capenable & IFCAP_POLLING)
- return;
-
- EM_CORE_LOCK(adapter);
- reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
- if (reg_icr & E1000_ICR_RXO)
- adapter->rx_overruns++;
- if ((reg_icr == 0xffffffff) || (reg_icr == 0)||
- (adapter->hw.mac.type >= e1000_82571 &&
- (reg_icr & E1000_ICR_INT_ASSERTED) == 0))
- goto out;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- goto out;
-
- if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- callout_stop(&adapter->timer);
- adapter->hw.mac.get_link_status = 1;
- em_update_link_status(adapter);
- /* Deal with TX cruft when link lost */
- em_tx_purge(adapter);
- callout_reset(&adapter->timer, hz,
- em_local_timer, adapter);
- goto out;
- }
-
- EM_TX_LOCK(adapter);
- em_txeof(adapter);
- em_rxeof(adapter, -1);
- em_txeof(adapter);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- em_start_locked(ifp);
- EM_TX_UNLOCK(adapter);
-
-out:
- EM_CORE_UNLOCK(adapter);
- return;
-}
-
-#else /* EM_FAST_IRQ, then fast interrupt routines only */
-
-static void
-em_handle_link(void *context, int pending)
-{
- struct adapter *adapter = context;
- struct ifnet *ifp = adapter->ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- return;
-
- EM_CORE_LOCK(adapter);
- callout_stop(&adapter->timer);
- em_update_link_status(adapter);
- /* Deal with TX cruft when link lost */
- em_tx_purge(adapter);
- callout_reset(&adapter->timer, hz, em_local_timer, adapter);
- EM_CORE_UNLOCK(adapter);
-}
-
-
-/* Combined RX/TX handler, used by Legacy and MSI */
-static void
-em_handle_rxtx(void *context, int pending)
-{
- struct adapter *adapter = context;
- struct ifnet *ifp = adapter->ifp;
-
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if (em_rxeof(adapter, adapter->rx_process_limit) != 0)
- taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
- EM_TX_LOCK(adapter);
- em_txeof(adapter);
-
-#if __FreeBSD_version >= 800000
- if (!drbr_empty(ifp, adapter->br))
- em_mq_start_locked(ifp, NULL);
-#else
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- em_start_locked(ifp);
-#endif
- EM_TX_UNLOCK(adapter);
- }
-
- em_enable_intr(adapter);
-}
/*********************************************************************
*
* Fast Legacy/MSI Combined Interrupt Service routine
*
*********************************************************************/
-#if __FreeBSD_version < 700000
-#define FILTER_STRAY
-#define FILTER_HANDLED
-static void
-#else
static int
-#endif
em_irq_fast(void *arg)
{
struct adapter *adapter = arg;
@@ -1713,13 +1423,8 @@ em_irq_fast(void *arg)
(reg_icr & E1000_ICR_INT_ASSERTED) == 0)
return FILTER_STRAY;
- /*
- * Mask interrupts until the taskqueue is finished running. This is
- * cheap, just assume that it is needed. This also works around the
- * MSI message reordering errata on certain systems.
- */
em_disable_intr(adapter);
- taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
+ taskqueue_enqueue(adapter->tq, &adapter->que_task);
/* Link status change */
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
@@ -1732,30 +1437,64 @@ em_irq_fast(void *arg)
return FILTER_HANDLED;
}
+/* Combined RX/TX handler, used by Legacy and MSI */
+static void
+em_handle_que(void *context, int pending)
+{
+ struct adapter *adapter = context;
+ struct ifnet *ifp = adapter->ifp;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct rx_ring *rxr = adapter->rx_rings;
+ bool more_rx;
+
+
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ EM_RX_LOCK(rxr);
+ more_rx = em_rxeof(rxr, adapter->rx_process_limit);
+ EM_RX_UNLOCK(rxr);
+
+ EM_TX_LOCK(txr);
+ em_txeof(txr);
+#ifdef EM_MULTIQUEUE
+ if (!drbr_empty(ifp, txr->br))
+ em_mq_start_locked(ifp, txr, NULL);
+#else
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ em_start_locked(ifp, txr);
+#endif
+ EM_TX_UNLOCK(txr);
+ if (more_rx) {
+ taskqueue_enqueue(adapter->tq, &adapter->que_task);
+ return;
+ }
+ }
+
+ em_enable_intr(adapter);
+ return;
+}
+
+
/*********************************************************************
*
* MSIX Interrupt Service Routines
*
**********************************************************************/
-#define EM_MSIX_TX 0x00040000
-#define EM_MSIX_RX 0x00010000
-#define EM_MSIX_LINK 0x00100000
-
static void
em_msix_tx(void *arg)
{
- struct adapter *adapter = arg;
- struct ifnet *ifp = adapter->ifp;
-
- ++adapter->tx_irq;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- EM_TX_LOCK(adapter);
- em_txeof(adapter);
- EM_TX_UNLOCK(adapter);
- taskqueue_enqueue(adapter->tq, &adapter->tx_task);
- }
- /* Reenable this interrupt */
- E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_TX);
+ struct tx_ring *txr = arg;
+ struct adapter *adapter = txr->adapter;
+ bool more;
+
+ ++txr->tx_irq;
+ EM_TX_LOCK(txr);
+ more = em_txeof(txr);
+ EM_TX_UNLOCK(txr);
+ if (more)
+ taskqueue_enqueue(txr->tq, &txr->tx_task);
+ else
+ /* Reenable this interrupt */
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims);
return;
}
@@ -1768,15 +1507,19 @@ em_msix_tx(void *arg)
static void
em_msix_rx(void *arg)
{
- struct adapter *adapter = arg;
- struct ifnet *ifp = adapter->ifp;
-
- ++adapter->rx_irq;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) &&
- (em_rxeof(adapter, adapter->rx_process_limit) != 0))
- taskqueue_enqueue(adapter->tq, &adapter->rx_task);
- /* Reenable this interrupt */
- E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_RX);
+ struct rx_ring *rxr = arg;
+ struct adapter *adapter = rxr->adapter;
+ bool more;
+
+ EM_RX_LOCK(rxr);
+ ++rxr->rx_irq;
+ more = em_rxeof(rxr, adapter->rx_process_limit);
+ EM_RX_UNLOCK(rxr);
+ if (more)
+ taskqueue_enqueue(rxr->tq, &rxr->rx_task);
+ else
+ /* Reenable this interrupt */
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
return;
}
@@ -1785,7 +1528,6 @@ em_msix_rx(void *arg)
* MSIX Link Fast Interrupt Service routine
*
**********************************************************************/
-
static void
em_msix_link(void *arg)
{
@@ -1798,45 +1540,70 @@ em_msix_link(void *arg)
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
adapter->hw.mac.get_link_status = 1;
taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
- }
- E1000_WRITE_REG(&adapter->hw, E1000_IMS,
- EM_MSIX_LINK | E1000_IMS_LSC);
+ } else
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS,
+ EM_MSIX_LINK | E1000_IMS_LSC);
return;
}
static void
em_handle_rx(void *context, int pending)
{
- struct adapter *adapter = context;
- struct ifnet *ifp = adapter->ifp;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) &&
- (em_rxeof(adapter, adapter->rx_process_limit) != 0))
- taskqueue_enqueue(adapter->tq, &adapter->rx_task);
-
+ struct rx_ring *rxr = context;
+ struct adapter *adapter = rxr->adapter;
+ bool more;
+
+ EM_RX_LOCK(rxr);
+ more = em_rxeof(rxr, adapter->rx_process_limit);
+ EM_RX_UNLOCK(rxr);
+ if (more)
+ taskqueue_enqueue(rxr->tq, &rxr->rx_task);
+ else
+ /* Reenable this interrupt */
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
}
static void
em_handle_tx(void *context, int pending)
{
- struct adapter *adapter = context;
+ struct tx_ring *txr = context;
+ struct adapter *adapter = txr->adapter;
struct ifnet *ifp = adapter->ifp;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if (!EM_TX_TRYLOCK(adapter))
- return;
- em_txeof(adapter);
-#if __FreeBSD_version >= 800000
- if (!drbr_empty(ifp, adapter->br))
- em_mq_start_locked(ifp, NULL);
+ if (!EM_TX_TRYLOCK(txr))
+ return;
+
+ em_txeof(txr);
+
+#ifdef EM_MULTIQUEUE
+ if (!drbr_empty(ifp, txr->br))
+ em_mq_start_locked(ifp, txr, NULL);
#else
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- em_start_locked(ifp);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ em_start_locked(ifp, txr);
#endif
- EM_TX_UNLOCK(adapter);
- }
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims);
+ EM_TX_UNLOCK(txr);
}
-#endif /* EM_FAST_IRQ */
+
+static void
+em_handle_link(void *context, int pending)
+{
+ struct adapter *adapter = context;
+ struct ifnet *ifp = adapter->ifp;
+
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ return;
+
+ EM_CORE_LOCK(adapter);
+ callout_stop(&adapter->timer);
+ em_update_link_status(adapter);
+ callout_reset(&adapter->timer, hz, em_local_timer, adapter);
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS,
+ EM_MSIX_LINK | E1000_IMS_LSC);
+ EM_CORE_UNLOCK(adapter);
+}
+
/*********************************************************************
*
@@ -1869,8 +1636,6 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
(adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
- if (adapter->hw.mac.type == e1000_82545)
- fiber_type = IFM_1000_LX;
ifmr->ifm_active |= fiber_type | IFM_FDX;
} else {
switch (adapter->link_speed) {
@@ -1962,8 +1727,9 @@ em_media_change(struct ifnet *ifp)
**********************************************************************/
static int
-em_xmit(struct adapter *adapter, struct mbuf **m_headp)
+em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
{
+ struct adapter *adapter = txr->adapter;
bus_dma_segment_t segs[EM_MAX_SCATTER];
bus_dmamap_t map;
struct em_buffer *tx_buffer, *tx_buffer_mapped;
@@ -1972,31 +1738,10 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
u32 txd_upper, txd_lower, txd_used, txd_saved;
int nsegs, i, j, first, last = 0;
int error, do_tso, tso_desc = 0;
-#if __FreeBSD_version < 700000
- struct m_tag *mtag;
-#endif
+
m_head = *m_headp;
txd_upper = txd_lower = txd_used = txd_saved = 0;
-
-#if __FreeBSD_version >= 700000
do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0);
-#else
- do_tso = 0;
-#endif
-
- /*
- * Force a cleanup if number of TX descriptors
- * available hits the threshold
- */
- if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
- em_txeof(adapter);
- /* Now do we at least have a minimal? */
- if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
- adapter->no_tx_desc_avail1++;
- return (ENOBUFS);
- }
- }
-
/*
* TSO workaround:
@@ -2018,12 +1763,12 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
* of the EOP which is the only one that
* now gets a DONE bit writeback.
*/
- first = adapter->next_avail_tx_desc;
- tx_buffer = &adapter->tx_buffer_area[first];
+ first = txr->next_avail_desc;
+ tx_buffer = &txr->tx_buffers[first];
tx_buffer_mapped = tx_buffer;
map = tx_buffer->map;
- error = bus_dmamap_load_mbuf_sg(adapter->txtag, map,
+ error = bus_dmamap_load_mbuf_sg(txr->txtag, map,
*m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
/*
@@ -2048,7 +1793,7 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
*m_headp = m;
/* Try it again */
- error = bus_dmamap_load_mbuf_sg(adapter->txtag, map,
+ error = bus_dmamap_load_mbuf_sg(txr->txtag, map,
*m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
if (error) {
@@ -2068,15 +1813,15 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
* it follows a TSO burst, then we need to add a
* sentinel descriptor to prevent premature writeback.
*/
- if ((do_tso == 0) && (adapter->tx_tso == TRUE)) {
+ if ((do_tso == 0) && (txr->tx_tso == TRUE)) {
if (nsegs == 1)
tso_desc = TRUE;
- adapter->tx_tso = FALSE;
+ txr->tx_tso = FALSE;
}
- if (nsegs > (adapter->num_tx_desc_avail - 2)) {
- adapter->no_tx_desc_avail2++;
- bus_dmamap_unload(adapter->txtag, map);
+ if (nsegs > (txr->tx_avail - 2)) {
+ txr->no_desc_avail++;
+ bus_dmamap_unload(txr->txtag, map);
return (ENOBUFS);
}
m_head = *m_headp;
@@ -2084,7 +1829,7 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
/* Do hardware assists */
#if __FreeBSD_version >= 700000
if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
- error = em_tso_setup(adapter, m_head, &txd_upper, &txd_lower);
+ error = em_tso_setup(txr, m_head, &txd_upper, &txd_lower);
if (error != TRUE)
return (ENXIO); /* something foobar */
/* we need to make a final sentinel transmit desc */
@@ -2092,123 +1837,70 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
} else
#endif
if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)
- em_transmit_checksum_setup(adapter, m_head,
+ em_transmit_checksum_setup(txr, m_head,
&txd_upper, &txd_lower);
- i = adapter->next_avail_tx_desc;
- if (adapter->pcix_82544)
- txd_saved = i;
+ i = txr->next_avail_desc;
/* Set up our transmit descriptors */
for (j = 0; j < nsegs; j++) {
bus_size_t seg_len;
bus_addr_t seg_addr;
- /* If adapter is 82544 and on PCIX bus */
- if(adapter->pcix_82544) {
- DESC_ARRAY desc_array;
- u32 array_elements, counter;
- /*
- * Check the Address and Length combination and
- * split the data accordingly
- */
- array_elements = em_fill_descriptors(segs[j].ds_addr,
- segs[j].ds_len, &desc_array);
- for (counter = 0; counter < array_elements; counter++) {
- if (txd_used == adapter->num_tx_desc_avail) {
- adapter->next_avail_tx_desc = txd_saved;
- adapter->no_tx_desc_avail2++;
- bus_dmamap_unload(adapter->txtag, map);
- return (ENOBUFS);
- }
- tx_buffer = &adapter->tx_buffer_area[i];
- ctxd = &adapter->tx_desc_base[i];
- ctxd->buffer_addr = htole64(
- desc_array.descriptor[counter].address);
- ctxd->lower.data = htole32(
- (adapter->txd_cmd | txd_lower | (u16)
- desc_array.descriptor[counter].length));
- ctxd->upper.data =
- htole32((txd_upper));
- last = i;
- if (++i == adapter->num_tx_desc)
- i = 0;
- tx_buffer->m_head = NULL;
- tx_buffer->next_eop = -1;
- txd_used++;
- }
+
+ tx_buffer = &txr->tx_buffers[i];
+ ctxd = &txr->tx_base[i];
+ seg_addr = segs[j].ds_addr;
+ seg_len = segs[j].ds_len;
+ /*
+ ** TSO Workaround:
+ ** If this is the last descriptor, we want to
+ ** split it so we have a small final sentinel
+ */
+ if (tso_desc && (j == (nsegs -1)) && (seg_len > 8)) {
+ seg_len -= 4;
+ ctxd->buffer_addr = htole64(seg_addr);
+ ctxd->lower.data = htole32(
+ adapter->txd_cmd | txd_lower | seg_len);
+ ctxd->upper.data =
+ htole32(txd_upper);
+ if (++i == adapter->num_tx_desc)
+ i = 0;
+ /* Now make the sentinel */
+ ++txd_used; /* using an extra txd */
+ ctxd = &txr->tx_base[i];
+ tx_buffer = &txr->tx_buffers[i];
+ ctxd->buffer_addr =
+ htole64(seg_addr + seg_len);
+ ctxd->lower.data = htole32(
+ adapter->txd_cmd | txd_lower | 4);
+ ctxd->upper.data =
+ htole32(txd_upper);
+ last = i;
+ if (++i == adapter->num_tx_desc)
+ i = 0;
} else {
- tx_buffer = &adapter->tx_buffer_area[i];
- ctxd = &adapter->tx_desc_base[i];
- seg_addr = segs[j].ds_addr;
- seg_len = segs[j].ds_len;
- /*
- ** TSO Workaround:
- ** If this is the last descriptor, we want to
- ** split it so we have a small final sentinel
- */
- if (tso_desc && (j == (nsegs -1)) && (seg_len > 8)) {
- seg_len -= 4;
- ctxd->buffer_addr = htole64(seg_addr);
- ctxd->lower.data = htole32(
- adapter->txd_cmd | txd_lower | seg_len);
- ctxd->upper.data =
- htole32(txd_upper);
- if (++i == adapter->num_tx_desc)
- i = 0;
- /* Now make the sentinel */
- ++txd_used; /* using an extra txd */
- ctxd = &adapter->tx_desc_base[i];
- tx_buffer = &adapter->tx_buffer_area[i];
- ctxd->buffer_addr =
- htole64(seg_addr + seg_len);
- ctxd->lower.data = htole32(
- adapter->txd_cmd | txd_lower | 4);
- ctxd->upper.data =
- htole32(txd_upper);
- last = i;
- if (++i == adapter->num_tx_desc)
- i = 0;
- } else {
- ctxd->buffer_addr = htole64(seg_addr);
- ctxd->lower.data = htole32(
- adapter->txd_cmd | txd_lower | seg_len);
- ctxd->upper.data =
- htole32(txd_upper);
- last = i;
- if (++i == adapter->num_tx_desc)
- i = 0;
- }
- tx_buffer->m_head = NULL;
- tx_buffer->next_eop = -1;
+ ctxd->buffer_addr = htole64(seg_addr);
+ ctxd->lower.data = htole32(
+ adapter->txd_cmd | txd_lower | seg_len);
+ ctxd->upper.data =
+ htole32(txd_upper);
+ last = i;
+ if (++i == adapter->num_tx_desc)
+ i = 0;
}
+ tx_buffer->m_head = NULL;
+ tx_buffer->next_eop = -1;
}
- adapter->next_avail_tx_desc = i;
- if (adapter->pcix_82544)
- adapter->num_tx_desc_avail -= txd_used;
- else {
- adapter->num_tx_desc_avail -= nsegs;
- if (tso_desc) /* TSO used an extra for sentinel */
- adapter->num_tx_desc_avail -= txd_used;
- }
+ txr->next_avail_desc = i;
+ txr->tx_avail -= nsegs;
+ if (tso_desc) /* TSO used an extra for sentinel */
+ txr->tx_avail -= txd_used;
- /*
- ** Handle VLAN tag, this is the
- ** biggest difference between
- ** 6.x and 7
- */
-#if __FreeBSD_version < 700000
- /* Find out if we are in vlan mode. */
- mtag = VLAN_OUTPUT_TAG(ifp, m_head);
- if (mtag != NULL) {
- ctxd->upper.fields.special =
- htole16(VLAN_TAG_VALUE(mtag));
-#else /* FreeBSD 7 */
if (m_head->m_flags & M_VLANTAG) {
/* Set the vlan id. */
ctxd->upper.fields.special =
htole16(m_head->m_pkthdr.ether_vtag);
-#endif
/* Tell hardware to add tag */
ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
}
@@ -2216,7 +1908,7 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
tx_buffer->m_head = m_head;
tx_buffer_mapped->map = tx_buffer->map;
tx_buffer->map = map;
- bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE);
/*
* Last Descriptor of Packet
@@ -2229,146 +1921,20 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp)
* Keep track in the first buffer which
* descriptor will be written back
*/
- tx_buffer = &adapter->tx_buffer_area[first];
+ tx_buffer = &txr->tx_buffers[first];
tx_buffer->next_eop = last;
- adapter->watchdog_time = ticks;
/*
* Advance the Transmit Descriptor Tail (TDT), this tells the E1000
* that this frame is available to transmit.
*/
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if (adapter->hw.mac.type == e1000_82547 &&
- adapter->link_duplex == HALF_DUPLEX)
- em_82547_move_tail(adapter);
- else {
- E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i);
- if (adapter->hw.mac.type == e1000_82547)
- em_82547_update_fifo_head(adapter,
- m_head->m_pkthdr.len);
- }
+ E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), i);
return (0);
}
-/*********************************************************************
- *
- * 82547 workaround to avoid controller hang in half-duplex environment.
- * The workaround is to avoid queuing a large packet that would span
- * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers
- * in this case. We do that only when FIFO is quiescent.
- *
- **********************************************************************/
-static void
-em_82547_move_tail(void *arg)
-{
- struct adapter *adapter = arg;
- struct e1000_tx_desc *tx_desc;
- u16 hw_tdt, sw_tdt, length = 0;
- bool eop = 0;
-
- EM_TX_LOCK_ASSERT(adapter);
-
- hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT(0));
- sw_tdt = adapter->next_avail_tx_desc;
-
- while (hw_tdt != sw_tdt) {
- tx_desc = &adapter->tx_desc_base[hw_tdt];
- length += tx_desc->lower.flags.length;
- eop = tx_desc->lower.data & E1000_TXD_CMD_EOP;
- if (++hw_tdt == adapter->num_tx_desc)
- hw_tdt = 0;
-
- if (eop) {
- if (em_82547_fifo_workaround(adapter, length)) {
- adapter->tx_fifo_wrk_cnt++;
- callout_reset(&adapter->tx_fifo_timer, 1,
- em_82547_move_tail, adapter);
- break;
- }
- E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), hw_tdt);
- em_82547_update_fifo_head(adapter, length);
- length = 0;
- }
- }
-}
-
-static int
-em_82547_fifo_workaround(struct adapter *adapter, int len)
-{
- int fifo_space, fifo_pkt_len;
-
- fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR);
-
- if (adapter->link_duplex == HALF_DUPLEX) {
- fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
-
- if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
- if (em_82547_tx_fifo_reset(adapter))
- return (0);
- else
- return (1);
- }
- }
-
- return (0);
-}
-
-static void
-em_82547_update_fifo_head(struct adapter *adapter, int len)
-{
- int fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR);
-
- /* tx_fifo_head is always 16 byte aligned */
- adapter->tx_fifo_head += fifo_pkt_len;
- if (adapter->tx_fifo_head >= adapter->tx_fifo_size) {
- adapter->tx_fifo_head -= adapter->tx_fifo_size;
- }
-}
-
-
-static int
-em_82547_tx_fifo_reset(struct adapter *adapter)
-{
- u32 tctl;
-
- if ((E1000_READ_REG(&adapter->hw, E1000_TDT(0)) ==
- E1000_READ_REG(&adapter->hw, E1000_TDH(0))) &&
- (E1000_READ_REG(&adapter->hw, E1000_TDFT) ==
- E1000_READ_REG(&adapter->hw, E1000_TDFH)) &&
- (E1000_READ_REG(&adapter->hw, E1000_TDFTS) ==
- E1000_READ_REG(&adapter->hw, E1000_TDFHS)) &&
- (E1000_READ_REG(&adapter->hw, E1000_TDFPC) == 0)) {
- /* Disable TX unit */
- tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
- E1000_WRITE_REG(&adapter->hw, E1000_TCTL,
- tctl & ~E1000_TCTL_EN);
-
- /* Reset FIFO pointers */
- E1000_WRITE_REG(&adapter->hw, E1000_TDFT,
- adapter->tx_head_addr);
- E1000_WRITE_REG(&adapter->hw, E1000_TDFH,
- adapter->tx_head_addr);
- E1000_WRITE_REG(&adapter->hw, E1000_TDFTS,
- adapter->tx_head_addr);
- E1000_WRITE_REG(&adapter->hw, E1000_TDFHS,
- adapter->tx_head_addr);
-
- /* Re-enable TX unit */
- E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
- E1000_WRITE_FLUSH(&adapter->hw);
-
- adapter->tx_fifo_head = 0;
- adapter->tx_fifo_reset_cnt++;
-
- return (TRUE);
- }
- else {
- return (FALSE);
- }
-}
-
static void
em_set_promisc(struct adapter *adapter)
{
@@ -2492,13 +2058,10 @@ em_local_timer(void *arg)
{
struct adapter *adapter = arg;
struct ifnet *ifp = adapter->ifp;
+ struct tx_ring *txr = adapter->tx_rings;
EM_CORE_LOCK_ASSERT(adapter);
-#ifndef DEVICE_POLLING
- taskqueue_enqueue(adapter->tq,
- &adapter->rxtx_task);
-#endif
em_update_link_status(adapter);
em_update_stats_counters(adapter);
@@ -2509,26 +2072,31 @@ em_local_timer(void *arg)
if (em_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING)
em_print_hw_stats(adapter);
- em_smartspeed(adapter);
-
/*
- * We check the watchdog: the time since
- * the last TX descriptor was cleaned.
- * This implies a functional TX engine.
- */
- if ((adapter->watchdog_check == TRUE) &&
- (ticks - adapter->watchdog_time > EM_WATCHDOG))
- goto hung;
+ ** Check for time since any descriptor was cleaned
+ */
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ EM_TX_LOCK(txr);
+ if (txr->watchdog_check == FALSE) {
+ EM_TX_UNLOCK(txr);
+ continue;
+ }
+ if ((ticks - txr->watchdog_time) > EM_WATCHDOG)
+ goto hung;
+ EM_TX_UNLOCK(txr);
+ }
callout_reset(&adapter->timer, hz, em_local_timer, adapter);
return;
hung:
device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
- adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
adapter->watchdog_events++;
+ EM_TX_UNLOCK(txr);
em_init_locked(adapter);
}
+
static void
em_update_link_status(struct adapter *adapter)
{
@@ -2592,7 +2160,8 @@ em_update_link_status(struct adapter *adapter)
device_printf(dev, "Link is Down\n");
adapter->link_active = 0;
/* Link down, disable watchdog */
- adapter->watchdog_check = FALSE;
+ // JFV change later
+ //adapter->watchdog_check = FALSE;
if_link_state_change(ifp, LINK_STATE_DOWN);
}
}
@@ -2611,22 +2180,30 @@ em_stop(void *arg)
{
struct adapter *adapter = arg;
struct ifnet *ifp = adapter->ifp;
+ struct tx_ring *txr = adapter->tx_rings;
EM_CORE_LOCK_ASSERT(adapter);
- EM_TX_LOCK_ASSERT(adapter);
INIT_DEBUGOUT("em_stop: begin");
em_disable_intr(adapter);
callout_stop(&adapter->timer);
- callout_stop(&adapter->tx_fifo_timer);
/* Tell the stack that the interface is no longer active */
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ /* Unarm watchdog timer. */
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ EM_TX_LOCK(txr);
+ txr->watchdog_check = FALSE;
+ EM_TX_UNLOCK(txr);
+ }
+
e1000_reset_hw(&adapter->hw);
- if (adapter->hw.mac.type >= e1000_82544)
- E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
+ E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
+
+ e1000_led_off(&adapter->hw);
+ e1000_cleanup_led(&adapter->hw);
}
@@ -2672,7 +2249,7 @@ static int
em_allocate_pci_resources(struct adapter *adapter)
{
device_t dev = adapter->dev;
- int val, rid, error = E1000_SUCCESS;
+ int rid;
rid = PCIR_BAR(0);
adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@@ -2687,58 +2264,17 @@ em_allocate_pci_resources(struct adapter *adapter)
rman_get_bushandle(adapter->memory);
adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
- /* Only older adapters use IO mapping */
- if ((adapter->hw.mac.type > e1000_82543) &&
- (adapter->hw.mac.type < e1000_82571)) {
- /* Figure our where our IO BAR is ? */
- for (rid = PCIR_BAR(0); rid < PCIR_CIS;) {
- val = pci_read_config(dev, rid, 4);
- if (EM_BAR_TYPE(val) == EM_BAR_TYPE_IO) {
- adapter->io_rid = rid;
- break;
- }
- rid += 4;
- /* check for 64bit BAR */
- if (EM_BAR_MEM_TYPE(val) == EM_BAR_MEM_TYPE_64BIT)
- rid += 4;
- }
- if (rid >= PCIR_CIS) {
- device_printf(dev, "Unable to locate IO BAR\n");
- return (ENXIO);
- }
- adapter->ioport = bus_alloc_resource_any(dev,
- SYS_RES_IOPORT, &adapter->io_rid, RF_ACTIVE);
- if (adapter->ioport == NULL) {
- device_printf(dev, "Unable to allocate bus resource: "
- "ioport\n");
- return (ENXIO);
- }
- adapter->hw.io_base = 0;
- adapter->osdep.io_bus_space_tag =
- rman_get_bustag(adapter->ioport);
- adapter->osdep.io_bus_space_handle =
- rman_get_bushandle(adapter->ioport);
- }
-
- /*
- ** Init the resource arrays
- ** used by MSIX setup
- */
- for (int i = 0; i < 3; i++) {
- adapter->rid[i] = i + 1; /* MSI/X RID starts at 1 */
- adapter->tag[i] = NULL;
- adapter->res[i] = NULL;
- }
+ /* Default to a single queue */
+ adapter->num_queues = 1;
/*
* Setup MSI/X or MSI if PCI Express
*/
- if (em_enable_msi)
- adapter->msi = em_setup_msix(adapter);
+ adapter->msix = em_setup_msix(adapter);
adapter->hw.back = &adapter->osdep;
- return (error);
+ return (0);
}
/*********************************************************************
@@ -2750,63 +2286,40 @@ int
em_allocate_legacy(struct adapter *adapter)
{
device_t dev = adapter->dev;
- int error;
+ int error, rid = 0;
/* Manually turn off all interrupts */
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
- /* Legacy RID is 0 */
- if (adapter->msi == 0)
- adapter->rid[0] = 0;
-
+ if (adapter->msix == 1) /* using MSI */
+ rid = 1;
/* We allocate a single interrupt resource */
- adapter->res[0] = bus_alloc_resource_any(dev,
- SYS_RES_IRQ, &adapter->rid[0], RF_SHAREABLE | RF_ACTIVE);
- if (adapter->res[0] == NULL) {
+ adapter->res = bus_alloc_resource_any(dev,
+ SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
+ if (adapter->res == NULL) {
device_printf(dev, "Unable to allocate bus resource: "
"interrupt\n");
return (ENXIO);
}
-#ifdef EM_LEGACY_IRQ
- /* We do Legacy setup */
- if ((error = bus_setup_intr(dev, adapter->res[0],
-#if __FreeBSD_version > 700000
- INTR_TYPE_NET | INTR_MPSAFE, NULL, em_intr, adapter,
-#else /* 6.X */
- INTR_TYPE_NET | INTR_MPSAFE, em_intr, adapter,
-#endif
- &adapter->tag[0])) != 0) {
- device_printf(dev, "Failed to register interrupt handler");
- return (error);
- }
-
-#else /* FAST_IRQ */
/*
- * Try allocating a fast interrupt and the associated deferred
- * processing contexts.
+ * Allocate a fast interrupt and the associated
+ * deferred processing contexts.
*/
- TASK_INIT(&adapter->rxtx_task, 0, em_handle_rxtx, adapter);
+ TASK_INIT(&adapter->que_task, 0, em_handle_que, adapter);
TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter);
adapter->tq = taskqueue_create_fast("em_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &adapter->tq);
taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
device_get_nameunit(adapter->dev));
-#if __FreeBSD_version < 700000
- if ((error = bus_setup_intr(dev, adapter->res[0],
- INTR_TYPE_NET | INTR_FAST, em_irq_fast, adapter,
-#else
- if ((error = bus_setup_intr(dev, adapter->res[0],
- INTR_TYPE_NET, em_irq_fast, NULL, adapter,
-#endif
- &adapter->tag[0])) != 0) {
+ if ((error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET,
+ em_irq_fast, NULL, adapter, &adapter->tag)) != 0) {
device_printf(dev, "Failed to register fast interrupt "
"handler: %d\n", error);
taskqueue_free(adapter->tq);
adapter->tq = NULL;
return (error);
}
-#endif /* EM_LEGACY_IRQ */
return (0);
}
@@ -2821,80 +2334,109 @@ em_allocate_legacy(struct adapter *adapter)
int
em_allocate_msix(struct adapter *adapter)
{
- device_t dev = adapter->dev;
- int error;
+ device_t dev = adapter->dev;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct rx_ring *rxr = adapter->rx_rings;
+ int error, rid, vector = 0;
+
/* Make sure all interrupts are disabled */
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
- /* First get the resources */
- for (int i = 0; i < adapter->msi; i++) {
- adapter->res[i] = bus_alloc_resource_any(dev,
- SYS_RES_IRQ, &adapter->rid[i], RF_ACTIVE);
- if (adapter->res[i] == NULL) {
+ /* First set up ring resources */
+ for (int i = 0; i < adapter->num_queues; i++, txr++, rxr++) {
+
+ /* RX ring */
+ rid = vector + 1;
+
+ rxr->res = bus_alloc_resource_any(dev,
+ SYS_RES_IRQ, &rid, RF_ACTIVE);
+ if (rxr->res == NULL) {
device_printf(dev,
"Unable to allocate bus resource: "
- "MSIX Interrupt\n");
+ "RX MSIX Interrupt %d\n", i);
return (ENXIO);
}
+ if ((error = bus_setup_intr(dev, rxr->res,
+ INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_rx,
+ rxr, &rxr->tag)) != 0) {
+ device_printf(dev, "Failed to register RX handler");
+ return (error);
+ }
+ rxr->msix = vector++; /* NOTE increment vector for TX */
+ TASK_INIT(&rxr->rx_task, 0, em_handle_rx, rxr);
+ rxr->tq = taskqueue_create_fast("em_rxq", M_NOWAIT,
+ taskqueue_thread_enqueue, &rxr->tq);
+ taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq",
+ device_get_nameunit(adapter->dev));
+ /*
+ ** Set the bit to enable interrupt
+ ** in E1000_IMS -- bits 20 and 21
+ ** are for RX0 and RX1, note this has
+ ** NOTHING to do with the MSIX vector
+ */
+ rxr->ims = 1 << (20 + i);
+ adapter->ivars |= (8 | rxr->msix) << (i * 4);
+
+ /* TX ring */
+ rid = vector + 1;
+ txr->res = bus_alloc_resource_any(dev,
+ SYS_RES_IRQ, &rid, RF_ACTIVE);
+ if (txr->res == NULL) {
+ device_printf(dev,
+ "Unable to allocate bus resource: "
+ "TX MSIX Interrupt %d\n", i);
+ return (ENXIO);
+ }
+ if ((error = bus_setup_intr(dev, txr->res,
+ INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_tx,
+ txr, &txr->tag)) != 0) {
+ device_printf(dev, "Failed to register TX handler");
+ return (error);
+ }
+ txr->msix = vector++; /* Increment vector for next pass */
+ TASK_INIT(&txr->tx_task, 0, em_handle_tx, txr);
+ txr->tq = taskqueue_create_fast("em_txq", M_NOWAIT,
+ taskqueue_thread_enqueue, &txr->tq);
+ taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq",
+ device_get_nameunit(adapter->dev));
+ /*
+ ** Set the bit to enable interrupt
+ ** in E1000_IMS -- bits 22 and 23
+ ** are for TX0 and TX1, note this has
+ ** NOTHING to do with the MSIX vector
+ */
+ txr->ims = 1 << (22 + i);
+ adapter->ivars |= (8 | txr->msix) << (8 + (i * 4));
}
- /*
- * Now allocate deferred processing contexts.
- */
- TASK_INIT(&adapter->rx_task, 0, em_handle_rx, adapter);
- TASK_INIT(&adapter->tx_task, 0, em_handle_tx, adapter);
- /*
- * Handle compatibility for msi case for deferral due to
- * trylock failure
- */
- TASK_INIT(&adapter->rxtx_task, 0, em_handle_tx, adapter);
+ /* Link interrupt */
+ ++rid;
+ adapter->res = bus_alloc_resource_any(dev,
+ SYS_RES_IRQ, &rid, RF_ACTIVE);
+ if (!adapter->res) {
+ device_printf(dev,"Unable to allocate "
+ "bus resource: Link interrupt [%d]\n", rid);
+ return (ENXIO);
+ }
+ /* Set the link handler function */
+ error = bus_setup_intr(dev, adapter->res,
+ INTR_TYPE_NET | INTR_MPSAFE, NULL,
+ em_msix_link, adapter, &adapter->tag);
+ if (error) {
+ adapter->res = NULL;
+ device_printf(dev, "Failed to register LINK handler");
+ return (error);
+ }
+ adapter->linkvec = vector;
+ adapter->ivars |= (8 | vector) << 16;
+ adapter->ivars |= 0x80000000;
TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter);
- adapter->tq = taskqueue_create_fast("em_taskq", M_NOWAIT,
+ adapter->tq = taskqueue_create_fast("em_link", M_NOWAIT,
taskqueue_thread_enqueue, &adapter->tq);
- taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
+ taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq",
device_get_nameunit(adapter->dev));
- /*
- * And setup the interrupt handlers
- */
-
- /* First slot to RX */
- if ((error = bus_setup_intr(dev, adapter->res[0],
-#if __FreeBSD_version > 700000
- INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_rx, adapter,
-#else /* 6.X */
- INTR_TYPE_NET | INTR_MPSAFE, em_msix_rx, adapter,
-#endif
- &adapter->tag[0])) != 0) {
- device_printf(dev, "Failed to register RX handler");
- return (error);
- }
-
- /* Next TX */
- if ((error = bus_setup_intr(dev, adapter->res[1],
-#if __FreeBSD_version > 700000
- INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_tx, adapter,
-#else /* 6.X */
- INTR_TYPE_NET | INTR_MPSAFE, em_msix_tx, adapter,
-#endif
- &adapter->tag[1])) != 0) {
- device_printf(dev, "Failed to register TX handler");
- return (error);
- }
-
- /* And Link */
- if ((error = bus_setup_intr(dev, adapter->res[2],
-#if __FreeBSD_version > 700000
- INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_link, adapter,
-#else /* 6.X */
- INTR_TYPE_NET | INTR_MPSAFE, em_msix_link, adapter,
-#endif
- &adapter->tag[2])) != 0) {
- device_printf(dev, "Failed to register TX handler");
- return (error);
- }
-
return (0);
}
@@ -2902,36 +2444,56 @@ em_allocate_msix(struct adapter *adapter)
static void
em_free_pci_resources(struct adapter *adapter)
{
- device_t dev = adapter->dev;
+ device_t dev = adapter->dev;
+ struct tx_ring *txr;
+ struct rx_ring *rxr;
+ int rid;
- /* Make sure the for loop below runs once */
- if (adapter->msi == 0)
- adapter->msi = 1;
/*
- * First release all the interrupt resources:
- * notice that since these are just kept
- * in an array we can do the same logic
- * whether its MSIX or just legacy.
- */
- for (int i = 0; i < adapter->msi; i++) {
- if (adapter->tag[i] != NULL) {
- bus_teardown_intr(dev, adapter->res[i],
- adapter->tag[i]);
- adapter->tag[i] = NULL;
+ ** Release all the queue interrupt resources:
+ */
+ for (int i = 0; i < adapter->num_queues; i++) {
+ txr = &adapter->tx_rings[i];
+ rxr = &adapter->rx_rings[i];
+ rid = txr->msix +1;
+ if (txr->tag != NULL) {
+ bus_teardown_intr(dev, txr->res, txr->tag);
+ txr->tag = NULL;
}
- if (adapter->res[i] != NULL) {
+ if (txr->res != NULL)
bus_release_resource(dev, SYS_RES_IRQ,
- adapter->rid[i], adapter->res[i]);
+ rid, txr->res);
+ rid = rxr->msix +1;
+ if (rxr->tag != NULL) {
+ bus_teardown_intr(dev, rxr->res, rxr->tag);
+ rxr->tag = NULL;
}
+ if (rxr->res != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ,
+ rid, rxr->res);
}
- if (adapter->msi)
+ if (adapter->linkvec) /* we are doing MSIX */
+ rid = adapter->linkvec + 1;
+ else
+ (adapter->msix != 0) ? (rid = 1):(rid = 0);
+
+ if (adapter->tag != NULL) {
+ bus_teardown_intr(dev, adapter->res, adapter->tag);
+ adapter->tag = NULL;
+ }
+
+ if (adapter->res != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res);
+
+
+ if (adapter->msix)
pci_release_msi(dev);
- if (adapter->msix != NULL)
+ if (adapter->msix_mem != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
- PCIR_BAR(EM_MSIX_BAR), adapter->msix);
+ PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
if (adapter->memory != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
@@ -2940,10 +2502,6 @@ em_free_pci_resources(struct adapter *adapter)
if (adapter->flash != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
EM_FLASH, adapter->flash);
-
- if (adapter->ioport != NULL)
- bus_release_resource(dev, SYS_RES_IOPORT,
- adapter->io_rid, adapter->ioport);
}
/*
@@ -2955,73 +2513,81 @@ em_setup_msix(struct adapter *adapter)
device_t dev = adapter->dev;
int val = 0;
- if (adapter->hw.mac.type < e1000_82571)
- return (0);
/* Setup MSI/X for Hartwell */
- if (adapter->hw.mac.type == e1000_82574) {
+ if ((adapter->hw.mac.type == e1000_82574) &&
+ (em_enable_msix == TRUE)) {
/* Map the MSIX BAR */
int rid = PCIR_BAR(EM_MSIX_BAR);
- adapter->msix = bus_alloc_resource_any(dev,
+ adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!adapter->msix) {
+ if (!adapter->msix_mem) {
/* May not be enabled */
device_printf(adapter->dev,
"Unable to map MSIX table \n");
goto msi;
}
val = pci_msix_count(dev);
- /*
- ** 82574 can be configured for 5 but
- ** we limit use to 3.
- */
- if (val > 3) val = 3;
- if ((val) && pci_alloc_msix(dev, &val) == 0) {
- device_printf(adapter->dev,"Using MSIX interrupts\n");
- return (val);
+ if (val != 5) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
+ adapter->msix_mem = NULL;
+ device_printf(adapter->dev,
+ "MSIX vectors wrong, using MSI \n");
+ goto msi;
}
+ if (em_msix_queues == 2) {
+ val = 5;
+ adapter->num_queues = 2;
+ } else {
+ val = 3;
+ adapter->num_queues = 1;
+ }
+ if (pci_alloc_msix(dev, &val) == 0) {
+ device_printf(adapter->dev,
+ "Using MSIX interrupts "
+ "with %d vectors\n", val);
+ }
+
+ return (val);
}
msi:
val = pci_msi_count(dev);
if (val == 1 && pci_alloc_msi(dev, &val) == 0) {
- adapter->msi = 1;
+ adapter->msix = 1;
device_printf(adapter->dev,"Using MSI interrupt\n");
return (val);
}
+ /* Should only happen due to manual invention */
+ device_printf(adapter->dev,"Setup MSIX failure\n");
return (0);
}
+
/*********************************************************************
*
* Initialize the hardware to a configuration
* as specified by the adapter structure.
*
**********************************************************************/
-static int
-em_hardware_init(struct adapter *adapter)
+static void
+em_reset(struct adapter *adapter)
{
- device_t dev = adapter->dev;
- u16 rx_buffer_size;
-
- INIT_DEBUGOUT("em_hardware_init: begin");
-
- /* Issue a global reset */
- e1000_reset_hw(&adapter->hw);
+ device_t dev = adapter->dev;
+ struct e1000_hw *hw = &adapter->hw;
+ u16 rx_buffer_size;
- /* When hardware is reset, fifo_head is also reset */
- adapter->tx_fifo_head = 0;
+ INIT_DEBUGOUT("em_reset: begin");
/* Set up smart power down as default off on newer adapters. */
- if (!em_smart_pwr_down && (adapter->hw.mac.type == e1000_82571 ||
- adapter->hw.mac.type == e1000_82572)) {
+ if (!em_smart_pwr_down && (hw->mac.type == e1000_82571 ||
+ hw->mac.type == e1000_82572)) {
u16 phy_tmp = 0;
/* Speed up time to link by disabling smart power down. */
- e1000_read_phy_reg(&adapter->hw,
- IGP02E1000_PHY_POWER_MGMT, &phy_tmp);
+ e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_tmp);
phy_tmp &= ~IGP02E1000_PM_SPD;
- e1000_write_phy_reg(&adapter->hw,
- IGP02E1000_PHY_POWER_MGMT, phy_tmp);
+ e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_tmp);
}
/*
@@ -3038,37 +2604,42 @@ em_hardware_init(struct adapter *adapter)
* by 1500.
* - The pause time is fairly large at 1000 x 512ns = 512 usec.
*/
- rx_buffer_size = ((E1000_READ_REG(&adapter->hw, E1000_PBA) &
- 0xffff) << 10 );
+ rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 );
- adapter->hw.fc.high_water = rx_buffer_size -
+ hw->fc.high_water = rx_buffer_size -
roundup2(adapter->max_frame_size, 1024);
- adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500;
+ hw->fc.low_water = hw->fc.high_water - 1500;
- if (adapter->hw.mac.type == e1000_80003es2lan)
- adapter->hw.fc.pause_time = 0xFFFF;
+ if (hw->mac.type == e1000_80003es2lan)
+ hw->fc.pause_time = 0xFFFF;
else
- adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME;
- adapter->hw.fc.send_xon = TRUE;
+ hw->fc.pause_time = EM_FC_PAUSE_TIME;
+
+ hw->fc.send_xon = TRUE;
/* Set Flow control, use the tunable location if sane */
if ((em_fc_setting >= 0) || (em_fc_setting < 4))
- adapter->hw.fc.requested_mode = em_fc_setting;
- else
- adapter->hw.fc.requested_mode = e1000_fc_none;
+ hw->fc.requested_mode = em_fc_setting;
+ else
+ hw->fc.requested_mode = e1000_fc_none;
/* Override - workaround for PCHLAN issue */
- if (adapter->hw.mac.type == e1000_pchlan)
- adapter->hw.fc.requested_mode = e1000_fc_rx_pause;
+ if (hw->mac.type == e1000_pchlan)
+ hw->fc.requested_mode = e1000_fc_rx_pause;
- if (e1000_init_hw(&adapter->hw) < 0) {
+ /* Issue a global reset */
+ e1000_reset_hw(hw);
+ E1000_WRITE_REG(hw, E1000_WUC, 0);
+
+ if (e1000_init_hw(hw) < 0) {
device_printf(dev, "Hardware Initialization Failed\n");
- return (EIO);
+ return;
}
- e1000_check_for_link(&adapter->hw);
-
- return (0);
+ E1000_WRITE_REG(hw, E1000_VET, ETHERTYPE_VLAN);
+ e1000_get_phy_info(hw);
+ e1000_check_for_link(hw);
+ return;
}
/*********************************************************************
@@ -3101,42 +2672,26 @@ em_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities = ifp->if_capenable = 0;
-#if __FreeBSD_version >= 800000
+#ifdef EM_MULTIQUEUE
/* Multiqueue tx functions */
ifp->if_transmit = em_mq_start;
ifp->if_qflush = em_qflush;
- adapter->br = buf_ring_alloc(4096, M_DEVBUF, M_WAITOK, &adapter->tx_mtx);
#endif
- if (adapter->hw.mac.type >= e1000_82543) {
- int version_cap;
-#if __FreeBSD_version < 700000
- version_cap = IFCAP_HWCSUM;
-#else
- version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
-#endif
- ifp->if_capabilities |= version_cap;
- ifp->if_capenable |= version_cap;
- }
-#if __FreeBSD_version >= 700000
- /* Identify TSO capable adapters */
- if ((adapter->hw.mac.type > e1000_82544) &&
- (adapter->hw.mac.type != e1000_82547))
- ifp->if_capabilities |= IFCAP_TSO4;
- /*
- * By default only enable on PCI-E, this
- * can be overriden by ifconfig.
- */
- if (adapter->hw.mac.type >= e1000_82571)
- ifp->if_capenable |= IFCAP_TSO4;
-#endif
+ ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
+ ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
+
+ /* Enable TSO by default, can disable with ifconfig */
+ ifp->if_capabilities |= IFCAP_TSO4;
+ ifp->if_capenable |= IFCAP_TSO4;
+
/*
* Tell the upper layer(s) we
* support full VLAN capability
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
- ifp->if_capenable |= (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING);
+ ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
/*
** Dont turn this on by default, if vlans are
@@ -3144,7 +2699,7 @@ em_setup_interface(device_t dev, struct adapter *adapter)
** then vlan events are not passed thru, breaking
** operation, but with HW FILTER off it works. If
** using vlans directly on the em driver you can
- ** enable this and get full hardware tag filtering.
+ ** enable this and get full hardware tag filtering.
*/
ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
@@ -3152,10 +2707,10 @@ em_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities |= IFCAP_POLLING;
#endif
- /* Limit WOL to MAGIC, not clear others are used */
+ /* Enable All WOL methods by default */
if (adapter->wol) {
- ifp->if_capabilities |= IFCAP_WOL_MAGIC;
- ifp->if_capenable |= IFCAP_WOL_MAGIC;
+ ifp->if_capabilities |= IFCAP_WOL;
+ ifp->if_capenable |= IFCAP_WOL;
}
/*
@@ -3168,8 +2723,6 @@ em_setup_interface(device_t dev, struct adapter *adapter)
(adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
u_char fiber_type = IFM_1000_SX; /* default type */
- if (adapter->hw.mac.type == e1000_82545)
- fiber_type = IFM_1000_LX;
ifmedia_add(&adapter->media, IFM_ETHER | fiber_type | IFM_FDX,
0, NULL);
ifmedia_add(&adapter->media, IFM_ETHER | fiber_type, 0, NULL);
@@ -3193,67 +2746,6 @@ em_setup_interface(device_t dev, struct adapter *adapter)
}
-/*********************************************************************
- *
- * Workaround for SmartSpeed on 82541 and 82547 controllers
- *
- **********************************************************************/
-static void
-em_smartspeed(struct adapter *adapter)
-{
- u16 phy_tmp;
-
- if (adapter->link_active || (adapter->hw.phy.type != e1000_phy_igp) ||
- adapter->hw.mac.autoneg == 0 ||
- (adapter->hw.phy.autoneg_advertised & ADVERTISE_1000_FULL) == 0)
- return;
-
- if (adapter->smartspeed == 0) {
- /* If Master/Slave config fault is asserted twice,
- * we assume back-to-back */
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
- if (!(phy_tmp & SR_1000T_MS_CONFIG_FAULT))
- return;
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
- if (phy_tmp & SR_1000T_MS_CONFIG_FAULT) {
- e1000_read_phy_reg(&adapter->hw,
- PHY_1000T_CTRL, &phy_tmp);
- if(phy_tmp & CR_1000T_MS_ENABLE) {
- phy_tmp &= ~CR_1000T_MS_ENABLE;
- e1000_write_phy_reg(&adapter->hw,
- PHY_1000T_CTRL, phy_tmp);
- adapter->smartspeed++;
- if(adapter->hw.mac.autoneg &&
- !e1000_copper_link_autoneg(&adapter->hw) &&
- !e1000_read_phy_reg(&adapter->hw,
- PHY_CONTROL, &phy_tmp)) {
- phy_tmp |= (MII_CR_AUTO_NEG_EN |
- MII_CR_RESTART_AUTO_NEG);
- e1000_write_phy_reg(&adapter->hw,
- PHY_CONTROL, phy_tmp);
- }
- }
- }
- return;
- } else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) {
- /* If still no link, perhaps using 2/3 pair cable */
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp);
- phy_tmp |= CR_1000T_MS_ENABLE;
- e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp);
- if(adapter->hw.mac.autoneg &&
- !e1000_copper_link_autoneg(&adapter->hw) &&
- !e1000_read_phy_reg(&adapter->hw, PHY_CONTROL, &phy_tmp)) {
- phy_tmp |= (MII_CR_AUTO_NEG_EN |
- MII_CR_RESTART_AUTO_NEG);
- e1000_write_phy_reg(&adapter->hw, PHY_CONTROL, phy_tmp);
- }
- }
- /* Restart process after EM_SMARTSPEED_MAX iterations */
- if(adapter->smartspeed++ == EM_SMARTSPEED_MAX)
- adapter->smartspeed = 0;
-}
-
-
/*
* Manage DMA'able memory.
*/
@@ -3271,11 +2763,7 @@ em_dma_malloc(struct adapter *adapter, bus_size_t size,
{
int error;
-#if __FreeBSD_version >= 700000
error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
-#else
- error = bus_dma_tag_create(NULL, /* parent */
-#endif
EM_DBA_ALIGN, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -3346,97 +2834,243 @@ em_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
/*********************************************************************
*
+ * Allocate memory for the transmit and receive rings, and then
+ * the descriptors associated with each, called only once at attach.
+ *
+ **********************************************************************/
+static int
+em_allocate_queues(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ struct tx_ring *txr = NULL;
+ struct rx_ring *rxr = NULL;
+ int rsize, tsize, error = E1000_SUCCESS;
+ int txconf = 0, rxconf = 0;
+
+
+ /* Allocate the TX ring struct memory */
+ if (!(adapter->tx_rings =
+ (struct tx_ring *) malloc(sizeof(struct tx_ring) *
+ adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
+ device_printf(dev, "Unable to allocate TX ring memory\n");
+ error = ENOMEM;
+ goto fail;
+ }
+
+ /* Now allocate the RX */
+ if (!(adapter->rx_rings =
+ (struct rx_ring *) malloc(sizeof(struct rx_ring) *
+ adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
+ device_printf(dev, "Unable to allocate RX ring memory\n");
+ error = ENOMEM;
+ goto rx_fail;
+ }
+
+ tsize = roundup2(adapter->num_tx_desc *
+ sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
+ /*
+ * Now set up the TX queues, txconf is needed to handle the
+ * possibility that things fail midcourse and we need to
+ * undo memory gracefully
+ */
+ for (int i = 0; i < adapter->num_queues; i++, txconf++) {
+ /* Set up some basics */
+ txr = &adapter->tx_rings[i];
+ txr->adapter = adapter;
+ txr->me = i;
+
+ /* Initialize the TX lock */
+ snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)",
+ device_get_nameunit(dev), txr->me);
+ mtx_init(&txr->tx_mtx, txr->mtx_name, NULL, MTX_DEF);
+
+ if (em_dma_malloc(adapter, tsize,
+ &txr->txdma, BUS_DMA_NOWAIT)) {
+ device_printf(dev,
+ "Unable to allocate TX Descriptor memory\n");
+ error = ENOMEM;
+ goto err_tx_desc;
+ }
+ txr->tx_base = (struct e1000_tx_desc *)txr->txdma.dma_vaddr;
+ bzero((void *)txr->tx_base, tsize);
+
+ if (em_allocate_transmit_buffers(txr)) {
+ device_printf(dev,
+ "Critical Failure setting up transmit buffers\n");
+ error = ENOMEM;
+ goto err_tx_desc;
+ }
+#if __FreeBSD_version >= 800000
+ /* Allocate a buf ring */
+ txr->br = buf_ring_alloc(4096, M_DEVBUF,
+ M_WAITOK, &txr->tx_mtx);
+#endif
+ }
+
+ /*
+ * Next the RX queues...
+ */
+ rsize = roundup2(adapter->num_rx_desc *
+ sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
+ for (int i = 0; i < adapter->num_queues; i++, rxconf++) {
+ rxr = &adapter->rx_rings[i];
+ rxr->adapter = adapter;
+ rxr->me = i;
+
+ /* Initialize the RX lock */
+ snprintf(rxr->mtx_name, sizeof(rxr->mtx_name), "%s:rx(%d)",
+ device_get_nameunit(dev), txr->me);
+ mtx_init(&rxr->rx_mtx, rxr->mtx_name, NULL, MTX_DEF);
+
+ if (em_dma_malloc(adapter, rsize,
+ &rxr->rxdma, BUS_DMA_NOWAIT)) {
+ device_printf(dev,
+ "Unable to allocate RxDescriptor memory\n");
+ error = ENOMEM;
+ goto err_rx_desc;
+ }
+ rxr->rx_base = (struct e1000_rx_desc *)rxr->rxdma.dma_vaddr;
+ bzero((void *)rxr->rx_base, rsize);
+
+ /* Allocate receive buffers for the ring*/
+ if (em_allocate_receive_buffers(rxr)) {
+ device_printf(dev,
+ "Critical Failure setting up receive buffers\n");
+ error = ENOMEM;
+ goto err_rx_desc;
+ }
+ }
+
+ return (0);
+
+err_rx_desc:
+ for (rxr = adapter->rx_rings; rxconf > 0; rxr++, rxconf--)
+ em_dma_free(adapter, &rxr->rxdma);
+err_tx_desc:
+ for (txr = adapter->tx_rings; txconf > 0; txr++, txconf--)
+ em_dma_free(adapter, &txr->txdma);
+ free(adapter->rx_rings, M_DEVBUF);
+rx_fail:
+ buf_ring_free(txr->br, M_DEVBUF);
+ free(adapter->tx_rings, M_DEVBUF);
+fail:
+ return (error);
+}
+
+
+/*********************************************************************
+ *
* Allocate memory for tx_buffer structures. The tx_buffer stores all
- * the information needed to transmit a packet on the wire.
+ * the information needed to transmit a packet on the wire. This is
+ * called only once at attach, setup is done every reset.
*
**********************************************************************/
static int
-em_allocate_transmit_structures(struct adapter *adapter)
+em_allocate_transmit_buffers(struct tx_ring *txr)
{
+ struct adapter *adapter = txr->adapter;
device_t dev = adapter->dev;
- struct em_buffer *tx_buffer;
- int error;
+ struct em_buffer *txbuf;
+ int error, i;
/*
- * Create DMA tags for tx descriptors
+ * Setup DMA descriptor areas.
*/
-#if __FreeBSD_version >= 700000
- if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
-#else
- if ((error = bus_dma_tag_create(NULL, /* parent */
-#endif
- 1, 0, /* alignment, bounds */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- EM_TSO_SIZE, /* maxsize */
- EM_MAX_SCATTER, /* nsegments */
- EM_TSO_SEG_SIZE, /* maxsegsize */
- 0, /* flags */
- NULL, /* lockfunc */
- NULL, /* lockarg */
- &adapter->txtag)) != 0) {
- device_printf(dev, "Unable to allocate TX DMA tag\n");
+ if ((error = bus_dma_tag_create(bus_get_dma_tag(dev),
+ 1, 0, /* alignment, bounds */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ EM_TSO_SIZE, /* maxsize */
+ EM_MAX_SCATTER, /* nsegments */
+ PAGE_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockfuncarg */
+ &txr->txtag))) {
+ device_printf(dev,"Unable to allocate TX DMA tag\n");
goto fail;
}
- adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) *
- adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (adapter->tx_buffer_area == NULL) {
+ if (!(txr->tx_buffers =
+ (struct em_buffer *) malloc(sizeof(struct em_buffer) *
+ adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) {
device_printf(dev, "Unable to allocate tx_buffer memory\n");
error = ENOMEM;
goto fail;
}
- /* Create the descriptor buffer dma maps */
- for (int i = 0; i < adapter->num_tx_desc; i++) {
- tx_buffer = &adapter->tx_buffer_area[i];
- error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map);
+ /* Create the descriptor buffer dma maps */
+ txbuf = txr->tx_buffers;
+ for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) {
+ error = bus_dmamap_create(txr->txtag, 0, &txbuf->map);
if (error != 0) {
device_printf(dev, "Unable to create TX DMA map\n");
goto fail;
}
- tx_buffer->next_eop = -1;
}
- return (0);
+ return 0;
fail:
+ /* We free all, it handles case where we are in the middle */
em_free_transmit_structures(adapter);
return (error);
}
/*********************************************************************
*
- * (Re)Initialize transmit structures.
+ * Initialize a transmit ring.
*
**********************************************************************/
static void
-em_setup_transmit_structures(struct adapter *adapter)
+em_setup_transmit_ring(struct tx_ring *txr)
{
- struct em_buffer *tx_buffer;
+ struct adapter *adapter = txr->adapter;
+ struct em_buffer *txbuf;
+ int i;
- /* Clear the old ring contents */
- bzero(adapter->tx_desc_base,
- (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
-
- /* Free any existing TX buffers */
- for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
- tx_buffer = &adapter->tx_buffer_area[i];
- bus_dmamap_sync(adapter->txtag, tx_buffer->map,
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(adapter->txtag, tx_buffer->map);
- m_freem(tx_buffer->m_head);
- tx_buffer->m_head = NULL;
- tx_buffer->next_eop = -1;
- }
+ /* Clear the old descriptor contents */
+ EM_TX_LOCK(txr);
+ bzero((void *)txr->tx_base,
+ (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
+ /* Reset indices */
+ txr->next_avail_desc = 0;
+ txr->next_to_clean = 0;
+
+ /* Free any existing tx buffers. */
+ txbuf = txr->tx_buffers;
+ for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) {
+ if (txbuf->m_head != NULL) {
+ bus_dmamap_sync(txr->txtag, txbuf->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(txr->txtag, txbuf->map);
+ m_freem(txbuf->m_head);
+ txbuf->m_head = NULL;
+ }
+ /* clear the watch index */
+ txbuf->next_eop = -1;
+ }
- /* Reset state */
- adapter->next_avail_tx_desc = 0;
- adapter->next_tx_to_clean = 0;
- adapter->num_tx_desc_avail = adapter->num_tx_desc;
+ /* Set number of descriptors available */
+ txr->tx_avail = adapter->num_tx_desc;
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ EM_TX_UNLOCK(txr);
+}
+
+/*********************************************************************
+ *
+ * Initialize all transmit rings.
+ *
+ **********************************************************************/
+static void
+em_setup_transmit_structures(struct adapter *adapter)
+{
+ struct tx_ring *txr = adapter->tx_rings;
+
+ for (int i = 0; i < adapter->num_queues; i++, txr++)
+ em_setup_transmit_ring(txr);
return;
}
@@ -3449,25 +3083,31 @@ em_setup_transmit_structures(struct adapter *adapter)
static void
em_initialize_transmit_unit(struct adapter *adapter)
{
+ struct tx_ring *txr = adapter->tx_rings;
+ struct e1000_hw *hw = &adapter->hw;
u32 tctl, tarc, tipg = 0;
- u64 bus_addr;
INIT_DEBUGOUT("em_initialize_transmit_unit: begin");
- /* Setup the Base and Length of the Tx Descriptor Ring */
- bus_addr = adapter->txdma.dma_paddr;
- E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0),
- adapter->num_tx_desc * sizeof(struct e1000_tx_desc));
- E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0),
- (u32)(bus_addr >> 32));
- E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0),
- (u32)bus_addr);
- /* Setup the HW Tx Head and Tail descriptor pointers */
- E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0);
- E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0);
-
- HW_DEBUGOUT2("Base = %x, Length = %x\n",
- E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)),
- E1000_READ_REG(&adapter->hw, E1000_TDLEN(0)));
+
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ u64 bus_addr = txr->txdma.dma_paddr;
+ /* Base and Len of TX Ring */
+ E1000_WRITE_REG(hw, E1000_TDLEN(i),
+ adapter->num_tx_desc * sizeof(struct e1000_tx_desc));
+ E1000_WRITE_REG(hw, E1000_TDBAH(i),
+ (u32)(bus_addr >> 32));
+ E1000_WRITE_REG(hw, E1000_TDBAL(i),
+ (u32)bus_addr);
+ /* Init the HEAD/TAIL indices */
+ E1000_WRITE_REG(hw, E1000_TDT(i), 0);
+ E1000_WRITE_REG(hw, E1000_TDH(i), 0);
+
+ HW_DEBUGOUT2("Base = %x, Length = %x\n",
+ E1000_READ_REG(&adapter->hw, E1000_TDBAL(i)),
+ E1000_READ_REG(&adapter->hw, E1000_TDLEN(i)));
+
+ txr->watchdog_check = FALSE;
+ }
/* Set the default values for the Tx Inter Packet Gap timer */
switch (adapter->hw.mac.type) {
@@ -3494,6 +3134,7 @@ em_initialize_transmit_unit(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg);
E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value);
+
if(adapter->hw.mac.type >= e1000_82540)
E1000_WRITE_REG(&adapter->hw, E1000_TADV,
adapter->tx_abs_int_delay.value);
@@ -3512,6 +3153,10 @@ em_initialize_transmit_unit(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
}
+ adapter->txd_cmd = E1000_TXD_CMD_IFCS;
+ if (adapter->tx_int_delay.value > 0)
+ adapter->txd_cmd |= E1000_TXD_CMD_IDE;
+
/* Program the Transmit Control Register */
tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
tctl &= ~E1000_TCTL_CT;
@@ -3524,59 +3169,84 @@ em_initialize_transmit_unit(struct adapter *adapter)
/* This write will effectively turn on the transmit unit. */
E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
- /* Setup Transmit Descriptor Base Settings */
- adapter->txd_cmd = E1000_TXD_CMD_IFCS;
-
- if (adapter->tx_int_delay.value > 0)
- adapter->txd_cmd |= E1000_TXD_CMD_IDE;
}
+
/*********************************************************************
*
- * Free all transmit related data structures.
+ * Free all transmit rings.
*
**********************************************************************/
static void
em_free_transmit_structures(struct adapter *adapter)
{
- struct em_buffer *tx_buffer;
+ struct tx_ring *txr = adapter->tx_rings;
- INIT_DEBUGOUT("free_transmit_structures: begin");
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ EM_TX_LOCK(txr);
+ em_free_transmit_buffers(txr);
+ em_dma_free(adapter, &txr->txdma);
+ EM_TX_UNLOCK(txr);
+ EM_TX_LOCK_DESTROY(txr);
+ }
- if (adapter->tx_buffer_area != NULL) {
- for (int i = 0; i < adapter->num_tx_desc; i++) {
- tx_buffer = &adapter->tx_buffer_area[i];
- if (tx_buffer->m_head != NULL) {
- bus_dmamap_sync(adapter->txtag, tx_buffer->map,
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(adapter->txtag,
- tx_buffer->map);
- m_freem(tx_buffer->m_head);
- tx_buffer->m_head = NULL;
- } else if (tx_buffer->map != NULL)
- bus_dmamap_unload(adapter->txtag,
- tx_buffer->map);
- if (tx_buffer->map != NULL) {
- bus_dmamap_destroy(adapter->txtag,
- tx_buffer->map);
- tx_buffer->map = NULL;
+ free(adapter->tx_rings, M_DEVBUF);
+}
+
+/*********************************************************************
+ *
+ * Free transmit ring related data structures.
+ *
+ **********************************************************************/
+static void
+em_free_transmit_buffers(struct tx_ring *txr)
+{
+ struct adapter *adapter = txr->adapter;
+ struct em_buffer *txbuf;
+
+ INIT_DEBUGOUT("free_transmit_ring: begin");
+
+ if (txr->tx_buffers == NULL)
+ return;
+
+ for (int i = 0; i < adapter->num_tx_desc; i++) {
+ txbuf = &txr->tx_buffers[i];
+ if (txbuf->m_head != NULL) {
+ bus_dmamap_sync(txr->txtag, txbuf->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(txr->txtag,
+ txbuf->map);
+ m_freem(txbuf->m_head);
+ txbuf->m_head = NULL;
+ if (txbuf->map != NULL) {
+ bus_dmamap_destroy(txr->txtag,
+ txbuf->map);
+ txbuf->map = NULL;
}
+ } else if (txbuf->map != NULL) {
+ bus_dmamap_unload(txr->txtag,
+ txbuf->map);
+ bus_dmamap_destroy(txr->txtag,
+ txbuf->map);
+ txbuf->map = NULL;
}
}
- if (adapter->tx_buffer_area != NULL) {
- free(adapter->tx_buffer_area, M_DEVBUF);
- adapter->tx_buffer_area = NULL;
- }
- if (adapter->txtag != NULL) {
- bus_dma_tag_destroy(adapter->txtag);
- adapter->txtag = NULL;
- }
#if __FreeBSD_version >= 800000
- if (adapter->br != NULL)
- buf_ring_free(adapter->br, M_DEVBUF);
+ if (txr->br != NULL)
+ buf_ring_free(txr->br, M_DEVBUF);
#endif
+ if (txr->tx_buffers != NULL) {
+ free(txr->tx_buffers, M_DEVBUF);
+ txr->tx_buffers = NULL;
+ }
+ if (txr->txtag != NULL) {
+ bus_dma_tag_destroy(txr->txtag);
+ txr->txtag = NULL;
+ }
+ return;
}
+
/*********************************************************************
*
* The offload context needs to be set when we transfer the first
@@ -3588,22 +3258,23 @@ em_free_transmit_structures(struct adapter *adapter)
* big performance win. -jfv
**********************************************************************/
static void
-em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
+em_transmit_checksum_setup(struct tx_ring *txr, struct mbuf *mp,
u32 *txd_upper, u32 *txd_lower)
{
- struct e1000_context_desc *TXD = NULL;
+ struct adapter *adapter = txr->adapter;
+ struct e1000_context_desc *TXD = NULL;
struct em_buffer *tx_buffer;
struct ether_vlan_header *eh;
struct ip *ip = NULL;
struct ip6_hdr *ip6;
- int curr_txd, ehdrlen;
+ int cur, ehdrlen;
u32 cmd, hdr_len, ip_hlen;
u16 etype;
u8 ipproto;
cmd = hdr_len = ipproto = 0;
- curr_txd = adapter->next_avail_tx_desc;
+ cur = txr->next_avail_desc;
/*
* Determine where frame payload starts.
@@ -3636,7 +3307,7 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
* Offset of place to put the checksum.
*/
TXD = (struct e1000_context_desc *)
- &adapter->tx_desc_base[curr_txd];
+ &txr->tx_base[cur];
TXD->lower_setup.ip_fields.ipcss = ehdrlen;
TXD->lower_setup.ip_fields.ipcse =
htole16(ehdrlen + ip_hlen);
@@ -3678,16 +3349,16 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
/* no need for context if already set */
- if (adapter->last_hw_offload == CSUM_TCP)
+ if (txr->last_hw_offload == CSUM_TCP)
return;
- adapter->last_hw_offload = CSUM_TCP;
+ txr->last_hw_offload = CSUM_TCP;
/*
* Start offset for payload checksum calculation.
* End offset for payload checksum calculation.
* Offset of place to put the checksum.
*/
TXD = (struct e1000_context_desc *)
- &adapter->tx_desc_base[curr_txd];
+ &txr->tx_base[cur];
TXD->upper_setup.tcp_fields.tucss = hdr_len;
TXD->upper_setup.tcp_fields.tucse = htole16(0);
TXD->upper_setup.tcp_fields.tucso =
@@ -3701,16 +3372,16 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
/* no need for context if already set */
- if (adapter->last_hw_offload == CSUM_UDP)
+ if (txr->last_hw_offload == CSUM_UDP)
return;
- adapter->last_hw_offload = CSUM_UDP;
+ txr->last_hw_offload = CSUM_UDP;
/*
* Start offset for header checksum calculation.
* End offset for header checksum calculation.
* Offset of place to put the checksum.
*/
TXD = (struct e1000_context_desc *)
- &adapter->tx_desc_base[curr_txd];
+ &txr->tx_base[cur];
TXD->upper_setup.tcp_fields.tucss = hdr_len;
TXD->upper_setup.tcp_fields.tucse = htole16(0);
TXD->upper_setup.tcp_fields.tucso =
@@ -3725,35 +3396,35 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
TXD->tcp_seg_setup.data = htole32(0);
TXD->cmd_and_length =
htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd);
- tx_buffer = &adapter->tx_buffer_area[curr_txd];
+ tx_buffer = &txr->tx_buffers[cur];
tx_buffer->m_head = NULL;
tx_buffer->next_eop = -1;
- if (++curr_txd == adapter->num_tx_desc)
- curr_txd = 0;
+ if (++cur == adapter->num_tx_desc)
+ cur = 0;
- adapter->num_tx_desc_avail--;
- adapter->next_avail_tx_desc = curr_txd;
+ txr->tx_avail--;
+ txr->next_avail_desc = cur;
}
-#if __FreeBSD_version >= 700000
/**********************************************************************
*
* Setup work for hardware segmentation offload (TSO)
*
**********************************************************************/
static bool
-em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper,
+em_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *txd_upper,
u32 *txd_lower)
{
- struct e1000_context_desc *TXD;
- struct em_buffer *tx_buffer;
- struct ether_vlan_header *eh;
- struct ip *ip;
- struct ip6_hdr *ip6;
- struct tcphdr *th;
- int curr_txd, ehdrlen, hdr_len, ip_hlen, isip6;
+ struct adapter *adapter = txr->adapter;
+ struct e1000_context_desc *TXD;
+ struct em_buffer *tx_buffer;
+ struct ether_vlan_header *eh;
+ struct ip *ip;
+ struct ip6_hdr *ip6;
+ struct tcphdr *th;
+ int cur, ehdrlen, hdr_len, ip_hlen, isip6;
u16 etype;
/*
@@ -3833,9 +3504,9 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper,
*txd_upper = ((isip6 ? 0 : E1000_TXD_POPTS_IXSM) |
E1000_TXD_POPTS_TXSM) << 8;
- curr_txd = adapter->next_avail_tx_desc;
- tx_buffer = &adapter->tx_buffer_area[curr_txd];
- TXD = (struct e1000_context_desc *) &adapter->tx_desc_base[curr_txd];
+ cur = txr->next_avail_desc;
+ tx_buffer = &txr->tx_buffers[cur];
+ TXD = (struct e1000_context_desc *) &txr->tx_base[cur];
/* IPv6 doesn't have a header checksum. */
if (!isip6) {
@@ -3870,24 +3541,23 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper,
TXD->cmd_and_length = htole32(adapter->txd_cmd |
E1000_TXD_CMD_DEXT | /* Extended descr */
E1000_TXD_CMD_TSE | /* TSE context */
- (isip6 ? 0 : E1000_TXD_CMD_IP) | /* Do IP csum */
+ (isip6 ? 0 : E1000_TXD_CMD_IP) |
E1000_TXD_CMD_TCP | /* Do TCP checksum */
(mp->m_pkthdr.len - (hdr_len))); /* Total len */
tx_buffer->m_head = NULL;
tx_buffer->next_eop = -1;
- if (++curr_txd == adapter->num_tx_desc)
- curr_txd = 0;
+ if (++cur == adapter->num_tx_desc)
+ cur = 0;
- adapter->num_tx_desc_avail--;
- adapter->next_avail_tx_desc = curr_txd;
- adapter->tx_tso = TRUE;
+ txr->tx_avail--;
+ txr->next_avail_desc = cur;
+ txr->tx_tso = TRUE;
return TRUE;
}
-#endif /* __FreeBSD_version >= 700000 */
/**********************************************************************
*
@@ -3896,25 +3566,26 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper,
* tx_buffer is put back on the free queue.
*
**********************************************************************/
-static void
-em_txeof(struct adapter *adapter)
+static bool
+em_txeof(struct tx_ring *txr)
{
+ struct adapter *adapter = txr->adapter;
int first, last, done, num_avail;
struct em_buffer *tx_buffer;
struct e1000_tx_desc *tx_desc, *eop_desc;
struct ifnet *ifp = adapter->ifp;
- EM_TX_LOCK_ASSERT(adapter);
+ EM_TX_LOCK_ASSERT(txr);
- if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
- return;
+ if (txr->tx_avail == adapter->num_tx_desc)
+ return (FALSE);
- num_avail = adapter->num_tx_desc_avail;
- first = adapter->next_tx_to_clean;
- tx_desc = &adapter->tx_desc_base[first];
- tx_buffer = &adapter->tx_buffer_area[first];
+ num_avail = txr->tx_avail;
+ first = txr->next_to_clean;
+ tx_desc = &txr->tx_base[first];
+ tx_buffer = &txr->tx_buffers[first];
last = tx_buffer->next_eop;
- eop_desc = &adapter->tx_desc_base[last];
+ eop_desc = &txr->tx_base[last];
/*
* What this does is get the index of the
@@ -3926,7 +3597,7 @@ em_txeof(struct adapter *adapter)
last = 0;
done = last;
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) {
@@ -3939,38 +3610,38 @@ em_txeof(struct adapter *adapter)
if (tx_buffer->m_head) {
ifp->if_opackets++;
- bus_dmamap_sync(adapter->txtag,
+ bus_dmamap_sync(txr->txtag,
tx_buffer->map,
BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(adapter->txtag,
+ bus_dmamap_unload(txr->txtag,
tx_buffer->map);
m_freem(tx_buffer->m_head);
tx_buffer->m_head = NULL;
}
tx_buffer->next_eop = -1;
- adapter->watchdog_time = ticks;
+ txr->watchdog_time = ticks;
if (++first == adapter->num_tx_desc)
first = 0;
- tx_buffer = &adapter->tx_buffer_area[first];
- tx_desc = &adapter->tx_desc_base[first];
+ tx_buffer = &txr->tx_buffers[first];
+ tx_desc = &txr->tx_base[first];
}
/* See if we can continue to the next packet */
last = tx_buffer->next_eop;
if (last != -1) {
- eop_desc = &adapter->tx_desc_base[last];
+ eop_desc = &txr->tx_base[last];
/* Get new done point */
if (++last == adapter->num_tx_desc) last = 0;
done = last;
} else
break;
}
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- adapter->next_tx_to_clean = first;
+ txr->next_to_clean = first;
/*
* If we have enough room, clear IFF_DRV_OACTIVE to
@@ -3980,88 +3651,87 @@ em_txeof(struct adapter *adapter)
if (num_avail > EM_TX_CLEANUP_THRESHOLD) {
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
if (num_avail == adapter->num_tx_desc) {
- adapter->watchdog_check = FALSE;
- adapter->num_tx_desc_avail = num_avail;
- return;
+ txr->watchdog_check = FALSE;
+ txr->tx_avail = num_avail;
+ return (FALSE);
}
}
- adapter->num_tx_desc_avail = num_avail;
- return;
+ txr->tx_avail = num_avail;
+ return (TRUE);
}
-/*********************************************************************
- *
- * When Link is lost sometimes there is work still in the TX ring
- * which may result in a watchdog, rather than allow that we do an
- * attempted cleanup and then reinit here. Note that this has been
- * seens mostly with fiber adapters.
- *
- **********************************************************************/
-static void
-em_tx_purge(struct adapter *adapter)
-{
- if ((!adapter->link_active) && (adapter->watchdog_check)) {
- EM_TX_LOCK(adapter);
- em_txeof(adapter);
- EM_TX_UNLOCK(adapter);
- if (adapter->watchdog_check) /* Still outstanding? */
- em_init_locked(adapter);
- }
-}
/*********************************************************************
*
- * Get a buffer from system mbuf buffer pool.
+ * Refresh RX descriptor mbufs from system mbuf buffer pool.
*
**********************************************************************/
-static int
-em_get_buf(struct adapter *adapter, int i)
+static void
+em_refresh_mbufs(struct rx_ring *rxr, int limit)
{
+ struct adapter *adapter = rxr->adapter;
struct mbuf *m;
bus_dma_segment_t segs[1];
bus_dmamap_t map;
- struct em_buffer *rx_buffer;
- int error, nsegs;
-
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- adapter->mbuf_cluster_failed++;
- return (ENOBUFS);
- }
- m->m_len = m->m_pkthdr.len = MCLBYTES;
-
- if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
- m_adj(m, ETHER_ALIGN);
+ struct em_buffer *rxbuf;
+ int i, error, nsegs, cleaned;
- /*
- * Using memory from the mbuf cluster pool, invoke the
- * bus_dma machinery to arrange the memory mapping.
- */
- error = bus_dmamap_load_mbuf_sg(adapter->rxtag,
- adapter->rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT);
- if (error != 0) {
- m_free(m);
- return (error);
- }
+ i = rxr->next_to_refresh;
+ cleaned = -1;
+ while (i != limit) {
+ m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (m == NULL)
+ goto update;
+ m->m_len = m->m_pkthdr.len = MCLBYTES;
- /* If nsegs is wrong then the stack is corrupt. */
- KASSERT(nsegs == 1, ("Too many segments returned!"));
+ if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
+ m_adj(m, ETHER_ALIGN);
- rx_buffer = &adapter->rx_buffer_area[i];
- if (rx_buffer->m_head != NULL)
- bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
+ /*
+ * Using memory from the mbuf cluster pool, invoke the
+ * bus_dma machinery to arrange the memory mapping.
+ */
+ error = bus_dmamap_load_mbuf_sg(rxr->rxtag, rxr->rx_sparemap,
+ m, segs, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ m_free(m);
+ goto update;
+ }
- map = rx_buffer->map;
- rx_buffer->map = adapter->rx_sparemap;
- adapter->rx_sparemap = map;
- bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
- rx_buffer->m_head = m;
+ /* If nsegs is wrong then the stack is corrupt. */
+ KASSERT(nsegs == 1, ("Too many segments returned!"));
+
+ rxbuf = &rxr->rx_buffers[i];
+ if (rxbuf->m_head != NULL)
+ bus_dmamap_unload(rxr->rxtag, rxbuf->map);
+
+ map = rxbuf->map;
+ rxbuf->map = rxr->rx_sparemap;
+ rxr->rx_sparemap = map;
+ bus_dmamap_sync(rxr->rxtag,
+ rxbuf->map, BUS_DMASYNC_PREREAD);
+ rxbuf->m_head = m;
+ rxr->rx_base[i].buffer_addr = htole64(segs[0].ds_addr);
+
+ cleaned = i;
+ /* Calculate next index */
+ if (++i == adapter->num_rx_desc)
+ i = 0;
+ /* This is the work marker for refresh */
+ rxr->next_to_refresh = i;
+ }
+update:
+ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ if (cleaned != -1) /* Update tail index */
+ E1000_WRITE_REG(&adapter->hw,
+ E1000_RDT(rxr->me), cleaned);
- adapter->rx_desc_base[i].buffer_addr = htole64(segs[0].ds_addr);
- return (0);
+ return;
}
+
/*********************************************************************
*
* Allocate memory for rx_buffer structures. Since we use one
@@ -4071,24 +3741,21 @@ em_get_buf(struct adapter *adapter, int i)
*
**********************************************************************/
static int
-em_allocate_receive_structures(struct adapter *adapter)
+em_allocate_receive_buffers(struct rx_ring *rxr)
{
- device_t dev = adapter->dev;
- struct em_buffer *rx_buffer;
- int i, error;
+ struct adapter *adapter = rxr->adapter;
+ device_t dev = adapter->dev;
+ struct em_buffer *rxbuf;
+ int error;
- adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) *
+ rxr->rx_buffers = malloc(sizeof(struct em_buffer) *
adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (adapter->rx_buffer_area == NULL) {
+ if (rxr->rx_buffers == NULL) {
device_printf(dev, "Unable to allocate rx_buffer memory\n");
return (ENOMEM);
}
-#if __FreeBSD_version >= 700000
error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
-#else
- error = bus_dma_tag_create(NULL, /* parent */
-#endif
1, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -4099,7 +3766,7 @@ em_allocate_receive_structures(struct adapter *adapter)
0, /* flags */
NULL, /* lockfunc */
NULL, /* lockarg */
- &adapter->rxtag);
+ &rxr->rxtag);
if (error) {
device_printf(dev, "%s: bus_dma_tag_create failed %d\n",
__func__, error);
@@ -4107,18 +3774,19 @@ em_allocate_receive_structures(struct adapter *adapter)
}
/* Create the spare map (used by getbuf) */
- error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
- &adapter->rx_sparemap);
+ error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT,
+ &rxr->rx_sparemap);
if (error) {
device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
__func__, error);
goto fail;
}
- rx_buffer = adapter->rx_buffer_area;
- for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
- error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
- &rx_buffer->map);
+ rxbuf = rxr->rx_buffers;
+ for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) {
+ rxbuf = &rxr->rx_buffers[i];
+ error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT,
+ &rxbuf->map);
if (error) {
device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
__func__, error);
@@ -4133,50 +3801,184 @@ fail:
return (error);
}
+
/*********************************************************************
*
- * (Re)initialize receive structures.
+ * Initialize a receive ring and its buffers.
*
**********************************************************************/
static int
-em_setup_receive_structures(struct adapter *adapter)
+em_setup_receive_ring(struct rx_ring *rxr)
{
- struct em_buffer *rx_buffer;
- int i, error;
-
- /* Reset descriptor ring */
- bzero(adapter->rx_desc_base,
- (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc);
-
- /* Free current RX buffers. */
- rx_buffer = adapter->rx_buffer_area;
- for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
- if (rx_buffer->m_head != NULL) {
- bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
+ struct adapter *adapter = rxr->adapter;
+ struct em_buffer *rxbuf;
+ bus_dma_segment_t seg[1];
+ int rsize, nsegs, error;
+
+
+ /* Clear the ring contents */
+ EM_RX_LOCK(rxr);
+ rsize = roundup2(adapter->num_rx_desc *
+ sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
+ bzero((void *)rxr->rx_base, rsize);
+
+ /*
+ ** Free current RX buffer structs and their mbufs
+ */
+ for (int i = 0; i < adapter->num_rx_desc; i++) {
+ rxbuf = &rxr->rx_buffers[i];
+ if (rxbuf->m_head != NULL) {
+ bus_dmamap_sync(rxr->rxtag, rxbuf->map,
BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
- m_freem(rx_buffer->m_head);
- rx_buffer->m_head = NULL;
+ bus_dmamap_unload(rxr->rxtag, rxbuf->map);
+ m_freem(rxbuf->m_head);
}
- }
+ }
- /* Allocate new ones. */
- for (i = 0; i < adapter->num_rx_desc; i++) {
- error = em_get_buf(adapter, i);
- if (error)
- return (error);
+ /* Now replenish the mbufs */
+ for (int j = 0; j != adapter->num_rx_desc; ++j) {
+
+ rxbuf = &rxr->rx_buffers[j];
+ rxbuf->m_head = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (rxbuf->m_head == NULL)
+ panic("RX ring hdr initialization failed!\n");
+ rxbuf->m_head->m_len = MCLBYTES;
+ rxbuf->m_head->m_flags &= ~M_HASFCS; /* we strip it */
+ rxbuf->m_head->m_pkthdr.len = MCLBYTES;
+
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->rxtag,
+ rxbuf->map, rxbuf->m_head, seg,
+ &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0)
+ panic("RX ring dma initialization failed!\n");
+ bus_dmamap_sync(rxr->rxtag,
+ rxbuf->map, BUS_DMASYNC_PREREAD);
+
+ /* Update descriptor */
+ rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr);
}
- /* Setup our descriptor pointers */
- adapter->next_rx_desc_to_check = 0;
- bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
+
+ /* Setup our descriptor indices */
+ rxr->next_to_check = 0;
+ rxr->next_to_refresh = 0;
+
+ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ EM_RX_UNLOCK(rxr);
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * Initialize all receive rings.
+ *
+ **********************************************************************/
+static int
+em_setup_receive_structures(struct adapter *adapter)
+{
+ struct rx_ring *rxr = adapter->rx_rings;
+ int j;
+
+ for (j = 0; j < adapter->num_queues; j++, rxr++)
+ if (em_setup_receive_ring(rxr))
+ goto fail;
+
return (0);
+fail:
+ /*
+ * Free RX buffers allocated so far, we will only handle
+ * the rings that completed, the failing case will have
+ * cleaned up for itself. 'j' failed, so its the terminus.
+ */
+ for (int i = 0; i < j; ++i) {
+ rxr = &adapter->rx_rings[i];
+ for (int n = 0; n < adapter->num_rx_desc; n++) {
+ struct em_buffer *rxbuf;
+ rxbuf = &rxr->rx_buffers[n];
+ if (rxbuf->m_head != NULL) {
+ bus_dmamap_sync(rxr->rxtag, rxbuf->map,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(rxr->rxtag, rxbuf->map);
+ m_freem(rxbuf->m_head);
+ rxbuf->m_head = NULL;
+ }
+ }
+ }
+
+ return (ENOBUFS);
}
/*********************************************************************
*
+ * Free all receive rings.
+ *
+ **********************************************************************/
+static void
+em_free_receive_structures(struct adapter *adapter)
+{
+ struct rx_ring *rxr = adapter->rx_rings;
+
+ for (int i = 0; i < adapter->num_queues; i++, rxr++) {
+ em_free_receive_buffers(rxr);
+ /* Free the ring memory as well */
+ em_dma_free(adapter, &rxr->rxdma);
+ EM_RX_LOCK_DESTROY(rxr);
+ }
+
+ free(adapter->rx_rings, M_DEVBUF);
+}
+
+
+/*********************************************************************
+ *
+ * Free receive ring data structures
+ *
+ **********************************************************************/
+static void
+em_free_receive_buffers(struct rx_ring *rxr)
+{
+ struct adapter *adapter = rxr->adapter;
+ struct em_buffer *rxbuf = NULL;
+
+ INIT_DEBUGOUT("free_receive_buffers: begin");
+
+ if (rxr->rx_sparemap) {
+ bus_dmamap_destroy(rxr->rxtag, rxr->rx_sparemap);
+ rxr->rx_sparemap = NULL;
+ }
+
+ if (rxr->rx_buffers != NULL) {
+ for (int i = 0; i < adapter->num_rx_desc; i++) {
+ rxbuf = &rxr->rx_buffers[i];
+ if (rxbuf->map != NULL) {
+ bus_dmamap_sync(rxr->rxtag, rxbuf->map,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(rxr->rxtag, rxbuf->map);
+ bus_dmamap_destroy(rxr->rxtag, rxbuf->map);
+ }
+ if (rxbuf->m_head != NULL) {
+ m_freem(rxbuf->m_head);
+ rxbuf->m_head = NULL;
+ }
+ }
+ free(rxr->rx_buffers, M_DEVBUF);
+ rxr->rx_buffers = NULL;
+ }
+
+ if (rxr->rxtag != NULL) {
+ bus_dma_tag_destroy(rxr->rxtag);
+ rxr->rxtag = NULL;
+ }
+
+ return;
+}
+
+
+/*********************************************************************
+ *
* Enable receive unit.
*
**********************************************************************/
@@ -4186,96 +3988,46 @@ em_setup_receive_structures(struct adapter *adapter)
static void
em_initialize_receive_unit(struct adapter *adapter)
{
+ struct rx_ring *rxr = adapter->rx_rings;
struct ifnet *ifp = adapter->ifp;
+ struct e1000_hw *hw = &adapter->hw;
u64 bus_addr;
u32 rctl, rxcsum;
- INIT_DEBUGOUT("em_initialize_receive_unit: begin");
+ INIT_DEBUGOUT("em_initialize_receive_units: begin");
/*
* Make sure receives are disabled while setting
* up the descriptor ring
*/
- rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
- E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
+ rctl = E1000_READ_REG(hw, E1000_RCTL);
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
- if (adapter->hw.mac.type >= e1000_82540) {
- E1000_WRITE_REG(&adapter->hw, E1000_RADV,
- adapter->rx_abs_int_delay.value);
- /*
- * Set the interrupt throttling rate. Value is calculated
- * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
- */
- E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR);
- }
+ E1000_WRITE_REG(&adapter->hw, E1000_RADV,
+ adapter->rx_abs_int_delay.value);
+ /*
+ * Set the interrupt throttling rate. Value is calculated
+ * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
+ */
+ E1000_WRITE_REG(hw, E1000_ITR, DEFAULT_ITR);
/*
** When using MSIX interrupts we need to throttle
** using the EITR register (82574 only)
*/
- if (adapter->msix)
+ if (hw->mac.type == e1000_82574)
for (int i = 0; i < 4; i++)
- E1000_WRITE_REG(&adapter->hw,
- E1000_EITR_82574(i), DEFAULT_ITR);
+ E1000_WRITE_REG(hw, E1000_EITR_82574(i),
+ DEFAULT_ITR);
/* Disable accelerated ackknowledge */
if (adapter->hw.mac.type == e1000_82574)
- E1000_WRITE_REG(&adapter->hw,
- E1000_RFCTL, E1000_RFCTL_ACK_DIS);
-
- /* Setup the Base and Length of the Rx Descriptor Ring */
- bus_addr = adapter->rxdma.dma_paddr;
- E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0),
- adapter->num_rx_desc * sizeof(struct e1000_rx_desc));
- E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0),
- (u32)(bus_addr >> 32));
- E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0),
- (u32)bus_addr);
-
- /* Setup the Receive Control Register */
- rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
- rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
- E1000_RCTL_RDMTS_HALF |
- (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
-
- /* Make sure VLAN Filters are off */
- rctl &= ~E1000_RCTL_VFE;
-
- if (e1000_tbi_sbp_enabled_82543(&adapter->hw))
- rctl |= E1000_RCTL_SBP;
- else
- rctl &= ~E1000_RCTL_SBP;
-
- switch (adapter->rx_buffer_len) {
- default:
- case 2048:
- rctl |= E1000_RCTL_SZ_2048;
- break;
- case 4096:
- rctl |= E1000_RCTL_SZ_4096 |
- E1000_RCTL_BSEX | E1000_RCTL_LPE;
- break;
- case 8192:
- rctl |= E1000_RCTL_SZ_8192 |
- E1000_RCTL_BSEX | E1000_RCTL_LPE;
- break;
- case 16384:
- rctl |= E1000_RCTL_SZ_16384 |
- E1000_RCTL_BSEX | E1000_RCTL_LPE;
- break;
- }
-
- if (ifp->if_mtu > ETHERMTU)
- rctl |= E1000_RCTL_LPE;
- else
- rctl &= ~E1000_RCTL_LPE;
+ E1000_WRITE_REG(hw, E1000_RFCTL, E1000_RFCTL_ACK_DIS);
- /* Enable 82543 Receive Checksum Offload for TCP and UDP */
- if ((adapter->hw.mac.type >= e1000_82543) &&
- (ifp->if_capenable & IFCAP_RXCSUM)) {
- rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM);
+ if (ifp->if_capenable & IFCAP_RXCSUM) {
+ rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
- E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum);
+ E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
}
/*
@@ -4285,73 +4037,46 @@ em_initialize_receive_unit(struct adapter *adapter)
** values in RDTR is a known source of problems on other
** platforms another solution is being sought.
*/
- if (adapter->hw.mac.type == e1000_82573)
- E1000_WRITE_REG(&adapter->hw, E1000_RDTR, 0x20);
+ if (hw->mac.type == e1000_82573)
+ E1000_WRITE_REG(hw, E1000_RDTR, 0x20);
- /* Enable Receives */
- E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
-
- /*
- * Setup the HW Rx Head and
- * Tail Descriptor Pointers
- */
- E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0);
- E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1);
-
- return;
-}
-
-/*********************************************************************
- *
- * Free receive related data structures.
- *
- **********************************************************************/
-static void
-em_free_receive_structures(struct adapter *adapter)
-{
- struct em_buffer *rx_buffer;
- int i;
+ for (int i = 0; i < adapter->num_queues; i++, rxr++) {
+ /* Setup the Base and Length of the Rx Descriptor Ring */
+ bus_addr = rxr->rxdma.dma_paddr;
+ E1000_WRITE_REG(hw, E1000_RDLEN(i),
+ adapter->num_rx_desc * sizeof(struct e1000_rx_desc));
+ E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32));
+ E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr);
+ /* Setup the Head and Tail Descriptor Pointers */
+ E1000_WRITE_REG(hw, E1000_RDH(i), 0);
+ E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1);
+ }
- INIT_DEBUGOUT("free_receive_structures: begin");
+ /* Setup the Receive Control Register */
+ rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
+ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+ (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
- if (adapter->rx_sparemap) {
- bus_dmamap_destroy(adapter->rxtag, adapter->rx_sparemap);
- adapter->rx_sparemap = NULL;
- }
+ /* Strip the CRC */
+ rctl |= E1000_RCTL_SECRC;
- /* Cleanup any existing buffers */
- if (adapter->rx_buffer_area != NULL) {
- rx_buffer = adapter->rx_buffer_area;
- for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
- if (rx_buffer->m_head != NULL) {
- bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
- BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(adapter->rxtag,
- rx_buffer->map);
- m_freem(rx_buffer->m_head);
- rx_buffer->m_head = NULL;
- } else if (rx_buffer->map != NULL)
- bus_dmamap_unload(adapter->rxtag,
- rx_buffer->map);
- if (rx_buffer->map != NULL) {
- bus_dmamap_destroy(adapter->rxtag,
- rx_buffer->map);
- rx_buffer->map = NULL;
- }
- }
- }
+ /* Make sure VLAN Filters are off */
+ rctl &= ~E1000_RCTL_VFE;
+ rctl &= ~E1000_RCTL_SBP;
+ rctl |= E1000_RCTL_SZ_2048;
+ if (ifp->if_mtu > ETHERMTU)
+ rctl |= E1000_RCTL_LPE;
+ else
+ rctl &= ~E1000_RCTL_LPE;
- if (adapter->rx_buffer_area != NULL) {
- free(adapter->rx_buffer_area, M_DEVBUF);
- adapter->rx_buffer_area = NULL;
- }
+ /* Write out the settings */
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- if (adapter->rxtag != NULL) {
- bus_dma_tag_destroy(adapter->rxtag);
- adapter->rxtag = NULL;
- }
+ return;
}
+
/*********************************************************************
*
* This routine executes in interrupt context. It replenishes
@@ -4364,184 +4089,134 @@ em_free_receive_structures(struct adapter *adapter)
* For polling we also now return the number of cleaned packets
*********************************************************************/
static int
-em_rxeof(struct adapter *adapter, int count)
+em_rxeof(struct rx_ring *rxr, int count)
{
- struct ifnet *ifp = adapter->ifp;;
- struct mbuf *mp;
- u8 status, accept_frame = 0, eop = 0;
- u16 len, desc_len, prev_len_adj;
- int i, rx_sent = 0;
- struct e1000_rx_desc *current_desc;
-
- EM_RX_LOCK(adapter);
- i = adapter->next_rx_desc_to_check;
- current_desc = &adapter->rx_desc_base[i];
- bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
- BUS_DMASYNC_POSTREAD);
-
- if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
- EM_RX_UNLOCK(adapter);
- return (rx_sent);
- }
+ struct adapter *adapter = rxr->adapter;
+ struct ifnet *ifp = adapter->ifp;
+ struct mbuf *mp, *sendmp;
+ u8 status = 0;
+ u16 len;
+ int i, processed, rxdone = 0;
+ bool eop;
+ struct e1000_rx_desc *cur;
- while ((current_desc->status & E1000_RXD_STAT_DD) &&
- (count != 0) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- struct mbuf *m = NULL;
+ EM_RX_LOCK_ASSERT(rxr);
- mp = adapter->rx_buffer_area[i].m_head;
- /*
- * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT
- * needs to access the last received byte in the mbuf.
- */
- bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
- BUS_DMASYNC_POSTREAD);
-
- accept_frame = 1;
- prev_len_adj = 0;
- desc_len = le16toh(current_desc->length);
- status = current_desc->status;
- if (status & E1000_RXD_STAT_EOP) {
- count--;
- eop = 1;
- if (desc_len < ETHER_CRC_LEN) {
- len = 0;
- prev_len_adj = ETHER_CRC_LEN - desc_len;
- } else
- len = desc_len - ETHER_CRC_LEN;
- } else {
- eop = 0;
- len = desc_len;
- }
+ for (i = rxr->next_to_check, processed = 0; count != 0;) {
- if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
- u8 last_byte;
- u32 pkt_len = desc_len;
-
- if (adapter->fmp != NULL)
- pkt_len += adapter->fmp->m_pkthdr.len;
-
- last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
- if (TBI_ACCEPT(&adapter->hw, status,
- current_desc->errors, pkt_len, last_byte,
- adapter->min_frame_size, adapter->max_frame_size)) {
- e1000_tbi_adjust_stats_82543(&adapter->hw,
- &adapter->stats, pkt_len,
- adapter->hw.mac.addr,
- adapter->max_frame_size);
- if (len > 0)
- len--;
- } else
- accept_frame = 0;
- }
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
- if (accept_frame) {
- if (em_get_buf(adapter, i) != 0) {
- ifp->if_iqdrops++;
- goto discard;
- }
+ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ cur = &rxr->rx_base[i];
+ status = cur->status;
+ mp = sendmp = NULL;
+
+ if ((status & E1000_RXD_STAT_DD) == 0)
+ break;
+
+ len = le16toh(cur->length);
+ eop = (status & E1000_RXD_STAT_EOP) != 0;
+ count--;
+
+ if ((cur->errors & E1000_RXD_ERR_FRAME_ERR_MASK) == 0) {
/* Assign correct length to the current fragment */
+ mp = rxr->rx_buffers[i].m_head;
mp->m_len = len;
- if (adapter->fmp == NULL) {
+ if (rxr->fmp == NULL) {
mp->m_pkthdr.len = len;
- adapter->fmp = mp; /* Store the first mbuf */
- adapter->lmp = mp;
+ rxr->fmp = mp; /* Store the first mbuf */
+ rxr->lmp = mp;
} else {
/* Chain mbuf's together */
mp->m_flags &= ~M_PKTHDR;
- /*
- * Adjust length of previous mbuf in chain if
- * we received less than 4 bytes in the last
- * descriptor.
- */
- if (prev_len_adj > 0) {
- adapter->lmp->m_len -= prev_len_adj;
- adapter->fmp->m_pkthdr.len -=
- prev_len_adj;
- }
- adapter->lmp->m_next = mp;
- adapter->lmp = adapter->lmp->m_next;
- adapter->fmp->m_pkthdr.len += len;
+ rxr->lmp->m_next = mp;
+ rxr->lmp = rxr->lmp->m_next;
+ rxr->fmp->m_pkthdr.len += len;
}
if (eop) {
- adapter->fmp->m_pkthdr.rcvif = ifp;
+ rxr->fmp->m_pkthdr.rcvif = ifp;
ifp->if_ipackets++;
- em_receive_checksum(adapter, current_desc,
- adapter->fmp);
+ em_receive_checksum(cur, rxr->fmp);
#ifndef __NO_STRICT_ALIGNMENT
if (adapter->max_frame_size >
(MCLBYTES - ETHER_ALIGN) &&
- em_fixup_rx(adapter) != 0)
+ em_fixup_rx(rxr) != 0)
goto skip;
#endif
if (status & E1000_RXD_STAT_VP) {
-#if __FreeBSD_version < 700000
- VLAN_INPUT_TAG_NEW(ifp, adapter->fmp,
- (le16toh(current_desc->special) &
- E1000_RXD_SPC_VLAN_MASK));
-#else
- adapter->fmp->m_pkthdr.ether_vtag =
- (le16toh(current_desc->special) &
+ rxr->fmp->m_pkthdr.ether_vtag =
+ (le16toh(cur->special) &
E1000_RXD_SPC_VLAN_MASK);
- adapter->fmp->m_flags |= M_VLANTAG;
-#endif
+ rxr->fmp->m_flags |= M_VLANTAG;
}
+#ifdef EM_MULTIQUEUE
+ rxr->fmp->m_pkthdr.flowid = curcpu;
+ rxr->fmp->m_flags |= M_FLOWID;
+#endif
#ifndef __NO_STRICT_ALIGNMENT
skip:
#endif
- m = adapter->fmp;
- adapter->fmp = NULL;
- adapter->lmp = NULL;
+ sendmp = rxr->fmp;
+ rxr->fmp = NULL;
+ rxr->lmp = NULL;
}
} else {
ifp->if_ierrors++;
-discard:
/* Reuse loaded DMA map and just update mbuf chain */
- mp = adapter->rx_buffer_area[i].m_head;
+ mp = rxr->rx_buffers[i].m_head;
mp->m_len = mp->m_pkthdr.len = MCLBYTES;
mp->m_data = mp->m_ext.ext_buf;
mp->m_next = NULL;
if (adapter->max_frame_size <=
(MCLBYTES - ETHER_ALIGN))
m_adj(mp, ETHER_ALIGN);
- if (adapter->fmp != NULL) {
- m_freem(adapter->fmp);
- adapter->fmp = NULL;
- adapter->lmp = NULL;
+ if (rxr->fmp != NULL) {
+ m_freem(rxr->fmp);
+ rxr->fmp = NULL;
+ rxr->lmp = NULL;
}
- m = NULL;
+ sendmp = NULL;
}
/* Zero out the receive descriptors status. */
- current_desc->status = 0;
- bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ cur->status = 0;
+ ++rxdone; /* cumulative for POLL */
+ ++processed;
/* Advance our pointers to the next descriptor. */
if (++i == adapter->num_rx_desc)
i = 0;
- /* Call into the stack */
- if (m != NULL) {
- adapter->next_rx_desc_to_check = i;
- EM_RX_UNLOCK(adapter);
- (*ifp->if_input)(ifp, m);
- EM_RX_LOCK(adapter);
- rx_sent++;
- i = adapter->next_rx_desc_to_check;
+
+ /* Send to the stack */
+ if (sendmp != NULL)
+ (*ifp->if_input)(ifp, sendmp);
+
+ /* Only refresh mbufs every 8 descriptors */
+ if (processed == 8) {
+ em_refresh_mbufs(rxr, i);
+ processed = 0;
}
- current_desc = &adapter->rx_desc_base[i];
}
- adapter->next_rx_desc_to_check = i;
-
- /* Advance the E1000's Receive Queue #0 "Tail Pointer". */
- if (--i < 0)
- i = adapter->num_rx_desc - 1;
- E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
- EM_RX_UNLOCK(adapter);
- return (rx_sent);
+
+ /* Catch any remaining refresh work */
+ if (processed != 0) {
+ em_refresh_mbufs(rxr, i);
+ processed = 0;
+ }
+
+ rxr->next_to_check = i;
+
+#ifdef DEVICE_POLLING
+ return (rxdone);
+#else
+ return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
+#endif
}
#ifndef __NO_STRICT_ALIGNMENT
@@ -4560,13 +4235,14 @@ discard:
* not used at all on architectures with strict alignment.
*/
static int
-em_fixup_rx(struct adapter *adapter)
+em_fixup_rx(struct rx_ring *rxr)
{
+ struct adapter *adapter = rxr->adapter;
struct mbuf *m, *n;
int error;
error = 0;
- m = adapter->fmp;
+ m = rxr->fmp;
if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN)) {
bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len);
m->m_data += ETHER_HDR_LEN;
@@ -4579,11 +4255,11 @@ em_fixup_rx(struct adapter *adapter)
n->m_len = ETHER_HDR_LEN;
M_MOVE_PKTHDR(n, m);
n->m_next = m;
- adapter->fmp = n;
+ rxr->fmp = n;
} else {
adapter->dropped_pkts++;
- m_freem(adapter->fmp);
- adapter->fmp = NULL;
+ m_freem(rxr->fmp);
+ rxr->fmp = NULL;
error = ENOMEM;
}
}
@@ -4600,13 +4276,10 @@ em_fixup_rx(struct adapter *adapter)
*
*********************************************************************/
static void
-em_receive_checksum(struct adapter *adapter,
- struct e1000_rx_desc *rx_desc, struct mbuf *mp)
+em_receive_checksum(struct e1000_rx_desc *rx_desc, struct mbuf *mp)
{
- /* 82543 or newer only */
- if ((adapter->hw.mac.type < e1000_82543) ||
- /* Ignore Checksum bit is set */
- (rx_desc->status & E1000_RXD_STAT_IXSM)) {
+ /* Ignore Checksum bit is set */
+ if (rx_desc->status & E1000_RXD_STAT_IXSM) {
mp->m_pkthdr.csum_flags = 0;
return;
}
@@ -4633,7 +4306,6 @@ em_receive_checksum(struct adapter *adapter,
}
}
-#if __FreeBSD_version >= 700029
/*
* This routine is run via an vlan
* config EVENT
@@ -4720,7 +4392,6 @@ em_setup_vlan_hw_support(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
adapter->max_frame_size + VLAN_TAG_SIZE);
}
-#endif
static void
em_enable_intr(struct adapter *adapter)
@@ -4728,7 +4399,7 @@ em_enable_intr(struct adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 ims_mask = IMS_ENABLE_MASK;
- if (adapter->msix) {
+ if (hw->mac.type == e1000_82574) {
E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
ims_mask |= EM_MSIX_MASK;
}
@@ -4740,7 +4411,7 @@ em_disable_intr(struct adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- if (adapter->msix)
+ if (hw->mac.type == e1000_82574)
E1000_WRITE_REG(hw, EM_EIAC, 0);
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
}
@@ -4763,15 +4434,12 @@ em_init_manageability(struct adapter *adapter)
manc &= ~(E1000_MANC_ARP_EN);
/* enable receiving management packets to the host */
- if (adapter->hw.mac.type >= e1000_82571) {
- manc |= E1000_MANC_EN_MNG2HOST;
+ manc |= E1000_MANC_EN_MNG2HOST;
#define E1000_MNG2HOST_PORT_623 (1 << 5)
#define E1000_MNG2HOST_PORT_664 (1 << 6)
- manc2h |= E1000_MNG2HOST_PORT_623;
- manc2h |= E1000_MNG2HOST_PORT_664;
- E1000_WRITE_REG(&adapter->hw, E1000_MANC2H, manc2h);
- }
-
+ manc2h |= E1000_MNG2HOST_PORT_623;
+ manc2h |= E1000_MNG2HOST_PORT_664;
+ E1000_WRITE_REG(&adapter->hw, E1000_MANC2H, manc2h);
E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
}
}
@@ -4788,9 +4456,7 @@ em_release_manageability(struct adapter *adapter)
/* re-enable hardware interception of ARP */
manc |= E1000_MANC_ARP_EN;
-
- if (adapter->hw.mac.type >= e1000_82571)
- manc &= ~E1000_MANC_EN_MNG2HOST;
+ manc &= ~E1000_MANC_EN_MNG2HOST;
E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
}
@@ -4874,20 +4540,10 @@ em_get_wakeup(device_t dev)
apme_mask = EM_EEPROM_APME;
switch (adapter->hw.mac.type) {
- case e1000_82542:
- case e1000_82543:
- break;
- case e1000_82544:
- e1000_read_nvm(&adapter->hw,
- NVM_INIT_CONTROL2_REG, 1, &eeprom_data);
- apme_mask = EM_82544_APME;
- break;
case e1000_82573:
case e1000_82583:
adapter->has_amt = TRUE;
/* Falls thru */
- case e1000_82546:
- case e1000_82546_rev_3:
case e1000_82571:
case e1000_82572:
case e1000_80003es2lan:
@@ -4921,11 +4577,6 @@ em_get_wakeup(device_t dev)
*/
device_id = pci_get_device(dev);
switch (device_id) {
- case E1000_DEV_ID_82546GB_PCIE:
- adapter->wol = 0;
- break;
- case E1000_DEV_ID_82546EB_FIBER:
- case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82571EB_FIBER:
/* Wake events only supported on port A for dual fiber
* regardless of eeprom setting */
@@ -4933,7 +4584,6 @@ em_get_wakeup(device_t dev)
E1000_STATUS_FUNC_1)
adapter->wol = 0;
break;
- case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
case E1000_DEV_ID_82571EB_QUAD_COPPER:
case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
@@ -4952,7 +4602,7 @@ em_get_wakeup(device_t dev)
/*
* Enable PCI Wake On Lan capability
*/
-void
+static void
em_enable_wakeup(device_t dev)
{
struct adapter *adapter = device_get_softc(dev);
@@ -4969,7 +4619,6 @@ em_enable_wakeup(device_t dev)
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
- /* ICH workaround code */
if ((adapter->hw.mac.type == e1000_ich8lan) ||
(adapter->hw.mac.type == e1000_pchlan) ||
(adapter->hw.mac.type == e1000_ich9lan) ||
@@ -5105,60 +4754,20 @@ out:
return ret;
}
-
-/*********************************************************************
-* 82544 Coexistence issue workaround.
-* There are 2 issues.
-* 1. Transmit Hang issue.
-* To detect this issue, following equation can be used...
-* SIZE[3:0] + ADDR[2:0] = SUM[3:0].
-* If SUM[3:0] is in between 1 to 4, we will have this issue.
-*
-* 2. DAC issue.
-* To detect this issue, following equation can be used...
-* SIZE[3:0] + ADDR[2:0] = SUM[3:0].
-* If SUM[3:0] is in between 9 to c, we will have this issue.
-*
-*
-* WORKAROUND:
-* Make sure we do not have ending address
-* as 1,2,3,4(Hang) or 9,a,b,c (DAC)
-*
-*************************************************************************/
-static u32
-em_fill_descriptors (bus_addr_t address, u32 length,
- PDESC_ARRAY desc_array)
+static void
+em_led_func(void *arg, int onoff)
{
- u32 safe_terminator;
-
- /* Since issue is sensitive to length and address.*/
- /* Let us first check the address...*/
- if (length <= 4) {
- desc_array->descriptor[0].address = address;
- desc_array->descriptor[0].length = length;
- desc_array->elements = 1;
- return (desc_array->elements);
- }
- safe_terminator = (u32)((((u32)address & 0x7) +
- (length & 0xF)) & 0xF);
- /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */
- if (safe_terminator == 0 ||
- (safe_terminator > 4 &&
- safe_terminator < 9) ||
- (safe_terminator > 0xC &&
- safe_terminator <= 0xF)) {
- desc_array->descriptor[0].address = address;
- desc_array->descriptor[0].length = length;
- desc_array->elements = 1;
- return (desc_array->elements);
+ struct adapter *adapter = arg;
+
+ EM_CORE_LOCK(adapter);
+ if (onoff) {
+ e1000_setup_led(&adapter->hw);
+ e1000_led_on(&adapter->hw);
+ } else {
+ e1000_led_off(&adapter->hw);
+ e1000_cleanup_led(&adapter->hw);
}
-
- desc_array->descriptor[0].address = address;
- desc_array->descriptor[0].length = length - 4;
- desc_array->descriptor[1].address = address + (length - 4);
- desc_array->descriptor[1].length = 4;
- desc_array->elements = 2;
- return (desc_array->elements);
+ EM_CORE_UNLOCK(adapter);
}
/**********************************************************************
@@ -5270,6 +4879,8 @@ em_print_debug_info(struct adapter *adapter)
{
device_t dev = adapter->dev;
u8 *hw_addr = adapter->hw.hw_addr;
+ struct rx_ring *rxr = adapter->rx_rings;
+ struct tx_ring *txr = adapter->tx_rings;
device_printf(dev, "Adapter hardware address = %p \n", hw_addr);
device_printf(dev, "CTRL = 0x%x RCTL = 0x%x \n",
@@ -5287,29 +4898,33 @@ em_print_debug_info(struct adapter *adapter)
device_printf(dev, "rx_int_delay = %d, rx_abs_int_delay = %d\n",
E1000_READ_REG(&adapter->hw, E1000_RDTR),
E1000_READ_REG(&adapter->hw, E1000_RADV));
- device_printf(dev, "fifo workaround = %lld, fifo_reset_count = %lld\n",
- (long long)adapter->tx_fifo_wrk_cnt,
- (long long)adapter->tx_fifo_reset_cnt);
- device_printf(dev, "hw tdh = %d, hw tdt = %d\n",
- E1000_READ_REG(&adapter->hw, E1000_TDH(0)),
- E1000_READ_REG(&adapter->hw, E1000_TDT(0)));
- device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
- E1000_READ_REG(&adapter->hw, E1000_RDH(0)),
- E1000_READ_REG(&adapter->hw, E1000_RDT(0)));
- device_printf(dev, "Num Tx descriptors avail = %d\n",
- adapter->num_tx_desc_avail);
- device_printf(dev, "Tx Descriptors not avail1 = %ld\n",
- adapter->no_tx_desc_avail1);
- device_printf(dev, "Tx Descriptors not avail2 = %ld\n",
- adapter->no_tx_desc_avail2);
+
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ device_printf(dev, "Queue(%d) tdh = %d, tdt = %d\n", i,
+ E1000_READ_REG(&adapter->hw, E1000_TDH(i)),
+ E1000_READ_REG(&adapter->hw, E1000_TDT(i)));
+ device_printf(dev, "TX(%d) no descriptors avail event = %ld\n",
+ txr->me, txr->no_desc_avail);
+ device_printf(dev, "TX(%d) MSIX IRQ Handled = %ld\n",
+ txr->me, txr->tx_irq);
+ device_printf(dev, "Num Tx descriptors avail = %d\n",
+ txr->tx_avail);
+ device_printf(dev, "Tx Descriptors not avail1 = %ld\n",
+ txr->no_desc_avail);
+ }
+ for (int i = 0; i < adapter->num_queues; i++, rxr++) {
+ device_printf(dev, "RX(%d) MSIX IRQ Handled = %ld\n",
+ rxr->me, rxr->rx_irq);
+ device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_RDH(i)),
+ E1000_READ_REG(&adapter->hw, E1000_RDT(i)));
+ }
device_printf(dev, "Std mbuf failed = %ld\n",
adapter->mbuf_alloc_failed);
device_printf(dev, "Std mbuf cluster failed = %ld\n",
adapter->mbuf_cluster_failed);
device_printf(dev, "Driver dropped packets = %ld\n",
adapter->dropped_pkts);
- device_printf(dev, "Driver tx dma failure in encap = %ld\n",
- adapter->no_tx_dma_setup);
}
static void
@@ -5342,12 +4957,8 @@ em_print_hw_stats(struct adapter *adapter)
(long long)adapter->stats.algnerrc);
device_printf(dev, "Collision/Carrier extension errors = %lld\n",
(long long)adapter->stats.cexterr);
- device_printf(dev, "RX overruns = %ld\n", adapter->rx_overruns);
device_printf(dev, "watchdog timeouts = %ld\n",
adapter->watchdog_events);
- device_printf(dev, "RX MSIX IRQ = %ld TX MSIX IRQ = %ld"
- " LINK MSIX IRQ = %ld\n", adapter->rx_irq,
- adapter->tx_irq , adapter->link_irq);
device_printf(dev, "XON Rcvd = %lld\n",
(long long)adapter->stats.xonrxc);
device_printf(dev, "XON Xmtd = %lld\n",
@@ -5451,9 +5062,7 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
struct em_int_delay_info *info;
struct adapter *adapter;
u32 regval;
- int error;
- int usecs;
- int ticks;
+ int error, usecs, ticks;
info = (struct em_int_delay_info *)arg1;
usecs = info->value;
@@ -5502,7 +5111,6 @@ em_add_int_delay_sysctl(struct adapter *adapter, const char *name,
info, 0, em_sysctl_int_delay, "I", description);
}
-#ifndef EM_LEGACY_IRQ
static void
em_add_rx_process_limit(struct adapter *adapter, const char *name,
const char *description, int *limit, int value)
@@ -5512,6 +5120,5 @@ em_add_rx_process_limit(struct adapter *adapter, const char *name,
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
}
-#endif
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index fe5a99b..225a8d0 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -52,7 +52,6 @@
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define EM_MIN_TXD 80
-#define EM_MAX_TXD_82543 256
#define EM_MAX_TXD 4096
#define EM_DEFAULT_TXD 1024
@@ -70,7 +69,6 @@
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define EM_MIN_RXD 80
-#define EM_MAX_RXD_82543 256
#define EM_MAX_RXD 4096
#define EM_DEFAULT_RXD 1024
@@ -144,7 +142,6 @@
* transmit descriptors.
*/
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
-#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
/*
* This parameter controls whether or not autonegotation is enabled.
@@ -182,7 +179,7 @@
#define EM_DEFAULT_PBA 0x00000030
#define EM_SMARTSPEED_DOWNSHIFT 3
#define EM_SMARTSPEED_MAX 15
-#define EM_MAX_INTR 10
+#define EM_MAX_LOOP 10
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define PCI_ANY_ID (~0U)
@@ -191,11 +188,6 @@
#define EM_EEPROM_APME 0x400;
#define EM_82544_APME 0x0004;
-/* Code compatilbility between 6 and 7 */
-#ifndef ETHER_BPF_MTAP
-#define ETHER_BPF_MTAP BPF_MTAP
-#endif
-
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
@@ -209,7 +201,6 @@
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
#define EM_BAR_TYPE_MASK 0x00000001
#define EM_BAR_TYPE_MMEM 0x00000000
-#define EM_BAR_TYPE_IO 0x00000001
#define EM_BAR_TYPE_FLASH 0x0014
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
#define EM_BAR_MEM_TYPE_MASK 0x00000006
@@ -232,11 +223,12 @@
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
-#define EM_MAX_SCATTER 64
+#define EM_MAX_SCATTER 32
#define EM_VFTA_SIZE 128
#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */
+#define EM_MSIX_LINK 0x01000000 /* For 82574 use */
#define ETH_ZLEN 60
#define ETH_ADDR_LEN 6
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
@@ -249,18 +241,6 @@
*/
#define EM_EIAC 0x000DC
-/* Used in for 82547 10Mb Half workaround */
-#define EM_PBA_BYTES_SHIFT 0xA
-#define EM_TX_HEAD_ADDR_SHIFT 7
-#define EM_PBA_TX_MASK 0xFFFF0000
-#define EM_FIFO_HDR 0x10
-#define EM_82547_PKT_THRESH 0x3e0
-
-/* Precision Time Sync (IEEE 1588) defines */
-#define ETHERTYPE_IEEE1588 0x88F7
-#define PICOSECS_PER_TICK 20833
-#define TSYNC_PORT 319 /* UDP port for the protocol */
-
/*
* Bus dma allocation structure used by
* e1000_dma_malloc and e1000_dma_free.
@@ -282,56 +262,129 @@ struct em_int_delay_info {
int value; /* Current value in usecs */
};
+/*
+ * The transmit ring, one per tx queue
+ */
+struct tx_ring {
+ struct adapter *adapter;
+ struct mtx tx_mtx;
+ char mtx_name[16];
+ u32 me;
+ u32 msix;
+ u32 ims;
+ bool watchdog_check;
+ int watchdog_time;
+ struct em_dma_alloc txdma;
+ struct e1000_tx_desc *tx_base;
+ struct task tx_task;
+ struct taskqueue *tq;
+ u32 next_avail_desc;
+ u32 next_to_clean;
+ struct em_buffer *tx_buffers;
+ volatile u16 tx_avail;
+ u32 tx_tso; /* last tx was tso */
+ u16 last_hw_offload;
+#if __FreeBSD_version >= 800000
+ struct buf_ring *br;
+#endif
+ /* Interrupt resources */
+ bus_dma_tag_t txtag;
+ void *tag;
+ struct resource *res;
+ unsigned long tx_irq;
+ unsigned long no_desc_avail;
+};
+
+/*
+ * The Receive ring, one per rx queue
+ */
+struct rx_ring {
+ struct adapter *adapter;
+ u32 me;
+ u32 msix;
+ u32 ims;
+ struct mtx rx_mtx;
+ char mtx_name[16];
+ u32 payload;
+ struct task rx_task;
+ struct taskqueue *tq;
+ struct e1000_rx_desc *rx_base;
+ struct em_dma_alloc rxdma;
+ u32 next_to_refresh;
+ u32 next_to_check;
+ struct em_buffer *rx_buffers;
+ struct mbuf *fmp;
+ struct mbuf *lmp;
+
+ /* Interrupt resources */
+ void *tag;
+ struct resource *res;
+ bus_dma_tag_t rxtag;
+ bus_dmamap_t rx_sparemap;
+
+ /* Soft stats */
+ unsigned long rx_irq;
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+};
+
+
/* Our adapter structure */
struct adapter {
struct ifnet *ifp;
-#if __FreeBSD_version >= 800000
- struct buf_ring *br;
-#endif
struct e1000_hw hw;
/* FreeBSD operating-system-specific structures. */
struct e1000_osdep osdep;
struct device *dev;
+ struct cdev *led_dev;
struct resource *memory;
struct resource *flash;
- struct resource *msix;
-
- struct resource *ioport;
- int io_rid;
+ struct resource *msix_mem;
- /* 82574 may use 3 int vectors */
- struct resource *res[3];
- void *tag[3];
- int rid[3];
+ struct resource *res;
+ void *tag;
+ u32 linkvec;
+ u32 ivars;
struct ifmedia media;
struct callout timer;
- struct callout tx_fifo_timer;
- bool watchdog_check;
- int watchdog_time;
- int msi;
+ int msix;
int if_flags;
int max_frame_size;
int min_frame_size;
struct mtx core_mtx;
- struct mtx tx_mtx;
- struct mtx rx_mtx;
int em_insert_vlan_header;
+ u32 ims;
+ bool in_detach;
/* Task for FAST handling */
struct task link_task;
- struct task rxtx_task;
- struct task rx_task;
- struct task tx_task;
+ struct task que_task;
struct taskqueue *tq; /* private task queue */
-#if __FreeBSD_version >= 700029
eventhandler_tag vlan_attach;
eventhandler_tag vlan_detach;
- u32 num_vlans;
-#endif
+
+ u16 num_vlans;
+ u16 num_queues;
+
+ /*
+ * Transmit rings:
+ * Allocated at run time, an array of rings.
+ */
+ struct tx_ring *tx_rings;
+ int num_tx_desc;
+ u32 txd_cmd;
+
+ /*
+ * Receive rings:
+ * Allocated at run time, an array of rings.
+ */
+ struct rx_ring *rx_rings;
+ int num_rx_desc;
+ u32 rx_process_limit;
/* Management and WOL features */
u32 wol;
@@ -348,96 +401,26 @@ struct adapter {
struct em_int_delay_info rx_int_delay;
struct em_int_delay_info rx_abs_int_delay;
- /*
- * Transmit definitions
- *
- * We have an array of num_tx_desc descriptors (handled
- * by the controller) paired with an array of tx_buffers
- * (at tx_buffer_area).
- * The index of the next available descriptor is next_avail_tx_desc.
- * The number of remaining tx_desc is num_tx_desc_avail.
- */
- struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
- struct e1000_tx_desc *tx_desc_base;
- uint32_t next_avail_tx_desc;
- uint32_t next_tx_to_clean;
- volatile uint16_t num_tx_desc_avail;
- uint16_t num_tx_desc;
- uint16_t last_hw_offload;
- uint32_t txd_cmd;
- struct em_buffer *tx_buffer_area;
- bus_dma_tag_t txtag; /* dma tag for tx */
- uint32_t tx_tso; /* last tx was tso */
-
- /*
- * Receive definitions
- *
- * we have an array of num_rx_desc rx_desc (handled by the
- * controller), and paired with an array of rx_buffers
- * (at rx_buffer_area).
- * The next pair to check on receive is at offset next_rx_desc_to_check
- */
- struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
- struct e1000_rx_desc *rx_desc_base;
- uint32_t next_rx_desc_to_check;
- uint32_t rx_buffer_len;
- uint16_t num_rx_desc;
- int rx_process_limit;
- struct em_buffer *rx_buffer_area;
- bus_dma_tag_t rxtag;
- bus_dmamap_t rx_sparemap;
-
- /*
- * First/last mbuf pointers, for
- * collecting multisegment RX packets.
- */
- struct mbuf *fmp;
- struct mbuf *lmp;
-
/* Misc stats maintained by the driver */
unsigned long dropped_pkts;
unsigned long mbuf_alloc_failed;
unsigned long mbuf_cluster_failed;
- unsigned long no_tx_desc_avail1;
- unsigned long no_tx_desc_avail2;
unsigned long no_tx_map_avail;
unsigned long no_tx_dma_setup;
- unsigned long watchdog_events;
unsigned long rx_overruns;
- unsigned long rx_irq;
- unsigned long tx_irq;
+ unsigned long watchdog_events;
unsigned long link_irq;
- /* 82547 workaround */
- uint32_t tx_fifo_size;
- uint32_t tx_fifo_head;
- uint32_t tx_fifo_head_addr;
- uint64_t tx_fifo_reset_cnt;
- uint64_t tx_fifo_wrk_cnt;
- uint32_t tx_head_addr;
-
- /* For 82544 PCIX Workaround */
- boolean_t pcix_82544;
- boolean_t in_detach;
-
-#ifdef EM_IEEE1588
- /* IEEE 1588 precision time support */
- struct cyclecounter cycles;
- struct nettimer clock;
- struct nettime_compare compare;
- struct hwtstamp_ctrl hwtstamp;
-#endif
-
struct e1000_hw_stats stats;
};
-/* ******************************************************************************
+/********************************************************************************
* vendor_info_array
*
* This array contains the list of Subvendor/Subdevice IDs on which the driver
* should load.
*
- * ******************************************************************************/
+ ********************************************************************************/
typedef struct _em_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
@@ -452,19 +435,6 @@ struct em_buffer {
bus_dmamap_t map; /* bus_dma map for packet */
};
-/* For 82544 PCIX Workaround */
-typedef struct _ADDRESS_LENGTH_PAIR
-{
- uint64_t address;
- uint32_t length;
-} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
-
-typedef struct _DESCRIPTOR_PAIR
-{
- ADDRESS_LENGTH_PAIR descriptor[4];
- uint32_t elements;
-} DESC_ARRAY, *PDESC_ARRAY;
-
#define EM_CORE_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
#define EM_TX_LOCK_INIT(_sc, _name) \
@@ -483,5 +453,6 @@ typedef struct _DESCRIPTOR_PAIR
#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
+#define EM_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rx_mtx, MA_OWNED)
#endif /* _EM_H_DEFINED_ */
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 2eb113a..e901bc2 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -63,10 +63,6 @@
#include <machine/bus.h>
#include <machine/resource.h>
-#ifdef IGB_IEEE1588
-#include <sys/ieee1588.h>
-#endif
-
#include <net/bpf.h>
#include <net/ethernet.h>
#include <net/if.h>
@@ -87,6 +83,7 @@
#include <netinet/udp.h>
#include <machine/in_cksum.h>
+#include <dev/led/led.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -102,7 +99,7 @@ int igb_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char igb_driver_version[] = "version - 1.9.1";
+char igb_driver_version[] = "version - 1.9.5";
/*********************************************************************
@@ -204,12 +201,11 @@ static void igb_disable_intr(struct adapter *);
static void igb_update_stats_counters(struct adapter *);
static bool igb_txeof(struct tx_ring *);
-static __inline void igb_rx_discard(struct rx_ring *,
- union e1000_adv_rx_desc *, int);
+static __inline void igb_rx_discard(struct rx_ring *, int);
static __inline void igb_rx_input(struct rx_ring *,
struct ifnet *, struct mbuf *, u32);
-static bool igb_rxeof(struct rx_ring *, int);
+static bool igb_rxeof(struct igb_queue *, int);
static void igb_rx_checksum(u32, struct mbuf *, u32);
static int igb_tx_ctx_setup(struct tx_ring *, struct mbuf *);
static bool igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
@@ -218,7 +214,7 @@ static void igb_disable_promisc(struct adapter *);
static void igb_set_multi(struct adapter *);
static void igb_print_hw_stats(struct adapter *);
static void igb_update_link_status(struct adapter *);
-static int igb_get_buf(struct rx_ring *, int, u8);
+static void igb_refresh_mbufs(struct rx_ring *, int);
static void igb_register_vlan(void *, struct ifnet *, u16);
static void igb_unregister_vlan(void *, struct ifnet *, u16);
@@ -239,6 +235,7 @@ static void igb_release_manageability(struct adapter *);
static void igb_get_hw_control(struct adapter *);
static void igb_release_hw_control(struct adapter *);
static void igb_enable_wakeup(device_t);
+static void igb_led_func(void *, int);
static int igb_irq_fast(void *);
static void igb_add_rx_process_limit(struct adapter *, const char *,
@@ -590,6 +587,9 @@ igb_attach(device_t dev)
/* Tell the stack that the interface is not active */
adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ adapter->led_dev = led_create(igb_led_func, adapter,
+ device_get_nameunit(dev));
+
INIT_DEBUGOUT("igb_attach: end");
return (0);
@@ -629,6 +629,9 @@ igb_detach(device_t dev)
return (EBUSY);
}
+ if (adapter->led_dev != NULL)
+ led_destroy(adapter->led_dev);
+
#ifdef DEVICE_POLLING
if (ifp->if_capenable & IFCAP_POLLING)
ether_poll_deregister(ifp);
@@ -755,8 +758,15 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp)
if (!adapter->link_active)
return;
- while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ /* Call cleanup if number of TX descriptors low */
+ if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD)
+ igb_txeof(txr);
+ while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ if (txr->tx_avail <= IGB_TX_OP_THRESHOLD) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL)
break;
@@ -776,6 +786,7 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp)
ETHER_BPF_MTAP(ifp, m_head);
/* Set watchdog on */
+ txr->watchdog_time = ticks;
txr->watchdog_check = TRUE;
}
}
@@ -814,6 +825,7 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
/* Which queue to use */
if ((m->m_flags & M_FLOWID) != 0)
i = m->m_pkthdr.flowid % adapter->num_queues;
+
txr = &adapter->tx_rings[i];
if (IGB_TX_TRYLOCK(txr)) {
@@ -841,6 +853,10 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
return (err);
}
+ /* Call cleanup if number of TX descriptors low */
+ if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD)
+ igb_txeof(txr);
+
enq = 0;
if (m == NULL) {
next = drbr_dequeue(ifp, txr->br);
@@ -850,6 +866,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
next = drbr_dequeue(ifp, txr->br);
} else
next = m;
+
/* Process the queue */
while (next != NULL) {
if ((err = igb_xmit(txr, &next)) != 0) {
@@ -871,6 +888,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
if (enq > 0) {
/* Set the watchdog */
txr->watchdog_check = TRUE;
+ txr->watchdog_time = ticks;
}
return (err);
}
@@ -1049,6 +1067,10 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
reinit = 1;
}
+ if (mask & IFCAP_VLAN_HWFILTER) {
+ ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
+ reinit = 1;
+ }
if (mask & IFCAP_LRO) {
ifp->if_capenable ^= IFCAP_LRO;
reinit = 1;
@@ -1104,6 +1126,19 @@ igb_init_locked(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
+ /* Use real VLAN Filter support? */
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ /* Use real VLAN Filter support */
+ igb_setup_vlan_hw_support(adapter);
+ else {
+ u32 ctrl;
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= E1000_CTRL_VME;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+ }
+ }
+
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
if (ifp->if_capenable & IFCAP_TXCSUM) {
@@ -1192,15 +1227,15 @@ igb_init(void *arg)
static void
igb_handle_rxtx(void *context, int pending)
{
- struct adapter *adapter = context;
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
- struct ifnet *ifp;
+ struct igb_queue *que = context;
+ struct adapter *adapter = que->adapter;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct ifnet *ifp;
ifp = adapter->ifp;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if (igb_rxeof(rxr, adapter->rx_process_limit))
+ if (igb_rxeof(que, adapter->rx_process_limit))
taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
IGB_TX_LOCK(txr);
igb_txeof(txr);
@@ -1224,21 +1259,14 @@ igb_handle_que(void *context, int pending)
struct igb_queue *que = context;
struct adapter *adapter = que->adapter;
struct tx_ring *txr = que->txr;
- struct rx_ring *rxr = que->rxr;
struct ifnet *ifp = adapter->ifp;
- u32 loop = IGB_MAX_LOOP;
bool more;
- /* RX first */
- do {
- more = igb_rxeof(rxr, -1);
- } while (loop-- && more);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ more = igb_rxeof(que, -1);
- if (IGB_TX_TRYLOCK(txr)) {
- loop = IGB_MAX_LOOP;
- do {
- more = igb_txeof(txr);
- } while (loop-- && more);
+ IGB_TX_LOCK(txr);
+ igb_txeof(txr);
#if __FreeBSD_version >= 800000
igb_mq_start_locked(ifp, txr, NULL);
#else
@@ -1246,6 +1274,10 @@ igb_handle_que(void *context, int pending)
igb_start_locked(txr, ifp);
#endif
IGB_TX_UNLOCK(txr);
+ if (more) {
+ taskqueue_enqueue(que->tq, &que->que_task);
+ return;
+ }
}
/* Reenable this interrupt */
@@ -1311,7 +1343,8 @@ igb_irq_fast(void *arg)
#ifdef DEVICE_POLLING
/*********************************************************************
*
- * Legacy polling routine
+ * Legacy polling routine : if using this code you MUST be sure that
+ * multiqueue is not defined, ie, set igb_num_queues to 1.
*
*********************************************************************/
#if __FreeBSD_version >= 800000
@@ -1323,12 +1356,12 @@ static void
#endif
igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
- struct adapter *adapter = ifp->if_softc;
- struct rx_ring *rxr = adapter->rx_rings;
- struct tx_ring *txr = adapter->tx_rings;
- u32 reg_icr, rx_done = 0;
- u32 loop = IGB_MAX_LOOP;
- bool more;
+ struct adapter *adapter = ifp->if_softc;
+ struct igb_queue *que = adapter->queues;
+ struct tx_ring *txr = adapter->tx_rings;
+ u32 reg_icr, rx_done = 0;
+ u32 loop = IGB_MAX_LOOP;
+ bool more;
IGB_CORE_LOCK(adapter);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
@@ -1348,7 +1381,7 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
IGB_CORE_UNLOCK(adapter);
/* TODO: rx_count */
- rx_done = igb_rxeof(rxr, count) ? 1 : 0;
+ rx_done = igb_rxeof(que, count) ? 1 : 0;
IGB_TX_LOCK(txr);
do {
@@ -1388,7 +1421,7 @@ igb_msix_que(void *arg)
more_tx = igb_txeof(txr);
IGB_TX_UNLOCK(txr);
- more_rx = igb_rxeof(rxr, adapter->rx_process_limit);
+ more_rx = igb_rxeof(que, adapter->rx_process_limit);
if (igb_enable_aim == FALSE)
goto no_calc;
@@ -1430,7 +1463,7 @@ igb_msix_que(void *arg)
if (adapter->hw.mac.type == e1000_82575)
newitr |= newitr << 16;
else
- newitr |= 0x8000000;
+ newitr |= E1000_EITR_CNT_IGNR;
/* save for next interrupt */
que->eitr_setting = newitr;
@@ -1955,6 +1988,7 @@ igb_update_link_status(struct adapter *adapter)
"Full Duplex" : "Half Duplex"));
adapter->link_active = 1;
ifp->if_baudrate = adapter->link_speed * 1000000;
+ /* This can sleep */
if_link_state_change(ifp, LINK_STATE_UP);
} else if (!link_check && (adapter->link_active == 1)) {
ifp->if_baudrate = adapter->link_speed = 0;
@@ -1962,6 +1996,7 @@ igb_update_link_status(struct adapter *adapter)
if (bootverbose)
device_printf(dev, "Link is Down\n");
adapter->link_active = 0;
+ /* This can sleep */
if_link_state_change(ifp, LINK_STATE_DOWN);
/* Turn off watchdogs */
for (int i = 0; i < adapter->num_queues; i++, txr++)
@@ -2003,6 +2038,9 @@ igb_stop(void *arg)
e1000_reset_hw(&adapter->hw);
E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
+
+ e1000_led_off(&adapter->hw);
+ e1000_cleanup_led(&adapter->hw);
}
@@ -2080,8 +2118,9 @@ igb_allocate_pci_resources(struct adapter *adapter)
static int
igb_allocate_legacy(struct adapter *adapter)
{
- device_t dev = adapter->dev;
- int error, rid = 0;
+ device_t dev = adapter->dev;
+ struct igb_queue *que = adapter->queues;
+ int error, rid = 0;
/* Turn off all interrupts */
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
@@ -2103,7 +2142,7 @@ igb_allocate_legacy(struct adapter *adapter)
* Try allocating a fast interrupt and the associated deferred
* processing contexts.
*/
- TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, adapter);
+ TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, que);
/* Make tasklet for deferred link handling */
TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT,
@@ -2328,7 +2367,7 @@ igb_configure_queues(struct adapter *adapter)
if (hw->mac.type == e1000_82575)
newitr |= newitr << 16;
else
- newitr |= 0x8000000;
+ newitr |= E1000_EITR_CNT_IGNR;
for (int i = 0; i < adapter->num_queues; i++) {
que = &adapter->queues[i];
@@ -2433,22 +2472,19 @@ igb_setup_msix(struct adapter *adapter)
/* Figure out a reasonable auto config value */
queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
- /* Can have max of 4 queues on 82575 */
- if (adapter->hw.mac.type == e1000_82575) {
- if (queues > 4)
- queues = 4;
- if (igb_num_queues > 4)
- igb_num_queues = 4;
- }
+ /* Manual override */
+ if (igb_num_queues != 0)
+ queues = igb_num_queues;
- if (igb_num_queues == 0)
- igb_num_queues = queues;
+ /* Can have max of 4 queues on 82575 */
+ if ((adapter->hw.mac.type == e1000_82575) && (queues > 4))
+ queues = 4;
/*
** One vector (RX/TX pair) per queue
** plus an additional for Link interrupt
*/
- want = igb_num_queues + 1;
+ want = queues + 1;
if (msgs >= want)
msgs = want;
else {
@@ -2461,7 +2497,7 @@ igb_setup_msix(struct adapter *adapter)
if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) {
device_printf(adapter->dev,
"Using MSIX interrupts with %d vectors\n", msgs);
- adapter->num_queues = igb_num_queues;
+ adapter->num_queues = queues;
return (msgs);
}
msi:
@@ -2660,13 +2696,24 @@ igb_setup_interface(device_t dev, struct adapter *adapter)
#endif
/*
- * Tell the upper layer(s) we support long frames.
+ * Tell the upper layer(s) we
+ * support full VLAN capability.
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
/*
+ ** Dont turn this on by default, if vlans are
+ ** created on another pseudo device (eg. lagg)
+ ** then vlan events are not passed thru, breaking
+ ** operation, but with HW FILTER off it works. If
+ ** using vlans directly on the em driver you can
+ ** enable this and get full hardware tag filtering.
+ */
+ ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
+
+ /*
* Specify the media types supported by this adapter and register
* callbacks to update media and link information
*/
@@ -2922,9 +2969,7 @@ err_tx_desc:
igb_dma_free(adapter, &txr->txdma);
free(adapter->rx_rings, M_DEVBUF);
rx_fail:
-#if __FreeBSD_version >= 800000
buf_ring_free(txr->br, M_DEVBUF);
-#endif
free(adapter->tx_rings, M_DEVBUF);
tx_fail:
free(adapter->queues, M_DEVBUF);
@@ -3502,111 +3547,88 @@ igb_txeof(struct tx_ring *txr)
/*********************************************************************
*
- * Setup descriptor buffer(s) from system mbuf buffer pools.
- * i - designates the ring index
- * clean - tells the function whether to update
- * the header, the packet buffer, or both.
+ * Refresh mbuf buffers for RX descriptor rings
+ * - now keeps its own state so discards due to resource
+ * exhaustion are unnecessary, if an mbuf cannot be obtained
+ * it just returns, keeping its placeholder, thus it can simply
+ * be recalled to try again.
*
**********************************************************************/
-static int
-igb_get_buf(struct rx_ring *rxr, int i, u8 clean)
+static void
+igb_refresh_mbufs(struct rx_ring *rxr, int limit)
{
struct adapter *adapter = rxr->adapter;
- struct igb_rx_buf *rxbuf;
- struct mbuf *mh, *mp;
bus_dma_segment_t hseg[1];
bus_dma_segment_t pseg[1];
- bus_dmamap_t map;
- int nsegs, error;
-
+ struct igb_rx_buf *rxbuf;
+ struct mbuf *mh, *mp;
+ int i, nsegs, error, cleaned;
- rxbuf = &rxr->rx_buffers[i];
- mh = mp = NULL;
- if ((clean & IGB_CLEAN_HEADER) != 0) {
- mh = m_gethdr(M_DONTWAIT, MT_DATA);
- if (mh == NULL) {
- adapter->mbuf_header_failed++;
- return (ENOBUFS);
- }
- mh->m_pkthdr.len = mh->m_len = MHLEN;
- /*
- * Because IGB_HDR_BUF size is less than MHLEN
- * and we configure controller to split headers
- * we can align mbuf on ETHER_ALIGN boundary.
- */
- m_adj(mh, ETHER_ALIGN);
- error = bus_dmamap_load_mbuf_sg(rxr->rx_htag,
- rxr->rx_hspare_map, mh, hseg, &nsegs, 0);
- if (error != 0) {
- m_freem(mh);
- return (error);
- }
- mh->m_flags &= ~M_PKTHDR;
- }
- if ((clean & IGB_CLEAN_PAYLOAD) != 0) {
- mp = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
- adapter->rx_mbuf_sz);
- if (mp == NULL) {
- if (mh != NULL) {
- adapter->mbuf_packet_failed++;
- bus_dmamap_unload(rxr->rx_htag,
- rxbuf->head_map);
- mh->m_flags |= M_PKTHDR;
- m_freem(mh);
+ i = rxr->next_to_refresh;
+ cleaned = -1; /* Signify no completions */
+ while (i != limit) {
+ rxbuf = &rxr->rx_buffers[i];
+ if (rxbuf->m_head == NULL) {
+ mh = m_gethdr(M_DONTWAIT, MT_DATA);
+ if (mh == NULL)
+ goto update;
+ mh->m_pkthdr.len = mh->m_len = MHLEN;
+ mh->m_len = MHLEN;
+ mh->m_flags |= M_PKTHDR;
+ m_adj(mh, ETHER_ALIGN);
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->htag,
+ rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("GET BUF: dmamap load"
+ " failure - %d\n", error);
+ m_free(mh);
+ goto update;
}
- return (ENOBUFS);
+ rxbuf->m_head = mh;
+ bus_dmamap_sync(rxr->htag, rxbuf->hmap,
+ BUS_DMASYNC_PREREAD);
+ rxr->rx_base[i].read.hdr_addr =
+ htole64(hseg[0].ds_addr);
}
- mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
- error = bus_dmamap_load_mbuf_sg(rxr->rx_ptag,
- rxr->rx_pspare_map, mp, pseg, &nsegs, 0);
- if (error != 0) {
- if (mh != NULL) {
- bus_dmamap_unload(rxr->rx_htag,
- rxbuf->head_map);
- mh->m_flags |= M_PKTHDR;
- m_freem(mh);
+
+ if (rxbuf->m_pack == NULL) {
+ mp = m_getjcl(M_DONTWAIT, MT_DATA,
+ M_PKTHDR, adapter->rx_mbuf_sz);
+ if (mp == NULL)
+ goto update;
+ mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->ptag,
+ rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("GET BUF: dmamap load"
+ " failure - %d\n", error);
+ m_free(mp);
+ goto update;
}
- m_freem(mp);
- return (error);
+ rxbuf->m_pack = mp;
+ bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
+ BUS_DMASYNC_PREREAD);
+ rxr->rx_base[i].read.pkt_addr =
+ htole64(pseg[0].ds_addr);
}
- mp->m_flags &= ~M_PKTHDR;
- }
-
- /* Loading new DMA maps complete, unload maps for received buffers. */
- if ((clean & IGB_CLEAN_HEADER) != 0 && rxbuf->m_head != NULL) {
- bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
- BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rx_htag, rxbuf->head_map);
- }
- if ((clean & IGB_CLEAN_PAYLOAD) != 0 && rxbuf->m_pack != NULL) {
- bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
- BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rx_ptag, rxbuf->pack_map);
- }
- /* Reflect loaded dmamaps. */
- if ((clean & IGB_CLEAN_HEADER) != 0) {
- map = rxbuf->head_map;
- rxbuf->head_map = rxr->rx_hspare_map;
- rxr->rx_hspare_map = map;
- rxbuf->m_head = mh;
- bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
- BUS_DMASYNC_PREREAD);
- rxr->rx_base[i].read.hdr_addr = htole64(hseg[0].ds_addr);
- }
- if ((clean & IGB_CLEAN_PAYLOAD) != 0) {
- map = rxbuf->pack_map;
- rxbuf->pack_map = rxr->rx_pspare_map;
- rxr->rx_pspare_map = map;
- rxbuf->m_pack = mp;
- bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
- BUS_DMASYNC_PREREAD);
- rxr->rx_base[i].read.pkt_addr = htole64(pseg[0].ds_addr);
+ cleaned = i;
+ /* Calculate next index */
+ if (++i == adapter->num_rx_desc)
+ i = 0;
+ /* This is the work marker for refresh */
+ rxr->next_to_refresh = i;
}
-
- return (0);
+update:
+ if (cleaned != -1) /* If we refreshed some, bump tail */
+ E1000_WRITE_REG(&adapter->hw,
+ E1000_RDT(rxr->me), cleaned);
+ return;
}
+
/*********************************************************************
*
* Allocate memory for rx_buffer structures. Since we use one
@@ -3643,7 +3665,7 @@ igb_allocate_receive_buffers(struct rx_ring *rxr)
0, /* flags */
NULL, /* lockfunc */
NULL, /* lockfuncarg */
- &rxr->rx_htag))) {
+ &rxr->htag))) {
device_printf(dev, "Unable to create RX DMA tag\n");
goto fail;
}
@@ -3659,40 +3681,22 @@ igb_allocate_receive_buffers(struct rx_ring *rxr)
0, /* flags */
NULL, /* lockfunc */
NULL, /* lockfuncarg */
- &rxr->rx_ptag))) {
+ &rxr->ptag))) {
device_printf(dev, "Unable to create RX payload DMA tag\n");
goto fail;
}
- /* Create the spare maps (used by getbuf) */
- error = bus_dmamap_create(rxr->rx_htag, BUS_DMA_NOWAIT,
- &rxr->rx_hspare_map);
- if (error) {
- device_printf(dev,
- "%s: bus_dmamap_create header spare failed: %d\n",
- __func__, error);
- goto fail;
- }
- error = bus_dmamap_create(rxr->rx_ptag, BUS_DMA_NOWAIT,
- &rxr->rx_pspare_map);
- if (error) {
- device_printf(dev,
- "%s: bus_dmamap_create packet spare failed: %d\n",
- __func__, error);
- goto fail;
- }
-
for (i = 0; i < adapter->num_rx_desc; i++) {
rxbuf = &rxr->rx_buffers[i];
- error = bus_dmamap_create(rxr->rx_htag,
- BUS_DMA_NOWAIT, &rxbuf->head_map);
+ error = bus_dmamap_create(rxr->htag,
+ BUS_DMA_NOWAIT, &rxbuf->hmap);
if (error) {
device_printf(dev,
"Unable to create RX head DMA maps\n");
goto fail;
}
- error = bus_dmamap_create(rxr->rx_ptag,
- BUS_DMA_NOWAIT, &rxbuf->pack_map);
+ error = bus_dmamap_create(rxr->ptag,
+ BUS_DMA_NOWAIT, &rxbuf->pmap);
if (error) {
device_printf(dev,
"Unable to create RX packet DMA maps\n");
@@ -3720,16 +3724,16 @@ igb_free_receive_ring(struct rx_ring *rxr)
for (i = 0; i < adapter->num_rx_desc; i++) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->m_head != NULL) {
- bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
+ bus_dmamap_sync(rxr->htag, rxbuf->hmap,
BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rx_htag, rxbuf->head_map);
+ bus_dmamap_unload(rxr->htag, rxbuf->hmap);
rxbuf->m_head->m_flags |= M_PKTHDR;
m_freem(rxbuf->m_head);
}
if (rxbuf->m_pack != NULL) {
- bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
+ bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rx_ptag, rxbuf->pack_map);
+ bus_dmamap_unload(rxr->ptag, rxbuf->pmap);
rxbuf->m_pack->m_flags |= M_PKTHDR;
m_freem(rxbuf->m_pack);
}
@@ -3750,8 +3754,10 @@ igb_setup_receive_ring(struct rx_ring *rxr)
struct adapter *adapter;
struct ifnet *ifp;
device_t dev;
+ struct igb_rx_buf *rxbuf;
+ bus_dma_segment_t pseg[1], hseg[1];
struct lro_ctrl *lro = &rxr->lro;
- int j, rsize, error = 0;
+ int rsize, nsegs, error = 0;
adapter = rxr->adapter;
dev = adapter->dev;
@@ -3768,15 +3774,53 @@ igb_setup_receive_ring(struct rx_ring *rxr)
*/
igb_free_receive_ring(rxr);
- /* Now replenish the ring mbufs */
- for (j = 0; j < adapter->num_rx_desc; j++) {
- if ((error = igb_get_buf(rxr, j, IGB_CLEAN_BOTH)) != 0)
- goto fail;
- }
+ /* Now replenish the ring mbufs */
+ for (int j = 0; j != adapter->num_rx_desc; ++j) {
+ struct mbuf *mh, *mp;
+
+ rxbuf = &rxr->rx_buffers[j];
+
+ /* First the header */
+ rxbuf->m_head = m_gethdr(M_DONTWAIT, MT_DATA);
+ if (rxbuf->m_head == NULL)
+ goto fail;
+ m_adj(rxbuf->m_head, ETHER_ALIGN);
+ mh = rxbuf->m_head;
+ mh->m_len = mh->m_pkthdr.len = MHLEN;
+ mh->m_flags |= M_PKTHDR;
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->htag,
+ rxbuf->hmap, rxbuf->m_head, hseg,
+ &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) /* Nothing elegant to do here */
+ goto fail;
+ bus_dmamap_sync(rxr->htag,
+ rxbuf->hmap, BUS_DMASYNC_PREREAD);
+ /* Update descriptor */
+ rxr->rx_base[j].read.hdr_addr = htole64(hseg[0].ds_addr);
+
+ /* Now the payload cluster */
+ rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA,
+ M_PKTHDR, adapter->rx_mbuf_sz);
+ if (rxbuf->m_pack == NULL)
+ goto fail;
+ mp = rxbuf->m_pack;
+ mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->ptag,
+ rxbuf->pmap, mp, pseg,
+ &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0)
+ goto fail;
+ bus_dmamap_sync(rxr->ptag,
+ rxbuf->pmap, BUS_DMASYNC_PREREAD);
+ /* Update descriptor */
+ rxr->rx_base[j].read.pkt_addr = htole64(pseg[0].ds_addr);
+ }
/* Setup our descriptor indices */
rxr->next_to_check = 0;
- rxr->last_cleaned = 0;
+ rxr->next_to_refresh = 0;
rxr->lro_enabled = FALSE;
if (igb_header_split)
@@ -4049,47 +4093,33 @@ igb_free_receive_buffers(struct rx_ring *rxr)
INIT_DEBUGOUT("free_receive_structures: begin");
- if (rxr->rx_hspare_map != NULL) {
- bus_dmamap_destroy(rxr->rx_htag, rxr->rx_hspare_map);
- rxr->rx_hspare_map = NULL;
- }
-
- if (rxr->rx_hspare_map != NULL) {
- bus_dmamap_destroy(rxr->rx_ptag, rxr->rx_pspare_map);
- rxr->rx_pspare_map = NULL;
- }
-
/* Cleanup any existing buffers */
if (rxr->rx_buffers != NULL) {
for (i = 0; i < adapter->num_rx_desc; i++) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->m_head != NULL) {
- bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
+ bus_dmamap_sync(rxr->htag, rxbuf->hmap,
BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rx_htag,
- rxbuf->head_map);
+ bus_dmamap_unload(rxr->htag, rxbuf->hmap);
rxbuf->m_head->m_flags |= M_PKTHDR;
m_freem(rxbuf->m_head);
}
if (rxbuf->m_pack != NULL) {
- bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
+ bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rx_ptag,
- rxbuf->pack_map);
+ bus_dmamap_unload(rxr->ptag, rxbuf->pmap);
rxbuf->m_pack->m_flags |= M_PKTHDR;
m_freem(rxbuf->m_pack);
}
rxbuf->m_head = NULL;
rxbuf->m_pack = NULL;
- if (rxbuf->head_map != NULL) {
- bus_dmamap_destroy(rxr->rx_htag,
- rxbuf->head_map);
- rxbuf->head_map = NULL;
+ if (rxbuf->hmap != NULL) {
+ bus_dmamap_destroy(rxr->htag, rxbuf->hmap);
+ rxbuf->hmap = NULL;
}
- if (rxbuf->pack_map != NULL) {
- bus_dmamap_destroy(rxr->rx_ptag,
- rxbuf->pack_map);
- rxbuf->pack_map = NULL;
+ if (rxbuf->pmap != NULL) {
+ bus_dmamap_destroy(rxr->ptag, rxbuf->pmap);
+ rxbuf->pmap = NULL;
}
}
if (rxr->rx_buffers != NULL) {
@@ -4098,26 +4128,43 @@ igb_free_receive_buffers(struct rx_ring *rxr)
}
}
- if (rxr->rx_htag != NULL) {
- bus_dma_tag_destroy(rxr->rx_htag);
- rxr->rx_htag = NULL;
+ if (rxr->htag != NULL) {
+ bus_dma_tag_destroy(rxr->htag);
+ rxr->htag = NULL;
}
- if (rxr->rx_ptag != NULL) {
- bus_dma_tag_destroy(rxr->rx_ptag);
- rxr->rx_ptag = NULL;
+ if (rxr->ptag != NULL) {
+ bus_dma_tag_destroy(rxr->ptag);
+ rxr->ptag = NULL;
}
}
static __inline void
-igb_rx_discard(struct rx_ring *rxr, union e1000_adv_rx_desc *cur, int i)
+igb_rx_discard(struct rx_ring *rxr, int i)
{
+ struct adapter *adapter = rxr->adapter;
+ struct igb_rx_buf *rbuf;
+ struct mbuf *mh, *mp;
+ rbuf = &rxr->rx_buffers[i];
if (rxr->fmp != NULL) {
rxr->fmp->m_flags |= M_PKTHDR;
m_freem(rxr->fmp);
rxr->fmp = NULL;
rxr->lmp = NULL;
}
+
+ mh = rbuf->m_head;
+ mp = rbuf->m_pack;
+
+ /* Reuse loaded DMA map and just update mbuf chain */
+ mh->m_len = MHLEN;
+ mh->m_flags |= M_PKTHDR;
+ mh->m_next = NULL;
+
+ mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz;
+ mp->m_data = mp->m_ext.ext_buf;
+ mp->m_next = NULL;
+ return;
}
static __inline void
@@ -4161,28 +4208,29 @@ igb_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype)
* Return TRUE if more to clean, FALSE otherwise
*********************************************************************/
static bool
-igb_rxeof(struct rx_ring *rxr, int count)
+igb_rxeof(struct igb_queue *que, int count)
{
- struct adapter *adapter = rxr->adapter;
+ struct adapter *adapter = que->adapter;
+ struct rx_ring *rxr = que->rxr;
struct ifnet *ifp = adapter->ifp;
struct lro_ctrl *lro = &rxr->lro;
struct lro_entry *queued;
- int i, prog = 0;
+ int i, processed = 0;
u32 ptype, staterr = 0;
union e1000_adv_rx_desc *cur;
IGB_RX_LOCK(rxr);
+ /* Sync the ring. */
+ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/* Main clean loop */
- for (i = rxr->next_to_check; count > 0; prog++) {
- struct mbuf *sendmp, *mh, *mp;
- u16 hlen, plen, hdr, vtag;
- bool eop = FALSE;
- u8 dopayload;
+ for (i = rxr->next_to_check; count != 0;) {
+ struct mbuf *sendmp, *mh, *mp;
+ struct igb_rx_buf *rxbuf;
+ u16 hlen, plen, hdr, vtag;
+ bool eop = FALSE;
- /* Sync the ring. */
- bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
cur = &rxr->rx_base[i];
staterr = le32toh(cur->wb.upper.status_error);
if ((staterr & E1000_RXD_STAT_DD) == 0)
@@ -4192,8 +4240,10 @@ igb_rxeof(struct rx_ring *rxr, int count)
count--;
sendmp = mh = mp = NULL;
cur->wb.upper.status_error = 0;
+ rxbuf = &rxr->rx_buffers[i];
plen = le16toh(cur->wb.upper.length);
ptype = le32toh(cur->wb.lower.lo_dword.data) & IGB_PKTTYPE_MASK;
+ vtag = le16toh(cur->wb.upper.vlan);
hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info);
eop = ((staterr & E1000_RXD_STAT_EOP) == E1000_RXD_STAT_EOP);
@@ -4206,7 +4256,7 @@ igb_rxeof(struct rx_ring *rxr, int count)
rxr->discard = TRUE;
else
rxr->discard = FALSE;
- igb_rx_discard(rxr, cur, i);
+ igb_rx_discard(rxr, i);
goto next_desc;
}
@@ -4229,7 +4279,8 @@ igb_rxeof(struct rx_ring *rxr, int count)
/* Handle the header mbuf */
mh = rxr->rx_buffers[i].m_head;
mh->m_len = hlen;
- dopayload = IGB_CLEAN_HEADER;
+ /* clear buf info for refresh */
+ rxbuf->m_head = NULL;
/*
** Get the payload length, this
** could be zero if its a small
@@ -4239,7 +4290,8 @@ igb_rxeof(struct rx_ring *rxr, int count)
mp = rxr->rx_buffers[i].m_pack;
mp->m_len = plen;
mh->m_next = mp;
- dopayload = IGB_CLEAN_BOTH;
+ /* clear buf info for refresh */
+ rxbuf->m_pack = NULL;
rxr->rx_split_packets++;
}
} else {
@@ -4250,26 +4302,11 @@ igb_rxeof(struct rx_ring *rxr, int count)
*/
mh = rxr->rx_buffers[i].m_pack;
mh->m_len = plen;
- dopayload = IGB_CLEAN_PAYLOAD;
+ /* clear buf info for refresh */
+ rxbuf->m_pack = NULL;
}
- /*
- ** get_buf will overwrite the writeback
- ** descriptor so save the VLAN tag now.
- */
- vtag = le16toh(cur->wb.upper.vlan);
- if (igb_get_buf(rxr, i, dopayload) != 0) {
- ifp->if_iqdrops++;
- /*
- * We've dropped a frame due to lack of resources
- * so we should drop entire multi-segmented
- * frames until we encounter EOP.
- */
- if ((staterr & E1000_RXD_STAT_EOP) != 0)
- rxr->discard = TRUE;
- igb_rx_discard(rxr, cur, i);
- goto next_desc;
- }
+ ++processed; /* So we know when to refresh */
/* Initial frame - setup */
if (rxr->fmp == NULL) {
@@ -4300,14 +4337,14 @@ igb_rxeof(struct rx_ring *rxr, int count)
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
igb_rx_checksum(staterr, rxr->fmp, ptype);
- /* XXX igb(4) always strips VLAN. */
+
if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
(staterr & E1000_RXD_STAT_VP) != 0) {
rxr->fmp->m_pkthdr.ether_vtag = vtag;
rxr->fmp->m_flags |= M_VLANTAG;
}
#if __FreeBSD_version >= 800000
- rxr->fmp->m_pkthdr.flowid = curcpu;
+ rxr->fmp->m_pkthdr.flowid = que->msix;
rxr->fmp->m_flags |= M_FLOWID;
#endif
sendmp = rxr->fmp;
@@ -4321,31 +4358,30 @@ next_desc:
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- rxr->last_cleaned = i; /* For updating tail */
-
/* Advance our pointers to the next descriptor. */
if (++i == adapter->num_rx_desc)
i = 0;
-
/*
- ** Note that we hold the RX lock thru
- ** the following call so this ring's
- ** next_to_check is not gonna change.
+ ** Send to the stack or LRO
*/
if (sendmp != NULL)
igb_rx_input(rxr, ifp, sendmp, ptype);
+
+ /* Every 8 descriptors we go to refresh mbufs */
+ if (processed == 8) {
+ igb_refresh_mbufs(rxr, i);
+ processed = 0;
+ }
}
- if (prog == 0) {
- IGB_RX_UNLOCK(rxr);
- return (FALSE);
+ /* Catch any remainders */
+ if (processed != 0) {
+ igb_refresh_mbufs(rxr, i);
+ processed = 0;
}
rxr->next_to_check = i;
- /* Advance the E1000's Receive Queue "Tail Pointer". */
- E1000_WRITE_REG(&adapter->hw, E1000_RDT(rxr->me), rxr->last_cleaned);
-
/*
* Flush any outstanding LRO work
*/
@@ -4630,7 +4666,7 @@ igb_is_valid_ether_addr(uint8_t *addr)
/*
* Enable PCI Wake On Lan capability
*/
-void
+static void
igb_enable_wakeup(device_t dev)
{
u16 cap, status;
@@ -4651,6 +4687,21 @@ igb_enable_wakeup(device_t dev)
return;
}
+static void
+igb_led_func(void *arg, int onoff)
+{
+ struct adapter *adapter = arg;
+
+ IGB_CORE_LOCK(adapter);
+ if (onoff) {
+ e1000_setup_led(&adapter->hw);
+ e1000_led_on(&adapter->hw);
+ } else {
+ e1000_led_off(&adapter->hw);
+ e1000_cleanup_led(&adapter->hw);
+ }
+ IGB_CORE_UNLOCK(adapter);
+}
/**********************************************************************
*
@@ -4662,10 +4713,12 @@ igb_update_stats_counters(struct adapter *adapter)
{
struct ifnet *ifp;
- if(adapter->hw.phy.media_type == e1000_media_type_copper ||
+ if (adapter->hw.phy.media_type == e1000_media_type_copper ||
(E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
- adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
- adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
+ adapter->stats.symerrs +=
+ E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
+ adapter->stats.sec +=
+ E1000_READ_REG(&adapter->hw, E1000_SEC);
}
adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
diff --git a/sys/dev/e1000/if_igb.h b/sys/dev/e1000/if_igb.h
index fbcf4a0..28bcc91 100644
--- a/sys/dev/e1000/if_igb.h
+++ b/sys/dev/e1000/if_igb.h
@@ -47,8 +47,8 @@
* desscriptors should meet the following condition.
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
-#define IGB_MIN_TXD 80
-#define IGB_DEFAULT_TXD 256
+#define IGB_MIN_TXD 256
+#define IGB_DEFAULT_TXD 1024
#define IGB_MAX_TXD 4096
/*
@@ -62,8 +62,8 @@
* desscriptors should meet the following condition.
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
-#define IGB_MIN_RXD 80
-#define IGB_DEFAULT_RXD 256
+#define IGB_MIN_RXD 256
+#define IGB_DEFAULT_RXD 1024
#define IGB_MAX_RXD 4096
/*
@@ -333,13 +333,11 @@ struct rx_ring {
bool discard;
struct mtx rx_mtx;
char mtx_name[16];
- u32 last_cleaned;
+ u32 next_to_refresh;
u32 next_to_check;
struct igb_rx_buf *rx_buffers;
- bus_dma_tag_t rx_htag; /* dma tag for rx head */
- bus_dmamap_t rx_hspare_map;
- bus_dma_tag_t rx_ptag; /* dma tag for rx packet */
- bus_dmamap_t rx_pspare_map;
+ bus_dma_tag_t htag; /* dma tag for rx head */
+ bus_dma_tag_t ptag; /* dma tag for rx packet */
/*
* First/last mbuf pointers, for
* collecting multisegment RX packets.
@@ -363,6 +361,7 @@ struct adapter {
struct e1000_osdep osdep;
struct device *dev;
+ struct cdev *led_dev;
struct resource *pci_mem;
struct resource *msix_mem;
@@ -468,8 +467,8 @@ struct igb_tx_buffer {
struct igb_rx_buf {
struct mbuf *m_head;
struct mbuf *m_pack;
- bus_dmamap_t head_map; /* bus_dma map for packet */
- bus_dmamap_t pack_map; /* bus_dma map for packet */
+ bus_dmamap_t hmap; /* bus_dma map for header */
+ bus_dmamap_t pmap; /* bus_dma map for packet */
};
#define IGB_CORE_LOCK_INIT(_sc, _name) \
diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c
new file mode 100644
index 0000000..825fb4e
--- /dev/null
+++ b/sys/dev/e1000/if_lem.c
@@ -0,0 +1,4552 @@
+/******************************************************************************
+
+ Copyright (c) 2001-2010, Intel Corporation
+ 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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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$*/
+
+#ifdef HAVE_KERNEL_OPTION_HEADERS
+#include "opt_device_polling.h"
+#include "opt_inet.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+#if __FreeBSD_version >= 700029
+#include <sys/eventhandler.h>
+#endif
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/bpf.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+#include <machine/in_cksum.h>
+#include <dev/led/led.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include "e1000_api.h"
+#include "if_lem.h"
+
+/*********************************************************************
+ * Set this to one to display debug statistics
+ *********************************************************************/
+int lem_display_debug_stats = 0;
+
+/*********************************************************************
+ * Legacy Em Driver version:
+ *********************************************************************/
+char lem_driver_version[] = "1.0.1";
+
+
+/*********************************************************************
+ * PCI Device ID Table
+ *
+ * Used by probe to select devices to load on
+ * Last field stores an index into e1000_strings
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
+ *********************************************************************/
+
+static em_vendor_info_t lem_vendor_info_array[] =
+{
+ /* Intel(R) PRO/1000 Network Connection */
+ { 0x8086, E1000_DEV_ID_82540EM, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82540EM_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82540EP, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82540EP_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82540EP_LP, PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82541EI, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82541ER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82541ER_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82541EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82541GI, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82541GI_LF, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82541GI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82542, PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82543GC_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82543GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82544EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82544EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82544GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82544GC_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82545EM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82545EM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82545GM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82545GM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82545GM_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82546EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546GB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546GB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546GB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546GB_PCIE, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3,
+ PCI_ANY_ID, PCI_ANY_ID, 0},
+
+ { 0x8086, E1000_DEV_ID_82547EI, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82547EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82547GI, PCI_ANY_ID, PCI_ANY_ID, 0},
+ /* required last entry */
+ { 0, 0, 0, 0, 0}
+};
+
+/*********************************************************************
+ * Table of branding strings for all supported NICs.
+ *********************************************************************/
+
+static char *lem_strings[] = {
+ "Intel(R) PRO/1000 Legacy Network Connection"
+};
+
+/*********************************************************************
+ * Function prototypes
+ *********************************************************************/
+static int lem_probe(device_t);
+static int lem_attach(device_t);
+static int lem_detach(device_t);
+static int lem_shutdown(device_t);
+static int lem_suspend(device_t);
+static int lem_resume(device_t);
+static void lem_start(struct ifnet *);
+static void lem_start_locked(struct ifnet *ifp);
+static int lem_ioctl(struct ifnet *, u_long, caddr_t);
+static void lem_init(void *);
+static void lem_init_locked(struct adapter *);
+static void lem_stop(void *);
+static void lem_media_status(struct ifnet *, struct ifmediareq *);
+static int lem_media_change(struct ifnet *);
+static void lem_identify_hardware(struct adapter *);
+static int lem_allocate_pci_resources(struct adapter *);
+static int lem_allocate_irq(struct adapter *adapter);
+static void lem_free_pci_resources(struct adapter *);
+static void lem_local_timer(void *);
+static int lem_hardware_init(struct adapter *);
+static void lem_setup_interface(device_t, struct adapter *);
+static void lem_setup_transmit_structures(struct adapter *);
+static void lem_initialize_transmit_unit(struct adapter *);
+static int lem_setup_receive_structures(struct adapter *);
+static void lem_initialize_receive_unit(struct adapter *);
+static void lem_enable_intr(struct adapter *);
+static void lem_disable_intr(struct adapter *);
+static void lem_free_transmit_structures(struct adapter *);
+static void lem_free_receive_structures(struct adapter *);
+static void lem_update_stats_counters(struct adapter *);
+static void lem_txeof(struct adapter *);
+static void lem_tx_purge(struct adapter *);
+static int lem_allocate_receive_structures(struct adapter *);
+static int lem_allocate_transmit_structures(struct adapter *);
+static int lem_rxeof(struct adapter *, int);
+#ifndef __NO_STRICT_ALIGNMENT
+static int lem_fixup_rx(struct adapter *);
+#endif
+static void lem_receive_checksum(struct adapter *, struct e1000_rx_desc *,
+ struct mbuf *);
+static void lem_transmit_checksum_setup(struct adapter *, struct mbuf *,
+ u32 *, u32 *);
+static void lem_set_promisc(struct adapter *);
+static void lem_disable_promisc(struct adapter *);
+static void lem_set_multi(struct adapter *);
+static void lem_print_hw_stats(struct adapter *);
+static void lem_update_link_status(struct adapter *);
+static int lem_get_buf(struct adapter *, int);
+#if __FreeBSD_version >= 700029
+static void lem_register_vlan(void *, struct ifnet *, u16);
+static void lem_unregister_vlan(void *, struct ifnet *, u16);
+static void lem_setup_vlan_hw_support(struct adapter *);
+#endif
+static int lem_xmit(struct adapter *, struct mbuf **);
+static void lem_smartspeed(struct adapter *);
+static int lem_82547_fifo_workaround(struct adapter *, int);
+static void lem_82547_update_fifo_head(struct adapter *, int);
+static int lem_82547_tx_fifo_reset(struct adapter *);
+static void lem_82547_move_tail(void *);
+static int lem_dma_malloc(struct adapter *, bus_size_t,
+ struct em_dma_alloc *, int);
+static void lem_dma_free(struct adapter *, struct em_dma_alloc *);
+static void lem_print_debug_info(struct adapter *);
+static void lem_print_nvm_info(struct adapter *);
+static int lem_is_valid_ether_addr(u8 *);
+static int lem_sysctl_stats(SYSCTL_HANDLER_ARGS);
+static int lem_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
+static u32 lem_fill_descriptors (bus_addr_t address, u32 length,
+ PDESC_ARRAY desc_array);
+static int lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
+static void lem_add_int_delay_sysctl(struct adapter *, const char *,
+ const char *, struct em_int_delay_info *, int, int);
+/* Management and WOL Support */
+static void lem_init_manageability(struct adapter *);
+static void lem_release_manageability(struct adapter *);
+static void lem_get_hw_control(struct adapter *);
+static void lem_release_hw_control(struct adapter *);
+static void lem_get_wakeup(device_t);
+static void lem_enable_wakeup(device_t);
+static int lem_enable_phy_wakeup(struct adapter *);
+static void lem_led_func(void *, int);
+
+#ifdef EM_LEGACY_IRQ
+static void lem_intr(void *);
+#else /* FAST IRQ */
+#if __FreeBSD_version < 700000
+static void lem_irq_fast(void *);
+#else
+static int lem_irq_fast(void *);
+#endif
+static void lem_handle_rxtx(void *context, int pending);
+static void lem_handle_link(void *context, int pending);
+static void lem_add_rx_process_limit(struct adapter *, const char *,
+ const char *, int *, int);
+#endif /* ~EM_LEGACY_IRQ */
+
+#ifdef DEVICE_POLLING
+static poll_handler_t lem_poll;
+#endif /* POLLING */
+
+/*********************************************************************
+ * FreeBSD Device Interface Entry Points
+ *********************************************************************/
+
+static device_method_t lem_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, lem_probe),
+ DEVMETHOD(device_attach, lem_attach),
+ DEVMETHOD(device_detach, lem_detach),
+ DEVMETHOD(device_shutdown, lem_shutdown),
+ DEVMETHOD(device_suspend, lem_suspend),
+ DEVMETHOD(device_resume, lem_resume),
+ {0, 0}
+};
+
+static driver_t lem_driver = {
+ "em", lem_methods, sizeof(struct adapter),
+};
+
+extern devclass_t em_devclass;
+DRIVER_MODULE(lem, pci, lem_driver, em_devclass, 0, 0);
+MODULE_DEPEND(lem, pci, 1, 1, 1);
+MODULE_DEPEND(lem, ether, 1, 1, 1);
+
+/*********************************************************************
+ * Tunable default values.
+ *********************************************************************/
+
+#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
+#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
+
+static int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
+static int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
+static int lem_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
+static int lem_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV);
+static int lem_rxd = EM_DEFAULT_RXD;
+static int lem_txd = EM_DEFAULT_TXD;
+static int lem_smart_pwr_down = FALSE;
+
+/* Controls whether promiscuous also shows bad packets */
+static int lem_debug_sbp = FALSE;
+
+TUNABLE_INT("hw.em.tx_int_delay", &lem_tx_int_delay_dflt);
+TUNABLE_INT("hw.em.rx_int_delay", &lem_rx_int_delay_dflt);
+TUNABLE_INT("hw.em.tx_abs_int_delay", &lem_tx_abs_int_delay_dflt);
+TUNABLE_INT("hw.em.rx_abs_int_delay", &lem_rx_abs_int_delay_dflt);
+TUNABLE_INT("hw.em.rxd", &lem_rxd);
+TUNABLE_INT("hw.em.txd", &lem_txd);
+TUNABLE_INT("hw.em.smart_pwr_down", &lem_smart_pwr_down);
+TUNABLE_INT("hw.em.sbp", &lem_debug_sbp);
+
+#ifndef EM_LEGACY_IRQ
+/* How many packets rxeof tries to clean at a time */
+static int lem_rx_process_limit = 100;
+TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit);
+#endif
+
+/* Flow control setting - default to FULL */
+static int lem_fc_setting = e1000_fc_full;
+TUNABLE_INT("hw.em.fc_setting", &lem_fc_setting);
+
+/*
+** Shadow VFTA table, this is needed because
+** the real vlan filter table gets cleared during
+** a soft reset and the driver needs to be able
+** to repopulate it.
+*/
+static u32 lem_shadow_vfta[EM_VFTA_SIZE];
+
+/* Global used in WOL setup with multiport cards */
+static int global_quad_port_a = 0;
+
+/*********************************************************************
+ * Device identification routine
+ *
+ * em_probe determines if the driver should be loaded on
+ * adapter based on PCI vendor/device id of the adapter.
+ *
+ * return BUS_PROBE_DEFAULT on success, positive on failure
+ *********************************************************************/
+
+static int
+lem_probe(device_t dev)
+{
+ char adapter_name[60];
+ u16 pci_vendor_id = 0;
+ u16 pci_device_id = 0;
+ u16 pci_subvendor_id = 0;
+ u16 pci_subdevice_id = 0;
+ em_vendor_info_t *ent;
+
+ INIT_DEBUGOUT("em_probe: begin");
+
+ pci_vendor_id = pci_get_vendor(dev);
+ if (pci_vendor_id != EM_VENDOR_ID)
+ return (ENXIO);
+
+ pci_device_id = pci_get_device(dev);
+ pci_subvendor_id = pci_get_subvendor(dev);
+ pci_subdevice_id = pci_get_subdevice(dev);
+
+ ent = lem_vendor_info_array;
+ while (ent->vendor_id != 0) {
+ if ((pci_vendor_id == ent->vendor_id) &&
+ (pci_device_id == ent->device_id) &&
+
+ ((pci_subvendor_id == ent->subvendor_id) ||
+ (ent->subvendor_id == PCI_ANY_ID)) &&
+
+ ((pci_subdevice_id == ent->subdevice_id) ||
+ (ent->subdevice_id == PCI_ANY_ID))) {
+ sprintf(adapter_name, "%s %s",
+ lem_strings[ent->index],
+ lem_driver_version);
+ device_set_desc_copy(dev, adapter_name);
+ return (BUS_PROBE_DEFAULT);
+ }
+ ent++;
+ }
+
+ return (ENXIO);
+}
+
+/*********************************************************************
+ * Device initialization routine
+ *
+ * The attach entry point is called when the driver is being loaded.
+ * This routine identifies the type of hardware, allocates all resources
+ * and initializes the hardware.
+ *
+ * return 0 on success, positive on failure
+ *********************************************************************/
+
+static int
+lem_attach(device_t dev)
+{
+ struct adapter *adapter;
+ int tsize, rsize;
+ int error = 0;
+
+ INIT_DEBUGOUT("lem_attach: begin");
+
+ adapter = device_get_softc(dev);
+ adapter->dev = adapter->osdep.dev = dev;
+ EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
+ EM_TX_LOCK_INIT(adapter, device_get_nameunit(dev));
+ EM_RX_LOCK_INIT(adapter, device_get_nameunit(dev));
+
+ /* SYSCTL stuff */
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
+ lem_sysctl_debug_info, "I", "Debug Information");
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
+ lem_sysctl_stats, "I", "Statistics");
+
+ callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
+ callout_init_mtx(&adapter->tx_fifo_timer, &adapter->tx_mtx, 0);
+
+ /* Determine hardware and mac info */
+ lem_identify_hardware(adapter);
+
+ /* Setup PCI resources */
+ if (lem_allocate_pci_resources(adapter)) {
+ device_printf(dev, "Allocation of PCI resources failed\n");
+ error = ENXIO;
+ goto err_pci;
+ }
+
+ /* Do Shared Code initialization */
+ if (e1000_setup_init_funcs(&adapter->hw, TRUE)) {
+ device_printf(dev, "Setup of Shared code failed\n");
+ error = ENXIO;
+ goto err_pci;
+ }
+
+ e1000_get_bus_info(&adapter->hw);
+
+ /* Set up some sysctls for the tunable interrupt delays */
+ lem_add_int_delay_sysctl(adapter, "rx_int_delay",
+ "receive interrupt delay in usecs", &adapter->rx_int_delay,
+ E1000_REGISTER(&adapter->hw, E1000_RDTR), lem_rx_int_delay_dflt);
+ lem_add_int_delay_sysctl(adapter, "tx_int_delay",
+ "transmit interrupt delay in usecs", &adapter->tx_int_delay,
+ E1000_REGISTER(&adapter->hw, E1000_TIDV), lem_tx_int_delay_dflt);
+ if (adapter->hw.mac.type >= e1000_82540) {
+ lem_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
+ "receive interrupt delay limit in usecs",
+ &adapter->rx_abs_int_delay,
+ E1000_REGISTER(&adapter->hw, E1000_RADV),
+ lem_rx_abs_int_delay_dflt);
+ lem_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
+ "transmit interrupt delay limit in usecs",
+ &adapter->tx_abs_int_delay,
+ E1000_REGISTER(&adapter->hw, E1000_TADV),
+ lem_tx_abs_int_delay_dflt);
+ }
+
+#ifndef EM_LEGACY_IRQ
+ /* Sysctls for limiting the amount of work done in the taskqueue */
+ lem_add_rx_process_limit(adapter, "rx_processing_limit",
+ "max number of rx packets to process", &adapter->rx_process_limit,
+ lem_rx_process_limit);
+#endif
+
+ /*
+ * Validate number of transmit and receive descriptors. It
+ * must not exceed hardware maximum, and must be multiple
+ * of E1000_DBA_ALIGN.
+ */
+ if (((lem_txd * sizeof(struct e1000_tx_desc)) % EM_DBA_ALIGN) != 0 ||
+ (adapter->hw.mac.type >= e1000_82544 && lem_txd > EM_MAX_TXD) ||
+ (adapter->hw.mac.type < e1000_82544 && lem_txd > EM_MAX_TXD_82543) ||
+ (lem_txd < EM_MIN_TXD)) {
+ device_printf(dev, "Using %d TX descriptors instead of %d!\n",
+ EM_DEFAULT_TXD, lem_txd);
+ adapter->num_tx_desc = EM_DEFAULT_TXD;
+ } else
+ adapter->num_tx_desc = lem_txd;
+ if (((lem_rxd * sizeof(struct e1000_rx_desc)) % EM_DBA_ALIGN) != 0 ||
+ (adapter->hw.mac.type >= e1000_82544 && lem_rxd > EM_MAX_RXD) ||
+ (adapter->hw.mac.type < e1000_82544 && lem_rxd > EM_MAX_RXD_82543) ||
+ (lem_rxd < EM_MIN_RXD)) {
+ device_printf(dev, "Using %d RX descriptors instead of %d!\n",
+ EM_DEFAULT_RXD, lem_rxd);
+ adapter->num_rx_desc = EM_DEFAULT_RXD;
+ } else
+ adapter->num_rx_desc = lem_rxd;
+
+ adapter->hw.mac.autoneg = DO_AUTO_NEG;
+ adapter->hw.phy.autoneg_wait_to_complete = FALSE;
+ adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
+ adapter->rx_buffer_len = 2048;
+
+ e1000_init_script_state_82541(&adapter->hw, TRUE);
+ e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE);
+
+ /* Copper options */
+ if (adapter->hw.phy.media_type == e1000_media_type_copper) {
+ adapter->hw.phy.mdix = AUTO_ALL_MODES;
+ adapter->hw.phy.disable_polarity_correction = FALSE;
+ adapter->hw.phy.ms_type = EM_MASTER_SLAVE;
+ }
+
+ /*
+ * Set the frame limits assuming
+ * standard ethernet sized frames.
+ */
+ adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE;
+ adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE;
+
+ /*
+ * This controls when hardware reports transmit completion
+ * status.
+ */
+ adapter->hw.mac.report_tx_early = 1;
+
+ tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
+ EM_DBA_ALIGN);
+
+ /* Allocate Transmit Descriptor ring */
+ if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
+ device_printf(dev, "Unable to allocate tx_desc memory\n");
+ error = ENOMEM;
+ goto err_tx_desc;
+ }
+ adapter->tx_desc_base =
+ (struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
+
+ rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
+ EM_DBA_ALIGN);
+
+ /* Allocate Receive Descriptor ring */
+ if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
+ device_printf(dev, "Unable to allocate rx_desc memory\n");
+ error = ENOMEM;
+ goto err_rx_desc;
+ }
+ adapter->rx_desc_base =
+ (struct e1000_rx_desc *)adapter->rxdma.dma_vaddr;
+
+ /*
+ ** Start from a known state, this is
+ ** important in reading the nvm and
+ ** mac from that.
+ */
+ e1000_reset_hw(&adapter->hw);
+
+ /* Make sure we have a good EEPROM before we read from it */
+ if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
+ /*
+ ** Some PCI-E parts fail the first check due to
+ ** the link being in sleep state, call it again,
+ ** if it fails a second time its a real issue.
+ */
+ if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
+ device_printf(dev,
+ "The EEPROM Checksum Is Not Valid\n");
+ error = EIO;
+ goto err_hw_init;
+ }
+ }
+
+ /* Copy the permanent MAC address out of the EEPROM */
+ if (e1000_read_mac_addr(&adapter->hw) < 0) {
+ device_printf(dev, "EEPROM read error while reading MAC"
+ " address\n");
+ error = EIO;
+ goto err_hw_init;
+ }
+
+ if (!lem_is_valid_ether_addr(adapter->hw.mac.addr)) {
+ device_printf(dev, "Invalid MAC address\n");
+ error = EIO;
+ goto err_hw_init;
+ }
+
+ /* Initialize the hardware */
+ if (lem_hardware_init(adapter)) {
+ device_printf(dev, "Unable to initialize the hardware\n");
+ error = EIO;
+ goto err_hw_init;
+ }
+
+ /* Allocate transmit descriptors and buffers */
+ if (lem_allocate_transmit_structures(adapter)) {
+ device_printf(dev, "Could not setup transmit structures\n");
+ error = ENOMEM;
+ goto err_tx_struct;
+ }
+
+ /* Allocate receive descriptors and buffers */
+ if (lem_allocate_receive_structures(adapter)) {
+ device_printf(dev, "Could not setup receive structures\n");
+ error = ENOMEM;
+ goto err_rx_struct;
+ }
+
+ /*
+ ** Do interrupt configuration
+ */
+ error = lem_allocate_irq(adapter);
+ if (error)
+ goto err_rx_struct;
+
+ /*
+ * Get Wake-on-Lan and Management info for later use
+ */
+ lem_get_wakeup(dev);
+
+ /* Setup OS specific network interface */
+ lem_setup_interface(dev, adapter);
+
+ /* Initialize statistics */
+ lem_update_stats_counters(adapter);
+
+ adapter->hw.mac.get_link_status = 1;
+ lem_update_link_status(adapter);
+
+ /* Indicate SOL/IDER usage */
+ if (e1000_check_reset_block(&adapter->hw))
+ device_printf(dev,
+ "PHY reset is blocked due to SOL/IDER session.\n");
+
+ /* Do we need workaround for 82544 PCI-X adapter? */
+ if (adapter->hw.bus.type == e1000_bus_type_pcix &&
+ adapter->hw.mac.type == e1000_82544)
+ adapter->pcix_82544 = TRUE;
+ else
+ adapter->pcix_82544 = FALSE;
+
+#if __FreeBSD_version >= 700029
+ /* Register for VLAN events */
+ adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
+ lem_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
+ adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
+ lem_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
+#endif
+
+ /* Non-AMT based hardware can now take control from firmware */
+ if (adapter->has_manage && !adapter->has_amt)
+ lem_get_hw_control(adapter);
+
+ /* Tell the stack that the interface is not active */
+ adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+ adapter->led_dev = led_create(lem_led_func, adapter,
+ device_get_nameunit(dev));
+
+ INIT_DEBUGOUT("lem_attach: end");
+
+ return (0);
+
+err_rx_struct:
+ lem_free_transmit_structures(adapter);
+err_tx_struct:
+err_hw_init:
+ lem_release_hw_control(adapter);
+ lem_dma_free(adapter, &adapter->rxdma);
+err_rx_desc:
+ lem_dma_free(adapter, &adapter->txdma);
+err_tx_desc:
+err_pci:
+ lem_free_pci_resources(adapter);
+ EM_TX_LOCK_DESTROY(adapter);
+ EM_RX_LOCK_DESTROY(adapter);
+ EM_CORE_LOCK_DESTROY(adapter);
+
+ return (error);
+}
+
+/*********************************************************************
+ * Device removal routine
+ *
+ * The detach entry point is called when the driver is being removed.
+ * This routine stops the adapter and deallocates all the resources
+ * that were allocated for driver operation.
+ *
+ * return 0 on success, positive on failure
+ *********************************************************************/
+
+static int
+lem_detach(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+ struct ifnet *ifp = adapter->ifp;
+
+ INIT_DEBUGOUT("em_detach: begin");
+
+ /* Make sure VLANS are not using driver */
+#if __FreeBSD_version >= 700000
+ if (adapter->ifp->if_vlantrunk != NULL) {
+#else
+ if (adapter->ifp->if_nvlans != 0) {
+#endif
+ device_printf(dev,"Vlan in use, detach first\n");
+ return (EBUSY);
+ }
+
+#ifdef DEVICE_POLLING
+ if (ifp->if_capenable & IFCAP_POLLING)
+ ether_poll_deregister(ifp);
+#endif
+
+ if (adapter->led_dev != NULL)
+ led_destroy(adapter->led_dev);
+
+ EM_CORE_LOCK(adapter);
+ EM_TX_LOCK(adapter);
+ adapter->in_detach = 1;
+ lem_stop(adapter);
+ e1000_phy_hw_reset(&adapter->hw);
+
+ lem_release_manageability(adapter);
+
+ EM_TX_UNLOCK(adapter);
+ EM_CORE_UNLOCK(adapter);
+
+#if __FreeBSD_version >= 700029
+ /* Unregister VLAN events */
+ if (adapter->vlan_attach != NULL)
+ EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
+ if (adapter->vlan_detach != NULL)
+ EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
+#endif
+
+ ether_ifdetach(adapter->ifp);
+ callout_drain(&adapter->timer);
+ callout_drain(&adapter->tx_fifo_timer);
+
+ lem_free_pci_resources(adapter);
+ bus_generic_detach(dev);
+ if_free(ifp);
+
+ lem_free_transmit_structures(adapter);
+ lem_free_receive_structures(adapter);
+
+ /* Free Transmit Descriptor ring */
+ if (adapter->tx_desc_base) {
+ lem_dma_free(adapter, &adapter->txdma);
+ adapter->tx_desc_base = NULL;
+ }
+
+ /* Free Receive Descriptor ring */
+ if (adapter->rx_desc_base) {
+ lem_dma_free(adapter, &adapter->rxdma);
+ adapter->rx_desc_base = NULL;
+ }
+
+ lem_release_hw_control(adapter);
+ EM_TX_LOCK_DESTROY(adapter);
+ EM_RX_LOCK_DESTROY(adapter);
+ EM_CORE_LOCK_DESTROY(adapter);
+
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * Shutdown entry point
+ *
+ **********************************************************************/
+
+static int
+lem_shutdown(device_t dev)
+{
+ return lem_suspend(dev);
+}
+
+/*
+ * Suspend/resume device methods.
+ */
+static int
+lem_suspend(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+
+ EM_CORE_LOCK(adapter);
+
+ lem_release_manageability(adapter);
+ lem_release_hw_control(adapter);
+ lem_enable_wakeup(dev);
+
+ EM_CORE_UNLOCK(adapter);
+
+ return bus_generic_suspend(dev);
+}
+
+static int
+lem_resume(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+ struct ifnet *ifp = adapter->ifp;
+
+ EM_CORE_LOCK(adapter);
+ lem_init_locked(adapter);
+ lem_init_manageability(adapter);
+ EM_CORE_UNLOCK(adapter);
+ lem_start(ifp);
+
+ return bus_generic_resume(dev);
+}
+
+
+static void
+lem_start_locked(struct ifnet *ifp)
+{
+ struct adapter *adapter = ifp->if_softc;
+ struct mbuf *m_head;
+
+ EM_TX_LOCK_ASSERT(adapter);
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+ if (!adapter->link_active)
+ return;
+
+ while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
+ if (m_head == NULL)
+ break;
+ /*
+ * Encapsulation can modify our pointer, and or make it
+ * NULL on failure. In that event, we can't requeue.
+ */
+ if (lem_xmit(adapter, &m_head)) {
+ if (m_head == NULL)
+ break;
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+ break;
+ }
+
+ /* Send a copy of the frame to the BPF listener */
+ ETHER_BPF_MTAP(ifp, m_head);
+
+ /* Set timeout in case hardware has problems transmitting. */
+ adapter->watchdog_check = TRUE;
+ adapter->watchdog_time = ticks;
+ }
+ if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+
+ return;
+}
+
+static void
+lem_start(struct ifnet *ifp)
+{
+ struct adapter *adapter = ifp->if_softc;
+
+ EM_TX_LOCK(adapter);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ lem_start_locked(ifp);
+ EM_TX_UNLOCK(adapter);
+}
+
+/*********************************************************************
+ * Ioctl entry point
+ *
+ * em_ioctl is called when the user wants to configure the
+ * interface.
+ *
+ * return 0 on success, positive on failure
+ **********************************************************************/
+
+static int
+lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+ struct adapter *adapter = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+#ifdef INET
+ struct ifaddr *ifa = (struct ifaddr *)data;
+#endif
+ int error = 0;
+
+ if (adapter->in_detach)
+ return (error);
+
+ switch (command) {
+ case SIOCSIFADDR:
+#ifdef INET
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ /*
+ * XXX
+ * Since resetting hardware takes a very long time
+ * and results in link renegotiation we only
+ * initialize the hardware only when it is absolutely
+ * required.
+ */
+ ifp->if_flags |= IFF_UP;
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ EM_CORE_LOCK(adapter);
+ lem_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
+ }
+ arp_ifinit(ifp, ifa);
+ } else
+#endif
+ error = ether_ioctl(ifp, command, data);
+ break;
+ case SIOCSIFMTU:
+ {
+ int max_frame_size;
+
+ IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
+
+ EM_CORE_LOCK(adapter);
+ switch (adapter->hw.mac.type) {
+ case e1000_82542:
+ max_frame_size = ETHER_MAX_LEN;
+ break;
+ default:
+ max_frame_size = MAX_JUMBO_FRAME_SIZE;
+ }
+ if (ifr->ifr_mtu > max_frame_size - ETHER_HDR_LEN -
+ ETHER_CRC_LEN) {
+ EM_CORE_UNLOCK(adapter);
+ error = EINVAL;
+ break;
+ }
+
+ ifp->if_mtu = ifr->ifr_mtu;
+ adapter->max_frame_size =
+ ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+ lem_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
+ break;
+ }
+ case SIOCSIFFLAGS:
+ IOCTL_DEBUGOUT("ioctl rcv'd:\
+ SIOCSIFFLAGS (Set Interface Flags)");
+ EM_CORE_LOCK(adapter);
+ if (ifp->if_flags & IFF_UP) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if ((ifp->if_flags ^ adapter->if_flags) &
+ (IFF_PROMISC | IFF_ALLMULTI)) {
+ lem_disable_promisc(adapter);
+ lem_set_promisc(adapter);
+ }
+ } else
+ lem_init_locked(adapter);
+ } else
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ EM_TX_LOCK(adapter);
+ lem_stop(adapter);
+ EM_TX_UNLOCK(adapter);
+ }
+ adapter->if_flags = ifp->if_flags;
+ EM_CORE_UNLOCK(adapter);
+ break;
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI");
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ EM_CORE_LOCK(adapter);
+ lem_disable_intr(adapter);
+ lem_set_multi(adapter);
+ if (adapter->hw.mac.type == e1000_82542 &&
+ adapter->hw.revision_id == E1000_REVISION_2) {
+ lem_initialize_receive_unit(adapter);
+ }
+#ifdef DEVICE_POLLING
+ if (!(ifp->if_capenable & IFCAP_POLLING))
+#endif
+ lem_enable_intr(adapter);
+ EM_CORE_UNLOCK(adapter);
+ }
+ break;
+ case SIOCSIFMEDIA:
+ /* Check SOL/IDER usage */
+ EM_CORE_LOCK(adapter);
+ if (e1000_check_reset_block(&adapter->hw)) {
+ EM_CORE_UNLOCK(adapter);
+ device_printf(adapter->dev, "Media change is"
+ " blocked due to SOL/IDER session.\n");
+ break;
+ }
+ EM_CORE_UNLOCK(adapter);
+ case SIOCGIFMEDIA:
+ IOCTL_DEBUGOUT("ioctl rcv'd: \
+ SIOCxIFMEDIA (Get/Set Interface Media)");
+ error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
+ break;
+ case SIOCSIFCAP:
+ {
+ int mask, reinit;
+
+ IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
+ reinit = 0;
+ mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+#ifdef DEVICE_POLLING
+ if (mask & IFCAP_POLLING) {
+ if (ifr->ifr_reqcap & IFCAP_POLLING) {
+ error = ether_poll_register(lem_poll, ifp);
+ if (error)
+ return (error);
+ EM_CORE_LOCK(adapter);
+ lem_disable_intr(adapter);
+ ifp->if_capenable |= IFCAP_POLLING;
+ EM_CORE_UNLOCK(adapter);
+ } else {
+ error = ether_poll_deregister(ifp);
+ /* Enable interrupt even in error case */
+ EM_CORE_LOCK(adapter);
+ lem_enable_intr(adapter);
+ ifp->if_capenable &= ~IFCAP_POLLING;
+ EM_CORE_UNLOCK(adapter);
+ }
+ }
+#endif
+ if (mask & IFCAP_HWCSUM) {
+ ifp->if_capenable ^= IFCAP_HWCSUM;
+ reinit = 1;
+ }
+ if (mask & IFCAP_VLAN_HWTAGGING) {
+ ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+ reinit = 1;
+ }
+ if ((mask & IFCAP_WOL) &&
+ (ifp->if_capabilities & IFCAP_WOL) != 0) {
+ if (mask & IFCAP_WOL_MCAST)
+ ifp->if_capenable ^= IFCAP_WOL_MCAST;
+ if (mask & IFCAP_WOL_MAGIC)
+ ifp->if_capenable ^= IFCAP_WOL_MAGIC;
+ }
+ if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING))
+ lem_init(adapter);
+#if __FreeBSD_version >= 700000
+ VLAN_CAPABILITIES(ifp);
+#endif
+ break;
+ }
+
+ default:
+ error = ether_ioctl(ifp, command, data);
+ break;
+ }
+
+ return (error);
+}
+
+
+/*********************************************************************
+ * Init entry point
+ *
+ * This routine is used in two ways. It is used by the stack as
+ * init entry point in network interface structure. It is also used
+ * by the driver as a hw/sw initialization routine to get to a
+ * consistent state.
+ *
+ * return 0 on success, positive on failure
+ **********************************************************************/
+
+static void
+lem_init_locked(struct adapter *adapter)
+{
+ struct ifnet *ifp = adapter->ifp;
+ device_t dev = adapter->dev;
+ u32 pba;
+
+ INIT_DEBUGOUT("lem_init: begin");
+
+ EM_CORE_LOCK_ASSERT(adapter);
+
+ EM_TX_LOCK(adapter);
+ lem_stop(adapter);
+ EM_TX_UNLOCK(adapter);
+
+ /*
+ * Packet Buffer Allocation (PBA)
+ * Writing PBA sets the receive portion of the buffer
+ * the remainder is used for the transmit buffer.
+ *
+ * Devices before the 82547 had a Packet Buffer of 64K.
+ * Default allocation: PBA=48K for Rx, leaving 16K for Tx.
+ * After the 82547 the buffer was reduced to 40K.
+ * Default allocation: PBA=30K for Rx, leaving 10K for Tx.
+ * Note: default does not leave enough room for Jumbo Frame >10k.
+ */
+ switch (adapter->hw.mac.type) {
+ case e1000_82547:
+ case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */
+ if (adapter->max_frame_size > 8192)
+ pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */
+ else
+ pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */
+ adapter->tx_fifo_head = 0;
+ adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT;
+ adapter->tx_fifo_size =
+ (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT;
+ break;
+ default:
+ /* Devices before 82547 had a Packet Buffer of 64K. */
+ if (adapter->max_frame_size > 8192)
+ pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
+ else
+ pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
+ }
+
+ INIT_DEBUGOUT1("lem_init: pba=%dK",pba);
+ E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba);
+
+ /* Get the latest mac address, User can use a LAA */
+ bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr,
+ ETHER_ADDR_LEN);
+
+ /* Put the address into the Receive Address Array */
+ e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+
+ /* Initialize the hardware */
+ if (lem_hardware_init(adapter)) {
+ device_printf(dev, "Unable to initialize the hardware\n");
+ return;
+ }
+ lem_update_link_status(adapter);
+
+ /* Setup VLAN support, basic and offload if available */
+ E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
+
+#if __FreeBSD_version < 700029
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
+ u32 ctrl;
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= E1000_CTRL_VME;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+ }
+#else
+ /* Use real VLAN Filter support */
+ lem_setup_vlan_hw_support(adapter);
+#endif
+
+ /* Set hardware offload abilities */
+ ifp->if_hwassist = 0;
+ if (adapter->hw.mac.type >= e1000_82543) {
+ if (ifp->if_capenable & IFCAP_TXCSUM)
+ ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
+ }
+
+ /* Configure for OS presence */
+ lem_init_manageability(adapter);
+
+ /* Prepare transmit descriptors and buffers */
+ lem_setup_transmit_structures(adapter);
+ lem_initialize_transmit_unit(adapter);
+
+ /* Setup Multicast table */
+ lem_set_multi(adapter);
+
+ /* Prepare receive descriptors and buffers */
+ if (lem_setup_receive_structures(adapter)) {
+ device_printf(dev, "Could not setup receive structures\n");
+ EM_TX_LOCK(adapter);
+ lem_stop(adapter);
+ EM_TX_UNLOCK(adapter);
+ return;
+ }
+ lem_initialize_receive_unit(adapter);
+
+ /* Don't lose promiscuous settings */
+ lem_set_promisc(adapter);
+
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
+ e1000_clear_hw_cntrs_base_generic(&adapter->hw);
+
+ /* MSI/X configuration for 82574 */
+ if (adapter->hw.mac.type == e1000_82574) {
+ int tmp;
+ tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
+ tmp |= E1000_CTRL_EXT_PBA_CLR;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp);
+ /*
+ ** Set the IVAR - interrupt vector routing.
+ ** Each nibble represents a vector, high bit
+ ** is enable, other 3 bits are the MSIX table
+ ** entry, we map RXQ0 to 0, TXQ0 to 1, and
+ ** Link (other) to 2, hence the magic number.
+ */
+ E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908);
+ }
+
+#ifdef DEVICE_POLLING
+ /*
+ * Only enable interrupts if we are not polling, make sure
+ * they are off otherwise.
+ */
+ if (ifp->if_capenable & IFCAP_POLLING)
+ lem_disable_intr(adapter);
+ else
+#endif /* DEVICE_POLLING */
+ lem_enable_intr(adapter);
+
+ /* AMT based hardware can now take control from firmware */
+ if (adapter->has_manage && adapter->has_amt)
+ lem_get_hw_control(adapter);
+
+ /* Don't reset the phy next time init gets called */
+ adapter->hw.phy.reset_disable = TRUE;
+}
+
+static void
+lem_init(void *arg)
+{
+ struct adapter *adapter = arg;
+
+ EM_CORE_LOCK(adapter);
+ lem_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
+}
+
+
+#ifdef DEVICE_POLLING
+/*********************************************************************
+ *
+ * Legacy polling routine
+ *
+ *********************************************************************/
+static int
+lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+ struct adapter *adapter = ifp->if_softc;
+ u32 reg_icr, rx_done = 0;
+
+ EM_CORE_LOCK(adapter);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ EM_CORE_UNLOCK(adapter);
+ return (rx_done);
+ }
+
+ if (cmd == POLL_AND_CHECK_STATUS) {
+ reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
+ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ callout_stop(&adapter->timer);
+ adapter->hw.mac.get_link_status = 1;
+ lem_update_link_status(adapter);
+ callout_reset(&adapter->timer, hz,
+ lem_local_timer, adapter);
+ }
+ }
+ EM_CORE_UNLOCK(adapter);
+
+ rx_done = lem_rxeof(adapter, count);
+
+ EM_TX_LOCK(adapter);
+ lem_txeof(adapter);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ lem_start_locked(ifp);
+ EM_TX_UNLOCK(adapter);
+ return (rx_done);
+}
+#endif /* DEVICE_POLLING */
+
+#ifdef EM_LEGACY_IRQ
+/*********************************************************************
+ *
+ * Legacy Interrupt Service routine
+ *
+ *********************************************************************/
+
+static void
+lem_intr(void *arg)
+{
+ struct adapter *adapter = arg;
+ struct ifnet *ifp = adapter->ifp;
+ u32 reg_icr;
+
+
+ if (ifp->if_capenable & IFCAP_POLLING)
+ return;
+
+ EM_CORE_LOCK(adapter);
+ reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
+ if (reg_icr & E1000_ICR_RXO)
+ adapter->rx_overruns++;
+
+ if ((reg_icr == 0xffffffff) || (reg_icr == 0))
+ goto out;
+
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ goto out;
+
+ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ callout_stop(&adapter->timer);
+ adapter->hw.mac.get_link_status = 1;
+ lem_update_link_status(adapter);
+ /* Deal with TX cruft when link lost */
+ lem_tx_purge(adapter);
+ callout_reset(&adapter->timer, hz,
+ lem_local_timer, adapter);
+ goto out;
+ }
+
+ EM_TX_LOCK(adapter);
+ lem_txeof(adapter);
+ lem_rxeof(adapter, -1);
+ lem_txeof(adapter);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+ !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ lem_start_locked(ifp);
+ EM_TX_UNLOCK(adapter);
+
+out:
+ EM_CORE_UNLOCK(adapter);
+ return;
+}
+
+#else /* EM_FAST_IRQ, then fast interrupt routines only */
+
+static void
+lem_handle_link(void *context, int pending)
+{
+ struct adapter *adapter = context;
+ struct ifnet *ifp = adapter->ifp;
+
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ return;
+
+ EM_CORE_LOCK(adapter);
+ callout_stop(&adapter->timer);
+ lem_update_link_status(adapter);
+ /* Deal with TX cruft when link lost */
+ lem_tx_purge(adapter);
+ callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
+ EM_CORE_UNLOCK(adapter);
+}
+
+
+/* Combined RX/TX handler, used by Legacy and MSI */
+static void
+lem_handle_rxtx(void *context, int pending)
+{
+ struct adapter *adapter = context;
+ struct ifnet *ifp = adapter->ifp;
+
+
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (lem_rxeof(adapter, adapter->rx_process_limit) != 0)
+ taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
+ EM_TX_LOCK(adapter);
+ lem_txeof(adapter);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ lem_start_locked(ifp);
+ EM_TX_UNLOCK(adapter);
+ }
+
+ lem_enable_intr(adapter);
+}
+
+/*********************************************************************
+ *
+ * Fast Legacy/MSI Combined Interrupt Service routine
+ *
+ *********************************************************************/
+#if __FreeBSD_version < 700000
+#define FILTER_STRAY
+#define FILTER_HANDLED
+static void
+#else
+static int
+#endif
+lem_irq_fast(void *arg)
+{
+ struct adapter *adapter = arg;
+ struct ifnet *ifp;
+ u32 reg_icr;
+
+ ifp = adapter->ifp;
+
+ reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
+
+ /* Hot eject? */
+ if (reg_icr == 0xffffffff)
+ return FILTER_STRAY;
+
+ /* Definitely not our interrupt. */
+ if (reg_icr == 0x0)
+ return FILTER_STRAY;
+
+ /*
+ * Mask interrupts until the taskqueue is finished running. This is
+ * cheap, just assume that it is needed. This also works around the
+ * MSI message reordering errata on certain systems.
+ */
+ lem_disable_intr(adapter);
+ taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
+
+ /* Link status change */
+ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ adapter->hw.mac.get_link_status = 1;
+ taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
+ }
+
+ if (reg_icr & E1000_ICR_RXO)
+ adapter->rx_overruns++;
+ return FILTER_HANDLED;
+}
+#endif /* ~EM_LEGACY_IRQ */
+
+
+/*********************************************************************
+ *
+ * Media Ioctl callback
+ *
+ * This routine is called whenever the user queries the status of
+ * the interface using ifconfig.
+ *
+ **********************************************************************/
+static void
+lem_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct adapter *adapter = ifp->if_softc;
+ u_char fiber_type = IFM_1000_SX;
+
+ INIT_DEBUGOUT("lem_media_status: begin");
+
+ EM_CORE_LOCK(adapter);
+ lem_update_link_status(adapter);
+
+ ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER;
+
+ if (!adapter->link_active) {
+ EM_CORE_UNLOCK(adapter);
+ return;
+ }
+
+ ifmr->ifm_status |= IFM_ACTIVE;
+
+ if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
+ (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
+ if (adapter->hw.mac.type == e1000_82545)
+ fiber_type = IFM_1000_LX;
+ ifmr->ifm_active |= fiber_type | IFM_FDX;
+ } else {
+ switch (adapter->link_speed) {
+ case 10:
+ ifmr->ifm_active |= IFM_10_T;
+ break;
+ case 100:
+ ifmr->ifm_active |= IFM_100_TX;
+ break;
+ case 1000:
+ ifmr->ifm_active |= IFM_1000_T;
+ break;
+ }
+ if (adapter->link_duplex == FULL_DUPLEX)
+ ifmr->ifm_active |= IFM_FDX;
+ else
+ ifmr->ifm_active |= IFM_HDX;
+ }
+ EM_CORE_UNLOCK(adapter);
+}
+
+/*********************************************************************
+ *
+ * Media Ioctl callback
+ *
+ * This routine is called when the user changes speed/duplex using
+ * media/mediopt option with ifconfig.
+ *
+ **********************************************************************/
+static int
+lem_media_change(struct ifnet *ifp)
+{
+ struct adapter *adapter = ifp->if_softc;
+ struct ifmedia *ifm = &adapter->media;
+
+ INIT_DEBUGOUT("lem_media_change: begin");
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ EM_CORE_LOCK(adapter);
+ switch (IFM_SUBTYPE(ifm->ifm_media)) {
+ case IFM_AUTO:
+ adapter->hw.mac.autoneg = DO_AUTO_NEG;
+ adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
+ break;
+ case IFM_1000_LX:
+ case IFM_1000_SX:
+ case IFM_1000_T:
+ adapter->hw.mac.autoneg = DO_AUTO_NEG;
+ adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ case IFM_100_TX:
+ adapter->hw.mac.autoneg = FALSE;
+ adapter->hw.phy.autoneg_advertised = 0;
+ if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
+ adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_FULL;
+ else
+ adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_HALF;
+ break;
+ case IFM_10_T:
+ adapter->hw.mac.autoneg = FALSE;
+ adapter->hw.phy.autoneg_advertised = 0;
+ if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
+ adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_FULL;
+ else
+ adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_HALF;
+ break;
+ default:
+ device_printf(adapter->dev, "Unsupported media type\n");
+ }
+
+ /* As the speed/duplex settings my have changed we need to
+ * reset the PHY.
+ */
+ adapter->hw.phy.reset_disable = FALSE;
+
+ lem_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
+
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * This routine maps the mbufs to tx descriptors.
+ *
+ * return 0 on success, positive on failure
+ **********************************************************************/
+
+static int
+lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
+{
+ bus_dma_segment_t segs[EM_MAX_SCATTER];
+ bus_dmamap_t map;
+ struct em_buffer *tx_buffer, *tx_buffer_mapped;
+ struct e1000_tx_desc *ctxd = NULL;
+ struct mbuf *m_head;
+ u32 txd_upper, txd_lower, txd_used, txd_saved;
+ int error, nsegs, i, j, first, last = 0;
+#if __FreeBSD_version < 700000
+ struct m_tag *mtag;
+#endif
+ m_head = *m_headp;
+ txd_upper = txd_lower = txd_used = txd_saved = 0;
+
+ /*
+ * Force a cleanup if number of TX descriptors
+ * available hits the threshold
+ */
+ if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
+ lem_txeof(adapter);
+ /* Now do we at least have a minimal? */
+ if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
+ adapter->no_tx_desc_avail1++;
+ return (ENOBUFS);
+ }
+ }
+
+ /*
+ * Map the packet for DMA
+ *
+ * Capture the first descriptor index,
+ * this descriptor will have the index
+ * of the EOP which is the only one that
+ * now gets a DONE bit writeback.
+ */
+ first = adapter->next_avail_tx_desc;
+ tx_buffer = &adapter->tx_buffer_area[first];
+ tx_buffer_mapped = tx_buffer;
+ map = tx_buffer->map;
+
+ error = bus_dmamap_load_mbuf_sg(adapter->txtag, map,
+ *m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
+
+ /*
+ * There are two types of errors we can (try) to handle:
+ * - EFBIG means the mbuf chain was too long and bus_dma ran
+ * out of segments. Defragment the mbuf chain and try again.
+ * - ENOMEM means bus_dma could not obtain enough bounce buffers
+ * at this point in time. Defer sending and try again later.
+ * All other errors, in particular EINVAL, are fatal and prevent the
+ * mbuf chain from ever going through. Drop it and report error.
+ */
+ if (error == EFBIG) {
+ struct mbuf *m;
+
+ m = m_defrag(*m_headp, M_DONTWAIT);
+ if (m == NULL) {
+ adapter->mbuf_alloc_failed++;
+ m_freem(*m_headp);
+ *m_headp = NULL;
+ return (ENOBUFS);
+ }
+ *m_headp = m;
+
+ /* Try it again */
+ error = bus_dmamap_load_mbuf_sg(adapter->txtag, map,
+ *m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
+
+ if (error) {
+ adapter->no_tx_dma_setup++;
+ m_freem(*m_headp);
+ *m_headp = NULL;
+ return (error);
+ }
+ } else if (error != 0) {
+ adapter->no_tx_dma_setup++;
+ return (error);
+ }
+
+ if (nsegs > (adapter->num_tx_desc_avail - 2)) {
+ adapter->no_tx_desc_avail2++;
+ bus_dmamap_unload(adapter->txtag, map);
+ return (ENOBUFS);
+ }
+ m_head = *m_headp;
+
+ /* Do hardware assists */
+ if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)
+ lem_transmit_checksum_setup(adapter, m_head,
+ &txd_upper, &txd_lower);
+
+ i = adapter->next_avail_tx_desc;
+ if (adapter->pcix_82544)
+ txd_saved = i;
+
+ /* Set up our transmit descriptors */
+ for (j = 0; j < nsegs; j++) {
+ bus_size_t seg_len;
+ bus_addr_t seg_addr;
+ /* If adapter is 82544 and on PCIX bus */
+ if(adapter->pcix_82544) {
+ DESC_ARRAY desc_array;
+ u32 array_elements, counter;
+ /*
+ * Check the Address and Length combination and
+ * split the data accordingly
+ */
+ array_elements = lem_fill_descriptors(segs[j].ds_addr,
+ segs[j].ds_len, &desc_array);
+ for (counter = 0; counter < array_elements; counter++) {
+ if (txd_used == adapter->num_tx_desc_avail) {
+ adapter->next_avail_tx_desc = txd_saved;
+ adapter->no_tx_desc_avail2++;
+ bus_dmamap_unload(adapter->txtag, map);
+ return (ENOBUFS);
+ }
+ tx_buffer = &adapter->tx_buffer_area[i];
+ ctxd = &adapter->tx_desc_base[i];
+ ctxd->buffer_addr = htole64(
+ desc_array.descriptor[counter].address);
+ ctxd->lower.data = htole32(
+ (adapter->txd_cmd | txd_lower | (u16)
+ desc_array.descriptor[counter].length));
+ ctxd->upper.data =
+ htole32((txd_upper));
+ last = i;
+ if (++i == adapter->num_tx_desc)
+ i = 0;
+ tx_buffer->m_head = NULL;
+ tx_buffer->next_eop = -1;
+ txd_used++;
+ }
+ } else {
+ tx_buffer = &adapter->tx_buffer_area[i];
+ ctxd = &adapter->tx_desc_base[i];
+ seg_addr = segs[j].ds_addr;
+ seg_len = segs[j].ds_len;
+ ctxd->buffer_addr = htole64(seg_addr);
+ ctxd->lower.data = htole32(
+ adapter->txd_cmd | txd_lower | seg_len);
+ ctxd->upper.data =
+ htole32(txd_upper);
+ last = i;
+ if (++i == adapter->num_tx_desc)
+ i = 0;
+ tx_buffer->m_head = NULL;
+ tx_buffer->next_eop = -1;
+ }
+ }
+
+ adapter->next_avail_tx_desc = i;
+
+ if (adapter->pcix_82544)
+ adapter->num_tx_desc_avail -= txd_used;
+ else
+ adapter->num_tx_desc_avail -= nsegs;
+
+ /*
+ ** Handle VLAN tag, this is the
+ ** biggest difference between
+ ** 6.x and 7
+ */
+#if __FreeBSD_version < 700000
+ /* Find out if we are in vlan mode. */
+ mtag = VLAN_OUTPUT_TAG(ifp, m_head);
+ if (mtag != NULL) {
+ ctxd->upper.fields.special =
+ htole16(VLAN_TAG_VALUE(mtag));
+ ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
+ }
+#else /* FreeBSD 7 */
+ if (m_head->m_flags & M_VLANTAG) {
+ /* Set the vlan id. */
+ ctxd->upper.fields.special =
+ htole16(m_head->m_pkthdr.ether_vtag);
+ /* Tell hardware to add tag */
+ ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
+ }
+#endif
+
+ tx_buffer->m_head = m_head;
+ tx_buffer_mapped->map = tx_buffer->map;
+ tx_buffer->map = map;
+ bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE);
+
+ /*
+ * Last Descriptor of Packet
+ * needs End Of Packet (EOP)
+ * and Report Status (RS)
+ */
+ ctxd->lower.data |=
+ htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
+ /*
+ * Keep track in the first buffer which
+ * descriptor will be written back
+ */
+ tx_buffer = &adapter->tx_buffer_area[first];
+ tx_buffer->next_eop = last;
+
+ /*
+ * Advance the Transmit Descriptor Tail (TDT), this tells the E1000
+ * that this frame is available to transmit.
+ */
+ bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ if (adapter->hw.mac.type == e1000_82547 &&
+ adapter->link_duplex == HALF_DUPLEX)
+ lem_82547_move_tail(adapter);
+ else {
+ E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i);
+ if (adapter->hw.mac.type == e1000_82547)
+ lem_82547_update_fifo_head(adapter,
+ m_head->m_pkthdr.len);
+ }
+
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * 82547 workaround to avoid controller hang in half-duplex environment.
+ * The workaround is to avoid queuing a large packet that would span
+ * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers
+ * in this case. We do that only when FIFO is quiescent.
+ *
+ **********************************************************************/
+static void
+lem_82547_move_tail(void *arg)
+{
+ struct adapter *adapter = arg;
+ struct e1000_tx_desc *tx_desc;
+ u16 hw_tdt, sw_tdt, length = 0;
+ bool eop = 0;
+
+ EM_TX_LOCK_ASSERT(adapter);
+
+ hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT(0));
+ sw_tdt = adapter->next_avail_tx_desc;
+
+ while (hw_tdt != sw_tdt) {
+ tx_desc = &adapter->tx_desc_base[hw_tdt];
+ length += tx_desc->lower.flags.length;
+ eop = tx_desc->lower.data & E1000_TXD_CMD_EOP;
+ if (++hw_tdt == adapter->num_tx_desc)
+ hw_tdt = 0;
+
+ if (eop) {
+ if (lem_82547_fifo_workaround(adapter, length)) {
+ adapter->tx_fifo_wrk_cnt++;
+ callout_reset(&adapter->tx_fifo_timer, 1,
+ lem_82547_move_tail, adapter);
+ break;
+ }
+ E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), hw_tdt);
+ lem_82547_update_fifo_head(adapter, length);
+ length = 0;
+ }
+ }
+}
+
+static int
+lem_82547_fifo_workaround(struct adapter *adapter, int len)
+{
+ int fifo_space, fifo_pkt_len;
+
+ fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR);
+
+ if (adapter->link_duplex == HALF_DUPLEX) {
+ fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
+
+ if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
+ if (lem_82547_tx_fifo_reset(adapter))
+ return (0);
+ else
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+static void
+lem_82547_update_fifo_head(struct adapter *adapter, int len)
+{
+ int fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR);
+
+ /* tx_fifo_head is always 16 byte aligned */
+ adapter->tx_fifo_head += fifo_pkt_len;
+ if (adapter->tx_fifo_head >= adapter->tx_fifo_size) {
+ adapter->tx_fifo_head -= adapter->tx_fifo_size;
+ }
+}
+
+
+static int
+lem_82547_tx_fifo_reset(struct adapter *adapter)
+{
+ u32 tctl;
+
+ if ((E1000_READ_REG(&adapter->hw, E1000_TDT(0)) ==
+ E1000_READ_REG(&adapter->hw, E1000_TDH(0))) &&
+ (E1000_READ_REG(&adapter->hw, E1000_TDFT) ==
+ E1000_READ_REG(&adapter->hw, E1000_TDFH)) &&
+ (E1000_READ_REG(&adapter->hw, E1000_TDFTS) ==
+ E1000_READ_REG(&adapter->hw, E1000_TDFHS)) &&
+ (E1000_READ_REG(&adapter->hw, E1000_TDFPC) == 0)) {
+ /* Disable TX unit */
+ tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
+ E1000_WRITE_REG(&adapter->hw, E1000_TCTL,
+ tctl & ~E1000_TCTL_EN);
+
+ /* Reset FIFO pointers */
+ E1000_WRITE_REG(&adapter->hw, E1000_TDFT,
+ adapter->tx_head_addr);
+ E1000_WRITE_REG(&adapter->hw, E1000_TDFH,
+ adapter->tx_head_addr);
+ E1000_WRITE_REG(&adapter->hw, E1000_TDFTS,
+ adapter->tx_head_addr);
+ E1000_WRITE_REG(&adapter->hw, E1000_TDFHS,
+ adapter->tx_head_addr);
+
+ /* Re-enable TX unit */
+ E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
+ E1000_WRITE_FLUSH(&adapter->hw);
+
+ adapter->tx_fifo_head = 0;
+ adapter->tx_fifo_reset_cnt++;
+
+ return (TRUE);
+ }
+ else {
+ return (FALSE);
+ }
+}
+
+static void
+lem_set_promisc(struct adapter *adapter)
+{
+ struct ifnet *ifp = adapter->ifp;
+ u32 reg_rctl;
+
+ reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+
+ if (ifp->if_flags & IFF_PROMISC) {
+ reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
+ /* Turn this on if you want to see bad packets */
+ if (lem_debug_sbp)
+ reg_rctl |= E1000_RCTL_SBP;
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
+ } else if (ifp->if_flags & IFF_ALLMULTI) {
+ reg_rctl |= E1000_RCTL_MPE;
+ reg_rctl &= ~E1000_RCTL_UPE;
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
+ }
+}
+
+static void
+lem_disable_promisc(struct adapter *adapter)
+{
+ u32 reg_rctl;
+
+ reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+
+ reg_rctl &= (~E1000_RCTL_UPE);
+ reg_rctl &= (~E1000_RCTL_MPE);
+ reg_rctl &= (~E1000_RCTL_SBP);
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
+}
+
+
+/*********************************************************************
+ * Multicast Update
+ *
+ * This routine is called whenever multicast address list is updated.
+ *
+ **********************************************************************/
+
+static void
+lem_set_multi(struct adapter *adapter)
+{
+ struct ifnet *ifp = adapter->ifp;
+ struct ifmultiaddr *ifma;
+ u32 reg_rctl = 0;
+ u8 *mta; /* Multicast array memory */
+ int mcnt = 0;
+
+ IOCTL_DEBUGOUT("lem_set_multi: begin");
+
+ if (adapter->hw.mac.type == e1000_82542 &&
+ adapter->hw.revision_id == E1000_REVISION_2) {
+ reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+ if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+ e1000_pci_clear_mwi(&adapter->hw);
+ reg_rctl |= E1000_RCTL_RST;
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
+ msec_delay(5);
+ }
+
+ /* Allocate temporary memory to setup array */
+ mta = malloc(sizeof(u8) *
+ (ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (mta == NULL)
+ panic("lem_set_multi memory failure\n");
+
+#if __FreeBSD_version < 800000
+ IF_ADDR_LOCK(ifp);
+#else
+ if_maddr_rlock(ifp);
+#endif
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
+ break;
+
+ bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
+ &mta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN);
+ mcnt++;
+ }
+#if __FreeBSD_version < 800000
+ IF_ADDR_UNLOCK(ifp);
+#else
+ if_maddr_runlock(ifp);
+#endif
+ if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) {
+ reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+ reg_rctl |= E1000_RCTL_MPE;
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
+ } else
+ e1000_update_mc_addr_list(&adapter->hw, mta, mcnt);
+
+ if (adapter->hw.mac.type == e1000_82542 &&
+ adapter->hw.revision_id == E1000_REVISION_2) {
+ reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+ reg_rctl &= ~E1000_RCTL_RST;
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
+ msec_delay(5);
+ if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+ e1000_pci_set_mwi(&adapter->hw);
+ }
+ free(mta, M_DEVBUF);
+}
+
+
+/*********************************************************************
+ * Timer routine
+ *
+ * This routine checks for link status and updates statistics.
+ *
+ **********************************************************************/
+
+static void
+lem_local_timer(void *arg)
+{
+ struct adapter *adapter = arg;
+ struct ifnet *ifp = adapter->ifp;
+
+ EM_CORE_LOCK_ASSERT(adapter);
+
+ taskqueue_enqueue(adapter->tq,
+ &adapter->rxtx_task);
+ lem_update_link_status(adapter);
+ lem_update_stats_counters(adapter);
+
+ if (lem_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING)
+ lem_print_hw_stats(adapter);
+
+ lem_smartspeed(adapter);
+
+ /*
+ * We check the watchdog: the time since
+ * the last TX descriptor was cleaned.
+ * This implies a functional TX engine.
+ */
+ if ((adapter->watchdog_check == TRUE) &&
+ (ticks - adapter->watchdog_time > EM_WATCHDOG))
+ goto hung;
+
+ callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
+ return;
+hung:
+ device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
+ adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ adapter->watchdog_events++;
+ lem_init_locked(adapter);
+}
+
+static void
+lem_update_link_status(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct ifnet *ifp = adapter->ifp;
+ device_t dev = adapter->dev;
+ u32 link_check = 0;
+
+ /* Get the cached link value or read phy for real */
+ switch (hw->phy.media_type) {
+ case e1000_media_type_copper:
+ if (hw->mac.get_link_status) {
+ /* Do the work to read phy */
+ e1000_check_for_link(hw);
+ link_check = !hw->mac.get_link_status;
+ if (link_check) /* ESB2 fix */
+ e1000_cfg_on_link_up(hw);
+ } else
+ link_check = TRUE;
+ break;
+ case e1000_media_type_fiber:
+ e1000_check_for_link(hw);
+ link_check = (E1000_READ_REG(hw, E1000_STATUS) &
+ E1000_STATUS_LU);
+ break;
+ case e1000_media_type_internal_serdes:
+ e1000_check_for_link(hw);
+ link_check = adapter->hw.mac.serdes_has_link;
+ break;
+ default:
+ case e1000_media_type_unknown:
+ break;
+ }
+
+ /* Now check for a transition */
+ if (link_check && (adapter->link_active == 0)) {
+ e1000_get_speed_and_duplex(hw, &adapter->link_speed,
+ &adapter->link_duplex);
+ if (bootverbose)
+ device_printf(dev, "Link is up %d Mbps %s\n",
+ adapter->link_speed,
+ ((adapter->link_duplex == FULL_DUPLEX) ?
+ "Full Duplex" : "Half Duplex"));
+ adapter->link_active = 1;
+ adapter->smartspeed = 0;
+ ifp->if_baudrate = adapter->link_speed * 1000000;
+ if_link_state_change(ifp, LINK_STATE_UP);
+ } else if (!link_check && (adapter->link_active == 1)) {
+ ifp->if_baudrate = adapter->link_speed = 0;
+ adapter->link_duplex = 0;
+ if (bootverbose)
+ device_printf(dev, "Link is Down\n");
+ adapter->link_active = 0;
+ /* Link down, disable watchdog */
+ adapter->watchdog_check = FALSE;
+ if_link_state_change(ifp, LINK_STATE_DOWN);
+ }
+}
+
+/*********************************************************************
+ *
+ * This routine disables all traffic on the adapter by issuing a
+ * global reset on the MAC and deallocates TX/RX buffers.
+ *
+ * This routine should always be called with BOTH the CORE
+ * and TX locks.
+ **********************************************************************/
+
+static void
+lem_stop(void *arg)
+{
+ struct adapter *adapter = arg;
+ struct ifnet *ifp = adapter->ifp;
+
+ EM_CORE_LOCK_ASSERT(adapter);
+ EM_TX_LOCK_ASSERT(adapter);
+
+ INIT_DEBUGOUT("lem_stop: begin");
+
+ lem_disable_intr(adapter);
+ callout_stop(&adapter->timer);
+ callout_stop(&adapter->tx_fifo_timer);
+
+ /* Tell the stack that the interface is no longer active */
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+ e1000_reset_hw(&adapter->hw);
+ if (adapter->hw.mac.type >= e1000_82544)
+ E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
+
+ e1000_led_off(&adapter->hw);
+ e1000_cleanup_led(&adapter->hw);
+}
+
+
+/*********************************************************************
+ *
+ * Determine hardware revision.
+ *
+ **********************************************************************/
+static void
+lem_identify_hardware(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+
+ /* Make sure our PCI config space has the necessary stuff set */
+ adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (!((adapter->hw.bus.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
+ (adapter->hw.bus.pci_cmd_word & PCIM_CMD_MEMEN))) {
+ device_printf(dev, "Memory Access and/or Bus Master bits "
+ "were not set!\n");
+ adapter->hw.bus.pci_cmd_word |=
+ (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
+ pci_write_config(dev, PCIR_COMMAND,
+ adapter->hw.bus.pci_cmd_word, 2);
+ }
+
+ /* Save off the information about this board */
+ adapter->hw.vendor_id = pci_get_vendor(dev);
+ adapter->hw.device_id = pci_get_device(dev);
+ adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
+ adapter->hw.subsystem_vendor_id =
+ pci_read_config(dev, PCIR_SUBVEND_0, 2);
+ adapter->hw.subsystem_device_id =
+ pci_read_config(dev, PCIR_SUBDEV_0, 2);
+
+ /* Do Shared Code Init and Setup */
+ if (e1000_set_mac_type(&adapter->hw)) {
+ device_printf(dev, "Setup init failure\n");
+ return;
+ }
+}
+
+static int
+lem_allocate_pci_resources(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ int val, rid, error = E1000_SUCCESS;
+
+ rid = PCIR_BAR(0);
+ adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &rid, RF_ACTIVE);
+ if (adapter->memory == NULL) {
+ device_printf(dev, "Unable to allocate bus resource: memory\n");
+ return (ENXIO);
+ }
+ adapter->osdep.mem_bus_space_tag =
+ rman_get_bustag(adapter->memory);
+ adapter->osdep.mem_bus_space_handle =
+ rman_get_bushandle(adapter->memory);
+ adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
+
+ /* Only older adapters use IO mapping */
+ if (adapter->hw.mac.type > e1000_82543) {
+ /* Figure our where our IO BAR is ? */
+ for (rid = PCIR_BAR(0); rid < PCIR_CIS;) {
+ val = pci_read_config(dev, rid, 4);
+ if (EM_BAR_TYPE(val) == EM_BAR_TYPE_IO) {
+ adapter->io_rid = rid;
+ break;
+ }
+ rid += 4;
+ /* check for 64bit BAR */
+ if (EM_BAR_MEM_TYPE(val) == EM_BAR_MEM_TYPE_64BIT)
+ rid += 4;
+ }
+ if (rid >= PCIR_CIS) {
+ device_printf(dev, "Unable to locate IO BAR\n");
+ return (ENXIO);
+ }
+ adapter->ioport = bus_alloc_resource_any(dev,
+ SYS_RES_IOPORT, &adapter->io_rid, RF_ACTIVE);
+ if (adapter->ioport == NULL) {
+ device_printf(dev, "Unable to allocate bus resource: "
+ "ioport\n");
+ return (ENXIO);
+ }
+ adapter->hw.io_base = 0;
+ adapter->osdep.io_bus_space_tag =
+ rman_get_bustag(adapter->ioport);
+ adapter->osdep.io_bus_space_handle =
+ rman_get_bushandle(adapter->ioport);
+ }
+
+ adapter->hw.back = &adapter->osdep;
+
+ return (error);
+}
+
+/*********************************************************************
+ *
+ * Setup the Legacy or MSI Interrupt handler
+ *
+ **********************************************************************/
+int
+lem_allocate_irq(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ int error, rid = 0;
+
+ /* Manually turn off all interrupts */
+ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
+
+ /* We allocate a single interrupt resource */
+ adapter->res[0] = bus_alloc_resource_any(dev,
+ SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
+ if (adapter->res[0] == NULL) {
+ device_printf(dev, "Unable to allocate bus resource: "
+ "interrupt\n");
+ return (ENXIO);
+ }
+
+#ifdef EM_LEGACY_IRQ
+ /* We do Legacy setup */
+ if ((error = bus_setup_intr(dev, adapter->res[0],
+#if __FreeBSD_version > 700000
+ INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
+#else /* 6.X */
+ INTR_TYPE_NET | INTR_MPSAFE, lem_intr, adapter,
+#endif
+ &adapter->tag[0])) != 0) {
+ device_printf(dev, "Failed to register interrupt handler");
+ return (error);
+ }
+
+#else /* FAST_IRQ */
+ /*
+ * Try allocating a fast interrupt and the associated deferred
+ * processing contexts.
+ */
+ TASK_INIT(&adapter->rxtx_task, 0, lem_handle_rxtx, adapter);
+ TASK_INIT(&adapter->link_task, 0, lem_handle_link, adapter);
+ adapter->tq = taskqueue_create_fast("lem_taskq", M_NOWAIT,
+ taskqueue_thread_enqueue, &adapter->tq);
+ taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
+ device_get_nameunit(adapter->dev));
+#if __FreeBSD_version < 700000
+ if ((error = bus_setup_intr(dev, adapter->res[0],
+ INTR_TYPE_NET | INTR_FAST, lem_irq_fast, adapter,
+#else
+ if ((error = bus_setup_intr(dev, adapter->res[0],
+ INTR_TYPE_NET, lem_irq_fast, NULL, adapter,
+#endif
+ &adapter->tag[0])) != 0) {
+ device_printf(dev, "Failed to register fast interrupt "
+ "handler: %d\n", error);
+ taskqueue_free(adapter->tq);
+ adapter->tq = NULL;
+ return (error);
+ }
+#endif /* EM_LEGACY_IRQ */
+
+ return (0);
+}
+
+
+static void
+lem_free_pci_resources(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+
+
+ if (adapter->tag[0] != NULL) {
+ bus_teardown_intr(dev, adapter->res[0],
+ adapter->tag[0]);
+ adapter->tag[0] = NULL;
+ }
+
+ if (adapter->res[0] != NULL) {
+ bus_release_resource(dev, SYS_RES_IRQ,
+ 0, adapter->res[0]);
+ }
+
+ if (adapter->memory != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ PCIR_BAR(0), adapter->memory);
+
+ if (adapter->ioport != NULL)
+ bus_release_resource(dev, SYS_RES_IOPORT,
+ adapter->io_rid, adapter->ioport);
+}
+
+
+/*********************************************************************
+ *
+ * Initialize the hardware to a configuration
+ * as specified by the adapter structure.
+ *
+ **********************************************************************/
+static int
+lem_hardware_init(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ u16 rx_buffer_size;
+
+ INIT_DEBUGOUT("lem_hardware_init: begin");
+
+ /* Issue a global reset */
+ e1000_reset_hw(&adapter->hw);
+
+ /* When hardware is reset, fifo_head is also reset */
+ adapter->tx_fifo_head = 0;
+
+ /*
+ * These parameters control the automatic generation (Tx) and
+ * response (Rx) to Ethernet PAUSE frames.
+ * - High water mark should allow for at least two frames to be
+ * received after sending an XOFF.
+ * - Low water mark works best when it is very near the high water mark.
+ * This allows the receiver to restart by sending XON when it has
+ * drained a bit. Here we use an arbitary value of 1500 which will
+ * restart after one full frame is pulled from the buffer. There
+ * could be several smaller frames in the buffer and if so they will
+ * not trigger the XON until their total number reduces the buffer
+ * by 1500.
+ * - The pause time is fairly large at 1000 x 512ns = 512 usec.
+ */
+ rx_buffer_size = ((E1000_READ_REG(&adapter->hw, E1000_PBA) &
+ 0xffff) << 10 );
+
+ adapter->hw.fc.high_water = rx_buffer_size -
+ roundup2(adapter->max_frame_size, 1024);
+ adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500;
+
+ adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME;
+ adapter->hw.fc.send_xon = TRUE;
+
+ /* Set Flow control, use the tunable location if sane */
+ if ((lem_fc_setting >= 0) || (lem_fc_setting < 4))
+ adapter->hw.fc.requested_mode = lem_fc_setting;
+ else
+ adapter->hw.fc.requested_mode = e1000_fc_none;
+
+ if (e1000_init_hw(&adapter->hw) < 0) {
+ device_printf(dev, "Hardware Initialization Failed\n");
+ return (EIO);
+ }
+
+ e1000_check_for_link(&adapter->hw);
+
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * Setup networking device structure and register an interface.
+ *
+ **********************************************************************/
+static void
+lem_setup_interface(device_t dev, struct adapter *adapter)
+{
+ struct ifnet *ifp;
+
+ INIT_DEBUGOUT("lem_setup_interface: begin");
+
+ ifp = adapter->ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ panic("%s: can not if_alloc()", device_get_nameunit(dev));
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_init = lem_init;
+ ifp->if_softc = adapter;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = lem_ioctl;
+ ifp->if_start = lem_start;
+ IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1);
+ ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1;
+ IFQ_SET_READY(&ifp->if_snd);
+
+ ether_ifattach(ifp, adapter->hw.mac.addr);
+
+ ifp->if_capabilities = ifp->if_capenable = 0;
+
+ if (adapter->hw.mac.type >= e1000_82543) {
+ int version_cap;
+#if __FreeBSD_version < 700000
+ version_cap = IFCAP_HWCSUM;
+#else
+ version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
+#endif
+ ifp->if_capabilities |= version_cap;
+ ifp->if_capenable |= version_cap;
+ }
+
+ /*
+ * Tell the upper layer(s) we support long frames.
+ */
+ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
+ ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
+
+#ifdef DEVICE_POLLING
+ ifp->if_capabilities |= IFCAP_POLLING;
+#endif
+
+ /* Enable All WOL methods by default */
+ if (adapter->wol) {
+ ifp->if_capabilities |= IFCAP_WOL;
+ ifp->if_capenable |= IFCAP_WOL;
+ }
+
+ /*
+ * Specify the media types supported by this adapter and register
+ * callbacks to update media and link information
+ */
+ ifmedia_init(&adapter->media, IFM_IMASK,
+ lem_media_change, lem_media_status);
+ if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
+ (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
+ u_char fiber_type = IFM_1000_SX; /* default type */
+
+ if (adapter->hw.mac.type == e1000_82545)
+ fiber_type = IFM_1000_LX;
+ ifmedia_add(&adapter->media, IFM_ETHER | fiber_type | IFM_FDX,
+ 0, NULL);
+ ifmedia_add(&adapter->media, IFM_ETHER | fiber_type, 0, NULL);
+ } else {
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL);
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX,
+ 0, NULL);
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX,
+ 0, NULL);
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
+ 0, NULL);
+ if (adapter->hw.phy.type != e1000_phy_ife) {
+ ifmedia_add(&adapter->media,
+ IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
+ ifmedia_add(&adapter->media,
+ IFM_ETHER | IFM_1000_T, 0, NULL);
+ }
+ }
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
+}
+
+
+/*********************************************************************
+ *
+ * Workaround for SmartSpeed on 82541 and 82547 controllers
+ *
+ **********************************************************************/
+static void
+lem_smartspeed(struct adapter *adapter)
+{
+ u16 phy_tmp;
+
+ if (adapter->link_active || (adapter->hw.phy.type != e1000_phy_igp) ||
+ adapter->hw.mac.autoneg == 0 ||
+ (adapter->hw.phy.autoneg_advertised & ADVERTISE_1000_FULL) == 0)
+ return;
+
+ if (adapter->smartspeed == 0) {
+ /* If Master/Slave config fault is asserted twice,
+ * we assume back-to-back */
+ e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
+ if (!(phy_tmp & SR_1000T_MS_CONFIG_FAULT))
+ return;
+ e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
+ if (phy_tmp & SR_1000T_MS_CONFIG_FAULT) {
+ e1000_read_phy_reg(&adapter->hw,
+ PHY_1000T_CTRL, &phy_tmp);
+ if(phy_tmp & CR_1000T_MS_ENABLE) {
+ phy_tmp &= ~CR_1000T_MS_ENABLE;
+ e1000_write_phy_reg(&adapter->hw,
+ PHY_1000T_CTRL, phy_tmp);
+ adapter->smartspeed++;
+ if(adapter->hw.mac.autoneg &&
+ !e1000_copper_link_autoneg(&adapter->hw) &&
+ !e1000_read_phy_reg(&adapter->hw,
+ PHY_CONTROL, &phy_tmp)) {
+ phy_tmp |= (MII_CR_AUTO_NEG_EN |
+ MII_CR_RESTART_AUTO_NEG);
+ e1000_write_phy_reg(&adapter->hw,
+ PHY_CONTROL, phy_tmp);
+ }
+ }
+ }
+ return;
+ } else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) {
+ /* If still no link, perhaps using 2/3 pair cable */
+ e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp);
+ phy_tmp |= CR_1000T_MS_ENABLE;
+ e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp);
+ if(adapter->hw.mac.autoneg &&
+ !e1000_copper_link_autoneg(&adapter->hw) &&
+ !e1000_read_phy_reg(&adapter->hw, PHY_CONTROL, &phy_tmp)) {
+ phy_tmp |= (MII_CR_AUTO_NEG_EN |
+ MII_CR_RESTART_AUTO_NEG);
+ e1000_write_phy_reg(&adapter->hw, PHY_CONTROL, phy_tmp);
+ }
+ }
+ /* Restart process after EM_SMARTSPEED_MAX iterations */
+ if(adapter->smartspeed++ == EM_SMARTSPEED_MAX)
+ adapter->smartspeed = 0;
+}
+
+
+/*
+ * Manage DMA'able memory.
+ */
+static void
+lem_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ if (error)
+ return;
+ *(bus_addr_t *) arg = segs[0].ds_addr;
+}
+
+static int
+lem_dma_malloc(struct adapter *adapter, bus_size_t size,
+ struct em_dma_alloc *dma, int mapflags)
+{
+ int error;
+
+#if __FreeBSD_version >= 700000
+ error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
+#else
+ error = bus_dma_tag_create(NULL, /* parent */
+#endif
+ EM_DBA_ALIGN, 0, /* alignment, bounds */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ size, /* maxsize */
+ 1, /* nsegments */
+ size, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
+ &dma->dma_tag);
+ if (error) {
+ device_printf(adapter->dev,
+ "%s: bus_dma_tag_create failed: %d\n",
+ __func__, error);
+ goto fail_0;
+ }
+
+ error = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dma->dma_map);
+ if (error) {
+ device_printf(adapter->dev,
+ "%s: bus_dmamem_alloc(%ju) failed: %d\n",
+ __func__, (uintmax_t)size, error);
+ goto fail_2;
+ }
+
+ dma->dma_paddr = 0;
+ error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
+ size, lem_dmamap_cb, &dma->dma_paddr, mapflags | BUS_DMA_NOWAIT);
+ if (error || dma->dma_paddr == 0) {
+ device_printf(adapter->dev,
+ "%s: bus_dmamap_load failed: %d\n",
+ __func__, error);
+ goto fail_3;
+ }
+
+ return (0);
+
+fail_3:
+ bus_dmamap_unload(dma->dma_tag, dma->dma_map);
+fail_2:
+ bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
+ bus_dma_tag_destroy(dma->dma_tag);
+fail_0:
+ dma->dma_map = NULL;
+ dma->dma_tag = NULL;
+
+ return (error);
+}
+
+static void
+lem_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
+{
+ if (dma->dma_tag == NULL)
+ return;
+ if (dma->dma_map != NULL) {
+ bus_dmamap_sync(dma->dma_tag, dma->dma_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(dma->dma_tag, dma->dma_map);
+ bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
+ dma->dma_map = NULL;
+ }
+ bus_dma_tag_destroy(dma->dma_tag);
+ dma->dma_tag = NULL;
+}
+
+
+/*********************************************************************
+ *
+ * Allocate memory for tx_buffer structures. The tx_buffer stores all
+ * the information needed to transmit a packet on the wire.
+ *
+ **********************************************************************/
+static int
+lem_allocate_transmit_structures(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ struct em_buffer *tx_buffer;
+ int error;
+
+ /*
+ * Create DMA tags for tx descriptors
+ */
+#if __FreeBSD_version >= 700000
+ if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
+#else
+ if ((error = bus_dma_tag_create(NULL, /* parent */
+#endif
+ 1, 0, /* alignment, bounds */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ EM_TSO_SIZE, /* maxsize */
+ EM_MAX_SCATTER, /* nsegments */
+ EM_TSO_SEG_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
+ &adapter->txtag)) != 0) {
+ device_printf(dev, "Unable to allocate TX DMA tag\n");
+ goto fail;
+ }
+
+ adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) *
+ adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (adapter->tx_buffer_area == NULL) {
+ device_printf(dev, "Unable to allocate tx_buffer memory\n");
+ error = ENOMEM;
+ goto fail;
+ }
+
+ /* Create the descriptor buffer dma maps */
+ for (int i = 0; i < adapter->num_tx_desc; i++) {
+ tx_buffer = &adapter->tx_buffer_area[i];
+ error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map);
+ if (error != 0) {
+ device_printf(dev, "Unable to create TX DMA map\n");
+ goto fail;
+ }
+ tx_buffer->next_eop = -1;
+ }
+
+ return (0);
+fail:
+ lem_free_transmit_structures(adapter);
+ return (error);
+}
+
+/*********************************************************************
+ *
+ * (Re)Initialize transmit structures.
+ *
+ **********************************************************************/
+static void
+lem_setup_transmit_structures(struct adapter *adapter)
+{
+ struct em_buffer *tx_buffer;
+
+ /* Clear the old ring contents */
+ bzero(adapter->tx_desc_base,
+ (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
+
+ /* Free any existing TX buffers */
+ for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
+ tx_buffer = &adapter->tx_buffer_area[i];
+ bus_dmamap_sync(adapter->txtag, tx_buffer->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(adapter->txtag, tx_buffer->map);
+ m_freem(tx_buffer->m_head);
+ tx_buffer->m_head = NULL;
+ tx_buffer->next_eop = -1;
+ }
+
+ /* Reset state */
+ adapter->next_avail_tx_desc = 0;
+ adapter->next_tx_to_clean = 0;
+ adapter->num_tx_desc_avail = adapter->num_tx_desc;
+
+ bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ return;
+}
+
+/*********************************************************************
+ *
+ * Enable transmit unit.
+ *
+ **********************************************************************/
+static void
+lem_initialize_transmit_unit(struct adapter *adapter)
+{
+ u32 tctl, tipg = 0;
+ u64 bus_addr;
+
+ INIT_DEBUGOUT("lem_initialize_transmit_unit: begin");
+ /* Setup the Base and Length of the Tx Descriptor Ring */
+ bus_addr = adapter->txdma.dma_paddr;
+ E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0),
+ adapter->num_tx_desc * sizeof(struct e1000_tx_desc));
+ E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0),
+ (u32)(bus_addr >> 32));
+ E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0),
+ (u32)bus_addr);
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+ E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0);
+ E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0);
+
+ HW_DEBUGOUT2("Base = %x, Length = %x\n",
+ E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)),
+ E1000_READ_REG(&adapter->hw, E1000_TDLEN(0)));
+
+ /* Set the default values for the Tx Inter Packet Gap timer */
+ switch (adapter->hw.mac.type) {
+ case e1000_82542:
+ tipg = DEFAULT_82542_TIPG_IPGT;
+ tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+ tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ break;
+ default:
+ if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
+ (adapter->hw.phy.media_type ==
+ e1000_media_type_internal_serdes))
+ tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+ else
+ tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+ tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+ tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ }
+
+ E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg);
+ E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value);
+ if(adapter->hw.mac.type >= e1000_82540)
+ E1000_WRITE_REG(&adapter->hw, E1000_TADV,
+ adapter->tx_abs_int_delay.value);
+
+ /* Program the Transmit Control Register */
+ tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
+ tctl &= ~E1000_TCTL_CT;
+ tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN |
+ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT));
+
+ /* This write will effectively turn on the transmit unit. */
+ E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
+
+ /* Setup Transmit Descriptor Base Settings */
+ adapter->txd_cmd = E1000_TXD_CMD_IFCS;
+
+ if (adapter->tx_int_delay.value > 0)
+ adapter->txd_cmd |= E1000_TXD_CMD_IDE;
+}
+
+/*********************************************************************
+ *
+ * Free all transmit related data structures.
+ *
+ **********************************************************************/
+static void
+lem_free_transmit_structures(struct adapter *adapter)
+{
+ struct em_buffer *tx_buffer;
+
+ INIT_DEBUGOUT("free_transmit_structures: begin");
+
+ if (adapter->tx_buffer_area != NULL) {
+ for (int i = 0; i < adapter->num_tx_desc; i++) {
+ tx_buffer = &adapter->tx_buffer_area[i];
+ if (tx_buffer->m_head != NULL) {
+ bus_dmamap_sync(adapter->txtag, tx_buffer->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(adapter->txtag,
+ tx_buffer->map);
+ m_freem(tx_buffer->m_head);
+ tx_buffer->m_head = NULL;
+ } else if (tx_buffer->map != NULL)
+ bus_dmamap_unload(adapter->txtag,
+ tx_buffer->map);
+ if (tx_buffer->map != NULL) {
+ bus_dmamap_destroy(adapter->txtag,
+ tx_buffer->map);
+ tx_buffer->map = NULL;
+ }
+ }
+ }
+ if (adapter->tx_buffer_area != NULL) {
+ free(adapter->tx_buffer_area, M_DEVBUF);
+ adapter->tx_buffer_area = NULL;
+ }
+ if (adapter->txtag != NULL) {
+ bus_dma_tag_destroy(adapter->txtag);
+ adapter->txtag = NULL;
+ }
+#if __FreeBSD_version >= 800000
+ if (adapter->br != NULL)
+ buf_ring_free(adapter->br, M_DEVBUF);
+#endif
+}
+
+/*********************************************************************
+ *
+ * The offload context needs to be set when we transfer the first
+ * packet of a particular protocol (TCP/UDP). This routine has been
+ * enhanced to deal with inserted VLAN headers, and IPV6 (not complete)
+ *
+ * Added back the old method of keeping the current context type
+ * and not setting if unnecessary, as this is reported to be a
+ * big performance win. -jfv
+ **********************************************************************/
+static void
+lem_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
+ u32 *txd_upper, u32 *txd_lower)
+{
+ struct e1000_context_desc *TXD = NULL;
+ struct em_buffer *tx_buffer;
+ struct ether_vlan_header *eh;
+ struct ip *ip = NULL;
+ struct ip6_hdr *ip6;
+ int curr_txd, ehdrlen;
+ u32 cmd, hdr_len, ip_hlen;
+ u16 etype;
+ u8 ipproto;
+
+
+ cmd = hdr_len = ipproto = 0;
+ curr_txd = adapter->next_avail_tx_desc;
+
+ /*
+ * Determine where frame payload starts.
+ * Jump over vlan headers if already present,
+ * helpful for QinQ too.
+ */
+ eh = mtod(mp, struct ether_vlan_header *);
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ etype = ntohs(eh->evl_proto);
+ ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ } else {
+ etype = ntohs(eh->evl_encap_proto);
+ ehdrlen = ETHER_HDR_LEN;
+ }
+
+ /*
+ * We only support TCP/UDP for IPv4 and IPv6 for the moment.
+ * TODO: Support SCTP too when it hits the tree.
+ */
+ switch (etype) {
+ case ETHERTYPE_IP:
+ ip = (struct ip *)(mp->m_data + ehdrlen);
+ ip_hlen = ip->ip_hl << 2;
+
+ /* Setup of IP header checksum. */
+ if (mp->m_pkthdr.csum_flags & CSUM_IP) {
+ /*
+ * Start offset for header checksum calculation.
+ * End offset for header checksum calculation.
+ * Offset of place to put the checksum.
+ */
+ TXD = (struct e1000_context_desc *)
+ &adapter->tx_desc_base[curr_txd];
+ TXD->lower_setup.ip_fields.ipcss = ehdrlen;
+ TXD->lower_setup.ip_fields.ipcse =
+ htole16(ehdrlen + ip_hlen);
+ TXD->lower_setup.ip_fields.ipcso =
+ ehdrlen + offsetof(struct ip, ip_sum);
+ cmd |= E1000_TXD_CMD_IP;
+ *txd_upper |= E1000_TXD_POPTS_IXSM << 8;
+ }
+
+ if (mp->m_len < ehdrlen + ip_hlen)
+ return; /* failure */
+
+ hdr_len = ehdrlen + ip_hlen;
+ ipproto = ip->ip_p;
+
+ break;
+ case ETHERTYPE_IPV6:
+ ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+ ip_hlen = sizeof(struct ip6_hdr); /* XXX: No header stacking. */
+
+ if (mp->m_len < ehdrlen + ip_hlen)
+ return; /* failure */
+
+ /* IPv6 doesn't have a header checksum. */
+
+ hdr_len = ehdrlen + ip_hlen;
+ ipproto = ip6->ip6_nxt;
+
+ break;
+ default:
+ *txd_upper = 0;
+ *txd_lower = 0;
+ return;
+ }
+
+ switch (ipproto) {
+ case IPPROTO_TCP:
+ if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
+ *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
+ *txd_upper |= E1000_TXD_POPTS_TXSM << 8;
+ /* no need for context if already set */
+ if (adapter->last_hw_offload == CSUM_TCP)
+ return;
+ adapter->last_hw_offload = CSUM_TCP;
+ /*
+ * Start offset for payload checksum calculation.
+ * End offset for payload checksum calculation.
+ * Offset of place to put the checksum.
+ */
+ TXD = (struct e1000_context_desc *)
+ &adapter->tx_desc_base[curr_txd];
+ TXD->upper_setup.tcp_fields.tucss = hdr_len;
+ TXD->upper_setup.tcp_fields.tucse = htole16(0);
+ TXD->upper_setup.tcp_fields.tucso =
+ hdr_len + offsetof(struct tcphdr, th_sum);
+ cmd |= E1000_TXD_CMD_TCP;
+ }
+ break;
+ case IPPROTO_UDP:
+ {
+ if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
+ *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
+ *txd_upper |= E1000_TXD_POPTS_TXSM << 8;
+ /* no need for context if already set */
+ if (adapter->last_hw_offload == CSUM_UDP)
+ return;
+ adapter->last_hw_offload = CSUM_UDP;
+ /*
+ * Start offset for header checksum calculation.
+ * End offset for header checksum calculation.
+ * Offset of place to put the checksum.
+ */
+ TXD = (struct e1000_context_desc *)
+ &adapter->tx_desc_base[curr_txd];
+ TXD->upper_setup.tcp_fields.tucss = hdr_len;
+ TXD->upper_setup.tcp_fields.tucse = htole16(0);
+ TXD->upper_setup.tcp_fields.tucso =
+ hdr_len + offsetof(struct udphdr, uh_sum);
+ }
+ /* Fall Thru */
+ }
+ default:
+ break;
+ }
+
+ TXD->tcp_seg_setup.data = htole32(0);
+ TXD->cmd_and_length =
+ htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd);
+ tx_buffer = &adapter->tx_buffer_area[curr_txd];
+ tx_buffer->m_head = NULL;
+ tx_buffer->next_eop = -1;
+
+ if (++curr_txd == adapter->num_tx_desc)
+ curr_txd = 0;
+
+ adapter->num_tx_desc_avail--;
+ adapter->next_avail_tx_desc = curr_txd;
+}
+
+
+/**********************************************************************
+ *
+ * Examine each tx_buffer in the used queue. If the hardware is done
+ * processing the packet then free associated resources. The
+ * tx_buffer is put back on the free queue.
+ *
+ **********************************************************************/
+static void
+lem_txeof(struct adapter *adapter)
+{
+ int first, last, done, num_avail;
+ struct em_buffer *tx_buffer;
+ struct e1000_tx_desc *tx_desc, *eop_desc;
+ struct ifnet *ifp = adapter->ifp;
+
+ EM_TX_LOCK_ASSERT(adapter);
+
+ if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
+ return;
+
+ num_avail = adapter->num_tx_desc_avail;
+ first = adapter->next_tx_to_clean;
+ tx_desc = &adapter->tx_desc_base[first];
+ tx_buffer = &adapter->tx_buffer_area[first];
+ last = tx_buffer->next_eop;
+ eop_desc = &adapter->tx_desc_base[last];
+
+ /*
+ * What this does is get the index of the
+ * first descriptor AFTER the EOP of the
+ * first packet, that way we can do the
+ * simple comparison on the inner while loop.
+ */
+ if (++last == adapter->num_tx_desc)
+ last = 0;
+ done = last;
+
+ bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ BUS_DMASYNC_POSTREAD);
+
+ while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) {
+ /* We clean the range of the packet */
+ while (first != done) {
+ tx_desc->upper.data = 0;
+ tx_desc->lower.data = 0;
+ tx_desc->buffer_addr = 0;
+ ++num_avail;
+
+ if (tx_buffer->m_head) {
+ ifp->if_opackets++;
+ bus_dmamap_sync(adapter->txtag,
+ tx_buffer->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(adapter->txtag,
+ tx_buffer->map);
+
+ m_freem(tx_buffer->m_head);
+ tx_buffer->m_head = NULL;
+ }
+ tx_buffer->next_eop = -1;
+ adapter->watchdog_time = ticks;
+
+ if (++first == adapter->num_tx_desc)
+ first = 0;
+
+ tx_buffer = &adapter->tx_buffer_area[first];
+ tx_desc = &adapter->tx_desc_base[first];
+ }
+ /* See if we can continue to the next packet */
+ last = tx_buffer->next_eop;
+ if (last != -1) {
+ eop_desc = &adapter->tx_desc_base[last];
+ /* Get new done point */
+ if (++last == adapter->num_tx_desc) last = 0;
+ done = last;
+ } else
+ break;
+ }
+ bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ adapter->next_tx_to_clean = first;
+
+ /*
+ * If we have enough room, clear IFF_DRV_OACTIVE to
+ * tell the stack that it is OK to send packets.
+ * If there are no pending descriptors, clear the watchdog.
+ */
+ if (num_avail > EM_TX_CLEANUP_THRESHOLD) {
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ if (num_avail == adapter->num_tx_desc) {
+ adapter->watchdog_check = FALSE;
+ adapter->num_tx_desc_avail = num_avail;
+ return;
+ }
+ }
+
+ adapter->num_tx_desc_avail = num_avail;
+ return;
+}
+
+/*********************************************************************
+ *
+ * When Link is lost sometimes there is work still in the TX ring
+ * which may result in a watchdog, rather than allow that we do an
+ * attempted cleanup and then reinit here. Note that this has been
+ * seens mostly with fiber adapters.
+ *
+ **********************************************************************/
+static void
+lem_tx_purge(struct adapter *adapter)
+{
+ if ((!adapter->link_active) && (adapter->watchdog_check)) {
+ EM_TX_LOCK(adapter);
+ lem_txeof(adapter);
+ EM_TX_UNLOCK(adapter);
+ if (adapter->watchdog_check) /* Still outstanding? */
+ lem_init_locked(adapter);
+ }
+}
+
+/*********************************************************************
+ *
+ * Get a buffer from system mbuf buffer pool.
+ *
+ **********************************************************************/
+static int
+lem_get_buf(struct adapter *adapter, int i)
+{
+ struct mbuf *m;
+ bus_dma_segment_t segs[1];
+ bus_dmamap_t map;
+ struct em_buffer *rx_buffer;
+ int error, nsegs;
+
+ m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (m == NULL) {
+ adapter->mbuf_cluster_failed++;
+ return (ENOBUFS);
+ }
+ m->m_len = m->m_pkthdr.len = MCLBYTES;
+
+ if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
+ m_adj(m, ETHER_ALIGN);
+
+ /*
+ * Using memory from the mbuf cluster pool, invoke the
+ * bus_dma machinery to arrange the memory mapping.
+ */
+ error = bus_dmamap_load_mbuf_sg(adapter->rxtag,
+ adapter->rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ m_free(m);
+ return (error);
+ }
+
+ /* If nsegs is wrong then the stack is corrupt. */
+ KASSERT(nsegs == 1, ("Too many segments returned!"));
+
+ rx_buffer = &adapter->rx_buffer_area[i];
+ if (rx_buffer->m_head != NULL)
+ bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
+
+ map = rx_buffer->map;
+ rx_buffer->map = adapter->rx_sparemap;
+ adapter->rx_sparemap = map;
+ bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
+ rx_buffer->m_head = m;
+
+ adapter->rx_desc_base[i].buffer_addr = htole64(segs[0].ds_addr);
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * Allocate memory for rx_buffer structures. Since we use one
+ * rx_buffer per received packet, the maximum number of rx_buffer's
+ * that we'll need is equal to the number of receive descriptors
+ * that we've allocated.
+ *
+ **********************************************************************/
+static int
+lem_allocate_receive_structures(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ struct em_buffer *rx_buffer;
+ int i, error;
+
+ adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) *
+ adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (adapter->rx_buffer_area == NULL) {
+ device_printf(dev, "Unable to allocate rx_buffer memory\n");
+ return (ENOMEM);
+ }
+
+#if __FreeBSD_version >= 700000
+ error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
+#else
+ error = bus_dma_tag_create(NULL, /* parent */
+#endif
+ 1, 0, /* alignment, bounds */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MCLBYTES, /* maxsize */
+ 1, /* nsegments */
+ MCLBYTES, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
+ &adapter->rxtag);
+ if (error) {
+ device_printf(dev, "%s: bus_dma_tag_create failed %d\n",
+ __func__, error);
+ goto fail;
+ }
+
+ /* Create the spare map (used by getbuf) */
+ error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
+ &adapter->rx_sparemap);
+ if (error) {
+ device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
+ __func__, error);
+ goto fail;
+ }
+
+ rx_buffer = adapter->rx_buffer_area;
+ for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
+ error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
+ &rx_buffer->map);
+ if (error) {
+ device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
+ __func__, error);
+ goto fail;
+ }
+ }
+
+ return (0);
+
+fail:
+ lem_free_receive_structures(adapter);
+ return (error);
+}
+
+/*********************************************************************
+ *
+ * (Re)initialize receive structures.
+ *
+ **********************************************************************/
+static int
+lem_setup_receive_structures(struct adapter *adapter)
+{
+ struct em_buffer *rx_buffer;
+ int i, error;
+
+ /* Reset descriptor ring */
+ bzero(adapter->rx_desc_base,
+ (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc);
+
+ /* Free current RX buffers. */
+ rx_buffer = adapter->rx_buffer_area;
+ for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
+ if (rx_buffer->m_head != NULL) {
+ bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
+ m_freem(rx_buffer->m_head);
+ rx_buffer->m_head = NULL;
+ }
+ }
+
+ /* Allocate new ones. */
+ for (i = 0; i < adapter->num_rx_desc; i++) {
+ error = lem_get_buf(adapter, i);
+ if (error)
+ return (error);
+ }
+
+ /* Setup our descriptor pointers */
+ adapter->next_rx_desc_to_check = 0;
+ bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * Enable receive unit.
+ *
+ **********************************************************************/
+#define MAX_INTS_PER_SEC 8000
+#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256)
+
+static void
+lem_initialize_receive_unit(struct adapter *adapter)
+{
+ struct ifnet *ifp = adapter->ifp;
+ u64 bus_addr;
+ u32 rctl, rxcsum;
+
+ INIT_DEBUGOUT("lem_initialize_receive_unit: begin");
+
+ /*
+ * Make sure receives are disabled while setting
+ * up the descriptor ring
+ */
+ rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
+
+ if (adapter->hw.mac.type >= e1000_82540) {
+ E1000_WRITE_REG(&adapter->hw, E1000_RADV,
+ adapter->rx_abs_int_delay.value);
+ /*
+ * Set the interrupt throttling rate. Value is calculated
+ * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
+ */
+ E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR);
+ }
+
+ /*
+ ** When using MSIX interrupts we need to throttle
+ ** using the EITR register (82574 only)
+ */
+ if (adapter->msix)
+ for (int i = 0; i < 4; i++)
+ E1000_WRITE_REG(&adapter->hw,
+ E1000_EITR_82574(i), DEFAULT_ITR);
+
+ /* Disable accelerated ackknowledge */
+ if (adapter->hw.mac.type == e1000_82574)
+ E1000_WRITE_REG(&adapter->hw,
+ E1000_RFCTL, E1000_RFCTL_ACK_DIS);
+
+ /* Setup the Base and Length of the Rx Descriptor Ring */
+ bus_addr = adapter->rxdma.dma_paddr;
+ E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0),
+ adapter->num_rx_desc * sizeof(struct e1000_rx_desc));
+ E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0),
+ (u32)(bus_addr >> 32));
+ E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0),
+ (u32)bus_addr);
+
+ /* Setup the Receive Control Register */
+ rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
+ E1000_RCTL_RDMTS_HALF |
+ (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
+
+ /* Make sure VLAN Filters are off */
+ rctl &= ~E1000_RCTL_VFE;
+
+ if (e1000_tbi_sbp_enabled_82543(&adapter->hw))
+ rctl |= E1000_RCTL_SBP;
+ else
+ rctl &= ~E1000_RCTL_SBP;
+
+ switch (adapter->rx_buffer_len) {
+ default:
+ case 2048:
+ rctl |= E1000_RCTL_SZ_2048;
+ break;
+ case 4096:
+ rctl |= E1000_RCTL_SZ_4096 |
+ E1000_RCTL_BSEX | E1000_RCTL_LPE;
+ break;
+ case 8192:
+ rctl |= E1000_RCTL_SZ_8192 |
+ E1000_RCTL_BSEX | E1000_RCTL_LPE;
+ break;
+ case 16384:
+ rctl |= E1000_RCTL_SZ_16384 |
+ E1000_RCTL_BSEX | E1000_RCTL_LPE;
+ break;
+ }
+
+ if (ifp->if_mtu > ETHERMTU)
+ rctl |= E1000_RCTL_LPE;
+ else
+ rctl &= ~E1000_RCTL_LPE;
+
+ /* Enable 82543 Receive Checksum Offload for TCP and UDP */
+ if ((adapter->hw.mac.type >= e1000_82543) &&
+ (ifp->if_capenable & IFCAP_RXCSUM)) {
+ rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM);
+ rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
+ E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum);
+ }
+
+ /* Enable Receives */
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
+
+ /*
+ * Setup the HW Rx Head and
+ * Tail Descriptor Pointers
+ */
+ E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0);
+ E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1);
+
+ return;
+}
+
+/*********************************************************************
+ *
+ * Free receive related data structures.
+ *
+ **********************************************************************/
+static void
+lem_free_receive_structures(struct adapter *adapter)
+{
+ struct em_buffer *rx_buffer;
+ int i;
+
+ INIT_DEBUGOUT("free_receive_structures: begin");
+
+ if (adapter->rx_sparemap) {
+ bus_dmamap_destroy(adapter->rxtag, adapter->rx_sparemap);
+ adapter->rx_sparemap = NULL;
+ }
+
+ /* Cleanup any existing buffers */
+ if (adapter->rx_buffer_area != NULL) {
+ rx_buffer = adapter->rx_buffer_area;
+ for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
+ if (rx_buffer->m_head != NULL) {
+ bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(adapter->rxtag,
+ rx_buffer->map);
+ m_freem(rx_buffer->m_head);
+ rx_buffer->m_head = NULL;
+ } else if (rx_buffer->map != NULL)
+ bus_dmamap_unload(adapter->rxtag,
+ rx_buffer->map);
+ if (rx_buffer->map != NULL) {
+ bus_dmamap_destroy(adapter->rxtag,
+ rx_buffer->map);
+ rx_buffer->map = NULL;
+ }
+ }
+ }
+
+ if (adapter->rx_buffer_area != NULL) {
+ free(adapter->rx_buffer_area, M_DEVBUF);
+ adapter->rx_buffer_area = NULL;
+ }
+
+ if (adapter->rxtag != NULL) {
+ bus_dma_tag_destroy(adapter->rxtag);
+ adapter->rxtag = NULL;
+ }
+}
+
+/*********************************************************************
+ *
+ * This routine executes in interrupt context. It replenishes
+ * the mbufs in the descriptor and sends data which has been
+ * dma'ed into host memory to upper layer.
+ *
+ * We loop at most count times if count is > 0, or until done if
+ * count < 0.
+ *
+ * For polling we also now return the number of cleaned packets
+ *********************************************************************/
+static int
+lem_rxeof(struct adapter *adapter, int count)
+{
+ struct ifnet *ifp = adapter->ifp;;
+ struct mbuf *mp;
+ u8 status, accept_frame = 0, eop = 0;
+ u16 len, desc_len, prev_len_adj;
+ int i, rx_sent = 0;
+ struct e1000_rx_desc *current_desc;
+
+ EM_RX_LOCK(adapter);
+ i = adapter->next_rx_desc_to_check;
+ current_desc = &adapter->rx_desc_base[i];
+ bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
+ BUS_DMASYNC_POSTREAD);
+
+ if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
+ EM_RX_UNLOCK(adapter);
+ return (rx_sent);
+ }
+
+ while ((current_desc->status & E1000_RXD_STAT_DD) &&
+ (count != 0) &&
+ (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ struct mbuf *m = NULL;
+
+ mp = adapter->rx_buffer_area[i].m_head;
+ /*
+ * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT
+ * needs to access the last received byte in the mbuf.
+ */
+ bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
+ BUS_DMASYNC_POSTREAD);
+
+ accept_frame = 1;
+ prev_len_adj = 0;
+ desc_len = le16toh(current_desc->length);
+ status = current_desc->status;
+ if (status & E1000_RXD_STAT_EOP) {
+ count--;
+ eop = 1;
+ if (desc_len < ETHER_CRC_LEN) {
+ len = 0;
+ prev_len_adj = ETHER_CRC_LEN - desc_len;
+ } else
+ len = desc_len - ETHER_CRC_LEN;
+ } else {
+ eop = 0;
+ len = desc_len;
+ }
+
+ if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
+ u8 last_byte;
+ u32 pkt_len = desc_len;
+
+ if (adapter->fmp != NULL)
+ pkt_len += adapter->fmp->m_pkthdr.len;
+
+ last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
+ if (TBI_ACCEPT(&adapter->hw, status,
+ current_desc->errors, pkt_len, last_byte,
+ adapter->min_frame_size, adapter->max_frame_size)) {
+ e1000_tbi_adjust_stats_82543(&adapter->hw,
+ &adapter->stats, pkt_len,
+ adapter->hw.mac.addr,
+ adapter->max_frame_size);
+ if (len > 0)
+ len--;
+ } else
+ accept_frame = 0;
+ }
+
+ if (accept_frame) {
+ if (lem_get_buf(adapter, i) != 0) {
+ ifp->if_iqdrops++;
+ goto discard;
+ }
+
+ /* Assign correct length to the current fragment */
+ mp->m_len = len;
+
+ if (adapter->fmp == NULL) {
+ mp->m_pkthdr.len = len;
+ adapter->fmp = mp; /* Store the first mbuf */
+ adapter->lmp = mp;
+ } else {
+ /* Chain mbuf's together */
+ mp->m_flags &= ~M_PKTHDR;
+ /*
+ * Adjust length of previous mbuf in chain if
+ * we received less than 4 bytes in the last
+ * descriptor.
+ */
+ if (prev_len_adj > 0) {
+ adapter->lmp->m_len -= prev_len_adj;
+ adapter->fmp->m_pkthdr.len -=
+ prev_len_adj;
+ }
+ adapter->lmp->m_next = mp;
+ adapter->lmp = adapter->lmp->m_next;
+ adapter->fmp->m_pkthdr.len += len;
+ }
+
+ if (eop) {
+ adapter->fmp->m_pkthdr.rcvif = ifp;
+ ifp->if_ipackets++;
+ lem_receive_checksum(adapter, current_desc,
+ adapter->fmp);
+#ifndef __NO_STRICT_ALIGNMENT
+ if (adapter->max_frame_size >
+ (MCLBYTES - ETHER_ALIGN) &&
+ lem_fixup_rx(adapter) != 0)
+ goto skip;
+#endif
+ if (status & E1000_RXD_STAT_VP) {
+#if __FreeBSD_version < 700000
+ VLAN_INPUT_TAG_NEW(ifp, adapter->fmp,
+ (le16toh(current_desc->special) &
+ E1000_RXD_SPC_VLAN_MASK));
+#else
+ adapter->fmp->m_pkthdr.ether_vtag =
+ (le16toh(current_desc->special) &
+ E1000_RXD_SPC_VLAN_MASK);
+ adapter->fmp->m_flags |= M_VLANTAG;
+#endif
+ }
+#ifndef __NO_STRICT_ALIGNMENT
+skip:
+#endif
+ m = adapter->fmp;
+ adapter->fmp = NULL;
+ adapter->lmp = NULL;
+ }
+ } else {
+ ifp->if_ierrors++;
+discard:
+ /* Reuse loaded DMA map and just update mbuf chain */
+ mp = adapter->rx_buffer_area[i].m_head;
+ mp->m_len = mp->m_pkthdr.len = MCLBYTES;
+ mp->m_data = mp->m_ext.ext_buf;
+ mp->m_next = NULL;
+ if (adapter->max_frame_size <=
+ (MCLBYTES - ETHER_ALIGN))
+ m_adj(mp, ETHER_ALIGN);
+ if (adapter->fmp != NULL) {
+ m_freem(adapter->fmp);
+ adapter->fmp = NULL;
+ adapter->lmp = NULL;
+ }
+ m = NULL;
+ }
+
+ /* Zero out the receive descriptors status. */
+ current_desc->status = 0;
+ bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ /* Advance our pointers to the next descriptor. */
+ if (++i == adapter->num_rx_desc)
+ i = 0;
+ /* Call into the stack */
+ if (m != NULL) {
+ adapter->next_rx_desc_to_check = i;
+ EM_RX_UNLOCK(adapter);
+ (*ifp->if_input)(ifp, m);
+ EM_RX_LOCK(adapter);
+ rx_sent++;
+ i = adapter->next_rx_desc_to_check;
+ }
+ current_desc = &adapter->rx_desc_base[i];
+ }
+ adapter->next_rx_desc_to_check = i;
+
+ /* Advance the E1000's Receive Queue #0 "Tail Pointer". */
+ if (--i < 0)
+ i = adapter->num_rx_desc - 1;
+ E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
+ EM_RX_UNLOCK(adapter);
+ return (rx_sent);
+}
+
+#ifndef __NO_STRICT_ALIGNMENT
+/*
+ * When jumbo frames are enabled we should realign entire payload on
+ * architecures with strict alignment. This is serious design mistake of 8254x
+ * as it nullifies DMA operations. 8254x just allows RX buffer size to be
+ * 2048/4096/8192/16384. What we really want is 2048 - ETHER_ALIGN to align its
+ * payload. On architecures without strict alignment restrictions 8254x still
+ * performs unaligned memory access which would reduce the performance too.
+ * To avoid copying over an entire frame to align, we allocate a new mbuf and
+ * copy ethernet header to the new mbuf. The new mbuf is prepended into the
+ * existing mbuf chain.
+ *
+ * Be aware, best performance of the 8254x is achived only when jumbo frame is
+ * not used at all on architectures with strict alignment.
+ */
+static int
+lem_fixup_rx(struct adapter *adapter)
+{
+ struct mbuf *m, *n;
+ int error;
+
+ error = 0;
+ m = adapter->fmp;
+ if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN)) {
+ bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len);
+ m->m_data += ETHER_HDR_LEN;
+ } else {
+ MGETHDR(n, M_DONTWAIT, MT_DATA);
+ if (n != NULL) {
+ bcopy(m->m_data, n->m_data, ETHER_HDR_LEN);
+ m->m_data += ETHER_HDR_LEN;
+ m->m_len -= ETHER_HDR_LEN;
+ n->m_len = ETHER_HDR_LEN;
+ M_MOVE_PKTHDR(n, m);
+ n->m_next = m;
+ adapter->fmp = n;
+ } else {
+ adapter->dropped_pkts++;
+ m_freem(adapter->fmp);
+ adapter->fmp = NULL;
+ error = ENOMEM;
+ }
+ }
+
+ return (error);
+}
+#endif
+
+/*********************************************************************
+ *
+ * Verify that the hardware indicated that the checksum is valid.
+ * Inform the stack about the status of checksum so that stack
+ * doesn't spend time verifying the checksum.
+ *
+ *********************************************************************/
+static void
+lem_receive_checksum(struct adapter *adapter,
+ struct e1000_rx_desc *rx_desc, struct mbuf *mp)
+{
+ /* 82543 or newer only */
+ if ((adapter->hw.mac.type < e1000_82543) ||
+ /* Ignore Checksum bit is set */
+ (rx_desc->status & E1000_RXD_STAT_IXSM)) {
+ mp->m_pkthdr.csum_flags = 0;
+ return;
+ }
+
+ if (rx_desc->status & E1000_RXD_STAT_IPCS) {
+ /* Did it pass? */
+ if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) {
+ /* IP Checksum Good */
+ mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
+ mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+
+ } else {
+ mp->m_pkthdr.csum_flags = 0;
+ }
+ }
+
+ if (rx_desc->status & E1000_RXD_STAT_TCPCS) {
+ /* Did it pass? */
+ if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) {
+ mp->m_pkthdr.csum_flags |=
+ (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ mp->m_pkthdr.csum_data = htons(0xffff);
+ }
+ }
+}
+
+#if __FreeBSD_version >= 700029
+/*
+ * This routine is run via an vlan
+ * config EVENT
+ */
+static void
+lem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
+{
+ struct adapter *adapter = ifp->if_softc;
+ u32 index, bit;
+
+ if (ifp->if_softc != arg) /* Not our event */
+ return;
+
+ if ((vtag == 0) || (vtag > 4095)) /* Invalid ID */
+ return;
+
+ index = (vtag >> 5) & 0x7F;
+ bit = vtag & 0x1F;
+ lem_shadow_vfta[index] |= (1 << bit);
+ ++adapter->num_vlans;
+ /* Re-init to load the changes */
+ lem_init(adapter);
+}
+
+/*
+ * This routine is run via an vlan
+ * unconfig EVENT
+ */
+static void
+lem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
+{
+ struct adapter *adapter = ifp->if_softc;
+ u32 index, bit;
+
+ if (ifp->if_softc != arg)
+ return;
+
+ if ((vtag == 0) || (vtag > 4095)) /* Invalid */
+ return;
+
+ index = (vtag >> 5) & 0x7F;
+ bit = vtag & 0x1F;
+ lem_shadow_vfta[index] &= ~(1 << bit);
+ --adapter->num_vlans;
+ /* Re-init to load the changes */
+ lem_init(adapter);
+}
+
+static void
+lem_setup_vlan_hw_support(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 reg;
+
+ /*
+ ** We get here thru init_locked, meaning
+ ** a soft reset, this has already cleared
+ ** the VFTA and other state, so if there
+ ** have been no vlan's registered do nothing.
+ */
+ if (adapter->num_vlans == 0)
+ return;
+
+ /*
+ ** A soft reset zero's out the VFTA, so
+ ** we need to repopulate it now.
+ */
+ for (int i = 0; i < EM_VFTA_SIZE; i++)
+ if (lem_shadow_vfta[i] != 0)
+ E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
+ i, lem_shadow_vfta[i]);
+
+ reg = E1000_READ_REG(hw, E1000_CTRL);
+ reg |= E1000_CTRL_VME;
+ E1000_WRITE_REG(hw, E1000_CTRL, reg);
+
+ /* Enable the Filter Table */
+ reg = E1000_READ_REG(hw, E1000_RCTL);
+ reg &= ~E1000_RCTL_CFIEN;
+ reg |= E1000_RCTL_VFE;
+ E1000_WRITE_REG(hw, E1000_RCTL, reg);
+
+ /* Update the frame size */
+ E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
+ adapter->max_frame_size + VLAN_TAG_SIZE);
+}
+#endif
+
+static void
+lem_enable_intr(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ims_mask = IMS_ENABLE_MASK;
+
+ if (adapter->msix) {
+ E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
+ ims_mask |= EM_MSIX_MASK;
+ }
+ E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
+}
+
+static void
+lem_disable_intr(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (adapter->msix)
+ E1000_WRITE_REG(hw, EM_EIAC, 0);
+ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
+}
+
+/*
+ * Bit of a misnomer, what this really means is
+ * to enable OS management of the system... aka
+ * to disable special hardware management features
+ */
+static void
+lem_init_manageability(struct adapter *adapter)
+{
+ /* A shared code workaround */
+ if (adapter->has_manage) {
+ int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
+ /* disable hardware interception of ARP */
+ manc &= ~(E1000_MANC_ARP_EN);
+ E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
+ }
+}
+
+/*
+ * Give control back to hardware management
+ * controller if there is one.
+ */
+static void
+lem_release_manageability(struct adapter *adapter)
+{
+ if (adapter->has_manage) {
+ int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
+
+ /* re-enable hardware interception of ARP */
+ manc |= E1000_MANC_ARP_EN;
+ E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
+ }
+}
+
+/*
+ * lem_get_hw_control sets the {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * For ASF and Pass Through versions of f/w this means
+ * that the driver is loaded. For AMT version type f/w
+ * this means that the network i/f is open.
+ */
+static void
+lem_get_hw_control(struct adapter *adapter)
+{
+ u32 ctrl_ext;
+
+ ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+ return;
+}
+
+/*
+ * lem_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * For ASF and Pass Through versions of f/w this means that
+ * the driver is no longer loaded. For AMT versions of the
+ * f/w this means that the network i/f is closed.
+ */
+static void
+lem_release_hw_control(struct adapter *adapter)
+{
+ u32 ctrl_ext;
+
+ if (!adapter->has_manage)
+ return;
+
+ ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+ return;
+}
+
+static int
+lem_is_valid_ether_addr(u8 *addr)
+{
+ char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
+
+ if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+/*
+** Parse the interface capabilities with regard
+** to both system management and wake-on-lan for
+** later use.
+*/
+static void
+lem_get_wakeup(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+ u16 eeprom_data = 0, device_id, apme_mask;
+
+ adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw);
+ apme_mask = EM_EEPROM_APME;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_82542:
+ case e1000_82543:
+ break;
+ case e1000_82544:
+ e1000_read_nvm(&adapter->hw,
+ NVM_INIT_CONTROL2_REG, 1, &eeprom_data);
+ apme_mask = EM_82544_APME;
+ break;
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ if (adapter->hw.bus.func == 1) {
+ e1000_read_nvm(&adapter->hw,
+ NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
+ break;
+ } else
+ e1000_read_nvm(&adapter->hw,
+ NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+ break;
+ default:
+ e1000_read_nvm(&adapter->hw,
+ NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+ break;
+ }
+ if (eeprom_data & apme_mask)
+ adapter->wol = (E1000_WUFC_MAG | E1000_WUFC_MC);
+ /*
+ * We have the eeprom settings, now apply the special cases
+ * where the eeprom may be wrong or the board won't support
+ * wake on lan on a particular port
+ */
+ device_id = pci_get_device(dev);
+ switch (device_id) {
+ case E1000_DEV_ID_82546GB_PCIE:
+ adapter->wol = 0;
+ break;
+ case E1000_DEV_ID_82546EB_FIBER:
+ case E1000_DEV_ID_82546GB_FIBER:
+ /* Wake events only supported on port A for dual fiber
+ * regardless of eeprom setting */
+ if (E1000_READ_REG(&adapter->hw, E1000_STATUS) &
+ E1000_STATUS_FUNC_1)
+ adapter->wol = 0;
+ break;
+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
+ /* if quad port adapter, disable WoL on all but port A */
+ if (global_quad_port_a != 0)
+ adapter->wol = 0;
+ /* Reset for multiple quad port adapters */
+ if (++global_quad_port_a == 4)
+ global_quad_port_a = 0;
+ break;
+ }
+ return;
+}
+
+
+/*
+ * Enable PCI Wake On Lan capability
+ */
+static void
+lem_enable_wakeup(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+ struct ifnet *ifp = adapter->ifp;
+ u32 pmc, ctrl, ctrl_ext, rctl;
+ u16 status;
+
+ if ((pci_find_extcap(dev, PCIY_PMG, &pmc) != 0))
+ return;
+
+ /* Advertise the wakeup capability */
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+ E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
+
+ /* Keep the laser running on Fiber adapters */
+ if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
+ adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
+ ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
+ }
+
+ /*
+ ** Determine type of Wakeup: note that wol
+ ** is set with all bits on by default.
+ */
+ if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0)
+ adapter->wol &= ~E1000_WUFC_MAG;
+
+ if ((ifp->if_capenable & IFCAP_WOL_MCAST) == 0)
+ adapter->wol &= ~E1000_WUFC_MC;
+ else {
+ rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+ rctl |= E1000_RCTL_MPE;
+ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
+ }
+
+ if (adapter->hw.mac.type == e1000_pchlan) {
+ if (lem_enable_phy_wakeup(adapter))
+ return;
+ } else {
+ E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
+ E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol);
+ }
+
+
+ /* Request PME */
+ status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2);
+ status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
+ if (ifp->if_capenable & IFCAP_WOL)
+ status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
+ pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2);
+
+ return;
+}
+
+/*
+** WOL in the newer chipset interfaces (pchlan)
+** require thing to be copied into the phy
+*/
+static int
+lem_enable_phy_wakeup(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 mreg, ret = 0;
+ u16 preg;
+
+ /* copy MAC RARs to PHY RARs */
+ for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
+ mreg = E1000_READ_REG(hw, E1000_RAL(i));
+ e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF));
+ e1000_write_phy_reg(hw, BM_RAR_M(i),
+ (u16)((mreg >> 16) & 0xFFFF));
+ mreg = E1000_READ_REG(hw, E1000_RAH(i));
+ e1000_write_phy_reg(hw, BM_RAR_H(i), (u16)(mreg & 0xFFFF));
+ e1000_write_phy_reg(hw, BM_RAR_CTRL(i),
+ (u16)((mreg >> 16) & 0xFFFF));
+ }
+
+ /* copy MAC MTA to PHY MTA */
+ for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
+ mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
+ e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
+ e1000_write_phy_reg(hw, BM_MTA(i) + 1,
+ (u16)((mreg >> 16) & 0xFFFF));
+ }
+
+ /* configure PHY Rx Control register */
+ e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg);
+ mreg = E1000_READ_REG(hw, E1000_RCTL);
+ if (mreg & E1000_RCTL_UPE)
+ preg |= BM_RCTL_UPE;
+ if (mreg & E1000_RCTL_MPE)
+ preg |= BM_RCTL_MPE;
+ preg &= ~(BM_RCTL_MO_MASK);
+ if (mreg & E1000_RCTL_MO_3)
+ preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
+ << BM_RCTL_MO_SHIFT);
+ if (mreg & E1000_RCTL_BAM)
+ preg |= BM_RCTL_BAM;
+ if (mreg & E1000_RCTL_PMCF)
+ preg |= BM_RCTL_PMCF;
+ mreg = E1000_READ_REG(hw, E1000_CTRL);
+ if (mreg & E1000_CTRL_RFCE)
+ preg |= BM_RCTL_RFCE;
+ e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg);
+
+ /* enable PHY wakeup in MAC register */
+ E1000_WRITE_REG(hw, E1000_WUC,
+ E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
+ E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol);
+
+ /* configure and enable PHY wakeup in PHY registers */
+ e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol);
+ e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
+
+ /* activate PHY wakeup */
+ ret = hw->phy.ops.acquire(hw);
+ if (ret) {
+ printf("Could not acquire PHY\n");
+ return ret;
+ }
+ e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+ (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+ ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg);
+ if (ret) {
+ printf("Could not read PHY page 769\n");
+ goto out;
+ }
+ preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
+ ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg);
+ if (ret)
+ printf("Could not set PHY Host Wakeup bit\n");
+out:
+ hw->phy.ops.release(hw);
+
+ return ret;
+}
+
+static void
+lem_led_func(void *arg, int onoff)
+{
+ struct adapter *adapter = arg;
+
+ EM_CORE_LOCK(adapter);
+ if (onoff) {
+ e1000_setup_led(&adapter->hw);
+ e1000_led_on(&adapter->hw);
+ } else {
+ e1000_led_off(&adapter->hw);
+ e1000_cleanup_led(&adapter->hw);
+ }
+ EM_CORE_UNLOCK(adapter);
+}
+
+/*********************************************************************
+* 82544 Coexistence issue workaround.
+* There are 2 issues.
+* 1. Transmit Hang issue.
+* To detect this issue, following equation can be used...
+* SIZE[3:0] + ADDR[2:0] = SUM[3:0].
+* If SUM[3:0] is in between 1 to 4, we will have this issue.
+*
+* 2. DAC issue.
+* To detect this issue, following equation can be used...
+* SIZE[3:0] + ADDR[2:0] = SUM[3:0].
+* If SUM[3:0] is in between 9 to c, we will have this issue.
+*
+*
+* WORKAROUND:
+* Make sure we do not have ending address
+* as 1,2,3,4(Hang) or 9,a,b,c (DAC)
+*
+*************************************************************************/
+static u32
+lem_fill_descriptors (bus_addr_t address, u32 length,
+ PDESC_ARRAY desc_array)
+{
+ u32 safe_terminator;
+
+ /* Since issue is sensitive to length and address.*/
+ /* Let us first check the address...*/
+ if (length <= 4) {
+ desc_array->descriptor[0].address = address;
+ desc_array->descriptor[0].length = length;
+ desc_array->elements = 1;
+ return (desc_array->elements);
+ }
+ safe_terminator = (u32)((((u32)address & 0x7) +
+ (length & 0xF)) & 0xF);
+ /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */
+ if (safe_terminator == 0 ||
+ (safe_terminator > 4 &&
+ safe_terminator < 9) ||
+ (safe_terminator > 0xC &&
+ safe_terminator <= 0xF)) {
+ desc_array->descriptor[0].address = address;
+ desc_array->descriptor[0].length = length;
+ desc_array->elements = 1;
+ return (desc_array->elements);
+ }
+
+ desc_array->descriptor[0].address = address;
+ desc_array->descriptor[0].length = length - 4;
+ desc_array->descriptor[1].address = address + (length - 4);
+ desc_array->descriptor[1].length = 4;
+ desc_array->elements = 2;
+ return (desc_array->elements);
+}
+
+/**********************************************************************
+ *
+ * Update the board statistics counters.
+ *
+ **********************************************************************/
+static void
+lem_update_stats_counters(struct adapter *adapter)
+{
+ struct ifnet *ifp;
+
+ if(adapter->hw.phy.media_type == e1000_media_type_copper ||
+ (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
+ adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
+ adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
+ }
+ adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
+ adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
+ adapter->stats.scc += E1000_READ_REG(&adapter->hw, E1000_SCC);
+ adapter->stats.ecol += E1000_READ_REG(&adapter->hw, E1000_ECOL);
+
+ adapter->stats.mcc += E1000_READ_REG(&adapter->hw, E1000_MCC);
+ adapter->stats.latecol += E1000_READ_REG(&adapter->hw, E1000_LATECOL);
+ adapter->stats.colc += E1000_READ_REG(&adapter->hw, E1000_COLC);
+ adapter->stats.dc += E1000_READ_REG(&adapter->hw, E1000_DC);
+ adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC);
+ adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC);
+ adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC);
+ adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
+ adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
+ adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
+ adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
+ adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, E1000_PRC127);
+ adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, E1000_PRC255);
+ adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, E1000_PRC511);
+ adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, E1000_PRC1023);
+ adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, E1000_PRC1522);
+ adapter->stats.gprc += E1000_READ_REG(&adapter->hw, E1000_GPRC);
+ adapter->stats.bprc += E1000_READ_REG(&adapter->hw, E1000_BPRC);
+ adapter->stats.mprc += E1000_READ_REG(&adapter->hw, E1000_MPRC);
+ adapter->stats.gptc += E1000_READ_REG(&adapter->hw, E1000_GPTC);
+
+ /* For the 64-bit byte counters the low dword must be read first. */
+ /* Both registers clear on the read of the high dword */
+
+ adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCH);
+ adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCH);
+
+ adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC);
+ adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC);
+ adapter->stats.rfc += E1000_READ_REG(&adapter->hw, E1000_RFC);
+ adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC);
+ adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC);
+
+ adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH);
+ adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH);
+
+ adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR);
+ adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT);
+ adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, E1000_PTC64);
+ adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, E1000_PTC127);
+ adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, E1000_PTC255);
+ adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, E1000_PTC511);
+ adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, E1000_PTC1023);
+ adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, E1000_PTC1522);
+ adapter->stats.mptc += E1000_READ_REG(&adapter->hw, E1000_MPTC);
+ adapter->stats.bptc += E1000_READ_REG(&adapter->hw, E1000_BPTC);
+
+ if (adapter->hw.mac.type >= e1000_82543) {
+ adapter->stats.algnerrc +=
+ E1000_READ_REG(&adapter->hw, E1000_ALGNERRC);
+ adapter->stats.rxerrc +=
+ E1000_READ_REG(&adapter->hw, E1000_RXERRC);
+ adapter->stats.tncrs +=
+ E1000_READ_REG(&adapter->hw, E1000_TNCRS);
+ adapter->stats.cexterr +=
+ E1000_READ_REG(&adapter->hw, E1000_CEXTERR);
+ adapter->stats.tsctc +=
+ E1000_READ_REG(&adapter->hw, E1000_TSCTC);
+ adapter->stats.tsctfc +=
+ E1000_READ_REG(&adapter->hw, E1000_TSCTFC);
+ }
+ ifp = adapter->ifp;
+
+ ifp->if_collisions = adapter->stats.colc;
+
+ /* Rx Errors */
+ ifp->if_ierrors = adapter->dropped_pkts + adapter->stats.rxerrc +
+ adapter->stats.crcerrs + adapter->stats.algnerrc +
+ adapter->stats.ruc + adapter->stats.roc +
+ adapter->stats.mpc + adapter->stats.cexterr;
+
+ /* Tx Errors */
+ ifp->if_oerrors = adapter->stats.ecol +
+ adapter->stats.latecol + adapter->watchdog_events;
+}
+
+
+/**********************************************************************
+ *
+ * This routine is called only when lem_display_debug_stats is enabled.
+ * This routine provides a way to take a look at important statistics
+ * maintained by the driver and hardware.
+ *
+ **********************************************************************/
+static void
+lem_print_debug_info(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ u8 *hw_addr = adapter->hw.hw_addr;
+
+ device_printf(dev, "Adapter hardware address = %p \n", hw_addr);
+ device_printf(dev, "CTRL = 0x%x RCTL = 0x%x \n",
+ E1000_READ_REG(&adapter->hw, E1000_CTRL),
+ E1000_READ_REG(&adapter->hw, E1000_RCTL));
+ device_printf(dev, "Packet buffer = Tx=%dk Rx=%dk \n",
+ ((E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff0000) >> 16),\
+ (E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff) );
+ device_printf(dev, "Flow control watermarks high = %d low = %d\n",
+ adapter->hw.fc.high_water,
+ adapter->hw.fc.low_water);
+ device_printf(dev, "tx_int_delay = %d, tx_abs_int_delay = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_TIDV),
+ E1000_READ_REG(&adapter->hw, E1000_TADV));
+ device_printf(dev, "rx_int_delay = %d, rx_abs_int_delay = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_RDTR),
+ E1000_READ_REG(&adapter->hw, E1000_RADV));
+ device_printf(dev, "fifo workaround = %lld, fifo_reset_count = %lld\n",
+ (long long)adapter->tx_fifo_wrk_cnt,
+ (long long)adapter->tx_fifo_reset_cnt);
+ device_printf(dev, "hw tdh = %d, hw tdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_TDH(0)),
+ E1000_READ_REG(&adapter->hw, E1000_TDT(0)));
+ device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_RDH(0)),
+ E1000_READ_REG(&adapter->hw, E1000_RDT(0)));
+ device_printf(dev, "Num Tx descriptors avail = %d\n",
+ adapter->num_tx_desc_avail);
+ device_printf(dev, "Tx Descriptors not avail1 = %ld\n",
+ adapter->no_tx_desc_avail1);
+ device_printf(dev, "Tx Descriptors not avail2 = %ld\n",
+ adapter->no_tx_desc_avail2);
+ device_printf(dev, "Std mbuf failed = %ld\n",
+ adapter->mbuf_alloc_failed);
+ device_printf(dev, "Std mbuf cluster failed = %ld\n",
+ adapter->mbuf_cluster_failed);
+ device_printf(dev, "Driver dropped packets = %ld\n",
+ adapter->dropped_pkts);
+ device_printf(dev, "Driver tx dma failure in encap = %ld\n",
+ adapter->no_tx_dma_setup);
+}
+
+static void
+lem_print_hw_stats(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+
+ device_printf(dev, "Excessive collisions = %lld\n",
+ (long long)adapter->stats.ecol);
+#if (DEBUG_HW > 0) /* Dont output these errors normally */
+ device_printf(dev, "Symbol errors = %lld\n",
+ (long long)adapter->stats.symerrs);
+#endif
+ device_printf(dev, "Sequence errors = %lld\n",
+ (long long)adapter->stats.sec);
+ device_printf(dev, "Defer count = %lld\n",
+ (long long)adapter->stats.dc);
+ device_printf(dev, "Missed Packets = %lld\n",
+ (long long)adapter->stats.mpc);
+ device_printf(dev, "Receive No Buffers = %lld\n",
+ (long long)adapter->stats.rnbc);
+ /* RLEC is inaccurate on some hardware, calculate our own. */
+ device_printf(dev, "Receive Length Errors = %lld\n",
+ ((long long)adapter->stats.roc + (long long)adapter->stats.ruc));
+ device_printf(dev, "Receive errors = %lld\n",
+ (long long)adapter->stats.rxerrc);
+ device_printf(dev, "Crc errors = %lld\n",
+ (long long)adapter->stats.crcerrs);
+ device_printf(dev, "Alignment errors = %lld\n",
+ (long long)adapter->stats.algnerrc);
+ device_printf(dev, "Collision/Carrier extension errors = %lld\n",
+ (long long)adapter->stats.cexterr);
+ device_printf(dev, "RX overruns = %ld\n", adapter->rx_overruns);
+ device_printf(dev, "watchdog timeouts = %ld\n",
+ adapter->watchdog_events);
+ device_printf(dev, "RX MSIX IRQ = %ld TX MSIX IRQ = %ld"
+ " LINK MSIX IRQ = %ld\n", adapter->rx_irq,
+ adapter->tx_irq , adapter->link_irq);
+ device_printf(dev, "XON Rcvd = %lld\n",
+ (long long)adapter->stats.xonrxc);
+ device_printf(dev, "XON Xmtd = %lld\n",
+ (long long)adapter->stats.xontxc);
+ device_printf(dev, "XOFF Rcvd = %lld\n",
+ (long long)adapter->stats.xoffrxc);
+ device_printf(dev, "XOFF Xmtd = %lld\n",
+ (long long)adapter->stats.xofftxc);
+ device_printf(dev, "Good Packets Rcvd = %lld\n",
+ (long long)adapter->stats.gprc);
+ device_printf(dev, "Good Packets Xmtd = %lld\n",
+ (long long)adapter->stats.gptc);
+}
+
+/**********************************************************************
+ *
+ * This routine provides a way to dump out the adapter eeprom,
+ * often a useful debug/service tool. This only dumps the first
+ * 32 words, stuff that matters is in that extent.
+ *
+ **********************************************************************/
+static void
+lem_print_nvm_info(struct adapter *adapter)
+{
+ u16 eeprom_data;
+ int i, j, row = 0;
+
+ /* Its a bit crude, but it gets the job done */
+ printf("\nInterface EEPROM Dump:\n");
+ printf("Offset\n0x0000 ");
+ for (i = 0, j = 0; i < 32; i++, j++) {
+ if (j == 8) { /* Make the offset block */
+ j = 0; ++row;
+ printf("\n0x00%x0 ",row);
+ }
+ e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
+ printf("%04x ", eeprom_data);
+ }
+ printf("\n");
+}
+
+static int
+lem_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter;
+ int error;
+ int result;
+
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (result == 1) {
+ adapter = (struct adapter *)arg1;
+ lem_print_debug_info(adapter);
+ }
+ /*
+ * This value will cause a hex dump of the
+ * first 32 16-bit words of the EEPROM to
+ * the screen.
+ */
+ if (result == 2) {
+ adapter = (struct adapter *)arg1;
+ lem_print_nvm_info(adapter);
+ }
+
+ return (error);
+}
+
+
+static int
+lem_sysctl_stats(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter;
+ int error;
+ int result;
+
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (result == 1) {
+ adapter = (struct adapter *)arg1;
+ lem_print_hw_stats(adapter);
+ }
+
+ return (error);
+}
+
+static int
+lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
+{
+ struct em_int_delay_info *info;
+ struct adapter *adapter;
+ u32 regval;
+ int error;
+ int usecs;
+ int ticks;
+
+ info = (struct em_int_delay_info *)arg1;
+ usecs = info->value;
+ error = sysctl_handle_int(oidp, &usecs, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (usecs < 0 || usecs > EM_TICKS_TO_USECS(65535))
+ return (EINVAL);
+ info->value = usecs;
+ ticks = EM_USECS_TO_TICKS(usecs);
+
+ adapter = info->adapter;
+
+ EM_CORE_LOCK(adapter);
+ regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
+ regval = (regval & ~0xffff) | (ticks & 0xffff);
+ /* Handle a few special cases. */
+ switch (info->offset) {
+ case E1000_RDTR:
+ break;
+ case E1000_TIDV:
+ if (ticks == 0) {
+ adapter->txd_cmd &= ~E1000_TXD_CMD_IDE;
+ /* Don't write 0 into the TIDV register. */
+ regval++;
+ } else
+ adapter->txd_cmd |= E1000_TXD_CMD_IDE;
+ break;
+ }
+ E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
+ EM_CORE_UNLOCK(adapter);
+ return (0);
+}
+
+static void
+lem_add_int_delay_sysctl(struct adapter *adapter, const char *name,
+ const char *description, struct em_int_delay_info *info,
+ int offset, int value)
+{
+ info->adapter = adapter;
+ info->offset = offset;
+ info->value = value;
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(adapter->dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
+ OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW,
+ info, 0, lem_sysctl_int_delay, "I", description);
+}
+
+#ifndef EM_LEGACY_IRQ
+static void
+lem_add_rx_process_limit(struct adapter *adapter, const char *name,
+ const char *description, int *limit, int value)
+{
+ *limit = value;
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
+ OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+}
+#endif
+
+
diff --git a/sys/dev/e1000/if_lem.h b/sys/dev/e1000/if_lem.h
new file mode 100644
index 0000000..13c2cbc
--- /dev/null
+++ b/sys/dev/e1000/if_lem.h
@@ -0,0 +1,481 @@
+/******************************************************************************
+
+ Copyright (c) 2001-2010, Intel Corporation
+ 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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _LEM_H_DEFINED_
+#define _LEM_H_DEFINED_
+
+
+/* Tunables */
+
+/*
+ * EM_TXD: Maximum number of Transmit Descriptors
+ * Valid Range: 80-256 for 82542 and 82543-based adapters
+ * 80-4096 for others
+ * Default Value: 256
+ * This value is the number of transmit descriptors allocated by the driver.
+ * Increasing this value allows the driver to queue more transmits. Each
+ * descriptor is 16 bytes.
+ * Since TDLEN should be multiple of 128bytes, the number of transmit
+ * desscriptors should meet the following condition.
+ * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
+ */
+#define EM_MIN_TXD 80
+#define EM_MAX_TXD_82543 256
+#define EM_MAX_TXD 4096
+#define EM_DEFAULT_TXD EM_MAX_TXD_82543
+
+/*
+ * EM_RXD - Maximum number of receive Descriptors
+ * Valid Range: 80-256 for 82542 and 82543-based adapters
+ * 80-4096 for others
+ * Default Value: 256
+ * This value is the number of receive descriptors allocated by the driver.
+ * Increasing this value allows the driver to buffer more incoming packets.
+ * Each descriptor is 16 bytes. A receive buffer is also allocated for each
+ * descriptor. The maximum MTU size is 16110.
+ * Since TDLEN should be multiple of 128bytes, the number of transmit
+ * desscriptors should meet the following condition.
+ * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
+ */
+#define EM_MIN_RXD 80
+#define EM_MAX_RXD_82543 256
+#define EM_MAX_RXD 4096
+#define EM_DEFAULT_RXD EM_MAX_RXD_82543
+
+/*
+ * EM_TIDV - Transmit Interrupt Delay Value
+ * Valid Range: 0-65535 (0=off)
+ * Default Value: 64
+ * This value delays the generation of transmit interrupts in units of
+ * 1.024 microseconds. Transmit interrupt reduction can improve CPU
+ * efficiency if properly tuned for specific network traffic. If the
+ * system is reporting dropped transmits, this value may be set too high
+ * causing the driver to run out of available transmit descriptors.
+ */
+#define EM_TIDV 64
+
+/*
+ * EM_TADV - Transmit Absolute Interrupt Delay Value
+ * (Not valid for 82542/82543/82544)
+ * Valid Range: 0-65535 (0=off)
+ * Default Value: 64
+ * This value, in units of 1.024 microseconds, limits the delay in which a
+ * transmit interrupt is generated. Useful only if EM_TIDV is non-zero,
+ * this value ensures that an interrupt is generated after the initial
+ * packet is sent on the wire within the set amount of time. Proper tuning,
+ * along with EM_TIDV, may improve traffic throughput in specific
+ * network conditions.
+ */
+#define EM_TADV 64
+
+/*
+ * EM_RDTR - Receive Interrupt Delay Timer (Packet Timer)
+ * Valid Range: 0-65535 (0=off)
+ * Default Value: 0
+ * This value delays the generation of receive interrupts in units of 1.024
+ * microseconds. Receive interrupt reduction can improve CPU efficiency if
+ * properly tuned for specific network traffic. Increasing this value adds
+ * extra latency to frame reception and can end up decreasing the throughput
+ * of TCP traffic. If the system is reporting dropped receives, this value
+ * may be set too high, causing the driver to run out of available receive
+ * descriptors.
+ *
+ * CAUTION: When setting EM_RDTR to a value other than 0, adapters
+ * may hang (stop transmitting) under certain network conditions.
+ * If this occurs a WATCHDOG message is logged in the system
+ * event log. In addition, the controller is automatically reset,
+ * restoring the network connection. To eliminate the potential
+ * for the hang ensure that EM_RDTR is set to 0.
+ */
+#define EM_RDTR 0
+
+/*
+ * Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
+ * Valid Range: 0-65535 (0=off)
+ * Default Value: 64
+ * This value, in units of 1.024 microseconds, limits the delay in which a
+ * receive interrupt is generated. Useful only if EM_RDTR is non-zero,
+ * this value ensures that an interrupt is generated after the initial
+ * packet is received within the set amount of time. Proper tuning,
+ * along with EM_RDTR, may improve traffic throughput in specific network
+ * conditions.
+ */
+#define EM_RADV 64
+
+/*
+ * This parameter controls the max duration of transmit watchdog.
+ */
+#define EM_WATCHDOG (10 * hz)
+
+/*
+ * This parameter controls when the driver calls the routine to reclaim
+ * transmit descriptors.
+ */
+#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
+#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
+
+/*
+ * This parameter controls whether or not autonegotation is enabled.
+ * 0 - Disable autonegotiation
+ * 1 - Enable autonegotiation
+ */
+#define DO_AUTO_NEG 1
+
+/*
+ * This parameter control whether or not the driver will wait for
+ * autonegotiation to complete.
+ * 1 - Wait for autonegotiation to complete
+ * 0 - Don't wait for autonegotiation to complete
+ */
+#define WAIT_FOR_AUTO_NEG_DEFAULT 0
+
+/* Tunables -- End */
+
+#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
+ ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
+ ADVERTISE_1000_FULL)
+
+#define AUTO_ALL_MODES 0
+
+/* PHY master/slave setting */
+#define EM_MASTER_SLAVE e1000_ms_hw_default
+
+/*
+ * Micellaneous constants
+ */
+#define EM_VENDOR_ID 0x8086
+#define EM_FLASH 0x0014
+
+#define EM_JUMBO_PBA 0x00000028
+#define EM_DEFAULT_PBA 0x00000030
+#define EM_SMARTSPEED_DOWNSHIFT 3
+#define EM_SMARTSPEED_MAX 15
+#define EM_MAX_LOOP 10
+
+#define MAX_NUM_MULTICAST_ADDRESSES 128
+#define PCI_ANY_ID (~0U)
+#define ETHER_ALIGN 2
+#define EM_FC_PAUSE_TIME 0x0680
+#define EM_EEPROM_APME 0x400;
+#define EM_82544_APME 0x0004;
+
+/* Code compatilbility between 6 and 7 */
+#ifndef ETHER_BPF_MTAP
+#define ETHER_BPF_MTAP BPF_MTAP
+#endif
+
+/*
+ * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
+ * multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
+ * also optimize cache line size effect. H/W supports up to cache line size 128.
+ */
+#define EM_DBA_ALIGN 128
+
+#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
+
+/* PCI Config defines */
+#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
+#define EM_BAR_TYPE_MASK 0x00000001
+#define EM_BAR_TYPE_MMEM 0x00000000
+#define EM_BAR_TYPE_IO 0x00000001
+#define EM_BAR_TYPE_FLASH 0x0014
+#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
+#define EM_BAR_MEM_TYPE_MASK 0x00000006
+#define EM_BAR_MEM_TYPE_32BIT 0x00000000
+#define EM_BAR_MEM_TYPE_64BIT 0x00000004
+#define EM_MSIX_BAR 3 /* On 82575 */
+
+/* Defines for printing debug information */
+#define DEBUG_INIT 0
+#define DEBUG_IOCTL 0
+#define DEBUG_HW 0
+
+#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
+#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
+#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
+#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
+#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
+#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
+#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
+#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
+#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
+
+#define EM_MAX_SCATTER 64
+#define EM_VFTA_SIZE 128
+#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
+#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
+#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */
+#define ETH_ZLEN 60
+#define ETH_ADDR_LEN 6
+#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
+
+/*
+ * 82574 has a nonstandard address for EIAC
+ * and since its only used in MSIX, and in
+ * the em driver only 82574 uses MSIX we can
+ * solve it just using this define.
+ */
+#define EM_EIAC 0x000DC
+
+/* Used in for 82547 10Mb Half workaround */
+#define EM_PBA_BYTES_SHIFT 0xA
+#define EM_TX_HEAD_ADDR_SHIFT 7
+#define EM_PBA_TX_MASK 0xFFFF0000
+#define EM_FIFO_HDR 0x10
+#define EM_82547_PKT_THRESH 0x3e0
+
+/* Precision Time Sync (IEEE 1588) defines */
+#define ETHERTYPE_IEEE1588 0x88F7
+#define PICOSECS_PER_TICK 20833
+#define TSYNC_PORT 319 /* UDP port for the protocol */
+
+/*
+ * Bus dma allocation structure used by
+ * e1000_dma_malloc and e1000_dma_free.
+ */
+struct em_dma_alloc {
+ bus_addr_t dma_paddr;
+ caddr_t dma_vaddr;
+ bus_dma_tag_t dma_tag;
+ bus_dmamap_t dma_map;
+ bus_dma_segment_t dma_seg;
+ int dma_nseg;
+};
+
+struct adapter;
+
+struct em_int_delay_info {
+ struct adapter *adapter; /* Back-pointer to the adapter struct */
+ int offset; /* Register offset to read/write */
+ int value; /* Current value in usecs */
+};
+
+/* Our adapter structure */
+struct adapter {
+ struct ifnet *ifp;
+#if __FreeBSD_version >= 800000
+ struct buf_ring *br;
+#endif
+ struct e1000_hw hw;
+
+ /* FreeBSD operating-system-specific structures. */
+ struct e1000_osdep osdep;
+ struct device *dev;
+ struct cdev *led_dev;
+
+ struct resource *memory;
+ struct resource *flash;
+ struct resource *msix;
+
+ struct resource *ioport;
+ int io_rid;
+
+ /* 82574 may use 3 int vectors */
+ struct resource *res[3];
+ void *tag[3];
+ int rid[3];
+
+ struct ifmedia media;
+ struct callout timer;
+ struct callout tx_fifo_timer;
+ bool watchdog_check;
+ int watchdog_time;
+ int msi;
+ int if_flags;
+ int max_frame_size;
+ int min_frame_size;
+ struct mtx core_mtx;
+ struct mtx tx_mtx;
+ struct mtx rx_mtx;
+ int em_insert_vlan_header;
+
+ /* Task for FAST handling */
+ struct task link_task;
+ struct task rxtx_task;
+ struct task rx_task;
+ struct task tx_task;
+ struct taskqueue *tq; /* private task queue */
+
+#if __FreeBSD_version >= 700029
+ eventhandler_tag vlan_attach;
+ eventhandler_tag vlan_detach;
+ u32 num_vlans;
+#endif
+
+ /* Management and WOL features */
+ u32 wol;
+ bool has_manage;
+ bool has_amt;
+
+ /* Info about the board itself */
+ uint8_t link_active;
+ uint16_t link_speed;
+ uint16_t link_duplex;
+ uint32_t smartspeed;
+ struct em_int_delay_info tx_int_delay;
+ struct em_int_delay_info tx_abs_int_delay;
+ struct em_int_delay_info rx_int_delay;
+ struct em_int_delay_info rx_abs_int_delay;
+
+ /*
+ * Transmit definitions
+ *
+ * We have an array of num_tx_desc descriptors (handled
+ * by the controller) paired with an array of tx_buffers
+ * (at tx_buffer_area).
+ * The index of the next available descriptor is next_avail_tx_desc.
+ * The number of remaining tx_desc is num_tx_desc_avail.
+ */
+ struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
+ struct e1000_tx_desc *tx_desc_base;
+ uint32_t next_avail_tx_desc;
+ uint32_t next_tx_to_clean;
+ volatile uint16_t num_tx_desc_avail;
+ uint16_t num_tx_desc;
+ uint16_t last_hw_offload;
+ uint32_t txd_cmd;
+ struct em_buffer *tx_buffer_area;
+ bus_dma_tag_t txtag; /* dma tag for tx */
+ uint32_t tx_tso; /* last tx was tso */
+
+ /*
+ * Receive definitions
+ *
+ * we have an array of num_rx_desc rx_desc (handled by the
+ * controller), and paired with an array of rx_buffers
+ * (at rx_buffer_area).
+ * The next pair to check on receive is at offset next_rx_desc_to_check
+ */
+ struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
+ struct e1000_rx_desc *rx_desc_base;
+ uint32_t next_rx_desc_to_check;
+ uint32_t rx_buffer_len;
+ uint16_t num_rx_desc;
+ int rx_process_limit;
+ struct em_buffer *rx_buffer_area;
+ bus_dma_tag_t rxtag;
+ bus_dmamap_t rx_sparemap;
+
+ /*
+ * First/last mbuf pointers, for
+ * collecting multisegment RX packets.
+ */
+ struct mbuf *fmp;
+ struct mbuf *lmp;
+
+ /* Misc stats maintained by the driver */
+ unsigned long dropped_pkts;
+ unsigned long mbuf_alloc_failed;
+ unsigned long mbuf_cluster_failed;
+ unsigned long no_tx_desc_avail1;
+ unsigned long no_tx_desc_avail2;
+ unsigned long no_tx_map_avail;
+ unsigned long no_tx_dma_setup;
+ unsigned long watchdog_events;
+ unsigned long rx_overruns;
+ unsigned long rx_irq;
+ unsigned long tx_irq;
+ unsigned long link_irq;
+
+ /* 82547 workaround */
+ uint32_t tx_fifo_size;
+ uint32_t tx_fifo_head;
+ uint32_t tx_fifo_head_addr;
+ uint64_t tx_fifo_reset_cnt;
+ uint64_t tx_fifo_wrk_cnt;
+ uint32_t tx_head_addr;
+
+ /* For 82544 PCIX Workaround */
+ boolean_t pcix_82544;
+ boolean_t in_detach;
+
+
+ struct e1000_hw_stats stats;
+};
+
+/* ******************************************************************************
+ * vendor_info_array
+ *
+ * This array contains the list of Subvendor/Subdevice IDs on which the driver
+ * should load.
+ *
+ * ******************************************************************************/
+typedef struct _em_vendor_info_t {
+ unsigned int vendor_id;
+ unsigned int device_id;
+ unsigned int subvendor_id;
+ unsigned int subdevice_id;
+ unsigned int index;
+} em_vendor_info_t;
+
+struct em_buffer {
+ int next_eop; /* Index of the desc to watch */
+ struct mbuf *m_head;
+ bus_dmamap_t map; /* bus_dma map for packet */
+};
+
+/* For 82544 PCIX Workaround */
+typedef struct _ADDRESS_LENGTH_PAIR
+{
+ uint64_t address;
+ uint32_t length;
+} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
+
+typedef struct _DESCRIPTOR_PAIR
+{
+ ADDRESS_LENGTH_PAIR descriptor[4];
+ uint32_t elements;
+} DESC_ARRAY, *PDESC_ARRAY;
+
+#define EM_CORE_LOCK_INIT(_sc, _name) \
+ mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
+#define EM_TX_LOCK_INIT(_sc, _name) \
+ mtx_init(&(_sc)->tx_mtx, _name, "EM TX Lock", MTX_DEF)
+#define EM_RX_LOCK_INIT(_sc, _name) \
+ mtx_init(&(_sc)->rx_mtx, _name, "EM RX Lock", MTX_DEF)
+#define EM_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
+#define EM_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
+#define EM_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
+#define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
+#define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
+#define EM_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
+#define EM_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
+#define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
+#define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
+#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
+#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
+#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
+
+#endif /* _LEM_H_DEFINED_ */
diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index 2602440..446046c 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 1998 Kazutaka YOKOTA and Michael Smith
+ * Copyright (c) 2009-2010 Jung-uk Kim <jkim@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -188,7 +189,7 @@ static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g,
#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG)
static ssize_t vesa_bios_state_buf_size(void);
static int vesa_bios_save_restore(int code, void *p, size_t size);
-#if 0
+#ifdef MODE_TABLE_BROKEN
static int vesa_bios_get_line_length(void);
#endif
static int vesa_bios_set_line_length(int pixel, int *bytes, int *lines);
@@ -199,6 +200,7 @@ static int vesa_bios_set_start(int x, int y);
static int vesa_map_gen_mode_num(int type, int color, int mode);
static int vesa_translate_flags(u_int16_t vflags);
static int vesa_translate_mmodel(u_int8_t vmodel);
+static int vesa_get_bpscanline(struct vesa_mode *vmode);
static int vesa_bios_init(void);
static void vesa_clear_modes(video_info_t *info, int color);
@@ -558,7 +560,7 @@ vesa_bios_save_restore(int code, void *p, size_t size)
return (regs.R_AX != 0x004f);
}
-#if 0
+#ifdef MODE_TABLE_BROKEN
static int
vesa_bios_get_line_length(void)
{
@@ -709,6 +711,43 @@ vesa_translate_mmodel(u_int8_t vmodel)
return (V_INFO_MM_OTHER);
}
+static int
+vesa_get_bpscanline(struct vesa_mode *vmode)
+{
+ int bpsl;
+
+ if ((vmode->v_modeattr & V_MODEGRAPHICS) != 0) {
+ /* Find the minimum length. */
+ switch (vmode->v_bpp / vmode->v_planes) {
+ case 1:
+ bpsl = vmode->v_width / 8;
+ break;
+ case 2:
+ bpsl = vmode->v_width / 4;
+ break;
+ case 4:
+ bpsl = vmode->v_width / 2;
+ break;
+ default:
+ bpsl = vmode->v_width * ((vmode->v_bpp + 7) / 8);
+ bpsl /= vmode->v_planes;
+ break;
+ }
+
+ /* Use VBE 3.0 information if it looks sane. */
+ if ((vmode->v_modeattr & V_MODELFB) != 0 &&
+ vesa_adp_info->v_version >= 0x0300 &&
+ vmode->v_linbpscanline > bpsl)
+ return (vmode->v_linbpscanline);
+
+ /* Return the minimum if the mode table looks absurd. */
+ if (vmode->v_bpscanline < bpsl)
+ return (bpsl);
+ }
+
+ return (vmode->v_bpscanline);
+}
+
#define VESA_MAXSTR 256
#define VESA_STRCPY(dst, src) do { \
@@ -724,8 +763,8 @@ vesa_translate_mmodel(u_int8_t vmodel)
static int
vesa_bios_init(void)
{
- static struct vesa_info buf;
struct vesa_mode vmode;
+ struct vesa_info *buf;
video_info_t *p;
x86regs_t regs;
size_t bsize;
@@ -733,7 +772,6 @@ vesa_bios_init(void)
void *vmbuf;
uint32_t offs;
uint16_t vers;
- int bpsl;
int is_via_cle266;
int modes;
int i;
@@ -762,7 +800,7 @@ vesa_bios_init(void)
x86bios_init_regs(&regs);
regs.R_AX = 0x4f00;
- vmbuf = x86bios_alloc(&offs, sizeof(buf));
+ vmbuf = x86bios_alloc(&offs, sizeof(*buf));
if (vmbuf == NULL)
return (1);
@@ -775,23 +813,23 @@ vesa_bios_init(void)
if (regs.R_AX != 0x004f || bcmp("VESA", vmbuf, 4) != 0)
goto fail;
- bcopy(vmbuf, &buf, sizeof(buf));
+ vesa_adp_info = buf = malloc(sizeof(*buf), M_DEVBUF, M_WAITOK);
+ bcopy(vmbuf, buf, sizeof(*buf));
- vesa_adp_info = &buf;
if (bootverbose) {
printf("VESA: information block\n");
- hexdump(&buf, sizeof(buf), NULL, HD_OMIT_CHARS);
+ hexdump(buf, sizeof(*buf), NULL, HD_OMIT_CHARS);
}
- vers = buf.v_version = le16toh(buf.v_version);
- buf.v_oemstr = le32toh(buf.v_oemstr);
- buf.v_flags = le32toh(buf.v_flags);
- buf.v_modetable = le32toh(buf.v_modetable);
- buf.v_memsize = le16toh(buf.v_memsize);
- buf.v_revision = le16toh(buf.v_revision);
- buf.v_venderstr = le32toh(buf.v_venderstr);
- buf.v_prodstr = le32toh(buf.v_prodstr);
- buf.v_revstr = le32toh(buf.v_revstr);
+ vers = buf->v_version = le16toh(buf->v_version);
+ buf->v_oemstr = le32toh(buf->v_oemstr);
+ buf->v_flags = le32toh(buf->v_flags);
+ buf->v_modetable = le32toh(buf->v_modetable);
+ buf->v_memsize = le16toh(buf->v_memsize);
+ buf->v_revision = le16toh(buf->v_revision);
+ buf->v_venderstr = le32toh(buf->v_venderstr);
+ buf->v_prodstr = le32toh(buf->v_prodstr);
+ buf->v_revstr = le32toh(buf->v_revstr);
if (vers < 0x0102) {
printf("VESA: VBE version %d.%d is not supported; "
@@ -801,21 +839,21 @@ vesa_bios_init(void)
return (1);
}
- VESA_STRCPY(vesa_oemstr, buf.v_oemstr);
+ VESA_STRCPY(vesa_oemstr, buf->v_oemstr);
if (vers >= 0x0200) {
- VESA_STRCPY(vesa_venderstr, buf.v_venderstr);
- VESA_STRCPY(vesa_prodstr, buf.v_prodstr);
- VESA_STRCPY(vesa_revstr, buf.v_revstr);
+ VESA_STRCPY(vesa_venderstr, buf->v_venderstr);
+ VESA_STRCPY(vesa_prodstr, buf->v_prodstr);
+ VESA_STRCPY(vesa_revstr, buf->v_revstr);
}
is_via_cle266 = strncmp(vesa_oemstr, VESA_VIA_CLE266,
sizeof(VESA_VIA_CLE266)) == 0;
- if (buf.v_modetable == 0)
+ if (buf->v_modetable == 0)
goto fail;
- msize = (size_t)buf.v_memsize * 64 * 1024;
+ msize = (size_t)buf->v_memsize * 64 * 1024;
- vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf.v_modetable));
+ vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf->v_modetable));
for (i = 0, modes = 0; (i < (M_VESA_MODE_MAX - M_VESA_BASE + 1)) &&
(vesa_vmodetab[i] != 0xffff); ++i) {
@@ -858,9 +896,7 @@ vesa_bios_init(void)
}
#endif
- bpsl = (vmode.v_modeattr & V_MODELFB) != 0 && vers >= 0x0300 ?
- vmode.v_linbpscanline : vmode.v_bpscanline;
- bsize = bpsl * vmode.v_height;
+ bsize = vesa_get_bpscanline(&vmode) * vmode.v_height;
if ((vmode.v_modeattr & V_MODEGRAPHICS) != 0)
bsize *= vmode.v_planes;
@@ -980,12 +1016,16 @@ vesa_bios_init(void)
if (!has_vesa_bios)
goto fail;
- x86bios_free(vmbuf, sizeof(buf));
+ x86bios_free(vmbuf, sizeof(*buf));
return (0);
fail:
if (vmbuf != NULL)
x86bios_free(vmbuf, sizeof(buf));
+ if (vesa_adp_info != NULL) {
+ free(vesa_adp_info, M_DEVBUF);
+ vesa_adp_info = NULL;
+ }
if (vesa_oemstr != NULL) {
free(vesa_oemstr, M_DEVBUF);
vesa_oemstr = NULL;
@@ -1209,7 +1249,7 @@ vesa_set_mode(video_adapter_t *adp, int mode)
int10_set_mode(adp->va_initial_bios_mode);
if (adp->va_info.vi_flags & V_INFO_LINEAR)
pmap_unmapdev(adp->va_buffer,
- adp->va_buffer_size);
+ vesa_adp_info->v_memsize * 64 * 1024);
/*
* Once (*prevvidsw->get_info)() succeeded,
* (*prevvidsw->set_mode)() below won't fail...
@@ -1241,12 +1281,12 @@ vesa_set_mode(video_adapter_t *adp, int mode)
if ((vesa_adp_info->v_flags & V_DAC8) != 0 &&
(info.vi_flags & V_INFO_GRAPHICS) != 0 &&
- (info.vi_flags & V_INFO_NONVGA) != 0 &&
vesa_bios_set_dac(8) > 6)
adp->va_flags |= V_ADP_DAC8;
if (adp->va_info.vi_flags & V_INFO_LINEAR)
- pmap_unmapdev(adp->va_buffer, adp->va_buffer_size);
+ pmap_unmapdev(adp->va_buffer,
+ vesa_adp_info->v_memsize * 64 * 1024);
#if VESA_DEBUG > 0
printf("VESA: mode set!\n");
@@ -1257,13 +1297,31 @@ vesa_set_mode(video_adapter_t *adp, int mode)
(info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
vesa_adp->va_crtc_addr =
(vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
+
+ vesa_adp->va_line_width = info.vi_buffer_size / info.vi_height;
+ if ((info.vi_flags & V_INFO_GRAPHICS) != 0)
+ vesa_adp->va_line_width /= info.vi_planes;
+
+#ifdef MODE_TABLE_BROKEN
+ /* If VBE function returns bigger bytes per scan line, use it. */
+ {
+ int bpsl = vesa_bios_get_line_length();
+ if (bpsl > vesa_adp->va_line_width) {
+ vesa_adp->va_line_width = bpsl;
+ info.vi_buffer_size = bpsl * info.vi_height;
+ if ((info.vi_flags & V_INFO_GRAPHICS) != 0)
+ info.vi_buffer_size *= info.vi_planes;
+ }
+ }
+#endif
+
if (info.vi_flags & V_INFO_LINEAR) {
#if VESA_DEBUG > 1
printf("VESA: setting up LFB\n");
#endif
vesa_adp->va_buffer =
(vm_offset_t)pmap_mapdev_attr(info.vi_buffer,
- info.vi_buffer_size, PAT_WRITE_COMBINING);
+ vesa_adp_info->v_memsize * 64 * 1024, PAT_WRITE_COMBINING);
vesa_adp->va_window = vesa_adp->va_buffer;
vesa_adp->va_window_size = info.vi_buffer_size / info.vi_planes;
vesa_adp->va_window_gran = info.vi_buffer_size / info.vi_planes;
@@ -1275,9 +1333,6 @@ vesa_set_mode(video_adapter_t *adp, int mode)
}
vesa_adp->va_buffer_size = info.vi_buffer_size;
vesa_adp->va_window_orig = 0;
- vesa_adp->va_line_width = info.vi_buffer_size / info.vi_height;
- if ((info.vi_flags & V_INFO_GRAPHICS) != 0)
- vesa_adp->va_line_width /= info.vi_planes;
vesa_adp->va_disp_start.x = 0;
vesa_adp->va_disp_start.y = 0;
#if VESA_DEBUG > 0
@@ -1322,10 +1377,10 @@ vesa_save_palette(video_adapter_t *adp, u_char *palette)
{
int bits;
- if (adp == vesa_adp && VESA_MODE(adp->va_mode) &&
- (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) {
+ if (adp == vesa_adp && VESA_MODE(adp->va_mode)) {
bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
- return (vesa_bios_save_palette(0, 256, palette, bits));
+ if (vesa_bios_save_palette(0, 256, palette, bits) == 0)
+ return (0);
}
return ((*prevvidsw->save_palette)(adp, palette));
@@ -1336,10 +1391,10 @@ vesa_load_palette(video_adapter_t *adp, u_char *palette)
{
int bits;
- if (adp == vesa_adp && VESA_MODE(adp->va_mode) &&
- (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) {
+ if (adp == vesa_adp && VESA_MODE(adp->va_mode)) {
bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
- return (vesa_bios_load_palette(0, 256, palette, bits));
+ if (vesa_bios_load_palette(0, 256, palette, bits) == 0)
+ return (0);
}
return ((*prevvidsw->load_palette)(adp, palette));
@@ -1544,8 +1599,6 @@ get_palette(video_adapter_t *adp, int base, int count,
return (1);
if (!VESA_MODE(adp->va_mode))
return (1);
- if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0)
- return (1);
bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
r = malloc(count * 3, M_DEVBUF, M_WAITOK);
@@ -1582,8 +1635,6 @@ set_palette(video_adapter_t *adp, int base, int count,
return (1);
if (!VESA_MODE(adp->va_mode))
return (1);
- if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0)
- return (1);
bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
r = malloc(count * 3, M_DEVBUF, M_WAITOK);
@@ -1828,6 +1879,8 @@ vesa_unload(void)
}
splx(s);
+ if (vesa_adp_info != NULL)
+ free(vesa_adp_info, M_DEVBUF);
if (vesa_oemstr != NULL)
free(vesa_oemstr, M_DEVBUF);
if (vesa_venderstr != NULL)
diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c
index 7d702ad..1bcf935 100644
--- a/sys/dev/fb/vga.c
+++ b/sys/dev/fb/vga.c
@@ -1979,6 +1979,7 @@ vga_show_font(video_adapter_t *adp, int page)
static int
vga_save_palette(video_adapter_t *adp, u_char *palette)
{
+ int bits;
int i;
prologue(adp, V_ADP_PALETTE, ENODEV);
@@ -1988,8 +1989,9 @@ vga_save_palette(video_adapter_t *adp, u_char *palette)
* VGA has 6 bit DAC .
*/
outb(PALRADR, 0x00);
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2;
for (i = 0; i < 256*3; ++i)
- palette[i] = inb(PALDATA) << 2;
+ palette[i] = inb(PALDATA) << bits;
inb(adp->va_crtc_addr + 6); /* reset flip/flop */
return 0;
}
@@ -1998,15 +2000,17 @@ static int
vga_save_palette2(video_adapter_t *adp, int base, int count,
u_char *r, u_char *g, u_char *b)
{
+ int bits;
int i;
prologue(adp, V_ADP_PALETTE, ENODEV);
outb(PALRADR, base);
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2;
for (i = 0; i < count; ++i) {
- r[i] = inb(PALDATA) << 2;
- g[i] = inb(PALDATA) << 2;
- b[i] = inb(PALDATA) << 2;
+ r[i] = inb(PALDATA) << bits;
+ g[i] = inb(PALDATA) << bits;
+ b[i] = inb(PALDATA) << bits;
}
inb(adp->va_crtc_addr + 6); /* reset flip/flop */
return 0;
@@ -2021,14 +2025,16 @@ vga_save_palette2(video_adapter_t *adp, int base, int count,
static int
vga_load_palette(video_adapter_t *adp, u_char *palette)
{
+ int bits;
int i;
prologue(adp, V_ADP_PALETTE, ENODEV);
outb(PIXMASK, 0xff); /* no pixelmask */
outb(PALWADR, 0x00);
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2;
for (i = 0; i < 256*3; ++i)
- outb(PALDATA, palette[i] >> 2);
+ outb(PALDATA, palette[i] >> bits);
inb(adp->va_crtc_addr + 6); /* reset flip/flop */
outb(ATC, 0x20); /* enable palette */
return 0;
@@ -2038,16 +2044,18 @@ static int
vga_load_palette2(video_adapter_t *adp, int base, int count,
u_char *r, u_char *g, u_char *b)
{
+ int bits;
int i;
prologue(adp, V_ADP_PALETTE, ENODEV);
outb(PIXMASK, 0xff); /* no pixelmask */
outb(PALWADR, base);
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2;
for (i = 0; i < count; ++i) {
- outb(PALDATA, r[i] >> 2);
- outb(PALDATA, g[i] >> 2);
- outb(PALDATA, b[i] >> 2);
+ outb(PALDATA, r[i] >> bits);
+ outb(PALDATA, g[i] >> bits);
+ outb(PALDATA, b[i] >> bits);
}
inb(adp->va_crtc_addr + 6); /* reset flip/flop */
outb(ATC, 0x20); /* enable palette */
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c
index 0b9d1fa..229ee6d 100644
--- a/sys/dev/firewire/sbp.c
+++ b/sys/dev/firewire/sbp.c
@@ -2698,7 +2698,7 @@ SBP_DEBUG(0)
#else
"segment length(%zd) is less than 16."
#endif
- "(seg=%d/%d)\n", s->ds_len, i+1, seg);
+ "(seg=%d/%d)\n", (size_t)s->ds_len, i+1, seg);
END_DEBUG
if (s->ds_len > SBP_SEG_MAX)
panic("ds_len > SBP_SEG_MAX, fix busdma code");
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index a8d961e..a480e7c 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -1417,60 +1417,6 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
FXP_IPCB_HARDWAREPARSING_ENABLE;
m = *m_head;
- /*
- * Deal with TCP/IP checksum offload. Note that
- * in order for TCP checksum offload to work,
- * the pseudo header checksum must have already
- * been computed and stored in the checksum field
- * in the TCP header. The stack should have
- * already done this for us.
- */
- if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
- txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
- if (m->m_pkthdr.csum_flags & CSUM_TCP)
- txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
-
-#ifdef FXP_IP_CSUM_WAR
- /*
- * XXX The 82550 chip appears to have trouble
- * dealing with IP header checksums in very small
- * datagrams, namely fragments from 1 to 3 bytes
- * in size. For example, say you want to transmit
- * a UDP packet of 1473 bytes. The packet will be
- * fragmented over two IP datagrams, the latter
- * containing only one byte of data. The 82550 will
- * botch the header checksum on the 1-byte fragment.
- * As long as the datagram contains 4 or more bytes
- * of data, you're ok.
- *
- * The following code attempts to work around this
- * problem: if the datagram is less than 38 bytes
- * in size (14 bytes ether header, 20 bytes IP header,
- * plus 4 bytes of data), we punt and compute the IP
- * header checksum by hand. This workaround doesn't
- * work very well, however, since it can be fooled
- * by things like VLAN tags and IP options that make
- * the header sizes/offsets vary.
- */
-
- if (m->m_pkthdr.csum_flags & CSUM_IP) {
- if (m->m_pkthdr.len < 38) {
- struct ip *ip;
- m->m_data += ETHER_HDR_LEN;
- ip = mtod(m, struct ip *);
- ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
- m->m_data -= ETHER_HDR_LEN;
- m->m_pkthdr.csum_flags &= ~CSUM_IP;
- } else {
- txp->tx_cb->ipcb_ip_activation_high =
- FXP_IPCB_HARDWAREPARSING_ENABLE;
- txp->tx_cb->ipcb_ip_schedule |=
- FXP_IPCB_IP_CHECKSUM_ENABLE;
- }
- }
-#endif
- }
-
if (m->m_pkthdr.csum_flags & CSUM_TSO) {
/*
* 82550/82551 requires ethernet/IP/TCP headers must be
@@ -1539,6 +1485,58 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
tcp_payload = m->m_pkthdr.len - ip_off - (ip->ip_hl << 2);
tcp_payload -= tcp->th_off << 2;
*m_head = m;
+ } else if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
+ /*
+ * Deal with TCP/IP checksum offload. Note that
+ * in order for TCP checksum offload to work,
+ * the pseudo header checksum must have already
+ * been computed and stored in the checksum field
+ * in the TCP header. The stack should have
+ * already done this for us.
+ */
+ txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
+ if (m->m_pkthdr.csum_flags & CSUM_TCP)
+ txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
+
+#ifdef FXP_IP_CSUM_WAR
+ /*
+ * XXX The 82550 chip appears to have trouble
+ * dealing with IP header checksums in very small
+ * datagrams, namely fragments from 1 to 3 bytes
+ * in size. For example, say you want to transmit
+ * a UDP packet of 1473 bytes. The packet will be
+ * fragmented over two IP datagrams, the latter
+ * containing only one byte of data. The 82550 will
+ * botch the header checksum on the 1-byte fragment.
+ * As long as the datagram contains 4 or more bytes
+ * of data, you're ok.
+ *
+ * The following code attempts to work around this
+ * problem: if the datagram is less than 38 bytes
+ * in size (14 bytes ether header, 20 bytes IP header,
+ * plus 4 bytes of data), we punt and compute the IP
+ * header checksum by hand. This workaround doesn't
+ * work very well, however, since it can be fooled
+ * by things like VLAN tags and IP options that make
+ * the header sizes/offsets vary.
+ */
+
+ if (m->m_pkthdr.csum_flags & CSUM_IP) {
+ if (m->m_pkthdr.len < 38) {
+ struct ip *ip;
+ m->m_data += ETHER_HDR_LEN;
+ ip = mtod(m, struct ip *);
+ ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+ m->m_data -= ETHER_HDR_LEN;
+ m->m_pkthdr.csum_flags &= ~CSUM_IP;
+ } else {
+ txp->tx_cb->ipcb_ip_activation_high =
+ FXP_IPCB_HARDWAREPARSING_ENABLE;
+ txp->tx_cb->ipcb_ip_schedule |=
+ FXP_IPCB_IP_CHECKSUM_ENABLE;
+ }
+ }
+#endif
}
error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, *m_head,
diff --git a/sys/dev/hme/if_hme_sbus.c b/sys/dev/hme/if_hme_sbus.c
index 9eea7b8..846ee11 100644
--- a/sys/dev/hme/if_hme_sbus.c
+++ b/sys/dev/hme/if_hme_sbus.c
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/hme/if_hmereg.h b/sys/dev/hme/if_hmereg.h
index b3c01cc..3d93eba 100644
--- a/sys/dev/hme/if_hmereg.h
+++ b/sys/dev/hme/if_hmereg.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/hme/if_hmevar.h b/sys/dev/hme/if_hmevar.h
index d49e675..845f839 100644
--- a/sys/dev/hme/if_hmevar.h
+++ b/sys/dev/hme/if_hmevar.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index 43a4914..e7de099 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -534,10 +534,12 @@ struct iap_event_descr {
#define IAP_F_CC2E (1 << 2) /* CPU: Core2 Extreme only */
#define IAP_F_CA (1 << 3) /* CPU: Atom */
#define IAP_F_I7 (1 << 4) /* CPU: Core i7 */
-#define IAP_F_FM (1 << 5) /* Fixed mask */
+#define IAP_F_I7O (1 << 4) /* CPU: Core i7 (old) */
+#define IAP_F_WM (1 << 5) /* CPU: Westmere */
+#define IAP_F_FM (1 << 6) /* Fixed mask */
-#define IAP_F_ALLCPUS \
- (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA | IAP_F_I7)
+#define IAP_F_ALLCPUSCORE2 \
+ (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA)
/* Sub fields of UMASK that this event supports. */
#define IAP_M_CORE (1 << 0) /* Core specificity */
@@ -570,151 +572,319 @@ static struct iap_event_descr iap_events[] = {
.iap_flags = (FLAGS) \
}
+ IAPDESCR(02H_01H, 0x02, 0x01, IAP_F_FM | IAP_F_I7O),
IAPDESCR(02H_81H, 0x02, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(03H_00H, 0x03, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(03H_01H, 0x03, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_WM),
+ IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
IAPDESCR(03H_08H, 0x03, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(03H_10H, 0x03, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(03H_20H, 0x03, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(04H_00H, 0x04, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(04H_01H, 0x04, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(04H_01H, 0x04, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
IAPDESCR(04H_02H, 0x04, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(04H_07H, 0x04, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(04H_08H, 0x04, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(05H_00H, 0x05, 0x00, IAP_F_FM | IAP_F_CC),
-
- IAPDESCR(06H_00H, 0x06, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7O | IAP_F_WM),
+ IAPDESCR(05H_03H, 0x05, 0x03, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(06H_00H, 0x06, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2 |
+ IAP_F_CC2E | IAP_F_CA),
+ IAPDESCR(06H_01H, 0x06, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(06H_02H, 0x06, 0x02, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(06H_04H, 0x06, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(06H_08H, 0x06, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(06H_0FH, 0x06, 0x0F, IAP_F_FM | IAP_F_I7O),
IAPDESCR(07H_00H, 0x07, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(07H_06H, 0x07, 0x06, IAP_F_FM | IAP_F_CA),
IAPDESCR(07H_08H, 0x07, 0x08, IAP_F_FM | IAP_F_CA),
- IAPDESCR(08H_01H, 0x08, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(08H_02H, 0x08, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(08H_04H, 0x08, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(08H_01H, 0x08, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(08H_02H, 0x08, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(08H_04H, 0x08, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_WM),
IAPDESCR(08H_05H, 0x08, 0x05, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_06H, 0x08, 0x06, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_07H, 0x08, 0x07, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_08H, 0x08, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(08H_09H, 0x08, 0x09, IAP_F_FM | IAP_F_CA),
+ IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7),
+
+ IAPDESCR(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
+ IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
+ IAPDESCR(09H_04H, 0x09, 0x04, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(09H_08H, 0x09, 0x08, IAP_F_FM | IAP_F_I7O),
- IAPDESCR(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(0BH_01H, 0x0B, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0BH_02H, 0x0B, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0BH_10H, 0x0B, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(0CH_01H, 0x0C, 0x01, IAP_F_FM | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(0CH_01H, 0x0C, 0x01, IAP_F_FM | IAP_F_CC2 | IAP_F_I7 |
+ IAP_F_WM),
IAPDESCR(0CH_02H, 0x0C, 0x02, IAP_F_FM | IAP_F_CC2),
IAPDESCR(0CH_03H, 0x0C, 0x03, IAP_F_FM | IAP_F_CA),
- IAPDESCR(10H_00H, 0x10, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
+ IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0EH_02H, 0x0E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(0FH_01H, 0x0F, 0x01, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(0FH_02H, 0x0F, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0FH_08H, 0x0F, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0FH_10H, 0x0F, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0FH_20H, 0x0F, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0FH_80H, 0x0F, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(10H_00H, 0x10, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_02H, 0x10, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_04H, 0x10, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_08H, 0x10, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(10H_81H, 0x10, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(11H_00H, 0x11, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
IAPDESCR(11H_01H, 0x11, 0x01, IAP_F_FM | IAP_F_CA),
IAPDESCR(11H_81H, 0x11, 0x81, IAP_F_FM | IAP_F_CA),
- IAPDESCR(12H_00H, 0x12, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(12H_01H, 0x12, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
+ IAPDESCR(12H_00H, 0x12, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(12H_01H, 0x12, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(12H_02H, 0x12, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(12H_04H, 0x12, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(12H_08H, 0x12, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(12H_10H, 0x12, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(12H_20H, 0x12, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(12H_40H, 0x12, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(12H_81H, 0x12, 0x81, IAP_F_FM | IAP_F_CA),
- IAPDESCR(13H_00H, 0x13, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(13H_01H, 0x13, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
+ IAPDESCR(13H_00H, 0x13, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(13H_01H, 0x13, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(13H_02H, 0x13, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(13H_04H, 0x13, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(13H_07H, 0x13, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(13H_81H, 0x13, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(14H_00H, 0x14, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
+ IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(14H_02H, 0x14, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(17H_01H, 0x17, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(18H_00H, 0x18, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(18H_01H, 0x18, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(19H_00H, 0x19, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(19H_01H, 0x19, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(19H_01H, 0x19, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(19H_02H, 0x19, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(21H, 0x21, IAP_M_CORE, IAP_F_ALLCPUS),
+ IAPDESCR(1DH_01H, 0x1D, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(1DH_02H, 0x1D, 0x02, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(1DH_04H, 0x1D, 0x04, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(1EH_01H, 0x1E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(20H_01H, 0x20, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(21H, 0x21, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(22H, 0x22, IAP_M_CORE, IAP_F_CC2),
- IAPDESCR(23H, 0x23, IAP_M_CORE, IAP_F_ALLCPUS),
- IAPDESCR(24H, 0x24, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUS),
- IAPDESCR(25H, 0x25, IAP_M_CORE, IAP_F_ALLCPUS),
- IAPDESCR(26H, 0x26, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUS),
- IAPDESCR(27H, 0x27, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUS),
- IAPDESCR(28H, 0x28, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUS),
+ IAPDESCR(23H, 0x23, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+
+ IAPDESCR(24H, 0x24, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(24H_01H, 0x24, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_02H, 0x24, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_03H, 0x24, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_04H, 0x24, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_08H, 0x24, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_0CH, 0x24, 0x0C, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_10H, 0x24, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(25H, 0x25, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+
+ IAPDESCR(26H, 0x26, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(26H_01H, 0x26, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_02H, 0x26, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_04H, 0x26, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_08H, 0x26, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_0FH, 0x26, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_10H, 0x26, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_20H, 0x26, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_40H, 0x26, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_80H, 0x26, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_F0H, 0x26, 0xF0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(26H_FFH, 0x26, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(27H, 0x27, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(27H_01H, 0x27, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_02H, 0x27, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_04H, 0x27, 0x04, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(27H_08H, 0x27, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_0EH, 0x27, 0x0E, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_0FH, 0x27, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_10H, 0x27, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_20H, 0x27, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_40H, 0x27, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_80H, 0x27, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_E0H, 0x27, 0xE0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_F0H, 0x27, 0xF0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(28H, 0x28, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(28H_01H, 0x28, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(28H_02H, 0x28, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(28H_04H, 0x28, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(28H_08H, 0x28, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(28H_0FH, 0x28, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
IAPDESCR(29H, 0x29, IAP_M_CORE | IAP_M_MESI, IAP_F_CC),
IAPDESCR(29H, 0x29, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
IAP_F_CA | IAP_F_CC2),
- IAPDESCR(2AH, 0x2A, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUS),
+ IAPDESCR(2AH, 0x2A, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUSCORE2),
IAPDESCR(2BH, 0x2B, IAP_M_CORE | IAP_M_MESI, IAP_F_CA | IAP_F_CC2),
IAPDESCR(2EH, 0x2E, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
- IAP_F_ALLCPUS),
- IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUS),
+ IAP_F_ALLCPUSCORE2),
+ IAPDESCR(2EH_01H, 0x2E, 0x01, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(2EH_02H, 0x2E, 0x02, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7),
+ IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7),
IAPDESCR(30H, 0x30, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
- IAP_F_ALLCPUS),
+ IAP_F_ALLCPUSCORE2),
IAPDESCR(32H, 0x32, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH, IAP_F_CC),
IAPDESCR(32H, 0x32, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(3AH, 0x3A, IAP_M_TRANSITION, IAP_F_CC),
IAPDESCR(3AH_00H, 0x3A, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(3BH_C0H, 0x3B, 0xC0, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(3BH_C0H, 0x3B, 0xC0, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(3CH_00H, 0x3C, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(3CH_00H, 0x3C, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+
+ IAPDESCR(3DH_01H, 0x3D, 0x01, IAP_F_FM | IAP_F_I7O),
IAPDESCR(40H, 0x40, IAP_M_MESI, IAP_F_CC | IAP_F_CC2),
+ IAPDESCR(40H_01H, 0x40, 0x01, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(40H_02H, 0x40, 0x02, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(40H_04H, 0x40, 0x04, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(40H_08H, 0x40, 0x08, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(40H_0FH, 0x40, 0x0F, IAP_F_FM | IAP_F_I7),
IAPDESCR(40H_21H, 0x40, 0x21, IAP_F_FM | IAP_F_CA),
IAPDESCR(41H, 0x41, IAP_M_MESI, IAP_F_CC | IAP_F_CC2),
+ IAPDESCR(41H_01H, 0x41, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(41H_02H, 0x41, 0x02, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(41H_04H, 0x41, 0x04, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(41H_08H, 0x41, 0x08, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(41H_0FH, 0x41, 0x0F, IAP_F_FM | IAP_F_I7O),
IAPDESCR(41H_22H, 0x41, 0x22, IAP_F_FM | IAP_F_CA),
- IAPDESCR(42H, 0x42, IAP_M_MESI, IAP_F_ALLCPUS),
+ IAPDESCR(42H, 0x42, IAP_M_MESI, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(42H_01H, 0x42, 0x01, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(42H_02H, 0x42, 0x02, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(42H_04H, 0x42, 0x04, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(42H_08H, 0x42, 0x08, IAP_F_FM | IAP_F_I7),
IAPDESCR(42H_10H, 0x42, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(43H_01H, 0x43, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(43H_02H, 0x43, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(43H_01H, 0x43, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7),
+ IAPDESCR(43H_02H, 0x43, 0x02, IAP_F_FM | IAP_F_CA |
+ IAP_F_CC2 | IAP_F_I7),
IAPDESCR(44H_02H, 0x44, 0x02, IAP_F_FM | IAP_F_CC),
- IAPDESCR(45H_0FH, 0x45, 0x0F, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(45H_0FH, 0x45, 0x0F, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(46H_00H, 0x46, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(47H_00H, 0x47, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(48H_00H, 0x48, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(46H_00H, 0x46, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(47H_00H, 0x47, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(49H_00H, 0x49, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(49H_01H, 0x49, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(48H_00H, 0x48, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(48H_02H, 0x48, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4BH_00H, 0x4B, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(4BH_01H, 0x4B, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(4BH_02H, 0x4B, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(49H_00H, 0x49, 0x00, IAP_F_FM | IAP_F_CC),
+ IAPDESCR(49H_01H, 0x49, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(49H_04H, 0x49, 0x04, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+
+ IAPDESCR(4BH_00H, 0x4B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(4BH_01H, 0x4B, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7O),
+ IAPDESCR(4BH_02H, 0x4B, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(4BH_03H, 0x4B, 0x03, IAP_F_FM | IAP_F_CC),
+ IAPDESCR(4BH_08H, 0x4B, 0x08, IAP_F_FM | IAP_F_I7O),
IAPDESCR(4CH_00H, 0x4C, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(4DH_01H, 0x4D, 0x01, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(4EH_01H, 0x4E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(4EH_02H, 0x4E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(4EH_04H, 0x4E, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(4EH_10H, 0x4E, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(4FH_00H, 0x4F, 0x00, IAP_F_FM | IAP_F_CC),
+ IAPDESCR(4FH_02H, 0x4F, 0x02, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(4FH_04H, 0x4F, 0x04, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(4FH_08H, 0x4F, 0x08, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(4FH_10H, 0x4F, 0x10, IAP_F_FM | IAP_F_WM),
+
+ IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(51H_08H, 0x51, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
+ IAPDESCR(52H_01H, 0x52, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(53H_01H, 0x53, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
IAPDESCR(61H, 0x61, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
IAPDESCR(61H_00H, 0x61, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(62H, 0x62, IAP_M_AGENT, IAP_F_ALLCPUS),
+ IAPDESCR(62H, 0x62, IAP_M_AGENT, IAP_F_ALLCPUSCORE2),
IAPDESCR(62H_00H, 0x62, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(63H, 0x63, IAP_M_AGENT | IAP_M_CORE,
IAP_F_CA | IAP_F_CC2),
IAPDESCR(63H, 0x63, IAP_M_CORE, IAP_F_CC),
+ IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(64H, 0x64, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(64H_40H, 0x64, 0x40, IAP_F_FM | IAP_F_CC),
@@ -723,16 +893,18 @@ static struct iap_event_descr iap_events[] = {
IAP_F_CA | IAP_F_CC2),
IAPDESCR(65H, 0x65, IAP_M_CORE, IAP_F_CC),
- IAPDESCR(66H, 0x66, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
+ IAPDESCR(66H, 0x66, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(67H, 0x67, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(67H, 0x67, IAP_M_AGENT, IAP_F_CC),
- IAPDESCR(68H, 0x68, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
- IAPDESCR(69H, 0x69, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
- IAPDESCR(6AH, 0x6A, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
- IAPDESCR(6BH, 0x6B, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
- IAPDESCR(6CH, 0x6C, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
+ IAPDESCR(68H, 0x68, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(69H, 0x69, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(6AH, 0x6A, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(6BH, 0x6B, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+
+ IAPDESCR(6CH, 0x6C, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
+ IAPDESCR(6CH_01H, 0x6C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(6DH, 0x6D, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(6DH, 0x6D, IAP_M_CORE, IAP_F_CC),
@@ -757,47 +929,89 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(7BH, 0x7B, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
- IAPDESCR(7DH, 0x7D, IAP_M_CORE, IAP_F_ALLCPUS),
+ IAPDESCR(7DH, 0x7D, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(7EH, 0x7E, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(7EH_00H, 0x7E, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(7FH, 0x7F, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
- IAPDESCR(80H_00H, 0x80, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(80H_02H, 0x80, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_I7),
- IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA | IAP_F_I7),
+ IAPDESCR(80H_00H, 0x80, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(80H_01H, 0x80, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(80H_02H, 0x80, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM),
+ IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM),
+ IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(81H_00H, 0x81, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(81H_00H, 0x81, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(81H_01H, 0x81, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(81H_02H, 0x81, 0x02, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(82H_01H, 0x82, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(82H_02H, 0x82, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(82H_04H, 0x82, 0x04, IAP_F_FM | IAP_F_CA),
IAPDESCR(82H_10H, 0x82, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(82H_12H, 0x82, 0x12, IAP_F_FM | IAP_F_CC2),
IAPDESCR(82H_40H, 0x82, 0x40, IAP_F_FM | IAP_F_CC2),
+ IAPDESCR(83H_01H, 0x83, 0x01, IAP_F_FM | IAP_F_I7O),
IAPDESCR(83H_02H, 0x83, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(85H_00H, 0x85, 0x00, IAP_F_FM | IAP_F_CC),
-
- IAPDESCR(86H_00H, 0x86, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
-
- IAPDESCR(87H_00H, 0x87, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
-
- IAPDESCR(88H_00H, 0x88, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(89H_00H, 0x89, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(8AH_00H, 0x8A, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(8BH_00H, 0x8B, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(8CH_00H, 0x8C, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(8DH_00H, 0x8D, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(8EH_00H, 0x8E, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(8FH_00H, 0x8F, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
-
- IAPDESCR(90H_00H, 0x90, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(91H_00H, 0x91, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(92H_00H, 0x92, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(93H_00H, 0x93, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(94H_00H, 0x94, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(85H_80H, 0x85, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+
+ IAPDESCR(86H_00H, 0x86, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+
+ IAPDESCR(87H_00H, 0x87, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(87H_02H, 0x87, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(87H_08H, 0x87, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(87H_0FH, 0x87, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(88H_00H, 0x88, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_07H, 0x88, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_30H, 0x88, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_7FH, 0x88, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(89H_00H, 0x89, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_02H, 0x89, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_07H, 0x89, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_30H, 0x89, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(8AH_00H, 0x8A, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(8BH_00H, 0x8B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(8CH_00H, 0x8C, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(8DH_00H, 0x8D, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(8EH_00H, 0x8E, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(8FH_00H, 0x8F, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+
+ IAPDESCR(90H_00H, 0x90, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(91H_00H, 0x91, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(92H_00H, 0x92, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(93H_00H, 0x93, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(94H_00H, 0x94, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(97H_00H, 0x97, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(98H_00H, 0x98, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -811,6 +1025,18 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(A1H_20H, 0xA1, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(A2H_00H, 0xA2, 0x00, IAP_F_FM | IAP_F_CC),
+ IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(AAH_01H, 0xAA, 0x01, IAP_F_FM | IAP_F_CC2),
IAPDESCR(AAH_02H, 0xAA, 0x02, IAP_F_FM | IAP_F_CA),
@@ -820,18 +1046,42 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(ABH_01H, 0xAB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(ABH_02H, 0xAB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(B0H_00H, 0xB0, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B0H_80H, 0xB0, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7),
-
- IAPDESCR(B1H_00H, 0xB1, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B1H_80H, 0xB1, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7),
-
- IAPDESCR(B3H_01H, 0xB3, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B3H_02H, 0xB3, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B3H_04H, 0xB3, 0x04, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B3H_08H, 0xB3, 0x08, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B3H_10H, 0xB3, 0x10, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(B3H_20H, 0xB3, 0x20, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(AEH_01H, 0xAE, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(B0H_00H, 0xB0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_10H, 0xB0, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B0H_80H, 0xB0, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_WM | IAP_F_I7O),
+
+ IAPDESCR(B1H_00H, 0xB1, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_1FH, 0xB1, 0x1F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_20H, 0xB1, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_3FH, 0xB1, 0x3F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_40H, 0xB1, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_80H, 0xB1, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM),
+
+ IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(B3H_01H, 0xB3, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B3H_02H, 0xB3, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B3H_04H, 0xB3, 0x04, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B3H_08H, 0xB3, 0x08, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(B3H_10H, 0xB3, 0x10, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(B3H_20H, 0xB3, 0x20, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(B3H_81H, 0xB3, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(B3H_82H, 0xB3, 0x82, IAP_F_FM | IAP_F_CA),
IAPDESCR(B3H_84H, 0xB3, 0x84, IAP_F_FM | IAP_F_CA),
@@ -839,10 +1089,28 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(B3H_90H, 0xB3, 0x90, IAP_F_FM | IAP_F_CA),
IAPDESCR(B3H_A0H, 0xB3, 0xA0, IAP_F_FM | IAP_F_CA),
- IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C0H_04H, 0xC0, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(B4H_01H, 0xB4, 0x01, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(B4H_02H, 0xB4, 0x02, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(B4H_04H, 0xB4, 0x04, IAP_F_FM | IAP_F_WM),
+
+ IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(B8H_01H, 0xB8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B8H_02H, 0xB8, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B8H_04H, 0xB8, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(BAH_01H, 0xBA, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(BAH_02H, 0xBA, 0x02, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(BBH_01H, 0xBB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C0H_04H, 0xC0, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(C0H_08H, 0xC0, 0x08, IAP_F_FM | IAP_F_CC2E),
IAPDESCR(C1H_00H, 0xC1, 0x00, IAP_F_FM | IAP_F_CC),
@@ -850,43 +1118,64 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(C1H_FEH, 0xC1, 0xFE, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C2H_00H, 0xC2, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(C2H_01H, 0xC2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(C2H_01H, 0xC2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(C2H_07H, 0xC2, 0x07, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C2H_08H, 0xC2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C2H_0FH, 0xC2, 0x0F, IAP_F_FM | IAP_F_CC2),
IAPDESCR(C2H_10H, 0xC2, 0x10, IAP_F_FM | IAP_F_CA),
IAPDESCR(C3H_00H, 0xC3, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(C3H_01H, 0xC3, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
-
- IAPDESCR(C4H_00H, 0xC4, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(C4H_01H, 0xC4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(C3H_01H, 0xC3, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(C4H_00H, 0xC4, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C4H_01H, 0xC4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(C4H_08H, 0xC4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C4H_0CH, 0xC4, 0x0C, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C4H_0FH, 0xC4, 0x0F, IAP_F_FM | IAP_F_CA),
- IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C5H_01H, 0xC5, 0x01, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C5H_04H, 0xC5, 0x04, IAP_F_FM | IAP_F_WM),
IAPDESCR(C6H_00H, 0xC6, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(C6H_01H, 0xC6, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C6H_02H, 0xC6, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C7H_00H, 0xC7, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(C7H_01H, 0xC7, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C7H_02H, 0xC7, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C7H_04H, 0xC7, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C7H_08H, 0xC7, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(C7H_10H, 0xC7, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(C7H_01H, 0xC7, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C7H_02H, 0xC7, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C7H_04H, 0xC7, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C7H_08H, 0xC7, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C7H_10H, 0xC7, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(C7H_1FH, 0xC7, 0x1F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C8H_00H, 0xC8, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(C8H_00H, 0xC8, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(C8H_20H, 0xC8, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(C9H_00H, 0xC9, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(C9H_00H, 0xC9, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(CAH_00H, 0xCA, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(CAH_01H, 0xCA, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -894,36 +1183,59 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(CAH_04H, 0xCA, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(CAH_08H, 0xCA, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CBH_01H, 0xCB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(CBH_02H, 0xCB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(CBH_04H, 0xCB, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(CBH_08H, 0xCB, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(CBH_10H, 0xCB, 0x10, IAP_F_FM | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(CBH_01H, 0xCB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CBH_02H, 0xCB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CBH_04H, 0xCB, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CBH_08H, 0xCB, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CBH_10H, 0xCB, 0x10, IAP_F_FM | IAP_F_CC2 | IAP_F_I7 |
+ IAP_F_WM),
+ IAPDESCR(CBH_40H, 0xCB, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CBH_80H, 0xCB, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(CCH_00H, 0xCC, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(CCH_01H, 0xCC, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(CCH_02H, 0xCC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
-
- IAPDESCR(CDH_00H, 0xCD, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(CEH_00H, 0xCE, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+ IAPDESCR(CCH_01H, 0xCC, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CCH_02H, 0xCC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CCH_03H, 0xCC, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(CDH_00H, 0xCD, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(CEH_00H, 0xCE, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(CFH_00H, 0xCF, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D0H_00H, 0xD0, 0x00, IAP_F_FM | IAP_F_CC),
-
- IAPDESCR(D2H_01H, 0xD2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
- IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(D1H_01H, 0xD1, 0x01, IAP_F_FM | IAP_F_WM),
+ IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(D2H_01H, 0xD2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(D2H_10H, 0xD2, 0x10, IAP_F_FM | IAP_F_CC2E),
- IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(D4H_02H, 0xD4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D4H_04H, 0xD4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D4H_08H, 0xD4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D4H_0FH, 0xD4, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(D5H_01H, 0xD5, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
+ IAPDESCR(D5H_01H, 0xD5, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_I7 | IAP_F_WM),
IAPDESCR(D5H_02H, 0xD5, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D5H_04H, 0xD5, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D5H_08H, 0xD5, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -947,6 +1259,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(DAH_02H, 0xDA, 0x02, IAP_F_FM | IAP_F_CC),
IAPDESCR(DBH_00H, 0xDB, 0x00, IAP_F_FM | IAP_F_CC),
+ IAPDESCR(DBH_01H, 0xDB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(DCH_01H, 0xDC, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(DCH_02H, 0xDC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -956,276 +1269,76 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(DCH_1FH, 0xDC, 0x1F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(E0H_00H, 0xE0, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(E0H_01H, 0xE0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
+ IAPDESCR(E0H_01H, 0xE0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM),
IAPDESCR(E2H_00H, 0xE2, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(E4H_00H, 0xE4, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
+
+ IAPDESCR(E4H_00H, 0xE4, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(E4H_01H, 0xE4, 0x01, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(E5H_01H, 0xE5, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(E6H_00H, 0xE6, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_CA),
-
- IAPDESCR(F0H_00H, 0xF0, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
- IAPDESCR(F8H_00H, 0xF8, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
-
- /* Added with nehalem. */
- IAPDESCR(02H_01H, 0x02, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(03H_01H, 0x03, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(05H_03H, 0x05, 0x03, IAP_F_FM | IAP_F_I7),
- IAPDESCR(06H_01H, 0x06, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(06H_02H, 0x06, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(06H_04H, 0x06, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(06H_08H, 0x06, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(06H_0FH, 0x06, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(09H_04H, 0x09, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(09H_08H, 0x09, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0BH_01H, 0x0B, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0BH_02H, 0x0B, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0EH_02H, 0x0E, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0FH_02H, 0x0F, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0FH_08H, 0x0F, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0FH_10H, 0x0F, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(0FH_20H, 0x0F, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_02H, 0x10, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_04H, 0x10, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_08H, 0x10, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(12H_02H, 0x12, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(12H_04H, 0x12, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(12H_08H, 0x12, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(12H_10H, 0x12, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(12H_20H, 0x12, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(12H_40H, 0x12, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(13H_02H, 0x13, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(13H_04H, 0x13, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(13H_07H, 0x13, 0x07, IAP_F_FM | IAP_F_I7),
- IAPDESCR(14H_02H, 0x14, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(17H_01H, 0x17, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(18H_01H, 0x18, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(1DH_01H, 0x1D, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(1DH_02H, 0x1D, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(1DH_04H, 0x1D, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(1EH_01H, 0x1E, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_01H, 0x24, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_02H, 0x24, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_03H, 0x24, 0x03, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_04H, 0x24, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_08H, 0x24, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_0CH, 0x24, 0x0C, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_10H, 0x24, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7),
- IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_01H, 0x26, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_02H, 0x26, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_04H, 0x26, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_08H, 0x26, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_0FH, 0x26, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_10H, 0x26, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_20H, 0x26, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_40H, 0x26, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_80H, 0x26, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_F0H, 0x26, 0xF0, IAP_F_FM | IAP_F_I7),
- IAPDESCR(26H_FFH, 0x26, 0xFF, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_01H, 0x27, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_02H, 0x27, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_04H, 0x27, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_08H, 0x27, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_0EH, 0x27, 0x0E, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_0FH, 0x27, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_10H, 0x27, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_20H, 0x27, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_40H, 0x27, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_80H, 0x27, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_E0H, 0x27, 0xE0, IAP_F_FM | IAP_F_I7),
- IAPDESCR(27H_F0H, 0x27, 0xF0, IAP_F_FM | IAP_F_I7),
- IAPDESCR(28H_01H, 0x28, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(28H_02H, 0x28, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(28H_04H, 0x28, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(28H_08H, 0x28, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(28H_0FH, 0x28, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(3DH_01H, 0x3D, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(40H_01H, 0x40, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(40H_02H, 0x40, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(40H_04H, 0x40, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(40H_08H, 0x40, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(40H_0FH, 0x40, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(41H_01H, 0x41, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(41H_02H, 0x41, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(41H_04H, 0x41, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(41H_08H, 0x41, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(41H_0FH, 0x41, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(42H_01H, 0x42, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(42H_02H, 0x42, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(42H_04H, 0x42, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(42H_08H, 0x42, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(48H_02H, 0x48, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4BH_08H, 0x4B, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4DH_01H, 0x4D, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4EH_01H, 0x4E, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4EH_02H, 0x4E, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4EH_04H, 0x4E, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4FH_02H, 0x4F, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4FH_04H, 0x4F, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(4FH_08H, 0x4F, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(51H_08H, 0x51, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(52H_01H, 0x52, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(53H_01H, 0x53, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(6CH_01H, 0x6C, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(80H_01H, 0x80, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(80H_10H, 0x80, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(81H_01H, 0x81, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(81H_02H, 0x81, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(82H_01H, 0x82, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(83H_01H, 0x83, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(85H_80H, 0x85, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(87H_02H, 0x87, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(87H_08H, 0x87, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(87H_0FH, 0x87, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_07H, 0x88, 0x07, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_30H, 0x88, 0x30, IAP_F_FM | IAP_F_I7),
- IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_02H, 0x89, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_07H, 0x89, 0x07, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_30H, 0x89, 0x30, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_20H, 0xB1, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B1H_40H, 0xB1, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B8H_01H, 0xB8, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B8H_02H, 0xB8, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(B8H_04H, 0xB8, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(BAH_01H, 0xBA, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(BAH_02H, 0xBA, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(C8H_20H, 0xC8, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(CBH_40H, 0xCB, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(CBH_80H, 0xCB, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(CCH_03H, 0xCC, 0x03, IAP_F_FM | IAP_F_I7),
- IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(DBH_01H, 0xDB, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(E4H_01H, 0xE4, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(E5H_01H, 0xE5, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(E8H_01H, 0xE8, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(E8H_02H, 0xE8, 0x02, IAP_F_FM | IAP_F_I7),
+ IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM),
+ IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(E8H_01H, 0xE8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(E8H_02H, 0xE8, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(E8H_03H, 0xE8, 0x03, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F2H_0FH, 0xF2, 0x0F, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F3H_01H, 0xF3, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F3H_02H, 0xF3, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F3H_04H, 0xF3, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F3H_08H, 0xF3, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F3H_10H, 0xF3, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F3H_20H, 0xF3, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F4H_01H, 0xF4, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F4H_02H, 0xF4, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F4H_04H, 0xF4, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F4H_08H, 0xF4, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F4H_10H, 0xF4, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F6H_01H, 0xF6, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F7H_01H, 0xF7, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F7H_02H, 0xF7, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F7H_04H, 0xF7, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(F8H_01H, 0xF8, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_01H, 0xFD, 0x01, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_02H, 0xFD, 0x02, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_04H, 0xFD, 0x04, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_08H, 0xFD, 0x08, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_10H, 0xFD, 0x10, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_20H, 0xFD, 0x20, IAP_F_FM | IAP_F_I7),
- IAPDESCR(FDH_40H, 0xFD, 0x40, IAP_F_FM | IAP_F_I7),
+
+ IAPDESCR(ECH_01H, 0xEC, 0x01, IAP_F_FM | IAP_F_WM),
+
+ IAPDESCR(F0H_00H, 0xF0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F2H_0FH, 0xF2, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(F3H_01H, 0xF3, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F3H_02H, 0xF3, 0x02, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F3H_04H, 0xF3, 0x04, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F3H_08H, 0xF3, 0x08, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F3H_10H, 0xF3, 0x10, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F3H_20H, 0xF3, 0x20, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(F4H_01H, 0xF4, 0x01, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F4H_02H, 0xF4, 0x02, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F4H_04H, 0xF4, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(F4H_08H, 0xF4, 0x08, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(F4H_10H, 0xF4, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(F6H_01H, 0xF6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
+ IAPDESCR(F7H_01H, 0xF7, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(F7H_02H, 0xF7, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(F7H_04H, 0xF7, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+
+ IAPDESCR(F8H_00H, 0xF8, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(F8H_01H, 0xF8, 0x01, IAP_F_FM | IAP_F_I7O),
+
+ IAPDESCR(FDH_01H, 0xFD, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(FDH_02H, 0xFD, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(FDH_04H, 0xFD, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(FDH_08H, 0xFD, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(FDH_10H, 0xFD, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(FDH_20H, 0xFD, 0x20, IAP_F_FM | IAP_F_WM | IAP_F_I7),
+ IAPDESCR(FDH_40H, 0xFD, 0x40, IAP_F_FM | IAP_F_WM | IAP_F_I7),
};
static const int niap_events = sizeof(iap_events) / sizeof(iap_events[0]);
@@ -1299,6 +1412,80 @@ iap_architectural_event_is_unsupported(enum pmc_event pe)
}
static int
+iap_event_corei7_ok_on_counter(enum pmc_event pe, int ri)
+{
+ uint32_t mask;
+
+ switch (pe) {
+ /*
+ * Events valid only on counter 0, 1.
+ */
+ case PMC_EV_IAP_EVENT_40H_01H:
+ case PMC_EV_IAP_EVENT_40H_02H:
+ case PMC_EV_IAP_EVENT_40H_04H:
+ case PMC_EV_IAP_EVENT_40H_08H:
+ case PMC_EV_IAP_EVENT_40H_0FH:
+ case PMC_EV_IAP_EVENT_41H_02H:
+ case PMC_EV_IAP_EVENT_41H_04H:
+ case PMC_EV_IAP_EVENT_41H_08H:
+ case PMC_EV_IAP_EVENT_42H_01H:
+ case PMC_EV_IAP_EVENT_42H_02H:
+ case PMC_EV_IAP_EVENT_42H_04H:
+ case PMC_EV_IAP_EVENT_42H_08H:
+ case PMC_EV_IAP_EVENT_43H_01H:
+ case PMC_EV_IAP_EVENT_43H_02H:
+ case PMC_EV_IAP_EVENT_48H_02H:
+ case PMC_EV_IAP_EVENT_51H_01H:
+ case PMC_EV_IAP_EVENT_51H_02H:
+ case PMC_EV_IAP_EVENT_51H_04H:
+ case PMC_EV_IAP_EVENT_51H_08H:
+ case PMC_EV_IAP_EVENT_63H_01H:
+ case PMC_EV_IAP_EVENT_63H_02H:
+ mask = 0x3;
+ break;
+
+ default:
+ mask = ~0; /* Any row index is ok. */
+ }
+
+ return (mask & (1 << ri));
+}
+
+static int
+iap_event_westmere_ok_on_counter(enum pmc_event pe, int ri)
+{
+ uint32_t mask;
+
+ switch (pe) {
+ /*
+ * Events valid only on counter 0.
+ */
+ case PMC_EV_IAP_EVENT_B3H_01H:
+ case PMC_EV_IAP_EVENT_B3H_02H:
+ case PMC_EV_IAP_EVENT_B3H_04H:
+ mask = 0x1;
+ break;
+
+ /*
+ * Events valid only on counter 0, 1.
+ */
+ case PMC_EV_IAP_EVENT_51H_01H:
+ case PMC_EV_IAP_EVENT_51H_02H:
+ case PMC_EV_IAP_EVENT_51H_04H:
+ case PMC_EV_IAP_EVENT_51H_08H:
+ case PMC_EV_IAP_EVENT_63H_01H:
+ case PMC_EV_IAP_EVENT_63H_02H:
+ mask = 0x3;
+ break;
+
+ default:
+ mask = ~0; /* Any row index is ok. */
+ }
+
+ return (mask & (1 << ri));
+}
+
+static int
iap_event_ok_on_counter(enum pmc_event pe, int ri)
{
uint32_t mask;
@@ -1310,6 +1497,9 @@ iap_event_ok_on_counter(enum pmc_event pe, int ri)
case PMC_EV_IAP_EVENT_10H_00H:
case PMC_EV_IAP_EVENT_14H_00H:
case PMC_EV_IAP_EVENT_18H_00H:
+ case PMC_EV_IAP_EVENT_B3H_01H:
+ case PMC_EV_IAP_EVENT_B3H_02H:
+ case PMC_EV_IAP_EVENT_B3H_04H:
case PMC_EV_IAP_EVENT_C1H_00H:
case PMC_EV_IAP_EVENT_CBH_01H:
case PMC_EV_IAP_EVENT_CBH_02H:
@@ -1356,8 +1546,19 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
if (iap_architectural_event_is_unsupported(ev))
return (EOPNOTSUPP);
- if (iap_event_ok_on_counter(ev, ri) == 0)
- return (EINVAL);
+ switch (core_cputype) {
+ case PMC_CPU_INTEL_COREI7:
+ if (iap_event_corei7_ok_on_counter(ev, ri) == 0)
+ return (EINVAL);
+ break;
+ case PMC_CPU_INTEL_WESTMERE:
+ if (iap_event_westmere_ok_on_counter(ev, ri) == 0)
+ return (EINVAL);
+ break;
+ default:
+ if (iap_event_ok_on_counter(ev, ri) == 0)
+ return (EINVAL);
+ }
/*
* Look for an event descriptor with matching CPU and event id
@@ -1381,6 +1582,9 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
case PMC_CPU_INTEL_COREI7:
cpuflag = IAP_F_I7;
break;
+ case PMC_CPU_INTEL_WESTMERE:
+ cpuflag = IAP_F_WM;
+ break;
}
for (n = 0, ie = iap_events; n < niap_events; n++, ie++)
@@ -1469,6 +1673,22 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
else if (config & IAP_ANY)
return (EINVAL);
+ /*
+ * Check offcore response configuration.
+ */
+ if (a->pm_md.pm_iap.pm_iap_rsp != 0) {
+ if (ev != PMC_EV_IAP_EVENT_B7H_01H &&
+ ev != PMC_EV_IAP_EVENT_BBH_01H)
+ return (EINVAL);
+ if (core_cputype == PMC_CPU_INTEL_COREI7 &&
+ ev == PMC_EV_IAP_EVENT_BBH_01H)
+ return (EINVAL);
+ if ( a->pm_md.pm_iap.pm_iap_rsp & ~IA_OFFCORE_RSP_MASK)
+ return (EINVAL);
+ pm->pm_md.pm_iap.pm_iap_rsp =
+ a->pm_md.pm_iap.pm_iap_rsp & IA_OFFCORE_RSP_MASK;
+ }
+
if (caps & PMC_CAP_THRESHOLD)
evsel |= (a->pm_md.pm_iap.pm_iap_config & IAP_F_CMASK);
if (caps & PMC_CAP_USER)
@@ -1628,6 +1848,18 @@ iap_start_pmc(int cpu, int ri)
PMCDBG(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
cpu, ri, IAP_EVSEL0 + ri, evsel);
+ /* Event specific configuration. */
+ switch (pm->pm_event) {
+ case PMC_EV_IAP_EVENT_B7H_01H:
+ wrmsr(IA_OFFCORE_RSP0, pm->pm_md.pm_iap.pm_iap_rsp);
+ break;
+ case PMC_EV_IAP_EVENT_BBH_01H:
+ wrmsr(IA_OFFCORE_RSP1, pm->pm_md.pm_iap.pm_iap_rsp);
+ break;
+ default:
+ break;
+ }
+
wrmsr(IAP_EVSEL0 + ri, evsel | IAP_EN);
if (core_cputype == PMC_CPU_INTEL_CORE)
@@ -1863,6 +2095,8 @@ core2_intr(int cpu, struct trapframe *tf)
error = pmc_process_interrupt(cpu, pm, tf,
TRAPF_USERMODE(tf));
+ if (error)
+ intrenable &= ~flag;
v = iaf_reload_count_to_perfctr_value(pm->pm_sc.pm_reloadcount);
@@ -1871,9 +2105,6 @@ core2_intr(int cpu, struct trapframe *tf)
PMCDBG(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", cpu, error,
(uintmax_t) v, (uintmax_t) rdpmc(IAF_RI_TO_MSR(n)));
-
- if (error)
- intrenable &= ~flag;
}
/*
diff --git a/sys/dev/hwpmc/hwpmc_core.h b/sys/dev/hwpmc/hwpmc_core.h
index 0c4ee5b..e88ecb0 100644
--- a/sys/dev/hwpmc/hwpmc_core.h
+++ b/sys/dev/hwpmc/hwpmc_core.h
@@ -46,6 +46,7 @@ struct pmc_md_iaf_op_pmcallocate {
*/
struct pmc_md_iap_op_pmcallocate {
uint32_t pm_iap_config;
+ uint32_t pm_iap_rsp;
};
#define IAP_EVSEL(C) ((C) & 0xFF)
@@ -59,6 +60,8 @@ struct pmc_md_iap_op_pmcallocate {
#define IAP_INV (1 << 23)
#define IAP_CMASK(C) (((C) & 0xFF) << 24)
+#define IA_OFFCORE_RSP_MASK 0xF7FF
+
#ifdef _KERNEL
/*
@@ -76,16 +79,15 @@ struct pmc_md_iap_op_pmcallocate {
/*
* Programmable counters.
*/
-#define IAP_PMC0 0x0C1
-#define IAP_PMC1 0x0C2
+#define IAP_PMC0 0x0C1
#define IAP_EVSEL0 0x186
-#define IAP_EVSEL1 0x187
/*
* Simplified programming interface in Intel Performance Architecture
* v2 and later.
*/
+
#define IA_GLOBAL_STATUS 0x38E
#define IA_GLOBAL_CTRL 0x38F
#define IA_GLOBAL_OVF_CTRL 0x390
@@ -93,12 +95,19 @@ struct pmc_md_iap_op_pmcallocate {
#define IA_GLOBAL_STATUS_FLAG_CONDCHG (1ULL << 63)
#define IA_GLOBAL_STATUS_FLAG_OVFBUF (1ULL << 62)
+/*
+ * Offcore response configuration.
+ */
+#define IA_OFFCORE_RSP0 0x1A6
+#define IA_OFFCORE_RSP1 0x1A7
+
struct pmc_md_iaf_pmc {
uint64_t pm_iaf_ctrl;
};
struct pmc_md_iap_pmc {
uint32_t pm_iap_evsel;
+ uint32_t pm_iap_rsp;
};
/*
diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c
index e953f68..82d5079 100644
--- a/sys/dev/hwpmc/hwpmc_intel.c
+++ b/sys/dev/hwpmc/hwpmc_intel.c
@@ -133,8 +133,14 @@ pmc_intel_initialize(void)
case 0x1A:
case 0x1E: /* Per Intel document 253669-032 9/2009, pages A-2 and A-57 */
case 0x1F: /* Per Intel document 253669-032 9/2009, pages A-2 and A-57 */
+ case 0x2E:
cputype = PMC_CPU_INTEL_COREI7;
- nclasses = 3;
+ nclasses = 5;
+ break;
+ case 0x25: /* Per Intel document 253669-033US 12/2009. */
+ case 0x2C: /* Per Intel document 253669-033US 12/2009. */
+ cputype = PMC_CPU_INTEL_WESTMERE;
+ nclasses = 5;
break;
}
break;
@@ -176,6 +182,7 @@ pmc_intel_initialize(void)
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_WESTMERE:
error = pmc_core_initialize(pmc_mdep, ncpus);
break;
@@ -226,6 +233,22 @@ pmc_intel_initialize(void)
KASSERT(0, ("[intel,%d] Unknown CPU type", __LINE__));
}
+ /*
+ * Init the uncore class.
+ */
+#if defined(__i386__) || defined(__amd64__)
+ switch (cputype) {
+ /*
+ * Intel Corei7 and Westmere processors.
+ */
+ case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_WESTMERE:
+ error = pmc_uncore_initialize(pmc_mdep, ncpus);
+ break;
+ default:
+ break;
+ }
+#endif
error:
if (error) {
@@ -247,6 +270,8 @@ pmc_intel_finalize(struct pmc_mdep *md)
case PMC_CPU_INTEL_CORE:
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
+ case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_WESTMERE:
pmc_core_finalize(md);
break;
@@ -269,4 +294,18 @@ pmc_intel_finalize(struct pmc_mdep *md)
default:
KASSERT(0, ("[intel,%d] unknown CPU type", __LINE__));
}
+
+ /*
+ * Uncore.
+ */
+#if defined(__i386__) || defined(__amd64__)
+ switch (md->pmd_cputype) {
+ case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_WESTMERE:
+ pmc_uncore_finalize(md);
+ break;
+ default:
+ break;
+ }
+#endif
}
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index a36a8dc..633c6f9 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -237,7 +237,7 @@ pmclog_get_buffer(struct pmc_owner *po)
static void
pmclog_loop(void *arg)
{
- int error;
+ int error, last_buffer;
struct pmc_owner *po;
struct pmclog_buffer *lb;
struct proc *p;
@@ -252,6 +252,7 @@ pmclog_loop(void *arg)
p = po->po_owner;
td = curthread;
mycred = td->td_ucred;
+ last_buffer = 0;
PROC_LOCK(p);
ownercred = crhold(p->p_ucred);
@@ -284,22 +285,14 @@ pmclog_loop(void *arg)
if ((lb = TAILQ_FIRST(&po->po_logbuffers)) == NULL) {
mtx_unlock_spin(&po->po_mtx);
- /*
- * Wakeup the thread waiting for the
- * PMC_OP_FLUSHLOG request to
- * complete.
- */
- if (po->po_flags & PMC_PO_IN_FLUSH) {
- po->po_flags &= ~PMC_PO_IN_FLUSH;
- wakeup_one(po->po_kthread);
- }
-
(void) msleep(po, &pmc_kthread_mtx, PWAIT,
"pmcloop", 0);
continue;
}
TAILQ_REMOVE(&po->po_logbuffers, lb, plb_next);
+ if (po->po_flags & PMC_PO_SHUTDOWN)
+ last_buffer = TAILQ_EMPTY(&po->po_logbuffers);
mtx_unlock_spin(&po->po_mtx);
}
@@ -328,8 +321,6 @@ pmclog_loop(void *arg)
if (error) {
/* XXX some errors are recoverable */
- /* XXX also check for SIGPIPE if a socket */
-
/* send a SIGIO to the owner and exit */
PROC_LOCK(p);
psignal(p, SIGIO);
@@ -344,6 +335,14 @@ pmclog_loop(void *arg)
break;
}
+ if (last_buffer) {
+ /*
+ * Close the file to get PMCLOG_EOF error
+ * in pmclog(3).
+ */
+ fo_close(po->po_file, curthread);
+ }
+
mtx_lock(&pmc_kthread_mtx);
/* put the used buffer back into the global pool */
@@ -425,6 +424,12 @@ pmclog_reserve(struct pmc_owner *po, int length)
mtx_lock_spin(&po->po_mtx);
+ /* No more data when shutdown in progress. */
+ if (po->po_flags & PMC_PO_SHUTDOWN) {
+ mtx_unlock_spin(&po->po_mtx);
+ return (NULL);
+ }
+
if (po->po_curbuf == NULL)
if (pmclog_get_buffer(po) != 0) {
mtx_unlock_spin(&po->po_mtx);
@@ -686,7 +691,7 @@ pmclog_deconfigure_log(struct pmc_owner *po)
int
pmclog_flush(struct pmc_owner *po)
{
- int error, has_pending_buffers;
+ int error;
PMCDBG(LOG,FLS,1, "po=%p", po);
@@ -714,16 +719,13 @@ pmclog_flush(struct pmc_owner *po)
mtx_lock_spin(&po->po_mtx);
if (po->po_curbuf)
pmclog_schedule_io(po);
- has_pending_buffers = !TAILQ_EMPTY(&po->po_logbuffers);
mtx_unlock_spin(&po->po_mtx);
- if (has_pending_buffers) {
- po->po_flags |= PMC_PO_IN_FLUSH; /* ask for a wakeup */
- error = msleep(po->po_kthread, &pmc_kthread_mtx, PWAIT,
- "pmcflush", 0);
- if (error == 0)
- error = po->po_error;
- }
+ /*
+ * Initiate shutdown: no new data queued,
+ * thread will close file on last block.
+ */
+ po->po_flags |= PMC_PO_SHUTDOWN;
error:
mtx_unlock(&pmc_kthread_mtx);
diff --git a/sys/dev/hwpmc/hwpmc_mips.c b/sys/dev/hwpmc/hwpmc_mips.c
new file mode 100644
index 0000000..69ad445
--- /dev/null
+++ b/sys/dev/hwpmc/hwpmc_mips.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2010, George V. Neville-Neil <gnn@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 <sys/param.h>
+#include <sys/pmc.h>
+#include <sys/systm.h>
+
+#include <machine/pmc_mdep.h>
+#include <machine/md_var.h>
+
+struct pmc_mdep *
+pmc_md_initialize()
+{
+ /* if (cpu_class == CPU_CLASS_MIPS24K)*/
+ return pmc_mips24k_initialize();
+ /* else
+ return NULL;*/
+}
+
+void
+pmc_md_finalize(struct pmc_mdep *md)
+{
+ /* if (cpu_class == CPU_CLASS_MIPS24K) */
+ pmc_mips24k_finalize(md);
+ /* else
+ KASSERT(0, ("[mips,%d] Unknown CPU Class 0x%x", __LINE__,
+ cpu_class));*/
+}
+
+int
+pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples,
+ struct trapframe *tf)
+{
+ (void) cc;
+ (void) maxsamples;
+ (void) tf;
+ return (0);
+}
+
+int
+pmc_save_user_callchain(uintptr_t *cc, int maxsamples,
+ struct trapframe *tf)
+{
+ (void) cc;
+ (void) maxsamples;
+ (void) tf;
+ return (0);
+}
diff --git a/sys/dev/hwpmc/hwpmc_mips24k.c b/sys/dev/hwpmc/hwpmc_mips24k.c
new file mode 100644
index 0000000..0b2a117
--- /dev/null
+++ b/sys/dev/hwpmc/hwpmc_mips24k.c
@@ -0,0 +1,570 @@
+/*-
+ * Copyright (c) 2010 George V. Neville-Neil <gnn@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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/pmc.h>
+#include <sys/pmckern.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/cputypes.h>
+#include <machine/pmc_mdep.h>
+
+/*
+ * Support for MIPS CPUs
+ *
+ */
+static int mips24k_npmcs;
+
+struct mips24k_event_code_map {
+ enum pmc_event pe_ev; /* enum value */
+ uint8_t pe_counter; /* Which counter this can be counted in. */
+ uint8_t pe_code; /* numeric code */
+};
+
+/*
+ * MIPS event codes are encoded with a select bit. The
+ * select bit is used when writing to CP0 so that we
+ * can select either counter 0/2 or 1/3. The cycle
+ * and instruction counters are special in that they
+ * can be counted on either 0/2 or 1/3.
+ */
+
+#define MIPS24K_ALL 255 /* Count events in any counter. */
+#define MIPS24K_CTR_0 0 /* Counter 0 Event */
+#define MIPS24K_CTR_1 1 /* Counter 1 Event */
+
+const struct mips24k_event_code_map mips24k_event_codes[] = {
+ { PMC_EV_MIPS24K_CYCLE, MIPS24K_ALL, 0},
+ { PMC_EV_MIPS24K_INSTR_EXECUTED, MIPS24K_ALL, 1},
+ { PMC_EV_MIPS24K_BRANCH_COMPLETED, MIPS24K_CTR_0, 2},
+ { PMC_EV_MIPS24K_BRANCH_MISPRED, MIPS24K_CTR_1, 2},
+ { PMC_EV_MIPS24K_RETURN, MIPS24K_CTR_0, 3},
+ { PMC_EV_MIPS24K_RETURN_MISPRED, MIPS24K_CTR_1, 3},
+ { PMC_EV_MIPS24K_RETURN_NOT_31, MIPS24K_CTR_0, 4},
+ { PMC_EV_MIPS24K_RETURN_NOTPRED, MIPS24K_CTR_1, 4},
+ { PMC_EV_MIPS24K_ITLB_ACCESS, MIPS24K_CTR_0, 5},
+ { PMC_EV_MIPS24K_ITLB_MISS, MIPS24K_CTR_1, 5},
+ { PMC_EV_MIPS24K_DTLB_ACCESS, MIPS24K_CTR_0, 6},
+ { PMC_EV_MIPS24K_DTLB_MISS, MIPS24K_CTR_1, 6},
+ { PMC_EV_MIPS24K_JTLB_IACCESS, MIPS24K_CTR_0, 7},
+ { PMC_EV_MIPS24K_JTLB_IMISS, MIPS24K_CTR_1, 7},
+ { PMC_EV_MIPS24K_JTLB_DACCESS, MIPS24K_CTR_0, 8},
+ { PMC_EV_MIPS24K_JTLB_DMISS, MIPS24K_CTR_1, 8},
+ { PMC_EV_MIPS24K_IC_FETCH, MIPS24K_CTR_0, 9},
+ { PMC_EV_MIPS24K_IC_MISS, MIPS24K_CTR_1, 9},
+ { PMC_EV_MIPS24K_DC_LOADSTORE, MIPS24K_CTR_0, 10},
+ { PMC_EV_MIPS24K_DC_WRITEBACK, MIPS24K_CTR_1, 10},
+ { PMC_EV_MIPS24K_DC_MISS, MIPS24K_ALL, 11},
+ /* 12 reserved */
+ { PMC_EV_MIPS24K_STORE_MISS, MIPS24K_CTR_0, 13},
+ { PMC_EV_MIPS24K_LOAD_MISS, MIPS24K_CTR_1, 13},
+ { PMC_EV_MIPS24K_INTEGER_COMPLETED, MIPS24K_CTR_0, 14},
+ { PMC_EV_MIPS24K_FP_COMPLETED, MIPS24K_CTR_1, 14},
+ { PMC_EV_MIPS24K_LOAD_COMPLETED, MIPS24K_CTR_0, 15},
+ { PMC_EV_MIPS24K_STORE_COMPLETED, MIPS24K_CTR_1, 15},
+ { PMC_EV_MIPS24K_BARRIER_COMPLETED, MIPS24K_CTR_0, 16},
+ { PMC_EV_MIPS24K_MIPS16_COMPLETED, MIPS24K_CTR_1, 16},
+ { PMC_EV_MIPS24K_NOP_COMPLETED, MIPS24K_CTR_0, 17},
+ { PMC_EV_MIPS24K_INTEGER_MULDIV_COMPLETED, MIPS24K_CTR_1, 17},
+ { PMC_EV_MIPS24K_RF_STALL, MIPS24K_CTR_0, 18},
+ { PMC_EV_MIPS24K_INSTR_REFETCH, MIPS24K_CTR_1, 18},
+ { PMC_EV_MIPS24K_STORE_COND_COMPLETED, MIPS24K_CTR_0, 19},
+ { PMC_EV_MIPS24K_STORE_COND_FAILED, MIPS24K_CTR_1, 19},
+ { PMC_EV_MIPS24K_ICACHE_REQUESTS, MIPS24K_CTR_0, 20},
+ { PMC_EV_MIPS24K_ICACHE_HIT, MIPS24K_CTR_1, 20},
+ { PMC_EV_MIPS24K_L2_WRITEBACK, MIPS24K_CTR_0, 21},
+ { PMC_EV_MIPS24K_L2_ACCESS, MIPS24K_CTR_1, 21},
+ { PMC_EV_MIPS24K_L2_MISS, MIPS24K_CTR_0, 22},
+ { PMC_EV_MIPS24K_L2_ERR_CORRECTED, MIPS24K_CTR_1, 22},
+ { PMC_EV_MIPS24K_EXCEPTIONS, MIPS24K_CTR_0, 23},
+ /* Event 23 on COP0 1/3 is undefined */
+ { PMC_EV_MIPS24K_RF_CYCLES_STALLED, MIPS24K_CTR_0, 24},
+ { PMC_EV_MIPS24K_IFU_CYCLES_STALLED, MIPS24K_CTR_0, 25},
+ { PMC_EV_MIPS24K_ALU_CYCLES_STALLED, MIPS24K_CTR_1, 25},
+ /* Events 26 through 32 undefined or reserved to customers */
+ { PMC_EV_MIPS24K_UNCACHED_LOAD, MIPS24K_CTR_0, 33},
+ { PMC_EV_MIPS24K_UNCACHED_STORE, MIPS24K_CTR_1, 33},
+ { PMC_EV_MIPS24K_CP2_REG_TO_REG_COMPLETED, MIPS24K_CTR_0, 35},
+ { PMC_EV_MIPS24K_MFTC_COMPLETED, MIPS24K_CTR_1, 35},
+ /* Event 36 reserved */
+ { PMC_EV_MIPS24K_IC_BLOCKED_CYCLES, MIPS24K_CTR_0, 37},
+ { PMC_EV_MIPS24K_DC_BLOCKED_CYCLES, MIPS24K_CTR_1, 37},
+ { PMC_EV_MIPS24K_L2_IMISS_STALL_CYCLES, MIPS24K_CTR_0, 38},
+ { PMC_EV_MIPS24K_L2_DMISS_STALL_CYCLES, MIPS24K_CTR_1, 38},
+ { PMC_EV_MIPS24K_DMISS_CYCLES, MIPS24K_CTR_0, 39},
+ { PMC_EV_MIPS24K_L2_MISS_CYCLES, MIPS24K_CTR_1, 39},
+ { PMC_EV_MIPS24K_UNCACHED_BLOCK_CYCLES, MIPS24K_CTR_0, 40},
+ { PMC_EV_MIPS24K_MDU_STALL_CYCLES, MIPS24K_CTR_0, 41},
+ { PMC_EV_MIPS24K_FPU_STALL_CYCLES, MIPS24K_CTR_1, 41},
+ { PMC_EV_MIPS24K_CP2_STALL_CYCLES, MIPS24K_CTR_0, 42},
+ { PMC_EV_MIPS24K_COREXTEND_STALL_CYCLES, MIPS24K_CTR_1, 42},
+ { PMC_EV_MIPS24K_ISPRAM_STALL_CYCLES, MIPS24K_CTR_0, 43},
+ { PMC_EV_MIPS24K_DSPRAM_STALL_CYCLES, MIPS24K_CTR_1, 43},
+ { PMC_EV_MIPS24K_CACHE_STALL_CYCLES, MIPS24K_CTR_0, 44},
+ /* Event 44 undefined on 1/3 */
+ { PMC_EV_MIPS24K_LOAD_TO_USE_STALLS, MIPS24K_CTR_0, 45},
+ { PMC_EV_MIPS24K_BASE_MISPRED_STALLS, MIPS24K_CTR_1, 45},
+ { PMC_EV_MIPS24K_CPO_READ_STALLS, MIPS24K_CTR_0, 46},
+ { PMC_EV_MIPS24K_BRANCH_MISPRED_CYCLES, MIPS24K_CTR_1, 46},
+ /* Event 47 reserved */
+ { PMC_EV_MIPS24K_IFETCH_BUFFER_FULL, MIPS24K_CTR_0, 48},
+ { PMC_EV_MIPS24K_FETCH_BUFFER_ALLOCATED, MIPS24K_CTR_1, 48},
+ { PMC_EV_MIPS24K_EJTAG_ITRIGGER, MIPS24K_CTR_0, 49},
+ { PMC_EV_MIPS24K_EJTAG_DTRIGGER, MIPS24K_CTR_1, 49},
+ { PMC_EV_MIPS24K_FSB_LT_QUARTER, MIPS24K_CTR_0, 50},
+ { PMC_EV_MIPS24K_FSB_QUARTER_TO_HALF, MIPS24K_CTR_1, 50},
+ { PMC_EV_MIPS24K_FSB_GT_HALF, MIPS24K_CTR_0, 51},
+ { PMC_EV_MIPS24K_FSB_FULL_PIPELINE_STALLS, MIPS24K_CTR_1, 51},
+ { PMC_EV_MIPS24K_LDQ_LT_QUARTER, MIPS24K_CTR_0, 52},
+ { PMC_EV_MIPS24K_LDQ_QUARTER_TO_HALF, MIPS24K_CTR_1, 52},
+ { PMC_EV_MIPS24K_LDQ_GT_HALF, MIPS24K_CTR_0, 53},
+ { PMC_EV_MIPS24K_LDQ_FULL_PIPELINE_STALLS, MIPS24K_CTR_1, 53},
+ { PMC_EV_MIPS24K_WBB_LT_QUARTER, MIPS24K_CTR_0, 54},
+ { PMC_EV_MIPS24K_WBB_QUARTER_TO_HALF, MIPS24K_CTR_1, 54},
+ { PMC_EV_MIPS24K_WBB_GT_HALF, MIPS24K_CTR_0, 55},
+ { PMC_EV_MIPS24K_WBB_FULL_PIPELINE_STALLS, MIPS24K_CTR_1, 55},
+ /* Events 56-63 reserved */
+ { PMC_EV_MIPS24K_REQUEST_LATENCY, MIPS24K_CTR_0, 61},
+ { PMC_EV_MIPS24K_REQUEST_COUNT, MIPS24K_CTR_1, 61}
+
+};
+
+const int mips24k_event_codes_size =
+ sizeof(mips24k_event_codes) / sizeof(mips24k_event_codes[0]);
+
+/*
+ * Per-processor information.
+ */
+struct mips24k_cpu {
+ struct pmc_hw *pc_mipspmcs;
+};
+
+static struct mips24k_cpu **mips24k_pcpu;
+
+/*
+ * Performance Count Register N
+ */
+static uint32_t
+mips24k_pmcn_read(unsigned int pmc)
+{
+ uint32_t reg = 0;
+
+ KASSERT(pmc < mips24k_npmcs, ("[mips,%d] illegal PMC number %d",
+ __LINE__, pmc));
+
+ /* The counter value is the next value after the control register. */
+ switch (pmc) {
+ case 0:
+ reg = mips_rd_perfcnt1();
+ break;
+ case 1:
+ reg = mips_rd_perfcnt3();
+ break;
+ default:
+ return 0;
+ }
+ return (reg);
+}
+
+static uint32_t
+mips24k_pmcn_write(unsigned int pmc, uint32_t reg)
+{
+
+ KASSERT(pmc < mips24k_npmcs, ("[mips,%d] illegal PMC number %d",
+ __LINE__, pmc));
+
+ switch (pmc) {
+ case 0:
+ mips_wr_perfcnt1(reg);
+ break;
+ case 1:
+ mips_wr_perfcnt3(reg);
+ break;
+ default:
+ return 0;
+ }
+ return (reg);
+}
+
+static int
+mips24k_allocate_pmc(int cpu, int ri, struct pmc *pm,
+ const struct pmc_op_pmcallocate *a)
+{
+ enum pmc_event pe;
+ uint32_t caps, config, counter;
+ int i;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < mips24k_npmcs,
+ ("[mips,%d] illegal row index %d", __LINE__, ri));
+
+ caps = a->pm_caps;
+ if (a->pm_class != PMC_CLASS_MIPS24K)
+ return (EINVAL);
+ pe = a->pm_ev;
+ for (i = 0; i < mips24k_event_codes_size; i++) {
+ if (mips24k_event_codes[i].pe_ev == pe) {
+ config = mips24k_event_codes[i].pe_code;
+ counter = mips24k_event_codes[i].pe_counter;
+ break;
+ }
+ }
+ if (i == mips24k_event_codes_size)
+ return (EINVAL);
+
+ if ((counter != MIPS24K_ALL) && (counter != ri))
+ return (EINVAL);
+
+ config <<= MIPS24K_PMC_SELECT;
+
+ if (caps & PMC_CAP_SYSTEM)
+ config |= (MIPS24K_PMC_SUPER_ENABLE |
+ MIPS24K_PMC_KERNEL_ENABLE);
+ if (caps & PMC_CAP_USER)
+ config |= MIPS24K_PMC_USER_ENABLE;
+ if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0)
+ config |= MIPS24K_PMC_ENABLE;
+
+ pm->pm_md.pm_mips24k.pm_mips24k_evsel = config;
+
+ PMCDBG(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, config);
+
+ return 0;
+}
+
+
+static int
+mips24k_read_pmc(int cpu, int ri, pmc_value_t *v)
+{
+ struct pmc *pm;
+ pmc_value_t tmp;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < mips24k_npmcs,
+ ("[mips,%d] illegal row index %d", __LINE__, ri));
+
+ pm = mips24k_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
+ tmp = mips24k_pmcn_read(ri);
+ PMCDBG(MDP,REA,2,"mips-read id=%d -> %jd", ri, tmp);
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ *v = MIPS24K_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
+ else
+ *v = tmp;
+
+ return 0;
+}
+
+static int
+mips24k_write_pmc(int cpu, int ri, pmc_value_t v)
+{
+ struct pmc *pm;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < mips24k_npmcs,
+ ("[mips,%d] illegal row-index %d", __LINE__, ri));
+
+ pm = mips24k_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
+
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ v = MIPS24K_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
+
+ PMCDBG(MDP,WRI,1,"mips-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+
+ mips24k_pmcn_write(ri, v);
+
+ return 0;
+}
+
+static int
+mips24k_config_pmc(int cpu, int ri, struct pmc *pm)
+{
+ struct pmc_hw *phw;
+
+ PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < mips24k_npmcs,
+ ("[mips,%d] illegal row-index %d", __LINE__, ri));
+
+ phw = &mips24k_pcpu[cpu]->pc_mipspmcs[ri];
+
+ KASSERT(pm == NULL || phw->phw_pmc == NULL,
+ ("[mips,%d] pm=%p phw->pm=%p hwpmc not unconfigured",
+ __LINE__, pm, phw->phw_pmc));
+
+ phw->phw_pmc = pm;
+
+ return 0;
+}
+
+static int
+mips24k_start_pmc(int cpu, int ri)
+{
+ uint32_t config;
+ struct pmc *pm;
+ struct pmc_hw *phw;
+
+ phw = &mips24k_pcpu[cpu]->pc_mipspmcs[ri];
+ pm = phw->phw_pmc;
+ config = pm->pm_md.pm_mips24k.pm_mips24k_evsel;
+
+ /* Enable the PMC. */
+ switch (ri) {
+ case 0:
+ mips_wr_perfcnt0(config);
+ break;
+ case 1:
+ mips_wr_perfcnt2(config);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int
+mips24k_stop_pmc(int cpu, int ri)
+{
+ struct pmc *pm;
+ struct pmc_hw *phw;
+
+ phw = &mips24k_pcpu[cpu]->pc_mipspmcs[ri];
+ pm = phw->phw_pmc;
+
+ /*
+ * Disable the PMCs.
+ *
+ * Clearing the entire register turns the counter off as well
+ * as removes the previously sampled event.
+ */
+ switch (ri) {
+ case 0:
+ mips_wr_perfcnt0(0);
+ break;
+ case 1:
+ mips_wr_perfcnt2(0);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int
+mips24k_release_pmc(int cpu, int ri, struct pmc *pmc)
+{
+ struct pmc_hw *phw;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < mips24k_npmcs,
+ ("[mips,%d] illegal row-index %d", __LINE__, ri));
+
+ phw = &mips24k_pcpu[cpu]->pc_mipspmcs[ri];
+ KASSERT(phw->phw_pmc == NULL,
+ ("[mips,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
+
+ return 0;
+}
+
+static int
+mips24k_intr(int cpu, struct trapframe *tf)
+{
+ return 0;
+}
+
+static int
+mips24k_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
+{
+ int error;
+ struct pmc_hw *phw;
+ char mips24k_name[PMC_NAME_MAX];
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d], illegal CPU %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < mips24k_npmcs,
+ ("[mips,%d] row-index %d out of range", __LINE__, ri));
+
+ phw = &mips24k_pcpu[cpu]->pc_mipspmcs[ri];
+ snprintf(mips24k_name, sizeof(mips24k_name), "MIPS-%d", ri);
+ if ((error = copystr(mips24k_name, pi->pm_name, PMC_NAME_MAX,
+ NULL)) != 0)
+ return error;
+ pi->pm_class = PMC_CLASS_MIPS24K;
+ if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
+ pi->pm_enabled = TRUE;
+ *ppmc = phw->phw_pmc;
+ } else {
+ pi->pm_enabled = FALSE;
+ *ppmc = NULL;
+ }
+
+ return (0);
+}
+
+static int
+mips24k_get_config(int cpu, int ri, struct pmc **ppm)
+{
+ *ppm = mips24k_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
+
+ return 0;
+}
+
+/*
+ * XXX don't know what we should do here.
+ */
+static int
+mips24k_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
+{
+ return 0;
+}
+
+static int
+mips24k_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
+{
+ return 0;
+}
+
+static int
+mips24k_pcpu_init(struct pmc_mdep *md, int cpu)
+{
+ int first_ri, i;
+ struct pmc_cpu *pc;
+ struct mips24k_cpu *pac;
+ struct pmc_hw *phw;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[mips,%d] wrong cpu number %d", __LINE__, cpu));
+ PMCDBG(MDP,INI,1,"mips-init cpu=%d", cpu);
+
+ mips24k_pcpu[cpu] = pac = malloc(sizeof(struct mips24k_cpu), M_PMC,
+ M_WAITOK|M_ZERO);
+ pac->pc_mipspmcs = malloc(sizeof(struct pmc_hw) * mips24k_npmcs,
+ M_PMC, M_WAITOK|M_ZERO);
+ pc = pmc_pcpu[cpu];
+ first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_MIPS24K].pcd_ri;
+ KASSERT(pc != NULL, ("[mips,%d] NULL per-cpu pointer", __LINE__));
+
+ for (i = 0, phw = pac->pc_mipspmcs; i < mips24k_npmcs; i++, phw++) {
+ phw->phw_state = PMC_PHW_FLAG_IS_ENABLED |
+ PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i);
+ phw->phw_pmc = NULL;
+ pc->pc_hwpmcs[i + first_ri] = phw;
+ }
+
+ /*
+ * Clear the counter control register which has the effect
+ * of disabling counting.
+ */
+ for (i = 0; i < mips24k_npmcs; i++)
+ mips24k_pmcn_write(i, 0);
+
+ return 0;
+}
+
+static int
+mips24k_pcpu_fini(struct pmc_mdep *md, int cpu)
+{
+ return 0;
+}
+
+struct pmc_mdep *
+pmc_mips24k_initialize()
+{
+ struct pmc_mdep *pmc_mdep;
+ struct pmc_classdep *pcd;
+
+ /*
+ * Read the counter control registers from CP0
+ * to determine the number of available PMCs.
+ * The control registers use bit 31 as a "more" bit.
+ *
+ * XXX: With the current macros it is hard to read the
+ * CP0 registers in any varied way.
+ */
+ mips24k_npmcs = 2;
+
+ PMCDBG(MDP,INI,1,"mips-init npmcs=%d", mips24k_npmcs);
+
+ /*
+ * Allocate space for pointers to PMC HW descriptors and for
+ * the MDEP structure used by MI code.
+ */
+ mips24k_pcpu = malloc(sizeof(struct mips24k_cpu *) * pmc_cpu_max(), M_PMC,
+ M_WAITOK|M_ZERO);
+
+ /* Just one class */
+ pmc_mdep = malloc(sizeof(struct pmc_mdep) + sizeof(struct pmc_classdep),
+ M_PMC, M_WAITOK|M_ZERO);
+
+ pmc_mdep->pmd_cputype = PMC_CPU_MIPS_24K;
+ pmc_mdep->pmd_nclass = 1;
+
+ pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_MIPS24K];
+ pcd->pcd_caps = MIPS24K_PMC_CAPS;
+ pcd->pcd_class = PMC_CLASS_MIPS24K;
+ pcd->pcd_num = mips24k_npmcs;
+ pcd->pcd_ri = pmc_mdep->pmd_npmc;
+ pcd->pcd_width = 32; /* XXX: Fix for 64 bit MIPS */
+
+ pcd->pcd_allocate_pmc = mips24k_allocate_pmc;
+ pcd->pcd_config_pmc = mips24k_config_pmc;
+ pcd->pcd_pcpu_fini = mips24k_pcpu_fini;
+ pcd->pcd_pcpu_init = mips24k_pcpu_init;
+ pcd->pcd_describe = mips24k_describe;
+ pcd->pcd_get_config = mips24k_get_config;
+ pcd->pcd_read_pmc = mips24k_read_pmc;
+ pcd->pcd_release_pmc = mips24k_release_pmc;
+ pcd->pcd_start_pmc = mips24k_start_pmc;
+ pcd->pcd_stop_pmc = mips24k_stop_pmc;
+ pcd->pcd_write_pmc = mips24k_write_pmc;
+
+ pmc_mdep->pmd_intr = mips24k_intr;
+ pmc_mdep->pmd_switch_in = mips24k_switch_in;
+ pmc_mdep->pmd_switch_out = mips24k_switch_out;
+
+ pmc_mdep->pmd_npmc += mips24k_npmcs;
+
+ return (pmc_mdep);
+}
+
+void
+pmc_mips24k_finalize(struct pmc_mdep *md)
+{
+ (void) md;
+}
+
diff --git a/sys/dev/hwpmc/hwpmc_mips24k.h b/sys/dev/hwpmc/hwpmc_mips24k.h
new file mode 100644
index 0000000..5944e45
--- /dev/null
+++ b/sys/dev/hwpmc/hwpmc_mips24k.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2010 George V. Neville-Neil <gnn@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 _DEV_HWPMC_MIPS24K_H_
+#define _DEV_HWPMC_MIPS24K_H_
+
+#define MIPS24K_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | \
+ PMC_CAP_SYSTEM | PMC_CAP_EDGE | \
+ PMC_CAP_THRESHOLD | PMC_CAP_READ | \
+ PMC_CAP_WRITE | PMC_CAP_INVERT | \
+ PMC_CAP_QUALIFIER)
+
+
+#define MIPS24K_PMC_USER_ENABLE 0x08 /* Count in USER mode */
+#define MIPS24K_PMC_SUPER_ENABLE 0x04 /* Count in SUPERVISOR mode */
+#define MIPS24K_PMC_KERNEL_ENABLE 0x02 /* Count in KERNEL mode */
+#define MIPS24K_PMC_ENABLE (MIPS24K_PMC_USER_ENABLE | \
+ MIPS24K_PMC_SUPER_ENABLE | \
+ MIPS24K_PMC_KERNEL_ENABLE)
+
+
+#define MIPS24K_RELOAD_COUNT_TO_PERFCTR_VALUE(R) (-(R))
+#define MIPS24K_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (-(P))
+
+#define MIPS24K_PMC_SELECT 0x4 /* Which bit position the event starts at. */
+#define MIPS24K_PMC_OFFSET 2 /* Control registers are 0, 2, 4, etc. */
+#define MIPS24K_PMC_MORE 0x800000 /* Test for more PMCs (bit 31) */
+
+#ifdef _KERNEL
+/* MD extension for 'struct pmc' */
+struct pmc_md_mips24k_pmc {
+ uint32_t pm_mips24k_evsel;
+};
+#endif /* _KERNEL */
+
+#endif /* _DEV_HWPMC_MIPS_H_ */
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index d331a85..e33b431 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -3972,9 +3972,11 @@ pmc_post_callchain_callback(void)
td = curthread;
- KASSERT((td->td_pflags & TDP_CALLCHAIN) == 0,
- ("[pmc,%d] thread %p already marked for callchain capture",
- __LINE__, (void *) td));
+ /*
+ * If there is multiple PMCs for the same interrupt ignore new post
+ */
+ if (td->td_pflags & TDP_CALLCHAIN)
+ return;
/*
* Mark this thread as needing callchain capture.
diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c
new file mode 100644
index 0000000..36cd95c
--- /dev/null
+++ b/sys/dev/hwpmc/hwpmc_uncore.c
@@ -0,0 +1,1121 @@
+/*-
+ * Copyright (c) 2010 Fabien Thomas
+ * 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.
+ */
+
+/*
+ * Intel Uncore PMCs.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/pmc.h>
+#include <sys/pmckern.h>
+#include <sys/systm.h>
+
+#include <machine/intr_machdep.h>
+#include <machine/apicvar.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/specialreg.h>
+
+#define UCF_PMC_CAPS \
+ (PMC_CAP_READ | PMC_CAP_WRITE)
+
+#define UCP_PMC_CAPS \
+ (PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \
+ PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE)
+
+static enum pmc_cputype uncore_cputype;
+
+struct uncore_cpu {
+ volatile uint32_t pc_resync;
+ volatile uint32_t pc_ucfctrl; /* Fixed function control. */
+ volatile uint64_t pc_globalctrl; /* Global control register. */
+ struct pmc_hw pc_uncorepmcs[];
+};
+
+static struct uncore_cpu **uncore_pcpu;
+
+static uint64_t uncore_pmcmask;
+
+static int uncore_ucf_ri; /* relative index of fixed counters */
+static int uncore_ucf_width;
+static int uncore_ucf_npmc;
+
+static int uncore_ucp_width;
+static int uncore_ucp_npmc;
+
+static int
+uncore_pcpu_noop(struct pmc_mdep *md, int cpu)
+{
+ (void) md;
+ (void) cpu;
+ return (0);
+}
+
+static int
+uncore_pcpu_init(struct pmc_mdep *md, int cpu)
+{
+ struct pmc_cpu *pc;
+ struct uncore_cpu *cc;
+ struct pmc_hw *phw;
+ int uncore_ri, n, npmc;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[ucf,%d] insane cpu number %d", __LINE__, cpu));
+
+ PMCDBG(MDP,INI,1,"uncore-init cpu=%d", cpu);
+
+ uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri;
+ npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num;
+ npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num;
+
+ cc = malloc(sizeof(struct uncore_cpu) + npmc * sizeof(struct pmc_hw),
+ M_PMC, M_WAITOK | M_ZERO);
+
+ uncore_pcpu[cpu] = cc;
+ pc = pmc_pcpu[cpu];
+
+ KASSERT(pc != NULL && cc != NULL,
+ ("[uncore,%d] NULL per-cpu structures cpu=%d", __LINE__, cpu));
+
+ for (n = 0, phw = cc->pc_uncorepmcs; n < npmc; n++, phw++) {
+ phw->phw_state = PMC_PHW_FLAG_IS_ENABLED |
+ PMC_PHW_CPU_TO_STATE(cpu) |
+ PMC_PHW_INDEX_TO_STATE(n + uncore_ri);
+ phw->phw_pmc = NULL;
+ pc->pc_hwpmcs[n + uncore_ri] = phw;
+ }
+
+ return (0);
+}
+
+static int
+uncore_pcpu_fini(struct pmc_mdep *md, int cpu)
+{
+ int uncore_ri, n, npmc;
+ struct pmc_cpu *pc;
+ struct uncore_cpu *cc;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] insane cpu number (%d)", __LINE__, cpu));
+
+ PMCDBG(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu);
+
+ if ((cc = uncore_pcpu[cpu]) == NULL)
+ return (0);
+
+ uncore_pcpu[cpu] = NULL;
+
+ pc = pmc_pcpu[cpu];
+
+ KASSERT(pc != NULL, ("[uncore,%d] NULL per-cpu %d state", __LINE__,
+ cpu));
+
+ npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num;
+ uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri;
+
+ for (n = 0; n < npmc; n++)
+ wrmsr(UCP_EVSEL0 + n, 0);
+
+ wrmsr(UCF_CTRL, 0);
+ npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num;
+
+ for (n = 0; n < npmc; n++)
+ pc->pc_hwpmcs[n + uncore_ri] = NULL;
+
+ free(cc, M_PMC);
+
+ return (0);
+}
+
+/*
+ * Fixed function counters.
+ */
+
+static pmc_value_t
+ucf_perfctr_value_to_reload_count(pmc_value_t v)
+{
+ v &= (1ULL << uncore_ucf_width) - 1;
+ return (1ULL << uncore_ucf_width) - v;
+}
+
+static pmc_value_t
+ucf_reload_count_to_perfctr_value(pmc_value_t rlc)
+{
+ return (1ULL << uncore_ucf_width) - rlc;
+}
+
+static int
+ucf_allocate_pmc(int cpu, int ri, struct pmc *pm,
+ const struct pmc_op_pmcallocate *a)
+{
+ enum pmc_event ev;
+ uint32_t caps, flags;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
+
+ PMCDBG(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
+
+ if (ri < 0 || ri > uncore_ucf_npmc)
+ return (EINVAL);
+
+ caps = a->pm_caps;
+
+ if (a->pm_class != PMC_CLASS_UCF ||
+ (caps & UCF_PMC_CAPS) != caps)
+ return (EINVAL);
+
+ ev = pm->pm_event;
+ if (ev < PMC_EV_UCF_FIRST || ev > PMC_EV_UCF_LAST)
+ return (EINVAL);
+
+ flags = UCF_EN;
+
+ pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4));
+
+ PMCDBG(MDP,ALL,2, "ucf-allocate config=0x%jx",
+ (uintmax_t) pm->pm_md.pm_ucf.pm_ucf_ctrl);
+
+ return (0);
+}
+
+static int
+ucf_config_pmc(int cpu, int ri, struct pmc *pm)
+{
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
+
+ KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ PMCDBG(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+
+ KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__,
+ cpu));
+
+ uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc = pm;
+
+ return (0);
+}
+
+static int
+ucf_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
+{
+ int error;
+ struct pmc_hw *phw;
+ char ucf_name[PMC_NAME_MAX];
+
+ phw = &uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri];
+
+ (void) snprintf(ucf_name, sizeof(ucf_name), "UCF-%d", ri);
+ if ((error = copystr(ucf_name, pi->pm_name, PMC_NAME_MAX,
+ NULL)) != 0)
+ return (error);
+
+ pi->pm_class = PMC_CLASS_UCF;
+
+ if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
+ pi->pm_enabled = TRUE;
+ *ppmc = phw->phw_pmc;
+ } else {
+ pi->pm_enabled = FALSE;
+ *ppmc = NULL;
+ }
+
+ return (0);
+}
+
+static int
+ucf_get_config(int cpu, int ri, struct pmc **ppm)
+{
+ *ppm = uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
+
+ return (0);
+}
+
+static int
+ucf_read_pmc(int cpu, int ri, pmc_value_t *v)
+{
+ struct pmc *pm;
+ pmc_value_t tmp;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ pm = uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
+
+ KASSERT(pm,
+ ("[uncore,%d] cpu %d ri %d(%d) pmc not configured", __LINE__, cpu,
+ ri, ri + uncore_ucf_ri));
+
+ tmp = rdmsr(UCF_CTR0 + ri);
+
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ *v = ucf_perfctr_value_to_reload_count(tmp);
+ else
+ *v = tmp;
+
+ PMCDBG(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v);
+
+ return (0);
+}
+
+static int
+ucf_release_pmc(int cpu, int ri, struct pmc *pmc)
+{
+ PMCDBG(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ KASSERT(uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc == NULL,
+ ("[uncore,%d] PHW pmc non-NULL", __LINE__));
+
+ return (0);
+}
+
+static int
+ucf_start_pmc(int cpu, int ri)
+{
+ struct pmc *pm;
+ struct uncore_cpu *ucfc;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ PMCDBG(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri);
+
+ ucfc = uncore_pcpu[cpu];
+ pm = ucfc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
+
+ ucfc->pc_ucfctrl |= pm->pm_md.pm_ucf.pm_ucf_ctrl;
+
+ wrmsr(UCF_CTRL, ucfc->pc_ucfctrl);
+
+ do {
+ ucfc->pc_resync = 0;
+ ucfc->pc_globalctrl |= (1ULL << (ri + UCF_OFFSET));
+ wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
+ } while (ucfc->pc_resync != 0);
+
+ PMCDBG(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
+ ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL),
+ ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL));
+
+ return (0);
+}
+
+static int
+ucf_stop_pmc(int cpu, int ri)
+{
+ uint32_t fc;
+ struct uncore_cpu *ucfc;
+
+ PMCDBG(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri);
+
+ ucfc = uncore_pcpu[cpu];
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ fc = (UCF_MASK << (ri * 4));
+
+ ucfc->pc_ucfctrl &= ~fc;
+
+ PMCDBG(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl);
+ wrmsr(UCF_CTRL, ucfc->pc_ucfctrl);
+
+ do {
+ ucfc->pc_resync = 0;
+ ucfc->pc_globalctrl &= ~(1ULL << (ri + UCF_OFFSET));
+ wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
+ } while (ucfc->pc_resync != 0);
+
+ PMCDBG(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
+ ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL),
+ ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL));
+
+ return (0);
+}
+
+static int
+ucf_write_pmc(int cpu, int ri, pmc_value_t v)
+{
+ struct uncore_cpu *cc;
+ struct pmc *pm;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ cc = uncore_pcpu[cpu];
+ pm = cc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
+
+ KASSERT(pm,
+ ("[uncore,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
+
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ v = ucf_reload_count_to_perfctr_value(v);
+
+ wrmsr(UCF_CTRL, 0); /* Turn off fixed counters */
+ wrmsr(UCF_CTR0 + ri, v);
+ wrmsr(UCF_CTRL, cc->pc_ucfctrl);
+
+ PMCDBG(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ",
+ cpu, ri, v, (uintmax_t) rdmsr(UCF_CTRL));
+
+ return (0);
+}
+
+
+static void
+ucf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
+{
+ struct pmc_classdep *pcd;
+
+ KASSERT(md != NULL, ("[ucf,%d] md is NULL", __LINE__));
+
+ PMCDBG(MDP,INI,1, "%s", "ucf-initialize");
+
+ pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF];
+
+ pcd->pcd_caps = UCF_PMC_CAPS;
+ pcd->pcd_class = PMC_CLASS_UCF;
+ pcd->pcd_num = npmc;
+ pcd->pcd_ri = md->pmd_npmc;
+ pcd->pcd_width = pmcwidth;
+
+ pcd->pcd_allocate_pmc = ucf_allocate_pmc;
+ pcd->pcd_config_pmc = ucf_config_pmc;
+ pcd->pcd_describe = ucf_describe;
+ pcd->pcd_get_config = ucf_get_config;
+ pcd->pcd_get_msr = NULL;
+ pcd->pcd_pcpu_fini = uncore_pcpu_noop;
+ pcd->pcd_pcpu_init = uncore_pcpu_noop;
+ pcd->pcd_read_pmc = ucf_read_pmc;
+ pcd->pcd_release_pmc = ucf_release_pmc;
+ pcd->pcd_start_pmc = ucf_start_pmc;
+ pcd->pcd_stop_pmc = ucf_stop_pmc;
+ pcd->pcd_write_pmc = ucf_write_pmc;
+
+ md->pmd_npmc += npmc;
+}
+
+/*
+ * Intel programmable PMCs.
+ */
+
+/*
+ * Event descriptor tables.
+ *
+ * For each event id, we track:
+ *
+ * 1. The CPUs that the event is valid for.
+ *
+ * 2. If the event uses a fixed UMASK, the value of the umask field.
+ * If the event doesn't use a fixed UMASK, a mask of legal bits
+ * to check against.
+ */
+
+struct ucp_event_descr {
+ enum pmc_event ucp_ev;
+ unsigned char ucp_evcode;
+ unsigned char ucp_umask;
+ unsigned char ucp_flags;
+};
+
+#define UCP_F_I7 (1 << 0) /* CPU: Core i7 */
+#define UCP_F_WM (1 << 1) /* CPU: Westmere */
+#define UCP_F_FM (1 << 2) /* Fixed mask */
+
+#define UCP_F_ALLCPUS \
+ (UCP_F_I7 | UCP_F_WM)
+
+#define UCP_F_CMASK 0xFF000000
+
+static struct ucp_event_descr ucp_events[] = {
+#undef UCPDESCR
+#define UCPDESCR(N,EV,UM,FLAGS) { \
+ .ucp_ev = PMC_EV_UCP_EVENT_##N, \
+ .ucp_evcode = (EV), \
+ .ucp_umask = (UM), \
+ .ucp_flags = (FLAGS) \
+ }
+
+ UCPDESCR(00H_01H, 0x00, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(00H_02H, 0x00, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(00H_04H, 0x00, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(01H_01H, 0x01, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(01H_02H, 0x01, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(01H_04H, 0x01, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(02H_01H, 0x02, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_01H, 0x03, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_02H, 0x03, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_04H, 0x03, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_08H, 0x03, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_10H, 0x03, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_20H, 0x03, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(03H_40H, 0x03, 0x40, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(04H_01H, 0x04, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(04H_02H, 0x04, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(04H_04H, 0x04, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(04H_08H, 0x04, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(04H_10H, 0x04, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(05H_01H, 0x05, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(05H_02H, 0x05, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(05H_04H, 0x05, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(06H_01H, 0x06, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(06H_02H, 0x06, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(06H_04H, 0x06, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(06H_08H, 0x06, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(06H_10H, 0x06, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(06H_20H, 0x06, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(07H_01H, 0x07, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(07H_02H, 0x07, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(07H_04H, 0x07, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(07H_08H, 0x07, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(07H_10H, 0x07, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(07H_20H, 0x07, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(07H_24H, 0x07, 0x24, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(08H_01H, 0x08, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(08H_02H, 0x08, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(08H_04H, 0x08, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(08H_03H, 0x08, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(09H_01H, 0x09, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(09H_02H, 0x09, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(09H_04H, 0x09, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(09H_03H, 0x09, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(0AH_01H, 0x0A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0AH_02H, 0x0A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0AH_04H, 0x0A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0AH_08H, 0x0A, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0AH_0FH, 0x0A, 0x0F, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(0BH_01H, 0x0B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0BH_02H, 0x0B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0BH_04H, 0x0B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0BH_08H, 0x0B, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0BH_10H, 0x0B, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(0BH_1FH, 0x0B, 0x1F, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(0CH_01H, 0x0C, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(0CH_02H, 0x0C, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(0CH_04H, 0x0C, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(0CH_08H, 0x0C, 0x08, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(20H_01H, 0x20, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(20H_02H, 0x20, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(20H_04H, 0x20, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(20H_08H, 0x20, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(20H_10H, 0x20, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(20H_20H, 0x20, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(21H_01H, 0x21, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(21H_02H, 0x21, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(21H_04H, 0x21, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(22H_01H, 0x22, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(22H_02H, 0x22, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(22H_04H, 0x22, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(23H_01H, 0x23, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(23H_02H, 0x23, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(23H_04H, 0x23, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(24H_02H, 0x24, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(24H_04H, 0x24, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(25H_01H, 0x25, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(25H_02H, 0x25, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(25H_04H, 0x25, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(26H_01H, 0x26, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(27H_01H, 0x27, 0x01, UCP_F_FM | UCP_F_I7),
+ UCPDESCR(27H_02H, 0x27, 0x02, UCP_F_FM | UCP_F_I7),
+ UCPDESCR(27H_04H, 0x27, 0x04, UCP_F_FM | UCP_F_I7),
+ UCPDESCR(27H_08H, 0x27, 0x08, UCP_F_FM | UCP_F_I7),
+ UCPDESCR(27H_10H, 0x27, 0x10, UCP_F_FM | UCP_F_I7),
+ UCPDESCR(27H_20H, 0x27, 0x20, UCP_F_FM | UCP_F_I7),
+
+ UCPDESCR(28H_01H, 0x28, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(28H_02H, 0x28, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(28H_04H, 0x28, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(28H_08H, 0x28, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(28H_10H, 0x28, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(28H_20H, 0x28, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(29H_01H, 0x29, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(29H_02H, 0x29, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(29H_04H, 0x29, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(29H_08H, 0x29, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(29H_10H, 0x29, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(29H_20H, 0x29, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(2AH_01H, 0x2A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2AH_02H, 0x2A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2AH_04H, 0x2A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2AH_07H, 0x2A, 0x07, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(2BH_01H, 0x2B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2BH_02H, 0x2B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2BH_04H, 0x2B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2BH_07H, 0x2B, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(2CH_01H, 0x2C, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2CH_02H, 0x2C, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2CH_04H, 0x2C, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2CH_07H, 0x2C, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(2DH_01H, 0x2D, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2DH_02H, 0x2D, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2DH_04H, 0x2D, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2DH_07H, 0x2D, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(2EH_01H, 0x2E, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2EH_02H, 0x2E, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2EH_04H, 0x2E, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2EH_07H, 0x2E, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(2FH_01H, 0x2F, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_02H, 0x2F, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_04H, 0x2F, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_07H, 0x2F, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_08H, 0x2F, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_10H, 0x2F, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_20H, 0x2F, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(2FH_38H, 0x2F, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(30H_01H, 0x30, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(30H_02H, 0x30, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(30H_04H, 0x30, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(30H_07H, 0x30, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(31H_01H, 0x31, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(31H_02H, 0x31, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(31H_04H, 0x31, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(31H_07H, 0x31, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(32H_01H, 0x32, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(32H_02H, 0x32, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(32H_04H, 0x32, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(32H_07H, 0x32, 0x07, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(33H_01H, 0x33, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(33H_02H, 0x33, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(33H_04H, 0x33, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(33H_07H, 0x33, 0x07, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(34H_01H, 0x34, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(34H_02H, 0x34, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(34H_04H, 0x34, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(34H_08H, 0x34, 0x08, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(34H_10H, 0x34, 0x10, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(34H_20H, 0x34, 0x20, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(35H_01H, 0x35, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(35H_02H, 0x35, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(35H_04H, 0x35, 0x04, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(40H_01H, 0x40, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_02H, 0x40, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_04H, 0x40, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_08H, 0x40, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_10H, 0x40, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_20H, 0x40, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_07H, 0x40, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(40H_38H, 0x40, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(41H_01H, 0x41, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_02H, 0x41, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_04H, 0x41, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_08H, 0x41, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_10H, 0x41, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_20H, 0x41, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_07H, 0x41, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(41H_38H, 0x41, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(42H_01H, 0x42, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(42H_02H, 0x42, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(42H_04H, 0x42, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(42H_08H, 0x42, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(43H_01H, 0x43, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(43H_02H, 0x43, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(60H_01H, 0x60, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(60H_02H, 0x60, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(60H_04H, 0x60, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(61H_01H, 0x61, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(61H_02H, 0x61, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(61H_04H, 0x61, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(62H_01H, 0x62, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(62H_02H, 0x62, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(62H_04H, 0x62, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(63H_01H, 0x63, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(63H_02H, 0x63, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(63H_04H, 0x63, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(63H_08H, 0x63, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(63H_10H, 0x63, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(63H_20H, 0x63, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(64H_01H, 0x64, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(64H_02H, 0x64, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(64H_04H, 0x64, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(64H_08H, 0x64, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(64H_10H, 0x64, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(64H_20H, 0x64, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(65H_01H, 0x65, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(65H_02H, 0x65, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(65H_04H, 0x65, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(66H_01H, 0x66, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(66H_02H, 0x66, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(66H_04H, 0x66, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+
+ UCPDESCR(67H_01H, 0x67, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(80H_01H, 0x80, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(80H_02H, 0x80, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(80H_04H, 0x80, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(80H_08H, 0x80, 0x08, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(81H_01H, 0x81, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(81H_02H, 0x81, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(81H_04H, 0x81, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(81H_08H, 0x81, 0x08, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(82H_01H, 0x82, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(83H_01H, 0x83, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(83H_02H, 0x83, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(83H_04H, 0x83, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(83H_08H, 0x83, 0x08, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(84H_01H, 0x84, 0x01, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(84H_02H, 0x84, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(84H_04H, 0x84, 0x04, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(84H_08H, 0x84, 0x08, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(85H_02H, 0x85, 0x02, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(86H_01H, 0x86, 0x01, UCP_F_FM | UCP_F_WM)
+};
+
+static const int nucp_events = sizeof(ucp_events) / sizeof(ucp_events[0]);
+
+static pmc_value_t
+ucp_perfctr_value_to_reload_count(pmc_value_t v)
+{
+ v &= (1ULL << uncore_ucp_width) - 1;
+ return (1ULL << uncore_ucp_width) - v;
+}
+
+static pmc_value_t
+ucp_reload_count_to_perfctr_value(pmc_value_t rlc)
+{
+ return (1ULL << uncore_ucp_width) - rlc;
+}
+
+static int
+ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
+ const struct pmc_op_pmcallocate *a)
+{
+ int n;
+ enum pmc_event ev;
+ struct ucp_event_descr *ie;
+ uint32_t caps, config, cpuflag, evsel;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row-index value %d", __LINE__, ri));
+
+ /* check requested capabilities */
+ caps = a->pm_caps;
+ if ((UCP_PMC_CAPS & caps) != caps)
+ return (EPERM);
+
+ ev = pm->pm_event;
+
+ /*
+ * Look for an event descriptor with matching CPU and event id
+ * fields.
+ */
+
+ switch (uncore_cputype) {
+ case PMC_CPU_INTEL_COREI7:
+ cpuflag = UCP_F_I7;
+ break;
+ case PMC_CPU_INTEL_WESTMERE:
+ cpuflag = UCP_F_WM;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ for (n = 0, ie = ucp_events; n < nucp_events; n++, ie++)
+ if (ie->ucp_ev == ev && ie->ucp_flags & cpuflag)
+ break;
+
+ if (n == nucp_events)
+ return (EINVAL);
+
+ /*
+ * A matching event descriptor has been found, so start
+ * assembling the contents of the event select register.
+ */
+ evsel = ie->ucp_evcode | UCP_EN;
+
+ config = a->pm_md.pm_ucp.pm_ucp_config & ~UCP_F_CMASK;
+
+ /*
+ * If the event uses a fixed umask value, reject any umask
+ * bits set by the user.
+ */
+ if (ie->ucp_flags & UCP_F_FM) {
+
+ if (UCP_UMASK(config) != 0)
+ return (EINVAL);
+
+ evsel |= (ie->ucp_umask << 8);
+
+ } else
+ return (EINVAL);
+
+ if (caps & PMC_CAP_THRESHOLD)
+ evsel |= (a->pm_md.pm_ucp.pm_ucp_config & UCP_F_CMASK);
+ if (caps & PMC_CAP_EDGE)
+ evsel |= UCP_EDGE;
+ if (caps & PMC_CAP_INVERT)
+ evsel |= UCP_INV;
+
+ pm->pm_md.pm_ucp.pm_ucp_evsel = evsel;
+
+ return (0);
+}
+
+static int
+ucp_config_pmc(int cpu, int ri, struct pmc *pm)
+{
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
+
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ PMCDBG(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+
+ KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__,
+ cpu));
+
+ uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc = pm;
+
+ return (0);
+}
+
+static int
+ucp_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
+{
+ int error;
+ struct pmc_hw *phw;
+ char ucp_name[PMC_NAME_MAX];
+
+ phw = &uncore_pcpu[cpu]->pc_uncorepmcs[ri];
+
+ (void) snprintf(ucp_name, sizeof(ucp_name), "UCP-%d", ri);
+ if ((error = copystr(ucp_name, pi->pm_name, PMC_NAME_MAX,
+ NULL)) != 0)
+ return (error);
+
+ pi->pm_class = PMC_CLASS_UCP;
+
+ if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
+ pi->pm_enabled = TRUE;
+ *ppmc = phw->phw_pmc;
+ } else {
+ pi->pm_enabled = FALSE;
+ *ppmc = NULL;
+ }
+
+ return (0);
+}
+
+static int
+ucp_get_config(int cpu, int ri, struct pmc **ppm)
+{
+ *ppm = uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc;
+
+ return (0);
+}
+
+static int
+ucp_read_pmc(int cpu, int ri, pmc_value_t *v)
+{
+ struct pmc *pm;
+ pmc_value_t tmp;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ pm = uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc;
+
+ KASSERT(pm,
+ ("[uncore,%d] cpu %d ri %d pmc not configured", __LINE__, cpu,
+ ri));
+
+ tmp = rdmsr(UCP_PMC0 + ri);
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ *v = ucp_perfctr_value_to_reload_count(tmp);
+ else
+ *v = tmp;
+
+ PMCDBG(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
+ ri, *v);
+
+ return (0);
+}
+
+static int
+ucp_release_pmc(int cpu, int ri, struct pmc *pm)
+{
+ (void) pm;
+
+ PMCDBG(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri,
+ pm);
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ KASSERT(uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc
+ == NULL, ("[uncore,%d] PHW pmc non-NULL", __LINE__));
+
+ return (0);
+}
+
+static int
+ucp_start_pmc(int cpu, int ri)
+{
+ struct pmc *pm;
+ uint32_t evsel;
+ struct uncore_cpu *cc;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row-index %d", __LINE__, ri));
+
+ cc = uncore_pcpu[cpu];
+ pm = cc->pc_uncorepmcs[ri].phw_pmc;
+
+ KASSERT(pm,
+ ("[uncore,%d] starting cpu%d,ri%d with no pmc configured",
+ __LINE__, cpu, ri));
+
+ PMCDBG(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri);
+
+ evsel = pm->pm_md.pm_ucp.pm_ucp_evsel;
+
+ PMCDBG(MDP,STA,2, "ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
+ cpu, ri, UCP_EVSEL0 + ri, evsel);
+
+ wrmsr(UCP_EVSEL0 + ri, evsel);
+
+ do {
+ cc->pc_resync = 0;
+ cc->pc_globalctrl |= (1ULL << ri);
+ wrmsr(UC_GLOBAL_CTRL, cc->pc_globalctrl);
+ } while (cc->pc_resync != 0);
+
+ return (0);
+}
+
+static int
+ucp_stop_pmc(int cpu, int ri)
+{
+ struct pmc *pm;
+ struct uncore_cpu *cc;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row index %d", __LINE__, ri));
+
+ cc = uncore_pcpu[cpu];
+ pm = cc->pc_uncorepmcs[ri].phw_pmc;
+
+ KASSERT(pm,
+ ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
+ cpu, ri));
+
+ PMCDBG(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri);
+
+ wrmsr(UCP_EVSEL0 + ri, 0); /* stop hw */
+
+ do {
+ cc->pc_resync = 0;
+ cc->pc_globalctrl &= ~(1ULL << ri);
+ wrmsr(UC_GLOBAL_CTRL, cc->pc_globalctrl);
+ } while (cc->pc_resync != 0);
+
+ return (0);
+}
+
+static int
+ucp_write_pmc(int cpu, int ri, pmc_value_t v)
+{
+ struct pmc *pm;
+ struct uncore_cpu *cc;
+
+ KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+ ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
+ KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
+ ("[uncore,%d] illegal row index %d", __LINE__, ri));
+
+ cc = uncore_pcpu[cpu];
+ pm = cc->pc_uncorepmcs[ri].phw_pmc;
+
+ KASSERT(pm,
+ ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
+ cpu, ri));
+
+ PMCDBG(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
+ UCP_PMC0 + ri, v);
+
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ v = ucp_reload_count_to_perfctr_value(v);
+
+ /*
+ * Write the new value to the counter. The counter will be in
+ * a stopped state when the pcd_write() entry point is called.
+ */
+
+ wrmsr(UCP_PMC0 + ri, v);
+
+ return (0);
+}
+
+
+static void
+ucp_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
+{
+ struct pmc_classdep *pcd;
+
+ KASSERT(md != NULL, ("[ucp,%d] md is NULL", __LINE__));
+
+ PMCDBG(MDP,INI,1, "%s", "ucp-initialize");
+
+ pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP];
+
+ pcd->pcd_caps = UCP_PMC_CAPS;
+ pcd->pcd_class = PMC_CLASS_UCP;
+ pcd->pcd_num = npmc;
+ pcd->pcd_ri = md->pmd_npmc;
+ pcd->pcd_width = pmcwidth;
+
+ pcd->pcd_allocate_pmc = ucp_allocate_pmc;
+ pcd->pcd_config_pmc = ucp_config_pmc;
+ pcd->pcd_describe = ucp_describe;
+ pcd->pcd_get_config = ucp_get_config;
+ pcd->pcd_get_msr = NULL;
+ pcd->pcd_pcpu_fini = uncore_pcpu_fini;
+ pcd->pcd_pcpu_init = uncore_pcpu_init;
+ pcd->pcd_read_pmc = ucp_read_pmc;
+ pcd->pcd_release_pmc = ucp_release_pmc;
+ pcd->pcd_start_pmc = ucp_start_pmc;
+ pcd->pcd_stop_pmc = ucp_stop_pmc;
+ pcd->pcd_write_pmc = ucp_write_pmc;
+
+ md->pmd_npmc += npmc;
+}
+
+int
+pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu)
+{
+ uncore_cputype = md->pmd_cputype;
+ uncore_pmcmask = 0;
+
+ /*
+ * Initialize programmable counters.
+ */
+
+ uncore_ucp_npmc = 8;
+ uncore_ucp_width = 48;
+
+ uncore_pmcmask |= ((1ULL << uncore_ucp_npmc) - 1);
+
+ ucp_initialize(md, maxcpu, uncore_ucp_npmc, uncore_ucp_width);
+
+ /*
+ * Initialize fixed function counters, if present.
+ */
+ uncore_ucf_ri = uncore_ucp_npmc;
+ uncore_ucf_npmc = 1;
+ uncore_ucf_width = 48;
+
+ ucf_initialize(md, maxcpu, uncore_ucf_npmc, uncore_ucf_width);
+ uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << UCF_OFFSET;
+
+ PMCDBG(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask,
+ uncore_ucf_ri);
+
+ uncore_pcpu = malloc(sizeof(struct uncore_cpu **) * maxcpu, M_PMC,
+ M_ZERO | M_WAITOK);
+
+ return (0);
+}
+
+void
+pmc_uncore_finalize(struct pmc_mdep *md)
+{
+ PMCDBG(MDP,INI,1, "%s", "uncore-finalize");
+
+ free(uncore_pcpu, M_PMC);
+ uncore_pcpu = NULL;
+}
diff --git a/sys/dev/hwpmc/hwpmc_uncore.h b/sys/dev/hwpmc/hwpmc_uncore.h
new file mode 100644
index 0000000..2be34db
--- /dev/null
+++ b/sys/dev/hwpmc/hwpmc_uncore.h
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 2010 Fabien Thomas
+ * 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 _DEV_HWPMC_UNCORE_H_
+#define _DEV_HWPMC_UNCORE_H_ 1
+
+/*
+ * Fixed-function PMCs.
+ */
+struct pmc_md_ucf_op_pmcallocate {
+ uint16_t pm_ucf_flags; /* additional flags */
+};
+
+#define UCF_EN 0x1
+#define UCF_PMI 0x4
+
+/*
+ * Programmable PMCs.
+ */
+struct pmc_md_ucp_op_pmcallocate {
+ uint32_t pm_ucp_config;
+};
+
+#define UCP_EVSEL(C) ((C) & 0xFF)
+#define UCP_UMASK(C) ((C) & 0xFF00)
+#define UCP_CTRR (1 << 17)
+#define UCP_EDGE (1 << 18)
+#define UCP_INT (1 << 20)
+#define UCP_EN (1 << 22)
+#define UCP_INV (1 << 23)
+#define UCP_CMASK(C) (((C) & 0xFF) << 24)
+
+#ifdef _KERNEL
+
+#define DCTL_FLAG_UNC_PMI (1ULL << 13)
+
+/*
+ * Fixed-function counters.
+ */
+
+#define UCF_MASK 0xF
+
+#define UCF_CTR0 0x394
+
+#define UCF_OFFSET 32
+#define UCF_CTRL 0x395
+
+/*
+ * Programmable counters.
+ */
+
+#define UCP_PMC0 0x3B0
+#define UCP_EVSEL0 0x3C0
+#define UCP_OPCODE_MATCH 0x396
+
+/*
+ * Simplified programming interface in Intel Performance Architecture
+ * v2 and later.
+ */
+
+#define UC_GLOBAL_STATUS 0x392
+#define UC_GLOBAL_CTRL 0x391
+#define UC_GLOBAL_OVF_CTRL 0x393
+
+#define UC_GLOBAL_STATUS_FLAG_CLRCHG (1ULL << 63)
+#define UC_GLOBAL_STATUS_FLAG_OVFPMI (1ULL << 61)
+#define UC_GLOBAL_CTRL_FLAG_FRZ (1ULL << 63)
+#define UC_GLOBAL_CTRL_FLAG_ENPMICORE0 (1ULL << 48)
+
+struct pmc_md_ucf_pmc {
+ uint64_t pm_ucf_ctrl;
+};
+
+struct pmc_md_ucp_pmc {
+ uint32_t pm_ucp_evsel;
+};
+
+/*
+ * Prototypes.
+ */
+
+int pmc_uncore_initialize(struct pmc_mdep *_md, int _maxcpu);
+void pmc_uncore_finalize(struct pmc_mdep *_md);
+
+void pmc_uncore_mark_started(int _cpu, int _pmc);
+
+int pmc_ucf_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width);
+void pmc_ucf_finalize(struct pmc_mdep *_md);
+
+int pmc_ucp_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width,
+ int _flags);
+void pmc_ucp_finalize(struct pmc_mdep *_md);
+
+#endif /* _KERNEL */
+#endif /* _DEV_HWPMC_UNCORE_H */
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index f43e128..df2d3ef 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -468,8 +468,10 @@ __PMC_EV_ALIAS("unhalted-reference-cycles", IAF_CPU_CLK_UNHALTED_REF)
* the CPU model happens inside hwpmc(4).
*/
#define __PMC_EV_IAP() \
+__PMC_EV(IAP, EVENT_02H_01H) \
__PMC_EV(IAP, EVENT_02H_81H) \
__PMC_EV(IAP, EVENT_03H_00H) \
+__PMC_EV(IAP, EVENT_03H_01H) \
__PMC_EV(IAP, EVENT_03H_02H) \
__PMC_EV(IAP, EVENT_03H_04H) \
__PMC_EV(IAP, EVENT_03H_08H) \
@@ -478,9 +480,18 @@ __PMC_EV(IAP, EVENT_03H_20H) \
__PMC_EV(IAP, EVENT_04H_00H) \
__PMC_EV(IAP, EVENT_04H_01H) \
__PMC_EV(IAP, EVENT_04H_02H) \
+__PMC_EV(IAP, EVENT_04H_07H) \
__PMC_EV(IAP, EVENT_04H_08H) \
__PMC_EV(IAP, EVENT_05H_00H) \
+__PMC_EV(IAP, EVENT_05H_01H) \
+__PMC_EV(IAP, EVENT_05H_02H) \
+__PMC_EV(IAP, EVENT_05H_03H) \
__PMC_EV(IAP, EVENT_06H_00H) \
+__PMC_EV(IAP, EVENT_06H_01H) \
+__PMC_EV(IAP, EVENT_06H_02H) \
+__PMC_EV(IAP, EVENT_06H_04H) \
+__PMC_EV(IAP, EVENT_06H_08H) \
+__PMC_EV(IAP, EVENT_06H_0FH) \
__PMC_EV(IAP, EVENT_07H_00H) \
__PMC_EV(IAP, EVENT_07H_01H) \
__PMC_EV(IAP, EVENT_07H_02H) \
@@ -495,41 +506,126 @@ __PMC_EV(IAP, EVENT_08H_06H) \
__PMC_EV(IAP, EVENT_08H_07H) \
__PMC_EV(IAP, EVENT_08H_08H) \
__PMC_EV(IAP, EVENT_08H_09H) \
+__PMC_EV(IAP, EVENT_08H_10H) \
+__PMC_EV(IAP, EVENT_08H_20H) \
+__PMC_EV(IAP, EVENT_08H_40H) \
+__PMC_EV(IAP, EVENT_08H_80H) \
__PMC_EV(IAP, EVENT_09H_01H) \
__PMC_EV(IAP, EVENT_09H_02H) \
+__PMC_EV(IAP, EVENT_09H_04H) \
+__PMC_EV(IAP, EVENT_09H_08H) \
+__PMC_EV(IAP, EVENT_0BH_01H) \
+__PMC_EV(IAP, EVENT_0BH_02H) \
+__PMC_EV(IAP, EVENT_0BH_10H) \
__PMC_EV(IAP, EVENT_0CH_01H) \
__PMC_EV(IAP, EVENT_0CH_02H) \
__PMC_EV(IAP, EVENT_0CH_03H) \
+__PMC_EV(IAP, EVENT_0EH_01H) \
+__PMC_EV(IAP, EVENT_0EH_02H) \
+__PMC_EV(IAP, EVENT_0FH_01H) \
+__PMC_EV(IAP, EVENT_0FH_02H) \
+__PMC_EV(IAP, EVENT_0FH_08H) \
+__PMC_EV(IAP, EVENT_0FH_10H) \
+__PMC_EV(IAP, EVENT_0FH_20H) \
+__PMC_EV(IAP, EVENT_0FH_80H) \
__PMC_EV(IAP, EVENT_10H_00H) \
__PMC_EV(IAP, EVENT_10H_01H) \
+__PMC_EV(IAP, EVENT_10H_02H) \
+__PMC_EV(IAP, EVENT_10H_04H) \
+__PMC_EV(IAP, EVENT_10H_08H) \
+__PMC_EV(IAP, EVENT_10H_10H) \
+__PMC_EV(IAP, EVENT_10H_20H) \
+__PMC_EV(IAP, EVENT_10H_40H) \
+__PMC_EV(IAP, EVENT_10H_80H) \
__PMC_EV(IAP, EVENT_10H_81H) \
__PMC_EV(IAP, EVENT_11H_00H) \
__PMC_EV(IAP, EVENT_11H_01H) \
__PMC_EV(IAP, EVENT_11H_81H) \
__PMC_EV(IAP, EVENT_12H_00H) \
__PMC_EV(IAP, EVENT_12H_01H) \
+__PMC_EV(IAP, EVENT_12H_02H) \
+__PMC_EV(IAP, EVENT_12H_04H) \
+__PMC_EV(IAP, EVENT_12H_08H) \
+__PMC_EV(IAP, EVENT_12H_10H) \
+__PMC_EV(IAP, EVENT_12H_20H) \
+__PMC_EV(IAP, EVENT_12H_40H) \
__PMC_EV(IAP, EVENT_12H_81H) \
__PMC_EV(IAP, EVENT_13H_00H) \
__PMC_EV(IAP, EVENT_13H_01H) \
+__PMC_EV(IAP, EVENT_13H_02H) \
+__PMC_EV(IAP, EVENT_13H_04H) \
+__PMC_EV(IAP, EVENT_13H_07H) \
__PMC_EV(IAP, EVENT_13H_81H) \
__PMC_EV(IAP, EVENT_14H_00H) \
__PMC_EV(IAP, EVENT_14H_01H) \
+__PMC_EV(IAP, EVENT_14H_02H) \
+__PMC_EV(IAP, EVENT_17H_01H) \
__PMC_EV(IAP, EVENT_18H_00H) \
+__PMC_EV(IAP, EVENT_18H_01H) \
__PMC_EV(IAP, EVENT_19H_00H) \
__PMC_EV(IAP, EVENT_19H_01H) \
__PMC_EV(IAP, EVENT_19H_02H) \
+__PMC_EV(IAP, EVENT_1DH_01H) \
+__PMC_EV(IAP, EVENT_1DH_02H) \
+__PMC_EV(IAP, EVENT_1DH_04H) \
+__PMC_EV(IAP, EVENT_1EH_01H) \
+__PMC_EV(IAP, EVENT_20H_01H) \
__PMC_EV(IAP, EVENT_21H) \
__PMC_EV(IAP, EVENT_22H) \
__PMC_EV(IAP, EVENT_23H) \
__PMC_EV(IAP, EVENT_24H) \
+__PMC_EV(IAP, EVENT_24H_01H) \
+__PMC_EV(IAP, EVENT_24H_02H) \
+__PMC_EV(IAP, EVENT_24H_03H) \
+__PMC_EV(IAP, EVENT_24H_04H) \
+__PMC_EV(IAP, EVENT_24H_08H) \
+__PMC_EV(IAP, EVENT_24H_0CH) \
+__PMC_EV(IAP, EVENT_24H_10H) \
+__PMC_EV(IAP, EVENT_24H_20H) \
+__PMC_EV(IAP, EVENT_24H_30H) \
+__PMC_EV(IAP, EVENT_24H_40H) \
+__PMC_EV(IAP, EVENT_24H_80H) \
+__PMC_EV(IAP, EVENT_24H_AAH) \
+__PMC_EV(IAP, EVENT_24H_C0H) \
+__PMC_EV(IAP, EVENT_24H_FFH) \
__PMC_EV(IAP, EVENT_25H) \
__PMC_EV(IAP, EVENT_26H) \
+__PMC_EV(IAP, EVENT_26H_01H) \
+__PMC_EV(IAP, EVENT_26H_02H) \
+__PMC_EV(IAP, EVENT_26H_04H) \
+__PMC_EV(IAP, EVENT_26H_08H) \
+__PMC_EV(IAP, EVENT_26H_0FH) \
+__PMC_EV(IAP, EVENT_26H_10H) \
+__PMC_EV(IAP, EVENT_26H_20H) \
+__PMC_EV(IAP, EVENT_26H_40H) \
+__PMC_EV(IAP, EVENT_26H_80H) \
+__PMC_EV(IAP, EVENT_26H_F0H) \
+__PMC_EV(IAP, EVENT_26H_FFH) \
__PMC_EV(IAP, EVENT_27H) \
+__PMC_EV(IAP, EVENT_27H_01H) \
+__PMC_EV(IAP, EVENT_27H_02H) \
+__PMC_EV(IAP, EVENT_27H_04H) \
+__PMC_EV(IAP, EVENT_27H_08H) \
+__PMC_EV(IAP, EVENT_27H_0EH) \
+__PMC_EV(IAP, EVENT_27H_0FH) \
+__PMC_EV(IAP, EVENT_27H_10H) \
+__PMC_EV(IAP, EVENT_27H_20H) \
+__PMC_EV(IAP, EVENT_27H_40H) \
+__PMC_EV(IAP, EVENT_27H_80H) \
+__PMC_EV(IAP, EVENT_27H_E0H) \
+__PMC_EV(IAP, EVENT_27H_F0H) \
__PMC_EV(IAP, EVENT_28H) \
+__PMC_EV(IAP, EVENT_28H_01H) \
+__PMC_EV(IAP, EVENT_28H_02H) \
+__PMC_EV(IAP, EVENT_28H_04H) \
+__PMC_EV(IAP, EVENT_28H_08H) \
+__PMC_EV(IAP, EVENT_28H_0FH) \
__PMC_EV(IAP, EVENT_29H) \
__PMC_EV(IAP, EVENT_2AH) \
__PMC_EV(IAP, EVENT_2BH) \
__PMC_EV(IAP, EVENT_2EH) \
+__PMC_EV(IAP, EVENT_2EH_01H) \
+__PMC_EV(IAP, EVENT_2EH_02H) \
__PMC_EV(IAP, EVENT_2EH_41H) \
__PMC_EV(IAP, EVENT_2EH_4FH) \
__PMC_EV(IAP, EVENT_30H) \
@@ -540,11 +636,26 @@ __PMC_EV(IAP, EVENT_3BH_C0H) \
__PMC_EV(IAP, EVENT_3CH_00H) \
__PMC_EV(IAP, EVENT_3CH_01H) \
__PMC_EV(IAP, EVENT_3CH_02H) \
+__PMC_EV(IAP, EVENT_3DH_01H) \
__PMC_EV(IAP, EVENT_40H) \
+__PMC_EV(IAP, EVENT_40H_01H) \
+__PMC_EV(IAP, EVENT_40H_02H) \
+__PMC_EV(IAP, EVENT_40H_04H) \
+__PMC_EV(IAP, EVENT_40H_08H) \
+__PMC_EV(IAP, EVENT_40H_0FH) \
__PMC_EV(IAP, EVENT_40H_21H) \
__PMC_EV(IAP, EVENT_41H) \
+__PMC_EV(IAP, EVENT_41H_01H) \
+__PMC_EV(IAP, EVENT_41H_02H) \
+__PMC_EV(IAP, EVENT_41H_04H) \
+__PMC_EV(IAP, EVENT_41H_08H) \
+__PMC_EV(IAP, EVENT_41H_0FH) \
__PMC_EV(IAP, EVENT_41H_22H) \
__PMC_EV(IAP, EVENT_42H) \
+__PMC_EV(IAP, EVENT_42H_01H) \
+__PMC_EV(IAP, EVENT_42H_02H) \
+__PMC_EV(IAP, EVENT_42H_04H) \
+__PMC_EV(IAP, EVENT_42H_08H) \
__PMC_EV(IAP, EVENT_42H_10H) \
__PMC_EV(IAP, EVENT_43H_01H) \
__PMC_EV(IAP, EVENT_43H_02H) \
@@ -553,22 +664,50 @@ __PMC_EV(IAP, EVENT_45H_0FH) \
__PMC_EV(IAP, EVENT_46H_00H) \
__PMC_EV(IAP, EVENT_47H_00H) \
__PMC_EV(IAP, EVENT_48H_00H) \
+__PMC_EV(IAP, EVENT_48H_02H) \
__PMC_EV(IAP, EVENT_49H_00H) \
__PMC_EV(IAP, EVENT_49H_01H) \
__PMC_EV(IAP, EVENT_49H_02H) \
+__PMC_EV(IAP, EVENT_49H_04H) \
+__PMC_EV(IAP, EVENT_49H_10H) \
+__PMC_EV(IAP, EVENT_49H_20H) \
+__PMC_EV(IAP, EVENT_49H_40H) \
+__PMC_EV(IAP, EVENT_49H_80H) \
__PMC_EV(IAP, EVENT_4BH_00H) \
__PMC_EV(IAP, EVENT_4BH_01H) \
__PMC_EV(IAP, EVENT_4BH_02H) \
__PMC_EV(IAP, EVENT_4BH_03H) \
+__PMC_EV(IAP, EVENT_4BH_08H) \
__PMC_EV(IAP, EVENT_4CH_00H) \
+__PMC_EV(IAP, EVENT_4CH_01H) \
+__PMC_EV(IAP, EVENT_4DH_01H) \
+__PMC_EV(IAP, EVENT_4EH_01H) \
+__PMC_EV(IAP, EVENT_4EH_02H) \
+__PMC_EV(IAP, EVENT_4EH_04H) \
__PMC_EV(IAP, EVENT_4EH_10H) \
__PMC_EV(IAP, EVENT_4FH_00H) \
+__PMC_EV(IAP, EVENT_4FH_02H) \
+__PMC_EV(IAP, EVENT_4FH_04H) \
+__PMC_EV(IAP, EVENT_4FH_08H) \
+__PMC_EV(IAP, EVENT_4FH_10H) \
+__PMC_EV(IAP, EVENT_51H_01H) \
+__PMC_EV(IAP, EVENT_51H_02H) \
+__PMC_EV(IAP, EVENT_51H_04H) \
+__PMC_EV(IAP, EVENT_51H_08H) \
+__PMC_EV(IAP, EVENT_52H_01H) \
+__PMC_EV(IAP, EVENT_53H_01H) \
__PMC_EV(IAP, EVENT_60H) \
+__PMC_EV(IAP, EVENT_60H_01H) \
+__PMC_EV(IAP, EVENT_60H_02H) \
+__PMC_EV(IAP, EVENT_60H_04H) \
+__PMC_EV(IAP, EVENT_60H_08H) \
__PMC_EV(IAP, EVENT_61H) \
__PMC_EV(IAP, EVENT_61H_00H) \
__PMC_EV(IAP, EVENT_62H) \
__PMC_EV(IAP, EVENT_62H_00H) \
__PMC_EV(IAP, EVENT_63H) \
+__PMC_EV(IAP, EVENT_63H_01H) \
+__PMC_EV(IAP, EVENT_63H_02H) \
__PMC_EV(IAP, EVENT_64H) \
__PMC_EV(IAP, EVENT_64H_40H) \
__PMC_EV(IAP, EVENT_65H) \
@@ -579,6 +718,7 @@ __PMC_EV(IAP, EVENT_69H) \
__PMC_EV(IAP, EVENT_6AH) \
__PMC_EV(IAP, EVENT_6BH) \
__PMC_EV(IAP, EVENT_6CH) \
+__PMC_EV(IAP, EVENT_6CH_01H) \
__PMC_EV(IAP, EVENT_6DH) \
__PMC_EV(IAP, EVENT_6EH) \
__PMC_EV(IAP, EVENT_6FH) \
@@ -592,20 +732,59 @@ __PMC_EV(IAP, EVENT_7EH) \
__PMC_EV(IAP, EVENT_7EH_00H) \
__PMC_EV(IAP, EVENT_7FH) \
__PMC_EV(IAP, EVENT_80H_00H) \
+__PMC_EV(IAP, EVENT_80H_01H) \
__PMC_EV(IAP, EVENT_80H_02H) \
__PMC_EV(IAP, EVENT_80H_03H) \
+__PMC_EV(IAP, EVENT_80H_04H) \
+__PMC_EV(IAP, EVENT_80H_10H) \
__PMC_EV(IAP, EVENT_81H_00H) \
+__PMC_EV(IAP, EVENT_81H_01H) \
+__PMC_EV(IAP, EVENT_81H_02H) \
+__PMC_EV(IAP, EVENT_82H_01H) \
__PMC_EV(IAP, EVENT_82H_02H) \
__PMC_EV(IAP, EVENT_82H_04H) \
__PMC_EV(IAP, EVENT_82H_10H) \
__PMC_EV(IAP, EVENT_82H_12H) \
__PMC_EV(IAP, EVENT_82H_40H) \
+__PMC_EV(IAP, EVENT_83H_01H) \
__PMC_EV(IAP, EVENT_83H_02H) \
__PMC_EV(IAP, EVENT_85H_00H) \
+__PMC_EV(IAP, EVENT_85H_01H) \
+__PMC_EV(IAP, EVENT_85H_02H) \
+__PMC_EV(IAP, EVENT_85H_04H) \
+__PMC_EV(IAP, EVENT_85H_10H) \
+__PMC_EV(IAP, EVENT_85H_20H) \
+__PMC_EV(IAP, EVENT_85H_40H) \
+__PMC_EV(IAP, EVENT_85H_80H) \
__PMC_EV(IAP, EVENT_86H_00H) \
__PMC_EV(IAP, EVENT_87H_00H) \
+__PMC_EV(IAP, EVENT_87H_01H) \
+__PMC_EV(IAP, EVENT_87H_02H) \
+__PMC_EV(IAP, EVENT_87H_04H) \
+__PMC_EV(IAP, EVENT_87H_08H) \
+__PMC_EV(IAP, EVENT_87H_0FH) \
__PMC_EV(IAP, EVENT_88H_00H) \
+__PMC_EV(IAP, EVENT_88H_01H) \
+__PMC_EV(IAP, EVENT_88H_02H) \
+__PMC_EV(IAP, EVENT_88H_04H) \
+__PMC_EV(IAP, EVENT_88H_07H) \
+__PMC_EV(IAP, EVENT_88H_08H) \
+__PMC_EV(IAP, EVENT_88H_10H) \
+__PMC_EV(IAP, EVENT_88H_20H) \
+__PMC_EV(IAP, EVENT_88H_30H) \
+__PMC_EV(IAP, EVENT_88H_40H) \
+__PMC_EV(IAP, EVENT_88H_7FH) \
__PMC_EV(IAP, EVENT_89H_00H) \
+__PMC_EV(IAP, EVENT_89H_01H) \
+__PMC_EV(IAP, EVENT_89H_02H) \
+__PMC_EV(IAP, EVENT_89H_04H) \
+__PMC_EV(IAP, EVENT_89H_07H) \
+__PMC_EV(IAP, EVENT_89H_08H) \
+__PMC_EV(IAP, EVENT_89H_10H) \
+__PMC_EV(IAP, EVENT_89H_20H) \
+__PMC_EV(IAP, EVENT_89H_30H) \
+__PMC_EV(IAP, EVENT_89H_40H) \
+__PMC_EV(IAP, EVENT_89H_7FH) \
__PMC_EV(IAP, EVENT_8AH_00H) \
__PMC_EV(IAP, EVENT_8BH_00H) \
__PMC_EV(IAP, EVENT_8CH_00H) \
@@ -627,16 +806,45 @@ __PMC_EV(IAP, EVENT_A1H_08H) \
__PMC_EV(IAP, EVENT_A1H_10H) \
__PMC_EV(IAP, EVENT_A1H_20H) \
__PMC_EV(IAP, EVENT_A2H_00H) \
+__PMC_EV(IAP, EVENT_A2H_01H) \
+__PMC_EV(IAP, EVENT_A2H_02H) \
+__PMC_EV(IAP, EVENT_A2H_04H) \
+__PMC_EV(IAP, EVENT_A2H_08H) \
+__PMC_EV(IAP, EVENT_A2H_10H) \
+__PMC_EV(IAP, EVENT_A2H_20H) \
+__PMC_EV(IAP, EVENT_A2H_40H) \
+__PMC_EV(IAP, EVENT_A2H_80H) \
+__PMC_EV(IAP, EVENT_A6H_01H) \
+__PMC_EV(IAP, EVENT_A7H_01H) \
+__PMC_EV(IAP, EVENT_A8H_01H) \
__PMC_EV(IAP, EVENT_AAH_01H) \
__PMC_EV(IAP, EVENT_AAH_02H) \
__PMC_EV(IAP, EVENT_AAH_03H) \
__PMC_EV(IAP, EVENT_AAH_08H) \
__PMC_EV(IAP, EVENT_ABH_01H) \
__PMC_EV(IAP, EVENT_ABH_02H) \
+__PMC_EV(IAP, EVENT_AEH_01H) \
__PMC_EV(IAP, EVENT_B0H_00H) \
+__PMC_EV(IAP, EVENT_B0H_01H) \
+__PMC_EV(IAP, EVENT_B0H_02H) \
+__PMC_EV(IAP, EVENT_B0H_04H) \
+__PMC_EV(IAP, EVENT_B0H_08H) \
+__PMC_EV(IAP, EVENT_B0H_10H) \
+__PMC_EV(IAP, EVENT_B0H_20H) \
+__PMC_EV(IAP, EVENT_B0H_40H) \
__PMC_EV(IAP, EVENT_B0H_80H) \
__PMC_EV(IAP, EVENT_B1H_00H) \
+__PMC_EV(IAP, EVENT_B1H_01H) \
+__PMC_EV(IAP, EVENT_B1H_02H) \
+__PMC_EV(IAP, EVENT_B1H_04H) \
+__PMC_EV(IAP, EVENT_B1H_08H) \
+__PMC_EV(IAP, EVENT_B1H_10H) \
+__PMC_EV(IAP, EVENT_B1H_1FH) \
+__PMC_EV(IAP, EVENT_B1H_20H) \
+__PMC_EV(IAP, EVENT_B1H_3FH) \
+__PMC_EV(IAP, EVENT_B1H_40H) \
__PMC_EV(IAP, EVENT_B1H_80H) \
+__PMC_EV(IAP, EVENT_B2H_01H) \
__PMC_EV(IAP, EVENT_B3H_01H) \
__PMC_EV(IAP, EVENT_B3H_02H) \
__PMC_EV(IAP, EVENT_B3H_04H) \
@@ -649,6 +857,16 @@ __PMC_EV(IAP, EVENT_B3H_84H) \
__PMC_EV(IAP, EVENT_B3H_88H) \
__PMC_EV(IAP, EVENT_B3H_90H) \
__PMC_EV(IAP, EVENT_B3H_A0H) \
+__PMC_EV(IAP, EVENT_B4H_01H) \
+__PMC_EV(IAP, EVENT_B4H_02H) \
+__PMC_EV(IAP, EVENT_B4H_04H) \
+__PMC_EV(IAP, EVENT_B7H_01H) \
+__PMC_EV(IAP, EVENT_B8H_01H) \
+__PMC_EV(IAP, EVENT_B8H_02H) \
+__PMC_EV(IAP, EVENT_B8H_04H) \
+__PMC_EV(IAP, EVENT_BAH_01H) \
+__PMC_EV(IAP, EVENT_BAH_02H) \
+__PMC_EV(IAP, EVENT_BBH_01H) \
__PMC_EV(IAP, EVENT_C0H_00H) \
__PMC_EV(IAP, EVENT_C0H_01H) \
__PMC_EV(IAP, EVENT_C0H_02H) \
@@ -662,12 +880,14 @@ __PMC_EV(IAP, EVENT_C2H_01H) \
__PMC_EV(IAP, EVENT_C2H_02H) \
__PMC_EV(IAP, EVENT_C2H_04H) \
__PMC_EV(IAP, EVENT_C2H_07H) \
+__PMC_EV(IAP, EVENT_C2H_08H) \
__PMC_EV(IAP, EVENT_C2H_0FH) \
__PMC_EV(IAP, EVENT_C2H_10H) \
-__PMC_EV(IAP, EVENT_C2H_08H) \
__PMC_EV(IAP, EVENT_C3H_00H) \
__PMC_EV(IAP, EVENT_C3H_01H) \
+__PMC_EV(IAP, EVENT_C3H_02H) \
__PMC_EV(IAP, EVENT_C3H_04H) \
+__PMC_EV(IAP, EVENT_C3H_10H) \
__PMC_EV(IAP, EVENT_C4H_00H) \
__PMC_EV(IAP, EVENT_C4H_01H) \
__PMC_EV(IAP, EVENT_C4H_02H) \
@@ -676,6 +896,9 @@ __PMC_EV(IAP, EVENT_C4H_08H) \
__PMC_EV(IAP, EVENT_C4H_0CH) \
__PMC_EV(IAP, EVENT_C4H_0FH) \
__PMC_EV(IAP, EVENT_C5H_00H) \
+__PMC_EV(IAP, EVENT_C5H_01H) \
+__PMC_EV(IAP, EVENT_C5H_02H) \
+__PMC_EV(IAP, EVENT_C5H_04H) \
__PMC_EV(IAP, EVENT_C6H_00H) \
__PMC_EV(IAP, EVENT_C6H_01H) \
__PMC_EV(IAP, EVENT_C6H_02H) \
@@ -687,6 +910,7 @@ __PMC_EV(IAP, EVENT_C7H_08H) \
__PMC_EV(IAP, EVENT_C7H_10H) \
__PMC_EV(IAP, EVENT_C7H_1FH) \
__PMC_EV(IAP, EVENT_C8H_00H) \
+__PMC_EV(IAP, EVENT_C8H_20H) \
__PMC_EV(IAP, EVENT_C9H_00H) \
__PMC_EV(IAP, EVENT_CAH_00H) \
__PMC_EV(IAP, EVENT_CAH_01H) \
@@ -698,13 +922,21 @@ __PMC_EV(IAP, EVENT_CBH_02H) \
__PMC_EV(IAP, EVENT_CBH_04H) \
__PMC_EV(IAP, EVENT_CBH_08H) \
__PMC_EV(IAP, EVENT_CBH_10H) \
+__PMC_EV(IAP, EVENT_CBH_40H) \
+__PMC_EV(IAP, EVENT_CBH_80H) \
__PMC_EV(IAP, EVENT_CCH_00H) \
__PMC_EV(IAP, EVENT_CCH_01H) \
__PMC_EV(IAP, EVENT_CCH_02H) \
+__PMC_EV(IAP, EVENT_CCH_03H) \
__PMC_EV(IAP, EVENT_CDH_00H) \
__PMC_EV(IAP, EVENT_CEH_00H) \
__PMC_EV(IAP, EVENT_CFH_00H) \
__PMC_EV(IAP, EVENT_D0H_00H) \
+__PMC_EV(IAP, EVENT_D0H_01H) \
+__PMC_EV(IAP, EVENT_D1H_01H) \
+__PMC_EV(IAP, EVENT_D1H_02H) \
+__PMC_EV(IAP, EVENT_D1H_04H) \
+__PMC_EV(IAP, EVENT_D1H_08H) \
__PMC_EV(IAP, EVENT_D2H_01H) \
__PMC_EV(IAP, EVENT_D2H_02H) \
__PMC_EV(IAP, EVENT_D2H_04H) \
@@ -735,6 +967,7 @@ __PMC_EV(IAP, EVENT_DAH_00H) \
__PMC_EV(IAP, EVENT_DAH_01H) \
__PMC_EV(IAP, EVENT_DAH_02H) \
__PMC_EV(IAP, EVENT_DBH_00H) \
+__PMC_EV(IAP, EVENT_DBH_01H) \
__PMC_EV(IAP, EVENT_DCH_01H) \
__PMC_EV(IAP, EVENT_DCH_02H) \
__PMC_EV(IAP, EVENT_DCH_04H) \
@@ -745,249 +978,16 @@ __PMC_EV(IAP, EVENT_E0H_00H) \
__PMC_EV(IAP, EVENT_E0H_01H) \
__PMC_EV(IAP, EVENT_E2H_00H) \
__PMC_EV(IAP, EVENT_E4H_00H) \
-__PMC_EV(IAP, EVENT_E6H_00H) \
-__PMC_EV(IAP, EVENT_E6H_01H) \
-__PMC_EV(IAP, EVENT_F0H_00H) \
-__PMC_EV(IAP, EVENT_F8H_00H) \
-__PMC_EV(IAP, EVENT_02H_01H) \
-__PMC_EV(IAP, EVENT_03H_01H) \
-__PMC_EV(IAP, EVENT_05H_01H) \
-__PMC_EV(IAP, EVENT_05H_02H) \
-__PMC_EV(IAP, EVENT_05H_03H) \
-__PMC_EV(IAP, EVENT_06H_01H) \
-__PMC_EV(IAP, EVENT_06H_02H) \
-__PMC_EV(IAP, EVENT_06H_04H) \
-__PMC_EV(IAP, EVENT_06H_08H) \
-__PMC_EV(IAP, EVENT_06H_0FH) \
-__PMC_EV(IAP, EVENT_08H_10H) \
-__PMC_EV(IAP, EVENT_08H_20H) \
-__PMC_EV(IAP, EVENT_08H_40H) \
-__PMC_EV(IAP, EVENT_08H_80H) \
-__PMC_EV(IAP, EVENT_09H_04H) \
-__PMC_EV(IAP, EVENT_09H_08H) \
-__PMC_EV(IAP, EVENT_0BH_01H) \
-__PMC_EV(IAP, EVENT_0BH_02H) \
-__PMC_EV(IAP, EVENT_0EH_01H) \
-__PMC_EV(IAP, EVENT_0EH_02H) \
-__PMC_EV(IAP, EVENT_0FH_02H) \
-__PMC_EV(IAP, EVENT_0FH_08H) \
-__PMC_EV(IAP, EVENT_0FH_10H) \
-__PMC_EV(IAP, EVENT_0FH_20H) \
-__PMC_EV(IAP, EVENT_10H_02H) \
-__PMC_EV(IAP, EVENT_10H_04H) \
-__PMC_EV(IAP, EVENT_10H_08H) \
-__PMC_EV(IAP, EVENT_10H_10H) \
-__PMC_EV(IAP, EVENT_10H_20H) \
-__PMC_EV(IAP, EVENT_10H_40H) \
-__PMC_EV(IAP, EVENT_10H_80H) \
-__PMC_EV(IAP, EVENT_12H_02H) \
-__PMC_EV(IAP, EVENT_12H_04H) \
-__PMC_EV(IAP, EVENT_12H_08H) \
-__PMC_EV(IAP, EVENT_12H_10H) \
-__PMC_EV(IAP, EVENT_12H_20H) \
-__PMC_EV(IAP, EVENT_12H_40H) \
-__PMC_EV(IAP, EVENT_13H_02H) \
-__PMC_EV(IAP, EVENT_13H_04H) \
-__PMC_EV(IAP, EVENT_13H_07H) \
-__PMC_EV(IAP, EVENT_14H_02H) \
-__PMC_EV(IAP, EVENT_17H_01H) \
-__PMC_EV(IAP, EVENT_18H_01H) \
-__PMC_EV(IAP, EVENT_1DH_01H) \
-__PMC_EV(IAP, EVENT_1DH_02H) \
-__PMC_EV(IAP, EVENT_1DH_04H) \
-__PMC_EV(IAP, EVENT_1EH_01H) \
-__PMC_EV(IAP, EVENT_24H_01H) \
-__PMC_EV(IAP, EVENT_24H_02H) \
-__PMC_EV(IAP, EVENT_24H_03H) \
-__PMC_EV(IAP, EVENT_24H_04H) \
-__PMC_EV(IAP, EVENT_24H_08H) \
-__PMC_EV(IAP, EVENT_24H_0CH) \
-__PMC_EV(IAP, EVENT_24H_10H) \
-__PMC_EV(IAP, EVENT_24H_20H) \
-__PMC_EV(IAP, EVENT_24H_30H) \
-__PMC_EV(IAP, EVENT_24H_40H) \
-__PMC_EV(IAP, EVENT_24H_80H) \
-__PMC_EV(IAP, EVENT_24H_AAH) \
-__PMC_EV(IAP, EVENT_24H_C0H) \
-__PMC_EV(IAP, EVENT_24H_FFH) \
-__PMC_EV(IAP, EVENT_26H_01H) \
-__PMC_EV(IAP, EVENT_26H_02H) \
-__PMC_EV(IAP, EVENT_26H_04H) \
-__PMC_EV(IAP, EVENT_26H_08H) \
-__PMC_EV(IAP, EVENT_26H_0FH) \
-__PMC_EV(IAP, EVENT_26H_10H) \
-__PMC_EV(IAP, EVENT_26H_20H) \
-__PMC_EV(IAP, EVENT_26H_40H) \
-__PMC_EV(IAP, EVENT_26H_80H) \
-__PMC_EV(IAP, EVENT_26H_F0H) \
-__PMC_EV(IAP, EVENT_26H_FFH) \
-__PMC_EV(IAP, EVENT_27H_01H) \
-__PMC_EV(IAP, EVENT_27H_02H) \
-__PMC_EV(IAP, EVENT_27H_04H) \
-__PMC_EV(IAP, EVENT_27H_08H) \
-__PMC_EV(IAP, EVENT_27H_0EH) \
-__PMC_EV(IAP, EVENT_27H_0FH) \
-__PMC_EV(IAP, EVENT_27H_10H) \
-__PMC_EV(IAP, EVENT_27H_20H) \
-__PMC_EV(IAP, EVENT_27H_40H) \
-__PMC_EV(IAP, EVENT_27H_80H) \
-__PMC_EV(IAP, EVENT_27H_E0H) \
-__PMC_EV(IAP, EVENT_27H_F0H) \
-__PMC_EV(IAP, EVENT_28H_01H) \
-__PMC_EV(IAP, EVENT_28H_02H) \
-__PMC_EV(IAP, EVENT_28H_04H) \
-__PMC_EV(IAP, EVENT_28H_08H) \
-__PMC_EV(IAP, EVENT_28H_0FH) \
-__PMC_EV(IAP, EVENT_3DH_01H) \
-__PMC_EV(IAP, EVENT_40H_01H) \
-__PMC_EV(IAP, EVENT_40H_02H) \
-__PMC_EV(IAP, EVENT_40H_04H) \
-__PMC_EV(IAP, EVENT_40H_08H) \
-__PMC_EV(IAP, EVENT_40H_0FH) \
-__PMC_EV(IAP, EVENT_41H_01H) \
-__PMC_EV(IAP, EVENT_41H_02H) \
-__PMC_EV(IAP, EVENT_41H_04H) \
-__PMC_EV(IAP, EVENT_41H_08H) \
-__PMC_EV(IAP, EVENT_41H_0FH) \
-__PMC_EV(IAP, EVENT_42H_01H) \
-__PMC_EV(IAP, EVENT_42H_02H) \
-__PMC_EV(IAP, EVENT_42H_04H) \
-__PMC_EV(IAP, EVENT_42H_08H) \
-__PMC_EV(IAP, EVENT_48H_02H) \
-__PMC_EV(IAP, EVENT_49H_10H) \
-__PMC_EV(IAP, EVENT_49H_20H) \
-__PMC_EV(IAP, EVENT_49H_40H) \
-__PMC_EV(IAP, EVENT_49H_80H) \
-__PMC_EV(IAP, EVENT_4BH_08H) \
-__PMC_EV(IAP, EVENT_4CH_01H) \
-__PMC_EV(IAP, EVENT_4DH_01H) \
-__PMC_EV(IAP, EVENT_4EH_01H) \
-__PMC_EV(IAP, EVENT_4EH_02H) \
-__PMC_EV(IAP, EVENT_4EH_04H) \
-__PMC_EV(IAP, EVENT_4FH_02H) \
-__PMC_EV(IAP, EVENT_4FH_04H) \
-__PMC_EV(IAP, EVENT_4FH_08H) \
-__PMC_EV(IAP, EVENT_51H_01H) \
-__PMC_EV(IAP, EVENT_51H_02H) \
-__PMC_EV(IAP, EVENT_51H_04H) \
-__PMC_EV(IAP, EVENT_51H_08H) \
-__PMC_EV(IAP, EVENT_52H_01H) \
-__PMC_EV(IAP, EVENT_53H_01H) \
-__PMC_EV(IAP, EVENT_60H_01H) \
-__PMC_EV(IAP, EVENT_60H_02H) \
-__PMC_EV(IAP, EVENT_60H_04H) \
-__PMC_EV(IAP, EVENT_60H_08H) \
-__PMC_EV(IAP, EVENT_63H_01H) \
-__PMC_EV(IAP, EVENT_63H_02H) \
-__PMC_EV(IAP, EVENT_6CH_01H) \
-__PMC_EV(IAP, EVENT_80H_01H) \
-__PMC_EV(IAP, EVENT_80H_04H) \
-__PMC_EV(IAP, EVENT_80H_10H) \
-__PMC_EV(IAP, EVENT_81H_01H) \
-__PMC_EV(IAP, EVENT_81H_02H) \
-__PMC_EV(IAP, EVENT_82H_01H) \
-__PMC_EV(IAP, EVENT_83H_01H) \
-__PMC_EV(IAP, EVENT_85H_01H) \
-__PMC_EV(IAP, EVENT_85H_02H) \
-__PMC_EV(IAP, EVENT_85H_04H) \
-__PMC_EV(IAP, EVENT_85H_10H) \
-__PMC_EV(IAP, EVENT_85H_20H) \
-__PMC_EV(IAP, EVENT_85H_40H) \
-__PMC_EV(IAP, EVENT_85H_80H) \
-__PMC_EV(IAP, EVENT_87H_01H) \
-__PMC_EV(IAP, EVENT_87H_02H) \
-__PMC_EV(IAP, EVENT_87H_04H) \
-__PMC_EV(IAP, EVENT_87H_08H) \
-__PMC_EV(IAP, EVENT_87H_0FH) \
-__PMC_EV(IAP, EVENT_88H_01H) \
-__PMC_EV(IAP, EVENT_88H_02H) \
-__PMC_EV(IAP, EVENT_88H_04H) \
-__PMC_EV(IAP, EVENT_88H_07H) \
-__PMC_EV(IAP, EVENT_88H_08H) \
-__PMC_EV(IAP, EVENT_88H_10H) \
-__PMC_EV(IAP, EVENT_88H_20H) \
-__PMC_EV(IAP, EVENT_88H_30H) \
-__PMC_EV(IAP, EVENT_88H_40H) \
-__PMC_EV(IAP, EVENT_89H_01H) \
-__PMC_EV(IAP, EVENT_89H_02H) \
-__PMC_EV(IAP, EVENT_89H_04H) \
-__PMC_EV(IAP, EVENT_89H_07H) \
-__PMC_EV(IAP, EVENT_89H_08H) \
-__PMC_EV(IAP, EVENT_89H_10H) \
-__PMC_EV(IAP, EVENT_89H_20H) \
-__PMC_EV(IAP, EVENT_89H_30H) \
-__PMC_EV(IAP, EVENT_89H_40H) \
-__PMC_EV(IAP, EVENT_89H_7FH) \
-__PMC_EV(IAP, EVENT_A2H_01H) \
-__PMC_EV(IAP, EVENT_A2H_02H) \
-__PMC_EV(IAP, EVENT_A2H_04H) \
-__PMC_EV(IAP, EVENT_A2H_08H) \
-__PMC_EV(IAP, EVENT_A2H_10H) \
-__PMC_EV(IAP, EVENT_A2H_20H) \
-__PMC_EV(IAP, EVENT_A2H_40H) \
-__PMC_EV(IAP, EVENT_A2H_80H) \
-__PMC_EV(IAP, EVENT_A6H_01H) \
-__PMC_EV(IAP, EVENT_A7H_01H) \
-__PMC_EV(IAP, EVENT_A8H_01H) \
-__PMC_EV(IAP, EVENT_B0H_01H) \
-__PMC_EV(IAP, EVENT_B0H_02H) \
-__PMC_EV(IAP, EVENT_B0H_04H) \
-__PMC_EV(IAP, EVENT_B0H_08H) \
-__PMC_EV(IAP, EVENT_B0H_20H) \
-__PMC_EV(IAP, EVENT_B0H_40H) \
-__PMC_EV(IAP, EVENT_B1H_01H) \
-__PMC_EV(IAP, EVENT_B1H_02H) \
-__PMC_EV(IAP, EVENT_B1H_04H) \
-__PMC_EV(IAP, EVENT_B1H_08H) \
-__PMC_EV(IAP, EVENT_B1H_10H) \
-__PMC_EV(IAP, EVENT_B1H_20H) \
-__PMC_EV(IAP, EVENT_B1H_40H) \
-__PMC_EV(IAP, EVENT_B2H_01H) \
-__PMC_EV(IAP, EVENT_B7H_01H) \
-__PMC_EV(IAP, EVENT_B8H_01H) \
-__PMC_EV(IAP, EVENT_B8H_02H) \
-__PMC_EV(IAP, EVENT_B8H_04H) \
-__PMC_EV(IAP, EVENT_BAH_01H) \
-__PMC_EV(IAP, EVENT_BAH_02H) \
-__PMC_EV(IAP, EVENT_C3H_02H) \
-__PMC_EV(IAP, EVENT_C3H_10H) \
-__PMC_EV(IAP, EVENT_C5H_02H) \
-__PMC_EV(IAP, EVENT_C8H_20H) \
-__PMC_EV(IAP, EVENT_CBH_40H) \
-__PMC_EV(IAP, EVENT_CBH_80H) \
-__PMC_EV(IAP, EVENT_CCH_03H) \
-__PMC_EV(IAP, EVENT_D0H_01H) \
-__PMC_EV(IAP, EVENT_D1H_02H) \
-__PMC_EV(IAP, EVENT_D1H_04H) \
-__PMC_EV(IAP, EVENT_D1H_08H) \
-__PMC_EV(IAP, EVENT_DBH_01H) \
__PMC_EV(IAP, EVENT_E4H_01H) \
__PMC_EV(IAP, EVENT_E5H_01H) \
-__PMC_EV(IAP, EVENT_F3H_04H) \
-__PMC_EV(IAP, EVENT_F3H_08H) \
-__PMC_EV(IAP, EVENT_F3H_10H) \
-__PMC_EV(IAP, EVENT_F3H_20H) \
-__PMC_EV(IAP, EVENT_F4H_01H) \
-__PMC_EV(IAP, EVENT_F4H_02H) \
-__PMC_EV(IAP, EVENT_F4H_04H) \
-__PMC_EV(IAP, EVENT_F4H_08H) \
-__PMC_EV(IAP, EVENT_F4H_10H) \
-__PMC_EV(IAP, EVENT_F6H_01H) \
-__PMC_EV(IAP, EVENT_F7H_01H) \
-__PMC_EV(IAP, EVENT_F7H_02H) \
-__PMC_EV(IAP, EVENT_F7H_04H) \
-__PMC_EV(IAP, EVENT_F8H_01H) \
-__PMC_EV(IAP, EVENT_FDH_01H) \
-__PMC_EV(IAP, EVENT_FDH_02H) \
-__PMC_EV(IAP, EVENT_FDH_04H) \
-__PMC_EV(IAP, EVENT_FDH_08H) \
-__PMC_EV(IAP, EVENT_FDH_10H) \
-__PMC_EV(IAP, EVENT_FDH_20H) \
-__PMC_EV(IAP, EVENT_FDH_40H) \
+__PMC_EV(IAP, EVENT_E6H_00H) \
+__PMC_EV(IAP, EVENT_E6H_01H) \
__PMC_EV(IAP, EVENT_E6H_02H) \
__PMC_EV(IAP, EVENT_E8H_01H) \
__PMC_EV(IAP, EVENT_E8H_02H) \
__PMC_EV(IAP, EVENT_E8H_03H) \
+__PMC_EV(IAP, EVENT_ECH_01H) \
+__PMC_EV(IAP, EVENT_F0H_00H) \
__PMC_EV(IAP, EVENT_F0H_01H) \
__PMC_EV(IAP, EVENT_F0H_02H) \
__PMC_EV(IAP, EVENT_F0H_04H) \
@@ -1005,10 +1005,31 @@ __PMC_EV(IAP, EVENT_F2H_04H) \
__PMC_EV(IAP, EVENT_F2H_08H) \
__PMC_EV(IAP, EVENT_F2H_0FH) \
__PMC_EV(IAP, EVENT_F3H_01H) \
-__PMC_EV(IAP, EVENT_F3H_02H)
-
+__PMC_EV(IAP, EVENT_F3H_02H) \
+__PMC_EV(IAP, EVENT_F3H_04H) \
+__PMC_EV(IAP, EVENT_F3H_08H) \
+__PMC_EV(IAP, EVENT_F3H_10H) \
+__PMC_EV(IAP, EVENT_F3H_20H) \
+__PMC_EV(IAP, EVENT_F4H_01H) \
+__PMC_EV(IAP, EVENT_F4H_02H) \
+__PMC_EV(IAP, EVENT_F4H_04H) \
+__PMC_EV(IAP, EVENT_F4H_08H) \
+__PMC_EV(IAP, EVENT_F4H_10H) \
+__PMC_EV(IAP, EVENT_F6H_01H) \
+__PMC_EV(IAP, EVENT_F7H_01H) \
+__PMC_EV(IAP, EVENT_F7H_02H) \
+__PMC_EV(IAP, EVENT_F7H_04H) \
+__PMC_EV(IAP, EVENT_F8H_00H) \
+__PMC_EV(IAP, EVENT_F8H_01H) \
+__PMC_EV(IAP, EVENT_FDH_01H) \
+__PMC_EV(IAP, EVENT_FDH_02H) \
+__PMC_EV(IAP, EVENT_FDH_04H) \
+__PMC_EV(IAP, EVENT_FDH_08H) \
+__PMC_EV(IAP, EVENT_FDH_10H) \
+__PMC_EV(IAP, EVENT_FDH_20H) \
+__PMC_EV(IAP, EVENT_FDH_40H)
-#define PMC_EV_IAP_FIRST PMC_EV_IAP_EVENT_02H_81H
+#define PMC_EV_IAP_FIRST PMC_EV_IAP_EVENT_02H_01H
#define PMC_EV_IAP_LAST PMC_EV_IAP_EVENT_FDH_40H
/*
@@ -1647,330 +1668,655 @@ __PMC_EV_ALIAS("X87_OPS_RETIRED.ANY", IAP_EVENT_C1H_FEH) \
__PMC_EV_ALIAS("X87_OPS_RETIRED.FXCH", IAP_EVENT_C1H_01H)
/*
- * Aliases for Core i7 PMC events.
+ * Core i7 and Xeon 5500 events removed between 253669-031US June 2009
+ * and 253669-033US December 2009.
+ */
+#define __PMC_EV_ALIAS_COREI7_OLD() \
+__PMC_EV_ALIAS("SB_FORWARD.ANY", IAP_EVENT_02H_01H) \
+__PMC_EV_ALIAS("LOAD_BLOCK.STD", IAP_EVENT_03H_01H) \
+__PMC_EV_ALIAS("LOAD_BLOCK.ADDRESS_OFFSET", IAP_EVENT_03H_04H) \
+__PMC_EV_ALIAS("SB_DRAIN.CYCLES", IAP_EVENT_04H_01H) \
+__PMC_EV_ALIAS("MISALIGN_MEM_REF.LOAD", IAP_EVENT_05H_01H) \
+__PMC_EV_ALIAS("MISALIGN_MEM_REF.STORE", IAP_EVENT_05H_02H) \
+__PMC_EV_ALIAS("MISALIGN_MEM_REF.ANY", IAP_EVENT_05H_03H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.NOT_STA", IAP_EVENT_06H_01H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.STA", IAP_EVENT_06H_02H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.ANY", IAP_EVENT_06H_0FH) \
+__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.RESET", IAP_EVENT_09H_01H) \
+__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.SUCCESS", IAP_EVENT_09H_02H) \
+__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCHDOG", IAP_EVENT_09H_04H) \
+__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCH_CYCLES", IAP_EVENT_09H_08H)\
+__PMC_EV_ALIAS("HW_INT.RCV", IAP_EVENT_1DH_01H) \
+__PMC_EV_ALIAS("HW_INT.CYCLES_MASKED", IAP_EVENT_1DH_02H) \
+__PMC_EV_ALIAS("HW_INT.CYCLES_PENDING_AND_MASKED", IAP_EVENT_1DH_04H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.E_STATE", IAP_EVENT_27H_04H) \
+__PMC_EV_ALIAS("UOPS_DECODED.DEC0", IAP_EVENT_3DH_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_ST.I_STATE", IAP_EVENT_41H_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_ST.MESI", IAP_EVENT_41H_0FH) \
+__PMC_EV_ALIAS("DTLB_MISSES.PDE_MISS", IAP_EVENT_49H_20H) \
+__PMC_EV_ALIAS("DTLB_MISSES.PDP_MISS", IAP_EVENT_49H_40H) \
+__PMC_EV_ALIAS("DTLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_49H_80H) \
+__PMC_EV_ALIAS("SSE_MEM_EXEC.NTA", IAP_EVENT_4BH_01H) \
+__PMC_EV_ALIAS("SSE_MEM_EXEC.STREAMING_STORES", IAP_EVENT_4BH_08H) \
+__PMC_EV_ALIAS("SFENCE_CYCLES", IAP_EVENT_4DH_01H) \
+__PMC_EV_ALIAS("EPT.EPDE_MISS", IAP_EVENT_4FH_02H) \
+__PMC_EV_ALIAS("EPT.EPDPE_HIT", IAP_EVENT_4FH_04H) \
+__PMC_EV_ALIAS("EPT.EPDPE_MISS", IAP_EVENT_4FH_08H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA", \
+ IAP_EVENT_60H_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE", \
+ IAP_EVENT_60H_02H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO", \
+ IAP_EVENT_60H_04H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ANY.READ", \
+ IAP_EVENT_60H_08H) \
+__PMC_EV_ALIAS("IFU_IVC.FULL", IAP_EVENT_81H_01H) \
+__PMC_EV_ALIAS("IFU_IVC.L1I_EVICTION", IAP_EVENT_81H_02H) \
+__PMC_EV_ALIAS("L1I_OPPORTUNISTIC_HITS", IAP_EVENT_83H_01H) \
+__PMC_EV_ALIAS("ITLB_MISSES.WALK_CYCLES", IAP_EVENT_85H_04H) \
+__PMC_EV_ALIAS("ITLB_MISSES.PMH_BUSY_CYCLES", IAP_EVENT_85H_04H) \
+__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT", IAP_EVENT_85H_10H) \
+__PMC_EV_ALIAS("ITLB_MISSES.PDE_MISS", IAP_EVENT_85H_20H) \
+__PMC_EV_ALIAS("ITLB_MISSES.PDP_MISS", IAP_EVENT_85H_40H) \
+__PMC_EV_ALIAS("ITLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_85H_80H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_DATA", IAP_EVENT_B0H_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_CODE", IAP_EVENT_B0H_02H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.RFO", IAP_EVENT_B0H_04H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.READ", IAP_EVENT_B0H_08H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.RFO", IAP_EVENT_B0H_10H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.UNCACHED_MEM", IAP_EVENT_B0H_20H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY", IAP_EVENT_B0H_80H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.DATA", IAP_EVENT_B3H_01H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE", \
+ IAP_EVENT_B3H_02H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.CODE", IAP_EVENT_B3H_04H) \
+__PMC_EV_ALIAS("PIC_ACCESSES.TPR_READS", IAP_EVENT_BAH_01H) \
+__PMC_EV_ALIAS("PIC_ACCESSES.TPR_WRITES", IAP_EVENT_BAH_02H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.FUSION_ASSIST", IAP_EVENT_C3H_10H) \
+__PMC_EV_ALIAS("BOGUS_BR", IAP_EVENT_E4H_01H) \
+__PMC_EV_ALIAS("L2_HW_PREFETCH.HIT", IAP_EVENT_F3H_01H) \
+__PMC_EV_ALIAS("L2_HW_PREFETCH.ALLOC", IAP_EVENT_F3H_02H) \
+__PMC_EV_ALIAS("L2_HW_PREFETCH.DATA_TRIGGER", IAP_EVENT_F3H_04H) \
+__PMC_EV_ALIAS("L2_HW_PREFETCH.CODE_TRIGGER", IAP_EVENT_F3H_08H) \
+__PMC_EV_ALIAS("L2_HW_PREFETCH.DCA_TRIGGER", IAP_EVENT_F3H_10H) \
+__PMC_EV_ALIAS("L2_HW_PREFETCH.KICK_START", IAP_EVENT_F3H_20H) \
+__PMC_EV_ALIAS("SQ_MISC.PROMOTION", IAP_EVENT_F4H_01H) \
+__PMC_EV_ALIAS("SQ_MISC.PROMOTION_POST_GO", IAP_EVENT_F4H_02H) \
+__PMC_EV_ALIAS("SQ_MISC.LRU_HINTS", IAP_EVENT_F4H_04H) \
+__PMC_EV_ALIAS("SQ_MISC.FILL_DROPPED", IAP_EVENT_F4H_08H) \
+__PMC_EV_ALIAS("SEGMENT_REG_LOADS", IAP_EVENT_F8H_01H)
+
+/*
+ * Aliases for Core i7 and Xeon 5500 PMC events (253669-033US December 2009)
*/
#define __PMC_EV_ALIAS_COREI7() \
__PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \
-__PMC_EV_ALIAS("SB_FORWARD.ANY", IAP_EVENT_02H_01H) \
-__PMC_EV_ALIAS("LOAD_BLOCK.STD", IAP_EVENT_03H_01H) \
-__PMC_EV_ALIAS("LOAD_BLOCK.ADDRESS_OFFSET", IAP_EVENT_03H_04H) \
-__PMC_EV_ALIAS("SB_DRAIN.CYCLES", IAP_EVENT_04H_01H) \
-__PMC_EV_ALIAS("MISALIGN_MEM_REF.LOAD", IAP_EVENT_05H_01H) \
-__PMC_EV_ALIAS("MISALIGN_MEM_REF.STORE", IAP_EVENT_05H_02H) \
-__PMC_EV_ALIAS("MISALIGN_MEM_REF.ANY", IAP_EVENT_05H_03H) \
-__PMC_EV_ALIAS("STORE_BLOCKS.NOT_STA", IAP_EVENT_06H_01H) \
-__PMC_EV_ALIAS("STORE_BLOCKS.STA", IAP_EVENT_06H_02H) \
-__PMC_EV_ALIAS("STORE_BLOCKS.AT_RET", IAP_EVENT_06H_04H) \
-__PMC_EV_ALIAS("STORE_BLOCKS.L1D_BLOCK", IAP_EVENT_06H_08H) \
-__PMC_EV_ALIAS("STORE_BLOCKS.ANY", IAP_EVENT_06H_0FH) \
-__PMC_EV_ALIAS("PARTIAL_ADDRESS_ALIAS", IAP_EVENT_07H_01H) \
-__PMC_EV_ALIAS("DTLB_LOAD_MISSES.ANY", IAP_EVENT_08H_01H) \
-__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_02H) \
-__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_10H) \
-__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_MISS", IAP_EVENT_08H_20H) \
-__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDP_MISS", IAP_EVENT_08H_40H) \
-__PMC_EV_ALIAS("DTLB_LOAD_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_08H_80H) \
-__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.RESET", IAP_EVENT_09H_01H) \
-__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.SUCCESS", IAP_EVENT_09H_02H) \
-__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCHDOG", IAP_EVENT_09H_04H) \
-__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCH_CYCLES", IAP_EVENT_09H_08H) \
-__PMC_EV_ALIAS("MEM_INST_RETIRED.LOADS", IAP_EVENT_0BH_01H) \
-__PMC_EV_ALIAS("MEM_INST_RETIRED.STORES", IAP_EVENT_0BH_02H) \
-__PMC_EV_ALIAS("MEM_STORE_RETIRED.DTLB_MISS", IAP_EVENT_0CH_01H) \
-__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \
-__PMC_EV_ALIAS("UOPS_ISSUED.FUSED", IAP_EVENT_0EH_02H) \
-__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.OTHER_CORE_L2_HITM", IAP_EVENT_0FH_02H) \
-__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_CACHE_LOCAL_HOME_HIT", IAP_EVENT_0FH_08H) \
-__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_DRAM", IAP_EVENT_0FH_10H) \
-__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM", IAP_EVENT_0FH_20H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.MMX", IAP_EVENT_10H_02H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP", IAP_EVENT_10H_04H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE2_INTEGER", IAP_EVENT_10H_08H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED", IAP_EVENT_10H_10H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR", IAP_EVENT_10H_20H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION", IAP_EVENT_10H_40H) \
-__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION", IAP_EVENT_10H_80H) \
-__PMC_EV_ALIAS("SIMD_INT_128.PACKED_MPY", IAP_EVENT_12H_01H) \
-__PMC_EV_ALIAS("SIMD_INT_128.PACKED_SHIFT", IAP_EVENT_12H_02H) \
-__PMC_EV_ALIAS("SIMD_INT_128.PACK", IAP_EVENT_12H_04H) \
-__PMC_EV_ALIAS("SIMD_INT_128.UNPACK", IAP_EVENT_12H_08H) \
-__PMC_EV_ALIAS("SIMD_INT_128.PACKED_LOGICAL", IAP_EVENT_12H_10H) \
-__PMC_EV_ALIAS("SIMD_INT_128.PACKED_ARITH", IAP_EVENT_12H_20H) \
-__PMC_EV_ALIAS("SIMD_INT_128.SHUFFLE_MOVE", IAP_EVENT_12H_40H) \
-__PMC_EV_ALIAS("LOAD_DISPATCH.RS", IAP_EVENT_13H_01H) \
-__PMC_EV_ALIAS("LOAD_DISPATCH.RS_DELAYED", IAP_EVENT_13H_02H) \
-__PMC_EV_ALIAS("LOAD_DISPATCH.MOB", IAP_EVENT_13H_04H) \
-__PMC_EV_ALIAS("LOAD_DISPATCH.ANY", IAP_EVENT_13H_07H) \
-__PMC_EV_ALIAS("ARITH.CYCLES_DIV_BUSY", IAP_EVENT_14H_01H) \
-__PMC_EV_ALIAS("ARITH.MUL", IAP_EVENT_14H_02H) \
-__PMC_EV_ALIAS("INST_QUEUE_WRITES", IAP_EVENT_17H_01H) \
-__PMC_EV_ALIAS("INST_DECODED.DEC0", IAP_EVENT_18H_01H) \
-__PMC_EV_ALIAS("TWO_UOP_INSTS_DECODED", IAP_EVENT_19H_01H) \
-__PMC_EV_ALIAS("HW_INT.RCV", IAP_EVENT_1DH_01H) \
-__PMC_EV_ALIAS("HW_INT.CYCLES_MASKED", IAP_EVENT_1DH_02H) \
-__PMC_EV_ALIAS("HW_INT.CYCLES_PENDING_AND_MASKED", IAP_EVENT_1DH_04H) \
-__PMC_EV_ALIAS("INST_QUEUE_WRITE_CYCLES", IAP_EVENT_1EH_01H) \
-__PMC_EV_ALIAS("L2_RQSTS.LD_HIT", IAP_EVENT_24H_01H) \
-__PMC_EV_ALIAS("L2_RQSTS.LD_MISS", IAP_EVENT_24H_02H) \
-__PMC_EV_ALIAS("L2_RQSTS.LOADS", IAP_EVENT_24H_03H) \
-__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT", IAP_EVENT_24H_04H) \
-__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_08H) \
-__PMC_EV_ALIAS("L2_RQSTS.RFOS", IAP_EVENT_24H_0CH) \
-__PMC_EV_ALIAS("L2_RQSTS.IFETCH_HIT", IAP_EVENT_24H_10H) \
-__PMC_EV_ALIAS("L2_RQSTS.IFETCH_MISS", IAP_EVENT_24H_20H) \
-__PMC_EV_ALIAS("L2_RQSTS.IFETCHES", IAP_EVENT_24H_30H) \
-__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_HIT", IAP_EVENT_24H_40H) \
-__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_MISS", IAP_EVENT_24H_80H) \
-__PMC_EV_ALIAS("L2_RQSTS.PREFETCHES", IAP_EVENT_24H_C0H) \
-__PMC_EV_ALIAS("L2_RQSTS.MISS", IAP_EVENT_24H_AAH) \
-__PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_FFH) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.I_STATE", IAP_EVENT_26H_01H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.S_STATE", IAP_EVENT_26H_02H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.E_STATE", IAP_EVENT_26H_04H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.M_STATE", IAP_EVENT_26H_08H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.MESI", IAP_EVENT_26H_0FH) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.I_STATE", IAP_EVENT_26H_10H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.S_STATE", IAP_EVENT_26H_20H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.E_STATE", IAP_EVENT_26H_40H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.M_STATE", IAP_EVENT_26H_80H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.MESI", IAP_EVENT_26H_F0H) \
-__PMC_EV_ALIAS("L2_DATA_RQSTS.ANY", IAP_EVENT_26H_FFH) \
-__PMC_EV_ALIAS("L2_WRITE.RFO.I_STATE", IAP_EVENT_27H_01H) \
-__PMC_EV_ALIAS("L2_WRITE.RFO.S_STATE", IAP_EVENT_27H_02H) \
-__PMC_EV_ALIAS("L2_WRITE.RFO.E_STATE", IAP_EVENT_27H_04H) \
-__PMC_EV_ALIAS("L2_WRITE.RFO.M_STATE", IAP_EVENT_27H_08H) \
-__PMC_EV_ALIAS("L2_WRITE.RFO.HIT", IAP_EVENT_27H_0EH) \
-__PMC_EV_ALIAS("L2_WRITE.RFO.MESI", IAP_EVENT_27H_0FH) \
-__PMC_EV_ALIAS("L2_WRITE.LOCK.I_STATE", IAP_EVENT_27H_10H) \
-__PMC_EV_ALIAS("L2_WRITE.LOCK.S_STATE", IAP_EVENT_27H_20H) \
-__PMC_EV_ALIAS("L2_WRITE.LOCK.E_STATE", IAP_EVENT_27H_40H) \
-__PMC_EV_ALIAS("L2_WRITE.LOCK.M_STATE", IAP_EVENT_27H_80H) \
-__PMC_EV_ALIAS("L2_WRITE.LOCK.HIT", IAP_EVENT_27H_E0H) \
-__PMC_EV_ALIAS("L2_WRITE.LOCK.MESI", IAP_EVENT_27H_F0H) \
-__PMC_EV_ALIAS("L1D_WB_L2.I_STATE", IAP_EVENT_28H_01H) \
-__PMC_EV_ALIAS("L1D_WB_L2.S_STATE", IAP_EVENT_28H_02H) \
-__PMC_EV_ALIAS("L1D_WB_L2.E_STATE", IAP_EVENT_28H_04H) \
-__PMC_EV_ALIAS("L1D_WB_L2.M_STATE", IAP_EVENT_28H_08H) \
-__PMC_EV_ALIAS("L1D_WB_L2.MESI", IAP_EVENT_28H_0FH) \
-__PMC_EV_ALIAS("LONGEST_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_4FH) \
-__PMC_EV_ALIAS("LONGEST_LAT_CACHE.MISS", IAP_EVENT_2EH_41H) \
-__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H) \
-__PMC_EV_ALIAS("CPU_CLK_UNHALTED.REF_P", IAP_EVENT_3CH_01H) \
-__PMC_EV_ALIAS("UOPS_DECODED.DEC0", IAP_EVENT_3DH_01H) \
-__PMC_EV_ALIAS("L1D_CACHE_LD.I_STATE", IAP_EVENT_40H_01H) \
-__PMC_EV_ALIAS("L1D_CACHE_LD.S_STATE", IAP_EVENT_40H_02H) \
-__PMC_EV_ALIAS("L1D_CACHE_LD.E_STATE", IAP_EVENT_40H_04H) \
-__PMC_EV_ALIAS("L1D_CACHE_LD.M_STATE", IAP_EVENT_40H_08H) \
-__PMC_EV_ALIAS("L1D_CACHE_LD.MESI", IAP_EVENT_40H_0FH) \
-__PMC_EV_ALIAS("L1D_CACHE_ST.I_STATE", IAP_EVENT_41H_01H) \
-__PMC_EV_ALIAS("L1D_CACHE_ST.S_STATE", IAP_EVENT_41H_02H) \
-__PMC_EV_ALIAS("L1D_CACHE_ST.E_STATE", IAP_EVENT_41H_04H) \
-__PMC_EV_ALIAS("L1D_CACHE_ST.M_STATE", IAP_EVENT_41H_08H) \
-__PMC_EV_ALIAS("L1D_CACHE_ST.MESI", IAP_EVENT_41H_0FH) \
-__PMC_EV_ALIAS("L1D_CACHE_LOCK.HIT", IAP_EVENT_42H_01H) \
-__PMC_EV_ALIAS("L1D_CACHE_LOCK.S_STATE", IAP_EVENT_42H_02H) \
-__PMC_EV_ALIAS("L1D_CACHE_LOCK.E_STATE", IAP_EVENT_42H_04H) \
-__PMC_EV_ALIAS("L1D_CACHE_LOCK.M_STATE", IAP_EVENT_42H_08H) \
-__PMC_EV_ALIAS("L1D_ALL_REF.ANY", IAP_EVENT_43H_01H) \
-__PMC_EV_ALIAS("L1D_ALL_REF.CACHEABLE", IAP_EVENT_43H_02H) \
-__PMC_EV_ALIAS("L1D_PEND_MISS.LOAD_BUFFERS_FULL", IAP_EVENT_48H_02H) \
-__PMC_EV_ALIAS("DTLB_MISSES.ANY", IAP_EVENT_49H_01H) \
-__PMC_EV_ALIAS("DTLB_MISSES.WALK_COMPLETED", IAP_EVENT_49H_02H) \
-__PMC_EV_ALIAS("DTLB_MISSES.STLB_HIT", IAP_EVENT_49H_10H) \
-__PMC_EV_ALIAS("DTLB_MISSES.PDE_MISS", IAP_EVENT_49H_20H) \
-__PMC_EV_ALIAS("DTLB_MISSES.PDP_MISS", IAP_EVENT_49H_40H) \
-__PMC_EV_ALIAS("DTLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_49H_80H) \
-__PMC_EV_ALIAS("SSE_MEM_EXEC.NTA", IAP_EVENT_4BH_01H) \
-__PMC_EV_ALIAS("SSE_MEM_EXEC.STREAMING_STORES", IAP_EVENT_4BH_08H) \
-__PMC_EV_ALIAS("LOAD_HIT_PRE", IAP_EVENT_4CH_01H) \
-__PMC_EV_ALIAS("SFENCE_CYCLES", IAP_EVENT_4DH_01H) \
-__PMC_EV_ALIAS("L1D_PREFETCH.REQUESTS", IAP_EVENT_4EH_01H) \
-__PMC_EV_ALIAS("L1D_PREFETCH.MISS", IAP_EVENT_4EH_02H) \
-__PMC_EV_ALIAS("L1D_PREFETCH.TRIGGERS", IAP_EVENT_4EH_04H) \
-__PMC_EV_ALIAS("EPT.EPDE_MISS", IAP_EVENT_4FH_02H) \
-__PMC_EV_ALIAS("EPT.EPDPE_HIT", IAP_EVENT_4FH_04H) \
-__PMC_EV_ALIAS("EPT.EPDPE_MISS", IAP_EVENT_4FH_08H) \
-__PMC_EV_ALIAS("L1D.REPL", IAP_EVENT_51H_01H) \
-__PMC_EV_ALIAS("L1D.M_REPL", IAP_EVENT_51H_02H) \
-__PMC_EV_ALIAS("L1D.M_EVICT", IAP_EVENT_51H_04H) \
-__PMC_EV_ALIAS("L1D.M_SNOOP_EVICT", IAP_EVENT_51H_08H) \
-__PMC_EV_ALIAS("L1D_CACHE_PREFETCH_LOCK_FB_HIT", IAP_EVENT_52H_01H) \
-__PMC_EV_ALIAS("L1D_CACHE_LOCK_FB_HIT", IAP_EVENT_53H_01H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA", IAP_EVENT_60H_01H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE", IAP_EVENT_60H_02H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO", IAP_EVENT_60H_04H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ANY.READ", IAP_EVENT_60H_08H) \
-__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D_L2", IAP_EVENT_63H_01H) \
-__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D", IAP_EVENT_63H_02H) \
-__PMC_EV_ALIAS("IO_TRANSACTIONS", IAP_EVENT_6CH_01H) \
-__PMC_EV_ALIAS("L1I.HITS", IAP_EVENT_80H_01H) \
-__PMC_EV_ALIAS("L1I.MISSES", IAP_EVENT_80H_02H) \
-__PMC_EV_ALIAS("L1I.READS", IAP_EVENT_80H_03H) \
-__PMC_EV_ALIAS("L1I.CYCLES_STALLED", IAP_EVENT_80H_04H) \
-__PMC_EV_ALIAS("IFU_IVC.FULL", IAP_EVENT_81H_01H) \
-__PMC_EV_ALIAS("IFU_IVC.L1I_EVICTION", IAP_EVENT_81H_02H) \
-__PMC_EV_ALIAS("LARGE_ITLB.HIT", IAP_EVENT_82H_01H) \
-__PMC_EV_ALIAS("L1I_OPPORTUNISTIC_HITS", IAP_EVENT_83H_01H) \
-__PMC_EV_ALIAS("ITLB_MISSES.ANY", IAP_EVENT_85H_01H) \
-__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H) \
-__PMC_EV_ALIAS("ITLB_MISSES.WALK_CYCLES", IAP_EVENT_85H_04H) \
-__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT", IAP_EVENT_85H_10H) \
-__PMC_EV_ALIAS("ITLB_MISSES.PDE_MISS", IAP_EVENT_85H_20H) \
-__PMC_EV_ALIAS("ITLB_MISSES.PDP_MISS", IAP_EVENT_85H_40H) \
-__PMC_EV_ALIAS("ITLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_85H_80H) \
-__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H) \
-__PMC_EV_ALIAS("ILD_STALL.MRU", IAP_EVENT_87H_02H) \
-__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H) \
-__PMC_EV_ALIAS("ILD_STALL.REGEN", IAP_EVENT_87H_08H) \
-__PMC_EV_ALIAS("ILD_STALL.ANY", IAP_EVENT_87H_0FH) \
-__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT", IAP_EVENT_88H_02H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NON_CALL", IAP_EVENT_88H_04H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.NON_CALLS", IAP_EVENT_88H_07H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.NEAR_CALLS", IAP_EVENT_88H_30H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_40H) \
-__PMC_EV_ALIAS("BR_INST_EXEC.ANY", IAP_EVENT_7FH) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT", IAP_EVENT_89H_02H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NON_CALL", IAP_EVENT_89H_04H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.NON_CALLS", IAP_EVENT_89H_07H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.NEAR_CALLS", IAP_EVENT_89H_30H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_40H) \
-__PMC_EV_ALIAS("BR_MISP_EXEC.ANY", IAP_EVENT_89H_7FH) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.LOAD", IAP_EVENT_A2H_02H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.RS_FULL", IAP_EVENT_A2H_04H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.STORE", IAP_EVENT_A2H_08H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.ROB_FULL", IAP_EVENT_A2H_10H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.FPCW", IAP_EVENT_A2H_20H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H) \
-__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H) \
-__PMC_EV_ALIAS("MACRO_INSTS.FUSIONS_DECODED", IAP_EVENT_A6H_01H) \
-__PMC_EV_ALIAS("BACLEAR_FORCE_IQ", IAP_EVENT_A7H_01H) \
-__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_DATA", IAP_EVENT_B0H_01H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_CODE", IAP_EVENT_B0H_02H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.RFO", IAP_EVENT_B0H_04H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.READ", IAP_EVENT_B0H_08H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.RFO", IAP_EVENT_80H_10H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.UNCACHED_MEM", IAP_EVENT_B0H_20H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK", IAP_EVENT_B0H_40H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY", IAP_EVENT_B0H_80H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT0", IAP_EVENT_B1H_01H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT1", IAP_EVENT_B1H_02H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT2_CORE", IAP_EVENT_B1H_04H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT3_CORE", IAP_EVENT_B1H_08H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT4_CORE", IAP_EVENT_B1H_10H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT5", IAP_EVENT_B1H_20H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT015", IAP_EVENT_B1H_40H) \
-__PMC_EV_ALIAS("UOPS_EXECUTED.PORT234", IAP_EVENT_B1H_80H) \
-__PMC_EV_ALIAS("OFFCORE_REQUESTS_SQ_FULL", IAP_EVENT_B2H_01H) \
-__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.DATA", IAP_EVENT_B3H_01H) \
-__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE", IAP_EVENT_B3H_02H) \
-__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.CODE", IAP_EVENT_B3H_04H) \
-__PMC_EV_ALIAS("OOF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H) \
-__PMC_EV_ALIAS("SNOOP_RESPONSE.HIT", IAP_EVENT_B8H_01H) \
-__PMC_EV_ALIAS("SNOOP_RESPONSE.HITE", IAP_EVENT_B8H_02H) \
-__PMC_EV_ALIAS("SNOOP_RESPONSE.HITM", IAP_EVENT_B8H_04H) \
-__PMC_EV_ALIAS("PIC_ACCESSES.TPR_READS", IAP_EVENT_BAH_01H) \
-__PMC_EV_ALIAS("PIC_ACCESSES.TPR_WRITES", IAP_EVENT_BAH_02H) \
-__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_01H) \
-__PMC_EV_ALIAS("INST_RETIRED.X87", IAP_EVENT_C0H_02H) \
-__PMC_EV_ALIAS("UOPS_RETIRED.ANY", IAP_EVENT_C2H_01H) \
-__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \
-__PMC_EV_ALIAS("UOPS_RETIRED.MACRO_FUSED", IAP_EVENT_C2H_04H) \
-__PMC_EV_ALIAS("MACHINE_CLEARS.CYCLES", IAP_EVENT_C3H_01H) \
-__PMC_EV_ALIAS("MACHINE_CLEARS.MEM_ORDER", IAP_EVENT_C3H_02H) \
-__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H) \
-__PMC_EV_ALIAS("MACHINE_CLEARS.FUSION_ASSIST", IAP_EVENT_C3H_10H) \
-__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_00H) \
-__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H) \
-__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H) \
-__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H) \
-__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H) \
-__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL", IAP_EVENT_C5H_02H) \
-__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_SINGLE", IAP_EVENT_C7H_01H) \
-__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_SINGLE", IAP_EVENT_C7H_02H) \
-__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_DOUBLE", IAP_EVENT_C7H_04H) \
-__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_DOUBLE", IAP_EVENT_C7H_08H) \
-__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.VECTOR_INTEGER", IAP_EVENT_C7H_10H) \
-__PMC_EV_ALIAS("ITLB_MISS_RETIRED", IAP_EVENT_C8H_20H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L1D_HIT", IAP_EVENT_CBH_01H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L2_HIT", IAP_EVENT_CBH_02H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.LLC_UNSHARED_HIT", IAP_EVENT_CBH_04H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM", IAP_EVENT_CBH_08H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.LLC_MISS", IAP_EVENT_CBH_10H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.HIT_LFB", IAP_EVENT_CBH_40H) \
-__PMC_EV_ALIAS("MEM_LOAD_RETIRED.DTLB_MISS", IAP_EVENT_CBH_80H) \
-__PMC_EV_ALIAS("FP_MMX_TRANS.TO_FP", IAP_EVENT_CCH_01H) \
-__PMC_EV_ALIAS("FP_MMX_TRANS.TO_MMX", IAP_EVENT_CCH_02H) \
-__PMC_EV_ALIAS("FP_MMX_TRANS.ANY", IAP_EVENT_CCH_03H) \
-__PMC_EV_ALIAS("MACRO_INSTS.DECODED", IAP_EVENT_D0H_01H) \
-__PMC_EV_ALIAS("UOPS_DECODED.MS", IAP_EVENT_D1H_02H) \
-__PMC_EV_ALIAS("UOPS_DECODED.ESP_FOLDING", IAP_EVENT_D1H_04H) \
-__PMC_EV_ALIAS("UOPS_DECODED.ESP_SYNC", IAP_EVENT_D1H_08H) \
-__PMC_EV_ALIAS("RAT_STALLS.FLAGS", IAP_EVENT_D2H_01H) \
-__PMC_EV_ALIAS("RAT_STALLS.REGISTERS", IAP_EVENT_D2H_02H) \
-__PMC_EV_ALIAS("RAT_STALLS.ROB_READ_PORT", IAP_EVENT_D2H_04H) \
-__PMC_EV_ALIAS("RAT_STALLS.SCOREBOARD", IAP_EVENT_D2H_08H) \
-__PMC_EV_ALIAS("RAT_STALLS.ANY", IAP_EVENT_D2H_0FH) \
-__PMC_EV_ALIAS("SEG_RENAME_STALLS", IAP_EVENT_D4H_01H) \
-__PMC_EV_ALIAS("ES_REG_RENAMES", IAP_EVENT_D5H_01H) \
-__PMC_EV_ALIAS("UOP_UNFUSION", IAP_EVENT_DBH_01H) \
-__PMC_EV_ALIAS("BR_INST_DECODED", IAP_EVENT_E0H_01H) \
-__PMC_EV_ALIAS("BOGUS_BR", IAP_EVENT_E4H_01H) \
-__PMC_EV_ALIAS("BPU_MISSED_CALL_RET", IAP_EVENT_E5H_01H) \
-__PMC_EV_ALIAS("BACLEAR.CLEAR", IAP_EVENT_E6H_01H) \
-__PMC_EV_ALIAS("BACLEAR.BAD_TARGET", IAP_EVENT_E6H_02H) \
-__PMC_EV_ALIAS("BPU_CLEARS.EARLY", IAP_EVENT_E8H_01H) \
-__PMC_EV_ALIAS("BPU_CLEARS.LATE", IAP_EVENT_E8H_02H) \
-__PMC_EV_ALIAS("BPU_CLEARS.ANY", IAP_EVENT_E8H_03H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD", IAP_EVENT_F0H_01H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO", IAP_EVENT_F0H_02H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH", IAP_EVENT_F0H_04H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH", IAP_EVENT_F0H_08H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB", IAP_EVENT_F0H_10H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL", IAP_EVENT_F0H_20H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.WB", IAP_EVENT_F0H_40H) \
-__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY", IAP_EVENT_F0H_80H) \
-__PMC_EV_ALIAS("L2_LINES_IN.S_STATE", IAP_EVENT_F1H_02H) \
-__PMC_EV_ALIAS("L2_LINES_IN.E_STATE", IAP_EVENT_F1H_04H) \
-__PMC_EV_ALIAS("L2_LINES_IN.ANY", IAP_EVENT_F1H_07H) \
-__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H) \
-__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H) \
-__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN", IAP_EVENT_F2H_04H) \
-__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY", IAP_EVENT_F2H_08H) \
-__PMC_EV_ALIAS("L2_LINES_OUT.ANY", IAP_EVENT_F2H_0FH) \
-__PMC_EV_ALIAS("L2_HW_PREFETCH.HIT", IAP_EVENT_F3H_01H) \
-__PMC_EV_ALIAS("L2_HW_PREFETCH.ALLOC", IAP_EVENT_F3H_02H) \
-__PMC_EV_ALIAS("L2_HW_PREFETCH.DATA_TRIGGER", IAP_EVENT_F3H_04H) \
-__PMC_EV_ALIAS("L2_HW_PREFETCH.CODE_TRIGGER", IAP_EVENT_F3H_08H) \
-__PMC_EV_ALIAS("L2_HW_PREFETCH.DCA_TRIGGER", IAP_EVENT_F3H_10H) \
-__PMC_EV_ALIAS("L2_HW_PREFETCH.KICK_START", IAP_EVENT_F3H_20H) \
-__PMC_EV_ALIAS("SQ_MISC.PROMOTION", IAP_EVENT_F4H_01H) \
-__PMC_EV_ALIAS("SQ_MISC.PROMOTION_POST_GO", IAP_EVENT_F4H_02H) \
-__PMC_EV_ALIAS("SQ_MISC.LRU_HINTS", IAP_EVENT_F4H_04H) \
-__PMC_EV_ALIAS("SQ_MISC.FILL_DROPPED", IAP_EVENT_F4H_08H) \
-__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK", IAP_EVENT_F4H_10H) \
-__PMC_EV_ALIAS("SQ_FULL_STALL_CYCLES", IAP_EVENT_F6H_01H) \
-__PMC_EV_ALIAS("FP_ASSIST.ALL", IAP_EVENT_F7H_01H) \
-__PMC_EV_ALIAS("FP_ASSIST.OUTPUT", IAP_EVENT_F7H_02H) \
-__PMC_EV_ALIAS("FP_ASSIST.INPUT", IAP_EVENT_F7H_04H) \
-__PMC_EV_ALIAS("SEGMENT_REG_LOADS", IAP_EVENT_F8H_01H) \
-__PMC_EV_ALIAS("SIMD_INT_64.PACKED_MPY", IAP_EVENT_FDH_01H) \
-__PMC_EV_ALIAS("SIMD_INT_64.PACKED_SHIFT", IAP_EVENT_FDH_02H) \
-__PMC_EV_ALIAS("SIMD_INT_64.PACK", IAP_EVENT_FDH_04H) \
-__PMC_EV_ALIAS("SIMD_INT_64.UNPACK", IAP_EVENT_FDH_08H) \
-__PMC_EV_ALIAS("SIMD_INT_64.PACKED_LOGICAL", IAP_EVENT_FDH_10H) \
-__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH", IAP_EVENT_FDH_20H) \
-__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
+__PMC_EV_ALIAS("SB_DRAIN.ANY", IAP_EVENT_04H_07H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.AT_RET", IAP_EVENT_06H_04H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.L1D_BLOCK", IAP_EVENT_06H_08H) \
+__PMC_EV_ALIAS("PARTIAL_ADDRESS_ALIAS", IAP_EVENT_07H_01H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.ANY", IAP_EVENT_08H_01H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_02H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_10H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_MISS", IAP_EVENT_08H_20H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDP_MISS", IAP_EVENT_08H_40H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.LARGE_WALK_COMPLETED", \
+ IAP_EVENT_08H_80H) \
+__PMC_EV_ALIAS("MEM_INST_RETIRED.LOADS", IAP_EVENT_0BH_01H) \
+__PMC_EV_ALIAS("MEM_INST_RETIRED.STORES", IAP_EVENT_0BH_02H) \
+__PMC_EV_ALIAS("MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD", \
+ IAP_EVENT_0BH_10H) \
+__PMC_EV_ALIAS("MEM_STORE_RETIRED.DTLB_MISS", IAP_EVENT_0CH_01H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.STALLED_CYCLES", IAP_EVENT_0EH_01H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.FUSED", IAP_EVENT_0EH_02H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.L3_DATA_MISS_UNKNOWN", \
+ IAP_EVENT_0FH_01H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.OTHER_CORE_L2_HITM", \
+ IAP_EVENT_0FH_02H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_CACHE_LOCAL_HOME_HIT", \
+ IAP_EVENT_0FH_08H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_DRAM", \
+ IAP_EVENT_0FH_10H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM", IAP_EVENT_0FH_20H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.UNCACHEABLE", IAP_EVENT_0FH_80H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.MMX", IAP_EVENT_10H_02H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP", IAP_EVENT_10H_04H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE2_INTEGER", IAP_EVENT_10H_08H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED", IAP_EVENT_10H_10H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR", IAP_EVENT_10H_20H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION", \
+ IAP_EVENT_10H_40H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION", \
+ IAP_EVENT_10H_80H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_MPY", IAP_EVENT_12H_01H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_SHIFT", IAP_EVENT_12H_02H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACK", IAP_EVENT_12H_04H) \
+__PMC_EV_ALIAS("SIMD_INT_128.UNPACK", IAP_EVENT_12H_08H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_LOGICAL", IAP_EVENT_12H_10H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_ARITH", IAP_EVENT_12H_20H) \
+__PMC_EV_ALIAS("SIMD_INT_128.SHUFFLE_MOVE", IAP_EVENT_12H_40H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.RS", IAP_EVENT_13H_01H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.RS_DELAYED", IAP_EVENT_13H_02H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.MOB", IAP_EVENT_13H_04H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.ANY", IAP_EVENT_13H_07H) \
+__PMC_EV_ALIAS("ARITH.CYCLES_DIV_BUSY", IAP_EVENT_14H_01H) \
+__PMC_EV_ALIAS("ARITH.MUL", IAP_EVENT_14H_02H) \
+__PMC_EV_ALIAS("INST_QUEUE_WRITES", IAP_EVENT_17H_01H) \
+__PMC_EV_ALIAS("INST_DECODED.DEC0", IAP_EVENT_18H_01H) \
+__PMC_EV_ALIAS("TWO_UOP_INSTS_DECODED", IAP_EVENT_19H_01H) \
+__PMC_EV_ALIAS("INST_QUEUE_WRITE_CYCLES", IAP_EVENT_1EH_01H) \
+__PMC_EV_ALIAS("LSD_OVERFLOW", IAP_EVENT_20H_01H) \
+__PMC_EV_ALIAS("L2_RQSTS.LD_HIT", IAP_EVENT_24H_01H) \
+__PMC_EV_ALIAS("L2_RQSTS.LD_MISS", IAP_EVENT_24H_02H) \
+__PMC_EV_ALIAS("L2_RQSTS.LOADS", IAP_EVENT_24H_03H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT", IAP_EVENT_24H_04H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_08H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFOS", IAP_EVENT_24H_0CH) \
+__PMC_EV_ALIAS("L2_RQSTS.IFETCH_HIT", IAP_EVENT_24H_10H) \
+__PMC_EV_ALIAS("L2_RQSTS.IFETCH_MISS", IAP_EVENT_24H_20H) \
+__PMC_EV_ALIAS("L2_RQSTS.IFETCHES", IAP_EVENT_24H_30H) \
+__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_HIT", IAP_EVENT_24H_40H) \
+__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_MISS", IAP_EVENT_24H_80H) \
+__PMC_EV_ALIAS("L2_RQSTS.PREFETCHES", IAP_EVENT_24H_C0H) \
+__PMC_EV_ALIAS("L2_RQSTS.MISS", IAP_EVENT_24H_AAH) \
+__PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_FFH) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.I_STATE", IAP_EVENT_26H_01H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.S_STATE", IAP_EVENT_26H_02H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.E_STATE", IAP_EVENT_26H_04H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.M_STATE", IAP_EVENT_26H_08H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.MESI", IAP_EVENT_26H_0FH) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.I_STATE", IAP_EVENT_26H_10H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.S_STATE", IAP_EVENT_26H_20H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.E_STATE", IAP_EVENT_26H_40H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.M_STATE", IAP_EVENT_26H_80H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.MESI", IAP_EVENT_26H_F0H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.ANY", IAP_EVENT_26H_FFH) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.I_STATE", IAP_EVENT_27H_01H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.S_STATE", IAP_EVENT_27H_02H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.M_STATE", IAP_EVENT_27H_08H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.HIT", IAP_EVENT_27H_0EH) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.MESI", IAP_EVENT_27H_0FH) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.I_STATE", IAP_EVENT_27H_10H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.S_STATE", IAP_EVENT_27H_20H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.E_STATE", IAP_EVENT_27H_40H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.M_STATE", IAP_EVENT_27H_80H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.HIT", IAP_EVENT_27H_E0H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.MESI", IAP_EVENT_27H_F0H) \
+__PMC_EV_ALIAS("L1D_WB_L2.I_STATE", IAP_EVENT_28H_01H) \
+__PMC_EV_ALIAS("L1D_WB_L2.S_STATE", IAP_EVENT_28H_02H) \
+__PMC_EV_ALIAS("L1D_WB_L2.E_STATE", IAP_EVENT_28H_04H) \
+__PMC_EV_ALIAS("L1D_WB_L2.M_STATE", IAP_EVENT_28H_08H) \
+__PMC_EV_ALIAS("L1D_WB_L2.MESI", IAP_EVENT_28H_0FH) \
+__PMC_EV_ALIAS("L3_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_4FH) \
+__PMC_EV_ALIAS("L3_LAT_CACHE.MISS", IAP_EVENT_2EH_41H) \
+__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H) \
+__PMC_EV_ALIAS("CPU_CLK_UNHALTED.REF_P", IAP_EVENT_3CH_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_LD.I_STATE", IAP_EVENT_40H_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_LD.S_STATE", IAP_EVENT_40H_02H) \
+__PMC_EV_ALIAS("L1D_CACHE_LD.E_STATE", IAP_EVENT_40H_04H) \
+__PMC_EV_ALIAS("L1D_CACHE_LD.M_STATE", IAP_EVENT_40H_08H) \
+__PMC_EV_ALIAS("L1D_CACHE_LD.MESI", IAP_EVENT_40H_0FH) \
+__PMC_EV_ALIAS("L1D_CACHE_ST.S_STATE", IAP_EVENT_41H_02H) \
+__PMC_EV_ALIAS("L1D_CACHE_ST.E_STATE", IAP_EVENT_41H_04H) \
+__PMC_EV_ALIAS("L1D_CACHE_ST.M_STATE", IAP_EVENT_41H_08H) \
+__PMC_EV_ALIAS("L1D_CACHE_LOCK.HIT", IAP_EVENT_42H_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_LOCK.S_STATE", IAP_EVENT_42H_02H) \
+__PMC_EV_ALIAS("L1D_CACHE_LOCK.E_STATE", IAP_EVENT_42H_04H) \
+__PMC_EV_ALIAS("L1D_CACHE_LOCK.M_STATE", IAP_EVENT_42H_08H) \
+__PMC_EV_ALIAS("L1D_ALL_REF.ANY", IAP_EVENT_43H_01H) \
+__PMC_EV_ALIAS("L1D_ALL_REF.CACHEABLE", IAP_EVENT_43H_02H) \
+__PMC_EV_ALIAS("L1D_PEND_MISS.LOAD_BUFFERS_FULL", IAP_EVENT_48H_02H) \
+__PMC_EV_ALIAS("DTLB_MISSES.ANY", IAP_EVENT_49H_01H) \
+__PMC_EV_ALIAS("DTLB_MISSES.WALK_COMPLETED", IAP_EVENT_49H_02H) \
+__PMC_EV_ALIAS("DTLB_MISSES.STLB_HIT", IAP_EVENT_49H_10H) \
+__PMC_EV_ALIAS("LOAD_HIT_PRE", IAP_EVENT_4CH_01H) \
+__PMC_EV_ALIAS("L1D_PREFETCH.REQUESTS", IAP_EVENT_4EH_01H) \
+__PMC_EV_ALIAS("L1D_PREFETCH.MISS", IAP_EVENT_4EH_02H) \
+__PMC_EV_ALIAS("L1D_PREFETCH.TRIGGERS", IAP_EVENT_4EH_04H) \
+__PMC_EV_ALIAS("L1D.REPL", IAP_EVENT_51H_01H) \
+__PMC_EV_ALIAS("L1D.M_REPL", IAP_EVENT_51H_02H) \
+__PMC_EV_ALIAS("L1D.M_EVICT", IAP_EVENT_51H_04H) \
+__PMC_EV_ALIAS("L1D.M_SNOOP_EVICT", IAP_EVENT_51H_08H) \
+__PMC_EV_ALIAS("L1D_CACHE_PREFETCH_LOCK_FB_HIT", IAP_EVENT_52H_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_LOCK_FB_HIT", IAP_EVENT_53H_01H) \
+__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D_L2", IAP_EVENT_63H_01H) \
+__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D", IAP_EVENT_63H_02H) \
+__PMC_EV_ALIAS("IO_TRANSACTIONS", IAP_EVENT_6CH_01H) \
+__PMC_EV_ALIAS("L1I.HITS", IAP_EVENT_80H_01H) \
+__PMC_EV_ALIAS("L1I.MISSES", IAP_EVENT_80H_02H) \
+__PMC_EV_ALIAS("L1I.READS", IAP_EVENT_80H_03H) \
+__PMC_EV_ALIAS("L1I.CYCLES_STALLED", IAP_EVENT_80H_04H) \
+__PMC_EV_ALIAS("LARGE_ITLB.HIT", IAP_EVENT_82H_01H) \
+__PMC_EV_ALIAS("ITLB_MISSES.ANY", IAP_EVENT_85H_01H) \
+__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H) \
+__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H) \
+__PMC_EV_ALIAS("ILD_STALL.MRU", IAP_EVENT_87H_02H) \
+__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H) \
+__PMC_EV_ALIAS("ILD_STALL.REGEN", IAP_EVENT_87H_08H) \
+__PMC_EV_ALIAS("ILD_STALL.ANY", IAP_EVENT_87H_0FH) \
+__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT", IAP_EVENT_88H_02H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NON_CALL", IAP_EVENT_88H_04H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.NON_CALLS", IAP_EVENT_88H_07H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.NEAR_CALLS", IAP_EVENT_88H_30H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_40H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.ANY", IAP_EVENT_88H_7FH) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT", IAP_EVENT_89H_02H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NON_CALL", IAP_EVENT_89H_04H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.NON_CALLS", IAP_EVENT_89H_07H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.NEAR_CALLS", IAP_EVENT_89H_30H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_40H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.ANY", IAP_EVENT_89H_7FH) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.LOAD", IAP_EVENT_A2H_02H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.RS_FULL", IAP_EVENT_A2H_04H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.STORE", IAP_EVENT_A2H_08H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.ROB_FULL", IAP_EVENT_A2H_10H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.FPCW", IAP_EVENT_A2H_20H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H) \
+__PMC_EV_ALIAS("MACRO_INSTS.FUSIONS_DECODED", IAP_EVENT_A6H_01H) \
+__PMC_EV_ALIAS("BACLEAR_FORCE_IQ", IAP_EVENT_A7H_01H) \
+__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \
+__PMC_EV_ALIAS("ITLB_FLUSH", IAP_EVENT_AEH_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK", IAP_EVENT_B0H_40H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT0", IAP_EVENT_B1H_01H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT1", IAP_EVENT_B1H_02H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT2_CORE", IAP_EVENT_B1H_04H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT3_CORE", IAP_EVENT_B1H_08H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT4_CORE", IAP_EVENT_B1H_10H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5", \
+ IAP_EVENT_B1H_1FH) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT5", IAP_EVENT_B1H_20H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES", IAP_EVENT_B1H_3FH) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT015", IAP_EVENT_B1H_40H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT234", IAP_EVENT_B1H_80H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_SQ_FULL", IAP_EVENT_B2H_01H) \
+__PMC_EV_ALIAS("OFF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H) \
+__PMC_EV_ALIAS("SNOOP_RESPONSE.HIT", IAP_EVENT_B8H_01H) \
+__PMC_EV_ALIAS("SNOOP_RESPONSE.HITE", IAP_EVENT_B8H_02H) \
+__PMC_EV_ALIAS("SNOOP_RESPONSE.HITM", IAP_EVENT_B8H_04H) \
+__PMC_EV_ALIAS("OFF_CORE_RESPONSE_1", IAP_EVENT_BBH_01H) \
+__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_01H) \
+__PMC_EV_ALIAS("INST_RETIRED.X87", IAP_EVENT_C0H_02H) \
+__PMC_EV_ALIAS("INST_RETIRED.MMX", IAP_EVENT_C0H_04H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.ANY", IAP_EVENT_C2H_01H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.MACRO_FUSED", IAP_EVENT_C2H_04H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.CYCLES", IAP_EVENT_C3H_01H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.MEM_ORDER", IAP_EVENT_C3H_02H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_00H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL", IAP_EVENT_C5H_02H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_SINGLE", IAP_EVENT_C7H_01H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_SINGLE", IAP_EVENT_C7H_02H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_DOUBLE", IAP_EVENT_C7H_04H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_DOUBLE", IAP_EVENT_C7H_08H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.VECTOR_INTEGER", IAP_EVENT_C7H_10H) \
+__PMC_EV_ALIAS("ITLB_MISS_RETIRED", IAP_EVENT_C8H_20H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L1D_HIT", IAP_EVENT_CBH_01H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L2_HIT", IAP_EVENT_CBH_02H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_UNSHARED_HIT", IAP_EVENT_CBH_04H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM", \
+ IAP_EVENT_CBH_08H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_MISS", IAP_EVENT_CBH_10H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.HIT_LFB", IAP_EVENT_CBH_40H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.DTLB_MISS", IAP_EVENT_CBH_80H) \
+__PMC_EV_ALIAS("FP_MMX_TRANS.TO_FP", IAP_EVENT_CCH_01H) \
+__PMC_EV_ALIAS("FP_MMX_TRANS.TO_MMX", IAP_EVENT_CCH_02H) \
+__PMC_EV_ALIAS("FP_MMX_TRANS.ANY", IAP_EVENT_CCH_03H) \
+__PMC_EV_ALIAS("MACRO_INSTS.DECODED", IAP_EVENT_D0H_01H) \
+__PMC_EV_ALIAS("UOPS_DECODED.MS", IAP_EVENT_D1H_02H) \
+__PMC_EV_ALIAS("UOPS_DECODED.ESP_FOLDING", IAP_EVENT_D1H_04H) \
+__PMC_EV_ALIAS("UOPS_DECODED.ESP_SYNC", IAP_EVENT_D1H_08H) \
+__PMC_EV_ALIAS("RAT_STALLS.FLAGS", IAP_EVENT_D2H_01H) \
+__PMC_EV_ALIAS("RAT_STALLS.REGISTERS", IAP_EVENT_D2H_02H) \
+__PMC_EV_ALIAS("RAT_STALLS.ROB_READ_PORT", IAP_EVENT_D2H_04H) \
+__PMC_EV_ALIAS("RAT_STALLS.SCOREBOARD", IAP_EVENT_D2H_08H) \
+__PMC_EV_ALIAS("RAT_STALLS.ANY", IAP_EVENT_D2H_0FH) \
+__PMC_EV_ALIAS("SEG_RENAME_STALLS", IAP_EVENT_D4H_01H) \
+__PMC_EV_ALIAS("ES_REG_RENAMES", IAP_EVENT_D5H_01H) \
+__PMC_EV_ALIAS("UOP_UNFUSION", IAP_EVENT_DBH_01H) \
+__PMC_EV_ALIAS("BR_INST_DECODED", IAP_EVENT_E0H_01H) \
+__PMC_EV_ALIAS("BPU_MISSED_CALL_RET", IAP_EVENT_E5H_01H) \
+__PMC_EV_ALIAS("BACLEAR.CLEAR", IAP_EVENT_E6H_01H) \
+__PMC_EV_ALIAS("BACLEAR.BAD_TARGET", IAP_EVENT_E6H_02H) \
+__PMC_EV_ALIAS("BPU_CLEARS.EARLY", IAP_EVENT_E8H_01H) \
+__PMC_EV_ALIAS("BPU_CLEARS.LATE", IAP_EVENT_E8H_02H) \
+__PMC_EV_ALIAS("BPU_CLEARS.ANY", IAP_EVENT_E8H_03H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD", IAP_EVENT_F0H_01H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO", IAP_EVENT_F0H_02H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH", IAP_EVENT_F0H_04H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH", IAP_EVENT_F0H_08H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB", IAP_EVENT_F0H_10H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL", IAP_EVENT_F0H_20H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.WB", IAP_EVENT_F0H_40H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY", IAP_EVENT_F0H_80H) \
+__PMC_EV_ALIAS("L2_LINES_IN.S_STATE", IAP_EVENT_F1H_02H) \
+__PMC_EV_ALIAS("L2_LINES_IN.E_STATE", IAP_EVENT_F1H_04H) \
+__PMC_EV_ALIAS("L2_LINES_IN.ANY", IAP_EVENT_F1H_07H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN", IAP_EVENT_F2H_04H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY", IAP_EVENT_F2H_08H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.ANY", IAP_EVENT_F2H_0FH) \
+__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK", IAP_EVENT_F4H_10H) \
+__PMC_EV_ALIAS("SQ_FULL_STALL_CYCLES", IAP_EVENT_F6H_01H) \
+__PMC_EV_ALIAS("FP_ASSIST.ALL", IAP_EVENT_F7H_01H) \
+__PMC_EV_ALIAS("FP_ASSIST.OUTPUT", IAP_EVENT_F7H_02H) \
+__PMC_EV_ALIAS("FP_ASSIST.INPUT", IAP_EVENT_F7H_04H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_MPY", IAP_EVENT_FDH_01H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_SHIFT", IAP_EVENT_FDH_02H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACK", IAP_EVENT_FDH_04H) \
+__PMC_EV_ALIAS("SIMD_INT_64.UNPACK", IAP_EVENT_FDH_08H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_LOGICAL", IAP_EVENT_FDH_10H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH", IAP_EVENT_FDH_20H) \
+__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H) \
+__PMC_EV_ALIAS_COREI7_OLD()
+
+/*
+ * Aliases for Westmere PMC events (253669-033US December 2009)
+ */
+#define __PMC_EV_ALIAS_WESTMERE() \
+__PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \
+__PMC_EV_ALIAS("LOAD_BLOCK.OVERLAP_STORE", IAP_EVENT_03H_02H) \
+__PMC_EV_ALIAS("SB_DRAIN.ANY", IAP_EVENT_04H_07H) \
+__PMC_EV_ALIAS("MISALIGN_MEMORY.STORE", IAP_EVENT_05H_02H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.AT_RET", IAP_EVENT_06H_04H) \
+__PMC_EV_ALIAS("STORE_BLOCKS.L1D_BLOCK", IAP_EVENT_06H_08H) \
+__PMC_EV_ALIAS("PARTIAL_ADDRESS_ALIAS", IAP_EVENT_07H_01H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.ANY", IAP_EVENT_08H_01H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_02H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_CYCLES", IAP_EVENT_08H_04H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_10H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_MISS", IAP_EVENT_08H_20H) \
+__PMC_EV_ALIAS("MEM_INST_RETIRED.LOADS", IAP_EVENT_0BH_01H) \
+__PMC_EV_ALIAS("MEM_INST_RETIRED.STORES", IAP_EVENT_0BH_02H) \
+__PMC_EV_ALIAS("MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD", \
+ IAP_EVENT_0BH_10H) \
+__PMC_EV_ALIAS("MEM_STORE_RETIRED.DTLB_MISS", IAP_EVENT_0CH_01H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.STALLED_CYCLES", IAP_EVENT_0EH_01H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.FUSED", IAP_EVENT_0EH_02H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_HITM", IAP_EVENT_0FH_02H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM_AND_REMOTE_CACHE_HIT", \
+ IAP_EVENT_0FH_08H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM", IAP_EVENT_0FH_10H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_DRAM", IAP_EVENT_0FH_20H) \
+__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.UNCACHEABLE", IAP_EVENT_0FH_80H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.MMX", IAP_EVENT_10H_02H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP", IAP_EVENT_10H_04H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE2_INTEGER", IAP_EVENT_10H_08H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED", IAP_EVENT_10H_10H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR", IAP_EVENT_10H_20H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION", \
+ IAP_EVENT_10H_40H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION", \
+ IAP_EVENT_10H_80H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_MPY", IAP_EVENT_12H_01H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_SHIFT", IAP_EVENT_12H_02H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACK", IAP_EVENT_12H_04H) \
+__PMC_EV_ALIAS("SIMD_INT_128.UNPACK", IAP_EVENT_12H_08H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_LOGICAL", IAP_EVENT_12H_10H) \
+__PMC_EV_ALIAS("SIMD_INT_128.PACKED_ARITH", IAP_EVENT_12H_20H) \
+__PMC_EV_ALIAS("SIMD_INT_128.SHUFFLE_MOVE", IAP_EVENT_12H_40H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.RS", IAP_EVENT_13H_01H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.RS_DELAYED", IAP_EVENT_13H_02H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.MOB", IAP_EVENT_13H_04H) \
+__PMC_EV_ALIAS("LOAD_DISPATCH.ANY", IAP_EVENT_13H_07H) \
+__PMC_EV_ALIAS("ARITH.CYCLES_DIV_BUSY", IAP_EVENT_14H_01H) \
+__PMC_EV_ALIAS("ARITH.MUL", IAP_EVENT_14H_02H) \
+__PMC_EV_ALIAS("INST_QUEUE_WRITES", IAP_EVENT_17H_01H) \
+__PMC_EV_ALIAS("INST_DECODED.DEC0", IAP_EVENT_18H_01H) \
+__PMC_EV_ALIAS("TWO_UOP_INSTS_DECODED", IAP_EVENT_19H_01H) \
+__PMC_EV_ALIAS("INST_QUEUE_WRITE_CYCLES", IAP_EVENT_1EH_01H) \
+__PMC_EV_ALIAS("LSD_OVERFLOW", IAP_EVENT_20H_01H) \
+__PMC_EV_ALIAS("L2_RQSTS.LD_HIT", IAP_EVENT_24H_01H) \
+__PMC_EV_ALIAS("L2_RQSTS.LD_MISS", IAP_EVENT_24H_02H) \
+__PMC_EV_ALIAS("L2_RQSTS.LOADS", IAP_EVENT_24H_03H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT", IAP_EVENT_24H_04H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_08H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFOS", IAP_EVENT_24H_0CH) \
+__PMC_EV_ALIAS("L2_RQSTS.IFETCH_HIT", IAP_EVENT_24H_10H) \
+__PMC_EV_ALIAS("L2_RQSTS.IFETCH_MISS", IAP_EVENT_24H_20H) \
+__PMC_EV_ALIAS("L2_RQSTS.IFETCHES", IAP_EVENT_24H_30H) \
+__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_HIT", IAP_EVENT_24H_40H) \
+__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_MISS", IAP_EVENT_24H_80H) \
+__PMC_EV_ALIAS("L2_RQSTS.PREFETCHES", IAP_EVENT_24H_C0H) \
+__PMC_EV_ALIAS("L2_RQSTS.MISS", IAP_EVENT_24H_AAH) \
+__PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_FFH) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.I_STATE", IAP_EVENT_26H_01H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.S_STATE", IAP_EVENT_26H_02H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.E_STATE", IAP_EVENT_26H_04H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.M_STATE", IAP_EVENT_26H_08H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.MESI", IAP_EVENT_26H_0FH) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.I_STATE", IAP_EVENT_26H_10H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.S_STATE", IAP_EVENT_26H_20H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.E_STATE", IAP_EVENT_26H_40H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.M_STATE", IAP_EVENT_26H_80H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.MESI", IAP_EVENT_26H_F0H) \
+__PMC_EV_ALIAS("L2_DATA_RQSTS.ANY", IAP_EVENT_26H_FFH) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.I_STATE", IAP_EVENT_27H_01H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.S_STATE", IAP_EVENT_27H_02H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.M_STATE", IAP_EVENT_27H_08H) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.HIT", IAP_EVENT_27H_0EH) \
+__PMC_EV_ALIAS("L2_WRITE.RFO.MESI", IAP_EVENT_27H_0FH) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.I_STATE", IAP_EVENT_27H_10H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.S_STATE", IAP_EVENT_27H_20H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.E_STATE", IAP_EVENT_27H_40H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.M_STATE", IAP_EVENT_27H_80H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.HIT", IAP_EVENT_27H_E0H) \
+__PMC_EV_ALIAS("L2_WRITE.LOCK.MESI", IAP_EVENT_27H_F0H) \
+__PMC_EV_ALIAS("L1D_WB_L2.I_STATE", IAP_EVENT_28H_01H) \
+__PMC_EV_ALIAS("L1D_WB_L2.S_STATE", IAP_EVENT_28H_02H) \
+__PMC_EV_ALIAS("L1D_WB_L2.E_STATE", IAP_EVENT_28H_04H) \
+__PMC_EV_ALIAS("L1D_WB_L2.M_STATE", IAP_EVENT_28H_08H) \
+__PMC_EV_ALIAS("L1D_WB_L2.MESI", IAP_EVENT_28H_0FH) \
+__PMC_EV_ALIAS("L3_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_02H) \
+__PMC_EV_ALIAS("L3_LAT_CACHE.MISS", IAP_EVENT_2EH_01H) \
+__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H) \
+__PMC_EV_ALIAS("CPU_CLK_UNHALTED.REF_P", IAP_EVENT_3CH_01H) \
+__PMC_EV_ALIAS("DTLB_MISSES.ANY", IAP_EVENT_49H_01H) \
+__PMC_EV_ALIAS("DTLB_MISSES.WALK_COMPLETED", IAP_EVENT_49H_02H) \
+__PMC_EV_ALIAS("DTLB_MISSES.WALK_CYCLES", IAP_EVENT_49H_04H) \
+__PMC_EV_ALIAS("DTLB_MISSES.STLB_HIT", IAP_EVENT_49H_10H) \
+__PMC_EV_ALIAS("DTLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_49H_80H) \
+__PMC_EV_ALIAS("LOAD_HIT_PRE", IAP_EVENT_4CH_01H) \
+__PMC_EV_ALIAS("L1D_PREFETCH.REQUESTS", IAP_EVENT_4EH_01H) \
+__PMC_EV_ALIAS("L1D_PREFETCH.MISS", IAP_EVENT_4EH_02H) \
+__PMC_EV_ALIAS("L1D_PREFETCH.TRIGGERS", IAP_EVENT_4EH_04H) \
+__PMC_EV_ALIAS("EPT.WALK_CYCLES", IAP_EVENT_4FH_10H) \
+__PMC_EV_ALIAS("L1D.REPL", IAP_EVENT_51H_01H) \
+__PMC_EV_ALIAS("L1D.M_REPL", IAP_EVENT_51H_02H) \
+__PMC_EV_ALIAS("L1D.M_EVICT", IAP_EVENT_51H_04H) \
+__PMC_EV_ALIAS("L1D.M_SNOOP_EVICT", IAP_EVENT_51H_08H) \
+__PMC_EV_ALIAS("L1D_CACHE_PREFETCH_LOCK_FB_HIT", IAP_EVENT_52H_01H) \
+__PMC_EV_ALIAS("L1D_CACHE_LOCK_FB_HIT", IAP_EVENT_53H_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA", \
+ IAP_EVENT_60H_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE", \
+ IAP_EVENT_60H_02H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO", \
+ IAP_EVENT_60H_04H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ANY.READ", \
+ IAP_EVENT_60H_08H) \
+__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D_L2", IAP_EVENT_63H_01H) \
+__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D", IAP_EVENT_63H_02H) \
+__PMC_EV_ALIAS("IO_TRANSACTIONS", IAP_EVENT_6CH_01H) \
+__PMC_EV_ALIAS("L1I.HITS", IAP_EVENT_80H_01H) \
+__PMC_EV_ALIAS("L1I.MISSES", IAP_EVENT_80H_02H) \
+__PMC_EV_ALIAS("L1I.READS", IAP_EVENT_80H_03H) \
+__PMC_EV_ALIAS("L1I.CYCLES_STALLED", IAP_EVENT_80H_04H) \
+__PMC_EV_ALIAS("LARGE_ITLB.HIT", IAP_EVENT_82H_01H) \
+__PMC_EV_ALIAS("ITLB_MISSES.ANY", IAP_EVENT_85H_01H) \
+__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H) \
+__PMC_EV_ALIAS("ITLB_MISSES.WALK_CYCLES", IAP_EVENT_85H_04H) \
+__PMC_EV_ALIAS("ITLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_85H_80H) \
+__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H) \
+__PMC_EV_ALIAS("ILD_STALL.MRU", IAP_EVENT_87H_02H) \
+__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H) \
+__PMC_EV_ALIAS("ILD_STALL.REGEN", IAP_EVENT_87H_08H) \
+__PMC_EV_ALIAS("ILD_STALL.ANY", IAP_EVENT_87H_0FH) \
+__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT", IAP_EVENT_88H_02H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NON_CALL", IAP_EVENT_88H_04H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.NON_CALLS", IAP_EVENT_88H_07H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.NEAR_CALLS", IAP_EVENT_88H_30H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_40H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.ANY", IAP_EVENT_88H_7FH) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT", IAP_EVENT_89H_02H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NON_CALL", IAP_EVENT_89H_04H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.NON_CALLS", IAP_EVENT_89H_07H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.NEAR_CALLS", IAP_EVENT_89H_30H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_40H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.ANY", IAP_EVENT_89H_7FH) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.LOAD", IAP_EVENT_A2H_02H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.RS_FULL", IAP_EVENT_A2H_04H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.STORE", IAP_EVENT_A2H_08H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.ROB_FULL", IAP_EVENT_A2H_10H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.FPCW", IAP_EVENT_A2H_20H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H) \
+__PMC_EV_ALIAS("MACRO_INSTS.FUSIONS_DECODED", IAP_EVENT_A6H_01H) \
+__PMC_EV_ALIAS("BACLEAR_FORCE_IQ", IAP_EVENT_A7H_01H) \
+__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \
+__PMC_EV_ALIAS("ITLB_FLUSH", IAP_EVENT_AEH_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_DATA", IAP_EVENT_B0H_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_CODE", IAP_EVENT_B0H_02H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.RFO", IAP_EVENT_B0H_04H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.READ", IAP_EVENT_B0H_08H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.RFO", IAP_EVENT_B0H_10H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK", IAP_EVENT_B0H_40H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY", IAP_EVENT_B0H_80H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT0", IAP_EVENT_B1H_01H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT1", IAP_EVENT_B1H_02H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT2_CORE", IAP_EVENT_B1H_04H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT3_CORE", IAP_EVENT_B1H_08H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT4_CORE", IAP_EVENT_B1H_10H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5", \
+ IAP_EVENT_B1H_1FH) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT5", IAP_EVENT_B1H_20H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES", IAP_EVENT_B1H_3FH) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT015", IAP_EVENT_B1H_40H) \
+__PMC_EV_ALIAS("UOPS_EXECUTED.PORT234", IAP_EVENT_B1H_80H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_SQ_FULL", IAP_EVENT_B2H_01H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.DATA", IAP_EVENT_B3H_01H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE", \
+ IAP_EVENT_B3H_02H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.CODE", IAP_EVENT_B3H_04H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS.CODE", IAP_EVENT_B4H_01H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS.DATA", IAP_EVENT_B4H_02H) \
+__PMC_EV_ALIAS("SNOOPQ_REQUESTS.INVALIDATE", IAP_EVENT_B4H_04H) \
+__PMC_EV_ALIAS("OFF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H) \
+__PMC_EV_ALIAS("SNOOP_RESPONSE.HIT", IAP_EVENT_B8H_01H) \
+__PMC_EV_ALIAS("SNOOP_RESPONSE.HITE", IAP_EVENT_B8H_02H) \
+__PMC_EV_ALIAS("SNOOP_RESPONSE.HITM", IAP_EVENT_B8H_04H) \
+__PMC_EV_ALIAS("OFF_CORE_RESPONSE_1", IAP_EVENT_BBH_01H) \
+__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_01H) \
+__PMC_EV_ALIAS("INST_RETIRED.X87", IAP_EVENT_C0H_02H) \
+__PMC_EV_ALIAS("INST_RETIRED.MMX", IAP_EVENT_C0H_04H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.ANY", IAP_EVENT_C2H_01H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.MACRO_FUSED", IAP_EVENT_C2H_04H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.CYCLES", IAP_EVENT_C3H_01H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.MEM_ORDER", IAP_EVENT_C3H_02H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_00H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_01H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL", IAP_EVENT_C5H_02H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_04H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_SINGLE", IAP_EVENT_C7H_01H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_SINGLE", IAP_EVENT_C7H_02H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_DOUBLE", IAP_EVENT_C7H_04H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_DOUBLE", IAP_EVENT_C7H_08H) \
+__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.VECTOR_INTEGER", IAP_EVENT_C7H_10H) \
+__PMC_EV_ALIAS("ITLB_MISS_RETIRED", IAP_EVENT_C8H_20H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L1D_HIT", IAP_EVENT_CBH_01H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L2_HIT", IAP_EVENT_CBH_02H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_UNSHARED_HIT", IAP_EVENT_CBH_04H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM", \
+ IAP_EVENT_CBH_08H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_MISS", IAP_EVENT_CBH_10H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.HIT_LFB", IAP_EVENT_CBH_40H) \
+__PMC_EV_ALIAS("MEM_LOAD_RETIRED.DTLB_MISS", IAP_EVENT_CBH_80H) \
+__PMC_EV_ALIAS("FP_MMX_TRANS.TO_FP", IAP_EVENT_CCH_01H) \
+__PMC_EV_ALIAS("FP_MMX_TRANS.TO_MMX", IAP_EVENT_CCH_02H) \
+__PMC_EV_ALIAS("FP_MMX_TRANS.ANY", IAP_EVENT_CCH_03H) \
+__PMC_EV_ALIAS("MACRO_INSTS.DECODED", IAP_EVENT_D0H_01H) \
+__PMC_EV_ALIAS("UOPS_DECODED.STALL_CYCLES", IAP_EVENT_D1H_01H) \
+__PMC_EV_ALIAS("UOPS_DECODED.MS", IAP_EVENT_D1H_02H) \
+__PMC_EV_ALIAS("UOPS_DECODED.ESP_FOLDING", IAP_EVENT_D1H_04H) \
+__PMC_EV_ALIAS("UOPS_DECODED.ESP_SYNC", IAP_EVENT_D1H_08H) \
+__PMC_EV_ALIAS("RAT_STALLS.FLAGS", IAP_EVENT_D2H_01H) \
+__PMC_EV_ALIAS("RAT_STALLS.REGISTERS", IAP_EVENT_D2H_02H) \
+__PMC_EV_ALIAS("RAT_STALLS.ROB_READ_PORT", IAP_EVENT_D2H_04H) \
+__PMC_EV_ALIAS("RAT_STALLS.SCOREBOARD", IAP_EVENT_D2H_08H) \
+__PMC_EV_ALIAS("RAT_STALLS.ANY", IAP_EVENT_D2H_0FH) \
+__PMC_EV_ALIAS("SEG_RENAME_STALLS", IAP_EVENT_D4H_01H) \
+__PMC_EV_ALIAS("ES_REG_RENAMES", IAP_EVENT_D5H_01H) \
+__PMC_EV_ALIAS("UOP_UNFUSION", IAP_EVENT_DBH_01H) \
+__PMC_EV_ALIAS("BR_INST_DECODED", IAP_EVENT_E0H_01H) \
+__PMC_EV_ALIAS("BPU_MISSED_CALL_RET", IAP_EVENT_E5H_01H) \
+__PMC_EV_ALIAS("BACLEAR.CLEAR", IAP_EVENT_E6H_01H) \
+__PMC_EV_ALIAS("BACLEAR.BAD_TARGET", IAP_EVENT_E6H_02H) \
+__PMC_EV_ALIAS("BPU_CLEARS.EARLY", IAP_EVENT_E8H_01H) \
+__PMC_EV_ALIAS("BPU_CLEARS.LATE", IAP_EVENT_E8H_02H) \
+__PMC_EV_ALIAS("THREAD_ACTIVE", IAP_EVENT_ECH_01H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD", IAP_EVENT_F0H_01H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO", IAP_EVENT_F0H_02H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH", IAP_EVENT_F0H_04H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH", IAP_EVENT_F0H_08H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB", IAP_EVENT_F0H_10H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL", IAP_EVENT_F0H_20H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.WB", IAP_EVENT_F0H_40H) \
+__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY", IAP_EVENT_F0H_80H) \
+__PMC_EV_ALIAS("L2_LINES_IN.S_STATE", IAP_EVENT_F1H_02H) \
+__PMC_EV_ALIAS("L2_LINES_IN.E_STATE", IAP_EVENT_F1H_04H) \
+__PMC_EV_ALIAS("L2_LINES_IN.ANY", IAP_EVENT_F1H_07H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN", IAP_EVENT_F2H_04H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY", IAP_EVENT_F2H_08H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.ANY", IAP_EVENT_F2H_0FH) \
+__PMC_EV_ALIAS("SQ_MISC.LRU_HINTS", IAP_EVENT_F4H_04H) \
+__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK", IAP_EVENT_F4H_10H) \
+__PMC_EV_ALIAS("SQ_FULL_STALL_CYCLES", IAP_EVENT_F6H_01H) \
+__PMC_EV_ALIAS("FP_ASSIST.ALL", IAP_EVENT_F7H_01H) \
+__PMC_EV_ALIAS("FP_ASSIST.OUTPUT", IAP_EVENT_F7H_02H) \
+__PMC_EV_ALIAS("FP_ASSIST.INPUT", IAP_EVENT_F7H_04H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_MPY", IAP_EVENT_FDH_01H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_SHIFT", IAP_EVENT_FDH_02H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACK", IAP_EVENT_FDH_04H) \
+__PMC_EV_ALIAS("SIMD_INT_64.UNPACK", IAP_EVENT_FDH_08H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_LOGICAL", IAP_EVENT_FDH_10H) \
+__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH", IAP_EVENT_FDH_20H) \
+__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
/* timestamp counters. */
#define __PMC_EV_TSC() \
@@ -1979,6 +2325,627 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
#define PMC_EV_TSC_FIRST PMC_EV_TSC_TSC
#define PMC_EV_TSC_LAST PMC_EV_TSC_TSC
+#define __PMC_EV_UCF() \
+__PMC_EV(UCF, UCLOCK)
+
+#define PMC_EV_UCF_FIRST PMC_EV_UCF_UCLOCK
+#define PMC_EV_UCF_LAST PMC_EV_UCF_UCLOCK
+
+#define __PMC_EV_UCP() \
+__PMC_EV(UCP, EVENT_00H_01H) \
+__PMC_EV(UCP, EVENT_00H_02H) \
+__PMC_EV(UCP, EVENT_00H_04H) \
+__PMC_EV(UCP, EVENT_01H_01H) \
+__PMC_EV(UCP, EVENT_01H_02H) \
+__PMC_EV(UCP, EVENT_01H_04H) \
+__PMC_EV(UCP, EVENT_02H_01H) \
+__PMC_EV(UCP, EVENT_03H_01H) \
+__PMC_EV(UCP, EVENT_03H_02H) \
+__PMC_EV(UCP, EVENT_03H_04H) \
+__PMC_EV(UCP, EVENT_03H_08H) \
+__PMC_EV(UCP, EVENT_03H_10H) \
+__PMC_EV(UCP, EVENT_03H_20H) \
+__PMC_EV(UCP, EVENT_03H_40H) \
+__PMC_EV(UCP, EVENT_04H_01H) \
+__PMC_EV(UCP, EVENT_04H_02H) \
+__PMC_EV(UCP, EVENT_04H_04H) \
+__PMC_EV(UCP, EVENT_04H_08H) \
+__PMC_EV(UCP, EVENT_04H_10H) \
+__PMC_EV(UCP, EVENT_05H_01H) \
+__PMC_EV(UCP, EVENT_05H_02H) \
+__PMC_EV(UCP, EVENT_05H_04H) \
+__PMC_EV(UCP, EVENT_06H_01H) \
+__PMC_EV(UCP, EVENT_06H_02H) \
+__PMC_EV(UCP, EVENT_06H_04H) \
+__PMC_EV(UCP, EVENT_06H_08H) \
+__PMC_EV(UCP, EVENT_06H_10H) \
+__PMC_EV(UCP, EVENT_06H_20H) \
+__PMC_EV(UCP, EVENT_07H_01H) \
+__PMC_EV(UCP, EVENT_07H_02H) \
+__PMC_EV(UCP, EVENT_07H_04H) \
+__PMC_EV(UCP, EVENT_07H_08H) \
+__PMC_EV(UCP, EVENT_07H_10H) \
+__PMC_EV(UCP, EVENT_07H_20H) \
+__PMC_EV(UCP, EVENT_07H_24H) \
+__PMC_EV(UCP, EVENT_08H_01H) \
+__PMC_EV(UCP, EVENT_08H_02H) \
+__PMC_EV(UCP, EVENT_08H_04H) \
+__PMC_EV(UCP, EVENT_08H_03H) \
+__PMC_EV(UCP, EVENT_09H_01H) \
+__PMC_EV(UCP, EVENT_09H_02H) \
+__PMC_EV(UCP, EVENT_09H_04H) \
+__PMC_EV(UCP, EVENT_09H_03H) \
+__PMC_EV(UCP, EVENT_0AH_01H) \
+__PMC_EV(UCP, EVENT_0AH_02H) \
+__PMC_EV(UCP, EVENT_0AH_04H) \
+__PMC_EV(UCP, EVENT_0AH_08H) \
+__PMC_EV(UCP, EVENT_0AH_0FH) \
+__PMC_EV(UCP, EVENT_0BH_01H) \
+__PMC_EV(UCP, EVENT_0BH_02H) \
+__PMC_EV(UCP, EVENT_0BH_04H) \
+__PMC_EV(UCP, EVENT_0BH_08H) \
+__PMC_EV(UCP, EVENT_0BH_10H) \
+__PMC_EV(UCP, EVENT_0BH_1FH) \
+__PMC_EV(UCP, EVENT_0CH_01H) \
+__PMC_EV(UCP, EVENT_0CH_02H) \
+__PMC_EV(UCP, EVENT_0CH_04H) \
+__PMC_EV(UCP, EVENT_0CH_08H) \
+__PMC_EV(UCP, EVENT_20H_01H) \
+__PMC_EV(UCP, EVENT_20H_02H) \
+__PMC_EV(UCP, EVENT_20H_04H) \
+__PMC_EV(UCP, EVENT_20H_08H) \
+__PMC_EV(UCP, EVENT_20H_10H) \
+__PMC_EV(UCP, EVENT_20H_20H) \
+__PMC_EV(UCP, EVENT_21H_01H) \
+__PMC_EV(UCP, EVENT_21H_02H) \
+__PMC_EV(UCP, EVENT_21H_04H) \
+__PMC_EV(UCP, EVENT_22H_01H) \
+__PMC_EV(UCP, EVENT_22H_02H) \
+__PMC_EV(UCP, EVENT_22H_04H) \
+__PMC_EV(UCP, EVENT_23H_01H) \
+__PMC_EV(UCP, EVENT_23H_02H) \
+__PMC_EV(UCP, EVENT_23H_04H) \
+__PMC_EV(UCP, EVENT_24H_02H) \
+__PMC_EV(UCP, EVENT_24H_04H) \
+__PMC_EV(UCP, EVENT_25H_01H) \
+__PMC_EV(UCP, EVENT_25H_02H) \
+__PMC_EV(UCP, EVENT_25H_04H) \
+__PMC_EV(UCP, EVENT_26H_01H) \
+__PMC_EV(UCP, EVENT_27H_01H) \
+__PMC_EV(UCP, EVENT_27H_02H) \
+__PMC_EV(UCP, EVENT_27H_04H) \
+__PMC_EV(UCP, EVENT_27H_08H) \
+__PMC_EV(UCP, EVENT_27H_10H) \
+__PMC_EV(UCP, EVENT_27H_20H) \
+__PMC_EV(UCP, EVENT_28H_01H) \
+__PMC_EV(UCP, EVENT_28H_02H) \
+__PMC_EV(UCP, EVENT_28H_04H) \
+__PMC_EV(UCP, EVENT_28H_08H) \
+__PMC_EV(UCP, EVENT_28H_10H) \
+__PMC_EV(UCP, EVENT_28H_20H) \
+__PMC_EV(UCP, EVENT_29H_01H) \
+__PMC_EV(UCP, EVENT_29H_02H) \
+__PMC_EV(UCP, EVENT_29H_04H) \
+__PMC_EV(UCP, EVENT_29H_08H) \
+__PMC_EV(UCP, EVENT_29H_10H) \
+__PMC_EV(UCP, EVENT_29H_20H) \
+__PMC_EV(UCP, EVENT_2AH_01H) \
+__PMC_EV(UCP, EVENT_2AH_02H) \
+__PMC_EV(UCP, EVENT_2AH_04H) \
+__PMC_EV(UCP, EVENT_2AH_07H) \
+__PMC_EV(UCP, EVENT_2BH_01H) \
+__PMC_EV(UCP, EVENT_2BH_02H) \
+__PMC_EV(UCP, EVENT_2BH_04H) \
+__PMC_EV(UCP, EVENT_2BH_07H) \
+__PMC_EV(UCP, EVENT_2CH_01H) \
+__PMC_EV(UCP, EVENT_2CH_02H) \
+__PMC_EV(UCP, EVENT_2CH_04H) \
+__PMC_EV(UCP, EVENT_2CH_07H) \
+__PMC_EV(UCP, EVENT_2DH_01H) \
+__PMC_EV(UCP, EVENT_2DH_02H) \
+__PMC_EV(UCP, EVENT_2DH_04H) \
+__PMC_EV(UCP, EVENT_2DH_07H) \
+__PMC_EV(UCP, EVENT_2EH_01H) \
+__PMC_EV(UCP, EVENT_2EH_02H) \
+__PMC_EV(UCP, EVENT_2EH_04H) \
+__PMC_EV(UCP, EVENT_2EH_07H) \
+__PMC_EV(UCP, EVENT_2FH_01H) \
+__PMC_EV(UCP, EVENT_2FH_02H) \
+__PMC_EV(UCP, EVENT_2FH_04H) \
+__PMC_EV(UCP, EVENT_2FH_07H) \
+__PMC_EV(UCP, EVENT_2FH_08H) \
+__PMC_EV(UCP, EVENT_2FH_10H) \
+__PMC_EV(UCP, EVENT_2FH_20H) \
+__PMC_EV(UCP, EVENT_2FH_38H) \
+__PMC_EV(UCP, EVENT_30H_01H) \
+__PMC_EV(UCP, EVENT_30H_02H) \
+__PMC_EV(UCP, EVENT_30H_04H) \
+__PMC_EV(UCP, EVENT_30H_07H) \
+__PMC_EV(UCP, EVENT_31H_01H) \
+__PMC_EV(UCP, EVENT_31H_02H) \
+__PMC_EV(UCP, EVENT_31H_04H) \
+__PMC_EV(UCP, EVENT_31H_07H) \
+__PMC_EV(UCP, EVENT_32H_01H) \
+__PMC_EV(UCP, EVENT_32H_02H) \
+__PMC_EV(UCP, EVENT_32H_04H) \
+__PMC_EV(UCP, EVENT_32H_07H) \
+__PMC_EV(UCP, EVENT_33H_01H) \
+__PMC_EV(UCP, EVENT_33H_02H) \
+__PMC_EV(UCP, EVENT_33H_04H) \
+__PMC_EV(UCP, EVENT_33H_07H) \
+__PMC_EV(UCP, EVENT_34H_01H) \
+__PMC_EV(UCP, EVENT_34H_02H) \
+__PMC_EV(UCP, EVENT_34H_04H) \
+__PMC_EV(UCP, EVENT_34H_08H) \
+__PMC_EV(UCP, EVENT_34H_10H) \
+__PMC_EV(UCP, EVENT_34H_20H) \
+__PMC_EV(UCP, EVENT_35H_01H) \
+__PMC_EV(UCP, EVENT_35H_02H) \
+__PMC_EV(UCP, EVENT_35H_04H) \
+__PMC_EV(UCP, EVENT_40H_01H) \
+__PMC_EV(UCP, EVENT_40H_02H) \
+__PMC_EV(UCP, EVENT_40H_04H) \
+__PMC_EV(UCP, EVENT_40H_08H) \
+__PMC_EV(UCP, EVENT_40H_10H) \
+__PMC_EV(UCP, EVENT_40H_20H) \
+__PMC_EV(UCP, EVENT_40H_07H) \
+__PMC_EV(UCP, EVENT_40H_38H) \
+__PMC_EV(UCP, EVENT_41H_01H) \
+__PMC_EV(UCP, EVENT_41H_02H) \
+__PMC_EV(UCP, EVENT_41H_04H) \
+__PMC_EV(UCP, EVENT_41H_08H) \
+__PMC_EV(UCP, EVENT_41H_10H) \
+__PMC_EV(UCP, EVENT_41H_20H) \
+__PMC_EV(UCP, EVENT_41H_07H) \
+__PMC_EV(UCP, EVENT_41H_38H) \
+__PMC_EV(UCP, EVENT_42H_01H) \
+__PMC_EV(UCP, EVENT_42H_02H) \
+__PMC_EV(UCP, EVENT_42H_04H) \
+__PMC_EV(UCP, EVENT_42H_08H) \
+__PMC_EV(UCP, EVENT_43H_01H) \
+__PMC_EV(UCP, EVENT_43H_02H) \
+__PMC_EV(UCP, EVENT_60H_01H) \
+__PMC_EV(UCP, EVENT_60H_02H) \
+__PMC_EV(UCP, EVENT_60H_04H) \
+__PMC_EV(UCP, EVENT_61H_01H) \
+__PMC_EV(UCP, EVENT_61H_02H) \
+__PMC_EV(UCP, EVENT_61H_04H) \
+__PMC_EV(UCP, EVENT_62H_01H) \
+__PMC_EV(UCP, EVENT_62H_02H) \
+__PMC_EV(UCP, EVENT_62H_04H) \
+__PMC_EV(UCP, EVENT_63H_01H) \
+__PMC_EV(UCP, EVENT_63H_02H) \
+__PMC_EV(UCP, EVENT_63H_04H) \
+__PMC_EV(UCP, EVENT_63H_08H) \
+__PMC_EV(UCP, EVENT_63H_10H) \
+__PMC_EV(UCP, EVENT_63H_20H) \
+__PMC_EV(UCP, EVENT_64H_01H) \
+__PMC_EV(UCP, EVENT_64H_02H) \
+__PMC_EV(UCP, EVENT_64H_04H) \
+__PMC_EV(UCP, EVENT_64H_08H) \
+__PMC_EV(UCP, EVENT_64H_10H) \
+__PMC_EV(UCP, EVENT_64H_20H) \
+__PMC_EV(UCP, EVENT_65H_01H) \
+__PMC_EV(UCP, EVENT_65H_02H) \
+__PMC_EV(UCP, EVENT_65H_04H) \
+__PMC_EV(UCP, EVENT_66H_01H) \
+__PMC_EV(UCP, EVENT_66H_02H) \
+__PMC_EV(UCP, EVENT_66H_04H) \
+__PMC_EV(UCP, EVENT_67H_01H) \
+__PMC_EV(UCP, EVENT_80H_01H) \
+__PMC_EV(UCP, EVENT_80H_02H) \
+__PMC_EV(UCP, EVENT_80H_04H) \
+__PMC_EV(UCP, EVENT_80H_08H) \
+__PMC_EV(UCP, EVENT_81H_01H) \
+__PMC_EV(UCP, EVENT_81H_02H) \
+__PMC_EV(UCP, EVENT_81H_04H) \
+__PMC_EV(UCP, EVENT_81H_08H) \
+__PMC_EV(UCP, EVENT_82H_01H) \
+__PMC_EV(UCP, EVENT_83H_01H) \
+__PMC_EV(UCP, EVENT_83H_02H) \
+__PMC_EV(UCP, EVENT_83H_04H) \
+__PMC_EV(UCP, EVENT_83H_08H) \
+__PMC_EV(UCP, EVENT_84H_01H) \
+__PMC_EV(UCP, EVENT_84H_02H) \
+__PMC_EV(UCP, EVENT_84H_04H) \
+__PMC_EV(UCP, EVENT_84H_08H) \
+__PMC_EV(UCP, EVENT_85H_02H) \
+__PMC_EV(UCP, EVENT_86H_01H)
+
+#define PMC_EV_UCP_FIRST PMC_EV_UCP_EVENT_00H_01H
+#define PMC_EV_UCP_LAST PMC_EV_UCP_EVENT_86H_01H
+
+#define __PMC_EV_ALIAS_COREI7UC() \
+__PMC_EV_ALIAS("GQ_CYCLES_FULL.READ_TRACKER", UCP_EVENT_00H_01H) \
+__PMC_EV_ALIAS("GQ_CYCLES_FULL.WRITE_TRACKER", UCP_EVENT_00H_02H) \
+__PMC_EV_ALIAS("GQ_CYCLES_FULL.PEER_PROBE_TRACKER", UCP_EVENT_00H_04H) \
+__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.READ_TRACKER", UCP_EVENT_01H_01H) \
+__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER", UCP_EVENT_01H_02H) \
+__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER", UCP_EVENT_01H_04H) \
+__PMC_EV_ALIAS("GQ_ALLOC.READ_TRACKER", UCP_EVENT_03H_01H) \
+__PMC_EV_ALIAS("GQ_ALLOC.RT_L3_MISS", UCP_EVENT_03H_02H) \
+__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_L3_RESP", UCP_EVENT_03H_04H) \
+__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_RTID_ACQUIRED", UCP_EVENT_03H_08H) \
+__PMC_EV_ALIAS("GQ_ALLOC.WT_TO_RTID_ACQUIRED", UCP_EVENT_03H_10H) \
+__PMC_EV_ALIAS("GQ_ALLOC.WRITE_TRACKER", UCP_EVENT_03H_20H) \
+__PMC_EV_ALIAS("GQ_ALLOC.PEER_PROBE_TRACKER", UCP_EVENT_03H_40H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_QPI", UCP_EVENT_04H_01H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_QMC", UCP_EVENT_04H_02H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_L3", UCP_EVENT_04H_04H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_02", UCP_EVENT_04H_08H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_13", UCP_EVENT_04H_10H) \
+__PMC_EV_ALIAS("GQ_DATA.TO_QPI_QMC", UCP_EVENT_05H_01H) \
+__PMC_EV_ALIAS("GQ_DATA.TO_L3", UCP_EVENT_05H_02H) \
+__PMC_EV_ALIAS("GQ_DATA.TO_CORES", UCP_EVENT_05H_04H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.I_STATE", UCP_EVENT_06H_01H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.S_STATE", UCP_EVENT_06H_02H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE", UCP_EVENT_06H_04H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE", UCP_EVENT_06H_08H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.CONFLICT", UCP_EVENT_06H_10H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.WB", UCP_EVENT_06H_20H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.I_STATE", UCP_EVENT_07H_01H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.S_STATE", UCP_EVENT_07H_02H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE", UCP_EVENT_07H_04H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE", UCP_EVENT_07H_08H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.CONFLICT", UCP_EVENT_07H_10H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.WB", UCP_EVENT_07H_20H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.HITM", UCP_EVENT_07H_24H) \
+__PMC_EV_ALIAS("L3_HITS.READ", UCP_EVENT_08H_01H) \
+__PMC_EV_ALIAS("L3_HITS.WRITE", UCP_EVENT_08H_02H) \
+__PMC_EV_ALIAS("L3_HITS.PROBE", UCP_EVENT_08H_04H) \
+__PMC_EV_ALIAS("L3_HITS.ANY", UCP_EVENT_08H_03H) \
+__PMC_EV_ALIAS("L3_MISS.READ", UCP_EVENT_09H_01H) \
+__PMC_EV_ALIAS("L3_MISS.WRITE", UCP_EVENT_09H_02H) \
+__PMC_EV_ALIAS("L3_MISS.PROBE", UCP_EVENT_09H_04H) \
+__PMC_EV_ALIAS("L3_MISS.ANY", UCP_EVENT_09H_03H) \
+__PMC_EV_ALIAS("L3_LINES_IN.M_STATE", UCP_EVENT_0AH_01H) \
+__PMC_EV_ALIAS("L3_LINES_IN.E_STATE", UCP_EVENT_0AH_02H) \
+__PMC_EV_ALIAS("L3_LINES_IN.S_STATE", UCP_EVENT_0AH_04H) \
+__PMC_EV_ALIAS("L3_LINES_IN.F_STATE", UCP_EVENT_0AH_08H) \
+__PMC_EV_ALIAS("L3_LINES_IN.ANY", UCP_EVENT_0AH_0FH) \
+__PMC_EV_ALIAS("L3_LINES_OUT.M_STATE", UCP_EVENT_0BH_01H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.E_STATE", UCP_EVENT_0BH_02H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.S_STATE", UCP_EVENT_0BH_04H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.I_STATE", UCP_EVENT_0BH_08H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.F_STATE", UCP_EVENT_0BH_10H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.ANY", UCP_EVENT_0BH_1FH) \
+__PMC_EV_ALIAS("QHL_REQUESTS.IOH_READS", UCP_EVENT_20H_01H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.IOH_WRITES", UCP_EVENT_20H_02H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_READS", UCP_EVENT_20H_04H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_WRITES", UCP_EVENT_20H_08H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_READS", UCP_EVENT_20H_10H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_WRITES", UCP_EVENT_20H_20H) \
+__PMC_EV_ALIAS("QHL_CYCLES_FULL.IOH", UCP_EVENT_21H_01H) \
+__PMC_EV_ALIAS("QHL_CYCLES_FULL.REMOTE", UCP_EVENT_21H_02H) \
+__PMC_EV_ALIAS("QHL_CYCLES_FULL.LOCAL", UCP_EVENT_21H_04H) \
+__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.IOH", UCP_EVENT_22H_01H) \
+__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.REMOTE", UCP_EVENT_22H_02H) \
+__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.LOCAL", UCP_EVENT_22H_04H) \
+__PMC_EV_ALIAS("QHL_OCCUPANCY.IOH", UCP_EVENT_23H_01H) \
+__PMC_EV_ALIAS("QHL_OCCUPANCY.REMOTE", UCP_EVENT_23H_02H) \
+__PMC_EV_ALIAS("QHL_OCCUPANCY.LOCAL", UCP_EVENT_23H_04H) \
+__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.2WAY", UCP_EVENT_24H_02H) \
+__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.3WAY", UCP_EVENT_24H_04H) \
+__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.IOH", UCP_EVENT_25H_01H) \
+__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.REMOTE", UCP_EVENT_25H_02H) \
+__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.LOCAL", UCP_EVENT_25H_04H) \
+__PMC_EV_ALIAS("QHL_TO_QMC_BYPASS", UCP_EVENT_26H_01H) \
+__PMC_EV_ALIAS("QMC_NORMAL_FULL.READ.CH0", UCP_EVENT_27H_01H) \
+__PMC_EV_ALIAS("QMC_NORMAL_FULL.READ.CH1", UCP_EVENT_27H_02H) \
+__PMC_EV_ALIAS("QMC_NORMAL_FULL.READ.CH2", UCP_EVENT_27H_04H) \
+__PMC_EV_ALIAS("QMC_NORMAL_FULL.WRITE.CH0", UCP_EVENT_27H_08H) \
+__PMC_EV_ALIAS("QMC_NORMAL_FULL.WRITE.CH1", UCP_EVENT_27H_10H) \
+__PMC_EV_ALIAS("QMC_NORMAL_FULL.WRITE.CH2", UCP_EVENT_27H_20H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH0", UCP_EVENT_28H_01H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH1", UCP_EVENT_28H_02H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH2", UCP_EVENT_28H_04H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH0", UCP_EVENT_28H_08H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH1", UCP_EVENT_28H_10H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH2", UCP_EVENT_28H_20H) \
+__PMC_EV_ALIAS("QMC_BUSY.READ.CH0", UCP_EVENT_29H_01H) \
+__PMC_EV_ALIAS("QMC_BUSY.READ.CH1", UCP_EVENT_29H_02H) \
+__PMC_EV_ALIAS("QMC_BUSY.READ.CH2", UCP_EVENT_29H_04H) \
+__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH0", UCP_EVENT_29H_08H) \
+__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH1", UCP_EVENT_29H_10H) \
+__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH2", UCP_EVENT_29H_20H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.CH0", UCP_EVENT_2AH_01H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.CH1", UCP_EVENT_2AH_02H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.CH2", UCP_EVENT_2AH_04H) \
+__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH0", UCP_EVENT_2BH_01H) \
+__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH1", UCP_EVENT_2BH_02H) \
+__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH2", UCP_EVENT_2BH_04H) \
+__PMC_EV_ALIAS("QMC_ISSOC_READS.ANY", UCP_EVENT_2BH_07H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.CH0", UCP_EVENT_2CH_01H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.CH1", UCP_EVENT_2CH_02H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.CH2", UCP_EVENT_2CH_04H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.ANY", UCP_EVENT_2CH_07H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH0", UCP_EVENT_2DH_01H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH1", UCP_EVENT_2DH_02H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH2", UCP_EVENT_2DH_04H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.ANY", UCP_EVENT_2DH_07H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH0", UCP_EVENT_2EH_01H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH1", UCP_EVENT_2EH_02H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH2", UCP_EVENT_2EH_04H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.ANY", UCP_EVENT_2EH_07H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.CH0", UCP_EVENT_2FH_01H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.CH1", UCP_EVENT_2FH_02H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.CH2", UCP_EVENT_2FH_04H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.ANY", UCP_EVENT_2FH_07H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH0", UCP_EVENT_2FH_08H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH1", UCP_EVENT_2FH_10H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH2", UCP_EVENT_2FH_20H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.ANY", UCP_EVENT_2FH_38H) \
+__PMC_EV_ALIAS("QMC_CANCEL.CH0", UCP_EVENT_30H_01H) \
+__PMC_EV_ALIAS("QMC_CANCEL.CH1", UCP_EVENT_30H_02H) \
+__PMC_EV_ALIAS("QMC_CANCEL.CH2", UCP_EVENT_30H_04H) \
+__PMC_EV_ALIAS("QMC_CANCEL.ANY", UCP_EVENT_30H_07H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH0", UCP_EVENT_31H_01H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH1", UCP_EVENT_31H_02H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH2", UCP_EVENT_31H_04H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.ANY", UCP_EVENT_31H_07H) \
+__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.LOCAL", UCP_EVENT_33H_04H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0", UCP_EVENT_40H_01H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0", UCP_EVENT_40H_02H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0", UCP_EVENT_40H_04H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1", UCP_EVENT_40H_08H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1", UCP_EVENT_40H_10H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1", UCP_EVENT_40H_20H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_0", UCP_EVENT_40H_07H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_1", UCP_EVENT_40H_38H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0", UCP_EVENT_41H_01H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0", UCP_EVENT_41H_02H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0", UCP_EVENT_41H_04H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1", UCP_EVENT_41H_08H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1", UCP_EVENT_41H_10H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1", UCP_EVENT_41H_20H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_0", UCP_EVENT_41H_07H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_1", UCP_EVENT_41H_38H) \
+__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_0", UCP_EVENT_42H_02H) \
+__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_1", UCP_EVENT_42H_08H) \
+__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0", UCP_EVENT_43H_01H) \
+__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1", UCP_EVENT_43H_02H) \
+__PMC_EV_ALIAS("DRAM_OPEN.CH0", UCP_EVENT_60H_01H) \
+__PMC_EV_ALIAS("DRAM_OPEN.CH1", UCP_EVENT_60H_02H) \
+__PMC_EV_ALIAS("DRAM_OPEN.CH2", UCP_EVENT_60H_04H) \
+__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH0", UCP_EVENT_61H_01H) \
+__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH1", UCP_EVENT_61H_02H) \
+__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH2", UCP_EVENT_61H_04H) \
+__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH0", UCP_EVENT_62H_01H) \
+__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH1", UCP_EVENT_62H_02H) \
+__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH2", UCP_EVENT_62H_04H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.CH0", UCP_EVENT_63H_01H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH0", UCP_EVENT_63H_02H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.CH1", UCP_EVENT_63H_04H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH1", UCP_EVENT_63H_08H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.CH2", UCP_EVENT_63H_10H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH2", UCP_EVENT_63H_20H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH0", UCP_EVENT_64H_01H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH0", UCP_EVENT_64H_02H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH1", UCP_EVENT_64H_04H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH1", UCP_EVENT_64H_08H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH2", UCP_EVENT_64H_10H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH2", UCP_EVENT_64H_20H) \
+__PMC_EV_ALIAS("DRAM_REFRESH.CH0", UCP_EVENT_65H_01H) \
+__PMC_EV_ALIAS("DRAM_REFRESH.CH1", UCP_EVENT_65H_02H) \
+__PMC_EV_ALIAS("DRAM_REFRESH.CH2", UCP_EVENT_65H_04H) \
+__PMC_EV_ALIAS("DRAM_PRE_ALL.CH0", UCP_EVENT_66H_01H) \
+__PMC_EV_ALIAS("DRAM_PRE_ALL.CH1", UCP_EVENT_66H_02H) \
+__PMC_EV_ALIAS("DRAM_PRE_ALL.CH2", UCP_EVENT_66H_04H)
+
+#define __PMC_EV_ALIAS_WESTMEREUC() \
+__PMC_EV_ALIAS("GQ_CYCLES_FULL.READ_TRACKER", UCP_EVENT_00H_01H) \
+__PMC_EV_ALIAS("GQ_CYCLES_FULL.WRITE_TRACKER", UCP_EVENT_00H_02H) \
+__PMC_EV_ALIAS("GQ_CYCLES_FULL.PEER_PROBE_TRACKER", UCP_EVENT_00H_04H) \
+__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.READ_TRACKER", UCP_EVENT_01H_01H) \
+__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER", UCP_EVENT_01H_02H) \
+__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER", UCP_EVENT_01H_04H) \
+__PMC_EV_ALIAS("GQ_OCCUPANCY.READ_TRACKER", UCP_EVENT_02H_01H) \
+__PMC_EV_ALIAS("GQ_ALLOC.READ_TRACKER", UCP_EVENT_03H_01H) \
+__PMC_EV_ALIAS("GQ_ALLOC.RT_L3_MISS", UCP_EVENT_03H_02H) \
+__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_L3_RESP", UCP_EVENT_03H_04H) \
+__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_RTID_ACQUIRED", UCP_EVENT_03H_08H) \
+__PMC_EV_ALIAS("GQ_ALLOC.WT_TO_RTID_ACQUIRED", UCP_EVENT_03H_10H) \
+__PMC_EV_ALIAS("GQ_ALLOC.WRITE_TRACKER", UCP_EVENT_03H_20H) \
+__PMC_EV_ALIAS("GQ_ALLOC.PEER_PROBE_TRACKER", UCP_EVENT_03H_40H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_QPI", UCP_EVENT_04H_01H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_QMC", UCP_EVENT_04H_02H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_L3", UCP_EVENT_04H_04H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_02", UCP_EVENT_04H_08H) \
+__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_13", UCP_EVENT_04H_10H) \
+__PMC_EV_ALIAS("GQ_DATA.TO_QPI_QMC", UCP_EVENT_05H_01H) \
+__PMC_EV_ALIAS("GQ_DATA.TO_L3", UCP_EVENT_05H_02H) \
+__PMC_EV_ALIAS("GQ_DATA.TO_CORES", UCP_EVENT_05H_04H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.I_STATE", UCP_EVENT_06H_01H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.S_STATE", UCP_EVENT_06H_02H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE", UCP_EVENT_06H_04H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE", UCP_EVENT_06H_08H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.CONFLICT", UCP_EVENT_06H_10H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.WB", UCP_EVENT_06H_20H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.I_STATE", UCP_EVENT_07H_01H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.S_STATE", UCP_EVENT_07H_02H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE", UCP_EVENT_07H_04H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE", UCP_EVENT_07H_08H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.CONFLICT", UCP_EVENT_07H_10H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.WB", UCP_EVENT_07H_20H) \
+__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.HITM", UCP_EVENT_07H_24H) \
+__PMC_EV_ALIAS("L3_HITS.READ", UCP_EVENT_08H_01H) \
+__PMC_EV_ALIAS("L3_HITS.WRITE", UCP_EVENT_08H_02H) \
+__PMC_EV_ALIAS("L3_HITS.PROBE", UCP_EVENT_08H_04H) \
+__PMC_EV_ALIAS("L3_HITS.ANY", UCP_EVENT_08H_03H) \
+__PMC_EV_ALIAS("L3_MISS.READ", UCP_EVENT_09H_01H) \
+__PMC_EV_ALIAS("L3_MISS.WRITE", UCP_EVENT_09H_02H) \
+__PMC_EV_ALIAS("L3_MISS.PROBE", UCP_EVENT_09H_04H) \
+__PMC_EV_ALIAS("L3_MISS.ANY", UCP_EVENT_09H_03H) \
+__PMC_EV_ALIAS("L3_LINES_IN.M_STATE", UCP_EVENT_0AH_01H) \
+__PMC_EV_ALIAS("L3_LINES_IN.E_STATE", UCP_EVENT_0AH_02H) \
+__PMC_EV_ALIAS("L3_LINES_IN.S_STATE", UCP_EVENT_0AH_04H) \
+__PMC_EV_ALIAS("L3_LINES_IN.F_STATE", UCP_EVENT_0AH_08H) \
+__PMC_EV_ALIAS("L3_LINES_IN.ANY", UCP_EVENT_0AH_0FH) \
+__PMC_EV_ALIAS("L3_LINES_OUT.M_STATE", UCP_EVENT_0BH_01H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.E_STATE", UCP_EVENT_0BH_02H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.S_STATE", UCP_EVENT_0BH_04H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.I_STATE", UCP_EVENT_0BH_08H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.F_STATE", UCP_EVENT_0BH_10H) \
+__PMC_EV_ALIAS("L3_LINES_OUT.ANY", UCP_EVENT_0BH_1FH) \
+__PMC_EV_ALIAS("GQ_SNOOP.GOTO_S", UCP_EVENT_0CH_01H) \
+__PMC_EV_ALIAS("GQ_SNOOP.GOTO_I", UCP_EVENT_0CH_02H) \
+__PMC_EV_ALIAS("GQ_SNOOP.GOTO_S_HIT", UCP_EVENT_0CH_04H) \
+__PMC_EV_ALIAS("GQ_SNOOP.GOTO_I_HIT", UCP_EVENT_0CH_08H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.IOH_READS", UCP_EVENT_20H_01H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.IOH_WRITES", UCP_EVENT_20H_02H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_READS", UCP_EVENT_20H_04H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_WRITES", UCP_EVENT_20H_08H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_READS", UCP_EVENT_20H_10H) \
+__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_WRITES", UCP_EVENT_20H_20H) \
+__PMC_EV_ALIAS("QHL_CYCLES_FULL.IOH", UCP_EVENT_21H_01H) \
+__PMC_EV_ALIAS("QHL_CYCLES_FULL.REMOTE", UCP_EVENT_21H_02H) \
+__PMC_EV_ALIAS("QHL_CYCLES_FULL.LOCAL", UCP_EVENT_21H_04H) \
+__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.IOH", UCP_EVENT_22H_01H) \
+__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.REMOTE", UCP_EVENT_22H_02H) \
+__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.LOCAL", UCP_EVENT_22H_04H) \
+__PMC_EV_ALIAS("QHL_OCCUPANCY.IOH", UCP_EVENT_23H_01H) \
+__PMC_EV_ALIAS("QHL_OCCUPANCY.REMOTE", UCP_EVENT_23H_02H) \
+__PMC_EV_ALIAS("QHL_OCCUPANCY.LOCAL", UCP_EVENT_23H_04H) \
+__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.2WAY", UCP_EVENT_24H_02H) \
+__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.3WAY", UCP_EVENT_24H_04H) \
+__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.IOH", UCP_EVENT_25H_01H) \
+__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.REMOTE", UCP_EVENT_25H_02H) \
+__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.LOCAL", UCP_EVENT_25H_04H) \
+__PMC_EV_ALIAS("QHL_TO_QMC_BYPASS", UCP_EVENT_26H_01H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH0", UCP_EVENT_28H_01H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH1", UCP_EVENT_28H_02H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH2", UCP_EVENT_28H_04H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH0", UCP_EVENT_28H_08H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH1", UCP_EVENT_28H_10H) \
+__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH2", UCP_EVENT_28H_20H) \
+__PMC_EV_ALIAS("QMC_BUSY.READ.CH0", UCP_EVENT_29H_01H) \
+__PMC_EV_ALIAS("QMC_BUSY.READ.CH1", UCP_EVENT_29H_02H) \
+__PMC_EV_ALIAS("QMC_BUSY.READ.CH2", UCP_EVENT_29H_04H) \
+__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH0", UCP_EVENT_29H_08H) \
+__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH1", UCP_EVENT_29H_10H) \
+__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH2", UCP_EVENT_29H_20H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.CH0", UCP_EVENT_2AH_01H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.CH1", UCP_EVENT_2AH_02H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.CH2", UCP_EVENT_2AH_04H) \
+__PMC_EV_ALIAS("QMC_OCCUPANCY.ANY", UCP_EVENT_2AH_07H) \
+__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH0", UCP_EVENT_2BH_01H) \
+__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH1", UCP_EVENT_2BH_02H) \
+__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH2", UCP_EVENT_2BH_04H) \
+__PMC_EV_ALIAS("QMC_ISSOC_READS.ANY", UCP_EVENT_2BH_07H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.CH0", UCP_EVENT_2CH_01H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.CH1", UCP_EVENT_2CH_02H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.CH2", UCP_EVENT_2CH_04H) \
+__PMC_EV_ALIAS("QMC_NORMAL_READS.ANY", UCP_EVENT_2CH_07H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH0", UCP_EVENT_2DH_01H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH1", UCP_EVENT_2DH_02H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH2", UCP_EVENT_2DH_04H) \
+__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.ANY", UCP_EVENT_2DH_07H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH0", UCP_EVENT_2EH_01H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH1", UCP_EVENT_2EH_02H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH2", UCP_EVENT_2EH_04H) \
+__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.ANY", UCP_EVENT_2EH_07H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.CH0", UCP_EVENT_2FH_01H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.CH1", UCP_EVENT_2FH_02H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.CH2", UCP_EVENT_2FH_04H) \
+__PMC_EV_ALIAS("QMC_WRITES.FULL.ANY", UCP_EVENT_2FH_07H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH0", UCP_EVENT_2FH_08H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH1", UCP_EVENT_2FH_10H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH2", UCP_EVENT_2FH_20H) \
+__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.ANY", UCP_EVENT_2FH_38H) \
+__PMC_EV_ALIAS("QMC_CANCEL.CH0", UCP_EVENT_30H_01H) \
+__PMC_EV_ALIAS("QMC_CANCEL.CH1", UCP_EVENT_30H_02H) \
+__PMC_EV_ALIAS("QMC_CANCEL.CH2", UCP_EVENT_30H_04H) \
+__PMC_EV_ALIAS("QMC_CANCEL.ANY", UCP_EVENT_30H_07H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH0", UCP_EVENT_31H_01H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH1", UCP_EVENT_31H_02H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH2", UCP_EVENT_31H_04H) \
+__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.ANY", UCP_EVENT_31H_07H) \
+__PMC_EV_ALIAS("IMC_RETRY.CH0", UCP_EVENT_32H_01H) \
+__PMC_EV_ALIAS("IMC_RETRY.CH1", UCP_EVENT_32H_02H) \
+__PMC_EV_ALIAS("IMC_RETRY.CH2", UCP_EVENT_32H_04H) \
+__PMC_EV_ALIAS("IMC_RETRY.ANY", UCP_EVENT_32H_07H) \
+__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.IOH", UCP_EVENT_33H_01H) \
+__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.REMOTE", UCP_EVENT_33H_02H) \
+__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.LOCAL", UCP_EVENT_33H_04H) \
+__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.ANY", UCP_EVENT_33H_07H) \
+__PMC_EV_ALIAS("QHL_SLEEPS.IOH_ORDER", UCP_EVENT_34H_01H) \
+__PMC_EV_ALIAS("QHL_SLEEPS.REMOTE_ORDER", UCP_EVENT_34H_02H) \
+__PMC_EV_ALIAS("QHL_SLEEPS.LOCAL_ORDER", UCP_EVENT_34H_04H) \
+__PMC_EV_ALIAS("QHL_SLEEPS.IOH_CONFLICT", UCP_EVENT_34H_08H) \
+__PMC_EV_ALIAS("QHL_SLEEPS.REMOTE_CONFLICT", UCP_EVENT_34H_10H) \
+__PMC_EV_ALIAS("QHL_SLEEPS.LOCAL_CONFLICT", UCP_EVENT_34H_20H) \
+__PMC_EV_ALIAS("ADDR_OPCODE_MATCH.IOH", UCP_EVENT_35H_01H) \
+__PMC_EV_ALIAS("ADDR_OPCODE_MATCH.REMOTE", UCP_EVENT_35H_02H) \
+__PMC_EV_ALIAS("ADDR_OPCODE_MATCH.LOCAL", UCP_EVENT_35H_04H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0", UCP_EVENT_40H_01H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0", UCP_EVENT_40H_02H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0", UCP_EVENT_40H_04H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1", UCP_EVENT_40H_08H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1", UCP_EVENT_40H_10H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1", UCP_EVENT_40H_20H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_0", UCP_EVENT_40H_07H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_1", UCP_EVENT_40H_38H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0", UCP_EVENT_41H_01H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0", UCP_EVENT_41H_02H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0", UCP_EVENT_41H_04H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1", UCP_EVENT_41H_08H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1", UCP_EVENT_41H_10H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1", UCP_EVENT_41H_20H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_0", UCP_EVENT_41H_07H) \
+__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_1", UCP_EVENT_41H_38H) \
+__PMC_EV_ALIAS("QPI_TX_HEADER.FULL.LINK_0", UCP_EVENT_42H_01H) \
+__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_0", UCP_EVENT_42H_02H) \
+__PMC_EV_ALIAS("QPI_TX_HEADER.FULL.LINK_1", UCP_EVENT_42H_04H) \
+__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_1", UCP_EVENT_42H_08H) \
+__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0", UCP_EVENT_43H_01H) \
+__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1", UCP_EVENT_43H_02H) \
+__PMC_EV_ALIAS("DRAM_OPEN.CH0", UCP_EVENT_60H_01H) \
+__PMC_EV_ALIAS("DRAM_OPEN.CH1", UCP_EVENT_60H_02H) \
+__PMC_EV_ALIAS("DRAM_OPEN.CH2", UCP_EVENT_60H_04H) \
+__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH0", UCP_EVENT_61H_01H) \
+__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH1", UCP_EVENT_61H_02H) \
+__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH2", UCP_EVENT_61H_04H) \
+__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH0", UCP_EVENT_62H_01H) \
+__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH1", UCP_EVENT_62H_02H) \
+__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH2", UCP_EVENT_62H_04H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.CH0", UCP_EVENT_63H_01H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH0", UCP_EVENT_63H_02H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.CH1", UCP_EVENT_63H_04H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH1", UCP_EVENT_63H_08H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.CH2", UCP_EVENT_63H_10H) \
+__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH2", UCP_EVENT_63H_20H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH0", UCP_EVENT_64H_01H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH0", UCP_EVENT_64H_02H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH1", UCP_EVENT_64H_04H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH1", UCP_EVENT_64H_08H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH2", UCP_EVENT_64H_10H) \
+__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH2", UCP_EVENT_64H_20H) \
+__PMC_EV_ALIAS("DRAM_REFRESH.CH0", UCP_EVENT_65H_01H) \
+__PMC_EV_ALIAS("DRAM_REFRESH.CH1", UCP_EVENT_65H_02H) \
+__PMC_EV_ALIAS("DRAM_REFRESH.CH2", UCP_EVENT_65H_04H) \
+__PMC_EV_ALIAS("DRAM_PRE_ALL.CH0", UCP_EVENT_66H_01H) \
+__PMC_EV_ALIAS("DRAM_PRE_ALL.CH1", UCP_EVENT_66H_02H) \
+__PMC_EV_ALIAS("DRAM_PRE_ALL.CH2", UCP_EVENT_66H_04H) \
+__PMC_EV_ALIAS("DRAM_THERMAL_THROTTLED", UCP_EVENT_67H_01H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_0", UCP_EVENT_80H_01H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_1", UCP_EVENT_80H_02H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_2", UCP_EVENT_80H_04H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_3", UCP_EVENT_80H_08H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_0", UCP_EVENT_81H_01H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_1", UCP_EVENT_81H_02H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_2", UCP_EVENT_81H_04H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_3", UCP_EVENT_81H_08H) \
+__PMC_EV_ALIAS("PROCHOT_ASSERTION", UCP_EVENT_82H_01H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_0", UCP_EVENT_83H_01H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_1", UCP_EVENT_83H_02H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_2", UCP_EVENT_83H_04H) \
+__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_3", UCP_EVENT_83H_08H) \
+__PMC_EV_ALIAS("TURBO_MODE.CORE_0", UCP_EVENT_84H_01H) \
+__PMC_EV_ALIAS("TURBO_MODE.CORE_1", UCP_EVENT_84H_02H) \
+__PMC_EV_ALIAS("TURBO_MODE.CORE_2", UCP_EVENT_84H_04H) \
+__PMC_EV_ALIAS("TURBO_MODE.CORE_3", UCP_EVENT_84H_08H) \
+__PMC_EV_ALIAS("CYCLES_UNHALTED_L3_FLL_ENABLE", UCP_EVENT_85H_02H) \
+__PMC_EV_ALIAS("CYCLES_UNHALTED_L3_FLL_DISABLE", UCP_EVENT_86H_01H)
/*
* Intel XScale events from:
@@ -2027,6 +2994,106 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
#define PMC_EV_XSCALE_LAST PMC_EV_XSCALE_DATA_BUS_TRANS
/*
+ * MIPS Events from "Programming the MIPS32 24K Core Family",
+ * Document Number: MD00355 Revision 04.63 December 19, 2008
+ * These events are kept in the order found in Table 7.4.
+ * For counters which are different between the left hand
+ * column (0/2) and the right hand column (1/3) the left
+ * hand is given first, e.g. BRANCH_COMPLETED and BRANCH_MISPRED
+ * in the definition below.
+ */
+
+#define __PMC_EV_MIPS24K() \
+ __PMC_EV(MIPS24K, CYCLE) \
+ __PMC_EV(MIPS24K, INSTR_EXECUTED) \
+ __PMC_EV(MIPS24K, BRANCH_COMPLETED) \
+ __PMC_EV(MIPS24K, BRANCH_MISPRED) \
+ __PMC_EV(MIPS24K, RETURN) \
+ __PMC_EV(MIPS24K, RETURN_MISPRED) \
+ __PMC_EV(MIPS24K, RETURN_NOT_31) \
+ __PMC_EV(MIPS24K, RETURN_NOTPRED) \
+ __PMC_EV(MIPS24K, ITLB_ACCESS) \
+ __PMC_EV(MIPS24K, ITLB_MISS) \
+ __PMC_EV(MIPS24K, DTLB_ACCESS) \
+ __PMC_EV(MIPS24K, DTLB_MISS) \
+ __PMC_EV(MIPS24K, JTLB_IACCESS) \
+ __PMC_EV(MIPS24K, JTLB_IMISS) \
+ __PMC_EV(MIPS24K, JTLB_DACCESS) \
+ __PMC_EV(MIPS24K, JTLB_DMISS) \
+ __PMC_EV(MIPS24K, IC_FETCH) \
+ __PMC_EV(MIPS24K, IC_MISS) \
+ __PMC_EV(MIPS24K, DC_LOADSTORE) \
+ __PMC_EV(MIPS24K, DC_WRITEBACK) \
+ __PMC_EV(MIPS24K, DC_MISS) \
+ __PMC_EV(MIPS24K, STORE_MISS) \
+ __PMC_EV(MIPS24K, LOAD_MISS) \
+ __PMC_EV(MIPS24K, INTEGER_COMPLETED) \
+ __PMC_EV(MIPS24K, FP_COMPLETED) \
+ __PMC_EV(MIPS24K, LOAD_COMPLETED) \
+ __PMC_EV(MIPS24K, STORE_COMPLETED) \
+ __PMC_EV(MIPS24K, BARRIER_COMPLETED) \
+ __PMC_EV(MIPS24K, MIPS16_COMPLETED) \
+ __PMC_EV(MIPS24K, NOP_COMPLETED) \
+ __PMC_EV(MIPS24K, INTEGER_MULDIV_COMPLETED)\
+ __PMC_EV(MIPS24K, RF_STALL) \
+ __PMC_EV(MIPS24K, INSTR_REFETCH) \
+ __PMC_EV(MIPS24K, STORE_COND_COMPLETED) \
+ __PMC_EV(MIPS24K, STORE_COND_FAILED) \
+ __PMC_EV(MIPS24K, ICACHE_REQUESTS) \
+ __PMC_EV(MIPS24K, ICACHE_HIT) \
+ __PMC_EV(MIPS24K, L2_WRITEBACK) \
+ __PMC_EV(MIPS24K, L2_ACCESS) \
+ __PMC_EV(MIPS24K, L2_MISS) \
+ __PMC_EV(MIPS24K, L2_ERR_CORRECTED) \
+ __PMC_EV(MIPS24K, EXCEPTIONS) \
+ __PMC_EV(MIPS24K, RF_CYCLES_STALLED) \
+ __PMC_EV(MIPS24K, IFU_CYCLES_STALLED) \
+ __PMC_EV(MIPS24K, ALU_CYCLES_STALLED) \
+ __PMC_EV(MIPS24K, UNCACHED_LOAD) \
+ __PMC_EV(MIPS24K, UNCACHED_STORE) \
+ __PMC_EV(MIPS24K, CP2_REG_TO_REG_COMPLETED)\
+ __PMC_EV(MIPS24K, MFTC_COMPLETED) \
+ __PMC_EV(MIPS24K, IC_BLOCKED_CYCLES) \
+ __PMC_EV(MIPS24K, DC_BLOCKED_CYCLES) \
+ __PMC_EV(MIPS24K, L2_IMISS_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, L2_DMISS_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, DMISS_CYCLES) \
+ __PMC_EV(MIPS24K, L2_MISS_CYCLES) \
+ __PMC_EV(MIPS24K, UNCACHED_BLOCK_CYCLES) \
+ __PMC_EV(MIPS24K, MDU_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, FPU_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, CP2_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, COREXTEND_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, ISPRAM_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, DSPRAM_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, CACHE_STALL_CYCLES) \
+ __PMC_EV(MIPS24K, LOAD_TO_USE_STALLS) \
+ __PMC_EV(MIPS24K, BASE_MISPRED_STALLS) \
+ __PMC_EV(MIPS24K, CPO_READ_STALLS) \
+ __PMC_EV(MIPS24K, BRANCH_MISPRED_CYCLES) \
+ __PMC_EV(MIPS24K, IFETCH_BUFFER_FULL) \
+ __PMC_EV(MIPS24K, FETCH_BUFFER_ALLOCATED) \
+ __PMC_EV(MIPS24K, EJTAG_ITRIGGER) \
+ __PMC_EV(MIPS24K, EJTAG_DTRIGGER) \
+ __PMC_EV(MIPS24K, FSB_LT_QUARTER) \
+ __PMC_EV(MIPS24K, FSB_QUARTER_TO_HALF) \
+ __PMC_EV(MIPS24K, FSB_GT_HALF) \
+ __PMC_EV(MIPS24K, FSB_FULL_PIPELINE_STALLS)\
+ __PMC_EV(MIPS24K, LDQ_LT_QUARTER) \
+ __PMC_EV(MIPS24K, LDQ_QUARTER_TO_HALF) \
+ __PMC_EV(MIPS24K, LDQ_GT_HALF) \
+ __PMC_EV(MIPS24K, LDQ_FULL_PIPELINE_STALLS)\
+ __PMC_EV(MIPS24K, WBB_LT_QUARTER) \
+ __PMC_EV(MIPS24K, WBB_QUARTER_TO_HALF) \
+ __PMC_EV(MIPS24K, WBB_GT_HALF) \
+ __PMC_EV(MIPS24K, WBB_FULL_PIPELINE_STALLS) \
+ __PMC_EV(MIPS24K, REQUEST_LATENCY) \
+ __PMC_EV(MIPS24K, REQUEST_COUNT)
+
+#define PMC_EV_MIPS24K_FIRST PMC_EV_MIPS24K_CYCLE
+#define PMC_EV_MIPS24K_LAST PMC_EV_MIPS24K_WBB_FULL_PIPELINE_STALLS
+
+/*
* All known PMC events.
*
* PMC event numbers are allocated sparsely to allow new PMC events to
@@ -2044,6 +3111,7 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
* 0x11080 0x0080 INTEL Pentium MMX events
* 0x11100 0x0100 INTEL Pentium Pro/P-II/P-III/Pentium-M events
* 0x11200 0x00FF INTEL XScale events
+ * 0x11300 0x00FF MIPS 24K events
*/
#define __PMC_EVENTS() \
__PMC_EV_BLOCK(TSC, 0x01000) \
@@ -2063,9 +3131,15 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
__PMC_EV_BLOCK(P6, 0x11100) \
__PMC_EV_P6() \
__PMC_EV_BLOCK(XSCALE, 0x11200) \
- __PMC_EV_XSCALE()
+ __PMC_EV_XSCALE() \
+ __PMC_EV_BLOCK(MIPS24K, 0x11300) \
+ __PMC_EV_MIPS24K() \
+ __PMC_EV_BLOCK(UCF, 0x12000) \
+ __PMC_EV_UCF() \
+ __PMC_EV_BLOCK(UCP, 0x12080) \
+ __PMC_EV_UCP() \
#define PMC_EVENT_FIRST PMC_EV_TSC_TSC
-#define PMC_EVENT_LAST PMC_EV_XSCALE_LAST
+#define PMC_EVENT_LAST PMC_EV_UCP_LAST
#endif /* _DEV_HWPMC_PMC_EVENTS_H_ */
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index 0b21758..3315d65 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -888,10 +888,10 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/*
* XXX when joining an ibss network we are called
* with a SCAN -> RUN transition on scan complete.
- * Use that to call ipw_auth_and_assoc. On completing
- * the join we are then called again with an
- * AUTH -> RUN transition and we want to do nothing.
- * This is all totally bogus and needs to be redone.
+ * Use that to call ipw_assoc. On completing the
+ * join we are then called again with an AUTH -> RUN
+ * transition and we want to do nothing. This is
+ * all totally bogus and needs to be redone.
*/
if (ostate == IEEE80211_S_SCAN)
ipw_assoc(ic, vap);
@@ -904,12 +904,19 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
break;
case IEEE80211_S_AUTH:
+ /*
+ * Move to ASSOC state after the ipw_assoc() call. Firmware
+ * takes care of authentication, after the call we'll receive
+ * only an assoc response which would otherwise be discared
+ * if we are still in AUTH state.
+ */
+ nstate = IEEE80211_S_ASSOC;
ipw_assoc(ic, vap);
break;
case IEEE80211_S_ASSOC:
/*
- * If we are not transitioning from AUTH the resend the
+ * If we are not transitioning from AUTH then resend the
* association request.
*/
if (ostate != IEEE80211_S_AUTH)
@@ -1021,7 +1028,6 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
}
sc->flags &= ~IPW_FLAG_ASSOCIATING;
sc->flags |= IPW_FLAG_ASSOCIATED;
- ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
break;
case IPW_STATE_SCANNING:
@@ -1034,8 +1040,10 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
* we checked the 802.11 layer state.
*/
if (sc->flags & IPW_FLAG_ASSOCIATED) {
+ IPW_UNLOCK(sc);
/* XXX probably need to issue disassoc to fw */
ieee80211_beacon_miss(ic);
+ IPW_LOCK(sc);
}
break;
@@ -1054,7 +1062,9 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
break;
}
if (sc->flags & IPW_FLAG_SCANNING) {
+ IPW_UNLOCK(sc);
ieee80211_scan_done(vap);
+ IPW_LOCK(sc);
sc->flags &= ~IPW_FLAG_SCANNING;
sc->sc_scan_timer = 0;
}
@@ -1064,13 +1074,16 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
DPRINTFN(2, ("Association lost (%s flags 0x%x)\n",
IEEESTATE(vap), sc->flags));
sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
- if (vap->iv_state == IEEE80211_S_RUN)
+ if (vap->iv_state == IEEE80211_S_RUN) {
+ IPW_UNLOCK(sc);
ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
+ IPW_LOCK(sc);
+ }
break;
case IPW_STATE_DISABLED:
/* XXX? is this right? */
- sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING |
+ sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING |
IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n",
IEEESTATE(vap), sc->flags));
@@ -1164,7 +1177,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
bus_addr_t physaddr;
int error;
int8_t rssi, nf;
- IPW_LOCK_DECL;
DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
status->rssi));
@@ -1234,10 +1246,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
IPW_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, nf);
+ (void) ieee80211_input(ni, m, rssi - nf, nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, rssi, nf);
+ (void) ieee80211_input_all(ic, m, rssi - nf, nf);
IPW_LOCK(sc);
bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
@@ -1378,8 +1390,11 @@ ipw_fatal_error_intr(struct ipw_softc *sc)
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
device_printf(sc->sc_dev, "firmware error\n");
- if (vap != NULL)
+ if (vap != NULL) {
+ IPW_UNLOCK(sc);
ieee80211_cancel_scan(vap);
+ IPW_LOCK(sc);
+ }
ieee80211_runtask(ic, &sc->sc_init_task);
}
@@ -1388,7 +1403,6 @@ ipw_intr(void *arg)
{
struct ipw_softc *sc = arg;
uint32_t r;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
@@ -1718,7 +1732,6 @@ static void
ipw_start(struct ifnet *ifp)
{
struct ipw_softc *sc = ifp->if_softc;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
ipw_start_locked(ifp);
@@ -1775,7 +1788,9 @@ ipw_watchdog(void *arg)
DPRINTFN(3, ("Scan timeout\n"));
/* End the scan */
if (sc->flags & IPW_FLAG_SCANNING) {
+ IPW_UNLOCK(sc);
ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
+ IPW_LOCK(sc);
sc->flags &= ~IPW_FLAG_SCANNING;
}
}
@@ -1791,7 +1806,6 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ieee80211com *ic = ifp->if_l2com;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0, startall = 0;
- IPW_LOCK_DECL;
switch (cmd) {
case SIOCSIFFLAGS:
@@ -2201,7 +2215,6 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
struct ipw_security security;
uint32_t data;
int error;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
error = ipw_disable(sc);
@@ -2260,8 +2273,8 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
if (error != 0)
goto done;
- if (vap->iv_appie_assocreq != NULL) {
- struct ieee80211_appie *ie = vap->iv_appie_assocreq;
+ if (vap->iv_appie_wpa != NULL) {
+ struct ieee80211_appie *ie = vap->iv_appie_wpa;
error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len);
if (error != 0)
goto done;
@@ -2291,7 +2304,6 @@ ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct ieee80211_node *ni = vap->iv_bss;
struct ipw_softc *sc = ifp->if_softc;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":"));
@@ -2327,7 +2339,6 @@ ipw_init(void *priv)
struct ipw_softc *sc = priv;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
ipw_init_locked(sc);
@@ -2534,7 +2545,6 @@ static void
ipw_stop(void *priv)
{
struct ipw_softc *sc = priv;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
ipw_stop_locked(sc);
@@ -2661,7 +2671,6 @@ ipw_scan_start(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
ipw_scan(sc);
@@ -2673,7 +2682,6 @@ ipw_set_channel(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
if (ic->ic_opmode == IEEE80211_M_MONITOR) {
@@ -2701,7 +2709,6 @@ ipw_scan_end(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
- IPW_LOCK_DECL;
IPW_LOCK(sc);
sc->flags &= ~IPW_FLAG_SCANNING;
diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h
index 8d9e049..89702d0 100644
--- a/sys/dev/ipw/if_ipwvar.h
+++ b/sys/dev/ipw/if_ipwvar.h
@@ -164,13 +164,6 @@ struct ipw_softc {
* NB.: This models the only instance of async locking in ipw_init_locked
* and must be kept in sync.
*/
-#define IPW_LOCK_DECL int __waslocked = 0
-#define IPW_LOCK(sc) do { \
- if (!(__waslocked = mtx_owned(&(sc)->sc_mtx))) \
- mtx_lock(&sc->sc_mtx); \
-} while (0)
-#define IPW_UNLOCK(sc) do { \
- if (!__waslocked) \
- mtx_unlock(&sc->sc_mtx); \
-} while (0)
+#define IPW_LOCK(sc) mtx_lock(&sc->sc_mtx);
+#define IPW_UNLOCK(sc) mtx_unlock(&sc->sc_mtx);
#define IPW_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 65e5d86..a03573a 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -74,14 +74,9 @@ __FBSDID("$FreeBSD$");
*/
static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
-static const char xact1[] = "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
-static const char xact2[] = "HBA attempted queued transaction to target routine %d on target %d bus %d";
-static const char xact3[] = "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
-static const char pskip[] = "SCSI phase skipped for target %d.%d.%d";
static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
-static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x";
static const char sc4[] = "NVRAM";
-static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)";
+static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
static const char lipd[] = "Chan %d LIP destroyed %d active commands";
static const char sacq[] = "unable to acquire scratch area";
@@ -107,6 +102,7 @@ static const uint8_t alpa_map[] = {
/*
* Local function prototypes.
*/
+static void isp_prt_endcmd(ispsoftc_t *, XS_T *);
static int isp_parse_async(ispsoftc_t *, uint16_t);
static int isp_parse_async_fc(ispsoftc_t *, uint16_t);
static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
@@ -1431,10 +1427,8 @@ isp_scsi_channel_init(ispsoftc_t *isp, int chan)
(sdp->isp_devparam[tgt].goal_offset << 8) |
(sdp->isp_devparam[tgt].goal_period);
}
- isp_prt(isp, ISP_LOGDEBUG0,
- "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
- chan, tgt, mbs.param[2], mbs.param[3] >> 8,
- mbs.param[3] & 0xff);
+ isp_prt(isp, ISP_LOGDEBUG0, "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
+ chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdf = DPARM_SAFE_DFLT;
@@ -1705,8 +1699,7 @@ isp_fibre_init(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, sacq);
return;
}
- isp_prt(isp, ISP_LOGDEBUG0,
- "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
@@ -4435,7 +4428,7 @@ isp_start(XS_T *xs)
*/
return (dmaresult);
}
- isp_prt(isp, ISP_LOGDEBUG0, "START cmd for %d.%d.%d cmd 0x%x datalen %ld", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
isp->isp_nactive++;
return (CMD_QUEUED);
}
@@ -5248,7 +5241,7 @@ again:
} else {
ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
}
- isp_prt(isp, ISP_LOGWARN, "%d.%d.%d FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), rlen, ptr, XS_CDBP(xs)[0] & 0xff);
+ isp_xs_prt(isp, xs, ISP_LOGWARN, "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", rlen, ptr, XS_CDBP(xs)[0] & 0xff);
if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
XS_SETERR(xs, HBA_BOTCH);
}
@@ -5325,25 +5318,9 @@ again:
isp_destroy_handle(isp, sp->req_handle);
if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
- ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
- (*XS_STSP(xs) != SCSI_GOOD)))) {
- char skey;
- if (req_state_flags & RQSF_GOT_SENSE) {
- skey = XS_SNSKEY(xs) & 0xf;
- if (skey < 10)
- skey += '0';
- else
- skey += 'a' - 10;
- } else if (*XS_STSP(xs) == SCSI_CHECK) {
- skey = '?';
- } else {
- skey = '.';
- }
- isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
- XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), (long) XS_GET_RESID(xs),
- *XS_STSP(xs), skey, XS_ERR(xs));
+ ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
+ isp_prt_endcmd(isp, xs);
}
-
if (isp->isp_nactive > 0) {
isp->isp_nactive--;
}
@@ -5393,6 +5370,25 @@ out:
* Support routines.
*/
+static void
+isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
+{
+ char cdbstr[16 * 5 + 1];
+ int i, lim;
+
+ lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
+ ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
+ for (i = 1; i < lim; i++) {
+ ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
+ }
+ if (XS_SENSE_VALID(xs)) {
+ isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s KEY/ASC/ASCQ=0x%02x/0x%02x/0x%02x",
+ XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs));
+ } else {
+ isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s STS 0x%x XS_ERR=0x%x", XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, *XS_STSP(xs), XS_ERR(xs));
+ }
+}
+
/*
* Parse an ASYNC mailbox complete
*
@@ -5937,8 +5933,7 @@ isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
*/
static int
-isp_handle_other_response(ispsoftc_t *isp, int type,
- isphdr_t *hp, uint32_t *optrp)
+isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
{
switch (type) {
case RQSTYPE_STATUS_CONT:
@@ -6010,24 +6005,18 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
case RQCS_INCOMPLETE:
if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
- isp_prt(isp, ISP_LOGDEBUG1,
- "Selection Timeout for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGDEBUG1, "Selection Timeout");
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_SELTIMEOUT);
*rp = XS_XFRLEN(xs);
}
return;
}
- isp_prt(isp, ISP_LOGERR,
- "command incomplete for %d.%d.%d, state 0x%x",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
- sp->req_state_flags);
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
break;
case RQCS_DMA_ERROR:
- isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
*rp = XS_XFRLEN(xs);
break;
@@ -6081,18 +6070,14 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
if (sp->req_status_flags & RQSTF_NEGOTIATION) {
ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
}
- isp_prt(isp, ISP_LOGERR, "%s", buf);
- isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error: %s", buf);
*rp = XS_XFRLEN(xs);
break;
}
case RQCS_RESET_OCCURRED:
{
int chan;
- isp_prt(isp, ISP_LOGWARN,
- "bus reset destroyed command for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
for (chan = 0; chan < isp->isp_nchan; chan++) {
FCPARAM(isp, chan)->sendmarker = 1;
}
@@ -6103,8 +6088,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
return;
}
case RQCS_ABORTED:
- isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ABORTED);
@@ -6112,8 +6096,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
return;
case RQCS_TIMEOUT:
- isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
/*
* XXX: Check to see if we logged out of the device.
*/
@@ -6124,83 +6107,62 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
case RQCS_DATA_OVERRUN:
XS_SET_RESID(xs, sp->req_resid);
- isp_prt(isp, ISP_LOGERR, "data overrun (%ld) for command on %d.%d.%d",
- (long) XS_GET_RESID(xs), XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_DATAOVR);
}
return;
case RQCS_COMMAND_OVERRUN:
- isp_prt(isp, ISP_LOGERR,
- "command overrun for command on %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
break;
case RQCS_STATUS_OVERRUN:
- isp_prt(isp, ISP_LOGERR,
- "status overrun for command on %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
break;
case RQCS_BAD_MESSAGE:
- isp_prt(isp, ISP_LOGERR,
- "msg not COMMAND COMPLETE after status %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
break;
case RQCS_NO_MESSAGE_OUT:
- isp_prt(isp, ISP_LOGERR,
- "No MESSAGE OUT phase after selection on %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
break;
case RQCS_EXT_ID_FAILED:
- isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
break;
case RQCS_IDE_MSG_FAILED:
- isp_prt(isp, ISP_LOGERR,
- "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
break;
case RQCS_ABORT_MSG_FAILED:
- isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
break;
case RQCS_REJECT_MSG_FAILED:
- isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
break;
case RQCS_NOP_MSG_FAILED:
- isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
break;
case RQCS_PARITY_ERROR_MSG_FAILED:
- isp_prt(isp, ISP_LOGERR,
- "MESSAGE PARITY ERROR rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
break;
case RQCS_DEVICE_RESET_MSG_FAILED:
- isp_prt(isp, ISP_LOGWARN,
- "BUS DEVICE RESET rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
break;
case RQCS_ID_MSG_FAILED:
- isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
break;
case RQCS_UNEXP_BUS_FREE:
- isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
break;
case RQCS_DATA_UNDERRUN:
@@ -6208,9 +6170,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
if (IS_FC(isp)) {
int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
- isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
- XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
- (ru_marked)? "marked" : "not marked");
+ isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
@@ -6225,18 +6185,15 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
}
case RQCS_XACT_ERR1:
- isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
- XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
break;
case RQCS_XACT_ERR2:
- isp_prt(isp, ISP_LOGERR, xact2,
- XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction to target routine %d", XS_LUN(xs));
break;
case RQCS_XACT_ERR3:
- isp_prt(isp, ISP_LOGERR, xact3,
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
break;
case RQCS_BAD_ENTRY:
@@ -6244,9 +6201,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
break;
case RQCS_QUEUE_FULL:
- isp_prt(isp, ISP_LOGDEBUG0,
- "internal queues full for %d.%d.%d status 0x%x",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
+ isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "internal queues full status 0x%x", *XS_STSP(xs));
/*
* If QFULL or some other status byte is set, then this
@@ -6270,23 +6225,18 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
return;
case RQCS_PHASE_SKIPPED:
- isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
- XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
break;
case RQCS_ARQS_FAILED:
- isp_prt(isp, ISP_LOGERR,
- "Auto Request Sense failed for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ARQFAIL);
}
return;
case RQCS_WIDE_FAILED:
- isp_prt(isp, ISP_LOGERR,
- "Wide Negotiation failed for %d.%d.%d",
- XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
if (IS_SCSI(isp)) {
sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
@@ -6299,9 +6249,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
return;
case RQCS_SYNCXFER_FAILED:
- isp_prt(isp, ISP_LOGERR,
- "SDTR Message failed for target %d.%d.%d",
- XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
if (IS_SCSI(isp)) {
sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
sdp += XS_CHANNEL(xs);
@@ -6312,9 +6260,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
break;
case RQCS_LVD_BUSERR:
- isp_prt(isp, ISP_LOGERR,
- "Bad LVD condition while talking to %d.%d.%d",
- XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
break;
case RQCS_PORT_UNAVAILABLE:
@@ -6384,8 +6330,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
}
static void
-isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
- XS_T *xs, long *rp)
+isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
{
int ru_marked, sv_marked;
int chan = XS_CHANNEL(xs);
@@ -6398,19 +6343,15 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
case RQCS_DMA_ERROR:
- isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
break;
case RQCS_TRANSPORT_ERROR:
- isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error");
break;
case RQCS_RESET_OCCURRED:
- isp_prt(isp, ISP_LOGWARN,
- "reset destroyed command for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
FCPARAM(isp, chan)->sendmarker = 1;
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BUSRESET);
@@ -6418,8 +6359,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
case RQCS_ABORTED:
- isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
FCPARAM(isp, chan)->sendmarker = 1;
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ABORTED);
@@ -6427,8 +6367,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
case RQCS_TIMEOUT:
- isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_CMDTIMEOUT);
}
@@ -6436,9 +6375,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
case RQCS_DATA_OVERRUN:
XS_SET_RESID(xs, sp->req_resid);
- isp_prt(isp, ISP_LOGERR,
- "data overrun for command on %d.%d.%d",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_DATAOVR);
}
@@ -6471,19 +6408,14 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
if ((ru_marked == 0 && sv_marked == 0) ||
(sp->req_resid > XS_XFRLEN(xs))) {
- isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
- XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
- (ru_marked)? "marked" : "not marked");
+ isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
return;
}
XS_SET_RESID(xs, sp->req_resid);
- isp_prt(isp, ISP_LOGDEBUG0,
- "%d.%d.%d data underrun (%d) for command 0x%x",
- XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
- sp->req_resid, XS_CDBP(xs)[0] & 0xff);
+ isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_NOERROR);
}
@@ -7384,8 +7316,7 @@ isp_spi_update(ispsoftc_t *isp, int chan)
if (sdp->isp_devparam[tgt].dev_enable == 0) {
sdp->isp_devparam[tgt].dev_update = 0;
sdp->isp_devparam[tgt].dev_refresh = 0;
- isp_prt(isp, ISP_LOGDEBUG0,
- "skipping target %d bus %d update", tgt, chan);
+ isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
continue;
}
/*
@@ -7441,10 +7372,8 @@ isp_spi_update(ispsoftc_t *isp, int chan)
sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
sdp->isp_devparam[tgt].actv_flags |=
(sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
- isp_prt(isp, ISP_LOGDEBUG0,
- "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
- chan, tgt, mbs.param[2], mbs.param[3] >> 8,
- mbs.param[3] & 0xff);
+ isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
+ chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
get = 0;
} else {
continue;
@@ -7778,8 +7707,7 @@ isp_read_nvram(ispsoftc_t *isp, int bus)
nvram_data[2] != 'P') {
if (isp->isp_bustype != ISP_BT_SBUS) {
isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
- isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
- nvram_data[0], nvram_data[1], nvram_data[2]);
+ isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
}
retval = -1;
goto out;
@@ -8294,8 +8222,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
ISP2100_NVRAM_TOV(nvram_data));
fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
- isp_prt(isp, ISP_LOGDEBUG0,
- "xfwoptions 0x%x zfw options 0x%x",
+ isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 902c827..5f64bcd 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -3950,11 +3950,15 @@ isp_gdt(void *arg)
if (lp->dev_map_idx == 0 || lp->target_mode) {
continue;
}
- if (lp->new_reserved == 0) {
+ /*
+ * We can use new_portid here because it is untouched
+ * while the state is ZOMBIE
+ */
+ if (lp->new_portid == 0) {
continue;
}
- lp->new_reserved -= 1;
- if (lp->new_reserved != 0) {
+ lp->new_portid -= 1;
+ if (lp->new_portid != 0) {
more_to_do++;
continue;
}
@@ -4064,7 +4068,7 @@ isp_kthread(void *arg)
*
* If not, we simply just wait for loop to come up.
*/
- if (lb && (fc->role & ISP_ROLE_INITIATOR)) {
+ if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) {
/*
* Increment loop down time by the last sleep interval
*/
@@ -4932,7 +4936,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
/*
* We don't do any simq freezing if we are only in target mode
*/
- if (fc->role & ISP_ROLE_INITIATOR) {
+ if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
if (fc->path) {
isp_freeze_loopdown(isp, bus, msg);
}
@@ -4968,7 +4972,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
va_end(ap);
fc = ISP_FC_PC(isp, bus);
lp->reserved = 0;
- if ((fc->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
+ if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
int dbidx = lp - FCPARAM(isp, bus)->portdb;
int i;
@@ -5056,10 +5060,13 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
*
* If it isn't marked that isp_gdt is going to get rid of it,
* announce that it's gone.
+ *
+ * We can use new_portid for the gone timer because it's
+ * undefined while the state is ZOMBIE.
*/
if (lp->dev_map_idx && lp->reserved == 0) {
lp->reserved = 1;
- lp->new_reserved = ISP_FC_PC(isp, bus)->gone_device_time;
+ lp->new_portid = ISP_FC_PC(isp, bus)->gone_device_time;
lp->state = FC_PORTDB_STATE_ZOMBIE;
if (fc->ready && !callout_active(&fc->gdt)) {
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d starting Gone Device Timer", bus);
@@ -5106,7 +5113,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
callout_stop(&fc->ldt);
}
isp_prt(isp, ISP_LOGINFO, msg, bus);
- if (fc->role & ISP_ROLE_INITIATOR) {
+ if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
isp_freeze_loopdown(isp, bus, msg);
}
wakeup(fc);
@@ -5425,6 +5432,20 @@ isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
printf("\n");
}
+void
+isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...)
+{
+ va_list ap;
+ if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
+ return;
+ }
+ xpt_print_path(xs->ccb_h.path);
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ printf("\n");
+}
+
uint64_t
isp_nanotime_sub(struct timespec *b, struct timespec *a)
{
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 2942594..44c8bdf 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -175,7 +175,7 @@ struct isp_fc {
simqfrozen : 3,
default_id : 8,
hysteresis : 8,
- role : 2,
+ def_role : 2, /* default role */
gdt_running : 1,
loop_dead : 1,
fcbsy : 1,
@@ -203,7 +203,7 @@ struct isp_spi {
tm_enabled : 1,
#endif
simqfrozen : 3,
- role : 3,
+ def_role : 2,
iid : 4;
#ifdef ISP_TARGET_MODE
struct tslist lun_hash[LUN_HASH_SIZE];
@@ -424,6 +424,8 @@ default: \
imin((sizeof((ccb)->sense_data)), ccb->sense_len)
#define XS_SNSKEY(ccb) ((ccb)->sense_data.flags & 0xf)
+#define XS_SNSASC(ccb) ((ccb)->sense_data.add_sense_code)
+#define XS_SNSASCQ(ccb) ((ccb)->sense_data.add_sense_code_qual)
#define XS_TAG_P(ccb) \
(((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \
(ccb)->tag_action != CAM_TAG_ACTION_NONE)
@@ -461,18 +463,18 @@ default: \
(xs)->ccb_h.status |= CAM_AUTOSNS_VALID; \
memcpy(&(xs)->sense_data, sense_ptr, imin(XS_SNSLEN(xs), sense_len))
-#define XS_SET_STATE_STAT(a, b, c)
+#define XS_SENSE_VALID(xs) (((xs)->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
#define DEFAULT_FRAMESIZE(isp) isp->isp_osinfo.framesize
#define DEFAULT_EXEC_THROTTLE(isp) isp->isp_osinfo.exec_throttle
#define GET_DEFAULT_ROLE(isp, chan) \
- (IS_FC(isp)? ISP_FC_PC(isp, chan)->role : ISP_SPI_PC(isp, chan)->role)
+ (IS_FC(isp)? ISP_FC_PC(isp, chan)->def_role : ISP_SPI_PC(isp, chan)->def_role)
#define SET_DEFAULT_ROLE(isp, chan, val) \
if (IS_FC(isp)) { \
- ISP_FC_PC(isp, chan)->role = val; \
+ ISP_FC_PC(isp, chan)->def_role = val; \
} else { \
- ISP_SPI_PC(isp, chan)->role = val; \
+ ISP_SPI_PC(isp, chan)->def_role = val; \
}
#define DEFAULT_IID(isp, chan) isp->isp_osinfo.pc.spi[chan].iid
@@ -593,6 +595,7 @@ extern int isp_autoconfig;
* Platform Library Functions
*/
void isp_prt(ispsoftc_t *, int level, const char *, ...) __printflike(3, 4);
+void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...) __printflike(4, 5);
uint64_t isp_nanotime_sub(struct timespec *, struct timespec *);
int isp_mbox_acquire(ispsoftc_t *);
void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index 43c161d..0201933 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -294,10 +294,10 @@ uint32_t
isp_handle_index(ispsoftc_t *isp, uint32_t handle)
{
if (!ISP_VALID_HANDLE(isp, handle)) {
- return (handle & ISP_HANDLE_CMD_MASK);
- } else {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (ISP_BAD_HANDLE_INDEX);
+ } else {
+ return (handle & ISP_HANDLE_CMD_MASK);
}
}
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 547f48e..8410ea6 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -547,10 +547,10 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
}
if (IS_SCSI(isp)) {
- ISP_SPI_PC(isp, chan)->role = tval;
+ ISP_SPI_PC(isp, chan)->def_role = tval;
return;
}
- ISP_FC_PC(isp, chan)->role = tval;
+ ISP_FC_PC(isp, chan)->def_role = tval;
tval = 0;
if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fullduplex", &tval) == 0 && tval != 0) {
@@ -833,7 +833,7 @@ isp_pci_attach(device_t dev)
* The 'it' suffix really only matters for SCSI cards in target mode.
*/
isp->isp_osinfo.fw = NULL;
- if (IS_SCSI(isp) && (ISP_SPI_PC(isp, 0)->role & ISP_ROLE_TARGET)) {
+ if (IS_SCSI(isp) && (ISP_SPI_PC(isp, 0)->def_role & ISP_ROLE_TARGET)) {
snprintf(fwname, sizeof (fwname), "isp_%04x_it", did);
isp->isp_osinfo.fw = firmware_get(fwname);
} else if (IS_24XX(isp) && (isp->isp_nchan > 1 || isp->isp_osinfo.forcemulti)) {
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index e2dd78f..895645a 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -195,7 +195,7 @@ isp_sbus_attach(device_t dev)
isp->isp_revision = 0; /* XXX */
isp->isp_dev = dev;
isp->isp_nchan = 1;
- ISP_SET_PC(isp, 0, role, role);
+ ISP_SET_PC(isp, 0, def_role, role);
/*
* Get the clock frequency and convert it from HZ to MHz,
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 5c8508c..e4bf869 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -954,12 +954,13 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
/*
* Platform Dependent Error and Debug Printout
*
- * Generally this is:
+ * Two required functions for each platform must be provided:
*
* void isp_prt(ispsoftc_t *, int level, const char *, ...)
+ * void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...)
*
* but due to compiler differences on different platforms this won't be
- * formally done here. Instead, it goes in each platform definition file.
+ * formally defined here. Instead, they go in each platform definition file.
*/
#define ISP_LOGALL 0x0 /* log always */
@@ -972,6 +973,7 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
#define ISP_LOGDEBUG2 0x40 /* log most debug messages */
#define ISP_LOGDEBUG3 0x80 /* log high frequency debug messages */
#define ISP_LOGSANCFG 0x100 /* log SAN configuration */
+#define ISP_LOG_CWARN 0x200 /* log SCSI command "warnings" (e.g., check conditions) */
#define ISP_LOGTINFO 0x1000 /* log informational messages (target mode) */
#define ISP_LOGTDEBUG0 0x2000 /* log simple debug messages (target mode) */
#define ISP_LOGTDEBUG1 0x4000 /* log intermediate debug messages (target) */
@@ -1045,6 +1047,8 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
* XS_SNSP(xs) gets a pointer to the associate sense data
* XS_SNSLEN(xs) gets the length of sense data storage
* XS_SNSKEY(xs) dereferences XS_SNSP to get the current stored Sense Key
+ * XS_SNSASC(xs) dereferences XS_SNSP to get the current stored Additional Sense Code
+ * XS_SNSASCQ(xs) dereferences XS_SNSP to get the current stored Additional Sense Code Qualifier
* XS_TAG_P(xs) predicate of whether this command should be tagged
* XS_TAG_TYPE(xs) which type of tag to use
* XS_SETERR(xs) set error state
@@ -1065,6 +1069,8 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
*
* XS_SAVE_SENSE(xs, sp, len) save sense data
*
+ * XS_SENSE_VALID(xs) indicates whether sense is valid
+ *
* DEFAULT_FRAMESIZE(ispsoftc_t *) Default Frame Size
* DEFAULT_EXEC_THROTTLE(ispsoftc_t *) Default Execution Throttle
*
diff --git a/sys/dev/ispfw/ispfw.c b/sys/dev/ispfw/ispfw.c
index 9fe8031..b351aee 100644
--- a/sys/dev/ispfw/ispfw.c
+++ b/sys/dev/ispfw/ispfw.c
@@ -142,6 +142,13 @@ static int isp_2500_multi_loaded;
#endif
#define ISPFW_VERSION 1
+
+#if !defined(KLD_MODULE)
+#define ISPFW_KLD 0
+#else
+#define ISPFW_KLD 1
+#endif
+
#define RMACRO(token) do { \
if (token##_loaded) \
break; \
@@ -153,7 +160,9 @@ static int isp_2500_multi_loaded;
break; \
} \
token##_loaded++; \
- printf("%s: registered firmware <%s>\n", MODULE_NAME, #token); \
+ if (bootverbose || ISPFW_KLD) \
+ printf("%s: registered firmware <%s>\n", MODULE_NAME, \
+ #token); \
} while (0)
#define UMACRO(token) do { \
@@ -165,7 +174,9 @@ static int isp_2500_multi_loaded;
break; \
} \
token##_loaded--; \
- printf("%s: unregistered firmware <%s>\n", MODULE_NAME, #token);\
+ if (bootverbose || ISPFW_KLD) \
+ printf("%s: unregistered firmware <%s>\n", MODULE_NAME, \
+ #token); \
} while (0)
static void
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index b6af7b8..09c1efd 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -65,166 +65,193 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip.h>
#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/iwn/if_iwnreg.h>
#include <dev/iwn/if_iwnvar.h>
static int iwn_probe(device_t);
static int iwn_attach(device_t);
-const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
-void iwn_radiotap_attach(struct iwn_softc *);
+static const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
+static void iwn_radiotap_attach(struct iwn_softc *);
static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
const char name[IFNAMSIZ], int unit, int opmode,
int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN]);
static void iwn_vap_delete(struct ieee80211vap *);
static int iwn_cleanup(device_t);
-static int iwn_detach(device_t);
-int iwn_nic_lock(struct iwn_softc *);
-int iwn_eeprom_lock(struct iwn_softc *);
-int iwn_init_otprom(struct iwn_softc *);
-int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
+static int iwn_detach(device_t);
+static int iwn_nic_lock(struct iwn_softc *);
+static int iwn_eeprom_lock(struct iwn_softc *);
+static int iwn_init_otprom(struct iwn_softc *);
+static int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
+static void iwn_dma_map_addr(void *, bus_dma_segment_t *, int, int);
static int iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
void **, bus_size_t, bus_size_t, int);
static void iwn_dma_contig_free(struct iwn_dma_info *);
-int iwn_alloc_sched(struct iwn_softc *);
-void iwn_free_sched(struct iwn_softc *);
-int iwn_alloc_kw(struct iwn_softc *);
-void iwn_free_kw(struct iwn_softc *);
-int iwn_alloc_ict(struct iwn_softc *);
-void iwn_free_ict(struct iwn_softc *);
-int iwn_alloc_fwmem(struct iwn_softc *);
-void iwn_free_fwmem(struct iwn_softc *);
-int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
-void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
-void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
-int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
+static int iwn_alloc_sched(struct iwn_softc *);
+static void iwn_free_sched(struct iwn_softc *);
+static int iwn_alloc_kw(struct iwn_softc *);
+static void iwn_free_kw(struct iwn_softc *);
+static int iwn_alloc_ict(struct iwn_softc *);
+static void iwn_free_ict(struct iwn_softc *);
+static int iwn_alloc_fwmem(struct iwn_softc *);
+static void iwn_free_fwmem(struct iwn_softc *);
+static int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
+static void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
+static void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
+static int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
int);
-void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
-void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
-void iwn5000_ict_reset(struct iwn_softc *);
-int iwn_read_eeprom(struct iwn_softc *,
+static void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
+static void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
+static void iwn5000_ict_reset(struct iwn_softc *);
+static int iwn_read_eeprom(struct iwn_softc *,
uint8_t macaddr[IEEE80211_ADDR_LEN]);
-void iwn4965_read_eeprom(struct iwn_softc *);
-void iwn4965_print_power_group(struct iwn_softc *, int);
-void iwn5000_read_eeprom(struct iwn_softc *);
+static void iwn4965_read_eeprom(struct iwn_softc *);
+static void iwn4965_print_power_group(struct iwn_softc *, int);
+static void iwn5000_read_eeprom(struct iwn_softc *);
+static uint32_t iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
+static void iwn_read_eeprom_band(struct iwn_softc *, int);
+#if 0 /* HT */
+static void iwn_read_eeprom_ht40(struct iwn_softc *, int);
+#endif
static void iwn_read_eeprom_channels(struct iwn_softc *, int,
uint32_t);
-void iwn_read_eeprom_enhinfo(struct iwn_softc *);
-struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
+static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
+static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
-void iwn_newassoc(struct ieee80211_node *, int);
-int iwn_media_change(struct ifnet *);
-int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
+static void iwn_newassoc(struct ieee80211_node *, int);
+static int iwn_media_change(struct ifnet *);
+static int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
+static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
static void iwn_timer_timeout(void *);
static void iwn_calib_reset(struct iwn_softc *);
-void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
+static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
#if 0 /* HT */
-void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
+static void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
#endif
-void iwn5000_rx_calib_results(struct iwn_softc *,
+static void iwn5000_rx_calib_results(struct iwn_softc *,
struct iwn_rx_desc *, struct iwn_rx_data *);
-void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
+static void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
-void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
+static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
-void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
+static void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
-void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
+static void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
uint8_t);
-void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
-void iwn_notif_intr(struct iwn_softc *);
-void iwn_wakeup_intr(struct iwn_softc *);
-void iwn_rftoggle_intr(struct iwn_softc *);
-void iwn_fatal_intr(struct iwn_softc *);
-void iwn_intr(void *);
-void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
+static void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
+static void iwn_notif_intr(struct iwn_softc *);
+static void iwn_wakeup_intr(struct iwn_softc *);
+static void iwn_rftoggle_intr(struct iwn_softc *);
+static void iwn_fatal_intr(struct iwn_softc *);
+static void iwn_intr(void *);
+static void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
uint16_t);
-void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
+static void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
uint16_t);
-void iwn5000_reset_sched(struct iwn_softc *, int, int);
-int iwn_tx_data(struct iwn_softc *, struct mbuf *,
+#ifdef notyet
+static void iwn5000_reset_sched(struct iwn_softc *, int, int);
+#endif
+static uint8_t iwn_plcp_signal(int);
+static int iwn_tx_data(struct iwn_softc *, struct mbuf *,
struct ieee80211_node *, struct iwn_tx_ring *);
static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-void iwn_start(struct ifnet *);
-void iwn_start_locked(struct ifnet *);
+static void iwn_start(struct ifnet *);
+static void iwn_start_locked(struct ifnet *);
static void iwn_watchdog(struct iwn_softc *sc);
-int iwn_ioctl(struct ifnet *, u_long, caddr_t);
-int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
-int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
+static int iwn_ioctl(struct ifnet *, u_long, caddr_t);
+static int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
+static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
int);
-int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
+static int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
int);
-int iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
-int iwn_add_broadcast_node(struct iwn_softc *, int);
-int iwn_wme_update(struct ieee80211com *);
+static int iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
+static int iwn_add_broadcast_node(struct iwn_softc *, int);
+static int iwn_wme_update(struct ieee80211com *);
static void iwn_update_mcast(struct ifnet *);
-void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
-int iwn_set_critical_temp(struct iwn_softc *);
-int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
-void iwn4965_power_calibration(struct iwn_softc *, int);
-int iwn4965_set_txpower(struct iwn_softc *,
+static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
+static int iwn_set_critical_temp(struct iwn_softc *);
+static int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
+static void iwn4965_power_calibration(struct iwn_softc *, int);
+static int iwn4965_set_txpower(struct iwn_softc *,
struct ieee80211_channel *, int);
-int iwn5000_set_txpower(struct iwn_softc *,
+static int iwn5000_set_txpower(struct iwn_softc *,
struct ieee80211_channel *, int);
-int iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
-int iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
-int iwn_get_noise(const struct iwn_rx_general_stats *);
-int iwn4965_get_temperature(struct iwn_softc *);
-int iwn5000_get_temperature(struct iwn_softc *);
-int iwn_init_sensitivity(struct iwn_softc *);
-void iwn_collect_noise(struct iwn_softc *,
+static int iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
+static int iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
+static int iwn_get_noise(const struct iwn_rx_general_stats *);
+static int iwn4965_get_temperature(struct iwn_softc *);
+static int iwn5000_get_temperature(struct iwn_softc *);
+static int iwn_init_sensitivity(struct iwn_softc *);
+static void iwn_collect_noise(struct iwn_softc *,
const struct iwn_rx_general_stats *);
-int iwn4965_init_gains(struct iwn_softc *);
-int iwn5000_init_gains(struct iwn_softc *);
-int iwn4965_set_gains(struct iwn_softc *);
-int iwn5000_set_gains(struct iwn_softc *);
-void iwn_tune_sensitivity(struct iwn_softc *,
+static int iwn4965_init_gains(struct iwn_softc *);
+static int iwn5000_init_gains(struct iwn_softc *);
+static int iwn4965_set_gains(struct iwn_softc *);
+static int iwn5000_set_gains(struct iwn_softc *);
+static void iwn_tune_sensitivity(struct iwn_softc *,
const struct iwn_rx_stats *);
-int iwn_send_sensitivity(struct iwn_softc *);
-int iwn_set_pslevel(struct iwn_softc *, int, int, int);
-int iwn_config(struct iwn_softc *);
-int iwn_scan(struct iwn_softc *);
-int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
-int iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
-int iwn5000_query_calibration(struct iwn_softc *);
-int iwn5000_send_calibration(struct iwn_softc *);
-int iwn5000_send_wimax_coex(struct iwn_softc *);
-int iwn4965_post_alive(struct iwn_softc *);
-int iwn5000_post_alive(struct iwn_softc *);
-int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
+static int iwn_send_sensitivity(struct iwn_softc *);
+static int iwn_set_pslevel(struct iwn_softc *, int, int, int);
+static int iwn_config(struct iwn_softc *);
+static int iwn_scan(struct iwn_softc *);
+static int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
+static int iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
+#if 0 /* HT */
+static int iwn_ampdu_rx_start(struct ieee80211com *,
+ struct ieee80211_node *, uint8_t);
+static void iwn_ampdu_rx_stop(struct ieee80211com *,
+ struct ieee80211_node *, uint8_t);
+static int iwn_ampdu_tx_start(struct ieee80211com *,
+ struct ieee80211_node *, uint8_t);
+static void iwn_ampdu_tx_stop(struct ieee80211com *,
+ struct ieee80211_node *, uint8_t);
+static void iwn4965_ampdu_tx_start(struct iwn_softc *,
+ struct ieee80211_node *, uint8_t, uint16_t);
+static void iwn4965_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
+static void iwn5000_ampdu_tx_start(struct iwn_softc *,
+ struct ieee80211_node *, uint8_t, uint16_t);
+static void iwn5000_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
+#endif
+static int iwn5000_query_calibration(struct iwn_softc *);
+static int iwn5000_send_calibration(struct iwn_softc *);
+static int iwn5000_send_wimax_coex(struct iwn_softc *);
+static int iwn4965_post_alive(struct iwn_softc *);
+static int iwn5000_post_alive(struct iwn_softc *);
+static int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
int);
-int iwn4965_load_firmware(struct iwn_softc *);
-int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
+static int iwn4965_load_firmware(struct iwn_softc *);
+static int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
const uint8_t *, int);
-int iwn5000_load_firmware(struct iwn_softc *);
-int iwn_read_firmware(struct iwn_softc *);
-int iwn_clock_wait(struct iwn_softc *);
-int iwn_apm_init(struct iwn_softc *);
-void iwn_apm_stop_master(struct iwn_softc *);
-void iwn_apm_stop(struct iwn_softc *);
-int iwn4965_nic_config(struct iwn_softc *);
-int iwn5000_nic_config(struct iwn_softc *);
-int iwn_hw_prepare(struct iwn_softc *);
-int iwn_hw_init(struct iwn_softc *);
-void iwn_hw_stop(struct iwn_softc *);
-void iwn_init_locked(struct iwn_softc *);
-void iwn_init(void *);
-void iwn_stop_locked(struct iwn_softc *);
-void iwn_stop(struct iwn_softc *);
+static int iwn5000_load_firmware(struct iwn_softc *);
+static int iwn_read_firmware(struct iwn_softc *);
+static int iwn_clock_wait(struct iwn_softc *);
+static int iwn_apm_init(struct iwn_softc *);
+static void iwn_apm_stop_master(struct iwn_softc *);
+static void iwn_apm_stop(struct iwn_softc *);
+static int iwn4965_nic_config(struct iwn_softc *);
+static int iwn5000_nic_config(struct iwn_softc *);
+static int iwn_hw_prepare(struct iwn_softc *);
+static int iwn_hw_init(struct iwn_softc *);
+static void iwn_hw_stop(struct iwn_softc *);
+static void iwn_init_locked(struct iwn_softc *);
+static void iwn_init(void *);
+static void iwn_stop_locked(struct iwn_softc *);
+static void iwn_stop(struct iwn_softc *);
static void iwn_scan_start(struct ieee80211com *);
static void iwn_scan_end(struct ieee80211com *);
static void iwn_set_channel(struct ieee80211com *);
static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
static void iwn_scan_mindwell(struct ieee80211_scan_state *);
+static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
+ struct ieee80211_channel *);
static int iwn_setregdomain(struct ieee80211com *,
struct ieee80211_regdomain *, int,
struct ieee80211_channel []);
@@ -562,12 +589,15 @@ iwn_attach(device_t dev)
#if IWN_RBUF_SIZE == 8192
IEEE80211_HTCAP_AMSDU7935 |
#endif
- IEEE80211_HTCAP_SMPS_DIS |
IEEE80211_HTCAP_CBW20_40 |
IEEE80211_HTCAP_SGI20 |
IEEE80211_HTCAP_SGI40;
if (sc->hw_type != IWN_HW_REV_TYPE_4965)
ic->ic_htcaps |= IEEE80211_HTCAP_GF;
+ if (sc->hw_type == IWN_HW_REV_TYPE_6050)
+ ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN;
+ else
+ ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS;
#endif
/* Read MAC address, channels, etc from EEPROM. */
@@ -643,7 +673,7 @@ fail:
return error;
}
-const struct iwn_hal *
+static const struct iwn_hal *
iwn_hal_attach(struct iwn_softc *sc)
{
sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
@@ -680,7 +710,7 @@ iwn_hal_attach(struct iwn_softc *sc)
break;
case IWN_HW_REV_TYPE_1000:
sc->sc_hal = &iwn5000_hal;
- sc->limits = &iwn5000_sensitivity_limits;
+ sc->limits = &iwn1000_sensitivity_limits;
sc->fwname = "iwn1000fw";
sc->txchainmask = IWN_ANT_A;
sc->rxchainmask = IWN_ANT_AB;
@@ -720,7 +750,7 @@ iwn_hal_attach(struct iwn_softc *sc)
/*
* Attach the interface to 802.11 radiotap.
*/
-void
+static void
iwn_radiotap_attach(struct iwn_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -755,14 +785,9 @@ iwn_vap_create(struct ieee80211com *ic,
ivp->iv_newstate = vap->iv_newstate;
vap->iv_newstate = iwn_newstate;
- ieee80211_amrr_init(&ivp->iv_amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /* ms */);
-
+ ieee80211_ratectl_init(vap);
/* Complete setup. */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status);
ic->ic_opmode = opmode;
return vap;
}
@@ -772,12 +797,12 @@ iwn_vap_delete(struct ieee80211vap *vap)
{
struct iwn_vap *ivp = IWN_VAP(vap);
- ieee80211_amrr_cleanup(&ivp->iv_amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(ivp, M_80211_VAP);
}
-int
+static int
iwn_cleanup(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
@@ -832,7 +857,7 @@ iwn_detach(device_t dev)
return 0;
}
-int
+static int
iwn_nic_lock(struct iwn_softc *sc)
{
int ntries;
@@ -843,7 +868,7 @@ iwn_nic_lock(struct iwn_softc *sc)
/* Spin until we actually get the lock. */
for (ntries = 0; ntries < 1000; ntries++) {
if ((IWN_READ(sc, IWN_GP_CNTRL) &
- (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
+ (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
IWN_GP_CNTRL_MAC_ACCESS_ENA)
return 0;
DELAY(10);
@@ -938,7 +963,7 @@ iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
iwn_mem_write(sc, addr, val);
}
-int
+static int
iwn_eeprom_lock(struct iwn_softc *sc)
{
int i, ntries;
@@ -969,7 +994,7 @@ iwn_eeprom_unlock(struct iwn_softc *sc)
* Initialize access by host to One Time Programmable ROM.
* NB: This kind of ROM can be found on 1000 or 6000 Series only.
*/
-int
+static int
iwn_init_otprom(struct iwn_softc *sc)
{
uint16_t prev, base, next;
@@ -1023,7 +1048,7 @@ iwn_init_otprom(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
{
uint32_t val, tmp;
@@ -1096,8 +1121,7 @@ iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
flags | BUS_DMA_ZERO, &dma->map);
if (error != 0) {
device_printf(sc->sc_dev,
- "%s: bus_dmamem_alloc failed, error %d\n",
- __func__, error);
+ "%s: bus_dmamem_alloc failed, error %d\n", __func__, error);
goto fail;
}
error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
@@ -1116,7 +1140,7 @@ fail:
return error;
}
-void
+static void
iwn_dma_contig_free(struct iwn_dma_info *dma)
{
if (dma->tag != NULL) {
@@ -1132,7 +1156,7 @@ iwn_dma_contig_free(struct iwn_dma_info *dma)
}
}
-int
+static int
iwn_alloc_sched(struct iwn_softc *sc)
{
/* TX scheduler rings must be aligned on a 1KB boundary. */
@@ -1140,13 +1164,13 @@ iwn_alloc_sched(struct iwn_softc *sc)
(void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);
}
-void
+static void
iwn_free_sched(struct iwn_softc *sc)
{
iwn_dma_contig_free(&sc->sched_dma);
}
-int
+static int
iwn_alloc_kw(struct iwn_softc *sc)
{
/* "Keep Warm" page must be aligned on a 4KB boundary. */
@@ -1154,13 +1178,13 @@ iwn_alloc_kw(struct iwn_softc *sc)
BUS_DMA_NOWAIT);
}
-void
+static void
iwn_free_kw(struct iwn_softc *sc)
{
iwn_dma_contig_free(&sc->kw_dma);
}
-int
+static int
iwn_alloc_ict(struct iwn_softc *sc)
{
/* ICT table must be aligned on a 4KB boundary. */
@@ -1168,13 +1192,13 @@ iwn_alloc_ict(struct iwn_softc *sc)
(void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);
}
-void
+static void
iwn_free_ict(struct iwn_softc *sc)
{
iwn_dma_contig_free(&sc->ict_dma);
}
-int
+static int
iwn_alloc_fwmem(struct iwn_softc *sc)
{
/* Must be aligned on a 16-byte boundary. */
@@ -1182,13 +1206,13 @@ iwn_alloc_fwmem(struct iwn_softc *sc)
sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
}
-void
+static void
iwn_free_fwmem(struct iwn_softc *sc)
{
iwn_dma_contig_free(&sc->fw_dma);
}
-int
+static int
iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
{
bus_size_t size;
@@ -1247,7 +1271,7 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
if (data->m == NULL) {
device_printf(sc->sc_dev,
- "%s: could not allocate rx mbuf\n", __func__);
+ "%s: could not allocate rx mbuf\n", __func__);
error = ENOMEM;
goto fail;
}
@@ -1278,7 +1302,7 @@ fail:
return error;
}
-void
+static void
iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
{
int ntries;
@@ -1302,7 +1326,7 @@ iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
sc->last_rx_valid = 0;
}
-void
+static void
iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
{
int i;
@@ -1324,7 +1348,7 @@ iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
}
}
-int
+static int
iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
{
bus_size_t size;
@@ -1398,7 +1422,7 @@ fail:
return error;
}
-void
+static void
iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
{
int i;
@@ -1421,7 +1445,7 @@ iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
ring->cur = 0;
}
-void
+static void
iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
{
int i;
@@ -1443,7 +1467,7 @@ iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
}
}
-void
+static void
iwn5000_ict_reset(struct iwn_softc *sc)
{
/* Disable interrupts. */
@@ -1468,7 +1492,7 @@ iwn5000_ict_reset(struct iwn_softc *sc)
IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
}
-int
+static int
iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -1529,7 +1553,7 @@ iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
return 0;
}
-void
+static void
iwn4965_read_eeprom(struct iwn_softc *sc)
{
uint32_t addr;
@@ -1577,7 +1601,7 @@ iwn4965_read_eeprom(struct iwn_softc *sc)
}
#ifdef IWN_DEBUG
-void
+static void
iwn4965_print_power_group(struct iwn_softc *sc, int i)
{
struct iwn4965_eeprom_band *band = &sc->bands[i];
@@ -1611,9 +1635,10 @@ iwn4965_print_power_group(struct iwn_softc *sc, int i)
}
#endif
-void
+static void
iwn5000_read_eeprom(struct iwn_softc *sc)
{
+ struct iwn5000_eeprom_calib_hdr hdr;
int32_t temp, volt;
uint32_t addr, base;
int i;
@@ -1637,6 +1662,12 @@ iwn5000_read_eeprom(struct iwn_softc *sc)
iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
base = le16toh(val);
+ iwn_read_prom_data(sc, base, &hdr, sizeof hdr);
+ DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+ "%s: calib version=%u pa type=%u voltage=%u\n",
+ __func__, hdr.version, hdr.pa_type, le16toh(hdr.volt));
+ sc->calib_ver = hdr.version;
+
if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
/* Compute temperature offset. */
iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
@@ -1706,6 +1737,10 @@ iwn_read_eeprom_band(struct iwn_softc *sc, int n)
c->ic_ieee = chan;
c->ic_maxregpower = channels[i].maxpwr;
c->ic_maxpower = 2*c->ic_maxregpower;
+
+ /* Save maximum allowed TX power for this channel. */
+ sc->maxpwr[chan] = channels[i].maxpwr;
+
if (n == 0) { /* 2GHz band */
c->ic_freq = ieee80211_ieee2mhz(chan,
IEEE80211_CHAN_G);
@@ -1812,7 +1847,7 @@ iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
-void
+static void
iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
{
struct iwn_eeprom_enhinfo enhinfo[35];
@@ -1849,23 +1884,20 @@ iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
}
}
-struct ieee80211_node *
+static struct ieee80211_node *
iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
{
return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
}
-void
+static void
iwn_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
- struct iwn_node *wn = (void *)ni;
-
- ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
- &wn->amn, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
-int
+static int
iwn_media_change(struct ifnet *ifp)
{
int error = ieee80211_media_change(ifp);
@@ -1873,7 +1905,7 @@ iwn_media_change(struct ifnet *ifp)
return (error == ENETRESET ? 0 : error);
}
-int
+static int
iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct iwn_vap *ivp = IWN_VAP(vap);
@@ -1920,7 +1952,7 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* Process an RX_PHY firmware notification. This is usually immediately
* followed by an MPDU_RX_DONE notification.
*/
-void
+static void
iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
@@ -1964,7 +1996,7 @@ iwn_calib_reset(struct iwn_softc *sc)
* Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
* Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
*/
-void
+static void
iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
@@ -2114,7 +2146,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
#if 0 /* HT */
/* Process an incoming Compressed BlockAck. */
-void
+static void
iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
@@ -2130,7 +2162,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
* Process a CALIBRATION_RESULT notification sent by the initialization
* firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
*/
-void
+static void
iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
@@ -2146,7 +2178,8 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
switch (calib->code) {
case IWN5000_PHY_CALIB_DC:
- if (sc->hw_type == IWN_HW_REV_TYPE_5150)
+ if (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
+ sc->hw_type == IWN_HW_REV_TYPE_6050)
idx = 0;
break;
case IWN5000_PHY_CALIB_LO:
@@ -2187,7 +2220,7 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
* Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
* The latter is sent by the firmware after each received beacon.
*/
-void
+static void
iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
@@ -2244,11 +2277,12 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
* Process a TX_DONE firmware notification. Unfortunately, the 4965AGN
* and 5000 adapters have different incompatible TX status formats.
*/
-void
+static void
iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
+ struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
"qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
@@ -2256,15 +2290,16 @@ iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
stat->btkillcnt, stat->rate, le16toh(stat->duration),
le32toh(stat->status));
- bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
iwn_tx_done(sc, desc, stat->ackfailcnt, le32toh(stat->status) & 0xff);
}
-void
+static void
iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
+ struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
"qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
@@ -2277,23 +2312,23 @@ iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
#endif
- bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
iwn_tx_done(sc, desc, stat->ackfailcnt, le16toh(stat->status) & 0xff);
}
/*
* Adapter-independent backend for TX_DONE firmware notifications.
*/
-void
+static void
iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
uint8_t status)
{
struct ifnet *ifp = sc->sc_ifp;
struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
struct iwn_tx_data *data = &ring->data[desc->idx];
- struct iwn_node *wn = (void *)data->ni;
struct mbuf *m;
struct ieee80211_node *ni;
+ struct ieee80211vap *vap;
KASSERT(data->ni != NULL, ("no node"));
@@ -2302,6 +2337,7 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
bus_dmamap_unload(ring->data_dmat, data->map);
m = data->m, data->m = NULL;
ni = data->ni, data->ni = NULL;
+ vap = ni->ni_vap;
if (m->m_flags & M_TXCB) {
/*
@@ -2331,11 +2367,11 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
*/
if (status & 0x80) {
ifp->if_oerrors++;
- ieee80211_amrr_tx_complete(&wn->amn,
- IEEE80211_AMRR_FAILURE, ackfailcnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
} else {
- ieee80211_amrr_tx_complete(&wn->amn,
- IEEE80211_AMRR_SUCCESS, ackfailcnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
}
m_freem(m);
ieee80211_free_node(ni);
@@ -2355,7 +2391,7 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
* Process a "command done" firmware notification. This is where we wakeup
* processes waiting for a synchronous command completion.
*/
-void
+static void
iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
{
struct iwn_tx_ring *ring = &sc->txq[4];
@@ -2378,7 +2414,7 @@ iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
/*
* Process an INT_FH_RX or INT_SW_RX interrupt.
*/
-void
+static void
iwn_notif_intr(struct iwn_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -2556,7 +2592,7 @@ iwn_notif_intr(struct iwn_softc *sc)
* Process an INT_WAKEUP interrupt raised when the microcontroller wakes up
* from power-down sleep mode.
*/
-void
+static void
iwn_wakeup_intr(struct iwn_softc *sc)
{
int qid;
@@ -2572,7 +2608,7 @@ iwn_wakeup_intr(struct iwn_softc *sc)
}
}
-void
+static void
iwn_rftoggle_intr(struct iwn_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -2594,7 +2630,7 @@ iwn_rftoggle_intr(struct iwn_softc *sc)
* we can't debug the firmware because it is neither open source nor free, it
* can help us to identify certain classes of problems.
*/
-void
+static void
iwn_fatal_intr(struct iwn_softc *sc)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -2654,7 +2690,7 @@ iwn_fatal_intr(struct iwn_softc *sc)
printf(" rx ring: cur=%d\n", sc->rxq.cur);
}
-void
+static void
iwn_intr(void *arg)
{
struct iwn_softc *sc = arg;
@@ -2675,8 +2711,10 @@ iwn_intr(void *arg)
sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT;
}
tmp = le32toh(tmp);
- if (tmp == 0xffffffff)
- tmp = 0; /* Shouldn't happen. */
+ if (tmp == 0xffffffff) /* Shouldn't happen. */
+ tmp = 0;
+ else if (tmp & 0xc0000) /* Workaround a HW bug. */
+ tmp |= 0x8000;
r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
r2 = 0; /* Unused. */
} else {
@@ -2750,7 +2788,7 @@ done:
* Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
* 5000 adapters use a slightly different format.)
*/
-void
+static void
iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
uint16_t len)
{
@@ -2766,7 +2804,7 @@ iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
}
}
-void
+static void
iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
uint16_t len)
{
@@ -2783,7 +2821,8 @@ iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
}
}
-void
+#ifdef notyet
+static void
iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
{
uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
@@ -2794,9 +2833,10 @@ iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
if (idx < IWN_SCHED_WINSZ) {
*(w + IWN_TX_RING_COUNT) = *w;
bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
- BUS_DMASYNC_PREWRITE);
+ BUS_DMASYNC_PREWRITE);
}
}
+#endif
static uint8_t
iwn_plcp_signal(int rate) {
@@ -2810,7 +2850,7 @@ iwn_plcp_signal(int rate) {
return 0;
}
-int
+static int
iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
struct iwn_tx_ring *ring)
{
@@ -2851,7 +2891,8 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else {
- (void) ieee80211_amrr_choose(ni, &wn->amn);
+ /* XXX pass pktlen */
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
ridx = iwn_plcp_signal(rate);
@@ -3001,7 +3042,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
if (error != 0) {
device_printf(sc->sc_dev,
"%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
- __func__, error);
+ __func__, error);
m_freem(m);
return error;
}
@@ -3196,7 +3237,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
if (error != 0) {
device_printf(sc->sc_dev,
"%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
- __func__, error);
+ __func__, error);
m_freem(m);
return error;
}
@@ -3287,7 +3328,7 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return error;
}
-void
+static void
iwn_start(struct ifnet *ifp)
{
struct iwn_softc *sc = ifp->if_softc;
@@ -3297,7 +3338,7 @@ iwn_start(struct ifnet *ifp)
IWN_UNLOCK(sc);
}
-void
+static void
iwn_start_locked(struct ifnet *ifp)
{
struct iwn_softc *sc = ifp->if_softc;
@@ -3340,7 +3381,7 @@ iwn_watchdog(struct iwn_softc *sc)
}
}
-int
+static int
iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct iwn_softc *sc = ifp->if_softc;
@@ -3386,7 +3427,7 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/*
* Send a command to the firmware.
*/
-int
+static int
iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
{
struct iwn_tx_ring *ring = &sc->txq[4];
@@ -3459,7 +3500,7 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
return async ? 0 : msleep(desc, &sc->sc_mtx, PCATCH, "iwncmd", hz);
}
-int
+static int
iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
{
struct iwn4965_node_info hnode;
@@ -3478,7 +3519,7 @@ iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
return iwn_cmd(sc, IWN_CMD_ADD_NODE, &hnode, sizeof hnode, async);
}
-int
+static int
iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
{
/* Direct mapping. */
@@ -3509,7 +3550,7 @@ static const uint8_t iwn_prev_ridx[] = {
* Configure hardware link parameters for the specified
* node operating on the specified channel.
*/
-int
+static int
iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -3582,7 +3623,7 @@ iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
/*
* Broadcast node is used to send group-addressed and management frames.
*/
-int
+static int
iwn_add_broadcast_node(struct iwn_softc *sc, int async)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -3602,7 +3643,7 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async)
return error;
}
-int
+static int
iwn_wme_update(struct ieee80211com *ic)
{
#define IWN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
@@ -3638,7 +3679,7 @@ iwn_update_mcast(struct ifnet *ifp)
/* Ignore */
}
-void
+static void
iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
{
struct iwn_cmd_led led;
@@ -3657,7 +3698,7 @@ iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
* Set the critical temperature at which the firmware will stop the radio
* and notify us.
*/
-int
+static int
iwn_set_critical_temp(struct iwn_softc *sc)
{
struct iwn_critical_temp crit;
@@ -3678,7 +3719,7 @@ iwn_set_critical_temp(struct iwn_softc *sc)
return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
}
-int
+static int
iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
{
struct iwn_cmd_timing cmd;
@@ -3700,7 +3741,7 @@ iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
}
-void
+static void
iwn4965_power_calibration(struct iwn_softc *sc, int temp)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -3721,7 +3762,7 @@ iwn4965_power_calibration(struct iwn_softc *sc, int temp)
* This function takes into account the regulatory information from EEPROM,
* the current temperature and the current voltage.
*/
-int
+static int
iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
int async)
{
@@ -3873,7 +3914,7 @@ iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
#undef fdivround
}
-int
+static int
iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
int async)
{
@@ -3894,7 +3935,7 @@ iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
/*
* Retrieve the maximum RSSI (in dBm) among receivers.
*/
-int
+static int
iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
{
struct iwn4965_rx_phystat *phy = (void *)stat->phybuf;
@@ -3925,7 +3966,7 @@ iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
return rssi - agc - IWN_RSSI_TO_DBM;
}
-int
+static int
iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
{
struct iwn5000_rx_phystat *phy = (void *)stat->phybuf;
@@ -3948,7 +3989,7 @@ iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
/*
* Retrieve the average noise (in dBm) among receivers.
*/
-int
+static int
iwn_get_noise(const struct iwn_rx_general_stats *stats)
{
int i, total, nbant, noise;
@@ -3967,7 +4008,7 @@ iwn_get_noise(const struct iwn_rx_general_stats *stats)
/*
* Compute temperature (in degC) from last received statistics.
*/
-int
+static int
iwn4965_get_temperature(struct iwn_softc *sc)
{
struct iwn_ucode_info *uc = &sc->ucode_info;
@@ -3992,7 +4033,7 @@ iwn4965_get_temperature(struct iwn_softc *sc)
return IWN_KTOC(temp);
}
-int
+static int
iwn5000_get_temperature(struct iwn_softc *sc)
{
int32_t temp;
@@ -4013,7 +4054,7 @@ iwn5000_get_temperature(struct iwn_softc *sc)
/*
* Initialize sensitivity calibration state machine.
*/
-int
+static int
iwn_init_sensitivity(struct iwn_softc *sc)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -4028,7 +4069,7 @@ iwn_init_sensitivity(struct iwn_softc *sc)
/* Set initial correlation values. */
calib->ofdm_x1 = sc->limits->min_ofdm_x1;
calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1;
- calib->ofdm_x4 = 90;
+ calib->ofdm_x4 = sc->limits->min_ofdm_x4;
calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4;
calib->cck_x4 = 125;
calib->cck_mrc_x4 = sc->limits->min_cck_mrc_x4;
@@ -4055,7 +4096,7 @@ iwn_init_sensitivity(struct iwn_softc *sc)
* after association and use them to determine connected antennas and
* to set differential gains.
*/
-void
+static void
iwn_collect_noise(struct iwn_softc *sc,
const struct iwn_rx_general_stats *stats)
{
@@ -4103,7 +4144,7 @@ iwn_collect_noise(struct iwn_softc *sc,
#endif
}
-int
+static int
iwn4965_init_gains(struct iwn_softc *sc)
{
struct iwn_phy_calib_gain cmd;
@@ -4116,14 +4157,11 @@ iwn4965_init_gains(struct iwn_softc *sc)
return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
}
-int
+static int
iwn5000_init_gains(struct iwn_softc *sc)
{
struct iwn_phy_calib cmd;
- if (sc->hw_type == IWN_HW_REV_TYPE_6050)
- return 0;
-
memset(&cmd, 0, sizeof cmd);
cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
cmd.ngroups = 1;
@@ -4133,7 +4171,7 @@ iwn5000_init_gains(struct iwn_softc *sc)
return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
}
-int
+static int
iwn4965_set_gains(struct iwn_softc *sc)
{
struct iwn_calib_state *calib = &sc->calib;
@@ -4166,15 +4204,15 @@ iwn4965_set_gains(struct iwn_softc *sc)
return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
}
-int
+static int
iwn5000_set_gains(struct iwn_softc *sc)
{
struct iwn_calib_state *calib = &sc->calib;
struct iwn_phy_calib_gain cmd;
- int i, ant, delta;
+ int i, ant, delta, div;
- if (sc->hw_type == IWN_HW_REV_TYPE_6050)
- return 0;
+ /* We collected 20 beacons and !=6050 need a 1.5 factor. */
+ div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
memset(&cmd, 0, sizeof cmd);
cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
@@ -4187,7 +4225,7 @@ iwn5000_set_gains(struct iwn_softc *sc)
if (sc->chainmask & (1 << i)) {
/* The delta is relative to antenna "ant". */
delta = ((int32_t)calib->noise[ant] -
- (int32_t)calib->noise[i]) / 30;
+ (int32_t)calib->noise[i]) / div;
/* Limit to [-4.5dB,+4.5dB]. */
cmd.gain[i - 1] = MIN(abs(delta), 3);
if (delta < 0)
@@ -4204,7 +4242,7 @@ iwn5000_set_gains(struct iwn_softc *sc)
* Tune RF RX sensitivity based on the number of false alarms detected
* during the last beacon period.
*/
-void
+static void
iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
{
#define inc(val, inc, max) \
@@ -4331,7 +4369,7 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
if (calib->cck_state != IWN_CCK_STATE_INIT &&
(((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
- calib->low_fa > 100)) {
+ calib->low_fa > 100)) {
inc(calib->energy_cck, 2, limits->min_energy_cck);
dec(calib->cck_x4, 3, limits->min_cck_x4);
dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4);
@@ -4356,7 +4394,7 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
#undef inc
}
-int
+static int
iwn_send_sensitivity(struct iwn_softc *sc)
{
struct iwn_calib_state *calib = &sc->calib;
@@ -4391,7 +4429,7 @@ iwn_send_sensitivity(struct iwn_softc *sc)
* Set STA mode power saving level (between 0 and 5).
* Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
*/
-int
+static int
iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
{
const struct iwn_pmgt *pmgt;
@@ -4442,7 +4480,7 @@ iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
return iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &cmd, sizeof cmd, async);
}
-int
+static int
iwn_config(struct iwn_softc *sc)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -4470,7 +4508,7 @@ iwn_config(struct iwn_softc *sc)
/* Configure bluetooth coexistence. */
memset(&bluetooth, 0, sizeof bluetooth);
- bluetooth.flags = IWN_BT_COEX_MODE_4WIRE;
+ bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO;
bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
@@ -4555,7 +4593,7 @@ iwn_config(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn_scan(struct iwn_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -4726,7 +4764,7 @@ iwn_scan(struct iwn_softc *sc)
return error;
}
-int
+static int
iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -4800,7 +4838,7 @@ iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
/*
* Configure the adapter for associated state.
*/
-int
+static int
iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
{
#define MS(v,x) (((v) & x) >> x##_S)
@@ -4891,7 +4929,6 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
__func__, error);
return error;
}
-
/* Configuration has changed, set TX power accordingly. */
error = hal->set_txpower(sc, ni->ni_chan, 1);
@@ -4950,7 +4987,7 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
* This function is called by upper layer when an ADDBA request is received
* from another STA and before the ADDBA response is sent.
*/
-int
+static int
iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
uint8_t tid)
{
@@ -4974,7 +5011,7 @@ iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
* This function is called by upper layer on teardown of an HT-immediate
* Block Ack agreement (eg. uppon receipt of a DELBA frame.)
*/
-void
+static void
iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
uint8_t tid)
{
@@ -4995,7 +5032,7 @@ iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
* This function is called by upper layer when an ADDBA response is received
* from another STA.
*/
-int
+static int
iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
uint8_t tid)
{
@@ -5024,7 +5061,7 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
return 0;
}
-void
+static void
iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
uint8_t tid)
{
@@ -5039,7 +5076,7 @@ iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
iwn_nic_unlock(sc);
}
-void
+static void
iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
uint8_t tid, uint16_t ssn)
{
@@ -5077,7 +5114,7 @@ iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
iwn_tid2fifo[tid] << 1);
}
-void
+static void
iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
{
int qid = 7 + tid;
@@ -5098,7 +5135,7 @@ iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
}
-void
+static void
iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
uint8_t tid, uint16_t ssn)
{
@@ -5135,7 +5172,7 @@ iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
}
-void
+static void
iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
{
int qid = 10 + tid;
@@ -5164,7 +5201,7 @@ iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
* Query calibration tables from the initialization firmware. We do this
* only once at first boot. Called from a process context.
*/
-int
+static int
iwn5000_query_calibration(struct iwn_softc *sc)
{
struct iwn5000_calib_config cmd;
@@ -5191,7 +5228,7 @@ iwn5000_query_calibration(struct iwn_softc *sc)
* Send calibration results to the runtime firmware. These results were
* obtained on first boot from the initialization firmware.
*/
-int
+static int
iwn5000_send_calibration(struct iwn_softc *sc)
{
int idx, error;
@@ -5214,7 +5251,7 @@ iwn5000_send_calibration(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn5000_send_wimax_coex(struct iwn_softc *sc)
{
struct iwn5000_wimax_coex wimax;
@@ -5245,7 +5282,7 @@ iwn5000_send_wimax_coex(struct iwn_softc *sc)
* This function is called after the runtime firmware notifies us of its
* readiness (called in a process context.)
*/
-int
+static int
iwn4965_post_alive(struct iwn_softc *sc)
{
int error, qid;
@@ -5298,7 +5335,7 @@ iwn4965_post_alive(struct iwn_softc *sc)
* This function is called after the initialization or runtime firmware
* notifies us of its readiness (called in a process context.)
*/
-int
+static int
iwn5000_post_alive(struct iwn_softc *sc)
{
int error, qid;
@@ -5404,7 +5441,7 @@ iwn5000_post_alive(struct iwn_softc *sc)
* The firmware boot code is small and is intended to be copied directly into
* the NIC internal memory (no DMA transfer.)
*/
-int
+static int
iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
{
int error, ntries;
@@ -5447,7 +5484,7 @@ iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
return 0;
}
-int
+static int
iwn4965_load_firmware(struct iwn_softc *sc)
{
struct iwn_fw_info *fw = &sc->fw;
@@ -5518,7 +5555,7 @@ iwn4965_load_firmware(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
const uint8_t *section, int size)
{
@@ -5556,7 +5593,7 @@ iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
}
-int
+static int
iwn5000_load_firmware(struct iwn_softc *sc)
{
struct iwn_fw_part *fw;
@@ -5588,7 +5625,7 @@ iwn5000_load_firmware(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn_read_firmware(struct iwn_softc *sc)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -5604,7 +5641,7 @@ iwn_read_firmware(struct iwn_softc *sc)
if (sc->fw_fp == NULL) {
device_printf(sc->sc_dev,
"%s: could not load firmare image \"%s\"\n", __func__,
- sc->fwname);
+ sc->fwname);
IWN_LOCK(sc);
return EINVAL;
}
@@ -5670,7 +5707,7 @@ iwn_read_firmware(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn_clock_wait(struct iwn_softc *sc)
{
int ntries;
@@ -5689,7 +5726,7 @@ iwn_clock_wait(struct iwn_softc *sc)
return ETIMEDOUT;
}
-int
+static int
iwn_apm_init(struct iwn_softc *sc)
{
uint32_t tmp;
@@ -5747,7 +5784,7 @@ iwn_apm_init(struct iwn_softc *sc)
return 0;
}
-void
+static void
iwn_apm_stop_master(struct iwn_softc *sc)
{
int ntries;
@@ -5763,7 +5800,7 @@ iwn_apm_stop_master(struct iwn_softc *sc)
__func__);
}
-void
+static void
iwn_apm_stop(struct iwn_softc *sc)
{
iwn_apm_stop_master(sc);
@@ -5775,7 +5812,7 @@ iwn_apm_stop(struct iwn_softc *sc)
IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
}
-int
+static int
iwn4965_nic_config(struct iwn_softc *sc)
{
if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
@@ -5794,7 +5831,7 @@ iwn4965_nic_config(struct iwn_softc *sc)
return 0;
}
-int
+static int
iwn5000_nic_config(struct iwn_softc *sc)
{
uint32_t tmp;
@@ -5831,13 +5868,17 @@ iwn5000_nic_config(struct iwn_softc *sc)
/* Use internal power amplifier only. */
IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
}
+ if (sc->hw_type == IWN_HW_REV_TYPE_6050 && sc->calib_ver >= 6) {
+ /* Indicate that ROM calibration version is >=6. */
+ IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6);
+ }
return 0;
}
/*
* Take NIC ownership over Intel Active Management Technology (AMT).
*/
-int
+static int
iwn_hw_prepare(struct iwn_softc *sc)
{
int ntries;
@@ -5873,7 +5914,7 @@ iwn_hw_prepare(struct iwn_softc *sc)
return ETIMEDOUT;
}
-int
+static int
iwn_hw_init(struct iwn_softc *sc)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -5984,7 +6025,7 @@ iwn_hw_init(struct iwn_softc *sc)
return hal->post_alive(sc);
}
-void
+static void
iwn_hw_stop(struct iwn_softc *sc)
{
const struct iwn_hal *hal = sc->sc_hal;
@@ -6038,7 +6079,7 @@ iwn_hw_stop(struct iwn_softc *sc)
iwn_apm_stop(sc);
}
-void
+static void
iwn_init_locked(struct iwn_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -6106,7 +6147,7 @@ fail:
iwn_stop_locked(sc);
}
-void
+static void
iwn_init(void *arg)
{
struct iwn_softc *sc = arg;
@@ -6121,7 +6162,7 @@ iwn_init(void *arg)
ieee80211_start_all(ic);
}
-void
+static void
iwn_stop_locked(struct iwn_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -6136,7 +6177,7 @@ iwn_stop_locked(struct iwn_softc *sc)
iwn_hw_stop(sc);
}
-void
+static void
iwn_stop(struct iwn_softc *sc)
{
IWN_LOCK(sc);
@@ -6434,4 +6475,3 @@ DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
MODULE_DEPEND(iwn, pci, 1, 1, 1);
MODULE_DEPEND(iwn, firmware, 1, 1, 1);
MODULE_DEPEND(iwn, wlan, 1, 1, 1);
-MODULE_DEPEND(iwn, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h
index 0aa7669..06e03ec 100644
--- a/sys/dev/iwn/if_iwnreg.h
+++ b/sys/dev/iwn/if_iwnreg.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: if_iwnreg.h,v 1.34 2009/11/08 11:54:48 damien Exp $ */
+/* $OpenBSD: if_iwnreg.h,v 1.37 2010/02/17 18:23:00 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -216,6 +216,7 @@
#define IWN_GP_DRIVER_RADIO_3X3_HYB (0 << 0)
#define IWN_GP_DRIVER_RADIO_2X2_HYB (1 << 0)
#define IWN_GP_DRIVER_RADIO_2X2_IPA (2 << 0)
+#define IWN_GP_DRIVER_CALIB_VER6 (1 << 2)
/* Possible flags for register IWN_UCODE_GP1_CLR. */
#define IWN_UCODE_GP1_RFKILL (1 << 1)
@@ -832,10 +833,9 @@ struct iwn5000_cmd_txpower {
/* Structure for command IWN_CMD_BLUETOOTH. */
struct iwn_bluetooth {
uint8_t flags;
-#define IWN_BT_COEX_DISABLE 0
-#define IWN_BT_COEX_MODE_2WIRE 1
-#define IWN_BT_COEX_MODE_3WIRE 2
-#define IWN_BT_COEX_MODE_4WIRE 3
+#define IWN_BT_COEX_CHAN_ANN (1 << 0)
+#define IWN_BT_COEX_BT_PRIO (1 << 1)
+#define IWN_BT_COEX_2_WIRE (1 << 2)
uint8_t lead_time;
#define IWN_BT_LEAD_TIME_DEF 30
@@ -1326,6 +1326,12 @@ struct iwn_eeprom_enhinfo {
int8_t mimo3; /* max power in half-dBm */
} __packed;
+struct iwn5000_eeprom_calib_hdr {
+ uint8_t version;
+ uint8_t pa_type;
+ uint16_t volt;
+} __packed;
+
#define IWN_NSAMPLES 3
struct iwn4965_eeprom_chan_samples {
uint8_t num;
@@ -1552,8 +1558,8 @@ static const struct iwn_sensitivity_limits iwn4965_sensitivity_limits = {
};
static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
- 120, 155,
- 240, 290,
+ 120, 120, /* min = max for performance bug in DSP. */
+ 240, 240, /* min = max for performance bug in DSP. */
90, 120,
170, 210,
125, 200,
@@ -1575,8 +1581,20 @@ static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
95
};
+static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {
+ 120, 155,
+ 240, 290,
+ 90, 120,
+ 170, 210,
+ 125, 200,
+ 170, 400,
+ 95,
+ 95,
+ 95
+};
+
static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
- 105, 145,
+ 105, 110,
192, 232,
80, 145,
128, 232,
@@ -1642,7 +1660,7 @@ static const char * const iwn_fw_errmsg[] = {
"DEBUG_1",
"DEBUG_2",
"DEBUG_3",
- "UNKNOWN"
+ "ADVANCED_SYSASSERT"
};
/* Find least significant bit that is set. */
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index 98c9c94..40ce30f 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: if_iwnvar.h,v 1.16 2009/11/04 17:46:52 damien Exp $ */
+/* $OpenBSD: if_iwnvar.h,v 1.17 2010/02/17 18:23:00 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -99,7 +99,6 @@ struct iwn_rx_ring {
struct iwn_node {
struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
uint16_t disable_tid;
uint8_t id;
uint8_t ridx[IEEE80211_RATE_MAXSIZE];
@@ -193,8 +192,6 @@ struct iwn_hal {
struct iwn_vap {
struct ieee80211vap iv_vap;
- struct ieee80211_amrr iv_amrr;
- struct callout iv_amrr_to;
uint8_t iv_ridx;
int (*iv_newstate)(struct ieee80211vap *,
@@ -284,6 +281,7 @@ struct iwn_softc {
bands[IWN_NBANDS];
struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
uint16_t rfcfg;
+ uint8_t calib_ver;
char eeprom_domain[4];
uint32_t eeprom_crystal;
int16_t eeprom_voltage;
diff --git a/sys/dev/ixgbe/LICENSE b/sys/dev/ixgbe/LICENSE
index 39264e0..0cf44c8 100644
--- a/sys/dev/ixgbe/LICENSE
+++ b/sys/dev/ixgbe/LICENSE
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c
index f66443a..9cc392d 100644
--- a/sys/dev/ixgbe/ixgbe.c
+++ b/sys/dev/ixgbe/ixgbe.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.0.7";
+char ixgbe_driver_version[] = "2.1.7";
/*********************************************************************
* PCI Device ID Table
@@ -76,6 +76,7 @@ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] =
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_XAUI_LOM, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_CX4, 0, 0, 0},
+ {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_T3_LOM, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0},
/* required last entry */
{0, 0, 0, 0, 0}
@@ -105,8 +106,8 @@ static int ixgbe_mq_start_locked(struct ifnet *,
static void ixgbe_qflush(struct ifnet *);
#endif
static int ixgbe_ioctl(struct ifnet *, u_long, caddr_t);
-static void ixgbe_init(void *);
-static void ixgbe_init_locked(struct adapter *);
+static void ixgbe_init(void *);
+static int ixgbe_init_locked(struct adapter *);
static void ixgbe_stop(void *);
static void ixgbe_media_status(struct ifnet *, struct ifmediareq *);
static int ixgbe_media_change(struct ifnet *);
@@ -136,20 +137,19 @@ static void ixgbe_free_receive_structures(struct adapter *);
static void ixgbe_free_receive_buffers(struct rx_ring *);
static void ixgbe_setup_hw_rsc(struct rx_ring *);
-static void ixgbe_init_moderation(struct adapter *);
static void ixgbe_enable_intr(struct adapter *);
static void ixgbe_disable_intr(struct adapter *);
static void ixgbe_update_stats_counters(struct adapter *);
static bool ixgbe_txeof(struct tx_ring *);
-static bool ixgbe_rxeof(struct rx_ring *, int);
-static void ixgbe_rx_checksum(u32, struct mbuf *);
+static bool ixgbe_rxeof(struct ix_queue *, int);
+static void ixgbe_rx_checksum(u32, struct mbuf *, u32);
static void ixgbe_set_promisc(struct adapter *);
static void ixgbe_disable_promisc(struct adapter *);
static void ixgbe_set_multi(struct adapter *);
static void ixgbe_print_hw_stats(struct adapter *);
static void ixgbe_print_debug_info(struct adapter *);
static void ixgbe_update_link_status(struct adapter *);
-static int ixgbe_get_buf(struct rx_ring *, int, int);
+static void ixgbe_refresh_mbufs(struct rx_ring *, int);
static int ixgbe_xmit(struct tx_ring *, struct mbuf **);
static int ixgbe_sysctl_stats(SYSCTL_HANDLER_ARGS);
static int ixgbe_sysctl_debug(SYSCTL_HANDLER_ARGS);
@@ -169,7 +169,9 @@ static void ixgbe_setup_vlan_hw_support(struct adapter *);
static void ixgbe_register_vlan(void *, struct ifnet *, u16);
static void ixgbe_unregister_vlan(void *, struct ifnet *, u16);
-static void ixgbe_update_aim(struct rx_ring *);
+static __inline void ixgbe_rx_discard(struct rx_ring *, int);
+static __inline void ixgbe_rx_input(struct rx_ring *, struct ifnet *,
+ struct mbuf *, u32);
/* Support for pluggable optic modules */
static bool ixgbe_sfp_probe(struct adapter *);
@@ -178,13 +180,11 @@ static bool ixgbe_sfp_probe(struct adapter *);
static void ixgbe_legacy_irq(void *);
/* The MSI/X Interrupt handlers */
-static void ixgbe_msix_tx(void *);
-static void ixgbe_msix_rx(void *);
+static void ixgbe_msix_que(void *);
static void ixgbe_msix_link(void *);
/* Deferred interrupt tasklets */
-static void ixgbe_handle_tx(void *, int);
-static void ixgbe_handle_rx(void *, int);
+static void ixgbe_handle_que(void *, int);
static void ixgbe_handle_link(void *, int);
static void ixgbe_handle_msf(void *, int);
static void ixgbe_handle_mod(void *, int);
@@ -222,23 +222,16 @@ MODULE_DEPEND(ixgbe, ether, 1, 1, 1);
*/
/*
-** These parameters are used in Adaptive
-** Interrupt Moderation. The value is set
-** into EITR and controls the interrupt
-** frequency. They can be modified but
-** be careful in tuning them.
+** AIM: Adaptive Interrupt Moderation
+** which means that the interrupt rate
+** is varied over time based on the
+** traffic for that interrupt vector
*/
static int ixgbe_enable_aim = TRUE;
TUNABLE_INT("hw.ixgbe.enable_aim", &ixgbe_enable_aim);
-static int ixgbe_low_latency = IXGBE_LOW_LATENCY;
-TUNABLE_INT("hw.ixgbe.low_latency", &ixgbe_low_latency);
-static int ixgbe_ave_latency = IXGBE_AVE_LATENCY;
-TUNABLE_INT("hw.ixgbe.ave_latency", &ixgbe_ave_latency);
-static int ixgbe_bulk_latency = IXGBE_BULK_LATENCY;
-TUNABLE_INT("hw.ixgbe.bulk_latency", &ixgbe_bulk_latency);
/* How many packets rxeof tries to clean at a time */
-static int ixgbe_rx_process_limit = 100;
+static int ixgbe_rx_process_limit = 128;
TUNABLE_INT("hw.ixgbe.rx_process_limit", &ixgbe_rx_process_limit);
/* Flow control setting, default to full */
@@ -271,20 +264,24 @@ static bool ixgbe_header_split = TRUE;
TUNABLE_INT("hw.ixgbe.hdr_split", &ixgbe_header_split);
/*
- * Number of Queues, should normally
- * be left at 0, it then autoconfigures to
- * the number of cpus. Each queue is a pair
- * of RX and TX rings with a dedicated interrupt
+ * Number of Queues, can be set to 0,
+ * it then autoconfigures based on the
+ * number of cpus. Each queue is a pair
+ * of RX and TX rings with a msix vector
*/
static int ixgbe_num_queues = 0;
TUNABLE_INT("hw.ixgbe.num_queues", &ixgbe_num_queues);
-/* Number of TX descriptors per ring */
-static int ixgbe_txd = DEFAULT_TXD;
+/*
+** Number of TX descriptors per ring,
+** setting higher than RX as this seems
+** the better performing choice.
+*/
+static int ixgbe_txd = PERFORM_TXD;
TUNABLE_INT("hw.ixgbe.txd", &ixgbe_txd);
/* Number of RX descriptors per ring */
-static int ixgbe_rxd = DEFAULT_RXD;
+static int ixgbe_rxd = PERFORM_RXD;
TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd);
/* Keep running tab on them for sanity check */
@@ -420,9 +417,11 @@ ixgbe_attach(device_t dev)
case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM :
case IXGBE_DEV_ID_82598EB_SFP_LOM :
case IXGBE_DEV_ID_82598AT :
- case IXGBE_DEV_ID_82598AT2 :
adapter->optics = IFM_10G_SR;
break;
+ case IXGBE_DEV_ID_82598AT2 :
+ adapter->optics = IFM_10G_T;
+ break;
case IXGBE_DEV_ID_82598EB_XF_LR :
adapter->optics = IFM_10G_LR;
break;
@@ -439,6 +438,10 @@ ixgbe_attach(device_t dev)
case IXGBE_DEV_ID_82599_XAUI_LOM :
case IXGBE_DEV_ID_82599_COMBO_BACKPLANE :
ixgbe_num_segs = IXGBE_82599_SCATTER;
+ break;
+ case IXGBE_DEV_ID_82599_T3_LOM:
+ ixgbe_num_segs = IXGBE_82599_SCATTER;
+ adapter->optics = IFM_10G_T;
default:
break;
}
@@ -464,21 +467,6 @@ ixgbe_attach(device_t dev)
OID_AUTO, "enable_aim", CTLTYPE_INT|CTLFLAG_RW,
&ixgbe_enable_aim, 1, "Interrupt Moderation");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "low_latency", CTLTYPE_INT|CTLFLAG_RW,
- &ixgbe_low_latency, 1, "Low Latency");
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "ave_latency", CTLTYPE_INT|CTLFLAG_RW,
- &ixgbe_ave_latency, 1, "Average Latency");
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "bulk_latency", CTLTYPE_INT|CTLFLAG_RW,
- &ixgbe_bulk_latency, 1, "Bulk Latency");
-
/* Set up the timer callout */
callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
@@ -592,22 +580,6 @@ ixgbe_attach(device_t dev)
/* Setup OS specific network interface */
ixgbe_setup_interface(dev, adapter);
-#ifdef IXGBE_IEEE1588
- /*
- ** Setup the timer: IEEE 1588 support
- */
- adapter->cycles.read = ixgbe_read_clock;
- adapter->cycles.mask = (u64)-1;
- adapter->cycles.mult = 1;
- adapter->cycles.shift = IXGBE_TSYNC_SHIFT;
- IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (1<<24) |
- IXGBE_TSYNC_CYCLE_TIME * IXGBE_TSYNC_SHIFT);
- IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
- IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0xFF800000);
-
- // JFV - this is not complete yet
-#endif
-
/* Sysctl for limiting the amount of work done in the taskqueue */
ixgbe_add_rx_process_limit(adapter, "rx_processing_limit",
"max number of rx packets to process", &adapter->rx_process_limit,
@@ -632,12 +604,13 @@ ixgbe_attach(device_t dev)
(hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
("Unknown"));
- if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
+ if ((hw->bus.width <= ixgbe_bus_width_pcie_x4) &&
+ (hw->bus.speed == ixgbe_bus_speed_2500)) {
device_printf(dev, "PCI-Express bandwidth available"
" for this card\n is not sufficient for"
" optimal performance.\n");
device_printf(dev, "For optimal performance a x8 "
- "PCI-Express slot is required.\n");
+ "PCIE, or x4 PCIE 2 slot is required.\n");
}
/* let hardware know driver is loaded */
@@ -670,8 +643,7 @@ static int
ixgbe_detach(device_t dev)
{
struct adapter *adapter = device_get_softc(dev);
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
+ struct ix_queue *que = adapter->queues;
u32 ctrl_ext;
INIT_DEBUGOUT("ixgbe_detach: begin");
@@ -686,17 +658,10 @@ ixgbe_detach(device_t dev)
ixgbe_stop(adapter);
IXGBE_CORE_UNLOCK(adapter);
- for (int i = 0; i < adapter->num_queues; i++, txr++) {
- if (txr->tq) {
- taskqueue_drain(txr->tq, &txr->tx_task);
- taskqueue_free(txr->tq);
- }
- }
-
- for (int i = 0; i < adapter->num_queues; i++, rxr++) {
- if (rxr->tq) {
- taskqueue_drain(rxr->tq, &rxr->rx_task);
- taskqueue_free(rxr->tq);
+ for (int i = 0; i < adapter->num_queues; i++, que++) {
+ if (que->tq) {
+ taskqueue_drain(que->tq, &que->que_task);
+ taskqueue_free(que->tq);
}
}
@@ -794,6 +759,7 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp)
/* Set watchdog on */
txr->watchdog_check = TRUE;
+ txr->watchdog_time = ticks;
}
return;
@@ -833,6 +799,7 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m)
/* Which queue to use */
if ((m->m_flags & M_FLOWID) != 0)
i = m->m_pkthdr.flowid % adapter->num_queues;
+
txr = &adapter->tx_rings[i];
if (IXGBE_TX_TRYLOCK(txr)) {
@@ -849,59 +816,50 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
{
struct adapter *adapter = txr->adapter;
struct mbuf *next;
- int err = 0;
+ int enqueued, err = 0;
- if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) ||
- (!adapter->link_active)) {
- err = drbr_enqueue(ifp, txr->br, m);
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING || adapter->link_active == 0) {
+ if (m != NULL)
+ err = drbr_enqueue(ifp, txr->br, m);
return (err);
}
- if (m == NULL) /* Called by tasklet */
- goto process;
-
- /* If nothing queued go right to xmit */
- if (!drbr_needs_enqueue(ifp, txr->br)) {
- if ((err = ixgbe_xmit(txr, &m)) != 0) {
- if (m != NULL)
- err = drbr_enqueue(ifp, txr->br, m);
+ enqueued = 0;
+ if (m == NULL) {
+ next = drbr_dequeue(ifp, txr->br);
+ } else if (drbr_needs_enqueue(ifp, txr->br)) {
+ if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
return (err);
- } else {
- /* Success, update stats */
- drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
- /* Send a copy of the frame to the BPF listener */
- ETHER_BPF_MTAP(ifp, m);
- /* Set the watchdog */
- txr->watchdog_check = TRUE;
- }
-
- } else if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
- return (err);
-
-process:
- if (drbr_empty(ifp, txr->br))
- return (err);
+ next = drbr_dequeue(ifp, txr->br);
+ } else
+ next = m;
/* Process the queue */
- while (TRUE) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- break;
- next = drbr_dequeue(ifp, txr->br);
- if (next == NULL)
- break;
+ while (next != NULL) {
if ((err = ixgbe_xmit(txr, &next)) != 0) {
if (next != NULL)
err = drbr_enqueue(ifp, txr->br, next);
break;
}
+ enqueued++;
drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
+ /* Send a copy of the frame to the BPF listener */
ETHER_BPF_MTAP(ifp, next);
- /* Set the watchdog */
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
+ if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+ next = drbr_dequeue(ifp, txr->br);
+ }
+
+ if (enqueued > 0) {
+ /* Set watchdog on */
txr->watchdog_check = TRUE;
+ txr->watchdog_time = ticks;
}
-
- if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (err);
}
@@ -938,8 +896,8 @@ ixgbe_qflush(struct ifnet *ifp)
static int
ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
{
- struct adapter *adapter = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *) data;
+ struct adapter *adapter = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *) data;
int error = 0;
switch (command) {
@@ -953,7 +911,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
ifp->if_mtu = ifr->ifr_mtu;
adapter->max_frame_size =
ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
- ixgbe_init_locked(adapter);
+ error = ixgbe_init_locked(adapter);
IXGBE_CORE_UNLOCK(adapter);
}
break;
@@ -968,7 +926,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
ixgbe_set_promisc(adapter);
}
} else
- ixgbe_init_locked(adapter);
+ error = ixgbe_init_locked(adapter);
} else
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ixgbe_stop(adapter);
@@ -999,26 +957,19 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
ifp->if_capenable ^= IFCAP_HWCSUM;
if (mask & IFCAP_TSO4)
ifp->if_capenable ^= IFCAP_TSO4;
- /* Only allow changing when using header split */
- if ((mask & IFCAP_LRO) && (ixgbe_header_split))
+ if (mask & IFCAP_LRO)
ifp->if_capenable ^= IFCAP_LRO;
if (mask & IFCAP_VLAN_HWTAGGING)
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ixgbe_init(adapter);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ IXGBE_CORE_LOCK(adapter);
+ error = ixgbe_init_locked(adapter);
+ IXGBE_CORE_UNLOCK(adapter);
+ }
VLAN_CAPABILITIES(ifp);
break;
}
-#ifdef IXGBE_IEEE1588
- /*
- ** IOCTL support for Precision Time (IEEE 1588) Support
- */
- case SIOCSHWTSTAMP:
- error = ixgbe_hwtstamp_ioctl(adapter, ifp);
- break;
-#endif
-
default:
IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command);
error = ether_ioctl(ifp, command, data);
@@ -1040,20 +991,24 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
**********************************************************************/
#define IXGBE_MHADD_MFS_SHIFT 16
-static void
+static int
ixgbe_init_locked(struct adapter *adapter)
{
struct ifnet *ifp = adapter->ifp;
device_t dev = adapter->dev;
- struct ixgbe_hw *hw;
+ struct ixgbe_hw *hw = &adapter->hw;
u32 k, txdctl, mhadd, gpie;
u32 rxdctl, rxctrl;
- int err;
+ mtx_assert(&adapter->core_mtx, MA_OWNED);
INIT_DEBUGOUT("ixgbe_init: begin");
+ ixgbe_reset_hw(hw);
+ hw->adapter_stopped = FALSE;
+ ixgbe_stop_adapter(hw);
+ callout_stop(&adapter->timer);
- hw = &adapter->hw;
- mtx_assert(&adapter->core_mtx, MA_OWNED);
+ /* reprogram the RAR[0] in case user changed it. */
+ ixgbe_set_rar(hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
/* Get the latest mac address, User can use a LAA */
bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr,
@@ -1061,16 +1016,14 @@ ixgbe_init_locked(struct adapter *adapter)
ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1);
hw->addr_ctrl.rar_used_count = 1;
- /* Do a warm reset */
- ixgbe_reset_hw(hw);
-
/* Prepare transmit descriptors and buffers */
if (ixgbe_setup_transmit_structures(adapter)) {
device_printf(dev,"Could not setup transmit structures\n");
ixgbe_stop(adapter);
- return;
+ return (ENOMEM);
}
+ ixgbe_init_hw(hw);
ixgbe_initialize_transmit_units(adapter);
/* Setup Multicast table */
@@ -1089,15 +1042,12 @@ ixgbe_init_locked(struct adapter *adapter)
if (ixgbe_setup_receive_structures(adapter)) {
device_printf(dev,"Could not setup receive structures\n");
ixgbe_stop(adapter);
- return;
+ return (ENOMEM);
}
/* Configure RX settings */
ixgbe_initialize_receive_units(adapter);
- /* Configure Interrupt Moderation */
- ixgbe_init_moderation(adapter);
-
gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE);
if (hw->mac.type == ixgbe_mac_82599EB) {
@@ -1122,8 +1072,11 @@ ixgbe_init_locked(struct adapter *adapter)
if (ifp->if_capenable & IFCAP_TSO4)
ifp->if_hwassist |= CSUM_TSO;
if (ifp->if_capenable & IFCAP_TXCSUM)
- ifp->if_hwassist = (CSUM_TCP | CSUM_UDP);
-
+ ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
+#if __FreeBSD_version >= 800000
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ifp->if_hwassist |= CSUM_SCTP;
+#endif
/* Set MTU size */
if (ifp->if_mtu > ETHERMTU) {
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
@@ -1174,7 +1127,7 @@ ixgbe_init_locked(struct adapter *adapter)
if (hw->mac.type == ixgbe_mac_82598EB)
rxctrl |= IXGBE_RXCTRL_DMBYPS;
rxctrl |= IXGBE_RXCTRL_RXEN;
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
+ ixgbe_enable_rx_dma(hw, rxctrl);
callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
@@ -1188,7 +1141,7 @@ ixgbe_init_locked(struct adapter *adapter)
#ifdef IXGBE_FDIR
/* Init Flow director */
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ if (hw->mac.type == ixgbe_mac_82599EB)
ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
#endif
@@ -1196,13 +1149,14 @@ ixgbe_init_locked(struct adapter *adapter)
** Check on any SFP devices that
** need to be kick-started
*/
- err = hw->phy.ops.identify(hw);
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- device_printf(dev,
- "Unsupported SFP+ module type was detected.\n");
- ixgbe_detach(dev);
- return;
- }
+ if (hw->phy.type == ixgbe_phy_none) {
+ int err = hw->phy.ops.identify(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ device_printf(dev,
+ "Unsupported SFP+ module type was detected.\n");
+ return (EIO);
+ }
+ }
/* Config/Enable Link */
ixgbe_config_link(adapter);
@@ -1214,7 +1168,7 @@ ixgbe_init_locked(struct adapter *adapter)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- return;
+ return (0);
}
static void
@@ -1291,36 +1245,20 @@ ixgbe_rearm_queues(struct adapter *adapter, u64 queues)
}
}
-static void
-ixgbe_handle_rx(void *context, int pending)
-{
- struct rx_ring *rxr = context;
- struct adapter *adapter = rxr->adapter;
- u32 loop = MAX_LOOP;
- bool more;
-
- do {
- more = ixgbe_rxeof(rxr, -1);
- } while (loop-- && more);
- /* Reenable this interrupt */
- ixgbe_enable_queue(adapter, rxr->msix);
-}
static void
-ixgbe_handle_tx(void *context, int pending)
+ixgbe_handle_que(void *context, int pending)
{
- struct tx_ring *txr = context;
- struct adapter *adapter = txr->adapter;
+ struct ix_queue *que = context;
+ struct adapter *adapter = que->adapter;
+ struct tx_ring *txr = que->txr;
struct ifnet *ifp = adapter->ifp;
- u32 loop = MAX_LOOP;
bool more;
- IXGBE_TX_LOCK(txr);
- do {
- more = ixgbe_txeof(txr);
- } while (loop-- && more);
-
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ more = ixgbe_rxeof(que, adapter->rx_process_limit);
+ IXGBE_TX_LOCK(txr);
+ ixgbe_txeof(txr);
#if __FreeBSD_version >= 800000
if (!drbr_empty(ifp, txr->br))
ixgbe_mq_start_locked(ifp, txr, NULL);
@@ -1328,11 +1266,16 @@ ixgbe_handle_tx(void *context, int pending)
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
ixgbe_start_locked(txr, ifp);
#endif
+ IXGBE_TX_UNLOCK(txr);
+ if (more) {
+ taskqueue_enqueue(que->tq, &que->que_task);
+ return;
+ }
}
- IXGBE_TX_UNLOCK(txr);
/* Reenable this interrupt */
- ixgbe_enable_queue(adapter, txr->msix);
+ ixgbe_enable_queue(adapter, que->msix);
+ return;
}
@@ -1345,33 +1288,32 @@ ixgbe_handle_tx(void *context, int pending)
static void
ixgbe_legacy_irq(void *arg)
{
- struct adapter *adapter = arg;
+ struct ix_queue *que = arg;
+ struct adapter *adapter = que->adapter;
struct ixgbe_hw *hw = &adapter->hw;
struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
- bool more;
+ bool more_tx, more_rx;
u32 reg_eicr, loop = MAX_LOOP;
reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
+ ++que->irqs;
if (reg_eicr == 0) {
ixgbe_enable_intr(adapter);
return;
}
- if (ixgbe_rxeof(rxr, adapter->rx_process_limit))
- taskqueue_enqueue(rxr->tq, &rxr->rx_task);
+ more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
IXGBE_TX_LOCK(txr);
- ++txr->tx_irq;
do {
- more = ixgbe_txeof(txr);
- } while (loop-- && more);
+ more_tx = ixgbe_txeof(txr);
+ } while (loop-- && more_tx);
IXGBE_TX_UNLOCK(txr);
- if (more)
- taskqueue_enqueue(txr->tq, &txr->tx_task);
+ if (more_rx || more_tx)
+ taskqueue_enqueue(que->tq, &que->que_task);
/* Check for fan failure */
if ((hw->phy.media_type == ixgbe_media_type_copper) &&
@@ -1382,15 +1324,8 @@ ixgbe_legacy_irq(void *arg)
}
/* Link status change */
- if (reg_eicr & IXGBE_EICR_LSC) {
- ixgbe_check_link(&adapter->hw,
- &adapter->link_speed, &adapter->link_up, 0);
- ixgbe_update_link_status(adapter);
- }
-
- /* Update interrupt rate */
- if (ixgbe_enable_aim == TRUE)
- ixgbe_update_aim(rxr);
+ if (reg_eicr & IXGBE_EICR_LSC)
+ taskqueue_enqueue(adapter->tq, &adapter->link_task);
ixgbe_enable_intr(adapter);
return;
@@ -1399,55 +1334,85 @@ ixgbe_legacy_irq(void *arg)
/*********************************************************************
*
- * MSI TX Interrupt Service routine
+ * MSI Queue Interrupt Service routine
*
**********************************************************************/
void
-ixgbe_msix_tx(void *arg)
+ixgbe_msix_que(void *arg)
{
- struct tx_ring *txr = arg;
- struct adapter *adapter = txr->adapter;
- bool more;
+ struct ix_queue *que = arg;
+ struct adapter *adapter = que->adapter;
+ struct tx_ring *txr = que->txr;
+ struct rx_ring *rxr = que->rxr;
+ bool more_tx, more_rx;
+ u32 newitr = 0;
- ixgbe_disable_queue(adapter, txr->msix);
+ ixgbe_disable_queue(adapter, que->msix);
+ ++que->irqs;
+
+ more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
IXGBE_TX_LOCK(txr);
- ++txr->tx_irq;
- more = ixgbe_txeof(txr);
+ more_tx = ixgbe_txeof(txr);
IXGBE_TX_UNLOCK(txr);
- if (more)
- taskqueue_enqueue(txr->tq, &txr->tx_task);
- else /* Reenable this interrupt */
- ixgbe_enable_queue(adapter, txr->msix);
- return;
-}
+ more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
-/*********************************************************************
- *
- * MSIX RX Interrupt Service routine
- *
- **********************************************************************/
-static void
-ixgbe_msix_rx(void *arg)
-{
- struct rx_ring *rxr = arg;
- struct adapter *adapter = rxr->adapter;
- bool more;
+ /* Do AIM now? */
- ixgbe_disable_queue(adapter, rxr->msix);
-
- ++rxr->rx_irq;
- more = ixgbe_rxeof(rxr, adapter->rx_process_limit);
-
- /* Update interrupt rate */
- if (ixgbe_enable_aim == TRUE)
- ixgbe_update_aim(rxr);
-
- if (more)
- taskqueue_enqueue(rxr->tq, &rxr->rx_task);
+ if (ixgbe_enable_aim == FALSE)
+ goto no_calc;
+ /*
+ ** Do Adaptive Interrupt Moderation:
+ ** - Write out last calculated setting
+ ** - Calculate based on average size over
+ ** the last interval.
+ */
+ if (que->eitr_setting)
+ IXGBE_WRITE_REG(&adapter->hw,
+ IXGBE_EITR(que->msix), que->eitr_setting);
+
+ que->eitr_setting = 0;
+
+ /* Idle, do nothing */
+ if ((txr->bytes == 0) && (rxr->bytes == 0))
+ goto no_calc;
+
+ if ((txr->bytes) && (txr->packets))
+ newitr = txr->bytes/txr->packets;
+ if ((rxr->bytes) && (rxr->packets))
+ newitr = max(newitr,
+ (rxr->bytes / rxr->packets));
+ newitr += 24; /* account for hardware frame, crc */
+
+ /* set an upper boundary */
+ newitr = min(newitr, 3000);
+
+ /* Be nice to the mid range */
+ if ((newitr > 300) && (newitr < 1200))
+ newitr = (newitr / 3);
else
- ixgbe_enable_queue(adapter, rxr->msix);
+ newitr = (newitr / 2);
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ newitr |= newitr << 16;
+ else
+ newitr |= IXGBE_EITR_CNT_WDIS;
+
+ /* save for next interrupt */
+ que->eitr_setting = newitr;
+
+ /* Reset state */
+ txr->bytes = 0;
+ txr->packets = 0;
+ rxr->bytes = 0;
+ rxr->packets = 0;
+
+no_calc:
+ if (more_tx || more_rx)
+ taskqueue_enqueue(que->tq, &que->que_task);
+ else /* Reenable this interrupt */
+ ixgbe_enable_queue(adapter, que->msix);
return;
}
@@ -1512,84 +1477,6 @@ ixgbe_msix_link(void *arg)
return;
}
-/*
-** Routine to do adjust the RX EITR value based on traffic,
-** its a simple three state model, but seems to help.
-**
-** Note that the three EITR values are tuneable using
-** sysctl in real time. The feature can be effectively
-** nullified by setting them equal.
-*/
-#define BULK_THRESHOLD 10000
-#define AVE_THRESHOLD 1600
-
-static void
-ixgbe_update_aim(struct rx_ring *rxr)
-{
- struct adapter *adapter = rxr->adapter;
- u32 olditr, newitr;
-
- /* Update interrupt moderation based on traffic */
- olditr = rxr->eitr_setting;
- newitr = olditr;
-
- /* Idle, don't change setting */
- if (rxr->bytes == 0)
- return;
-
- if (olditr == ixgbe_low_latency) {
- if (rxr->bytes > AVE_THRESHOLD)
- newitr = ixgbe_ave_latency;
- } else if (olditr == ixgbe_ave_latency) {
- if (rxr->bytes < AVE_THRESHOLD)
- newitr = ixgbe_low_latency;
- else if (rxr->bytes > BULK_THRESHOLD)
- newitr = ixgbe_bulk_latency;
- } else if (olditr == ixgbe_bulk_latency) {
- if (rxr->bytes < BULK_THRESHOLD)
- newitr = ixgbe_ave_latency;
- }
-
- if (olditr != newitr) {
- /* Change interrupt rate */
- rxr->eitr_setting = newitr;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(rxr->me),
- newitr | (newitr << 16));
- }
-
- rxr->bytes = 0;
- return;
-}
-
-static void
-ixgbe_init_moderation(struct adapter *adapter)
-{
- struct rx_ring *rxr = adapter->rx_rings;
- struct tx_ring *txr = adapter->tx_rings;
-
- /* Single interrupt - MSI or Legacy? */
- if (adapter->msix < 2) {
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(0), 100);
- return;
- }
-
- /* TX irq moderation rate is fixed */
- for (int i = 0; i < adapter->num_queues; i++, txr++)
- IXGBE_WRITE_REG(&adapter->hw,
- IXGBE_EITR(txr->msix), ixgbe_ave_latency);
-
- /* RX moderation will be adapted over time, set default */
- for (int i = 0; i < adapter->num_queues; i++, rxr++) {
- IXGBE_WRITE_REG(&adapter->hw,
- IXGBE_EITR(rxr->msix), ixgbe_low_latency);
- }
-
- /* Set Link moderation */
- IXGBE_WRITE_REG(&adapter->hw,
- IXGBE_EITR(adapter->linkvec), IXGBE_LINK_ITR);
-
-}
-
/*********************************************************************
*
* Media Ioctl callback
@@ -1665,11 +1552,10 @@ ixgbe_media_change(struct ifnet * ifp)
/*********************************************************************
*
- * This routine maps the mbufs to tx descriptors.
- * WARNING: while this code is using an MQ style infrastructure,
- * it would NOT work as is with more than 1 queue.
+ * This routine maps the mbufs to tx descriptors, allowing the
+ * TX engine to transmit the packets.
+ * - return 0 on success, positive on failure
*
- * return 0 on success, positive on failure
**********************************************************************/
static int
@@ -1695,14 +1581,6 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp)
if (m_head->m_flags & M_VLANTAG)
cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE;
- /* Do a clean if descriptors are low */
- if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD) {
- ixgbe_txeof(txr);
- /* Now do we at least have a minimal? */
- if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD)
- return (ENOBUFS);
- }
-
/*
* Important to capture the first descriptor
* used because it will contain the index of
@@ -1756,7 +1634,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp)
/* Make certain there are enough descriptors */
if (nsegs > txr->tx_avail - 2) {
- txr->no_tx_desc_avail++;
+ txr->no_desc_avail++;
error = ENOBUFS;
goto xmit_fail;
}
@@ -1814,7 +1692,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp)
txd->read.cmd_type_len = htole32(txr->txd_cmd |
cmd_type_len |seglen);
txd->read.olinfo_status = htole32(olinfo_status);
- last = i; /* Next descriptor that will get completed */
+ last = i; /* descriptor that will get completion IRQ */
if (++i == adapter->num_tx_desc)
i = 0;
@@ -1844,6 +1722,11 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp)
*/
++txr->total_packets;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), i);
+
+ /* Do a clean if descriptors are low */
+ if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD)
+ ixgbe_txeof(txr);
+
return (0);
xmit_fail:
@@ -1978,7 +1861,6 @@ ixgbe_local_timer(void *arg)
struct ifnet *ifp = adapter->ifp;
device_t dev = adapter->dev;
struct tx_ring *txr = adapter->tx_rings;
- bool tx_hung = FALSE;
mtx_assert(&adapter->core_mtx, MA_OWNED);
@@ -1989,21 +1871,32 @@ ixgbe_local_timer(void *arg)
ixgbe_update_link_status(adapter);
ixgbe_update_stats_counters(adapter);
- if (ixgbe_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) {
+
+ /* Debug display */
+ if (ixgbe_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING)
ixgbe_print_hw_stats(adapter);
- }
+
+ /*
+ * If the interface has been paused
+ * then don't do the watchdog check
+ */
+ if (IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)
+ goto out;
/*
** Check for time since any descriptor was cleaned
*/
for (int i = 0; i < adapter->num_queues; i++, txr++) {
- if (txr->watchdog_check == FALSE)
+ IXGBE_TX_LOCK(txr);
+ if (txr->watchdog_check == FALSE) {
+ IXGBE_TX_UNLOCK(txr);
continue;
- if ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG) {
- tx_hung = TRUE;
- goto hung;
}
+ if ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG)
+ goto hung;
+ IXGBE_TX_UNLOCK(txr);
}
out:
+ ixgbe_rearm_queues(adapter, adapter->que_mask);
callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
return;
@@ -2017,6 +1910,7 @@ hung:
txr->me, txr->tx_avail, txr->next_to_clean);
adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
adapter->watchdog_events++;
+ IXGBE_TX_UNLOCK(txr);
ixgbe_init_locked(adapter);
}
@@ -2123,8 +2017,7 @@ static int
ixgbe_allocate_legacy(struct adapter *adapter)
{
device_t dev = adapter->dev;
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
+ struct ix_queue *que = adapter->queues;
int error, rid = 0;
/* MSI RID at 1 */
@@ -2144,15 +2037,10 @@ ixgbe_allocate_legacy(struct adapter *adapter)
* Try allocating a fast interrupt and the associated deferred
* processing contexts.
*/
- TASK_INIT(&txr->tx_task, 0, ixgbe_handle_tx, txr);
- TASK_INIT(&rxr->rx_task, 0, ixgbe_handle_rx, rxr);
- txr->tq = taskqueue_create_fast("ixgbe_txq", M_NOWAIT,
- taskqueue_thread_enqueue, &txr->tq);
- rxr->tq = taskqueue_create_fast("ixgbe_rxq", M_NOWAIT,
- taskqueue_thread_enqueue, &rxr->tq);
- taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq",
- device_get_nameunit(adapter->dev));
- taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq",
+ TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que);
+ que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT,
+ taskqueue_thread_enqueue, &que->tq);
+ taskqueue_start_threads(&que->tq, 1, PI_NET, "%s ixq",
device_get_nameunit(adapter->dev));
/* Tasklets for Link, SFP and Multispeed Fiber */
@@ -2169,15 +2057,17 @@ ixgbe_allocate_legacy(struct adapter *adapter)
if ((error = bus_setup_intr(dev, adapter->res,
INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_legacy_irq,
- adapter, &adapter->tag)) != 0) {
+ que, &adapter->tag)) != 0) {
device_printf(dev, "Failed to register fast interrupt "
"handler: %d\n", error);
- taskqueue_free(txr->tq);
- taskqueue_free(rxr->tq);
- txr->tq = NULL;
- rxr->tq = NULL;
+ taskqueue_free(que->tq);
+ taskqueue_free(adapter->tq);
+ que->tq = NULL;
+ adapter->tq = NULL;
return (error);
}
+ /* For simplicity in the handlers */
+ adapter->que_mask = IXGBE_EIMS_ENABLE_MASK;
return (0);
}
@@ -2192,83 +2082,44 @@ static int
ixgbe_allocate_msix(struct adapter *adapter)
{
device_t dev = adapter->dev;
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
+ struct ix_queue *que = adapter->queues;
int error, rid, vector = 0;
- /* TX setup: the code is here for multi tx,
- there are other parts of the driver not ready for it */
- for (int i = 0; i < adapter->num_queues; i++, vector++, txr++) {
+ for (int i = 0; i < adapter->num_queues; i++, vector++, que++) {
rid = vector + 1;
- txr->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
- if (!txr->res) {
- device_printf(dev,"Unable to allocate"
- " bus resource: tx interrupt [%d]\n", vector);
- return (ENXIO);
- }
- /* Set the handler function */
- error = bus_setup_intr(dev, txr->res,
- INTR_TYPE_NET | INTR_MPSAFE, NULL,
- ixgbe_msix_tx, txr, &txr->tag);
- if (error) {
- txr->res = NULL;
- device_printf(dev, "Failed to register TX handler");
- return (error);
- }
- txr->msix = vector;
- /*
- ** Bind the msix vector, and thus the
- ** ring to the corresponding cpu.
- */
- if (adapter->num_queues > 1)
- bus_bind_intr(dev, txr->res, i);
-
- TASK_INIT(&txr->tx_task, 0, ixgbe_handle_tx, txr);
- txr->tq = taskqueue_create_fast("ixgbe_txq", M_NOWAIT,
- taskqueue_thread_enqueue, &txr->tq);
- taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq",
- device_get_nameunit(adapter->dev));
- }
-
- /* RX setup */
- for (int i = 0; i < adapter->num_queues; i++, vector++, rxr++) {
- rid = vector + 1;
- rxr->res = bus_alloc_resource_any(dev,
- SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
- if (!rxr->res) {
+ if (que->res == NULL) {
device_printf(dev,"Unable to allocate"
- " bus resource: rx interrupt [%d],"
- "rid = %d\n", i, rid);
+ " bus resource: que interrupt [%d]\n", vector);
return (ENXIO);
}
/* Set the handler function */
- error = bus_setup_intr(dev, rxr->res,
+ error = bus_setup_intr(dev, que->res,
INTR_TYPE_NET | INTR_MPSAFE, NULL,
- ixgbe_msix_rx, rxr, &rxr->tag);
+ ixgbe_msix_que, que, &que->tag);
if (error) {
- rxr->res = NULL;
- device_printf(dev, "Failed to register RX handler");
+ que->res = NULL;
+ device_printf(dev, "Failed to register QUE handler");
return (error);
}
- rxr->msix = vector;
- /* used in local timer */
- adapter->rx_mask |= (u64)(1 << vector);
+ que->msix = vector;
+ adapter->que_mask |= (u64)(1 << que->msix);
/*
** Bind the msix vector, and thus the
** ring to the corresponding cpu.
*/
if (adapter->num_queues > 1)
- bus_bind_intr(dev, rxr->res, i);
+ bus_bind_intr(dev, que->res, i);
- TASK_INIT(&rxr->rx_task, 0, ixgbe_handle_rx, rxr);
- rxr->tq = taskqueue_create_fast("ixgbe_rxq", M_NOWAIT,
- taskqueue_thread_enqueue, &rxr->tq);
- taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq",
+ TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que);
+ que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT,
+ taskqueue_thread_enqueue, &que->tq);
+ taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que",
device_get_nameunit(adapter->dev));
}
- /* Now for Link changes */
+ /* and Link */
rid = vector + 1;
adapter->res = bus_alloc_resource_any(dev,
SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
@@ -2340,15 +2191,15 @@ ixgbe_setup_msix(struct adapter *adapter)
}
/* Figure out a reasonable auto config value */
- queues = (mp_ncpus > ((msgs-1)/2)) ? (msgs-1)/2 : mp_ncpus;
+ queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
if (ixgbe_num_queues == 0)
ixgbe_num_queues = queues;
/*
- ** Want two vectors (RX/TX) per queue
+ ** Want one vector (RX/TX pair) per queue
** plus an additional for Link.
*/
- want = (ixgbe_num_queues * 2) + 1;
+ want = ixgbe_num_queues + 1;
if (msgs >= want)
msgs = want;
else {
@@ -2409,8 +2260,7 @@ ixgbe_allocate_pci_resources(struct adapter *adapter)
static void
ixgbe_free_pci_resources(struct adapter * adapter)
{
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
+ struct ix_queue *que = adapter->queues;
device_t dev = adapter->dev;
int rid, memrid;
@@ -2431,29 +2281,18 @@ ixgbe_free_pci_resources(struct adapter * adapter)
goto mem;
/*
- ** Release all the interrupt resources:
- ** notice this is harmless for Legacy or
- ** MSI since pointers will always be NULL
+ ** Release all msix queue resources:
*/
- for (int i = 0; i < adapter->num_queues; i++, txr++) {
- rid = txr->msix + 1;
- if (txr->tag != NULL) {
- bus_teardown_intr(dev, txr->res, txr->tag);
- txr->tag = NULL;
+ for (int i = 0; i < adapter->num_queues; i++, que++) {
+ rid = que->msix + 1;
+ if (que->tag != NULL) {
+ bus_teardown_intr(dev, que->res, que->tag);
+ que->tag = NULL;
}
- if (txr->res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, rid, txr->res);
+ if (que->res != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ, rid, que->res);
}
- for (int i = 0; i < adapter->num_queues; i++, rxr++) {
- rid = rxr->msix + 1;
- if (rxr->tag != NULL) {
- bus_teardown_intr(dev, rxr->res, rxr->tag);
- rxr->tag = NULL;
- }
- if (rxr->res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, rid, rxr->res);
- }
/* Clean the Legacy or Link interrupt last */
if (adapter->linkvec) /* we are doing MSIX */
@@ -2467,6 +2306,7 @@ ixgbe_free_pci_resources(struct adapter * adapter)
}
if (adapter->res != NULL)
bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res);
+
mem:
if (adapter->msix)
pci_release_msi(dev);
@@ -2524,9 +2364,7 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
- ifp->if_capabilities |= IFCAP_JUMBO_MTU;
- if (ixgbe_header_split)
- ifp->if_capabilities |= IFCAP_LRO;
+ ifp->if_capabilities |= IFCAP_JUMBO_MTU | IFCAP_LRO;
ifp->if_capenable = ifp->if_capabilities;
@@ -2546,6 +2384,7 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter)
}
ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
+
return;
}
@@ -2556,17 +2395,7 @@ ixgbe_config_link(struct adapter *adapter)
u32 autoneg, err = 0;
bool sfp, negotiate;
- switch (hw->phy.type) {
- case ixgbe_phy_sfp_avago:
- case ixgbe_phy_sfp_ftl:
- case ixgbe_phy_sfp_intel:
- case ixgbe_phy_sfp_unknown:
- case ixgbe_phy_tw_tyco:
- case ixgbe_phy_tw_unknown:
- sfp = TRUE;
- default:
- sfp = FALSE;
- }
+ sfp = ixgbe_is_sfp(hw);
if (sfp) {
if (hw->phy.multispeed_fiber) {
@@ -2613,8 +2442,8 @@ ixgbe_dma_malloc(struct adapter *adapter, bus_size_t size,
device_t dev = adapter->dev;
int r;
- r = bus_dma_tag_create(NULL, /* parent */
- 1, 0, /* alignment, bounds */
+ r = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
+ DBA_ALIGN, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
@@ -2679,21 +2508,30 @@ ixgbe_dma_free(struct adapter *adapter, struct ixgbe_dma_alloc *dma)
static int
ixgbe_allocate_queues(struct adapter *adapter)
{
- device_t dev = adapter->dev;
- struct tx_ring *txr;
- struct rx_ring *rxr;
+ device_t dev = adapter->dev;
+ struct ix_queue *que;
+ struct tx_ring *txr;
+ struct rx_ring *rxr;
int rsize, tsize, error = IXGBE_SUCCESS;
int txconf = 0, rxconf = 0;
+ /* First allocate the top level queue structs */
+ if (!(adapter->queues =
+ (struct ix_queue *) malloc(sizeof(struct ix_queue) *
+ adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
+ device_printf(dev, "Unable to allocate queue memory\n");
+ error = ENOMEM;
+ goto fail;
+ }
+
/* First allocate the TX ring struct memory */
if (!(adapter->tx_rings =
(struct tx_ring *) malloc(sizeof(struct tx_ring) *
adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
device_printf(dev, "Unable to allocate TX ring memory\n");
error = ENOMEM;
- goto fail;
+ goto tx_fail;
}
- txr = adapter->tx_rings;
/* Next allocate the RX */
if (!(adapter->rx_rings =
@@ -2703,11 +2541,10 @@ ixgbe_allocate_queues(struct adapter *adapter)
error = ENOMEM;
goto rx_fail;
}
- rxr = adapter->rx_rings;
/* For the ring itself */
tsize = roundup2(adapter->num_tx_desc *
- sizeof(union ixgbe_adv_tx_desc), 4096);
+ sizeof(union ixgbe_adv_tx_desc), DBA_ALIGN);
/*
* Now set up the TX queues, txconf is needed to handle the
@@ -2746,6 +2583,12 @@ ixgbe_allocate_queues(struct adapter *adapter)
/* Allocate a buf ring */
txr->br = buf_ring_alloc(IXGBE_BR_SIZE, M_DEVBUF,
M_WAITOK, &txr->tx_mtx);
+ if (txr->br == NULL) {
+ device_printf(dev,
+ "Critical Failure setting up buf ring\n");
+ error = ENOMEM;
+ goto err_tx_desc;
+ }
#endif
}
@@ -2753,7 +2596,7 @@ ixgbe_allocate_queues(struct adapter *adapter)
* Next the RX queues...
*/
rsize = roundup2(adapter->num_rx_desc *
- sizeof(union ixgbe_adv_rx_desc), 4096);
+ sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN);
for (int i = 0; i < adapter->num_queues; i++, rxconf++) {
rxr = &adapter->rx_rings[i];
/* Set up some basics */
@@ -2784,6 +2627,16 @@ ixgbe_allocate_queues(struct adapter *adapter)
}
}
+ /*
+ ** Finally set up the queue holding structs
+ */
+ for (int i = 0; i < adapter->num_queues; i++) {
+ que = &adapter->queues[i];
+ que->adapter = adapter;
+ que->txr = &adapter->tx_rings[i];
+ que->rxr = &adapter->rx_rings[i];
+ }
+
return (0);
err_rx_desc:
@@ -2795,6 +2648,8 @@ err_tx_desc:
free(adapter->rx_rings, M_DEVBUF);
rx_fail:
free(adapter->tx_rings, M_DEVBUF);
+tx_fail:
+ free(adapter->queues, M_DEVBUF);
fail:
return (error);
}
@@ -2871,6 +2726,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
int i;
/* Clear the old ring contents */
+ IXGBE_TX_LOCK(txr);
bzero((void *)txr->tx_base,
(sizeof(union ixgbe_adv_tx_desc)) * adapter->num_tx_desc);
/* Reset indices */
@@ -2902,6 +2758,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ IXGBE_TX_UNLOCK(txr);
}
/*********************************************************************
@@ -3158,6 +3015,12 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP;
break;
+#if __FreeBSD_version >= 800000
+ case IPPROTO_SCTP:
+ if (mp->m_pkthdr.csum_flags & CSUM_SCTP)
+ type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
+ break;
+#endif
default:
offload = FALSE;
break;
@@ -3281,6 +3144,7 @@ static void
ixgbe_atr(struct tx_ring *txr, struct mbuf *mp)
{
struct adapter *adapter = txr->adapter;
+ struct ix_queue *que;
struct ixgbe_atr_input atr_input;
struct ip *ip;
struct tcphdr *th;
@@ -3331,6 +3195,7 @@ ixgbe_atr(struct tx_ring *txr, struct mbuf *mp)
src_ipv4_addr = ip->ip_src.s_addr;
dst_ipv4_addr = ip->ip_dst.s_addr;
flex_bytes = etype;
+ que = &adapter->queues[txr->me];
ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id);
ixgbe_atr_set_src_port_82599(&atr_input, dst_port);
@@ -3343,7 +3208,7 @@ ixgbe_atr(struct tx_ring *txr, struct mbuf *mp)
/* This assumes the Rx queue and Tx queue are bound to the same CPU */
ixgbe_fdir_add_signature_filter_82599(&adapter->hw,
- &atr_input, txr->msix);
+ &atr_input, que->msix);
}
#endif
@@ -3401,7 +3266,8 @@ ixgbe_txeof(struct tx_ring *txr)
++txr->tx_avail;
if (tx_buffer->m_head) {
- ifp->if_opackets++;
+ txr->bytes +=
+ tx_buffer->m_head->m_pkthdr.len;
bus_dmamap_sync(txr->txtag,
tx_buffer->map,
BUS_DMASYNC_POSTWRITE);
@@ -3421,6 +3287,8 @@ ixgbe_txeof(struct tx_ring *txr)
tx_desc =
(struct ixgbe_legacy_tx_desc *)&txr->tx_base[first];
}
+ ++txr->packets;
+ ++ifp->if_opackets;
/* See if there is more work now */
last = tx_buffer->eop_index;
if (last != -1) {
@@ -3456,27 +3324,32 @@ ixgbe_txeof(struct tx_ring *txr)
/*********************************************************************
*
- * Refresh mbuf buffers for a range of descriptors
+ * Refresh mbuf buffers for RX descriptor rings
+ * - now keeps its own state so discards due to resource
+ * exhaustion are unnecessary, if an mbuf cannot be obtained
+ * it just returns, keeping its placeholder, thus it can simply
+ * be recalled to try again.
*
**********************************************************************/
-static int
-ixgbe_get_buf(struct rx_ring *rxr, int first, int limit)
+static void
+ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
{
struct adapter *adapter = rxr->adapter;
bus_dma_segment_t seg[2];
struct ixgbe_rx_buf *rxbuf;
struct mbuf *mh, *mp;
bus_dmamap_t map;
- int i, nsegs, error;
+ int i, nsegs, error, cleaned;
- i = first;
+ i = rxr->next_to_refresh;
+ cleaned = -1; /* Signify no completions */
while (i != limit) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->m_head == NULL) {
mh = m_gethdr(M_DONTWAIT, MT_DATA);
if (mh == NULL)
- goto failure;
+ goto update;
} else /* reuse */
mh = rxbuf->m_head;
@@ -3487,13 +3360,14 @@ ixgbe_get_buf(struct rx_ring *rxr, int first, int limit)
mp = m_getjcl(M_DONTWAIT, MT_DATA,
M_PKTHDR, adapter->rx_mbuf_sz);
if (mp == NULL)
- goto failure;
+ goto update;
mp->m_len = adapter->rx_mbuf_sz;
mp->m_flags &= ~M_PKTHDR;
} else { /* reusing */
mp = rxbuf->m_pack;
mp->m_len = adapter->rx_mbuf_sz;
mp->m_flags &= ~M_PKTHDR;
+ mp->m_next = NULL;
}
/*
@@ -3509,7 +3383,7 @@ ixgbe_get_buf(struct rx_ring *rxr, int first, int limit)
if (error != 0) {
printf("GET BUF: dmamap load failure - %d\n", error);
m_free(mh);
- return (error);
+ goto update;
}
/* Unload old mapping and update buffer struct */
@@ -3527,52 +3401,21 @@ ixgbe_get_buf(struct rx_ring *rxr, int first, int limit)
rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr);
rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr);
+ cleaned = i;
/* Calculate next index */
if (++i == adapter->num_rx_desc)
i = 0;
+ /* This is the work marker for refresh */
+ rxr->next_to_refresh = i;
}
+update:
+ if (cleaned != -1) /* If we refreshed some, bump tail */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), cleaned);
- return (0);
-
-failure:
- panic("GET BUF: ENOBUFS\n");
-
-#if 0
- /*
- ** If we get here, we have an mbuf resource
- ** issue, so we discard the incoming packet
- ** and attempt to reuse existing mbufs next
- ** pass thru the ring, but to do so we must
- ** fix up the descriptor which had the address
- ** clobbered with writeback info.
- */
-remap:
- adapter->mbuf_header_failed++;
- merr = ENOBUFS;
- /* Is there a reusable buffer? */
- mh = rxr->rx_buffers[i].m_head;
- if (mh == NULL) /* Nope, init error */
- return (merr);
- mp = rxr->rx_buffers[i].m_pack;
- if (mp == NULL) /* Nope, init error */
- return (merr);
- /* Get our old mapping */
- rxbuf = &rxr->rx_buffers[i];
- error = bus_dmamap_load_mbuf_sg(rxr->rxtag,
- rxbuf->map, mh, seg, &nsegs, BUS_DMA_NOWAIT);
- if (error != 0) {
- /* We really have a problem */
- m_free(mh);
- return (error);
- }
- /* Now fix the descriptor as needed */
- rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr);
- rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr);
-
- return (merr);
-#endif
+ return;
}
+
/*********************************************************************
*
* Allocate memory for rx_buffer structures. Since we use one
@@ -3603,7 +3446,7 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr)
** with packet split (hence the two segments, even though
** it may not always use this.
*/
- if ((error = bus_dma_tag_create(NULL, /* parent */
+ if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
1, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -3646,7 +3489,6 @@ fail:
return (error);
}
-
/*
** Used to detect a descriptor that has
** been merged by Hardware RSC.
@@ -3670,11 +3512,12 @@ ixgbe_setup_hw_rsc(struct rx_ring *rxr)
{
struct adapter *adapter = rxr->adapter;
struct ixgbe_hw *hw = &adapter->hw;
- u32 rscctrl, rdrxctl;
+ u32 rscctrl, rdrxctl;
rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ rdrxctl |= IXGBE_RDRXCTL_RSCACKC;
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(rxr->me));
@@ -3723,6 +3566,7 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
dev = adapter->dev;
/* Clear the ring contents */
+ IXGBE_RX_LOCK(rxr);
rsize = roundup2(adapter->num_rx_desc *
sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN);
bzero((void *)rxr->rx_base, rsize);
@@ -3781,14 +3625,12 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
/* Setup our descriptor indices */
rxr->next_to_check = 0;
- rxr->last_refreshed = 0;
+ rxr->next_to_refresh = 0;
rxr->lro_enabled = FALSE;
/* Use header split if configured */
if (ixgbe_header_split)
rxr->hdr_split = TRUE;
- else
- ifp->if_capabilities &= ~IFCAP_LRO;
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -3796,40 +3638,25 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
/*
** Now set up the LRO interface:
** 82598 uses software LRO, the
- ** 82599 on the other hand uses a
- ** hardware assist to do the same.
- ** We only do LRO when header split
- ** is enabled, its simpler that way.
+ ** 82599 additionally uses a
+ ** hardware assist.
+ **
+ ** Disable RSC when RXCSUM is off
*/
- if ((ifp->if_capenable & IFCAP_LRO) && (rxr->hdr_split)) {
+ if ((adapter->hw.mac.type == ixgbe_mac_82599EB) &&
+ (ifp->if_capenable & IFCAP_RXCSUM))
+ ixgbe_setup_hw_rsc(rxr);
+ else if (ifp->if_capenable & IFCAP_LRO) {
int err = tcp_lro_init(lro);
if (err)
panic("LRO Initialization failed!\n");
INIT_DEBUGOUT("RX Soft LRO Initialized\n");
rxr->lro_enabled = TRUE;
lro->ifp = adapter->ifp;
- ixgbe_setup_hw_rsc(rxr);
}
+ IXGBE_RX_UNLOCK(rxr);
return (0);
-#if 0
-fail:
- /*
- * We need to clean up any buffers allocated
- * so far, 'j' is the failing index.
- */
- for (int i = 0; i < j; i++) {
- rxbuf = &rxr->rx_buffers[i];
- if (rxbuf->m_head != NULL) {
- bus_dmamap_sync(rxr->rxtag, rxbuf->map,
- BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(rxr->rxtag, rxbuf->map);
- m_freem(rxbuf->m_head);
- rxbuf->m_head = NULL;
- }
- }
- return (ENOBUFS);
-#endif
}
/*********************************************************************
@@ -4025,6 +3852,7 @@ ixgbe_free_receive_structures(struct adapter *adapter)
free(adapter->rx_rings, M_DEVBUF);
}
+
/*********************************************************************
*
* Free receive ring data structures
@@ -4065,6 +3893,61 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr)
return;
}
+static __inline void
+ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype)
+{
+
+ /*
+ * ATM LRO is only for IPv4/TCP packets and TCP checksum of the packet
+ * should be computed by hardware. Also it should not have VLAN tag in
+ * ethernet header.
+ */
+ if (rxr->lro_enabled &&
+ (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
+ (ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 &&
+ (ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) ==
+ (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) &&
+ (m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) ==
+ (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) {
+ /*
+ * Send to the stack if:
+ ** - LRO not enabled, or
+ ** - no LRO resources, or
+ ** - lro enqueue fails
+ */
+ if (rxr->lro.lro_cnt != 0)
+ if (tcp_lro_rx(&rxr->lro, m, 0) == 0)
+ return;
+ }
+ (*ifp->if_input)(ifp, m);
+}
+
+static __inline void
+ixgbe_rx_discard(struct rx_ring *rxr, int i)
+{
+ struct adapter *adapter = rxr->adapter;
+ struct ixgbe_rx_buf *rbuf;
+ struct mbuf *mh, *mp;
+
+ rbuf = &rxr->rx_buffers[i];
+ if (rbuf->fmp != NULL) /* Partial chain ? */
+ m_freem(rbuf->fmp);
+
+ mh = rbuf->m_head;
+ mp = rbuf->m_pack;
+
+ /* Reuse loaded DMA map and just update mbuf chain */
+ mh->m_len = MHLEN;
+ mh->m_flags |= M_PKTHDR;
+ mh->m_next = NULL;
+
+ mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz;
+ mp->m_data = mp->m_ext.ext_buf;
+ mp->m_next = NULL;
+ return;
+}
+
+
/*********************************************************************
*
* This routine executes in interrupt context. It replenishes
@@ -4077,154 +3960,176 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr)
* Return TRUE for more work, FALSE for all clean.
*********************************************************************/
static bool
-ixgbe_rxeof(struct rx_ring *rxr, int count)
+ixgbe_rxeof(struct ix_queue *que, int count)
{
- struct adapter *adapter = rxr->adapter;
- struct ifnet *ifp = adapter->ifp;
+ struct adapter *adapter = que->adapter;
+ struct rx_ring *rxr = que->rxr;
+ struct ifnet *ifp = adapter->ifp;
struct lro_ctrl *lro = &rxr->lro;
struct lro_entry *queued;
- int i, processed = 0;
- u32 staterr;
+ int i, nextp, processed = 0;
+ u32 staterr = 0;
union ixgbe_adv_rx_desc *cur;
-
+ struct ixgbe_rx_buf *rbuf, *nbuf;
IXGBE_RX_LOCK(rxr);
- i = rxr->next_to_check;
- cur = &rxr->rx_base[i];
- staterr = cur->wb.upper.status_error;
-
- if (!(staterr & IXGBE_RXD_STAT_DD)) {
- IXGBE_RX_UNLOCK(rxr);
- return FALSE;
- }
- /* Sync the ring */
+ /* Sync the ring. */
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
- BUS_DMASYNC_POSTREAD);
-
- while ((staterr & IXGBE_RXD_STAT_DD) && (count != 0) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- struct mbuf *sendmp, *mh, *mp, *nh, *np;
- struct ixgbe_rx_buf *nxtbuf;
- u32 rsc;
- u16 hlen, plen, hdr, nextp, vtag;
- bool accept_frame, eop;
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ for (i = rxr->next_to_check; count != 0;) {
+ struct mbuf *sendmp, *mh, *mp;
+ u32 rsc, ptype;
+ u16 hlen, plen, hdr, vtag;
+ bool eop;
+
+ cur = &rxr->rx_base[i];
+ staterr = le32toh(cur->wb.upper.status_error);
- accept_frame = TRUE;
- hlen = plen = rsc = nextp = 0;
- sendmp = mh = mp = nh = np = NULL;
+ if ((staterr & IXGBE_RXD_STAT_DD) == 0)
+ break;
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
- /* Sync the buffers */
- bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[i].map,
- BUS_DMASYNC_POSTREAD);
- mh = rxr->rx_buffers[i].m_head;
- mp = rxr->rx_buffers[i].m_pack;
+ count--;
+ sendmp = NULL;
+ nbuf = NULL;
+ rsc = 0;
+ cur->wb.upper.status_error = 0;
+ rbuf = &rxr->rx_buffers[i];
+ mh = rbuf->m_head;
+ mp = rbuf->m_pack;
+
+ plen = le16toh(cur->wb.upper.length);
+ ptype = le32toh(cur->wb.lower.lo_dword.data) &
+ IXGBE_RXDADV_PKTTYPE_MASK;
+ hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info);
vtag = le16toh(cur->wb.upper.vlan);
eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0);
+ /* Make sure all parts of a bad packet are discarded */
+ if (((staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) ||
+ (rxr->discard)) {
+ ifp->if_ierrors++;
+ rxr->rx_discarded++;
+ if (!eop)
+ rxr->discard = TRUE;
+ else
+ rxr->discard = FALSE;
+ ixgbe_rx_discard(rxr, i);
+ goto next_desc;
+ }
+
+ /*
+ ** On 82599 which supports a hardware
+ ** LRO (called HW RSC), packets need
+ ** not be fragmented across sequential
+ ** descriptors, rather the next descriptor
+ ** is indicated in bits of the descriptor.
+ ** This also means that we might proceses
+ ** more than one packet at a time, something
+ ** that has never been true before, it
+ ** required eliminating global chain pointers
+ ** in favor of what we are doing here. -jfv
+ */
if (!eop) {
/*
- ** On 82599 which supports a hardware
- ** LRO (called HW RSC), packets need
- ** not be fragmented across sequential
- ** descriptors, rather the next descriptor
- ** is indicated in bits of the current.
- ** This also means that we might proceses
- ** more than one packet at a time, something
- ** that has never been true before, it
- ** required eliminating global chain pointers
- ** in favor of what we are doing here. -jfv
+ ** Figure out the next descriptor
+ ** of this frame.
*/
if (rxr->hw_rsc == TRUE) {
rsc = ixgbe_rsc_count(cur);
rxr->rsc_num += (rsc - 1);
}
- if (rsc) {
+ if (rsc) { /* Get hardware index */
nextp = ((staterr &
IXGBE_RXDADV_NEXTP_MASK) >>
IXGBE_RXDADV_NEXTP_SHIFT);
- } else {
+ } else { /* Just sequential */
nextp = i + 1;
if (nextp == adapter->num_rx_desc)
nextp = 0;
}
- nxtbuf = &rxr->rx_buffers[nextp];
- prefetch(nxtbuf);
+ nbuf = &rxr->rx_buffers[nextp];
+ prefetch(nbuf);
}
-
/*
- ** The way the hardware is configured to
- ** split, it will ONLY use the header buffer
- ** when header split is enabled, otherwise we
- ** get legacy behavior, ie, both header and
- ** payload are DMA'd into JUST the payload buffer.
+ ** The header mbuf is ONLY used when header
+ ** split is enabled, otherwise we get normal
+ ** behavior, ie, both header and payload
+ ** are DMA'd into the payload buffer.
**
** Rather than using the fmp/lmp global pointers
** we now keep the head of a packet chain in the
- ** m_nextpkt pointer and pass this along from one
+ ** buffer struct and pass this along from one
** descriptor to the next, until we get EOP.
- **
*/
- if ((rxr->hdr_split) && (mh->m_nextpkt == NULL)) {
- hdr = le16toh(cur->
- wb.lower.lo_dword.hs_rss.hdr_info);
+ if (rxr->hdr_split && (rbuf->fmp == NULL)) {
+ /* This must be an initial descriptor */
hlen = (hdr & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
IXGBE_RXDADV_HDRBUFLEN_SHIFT;
if (hlen > IXGBE_RX_HDR)
hlen = IXGBE_RX_HDR;
- plen = le16toh(cur->wb.upper.length);
mh->m_len = hlen;
mh->m_flags |= M_PKTHDR;
mh->m_next = NULL;
mh->m_pkthdr.len = mh->m_len;
- /* Null this so getbuf replenishes */
- rxr->rx_buffers[i].m_head = NULL;
+ /* Null buf pointer so it is refreshed */
+ rbuf->m_head = NULL;
/*
- ** Get the payload length, this
+ ** Check the payload length, this
** could be zero if its a small
** packet.
*/
- if (plen) {
+ if (plen > 0) {
mp->m_len = plen;
mp->m_next = NULL;
mp->m_flags &= ~M_PKTHDR;
mh->m_next = mp;
mh->m_pkthdr.len += mp->m_len;
- /* Null this so getbuf replenishes */
- rxr->rx_buffers[i].m_pack = NULL;
+ /* Null buf pointer so it is refreshed */
+ rbuf->m_pack = NULL;
rxr->rx_split_packets++;
}
- /* Setup the forward chain */
- if (eop == 0) {
- nh = rxr->rx_buffers[nextp].m_head;
- np = rxr->rx_buffers[nextp].m_pack;
- nh->m_nextpkt = mh;
- if (plen)
- mp->m_next = np;
- else
- mh->m_next = np;
- } else {
- sendmp = mh;
- if (staterr & IXGBE_RXD_STAT_VP) {
- sendmp->m_pkthdr.ether_vtag = vtag;
- sendmp->m_flags |= M_VLANTAG;
- }
- }
+ /*
+ ** Now create the forward
+ ** chain so when complete
+ ** we wont have to.
+ */
+ if (eop == 0) {
+ /* stash the chain head */
+ nbuf->fmp = mh;
+ /* Make forward chain */
+ if (plen)
+ mp->m_next = nbuf->m_pack;
+ else
+ mh->m_next = nbuf->m_pack;
+ } else {
+ /* Singlet, prepare to send */
+ sendmp = mh;
+ if (staterr & IXGBE_RXD_STAT_VP) {
+ sendmp->m_pkthdr.ether_vtag = vtag;
+ sendmp->m_flags |= M_VLANTAG;
+ }
+ }
} else {
/*
** Either no header split, or a
** secondary piece of a fragmented
- ** packet.
+ ** split packet.
*/
- mp->m_len = le16toh(cur->wb.upper.length);
- rxr->rx_buffers[i].m_pack = NULL;
- /* stored head pointer */
- sendmp = mh->m_nextpkt;
- if (sendmp != NULL) {
+ mp->m_len = plen;
+ /*
+ ** See if there is a stored head
+ ** that determines what we are
+ */
+ sendmp = rbuf->fmp;
+ rbuf->m_pack = rbuf->fmp = NULL;
+
+ if (sendmp != NULL) /* secondary frag */
sendmp->m_pkthdr.len += mp->m_len;
- sendmp->m_nextpkt = NULL;
- } else {
+ else {
/* first desc of a non-ps chain */
sendmp = mp;
sendmp->m_flags |= M_PKTHDR;
@@ -4233,106 +4138,53 @@ ixgbe_rxeof(struct rx_ring *rxr, int count)
sendmp->m_pkthdr.ether_vtag = vtag;
sendmp->m_flags |= M_VLANTAG;
}
- }
- /* Carry head forward */
+ }
+ /* Pass the head pointer on */
if (eop == 0) {
- nh = rxr->rx_buffers[nextp].m_head;
- np = rxr->rx_buffers[nextp].m_pack;
- nh->m_nextpkt = sendmp;
- mp->m_next = np;
+ nbuf->fmp = sendmp;
sendmp = NULL;
+ mp->m_next = nbuf->m_pack;
}
- mh->m_nextpkt = NULL;
}
-
- if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)
- accept_frame = FALSE;
-
- if (accept_frame) {
- ++processed;
- if (eop) {
- --count;
- sendmp->m_pkthdr.rcvif = ifp;
- ifp->if_ipackets++;
- rxr->rx_packets++;
- /* capture data for AIM */
- rxr->bytes += sendmp->m_pkthdr.len;
- rxr->rx_bytes += rxr->bytes;
- if (ifp->if_capenable & IFCAP_RXCSUM)
- ixgbe_rx_checksum(staterr, sendmp);
- else
- sendmp->m_pkthdr.csum_flags = 0;
+ ++processed;
+ /* Sending this frame? */
+ if (eop) {
+ sendmp->m_pkthdr.rcvif = ifp;
+ ifp->if_ipackets++;
+ rxr->rx_packets++;
+ /* capture data for AIM */
+ rxr->bytes += sendmp->m_pkthdr.len;
+ rxr->rx_bytes += sendmp->m_pkthdr.len;
+ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
+ ixgbe_rx_checksum(staterr, sendmp, ptype);
#if __FreeBSD_version >= 800000
- /* Get the RSS Hash */
- sendmp->m_pkthdr.flowid =
- le16toh(cur->wb.lower.hi_dword.rss);
- sendmp->m_flags |= M_FLOWID;
+ sendmp->m_pkthdr.flowid = que->msix;
+ sendmp->m_flags |= M_FLOWID;
#endif
- }
- } else {
- ifp->if_ierrors++;
- /* Reuse loaded DMA map and just update mbuf chain */
- mh->m_len = MHLEN;
- mh->m_flags |= M_PKTHDR;
- mh->m_next = NULL;
- mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz;
- mp->m_data = mp->m_ext.ext_buf;
- if (mp->m_next) { /* Free chain */
- sendmp = mp->m_next;
- m_free(sendmp);
- }
- mp->m_next = NULL;
- if (adapter->max_frame_size <=
- (MCLBYTES - ETHER_ALIGN))
- m_adj(mp, ETHER_ALIGN);
- sendmp = NULL;
}
+next_desc:
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- rxr->last_refreshed = i; /* for updating tail */
+ /* Advance our pointers to the next descriptor. */
if (++i == adapter->num_rx_desc)
i = 0;
- /* Prefetch next descriptor */
- cur = &rxr->rx_base[i];
- prefetch(cur);
- /*
- ** Now send up to the stack,
- ** note that the RX lock is
- ** held thru this call.
- */
- if (sendmp != NULL) {
- /*
- ** Send to the stack if:
- ** - Soft LRO not enabled, or
- ** - no Soft LRO resources, or
- ** - soft lro enqueue fails
- */
- if ((!rxr->lro_enabled) ||
- ((!lro->lro_cnt) || (tcp_lro_rx(lro, sendmp, 0))))
- (*ifp->if_input)(ifp, sendmp);
- }
+ /* Now send to the stack or do LRO */
+ if (sendmp != NULL)
+ ixgbe_rx_input(rxr, ifp, sendmp, ptype);
- /* Replenish every 8 max */
+ /* Every 8 descriptors we go to refresh mbufs */
if (processed == 8) {
- ixgbe_get_buf(rxr, rxr->next_to_check, i);
+ ixgbe_refresh_mbufs(rxr, i);
processed = 0;
- IXGBE_WRITE_REG(&adapter->hw,
- IXGBE_RDT(rxr->me), rxr->last_refreshed);
- rxr->next_to_check = i;
}
-
- /* Next iteration */
- staterr = cur->wb.upper.status_error;
}
- /* Replenish remaining work */
+ /* Refresh any remaining buf structs */
if (processed != 0) {
- ixgbe_get_buf(rxr, rxr->next_to_check, i);
+ ixgbe_refresh_mbufs(rxr, i);
processed = 0;
- IXGBE_WRITE_REG(&adapter->hw,
- IXGBE_RDT(rxr->me), rxr->last_refreshed);
}
rxr->next_to_check = i;
@@ -4340,8 +4192,7 @@ ixgbe_rxeof(struct rx_ring *rxr, int count)
/*
* Flush any outstanding LRO work
*/
- while (!SLIST_EMPTY(&lro->lro_active)) {
- queued = SLIST_FIRST(&lro->lro_active);
+ while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
SLIST_REMOVE_HEAD(&lro->lro_active, next);
tcp_lro_flush(lro, queued);
}
@@ -4349,17 +4200,18 @@ ixgbe_rxeof(struct rx_ring *rxr, int count)
IXGBE_RX_UNLOCK(rxr);
/*
- ** Leaving with more to clean?
- ** then schedule another interrupt.
+ ** We still have cleaning to do?
+ ** Schedule another interrupt if so.
*/
- if (staterr & IXGBE_RXD_STAT_DD) {
- ixgbe_rearm_queues(adapter, (u64)(1 << rxr->msix));
- return TRUE;
+ if ((staterr & IXGBE_RXD_STAT_DD) != 0) {
+ ixgbe_rearm_queues(adapter, (u64)(1 << que->msix));
+ return (TRUE);
}
- return FALSE;
+ return (FALSE);
}
+
/*********************************************************************
*
* Verify that the hardware indicated that the checksum is valid.
@@ -4368,13 +4220,17 @@ ixgbe_rxeof(struct rx_ring *rxr, int count)
*
*********************************************************************/
static void
-ixgbe_rx_checksum(u32 staterr, struct mbuf * mp)
+ixgbe_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype)
{
- u16 status = (u16) staterr;
- u8 errors = (u8) (staterr >> 24);
+ u16 status = (u16) staterr;
+ u8 errors = (u8) (staterr >> 24);
+ bool sctp = FALSE;
+
+ if ((ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 &&
+ (ptype & IXGBE_RXDADV_PKTTYPE_SCTP) != 0)
+ sctp = TRUE;
if (status & IXGBE_RXD_STAT_IPCS) {
- /* Did it pass? */
if (!(errors & IXGBE_RXD_ERR_IPE)) {
/* IP Checksum Good */
mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
@@ -4384,11 +4240,15 @@ ixgbe_rx_checksum(u32 staterr, struct mbuf * mp)
mp->m_pkthdr.csum_flags = 0;
}
if (status & IXGBE_RXD_STAT_L4CS) {
- /* Did it pass? */
+ u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+#if __FreeBSD_version >= 800000
+ if (sctp)
+ type = CSUM_SCTP_VALID;
+#endif
if (!(errors & IXGBE_RXD_ERR_TCPE)) {
- mp->m_pkthdr.csum_flags |=
- (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
- mp->m_pkthdr.csum_data = htons(0xffff);
+ mp->m_pkthdr.csum_flags |= type;
+ if (!sctp)
+ mp->m_pkthdr.csum_data = htons(0xffff);
}
}
return;
@@ -4493,8 +4353,7 @@ static void
ixgbe_enable_intr(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
+ struct ix_queue *que = adapter->queues;
u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
@@ -4528,10 +4387,8 @@ ixgbe_enable_intr(struct adapter *adapter)
** allow for handling the extended (beyond 32) MSIX
** vectors that can be used by 82599
*/
- for (int i = 0; i < adapter->num_queues; i++, rxr++)
- ixgbe_enable_queue(adapter, rxr->msix);
- for (int i = 0; i < adapter->num_queues; i++, txr++)
- ixgbe_enable_queue(adapter, txr->msix);
+ for (int i = 0; i < adapter->num_queues; i++, que++)
+ ixgbe_enable_queue(adapter, que->msix);
IXGBE_WRITE_FLUSH(hw);
@@ -4626,14 +4483,17 @@ ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
static void
ixgbe_configure_ivars(struct adapter *adapter)
{
- struct tx_ring *txr = adapter->tx_rings;
- struct rx_ring *rxr = adapter->rx_rings;
-
- for (int i = 0; i < adapter->num_queues; i++, rxr++)
- ixgbe_set_ivar(adapter, i, rxr->msix, 0);
+ struct ix_queue *que = adapter->queues;
- for (int i = 0; i < adapter->num_queues; i++, txr++)
- ixgbe_set_ivar(adapter, i, txr->msix, 1);
+ for (int i = 0; i < adapter->num_queues; i++, que++) {
+ /* First the RX queue entry */
+ ixgbe_set_ivar(adapter, i, que->msix, 0);
+ /* ... and the TX */
+ ixgbe_set_ivar(adapter, i, que->msix, 1);
+ /* Set an Initial EITR value */
+ IXGBE_WRITE_REG(&adapter->hw,
+ IXGBE_EITR(que->msix), IXGBE_LOW_LATENCY);
+ }
/* For the Link interrupt */
ixgbe_set_ivar(adapter, 1, adapter->linkvec, -1);
@@ -4922,44 +4782,43 @@ static void
ixgbe_print_debug_info(struct adapter *adapter)
{
device_t dev = adapter->dev;
- struct rx_ring *rxr = adapter->rx_rings;
- struct tx_ring *txr = adapter->tx_rings;
- struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ix_queue *que = adapter->queues;
+ struct rx_ring *rxr;
+ struct tx_ring *txr;
+ struct lro_ctrl *lro;
device_printf(dev,"Error Byte Count = %u \n",
IXGBE_READ_REG(hw, IXGBE_ERRBC));
- for (int i = 0; i < adapter->num_queues; i++, rxr++) {
- struct lro_ctrl *lro = &rxr->lro;
- device_printf(dev,"Queue[%d]: rdh = %d, hw rdt = %d\n",
+ for (int i = 0; i < adapter->num_queues; i++, que++) {
+ txr = que->txr;
+ rxr = que->rxr;
+ lro = &rxr->lro;
+ device_printf(dev,"QUE(%d) IRQs Handled: %lu\n",
+ que->msix, (long)que->irqs);
+ device_printf(dev,"RX[%d]: rdh = %d, hw rdt = %d\n",
i, IXGBE_READ_REG(hw, IXGBE_RDH(i)),
IXGBE_READ_REG(hw, IXGBE_RDT(i)));
+ device_printf(dev,"TX[%d] tdh = %d, hw tdt = %d\n", i,
+ IXGBE_READ_REG(hw, IXGBE_TDH(i)),
+ IXGBE_READ_REG(hw, IXGBE_TDT(i)));
device_printf(dev,"RX(%d) Packets Received: %lld\n",
rxr->me, (long long)rxr->rx_packets);
device_printf(dev,"RX(%d) Split RX Packets: %lld\n",
rxr->me, (long long)rxr->rx_split_packets);
device_printf(dev,"RX(%d) Bytes Received: %lu\n",
rxr->me, (long)rxr->rx_bytes);
- device_printf(dev,"RX(%d) IRQ Handled: %lu\n",
- rxr->me, (long)rxr->rx_irq);
device_printf(dev,"RX(%d) LRO Queued= %d\n",
rxr->me, lro->lro_queued);
device_printf(dev,"RX(%d) LRO Flushed= %d\n",
rxr->me, lro->lro_flushed);
device_printf(dev,"RX(%d) HW LRO Merges= %lu\n",
rxr->me, (long)rxr->rsc_num);
- }
-
- for (int i = 0; i < adapter->num_queues; i++, txr++) {
- device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", i,
- IXGBE_READ_REG(hw, IXGBE_TDH(i)),
- IXGBE_READ_REG(hw, IXGBE_TDT(i)));
device_printf(dev,"TX(%d) Packets Sent: %lu\n",
txr->me, (long)txr->total_packets);
- device_printf(dev,"TX(%d) IRQ Handled: %lu\n",
- txr->me, (long)txr->tx_irq);
device_printf(dev,"TX(%d) NO Desc Avail: %lu\n",
- txr->me, (long)txr->no_tx_desc_avail);
+ txr->me, (long)txr->no_desc_avail);
}
device_printf(dev,"Link IRQ Handled: %lu\n",
@@ -5050,174 +4909,3 @@ ixgbe_add_rx_process_limit(struct adapter *adapter, const char *name,
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
}
-
-#ifdef IXGBE_IEEE1588
-
-/*
-** ixgbe_hwtstamp_ioctl - control hardware time stamping
-**
-** Outgoing time stamping can be enabled and disabled. Play nice and
-** disable it when requested, although it shouldn't case any overhead
-** when no packet needs it. At most one packet in the queue may be
-** marked for time stamping, otherwise it would be impossible to tell
-** for sure to which packet the hardware time stamp belongs.
-**
-** Incoming time stamping has to be configured via the hardware
-** filters. Not all combinations are supported, in particular event
-** type has to be specified. Matching the kind of event packet is
-** not supported, with the exception of "all V2 events regardless of
-** level 2 or 4".
-**
-*/
-static int
-ixgbe_hwtstamp_ioctl(struct adapter *adapter, struct ifreq *ifr)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct hwtstamp_ctrl *config;
- u32 tsync_tx_ctl_bit = IXGBE_TSYNCTXCTL_ENABLED;
- u32 tsync_rx_ctl_bit = IXGBE_TSYNCRXCTL_ENABLED;
- u32 tsync_rx_ctl_type = 0;
- u32 tsync_rx_cfg = 0;
- int is_l4 = 0;
- int is_l2 = 0;
- u16 port = 319; /* PTP */
- u32 regval;
-
- config = (struct hwtstamp_ctrl *) ifr->ifr_data;
-
- /* reserved for future extensions */
- if (config->flags)
- return (EINVAL);
-
- switch (config->tx_type) {
- case HWTSTAMP_TX_OFF:
- tsync_tx_ctl_bit = 0;
- break;
- case HWTSTAMP_TX_ON:
- tsync_tx_ctl_bit = IXGBE_TSYNCTXCTL_ENABLED;
- break;
- default:
- return (ERANGE);
- }
-
- switch (config->rx_filter) {
- case HWTSTAMP_FILTER_NONE:
- tsync_rx_ctl_bit = 0;
- break;
- case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
- case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
- case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
- case HWTSTAMP_FILTER_ALL:
- /*
- * register TSYNCRXCFG must be set, therefore it is not
- * possible to time stamp both Sync and Delay_Req messages
- * => fall back to time stamping all packets
- */
- tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_ALL;
- config->rx_filter = HWTSTAMP_FILTER_ALL;
- break;
- case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
- tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L4_V1;
- tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
- is_l4 = 1;
- break;
- case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
- tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L4_V1;
- tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
- is_l4 = 1;
- break;
- case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
- case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
- tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2;
- tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
- is_l2 = 1;
- is_l4 = 1;
- config->rx_filter = HWTSTAMP_FILTER_SOME;
- break;
- case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
- case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
- tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2;
- tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
- is_l2 = 1;
- is_l4 = 1;
- config->rx_filter = HWTSTAMP_FILTER_SOME;
- break;
- case HWTSTAMP_FILTER_PTP_V2_EVENT:
- case HWTSTAMP_FILTER_PTP_V2_SYNC:
- case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
- tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
- config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
- is_l2 = 1;
- break;
- default:
- return -ERANGE;
- }
-
- /* enable/disable TX */
- regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
- regval = (regval & ~IXGBE_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit;
- IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval);
-
- /* enable/disable RX, define which PTP packets are time stamped */
- regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
- regval = (regval & ~IXGBE_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit;
- regval = (regval & ~0xE) | tsync_rx_ctl_type;
- IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval);
- IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCFG, tsync_rx_cfg);
-
- /*
- * Ethertype Filter Queue Filter[0][15:0] = 0x88F7
- * (Ethertype to filter on)
- * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter)
- * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping)
- */
- IXGBE_WRITE_REG(hw, IXGBE_ETQF0, is_l2 ? 0x440088f7 : 0);
-
- /* L4 Queue Filter[0]: only filter by source and destination port */
- IXGBE_WRITE_REG(hw, IXGBE_SPQF0, htons(port));
- IXGBE_WRITE_REG(hw, IXGBE_IMIREXT(0), is_l4 ?
- ((1<<12) | (1<<19) /* bypass size and control flags */) : 0);
- IXGBE_WRITE_REG(hw, IXGBE_IMIR(0), is_l4 ?
- (htons(port)
- | (0<<16) /* immediate interrupt disabled */
- | 0 /* (1<<17) bit cleared: do not bypass
- destination port check */)
- : 0);
- IXGBE_WRITE_REG(hw, IXGBE_FTQF0, is_l4 ?
- (0x11 /* UDP */
- | (1<<15) /* VF not compared */
- | (1<<27) /* Enable Timestamping */
- | (7<<28) /* only source port filter enabled,
- source/target address and protocol
- masked */)
- : ((1<<15) | (15<<28) /* all mask bits set = filter not
- enabled */));
-
- wrfl();
-
- adapter->hwtstamp_ctrl = config;
-
- /* clear TX/RX time stamp registers, just to be sure */
- regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
- regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
-
- return (error);
-}
-
-/*
-** ixgbe_read_clock - read raw cycle counter (to be used by time counter)
-*/
-static cycle_t ixgbe_read_clock(const struct cyclecounter *tc)
-{
- struct adapter *adapter =
- container_of(tc, struct igb_adapter, cycles);
- struct ixgbe_hw *hw = &adapter->hw;
- u64 stamp;
-
- stamp = IXGBE_READ_REG(hw, IXGBE_SYSTIML);
- stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32ULL;
-
- return (stamp);
-}
-
-#endif /* IXGBE_IEEE1588 */
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
index d52eed3..f598b8f 100644
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -176,10 +176,16 @@
#define MSIX_82599_BAR 4
#define IXGBE_TSO_SIZE 65535
#define IXGBE_TX_BUFFER_SIZE ((u32) 1514)
-#define IXGBE_RX_HDR 256
+#define IXGBE_RX_HDR 128
#define IXGBE_VFTA_SIZE 128
#define IXGBE_BR_SIZE 4096
-#define CSUM_OFFLOAD 7 /* Bits in csum flags */
+
+/* Offload bits in mbuf flag */
+#if __FreeBSD_version >= 800000
+#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP)
+#else
+#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP)
+#endif
/* For 6.X code compatibility */
#if !defined(ETHER_BPF_MTAP)
@@ -231,6 +237,7 @@ struct ixgbe_tx_buf {
struct ixgbe_rx_buf {
struct mbuf *m_head;
struct mbuf *m_pack;
+ struct mbuf *fmp;
bus_dmamap_t map;
};
@@ -248,20 +255,34 @@ struct ixgbe_dma_alloc {
};
/*
- * The transmit ring, one per tx queue
+** Driver queue struct: this is the interrupt container
+** for the associated tx and rx ring.
+*/
+struct ix_queue {
+ struct adapter *adapter;
+ u32 msix; /* This queue's MSIX vector */
+ u32 eims; /* This queue's EIMS bit */
+ u32 eitr_setting;
+ struct resource *res;
+ void *tag;
+ struct tx_ring *txr;
+ struct rx_ring *rxr;
+ struct task que_task;
+ struct taskqueue *tq;
+ u64 irqs;
+};
+
+/*
+ * The transmit ring, one per queue
*/
struct tx_ring {
struct adapter *adapter;
struct mtx tx_mtx;
u32 me;
- u32 msix;
bool watchdog_check;
int watchdog_time;
union ixgbe_adv_tx_desc *tx_base;
- volatile u32 tx_hwb;
struct ixgbe_dma_alloc txdma;
- struct task tx_task;
- struct taskqueue *tq;
u32 next_avail_desc;
u32 next_to_clean;
struct ixgbe_tx_buf *tx_buffers;
@@ -272,17 +293,14 @@ struct tx_ring {
#if __FreeBSD_version >= 800000
struct buf_ring *br;
#endif
- /* Interrupt resources */
- void *tag;
- struct resource *res;
#ifdef IXGBE_FDIR
u16 atr_sample;
u16 atr_count;
#endif
+ u32 bytes; /* used for AIM */
+ u32 packets;
/* Soft Stats */
- u32 no_tx_desc_avail;
- u32 no_tx_desc_late;
- u64 tx_irq;
+ u64 no_desc_avail;
u64 total_packets;
};
@@ -294,35 +312,29 @@ struct rx_ring {
struct adapter *adapter;
struct mtx rx_mtx;
u32 me;
- u32 msix;
- u32 payload;
- struct task rx_task;
- struct taskqueue *tq;
union ixgbe_adv_rx_desc *rx_base;
struct ixgbe_dma_alloc rxdma;
struct lro_ctrl lro;
bool lro_enabled;
bool hdr_split;
bool hw_rsc;
- unsigned int last_refreshed;
- unsigned int next_to_check;
+ bool discard;
+ u32 next_to_refresh;
+ u32 next_to_check;
+ char mtx_name[16];
struct ixgbe_rx_buf *rx_buffers;
bus_dma_tag_t rxtag;
bus_dmamap_t spare_map;
- char mtx_name[16];
u32 bytes; /* Used for AIM calc */
- u32 eitr_setting;
-
- /* Interrupt resources */
- void *tag;
- struct resource *res;
+ u32 packets;
/* Soft stats */
u64 rx_irq;
u64 rx_split_packets;
u64 rx_packets;
u64 rx_bytes;
+ u64 rx_discarded;
u64 rsc_num;
#ifdef IXGBE_FDIR
u64 flm;
@@ -331,52 +343,52 @@ struct rx_ring {
/* Our adapter structure */
struct adapter {
- struct ifnet *ifp;
- struct ixgbe_hw hw;
+ struct ifnet *ifp;
+ struct ixgbe_hw hw;
struct ixgbe_osdep osdep;
- struct device *dev;
+ struct device *dev;
- struct resource *pci_mem;
- struct resource *msix_mem;
+ struct resource *pci_mem;
+ struct resource *msix_mem;
/*
* Interrupt resources: this set is
* either used for legacy, or for Link
* when doing MSIX
*/
- void *tag;
- struct resource *res;
+ void *tag;
+ struct resource *res;
- struct ifmedia media;
- struct callout timer;
- int msix;
- int if_flags;
+ struct ifmedia media;
+ struct callout timer;
+ int msix;
+ int if_flags;
- struct mtx core_mtx;
+ struct mtx core_mtx;
- eventhandler_tag vlan_attach;
- eventhandler_tag vlan_detach;
+ eventhandler_tag vlan_attach;
+ eventhandler_tag vlan_detach;
- u16 num_vlans;
- u16 num_queues;
+ u16 num_vlans;
+ u16 num_queues;
/* Info about the board itself */
- u32 optics;
- bool link_active;
- u16 max_frame_size;
- u32 link_speed;
- bool link_up;
- u32 linkvec;
+ u32 optics;
+ bool link_active;
+ u16 max_frame_size;
+ u32 link_speed;
+ bool link_up;
+ u32 linkvec;
/* Mbuf cluster size */
- u32 rx_mbuf_sz;
+ u32 rx_mbuf_sz;
/* Support for pluggable optics */
- bool sfp_probe;
- struct task link_task; /* Link tasklet */
- struct task mod_task; /* SFP tasklet */
- struct task msf_task; /* Multispeed Fiber tasklet */
+ bool sfp_probe;
+ struct task link_task; /* Link tasklet */
+ struct task mod_task; /* SFP tasklet */
+ struct task msf_task; /* Multispeed Fiber */
#ifdef IXGBE_FDIR
int fdir_reinit;
struct task fdir_task;
@@ -384,41 +396,41 @@ struct adapter {
struct taskqueue *tq;
/*
+ ** Queues:
+ ** This is the irq holder, it has
+ ** and RX/TX pair or rings associated
+ ** with it.
+ */
+ struct ix_queue *queues;
+
+ /*
* Transmit rings:
* Allocated at run time, an array of rings.
*/
- struct tx_ring *tx_rings;
- int num_tx_desc;
+ struct tx_ring *tx_rings;
+ int num_tx_desc;
/*
* Receive rings:
* Allocated at run time, an array of rings.
*/
- struct rx_ring *rx_rings;
- int num_rx_desc;
- u64 rx_mask;
- u32 rx_process_limit;
-
-#ifdef IXGBE_IEEE1588
- /* IEEE 1588 precision time support */
- struct cyclecounter cycles;
- struct nettimer clock;
- struct nettime_compare compare;
- struct hwtstamp_ctrl hwtstamp;
-#endif
+ struct rx_ring *rx_rings;
+ int num_rx_desc;
+ u64 que_mask;
+ u32 rx_process_limit;
/* Misc stats maintained by the driver */
- unsigned long dropped_pkts;
- unsigned long mbuf_defrag_failed;
- unsigned long mbuf_header_failed;
- unsigned long mbuf_packet_failed;
- unsigned long no_tx_map_avail;
- unsigned long no_tx_dma_setup;
- unsigned long watchdog_events;
- unsigned long tso_tx;
- unsigned long link_irq;
-
- struct ixgbe_hw_stats stats;
+ unsigned long dropped_pkts;
+ unsigned long mbuf_defrag_failed;
+ unsigned long mbuf_header_failed;
+ unsigned long mbuf_packet_failed;
+ unsigned long no_tx_map_avail;
+ unsigned long no_tx_dma_setup;
+ unsigned long watchdog_events;
+ unsigned long tso_tx;
+ unsigned long link_irq;
+
+ struct ixgbe_hw_stats stats;
};
/* Precision Time Sync (IEEE 1588) defines */
@@ -452,8 +464,8 @@ ixgbe_is_sfp(struct ixgbe_hw *hw)
case ixgbe_phy_sfp_ftl:
case ixgbe_phy_sfp_intel:
case ixgbe_phy_sfp_unknown:
- case ixgbe_phy_tw_tyco:
- case ixgbe_phy_tw_unknown:
+ case ixgbe_phy_sfp_passive_tyco:
+ case ixgbe_phy_sfp_passive_unknown:
return TRUE;
default:
return FALSE;
diff --git a/sys/dev/ixgbe/ixgbe_82598.c b/sys/dev/ixgbe/ixgbe_82598.c
index 12711b0..0570aa5 100644
--- a/sys/dev/ixgbe/ixgbe_82598.c
+++ b/sys/dev/ixgbe/ixgbe_82598.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -59,6 +59,7 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete);
static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw);
+void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw);
s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan,
@@ -164,6 +165,7 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
/* MAC */
mac->ops.start_hw = &ixgbe_start_hw_82598;
+ mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_82598;
mac->ops.reset_hw = &ixgbe_reset_hw_82598;
mac->ops.get_media_type = &ixgbe_get_media_type_82598;
mac->ops.get_supported_physical_layer =
@@ -273,7 +275,8 @@ out:
* @hw: pointer to hardware structure
*
* Starts the hardware using the generic start_hw function.
- * Then set pcie completion timeout
+ * Disables relaxed ordering Then set pcie completion timeout
+ *
**/
s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
{
@@ -287,17 +290,17 @@ s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
/* Disable relaxed ordering */
for (i = 0; ((i < hw->mac.max_tx_queues) &&
- (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
}
for (i = 0; ((i < hw->mac.max_rx_queues) &&
- (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
}
@@ -439,15 +442,23 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
DEBUGFUNC("ixgbe_fc_enable_82598");
/*
- * On 82598 backplane having FC on causes resets while doing
- * KX, so turn off here.
+ * On 82598 having Rx FC on causes resets while doing 1G
+ * so if it's on turn it off once we know link_speed. For
+ * more details see 82598 Specification update.
*/
hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
- if (link_up &&
- link_speed == IXGBE_LINK_SPEED_1GB_FULL &&
- hw->mac.ops.get_media_type(hw) == ixgbe_media_type_backplane) {
- hw->fc.disable_fc_autoneg = TRUE;
- hw->fc.requested_mode = ixgbe_fc_none;
+ if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
+ switch (hw->fc.requested_mode) {
+ case ixgbe_fc_full:
+ hw->fc.requested_mode = ixgbe_fc_tx_pause;
+ break;
+ case ixgbe_fc_rx_pause:
+ hw->fc.requested_mode = ixgbe_fc_none;
+ break;
+ default:
+ /* no change */
+ break;
+ }
}
/* Negotiate the fc mode to use */
@@ -842,12 +853,9 @@ no_phy_reset:
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
- status = ixgbe_disable_pcie_master(hw);
- if (status != IXGBE_SUCCESS) {
- status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
- }
+ ixgbe_disable_pcie_master(hw);
+mac_reset_top:
/*
* Issue global reset to the MAC. This needs to be a SW reset.
* If link reset is used, it might reset the MAC when mng is using it
@@ -868,6 +876,19 @@ no_phy_reset:
DEBUGOUT("Reset polling failed to complete.\n");
}
+ /*
+ * Double resets are required for recovery from certain error
+ * conditions. Between resets, it is necessary to stall to allow time
+ * for any pending HW events to complete. We use 1usec since that is
+ * what is needed for ixgbe_disable_pcie_master(). The second reset
+ * then clears out any effects of those events.
+ */
+ if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
+ hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
+ usec_delay(1);
+ goto mac_reset_top;
+ }
+
msec_delay(50);
gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
@@ -1299,3 +1320,32 @@ static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw)
return IXGBE_SUCCESS;
}
+/**
+ * ixgbe_enable_relaxed_ordering_82598 - enable relaxed ordering
+ * @hw: pointer to hardware structure
+ *
+ **/
+void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw)
+{
+ u32 regval;
+ u32 i;
+
+ DEBUGFUNC("ixgbe_enable_relaxed_ordering_82598");
+
+ /* Enable relaxed ordering */
+ for (i = 0; ((i < hw->mac.max_tx_queues) &&
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+ regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
+ }
+
+ for (i = 0; ((i < hw->mac.max_rx_queues) &&
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+ regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+ }
+
+}
diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c
index 97b655a..8c5ff21 100644
--- a/sys/dev/ixgbe/ixgbe_82599.c
+++ b/sys/dev/ixgbe/ixgbe_82599.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -64,6 +64,7 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw);
+void ixgbe_enable_relaxed_ordering_82599(struct ixgbe_hw *hw);
s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
@@ -267,6 +268,8 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
DEBUGFUNC("ixgbe_get_link_capabilities_82599");
+
+
/*
* Determine link capabilities based on the stored value of AUTOC,
* which represents EEPROM defaults. If AUTOC value has not
@@ -878,7 +881,7 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
{
s32 status = IXGBE_SUCCESS;
- u32 ctrl, ctrl_ext;
+ u32 ctrl;
u32 i;
u32 autoc;
u32 autoc2;
@@ -913,12 +916,9 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
- status = ixgbe_disable_pcie_master(hw);
- if (status != IXGBE_SUCCESS) {
- status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
- }
+ ixgbe_disable_pcie_master(hw);
+mac_reset_top:
/*
* Issue global reset to the MAC. This needs to be a SW reset.
* If link reset is used, it might reset the MAC when mng is using it
@@ -938,10 +938,19 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
status = IXGBE_ERR_RESET_FAILED;
DEBUGOUT("Reset polling failed to complete.\n");
}
- /* Clear PF Reset Done bit so PF/VF Mail Ops can work */
- ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
- ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
- IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+ /*
+ * Double resets are required for recovery from certain error
+ * conditions. Between resets, it is necessary to stall to allow time
+ * for any pending HW events to complete. We use 1usec since that is
+ * what is needed for ixgbe_disable_pcie_master(). The second reset
+ * then clears out any effects of those events.
+ */
+ if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
+ hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
+ usec_delay(1);
+ goto mac_reset_top;
+ }
msec_delay(50);
@@ -981,8 +990,6 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
hw->mac.num_rar_entries = 128;
hw->mac.ops.init_rx_addrs(hw);
-
-
/* Store the permanent SAN mac address */
hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
@@ -1207,6 +1214,9 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
/* Send interrupt when 64 filters are left */
fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+ /* Initialize the drop queue to Rx queue 127 */
+ fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT);
+
switch (pballoc) {
case IXGBE_FDIR_PBALLOC_64K:
/* 2k - 1 perfect filters */
@@ -1886,23 +1896,26 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
* ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
* @hw: pointer to hardware structure
* @input: input bitstream
+ * @input_masks: masks for the input bitstream
+ * @soft_id: software index for the filters
* @queue: queue index to direct traffic to
*
* Note that the caller to this function must lock before calling, since the
* hardware writes must be protected from one another.
**/
s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
- struct ixgbe_atr_input *input,
- u16 soft_id,
- u8 queue)
+ struct ixgbe_atr_input *input,
+ struct ixgbe_atr_input_masks *input_masks,
+ u16 soft_id, u8 queue)
{
u32 fdircmd = 0;
u32 fdirhash;
- u32 src_ipv4, dst_ipv4;
+ u32 src_ipv4 = 0, dst_ipv4 = 0;
u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4;
u16 src_port, dst_port, vlan_id, flex_bytes;
u16 bucket_hash;
u8 l4type;
+ u8 fdirm = 0;
DEBUGFUNC("ixgbe_fdir_add_perfect_filter_82599");
@@ -1959,7 +1972,6 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
/* IPv4 */
ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4);
IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4);
-
}
ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4);
@@ -1968,7 +1980,78 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id |
(flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT)));
IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port |
- (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+ (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+
+ /*
+ * Program the relevant mask registers. If src/dst_port or src/dst_addr
+ * are zero, then assume a full mask for that field. Also assume that
+ * a VLAN of 0 is unspecified, so mask that out as well. L4type
+ * cannot be masked out in this implementation.
+ *
+ * This also assumes IPv4 only. IPv6 masking isn't supported at this
+ * point in time.
+ */
+ if (src_ipv4 == 0)
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff);
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask);
+
+ if (dst_ipv4 == 0)
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff);
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask);
+
+ switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+ case IXGBE_ATR_L4TYPE_TCP:
+ if (src_port == 0)
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff);
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+ input_masks->src_port_mask);
+
+ if (dst_port == 0)
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
+ (0xffff << 16)));
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
+ (input_masks->dst_port_mask << 16)));
+ break;
+ case IXGBE_ATR_L4TYPE_UDP:
+ if (src_port == 0)
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff);
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+ input_masks->src_port_mask);
+
+ if (dst_port == 0)
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
+ (0xffff << 16)));
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
+ (input_masks->src_port_mask << 16)));
+ break;
+ default:
+ /* this already would have failed above */
+ break;
+ }
+
+ /* Program the last mask register, FDIRM */
+ if (input_masks->vlan_id_mask || !vlan_id)
+ /* Mask both VLAN and VLANP - bits 0 and 1 */
+ fdirm |= (IXGBE_FDIRM_VLANID | IXGBE_FDIRM_VLANP);
+
+ if (input_masks->data_mask || !flex_bytes)
+ /* Flex bytes need masking, so mask the whole thing - bit 4 */
+ fdirm |= IXGBE_FDIRM_FLEX;
+
+ /* Now mask VM pool and destination IPv6 - bits 5 and 2 */
+ fdirm |= (IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW;
fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE;
@@ -2063,7 +2146,7 @@ s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw)
for (i = 0; i < hw->mac.max_rx_queues; i++) {
regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
}
@@ -2192,10 +2275,14 @@ sfp_check:
goto out;
switch (hw->phy.type) {
- case ixgbe_phy_tw_tyco:
- case ixgbe_phy_tw_unknown:
+ case ixgbe_phy_sfp_passive_tyco:
+ case ixgbe_phy_sfp_passive_unknown:
physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
break;
+ case ixgbe_phy_sfp_ftl_active:
+ case ixgbe_phy_sfp_active_unknown:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
+ break;
case ixgbe_phy_sfp_avago:
case ixgbe_phy_sfp_ftl:
case ixgbe_phy_sfp_intel:
@@ -2328,3 +2415,30 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
fw_version_out:
return status;
}
+/**
+ * ixgbe_enable_relaxed_ordering_82599 - Enable relaxed ordering
+ * @hw: pointer to hardware structure
+ *
+ **/
+void ixgbe_enable_relaxed_ordering_82599(struct ixgbe_hw *hw)
+{
+ u32 regval;
+ u32 i;
+
+ DEBUGFUNC("ixgbe_enable_relaxed_ordering_82599");
+
+ /* Enable relaxed ordering */
+ for (i = 0; i < hw->mac.max_tx_queues; i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
+ regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
+ }
+
+ for (i = 0; i < hw->mac.max_rx_queues; i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+ regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+ }
+
+}
diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c
index 4464457..a65686e 100644
--- a/sys/dev/ixgbe/ixgbe_api.c
+++ b/sys/dev/ixgbe/ixgbe_api.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -111,6 +111,7 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
case IXGBE_DEV_ID_82599_SFP:
case IXGBE_DEV_ID_82599_CX4:
+ case IXGBE_DEV_ID_82599_T3_LOM:
hw->mac.type = ixgbe_mac_82599EB;
break;
default:
@@ -168,6 +169,20 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_enable_relaxed_ordering - Enables tx relaxed ordering,
+ * which is disabled by default in ixgbe_start_hw();
+ *
+ * @hw: pointer to hardware structure
+ *
+ * Enable relaxed ordering;
+ **/
+void ixgbe_enable_relaxed_ordering(struct ixgbe_hw *hw)
+{
+ if (hw->mac.ops.enable_relaxed_ordering)
+ hw->mac.ops.enable_relaxed_ordering(hw);
+}
+
+/**
* ixgbe_clear_hw_cntrs - Clear hardware counters
* @hw: pointer to hardware structure
*
diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h
index 8ab78ad..48c523c 100644
--- a/sys/dev/ixgbe/ixgbe_api.h
+++ b/sys/dev/ixgbe/ixgbe_api.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw);
s32 ixgbe_init_hw(struct ixgbe_hw *hw);
s32 ixgbe_reset_hw(struct ixgbe_hw *hw);
s32 ixgbe_start_hw(struct ixgbe_hw *hw);
+void ixgbe_enable_relaxed_ordering(struct ixgbe_hw *hw);
s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw);
enum ixgbe_media_type ixgbe_get_media_type(struct ixgbe_hw *hw);
s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr);
@@ -122,6 +123,7 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
u8 queue);
s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
struct ixgbe_atr_input *input,
+ struct ixgbe_atr_input_masks *masks,
u16 soft_id,
u8 queue);
u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key);
diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c
index 89e57d8..217c477 100644
--- a/sys/dev/ixgbe/ixgbe_common.c
+++ b/sys/dev/ixgbe/ixgbe_common.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -474,8 +474,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests
*/
- if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS)
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
+ ixgbe_disable_pcie_master(hw);
return IXGBE_SUCCESS;
}
@@ -2198,10 +2197,14 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
u32 i;
u32 reg_val;
u32 number_of_queues;
- s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
+ s32 status = IXGBE_SUCCESS;
DEBUGFUNC("ixgbe_disable_pcie_master");
+ /* Just jump out if bus mastering is already disabled */
+ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
+ goto out;
+
/* Disable the receive unit by stopping each queue */
number_of_queues = hw->mac.max_rx_queues;
for (i = 0; i < number_of_queues; i++) {
@@ -2217,13 +2220,42 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
- if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
- status = IXGBE_SUCCESS;
+ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
+ goto out;
+ usec_delay(100);
+ }
+
+ DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n");
+ status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
+
+ /*
+ * The GIO Master Disable bit didn't clear. There are multiple reasons
+ * for this listed in the datasheet 5.2.5.3.2 Master Disable, and they
+ * all require a double reset to recover from. Before proceeding, we
+ * first wait a little more to try to ensure that, at a minimum, the
+ * PCIe block has no transactions pending.
+ */
+ for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
+ if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) &
+ IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
break;
- }
usec_delay(100);
}
+ if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT)
+ DEBUGOUT("PCIe transaction pending bit also did not clear.\n");
+
+ /*
+ * Two consecutive resets are required via CTRL.RST per datasheet
+ * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine
+ * of this need. The first reset prevents new master requests from
+ * being issued by our device. We then must wait 1usec for any
+ * remaining completions from the PCIe bus to trickle in, and then reset
+ * again to clear out any effects they may have had on our device.
+ */
+ hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
+
+out:
return status;
}
@@ -2695,6 +2727,10 @@ s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
u32 first_empty_slot = 0;
s32 regindex;
+ /* short cut the special case */
+ if (vlan == 0)
+ return 0;
+
/*
* Search for the vlan id in the VLVF entries. Save off the first empty
* slot found along the way
@@ -2717,7 +2753,7 @@ s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
regindex = first_empty_slot;
else {
DEBUGOUT("No space in VLVF.\n");
- regindex = -1;
+ regindex = IXGBE_ERR_NO_SPACE;
}
}
@@ -2738,8 +2774,11 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
{
s32 regindex;
u32 bitindex;
+ u32 vfta;
u32 bits;
u32 vt;
+ u32 targetbit;
+ bool vfta_changed = FALSE;
DEBUGFUNC("ixgbe_set_vfta_generic");
@@ -2749,6 +2788,7 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
/*
* this is a 2 part operation - first the VFTA, then the
* VLVF and VLVFB if VT Mode is set
+ * We don't write the VFTA until we know the VLVF part succeeded.
*/
/* Part 1
@@ -2759,13 +2799,20 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
*/
regindex = (vlan >> 5) & 0x7F;
bitindex = vlan & 0x1F;
- bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
- if (vlan_on)
- bits |= (1 << bitindex);
- else
- bits &= ~(1 << bitindex);
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+ targetbit = (1 << bitindex);
+ vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+ if (vlan_on) {
+ if (!(vfta & targetbit)) {
+ vfta |= targetbit;
+ vfta_changed = TRUE;
+ }
+ } else {
+ if ((vfta & targetbit)) {
+ vfta &= ~targetbit;
+ vfta_changed = TRUE;
+ }
+ }
/* Part 2
* If VT Mode is set
@@ -2777,61 +2824,84 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
*/
vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
if (vt & IXGBE_VT_CTL_VT_ENABLE) {
- if (vlan == 0) {
- regindex = 0;
- } else {
- regindex = ixgbe_find_vlvf_slot(hw, vlan);
- if (regindex < 0)
- goto out;
- }
+ s32 vlvf_index;
+
+ vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
+ if (vlvf_index < 0)
+ return vlvf_index;
if (vlan_on) {
/* set the pool bit */
if (vind < 32) {
bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB(regindex*2));
+ IXGBE_VLVFB(vlvf_index*2));
bits |= (1 << vind);
IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB(regindex*2),
+ IXGBE_VLVFB(vlvf_index*2),
bits);
} else {
bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB((regindex*2)+1));
- bits |= (1 << vind);
+ IXGBE_VLVFB((vlvf_index*2)+1));
+ bits |= (1 << (vind-32));
IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB((regindex*2)+1),
+ IXGBE_VLVFB((vlvf_index*2)+1),
bits);
}
} else {
/* clear the pool bit */
if (vind < 32) {
bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB(regindex*2));
+ IXGBE_VLVFB(vlvf_index*2));
bits &= ~(1 << vind);
IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB(regindex*2),
+ IXGBE_VLVFB(vlvf_index*2),
bits);
bits |= IXGBE_READ_REG(hw,
- IXGBE_VLVFB((regindex*2)+1));
+ IXGBE_VLVFB((vlvf_index*2)+1));
} else {
bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB((regindex*2)+1));
- bits &= ~(1 << vind);
+ IXGBE_VLVFB((vlvf_index*2)+1));
+ bits &= ~(1 << (vind-32));
IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB((regindex*2)+1),
+ IXGBE_VLVFB((vlvf_index*2)+1),
bits);
bits |= IXGBE_READ_REG(hw,
- IXGBE_VLVFB(regindex*2));
+ IXGBE_VLVFB(vlvf_index*2));
}
}
- if (bits)
- IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
+ /*
+ * If there are still bits set in the VLVFB registers
+ * for the VLAN ID indicated we need to see if the
+ * caller is requesting that we clear the VFTA entry bit.
+ * If the caller has requested that we clear the VFTA
+ * entry bit but there are still pools/VFs using this VLAN
+ * ID entry then ignore the request. We're not worried
+ * about the case where we're turning the VFTA VLAN ID
+ * entry bit on, only when requested to turn it off as
+ * there may be multiple pools and/or VFs using the
+ * VLAN ID entry. In that case we cannot clear the
+ * VFTA bit until all pools/VFs using that VLAN ID have also
+ * been cleared. This will be indicated by "bits" being
+ * zero.
+ */
+ if (bits) {
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
(IXGBE_VLVF_VIEN | vlan));
+ if (!vlan_on) {
+ /* someone wants to clear the vfta entry
+ * but some pools/VFs are still using it.
+ * Ignore it. */
+ vfta_changed = FALSE;
+ }
+ }
else
- IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
}
-out:
+
+ if (vfta_changed)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
+
return IXGBE_SUCCESS;
}
@@ -2869,14 +2939,23 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
* Reads the links register to determine if link is up and the current speed
**/
s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up, bool link_up_wait_to_complete)
+ bool *link_up, bool link_up_wait_to_complete)
{
- u32 links_reg;
+ u32 links_reg, links_orig;
u32 i;
DEBUGFUNC("ixgbe_check_mac_link_generic");
+ /* clear the old state */
+ links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
+
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+
+ if (links_orig != links_reg) {
+ DEBUGOUT2("LINKS changed from %08X to %08X\n",
+ links_orig, links_reg);
+ }
+
if (link_up_wait_to_complete) {
for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
if (links_reg & IXGBE_LINKS_UP) {
diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c
index 9bab98d..7ec2981 100644
--- a/sys/dev/ixgbe/ixgbe_phy.c
+++ b/sys/dev/ixgbe/ixgbe_phy.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -77,7 +77,8 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic;
phy->sfp_type = ixgbe_sfp_type_unknown;
-
+ phy->ops.check_overtemp = &ixgbe_tn_check_overtemp;
+ phy->ops.set_low_power_state = &ixgbe_tn_set_low_power_state;
return IXGBE_SUCCESS;
}
@@ -241,13 +242,19 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
IXGBE_MDIO_PHY_XS_DEV_TYPE,
IXGBE_MDIO_PHY_XS_RESET);
- /* Poll for reset bit to self-clear indicating reset is complete */
- for (i = 0; i < 500; i++) {
- msec_delay(1);
+ /*
+ * Poll for reset bit to self-clear indicating reset is complete.
+ * Some PHYs could take up to 3 seconds to complete and need about
+ * 1.7 usec delay after the reset is complete.
+ */
+ for (i = 0; i < 30; i++) {
+ msec_delay(100);
hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl);
- if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET))
+ if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) {
+ usec_delay(2);
break;
+ }
}
if (ctrl & IXGBE_MDIO_PHY_XS_RESET) {
@@ -922,6 +929,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
u8 comp_codes_10g = 0;
u8 oui_bytes[3] = {0, 0, 0};
u8 cable_tech = 0;
+ u8 cable_spec = 0;
u16 enforce_sfp = 0;
DEBUGFUNC("ixgbe_identify_sfp_module_generic");
@@ -968,6 +976,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
* 4 SFP_DA_CORE1 - 82599-specific
* 5 SFP_SR/LR_CORE0 - 82599-specific
* 6 SFP_SR/LR_CORE1 - 82599-specific
+ * 7 SFP_act_lmt_DA_CORE0 - 82599-specific
+ * 8 SFP_act_lmt_DA_CORE1 - 82599-specific
*/
if (hw->mac.type == ixgbe_mac_82598EB) {
if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
@@ -979,29 +989,40 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
else
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
} else if (hw->mac.type == ixgbe_mac_82599EB) {
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
if (hw->bus.lan_id == 0)
hw->phy.sfp_type =
ixgbe_sfp_type_da_cu_core0;
else
hw->phy.sfp_type =
ixgbe_sfp_type_da_cu_core1;
- else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_srlr_core0;
- else
+ } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
+ hw->phy.ops.read_i2c_eeprom(
+ hw, IXGBE_SFF_CABLE_SPEC_COMP,
+ &cable_spec);
+ if (cable_spec &
+ IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_act_lmt_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_act_lmt_core1;
+ } else
hw->phy.sfp_type =
- ixgbe_sfp_type_srlr_core1;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ ixgbe_sfp_type_unknown;
+ } else if (comp_codes_10g &
+ (IXGBE_SFF_10GBASESR_CAPABLE |
+ IXGBE_SFF_10GBASELR_CAPABLE)) {
if (hw->bus.lan_id == 0)
hw->phy.sfp_type =
ixgbe_sfp_type_srlr_core0;
else
hw->phy.sfp_type =
ixgbe_sfp_type_srlr_core1;
- else
+ } else {
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ }
}
if (hw->phy.sfp_type != stored_sfp_type)
@@ -1036,10 +1057,14 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
switch (vendor_oui) {
case IXGBE_SFF_VENDOR_OUI_TYCO:
if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.type = ixgbe_phy_tw_tyco;
+ hw->phy.type =
+ ixgbe_phy_sfp_passive_tyco;
break;
case IXGBE_SFF_VENDOR_OUI_FTL:
- hw->phy.type = ixgbe_phy_sfp_ftl;
+ if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
+ hw->phy.type = ixgbe_phy_sfp_ftl_active;
+ else
+ hw->phy.type = ixgbe_phy_sfp_ftl;
break;
case IXGBE_SFF_VENDOR_OUI_AVAGO:
hw->phy.type = ixgbe_phy_sfp_avago;
@@ -1049,15 +1074,20 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
break;
default:
if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.type = ixgbe_phy_tw_unknown;
+ hw->phy.type =
+ ixgbe_phy_sfp_passive_unknown;
+ else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
+ hw->phy.type =
+ ixgbe_phy_sfp_active_unknown;
else
hw->phy.type = ixgbe_phy_sfp_unknown;
break;
}
}
- /* All passive DA cables are supported */
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
+ /* Allow any DA cable vendor */
+ if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
+ IXGBE_SFF_DA_ACTIVE_CABLE)) {
status = IXGBE_SUCCESS;
goto out;
}
@@ -1108,6 +1138,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
u16 *data_offset)
{
u16 sfp_id;
+ u16 sfp_type = hw->phy.sfp_type;
DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets");
@@ -1121,6 +1152,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
(hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
return IXGBE_ERR_SFP_NOT_SUPPORTED;
+ /* Limiting active cables must be initialized as SR modules */
+ if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0)
+ sfp_type = ixgbe_sfp_type_srlr_core0;
+ else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1)
+ sfp_type = ixgbe_sfp_type_srlr_core1;
+
/* Read offset to PHY init contents */
hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
@@ -1137,7 +1174,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
hw->eeprom.ops.read(hw, *list_offset, &sfp_id);
while (sfp_id != IXGBE_PHY_INIT_END_NL) {
- if (sfp_id == hw->phy.sfp_type) {
+ if (sfp_id == sfp_type) {
(*list_offset)++;
hw->eeprom.ops.read(hw, *list_offset, data_offset);
if ((!*data_offset) || (*data_offset == 0xFFFF)) {
@@ -1722,3 +1759,56 @@ void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
/* Put the i2c bus back to default state */
ixgbe_i2c_stop(hw);
}
+
+/**
+ * ixgbe_check_overtemp - Checks if an overtemp occured.
+ * @hw: pointer to hardware structure
+ *
+ * Checks if the LASI temp alarm status was triggered due to overtemp
+ **/
+s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_SUCCESS;
+ u16 phy_data = 0;
+
+ DEBUGFUNC("ixgbe_tn_check_overtemp");
+
+ if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
+ goto out;
+
+ /* Check that the LASI temp alarm status was triggered */
+ hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data);
+
+ if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
+ goto out;
+
+ status = IXGBE_ERR_OVERTEMP;
+out:
+ return status;
+}
+
+
+/**
+ * ixgbe_set_tn_low_power_state - Sets the teranetics phy into low power state
+ * @hw: pointer to hardware structure
+ *
+ * Sets the phy into low power mode when LASI temp alarm status is triggered
+ **/
+s32 ixgbe_tn_set_low_power_state(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_SUCCESS;
+ u16 phy_data = 0;
+
+ DEBUGFUNC("ixgbe_set_tn_low_power_state");
+
+ /* Set the phy into low power mode */
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_CONTROL_ADDR,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data);
+ phy_data |= IXGBE_MDIO_PHY_LOW_POWER_MODE;
+ hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_CONTROL_ADDR,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE, phy_data);
+
+ return status;
+}
+
diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h
index 39f3bc8..8f49aa8 100644
--- a/sys/dev/ixgbe/ixgbe_phy.h
+++ b/sys/dev/ixgbe/ixgbe_phy.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -47,9 +47,12 @@
#define IXGBE_SFF_1GBE_COMP_CODES 0x6
#define IXGBE_SFF_10GBE_COMP_CODES 0x3
#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8
+#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C
/* Bitmasks */
#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4
+#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8
+#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4
#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
#define IXGBE_SFF_1GBASELX_CAPABLE 0x2
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
@@ -84,6 +87,9 @@
#define IXGBE_I2C_T_SU_STO 4
#define IXGBE_I2C_T_BUF 5
+#define IXGBE_TN_LASI_STATUS_REG 0x9005
+#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008
+
s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
@@ -119,6 +125,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
u16 *list_offset,
u16 *data_offset);
+s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw);
+s32 ixgbe_tn_set_low_power_state(struct ixgbe_hw *hw);
s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h
index 0b10119..2e1f062 100644
--- a/sys/dev/ixgbe/ixgbe_type.h
+++ b/sys/dev/ixgbe/ixgbe_type.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2009, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -57,9 +57,11 @@
#define IXGBE_DEV_ID_82599_KX4 0x10F7
#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
+#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
#define IXGBE_DEV_ID_82599_CX4 0x10F9
#define IXGBE_DEV_ID_82599_SFP 0x10FB
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
+#define IXGBE_DEV_ID_82599_T3_LOM 0x151C
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -89,7 +91,7 @@
/* General Receive Control */
#define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */
-#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */
+#define IXGBE_GRC_APME 0x00000002 /* APM enabled in EEPROM */
#define IXGBE_VPDDIAG0 0x10204
#define IXGBE_VPDDIAG1 0x10208
@@ -198,6 +200,7 @@
#define IXGBE_RFCTL 0x05008
#define IXGBE_DRECCCTL 0x02F08
#define IXGBE_DRECCCTL_DISABLE 0
+
/* Multicast Table Array - 128 entries */
#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4))
#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
@@ -334,7 +337,7 @@
/* Wake Up Control */
#define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */
#define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */
-#define IXGBE_WUC_ADVD3WUC 0x00000010 /* D3Cold wake up cap. enable*/
+#define IXGBE_WUC_WKEN 0x00000010 /* Enable PE_WAKE_N pin assertion */
/* Wake Up Filter Control */
#define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
@@ -736,6 +739,12 @@
#define IXGBE_GCR_CMPL_TMOUT_RESEND 0x00010000
#define IXGBE_GCR_CAP_VER2 0x00040000
+#define IXGBE_GCR_EXT_MSIX_EN 0x80000000
+#define IXGBE_GCR_EXT_VT_MODE_16 0x00000001
+#define IXGBE_GCR_EXT_VT_MODE_32 0x00000002
+#define IXGBE_GCR_EXT_VT_MODE_64 0x00000003
+#define IXGBE_GCR_EXT_SRIOV (IXGBE_GCR_EXT_MSIX_EN | \
+ IXGBE_GCR_EXT_VT_MODE_64)
/* Time Sync Registers */
#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */
#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */
@@ -889,6 +898,8 @@
#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */
#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI */
+#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC enabled */
+#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */
/* RQTC Bit Masks and Shifts */
#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4)
@@ -1020,7 +1031,9 @@
#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */
#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */
#define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */
+#define IXGBE_MDIO_PHY_SET_LOW_POWER_MODE 0x0800 /* Set low power mode */
+#define IXGBE_MDIO_PMA_PMD_CONTROL_ADDR 0x0000 /* PMA/PMD Control Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
@@ -1369,10 +1382,12 @@
* EAPOL 802.1x (0x888e): Filter 0
* FCoE (0x8906): Filter 2
* 1588 (0x88f7): Filter 3
+ * FIP (0x8914): Filter 4
*/
#define IXGBE_ETQF_FILTER_EAPOL 0
#define IXGBE_ETQF_FILTER_FCOE 2
#define IXGBE_ETQF_FILTER_1588 3
+#define IXGBE_ETQF_FILTER_FIP 4
/* VLAN Control Bit Masks */
#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */
#define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */
@@ -1476,6 +1491,7 @@
#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+
/* LINKS Bit Masks */
#define IXGBE_LINKS_KX_AN_COMP 0x80000000
#define IXGBE_LINKS_UP 0x40000000
@@ -1655,6 +1671,8 @@
#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt. WWN base exists */
/* PCI Bus Info */
+#define IXGBE_PCI_DEVICE_STATUS 0xAA
+#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020
#define IXGBE_PCI_LINK_STATUS 0xB2
#define IXGBE_PCI_DEVICE_CONTROL2 0xC8
#define IXGBE_PCI_LINK_WIDTH 0x3F0
@@ -1787,6 +1805,7 @@
#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */
#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */
#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_4TC_4TQ 0x8 /* 4 TC if RT_ENA and VT_ENA */
#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
/* Receive Descriptor bit definitions */
@@ -2000,10 +2019,9 @@ enum ixgbe_fdir_pballoc_type {
#define IXGBE_FDIRM_VLANID 0x00000001
#define IXGBE_FDIRM_VLANP 0x00000002
#define IXGBE_FDIRM_POOL 0x00000004
-#define IXGBE_FDIRM_L3P 0x00000008
-#define IXGBE_FDIRM_L4P 0x00000010
-#define IXGBE_FDIRM_FLEX 0x00000020
-#define IXGBE_FDIRM_DIPv6 0x00000040
+#define IXGBE_FDIRM_L4P 0x00000008
+#define IXGBE_FDIRM_FLEX 0x00000010
+#define IXGBE_FDIRM_DIPv6 0x00000020
#define IXGBE_FDIRFREE_FREE_MASK 0xFFFF
#define IXGBE_FDIRFREE_FREE_SHIFT 0
@@ -2218,6 +2236,8 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800
#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
+#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000
+
/* Software ATR hash keys */
#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D
@@ -2258,6 +2278,15 @@ struct ixgbe_atr_input {
u8 byte_stream[42];
};
+struct ixgbe_atr_input_masks {
+ u32 src_ip_mask;
+ u32 dst_ip_mask;
+ u16 src_port_mask;
+ u16 dst_port_mask;
+ u16 vlan_id_mask;
+ u16 data_mask;
+};
+
enum ixgbe_eeprom_type {
ixgbe_eeprom_uninitialized = 0,
ixgbe_eeprom_spi,
@@ -2281,10 +2310,12 @@ enum ixgbe_phy_type {
ixgbe_phy_qt,
ixgbe_phy_xaui,
ixgbe_phy_nl,
- ixgbe_phy_tw_tyco,
- ixgbe_phy_tw_unknown,
+ ixgbe_phy_sfp_passive_tyco,
+ ixgbe_phy_sfp_passive_unknown,
+ ixgbe_phy_sfp_active_unknown,
ixgbe_phy_sfp_avago,
ixgbe_phy_sfp_ftl,
+ ixgbe_phy_sfp_ftl_active,
ixgbe_phy_sfp_unknown,
ixgbe_phy_sfp_intel,
ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/
@@ -2312,6 +2343,8 @@ enum ixgbe_sfp_type {
ixgbe_sfp_type_da_cu_core1 = 4,
ixgbe_sfp_type_srlr_core0 = 5,
ixgbe_sfp_type_srlr_core1 = 6,
+ ixgbe_sfp_type_da_act_lmt_core0 = 7,
+ ixgbe_sfp_type_da_act_lmt_core1 = 8,
ixgbe_sfp_type_not_present = 0xFFFE,
ixgbe_sfp_type_unknown = 0xFFFF
};
@@ -2354,25 +2387,25 @@ enum ixgbe_bus_type {
/* PCI bus speeds */
enum ixgbe_bus_speed {
ixgbe_bus_speed_unknown = 0,
- ixgbe_bus_speed_33,
- ixgbe_bus_speed_66,
- ixgbe_bus_speed_100,
- ixgbe_bus_speed_120,
- ixgbe_bus_speed_133,
- ixgbe_bus_speed_2500,
- ixgbe_bus_speed_5000,
+ ixgbe_bus_speed_33 = 33,
+ ixgbe_bus_speed_66 = 66,
+ ixgbe_bus_speed_100 = 100,
+ ixgbe_bus_speed_120 = 120,
+ ixgbe_bus_speed_133 = 133,
+ ixgbe_bus_speed_2500 = 2500,
+ ixgbe_bus_speed_5000 = 5000,
ixgbe_bus_speed_reserved
};
/* PCI bus widths */
enum ixgbe_bus_width {
ixgbe_bus_width_unknown = 0,
- ixgbe_bus_width_pcie_x1,
- ixgbe_bus_width_pcie_x2,
+ ixgbe_bus_width_pcie_x1 = 1,
+ ixgbe_bus_width_pcie_x2 = 2,
ixgbe_bus_width_pcie_x4 = 4,
ixgbe_bus_width_pcie_x8 = 8,
- ixgbe_bus_width_32,
- ixgbe_bus_width_64,
+ ixgbe_bus_width_32 = 32,
+ ixgbe_bus_width_64 = 64,
ixgbe_bus_width_reserved
};
@@ -2503,6 +2536,7 @@ struct ixgbe_mac_operations {
s32 (*reset_hw)(struct ixgbe_hw *);
s32 (*start_hw)(struct ixgbe_hw *);
s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
+ void (*enable_relaxed_ordering)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
@@ -2570,6 +2604,8 @@ struct ixgbe_phy_operations {
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
void (*i2c_bus_clear)(struct ixgbe_hw *);
+ s32 (*check_overtemp)(struct ixgbe_hw *);
+ s32 (*set_low_power_state)(struct ixgbe_hw *);
};
struct ixgbe_eeprom_info {
@@ -2580,6 +2616,7 @@ struct ixgbe_eeprom_info {
u16 address_bits;
};
+#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
struct ixgbe_mac_info {
struct ixgbe_mac_operations ops;
enum ixgbe_mac_type type;
@@ -2603,6 +2640,7 @@ struct ixgbe_mac_info {
u32 orig_autoc2;
bool orig_link_settings_stored;
bool autotry_restart;
+ u8 flags;
};
struct ixgbe_phy_info {
@@ -2668,6 +2706,8 @@ struct ixgbe_hw {
#define IXGBE_ERR_NO_SAN_ADDR_PTR -22
#define IXGBE_ERR_FDIR_REINIT_FAILED -23
#define IXGBE_ERR_EEPROM_VERSION -24
+#define IXGBE_ERR_NO_SPACE -25
+#define IXGBE_ERR_OVERTEMP -26
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
diff --git a/sys/dev/le/am79900var.h b/sys/dev/le/am79900var.h
index 196667e..79ab330 100644
--- a/sys/dev/le/am79900var.h
+++ b/sys/dev/le/am79900var.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/le/am7990var.h b/sys/dev/le/am7990var.h
index 8b2c8bf..24cbfe0 100644
--- a/sys/dev/le/am7990var.h
+++ b/sys/dev/le/am7990var.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/le/if_le_ledma.c b/sys/dev/le/if_le_ledma.c
index b07e610..7b09366 100644
--- a/sys/dev/le/if_le_ledma.c
+++ b/sys/dev/le/if_le_ledma.c
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/le/lancevar.h b/sys/dev/le/lancevar.h
index b524596..a0d3939 100644
--- a/sys/dev/le/lancevar.h
+++ b/sys/dev/le/lancevar.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index 21354ef..57e0d3d 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -168,8 +168,8 @@ malo_bar0_read4(struct malo_softc *sc, bus_size_t off)
static void
malo_bar0_write4(struct malo_softc *sc, bus_size_t off, uint32_t val)
{
- DPRINTF(sc, MALO_DEBUG_FW, "%s: off 0x%zx val 0x%x\n",
- __func__, off, val);
+ DPRINTF(sc, MALO_DEBUG_FW, "%s: off 0x%jx val 0x%x\n",
+ __func__, (intmax_t)off, val);
bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val);
}
diff --git a/sys/dev/mfi/mfi_cam.c b/sys/dev/mfi/mfi_cam.c
index 83a8e4e..fe1ffe5 100644
--- a/sys/dev/mfi/mfi_cam.c
+++ b/sys/dev/mfi/mfi_cam.c
@@ -95,6 +95,7 @@ static driver_t mfip_driver = {
};
DRIVER_MODULE(mfip, mfi, mfip_driver, mfip_devclass, 0, 0);
MODULE_DEPEND(mfip, cam, 1, 1, 1);
+MODULE_DEPEND(mfip, mfi, 1, 1, 1);
#define ccb_mfip_ptr sim_priv.entries[0].ptr
diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c
index 5f0b341..685aa0b 100644
--- a/sys/dev/mfi/mfi_pci.c
+++ b/sys/dev/mfi/mfi_pci.c
@@ -105,6 +105,7 @@ static driver_t mfi_pci_driver = {
static devclass_t mfi_devclass;
DRIVER_MODULE(mfi, pci, mfi_pci_driver, mfi_devclass, 0, 0);
+MODULE_VERSION(mfi, 1);
struct mfi_ident {
uint16_t vendor;
diff --git a/sys/dev/mii/bmtphyreg.h b/sys/dev/mii/bmtphyreg.h
index 223d631..6aa141d 100644
--- a/sys/dev/mii/bmtphyreg.h
+++ b/sys/dev/mii/bmtphyreg.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index ddbec67..97a423c 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -72,8 +72,10 @@ struct brgphy_softc {
int mii_model;
int mii_rev;
int serdes_flags; /* Keeps track of the serdes type used */
-#define BRGPHY_5706S 0x0001
-#define BRGPHY_5708S 0x0002
+#define BRGPHY_5706S 0x0001
+#define BRGPHY_5708S 0x0002
+#define BRGPHY_NOANWAIT 0x0004
+#define BRGPHY_5709S 0x0008
int bce_phy_flags; /* PHY flags transferred from the MAC driver */
};
@@ -138,10 +140,28 @@ static const struct mii_phydesc brgphys[] = {
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
+ MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S),
MII_PHY_DESC(BROADCOM2, BCM5906),
MII_PHY_END
};
+#define HS21_PRODUCT_ID "IBM eServer BladeCenter HS21"
+#define HS21_BCM_CHIPID 0x57081021
+
+static int
+detect_hs21(struct bce_softc *bce_sc)
+{
+ char *sysenv;
+
+ if (bce_sc->bce_chipid != HS21_BCM_CHIPID)
+ return (0);
+ sysenv = getenv("smbios.system.product");
+ if (sysenv == NULL)
+ return (0);
+ if (strncmp(sysenv, HS21_PRODUCT_ID, strlen(HS21_PRODUCT_ID)) != 0)
+ return (0);
+ return (1);
+}
/* Search for our PHY in the list of known PHYs */
static int
@@ -198,30 +218,34 @@ brgphy_attach(device_t dev)
break;
case MII_OUI_xxBROADCOM:
switch (bsc->mii_model) {
- case MII_MODEL_xxBROADCOM_BCM5706:
- case MII_MODEL_xxBROADCOM_BCM5714:
- /*
- * The 5464 PHY used in the 5706 supports both copper
- * and fiber interfaces over GMII. Need to check the
- * shadow registers to see which mode is actually
- * in effect, and therefore whether we have 5706C or
- * 5706S.
- */
- PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
- BRGPHY_SHADOW_1C_MODE_CTRL);
- if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
- BRGPHY_SHADOW_1C_ENA_1000X) {
- bsc->serdes_flags |= BRGPHY_5706S;
- sc->mii_flags |= MIIF_HAVEFIBER;
- }
- break;
+ case MII_MODEL_xxBROADCOM_BCM5706:
+ case MII_MODEL_xxBROADCOM_BCM5714:
+ /*
+ * The 5464 PHY used in the 5706 supports both copper
+ * and fiber interfaces over GMII. Need to check the
+ * shadow registers to see which mode is actually
+ * in effect, and therefore whether we have 5706C or
+ * 5706S.
+ */
+ PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
+ BRGPHY_SHADOW_1C_MODE_CTRL);
+ if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
+ BRGPHY_SHADOW_1C_ENA_1000X) {
+ bsc->serdes_flags |= BRGPHY_5706S;
+ sc->mii_flags |= MIIF_HAVEFIBER;
+ }
+ break;
} break;
case MII_OUI_xxBROADCOM_ALT1:
switch (bsc->mii_model) {
- case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
- bsc->serdes_flags |= BRGPHY_5708S;
- sc->mii_flags |= MIIF_HAVEFIBER;
- break;
+ case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
+ bsc->serdes_flags |= BRGPHY_5708S;
+ sc->mii_flags |= MIIF_HAVEFIBER;
+ break;
+ case MII_MODEL_xxBROADCOM_ALT1_BCM5709S:
+ bsc->serdes_flags |= BRGPHY_5709S;
+ sc->mii_flags |= MIIF_HAVEFIBER;
+ break;
} break;
default:
device_printf(dev, "Unrecognized OUI for PHY!\n");
@@ -291,6 +315,19 @@ brgphy_attach(device_t dev)
if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0);
printf("2500baseSX-FDX, ");
+ } else if ((bsc->serdes_flags & BRGPHY_5708S) && bce_sc &&
+ (detect_hs21(bce_sc) != 0)) {
+ /*
+ * There appears to be certain silicon revision
+ * in IBM HS21 blades that is having issues with
+ * this driver wating for the auto-negotiation to
+ * complete. This happens with a specific chip id
+ * only and when the 1000baseSX-FDX is the only
+ * mode. Workaround this issue since it's unlikely
+ * to be ever addressed.
+ */
+ printf("auto-neg workaround, ");
+ bsc->serdes_flags |= BRGPHY_NOANWAIT;
}
}
@@ -544,7 +581,8 @@ brgphy_status(struct mii_softc *sc)
/* Autoneg is still in progress. */
if ((bmcr & BRGPHY_BMCR_AUTOEN) &&
- (bmsr & BRGPHY_BMSR_ACOMP) == 0) {
+ (bmsr & BRGPHY_BMSR_ACOMP) == 0 &&
+ (bsc->serdes_flags & BRGPHY_NOANWAIT) == 0) {
/* Erg, still trying, I guess... */
mii->mii_media_active |= IFM_NONE;
goto brgphy_status_exit;
@@ -599,6 +637,7 @@ brgphy_status(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
+ /* Check for MRBE auto-negotiated speed results. */
switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) {
case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10:
mii->mii_media_active |= IFM_10_FL; break;
@@ -610,11 +649,40 @@ brgphy_status(struct mii_softc *sc)
mii->mii_media_active |= IFM_2500_SX; break;
}
+ /* Check for MRBE auto-negotiated duplex results. */
if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX)
mii->mii_media_active |= IFM_FDX;
else
mii->mii_media_active |= IFM_HDX;
- }
+
+ } else if (bsc->serdes_flags & BRGPHY_5709S) {
+
+ /* Select GP Status Block of the AN MMD, get autoneg results. */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_GP_STATUS);
+ xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
+
+ /* Restore IEEE0 block (assumed in all brgphy(4) code). */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+
+ /* Check for MRBE auto-negotiated speed results. */
+ switch (xstat & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) {
+ case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10:
+ mii->mii_media_active |= IFM_10_FL; break;
+ case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100:
+ mii->mii_media_active |= IFM_100_FX; break;
+ case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G:
+ mii->mii_media_active |= IFM_1000_SX; break;
+ case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G:
+ mii->mii_media_active |= IFM_2500_SX; break;
+ }
+
+ /* Check for MRBE auto-negotiated duplex results. */
+ if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
+ }
+
}
#if 0
@@ -935,6 +1003,7 @@ brgphy_reset(struct mii_softc *sc)
struct bge_softc *bge_sc = NULL;
struct bce_softc *bce_sc = NULL;
struct ifnet *ifp;
+ int val;
/* Perform a standard PHY reset. */
mii_phy_reset(sc);
@@ -1057,7 +1126,49 @@ brgphy_reset(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
BRGPHY_5708S_DIG_PG0);
}
- } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
+ } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709 &&
+ (bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) {
+
+ /* Select the SerDes Digital block of the AN MMD. */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_SERDES_DIG);
+ val = PHY_READ(sc, BRGPHY_SERDES_DIG_1000X_CTL1);
+ val &= ~BRGPHY_SD_DIG_1000X_CTL1_AUTODET;
+ val |= BRGPHY_SD_DIG_1000X_CTL1_FIBER;
+ PHY_WRITE(sc, BRGPHY_SERDES_DIG_1000X_CTL1, val);
+
+ /* Select the Over 1G block of the AN MMD. */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_OVER_1G);
+
+ /* Enable autoneg "Next Page" to advertise 2.5G support. */
+ val = PHY_READ(sc, BRGPHY_OVER_1G_UNFORMAT_PG1);
+ if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
+ val |= BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
+ else
+ val &= ~BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
+ PHY_WRITE(sc, BRGPHY_OVER_1G_UNFORMAT_PG1, val);
+
+ /* Select the Multi-Rate Backplane Ethernet block of the AN MMD. */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_MRBE);
+
+ /* Enable MRBE speed autoneg. */
+ val = PHY_READ(sc, BRGPHY_MRBE_MSG_PG5_NP);
+ val |= BRGPHY_MRBE_MSG_PG5_NP_MBRE |
+ BRGPHY_MRBE_MSG_PG5_NP_T2;
+ PHY_WRITE(sc, BRGPHY_MRBE_MSG_PG5_NP, val);
+
+ /* Select the Clause 73 User B0 block of the AN MMD. */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_CL73_USER_B0);
+
+ /* Enable MRBE speed autoneg. */
+ PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1,
+ BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP |
+ BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR |
+ BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG);
+
+ /* Restore IEEE0 block (assumed in all brgphy(4) code). */
+ PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+
+ } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) ||
(BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx))
brgphy_fixup_disable_early_dac(sc);
diff --git a/sys/dev/mii/brgphyreg.h b/sys/dev/mii/brgphyreg.h
index 643655f..883269e 100644
--- a/sys/dev/mii/brgphyreg.h
+++ b/sys/dev/mii/brgphyreg.h
@@ -359,6 +359,61 @@
/* End: PHY register values for the 5708S SerDes PHY */
/*******************************************************/
+/*******************************************************/
+/* Begin: PHY register values for the 5709S SerDes PHY */
+/*******************************************************/
+
+/* 5709S SerDes "General Purpose Status" Registers */
+#define BRGPHY_BLOCK_ADDR_GP_STATUS 0x8120
+#define BRGPHY_GP_STATUS_TOP_ANEG_STATUS 0x1B
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK 0x3F00
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10 0x0000
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100 0x0100
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G 0x0200
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G 0x0300
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1GKX 0x0D00
+#define BRGPHY_GP_STATUS_TOP_ANEG_FDX 0x0008
+#define BRGPHY_GP_STATUS_TOP_ANEG_LINK_UP 0x0004
+#define BRGPHY_GP_STATUS_TOP_ANEG_CL73_COMP 0x0001
+
+/* 5709S SerDes "SerDes Digital" Registers */
+#define BRGPHY_BLOCK_ADDR_SERDES_DIG 0x8300
+#define BRGPHY_SERDES_DIG_1000X_CTL1 0x0010
+#define BRGPHY_SD_DIG_1000X_CTL1_AUTODET 0x0010
+#define BRGPHY_SD_DIG_1000X_CTL1_FIBER 0x0001
+
+/* 5709S SerDes "Over 1G" Registers */
+#define BRGPHY_BLOCK_ADDR_OVER_1G 0x8320
+#define BRGPHY_OVER_1G_UNFORMAT_PG1 0x19
+
+/* 5709S SerDes "Multi-Rate Backplane Ethernet" Registers */
+#define BRGPHY_BLOCK_ADDR_MRBE 0x8350
+#define BRGPHY_MRBE_MSG_PG5_NP 0x10
+#define BRGPHY_MRBE_MSG_PG5_NP_MBRE 0x0001
+#define BRGPHY_MRBE_MSG_PG5_NP_T2 0x0001
+
+/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
+#define BRGPHY_BLOCK_ADDR_CL73_USER_B0 0x8370
+#define BRGPHY_CL73_USER_B0_MBRE_CTL1 0x12
+#define BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP 0x2000
+#define BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR 0x4000
+#define BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG 0x8000
+
+/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
+#define BRGPHY_BLOCK_ADDR_ADDR_EXT 0xFFD0
+
+/* 5709S SerDes "Combo IEEE 0" Registers */
+#define BRGPHY_BLOCK_ADDR_COMBO_IEEE0 0xFFE0
+
+#define BRGPHY_ADDR_EXT 0x1E
+#define BRGPHY_BLOCK_ADDR 0x1F
+
+#define BRGPHY_ADDR_EXT_AN_MMD 0x3800
+
+/*******************************************************/
+/* End: PHY register values for the 5709S SerDes PHY */
+/*******************************************************/
+
#define BRGPHY_INTRS \
~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG)
diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c
index 2ff31d3..b50eb07 100644
--- a/sys/dev/mii/e1000phy.c
+++ b/sys/dev/mii/e1000phy.c
@@ -276,7 +276,6 @@ e1000phy_reset(struct mii_softc *sc)
case MII_MODEL_MARVELL_E1118:
break;
case MII_MODEL_MARVELL_E1116:
- case MII_MODEL_MARVELL_E1149:
page = PHY_READ(sc, E1000_EADR);
/* Select page 3, LED control register. */
PHY_WRITE(sc, E1000_EADR, 3);
diff --git a/sys/dev/mii/icsphyreg.h b/sys/dev/mii/icsphyreg.h
index 22e4486..d92d0b5 100644
--- a/sys/dev/mii/icsphyreg.h
+++ b/sys/dev/mii/icsphyreg.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/lxtphyreg.h b/sys/dev/mii/lxtphyreg.h
index 662bd34..f563b09 100644
--- a/sys/dev/mii/lxtphyreg.h
+++ b/sys/dev/mii/lxtphyreg.h
@@ -18,13 +18,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c
index 065bc5d..efb768e 100644
--- a/sys/dev/mii/mii.c
+++ b/sys/dev/mii/mii.c
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -180,6 +173,8 @@ miibus_attach(device_t dev)
* XXX: EVIL HACK!
*/
mii->mii_ifp = *(struct ifnet**)device_get_softc(device_get_parent(dev));
+ mii->mii_ifp->if_capabilities |= IFCAP_LINKSTATE;
+ mii->mii_ifp->if_capenable |= IFCAP_LINKSTATE;
ivars = device_get_ivars(dev);
ifmedia_init(&mii->mii_media, IFM_IMASK, ivars->ifmedia_upd,
ivars->ifmedia_sts);
@@ -258,19 +253,12 @@ miibus_statchg(device_t dev)
{
device_t parent;
struct mii_data *mii;
- struct ifnet *ifp;
parent = device_get_parent(dev);
MIIBUS_STATCHG(parent);
mii = device_get_softc(dev);
-
- /*
- * Note that each NIC's softc must start with an ifnet pointer.
- * XXX: EVIL HACK!
- */
- ifp = *(struct ifnet **)device_get_softc(parent);
- ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
+ mii->mii_ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
return;
}
@@ -293,11 +281,7 @@ miibus_linkchg(device_t dev)
link_state = LINK_STATE_DOWN;
} else
link_state = LINK_STATE_UNKNOWN;
- /*
- * Note that each NIC's softc must start with an ifnet pointer.
- * XXX: EVIL HACK!
- */
- if_link_state_change(*(struct ifnet**)device_get_softc(parent), link_state);
+ if_link_state_change(mii->mii_ifp, link_state);
}
static void
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c
index 218f080..c8b9ece 100644
--- a/sys/dev/mii/mii_physubr.c
+++ b/sys/dev/mii/mii_physubr.c
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index 06e07be..30cd09c 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -17,13 +17,6 @@ $FreeBSD$
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -109,6 +102,7 @@ oui xxREALTEK 0x000732
*/
/* Agere Systems PHYs */
+model AGERE ET1011 0x0001 ET1011 10/100/1000baseT PHY
model AGERE ET1011C 0x0004 ET1011C 10/100/1000baseT PHY
/* Altima Communications PHYs */
@@ -157,6 +151,7 @@ model xxBROADCOM_ALT1 BCM5722 0x002d BCM5722 10/100/1000baseTX PHY
model xxBROADCOM_ALT1 BCM5784 0x003a BCM5784 10/100/1000baseTX PHY
model xxBROADCOM_ALT1 BCM5709C 0x003c BCM5709C 10/100/1000baseTX PHY
model xxBROADCOM_ALT1 BCM5761 0x003d BCM5761 10/100/1000baseTX PHY
+model xxBROADCOM_ALT1 BCM5709S 0x003f BCM5709S 1000/2500baseSX PHY
model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX PHY
/* Cicada Semiconductor PHYs (now owned by Vitesse?) */
diff --git a/sys/dev/mii/miivar.h b/sys/dev/mii/miivar.h
index 569dced..6b5a121 100644
--- a/sys/dev/mii/miivar.h
+++ b/sys/dev/mii/miivar.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/nsphyreg.h b/sys/dev/mii/nsphyreg.h
index 5ff0490..71fcfb6 100644
--- a/sys/dev/mii/nsphyreg.h
+++ b/sys/dev/mii/nsphyreg.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/nsphyterreg.h b/sys/dev/mii/nsphyterreg.h
index 5429afe..3bf5208 100644
--- a/sys/dev/mii/nsphyterreg.h
+++ b/sys/dev/mii/nsphyterreg.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/qsphyreg.h b/sys/dev/mii/qsphyreg.h
index a697865..91ebe0b 100644
--- a/sys/dev/mii/qsphyreg.h
+++ b/sys/dev/mii/qsphyreg.h
@@ -18,13 +18,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mii/truephy.c b/sys/dev/mii/truephy.c
index 4eba9d9..069b2a0 100644
--- a/sys/dev/mii/truephy.c
+++ b/sys/dev/mii/truephy.c
@@ -76,6 +76,7 @@ static device_method_t truephy_methods[] = {
};
static const struct mii_phydesc truephys[] = {
+ MII_PHY_DESC(AGERE, ET1011),
MII_PHY_DESC(AGERE, ET1011C),
MII_PHY_END
};
@@ -161,7 +162,10 @@ truephy_attach(device_t dev)
mii->mii_instance++;
- truephy_reset(sc);
+ if (MII_MODEL(ma->mii_id2) == MII_MODEL_AGERE_ET1011)
+ mii_phy_reset(sc);
+ else
+ truephy_reset(sc);
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
if (sc->mii_capabilities & BMSR_EXTSTAT) {
diff --git a/sys/dev/mii/ukphy_subr.c b/sys/dev/mii/ukphy_subr.c
index fdfc972..3c25de8 100644
--- a/sys/dev/mii/ukphy_subr.c
+++ b/sys/dev/mii/ukphy_subr.c
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c
index 302030f..5e63ef9 100644
--- a/sys/dev/mpt/mpt_cam.c
+++ b/sys/dev/mpt/mpt_cam.c
@@ -1208,14 +1208,18 @@ mpt_cam_detach(struct mpt_softc *mpt)
if (mpt->sim != NULL) {
xpt_free_path(mpt->path);
+ MPT_LOCK(mpt);
xpt_bus_deregister(cam_sim_path(mpt->sim));
+ MPT_UNLOCK(mpt);
cam_sim_free(mpt->sim, TRUE);
mpt->sim = NULL;
}
if (mpt->phydisk_sim != NULL) {
xpt_free_path(mpt->phydisk_path);
+ MPT_LOCK(mpt);
xpt_bus_deregister(cam_sim_path(mpt->phydisk_sim));
+ MPT_UNLOCK(mpt);
cam_sim_free(mpt->phydisk_sim, TRUE);
mpt->phydisk_sim = NULL;
}
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index d087195..c083e1e 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -266,6 +266,7 @@ static void msk_intr_hwerr(struct msk_softc *);
#ifndef __NO_STRICT_ALIGNMENT
static __inline void msk_fixup_rx(struct mbuf *);
#endif
+static __inline void msk_rxcsum(struct msk_if_softc *, uint32_t, struct mbuf *);
static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
static void msk_txeof(struct msk_if_softc *, int);
@@ -290,6 +291,7 @@ static int msk_txrx_dma_alloc(struct msk_if_softc *);
static int msk_rx_dma_jalloc(struct msk_if_softc *);
static void msk_txrx_dma_free(struct msk_if_softc *);
static void msk_rx_dma_jfree(struct msk_if_softc *);
+static int msk_rx_fill(struct msk_if_softc *, int);
static int msk_init_rx_ring(struct msk_if_softc *);
static int msk_init_jumbo_rx_ring(struct msk_if_softc *);
static void msk_init_tx_ring(struct msk_if_softc *);
@@ -643,6 +645,54 @@ msk_setvlan(struct msk_if_softc *sc_if, struct ifnet *ifp)
}
static int
+msk_rx_fill(struct msk_if_softc *sc_if, int jumbo)
+{
+ uint16_t idx;
+ int i;
+
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ (sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+ /* Wait until controller executes OP_TCPSTART command. */
+ for (i = 10; i > 0; i--) {
+ DELAY(10);
+ idx = CSR_READ_2(sc_if->msk_softc,
+ Y2_PREF_Q_ADDR(sc_if->msk_rxq,
+ PREF_UNIT_GET_IDX_REG));
+ if (idx != 0)
+ break;
+ }
+ if (i == 0) {
+ device_printf(sc_if->msk_if_dev,
+ "prefetch unit stuck?\n");
+ return (ETIMEDOUT);
+ }
+ /*
+ * Fill consumed LE with free buffer. This can be done
+ * in Rx handler but we don't want to add special code
+ * in fast handler.
+ */
+ if (jumbo > 0) {
+ if (msk_jumbo_newbuf(sc_if, 0) != 0)
+ return (ENOBUFS);
+ bus_dmamap_sync(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
+ sc_if->msk_cdata.msk_jumbo_rx_ring_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ } else {
+ if (msk_newbuf(sc_if, 0) != 0)
+ return (ENOBUFS);
+ bus_dmamap_sync(sc_if->msk_cdata.msk_rx_ring_tag,
+ sc_if->msk_cdata.msk_rx_ring_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ }
+ sc_if->msk_cdata.msk_rx_prod = 0;
+ CSR_WRITE_2(sc_if->msk_softc,
+ Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
+ sc_if->msk_cdata.msk_rx_prod);
+ }
+ return (0);
+}
+
+static int
msk_init_rx_ring(struct msk_if_softc *sc_if)
{
struct msk_ring_data *rd;
@@ -658,7 +708,21 @@ msk_init_rx_ring(struct msk_if_softc *sc_if)
rd = &sc_if->msk_rdata;
bzero(rd->msk_rx_ring, sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT);
prod = sc_if->msk_cdata.msk_rx_prod;
- for (i = 0; i < MSK_RX_RING_CNT; i++) {
+ i = 0;
+ /* Have controller know how to compute Rx checksum. */
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ (sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+ rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
+ rxd->rx_m = NULL;
+ rxd->rx_le = &rd->msk_rx_ring[prod];
+ rxd->rx_le->msk_addr = htole32(ETHER_HDR_LEN << 16 |
+ ETHER_HDR_LEN);
+ rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
+ MSK_INC(prod, MSK_RX_RING_CNT);
+ MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
+ i++;
+ }
+ for (; i < MSK_RX_RING_CNT; i++) {
rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_rx_ring[prod];
@@ -676,7 +740,8 @@ msk_init_rx_ring(struct msk_if_softc *sc_if)
CSR_WRITE_2(sc_if->msk_softc,
Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
sc_if->msk_cdata.msk_rx_prod);
-
+ if (msk_rx_fill(sc_if, 0) != 0)
+ return (ENOBUFS);
return (0);
}
@@ -697,7 +762,21 @@ msk_init_jumbo_rx_ring(struct msk_if_softc *sc_if)
bzero(rd->msk_jumbo_rx_ring,
sizeof(struct msk_rx_desc) * MSK_JUMBO_RX_RING_CNT);
prod = sc_if->msk_cdata.msk_rx_prod;
- for (i = 0; i < MSK_JUMBO_RX_RING_CNT; i++) {
+ i = 0;
+ /* Have controller know how to compute Rx checksum. */
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ (sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+ rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
+ rxd->rx_m = NULL;
+ rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
+ rxd->rx_le->msk_addr = htole32(ETHER_HDR_LEN << 16 |
+ ETHER_HDR_LEN);
+ rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
+ MSK_INC(prod, MSK_JUMBO_RX_RING_CNT);
+ MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_JUMBO_RX_RING_CNT);
+ i++;
+ }
+ for (; i < MSK_JUMBO_RX_RING_CNT; i++) {
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
@@ -714,7 +793,8 @@ msk_init_jumbo_rx_ring(struct msk_if_softc *sc_if)
CSR_WRITE_2(sc_if->msk_softc,
Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
sc_if->msk_cdata.msk_rx_prod);
-
+ if (msk_rx_fill(sc_if, 1) != 0)
+ return (ENOBUFS);
return (0);
}
@@ -923,7 +1003,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct msk_if_softc *sc_if;
struct ifreq *ifr;
struct mii_data *mii;
- int error, mask;
+ int error, mask, reinit;
sc_if = ifp->if_softc;
ifr = (struct ifreq *)data;
@@ -982,6 +1062,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
break;
case SIOCSIFCAP:
+ reinit = 0;
MSK_IF_LOCK(sc_if);
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
if ((mask & IFCAP_TXCSUM) != 0 &&
@@ -993,8 +1074,11 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_hwassist &= ~MSK_CSUM_FEATURES;
}
if ((mask & IFCAP_RXCSUM) != 0 &&
- (IFCAP_RXCSUM & ifp->if_capabilities) != 0)
+ (IFCAP_RXCSUM & ifp->if_capabilities) != 0) {
ifp->if_capenable ^= IFCAP_RXCSUM;
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0)
+ reinit = 1;
+ }
if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
(IFCAP_VLAN_HWCSUM & ifp->if_capabilities) != 0)
ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
@@ -1021,8 +1105,11 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO);
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
}
-
VLAN_CAPABILITIES(ifp);
+ if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ msk_init_locked(sc_if);
+ }
MSK_IF_UNLOCK(sc_if);
break;
default:
@@ -1125,7 +1212,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
*/
CSR_WRITE_1(sc, B2_Y2_CLK_GATE, val);
- val = pci_read_config(sc->msk_dev, PCI_OUR_REG_1, 4);
+ val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
if (sc->msk_hw_id == CHIP_ID_YUKON_XL) {
if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
@@ -1136,7 +1223,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
}
}
/* Release PHY from PowerDown/COMA mode. */
- pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
switch (sc->msk_hw_id) {
case CHIP_ID_YUKON_EC_U:
case CHIP_ID_YUKON_EX:
@@ -1145,16 +1232,16 @@ msk_phy_power(struct msk_softc *sc, int mode)
CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
/* Enable all clocks. */
- pci_write_config(sc->msk_dev, PCI_OUR_REG_3, 0, 4);
- our = pci_read_config(sc->msk_dev, PCI_OUR_REG_4, 4);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
+ our = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
our &= (PCI_FORCE_ASPM_REQUEST|PCI_ASPM_GPHY_LINK_DOWN|
PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST);
/* Set all bits to 0 except bits 15..12. */
- pci_write_config(sc->msk_dev, PCI_OUR_REG_4, our, 4);
- our = pci_read_config(sc->msk_dev, PCI_OUR_REG_5, 4);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, our);
+ our = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
our &= PCI_CTL_TIM_VMAIN_AV_MSK;
- pci_write_config(sc->msk_dev, PCI_OUR_REG_5, our, 4);
- pci_write_config(sc->msk_dev, PCI_CFG_REG_1, 0, 4);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, our);
+ CSR_PCI_WRITE_4(sc, PCI_CFG_REG_1, 0);
/*
* Disable status race, workaround for
* Yukon EC Ultra & Yukon EX.
@@ -1175,7 +1262,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
}
break;
case MSK_PHY_POWERDOWN:
- val = pci_read_config(sc->msk_dev, PCI_OUR_REG_1, 4);
+ val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
val |= PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD;
if (sc->msk_hw_id == CHIP_ID_YUKON_XL &&
sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
@@ -1183,7 +1270,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
if (sc->msk_num_port > 1)
val &= ~PCI_Y2_PHY2_COMA;
}
- pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
val = Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
@@ -1480,23 +1567,14 @@ msk_attach(device_t dev)
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- /*
- * IFCAP_RXCSUM capability is intentionally disabled as the hardware
- * has serious bug in Rx checksum offload for all Yukon II family
- * hardware. It seems there is a workaround to make it work somtimes.
- * However, the workaround also have to check OP code sequences to
- * verify whether the OP code is correct. Sometimes it should compute
- * IP/TCP/UDP checksum in driver in order to verify correctness of
- * checksum computed by hardware. If you have to compute checksum
- * with software to verify the hardware's checksum why have hardware
- * compute the checksum? I think there is no reason to spend time to
- * make Rx checksum offload work on Yukon II hardware.
- */
ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_TSO4;
/*
- * Enable Rx checksum offloading if controller support new
- * descriptor format.
+ * Enable Rx checksum offloading if controller supports
+ * new descriptor formant and controller is not Yukon XL.
*/
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ sc->msk_hw_id != CHIP_ID_YUKON_XL)
+ ifp->if_capabilities |= IFCAP_RXCSUM;
if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 &&
(sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
ifp->if_capabilities |= IFCAP_RXCSUM;
@@ -2527,23 +2605,32 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
ip = (struct ip *)(mtod(m, char *) + offset);
offset += (ip->ip_hl << 2);
tcp_offset = offset;
- /*
- * It seems that Yukon II has Tx checksum offload bug for
- * small TCP packets that's less than 60 bytes in size
- * (e.g. TCP window probe packet, pure ACK packet).
- * Common work around like padding with zeros to make the
- * frame minimum ethernet frame size didn't work at all.
- * Instead of disabling checksum offload completely we
- * resort to S/W checksum routine when we encounter short
- * TCP frames.
- * Short UDP packets appear to be handled correctly by
- * Yukon II. Also I assume this bug does not happen on
- * controllers that use newer descriptor format or
- * automatic Tx checksum calaulcation.
- */
- if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+ if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+ m = m_pullup(m, offset + sizeof(struct tcphdr));
+ if (m == NULL) {
+ *m_head = NULL;
+ return (ENOBUFS);
+ }
+ tcp = (struct tcphdr *)(mtod(m, char *) + offset);
+ offset += (tcp->th_off << 2);
+ } else if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
(m->m_pkthdr.len < MSK_MIN_FRAMELEN) &&
(m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
+ /*
+ * It seems that Yukon II has Tx checksum offload bug
+ * for small TCP packets that's less than 60 bytes in
+ * size (e.g. TCP window probe packet, pure ACK packet).
+ * Common work around like padding with zeros to make
+ * the frame minimum ethernet frame size didn't work at
+ * all.
+ * Instead of disabling checksum offload completely we
+ * resort to S/W checksum routine when we encounter
+ * short TCP frames.
+ * Short UDP packets appear to be handled correctly by
+ * Yukon II. Also I assume this bug does not happen on
+ * controllers that use newer descriptor format or
+ * automatic Tx checksum calaulcation.
+ */
m = m_pullup(m, offset + sizeof(struct tcphdr));
if (m == NULL) {
*m_head = NULL;
@@ -2554,15 +2641,6 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
m->m_pkthdr.len, offset);
m->m_pkthdr.csum_flags &= ~CSUM_TCP;
}
- if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
- m = m_pullup(m, offset + sizeof(struct tcphdr));
- if (m == NULL) {
- *m_head = NULL;
- return (ENOBUFS);
- }
- tcp = (struct tcphdr *)(mtod(m, char *) + offset);
- offset += (tcp->th_off << 2);
- }
*m_head = m;
}
@@ -2906,6 +2984,96 @@ msk_fixup_rx(struct mbuf *m)
}
#endif
+static __inline void
+msk_rxcsum(struct msk_if_softc *sc_if, uint32_t control, struct mbuf *m)
+{
+ struct ether_header *eh;
+ struct ip *ip;
+ struct udphdr *uh;
+ int32_t hlen, len, pktlen, temp32;
+ uint16_t csum, *opts;
+
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0) {
+ if ((control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
+ m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+ if ((control & CSS_IPV4_CSUM_OK) != 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
+ (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
+ m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+ CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
+ return;
+ }
+ /*
+ * Marvell Yukon controllers that support OP_RXCHKS has known
+ * to have various Rx checksum offloading bugs. These
+ * controllers can be configured to compute simple checksum
+ * at two different positions. So we can compute IP and TCP/UDP
+ * checksum at the same time. We intentionally have controller
+ * compute TCP/UDP checksum twice by specifying the same
+ * checksum start position and compare the result. If the value
+ * is different it would indicate the hardware logic was wrong.
+ */
+ if ((sc_if->msk_csum & 0xFFFF) != (sc_if->msk_csum >> 16)) {
+ if (bootverbose)
+ device_printf(sc_if->msk_if_dev,
+ "Rx checksum value mismatch!\n");
+ return;
+ }
+ pktlen = m->m_pkthdr.len;
+ if (pktlen < sizeof(struct ether_header) + sizeof(struct ip))
+ return;
+ eh = mtod(m, struct ether_header *);
+ if (eh->ether_type != htons(ETHERTYPE_IP))
+ return;
+ ip = (struct ip *)(eh + 1);
+ if (ip->ip_v != IPVERSION)
+ return;
+
+ hlen = ip->ip_hl << 2;
+ pktlen -= sizeof(struct ether_header);
+ if (hlen < sizeof(struct ip))
+ return;
+ if (ntohs(ip->ip_len) < hlen)
+ return;
+ if (ntohs(ip->ip_len) != pktlen)
+ return;
+ if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
+ return; /* can't handle fragmented packet. */
+
+ switch (ip->ip_p) {
+ case IPPROTO_TCP:
+ if (pktlen < (hlen + sizeof(struct tcphdr)))
+ return;
+ break;
+ case IPPROTO_UDP:
+ if (pktlen < (hlen + sizeof(struct udphdr)))
+ return;
+ uh = (struct udphdr *)((caddr_t)ip + hlen);
+ if (uh->uh_sum == 0)
+ return; /* no checksum */
+ break;
+ default:
+ return;
+ }
+ csum = ntohs(sc_if->msk_csum & 0xFFFF);
+ /* Checksum fixup for IP options. */
+ len = hlen - sizeof(struct ip);
+ if (len > 0) {
+ opts = (uint16_t *)(ip + 1);
+ for (; len > 0; len -= sizeof(uint16_t), opts++) {
+ temp32 = csum - *opts;
+ temp32 = (temp32 >> 16) + (temp32 & 65535);
+ csum = temp32 & 65535;
+ }
+ }
+ m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
+ m->m_pkthdr.csum_data = csum;
+}
+
static void
msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
int len)
@@ -2960,18 +3128,8 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
msk_fixup_rx(m);
#endif
ifp->if_ipackets++;
- if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
- (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
- m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
- if ((control & CSS_IPV4_CSUM_OK) != 0)
- m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
- if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
- (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
- m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
- CSUM_PSEUDO_HDR;
- m->m_pkthdr.csum_data = 0xffff;
- }
- }
+ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
+ msk_rxcsum(sc_if, control, m);
/* Check for VLAN tagged packets. */
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3030,18 +3188,8 @@ msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
msk_fixup_rx(m);
#endif
ifp->if_ipackets++;
- if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
- (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
- m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
- if ((control & CSS_IPV4_CSUM_OK) != 0)
- m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
- if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
- (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
- m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
- CSUM_PSEUDO_HDR;
- m->m_pkthdr.csum_data = 0xffff;
- }
- }
+ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
+ msk_rxcsum(sc_if, control, m);
/* Check for VLAN tagged packets. */
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3325,6 +3473,9 @@ msk_handle_events(struct msk_softc *sc)
uint32_t control, status;
int cons, len, port, rxprog;
+ if (sc->msk_stat_cons == CSR_READ_2(sc, STAT_PUT_IDX))
+ return (0);
+
/* Sync status LEs. */
bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -3355,6 +3506,9 @@ msk_handle_events(struct msk_softc *sc)
break;
case OP_RXCHKSVLAN:
sc_if->msk_vtag = ntohs(len);
+ /* FALLTHROUGH */
+ case OP_RXCHKS:
+ sc_if->msk_csum = status;
break;
case OP_RXSTAT:
if (sc_if->msk_framesize >
@@ -3405,7 +3559,7 @@ msk_handle_events(struct msk_softc *sc)
if (rxput[MSK_PORT_B] > 0)
msk_rxput(sc->msk_if[MSK_PORT_B]);
- return (rxprog > sc->msk_process_limit ? EAGAIN : 0);
+ return (sc->msk_stat_cons != CSR_READ_2(sc, STAT_PUT_IDX));
}
static void
@@ -3739,8 +3893,13 @@ msk_init_locked(struct msk_if_softc *sc_if)
msk_init_tx_ring(sc_if);
/* Disable Rx checksum offload and RSS hash. */
- CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_rxq, Q_CSR),
- BMU_DIS_RX_CHKSUM | BMU_DIS_RX_RSS_HASH);
+ reg = BMU_DIS_RX_RSS_HASH;
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ (ifp->if_capenable & IFCAP_RXCSUM) != 0)
+ reg |= BMU_ENA_RX_CHKSUM;
+ else
+ reg |= BMU_DIS_RX_CHKSUM;
+ CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_rxq, Q_CSR), reg);
if (sc_if->msk_framesize > (MCLBYTES - MSK_RX_BUF_ALIGN)) {
msk_set_prefetch(sc, sc_if->msk_rxq,
sc_if->msk_rdata.msk_jumbo_rx_ring_paddr,
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index 9c18ba7..34cac67 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -2547,6 +2547,7 @@ struct msk_if_softc {
struct msk_hw_stats msk_stats;
int msk_if_flags;
uint16_t msk_vtag; /* VLAN tag id. */
+ uint32_t msk_csum;
};
#define MSK_TIMEOUT 1000
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index 5b8bb99..956b1aa 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -883,6 +883,9 @@ mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data)
case MXGEFW_CMD_ERROR_BUSY:
err = EBUSY;
break;
+ case MXGEFW_CMD_ERROR_I2C_ABSENT:
+ err = ENXIO;
+ break;
default:
device_printf(sc->dev,
"mxge: command %d "
@@ -2782,37 +2785,25 @@ static struct mxge_media_type mxge_sfp_media_types[] =
};
static void
-mxge_set_media(mxge_softc_t *sc, int type)
+mxge_media_set(mxge_softc_t *sc, int media_type)
{
- sc->media_flags |= type;
- ifmedia_add(&sc->media, sc->media_flags, 0, NULL);
- ifmedia_set(&sc->media, sc->media_flags);
-}
+
+ ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX | media_type,
+ 0, NULL);
+ ifmedia_set(&sc->media, IFM_ETHER | IFM_FDX | media_type);
+ sc->current_media = media_type;
+ sc->media.ifm_media = sc->media.ifm_cur->ifm_media;
+}
-/*
- * Determine the media type for a NIC. Some XFPs will identify
- * themselves only when their link is up, so this is initiated via a
- * link up interrupt. However, this can potentially take up to
- * several milliseconds, so it is run via the watchdog routine, rather
- * than in the interrupt handler itself. This need only be done
- * once, not each time the link is up.
- */
static void
-mxge_media_probe(mxge_softc_t *sc)
+mxge_media_init(mxge_softc_t *sc)
{
- mxge_cmd_t cmd;
- char *cage_type;
char *ptr;
- struct mxge_media_type *mxge_media_types = NULL;
- int i, err, ms, mxge_media_type_entries;
- uint32_t byte;
-
- sc->need_media_probe = 0;
+ int i;
- /* if we've already set a media type, we're done */
- if (sc->media_flags != (IFM_ETHER | IFM_AUTO))
- return;
+ ifmedia_removeall(&sc->media);
+ mxge_media_set(sc, IFM_AUTO);
/*
* parse the product code to deterimine the interface type
@@ -2823,6 +2814,7 @@ mxge_media_probe(mxge_softc_t *sc)
ptr = sc->product_code_string;
if (ptr == NULL) {
device_printf(sc->dev, "Missing product code\n");
+ return;
}
for (i = 0; i < 3; i++, ptr++) {
@@ -2835,17 +2827,44 @@ mxge_media_probe(mxge_softc_t *sc)
}
if (*ptr == 'C') {
/* -C is CX4 */
- mxge_set_media(sc, IFM_10G_CX4);
- return;
- }
- else if (*ptr == 'Q') {
+ sc->connector = MXGE_CX4;
+ mxge_media_set(sc, IFM_10G_CX4);
+ } else if (*ptr == 'Q') {
/* -Q is Quad Ribbon Fiber */
+ sc->connector = MXGE_QRF;
device_printf(sc->dev, "Quad Ribbon Fiber Media\n");
/* FreeBSD has no media type for Quad ribbon fiber */
- return;
+ } else if (*ptr == 'R') {
+ /* -R is XFP */
+ sc->connector = MXGE_XFP;
+ } else if (*ptr == 'S' || *(ptr +1) == 'S') {
+ /* -S or -2S is SFP+ */
+ sc->connector = MXGE_SFP;
+ } else {
+ device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
}
+}
- if (*ptr == 'R') {
+/*
+ * Determine the media type for a NIC. Some XFPs will identify
+ * themselves only when their link is up, so this is initiated via a
+ * link up interrupt. However, this can potentially take up to
+ * several milliseconds, so it is run via the watchdog routine, rather
+ * than in the interrupt handler itself.
+ */
+static void
+mxge_media_probe(mxge_softc_t *sc)
+{
+ mxge_cmd_t cmd;
+ char *cage_type;
+
+ struct mxge_media_type *mxge_media_types = NULL;
+ int i, err, ms, mxge_media_type_entries;
+ uint32_t byte;
+
+ sc->need_media_probe = 0;
+
+ if (sc->connector == MXGE_XFP) {
/* -R is XFP */
mxge_media_types = mxge_xfp_media_types;
mxge_media_type_entries =
@@ -2853,9 +2872,7 @@ mxge_media_probe(mxge_softc_t *sc)
sizeof (mxge_xfp_media_types[0]);
byte = MXGE_XFP_COMPLIANCE_BYTE;
cage_type = "XFP";
- }
-
- if (*ptr == 'S' || *(ptr +1) == 'S') {
+ } else if (sc->connector == MXGE_SFP) {
/* -S or -2S is SFP+ */
mxge_media_types = mxge_sfp_media_types;
mxge_media_type_entries =
@@ -2863,10 +2880,8 @@ mxge_media_probe(mxge_softc_t *sc)
sizeof (mxge_sfp_media_types[0]);
cage_type = "SFP+";
byte = 3;
- }
-
- if (mxge_media_types == NULL) {
- device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
+ } else {
+ /* nothing to do; media type cannot change */
return;
}
@@ -2909,7 +2924,10 @@ mxge_media_probe(mxge_softc_t *sc)
if (mxge_verbose)
device_printf(sc->dev, "%s:%s\n", cage_type,
mxge_media_types[0].name);
- mxge_set_media(sc, mxge_media_types[0].flag);
+ if (sc->current_media != mxge_media_types[0].flag) {
+ mxge_media_init(sc);
+ mxge_media_set(sc, mxge_media_types[0].flag);
+ }
return;
}
for (i = 1; i < mxge_media_type_entries; i++) {
@@ -2919,12 +2937,16 @@ mxge_media_probe(mxge_softc_t *sc)
cage_type,
mxge_media_types[i].name);
- mxge_set_media(sc, mxge_media_types[i].flag);
+ if (sc->current_media != mxge_media_types[i].flag) {
+ mxge_media_init(sc);
+ mxge_media_set(sc, mxge_media_types[i].flag);
+ }
return;
}
}
- device_printf(sc->dev, "%s media 0x%x unknown\n", cage_type,
- cmd.data0);
+ if (mxge_verbose)
+ device_printf(sc->dev, "%s media 0x%x unknown\n",
+ cage_type, cmd.data0);
return;
}
@@ -2988,10 +3010,12 @@ mxge_intr(void *arg)
sc->link_state = stats->link_up;
if (sc->link_state) {
if_link_state_change(sc->ifp, LINK_STATE_UP);
+ sc->ifp->if_baudrate = IF_Gbps(10UL);
if (mxge_verbose)
device_printf(sc->dev, "link up\n");
} else {
if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+ sc->ifp->if_baudrate = 0;
if (mxge_verbose)
device_printf(sc->dev, "link down\n");
}
@@ -4026,9 +4050,9 @@ mxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
if (sc == NULL)
return;
ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER | IFM_FDX;
ifmr->ifm_status |= sc->link_state ? IFM_ACTIVE : 0;
- ifmr->ifm_active = IFM_AUTO | IFM_ETHER;
- ifmr->ifm_active |= sc->link_state ? IFM_FDX : 0;
+ ifmr->ifm_active |= sc->current_media;
}
static int
@@ -4135,6 +4159,9 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
break;
case SIOCGIFMEDIA:
+ mtx_lock(&sc->driver_mtx);
+ mxge_media_probe(sc);
+ mtx_unlock(&sc->driver_mtx);
err = ifmedia_ioctl(ifp, (struct ifreq *)data,
&sc->media, command);
break;
@@ -4616,8 +4643,6 @@ mxge_attach(device_t dev)
err = ENOMEM;
goto abort_with_nothing;
}
- taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(sc->dev));
err = bus_dma_tag_create(NULL, /* parent */
1, /* alignment */
@@ -4723,7 +4748,7 @@ mxge_attach(device_t dev)
err = mxge_alloc_rings(sc);
if (err != 0) {
device_printf(sc->dev, "failed to allocate rings\n");
- goto abort_with_dmabench;
+ goto abort_with_slices;
}
err = mxge_add_irq(sc);
@@ -4734,7 +4759,7 @@ mxge_attach(device_t dev)
ifp->if_baudrate = IF_Gbps(10UL);
ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4 |
- IFCAP_VLAN_MTU;
+ IFCAP_VLAN_MTU | IFCAP_LINKSTATE;
#ifdef INET
ifp->if_capabilities |= IFCAP_LRO;
#endif
@@ -4768,7 +4793,7 @@ mxge_attach(device_t dev)
/* Initialise the ifmedia structure */
ifmedia_init(&sc->media, 0, mxge_media_change,
mxge_media_status);
- mxge_set_media(sc, IFM_ETHER | IFM_AUTO);
+ mxge_media_init(sc);
mxge_media_probe(sc);
sc->dying = 0;
ether_ifattach(ifp, sc->mac_addr);
@@ -4781,6 +4806,8 @@ mxge_attach(device_t dev)
ifp->if_transmit = mxge_transmit;
ifp->if_qflush = mxge_qflush;
#endif
+ taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq",
+ device_get_nameunit(sc->dev));
callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
return 0;
diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h
index 5c1627f..c85a29b 100644
--- a/sys/dev/mxge/if_mxge_var.h
+++ b/sys/dev/mxge/if_mxge_var.h
@@ -268,6 +268,8 @@ struct mxge_softc {
int num_slices;
int rx_ring_size;
int dying;
+ int connector;
+ int current_media;
mxge_dma_t dmabench_dma;
struct callout co_hdl;
struct taskqueue *tq;
@@ -293,6 +295,12 @@ struct mxge_softc {
#define MXGE_MIN_THROTTLE 416
#define MXGE_MAX_THROTTLE 4096
+/* Types of connectors on NICs supported by this driver */
+#define MXGE_CX4 0
+#define MXGE_XFP 1
+#define MXGE_SFP 2
+#define MXGE_QRF 3
+
#define MXGE_HIGHPART_TO_U32(X) \
(sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)
#define MXGE_LOWPART_TO_U32(X) ((uint32_t)(X))
diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c
index 5d0bfd2..7d77754 100644
--- a/sys/dev/nfe/if_nfe.c
+++ b/sys/dev/nfe/if_nfe.c
@@ -2366,7 +2366,12 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
m = *m_head;
cflags = flags = 0;
tso_segsz = 0;
- if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
+ if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+ tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
+ NFE_TX_TSO_SHIFT;
+ cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
+ cflags |= NFE_TX_TSO;
+ } else if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
cflags |= NFE_TX_IP_CSUM;
if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
@@ -2374,12 +2379,6 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
cflags |= NFE_TX_TCP_UDP_CSUM;
}
- if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
- tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
- NFE_TX_TSO_SHIFT;
- cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
- cflags |= NFE_TX_TSO;
- }
for (i = 0; i < nsegs; i++) {
if (sc->nfe_flags & NFE_40BIT_ADDR) {
diff --git a/sys/dev/ofw/ofw_standard.c b/sys/dev/ofw/ofw_standard.c
index de18a9e..e521fa0 100644
--- a/sys/dev/ofw/ofw_standard.c
+++ b/sys/dev/ofw/ofw_standard.c
@@ -165,7 +165,7 @@ ofw_std_init(ofw_t ofw, void *openfirm)
static int
ofw_std_test(ofw_t ofw, const char *name)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -187,7 +187,7 @@ static int
ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns,
unsigned long *returns)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -217,7 +217,7 @@ ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns,
static phandle_t
ofw_std_peer(ofw_t ofw, phandle_t node)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -239,7 +239,7 @@ ofw_std_peer(ofw_t ofw, phandle_t node)
static phandle_t
ofw_std_child(ofw_t ofw, phandle_t node)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -261,7 +261,7 @@ ofw_std_child(ofw_t ofw, phandle_t node)
static phandle_t
ofw_std_parent(ofw_t ofw, phandle_t node)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -283,7 +283,7 @@ ofw_std_parent(ofw_t ofw, phandle_t node)
static phandle_t
ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -305,7 +305,7 @@ ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance)
static ssize_t
ofw_std_getproplen(ofw_t ofw, phandle_t package, const char *propname)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -330,7 +330,7 @@ static ssize_t
ofw_std_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf,
size_t buflen)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -359,7 +359,7 @@ static int
ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
size_t size)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -387,7 +387,7 @@ static int
ofw_std_setprop(ofw_t ofw, phandle_t package, const char *propname,
const void *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -415,7 +415,7 @@ ofw_std_setprop(ofw_t ofw, phandle_t package, const char *propname,
static ssize_t
ofw_std_canon(ofw_t ofw, const char *device, char *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -441,7 +441,7 @@ ofw_std_canon(ofw_t ofw, const char *device, char *buf, size_t len)
static phandle_t
ofw_std_finddevice(ofw_t ofw, const char *device)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -463,7 +463,7 @@ ofw_std_finddevice(ofw_t ofw, const char *device)
static ssize_t
ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -489,7 +489,7 @@ ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
static ssize_t
ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -516,7 +516,7 @@ static int
ofw_std_call_method(ofw_t ofw, ihandle_t instance, const char *method,
int nargs, int nreturns, unsigned long *args_and_returns)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -559,7 +559,7 @@ ofw_std_call_method(ofw_t ofw, ihandle_t instance, const char *method,
static ihandle_t
ofw_std_open(ofw_t ofw, const char *device)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -581,7 +581,7 @@ ofw_std_open(ofw_t ofw, const char *device)
static void
ofw_std_close(ofw_t ofw, ihandle_t instance)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -589,6 +589,7 @@ ofw_std_close(ofw_t ofw, ihandle_t instance)
} args = {
(cell_t)"close",
1,
+ 0,
};
args.instance = instance;
@@ -599,7 +600,7 @@ ofw_std_close(ofw_t ofw, ihandle_t instance)
static ssize_t
ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -626,7 +627,7 @@ ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
static ssize_t
ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -652,7 +653,7 @@ ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
static int
ofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -682,7 +683,7 @@ ofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos)
static caddr_t
ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -708,7 +709,7 @@ ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align)
static void
ofw_std_release(ofw_t ofw, void *virt, size_t size)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -717,6 +718,7 @@ ofw_std_release(ofw_t ofw, void *virt, size_t size)
} args = {
(cell_t)"release",
2,
+ 0,
};
args.virt = (cell_t)virt;
@@ -732,12 +734,14 @@ ofw_std_release(ofw_t ofw, void *virt, size_t size)
static void
ofw_std_enter(ofw_t ofw)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
} args = {
(cell_t)"enter",
+ 0,
+ 0,
};
openfirmware(&args);
@@ -748,12 +752,14 @@ ofw_std_enter(ofw_t ofw)
static void
ofw_std_exit(ofw_t ofw)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
} args = {
(cell_t)"exit",
+ 0,
+ 0,
};
openfirmware(&args);
diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c
index 19fe9df..d86b8fb 100644
--- a/sys/dev/pci/vga_pci.c
+++ b/sys/dev/pci/vga_pci.c
@@ -232,7 +232,7 @@ vga_pci_read_config(device_t dev, device_t child, int reg, int width)
}
static void
-vga_pci_write_config(device_t dev, device_t child, int reg,
+vga_pci_write_config(device_t dev, device_t child, int reg,
uint32_t val, int width)
{
@@ -409,7 +409,6 @@ static device_method_t vga_pci_methods[] = {
DEVMETHOD(bus_write_ivar, vga_pci_write_ivar),
DEVMETHOD(bus_setup_intr, vga_pci_setup_intr),
DEVMETHOD(bus_teardown_intr, vga_pci_teardown_intr),
-
DEVMETHOD(bus_alloc_resource, vga_pci_alloc_resource),
DEVMETHOD(bus_release_resource, vga_pci_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
diff --git a/sys/dev/ppc/ppc_pci.c b/sys/dev/ppc/ppc_pci.c
index c8e40b5..ed59413 100644
--- a/sys/dev/ppc/ppc_pci.c
+++ b/sys/dev/ppc/ppc_pci.c
@@ -89,6 +89,7 @@ static struct pci_id pci_ids[] = {
{ 0x84031415, "Oxford Semiconductor OX12PCI840 Parallel port", 0x10 },
{ 0x95131415, "Oxford Semiconductor OX16PCI954 Parallel port", 0x10 },
{ 0x98059710, "NetMos NM9805 1284 Printer port", 0x10 },
+ { 0x99019710, "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 },
{ 0xffff }
};
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index 455b5ad..9549107 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -103,8 +103,6 @@ static void rt2560_reset_rx_ring(struct rt2560_softc *,
struct rt2560_rx_ring *);
static void rt2560_free_rx_ring(struct rt2560_softc *,
struct rt2560_rx_ring *);
-static struct ieee80211_node *rt2560_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
static void rt2560_newassoc(struct ieee80211_node *, int);
static int rt2560_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -307,7 +305,6 @@ rt2560_attach(device_t dev, int id)
ic->ic_raw_xmit = rt2560_raw_xmit;
ic->ic_updateslot = rt2560_update_slot;
ic->ic_update_promisc = rt2560_update_promisc;
- ic->ic_node_alloc = rt2560_node_alloc;
ic->ic_scan_start = rt2560_scan_start;
ic->ic_scan_end = rt2560_scan_end;
ic->ic_set_channel = rt2560_set_channel;
@@ -430,11 +427,7 @@ rt2560_vap_create(struct ieee80211com *ic,
vap->iv_newstate = rt2560_newstate;
vap->iv_update_beacon = rt2560_beacon_update;
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /* ms */);
-
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
@@ -447,7 +440,7 @@ rt2560_vap_delete(struct ieee80211vap *vap)
{
struct rt2560_vap *rvp = RT2560_VAP(vap);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
}
@@ -764,25 +757,11 @@ rt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
bus_dma_tag_destroy(ring->data_dmat);
}
-static struct ieee80211_node *
-rt2560_node_alloc(struct ieee80211vap *vap,
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct rt2560_node *rn;
-
- rn = malloc(sizeof (struct rt2560_node), M_80211_NODE,
- M_NOWAIT | M_ZERO);
-
- return (rn != NULL) ? &rn->ni : NULL;
-}
-
static void
rt2560_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RT2560_VAP(vap)->amrr,
- &RT2560_NODE(ni)->amrr, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
static int
@@ -955,10 +934,11 @@ rt2560_tx_intr(struct rt2560_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
- struct rt2560_node *rn;
struct mbuf *m;
uint32_t flags;
int retrycnt;
+ struct ieee80211vap *vap;
+ struct ieee80211_node *ni;
bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
BUS_DMASYNC_POSTREAD);
@@ -973,15 +953,19 @@ rt2560_tx_intr(struct rt2560_softc *sc)
!(flags & RT2560_TX_VALID))
break;
- rn = (struct rt2560_node *)data->ni;
m = data->m;
+ ni = data->ni;
+ vap = ni->ni_vap;
switch (flags & RT2560_TX_RESULT_MASK) {
case RT2560_TX_SUCCESS:
+ retrycnt = 0;
+
DPRINTFN(sc, 10, "%s\n", "data frame sent successfully");
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_SUCCESS, 0);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_opackets++;
break;
@@ -991,8 +975,9 @@ rt2560_tx_intr(struct rt2560_softc *sc)
DPRINTFN(sc, 9, "data frame sent after %u retries\n",
retrycnt);
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_SUCCESS, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_opackets++;
break;
@@ -1002,8 +987,9 @@ rt2560_tx_intr(struct rt2560_softc *sc)
DPRINTFN(sc, 9, "data frame failed after %d retries\n",
retrycnt);
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_FAILURE, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, NULL);
ifp->if_oerrors++;
break;
@@ -1821,7 +1807,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {
- (void) ieee80211_amrr_choose(ni, &RT2560_NODE(ni)->amrr);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h
index 288577b..b6a8d68 100644
--- a/sys/dev/ral/rt2560var.h
+++ b/sys/dev/ral/rt2560var.h
@@ -95,16 +95,9 @@ struct rt2560_rx_ring {
int cur_decrypt;
};
-struct rt2560_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amrr;
-};
-#define RT2560_NODE(ni) ((struct rt2560_node *)(ni))
-
struct rt2560_vap {
struct ieee80211vap ral_vap;
struct ieee80211_beacon_offsets ral_bo;
- struct ieee80211_amrr amrr;
int (*ral_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index 9e6693f..9bc8838 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -100,8 +100,6 @@ static void rt2661_reset_rx_ring(struct rt2661_softc *,
struct rt2661_rx_ring *);
static void rt2661_free_rx_ring(struct rt2661_softc *,
struct rt2661_rx_ring *);
-static struct ieee80211_node *rt2661_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
static void rt2661_newassoc(struct ieee80211_node *, int);
static int rt2661_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -307,7 +305,6 @@ rt2661_attach(device_t dev, int id)
ieee80211_ifattach(ic, macaddr);
ic->ic_newassoc = rt2661_newassoc;
- ic->ic_node_alloc = rt2661_node_alloc;
#if 0
ic->ic_wme.wme_update = rt2661_wme_update;
#endif
@@ -428,11 +425,7 @@ rt2661_vap_create(struct ieee80211com *ic,
vap->iv_update_beacon = rt2661_beacon_update;
#endif
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /* ms */);
-
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
@@ -445,7 +438,7 @@ rt2661_vap_delete(struct ieee80211vap *vap)
{
struct rt2661_vap *rvp = RT2661_VAP(vap);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
}
@@ -771,25 +764,11 @@ rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
bus_dma_tag_destroy(ring->data_dmat);
}
-static struct ieee80211_node *
-rt2661_node_alloc(struct ieee80211vap *vap,
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct rt2661_node *rn;
-
- rn = malloc(sizeof (struct rt2661_node), M_80211_NODE,
- M_NOWAIT | M_ZERO);
-
- return (rn != NULL) ? &rn->ni : NULL;
-}
-
static void
rt2661_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RT2661_VAP(vap)->amrr,
- &RT2661_NODE(ni)->amrr, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
static int
@@ -899,9 +878,9 @@ rt2661_tx_intr(struct rt2661_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct rt2661_tx_ring *txq;
struct rt2661_tx_data *data;
- struct rt2661_node *rn;
uint32_t val;
int qid, retrycnt;
+ struct ieee80211vap *vap;
for (;;) {
struct ieee80211_node *ni;
@@ -925,8 +904,8 @@ rt2661_tx_intr(struct rt2661_softc *sc)
/* if no frame has been sent, ignore */
if (ni == NULL)
continue;
-
- rn = RT2661_NODE(ni);
+ else
+ vap = ni->ni_vap;
switch (RT2661_TX_RESULT(val)) {
case RT2661_TX_SUCCESS:
@@ -935,8 +914,9 @@ rt2661_tx_intr(struct rt2661_softc *sc)
DPRINTFN(sc, 10, "data frame sent successfully after "
"%d retries\n", retrycnt);
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_SUCCESS, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_opackets++;
break;
@@ -946,8 +926,9 @@ rt2661_tx_intr(struct rt2661_softc *sc)
DPRINTFN(sc, 9, "%s\n",
"sending data frame failed (too much retries)");
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_FAILURE, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, NULL);
ifp->if_oerrors++;
break;
@@ -1511,7 +1492,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {
- (void) ieee80211_amrr_choose(ni, &RT2661_NODE(ni)->amrr);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
rate &= IEEE80211_RATE_VAL;
diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h
index db1d4de..9927d13 100644
--- a/sys/dev/ral/rt2661var.h
+++ b/sys/dev/ral/rt2661var.h
@@ -88,15 +88,8 @@ struct rt2661_rx_ring {
int next;
};
-struct rt2661_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amrr;
-};
-#define RT2661_NODE(ni) ((struct rt2661_node *)(ni))
-
struct rt2661_vap {
struct ieee80211vap ral_vap;
- struct ieee80211_amrr amrr;
int (*ral_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 9785801..8091506 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -174,8 +174,7 @@ static struct rl_type re_devs[] = {
{ RT_VENDORID, RT_DEVICEID_8101E, 0,
"RealTek 8101E/8102E/8102EL/8103E PCIe 10/100baseTX" },
{ RT_VENDORID, RT_DEVICEID_8168, 0,
- "RealTek 8168/8168B/8168C/8168CP/8168D/8168DP/"
- "8111B/8111C/8111CP/8111DP PCIe Gigabit Ethernet" },
+ "RealTek 8168/8111 B/C/CP/D/DP/E PCIe Gigabit Ethernet" },
{ RT_VENDORID, RT_DEVICEID_8169, 0,
"RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
@@ -220,6 +219,7 @@ static struct rl_hwrev re_hwrevs[] = {
{ RL_HWREV_8168CP, RL_8169, "8168CP/8111CP"},
{ RL_HWREV_8168D, RL_8169, "8168D/8111D"},
{ RL_HWREV_8168DP, RL_8169, "8168DP/8111DP"},
+ { RL_HWREV_8168E, RL_8169, "8168E/8111E"},
{ 0, 0, NULL }
};
@@ -1310,6 +1310,11 @@ re_attach(device_t dev)
*/
sc->rl_flags |= RL_FLAG_NOJUMBO;
break;
+ case RL_HWREV_8168E:
+ sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
+ RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
+ RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_NOJUMBO;
+ break;
case RL_HWREV_8169_8110SB:
case RL_HWREV_8169_8110SBL:
case RL_HWREV_8169_8110SC:
@@ -1393,6 +1398,8 @@ re_attach(device_t dev)
}
/* Take PHY out of power down mode. */
+ if ((sc->rl_flags & RL_FLAG_PHYWAKE_PM) != 0)
+ CSR_WRITE_1(sc, RL_PMCH, CSR_READ_1(sc, RL_PMCH) | 0x80);
if ((sc->rl_flags & RL_FLAG_PHYWAKE) != 0) {
re_gmii_writereg(dev, 1, 0x1f, 0);
re_gmii_writereg(dev, 1, 0x0e, 0);
@@ -3135,6 +3142,9 @@ re_setwol(struct rl_softc *sc)
v |= RL_CFG5_WOL_LANWAKE;
CSR_WRITE_1(sc, RL_CFG5, v);
+ if ((ifp->if_capenable & IFCAP_WOL) != 0 &&
+ (sc->rl_flags & RL_FLAG_PHYWAKE_PM) != 0)
+ CSR_WRITE_1(sc, RL_PMCH, CSR_READ_1(sc, RL_PMCH) & ~0x80);
/*
* It seems that hardware resets its link speed to 100Mbps in
* power down mode so switching to 100Mbps in driver is not
diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c
new file mode 100644
index 0000000..6c737bd
--- /dev/null
+++ b/sys/dev/sge/if_sge.c
@@ -0,0 +1,1748 @@
+/*-
+ * Copyright (c) 2008-2010 Nikolay Denev <ndenev@gmail.com>
+ * Copyright (c) 2007-2008 Alexander Pohoyda <alexander.pohoyda@gmx.net>
+ * Copyright (c) 1997, 1998, 1999
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 AUTHORS OR
+ * THE VOICES IN THEIR HEADS 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$");
+
+/*
+ * SiS 190/191 PCI Ethernet NIC driver.
+ *
+ * Adapted to SiS 190 NIC by Alexander Pohoyda based on the original
+ * SiS 900 driver by Bill Paul, using SiS 190/191 Solaris driver by
+ * Masayuki Murayama and SiS 190/191 GNU/Linux driver by K.M. Liu
+ * <kmliu@sis.com>. Thanks to Pyun YongHyeon <pyunyh@gmail.com> for
+ * review and very useful comments.
+ *
+ * Adapted to SiS 191 NIC by Nikolay Denev with further ideas from the
+ * Linux and Solaris drivers.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/sge/if_sgereg.h>
+
+MODULE_DEPEND(sge, pci, 1, 1, 1);
+MODULE_DEPEND(sge, ether, 1, 1, 1);
+MODULE_DEPEND(sge, miibus, 1, 1, 1);
+
+/* "device miibus0" required. See GENERIC if you get errors here. */
+#include "miibus_if.h"
+
+/*
+ * Various supported device vendors/types and their names.
+ */
+static struct sge_type sge_devs[] = {
+ { SIS_VENDORID, SIS_DEVICEID_190, "SiS190 Fast Ethernet" },
+ { SIS_VENDORID, SIS_DEVICEID_191, "SiS191 Fast/Gigabit Ethernet" },
+ { 0, 0, NULL }
+};
+
+static int sge_probe(device_t);
+static int sge_attach(device_t);
+static int sge_detach(device_t);
+static int sge_shutdown(device_t);
+static int sge_suspend(device_t);
+static int sge_resume(device_t);
+
+static int sge_miibus_readreg(device_t, int, int);
+static int sge_miibus_writereg(device_t, int, int, int);
+static void sge_miibus_statchg(device_t);
+
+static int sge_newbuf(struct sge_softc *, int);
+static int sge_encap(struct sge_softc *, struct mbuf **);
+#ifndef __NO_STRICT_ALIGNMENT
+static __inline void
+ sge_fixup_rx(struct mbuf *);
+#endif
+static __inline void
+ sge_discard_rxbuf(struct sge_softc *, int);
+static void sge_rxeof(struct sge_softc *);
+static void sge_txeof(struct sge_softc *);
+static void sge_intr(void *);
+static void sge_tick(void *);
+static void sge_start(struct ifnet *);
+static void sge_start_locked(struct ifnet *);
+static int sge_ioctl(struct ifnet *, u_long, caddr_t);
+static void sge_init(void *);
+static void sge_init_locked(struct sge_softc *);
+static void sge_stop(struct sge_softc *);
+static void sge_watchdog(struct sge_softc *);
+static int sge_ifmedia_upd(struct ifnet *);
+static void sge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+static int sge_get_mac_addr_apc(struct sge_softc *, uint8_t *);
+static int sge_get_mac_addr_eeprom(struct sge_softc *, uint8_t *);
+static uint16_t sge_read_eeprom(struct sge_softc *, int);
+
+static void sge_rxfilter(struct sge_softc *);
+static void sge_reset(struct sge_softc *);
+static int sge_list_rx_init(struct sge_softc *);
+static int sge_list_rx_free(struct sge_softc *);
+static int sge_list_tx_init(struct sge_softc *);
+static int sge_list_tx_free(struct sge_softc *);
+
+static int sge_dma_alloc(struct sge_softc *);
+static void sge_dma_free(struct sge_softc *);
+static void sge_dma_map_addr(void *, bus_dma_segment_t *, int, int);
+
+static device_method_t sge_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sge_probe),
+ DEVMETHOD(device_attach, sge_attach),
+ DEVMETHOD(device_detach, sge_detach),
+ DEVMETHOD(device_suspend, sge_suspend),
+ DEVMETHOD(device_resume, sge_resume),
+ DEVMETHOD(device_shutdown, sge_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ /* MII interface */
+ DEVMETHOD(miibus_readreg, sge_miibus_readreg),
+ DEVMETHOD(miibus_writereg, sge_miibus_writereg),
+ DEVMETHOD(miibus_statchg, sge_miibus_statchg),
+
+ KOBJMETHOD_END
+};
+
+static driver_t sge_driver = {
+ "sge", sge_methods, sizeof(struct sge_softc)
+};
+
+static devclass_t sge_devclass;
+
+DRIVER_MODULE(sge, pci, sge_driver, sge_devclass, 0, 0);
+DRIVER_MODULE(miibus, sge, miibus_driver, miibus_devclass, 0, 0);
+
+/*
+ * Register space access macros.
+ */
+#define CSR_WRITE_4(sc, reg, val) bus_write_4(sc->sge_res, reg, val)
+#define CSR_WRITE_2(sc, reg, val) bus_write_2(sc->sge_res, reg, val)
+#define CSR_WRITE_1(cs, reg, val) bus_write_1(sc->sge_res, reg, val)
+
+#define CSR_READ_4(sc, reg) bus_read_4(sc->sge_res, reg)
+#define CSR_READ_2(sc, reg) bus_read_2(sc->sge_res, reg)
+#define CSR_READ_1(sc, reg) bus_read_1(sc->sge_res, reg)
+
+/* Define to show Tx/Rx error status. */
+#undef SGE_SHOW_ERRORS
+
+#define SGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
+
+static void
+sge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ bus_addr_t *p;
+
+ if (error != 0)
+ return;
+ KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
+ p = arg;
+ *p = segs->ds_addr;
+}
+
+/*
+ * Read a sequence of words from the EEPROM.
+ */
+static uint16_t
+sge_read_eeprom(struct sge_softc *sc, int offset)
+{
+ uint32_t val;
+ int i;
+
+ KASSERT(offset <= EI_OFFSET, ("EEPROM offset too big"));
+ CSR_WRITE_4(sc, ROMInterface,
+ EI_REQ | EI_OP_RD | (offset << EI_OFFSET_SHIFT));
+ DELAY(500);
+ for (i = 0; i < SGE_TIMEOUT; i++) {
+ val = CSR_READ_4(sc, ROMInterface);
+ if ((val & EI_REQ) == 0)
+ break;
+ DELAY(100);
+ }
+ if (i == SGE_TIMEOUT) {
+ device_printf(sc->sge_dev,
+ "EEPROM read timeout : 0x%08x\n", val);
+ return (0xffff);
+ }
+
+ return ((val & EI_DATA) >> EI_DATA_SHIFT);
+}
+
+static int
+sge_get_mac_addr_eeprom(struct sge_softc *sc, uint8_t *dest)
+{
+ uint16_t val;
+ int i;
+
+ val = sge_read_eeprom(sc, EEPROMSignature);
+ if (val == 0xffff || val == 0) {
+ device_printf(sc->sge_dev,
+ "invalid EEPROM signature : 0x%04x\n", val);
+ return (EINVAL);
+ }
+
+ for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
+ val = sge_read_eeprom(sc, EEPROMMACAddr + i / 2);
+ dest[i + 0] = (uint8_t)val;
+ dest[i + 1] = (uint8_t)(val >> 8);
+ }
+
+ if ((sge_read_eeprom(sc, EEPROMInfo) & 0x80) != 0)
+ sc->sge_flags |= SGE_FLAG_RGMII;
+ return (0);
+}
+
+/*
+ * For SiS96x, APC CMOS RAM is used to store ethernet address.
+ * APC CMOS RAM is accessed through ISA bridge.
+ */
+static int
+sge_get_mac_addr_apc(struct sge_softc *sc, uint8_t *dest)
+{
+#if defined(__amd64__) || defined(__i386__)
+ devclass_t pci;
+ device_t bus, dev = NULL;
+ device_t *kids;
+ struct apc_tbl {
+ uint16_t vid;
+ uint16_t did;
+ } *tp, apc_tbls[] = {
+ { SIS_VENDORID, 0x0965 },
+ { SIS_VENDORID, 0x0966 },
+ { SIS_VENDORID, 0x0968 }
+ };
+ uint8_t reg;
+ int busnum, cnt, i, j, numkids;
+
+ cnt = sizeof(apc_tbls) / sizeof(apc_tbls[0]);
+ pci = devclass_find("pci");
+ for (busnum = 0; busnum < devclass_get_maxunit(pci); busnum++) {
+ bus = devclass_get_device(pci, busnum);
+ if (!bus)
+ continue;
+ if (device_get_children(bus, &kids, &numkids) != 0)
+ continue;
+ for (i = 0; i < numkids; i++) {
+ dev = kids[i];
+ if (pci_get_class(dev) == PCIC_BRIDGE &&
+ pci_get_subclass(dev) == PCIS_BRIDGE_ISA) {
+ tp = apc_tbls;
+ for (j = 0; j < cnt; j++) {
+ if (pci_get_vendor(dev) == tp->vid &&
+ pci_get_device(dev) == tp->did) {
+ free(kids, M_TEMP);
+ goto apc_found;
+ }
+ tp++;
+ }
+ }
+ }
+ free(kids, M_TEMP);
+ }
+ device_printf(sc->sge_dev, "couldn't find PCI-ISA bridge\n");
+ return (EINVAL);
+apc_found:
+ /* Enable port 0x78 and 0x79 to access APC registers. */
+ reg = pci_read_config(dev, 0x48, 1);
+ pci_write_config(dev, 0x48, reg & ~0x02, 1);
+ DELAY(50);
+ pci_read_config(dev, 0x48, 1);
+ /* Read stored ethernet address. */
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ outb(0x78, 0x09 + i);
+ dest[i] = inb(0x79);
+ }
+ outb(0x78, 0x12);
+ if ((inb(0x79) & 0x80) != 0)
+ sc->sge_flags |= SGE_FLAG_RGMII;
+ /* Restore access to APC registers. */
+ pci_write_config(dev, 0x48, reg, 1);
+
+ return (0);
+#else
+ return (EINVAL);
+#endif
+}
+
+static int
+sge_miibus_readreg(device_t dev, int phy, int reg)
+{
+ struct sge_softc *sc;
+ uint32_t val;
+ int i;
+
+ sc = device_get_softc(dev);
+ CSR_WRITE_4(sc, GMIIControl, (phy << GMI_PHY_SHIFT) |
+ (reg << GMI_REG_SHIFT) | GMI_OP_RD | GMI_REQ);
+ DELAY(10);
+ for (i = 0; i < SGE_TIMEOUT; i++) {
+ val = CSR_READ_4(sc, GMIIControl);
+ if ((val & GMI_REQ) == 0)
+ break;
+ DELAY(10);
+ }
+ if (i == SGE_TIMEOUT) {
+ device_printf(sc->sge_dev, "PHY read timeout : %d\n", reg);
+ return (0);
+ }
+ return ((val & GMI_DATA) >> GMI_DATA_SHIFT);
+}
+
+static int
+sge_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+ struct sge_softc *sc;
+ uint32_t val;
+ int i;
+
+ sc = device_get_softc(dev);
+ CSR_WRITE_4(sc, GMIIControl, (phy << GMI_PHY_SHIFT) |
+ (reg << GMI_REG_SHIFT) | (data << GMI_DATA_SHIFT) |
+ GMI_OP_WR | GMI_REQ);
+ DELAY(10);
+ for (i = 0; i < SGE_TIMEOUT; i++) {
+ val = CSR_READ_4(sc, GMIIControl);
+ if ((val & GMI_REQ) == 0)
+ break;
+ DELAY(10);
+ }
+ if (i == SGE_TIMEOUT)
+ device_printf(sc->sge_dev, "PHY write timeout : %d\n", reg);
+ return (0);
+}
+
+static void
+sge_miibus_statchg(device_t dev)
+{
+ struct sge_softc *sc;
+ struct mii_data *mii;
+ struct ifnet *ifp;
+ uint32_t ctl, speed;
+
+ sc = device_get_softc(dev);
+ mii = device_get_softc(sc->sge_miibus);
+ ifp = sc->sge_ifp;
+ if (mii == NULL || ifp == NULL ||
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ return;
+ speed = 0;
+ sc->sge_flags &= ~SGE_FLAG_LINK;
+ if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+ (IFM_ACTIVE | IFM_AVALID)) {
+ switch (IFM_SUBTYPE(mii->mii_media_active)) {
+ case IFM_10_T:
+ sc->sge_flags |= SGE_FLAG_LINK;
+ speed = SC_SPEED_10;
+ break;
+ case IFM_100_TX:
+ sc->sge_flags |= SGE_FLAG_LINK;
+ speed = SC_SPEED_100;
+ break;
+ case IFM_1000_T:
+ if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0) {
+ sc->sge_flags |= SGE_FLAG_LINK;
+ speed = SC_SPEED_1000;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if ((sc->sge_flags & SGE_FLAG_LINK) == 0)
+ return;
+ /* Reprogram MAC to resolved speed/duplex/flow-control parameters. */
+ ctl = CSR_READ_4(sc, StationControl);
+ ctl &= ~(0x0f000000 | SC_FDX | SC_SPEED_MASK);
+ if (speed == SC_SPEED_1000) {
+ ctl |= 0x07000000;
+ sc->sge_flags |= SGE_FLAG_SPEED_1000;
+ } else {
+ ctl |= 0x04000000;
+ sc->sge_flags &= ~SGE_FLAG_SPEED_1000;
+ }
+#ifdef notyet
+ if ((sc->sge_flags & SGE_FLAG_GMII) != 0)
+ ctl |= 0x03000000;
+#endif
+ ctl |= speed;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
+ ctl |= SC_FDX;
+ sc->sge_flags |= SGE_FLAG_FDX;
+ } else
+ sc->sge_flags &= ~SGE_FLAG_FDX;
+ CSR_WRITE_4(sc, StationControl, ctl);
+ if ((sc->sge_flags & SGE_FLAG_RGMII) != 0) {
+ CSR_WRITE_4(sc, RGMIIDelay, 0x0441);
+ CSR_WRITE_4(sc, RGMIIDelay, 0x0440);
+ }
+}
+
+static void
+sge_rxfilter(struct sge_softc *sc)
+{
+ struct ifnet *ifp;
+ struct ifmultiaddr *ifma;
+ uint32_t crc, hashes[2];
+ uint16_t rxfilt;
+
+ SGE_LOCK_ASSERT(sc);
+
+ ifp = sc->sge_ifp;
+ hashes[0] = hashes[1] = 0;
+ rxfilt = AcceptMyPhys;
+ if ((ifp->if_flags & IFF_BROADCAST) != 0)
+ rxfilt |= AcceptBroadcast;
+ if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
+ if ((ifp->if_flags & IFF_PROMISC) != 0)
+ rxfilt |= AcceptAllPhys;
+ rxfilt |= AcceptMulticast;
+ hashes[0] = 0xFFFFFFFF;
+ hashes[1] = 0xFFFFFFFF;
+ goto done;
+ }
+ rxfilt |= AcceptMulticast;
+ /* Now program new ones. */
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ crc = ether_crc32_be(LLADDR((struct sockaddr_dl *)
+ ifma->ifma_addr), ETHER_ADDR_LEN);
+ hashes[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
+ }
+ if_maddr_runlock(ifp);
+done:
+ CSR_WRITE_2(sc, RxMacControl, rxfilt | 0x02);
+ CSR_WRITE_4(sc, RxHashTable, hashes[0]);
+ CSR_WRITE_4(sc, RxHashTable2, hashes[1]);
+}
+
+static void
+sge_reset(struct sge_softc *sc)
+{
+
+ CSR_WRITE_4(sc, IntrMask, 0);
+ CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
+
+ /* Soft reset. */
+ CSR_WRITE_4(sc, IntrControl, 0x8000);
+ CSR_READ_4(sc, IntrControl);
+ DELAY(100);
+ CSR_WRITE_4(sc, IntrControl, 0);
+ /* Stop MAC. */
+ CSR_WRITE_4(sc, TX_CTL, 0x1a00);
+ CSR_WRITE_4(sc, RX_CTL, 0x1a00);
+
+ CSR_WRITE_4(sc, IntrMask, 0);
+ CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
+
+ CSR_WRITE_4(sc, GMIIControl, 0);
+}
+
+/*
+ * Probe for an SiS chip. Check the PCI vendor and device
+ * IDs against our list and return a device name if we find a match.
+ */
+static int
+sge_probe(device_t dev)
+{
+ struct sge_type *t;
+
+ t = sge_devs;
+ while (t->sge_name != NULL) {
+ if ((pci_get_vendor(dev) == t->sge_vid) &&
+ (pci_get_device(dev) == t->sge_did)) {
+ device_set_desc(dev, t->sge_name);
+ return (BUS_PROBE_DEFAULT);
+ }
+ t++;
+ }
+
+ return (ENXIO);
+}
+
+/*
+ * Attach the interface. Allocate softc structures, do ifmedia
+ * setup and ethernet/BPF attach.
+ */
+static int
+sge_attach(device_t dev)
+{
+ struct sge_softc *sc;
+ struct ifnet *ifp;
+ uint8_t eaddr[ETHER_ADDR_LEN];
+ int error = 0, rid;
+
+ sc = device_get_softc(dev);
+ sc->sge_dev = dev;
+
+ mtx_init(&sc->sge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+ MTX_DEF);
+ callout_init_mtx(&sc->sge_stat_ch, &sc->sge_mtx, 0);
+
+ /*
+ * Map control/status registers.
+ */
+ pci_enable_busmaster(dev);
+
+ /* Allocate resources. */
+ sc->sge_res_id = PCIR_BAR(0);
+ sc->sge_res_type = SYS_RES_MEMORY;
+ sc->sge_res = bus_alloc_resource_any(dev, sc->sge_res_type,
+ &sc->sge_res_id, RF_ACTIVE);
+ if (sc->sge_res == NULL) {
+ device_printf(dev, "couldn't allocate resource\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ rid = 0;
+ sc->sge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->sge_irq == NULL) {
+ device_printf(dev, "couldn't allocate IRQ resources\n");
+ error = ENXIO;
+ goto fail;
+ }
+ sc->sge_rev = pci_get_revid(dev);
+ if (pci_get_device(dev) == SIS_DEVICEID_190)
+ sc->sge_flags |= SGE_FLAG_FASTETHER;
+ /* Reset the adapter. */
+ sge_reset(sc);
+
+ /* Get MAC address from the EEPROM. */
+ if ((pci_read_config(dev, 0x73, 1) & 0x01) != 0)
+ sge_get_mac_addr_apc(sc, eaddr);
+ else
+ sge_get_mac_addr_eeprom(sc, eaddr);
+
+ if ((error = sge_dma_alloc(sc)) != 0)
+ goto fail;
+
+ ifp = sc->sge_ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL) {
+ device_printf(dev, "cannot allocate ifnet structure.\n");
+ error = ENOSPC;
+ goto fail;
+ }
+ ifp->if_softc = sc;
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = sge_ioctl;
+ ifp->if_start = sge_start;
+ ifp->if_init = sge_init;
+ ifp->if_snd.ifq_drv_maxlen = SGE_TX_RING_CNT - 1;
+ IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
+ IFQ_SET_READY(&ifp->if_snd);
+ ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_RXCSUM;
+ ifp->if_hwassist = SGE_CSUM_FEATURES;
+ ifp->if_capenable = ifp->if_capabilities;
+ /*
+ * Do MII setup.
+ */
+ if (mii_phy_probe(dev, &sc->sge_miibus, sge_ifmedia_upd,
+ sge_ifmedia_sts)) {
+ device_printf(dev, "no PHY found!\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ /*
+ * Call MI attach routine.
+ */
+ ether_ifattach(ifp, eaddr);
+
+ /* VLAN setup. */
+ ifp->if_capabilities |= IFCAP_VLAN_MTU;
+ ifp->if_capenable = ifp->if_capabilities;
+ /* Tell the upper layer(s) we support long frames. */
+ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+
+ /* Hook interrupt last to avoid having to lock softc */
+ error = bus_setup_intr(dev, sc->sge_irq, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, sge_intr, sc, &sc->sge_intrhand);
+ if (error) {
+ device_printf(dev, "couldn't set up irq\n");
+ ether_ifdetach(ifp);
+ goto fail;
+ }
+
+fail:
+ if (error)
+ sge_detach(dev);
+
+ return (error);
+}
+
+/*
+ * Shutdown hardware and free up resources. This can be called any
+ * time after the mutex has been initialized. It is called in both
+ * the error case in attach and the normal detach case so it needs
+ * to be careful about only freeing resources that have actually been
+ * allocated.
+ */
+static int
+sge_detach(device_t dev)
+{
+ struct sge_softc *sc;
+ struct ifnet *ifp;
+
+ sc = device_get_softc(dev);
+ ifp = sc->sge_ifp;
+ /* These should only be active if attach succeeded. */
+ if (device_is_attached(dev)) {
+ ether_ifdetach(ifp);
+ SGE_LOCK(sc);
+ sge_stop(sc);
+ SGE_UNLOCK(sc);
+ callout_drain(&sc->sge_stat_ch);
+ }
+ if (sc->sge_miibus)
+ device_delete_child(dev, sc->sge_miibus);
+ bus_generic_detach(dev);
+
+ if (sc->sge_intrhand)
+ bus_teardown_intr(dev, sc->sge_irq, sc->sge_intrhand);
+ if (sc->sge_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sge_irq);
+ if (sc->sge_res)
+ bus_release_resource(dev, sc->sge_res_type, sc->sge_res_id,
+ sc->sge_res);
+ if (ifp)
+ if_free(ifp);
+ sge_dma_free(sc);
+ mtx_destroy(&sc->sge_mtx);
+
+ return (0);
+}
+
+/*
+ * Stop all chip I/O so that the kernel's probe routines don't
+ * get confused by errant DMAs when rebooting.
+ */
+static int
+sge_shutdown(device_t dev)
+{
+ struct sge_softc *sc;
+
+ sc = device_get_softc(dev);
+ SGE_LOCK(sc);
+ sge_stop(sc);
+ SGE_UNLOCK(sc);
+ return (0);
+}
+
+static int
+sge_suspend(device_t dev)
+{
+ struct sge_softc *sc;
+ struct ifnet *ifp;
+
+ sc = device_get_softc(dev);
+ SGE_LOCK(sc);
+ ifp = sc->sge_ifp;
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ sge_stop(sc);
+ SGE_UNLOCK(sc);
+ return (0);
+}
+
+static int
+sge_resume(device_t dev)
+{
+ struct sge_softc *sc;
+ struct ifnet *ifp;
+
+ sc = device_get_softc(dev);
+ SGE_LOCK(sc);
+ ifp = sc->sge_ifp;
+ if ((ifp->if_flags & IFF_UP) != 0)
+ sge_init_locked(sc);
+ SGE_UNLOCK(sc);
+ return (0);
+}
+
+static int
+sge_dma_alloc(struct sge_softc *sc)
+{
+ struct sge_chain_data *cd;
+ struct sge_list_data *ld;
+ int error, i;
+
+ cd = &sc->sge_cdata;
+ ld = &sc->sge_ldata;
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->sge_dev),
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
+ 1, /* nsegments */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
+ &cd->sge_tag);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create parent DMA tag.\n");
+ goto fail;
+ }
+
+ /* RX descriptor ring */
+ error = bus_dma_tag_create(cd->sge_tag,
+ SGE_DESC_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ SGE_RX_RING_SZ, 1, /* maxsize,nsegments */
+ SGE_RX_RING_SZ, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
+ &cd->sge_rx_tag);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create Rx ring DMA tag.\n");
+ goto fail;
+ }
+ /* Allocate DMA'able memory and load DMA map for RX ring. */
+ error = bus_dmamem_alloc(cd->sge_rx_tag, (void **)&ld->sge_rx_ring,
+ BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+ &cd->sge_rx_dmamap);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not allocate DMA'able memory for Rx ring.\n");
+ goto fail;
+ }
+ error = bus_dmamap_load(cd->sge_rx_tag, cd->sge_rx_dmamap,
+ ld->sge_rx_ring, SGE_RX_RING_SZ, sge_dma_map_addr,
+ &ld->sge_rx_paddr, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not load DMA'able memory for Rx ring.\n");
+ }
+
+ /* TX descriptor ring */
+ error = bus_dma_tag_create(cd->sge_tag,
+ SGE_DESC_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ SGE_TX_RING_SZ, 1, /* maxsize,nsegments */
+ SGE_TX_RING_SZ, /* maxsegsize */
+ 0, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
+ &cd->sge_tx_tag);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create Rx ring DMA tag.\n");
+ goto fail;
+ }
+ /* Allocate DMA'able memory and load DMA map for TX ring. */
+ error = bus_dmamem_alloc(cd->sge_tx_tag, (void **)&ld->sge_tx_ring,
+ BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+ &cd->sge_tx_dmamap);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not allocate DMA'able memory for Tx ring.\n");
+ goto fail;
+ }
+ error = bus_dmamap_load(cd->sge_tx_tag, cd->sge_tx_dmamap,
+ ld->sge_tx_ring, SGE_TX_RING_SZ, sge_dma_map_addr,
+ &ld->sge_tx_paddr, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not load DMA'able memory for Rx ring.\n");
+ goto fail;
+ }
+
+ /* Create DMA tag for Tx buffers. */
+ error = bus_dma_tag_create(cd->sge_tag, 1, 0, BUS_SPACE_MAXADDR,
+ BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES * SGE_MAXTXSEGS,
+ SGE_MAXTXSEGS, MCLBYTES, 0, NULL, NULL, &cd->sge_txmbuf_tag);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create Tx mbuf DMA tag.\n");
+ goto fail;
+ }
+
+ /* Create DMA tag for Rx buffers. */
+ error = bus_dma_tag_create(cd->sge_tag, SGE_RX_BUF_ALIGN, 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1,
+ MCLBYTES, 0, NULL, NULL, &cd->sge_rxmbuf_tag);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create Rx mbuf DMA tag.\n");
+ goto fail;
+ }
+
+ /* Create DMA maps for Tx buffers. */
+ for (i = 0; i < SGE_TX_RING_CNT; i++) {
+ error = bus_dmamap_create(cd->sge_txmbuf_tag, 0,
+ &cd->sge_tx_map[i]);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create Tx DMA map.\n");
+ goto fail;
+ }
+ }
+ /* Create spare DMA map for Rx buffer. */
+ error = bus_dmamap_create(cd->sge_rxmbuf_tag, 0, &cd->sge_rx_spare_map);
+ if (error != 0) {
+ device_printf(sc->sge_dev,
+ "could not create spare Rx DMA map.\n");
+ goto fail;
+ }
+ /* Create DMA maps for Rx buffers. */
+ for (i = 0; i < SGE_RX_RING_CNT; i++) {
+ error = bus_dmamap_create(cd->sge_rxmbuf_tag, 0,
+ &cd->sge_rx_map[i]);
+ if (error) {
+ device_printf(sc->sge_dev,
+ "could not create Rx DMA map.\n");
+ goto fail;
+ }
+ }
+fail:
+ return (error);
+}
+
+static void
+sge_dma_free(struct sge_softc *sc)
+{
+ struct sge_chain_data *cd;
+ struct sge_list_data *ld;
+ int i;
+
+ cd = &sc->sge_cdata;
+ ld = &sc->sge_ldata;
+ /* Rx ring. */
+ if (cd->sge_rx_tag != NULL) {
+ if (cd->sge_rx_dmamap != NULL)
+ bus_dmamap_unload(cd->sge_rx_tag, cd->sge_rx_dmamap);
+ if (cd->sge_rx_dmamap != NULL && ld->sge_rx_ring != NULL)
+ bus_dmamem_free(cd->sge_rx_tag, ld->sge_rx_ring,
+ cd->sge_rx_dmamap);
+ ld->sge_rx_ring = NULL;
+ cd->sge_rx_dmamap = NULL;
+ bus_dma_tag_destroy(cd->sge_rx_tag);
+ cd->sge_rx_tag = NULL;
+ }
+ /* Tx ring. */
+ if (cd->sge_tx_tag != NULL) {
+ if (cd->sge_tx_dmamap != NULL)
+ bus_dmamap_unload(cd->sge_tx_tag, cd->sge_tx_dmamap);
+ if (cd->sge_tx_dmamap != NULL && ld->sge_tx_ring != NULL)
+ bus_dmamem_free(cd->sge_tx_tag, ld->sge_tx_ring,
+ cd->sge_tx_dmamap);
+ ld->sge_tx_ring = NULL;
+ cd->sge_tx_dmamap = NULL;
+ bus_dma_tag_destroy(cd->sge_tx_tag);
+ cd->sge_tx_tag = NULL;
+ }
+ /* Rx buffers. */
+ if (cd->sge_rxmbuf_tag != NULL) {
+ for (i = 0; i < SGE_RX_RING_CNT; i++) {
+ if (cd->sge_rx_map[i] != NULL) {
+ bus_dmamap_destroy(cd->sge_rxmbuf_tag,
+ cd->sge_rx_map[i]);
+ cd->sge_rx_map[i] = NULL;
+ }
+ }
+ if (cd->sge_rx_spare_map != NULL) {
+ bus_dmamap_destroy(cd->sge_rxmbuf_tag,
+ cd->sge_rx_spare_map);
+ cd->sge_rx_spare_map = NULL;
+ }
+ bus_dma_tag_destroy(cd->sge_rxmbuf_tag);
+ cd->sge_rxmbuf_tag = NULL;
+ }
+ /* Tx buffers. */
+ if (cd->sge_txmbuf_tag != NULL) {
+ for (i = 0; i < SGE_TX_RING_CNT; i++) {
+ if (cd->sge_tx_map[i] != NULL) {
+ bus_dmamap_destroy(cd->sge_txmbuf_tag,
+ cd->sge_tx_map[i]);
+ cd->sge_tx_map[i] = NULL;
+ }
+ }
+ bus_dma_tag_destroy(cd->sge_txmbuf_tag);
+ cd->sge_txmbuf_tag = NULL;
+ }
+ if (cd->sge_tag != NULL)
+ bus_dma_tag_destroy(cd->sge_tag);
+ cd->sge_tag = NULL;
+}
+
+/*
+ * Initialize the TX descriptors.
+ */
+static int
+sge_list_tx_init(struct sge_softc *sc)
+{
+ struct sge_list_data *ld;
+ struct sge_chain_data *cd;
+
+ SGE_LOCK_ASSERT(sc);
+ ld = &sc->sge_ldata;
+ cd = &sc->sge_cdata;
+ bzero(ld->sge_tx_ring, SGE_TX_RING_SZ);
+ ld->sge_tx_ring[SGE_TX_RING_CNT - 1].sge_flags = htole32(RING_END);
+ bus_dmamap_sync(cd->sge_tx_tag, cd->sge_tx_dmamap,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ cd->sge_tx_prod = 0;
+ cd->sge_tx_cons = 0;
+ cd->sge_tx_cnt = 0;
+ return (0);
+}
+
+static int
+sge_list_tx_free(struct sge_softc *sc)
+{
+ struct sge_chain_data *cd;
+ int i;
+
+ SGE_LOCK_ASSERT(sc);
+ cd = &sc->sge_cdata;
+ for (i = 0; i < SGE_TX_RING_CNT; i++) {
+ if (cd->sge_tx_mbuf[i] != NULL) {
+ bus_dmamap_sync(cd->sge_txmbuf_tag,
+ cd->sge_tx_map[i], BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(cd->sge_txmbuf_tag,
+ cd->sge_tx_map[i]);
+ m_free(cd->sge_tx_mbuf[i]);
+ cd->sge_tx_mbuf[i] = NULL;
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Initialize the RX descriptors and allocate mbufs for them. Note that
+ * we arrange the descriptors in a closed ring, so that the last descriptor
+ * has RING_END flag set.
+ */
+static int
+sge_list_rx_init(struct sge_softc *sc)
+{
+ struct sge_chain_data *cd;
+ int i;
+
+ SGE_LOCK_ASSERT(sc);
+ cd = &sc->sge_cdata;
+ cd->sge_rx_cons = 0;
+ bzero(sc->sge_ldata.sge_rx_ring, SGE_RX_RING_SZ);
+ for (i = 0; i < SGE_RX_RING_CNT; i++) {
+ if (sge_newbuf(sc, i) != 0)
+ return (ENOBUFS);
+ }
+ bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ return (0);
+}
+
+static int
+sge_list_rx_free(struct sge_softc *sc)
+{
+ struct sge_chain_data *cd;
+ int i;
+
+ SGE_LOCK_ASSERT(sc);
+ cd = &sc->sge_cdata;
+ for (i = 0; i < SGE_RX_RING_CNT; i++) {
+ if (cd->sge_rx_mbuf[i] != NULL) {
+ bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[i],
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(cd->sge_rxmbuf_tag,
+ cd->sge_rx_map[i]);
+ m_free(cd->sge_rx_mbuf[i]);
+ cd->sge_rx_mbuf[i] = NULL;
+ }
+ }
+ return (0);
+}
+
+/*
+ * Initialize an RX descriptor and attach an MBUF cluster.
+ */
+static int
+sge_newbuf(struct sge_softc *sc, int prod)
+{
+ struct mbuf *m;
+ struct sge_desc *desc;
+ struct sge_chain_data *cd;
+ bus_dma_segment_t segs[1];
+ bus_dmamap_t map;
+ int error, nsegs;
+
+ SGE_LOCK_ASSERT(sc);
+
+ cd = &sc->sge_cdata;
+ m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (m == NULL)
+ return (ENOBUFS);
+ m->m_len = m->m_pkthdr.len = MCLBYTES;
+ m_adj(m, SGE_RX_BUF_ALIGN);
+ error = bus_dmamap_load_mbuf_sg(cd->sge_rxmbuf_tag,
+ cd->sge_rx_spare_map, m, segs, &nsegs, 0);
+ if (error != 0) {
+ m_freem(m);
+ return (error);
+ }
+ KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
+ if (cd->sge_rx_mbuf[prod] != NULL) {
+ bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod],
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod]);
+ }
+ map = cd->sge_rx_map[prod];
+ cd->sge_rx_map[prod] = cd->sge_rx_spare_map;
+ cd->sge_rx_spare_map = map;
+ bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod],
+ BUS_DMASYNC_PREREAD);
+ cd->sge_rx_mbuf[prod] = m;
+
+ desc = &sc->sge_ldata.sge_rx_ring[prod];
+ desc->sge_sts_size = 0;
+ desc->sge_ptr = htole32(SGE_ADDR_LO(segs[0].ds_addr));
+ desc->sge_flags = htole32(segs[0].ds_len);
+ if (prod == SGE_RX_RING_CNT - 1)
+ desc->sge_flags |= htole32(RING_END);
+ desc->sge_cmdsts = htole32(RDC_OWN | RDC_INTR | RDC_IP_CSUM |
+ RDC_TCP_CSUM | RDC_UDP_CSUM);
+ return (0);
+}
+
+#ifndef __NO_STRICT_ALIGNMENT
+static __inline void
+sge_fixup_rx(struct mbuf *m)
+{
+ int i;
+ uint16_t *src, *dst;
+
+ src = mtod(m, uint16_t *);
+ dst = src - 3;
+
+ for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++)
+ *dst++ = *src++;
+
+ m->m_data -= (SGE_RX_BUF_ALIGN - ETHER_ALIGN);
+}
+#endif
+
+static __inline void
+sge_discard_rxbuf(struct sge_softc *sc, int index)
+{
+ struct sge_desc *desc;
+
+ desc = &sc->sge_ldata.sge_rx_ring[index];
+ desc->sge_sts_size = 0;
+ desc->sge_flags = htole32(MCLBYTES - SGE_RX_BUF_ALIGN);
+ if (index == SGE_RX_RING_CNT - 1)
+ desc->sge_flags |= htole32(RING_END);
+ desc->sge_cmdsts = htole32(RDC_OWN | RDC_INTR | RDC_IP_CSUM |
+ RDC_TCP_CSUM | RDC_UDP_CSUM);
+}
+
+/*
+ * A frame has been uploaded: pass the resulting mbuf chain up to
+ * the higher level protocols.
+ */
+static void
+sge_rxeof(struct sge_softc *sc)
+{
+ struct ifnet *ifp;
+ struct mbuf *m;
+ struct sge_chain_data *cd;
+ struct sge_desc *cur_rx;
+ uint32_t rxinfo, rxstat;
+ int cons, prog;
+
+ SGE_LOCK_ASSERT(sc);
+
+ ifp = sc->sge_ifp;
+ cd = &sc->sge_cdata;
+
+ bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ cons = cd->sge_rx_cons;
+ for (prog = 0; prog < SGE_RX_RING_CNT; prog++,
+ SGE_INC(cons, SGE_RX_RING_CNT)) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
+ cur_rx = &sc->sge_ldata.sge_rx_ring[cons];
+ rxinfo = le32toh(cur_rx->sge_cmdsts);
+ if ((rxinfo & RDC_OWN) != 0)
+ break;
+ rxstat = le32toh(cur_rx->sge_sts_size);
+ if (SGE_RX_ERROR(rxstat) != 0 || SGE_RX_NSEGS(rxstat) != 1) {
+ /* XXX We don't support multi-segment frames yet. */
+#ifdef SGE_SHOW_ERRORS
+ device_printf(sc->sge_dev, "Rx error : 0x%b\n", rxstat,
+ RX_ERR_BITS);
+#endif
+ sge_discard_rxbuf(sc, cons);
+ ifp->if_ierrors++;
+ continue;
+ }
+ m = cd->sge_rx_mbuf[cons];
+ if (sge_newbuf(sc, cons) != 0) {
+ sge_discard_rxbuf(sc, cons);
+ ifp->if_iqdrops++;
+ continue;
+ }
+ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+ if ((rxinfo & RDC_IP_CSUM) != 0 &&
+ (rxinfo & RDC_IP_CSUM_OK) != 0)
+ m->m_pkthdr.csum_flags |=
+ CSUM_IP_CHECKED | CSUM_IP_VALID;
+ if (((rxinfo & RDC_TCP_CSUM) != 0 &&
+ (rxinfo & RDC_TCP_CSUM_OK) != 0) ||
+ ((rxinfo & RDC_UDP_CSUM) != 0 &&
+ (rxinfo & RDC_UDP_CSUM_OK) != 0)) {
+ m->m_pkthdr.csum_flags |=
+ CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
+ /*
+ * TODO : VLAN hardware tag stripping.
+ */
+ m->m_pkthdr.len = m->m_len =
+ SGE_RX_BYTES(rxstat) - ETHER_CRC_LEN;
+#ifndef __NO_STRICT_ALIGNMENT
+ sge_fixup_rx(m);
+#endif
+ m->m_pkthdr.rcvif = ifp;
+ ifp->if_ipackets++;
+ SGE_UNLOCK(sc);
+ (*ifp->if_input)(ifp, m);
+ SGE_LOCK(sc);
+ }
+
+ if (prog > 0) {
+ bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ cd->sge_rx_cons = cons;
+ }
+}
+
+/*
+ * A frame was downloaded to the chip. It's safe for us to clean up
+ * the list buffers.
+ */
+static void
+sge_txeof(struct sge_softc *sc)
+{
+ struct ifnet *ifp;
+ struct sge_list_data *ld;
+ struct sge_chain_data *cd;
+ uint32_t txstat;
+ int cons, prod;
+
+ SGE_LOCK_ASSERT(sc);
+
+ ifp = sc->sge_ifp;
+ ld = &sc->sge_ldata;
+ cd = &sc->sge_cdata;
+
+ if (cd->sge_tx_cnt == 0)
+ return;
+ bus_dmamap_sync(cd->sge_tx_tag, cd->sge_tx_dmamap,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ cons = cd->sge_tx_cons;
+ prod = cd->sge_tx_prod;
+ for (; cons != prod; SGE_INC(cons, SGE_TX_RING_CNT)) {
+ txstat = le32toh(ld->sge_tx_ring[cons].sge_cmdsts);
+ if ((txstat & TDC_OWN) != 0)
+ break;
+ cd->sge_tx_cnt--;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ if (cd->sge_tx_mbuf[cons] != NULL) {
+ bus_dmamap_sync(cd->sge_txmbuf_tag,
+ cd->sge_tx_map[cons], BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(cd->sge_txmbuf_tag,
+ cd->sge_tx_map[cons]);
+ m_freem(cd->sge_tx_mbuf[cons]);
+ cd->sge_tx_mbuf[cons] = NULL;
+ if (SGE_TX_ERROR(txstat) != 0) {
+#ifdef SGE_SHOW_ERRORS
+ device_printf(sc->sge_dev, "Tx error : 0x%b\n",
+ txstat, TX_ERR_BITS);
+#endif
+ ifp->if_oerrors++;
+ } else {
+#ifdef notyet
+ ifp->if_collisions += (txstat & 0xFFFF) - 1;
+#endif
+ ifp->if_opackets++;
+ }
+ }
+
+ }
+ cd->sge_tx_cons = cons;
+ if (cd->sge_tx_cnt == 0)
+ sc->sge_timer = 0;
+}
+
+static void
+sge_tick(void *arg)
+{
+ struct sge_softc *sc;
+ struct mii_data *mii;
+ struct ifnet *ifp;
+
+ sc = arg;
+ SGE_LOCK_ASSERT(sc);
+
+ ifp = sc->sge_ifp;
+ mii = device_get_softc(sc->sge_miibus);
+ mii_tick(mii);
+ if ((sc->sge_flags & SGE_FLAG_LINK) == 0) {
+ sge_miibus_statchg(sc->sge_dev);
+ if ((sc->sge_flags & SGE_FLAG_LINK) != 0 &&
+ !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ sge_start_locked(ifp);
+ }
+ /*
+ * Reclaim transmitted frames here as we do not request
+ * Tx completion interrupt for every queued frames to
+ * reduce excessive interrupts.
+ */
+ sge_txeof(sc);
+ sge_watchdog(sc);
+ callout_reset(&sc->sge_stat_ch, hz, sge_tick, sc);
+}
+
+static void
+sge_intr(void *arg)
+{
+ struct sge_softc *sc;
+ struct ifnet *ifp;
+ uint32_t status;
+
+ sc = arg;
+ SGE_LOCK(sc);
+ ifp = sc->sge_ifp;
+
+ status = CSR_READ_4(sc, IntrStatus);
+ if (status == 0xFFFFFFFF || (status & SGE_INTRS) == 0) {
+ /* Not ours. */
+ SGE_UNLOCK(sc);
+ return;
+ }
+ /* Acknowledge interrupts. */
+ CSR_WRITE_4(sc, IntrStatus, status);
+ /* Disable further interrupts. */
+ CSR_WRITE_4(sc, IntrMask, 0);
+ /*
+ * It seems the controller supports some kind of interrupt
+ * moderation mechanism but we still don't know how to
+ * enable that. To reduce number of generated interrupts
+ * under load we check pending interrupts in a loop. This
+ * will increase number of register access and is not correct
+ * way to handle interrupt moderation but there seems to be
+ * no other way at this time.
+ */
+ for (;;) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
+ if ((status & (INTR_RX_DONE | INTR_RX_IDLE)) != 0) {
+ sge_rxeof(sc);
+ /* Wakeup Rx MAC. */
+ if ((status & INTR_RX_IDLE) != 0)
+ CSR_WRITE_4(sc, RX_CTL,
+ 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB);
+ }
+ if ((status & (INTR_TX_DONE | INTR_TX_IDLE)) != 0)
+ sge_txeof(sc);
+ status = CSR_READ_4(sc, IntrStatus);
+ if ((status & SGE_INTRS) == 0)
+ break;
+ /* Acknowledge interrupts. */
+ CSR_WRITE_4(sc, IntrStatus, status);
+ }
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ /* Re-enable interrupts */
+ CSR_WRITE_4(sc, IntrMask, SGE_INTRS);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ sge_start_locked(ifp);
+ }
+ SGE_UNLOCK(sc);
+}
+
+/*
+ * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
+ * pointers to the fragment pointers.
+ */
+static int
+sge_encap(struct sge_softc *sc, struct mbuf **m_head)
+{
+ struct mbuf *m;
+ struct sge_desc *desc;
+ bus_dma_segment_t txsegs[SGE_MAXTXSEGS];
+ bus_dmamap_t map;
+ uint32_t cflags;
+ int error, nsegs, prod;
+
+ SGE_LOCK_ASSERT(sc);
+
+ prod = sc->sge_cdata.sge_tx_prod;
+ map = sc->sge_cdata.sge_tx_map[prod];
+ /*
+ * Reading Windows inf file indicates SiS controller supports
+ * TSO, VLAN hardware tag insertion/stripping, interrupt
+ * moderation and Tx/Rx checksum offloading. Unfortunately
+ * vendor didn't release these information so we're guessing
+ * descriptor usage with trial and errors.
+ *
+ * Controller seems to support multi-fragmented buffers but
+ * don't know how to enable that feature so limit number of
+ * fragmented Tx buffers to single buffer until we understand
+ * the controller internals.
+ * I assume the controller can pad zero bytes if frame length
+ * is less than 60 bytes and I also think the controller has
+ * no Tx buffer alignment limitation. - Need testing!
+ */
+ if ((*m_head)->m_next != NULL) {
+ m = m_defrag(*m_head, M_DONTWAIT);
+ if (m == NULL) {
+ m_freem(*m_head);
+ *m_head = NULL;
+ return (ENOBUFS);
+ }
+ *m_head = m;
+ }
+ error = bus_dmamap_load_mbuf_sg(sc->sge_cdata.sge_tx_tag, map,
+ *m_head, txsegs, &nsegs, 0);
+ if (error != 0) {
+ m_freem(*m_head);
+ *m_head = NULL;
+ return (error);
+ }
+ /* Check descriptor overrun. */
+ if (sc->sge_cdata.sge_tx_cnt + nsegs >= SGE_TX_RING_CNT) {
+ bus_dmamap_unload(sc->sge_cdata.sge_tx_tag, map);
+ return (ENOBUFS);
+ }
+ bus_dmamap_sync(sc->sge_cdata.sge_tx_tag, map, BUS_DMASYNC_PREWRITE);
+
+ cflags = 0;
+ if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
+ cflags |= TDC_IP_CSUM;
+ if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
+ cflags |= TDC_TCP_CSUM;
+ if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
+ cflags |= TDC_UDP_CSUM;
+ desc = &sc->sge_ldata.sge_tx_ring[prod];
+ desc->sge_sts_size = htole32((*m_head)->m_pkthdr.len);
+ desc->sge_ptr = htole32(SGE_ADDR_LO(txsegs[0].ds_addr));
+ desc->sge_flags = htole32(txsegs[0].ds_len);
+ if (prod == SGE_TX_RING_CNT - 1)
+ desc->sge_flags |= htole32(RING_END);
+ desc->sge_cmdsts = htole32(TDC_DEF | TDC_CRC | TDC_PAD | cflags);
+#if 1
+ if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0)
+ desc->sge_cmdsts |= htole32(TDC_BST);
+#else
+ if ((sc->sge_flags & SGE_FLAG_FDX) == 0) {
+ desc->sge_cmdsts |= htole32(TDC_COL | TDC_CRS | TDC_BKF);
+ if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0)
+ desc->sge_cmdsts |= htole32(TDC_EXT | TDC_BST);
+ }
+#endif
+ /* Request interrupt and give ownership to controller. */
+ if ((prod % SGE_TX_INTR_FRAMES) == 0)
+ desc->sge_cmdsts |= htole32(TDC_OWN | TDC_INTR);
+ else
+ desc->sge_cmdsts |= htole32(TDC_OWN);
+ sc->sge_cdata.sge_tx_mbuf[prod] = *m_head;
+ sc->sge_cdata.sge_tx_cnt++;
+ SGE_INC(sc->sge_cdata.sge_tx_prod, SGE_TX_RING_CNT);
+ return (0);
+}
+
+static void
+sge_start(struct ifnet *ifp)
+{
+ struct sge_softc *sc;
+
+ sc = ifp->if_softc;
+ SGE_LOCK(sc);
+ sge_start_locked(ifp);
+ SGE_UNLOCK(sc);
+}
+
+static void
+sge_start_locked(struct ifnet *ifp)
+{
+ struct sge_softc *sc;
+ struct mbuf *m_head;
+ int queued = 0;
+
+ sc = ifp->if_softc;
+ SGE_LOCK_ASSERT(sc);
+
+ if ((sc->sge_flags & SGE_FLAG_LINK) == 0 ||
+ (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+
+ for (queued = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
+ if (sc->sge_cdata.sge_tx_cnt == SGE_TX_RING_CNT - 1) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
+ if (m_head == NULL)
+ break;
+ if (sge_encap(sc, &m_head)) {
+ IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+ queued++;
+ /*
+ * If there's a BPF listener, bounce a copy of this frame
+ * to him.
+ */
+ BPF_MTAP(ifp, m_head);
+ }
+
+ if (queued > 0) {
+ bus_dmamap_sync(sc->sge_cdata.sge_tx_tag,
+ sc->sge_cdata.sge_tx_dmamap,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB | TX_CTL_POLL);
+ sc->sge_timer = 5;
+ }
+}
+
+static void
+sge_init(void *arg)
+{
+ struct sge_softc *sc;
+
+ sc = arg;
+ SGE_LOCK(sc);
+ sge_init_locked(sc);
+ SGE_UNLOCK(sc);
+}
+
+static void
+sge_init_locked(struct sge_softc *sc)
+{
+ struct ifnet *ifp;
+ struct mii_data *mii;
+ int i;
+
+ SGE_LOCK_ASSERT(sc);
+ ifp = sc->sge_ifp;
+ mii = device_get_softc(sc->sge_miibus);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ return;
+ /*
+ * Cancel pending I/O and free all RX/TX buffers.
+ */
+ sge_stop(sc);
+ sge_reset(sc);
+
+ /* Init circular RX list. */
+ if (sge_list_rx_init(sc) == ENOBUFS) {
+ device_printf(sc->sge_dev, "no memory for Rx buffers\n");
+ sge_stop(sc);
+ return;
+ }
+ /* Init TX descriptors. */
+ sge_list_tx_init(sc);
+ /*
+ * Load the address of the RX and TX lists.
+ */
+ CSR_WRITE_4(sc, TX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_tx_paddr));
+ CSR_WRITE_4(sc, RX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_rx_paddr));
+
+ CSR_WRITE_4(sc, TxMacControl, 0x60);
+ CSR_WRITE_4(sc, 0x6c, 0);
+ CSR_WRITE_4(sc, RxWakeOnLan, 0);
+ CSR_WRITE_4(sc, RxWakeOnLanData, 0);
+ /* Allow receiving VLAN frames. */
+ CSR_WRITE_2(sc, RxMPSControl, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ CSR_WRITE_1(sc, RxMacAddr + i, IF_LLADDR(ifp)[i]);
+ sge_rxfilter(sc);
+
+ /* Initialize default speed/duplex information. */
+ if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0)
+ sc->sge_flags |= SGE_FLAG_SPEED_1000;
+ sc->sge_flags |= SGE_FLAG_FDX;
+ if ((sc->sge_flags & SGE_FLAG_RGMII) != 0)
+ CSR_WRITE_4(sc, StationControl, 0x04008001);
+ else
+ CSR_WRITE_4(sc, StationControl, 0x04000001);
+ /*
+ * XXX Try to mitigate interrupts.
+ */
+ CSR_WRITE_4(sc, IntrControl, 0x08880000);
+#ifdef notyet
+ if (sc->sge_intrcontrol != 0)
+ CSR_WRITE_4(sc, IntrControl, sc->sge_intrcontrol);
+ if (sc->sge_intrtimer != 0)
+ CSR_WRITE_4(sc, IntrTimer, sc->sge_intrtimer);
+#endif
+
+ /*
+ * Clear and enable interrupts.
+ */
+ CSR_WRITE_4(sc, IntrStatus, 0xFFFFFFFF);
+ CSR_WRITE_4(sc, IntrMask, SGE_INTRS);
+
+ /* Enable receiver and transmitter. */
+ CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB);
+ CSR_WRITE_4(sc, RX_CTL, 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB);
+
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ sc->sge_flags &= ~SGE_FLAG_LINK;
+ mii_mediachg(mii);
+ callout_reset(&sc->sge_stat_ch, hz, sge_tick, sc);
+}
+
+/*
+ * Set media options.
+ */
+static int
+sge_ifmedia_upd(struct ifnet *ifp)
+{
+ struct sge_softc *sc;
+ struct mii_data *mii;
+ int error;
+
+ sc = ifp->if_softc;
+ SGE_LOCK(sc);
+ mii = device_get_softc(sc->sge_miibus);
+ sc->sge_flags &= ~SGE_FLAG_LINK;
+ if (mii->mii_instance) {
+ struct mii_softc *miisc;
+ LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
+ mii_phy_reset(miisc);
+ }
+ error = mii_mediachg(mii);
+ SGE_UNLOCK(sc);
+
+ return (error);
+}
+
+/*
+ * Report current media status.
+ */
+static void
+sge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct sge_softc *sc;
+ struct mii_data *mii;
+
+ sc = ifp->if_softc;
+ SGE_LOCK(sc);
+ mii = device_get_softc(sc->sge_miibus);
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ SGE_UNLOCK(sc);
+ return;
+ }
+ mii_pollstat(mii);
+ SGE_UNLOCK(sc);
+ ifmr->ifm_active = mii->mii_media_active;
+ ifmr->ifm_status = mii->mii_media_status;
+}
+
+static int
+sge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+ struct sge_softc *sc;
+ struct ifreq *ifr;
+ struct mii_data *mii;
+ int error = 0, mask;
+
+ sc = ifp->if_softc;
+ ifr = (struct ifreq *)data;
+
+ switch(command) {
+ case SIOCSIFFLAGS:
+ SGE_LOCK(sc);
+ if ((ifp->if_flags & IFF_UP) != 0) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+ ((ifp->if_flags ^ sc->sge_if_flags) &
+ (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+ sge_rxfilter(sc);
+ else
+ sge_init_locked(sc);
+ } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ sge_stop(sc);
+ sc->sge_if_flags = ifp->if_flags;
+ SGE_UNLOCK(sc);
+ break;
+ case SIOCSIFCAP:
+ SGE_LOCK(sc);
+ mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+ if ((mask & IFCAP_TXCSUM) != 0 &&
+ (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
+ ifp->if_capenable ^= IFCAP_TXCSUM;
+ if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
+ ifp->if_hwassist |= SGE_CSUM_FEATURES;
+ else
+ ifp->if_hwassist &= ~SGE_CSUM_FEATURES;
+ }
+ if ((mask & IFCAP_RXCSUM) != 0 &&
+ (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
+ ifp->if_capenable ^= IFCAP_RXCSUM;
+ SGE_UNLOCK(sc);
+ break;
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ SGE_LOCK(sc);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ sge_rxfilter(sc);
+ SGE_UNLOCK(sc);
+ break;
+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ mii = device_get_softc(sc->sge_miibus);
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
+ break;
+ default:
+ error = ether_ioctl(ifp, command, data);
+ break;
+ }
+
+ return (error);
+}
+
+static void
+sge_watchdog(struct sge_softc *sc)
+{
+ struct ifnet *ifp;
+
+ SGE_LOCK_ASSERT(sc);
+ if (sc->sge_timer == 0 || --sc->sge_timer > 0)
+ return;
+
+ ifp = sc->sge_ifp;
+ if ((sc->sge_flags & SGE_FLAG_LINK) == 0) {
+ if (1 || bootverbose)
+ device_printf(sc->sge_dev,
+ "watchdog timeout (lost link)\n");
+ ifp->if_oerrors++;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sge_init_locked(sc);
+ return;
+ }
+ device_printf(sc->sge_dev, "watchdog timeout\n");
+ ifp->if_oerrors++;
+
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sge_init_locked(sc);
+ if (!IFQ_DRV_IS_EMPTY(&sc->sge_ifp->if_snd))
+ sge_start_locked(ifp);
+}
+
+/*
+ * Stop the adapter and free any mbufs allocated to the
+ * RX and TX lists.
+ */
+static void
+sge_stop(struct sge_softc *sc)
+{
+ struct ifnet *ifp;
+
+ ifp = sc->sge_ifp;
+
+ SGE_LOCK_ASSERT(sc);
+
+ sc->sge_timer = 0;
+ callout_stop(&sc->sge_stat_ch);
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+ CSR_WRITE_4(sc, IntrMask, 0);
+ CSR_READ_4(sc, IntrMask);
+ CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
+ /* Stop TX/RX MAC. */
+ CSR_WRITE_4(sc, TX_CTL, 0x1a00);
+ CSR_WRITE_4(sc, RX_CTL, 0x1a00);
+ /* XXX Can we assume active DMA cycles gone? */
+ DELAY(2000);
+ CSR_WRITE_4(sc, IntrMask, 0);
+ CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
+
+ sc->sge_flags &= ~SGE_FLAG_LINK;
+ sge_list_rx_free(sc);
+ sge_list_tx_free(sc);
+}
diff --git a/sys/dev/sge/if_sgereg.h b/sys/dev/sge/if_sgereg.h
new file mode 100644
index 0000000..29253e0
--- /dev/null
+++ b/sys/dev/sge/if_sgereg.h
@@ -0,0 +1,350 @@
+/*-
+ * Copyright (c) 2008, 2009, 2010 Nikolay Denev <ndenev@gmail.com>
+ * Copyright (c) 2007, 2008 Alexander Pohoyda <alexander.pohoyda@gmx.net>
+ * Copyright (c) 1997, 1998, 1999
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 AUTHORS OR
+ * THE VOICES IN THEIR HEADS 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 _IF_SGEREG_H
+#define _IF_SGEREG_H
+
+/*
+ * SiS PCI vendor ID.
+ */
+#define SIS_VENDORID 0x1039
+
+/*
+ * SiS PCI device IDs
+ */
+#define SIS_DEVICEID_190 0x0190
+#define SIS_DEVICEID_191 0x0191
+
+#define TX_CTL 0x00
+#define TX_DESC 0x04
+#define Reserved0 0x08
+#define TX_NEXT 0x0c
+
+#define RX_CTL 0x10
+#define RX_DESC 0x14
+#define Reserved1 0x18
+#define RX_NEXT 0x1c
+
+#define IntrStatus 0x20
+#define IntrMask 0x24
+#define IntrControl 0x28
+#define IntrTimer 0x2c
+
+#define PMControl 0x30
+#define Reserved2 0x34
+#define ROMControl 0x38
+#define ROMInterface 0x3c
+#define StationControl 0x40
+#define GMIIControl 0x44
+#define GMacIOCR 0x48
+#define GMacIOCTL 0x4c
+#define TxMacControl 0x50
+#define TxMacTimeLimit 0x54
+#define RGMIIDelay 0x58
+#define Reserved3 0x5c
+#define RxMacControl 0x60 /* 1 WORD */
+#define RxMacAddr 0x62 /* 6x BYTE */
+#define RxHashTable 0x68 /* 1 LONG */
+#define RxHashTable2 0x6c /* 1 LONG */
+#define RxWakeOnLan 0x70
+#define RxWakeOnLanData 0x74
+#define RxMPSControl 0x78
+#define Reserved4 0x7c
+
+/*
+ * IntrStatus Register Content
+ */
+#define INTR_SOFT 0x40000000
+#define INTR_TIMER 0x20000000
+#define INTR_PAUSE_FRAME 0x00080000
+#define INTR_MAGIC_FRAME 0x00040000
+#define INTR_WAKE_FRAME 0x00020000
+#define INTR_LINK 0x00010000
+#define INTR_RX_IDLE 0x00000080
+#define INTR_RX_DONE 0x00000040
+#define INTR_TXQ1_IDLE 0x00000020
+#define INTR_TXQ1_DONE 0x00000010
+#define INTR_TX_IDLE 0x00000008
+#define INTR_TX_DONE 0x00000004
+#define INTR_RX_HALT 0x00000002
+#define INTR_TX_HALT 0x00000001
+
+#define SGE_INTRS \
+ (INTR_RX_IDLE | INTR_RX_DONE | INTR_TXQ1_IDLE | \
+ INTR_TXQ1_DONE |INTR_TX_IDLE | INTR_TX_DONE | \
+ INTR_TX_HALT | INTR_RX_HALT)
+
+/*
+ * RxStatusDesc Register Content
+ */
+#define RxRES 0x00200000
+#define RxCRC 0x00080000
+#define RxRUNT 0x00100000
+#define RxRWT 0x00400000
+
+/*
+ * RX_CTL Register Content
+ */
+#define RX_CTL_POLL 0x00000010
+#define RX_CTL_ENB 0x00000001
+
+/*
+ * TX_CTL Register Content
+ */
+#define TX_CTL_POLL 0x00000010
+#define TX_CTL_ENB 0x00000001
+
+/*
+ * RxMacControl Register Content
+ */
+#define AcceptBroadcast 0x0800
+#define AcceptMulticast 0x0400
+#define AcceptMyPhys 0x0200
+#define AcceptAllPhys 0x0100
+#define AcceptErr 0x0020
+#define AcceptRunt 0x0010
+
+/* Station control register. */
+#define SC_LOOPBACK 0x80000000
+#define SC_RGMII 0x00008000
+#define SC_FDX 0x00001000
+#define SC_SPEED_MASK 0x00000c00
+#define SC_SPEED_10 0x00000400
+#define SC_SPEED_100 0x00000800
+#define SC_SPEED_1000 0x00000c00
+
+/*
+ * Gigabit Media Independent Interface CTL register
+ */
+#define GMI_DATA 0xffff0000
+#define GMI_DATA_SHIFT 16
+#define GMI_REG 0x0000f800
+#define GMI_REG_SHIFT 11
+#define GMI_PHY 0x000007c0
+#define GMI_PHY_SHIFT 6
+#define GMI_OP_WR 0x00000020
+#define GMI_OP_RD 0x00000000
+#define GMI_REQ 0x00000010
+#define GMI_MDIO 0x00000008
+#define GMI_MDDIR 0x00000004
+#define GMI_MDC 0x00000002
+#define GMI_MDEN 0x00000001
+
+/* Tx descriptor command bits. */
+#define TDC_OWN 0x80000000
+#define TDC_INTR 0x40000000
+#define TDC_THOL3 0x30000000
+#define TDC_THOL2 0x20000000
+#define TDC_THOL1 0x10000000
+#define TDC_THOL0 0x00000000
+#define TDC_LS 0x08000000
+#define TDC_IP_CSUM 0x04000000
+#define TDC_TCP_CSUM 0x02000000
+#define TDC_UDP_CSUM 0x01000000
+#define TDC_BST 0x00800000
+#define TDC_EXT 0x00400000
+#define TDC_DEF 0x00200000
+#define TDC_BKF 0x00100000
+#define TDC_CRS 0x00080000
+#define TDC_COL 0x00040000
+#define TDC_CRC 0x00020000
+#define TDC_PAD 0x00010000
+
+#define SGE_TX_INTR_FRAMES 32
+
+/*
+ * TX descriptor status bits.
+ */
+#define TDS_OWC 0x00080000
+#define TDS_ABT 0x00040000
+#define TDS_FIFO 0x00020000
+#define TDS_CRS 0x00010000
+#define TDS_COLLS 0x0000ffff
+#define SGE_TX_ERROR(x) ((x) & (TDS_OWC | TDS_ABT | TDS_FIFO | TDS_CRS))
+#define TX_ERR_BITS "\20" \
+ "\21CRS\22FIFO\23ABT\24OWC"
+
+/* Rx descriptor command bits. */
+#define RDC_OWN 0x80000000
+#define RDC_INTR 0x40000000
+#define RDC_IP_CSUM 0x20000000
+#define RDC_TCP_CSUM 0x10000000
+#define RDC_UDP_CSUM 0x08000000
+#define RDC_IP_CSUM_OK 0x04000000
+#define RDC_TCP_CSUM_OK 0x02000000
+#define RDC_UDP_CSUM_OK 0x01000000
+#define RDC_WAKEUP 0x00400000
+#define RDC_MAGIC 0x00200000
+#define RDC_PAUSE 0x00100000
+#define RDC_BCAST 0x000c0000
+#define RDC_MCAST 0x00080000
+#define RDC_UCAST 0x00040000
+#define RDC_CRCOFF 0x00020000
+#define RDC_PREADD 0x00010000
+
+/*
+ * RX descriptor status bits
+ */
+#define RDS_TAGON 0x80000000
+#define RDS_DESCS 0x3f000000
+#define RDS_ABORT 0x00800000
+#define RDS_SHORT 0x00400000
+#define RDS_LIMIT 0x00200000
+#define RDS_MIIER 0x00100000
+#define RDS_OVRUN 0x00080000
+#define RDS_NIBON 0x00040000
+#define RDS_COLON 0x00020000
+#define RDS_CRCOK 0x00010000
+#define SGE_RX_ERROR(x) \
+ ((x) & (RDS_COLON | RDS_NIBON | RDS_OVRUN | RDS_MIIER | \
+ RDS_LIMIT | RDS_SHORT | RDS_ABORT))
+#define SGE_RX_NSEGS(x) (((x) & RDS_DESCS) >> 24)
+#define RX_ERR_BITS "\20" \
+ "\21CRCOK\22COLON\23NIBON\24OVRUN" \
+ "\25MIIER\26LIMIT\27SHORT\30ABORT" \
+ "\40TAGON"
+
+#define RING_END 0x80000000
+#define SGE_RX_BYTES(x) ((x) & 0xFFFF)
+#define SGE_INC(x, y) (x) = (((x) + 1) % y)
+
+/* Taken from Solaris driver */
+#define EI_DATA 0xffff0000
+#define EI_DATA_SHIFT 16
+#define EI_OFFSET 0x0000fc00
+#define EI_OFFSET_SHIFT 10
+#define EI_OP 0x00000300
+#define EI_OP_SHIFT 8
+#define EI_OP_RD (2 << EI_OP_SHIFT)
+#define EI_OP_WR (1 << EI_OP_SHIFT)
+#define EI_REQ 0x00000080
+#define EI_DO 0x00000008
+#define EI_DI 0x00000004
+#define EI_CLK 0x00000002
+#define EI_CS 0x00000001
+
+/*
+ * EEPROM Addresses
+ */
+#define EEPROMSignature 0x00
+#define EEPROMCLK 0x01
+#define EEPROMInfo 0x02
+#define EEPROMMACAddr 0x03
+
+struct sge_desc {
+ uint32_t sge_sts_size;
+ uint32_t sge_cmdsts;
+ uint32_t sge_ptr;
+ uint32_t sge_flags;
+};
+
+#define SGE_RX_RING_CNT 256 /* [8, 1024] */
+#define SGE_TX_RING_CNT 256 /* [8, 8192] */
+#define SGE_DESC_ALIGN 16
+#define SGE_MAXTXSEGS 1
+#define SGE_RX_BUF_ALIGN sizeof(uint64_t)
+
+#define SGE_RX_RING_SZ (SGE_RX_RING_CNT * sizeof(struct sge_desc))
+#define SGE_TX_RING_SZ (SGE_TX_RING_CNT * sizeof(struct sge_desc))
+#define SGE_ADDR_LO(x) ((uint64_t) (x) & 0xFFFFFFFF)
+
+struct sge_list_data {
+ struct sge_desc *sge_rx_ring;
+ struct sge_desc *sge_tx_ring;
+ /* physical bus addresses of sge_rx_ring/sge_tx_ring */
+ bus_addr_t sge_rx_paddr;
+ bus_addr_t sge_tx_paddr;
+};
+
+struct sge_chain_data {
+ bus_dma_tag_t sge_tag;
+ bus_dma_tag_t sge_rx_tag;
+ bus_dma_tag_t sge_tx_tag;
+ bus_dmamap_t sge_rx_dmamap;
+ bus_dmamap_t sge_tx_dmamap;
+ bus_dma_tag_t sge_txmbuf_tag;
+ bus_dma_tag_t sge_rxmbuf_tag;
+ struct mbuf *sge_rx_mbuf[SGE_RX_RING_CNT];
+ struct mbuf *sge_tx_mbuf[SGE_TX_RING_CNT];
+ bus_dmamap_t sge_rx_map[SGE_RX_RING_CNT];
+ bus_dmamap_t sge_rx_spare_map;
+ bus_dmamap_t sge_tx_map[SGE_TX_RING_CNT];
+ int sge_rx_cons;
+ int sge_tx_prod;
+ int sge_tx_cons;
+ int sge_tx_cnt;
+};
+
+struct sge_type {
+ uint16_t sge_vid;
+ uint16_t sge_did;
+ char *sge_name;
+};
+
+struct sge_softc {
+ struct ifnet *sge_ifp; /* interface info */
+ struct resource *sge_res;
+ int sge_res_id;
+ int sge_res_type;
+ struct resource *sge_irq;
+ void *sge_intrhand;
+ device_t sge_dev;
+ device_t sge_miibus;
+ uint8_t sge_rev;
+ struct sge_list_data sge_ldata;
+ struct sge_chain_data sge_cdata;
+ struct callout sge_stat_ch;
+ int sge_timer;
+ int sge_flags;
+#define SGE_FLAG_FASTETHER 0x0001
+#define SGE_FLAG_RGMII 0x0010
+#define SGE_FLAG_SPEED_1000 0x2000
+#define SGE_FLAG_FDX 0x4000
+#define SGE_FLAG_LINK 0x8000
+ int sge_if_flags;
+ int sge_intrcontrol;
+ int sge_intrtimer;
+ struct mtx sge_mtx;
+};
+
+#define SGE_LOCK(_sc) mtx_lock(&(_sc)->sge_mtx)
+#define SGE_UNLOCK(_sc) mtx_unlock(&(_sc)->sge_mtx)
+#define SGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sge_mtx, MA_OWNED)
+
+#define SGE_TIMEOUT 1000
+
+#endif /* _IF_SGEREG_H */
diff --git a/sys/dev/siba/siba.c b/sys/dev/siba/siba.c
index 541585b..4ee11ca 100644
--- a/sys/dev/siba/siba.c
+++ b/sys/dev/siba/siba.c
@@ -632,7 +632,7 @@ static device_method_t siba_methods[] = {
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_write_ivar, siba_write_ivar),
- {0, 0},
+ KOBJMETHOD_END
};
static driver_t siba_driver = {
diff --git a/sys/dev/siba/siba_bwn.c b/sys/dev/siba/siba_bwn.c
index a5513bd..b335484 100644
--- a/sys/dev/siba/siba_bwn.c
+++ b/sys/dev/siba/siba_bwn.c
@@ -97,8 +97,6 @@ static const struct siba_dev {
{ PCI_VENDOR_BROADCOM, 0x432b, "Unknown" }
};
-device_t siba_add_child(device_t, struct siba_softc *, int, const char *,
- int);
int siba_core_attach(struct siba_softc *);
int siba_core_detach(struct siba_softc *);
int siba_core_suspend(struct siba_softc *);
@@ -154,6 +152,7 @@ siba_bwn_attach(device_t dev)
siba->siba_pci_vid = pci_get_vendor(dev);
siba->siba_pci_subvid = pci_get_subvendor(dev);
siba->siba_pci_subdid = pci_get_subdevice(dev);
+ siba->siba_pci_revid = pci_get_revid(dev);
return (siba_core_attach(siba));
}
@@ -238,15 +237,6 @@ siba_bwn_resume(device_t dev)
return (0);
}
-static device_t
-siba_bwn_add_child(device_t dev, int order, const char *name, int unit)
-{
- struct siba_bwn_softc *ssc = device_get_softc(dev);
- struct siba_softc *siba = &ssc->ssc_siba;
-
- return (siba_add_child(dev, siba, order, name, unit));
-}
-
/* proxying to the parent */
static struct resource *
siba_bwn_alloc_resource(device_t dev, device_t child, int type, int *rid,
@@ -332,6 +322,71 @@ siba_bwn_msi_count(device_t dev, device_t child)
return (pci_msi_count(dev));
}
+static int
+siba_bwn_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+ struct siba_dev_softc *sd;
+ struct siba_softc *siba;;
+
+ sd = device_get_ivars(child);
+ siba = sd->sd_bus;
+
+ switch (which) {
+ case SIBA_IVAR_VENDOR:
+ *result = sd->sd_id.sd_vendor;
+ break;
+ case SIBA_IVAR_DEVICE:
+ *result = sd->sd_id.sd_device;
+ break;
+ case SIBA_IVAR_REVID:
+ *result = sd->sd_id.sd_rev;
+ break;
+ case SIBA_IVAR_PCI_VENDOR:
+ *result = siba->siba_pci_vid;
+ break;
+ case SIBA_IVAR_PCI_DEVICE:
+ *result = siba->siba_pci_did;
+ break;
+ case SIBA_IVAR_PCI_SUBVENDOR:
+ *result = siba->siba_pci_subvid;
+ break;
+ case SIBA_IVAR_PCI_SUBDEVICE:
+ *result = siba->siba_pci_subdid;
+ break;
+ case SIBA_IVAR_PCI_REVID:
+ *result = siba->siba_pci_revid;
+ break;
+ case SIBA_IVAR_CHIPID:
+ *result = siba->siba_chipid;
+ break;
+ case SIBA_IVAR_CHIPREV:
+ *result = siba->siba_chiprev;
+ break;
+ case SIBA_IVAR_CHIPPKG:
+ *result = siba->siba_chippkg;
+ break;
+ case SIBA_IVAR_TYPE:
+ *result = siba->siba_type;
+ break;
+ case SIBA_IVAR_CC_PMUFREQ:
+ *result = siba->siba_cc.scc_pmu.freq;
+ break;
+ case SIBA_IVAR_CC_CAPS:
+ *result = siba->siba_cc.scc_caps;
+ break;
+ case SIBA_IVAR_CC_POWERDELAY:
+ *result = siba->siba_cc.scc_powerup_delay;
+ break;
+ case SIBA_IVAR_PCICORE_REVID:
+ *result = siba->siba_pci.spc_dev->sd_id.sd_rev;
+ break;
+ default:
+ return (ENOENT);
+ }
+
+ return (0);
+}
+
static device_method_t siba_bwn_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, siba_bwn_probe),
@@ -342,9 +397,9 @@ static device_method_t siba_bwn_methods[] = {
DEVMETHOD(device_resume, siba_bwn_resume),
/* Bus interface */
- DEVMETHOD(bus_add_child, siba_bwn_add_child),
DEVMETHOD(bus_alloc_resource, siba_bwn_alloc_resource),
DEVMETHOD(bus_release_resource, siba_bwn_release_resource),
+ DEVMETHOD(bus_read_ivar, siba_bwn_read_ivar),
DEVMETHOD(bus_setup_intr, siba_bwn_setup_intr),
DEVMETHOD(bus_teardown_intr, siba_bwn_teardown_intr),
@@ -354,7 +409,7 @@ static device_method_t siba_bwn_methods[] = {
DEVMETHOD(pci_release_msi, siba_bwn_release_msi),
DEVMETHOD(pci_msi_count, siba_bwn_msi_count),
- { 0,0 }
+ KOBJMETHOD_END
};
static driver_t siba_bwn_driver = {
"siba_bwn",
diff --git a/sys/dev/siba/siba_cc.c b/sys/dev/siba/siba_cc.c
index db0aac5..67af696 100644
--- a/sys/dev/siba/siba_cc.c
+++ b/sys/dev/siba/siba_cc.c
@@ -141,7 +141,7 @@ static device_method_t siba_cc_methods[] = {
DEVMETHOD(device_attach, siba_cc_attach),
DEVMETHOD(device_probe, siba_cc_probe),
- {0, 0},
+ KOBJMETHOD_END
};
static driver_t siba_cc_driver = {
diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
index d19771d..979ac14 100644
--- a/sys/dev/siba/siba_core.c
+++ b/sys/dev/siba/siba_core.c
@@ -133,8 +133,13 @@ static void siba_pci_write_multi_4(struct siba_dev_softc *, const void *,
size_t, uint16_t);
static const char *siba_core_name(uint16_t);
static void siba_pcicore_init(struct siba_pci *);
-device_t siba_add_child(device_t, struct siba_softc *, int, const char *,
- int);
+static uint32_t siba_read_4_sub(struct siba_dev_softc *, uint16_t);
+static void siba_write_4_sub(struct siba_dev_softc *, uint16_t, uint32_t);
+static void siba_powerup_sub(struct siba_softc *, int);
+static int siba_powerdown_sub(struct siba_softc *);
+static int siba_dev_isup_sub(struct siba_dev_softc *);
+static void siba_dev_up_sub(struct siba_dev_softc *, uint32_t);
+static void siba_dev_down_sub(struct siba_dev_softc *, uint32_t);
int siba_core_attach(struct siba_softc *);
int siba_core_detach(struct siba_softc *);
int siba_core_suspend(struct siba_softc *);
@@ -183,7 +188,7 @@ siba_core_attach(struct siba_softc *siba)
/* XXX init PCI or PCMCIA host devices */
- siba_powerup(siba, 0);
+ siba_powerup_sub(siba, 0);
/* init ChipCommon */
scc = &siba->siba_cc;
@@ -194,20 +199,16 @@ siba_core_attach(struct siba_softc *siba)
siba_cc_powerup_delay(scc);
}
- /* fetch various internal informations for PCI */
- siba->siba_board_vendor = pci_read_config(siba->siba_dev,
- PCIR_SUBVEND_0, 2);
- siba->siba_board_type = pci_read_config(siba->siba_dev, PCIR_SUBDEV_0,
- 2);
- siba->siba_board_rev = pci_read_config(siba->siba_dev, PCIR_REVID, 2);
error = siba_pci_sprom(siba, &siba->siba_sprom);
if (error) {
- siba_powerdown(siba);
+ siba_powerdown_sub(siba);
return (error);
}
- siba_powerdown(siba);
- return (0);
+ siba_pcicore_init(&siba->siba_pci);
+ siba_powerdown_sub(siba);
+
+ return (bus_generic_attach(siba->siba_dev));
}
int
@@ -277,6 +278,7 @@ siba_scan(struct siba_softc *siba)
{
struct siba_dev_softc *sd;
uint32_t idhi, tmp;
+ device_t child;
int base, dev_i = 0, error, i, is_pcie, n_80211 = 0, n_cc = 0,
n_pci = 0;
@@ -387,6 +389,14 @@ siba_scan(struct siba_softc *siba)
break;
}
dev_i++;
+
+ child = device_add_child(siba->siba_dev, NULL, -1);
+ if (child == NULL) {
+ device_printf(siba->siba_dev, "child attach failed\n");
+ continue;
+ }
+
+ device_set_ivars(child, sd);
}
siba->siba_ndevs = dev_i;
}
@@ -737,7 +747,16 @@ siba_pci_write_multi_4(struct siba_dev_softc *sd, const void *buffer,
}
void
-siba_powerup(struct siba_softc *siba, int dynamic)
+siba_powerup(device_t dev, int dynamic)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+
+ siba_powerup_sub(siba, dynamic);
+}
+
+static void
+siba_powerup_sub(struct siba_softc *siba, int dynamic)
{
siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1);
@@ -793,77 +812,101 @@ siba_cc_clock(struct siba_cc *scc, enum siba_clock clock)
}
uint16_t
-siba_read_2(struct siba_dev_softc *sd, uint16_t offset)
+siba_read_2(device_t dev, uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
return (sd->sd_ops->read_2(sd, offset));
}
uint32_t
-siba_read_4(struct siba_dev_softc *sd, uint16_t offset)
+siba_read_4(device_t dev, uint16_t offset)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+
+ return (siba_read_4_sub(sd, offset));
+}
+
+static uint32_t
+siba_read_4_sub(struct siba_dev_softc *sd, uint16_t offset)
{
return (sd->sd_ops->read_4(sd, offset));
}
void
-siba_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value)
+siba_write_2(device_t dev, uint16_t offset, uint16_t value)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->write_2(sd, offset, value);
}
void
-siba_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value)
+siba_write_4(device_t dev, uint16_t offset, uint32_t value)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+
+ return (siba_write_4_sub(sd, offset, value));
+}
+
+static void
+siba_write_4_sub(struct siba_dev_softc *sd, uint16_t offset, uint32_t value)
{
sd->sd_ops->write_4(sd, offset, value);
}
void
-siba_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count,
+siba_read_multi_1(device_t dev, void *buffer, size_t count,
uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->read_multi_1(sd, buffer, count, offset);
}
void
-siba_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count,
+siba_read_multi_2(device_t dev, void *buffer, size_t count,
uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->read_multi_2(sd, buffer, count, offset);
}
void
-siba_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count,
+siba_read_multi_4(device_t dev, void *buffer, size_t count,
uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->read_multi_4(sd, buffer, count, offset);
}
void
-siba_write_multi_1(struct siba_dev_softc *sd, const void *buffer,
- size_t count, uint16_t offset)
+siba_write_multi_1(device_t dev, const void *buffer, size_t count,
+ uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->write_multi_1(sd, buffer, count, offset);
}
void
-siba_write_multi_2(struct siba_dev_softc *sd, const void *buffer,
- size_t count, uint16_t offset)
+siba_write_multi_2(device_t dev, const void *buffer, size_t count,
+ uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->write_multi_2(sd, buffer, count, offset);
}
void
-siba_write_multi_4(struct siba_dev_softc *sd, const void *buffer,
- size_t count, uint16_t offset)
+siba_write_multi_4(device_t dev, const void *buffer, size_t count,
+ uint16_t offset)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
sd->sd_ops->write_multi_4(sd, buffer, count, offset);
}
@@ -1676,7 +1719,16 @@ siba_sprom_r123_antgain(uint8_t sprom_revision, const uint16_t *in,
#undef SIBA_SHIFTOUT
int
-siba_powerdown(struct siba_softc *siba)
+siba_powerdown(device_t dev)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+
+ return (siba_powerdown_sub(siba));
+}
+
+static int
+siba_powerdown_sub(struct siba_softc *siba)
{
struct siba_cc *scc;
@@ -1701,61 +1753,77 @@ siba_pcicore_init(struct siba_pci *spc)
return;
siba = sd->sd_bus;
- if (!siba_dev_isup(sd))
- siba_dev_up(sd, 0);
+ if (!siba_dev_isup_sub(sd))
+ siba_dev_up_sub(sd, 0);
KASSERT(spc->spc_hostmode == 0,
("%s:%d: hostmode", __func__, __LINE__));
/* disable PCI interrupt */
- siba_write_4(spc->spc_dev, SIBA_INTR_MASK, 0);
+ siba_write_4_sub(spc->spc_dev, SIBA_INTR_MASK, 0);
}
int
-siba_dev_isup(struct siba_dev_softc *sd)
+siba_dev_isup(device_t dev)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+
+ return (siba_dev_isup_sub(sd));
+}
+
+static int
+siba_dev_isup_sub(struct siba_dev_softc *sd)
{
uint32_t reject, val;
reject = siba_tmslow_reject_bitmask(sd);
- val = siba_read_4(sd, SIBA_TGSLOW);
+ val = siba_read_4_sub(sd, SIBA_TGSLOW);
val &= SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_RESET | reject;
return (val == SIBA_TGSLOW_CLOCK);
}
void
-siba_dev_up(struct siba_dev_softc *sd, uint32_t flags)
+siba_dev_up(device_t dev, uint32_t flags)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+
+ siba_dev_up_sub(sd, flags);
+}
+
+static void
+siba_dev_up_sub(struct siba_dev_softc *sd, uint32_t flags)
{
uint32_t val;
- siba_dev_down(sd, flags);
- siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK |
- SIBA_TGSLOW_FGC | flags);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_dev_down_sub(sd, flags);
+ siba_write_4_sub(sd, SIBA_TGSLOW,
+ SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags);
+ siba_read_4_sub(sd, SIBA_TGSLOW);
DELAY(1);
- if (siba_read_4(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR)
- siba_write_4(sd, SIBA_TGSHIGH, 0);
+ if (siba_read_4_sub(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR)
+ siba_write_4_sub(sd, SIBA_TGSHIGH, 0);
- val = siba_read_4(sd, SIBA_IAS);
+ val = siba_read_4_sub(sd, SIBA_IAS);
if (val & (SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT)) {
val &= ~(SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT);
- siba_write_4(sd, SIBA_IAS, val);
+ siba_write_4_sub(sd, SIBA_IAS, val);
}
- siba_write_4(sd, SIBA_TGSLOW,
+ siba_write_4_sub(sd, SIBA_TGSLOW,
SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_read_4_sub(sd, SIBA_TGSLOW);
DELAY(1);
- siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_write_4_sub(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags);
+ siba_read_4_sub(sd, SIBA_TGSLOW);
DELAY(1);
}
static uint32_t
siba_tmslow_reject_bitmask(struct siba_dev_softc *sd)
{
- uint32_t rev = siba_read_4(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV;
+ uint32_t rev = siba_read_4_sub(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV;
switch (rev) {
case SIBA_IDLOW_SSBREV_22:
@@ -1776,20 +1844,28 @@ siba_tmslow_reject_bitmask(struct siba_dev_softc *sd)
}
void
-siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
+siba_dev_down(device_t dev, uint32_t flags)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+
+ siba_dev_down_sub(sd, flags);
+}
+
+static void
+siba_dev_down_sub(struct siba_dev_softc *sd, uint32_t flags)
{
struct siba_softc *siba = sd->sd_bus;
uint32_t reject, val;
int i;
- if (siba_read_4(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET)
+ if (siba_read_4_sub(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET)
return;
reject = siba_tmslow_reject_bitmask(sd);
- siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK);
+ siba_write_4_sub(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK);
for (i = 0; i < 1000; i++) {
- val = siba_read_4(sd, SIBA_TGSLOW);
+ val = siba_read_4_sub(sd, SIBA_TGSLOW);
if (val & reject)
break;
DELAY(10);
@@ -1799,7 +1875,7 @@ siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
reject, SIBA_TGSLOW);
}
for (i = 0; i < 1000; i++) {
- val = siba_read_4(sd, SIBA_TGSHIGH);
+ val = siba_read_4_sub(sd, SIBA_TGSHIGH);
if (!(val & SIBA_TGSHIGH_BUSY))
break;
DELAY(10);
@@ -1809,12 +1885,12 @@ siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
SIBA_TGSHIGH_BUSY, SIBA_TGSHIGH);
}
- siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK |
+ siba_write_4_sub(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK |
reject | SIBA_TGSLOW_RESET | flags);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_read_4_sub(sd, SIBA_TGSLOW);
DELAY(1);
- siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags);
- siba_read_4(sd, SIBA_TGSLOW);
+ siba_write_4_sub(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags);
+ siba_read_4_sub(sd, SIBA_TGSLOW);
DELAY(1);
}
@@ -1831,21 +1907,22 @@ siba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd)
SIBA_PCICORE_SBTOPCI_PREF | SIBA_PCICORE_SBTOPCI_BURST);
if (psd->sd_id.sd_rev < 5) {
- tmp = siba_read_4(psd, SIBA_IMCFGLO);
+ tmp = siba_read_4_sub(psd, SIBA_IMCFGLO);
tmp &= ~SIBA_IMCFGLO_SERTO;
tmp = (tmp | 2) & ~SIBA_IMCFGLO_REQTO;
tmp |= 3 << 4 /* SIBA_IMCFGLO_REQTO_SHIFT */;
- siba_write_4(psd, SIBA_IMCFGLO, tmp);
+ siba_write_4_sub(psd, SIBA_IMCFGLO, tmp);
/* broadcast value */
sd = (siba->siba_cc.scc_dev != NULL) ?
siba->siba_cc.scc_dev : siba->siba_pci.spc_dev;
if (sd != NULL) {
- siba_write_4(sd, SIBA_PCICORE_BCAST_ADDR,
+ siba_write_4_sub(sd, SIBA_PCICORE_BCAST_ADDR,
0xfd8);
- siba_read_4(sd, SIBA_PCICORE_BCAST_ADDR);
- siba_write_4(sd, SIBA_PCICORE_BCAST_DATA, 0);
- siba_read_4(sd, SIBA_PCICORE_BCAST_DATA);
+ siba_read_4_sub(sd, SIBA_PCICORE_BCAST_ADDR);
+ siba_write_4_sub(sd,
+ SIBA_PCICORE_BCAST_DATA, 0);
+ siba_read_4_sub(sd, SIBA_PCICORE_BCAST_DATA);
}
} else if (psd->sd_id.sd_rev >= 11) {
tmp = siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2);
@@ -1869,27 +1946,31 @@ siba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd)
}
void
-siba_pcicore_intr(struct siba_pci *spc, struct siba_dev_softc *sd)
+siba_pcicore_intr(device_t dev)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+ struct siba_pci *spc = &siba->siba_pci;
struct siba_dev_softc *psd = spc->spc_dev;
- struct siba_softc *siba;
uint32_t tmp;
- if (sd->sd_bus->siba_type != SIBA_TYPE_PCI || !psd)
+ if (siba->siba_type != SIBA_TYPE_PCI || !psd)
return;
- siba = psd->sd_bus;
+ KASSERT(siba == psd->sd_bus, ("different pointers"));
+
/* enable interrupts */
if (siba->siba_dev != NULL &&
- (psd->sd_id.sd_rev >= 6 || psd->sd_id.sd_device == SIBA_DEVID_PCIE)) {
+ (psd->sd_id.sd_rev >= 6 ||
+ psd->sd_id.sd_device == SIBA_DEVID_PCIE)) {
tmp = pci_read_config(siba->siba_dev, SIBA_IRQMASK, 4);
tmp |= (1 << sd->sd_coreidx) << 8;
pci_write_config(siba->siba_dev, SIBA_IRQMASK, tmp, 4);
} else {
- tmp = siba_read_4(sd, SIBA_TPS);
+ tmp = siba_read_4_sub(sd, SIBA_TPS);
tmp &= SIBA_TPS_BPFLAG;
- siba_write_4(psd, SIBA_INTR_MASK,
- siba_read_4(psd, SIBA_INTR_MASK) | (1 << tmp));
+ siba_write_4_sub(psd, SIBA_INTR_MASK,
+ siba_read_4_sub(psd, SIBA_INTR_MASK) | (1 << tmp));
}
/* setup PCIcore */
@@ -1901,14 +1982,14 @@ static uint32_t
siba_pcicore_read_4(struct siba_pci *spc, uint16_t offset)
{
- return (siba_read_4(spc->spc_dev, offset));
+ return (siba_read_4_sub(spc->spc_dev, offset));
}
static void
siba_pcicore_write_4(struct siba_pci *spc, uint16_t offset, uint32_t value)
{
- siba_write_4(spc->spc_dev, offset, value);
+ siba_write_4_sub(spc->spc_dev, offset, value);
}
static uint32_t
@@ -1948,68 +2029,27 @@ siba_pcie_mdio_write(struct siba_pci *spc, uint8_t device, uint8_t address,
}
uint32_t
-siba_dma_translation(struct siba_dev_softc *sd)
+siba_dma_translation(device_t dev)
{
+#ifdef INVARIANTS
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
- KASSERT(sd->sd_bus->siba_type == SIBA_TYPE_PCI,
- ("unsupported bustype %d\n", sd->sd_bus->siba_type));
+ KASSERT(siba->siba_type == SIBA_TYPE_PCI,
+ ("unsupported bustype %d\n", siba->siba_type));
+#endif
return (SIBA_PCI_DMA);
}
void
-siba_barrier(struct siba_dev_softc *sd, int flags)
+siba_barrier(device_t dev, int flags)
{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
struct siba_softc *siba = sd->sd_bus;
SIBA_BARRIER(siba, flags);
}
-/*
- * Attach it as child.
- */
-device_t
-siba_add_child(device_t dev, struct siba_softc *siba, int order,
- const char *name, int unit)
-{
- struct siba_dev_softc *sd;
- device_t child;
- int idx = 0, i;
-
- child = device_add_child(dev, name, unit);
- if (child == NULL)
- return (NULL);
-
- siba_powerup(siba, 0);
- siba_pcicore_init(&siba->siba_pci);
- siba_powerdown(siba);
-
- for (i = 0; i < siba->siba_ndevs; i++) {
- sd = &(siba->siba_devs[i]);
-
- if (sd->sd_id.sd_device != SIBA_DEVID_80211) {
- DPRINTF(siba, SIBA_DEBUG_CORE,
- "skip to register coreid %#x (%s)\n",
- sd->sd_id.sd_device,
- siba_core_name(sd->sd_id.sd_device));
- continue;
- }
-
- DPRINTF(siba, SIBA_DEBUG_CORE,
- "siba: attaching coreid %#x (%s) idx %d\n",
- sd->sd_id.sd_device,
- siba_core_name(sd->sd_id.sd_device), idx);
-
- KASSERT(sd->sd_id.sd_device == SIBA_DEVID_80211,
- ("%s:%d: SIBA_DEVID_80211 is only supportted currently.",
- __func__, __LINE__));
-
- device_set_ivars(child, sd);
- device_probe_and_attach(child);
- idx++;
- }
- return (child);
-}
-
static void
siba_cc_suspend(struct siba_cc *scc)
{
@@ -2041,10 +2081,10 @@ siba_core_resume(struct siba_softc *siba)
siba->siba_pci.spc_inited = 0;
siba->siba_curdev = NULL;
- siba_powerup(siba, 0);
+ siba_powerup_sub(siba, 0);
/* XXX setup H/W for PCMCIA??? */
siba_cc_resume(&siba->siba_cc);
- siba_powerdown(siba);
+ siba_powerdown_sub(siba);
return (0);
}
@@ -2063,9 +2103,11 @@ siba_cc_regctl_setmask(struct siba_cc *cc, uint32_t offset, uint32_t mask,
}
void
-siba_cc_pmu_set_ldovolt(struct siba_cc *scc, int id, uint32_t volt)
+siba_cc_pmu_set_ldovolt(device_t dev, int id, uint32_t volt)
{
- struct siba_softc *siba = scc->scc_dev->sd_bus;
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+ struct siba_cc *scc = &siba->siba_cc;
uint32_t *p = NULL, info[5][3] = {
{ 2, 25, 0xf },
{ 3, 1, 0xf },
@@ -2107,9 +2149,11 @@ siba_cc_pmu_set_ldovolt(struct siba_cc *scc, int id, uint32_t volt)
}
void
-siba_cc_pmu_set_ldoparef(struct siba_cc *scc, uint8_t on)
+siba_cc_pmu_set_ldoparef(device_t dev, uint8_t on)
{
- struct siba_softc *siba = scc->scc_dev->sd_bus;
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+ struct siba_cc *scc = &siba->siba_cc;
int ldo;
ldo = ((siba->siba_chipid == 0x4312) ? SIBA_CC_PMU_4312_PA_REF :
@@ -2124,3 +2168,419 @@ siba_cc_pmu_set_ldoparef(struct siba_cc *scc, uint8_t on)
SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, ~(1 << ldo));
SIBA_CC_READ32(scc, SIBA_CC_PMU_MINRES);
}
+
+int
+siba_read_sprom(device_t dev, device_t child, int which, uintptr_t *result)
+{
+ struct siba_dev_softc *sd = device_get_ivars(child);
+ struct siba_softc *siba = sd->sd_bus;
+
+ switch (which) {
+ case SIBA_SPROMVAR_REV:
+ *result = siba->siba_sprom.rev;
+ break;
+ case SIBA_SPROMVAR_MAC_80211BG:
+ *((uint8_t **) result) = siba->siba_sprom.mac_80211bg;
+ break;
+ case SIBA_SPROMVAR_MAC_ETH:
+ *((uint8_t **) result) = siba->siba_sprom.mac_eth;
+ break;
+ case SIBA_SPROMVAR_MAC_80211A:
+ *((uint8_t **) result) = siba->siba_sprom.mac_80211a;
+ break;
+ case SIBA_SPROMVAR_MII_ETH0:
+ *result = siba->siba_sprom.mii_eth0;
+ break;
+ case SIBA_SPROMVAR_MII_ETH1:
+ *result = siba->siba_sprom.mii_eth1;
+ break;
+ case SIBA_SPROMVAR_MDIO_ETH0:
+ *result = siba->siba_sprom.mdio_eth0;
+ break;
+ case SIBA_SPROMVAR_MDIO_ETH1:
+ *result = siba->siba_sprom.mdio_eth1;
+ break;
+ case SIBA_SPROMVAR_BREV:
+ *result = siba->siba_sprom.brev;
+ break;
+ case SIBA_SPROMVAR_CCODE:
+ *result = siba->siba_sprom.ccode;
+ break;
+ case SIBA_SPROMVAR_ANT_A:
+ *result = siba->siba_sprom.ant_a;
+ break;
+ case SIBA_SPROMVAR_ANT_BG:
+ *result = siba->siba_sprom.ant_bg;
+ break;
+ case SIBA_SPROMVAR_PA0B0:
+ *result = siba->siba_sprom.pa0b0;
+ break;
+ case SIBA_SPROMVAR_PA0B1:
+ *result = siba->siba_sprom.pa0b1;
+ break;
+ case SIBA_SPROMVAR_PA0B2:
+ *result = siba->siba_sprom.pa0b2;
+ break;
+ case SIBA_SPROMVAR_PA1B0:
+ *result = siba->siba_sprom.pa1b0;
+ break;
+ case SIBA_SPROMVAR_PA1B1:
+ *result = siba->siba_sprom.pa1b1;
+ break;
+ case SIBA_SPROMVAR_PA1B2:
+ *result = siba->siba_sprom.pa1b2;
+ break;
+ case SIBA_SPROMVAR_PA1LOB0:
+ *result = siba->siba_sprom.pa1lob0;
+ break;
+ case SIBA_SPROMVAR_PA1LOB1:
+ *result = siba->siba_sprom.pa1lob1;
+ break;
+ case SIBA_SPROMVAR_PA1LOB2:
+ *result = siba->siba_sprom.pa1lob2;
+ break;
+ case SIBA_SPROMVAR_PA1HIB0:
+ *result = siba->siba_sprom.pa1hib0;
+ break;
+ case SIBA_SPROMVAR_PA1HIB1:
+ *result = siba->siba_sprom.pa1hib1;
+ break;
+ case SIBA_SPROMVAR_PA1HIB2:
+ *result = siba->siba_sprom.pa1hib2;
+ break;
+ case SIBA_SPROMVAR_GPIO0:
+ *result = siba->siba_sprom.gpio0;
+ break;
+ case SIBA_SPROMVAR_GPIO1:
+ *result = siba->siba_sprom.gpio1;
+ break;
+ case SIBA_SPROMVAR_GPIO2:
+ *result = siba->siba_sprom.gpio2;
+ break;
+ case SIBA_SPROMVAR_GPIO3:
+ *result = siba->siba_sprom.gpio3;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_AL:
+ *result = siba->siba_sprom.maxpwr_al;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_A:
+ *result = siba->siba_sprom.maxpwr_a;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_AH:
+ *result = siba->siba_sprom.maxpwr_ah;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_BG:
+ *result = siba->siba_sprom.maxpwr_bg;
+ break;
+ case SIBA_SPROMVAR_RXPO2G:
+ *result = siba->siba_sprom.rxpo2g;
+ break;
+ case SIBA_SPROMVAR_RXPO5G:
+ *result = siba->siba_sprom.rxpo5g;
+ break;
+ case SIBA_SPROMVAR_TSSI_A:
+ *result = siba->siba_sprom.tssi_a;
+ break;
+ case SIBA_SPROMVAR_TSSI_BG:
+ *result = siba->siba_sprom.tssi_bg;
+ break;
+ case SIBA_SPROMVAR_TRI2G:
+ *result = siba->siba_sprom.tri2g;
+ break;
+ case SIBA_SPROMVAR_TRI5GL:
+ *result = siba->siba_sprom.tri5gl;
+ break;
+ case SIBA_SPROMVAR_TRI5G:
+ *result = siba->siba_sprom.tri5g;
+ break;
+ case SIBA_SPROMVAR_TRI5GH:
+ *result = siba->siba_sprom.tri5gh;
+ break;
+ case SIBA_SPROMVAR_RSSISAV2G:
+ *result = siba->siba_sprom.rssisav2g;
+ break;
+ case SIBA_SPROMVAR_RSSISMC2G:
+ *result = siba->siba_sprom.rssismc2g;
+ break;
+ case SIBA_SPROMVAR_RSSISMF2G:
+ *result = siba->siba_sprom.rssismf2g;
+ break;
+ case SIBA_SPROMVAR_BXA2G:
+ *result = siba->siba_sprom.bxa2g;
+ break;
+ case SIBA_SPROMVAR_RSSISAV5G:
+ *result = siba->siba_sprom.rssisav5g;
+ break;
+ case SIBA_SPROMVAR_RSSISMC5G:
+ *result = siba->siba_sprom.rssismc5g;
+ break;
+ case SIBA_SPROMVAR_RSSISMF5G:
+ *result = siba->siba_sprom.rssismf5g;
+ break;
+ case SIBA_SPROMVAR_BXA5G:
+ *result = siba->siba_sprom.bxa5g;
+ break;
+ case SIBA_SPROMVAR_CCK2GPO:
+ *result = siba->siba_sprom.cck2gpo;
+ break;
+ case SIBA_SPROMVAR_OFDM2GPO:
+ *result = siba->siba_sprom.ofdm2gpo;
+ break;
+ case SIBA_SPROMVAR_OFDM5GLPO:
+ *result = siba->siba_sprom.ofdm5glpo;
+ break;
+ case SIBA_SPROMVAR_OFDM5GPO:
+ *result = siba->siba_sprom.ofdm5gpo;
+ break;
+ case SIBA_SPROMVAR_OFDM5GHPO:
+ *result = siba->siba_sprom.ofdm5ghpo;
+ break;
+ case SIBA_SPROMVAR_BF_LO:
+ *result = siba->siba_sprom.bf_lo;
+ break;
+ case SIBA_SPROMVAR_BF_HI:
+ *result = siba->siba_sprom.bf_hi;
+ break;
+ case SIBA_SPROMVAR_BF2_LO:
+ *result = siba->siba_sprom.bf2_lo;
+ break;
+ case SIBA_SPROMVAR_BF2_HI:
+ *result = siba->siba_sprom.bf2_hi;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+int
+siba_write_sprom(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct siba_dev_softc *sd = device_get_ivars(child);
+ struct siba_softc *siba = sd->sd_bus;
+
+ switch (which) {
+ case SIBA_SPROMVAR_REV:
+ siba->siba_sprom.rev = value;
+ break;
+ case SIBA_SPROMVAR_MII_ETH0:
+ siba->siba_sprom.mii_eth0 = value;
+ break;
+ case SIBA_SPROMVAR_MII_ETH1:
+ siba->siba_sprom.mii_eth1 = value;
+ break;
+ case SIBA_SPROMVAR_MDIO_ETH0:
+ siba->siba_sprom.mdio_eth0 = value;
+ break;
+ case SIBA_SPROMVAR_MDIO_ETH1:
+ siba->siba_sprom.mdio_eth1 = value;
+ break;
+ case SIBA_SPROMVAR_BREV:
+ siba->siba_sprom.brev = value;
+ break;
+ case SIBA_SPROMVAR_CCODE:
+ siba->siba_sprom.ccode = value;
+ break;
+ case SIBA_SPROMVAR_ANT_A:
+ siba->siba_sprom.ant_a = value;
+ break;
+ case SIBA_SPROMVAR_ANT_BG:
+ siba->siba_sprom.ant_bg = value;
+ break;
+ case SIBA_SPROMVAR_PA0B0:
+ siba->siba_sprom.pa0b0 = value;
+ break;
+ case SIBA_SPROMVAR_PA0B1:
+ siba->siba_sprom.pa0b1 = value;
+ break;
+ case SIBA_SPROMVAR_PA0B2:
+ siba->siba_sprom.pa0b2 = value;
+ break;
+ case SIBA_SPROMVAR_PA1B0:
+ siba->siba_sprom.pa1b0 = value;
+ break;
+ case SIBA_SPROMVAR_PA1B1:
+ siba->siba_sprom.pa1b1 = value;
+ break;
+ case SIBA_SPROMVAR_PA1B2:
+ siba->siba_sprom.pa1b2 = value;
+ break;
+ case SIBA_SPROMVAR_PA1LOB0:
+ siba->siba_sprom.pa1lob0 = value;
+ break;
+ case SIBA_SPROMVAR_PA1LOB1:
+ siba->siba_sprom.pa1lob1 = value;
+ break;
+ case SIBA_SPROMVAR_PA1LOB2:
+ siba->siba_sprom.pa1lob2 = value;
+ break;
+ case SIBA_SPROMVAR_PA1HIB0:
+ siba->siba_sprom.pa1hib0 = value;
+ break;
+ case SIBA_SPROMVAR_PA1HIB1:
+ siba->siba_sprom.pa1hib1 = value;
+ break;
+ case SIBA_SPROMVAR_PA1HIB2:
+ siba->siba_sprom.pa1hib2 = value;
+ break;
+ case SIBA_SPROMVAR_GPIO0:
+ siba->siba_sprom.gpio0 = value;
+ break;
+ case SIBA_SPROMVAR_GPIO1:
+ siba->siba_sprom.gpio1 = value;
+ break;
+ case SIBA_SPROMVAR_GPIO2:
+ siba->siba_sprom.gpio2 = value;
+ break;
+ case SIBA_SPROMVAR_GPIO3:
+ siba->siba_sprom.gpio3 = value;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_AL:
+ siba->siba_sprom.maxpwr_al = value;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_A:
+ siba->siba_sprom.maxpwr_a = value;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_AH:
+ siba->siba_sprom.maxpwr_ah = value;
+ break;
+ case SIBA_SPROMVAR_MAXPWR_BG:
+ siba->siba_sprom.maxpwr_bg = value;
+ break;
+ case SIBA_SPROMVAR_RXPO2G:
+ siba->siba_sprom.rxpo2g = value;
+ break;
+ case SIBA_SPROMVAR_RXPO5G:
+ siba->siba_sprom.rxpo5g = value;
+ break;
+ case SIBA_SPROMVAR_TSSI_A:
+ siba->siba_sprom.tssi_a = value;
+ break;
+ case SIBA_SPROMVAR_TSSI_BG:
+ siba->siba_sprom.tssi_bg = value;
+ break;
+ case SIBA_SPROMVAR_TRI2G:
+ siba->siba_sprom.tri2g = value;
+ break;
+ case SIBA_SPROMVAR_TRI5GL:
+ siba->siba_sprom.tri5gl = value;
+ break;
+ case SIBA_SPROMVAR_TRI5G:
+ siba->siba_sprom.tri5g = value;
+ break;
+ case SIBA_SPROMVAR_TRI5GH:
+ siba->siba_sprom.tri5gh = value;
+ break;
+ case SIBA_SPROMVAR_RSSISAV2G:
+ siba->siba_sprom.rssisav2g = value;
+ break;
+ case SIBA_SPROMVAR_RSSISMC2G:
+ siba->siba_sprom.rssismc2g = value;
+ break;
+ case SIBA_SPROMVAR_RSSISMF2G:
+ siba->siba_sprom.rssismf2g = value;
+ break;
+ case SIBA_SPROMVAR_BXA2G:
+ siba->siba_sprom.bxa2g = value;
+ break;
+ case SIBA_SPROMVAR_RSSISAV5G:
+ siba->siba_sprom.rssisav5g = value;
+ break;
+ case SIBA_SPROMVAR_RSSISMC5G:
+ siba->siba_sprom.rssismc5g = value;
+ break;
+ case SIBA_SPROMVAR_RSSISMF5G:
+ siba->siba_sprom.rssismf5g = value;
+ break;
+ case SIBA_SPROMVAR_BXA5G:
+ siba->siba_sprom.bxa5g = value;
+ break;
+ case SIBA_SPROMVAR_CCK2GPO:
+ siba->siba_sprom.cck2gpo = value;
+ break;
+ case SIBA_SPROMVAR_OFDM2GPO:
+ siba->siba_sprom.ofdm2gpo = value;
+ break;
+ case SIBA_SPROMVAR_OFDM5GLPO:
+ siba->siba_sprom.ofdm5glpo = value;
+ break;
+ case SIBA_SPROMVAR_OFDM5GPO:
+ siba->siba_sprom.ofdm5gpo = value;
+ break;
+ case SIBA_SPROMVAR_OFDM5GHPO:
+ siba->siba_sprom.ofdm5ghpo = value;
+ break;
+ case SIBA_SPROMVAR_BF_LO:
+ siba->siba_sprom.bf_lo = value;
+ break;
+ case SIBA_SPROMVAR_BF_HI:
+ siba->siba_sprom.bf_hi = value;
+ break;
+ case SIBA_SPROMVAR_BF2_LO:
+ siba->siba_sprom.bf2_lo = value;
+ break;
+ case SIBA_SPROMVAR_BF2_HI:
+ siba->siba_sprom.bf2_hi = value;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+#define SIBA_GPIOCTL 0x06c
+
+uint32_t
+siba_gpio_get(device_t dev)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+ struct siba_dev_softc *gpiodev, *pcidev = NULL;
+
+ pcidev = siba->siba_pci.spc_dev;
+ gpiodev = siba->siba_cc.scc_dev ? siba->siba_cc.scc_dev : pcidev;
+ if (!gpiodev)
+ return (-1);
+ return (siba_read_4_sub(gpiodev, SIBA_GPIOCTL));
+}
+
+void
+siba_gpio_set(device_t dev, uint32_t value)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+ struct siba_dev_softc *gpiodev, *pcidev = NULL;
+
+ pcidev = siba->siba_pci.spc_dev;
+ gpiodev = siba->siba_cc.scc_dev ? siba->siba_cc.scc_dev : pcidev;
+ if (!gpiodev)
+ return;
+ siba_write_4_sub(gpiodev, SIBA_GPIOCTL, value);
+}
+
+void
+siba_fix_imcfglobug(device_t dev)
+{
+ struct siba_dev_softc *sd = device_get_ivars(dev);
+ struct siba_softc *siba = sd->sd_bus;
+ uint32_t tmp;
+
+ if (siba->siba_pci.spc_dev == NULL)
+ return;
+ if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI ||
+ siba->siba_pci.spc_dev->sd_id.sd_rev > 5)
+ return;
+
+ tmp = siba_read_4_sub(sd, SIBA_IMCFGLO) &
+ ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO);
+ switch (siba->siba_type) {
+ case SIBA_TYPE_PCI:
+ case SIBA_TYPE_PCMCIA:
+ tmp |= 0x32;
+ break;
+ case SIBA_TYPE_SSB:
+ tmp |= 0x53;
+ break;
+ }
+ siba_write_4_sub(sd, SIBA_IMCFGLO, tmp);
+}
diff --git a/sys/dev/siba/siba_pcib.c b/sys/dev/siba/siba_pcib.c
index 5175aa7..d6ddeb6 100644
--- a/sys/dev/siba/siba_pcib.c
+++ b/sys/dev/siba/siba_pcib.c
@@ -419,7 +419,7 @@ static device_method_t siba_pcib_methods[] = {
DEVMETHOD(pcib_write_config, siba_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, siba_pcib_route_interrupt),
- {0, 0},
+ KOBJMETHOD_END
};
static driver_t siba_pcib_driver = {
diff --git a/sys/dev/siba/sibavar.h b/sys/dev/siba/sibavar.h
index 307903b..9b82310 100644
--- a/sys/dev/siba/sibavar.h
+++ b/sys/dev/siba/sibavar.h
@@ -34,11 +34,30 @@
struct siba_softc;
struct siba_dev_softc;
+enum siba_type {
+ SIBA_TYPE_SSB,
+ SIBA_TYPE_PCI,
+ SIBA_TYPE_PCMCIA,
+};
+
enum siba_device_ivars {
SIBA_IVAR_VENDOR,
SIBA_IVAR_DEVICE,
SIBA_IVAR_REVID,
- SIBA_IVAR_CORE_INDEX
+ SIBA_IVAR_CORE_INDEX,
+ SIBA_IVAR_PCI_VENDOR,
+ SIBA_IVAR_PCI_DEVICE,
+ SIBA_IVAR_PCI_SUBVENDOR,
+ SIBA_IVAR_PCI_SUBDEVICE,
+ SIBA_IVAR_PCI_REVID,
+ SIBA_IVAR_CHIPID,
+ SIBA_IVAR_CHIPREV,
+ SIBA_IVAR_CHIPPKG,
+ SIBA_IVAR_TYPE,
+ SIBA_IVAR_CC_PMUFREQ,
+ SIBA_IVAR_CC_CAPS,
+ SIBA_IVAR_CC_POWERDELAY,
+ SIBA_IVAR_PCICORE_REVID
};
#define SIBA_ACCESSOR(var, ivar, type) \
@@ -48,6 +67,19 @@ SIBA_ACCESSOR(vendor, VENDOR, uint16_t)
SIBA_ACCESSOR(device, DEVICE, uint16_t)
SIBA_ACCESSOR(revid, REVID, uint8_t)
SIBA_ACCESSOR(core_index, CORE_INDEX, uint8_t)
+SIBA_ACCESSOR(pci_vendor, PCI_VENDOR, uint16_t)
+SIBA_ACCESSOR(pci_device, PCI_DEVICE, uint16_t)
+SIBA_ACCESSOR(pci_subvendor, PCI_SUBVENDOR, uint16_t)
+SIBA_ACCESSOR(pci_subdevice, PCI_SUBDEVICE, uint16_t)
+SIBA_ACCESSOR(pci_revid, PCI_REVID, uint8_t)
+SIBA_ACCESSOR(chipid, CHIPID, uint16_t)
+SIBA_ACCESSOR(chiprev, CHIPREV, uint16_t)
+SIBA_ACCESSOR(chippkg, CHIPPKG, uint8_t)
+SIBA_ACCESSOR(type, TYPE, enum siba_type)
+SIBA_ACCESSOR(cc_pmufreq, CC_PMUFREQ, uint32_t)
+SIBA_ACCESSOR(cc_caps, CC_CAPS, uint32_t)
+SIBA_ACCESSOR(cc_powerdelay, CC_POWERDELAY, uint16_t)
+SIBA_ACCESSOR(pcicore_revid, PCICORE_REVID, uint8_t)
#undef SIBA_ACCESSOR
@@ -135,9 +167,9 @@ enum {
SIBA_WRITE_2((siba), (reg), SIBA_READ_2((siba), (reg)) & ~(bits))
#define SIBA_CC_READ32(scc, offset) \
- siba_read_4((scc)->scc_dev, offset)
+ siba_read_4_sub((scc)->scc_dev, offset)
#define SIBA_CC_WRITE32(scc, offset, val) \
- siba_write_4((scc)->scc_dev, offset, val)
+ siba_write_4_sub((scc)->scc_dev, offset, val)
#define SIBA_CC_MASK32(scc, offset, mask) \
SIBA_CC_WRITE32(scc, offset, SIBA_CC_READ32(scc, offset) & (mask))
#define SIBA_CC_SET32(scc, offset, set) \
@@ -146,12 +178,6 @@ enum {
SIBA_CC_WRITE32(scc, offset, \
(SIBA_CC_READ32(scc, offset) & (mask)) | (set))
-enum siba_type {
- SIBA_TYPE_SSB,
- SIBA_TYPE_PCI,
- SIBA_TYPE_PCMCIA,
-};
-
enum siba_clock {
SIBA_CLOCK_DYNAMIC,
SIBA_CLOCK_SLOW,
@@ -195,6 +221,152 @@ struct siba_cc_pmu_res_depend {
uint32_t depend;
};
+enum siba_sprom_vars {
+ SIBA_SPROMVAR_REV,
+ SIBA_SPROMVAR_MAC_80211BG,
+ SIBA_SPROMVAR_MAC_ETH,
+ SIBA_SPROMVAR_MAC_80211A,
+ SIBA_SPROMVAR_MII_ETH0,
+ SIBA_SPROMVAR_MII_ETH1,
+ SIBA_SPROMVAR_MDIO_ETH0,
+ SIBA_SPROMVAR_MDIO_ETH1,
+ SIBA_SPROMVAR_BREV,
+ SIBA_SPROMVAR_CCODE,
+ SIBA_SPROMVAR_ANT_A,
+ SIBA_SPROMVAR_ANT_BG,
+ SIBA_SPROMVAR_PA0B0,
+ SIBA_SPROMVAR_PA0B1,
+ SIBA_SPROMVAR_PA0B2,
+ SIBA_SPROMVAR_PA1B0,
+ SIBA_SPROMVAR_PA1B1,
+ SIBA_SPROMVAR_PA1B2,
+ SIBA_SPROMVAR_PA1LOB0,
+ SIBA_SPROMVAR_PA1LOB1,
+ SIBA_SPROMVAR_PA1LOB2,
+ SIBA_SPROMVAR_PA1HIB0,
+ SIBA_SPROMVAR_PA1HIB1,
+ SIBA_SPROMVAR_PA1HIB2,
+ SIBA_SPROMVAR_GPIO0,
+ SIBA_SPROMVAR_GPIO1,
+ SIBA_SPROMVAR_GPIO2,
+ SIBA_SPROMVAR_GPIO3,
+ SIBA_SPROMVAR_MAXPWR_AL,
+ SIBA_SPROMVAR_MAXPWR_A,
+ SIBA_SPROMVAR_MAXPWR_AH,
+ SIBA_SPROMVAR_MAXPWR_BG,
+ SIBA_SPROMVAR_RXPO2G,
+ SIBA_SPROMVAR_RXPO5G,
+ SIBA_SPROMVAR_TSSI_A,
+ SIBA_SPROMVAR_TSSI_BG,
+ SIBA_SPROMVAR_TRI2G,
+ SIBA_SPROMVAR_TRI5GL,
+ SIBA_SPROMVAR_TRI5G,
+ SIBA_SPROMVAR_TRI5GH,
+ SIBA_SPROMVAR_RSSISAV2G,
+ SIBA_SPROMVAR_RSSISMC2G,
+ SIBA_SPROMVAR_RSSISMF2G,
+ SIBA_SPROMVAR_BXA2G,
+ SIBA_SPROMVAR_RSSISAV5G,
+ SIBA_SPROMVAR_RSSISMC5G,
+ SIBA_SPROMVAR_RSSISMF5G,
+ SIBA_SPROMVAR_BXA5G,
+ SIBA_SPROMVAR_CCK2GPO,
+ SIBA_SPROMVAR_OFDM2GPO,
+ SIBA_SPROMVAR_OFDM5GLPO,
+ SIBA_SPROMVAR_OFDM5GPO,
+ SIBA_SPROMVAR_OFDM5GHPO,
+ SIBA_SPROMVAR_BF_LO,
+ SIBA_SPROMVAR_BF_HI,
+ SIBA_SPROMVAR_BF2_LO,
+ SIBA_SPROMVAR_BF2_HI
+};
+
+int siba_read_sprom(device_t, device_t, int, uintptr_t *);
+int siba_write_sprom(device_t, device_t, int, uintptr_t);
+
+/**
+ * Generic sprom accessor generation macros for siba(4) drivers
+ */
+#define __SPROM_ACCESSOR(varp, var, ivarp, ivar, type) \
+ \
+static __inline type varp ## _get_ ## var(device_t dev) \
+{ \
+ uintptr_t v; \
+ siba_read_sprom(device_get_parent(dev), dev, \
+ ivarp ## _SPROMVAR_ ## ivar, &v); \
+ return ((type) v); \
+} \
+ \
+static __inline void varp ## _set_ ## var(device_t dev, type t) \
+{ \
+ uintptr_t v = (uintptr_t) t; \
+ siba_write_sprom(device_get_parent(dev), dev, \
+ ivarp ## _SPROMVAR_ ## ivar, v); \
+}
+
+#define SIBA_SPROM_ACCESSOR(var, ivar, type) \
+ __SPROM_ACCESSOR(siba_sprom, var, SIBA, ivar, type)
+
+SIBA_SPROM_ACCESSOR(rev, REV, uint8_t);
+SIBA_SPROM_ACCESSOR(mac_80211bg, MAC_80211BG, uint8_t *);
+SIBA_SPROM_ACCESSOR(mac_eth, MAC_ETH, uint8_t *);
+SIBA_SPROM_ACCESSOR(mac_80211a, MAC_80211A, uint8_t *);
+SIBA_SPROM_ACCESSOR(mii_eth0, MII_ETH0, uint8_t);
+SIBA_SPROM_ACCESSOR(mii_eth1, MII_ETH1, uint8_t);
+SIBA_SPROM_ACCESSOR(mdio_eth0, MDIO_ETH0, uint8_t);
+SIBA_SPROM_ACCESSOR(mdio_eth1, MDIO_ETH1, uint8_t);
+SIBA_SPROM_ACCESSOR(brev, BREV, uint8_t);
+SIBA_SPROM_ACCESSOR(ccode, CCODE, uint8_t);
+SIBA_SPROM_ACCESSOR(ant_a, ANT_A, uint8_t);
+SIBA_SPROM_ACCESSOR(ant_bg, ANT_BG, uint8_t);
+SIBA_SPROM_ACCESSOR(pa0b0, PA0B0, uint16_t);
+SIBA_SPROM_ACCESSOR(pa0b1, PA0B1, uint16_t);
+SIBA_SPROM_ACCESSOR(pa0b2, PA0B2, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1b0, PA1B0, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1b1, PA1B1, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1b2, PA1B2, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1lob0, PA1LOB0, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1lob1, PA1LOB1, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1lob2, PA1LOB2, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1hib0, PA1HIB0, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1hib1, PA1HIB1, uint16_t);
+SIBA_SPROM_ACCESSOR(pa1hib2, PA1HIB2, uint16_t);
+SIBA_SPROM_ACCESSOR(gpio0, GPIO0, uint8_t);
+SIBA_SPROM_ACCESSOR(gpio1, GPIO1, uint8_t);
+SIBA_SPROM_ACCESSOR(gpio2, GPIO2, uint8_t);
+SIBA_SPROM_ACCESSOR(gpio3, GPIO3, uint8_t);
+SIBA_SPROM_ACCESSOR(maxpwr_al, MAXPWR_AL, uint16_t);
+SIBA_SPROM_ACCESSOR(maxpwr_a, MAXPWR_A, uint16_t);
+SIBA_SPROM_ACCESSOR(maxpwr_ah, MAXPWR_AH, uint16_t);
+SIBA_SPROM_ACCESSOR(maxpwr_bg, MAXPWR_BG, uint16_t);
+SIBA_SPROM_ACCESSOR(rxpo2g, RXPO2G, uint8_t);
+SIBA_SPROM_ACCESSOR(rxpo5g, RXPO5G, uint8_t);
+SIBA_SPROM_ACCESSOR(tssi_a, TSSI_A, uint8_t);
+SIBA_SPROM_ACCESSOR(tssi_bg, TSSI_BG, uint8_t);
+SIBA_SPROM_ACCESSOR(tri2g, TRI2G, uint8_t);
+SIBA_SPROM_ACCESSOR(tri5gl, TRI5GL, uint8_t);
+SIBA_SPROM_ACCESSOR(tri5g, TRI5G, uint8_t);
+SIBA_SPROM_ACCESSOR(tri5gh, TRI5GH, uint8_t);
+SIBA_SPROM_ACCESSOR(rssisav2g, RSSISAV2G, uint8_t);
+SIBA_SPROM_ACCESSOR(rssismc2g, RSSISMC2G, uint8_t);
+SIBA_SPROM_ACCESSOR(rssismf2g, RSSISMF2G, uint8_t);
+SIBA_SPROM_ACCESSOR(bxa2g, BXA2G, uint8_t);
+SIBA_SPROM_ACCESSOR(rssisav5g, RSSISAV5G, uint8_t);
+SIBA_SPROM_ACCESSOR(rssismc5g, RSSISMC5G, uint8_t);
+SIBA_SPROM_ACCESSOR(rssismf5g, RSSISMF5G, uint8_t);
+SIBA_SPROM_ACCESSOR(bxa5g, BXA5G, uint8_t);
+SIBA_SPROM_ACCESSOR(cck2gpo, CCK2GPO, uint16_t);
+SIBA_SPROM_ACCESSOR(ofdm2gpo, OFDM2GPO, uint32_t);
+SIBA_SPROM_ACCESSOR(ofdm5glpo, OFDM5GLPO, uint32_t);
+SIBA_SPROM_ACCESSOR(ofdm5gpo, OFDM5GPO, uint32_t);
+SIBA_SPROM_ACCESSOR(ofdm5ghpo, OFDM5GHPO, uint32_t);
+SIBA_SPROM_ACCESSOR(bf_lo, BF_LO, uint16_t);
+SIBA_SPROM_ACCESSOR(bf_hi, BF_HI, uint16_t);
+SIBA_SPROM_ACCESSOR(bf2_lo, BF2_LO, uint16_t);
+SIBA_SPROM_ACCESSOR(bf2_hi, BF2_HI, uint16_t);
+
+#undef SIBA_SPROM_ACCESSOR
+
struct siba_sprom {
uint8_t rev; /* revision */
uint8_t mac_80211bg[6]; /* address for 802.11b/g */
@@ -358,6 +530,7 @@ struct siba_softc {
uint16_t siba_pci_did;
uint16_t siba_pci_subvid;
uint16_t siba_pci_subdid;
+ uint8_t siba_pci_revid;
int siba_mem_rid;
uint16_t siba_chipid; /* for CORE 0 */
@@ -368,41 +541,32 @@ struct siba_softc {
struct siba_pci siba_pci; /* PCI-core */
const struct siba_bus_ops *siba_ops;
- /* board informations */
- uint16_t siba_board_vendor;
- uint16_t siba_board_type;
- uint16_t siba_board_rev;
struct siba_sprom siba_sprom; /* SPROM */
uint16_t siba_spromsize; /* in word size */
};
-void siba_powerup(struct siba_softc *, int);
-uint16_t siba_read_2(struct siba_dev_softc *, uint16_t);
-void siba_write_2(struct siba_dev_softc *, uint16_t, uint16_t);
-uint32_t siba_read_4(struct siba_dev_softc *, uint16_t);
-void siba_write_4(struct siba_dev_softc *, uint16_t, uint32_t);
-void siba_dev_up(struct siba_dev_softc *, uint32_t);
-void siba_dev_down(struct siba_dev_softc *, uint32_t);
-int siba_powerdown(struct siba_softc *);
-int siba_dev_isup(struct siba_dev_softc *);
-void siba_pcicore_intr(struct siba_pci *, struct siba_dev_softc *);
-uint32_t siba_dma_translation(struct siba_dev_softc *);
-void *siba_dma_alloc_consistent(struct siba_dev_softc *, size_t,
- bus_addr_t *);
-void siba_read_multi_1(struct siba_dev_softc *, void *, size_t,
- uint16_t);
-void siba_read_multi_2(struct siba_dev_softc *, void *, size_t,
- uint16_t);
-void siba_read_multi_4(struct siba_dev_softc *, void *, size_t,
- uint16_t);
-void siba_write_multi_1(struct siba_dev_softc *, const void *,
- size_t, uint16_t);
-void siba_write_multi_2(struct siba_dev_softc *, const void *,
- size_t, uint16_t);
-void siba_write_multi_4(struct siba_dev_softc *, const void *,
- size_t, uint16_t);
-void siba_barrier(struct siba_dev_softc *, int);
-void siba_cc_pmu_set_ldovolt(struct siba_cc *, int, uint32_t);
-void siba_cc_pmu_set_ldoparef(struct siba_cc *, uint8_t);
+void siba_powerup(device_t, int);
+int siba_powerdown(device_t);
+uint16_t siba_read_2(device_t, uint16_t);
+void siba_write_2(device_t, uint16_t, uint16_t);
+uint32_t siba_read_4(device_t, uint16_t);
+void siba_write_4(device_t, uint16_t, uint32_t);
+void siba_dev_up(device_t, uint32_t);
+void siba_dev_down(device_t, uint32_t);
+int siba_dev_isup(device_t);
+void siba_pcicore_intr(device_t);
+uint32_t siba_dma_translation(device_t);
+void siba_read_multi_1(device_t, void *, size_t, uint16_t);
+void siba_read_multi_2(device_t, void *, size_t, uint16_t);
+void siba_read_multi_4(device_t, void *, size_t, uint16_t);
+void siba_write_multi_1(device_t, const void *, size_t, uint16_t);
+void siba_write_multi_2(device_t, const void *, size_t, uint16_t);
+void siba_write_multi_4(device_t, const void *, size_t, uint16_t);
+void siba_barrier(device_t, int);
+void siba_cc_pmu_set_ldovolt(device_t, int, uint32_t);
+void siba_cc_pmu_set_ldoparef(device_t, uint8_t);
+void siba_gpio_set(device_t, uint32_t);
+uint32_t siba_gpio_get(device_t);
+void siba_fix_imcfglobug(device_t);
#endif /* _SIBA_SIBAVAR_H_ */
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 29afa2a..c9c1572 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -94,14 +94,15 @@ static struct {
int ports;
int quirks;
#define SIIS_Q_SNTF 1
+#define SIIS_Q_NOMSI 2
} siis_ids[] = {
{0x31241095, "SiI3124", 4, 0},
{0x31248086, "SiI3124", 4, 0},
- {0x31321095, "SiI3132", 2, SIIS_Q_SNTF},
- {0x02421095, "SiI3132", 2, SIIS_Q_SNTF},
- {0x02441095, "SiI3132", 2, SIIS_Q_SNTF},
- {0x31311095, "SiI3131", 1, SIIS_Q_SNTF},
- {0x35311095, "SiI3531", 1, SIIS_Q_SNTF},
+ {0x31321095, "SiI3132", 2, SIIS_Q_SNTF|SIIS_Q_NOMSI},
+ {0x02421095, "SiI3132", 2, SIIS_Q_SNTF|SIIS_Q_NOMSI},
+ {0x02441095, "SiI3132", 2, SIIS_Q_SNTF|SIIS_Q_NOMSI},
+ {0x31311095, "SiI3131", 1, SIIS_Q_SNTF|SIIS_Q_NOMSI},
+ {0x35311095, "SiI3531", 1, SIIS_Q_SNTF|SIIS_Q_NOMSI},
{0, NULL, 0, 0}
};
@@ -163,6 +164,7 @@ siis_attach(device_t dev)
rman_fini(&ctlr->sc_iomem);
return (error);
}
+ pci_enable_busmaster(dev);
/* Reset controller */
siis_resume(dev);
/* Number of HW channels */
@@ -249,7 +251,7 @@ static int
siis_setup_interrupt(device_t dev)
{
struct siis_controller *ctlr = device_get_softc(dev);
- int msi = 0;
+ int msi = ctlr->quirks & SIIS_Q_NOMSI ? 0 : 1;
/* Process hints. */
resource_int_value(device_get_name(dev),
diff --git a/sys/dev/sis/if_sis.c b/sys/dev/sis/if_sis.c
index aac46f7..1983342 100644
--- a/sys/dev/sis/if_sis.c
+++ b/sys/dev/sis/if_sis.c
@@ -1483,15 +1483,6 @@ sis_rxeof(struct sis_softc *sc)
return (rx_npkts);
}
-static void
-sis_rxeoc(struct sis_softc *sc)
-{
-
- SIS_LOCK_ASSERT(sc);
- sis_rxeof(sc);
- sis_initl(sc);
-}
-
/*
* A frame was downloaded to the chip. It's safe for us to clean up
* the list buffers.
@@ -1614,7 +1605,7 @@ sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
status = CSR_READ_4(sc, SIS_ISR);
if (status & (SIS_ISR_RX_ERR|SIS_ISR_RX_OFLOW))
- sis_rxeoc(sc);
+ ifp->if_ierrors++;
if (status & (SIS_ISR_RX_IDLE))
SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
@@ -1672,7 +1663,7 @@ sis_intr(void *arg)
sis_rxeof(sc);
if (status & SIS_ISR_RX_OFLOW)
- sis_rxeoc(sc);
+ ifp->if_ierrors++;
if (status & (SIS_ISR_RX_IDLE))
SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
@@ -2017,7 +2008,7 @@ sis_initl(struct sis_softc *sc)
CSR_WRITE_4(sc, NS_PHY_PAGE, 0x0001);
reg = CSR_READ_4(sc, NS_PHY_DSPCFG) & 0xfff;
CSR_WRITE_4(sc, NS_PHY_DSPCFG, reg | 0x1000);
- DELAY(100000);
+ DELAY(100);
reg = CSR_READ_4(sc, NS_PHY_TDATA) & 0xff;
if ((reg & 0x0080) == 0 || (reg > 0xd8 && reg <= 0xff)) {
device_printf(sc->sis_dev,
diff --git a/sys/dev/sound/pci/envy24.c b/sys/dev/sound/pci/envy24.c
index 09c616c..57a8ed6 100644
--- a/sys/dev/sound/pci/envy24.c
+++ b/sys/dev/sound/pci/envy24.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
* All rights reserved.
*
diff --git a/sys/dev/sound/pci/envy24.h b/sys/dev/sound/pci/envy24.h
index b6dad28..5a3a373 100644
--- a/sys/dev/sound/pci/envy24.h
+++ b/sys/dev/sound/pci/envy24.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
* All rights reserved.
*
diff --git a/sys/dev/sound/pci/envy24ht.c b/sys/dev/sound/pci/envy24ht.c
index b049562..7c1874b 100644
--- a/sys/dev/sound/pci/envy24ht.c
+++ b/sys/dev/sound/pci/envy24ht.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2006 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
* All rights reserved.
diff --git a/sys/dev/sound/pci/envy24ht.h b/sys/dev/sound/pci/envy24ht.h
index 7eb0a65..8901dc3 100644
--- a/sys/dev/sound/pci/envy24ht.h
+++ b/sys/dev/sound/pci/envy24ht.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2006 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
* All rights reserved.
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index 8d04f70..5b9591a 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -355,7 +355,7 @@ es1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
if (mixtable[dev].left == 0xf)
rl = (l < 2) ? 0x80 : 7 - (l - 2) / 14;
else
- rl = (l < 10) ? 0x80 : 15 - (l - 10) / 6;
+ rl = (l < 7) ? 0x80 : 31 - (l - 7) / 3;
es = mix_getdevinfo(m);
ES_LOCK(es);
if (dev == SOUND_MIXER_PCM && (ES_SINGLE_PCM_MIX(es->escfg)) &&
@@ -364,7 +364,7 @@ es1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
else
set_dac1 = 0;
if (mixtable[dev].stereo) {
- rr = (r < 10) ? 0x80 : 15 - (r - 10) / 6;
+ rr = (r < 7) ? 0x80 : 31 - (r - 7) / 3;
es1370_wrcodec(es, mixtable[dev].right, rr);
if (set_dac1 && mixtable[SOUND_MIXER_SYNTH].stereo)
es1370_wrcodec(es,
diff --git a/sys/dev/sound/pci/es137x.h b/sys/dev/sound/pci/es137x.h
index fb86a94..01cb53d 100644
--- a/sys/dev/sound/pci/es137x.h
+++ b/sys/dev/sound/pci/es137x.h
@@ -11,6 +11,18 @@
* 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$
*/
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 0681568..7717ff4 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -619,10 +619,14 @@ static const struct {
#define HDA_CODEC_ALC267 HDA_CODEC_CONSTRUCT(REALTEK, 0x0267)
#define HDA_CODEC_ALC268 HDA_CODEC_CONSTRUCT(REALTEK, 0x0268)
#define HDA_CODEC_ALC269 HDA_CODEC_CONSTRUCT(REALTEK, 0x0269)
+#define HDA_CODEC_ALC270 HDA_CODEC_CONSTRUCT(REALTEK, 0x0270)
#define HDA_CODEC_ALC272 HDA_CODEC_CONSTRUCT(REALTEK, 0x0272)
+#define HDA_CODEC_ALC273 HDA_CODEC_CONSTRUCT(REALTEK, 0x0273)
+#define HDA_CODEC_ALC275 HDA_CODEC_CONSTRUCT(REALTEK, 0x0275)
#define HDA_CODEC_ALC660 HDA_CODEC_CONSTRUCT(REALTEK, 0x0660)
#define HDA_CODEC_ALC662 HDA_CODEC_CONSTRUCT(REALTEK, 0x0662)
#define HDA_CODEC_ALC663 HDA_CODEC_CONSTRUCT(REALTEK, 0x0663)
+#define HDA_CODEC_ALC665 HDA_CODEC_CONSTRUCT(REALTEK, 0x0665)
#define HDA_CODEC_ALC861 HDA_CODEC_CONSTRUCT(REALTEK, 0x0861)
#define HDA_CODEC_ALC861VD HDA_CODEC_CONSTRUCT(REALTEK, 0x0862)
#define HDA_CODEC_ALC880 HDA_CODEC_CONSTRUCT(REALTEK, 0x0880)
@@ -632,6 +636,7 @@ static const struct {
#define HDA_CODEC_ALC887 HDA_CODEC_CONSTRUCT(REALTEK, 0x0887)
#define HDA_CODEC_ALC888 HDA_CODEC_CONSTRUCT(REALTEK, 0x0888)
#define HDA_CODEC_ALC889 HDA_CODEC_CONSTRUCT(REALTEK, 0x0889)
+#define HDA_CODEC_ALC892 HDA_CODEC_CONSTRUCT(REALTEK, 0x0892)
#define HDA_CODEC_ALCXXXX HDA_CODEC_CONSTRUCT(REALTEK, 0xffff)
/* Analog Devices */
@@ -735,6 +740,7 @@ static const struct {
#define HDA_CODEC_CX20551 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047)
#define HDA_CODEC_CX20561 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5051)
#define HDA_CODEC_CX20582 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5066)
+#define HDA_CODEC_CX20583 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5067)
#define HDA_CODEC_CXXXXX HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff)
/* VIA */
@@ -805,7 +811,8 @@ static const struct {
#define HDA_CODEC_INTELG45_1 HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
#define HDA_CODEC_INTELG45_2 HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
#define HDA_CODEC_INTELG45_3 HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
-#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
+#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
+#define HDA_CODEC_INTELG45_5 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
#define HDA_CODEC_INTELQ57 HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
#define HDA_CODEC_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
@@ -821,10 +828,14 @@ static const struct {
{ HDA_CODEC_ALC267, "Realtek ALC267" },
{ HDA_CODEC_ALC268, "Realtek ALC268" },
{ HDA_CODEC_ALC269, "Realtek ALC269" },
+ { HDA_CODEC_ALC270, "Realtek ALC270" },
{ HDA_CODEC_ALC272, "Realtek ALC272" },
+ { HDA_CODEC_ALC273, "Realtek ALC273" },
+ { HDA_CODEC_ALC275, "Realtek ALC275" },
{ HDA_CODEC_ALC660, "Realtek ALC660" },
{ HDA_CODEC_ALC662, "Realtek ALC662" },
{ HDA_CODEC_ALC663, "Realtek ALC663" },
+ { HDA_CODEC_ALC665, "Realtek ALC665" },
{ HDA_CODEC_ALC861, "Realtek ALC861" },
{ HDA_CODEC_ALC861VD, "Realtek ALC861-VD" },
{ HDA_CODEC_ALC880, "Realtek ALC880" },
@@ -834,6 +845,7 @@ static const struct {
{ HDA_CODEC_ALC887, "Realtek ALC887" },
{ HDA_CODEC_ALC888, "Realtek ALC888" },
{ HDA_CODEC_ALC889, "Realtek ALC889" },
+ { HDA_CODEC_ALC892, "Realtek ALC892" },
{ HDA_CODEC_AD1882, "Analog Devices AD1882" },
{ HDA_CODEC_AD1882A, "Analog Devices AD1882A" },
{ HDA_CODEC_AD1883, "Analog Devices AD1883" },
@@ -907,6 +919,7 @@ static const struct {
{ HDA_CODEC_CX20551, "Conexant CX20551 (Waikiki)" },
{ HDA_CODEC_CX20561, "Conexant CX20561 (Hermosa)" },
{ HDA_CODEC_CX20582, "Conexant CX20582 (Pebble)" },
+ { HDA_CODEC_CX20583, "Conexant CX20583 (Pebble HSF)" },
{ HDA_CODEC_VT1708_8, "VIA VT1708_8" },
{ HDA_CODEC_VT1708_9, "VIA VT1708_9" },
{ HDA_CODEC_VT1708_A, "VIA VT1708_A" },
@@ -966,6 +979,7 @@ static const struct {
{ HDA_CODEC_INTELG45_2, "Intel G45 HDMI" },
{ HDA_CODEC_INTELG45_3, "Intel G45 HDMI" },
{ HDA_CODEC_INTELG45_4, "Intel G45 HDMI" },
+ { HDA_CODEC_INTELG45_5, "Intel G45 HDMI" },
{ HDA_CODEC_INTELQ57, "Intel Q57 HDMI" },
{ HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" },
{ HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" },
diff --git a/sys/dev/sound/pci/spicds.c b/sys/dev/sound/pci/spicds.c
index 09fdc11..78d9374 100644
--- a/sys/dev/sound/pci/spicds.c
+++ b/sys/dev/sound/pci/spicds.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2006 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
* All rights reserved.
diff --git a/sys/dev/sound/pci/spicds.h b/sys/dev/sound/pci/spicds.h
index c206be3..f98bf93 100644
--- a/sys/dev/sound/pci/spicds.h
+++ b/sys/dev/sound/pci/spicds.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2006 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
* Copyright (c) 2001 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
* All rights reserved.
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index d0ebfad..19801b2 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -1071,6 +1071,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
if (IOCGROUP(cmd) == 'M') {
if (cmd == OSS_GETVERSION) {
*arg_i = SOUND_VERSION;
+ PCM_GIANT_EXIT(d);
return (0);
}
ret = dsp_ioctl_channel(i_dev, PCM_VOLCH(i_dev), cmd, arg);
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 069a8c0..1613266 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -91,7 +91,7 @@ static int uaudio_default_rate = 0; /* use rate list */
static int uaudio_default_bits = 32;
static int uaudio_default_channels = 0; /* use default */
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uaudio_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
@@ -321,7 +321,7 @@ static const struct uaudio_format uaudio_formats[] = {
#define UAC_RECORD 3
#define UAC_NCLASSES 4
-#if USB_DEBUG
+#ifdef USB_DEBUG
static const char *uac_names[] = {
"outputs", "inputs", "equalization", "record"
};
@@ -406,7 +406,7 @@ static void umidi_init(device_t dev);
static int32_t umidi_probe(device_t dev);
static int32_t umidi_detach(device_t dev);
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void uaudio_chan_dump_ep_desc(
const usb_endpoint_descriptor_audio_t *);
static void uaudio_mixer_dump_cluster(uint8_t,
@@ -780,7 +780,7 @@ uaudio_detach(device_t dev)
* AS - Audio Stream - routines
*========================================================================*/
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void
uaudio_chan_dump_ep_desc(const usb_endpoint_descriptor_audio_t *ed)
{
@@ -1019,7 +1019,7 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
if ((chan->valid == 0) && usbd_get_iface(udev, curidx)) {
chan->valid = 1;
-#if USB_DEBUG
+#ifdef USB_DEBUG
uaudio_chan_dump_ep_desc(ed1);
uaudio_chan_dump_ep_desc(ed2);
@@ -1689,7 +1689,7 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc)
uaudio_mixer_add_ctl_sub(sc, mc);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uaudio_debug > 2) {
uint8_t i;
@@ -1708,7 +1708,7 @@ static void
uaudio_mixer_add_input(struct uaudio_softc *sc,
const struct uaudio_terminal_node *iot, int id)
{
-#if USB_DEBUG
+#ifdef USB_DEBUG
const struct usb_audio_input_terminal *d = iot[id].u.it;
DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x "
@@ -1724,7 +1724,7 @@ static void
uaudio_mixer_add_output(struct uaudio_softc *sc,
const struct uaudio_terminal_node *iot, int id)
{
-#if USB_DEBUG
+#ifdef USB_DEBUG
const struct usb_audio_output_terminal *d = iot[id].u.ot;
DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x "
@@ -2257,7 +2257,7 @@ error:
return (NULL);
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void
uaudio_mixer_dump_cluster(uint8_t id, const struct uaudio_terminal_node *iot)
{
@@ -2350,7 +2350,7 @@ done:
return (r);
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
struct uaudio_tt_to_string {
uint16_t terminal_type;
@@ -2856,7 +2856,7 @@ uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb_device *udev,
(iot + i)->root = iot;
} while (i--);
-#if USB_DEBUG
+#ifdef USB_DEBUG
i = ID_max;
do {
uint8_t j;
diff --git a/sys/dev/syscons/logo/beastie.c b/sys/dev/syscons/logo/beastie.c
new file mode 100644
index 0000000..ea3f46e
--- /dev/null
+++ b/sys/dev/syscons/logo/beastie.c
@@ -0,0 +1,358 @@
+/* $FreeBSD$ */
+
+#define logo_width 88
+#define logo_height 88
+
+unsigned int logo_w = logo_width;
+unsigned int logo_h = logo_height;
+
+unsigned char logo_pal[768] = {
+ 0x00, 0x00, 0x00,
+ 0x33, 0x33, 0x33,
+ 0x66, 0x66, 0x66,
+ 0x99, 0x99, 0x99,
+ 0xcc, 0xcc, 0xcc,
+ 0xff, 0xff, 0xff,
+ 0x90, 0x8f, 0x90,
+ 0x56, 0x4b, 0x55,
+ 0xa3, 0xa5, 0xab,
+ 0xfd, 0xfd, 0xfd,
+ 0x6d, 0x6e, 0x74,
+ 0x41, 0x2b, 0x39,
+ 0xcb, 0xc8, 0xcb,
+ 0xcf, 0xbb, 0xba,
+ 0x8e, 0x82, 0x87,
+ 0x5c, 0x5d, 0x60,
+ 0x52, 0x2a, 0x37,
+ 0x7f, 0x76, 0x7d,
+ 0x82, 0x82, 0x85,
+ 0x7a, 0x3e, 0x45,
+ 0x7f, 0x6e, 0x70,
+ 0xef, 0xef, 0xed,
+ 0x53, 0x41, 0x4b,
+ 0x67, 0x2b, 0x35,
+ 0x6a, 0x55, 0x62,
+ 0xe7, 0xe2, 0xe3,
+ 0x64, 0x35, 0x3f,
+ 0xf7, 0xe0, 0xe7,
+ 0xb1, 0xb2, 0xb2,
+ 0x31, 0x2b, 0x35,
+ 0x7a, 0x2d, 0x37,
+ 0x69, 0x4c, 0x56,
+ 0x95, 0x9d, 0xa4,
+ 0x85, 0x61, 0x69,
+ 0x40, 0x34, 0x41,
+ 0x8f, 0x2e, 0x39,
+ 0x7a, 0x50, 0x5a,
+ 0xde, 0xe1, 0xe0,
+ 0x32, 0x33, 0x3d,
+ 0xa0, 0x9b, 0x9c,
+ 0x68, 0x63, 0x67,
+ 0x76, 0x60, 0x67,
+ 0xba, 0xb6, 0xb8,
+ 0x29, 0x24, 0x41,
+ 0x38, 0x21, 0x29,
+ 0x42, 0x21, 0x27,
+ 0xa2, 0x2a, 0x32,
+ 0x56, 0x55, 0x58,
+ 0x55, 0x21, 0x2b,
+ 0x7a, 0x20, 0x2a,
+ 0x37, 0x16, 0x21,
+ 0x4d, 0x18, 0x37,
+ 0x8a, 0x3a, 0x3e,
+ 0xc0, 0xc2, 0xc4,
+ 0x64, 0x23, 0x2c,
+ 0x37, 0x1a, 0x24,
+ 0x42, 0x18, 0x20,
+ 0x4c, 0x21, 0x2b,
+ 0xa0, 0x23, 0x2e,
+ 0x95, 0x6c, 0x76,
+ 0x26, 0x16, 0x1c,
+ 0xa5, 0x18, 0x23,
+ 0x84, 0x20, 0x2b,
+ 0x6d, 0x3f, 0x49,
+ 0xae, 0xa7, 0xac,
+ 0x2a, 0x1f, 0x24,
+ 0x90, 0x21, 0x30,
+ 0xa0, 0x39, 0x3e,
+ 0x95, 0x0f, 0x1c,
+ 0x84, 0x13, 0x1e,
+ 0x4e, 0x17, 0x24,
+ 0x8c, 0x56, 0x5f,
+ 0xe0, 0xc4, 0xcb,
+ 0xa5, 0x7f, 0x8e,
+ 0xff, 0xff, 0xf1,
+ 0x3d, 0x3d, 0x5d,
+ 0x61, 0x19, 0x26,
+ 0xd5, 0xd5, 0xd5,
+ 0xff, 0xf1, 0xed,
+ 0xb6, 0x9c, 0xa5,
+ 0x87, 0x4c, 0x5a,
+ 0xa0, 0x76, 0x76,
+ 0xc8, 0xa0, 0xa0,
+ 0xa2, 0xc1, 0xc8,
+ 0x91, 0xae, 0xb6,
+ 0x52, 0x8b, 0xae,
+ 0xb3, 0xd2, 0xd4,
+ 0x95, 0xb7, 0xc1,
+ 0x54, 0x6e, 0x83,
+ 0x67, 0x90, 0xa6,
+ 0x44, 0x3e, 0x45,
+ 0x23, 0x40, 0x6a,
+ 0x41, 0x6e, 0x97,
+ 0x7e, 0x8e, 0x91,
+ 0x52, 0x33, 0x41,
+ 0x39, 0x49, 0x68,
+ 0x1d, 0x2a, 0x48,
+ 0x17, 0x21, 0x45,
+ 0x90, 0x17, 0x1f,
+ 0x38, 0x54, 0x71,
+ 0x1c, 0x33, 0x58,
+ 0x1c, 0x1e, 0x23,
+ 0x6c, 0x17, 0x21,
+ 0xb0, 0xc5, 0xc1,
+ 0x5d, 0x7f, 0x96,
+ 0xe9, 0xbf, 0xc1,
+ 0x96, 0x06, 0x0f,
+ 0x78, 0x16, 0x1e,
+ 0xab, 0x0e, 0x18,
+ 0xa6, 0x06, 0x0e,
+ 0x4c, 0x4c, 0x54,
+ 0x61, 0x42, 0x4c,
+ 0x48, 0x5f, 0x84,
+ 0xa0, 0xb8, 0xbe,
+ 0x5c, 0x66, 0x7f,
+ 0x7b, 0x9e, 0xa9,
+ 0x6f, 0x75, 0x7f,
+ 0x45, 0x54, 0x74,
+ 0x32, 0x3e, 0x63,
+ 0xb1, 0xb4, 0xb3,
+ 0x66, 0x9d, 0xb4,
+ 0x7a, 0x9f, 0xbb,
+ 0x82, 0xaa, 0xba,
+ 0x13, 0x15, 0x17,
+ 0x0b, 0x0b, 0x0a,
+ 0x37, 0x66, 0x92,
+ 0x4c, 0x7f, 0xa5,
+ 0x24, 0x4c, 0x7b,
+ 0x25, 0x5f, 0x91,
+ 0x40, 0x7d, 0xa5,
+ 0x1d, 0x56, 0x88,
+ 0x2d, 0x6f, 0xa0,
+ 0x70, 0x81, 0x8f,
+ 0x58, 0x97, 0xbd,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+};
+
+unsigned char logo_img[logo_width*logo_height] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x09, 0x0a, 0x0b, 0x07, 0x0c, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0d, 0x0e, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x09, 0x0f, 0x0b, 0x10, 0x11, 0x09, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x12, 0x13, 0x14, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x16, 0x0b, 0x17, 0x18, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x13, 0x1a, 0x1b, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1c, 0x1d, 0x10, 0x1e, 0x1f, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x20, 0x0b, 0x1e, 0x21, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x19, 0x22, 0x0b, 0x17, 0x23, 0x24, 0x15, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x25, 0x26, 0x10, 0x23, 0x27, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x05, 0x05, 0x05, 0x25, 0x27, 0x11, 0x28, 0x29, 0x11, 0x06, 0x0d, 0x09, 0x05, 0x2a, 0x2b, 0x2c, 0x2d, 0x1e, 0x2e, 0x21, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2f, 0x0b, 0x30, 0x31, 0x0c, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x06, 0x16, 0x22, 0x1d, 0x2c, 0x32, 0x33, 0x17, 0x17, 0x17, 0x22, 0x14, 0x16, 0x1d, 0x2c, 0x2d, 0x1e, 0x2e, 0x34, 0x0c, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x2b, 0x2c, 0x36, 0x36, 0x35, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x27, 0x0b, 0x2c, 0x2c, 0x37, 0x32, 0x38, 0x2c, 0x2d, 0x39, 0x36, 0x17, 0x30, 0x2c, 0x2c, 0x2d, 0x2c, 0x2c, 0x1a, 0x3a, 0x3a, 0x3b, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0a, 0x2d, 0x2b, 0x33, 0x31, 0x0e, 0x05, 0x05, 0x05, 0x05, 0x09, 0x28, 0x2c, 0x37, 0x3c, 0x32, 0x38, 0x38, 0x37, 0x2c, 0x30, 0x36, 0x36, 0x17, 0x31, 0x36, 0x23, 0x23, 0x17, 0x2c, 0x17, 0x3a, 0x3d, 0x13, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x22, 0x2c, 0x37, 0x33, 0x3e, 0x31, 0x3f, 0x40, 0x19, 0x05, 0x11, 0x2c, 0x2c, 0x32, 0x32, 0x32, 0x38, 0x37, 0x41, 0x30, 0x3a, 0x3a, 0x2e, 0x42, 0x43, 0x17, 0x1a, 0x13, 0x23, 0x31, 0x1a, 0x2e, 0x3d, 0x1a, 0x09, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0b, 0x37, 0x32, 0x37, 0x33, 0x44, 0x44, 0x45, 0x17, 0x1a, 0x10, 0x2d, 0x37, 0x38, 0x46, 0x33, 0x46, 0x32, 0x2c, 0x23, 0x23, 0x47, 0x21, 0x13, 0x43, 0x34, 0x48, 0x19, 0x49, 0x34, 0x17, 0x1e, 0x3a, 0x13, 0x4a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4b, 0x32, 0x32, 0x32, 0x32, 0x4c, 0x45, 0x44, 0x44, 0x42, 0x36, 0x30, 0x33, 0x46, 0x38, 0x33, 0x46, 0x38, 0x31, 0x23, 0x27, 0x09, 0x4a, 0x4d, 0x47, 0x43, 0x0d, 0x4e, 0x4a, 0x4f, 0x34, 0x1a, 0x2e, 0x29, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x33, 0x32, 0x32, 0x32, 0x33, 0x4c, 0x31, 0x45, 0x3e, 0x31, 0x36, 0x46, 0x46, 0x33, 0x33, 0x39, 0x30, 0x23, 0x50, 0x4a, 0x4a, 0x4a, 0x4a, 0x4d, 0x47, 0x51, 0x4e, 0x4a, 0x4a, 0x0e, 0x13, 0x1a, 0x27, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x2b, 0x32, 0x32, 0x2b, 0x32, 0x33, 0x4c, 0x33, 0x4c, 0x4c, 0x36, 0x30, 0x30, 0x30, 0x30, 0x31, 0x23, 0x3a, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4f, 0x50, 0x1b, 0x4e, 0x4a, 0x19, 0x50, 0x16, 0x0c, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x32, 0x32, 0x32, 0x32, 0x2b, 0x33, 0x33, 0x30, 0x2d, 0x39, 0x30, 0x30, 0x30, 0x4c, 0x36, 0x42, 0x3a, 0x52, 0x05, 0x4a, 0x4a, 0x4a, 0x4a, 0x09, 0x3b, 0x52, 0x4e, 0x4a, 0x4a, 0x4f, 0x1a, 0x2a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4d, 0x2b, 0x2b, 0x32, 0x32, 0x32, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x10, 0x30, 0x30, 0x3e, 0x23, 0x3a, 0x0d, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x40, 0x51, 0x4a, 0x4a, 0x25, 0x15, 0x1f, 0x27, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x40, 0x22, 0x2c, 0x32, 0x32, 0x32, 0x38, 0x2d, 0x2c, 0x41, 0x32, 0x39, 0x46, 0x4c, 0x31, 0x2e, 0x2e, 0x0c, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x25, 0x53, 0x18, 0x4a, 0x54, 0x55, 0x56, 0x51, 0x11, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x22, 0x32, 0x32, 0x32, 0x38, 0x38, 0x32, 0x2c, 0x37, 0x38, 0x30, 0x30, 0x3e, 0x3a, 0x3a, 0x2a, 0x4a, 0x4a, 0x05, 0x4a, 0x57, 0x58, 0x59, 0x5a, 0x35, 0x58, 0x5b, 0x5c, 0x5d, 0x5e, 0x4a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4d, 0x07, 0x37, 0x32, 0x38, 0x38, 0x32, 0x32, 0x41, 0x38, 0x30, 0x30, 0x3e, 0x3a, 0x3d, 0x27, 0x05, 0x4a, 0x4a, 0x4a, 0x5c, 0x5f, 0x59, 0x1d, 0x29, 0x2f, 0x60, 0x61, 0x26, 0x0b, 0x1c, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4e, 0x0a, 0x2d, 0x38, 0x38, 0x32, 0x37, 0x32, 0x2d, 0x39, 0x36, 0x31, 0x62, 0x3d, 0x0e, 0x4a, 0x4a, 0x4a, 0x09, 0x63, 0x64, 0x64, 0x61, 0x2d, 0x1d, 0x65, 0x61, 0x2b, 0x17, 0x16, 0x4a, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x27, 0x2c, 0x38, 0x38, 0x37, 0x37, 0x38, 0x2d, 0x30, 0x31, 0x42, 0x3a, 0x18, 0x09, 0x05, 0x05, 0x4a, 0x63, 0x60, 0x60, 0x2b, 0x10, 0x2d, 0x41, 0x41, 0x30, 0x42, 0x3e, 0x29, 0x09, 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x37, 0x32, 0x38, 0x32, 0x41, 0x38, 0x38, 0x30, 0x66, 0x31, 0x3a, 0x1e, 0x67, 0x4a, 0x4a, 0x05, 0x68, 0x64, 0x61, 0x2b, 0x17, 0x36, 0x10, 0x33, 0x31, 0x42, 0x3d, 0x45, 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x1c, 0x2c, 0x32, 0x32, 0x37, 0x41, 0x2c, 0x46, 0x30, 0x36, 0x36, 0x42, 0x42, 0x29, 0x1b, 0x4a, 0x4a, 0x4d, 0x26, 0x60, 0x0b, 0x17, 0x36, 0x44, 0x45, 0x66, 0x3e, 0x44, 0x44, 0x1a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x2c, 0x32, 0x32, 0x38, 0x37, 0x32, 0x37, 0x30, 0x36, 0x4c, 0x31, 0x1e, 0x10, 0x1f, 0x52, 0x69, 0x52, 0x07, 0x2c, 0x10, 0x36, 0x62, 0x6a, 0x44, 0x6b, 0x3e, 0x44, 0x6c, 0x30, 0x09, 0x05, 0x05, 0x25, 0x54, 0x19, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x25, 0x2c, 0x37, 0x38, 0x37, 0x2c, 0x32, 0x32, 0x46, 0x30, 0x46, 0x4c, 0x31, 0x66, 0x4c, 0x36, 0x1a, 0x1a, 0x17, 0x37, 0x37, 0x10, 0x31, 0x62, 0x45, 0x4c, 0x3e, 0x44, 0x62, 0x30, 0x09, 0x05, 0x0a, 0x70, 0x71, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x22, 0x32, 0x32, 0x38, 0x41, 0x41, 0x38, 0x2d, 0x46, 0x66, 0x44, 0x6c, 0x6c, 0x6c, 0x3d, 0x3a, 0x42, 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x30, 0x36, 0x3e, 0x3e, 0x31, 0x07, 0x05, 0x12, 0x6e, 0x72, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x2d, 0x2c, 0x38, 0x32, 0x41, 0x37, 0x2d, 0x46, 0x66, 0x6a, 0x6c, 0x6d, 0x6d, 0x6c, 0x3d, 0x3d, 0x31, 0x38, 0x38, 0x39, 0x33, 0x39, 0x36, 0x30, 0x30, 0x66, 0x30, 0x40, 0x4d, 0x5f, 0x4d, 0x4d, 0x05, 0x05, 0x05, 0x15, 0x04, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x5a, 0x2d, 0x32, 0x32, 0x37, 0x37, 0x32, 0x38, 0x46, 0x46, 0x66, 0x45, 0x44, 0x62, 0x44, 0x44, 0x3e, 0x31, 0x31, 0x31, 0x31, 0x31, 0x33, 0x37, 0x30, 0x10, 0x06, 0x05, 0x12, 0x0a, 0x05, 0x05, 0x05, 0x08, 0x68, 0x73, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x22, 0x32, 0x32, 0x32, 0x3c, 0x37, 0x37, 0x2d, 0x39, 0x39, 0x39, 0x36, 0x36, 0x6b, 0x3e, 0x3e, 0x3e, 0x3e, 0x31, 0x4c, 0x39, 0x2d, 0x10, 0x16, 0x2a, 0x05, 0x05, 0x74, 0x74, 0x05, 0x05, 0x0c, 0x75, 0x5f, 0x1c, 0x05, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x40, 0x2c, 0x32, 0x32, 0x32, 0x41, 0x37, 0x41, 0x2c, 0x2c, 0x41, 0x2c, 0x33, 0x36, 0x31, 0x36, 0x31, 0x31, 0x17, 0x46, 0x2c, 0x16, 0x40, 0x05, 0x05, 0x05, 0x05, 0x20, 0x5f, 0x4d, 0x72, 0x76, 0x06, 0x25, 0x4a, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x40, 0x0b, 0x2d, 0x37, 0x2d, 0x2c, 0x2c, 0x37, 0x37, 0x38, 0x2c, 0x37, 0x2c, 0x10, 0x10, 0x39, 0x30, 0x0b, 0x2c, 0x11, 0x09, 0x05, 0x09, 0x4a, 0x05, 0x05, 0x19, 0x1d, 0x26, 0x76, 0x08, 0x05, 0x05, 0x05, 0x15, 0x25, 0x4d, 0x53, 0x77, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4d, 0x5a, 0x2c, 0x37, 0x2d, 0x2c, 0x37, 0x37, 0x39, 0x39, 0x33, 0x38, 0x2c, 0x2d, 0x2d, 0x2c, 0x5e, 0x2a, 0x05, 0x15, 0x3b, 0x17, 0x1f, 0x19, 0x05, 0x06, 0x26, 0x60, 0x5f, 0x0c, 0x05, 0x05, 0x05, 0x35, 0x68, 0x78, 0x56, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x2c, 0x2c, 0x2c, 0x37, 0x32, 0x37, 0x2c, 0x37, 0x32, 0x46, 0x33, 0x46, 0x39, 0x11, 0x15, 0x05, 0x05, 0x18, 0x31, 0x44, 0x6a, 0x30, 0x6e, 0x2b, 0x4b, 0x11, 0x5f, 0x63, 0x72, 0x54, 0x20, 0x74, 0x58, 0x25, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x15, 0x0b, 0x2c, 0x38, 0x2d, 0x39, 0x39, 0x2d, 0x37, 0x3c, 0x32, 0x37, 0x0b, 0x18, 0x05, 0x05, 0x05, 0x4e, 0x26, 0x32, 0x45, 0x6a, 0x46, 0x2b, 0x72, 0x4e, 0x05, 0x35, 0x0a, 0x75, 0x5f, 0x70, 0x08, 0x09, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x22, 0x2d, 0x30, 0x6b, 0x6b, 0x66, 0x36, 0x30, 0x36, 0x4c, 0x36, 0x30, 0x18, 0x05, 0x05, 0x05, 0x09, 0x4b, 0x32, 0x46, 0x66, 0x38, 0x0b, 0x09, 0x05, 0x05, 0x05, 0x05, 0x09, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0a, 0x2c, 0x2c, 0x31, 0x62, 0x62, 0x6b, 0x31, 0x45, 0x44, 0x44, 0x45, 0x31, 0x10, 0x0c, 0x4d, 0x0c, 0x08, 0x0b, 0x3c, 0x32, 0x33, 0x66, 0x17, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x22, 0x2c, 0x2d, 0x31, 0x45, 0x6b, 0x36, 0x31, 0x6b, 0x62, 0x45, 0x6a, 0x66, 0x30, 0x0b, 0x2c, 0x2c, 0x2c, 0x2c, 0x37, 0x46, 0x6b, 0x44, 0x62, 0x5e, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x1d, 0x2c, 0x39, 0x36, 0x4c, 0x30, 0x30, 0x30, 0x36, 0x4c, 0x66, 0x4c, 0x36, 0x30, 0x37, 0x41, 0x2c, 0x2d, 0x2c, 0x3c, 0x33, 0x6b, 0x44, 0x44, 0x39, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x2d, 0x2d, 0x2d, 0x36, 0x39, 0x2d, 0x32, 0x38, 0x38, 0x46, 0x6a, 0x6d, 0x3d, 0x62, 0x46, 0x3c, 0x37, 0x2d, 0x32, 0x32, 0x32, 0x38, 0x4c, 0x30, 0x16, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0a, 0x37, 0x38, 0x38, 0x39, 0x37, 0x2c, 0x37, 0x37, 0x30, 0x45, 0x6d, 0x6d, 0x62, 0x62, 0x38, 0x3c, 0x3c, 0x32, 0x37, 0x32, 0x32, 0x32, 0x2c, 0x14, 0x15, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x6e, 0x37, 0x38, 0x38, 0x38, 0x37, 0x2c, 0x2d, 0x30, 0x31, 0x62, 0x6a, 0x6d, 0x6a, 0x6a, 0x46, 0x32, 0x32, 0x37, 0x37, 0x32, 0x30, 0x17, 0x29, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4a, 0x0b, 0x38, 0x38, 0x38, 0x2c, 0x2c, 0x0b, 0x2d, 0x39, 0x4c, 0x45, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x38, 0x37, 0x2c, 0x41, 0x18, 0x1c, 0x0c, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x15, 0x0b, 0x2d, 0x38, 0x38, 0x37, 0x2c, 0x2c, 0x2c, 0x37, 0x32, 0x4c, 0x6b, 0x44, 0x44, 0x45, 0x6a, 0x45, 0x38, 0x37, 0x1c, 0x09, 0x05, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x1d, 0x38, 0x38, 0x38, 0x38, 0x2c, 0x3c, 0x37, 0x37, 0x32, 0x32, 0x46, 0x36, 0x1e, 0x6b, 0x4c, 0x46, 0x32, 0x22, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x37, 0x32, 0x37, 0x38, 0x38, 0x37, 0x32, 0x3c, 0x32, 0x32, 0x37, 0x38, 0x2d, 0x2d, 0x38, 0x2c, 0x2c, 0x4f, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x3c, 0x37, 0x41, 0x38, 0x2d, 0x37, 0x37, 0x3c, 0x32, 0x3c, 0x32, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x41, 0x3c, 0x3c, 0x38, 0x32, 0x3c, 0x3c, 0x3c, 0x41, 0x32, 0x41, 0x37, 0x2c, 0x2c, 0x41, 0x38, 0x45, 0x18, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x2c, 0x3c, 0x37, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x4c, 0x45, 0x6a, 0x1a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x2c, 0x37, 0x41, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x41, 0x37, 0x37, 0x4c, 0x44, 0x6d, 0x6a, 0x1a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x5a, 0x2c, 0x41, 0x3c, 0x3c, 0x3c, 0x32, 0x2c, 0x32, 0x2c, 0x2c, 0x38, 0x38, 0x36, 0x45, 0x62, 0x44, 0x45, 0x29, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x2c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x32, 0x37, 0x39, 0x4c, 0x4c, 0x45, 0x62, 0x44, 0x62, 0x30, 0x2a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4a, 0x5a, 0x41, 0x3c, 0x3c, 0x3c, 0x3c, 0x32, 0x3c, 0x37, 0x37, 0x2d, 0x46, 0x4c, 0x6b, 0x6b, 0x45, 0x3e, 0x36, 0x29, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x27, 0x3c, 0x37, 0x3c, 0x3c, 0x37, 0x37, 0x32, 0x38, 0x37, 0x37, 0x37, 0x38, 0x39, 0x36, 0x4c, 0x30, 0x10, 0x16, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x25, 0x1d, 0x37, 0x37, 0x41, 0x32, 0x3c, 0x32, 0x41, 0x37, 0x32, 0x2c, 0x41, 0x37, 0x2c, 0x32, 0x37, 0x2c, 0x2c, 0x5a, 0x0c, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x05, 0x05, 0x15, 0x5a, 0x37, 0x2c, 0x41, 0x2c, 0x2c, 0x41, 0x37, 0x41, 0x41, 0x3c, 0x2c, 0x41, 0x41, 0x3c, 0x37, 0x2c, 0x39, 0x0b, 0x0b, 0x25, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x2a, 0x22, 0x2d, 0x37, 0x2c, 0x3c, 0x1d, 0x2c, 0x38, 0x2c, 0x41, 0x2c, 0x2c, 0x2d, 0x39, 0x37, 0x3c, 0x37, 0x30, 0x1a, 0x5e, 0x6e, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x2a, 0x6e, 0x0b, 0x2d, 0x38, 0x41, 0x41, 0x6e, 0x5a, 0x2c, 0x41, 0x32, 0x38, 0x32, 0x39, 0x3f, 0x6f, 0x16, 0x37, 0x1a, 0x1f, 0x1f, 0x16, 0x1d, 0x0c, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x09, 0x40, 0x07, 0x2c, 0x37, 0x2c, 0x2d, 0x2c, 0x1d, 0x0e, 0x09, 0x0b, 0x4b, 0x07, 0x41, 0x38, 0x2d, 0x10, 0x2d, 0x10, 0x0b, 0x2b, 0x33, 0x3f, 0x21, 0x29, 0x07, 0x5e, 0x2f, 0x12, 0x08, 0x2a, 0x0c, 0x25, 0x09, 0x09, 0x09, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x19, 0x40, 0x28, 0x22, 0x2c, 0x38, 0x32, 0x32, 0x32, 0x1d, 0x0e, 0x19, 0x05, 0x35, 0x2c, 0x4b, 0x70, 0x0b, 0x32, 0x2c, 0x16, 0x16, 0x16, 0x0b, 0x22, 0x26, 0x0b, 0x10, 0x3f, 0x29, 0x1f, 0x47, 0x1f, 0x1f, 0x5e, 0x0b, 0x4b, 0x74, 0x84, 0x74, 0x84, 0x06, 0x35, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x09, 0x4d, 0x27, 0x0a, 0x22, 0x1d, 0x2c, 0x2c, 0x37, 0x32, 0x41, 0x41, 0x16, 0x27, 0x15, 0x09, 0x4a, 0x09, 0x28, 0x2d, 0x0b, 0x76, 0x2c, 0x37, 0x2d, 0x37, 0x32, 0x37, 0x0b, 0x0b, 0x5e, 0x5a, 0x4b, 0x0b, 0x0b, 0x07, 0x6e, 0x16, 0x5e, 0x10, 0x76, 0x5c, 0x68, 0x79, 0x7a, 0x53, 0x71, 0x54, 0x5d, 0x08, 0x4d, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x25, 0x27, 0x28, 0x0b, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x41, 0x41, 0x41, 0x22, 0x11, 0x35, 0x4d, 0x4d, 0x35, 0x1c, 0x06, 0x0a, 0x22, 0x38, 0x38, 0x37, 0x38, 0x38, 0x38, 0x2d, 0x39, 0x39, 0x39, 0x10, 0x39, 0x10, 0x4b, 0x12, 0x08, 0x35, 0x67, 0x2a, 0x08, 0x74, 0x70, 0x81, 0x55, 0x78, 0x79, 0x57, 0x53, 0x71, 0x71, 0x73, 0x84, 0x25, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x05, 0x09, 0x27, 0x16, 0x0b, 0x2c, 0x2d, 0x2c, 0x41, 0x41, 0x1d, 0x22, 0x5a, 0x0f, 0x14, 0x0a, 0x28, 0x0a, 0x28, 0x28, 0x28, 0x6e, 0x5a, 0x65, 0x1d, 0x0b, 0x2d, 0x38, 0x46, 0x38, 0x38, 0x38, 0x39, 0x2d, 0x46, 0x39, 0x30, 0x39, 0x4b, 0x68, 0x79, 0x7a, 0x57, 0x67, 0x67, 0x56, 0x53, 0x71, 0x68, 0x7e, 0x85, 0x59, 0x73, 0x79, 0x54, 0x7a, 0x54, 0x06, 0x1c, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x4d, 0x16, 0x0b, 0x10, 0x39, 0x2d, 0x0b, 0x28, 0x06, 0x2a, 0x25, 0x35, 0x06, 0x11, 0x0a, 0x28, 0x07, 0x5a, 0x22, 0x26, 0x5a, 0x41, 0x7b, 0x7c, 0x60, 0x76, 0x22, 0x1d, 0x32, 0x38, 0x46, 0x46, 0x46, 0x38, 0x38, 0x38, 0x38, 0x2b, 0x75, 0x7d, 0x7e, 0x55, 0x78, 0x7a, 0x57, 0x57, 0x57, 0x71, 0x20, 0x68, 0x55, 0x85, 0x7a, 0x57, 0x53, 0x71, 0x57, 0x5d, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x0c, 0x16, 0x0b, 0x30, 0x39, 0x18, 0x2a, 0x09, 0x05, 0x4e, 0x19, 0x25, 0x0c, 0x27, 0x11, 0x0a, 0x0a, 0x2f, 0x5a, 0x5a, 0x26, 0x5a, 0x7b, 0x7c, 0x7c, 0x61, 0x7f, 0x7f, 0x7f, 0x76, 0x22, 0x22, 0x0b, 0x2d, 0x0b, 0x2d, 0x2d, 0x33, 0x0b, 0x5f, 0x80, 0x7d, 0x5c, 0x81, 0x55, 0x59, 0x59, 0x73, 0x73, 0x54, 0x5c, 0x5c, 0x7e, 0x55, 0x59, 0x73, 0x7a, 0x71, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x09, 0x25, 0x08, 0x07, 0x5e, 0x10, 0x22, 0x1c, 0x4a, 0x05, 0x09, 0x05, 0x15, 0x4d, 0x19, 0x19, 0x4d, 0x08, 0x12, 0x74, 0x0f, 0x6e, 0x5a, 0x26, 0x1d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x61, 0x5b, 0x82, 0x82, 0x80, 0x80, 0x82, 0x7f, 0x7f, 0x7f, 0x7f, 0x5b, 0x7f, 0x82, 0x80, 0x7d, 0x5c, 0x7e, 0x79, 0x54, 0x54, 0x7a, 0x73, 0x0f, 0x2a, 0x25, 0x19, 0x09, 0x4a, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x4d, 0x2a, 0x06, 0x74, 0x28, 0x22, 0x22, 0x2d, 0x2c, 0x0e, 0x05, 0x05, 0x05, 0x05, 0x05, 0x3b, 0x07, 0x19, 0x09, 0x25, 0x0c, 0x27, 0x12, 0x0f, 0x2f, 0x26, 0x26, 0x1d, 0x65, 0x65, 0x7c, 0x7c, 0x7b, 0x7c, 0x7b, 0x7b, 0x60, 0x5b, 0x7f, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x80, 0x80, 0x83, 0x83, 0x81, 0x7e, 0x59, 0x73, 0x73, 0x84, 0x5d, 0x25, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x19, 0x08, 0x12, 0x0a, 0x0f, 0x6e, 0x5a, 0x26, 0x22, 0x2c, 0x2c, 0x0b, 0x27, 0x05, 0x05, 0x05, 0x15, 0x1e, 0x1e, 0x6f, 0x0c, 0x09, 0x15, 0x0c, 0x20, 0x12, 0x0f, 0x6e, 0x5a, 0x26, 0x26, 0x26, 0x65, 0x65, 0x65, 0x65, 0x7b, 0x7c, 0x7b, 0x65, 0x7b, 0x61, 0x61, 0x60, 0x64, 0x64, 0x64, 0x5b, 0x5b, 0x5f, 0x63, 0x70, 0x63, 0x58, 0x5d, 0x2a, 0x15, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x4a, 0x4d, 0x27, 0x11, 0x0a, 0x28, 0x6e, 0x5a, 0x26, 0x65, 0x41, 0x1d, 0x2c, 0x2c, 0x5e, 0x29, 0x0e, 0x14, 0x17, 0x31, 0x6b, 0x30, 0x14, 0x25, 0x09, 0x15, 0x4d, 0x08, 0x74, 0x0a, 0x0f, 0x2f, 0x5a, 0x26, 0x26, 0x1d, 0x1d, 0x1d, 0x2b, 0x65, 0x1d, 0x41, 0x65, 0x65, 0x7b, 0x65, 0x65, 0x1d, 0x6e, 0x74, 0x5d, 0x1c, 0x25, 0x15, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x19, 0x4d, 0x08, 0x06, 0x0a, 0x2f, 0x6e, 0x2f, 0x6e, 0x26, 0x41, 0x7b, 0x65, 0x41, 0x37, 0x33, 0x30, 0x36, 0x36, 0x4c, 0x6b, 0x66, 0x30, 0x14, 0x35, 0x4a, 0x09, 0x15, 0x15, 0x25, 0x25, 0x0c, 0x1c, 0x08, 0x06, 0x5d, 0x5d, 0x5d, 0x0e, 0x06, 0x12, 0x06, 0x08, 0x1c, 0x2a, 0x0c, 0x19, 0x09, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x09, 0x19, 0x35, 0x08, 0x12, 0x28, 0x2f, 0x2f, 0x6e, 0x5a, 0x41, 0x7c, 0x3c, 0x3c, 0x2c, 0x41, 0x2d, 0x2d, 0x39, 0x30, 0x4c, 0x4c, 0x66, 0x66, 0x31, 0x24, 0x20, 0x4a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x4a, 0x09, 0x4a, 0x09, 0x09, 0x05, 0x09, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x15, 0x0c, 0x1c, 0x12, 0x28, 0x2f, 0x5a, 0x1d, 0x7c, 0x7b, 0x41, 0x7b, 0x3c, 0x7b, 0x3c, 0x41, 0x41, 0x5a, 0x16, 0x28, 0x14, 0x14, 0x14, 0x3b, 0x12, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x4a, 0x09, 0x15, 0x1c, 0x12, 0x12, 0x0a, 0x0f, 0x2f, 0x07, 0x2f, 0x0a, 0x12, 0x27, 0x0c, 0x4d, 0x15, 0x09, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x09, 0x15, 0x15, 0x15, 0x19, 0x4e, 0x4e, 0x05, 0x4a, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+unsigned int logo_img_size = sizeof(logo_img);
diff --git a/sys/dev/syscons/logo/logo.c b/sys/dev/syscons/logo/logo.c
index ea3f46e..1c5aa22 100644
--- a/sys/dev/syscons/logo/logo.c
+++ b/sys/dev/syscons/logo/logo.c
@@ -1,358 +1,841 @@
/* $FreeBSD$ */
-#define logo_width 88
-#define logo_height 88
+#define LOGO_WIDTH 66
+#define LOGO_HEIGHT 69
-unsigned int logo_w = logo_width;
-unsigned int logo_h = logo_height;
+unsigned int logo_w = LOGO_WIDTH;
+unsigned int logo_h = LOGO_HEIGHT;
-unsigned char logo_pal[768] = {
- 0x00, 0x00, 0x00,
- 0x33, 0x33, 0x33,
- 0x66, 0x66, 0x66,
- 0x99, 0x99, 0x99,
- 0xcc, 0xcc, 0xcc,
- 0xff, 0xff, 0xff,
- 0x90, 0x8f, 0x90,
- 0x56, 0x4b, 0x55,
- 0xa3, 0xa5, 0xab,
- 0xfd, 0xfd, 0xfd,
- 0x6d, 0x6e, 0x74,
- 0x41, 0x2b, 0x39,
- 0xcb, 0xc8, 0xcb,
- 0xcf, 0xbb, 0xba,
- 0x8e, 0x82, 0x87,
- 0x5c, 0x5d, 0x60,
- 0x52, 0x2a, 0x37,
- 0x7f, 0x76, 0x7d,
- 0x82, 0x82, 0x85,
- 0x7a, 0x3e, 0x45,
- 0x7f, 0x6e, 0x70,
- 0xef, 0xef, 0xed,
- 0x53, 0x41, 0x4b,
- 0x67, 0x2b, 0x35,
- 0x6a, 0x55, 0x62,
- 0xe7, 0xe2, 0xe3,
- 0x64, 0x35, 0x3f,
- 0xf7, 0xe0, 0xe7,
- 0xb1, 0xb2, 0xb2,
- 0x31, 0x2b, 0x35,
- 0x7a, 0x2d, 0x37,
- 0x69, 0x4c, 0x56,
- 0x95, 0x9d, 0xa4,
- 0x85, 0x61, 0x69,
- 0x40, 0x34, 0x41,
- 0x8f, 0x2e, 0x39,
- 0x7a, 0x50, 0x5a,
- 0xde, 0xe1, 0xe0,
- 0x32, 0x33, 0x3d,
- 0xa0, 0x9b, 0x9c,
- 0x68, 0x63, 0x67,
- 0x76, 0x60, 0x67,
- 0xba, 0xb6, 0xb8,
- 0x29, 0x24, 0x41,
- 0x38, 0x21, 0x29,
- 0x42, 0x21, 0x27,
- 0xa2, 0x2a, 0x32,
- 0x56, 0x55, 0x58,
- 0x55, 0x21, 0x2b,
- 0x7a, 0x20, 0x2a,
- 0x37, 0x16, 0x21,
- 0x4d, 0x18, 0x37,
- 0x8a, 0x3a, 0x3e,
- 0xc0, 0xc2, 0xc4,
- 0x64, 0x23, 0x2c,
- 0x37, 0x1a, 0x24,
- 0x42, 0x18, 0x20,
- 0x4c, 0x21, 0x2b,
- 0xa0, 0x23, 0x2e,
- 0x95, 0x6c, 0x76,
- 0x26, 0x16, 0x1c,
- 0xa5, 0x18, 0x23,
- 0x84, 0x20, 0x2b,
- 0x6d, 0x3f, 0x49,
- 0xae, 0xa7, 0xac,
- 0x2a, 0x1f, 0x24,
- 0x90, 0x21, 0x30,
- 0xa0, 0x39, 0x3e,
- 0x95, 0x0f, 0x1c,
- 0x84, 0x13, 0x1e,
- 0x4e, 0x17, 0x24,
- 0x8c, 0x56, 0x5f,
- 0xe0, 0xc4, 0xcb,
- 0xa5, 0x7f, 0x8e,
- 0xff, 0xff, 0xf1,
- 0x3d, 0x3d, 0x5d,
- 0x61, 0x19, 0x26,
- 0xd5, 0xd5, 0xd5,
- 0xff, 0xf1, 0xed,
- 0xb6, 0x9c, 0xa5,
- 0x87, 0x4c, 0x5a,
- 0xa0, 0x76, 0x76,
- 0xc8, 0xa0, 0xa0,
- 0xa2, 0xc1, 0xc8,
- 0x91, 0xae, 0xb6,
- 0x52, 0x8b, 0xae,
- 0xb3, 0xd2, 0xd4,
- 0x95, 0xb7, 0xc1,
- 0x54, 0x6e, 0x83,
- 0x67, 0x90, 0xa6,
- 0x44, 0x3e, 0x45,
- 0x23, 0x40, 0x6a,
- 0x41, 0x6e, 0x97,
- 0x7e, 0x8e, 0x91,
- 0x52, 0x33, 0x41,
- 0x39, 0x49, 0x68,
- 0x1d, 0x2a, 0x48,
- 0x17, 0x21, 0x45,
- 0x90, 0x17, 0x1f,
- 0x38, 0x54, 0x71,
- 0x1c, 0x33, 0x58,
- 0x1c, 0x1e, 0x23,
- 0x6c, 0x17, 0x21,
- 0xb0, 0xc5, 0xc1,
- 0x5d, 0x7f, 0x96,
- 0xe9, 0xbf, 0xc1,
- 0x96, 0x06, 0x0f,
- 0x78, 0x16, 0x1e,
- 0xab, 0x0e, 0x18,
- 0xa6, 0x06, 0x0e,
- 0x4c, 0x4c, 0x54,
- 0x61, 0x42, 0x4c,
- 0x48, 0x5f, 0x84,
- 0xa0, 0xb8, 0xbe,
- 0x5c, 0x66, 0x7f,
- 0x7b, 0x9e, 0xa9,
- 0x6f, 0x75, 0x7f,
- 0x45, 0x54, 0x74,
- 0x32, 0x3e, 0x63,
- 0xb1, 0xb4, 0xb3,
- 0x66, 0x9d, 0xb4,
- 0x7a, 0x9f, 0xbb,
- 0x82, 0xaa, 0xba,
- 0x13, 0x15, 0x17,
- 0x0b, 0x0b, 0x0a,
- 0x37, 0x66, 0x92,
- 0x4c, 0x7f, 0xa5,
- 0x24, 0x4c, 0x7b,
- 0x25, 0x5f, 0x91,
- 0x40, 0x7d, 0xa5,
- 0x1d, 0x56, 0x88,
- 0x2d, 0x6f, 0xa0,
- 0x70, 0x81, 0x8f,
- 0x58, 0x97, 0xbd,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
+unsigned char logo_pal[256 * 3] = {
+ 0x00, 0x00, 0x00,
+ 0x0b, 0x00, 0x00,
+ 0x0b, 0x0b, 0x0b,
+ 0x13, 0x01, 0x01,
+ 0x1b, 0x05, 0x04,
+ 0x13, 0x13, 0x13,
+ 0x1b, 0x1b, 0x1b,
+ 0x1c, 0x15, 0x14,
+ 0x25, 0x03, 0x01,
+ 0x33, 0x0e, 0x0c,
+ 0x23, 0x21, 0x1a,
+ 0x23, 0x23, 0x23,
+ 0x2b, 0x2b, 0x2b,
+ 0x3c, 0x3c, 0x3c,
+ 0x34, 0x32, 0x32,
+ 0x35, 0x30, 0x2a,
+ 0x58, 0x00, 0x00,
+ 0x4c, 0x0f, 0x0d,
+ 0x47, 0x24, 0x15,
+ 0x6c, 0x01, 0x01,
+ 0x66, 0x09, 0x09,
+ 0x66, 0x17, 0x15,
+ 0x74, 0x01, 0x00,
+ 0x7b, 0x00, 0x00,
+ 0x77, 0x09, 0x08,
+ 0x79, 0x19, 0x17,
+ 0x6e, 0x3e, 0x3e,
+ 0x76, 0x35, 0x35,
+ 0x72, 0x2b, 0x26,
+ 0x65, 0x2a, 0x20,
+ 0x5a, 0x4f, 0x32,
+ 0x44, 0x44, 0x44,
+ 0x4b, 0x4a, 0x4a,
+ 0x57, 0x56, 0x56,
+ 0x56, 0x4d, 0x4c,
+ 0x77, 0x45, 0x45,
+ 0x6d, 0x5d, 0x4f,
+ 0x6c, 0x6c, 0x6c,
+ 0x62, 0x62, 0x62,
+ 0x76, 0x75, 0x75,
+ 0x72, 0x67, 0x55,
+ 0x84, 0x00, 0x00,
+ 0x8b, 0x00, 0x00,
+ 0x88, 0x0c, 0x0b,
+ 0x89, 0x18, 0x17,
+ 0x93, 0x00, 0x00,
+ 0x9b, 0x00, 0x00,
+ 0x99, 0x0a, 0x06,
+ 0x95, 0x17, 0x16,
+ 0x95, 0x11, 0x0c,
+ 0x87, 0x2a, 0x29,
+ 0x99, 0x29, 0x27,
+ 0x98, 0x37, 0x37,
+ 0x86, 0x39, 0x34,
+ 0xa4, 0x00, 0x00,
+ 0xab, 0x00, 0x00,
+ 0xab, 0x0c, 0x01,
+ 0xa7, 0x0b, 0x06,
+ 0xa8, 0x13, 0x0a,
+ 0xa6, 0x16, 0x15,
+ 0xb3, 0x00, 0x00,
+ 0xbb, 0x00, 0x00,
+ 0xb7, 0x0a, 0x03,
+ 0xb3, 0x12, 0x00,
+ 0xba, 0x15, 0x03,
+ 0xb5, 0x18, 0x17,
+ 0xb7, 0x27, 0x03,
+ 0xb9, 0x27, 0x18,
+ 0xa8, 0x2a, 0x16,
+ 0xa8, 0x26, 0x25,
+ 0xb9, 0x2a, 0x29,
+ 0xb6, 0x39, 0x37,
+ 0xab, 0x35, 0x2f,
+ 0xae, 0x4c, 0x36,
+ 0x93, 0x5d, 0x39,
+ 0x90, 0x4e, 0x4b,
+ 0x91, 0x67, 0x56,
+ 0x8a, 0x75, 0x70,
+ 0xa8, 0x49, 0x47,
+ 0xb4, 0x5a, 0x58,
+ 0xb2, 0x53, 0x4b,
+ 0xac, 0x71, 0x53,
+ 0xb8, 0x7a, 0x78,
+ 0xb2, 0x65, 0x64,
+ 0xc3, 0x01, 0x00,
+ 0xc3, 0x0a, 0x00,
+ 0xcb, 0x00, 0x00,
+ 0xca, 0x0b, 0x00,
+ 0xc7, 0x08, 0x08,
+ 0xc5, 0x13, 0x00,
+ 0xcb, 0x12, 0x00,
+ 0xcb, 0x1a, 0x01,
+ 0xc3, 0x18, 0x05,
+ 0xc9, 0x17, 0x14,
+ 0xd3, 0x00, 0x00,
+ 0xd2, 0x0b, 0x00,
+ 0xdb, 0x00, 0x00,
+ 0xd8, 0x0c, 0x05,
+ 0xd3, 0x14, 0x00,
+ 0xd3, 0x1b, 0x01,
+ 0xdb, 0x1c, 0x01,
+ 0xd9, 0x14, 0x03,
+ 0xd5, 0x18, 0x15,
+ 0xc8, 0x25, 0x01,
+ 0xd4, 0x23, 0x02,
+ 0xd3, 0x2b, 0x01,
+ 0xdb, 0x22, 0x01,
+ 0xdb, 0x2a, 0x01,
+ 0xd5, 0x27, 0x1c,
+ 0xd6, 0x33, 0x02,
+ 0xdb, 0x33, 0x02,
+ 0xda, 0x3a, 0x03,
+ 0xd4, 0x3c, 0x1a,
+ 0xc8, 0x33, 0x17,
+ 0xca, 0x29, 0x24,
+ 0xc8, 0x32, 0x2b,
+ 0xd3, 0x35, 0x2d,
+ 0xe3, 0x00, 0x00,
+ 0xeb, 0x00, 0x00,
+ 0xea, 0x0b, 0x00,
+ 0xe5, 0x18, 0x03,
+ 0xf1, 0x03, 0x00,
+ 0xf4, 0x0b, 0x00,
+ 0xf4, 0x17, 0x01,
+ 0xe2, 0x24, 0x01,
+ 0xe3, 0x2a, 0x01,
+ 0xe9, 0x2c, 0x02,
+ 0xea, 0x28, 0x07,
+ 0xe3, 0x33, 0x01,
+ 0xe3, 0x3b, 0x02,
+ 0xea, 0x33, 0x02,
+ 0xeb, 0x3c, 0x02,
+ 0xe9, 0x3c, 0x09,
+ 0xf4, 0x25, 0x04,
+ 0xf3, 0x34, 0x0e,
+ 0xed, 0x35, 0x29,
+ 0xd9, 0x45, 0x0b,
+ 0xd7, 0x43, 0x14,
+ 0xc8, 0x40, 0x19,
+ 0xd7, 0x56, 0x3a,
+ 0xcf, 0x46, 0x34,
+ 0xec, 0x43, 0x03,
+ 0xeb, 0x4c, 0x04,
+ 0xe4, 0x47, 0x05,
+ 0xe9, 0x58, 0x17,
+ 0xf0, 0x47, 0x03,
+ 0xf1, 0x4f, 0x11,
+ 0xee, 0x4a, 0x2d,
+ 0xee, 0x6d, 0x19,
+ 0xee, 0x6c, 0x34,
+ 0xcf, 0x66, 0x33,
+ 0xc9, 0x4b, 0x49,
+ 0xc6, 0x57, 0x57,
+ 0xdb, 0x55, 0x4a,
+ 0xd7, 0x58, 0x52,
+ 0xcf, 0x4e, 0x49,
+ 0xd3, 0x69, 0x54,
+ 0xc9, 0x69, 0x67,
+ 0xc9, 0x77, 0x76,
+ 0xda, 0x7a, 0x77,
+ 0xd3, 0x72, 0x6d,
+ 0xf5, 0x59, 0x4c,
+ 0xed, 0x71, 0x51,
+ 0xe5, 0x74, 0x65,
+ 0xef, 0x76, 0x6e,
+ 0xb6, 0x8c, 0x6b,
+ 0xa4, 0x8c, 0x63,
+ 0xf2, 0x98, 0x28,
+ 0xf2, 0x92, 0x36,
+ 0xf3, 0xa8, 0x2b,
+ 0xf6, 0xb4, 0x35,
+ 0xed, 0xaa, 0x34,
+ 0xdb, 0x95, 0x2c,
+ 0xf1, 0x8f, 0x52,
+ 0xfa, 0x87, 0x67,
+ 0xfa, 0x97, 0x75,
+ 0xef, 0x8e, 0x73,
+ 0xf2, 0xb1, 0x4f,
+ 0xf5, 0xa6, 0x79,
+ 0xf0, 0xae, 0x71,
+ 0xd1, 0x88, 0x76,
+ 0xf6, 0xcc, 0x69,
+ 0xfc, 0xe9, 0x76,
+ 0x89, 0x89, 0x89,
+ 0x98, 0x97, 0x97,
+ 0x90, 0x8f, 0x8f,
+ 0xb3, 0x94, 0x89,
+ 0xa6, 0xa6, 0xa5,
+ 0xb8, 0xb8, 0xb8,
+ 0xb2, 0xa8, 0xa6,
+ 0xc3, 0x8c, 0x8b,
+ 0xd5, 0x88, 0x87,
+ 0xd7, 0x99, 0x98,
+ 0xcd, 0x9a, 0x9a,
+ 0xd0, 0xa6, 0x93,
+ 0xc6, 0xaa, 0xa4,
+ 0xd5, 0xa7, 0xa7,
+ 0xd9, 0xb8, 0xb6,
+ 0xc6, 0xb9, 0xb5,
+ 0xfa, 0x9a, 0x8a,
+ 0xef, 0x94, 0x8d,
+ 0xed, 0xa6, 0x93,
+ 0xf7, 0xa7, 0x86,
+ 0xf5, 0xa9, 0x98,
+ 0xf6, 0xb7, 0x87,
+ 0xf6, 0xb5, 0x97,
+ 0xec, 0xab, 0x93,
+ 0xe5, 0xa7, 0xa6,
+ 0xe2, 0xb4, 0xb4,
+ 0xfa, 0xac, 0xa3,
+ 0xf3, 0xb6, 0xa6,
+ 0xfa, 0xba, 0xb5,
+ 0xe8, 0xb6, 0xac,
+ 0xf5, 0xc2, 0x94,
+ 0xfa, 0xc7, 0xa8,
+ 0xf8, 0xc7, 0xba,
+ 0xfa, 0xd4, 0xab,
+ 0xf9, 0xd5, 0xb8,
+ 0xeb, 0xc5, 0xb1,
+ 0xfd, 0xea, 0x8b,
+ 0xfd, 0xeb, 0xba,
+ 0xfd, 0xef, 0xae,
+ 0xd2, 0xc7, 0xbf,
+ 0xca, 0xc8, 0xc7,
+ 0xd5, 0xc7, 0xc7,
+ 0xd7, 0xd6, 0xd6,
+ 0xd3, 0xd1, 0xc4,
+ 0xea, 0xc6, 0xc6,
+ 0xec, 0xd3, 0xd3,
+ 0xe8, 0xda, 0xd9,
+ 0xf8, 0xca, 0xc8,
+ 0xfa, 0xd8, 0xc7,
+ 0xf1, 0xd5, 0xd4,
+ 0xf3, 0xda, 0xda,
+ 0xfb, 0xdb, 0xd3,
+ 0xfb, 0xdd, 0xdb,
+ 0xf8, 0xd7, 0xd5,
+ 0xef, 0xde, 0xc8,
+ 0xfb, 0xe4, 0xcd,
+ 0xfc, 0xe8, 0xc9,
+ 0xfc, 0xe4, 0xdc,
+ 0xfb, 0xeb, 0xdb,
+ 0xf8, 0xe6, 0xd6,
+ 0xfd, 0xf7, 0xcb,
+ 0xf1, 0xe9, 0xd9,
+ 0xe9, 0xe6, 0xe6,
+ 0xfa, 0xe4, 0xe3,
+ 0xfb, 0xeb, 0xe3,
+ 0xfa, 0xec, 0xea,
+ 0xf4, 0xe7, 0xe4,
+ 0xfc, 0xf1, 0xe3,
+ 0xfc, 0xf2, 0xec,
+ 0xf4, 0xf4, 0xf4,
+ 0xfc, 0xf4, 0xf2,
+ 0xfd, 0xf9, 0xf5,
+ 0xfd, 0xfc, 0xfb
};
-unsigned char logo_img[logo_width*logo_height] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x09, 0x0a, 0x0b, 0x07, 0x0c, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0d, 0x0e, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x09, 0x0f, 0x0b, 0x10, 0x11, 0x09, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x12, 0x13, 0x14, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x16, 0x0b, 0x17, 0x18, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x13, 0x1a, 0x1b, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1c, 0x1d, 0x10, 0x1e, 0x1f, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x20, 0x0b, 0x1e, 0x21, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x19, 0x22, 0x0b, 0x17, 0x23, 0x24, 0x15, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x25, 0x26, 0x10, 0x23, 0x27, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x05, 0x05, 0x05, 0x25, 0x27, 0x11, 0x28, 0x29, 0x11, 0x06, 0x0d, 0x09, 0x05, 0x2a, 0x2b, 0x2c, 0x2d, 0x1e, 0x2e, 0x21, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2f, 0x0b, 0x30, 0x31, 0x0c, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x06, 0x16, 0x22, 0x1d, 0x2c, 0x32, 0x33, 0x17, 0x17, 0x17, 0x22, 0x14, 0x16, 0x1d, 0x2c, 0x2d, 0x1e, 0x2e, 0x34, 0x0c, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x2b, 0x2c, 0x36, 0x36, 0x35, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x27, 0x0b, 0x2c, 0x2c, 0x37, 0x32, 0x38, 0x2c, 0x2d, 0x39, 0x36, 0x17, 0x30, 0x2c, 0x2c, 0x2d, 0x2c, 0x2c, 0x1a, 0x3a, 0x3a, 0x3b, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0a, 0x2d, 0x2b, 0x33, 0x31, 0x0e, 0x05, 0x05, 0x05, 0x05, 0x09, 0x28, 0x2c, 0x37, 0x3c, 0x32, 0x38, 0x38, 0x37, 0x2c, 0x30, 0x36, 0x36, 0x17, 0x31, 0x36, 0x23, 0x23, 0x17, 0x2c, 0x17, 0x3a, 0x3d, 0x13, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x22, 0x2c, 0x37, 0x33, 0x3e, 0x31, 0x3f, 0x40, 0x19, 0x05, 0x11, 0x2c, 0x2c, 0x32, 0x32, 0x32, 0x38, 0x37, 0x41, 0x30, 0x3a, 0x3a, 0x2e, 0x42, 0x43, 0x17, 0x1a, 0x13, 0x23, 0x31, 0x1a, 0x2e, 0x3d, 0x1a, 0x09, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0b, 0x37, 0x32, 0x37, 0x33, 0x44, 0x44, 0x45, 0x17, 0x1a, 0x10, 0x2d, 0x37, 0x38, 0x46, 0x33, 0x46, 0x32, 0x2c, 0x23, 0x23, 0x47, 0x21, 0x13, 0x43, 0x34, 0x48, 0x19, 0x49, 0x34, 0x17, 0x1e, 0x3a, 0x13, 0x4a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4b, 0x32, 0x32, 0x32, 0x32, 0x4c, 0x45, 0x44, 0x44, 0x42, 0x36, 0x30, 0x33, 0x46, 0x38, 0x33, 0x46, 0x38, 0x31, 0x23, 0x27, 0x09, 0x4a, 0x4d, 0x47, 0x43, 0x0d, 0x4e, 0x4a, 0x4f, 0x34, 0x1a, 0x2e, 0x29, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x33, 0x32, 0x32, 0x32, 0x33, 0x4c, 0x31, 0x45, 0x3e, 0x31, 0x36, 0x46, 0x46, 0x33, 0x33, 0x39, 0x30, 0x23, 0x50, 0x4a, 0x4a, 0x4a, 0x4a, 0x4d, 0x47, 0x51, 0x4e, 0x4a, 0x4a, 0x0e, 0x13, 0x1a, 0x27, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x2b, 0x32, 0x32, 0x2b, 0x32, 0x33, 0x4c, 0x33, 0x4c, 0x4c, 0x36, 0x30, 0x30, 0x30, 0x30, 0x31, 0x23, 0x3a, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4f, 0x50, 0x1b, 0x4e, 0x4a, 0x19, 0x50, 0x16, 0x0c, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x32, 0x32, 0x32, 0x32, 0x2b, 0x33, 0x33, 0x30, 0x2d, 0x39, 0x30, 0x30, 0x30, 0x4c, 0x36, 0x42, 0x3a, 0x52, 0x05, 0x4a, 0x4a, 0x4a, 0x4a, 0x09, 0x3b, 0x52, 0x4e, 0x4a, 0x4a, 0x4f, 0x1a, 0x2a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4d, 0x2b, 0x2b, 0x32, 0x32, 0x32, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x10, 0x30, 0x30, 0x3e, 0x23, 0x3a, 0x0d, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x40, 0x51, 0x4a, 0x4a, 0x25, 0x15, 0x1f, 0x27, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x40, 0x22, 0x2c, 0x32, 0x32, 0x32, 0x38, 0x2d, 0x2c, 0x41, 0x32, 0x39, 0x46, 0x4c, 0x31, 0x2e, 0x2e, 0x0c, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x25, 0x53, 0x18, 0x4a, 0x54, 0x55, 0x56, 0x51, 0x11, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x22, 0x32, 0x32, 0x32, 0x38, 0x38, 0x32, 0x2c, 0x37, 0x38, 0x30, 0x30, 0x3e, 0x3a, 0x3a, 0x2a, 0x4a, 0x4a, 0x05, 0x4a, 0x57, 0x58, 0x59, 0x5a, 0x35, 0x58, 0x5b, 0x5c, 0x5d, 0x5e, 0x4a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4d, 0x07, 0x37, 0x32, 0x38, 0x38, 0x32, 0x32, 0x41, 0x38, 0x30, 0x30, 0x3e, 0x3a, 0x3d, 0x27, 0x05, 0x4a, 0x4a, 0x4a, 0x5c, 0x5f, 0x59, 0x1d, 0x29, 0x2f, 0x60, 0x61, 0x26, 0x0b, 0x1c, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4e, 0x0a, 0x2d, 0x38, 0x38, 0x32, 0x37, 0x32, 0x2d, 0x39, 0x36, 0x31, 0x62, 0x3d, 0x0e, 0x4a, 0x4a, 0x4a, 0x09, 0x63, 0x64, 0x64, 0x61, 0x2d, 0x1d, 0x65, 0x61, 0x2b, 0x17, 0x16, 0x4a, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x27, 0x2c, 0x38, 0x38, 0x37, 0x37, 0x38, 0x2d, 0x30, 0x31, 0x42, 0x3a, 0x18, 0x09, 0x05, 0x05, 0x4a, 0x63, 0x60, 0x60, 0x2b, 0x10, 0x2d, 0x41, 0x41, 0x30, 0x42, 0x3e, 0x29, 0x09, 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x37, 0x32, 0x38, 0x32, 0x41, 0x38, 0x38, 0x30, 0x66, 0x31, 0x3a, 0x1e, 0x67, 0x4a, 0x4a, 0x05, 0x68, 0x64, 0x61, 0x2b, 0x17, 0x36, 0x10, 0x33, 0x31, 0x42, 0x3d, 0x45, 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x1c, 0x2c, 0x32, 0x32, 0x37, 0x41, 0x2c, 0x46, 0x30, 0x36, 0x36, 0x42, 0x42, 0x29, 0x1b, 0x4a, 0x4a, 0x4d, 0x26, 0x60, 0x0b, 0x17, 0x36, 0x44, 0x45, 0x66, 0x3e, 0x44, 0x44, 0x1a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x2c, 0x32, 0x32, 0x38, 0x37, 0x32, 0x37, 0x30, 0x36, 0x4c, 0x31, 0x1e, 0x10, 0x1f, 0x52, 0x69, 0x52, 0x07, 0x2c, 0x10, 0x36, 0x62, 0x6a, 0x44, 0x6b, 0x3e, 0x44, 0x6c, 0x30, 0x09, 0x05, 0x05, 0x25, 0x54, 0x19, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x25, 0x2c, 0x37, 0x38, 0x37, 0x2c, 0x32, 0x32, 0x46, 0x30, 0x46, 0x4c, 0x31, 0x66, 0x4c, 0x36, 0x1a, 0x1a, 0x17, 0x37, 0x37, 0x10, 0x31, 0x62, 0x45, 0x4c, 0x3e, 0x44, 0x62, 0x30, 0x09, 0x05, 0x0a, 0x70, 0x71, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x22, 0x32, 0x32, 0x38, 0x41, 0x41, 0x38, 0x2d, 0x46, 0x66, 0x44, 0x6c, 0x6c, 0x6c, 0x3d, 0x3a, 0x42, 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x30, 0x36, 0x3e, 0x3e, 0x31, 0x07, 0x05, 0x12, 0x6e, 0x72, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x2d, 0x2c, 0x38, 0x32, 0x41, 0x37, 0x2d, 0x46, 0x66, 0x6a, 0x6c, 0x6d, 0x6d, 0x6c, 0x3d, 0x3d, 0x31, 0x38, 0x38, 0x39, 0x33, 0x39, 0x36, 0x30, 0x30, 0x66, 0x30, 0x40, 0x4d, 0x5f, 0x4d, 0x4d, 0x05, 0x05, 0x05, 0x15, 0x04, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x5a, 0x2d, 0x32, 0x32, 0x37, 0x37, 0x32, 0x38, 0x46, 0x46, 0x66, 0x45, 0x44, 0x62, 0x44, 0x44, 0x3e, 0x31, 0x31, 0x31, 0x31, 0x31, 0x33, 0x37, 0x30, 0x10, 0x06, 0x05, 0x12, 0x0a, 0x05, 0x05, 0x05, 0x08, 0x68, 0x73, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x22, 0x32, 0x32, 0x32, 0x3c, 0x37, 0x37, 0x2d, 0x39, 0x39, 0x39, 0x36, 0x36, 0x6b, 0x3e, 0x3e, 0x3e, 0x3e, 0x31, 0x4c, 0x39, 0x2d, 0x10, 0x16, 0x2a, 0x05, 0x05, 0x74, 0x74, 0x05, 0x05, 0x0c, 0x75, 0x5f, 0x1c, 0x05, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x40, 0x2c, 0x32, 0x32, 0x32, 0x41, 0x37, 0x41, 0x2c, 0x2c, 0x41, 0x2c, 0x33, 0x36, 0x31, 0x36, 0x31, 0x31, 0x17, 0x46, 0x2c, 0x16, 0x40, 0x05, 0x05, 0x05, 0x05, 0x20, 0x5f, 0x4d, 0x72, 0x76, 0x06, 0x25, 0x4a, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x40, 0x0b, 0x2d, 0x37, 0x2d, 0x2c, 0x2c, 0x37, 0x37, 0x38, 0x2c, 0x37, 0x2c, 0x10, 0x10, 0x39, 0x30, 0x0b, 0x2c, 0x11, 0x09, 0x05, 0x09, 0x4a, 0x05, 0x05, 0x19, 0x1d, 0x26, 0x76, 0x08, 0x05, 0x05, 0x05, 0x15, 0x25, 0x4d, 0x53, 0x77, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4d, 0x5a, 0x2c, 0x37, 0x2d, 0x2c, 0x37, 0x37, 0x39, 0x39, 0x33, 0x38, 0x2c, 0x2d, 0x2d, 0x2c, 0x5e, 0x2a, 0x05, 0x15, 0x3b, 0x17, 0x1f, 0x19, 0x05, 0x06, 0x26, 0x60, 0x5f, 0x0c, 0x05, 0x05, 0x05, 0x35, 0x68, 0x78, 0x56, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x2c, 0x2c, 0x2c, 0x37, 0x32, 0x37, 0x2c, 0x37, 0x32, 0x46, 0x33, 0x46, 0x39, 0x11, 0x15, 0x05, 0x05, 0x18, 0x31, 0x44, 0x6a, 0x30, 0x6e, 0x2b, 0x4b, 0x11, 0x5f, 0x63, 0x72, 0x54, 0x20, 0x74, 0x58, 0x25, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x15, 0x0b, 0x2c, 0x38, 0x2d, 0x39, 0x39, 0x2d, 0x37, 0x3c, 0x32, 0x37, 0x0b, 0x18, 0x05, 0x05, 0x05, 0x4e, 0x26, 0x32, 0x45, 0x6a, 0x46, 0x2b, 0x72, 0x4e, 0x05, 0x35, 0x0a, 0x75, 0x5f, 0x70, 0x08, 0x09, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x35, 0x22, 0x2d, 0x30, 0x6b, 0x6b, 0x66, 0x36, 0x30, 0x36, 0x4c, 0x36, 0x30, 0x18, 0x05, 0x05, 0x05, 0x09, 0x4b, 0x32, 0x46, 0x66, 0x38, 0x0b, 0x09, 0x05, 0x05, 0x05, 0x05, 0x09, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0a, 0x2c, 0x2c, 0x31, 0x62, 0x62, 0x6b, 0x31, 0x45, 0x44, 0x44, 0x45, 0x31, 0x10, 0x0c, 0x4d, 0x0c, 0x08, 0x0b, 0x3c, 0x32, 0x33, 0x66, 0x17, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x22, 0x2c, 0x2d, 0x31, 0x45, 0x6b, 0x36, 0x31, 0x6b, 0x62, 0x45, 0x6a, 0x66, 0x30, 0x0b, 0x2c, 0x2c, 0x2c, 0x2c, 0x37, 0x46, 0x6b, 0x44, 0x62, 0x5e, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x1d, 0x2c, 0x39, 0x36, 0x4c, 0x30, 0x30, 0x30, 0x36, 0x4c, 0x66, 0x4c, 0x36, 0x30, 0x37, 0x41, 0x2c, 0x2d, 0x2c, 0x3c, 0x33, 0x6b, 0x44, 0x44, 0x39, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x2d, 0x2d, 0x2d, 0x36, 0x39, 0x2d, 0x32, 0x38, 0x38, 0x46, 0x6a, 0x6d, 0x3d, 0x62, 0x46, 0x3c, 0x37, 0x2d, 0x32, 0x32, 0x32, 0x38, 0x4c, 0x30, 0x16, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0a, 0x37, 0x38, 0x38, 0x39, 0x37, 0x2c, 0x37, 0x37, 0x30, 0x45, 0x6d, 0x6d, 0x62, 0x62, 0x38, 0x3c, 0x3c, 0x32, 0x37, 0x32, 0x32, 0x32, 0x2c, 0x14, 0x15, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x6e, 0x37, 0x38, 0x38, 0x38, 0x37, 0x2c, 0x2d, 0x30, 0x31, 0x62, 0x6a, 0x6d, 0x6a, 0x6a, 0x46, 0x32, 0x32, 0x37, 0x37, 0x32, 0x30, 0x17, 0x29, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4a, 0x0b, 0x38, 0x38, 0x38, 0x2c, 0x2c, 0x0b, 0x2d, 0x39, 0x4c, 0x45, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x38, 0x37, 0x2c, 0x41, 0x18, 0x1c, 0x0c, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x15, 0x0b, 0x2d, 0x38, 0x38, 0x37, 0x2c, 0x2c, 0x2c, 0x37, 0x32, 0x4c, 0x6b, 0x44, 0x44, 0x45, 0x6a, 0x45, 0x38, 0x37, 0x1c, 0x09, 0x05, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x1d, 0x38, 0x38, 0x38, 0x38, 0x2c, 0x3c, 0x37, 0x37, 0x32, 0x32, 0x46, 0x36, 0x1e, 0x6b, 0x4c, 0x46, 0x32, 0x22, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x37, 0x32, 0x37, 0x38, 0x38, 0x37, 0x32, 0x3c, 0x32, 0x32, 0x37, 0x38, 0x2d, 0x2d, 0x38, 0x2c, 0x2c, 0x4f, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x3c, 0x37, 0x41, 0x38, 0x2d, 0x37, 0x37, 0x3c, 0x32, 0x3c, 0x32, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x41, 0x3c, 0x3c, 0x38, 0x32, 0x3c, 0x3c, 0x3c, 0x41, 0x32, 0x41, 0x37, 0x2c, 0x2c, 0x41, 0x38, 0x45, 0x18, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x2c, 0x3c, 0x37, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x4c, 0x45, 0x6a, 0x1a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x2c, 0x37, 0x41, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x41, 0x37, 0x37, 0x4c, 0x44, 0x6d, 0x6a, 0x1a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x5a, 0x2c, 0x41, 0x3c, 0x3c, 0x3c, 0x32, 0x2c, 0x32, 0x2c, 0x2c, 0x38, 0x38, 0x36, 0x45, 0x62, 0x44, 0x45, 0x29, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x2a, 0x2c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x32, 0x37, 0x39, 0x4c, 0x4c, 0x45, 0x62, 0x44, 0x62, 0x30, 0x2a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x4a, 0x5a, 0x41, 0x3c, 0x3c, 0x3c, 0x3c, 0x32, 0x3c, 0x37, 0x37, 0x2d, 0x46, 0x4c, 0x6b, 0x6b, 0x45, 0x3e, 0x36, 0x29, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x27, 0x3c, 0x37, 0x3c, 0x3c, 0x37, 0x37, 0x32, 0x38, 0x37, 0x37, 0x37, 0x38, 0x39, 0x36, 0x4c, 0x30, 0x10, 0x16, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x25, 0x1d, 0x37, 0x37, 0x41, 0x32, 0x3c, 0x32, 0x41, 0x37, 0x32, 0x2c, 0x41, 0x37, 0x2c, 0x32, 0x37, 0x2c, 0x2c, 0x5a, 0x0c, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x05, 0x05, 0x15, 0x5a, 0x37, 0x2c, 0x41, 0x2c, 0x2c, 0x41, 0x37, 0x41, 0x41, 0x3c, 0x2c, 0x41, 0x41, 0x3c, 0x37, 0x2c, 0x39, 0x0b, 0x0b, 0x25, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x2a, 0x22, 0x2d, 0x37, 0x2c, 0x3c, 0x1d, 0x2c, 0x38, 0x2c, 0x41, 0x2c, 0x2c, 0x2d, 0x39, 0x37, 0x3c, 0x37, 0x30, 0x1a, 0x5e, 0x6e, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x2a, 0x6e, 0x0b, 0x2d, 0x38, 0x41, 0x41, 0x6e, 0x5a, 0x2c, 0x41, 0x32, 0x38, 0x32, 0x39, 0x3f, 0x6f, 0x16, 0x37, 0x1a, 0x1f, 0x1f, 0x16, 0x1d, 0x0c, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x09, 0x40, 0x07, 0x2c, 0x37, 0x2c, 0x2d, 0x2c, 0x1d, 0x0e, 0x09, 0x0b, 0x4b, 0x07, 0x41, 0x38, 0x2d, 0x10, 0x2d, 0x10, 0x0b, 0x2b, 0x33, 0x3f, 0x21, 0x29, 0x07, 0x5e, 0x2f, 0x12, 0x08, 0x2a, 0x0c, 0x25, 0x09, 0x09, 0x09, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x19, 0x40, 0x28, 0x22, 0x2c, 0x38, 0x32, 0x32, 0x32, 0x1d, 0x0e, 0x19, 0x05, 0x35, 0x2c, 0x4b, 0x70, 0x0b, 0x32, 0x2c, 0x16, 0x16, 0x16, 0x0b, 0x22, 0x26, 0x0b, 0x10, 0x3f, 0x29, 0x1f, 0x47, 0x1f, 0x1f, 0x5e, 0x0b, 0x4b, 0x74, 0x84, 0x74, 0x84, 0x06, 0x35, 0x09, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x09, 0x4d, 0x27, 0x0a, 0x22, 0x1d, 0x2c, 0x2c, 0x37, 0x32, 0x41, 0x41, 0x16, 0x27, 0x15, 0x09, 0x4a, 0x09, 0x28, 0x2d, 0x0b, 0x76, 0x2c, 0x37, 0x2d, 0x37, 0x32, 0x37, 0x0b, 0x0b, 0x5e, 0x5a, 0x4b, 0x0b, 0x0b, 0x07, 0x6e, 0x16, 0x5e, 0x10, 0x76, 0x5c, 0x68, 0x79, 0x7a, 0x53, 0x71, 0x54, 0x5d, 0x08, 0x4d, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x25, 0x27, 0x28, 0x0b, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x41, 0x41, 0x41, 0x22, 0x11, 0x35, 0x4d, 0x4d, 0x35, 0x1c, 0x06, 0x0a, 0x22, 0x38, 0x38, 0x37, 0x38, 0x38, 0x38, 0x2d, 0x39, 0x39, 0x39, 0x10, 0x39, 0x10, 0x4b, 0x12, 0x08, 0x35, 0x67, 0x2a, 0x08, 0x74, 0x70, 0x81, 0x55, 0x78, 0x79, 0x57, 0x53, 0x71, 0x71, 0x73, 0x84, 0x25, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x05, 0x09, 0x27, 0x16, 0x0b, 0x2c, 0x2d, 0x2c, 0x41, 0x41, 0x1d, 0x22, 0x5a, 0x0f, 0x14, 0x0a, 0x28, 0x0a, 0x28, 0x28, 0x28, 0x6e, 0x5a, 0x65, 0x1d, 0x0b, 0x2d, 0x38, 0x46, 0x38, 0x38, 0x38, 0x39, 0x2d, 0x46, 0x39, 0x30, 0x39, 0x4b, 0x68, 0x79, 0x7a, 0x57, 0x67, 0x67, 0x56, 0x53, 0x71, 0x68, 0x7e, 0x85, 0x59, 0x73, 0x79, 0x54, 0x7a, 0x54, 0x06, 0x1c, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x4d, 0x16, 0x0b, 0x10, 0x39, 0x2d, 0x0b, 0x28, 0x06, 0x2a, 0x25, 0x35, 0x06, 0x11, 0x0a, 0x28, 0x07, 0x5a, 0x22, 0x26, 0x5a, 0x41, 0x7b, 0x7c, 0x60, 0x76, 0x22, 0x1d, 0x32, 0x38, 0x46, 0x46, 0x46, 0x38, 0x38, 0x38, 0x38, 0x2b, 0x75, 0x7d, 0x7e, 0x55, 0x78, 0x7a, 0x57, 0x57, 0x57, 0x71, 0x20, 0x68, 0x55, 0x85, 0x7a, 0x57, 0x53, 0x71, 0x57, 0x5d, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x0c, 0x16, 0x0b, 0x30, 0x39, 0x18, 0x2a, 0x09, 0x05, 0x4e, 0x19, 0x25, 0x0c, 0x27, 0x11, 0x0a, 0x0a, 0x2f, 0x5a, 0x5a, 0x26, 0x5a, 0x7b, 0x7c, 0x7c, 0x61, 0x7f, 0x7f, 0x7f, 0x76, 0x22, 0x22, 0x0b, 0x2d, 0x0b, 0x2d, 0x2d, 0x33, 0x0b, 0x5f, 0x80, 0x7d, 0x5c, 0x81, 0x55, 0x59, 0x59, 0x73, 0x73, 0x54, 0x5c, 0x5c, 0x7e, 0x55, 0x59, 0x73, 0x7a, 0x71, 0x19, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x09, 0x25, 0x08, 0x07, 0x5e, 0x10, 0x22, 0x1c, 0x4a, 0x05, 0x09, 0x05, 0x15, 0x4d, 0x19, 0x19, 0x4d, 0x08, 0x12, 0x74, 0x0f, 0x6e, 0x5a, 0x26, 0x1d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x61, 0x5b, 0x82, 0x82, 0x80, 0x80, 0x82, 0x7f, 0x7f, 0x7f, 0x7f, 0x5b, 0x7f, 0x82, 0x80, 0x7d, 0x5c, 0x7e, 0x79, 0x54, 0x54, 0x7a, 0x73, 0x0f, 0x2a, 0x25, 0x19, 0x09, 0x4a, 0x05, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x4d, 0x2a, 0x06, 0x74, 0x28, 0x22, 0x22, 0x2d, 0x2c, 0x0e, 0x05, 0x05, 0x05, 0x05, 0x05, 0x3b, 0x07, 0x19, 0x09, 0x25, 0x0c, 0x27, 0x12, 0x0f, 0x2f, 0x26, 0x26, 0x1d, 0x65, 0x65, 0x7c, 0x7c, 0x7b, 0x7c, 0x7b, 0x7b, 0x60, 0x5b, 0x7f, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x80, 0x80, 0x83, 0x83, 0x81, 0x7e, 0x59, 0x73, 0x73, 0x84, 0x5d, 0x25, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x19, 0x08, 0x12, 0x0a, 0x0f, 0x6e, 0x5a, 0x26, 0x22, 0x2c, 0x2c, 0x0b, 0x27, 0x05, 0x05, 0x05, 0x15, 0x1e, 0x1e, 0x6f, 0x0c, 0x09, 0x15, 0x0c, 0x20, 0x12, 0x0f, 0x6e, 0x5a, 0x26, 0x26, 0x26, 0x65, 0x65, 0x65, 0x65, 0x7b, 0x7c, 0x7b, 0x65, 0x7b, 0x61, 0x61, 0x60, 0x64, 0x64, 0x64, 0x5b, 0x5b, 0x5f, 0x63, 0x70, 0x63, 0x58, 0x5d, 0x2a, 0x15, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x4a, 0x4d, 0x27, 0x11, 0x0a, 0x28, 0x6e, 0x5a, 0x26, 0x65, 0x41, 0x1d, 0x2c, 0x2c, 0x5e, 0x29, 0x0e, 0x14, 0x17, 0x31, 0x6b, 0x30, 0x14, 0x25, 0x09, 0x15, 0x4d, 0x08, 0x74, 0x0a, 0x0f, 0x2f, 0x5a, 0x26, 0x26, 0x1d, 0x1d, 0x1d, 0x2b, 0x65, 0x1d, 0x41, 0x65, 0x65, 0x7b, 0x65, 0x65, 0x1d, 0x6e, 0x74, 0x5d, 0x1c, 0x25, 0x15, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x19, 0x4d, 0x08, 0x06, 0x0a, 0x2f, 0x6e, 0x2f, 0x6e, 0x26, 0x41, 0x7b, 0x65, 0x41, 0x37, 0x33, 0x30, 0x36, 0x36, 0x4c, 0x6b, 0x66, 0x30, 0x14, 0x35, 0x4a, 0x09, 0x15, 0x15, 0x25, 0x25, 0x0c, 0x1c, 0x08, 0x06, 0x5d, 0x5d, 0x5d, 0x0e, 0x06, 0x12, 0x06, 0x08, 0x1c, 0x2a, 0x0c, 0x19, 0x09, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x09, 0x19, 0x35, 0x08, 0x12, 0x28, 0x2f, 0x2f, 0x6e, 0x5a, 0x41, 0x7c, 0x3c, 0x3c, 0x2c, 0x41, 0x2d, 0x2d, 0x39, 0x30, 0x4c, 0x4c, 0x66, 0x66, 0x31, 0x24, 0x20, 0x4a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x4a, 0x09, 0x4a, 0x09, 0x09, 0x05, 0x09, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x15, 0x0c, 0x1c, 0x12, 0x28, 0x2f, 0x5a, 0x1d, 0x7c, 0x7b, 0x41, 0x7b, 0x3c, 0x7b, 0x3c, 0x41, 0x41, 0x5a, 0x16, 0x28, 0x14, 0x14, 0x14, 0x3b, 0x12, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x4a, 0x09, 0x15, 0x1c, 0x12, 0x12, 0x0a, 0x0f, 0x2f, 0x07, 0x2f, 0x0a, 0x12, 0x27, 0x0c, 0x4d, 0x15, 0x09, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x09, 0x15, 0x15, 0x15, 0x19, 0x4e, 0x4e, 0x05, 0x4a, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+unsigned char logo_img[LOGO_WIDTH * LOGO_HEIGHT] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02,
+ 0x02, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0b,
+ 0x0b, 0x06, 0x06, 0x06, 0x05, 0x05, 0x02, 0x02,
+ 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x10, 0x2c, 0x48, 0x47, 0x33,
+ 0x14, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x05, 0x05,
+ 0x06, 0x0b, 0x0c, 0x1f, 0x21, 0x25, 0xb7, 0xb9,
+ 0xb8, 0xb8, 0xb9, 0xb9, 0x27, 0x26, 0x20, 0x0d,
+ 0x0c, 0x06, 0x06, 0x05, 0x02, 0x02, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x11, 0x2c, 0x45, 0x44, 0x31, 0x18, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x13, 0x2b, 0x45, 0x47,
+ 0xa0, 0xc8, 0xc8, 0x9c, 0x47, 0x15, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x05, 0x06,
+ 0x0b, 0x0d, 0x26, 0xb8, 0xbc, 0xe1, 0xf5, 0xfc,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ 0xf5, 0xdf, 0xbb, 0xb7, 0x21, 0x0e, 0x0b, 0x05,
+ 0x05, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x11, 0x35, 0x9a, 0xa4, 0xa4, 0x9f, 0x97, 0x3a,
+ 0x2a, 0x16, 0x08, 0x00, 0x00, 0x04, 0x2a, 0x29,
+ 0x31, 0x45, 0x97, 0xc8, 0xe6, 0xd3, 0xc7, 0xb0,
+ 0x9c, 0x1c, 0x08, 0x00, 0x02, 0x02, 0x05, 0x06,
+ 0x0c, 0x21, 0xb8, 0xe1, 0xfc, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf5, 0xbc,
+ 0x27, 0x1f, 0x0c, 0x06, 0x02, 0x02, 0x00, 0x01,
+ 0x12, 0x50, 0xb0, 0xd1, 0xd3, 0xd3, 0xd2, 0x9f,
+ 0x46, 0x2f, 0x29, 0x2a, 0x10, 0x00, 0x00, 0x08,
+ 0x2e, 0x29, 0x2a, 0x3a, 0x43, 0x9b, 0xd4, 0xf8,
+ 0xec, 0xd3, 0xd1, 0xc7, 0xa3, 0x1c, 0x0a, 0x0a,
+ 0x0c, 0x26, 0xbc, 0xf5, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfd, 0xfe,
+ 0xff, 0xff, 0xfc, 0xe1, 0xb7, 0x1f, 0x0c, 0x06,
+ 0x12, 0x51, 0xd2, 0xed, 0xec, 0xec, 0xf6, 0xeb,
+ 0xcf, 0x97, 0x41, 0x2d, 0x29, 0x2d, 0x13, 0x00,
+ 0x00, 0x03, 0x2e, 0x2a, 0x2a, 0x2e, 0x3a, 0x72,
+ 0x99, 0xd1, 0xe9, 0xec, 0xd7, 0xd7, 0xd6, 0xd5,
+ 0xb4, 0x4c, 0xbb, 0xf5, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xfd, 0xe9, 0xe9, 0xe8, 0xe9, 0xe9,
+ 0xe9, 0xeb, 0xf0, 0xf8, 0xfc, 0xfe, 0xfd, 0xe1,
+ 0x4d, 0x51, 0xd2, 0xf0, 0xf6, 0xf7, 0xf6, 0xfd,
+ 0xf6, 0xd1, 0x9a, 0x73, 0x3a, 0x2d, 0x29, 0x2d,
+ 0x10, 0x00, 0x00, 0x01, 0x2d, 0x2d, 0x29, 0x2d,
+ 0x39, 0x40, 0x6c, 0xa1, 0xa4, 0xcb, 0xd3, 0xe6,
+ 0xe6, 0xe7, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xe9, 0xe9,
+ 0xe8, 0xec, 0xec, 0xe4, 0xcf, 0xc0, 0xc0, 0xda,
+ 0xe9, 0xd8, 0xd8, 0xfa, 0xfb, 0xfb, 0xf8, 0xfb,
+ 0xf8, 0xec, 0xd1, 0xa3, 0x8c, 0x41, 0x2f, 0x2a,
+ 0x29, 0x2e, 0x11, 0x00, 0x00, 0x00, 0x16, 0x36,
+ 0x29, 0x2d, 0x2e, 0x3c, 0x5d, 0x6c, 0x87, 0xa1,
+ 0xa4, 0xcb, 0xe7, 0xf8, 0xfc, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xfd, 0xe9, 0xe8, 0xe8, 0xe8, 0xbf, 0x41, 0x3e,
+ 0x3b, 0x8c, 0xcd, 0xf1, 0xfe, 0xfd, 0xfd, 0xfb,
+ 0xfb, 0xf0, 0xe6, 0xc7, 0xa4, 0x9a, 0x73, 0x39,
+ 0x2d, 0x29, 0x2a, 0x3b, 0x08, 0x00, 0x00, 0x00,
+ 0x11, 0x37, 0x2a, 0x2a, 0x2d, 0x37, 0x3e, 0x61,
+ 0x87, 0x87, 0xa1, 0xc7, 0xf6, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
+ 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf9, 0xe5, 0xe3, 0x46,
+ 0x36, 0x3a, 0x8c, 0xd4, 0xfb, 0xff, 0xfe, 0xff,
+ 0xfd, 0xf8, 0xf0, 0xe6, 0xd1, 0xc8, 0xa4, 0x74,
+ 0x3e, 0x36, 0x2a, 0x29, 0x3b, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x08, 0x3b, 0x2f, 0x29, 0x2a, 0x36,
+ 0x3e, 0x58, 0x6c, 0x87, 0xc7, 0xf9, 0xff, 0xff,
+ 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff,
+ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc,
+ 0xff, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xf9,
+ 0xe3, 0x45, 0x39, 0x8c, 0xe7, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xfb, 0xeb, 0xe6, 0xd3, 0xc7, 0xa4,
+ 0x8c, 0x3e, 0x3c, 0x2f, 0x29, 0x31, 0x47, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x2a,
+ 0x29, 0x2f, 0x38, 0x5d, 0x6c, 0xa4, 0xf6, 0xff,
+ 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
+ 0xff, 0xfe, 0xfd, 0xfb, 0xfb, 0xfd, 0xfd, 0xfc,
+ 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
+ 0xfc, 0xff, 0xe9, 0x47, 0x3a, 0xb0, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xfd, 0xf6, 0xec, 0xd3, 0xd1,
+ 0xc8, 0x8c, 0x58, 0x3e, 0x36, 0x2d, 0x29, 0x45,
+ 0x47, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x09,
+ 0x47, 0x2f, 0x29, 0x2f, 0x3a, 0x41, 0x98, 0xe8,
+ 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xfb, 0xfe,
+ 0xfd, 0xfe, 0xfe, 0xfb, 0xfb, 0xfb, 0xfa, 0xfb,
+ 0xfb, 0xfb, 0xfd, 0xfd, 0xf8, 0xf8, 0xfd, 0xfd,
+ 0xf8, 0xfd, 0xf8, 0xf8, 0xf8, 0xc0, 0x97, 0xcc,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf8, 0xeb, 0xec,
+ 0xd3, 0xc8, 0x87, 0x5f, 0x3d, 0x37, 0x2f, 0x2a,
+ 0x30, 0x4f, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x34, 0x46, 0x2b, 0x2b, 0x3b, 0x97,
+ 0xe3, 0xfd, 0xff, 0xff, 0xfd, 0xf8, 0xfd, 0xfd,
+ 0xfd, 0xfd, 0xfd, 0xfd, 0xf8, 0xf8, 0xf7, 0xf7,
+ 0xfa, 0xfa, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
+ 0xf8, 0xf8, 0xfa, 0xf7, 0xf7, 0xfa, 0xf1, 0xe3,
+ 0xbf, 0xca, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xf6,
+ 0xeb, 0xd7, 0xaf, 0x87, 0x60, 0x57, 0x3c, 0x36,
+ 0x2d, 0x2b, 0x4e, 0x9d, 0x09, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x12, 0x98, 0x30, 0x2b,
+ 0x48, 0xc4, 0xfc, 0xff, 0xff, 0xfd, 0xf8, 0xf8,
+ 0xfd, 0xfd, 0xfb, 0xfb, 0xfd, 0xfd, 0xf8, 0xf8,
+ 0xf6, 0xf1, 0xf1, 0xf0, 0xf7, 0xf8, 0xf9, 0xf9,
+ 0xf7, 0xf4, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf4,
+ 0xf9, 0xf0, 0xd0, 0xce, 0xf0, 0xff, 0xff, 0xfd,
+ 0xfb, 0xeb, 0xd3, 0xa4, 0x87, 0x61, 0x5e, 0x3e,
+ 0x38, 0x2e, 0x2a, 0x33, 0x9e, 0x34, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4e,
+ 0x50, 0x33, 0xbe, 0xf8, 0xfd, 0xff, 0xfd, 0xf8,
+ 0xf8, 0xfb, 0xfb, 0xfe, 0xfb, 0xfb, 0xfb, 0xf8,
+ 0xf6, 0xf6, 0xeb, 0xef, 0xef, 0xf0, 0xf6, 0xf6,
+ 0xeb, 0xf2, 0xef, 0xee, 0xee, 0xef, 0xef, 0xee,
+ 0xf2, 0xf6, 0xe9, 0xf4, 0xe8, 0xcf, 0xd1, 0xf7,
+ 0xf0, 0xea, 0xd3, 0xc7, 0xa1, 0x87, 0x78, 0x5f,
+ 0x55, 0x3c, 0x36, 0x2a, 0x2c, 0x4f, 0x9e, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1d, 0xa0, 0x53, 0xe4, 0xfc, 0xff, 0xfd,
+ 0xf6, 0xf6, 0xfb, 0xfb, 0xfd, 0xfe, 0xfb, 0xfb,
+ 0xf8, 0xf6, 0xf6, 0xf6, 0xeb, 0xef, 0xe7, 0xea,
+ 0xea, 0xe7, 0xe7, 0xe7, 0xd9, 0xef, 0xe7, 0xe7,
+ 0xe7, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe4, 0xbf,
+ 0x97, 0xcb, 0xd2, 0xc7, 0xae, 0xa1, 0x87, 0x78,
+ 0x61, 0x57, 0x3d, 0x36, 0x2d, 0x2b, 0x4e, 0xbf,
+ 0x4e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x53, 0xe4, 0xf6, 0xfe,
+ 0xfd, 0xf7, 0xf0, 0xf8, 0xfb, 0xfe, 0xff, 0xff,
+ 0xfe, 0xfb, 0xf7, 0xf6, 0xeb, 0xec, 0xeb, 0xe7,
+ 0xe7, 0xe7, 0xe7, 0xd9, 0xd9, 0xd9, 0xd9, 0xd7,
+ 0xd9, 0xd7, 0xe6, 0xe4, 0xe4, 0xe6, 0xe4, 0xe4,
+ 0xe4, 0xd0, 0x97, 0x99, 0xca, 0xaf, 0xa1, 0x93,
+ 0x87, 0x61, 0x57, 0x3d, 0x37, 0x2f, 0x2b, 0x34,
+ 0x9e, 0xbf, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x27, 0xe5,
+ 0xf9, 0xff, 0xf7, 0xf2, 0xf7, 0xf7, 0xfb, 0xff,
+ 0xff, 0xff, 0xfe, 0xfa, 0xf1, 0xf6, 0xec, 0xe6,
+ 0xe6, 0xe6, 0xd7, 0xd6, 0xd8, 0xd6, 0xd6, 0xd6,
+ 0xd6, 0xd2, 0xd3, 0xe3, 0xe3, 0xda, 0xe3, 0xd0,
+ 0xe3, 0xe3, 0xe3, 0xe3, 0xc1, 0x49, 0xa1, 0xa1,
+ 0xa1, 0x87, 0x77, 0x5f, 0x3e, 0x3e, 0x36, 0x2a,
+ 0x2c, 0x53, 0xc0, 0x9d, 0x0f, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c,
+ 0xdf, 0xe8, 0xfd, 0xfb, 0xe7, 0xea, 0xf1, 0xf8,
+ 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xf1, 0xf0, 0xec,
+ 0xe6, 0xe6, 0xd7, 0xd6, 0xd6, 0xd2, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xd1, 0xcf, 0xcf, 0xcf, 0xcf,
+ 0xcf, 0xcf, 0xd0, 0xd0, 0xcf, 0xd0, 0xd0, 0xbe,
+ 0x47, 0x87, 0x87, 0x77, 0x61, 0x3d, 0x3c, 0x2e,
+ 0x2d, 0x2b, 0x4e, 0xc1, 0xc8, 0xc4, 0x27, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x25, 0xe5, 0xe9, 0xfe, 0xec, 0xe7, 0xea,
+ 0xf0, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xee,
+ 0xe7, 0xe6, 0xd3, 0xd1, 0xcd, 0xcd, 0xca, 0xca,
+ 0xcb, 0xca, 0xae, 0xa2, 0xa2, 0xa1, 0x99, 0x9b,
+ 0x9b, 0x9b, 0x97, 0x97, 0x98, 0x9d, 0x9e, 0xbe,
+ 0xc0, 0xc0, 0x52, 0x48, 0x66, 0x5e, 0x3d, 0x3c,
+ 0x36, 0x2d, 0x2b, 0x33, 0x9e, 0xcf, 0x9e, 0xe0,
+ 0xbc, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0xbc, 0xe4, 0xf8, 0xf6, 0xd7,
+ 0xd9, 0xea, 0xf0, 0xfb, 0xff, 0xff, 0xff, 0xf7,
+ 0xee, 0xd9, 0xd7, 0xd3, 0xcb, 0xcc, 0xca, 0xb2,
+ 0xaf, 0xa2, 0x95, 0x93, 0x86, 0x86, 0x87, 0x72,
+ 0x72, 0x72, 0x72, 0x72, 0x46, 0x46, 0x46, 0x46,
+ 0x46, 0x47, 0x4e, 0x53, 0x52, 0x53, 0x48, 0x3e,
+ 0x3c, 0x36, 0x2e, 0x2a, 0x2c, 0x4f, 0xcf, 0x9d,
+ 0x52, 0xc6, 0xe1, 0x21, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0xe5, 0xe3, 0xfd,
+ 0xd7, 0xd4, 0xd9, 0xea, 0xf4, 0xf7, 0xfb, 0xfb,
+ 0xfa, 0xee, 0xd9, 0xd6, 0xd2, 0xcb, 0xc7, 0xaf,
+ 0xae, 0xa1, 0x92, 0x86, 0x85, 0x85, 0x7b, 0x66,
+ 0x66, 0x66, 0x66, 0x5d, 0x5d, 0x5d, 0x41, 0x41,
+ 0x41, 0x41, 0x41, 0x45, 0x45, 0x48, 0x34, 0x4e,
+ 0x4b, 0x34, 0x30, 0x2f, 0x2b, 0x2b, 0x4e, 0xbf,
+ 0x9f, 0x34, 0x53, 0xbd, 0xe1, 0xbb, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xb9, 0xe4,
+ 0xe4, 0xf7, 0xcd, 0xd2, 0xd7, 0xea, 0xf1, 0xfa,
+ 0xfa, 0xf1, 0xef, 0xd9, 0xd6, 0xcc, 0xc7, 0xaf,
+ 0xae, 0x93, 0x86, 0x85, 0x85, 0x7b, 0x7a, 0x7b,
+ 0x77, 0x61, 0x61, 0x58, 0x58, 0x58, 0x58, 0x3e,
+ 0x3e, 0x3e, 0x3e, 0x3b, 0x3b, 0x3b, 0x3b, 0x30,
+ 0x33, 0x33, 0x33, 0x4b, 0x35, 0x32, 0x19, 0x2b,
+ 0x45, 0x73, 0x34, 0x23, 0x4c, 0xba, 0xdf, 0xdf,
+ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xdf, 0xe3, 0xe9, 0xda, 0xc9, 0xcd, 0xd7, 0xf2,
+ 0xfa, 0xfb, 0xfa, 0xf1, 0xdc, 0xd5, 0xca, 0xaf,
+ 0xae, 0x95, 0x86, 0x85, 0x85, 0x7b, 0x7a, 0x7a,
+ 0x7a, 0x79, 0x75, 0x61, 0x60, 0x5e, 0x56, 0x54,
+ 0x58, 0x3d, 0x3e, 0x3c, 0x37, 0x39, 0x39, 0x36,
+ 0x39, 0x2f, 0x30, 0x30, 0x2c, 0x32, 0x35, 0x35,
+ 0x23, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x4b, 0xa5,
+ 0xc3, 0xe1, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0d, 0xe5, 0xd0, 0xe9, 0xce, 0xb2, 0xce,
+ 0xd9, 0xee, 0xfe, 0xff, 0xfa, 0xdc, 0xd8, 0xb2,
+ 0xae, 0xa2, 0x86, 0x85, 0x7b, 0x7b, 0x7a, 0x7a,
+ 0x79, 0x79, 0x79, 0x76, 0x60, 0x5e, 0x5e, 0x5e,
+ 0x56, 0x54, 0x3d, 0x3d, 0x3c, 0x3c, 0x37, 0x37,
+ 0x36, 0x2e, 0x2f, 0x2f, 0x2f, 0x2b, 0x2b, 0x2c,
+ 0x19, 0x1c, 0x35, 0x23, 0x23, 0x1a, 0x1a, 0x23,
+ 0x4b, 0x4c, 0xba, 0xe1, 0xb9, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x25, 0xe9, 0xd0, 0xe6, 0xb4,
+ 0xb0, 0xcc, 0xd8, 0xfa, 0xff, 0xff, 0xfa, 0xd8,
+ 0xd5, 0xa2, 0x90, 0x82, 0x85, 0x7b, 0x7a, 0x7a,
+ 0x79, 0x79, 0x79, 0x79, 0x79, 0x76, 0x60, 0x5e,
+ 0x5e, 0x58, 0x56, 0x54, 0x3d, 0x3d, 0x3c, 0x37,
+ 0x37, 0x36, 0x36, 0x2e, 0x2e, 0x2f, 0x2f, 0x2b,
+ 0x2b, 0x2b, 0x2b, 0x19, 0x19, 0x1c, 0x23, 0x23,
+ 0x23, 0x23, 0x4b, 0x4b, 0xa5, 0xdf, 0xbc, 0x0b,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0xb8, 0xe4, 0xd0,
+ 0xce, 0xa3, 0xad, 0xcc, 0xd8, 0xfa, 0xff, 0xfb,
+ 0xe7, 0xd5, 0xad, 0x92, 0x85, 0x85, 0x78, 0x7a,
+ 0x7a, 0x79, 0x79, 0x79, 0x79, 0x76, 0x76, 0x60,
+ 0x5e, 0x5e, 0x56, 0x56, 0x54, 0x54, 0x3d, 0x3d,
+ 0x3c, 0x37, 0x37, 0x36, 0x36, 0x2e, 0x2e, 0x2d,
+ 0x2d, 0x2a, 0x2a, 0x2b, 0x18, 0x18, 0x19, 0x15,
+ 0x1c, 0x1a, 0x1a, 0x23, 0x23, 0x4a, 0x51, 0xc5,
+ 0xe2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x05, 0xbc,
+ 0xe3, 0xc4, 0xa3, 0x95, 0xb1, 0xb3, 0xd8, 0xee,
+ 0xfa, 0xef, 0xd5, 0xad, 0x94, 0x86, 0x78, 0x77,
+ 0x77, 0x7a, 0x76, 0x76, 0x79, 0x79, 0x76, 0x76,
+ 0x76, 0x60, 0x5e, 0x56, 0x56, 0x54, 0x54, 0x3d,
+ 0x3d, 0x3c, 0x3c, 0x37, 0x37, 0x36, 0x2e, 0x2e,
+ 0x2d, 0x2d, 0x2a, 0x2a, 0x29, 0x29, 0x17, 0x16,
+ 0x18, 0x14, 0x15, 0x15, 0x1c, 0x1b, 0x35, 0x35,
+ 0x49, 0xc3, 0xe1, 0x21, 0x00, 0x00, 0x00, 0x00,
+ 0x0b, 0xe1, 0xd0, 0xc4, 0x8b, 0x94, 0xad, 0xb3,
+ 0xcd, 0xd6, 0xd8, 0xcd, 0xb1, 0x94, 0x91, 0x7c,
+ 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+ 0x76, 0x76, 0x75, 0x5e, 0x56, 0x56, 0x56, 0x54,
+ 0x54, 0x3d, 0x3d, 0x3c, 0x3c, 0x37, 0x37, 0x36,
+ 0x2e, 0x2d, 0x2d, 0x2d, 0x2a, 0x2a, 0x29, 0x29,
+ 0x17, 0x16, 0x18, 0x14, 0x14, 0x14, 0x15, 0x15,
+ 0x1c, 0x19, 0x49, 0xc2, 0xf4, 0x25, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0xe1, 0xc5, 0xbf, 0x8a, 0x90,
+ 0xa8, 0xad, 0xb2, 0xcc, 0xb2, 0xad, 0x95, 0x92,
+ 0x91, 0x78, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76,
+ 0x76, 0x75, 0x76, 0x75, 0x75, 0x5e, 0x56, 0x56,
+ 0x54, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x37, 0x36,
+ 0x36, 0x36, 0x2d, 0x2d, 0x2d, 0x2d, 0x2a, 0x29,
+ 0x29, 0x17, 0x17, 0x16, 0x16, 0x17, 0x18, 0x14,
+ 0x14, 0x14, 0x14, 0x18, 0x44, 0xc2, 0xf5, 0xb7,
+ 0x02, 0x00, 0x00, 0x00, 0x1f, 0xf5, 0xc4, 0xa0,
+ 0x6f, 0x8f, 0x90, 0x95, 0xad, 0xad, 0x95, 0x94,
+ 0x92, 0x91, 0x91, 0x78, 0x75, 0x75, 0x75, 0x75,
+ 0x75, 0x76, 0x75, 0x75, 0x75, 0x75, 0x60, 0x56,
+ 0x56, 0x54, 0x54, 0x3d, 0x3d, 0x3c, 0x3c, 0x37,
+ 0x37, 0x36, 0x36, 0x36, 0x2e, 0x2d, 0x2d, 0x2a,
+ 0x2a, 0x29, 0x29, 0x17, 0x29, 0x2a, 0x2d, 0x2d,
+ 0x13, 0x13, 0x14, 0x13, 0x14, 0x18, 0x44, 0xc2,
+ 0xfa, 0xb8, 0x02, 0x00, 0x00, 0x00, 0x20, 0xf5,
+ 0xc4, 0x9d, 0x6d, 0x80, 0x8f, 0x88, 0x90, 0x90,
+ 0x92, 0x91, 0x86, 0x83, 0x83, 0x7c, 0x75, 0x75,
+ 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+ 0x5e, 0x54, 0x54, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
+ 0x3c, 0x37, 0x37, 0x36, 0x36, 0x2d, 0x2e, 0x2d,
+ 0x2d, 0x2a, 0x2a, 0x29, 0x29, 0x2a, 0x36, 0x37,
+ 0x36, 0x17, 0x13, 0x13, 0x13, 0x13, 0x13, 0x18,
+ 0x44, 0xd5, 0xf5, 0xbb, 0x02, 0x00, 0x00, 0x00,
+ 0x21, 0xf5, 0xc0, 0x50, 0x68, 0x6b, 0x80, 0x80,
+ 0x80, 0x83, 0x80, 0x82, 0x82, 0x82, 0x83, 0x7e,
+ 0x60, 0x75, 0x60, 0x75, 0x75, 0x75, 0x75, 0x75,
+ 0x75, 0x60, 0x5e, 0x54, 0x3d, 0x3d, 0x3d, 0x3d,
+ 0x3c, 0x3c, 0x37, 0x37, 0x36, 0x36, 0x2e, 0x2d,
+ 0x2d, 0x2d, 0x2a, 0x2a, 0x2a, 0x2d, 0x37, 0x3c,
+ 0x37, 0x37, 0x2a, 0x13, 0x13, 0x13, 0x16, 0x18,
+ 0x17, 0x29, 0x44, 0xd8, 0xf4, 0xbb, 0x02, 0x00,
+ 0x00, 0x00, 0x21, 0xf5, 0xc4, 0x49, 0x68, 0x6a,
+ 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x82, 0x82,
+ 0x82, 0x82, 0x75, 0x60, 0x60, 0x60, 0x60, 0x60,
+ 0x60, 0x60, 0x60, 0x60, 0x56, 0x3d, 0x3d, 0x3d,
+ 0x3c, 0x3c, 0x37, 0x37, 0x37, 0x36, 0x36, 0x2e,
+ 0x2e, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x3c, 0x3c,
+ 0x3c, 0x3c, 0x37, 0x2e, 0x16, 0x13, 0x16, 0x16,
+ 0x17, 0x17, 0x29, 0x2a, 0x46, 0xd8, 0xfa, 0xbb,
+ 0x02, 0x00, 0x00, 0x00, 0x1f, 0xf5, 0xc4, 0x50,
+ 0x59, 0x6a, 0x6a, 0x7c, 0x7c, 0x7e, 0x7d, 0x7e,
+ 0x7e, 0x7e, 0x82, 0x82, 0x65, 0x5e, 0x60, 0x60,
+ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x56, 0x3d,
+ 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x37, 0x36, 0x36,
+ 0x2e, 0x2e, 0x2e, 0x2d, 0x2d, 0x36, 0x3c, 0x3d,
+ 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x29, 0x13, 0x13,
+ 0x16, 0x17, 0x17, 0x29, 0x2a, 0x2f, 0x8b, 0xdc,
+ 0xf9, 0xb8, 0x02, 0x00, 0x00, 0x00, 0x0d, 0xf5,
+ 0xc4, 0x47, 0x40, 0x63, 0x64, 0x64, 0x64, 0x7c,
+ 0x7c, 0x7c, 0x7e, 0x85, 0x7e, 0x7e, 0x7c, 0x60,
+ 0x60, 0x5e, 0x60, 0x5e, 0x60, 0x5e, 0x60, 0x5e,
+ 0x54, 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x37, 0x36,
+ 0x36, 0x36, 0x36, 0x2d, 0x2d, 0x36, 0x3d, 0x3d,
+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x37, 0x36, 0x16,
+ 0x13, 0x13, 0x16, 0x17, 0x29, 0x2a, 0x2a, 0x2e,
+ 0xad, 0xdc, 0xf1, 0xb8, 0x02, 0x00, 0x00, 0x00,
+ 0x0c, 0xe5, 0xe0, 0x4e, 0x3f, 0x5b, 0x65, 0x6a,
+ 0x64, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7e, 0x7e,
+ 0x7e, 0x61, 0x5e, 0x5e, 0x5e, 0x60, 0x5e, 0x5e,
+ 0x5e, 0x5e, 0x3d, 0x3c, 0x37, 0x37, 0x37, 0x36,
+ 0x36, 0x36, 0x36, 0x2e, 0x2d, 0x36, 0x3c, 0x3d,
+ 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x37, 0x37, 0x37,
+ 0x2a, 0x13, 0x13, 0x16, 0x17, 0x29, 0x29, 0x2a,
+ 0x2d, 0x43, 0xd5, 0xdc, 0xf4, 0xb7, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0xdf, 0xe4, 0x50, 0x38, 0x40,
+ 0x62, 0x65, 0x64, 0x64, 0x7c, 0x7c, 0x7c, 0x7e,
+ 0x7d, 0x7e, 0x7e, 0x64, 0x5e, 0x5e, 0x5e, 0x5e,
+ 0x5e, 0x5e, 0x5e, 0x5e, 0x3d, 0x37, 0x37, 0x37,
+ 0x36, 0x36, 0x36, 0x2e, 0x2e, 0x2d, 0x36, 0x3d,
+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c, 0x37,
+ 0x37, 0x36, 0x17, 0x13, 0x16, 0x16, 0x17, 0x29,
+ 0x2a, 0x2d, 0x36, 0x95, 0xdb, 0xdc, 0xf4, 0x25,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0xbc, 0xf9, 0x4f,
+ 0x2f, 0x3f, 0x5c, 0x64, 0x64, 0x64, 0x64, 0x64,
+ 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x5f, 0x5e,
+ 0x56, 0x56, 0x5e, 0x5e, 0x5e, 0x56, 0x3c, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x2e, 0x2e, 0x2d, 0x36,
+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
+ 0x3c, 0x37, 0x37, 0x2d, 0x16, 0x13, 0x16, 0x17,
+ 0x29, 0x29, 0x2d, 0x2d, 0x44, 0xb5, 0xdd, 0xef,
+ 0xe1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9,
+ 0xfc, 0x52, 0x31, 0x3f, 0x3f, 0x5c, 0x63, 0x65,
+ 0x64, 0x64, 0x7c, 0x7c, 0x7c, 0x7e, 0x7d, 0x7d,
+ 0x64, 0x56, 0x5e, 0x56, 0x56, 0x56, 0x56, 0x56,
+ 0x3c, 0x36, 0x36, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d,
+ 0x36, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
+ 0x3c, 0x37, 0x37, 0x37, 0x37, 0x2a, 0x13, 0x13,
+ 0x16, 0x17, 0x29, 0x2a, 0x2d, 0x39, 0xad, 0xb6,
+ 0xdd, 0xf3, 0xe2, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x26, 0xfc, 0xc4, 0x30, 0x2f, 0x3f, 0x3f,
+ 0x59, 0x62, 0x64, 0x64, 0x6a, 0x64, 0x7c, 0x7c,
+ 0x7c, 0x7d, 0x7d, 0x65, 0x56, 0x56, 0x56, 0x56,
+ 0x56, 0x56, 0x37, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d,
+ 0x2d, 0x36, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3c,
+ 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x37, 0x36, 0x29,
+ 0x13, 0x16, 0x17, 0x29, 0x2a, 0x2a, 0x2e, 0x96,
+ 0xb6, 0xdb, 0xdd, 0xf3, 0xbd, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0e, 0xe1, 0xe5, 0x32, 0x2d,
+ 0x3f, 0x3f, 0x3f, 0x5a, 0x63, 0x65, 0x64, 0x64,
+ 0x6a, 0x64, 0x7c, 0x7c, 0x7d, 0x7c, 0x57, 0x56,
+ 0x54, 0x54, 0x56, 0x54, 0x37, 0x2e, 0x2e, 0x2d,
+ 0x2d, 0x2d, 0x36, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
+ 0x3c, 0x3c, 0x3c, 0x37, 0x3c, 0x37, 0x37, 0x36,
+ 0x36, 0x17, 0x16, 0x17, 0x29, 0x29, 0x2d, 0x2d,
+ 0x47, 0xb5, 0xdb, 0xdd, 0xf3, 0xf4, 0xb7, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xbc, 0xfd,
+ 0x4f, 0x2a, 0x2f, 0x38, 0x3f, 0x59, 0x65, 0x63,
+ 0x65, 0x64, 0x64, 0x64, 0x6a, 0x7c, 0x6b, 0x7c,
+ 0x6a, 0x57, 0x54, 0x54, 0x54, 0x54, 0x37, 0x2d,
+ 0x2d, 0x2d, 0x2d, 0x2d, 0x3c, 0x3d, 0x3d, 0x3d,
+ 0x3d, 0x3c, 0x3c, 0x3c, 0x37, 0x37, 0x37, 0x37,
+ 0x36, 0x36, 0x36, 0x17, 0x16, 0x17, 0x29, 0x2a,
+ 0x2d, 0x43, 0xb1, 0xb6, 0xdb, 0xdd, 0xf3, 0xe5,
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x25, 0xfe, 0xc3, 0x2b, 0x2d, 0x38, 0x38, 0x55,
+ 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x64, 0x6a,
+ 0x7c, 0x6b, 0x7d, 0x64, 0x57, 0x54, 0x3d, 0x3d,
+ 0x37, 0x2d, 0x2d, 0x2a, 0x2a, 0x37, 0x3d, 0x3d,
+ 0x3c, 0x3d, 0x3c, 0x3c, 0x3c, 0x37, 0x3c, 0x37,
+ 0x37, 0x37, 0x36, 0x36, 0x36, 0x29, 0x17, 0x29,
+ 0x2a, 0x2d, 0x5c, 0x95, 0xb1, 0xb5, 0xdb, 0xf3,
+ 0xf3, 0xbc, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0xe1, 0xf9, 0x34, 0x29, 0x36,
+ 0x3f, 0x55, 0x5a, 0x62, 0x62, 0x63, 0x63, 0x64,
+ 0x64, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6a, 0x57,
+ 0x3d, 0x3d, 0x37, 0x2a, 0x2a, 0x2a, 0x2d, 0x3c,
+ 0x3d, 0x3d, 0x3c, 0x3c, 0x3c, 0x3c, 0x37, 0x37,
+ 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x17,
+ 0x29, 0x29, 0x2a, 0x39, 0x89, 0x96, 0xad, 0xb1,
+ 0xd8, 0xf3, 0xf4, 0xb7, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0xb8, 0xfe, 0xbe,
+ 0x18, 0x2a, 0x2f, 0x3e, 0x57, 0x5a, 0x5f, 0x62,
+ 0x62, 0x63, 0x63, 0x63, 0x6a, 0x6a, 0x6a, 0x6b,
+ 0x69, 0x6b, 0x59, 0x3d, 0x37, 0x2a, 0x2a, 0x29,
+ 0x2e, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x37,
+ 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x37, 0x37,
+ 0x36, 0x29, 0x29, 0x2d, 0x3a, 0x71, 0x70, 0x93,
+ 0x95, 0xb2, 0xd9, 0xef, 0xe2, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0xf5, 0xf5, 0x32, 0x18, 0x2d, 0x3e, 0x57, 0x57,
+ 0x5a, 0x62, 0x5f, 0x62, 0x63, 0x63, 0x63, 0x68,
+ 0x6a, 0x6a, 0x6a, 0x6b, 0x69, 0x63, 0x38, 0x29,
+ 0x29, 0x29, 0x37, 0x3c, 0x3c, 0x3c, 0x3c, 0x37,
+ 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x37,
+ 0x37, 0x3c, 0x37, 0x29, 0x2f, 0x42, 0x71, 0x73,
+ 0x70, 0x70, 0x8b, 0xce, 0xd9, 0xed, 0xb8, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0xbb, 0xfc, 0xbe, 0x18, 0x29, 0x36,
+ 0x57, 0x57, 0x57, 0x5a, 0x5a, 0x5a, 0x62, 0x63,
+ 0x63, 0x63, 0x63, 0x68, 0x6a, 0x6a, 0x6a, 0x69,
+ 0x68, 0x3a, 0x2a, 0x2a, 0x37, 0x3c, 0x3c, 0x37,
+ 0x37, 0x37, 0x37, 0x37, 0x36, 0x37, 0x36, 0x36,
+ 0x37, 0x37, 0x3c, 0x3c, 0x3e, 0x42, 0x71, 0x8a,
+ 0x8a, 0x89, 0x70, 0x70, 0xa3, 0xda, 0xda, 0xde,
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe1, 0xf9, 0x34,
+ 0x16, 0x2a, 0x55, 0x55, 0x57, 0x57, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x63, 0x63, 0x63, 0x68, 0x68, 0x68,
+ 0x68, 0x69, 0x69, 0x67, 0x42, 0x42, 0x40, 0x3c,
+ 0x37, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x37, 0x37, 0x3e, 0x59, 0x69, 0x6f, 0x89,
+ 0x89, 0x89, 0x8a, 0x70, 0x70, 0x8b, 0xc9, 0xd2,
+ 0xda, 0xb9, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xb9,
+ 0xfe, 0xc4, 0x18, 0x17, 0x36, 0x55, 0x55, 0x55,
+ 0x55, 0x57, 0x5a, 0x5a, 0x63, 0x63, 0x5b, 0x63,
+ 0x68, 0x68, 0x68, 0x68, 0x68, 0x42, 0x42, 0x67,
+ 0x6d, 0x67, 0x67, 0x5c, 0x40, 0x3e, 0x38, 0x38,
+ 0x3c, 0x3f, 0x40, 0x67, 0x69, 0x6f, 0x8f, 0x8e,
+ 0x8f, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89, 0xb0,
+ 0xd1, 0xd4, 0xc6, 0x1f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0xbc, 0xf5, 0x4f, 0x17, 0x29, 0x3c,
+ 0x55, 0x55, 0x55, 0x57, 0x59, 0x59, 0x5a, 0x5a,
+ 0x5b, 0x5b, 0x63, 0x5b, 0x68, 0x68, 0x68, 0x67,
+ 0x42, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6f,
+ 0x6f, 0x6f, 0x6f, 0x6f, 0x8f, 0x8f, 0x8f, 0x8e,
+ 0x8e, 0x8e, 0x8e, 0x88, 0x88, 0x88, 0x88, 0x89,
+ 0xa3, 0xcd, 0xd2, 0xc5, 0x25, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x21, 0xe1, 0xe3, 0x33,
+ 0x29, 0x2a, 0x3e, 0x54, 0x55, 0x55, 0x55, 0x55,
+ 0x59, 0x5a, 0x5c, 0x5a, 0x5b, 0x5b, 0x68, 0x67,
+ 0x68, 0x67, 0x42, 0x67, 0x69, 0x69, 0x6d, 0x6d,
+ 0x6d, 0x6f, 0x6f, 0x81, 0x6f, 0x8d, 0x8f, 0x8f,
+ 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x88,
+ 0x90, 0xa2, 0xcd, 0xd2, 0xd4, 0xb8, 0x0b, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x27,
+ 0xf5, 0xc0, 0x31, 0x29, 0x2d, 0x3e, 0x3d, 0x54,
+ 0x55, 0x55, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5b,
+ 0x67, 0x5b, 0x67, 0x67, 0x42, 0x67, 0x69, 0x69,
+ 0x69, 0x6d, 0x6d, 0x6e, 0x80, 0x6f, 0x81, 0x8f,
+ 0x81, 0x81, 0x8d, 0x91, 0x8e, 0x91, 0x8e, 0x8e,
+ 0x88, 0x88, 0x95, 0xca, 0xce, 0xd2, 0xbd, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0xb9, 0xf5, 0x9e, 0x2f, 0x2a, 0x2d,
+ 0x3e, 0x55, 0x3e, 0x55, 0x55, 0x55, 0x59, 0x5c,
+ 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x67, 0x42, 0x67,
+ 0x69, 0x69, 0x69, 0x69, 0x6d, 0x6e, 0x6e, 0x80,
+ 0x81, 0x81, 0x81, 0x8f, 0x8d, 0x8e, 0x91, 0x8e,
+ 0x8e, 0x8e, 0x8e, 0x95, 0xca, 0xce, 0xcd, 0xc3,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0b, 0xb8, 0xe5, 0x9d,
+ 0x2f, 0x2d, 0x2e, 0x3e, 0x55, 0x55, 0x55, 0x55,
+ 0x59, 0x59, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b,
+ 0x40, 0x67, 0x68, 0x69, 0x69, 0x6b, 0x6e, 0x6e,
+ 0x6e, 0x80, 0x81, 0x81, 0x81, 0x83, 0x8d, 0x8d,
+ 0x8d, 0x8d, 0x91, 0x8e, 0x95, 0xb2, 0xcd, 0xcd,
+ 0xc3, 0x26, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xb8, 0xe3, 0x9d, 0x39, 0x2e, 0x36, 0x37, 0x54,
+ 0x55, 0x57, 0x57, 0x59, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x63, 0x5b, 0x42, 0x67, 0x68, 0x6a, 0x6a, 0x6b,
+ 0x6b, 0x80, 0x6b, 0x80, 0x80, 0x81, 0x83, 0x83,
+ 0x83, 0x83, 0x8d, 0x8d, 0x8e, 0xad, 0xca, 0xce,
+ 0xce, 0xc3, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0b, 0xb7, 0xe3, 0x9d, 0x3a, 0x36,
+ 0x36, 0x38, 0x3d, 0x57, 0x57, 0x57, 0x57, 0x5f,
+ 0x5a, 0x62, 0x63, 0x63, 0x5c, 0x5c, 0x6a, 0x6a,
+ 0x6a, 0x6b, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x82,
+ 0x82, 0x82, 0x83, 0x83, 0x91, 0x94, 0xa8, 0xb2,
+ 0xca, 0xce, 0xc2, 0x21, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0xc5,
+ 0xbf, 0x43, 0x3c, 0x3c, 0x3c, 0x3d, 0x54, 0x57,
+ 0x5f, 0x62, 0x5f, 0x62, 0x62, 0x63, 0x5b, 0x5c,
+ 0x68, 0x6a, 0x6a, 0x7c, 0x6b, 0x7d, 0x7d, 0x7d,
+ 0x80, 0x82, 0x82, 0x83, 0x82, 0x91, 0x94, 0xaa,
+ 0xb1, 0xca, 0xce, 0xba, 0x1f, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x22, 0xbd, 0xc0, 0x97, 0x5d, 0x3e, 0x3e,
+ 0x3d, 0x3d, 0x57, 0x57, 0x61, 0x62, 0x65, 0x63,
+ 0x5b, 0x5c, 0x63, 0x64, 0x64, 0x64, 0x7c, 0x7c,
+ 0x7c, 0x7e, 0x7e, 0x82, 0x82, 0x83, 0x94, 0xa9,
+ 0xaa, 0xb1, 0xb2, 0xc2, 0x4d, 0x0c, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x27, 0xc3, 0xa0,
+ 0x73, 0x5d, 0x58, 0x55, 0x3d, 0x54, 0x57, 0x57,
+ 0x5f, 0x5f, 0x59, 0x59, 0x63, 0x64, 0x7c, 0x78,
+ 0x7c, 0x85, 0x7c, 0x7c, 0x7f, 0x84, 0x94, 0xa7,
+ 0xaa, 0xaa, 0xb1, 0xb3, 0xa5, 0x21, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x1f, 0x4d, 0xbe, 0x9d, 0x74, 0x72, 0x66, 0x5d,
+ 0x5d, 0x58, 0x57, 0x55, 0x55, 0x55, 0x5c, 0x62,
+ 0x65, 0x64, 0x7c, 0x7d, 0x80, 0x8e, 0x94, 0xa9,
+ 0xa9, 0xaa, 0xaa, 0xaa, 0xa6, 0x28, 0x0e, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x1f, 0x4d, 0xa5, 0x9a,
+ 0x9b, 0x74, 0x74, 0x74, 0x72, 0x72, 0x6c, 0x6c,
+ 0x6c, 0x74, 0x89, 0x90, 0x94, 0xa7, 0xa7, 0xa9,
+ 0xa9, 0xa9, 0xaa, 0xab, 0xa6, 0x28, 0x0f, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x0c, 0x21, 0x4d, 0x53, 0x9a, 0x9a, 0x9b, 0x9b,
+ 0x99, 0x99, 0x99, 0xa1, 0xa2, 0xa2, 0xa8, 0xa7,
+ 0xab, 0xab, 0xac, 0xac, 0x4c, 0x1e, 0x0a, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x0a, 0x0d, 0x22,
+ 0x23, 0x4b, 0x4e, 0x50, 0x50, 0x4f, 0x50, 0x50,
+ 0x4c, 0x4c, 0x4a, 0x1e, 0x0f, 0x0a, 0x02, 0x00,
+ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x02, 0x02, 0x05, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
};
+
unsigned int logo_img_size = sizeof(logo_img);
diff --git a/sys/dev/syscons/logo/logo_saver.c b/sys/dev/syscons/logo/logo_saver.c
index c77edfb..16dd333 100644
--- a/sys/dev/syscons/logo/logo_saver.c
+++ b/sys/dev/syscons/logo/logo_saver.c
@@ -171,4 +171,8 @@ static scrn_saver_t logo_module = {
NULL
};
+#ifdef BEASTIE_LOGO
+SAVER_MODULE(beastie_saver, logo_module);
+#else
SAVER_MODULE(logo_saver, logo_module);
+#endif
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c
index fd823ce..dbee6f2 100644
--- a/sys/dev/syscons/scvgarndr.c
+++ b/sys/dev/syscons/scvgarndr.c
@@ -181,9 +181,17 @@ static u_short mouse_or_mask[16] = {
#define vga_drawpxl(pos, color) \
switch (scp->sc->adp->va_info.vi_depth) { \
case 32: \
- case 24: \
writel(pos, vga_palette32[color]); \
break; \
+ case 24: \
+ if (((pos) & 1) == 0) { \
+ writew(pos, vga_palette32[color]); \
+ writeb(pos + 2, vga_palette32[color] >> 16);\
+ } else { \
+ writeb(pos, vga_palette32[color]); \
+ writew(pos + 1, vga_palette32[color] >> 8);\
+ } \
+ break; \
case 16: \
if (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)\
writew(pos, vga_palette15[color]); \
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index 0f55499..5c3dc8e 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -741,7 +741,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
#ifndef SC_NO_PALETTE_LOADING
#ifdef SC_PIXEL_MODE
- if ((adp->va_flags & V_ADP_DAC8) != 0)
+ if (adp->va_info.vi_mem_model == V_INFO_MM_DIRECT)
vidd_load_palette(adp, scp->sc->palette2);
else
#endif
@@ -802,7 +802,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
if (scp == scp->sc->cur_scp) {
set_mode(scp);
#ifndef SC_NO_PALETTE_LOADING
- if ((adp->va_flags & V_ADP_DAC8) != 0)
+ if (adp->va_info.vi_mem_model == V_INFO_MM_DIRECT)
vidd_load_palette(adp, scp->sc->palette2);
else
vidd_load_palette(adp, scp->sc->palette);
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 719935d..9128393 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -2131,7 +2131,7 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
if (set_mode(scp) == 0) {
#ifndef SC_NO_PALETTE_LOADING
#ifdef SC_PIXEL_MODE
- if ((scp->sc->adp->va_flags & V_ADP_DAC8) != 0)
+ if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT)
vidd_load_palette(scp->sc->adp, scp->sc->palette2);
else
#endif
@@ -2540,7 +2540,7 @@ exchange_scr(sc_softc_t *sc)
#ifndef SC_NO_PALETTE_LOADING
if (ISGRAPHSC(sc->old_scp)) {
#ifdef SC_PIXEL_MODE
- if ((sc->adp->va_flags & V_ADP_DAC8) != 0)
+ if (sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT)
vidd_load_palette(sc->adp, sc->palette2);
else
#endif
diff --git a/sys/dev/uart/uart.h b/sys/dev/uart/uart.h
index eb66da0..bd7861d 100644
--- a/sys/dev/uart/uart.h
+++ b/sys/dev/uart/uart.h
@@ -67,6 +67,7 @@ struct uart_class;
extern struct uart_class uart_ns8250_class __attribute__((weak));
extern struct uart_class uart_quicc_class __attribute__((weak));
extern struct uart_class uart_sab82532_class __attribute__((weak));
+extern struct uart_class uart_sbbc_class __attribute__((weak));
extern struct uart_class uart_z8530_class __attribute__((weak));
#ifdef PC98
diff --git a/sys/dev/uart/uart_cpu_sparc64.c b/sys/dev/uart/uart_cpu_sparc64.c
index 0f40cb7..c89b39f 100644
--- a/sys/dev/uart/uart_cpu_sparc64.c
+++ b/sys/dev/uart/uart_cpu_sparc64.c
@@ -133,6 +133,14 @@ uart_cpu_getdev_console(phandle_t options, char *dev, size_t devsz)
return (-1);
if (strcmp(buf, "serial") != 0)
return (-1);
+ /* For a Serengeti console device point to the bootbus controller. */
+ if (OF_getprop(input, "name", buf, sizeof(buf)) > 0 &&
+ !strcmp(buf, "sgcn")) {
+ if ((chosen = OF_finddevice("/chosen")) == -1)
+ return (-1);
+ if (OF_getprop(chosen, "iosram", &input, sizeof(input)) == -1)
+ return (-1);
+ }
return (input);
}
@@ -258,6 +266,9 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
!strcmp(compat, "su16552")) {
class = &uart_ns8250_class;
di->bas.chan = 0;
+ } else if (!strcmp(compat, "sgsbbc")) {
+ class = &uart_sbbc_class;
+ di->bas.chan = 0;
}
if (class == NULL)
return (ENXIO);
diff --git a/sys/dev/ubsec/ubsec.c b/sys/dev/ubsec/ubsec.c
index 5e3cc8b..1ea150d 100644
--- a/sys/dev/ubsec/ubsec.c
+++ b/sys/dev/ubsec/ubsec.c
@@ -1886,8 +1886,8 @@ ubsec_dma_malloc(
BUS_DMA_NOWAIT, &dma->dma_map);
if (r != 0) {
device_printf(sc->sc_dev, "ubsec_dma_malloc: "
- "bus_dmammem_alloc failed; size %zu, error %u\n",
- size, r);
+ "bus_dmammem_alloc failed; size %ju, error %u\n",
+ (intmax_t)size, r);
goto fail_2;
}
diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
index 28ad987..12cfe53 100644
--- a/sys/dev/usb/controller/ehci.c
+++ b/sys/dev/usb/controller/ehci.c
@@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
((ehci_softc_t *)(((uint8_t *)(bus)) - \
((uint8_t *)&(((ehci_softc_t *)0)->sc_bus))))
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ehcidebug = 0;
static int ehcinohighspeed = 0;
static int ehciiaadbug = 0;
@@ -258,7 +258,7 @@ ehci_init(ehci_softc_t *sc)
usb_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0);
usb_callout_init_mtx(&sc->sc_tmo_poll, &sc->sc_bus.bus_mtx, 0);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehciiaadbug)
sc->sc_flags |= EHCI_SCFLG_IAADBUG;
if (ehcilostintrbug)
@@ -486,7 +486,7 @@ ehci_init(ehci_softc_t *sc)
usb_bus_mem_flush_all(&sc->sc_bus, &ehci_iterate_hw_softc);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug) {
ehci_dump_sqh(sc, sc->sc_async_p_last);
}
@@ -685,7 +685,7 @@ ehci_shutdown(ehci_softc_t *sc)
}
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void
ehci_dump_regs(ehci_softc_t *sc)
{
@@ -1229,7 +1229,7 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
xfer->td_transfer_cache = td;
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (status & EHCI_QTD_STATERRS) {
DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x"
"status=%s%s%s%s%s%s%s%s\n",
@@ -1260,7 +1260,7 @@ ehci_non_isoc_done(struct usb_xfer *xfer)
DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
xfer, xfer->endpoint);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 10) {
ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
@@ -1527,7 +1527,7 @@ ehci_interrupt(ehci_softc_t *sc)
DPRINTFN(16, "real interrupt\n");
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 15) {
ehci_dump_regs(sc);
}
@@ -1548,7 +1548,7 @@ ehci_interrupt(ehci_softc_t *sc)
if (status & EHCI_STS_HSE) {
printf("%s: unrecoverable error, "
"controller halted\n", __FUNCTION__);
-#if USB_DEBUG
+#ifdef USB_DEBUG
ehci_dump_regs(sc);
ehci_dump_isoc(sc);
#endif
@@ -1978,7 +1978,7 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
xfer->td_transfer_last = td;
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 8) {
DPRINTF("nexttog=%d; data before transfer:\n",
xfer->endpoint->toggle_next);
@@ -2106,7 +2106,7 @@ ehci_isoc_fs_done(ehci_softc_t *sc, struct usb_xfer *xfer)
if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
pp_last = &sc->sc_isoc_fs_p_last[0];
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("isoc FS-TD\n");
ehci_dump_sitd(sc, td);
@@ -2160,7 +2160,7 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb_xfer *xfer)
if (pp_last >= &sc->sc_isoc_hs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
pp_last = &sc->sc_isoc_hs_p_last[0];
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("isoc HS-TD\n");
ehci_dump_itd(sc, td);
@@ -2224,7 +2224,7 @@ ehci_device_done(struct usb_xfer *xfer, usb_error_t error)
if ((methods == &ehci_device_bulk_methods) ||
(methods == &ehci_device_ctrl_methods)) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 8) {
DPRINTF("nexttog=%d; data after transfer:\n",
xfer->endpoint->toggle_next);
@@ -2509,7 +2509,7 @@ ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
uint8_t sb;
uint8_t error;
-#if USB_DEBUG
+#ifdef USB_DEBUG
uint8_t once = 1;
#endif
@@ -2593,7 +2593,7 @@ ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
/* reuse sitd_portaddr and sitd_back from last transfer */
if (*plen > xfer->max_frame_size) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (once) {
once = 0;
printf("%s: frame length(%d) exceeds %d "
@@ -2683,7 +2683,7 @@ ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
}
usb_pc_cpu_flush(td->page_cache);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("FS-TD %d\n", nframes);
ehci_dump_sitd(sc, td);
@@ -2800,7 +2800,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
uint8_t td_no;
uint8_t page_no;
-#if USB_DEBUG
+#ifdef USB_DEBUG
uint8_t once = 1;
#endif
@@ -2878,7 +2878,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
}
/* range check */
if (*plen > xfer->max_frame_size) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (once) {
once = 0;
printf("%s: frame length(%d) exceeds %d bytes "
@@ -2962,7 +2962,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
td->itd_status[td_no - 1] |= htohc32(sc, EHCI_ITD_IOC);
}
usb_pc_cpu_flush(td->page_cache);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("HS-TD %d\n", nframes);
ehci_dump_itd(sc, td);
@@ -3398,7 +3398,7 @@ ehci_roothub_exec(struct usb_device *udev,
break;
case UHF_PORT_RESET:
DPRINTFN(6, "reset port %d\n", index);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ehcinohighspeed) {
/*
* Connect USB device to companion
diff --git a/sys/dev/usb/controller/ehci.h b/sys/dev/usb/controller/ehci.h
index b6426c4..397e61d 100644
--- a/sys/dev/usb/controller/ehci.h
+++ b/sys/dev/usb/controller/ehci.h
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index c81122b..c8d2d61 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -215,6 +208,8 @@ ehci_pci_match(device_t self)
return "NVIDIA nForce3 250 USB 2.0 controller";
case 0x005b10de:
return "NVIDIA nForce4 USB 2.0 controller";
+ case 0x036d10de:
+ return "NVIDIA nForce MCP55 USB 2.0 controller";
case 0x03f210de:
return "NVIDIA nForce MCP61 USB 2.0 controller";
case 0x0aa610de:
diff --git a/sys/dev/usb/controller/ehcireg.h b/sys/dev/usb/controller/ehcireg.h
index 182d9d6..4da80c0 100644
--- a/sys/dev/usb/controller/ehcireg.h
+++ b/sys/dev/usb/controller/ehcireg.h
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/ohci.h b/sys/dev/usb/controller/ohci.h
index 60574bb..d85c2c9 100644
--- a/sys/dev/usb/controller/ohci.h
+++ b/sys/dev/usb/controller/ohci.h
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c
index 3959471..b37fc33 100644
--- a/sys/dev/usb/controller/ohci_pci.c
+++ b/sys/dev/usb/controller/ohci_pci.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -173,6 +166,8 @@ ohci_pci_match(device_t self)
case 0x00d710de:
return ("nVidia nForce3 USB Controller");
+ case 0x036c10de:
+ return ("nVidia nForce MCP55 USB Controller");
case 0x03f110de:
return ("nVidia nForce MCP61 USB Controller");
case 0x0aa510de:
diff --git a/sys/dev/usb/controller/ohci_s3c24x0.c b/sys/dev/usb/controller/ohci_s3c24x0.c
new file mode 100644
index 0000000..2eb82f0
--- /dev/null
+++ b/sys/dev/usb/controller/ohci_s3c24x0.c
@@ -0,0 +1,219 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ * Copyright (c) 2009 Andrew Turner. 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 ``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 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 <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/linker_set.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ohci.h>
+#include <dev/usb/controller/ohcireg.h>
+
+#include <sys/rman.h>
+
+#include <arm/s3c2xx0/s3c24x0reg.h>
+
+static device_probe_t ohci_s3c24x0_probe;
+static device_attach_t ohci_s3c24x0_attach;
+static device_detach_t ohci_s3c24x0_detach;
+
+static int
+ohci_s3c24x0_probe(device_t dev)
+{
+ device_set_desc(dev, "S3C24x0 integrated OHCI controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ohci_s3c24x0_attach(device_t dev)
+{
+ struct ohci_softc *sc = device_get_softc(dev);
+ int err;
+ int rid;
+
+ /* initialise some bus fields */
+ sc->sc_bus.parent = dev;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
+
+ /* get all DMA memory */
+ if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
+ &ohci_iterate_hw_softc)) {
+ return (ENOMEM);
+ }
+
+ sc->sc_dev = dev;
+
+ rid = 0;
+ sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
+ &rid, RF_ACTIVE);
+
+ if (!(sc->sc_io_res)) {
+ err = ENOMEM;
+ goto error;
+ }
+ sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+ sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+ sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_ACTIVE);
+ if (!(sc->sc_irq_res)) {
+ goto error;
+ }
+ sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+ if (!(sc->sc_bus.bdev)) {
+ goto error;
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+ strlcpy(sc->sc_vendor, "Samsung", sizeof(sc->sc_vendor));
+
+ err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, (void *)ohci_interrupt, sc, &sc->sc_intr_hdl);
+ if (err) {
+ sc->sc_intr_hdl = NULL;
+ goto error;
+ }
+
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl,
+ OHCI_CONTROL, 0);
+
+ err = ohci_init(sc);
+ if (!err) {
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ }
+ if (err) {
+ goto error;
+ }
+ return (0);
+
+error:
+ ohci_s3c24x0_detach(dev);
+ return (ENXIO);
+}
+
+static int
+ohci_s3c24x0_detach(device_t dev)
+{
+ struct ohci_softc *sc = device_get_softc(dev);
+ device_t bdev;
+ int err;
+
+ if (sc->sc_bus.bdev) {
+ bdev = sc->sc_bus.bdev;
+ device_detach(bdev);
+ device_delete_child(dev, bdev);
+ }
+ /* during module unload there are lots of children leftover */
+ device_delete_all_children(dev);
+
+ /*
+ * Put the controller into reset, then disable clocks and do
+ * the MI tear down. We have to disable the clocks/hardware
+ * after we do the rest of the teardown. We also disable the
+ * clocks in the opposite order we acquire them, but that
+ * doesn't seem to be absolutely necessary. We free up the
+ * clocks after we disable them, so the system could, in
+ * theory, reuse them.
+ */
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl,
+ OHCI_CONTROL, 0);
+
+ if (sc->sc_irq_res && sc->sc_intr_hdl) {
+ /*
+ * only call ohci_detach() after ohci_init()
+ */
+ ohci_detach(sc);
+
+ err = bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_hdl);
+ sc->sc_intr_hdl = NULL;
+ }
+ if (sc->sc_irq_res) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+ sc->sc_irq_res = NULL;
+ }
+ if (sc->sc_io_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, 0,
+ sc->sc_io_res);
+ sc->sc_io_res = NULL;
+ }
+ usb_bus_mem_free_all(&sc->sc_bus, &ohci_iterate_hw_softc);
+
+ return (0);
+}
+
+static device_method_t ohci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ohci_s3c24x0_probe),
+ DEVMETHOD(device_attach, ohci_s3c24x0_attach),
+ DEVMETHOD(device_detach, ohci_s3c24x0_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+ {0, 0}
+};
+
+static driver_t ohci_driver = {
+ "ohci",
+ ohci_methods,
+ sizeof(struct ohci_softc),
+};
+
+static devclass_t ohci_devclass;
+
+DRIVER_MODULE(ohci, s3c24x0, ohci_driver, ohci_devclass, 0, 0);
+MODULE_DEPEND(ohci, usb, 1, 1, 1);
diff --git a/sys/dev/usb/controller/ohcireg.h b/sys/dev/usb/controller/ohcireg.h
index 9127a02..7f14875 100644
--- a/sys/dev/usb/controller/ohcireg.h
+++ b/sys/dev/usb/controller/ohcireg.h
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c
index 837a26f..f87907c 100644
--- a/sys/dev/usb/controller/uhci.c
+++ b/sys/dev/usb/controller/uhci.c
@@ -82,7 +82,7 @@ __FBSDID("$FreeBSD$");
((uhci_softc_t *)(((uint8_t *)(bus)) - \
((uint8_t *)&(((uhci_softc_t *)0)->sc_bus))))
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uhcidebug = 0;
static int uhcinoloop = 0;
@@ -459,7 +459,7 @@ uhci_init(uhci_softc_t *sc)
usb_callout_init_mtx(&sc->sc_root_intr, &sc->sc_bus.bus_mtx, 0);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 2) {
uhci_dumpregs(sc);
}
@@ -668,7 +668,7 @@ uhci_suspend(uhci_softc_t *sc)
{
USB_BUS_LOCK(&sc->sc_bus);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 2) {
uhci_dumpregs(sc);
}
@@ -712,7 +712,7 @@ uhci_resume(uhci_softc_t *sc)
uhci_start(sc);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 2) {
uhci_dumpregs(sc);
}
@@ -724,7 +724,7 @@ uhci_resume(uhci_softc_t *sc)
uhci_do_poll(&sc->sc_bus);
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void
uhci_dumpregs(uhci_softc_t *sc)
{
@@ -855,7 +855,7 @@ uhci_add_loop(uhci_softc_t *sc)
struct uhci_qh *qh_lst;
struct uhci_qh *qh_rec;
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcinoloop) {
return;
}
@@ -878,7 +878,7 @@ uhci_rem_loop(uhci_softc_t *sc)
{
struct uhci_qh *qh_lst;
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcinoloop) {
return;
}
@@ -1046,7 +1046,7 @@ uhci_isoc_done(uhci_softc_t *sc, struct usb_xfer *xfer)
if (pp_last >= &sc->sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]) {
pp_last = &sc->sc_isoc_p_last[0];
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 5) {
DPRINTF("isoc TD\n");
uhci_dump_td(td);
@@ -1177,7 +1177,7 @@ uhci_non_isoc_done_sub(struct usb_xfer *xfer)
xfer->endpoint->toggle_next = (token & UHCI_TD_SET_DT(1)) ? 0 : 1;
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (status & UHCI_TD_ERROR) {
DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x "
"status=%s%s%s%s%s%s%s%s%s%s%s\n",
@@ -1207,7 +1207,7 @@ uhci_non_isoc_done(struct usb_xfer *xfer)
DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
xfer, xfer->endpoint);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 10) {
uhci_dump_tds(xfer->td_transfer_first);
}
@@ -1446,7 +1446,7 @@ uhci_interrupt(uhci_softc_t *sc)
DPRINTFN(16, "real interrupt\n");
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 15) {
uhci_dumpregs(sc);
}
@@ -1460,7 +1460,7 @@ uhci_interrupt(uhci_softc_t *sc)
UHCI_STS_HCPE | UHCI_STS_HCH)) {
if (status & UHCI_STS_RD) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
printf("%s: resume detect\n",
__FUNCTION__);
#endif
@@ -1477,7 +1477,7 @@ uhci_interrupt(uhci_softc_t *sc)
/* no acknowledge needed */
DPRINTF("%s: host controller halted\n",
__FUNCTION__);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 0) {
uhci_dump_all(sc);
}
@@ -1839,7 +1839,7 @@ uhci_setup_standard_chain(struct usb_xfer *xfer)
xfer->td_transfer_last = td;
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 8) {
DPRINTF("nexttog=%d; data before transfer:\n",
xfer->endpoint->toggle_next);
@@ -2155,7 +2155,7 @@ uhci_device_isoc_enter(struct usb_xfer *xfer)
uint32_t temp;
uint32_t *plen;
-#if USB_DEBUG
+#ifdef USB_DEBUG
uint8_t once = 1;
#endif
@@ -2227,7 +2227,7 @@ uhci_device_isoc_enter(struct usb_xfer *xfer)
pp_last = &sc->sc_isoc_p_last[0];
}
if (*plen > xfer->max_frame_size) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (once) {
once = 0;
printf("%s: frame length(%d) exceeds %d "
@@ -2279,7 +2279,7 @@ uhci_device_isoc_enter(struct usb_xfer *xfer)
usb_pc_cpu_flush(td->page_cache);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (uhcidebug > 5) {
DPRINTF("TD %d\n", nframes);
uhci_dump_td(td);
diff --git a/sys/dev/usb/controller/uhci.h b/sys/dev/usb/controller/uhci.h
index f526431..0878e79 100644
--- a/sys/dev/usb/controller/uhci.h
+++ b/sys/dev/usb/controller/uhci.h
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 81421e3..82dae53 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/uhcireg.h b/sys/dev/usb/controller/uhcireg.h
index 993b73c..95eae49 100644
--- a/sys/dev/usb/controller/uhcireg.h
+++ b/sys/dev/usb/controller/uhcireg.h
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index eb961fc..e91904c 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -24,6 +24,8 @@
* SUCH DAMAGE.
*/
+#include "opt_ddb.h"
+
#include <sys/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
@@ -220,6 +222,7 @@ usb_bus_explore(struct usb_proc_msg *pm)
bus->driver_added_refcount = 1;
}
+#ifdef DDB
/*
* The following three lines of code are only here to
* recover from DDB:
@@ -227,6 +230,7 @@ usb_bus_explore(struct usb_proc_msg *pm)
usb_proc_rewakeup(&bus->control_xfer_proc);
usb_proc_rewakeup(&bus->giant_callback_proc);
usb_proc_rewakeup(&bus->non_giant_callback_proc);
+#endif
USB_BUS_UNLOCK(bus);
@@ -289,11 +293,13 @@ usb_power_wdog(void *arg)
usb_callout_reset(&bus->power_wdog,
4 * hz, usb_power_wdog, arg);
+#ifdef DDB
/*
* The following line of code is only here to recover from
* DDB:
*/
usb_proc_rewakeup(&bus->explore_proc); /* recover from DDB */
+#endif
USB_BUS_UNLOCK(bus);
diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c
index fe14d51..7422169 100644
--- a/sys/dev/usb/controller/uss820dci.c
+++ b/sys/dev/usb/controller/uss820dci.c
@@ -77,7 +77,7 @@
#define USS820_DCI_PC2SC(pc) \
USS820_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uss820dcidebug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci");
@@ -333,6 +333,14 @@ uss820dci_setup_rx(struct uss820dci_td *td)
} else {
sc->sc_dv_addr = 0xFF;
}
+
+ /* reset TX FIFO */
+ temp = USS820_READ_1(sc, USS820_TXCON);
+ temp |= USS820_TXCON_TXCLR;
+ USS820_WRITE_1(sc, USS820_TXCON, temp);
+ temp &= ~USS820_TXCON_TXCLR;
+ USS820_WRITE_1(sc, USS820_TXCON, temp);
+
return (0); /* complete */
setup_not_complete:
diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c
index 6c0ce2c..c0fe6d4 100644
--- a/sys/dev/usb/input/atp.c
+++ b/sys/dev/usb/input/atp.c
@@ -116,7 +116,7 @@ __FBSDID("$FreeBSD$");
/* Tunables */
SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB atp");
-#if USB_DEBUG
+#ifdef USB_DEBUG
enum atp_log_level {
ATP_LLEVEL_DISABLED = 0,
ATP_LLEVEL_ERROR,
@@ -126,7 +126,7 @@ enum atp_log_level {
static int atp_debug = ATP_LLEVEL_ERROR; /* the default is to only log errors */
SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug, CTLFLAG_RW,
&atp_debug, ATP_LLEVEL_ERROR, "ATP debug level");
-#endif /* #if USB_DEBUG */
+#endif /* USB_DEBUG */
static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT;
SYSCTL_INT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RW, &atp_touch_timeout,
@@ -1055,7 +1055,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
if (pspans_y[j].matched == FALSE) break;
}
if ((i < n_xpspans) && (j < n_ypspans)) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (atp_debug >= ATP_LLEVEL_INFO) {
printf("unmatched pspans:");
for (; i < n_xpspans; i++) {
@@ -1072,7 +1072,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
}
printf("\n");
}
-#endif /* #if USB_DEBUG */
+#endif /* USB_DEBUG */
if ((n_xpspans == 1) && (n_ypspans == 1))
/* The common case of a single pair of new pspans. */
atp_add_stroke(sc, &pspans_x[0], &pspans_y[0]);
@@ -1082,7 +1082,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
pspans_y, n_ypspans);
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (atp_debug >= ATP_LLEVEL_INFO) {
for (i = 0; i < sc->sc_n_strokes; i++) {
atp_stroke *stroke = &sc->sc_strokes[i];
@@ -1110,7 +1110,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
if (sc->sc_n_strokes)
printf("\n");
}
-#endif /* #if USB_DEBUG */
+#endif /* USB_DEBUG */
return (movement);
}
diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c
index be356a5..d36ecf3 100644
--- a/sys/dev/usb/input/uhid.c
+++ b/sys/dev/usb/input/uhid.c
@@ -23,13 +23,6 @@ __FBSDID("$FreeBSD$");
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -83,7 +76,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/input/usb_rdesc.h>
#include <dev/usb/quirk/usb_quirk.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uhid_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid");
diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
index 4e43931..034a781 100644
--- a/sys/dev/usb/input/ukbd.c
+++ b/sys/dev/usb/input/ukbd.c
@@ -18,13 +18,6 @@ __FBSDID("$FreeBSD$");
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -95,7 +88,7 @@ __FBSDID("$FreeBSD$");
/* the following file must be included after "ukbdmap.h" */
#include <dev/kbd/kbdtables.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ukbd_debug = 0;
static int ukbd_no_leds = 0;
@@ -109,8 +102,6 @@ TUNABLE_INT("hw.usb.ukbd.debug", &ukbd_debug);
TUNABLE_INT("hw.usb.ukbd.no_leds", &ukbd_no_leds);
#endif
-#define UPROTO_BOOT_KEYBOARD 1
-
#define UKBD_EMULATE_ATSCANCODE 1
#define UKBD_DRIVER_NAME "ukbd"
#define UKBD_NMOD 8 /* units */
@@ -621,7 +612,7 @@ ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t error)
apple_fn = 1;
else
apple_fn = 0;
-#if USB_DEBUG
+#ifdef USB_DEBUG
DPRINTF("apple_eject=%u apple_fn=%u\n",
apple_eject, apple_fn);
@@ -687,7 +678,7 @@ ukbd_set_leds_callback(struct usb_xfer *xfer, usb_error_t error)
uint8_t buf[2];
struct ukbd_softc *sc = usbd_xfer_softc(xfer);
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (ukbd_no_leds)
return;
#endif
@@ -777,7 +768,7 @@ ukbd_probe(device_t dev)
return (ENXIO);
if ((uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT) &&
- (uaa->info.bInterfaceProtocol == UPROTO_BOOT_KEYBOARD)) {
+ (uaa->info.bInterfaceProtocol == UIPROTO_BOOT_KEYBOARD)) {
if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
return (ENXIO);
else
@@ -883,28 +874,32 @@ ukbd_attach(device_t dev)
err = usbd_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
&hid_len, M_TEMP, uaa->info.bIfaceIndex);
if (err == 0) {
+ uint8_t apple_keys = 0;
uint8_t temp_id;
/* investigate if this is an Apple Keyboard */
if (hid_locate(hid_ptr, hid_len,
HID_USAGE2(HUP_CONSUMER, HUG_APPLE_EJECT),
hid_input, 0, &sc->sc_loc_apple_eject, &flags,
- &sc->sc_kbd_id)) {
+ &temp_id)) {
if (flags & HIO_VARIABLE)
sc->sc_flags |= UKBD_FLAG_APPLE_EJECT |
UKBD_FLAG_APPLE_SWAP;
- if (hid_locate(hid_ptr, hid_len,
- HID_USAGE2(0xFFFF, 0x0003),
- hid_input, 0, &sc->sc_loc_apple_fn, &flags,
- &temp_id)) {
- if (flags & HIO_VARIABLE)
- sc->sc_flags |= UKBD_FLAG_APPLE_FN |
- UKBD_FLAG_APPLE_SWAP;
- if (temp_id != sc->sc_kbd_id) {
- DPRINTF("HID IDs mismatch\n");
- }
- }
- } else {
+ DPRINTFN(1, "Found Apple eject-key\n");
+ apple_keys = 1;
+ sc->sc_kbd_id = temp_id;
+ }
+ if (hid_locate(hid_ptr, hid_len,
+ HID_USAGE2(0xFFFF, 0x0003),
+ hid_input, 0, &sc->sc_loc_apple_fn, &flags,
+ &temp_id)) {
+ if (flags & HIO_VARIABLE)
+ sc->sc_flags |= UKBD_FLAG_APPLE_FN;
+ DPRINTFN(1, "Found Apple FN-key\n");
+ apple_keys = 1;
+ sc->sc_kbd_id = temp_id;
+ }
+ if (apple_keys == 0) {
/*
* Assume the first HID ID contains the
* keyboard data
diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
index e29f4eb..e1e37be 100644
--- a/sys/dev/usb/input/ums.c
+++ b/sys/dev/usb/input/ums.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -81,7 +74,7 @@ __FBSDID("$FreeBSD$");
#include <sys/tty.h>
#include <sys/mouse.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ums_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums");
@@ -501,7 +494,9 @@ ums_attach(device_t dev)
int err;
uint16_t d_len;
uint8_t i;
+#ifdef USB_DEBUG
uint8_t j;
+#endif
DPRINTFN(11, "sc=%p\n", sc);
@@ -595,7 +590,7 @@ ums_attach(device_t dev)
free(d_ptr, M_TEMP);
d_ptr = NULL;
-#if USB_DEBUG
+#ifdef USB_DEBUG
for (j = 0; j < UMS_INFO_MAX; j++) {
info = &sc->sc_info[j];
diff --git a/sys/dev/usb/misc/udbp.c b/sys/dev/usb/misc/udbp.c
index ada6b3c..5eef310 100644
--- a/sys/dev/usb/misc/udbp.c
+++ b/sys/dev/usb/misc/udbp.c
@@ -94,7 +94,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/misc/udbp.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int udbp_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c
index b508474..a8c0a54 100644
--- a/sys/dev/usb/net/if_aue.c
+++ b/sys/dev/usb/net/if_aue.c
@@ -100,7 +100,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/net/usb_ethernet.h>
#include <dev/usb/net/if_auereg.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int aue_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, aue, CTLFLAG_RW, 0, "USB aue");
diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index 9772f40..e255c85 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -123,7 +123,7 @@ __FBSDID("$FreeBSD$");
*/
#define AXE_178_MAX_FRAME_BURST 1
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int axe_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe");
diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c
index 2fcb0ff..b5e7fd4 100644
--- a/sys/dev/usb/net/if_cdce.c
+++ b/sys/dev/usb/net/if_cdce.c
@@ -108,7 +108,7 @@ static uether_fn_t cdce_setpromisc;
static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t);
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int cdce_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet");
diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c
index 05ff1a5..e26b29f 100644
--- a/sys/dev/usb/net/if_cue.c
+++ b/sys/dev/usb/net/if_cue.c
@@ -122,7 +122,7 @@ static int cue_getmac(struct cue_softc *, void *);
static uint32_t cue_mchash(const uint8_t *);
static void cue_reset(struct cue_softc *);
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int cue_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue");
diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c
index 5d35da4..4eee094 100644
--- a/sys/dev/usb/net/if_kue.c
+++ b/sys/dev/usb/net/if_kue.c
@@ -163,7 +163,7 @@ static int kue_ctl(struct kue_softc *, uint8_t, uint8_t, uint16_t,
static int kue_load_fw(struct kue_softc *);
static void kue_reset(struct kue_softc *);
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int kue_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, kue, CTLFLAG_RW, 0, "USB kue");
diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c
index 3e77305..f0d1608 100644
--- a/sys/dev/usb/net/if_rue.c
+++ b/sys/dev/usb/net/if_rue.c
@@ -97,7 +97,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/net/usb_ethernet.h>
#include <dev/usb/net/if_ruereg.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int rue_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue");
diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c
index ae30b14..f56e9b0 100644
--- a/sys/dev/usb/net/if_udav.c
+++ b/sys/dev/usb/net/if_udav.c
@@ -185,7 +185,7 @@ static const struct usb_ether_methods udav_ue_methods = {
.ue_mii_sts = udav_ifmedia_status,
};
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int udav_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, udav, CTLFLAG_RW, 0, "USB udav");
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index aa89fdc..b829ac1 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -227,6 +227,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI,
UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */
+ USB_QUIRK(JMICRON, JM20336, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI,
UQ_MSC_NO_SYNC_CACHE),
@@ -317,6 +318,8 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(PNY, ATTACHE2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE,
UQ_MSC_NO_START_STOP),
+ USB_QUIRK(PROLIFIC, PL2506, 0x0000, 0xffff,
+ UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK_VP(USB_VENDOR_SAMSUNG_TECHWIN,
USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
@@ -442,6 +445,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(ACTIONS, MP4, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(ASUS, GMSC, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+ USB_QUIRK(UNKNOWN4, USBMEMSTICK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
};
#undef USB_QUIRK_VP
#undef USB_QUIRK
diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 0d218d5..ffe8812 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -63,7 +63,7 @@
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int u3g_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, u3g, CTLFLAG_RW, 0, "USB 3g");
@@ -501,6 +501,7 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(OPTION, GTICON322, U3GINIT_REZERO),
U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GINIT_ZTESTOR),
U3G_DEV(QUALCOMMINC, ZTE_STOR2, U3GINIT_SCSIEJECT),
+ U3G_DEV(QUANTA, Q101_STOR, U3GINIT_SCSIEJECT),
U3G_DEV(SIERRA, TRUINSTALL, U3GINIT_SIERRA),
#undef U3G_DEV
};
diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c
index 32639fc..5817509 100644
--- a/sys/dev/usb/serial/ubsa.c
+++ b/sys/dev/usb/serial/ubsa.c
@@ -93,7 +93,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ubsa_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa");
@@ -405,9 +405,8 @@ ubsa_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
static int
ubsa_pre_param(struct ucom_softc *ucom, struct termios *t)
{
- struct ubsa_softc *sc = ucom->sc_parent;
- DPRINTF("sc = %p\n", sc);
+ DPRINTF("sc = %p\n", ucom->sc_parent);
switch (t->c_ospeed) {
case B0:
diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c
index 06c96c0..3f2dc2d 100644
--- a/sys/dev/usb/serial/ubser.c
+++ b/sys/dev/usb/serial/ubser.c
@@ -115,7 +115,7 @@ __FBSDID("$FreeBSD$");
#define VENDOR_SET_BREAK 0x02
#define VENDOR_CLEAR_BREAK 0x03
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ubser_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c
index 9fea849..92f3a92 100644
--- a/sys/dev/usb/serial/uchcom.c
+++ b/sys/dev/usb/serial/uchcom.c
@@ -101,7 +101,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uchcom_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uchcom, CTLFLAG_RW, 0, "USB uchcom");
diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 3518a41..b9d1d34 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -80,7 +73,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
#include <dev/usb/serial/uftdi_reg.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uftdi_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi");
@@ -91,8 +84,6 @@ SYSCTL_INT(_hw_usb_uftdi, OID_AUTO, debug, CTLFLAG_RW,
#define UFTDI_CONFIG_INDEX 0
#define UFTDI_IFACE_INDEX 0
-#define UFTDI_IBUFSIZE 64 /* bytes, maximum number of bytes per
- * frame */
#define UFTDI_OBUFSIZE 64 /* bytes, cannot be increased due to
* do size encoding */
@@ -173,7 +164,7 @@ static const struct usb_config uftdi_config[UFTDI_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
- .bufsize = UFTDI_IBUFSIZE,
+ .bufsize = 0, /* use wMaxPacketSize */
.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
.callback = &uftdi_read_callback,
},
diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c
index 99656dd..e806607 100644
--- a/sys/dev/usb/serial/ugensa.c
+++ b/sys/dev/usb/serial/ugensa.c
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c
index 0efcaaf..2f80be8 100644
--- a/sys/dev/usb/serial/uipaq.c
+++ b/sys/dev/usb/serial/uipaq.c
@@ -17,13 +17,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/serial/ulpt.c b/sys/dev/usb/serial/ulpt.c
index 786452f..58dc367 100644
--- a/sys/dev/usb/serial/ulpt.c
+++ b/sys/dev/usb/serial/ulpt.c
@@ -19,13 +19,6 @@ __FBSDID("$FreeBSD$");
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -79,7 +72,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_debug.h>
#include <dev/usb/usb_process.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ulpt_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt");
diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
index 39afdad..a7d00c9 100644
--- a/sys/dev/usb/serial/umodem.c
+++ b/sys/dev/usb/serial/umodem.c
@@ -116,7 +116,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int umodem_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem");
diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c
index 0481b19..3a36a44 100644
--- a/sys/dev/usb/serial/umoscom.c
+++ b/sys/dev/usb/serial/umoscom.c
@@ -48,7 +48,7 @@
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int umoscom_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, umoscom, CTLFLAG_RW, 0, "USB umoscom");
diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c
index c5d58e4..ae88805 100644
--- a/sys/dev/usb/serial/uplcom.c
+++ b/sys/dev/usb/serial/uplcom.c
@@ -116,7 +116,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uplcom_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
index 871ae54..6573d8e 100644
--- a/sys/dev/usb/serial/usb_serial.c
+++ b/sys/dev/usb/serial/usb_serial.c
@@ -104,7 +104,7 @@ __FBSDID("$FreeBSD$");
SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ucom_debug = 0;
SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW,
diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c
index d97cc2c..f20c12a 100644
--- a/sys/dev/usb/serial/uslcom.c
+++ b/sys/dev/usb/serial/uslcom.c
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uslcom_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uslcom, CTLFLAG_RW, 0, "USB uslcom");
diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
index 9e6daa9..77ff31f 100644
--- a/sys/dev/usb/serial/uvisor.c
+++ b/sys/dev/usb/serial/uvisor.c
@@ -29,13 +29,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -85,7 +78,7 @@
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uvisor_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor");
@@ -263,6 +256,7 @@ MODULE_DEPEND(uvisor, usb, 1, 1, 1);
static const struct usb_device_id uvisor_devs[] = {
#define UVISOR_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
UVISOR_DEV(ACEECA, MEZ1000, UVISOR_FLAG_PALM4),
+ UVISOR_DEV(ALPHASMART, DANA_SYNC, UVISOR_FLAG_PALM4),
UVISOR_DEV(GARMIN, IQUE_3600, UVISOR_FLAG_PALM4),
UVISOR_DEV(FOSSIL, WRISTPDA, UVISOR_FLAG_PALM4),
UVISOR_DEV(HANDSPRING, VISOR, UVISOR_FLAG_VISOR),
@@ -345,11 +339,6 @@ uvisor_attach(device_t dev)
DPRINTF("could not allocate all pipes\n");
goto detach;
}
- /* clear stall at first run */
- mtx_lock(&sc->sc_mtx);
- usbd_xfer_set_stall(sc->sc_xfer[UVISOR_BULK_DT_WR]);
- usbd_xfer_set_stall(sc->sc_xfer[UVISOR_BULK_DT_RD]);
- mtx_unlock(&sc->sc_mtx);
error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
&uvisor_callback, &sc->sc_mtx);
@@ -403,7 +392,7 @@ uvisor_init(struct uvisor_softc *sc, struct usb_device *udev, struct usb_config
goto done;
}
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (sc->sc_flag & UVISOR_FLAG_VISOR) {
uint16_t i, np;
const char *desc;
diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c
index 4e3ff57..f220587 100644
--- a/sys/dev/usb/serial/uvscom.c
+++ b/sys/dev/usb/serial/uvscom.c
@@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/serial/usb_serial.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int uvscom_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom");
diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index b14bb47..a66357b 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -146,7 +146,7 @@ __FBSDID("$FreeBSD$");
#define UMASS_USB_FLAGS
#endif
-#if USB_DEBUG
+#ifdef USB_DEBUG
#define DIF(m, x) \
do { \
if (umass_debug & (m)) { x ; } \
@@ -488,7 +488,7 @@ static uint8_t umass_no_transform(struct umass_softc *, uint8_t *, uint8_t);
static uint8_t umass_std_transform(struct umass_softc *, union ccb *, uint8_t
*, uint8_t);
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void umass_bbb_dump_cbw(struct umass_softc *, umass_bbb_cbw_t *);
static void umass_bbb_dump_csw(struct umass_softc *, umass_bbb_csw_t *);
static void umass_cbi_dump_cmd(struct umass_softc *, void *, uint8_t);
@@ -917,7 +917,7 @@ umass_attach(device_t dev)
}
sc->sc_iface_no = id->bInterfaceNumber;
-#if USB_DEBUG
+#ifdef USB_DEBUG
device_printf(dev, " ");
switch (sc->sc_proto & UMASS_PROTO_COMMAND) {
@@ -3012,7 +3012,7 @@ umass_std_transform(struct umass_softc *sc, union ccb *ccb,
return (1);
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
static void
umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
{
diff --git a/sys/dev/usb/storage/urio.c b/sys/dev/usb/storage/urio.c
index 403c4c2..1aef846 100644
--- a/sys/dev/usb/storage/urio.c
+++ b/sys/dev/usb/storage/urio.c
@@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/storage/rio500_usb.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int urio_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio");
diff --git a/sys/dev/usb/storage/ustorage_fs.c b/sys/dev/usb/storage/ustorage_fs.c
index 10047e1..52cfd6e 100644
--- a/sys/dev/usb/storage/ustorage_fs.c
+++ b/sys/dev/usb/storage/ustorage_fs.c
@@ -64,7 +64,7 @@
#define USB_DEBUG_VAR ustorage_fs_debug
#include <dev/usb/usb_debug.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ustorage_fs_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs");
diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c
index d3271b2..80ea15f 100644
--- a/sys/dev/usb/template/usb_template.c
+++ b/sys/dev/usb/template/usb_template.c
@@ -98,13 +98,10 @@ static void *usb_temp_get_config_desc(struct usb_device *, uint16_t *,
static const void *usb_temp_get_string_desc(struct usb_device *, uint16_t,
uint8_t);
static const void *usb_temp_get_vendor_desc(struct usb_device *,
- const struct usb_device_request *);
+ const struct usb_device_request *, uint16_t *plen);
static const void *usb_temp_get_hub_desc(struct usb_device *);
static usb_error_t usb_temp_get_desc(struct usb_device *,
struct usb_device_request *, const void **, uint16_t *);
-static usb_error_t usb_temp_setup(struct usb_device *,
- const struct usb_temp_device_desc *);
-static void usb_temp_unsetup(struct usb_device *);
static usb_error_t usb_temp_setup_by_index(struct usb_device *,
uint16_t index);
static void usb_temp_init(void *);
@@ -165,15 +162,23 @@ usb_make_endpoint_desc(struct usb_temp_setup *temp,
const void **rd;
uint16_t old_size;
uint16_t mps;
- uint8_t ea = 0; /* Endpoint Address */
- uint8_t et = 0; /* Endpiont Type */
+ uint8_t ea; /* Endpoint Address */
+ uint8_t et; /* Endpiont Type */
/* Reserve memory */
old_size = temp->size;
- temp->size += sizeof(*ed);
- /* Scan all Raw Descriptors first */
+ ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
+ et = (ted->bmAttributes & UE_XFERTYPE);
+
+ if (et == UE_ISOCHRONOUS) {
+ /* account for extra byte fields */
+ temp->size += sizeof(*ed) + 2;
+ } else {
+ temp->size += sizeof(*ed);
+ }
+ /* Scan all Raw Descriptors first */
rd = ted->ppRawDesc;
if (rd) {
while (*rd) {
@@ -195,8 +200,6 @@ usb_make_endpoint_desc(struct usb_temp_setup *temp,
/* escape for Zero Max Packet Size */
mps = 0;
}
- ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
- et = (ted->bmAttributes & UE_XFERTYPE);
/*
* Fill out the real USB endpoint descriptor
@@ -204,7 +207,10 @@ usb_make_endpoint_desc(struct usb_temp_setup *temp,
*/
if (temp->buf) {
ed = USB_ADD_BYTES(temp->buf, old_size);
- ed->bLength = sizeof(*ed);
+ if (et == UE_ISOCHRONOUS)
+ ed->bLength = sizeof(*ed) + 2;
+ else
+ ed->bLength = sizeof(*ed);
ed->bDescriptorType = UDESC_ENDPOINT;
ed->bEndpointAddress = ea;
ed->bmAttributes = ted->bmAttributes;
@@ -1035,7 +1041,7 @@ usb_temp_get_config_desc(struct usb_device *udev,
*------------------------------------------------------------------------*/
static const void *
usb_temp_get_vendor_desc(struct usb_device *udev,
- const struct usb_device_request *req)
+ const struct usb_device_request *req, uint16_t *plen)
{
const struct usb_temp_device_desc *tdd;
@@ -1046,7 +1052,7 @@ usb_temp_get_vendor_desc(struct usb_device *udev,
if (tdd->getVendorDesc == NULL) {
return (NULL);
}
- return ((tdd->getVendorDesc) (req));
+ return ((tdd->getVendorDesc) (req, plen));
}
/*------------------------------------------------------------------------*
@@ -1109,7 +1115,6 @@ usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req,
default:
goto tr_stalled;
}
- break;
case UT_READ_CLASS_DEVICE:
switch (req->bRequest) {
case UR_GET_DESCRIPTOR:
@@ -1117,11 +1122,6 @@ usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req,
default:
goto tr_stalled;
}
- break;
- case UT_READ_VENDOR_DEVICE:
- case UT_READ_VENDOR_OTHER:
- buf = usb_temp_get_vendor_desc(udev, req);
- goto tr_valid;
default:
goto tr_stalled;
}
@@ -1158,7 +1158,6 @@ tr_handle_get_descriptor:
default:
goto tr_stalled;
}
- goto tr_stalled;
tr_handle_get_class_descriptor:
if (req->wValue[0]) {
@@ -1168,17 +1167,20 @@ tr_handle_get_class_descriptor:
goto tr_valid;
tr_valid:
- if (buf == NULL) {
+ if (buf == NULL)
goto tr_stalled;
- }
- if (len == 0) {
+ if (len == 0)
len = buf[0];
- }
*pPtr = buf;
*pLength = len;
return (0); /* success */
tr_stalled:
+ /* try to get a vendor specific descriptor */
+ len = 0;
+ buf = usb_temp_get_vendor_desc(udev, req, &len);
+ if (buf != NULL)
+ goto tr_valid;
*pPtr = NULL;
*pLength = 0;
return (0); /* we ignore failures */
@@ -1195,7 +1197,7 @@ tr_stalled:
* 0: Success
* Else: Failure
*------------------------------------------------------------------------*/
-static usb_error_t
+usb_error_t
usb_temp_setup(struct usb_device *udev,
const struct usb_temp_device_desc *tdd)
{
@@ -1285,7 +1287,7 @@ error:
* This function frees any memory associated with the currently
* setup template, if any.
*------------------------------------------------------------------------*/
-static void
+void
usb_temp_unsetup(struct usb_device *udev)
{
if (udev->usb_template_ptr) {
diff --git a/sys/dev/usb/template/usb_template.h b/sys/dev/usb/template/usb_template.h
index cc9ca0c..2473af3 100644
--- a/sys/dev/usb/template/usb_template.h
+++ b/sys/dev/usb/template/usb_template.h
@@ -31,7 +31,7 @@
#define _USB_TEMPLATE_H_
typedef const void *(usb_temp_get_string_desc_t)(uint16_t lang_id, uint8_t string_index);
-typedef const void *(usb_temp_get_vendor_desc_t)(const struct usb_device_request *req);
+typedef const void *(usb_temp_get_vendor_desc_t)(const struct usb_device_request *req, uint16_t *plen);
struct usb_temp_packet_size {
uint16_t mps[USB_SPEED_MAX];
@@ -98,5 +98,8 @@ extern const struct usb_temp_device_desc usb_template_cdce;
extern const struct usb_temp_device_desc usb_template_msc; /* Mass Storage Class */
extern const struct usb_temp_device_desc usb_template_mtp; /* Message Transfer
* Protocol */
+usb_error_t usb_temp_setup(struct usb_device *,
+ const struct usb_temp_device_desc *);
+void usb_temp_unsetup(struct usb_device *);
#endif /* _USB_TEMPLATE_H_ */
diff --git a/sys/dev/usb/template/usb_template_mtp.c b/sys/dev/usb/template/usb_template_mtp.c
index a98a242..40da823 100644
--- a/sys/dev/usb/template/usb_template_mtp.c
+++ b/sys/dev/usb/template/usb_template_mtp.c
@@ -211,7 +211,7 @@ const struct usb_temp_device_desc usb_template_mtp = {
* Else: Success. Pointer to vendor descriptor is returned.
*------------------------------------------------------------------------*/
static const void *
-mtp_get_vendor_desc(const struct usb_device_request *req)
+mtp_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
{
static const uint8_t dummy_desc[0x28] = {
0x28, 0, 0, 0, 0, 1, 4, 0,
diff --git a/sys/dev/usb/usb_cdc.h b/sys/dev/usb/usb_cdc.h
index 7032bf4..c5a13f6 100644
--- a/sys/dev/usb/usb_cdc.h
+++ b/sys/dev/usb/usb_cdc.h
@@ -17,13 +17,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c
index b95a4f6..89aaa8f 100644
--- a/sys/dev/usb/usb_compat_linux.c
+++ b/sys/dev/usb/usb_compat_linux.c
@@ -435,7 +435,7 @@ usb_submit_urb(struct urb *urb, uint16_t mem_flags)
uhe->bsd_xfer[1]) {
/* we are ready! */
- TAILQ_INSERT_HEAD(&uhe->bsd_urb_list, urb, bsd_urb_list);
+ TAILQ_INSERT_TAIL(&uhe->bsd_urb_list, urb, bsd_urb_list);
urb->status = -EINPROGRESS;
@@ -908,6 +908,7 @@ usb_linux_create_usb_device(struct usb_device *udev, device_t dev)
if (p_uhe) {
bcopy(ed, &p_uhe->desc, sizeof(p_uhe->desc));
p_uhe->bsd_iface_index = iface_index - 1;
+ TAILQ_INIT(&p_uhe->bsd_urb_list);
p_uhe++;
}
if (p_uhi) {
@@ -970,7 +971,7 @@ usb_linux_create_usb_device(struct usb_device *udev, device_t dev)
udev->devnum = device_get_unit(dev);
bcopy(&udev->ddesc, &udev->descriptor,
sizeof(udev->descriptor));
- bcopy(udev->default_ep.edesc, &udev->ep0.desc,
+ bcopy(udev->ctrl_ep.edesc, &udev->ep0.desc,
sizeof(udev->ep0.desc));
}
}
diff --git a/sys/dev/usb/usb_debug.h b/sys/dev/usb/usb_debug.h
index b6bfbcf..8718c89 100644
--- a/sys/dev/usb/usb_debug.h
+++ b/sys/dev/usb/usb_debug.h
@@ -34,7 +34,7 @@ extern int usb_debug;
/* Check if USB debugging is enabled. */
#ifdef USB_DEBUG_VAR
-#if (USB_DEBUG != 0)
+#ifdef USB_DEBUG
#define DPRINTFN(n,fmt,...) do { \
if ((USB_DEBUG_VAR) >= (n)) { \
printf("%s: " fmt, \
diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c
index dffabad..2ac5b2e 100644
--- a/sys/dev/usb/usb_dev.c
+++ b/sys/dev/usb/usb_dev.c
@@ -284,7 +284,7 @@ error:
usbd_enum_unlock(cpd->udev);
if (--(cpd->udev->refcount) == 0) {
- cv_signal(cpd->udev->default_cv + 1);
+ cv_signal(&cpd->udev->ref_cv);
}
}
mtx_unlock(&usb_ref_lock);
@@ -352,7 +352,7 @@ usb_unref_device(struct usb_cdev_privdata *cpd,
}
if (crd->is_uref) {
if (--(cpd->udev->refcount) == 0) {
- cv_signal(cpd->udev->default_cv + 1);
+ cv_signal(&cpd->udev->ref_cv);
}
crd->is_uref = 0;
}
@@ -500,7 +500,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
/* update some fields */
f->fifo_index = n + USB_FIFO_TX;
f->dev_ep_index = e;
- f->priv_mtx = udev->default_mtx;
+ f->priv_mtx = &udev->device_mtx;
f->priv_sc0 = ep;
f->methods = &usb_ugen_methods;
f->iface_index = ep->iface_index;
@@ -527,7 +527,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
/* update some fields */
f->fifo_index = n + USB_FIFO_RX;
f->dev_ep_index = e;
- f->priv_mtx = udev->default_mtx;
+ f->priv_mtx = &udev->device_mtx;
f->priv_sc0 = ep;
f->methods = &usb_ugen_methods;
f->iface_index = ep->iface_index;
@@ -615,7 +615,7 @@ usb_dev_get_ep(struct usb_device *udev, uint8_t ep_index, uint8_t dir)
uint8_t ep_dir;
if (ep_index == 0) {
- ep = &udev->default_ep;
+ ep = &udev->ctrl_ep;
} else {
if (dir == USB_FIFO_RX) {
if (udev->flags.usb_mode == USB_MODE_HOST) {
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 5aef59d..95020de 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -45,6 +45,7 @@
#include <sys/priv.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
+#include <sys/sbuf.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -80,7 +81,6 @@
static void usb_init_endpoint(struct usb_device *, uint8_t,
struct usb_endpoint_descriptor *, struct usb_endpoint *);
static void usb_unconfigure(struct usb_device *, uint8_t);
-static void usb_detach_device(struct usb_device *, uint8_t, uint8_t);
static void usb_detach_device_sub(struct usb_device *, device_t *,
uint8_t);
static uint8_t usb_probe_and_attach_sub(struct usb_device *,
@@ -179,9 +179,9 @@ usbd_get_ep_by_addr(struct usb_device *udev, uint8_t ea_val)
/*
* The default endpoint is always present and is checked separately:
*/
- if ((udev->default_ep.edesc) &&
- ((udev->default_ep.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
- ep = &udev->default_ep;
+ if ((udev->ctrl_ep.edesc) &&
+ ((udev->ctrl_ep.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
+ ep = &udev->ctrl_ep;
goto found;
}
return (NULL);
@@ -297,11 +297,11 @@ usbd_get_endpoint(struct usb_device *udev, uint8_t iface_index,
* address" and "any direction" returns the first endpoint of the
* interface. "iface_index" and "direction" is ignored:
*/
- if ((udev->default_ep.edesc) &&
- ((udev->default_ep.edesc->bEndpointAddress & ea_mask) == ea_val) &&
- ((udev->default_ep.edesc->bmAttributes & type_mask) == type_val) &&
+ if ((udev->ctrl_ep.edesc) &&
+ ((udev->ctrl_ep.edesc->bEndpointAddress & ea_mask) == ea_val) &&
+ ((udev->ctrl_ep.edesc->bmAttributes & type_mask) == type_val) &&
(!index)) {
- ep = &udev->default_ep;
+ ep = &udev->ctrl_ep;
goto found;
}
return (NULL);
@@ -655,7 +655,7 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
goto cleanup;
if (cmd == USB_CFG_INIT) {
- sx_assert(udev->default_sx + 1, SA_LOCKED);
+ sx_assert(&udev->enum_sx, SA_LOCKED);
/* check for in-use endpoints */
@@ -1062,7 +1062,7 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index,
}
DPRINTFN(4, "udev=%p\n", udev);
- sx_assert(udev->default_sx + 1, SA_LOCKED);
+ sx_assert(&udev->enum_sx, SA_LOCKED);
/*
* First detach the child to give the child's detach routine a
@@ -1380,7 +1380,7 @@ usb_suspend_resume(struct usb_device *udev, uint8_t do_suspend)
}
DPRINTFN(4, "udev=%p do_suspend=%d\n", udev, do_suspend);
- sx_assert(udev->default_sx + 1, SA_LOCKED);
+ sx_assert(&udev->enum_sx, SA_LOCKED);
USB_BUS_LOCK(udev->bus);
/* filter the suspend events */
@@ -1419,13 +1419,13 @@ usbd_clear_stall_proc(struct usb_proc_msg *_pm)
/* Change lock */
USB_BUS_UNLOCK(udev->bus);
- mtx_lock(udev->default_mtx);
+ mtx_lock(&udev->device_mtx);
/* Start clear stall callback */
- usbd_transfer_start(udev->default_xfer[1]);
+ usbd_transfer_start(udev->ctrl_xfer[1]);
/* Change lock */
- mtx_unlock(udev->default_mtx);
+ mtx_unlock(&udev->device_mtx);
USB_BUS_LOCK(udev->bus);
}
@@ -1491,16 +1491,16 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
return (NULL);
}
/* initialise our SX-lock */
- sx_init(udev->default_sx, "0123456789ABCDEF - USB device SX lock" + depth);
+ sx_init_flags(&udev->ctrl_sx, "USB device SX lock", SX_DUPOK);
/* initialise our SX-lock */
- sx_init(udev->default_sx + 1, "0123456789ABCDEF - USB config SX lock" + depth);
+ sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
- cv_init(udev->default_cv, "WCTRL");
- cv_init(udev->default_cv + 1, "UGONE");
+ cv_init(&udev->ctrlreq_cv, "WCTRL");
+ cv_init(&udev->ref_cv, "UGONE");
/* initialise our mutex */
- mtx_init(udev->default_mtx, "USB device mutex", NULL, MTX_DEF);
+ mtx_init(&udev->device_mtx, "USB device mutex", NULL, MTX_DEF);
/* initialise generic clear stall */
udev->cs_msg[0].hdr.pm_callback = &usbd_clear_stall_proc;
@@ -1529,13 +1529,13 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
udev->refcount = 1;
/* set up default endpoint descriptor */
- udev->default_ep_desc.bLength = sizeof(udev->default_ep_desc);
- udev->default_ep_desc.bDescriptorType = UDESC_ENDPOINT;
- udev->default_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
- udev->default_ep_desc.bmAttributes = UE_CONTROL;
- udev->default_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
- udev->default_ep_desc.wMaxPacketSize[1] = 0;
- udev->default_ep_desc.bInterval = 0;
+ udev->ctrl_ep_desc.bLength = sizeof(udev->ctrl_ep_desc);
+ udev->ctrl_ep_desc.bDescriptorType = UDESC_ENDPOINT;
+ udev->ctrl_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
+ udev->ctrl_ep_desc.bmAttributes = UE_CONTROL;
+ udev->ctrl_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
+ udev->ctrl_ep_desc.wMaxPacketSize[1] = 0;
+ udev->ctrl_ep_desc.bInterval = 0;
udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET;
udev->speed = speed;
@@ -1559,8 +1559,8 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
/* init the default endpoint */
usb_init_endpoint(udev, 0,
- &udev->default_ep_desc,
- &udev->default_ep);
+ &udev->ctrl_ep_desc,
+ &udev->ctrl_ep);
/* set device index */
udev->device_index = device_index;
@@ -1573,10 +1573,10 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
LIST_INIT(&udev->pd_list);
/* Create the control endpoint device */
- udev->default_dev = usb_make_dev(udev, 0, FREAD|FWRITE);
+ udev->ctrl_dev = usb_make_dev(udev, 0, FREAD|FWRITE);
/* Create a link from /dev/ugenX.X to the default endpoint */
- make_dev_alias(udev->default_dev, udev->ugen_name);
+ make_dev_alias(udev->ctrl_dev, udev->ugen_name);
#endif
if (udev->flags.usb_mode == USB_MODE_HOST) {
@@ -1835,7 +1835,7 @@ config_done:
printf("%s: <%s> at %s\n", udev->ugen_name, udev->manufacturer,
device_get_nameunit(udev->bus->bdev));
- usb_notify_addq("+", udev);
+ usb_notify_addq("ATTACH", udev);
#endif
done:
if (err) {
@@ -1981,7 +1981,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
usb_set_device_state(udev, USB_STATE_DETACHED);
#if USB_HAVE_UGEN
- usb_notify_addq("-", udev);
+ usb_notify_addq("DETACH", udev);
printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name,
udev->manufacturer, device_get_nameunit(bus->bdev));
@@ -2005,24 +2005,24 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
mtx_lock(&usb_ref_lock);
udev->refcount--;
while (udev->refcount != 0) {
- cv_wait(udev->default_cv + 1, &usb_ref_lock);
+ cv_wait(&udev->ref_cv, &usb_ref_lock);
}
mtx_unlock(&usb_ref_lock);
- destroy_dev_sched_cb(udev->default_dev, usb_cdev_cleanup,
- udev->default_dev->si_drv1);
+ destroy_dev_sched_cb(udev->ctrl_dev, usb_cdev_cleanup,
+ udev->ctrl_dev->si_drv1);
#endif
if (udev->flags.usb_mode == USB_MODE_DEVICE) {
/* stop receiving any control transfers (Device Side Mode) */
- usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
+ usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
}
/* the following will get the device unconfigured in software */
usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_EP0);
/* unsetup any leftover default USB transfers */
- usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
+ usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
/* template unsetup, if any */
(usb_temp_unsetup_p) (udev);
@@ -2036,13 +2036,13 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
&udev->cs_msg[0], &udev->cs_msg[1]);
USB_BUS_UNLOCK(udev->bus);
- sx_destroy(udev->default_sx);
- sx_destroy(udev->default_sx + 1);
+ sx_destroy(&udev->ctrl_sx);
+ sx_destroy(&udev->enum_sx);
- cv_destroy(udev->default_cv);
- cv_destroy(udev->default_cv + 1);
+ cv_destroy(&udev->ctrlreq_cv);
+ cv_destroy(&udev->ref_cv);
- mtx_destroy(udev->default_mtx);
+ mtx_destroy(&udev->device_mtx);
#if USB_HAVE_UGEN
KASSERT(LIST_FIRST(&udev->pd_list) == NULL, ("leaked cdev entries"));
#endif
@@ -2348,13 +2348,23 @@ usbd_get_device_index(struct usb_device *udev)
*
* This function will generate events for dev.
*------------------------------------------------------------------------*/
+#ifndef BURN_BRIDGES
static void
-usb_notify_addq(const char *type, struct usb_device *udev)
+usb_notify_addq_compat(const char *type, struct usb_device *udev)
{
char *data = NULL;
+ const char *ntype;
struct malloc_type *mt;
const size_t buf_size = 512;
+ /* Convert notify type */
+ if (strcmp(type, "ATTACH") == 0)
+ ntype = "+";
+ else if (strcmp(type, "DETACH") == 0)
+ ntype = "-";
+ else
+ return;
+
mtx_lock(&malloc_mtx);
mt = malloc_desc2type("bus"); /* XXX M_BUS */
mtx_unlock(&malloc_mtx);
@@ -2379,7 +2389,7 @@ usb_notify_addq(const char *type, struct usb_device *udev)
"port=%u "
"on "
"%s\n",
- type,
+ ntype,
udev->ugen_name,
UGETW(udev->ddesc.idVendor),
UGETW(udev->ddesc.idProduct),
@@ -2394,6 +2404,89 @@ usb_notify_addq(const char *type, struct usb_device *udev)
devctl_queue_data(data);
}
+#endif
+
+static void
+usb_notify_addq(const char *type, struct usb_device *udev)
+{
+ struct usb_interface *iface;
+ struct sbuf *sb;
+ int i;
+
+#ifndef BURN_BRIDGES
+ usb_notify_addq_compat(type, udev);
+#endif
+
+ /* announce the device */
+ sb = sbuf_new_auto();
+ sbuf_printf(sb,
+ "cdev=%s "
+ "vendor=0x%04x "
+ "product=0x%04x "
+ "devclass=0x%02x "
+ "devsubclass=0x%02x "
+ "sernum=\"%s\" "
+ "release=0x%04x "
+ "mode=%s "
+ "port=%u "
+ "parent=%s\n",
+ udev->ugen_name,
+ UGETW(udev->ddesc.idVendor),
+ UGETW(udev->ddesc.idProduct),
+ udev->ddesc.bDeviceClass,
+ udev->ddesc.bDeviceSubClass,
+ udev->serial,
+ UGETW(udev->ddesc.bcdDevice),
+ (udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
+ udev->port_no,
+ udev->parent_hub != NULL ?
+ udev->parent_hub->ugen_name :
+ device_get_nameunit(device_get_parent(udev->bus->bdev)));
+ sbuf_finish(sb);
+ devctl_notify("USB", "DEVICE", type, sbuf_data(sb));
+ sbuf_delete(sb);
+
+ /* announce each interface */
+ for (i = 0; i < USB_IFACE_MAX; i++) {
+ iface = usbd_get_iface(udev, i);
+ if (iface == NULL)
+ break; /* end of interfaces */
+ if (iface->idesc == NULL)
+ continue; /* no interface descriptor */
+
+ sb = sbuf_new_auto();
+ sbuf_printf(sb,
+ "cdev=%s "
+ "vendor=0x%04x "
+ "product=0x%04x "
+ "devclass=0x%02x "
+ "devsubclass=0x%02x "
+ "sernum=\"%s\" "
+ "release=0x%04x "
+ "mode=%s "
+ "interface=%d "
+ "endpoints=%d "
+ "intclass=0x%02x "
+ "intsubclass=0x%02x "
+ "intprotocol=0x%02x\n",
+ udev->ugen_name,
+ UGETW(udev->ddesc.idVendor),
+ UGETW(udev->ddesc.idProduct),
+ udev->ddesc.bDeviceClass,
+ udev->ddesc.bDeviceSubClass,
+ udev->serial,
+ UGETW(udev->ddesc.bcdDevice),
+ (udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
+ iface->idesc->bInterfaceNumber,
+ iface->idesc->bNumEndpoints,
+ iface->idesc->bInterfaceClass,
+ iface->idesc->bInterfaceSubClass,
+ iface->idesc->bInterfaceProtocol);
+ sbuf_finish(sb);
+ devctl_notify("USB", "INTERFACE", type, sbuf_data(sb));
+ sbuf_delete(sb);
+ }
+}
/*------------------------------------------------------------------------*
* usb_fifo_free_wrap
@@ -2495,7 +2588,7 @@ usbd_device_attached(struct usb_device *udev)
void
usbd_enum_lock(struct usb_device *udev)
{
- sx_xlock(udev->default_sx + 1);
+ sx_xlock(&udev->enum_sx);
/*
* NEWBUS LOCK NOTE: We should check if any parent SX locks
* are locked before locking Giant. Else the lock can be
@@ -2510,7 +2603,7 @@ void
usbd_enum_unlock(struct usb_device *udev)
{
mtx_unlock(&Giant);
- sx_xunlock(udev->default_sx + 1);
+ sx_xunlock(&udev->enum_sx);
}
/*
@@ -2521,5 +2614,5 @@ usbd_enum_unlock(struct usb_device *udev)
uint8_t
usbd_enum_is_locked(struct usb_device *udev)
{
- return (sx_xlocked(udev->default_sx + 1));
+ return (sx_xlocked(&udev->enum_sx));
}
diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h
index 66f975a..08b9fd7 100644
--- a/sys/dev/usb/usb_device.h
+++ b/sys/dev/usb/usb_device.h
@@ -30,7 +30,7 @@
struct usb_symlink; /* UGEN */
struct usb_device; /* linux compat */
-#define USB_DEFAULT_XFER_MAX 2
+#define USB_CTRL_XFER_MAX 2
/* "usb_parse_config()" commands */
@@ -113,11 +113,13 @@ struct usb_power_save {
struct usb_device {
struct usb_clear_stall_msg cs_msg[2]; /* generic clear stall
* messages */
- struct sx default_sx[2];
- struct mtx default_mtx[1];
- struct cv default_cv[2];
+ struct sx ctrl_sx;
+ struct sx enum_sx;
+ struct mtx device_mtx;
+ struct cv ctrlreq_cv;
+ struct cv ref_cv;
struct usb_interface *ifaces;
- struct usb_endpoint default_ep; /* Control Endpoint 0 */
+ struct usb_endpoint ctrl_ep; /* Control Endpoint 0 */
struct usb_endpoint *endpoints;
struct usb_power_save pwr_save;/* power save data */
struct usb_bus *bus; /* our USB BUS */
@@ -126,13 +128,13 @@ struct usb_device {
struct usb_device *parent_hs_hub; /* high-speed parent HUB */
struct usb_config_descriptor *cdesc; /* full config descr */
struct usb_hub *hub; /* only if this is a hub */
- struct usb_xfer *default_xfer[USB_DEFAULT_XFER_MAX];
+ struct usb_xfer *ctrl_xfer[USB_CTRL_XFER_MAX];
struct usb_temp_data *usb_template_ptr;
struct usb_endpoint *ep_curr; /* current clear stall endpoint */
#if USB_HAVE_UGEN
struct usb_fifo *fifo[USB_FIFO_MAX];
struct usb_symlink *ugen_symlink; /* our generic symlink */
- struct cdev *default_dev; /* Control Endpoint 0 device node */
+ struct cdev *ctrl_dev; /* Control Endpoint 0 device node */
LIST_HEAD(,usb_fs_privdata) pd_list;
char ugen_name[20]; /* name of ugenX.X device */
#endif
@@ -164,7 +166,7 @@ struct usb_device {
struct usb_device_flags flags;
- struct usb_endpoint_descriptor default_ep_desc; /* for endpoint 0 */
+ struct usb_endpoint_descriptor ctrl_ep_desc; /* for endpoint 0 */
struct usb_device_descriptor ddesc; /* device descriptor */
char *serial; /* serial number */
@@ -196,6 +198,7 @@ struct usb_device *usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
enum usb_dev_speed speed, enum usb_hc_mode mode);
usb_error_t usb_probe_and_attach(struct usb_device *udev,
uint8_t iface_index);
+void usb_detach_device(struct usb_device *, uint8_t, uint8_t);
usb_error_t usb_reset_iface_endpoints(struct usb_device *udev,
uint8_t iface_index);
usb_error_t usbd_set_config_index(struct usb_device *udev, uint8_t index);
diff --git a/sys/dev/usb/usb_freebsd.h b/sys/dev/usb/usb_freebsd.h
index 1f34317..8a008cd 100644
--- a/sys/dev/usb/usb_freebsd.h
+++ b/sys/dev/usb/usb_freebsd.h
@@ -57,10 +57,6 @@
#define USB_HUB_MAX_DEPTH 5
#define USB_EP0_BUFSIZE 1024 /* bytes */
-#ifndef USB_DEBUG
-#define USB_DEBUG 1
-#endif
-
typedef uint32_t usb_timeout_t; /* milliseconds */
typedef uint32_t usb_frlength_t; /* bytes */
typedef uint32_t usb_frcount_t; /* units */
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index 9fc0cc7..db27468 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -81,11 +81,11 @@
static usb_callback_t ugen_read_clear_stall_callback;
static usb_callback_t ugen_write_clear_stall_callback;
-static usb_callback_t ugen_default_read_callback;
-static usb_callback_t ugen_default_write_callback;
+static usb_callback_t ugen_ctrl_read_callback;
+static usb_callback_t ugen_ctrl_write_callback;
static usb_callback_t ugen_isoc_read_callback;
static usb_callback_t ugen_isoc_write_callback;
-static usb_callback_t ugen_default_fs_callback;
+static usb_callback_t ugen_ctrl_fs_callback;
static usb_fifo_open_t ugen_open;
static usb_fifo_close_t ugen_close;
@@ -265,7 +265,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
if (f->flag_short) {
usb_config[0].flags.force_short_xfer = 1;
}
- usb_config[0].callback = &ugen_default_write_callback;
+ usb_config[0].callback = &ugen_ctrl_write_callback;
usb_config[0].timeout = f->timeout;
usb_config[0].frames = 1;
usb_config[0].bufsize = f->bufsize;
@@ -335,7 +335,7 @@ ugen_open_pipe_read(struct usb_fifo *f)
}
usb_config[0].timeout = f->timeout;
usb_config[0].frames = 1;
- usb_config[0].callback = &ugen_default_read_callback;
+ usb_config[0].callback = &ugen_ctrl_read_callback;
usb_config[0].bufsize = f->bufsize;
if (ugen_transfer_setup(f, usb_config, 2)) {
@@ -401,7 +401,7 @@ ugen_stop_io(struct usb_fifo *f)
}
static void
-ugen_default_read_callback(struct usb_xfer *xfer, usb_error_t error)
+ugen_ctrl_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct usb_fifo *f = usbd_xfer_softc(xfer);
struct usb_mbuf *m;
@@ -453,7 +453,7 @@ ugen_default_read_callback(struct usb_xfer *xfer, usb_error_t error)
}
static void
-ugen_default_write_callback(struct usb_xfer *xfer, usb_error_t error)
+ugen_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct usb_fifo *f = usbd_xfer_softc(xfer);
usb_frlength_t actlen;
@@ -1480,7 +1480,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
usb_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
usb_config[0].interval = USB_DEFAULT_INTERVAL;
usb_config[0].flags.proxy_buffer = 1;
- usb_config[0].callback = &ugen_default_fs_callback;
+ usb_config[0].callback = &ugen_ctrl_fs_callback;
usb_config[0].timeout = 0; /* no timeout */
usb_config[0].frames = u.popen->max_frames;
usb_config[0].bufsize = u.popen->max_bufsize;
@@ -2095,17 +2095,32 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
break;
case USB_IFACE_DRIVER_ACTIVE:
- /* TODO */
- *u.pint = 0;
+
+ n = *u.pint & 0xFF;
+
+ iface = usbd_get_iface(f->udev, n);
+
+ if (iface && iface->subdev)
+ error = 0;
+ else
+ error = ENXIO;
break;
case USB_IFACE_DRIVER_DETACH:
- /* TODO */
+
error = priv_check(curthread, PRIV_DRIVER);
- if (error) {
+
+ if (error)
+ break;
+
+ n = *u.pint & 0xFF;
+
+ if (n == USB_IFACE_INDEX_ANY) {
+ error = EINVAL;
break;
}
- error = EINVAL;
+
+ usb_detach_device(f->udev, n, 0);
break;
case USB_SET_POWER_MODE:
@@ -2186,7 +2201,7 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
}
static void
-ugen_default_fs_callback(struct usb_xfer *xfer, usb_error_t error)
+ugen_ctrl_fs_callback(struct usb_xfer *xfer, usb_error_t error)
{
; /* workaround for a bug in "indent" */
diff --git a/sys/dev/usb/usb_hid.c b/sys/dev/usb/usb_hid.c
index f13bbf1..1f93227 100644
--- a/sys/dev/usb/usb_hid.c
+++ b/sys/dev/usb/usb_hid.c
@@ -19,13 +19,6 @@ __FBSDID("$FreeBSD$");
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index 9779796..c31f8fa 100644
--- a/sys/dev/usb/usb_hub.c
+++ b/sys/dev/usb/usb_hub.c
@@ -246,7 +246,7 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
/* start control transfer, if device mode */
if (child->flags.usb_mode == USB_MODE_DEVICE) {
- usbd_default_transfer_setup(child);
+ usbd_ctrl_transfer_setup(child);
}
/* if a HUB becomes present, do a recursive HUB explore */
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index 03745fa..6150cb1 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -68,7 +68,7 @@
#include <dev/usb/usb_bus.h>
#include <sys/ctype.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int usb_pr_poll_delay = USB_PORT_RESET_DELAY;
static int usb_pr_recovery_delay = USB_PORT_RESET_RECOVERY;
static int usb_ss_delay = 0;
@@ -99,7 +99,7 @@ usbd_do_request_callback(struct usb_xfer *xfer, usb_error_t error)
usbd_transfer_submit(xfer);
break;
default:
- cv_signal(xfer->xroot->udev->default_cv);
+ cv_signal(&xfer->xroot->udev->ctrlreq_cv);
break;
}
}
@@ -319,7 +319,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
* is achieved when multiple threads are involved:
*/
- sx_xlock(udev->default_sx);
+ sx_xlock(&udev->ctrl_sx);
hr_func = usbd_get_hr_func(udev);
@@ -374,9 +374,9 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
/*
* Setup a new USB transfer or use the existing one, if any:
*/
- usbd_default_transfer_setup(udev);
+ usbd_ctrl_transfer_setup(udev);
- xfer = udev->default_xfer[0];
+ xfer = udev->ctrl_xfer[0];
if (xfer == NULL) {
/* most likely out of memory */
err = USB_ERR_NOMEM;
@@ -433,7 +433,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
} else {
if (xfer->frlengths[0] == 0) {
if (xfer->flags.manual_status) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
int temp;
temp = usb_ss_delay;
@@ -457,7 +457,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
usbd_transfer_start(xfer);
while (usbd_transfer_pending(xfer)) {
- cv_wait(udev->default_cv,
+ cv_wait(&udev->ctrlreq_cv,
xfer->xroot->xfer_mtx);
}
@@ -534,7 +534,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
USB_XFER_UNLOCK(xfer);
done:
- sx_xunlock(udev->default_sx);
+ sx_xunlock(&udev->ctrl_sx);
if (mtx) {
mtx_lock(mtx);
@@ -603,7 +603,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
usb_error_t err;
uint16_t n;
-#if USB_DEBUG
+#ifdef USB_DEBUG
uint16_t pr_poll_delay;
uint16_t pr_recovery_delay;
@@ -612,7 +612,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
if (err) {
goto done;
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
/* range check input parameters */
pr_poll_delay = usb_pr_poll_delay;
if (pr_poll_delay < 1) {
@@ -627,7 +627,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
#endif
n = 0;
while (1) {
-#if USB_DEBUG
+#ifdef USB_DEBUG
/* wait for the device to recover from reset */
usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
n += pr_poll_delay;
@@ -666,7 +666,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
err = USB_ERR_TIMEOUT;
goto done;
}
-#if USB_DEBUG
+#ifdef USB_DEBUG
/* wait for the device to recover from reset */
usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));
#else
diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
index e7cb202..535d12b 100644
--- a/sys/dev/usb/usb_transfer.c
+++ b/sys/dev/usb/usb_transfer.c
@@ -72,7 +72,7 @@ struct usb_std_packet_size {
static usb_callback_t usb_request_callback;
-static const struct usb_config usb_control_ep_cfg[USB_DEFAULT_XFER_MAX] = {
+static const struct usb_config usb_control_ep_cfg[USB_CTRL_XFER_MAX] = {
/* This transfer is used for generic control endpoint transfers */
@@ -1418,7 +1418,7 @@ usbd_transfer_submit(struct usb_xfer *xfer)
xfer, xfer->endpoint, xfer->nframes, USB_GET_DATA_ISREAD(xfer) ?
"read" : "write");
-#if USB_DEBUG
+#ifdef USB_DEBUG
if (USB_DEBUG_VAR > 0) {
USB_BUS_LOCK(bus);
@@ -2410,28 +2410,31 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
* Check if we are supposed to stall the endpoint:
*/
if (xfer->flags.stall_pipe) {
+ struct usb_device *udev;
+ struct usb_xfer_root *info;
+
/* clear stall command */
xfer->flags.stall_pipe = 0;
+ /* get pointer to USB device */
+ info = xfer->xroot;
+ udev = info->udev;
+
/*
* Only stall BULK and INTERRUPT endpoints.
*/
type = (ep->edesc->bmAttributes & UE_XFERTYPE);
if ((type == UE_BULK) ||
(type == UE_INTERRUPT)) {
- struct usb_device *udev;
- struct usb_xfer_root *info;
uint8_t did_stall;
- info = xfer->xroot;
- udev = info->udev;
did_stall = 1;
if (udev->flags.usb_mode == USB_MODE_DEVICE) {
(udev->bus->methods->set_stall) (
udev, NULL, ep, &did_stall);
- } else if (udev->default_xfer[1]) {
- info = udev->default_xfer[1]->xroot;
+ } else if (udev->ctrl_xfer[1]) {
+ info = udev->ctrl_xfer[1]->xroot;
usb_proc_msignal(
&info->bus->non_giant_callback_proc,
&udev->cs_msg[0], &udev->cs_msg[1]);
@@ -2452,6 +2455,17 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
ep->is_stalled = 1;
return;
}
+ } else if (type == UE_ISOCHRONOUS) {
+
+ /*
+ * Make sure any FIFO overflow or other FIFO
+ * error conditions go away by resetting the
+ * endpoint FIFO through the clear stall
+ * method.
+ */
+ if (udev->flags.usb_mode == USB_MODE_DEVICE) {
+ (udev->bus->methods->clear_stall) (udev, ep);
+ }
}
}
/* Set or clear stall complete - special case */
@@ -2743,13 +2757,13 @@ usb_command_wrapper(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
}
/*------------------------------------------------------------------------*
- * usbd_default_transfer_setup
+ * usbd_ctrl_transfer_setup
*
* This function is used to setup the default USB control endpoint
* transfer.
*------------------------------------------------------------------------*/
void
-usbd_default_transfer_setup(struct usb_device *udev)
+usbd_ctrl_transfer_setup(struct usb_device *udev)
{
struct usb_xfer *xfer;
uint8_t no_resetup;
@@ -2760,12 +2774,12 @@ usbd_default_transfer_setup(struct usb_device *udev)
return;
repeat:
- xfer = udev->default_xfer[0];
+ xfer = udev->ctrl_xfer[0];
if (xfer) {
USB_XFER_LOCK(xfer);
no_resetup =
((xfer->address == udev->address) &&
- (udev->default_ep_desc.wMaxPacketSize[0] ==
+ (udev->ctrl_ep_desc.wMaxPacketSize[0] ==
udev->ddesc.bMaxPacketSize));
if (udev->flags.usb_mode == USB_MODE_DEVICE) {
if (no_resetup) {
@@ -2792,13 +2806,13 @@ repeat:
/*
* Update wMaxPacketSize for the default control endpoint:
*/
- udev->default_ep_desc.wMaxPacketSize[0] =
+ udev->ctrl_ep_desc.wMaxPacketSize[0] =
udev->ddesc.bMaxPacketSize;
/*
* Unsetup any existing USB transfer:
*/
- usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
+ usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
/*
* Try to setup a new USB transfer for the
@@ -2806,8 +2820,8 @@ repeat:
*/
iface_index = 0;
if (usbd_transfer_setup(udev, &iface_index,
- udev->default_xfer, usb_control_ep_cfg, USB_DEFAULT_XFER_MAX, NULL,
- udev->default_mtx)) {
+ udev->ctrl_xfer, usb_control_ep_cfg, USB_CTRL_XFER_MAX, NULL,
+ &udev->device_mtx)) {
DPRINTFN(0, "could not setup default "
"USB transfer\n");
} else {
@@ -2987,13 +3001,13 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
USB_BUS_LOCK(xroot->bus);
/* check for clear stall */
- if (udev->default_xfer[1] != NULL) {
+ if (udev->ctrl_xfer[1] != NULL) {
/* poll clear stall start */
pm = &udev->cs_msg[0].hdr;
(pm->pm_callback) (pm);
/* poll clear stall done thread */
- pm = &udev->default_xfer[1]->
+ pm = &udev->ctrl_xfer[1]->
xroot->done_m[0].hdr;
(pm->pm_callback) (pm);
}
diff --git a/sys/dev/usb/usb_transfer.h b/sys/dev/usb/usb_transfer.h
index 27f3aff..6e08df0 100644
--- a/sys/dev/usb/usb_transfer.h
+++ b/sys/dev/usb/usb_transfer.h
@@ -123,7 +123,7 @@ void usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error);
void usbd_transfer_enqueue(struct usb_xfer_queue *pq,
struct usb_xfer *xfer);
void usbd_transfer_setup_sub(struct usb_setup_params *parm);
-void usbd_default_transfer_setup(struct usb_device *udev);
+void usbd_ctrl_transfer_setup(struct usb_device *udev);
void usbd_clear_data_toggle(struct usb_device *udev,
struct usb_endpoint *ep);
usb_callback_t usbd_do_request_callback;
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 2385daf..a7bac44 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -17,13 +17,6 @@ $FreeBSD$
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -65,6 +58,7 @@ $FreeBSD$
vendor UNKNOWN1 0x0053 Unknown vendor
vendor UNKNOWN2 0x0105 Unknown vendor
vendor EGALAX2 0x0123 eGalax, Inc.
+vendor UNKNOWN4 0x0204 Unknown vendor
vendor HUMAX 0x02ad HUMAX
vendor LTS 0x0386 LTS
vendor BWCT 0x03da Bernd Walter Computer Technology
@@ -277,6 +271,7 @@ vendor LACIE 0x059f LaCie
vendor FUJIFILM 0x05a2 Fuji Film
vendor ARC 0x05a3 ARC
vendor ORTEK 0x05a4 Ortek
+vendor CISCOLINKSYS3 0x05a6 Cisco-Linksys
vendor BOSE 0x05a7 Bose
vendor OMNIVISION 0x05a9 OmniVision
vendor INSYSTEM 0x05ab In-System Design
@@ -407,6 +402,7 @@ vendor STSN 0x07ef STSN
vendor CENTURY 0x07f7 Century Corp
vendor ZOOM 0x0803 Zoom Telephonics
vendor PCS 0x0810 Personal Communication Systems
+vendor ALPHASMART 0x081e AlphaSmart, Inc.
vendor BROADLOGIC 0x0827 BroadLogic
vendor HANDSPRING 0x082d Handspring
vendor PALM 0x0830 Palm Computing
@@ -544,6 +540,8 @@ vendor FALCOM 0x0f94 Falcom Wireless Communications GmbH
vendor RIM 0x0fca Research In Motion
vendor DYNASTREAM 0x0fcf Dynastream Innovations
vendor QUALCOMM 0x1004 Qualcomm
+vendor APACER 0x1005 Apacer
+vendor MOTOROLA4 0x100d Motorola
vendor DESKNOTE 0x1019 Desknote
vendor GIGABYTE 0x1044 GIGABYTE
vendor WESTERN 0x1058 Western Digital
@@ -640,6 +638,7 @@ vendor LINKSYS3 0x1915 Linksys
vendor QUALCOMMINC 0x19d2 Qualcomm, Incorporated
vendor WCH2 0x1a86 QinHeng Electronics
vendor STELERA 0x1a8d Stelera Wireless
+vendor OVISLINK 0x1b75 OvisLink
vendor TCTMOBILE 0x1bbb TCT Mobile
vendor TELIT 0x1bc7 Telit
vendor MPMAN 0x1cae MpMan
@@ -681,6 +680,7 @@ vendor 3COM2 0x6891 3Com
vendor EDIMAX 0x7392 Edimax
vendor INTEL 0x8086 Intel
vendor INTEL2 0x8087 Intel
+vendor ALLWIN 0x8516 ALLWIN Tech
vendor SITECOM2 0x9016 Sitecom
vendor MOSCHIP 0x9710 MosChip Semiconductor
vendor MARVELL 0x9e88 Marvell Technology Group Ltd.
@@ -760,6 +760,7 @@ product ACCTON RT3070_1 0xa701 RT3070
product ACCTON RT3070_2 0xa702 RT3070
product ACCTON RT2870_1 0xb522 RT2870
product ACCTON RT3070_3 0xc522 RT3070
+product ACCTON RT3070_5 0xd522 RT3070
product ACCTON ZD1211B 0xe501 ZD1211B
/* Aceeca products */
@@ -892,6 +893,19 @@ product ALTEC ASC495 0xff05 ASC495 Speakers
/* Allied Telesyn International products */
product ALLIEDTELESYN ATUSB100 0xb100 AT-USB100
+/* ALLWIN Tech products */
+product ALLWIN RT2070 0x2070 RT2070
+product ALLWIN RT2770 0x2770 RT2770
+product ALLWIN RT2870 0x2870 RT2870
+product ALLWIN RT3070 0x3070 RT3070
+product ALLWIN RT3071 0x3071 RT3071
+product ALLWIN RT3072 0x3072 RT3072
+product ALLWIN RT3572 0x3572 RT3572
+
+/* AlphaSmart, Inc. products */
+product ALPHASMART DANA_KB 0xdbac AlphaSmart Dana Keyboard
+product ALPHASMART DANA_SYNC 0xdf00 AlphaSmart Dana HotSync
+
/* Amoi products */
product AMOI H01 0x0800 H01 3G modem
product AMOI H01A 0x7002 H01A 3G modem
@@ -990,7 +1004,8 @@ product ASUS RT2870_2 0x1732 RT2870
product ASUS RT2870_3 0x1742 RT2870
product ASUS RT2870_4 0x1760 RT2870
product ASUS RT2870_5 0x1761 RT2870
-product ASUS RT3070 0x1784 RT3070
+product ASUS USBN13 0x1784 USB-N13
+product ASUS RT3070_1 0x1790 RT3070
product ASUS P535 0x420f ASUS P535 PDA
product ASUS GMSC 0x422f ASUS Generic Mass Storage
product ASUS RT2570 0x1706 RT2500USB Wireless Adapter
@@ -1084,6 +1099,7 @@ product BROADCOM BCM2033 0x2033 BCM2033 Bluetooth USB dongle
/* Brother Industries products */
product BROTHER HL1050 0x0002 HL-1050 laser printer
+product BROTHER MFC8600_9650 0x0100 MFC8600/9650 multifunction device
/* Behavior Technology Computer products */
product BTC BTC7932 0x6782 Keyboard with mouse port
@@ -1148,7 +1164,8 @@ product CISCOLINKSYS HU200TS 0x001a HU200TS Wireless Adapter
product CISCOLINKSYS WUSB54GC 0x0020 WUSB54GC
product CISCOLINKSYS WUSB54GR 0x0023 WUSB54GR
product CISCOLINKSYS WUSBF54G 0x0024 WUSBF54G
-product CISCOLINKSYS2 RT3070 0x4001 RT3070
+product CISCOLINKSYS2 RT3070 0x4001 RT3070
+product CISCOLINKSYS3 RT3070 0x0101 RT3070
/* CMOTECH products */
product CMOTECH CNU510 0x5141 CDMA Technologies USB modem
@@ -1175,6 +1192,8 @@ product CONCEPTRONIC AR5523_2 0x7811 AR5523
product CONCEPTRONIC AR5523_2_NF 0x7812 AR5523 (no firmware)
product CONCEPTRONIC2 C54RU 0x3c02 C54RU WLAN
product CONCEPTRONIC2 C54RU2 0x3c22 C54RU
+product CONCEPTRONIC2 RT3070_1 0x3c08 RT3070
+product CONCEPTRONIC2 RT3070_2 0x3c11 RT3070
product CONCEPTRONIC2 VIGORN61 0x3c25 VIGORN61
product CONCEPTRONIC2 RT2870_1 0x3c06 RT2870
product CONCEPTRONIC2 RT2870_2 0x3c07 RT2870
@@ -1327,12 +1346,14 @@ product DLINK2 DWA111 0x3c06 DWA-111
product DLINK2 RT2870_1 0x3c09 RT2870
product DLINK2 DWA110 0x3c07 DWA-110
product DLINK2 RT3072 0x3c0a RT3072
+product DLINK2 RT3072_1 0x3c0b RT3072
product DLINK2 RT3070_1 0x3c0d RT3070
product DLINK2 RT3070_2 0x3c0e RT3070
product DLINK2 RT3070_3 0x3c0f RT3070
product DLINK2 RT2870_2 0x3c11 RT2870
product DLINK2 DWA130 0x3c13 DWA-130
product DLINK2 RT3070_4 0x3c15 RT3070
+product DLINK2 RT3070_5 0x3c16 RT3070
product DLINK3 DWM652 0x3e04 DWM-652
/* DMI products */
@@ -1793,6 +1814,7 @@ product JABLOTRON PC60B 0x0001 PC-60B
product JATON EDA 0x5704 Ethernet
/* JMicron products */
+product JMICRON JM20336 0x2336 USB to SATA Bridge
product JMICRON JM20337 0x2338 USB to ATA/ATAPI Bridge
/* JVC products */
@@ -1903,6 +1925,7 @@ product LINKSYS4 WUSB100 0x0070 WUSB100
product LINKSYS4 WUSB600N 0x0071 WUSB600N
product LINKSYS4 WUSB54GCV2 0x0073 WUSB54GC v2
product LINKSYS4 WUSB54GCV3 0x0077 WUSB54GC v3
+product LINKSYS4 RT3070 0x0078 RT3070
product LINKSYS4 WUSB600NV2 0x0079 WUSB600N v2
/* Logitech products */
@@ -1976,6 +1999,8 @@ product MELCO KG54L 0x00da WLI-U2-KG54L
product MELCO WLIUCG300N 0x00e8 WLI-UC-G300N
product MELCO SG54HG 0x00f4 WLI-U2-SG54HG
product MELCO WLIUCAG300N 0x012e WLI-UC-AG300N
+product MELCO RT2870_1 0x0148 RT2870
+product MELCO RT2870_2 0x0150 RT2870
product MELCO WLIUCGN 0x015d WLI-UC-GN
/* Merlin products */
@@ -1996,7 +2021,9 @@ product MGE UPS2 0xffff MGE UPS SYSTEMS PROTECTIONCENTER 2
product MSI BT_DONGLE 0x1967 Bluetooth USB dongle
product MSI RT3070_1 0x3820 RT3070
product MSI RT3070_2 0x3821 RT3070
+product MSI RT3070_8 0x3822 RT3070
product MSI RT3070_3 0x3870 RT3070
+product MSI RT3070_9 0x3871 RT3070
product MSI UB11B 0x6823 UB11B
product MSI RT2570 0x6861 RT2570
product MSI RT2570_2 0x6865 RT2570
@@ -2005,14 +2032,13 @@ product MSI RT2573_1 0x6874 RT2573
product MSI RT2573_2 0x6877 RT2573
product MSI RT3070_4 0x6899 RT3070
product MSI RT3070_5 0x821a RT3070
+product MSI RT3070_10 0x822a RT3070
product MSI RT3070_6 0x870a RT3070
+product MSI RT3070_11 0x871a RT3070
product MSI RT3070_7 0x899a RT3070
product MSI RT2573_3 0xa861 RT2573
product MSI RT2573_4 0xa874 RT2573
-/* Microdia products */
-product MICRODIA TWINKLECAM 0x600d TwinkleCam USB camera
-
/* Microsoft products */
product MICROSOFT SIDEPREC 0x0008 SideWinder Precision Pro
product MICROSOFT INTELLIMOUSE 0x0009 IntelliMouse
@@ -2032,6 +2058,7 @@ product MICROSOFT WLNOTEBOOK2 0x00e1 Wireless Optical Mouse 3000 (Model 1056)
product MICROSOFT WLNOTEBOOK3 0x00d2 Wireless Optical Mouse 3000 (Model 1049)
product MICROSOFT WLUSBMOUSE 0x00b9 Wireless USB Mouse
product MICROSOFT XBOX360 0x0292 XBOX 360 WLAN
+product MICROSOFT NATURAL4000 0x00db Natural Ergonomic Keyboard 4000
/* Microtech products */
product MICROTECH SCSIDB25 0x0004 USB-SCSI-DB25
@@ -2089,6 +2116,8 @@ product MOTOROLA2 A41XV32X 0x2a22 A41x/V32x Mobile Phones
product MOTOROLA2 E398 0x4810 E398 Mobile Phone
product MOTOROLA2 USBLAN 0x600c USBLAN
product MOTOROLA2 USBLAN2 0x6027 USBLAN
+product MOTOROLA4 RT2770 0x9031 RT2770
+product MOTOROLA4 RT3070 0x9032 RT3070
/* MultiTech products */
product MULTITECH ATLAS 0xf101 MT5634ZBA-USB modem
@@ -2101,6 +2130,7 @@ product MUSTEK 1200UB 0x0006 1200 UB scanner
product MUSTEK 1200USBPLUS 0x0007 1200 USB Plus scanner
product MUSTEK 1200CUPLUS 0x0008 1200 CU Plus scanner
product MUSTEK BEARPAW1200F 0x0010 BearPaw 1200F scanner
+product MUSTEK BEARPAW2400TA 0x0218 BearPaw 2400TA scanner
product MUSTEK BEARPAW1200TA 0x021e BearPaw 1200TA scanner
product MUSTEK 600USB 0x0873 600 USB scanner
product MUSTEK MDC800 0xa800 MDC-800 digital camera
@@ -2259,6 +2289,9 @@ product OPTION MODHSXPA 0xd013 Globetrotter HSUPA
product OPTION ICON321 0xd031 Globetrotter HSUPA
product OPTION ICON505 0xd055 Globetrotter iCON 505
+/* OvisLink product */
+product OVISLINK RT3072 0x3072 RT3072
+
/* OQO */
product OQO WIFI01 0x0002 model 01 WiFi interface
product OQO BT01 0x0003 model 01 Bluetooth interface
@@ -2293,6 +2326,7 @@ product PARA RT3070 0x8888 RT3070
product PEGATRON RT2870 0x0002 RT2870
product PEGATRON RT3070 0x000c RT3070
product PEGATRON RT3070_2 0x000e RT3070
+product PEGATRON RT3070_3 0x0010 RT3070
/* Peracom products */
product PERACOM SERIAL1 0x0001 Serial
@@ -2382,6 +2416,7 @@ product PROLIFIC PL2303 0x2303 PL2303 Serial (ATEN/IOGEAR UC232A)
product PROLIFIC PL2305 0x2305 Parallel printer
product PROLIFIC ATAPI4 0x2307 ATAPI-4 Controller
product PROLIFIC PL2501 0x2501 PL2501 Host-Host interface
+product PROLIFIC PL2506 0x2506 PL2506 USB to IDE Bridge
product PROLIFIC PHAROS 0xaaa0 Prolific Pharos
product PROLIFIC RSAQ3 0xaaa2 PL2303 Serial Adapter (IODATA USB-RSAQ3)
product PROLIFIC2 WSIM 0x2001 Willcom WSIM
@@ -2481,13 +2516,15 @@ product QUALCOMMINC E2002 0x2002 3G modem
product QUALCOMMINC E2003 0x2003 3G modem
/* Quanta products */
-/* Quanta products */
+product QUANTA RW6815_1 0x00ce HP iPAQ rw6815
product QUANTA RT3070 0x0304 RT3070
+product QUANTA Q101_STOR 0x1000 USB Q101 Storage
product QUANTA Q101 0xea02 HSDPA modem
product QUANTA Q111 0xea03 HSDPA modem
product QUANTA GLX 0xea04 HSDPA modem
product QUANTA GKE 0xea05 HSDPA modem
product QUANTA GLE 0xea06 HSDPA modem
+product QUANTA RW6815_2 0xf003 HP iPAQ rw6815
/* Qtronix products */
product QTRONIX 980N 0x2011 Scorpion-980N keyboard
@@ -2512,7 +2549,9 @@ product RALINK RT2870 0x2870 RT2870
product RALINK RT3070 0x3070 RT3070
product RALINK RT3071 0x3071 RT3071
product RALINK RT3072 0x3072 RT3072
+product RALINK RT3370 0x3370 RT3370
product RALINK RT3572 0x3572 RT3572
+product RALINK RT8070 0x8070 RT8070
product RALINK RT2570_3 0x9020 RT2500USB Wireless Adapter
product RALINK RT2573_2 0x9021 RT2501USB Wireless Adapter
@@ -2693,6 +2732,7 @@ product SIERRA AIRCARD875 0x6820 Aircard 875 HSDPA
product SIERRA TRUINSTALL 0x0fff Aircard Tru Installer
/* Sigmatel products */
+product SIGMATEL WBT_3052 0x4200 WBT-3052 IrDA/USB Bridge
product SIGMATEL I_BEAD100 0x8008 i-Bead 100 MP3 Player
/* SIIG products */
@@ -2749,6 +2789,7 @@ product SITECOMEU RT3070_3 0x003c RT3070
product SITECOMEU RT3070_4 0x003d RT3070
product SITECOMEU RT3070 0x003e RT3070
product SITECOMEU WL608 0x003f WL-608
+product SITECOMEU RT3071 0x0040 RT3071
product SITECOMEU RT3072_1 0x0041 RT3072
product SITECOMEU RT3072_2 0x0042 RT3072
product SITECOMEU RT3072_3 0x0047 RT3072
@@ -2775,6 +2816,7 @@ product SMC 2202USB 0x0200 10/100 Ethernet
product SMC 2206USB 0x0201 EZ Connect USB Ethernet
product SMC 2862WG 0xee13 EZ Connect Wireless Adapter
product SMC2 2020HUB 0x2020 USB Hub
+product SMC2 2514HUB 0x2514 USB Hub
product SMC3 2662WUSB 0xa002 2662W-AR Wireless
/* SOHOware products */
@@ -2884,6 +2926,7 @@ product SURECOM RT2573 0x31f3 RT2573
/* Sweex products */
product SWEEX ZD1211 0x1809 ZD1211
+product SWEEX2 LW153 0x0153 LW153
product SWEEX2 LW303 0x0302 LW303
product SWEEX2 LW313 0x0313 LW313
@@ -2939,6 +2982,7 @@ product TOPRE HHKB 0x0100 HHKB Professional
/* Toshiba Corporation products */
product TOSHIBA POCKETPC_E740 0x0706 PocketPC e740
+product TOSHIBA RT3070 0x0a07 RT3070
product TOSHIBA G450 0x0d45 G450 modem
product TOSHIBA HSDPA 0x1302 G450 modem
@@ -2987,6 +3031,9 @@ product UMEDIA AR5523_2_NF 0x3206 AR5523 (no firmware)
/* Universal Access products */
product UNIACCESS PANACHE 0x0101 Panache Surf USB ISDN Adapter
+/* Unknown vendors */
+product UNKNOWN4 USBMEMSTICK 0x6025 Flash Disk CBM
+
/* U.S. Robotics products */
product USR USR5423 0x0121 USR5423 WLAN
@@ -3119,3 +3166,4 @@ product ZYXEL M202 0x340a M-202
product ZYXEL G220V2 0x340f G-220 v2
product ZYXEL G202 0x3410 G-202
product ZYXEL RT2870_1 0x3416 RT2870
+product ZYXEL RT2870_2 0x341a RT2870
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index 0cd394d..4a5fbae 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/wlan/if_rumvar.h>
#include <dev/usb/wlan/if_rumfw.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int rum_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
@@ -140,7 +140,6 @@ static const struct usb_device_id rum_devs[] = {
};
MODULE_DEPEND(rum, wlan, 1, 1, 1);
-MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
MODULE_DEPEND(rum, usb, 1, 1, 1);
static device_probe_t rum_match;
@@ -212,17 +211,14 @@ static int rum_prepare_beacon(struct rum_softc *,
struct ieee80211vap *);
static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void rum_newassoc(struct ieee80211_node *, int);
static void rum_scan_start(struct ieee80211com *);
static void rum_scan_end(struct ieee80211com *);
static void rum_set_channel(struct ieee80211com *);
static int rum_get_rssi(struct rum_softc *, uint8_t);
-static void rum_amrr_start(struct rum_softc *,
+static void rum_ratectl_start(struct rum_softc *,
struct ieee80211_node *);
-static void rum_amrr_timeout(void *);
-static void rum_amrr_task(void *, int);
+static void rum_ratectl_timeout(void *);
+static void rum_ratectl_task(void *, int);
static int rum_pause(struct rum_softc *, int);
static const struct {
@@ -511,9 +507,7 @@ rum_attach(device_t self)
ieee80211_ifattach(ic, sc->sc_bssid);
ic->ic_update_promisc = rum_update_promisc;
- ic->ic_newassoc = rum_newassoc;
ic->ic_raw_xmit = rum_raw_xmit;
- ic->ic_node_alloc = rum_node_alloc;
ic->ic_scan_start = rum_scan_start;
ic->ic_scan_end = rum_scan_end;
ic->ic_set_channel = rum_set_channel;
@@ -608,13 +602,10 @@ rum_vap_create(struct ieee80211com *ic,
rvp->newstate = vap->iv_newstate;
vap->iv_newstate = rum_newstate;
- usb_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
- TASK_INIT(&rvp->amrr_task, 0, rum_amrr_task, rvp);
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
+ usb_callout_init_mtx(&rvp->ratectl_ch, &sc->sc_mtx, 0);
+ TASK_INIT(&rvp->ratectl_task, 0, rum_ratectl_task, rvp);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
ic->ic_opmode = opmode;
@@ -627,9 +618,9 @@ rum_vap_delete(struct ieee80211vap *vap)
struct rum_vap *rvp = RUM_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- usb_callout_drain(&rvp->amrr_ch);
- ieee80211_draintask(ic, &rvp->amrr_task);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ usb_callout_drain(&rvp->ratectl_ch);
+ ieee80211_draintask(ic, &rvp->ratectl_task);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
}
@@ -716,7 +707,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
RUM_LOCK(sc);
- usb_callout_stop(&rvp->amrr_ch);
+ usb_callout_stop(&rvp->ratectl_ch);
switch (nstate) {
case IEEE80211_S_INIT:
@@ -751,7 +742,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* enable automatic rate adaptation */
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- rum_amrr_start(sc, ni);
+ rum_ratectl_start(sc, ni);
break;
default:
break;
@@ -2194,7 +2185,7 @@ bad:
}
static void
-rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
+rum_ratectl_start(struct rum_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct rum_vap *rvp = RUM_VAP(vap);
@@ -2202,23 +2193,23 @@ rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
/* clear statistic registers (STA_CSR0 to STA_CSR5) */
rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
- ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
+ ieee80211_ratectl_node_init(ni);
- usb_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
+ usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
}
static void
-rum_amrr_timeout(void *arg)
+rum_ratectl_timeout(void *arg)
{
struct rum_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- ieee80211_runtask(ic, &rvp->amrr_task);
+ ieee80211_runtask(ic, &rvp->ratectl_task);
}
static void
-rum_amrr_task(void *arg, int pending)
+rum_ratectl_task(void *arg, int pending)
{
struct rum_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
@@ -2227,6 +2218,7 @@ rum_amrr_task(void *arg, int pending)
struct rum_softc *sc = ifp->if_softc;
struct ieee80211_node *ni = vap->iv_bss;
int ok, fail;
+ int sum, retrycnt;
RUM_LOCK(sc);
/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
@@ -2235,36 +2227,18 @@ rum_amrr_task(void *arg, int pending)
ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */
(le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */
fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */
+ sum = ok+fail;
+ retrycnt = (le32toh(sc->sta[5]) & 0xffff) + fail;
- ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn,
- ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
- (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
+ ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
- usb_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
+ usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
RUM_UNLOCK(sc);
}
-/* ARGUSED */
-static struct ieee80211_node *
-rum_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct rum_node *rn;
-
- rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return rn != NULL ? &rn->ni : NULL;
-}
-
-static void
-rum_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
-}
-
static void
rum_scan_start(struct ieee80211com *ic)
{
diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h
index 82bb117..f46634c 100644
--- a/sys/dev/usb/wlan/if_rumvar.h
+++ b/sys/dev/usb/wlan/if_rumvar.h
@@ -67,18 +67,11 @@ struct rum_tx_data {
};
typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead;
-struct rum_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define RUM_NODE(ni) ((struct rum_node *)(ni))
-
struct rum_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct usb_callout amrr_ch;
- struct task amrr_task;
+ struct usb_callout ratectl_ch;
+ struct task ratectl_task;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 03fbdf1..3ab607f 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -1,8 +1,9 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2008,2009 Damien Bergamini <damien.bergamini@free.fr>
- * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
+ * Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini@free.fr>
+ * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
+ * USB Consulting, Hans Petter Selasky <hselasky@freebsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,8 +18,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* release date Jan. 09, 2010 */
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -66,7 +65,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -80,7 +79,7 @@ __FBSDID("$FreeBSD$");
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
-#if USB_DEBUG
+#ifdef USB_DEBUG
#define RUN_DEBUG
#endif
@@ -107,11 +106,20 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_3) },
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_4) },
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_5) },
+ { USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070) },
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_1) },
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_2) },
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_3) },
{ USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_4) },
+ { USB_VP(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_5) },
{ USB_VP(USB_VENDOR_AIRTIES, USB_PRODUCT_AIRTIES_RT3070) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2070) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2770) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2870) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3070) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3071) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3072) },
+ { USB_VP(USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3572) },
{ USB_VP(USB_VENDOR_AMIGO, USB_PRODUCT_AMIGO_RT2870_1) },
{ USB_VP(USB_VENDOR_AMIGO, USB_PRODUCT_AMIGO_RT2870_2) },
{ USB_VP(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GNR) },
@@ -122,6 +130,8 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_3) },
{ USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_4) },
{ USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_5) },
+ { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN13) },
+ { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT3070_1) },
{ USB_VP(USB_VENDOR_ASUS2, USB_PRODUCT_ASUS2_USBN11) },
{ USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT2870_1) },
{ USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT2870_2) },
@@ -133,6 +143,8 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V1) },
{ USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RT2870_1) },
{ USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RT2870_2) },
+ { USB_VP(USB_VENDOR_CISCOLINKSYS2, USB_PRODUCT_CISCOLINKSYS2_RT3070) },
+ { USB_VP(USB_VENDOR_CISCOLINKSYS3, USB_PRODUCT_CISCOLINKSYS2_RT3070) },
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_1) },
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_2) },
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_3) },
@@ -141,6 +153,8 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_6) },
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_7) },
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_8) },
+ { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_1) },
+ { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_2) },
{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_VIGORN61) },
{ USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB300GNM) },
{ USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_1) },
@@ -157,7 +171,9 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_2) },
{ USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_3) },
{ USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_4) },
+ { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_5) },
{ USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3072) },
+ { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3072_1) },
{ USB_VP(USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7717) },
{ USB_VP(USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7718) },
{ USB_VP(USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RT2870_1) },
@@ -178,6 +194,7 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_2) },
{ USB_VP(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_3) },
{ USB_VP(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_4) },
+ { USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_RT3070) },
{ USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB100) },
{ USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GCV3) },
{ USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N) },
@@ -185,9 +202,13 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_1) },
{ USB_VP(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_2) },
{ USB_VP(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_3) },
+ { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_1) },
+ { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_2) },
{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCAG300N) },
{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300N) },
{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGN) },
+ { USB_VP(USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT2770) },
+ { USB_VP(USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT3070) },
{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_1) },
{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_2) },
{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_3) },
@@ -195,10 +216,16 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_5) },
{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_6) },
{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_7) },
+ { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_8) },
+ { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_9) },
+ { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_10) },
+ { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_11) },
+ { USB_VP(USB_VENDOR_OVISLINK, USB_PRODUCT_OVISLINK_RT3072) },
{ USB_VP(USB_VENDOR_PARA, USB_PRODUCT_PARA_RT3070) },
{ USB_VP(USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT2870) },
{ USB_VP(USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070) },
{ USB_VP(USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070_2) },
+ { USB_VP(USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070_3) },
{ USB_VP(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_RT2870) },
{ USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS300MINIS) },
{ USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRON) },
@@ -212,7 +239,9 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3070) },
{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3071) },
{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3072) },
+ { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3370) },
{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3572) },
+ { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT8070) },
{ USB_VP(USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_RT2870_1) },
{ USB_VP(USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_1) },
{ USB_VP(USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_2) },
@@ -234,6 +263,7 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_2) },
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_3) },
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_4) },
+ { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3071) },
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_1) },
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_2) },
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_3) },
@@ -243,8 +273,10 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL608) },
{ USB_VP(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2870_1) },
{ USB_VP(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT3070) },
+ { USB_VP(USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW153) },
{ USB_VP(USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW303) },
{ USB_VP(USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW313) },
+ { USB_VP(USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_RT3070) },
{ USB_VP(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_RT2870_1) },
{ USB_VP(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_1) },
{ USB_VP(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_2) },
@@ -254,10 +286,10 @@ static const struct usb_device_id run_devs[] = {
{ USB_VP(USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3072_1) },
{ USB_VP(USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3072_2) },
{ USB_VP(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_1) },
+ { USB_VP(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_2) },
};
MODULE_DEPEND(run, wlan, 1, 1, 1);
-MODULE_DEPEND(run, wlan_amrr, 1, 1, 1);
MODULE_DEPEND(run, usb, 1, 1, 1);
MODULE_DEPEND(run, firmware, 1, 1, 1);
@@ -317,9 +349,9 @@ static int run_key_set(struct ieee80211vap *, const struct ieee80211_key *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
static int run_key_delete(struct ieee80211vap *,
const struct ieee80211_key *);
-static void run_amrr_start(struct run_softc *, struct ieee80211_node *);
-static void run_amrr_to(void *);
-static void run_amrr_cb(void *, int);
+static void run_ratectl_start(struct run_softc *, struct ieee80211_node *);
+static void run_ratectl_to(void *);
+static void run_ratectl_cb(void *, int);
static void run_iter_func(void *, struct ieee80211_node *);
static void run_newassoc(struct ieee80211_node *, int);
static void run_rx_frame(struct run_softc *, struct mbuf *, uint32_t);
@@ -340,10 +372,12 @@ static int run_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void run_start(struct ifnet *);
static int run_ioctl(struct ifnet *, u_long, caddr_t);
+static void run_set_agc(struct run_softc *, uint8_t);
static void run_select_chan_group(struct run_softc *, int);
static void run_set_rx_antenna(struct run_softc *, int);
static void run_rt2870_set_chan(struct run_softc *, u_int);
static void run_rt3070_set_chan(struct run_softc *, u_int);
+static void run_rt3572_set_chan(struct run_softc *, u_int);
static int run_set_chan(struct run_softc *, struct ieee80211_channel *);
static void run_set_channel(struct ieee80211com *);
static void run_scan_start(struct ieee80211com *);
@@ -369,6 +403,7 @@ static int run_bbp_init(struct run_softc *);
static int run_rt3070_rf_init(struct run_softc *);
static int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
uint8_t *);
+static void run_rt3070_rf_setup(struct run_softc *);
static int run_txrx_enable(struct run_softc *);
static void run_init(void *);
static void run_init_locked(struct run_softc *);
@@ -398,8 +433,8 @@ static const struct rfprog {
struct {
uint8_t n, r, k;
-} run_rf3020_freqs[] = {
- RT3070_RF3020
+} rt3070_freqs[] = {
+ RT3070_RF3052
};
static const struct {
@@ -407,6 +442,8 @@ static const struct {
uint8_t val;
} rt3070_def_rf[] = {
RT3070_DEF_RF
+},rt3572_def_rf[] = {
+ RT3572_DEF_RF
};
static const struct usb_config run_config[RUN_N_XFER] = {
@@ -502,6 +539,7 @@ run_attach(device_t self)
struct usb_attach_arg *uaa = device_get_ivars(self);
struct ieee80211com *ic;
struct ifnet *ifp;
+ uint32_t ver;
int i, ntries, error;
uint8_t iface_index, bands;
@@ -513,11 +551,10 @@ run_attach(device_t self)
MTX_NETWORK_LOCK, MTX_DEF);
iface_index = RT2860_IFACE_INDEX;
- /* Rx transfer has own lock */
error = usbd_transfer_setup(uaa->device, &iface_index,
sc->sc_xfer, run_config, RUN_N_XFER, sc, &sc->sc_mtx);
if (error) {
- device_printf(self, "could not allocate USB Tx transfers, "
+ device_printf(self, "could not allocate USB transfers, "
"err=%s\n", usbd_errstr(error));
goto detach;
}
@@ -526,11 +563,11 @@ run_attach(device_t self)
/* wait for the chip to settle */
for (ntries = 0; ntries < 100; ntries++) {
- if (run_read(sc, RT2860_ASIC_VER_ID, &sc->mac_rev) != 0){
+ if (run_read(sc, RT2860_ASIC_VER_ID, &ver) != 0){
RUN_UNLOCK(sc);
goto detach;
}
- if (sc->mac_rev != 0 && sc->mac_rev != 0xffffffff)
+ if (ver != 0 && ver != 0xffffffff)
break;
run_delay(sc, 10);
}
@@ -540,13 +577,15 @@ run_attach(device_t self)
RUN_UNLOCK(sc);
goto detach;
}
+ sc->mac_ver = ver >> 16;
+ sc->mac_rev = ver & 0xffff;
/* retrieve RF rev. no and various other things from EEPROM */
run_read_eeprom(sc);
device_printf(sc->sc_dev,
"MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n",
- sc->mac_rev >> 16, sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev),
+ sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev),
sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
if ((error = run_load_microcode(sc)) != 0) {
@@ -609,7 +648,9 @@ run_attach(device_t self)
* Do this by own because h/w supports
* more channels than ieee80211_init_channels()
*/
- if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) {
+ if (sc->rf_rev == RT2860_RF_2750 ||
+ sc->rf_rev == RT2860_RF_2850 ||
+ sc->rf_rev == RT3070_RF_3052) {
/* set supported .11a rates */
for (i = 14; i < nitems(rt2860_rf2850); i++) {
uint8_t chan = rt2860_rf2850[i].chan;
@@ -712,14 +753,12 @@ run_vap_create(struct ieee80211com *ic,
rvp->newstate = vap->iv_newstate;
vap->iv_newstate = run_newstate;
- TASK_INIT(&rvp->amrr_task, 0, run_amrr_cb, rvp);
+ TASK_INIT(&rvp->ratectl_task, 0, run_ratectl_cb, rvp);
TASK_INIT(&sc->wme_task, 0, run_wme_update_cb, ic);
TASK_INIT(&sc->usb_timeout_task, 0, run_usb_timeout_cb, sc);
- callout_init((struct callout *)&rvp->amrr_ch, 1);
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
+ callout_init((struct callout *)&rvp->ratectl_ch, 1);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status);
@@ -743,13 +782,17 @@ run_vap_delete(struct ieee80211vap *vap)
sc = ifp->if_softc;
- if (ifp && ifp->if_flags & IFF_UP){
- RUN_LOCK(sc);
- run_stop(sc);
- RUN_UNLOCK(sc);
- }
+ RUN_LOCK(sc);
+ sc->sc_rvp->ratectl_run = RUN_RATECTL_OFF;
+ RUN_UNLOCK(sc);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ /* drain them all */
+ usb_callout_drain(&sc->sc_rvp->ratectl_ch);
+ ieee80211_draintask(ic, &sc->sc_rvp->ratectl_task);
+ ieee80211_draintask(ic, &sc->wme_task);
+ ieee80211_draintask(ic, &sc->usb_timeout_task);
+
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
sc->sc_rvp = NULL;
@@ -808,7 +851,9 @@ run_load_microcode(struct run_softc *sc)
const uint64_t *temp;
uint64_t bytes;
+ RUN_UNLOCK(sc);
fw = firmware_get("runfw");
+ RUN_LOCK(sc);
if(fw == NULL){
device_printf(sc->sc_dev,
"failed loadfirmware of file %s\n", "runfw");
@@ -829,14 +874,11 @@ run_load_microcode(struct run_softc *sc)
* last half is for rt3071.
*/
base = fw->data;
- if ((sc->mac_rev >> 16) != 0x2860 &&
- (sc->mac_rev >> 16) != 0x2872 &&
- (sc->mac_rev >> 16) != 0x3070 &&
- (sc->mac_rev >> 16) != 0x3572){
+ if ((sc->mac_ver) != 0x2860 &&
+ (sc->mac_ver) != 0x2872 &&
+ (sc->mac_ver) != 0x3070){
base += 4096;
- device_printf(sc->sc_dev, "loading RT3071 firmware\n");
- } else
- device_printf(sc->sc_dev, "loading RT2870 firmware\n");
+ }
/* cheap sanity check */
temp = fw->data;
@@ -866,7 +908,7 @@ run_load_microcode(struct run_softc *sc)
run_delay(sc, 10);
run_write(sc, RT2860_H2M_MAILBOX, 0);
- if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_BOOT, 0)) != 0)
+ if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0)
goto fail;
/* wait until microcontroller is ready */
@@ -884,7 +926,8 @@ run_load_microcode(struct run_softc *sc)
error = ETIMEDOUT;
goto fail;
}
- DPRINTF("microcode successfully loaded after %d tries\n", ntries);
+ device_printf(sc->sc_dev, "firmware %s loaded\n",
+ (base == fw->data) ? "RT2870" : "RT3071");
fail:
firmware_put(fw, FIRMWARE_UNLOAD);
@@ -1283,7 +1326,7 @@ run_read_eeprom(struct run_softc *sc)
/* check whether the ROM is eFUSE ROM or EEPROM */
sc->sc_srom_read = run_eeprom_read_2;
- if ((sc->mac_rev & 0xfff00000) >= 0x30700000) {
+ if (sc->mac_ver >= 0x3070) {
run_read(sc, RT3070_EFUSE_CTRL, &tmp);
DPRINTF("EFUSE_CTRL=0x%08x\n", tmp);
if (tmp & RT3070_SEL_EFUSE)
@@ -1305,21 +1348,32 @@ run_read_eeprom(struct run_softc *sc)
sc->sc_bssid[4] = val & 0xff;
sc->sc_bssid[5] = val >> 8;
- /* read default BBP settings */
- for (i = 0; i < 8; i++) {
+ /* read vender BBP settings */
+ for (i = 0; i < 10; i++) {
run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val);
sc->bbp[i].val = val & 0xff;
sc->bbp[i].reg = val >> 8;
DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val);
}
+ if (sc->mac_ver >= 0x3071) {
+ /* read vendor RF settings */
+ for (i = 0; i < 10; i++) {
+ run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val);
+ sc->rf[i].val = val & 0xff;
+ sc->rf[i].reg = val >> 8;
+ DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg,
+ sc->rf[i].val);
+ }
+ }
/* read RF frequency offset from EEPROM */
run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val);
sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
DPRINTF("EEPROM freq offset %d\n", sc->freq & 0xff);
- if ((sc->leds = val >> 8) != 0xff) {
+ if (val >> 8 != 0xff) {
/* read LEDs operating mode */
+ sc->leds = val >> 8;
run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]);
run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]);
run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]);
@@ -1337,7 +1391,12 @@ run_read_eeprom(struct run_softc *sc)
run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
if (val == 0xffff) {
DPRINTF("invalid EEPROM antenna info, using default\n");
- if ((sc->mac_rev >> 16) >= 0x3070) {
+ if (sc->mac_ver == 0x3572) {
+ /* default to RF3052 2T2R */
+ sc->rf_rev = RT3070_RF_3052;
+ sc->ntxchains = 2;
+ sc->nrxchains = 2;
+ } else if (sc->mac_ver >= 0x3070) {
/* default to RF3020 1T1R */
sc->rf_rev = RT3070_RF_3020;
sc->ntxchains = 1;
@@ -1356,13 +1415,18 @@ run_read_eeprom(struct run_softc *sc)
DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n",
sc->rf_rev, sc->ntxchains, sc->nrxchains);
- /* check if RF supports automatic Tx access gain control */
run_srom_read(sc, RT2860_EEPROM_CONFIG, &val);
DPRINTF("EEPROM CFG 0x%04x\n", val);
+ /* check if driver should patch the DAC issue */
+ if ((val >> 8) != 0xff)
+ sc->patch_dac = (val >> 15) & 1;
if ((val & 0xff) != 0xff) {
sc->ext_5ghz_lna = (val >> 3) & 1;
sc->ext_2ghz_lna = (val >> 2) & 1;
+ /* check if RF supports automatic Tx access gain control */
sc->calib_2ghz = sc->calib_5ghz = (val >> 1) & 1;
+ /* check if we have a hardware radio switch */
+ sc->rfswitch = val & 1;
}
/* read power settings for 2GHz channels */
@@ -1385,7 +1449,7 @@ run_read_eeprom(struct run_softc *sc)
rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]);
}
/* read power settings for 5GHz channels */
- for (i = 0; i < 36; i += 2) {
+ for (i = 0; i < 40; i += 2) {
run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val);
sc->txpow1[i + 14] = (int8_t)(val & 0xff);
sc->txpow1[i + 15] = (int8_t)(val >> 8);
@@ -1395,7 +1459,7 @@ run_read_eeprom(struct run_softc *sc)
sc->txpow2[i + 15] = (int8_t)(val >> 8);
}
/* fix broken Tx power entries */
- for (i = 0; i < 36; i++) {
+ for (i = 0; i < 40; i++) {
if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
sc->txpow1[14 + i] = 5;
if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
@@ -1444,14 +1508,32 @@ run_read_eeprom(struct run_softc *sc)
sc->rssi_2ghz[0] = val & 0xff; /* Ant A */
sc->rssi_2ghz[1] = val >> 8; /* Ant B */
run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val);
- sc->rssi_2ghz[2] = val & 0xff; /* Ant C */
+ if (sc->mac_ver >= 0x3070) {
+ /*
+ * On RT3070 chips (limited to 2 Rx chains), this ROM
+ * field contains the Tx mixer gain for the 2GHz band.
+ */
+ if ((val & 0xff) != 0xff)
+ sc->txmixgain_2ghz = val & 0x7;
+ DPRINTF("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz);
+ } else
+ sc->rssi_2ghz[2] = val & 0xff; /* Ant C */
sc->lna[2] = val >> 8; /* channel group 2 */
run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val);
sc->rssi_5ghz[0] = val & 0xff; /* Ant A */
sc->rssi_5ghz[1] = val >> 8; /* Ant B */
run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val);
- sc->rssi_5ghz[2] = val & 0xff; /* Ant C */
+ if (sc->mac_ver == 0x3572) {
+ /*
+ * On RT3572 chips (limited to 2 Rx chains), this ROM
+ * field contains the Tx mixer gain for the 5GHz band.
+ */
+ if ((val & 0xff) != 0xff)
+ sc->txmixgain_5ghz = val & 0x7;
+ DPRINTF("tx mixer gain=%u (5GHz)\n", sc->txmixgain_5ghz);
+ } else
+ sc->rssi_5ghz[2] = val & 0xff; /* Ant C */
sc->lna[3] = val >> 8; /* channel group 3 */
run_srom_read(sc, RT2860_EEPROM_LNA, &val);
@@ -1547,8 +1629,8 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
RUN_LOCK(sc);
- sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
- usb_callout_stop(&rvp->amrr_ch);
+ sc->sc_rvp->ratectl_run = RUN_RATECTL_OFF;
+ usb_callout_stop(&rvp->ratectl_ch);
if (ostate == IEEE80211_S_RUN) {
/* turn link LED off */
@@ -1596,7 +1678,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* enable automatic rate adaptation */
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- run_amrr_start(sc, ni);
+ run_ratectl_start(sc, ni);
/* turn link LED on */
run_set_leds(sc, RT2860_LED_RADIO |
@@ -1876,12 +1958,11 @@ fail:
}
static void
-run_amrr_start(struct run_softc *sc, struct ieee80211_node *ni)
+run_ratectl_start(struct run_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct run_vap *rvp = RUN_VAP(vap);
uint32_t sta[3];
- uint8_t wcid;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -1889,30 +1970,29 @@ run_amrr_start(struct run_softc *sc, struct ieee80211_node *ni)
run_read_region_1(sc, RT2860_TX_STA_CNT0,
(uint8_t *)sta, sizeof sta);
- wcid = RUN_AID2WCID(ni == NULL ? 0 : ni->ni_associd);
- ieee80211_amrr_node_init(&rvp->amrr, &rvp->amn[wcid], ni);
+ ieee80211_ratectl_node_init(ni);
/* start at lowest available bit-rate, AMRR will raise */
ni->ni_txrate = 2;
/* start calibration timer */
- rvp->amrr_run = RUN_AMRR_ON;
- usb_callout_reset(&rvp->amrr_ch, hz, run_amrr_to, rvp);
+ rvp->ratectl_run = RUN_RATECTL_ON;
+ usb_callout_reset(&rvp->ratectl_ch, hz, run_ratectl_to, rvp);
}
static void
-run_amrr_to(void *arg)
+run_ratectl_to(void *arg)
{
struct run_vap *rvp = arg;
/* do it in a process context, so it can go sleep */
- ieee80211_runtask(rvp->vap.iv_ic, &rvp->amrr_task);
+ ieee80211_runtask(rvp->vap.iv_ic, &rvp->ratectl_task);
/* next timeout will be rescheduled in the callback task */
}
/* ARGSUSED */
static void
-run_amrr_cb(void *arg, int pending)
+run_ratectl_cb(void *arg, int pending)
{
struct run_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
@@ -1935,8 +2015,8 @@ run_amrr_cb(void *arg, int pending)
ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, rvp);
}
- if(rvp->amrr_run == RUN_AMRR_ON)
- usb_callout_reset(&rvp->amrr_ch, hz, run_amrr_to, rvp);
+ if(rvp->ratectl_run == RUN_RATECTL_ON)
+ usb_callout_reset(&rvp->ratectl_ch, hz, run_ratectl_to, rvp);
}
@@ -1948,10 +2028,11 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
struct ifnet *ifp = ic->ic_ifp;
struct run_softc *sc = ifp->if_softc;
struct ieee80211_node_table *nt = &ic->ic_sta;
- struct ieee80211_amrr_node *amn = &rvp->amn[0]; /* make compiler happy */
uint32_t sta[3], stat;
int error;
uint8_t wcid, mcs, pid;
+ struct ieee80211vap *vap = ni->ni_vap;
+ int txcnt = 0, success = 0, retrycnt = 0;
if(ic->ic_opmode != IEEE80211_M_STA)
IEEE80211_NODE_ITERATE_UNLOCK(nt);
@@ -1971,10 +2052,7 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
continue;
/* update per-STA AMRR stats */
- amn = &rvp->amn[wcid];
- amn->amn_txcnt++;
if (stat & RT2860_TXQ_OK) {
- amn->amn_success++;
/*
* Check if there were retries, ie if the Tx
* success rate is different from the requested
@@ -1984,16 +2062,20 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
mcs = (stat >> RT2860_TXQ_MCS_SHIFT) & 0x7f;
pid = (stat >> RT2860_TXQ_PID_SHIFT) & 0xf;
if (mcs + 1 != pid)
- amn->amn_retrycnt++;
+ retrycnt = 1;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
} else {
- amn->amn_retrycnt++;
+ retrycnt = 1;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_oerrors++;
}
run_read_region_1(sc, RT2860_TX_STAT_FIFO,
(uint8_t *)&stat, sizeof stat);
}
- DPRINTFN(3, "retrycnt=%d txcnt=%d success=%d\n",
- amn->amn_retrycnt, amn->amn_txcnt, amn->amn_success);
} else {
/* read statistic counters (clear on read) and update AMRR state */
error = run_read_region_1(sc, RT2860_TX_STA_CNT0, (uint8_t *)sta,
@@ -2005,26 +2087,25 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
le32toh(sta[1]) >> 16, le32toh(sta[1]) & 0xffff,
le32toh(sta[0]) & 0xffff);
- wcid = RUN_AID2WCID(ni == NULL ? 0 : ni->ni_associd);
- amn = &rvp->amn[wcid];
-
/* count failed TX as errors */
ifp->if_oerrors += le32toh(sta[0]) & 0xffff;
- amn->amn_retrycnt =
+ retrycnt =
(le32toh(sta[0]) & 0xffff) + /* failed TX count */
(le32toh(sta[1]) >> 16); /* TX retransmission count */
- amn->amn_txcnt =
- amn->amn_retrycnt +
+ txcnt =
+ retrycnt +
(le32toh(sta[1]) & 0xffff); /* successful TX count */
- amn->amn_success =
+ success =
(le32toh(sta[1]) >> 16) +
(le32toh(sta[1]) & 0xffff);
+ ieee80211_ratectl_tx_update(vap, ni, &txcnt, &success,
+ &retrycnt);
}
- ieee80211_amrr_choose(ni, amn);
+ ieee80211_ratectl_rate(ni, NULL, 0);
skip:;
RUN_UNLOCK(sc);
@@ -2639,7 +2720,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
dur = rt2860_rates[ridx].sp_ack_dur;
else
dur = rt2860_rates[ridx].lp_ack_dur;
- *(uint16_t *)wh->i_dur = htole16(dur + sc->sifs);
+ *(uint16_t *)wh->i_dur = htole16(dur);
}
/* reserve slots for mgmt packets, just in case */
@@ -3006,9 +3087,26 @@ run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
static void
+run_set_agc(struct run_softc *sc, uint8_t agc)
+{
+ uint8_t bbp;
+
+ if (sc->mac_ver == 0x3572) {
+ run_bbp_read(sc, 27, &bbp);
+ bbp &= ~(0x3 << 5);
+ run_bbp_write(sc, 27, bbp | 0 << 5); /* select Rx0 */
+ run_bbp_write(sc, 66, agc);
+ run_bbp_write(sc, 27, bbp | 1 << 5); /* select Rx1 */
+ run_bbp_write(sc, 66, agc);
+ } else
+ run_bbp_write(sc, 66, agc);
+}
+
+static void
run_select_chan_group(struct run_softc *sc, int group)
{
uint32_t tmp;
+ uint8_t agc;
run_bbp_write(sc, 62, 0x37 - sc->lna[group]);
run_bbp_write(sc, 63, 0x37 - sc->lna[group]);
@@ -3024,13 +3122,14 @@ run_select_chan_group(struct run_softc *sc, int group)
run_bbp_write(sc, 75, 0x50);
}
} else {
- if (sc->ext_5ghz_lna) {
+ if (sc->mac_ver == 0x3572)
+ run_bbp_write(sc, 82, 0x94);
+ else
run_bbp_write(sc, 82, 0xf2);
+ if (sc->ext_5ghz_lna)
run_bbp_write(sc, 75, 0x46);
- } else {
- run_bbp_write(sc, 82, 0xf2);
+ else
run_bbp_write(sc, 75, 0x50);
- }
}
run_read(sc, RT2860_TX_BAND_CFG, &tmp);
@@ -3053,13 +3152,26 @@ run_select_chan_group(struct run_softc *sc, int group)
if (sc->nrxchains > 1)
tmp |= RT2860_LNA_PE_A1_EN;
}
- run_write(sc, RT2860_TX_PIN_CFG, tmp);
+ if (sc->mac_ver == 0x3572) {
+ run_rt3070_rf_write(sc, 8, 0x00);
+ run_write(sc, RT2860_TX_PIN_CFG, tmp);
+ run_rt3070_rf_write(sc, 8, 0x80);
+ } else
+ run_write(sc, RT2860_TX_PIN_CFG, tmp);
/* set initial AGC value */
- if (group == 0)
- run_bbp_write(sc, 66, 0x2e + sc->lna[0]);
- else
- run_bbp_write(sc, 66, 0x32 + (sc->lna[group] * 5) / 3);
+ if (group == 0) { /* 2GHz band */
+ if (sc->mac_ver >= 0x3070)
+ agc = 0x1c + sc->lna[0] * 2;
+ else
+ agc = 0x2e + sc->lna[0];
+ } else { /* 5GHz band */
+ if (sc->mac_ver == 0x3572)
+ agc = 0x22 + (sc->lna[group] * 5) / 3;
+ else
+ agc = 0x32 + (sc->lna[group] * 5) / 3;
+ }
+ run_set_agc(sc, agc);
}
static void
@@ -3122,18 +3234,22 @@ run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
{
int8_t txpow1, txpow2;
uint8_t rf;
+ int i;
/* RT3070 is 2GHz only */
KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n"));
+ /* find the settings for this channel (we know it exists) */
+ for (i = 0; rt2860_rf2850[i].chan != chan; i++);
+
/* use Tx power values from EEPROM */
- txpow1 = sc->txpow1[chan - 1];
- txpow2 = sc->txpow2[chan - 1];
+ txpow1 = sc->txpow1[i];
+ txpow2 = sc->txpow2[i];
- run_rt3070_rf_write(sc, 2, run_rf3020_freqs[chan - 1].n);
- run_rt3070_rf_write(sc, 3, run_rf3020_freqs[chan - 1].k);
+ run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
+ run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
run_rt3070_rf_read(sc, 6, &rf);
- rf = (rf & ~0x03) | run_rf3020_freqs[chan - 1].r;
+ rf = (rf & ~0x03) | rt3070_freqs[i].r;
run_rt3070_rf_write(sc, 6, rf);
/* set Tx0 power */
@@ -3164,12 +3280,166 @@ run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
run_rt3070_rf_write(sc, 23, rf);
/* program RF filter */
- run_rt3070_rf_write(sc, 24, sc->rf24_20mhz);
- run_rt3070_rf_write(sc, 31, sc->rf24_20mhz);
+ run_rt3070_rf_read(sc, 24, &rf); /* Tx */
+ rf = (rf & ~0x3f) | sc->rf24_20mhz;
+ run_rt3070_rf_write(sc, 24, rf);
+ run_rt3070_rf_read(sc, 31, &rf); /* Rx */
+ rf = (rf & ~0x3f) | sc->rf24_20mhz;
+ run_rt3070_rf_write(sc, 31, rf);
+
+ /* enable RF tuning */
+ run_rt3070_rf_read(sc, 7, &rf);
+ run_rt3070_rf_write(sc, 7, rf | 0x01);
+}
+
+static void
+run_rt3572_set_chan(struct run_softc *sc, u_int chan)
+{
+ int8_t txpow1, txpow2;
+ uint32_t tmp;
+ uint8_t rf;
+ int i;
+
+ /* find the settings for this channel (we know it exists) */
+ for (i = 0; rt2860_rf2850[i].chan != chan; i++);
+
+ /* use Tx power values from EEPROM */
+ txpow1 = sc->txpow1[i];
+ txpow2 = sc->txpow2[i];
+
+ if (chan <= 14) {
+ run_bbp_write(sc, 25, sc->bbp25);
+ run_bbp_write(sc, 26, sc->bbp26);
+ } else {
+ /* enable IQ phase correction */
+ run_bbp_write(sc, 25, 0x09);
+ run_bbp_write(sc, 26, 0xff);
+ }
+
+ run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
+ run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
+ run_rt3070_rf_read(sc, 6, &rf);
+ rf = (rf & ~0x0f) | rt3070_freqs[i].r;
+ rf |= (chan <= 14) ? 0x08 : 0x04;
+ run_rt3070_rf_write(sc, 6, rf);
+
+ /* set PLL mode */
+ run_rt3070_rf_read(sc, 5, &rf);
+ rf &= ~(0x08 | 0x04);
+ rf |= (chan <= 14) ? 0x04 : 0x08;
+ run_rt3070_rf_write(sc, 5, rf);
+
+ /* set Tx power for chain 0 */
+ if (chan <= 14)
+ rf = 0x60 | txpow1;
+ else
+ rf = 0xe0 | (txpow1 & 0xc) << 1 | (txpow1 & 0x3);
+ run_rt3070_rf_write(sc, 12, rf);
+
+ /* set Tx power for chain 1 */
+ if (chan <= 14)
+ rf = 0x60 | txpow2;
+ else
+ rf = 0xe0 | (txpow2 & 0xc) << 1 | (txpow2 & 0x3);
+ run_rt3070_rf_write(sc, 13, rf);
+
+ /* set Tx/Rx streams */
+ run_rt3070_rf_read(sc, 1, &rf);
+ rf &= ~0xfc;
+ if (sc->ntxchains == 1)
+ rf |= 1 << 7 | 1 << 5; /* 1T: disable Tx chains 2 & 3 */
+ else if (sc->ntxchains == 2)
+ rf |= 1 << 7; /* 2T: disable Tx chain 3 */
+ if (sc->nrxchains == 1)
+ rf |= 1 << 6 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */
+ else if (sc->nrxchains == 2)
+ rf |= 1 << 6; /* 2R: disable Rx chain 3 */
+ run_rt3070_rf_write(sc, 1, rf);
+
+ /* set RF offset */
+ run_rt3070_rf_read(sc, 23, &rf);
+ rf = (rf & ~0x7f) | sc->freq;
+ run_rt3070_rf_write(sc, 23, rf);
+
+ /* program RF filter */
+ rf = sc->rf24_20mhz;
+ run_rt3070_rf_write(sc, 24, rf); /* Tx */
+ run_rt3070_rf_write(sc, 31, rf); /* Rx */
+
+ /* enable RF tuning */
+ run_rt3070_rf_read(sc, 7, &rf);
+ rf = (chan <= 14) ? 0xd8 : ((rf & ~0xc8) | 0x14);
+ run_rt3070_rf_write(sc, 7, rf);
+
+ /* TSSI */
+ rf = (chan <= 14) ? 0xc3 : 0xc0;
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* set loop filter 1 */
+ run_rt3070_rf_write(sc, 10, 0xf1);
+ /* set loop filter 2 */
+ run_rt3070_rf_write(sc, 11, (chan <= 14) ? 0xb9 : 0x00);
+
+ /* set tx_mx2_ic */
+ run_rt3070_rf_write(sc, 15, (chan <= 14) ? 0x53 : 0x43);
+ /* set tx_mx1_ic */
+ if (chan <= 14)
+ rf = 0x48 | sc->txmixgain_2ghz;
+ else
+ rf = 0x78 | sc->txmixgain_5ghz;
+ run_rt3070_rf_write(sc, 16, rf);
+
+ /* set tx_lo1 */
+ run_rt3070_rf_write(sc, 17, 0x23);
+ /* set tx_lo2 */
+ if (chan <= 14)
+ rf = 0x93;
+ else if (chan <= 64)
+ rf = 0xb7;
+ else if (chan <= 128)
+ rf = 0x74;
+ else
+ rf = 0x72;
+ run_rt3070_rf_write(sc, 19, rf);
+
+ /* set rx_lo1 */
+ if (chan <= 14)
+ rf = 0xb3;
+ else if (chan <= 64)
+ rf = 0xf6;
+ else if (chan <= 128)
+ rf = 0xf4;
+ else
+ rf = 0xf3;
+ run_rt3070_rf_write(sc, 20, rf);
+
+ /* set pfd_delay */
+ if (chan <= 14)
+ rf = 0x15;
+ else if (chan <= 64)
+ rf = 0x3d;
+ else
+ rf = 0x01;
+ run_rt3070_rf_write(sc, 25, rf);
+
+ /* set rx_lo2 */
+ run_rt3070_rf_write(sc, 26, (chan <= 14) ? 0x85 : 0x87);
+ /* set ldo_rf_vc */
+ run_rt3070_rf_write(sc, 27, (chan <= 14) ? 0x00 : 0x01);
+ /* set drv_cc */
+ run_rt3070_rf_write(sc, 29, (chan <= 14) ? 0x9b : 0x9f);
+
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ tmp &= ~0x8080;
+ if (chan <= 14)
+ tmp |= 0x80;
+ run_write(sc, RT2860_GPIO_CTRL, tmp);
/* enable RF tuning */
run_rt3070_rf_read(sc, 7, &rf);
run_rt3070_rf_write(sc, 7, rf | 0x01);
+
+ run_delay(sc, 2);
}
static void
@@ -3178,13 +3448,11 @@ run_set_rx_antenna(struct run_softc *sc, int aux)
uint32_t tmp;
if (aux) {
- run_read(sc, RT2860_PCI_EECTRL, &tmp);
- run_write(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C);
+ run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0);
run_read(sc, RT2860_GPIO_CTRL, &tmp);
run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
} else {
- run_read(sc, RT2860_PCI_EECTRL, &tmp);
- run_write(sc, RT2860_PCI_EECTRL, tmp | RT2860_C);
+ run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1);
run_read(sc, RT2860_GPIO_CTRL, &tmp);
run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
}
@@ -3200,14 +3468,13 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return EINVAL;
- if ((sc->mac_rev >> 16) >= 0x3070)
+ if (sc->mac_ver == 0x3572)
+ run_rt3572_set_chan(sc, chan);
+ else if (sc->mac_ver >= 0x3070)
run_rt3070_set_chan(sc, chan);
else
run_rt2870_set_chan(sc, chan);
- /* 802.11a uses a 16 microseconds short interframe space */
- sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
-
/* determine channel group */
if (chan <= 14)
group = 0;
@@ -3373,7 +3640,7 @@ run_usb_timeout_cb(void *arg, int pending)
struct run_softc *sc = arg;
struct ieee80211vap *vap = &sc->sc_rvp->vap;
- RUN_LOCK_ASSERT(sc, MA_OWNED);
+ RUN_LOCK(sc);
if(vap->iv_state == IEEE80211_S_RUN &&
vap->iv_opmode != IEEE80211_M_STA)
@@ -3384,6 +3651,8 @@ run_usb_timeout_cb(void *arg, int pending)
ieee80211_cancel_scan(vap);
} else
DPRINTF("timeout by unknown cause\n");
+
+ RUN_UNLOCK(sc);
}
static void
@@ -3611,15 +3880,14 @@ run_bbp_init(struct run_softc *sc)
}
/* fix BBP84 for RT2860E */
- if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
- run_bbp_write(sc, 84, 0x19);
+ if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101)
+ run_bbp_write(sc, 84, 0x19);
- if ((sc->mac_rev >> 16) >= 0x3070) {
+ if (sc->mac_ver >= 0x3070) {
run_bbp_write(sc, 79, 0x13);
run_bbp_write(sc, 80, 0x05);
run_bbp_write(sc, 81, 0x33);
- /* XXX RT3090 needs more */
- } else if (sc->mac_rev == 0x28600100) {
+ } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) {
run_bbp_write(sc, 69, 0x16);
run_bbp_write(sc, 73, 0x12);
}
@@ -3630,7 +3898,7 @@ static int
run_rt3070_rf_init(struct run_softc *sc)
{
uint32_t tmp;
- uint8_t rf, bbp4;
+ uint8_t rf, target, bbp4;
int i;
run_rt3070_rf_read(sc, 30, &rf);
@@ -3640,44 +3908,58 @@ run_rt3070_rf_init(struct run_softc *sc)
run_rt3070_rf_write(sc, 30, rf & ~0x80);
/* initialize RF registers to default value */
- for (i = 0; i < nitems(rt3070_def_rf); i++) {
- run_rt3070_rf_write(sc, rt3070_def_rf[i].reg,
- rt3070_def_rf[i].val);
+ if (sc->mac_ver == 0x3572) {
+ for (i = 0; i < nitems(rt3572_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt3572_def_rf[i].reg,
+ rt3572_def_rf[i].val);
+ }
+ } else {
+ for (i = 0; i < nitems(rt3070_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt3070_def_rf[i].reg,
+ rt3070_def_rf[i].val);
+ }
}
- if ((sc->mac_rev >> 16) == 0x3070) {
+
+ if (sc->mac_ver == 0x3070) {
/* change voltage from 1.2V to 1.35V for RT3070 */
run_read(sc, RT3070_LDO_CFG0, &tmp);
tmp = (tmp & ~0x0f000000) | 0x0d000000;
run_write(sc, RT3070_LDO_CFG0, tmp);
- } else if ((sc->mac_rev >> 16) == 0x3071) {
+ } else if (sc->mac_ver == 0x3071) {
run_rt3070_rf_read(sc, 6, &rf);
run_rt3070_rf_write(sc, 6, rf | 0x40);
run_rt3070_rf_write(sc, 31, 0x14);
run_read(sc, RT3070_LDO_CFG0, &tmp);
tmp &= ~0x1f000000;
- if ((sc->mac_rev & 0xffff) < 0x0211)
- tmp |= 0x0d000000;
+ if (sc->mac_rev < 0x0211)
+ tmp |= 0x0d000000; /* 1.3V */
else
- tmp |= 0x01000000;
+ tmp |= 0x01000000; /* 1.2V */
run_write(sc, RT3070_LDO_CFG0, tmp);
/* patch LNA_PE_G1 */
run_read(sc, RT3070_GPIO_SWITCH, &tmp);
run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
- } else if((sc->mac_rev >> 16) == 0x3572){
- if ((sc->mac_rev & 0xffff) < 0x0211){
+ } else if(sc->mac_ver == 0x3572){
+ run_rt3070_rf_read(sc, 6, &rf);
+ run_rt3070_rf_write(sc, 6, rf | 0x40);
+
+ if (sc->mac_rev < 0x0211){
+ /* increase voltage from 1.2V to 1.35V */
run_read(sc, RT3070_LDO_CFG0, &tmp);
tmp = (tmp & ~0x0f000000) | 0x0d000000;
run_write(sc, RT3070_LDO_CFG0, tmp);
} else {
+ /* increase voltage from 1.2V to 1.35V */
run_read(sc, RT3070_LDO_CFG0, &tmp);
tmp = (tmp & ~0x1f000000) | 0x0d000000;
run_write(sc, RT3070_LDO_CFG0, tmp);
run_delay(sc, 1); /* wait for 1msec */
+ /* decrease voltage back to 1.2V */
tmp = (tmp & ~0x1f000000) | 0x01000000;
run_write(sc, RT3070_LDO_CFG0, tmp);
}
@@ -3689,27 +3971,47 @@ run_rt3070_rf_init(struct run_softc *sc)
/* calibrate filter for 20MHz bandwidth */
sc->rf24_20mhz = 0x1f; /* default value */
- run_rt3070_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz);
+ target = (sc->mac_ver < 0x3071) ? 0x16 : 0x13;
+ run_rt3070_filter_calib(sc, 0x07, target, &sc->rf24_20mhz);
/* select 40MHz bandwidth */
run_bbp_read(sc, 4, &bbp4);
run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10);
+ run_rt3070_rf_read(sc, 31, &rf);
+ run_rt3070_rf_write(sc, 31, rf | 0x20);
/* calibrate filter for 40MHz bandwidth */
sc->rf24_40mhz = 0x2f; /* default value */
- run_rt3070_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz);
+ target = (sc->mac_ver < 0x3071) ? 0x19 : 0x15;
+ run_rt3070_filter_calib(sc, 0x27, target, &sc->rf24_40mhz);
/* go back to 20MHz bandwidth */
run_bbp_read(sc, 4, &bbp4);
run_bbp_write(sc, 4, bbp4 & ~0x18);
- if ((sc->mac_rev & 0xffff) < 0x0211)
+ if (sc->mac_ver == 0x3572) {
+ /* save default BBP registers 25 and 26 values */
+ run_bbp_read(sc, 25, &sc->bbp25);
+ run_bbp_read(sc, 26, &sc->bbp26);
+ } else if (sc->mac_rev < 0x0211)
run_rt3070_rf_write(sc, 27, 0x03);
run_read(sc, RT3070_OPT_14, &tmp);
run_write(sc, RT3070_OPT_14, tmp | 1);
- if ((sc->mac_rev >> 16) == 0x3071) {
+ if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) {
+ run_rt3070_rf_read(sc, 17, &rf);
+ rf &= ~RT3070_TX_LO1;
+ if ((sc->mac_ver == 0x3070 ||
+ (sc->mac_ver == 0x3071 && sc->mac_rev >= 0x0211)) &&
+ !sc->ext_2ghz_lna)
+ rf |= 0x20; /* fix for long range Rx issue */
+ if (sc->txmixgain_2ghz >= 1)
+ rf = (rf & ~0x7) | sc->txmixgain_2ghz;
+ run_rt3070_rf_write(sc, 17, rf);
+ }
+
+ if (sc->mac_rev == 0x3071) {
run_rt3070_rf_read(sc, 1, &rf);
rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD);
rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD;
@@ -3718,21 +4020,18 @@ run_rt3070_rf_init(struct run_softc *sc)
run_rt3070_rf_read(sc, 15, &rf);
run_rt3070_rf_write(sc, 15, rf & ~RT3070_TX_LO2);
- run_rt3070_rf_read(sc, 17, &rf);
- rf &= ~RT3070_TX_LO1;
- if ((sc->mac_rev & 0xffff) >= 0x0211 && !sc->ext_2ghz_lna)
- rf |= 0x20; /* fix for long range Rx issue */
- run_rt3070_rf_write(sc, 17, rf);
-
run_rt3070_rf_read(sc, 20, &rf);
run_rt3070_rf_write(sc, 20, rf & ~RT3070_RX_LO1);
run_rt3070_rf_read(sc, 21, &rf);
run_rt3070_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
+ }
+ if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) {
+ /* fix Tx to Rx IQ glitch by raising RF voltage */
run_rt3070_rf_read(sc, 27, &rf);
rf &= ~0x77;
- if ((sc->mac_rev & 0xffff) < 0x0211)
+ if (sc->mac_rev < 0x0211)
rf |= 0x03;
run_rt3070_rf_write(sc, 27, rf);
}
@@ -3748,7 +4047,8 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
int ntries;
/* program filter */
- rf24 = init; /* initial filter value */
+ run_rt3070_rf_read(sc, 24, &rf24);
+ rf24 = (rf24 & 0xc0) | init; /* initial filter value */
run_rt3070_rf_write(sc, 24, rf24);
/* enable baseband loopback mode */
@@ -3803,6 +4103,86 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
return 0;
}
+static void
+run_rt3070_rf_setup(struct run_softc *sc)
+{
+ uint8_t bbp, rf;
+ int i;
+
+ if (sc->mac_ver == 0x3572) {
+ /* enable DC filter */
+ if (sc->mac_rev >= 0x0201)
+ run_bbp_write(sc, 103, 0xc0);
+
+ run_bbp_read(sc, 138, &bbp);
+ if (sc->ntxchains == 1)
+ bbp |= 0x20; /* turn off DAC1 */
+ if (sc->nrxchains == 1)
+ bbp &= ~0x02; /* turn off ADC1 */
+ run_bbp_write(sc, 138, bbp);
+
+ if (sc->mac_rev >= 0x0211) {
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ run_rt3070_rf_read(sc, 16, &rf);
+ rf = (rf & ~0x07) | sc->txmixgain_2ghz;
+ run_rt3070_rf_write(sc, 16, rf);
+
+ } else if (sc->mac_ver == 0x3071) {
+ /* enable DC filter */
+ if (sc->mac_rev >= 0x0201)
+ run_bbp_write(sc, 103, 0xc0);
+
+ run_bbp_read(sc, 138, &bbp);
+ if (sc->ntxchains == 1)
+ bbp |= 0x20; /* turn off DAC1 */
+ if (sc->nrxchains == 1)
+ bbp &= ~0x02; /* turn off ADC1 */
+ run_bbp_write(sc, 138, bbp);
+
+ if (sc->mac_rev >= 0x0211) {
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ run_write(sc, RT2860_TX_SW_CFG1, 0);
+ if (sc->mac_rev < 0x0211) {
+ run_write(sc, RT2860_TX_SW_CFG2,
+ sc->patch_dac ? 0x2c : 0x0f);
+ } else
+ run_write(sc, RT2860_TX_SW_CFG2, 0);
+
+ } else if (sc->mac_ver == 0x3070) {
+ if (sc->mac_rev >= 0x0201) {
+ /* enable DC filter */
+ run_bbp_write(sc, 103, 0xc0);
+
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
+ if (sc->mac_rev < 0x0211) {
+ run_write(sc, RT2860_TX_SW_CFG1, 0);
+ run_write(sc, RT2860_TX_SW_CFG2, 0x2c);
+ } else
+ run_write(sc, RT2860_TX_SW_CFG2, 0);
+ }
+
+ /* initialize RF registers from ROM for >=RT3071*/
+ if (sc->mac_ver >= 0x3071) {
+ for (i = 0; i < 10; i++) {
+ if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
+ continue;
+ run_rt3070_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
+ }
+ }
+}
+
static int
run_txrx_enable(struct run_softc *sc)
{
@@ -3854,7 +4234,6 @@ run_init_locked(struct run_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = &sc->sc_rvp->vap;
uint32_t tmp;
uint8_t bbp1, bbp3;
int i;
@@ -3921,12 +4300,10 @@ run_init_locked(struct run_softc *sc)
run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344);
run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa);
- if ((sc->mac_rev >> 16) >= 0x3070) {
+ if (sc->mac_ver >= 0x3070) {
/* set delay of PA_PE assertion to 1us (unit of 0.25us) */
run_write(sc, RT2860_TX_SW_CFG0,
4 << RT2860_DLY_PAPE_EN_SHIFT);
- run_write(sc, RT2860_TX_SW_CFG1, 0);
- run_write(sc, RT2860_TX_SW_CFG2, 0x1f);
}
/* wait while MAC is busy */
@@ -3969,7 +4346,7 @@ run_init_locked(struct run_softc *sc)
tmp = (tmp & ~0xff) | 0x1e;
run_write(sc, RT2860_US_CYC_CNT, tmp);
- if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
+ if (sc->mac_rev != 0x0101)
run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f);
run_write(sc, RT2860_WMM_TXOP0_CFG, 0);
@@ -3991,6 +4368,9 @@ run_init_locked(struct run_softc *sc)
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]);
+ if (sc->mac_ver >= 0x3070)
+ run_rt3070_rf_init(sc);
+
/* disable non-existing Rx chains */
run_bbp_read(sc, 3, &bbp3);
bbp3 &= ~(1 << 3 | 1 << 4);
@@ -4006,11 +4386,10 @@ run_init_locked(struct run_softc *sc)
bbp1 &= ~(1 << 3 | 1 << 4);
run_bbp_write(sc, 1, bbp1);
- if ((sc->mac_rev >> 16) >= 0x3070)
- run_rt3070_rf_init(sc);
+ if (sc->mac_ver >= 0x3070)
+ run_rt3070_rf_setup(sc);
/* select default channel */
- vap->iv_bss->ni_chan = ic->ic_curchan; /* ic_bsschan?? */
run_set_chan(sc, ic->ic_curchan);
/* setup initial protection mode */
@@ -4063,25 +4442,21 @@ run_stop(void *arg)
RUN_LOCK_ASSERT(sc, MA_OWNED);
- if (ic->ic_flags & IEEE80211_F_SCAN)
- ieee80211_cancel_scan(&sc->sc_rvp->vap);
+ if(sc->sc_rvp != NULL){
+ sc->sc_rvp->ratectl_run = RUN_RATECTL_OFF;
+ if (ic->ic_flags & IEEE80211_F_SCAN)
+ ieee80211_cancel_scan(&sc->sc_rvp->vap);
+ }
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
run_set_leds(sc, 0); /* turn all LEDs off */
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
-
RUN_UNLOCK(sc);
- /* drain them all */
- usb_callout_drain(&sc->sc_rvp->amrr_ch);
- ieee80211_draintask(ic, &sc->sc_rvp->amrr_task);
- ieee80211_draintask(ic, &sc->wme_task);
for(i = 0; i < RUN_N_XFER; i++)
usbd_transfer_drain(sc->sc_xfer[i]);
- ieee80211_draintask(ic, &sc->usb_timeout_task);
RUN_LOCK(sc);
diff --git a/sys/dev/usb/wlan/if_runreg.h b/sys/dev/usb/wlan/if_runreg.h
index f630fb1..f872fad 100644
--- a/sys/dev/usb/wlan/if_runreg.h
+++ b/sys/dev/usb/wlan/if_runreg.h
@@ -310,7 +310,8 @@
#define RT2860_MCU_CMD_LED1 0x52
#define RT2860_MCU_CMD_LED2 0x53
#define RT2860_MCU_CMD_LED3 0x54
-#define RT2860_MCU_CMD_BOOT 0x72
+#define RT2860_MCU_CMD_RFRESET 0x72
+#define RT2860_MCU_CMD_ANTSEL 0x73
#define RT2860_MCU_CMD_BBP 0x80
#define RT2860_MCU_CMD_PSLEVEL 0x83
@@ -890,6 +891,7 @@ struct rt2860_rxwi {
#define RT2860_EEPROM_TSSI5_5GHZ 0x6e
#define RT2860_EEPROM_RPWR 0x6f
#define RT2860_EEPROM_BBP_BASE 0x78
+#define RT3071_EEPROM_RF_BASE 0x82
#define RT2860_RIDX_CCK1 0
#define RT2860_RIDX_CCK11 3
@@ -903,18 +905,18 @@ static const struct rt2860_rate {
uint16_t sp_ack_dur;
uint16_t lp_ack_dur;
} rt2860_rates[] = {
- { 2, 0, IEEE80211_T_DS, 0, 304, 304 },
- { 4, 1, IEEE80211_T_DS, 1, 248, 152 },
- { 11, 2, IEEE80211_T_DS, 2, 213, 117 },
- { 22, 3, IEEE80211_T_DS, 3, 203, 107 },
- { 12, 0, IEEE80211_T_OFDM, 4, 50, 50 },
- { 18, 1, IEEE80211_T_OFDM, 4, 42, 42 },
- { 24, 2, IEEE80211_T_OFDM, 6, 38, 38 },
- { 36, 3, IEEE80211_T_OFDM, 6, 34, 34 },
- { 48, 4, IEEE80211_T_OFDM, 8, 34, 34 },
- { 72, 5, IEEE80211_T_OFDM, 8, 30, 30 },
- { 96, 6, IEEE80211_T_OFDM, 8, 30, 30 },
- { 108, 7, IEEE80211_T_OFDM, 8, 30, 30 }
+ { 2, 0, IEEE80211_T_DS, 0, 314, 314 },
+ { 4, 1, IEEE80211_T_DS, 1, 258, 162 },
+ { 11, 2, IEEE80211_T_DS, 2, 223, 127 },
+ { 22, 3, IEEE80211_T_DS, 3, 213, 117 },
+ { 12, 0, IEEE80211_T_OFDM, 4, 60, 60 },
+ { 18, 1, IEEE80211_T_OFDM, 4, 52, 52 },
+ { 24, 2, IEEE80211_T_OFDM, 6, 48, 48 },
+ { 36, 3, IEEE80211_T_OFDM, 6, 44, 44 },
+ { 48, 4, IEEE80211_T_OFDM, 8, 44, 44 },
+ { 72, 5, IEEE80211_T_OFDM, 8, 40, 40 },
+ { 96, 6, IEEE80211_T_OFDM, 8, 40, 40 },
+ { 108, 7, IEEE80211_T_OFDM, 8, 40, 40 }
};
/*
@@ -1034,7 +1036,8 @@ static const struct rt2860_rate {
{ 91, 0x04 }, \
{ 92, 0x00 }, \
{ 103, 0x00 }, \
- { 105, 0x05 }
+ { 105, 0x05 }, \
+ { 106, 0x35 }
/*
* Default settings for RF registers; values derived from the reference driver.
@@ -1088,8 +1091,13 @@ static const struct rt2860_rate {
{ 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 }, \
{ 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 }, \
{ 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 }, \
- { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }
+ { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }, \
+ { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 }, \
+ { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 }, \
+ { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 }, \
+ { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 }
+#if 0
#define RT3070_RF3020 \
{ 241, 2, 2 }, \
{ 241, 2, 7 }, \
@@ -1105,6 +1113,62 @@ static const struct rt2860_rate {
{ 246, 2, 7 }, \
{ 247, 2, 2 }, \
{ 248, 2, 4 }
+#endif
+
+#define RT3070_RF3052 \
+ { 0xf1, 2, 2 }, \
+ { 0xf1, 2, 7 }, \
+ { 0xf2, 2, 2 }, \
+ { 0xf2, 2, 7 }, \
+ { 0xf3, 2, 2 }, \
+ { 0xf3, 2, 7 }, \
+ { 0xf4, 2, 2 }, \
+ { 0xf4, 2, 7 }, \
+ { 0xf5, 2, 2 }, \
+ { 0xf5, 2, 7 }, \
+ { 0xf6, 2, 2 }, \
+ { 0xf6, 2, 7 }, \
+ { 0xf7, 2, 2 }, \
+ { 0xf8, 2, 4 }, \
+ { 0x56, 0, 4 }, \
+ { 0x56, 0, 6 }, \
+ { 0x56, 0, 8 }, \
+ { 0x57, 0, 0 }, \
+ { 0x57, 0, 2 }, \
+ { 0x57, 0, 4 }, \
+ { 0x57, 0, 8 }, \
+ { 0x57, 0, 10 }, \
+ { 0x58, 0, 0 }, \
+ { 0x58, 0, 4 }, \
+ { 0x58, 0, 6 }, \
+ { 0x58, 0, 8 }, \
+ { 0x5b, 0, 8 }, \
+ { 0x5b, 0, 10 }, \
+ { 0x5c, 0, 0 }, \
+ { 0x5c, 0, 4 }, \
+ { 0x5c, 0, 6 }, \
+ { 0x5c, 0, 8 }, \
+ { 0x5d, 0, 0 }, \
+ { 0x5d, 0, 2 }, \
+ { 0x5d, 0, 4 }, \
+ { 0x5d, 0, 8 }, \
+ { 0x5d, 0, 10 }, \
+ { 0x5e, 0, 0 }, \
+ { 0x5e, 0, 4 }, \
+ { 0x5e, 0, 6 }, \
+ { 0x5e, 0, 8 }, \
+ { 0x5f, 0, 0 }, \
+ { 0x5f, 0, 9 }, \
+ { 0x5f, 0, 11 }, \
+ { 0x60, 0, 1 }, \
+ { 0x60, 0, 5 }, \
+ { 0x60, 0, 7 }, \
+ { 0x60, 0, 9 }, \
+ { 0x61, 0, 1 }, \
+ { 0x61, 0, 3 }, \
+ { 0x61, 0, 5 }, \
+ { 0x61, 0, 7 }, \
+ { 0x61, 0, 9 }
#define RT3070_DEF_RF \
{ 4, 0x40 }, \
@@ -1127,4 +1191,37 @@ static const struct rt2860_rate {
{ 25, 0x01 }, \
{ 29, 0x1f }
+#define RT3572_DEF_RF \
+ { 0, 0x70 }, \
+ { 1, 0x81 }, \
+ { 2, 0xf1 }, \
+ { 3, 0x02 }, \
+ { 4, 0x4c }, \
+ { 5, 0x05 }, \
+ { 6, 0x4a }, \
+ { 7, 0xd8 }, \
+ { 9, 0xc3 }, \
+ { 10, 0xf1 }, \
+ { 11, 0xb9 }, \
+ { 12, 0x70 }, \
+ { 13, 0x65 }, \
+ { 14, 0xa0 }, \
+ { 15, 0x53 }, \
+ { 16, 0x4c }, \
+ { 17, 0x23 }, \
+ { 18, 0xac }, \
+ { 19, 0x93 }, \
+ { 20, 0xb3 }, \
+ { 21, 0xd0 }, \
+ { 22, 0x00 }, \
+ { 23, 0x3c }, \
+ { 24, 0x16 }, \
+ { 25, 0x15 }, \
+ { 26, 0x85 }, \
+ { 27, 0x00 }, \
+ { 28, 0x00 }, \
+ { 29, 0x9b }, \
+ { 30, 0x09 }, \
+ { 31, 0x10 }
+
#endif /* _IF_RUNREG_H_ */
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index 28d6feb..a7f8f1f 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -2,7 +2,8 @@
/*-
* Copyright (c) 2008,2009 Damien Bergamini <damien.bergamini@free.fr>
- * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
+ * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
+ * USB Consulting, Hans Petter Selasky <hselasky@freebsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -106,13 +107,11 @@ struct run_node {
struct run_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct ieee80211_amrr_node amn[RT2870_WCID_MAX + 1];
- struct usb_callout amrr_ch;
- struct task amrr_task;
- uint8_t amrr_run;
-#define RUN_AMRR_ON 1
-#define RUN_AMRR_OFF 0
+ struct usb_callout ratectl_ch;
+ struct task ratectl_task;
+ uint8_t ratectl_run;
+#define RUN_RATECTL_ON 1
+#define RUN_RATECTL_OFF 0
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -154,21 +153,28 @@ struct run_softc {
int (*sc_srom_read)(struct run_softc *,
uint16_t, uint16_t *);
- uint32_t mac_rev;
+ uint16_t mac_ver;
+ uint16_t mac_rev;
uint8_t rf_rev;
uint8_t freq;
uint8_t ntxchains;
uint8_t nrxchains;
int fixed_ridx;
+ uint8_t bbp25;
+ uint8_t bbp26;
uint8_t rf24_20mhz;
uint8_t rf24_40mhz;
+ uint8_t patch_dac;
+ uint8_t rfswitch;
uint8_t ext_2ghz_lna;
uint8_t ext_5ghz_lna;
uint8_t calib_2ghz;
uint8_t calib_5ghz;
- int8_t txpow1[50];
- int8_t txpow2[50];
+ uint8_t txmixgain_2ghz;
+ uint8_t txmixgain_5ghz;
+ int8_t txpow1[54];
+ int8_t txpow2[54];
int8_t rssi_2ghz[3];
int8_t rssi_5ghz[3];
uint8_t lna[4];
@@ -176,7 +182,7 @@ struct run_softc {
struct {
uint8_t reg;
uint8_t val;
- } bbp[8];
+ } bbp[8], rf[10];
uint8_t leds;
uint16_t led[3];
uint32_t txpow20mhz[5];
@@ -196,8 +202,6 @@ struct run_softc {
struct mbuf *rx_m;
- int sifs;
-
union {
struct run_rx_radiotap_header th;
uint8_t pad[64];
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 25fb86f..4a4378b 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/wlan/if_uralreg.h>
#include <dev/usb/wlan/if_uralvar.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int ural_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural");
@@ -162,9 +162,6 @@ static void ural_write_multi(struct ural_softc *, uint16_t, void *,
static void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t);
static uint8_t ural_bbp_read(struct ural_softc *, uint8_t);
static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
-static struct ieee80211_node *ural_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void ural_newassoc(struct ieee80211_node *, int);
static void ural_scan_start(struct ieee80211com *);
static void ural_scan_end(struct ieee80211com *);
static void ural_set_channel(struct ieee80211com *);
@@ -191,10 +188,10 @@ static void ural_init(void *);
static void ural_stop(struct ural_softc *);
static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void ural_amrr_start(struct ural_softc *,
+static void ural_ratectl_start(struct ural_softc *,
struct ieee80211_node *);
-static void ural_amrr_timeout(void *);
-static void ural_amrr_task(void *, int);
+static void ural_ratectl_timeout(void *);
+static void ural_ratectl_task(void *, int);
static int ural_pause(struct ural_softc *sc, int timeout);
/*
@@ -403,7 +400,6 @@ static devclass_t ural_devclass;
DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, NULL, 0);
MODULE_DEPEND(ural, usb, 1, 1, 1);
MODULE_DEPEND(ural, wlan, 1, 1, 1);
-MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1);
static int
ural_match(device_t self)
@@ -500,9 +496,7 @@ ural_attach(device_t self)
ieee80211_ifattach(ic, sc->sc_bssid);
ic->ic_update_promisc = ural_update_promisc;
- ic->ic_newassoc = ural_newassoc;
ic->ic_raw_xmit = ural_raw_xmit;
- ic->ic_node_alloc = ural_node_alloc;
ic->ic_scan_start = ural_scan_start;
ic->ic_scan_end = ural_scan_end;
ic->ic_set_channel = ural_set_channel;
@@ -597,12 +591,10 @@ ural_vap_create(struct ieee80211com *ic,
uvp->newstate = vap->iv_newstate;
vap->iv_newstate = ural_newstate;
- usb_callout_init_mtx(&uvp->amrr_ch, &sc->sc_mtx, 0);
- TASK_INIT(&uvp->amrr_task, 0, ural_amrr_task, uvp);
- ieee80211_amrr_init(&uvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
+ usb_callout_init_mtx(&uvp->ratectl_ch, &sc->sc_mtx, 0);
+ TASK_INIT(&uvp->ratectl_task, 0, ural_ratectl_task, uvp);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
@@ -616,9 +608,9 @@ ural_vap_delete(struct ieee80211vap *vap)
struct ural_vap *uvp = URAL_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- usb_callout_drain(&uvp->amrr_ch);
- ieee80211_draintask(ic, &uvp->amrr_task);
- ieee80211_amrr_cleanup(&uvp->amrr);
+ usb_callout_drain(&uvp->ratectl_ch);
+ ieee80211_draintask(ic, &uvp->ratectl_task);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(uvp, M_80211_VAP);
}
@@ -703,7 +695,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
RAL_LOCK(sc);
- usb_callout_stop(&uvp->amrr_ch);
+ usb_callout_stop(&uvp->ratectl_ch);
switch (nstate) {
case IEEE80211_S_INIT:
@@ -759,7 +751,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* XXX should use ic_bsschan but not valid until after newstate call below */
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- ural_amrr_start(sc, ni);
+ ural_ratectl_start(sc, ni);
break;
@@ -1584,25 +1576,6 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff);
}
-/* ARGUSED */
-static struct ieee80211_node *
-ural_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct ural_node *un;
-
- un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return un != NULL ? &un->ni : NULL;
-}
-
-static void
-ural_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni);
-}
-
static void
ural_scan_start(struct ieee80211com *ic)
{
@@ -2231,7 +2204,7 @@ bad:
}
static void
-ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
+ural_ratectl_start(struct ural_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ural_vap *uvp = URAL_VAP(vap);
@@ -2239,23 +2212,23 @@ ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
- ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni);
+ ieee80211_ratectl_node_init(ni);
- usb_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp);
+ usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
}
static void
-ural_amrr_timeout(void *arg)
+ural_ratectl_timeout(void *arg)
{
struct ural_vap *uvp = arg;
struct ieee80211vap *vap = &uvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- ieee80211_runtask(ic, &uvp->amrr_task);
+ ieee80211_runtask(ic, &uvp->ratectl_task);
}
static void
-ural_amrr_task(void *arg, int pending)
+ural_ratectl_task(void *arg, int pending)
{
struct ural_vap *uvp = arg;
struct ieee80211vap *vap = &uvp->vap;
@@ -2264,6 +2237,7 @@ ural_amrr_task(void *arg, int pending)
struct ural_softc *sc = ifp->if_softc;
struct ieee80211_node *ni = vap->iv_bss;
int ok, fail;
+ int sum, retrycnt;
RAL_LOCK(sc);
/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
@@ -2272,14 +2246,15 @@ ural_amrr_task(void *arg, int pending)
ok = sc->sta[7] + /* TX ok w/o retry */
sc->sta[8]; /* TX ok w/ retry */
fail = sc->sta[9]; /* TX retry-fail count */
+ sum = ok+fail;
+ retrycnt = sc->sta[8] + fail;
- ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn,
- ok+fail, ok, sc->sta[8] + fail);
- (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn);
+ ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
- usb_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp);
+ usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
RAL_UNLOCK(sc);
}
diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h
index 5d9c582..46dbfbd 100644
--- a/sys/dev/usb/wlan/if_uralvar.h
+++ b/sys/dev/usb/wlan/if_uralvar.h
@@ -71,18 +71,11 @@ struct ural_tx_data {
};
typedef STAILQ_HEAD(, ural_tx_data) ural_txdhead;
-struct ural_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define URAL_NODE(ni) ((struct ural_node *)(ni))
-
struct ural_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct usb_callout amrr_ch;
- struct task amrr_task;
+ struct usb_callout ratectl_ch;
+ struct task ratectl_task;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 724bfaa..a0b8179 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/wlan/if_zydreg.h>
#include <dev/usb/wlan/if_zydfw.h>
-#if USB_DEBUG
+#ifdef USB_DEBUG
static int zyd_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd");
@@ -125,8 +125,6 @@ static void zyd_vap_delete(struct ieee80211vap *);
static void zyd_tx_free(struct zyd_tx_data *, int);
static void zyd_setup_tx_list(struct zyd_softc *);
static void zyd_unsetup_tx_list(struct zyd_softc *);
-static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
void *, int, int);
@@ -163,7 +161,6 @@ static void zyd_init_locked(struct zyd_softc *);
static void zyd_init(void *);
static void zyd_stop(struct zyd_softc *);
static int zyd_loadfirmware(struct zyd_softc *);
-static void zyd_newassoc(struct ieee80211_node *, int);
static void zyd_scan_start(struct ieee80211com *);
static void zyd_scan_end(struct ieee80211com *);
static void zyd_set_channel(struct ieee80211com *);
@@ -408,9 +405,7 @@ zyd_attach(device_t dev)
ieee80211_init_channels(ic, NULL, &bands);
ieee80211_ifattach(ic, sc->sc_bssid);
- ic->ic_newassoc = zyd_newassoc;
ic->ic_raw_xmit = zyd_raw_xmit;
- ic->ic_node_alloc = zyd_node_alloc;
ic->ic_scan_start = zyd_scan_start;
ic->ic_scan_end = zyd_scan_end;
ic->ic_set_channel = zyd_set_channel;
@@ -483,10 +478,8 @@ zyd_vap_create(struct ieee80211com *ic,
zvp->newstate = vap->iv_newstate;
vap->iv_newstate = zyd_newstate;
- ieee80211_amrr_init(&zvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
@@ -500,7 +493,7 @@ zyd_vap_delete(struct ieee80211vap *vap)
{
struct zyd_vap *zvp = ZYD_VAP(vap);
- ieee80211_amrr_cleanup(&zvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(zvp, M_80211_VAP);
}
@@ -518,8 +511,8 @@ zyd_tx_free(struct zyd_tx_data *data, int txerr)
data->m = NULL;
if (txerr == 0)
- ieee80211_amrr_tx_complete(&ZYD_NODE(data->ni)->amn,
- IEEE80211_AMRR_SUCCESS, 0);
+ ieee80211_ratectl_tx_complete(data->ni->ni_vap,
+ data->ni, IEEE80211_RATECTL_TX_SUCCESS, NULL, NULL);
ieee80211_free_node(data->ni);
data->ni = NULL;
}
@@ -572,17 +565,6 @@ zyd_unsetup_tx_list(struct zyd_softc *sc)
}
}
-/* ARGUSED */
-static struct ieee80211_node *
-zyd_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct zyd_node *zn;
-
- zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return (zn != NULL) ? (&zn->ni) : (NULL);
-}
-
static int
zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
@@ -669,9 +651,12 @@ zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
*/
ni = ieee80211_find_txnode(vap, retry->macaddr);
if (ni != NULL) {
- ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn,
- IEEE80211_AMRR_FAILURE,
- (int)(le16toh(retry->count) & 0xff));
+ int retrycnt =
+ (int)(le16toh(retry->count) & 0xff);
+
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, NULL);
ieee80211_free_node(ni);
}
if (le16toh(retry->count) & 0x100)
@@ -2498,7 +2483,7 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else {
- (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
}
@@ -2910,14 +2895,6 @@ zyd_loadfirmware(struct zyd_softc *sc)
}
static void
-zyd_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni);
-}
-
-static void
zyd_scan_start(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
@@ -2970,4 +2947,3 @@ static devclass_t zyd_devclass;
DRIVER_MODULE(zyd, uhub, zyd_driver, zyd_devclass, NULL, 0);
MODULE_DEPEND(zyd, usb, 1, 1, 1);
MODULE_DEPEND(zyd, wlan, 1, 1, 1);
-MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h
index 57a5e87..dd11632 100644
--- a/sys/dev/usb/wlan/if_zydreg.h
+++ b/sys/dev/usb/wlan/if_zydreg.h
@@ -1177,12 +1177,6 @@ struct zyd_rx_data {
int rssi;
};
-struct zyd_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define ZYD_NODE(ni) ((struct zyd_node *)(ni))
-
struct zyd_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint8_t wr_flags;
@@ -1243,7 +1237,6 @@ struct zyd_vap {
struct ieee80211vap vap;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
- struct ieee80211_amrr amrr;
};
#define ZYD_VAP(vap) ((struct zyd_vap *)(vap))
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 1797c2d..9bf9342 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_ratectl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -173,8 +174,7 @@ static int wpi_alloc_tx_ring(struct wpi_softc *, struct wpi_tx_ring *,
int, int);
static void wpi_reset_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
static void wpi_free_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
-static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
+static void wpi_newassoc(struct ieee80211_node *, int);
static int wpi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void wpi_mem_lock(struct wpi_softc *);
static void wpi_mem_unlock(struct wpi_softc *);
@@ -235,7 +235,6 @@ static void wpi_init_locked(struct wpi_softc *, int);
static void wpi_stop(struct wpi_softc *);
static void wpi_stop_locked(struct wpi_softc *);
-static void wpi_newassoc(struct ieee80211_node *, int);
static int wpi_set_txpower(struct wpi_softc *, struct ieee80211_channel *,
int);
static void wpi_calib_timeout(void *);
@@ -668,9 +667,8 @@ wpi_attach(device_t dev)
ieee80211_ifattach(ic, macaddr);
/* override default methods */
- ic->ic_node_alloc = wpi_node_alloc;
- ic->ic_newassoc = wpi_newassoc;
ic->ic_raw_xmit = wpi_raw_xmit;
+ ic->ic_newassoc = wpi_newassoc;
ic->ic_wme.wme_update = wpi_wme_update;
ic->ic_scan_start = wpi_scan_start;
ic->ic_scan_end = wpi_scan_end;
@@ -782,11 +780,7 @@ wpi_vap_create(struct ieee80211com *ic,
wvp->newstate = vap->iv_newstate;
vap->iv_newstate = wpi_newstate;
- ieee80211_amrr_init(&wvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /*ms*/);
-
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
ic->ic_opmode = opmode;
@@ -798,7 +792,7 @@ wpi_vap_delete(struct ieee80211vap *vap)
{
struct wpi_vap *wvp = WPI_VAP(vap);
- ieee80211_amrr_cleanup(&wvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(wvp, M_80211_VAP);
}
@@ -1236,18 +1230,6 @@ wpi_resume(device_t dev)
return 0;
}
-/* ARGSUSED */
-static struct ieee80211_node *
-wpi_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct wpi_node *wn;
-
- wn = malloc(sizeof (struct wpi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
-
- return &wn->ni;
-}
-
/**
* Called by net80211 when ever there is a change to 80211 state machine
*/
@@ -1567,7 +1549,9 @@ wpi_tx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc)
struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3];
struct wpi_tx_data *txdata = &ring->data[desc->idx];
struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1);
- struct wpi_node *wn = (struct wpi_node *)txdata->ni;
+ struct ieee80211_node *ni = txdata->ni;
+ struct ieee80211vap *vap = ni->ni_vap;
+ int retrycnt = 0;
DPRINTFN(WPI_DEBUG_TX, ("tx done: qid=%d idx=%d retries=%d nkill=%d "
"rate=%x duration=%d status=%x\n", desc->qid, desc->idx,
@@ -1580,11 +1564,12 @@ wpi_tx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc)
* the lowest available bit-rate.
* XXX frames w/o ACK shouldn't be used either
*/
- wn->amn.amn_txcnt++;
if (stat->ntries > 0) {
DPRINTFN(WPI_DEBUG_TX, ("%d retries\n", stat->ntries));
- wn->amn.amn_retrycnt++;
+ retrycnt = 1;
}
+ ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
/* XXX oerrors should only count errors !maxtries */
if ((le32toh(stat->status) & 0xff) != 1)
@@ -1919,7 +1904,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {
- (void) ieee80211_amrr_choose(ni, &WPI_NODE(ni)->amn);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
tx->rate = wpi_plcp_signal(rate);
@@ -3214,10 +3199,9 @@ wpi_stop(struct wpi_softc *sc)
static void
wpi_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_vap *wvp = WPI_VAP(vap);
- ieee80211_amrr_node_init(&wvp->amrr, &WPI_NODE(ni)->amn, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
static void
@@ -3706,4 +3690,3 @@ static const char *wpi_cmd_str(int cmd)
MODULE_DEPEND(wpi, pci, 1, 1, 1);
MODULE_DEPEND(wpi, wlan, 1, 1, 1);
MODULE_DEPEND(wpi, firmware, 1, 1, 1);
-MODULE_DEPEND(wpi, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index 811624b..00579b3e 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -106,12 +106,6 @@ struct wpi_amrr {
int recovery;
};
-struct wpi_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define WPI_NODE(ni) ((struct wpi_node *)(ni))
-
struct wpi_power_sample {
uint8_t index;
int8_t power;
@@ -127,7 +121,6 @@ struct wpi_power_group {
struct wpi_vap {
struct ieee80211vap vap;
- struct ieee80211_amrr amrr;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c
index a6111e2..3088ecb 100644
--- a/sys/dev/xen/netback/netback.c
+++ b/sys/dev/xen/netback/netback.c
@@ -302,7 +302,7 @@ fixup_checksum(struct mbuf *m)
m->m_pkthdr.csum_flags &= ~CSUM_TCP;
#ifdef SCTP
} else if (sw_csum & CSUM_SCTP) {
- sctp_delayed_cksum(m);
+ sctp_delayed_cksum(m, iphlen);
sw_csum &= ~CSUM_SCTP;
#endif
} else {
diff --git a/sys/fs/coda/cnode.h b/sys/fs/coda/cnode.h
index 8506404..27531a4 100644
--- a/sys/fs/coda/cnode.h
+++ b/sys/fs/coda/cnode.h
@@ -94,7 +94,7 @@ extern int coda_vfsop_print_entry;
struct cnode {
struct vnode *c_vnode;
u_short c_flags; /* flags (see below) */
- CodaFid c_fid; /* file handle */
+ struct CodaFid c_fid; /* file handle */
struct vnode *c_ovp; /* open vnode pointer */
u_short c_ocount; /* count of openers */
u_short c_owrite; /* count of open for write */
@@ -196,7 +196,8 @@ void coda_unmounting(struct mount *whoIam);
int coda_vmflush(struct cnode *cp);
/* cfs_vnodeops.h */
-struct cnode *make_coda_node(CodaFid *fid, struct mount *vfsp, short type);
+struct cnode *make_coda_node(struct CodaFid *fid, struct mount *vfsp,
+ short type);
int coda_vnodeopstats_init(void);
/* sigh */
diff --git a/sys/fs/coda/coda.h b/sys/fs/coda/coda.h
index 93547a4..ee1e760 100644
--- a/sys/fs/coda/coda.h
+++ b/sys/fs/coda/coda.h
@@ -103,6 +103,8 @@ struct timespec {
};
#endif
+typedef u_int32_t cuid_t;
+typedef u_int32_t cgid_t;
/*
* Cfs constants
@@ -132,14 +134,13 @@ struct timespec {
#define C_A_F_OK 0 /* Test for existence. */
-
#ifndef _VENUS_DIRENT_T_
#define _VENUS_DIRENT_T_ 1
struct venus_dirent {
- unsigned long d_fileno; /* file number of entry */
+ unsigned int d_fileno; /* file number of entry */
unsigned short d_reclen; /* length of this record */
- char d_type; /* file type, see below */
- char d_namlen; /* length of string in d_name */
+ unsigned char d_type; /* file type, see below */
+ unsigned char d_namlen; /* length of string in d_name */
char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
};
#undef DIRSIZ
@@ -169,19 +170,19 @@ struct venus_dirent {
#ifdef CODA_COMPAT_5
-typedef struct {
+struct CodaFid {
u_long Volume;
u_long Vnode;
u_long Unique;
-} CodaFid;
+};
-static __inline__ ino_t coda_f2i(CodaFid *fid)
+static __inline__ ino_t coda_f2i(struct CodaFid *fid)
{
if (!fid) return 0;
return (fid->Unique + (fid->Vnode<<10) + (fid->Volume<<20));
}
-static __inline__ char * coda_f2s(CodaFid *fid)
+static __inline__ char * coda_f2s(struct CodaFid *fid)
{
static char fid_str [35];
snprintf (fid_str, 35, "[%lx.%lx.%lx]", fid->Volume,
@@ -189,7 +190,7 @@ static __inline__ char * coda_f2s(CodaFid *fid)
return fid_str;
}
-static __inline__ int coda_fid_eq (CodaFid *fid1, CodaFid *fid2)
+static __inline__ int coda_fid_eq (struct CodaFid *fid1, struct CodaFid *fid2)
{
return (fid1->Volume == fid2->Volume &&
fid1->Vnode == fid2->Vnode &&
@@ -203,18 +204,18 @@ struct coda_cred {
#else /* CODA_COMPAT_5 */
-typedef struct {
+struct CodaFid {
u_int32_t opaque[4];
-} CodaFid;
+};
-static __inline__ ino_t coda_f2i(CodaFid *fid)
+static __inline__ ino_t coda_f2i(struct CodaFid *fid)
{
if ( ! fid )
return 0;
return (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]);
}
-static __inline__ char * coda_f2s(CodaFid *fid)
+static __inline__ char * coda_f2s(struct CodaFid *fid)
{
static char fid_str [35];
snprintf (fid_str, 35, "[%x.%x.%x.%x]", fid->opaque[0],
@@ -222,7 +223,7 @@ static __inline__ char * coda_f2s(CodaFid *fid)
return fid_str;
}
-static __inline__ int coda_fid_eq (CodaFid *fid1, CodaFid *fid2)
+static __inline__ int coda_fid_eq (struct CodaFid *fid1, struct CodaFid *fid2)
{
return (fid1->opaque[0] == fid2->opaque[0] &&
fid1->opaque[1] == fid2->opaque[1] &&
@@ -240,11 +241,11 @@ static __inline__ int coda_fid_eq (CodaFid *fid1, CodaFid *fid2)
enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
struct coda_vattr {
- int va_type; /* vnode type (for create) */
+ long va_type; /* vnode type (for create) */
u_short va_mode; /* files access mode and type */
short va_nlink; /* number of references to file */
- uid_t va_uid; /* owner user id */
- gid_t va_gid; /* owner group id */
+ cuid_t va_uid; /* owner user id */
+ cgid_t va_gid; /* owner group id */
long va_fileid; /* file id */
u_quad_t va_size; /* file size in bytes */
long va_blocksize; /* blocksize preferred for i/o */
@@ -313,7 +314,7 @@ struct coda_statfs {
#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
VC_MAXDATASIZE
-#define CIOC_KERNEL_VERSION _IOWR('c', 10, sizeof (int))
+#define CIOC_KERNEL_VERSION _IOWR('c', 10, int)
#if 0
/* don't care about kernel version number */
#define CODA_KERNEL_VERSION 0
@@ -344,23 +345,23 @@ struct coda_in_hdr {
struct coda_in_hdr {
u_int32_t opcode;
u_int32_t unique; /* Keep multiple outstanding msgs distinct */
- pid_t pid; /* Common to all */
- pid_t pgid; /* Common to all */
- uid_t uid; /* Common to all */
+ pid_t pid;
+ pid_t pgid;
+ cuid_t uid;
};
#endif
/* Really important that opcode and unique are 1st two fields! */
struct coda_out_hdr {
- unsigned long opcode;
- unsigned long unique;
- unsigned long result;
+ u_int32_t opcode;
+ u_int32_t unique;
+ u_int32_t result;
};
/* coda_root: NO_IN */
struct coda_root_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
};
struct coda_root_in {
@@ -373,7 +374,7 @@ struct coda_root_in {
/* coda_open: */
struct coda_open_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int flags;
};
@@ -387,7 +388,7 @@ struct coda_open_out {
/* coda_close: */
struct coda_close_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int flags;
};
@@ -398,7 +399,7 @@ struct coda_close_out {
/* coda_ioctl: */
struct coda_ioctl_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int cmd;
int len;
int rwflag;
@@ -415,7 +416,7 @@ struct coda_ioctl_out {
/* coda_getattr: */
struct coda_getattr_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
};
struct coda_getattr_out {
@@ -427,7 +428,7 @@ struct coda_getattr_out {
/* coda_setattr: NO_OUT */
struct coda_setattr_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
struct coda_vattr attr;
};
@@ -438,7 +439,7 @@ struct coda_setattr_out {
/* coda_access: NO_OUT */
struct coda_access_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int flags;
};
@@ -454,14 +455,14 @@ struct coda_access_out {
/* coda_lookup: */
struct coda_lookup_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int name; /* Place holder for data. */
int flags;
};
struct coda_lookup_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
int vtype;
};
@@ -469,7 +470,7 @@ struct coda_lookup_out {
/* coda_create: */
struct coda_create_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
struct coda_vattr attr;
int excl;
int mode;
@@ -478,7 +479,7 @@ struct coda_create_in {
struct coda_create_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
struct coda_vattr attr;
};
@@ -486,7 +487,7 @@ struct coda_create_out {
/* coda_remove: NO_OUT */
struct coda_remove_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int name; /* Place holder for data. */
};
@@ -497,8 +498,8 @@ struct coda_remove_out {
/* coda_link: NO_OUT */
struct coda_link_in {
struct coda_in_hdr ih;
- CodaFid sourceFid; /* cnode to link *to* */
- CodaFid destFid; /* Directory in which to place link */
+ struct CodaFid sourceFid; /* cnode to link *to* */
+ struct CodaFid destFid; /* Directory in which to place link */
int tname; /* Place holder for data. */
};
@@ -510,9 +511,9 @@ struct coda_link_out {
/* coda_rename: NO_OUT */
struct coda_rename_in {
struct coda_in_hdr ih;
- CodaFid sourceFid;
+ struct CodaFid sourceFid;
int srcname;
- CodaFid destFid;
+ struct CodaFid destFid;
int destname;
};
@@ -523,14 +524,14 @@ struct coda_rename_out {
/* coda_mkdir: */
struct coda_mkdir_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
struct coda_vattr attr;
int name; /* Place holder for data. */
};
struct coda_mkdir_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
struct coda_vattr attr;
};
@@ -538,7 +539,7 @@ struct coda_mkdir_out {
/* coda_rmdir: NO_OUT */
struct coda_rmdir_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int name; /* Place holder for data. */
};
@@ -549,7 +550,7 @@ struct coda_rmdir_out {
/* coda_readdir: */
struct coda_readdir_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int count;
int offset;
};
@@ -563,7 +564,7 @@ struct coda_readdir_out {
/* coda_symlink: NO_OUT */
struct coda_symlink_in {
struct coda_in_hdr ih;
- CodaFid Fid; /* Directory to put symlink in */
+ struct CodaFid Fid; /* Directory to put symlink in */
int srcname;
struct coda_vattr attr;
int tname;
@@ -576,7 +577,7 @@ struct coda_symlink_out {
/* coda_readlink: */
struct coda_readlink_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
};
struct coda_readlink_out {
@@ -589,7 +590,7 @@ struct coda_readlink_out {
/* coda_fsync: NO_OUT */
struct coda_fsync_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
};
struct coda_fsync_out {
@@ -599,18 +600,18 @@ struct coda_fsync_out {
/* coda_inactive: NO_OUT */
struct coda_inactive_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
};
/* coda_vget: */
struct coda_vget_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
};
struct coda_vget_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
int vtype;
};
@@ -626,7 +627,7 @@ struct coda_purgeuser_out {
#ifdef CODA_COMPAT_5
struct coda_cred cred;
#else
- uid_t uid;
+ cuid_t uid;
#endif
};
@@ -634,14 +635,14 @@ struct coda_purgeuser_out {
/* CODA_ZAPFILE is a venus->kernel call */
struct coda_zapfile_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
};
/* coda_zapdir: */
/* CODA_ZAPDIR is a venus->kernel call */
struct coda_zapdir_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
};
/* coda_zapnode: */
@@ -651,41 +652,44 @@ struct coda_zapvnode_out {
#ifdef CODA_COMPAT_5
struct coda_cred cred;
#endif
- CodaFid Fid;
+ struct CodaFid Fid;
};
/* coda_purgefid: */
/* CODA_PURGEFID is a venus->kernel call */
struct coda_purgefid_out {
struct coda_out_hdr oh;
- CodaFid Fid;
+ struct CodaFid Fid;
};
/* coda_replace: */
/* CODA_REPLACE is a venus->kernel call */
struct coda_replace_out { /* coda_replace is a venus->kernel call */
struct coda_out_hdr oh;
- CodaFid NewFid;
- CodaFid OldFid;
+ struct CodaFid NewFid;
+ struct CodaFid OldFid;
};
/* coda_open_by_fd: */
struct coda_open_by_fd_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int flags;
};
struct coda_open_by_fd_out {
struct coda_out_hdr oh;
int fd;
+#ifdef _KERNEL
+ /* not passed from userspace but used in-kernel only */
struct vnode *vp;
+#endif
};
/* coda_open_by_path: */
struct coda_open_by_path_in {
struct coda_in_hdr ih;
- CodaFid Fid;
+ struct CodaFid Fid;
int flags;
};
@@ -799,6 +803,9 @@ struct PioctlData {
#define CODA_CONTROL ".CONTROL"
#define CODA_CONTROLLEN 8
+#define CTL_VOL -1
+#define CTL_VNO -1
+#define CTL_UNI -1
#define CTL_INO -1
#define CTL_FILE "/coda/.CONTROL"
@@ -810,10 +817,9 @@ struct PioctlData {
#define INVAL_FID { 0, 0, 0 }
#else
#define CTL_FID { { -1, -1, -1, -1 } }
-#define IS_CTL_FID(fidp) ((fidp)->opaque[0] == -1 &&\
- (fidp)->opaque[1] == -1 &&\
- (fidp)->opaque[2] == -1 &&\
- (fidp)->opaque[3] == -1)
+#define IS_CTL_FID(fidp) ((fidp)->opaque[1] == CTL_VOL && \
+ (fidp)->opaque[2] == CTL_VNO && \
+ (fidp)->opaque[3] == CTL_UNI)
#define INVAL_FID { { 0, 0, 0, 0 } }
#endif
diff --git a/sys/fs/coda/coda_subr.c b/sys/fs/coda/coda_subr.c
index e24950b..08c03cb 100644
--- a/sys/fs/coda/coda_subr.c
+++ b/sys/fs/coda/coda_subr.c
@@ -164,7 +164,7 @@ coda_unsave(struct cnode *cp)
* NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
*/
struct cnode *
-coda_find(CodaFid *fid)
+coda_find(struct CodaFid *fid)
{
struct cnode *cp;
diff --git a/sys/fs/coda/coda_subr.h b/sys/fs/coda/coda_subr.h
index 0efc081..b8edfd3 100644
--- a/sys/fs/coda/coda_subr.h
+++ b/sys/fs/coda/coda_subr.h
@@ -35,7 +35,7 @@
struct cnode *coda_alloc(void);
void coda_free(struct cnode *cp);
-struct cnode *coda_find(CodaFid *fid);
+struct cnode *coda_find(struct CodaFid *fid);
void coda_flush(struct coda_mntinfo *mnt, enum dc_status dcstat);
void coda_testflush(void);
void coda_checkunmounting(struct mount *mp);
diff --git a/sys/fs/coda/coda_venus.c b/sys/fs/coda/coda_venus.c
index b5e3b96..9999d3a 100644
--- a/sys/fs/coda/coda_venus.c
+++ b/sys/fs/coda/coda_venus.c
@@ -177,7 +177,7 @@ int coda_kernel_version = CODA_KERNEL_VERSION;
int
venus_root(void *mdp, struct ucred *cred, struct proc *p,
- /*out*/ CodaFid *VFid)
+ /*out*/ struct CodaFid *VFid)
{
DECL_NO_IN(coda_root); /* sets Isize & Osize */
ALLOC_NO_IN(coda_root); /* sets inp & outp */
@@ -194,7 +194,7 @@ venus_root(void *mdp, struct ucred *cred, struct proc *p,
}
int
-venus_open(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
+venus_open(void *mdp, struct CodaFid *fid, int flag, struct ucred *cred,
struct proc *p, /*out*/ struct vnode **vp)
{
int cflag;
@@ -215,7 +215,7 @@ venus_open(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
}
int
-venus_close(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
+venus_close(void *mdp, struct CodaFid *fid, int flag, struct ucred *cred,
struct proc *p)
{
int cflag;
@@ -252,7 +252,7 @@ venus_write(void)
* normal files.
*/
int
-venus_ioctl(void *mdp, CodaFid *fid, int com, int flag, caddr_t data,
+venus_ioctl(void *mdp, struct CodaFid *fid, int com, int flag, caddr_t data,
struct ucred *cred, struct proc *p)
{
DECL(coda_ioctl); /* sets Isize & Osize */
@@ -304,7 +304,8 @@ venus_ioctl(void *mdp, CodaFid *fid, int com, int flag, caddr_t data,
}
int
-venus_getattr(void *mdp, CodaFid *fid, struct ucred *cred, struct vattr *vap)
+venus_getattr(void *mdp, struct CodaFid *fid, struct ucred *cred,
+ struct vattr *vap)
{
struct proc *p;
DECL(coda_getattr); /* sets Isize & Osize */
@@ -326,7 +327,8 @@ venus_getattr(void *mdp, CodaFid *fid, struct ucred *cred, struct vattr *vap)
}
int
-venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap, struct ucred *cred)
+venus_setattr(void *mdp, struct CodaFid *fid, struct vattr *vap,
+ struct ucred *cred)
{
struct proc *p;
DECL_NO_OUT(coda_setattr); /* sets Isize & Osize */
@@ -347,8 +349,8 @@ venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap, struct ucred *cred)
}
int
-venus_access(void *mdp, CodaFid *fid, accmode_t accmode, struct ucred *cred,
- struct proc *p)
+venus_access(void *mdp, struct CodaFid *fid, accmode_t accmode,
+ struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_access); /* sets Isize & Osize */
ALLOC_NO_OUT(coda_access); /* sets inp & outp */
@@ -374,8 +376,8 @@ venus_access(void *mdp, CodaFid *fid, accmode_t accmode, struct ucred *cred,
}
int
-venus_readlink(void *mdp, CodaFid *fid, struct ucred *cred, struct proc *p,
- /*out*/ char **str, int *len)
+venus_readlink(void *mdp, struct CodaFid *fid, struct ucred *cred,
+ struct proc *p, /*out*/ char **str, int *len)
{
DECL(coda_readlink); /* sets Isize & Osize */
coda_readlink_size += CODA_MAXPATHLEN;
@@ -400,7 +402,7 @@ venus_readlink(void *mdp, CodaFid *fid, struct ucred *cred, struct proc *p,
}
int
-venus_fsync(void *mdp, CodaFid *fid, struct proc *p)
+venus_fsync(void *mdp, struct CodaFid *fid, struct proc *p)
{
DECL_NO_OUT(coda_fsync); /* sets Isize & Osize */
ALLOC_NO_OUT(coda_fsync); /* sets inp & outp */
@@ -420,8 +422,9 @@ venus_fsync(void *mdp, CodaFid *fid, struct proc *p)
}
int
-venus_lookup(void *mdp, CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p, /*out*/ CodaFid *VFid, int *vtype)
+venus_lookup(void *mdp, struct CodaFid *fid, const char *nm, int len,
+ struct ucred *cred, struct proc *p, /*out*/ struct CodaFid *VFid,
+ int *vtype)
{
DECL(coda_lookup); /* sets Isize & Osize */
coda_lookup_size += len + 1;
@@ -457,9 +460,9 @@ venus_lookup(void *mdp, CodaFid *fid, const char *nm, int len,
}
int
-venus_create(void *mdp, CodaFid *fid, const char *nm, int len, int exclusive,
- int mode, struct vattr *va, struct ucred *cred, struct proc *p,
- /*out*/ CodaFid *VFid, struct vattr *attr)
+venus_create(void *mdp, struct CodaFid *fid, const char *nm, int len,
+ int exclusive, int mode, struct vattr *va, struct ucred *cred,
+ struct proc *p, /*out*/ struct CodaFid *VFid, struct vattr *attr)
{
DECL(coda_create); /* sets Isize & Osize */
coda_create_size += len + 1;
@@ -488,7 +491,7 @@ venus_create(void *mdp, CodaFid *fid, const char *nm, int len, int exclusive,
}
int
-venus_remove(void *mdp, CodaFid *fid, const char *nm, int len,
+venus_remove(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_remove); /* sets Isize & Osize */
@@ -511,8 +514,8 @@ venus_remove(void *mdp, CodaFid *fid, const char *nm, int len,
}
int
-venus_link(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm, int len,
- struct ucred *cred, struct proc *p)
+venus_link(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
+ const char *nm, int len, struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_link); /* sets Isize & Osize */
coda_link_size += len + 1;
@@ -535,8 +538,9 @@ venus_link(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm, int len,
}
int
-venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm, int len,
- const char *tnm, int tlen, struct ucred *cred, struct proc *p)
+venus_rename(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
+ const char *nm, int len, const char *tnm, int tlen, struct ucred *cred,
+ struct proc *p)
{
DECL_NO_OUT(coda_rename); /* sets Isize & Osize */
coda_rename_size += len + 1 + tlen + 1;
@@ -562,9 +566,9 @@ venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm, int len,
}
int
-venus_mkdir(void *mdp, CodaFid *fid, const char *nm, int len,
+venus_mkdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct vattr *va, struct ucred *cred, struct proc *p,
- /*out*/ CodaFid *VFid, struct vattr *ova)
+ /*out*/ struct CodaFid *VFid, struct vattr *ova)
{
DECL(coda_mkdir); /* sets Isize & Osize */
coda_mkdir_size += len + 1;
@@ -591,7 +595,7 @@ venus_mkdir(void *mdp, CodaFid *fid, const char *nm, int len,
}
int
-venus_rmdir(void *mdp, CodaFid *fid, const char *nm, int len,
+venus_rmdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_rmdir); /* sets Isize & Osize */
@@ -614,7 +618,7 @@ venus_rmdir(void *mdp, CodaFid *fid, const char *nm, int len,
}
int
-venus_symlink(void *mdp, CodaFid *fid, const char *lnm, int llen,
+venus_symlink(void *mdp, struct CodaFid *fid, const char *lnm, int llen,
const char *nm, int len, struct vattr *va, struct ucred *cred,
struct proc *p)
{
@@ -645,7 +649,7 @@ venus_symlink(void *mdp, CodaFid *fid, const char *lnm, int llen,
* XXX: Unused.
*/
int
-venus_readdir(void *mdp, CodaFid *fid, int count, int offset,
+venus_readdir(void *mdp, struct CodaFid *fid, int count, int offset,
struct ucred *cred, struct proc *p, /*out*/ char *buffer, int *len)
{
DECL(coda_readdir); /* sets Isize & Osize */
@@ -672,8 +676,8 @@ venus_readdir(void *mdp, CodaFid *fid, int count, int offset,
}
int
-venus_fhtovp(void *mdp, CodaFid *fid, struct ucred *cred, struct proc *p,
- /*out*/ CodaFid *VFid, int *vtype)
+venus_fhtovp(void *mdp, struct CodaFid *fid, struct ucred *cred,
+ struct proc *p, /*out*/ struct CodaFid *VFid, int *vtype)
{
DECL(coda_vget); /* sets Isize & Osize */
ALLOC(coda_vget); /* sets inp & outp */
diff --git a/sys/fs/coda/coda_venus.h b/sys/fs/coda/coda_venus.h
index 0d4dac0..95f1c57 100644
--- a/sys/fs/coda/coda_venus.h
+++ b/sys/fs/coda/coda_venus.h
@@ -34,49 +34,50 @@
#define _CODA_VENUS_H_
int venus_root(void *mdp, struct ucred *cred, struct proc *p,
- /*out*/ CodaFid *VFid);
-int venus_open(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
- struct proc *p, /*out*/ struct vnode **vp);
-int venus_close(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
- struct proc *p);
+ /*out*/ struct CodaFid *VFid);
+int venus_open(void *mdp, struct CodaFid *fid, int flag,
+ struct ucred *cred, struct proc *p, /*out*/ struct vnode **vp);
+int venus_close(void *mdp, struct CodaFid *fid, int flag,
+ struct ucred *cred, struct proc *p);
void venus_read(void);
void venus_write(void);
-int venus_ioctl(void *mdp, CodaFid *fid, int com, int flag, caddr_t data,
- struct ucred *cred, struct proc *p);
-int venus_getattr(void *mdp, CodaFid *fid, struct ucred *cred,
+int venus_ioctl(void *mdp, struct CodaFid *fid, int com, int flag,
+ caddr_t data, struct ucred *cred, struct proc *p);
+int venus_getattr(void *mdp, struct CodaFid *fid, struct ucred *cred,
struct vattr *vap);
-int venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap,
+int venus_setattr(void *mdp, struct CodaFid *fid, struct vattr *vap,
struct ucred *cred);
-int venus_access(void *mdp, CodaFid *fid, int mode, struct ucred *cred,
- struct proc *p);
-int venus_readlink(void *mdp, CodaFid *fid, struct ucred *cred,
+int venus_access(void *mdp, struct CodaFid *fid, int mode,
+ struct ucred *cred, struct proc *p);
+int venus_readlink(void *mdp, struct CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ char **str, int *len);
-int venus_fsync(void *mdp, CodaFid *fid, struct proc *p);
-int venus_lookup(void *mdp, CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p, /*out*/ CodaFid *VFid,
+int venus_fsync(void *mdp, struct CodaFid *fid, struct proc *p);
+int venus_lookup(void *mdp, struct CodaFid *fid, const char *nm, int len,
+ struct ucred *cred, struct proc *p, /*out*/ struct CodaFid *VFid,
int *vtype);
-int venus_create(void *mdp, CodaFid *fid, const char *nm, int len,
+int venus_create(void *mdp, struct CodaFid *fid, const char *nm, int len,
int exclusive, int mode, struct vattr *va, struct ucred *cred,
- struct proc *p, /*out*/ CodaFid *VFid, struct vattr *attr);
-int venus_remove(void *mdp, CodaFid *fid, const char *nm, int len,
+ struct proc *p, /*out*/ struct CodaFid *VFid,
+ struct vattr *attr);
+int venus_remove(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p);
-int venus_link(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm,
- int len, struct ucred *cred, struct proc *p);
-int venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm,
- int len, const char *tnm, int tlen, struct ucred *cred,
- struct proc *p);
-int venus_mkdir(void *mdp, CodaFid *fid, const char *nm, int len,
+int venus_link(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
+ const char *nm, int len, struct ucred *cred, struct proc *p);
+int venus_rename(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
+ const char *nm, int len, const char *tnm, int tlen,
+ struct ucred *cred, struct proc *p);
+int venus_mkdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct vattr *va, struct ucred *cred, struct proc *p,
- /*out*/ CodaFid *VFid, struct vattr *ova);
-int venus_rmdir(void *mdp, CodaFid *fid, const char *nm, int len,
+ /*out*/ struct CodaFid *VFid, struct vattr *ova);
+int venus_rmdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
+ struct ucred *cred, struct proc *p);
+int venus_symlink(void *mdp, struct CodaFid *fid, const char *lnm,
+ int llen, const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p);
-int venus_symlink(void *mdp, CodaFid *fid, const char *lnm, int llen,
- const char *nm, int len, struct vattr *va, struct ucred *cred,
- struct proc *p);
-int venus_readdir(void *mdp, CodaFid *fid, int count, int offset,
+int venus_readdir(void *mdp, struct CodaFid *fid, int count, int offset,
struct ucred *cred, struct proc *p, /*out*/ char *buffer,
int *len);
-int venus_fhtovp(void *mdp, CodaFid *fid, struct ucred *cred,
- struct proc *p, /*out*/ CodaFid *VFid, int *vtype);
+int venus_fhtovp(void *mdp, struct CodaFid *fid, struct ucred *cred,
+ struct proc *p, /*out*/ struct CodaFid *VFid, int *vtype);
#endif /* !_CODA_VENUS_H_ */
diff --git a/sys/fs/coda/coda_vfsops.c b/sys/fs/coda/coda_vfsops.c
index b12c43b..90660c6 100644
--- a/sys/fs/coda/coda_vfsops.c
+++ b/sys/fs/coda/coda_vfsops.c
@@ -113,8 +113,8 @@ coda_mount(struct mount *vfsp)
struct cdev *dev;
struct coda_mntinfo *mi;
struct vnode *rootvp;
- CodaFid rootfid = INVAL_FID;
- CodaFid ctlfid = CTL_FID;
+ struct CodaFid rootfid = INVAL_FID;
+ struct CodaFid ctlfid = CTL_FID;
int error;
struct nameidata ndp;
ENTRY;
@@ -268,8 +268,8 @@ coda_root(struct mount *vfsp, int flags, struct vnode **vpp)
int error;
struct proc *p;
struct thread *td;
- CodaFid VFid;
- static const CodaFid invalfid = INVAL_FID;
+ struct CodaFid VFid;
+ static const struct CodaFid invalfid = INVAL_FID;
td = curthread;
p = td->td_proc;
@@ -288,7 +288,7 @@ coda_root(struct mount *vfsp, int flags, struct vnode **vpp)
* but not in any released versions as of 6 Mar 2003.
*/
if (memcmp(&VTOC(mi->mi_rootvp)->c_fid, &invalfid,
- sizeof(CodaFid)) != 0 || mi->mi_started == 0) {
+ sizeof(struct CodaFid)) != 0 || mi->mi_started == 0) {
/*
* Found valid root.
*/
@@ -407,7 +407,7 @@ coda_fhtovp(struct mount *vfsp, struct fid *fhp, struct mbuf *nam,
int error;
struct thread *td = curthread; /* XXX -mach */
struct proc *p = td->td_proc;
- CodaFid VFid;
+ struct CodaFid VFid;
int vtype;
ENTRY;
diff --git a/sys/fs/coda/coda_vfsops.h b/sys/fs/coda/coda_vfsops.h
index b51f4bc..e5b3a11 100644
--- a/sys/fs/coda/coda_vfsops.h
+++ b/sys/fs/coda/coda_vfsops.h
@@ -42,7 +42,7 @@
struct cfid {
u_short cfid_len;
u_short padding;
- CodaFid cfid_fid;
+ struct CodaFid cfid_fid;
};
struct mbuf;
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
index edaba65..79d53e5 100644
--- a/sys/fs/coda/coda_vnops.c
+++ b/sys/fs/coda/coda_vnops.c
@@ -872,7 +872,7 @@ coda_lookup(struct vop_cachedlookup_args *ap)
struct cnode *cp;
const char *nm = cnp->cn_nameptr;
int len = cnp->cn_namelen;
- CodaFid VFid;
+ struct CodaFid VFid;
int vtype;
int error = 0;
@@ -1009,7 +1009,7 @@ coda_create(struct vop_create_args *ap)
struct cnode *cp;
const char *nm = cnp->cn_nameptr;
int len = cnp->cn_namelen;
- CodaFid VFid;
+ struct CodaFid VFid;
struct vattr attr;
MARK_ENTRY(CODA_CREATE_STATS);
@@ -1278,7 +1278,7 @@ coda_mkdir(struct vop_mkdir_args *ap)
const char *nm = cnp->cn_nameptr;
int len = cnp->cn_namelen;
struct cnode *cp;
- CodaFid VFid;
+ struct CodaFid VFid;
struct vattr ova;
MARK_ENTRY(CODA_MKDIR_STATS);
@@ -1687,7 +1687,7 @@ coda_print_cred(struct ucred *cred)
* coda_unsave.
*/
struct cnode *
-make_coda_node(CodaFid *fid, struct mount *vfsp, short type)
+make_coda_node(struct CodaFid *fid, struct mount *vfsp, short type)
{
struct cnode *cp;
struct vnode *vp;
diff --git a/sys/fs/deadfs/dead_vnops.c b/sys/fs/deadfs/dead_vnops.c
index 7a07b38..e255654 100644
--- a/sys/fs/deadfs/dead_vnops.c
+++ b/sys/fs/deadfs/dead_vnops.c
@@ -225,13 +225,7 @@ dead_rename(ap)
struct componentname *a_tcnp;
} */ *ap;
{
- if (ap->a_tvp)
- vput(ap->a_tvp);
- if (ap->a_tdvp == ap->a_tvp)
- vrele(ap->a_tdvp);
- else
- vput(ap->a_tdvp);
- vrele(ap->a_fdvp);
- vrele(ap->a_fvp);
+
+ vop_rename_fail(ap);
return (EXDEV);
}
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index 07b2547..43cf65e 100644
--- a/sys/fs/fdescfs/fdesc_vnops.c
+++ b/sys/fs/fdescfs/fdesc_vnops.c
@@ -522,11 +522,10 @@ fdesc_readdir(ap)
FILEDESC_SLOCK(fdp);
while (i < fdp->fd_nfiles + 2 && uio->uio_resid >= UIO_MX) {
+ bzero((caddr_t)dp, UIO_MX);
switch (i) {
case 0: /* `.' */
case 1: /* `..' */
- bzero((caddr_t)dp, UIO_MX);
-
dp->d_fileno = i + FD_ROOT;
dp->d_namlen = i + 1;
dp->d_reclen = UIO_MX;
@@ -535,26 +534,24 @@ fdesc_readdir(ap)
dp->d_type = DT_DIR;
break;
default:
- if (fdp->fd_ofiles[fcnt] == NULL) {
- FILEDESC_SUNLOCK(fdp);
- goto done;
- }
-
- bzero((caddr_t) dp, UIO_MX);
+ if (fdp->fd_ofiles[fcnt] == NULL)
+ break;
dp->d_namlen = sprintf(dp->d_name, "%d", fcnt);
dp->d_reclen = UIO_MX;
dp->d_type = DT_UNKNOWN;
dp->d_fileno = i + FD_DESC;
break;
}
- /*
- * And ship to userland
- */
- FILEDESC_SUNLOCK(fdp);
- error = uiomove(dp, UIO_MX, uio);
- if (error)
- goto done;
- FILEDESC_SLOCK(fdp);
+ if (dp->d_namlen != 0) {
+ /*
+ * And ship to userland
+ */
+ FILEDESC_SUNLOCK(fdp);
+ error = uiomove(dp, UIO_MX, uio);
+ if (error)
+ goto done;
+ FILEDESC_SLOCK(fdp);
+ }
i++;
fcnt++;
}
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index ce5048a..999125d 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -125,14 +125,14 @@ msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
#endif
dp = VTODE(vdp);
pmp = dp->de_pmp;
- if (vpp != NULL)
- *vpp = NULL;
#ifdef MSDOSFS_DEBUG
printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n",
vdp, dp, dp->de_Attributes);
#endif
restart:
+ if (vpp != NULL)
+ *vpp = NULL;
/*
* If they are going after the . or .. entry in the root directory,
* they won't find it. DOS filesystems don't have them in the root
@@ -525,8 +525,10 @@ foundroot:
pdp = vdp;
if (flags & ISDOTDOT) {
error = msdosfs_deget_dotdot(pdp, cluster, blkoff, vpp);
- if (error)
+ if (error) {
+ *vpp = NULL;
return (error);
+ }
/*
* Recheck that ".." still points to the inode we
* looked up before pdp lock was dropped.
@@ -534,6 +536,7 @@ foundroot:
error = msdosfs_lookup_(pdp, NULL, cnp, &inode1);
if (error) {
vput(*vpp);
+ *vpp = NULL;
return (error);
}
if (VTODE(*vpp)->de_inode != inode1) {
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 20a4dbd..a0801bd 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -383,10 +383,9 @@ msdosfs_mount(struct mount *mp)
pmp = VFSTOMSDOSFS(mp);
#endif
} else {
+ vput(devvp);
if (devvp != pmp->pm_devvp)
- error = EINVAL; /* XXX needs translation */
- else
- vput(devvp);
+ return (EINVAL); /* XXX needs translation */
}
if (error) {
vrele(devvp);
@@ -581,6 +580,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
|| (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
|| (pmp->pm_HugeSectors == 0)
|| (pmp->pm_FATsecs == 0)
+ || (SecPerClust * pmp->pm_BlkPerSec > MAXBSIZE / DEV_BSIZE)
) {
error = EINVAL;
goto error_exit;
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 8b6ada3..384bdb4 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -650,7 +650,7 @@ tryagain:
trylater_delay = NFS_TRYLATERDEL;
waituntil = NFSD_MONOSEC + trylater_delay;
while (NFSD_MONOSEC < waituntil)
- (void) nfs_catnap(PZERO, "nfstry");
+ (void) nfs_catnap(PZERO, 0, "nfstry");
trylater_delay *= 2;
goto tryagain;
}
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index 7f27494..2676566 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -82,7 +82,8 @@ SYSCTL_STRING(_vfs_newnfs, OID_AUTO, callback_addr, CTLFLAG_RW,
*/
MALLOC_DEFINE(M_NEWNFSRVCACHE, "NFSD srvcache", "NFSD Server Request Cache");
MALLOC_DEFINE(M_NEWNFSDCLIENT, "NFSD V4client", "NFSD V4 Client Id");
-MALLOC_DEFINE(M_NEWNFSDSTATE, "NFSD V4state", "NFSD V4 State (Openowner, Open, Lockowner, Delegation");
+MALLOC_DEFINE(M_NEWNFSDSTATE, "NFSD V4state",
+ "NFSD V4 State (Openowner, Open, Lockowner, Delegation");
MALLOC_DEFINE(M_NEWNFSDLOCK, "NFSD V4lock", "NFSD V4 byte range lock");
MALLOC_DEFINE(M_NEWNFSDLOCKFILE, "NFSD lckfile", "NFSD Open/Lock file");
MALLOC_DEFINE(M_NEWNFSSTRING, "NFSD string", "NFSD V4 long string");
@@ -97,7 +98,10 @@ MALLOC_DEFINE(M_NEWNFSCLLOCKOWNER, "NFSCL lckown", "NFSCL Lock Owner");
MALLOC_DEFINE(M_NEWNFSCLLOCK, "NFSCL lck", "NFSCL Lock");
MALLOC_DEFINE(M_NEWNFSV4NODE, "NEWNFSnode", "New nfs vnode");
MALLOC_DEFINE(M_NEWNFSDIRECTIO, "NEWdirectio", "New nfs Direct IO buffer");
-MALLOC_DEFINE(M_NEWNFSDIROFF, "Newnfscl_diroff", "New NFS directory offset data");
+MALLOC_DEFINE(M_NEWNFSDIROFF, "NFSCL diroffdiroff",
+ "New NFS directory offset data");
+MALLOC_DEFINE(M_NEWNFSDROLLBACK, "NFSD rollback",
+ "New NFS local lock rollback");
/*
* Definition of mutex locks.
@@ -117,7 +121,7 @@ struct mtx nfs_slock_mutex;
/* local functions */
static int nfssvc_call(struct thread *, struct nfssvc_args *, struct ucred *);
-#if defined(__i386__)
+#ifdef __NO_STRICT_ALIGNMENT
/*
* These architectures don't need re-alignment, so just return.
*/
@@ -127,7 +131,7 @@ newnfs_realign(struct mbuf **pm)
return;
}
-#else
+#else /* !__NO_STRICT_ALIGNMENT */
/*
* newnfs_realign:
*
@@ -185,7 +189,7 @@ newnfs_realign(struct mbuf **pm)
pm = &m->m_next;
}
}
-#endif /* !__i386__ */
+#endif /* __NO_STRICT_ALIGNMENT */
#ifdef notdef
static void
@@ -221,6 +225,8 @@ void
newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
{
+ KASSERT(nfscr->nfsc_ngroups >= 0,
+ ("newnfs_copycred: negative nfsc_ngroups"));
cr->cr_uid = nfscr->nfsc_uid;
crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
}
@@ -339,17 +345,21 @@ newnfs_timer(void *arg)
/*
- * sleep for a short period of time.
+ * Sleep for a short period of time unless errval == NFSERR_GRACE, where
+ * the sleep should be for 5 seconds.
* Since lbolt doesn't exist in FreeBSD-CURRENT, just use a timeout on
* an event that never gets a wakeup. Only return EINTR or 0.
*/
int
-nfs_catnap(int prio, const char *wmesg)
+nfs_catnap(int prio, int errval, const char *wmesg)
{
static int non_event;
int ret;
- ret = tsleep(&non_event, prio, wmesg, 1);
+ if (errval == NFSERR_GRACE)
+ ret = tsleep(&non_event, prio, wmesg, 5 * hz);
+ else
+ ret = tsleep(&non_event, prio, wmesg, 1);
if (ret != EINTR)
ret = 0;
return (ret);
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 8e53ae6..dc5b2dc 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -1824,6 +1824,19 @@ nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex)
}
/*
+ * Test for a lock. Return 1 if locked, 0 otherwise.
+ */
+APPLESTATIC int
+nfsv4_testlock(struct nfsv4lock *lp)
+{
+
+ if ((lp->nfslock_lock & NFSV4LOCK_LOCK) == 0 &&
+ lp->nfslock_usecnt == 0)
+ return (0);
+ return (1);
+}
+
+/*
* Wake up anyone sleeping, waiting for this lock.
*/
static void
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 17714d7..d6ecda2 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -251,6 +251,7 @@ int nfsv4_lock(struct nfsv4lock *, int, int *, void *);
void nfsv4_unlock(struct nfsv4lock *, int);
void nfsv4_relref(struct nfsv4lock *);
void nfsv4_getref(struct nfsv4lock *, int *, void *);
+int nfsv4_testlock(struct nfsv4lock *);
int nfsrv_mtostr(struct nfsrv_descript *, char *, int);
int nfsrv_checkutf8(u_int8_t *, int);
int newnfs_sndlock(int *);
@@ -321,7 +322,7 @@ int nfsvno_v4rootexport(struct nfsrv_descript *);
void newnfs_portinit(void);
struct ucred *newnfs_getcred(void);
void newnfs_setroot(struct ucred *);
-int nfs_catnap(int, const char *);
+int nfs_catnap(int, int, const char *);
struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t);
int nfsrv_atroot(vnode_t, long *);
void newnfs_timer(void *);
@@ -368,7 +369,7 @@ int nfsrpc_readlink(vnode_t, struct uio *, struct ucred *,
int nfsrpc_read(vnode_t, struct uio *, struct ucred *, NFSPROC_T *,
struct nfsvattr *, int *, void *);
int nfsrpc_write(vnode_t, struct uio *, int *, u_char *,
- struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *);
+ struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *, int);
int nfsrpc_mknod(vnode_t, char *, int, struct vattr *, u_int32_t,
enum vtype, struct ucred *, NFSPROC_T *, struct nfsvattr *,
struct nfsvattr *, struct nfsfh **, int *, int *, void *);
@@ -501,7 +502,7 @@ int nfscl_maperr(NFSPROC_T *, int, uid_t, gid_t);
void nfscl_init(void);
/* nfs_clbio.c */
-int ncl_flush(vnode_t, int, struct ucred *, NFSPROC_T *, int);
+int ncl_flush(vnode_t, int, struct ucred *, NFSPROC_T *, int, int);
/* nfs_clnode.c */
void ncl_invalcaches(vnode_t);
diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h
index 10747af..72d8eeb 100644
--- a/sys/fs/nfs/nfsclstate.h
+++ b/sys/fs/nfs/nfsclstate.h
@@ -74,6 +74,7 @@ struct nfsclclient {
#define NFSCLFLAGS_EXPIREIT 0x0040
#define NFSCLFLAGS_FIRSTDELEG 0x0080
#define NFSCLFLAGS_GOTDELEG 0x0100
+#define NFSCLFLAGS_RECVRINPROG 0x0200
struct nfsclowner {
LIST_ENTRY(nfsclowner) nfsow_list;
@@ -140,6 +141,7 @@ struct nfsclopen {
#define NFSCLOPEN_OK 0
#define NFSCLOPEN_DOOPEN 1
#define NFSCLOPEN_DOOPENDOWNGRADE 2
+#define NFSCLOPEN_SETCRED 3
struct nfscllockowner {
LIST_ENTRY(nfscllockowner) nfsl_list;
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index c7ef67c..0fa2e14 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -143,21 +143,21 @@
#define NFSMGET(m) do { \
MGET((m), M_TRYWAIT, MT_DATA); \
while ((m) == NULL ) { \
- (void) nfs_catnap(PZERO, "nfsmget"); \
+ (void) nfs_catnap(PZERO, 0, "nfsmget"); \
MGET((m), M_TRYWAIT, MT_DATA); \
} \
} while (0)
#define NFSMGETHDR(m) do { \
MGETHDR((m), M_TRYWAIT, MT_DATA); \
while ((m) == NULL ) { \
- (void) nfs_catnap(PZERO, "nfsmget"); \
+ (void) nfs_catnap(PZERO, 0, "nfsmget"); \
MGETHDR((m), M_TRYWAIT, MT_DATA); \
} \
} while (0)
#define NFSMCLGET(m, w) do { \
MGET((m), M_TRYWAIT, MT_DATA); \
while ((m) == NULL ) { \
- (void) nfs_catnap(PZERO, "nfsmget"); \
+ (void) nfs_catnap(PZERO, 0, "nfsmget"); \
MGET((m), M_TRYWAIT, MT_DATA); \
} \
MCLGET((m), (w)); \
@@ -165,7 +165,7 @@
#define NFSMCLGETHDR(m, w) do { \
MGETHDR((m), M_TRYWAIT, MT_DATA); \
while ((m) == NULL ) { \
- (void) nfs_catnap(PZERO, "nfsmget"); \
+ (void) nfs_catnap(PZERO, 0, "nfsmget"); \
MGETHDR((m), M_TRYWAIT, MT_DATA); \
} \
} while (0)
@@ -539,6 +539,7 @@ void nfsrvd_rcv(struct socket *, void *, int);
#define NFSSTATESPINLOCK extern struct mtx nfs_state_mutex
#define NFSLOCKSTATE() mtx_lock(&nfs_state_mutex)
#define NFSUNLOCKSTATE() mtx_unlock(&nfs_state_mutex)
+#define NFSSTATEMUTEXPTR (&nfs_state_mutex)
#define NFSREQSPINLOCK extern struct mtx nfs_req_mutex
#define NFSLOCKREQ() mtx_lock(&nfs_req_mutex)
#define NFSUNLOCKREQ() mtx_unlock(&nfs_req_mutex)
@@ -674,6 +675,7 @@ MALLOC_DECLARE(M_NEWNFSDIROFF);
MALLOC_DECLARE(M_NEWNFSV4NODE);
MALLOC_DECLARE(M_NEWNFSDIRECTIO);
MALLOC_DECLARE(M_NEWNFSMNT);
+MALLOC_DECLARE(M_NEWNFSDROLLBACK);
#define M_NFSRVCACHE M_NEWNFSRVCACHE
#define M_NFSDCLIENT M_NEWNFSDCLIENT
#define M_NFSDSTATE M_NEWNFSDSTATE
@@ -692,6 +694,7 @@ MALLOC_DECLARE(M_NEWNFSMNT);
#define M_NFSDIROFF M_NEWNFSDIROFF
#define M_NFSV4NODE M_NEWNFSV4NODE
#define M_NFSDIRECTIO M_NEWNFSDIRECTIO
+#define M_NFSDROLLBACK M_NEWNFSDROLLBACK
#define NFSINT_SIGMASK(set) \
(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \
diff --git a/sys/fs/nfs/nfsrvstate.h b/sys/fs/nfs/nfsrvstate.h
index 629b18c..964b998 100644
--- a/sys/fs/nfs/nfsrvstate.h
+++ b/sys/fs/nfs/nfsrvstate.h
@@ -185,6 +185,17 @@ struct nfslockconflict {
};
/*
+ * This structure is used to keep track of local locks that might need
+ * to be rolled back.
+ */
+struct nfsrollback {
+ LIST_ENTRY(nfsrollback) rlck_list;
+ uint64_t rlck_first;
+ uint64_t rlck_end;
+ int rlck_type;
+};
+
+/*
* This structure refers to a file for which lock(s) and/or open(s) exist.
* Searched via hash table on file handle or found via the back pointer from an
* open or lock owner.
@@ -193,8 +204,12 @@ struct nfslockfile {
LIST_HEAD(, nfsstate) lf_open; /* Open list */
LIST_HEAD(, nfsstate) lf_deleg; /* Delegation list */
LIST_HEAD(, nfslock) lf_lock; /* Lock list */
+ LIST_HEAD(, nfslock) lf_locallock; /* Local lock list */
+ LIST_HEAD(, nfsrollback) lf_rollback; /* Local lock rollback list */
LIST_ENTRY(nfslockfile) lf_hash; /* Hash list entry */
fhandle_t lf_fh; /* The file handle */
+ struct nfsv4lock lf_locallock_lck; /* serialize local locking */
+ int lf_usecount; /* Ref count for locking */
};
/*
diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h
index 4b54286..c6071af 100644
--- a/sys/fs/nfsclient/nfs.h
+++ b/sys/fs/nfsclient/nfs.h
@@ -79,14 +79,16 @@ int ncl_biowrite(struct vnode *, struct uio *, int, struct ucred *);
int ncl_vinvalbuf(struct vnode *, int, struct thread *, int);
int ncl_asyncio(struct nfsmount *, struct buf *, struct ucred *,
struct thread *);
-int ncl_doio(struct vnode *, struct buf *, struct ucred *, struct thread *);
+int ncl_doio(struct vnode *, struct buf *, struct ucred *, struct thread *,
+ int);
void ncl_nhinit(void);
void ncl_nhuninit(void);
void ncl_nodelock(struct nfsnode *);
void ncl_nodeunlock(struct nfsnode *);
int ncl_getattrcache(struct vnode *, struct vattr *);
int ncl_readrpc(struct vnode *, struct uio *, struct ucred *);
-int ncl_writerpc(struct vnode *, struct uio *, struct ucred *, int *, int *);
+int ncl_writerpc(struct vnode *, struct uio *, struct ucred *, int *, int *,
+ int);
int ncl_readlinkrpc(struct vnode *, struct uio *, struct ucred *);
int ncl_readdirrpc(struct vnode *, struct uio *, struct ucred *,
struct thread *);
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index d0dd2cc..2401c88 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -336,7 +336,7 @@ ncl_putpages(struct vop_putpages_args *ap)
else
iomode = NFSWRITE_FILESYNC;
- error = ncl_writerpc(vp, &uio, cred, &iomode, &must_commit);
+ error = ncl_writerpc(vp, &uio, cred, &iomode, &must_commit, 0);
pmap_qremove(kva, npages);
relpbuf(bp, &ncl_pbuf_freecnt);
@@ -554,7 +554,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
brelse(bp);
return (error);
@@ -583,7 +583,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
bp->b_ioflags |= BIO_ERROR;
brelse(bp);
@@ -609,7 +609,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
brelse(bp);
}
@@ -638,7 +638,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
/*
* no error + B_INVAL == directory EOF,
* use the block.
@@ -771,7 +771,7 @@ do_sync:
uio.uio_td = td;
iomode = NFSWRITE_FILESYNC;
error = ncl_writerpc(vp, &uio, cred, &iomode,
- &must_commit);
+ &must_commit, 0);
KASSERT((must_commit == 0),
("ncl_directio_write: Did not commit write"));
if (error)
@@ -1122,7 +1122,7 @@ again:
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
brelse(bp);
break;
@@ -1523,7 +1523,7 @@ ncl_doio_directwrite(struct buf *bp)
iomode = NFSWRITE_FILESYNC;
uiop->uio_td = NULL; /* NULL since we're in nfsiod */
- ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit);
+ ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit, 0);
KASSERT((must_commit == 0), ("ncl_doio_directwrite: Did not commit write"));
free(iov_base, M_NFSDIRECTIO);
free(uiop->uio_iov, M_NFSDIRECTIO);
@@ -1550,7 +1550,8 @@ ncl_doio_directwrite(struct buf *bp)
* synchronously or from an nfsiod.
*/
int
-ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
+ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td,
+ int called_from_strategy)
{
struct uio *uiop;
struct nfsnode *np;
@@ -1695,7 +1696,8 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
else
iomode = NFSWRITE_FILESYNC;
- error = ncl_writerpc(vp, uiop, cr, &iomode, &must_commit);
+ error = ncl_writerpc(vp, uiop, cr, &iomode, &must_commit,
+ called_from_strategy);
/*
* When setting B_NEEDCOMMIT also set B_CLUSTEROK to try
@@ -1732,6 +1734,12 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
* the block is reused. This is indicated by setting
* the B_DELWRI and B_NEEDCOMMIT flags.
*
+ * EIO is returned by ncl_writerpc() to indicate a recoverable
+ * write error and is handled as above, except that
+ * B_EINTR isn't set. One cause of this is a stale stateid
+ * error for the RPC that indicates recovery is required,
+ * when called with called_from_strategy != 0.
+ *
* If the buffer is marked B_PAGING, it does not reside on
* the vp's paging queues so we cannot call bdirty(). The
* bp in this case is not an NFS cache block so we should
@@ -1760,7 +1768,8 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
bdirty(bp);
bp->b_flags &= ~B_DONE;
}
- if (error && (bp->b_flags & B_ASYNC) == 0)
+ if ((error == EINTR || error == ETIMEDOUT) &&
+ (bp->b_flags & B_ASYNC) == 0)
bp->b_flags |= B_EINTR;
splx(s);
} else {
diff --git a/sys/fs/nfsclient/nfs_clnfsiod.c b/sys/fs/nfsclient/nfs_clnfsiod.c
index 6649fc0..62ea4f8 100644
--- a/sys/fs/nfsclient/nfs_clnfsiod.c
+++ b/sys/fs/nfsclient/nfs_clnfsiod.c
@@ -278,9 +278,11 @@ nfssvc_iod(void *instance)
(void)ncl_doio_directwrite(bp);
} else {
if (bp->b_iocmd == BIO_READ)
- (void) ncl_doio(bp->b_vp, bp, bp->b_rcred, NULL);
+ (void) ncl_doio(bp->b_vp, bp, bp->b_rcred,
+ NULL, 0);
else
- (void) ncl_doio(bp->b_vp, bp, bp->b_wcred, NULL);
+ (void) ncl_doio(bp->b_vp, bp, bp->b_wcred,
+ NULL, 0);
}
mtx_lock(&ncl_iod_mutex);
/*
diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
index 6b2aa7a..c133742 100644
--- a/sys/fs/nfsclient/nfs_clnode.c
+++ b/sys/fs/nfsclient/nfs_clnode.c
@@ -199,7 +199,7 @@ ncl_inactive(struct vop_inactive_args *ap)
* available for the writes.
*/
if (nfscl_mustflush(vp))
- (void) ncl_flush(vp, MNT_WAIT, NULL, ap->a_td, 1);
+ (void) ncl_flush(vp, MNT_WAIT, NULL, ap->a_td, 1, 0);
(void) nfsrpc_close(vp, 1, ap->a_td);
}
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index e81c3bf..f39666d 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -978,6 +978,8 @@ newnfs_copyincred(struct ucred *cr, struct nfscred *nfscr)
{
int i;
+ KASSERT(cr->cr_ngroups >= 0,
+ ("newnfs_copyincred: negative cr_ngroups"));
nfscr->nfsc_uid = cr->cr_uid;
nfscr->nfsc_ngroups = MIN(cr->cr_ngroups, NFS_MAXGRPS + 1);
for (i = 0; i < nfscr->nfsc_ngroups; i++)
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 95943a9..a84a301 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -278,7 +278,13 @@ else printf(" fhl=0\n");
error = EIO;
}
newnfs_copyincred(cred, &op->nfso_cred);
- }
+ } else if (ret == NFSCLOPEN_SETCRED)
+ /*
+ * This is a new local open on a delegation. It needs
+ * to have credentials so that an open can be done
+ * against the server during recovery.
+ */
+ newnfs_copyincred(cred, &op->nfso_cred);
/*
* nfso_opencnt is the count of how many VOP_OPEN()s have
@@ -292,7 +298,7 @@ else printf(" fhl=0\n");
nfscl_openrelease(op, error, newone);
if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
- (void) nfs_catnap(PZERO, "nfs_open");
+ (void) nfs_catnap(PZERO, error, "nfs_open");
} else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
&& clidrev != 0) {
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -454,7 +460,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
cred, p);
if (ret == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfs_open");
+ (void) nfs_catnap(PZERO, ret, "nfs_open");
} while (ret == NFSERR_DELAY);
error = ret;
}
@@ -478,7 +484,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
newfhlen, mode, op, name, namelen, &ndp, 0, 0x0,
cred, p, syscred, 1);
if (ret == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfs_open2");
+ (void) nfs_catnap(PZERO, ret, "nfs_open2");
} while (ret == NFSERR_DELAY);
if (ret) {
if (ndp != NULL)
@@ -618,6 +624,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
nd->nd_repstat == NFSERR_DELAY) &&
error == 0)
(void) nfs_catnap(PZERO,
+ (int)nd->nd_repstat,
"nfs_close");
} while ((nd->nd_repstat == NFSERR_GRACE ||
nd->nd_repstat == NFSERR_DELAY) &&
@@ -639,7 +646,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
do {
error = nfscl_tryclose(op, tcred, nmp, p);
if (error == NFSERR_GRACE)
- (void) nfs_catnap(PZERO, "nfs_close");
+ (void) nfs_catnap(PZERO, error, "nfs_close");
} while (error == NFSERR_GRACE);
NFSLOCKCLSTATE();
nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
@@ -993,7 +1000,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr *vap, NFSACL_T *aclp,
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
error == NFSERR_OLDSTATEID) {
- (void) nfs_catnap(PZERO, "nfs_setattr");
+ (void) nfs_catnap(PZERO, error, "nfs_setattr");
} else if ((error == NFSERR_EXPIRED ||
error == NFSERR_BADSTATEID) && clidrev != 0) {
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1238,7 +1245,7 @@ nfsrpc_read(vnode_t vp, struct uio *uiop, struct ucred *cred,
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
error == NFSERR_OLDSTATEID) {
- (void) nfs_catnap(PZERO, "nfs_read");
+ (void) nfs_catnap(PZERO, error, "nfs_read");
} else if ((error == NFSERR_EXPIRED ||
error == NFSERR_BADSTATEID) && clidrev != 0) {
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1340,11 +1347,16 @@ nfsmout:
/*
* nfs write operation
+ * When called_from_strategy != 0, it should return EIO for an error that
+ * indicates recovery is in progress, so that the buffer will be left
+ * dirty and be written back to the server later. If it loops around,
+ * the recovery thread could get stuck waiting for the buffer and recovery
+ * will then deadlock.
*/
APPLESTATIC int
nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp,
struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp,
- void *stuff)
+ void *stuff, int called_from_strategy)
{
int error, expireret = 0, retrycnt, nostateid;
u_int32_t clidrev = 0;
@@ -1398,18 +1410,21 @@ nfscl_dumpstate(nmp, 1, 1, 0, 0);
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
error == NFSERR_OLDSTATEID) {
- (void) nfs_catnap(PZERO, "nfs_write");
+ (void) nfs_catnap(PZERO, error, "nfs_write");
} else if ((error == NFSERR_EXPIRED ||
error == NFSERR_BADSTATEID) && clidrev != 0) {
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
}
retrycnt++;
- } while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
- error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
+ } while (error == NFSERR_GRACE || error == NFSERR_DELAY ||
+ ((error == NFSERR_STALESTATEID ||
+ error == NFSERR_STALEDONTRECOVER) && called_from_strategy == 0) ||
(error == NFSERR_OLDSTATEID && retrycnt < 20) ||
((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) &&
expireret == 0 && clidrev != 0 && retrycnt < 4));
- if (error && retrycnt >= 4)
+ if (error != 0 && (retrycnt >= 4 ||
+ ((error == NFSERR_STALESTATEID ||
+ error == NFSERR_STALEDONTRECOVER) && called_from_strategy != 0)))
error = EIO;
if (NFSHASNFSV4(nmp) && p == NULL)
NFSFREECRED(newcred);
@@ -1722,7 +1737,7 @@ nfsrpc_create(vnode_t dvp, char *name, int namelen, struct vattr *vap,
nfscl_ownerrelease(owp, error, newone, unlocked);
if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
- (void) nfs_catnap(PZERO, "nfs_open");
+ (void) nfs_catnap(PZERO, error, "nfs_open");
} else if ((error == NFSERR_EXPIRED ||
error == NFSERR_BADSTATEID) && clidrev != 0) {
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1955,7 +1970,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
ret = nfsrpc_openconfirm(dvp, nfhp->nfh_fh,
nfhp->nfh_len, op, cred, p);
if (ret == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfs_create");
+ (void) nfs_catnap(PZERO, ret, "nfs_create");
} while (ret == NFSERR_DELAY);
error = ret;
}
@@ -1977,7 +1992,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
(NFSV4OPEN_ACCESSWRITE | NFSV4OPEN_ACCESSREAD), op,
name, namelen, &dp, 0, 0x0, cred, p, 0, 1);
if (ret == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfs_crt2");
+ (void) nfs_catnap(PZERO, ret, "nfs_crt2");
} while (ret == NFSERR_DELAY);
if (ret) {
if (dp != NULL)
@@ -3519,7 +3534,8 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
if ((nd->nd_repstat == NFSERR_GRACE ||
nd->nd_repstat == NFSERR_DELAY) &&
error == 0)
- (void) nfs_catnap(PZERO, "nfs_advlock");
+ (void) nfs_catnap(PZERO, (int)nd->nd_repstat,
+ "nfs_advlock");
} while ((nd->nd_repstat == NFSERR_GRACE ||
nd->nd_repstat == NFSERR_DELAY) && error == 0);
}
@@ -3556,7 +3572,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
error == NFSERR_STALEDONTRECOVER ||
error == NFSERR_STALECLIENTID || error == NFSERR_DELAY) {
- (void) nfs_catnap(PZERO, "nfs_advlock");
+ (void) nfs_catnap(PZERO, error, "nfs_advlock");
} else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
&& clidrev != 0) {
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 568c5de..b6fad20 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -139,7 +139,7 @@ static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *);
static int nfscl_errmap(struct nfsrv_descript *);
static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *);
static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *,
- struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *);
+ struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int);
static void nfscl_freeopenowner(struct nfsclowner *, int);
static void nfscl_cleandeleg(struct nfscldeleg *);
static int nfscl_trydelegreturn(struct nfscldeleg *, struct ucred *,
@@ -274,8 +274,13 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg,
*owpp = owp;
if (opp != NULL)
*opp = op;
- if (retp != NULL)
- *retp = NFSCLOPEN_OK;
+ if (retp != NULL) {
+ if (nfhp != NULL && dp != NULL && nop == NULL)
+ /* new local open on delegation */
+ *retp = NFSCLOPEN_SETCRED;
+ else
+ *retp = NFSCLOPEN_OK;
+ }
/*
* Now, check the mode on the open and return the appropriate
@@ -476,6 +481,13 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode,
}
/*
+ * Wait for recovery to complete.
+ */
+ while ((clp->nfsc_flags & NFSCLFLAGS_RECVRINPROG))
+ (void) nfsmsleep(&clp->nfsc_flags, NFSCLSTATEMUTEXPTR,
+ PZERO, "nfsrecvr", NULL);
+
+ /*
* First, look for a delegation.
*/
LIST_FOREACH(dp, NFSCLDELEGHASH(clp, nfhp, fhlen), nfsdl_hash) {
@@ -772,7 +784,7 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
if (error == NFSERR_STALECLIENTID ||
error == NFSERR_STALEDONTRECOVER ||
error == NFSERR_CLIDINUSE) {
- (void) nfs_catnap(PZERO, "nfs_setcl");
+ (void) nfs_catnap(PZERO, error, "nfs_setcl");
}
} while (((error == NFSERR_STALECLIENTID ||
error == NFSERR_STALEDONTRECOVER) && --trystalecnt > 0) ||
@@ -1773,6 +1785,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
* block when trying to use state.
*/
NFSLOCKCLSTATE();
+ clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG;
do {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
NFSCLSTATEMUTEXPTR);
@@ -1789,9 +1802,10 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
error == NFSERR_STALEDONTRECOVER) && --trycnt > 0);
if (error) {
nfscl_cleanclient(clp);
- clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
- NFSCLFLAGS_RECOVER);
NFSLOCKCLSTATE();
+ clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
+ NFSCLFLAGS_RECOVER | NFSCLFLAGS_RECVRINPROG);
+ wakeup(&clp->nfsc_flags);
nfsv4_unlock(&clp->nfsc_lock, 0);
NFSUNLOCKCLSTATE();
return;
@@ -2032,7 +2046,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
newnfs_copycred(&op->nfso_cred, tcred);
error = nfscl_tryclose(op, tcred, nmp, p);
if (error == NFSERR_GRACE)
- (void) nfs_catnap(PZERO, "nfsexcls");
+ (void) nfs_catnap(PZERO, error, "nfsexcls");
} while (error == NFSERR_GRACE);
LIST_REMOVE(op, nfso_list);
FREE((caddr_t)op, M_NFSCLOPEN);
@@ -2045,13 +2059,15 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
newnfs_copycred(&dp->nfsdl_cred, tcred);
error = nfscl_trydelegreturn(dp, tcred, nmp, p);
if (error == NFSERR_GRACE)
- (void) nfs_catnap(PZERO, "nfsexdlg");
+ (void) nfs_catnap(PZERO, error, "nfsexdlg");
} while (error == NFSERR_GRACE);
TAILQ_REMOVE(&extra_deleg, dp, nfsdl_list);
FREE((caddr_t)dp, M_NFSCLDELEG);
}
NFSLOCKCLSTATE();
+ clp->nfsc_flags &= ~NFSCLFLAGS_RECVRINPROG;
+ wakeup(&clp->nfsc_flags);
nfsv4_unlock(&clp->nfsc_lock, 0);
NFSUNLOCKCLSTATE();
NFSFREECRED(tcred);
@@ -2095,6 +2111,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
NFSUNLOCKCLSTATE();
return (0);
}
+ clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG;
NFSUNLOCKCLSTATE();
nmp = clp->nfsc_nmp;
@@ -2111,6 +2128,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
* Clear out any state.
*/
nfscl_cleanclient(clp);
+ NFSLOCKCLSTATE();
clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
NFSCLFLAGS_RECOVER);
} else {
@@ -2124,14 +2142,15 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
* Expire the state for the client.
*/
nfscl_expireclient(clp, nmp, cred, p);
+ NFSLOCKCLSTATE();
clp->nfsc_flags |= NFSCLFLAGS_HASCLIENTID;
clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER;
}
- NFSFREECRED(cred);
- clp->nfsc_flags &= ~NFSCLFLAGS_EXPIREIT;
- NFSLOCKCLSTATE();
+ clp->nfsc_flags &= ~(NFSCLFLAGS_EXPIREIT | NFSCLFLAGS_RECVRINPROG);
+ wakeup(&clp->nfsc_flags);
nfsv4_unlock(&clp->nfsc_lock, 0);
NFSUNLOCKCLSTATE();
+ NFSFREECRED(cred);
return (error);
}
@@ -2311,14 +2330,30 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p)
struct ucred *cred;
u_int32_t clidrev;
int error, cbpathdown, islept, igotlock, ret, clearok;
+ uint32_t recover_done_time = 0;
cred = newnfs_getcred();
+ NFSLOCKCLSTATE();
clp->nfsc_flags |= NFSCLFLAGS_HASTHREAD;
+ NFSUNLOCKCLSTATE();
for(;;) {
newnfs_setroot(cred);
cbpathdown = 0;
- if (clp->nfsc_flags & NFSCLFLAGS_RECOVER)
- nfscl_recover(clp, cred, p);
+ if (clp->nfsc_flags & NFSCLFLAGS_RECOVER) {
+ /*
+ * Only allow one recover within 1/2 of the lease
+ * duration (nfsc_renew).
+ */
+ if (recover_done_time < NFSD_MONOSEC) {
+ recover_done_time = NFSD_MONOSEC +
+ clp->nfsc_renew;
+ nfscl_recover(clp, cred, p);
+ } else {
+ NFSLOCKCLSTATE();
+ clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER;
+ NFSUNLOCKCLSTATE();
+ }
+ }
if (clp->nfsc_expire <= NFSD_MONOSEC &&
(clp->nfsc_flags & NFSCLFLAGS_HASCLIENTID)) {
clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
@@ -2326,9 +2361,11 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p)
error = nfsrpc_renew(clp, cred, p);
if (error == NFSERR_CBPATHDOWN)
cbpathdown = 1;
- else if (error == NFSERR_STALECLIENTID)
+ else if (error == NFSERR_STALECLIENTID) {
+ NFSLOCKCLSTATE();
clp->nfsc_flags |= NFSCLFLAGS_RECOVER;
- else if (error == NFSERR_EXPIRED)
+ NFSUNLOCKCLSTATE();
+ } else if (error == NFSERR_EXPIRED)
(void) nfscl_hasexpired(clp, clidrev, p);
}
@@ -2432,7 +2469,7 @@ tryagain:
NFSUNLOCKCLSTATE();
newnfs_copycred(&dp->nfsdl_cred, cred);
ret = nfscl_recalldeleg(clp, clp->nfsc_nmp, dp,
- NULL, cred, p);
+ NULL, cred, p, 1);
if (!ret) {
nfscl_cleandeleg(dp);
TAILQ_REMOVE(&clp->nfsc_deleg, dp,
@@ -3272,7 +3309,8 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off,
*/
static int
nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
- struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p)
+ struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p,
+ int called_from_renewthread)
{
struct nfsclowner *owp, *lowp, *nowp;
struct nfsclopen *op, *lop;
@@ -3306,6 +3344,7 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
* Ok, if it's a write delegation, flush data to the server, so
* that close/open consistency is retained.
*/
+ ret = 0;
NFSLOCKNODE(np);
if ((dp->nfsdl_flags & NFSCLDL_WRITE) && (np->n_flag & NMODIFIED)) {
#ifdef APPLE
@@ -3314,7 +3353,8 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
np->n_flag |= NDELEGRECALL;
#endif
NFSUNLOCKNODE(np);
- (void) ncl_flush(vp, MNT_WAIT, cred, p, 1);
+ ret = ncl_flush(vp, MNT_WAIT, cred, p, 1,
+ called_from_renewthread);
NFSLOCKNODE(np);
#ifdef APPLE
OSBitAndAtomic((int32_t)~(NMODIFIED | NDELEGRECALL), (UInt32 *)&np->n_flag);
@@ -3323,6 +3363,16 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
#endif
}
NFSUNLOCKNODE(np);
+ if (ret == EIO && called_from_renewthread != 0) {
+ /*
+ * If the flush failed with EIO for the renew thread,
+ * return now, so that the dirty buffer will be flushed
+ * later.
+ */
+ if (gotvp != 0)
+ vrele(vp);
+ return (ret);
+ }
/*
* Now, for each openowner with opens issued locally, move them
@@ -3569,7 +3619,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
mode, op, name, namelen, ndpp, reclaim, delegtype, cred, p,
0, 0);
if (error == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstryop");
+ (void) nfs_catnap(PZERO, error, "nfstryop");
} while (error == NFSERR_DELAY);
if (error == EAUTH || error == EACCES) {
/* Try again using system credentials */
@@ -3579,7 +3629,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
newfhlen, mode, op, name, namelen, ndpp, reclaim,
delegtype, cred, p, 1, 0);
if (error == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstryop");
+ (void) nfs_catnap(PZERO, error, "nfstryop");
} while (error == NFSERR_DELAY);
}
return (error);
@@ -3602,7 +3652,8 @@ nfscl_trylock(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp,
error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp, newone,
reclaim, off, len, type, cred, p, 0);
if (!error && nd->nd_repstat == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstrylck");
+ (void) nfs_catnap(PZERO, (int)nd->nd_repstat,
+ "nfstrylck");
} while (!error && nd->nd_repstat == NFSERR_DELAY);
if (!error)
error = nd->nd_repstat;
@@ -3613,7 +3664,8 @@ nfscl_trylock(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp,
error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp,
newone, reclaim, off, len, type, cred, p, 1);
if (!error && nd->nd_repstat == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstrylck");
+ (void) nfs_catnap(PZERO, (int)nd->nd_repstat,
+ "nfstrylck");
} while (!error && nd->nd_repstat == NFSERR_DELAY);
if (!error)
error = nd->nd_repstat;
@@ -3635,7 +3687,7 @@ nfscl_trydelegreturn(struct nfscldeleg *dp, struct ucred *cred,
do {
error = nfsrpc_delegreturn(dp, cred, nmp, p, 0);
if (error == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstrydp");
+ (void) nfs_catnap(PZERO, error, "nfstrydp");
} while (error == NFSERR_DELAY);
if (error == EAUTH || error == EACCES) {
/* Try again using system credentials */
@@ -3643,7 +3695,7 @@ nfscl_trydelegreturn(struct nfscldeleg *dp, struct ucred *cred,
do {
error = nfsrpc_delegreturn(dp, cred, nmp, p, 1);
if (error == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstrydp");
+ (void) nfs_catnap(PZERO, error, "nfstrydp");
} while (error == NFSERR_DELAY);
}
return (error);
@@ -3664,7 +3716,7 @@ nfscl_tryclose(struct nfsclopen *op, struct ucred *cred,
do {
error = nfsrpc_closerpc(nd, nmp, op, cred, p, 0);
if (error == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstrycl");
+ (void) nfs_catnap(PZERO, error, "nfstrycl");
} while (error == NFSERR_DELAY);
if (error == EAUTH || error == EACCES) {
/* Try again using system credentials */
@@ -3672,7 +3724,7 @@ nfscl_tryclose(struct nfsclopen *op, struct ucred *cred,
do {
error = nfsrpc_closerpc(nd, nmp, op, cred, p, 1);
if (error == NFSERR_DELAY)
- (void) nfs_catnap(PZERO, "nfstrycl");
+ (void) nfs_catnap(PZERO, error, "nfstrycl");
} while (error == NFSERR_DELAY);
}
return (error);
@@ -3820,7 +3872,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
NFSUNLOCKCLSTATE();
cred = newnfs_getcred();
newnfs_copycred(&dp->nfsdl_cred, cred);
- (void) nfscl_recalldeleg(clp, nmp, dp, vp, cred, p);
+ (void) nfscl_recalldeleg(clp, nmp, dp, vp, cred, p, 0);
NFSFREECRED(cred);
triedrecall = 1;
NFSLOCKCLSTATE();
@@ -3918,7 +3970,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
NFSUNLOCKCLSTATE();
cred = newnfs_getcred();
newnfs_copycred(&dp->nfsdl_cred, cred);
- (void) nfscl_recalldeleg(clp, nmp, dp, fvp, cred, p);
+ (void) nfscl_recalldeleg(clp, nmp, dp, fvp, cred, p, 0);
NFSFREECRED(cred);
triedrecall = 1;
NFSLOCKCLSTATE();
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 0bf2bf4..76154c3 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -652,7 +652,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
while (newnfs_connect(nmp, &nmp->nm_sockreq,
cred, td, 0)) {
printf("newnfs_args: retrying connect\n");
- (void) nfs_catnap(PSOCK, "newnfscon");
+ (void) nfs_catnap(PSOCK, 0, "newnfscon");
}
}
} else {
@@ -1188,7 +1188,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
cred, td);
if (error)
- (void) nfs_catnap(PZERO, "nfsgetdirp");
+ (void) nfs_catnap(PZERO, error, "nfsgetdirp");
} while (error && --trycnt > 0);
if (error) {
error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
@@ -1284,7 +1284,7 @@ nfs_unmount(struct mount *mp, int mntflags)
do {
error = vflush(mp, 1, flags, td);
if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
- (void) nfs_catnap(PSOCK, "newndm");
+ (void) nfs_catnap(PSOCK, error, "newndm");
} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
if (error)
goto out;
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 3be823f..d53c838 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -670,13 +670,13 @@ nfs_close(struct vop_close_args *ap)
* traditional vnode locking implemented for Vnode Ops.
*/
int cm = newnfs_commit_on_close ? 1 : 0;
- error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td, cm);
+ error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td, cm, 0);
/* np->n_flag &= ~NMODIFIED; */
} else if (NFS_ISV4(vp)) {
if (nfscl_mustflush(vp)) {
int cm = newnfs_commit_on_close ? 1 : 0;
error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td,
- cm);
+ cm, 0);
/*
* as above w.r.t races when clearing
* NMODIFIED.
@@ -1306,7 +1306,7 @@ ncl_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
*/
int
ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
- int *iomode, int *must_commit)
+ int *iomode, int *must_commit, int called_from_strategy)
{
struct nfsvattr nfsva;
int error = 0, attrflag, ret;
@@ -1315,7 +1315,7 @@ ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
*must_commit = 0;
error = nfsrpc_write(vp, uiop, iomode, verf, cred,
- uiop->uio_td, &nfsva, &attrflag, NULL);
+ uiop->uio_td, &nfsva, &attrflag, NULL, called_from_strategy);
NFSLOCKMNT(nmp);
if (!error && NFSHASWRITEVERF(nmp) &&
NFSBCMP(verf, nmp->nm_verf, NFSX_VERF)) {
@@ -2473,7 +2473,7 @@ nfs_strategy(struct vop_strategy_args *ap)
*/
if ((bp->b_flags & B_ASYNC) == 0 ||
ncl_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
- (void)ncl_doio(ap->a_vp, bp, cr, curthread);
+ (void) ncl_doio(ap->a_vp, bp, cr, curthread, 1);
return (0);
}
@@ -2484,17 +2484,20 @@ nfs_strategy(struct vop_strategy_args *ap)
static int
nfs_fsync(struct vop_fsync_args *ap)
{
- return (ncl_flush(ap->a_vp, ap->a_waitfor, NULL, ap->a_td, 1));
+ return (ncl_flush(ap->a_vp, ap->a_waitfor, NULL, ap->a_td, 1, 0));
}
/*
* Flush all the blocks associated with a vnode.
* Walk through the buffer pool and push any dirty pages
* associated with the vnode.
+ * If the called_from_renewthread argument is TRUE, it has been called
+ * from the NFSv4 renew thread and, as such, cannot block indefinitely
+ * waiting for a buffer write to complete.
*/
int
ncl_flush(struct vnode *vp, int waitfor, struct ucred *cred, struct thread *td,
- int commit)
+ int commit, int called_from_renewthread)
{
struct nfsnode *np = VTONFS(vp);
struct buf *bp;
@@ -2513,6 +2516,8 @@ ncl_flush(struct vnode *vp, int waitfor, struct ucred *cred, struct thread *td,
struct buf *bvec_on_stack[NFS_COMMITBVECSIZ];
int bvecsize = 0, bveccount;
+ if (called_from_renewthread != 0)
+ slptimeo = hz;
if (nmp->nm_flag & NFSMNT_INT)
slpflag = NFS_PCATCH;
if (!commit)
@@ -2708,6 +2713,14 @@ loop:
error = 0;
goto loop;
}
+ if (called_from_renewthread != 0) {
+ /*
+ * Return EIO so the flush will be retried
+ * later.
+ */
+ error = EIO;
+ goto done;
+ }
if (newnfs_sigintr(nmp, td)) {
error = EINTR;
goto done;
@@ -2747,6 +2760,14 @@ loop:
error = bufobj_wwait(bo, slpflag, slptimeo);
if (error) {
BO_UNLOCK(bo);
+ if (called_from_renewthread != 0) {
+ /*
+ * Return EIO so that the flush will be
+ * retried later.
+ */
+ error = EIO;
+ goto done;
+ }
error = newnfs_sigintr(nmp, td);
if (error)
goto done;
@@ -2838,7 +2859,7 @@ nfs_advlock(struct vop_advlock_args *ap)
*/
if (ap->a_op == F_UNLCK &&
nfscl_checkwritelocked(vp, ap->a_fl, cred, td))
- (void) ncl_flush(vp, MNT_WAIT, cred, td, 1);
+ (void) ncl_flush(vp, MNT_WAIT, cred, td, 1, 0);
/*
* Loop around doing the lock op, while a blocking lock
@@ -2850,7 +2871,8 @@ nfs_advlock(struct vop_advlock_args *ap)
if (ret == NFSERR_DENIED && (ap->a_flags & F_WAIT) &&
ap->a_op == F_SETLK) {
VOP_UNLOCK(vp, 0);
- error = nfs_catnap(PZERO | PCATCH, "ncladvl");
+ error = nfs_catnap(PZERO | PCATCH, ret,
+ "ncladvl");
if (error)
return (EINTR);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 3b7f8d0..ba367e3 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -869,6 +869,7 @@ nfsvno_mkdir(struct nameidata *ndp, struct nfsvattr *nvap, uid_t saved_uid,
else
vput(ndp->ni_dvp);
vrele(ndp->ni_vp);
+ nfsvno_relpathbuf(ndp);
return (EEXIST);
}
error = VOP_MKDIR(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd,
@@ -1396,24 +1397,16 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct vnode *vp,
* nfs readdir service
* - mallocs what it thinks is enough to read
* count rounded up to a multiple of DIRBLKSIZ <= NFS_MAXREADDIR
- * - calls nfsvno_readdir()
+ * - calls VOP_READDIR()
* - loops around building the reply
* if the output generated exceeds count break out of loop
* The NFSM_CLGET macro is used here so that the reply will be packed
* tightly in mbuf clusters.
- * - it only knows that it has encountered eof when the nfsvno_readdir()
- * reads nothing
- * - as such one readdir rpc will return eof false although you are there
- * and then the next will return eof
* - it trims out records with d_fileno == 0
* this doesn't matter for Unix clients, but they might confuse clients
* for other os'.
* - it trims out records with d_type == DT_WHT
* these cannot be seen through NFS (unless we extend the protocol)
- * NB: It is tempting to set eof to true if the nfsvno_readdir() reads less
- * than requested, but this may not apply to all filesystems. For
- * example, client NFS does not { although it is never remote mounted
- * anyhow }
* The alternate call nfsrvd_readdirplus() does lookups as well.
* PS: The NFS protocol spec. does not clarify what the "count" byte
* argument is a count of.. just name strings and file id's or the
@@ -1455,7 +1448,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
}
toff = off;
cnt = fxdr_unsigned(int, *tl);
- if (cnt > NFS_SRVMAXDATA(nd))
+ if (cnt > NFS_SRVMAXDATA(nd) || cnt < 0)
cnt = NFS_SRVMAXDATA(nd);
siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
fullsiz = siz;
@@ -1473,6 +1466,13 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
nd->nd_repstat = NFSERR_BAD_COOKIE;
#endif
}
+ if (nd->nd_repstat == 0 && cnt == 0) {
+ if (nd->nd_flag & ND_NFSV2)
+ /* NFSv2 does not have NFSERR_TOOSMALL */
+ nd->nd_repstat = EPERM;
+ else
+ nd->nd_repstat = NFSERR_TOOSMALL;
+ }
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE,
@@ -1695,7 +1695,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
* Use the server's maximum data transfer size as the upper bound
* on reply datalen.
*/
- if (cnt > NFS_SRVMAXDATA(nd))
+ if (cnt > NFS_SRVMAXDATA(nd) || cnt < 0)
cnt = NFS_SRVMAXDATA(nd);
/*
@@ -1704,7 +1704,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
* so I set it to cnt for that case. I also round it up to the
* next multiple of DIRBLKSIZ.
*/
- if (siz == 0)
+ if (siz <= 0)
siz = cnt;
siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
@@ -2443,6 +2443,9 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam,
*credp = NULL;
exp->nes_numsecflavor = 0;
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
+ if (error != 0)
+ /* Make sure the server replies ESTALE to the client. */
+ error = ESTALE;
if (nam && !error) {
error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
&exp->nes_numsecflavor, &secflavors);
@@ -2671,24 +2674,23 @@ nfsrv_getsocksndseq(struct socket *so, tcp_seq *maxp, tcp_seq *unap)
{
struct inpcb *inp;
struct tcpcb *tp;
- int error = EPIPE;
- INP_INFO_RLOCK(&V_tcbinfo);
inp = sotoinpcb(so);
- if (inp == NULL) {
- INP_INFO_RUNLOCK(&V_tcbinfo);
- return (error);
- }
+ KASSERT(inp != NULL, ("nfsrv_getsocksndseq: inp == NULL"));
INP_RLOCK(inp);
- INP_INFO_RUNLOCK(&V_tcbinfo);
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+ INP_RUNLOCK(inp);
+ return (EPIPE);
+ }
tp = intotcpcb(inp);
- if (tp != NULL && tp->t_state == TCPS_ESTABLISHED) {
- *maxp = tp->snd_max;
- *unap = tp->snd_una;
- error = 0;
+ if (tp->t_state != TCPS_ESTABLISHED) {
+ INP_RUNLOCK(inp);
+ return (EPIPE);
}
+ *maxp = tp->snd_max;
+ *unap = tp->snd_una;
INP_RUNLOCK(inp);
- return (error);
+ return (0);
}
/*
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index e56610b..50fa822 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -1086,7 +1086,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram,
case NFFIFO:
break;
case NFDIR:
- cnflags = LOCKPARENT;
+ cnflags = (LOCKPARENT | SAVENAME);
break;
default:
nd->nd_repstat = NFSERR_BADTYPE;
@@ -1549,7 +1549,8 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
NFSVOPUNLOCK(dp, 0, p);
}
}
- NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, LOCKPARENT);
+ NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
+ LOCKPARENT | SAVENAME);
if (!nd->nd_repstat) {
nfsvno_setpathbuf(&named, &bufp, &hashp);
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
@@ -1743,7 +1744,8 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram,
nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
return (0);
}
- NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, LOCKPARENT);
+ NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
+ LOCKPARENT | SAVENAME);
nfsvno_setpathbuf(&named, &bufp, &hashp);
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
if (error) {
@@ -2084,6 +2086,10 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int isdgram,
if (flags & NFSLCK_OPENTOLOCK) {
NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED + NFSX_STATEID);
i = fxdr_unsigned(int, *(tl+4+(NFSX_STATEID / NFSX_UNSIGNED)));
+ if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
+ nd->nd_repstat = NFSERR_BADXDR;
+ goto nfsmout;
+ }
MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
M_NFSDSTATE, M_WAITOK);
stp->ls_ownerlen = i;
@@ -2227,6 +2233,10 @@ nfsrvd_lockt(struct nfsrv_descript *nd, __unused int isdgram,
NFSM_DISSECT(tl, u_int32_t *, 8 * NFSX_UNSIGNED);
i = fxdr_unsigned(int, *(tl + 7));
+ if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
+ nd->nd_repstat = NFSERR_BADXDR;
+ goto nfsmout;
+ }
MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
M_NFSDSTATE, M_WAITOK);
stp->ls_ownerlen = i;
@@ -2348,6 +2358,8 @@ nfsrvd_locku(struct nfsrv_descript *nd, __unused int isdgram,
break;
default:
nd->nd_repstat = NFSERR_BADXDR;
+ free(stp, M_NFSDSTATE);
+ free(lop, M_NFSDLOCK);
goto nfsmout;
};
stp->ls_ownerlen = 0;
@@ -2437,6 +2449,14 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
named.ni_cnd.cn_nameiop = 0;
NFSM_DISSECT(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
i = fxdr_unsigned(int, *(tl + 5));
+ if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
+ nd->nd_repstat = NFSERR_BADXDR;
+ vrele(dp);
+#ifdef NFS4_ACL_EXTATTR_NAME
+ acl_free(aclp);
+#endif
+ return (0);
+ }
MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
M_NFSDSTATE, M_WAITOK);
stp->ls_ownerlen = i;
@@ -3389,6 +3409,10 @@ nfsrvd_releaselckown(struct nfsrv_descript *nd, __unused int isdgram,
}
NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
len = fxdr_unsigned(int, *(tl + 2));
+ if (len <= 0 || len > NFSV4_OPAQUELIMIT) {
+ nd->nd_repstat = NFSERR_BADXDR;
+ return (0);
+ }
MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + len,
M_NFSDSTATE, M_WAITOK);
stp->ls_ownerlen = len;
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 3e38cf4..e475cb7 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -65,11 +65,11 @@ static void nfsrv_dumpaclient(struct nfsclient *clp,
struct nfsd_dumpclients *dumpp);
static void nfsrv_freeopenowner(struct nfsstate *stp, int cansleep,
NFSPROC_T *p);
-static int nfsrv_freeopen(struct nfsstate *stp, int *freedlockp,
- int cansleep, NFSPROC_T *p);
-static int nfsrv_freelockowner(struct nfsstate *stp, int *freedlockp,
- int cansleep, NFSPROC_T *p);
-static int nfsrv_freeallnfslocks(struct nfsstate *stp, int *freedlockp,
+static int nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep,
+ NFSPROC_T *p);
+static void nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep,
+ NFSPROC_T *p);
+static void nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp,
int cansleep, NFSPROC_T *p);
static void nfsrv_freenfslock(struct nfslock *lop);
static void nfsrv_freenfslockfile(struct nfslockfile *lfp);
@@ -80,8 +80,8 @@ static void nfsrv_getowner(struct nfsstatehead *hp, struct nfsstate *new_stp,
struct nfsstate **stpp);
static int nfsrv_getlockfh(vnode_t vp, u_short flags,
struct nfslockfile **new_lfpp, fhandle_t *nfhp, NFSPROC_T *p);
-static int nfsrv_getlockfile(u_short flags,
- struct nfslockfile **new_lfpp, struct nfslockfile **lfpp, fhandle_t *nfhp);
+static int nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
+ struct nfslockfile **lfpp, fhandle_t *nfhp, int lockit);
static void nfsrv_insertlock(struct nfslock *new_lop,
struct nfslock *insert_lop, struct nfsstate *stp, struct nfslockfile *lfp);
static void nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp,
@@ -109,9 +109,20 @@ static time_t nfsrv_leaseexpiry(void);
static void nfsrv_delaydelegtimeout(struct nfsstate *stp);
static int nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid,
struct nfsstate *stp, struct nfsrvcache *op);
-static void nfsrv_locallocks(vnode_t vp, struct nfslockfile *lfp,
- NFSPROC_T *p);
static int nfsrv_nootherstate(struct nfsstate *stp);
+static int nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags,
+ uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p);
+static void nfsrv_localunlock(vnode_t vp, struct nfslockfile *lfp,
+ uint64_t init_first, uint64_t init_end, NFSPROC_T *p);
+static int nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags,
+ int oldflags, uint64_t first, uint64_t end, struct nfslockconflict *cfp,
+ NFSPROC_T *p);
+static void nfsrv_locallock_rollback(vnode_t vp, struct nfslockfile *lfp,
+ NFSPROC_T *p);
+static void nfsrv_locallock_commit(struct nfslockfile *lfp, int flags,
+ uint64_t first, uint64_t end);
+static void nfsrv_locklf(struct nfslockfile *lfp);
+static void nfsrv_unlocklf(struct nfslockfile *lfp);
/*
* Scan the client list for a match and either return the current one,
@@ -683,7 +694,7 @@ nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt,
ret = nfsrv_getlockfh(vp, 0, NULL, &nfh, p);
NFSLOCKSTATE();
if (!ret)
- ret = nfsrv_getlockfile(0, NULL, &lfp, &nfh);
+ ret = nfsrv_getlockfile(0, NULL, &lfp, &nfh, 0);
if (ret) {
ldumpp[0].ndlck_clid.nclid_idlen = 0;
NFSUNLOCKSTATE();
@@ -927,9 +938,8 @@ nfsrv_cleanclient(struct nfsclient *clp, NFSPROC_T *p)
{
struct nfsstate *stp, *nstp;
- LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) {
+ LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp)
nfsrv_freeopenowner(stp, 1, p);
- }
}
/*
@@ -993,7 +1003,10 @@ nfsrv_freedeleg(struct nfsstate *stp)
LIST_REMOVE(stp, ls_file);
lfp = stp->ls_lfp;
if (LIST_EMPTY(&lfp->lf_open) &&
- LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg))
+ LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg) &&
+ LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) &&
+ lfp->lf_usecount == 0 &&
+ nfsv4_testlock(&lfp->lf_locallock_lck) == 0)
nfsrv_freenfslockfile(lfp);
FREE((caddr_t)stp, M_NFSDSTATE);
newnfsstats.srvdelegates--;
@@ -1031,16 +1044,14 @@ nfsrv_freeopenowner(struct nfsstate *stp, int cansleep, NFSPROC_T *p)
* This function frees an open (nfsstate open structure) with all associated
* lock_owners and locks. It also frees the nfslockfile structure iff there
* are no other opens on the file.
- * Must be called with soft clock interrupts disabled.
* Returns 1 if it free'd the nfslockfile, 0 otherwise.
*/
static int
-nfsrv_freeopen(struct nfsstate *stp, int *freedlockp, int cansleep,
- NFSPROC_T *p)
+nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p)
{
struct nfsstate *nstp, *tstp;
struct nfslockfile *lfp;
- int ret = 0, ret2;
+ int ret;
LIST_REMOVE(stp, ls_hash);
LIST_REMOVE(stp, ls_list);
@@ -1048,28 +1059,27 @@ nfsrv_freeopen(struct nfsstate *stp, int *freedlockp, int cansleep,
lfp = stp->ls_lfp;
/*
+ * Now, free all lockowners associated with this open.
+ */
+ LIST_FOREACH_SAFE(tstp, &stp->ls_open, ls_list, nstp)
+ nfsrv_freelockowner(tstp, vp, cansleep, p);
+
+ /*
* The nfslockfile is freed here if there are no locks
* associated with the open.
* If there are locks associated with the open, the
* nfslockfile structure can be freed via nfsrv_freelockowner().
* (That is why the call must be here instead of after the loop.)
*/
- if (LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) &&
- LIST_EMPTY(&lfp->lf_deleg)) {
+ if (lfp != NULL && LIST_EMPTY(&lfp->lf_open) &&
+ LIST_EMPTY(&lfp->lf_deleg) && LIST_EMPTY(&lfp->lf_lock) &&
+ LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) &&
+ lfp->lf_usecount == 0 &&
+ (cansleep != 0 || nfsv4_testlock(&lfp->lf_locallock_lck) == 0)) {
nfsrv_freenfslockfile(lfp);
ret = 1;
- }
- /*
- * Now, free all lockowners associated with this open.
- */
- nstp = LIST_FIRST(&stp->ls_open);
- while (nstp != LIST_END(&stp->ls_open)) {
- tstp = nstp;
- nstp = LIST_NEXT(nstp, ls_list);
- ret2 = nfsrv_freelockowner(tstp, freedlockp, cansleep, p);
- if (ret == 0 && ret2 != 0)
- ret = ret2;
- }
+ } else
+ ret = 0;
FREE((caddr_t)stp, M_NFSDSTATE);
newnfsstats.srvopens--;
nfsrv_openpluslock--;
@@ -1078,79 +1088,76 @@ nfsrv_freeopen(struct nfsstate *stp, int *freedlockp, int cansleep,
/*
* Frees a lockowner and all associated locks.
- * It also frees the nfslockfile structure, if there are no more
- * references to it.
- * Must be called with soft clock interrupts disabled.
- * Returns 1 if it free'd the nfslockfile structure, 1 otherwise.
*/
-static int
-nfsrv_freelockowner(struct nfsstate *stp, int *freedlockp, int cansleep,
+static void
+nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep,
NFSPROC_T *p)
{
- int ret;
LIST_REMOVE(stp, ls_hash);
LIST_REMOVE(stp, ls_list);
- ret = nfsrv_freeallnfslocks(stp, freedlockp, cansleep, p);
+ nfsrv_freeallnfslocks(stp, vp, cansleep, p);
if (stp->ls_op)
nfsrvd_derefcache(stp->ls_op);
FREE((caddr_t)stp, M_NFSDSTATE);
newnfsstats.srvlockowners--;
nfsrv_openpluslock--;
- return (ret);
}
/*
* Free all the nfs locks on a lockowner.
- * Returns 1 if it free'd the nfslockfile structure, 0 otherwise.
- * If any byte range lock is free'd, *freedlockp is set to 1.
*/
-static int
-nfsrv_freeallnfslocks(struct nfsstate *stp, int *freedlockp, int cansleep,
+static void
+nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
NFSPROC_T *p)
{
struct nfslock *lop, *nlop;
- struct nfslockfile *lfp = NULL, *olfp = NULL;
- int ret = 0;
+ struct nfsrollback *rlp, *nrlp;
+ struct nfslockfile *lfp = NULL;
+ int gottvp = 0;
+ vnode_t tvp = NULL;
lop = LIST_FIRST(&stp->ls_lock);
while (lop != LIST_END(&stp->ls_lock)) {
nlop = LIST_NEXT(lop, lo_lckowner);
/*
- * Since locks off a lockowner are ordered by
- * file, you should update the local locks when
- * you hit the next file OR the end of the lock
- * list. If there are no locks for other owners,
- * it must be done before the lockowner is discarded.
- * (All this only applies if cansleep == 1.)
+ * Since all locks should be for the same file, lfp should
+ * not change.
*/
- olfp = lfp;
- lfp = lop->lo_lfp;
- nfsrv_freenfslock(lop);
- if (freedlockp)
- *freedlockp = 1;
- if (LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) &&
- LIST_EMPTY(&lfp->lf_deleg)) {
- if (cansleep)
- nfsrv_locallocks(NULL, lfp, p);
- nfsrv_freenfslockfile(lfp);
- /*
- * Set the pointer(s) to this lockowner NULL,
- * to indicate it has been free'd and local
- * locks discarded already.
- */
- if (olfp == lfp)
- olfp = NULL;
- lfp = NULL;
- ret = 1;
+ if (lfp == NULL)
+ lfp = lop->lo_lfp;
+ else if (lfp != lop->lo_lfp)
+ panic("allnfslocks");
+ /*
+ * If vp is NULL and cansleep != 0, a vnode must be acquired
+ * from the file handle. This only occurs when called from
+ * nfsrv_cleanclient().
+ */
+ if (gottvp == 0) {
+ if (nfsrv_dolocallocks == 0)
+ tvp = NULL;
+ else if (vp == NULL && cansleep != 0)
+ tvp = nfsvno_getvp(&lfp->lf_fh);
+ else
+ tvp = vp;
+ gottvp = 1;
+ }
+
+ if (tvp != NULL) {
+ if (cansleep == 0)
+ panic("allnfs2");
+ nfsrv_localunlock(tvp, lfp, lop->lo_first,
+ lop->lo_end, p);
+ LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list,
+ nrlp)
+ free(rlp, M_NFSDROLLBACK);
+ LIST_INIT(&lfp->lf_rollback);
}
- if (cansleep && olfp != lfp && olfp != NULL)
- nfsrv_locallocks(NULL, olfp, p);
+ nfsrv_freenfslock(lop);
lop = nlop;
}
- if (cansleep && lfp != NULL)
- nfsrv_locallocks(NULL, olfp, p);
- return (ret);
+ if (vp == NULL && tvp != NULL)
+ vput(tvp);
}
/*
@@ -1161,11 +1168,13 @@ static void
nfsrv_freenfslock(struct nfslock *lop)
{
- LIST_REMOVE(lop, lo_lckfile);
+ if (lop->lo_lckfile.le_prev != NULL) {
+ LIST_REMOVE(lop, lo_lckfile);
+ newnfsstats.srvlocks--;
+ nfsrv_openpluslock--;
+ }
LIST_REMOVE(lop, lo_lckowner);
FREE((caddr_t)lop, M_NFSDLOCK);
- newnfsstats.srvlocks--;
- nfsrv_openpluslock--;
}
/*
@@ -1240,7 +1249,8 @@ nfsrv_getowner(struct nfsstatehead *hp, struct nfsstate *new_stp,
APPLESTATIC int
nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
struct nfslock **new_lopp, struct nfslockconflict *cfp,
- nfsquad_t clientid, nfsv4stateid_t *stateidp, __unused struct nfsexstuff *exp,
+ nfsquad_t clientid, nfsv4stateid_t *stateidp,
+ __unused struct nfsexstuff *exp,
struct nfsrv_descript *nd, NFSPROC_T *p)
{
struct nfslock *lop;
@@ -1253,9 +1263,11 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
struct nfsstate *stp, *lckstp = NULL;
struct nfsclient *clp = NULL;
u_int32_t bits;
- int error = 0, haslock = 0, ret;
- int getlckret, delegation = 0;
+ int error = 0, haslock = 0, ret, reterr;
+ int getlckret, delegation = 0, filestruct_locked;
fhandle_t nfh;
+ uint64_t first, end;
+ uint32_t lock_flags;
if (new_stp->ls_flags & (NFSLCK_CHECK | NFSLCK_SETATTR)) {
/*
@@ -1290,23 +1302,6 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
return (NFSERR_RESOURCE);
/*
- * For Lock, check for a conflict with a lock held by
- * a process running locally on the server now, before
- * monkeying with nfsd state. Since the vp is locked, any
- * other local calls are blocked during this Op.
- */
- if (new_stp->ls_flags & NFSLCK_LOCK) {
- if (new_lop->lo_flags & NFSLCK_WRITE)
- error = nfsvno_localconflict(vp, F_WRLCK,
- new_lop->lo_first, new_lop->lo_end, cfp, p);
- else
- error = nfsvno_localconflict(vp, F_RDLCK,
- new_lop->lo_first, new_lop->lo_end, cfp, p);
- if (error)
- return (error);
- }
-
- /*
* For the lock case, get another nfslock structure,
* just in case we need it.
* Malloc now, before we start sifting through the linked lists,
@@ -1316,6 +1311,9 @@ tryagain:
if (new_stp->ls_flags & NFSLCK_LOCK)
MALLOC(other_lop, struct nfslock *, sizeof (struct nfslock),
M_NFSDLOCK, M_WAITOK);
+ filestruct_locked = 0;
+ reterr = 0;
+ lfp = NULL;
/*
* Get the lockfile structure for CFH now, so we can do a sanity
@@ -1324,22 +1322,41 @@ tryagain:
* shouldn't be incremented for this case.
* If nfsrv_getlockfile() returns -1, it means "not found", which
* will be handled later.
+ * If we are doing Lock/LockU and local locking is enabled, sleep
+ * lock the nfslockfile structure.
*/
getlckret = nfsrv_getlockfh(vp, new_stp->ls_flags, NULL, &nfh, p);
NFSLOCKSTATE();
- if (!getlckret)
- getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL,
- &lfp, &nfh);
- if (getlckret != 0 && getlckret != -1) {
- NFSUNLOCKSTATE();
- if (other_lop)
- FREE((caddr_t)other_lop, M_NFSDLOCK);
- if (haslock) {
- NFSLOCKV4ROOTMUTEX();
- nfsv4_unlock(&nfsv4rootfs_lock, 1);
- NFSUNLOCKV4ROOTMUTEX();
+ if (getlckret == 0) {
+ if ((new_stp->ls_flags & (NFSLCK_LOCK | NFSLCK_UNLOCK)) != 0 &&
+ nfsrv_dolocallocks != 0 && nd->nd_repstat == 0) {
+ getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL,
+ &lfp, &nfh, 1);
+ if (getlckret == 0)
+ filestruct_locked = 1;
+ } else
+ getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL,
+ &lfp, &nfh, 0);
+ }
+ if (getlckret != 0 && getlckret != -1)
+ reterr = getlckret;
+
+ if (filestruct_locked != 0) {
+ LIST_INIT(&lfp->lf_rollback);
+ if ((new_stp->ls_flags & NFSLCK_LOCK)) {
+ /*
+ * For local locking, do the advisory locking now, so
+ * that any conflict can be detected. A failure later
+ * can be rolled back locally. If an error is returned,
+ * struct nfslockfile has been unlocked and any local
+ * locking rolled back.
+ */
+ NFSUNLOCKSTATE();
+ reterr = nfsrv_locallock(vp, lfp,
+ (new_lop->lo_flags & (NFSLCK_READ | NFSLCK_WRITE)),
+ new_lop->lo_first, new_lop->lo_end, cfp, p);
+ NFSLOCKSTATE();
}
- return (getlckret);
}
/*
@@ -1381,11 +1398,11 @@ tryagain:
*/
if (error == 0 && (stp->ls_flags & NFSLCK_OPEN) &&
((stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM) ||
- (getlckret != -1 && stp->ls_lfp != lfp)))
+ (getlckret == 0 && stp->ls_lfp != lfp)))
error = NFSERR_BADSTATEID;
if (error == 0 &&
(stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) &&
- getlckret != -1 && stp->ls_lfp != lfp)
+ getlckret == 0 && stp->ls_lfp != lfp)
error = NFSERR_BADSTATEID;
/*
@@ -1398,7 +1415,7 @@ tryagain:
*/
if (error == 0 && (stp->ls_flags &
(NFSLCK_OPEN | NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) == 0 &&
- getlckret != -1 && stp->ls_lfp != lfp) {
+ getlckret == 0 && stp->ls_lfp != lfp) {
#ifdef DIAGNOSTIC
printf("Got a lock statid for different file open\n");
#endif
@@ -1478,12 +1495,30 @@ tryagain:
nfsrv_markstable(clp);
/*
- * If nd_repstat is set, we can return that now, since the
- * seqid# has been incremented.
+ * At this point, either error == NFSERR_BADSTATEID or the
+ * seqid# has been updated, so we can return any error.
+ * If error == 0, there may be an error in:
+ * nd_repstat - Set by the calling function.
+ * reterr - Set above, if getting the nfslockfile structure
+ * or acquiring the local lock failed.
+ * (If both of these are set, nd_repstat should probably be
+ * returned, since that error was detected before this
+ * function call.)
*/
- if (nd->nd_repstat && !error)
- error = nd->nd_repstat;
- if (error) {
+ if (error != 0 || nd->nd_repstat != 0 || reterr != 0) {
+ if (error == 0) {
+ if (nd->nd_repstat != 0)
+ error = nd->nd_repstat;
+ else
+ error = reterr;
+ }
+ if (filestruct_locked != 0) {
+ /* Roll back local locks. */
+ NFSUNLOCKSTATE();
+ nfsrv_locallock_rollback(vp, lfp, p);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ }
NFSUNLOCKSTATE();
if (other_lop)
FREE((caddr_t)other_lop, M_NFSDLOCK);
@@ -1569,6 +1604,13 @@ tryagain:
((new_stp->ls_flags & (NFSLCK_CHECK|NFSLCK_WRITEACCESS)) ==
(NFSLCK_CHECK | NFSLCK_WRITEACCESS) &&
!(mystp->ls_flags & NFSLCK_WRITEACCESS))) {
+ if (filestruct_locked != 0) {
+ /* Roll back local locks. */
+ NFSUNLOCKSTATE();
+ nfsrv_locallock_rollback(vp, lfp, p);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ }
NFSUNLOCKSTATE();
if (other_lop)
FREE((caddr_t)other_lop, M_NFSDLOCK);
@@ -1680,11 +1722,18 @@ tryagain:
(new_lop->lo_flags & NFSLCK_WRITE) &&
(clp != tstp->ls_clp ||
(tstp->ls_flags & NFSLCK_DELEGREAD)))) {
+ if (filestruct_locked != 0) {
+ /* Roll back local locks. */
+ NFSUNLOCKSTATE();
+ nfsrv_locallock_rollback(vp, lfp, p);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ }
ret = nfsrv_delegconflict(tstp, &haslock, p, vp);
if (ret) {
/*
* nfsrv_delegconflict unlocks state when it
- * returns non-zero.
+ * returns non-zero, which it always does.
*/
if (other_lop) {
FREE((caddr_t)other_lop, M_NFSDLOCK);
@@ -1696,6 +1745,7 @@ tryagain:
}
return (ret);
}
+ /* Never gets here. */
}
tstp = nstp;
}
@@ -1706,32 +1756,21 @@ tryagain:
* just let it happen.)
*/
if (new_stp->ls_flags & NFSLCK_UNLOCK) {
+ first = new_lop->lo_first;
+ end = new_lop->lo_end;
nfsrv_updatelock(stp, new_lopp, &other_lop, lfp);
stateidp->seqid = ++(stp->ls_stateid.seqid);
stateidp->other[0] = stp->ls_stateid.other[0];
stateidp->other[1] = stp->ls_stateid.other[1];
stateidp->other[2] = stp->ls_stateid.other[2];
- /*
- * For a non-empty flp->lf_lock list, I believe
- * nfsrv_locallocks() can safely traverse the list, including
- * sleeping, for two reasons:
- * 1 - The Lock/LockU/Close Ops all require a locked
- * vnode for the file and we currently have that.
- * 2 - The only other thing that modifies a non-empty
- * list is nfsrv_cleanclient() and it is always
- * done with the exclusive nfsv4rootfs_lock held.
- * Since this Op in progress holds either a shared or
- * exclusive lock on nfsv4rootfs_lock, that can't
- * happen now.
- * However, the structure pointed to by lfp can go
- * in many places for an empty list, so that is handled
- * by passing a NULL pointer to nfsrv_locallocks().
- * Do that check now, while we are still SMP safe.
- */
- if (LIST_EMPTY(&lfp->lf_lock))
- lfp = NULL;
+ if (filestruct_locked != 0) {
+ NFSUNLOCKSTATE();
+ /* Update the local locks. */
+ nfsrv_localunlock(vp, lfp, first, end, p);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ }
NFSUNLOCKSTATE();
- nfsrv_locallocks(vp, lfp, p);
if (haslock) {
NFSLOCKV4ROOTMUTEX();
nfsv4_unlock(&nfsv4rootfs_lock, 1);
@@ -1763,6 +1802,13 @@ tryagain:
}
ret = nfsrv_clientconflict(lop->lo_stp->ls_clp,&haslock,vp,p);
if (ret) {
+ if (filestruct_locked != 0) {
+ /* Roll back local locks. */
+ nfsrv_locallock_rollback(vp, lfp, p);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ NFSUNLOCKSTATE();
+ }
/*
* nfsrv_clientconflict() unlocks state when it
* returns non-zero.
@@ -1790,6 +1836,13 @@ tryagain:
error = NFSERR_LOCKED;
else
error = NFSERR_DENIED;
+ if (filestruct_locked != 0) {
+ /* Roll back local locks. */
+ NFSUNLOCKSTATE();
+ nfsrv_locallock_rollback(vp, lfp, p);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ }
NFSUNLOCKSTATE();
if (haslock) {
NFSLOCKV4ROOTMUTEX();
@@ -1820,6 +1873,9 @@ tryagain:
* - exist_lock_owner where lock_owner exists
* - open_to_lock_owner with new lock_owner
*/
+ first = new_lop->lo_first;
+ end = new_lop->lo_end;
+ lock_flags = new_lop->lo_flags;
if (!(new_stp->ls_flags & NFSLCK_OPENTOLOCK)) {
nfsrv_updatelock(lckstp, new_lopp, &other_lop, lfp);
stateidp->seqid = ++(lckstp->ls_stateid.seqid);
@@ -1854,11 +1910,13 @@ tryagain:
newnfsstats.srvlockowners++;
nfsrv_openpluslock++;
}
- /* See comment above, w.r.t. nfsrv_locallocks(). */
- if (LIST_EMPTY(&lfp->lf_lock))
- lfp = NULL;
+ if (filestruct_locked != 0) {
+ NFSUNLOCKSTATE();
+ nfsrv_locallock_commit(lfp, lock_flags, first, end);
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ }
NFSUNLOCKSTATE();
- nfsrv_locallocks(vp, lfp, p);
if (haslock) {
NFSLOCKV4ROOTMUTEX();
nfsv4_unlock(&nfsv4rootfs_lock, 1);
@@ -1984,7 +2042,7 @@ tryagain:
error = getfhret;
else
error = nfsrv_getlockfile(new_stp->ls_flags, &new_lfp, &lfp,
- NULL);
+ NULL, 0);
if (new_lfp)
FREE((caddr_t)new_lfp, M_NFSDLOCKFILE);
if (error) {
@@ -2227,7 +2285,7 @@ tryagain:
error = getfhret;
else
error = nfsrv_getlockfile(new_stp->ls_flags, &new_lfp, &lfp,
- NULL);
+ NULL, 0);
if (new_lfp)
FREE((caddr_t)new_lfp, M_NFSDLOCKFILE);
if (error) {
@@ -2775,7 +2833,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
struct nfsclient *clp;
struct nfslockfile *lfp;
u_int32_t bits;
- int error, gotstate = 0, len = 0, ret, freedlock;
+ int error, gotstate = 0, len = 0;
u_char client[NFSV4_OPAQUELIMIT];
/*
@@ -2863,26 +2921,19 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
} else if (new_stp->ls_flags & NFSLCK_CLOSE) {
ownerstp = stp->ls_openowner;
lfp = stp->ls_lfp;
- freedlock = 0;
- ret = nfsrv_freeopen(stp, &freedlock, 0, p);
- /* See comment on nfsrv_lockctrl() w.r.t. locallocks. */
- if (ret) {
- lfp = NULL;
+ if (nfsrv_dolocallocks != 0 && !LIST_EMPTY(&stp->ls_open)) {
+ /* Get the lf lock */
+ nfsrv_locklf(lfp);
+ NFSUNLOCKSTATE();
+ if (nfsrv_freeopen(stp, vp, 1, p) == 0) {
+ NFSLOCKSTATE();
+ nfsrv_unlocklf(lfp);
+ NFSUNLOCKSTATE();
+ }
} else {
- if (LIST_EMPTY(&lfp->lf_lock))
- lfp = NULL;
- }
- /*
- * For now, I won't do this. The openowner should be
- * free'd in NFSNOOPEN seconds and it will be deref'd then.
- if (LIST_EMPTY(&ownerstp->ls_open) && ownerstp->ls_op) {
- nfsrvd_derefcache(ownerstp->ls_op);
- ownerstp->ls_op = NULL;
+ (void) nfsrv_freeopen(stp, NULL, 0, p);
+ NFSUNLOCKSTATE();
}
- */
- NFSUNLOCKSTATE();
- if (freedlock && lfp != NULL)
- nfsrv_locallocks(vp, lfp, p);
} else {
/*
* Update the share bits, making sure that the new set are a
@@ -3024,7 +3075,7 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
!NFSBCMP(stp->ls_owner, new_stp->ls_owner,
stp->ls_ownerlen)){
if (LIST_EMPTY(&stp->ls_lock)) {
- (void) nfsrv_freelockowner(stp, NULL, 0, p);
+ nfsrv_freelockowner(stp, NULL, 0, p);
} else {
NFSUNLOCKSTATE();
return (NFSERR_LOCKSHELD);
@@ -3072,7 +3123,7 @@ nfsrv_getlockfh(vnode_t vp, u_short flags,
*/
static int
nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
- struct nfslockfile **lfpp, fhandle_t *nfhp)
+ struct nfslockfile **lfpp, fhandle_t *nfhp, int lockit)
{
struct nfslockfile *lfp;
fhandle_t *fhp = NULL, *tfhp;
@@ -3096,6 +3147,8 @@ nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
LIST_FOREACH(lfp, hp, lf_hash) {
tfhp = &lfp->lf_fh;
if (NFSVNO_CMPFH(fhp, tfhp)) {
+ if (lockit)
+ nfsrv_locklf(lfp);
*lfpp = lfp;
return (0);
}
@@ -3109,6 +3162,11 @@ nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
LIST_INIT(&new_lfp->lf_open);
LIST_INIT(&new_lfp->lf_lock);
LIST_INIT(&new_lfp->lf_deleg);
+ LIST_INIT(&new_lfp->lf_locallock);
+ LIST_INIT(&new_lfp->lf_rollback);
+ new_lfp->lf_locallock_lck.nfslock_usecnt = 0;
+ new_lfp->lf_locallock_lck.nfslock_lock = 0;
+ new_lfp->lf_usecount = 0;
LIST_INSERT_HEAD(hp, new_lfp, lf_hash);
*lfpp = new_lfp;
*new_lfpp = NULL;
@@ -3130,31 +3188,39 @@ nfsrv_insertlock(struct nfslock *new_lop, struct nfslock *insert_lop,
new_lop->lo_stp = stp;
new_lop->lo_lfp = lfp;
- /* Insert in increasing lo_first order */
- lop = LIST_FIRST(&lfp->lf_lock);
- if (lop == LIST_END(&lfp->lf_lock) ||
- new_lop->lo_first <= lop->lo_first) {
- LIST_INSERT_HEAD(&lfp->lf_lock, new_lop, lo_lckfile);
- } else {
- nlop = LIST_NEXT(lop, lo_lckfile);
- while (nlop != LIST_END(&lfp->lf_lock) &&
- nlop->lo_first < new_lop->lo_first) {
- lop = nlop;
+ if (stp != NULL) {
+ /* Insert in increasing lo_first order */
+ lop = LIST_FIRST(&lfp->lf_lock);
+ if (lop == LIST_END(&lfp->lf_lock) ||
+ new_lop->lo_first <= lop->lo_first) {
+ LIST_INSERT_HEAD(&lfp->lf_lock, new_lop, lo_lckfile);
+ } else {
nlop = LIST_NEXT(lop, lo_lckfile);
+ while (nlop != LIST_END(&lfp->lf_lock) &&
+ nlop->lo_first < new_lop->lo_first) {
+ lop = nlop;
+ nlop = LIST_NEXT(lop, lo_lckfile);
+ }
+ LIST_INSERT_AFTER(lop, new_lop, lo_lckfile);
}
- LIST_INSERT_AFTER(lop, new_lop, lo_lckfile);
+ } else {
+ new_lop->lo_lckfile.le_prev = NULL; /* list not used */
}
/*
- * Insert after insert_lop, which is overloaded as stp for
+ * Insert after insert_lop, which is overloaded as stp or lfp for
* an empty list.
*/
- if ((struct nfsstate *)insert_lop == stp)
+ if (stp == NULL && (struct nfslockfile *)insert_lop == lfp)
+ LIST_INSERT_HEAD(&lfp->lf_locallock, new_lop, lo_lckowner);
+ else if ((struct nfsstate *)insert_lop == stp)
LIST_INSERT_HEAD(&stp->ls_lock, new_lop, lo_lckowner);
else
LIST_INSERT_AFTER(insert_lop, new_lop, lo_lckowner);
- newnfsstats.srvlocks++;
- nfsrv_openpluslock++;
+ if (stp != NULL) {
+ newnfsstats.srvlocks++;
+ nfsrv_openpluslock++;
+ }
}
/*
@@ -3180,9 +3246,14 @@ nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp,
*/
if (new_lop->lo_flags & NFSLCK_UNLOCK)
unlock = 1;
- ilop = (struct nfslock *)stp;
- lop = LIST_FIRST(&stp->ls_lock);
- while (lop != LIST_END(&stp->ls_lock)) {
+ if (stp != NULL) {
+ ilop = (struct nfslock *)stp;
+ lop = LIST_FIRST(&stp->ls_lock);
+ } else {
+ ilop = (struct nfslock *)lfp;
+ lop = LIST_FIRST(&lfp->lf_locallock);
+ }
+ while (lop != NULL) {
/*
* Only check locks for this file that aren't before the start of
* new lock's range.
@@ -3278,8 +3349,7 @@ nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp,
}
ilop = lop;
lop = LIST_NEXT(lop, lo_lckowner);
- if (myfile && (lop == LIST_END(&stp->ls_lock) ||
- lop->lo_lfp != lfp))
+ if (myfile && (lop == NULL || lop->lo_lfp != lfp))
break;
}
@@ -4362,7 +4432,7 @@ nfsrv_checkremove(vnode_t vp, int remove, NFSPROC_T *p)
tryagain:
NFSLOCKSTATE();
if (!error)
- error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh);
+ error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh, 0);
if (error) {
NFSUNLOCKSTATE();
if (haslock) {
@@ -4508,7 +4578,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
100000)
return;
/* Sleep for a short period of time */
- (void) nfs_catnap(PZERO, "nfsremove");
+ (void) nfs_catnap(PZERO, 0, "nfsremove");
}
} while (error == NFSERR_DELAY);
}
@@ -4612,7 +4682,7 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
error = nfsrv_getlockfh(vp, NFSLCK_CHECK, NULL, &nfh, p);
NFSLOCKSTATE();
if (!error)
- error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh);
+ error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh, 0);
if (error) {
NFSUNLOCKSTATE();
if (error == -1)
@@ -4783,112 +4853,252 @@ nfsrv_delaydelegtimeout(struct nfsstate *stp)
}
/*
- * Go through a lock list and set local locks for all ranges.
- * This assumes that the lock list is sorted on increasing
- * lo_first and that the list won't change, despite the possibility
- * of sleeps.
+ * This function checks to see if there is any other state associated
+ * with the openowner for this Open.
+ * It returns 1 if there is no other state, 0 otherwise.
*/
-static void
-nfsrv_locallocks(vnode_t vp, struct nfslockfile *lfp,
- NFSPROC_T *p)
+static int
+nfsrv_nootherstate(struct nfsstate *stp)
{
- struct nfslock *lop, *nlop;
- vnode_t tvp;
- int newcollate, flags = 0;
- u_int64_t first = 0x0ull, end = 0x0ull;
+ struct nfsstate *tstp;
- if (!nfsrv_dolocallocks)
- return;
- /*
- * If vp is NULL, a vnode must be aquired from the file
- * handle.
- */
- if (vp == NULL) {
- if (lfp == NULL)
- panic("nfsrv_locallocks");
- tvp = nfsvno_getvp(&lfp->lf_fh);
- if (tvp == NULL)
- return;
- } else {
- tvp = vp;
+ LIST_FOREACH(tstp, &stp->ls_openowner->ls_open, ls_list) {
+ if (tstp != stp || !LIST_EMPTY(&tstp->ls_lock))
+ return (0);
}
+ return (1);
+}
- /*
- * If lfp == NULL, the lock list is empty, so just unlock
- * everything.
- */
- if (lfp == NULL) {
- (void) nfsvno_advlock(tvp, F_UNLCK, (u_int64_t)0,
- NFS64BITSSET, p);
- /* vp can't be NULL */
- return;
- }
+/*
+ * Create a list of lock deltas (changes to local byte range locking
+ * that can be rolled back using the list) and apply the changes via
+ * nfsvno_advlock(). Optionally, lock the list. It is expected that either
+ * the rollback or update function will be called after this.
+ * It returns an error (and rolls back, as required), if any nfsvno_advlock()
+ * call fails. If it returns an error, it will unlock the list.
+ */
+static int
+nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags,
+ uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p)
+{
+ struct nfslock *lop, *nlop;
+ int error = 0;
- /* handle whole file case first */
- lop = LIST_FIRST(&lfp->lf_lock);
- if (lop != LIST_END(&lfp->lf_lock) &&
- lop->lo_first == (u_int64_t)0 &&
- lop->lo_end == NFS64BITSSET) {
- if (lop->lo_flags & NFSLCK_WRITE)
- (void) nfsvno_advlock(tvp, F_WRLCK, lop->lo_first,
- lop->lo_end, p);
- else
- (void) nfsvno_advlock(tvp, F_RDLCK, lop->lo_first,
- lop->lo_end, p);
- if (vp == NULL)
- vput(tvp);
- return;
+ /* Loop through the list of locks. */
+ lop = LIST_FIRST(&lfp->lf_locallock);
+ while (first < end && lop != NULL) {
+ nlop = LIST_NEXT(lop, lo_lckowner);
+ if (first >= lop->lo_end) {
+ /* not there yet */
+ lop = nlop;
+ } else if (first < lop->lo_first) {
+ /* new one starts before entry in list */
+ if (end <= lop->lo_first) {
+ /* no overlap between old and new */
+ error = nfsrv_dolocal(vp, lfp, flags,
+ NFSLCK_UNLOCK, first, end, cfp, p);
+ if (error != 0)
+ break;
+ first = end;
+ } else {
+ /* handle fragment overlapped with new one */
+ error = nfsrv_dolocal(vp, lfp, flags,
+ NFSLCK_UNLOCK, first, lop->lo_first, cfp,
+ p);
+ if (error != 0)
+ break;
+ first = lop->lo_first;
+ }
+ } else {
+ /* new one overlaps this entry in list */
+ if (end <= lop->lo_end) {
+ /* overlaps all of new one */
+ error = nfsrv_dolocal(vp, lfp, flags,
+ lop->lo_flags, first, end, cfp, p);
+ if (error != 0)
+ break;
+ first = end;
+ } else {
+ /* handle fragment overlapped with new one */
+ error = nfsrv_dolocal(vp, lfp, flags,
+ lop->lo_flags, first, lop->lo_end, cfp, p);
+ if (error != 0)
+ break;
+ first = lop->lo_end;
+ lop = nlop;
+ }
+ }
}
+ if (first < end && error == 0)
+ /* handle fragment past end of list */
+ error = nfsrv_dolocal(vp, lfp, flags, NFSLCK_UNLOCK, first,
+ end, cfp, p);
+ return (error);
+}
- /*
- * Now, handle the separate byte ranges cases.
- */
- (void) nfsvno_advlock(tvp, F_UNLCK, (u_int64_t)0,
- NFS64BITSSET, p);
- newcollate = 1;
- while (lop != LIST_END(&lfp->lf_lock)) {
- nlop = LIST_NEXT(lop, lo_lckfile);
- if (newcollate) {
- first = lop->lo_first;
- end = lop->lo_end;
- flags = lop->lo_flags;
- newcollate = 0;
+/*
+ * Local lock unlock. Unlock all byte ranges that are no longer locked
+ * by NFSv4.
+ */
+static void
+nfsrv_localunlock(vnode_t vp, struct nfslockfile *lfp, uint64_t init_first,
+ uint64_t init_end, NFSPROC_T *p)
+{
+ struct nfslock *lop;
+
+ uint64_t first, end;
+
+ first = init_first;
+ end = init_end;
+ while (first < init_end) {
+ /* Loop through all nfs locks, adjusting first and end */
+ LIST_FOREACH(lop, &lfp->lf_lock, lo_lckfile) {
+ if (first >= lop->lo_first &&
+ first < lop->lo_end)
+ /* Overlaps initial part */
+ first = lop->lo_end;
+ else if (end > lop->lo_first &&
+ lop->lo_first >= first)
+ /* Begins before end and past first */
+ end = lop->lo_first;
+ if (first >= end)
+ /* shrunk to 0 so this iteration is done */
+ break;
}
- if (nlop != LIST_END(&lfp->lf_lock) &&
- flags == nlop->lo_flags &&
- end >= nlop->lo_first) {
- /* can collate this one */
- end = nlop->lo_end;
- } else {
- /* do the local lock and start again */
- if (flags & NFSLCK_WRITE)
- (void) nfsvno_advlock(tvp, F_WRLCK, first,
- end, p);
- else
- (void) nfsvno_advlock(tvp, F_RDLCK, first,
- end, p);
- newcollate = 1;
+ if (first < end) {
+ /* Unlock this segment */
+ (void) nfsrv_dolocal(vp, lfp, NFSLCK_UNLOCK,
+ NFSLCK_READ, first, end, NULL, p);
+ nfsrv_locallock_commit(lfp, NFSLCK_UNLOCK,
+ first, end);
}
- lop = nlop;
+ /* and move on to the rest of the range */
+ first = end;
+ end = init_end;
}
- if (vp == NULL)
- vput(tvp);
}
/*
- * This function checks to see if there is any other state associated
- * with the openowner for this Open.
- * It returns 1 if there is no other state, 0 otherwise.
+ * Do the local lock operation and update the rollback list, as required.
+ * Perform the rollback and return the error if nfsvno_advlock() fails.
*/
static int
-nfsrv_nootherstate(struct nfsstate *stp)
+nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, int oldflags,
+ uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p)
{
- struct nfsstate *tstp;
+ struct nfsrollback *rlp;
+ int error, ltype, oldltype;
- LIST_FOREACH(tstp, &stp->ls_openowner->ls_open, ls_list) {
- if (tstp != stp || !LIST_EMPTY(&tstp->ls_lock))
- return (0);
+ if (flags & NFSLCK_WRITE)
+ ltype = F_WRLCK;
+ else if (flags & NFSLCK_READ)
+ ltype = F_RDLCK;
+ else
+ ltype = F_UNLCK;
+ if (oldflags & NFSLCK_WRITE)
+ oldltype = F_WRLCK;
+ else if (oldflags & NFSLCK_READ)
+ oldltype = F_RDLCK;
+ else
+ oldltype = F_UNLCK;
+ if (ltype == oldltype || (oldltype == F_WRLCK && ltype == F_RDLCK))
+ /* nothing to do */
+ return (0);
+ error = nfsvno_advlock(vp, ltype, first, end, p);
+ if (error != 0) {
+ if (cfp != NULL) {
+ cfp->cl_clientid.lval[0] = 0;
+ cfp->cl_clientid.lval[1] = 0;
+ cfp->cl_first = 0;
+ cfp->cl_end = NFS64BITSSET;
+ cfp->cl_flags = NFSLCK_WRITE;
+ cfp->cl_ownerlen = 5;
+ NFSBCOPY("LOCAL", cfp->cl_owner, 5);
+ }
+ nfsrv_locallock_rollback(vp, lfp, p);
+ } else if (ltype != F_UNLCK) {
+ rlp = malloc(sizeof (struct nfsrollback), M_NFSDROLLBACK,
+ M_WAITOK);
+ rlp->rlck_first = first;
+ rlp->rlck_end = end;
+ rlp->rlck_type = oldltype;
+ LIST_INSERT_HEAD(&lfp->lf_rollback, rlp, rlck_list);
}
- return (1);
+ return (error);
+}
+
+/*
+ * Roll back local lock changes and free up the rollback list.
+ */
+static void
+nfsrv_locallock_rollback(vnode_t vp, struct nfslockfile *lfp, NFSPROC_T *p)
+{
+ struct nfsrollback *rlp, *nrlp;
+
+ LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, nrlp) {
+ (void) nfsvno_advlock(vp, rlp->rlck_type, rlp->rlck_first,
+ rlp->rlck_end, p);
+ free(rlp, M_NFSDROLLBACK);
+ }
+ LIST_INIT(&lfp->lf_rollback);
+}
+
+/*
+ * Update local lock list and delete rollback list (ie now committed to the
+ * local locks). Most of the work is done by the internal function.
+ */
+static void
+nfsrv_locallock_commit(struct nfslockfile *lfp, int flags, uint64_t first,
+ uint64_t end)
+{
+ struct nfsrollback *rlp, *nrlp;
+ struct nfslock *new_lop, *other_lop;
+
+ new_lop = malloc(sizeof (struct nfslock), M_NFSDLOCK, M_WAITOK);
+ if (flags & (NFSLCK_READ | NFSLCK_WRITE))
+ other_lop = malloc(sizeof (struct nfslock), M_NFSDLOCK,
+ M_WAITOK);
+ else
+ other_lop = NULL;
+ new_lop->lo_flags = flags;
+ new_lop->lo_first = first;
+ new_lop->lo_end = end;
+ nfsrv_updatelock(NULL, &new_lop, &other_lop, lfp);
+ if (new_lop != NULL)
+ free(new_lop, M_NFSDLOCK);
+ if (other_lop != NULL)
+ free(other_lop, M_NFSDLOCK);
+
+ /* and get rid of the rollback list */
+ LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, nrlp)
+ free(rlp, M_NFSDROLLBACK);
+ LIST_INIT(&lfp->lf_rollback);
+}
+
+/*
+ * Lock the struct nfslockfile for local lock updating.
+ */
+static void
+nfsrv_locklf(struct nfslockfile *lfp)
+{
+ int gotlock;
+
+ /* lf_usecount ensures *lfp won't be free'd */
+ lfp->lf_usecount++;
+ do {
+ gotlock = nfsv4_lock(&lfp->lf_locallock_lck, 1, NULL,
+ NFSSTATEMUTEXPTR);
+ } while (gotlock == 0);
+ lfp->lf_usecount--;
+}
+
+/*
+ * Unlock the struct nfslockfile after local lock updating.
+ */
+static void
+nfsrv_unlocklf(struct nfslockfile *lfp)
+{
+
+ nfsv4_unlock(&lfp->lf_locallock_lck, 0);
}
diff --git a/sys/fs/nwfs/nwfs.h b/sys/fs/nwfs/nwfs.h
index d7b2f62..af71724 100644
--- a/sys/fs/nwfs/nwfs.h
+++ b/sys/fs/nwfs/nwfs.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c
index 2f9ac01..75b1c18 100644
--- a/sys/fs/nwfs/nwfs_io.c
+++ b/sys/fs/nwfs/nwfs_io.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_ioctl.c b/sys/fs/nwfs/nwfs_ioctl.c
index 0fd5531..35fe93e 100644
--- a/sys/fs/nwfs/nwfs_ioctl.c
+++ b/sys/fs/nwfs/nwfs_ioctl.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_mount.h b/sys/fs/nwfs/nwfs_mount.h
index a6f9568..a1670942 100644
--- a/sys/fs/nwfs/nwfs_mount.h
+++ b/sys/fs/nwfs/nwfs_mount.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_node.c b/sys/fs/nwfs/nwfs_node.c
index 1e044c66..fc9b41b 100644
--- a/sys/fs/nwfs/nwfs_node.c
+++ b/sys/fs/nwfs/nwfs_node.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_node.h b/sys/fs/nwfs/nwfs_node.h
index f2e0ada..89545eb 100644
--- a/sys/fs/nwfs/nwfs_node.h
+++ b/sys/fs/nwfs/nwfs_node.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_subr.c b/sys/fs/nwfs/nwfs_subr.c
index 732651f..cb85450 100644
--- a/sys/fs/nwfs/nwfs_subr.c
+++ b/sys/fs/nwfs/nwfs_subr.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_subr.h b/sys/fs/nwfs/nwfs_subr.h
index 683a943..e571349 100644
--- a/sys/fs/nwfs/nwfs_subr.h
+++ b/sys/fs/nwfs/nwfs_subr.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c
index eed51c6..497414e 100644
--- a/sys/fs/nwfs/nwfs_vfsops.c
+++ b/sys/fs/nwfs/nwfs_vfsops.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/nwfs/nwfs_vnops.c b/sys/fs/nwfs/nwfs_vnops.c
index e63df80..e4f42b1 100644
--- a/sys/fs/nwfs/nwfs_vnops.c
+++ b/sys/fs/nwfs/nwfs_vnops.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/procfs/procfs_dbregs.c b/sys/fs/procfs/procfs_dbregs.c
index efa4e14..68945ef 100644
--- a/sys/fs/procfs/procfs_dbregs.c
+++ b/sys/fs/procfs/procfs_dbregs.c
@@ -59,10 +59,9 @@
#include <fs/pseudofs/pseudofs.h>
#include <fs/procfs/procfs.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/procfs.h>
#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
/*
* PROC(write, dbregs, td2, &r) becomes
@@ -90,7 +89,7 @@ procfs_doprocdbregs(PFS_FILL_ARGS)
int error;
struct dbreg r;
struct thread *td2;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct dbreg32 r32;
int wrap32 = 0;
#endif
@@ -106,7 +105,7 @@ procfs_doprocdbregs(PFS_FILL_ARGS)
}
td2 = FIRST_THREAD_IN_PROC(p);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
if ((td2->td_proc->p_sysent->sv_flags & SV_ILP32) == 0) {
PROC_UNLOCK(p);
diff --git a/sys/fs/procfs/procfs_fpregs.c b/sys/fs/procfs/procfs_fpregs.c
index 43af53e..c35b066 100644
--- a/sys/fs/procfs/procfs_fpregs.c
+++ b/sys/fs/procfs/procfs_fpregs.c
@@ -53,10 +53,9 @@
#include <fs/pseudofs/pseudofs.h>
#include <fs/procfs/procfs.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/procfs.h>
#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
/*
* PROC(write, fpregs, td2, &r) becomes
@@ -84,7 +83,7 @@ procfs_doprocfpregs(PFS_FILL_ARGS)
int error;
struct fpreg r;
struct thread *td2;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct fpreg32 r32;
int wrap32 = 0;
#endif
@@ -101,7 +100,7 @@ procfs_doprocfpregs(PFS_FILL_ARGS)
/* XXXKSE: */
td2 = FIRST_THREAD_IN_PROC(p);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
if ((td2->td_proc->p_sysent->sv_flags & SV_ILP32) == 0) {
PROC_UNLOCK(p);
diff --git a/sys/fs/procfs/procfs_ioctl.c b/sys/fs/procfs/procfs_ioctl.c
index ccff555..4b45af6 100644
--- a/sys/fs/procfs/procfs_ioctl.c
+++ b/sys/fs/procfs/procfs_ioctl.c
@@ -42,7 +42,7 @@
#include <fs/pseudofs/pseudofs.h>
#include <fs/procfs/procfs.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct procfs_status32 {
int state; /* Running, stopped, something else? */
int flags; /* Any flags */
@@ -62,7 +62,7 @@ int
procfs_ioctl(PFS_IOCTL_ARGS)
{
struct procfs_status *ps;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct procfs_status32 *ps32;
#endif
int error, flags, sig;
@@ -142,7 +142,7 @@ procfs_ioctl(PFS_IOCTL_ARGS)
ps->why = p->p_step ? p->p_stype : 0;
ps->val = p->p_step ? p->p_xstat : 0;
break;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
case PIOCWAIT32:
while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) {
/* sleep until p stops */
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index 878e2d5..2622d1e 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -47,7 +47,7 @@
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sbuf.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/sysent.h>
#endif
#include <sys/uio.h>
@@ -86,7 +86,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
struct uidinfo *uip;
int error, vfslocked;
unsigned int last_timestamp;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
int wrap32 = 0;
#endif
@@ -99,7 +99,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
if (uio->uio_rw != UIO_READ)
return (EOPNOTSUPP);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (curproc->p_sysent->sv_flags & SV_ILP32) {
if (!(p->p_sysent->sv_flags & SV_ILP32))
return (EOPNOTSUPP);
@@ -209,7 +209,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
"0x%lx 0x%lx %d %d %p %s%s%s %d %d 0x%x %s %s %s %s %s %d\n",
(u_long)e_start, (u_long)e_end,
resident, privateresident,
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
wrap32 ? NULL : obj, /* Hide 64 bit value */
#else
obj,
diff --git a/sys/fs/procfs/procfs_regs.c b/sys/fs/procfs/procfs_regs.c
index 82922fb..5bf1c0a 100644
--- a/sys/fs/procfs/procfs_regs.c
+++ b/sys/fs/procfs/procfs_regs.c
@@ -53,10 +53,9 @@
#include <fs/pseudofs/pseudofs.h>
#include <fs/procfs/procfs.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/procfs.h>
#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
/*
* PROC(write, regs, td2, &r) becomes
@@ -84,7 +83,7 @@ procfs_doprocregs(PFS_FILL_ARGS)
int error;
struct reg r;
struct thread *td2;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct reg32 r32;
int wrap32 = 0;
#endif
@@ -101,7 +100,7 @@ procfs_doprocregs(PFS_FILL_ARGS)
/* XXXKSE: */
td2 = FIRST_THREAD_IN_PROC(p);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
if ((td2->td_proc->p_sysent->sv_flags & SV_ILP32) == 0) {
PROC_UNLOCK(p);
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index 5854378..f8343a9 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -542,7 +542,7 @@ pfs_lookup(struct vop_cachedlookup_args *va)
if (cnp->cn_flags & ISDOTDOT)
vn_lock(vn, LK_EXCLUSIVE|LK_RETRY);
- if (cnp->cn_flags & MAKEENTRY)
+ if (cnp->cn_flags & MAKEENTRY && !(vn->v_iflag & VI_DOOMED))
cache_enter(vn, *vpp, cnp);
PFS_RETURN (0);
failed:
diff --git a/sys/fs/smbfs/smbfs.h b/sys/fs/smbfs/smbfs.h
index bdecd99..4be0a55 100644
--- a/sys/fs/smbfs/smbfs.h
+++ b/sys/fs/smbfs/smbfs.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c
index 8ff8266..df779a6 100644
--- a/sys/fs/smbfs/smbfs_io.c
+++ b/sys/fs/smbfs/smbfs_io.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c
index 38464cd..a0543e2 100644
--- a/sys/fs/smbfs/smbfs_node.c
+++ b/sys/fs/smbfs/smbfs_node.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_node.h b/sys/fs/smbfs/smbfs_node.h
index f9c08cf..ed1c17d 100644
--- a/sys/fs/smbfs/smbfs_node.h
+++ b/sys/fs/smbfs/smbfs_node.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_smb.c b/sys/fs/smbfs/smbfs_smb.c
index 3a89a9c..f58f7de 100644
--- a/sys/fs/smbfs/smbfs_smb.c
+++ b/sys/fs/smbfs/smbfs_smb.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_subr.c b/sys/fs/smbfs/smbfs_subr.c
index 68ed0b1..b775dff 100644
--- a/sys/fs/smbfs/smbfs_subr.c
+++ b/sys/fs/smbfs/smbfs_subr.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_subr.h b/sys/fs/smbfs/smbfs_subr.h
index a72b9e6..1511290 100644
--- a/sys/fs/smbfs/smbfs_subr.h
+++ b/sys/fs/smbfs/smbfs_subr.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c
index 2a328b3..16352d7 100644
--- a/sys/fs/smbfs/smbfs_vfsops.c
+++ b/sys/fs/smbfs/smbfs_vfsops.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index 0fd0233..830c249 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c
index 2a405c5b..a3746c0 100644
--- a/sys/geom/eli/g_eli.c
+++ b/sys/geom/eli/g_eli.c
@@ -340,7 +340,7 @@ g_eli_worker(void *arg)
}
#endif
thread_lock(curthread);
- sched_prio(curthread, PRIBIO);
+ sched_prio(curthread, PUSER);
if (sc->sc_crypto == G_ELI_CRYPTO_SW && g_eli_threads == 0)
sched_bind(curthread, wr->w_number);
thread_unlock(curthread);
@@ -361,8 +361,7 @@ g_eli_worker(void *arg)
mtx_unlock(&sc->sc_queue_mtx);
kproc_exit(0);
}
- msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
- "geli:w", 0);
+ msleep(sc, &sc->sc_queue_mtx, PDROP, "geli:w", 0);
continue;
}
mtx_unlock(&sc->sc_queue_mtx);
diff --git a/sys/geom/gate/g_gate.c b/sys/geom/gate/g_gate.c
index 952e856..dd69a87 100644
--- a/sys/geom/gate/g_gate.c
+++ b/sys/geom/gate/g_gate.c
@@ -109,27 +109,17 @@ g_gate_destroy(struct g_gate_softc *sc, boolean_t force)
g_orphan_provider(pp, ENXIO);
callout_drain(&sc->sc_callout);
mtx_lock(&sc->sc_queue_mtx);
- for (;;) {
- bp = bioq_first(&sc->sc_inqueue);
- if (bp != NULL) {
- bioq_remove(&sc->sc_inqueue, bp);
- sc->sc_queue_count--;
- G_GATE_LOGREQ(1, bp, "Request canceled.");
- g_io_deliver(bp, ENXIO);
- } else {
- break;
- }
+ while ((bp = bioq_first(&sc->sc_inqueue)) != NULL) {
+ bioq_remove(&sc->sc_inqueue, bp);
+ sc->sc_queue_count--;
+ G_GATE_LOGREQ(1, bp, "Request canceled.");
+ g_io_deliver(bp, ENXIO);
}
- for (;;) {
- bp = bioq_first(&sc->sc_outqueue);
- if (bp != NULL) {
- bioq_remove(&sc->sc_outqueue, bp);
- sc->sc_queue_count--;
- G_GATE_LOGREQ(1, bp, "Request canceled.");
- g_io_deliver(bp, ENXIO);
- } else {
- break;
- }
+ while ((bp = bioq_first(&sc->sc_outqueue)) != NULL) {
+ bioq_remove(&sc->sc_outqueue, bp);
+ sc->sc_queue_count--;
+ G_GATE_LOGREQ(1, bp, "Request canceled.");
+ g_io_deliver(bp, ENXIO);
}
mtx_unlock(&sc->sc_queue_mtx);
g_topology_unlock();
diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c
index c804bab..d1e56d6 100644
--- a/sys/geom/geom_dump.c
+++ b/sys/geom/geom_dump.c
@@ -154,6 +154,28 @@ g_conftxt(void *p, int flag)
static void
+g_conf_print_escaped(struct sbuf *sb, const char *fmt, const char *str)
+{
+ struct sbuf *s;
+ const u_char *c;
+
+ s = sbuf_new_auto();
+
+ for (c = str; *c != '\0'; c++) {
+ if (*c == '&' || *c == '<' || *c == '>' ||
+ *c == '\'' || *c == '"' || *c > 0x7e)
+ sbuf_printf(s, "&#x%X;", *c);
+ else if (*c == '\t' || *c == '\n' || *c == '\r' || *c > 0x1f)
+ sbuf_putc(s, *c);
+ else
+ sbuf_putc(s, '?');
+ }
+ sbuf_finish(s);
+ sbuf_printf(sb, fmt, sbuf_data(s));
+ sbuf_delete(s);
+}
+
+static void
g_conf_consumer(struct sbuf *sb, struct g_consumer *cp)
{
@@ -181,7 +203,7 @@ g_conf_provider(struct sbuf *sb, struct g_provider *pp)
sbuf_printf(sb, "\t <geom ref=\"%p\"/>\n", pp->geom);
sbuf_printf(sb, "\t <mode>r%dw%de%d</mode>\n",
pp->acr, pp->acw, pp->ace);
- sbuf_printf(sb, "\t <name>%s</name>\n", pp->name);
+ g_conf_print_escaped(sb, "\t <name>%s</name>\n", pp->name);
sbuf_printf(sb, "\t <mediasize>%jd</mediasize>\n",
(intmax_t)pp->mediasize);
sbuf_printf(sb, "\t <sectorsize>%u</sectorsize>\n", pp->sectorsize);
@@ -208,7 +230,7 @@ g_conf_geom(struct sbuf *sb, struct g_geom *gp, struct g_provider *pp, struct g_
sbuf_printf(sb, " <geom id=\"%p\">\n", gp);
sbuf_printf(sb, " <class ref=\"%p\"/>\n", gp->class);
- sbuf_printf(sb, " <name>%s</name>\n", gp->name);
+ g_conf_print_escaped(sb, " <name>%s</name>\n", gp->name);
sbuf_printf(sb, " <rank>%d</rank>\n", gp->rank);
if (gp->flags & G_GEOM_WITHER)
sbuf_printf(sb, " <wither/>\n");
@@ -237,7 +259,7 @@ g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_pr
struct g_geom *gp2;
sbuf_printf(sb, " <class id=\"%p\">\n", mp);
- sbuf_printf(sb, " <name>%s</name>\n", mp->name);
+ g_conf_print_escaped(sb, " <name>%s</name>\n", mp->name);
LIST_FOREACH(gp2, &mp->geom, geom) {
if (gp != NULL && gp != gp2)
continue;
diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c
index 0b6525e..1090c0b 100644
--- a/sys/geom/geom_io.c
+++ b/sys/geom/geom_io.c
@@ -309,8 +309,8 @@ g_io_check(struct bio *bp)
case BIO_READ:
case BIO_WRITE:
case BIO_DELETE:
- /* Zero sectorsize is a probably lack of media */
- if (pp->sectorsize == 0)
+ /* Zero sectorsize or mediasize is probably a lack of media. */
+ if (pp->sectorsize == 0 || pp->mediasize == 0)
return (ENXIO);
/* Reject I/O not on sector boundary */
if (bp->bio_offset % pp->sectorsize)
@@ -443,7 +443,10 @@ g_io_request(struct bio *bp, struct g_consumer *cp)
("Bio already on queue bp=%p", bp));
bp->bio_flags |= BIO_ONQUEUE;
- binuptime(&bp->bio_t0);
+ if (g_collectstats)
+ binuptime(&bp->bio_t0);
+ else
+ getbinuptime(&bp->bio_t0);
/*
* The statistics collection is lockless, as such, but we
diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
index 9bef0e3..772277e 100644
--- a/sys/geom/geom_subr.c
+++ b/sys/geom/geom_subr.c
@@ -59,6 +59,10 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#endif
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
+
struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
@@ -1011,12 +1015,11 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len)
#if defined(DIAGNOSTIC) || defined(DDB)
/*
- * This function walks (topologically unsafely) the mesh and return a
- * non-zero integer if it finds the argument pointer is an object.
- * The return value indicates which type of object it is belived to be.
- * If topology is not locked, this function is potentially dangerous,
- * but since it is for debugging purposes and can be useful for instance
- * from DDB, we do not assert topology lock is held.
+ * This function walks the mesh and returns a non-zero integer if it
+ * finds the argument pointer is an object. The return value indicates
+ * which type of object it is believed to be. If topology is not locked,
+ * this function is potentially dangerous, but we don't assert that the
+ * topology lock is held when called from debugger.
*/
int
g_valid_obj(void const *ptr)
@@ -1026,7 +1029,10 @@ g_valid_obj(void const *ptr)
struct g_consumer *cp;
struct g_provider *pp;
- g_topology_assert();
+#ifdef KDB
+ if (kdb_active == 0)
+#endif
+ g_topology_assert();
LIST_FOREACH(mp, &g_classes, class) {
if (ptr == mp)
diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c
index 9d01f40..e50e17b 100644
--- a/sys/geom/geom_vfs.c
+++ b/sys/geom/geom_vfs.c
@@ -161,6 +161,10 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr
g_topology_assert();
*cpp = NULL;
+ bo = &vp->v_bufobj;
+ if (bo->bo_private != vp)
+ return (EBUSY);
+
pp = g_dev_getprovider(vp->v_rdev);
if (pp == NULL)
return (ENOENT);
@@ -176,7 +180,7 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr
vnode_create_vobject(vp, pp->mediasize, curthread);
VFS_UNLOCK_GIANT(vfslocked);
*cpp = cp;
- bo = &vp->v_bufobj;
+ cp->private = vp;
bo->bo_ops = g_vfs_bufops;
bo->bo_private = cp;
bo->bo_bsize = pp->sectorsize;
@@ -196,5 +200,6 @@ g_vfs_close(struct g_consumer *cp)
gp = cp->geom;
bo = gp->softc;
bufobj_invalbuf(bo, V_SAVE, 0, 0);
+ bo->bo_private = cp->private;
g_wither_geom_close(gp, ENXIO);
}
diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c
index a2e61586..7e145dc 100644
--- a/sys/geom/multipath/g_multipath.c
+++ b/sys/geom/multipath/g_multipath.c
@@ -70,6 +70,9 @@ static int g_multipath_destroy(struct g_geom *);
static int
g_multipath_destroy_geom(struct gctl_req *, struct g_class *, struct g_geom *);
+static struct g_geom *g_multipath_find_geom(struct g_class *, const char *);
+static int g_multipath_rotate(struct g_geom *);
+
static g_taste_t g_multipath_taste;
static g_ctl_req_t g_multipath_config;
static g_init_t g_multipath_init;
@@ -406,6 +409,30 @@ g_multipath_destroy_geom(struct gctl_req *req, struct g_class *mp,
return (g_multipath_destroy(gp));
}
+static int
+g_multipath_rotate(struct g_geom *gp)
+{
+ struct g_consumer *lcp;
+ struct g_multipath_softc *sc = gp->softc;
+
+ g_topology_assert();
+ if (sc == NULL)
+ return (ENXIO);
+ LIST_FOREACH(lcp, &gp->consumer, consumer) {
+ if ((lcp->index & MP_BAD) == 0) {
+ if (sc->cp_active != lcp) {
+ break;
+ }
+ }
+ }
+ if (lcp) {
+ sc->cp_active = lcp;
+ printf("GEOM_MULTIPATH: %s now active path in %s\n",
+ lcp->provider->name, sc->sc_name);
+ }
+ return (0);
+}
+
static void
g_multipath_init(struct g_class *mp)
{
@@ -576,14 +603,13 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
}
static void
-g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
+g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp)
{
struct g_geom *gp;
- struct g_provider *pp0, *pp1;
- struct g_multipath_metadata md;
- const char *name, *mpname, *uuid;
+ struct g_consumer *cp;
+ struct g_provider *pp, *pp0;
+ const char *name, *mpname;
static const char devpf[6] = "/dev/";
- int *nargs, error;
g_topology_assert();
@@ -592,14 +618,9 @@ g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "No 'arg0' argument");
return;
}
-
- nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
- if (nargs == NULL) {
- gctl_error(req, "No 'nargs' argument");
- return;
- }
- if (*nargs != 4) {
- gctl_error(req, "missing device or uuid arguments");
+ gp = g_multipath_find_geom(mp, mpname);
+ if (gp == NULL) {
+ gctl_error(req, "Device %s is invalid", mpname);
return;
}
@@ -610,78 +631,45 @@ g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
}
if (strncmp(name, devpf, 5) == 0)
name += 5;
- pp0 = g_provider_by_name(name);
- if (pp0 == NULL) {
- gctl_error(req, "Provider %s is invalid", name);
- return;
- }
-
- name = gctl_get_asciiparam(req, "arg2");
- if (name == NULL) {
- gctl_error(req, "No 'arg2' argument");
- return;
- }
- if (strncmp(name, devpf, 5) == 0)
- name += 5;
- pp1 = g_provider_by_name(name);
- if (pp1 == NULL) {
+ pp = g_provider_by_name(name);
+ if (pp == NULL) {
gctl_error(req, "Provider %s is invalid", name);
return;
}
- uuid = gctl_get_asciiparam(req, "arg3");
- if (uuid == NULL) {
- gctl_error(req, "No uuid argument");
- return;
- }
- if (strlen(uuid) != 36) {
- gctl_error(req, "Malformed uuid argument");
- return;
- }
-
/*
- * Check to make sure parameters from the two providers are the same
+ * Check to make sure parameters match, if we already have one.
*/
- if (pp0 == pp1) {
- gctl_error(req, "providers %s and %s are the same",
- pp0->name, pp1->name);
- return;
- }
- if (pp0->mediasize != pp1->mediasize) {
- gctl_error(req, "Provider %s is %jd; Provider %s is %jd",
- pp0->name, (intmax_t) pp0->mediasize,
- pp1->name, (intmax_t) pp1->mediasize);
- return;
+ cp = LIST_FIRST(&gp->consumer);
+ if (cp) {
+ pp0 = cp->provider;
+ } else {
+ pp0 = NULL;
}
- if (pp0->sectorsize != pp1->sectorsize) {
- gctl_error(req, "Provider %s has sectorsize %u; Provider %s "
- "has sectorsize %u", pp0->name, pp0->sectorsize,
- pp1->name, pp1->sectorsize);
- return;
+ if (pp0) {
+ if (pp0 == pp) {
+ gctl_error(req, "providers %s and %s are the same",
+ pp0->name, pp->name);
+ return;
+ }
+ if (pp0->mediasize != pp->mediasize) {
+ gctl_error(req, "Provider %s is %jd; Provider %s is %jd",
+ pp0->name, (intmax_t) pp0->mediasize,
+ pp->name, (intmax_t) pp->mediasize);
+ return;
+ }
+ if (pp0->sectorsize != pp->sectorsize) {
+ gctl_error(req, "Provider %s has sectorsize %u; Provider %s "
+ "has sectorsize %u", pp0->name, pp0->sectorsize,
+ pp->name, pp->sectorsize);
+ return;
+ }
}
/*
- * cons up enough of a metadata structure to use.
+ * Now add....
*/
- memset(&md, 0, sizeof(md));
- md.md_size = pp0->mediasize;
- md.md_sectorsize = pp0->sectorsize;
- strlcpy(md.md_name, mpname, sizeof(md.md_name));
- strlcpy(md.md_uuid, uuid, sizeof(md.md_uuid));
-
- gp = g_multipath_create(mp, &md);
- if (gp == NULL)
- return;
- error = g_multipath_add_disk(gp, pp0);
- if (error) {
- g_multipath_destroy(gp);
- return;
- }
- error = g_multipath_add_disk(gp, pp1);
- if (error) {
- g_multipath_destroy(gp);
- return;
- }
+ (void) g_multipath_add_disk(gp, pp);
}
static struct g_geom *
@@ -723,6 +711,63 @@ g_multipath_ctl_destroy(struct gctl_req *req, struct g_class *mp)
}
static void
+g_multipath_ctl_rotate(struct gctl_req *req, struct g_class *mp)
+{
+ struct g_geom *gp;
+ const char *name;
+ int error;
+
+ g_topology_assert();
+
+ name = gctl_get_asciiparam(req, "arg0");
+ if (name == NULL) {
+ gctl_error(req, "No 'arg0' argument");
+ return;
+ }
+ gp = g_multipath_find_geom(mp, name);
+ if (gp == NULL) {
+ gctl_error(req, "Device %s is invalid", name);
+ return;
+ }
+ error = g_multipath_rotate(gp);
+ if (error != 0) {
+ gctl_error(req, "failed to rotate %s (err=%d)", name, error);
+ }
+}
+
+static void
+g_multipath_ctl_getactive(struct gctl_req *req, struct g_class *mp)
+{
+ struct sbuf *sb;
+ struct g_geom *gp;
+ struct g_multipath_softc *sc;
+ const char *name;
+
+ sb = sbuf_new_auto();
+
+ g_topology_assert();
+ name = gctl_get_asciiparam(req, "arg0");
+ if (name == NULL) {
+ gctl_error(req, "No 'arg0' argument");
+ return;
+ }
+ gp = g_multipath_find_geom(mp, name);
+ if (gp == NULL) {
+ gctl_error(req, "Device %s is invalid", name);
+ return;
+ }
+ sc = gp->softc;
+ if (sc->cp_active) {
+ sbuf_printf(sb, "%s\n", sc->cp_active->provider->name);
+ } else {
+ sbuf_printf(sb, "none\n");
+ }
+ sbuf_finish(sb);
+ gctl_set_param_err(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
+ sbuf_delete(sb);
+}
+
+static void
g_multipath_config(struct gctl_req *req, struct g_class *mp, const char *verb)
{
uint32_t *version;
@@ -732,10 +777,14 @@ g_multipath_config(struct gctl_req *req, struct g_class *mp, const char *verb)
gctl_error(req, "No 'version' argument");
} else if (*version != G_MULTIPATH_VERSION) {
gctl_error(req, "Userland and kernel parts are out of sync");
- } else if (strcmp(verb, "create") == 0) {
- g_multipath_ctl_create(req, mp);
+ } else if (strcmp(verb, "add") == 0) {
+ g_multipath_ctl_add(req, mp);
} else if (strcmp(verb, "destroy") == 0) {
g_multipath_ctl_destroy(req, mp);
+ } else if (strcmp(verb, "rotate") == 0) {
+ g_multipath_ctl_rotate(req, mp);
+ } else if (strcmp(verb, "getactive") == 0) {
+ g_multipath_ctl_getactive(req, mp);
} else {
gctl_error(req, "Unknown verb %s", verb);
}
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 0434ace..f47ac08 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -855,7 +855,9 @@ g_part_ctl_delete(struct gctl_req *req, struct g_part_parms *gpp)
static int
g_part_ctl_destroy(struct gctl_req *req, struct g_part_parms *gpp)
{
+ struct g_consumer *cp;
struct g_geom *gp;
+ struct g_provider *pp;
struct g_part_entry *entry;
struct g_part_table *null, *table;
struct sbuf *sb;
@@ -885,6 +887,11 @@ g_part_ctl_destroy(struct gctl_req *req, struct g_part_parms *gpp)
null->gpt_gp = gp;
null->gpt_scheme = &g_part_null_scheme;
LIST_INIT(&null->gpt_entry);
+
+ cp = LIST_FIRST(&gp->consumer);
+ pp = cp->provider;
+ null->gpt_last = pp->mediasize / pp->sectorsize - 1;
+
null->gpt_depth = table->gpt_depth;
null->gpt_opened = table->gpt_opened;
null->gpt_smhead = table->gpt_smhead;
@@ -971,9 +978,85 @@ g_part_ctl_recover(struct gctl_req *req, struct g_part_parms *gpp)
static int
g_part_ctl_resize(struct gctl_req *req, struct g_part_parms *gpp)
{
- gctl_error(req, "%d verb 'resize'", ENOSYS);
- return (ENOSYS);
-}
+ struct g_geom *gp;
+ struct g_provider *pp;
+ struct g_part_entry *pe, *entry;
+ struct g_part_table *table;
+ struct sbuf *sb;
+ quad_t end;
+ int error;
+
+ gp = gpp->gpp_geom;
+ G_PART_TRACE((G_T_TOPOLOGY, "%s(%s)", __func__, gp->name));
+ g_topology_assert();
+ table = gp->softc;
+
+ /* check gpp_index */
+ LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
+ if (entry->gpe_deleted || entry->gpe_internal)
+ continue;
+ if (entry->gpe_index == gpp->gpp_index)
+ break;
+ }
+ if (entry == NULL) {
+ gctl_error(req, "%d index '%d'", ENOENT, gpp->gpp_index);
+ return (ENOENT);
+ }
+
+ /* check gpp_size */
+ end = entry->gpe_start + gpp->gpp_size - 1;
+ if (gpp->gpp_size < 1 || end > table->gpt_last) {
+ gctl_error(req, "%d size '%jd'", EINVAL,
+ (intmax_t)gpp->gpp_size);
+ return (EINVAL);
+ }
+
+ LIST_FOREACH(pe, &table->gpt_entry, gpe_entry) {
+ if (pe->gpe_deleted || pe->gpe_internal || pe == entry)
+ continue;
+ if (end >= pe->gpe_start && end <= pe->gpe_end) {
+ gctl_error(req, "%d end '%jd'", ENOSPC,
+ (intmax_t)end);
+ return (ENOSPC);
+ }
+ if (entry->gpe_start < pe->gpe_start && end > pe->gpe_end) {
+ gctl_error(req, "%d size '%jd'", ENOSPC,
+ (intmax_t)gpp->gpp_size);
+ return (ENOSPC);
+ }
+ }
+
+ pp = entry->gpe_pp;
+ if ((g_debugflags & 16) == 0 &&
+ (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)) {
+ gctl_error(req, "%d", EBUSY);
+ return (EBUSY);
+ }
+
+ error = G_PART_RESIZE(table, entry, gpp);
+ if (error) {
+ gctl_error(req, "%d", error);
+ return (error);
+ }
+
+ if (!entry->gpe_created)
+ entry->gpe_modified = 1;
+
+ /* update mediasize of changed provider */
+ pp->mediasize = (entry->gpe_end - entry->gpe_start + 1) *
+ pp->sectorsize;
+
+ /* Provide feedback if so requested. */
+ if (gpp->gpp_parms & G_PART_PARM_OUTPUT) {
+ sb = sbuf_new_auto();
+ G_PART_FULLNAME(table, entry, sb, gp->name);
+ sbuf_cat(sb, " resized\n");
+ sbuf_finish(sb);
+ gctl_set_param(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
+ sbuf_delete(sb);
+ }
+ return (0);
+}
static int
g_part_ctl_setunset(struct gctl_req *req, struct g_part_parms *gpp,
@@ -1065,10 +1148,16 @@ g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp)
table->gpt_created) ? 1 : 0;
if (reprobe) {
- if (!LIST_EMPTY(&table->gpt_entry)) {
+ LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
+ if (entry->gpe_internal)
+ continue;
error = EBUSY;
goto fail;
}
+ while ((entry = LIST_FIRST(&table->gpt_entry)) != NULL) {
+ LIST_REMOVE(entry, gpe_entry);
+ g_free(entry);
+ }
error = g_part_probe(gp, cp, table->gpt_depth);
if (error) {
g_topology_lock();
@@ -1077,6 +1166,15 @@ g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp)
return (0);
}
table = gp->softc;
+
+ /*
+ * Synthesize a disk geometry. Some partitioning schemes
+ * depend on it and since some file systems need it even
+ * when the partitition scheme doesn't, we do it here in
+ * scheme-independent code.
+ */
+ pp = cp->provider;
+ g_part_geometry(table, cp, pp->mediasize / pp->sectorsize);
}
error = G_PART_READ(table, cp);
@@ -1194,7 +1292,8 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
mparms |= G_PART_PARM_GEOM;
} else if (!strcmp(verb, "resize")) {
ctlreq = G_PART_CTL_RESIZE;
- mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
+ mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX |
+ G_PART_PARM_SIZE;
}
break;
case 's':
diff --git a/sys/geom/part/g_part_apm.c b/sys/geom/part/g_part_apm.c
index 030a0e6..c80925a 100644
--- a/sys/geom/part/g_part_apm.c
+++ b/sys/geom/part/g_part_apm.c
@@ -74,6 +74,8 @@ static int g_part_apm_read(struct g_part_table *, struct g_consumer *);
static const char *g_part_apm_type(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_apm_write(struct g_part_table *, struct g_consumer *);
+static int g_part_apm_resize(struct g_part_table *, struct g_part_entry *,
+ struct g_part_parms *);
static kobj_method_t g_part_apm_methods[] = {
KOBJMETHOD(g_part_add, g_part_apm_add),
@@ -82,6 +84,7 @@ static kobj_method_t g_part_apm_methods[] = {
KOBJMETHOD(g_part_dumpconf, g_part_apm_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_apm_dumpto),
KOBJMETHOD(g_part_modify, g_part_apm_modify),
+ KOBJMETHOD(g_part_resize, g_part_apm_resize),
KOBJMETHOD(g_part_name, g_part_apm_name),
KOBJMETHOD(g_part_probe, g_part_apm_probe),
KOBJMETHOD(g_part_read, g_part_apm_read),
@@ -318,6 +321,19 @@ g_part_apm_modify(struct g_part_table *basetable,
return (0);
}
+static int
+g_part_apm_resize(struct g_part_table *basetable,
+ struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+ struct g_part_apm_entry *entry;
+
+ entry = (struct g_part_apm_entry *)baseentry;
+ baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
+ entry->ent.ent_size = gpp->gpp_size;
+
+ return (0);
+}
+
static const char *
g_part_apm_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
diff --git a/sys/geom/part/g_part_bsd.c b/sys/geom/part/g_part_bsd.c
index 18a74aa..e99f0bb 100644
--- a/sys/geom/part/g_part_bsd.c
+++ b/sys/geom/part/g_part_bsd.c
@@ -73,6 +73,8 @@ static int g_part_bsd_read(struct g_part_table *, struct g_consumer *);
static const char *g_part_bsd_type(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_bsd_write(struct g_part_table *, struct g_consumer *);
+static int g_part_bsd_resize(struct g_part_table *, struct g_part_entry *,
+ struct g_part_parms *);
static kobj_method_t g_part_bsd_methods[] = {
KOBJMETHOD(g_part_add, g_part_bsd_add),
@@ -82,6 +84,7 @@ static kobj_method_t g_part_bsd_methods[] = {
KOBJMETHOD(g_part_dumpconf, g_part_bsd_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_bsd_dumpto),
KOBJMETHOD(g_part_modify, g_part_bsd_modify),
+ KOBJMETHOD(g_part_resize, g_part_bsd_resize),
KOBJMETHOD(g_part_name, g_part_bsd_name),
KOBJMETHOD(g_part_probe, g_part_bsd_probe),
KOBJMETHOD(g_part_read, g_part_bsd_read),
@@ -288,6 +291,19 @@ g_part_bsd_modify(struct g_part_table *basetable,
return (0);
}
+static int
+g_part_bsd_resize(struct g_part_table *basetable,
+ struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+ struct g_part_bsd_entry *entry;
+
+ entry = (struct g_part_bsd_entry *)baseentry;
+ baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
+ entry->part.p_size = gpp->gpp_size;
+
+ return (0);
+}
+
static const char *
g_part_bsd_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index b0c9598..a6f7490 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -103,6 +103,8 @@ static int g_part_gpt_read(struct g_part_table *, struct g_consumer *);
static const char *g_part_gpt_type(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_gpt_write(struct g_part_table *, struct g_consumer *);
+static int g_part_gpt_resize(struct g_part_table *, struct g_part_entry *,
+ struct g_part_parms *);
static kobj_method_t g_part_gpt_methods[] = {
KOBJMETHOD(g_part_add, g_part_gpt_add),
@@ -112,6 +114,7 @@ static kobj_method_t g_part_gpt_methods[] = {
KOBJMETHOD(g_part_dumpconf, g_part_gpt_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_gpt_dumpto),
KOBJMETHOD(g_part_modify, g_part_gpt_modify),
+ KOBJMETHOD(g_part_resize, g_part_gpt_resize),
KOBJMETHOD(g_part_name, g_part_gpt_name),
KOBJMETHOD(g_part_probe, g_part_gpt_probe),
KOBJMETHOD(g_part_read, g_part_gpt_read),
@@ -550,6 +553,19 @@ g_part_gpt_modify(struct g_part_table *basetable,
return (0);
}
+static int
+g_part_gpt_resize(struct g_part_table *basetable,
+ struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+ struct g_part_gpt_entry *entry;
+ entry = (struct g_part_gpt_entry *)baseentry;
+
+ baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
+ entry->ent.ent_lba_end = baseentry->gpe_end;
+
+ return (0);
+}
+
static const char *
g_part_gpt_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
diff --git a/sys/geom/part/g_part_if.m b/sys/geom/part/g_part_if.m
index 8252f0c..04440fe 100644
--- a/sys/geom/part/g_part_if.m
+++ b/sys/geom/part/g_part_if.m
@@ -58,6 +58,13 @@ CODE {
{
return (0);
}
+
+ static int
+ default_resize(struct g_part_table *t __unused,
+ struct g_part_entry *e __unused, struct g_part_parms *p __unused)
+ {
+ return (ENOSYS);
+ }
};
# add() - scheme specific processing for the add verb.
@@ -114,6 +121,13 @@ METHOD int modify {
struct g_part_parms *gpp;
};
+# resize() - scheme specific processing for the resize verb.
+METHOD int resize {
+ struct g_part_table *table;
+ struct g_part_entry *entry;
+ struct g_part_parms *gpp;
+} DEFAULT default_resize;
+
# name() - return the name of the given partition entry.
# Typical names are "p1", "s0" or "c".
METHOD const char * name {
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 72d0ecb..8b5ba27 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -76,6 +76,8 @@ static int g_part_mbr_setunset(struct g_part_table *, struct g_part_entry *,
static const char *g_part_mbr_type(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_mbr_write(struct g_part_table *, struct g_consumer *);
+static int g_part_mbr_resize(struct g_part_table *, struct g_part_entry *,
+ struct g_part_parms *);
static kobj_method_t g_part_mbr_methods[] = {
KOBJMETHOD(g_part_add, g_part_mbr_add),
@@ -85,6 +87,7 @@ static kobj_method_t g_part_mbr_methods[] = {
KOBJMETHOD(g_part_dumpconf, g_part_mbr_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_mbr_dumpto),
KOBJMETHOD(g_part_modify, g_part_mbr_modify),
+ KOBJMETHOD(g_part_resize, g_part_mbr_resize),
KOBJMETHOD(g_part_name, g_part_mbr_name),
KOBJMETHOD(g_part_probe, g_part_mbr_probe),
KOBJMETHOD(g_part_read, g_part_mbr_read),
@@ -302,6 +305,31 @@ g_part_mbr_modify(struct g_part_table *basetable,
return (0);
}
+static int
+g_part_mbr_resize(struct g_part_table *basetable,
+ struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+ struct g_part_mbr_entry *entry;
+ uint32_t size, sectors;
+
+ sectors = basetable->gpt_sectors;
+ size = gpp->gpp_size;
+
+ if (size < sectors)
+ return (EINVAL);
+ if (size % sectors)
+ size = size - (size % sectors);
+ if (size < sectors)
+ return (EINVAL);
+
+ entry = (struct g_part_mbr_entry *)baseentry;
+ baseentry->gpe_end = baseentry->gpe_start + size - 1;
+ entry->ent.dp_size = size;
+ mbr_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
+ &entry->ent.dp_ehd, &entry->ent.dp_esect);
+ return (0);
+}
+
static const char *
g_part_mbr_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c
index 8857f9b..ab83662 100644
--- a/sys/geom/part/g_part_pc98.c
+++ b/sys/geom/part/g_part_pc98.c
@@ -77,6 +77,8 @@ static int g_part_pc98_setunset(struct g_part_table *, struct g_part_entry *,
static const char *g_part_pc98_type(struct g_part_table *,
struct g_part_entry *, char *, size_t);
static int g_part_pc98_write(struct g_part_table *, struct g_consumer *);
+static int g_part_pc98_resize(struct g_part_table *, struct g_part_entry *,
+ struct g_part_parms *);
static kobj_method_t g_part_pc98_methods[] = {
KOBJMETHOD(g_part_add, g_part_pc98_add),
@@ -86,6 +88,7 @@ static kobj_method_t g_part_pc98_methods[] = {
KOBJMETHOD(g_part_dumpconf, g_part_pc98_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_pc98_dumpto),
KOBJMETHOD(g_part_modify, g_part_pc98_modify),
+ KOBJMETHOD(g_part_resize, g_part_pc98_resize),
KOBJMETHOD(g_part_name, g_part_pc98_name),
KOBJMETHOD(g_part_probe, g_part_pc98_probe),
KOBJMETHOD(g_part_read, g_part_pc98_read),
@@ -308,6 +311,31 @@ g_part_pc98_modify(struct g_part_table *basetable,
return (0);
}
+static int
+g_part_pc98_resize(struct g_part_table *basetable,
+ struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+ struct g_part_pc98_entry *entry;
+ uint32_t size, cyl;
+
+ cyl = basetable->gpt_heads * basetable->gpt_sectors;
+ size = gpp->gpp_size;
+
+ if (size < cyl)
+ return (EINVAL);
+ if (size % cyl)
+ size = size - (size % cyl);
+ if (size < cyl)
+ return (EINVAL);
+
+ entry = (struct g_part_pc98_entry *)baseentry;
+ baseentry->gpe_end = baseentry->gpe_start + size - 1;
+ pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
+ &entry->ent.dp_ehd, &entry->ent.dp_esect);
+
+ return (0);
+}
+
static const char *
g_part_pc98_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
diff --git a/sys/geom/part/g_part_vtoc8.c b/sys/geom/part/g_part_vtoc8.c
index 0108e97..2cabcfd 100644
--- a/sys/geom/part/g_part_vtoc8.c
+++ b/sys/geom/part/g_part_vtoc8.c
@@ -67,6 +67,8 @@ static int g_part_vtoc8_read(struct g_part_table *, struct g_consumer *);
static const char *g_part_vtoc8_type(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_vtoc8_write(struct g_part_table *, struct g_consumer *);
+static int g_part_vtoc8_resize(struct g_part_table *, struct g_part_entry *,
+ struct g_part_parms *);
static kobj_method_t g_part_vtoc8_methods[] = {
KOBJMETHOD(g_part_add, g_part_vtoc8_add),
@@ -75,6 +77,7 @@ static kobj_method_t g_part_vtoc8_methods[] = {
KOBJMETHOD(g_part_dumpconf, g_part_vtoc8_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_vtoc8_dumpto),
KOBJMETHOD(g_part_modify, g_part_vtoc8_modify),
+ KOBJMETHOD(g_part_resize, g_part_vtoc8_resize),
KOBJMETHOD(g_part_name, g_part_vtoc8_name),
KOBJMETHOD(g_part_probe, g_part_vtoc8_probe),
KOBJMETHOD(g_part_read, g_part_vtoc8_read),
@@ -294,6 +297,26 @@ g_part_vtoc8_modify(struct g_part_table *basetable,
return (0);
}
+static int
+g_part_vtoc8_resize(struct g_part_table *basetable,
+ struct g_part_entry *entry, struct g_part_parms *gpp)
+{
+ struct g_part_vtoc8_table *table;
+ uint64_t size;
+
+ table = (struct g_part_vtoc8_table *)basetable;
+ size = gpp->gpp_size;
+ if (size % table->secpercyl)
+ size = size - (size % table->secpercyl);
+ if (size < table->secpercyl)
+ return (EINVAL);
+
+ entry->gpe_end = entry->gpe_start + size - 1;
+ be32enc(&table->vtoc.map[entry->gpe_index - 1].nblks, size);
+
+ return (0);
+}
+
static const char *
g_part_vtoc8_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
diff --git a/sys/geom/sched/README b/sys/geom/sched/README
new file mode 100644
index 0000000..1b52d90
--- /dev/null
+++ b/sys/geom/sched/README
@@ -0,0 +1,162 @@
+
+ --- GEOM BASED DISK SCHEDULERS FOR FREEBSD ---
+
+This code contains a framework for GEOM-based disk schedulers and a
+couple of sample scheduling algorithms that use the framework and
+implement two forms of "anticipatory scheduling" (see below for more
+details).
+
+As a quick example of what this code can give you, try to run "dd",
+"tar", or some other program with highly SEQUENTIAL access patterns,
+together with "cvs", "cvsup", "svn" or other highly RANDOM access patterns
+(this is not a made-up example: it is pretty common for developers
+to have one or more apps doing random accesses, and others that do
+sequential accesses e.g., loading large binaries from disk, checking
+the integrity of tarballs, watching media streams and so on).
+
+These are the results we get on a local machine (AMD BE2400 dual
+core CPU, SATA 250GB disk):
+
+ /mnt is a partition mounted on /dev/ad0s1f
+
+ cvs: cvs -d /mnt/home/ncvs-local update -Pd /mnt/ports
+ dd-read: dd bs=128k of=/dev/null if=/dev/ad0 (or ad0-sched-)
+ dd-writew dd bs=128k if=/dev/zero of=/mnt/largefile
+
+ NO SCHEDULER RR SCHEDULER
+ dd cvs dd cvs
+
+ dd-read only 72 MB/s ---- 72 MB/s ---
+ dd-write only 55 MB/s --- 55 MB/s ---
+ dd-read+cvs 6 MB/s ok 30 MB/s ok
+ dd-write+cvs 55 MB/s slooow 14 MB/s ok
+
+As you can see, when a cvs is running concurrently with dd, the
+performance drops dramatically, and depending on read or write mode,
+one of the two is severely penalized. The use of the RR scheduler
+in this example makes the dd-reader go much faster when competing
+with cvs, and lets cvs progress when competing with a writer.
+
+To try it out:
+
+1. USERS OF FREEBSD 7, PLEASE READ CAREFULLY THE FOLLOWING:
+
+ On loading, this module patches one kernel function (g_io_request())
+ so that I/O requests ("bio's") carry a classification tag, useful
+ for scheduling purposes.
+
+ ON FREEBSD 7, the tag is stored in an existing (though rarely used)
+ field of the "struct bio", a solution which makes this module
+ incompatible with other modules using it, such as ZFS and gjournal.
+ Additionally, g_io_request() is patched in-memory to add a call
+ to the function that initializes this field (i386/amd64 only;
+ for other architectures you need to manually patch sys/geom/geom_io.c).
+ See details in the file g_sched.c.
+
+ On FreeBSD 8.0 and above, the above trick is not necessary,
+ as the struct bio contains dedicated fields for the classifier,
+ and hooks for request classifiers.
+
+ If you don't like the above, don't run this code.
+
+2. PLEASE MAKE SURE THAT THE DISK THAT YOU WILL BE USING FOR TESTS
+ DOES NOT CONTAIN PRECIOUS DATA.
+ This is experimental code, so we make no guarantees, though
+ I am routinely using it on my desktop and laptop.
+
+3. EXTRACT AND BUILD THE PROGRAMS
+ A 'make install' in the directory should work (with root privs),
+ or you can even try the binary modules.
+ If you want to build the modules yourself, look at the Makefile.
+
+4. LOAD THE MODULE, CREATE A GEOM NODE, RUN TESTS
+
+ The scheduler's module must be loaded first:
+
+ # kldload gsched_rr
+
+ substitute with gsched_as to test AS. Then, supposing that you are
+ using /dev/ad0 for testing, a scheduler can be attached to it with:
+
+ # geom sched insert ad0
+
+ The scheduler is inserted transparently in the geom chain, so
+ mounted partitions and filesystems will keep working, but
+ now requests will go through the scheduler.
+
+ To change scheduler on-the-fly, you can reconfigure the geom:
+
+ # geom sched configure -a as ad0.sched.
+
+ assuming that gsched_as was loaded previously.
+
+5. SCHEDULER REMOVAL
+
+ In principle it is possible to remove the scheduler module
+ even on an active chain by doing
+
+ # geom sched destroy ad0.sched.
+
+ However, there is some race in the geom subsystem which makes
+ the removal unsafe if there are active requests on a chain.
+ So, in order to reduce the risk of data losses, make sure
+ you don't remove a scheduler from a chain with ongoing transactions.
+
+--- NOTES ON THE SCHEDULERS ---
+
+The important contribution of this code is the framework to experiment
+with different scheduling algorithms. 'Anticipatory scheduling'
+is a very powerful technique based on the following reasoning:
+
+ The disk throughput is much better if it serves sequential requests.
+ If we have a mix of sequential and random requests, and we see a
+ non-sequential request, do not serve it immediately but instead wait
+ a little bit (2..5ms) to see if there is another one coming that
+ the disk can serve more efficiently.
+
+There are many details that should be added to make sure that the
+mechanism is effective with different workloads and systems, to
+gain a few extra percent in performance, to improve fairness,
+insulation among processes etc. A discussion of the vast literature
+on the subject is beyond the purpose of this short note.
+
+--------------------------------------------------------------------------
+
+TRANSPARENT INSERT/DELETE
+
+geom_sched is an ordinary geom module, however it is convenient
+to plug it transparently into the geom graph, so that one can
+enable or disable scheduling on a mounted filesystem, and the
+names in /etc/fstab do not depend on the presence of the scheduler.
+
+To understand how this works in practice, remember that in GEOM
+we have "providers" and "geom" objects.
+Say that we want to hook a scheduler on provider "ad0",
+accessible through pointer 'pp'. Originally, pp is attached to
+geom "ad0" (same name, different object) accessible through pointer old_gp
+
+ BEFORE ---> [ pp --> old_gp ...]
+
+A normal "geom sched create ad0" call would create a new geom node
+on top of provider ad0/pp, and export a newly created provider
+("ad0.sched." accessible through pointer newpp).
+
+ AFTER create ---> [ newpp --> gp --> cp ] ---> [ pp --> old_gp ... ]
+
+On top of newpp, a whole tree will be created automatically, and we
+can e.g. mount partitions on /dev/ad0.sched.s1d, and those requests
+will go through the scheduler, whereas any partition mounted on
+the pre-existing device entries will not go through the scheduler.
+
+With the transparent insert mechanism, the original provider "ad0"/pp
+is hooked to the newly created geom, as follows:
+
+ AFTER insert ---> [ pp --> gp --> cp ] ---> [ newpp --> old_gp ... ]
+
+so anything that was previously using provider pp will now have
+the requests routed through the scheduler node.
+
+A removal ("geom sched destroy ad0.sched.") will restore the original
+configuration.
+
+# $FreeBSD$
diff --git a/sys/geom/sched/g_sched.c b/sys/geom/sched/g_sched.c
new file mode 100644
index 0000000..6f339b9
--- /dev/null
+++ b/sys/geom/sched/g_sched.c
@@ -0,0 +1,1895 @@
+/*-
+ * Copyright (c) 2009-2010 Fabio Checconi
+ * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
+ * 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 AUTHORS 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 AUTHORS 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.
+ */
+
+/*
+ * $Id$
+ * $FreeBSD$
+ *
+ * Main control module for geom-based disk schedulers ('sched').
+ *
+ * USER VIEW
+ * A 'sched' node is typically inserted transparently between
+ * an existing provider pp and its original geom gp
+ *
+ * [pp --> gp ..]
+ *
+ * using the command "geom sched insert <provider>" and
+ * resulting in the following topology
+ *
+ * [pp --> sched_gp --> cp] [new_pp --> gp ... ]
+ *
+ * Deletion "geom sched destroy <provider>.sched." restores the
+ * original chain. The normal "geom sched create <provide>"
+ * is also supported.
+ *
+ * INTERNALS
+ * Internally, the 'sched' uses the following data structures
+ *
+ * geom{} g_sched_softc{} g_gsched{}
+ * +----------+ +---------------+ +-------------+
+ * | softc *-|--->| sc_gsched *-|-->| gs_init |
+ * | ... | | | | gs_fini |
+ * | | | [ hash table] | | gs_start |
+ * +----------+ | | | ... |
+ * | | +-------------+
+ * | |
+ * | | g_*_softc{}
+ * | | +-------------+
+ * | sc_data *-|-->| |
+ * +---------------+ | algorithm- |
+ * | specific |
+ * +-------------+
+ *
+ * A g_sched_softc{} is created with a "geom sched insert" call.
+ * In turn this instantiates a specific scheduling algorithm,
+ * which sets sc_gsched to point to the algorithm callbacks,
+ * and calls gs_init() to create the g_*_softc{} .
+ * The other callbacks (gs_start, gs_next, ...) are invoked
+ * as needed
+ *
+ * g_sched_softc{} is defined in g_sched.h and mostly used here;
+ * g_gsched{}, and the gs_callbacks, are documented in gs_scheduler.h;
+ * g_*_softc{} is defined/implemented by each algorithm (gs_*.c)
+ *
+ * DATA MOVING
+ * When a bio is received on the provider, it goes to the
+ * g_sched_start() which calls gs_start() to initially queue it;
+ * then we call g_sched_dispatch() that loops around gs_next()
+ * to select zero or more bio's to be sent downstream.
+ *
+ * g_sched_dispatch() can also be called as a result of a timeout,
+ * e.g. when doing anticipation or pacing requests.
+ *
+ * When a bio comes back, it goes to g_sched_done() which in turn
+ * calls gs_done(). The latter does any necessary housekeeping in
+ * the scheduling algorithm, and may decide to call g_sched_dispatch()
+ * to send more bio's downstream.
+ *
+ * If an algorithm needs per-flow queues, these are created
+ * calling gs_init_class() and destroyed with gs_fini_class(),
+ * and they are also inserted in the hash table implemented in
+ * the g_sched_softc{}
+ *
+ * If an algorithm is replaced, or a transparently-inserted node is
+ * removed with "geom sched destroy", we need to remove all references
+ * to the g_*_softc{} and g_sched_softc from the bio's still in
+ * the scheduler. g_sched_forced_dispatch() helps doing this.
+ * XXX need to explain better.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/bio.h>
+#include <sys/limits.h>
+#include <sys/hash.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/proc.h> /* we access curthread */
+#include <geom/geom.h>
+#include "gs_scheduler.h"
+#include "g_sched.h" /* geom hooks */
+
+/*
+ * Size of the per-geom hash table storing traffic classes.
+ * We may decide to change it at a later time, it has no ABI
+ * implications as it is only used for run-time allocations.
+ */
+#define G_SCHED_HASH_SIZE 32
+
+static int g_sched_destroy(struct g_geom *gp, boolean_t force);
+static int g_sched_destroy_geom(struct gctl_req *req,
+ struct g_class *mp, struct g_geom *gp);
+static void g_sched_config(struct gctl_req *req, struct g_class *mp,
+ const char *verb);
+static struct g_geom *g_sched_taste(struct g_class *mp,
+ struct g_provider *pp, int flags __unused);
+static void g_sched_dumpconf(struct sbuf *sb, const char *indent,
+ struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp);
+static void g_sched_init(struct g_class *mp);
+static void g_sched_fini(struct g_class *mp);
+
+struct g_class g_sched_class = {
+ .name = G_SCHED_CLASS_NAME,
+ .version = G_VERSION,
+ .ctlreq = g_sched_config,
+ .taste = g_sched_taste,
+ .destroy_geom = g_sched_destroy_geom,
+ .init = g_sched_init,
+ .fini = g_sched_fini
+};
+
+MALLOC_DEFINE(M_GEOM_SCHED, "GEOM_SCHED", "Geom schedulers data structures");
+
+/*
+ * Global variables describing the state of the geom_sched module.
+ * There is only one static instance of this structure.
+ */
+LIST_HEAD(gs_list, g_gsched); /* type, link field */
+struct geom_sched_vars {
+ struct mtx gs_mtx;
+ struct gs_list gs_scheds; /* list of algorithms */
+ u_int gs_debug;
+ u_int gs_sched_count; /* how many algorithms ? */
+ u_int gs_patched; /* g_io_request was patched */
+
+ u_int gs_initialized;
+ u_int gs_expire_secs; /* expiration of hash entries */
+
+ struct bio_queue_head gs_pending;
+ u_int gs_npending;
+
+ /* The following are for stats, usually protected by gs_mtx. */
+ u_long gs_requests; /* total requests */
+ u_long gs_done; /* total done */
+ u_int gs_in_flight; /* requests in flight */
+ u_int gs_writes_in_flight;
+ u_int gs_bytes_in_flight;
+ u_int gs_write_bytes_in_flight;
+
+ char gs_names[256]; /* names of schedulers */
+};
+
+static struct geom_sched_vars me = {
+ .gs_expire_secs = 10,
+};
+
+SYSCTL_DECL(_kern_geom);
+SYSCTL_NODE(_kern_geom, OID_AUTO, sched, CTLFLAG_RW, 0,
+ "GEOM_SCHED stuff");
+
+SYSCTL_INT(_kern_geom_sched, OID_AUTO, in_flight_wb, CTLFLAG_RD,
+ &me.gs_write_bytes_in_flight, 0, "Write bytes in flight");
+
+SYSCTL_INT(_kern_geom_sched, OID_AUTO, in_flight_b, CTLFLAG_RD,
+ &me.gs_bytes_in_flight, 0, "Bytes in flight");
+
+SYSCTL_UINT(_kern_geom_sched, OID_AUTO, in_flight_w, CTLFLAG_RD,
+ &me.gs_writes_in_flight, 0, "Write Requests in flight");
+
+SYSCTL_UINT(_kern_geom_sched, OID_AUTO, in_flight, CTLFLAG_RD,
+ &me.gs_in_flight, 0, "Requests in flight");
+
+SYSCTL_ULONG(_kern_geom_sched, OID_AUTO, done, CTLFLAG_RD,
+ &me.gs_done, 0, "Total done");
+
+SYSCTL_ULONG(_kern_geom_sched, OID_AUTO, requests, CTLFLAG_RD,
+ &me.gs_requests, 0, "Total requests");
+
+SYSCTL_STRING(_kern_geom_sched, OID_AUTO, algorithms, CTLFLAG_RD,
+ &me.gs_names, 0, "Algorithm names");
+
+SYSCTL_UINT(_kern_geom_sched, OID_AUTO, alg_count, CTLFLAG_RD,
+ &me.gs_sched_count, 0, "Number of algorithms");
+
+SYSCTL_UINT(_kern_geom_sched, OID_AUTO, debug, CTLFLAG_RW,
+ &me.gs_debug, 0, "Debug level");
+
+SYSCTL_UINT(_kern_geom_sched, OID_AUTO, expire_secs, CTLFLAG_RW,
+ &me.gs_expire_secs, 0, "Expire time in seconds");
+
+/*
+ * g_sched calls the scheduler algorithms with this lock held.
+ * The locking functions are exposed so the scheduler algorithms can also
+ * protect themselves e.g. when running a callout handler.
+ */
+void
+g_sched_lock(struct g_geom *gp)
+{
+ struct g_sched_softc *sc = gp->softc;
+
+ mtx_lock(&sc->sc_mtx);
+}
+
+void
+g_sched_unlock(struct g_geom *gp)
+{
+ struct g_sched_softc *sc = gp->softc;
+
+ mtx_unlock(&sc->sc_mtx);
+}
+
+/*
+ * Support functions to handle references to the module,
+ * which are coming from devices using this scheduler.
+ */
+static inline void
+g_gsched_ref(struct g_gsched *gsp)
+{
+
+ atomic_add_int(&gsp->gs_refs, 1);
+}
+
+static inline void
+g_gsched_unref(struct g_gsched *gsp)
+{
+
+ atomic_add_int(&gsp->gs_refs, -1);
+}
+
+/*
+ * Update the stats when this request is done.
+ */
+static void
+g_sched_update_stats(struct bio *bio)
+{
+
+ me.gs_done++;
+ me.gs_in_flight--;
+ me.gs_bytes_in_flight -= bio->bio_length;
+ if (bio->bio_cmd & BIO_WRITE) {
+ me.gs_writes_in_flight--;
+ me.gs_write_bytes_in_flight -= bio->bio_length;
+ }
+}
+
+/*
+ * Dispatch any pending request.
+ */
+static void
+g_sched_forced_dispatch(struct g_geom *gp)
+{
+ struct g_sched_softc *sc = gp->softc;
+ struct g_gsched *gsp = sc->sc_gsched;
+ struct bio *bp;
+
+ KASSERT(mtx_owned(&sc->sc_mtx),
+ ("sc_mtx not owned during forced dispatch"));
+
+ while ((bp = gsp->gs_next(sc->sc_data, 1)) != NULL)
+ g_io_request(bp, LIST_FIRST(&gp->consumer));
+}
+
+/*
+ * The main dispatch loop, called either here after the start
+ * routine, or by scheduling algorithms when they receive a timeout
+ * or a 'done' notification. Does not share code with the forced
+ * dispatch path, since the gs_done() callback can call us.
+ */
+void
+g_sched_dispatch(struct g_geom *gp)
+{
+ struct g_sched_softc *sc = gp->softc;
+ struct g_gsched *gsp = sc->sc_gsched;
+ struct bio *bp;
+
+ KASSERT(mtx_owned(&sc->sc_mtx), ("sc_mtx not owned during dispatch"));
+
+ if ((sc->sc_flags & G_SCHED_FLUSHING))
+ return;
+
+ while ((bp = gsp->gs_next(sc->sc_data, 0)) != NULL)
+ g_io_request(bp, LIST_FIRST(&gp->consumer));
+}
+
+/*
+ * Recent (8.0 and above) versions of FreeBSD have support to
+ * register classifiers of disk requests. The classifier is
+ * invoked by g_io_request(), and stores the information into
+ * bp->bio_classifier1.
+ *
+ * Support for older versions, which is left here only for
+ * documentation purposes, relies on two hacks:
+ * 1. classification info is written into the bio_caller1
+ * field of the topmost node in the bio chain. This field
+ * is rarely used, but this module is incompatible with
+ * those that use bio_caller1 for other purposes,
+ * such as ZFS and gjournal;
+ * 2. g_io_request() is patched in-memory when the module is
+ * loaded, so that the function calls a classifier as its
+ * first thing. g_io_request() is restored when the module
+ * is unloaded. This functionality is only supported for
+ * x86 and amd64, other architectures need source code changes.
+ */
+
+/*
+ * Lookup the identity of the issuer of the original request.
+ * In the current implementation we use the curthread of the
+ * issuer, but different mechanisms may be implemented later
+ * so we do not make assumptions on the return value which for
+ * us is just an opaque identifier.
+ */
+
+static inline u_long
+g_sched_classify(struct bio *bp)
+{
+
+#if __FreeBSD_version > 800098
+ /* we have classifier fields in the struct bio */
+#define HAVE_BIO_CLASSIFIER
+ return ((u_long)bp->bio_classifier1);
+#else
+#warning old version!!!
+ while (bp->bio_parent != NULL)
+ bp = bp->bio_parent;
+
+ return ((u_long)bp->bio_caller1);
+#endif
+}
+
+/* Return the hash chain for the given key. */
+static inline struct g_hash *
+g_sched_hash(struct g_sched_softc *sc, u_long key)
+{
+
+ return (&sc->sc_hash[key & sc->sc_mask]);
+}
+
+/*
+ * Helper function for the children classes, which takes
+ * a geom and a bio and returns the private descriptor
+ * associated to the request. This involves fetching
+ * the classification field and [al]locating the
+ * corresponding entry in the hash table.
+ */
+void *
+g_sched_get_class(struct g_geom *gp, struct bio *bp)
+{
+ struct g_sched_softc *sc;
+ struct g_sched_class *gsc;
+ struct g_gsched *gsp;
+ struct g_hash *bucket;
+ u_long key;
+
+ sc = gp->softc;
+ key = g_sched_classify(bp);
+ bucket = g_sched_hash(sc, key);
+ LIST_FOREACH(gsc, bucket, gsc_clist) {
+ if (key == gsc->gsc_key) {
+ gsc->gsc_refs++;
+ return (gsc->gsc_priv);
+ }
+ }
+
+ gsp = sc->sc_gsched;
+ gsc = malloc(sizeof(*gsc) + gsp->gs_priv_size,
+ M_GEOM_SCHED, M_NOWAIT | M_ZERO);
+ if (!gsc)
+ return (NULL);
+
+ if (gsp->gs_init_class(sc->sc_data, gsc->gsc_priv)) {
+ free(gsc, M_GEOM_SCHED);
+ return (NULL);
+ }
+
+ gsc->gsc_refs = 2; /* 1 for the hash table, 1 for the caller. */
+ gsc->gsc_key = key;
+ LIST_INSERT_HEAD(bucket, gsc, gsc_clist);
+
+ gsc->gsc_expire = ticks + me.gs_expire_secs * hz;
+
+ return (gsc->gsc_priv);
+}
+
+/*
+ * Release a reference to the per-client descriptor,
+ */
+void
+g_sched_put_class(struct g_geom *gp, void *priv)
+{
+ struct g_sched_class *gsc;
+ struct g_sched_softc *sc;
+
+ gsc = g_sched_priv2class(priv);
+ gsc->gsc_expire = ticks + me.gs_expire_secs * hz;
+
+ if (--gsc->gsc_refs > 0)
+ return;
+
+ sc = gp->softc;
+ sc->sc_gsched->gs_fini_class(sc->sc_data, priv);
+
+ LIST_REMOVE(gsc, gsc_clist);
+ free(gsc, M_GEOM_SCHED);
+}
+
+static void
+g_sched_hash_fini(struct g_geom *gp, struct g_hash *hp, u_long mask,
+ struct g_gsched *gsp, void *data)
+{
+ struct g_sched_class *cp, *cp2;
+ int i;
+
+ if (!hp)
+ return;
+
+ if (data && gsp->gs_hash_unref)
+ gsp->gs_hash_unref(data);
+
+ for (i = 0; i < G_SCHED_HASH_SIZE; i++) {
+ LIST_FOREACH_SAFE(cp, &hp[i], gsc_clist, cp2)
+ g_sched_put_class(gp, cp->gsc_priv);
+ }
+
+ hashdestroy(hp, M_GEOM_SCHED, mask);
+}
+
+static struct g_hash *
+g_sched_hash_init(struct g_gsched *gsp, u_long *mask, int flags)
+{
+ struct g_hash *hash;
+
+ if (gsp->gs_priv_size == 0)
+ return (NULL);
+
+ hash = hashinit_flags(G_SCHED_HASH_SIZE, M_GEOM_SCHED, mask, flags);
+
+ return (hash);
+}
+
+static void
+g_sched_flush_classes(struct g_geom *gp)
+{
+ struct g_sched_softc *sc;
+ struct g_sched_class *cp, *cp2;
+ int i;
+
+ sc = gp->softc;
+
+ if (!sc->sc_hash || ticks - sc->sc_flush_ticks <= 0)
+ return;
+
+ for (i = 0; i < G_SCHED_HASH_SIZE; i++) {
+ LIST_FOREACH_SAFE(cp, &sc->sc_hash[i], gsc_clist, cp2) {
+ if (cp->gsc_refs == 1 && ticks - cp->gsc_expire > 0)
+ g_sched_put_class(gp, cp->gsc_priv);
+ }
+ }
+
+ sc->sc_flush_ticks = ticks + me.gs_expire_secs * hz;
+}
+
+/*
+ * Wait for the completion of any outstanding request. To ensure
+ * that this does not take forever the caller has to make sure that
+ * no new request enter the scehduler before calling us.
+ *
+ * Must be called with the gp mutex held and topology locked.
+ */
+static int
+g_sched_wait_pending(struct g_geom *gp)
+{
+ struct g_sched_softc *sc = gp->softc;
+ int endticks = ticks + hz;
+
+ g_topology_assert();
+
+ while (sc->sc_pending && endticks - ticks >= 0)
+ msleep(gp, &sc->sc_mtx, 0, "sched_wait_pending", hz / 4);
+
+ return (sc->sc_pending ? ETIMEDOUT : 0);
+}
+
+static int
+g_sched_remove_locked(struct g_geom *gp, struct g_gsched *gsp)
+{
+ struct g_sched_softc *sc = gp->softc;
+ int error;
+
+ /* Set the flushing flag: new bios will not enter the scheduler. */
+ sc->sc_flags |= G_SCHED_FLUSHING;
+
+ g_sched_forced_dispatch(gp);
+ error = g_sched_wait_pending(gp);
+ if (error)
+ goto failed;
+
+ /* No more requests pending or in flight from the old gsp. */
+
+ g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask, gsp, sc->sc_data);
+ sc->sc_hash = NULL;
+
+ /*
+ * Avoid deadlock here by releasing the gp mutex and reacquiring
+ * it once done. It should be safe, since no reconfiguration or
+ * destruction can take place due to the geom topology lock; no
+ * new request can use the current sc_data since we flagged the
+ * geom as being flushed.
+ */
+ g_sched_unlock(gp);
+ gsp->gs_fini(sc->sc_data);
+ g_sched_lock(gp);
+
+ sc->sc_gsched = NULL;
+ sc->sc_data = NULL;
+ g_gsched_unref(gsp);
+
+failed:
+ sc->sc_flags &= ~G_SCHED_FLUSHING;
+
+ return (error);
+}
+
+static int
+g_sched_remove(struct g_geom *gp, struct g_gsched *gsp)
+{
+ int error;
+
+ g_sched_lock(gp);
+ error = g_sched_remove_locked(gp, gsp); /* gsp is surely non-null */
+ g_sched_unlock(gp);
+
+ return (error);
+}
+
+/*
+ * Support function for create/taste -- locate the desired
+ * algorithm and grab a reference to it.
+ */
+static struct g_gsched *
+g_gsched_find(const char *name)
+{
+ struct g_gsched *gsp = NULL;
+
+ mtx_lock(&me.gs_mtx);
+ LIST_FOREACH(gsp, &me.gs_scheds, glist) {
+ if (strcmp(name, gsp->gs_name) == 0) {
+ g_gsched_ref(gsp);
+ break;
+ }
+ }
+ mtx_unlock(&me.gs_mtx);
+
+ return (gsp);
+}
+
+/*
+ * Rebuild the list of scheduler names.
+ * To be called with me.gs_mtx lock held.
+ */
+static void
+g_gsched_build_names(struct g_gsched *gsp)
+{
+ int pos, l;
+ struct g_gsched *cur;
+
+ pos = 0;
+ LIST_FOREACH(cur, &me.gs_scheds, glist) {
+ l = strlen(cur->gs_name);
+ if (l + pos + 1 + 1 < sizeof(me.gs_names)) {
+ if (pos != 0)
+ me.gs_names[pos++] = ' ';
+ strcpy(me.gs_names + pos, cur->gs_name);
+ pos += l;
+ }
+ }
+ me.gs_names[pos] = '\0';
+}
+
+/*
+ * Register or unregister individual scheduling algorithms.
+ */
+static int
+g_gsched_register(struct g_gsched *gsp)
+{
+ struct g_gsched *cur;
+ int error = 0;
+
+ mtx_lock(&me.gs_mtx);
+ LIST_FOREACH(cur, &me.gs_scheds, glist) {
+ if (strcmp(gsp->gs_name, cur->gs_name) == 0)
+ break;
+ }
+ if (cur != NULL) {
+ G_SCHED_DEBUG(0, "A scheduler named %s already"
+ "exists.", gsp->gs_name);
+ error = EEXIST;
+ } else {
+ LIST_INSERT_HEAD(&me.gs_scheds, gsp, glist);
+ gsp->gs_refs = 1;
+ me.gs_sched_count++;
+ g_gsched_build_names(gsp);
+ }
+ mtx_unlock(&me.gs_mtx);
+
+ return (error);
+}
+
+struct g_gsched_unregparm {
+ struct g_gsched *gup_gsp;
+ int gup_error;
+};
+
+static void
+g_gsched_unregister(void *arg, int flag)
+{
+ struct g_gsched_unregparm *parm = arg;
+ struct g_gsched *gsp = parm->gup_gsp, *cur, *tmp;
+ struct g_sched_softc *sc;
+ struct g_geom *gp, *gp_tmp;
+ int error;
+
+ parm->gup_error = 0;
+
+ g_topology_assert();
+
+ if (flag == EV_CANCEL)
+ return;
+
+ mtx_lock(&me.gs_mtx);
+
+ LIST_FOREACH_SAFE(gp, &g_sched_class.geom, geom, gp_tmp) {
+ if (gp->class != &g_sched_class)
+ continue; /* Should not happen. */
+
+ sc = gp->softc;
+ if (sc->sc_gsched == gsp) {
+ error = g_sched_remove(gp, gsp);
+ if (error)
+ goto failed;
+ }
+ }
+
+ LIST_FOREACH_SAFE(cur, &me.gs_scheds, glist, tmp) {
+ if (cur != gsp)
+ continue;
+
+ if (gsp->gs_refs != 1) {
+ G_SCHED_DEBUG(0, "%s still in use.",
+ gsp->gs_name);
+ parm->gup_error = EBUSY;
+ } else {
+ LIST_REMOVE(gsp, glist);
+ me.gs_sched_count--;
+ g_gsched_build_names(gsp);
+ }
+ break;
+ }
+
+ if (cur == NULL) {
+ G_SCHED_DEBUG(0, "%s not registered.", gsp->gs_name);
+ parm->gup_error = ENOENT;
+ }
+
+failed:
+ mtx_unlock(&me.gs_mtx);
+}
+
+static inline void
+g_gsched_global_init(void)
+{
+
+ if (!me.gs_initialized) {
+ G_SCHED_DEBUG(0, "Initializing global data.");
+ mtx_init(&me.gs_mtx, "gsched", NULL, MTX_DEF);
+ LIST_INIT(&me.gs_scheds);
+ gs_bioq_init(&me.gs_pending);
+ me.gs_initialized = 1;
+ }
+}
+
+/*
+ * Module event called when a scheduling algorithm module is loaded or
+ * unloaded.
+ */
+int
+g_gsched_modevent(module_t mod, int cmd, void *arg)
+{
+ struct g_gsched *gsp = arg;
+ struct g_gsched_unregparm parm;
+ int error;
+
+ G_SCHED_DEBUG(0, "Modevent %d.", cmd);
+
+ /*
+ * If the module is loaded at boot, the geom thread that calls
+ * g_sched_init() might actually run after g_gsched_modevent(),
+ * so make sure that the module is properly initialized.
+ */
+ g_gsched_global_init();
+
+ error = EOPNOTSUPP;
+ switch (cmd) {
+ case MOD_LOAD:
+ error = g_gsched_register(gsp);
+ G_SCHED_DEBUG(0, "Loaded module %s error %d.",
+ gsp->gs_name, error);
+ if (error == 0)
+ g_retaste(&g_sched_class);
+ break;
+
+ case MOD_UNLOAD:
+ parm.gup_gsp = gsp;
+ parm.gup_error = 0;
+
+ error = g_waitfor_event(g_gsched_unregister,
+ &parm, M_WAITOK, NULL);
+ if (error == 0)
+ error = parm.gup_error;
+ G_SCHED_DEBUG(0, "Unloaded module %s error %d.",
+ gsp->gs_name, error);
+ break;
+ };
+
+ return (error);
+}
+
+#ifdef KTR
+#define TRC_BIO_EVENT(e, bp) g_sched_trace_bio_ ## e (bp)
+
+static inline char
+g_sched_type(struct bio *bp)
+{
+
+ if (0 != (bp->bio_cmd & BIO_READ))
+ return ('R');
+ else if (0 != (bp->bio_cmd & BIO_WRITE))
+ return ('W');
+ return ('U');
+}
+
+static inline void
+g_sched_trace_bio_START(struct bio *bp)
+{
+
+ CTR5(KTR_GSCHED, "S %lu %c %lu/%lu %lu", g_sched_classify(bp),
+ g_sched_type(bp), bp->bio_offset / ULONG_MAX,
+ bp->bio_offset, bp->bio_length);
+}
+
+static inline void
+g_sched_trace_bio_DONE(struct bio *bp)
+{
+
+ CTR5(KTR_GSCHED, "D %lu %c %lu/%lu %lu", g_sched_classify(bp),
+ g_sched_type(bp), bp->bio_offset / ULONG_MAX,
+ bp->bio_offset, bp->bio_length);
+}
+#else /* !KTR */
+#define TRC_BIO_EVENT(e, bp)
+#endif /* !KTR */
+
+/*
+ * g_sched_done() and g_sched_start() dispatch the geom requests to
+ * the scheduling algorithm in use.
+ */
+static void
+g_sched_done(struct bio *bio)
+{
+ struct g_geom *gp = bio->bio_caller2;
+ struct g_sched_softc *sc = gp->softc;
+
+ TRC_BIO_EVENT(DONE, bio);
+
+ KASSERT(bio->bio_caller1, ("null bio_caller1 in g_sched_done"));
+
+ g_sched_lock(gp);
+
+ g_sched_update_stats(bio);
+ sc->sc_gsched->gs_done(sc->sc_data, bio);
+ if (!--sc->sc_pending)
+ wakeup(gp);
+
+ g_sched_flush_classes(gp);
+ g_sched_unlock(gp);
+
+ g_std_done(bio);
+}
+
+static void
+g_sched_start(struct bio *bp)
+{
+ struct g_geom *gp = bp->bio_to->geom;
+ struct g_sched_softc *sc = gp->softc;
+ struct bio *cbp;
+
+ TRC_BIO_EVENT(START, bp);
+ G_SCHED_LOGREQ(bp, "Request received.");
+
+ cbp = g_clone_bio(bp);
+ if (cbp == NULL) {
+ g_io_deliver(bp, ENOMEM);
+ return;
+ }
+ cbp->bio_done = g_sched_done;
+ cbp->bio_to = LIST_FIRST(&gp->provider);
+ KASSERT(cbp->bio_to != NULL, ("NULL provider"));
+
+ /* We only schedule reads and writes. */
+ if (0 == (bp->bio_cmd & (BIO_READ | BIO_WRITE)))
+ goto bypass;
+
+ G_SCHED_LOGREQ(cbp, "Sending request.");
+
+ g_sched_lock(gp);
+ /*
+ * Call the algorithm's gs_start to queue the request in the
+ * scheduler. If gs_start fails then pass the request down,
+ * otherwise call g_sched_dispatch() which tries to push
+ * one or more requests down.
+ */
+ if (!sc->sc_gsched || (sc->sc_flags & G_SCHED_FLUSHING) ||
+ sc->sc_gsched->gs_start(sc->sc_data, cbp)) {
+ g_sched_unlock(gp);
+ goto bypass;
+ }
+ /*
+ * We use bio_caller1 to mark requests that are scheduled
+ * so make sure it is not NULL.
+ */
+ if (cbp->bio_caller1 == NULL)
+ cbp->bio_caller1 = &me; /* anything not NULL */
+
+ cbp->bio_caller2 = gp;
+ sc->sc_pending++;
+
+ /* Update general stats. */
+ me.gs_in_flight++;
+ me.gs_requests++;
+ me.gs_bytes_in_flight += bp->bio_length;
+ if (bp->bio_cmd & BIO_WRITE) {
+ me.gs_writes_in_flight++;
+ me.gs_write_bytes_in_flight += bp->bio_length;
+ }
+ g_sched_dispatch(gp);
+ g_sched_unlock(gp);
+ return;
+
+bypass:
+ cbp->bio_done = g_std_done;
+ cbp->bio_caller1 = NULL; /* not scheduled */
+ g_io_request(cbp, LIST_FIRST(&gp->consumer));
+}
+
+/*
+ * The next few functions are the geom glue.
+ */
+static void
+g_sched_orphan(struct g_consumer *cp)
+{
+
+ g_topology_assert();
+ g_sched_destroy(cp->geom, 1);
+}
+
+static int
+g_sched_access(struct g_provider *pp, int dr, int dw, int de)
+{
+ struct g_geom *gp;
+ struct g_consumer *cp;
+ int error;
+
+ gp = pp->geom;
+ cp = LIST_FIRST(&gp->consumer);
+ error = g_access(cp, dr, dw, de);
+
+ return (error);
+}
+
+static void
+g_sched_temporary_start(struct bio *bio)
+{
+
+ mtx_lock(&me.gs_mtx);
+ me.gs_npending++;
+ gs_bioq_disksort(&me.gs_pending, bio);
+ mtx_unlock(&me.gs_mtx);
+}
+
+static void
+g_sched_flush_pending(g_start_t *start)
+{
+ struct bio *bp;
+
+ while ((bp = gs_bioq_takefirst(&me.gs_pending)))
+ start(bp);
+}
+
+static int
+g_insert_proxy(struct g_geom *gp, struct g_provider *newpp,
+ struct g_geom *dstgp, struct g_provider *pp, struct g_consumer *cp)
+{
+ struct g_sched_softc *sc = gp->softc;
+ g_start_t *saved_start, *flush = g_sched_start;
+ int error = 0, endticks = ticks + hz;
+
+ g_cancel_event(newpp); /* prevent taste() */
+ /* copy private fields */
+ newpp->private = pp->private;
+ newpp->index = pp->index;
+
+ /* Queue all the early requests coming for us. */
+ me.gs_npending = 0;
+ saved_start = pp->geom->start;
+ dstgp->start = g_sched_temporary_start;
+
+ while (pp->nstart - pp->nend != me.gs_npending &&
+ endticks - ticks >= 0)
+ tsleep(pp, PRIBIO, "-", hz/10);
+
+ if (pp->nstart - pp->nend != me.gs_npending) {
+ flush = saved_start;
+ error = ETIMEDOUT;
+ goto fail;
+ }
+
+ /* link pp to this geom */
+ LIST_REMOVE(pp, provider);
+ pp->geom = gp;
+ LIST_INSERT_HEAD(&gp->provider, pp, provider);
+
+ /*
+ * replicate the counts from the parent in the
+ * new provider and consumer nodes
+ */
+ cp->acr = newpp->acr = pp->acr;
+ cp->acw = newpp->acw = pp->acw;
+ cp->ace = newpp->ace = pp->ace;
+ sc->sc_flags |= G_SCHED_PROXYING;
+
+fail:
+ dstgp->start = saved_start;
+
+ g_sched_flush_pending(flush);
+
+ return (error);
+}
+
+/*
+ * Create a geom node for the device passed as *pp.
+ * If successful, add a reference to this gsp.
+ */
+static int
+g_sched_create(struct gctl_req *req, struct g_class *mp,
+ struct g_provider *pp, struct g_gsched *gsp, int proxy)
+{
+ struct g_sched_softc *sc = NULL;
+ struct g_geom *gp, *dstgp;
+ struct g_provider *newpp = NULL;
+ struct g_consumer *cp = NULL;
+ char name[64];
+ int error;
+
+ g_topology_assert();
+
+ snprintf(name, sizeof(name), "%s%s", pp->name, G_SCHED_SUFFIX);
+ LIST_FOREACH(gp, &mp->geom, geom) {
+ if (strcmp(gp->name, name) == 0) {
+ gctl_error(req, "Geom %s already exists.",
+ name);
+ return (EEXIST);
+ }
+ }
+
+ gp = g_new_geomf(mp, name);
+ dstgp = proxy ? pp->geom : gp; /* where do we link the provider */
+ if (gp == NULL) {
+ gctl_error(req, "Cannot create geom %s.", name);
+ error = ENOMEM;
+ goto fail;
+ }
+
+ sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
+ sc->sc_gsched = gsp;
+ sc->sc_data = gsp->gs_init(gp);
+ if (sc->sc_data == NULL) {
+ error = ENOMEM;
+ goto fail;
+ }
+
+ sc->sc_hash = g_sched_hash_init(gsp, &sc->sc_mask, HASH_WAITOK);
+
+ /*
+ * Do not initialize the flush mechanism, will be initialized
+ * on the first insertion on the hash table.
+ */
+
+ mtx_init(&sc->sc_mtx, "g_sched_mtx", NULL, MTX_DEF);
+
+ gp->softc = sc;
+ gp->start = g_sched_start;
+ gp->orphan = g_sched_orphan;
+ gp->access = g_sched_access;
+ gp->dumpconf = g_sched_dumpconf;
+
+ newpp = g_new_providerf(dstgp, gp->name);
+ if (newpp == NULL) {
+ gctl_error(req, "Cannot create provider %s.", name);
+ error = ENOMEM;
+ goto fail;
+ }
+
+ newpp->mediasize = pp->mediasize;
+ newpp->sectorsize = pp->sectorsize;
+
+ cp = g_new_consumer(gp);
+ if (cp == NULL) {
+ gctl_error(req, "Cannot create consumer for %s.",
+ gp->name);
+ error = ENOMEM;
+ goto fail;
+ }
+
+ error = g_attach(cp, proxy ? newpp : pp);
+ if (error != 0) {
+ gctl_error(req, "Cannot attach to provider %s.",
+ pp->name);
+ goto fail;
+ }
+
+ g_error_provider(newpp, 0);
+ if (proxy) {
+ error = g_insert_proxy(gp, newpp, dstgp, pp, cp);
+ if (error)
+ goto fail;
+ }
+ G_SCHED_DEBUG(0, "Device %s created.", gp->name);
+
+ g_gsched_ref(gsp);
+
+ return (0);
+
+fail:
+ if (cp != NULL) {
+ if (cp->provider != NULL)
+ g_detach(cp);
+ g_destroy_consumer(cp);
+ }
+
+ if (newpp != NULL)
+ g_destroy_provider(newpp);
+
+ if (sc && sc->sc_hash) {
+ g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask,
+ gsp, sc->sc_data);
+ }
+
+ if (sc && sc->sc_data)
+ gsp->gs_fini(sc->sc_data);
+
+ if (gp != NULL) {
+ if (gp->softc != NULL)
+ g_free(gp->softc);
+ g_destroy_geom(gp);
+ }
+
+ return (error);
+}
+
+/*
+ * Support for dynamic switching of scheduling algorithms.
+ * First initialize the data structures for the new algorithm,
+ * then call g_sched_remove_locked() to flush all references
+ * to the old one, finally link the new algorithm.
+ */
+static int
+g_sched_change_algo(struct gctl_req *req, struct g_class *mp,
+ struct g_provider *pp, struct g_gsched *gsp)
+{
+ struct g_sched_softc *sc;
+ struct g_geom *gp;
+ struct g_hash *newh;
+ void *data;
+ u_long mask;
+ int error = 0;
+
+ gp = pp->geom;
+ sc = gp->softc;
+
+ data = gsp->gs_init(gp);
+ if (data == NULL)
+ return (ENOMEM);
+
+ newh = g_sched_hash_init(gsp, &mask, HASH_WAITOK);
+ if (gsp->gs_priv_size && !newh) {
+ error = ENOMEM;
+ goto fail;
+ }
+
+ g_sched_lock(gp);
+ if (sc->sc_gsched) { /* can be NULL in some cases */
+ error = g_sched_remove_locked(gp, sc->sc_gsched);
+ if (error)
+ goto fail;
+ }
+
+ g_gsched_ref(gsp);
+ sc->sc_gsched = gsp;
+ sc->sc_data = data;
+ sc->sc_hash = newh;
+ sc->sc_mask = mask;
+
+ g_sched_unlock(gp);
+
+ return (0);
+
+fail:
+ if (newh)
+ g_sched_hash_fini(gp, newh, mask, gsp, data);
+
+ if (data)
+ gsp->gs_fini(data);
+
+ g_sched_unlock(gp);
+
+ return (error);
+}
+
+/*
+ * Stop the request flow directed to the proxy, redirecting the new
+ * requests to the me.gs_pending queue.
+ */
+static struct g_provider *
+g_detach_proxy(struct g_geom *gp)
+{
+ struct g_consumer *cp;
+ struct g_provider *pp, *newpp;
+
+ do {
+ pp = LIST_FIRST(&gp->provider);
+ if (pp == NULL)
+ break;
+ cp = LIST_FIRST(&gp->consumer);
+ if (cp == NULL)
+ break;
+ newpp = cp->provider;
+ if (newpp == NULL)
+ break;
+
+ me.gs_npending = 0;
+ pp->geom->start = g_sched_temporary_start;
+
+ return (pp);
+ } while (0);
+ printf("%s error detaching proxy %s\n", __FUNCTION__, gp->name);
+
+ return (NULL);
+}
+
+static void
+g_sched_blackhole(struct bio *bp)
+{
+
+ g_io_deliver(bp, ENXIO);
+}
+
+static inline void
+g_reparent_provider(struct g_provider *pp, struct g_geom *gp,
+ struct g_provider *newpp)
+{
+
+ LIST_REMOVE(pp, provider);
+ if (newpp) {
+ pp->private = newpp->private;
+ pp->index = newpp->index;
+ }
+ pp->geom = gp;
+ LIST_INSERT_HEAD(&gp->provider, pp, provider);
+}
+
+static inline void
+g_unproxy_provider(struct g_provider *oldpp, struct g_provider *newpp)
+{
+ struct g_geom *gp = oldpp->geom;
+
+ g_reparent_provider(oldpp, newpp->geom, newpp);
+
+ /*
+ * Hackish: let the system destroy the old provider for us, just
+ * in case someone attached a consumer to it, in which case a
+ * direct call to g_destroy_provider() would not work.
+ */
+ g_reparent_provider(newpp, gp, NULL);
+}
+
+/*
+ * Complete the proxy destruction, linking the old provider to its
+ * original geom, and destroying the proxy provider. Also take care
+ * of issuing the pending requests collected in me.gs_pending (if any).
+ */
+static int
+g_destroy_proxy(struct g_geom *gp, struct g_provider *oldpp)
+{
+ struct g_consumer *cp;
+ struct g_provider *newpp;
+
+ do {
+ cp = LIST_FIRST(&gp->consumer);
+ if (cp == NULL)
+ break;
+ newpp = cp->provider;
+ if (newpp == NULL)
+ break;
+
+ /* Relink the provider to its original geom. */
+ g_unproxy_provider(oldpp, newpp);
+
+ /* Detach consumer from provider, and destroy provider. */
+ cp->acr = newpp->acr = 0;
+ cp->acw = newpp->acw = 0;
+ cp->ace = newpp->ace = 0;
+ g_detach(cp);
+
+ /* Send the pending bios through the right start function. */
+ g_sched_flush_pending(oldpp->geom->start);
+
+ return (0);
+ } while (0);
+ printf("%s error destroying proxy %s\n", __FUNCTION__, gp->name);
+
+ /* We cannot send the pending bios anywhere... */
+ g_sched_flush_pending(g_sched_blackhole);
+
+ return (EINVAL);
+}
+
+static int
+g_sched_destroy(struct g_geom *gp, boolean_t force)
+{
+ struct g_provider *pp, *oldpp = NULL;
+ struct g_sched_softc *sc;
+ struct g_gsched *gsp;
+ int error;
+
+ g_topology_assert();
+ sc = gp->softc;
+ if (sc == NULL)
+ return (ENXIO);
+ if (!(sc->sc_flags & G_SCHED_PROXYING)) {
+ pp = LIST_FIRST(&gp->provider);
+ if (pp && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
+ const char *msg = force ?
+ "but we force removal" : "cannot remove";
+
+ G_SCHED_DEBUG(!force,
+ "Device %s is still open (r%dw%de%d), %s.",
+ pp->name, pp->acr, pp->acw, pp->ace, msg);
+ if (!force)
+ return (EBUSY);
+ } else {
+ G_SCHED_DEBUG(0, "Device %s removed.", gp->name);
+ }
+ } else
+ oldpp = g_detach_proxy(gp);
+
+ gsp = sc->sc_gsched;
+ if (gsp) {
+ /*
+ * XXX bad hack here: force a dispatch to release
+ * any reference to the hash table still held by
+ * the scheduler.
+ */
+ g_sched_lock(gp);
+ /*
+ * We are dying here, no new requests should enter
+ * the scheduler. This is granted by the topolgy,
+ * either in case we were proxying (new bios are
+ * being redirected) or not (see the access check
+ * above).
+ */
+ g_sched_forced_dispatch(gp);
+ error = g_sched_wait_pending(gp);
+
+ if (error) {
+ /*
+ * Not all the requests came home: this might happen
+ * under heavy load, or if we were waiting for any
+ * bio which is served in the event path (see
+ * geom_slice.c for an example of how this can
+ * happen). Try to restore a working configuration
+ * if we can fail.
+ */
+ if ((sc->sc_flags & G_SCHED_PROXYING) && oldpp) {
+ g_sched_flush_pending(force ?
+ g_sched_blackhole : g_sched_start);
+ }
+
+ /*
+ * In the forced destroy case there is not so much
+ * we can do, we have pending bios that will call
+ * g_sched_done() somehow, and we don't want them
+ * to crash the system using freed memory. We tell
+ * the user that something went wrong, and leak some
+ * memory here.
+ * Note: the callers using force = 1 ignore the
+ * return value.
+ */
+ if (force) {
+ G_SCHED_DEBUG(0, "Pending requests while "
+ " destroying geom, some memory leaked.");
+ }
+
+ return (error);
+ }
+
+ g_sched_unlock(gp);
+ g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask,
+ gsp, sc->sc_data);
+ sc->sc_hash = NULL;
+ gsp->gs_fini(sc->sc_data);
+ g_gsched_unref(gsp);
+ sc->sc_gsched = NULL;
+ }
+
+ if ((sc->sc_flags & G_SCHED_PROXYING) && oldpp) {
+ error = g_destroy_proxy(gp, oldpp);
+
+ if (error) {
+ if (force) {
+ G_SCHED_DEBUG(0, "Unrecoverable error while "
+ "destroying a proxy geom, leaking some "
+ " memory.");
+ }
+
+ return (error);
+ }
+ }
+
+ mtx_destroy(&sc->sc_mtx);
+
+ g_free(gp->softc);
+ gp->softc = NULL;
+ g_wither_geom(gp, ENXIO);
+
+ return (error);
+}
+
+static int
+g_sched_destroy_geom(struct gctl_req *req, struct g_class *mp,
+ struct g_geom *gp)
+{
+
+ return (g_sched_destroy(gp, 0));
+}
+
+/*
+ * Functions related to the classification of requests.
+ *
+ * On recent FreeBSD versions (8.0 and above), we store a reference
+ * to the issuer of a request in bp->bio_classifier1 as soon
+ * as the bio is posted to the geom queue (and not later, because
+ * requests are managed by the g_down thread afterwards).
+ *
+ * On older versions of the system (but this code is not used
+ * in any existing release), we [ab]use the caller1 field in the
+ * root element of the bio tree to store the classification info.
+ * The marking is done at the beginning of g_io_request()
+ * and only if we find that the field is NULL.
+ *
+ * To avoid rebuilding the kernel, this module will patch the
+ * initial part of g_io_request() so it jumps to some hand-coded
+ * assembly that does the marking and then executes the original
+ * body of g_io_request().
+ *
+ * fake_ioreq[] is architecture-specific machine code
+ * that implements the above. CODE_SIZE, STORE_SIZE etc.
+ * are constants used in the patching routine. Look at the
+ * code in g_ioreq_patch() for the details.
+ */
+
+#ifndef HAVE_BIO_CLASSIFIER
+/*
+ * Support for old FreeBSD versions
+ */
+#if defined(__i386__)
+#define CODE_SIZE 29
+#define STORE_SIZE 5
+#define EPILOGUE 5
+#define SIZE (CODE_SIZE + STORE_SIZE + EPILOGUE)
+
+static u_char fake_ioreq[SIZE] = {
+ 0x8b, 0x44, 0x24, 0x04, /* mov bp, %eax */
+ /* 1: */
+ 0x89, 0xc2, /* mov %eax, %edx # edx = bp */
+ 0x8b, 0x40, 0x64, /* mov bp->bio_parent, %eax */
+ 0x85, 0xc0, /* test %eax, %eax */
+ 0x75, 0xf7, /* jne 1b */
+ 0x8b, 0x42, 0x30, /* mov bp->bp_caller1, %eax */
+ 0x85, 0xc0, /* test %eax, %eax */
+ 0x75, 0x09, /* jne 2f */
+ 0x64, 0xa1, 0x00, 0x00, /* mov %fs:0, %eax */
+ 0x00, 0x00,
+ 0x89, 0x42, 0x30, /* mov %eax, bp->bio_caller1 */
+ /* 2: */
+ 0x55, 0x89, 0xe5, 0x57, 0x56,
+ 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp back... */
+};
+#elif defined(__amd64)
+#define CODE_SIZE 38
+#define STORE_SIZE 6
+#define EPILOGUE 5
+#define SIZE (CODE_SIZE + STORE_SIZE + EPILOGUE)
+
+static u_char fake_ioreq[SIZE] = {
+ 0x48, 0x89, 0xf8, /* mov bp, %rax */
+ /* 1: */
+ 0x48, 0x89, 0xc2, /* mov %rax, %rdx # rdx = bp */
+ 0x48, 0x8b, 0x82, 0xa8, /* mov bp->bio_parent, %rax */
+ 0x00, 0x00, 0x00,
+ 0x48, 0x85, 0xc0, /* test %rax, %rax */
+ 0x75, 0xf1, /* jne 1b */
+ 0x48, 0x83, 0x7a, 0x58, /* cmp $0, bp->bp_caller1 */
+ 0x00,
+ 0x75, 0x0d, /* jne 2f */
+ 0x65, 0x48, 0x8b, 0x04, /* mov %gs:0, %rax */
+ 0x25, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x48, 0x89, 0x42, 0x58, /* mov %rax, bp->bio_caller1 */
+ /* 2: */
+ 0x55, 0x48, 0x89, 0xe5, 0x41, 0x56,
+ 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp back... */
+};
+#else /* neither x86 nor amd64 */
+static void
+g_new_io_request(struct bio *bp, struct g_consumer *cp)
+{
+ struct bio *top = bp;
+
+ /*
+ * bio classification: if bio_caller1 is available in the
+ * root of the 'struct bio' tree, store there the thread id
+ * of the thread that originated the request.
+ * More sophisticated classification schemes can be used.
+ */
+ while (top->bio_parent)
+ top = top->bio_parent;
+
+ if (top->bio_caller1 == NULL)
+ top->bio_caller1 = curthread;
+}
+
+#error please add the code above in g_new_io_request() to the beginning of \
+ /sys/geom/geom_io.c::g_io_request(), and remove this line.
+#endif /* end of arch-specific code */
+
+static int
+g_ioreq_patch(void)
+{
+ u_char *original;
+ u_long ofs;
+ int found;
+
+ if (me.gs_patched)
+ return (-1);
+
+ original = (u_char *)g_io_request;
+
+ found = !bcmp(original, fake_ioreq + CODE_SIZE, STORE_SIZE);
+ if (!found)
+ return (-1);
+
+ /* Jump back to the original + STORE_SIZE. */
+ ofs = (original + STORE_SIZE) - (fake_ioreq + SIZE);
+ bcopy(&ofs, fake_ioreq + CODE_SIZE + STORE_SIZE + 1, 4);
+
+ /* Patch the original address with a jump to the trampoline. */
+ *original = 0xe9; /* jump opcode */
+ ofs = fake_ioreq - (original + 5);
+ bcopy(&ofs, original + 1, 4);
+
+ me.gs_patched = 1;
+
+ return (0);
+}
+
+/*
+ * Restore the original code, this is easy.
+ */
+static void
+g_ioreq_restore(void)
+{
+ u_char *original;
+
+ if (me.gs_patched) {
+ original = (u_char *)g_io_request;
+ bcopy(fake_ioreq + CODE_SIZE, original, STORE_SIZE);
+ me.gs_patched = 0;
+ }
+}
+
+static inline void
+g_classifier_ini(void)
+{
+
+ g_ioreq_patch();
+}
+
+static inline void
+g_classifier_fini(void)
+{
+
+ g_ioreq_restore();
+}
+
+/*--- end of support code for older FreeBSD versions */
+
+#else /* HAVE_BIO_CLASSIFIER */
+
+/*
+ * Classifier support for recent FreeBSD versions: we use
+ * a very simple classifier, only use curthread to tag a request.
+ * The classifier is registered at module load, and unregistered
+ * at module unload.
+ */
+static int
+g_sched_tag(void *arg, struct bio *bp)
+{
+
+ bp->bio_classifier1 = curthread;
+ return (1);
+}
+
+static struct g_classifier_hook g_sched_classifier = {
+ .func = g_sched_tag,
+};
+
+static inline void
+g_classifier_ini(void)
+{
+
+ g_register_classifier(&g_sched_classifier);
+}
+
+static inline void
+g_classifier_fini(void)
+{
+
+ g_unregister_classifier(&g_sched_classifier);
+}
+#endif /* HAVE_BIO_CLASSIFIER */
+
+static void
+g_sched_init(struct g_class *mp)
+{
+
+ g_gsched_global_init();
+
+ G_SCHED_DEBUG(0, "Loading: mp = %p, g_sched_class = %p.",
+ mp, &g_sched_class);
+
+ /* Patch g_io_request to store classification info in the bio. */
+ g_classifier_ini();
+}
+
+static void
+g_sched_fini(struct g_class *mp)
+{
+
+ g_classifier_fini();
+
+ G_SCHED_DEBUG(0, "Unloading...");
+
+ KASSERT(LIST_EMPTY(&me.gs_scheds), ("still registered schedulers"));
+ mtx_destroy(&me.gs_mtx);
+}
+
+/*
+ * Read the i-th argument for a request, skipping the /dev/
+ * prefix if present.
+ */
+static const char *
+g_sched_argi(struct gctl_req *req, int i)
+{
+ static const char *dev_prefix = "/dev/";
+ const char *name;
+ char param[16];
+ int l = strlen(dev_prefix);
+
+ snprintf(param, sizeof(param), "arg%d", i);
+ name = gctl_get_asciiparam(req, param);
+ if (name == NULL)
+ gctl_error(req, "No 'arg%d' argument", i);
+ else if (strncmp(name, dev_prefix, l) == 0)
+ name += l;
+ return (name);
+}
+
+/*
+ * Fetch nargs and do appropriate checks.
+ */
+static int
+g_sched_get_nargs(struct gctl_req *req)
+{
+ int *nargs;
+
+ nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
+ if (nargs == NULL) {
+ gctl_error(req, "No 'nargs' argument");
+ return (0);
+ }
+ if (*nargs <= 0)
+ gctl_error(req, "Missing device(s).");
+ return (*nargs);
+}
+
+/*
+ * Check whether we should add the class on certain volumes when
+ * this geom is created. Right now this is under control of a kenv
+ * variable containing the names of all devices that we care about.
+ * Probably we should only support transparent insertion as the
+ * preferred mode of operation.
+ */
+static struct g_geom *
+g_sched_taste(struct g_class *mp, struct g_provider *pp,
+ int flags __unused)
+{
+ struct g_gsched *gsp = NULL; /* the . algorithm we want */
+ const char *s; /* generic string pointer */
+ const char *taste_names; /* devices we like */
+ int l;
+
+ g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__,
+ mp->name, pp->name);
+ g_topology_assert();
+
+ G_SCHED_DEBUG(2, "Tasting %s.", pp->name);
+
+ do {
+ /* do not taste on ourselves */
+ if (pp->geom->class == mp)
+ break;
+
+ taste_names = getenv("geom.sched.taste");
+ if (taste_names == NULL)
+ break;
+
+ l = strlen(pp->name);
+ for (s = taste_names; *s &&
+ (s = strstr(s, pp->name)); s++) {
+ /* further checks for an exact match */
+ if ( (s == taste_names || s[-1] == ' ') &&
+ (s[l] == '\0' || s[l] == ' ') )
+ break;
+ }
+ if (s == NULL)
+ break;
+ G_SCHED_DEBUG(0, "Attach device %s match [%s]\n",
+ pp->name, s);
+
+ /* look up the provider name in the list */
+ s = getenv("geom.sched.algo");
+ if (s == NULL)
+ s = "rr";
+
+ gsp = g_gsched_find(s); /* also get a reference */
+ if (gsp == NULL) {
+ G_SCHED_DEBUG(0, "Bad '%s' algorithm.", s);
+ break;
+ }
+
+ /* XXX create with 1 as last argument ? */
+ g_sched_create(NULL, mp, pp, gsp, 0);
+ g_gsched_unref(gsp);
+ } while (0);
+ return NULL;
+}
+
+static void
+g_sched_ctl_create(struct gctl_req *req, struct g_class *mp, int proxy)
+{
+ struct g_provider *pp;
+ struct g_gsched *gsp;
+ const char *name;
+ int i, nargs;
+
+ g_topology_assert();
+
+ name = gctl_get_asciiparam(req, "algo");
+ if (name == NULL) {
+ gctl_error(req, "No '%s' argument", "algo");
+ return;
+ }
+
+ gsp = g_gsched_find(name); /* also get a reference */
+ if (gsp == NULL) {
+ gctl_error(req, "Bad algorithm '%s'", name);
+ return;
+ }
+
+ nargs = g_sched_get_nargs(req);
+
+ /*
+ * Run on the arguments, and break on any error.
+ * We look for a device name, but skip the /dev/ prefix if any.
+ */
+ for (i = 0; i < nargs; i++) {
+ name = g_sched_argi(req, i);
+ if (name == NULL)
+ break;
+ pp = g_provider_by_name(name);
+ if (pp == NULL) {
+ G_SCHED_DEBUG(1, "Provider %s is invalid.", name);
+ gctl_error(req, "Provider %s is invalid.", name);
+ break;
+ }
+ if (g_sched_create(req, mp, pp, gsp, proxy) != 0)
+ break;
+ }
+
+ g_gsched_unref(gsp);
+}
+
+static void
+g_sched_ctl_configure(struct gctl_req *req, struct g_class *mp)
+{
+ struct g_provider *pp;
+ struct g_gsched *gsp;
+ const char *name;
+ int i, nargs;
+
+ g_topology_assert();
+
+ name = gctl_get_asciiparam(req, "algo");
+ if (name == NULL) {
+ gctl_error(req, "No '%s' argument", "algo");
+ return;
+ }
+
+ gsp = g_gsched_find(name); /* also get a reference */
+ if (gsp == NULL) {
+ gctl_error(req, "Bad algorithm '%s'", name);
+ return;
+ }
+
+ nargs = g_sched_get_nargs(req);
+
+ /*
+ * Run on the arguments, and break on any error.
+ * We look for a device name, but skip the /dev/ prefix if any.
+ */
+ for (i = 0; i < nargs; i++) {
+ name = g_sched_argi(req, i);
+ if (name == NULL)
+ break;
+ pp = g_provider_by_name(name);
+ if (pp == NULL || pp->geom->class != mp) {
+ G_SCHED_DEBUG(1, "Provider %s is invalid.", name);
+ gctl_error(req, "Provider %s is invalid.", name);
+ break;
+ }
+ if (g_sched_change_algo(req, mp, pp, gsp) != 0)
+ break;
+ }
+
+ g_gsched_unref(gsp);
+}
+
+static struct g_geom *
+g_sched_find_geom(struct g_class *mp, const char *name)
+{
+ struct g_geom *gp;
+
+ LIST_FOREACH(gp, &mp->geom, geom) {
+ if (strcmp(gp->name, name) == 0)
+ return (gp);
+ }
+ return (NULL);
+}
+
+static void
+g_sched_ctl_destroy(struct gctl_req *req, struct g_class *mp)
+{
+ int nargs, *force, error, i;
+ struct g_geom *gp;
+ const char *name;
+
+ g_topology_assert();
+
+ nargs = g_sched_get_nargs(req);
+
+ force = gctl_get_paraml(req, "force", sizeof(*force));
+ if (force == NULL) {
+ gctl_error(req, "No 'force' argument");
+ return;
+ }
+
+ for (i = 0; i < nargs; i++) {
+ name = g_sched_argi(req, i);
+ if (name == NULL)
+ break;
+
+ gp = g_sched_find_geom(mp, name);
+ if (gp == NULL) {
+ G_SCHED_DEBUG(1, "Device %s is invalid.", name);
+ gctl_error(req, "Device %s is invalid.", name);
+ break;
+ }
+
+ error = g_sched_destroy(gp, *force);
+ if (error != 0) {
+ gctl_error(req, "Cannot destroy device %s (error=%d).",
+ gp->name, error);
+ break;
+ }
+ }
+}
+
+static void
+g_sched_config(struct gctl_req *req, struct g_class *mp, const char *verb)
+{
+ uint32_t *version;
+
+ g_topology_assert();
+
+ version = gctl_get_paraml(req, "version", sizeof(*version));
+ if (version == NULL) {
+ gctl_error(req, "No '%s' argument.", "version");
+ return;
+ }
+
+ if (*version != G_SCHED_VERSION) {
+ gctl_error(req, "Userland and kernel parts are "
+ "out of sync.");
+ return;
+ }
+
+ if (strcmp(verb, "create") == 0) {
+ g_sched_ctl_create(req, mp, 0);
+ return;
+ } else if (strcmp(verb, "insert") == 0) {
+ g_sched_ctl_create(req, mp, 1);
+ return;
+ } else if (strcmp(verb, "configure") == 0) {
+ g_sched_ctl_configure(req, mp);
+ return;
+ } else if (strcmp(verb, "destroy") == 0) {
+ g_sched_ctl_destroy(req, mp);
+ return;
+ }
+
+ gctl_error(req, "Unknown verb.");
+}
+
+static void
+g_sched_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
+ struct g_consumer *cp, struct g_provider *pp)
+{
+ struct g_sched_softc *sc = gp->softc;
+ struct g_gsched *gsp = sc->sc_gsched;
+ if (indent == NULL) { /* plaintext */
+ sbuf_printf(sb, " algo %s", gsp ? gsp->gs_name : "--");
+ }
+ if (gsp->gs_dumpconf)
+ gsp->gs_dumpconf(sb, indent, gp, cp, pp);
+}
+
+DECLARE_GEOM_CLASS(g_sched_class, g_sched);
+MODULE_VERSION(geom_sched, 0);
diff --git a/sys/geom/sched/g_sched.h b/sys/geom/sched/g_sched.h
new file mode 100644
index 0000000..3a34e29
--- /dev/null
+++ b/sys/geom/sched/g_sched.h
@@ -0,0 +1,138 @@
+/*-
+ * Copyright (c) 2009-2010 Fabio Checconi
+ * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
+ * 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 AUTHORS 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 AUTHORS 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 _G_SCHED_H_
+#define _G_SCHED_H_
+
+/*
+ * $Id$
+ * $FreeBSD$
+ *
+ * Header for the geom_sched class (userland library and kernel part).
+ * See g_sched.c for documentation.
+ * The userland code only needs the three G_SCHED_* values below.
+ */
+
+#define G_SCHED_CLASS_NAME "SCHED"
+#define G_SCHED_VERSION 0
+#define G_SCHED_SUFFIX ".sched."
+
+#ifdef _KERNEL
+#define G_SCHED_DEBUG(lvl, ...) do { \
+ if (me.gs_debug >= (lvl)) { \
+ printf("GEOM_SCHED"); \
+ if (me.gs_debug > 0) \
+ printf("[%u]", lvl); \
+ printf(": "); \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
+ } \
+} while (0)
+
+#define G_SCHED_LOGREQ(bp, ...) do { \
+ if (me.gs_debug >= 2) { \
+ printf("GEOM_SCHED[2]: "); \
+ printf(__VA_ARGS__); \
+ printf(" "); \
+ g_print_bio(bp); \
+ printf("\n"); \
+ } \
+} while (0)
+
+LIST_HEAD(g_hash, g_sched_class);
+
+/*
+ * Descriptor of a scheduler.
+ * In addition to the obvious fields, sc_flushing and sc_pending
+ * support dynamic switching of scheduling algorithm.
+ * Normally, sc_flushing is 0, and requests that are scheduled are
+ * also added to the sc_pending queue, and removed when we receive
+ * the 'done' event.
+ *
+ * When we are transparently inserted on an existing provider,
+ * sc_proxying is set. The detach procedure is slightly different.
+ *
+ * When switching schedulers, sc_flushing is set so requests bypass us,
+ * and at the same time we update the pointer in the pending bios
+ * to ignore us when they return up.
+ * XXX it would be more efficient to implement sc_pending with
+ * a generation number: the softc generation is increased when
+ * we change scheduling algorithm, we store the current generation
+ * number in the pending bios, and when they come back we ignore
+ * the done() call if the generation number do not match.
+ */
+struct g_sched_softc {
+ /*
+ * Generic fields used by any scheduling algorithm:
+ * a mutex, the class descriptor, flags, list of pending
+ * requests (used when flushing the module) and support
+ * for hash tables where we store per-flow queues.
+ */
+ struct mtx sc_mtx;
+ struct g_gsched *sc_gsched; /* Scheduler descriptor. */
+ int sc_pending; /* Pending requests. */
+ int sc_flags; /* Various flags. */
+
+ /*
+ * Hash tables to store per-flow queues are generally useful
+ * so we handle them in the common code.
+ * sc_hash and sc_mask are parameters of the hash table,
+ * the last two fields are used to periodically remove
+ * expired items from the hash table.
+ */
+ struct g_hash *sc_hash;
+ u_long sc_mask;
+ int sc_flush_ticks; /* Next tick for a flush. */
+ int sc_flush_bucket; /* Next bucket to flush. */
+
+ /*
+ * Pointer to the algorithm's private data, which is the value
+ * returned by sc_gsched->gs_init() . A NULL here means failure.
+ * XXX intptr_t might be more appropriate.
+ */
+ void *sc_data;
+};
+
+#define G_SCHED_PROXYING 1
+#define G_SCHED_FLUSHING 2
+
+/*
+ * Temporary- our own version of the disksort, because the
+ * version in 7.x and 8.x before march 2009 is buggy.
+ */
+void gs_bioq_init(struct bio_queue_head *);
+void gs_bioq_remove(struct bio_queue_head *, struct bio *);
+void gs_bioq_flush(struct bio_queue_head *, struct devstat *, int);
+void gs_bioq_insert_head(struct bio_queue_head *, struct bio *);
+void gs_bioq_insert_tail(struct bio_queue_head *, struct bio *);
+struct bio *gs_bioq_first(struct bio_queue_head *);
+struct bio *gs_bioq_takefirst(struct bio_queue_head *);
+void gs_bioq_disksort(struct bio_queue_head *, struct bio *);
+
+#endif /* _KERNEL */
+
+#endif /* _G_SCHED_H_ */
diff --git a/sys/geom/sched/gs_rr.c b/sys/geom/sched/gs_rr.c
new file mode 100644
index 0000000..c4b1990
--- /dev/null
+++ b/sys/geom/sched/gs_rr.c
@@ -0,0 +1,686 @@
+/*-
+ * Copyright (c) 2009-2010 Fabio Checconi
+ * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * $Id$
+ * $FreeBSD$
+ *
+ * A round-robin (RR) anticipatory scheduler, with per-client queues.
+ *
+ * The goal of this implementation is to improve throughput compared
+ * to the pure elevator algorithm, and insure some fairness among
+ * clients.
+ *
+ * Requests coming from the same client are put in the same queue.
+ * We use anticipation to help reducing seeks, and each queue
+ * is never served continuously for more than a given amount of
+ * time or data. Queues are then served in a round-robin fashion.
+ *
+ * Each queue can be in any of the following states:
+ * READY immediately serve the first pending request;
+ * BUSY one request is under service, wait for completion;
+ * IDLING do not serve incoming requests immediately, unless
+ * they are "eligible" as defined later.
+ *
+ * Scheduling is made looking at the status of all queues,
+ * and the first one in round-robin order is privileged.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bio.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/sysctl.h>
+#include "gs_scheduler.h"
+
+/* possible states of the scheduler */
+enum g_rr_state {
+ G_QUEUE_READY = 0, /* Ready to dispatch. */
+ G_QUEUE_BUSY, /* Waiting for a completion. */
+ G_QUEUE_IDLING /* Waiting for a new request. */
+};
+
+/* possible queue flags */
+enum g_rr_flags {
+ G_FLAG_COMPLETED = 1, /* Completed a req. in the current budget. */
+};
+
+struct g_rr_softc;
+
+/*
+ * Queue descriptor, containing reference count, scheduling
+ * state, a queue of pending requests, configuration parameters.
+ * Queues with pending request(s) and not under service are also
+ * stored in a Round Robin (RR) list.
+ */
+struct g_rr_queue {
+ struct g_rr_softc *q_sc; /* link to the parent */
+
+ enum g_rr_state q_status;
+ unsigned int q_service; /* service received so far */
+ int q_slice_end; /* actual slice end in ticks */
+ enum g_rr_flags q_flags; /* queue flags */
+ struct bio_queue_head q_bioq;
+
+ /* Scheduling parameters */
+ unsigned int q_budget; /* slice size in bytes */
+ unsigned int q_slice_duration; /* slice size in ticks */
+ unsigned int q_wait_ticks; /* wait time for anticipation */
+
+ /* Stats to drive the various heuristics. */
+ struct g_savg q_thinktime; /* Thinktime average. */
+ struct g_savg q_seekdist; /* Seek distance average. */
+
+ int q_bionum; /* Number of requests. */
+
+ off_t q_lastoff; /* Last submitted req. offset. */
+ int q_lastsub; /* Last submitted req. time. */
+
+ /* Expiration deadline for an empty queue. */
+ int q_expire;
+
+ TAILQ_ENTRY(g_rr_queue) q_tailq; /* RR list link field */
+};
+
+/* List types. */
+TAILQ_HEAD(g_rr_tailq, g_rr_queue);
+
+/* list of scheduler instances */
+LIST_HEAD(g_scheds, g_rr_softc);
+
+/* Default quantum for RR between queues. */
+#define G_RR_DEFAULT_BUDGET 0x00800000
+
+/*
+ * Per device descriptor, holding the Round Robin list of queues
+ * accessing the disk, a reference to the geom, and the timer.
+ */
+struct g_rr_softc {
+ struct g_geom *sc_geom;
+
+ /*
+ * sc_active is the queue we are anticipating for.
+ * It is set only in gs_rr_next(), and possibly cleared
+ * only in gs_rr_next() or on a timeout.
+ * The active queue is never in the Round Robin list
+ * even if it has requests queued.
+ */
+ struct g_rr_queue *sc_active;
+ struct callout sc_wait; /* timer for sc_active */
+
+ struct g_rr_tailq sc_rr_tailq; /* the round-robin list */
+ int sc_nqueues; /* number of queues */
+
+ /* Statistics */
+ int sc_in_flight; /* requests in the driver */
+
+ LIST_ENTRY(g_rr_softc) sc_next;
+};
+
+/* Descriptor for bounded values, min and max are constant. */
+struct x_bound {
+ const int x_min;
+ int x_cur;
+ const int x_max;
+};
+
+/*
+ * parameters, config and stats
+ */
+struct g_rr_params {
+ int queues; /* total number of queues */
+ int w_anticipate; /* anticipate writes */
+ int bypass; /* bypass scheduling writes */
+
+ int units; /* how many instances */
+ /* sc_head is used for debugging */
+ struct g_scheds sc_head; /* first scheduler instance */
+
+ struct x_bound queue_depth; /* max parallel requests */
+ struct x_bound wait_ms; /* wait time, milliseconds */
+ struct x_bound quantum_ms; /* quantum size, milliseconds */
+ struct x_bound quantum_kb; /* quantum size, Kb (1024 bytes) */
+
+ /* statistics */
+ int wait_hit; /* success in anticipation */
+ int wait_miss; /* failure in anticipation */
+};
+
+/*
+ * Default parameters for the scheduler. The quantum sizes target
+ * a 80MB/s disk; if the hw is faster or slower the minimum of the
+ * two will have effect: the clients will still be isolated but
+ * the fairness may be limited. A complete solution would involve
+ * the on-line measurement of the actual disk throughput to derive
+ * these parameters. Or we may just choose to ignore service domain
+ * fairness and accept what can be achieved with time-only budgets.
+ */
+static struct g_rr_params me = {
+ .sc_head = LIST_HEAD_INITIALIZER(&me.sc_head),
+ .w_anticipate = 1,
+ .queue_depth = { 1, 1, 50 },
+ .wait_ms = { 1, 10, 30 },
+ .quantum_ms = { 1, 100, 500 },
+ .quantum_kb = { 16, 8192, 65536 },
+};
+
+struct g_rr_params *gs_rr_me = &me;
+
+SYSCTL_DECL(_kern_geom_sched);
+SYSCTL_NODE(_kern_geom_sched, OID_AUTO, rr, CTLFLAG_RW, 0,
+ "GEOM_SCHED ROUND ROBIN stuff");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, units, CTLFLAG_RD,
+ &me.units, 0, "Scheduler instances");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, queues, CTLFLAG_RD,
+ &me.queues, 0, "Total rr queues");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, wait_ms, CTLFLAG_RW,
+ &me.wait_ms.x_cur, 0, "Wait time milliseconds");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, quantum_ms, CTLFLAG_RW,
+ &me.quantum_ms.x_cur, 0, "Quantum size milliseconds");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, bypass, CTLFLAG_RW,
+ &me.bypass, 0, "Bypass scheduler");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, w_anticipate, CTLFLAG_RW,
+ &me.w_anticipate, 0, "Do anticipation on writes");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, quantum_kb, CTLFLAG_RW,
+ &me.quantum_kb.x_cur, 0, "Quantum size Kbytes");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, queue_depth, CTLFLAG_RW,
+ &me.queue_depth.x_cur, 0, "Maximum simultaneous requests");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, wait_hit, CTLFLAG_RW,
+ &me.wait_hit, 0, "Hits in anticipation");
+SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, wait_miss, CTLFLAG_RW,
+ &me.wait_miss, 0, "Misses in anticipation");
+
+#ifdef DEBUG_QUEUES
+/* print the status of a queue */
+static void
+gs_rr_dump_q(struct g_rr_queue *qp, int index)
+{
+ int l = 0;
+ struct bio *bp;
+
+ TAILQ_FOREACH(bp, &(qp->q_bioq.queue), bio_queue) {
+ l++;
+ }
+ printf("--- rr queue %d %p status %d len %d ---\n",
+ index, qp, qp->q_status, l);
+}
+
+/*
+ * Dump the scheduler status when writing to this sysctl variable.
+ * XXX right now we only dump the status of the last instance created.
+ * not a severe issue because this is only for debugging
+ */
+static int
+gs_rr_sysctl_status(SYSCTL_HANDLER_ARGS)
+{
+ int error, val = 0;
+ struct g_rr_softc *sc;
+
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error || !req->newptr )
+ return (error);
+
+ printf("called %s\n", __FUNCTION__);
+
+ LIST_FOREACH(sc, &me.sc_head, sc_next) {
+ int i, tot = 0;
+ printf("--- sc %p active %p nqueues %d "
+ "callout %d in_flight %d ---\n",
+ sc, sc->sc_active, sc->sc_nqueues,
+ callout_active(&sc->sc_wait),
+ sc->sc_in_flight);
+ for (i = 0; i < G_RR_HASH_SIZE; i++) {
+ struct g_rr_queue *qp;
+ LIST_FOREACH(qp, &sc->sc_hash[i], q_hash) {
+ gs_rr_dump_q(qp, tot);
+ tot++;
+ }
+ }
+ }
+ return (0);
+}
+
+SYSCTL_PROC(_kern_geom_sched_rr, OID_AUTO, status,
+ CTLTYPE_UINT | CTLFLAG_RW,
+ 0, sizeof(int), gs_rr_sysctl_status, "I", "status");
+
+#endif /* DEBUG_QUEUES */
+
+/*
+ * Get a bounded value, optionally convert to a min of t_min ticks.
+ */
+static int
+get_bounded(struct x_bound *v, int t_min)
+{
+ int x;
+
+ x = v->x_cur;
+ if (x < v->x_min)
+ x = v->x_min;
+ else if (x > v->x_max)
+ x = v->x_max;
+ if (t_min) {
+ x = x * hz / 1000; /* convert to ticks */
+ if (x < t_min)
+ x = t_min;
+ }
+ return x;
+}
+
+/*
+ * Get a reference to the queue for bp, using the generic
+ * classification mechanism.
+ */
+static struct g_rr_queue *
+g_rr_queue_get(struct g_rr_softc *sc, struct bio *bp)
+{
+
+ return (g_sched_get_class(sc->sc_geom, bp));
+}
+
+static int
+g_rr_init_class(void *data, void *priv)
+{
+ struct g_rr_softc *sc = data;
+ struct g_rr_queue *qp = priv;
+
+ gs_bioq_init(&qp->q_bioq);
+
+ /*
+ * Set the initial parameters for the client:
+ * slice size in bytes and ticks, and wait ticks.
+ * Right now these are constant, but we could have
+ * autoconfiguration code to adjust the values based on
+ * the actual workload.
+ */
+ qp->q_budget = 1024 * get_bounded(&me.quantum_kb, 0);
+ qp->q_slice_duration = get_bounded(&me.quantum_ms, 2);
+ qp->q_wait_ticks = get_bounded(&me.wait_ms, 2);
+
+ qp->q_sc = sc; /* link to the parent */
+ qp->q_sc->sc_nqueues++;
+ me.queues++;
+
+ return (0);
+}
+
+/*
+ * Release a reference to the queue.
+ */
+static void
+g_rr_queue_put(struct g_rr_queue *qp)
+{
+
+ g_sched_put_class(qp->q_sc->sc_geom, qp);
+}
+
+static void
+g_rr_fini_class(void *data, void *priv)
+{
+ struct g_rr_queue *qp = priv;
+
+ KASSERT(gs_bioq_first(&qp->q_bioq) == NULL,
+ ("released nonempty queue"));
+ qp->q_sc->sc_nqueues--;
+ me.queues--;
+}
+
+static inline int
+g_rr_queue_expired(struct g_rr_queue *qp)
+{
+
+ if (qp->q_service >= qp->q_budget)
+ return (1);
+
+ if ((qp->q_flags & G_FLAG_COMPLETED) &&
+ ticks - qp->q_slice_end >= 0)
+ return (1);
+
+ return (0);
+}
+
+static inline int
+g_rr_should_anticipate(struct g_rr_queue *qp, struct bio *bp)
+{
+ int wait = get_bounded(&me.wait_ms, 2);
+
+ if (!me.w_anticipate && (bp->bio_cmd & BIO_WRITE))
+ return (0);
+
+ if (g_savg_valid(&qp->q_thinktime) &&
+ g_savg_read(&qp->q_thinktime) > wait)
+ return (0);
+
+ if (g_savg_valid(&qp->q_seekdist) &&
+ g_savg_read(&qp->q_seekdist) > 8192)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Called on a request arrival, timeout or completion.
+ * Try to serve a request among those queued.
+ */
+static struct bio *
+g_rr_next(void *data, int force)
+{
+ struct g_rr_softc *sc = data;
+ struct g_rr_queue *qp;
+ struct bio *bp, *next;
+ int expired;
+
+ qp = sc->sc_active;
+ if (me.bypass == 0 && !force) {
+ if (sc->sc_in_flight >= get_bounded(&me.queue_depth, 0))
+ return (NULL);
+
+ /* Try with the queue under service first. */
+ if (qp != NULL && qp->q_status != G_QUEUE_READY) {
+ /*
+ * Queue is anticipating, ignore request.
+ * We should check that we are not past
+ * the timeout, but in that case the timeout
+ * will fire immediately afterwards so we
+ * don't bother.
+ */
+ return (NULL);
+ }
+ } else if (qp != NULL && qp->q_status != G_QUEUE_READY) {
+ g_rr_queue_put(qp);
+ sc->sc_active = qp = NULL;
+ }
+
+ /*
+ * No queue under service, look for the first in RR order.
+ * If we find it, select if as sc_active, clear service
+ * and record the end time of the slice.
+ */
+ if (qp == NULL) {
+ qp = TAILQ_FIRST(&sc->sc_rr_tailq);
+ if (qp == NULL)
+ return (NULL); /* no queues at all, return */
+ /* otherwise select the new queue for service. */
+ TAILQ_REMOVE(&sc->sc_rr_tailq, qp, q_tailq);
+ sc->sc_active = qp;
+ qp->q_service = 0;
+ qp->q_flags &= ~G_FLAG_COMPLETED;
+ }
+
+ bp = gs_bioq_takefirst(&qp->q_bioq); /* surely not NULL */
+ qp->q_service += bp->bio_length; /* charge the service */
+
+ /*
+ * The request at the head of the active queue is always
+ * dispatched, and gs_rr_next() will be called again
+ * immediately.
+ * We need to prepare for what to do next:
+ *
+ * 1. have we reached the end of the (time or service) slice ?
+ * If so, clear sc_active and possibly requeue the previous
+ * active queue if it has more requests pending;
+ * 2. do we have more requests in sc_active ?
+ * If yes, do not anticipate, as gs_rr_next() will run again;
+ * if no, decide whether or not to anticipate depending
+ * on read or writes (e.g., anticipate only on reads).
+ */
+ expired = g_rr_queue_expired(qp); /* are we expired ? */
+ next = gs_bioq_first(&qp->q_bioq); /* do we have one more ? */
+ if (expired) {
+ sc->sc_active = NULL;
+ /* Either requeue or release reference. */
+ if (next != NULL)
+ TAILQ_INSERT_TAIL(&sc->sc_rr_tailq, qp, q_tailq);
+ else
+ g_rr_queue_put(qp);
+ } else if (next != NULL) {
+ qp->q_status = G_QUEUE_READY;
+ } else {
+ if (!force && g_rr_should_anticipate(qp, bp)) {
+ /* anticipate */
+ qp->q_status = G_QUEUE_BUSY;
+ } else {
+ /* do not anticipate, release reference */
+ g_rr_queue_put(qp);
+ sc->sc_active = NULL;
+ }
+ }
+ /* If sc_active != NULL, its q_status is always correct. */
+
+ sc->sc_in_flight++;
+
+ return (bp);
+}
+
+static inline void
+g_rr_update_thinktime(struct g_rr_queue *qp)
+{
+ int delta = ticks - qp->q_lastsub, wait = get_bounded(&me.wait_ms, 2);
+
+ if (qp->q_sc->sc_active != qp)
+ return;
+
+ qp->q_lastsub = ticks;
+ delta = (delta > 2 * wait) ? 2 * wait : delta;
+ if (qp->q_bionum > 7)
+ g_savg_add_sample(&qp->q_thinktime, delta);
+}
+
+static inline void
+g_rr_update_seekdist(struct g_rr_queue *qp, struct bio *bp)
+{
+ off_t dist;
+
+ if (qp->q_lastoff > bp->bio_offset)
+ dist = qp->q_lastoff - bp->bio_offset;
+ else
+ dist = bp->bio_offset - qp->q_lastoff;
+
+ if (dist > (8192 * 8))
+ dist = 8192 * 8;
+
+ qp->q_lastoff = bp->bio_offset + bp->bio_length;
+
+ if (qp->q_bionum > 7)
+ g_savg_add_sample(&qp->q_seekdist, dist);
+}
+
+/*
+ * Called when a real request for disk I/O arrives.
+ * Locate the queue associated with the client.
+ * If the queue is the one we are anticipating for, reset its timeout;
+ * if the queue is not in the round robin list, insert it in the list.
+ * On any error, do not queue the request and return -1, the caller
+ * will take care of this request.
+ */
+static int
+g_rr_start(void *data, struct bio *bp)
+{
+ struct g_rr_softc *sc = data;
+ struct g_rr_queue *qp;
+
+ if (me.bypass)
+ return (-1); /* bypass the scheduler */
+
+ /* Get the queue for the request. */
+ qp = g_rr_queue_get(sc, bp);
+ if (qp == NULL)
+ return (-1); /* allocation failed, tell upstream */
+
+ if (gs_bioq_first(&qp->q_bioq) == NULL) {
+ /*
+ * We are inserting into an empty queue.
+ * Reset its state if it is sc_active,
+ * otherwise insert it in the RR list.
+ */
+ if (qp == sc->sc_active) {
+ qp->q_status = G_QUEUE_READY;
+ callout_stop(&sc->sc_wait);
+ } else {
+ g_sched_priv_ref(qp);
+ TAILQ_INSERT_TAIL(&sc->sc_rr_tailq, qp, q_tailq);
+ }
+ }
+
+ qp->q_bionum = 1 + qp->q_bionum - (qp->q_bionum >> 3);
+
+ g_rr_update_thinktime(qp);
+ g_rr_update_seekdist(qp, bp);
+
+ /* Inherit the reference returned by g_rr_queue_get(). */
+ bp->bio_caller1 = qp;
+ gs_bioq_disksort(&qp->q_bioq, bp);
+
+ return (0);
+}
+
+/*
+ * Callout executed when a queue times out anticipating a new request.
+ */
+static void
+g_rr_wait_timeout(void *data)
+{
+ struct g_rr_softc *sc = data;
+ struct g_geom *geom = sc->sc_geom;
+
+ g_sched_lock(geom);
+ /*
+ * We can race with other events, so check if
+ * sc_active is still valid.
+ */
+ if (sc->sc_active != NULL) {
+ /* Release the reference to the queue. */
+ g_rr_queue_put(sc->sc_active);
+ sc->sc_active = NULL;
+ me.wait_hit--;
+ me.wait_miss++; /* record the miss */
+ }
+ g_sched_dispatch(geom);
+ g_sched_unlock(geom);
+}
+
+/*
+ * Module glue: allocate descriptor, initialize its fields.
+ */
+static void *
+g_rr_init(struct g_geom *geom)
+{
+ struct g_rr_softc *sc;
+
+ /* XXX check whether we can sleep */
+ sc = malloc(sizeof *sc, M_GEOM_SCHED, M_NOWAIT | M_ZERO);
+ sc->sc_geom = geom;
+ TAILQ_INIT(&sc->sc_rr_tailq);
+ callout_init(&sc->sc_wait, CALLOUT_MPSAFE);
+ LIST_INSERT_HEAD(&me.sc_head, sc, sc_next);
+ me.units++;
+
+ return (sc);
+}
+
+/*
+ * Module glue -- drain the callout structure, destroy the
+ * hash table and its element, and free the descriptor.
+ */
+static void
+g_rr_fini(void *data)
+{
+ struct g_rr_softc *sc = data;
+
+ callout_drain(&sc->sc_wait);
+ KASSERT(sc->sc_active == NULL, ("still a queue under service"));
+ KASSERT(TAILQ_EMPTY(&sc->sc_rr_tailq), ("still scheduled queues"));
+
+ LIST_REMOVE(sc, sc_next);
+ me.units--;
+ free(sc, M_GEOM_SCHED);
+}
+
+/*
+ * Called when the request under service terminates.
+ * Start the anticipation timer if needed.
+ */
+static void
+g_rr_done(void *data, struct bio *bp)
+{
+ struct g_rr_softc *sc = data;
+ struct g_rr_queue *qp;
+
+ sc->sc_in_flight--;
+
+ qp = bp->bio_caller1;
+ if (qp == sc->sc_active && qp->q_status == G_QUEUE_BUSY) {
+ if (!(qp->q_flags & G_FLAG_COMPLETED)) {
+ qp->q_flags |= G_FLAG_COMPLETED;
+ /* in case we want to make the slice adaptive */
+ qp->q_slice_duration = get_bounded(&me.quantum_ms, 2);
+ qp->q_slice_end = ticks + qp->q_slice_duration;
+ }
+
+ /* The queue is trying anticipation, start the timer. */
+ qp->q_status = G_QUEUE_IDLING;
+ /* may make this adaptive */
+ qp->q_wait_ticks = get_bounded(&me.wait_ms, 2);
+ me.wait_hit++;
+ callout_reset(&sc->sc_wait, qp->q_wait_ticks,
+ g_rr_wait_timeout, sc);
+ } else
+ g_sched_dispatch(sc->sc_geom);
+
+ /* Release a reference to the queue. */
+ g_rr_queue_put(qp);
+}
+
+static void
+g_rr_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
+ struct g_consumer *cp, struct g_provider *pp)
+{
+ if (indent == NULL) { /* plaintext */
+ sbuf_printf(sb, " units %d queues %d",
+ me.units, me.queues);
+ }
+}
+
+static struct g_gsched g_rr = {
+ .gs_name = "rr",
+ .gs_priv_size = sizeof(struct g_rr_queue),
+ .gs_init = g_rr_init,
+ .gs_fini = g_rr_fini,
+ .gs_start = g_rr_start,
+ .gs_done = g_rr_done,
+ .gs_next = g_rr_next,
+ .gs_dumpconf = g_rr_dumpconf,
+ .gs_init_class = g_rr_init_class,
+ .gs_fini_class = g_rr_fini_class,
+};
+
+DECLARE_GSCHED_MODULE(rr, &g_rr);
diff --git a/sys/geom/sched/gs_scheduler.h b/sys/geom/sched/gs_scheduler.h
new file mode 100644
index 0000000..31e47e6
--- /dev/null
+++ b/sys/geom/sched/gs_scheduler.h
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 2009-2010 Fabio Checconi
+ * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
+ * 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 AUTHORS 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 AUTHORS 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.
+ */
+
+/*
+ * $Id$
+ * $FreeBSD$
+ *
+ * Prototypes for GEOM-based disk scheduling algorithms.
+ * See g_sched.c for generic documentation.
+ *
+ * This file is used by the kernel modules implementing the various
+ * scheduling algorithms. They should provide all the methods
+ * defined in struct g_gsched, and also invoke the macro
+ * DECLARE_GSCHED_MODULE
+ * which registers the scheduling algorithm with the geom_sched module.
+ *
+ * The various scheduling algorithms do not need to know anything
+ * about geom, they only need to handle the 'bio' requests they
+ * receive, pass them down when needed, and use the locking interface
+ * defined below.
+ */
+
+#ifndef _G_GSCHED_H_
+#define _G_GSCHED_H_
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/queue.h>
+#include <geom/geom.h>
+#include "g_sched.h"
+
+/*
+ * This is the interface exported to scheduling modules.
+ *
+ * gs_init() is called when our scheduling algorithm
+ * starts being used by a geom 'sched'
+ *
+ * gs_fini() is called when the algorithm is released.
+ *
+ * gs_start() is called when a new request comes in. It should
+ * enqueue the request and return 0 if success, or return non-zero
+ * in case of failure (meaning the request is passed down).
+ * The scheduler can use bio->bio_caller1 to store a non-null
+ * pointer meaning the request is under its control.
+ *
+ * gs_next() is called in a loop by g_sched_dispatch(), right after
+ * gs_start(), or on timeouts or 'done' events. It should return
+ * immediately, either a pointer to the bio to be served or NULL
+ * if no bio should be served now. If force is specified, a
+ * work-conserving behavior is expected.
+ *
+ * gs_done() is called when a request under service completes.
+ * In turn the scheduler may decide to call the dispatch loop
+ * to serve other pending requests (or make sure there is a pending
+ * timeout to avoid stalls).
+ *
+ * gs_init_class() is called when a new client (as determined by
+ * the classifier) starts being used.
+ *
+ * gs_hash_unref() is called right before the class hashtable is
+ * destroyed; after this call, the scheduler is supposed to hold no
+ * more references to the elements in the table.
+ */
+
+/* Forward declarations for prototypes. */
+struct g_geom;
+struct g_sched_class;
+
+typedef void *gs_init_t (struct g_geom *geom);
+typedef void gs_fini_t (void *data);
+typedef int gs_start_t (void *data, struct bio *bio);
+typedef void gs_done_t (void *data, struct bio *bio);
+typedef struct bio *gs_next_t (void *data, int force);
+typedef int gs_init_class_t (void *data, void *priv);
+typedef void gs_fini_class_t (void *data, void *priv);
+typedef void gs_hash_unref_t (void *data);
+
+struct g_gsched {
+ const char *gs_name;
+ int gs_refs;
+ int gs_priv_size;
+
+ gs_init_t *gs_init;
+ gs_fini_t *gs_fini;
+ gs_start_t *gs_start;
+ gs_done_t *gs_done;
+ gs_next_t *gs_next;
+ g_dumpconf_t *gs_dumpconf;
+
+ gs_init_class_t *gs_init_class;
+ gs_fini_class_t *gs_fini_class;
+ gs_hash_unref_t *gs_hash_unref;
+
+ LIST_ENTRY(g_gsched) glist;
+};
+
+#define KTR_GSCHED KTR_SPARE4
+
+MALLOC_DECLARE(M_GEOM_SCHED);
+
+/*
+ * Basic classification mechanism. Each request is associated to
+ * a g_sched_class, and each scheduler has the opportunity to set
+ * its own private data for the given (class, geom) pair. The
+ * private data have a base type of g_sched_private, and are
+ * extended at the end with the actual private fields of each
+ * scheduler.
+ */
+struct g_sched_class {
+ int gsc_refs;
+ int gsc_expire;
+ u_long gsc_key;
+ LIST_ENTRY(g_sched_class) gsc_clist;
+
+ void *gsc_priv[0];
+};
+
+/*
+ * Manipulate the classifier's data. g_sched_get_class() gets a reference
+ * to the the class corresponding to bp in gp, allocating and initializing
+ * it if necessary. g_sched_put_class() releases the reference.
+ * The returned value points to the private data for the class.
+ */
+void *g_sched_get_class(struct g_geom *gp, struct bio *bp);
+void g_sched_put_class(struct g_geom *gp, void *priv);
+
+static inline struct g_sched_class *
+g_sched_priv2class(void *priv)
+{
+
+ return ((struct g_sched_class *)((u_long)priv -
+ offsetof(struct g_sched_class, gsc_priv)));
+}
+
+static inline void
+g_sched_priv_ref(void *priv)
+{
+ struct g_sched_class *gsc;
+
+ gsc = g_sched_priv2class(priv);
+ gsc->gsc_refs++;
+}
+
+/*
+ * Locking interface. When each operation registered with the
+ * scheduler is invoked, a per-instance lock is taken to protect
+ * the data associated with it. If the scheduler needs something
+ * else to access the same data (e.g., a callout) it must use
+ * these functions.
+ */
+void g_sched_lock(struct g_geom *gp);
+void g_sched_unlock(struct g_geom *gp);
+
+/*
+ * Restart request dispatching. Must be called with the per-instance
+ * mutex held.
+ */
+void g_sched_dispatch(struct g_geom *geom);
+
+/*
+ * Simple gathering of statistical data, used by schedulers to collect
+ * info on process history. Just keep an exponential average of the
+ * samples, with some extra bits of precision.
+ */
+struct g_savg {
+ uint64_t gs_avg;
+ unsigned int gs_smpl;
+};
+
+static inline void
+g_savg_add_sample(struct g_savg *ss, uint64_t sample)
+{
+
+ /* EMA with alpha = 0.125, fixed point, 3 bits of precision. */
+ ss->gs_avg = sample + ss->gs_avg - (ss->gs_avg >> 3);
+ ss->gs_smpl = 1 + ss->gs_smpl - (ss->gs_smpl >> 3);
+}
+
+static inline int
+g_savg_valid(struct g_savg *ss)
+{
+
+ /* We want at least 8 samples to deem an average as valid. */
+ return (ss->gs_smpl > 7);
+}
+
+static inline uint64_t
+g_savg_read(struct g_savg *ss)
+{
+
+ return (ss->gs_avg / ss->gs_smpl);
+}
+
+/*
+ * Declaration of a scheduler module.
+ */
+int g_gsched_modevent(module_t mod, int cmd, void *arg);
+
+#define DECLARE_GSCHED_MODULE(name, gsched) \
+ static moduledata_t name##_mod = { \
+ #name, \
+ g_gsched_modevent, \
+ gsched, \
+ }; \
+ DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); \
+ MODULE_DEPEND(name, geom_sched, 0, 0, 0);
+
+#endif /* _KERNEL */
+
+#endif /* _G_GSCHED_H_ */
diff --git a/sys/geom/sched/subr_disk.c b/sys/geom/sched/subr_disk.c
new file mode 100644
index 0000000..008eaab
--- /dev/null
+++ b/sys/geom/sched/subr_disk.c
@@ -0,0 +1,209 @@
+/*-
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * The bioq_disksort() (and the specification of the bioq API)
+ * have been written by Luigi Rizzo and Fabio Checconi under the same
+ * license as above.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+//#include "opt_geom.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/conf.h>
+#include <sys/disk.h>
+#include <geom/geom_disk.h>
+#include "g_sched.h"
+
+/*
+ * BIO queue implementation
+ *
+ * Please read carefully the description below before making any change
+ * to the code, or you might change the behaviour of the data structure
+ * in undesirable ways.
+ *
+ * A bioq stores disk I/O request (bio), normally sorted according to
+ * the distance of the requested position (bio->bio_offset) from the
+ * current head position (bioq->last_offset) in the scan direction, i.e.
+ *
+ * (uoff_t)(bio_offset - last_offset)
+ *
+ * Note that the cast to unsigned (uoff_t) is fundamental to insure
+ * that the distance is computed in the scan direction.
+ *
+ * The main methods for manipulating the bioq are:
+ *
+ * bioq_disksort() performs an ordered insertion;
+ *
+ * bioq_first() return the head of the queue, without removing;
+ *
+ * bioq_takefirst() return and remove the head of the queue,
+ * updating the 'current head position' as
+ * bioq->last_offset = bio->bio_offset + bio->bio_length;
+ *
+ * When updating the 'current head position', we assume that the result of
+ * bioq_takefirst() is dispatched to the device, so bioq->last_offset
+ * represents the head position once the request is complete.
+ *
+ * If the bioq is manipulated using only the above calls, it starts
+ * with a sorted sequence of requests with bio_offset >= last_offset,
+ * possibly followed by another sorted sequence of requests with
+ * 0 <= bio_offset < bioq->last_offset
+ *
+ * NOTE: historical behaviour was to ignore bio->bio_length in the
+ * update, but its use tracks the head position in a better way.
+ * Historical behaviour was also to update the head position when
+ * the request under service is complete, rather than when the
+ * request is extracted from the queue. However, the current API
+ * has no method to update the head position; secondly, once
+ * a request has been submitted to the disk, we have no idea of
+ * the actual head position, so the final one is our best guess.
+ *
+ * --- Direct queue manipulation ---
+ *
+ * A bioq uses an underlying TAILQ to store requests, so we also
+ * export methods to manipulate the TAILQ, in particular:
+ *
+ * bioq_insert_tail() insert an entry at the end.
+ * It also creates a 'barrier' so all subsequent
+ * insertions through bioq_disksort() will end up
+ * after this entry;
+ *
+ * bioq_insert_head() insert an entry at the head, update
+ * bioq->last_offset = bio->bio_offset so that
+ * all subsequent insertions through bioq_disksort()
+ * will end up after this entry;
+ *
+ * bioq_remove() remove a generic element from the queue, act as
+ * bioq_takefirst() if invoked on the head of the queue.
+ *
+ * The semantic of these methods is the same of the operations
+ * on the underlying TAILQ, but with additional guarantees on
+ * subsequent bioq_disksort() calls. E.g. bioq_insert_tail()
+ * can be useful for making sure that all previous ops are flushed
+ * to disk before continuing.
+ *
+ * Updating bioq->last_offset on a bioq_insert_head() guarantees
+ * that the bio inserted with the last bioq_insert_head() will stay
+ * at the head of the queue even after subsequent bioq_disksort().
+ *
+ * Note that when the direct queue manipulation functions are used,
+ * the queue may contain multiple inversion points (i.e. more than
+ * two sorted sequences of requests).
+ *
+ */
+
+void
+gs_bioq_init(struct bio_queue_head *head)
+{
+
+ TAILQ_INIT(&head->queue);
+ head->last_offset = 0;
+ head->insert_point = NULL;
+}
+
+void
+gs_bioq_remove(struct bio_queue_head *head, struct bio *bp)
+{
+
+ if (bp == TAILQ_FIRST(&head->queue))
+ head->last_offset = bp->bio_offset + bp->bio_length;
+
+ if (bp == head->insert_point)
+ head->insert_point = NULL;
+
+ TAILQ_REMOVE(&head->queue, bp, bio_queue);
+}
+
+void
+gs_bioq_flush(struct bio_queue_head *head, struct devstat *stp, int error)
+{
+ struct bio *bp;
+
+ while ((bp = gs_bioq_takefirst(head)) != NULL)
+ biofinish(bp, stp, error);
+}
+
+void
+gs_bioq_insert_head(struct bio_queue_head *head, struct bio *bp)
+{
+
+ head->last_offset = bp->bio_offset;
+ TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
+}
+
+void
+gs_bioq_insert_tail(struct bio_queue_head *head, struct bio *bp)
+{
+
+ TAILQ_INSERT_TAIL(&head->queue, bp, bio_queue);
+ head->insert_point = bp;
+}
+
+struct bio *
+gs_bioq_first(struct bio_queue_head *head)
+{
+
+ return (TAILQ_FIRST(&head->queue));
+}
+
+struct bio *
+gs_bioq_takefirst(struct bio_queue_head *head)
+{
+ struct bio *bp;
+
+ bp = TAILQ_FIRST(&head->queue);
+ if (bp != NULL)
+ gs_bioq_remove(head, bp);
+ return (bp);
+}
+
+/*
+ * Compute the sorting key. The cast to unsigned is
+ * fundamental for correctness, see the description
+ * near the beginning of the file.
+ */
+static inline uoff_t
+gs_bioq_bio_key(struct bio_queue_head *head, struct bio *bp)
+{
+
+ return ((uoff_t)(bp->bio_offset - head->last_offset));
+}
+
+/*
+ * Seek sort for disks.
+ *
+ * Sort all requests in a single queue while keeping
+ * track of the current position of the disk with last_offset.
+ * See above for details.
+ */
+void
+gs_bioq_disksort(struct bio_queue_head *head, struct bio *bp)
+{
+ struct bio *cur, *prev = NULL;
+ uoff_t key = gs_bioq_bio_key(head, bp);
+
+ cur = TAILQ_FIRST(&head->queue);
+
+ if (head->insert_point)
+ cur = head->insert_point;
+
+ while (cur != NULL && key >= gs_bioq_bio_key(head, cur)) {
+ prev = cur;
+ cur = TAILQ_NEXT(cur, bio_queue);
+ }
+
+ if (prev == NULL)
+ TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
+ else
+ TAILQ_INSERT_AFTER(&head->queue, prev, bp, bio_queue);
+}
diff --git a/sys/geom/vinum/geom_vinum.c b/sys/geom/vinum/geom_vinum.c
index b921a1b..479fc8a 100644
--- a/sys/geom/vinum/geom_vinum.c
+++ b/sys/geom/vinum/geom_vinum.c
@@ -788,7 +788,15 @@ gv_worker(void *arg)
"completely accessible", p->name);
break;
}
+ if (p->flags & GV_PLEX_SYNCING ||
+ p->flags & GV_PLEX_REBUILDING ||
+ p->flags & GV_PLEX_GROWING) {
+ G_VINUM_DEBUG(0, "plex %s is busy with "
+ "syncing or parity build", p->name);
+ break;
+ }
p->synced = 0;
+ p->flags |= GV_PLEX_REBUILDING;
g_topology_assert_not();
g_topology_lock();
err = gv_access(p->vol_sc->provider, 1, 1, 0);
@@ -811,6 +819,13 @@ gv_worker(void *arg)
"completely accessible", p->name);
break;
}
+ if (p->flags & GV_PLEX_SYNCING ||
+ p->flags & GV_PLEX_REBUILDING ||
+ p->flags & GV_PLEX_GROWING) {
+ G_VINUM_DEBUG(0, "plex %s is busy with "
+ "syncing or parity build", p->name);
+ break;
+ }
p->synced = 0;
g_topology_assert_not();
g_topology_lock();
diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c
index ae23178..7ea57d9 100644
--- a/sys/i386/acpica/acpi_machdep.c
+++ b/sys/i386/acpica/acpi_machdep.c
@@ -641,8 +641,10 @@ map_table(vm_paddr_t pa, int offset, const char *sig)
if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
if (bootverbose)
printf("ACPI: Failed checksum for table %s\n", sig);
+#if (ACPI_CHECKSUM_ABORT)
table_unmap(table, length);
return (NULL);
+#endif
}
return (table);
}
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 730dcc9..24f5aab 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -46,7 +46,6 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
options COMPAT_FREEBSD4 # Compatible with FreeBSD4
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options COMPAT_FREEBSD6 # Compatible with FreeBSD6
@@ -236,6 +235,7 @@ device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le')
device re # RealTek 8139C+/8169/8169S/8110S
device rl # RealTek 8129/8139
device sf # Adaptec AIC-6915 (``Starfire'')
+device sge # Silicon Integrated Systems SiS190/191
device sis # Silicon Integrated Systems SiS 900/SiS 7016
device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet
device ste # Sundance ST201 (D-Link DFE-550TX)
@@ -294,6 +294,7 @@ device firmware # firmware assist module
device bpf # Berkeley packet filter
# USB support
+options USB_DEBUG # enable debug msgs
device uhci # UHCI PCI->USB interface
device ohci # OHCI PCI->USB interface
device ehci # EHCI PCI->USB interface (USB 2.0)
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index af3da83..cc62ed9 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -862,6 +862,15 @@ options PMAP_SHPGPERPROC=201
#
options KVA_PAGES=260
+#
+# Number of initial kernel page table pages used for early bootstrap.
+# This number should include enough pages to map the kernel, any
+# modules or other data loaded with the kernel by the loader, and data
+# structures allocated before the VM system is initialized such as the
+# vm_page_t array. Each page table page maps 4MB (2MB with PAE).
+#
+options NKPT=31
+
#####################################################################
# ABI Emulation
diff --git a/sys/i386/conf/XBOX b/sys/i386/conf/XBOX
index 9671965..2ba5738 100644
--- a/sys/i386/conf/XBOX
+++ b/sys/i386/conf/XBOX
@@ -82,6 +82,7 @@ device pty # BSD-style compatibility pseudo ttys
device bpf # Berkeley packet filter
# USB support
+options USB_DEBUG # enable debug msgs
#device uhci # UHCI PCI->USB interface
device ohci # OHCI PCI->USB interface
device usb # USB Bus (required)
diff --git a/sys/i386/conf/XEN b/sys/i386/conf/XEN
index ed07b0d..352c1ab 100644
--- a/sys/i386/conf/XEN
+++ b/sys/i386/conf/XEN
@@ -31,7 +31,6 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
options COMPAT_FREEBSD4 # Compatible with FreeBSD4
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options COMPAT_FREEBSD6 # Compatible with FreeBSD6
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index d4dd90b..c4c5b01 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -110,6 +110,19 @@ IDTVEC(timerint)
MEXITCOUNT
jmp doreti
+/*
+ * Local APIC error interrupt handler.
+ */
+ .text
+ SUPERALIGN_TEXT
+IDTVEC(errorint)
+ PUSH_FRAME
+ SET_KERNEL_SREGS
+ FAKE_MCOUNT(TF_EIP(%esp))
+ call lapic_handle_error
+ MEXITCOUNT
+ jmp doreti
+
#ifdef SMP
/*
* Global address space TLB shootdown.
diff --git a/sys/i386/i386/bpf_jit_machdep.c b/sys/i386/i386/bpf_jit_machdep.c
index e9d9eca..4c2946f 100644
--- a/sys/i386/i386/bpf_jit_machdep.c
+++ b/sys/i386/i386/bpf_jit_machdep.c
@@ -440,62 +440,77 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size)
break;
case BPF_JMP|BPF_JA:
- JMP(stream.refs[stream.bpf_pc + ins->k] -
- stream.refs[stream.bpf_pc]);
+ JUMP(ins->k);
break;
case BPF_JMP|BPF_JGT|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPid(ins->k, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPid(ins->k, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPid(ins->k, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_K:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
TESTid(ins->k, EAX);
JCC(JNE, JE);
break;
case BPF_JMP|BPF_JGT|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPrd(EDX, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPrd(EDX, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
CMPrd(EDX, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_X:
- if (ins->jt == 0 && ins->jf == 0)
+ if (ins->jt == ins->jf) {
+ JUMP(ins->jt);
break;
+ }
TESTrd(EDX, EAX);
JCC(JNE, JE);
break;
diff --git a/sys/i386/i386/bpf_jit_machdep.h b/sys/i386/i386/bpf_jit_machdep.h
index e82f68a..4ae5494 100644
--- a/sys/i386/i386/bpf_jit_machdep.h
+++ b/sys/i386/i386/bpf_jit_machdep.h
@@ -418,4 +418,10 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n);
} \
} while (0)
+#define JUMP(off) do { \
+ if ((off) != 0) \
+ JMP(stream.refs[stream.bpf_pc + (off)] - \
+ stream.refs[stream.bpf_pc]); \
+} while (0)
+
#endif /* _BPF_JIT_MACHDEP_H_ */
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index 62c27ab..931bfaf 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -672,9 +672,11 @@ printcpuinfo(void)
cpu_vendor_id == CPU_VENDOR_NSC ||
(cpu_vendor_id == CPU_VENDOR_CYRIX &&
((cpu_id & 0xf00) > 0x500))) {
- printf(" Stepping = %u", cpu_id & 0xf);
+ printf(" Family = %x", CPUID_TO_FAMILY(cpu_id));
+ printf(" Model = %x", CPUID_TO_MODEL(cpu_id));
+ printf(" Stepping = %u", cpu_id & CPUID_STEPPING);
if (cpu_vendor_id == CPU_VENDOR_CYRIX)
- printf(" DIR=0x%04x", cyrix_did);
+ printf("\n DIR=0x%04x", cyrix_did);
if (cpu_high > 0) {
/*
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
index e0049c8..d894d32 100644
--- a/sys/i386/i386/local_apic.c
+++ b/sys/i386/i386/local_apic.c
@@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$");
#ifdef KDTRACE_HOOKS
#include <sys/dtrace_bsd.h>
-cyclic_clock_func_t lapic_cyclic_clock_func[MAXCPU];
+cyclic_clock_func_t cyclic_clock_func[MAXCPU];
#endif
/* Sanity checks on IDT vectors. */
@@ -116,14 +116,12 @@ struct lapic {
int la_ioint_irqs[APIC_NUM_IOINTS + 1];
} static lapics[MAX_APIC_ID + 1];
-/* XXX: should thermal be an NMI? */
-
/* Global defaults for local APIC LVT entries. */
static struct lvt lvts[LVT_MAX + 1] = {
{ 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 }, /* LINT0: masked ExtINT */
{ 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT }, /* Timer */
- { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */
+ { 1, 1, 0, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */
{ 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT }, /* Thermal */
};
@@ -150,6 +148,7 @@ extern inthand_t IDTVEC(rsvd);
volatile lapic_t *lapic;
vm_paddr_t lapic_paddr;
static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz;
+static enum lapic_clock clockcoverage;
static void lapic_enable(void);
static void lapic_resume(struct pic *pic);
@@ -161,17 +160,6 @@ static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value);
struct pic lapic_pic = { .pic_resume = lapic_resume };
-/*
- * The atrtc device is compiled in only if atpic is present.
- * If it is not, force lapic to take care of all the clocks.
- */
-#ifdef DEV_ATPIC
-static int lapic_allclocks;
-TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
-#else
-static int lapic_allclocks = 1;
-#endif
-
static uint32_t
lvt_mode(struct lapic *la, u_int pin, uint32_t value)
{
@@ -238,7 +226,11 @@ lapic_init(vm_paddr_t addr)
setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
- /* XXX: error/thermal interrupts */
+ /* Local APIC error interrupt. */
+ setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_SYS386IGT, SEL_KPL,
+ GSEL(GCODE_SEL, SEL_KPL));
+
+ /* XXX: Thermal interrupt */
}
/*
@@ -291,7 +283,7 @@ lapic_dump(const char* str)
lapic->id, lapic->version, lapic->ldr, lapic->dfr);
printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n",
lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
- printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pcm: 0x%08x\n",
+ printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n",
lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error,
lapic->lvt_pcint);
}
@@ -339,7 +331,11 @@ lapic_setup(int boot)
lapic_timer_enable_intr();
}
- /* XXX: Error and thermal LVTs */
+ /* Program error LVT and clear any existing errors. */
+ lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error);
+ lapic->esr = 0;
+
+ /* XXX: Thermal LVT */
intr_restore(eflags);
}
@@ -431,17 +427,20 @@ lapic_disable_pmc(void)
* that it can drive hardclock, statclock, and profclock.
*/
enum lapic_clock
-lapic_setup_clock(void)
+lapic_setup_clock(enum lapic_clock srcsdes)
{
u_long value;
int i;
- /* Can't drive the timer without a local APIC. */
- if (lapic == NULL)
- return (LAPIC_CLOCK_NONE);
+ /* lapic_setup_clock() should not be called with LAPIC_CLOCK_NONE. */
+ MPASS(srcsdes != LAPIC_CLOCK_NONE);
- if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)
- return (LAPIC_CLOCK_NONE);
+ /* Can't drive the timer without a local APIC. */
+ if (lapic == NULL ||
+ (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) {
+ clockcoverage = LAPIC_CLOCK_NONE;
+ return (clockcoverage);
+ }
/* Start off with a divisor of 2 (power on reset default). */
lapic_timer_divisor = 2;
@@ -477,7 +476,7 @@ lapic_setup_clock(void)
* Please note that stathz and profhz are set only if all the
* clocks are handled through the local APIC.
*/
- if (lapic_allclocks != 0) {
+ if (srcsdes == LAPIC_CLOCK_ALL) {
if (hz >= 1500)
lapic_timer_hz = hz;
else if (hz >= 750)
@@ -487,7 +486,7 @@ lapic_setup_clock(void)
} else
lapic_timer_hz = hz;
lapic_timer_period = value / lapic_timer_hz;
- if (lapic_allclocks != 0) {
+ if (srcsdes == LAPIC_CLOCK_ALL) {
if (lapic_timer_hz < 128)
stathz = lapic_timer_hz;
else
@@ -501,7 +500,8 @@ lapic_setup_clock(void)
*/
lapic_timer_periodic(lapic_timer_period);
lapic_timer_enable_intr();
- return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL);
+ clockcoverage = srcsdes;
+ return (srcsdes);
}
void
@@ -731,18 +731,6 @@ lapic_eoi(void)
lapic->eoi = 0;
}
-/*
- * Read the contents of the error status register. We have to write
- * to the register first before reading from it.
- */
-u_int
-lapic_error(void)
-{
-
- lapic->esr = 0;
- return (lapic->esr);
-}
-
void
lapic_handle_intr(int vector, struct trapframe *frame)
{
@@ -791,8 +779,8 @@ lapic_handle_timer(struct trapframe *frame)
* timers.
*/
int cpu = PCPU_GET(cpuid);
- if (lapic_cyclic_clock_func[cpu] != NULL)
- (*lapic_cyclic_clock_func[cpu])(frame);
+ if (cyclic_clock_func[cpu] != NULL)
+ (*cyclic_clock_func[cpu])(frame);
#endif
/* Fire hardclock at hz. */
@@ -804,7 +792,7 @@ lapic_handle_timer(struct trapframe *frame)
else
hardclock_cpu(TRAPF_USERMODE(frame));
}
- if (lapic_allclocks != 0) {
+ if (clockcoverage == LAPIC_CLOCK_ALL) {
/* Fire statclock at stathz. */
la->la_stat_ticks += stathz;
@@ -869,6 +857,24 @@ lapic_timer_enable_intr(void)
lapic->lvt_timer = value;
}
+void
+lapic_handle_error(void)
+{
+ u_int32_t esr;
+
+ /*
+ * Read the contents of the error status register. Write to
+ * the register first before reading from it to force the APIC
+ * to update its value to indicate any errors that have
+ * occurred since the previous write to the register.
+ */
+ lapic->esr = 0;
+ esr = lapic->esr;
+
+ printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr);
+ lapic_eoi();
+}
+
u_int
apic_cpuid(u_int apic_id)
{
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 1ef94ea..5293d53 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -944,7 +944,8 @@ freebsd4_sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
- printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags);
+ uprintf("pid %d (%s): freebsd4_sigreturn eflags = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, eflags);
return (EINVAL);
}
@@ -955,7 +956,8 @@ freebsd4_sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
- printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
+ uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@@ -1056,7 +1058,8 @@ sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
- printf("sigreturn: eflags = 0x%x\n", eflags);
+ uprintf("pid %d (%s): sigreturn eflags = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, eflags);
return (EINVAL);
}
@@ -1067,7 +1070,8 @@ sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
- printf("sigreturn: cs = 0x%x\n", cs);
+ uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
+ td->td_proc->p_pid, td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@@ -1461,11 +1465,7 @@ SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
* Reset registers to default values on exec.
*/
void
-exec_setregs(td, entry, stack, ps_strings)
- struct thread *td;
- u_long entry;
- u_long stack;
- u_long ps_strings;
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *regs = td->td_frame;
struct pcb *pcb = td->td_pcb;
@@ -1481,7 +1481,7 @@ exec_setregs(td, entry, stack, ps_strings)
mtx_unlock_spin(&dt_lock);
bzero((char *)regs, sizeof(struct trapframe));
- regs->tf_eip = entry;
+ regs->tf_eip = imgp->entry_addr;
regs->tf_esp = stack;
regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T);
regs->tf_ss = _udatasel;
@@ -1491,7 +1491,7 @@ exec_setregs(td, entry, stack, ps_strings)
regs->tf_cs = _ucodesel;
/* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
- regs->tf_ebx = ps_strings;
+ regs->tf_ebx = imgp->ps_strings;
/*
* Reset the hardware debug registers if they were in use.
diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c
index 6148af7..8d33b51 100644
--- a/sys/i386/i386/mca.c
+++ b/sys/i386/i386/mca.c
@@ -60,11 +60,20 @@ static int mca_count; /* Number of records stored. */
SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture");
-static int mca_enabled = 0;
+static int mca_enabled = 1;
TUNABLE_INT("hw.mca.enabled", &mca_enabled);
SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0,
"Administrative toggle for machine check support");
+static int amd10h_L1TP = 1;
+TUNABLE_INT("hw.mca.amd10h_L1TP", &amd10h_L1TP);
+SYSCTL_INT(_hw_mca, OID_AUTO, amd10h_L1TP, CTLFLAG_RDTUN, &amd10h_L1TP, 0,
+ "Administrative toggle for logging of level one TLB parity (L1TP) errors");
+
+int workaround_erratum383;
+SYSCTL_INT(_hw_mca, OID_AUTO, erratum383, CTLFLAG_RD, &workaround_erratum383, 0,
+ "Is the workaround for Erratum 383 on AMD Family 10h processors enabled?");
+
static STAILQ_HEAD(, mca_internal) mca_records;
static struct callout mca_timer;
static int mca_ticks = 3600; /* Check hourly by default. */
@@ -177,19 +186,46 @@ mca_error_request(uint16_t mca_error)
return ("???");
}
+static const char *
+mca_error_mmtype(uint16_t mca_error)
+{
+
+ switch ((mca_error & 0x70) >> 4) {
+ case 0x0:
+ return ("GEN");
+ case 0x1:
+ return ("RD");
+ case 0x2:
+ return ("WR");
+ case 0x3:
+ return ("AC");
+ case 0x4:
+ return ("MS");
+ }
+ return ("???");
+}
+
/* Dump details about a single machine check. */
static void __nonnull(1)
mca_log(const struct mca_record *rec)
{
uint16_t mca_error;
- printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank,
+ printf("MCA: Bank %d, Status 0x%016llx\n", rec->mr_bank,
(long long)rec->mr_status);
- printf("MCA: CPU %d ", rec->mr_apic_id);
+ printf("MCA: Global Cap 0x%016llx, Status 0x%016llx\n",
+ (long long)rec->mr_mcg_cap, (long long)rec->mr_mcg_status);
+ printf("MCA: Vendor \"%s\", ID 0x%x, APIC ID %d\n", cpu_vendor,
+ rec->mr_cpu_id, rec->mr_apic_id);
+ printf("MCA: CPU %d ", rec->mr_cpu);
if (rec->mr_status & MC_STATUS_UC)
printf("UNCOR ");
- else
+ else {
printf("COR ");
+ if (rec->mr_mcg_cap & MCG_CAP_TES_P)
+ printf("(%lld) ", ((long long)rec->mr_status &
+ MC_STATUS_COR_COUNT) >> 38);
+ }
if (rec->mr_status & MC_STATUS_PCC)
printf("PCC ");
if (rec->mr_status & MC_STATUS_OVER)
@@ -212,6 +248,9 @@ mca_log(const struct mca_record *rec)
case 0x0004:
printf("FRC error");
break;
+ case 0x0005:
+ printf("internal parity error");
+ break;
case 0x0400:
printf("internal timer error");
break;
@@ -236,6 +275,17 @@ mca_log(const struct mca_record *rec)
break;
}
+ /* Memory controller error. */
+ if ((mca_error & 0xef80) == 0x0080) {
+ printf("%s channel ", mca_error_mmtype(mca_error));
+ if ((mca_error & 0x000f) != 0x000f)
+ printf("%d", mca_error & 0x000f);
+ else
+ printf("??");
+ printf(" memory error");
+ break;
+ }
+
/* Cache error. */
if ((mca_error & 0xef00) == 0x0100) {
printf("%sCACHE %s %s error",
@@ -313,6 +363,11 @@ mca_check_status(int bank, struct mca_record *rec)
rec->mr_misc = rdmsr(MSR_MC_MISC(bank));
rec->mr_tsc = rdtsc();
rec->mr_apic_id = PCPU_GET(apic_id);
+ rec->mr_mcg_cap = rdmsr(MSR_MCG_CAP);
+ rec->mr_mcg_status = rdmsr(MSR_MCG_STATUS);
+ rec->mr_cpu_id = cpu_id;
+ rec->mr_cpu_vendor_id = cpu_vendor_id;
+ rec->mr_cpu = PCPU_GET(cpuid);
/*
* Clear machine check. Don't do this for uncorrectable
@@ -481,7 +536,7 @@ void
mca_init(void)
{
uint64_t mcg_cap;
- uint64_t ctl;
+ uint64_t ctl, mask;
int skip;
int i;
@@ -489,6 +544,15 @@ mca_init(void)
if (!mca_enabled || !(cpu_feature & CPUID_MCE))
return;
+ /*
+ * On AMD Family 10h processors, unless logging of level one TLB
+ * parity (L1TP) errors is disabled, enable the recommended workaround
+ * for Erratum 383.
+ */
+ if (cpu_vendor_id == CPU_VENDOR_AMD &&
+ CPUID_TO_FAMILY(cpu_id) == 0x10 && amd10h_L1TP)
+ workaround_erratum383 = 1;
+
if (cpu_feature & CPUID_MCA) {
if (PCPU_GET(cpuid) == 0)
mca_setup();
@@ -499,6 +563,19 @@ mca_init(void)
/* Enable MCA features. */
wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE);
+ /*
+ * Disable logging of level one TLB parity (L1TP) errors by
+ * the data cache as an alternative workaround for AMD Family
+ * 10h Erratum 383. Unlike the recommended workaround, there
+ * is no performance penalty to this workaround. However,
+ * L1TP errors will go unreported.
+ */
+ if (cpu_vendor_id == CPU_VENDOR_AMD &&
+ CPUID_TO_FAMILY(cpu_id) == 0x10 && !amd10h_L1TP) {
+ mask = rdmsr(MSR_MC0_CTL_MASK);
+ if ((mask & (1UL << 5)) == 0)
+ wrmsr(MSR_MC0_CTL_MASK, mask | (1UL << 5));
+ }
for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) {
/* By default enable logging of all errors. */
ctl = 0xffffffffffffffffUL;
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 6729288..716c25e 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include "opt_cpu.h"
#include "opt_kstack_pages.h"
#include "opt_mp_watchdog.h"
+#include "opt_pmap.h"
#include "opt_sched.h"
#include "opt_smp.h"
diff --git a/sys/i386/i386/mpboot.s b/sys/i386/i386/mpboot.s
index 5effeb9..8870858 100644
--- a/sys/i386/i386/mpboot.s
+++ b/sys/i386/i386/mpboot.s
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1995, Jack F. Vogel
+ * Copyright (c) 1995 Jack F. Vogel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,11 +10,6 @@
* 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 Jack F. Vogel
- * 4. The name of the developer may be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 4b2e34f..d8b9686 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -5,7 +5,7 @@
* All rights reserved.
* Copyright (c) 1994 David Greenman
* All rights reserved.
- * Copyright (c) 2005-2008 Alan L. Cox <alc@cs.rice.edu>
+ * Copyright (c) 2005-2010 Alan L. Cox <alc@cs.rice.edu>
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -163,7 +163,7 @@ __FBSDID("$FreeBSD$");
#if !defined(DIAGNOSTIC)
#ifdef __GNUC_GNU_INLINE__
-#define PMAP_INLINE inline
+#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
#else
#define PMAP_INLINE extern inline
#endif
@@ -207,8 +207,8 @@ vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
int pgeflag = 0; /* PG_G or-in */
int pseflag = 0; /* PG_PS or-in */
-static int nkpt;
-vm_offset_t kernel_vm_end;
+static int nkpt = NKPT;
+vm_offset_t kernel_vm_end = KERNBASE + NKPT * NBPDR;
extern u_int32_t KERNend;
extern u_int32_t KPTphys;
@@ -296,7 +296,9 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va,
static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte);
static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte);
static boolean_t pmap_is_modified_pvh(struct md_page *pvh);
+static boolean_t pmap_is_referenced_pvh(struct md_page *pvh);
static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode);
+static void pmap_kenter_pde(vm_offset_t va, pd_entry_t newpde);
static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va);
static void pmap_pde_attr(pd_entry_t *pde, int cache_bits);
static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va);
@@ -315,6 +317,9 @@ static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m);
static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
vm_page_t m);
+static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
+ pd_entry_t newpde);
+static void pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde);
static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags);
@@ -380,11 +385,17 @@ pmap_bootstrap(vm_paddr_t firstaddr)
kernel_pmap->pm_active = -1; /* don't allow deactivation */
TAILQ_INIT(&kernel_pmap->pm_pvchunk);
LIST_INIT(&allpmaps);
+
+ /*
+ * Request a spin mutex so that changes to allpmaps cannot be
+ * preempted by smp_rendezvous_cpus(). Otherwise,
+ * pmap_update_pde_kernel() could access allpmaps while it is
+ * being changed.
+ */
mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_SPIN);
mtx_lock_spin(&allpmaps_lock);
LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list);
mtx_unlock_spin(&allpmaps_lock);
- nkpt = NKPT;
/*
* Reserve some special page table entries/VA space for temporary
@@ -692,19 +703,21 @@ pmap_init(void)
pv_entry_high_water = 9 * (pv_entry_max / 10);
/*
- * Disable large page mappings by default if the kernel is running in
- * a virtual machine on an AMD Family 10h processor. This is a work-
- * around for Erratum 383.
+ * If the kernel is running in a virtual machine on an AMD Family 10h
+ * processor, then it must assume that MCA is enabled by the virtual
+ * machine monitor.
*/
if (vm_guest == VM_GUEST_VM && cpu_vendor_id == CPU_VENDOR_AMD &&
CPUID_TO_FAMILY(cpu_id) == 0x10)
- pg_ps_enabled = 0;
+ workaround_erratum383 = 1;
/*
- * Are large page mappings enabled?
+ * Are large page mappings supported and enabled?
*/
TUNABLE_INT_FETCH("vm.pmap.pg_ps_enabled", &pg_ps_enabled);
- if (pg_ps_enabled) {
+ if (pseflag == 0)
+ pg_ps_enabled = 0;
+ else if (pg_ps_enabled) {
KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
("pmap_init: can't assign to pagesizes[1]"));
pagesizes[1] = NBPDR;
@@ -850,6 +863,69 @@ pmap_cache_bits(int mode, boolean_t is_pde)
cache_bits |= PG_NC_PWT;
return (cache_bits);
}
+
+/*
+ * The caller is responsible for maintaining TLB consistency.
+ */
+static void
+pmap_kenter_pde(vm_offset_t va, pd_entry_t newpde)
+{
+ pd_entry_t *pde;
+ pmap_t pmap;
+ boolean_t PTD_updated;
+
+ PTD_updated = FALSE;
+ mtx_lock_spin(&allpmaps_lock);
+ LIST_FOREACH(pmap, &allpmaps, pm_list) {
+ if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] &
+ PG_FRAME))
+ PTD_updated = TRUE;
+ pde = pmap_pde(pmap, va);
+ pde_store(pde, newpde);
+ }
+ mtx_unlock_spin(&allpmaps_lock);
+ KASSERT(PTD_updated,
+ ("pmap_kenter_pde: current page table is not in allpmaps"));
+}
+
+/*
+ * After changing the page size for the specified virtual address in the page
+ * table, flush the corresponding entries from the processor's TLB. Only the
+ * calling processor's TLB is affected.
+ *
+ * The calling thread must be pinned to a processor.
+ */
+static void
+pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde)
+{
+ u_long cr4;
+
+ if ((newpde & PG_PS) == 0)
+ /* Demotion: flush a specific 2MB page mapping. */
+ invlpg(va);
+ else if ((newpde & PG_G) == 0)
+ /*
+ * Promotion: flush every 4KB page mapping from the TLB
+ * because there are too many to flush individually.
+ */
+ invltlb();
+ else {
+ /*
+ * Promotion: flush every 4KB page mapping from the TLB,
+ * including any global (PG_G) mappings.
+ */
+ cr4 = rcr4();
+ load_cr4(cr4 & ~CR4_PGE);
+ /*
+ * Although preemption at this point could be detrimental to
+ * performance, it would not lead to an error. PG_G is simply
+ * ignored if CR4.PGE is clear. Moreover, in case this block
+ * is re-entered, the load_cr4() either above or below will
+ * modify CR4.PGE flushing the TLB.
+ */
+ load_cr4(cr4 | CR4_PGE);
+ }
+}
#ifdef SMP
/*
* For SMP, these functions have to use the IPI mechanism for coherence.
@@ -946,6 +1022,92 @@ pmap_invalidate_cache(void)
smp_cache_flush();
sched_unpin();
}
+
+struct pde_action {
+ cpumask_t store; /* processor that updates the PDE */
+ cpumask_t invalidate; /* processors that invalidate their TLB */
+ vm_offset_t va;
+ pd_entry_t *pde;
+ pd_entry_t newpde;
+};
+
+static void
+pmap_update_pde_kernel(void *arg)
+{
+ struct pde_action *act = arg;
+ pd_entry_t *pde;
+ pmap_t pmap;
+
+ if (act->store == PCPU_GET(cpumask))
+ /*
+ * Elsewhere, this operation requires allpmaps_lock for
+ * synchronization. Here, it does not because it is being
+ * performed in the context of an all_cpus rendezvous.
+ */
+ LIST_FOREACH(pmap, &allpmaps, pm_list) {
+ pde = pmap_pde(pmap, act->va);
+ pde_store(pde, act->newpde);
+ }
+}
+
+static void
+pmap_update_pde_user(void *arg)
+{
+ struct pde_action *act = arg;
+
+ if (act->store == PCPU_GET(cpumask))
+ pde_store(act->pde, act->newpde);
+}
+
+static void
+pmap_update_pde_teardown(void *arg)
+{
+ struct pde_action *act = arg;
+
+ if ((act->invalidate & PCPU_GET(cpumask)) != 0)
+ pmap_update_pde_invalidate(act->va, act->newpde);
+}
+
+/*
+ * Change the page size for the specified virtual address in a way that
+ * prevents any possibility of the TLB ever having two entries that map the
+ * same virtual address using different page sizes. This is the recommended
+ * workaround for Erratum 383 on AMD Family 10h processors. It prevents a
+ * machine check exception for a TLB state that is improperly diagnosed as a
+ * hardware error.
+ */
+static void
+pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
+{
+ struct pde_action act;
+ cpumask_t active, cpumask;
+
+ sched_pin();
+ cpumask = PCPU_GET(cpumask);
+ if (pmap == kernel_pmap)
+ active = all_cpus;
+ else
+ active = pmap->pm_active;
+ if ((active & PCPU_GET(other_cpus)) != 0) {
+ act.store = cpumask;
+ act.invalidate = active;
+ act.va = va;
+ act.pde = pde;
+ act.newpde = newpde;
+ smp_rendezvous_cpus(cpumask | active,
+ smp_no_rendevous_barrier, pmap == kernel_pmap ?
+ pmap_update_pde_kernel : pmap_update_pde_user,
+ pmap_update_pde_teardown, &act);
+ } else {
+ if (pmap == kernel_pmap)
+ pmap_kenter_pde(va, newpde);
+ else
+ pde_store(pde, newpde);
+ if ((active & cpumask) != 0)
+ pmap_update_pde_invalidate(va, newpde);
+ }
+ sched_unpin();
+}
#else /* !SMP */
/*
* Normal, non-SMP, 486+ invalidation functions.
@@ -983,6 +1145,18 @@ pmap_invalidate_cache(void)
wbinvd();
}
+
+static void
+pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
+{
+
+ if (pmap == kernel_pmap)
+ pmap_kenter_pde(va, newpde);
+ else
+ pde_store(pde, newpde);
+ if (pmap == kernel_pmap || pmap->pm_active)
+ pmap_update_pde_invalidate(va, newpde);
+}
#endif /* !SMP */
void
@@ -996,7 +1170,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
if (cpu_feature & CPUID_SS)
; /* If "Self Snoop" is supported, do nothing. */
- else if (cpu_feature & CPUID_CLFSH) {
+ else if ((cpu_feature & CPUID_CLFSH) != 0 &&
+ eva - sva < 2 * 1024 * 1024) {
/*
* Otherwise, do per-cache line flush. Use the mfence
@@ -1013,7 +1188,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
/*
* No targeted cache flush methods are supported by CPU,
- * globally invalidate cache as a last resort.
+ * or the supplied range is bigger than 2MB.
+ * Globally invalidate cache.
*/
pmap_invalidate_cache();
}
@@ -1431,9 +1607,9 @@ pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, vm_page_t *free)
--m->wire_count;
if (m->wire_count == 0)
- return _pmap_unwire_pte_hold(pmap, m, free);
+ return (_pmap_unwire_pte_hold(pmap, m, free));
else
- return 0;
+ return (0);
}
static int
@@ -1467,7 +1643,7 @@ _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, vm_page_t *free)
*/
pmap_add_delayed_free_list(m, free, TRUE);
- return 1;
+ return (1);
}
/*
@@ -1481,10 +1657,10 @@ pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t *free)
vm_page_t mpte;
if (va >= VM_MAXUSER_ADDRESS)
- return 0;
+ return (0);
ptepde = *pmap_pde(pmap, va);
mpte = PHYS_TO_VM_PAGE(ptepde & PG_FRAME);
- return pmap_unwire_pte_hold(pmap, mpte, free);
+ return (pmap_unwire_pte_hold(pmap, mpte, free));
}
void
@@ -1635,7 +1811,7 @@ _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags)
pmap->pm_pdir[ptepindex] =
(pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_A | PG_M);
- return m;
+ return (m);
}
static vm_page_t
@@ -1833,7 +2009,7 @@ kvm_size(SYSCTL_HANDLER_ARGS)
{
unsigned long ksize = VM_MAX_KERNEL_ADDRESS - KERNBASE;
- return sysctl_handle_long(oidp, &ksize, 0, req);
+ return (sysctl_handle_long(oidp, &ksize, 0, req));
}
SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG|CTLFLAG_RD,
0, 0, kvm_size, "IU", "Size of KVM");
@@ -1843,7 +2019,7 @@ kvm_free(SYSCTL_HANDLER_ARGS)
{
unsigned long kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end;
- return sysctl_handle_long(oidp, &kfree, 0, req);
+ return (sysctl_handle_long(oidp, &kfree, 0, req));
}
SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD,
0, 0, kvm_free, "IU", "Amount of KVM free");
@@ -1854,32 +2030,17 @@ SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD,
void
pmap_growkernel(vm_offset_t addr)
{
- struct pmap *pmap;
vm_paddr_t ptppaddr;
vm_page_t nkpg;
pd_entry_t newpdir;
- pt_entry_t *pde;
- boolean_t updated_PTD;
mtx_assert(&kernel_map->system_mtx, MA_OWNED);
- if (kernel_vm_end == 0) {
- kernel_vm_end = KERNBASE;
- nkpt = 0;
- while (pdir_pde(PTD, kernel_vm_end)) {
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
- nkpt++;
- if (kernel_vm_end - 1 >= kernel_map->max_offset) {
- kernel_vm_end = kernel_map->max_offset;
- break;
- }
- }
- }
- addr = roundup2(addr, PAGE_SIZE * NPTEPG);
+ addr = roundup2(addr, NBPDR);
if (addr - 1 >= kernel_map->max_offset)
addr = kernel_map->max_offset;
while (kernel_vm_end < addr) {
if (pdir_pde(PTD, kernel_vm_end)) {
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
+ kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
if (kernel_vm_end - 1 >= kernel_map->max_offset) {
kernel_vm_end = kernel_map->max_offset;
break;
@@ -1901,19 +2062,8 @@ pmap_growkernel(vm_offset_t addr)
newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M);
pdir_pde(KPTD, kernel_vm_end) = pgeflag | newpdir;
- updated_PTD = FALSE;
- mtx_lock_spin(&allpmaps_lock);
- LIST_FOREACH(pmap, &allpmaps, pm_list) {
- if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] &
- PG_FRAME))
- updated_PTD = TRUE;
- pde = pmap_pde(pmap, kernel_vm_end);
- pde_store(pde, newpdir);
- }
- mtx_unlock_spin(&allpmaps_lock);
- KASSERT(updated_PTD,
- ("pmap_growkernel: current page table is not in allpmaps"));
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
+ pmap_kenter_pde(kernel_vm_end, newpdir);
+ kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
if (kernel_vm_end - 1 >= kernel_map->max_offset) {
kernel_vm_end = kernel_map->max_offset;
break;
@@ -1933,7 +2083,7 @@ static __inline struct pv_chunk *
pv_to_chunk(pv_entry_t pv)
{
- return (struct pv_chunk *)((uintptr_t)pv & ~(uintptr_t)PAGE_MASK);
+ return ((struct pv_chunk *)((uintptr_t)pv & ~(uintptr_t)PAGE_MASK));
}
#define PV_PMAP(pv) (pv_to_chunk(pv)->pc_pmap)
@@ -2356,7 +2506,6 @@ static boolean_t
pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
{
pd_entry_t newpde, oldpde;
- pmap_t allpmaps_entry;
pt_entry_t *firstpte, newpte;
vm_paddr_t mptepa;
vm_page_t free, mpte;
@@ -2462,25 +2611,11 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
* processor changing the setting of PG_A and/or PG_M between
* the read above and the store below.
*/
- if (pmap == kernel_pmap) {
- /*
- * A harmless race exists between this loop and the bcopy()
- * in pmap_pinit() that initializes the kernel segment of
- * the new page table directory. Specifically, that bcopy()
- * may copy the new PDE from the PTD to the new page table
- * before this loop updates that new page table.
- */
- mtx_lock_spin(&allpmaps_lock);
- LIST_FOREACH(allpmaps_entry, &allpmaps, pm_list) {
- pde = pmap_pde(allpmaps_entry, va);
- KASSERT(*pde == newpde || (*pde & PG_PTE_PROMOTE) ==
- (oldpde & PG_PTE_PROMOTE),
- ("pmap_demote_pde: pde was %#jx, expected %#jx",
- (uintmax_t)*pde, (uintmax_t)oldpde));
- pde_store(pde, newpde);
- }
- mtx_unlock_spin(&allpmaps_lock);
- } else
+ if (workaround_erratum383)
+ pmap_update_pde(pmap, va, pde, newpde);
+ else if (pmap == kernel_pmap)
+ pmap_kenter_pde(va, newpde);
+ else
pde_store(pde, newpde);
if (firstpte == PADDR2)
mtx_unlock(&PMAP2mutex);
@@ -2820,18 +2955,9 @@ retry:
if (oldpde & PG_MANAGED) {
eva = sva + NBPDR;
for (va = sva, m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME);
- va < eva; va += PAGE_SIZE, m++) {
- /*
- * In contrast to the analogous operation on a 4KB page
- * mapping, the mapping's PG_A flag is not cleared and
- * the page's PG_REFERENCED flag is not set. The
- * reason is that pmap_demote_pde() expects that a 2/4MB
- * page mapping with a stored page table page has PG_A
- * set.
- */
+ va < eva; va += PAGE_SIZE, m++)
if ((oldpde & (PG_M | PG_RW)) == (PG_M | PG_RW))
vm_page_dirty(m);
- }
}
if ((prot & VM_PROT_WRITE) == 0)
newpde &= ~(PG_RW | PG_M);
@@ -2939,22 +3065,15 @@ retry:
obits = pbits = *pte;
if ((pbits & PG_V) == 0)
continue;
- if (pbits & PG_MANAGED) {
- m = NULL;
- if (pbits & PG_A) {
+
+ if ((prot & VM_PROT_WRITE) == 0) {
+ if ((pbits & (PG_MANAGED | PG_M | PG_RW)) ==
+ (PG_MANAGED | PG_M | PG_RW)) {
m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
- vm_page_flag_set(m, PG_REFERENCED);
- pbits &= ~PG_A;
- }
- if ((pbits & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
- if (m == NULL)
- m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
vm_page_dirty(m);
}
- }
-
- if ((prot & VM_PROT_WRITE) == 0)
pbits &= ~(PG_RW | PG_M);
+ }
#ifdef PAE
if ((prot & VM_PROT_EXECUTE) == 0)
pbits |= pg_nx;
@@ -2999,7 +3118,6 @@ static void
pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
{
pd_entry_t newpde;
- pmap_t allpmaps_entry;
pt_entry_t *firstpte, oldpte, pa, *pte;
vm_offset_t oldpteva;
vm_page_t mpte;
@@ -3011,7 +3129,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
* either invalid, unused, or does not map the first 4KB physical page
* within a 2- or 4MB page.
*/
- firstpte = vtopte(trunc_4mpage(va));
+ firstpte = pmap_pte_quick(pmap, trunc_4mpage(va));
setpde:
newpde = *firstpte;
if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V)) {
@@ -3103,14 +3221,11 @@ setpte:
/*
* Map the superpage.
*/
- if (pmap == kernel_pmap) {
- mtx_lock_spin(&allpmaps_lock);
- LIST_FOREACH(allpmaps_entry, &allpmaps, pm_list) {
- pde = pmap_pde(allpmaps_entry, va);
- pde_store(pde, PG_PS | newpde);
- }
- mtx_unlock_spin(&allpmaps_lock);
- } else
+ if (workaround_erratum383)
+ pmap_update_pde(pmap, va, pde, PG_PS | newpde);
+ else if (pmap == kernel_pmap)
+ pmap_kenter_pde(va, PG_PS | newpde);
+ else
pde_store(pde, PG_PS | newpde);
pmap_pde_promotions++;
@@ -3531,7 +3646,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
pte_store(pte, pa | PG_V | PG_U);
else
pte_store(pte, pa | PG_V | PG_U | PG_MANAGED);
- return mpte;
+ return (mpte);
}
/*
@@ -3928,12 +4043,12 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
int loops = 0;
if (m->flags & PG_FICTITIOUS)
- return FALSE;
+ return (FALSE);
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
if (PV_PMAP(pv) == pmap) {
- return TRUE;
+ return (TRUE);
}
loops++;
if (loops >= 16)
@@ -4226,6 +4341,51 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
}
/*
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+ if (m->flags & PG_FICTITIOUS)
+ return (FALSE);
+ if (pmap_is_referenced_pvh(&m->md))
+ return (TRUE);
+ return (pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m))));
+}
+
+/*
+ * Returns TRUE if any of the given mappings were referenced and FALSE
+ * otherwise. Both page and 4mpage mappings are supported.
+ */
+static boolean_t
+pmap_is_referenced_pvh(struct md_page *pvh)
+{
+ pv_entry_t pv;
+ pt_entry_t *pte;
+ pmap_t pmap;
+ boolean_t rv;
+
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ rv = FALSE;
+ sched_pin();
+ TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+ pmap = PV_PMAP(pv);
+ PMAP_LOCK(pmap);
+ pte = pmap_pte_quick(pmap, pv->pv_va);
+ rv = (*pte & (PG_A | PG_V)) == (PG_A | PG_V);
+ PMAP_UNLOCK(pmap);
+ if (rv)
+ break;
+ }
+ sched_unpin();
+ return (rv);
+}
+
+/*
* Clear the write and modified bits in each of the given page's mappings.
*/
void
@@ -4802,7 +4962,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
if (pte != 0) {
val |= MINCORE_INCORE;
if ((pte & PG_MANAGED) == 0)
- return val;
+ return (val);
m = PHYS_TO_VM_PAGE(pa);
@@ -4831,14 +4991,12 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
*/
vm_page_lock_queues();
if ((m->flags & PG_REFERENCED) ||
- pmap_ts_referenced(m)) {
+ pmap_is_referenced(m))
val |= MINCORE_REFERENCED_OTHER;
- vm_page_flag_set(m, PG_REFERENCED);
- }
vm_page_unlock_queues();
}
}
- return val;
+ return (val);
}
void
@@ -4933,7 +5091,7 @@ pmap_pid_dump(int pid)
printf("\n");
}
sx_sunlock(&allproc_lock);
- return npte;
+ return (npte);
}
pte = pmap_pte(pmap, va);
if (pte && pmap_pte_v(pte)) {
@@ -4958,7 +5116,7 @@ pmap_pid_dump(int pid)
}
}
sx_sunlock(&allproc_lock);
- return npte;
+ return (npte);
}
#endif
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 305cfd2..a11daa6 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -277,7 +277,7 @@ trap(struct trapframe *frame)
* enabled later.
*/
if (ISPL(frame->tf_cs) == SEL_UPL || (frame->tf_eflags & PSL_VM))
- printf(
+ uprintf(
"pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curthread->td_name, type);
else if (type != T_BPTFLT && type != T_TRCTRAP &&
@@ -507,7 +507,7 @@ trap(struct trapframe *frame)
if (npxdna())
goto userout;
#endif
- printf("pid %d killed due to lack of floating point\n",
+ uprintf("pid %d killed due to lack of floating point\n",
p->p_pid);
i = SIGKILL;
ucode = 0;
@@ -540,6 +540,10 @@ trap(struct trapframe *frame)
* XXX this should be fatal unless the kernel has
* registered such use.
*/
+ printf("npxdna in kernel mode!\n");
+#ifdef KDB
+ kdb_backtrace();
+#endif
if (npxdna())
goto out;
#endif
diff --git a/sys/i386/ibcs2/ibcs2_stat.c b/sys/i386/ibcs2/ibcs2_stat.c
index 9253071..b61e45e 100644
--- a/sys/i386/ibcs2/ibcs2_stat.c
+++ b/sys/i386/ibcs2/ibcs2_stat.c
@@ -72,9 +72,9 @@ bsd_stat2ibcs_stat(st, st4)
st4->st_size = (ibcs2_off_t)st->st_size;
else
st4->st_size = -2;
- st4->st_atim = (ibcs2_time_t)st->st_atime;
- st4->st_mtim = (ibcs2_time_t)st->st_mtime;
- st4->st_ctim = (ibcs2_time_t)st->st_ctime;
+ st4->st_atim = (ibcs2_time_t)st->st_atim.tv_sec;
+ st4->st_mtim = (ibcs2_time_t)st->st_mtim.tv_sec;
+ st4->st_ctim = (ibcs2_time_t)st->st_ctim.tv_sec;
}
static int
diff --git a/sys/i386/include/_inttypes.h b/sys/i386/include/_inttypes.h
index 7da589d..ca70a7a 100644
--- a/sys/i386/include/_inttypes.h
+++ b/sys/i386/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index 2f8e716..bcb84a0 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
@@ -208,7 +208,8 @@ struct apic_enumerator {
inthand_t
IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
- IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
+ IDTVEC(apic_isr7), IDTVEC(errorint), IDTVEC(spuriousint),
+ IDTVEC(timerint);
extern vm_paddr_t lapic_paddr;
extern int apic_cpuids[];
@@ -240,13 +241,13 @@ void lapic_disable_pmc(void);
void lapic_dump(const char *str);
int lapic_enable_pmc(void);
void lapic_eoi(void);
-u_int lapic_error(void);
int lapic_id(void);
void lapic_init(vm_paddr_t addr);
int lapic_intr_pending(u_int vector);
void lapic_ipi_raw(register_t icrlo, u_int dest);
void lapic_ipi_vectored(u_int vector, int dest);
int lapic_ipi_wait(int delay);
+void lapic_handle_error(void);
void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(struct trapframe *frame);
void lapic_reenable_pmc(void);
@@ -259,7 +260,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
enum intr_trigger trigger);
void lapic_set_tpr(u_int vector);
void lapic_setup(int boot);
-enum lapic_clock lapic_setup_clock(void);
+enum lapic_clock lapic_setup_clock(enum lapic_clock srcsdes);
#endif /* !LOCORE */
#endif /* _MACHINE_APICVAR_H_ */
diff --git a/sys/i386/include/bootinfo.h b/sys/i386/include/bootinfo.h
index 09b4e2c..9c36e28 100644
--- a/sys/i386/include/bootinfo.h
+++ b/sys/i386/include/bootinfo.h
@@ -65,6 +65,13 @@ struct bootinfo {
u_int32_t bi_kernend; /* end of kernel space */
u_int32_t bi_envp; /* environment */
u_int32_t bi_modulep; /* preloaded modules */
+ uint64_t bi_hcdp; /* DIG64 HCDP table */
+ uint64_t bi_fpswa; /* FPSWA interface */
+ uint64_t bi_systab; /* pa of EFI system table */
+ uint64_t bi_memmap; /* pa of EFI memory map */
+ uint64_t bi_memmap_size; /* size of EFI memory map */
+ uint64_t bi_memdesc_size; /* sizeof EFI memory desc */
+ uint32_t bi_memdesc_version; /* EFI memory desc version */
};
#ifdef _KERNEL
diff --git a/sys/i386/include/mca.h b/sys/i386/include/mca.h
index ddc3aeb..bc09480 100644
--- a/sys/i386/include/mca.h
+++ b/sys/i386/include/mca.h
@@ -37,6 +37,11 @@ struct mca_record {
uint64_t mr_tsc;
int mr_apic_id;
int mr_bank;
+ uint64_t mr_mcg_cap;
+ uint64_t mr_mcg_status;
+ int mr_cpu_id;
+ int mr_cpu_vendor_id;
+ int mr_cpu;
};
#ifdef _KERNEL
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index e2968e9..44eb8a6 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -73,6 +73,7 @@ extern int szosigcode;
#endif
extern uint32_t *vm_page_dump;
extern int vm_page_dump_size;
+extern int workaround_erratum383;
typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
struct thread;
diff --git a/sys/i386/include/pmc_mdep.h b/sys/i386/include/pmc_mdep.h
index 4389a20..9209a2b 100644
--- a/sys/i386/include/pmc_mdep.h
+++ b/sys/i386/include/pmc_mdep.h
@@ -49,6 +49,8 @@ struct pmc_mdep;
* PENTIUM Intel Pentium MMX.
* IAP Intel Core/Core2/Atom programmable PMCs.
* IAF Intel fixed-function PMCs.
+ * UCP Intel Uncore programmable PMCs.
+ * UCF Intel Uncore fixed-function PMCs.
*/
#include <dev/hwpmc/hwpmc_amd.h> /* K7 and K8 */
@@ -57,11 +59,12 @@ struct pmc_mdep;
#include <dev/hwpmc/hwpmc_ppro.h>
#include <dev/hwpmc/hwpmc_pentium.h>
#include <dev/hwpmc/hwpmc_tsc.h>
+#include <dev/hwpmc/hwpmc_uncore.h>
/*
* Intel processors implementing V2 and later of the Intel performance
* measurement architecture have PMCs of the following classes: TSC,
- * IAF and IAP.
+ * IAF, IAP, UCF and UCP.
*/
#define PMC_MDEP_CLASS_INDEX_TSC 0
#define PMC_MDEP_CLASS_INDEX_K7 1
@@ -71,6 +74,8 @@ struct pmc_mdep;
#define PMC_MDEP_CLASS_INDEX_P6 1
#define PMC_MDEP_CLASS_INDEX_IAP 1
#define PMC_MDEP_CLASS_INDEX_IAF 2
+#define PMC_MDEP_CLASS_INDEX_UCP 3
+#define PMC_MDEP_CLASS_INDEX_UCF 4
/*
* Architecture specific extensions to <sys/pmc.h> structures.
@@ -80,6 +85,8 @@ union pmc_md_op_pmcallocate {
struct pmc_md_amd_op_pmcallocate pm_amd;
struct pmc_md_iaf_op_pmcallocate pm_iaf;
struct pmc_md_iap_op_pmcallocate pm_iap;
+ struct pmc_md_ucf_op_pmcallocate pm_ucf;
+ struct pmc_md_ucp_op_pmcallocate pm_ucp;
struct pmc_md_p4_op_pmcallocate pm_p4;
struct pmc_md_pentium_op_pmcallocate pm_pentium;
struct pmc_md_ppro_op_pmcallocate pm_ppro;
@@ -97,6 +104,8 @@ union pmc_md_pmc {
struct pmc_md_amd_pmc pm_amd;
struct pmc_md_iaf_pmc pm_iaf;
struct pmc_md_iap_pmc pm_iap;
+ struct pmc_md_ucf_pmc pm_ucf;
+ struct pmc_md_ucp_pmc pm_ucp;
struct pmc_md_p4_pmc pm_p4;
struct pmc_md_pentium_pmc pm_pentium;
struct pmc_md_ppro_pmc pm_ppro;
diff --git a/sys/i386/include/proc.h b/sys/i386/include/proc.h
index 1e0b9f9..0b9fca2 100644
--- a/sys/i386/include/proc.h
+++ b/sys/i386/include/proc.h
@@ -57,6 +57,8 @@ struct mdproc {
struct proc_ldt *md_ldt; /* (t) per-process ldt */
};
+#define KINFO_PROC_SIZE 768
+
#ifdef _KERNEL
/* Get the current kernel thread stack usage. */
diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
index d51da6d..d2494c7 100644
--- a/sys/i386/include/specialreg.h
+++ b/sys/i386/include/specialreg.h
@@ -273,6 +273,7 @@
#define MSR_MTRR16kBase 0x258
#define MSR_MTRR4kBase 0x268
#define MSR_PAT 0x277
+#define MSR_MC0_CTL2 0x280
#define MSR_MTRRdefType 0x2ff
#define MSR_MC0_CTL 0x400
#define MSR_MC0_STATUS 0x401
@@ -326,16 +327,16 @@
#define MTRR_N64K 8 /* numbers of fixed-size entries */
#define MTRR_N16K 16
#define MTRR_N4K 64
-#define MTRR_CAP_WC 0x0000000000000400ULL
-#define MTRR_CAP_FIXED 0x0000000000000100ULL
-#define MTRR_CAP_VCNT 0x00000000000000ffULL
-#define MTRR_DEF_ENABLE 0x0000000000000800ULL
-#define MTRR_DEF_FIXED_ENABLE 0x0000000000000400ULL
-#define MTRR_DEF_TYPE 0x00000000000000ffULL
-#define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000ULL
-#define MTRR_PHYSBASE_TYPE 0x00000000000000ffULL
-#define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000ULL
-#define MTRR_PHYSMASK_VALID 0x0000000000000800ULL
+#define MTRR_CAP_WC 0x0000000000000400
+#define MTRR_CAP_FIXED 0x0000000000000100
+#define MTRR_CAP_VCNT 0x00000000000000ff
+#define MTRR_DEF_ENABLE 0x0000000000000800
+#define MTRR_DEF_FIXED_ENABLE 0x0000000000000400
+#define MTRR_DEF_TYPE 0x00000000000000ff
+#define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000
+#define MTRR_PHYSBASE_TYPE 0x00000000000000ff
+#define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000
+#define MTRR_PHYSMASK_VALID 0x0000000000000800
/*
* Cyrix configuration registers, accessible as IO ports.
@@ -421,27 +422,38 @@
#define MCG_CAP_COUNT 0x000000ff
#define MCG_CAP_CTL_P 0x00000100
#define MCG_CAP_EXT_P 0x00000200
+#define MCG_CAP_CMCI_P 0x00000400
#define MCG_CAP_TES_P 0x00000800
#define MCG_CAP_EXT_CNT 0x00ff0000
+#define MCG_CAP_SER_P 0x01000000
#define MCG_STATUS_RIPV 0x00000001
#define MCG_STATUS_EIPV 0x00000002
#define MCG_STATUS_MCIP 0x00000004
-#define MCG_CTL_ENABLE 0xffffffffffffffffUL
-#define MCG_CTL_DISABLE 0x0000000000000000UL
+#define MCG_CTL_ENABLE 0xffffffffffffffff
+#define MCG_CTL_DISABLE 0x0000000000000000
#define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4)
#define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4)
#define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4)
#define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4)
-#define MC_STATUS_MCA_ERROR 0x000000000000ffffUL
-#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000UL
-#define MC_STATUS_OTHER_INFO 0x01ffffff00000000UL
-#define MC_STATUS_PCC 0x0200000000000000UL
-#define MC_STATUS_ADDRV 0x0400000000000000UL
-#define MC_STATUS_MISCV 0x0800000000000000UL
-#define MC_STATUS_EN 0x1000000000000000UL
-#define MC_STATUS_UC 0x2000000000000000UL
-#define MC_STATUS_OVER 0x4000000000000000UL
-#define MC_STATUS_VAL 0x8000000000000000UL
+#define MSR_MC_CTL2(x) (MSR_MC0_CTL2 + (x)) /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_MCA_ERROR 0x000000000000ffff
+#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000
+#define MC_STATUS_OTHER_INFO 0x01ffffff00000000
+#define MC_STATUS_COR_COUNT 0x001fffc000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_TES_STATUS 0x0060000000000000 /* If MCG_CAP_TES_P */
+#define MC_STATUS_AR 0x0080000000000000 /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_S 0x0100000000000000 /* If MCG_CAP_CMCI_P */
+#define MC_STATUS_PCC 0x0200000000000000
+#define MC_STATUS_ADDRV 0x0400000000000000
+#define MC_STATUS_MISCV 0x0800000000000000
+#define MC_STATUS_EN 0x1000000000000000
+#define MC_STATUS_UC 0x2000000000000000
+#define MC_STATUS_OVER 0x4000000000000000
+#define MC_STATUS_VAL 0x8000000000000000
+#define MC_MISC_RA_LSB 0x000000000000003f /* If MCG_CAP_SER_P */
+#define MC_MISC_ADDRESS_MODE 0x00000000000001c0 /* If MCG_CAP_SER_P */
+#define MC_CTL2_THRESHOLD 0x0000000000003fff
+#define MC_CTL2_CMCI_EN 0x0000000040000000
/*
* The following four 3-byte registers control the non-cacheable regions.
@@ -539,6 +551,7 @@
/* AMD64 MSR's */
#define MSR_EFER 0xc0000080 /* extended features */
#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */
+#define MSR_MC0_CTL_MASK 0xc0010044
/* VIA ACE crypto featureset: for via_feature_rng */
#define VIA_HAS_RNG 1 /* cpu has RNG */
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index d614716..fe84c06 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -178,9 +178,9 @@ struct l_newstat {
l_ulong st_size;
l_ulong st_blksize;
l_ulong st_blocks;
- struct l_timespec st_atimespec;
- struct l_timespec st_mtimespec;
- struct l_timespec st_ctimespec;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
l_ulong __unused4;
l_ulong __unused5;
};
@@ -194,9 +194,9 @@ struct l_stat {
l_ushort st_gid;
l_ushort st_rdev;
l_long st_size;
- struct l_timespec st_atimespec;
- struct l_timespec st_mtimespec;
- struct l_timespec st_ctimespec;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
l_long st_blksize;
l_long st_blocks;
l_ulong st_flags;
@@ -217,9 +217,9 @@ struct l_stat64 {
l_ulong st_blksize;
l_ulong st_blocks;
l_ulong __pad4;
- struct l_timespec st_atimespec;
- struct l_timespec st_mtimespec;
- struct l_timespec st_ctimespec;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
l_ulonglong st_ino;
};
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 069b5bb..3f0c6f4 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -105,8 +105,8 @@ static int elf_linux_fixup(register_t **stack_base,
static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
caddr_t *params);
static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
-static void exec_linux_setregs(struct thread *td, u_long entry,
- u_long stack, u_long ps_strings);
+static void exec_linux_setregs(struct thread *td,
+ struct image_params *imgp, u_long stack);
static register_t *linux_copyout_strings(struct image_params *imgp);
static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel);
@@ -927,12 +927,11 @@ exec_linux_imgact_try(struct image_params *imgp)
* override the exec_setregs default(s) here.
*/
static void
-exec_linux_setregs(struct thread *td, u_long entry,
- u_long stack, u_long ps_strings)
+exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct pcb *pcb = td->td_pcb;
- exec_setregs(td, entry, stack, ps_strings);
+ exec_setregs(td, imgp, stack);
/* Linux sets %gs to 0, we default to _udatasel */
pcb->pcb_gs = 0;
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index d408e97..76a919f 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include "opt_cpu.h"
#include "opt_kstack_pages.h"
#include "opt_mp_watchdog.h"
+#include "opt_pmap.h"
#include "opt_sched.h"
#include "opt_smp.h"
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index ae4d4aa..40e36be 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -3718,6 +3718,34 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
return (rv);
}
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+ pv_entry_t pv;
+ pt_entry_t *pte;
+ pmap_t pmap;
+ boolean_t rv;
+
+ rv = FALSE;
+ if (m->flags & PG_FICTITIOUS)
+ return (rv);
+ sched_pin();
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ pmap = PV_PMAP(pv);
+ PMAP_LOCK(pmap);
+ pte = pmap_pte_quick(pmap, pv->pv_va);
+ rv = (*pte & (PG_A | PG_V)) == (PG_A | PG_V);
+ PMAP_UNLOCK(pmap);
+ if (rv)
+ break;
+ }
+ if (*PMAP1)
+ PT_SET_MA(PADDR1, 0);
+ sched_unpin();
+ return (rv);
+}
+
void
pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len)
{
@@ -4145,10 +4173,8 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
*/
vm_page_lock_queues();
if ((m->flags & PG_REFERENCED) ||
- pmap_ts_referenced(m)) {
+ pmap_is_referenced(m))
val |= MINCORE_REFERENCED_OTHER;
- vm_page_flag_set(m, PG_REFERENCED);
- }
vm_page_unlock_queues();
}
}
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index b64c014..cf06a29 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -20,21 +20,21 @@
#
# $FreeBSD$
-cpu ITANIUM
+cpu ITANIUM2
ident GENERIC
makeoptions DEBUG=-g # Build kernel with debug information.
options AUDIT # Security event auditing
options CD9660 # ISO 9660 Filesystem
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
-options COMPAT_FREEBSD6 # Compatible with FreeBSD6
options COMPAT_FREEBSD7 # Compatible with FreeBSD7
options DDB # Support DDB
options DEADLKRES # Enable the deadlock resolver
options FFS # Berkeley Fast Filesystem
+options FLOWTABLE # per-cpu routing cache
options GDB # Support remote GDB
options GEOM_LABEL # Provides labelization
+options INCLUDE_CONFIG_FILE # Include this file in kernel
options INET # InterNETworking
options INET6 # IPv6 communications protocols
options INVARIANTS # Enable calls of extra sanity checking
@@ -45,9 +45,11 @@ options MAC # TrustedBSD MAC Framework
options MD_ROOT # MD usable as root device
options MSDOSFS # MSDOS Filesystem
options NFSCLIENT # Network Filesystem Client
-options NFSSERVER # Network Filesystem Server
options NFSLOCKD # Network Lock Manager
+options NFSSERVER # Network Filesystem Server
options NFS_ROOT # NFS usable as root device
+options P1003_1B_SEMAPHORES # POSIX-style semaphores
+options PREEMPTION # Enable kernel thread preemption
options PRINTF_BUFR_SIZE=128 # Printf buffering to limit interspersion
options PROCFS # Process filesystem (/proc)
options PSEUDOFS # Pseudo-filesystem framework
@@ -60,15 +62,12 @@ options STACK # stack(9) support
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options SYSVSHM # SYSV-style shared memory
-options P1003_1B_SEMAPHORES # POSIX-style semaphores
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Hash-based directory lookup scheme
options UFS_GJOURNAL # Enable gjournal-based UFS journaling
options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B RT extensions
-options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
-options INCLUDE_CONFIG_FILE # Include this file in kernel
# Various "busses"
device firewire # FireWire bus code
@@ -82,20 +81,25 @@ device ata # ATA controller
device atadisk # ATA disk drives
device atapicd # ATAPI CDROM drives
device atapifd # ATAPI floppy drives
+device atapist # ATAPI tape drives
device ataraid # ATA RAID drives
# SCSI Controllers
device ahc # AHA2940 and AIC7xxx devices
device ahd # AHA39320/29320 and AIC79xx devices
+device hptiop # Highpoint RocketRaid 3xxx series
device isp # Qlogic family
device mpt # LSI-Logic MPT-Fusion
device sym # NCR/Symbios Logic
# RAID controllers interfaced to the SCSI subsystem
+device amr # AMI MegaRAID
device ciss # Compaq Smart RAID 5*
device dpt # DPT Smartcache III, IV
device iir # Intel Integrated RAID
+device ips # IBM (Adaptec) ServeRAID
device mly # Mylex AcceleRAID/eXtremeRAID
+device twa # 3ware 9000 series PATA/SATA RAID
# SCSI peripherals
device cd # CD-ROM, DVD-ROM etc.
@@ -108,11 +112,11 @@ device ses # Environmental Services (and SAF-TE)
# RAID controllers
device aac # Adaptec FSA RAID
device aacp # SCSI passthrough for aac (requires CAM)
-device amr # AMI MegaRAID
device ida # Compaq Smart RAID
device mlx # Mylex DAC960 family
# USB host controllers and peripherals
+options USB_DEBUG # enable debug msgs
device ehci # EHCI host controller
device ohci # OHCI PCI->USB interface
device uhci # UHCI PCI->USB interface
@@ -124,34 +128,58 @@ device ums # Mouse
# PCI Ethernet NICs.
device de # DEC/Intel DC21x4x (``Tulip'')
-device em # Intel PRO/1000 adapter Gigabit Ethernet Card
-device le # AMD Am7900 LANCE and Am79C9xx PCnet
+device em # Intel PRO/1000 Gigabit Ethernet Family
+device igb # Intel PRO/1000 PCIE Server Gigabit Family
+device ixgbe # Intel PRO/10GbE PCIE Ethernet Family
device txp # 3Com 3cR990 (``Typhoon'')
-device vx # 3Com 3c590, 3c595 (``Vortex'')
# PCI Ethernet NICs that use the common MII bus controller code.
+device ae # Attansic/Atheros L2 FastEthernet
+device age # Attansic/Atheros L1 Gigabit Ethernet
+device alc # Atheros AR8131/AR8132 Ethernet
+device ale # Atheros AR8121/AR8113/AR8114 Ethernet
+device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet
+device bfe # Broadcom BCM440x 10/100 Ethernet
device bge # Broadcom BCM570xx Gigabit Ethernet
-device dc # DEC/Intel 21143 and various workalikes
+device et # Agere ET1310 10/100/Gigabit Ethernet
+device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet
+device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet
+device nge # NatSemi DP83820 gigabit Ethernet
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
-device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le')
device re # RealTek 8139C+/8169/8169S/8110S
-device rl # RealTek 8129/8139
device sf # Adaptec AIC-6915 (``Starfire'')
-device sis # Silicon Integrated Systems SiS 900/SiS 7016
+device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet
+device ste # Sundance ST201 (D-Link DFE-550TX)
+device stge # Sundance/Tamarack TC9021 gigabit Ethernet
+device tx # SMC EtherPower II (83c170 ``EPIC'')
+device vge # VIA VT612x gigabit Ethernet
device xl # 3Com 3c90x ("Boomerang", "Cyclone")
# USB Ethernet
device aue # ADMtek USB Ethernet
+device axe # ASIX Electronics USB Ethernet
device cdce # Generic USB over Ethernet
device cue # CATC USB Ethernet
device kue # Kawasaki LSI USB Ethernet
+device rue # RealTek RTL8150 USB Ethernet
+device udav # Davicom DM9601E USB
+
+# USB Serial
+device uark # Technologies ARK3116 based serial adapters
+device ubsa # Belkin F5U103 and compatible serial adapters
+device uftdi # For FTDI usb serial adapters
+device uipaq # Some WinCE based devices
+device uplcom # Prolific PL-2303 serial adapters
+device uslcom # SI Labs CP2101/CP2102 serial adapters
+device uvisor # Visor and Palm devices
+device uvscom # USB serial support for DDI pocket's PHS
# FireWire support
+device fwip # IP over FireWire (RFC 2734,3146)
device sbp # SCSI over FireWire (need scbus & da)
# Various (pseudo) devices
device ether # Ethernet support
-device vlan # 802.1Q VLAN support
device faith # IPv6-to-IPv4 relaying (translation)
device gif # IPv6 and IPv4 tunneling
device loop # Network loopback
@@ -161,6 +189,7 @@ device puc # Multi I/O cards and multi-channel UARTs
device random # Entropy device
device tun # Packet tunnel.
device uart # Serial port (UART)
+device vlan # 802.1Q VLAN support
device firmware # firmware assist module
# The `bpf' device enables the Berkeley Packet Filter.
diff --git a/sys/ia64/conf/NOTES b/sys/ia64/conf/NOTES
index 873199a..3f38218 100644
--- a/sys/ia64/conf/NOTES
+++ b/sys/ia64/conf/NOTES
@@ -12,10 +12,10 @@
cpu ITANIUM
cpu ITANIUM2
-# option: COMPAT_IA32
+# option: COMPAT_FREEBSD32
# This option enables the support for execution of i386 (32-bit) programs on
# ia64. It is based on the ia32 emulation in the processor.
-options COMPAT_IA32
+options COMPAT_FREEBSD32
# option: LOG2_ID_PAGE_SIZE
# Specify the log2 size of the identity (direct) mappings in regions 6 and 7
diff --git a/sys/ia64/ia32/ia32_signal.c b/sys/ia64/ia32/ia32_signal.c
index a981c84..e5eee41 100644
--- a/sys/ia64/ia32/ia32_signal.c
+++ b/sys/ia64/ia32/ia32_signal.c
@@ -120,7 +120,7 @@ freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap)
void
-ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf = td->td_frame;
vm_offset_t gdt, ldt;
@@ -129,7 +129,7 @@ ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
struct segment_descriptor desc;
struct vmspace *vmspace = td->td_proc->p_vmspace;
- exec_setregs(td, entry, stack, ps_strings);
+ exec_setregs(td, imgp, stack);
/* Non-syscall frames are cleared by exec_setregs() */
if (tf->tf_flags & FRAME_SYSCALL) {
diff --git a/sys/ia64/ia64/autoconf.c b/sys/ia64/ia64/autoconf.c
index 5a380516..cf073c8 100644
--- a/sys/ia64/ia64/autoconf.c
+++ b/sys/ia64/ia64/autoconf.c
@@ -39,15 +39,9 @@
#include <sys/bus.h>
#include <sys/cons.h>
-#include <machine/md_var.h>
#include <machine/bootinfo.h>
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_periph.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/cam_debug.h>
+#include <machine/intr.h>
+#include <machine/md_var.h>
static void configure_first(void *);
static void configure(void *);
@@ -97,12 +91,9 @@ static void
configure_final(void *dummy)
{
- /*
- * Now we're ready to handle (pending) interrupts.
- * XXX this is slightly misplaced.
- */
- enable_intr();
-
cninit_finish();
+
+ ia64_enable_intr();
+
cold = 0;
}
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c
index a9c39fc..33dbb2e 100644
--- a/sys/ia64/ia64/clock.c
+++ b/sys/ia64/ia64/clock.c
@@ -29,19 +29,42 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/priority.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
-#include <sys/bus.h>
#include <sys/timetc.h>
#include <sys/pcpu.h>
-#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/efi.h>
+#include <machine/intr.h>
+#include <machine/intrcnt.h>
#include <machine/md_var.h>
+#include <machine/smp.h>
+
+SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
+
+static int adjust_edges = 0;
+SYSCTL_INT(_debug_clock, OID_AUTO, adjust_edges, CTLFLAG_RD,
+ &adjust_edges, 0, "Number of times ITC got more than 12.5% behind");
+
+static int adjust_excess = 0;
+SYSCTL_INT(_debug_clock, OID_AUTO, adjust_excess, CTLFLAG_RD,
+ &adjust_excess, 0, "Total number of ignored ITC interrupts");
+
+static int adjust_lost = 0;
+SYSCTL_INT(_debug_clock, OID_AUTO, adjust_lost, CTLFLAG_RD,
+ &adjust_lost, 0, "Total number of lost ITC interrupts");
-uint64_t ia64_clock_reload;
+static int adjust_ticks = 0;
+SYSCTL_INT(_debug_clock, OID_AUTO, adjust_ticks, CTLFLAG_RD,
+ &adjust_ticks, 0, "Total number of ITC interrupts with adjustment");
+
+static u_int ia64_clock_xiv;
+static uint64_t ia64_clock_reload;
#ifndef SMP
static timecounter_get_t ia64_get_timecount;
@@ -54,26 +77,80 @@ static struct timecounter ia64_timecounter = {
"ITC" /* name */
};
-static unsigned
+static u_int
ia64_get_timecount(struct timecounter* tc)
{
return ia64_get_itc();
}
#endif
-void
-pcpu_initclock(void)
+static u_int
+ia64_ih_clock(struct thread *td, u_int xiv, struct trapframe *tf)
{
+ uint64_t adj, clk, itc;
+ int64_t delta;
+ int count;
- PCPU_SET(md.clockadj, 0);
- PCPU_SET(md.clock, ia64_get_itc());
- ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
- ia64_set_itv(CLOCK_VECTOR); /* highest priority class */
- ia64_srlz_d();
+ PCPU_INC(md.stats.pcs_nclks);
+
+ if (PCPU_GET(cpuid) == 0) {
+ /*
+ * Clock processing on the BSP.
+ */
+ intrcnt[INTRCNT_CLOCK]++;
+
+ itc = ia64_get_itc();
+
+ adj = PCPU_GET(md.clockadj);
+ clk = PCPU_GET(md.clock);
+
+ delta = itc - clk;
+ count = 0;
+ while (delta >= ia64_clock_reload) {
+#ifdef SMP
+ ipi_all_but_self(ia64_clock_xiv);
+#endif
+ hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
+ if (profprocs != 0)
+ profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
+ statclock(TRAPF_USERMODE(tf));
+ delta -= ia64_clock_reload;
+ clk += ia64_clock_reload;
+ if (adj != 0)
+ adjust_ticks++;
+ count++;
+ }
+ ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
+ ia64_srlz_d();
+ if (count > 0) {
+ adjust_lost += count - 1;
+ if (delta > (ia64_clock_reload >> 3)) {
+ if (adj == 0)
+ adjust_edges++;
+ adj = ia64_clock_reload >> 4;
+ } else
+ adj = 0;
+ } else {
+ adj = 0;
+ adjust_excess++;
+ }
+ PCPU_SET(md.clock, clk);
+ PCPU_SET(md.clockadj, adj);
+ } else {
+ /*
+ * Clock processing on the BSP.
+ */
+ hardclock_cpu(TRAPF_USERMODE(tf));
+ if (profprocs != 0)
+ profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
+ statclock(TRAPF_USERMODE(tf));
+ }
+
+ return (0);
}
/*
- * Start the real-time and statistics clocks. We use cr.itc and cr.itm
+ * Start the real-time and statistics clocks. We use ar.itc and cr.itm
* to implement a 1000hz clock.
*/
void
@@ -81,6 +158,11 @@ cpu_initclocks()
{
u_long itc_freq;
+ ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI,
+ ia64_ih_clock);
+ if (ia64_clock_xiv == 0)
+ panic("No XIV for clock interrupts");
+
itc_freq = (u_long)ia64_itc_freq() * 1000000ul;
stathz = hz;
@@ -91,7 +173,11 @@ cpu_initclocks()
tc_init(&ia64_timecounter);
#endif
- pcpu_initclock();
+ PCPU_SET(md.clockadj, 0);
+ PCPU_SET(md.clock, ia64_get_itc());
+ ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
+ ia64_set_itv(ia64_clock_xiv);
+ ia64_srlz_d();
}
void
diff --git a/sys/ia64/ia64/db_machdep.c b/sys/ia64/ia64/db_machdep.c
index d1163cb..2684bfe 100644
--- a/sys/ia64/ia64/db_machdep.c
+++ b/sys/ia64/ia64/db_machdep.c
@@ -577,6 +577,13 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
void
db_show_mdpcpu(struct pcpu *pc)
{
+ struct pcpu_md *md = &pc->pc_md;
+
+ db_printf("MD: vhpt = %#lx\n", md->vhpt);
+ db_printf("MD: lid = %#lx\n", md->lid);
+ db_printf("MD: clock = %#lx/%#lx\n", md->clock, md->clockadj);
+ db_printf("MD: stats = %p\n", &md->stats);
+ db_printf("MD: pmap = %p\n", md->current_pmap);
}
void
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
index 3a4ac03..4464a88 100644
--- a/sys/ia64/ia64/exception.S
+++ b/sys/ia64/ia64/exception.S
@@ -676,7 +676,7 @@ ivt_##name: \
#define IVT_END(name) \
.endp ivt_##name
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#define IA32_TRAP ia32_trap
#else
#define IA32_TRAP trap
@@ -1303,7 +1303,7 @@ IVT_END(Break_Instruction)
IVT_ENTRY(External_Interrupt, 0x3000)
{ .mib
- mov r17=cr.ivr // Put the vector in the trap frame.
+ mov r17=ar.itc // Put the ITC in the trapframe.
mov r16=ip
br.sptk exception_save
;;
@@ -1317,7 +1317,7 @@ IVT_ENTRY(External_Interrupt, 0x3000)
{ .mib
add out0=16,sp
nop 0
- br.call.sptk rp=interrupt
+ br.call.sptk rp=ia64_handle_intr
;;
}
{ .mib
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 9f76252..d81054b 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -61,8 +61,8 @@
#include <net/if.h>
#include <netinet/in.h>
-#ifdef COMPAT_IA32
-ASSYM(COMPAT_IA32, COMPAT_IA32);
+#ifdef COMPAT_FREEBSD32
+ASSYM(COMPAT_FREEBSD32, COMPAT_FREEBSD32);
#endif
ASSYM(DT_NULL, DT_NULL);
diff --git a/sys/ia64/ia64/highfp.c b/sys/ia64/ia64/highfp.c
index 145ee48..f18773b 100644
--- a/sys/ia64/ia64/highfp.c
+++ b/sys/ia64/ia64/highfp.c
@@ -53,7 +53,7 @@ ia64_highfp_ipi(struct pcpu *cpu)
{
int error;
- ipi_send(cpu, IPI_HIGH_FP);
+ ipi_send(cpu, ia64_ipi_highfp);
error = msleep_spin(&cpu->pc_fpcurthread, &ia64_highfp_mtx,
"High FP", 0);
return (error);
@@ -92,8 +92,6 @@ ia64_highfp_enable(struct thread *td, struct trapframe *tf)
pcb = td->td_pcb;
mtx_lock_spin(&ia64_highfp_mtx);
- KASSERT((tf->tf_special.psr & IA64_PSR_DFH) != 0,
- ("(tf->tf_special.psr & IA64_PSR_DFH) == 0"));
cpu = pcb->pcb_fpcpu;
#ifdef SMP
if (cpu != NULL && cpu != pcpup) {
diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c
index a9bee27..adb16ec 100644
--- a/sys/ia64/ia64/interrupt.c
+++ b/sys/ia64/ia64/interrupt.c
@@ -43,6 +43,7 @@
#include <sys/proc.h>
#include <sys/vmmeter.h>
#include <sys/bus.h>
+#include <sys/interrupt.h>
#include <sys/malloc.h>
#include <sys/ktr.h>
#include <sys/lock.h>
@@ -52,46 +53,20 @@
#include <sys/sysctl.h>
#include <sys/syslog.h>
-#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/fpu.h>
#include <machine/frame.h>
#include <machine/intr.h>
+#include <machine/intrcnt.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <machine/smp.h>
-#ifdef EVCNT_COUNTERS
-struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */
-#else
-#include <sys/interrupt.h>
-#include <machine/intrcnt.h>
-#endif
-
#ifdef DDB
#include <ddb/ddb.h>
#endif
-SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
-
-static int adjust_edges = 0;
-SYSCTL_INT(_debug_clock, OID_AUTO, adjust_edges, CTLFLAG_RD,
- &adjust_edges, 0, "Number of times ITC got more than 12.5% behind");
-
-static int adjust_excess = 0;
-SYSCTL_INT(_debug_clock, OID_AUTO, adjust_excess, CTLFLAG_RD,
- &adjust_excess, 0, "Total number of ignored ITC interrupts");
-
-static int adjust_lost = 0;
-SYSCTL_INT(_debug_clock, OID_AUTO, adjust_lost, CTLFLAG_RD,
- &adjust_lost, 0, "Total number of lost ITC interrupts");
-
-static int adjust_ticks = 0;
-SYSCTL_INT(_debug_clock, OID_AUTO, adjust_ticks, CTLFLAG_RD,
- &adjust_ticks, 0, "Total number of ITC interrupts with adjustment");
-
-
struct ia64_intr {
struct intr_event *event; /* interrupt event */
volatile long *cntp; /* interrupt counter */
@@ -99,190 +74,120 @@ struct ia64_intr {
u_int irq;
};
-static struct ia64_intr *ia64_intrs[256];
+ia64_ihtype *ia64_handler[IA64_NXIVS];
+static enum ia64_xiv_use ia64_xiv[IA64_NXIVS];
+static struct ia64_intr *ia64_intrs[IA64_NXIVS];
-static void ia64_dispatch_intr(void *, u_int);
+static ia64_ihtype ia64_ih_invalid;
+static ia64_ihtype ia64_ih_irq;
void
-interrupt(struct trapframe *tf)
+ia64_xiv_init(void)
{
- struct thread *td;
- uint64_t adj, clk, itc;
- int64_t delta;
- u_int vector;
- int count;
- uint8_t inta;
+ u_int xiv;
- ia64_set_fpsr(IA64_FPSR_DEFAULT);
+ for (xiv = 0; xiv < IA64_NXIVS; xiv++) {
+ ia64_handler[xiv] = ia64_ih_invalid;
+ ia64_xiv[xiv] = IA64_XIV_FREE;
+ ia64_intrs[xiv] = NULL;
+ }
+ (void)ia64_xiv_reserve(15, IA64_XIV_ARCH, NULL);
+}
- td = curthread;
+int
+ia64_xiv_free(u_int xiv, enum ia64_xiv_use what)
+{
- PCPU_INC(cnt.v_intr);
+ if (xiv >= IA64_NXIVS)
+ return (EINVAL);
+ if (what == IA64_XIV_FREE || what == IA64_XIV_ARCH)
+ return (EINVAL);
+ if (ia64_xiv[xiv] != what)
+ return (ENXIO);
+ ia64_xiv[xiv] = IA64_XIV_FREE;
+ ia64_handler[xiv] = ia64_ih_invalid;
+ return (0);
+}
- vector = tf->tf_special.ifa;
+int
+ia64_xiv_reserve(u_int xiv, enum ia64_xiv_use what, ia64_ihtype ih)
+{
- next:
- /*
- * Handle ExtINT interrupts by generating an INTA cycle to
- * read the vector.
- */
- if (vector == 0) {
- PCPU_INC(md.stats.pcs_nextints);
- inta = ia64_ld1(&ia64_pib->ib_inta);
- if (inta == 15) {
- PCPU_INC(md.stats.pcs_nstrays);
- __asm __volatile("mov cr.eoi = r0;; srlz.d");
- goto stray;
- }
- vector = (int)inta;
- } else if (vector == 15) {
- PCPU_INC(md.stats.pcs_nstrays);
- goto stray;
- }
+ if (xiv >= IA64_NXIVS)
+ return (EINVAL);
+ if (what == IA64_XIV_FREE)
+ return (EINVAL);
+ if (ia64_xiv[xiv] != IA64_XIV_FREE)
+ return (EBUSY);
+ ia64_xiv[xiv] = what;
+ ia64_handler[xiv] = (ih == NULL) ? ia64_ih_invalid: ih;
+ if (bootverbose)
+ printf("XIV %u: use=%u, IH=%p\n", xiv, what, ih);
+ return (0);
+}
+
+u_int
+ia64_xiv_alloc(u_int prio, enum ia64_xiv_use what, ia64_ihtype ih)
+{
+ u_int hwprio;
+ u_int xiv0, xiv;
- if (vector == CLOCK_VECTOR) {/* clock interrupt */
- /* CTR0(KTR_INTR, "clock interrupt"); */
+ hwprio = prio >> 2;
+ if (hwprio > IA64_MAX_HWPRIO)
+ hwprio = IA64_MAX_HWPRIO;
- itc = ia64_get_itc();
+ xiv0 = IA64_NXIVS - (hwprio + 1) * 16;
- PCPU_INC(md.stats.pcs_nclks);
-#ifdef EVCNT_COUNTERS
- clock_intr_evcnt.ev_count++;
-#else
- intrcnt[INTRCNT_CLOCK]++;
-#endif
+ KASSERT(xiv0 >= IA64_MIN_XIV, ("%s: min XIV", __func__));
+ KASSERT(xiv0 < IA64_NXIVS, ("%s: max XIV", __func__));
- critical_enter();
-
- adj = PCPU_GET(md.clockadj);
- clk = PCPU_GET(md.clock);
- delta = itc - clk;
- count = 0;
- while (delta >= ia64_clock_reload) {
- /* Only the BSP runs the real clock */
- if (PCPU_GET(cpuid) == 0)
- hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
- else
- hardclock_cpu(TRAPF_USERMODE(tf));
- if (profprocs != 0)
- profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
- statclock(TRAPF_USERMODE(tf));
- delta -= ia64_clock_reload;
- clk += ia64_clock_reload;
- if (adj != 0)
- adjust_ticks++;
- count++;
- }
- ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
- if (count > 0) {
- adjust_lost += count - 1;
- if (delta > (ia64_clock_reload >> 3)) {
- if (adj == 0)
- adjust_edges++;
- adj = ia64_clock_reload >> 4;
- } else
- adj = 0;
- } else {
- adj = 0;
- adjust_excess++;
- }
- PCPU_SET(md.clock, clk);
- PCPU_SET(md.clockadj, adj);
- critical_exit();
- ia64_srlz_d();
+ xiv = xiv0;
+ while (xiv < IA64_NXIVS && ia64_xiv_reserve(xiv, what, ih))
+ xiv++;
-#ifdef SMP
- } else if (vector == ipi_vector[IPI_AST]) {
- PCPU_INC(md.stats.pcs_nasts);
- CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid));
- } else if (vector == ipi_vector[IPI_HIGH_FP]) {
- PCPU_INC(md.stats.pcs_nhighfps);
- ia64_highfp_save_ipi();
- } else if (vector == ipi_vector[IPI_RENDEZVOUS]) {
- PCPU_INC(md.stats.pcs_nrdvs);
- CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid));
- enable_intr();
- smp_rendezvous_action();
- disable_intr();
- } else if (vector == ipi_vector[IPI_STOP]) {
- PCPU_INC(md.stats.pcs_nstops);
- cpumask_t mybit = PCPU_GET(cpumask);
-
- /* Make sure IPI_STOP_HARD is mapped to IPI_STOP. */
- KASSERT(IPI_STOP == IPI_STOP_HARD,
- ("%s: IPI_STOP_HARD not handled.", __func__));
-
- savectx(PCPU_PTR(md.pcb));
- atomic_set_int(&stopped_cpus, mybit);
- while ((started_cpus & mybit) == 0)
- cpu_spinwait();
- atomic_clear_int(&started_cpus, mybit);
- atomic_clear_int(&stopped_cpus, mybit);
- } else if (vector == ipi_vector[IPI_PREEMPT]) {
- PCPU_INC(md.stats.pcs_npreempts);
- CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid));
- __asm __volatile("mov cr.eoi = r0;; srlz.d");
- enable_intr();
- sched_preempt(curthread);
- disable_intr();
- goto stray;
-#endif
- } else {
- PCPU_INC(md.stats.pcs_nhwints);
- atomic_add_int(&td->td_intr_nesting_level, 1);
- ia64_dispatch_intr(tf, vector);
- atomic_subtract_int(&td->td_intr_nesting_level, 1);
- }
+ if (xiv < IA64_NXIVS)
+ return (xiv);
- __asm __volatile("mov cr.eoi = r0;; srlz.d");
- vector = ia64_get_ivr();
- if (vector != 15)
- goto next;
+ xiv = xiv0;
+ while (xiv >= IA64_MIN_XIV && ia64_xiv_reserve(xiv, what, ih))
+ xiv--;
-stray:
- if (TRAPF_USERMODE(tf)) {
- enable_intr();
- userret(td, tf);
- mtx_assert(&Giant, MA_NOTOWNED);
- do_ast(tf);
- }
+ return ((xiv >= IA64_MIN_XIV) ? xiv : 0);
}
-
static void
ia64_intr_eoi(void *arg)
{
- u_int vector = (uintptr_t)arg;
+ u_int xiv = (uintptr_t)arg;
struct ia64_intr *i;
- i = ia64_intrs[vector];
- if (i != NULL)
- sapic_eoi(i->sapic, vector);
+ i = ia64_intrs[xiv];
+ KASSERT(i != NULL, ("%s", __func__));
+ sapic_eoi(i->sapic, xiv);
}
static void
ia64_intr_mask(void *arg)
{
- u_int vector = (uintptr_t)arg;
+ u_int xiv = (uintptr_t)arg;
struct ia64_intr *i;
- i = ia64_intrs[vector];
- if (i != NULL) {
- sapic_mask(i->sapic, i->irq);
- sapic_eoi(i->sapic, vector);
- }
+ i = ia64_intrs[xiv];
+ KASSERT(i != NULL, ("%s", __func__));
+ sapic_mask(i->sapic, i->irq);
+ sapic_eoi(i->sapic, xiv);
}
static void
ia64_intr_unmask(void *arg)
{
- u_int vector = (uintptr_t)arg;
+ u_int xiv = (uintptr_t)arg;
struct ia64_intr *i;
- i = ia64_intrs[vector];
- if (i != NULL)
- sapic_unmask(i->sapic, i->irq);
+ i = ia64_intrs[xiv];
+ KASSERT(i != NULL, ("%s", __func__));
+ sapic_unmask(i->sapic, i->irq);
}
int
@@ -292,7 +197,7 @@ ia64_setup_intr(const char *name, int irq, driver_filter_t filter,
struct ia64_intr *i;
struct sapic *sa;
char *intrname;
- u_int prio, vector;
+ u_int prio, xiv;
int error;
prio = intr_priority(flags);
@@ -301,37 +206,41 @@ ia64_setup_intr(const char *name, int irq, driver_filter_t filter,
/* XXX lock */
- /* Get the I/O SAPIC and vector that corresponds to the IRQ. */
- sa = sapic_lookup(irq, &vector);
+ /* Get the I/O SAPIC and XIV that corresponds to the IRQ. */
+ sa = sapic_lookup(irq, &xiv);
if (sa == NULL) {
/* XXX unlock */
return (EINVAL);
}
- if (vector == 0) {
+ if (xiv == 0) {
/* XXX unlock */
i = malloc(sizeof(struct ia64_intr), M_DEVBUF,
M_ZERO | M_WAITOK);
/* XXX lock */
- sa = sapic_lookup(irq, &vector);
+ sa = sapic_lookup(irq, &xiv);
KASSERT(sa != NULL, ("sapic_lookup"));
- if (vector != 0)
+ if (xiv != 0)
free(i, M_DEVBUF);
}
/*
- * If the IRQ has no vector assigned to it yet, assign one based
+ * If the IRQ has no XIV assigned to it yet, assign one based
* on the priority.
*/
- if (vector == 0) {
- vector = (256 - 64) - (prio << 1);
- while (vector < 256 && ia64_intrs[vector] != NULL)
- vector++;
+ if (xiv == 0) {
+ xiv = ia64_xiv_alloc(prio, IA64_XIV_IRQ, ia64_ih_irq);
+ if (xiv == 0) {
+ /* XXX unlock */
+ free(i, M_DEVBUF);
+ return (ENOSPC);
+ }
- error = intr_event_create(&i->event, (void *)(uintptr_t)vector,
+ error = intr_event_create(&i->event, (void *)(uintptr_t)xiv,
0, irq, ia64_intr_mask, ia64_intr_unmask, ia64_intr_eoi,
NULL, "irq%u:", irq);
if (error) {
+ ia64_xiv_free(xiv, IA64_XIV_IRQ);
/* XXX unlock */
free(i, M_DEVBUF);
return (error);
@@ -339,25 +248,25 @@ ia64_setup_intr(const char *name, int irq, driver_filter_t filter,
i->sapic = sa;
i->irq = irq;
- i->cntp = intrcnt + irq + INTRCNT_ISA_IRQ;
- ia64_intrs[vector] = i;
- sapic_enable(sa, irq, vector);
+ i->cntp = intrcnt + xiv;
+ ia64_intrs[xiv] = i;
/* XXX unlock */
+ sapic_enable(sa, irq, xiv);
+
if (name != NULL && *name != '\0') {
/* XXX needs abstraction. Too error prone. */
- intrname = intrnames +
- (irq + INTRCNT_ISA_IRQ) * INTRNAME_LEN;
+ intrname = intrnames + xiv * INTRNAME_LEN;
memset(intrname, ' ', INTRNAME_LEN - 1);
bcopy(name, intrname, strlen(name));
}
} else {
- i = ia64_intrs[vector];
+ i = ia64_intrs[xiv];
/* XXX unlock */
}
- KASSERT(i != NULL, ("vector mapping bug"));
+ KASSERT(i != NULL, ("XIV mapping bug"));
error = intr_event_add_handler(i->event, name, filter, handler, arg,
prio, flags, cookiep);
@@ -371,62 +280,134 @@ ia64_teardown_intr(void *cookie)
return (intr_event_remove_handler(cookie));
}
-static void
-ia64_dispatch_intr(void *frame, u_int vector)
+void
+ia64_bind_intr(void)
+{
+ struct ia64_intr *i;
+ struct pcpu *pc;
+ u_int xiv;
+ int cpu;
+
+ cpu = MAXCPU;
+ for (xiv = IA64_NXIVS - 1; xiv >= IA64_MIN_XIV; xiv--) {
+ if (ia64_xiv[xiv] != IA64_XIV_IRQ)
+ continue;
+ i = ia64_intrs[xiv];
+ do {
+ cpu = (cpu == 0) ? MAXCPU - 1 : cpu - 1;
+ pc = cpuid_to_pcpu[cpu];
+ } while (pc == NULL || !pc->pc_md.awake);
+ sapic_bind_intr(i->irq, pc);
+ }
+}
+
+/*
+ * Interrupt handlers.
+ */
+
+void
+ia64_handle_intr(struct trapframe *tf)
+{
+ struct thread *td;
+ u_int xiv;
+
+ td = curthread;
+ ia64_set_fpsr(IA64_FPSR_DEFAULT);
+ PCPU_INC(cnt.v_intr);
+
+ xiv = ia64_get_ivr();
+ ia64_srlz_d();
+ if (xiv == 15) {
+ PCPU_INC(md.stats.pcs_nstrays);
+ goto out;
+ }
+
+ critical_enter();
+
+ do {
+ CTR2(KTR_INTR, "INTR: ITC=%u, XIV=%u",
+ (u_int)tf->tf_special.ifa, xiv);
+ (ia64_handler[xiv])(td, xiv, tf);
+ ia64_set_eoi(0);
+ ia64_srlz_d();
+ xiv = ia64_get_ivr();
+ ia64_srlz_d();
+ } while (xiv != 15);
+
+ critical_exit();
+
+ out:
+ if (TRAPF_USERMODE(tf)) {
+ while (td->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) {
+ ia64_enable_intr();
+ ast(tf);
+ ia64_disable_intr();
+ }
+ }
+}
+
+static u_int
+ia64_ih_invalid(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+
+ panic("invalid XIV: %u", xiv);
+ return (0);
+}
+
+static u_int
+ia64_ih_irq(struct thread *td, u_int xiv, struct trapframe *tf)
{
struct ia64_intr *i;
struct intr_event *ie; /* our interrupt event */
- /*
- * Find the interrupt thread for this vector.
- */
- i = ia64_intrs[vector];
- KASSERT(i != NULL, ("%s: unassigned vector", __func__));
+ PCPU_INC(md.stats.pcs_nhwints);
+
+ /* Find the interrupt thread for this XIV. */
+ i = ia64_intrs[xiv];
+ KASSERT(i != NULL, ("%s: unassigned XIV", __func__));
(*i->cntp)++;
ie = i->event;
KASSERT(ie != NULL, ("%s: interrupt without event", __func__));
- if (intr_event_handle(ie, frame) != 0) {
- /*
- * XXX: The pre-INTR_FILTER code didn't mask stray
- * interrupts.
- */
- ia64_intr_mask((void *)(uintptr_t)vector);
+ if (intr_event_handle(ie, tf) != 0) {
+ ia64_intr_mask((void *)(uintptr_t)xiv);
log(LOG_ERR, "stray irq%u\n", i->irq);
}
+
+ return (0);
}
#ifdef DDB
static void
-db_print_vector(u_int vector, int always)
+db_print_xiv(u_int xiv, int always)
{
struct ia64_intr *i;
- i = ia64_intrs[vector];
+ i = ia64_intrs[xiv];
if (i != NULL) {
- db_printf("vector %u (%p): ", vector, i);
+ db_printf("XIV %u (%p): ", xiv, i);
sapic_print(i->sapic, i->irq);
} else if (always)
- db_printf("vector %u: unassigned\n", vector);
+ db_printf("XIV %u: unassigned\n", xiv);
}
-DB_SHOW_COMMAND(vector, db_show_vector)
+DB_SHOW_COMMAND(xiv, db_show_xiv)
{
- u_int vector;
+ u_int xiv;
if (have_addr) {
- vector = ((addr >> 4) % 16) * 10 + (addr % 16);
- if (vector >= 256)
- db_printf("error: vector %u not in range [0..255]\n",
- vector);
+ xiv = ((addr >> 4) % 16) * 10 + (addr % 16);
+ if (xiv >= IA64_NXIVS)
+ db_printf("error: XIV %u not in range [0..%u]\n",
+ xiv, IA64_NXIVS - 1);
else
- db_print_vector(vector, 1);
+ db_print_xiv(xiv, 1);
} else {
- for (vector = 0; vector < 256; vector++)
- db_print_vector(vector, 0);
+ for (xiv = 0; xiv < IA64_NXIVS; xiv++)
+ db_print_xiv(xiv, 0);
}
}
diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S
index afba834..ce66dca 100644
--- a/sys/ia64/ia64/locore.S
+++ b/sys/ia64/ia64/locore.S
@@ -26,16 +26,13 @@
* $FreeBSD$
*/
+#include <sys/syscall.h>
#include <machine/asm.h>
#include <machine/ia64_cpu.h>
+#include <machine/intrcnt.h>
#include <machine/pte.h>
-#include <sys/syscall.h>
-#include <assym.s>
-
-#ifndef EVCNT_COUNTERS
-#define _LOCORE
#include <machine/intrcnt.h>
-#endif
+#include <assym.s>
.section .data.proc0,"aw"
.global kstack
@@ -310,7 +307,7 @@ EXPORT(intrnames)
.ascii "clock"
.fill INTRNAME_LEN - 5 - 1, 1, ' '
.byte 0
-intr_n = 0
+intr_n = 1
.rept INTRCNT_COUNT - 1
.ascii "#"
.byte intr_n / 100 + '0'
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index cddf6c0..c13adc3 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_pager.h>
#include <machine/bootinfo.h>
-#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/efi.h>
#include <machine/elf.h>
@@ -100,8 +99,6 @@ __FBSDID("$FreeBSD$");
#include <machine/unwind.h>
#include <machine/vmparam.h>
-#include <i386/include/specialreg.h>
-
SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, "");
SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, "");
@@ -374,7 +371,7 @@ cpu_startup(void *dummy)
SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
"nstrays", CTLFLAG_RD, &pcs->pcs_nstrays,
- "Number of stray vectors");
+ "Number of stray interrupts");
}
}
SYSINIT(cpu_startup, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
@@ -443,25 +440,29 @@ cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx)
struct pcb *oldpcb, *newpcb;
oldpcb = old->td_pcb;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
ia32_savectx(oldpcb);
#endif
if (PCPU_GET(fpcurthread) == old)
old->td_frame->tf_special.psr |= IA64_PSR_DFH;
if (!savectx(oldpcb)) {
atomic_store_rel_ptr(&old->td_lock, mtx);
-#if defined(SCHED_ULE) && defined(SMP)
- /* td_lock is volatile */
- while (new->td_lock == &blocked_lock)
- ;
-#endif
+
newpcb = new->td_pcb;
oldpcb->pcb_current_pmap =
pmap_switch(newpcb->pcb_current_pmap);
+
+#if defined(SCHED_ULE) && defined(SMP)
+ while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock)
+ cpu_spinwait();
+#endif
+
PCPU_SET(curthread, new);
-#ifdef COMPAT_IA32
+
+#ifdef COMPAT_FREEBSD32
ia32_restorectx(newpcb);
#endif
+
if (PCPU_GET(fpcurthread) == new)
new->td_frame->tf_special.psr &= ~IA64_PSR_DFH;
restorectx(newpcb);
@@ -478,10 +479,18 @@ cpu_throw(struct thread *old __unused, struct thread *new)
newpcb = new->td_pcb;
(void)pmap_switch(newpcb->pcb_current_pmap);
+
+#if defined(SCHED_ULE) && defined(SMP)
+ while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock)
+ cpu_spinwait();
+#endif
+
PCPU_SET(curthread, new);
-#ifdef COMPAT_IA32
+
+#ifdef COMPAT_FREEBSD32
ia32_restorectx(newpcb);
#endif
+
restorectx(newpcb);
/* We should not get here. */
panic("cpu_throw: restorectx() returned");
@@ -709,16 +718,6 @@ ia64_init(void)
*/
boothowto = bootinfo.bi_boothowto;
- /*
- * Catch case of boot_verbose set in environment.
- */
- if ((p = getenv("boot_verbose")) != NULL) {
- if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) {
- boothowto |= RB_VERBOSE;
- }
- freeenv(p);
- }
-
if (boothowto & RB_VERBOSE)
bootverbose = 1;
@@ -772,6 +771,7 @@ ia64_init(void)
*/
map_pal_code();
efi_boot_minimal(bootinfo.bi_systab);
+ ia64_xiv_init();
ia64_sal_init();
calculate_frequencies();
@@ -786,7 +786,7 @@ ia64_init(void)
init_param1();
p = getenv("kernelname");
- if (p) {
+ if (p != NULL) {
strncpy(kernelname, p, sizeof(kernelname) - 1);
freeenv(p);
}
@@ -1328,7 +1328,7 @@ set_mcontext(struct thread *td, const mcontext_t *mc)
* Clear registers on exec.
*/
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf;
uint64_t *ksttop, *kst;
@@ -1366,7 +1366,7 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
*kst-- = 0;
if (((uintptr_t)kst & 0x1ff) == 0x1f8)
*kst-- = 0;
- *kst-- = ps_strings;
+ *kst-- = imgp->ps_strings;
if (((uintptr_t)kst & 0x1ff) == 0x1f8)
*kst-- = 0;
*kst = stack;
@@ -1381,11 +1381,11 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
* Assumes that (bspstore & 0x1f8) < 0x1e0.
*/
suword((caddr_t)tf->tf_special.bspstore - 24, stack);
- suword((caddr_t)tf->tf_special.bspstore - 16, ps_strings);
+ suword((caddr_t)tf->tf_special.bspstore - 16, imgp->ps_strings);
suword((caddr_t)tf->tf_special.bspstore - 8, 0);
}
- tf->tf_special.iip = entry;
+ tf->tf_special.iip = imgp->entry_addr;
tf->tf_special.sp = (stack & ~15) - 16;
tf->tf_special.rsc = 0xf;
tf->tf_special.fpsr = IA64_FPSR_DEFAULT;
diff --git a/sys/ia64/ia64/mca.c b/sys/ia64/ia64/mca.c
index e25031d..a11742a 100644
--- a/sys/ia64/ia64/mca.c
+++ b/sys/ia64/ia64/mca.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002-2010 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/mca.h>
+#include <machine/pal.h>
#include <machine/sal.h>
#include <machine/smp.h>
@@ -44,19 +45,19 @@ MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture");
struct mca_info {
STAILQ_ENTRY(mca_info) mi_link;
- char mi_name[32];
+ u_long mi_seqnr;
+ u_int mi_cpuid;
size_t mi_recsz;
char mi_record[0];
};
-static STAILQ_HEAD(, mca_info) mca_records =
- STAILQ_HEAD_INITIALIZER(mca_records);
+STAILQ_HEAD(mca_info_list, mca_info);
-int64_t mca_info_size[SAL_INFO_TYPES];
-vm_offset_t mca_info_block;
-struct mtx mca_info_block_lock;
+static int64_t mca_info_size[SAL_INFO_TYPES];
+static vm_offset_t mca_info_block;
+static struct mtx mca_info_block_lock;
-SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RW, 0, "MCA container");
+SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RW, NULL, "MCA container");
static int mca_count; /* Number of records stored. */
static int mca_first; /* First (lowest) record ID. */
@@ -69,6 +70,32 @@ SYSCTL_INT(_hw_mca, OID_AUTO, first, CTLFLAG_RD, &mca_first, 0,
SYSCTL_INT(_hw_mca, OID_AUTO, last, CTLFLAG_RD, &mca_last, 0,
"Last record id");
+static struct mtx mca_sysctl_lock;
+
+static int
+mca_sysctl_inject(SYSCTL_HANDLER_ARGS)
+{
+ struct ia64_pal_result res;
+ u_int val;
+ int error;
+
+ val = 0;
+ error = sysctl_wire_old_buffer(req, sizeof(u_int));
+ if (!error)
+ error = sysctl_handle_int(oidp, &val, 0, req);
+
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ /* For example: val=137 causes a fatal CPU error. */
+ res = ia64_call_pal_stacked(PAL_MC_ERROR_INJECT, val, 0, 0);
+ printf("%s: %#lx, %#lx, %#lx, %#lx\n", __func__, res.pal_status,
+ res.pal_result[0], res.pal_result[1], res.pal_result[2]);
+ return (0);
+}
+SYSCTL_PROC(_hw_mca, OID_AUTO, inject, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
+ mca_sysctl_inject, "I", "set to trigger a MCA");
+
static int
mca_sysctl_handler(SYSCTL_HANDLER_ARGS)
{
@@ -85,27 +112,8 @@ mca_sysctl_handler(SYSCTL_HANDLER_ARGS)
return (error);
}
-void
-ia64_mca_populate(void)
-{
- struct mca_info *rec;
-
- mtx_lock_spin(&mca_info_block_lock);
- while (!STAILQ_EMPTY(&mca_records)) {
- rec = STAILQ_FIRST(&mca_records);
- STAILQ_REMOVE_HEAD(&mca_records, mi_link);
- mtx_unlock_spin(&mca_info_block_lock);
- (void)SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca),
- OID_AUTO, rec->mi_name, CTLTYPE_OPAQUE | CTLFLAG_RD,
- rec->mi_record, rec->mi_recsz, mca_sysctl_handler, "S,MCA",
- "Error record");
- mtx_lock_spin(&mca_info_block_lock);
- }
- mtx_unlock_spin(&mca_info_block_lock);
-}
-
-void
-ia64_mca_save_state(int type)
+static void
+ia64_mca_collect_state(int type, struct mca_info_list *reclst)
{
struct ia64_sal_result result;
struct mca_record_header *hdr;
@@ -123,13 +131,13 @@ ia64_mca_save_state(int type)
if (mca_info_block == 0)
return;
- mtx_lock_spin(&mca_info_block_lock);
while (1) {
+ mtx_lock_spin(&mca_info_block_lock);
result = ia64_sal_entry(SAL_GET_STATE_INFO, type, 0,
mca_info_block, 0, 0, 0, 0);
if (result.sal_status < 0) {
mtx_unlock_spin(&mca_info_block_lock);
- return;
+ break;
}
hdr = (struct mca_record_header *)mca_info_block;
@@ -142,9 +150,10 @@ ia64_mca_save_state(int type)
M_NOWAIT | M_ZERO);
if (rec == NULL)
/* XXX: Not sure what to do. */
- return;
+ break;
- sprintf(rec->mi_name, "%lld", (long long)seqnr);
+ rec->mi_seqnr = seqnr;
+ rec->mi_cpuid = PCPU_GET(cpuid);
mtx_lock_spin(&mca_info_block_lock);
@@ -163,7 +172,6 @@ ia64_mca_save_state(int type)
if (seqnr != hdr->rh_seqnr) {
mtx_unlock_spin(&mca_info_block_lock);
free(rec, M_MCA);
- mtx_lock_spin(&mca_info_block_lock);
continue;
}
}
@@ -171,23 +179,51 @@ ia64_mca_save_state(int type)
rec->mi_recsz = recsz;
bcopy((char*)mca_info_block, rec->mi_record, recsz);
- if (mca_count > 0) {
- if (seqnr < mca_first)
- mca_first = seqnr;
- else if (seqnr > mca_last)
- mca_last = seqnr;
- } else
- mca_first = mca_last = seqnr;
-
- mca_count++;
- STAILQ_INSERT_TAIL(&mca_records, rec, mi_link);
-
/*
* Clear the state so that we get any other records when
* they exist.
*/
result = ia64_sal_entry(SAL_CLEAR_STATE_INFO, type, 0, 0, 0,
0, 0, 0);
+
+ mtx_unlock_spin(&mca_info_block_lock);
+
+ STAILQ_INSERT_TAIL(reclst, rec, mi_link);
+ }
+}
+
+void
+ia64_mca_save_state(int type)
+{
+ char name[64];
+ struct mca_info_list reclst = STAILQ_HEAD_INITIALIZER(reclst);
+ struct mca_info *rec;
+ struct sysctl_oid *oid;
+
+ ia64_mca_collect_state(type, &reclst);
+
+ STAILQ_FOREACH(rec, &reclst, mi_link) {
+ sprintf(name, "%lu", rec->mi_seqnr);
+ oid = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca),
+ OID_AUTO, name, CTLFLAG_RW, NULL, name);
+ if (oid == NULL)
+ continue;
+
+ mtx_lock(&mca_sysctl_lock);
+ if (mca_count > 0) {
+ if (rec->mi_seqnr < mca_first)
+ mca_first = rec->mi_seqnr;
+ else if (rec->mi_seqnr > mca_last)
+ mca_last = rec->mi_seqnr;
+ } else
+ mca_first = mca_last = rec->mi_seqnr;
+ mca_count++;
+ mtx_unlock(&mca_sysctl_lock);
+
+ sprintf(name, "%u", rec->mi_cpuid);
+ SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(oid), rec->mi_cpuid,
+ name, CTLTYPE_OPAQUE | CTLFLAG_RD, rec->mi_record,
+ rec->mi_recsz, mca_sysctl_handler, "S,MCA", "MCA record");
}
}
@@ -237,7 +273,14 @@ ia64_mca_init(void)
* should be rare. On top of that, performance is not an issue when
* dealing with machine checks...
*/
- mtx_init(&mca_info_block_lock, "MCA spin lock", NULL, MTX_SPIN);
+ mtx_init(&mca_info_block_lock, "MCA info lock", NULL, MTX_SPIN);
+
+ /*
+ * Serialize sysctl operations with a sleep lock. Note that this
+ * implies that we update the sysctl tree in a context that allows
+ * sleeping.
+ */
+ mtx_init(&mca_sysctl_lock, "MCA sysctl lock", NULL, MTX_DEF);
/*
* Get and save any processor and platfom error records. Note that in
diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c
index c5ed48f..05f352a 100644
--- a/sys/ia64/ia64/mp_machdep.c
+++ b/sys/ia64/ia64/mp_machdep.c
@@ -46,11 +46,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/uuid.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_kern.h>
-
#include <machine/atomic.h>
#include <machine/cpu.h>
#include <machine/fpu.h>
@@ -59,10 +54,13 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/pal.h>
#include <machine/pcb.h>
-#include <machine/pmap.h>
#include <machine/sal.h>
#include <machine/smp.h>
-#include <i386/include/specialreg.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
MALLOC_DEFINE(M_SMP, "SMP", "SMP related allocations");
@@ -81,7 +79,68 @@ volatile int ap_delay;
volatile int ap_awake;
volatile int ap_spin;
-static void cpu_mp_unleash(void *);
+int ia64_ipi_ast;
+int ia64_ipi_highfp;
+int ia64_ipi_nmi;
+int ia64_ipi_preempt;
+int ia64_ipi_rndzvs;
+int ia64_ipi_stop;
+
+static u_int
+ia64_ih_ast(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+
+ PCPU_INC(md.stats.pcs_nasts);
+ CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid));
+ return (0);
+}
+
+static u_int
+ia64_ih_highfp(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+
+ PCPU_INC(md.stats.pcs_nhighfps);
+ ia64_highfp_save_ipi();
+ return (0);
+}
+
+static u_int
+ia64_ih_preempt(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+
+ PCPU_INC(md.stats.pcs_npreempts);
+ CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid));
+ sched_preempt(curthread);
+ return (0);
+}
+
+static u_int
+ia64_ih_rndzvs(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+
+ PCPU_INC(md.stats.pcs_nrdvs);
+ CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid));
+ smp_rendezvous_action();
+ return (0);
+}
+
+static u_int
+ia64_ih_stop(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+ cpumask_t mybit;
+
+ PCPU_INC(md.stats.pcs_nstops);
+ mybit = PCPU_GET(cpumask);
+
+ savectx(PCPU_PTR(md.pcb));
+
+ atomic_set_int(&stopped_cpus, mybit);
+ while ((started_cpus & mybit) == 0)
+ cpu_spinwait();
+ atomic_clear_int(&started_cpus, mybit);
+ atomic_clear_int(&stopped_cpus, mybit);
+ return (0);
+}
struct cpu_group *
cpu_topo(void)
@@ -93,13 +152,15 @@ cpu_topo(void)
static void
ia64_store_mca_state(void* arg)
{
- unsigned int ncpu = (unsigned int)(uintptr_t)arg;
- struct thread* td;
+ struct pcpu *pc = arg;
+ struct thread *td = curthread;
- /* ia64_mca_save_state() is CPU-sensitive, so bind ourself to our target CPU */
- td = curthread;
+ /*
+ * ia64_mca_save_state() is CPU-sensitive, so bind ourself to our
+ * target CPU.
+ */
thread_lock(td);
- sched_bind(td, ncpu);
+ sched_bind(td, pc->pc_cpuid);
thread_unlock(td);
/*
@@ -116,7 +177,6 @@ void
ia64_ap_startup(void)
{
uint64_t vhpt;
- int vector;
pcpup = ap_pcpu;
ia64_set_k4((intptr_t)pcpup);
@@ -148,24 +208,11 @@ ia64_ap_startup(void)
CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid));
- /* Acknowledge and EOI all interrupts. */
- vector = ia64_get_ivr();
- while (vector != 15) {
- ia64_srlz_d();
- if (vector == 0)
- vector = (int)ia64_ld1(&ia64_pib->ib_inta);
- ia64_set_eoi(0);
- ia64_srlz_d();
- vector = ia64_get_ivr();
- }
- ia64_srlz_d();
-
- /* kick off the clock on this AP */
- pcpu_initclock();
-
+ /* Mask interval timer interrupts on APs. */
+ ia64_set_itv(0x10000);
ia64_set_tpr(0);
ia64_srlz_d();
- enable_intr();
+ ia64_enable_intr();
sched_throw(NULL);
/* NOTREACHED */
@@ -200,7 +247,7 @@ cpu_mp_probe(void)
* case we can have multiple processors, but we simply can't wake
* them up...
*/
- return (mp_ncpus > 1 && ipi_vector[IPI_AP_WAKEUP] != 0);
+ return (mp_ncpus > 1 && ia64_ipi_wakeup != 0);
}
void
@@ -276,7 +323,7 @@ cpu_mp_start()
if (bootverbose)
printf("SMP: waking up cpu%d\n", pc->pc_cpuid);
- ipi_send(pc, IPI_AP_WAKEUP);
+ ipi_send(pc, ia64_ipi_wakeup);
do {
DELAY(1000);
@@ -300,13 +347,24 @@ cpu_mp_unleash(void *dummy)
if (mp_ncpus <= 1)
return;
+ /* Allocate XIVs for IPIs */
+ ia64_ipi_ast = ia64_xiv_alloc(PI_DULL, IA64_XIV_IPI, ia64_ih_ast);
+ ia64_ipi_highfp = ia64_xiv_alloc(PI_AV, IA64_XIV_IPI, ia64_ih_highfp);
+ ia64_ipi_preempt = ia64_xiv_alloc(PI_SOFT, IA64_XIV_IPI,
+ ia64_ih_preempt);
+ ia64_ipi_rndzvs = ia64_xiv_alloc(PI_AV, IA64_XIV_IPI, ia64_ih_rndzvs);
+ ia64_ipi_stop = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI, ia64_ih_stop);
+
+ /* Reserve the NMI vector for IPI_STOP_HARD if possible */
+ ia64_ipi_nmi = (ia64_xiv_reserve(2, IA64_XIV_IPI, ia64_ih_stop) != 0)
+ ? ia64_ipi_stop : 0x400; /* DM=NMI, Vector=n/a */
+
cpus = 0;
smp_cpus = 0;
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
cpus++;
if (pc->pc_md.awake) {
- kproc_create(ia64_store_mca_state,
- (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0,
+ kproc_create(ia64_store_mca_state, pc, NULL, 0, 0,
"mca %u", pc->pc_cpuid);
smp_cpus++;
}
@@ -325,6 +383,12 @@ cpu_mp_unleash(void *dummy)
smp_active = 1;
smp_started = 1;
+
+ /*
+ * Now that all CPUs are up and running, bind interrupts to each of
+ * them.
+ */
+ ia64_bind_intr();
}
/*
@@ -361,20 +425,18 @@ ipi_all_but_self(int ipi)
* fields are used here.
*/
void
-ipi_send(struct pcpu *cpu, int ipi)
+ipi_send(struct pcpu *cpu, int xiv)
{
u_int lid;
- uint8_t vector;
+
+ KASSERT(xiv != 0, ("ipi_send"));
lid = LID_SAPIC(cpu->pc_md.lid);
- vector = ipi_vector[ipi];
- KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi));
ia64_mf();
- ia64_st8(&(ia64_pib->ib_ipi[lid][0]), vector);
+ ia64_st8(&(ia64_pib->ib_ipi[lid][0]), xiv);
ia64_mf_a();
- CTR4(KTR_SMP, "ipi_send(%p, %ld): cpuid=%d, vector=%u", cpu, ipi,
- PCPU_GET(cpuid), vector);
+ CTR3(KTR_SMP, "ipi_send(%p, %d): cpuid=%d", cpu, xiv, PCPU_GET(cpuid));
}
SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL);
diff --git a/sys/ia64/ia64/nexus.c b/sys/ia64/ia64/nexus.c
index 17c07d6..9885b74 100644
--- a/sys/ia64/ia64/nexus.c
+++ b/sys/ia64/ia64/nexus.c
@@ -50,13 +50,13 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/interrupt.h>
+#include <sys/pcpu.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/efi.h>
#include <machine/intr.h>
-#include <machine/nexusvar.h>
#include <machine/pmap.h>
#include <machine/resource.h>
#include <machine/vmparam.h>
@@ -73,12 +73,11 @@
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
- int nx_pcibus;
};
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
-static struct rman irq_rman, drq_rman, port_rman, mem_rman;
+static struct rman irq_rman, port_rman, mem_rman;
static int nexus_probe(device_t);
static int nexus_attach(device_t);
@@ -87,8 +86,6 @@ static device_t nexus_add_child(device_t bus, int order, const char *name,
int unit);
static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
-static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
-static int nexus_write_ivar(device_t, device_t, int, uintptr_t);
static int nexus_activate_resource(device_t, device_t, int, int,
struct resource *);
static int nexus_deactivate_resource(device_t, device_t, int, int,
@@ -105,6 +102,7 @@ static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
static int nexus_get_resource(device_t, device_t, int, int, u_long *,
u_long *);
static void nexus_delete_resource(device_t, device_t, int, int);
+static int nexus_bind_intr(device_t, device_t, struct resource *, int);
static int nexus_config_intr(device_t, int, enum intr_trigger,
enum intr_polarity);
@@ -123,8 +121,6 @@ static device_method_t nexus_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_add_child, nexus_add_child),
- DEVMETHOD(bus_read_ivar, nexus_read_ivar),
- DEVMETHOD(bus_write_ivar, nexus_write_ivar),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_release_resource, nexus_release_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
@@ -135,6 +131,7 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_set_resource, nexus_set_resource),
DEVMETHOD(bus_get_resource, nexus_get_resource),
DEVMETHOD(bus_delete_resource, nexus_delete_resource),
+ DEVMETHOD(bus_bind_intr, nexus_bind_intr),
DEVMETHOD(bus_config_intr, nexus_config_intr),
/* Clock interface */
@@ -159,56 +156,15 @@ nexus_probe(device_t dev)
device_quiet(dev); /* suppress attach message for neatness */
- /*
- * XXX working notes:
- *
- * - IRQ resource creation should be moved to the PIC/APIC driver.
- * - DRQ resource creation should be moved to the DMAC driver.
- * - The above should be sorted to probe earlier than any child busses.
- *
- * - Leave I/O and memory creation here, as child probes may need them.
- * (especially eg. ACPI)
- */
-
- /*
- * IRQ's are on the mainboard on old systems, but on the ISA part
- * of PCI->ISA bridges. There would be multiple sets of IRQs on
- * multi-ISA-bus systems. PCI interrupts are routed to the ISA
- * component, so in a way, PCI can be a partial child of an ISA bus(!).
- * APIC interrupts are global though.
- *
- * XXX We depend on the AT PIC driver correctly claiming IRQ 2
- * to prevent its reuse elsewhere in the !APIC_IO case.
- */
- irq_rman.rm_start = 0;
irq_rman.rm_type = RMAN_ARRAY;
irq_rman.rm_descr = "Interrupt request lines";
- irq_rman.rm_end = 255;
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = IA64_NXIVS - 1;
if (rman_init(&irq_rman)
|| rman_manage_region(&irq_rman,
irq_rman.rm_start, irq_rman.rm_end))
panic("nexus_probe irq_rman");
- /*
- * ISA DMA on PCI systems is implemented in the ISA part of each
- * PCI->ISA bridge and the channels can be duplicated if there are
- * multiple bridges. (eg: laptops with docking stations)
- */
- drq_rman.rm_start = 0;
- drq_rman.rm_end = 7;
- drq_rman.rm_type = RMAN_ARRAY;
- drq_rman.rm_descr = "DMA request lines";
- /* XXX drq 0 not available on some machines */
- if (rman_init(&drq_rman)
- || rman_manage_region(&drq_rman,
- drq_rman.rm_start, drq_rman.rm_end))
- panic("nexus_probe drq_rman");
-
- /*
- * However, IO ports and Memory truely are global at this level,
- * as are APIC interrupts (however many IO APICS there turn out
- * to be on large systems..)
- */
port_rman.rm_start = 0;
port_rman.rm_end = 0xffff;
port_rman.rm_type = RMAN_ARRAY;
@@ -256,8 +212,6 @@ nexus_print_child(device_t bus, device_t child)
retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx");
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
- if (ndev->nx_pcibus != -1)
- retval += printf(" pcibus %d", ndev->nx_pcibus);
if (device_get_flags(child))
retval += printf(" flags %#x", device_get_flags(child));
retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */
@@ -275,7 +229,6 @@ nexus_add_child(device_t bus, int order, const char *name, int unit)
if (!ndev)
return(0);
resource_list_init(&ndev->nx_resources);
- ndev->nx_pcibus = -1;
child = device_add_child_ordered(bus, order, name, unit);
@@ -285,37 +238,6 @@ nexus_add_child(device_t bus, int order, const char *name, int unit)
return(child);
}
-static int
-nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct nexus_device *ndev = DEVTONX(child);
-
- switch (which) {
- case NEXUS_IVAR_PCIBUS:
- *result = ndev->nx_pcibus;
- break;
- default:
- return ENOENT;
- }
- return 0;
-}
-
-
-static int
-nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
-{
- struct nexus_device *ndev = DEVTONX(child);
-
- switch (which) {
- case NEXUS_IVAR_PCIBUS:
- ndev->nx_pcibus = value;
- break;
- default:
- return ENOENT;
- }
- return 0;
-}
-
/*
* Allocate a resource on behalf of child. NB: child is usually going to be a
@@ -355,10 +277,6 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
rm = &irq_rman;
break;
- case SYS_RES_DRQ:
- rm = &drq_rman;
- break;
-
case SYS_RES_IOPORT:
rm = &port_rman;
break;
@@ -547,6 +465,17 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
}
static int
+nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
+{
+ struct pcpu *pc;
+
+ pc = cpuid_to_pcpu[cpu];
+ if (pc == NULL)
+ return (EINVAL);
+ return (sapic_bind_intr(rman_get_start(irq), pc));
+}
+
+static int
nexus_gettime(device_t dev, struct timespec *ts)
{
struct clocktime ct;
@@ -591,4 +520,3 @@ nexus_settime(device_t dev, struct timespec *ts)
tm.tm_mday = ct.day;
return (efi_set_time(&tm));
}
-
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index f829746..a7c47ef 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -238,7 +238,7 @@ static pv_entry_t get_pv_entry(pmap_t locked_pmap);
static void pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va,
vm_page_t m, vm_prot_t prot);
static void pmap_free_pte(struct ia64_lpte *pte, vm_offset_t va);
-static void pmap_invalidate_all(pmap_t pmap);
+static void pmap_invalidate_all(void);
static int pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte,
vm_offset_t va, pv_entry_t pv, int freepte);
static int pmap_remove_vhpt(vm_offset_t va);
@@ -475,7 +475,7 @@ pmap_bootstrap()
/*
* Clear out any random TLB entries left over from booting.
*/
- pmap_invalidate_all(kernel_pmap);
+ pmap_invalidate_all();
map_gateway_page();
}
@@ -536,21 +536,19 @@ pmap_init(void)
***************************************************/
static void
-pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
+pmap_invalidate_page(vm_offset_t va)
{
struct ia64_lpte *pte;
struct pcpu *pc;
+ uint64_t tag;
u_int vhpt_ofs;
- KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
- ("invalidating TLB for non-current pmap"));
-
- vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt);
critical_enter();
+ vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt);
+ tag = ia64_ttag(va);
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
pte = (struct ia64_lpte *)(pc->pc_md.vhpt + vhpt_ofs);
- if (pte->tag == ia64_ttag(va))
- pte->tag = 1UL << 63;
+ atomic_cmpset_64(&pte->tag, tag, 1UL << 63);
}
critical_exit();
mtx_lock_spin(&pmap_ptcmutex);
@@ -577,16 +575,14 @@ pmap_invalidate_all_1(void *arg)
}
static void
-pmap_invalidate_all(pmap_t pmap)
+pmap_invalidate_all(void)
{
- KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
- ("invalidating TLB for non-current pmap"));
-
#ifdef SMP
- if (mp_ncpus > 1)
+ if (mp_ncpus > 1) {
smp_rendezvous(NULL, pmap_invalidate_all_1, NULL, NULL);
- else
+ return;
+ }
#endif
pmap_invalidate_all_1(NULL);
}
@@ -794,7 +790,7 @@ retry:
pte = pmap_find_vhpt(va);
KASSERT(pte != NULL, ("pte"));
pmap_remove_vhpt(va);
- pmap_invalidate_page(pmap, va);
+ pmap_invalidate_page(va);
pmap_switch(oldpmap);
if (pmap_accessed(pte))
vm_page_flag_set(m, PG_REFERENCED);
@@ -1160,9 +1156,6 @@ pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va,
int error;
vm_page_t m;
- KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
- ("removing pte for non-current pmap"));
-
/*
* First remove from the VHPT.
*/
@@ -1170,7 +1163,7 @@ pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va,
if (error)
return (error);
- pmap_invalidate_page(pmap, va);
+ pmap_invalidate_page(va);
if (pmap_wired(pte))
pmap->pm_stats.wired_count -= 1;
@@ -1238,7 +1231,7 @@ pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
for (i = 0; i < count; i++) {
pte = pmap_find_kpte(va);
if (pmap_present(pte))
- pmap_invalidate_page(kernel_pmap, va);
+ pmap_invalidate_page(va);
else
pmap_enter_vhpt(pte, va);
pmap_pte_prot(kernel_pmap, pte, VM_PROT_ALL);
@@ -1261,7 +1254,7 @@ pmap_qremove(vm_offset_t va, int count)
pte = pmap_find_kpte(va);
if (pmap_present(pte)) {
pmap_remove_vhpt(va);
- pmap_invalidate_page(kernel_pmap, va);
+ pmap_invalidate_page(va);
pmap_clear_present(pte);
}
va += PAGE_SIZE;
@@ -1279,7 +1272,7 @@ pmap_kenter(vm_offset_t va, vm_offset_t pa)
pte = pmap_find_kpte(va);
if (pmap_present(pte))
- pmap_invalidate_page(kernel_pmap, va);
+ pmap_invalidate_page(va);
else
pmap_enter_vhpt(pte, va);
pmap_pte_prot(kernel_pmap, pte, VM_PROT_ALL);
@@ -1297,7 +1290,7 @@ pmap_kremove(vm_offset_t va)
pte = pmap_find_kpte(va);
if (pmap_present(pte)) {
pmap_remove_vhpt(va);
- pmap_invalidate_page(kernel_pmap, va);
+ pmap_invalidate_page(va);
pmap_clear_present(pte);
}
}
@@ -1321,23 +1314,6 @@ pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
}
/*
- * Remove a single page from a process address space
- */
-static void
-pmap_remove_page(pmap_t pmap, vm_offset_t va)
-{
- struct ia64_lpte *pte;
-
- KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
- ("removing page for non-current pmap"));
-
- pte = pmap_find_vhpt(va);
- if (pte != NULL)
- pmap_remove_pte(pmap, pte, va, 0, 1);
- return;
-}
-
-/*
* Remove the given range of addresses from the specified map.
*
* It is assumed that the start and end are properly
@@ -1364,7 +1340,9 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
* code.
*/
if (sva + PAGE_SIZE == eva) {
- pmap_remove_page(pmap, sva);
+ pte = pmap_find_vhpt(sva);
+ if (pte != NULL)
+ pmap_remove_pte(pmap, pte, sva, 0, 1);
goto out;
}
@@ -1491,7 +1469,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
ia64_sync_icache(sva, PAGE_SIZE);
pmap_pte_prot(pmap, pte, prot);
- pmap_invalidate_page(pmap, sva);
+ pmap_invalidate_page(sva);
}
vm_page_unlock_queues();
pmap_switch(oldpmap);
@@ -1582,7 +1560,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
else if (pmap_exec(&origpte))
icache_inval = FALSE;
- pmap_invalidate_page(pmap, va);
+ pmap_invalidate_page(va);
goto validate;
}
@@ -1929,7 +1907,8 @@ pmap_remove_pages(pmap_t pmap)
pv_entry_t pv, npv;
if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) {
- printf("warning: pmap_remove_pages called with non-current pmap\n");
+ printf("warning: %s called with non-current pmap\n",
+ __func__);
return;
}
@@ -1984,7 +1963,7 @@ pmap_ts_referenced(vm_page_t m)
if (pmap_accessed(pte)) {
count++;
pmap_clear_accessed(pte);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ pmap_invalidate_page(pv->pv_va);
}
pmap_switch(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
@@ -2044,6 +2023,37 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
}
/*
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+ struct ia64_lpte *pte;
+ pmap_t oldpmap;
+ pv_entry_t pv;
+ boolean_t rv;
+
+ rv = FALSE;
+ if (m->flags & PG_FICTITIOUS)
+ return (rv);
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ PMAP_LOCK(pv->pv_pmap);
+ oldpmap = pmap_switch(pv->pv_pmap);
+ pte = pmap_find_vhpt(pv->pv_va);
+ pmap_switch(oldpmap);
+ KASSERT(pte != NULL, ("pte"));
+ rv = pmap_accessed(pte) ? TRUE : FALSE;
+ PMAP_UNLOCK(pv->pv_pmap);
+ if (rv)
+ break;
+ }
+ return (rv);
+}
+
+/*
* Clear the modify bits on the specified physical page.
*/
void
@@ -2063,7 +2073,7 @@ pmap_clear_modify(vm_page_t m)
KASSERT(pte != NULL, ("pte"));
if (pmap_dirty(pte)) {
pmap_clear_dirty(pte);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ pmap_invalidate_page(pv->pv_va);
}
pmap_switch(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
@@ -2092,7 +2102,7 @@ pmap_clear_reference(vm_page_t m)
KASSERT(pte != NULL, ("pte"));
if (pmap_accessed(pte)) {
pmap_clear_accessed(pte);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ pmap_invalidate_page(pv->pv_va);
}
pmap_switch(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
@@ -2128,7 +2138,7 @@ pmap_remove_write(vm_page_t m)
}
prot &= ~VM_PROT_WRITE;
pmap_pte_prot(pmap, pte, prot);
- pmap_invalidate_page(pmap, pv->pv_va);
+ pmap_invalidate_page(pv->pv_va);
}
pmap_switch(oldpmap);
PMAP_UNLOCK(pmap);
@@ -2218,10 +2228,8 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
* Referenced by someone
*/
vm_page_lock_queues();
- if (pmap_ts_referenced(m)) {
+ if (pmap_is_referenced(m))
val |= MINCORE_REFERENCED_OTHER;
- vm_page_flag_set(m, PG_REFERENCED);
- }
vm_page_unlock_queues();
}
}
diff --git a/sys/ia64/ia64/sal.c b/sys/ia64/ia64/sal.c
index 4f46d65..6f081be 100644
--- a/sys/ia64/ia64/sal.c
+++ b/sys/ia64/ia64/sal.c
@@ -29,21 +29,18 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/efi.h>
+#include <machine/intr.h>
#include <machine/md_var.h>
#include <machine/sal.h>
#include <machine/smp.h>
-/*
- * IPIs are used more genericly than only
- * for inter-processor interrupts. Don't
- * make it a SMP specific thing...
- */
-int ipi_vector[IPI_COUNT];
+int ia64_ipi_wakeup;
static struct ia64_fdesc sal_fdesc;
static sal_entry_t fake_sal;
@@ -66,22 +63,6 @@ fake_sal(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4,
return res;
}
-static void
-setup_ipi_vectors(int ceil)
-{
- int ipi;
-
- ipi_vector[IPI_MCA_RENDEZ] = ceil - 0x10;
-
- ipi = IPI_AST; /* First generic IPI. */
- ceil -= 0x20; /* First vector in group. */
- while (ipi < IPI_COUNT)
- ipi_vector[ipi++] = ceil++;
-
- ipi_vector[IPI_HIGH_FP] = ceil - 0x30;
- ipi_vector[IPI_MCA_CMCV] = ceil - 0x30 + 1;
-}
-
void
ia64_sal_init(void)
{
@@ -89,7 +70,7 @@ ia64_sal_init(void)
48, 32, 16, 32, 16, 16
};
u_int8_t *p;
- int i;
+ int error, i;
sal_systbl = efi_get_table(&sal_table);
if (sal_systbl == NULL)
@@ -132,36 +113,19 @@ ia64_sal_init(void)
break;
}
- if (dp->sale_vector < 0x10 || dp->sale_vector > 0xff) {
- printf("SAL: invalid AP wake-up vector "
- "(0x%lx)\n", dp->sale_vector);
- break;
- }
-
- /*
- * SAL documents that the wake-up vector should be
- * high (close to 255). The MCA rendezvous vector
- * should be less than the wake-up vector, but still
- * "high". We use the following priority assignment:
- * Wake-up: priority of the sale_vector
- * Rendezvous: priority-1
- * Generic IPIs: priority-2
- * Special IPIs: priority-3
- * Consequently, the wake-up priority should be at
- * least 4 (ie vector >= 0x40).
- */
- if (dp->sale_vector < 0x40) {
- printf("SAL: AP wake-up vector too low "
- "(0x%lx)\n", dp->sale_vector);
+ /* Reserve the XIV so that we won't use it. */
+ error = ia64_xiv_reserve(dp->sale_vector,
+ IA64_XIV_PLAT, NULL);
+ if (error) {
+ printf("SAL: invalid AP wake-up XIV (%#lx)\n",
+ dp->sale_vector);
break;
}
+ ia64_ipi_wakeup = dp->sale_vector;
if (bootverbose)
- printf("SAL: AP wake-up vector: 0x%lx\n",
- dp->sale_vector);
-
- ipi_vector[IPI_AP_WAKEUP] = dp->sale_vector;
- setup_ipi_vectors(dp->sale_vector & 0xf0);
+ printf("SAL: AP wake-up XIV: %#x\n",
+ ia64_ipi_wakeup);
#ifdef SMP
fd = (struct ia64_fdesc *) os_boot_rendez;
@@ -175,7 +139,4 @@ ia64_sal_init(void)
}
p += sizes[*p];
}
-
- if (ipi_vector[IPI_AP_WAKEUP] == 0)
- setup_ipi_vectors(0xf0);
}
diff --git a/sys/ia64/ia64/sapic.c b/sys/ia64/ia64/sapic.c
index cb8a1c3..5aa1449 100644
--- a/sys/ia64/ia64/sapic.c
+++ b/sys/ia64/ia64/sapic.c
@@ -35,6 +35,7 @@
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/pcpu.h>
#include <sys/sysctl.h>
#include <machine/intr.h>
@@ -172,6 +173,26 @@ sapic_lookup(u_int irq, u_int *vecp)
int
+sapic_bind_intr(u_int irq, struct pcpu *pc)
+{
+ struct sapic_rte rte;
+ struct sapic *sa;
+
+ sa = sapic_lookup(irq, NULL);
+ if (sa == NULL)
+ return (EINVAL);
+
+ mtx_lock_spin(&sa->sa_mtx);
+ sapic_read_rte(sa, irq - sa->sa_base, &rte);
+ rte.rte_destination_id = (pc->pc_md.lid >> 24) & 255;
+ rte.rte_destination_eid = (pc->pc_md.lid >> 16) & 255;
+ rte.rte_delivery_mode = SAPIC_DELMODE_FIXED;
+ sapic_write_rte(sa, irq - sa->sa_base, &rte);
+ mtx_unlock_spin(&sa->sa_mtx);
+ return (0);
+}
+
+int
sapic_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol)
{
struct sapic_rte rte;
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 6264462..f539097 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -334,11 +334,11 @@ int
do_ast(struct trapframe *tf)
{
- disable_intr();
+ ia64_disable_intr();
while (curthread->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) {
- enable_intr();
+ ia64_enable_intr();
ast(tf);
- disable_intr();
+ ia64_disable_intr();
}
/*
* Keep interrupts disabled. We return r10 as a favor to the EPC
diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c
index 37af94b..6222d33 100644
--- a/sys/ia64/ia64/vm_machdep.c
+++ b/sys/ia64/ia64/vm_machdep.c
@@ -70,6 +70,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/bio.h>
#include <sys/buf.h>
@@ -89,14 +90,11 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
-#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
-#include <i386/include/psl.h>
-
void
cpu_thread_exit(struct thread *td)
{
diff --git a/sys/ia64/include/_inttypes.h b/sys/ia64/include/_inttypes.h
index e6b2536..a7cbea5 100644
--- a/sys/ia64/include/_inttypes.h
+++ b/sys/ia64/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/ia64/include/acpica_machdep.h b/sys/ia64/include/acpica_machdep.h
index 26191c0..38efffd 100644
--- a/sys/ia64/include/acpica_machdep.h
+++ b/sys/ia64/include/acpica_machdep.h
@@ -56,8 +56,8 @@
#define ACPI_ASM_MACROS
#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() disable_intr()
-#define ACPI_ENABLE_IRQS() enable_intr()
+#define ACPI_DISABLE_IRQS() ia64_disable_intr()
+#define ACPI_ENABLE_IRQS() ia64_enable_intr()
#define ACPI_FLUSH_CPU_CACHE() /* XXX ia64_fc()? */
diff --git a/sys/ia64/include/clock.h b/sys/ia64/include/clock.h
index 772fc2a..6b87a89 100644
--- a/sys/ia64/include/clock.h
+++ b/sys/ia64/include/clock.h
@@ -9,12 +9,4 @@
#ifndef _MACHINE_CLOCK_H_
#define _MACHINE_CLOCK_H_
-#ifdef _KERNEL
-
-#define CLOCK_VECTOR 254
-
-extern uint64_t ia64_clock_reload;
-
-#endif
-
#endif /* !_MACHINE_CLOCK_H_ */
diff --git a/sys/ia64/include/cpufunc.h b/sys/ia64/include/cpufunc.h
index 9ae06a2..925d4ba 100644
--- a/sys/ia64/include/cpufunc.h
+++ b/sys/ia64/include/cpufunc.h
@@ -56,13 +56,13 @@ breakpoint(void)
static __inline void
-disable_intr(void)
+ia64_disable_intr(void)
{
__asm __volatile ("rsm psr.i");
}
static __inline void
-enable_intr(void)
+ia64_enable_intr(void)
{
__asm __volatile ("ssm psr.i;; srlz.d");
}
@@ -71,8 +71,9 @@ static __inline register_t
intr_disable(void)
{
register_t psr;
+
__asm __volatile ("mov %0=psr;;" : "=r"(psr));
- disable_intr();
+ ia64_disable_intr();
return ((psr & IA64_PSR_I) ? 1 : 0);
}
@@ -80,7 +81,7 @@ static __inline void
intr_restore(register_t ie)
{
if (ie)
- enable_intr();
+ ia64_enable_intr();
}
#endif /* __GNUCLIKE_ASM */
diff --git a/sys/ia64/include/elf.h b/sys/ia64/include/elf.h
index c6a43fc..27182db 100644
--- a/sys/ia64/include/elf.h
+++ b/sys/ia64/include/elf.h
@@ -43,6 +43,7 @@
#include <sys/elf_generic.h>
#define ELF_ARCH EM_IA_64
+#define ELF_ARCH32 EM_386
#define ELF_MACHINE_OK(x) ((x) == EM_IA_64)
diff --git a/sys/ia64/include/frame.h b/sys/ia64/include/frame.h
index 262a8bf..683d164 100644
--- a/sys/ia64/include/frame.h
+++ b/sys/ia64/include/frame.h
@@ -29,7 +29,9 @@
#ifndef _MACHINE_FRAME_H_
#define _MACHINE_FRAME_H_
+#ifndef _MACHINE_REGSET_H_
#include <machine/_regset.h>
+#endif
/*
* Software trap, exception, and syscall frame.
diff --git a/sys/ia64/include/intr.h b/sys/ia64/include/intr.h
index 0635e34..81603cf 100644
--- a/sys/ia64/include/intr.h
+++ b/sys/ia64/include/intr.h
@@ -30,7 +30,15 @@
#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_
+#define IA64_NXIVS 256 /* External Interrupt Vectors */
+#define IA64_MIN_XIV 16
+
+#define IA64_MAX_HWPRIO 14
+
+struct pcpu;
struct sapic;
+struct thread;
+struct trapframe;
/*
* Layout of the Processor Interrupt Block.
@@ -46,12 +54,30 @@ struct ia64_pib
uint8_t _rsvd4[0x1fff0];
};
+enum ia64_xiv_use {
+ IA64_XIV_FREE,
+ IA64_XIV_ARCH, /* Architecturally defined. */
+ IA64_XIV_PLAT, /* Platform defined. */
+ IA64_XIV_IPI, /* Used for IPIs. */
+ IA64_XIV_IRQ /* Used for external interrupts. */
+};
+
+typedef u_int (ia64_ihtype)(struct thread *, u_int, struct trapframe *);
+
extern struct ia64_pib *ia64_pib;
+void ia64_bind_intr(void);
+void ia64_handle_intr(struct trapframe *);
int ia64_setup_intr(const char *, int, driver_filter_t, driver_intr_t,
void *, enum intr_type, void **);
int ia64_teardown_intr(void *);
+void ia64_xiv_init(void);
+u_int ia64_xiv_alloc(u_int, enum ia64_xiv_use, ia64_ihtype);
+int ia64_xiv_free(u_int, enum ia64_xiv_use);
+int ia64_xiv_reserve(u_int, enum ia64_xiv_use, ia64_ihtype);
+
+int sapic_bind_intr(u_int, struct pcpu *);
int sapic_config_intr(u_int, enum intr_trigger, enum intr_polarity);
struct sapic *sapic_create(u_int, u_int, uint64_t);
int sapic_enable(struct sapic *, u_int, u_int);
diff --git a/sys/ia64/include/intrcnt.h b/sys/ia64/include/intrcnt.h
index c4f73c0..5e165ea 100644
--- a/sys/ia64/include/intrcnt.h
+++ b/sys/ia64/include/intrcnt.h
@@ -29,11 +29,7 @@
*/
#define INTRCNT_CLOCK 0
-#define INTRCNT_ISA_IRQ (INTRCNT_CLOCK + 1)
-#define INTRCNT_ISA_IRQ_LEN 16
-#define INTRCNT_OTHER_BASE (INTRCNT_ISA_IRQ + INTRCNT_ISA_IRQ_LEN)
-#define INTRCNT_OTHER_LEN 240
-#define INTRCNT_COUNT (INTRCNT_OTHER_BASE + INTRCNT_OTHER_LEN)
+#define INTRCNT_COUNT 256
/*
* Maximum name length in intrnames table (including terminating '\0'.
diff --git a/sys/ia64/include/mca.h b/sys/ia64/include/mca.h
index 94926d1..e13d2bf 100644
--- a/sys/ia64/include/mca.h
+++ b/sys/ia64/include/mca.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002-2010 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -240,7 +240,6 @@ struct mca_pcidev_reg {
#ifdef _KERNEL
void ia64_mca_init(void);
-void ia64_mca_populate(void);
void ia64_mca_save_state(int);
#endif /* _KERNEL */
diff --git a/sys/ia64/include/pal.h b/sys/ia64/include/pal.h
index 6cb865d..7c0e16f 100644
--- a/sys/ia64/include/pal.h
+++ b/sys/ia64/include/pal.h
@@ -54,11 +54,11 @@
#define PAL_VERSION 20
#define PAL_MC_CLEAR_LOG 21
#define PAL_MC_DRAIN 22
+#define PAL_MC_EXPECTED 23
#define PAL_MC_DYNAMIC_STATE 24
#define PAL_MC_ERROR_INFO 25
-#define PAL_MC_EXPECTED 23
+#define PAL_MC_RESUME 26
#define PAL_MC_REGISTER_MEM 27
-#define PAL_MC_RESUME 26
#define PAL_HALT 28
#define PAL_HALT_LIGHT 29
#define PAL_COPY_INFO 30
@@ -66,11 +66,16 @@
#define PAL_PMI_ENTRYPOINT 32
#define PAL_ENTER_IA_32_ENV 33
#define PAL_VM_PAGE_SIZE 34
-#define PAL_MEM_FOR_TEST 37
+#define PAL_TEST_INFO 37
#define PAL_CACHE_PROT_INFO 38
#define PAL_REGISTER_INFO 39
-#define PAL_SHUTDOWN 40
#define PAL_PREFETCH_VISIBILITY 41
+#define PAL_LOGICAL_TO_PHYSICAL 42
+#define PAL_CACHE_SHARED_INFO 43
+#define PAL_PSTATE_INFO 44
+#define PAL_SHUTDOWN 45
+#define PAL_GET_HW_POLICY 48
+#define PAL_SET_HW_POLICY 49
/*
* Architected stacked calling convention procedures.
@@ -81,6 +86,19 @@
#define PAL_CACHE_READ 259
#define PAL_CACHE_WRITE 260
#define PAL_VM_TR_READ 261
+#define PAL_GET_PSTATE 262
+#define PAL_SET_PSTATE 263
+#define PAL_VP_CREATE 265
+#define PAL_VP_ENV_INFO 266
+#define PAL_VP_EXIT_ENV 267
+#define PAL_VP_INIT_ENV 268
+#define PAL_VP_REGISTER 269
+#define PAL_VP_RESTORE 270
+#define PAL_VP_SAVE 271
+#define PAL_VP_TERMINATE 272
+#define PAL_BRAND_INFO 274
+#define PAL_MC_ERROR_INJECT 276
+#define PAL_MEMORY_BUFFER 277
/*
* Default physical address of the Processor Interrupt Block (PIB).
@@ -90,20 +108,19 @@
struct ia64_pal_result {
int64_t pal_status;
- u_int64_t pal_result[3];
+ uint64_t pal_result[3];
};
-extern struct ia64_pal_result
- ia64_call_pal_static(u_int64_t proc, u_int64_t arg1,
- u_int64_t arg2, u_int64_t arg3);
-extern struct ia64_pal_result
- ia64_call_pal_static_physical(u_int64_t proc, u_int64_t arg1,
- u_int64_t arg2, u_int64_t arg3);
-extern struct ia64_pal_result
- ia64_call_pal_stacked(u_int64_t proc, u_int64_t arg1,
- u_int64_t arg2, u_int64_t arg3);
-extern struct ia64_pal_result
- ia64_call_pal_stacked_physical(u_int64_t proc, u_int64_t arg1,
- u_int64_t arg2, u_int64_t arg3);
+struct ia64_pal_result ia64_call_pal_static(uint64_t proc, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3);
+
+struct ia64_pal_result ia64_call_pal_static_physical(uint64_t proc,
+ uint64_t arg1, uint64_t arg2, uint64_t arg3);
+
+struct ia64_pal_result ia64_call_pal_stacked(uint64_t proc, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3);
+
+struct ia64_pal_result ia64_call_pal_stacked_physical(uint64_t proc,
+ uint64_t arg1, uint64_t arg2, uint64_t arg3);
#endif /* _MACHINE_PAL_H_ */
diff --git a/sys/ia64/include/pcb.h b/sys/ia64/include/pcb.h
index 5d250bf..59334bf 100644
--- a/sys/ia64/include/pcb.h
+++ b/sys/ia64/include/pcb.h
@@ -30,7 +30,9 @@
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
+#ifndef _MACHINE_REGSET_H_
#include <machine/_regset.h>
+#endif
/*
* PCB: process control block
diff --git a/sys/ia64/include/pcpu.h b/sys/ia64/include/pcpu.h
index bc9fe08..3c6e6a7 100644
--- a/sys/ia64/include/pcpu.h
+++ b/sys/ia64/include/pcpu.h
@@ -70,6 +70,16 @@ struct pcpu;
register struct pcpu *pcpup __asm__("r13");
+static __inline struct thread *
+__curthread(void)
+{
+ struct thread *td;
+
+ __asm __volatile("ld8.acq %0=[r13]" : "=r"(td));
+ return (td);
+}
+#define curthread (__curthread())
+
#define PCPU_GET(member) (pcpup->pc_ ## member)
/*
@@ -81,8 +91,6 @@ register struct pcpu *pcpup __asm__("r13");
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value))
-void pcpu_initclock(void);
-
#endif /* _KERNEL */
#endif /* !_MACHINE_PCPU_H_ */
diff --git a/sys/ia64/include/proc.h b/sys/ia64/include/proc.h
index 6bf9c78..81e2e4f 100644
--- a/sys/ia64/include/proc.h
+++ b/sys/ia64/include/proc.h
@@ -38,4 +38,7 @@ struct mdproc {
int __dummy; /* Avoid having an empty struct. */
};
+#define KINFO_PROC_SIZE 1088
+#define KINFO_PROC32_SIZE 768
+
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/ia64/include/reg.h b/sys/ia64/include/reg.h
index 453c9b8..e95db31 100644
--- a/sys/ia64/include/reg.h
+++ b/sys/ia64/include/reg.h
@@ -31,6 +31,10 @@
#include <machine/_regset.h>
+#if defined(_KERNEL) && !defined(_STANDALONE)
+#include "opt_compat.h"
+#endif
+
struct reg {
struct _special r_special;
struct _callee_saved r_preserved;
@@ -48,6 +52,11 @@ struct dbreg {
unsigned long dbr_inst[8];
};
+#ifdef COMPAT_FREEBSD32
+#include <machine/fpu.h>
+#include <compat/ia32/ia32_reg.h>
+#endif
+
#ifdef _KERNEL
struct thread;
diff --git a/sys/ia64/include/smp.h b/sys/ia64/include/smp.h
index 4eddf74..9f976de 100644
--- a/sys/ia64/include/smp.h
+++ b/sys/ia64/include/smp.h
@@ -6,31 +6,23 @@
#ifdef _KERNEL
-/*
- * Interprocessor interrupts for SMP. The following values are indices
- * into the IPI vector table. The SAL gives us the vector used for AP
- * wake-up. We base the other vectors on that. Keep IPI_AP_WAKEUP at
- * index 0. See sal.c for details.
- */
-/* Architecture specific IPIs. */
-#define IPI_AP_WAKEUP 0
-#define IPI_HIGH_FP 1
-#define IPI_MCA_CMCV 2
-#define IPI_MCA_RENDEZ 3
-/* Machine independent IPIs. */
-#define IPI_AST 4
-#define IPI_RENDEZVOUS 5
-#define IPI_STOP 6
-#define IPI_STOP_HARD 6
-#define IPI_PREEMPT 7
-
-#define IPI_COUNT 8
+#define IPI_AST ia64_ipi_ast
+#define IPI_PREEMPT ia64_ipi_preempt
+#define IPI_RENDEZVOUS ia64_ipi_rndzvs
+#define IPI_STOP ia64_ipi_stop
+#define IPI_STOP_HARD ia64_ipi_nmi
#ifndef LOCORE
struct pcpu;
-extern int ipi_vector[];
+extern int ia64_ipi_ast;
+extern int ia64_ipi_highfp;
+extern int ia64_ipi_nmi;
+extern int ia64_ipi_preempt;
+extern int ia64_ipi_rndzvs;
+extern int ia64_ipi_stop;
+extern int ia64_ipi_wakeup;
void ipi_all_but_self(int ipi);
void ipi_selected(cpumask_t cpus, int ipi);
diff --git a/sys/ia64/pci/pci_cfgreg.c b/sys/ia64/pci/pci_cfgreg.c
index 4858d94..00d8397 100644
--- a/sys/ia64/pci/pci_cfgreg.c
+++ b/sys/ia64/pci/pci_cfgreg.c
@@ -28,6 +28,7 @@
*/
#include <sys/param.h>
+#include <machine/cpufunc.h>
#include <machine/pci_cfgreg.h>
#include <machine/sal.h>
@@ -66,6 +67,7 @@ uint32_t
pci_cfgregread(int bus, int slot, int func, int reg, int len)
{
struct ia64_sal_result res;
+ register_t is;
u_long addr;
addr = pci_sal_address(0, bus, slot, func, reg);
@@ -75,17 +77,18 @@ pci_cfgregread(int bus, int slot, int func, int reg, int len)
if (!pci_valid_access(reg, len))
return (~0);
+ is = intr_disable();
res = ia64_sal_entry(SAL_PCI_CONFIG_READ, addr, len, 0, 0, 0, 0, 0);
- if (res.sal_status < 0)
- return (~0);
+ intr_restore(is);
- return (res.sal_result[0]);
+ return ((res.sal_status < 0) ? ~0 : res.sal_result[0]);
}
void
pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, int len)
{
struct ia64_sal_result res;
+ register_t is;
u_long addr;
addr = pci_sal_address(0, bus, slot, func, reg);
@@ -95,5 +98,7 @@ pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, int len)
if (!pci_valid_access(reg, len))
return;
+ is = intr_disable();
res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE, addr, len, data, 0, 0, 0, 0);
+ intr_restore(is);
}
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index fa6ddaf..236894f 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -75,11 +75,6 @@ __FBSDID("$FreeBSD$");
#include <machine/elf.h>
#include <machine/md_var.h>
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
-#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
-#endif
-
#define OLD_EI_BRAND 8
static int __elfN(check_header)(const Elf_Ehdr *hdr);
@@ -837,13 +832,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
phdr[i].p_vaddr + et_dyn_addr - seg_addr);
/*
- * Is this .text or .data? We can't use
- * VM_PROT_WRITE or VM_PROT_EXEC, it breaks the
- * alpha terribly and possibly does other bad
- * things so we stick to the old way of figuring
- * it out: If the segment contains the program
- * entry point, it's a text segment, otherwise it
- * is a data segment.
+ * Make the largest executable segment the official
+ * text segment and all others data.
*
* Note that obreak() assumes that data_addr +
* data_size == end of data load area, and the ELF
@@ -851,12 +841,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* address. If multiple data segments exist, the
* last one will be used.
*/
- if (hdr->e_entry >= phdr[i].p_vaddr &&
- hdr->e_entry < (phdr[i].p_vaddr +
- phdr[i].p_memsz)) {
+
+ if (phdr[i].p_flags & PF_X && text_size < seg_size) {
text_size = seg_size;
text_addr = seg_addr;
- entry = (u_long)hdr->e_entry + et_dyn_addr;
} else {
data_size = seg_size;
data_addr = seg_addr;
@@ -876,6 +864,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
data_size = text_size;
}
+ entry = (u_long)hdr->e_entry + et_dyn_addr;
+
/*
* Check limits. It should be safe to check the
* limits after loading the segments since we do
@@ -953,6 +943,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
imgp->auxargs = elf_auxargs;
imgp->interpreted = 0;
+ imgp->reloc_base = addr;
imgp->proc->p_osrel = osrel;
return (error);
@@ -1136,11 +1127,11 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
#ifdef COMPRESS_USER_CORES
done:
-#endif
if (core_buf)
free(core_buf, M_TEMP);
if (gzfile)
gzclose(gzfile);
+#endif
free(hdr, M_TEMP);
@@ -1303,7 +1294,9 @@ __elfN(corehdr)(td, vp, cred, numsegs, hdr, hdrsize, gzfile)
}
}
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+#include <compat/freebsd32/freebsd32.h>
+
typedef struct prstatus32 elf_prstatus_t;
typedef struct prpsinfo32 elf_prpsinfo_t;
typedef struct fpreg32 elf_prfpregset_t;
@@ -1387,7 +1380,7 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
status->pr_osreldate = osreldate;
status->pr_cursig = p->p_sig;
status->pr_pid = thr->td_tid;
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
fill_regs32(thr, &status->pr_reg);
fill_fpregs32(thr, fpregset);
#else
@@ -1439,8 +1432,8 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
ehdr->e_ident[EI_ABIVERSION] = 0;
ehdr->e_ident[EI_PAD] = 0;
ehdr->e_type = ET_CORE;
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
- ehdr->e_machine = EM_386;
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+ ehdr->e_machine = ELF_ARCH32;
#else
ehdr->e_machine = ELF_ARCH;
#endif
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index f1508c8..e9090fb 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -382,8 +382,9 @@ static void
proc0_init(void *dummy __unused)
{
struct proc *p;
- unsigned i;
struct thread *td;
+ vm_paddr_t pageablemem;
+ int i;
GIANT_REQUIRED;
p = &proc0;
@@ -493,10 +494,16 @@ proc0_init(void *dummy __unused)
p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
- i = ptoa(cnt.v_free_count);
- p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
- p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
- p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
+ p->p_limit->pl_rlimit[RLIMIT_DATA].rlim_cur = dfldsiz;
+ p->p_limit->pl_rlimit[RLIMIT_DATA].rlim_max = maxdsiz;
+ p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur = dflssiz;
+ p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_max = maxssiz;
+ /* Cast to avoid overflow on i386/PAE. */
+ pageablemem = ptoa((vm_paddr_t)cnt.v_free_count);
+ p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_cur =
+ p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = pageablemem;
+ p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = pageablemem / 3;
+ p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = pageablemem;
p->p_cpulimit = RLIM_INFINITY;
p->p_stats = pstats_alloc();
@@ -510,9 +517,8 @@ proc0_init(void *dummy __unused)
* proc0 is not expected to enter usermode, so there is no special
* handling for sv_minuser here, like is done for exec_new_vmspace().
*/
- vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
- p->p_sysent->sv_maxuser);
- vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
+ vm_map_init(&vmspace0.vm_map, vmspace_pmap(&vmspace0),
+ p->p_sysent->sv_minuser, p->p_sysent->sv_maxuser);
/*-
* call the init and ctor for the new thread and proc
diff --git a/sys/kern/kern_alq.c b/sys/kern/kern_alq.c
index a4ece79..98e6de8 100644
--- a/sys/kern/kern_alq.c
+++ b/sys/kern/kern_alq.c
@@ -1,7 +1,13 @@
/*-
* Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org>
+ * Copyright (c) 2008-2009, Lawrence Stewart <lstewart@freebsd.org>
+ * Copyright (c) 2009-2010, The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed at the Centre for Advanced
+ * Internet Architectures, Swinburne University of Technology, Melbourne,
+ * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -27,6 +33,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_mac.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -47,16 +55,23 @@ __FBSDID("$FreeBSD$");
/* Async. Logging Queue */
struct alq {
+ char *aq_entbuf; /* Buffer for stored entries */
int aq_entmax; /* Max entries */
int aq_entlen; /* Entry length */
- char *aq_entbuf; /* Buffer for stored entries */
+ int aq_freebytes; /* Bytes available in buffer */
+ int aq_buflen; /* Total length of our buffer */
+ int aq_writehead; /* Location for next write */
+ int aq_writetail; /* Flush starts at this location */
+ int aq_wrapearly; /* # bytes left blank at end of buf */
int aq_flags; /* Queue flags */
+ int aq_waiters; /* Num threads waiting for resources
+ * NB: Used as a wait channel so must
+ * not be first field in the alq struct
+ */
+ struct ale aq_getpost; /* ALE for use by get/post */
struct mtx aq_mtx; /* Queue lock */
struct vnode *aq_vp; /* Open vnode handle */
struct ucred *aq_cred; /* Credentials of the opening thread */
- struct ale *aq_first; /* First ent */
- struct ale *aq_entfree; /* First free ent */
- struct ale *aq_entvalid; /* First ent valid for writing */
LIST_ENTRY(alq) aq_act; /* List of active queues */
LIST_ENTRY(alq) aq_link; /* List of all queues */
};
@@ -65,10 +80,14 @@ struct alq {
#define AQ_ACTIVE 0x0002 /* on the active list */
#define AQ_FLUSHING 0x0004 /* doing IO */
#define AQ_SHUTDOWN 0x0008 /* Queue no longer valid */
+#define AQ_ORDERED 0x0010 /* Queue enforces ordered writes */
+#define AQ_LEGACY 0x0020 /* Legacy queue (fixed length writes) */
#define ALQ_LOCK(alq) mtx_lock_spin(&(alq)->aq_mtx)
#define ALQ_UNLOCK(alq) mtx_unlock_spin(&(alq)->aq_mtx)
+#define HAS_PENDING_DATA(alq) ((alq)->aq_freebytes != (alq)->aq_buflen)
+
static MALLOC_DEFINE(M_ALD, "ALD", "ALD");
/*
@@ -95,6 +114,7 @@ static void ald_deactivate(struct alq *);
/* Internal queue functions */
static void alq_shutdown(struct alq *);
+static void alq_destroy(struct alq *);
static int alq_doio(struct alq *);
@@ -180,8 +200,15 @@ ald_daemon(void)
ALD_LOCK();
for (;;) {
- while ((alq = LIST_FIRST(&ald_active)) == NULL)
- msleep(&ald_active, &ald_mtx, PWAIT, "aldslp", 0);
+ while ((alq = LIST_FIRST(&ald_active)) == NULL &&
+ !ald_shutingdown)
+ mtx_sleep(&ald_active, &ald_mtx, PWAIT, "aldslp", 0);
+
+ /* Don't shutdown until all active ALQs are flushed. */
+ if (ald_shutingdown && alq == NULL) {
+ ALD_UNLOCK();
+ break;
+ }
ALQ_LOCK(alq);
ald_deactivate(alq);
@@ -189,9 +216,11 @@ ald_daemon(void)
needwakeup = alq_doio(alq);
ALQ_UNLOCK(alq);
if (needwakeup)
- wakeup(alq);
+ wakeup_one(alq);
ALD_LOCK();
}
+
+ kproc_exit(0);
}
static void
@@ -200,14 +229,29 @@ ald_shutdown(void *arg, int howto)
struct alq *alq;
ALD_LOCK();
+
+ /* Ensure no new queues can be created. */
ald_shutingdown = 1;
+ /* Shutdown all ALQs prior to terminating the ald_daemon. */
while ((alq = LIST_FIRST(&ald_queues)) != NULL) {
LIST_REMOVE(alq, aq_link);
ALD_UNLOCK();
alq_shutdown(alq);
ALD_LOCK();
}
+
+ /* At this point, all ALQs are flushed and shutdown. */
+
+ /*
+ * Wake ald_daemon so that it exits. It won't be able to do
+ * anything until we mtx_sleep because we hold the ald_mtx.
+ */
+ wakeup(&ald_active);
+
+ /* Wait for ald_daemon to exit. */
+ mtx_sleep(ald_proc, &ald_mtx, PWAIT, "aldslp", 0);
+
ALD_UNLOCK();
}
@@ -219,8 +263,22 @@ alq_shutdown(struct alq *alq)
/* Stop any new writers. */
alq->aq_flags |= AQ_SHUTDOWN;
+ /*
+ * If the ALQ isn't active but has unwritten data (possible if
+ * the ALQ_NOACTIVATE flag has been used), explicitly activate the
+ * ALQ here so that the pending data gets flushed by the ald_daemon.
+ */
+ if (!(alq->aq_flags & AQ_ACTIVE) && HAS_PENDING_DATA(alq)) {
+ alq->aq_flags |= AQ_ACTIVE;
+ ALQ_UNLOCK(alq);
+ ALD_LOCK();
+ ald_activate(alq);
+ ALD_UNLOCK();
+ ALQ_LOCK(alq);
+ }
+
/* Drain IO */
- while (alq->aq_flags & (AQ_FLUSHING|AQ_ACTIVE)) {
+ while (alq->aq_flags & AQ_ACTIVE) {
alq->aq_flags |= AQ_WANTED;
msleep_spin(alq, &alq->aq_mtx, "aldclose", 0);
}
@@ -231,6 +289,17 @@ alq_shutdown(struct alq *alq)
crfree(alq->aq_cred);
}
+void
+alq_destroy(struct alq *alq)
+{
+ /* Drain all pending IO. */
+ alq_shutdown(alq);
+
+ mtx_destroy(&alq->aq_mtx);
+ free(alq->aq_entbuf, M_ALD);
+ free(alq, M_ALD);
+}
+
/*
* Flush all pending data to disk. This operation will block.
*/
@@ -242,46 +311,54 @@ alq_doio(struct alq *alq)
struct vnode *vp;
struct uio auio;
struct iovec aiov[2];
- struct ale *ale;
- struct ale *alstart;
int totlen;
int iov;
int vfslocked;
+ int wrapearly;
+
+ KASSERT((HAS_PENDING_DATA(alq)), ("%s: queue empty!", __func__));
vp = alq->aq_vp;
td = curthread;
totlen = 0;
- iov = 0;
-
- alstart = ale = alq->aq_entvalid;
- alq->aq_entvalid = NULL;
+ iov = 1;
+ wrapearly = alq->aq_wrapearly;
bzero(&aiov, sizeof(aiov));
bzero(&auio, sizeof(auio));
- do {
- if (aiov[iov].iov_base == NULL)
- aiov[iov].iov_base = ale->ae_data;
- aiov[iov].iov_len += alq->aq_entlen;
- totlen += alq->aq_entlen;
- /* Check to see if we're wrapping the buffer */
- if (ale->ae_data + alq->aq_entlen != ale->ae_next->ae_data)
- iov++;
- ale->ae_flags &= ~AE_VALID;
- ale = ale->ae_next;
- } while (ale->ae_flags & AE_VALID);
+ /* Start the write from the location of our buffer tail pointer. */
+ aiov[0].iov_base = alq->aq_entbuf + alq->aq_writetail;
+
+ if (alq->aq_writetail < alq->aq_writehead) {
+ /* Buffer not wrapped. */
+ totlen = aiov[0].iov_len = alq->aq_writehead - alq->aq_writetail;
+ } else if (alq->aq_writehead == 0) {
+ /* Buffer not wrapped (special case to avoid an empty iov). */
+ totlen = aiov[0].iov_len = alq->aq_buflen - alq->aq_writetail -
+ wrapearly;
+ } else {
+ /*
+ * Buffer wrapped, requires 2 aiov entries:
+ * - first is from writetail to end of buffer
+ * - second is from start of buffer to writehead
+ */
+ aiov[0].iov_len = alq->aq_buflen - alq->aq_writetail -
+ wrapearly;
+ iov++;
+ aiov[1].iov_base = alq->aq_entbuf;
+ aiov[1].iov_len = alq->aq_writehead;
+ totlen = aiov[0].iov_len + aiov[1].iov_len;
+ }
alq->aq_flags |= AQ_FLUSHING;
ALQ_UNLOCK(alq);
- if (iov == 2 || aiov[iov].iov_base == NULL)
- iov--;
-
auio.uio_iov = &aiov[0];
auio.uio_offset = 0;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_WRITE;
- auio.uio_iovcnt = iov + 1;
+ auio.uio_iovcnt = iov;
auio.uio_resid = totlen;
auio.uio_td = td;
@@ -305,8 +382,28 @@ alq_doio(struct alq *alq)
ALQ_LOCK(alq);
alq->aq_flags &= ~AQ_FLUSHING;
- if (alq->aq_entfree == NULL)
- alq->aq_entfree = alstart;
+ /* Adjust writetail as required, taking into account wrapping. */
+ alq->aq_writetail = (alq->aq_writetail + totlen + wrapearly) %
+ alq->aq_buflen;
+ alq->aq_freebytes += totlen + wrapearly;
+
+ /*
+ * If we just flushed part of the buffer which wrapped, reset the
+ * wrapearly indicator.
+ */
+ if (wrapearly)
+ alq->aq_wrapearly = 0;
+
+ /*
+ * If we just flushed the buffer completely, reset indexes to 0 to
+ * minimise buffer wraps.
+ * This is also required to ensure alq_getn() can't wedge itself.
+ */
+ if (!HAS_PENDING_DATA(alq))
+ alq->aq_writehead = alq->aq_writetail = 0;
+
+ KASSERT((alq->aq_writetail >= 0 && alq->aq_writetail < alq->aq_buflen),
+ ("%s: aq_writetail < 0 || aq_writetail >= aq_buflen", __func__));
if (alq->aq_flags & AQ_WANTED) {
alq->aq_flags &= ~AQ_WANTED;
@@ -331,27 +428,27 @@ SYSINIT(ald, SI_SUB_LOCK, SI_ORDER_ANY, ald_startup, NULL);
/*
* Create the queue data structure, allocate the buffer, and open the file.
*/
+
int
-alq_open(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
- int size, int count)
+alq_open_flags(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
+ int size, int flags)
{
struct thread *td;
struct nameidata nd;
- struct ale *ale;
- struct ale *alp;
struct alq *alq;
- char *bufp;
- int flags;
+ int oflags;
int error;
- int i, vfslocked;
+ int vfslocked;
+
+ KASSERT((size > 0), ("%s: size <= 0", __func__));
*alqp = NULL;
td = curthread;
NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, file, td);
- flags = FWRITE | O_NOFOLLOW | O_CREAT;
+ oflags = FWRITE | O_NOFOLLOW | O_CREAT;
- error = vn_open_cred(&nd, &flags, cmode, 0, cred, NULL);
+ error = vn_open_cred(&nd, &oflags, cmode, 0, cred, NULL);
if (error)
return (error);
@@ -362,110 +459,430 @@ alq_open(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
VFS_UNLOCK_GIANT(vfslocked);
alq = malloc(sizeof(*alq), M_ALD, M_WAITOK|M_ZERO);
- alq->aq_entbuf = malloc(count * size, M_ALD, M_WAITOK|M_ZERO);
- alq->aq_first = malloc(sizeof(*ale) * count, M_ALD, M_WAITOK|M_ZERO);
alq->aq_vp = nd.ni_vp;
alq->aq_cred = crhold(cred);
- alq->aq_entmax = count;
- alq->aq_entlen = size;
- alq->aq_entfree = alq->aq_first;
mtx_init(&alq->aq_mtx, "ALD Queue", NULL, MTX_SPIN|MTX_QUIET);
- bufp = alq->aq_entbuf;
- ale = alq->aq_first;
- alp = NULL;
-
- /* Match up entries with buffers */
- for (i = 0; i < count; i++) {
- if (alp)
- alp->ae_next = ale;
- ale->ae_data = bufp;
- alp = ale;
- ale++;
- bufp += size;
- }
+ alq->aq_buflen = size;
+ alq->aq_entmax = 0;
+ alq->aq_entlen = 0;
- alp->ae_next = alq->aq_first;
+ alq->aq_freebytes = alq->aq_buflen;
+ alq->aq_entbuf = malloc(alq->aq_buflen, M_ALD, M_WAITOK|M_ZERO);
+ alq->aq_writehead = alq->aq_writetail = 0;
+ if (flags & ALQ_ORDERED)
+ alq->aq_flags |= AQ_ORDERED;
- if ((error = ald_add(alq)) != 0)
+ if ((error = ald_add(alq)) != 0) {
+ alq_destroy(alq);
return (error);
+ }
+
*alqp = alq;
return (0);
}
+int
+alq_open(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
+ int size, int count)
+{
+ int ret;
+
+ KASSERT((count >= 0), ("%s: count < 0", __func__));
+
+ if (count > 0) {
+ ret = alq_open_flags(alqp, file, cred, cmode, size*count, 0);
+ (*alqp)->aq_flags |= AQ_LEGACY;
+ (*alqp)->aq_entmax = count;
+ (*alqp)->aq_entlen = size;
+ } else
+ ret = alq_open_flags(alqp, file, cred, cmode, size, 0);
+
+ return (ret);
+}
+
+
/*
* Copy a new entry into the queue. If the operation would block either
* wait or return an error depending on the value of waitok.
*/
int
-alq_write(struct alq *alq, void *data, int waitok)
+alq_writen(struct alq *alq, void *data, int len, int flags)
{
- struct ale *ale;
+ int activate, copy, ret;
+ void *waitchan;
- if ((ale = alq_get(alq, waitok)) == NULL)
+ KASSERT((len > 0 && len <= alq->aq_buflen),
+ ("%s: len <= 0 || len > aq_buflen", __func__));
+
+ activate = ret = 0;
+ copy = len;
+ waitchan = NULL;
+
+ ALQ_LOCK(alq);
+
+ /*
+ * Fail to perform the write and return EWOULDBLOCK if:
+ * - The message is larger than our underlying buffer.
+ * - The ALQ is being shutdown.
+ * - There is insufficient free space in our underlying buffer
+ * to accept the message and the user can't wait for space.
+ * - There is insufficient free space in our underlying buffer
+ * to accept the message and the alq is inactive due to prior
+ * use of the ALQ_NOACTIVATE flag (which would lead to deadlock).
+ */
+ if (len > alq->aq_buflen ||
+ alq->aq_flags & AQ_SHUTDOWN ||
+ (((flags & ALQ_NOWAIT) || (!(alq->aq_flags & AQ_ACTIVE) &&
+ HAS_PENDING_DATA(alq))) && alq->aq_freebytes < len)) {
+ ALQ_UNLOCK(alq);
return (EWOULDBLOCK);
+ }
- bcopy(data, ale->ae_data, alq->aq_entlen);
- alq_post(alq, ale);
+ /*
+ * If we want ordered writes and there is already at least one thread
+ * waiting for resources to become available, sleep until we're woken.
+ */
+ if (alq->aq_flags & AQ_ORDERED && alq->aq_waiters > 0) {
+ KASSERT(!(flags & ALQ_NOWAIT),
+ ("%s: ALQ_NOWAIT set but incorrectly ignored!", __func__));
+ alq->aq_waiters++;
+ msleep_spin(&alq->aq_waiters, &alq->aq_mtx, "alqwnord", 0);
+ alq->aq_waiters--;
+ }
- return (0);
+ /*
+ * (ALQ_WAITOK && aq_freebytes < len) or aq_freebytes >= len, either
+ * enter while loop and sleep until we have enough free bytes (former)
+ * or skip (latter). If AQ_ORDERED is set, only 1 thread at a time will
+ * be in this loop. Otherwise, multiple threads may be sleeping here
+ * competing for ALQ resources.
+ */
+ while (alq->aq_freebytes < len && !(alq->aq_flags & AQ_SHUTDOWN)) {
+ KASSERT(!(flags & ALQ_NOWAIT),
+ ("%s: ALQ_NOWAIT set but incorrectly ignored!", __func__));
+ alq->aq_flags |= AQ_WANTED;
+ alq->aq_waiters++;
+ if (waitchan)
+ wakeup(waitchan);
+ msleep_spin(alq, &alq->aq_mtx, "alqwnres", 0);
+ alq->aq_waiters--;
+
+ /*
+ * If we're the first thread to wake after an AQ_WANTED wakeup
+ * but there isn't enough free space for us, we're going to loop
+ * and sleep again. If there are other threads waiting in this
+ * loop, schedule a wakeup so that they can see if the space
+ * they require is available.
+ */
+ if (alq->aq_waiters > 0 && !(alq->aq_flags & AQ_ORDERED) &&
+ alq->aq_freebytes < len && !(alq->aq_flags & AQ_WANTED))
+ waitchan = alq;
+ else
+ waitchan = NULL;
+ }
+
+ /*
+ * If there are waiters, we need to signal the waiting threads after we
+ * complete our work. The alq ptr is used as a wait channel for threads
+ * requiring resources to be freed up. In the AQ_ORDERED case, threads
+ * are not allowed to concurrently compete for resources in the above
+ * while loop, so we use a different wait channel in this case.
+ */
+ if (alq->aq_waiters > 0) {
+ if (alq->aq_flags & AQ_ORDERED)
+ waitchan = &alq->aq_waiters;
+ else
+ waitchan = alq;
+ } else
+ waitchan = NULL;
+
+ /* Bail if we're shutting down. */
+ if (alq->aq_flags & AQ_SHUTDOWN) {
+ ret = EWOULDBLOCK;
+ goto unlock;
+ }
+
+ /*
+ * If we need to wrap the buffer to accommodate the write,
+ * we'll need 2 calls to bcopy.
+ */
+ if ((alq->aq_buflen - alq->aq_writehead) < len)
+ copy = alq->aq_buflen - alq->aq_writehead;
+
+ /* Copy message (or part thereof if wrap required) to the buffer. */
+ bcopy(data, alq->aq_entbuf + alq->aq_writehead, copy);
+ alq->aq_writehead += copy;
+
+ if (alq->aq_writehead >= alq->aq_buflen) {
+ KASSERT((alq->aq_writehead == alq->aq_buflen),
+ ("%s: alq->aq_writehead (%d) > alq->aq_buflen (%d)",
+ __func__,
+ alq->aq_writehead,
+ alq->aq_buflen));
+ alq->aq_writehead = 0;
+ }
+
+ if (copy != len) {
+ /*
+ * Wrap the buffer by copying the remainder of our message
+ * to the start of the buffer and resetting aq_writehead.
+ */
+ bcopy(((uint8_t *)data)+copy, alq->aq_entbuf, len - copy);
+ alq->aq_writehead = len - copy;
+ }
+
+ KASSERT((alq->aq_writehead >= 0 && alq->aq_writehead < alq->aq_buflen),
+ ("%s: aq_writehead < 0 || aq_writehead >= aq_buflen", __func__));
+
+ alq->aq_freebytes -= len;
+
+ if (!(alq->aq_flags & AQ_ACTIVE) && !(flags & ALQ_NOACTIVATE)) {
+ alq->aq_flags |= AQ_ACTIVE;
+ activate = 1;
+ }
+
+ KASSERT((HAS_PENDING_DATA(alq)), ("%s: queue empty!", __func__));
+
+unlock:
+ ALQ_UNLOCK(alq);
+
+ if (activate) {
+ ALD_LOCK();
+ ald_activate(alq);
+ ALD_UNLOCK();
+ }
+
+ /* NB: We rely on wakeup_one waking threads in a FIFO manner. */
+ if (waitchan != NULL)
+ wakeup_one(waitchan);
+
+ return (ret);
+}
+
+int
+alq_write(struct alq *alq, void *data, int flags)
+{
+ /* Should only be called in fixed length message (legacy) mode. */
+ KASSERT((alq->aq_flags & AQ_LEGACY),
+ ("%s: fixed length write on variable length queue", __func__));
+ return (alq_writen(alq, data, alq->aq_entlen, flags));
}
+/*
+ * Retrieve a pointer for the ALQ to write directly into, avoiding bcopy.
+ */
struct ale *
-alq_get(struct alq *alq, int waitok)
+alq_getn(struct alq *alq, int len, int flags)
{
- struct ale *ale;
- struct ale *aln;
+ int contigbytes;
+ void *waitchan;
- ale = NULL;
+ KASSERT((len > 0 && len <= alq->aq_buflen),
+ ("%s: len <= 0 || len > alq->aq_buflen", __func__));
+
+ waitchan = NULL;
ALQ_LOCK(alq);
- /* Loop until we get an entry or we're shutting down */
- while ((alq->aq_flags & AQ_SHUTDOWN) == 0 &&
- (ale = alq->aq_entfree) == NULL &&
- (waitok & ALQ_WAITOK)) {
+ /*
+ * Determine the number of free contiguous bytes.
+ * We ensure elsewhere that if aq_writehead == aq_writetail because
+ * the buffer is empty, they will both be set to 0 and therefore
+ * aq_freebytes == aq_buflen and is fully contiguous.
+ * If they are equal and the buffer is not empty, aq_freebytes will
+ * be 0 indicating the buffer is full.
+ */
+ if (alq->aq_writehead <= alq->aq_writetail)
+ contigbytes = alq->aq_freebytes;
+ else {
+ contigbytes = alq->aq_buflen - alq->aq_writehead;
+
+ if (contigbytes < len) {
+ /*
+ * Insufficient space at end of buffer to handle a
+ * contiguous write. Wrap early if there's space at
+ * the beginning. This will leave a hole at the end
+ * of the buffer which we will have to skip over when
+ * flushing the buffer to disk.
+ */
+ if (alq->aq_writetail >= len || flags & ALQ_WAITOK) {
+ /* Keep track of # bytes left blank. */
+ alq->aq_wrapearly = contigbytes;
+ /* Do the wrap and adjust counters. */
+ contigbytes = alq->aq_freebytes =
+ alq->aq_writetail;
+ alq->aq_writehead = 0;
+ }
+ }
+ }
+
+ /*
+ * Return a NULL ALE if:
+ * - The message is larger than our underlying buffer.
+ * - The ALQ is being shutdown.
+ * - There is insufficient free space in our underlying buffer
+ * to accept the message and the user can't wait for space.
+ * - There is insufficient free space in our underlying buffer
+ * to accept the message and the alq is inactive due to prior
+ * use of the ALQ_NOACTIVATE flag (which would lead to deadlock).
+ */
+ if (len > alq->aq_buflen ||
+ alq->aq_flags & AQ_SHUTDOWN ||
+ (((flags & ALQ_NOWAIT) || (!(alq->aq_flags & AQ_ACTIVE) &&
+ HAS_PENDING_DATA(alq))) && contigbytes < len)) {
+ ALQ_UNLOCK(alq);
+ return (NULL);
+ }
+
+ /*
+ * If we want ordered writes and there is already at least one thread
+ * waiting for resources to become available, sleep until we're woken.
+ */
+ if (alq->aq_flags & AQ_ORDERED && alq->aq_waiters > 0) {
+ KASSERT(!(flags & ALQ_NOWAIT),
+ ("%s: ALQ_NOWAIT set but incorrectly ignored!", __func__));
+ alq->aq_waiters++;
+ msleep_spin(&alq->aq_waiters, &alq->aq_mtx, "alqgnord", 0);
+ alq->aq_waiters--;
+ }
+
+ /*
+ * (ALQ_WAITOK && contigbytes < len) or contigbytes >= len, either enter
+ * while loop and sleep until we have enough contiguous free bytes
+ * (former) or skip (latter). If AQ_ORDERED is set, only 1 thread at a
+ * time will be in this loop. Otherwise, multiple threads may be
+ * sleeping here competing for ALQ resources.
+ */
+ while (contigbytes < len && !(alq->aq_flags & AQ_SHUTDOWN)) {
+ KASSERT(!(flags & ALQ_NOWAIT),
+ ("%s: ALQ_NOWAIT set but incorrectly ignored!", __func__));
alq->aq_flags |= AQ_WANTED;
- msleep_spin(alq, &alq->aq_mtx, "alqget", 0);
+ alq->aq_waiters++;
+ if (waitchan)
+ wakeup(waitchan);
+ msleep_spin(alq, &alq->aq_mtx, "alqgnres", 0);
+ alq->aq_waiters--;
+
+ if (alq->aq_writehead <= alq->aq_writetail)
+ contigbytes = alq->aq_freebytes;
+ else
+ contigbytes = alq->aq_buflen - alq->aq_writehead;
+
+ /*
+ * If we're the first thread to wake after an AQ_WANTED wakeup
+ * but there isn't enough free space for us, we're going to loop
+ * and sleep again. If there are other threads waiting in this
+ * loop, schedule a wakeup so that they can see if the space
+ * they require is available.
+ */
+ if (alq->aq_waiters > 0 && !(alq->aq_flags & AQ_ORDERED) &&
+ contigbytes < len && !(alq->aq_flags & AQ_WANTED))
+ waitchan = alq;
+ else
+ waitchan = NULL;
}
- if (ale != NULL) {
- aln = ale->ae_next;
- if ((aln->ae_flags & AE_VALID) == 0)
- alq->aq_entfree = aln;
+ /*
+ * If there are waiters, we need to signal the waiting threads after we
+ * complete our work. The alq ptr is used as a wait channel for threads
+ * requiring resources to be freed up. In the AQ_ORDERED case, threads
+ * are not allowed to concurrently compete for resources in the above
+ * while loop, so we use a different wait channel in this case.
+ */
+ if (alq->aq_waiters > 0) {
+ if (alq->aq_flags & AQ_ORDERED)
+ waitchan = &alq->aq_waiters;
else
- alq->aq_entfree = NULL;
+ waitchan = alq;
} else
+ waitchan = NULL;
+
+ /* Bail if we're shutting down. */
+ if (alq->aq_flags & AQ_SHUTDOWN) {
ALQ_UNLOCK(alq);
+ if (waitchan != NULL)
+ wakeup_one(waitchan);
+ return (NULL);
+ }
+
+ /*
+ * If we are here, we have a contiguous number of bytes >= len
+ * available in our buffer starting at aq_writehead.
+ */
+ alq->aq_getpost.ae_data = alq->aq_entbuf + alq->aq_writehead;
+ alq->aq_getpost.ae_bytesused = len;
+ return (&alq->aq_getpost);
+}
- return (ale);
+struct ale *
+alq_get(struct alq *alq, int flags)
+{
+ /* Should only be called in fixed length message (legacy) mode. */
+ KASSERT((alq->aq_flags & AQ_LEGACY),
+ ("%s: fixed length get on variable length queue", __func__));
+ return (alq_getn(alq, alq->aq_entlen, flags));
}
void
-alq_post(struct alq *alq, struct ale *ale)
+alq_post_flags(struct alq *alq, struct ale *ale, int flags)
{
int activate;
+ void *waitchan;
- ale->ae_flags |= AE_VALID;
+ activate = 0;
- if (alq->aq_entvalid == NULL)
- alq->aq_entvalid = ale;
+ if (ale->ae_bytesused > 0) {
+ if (!(alq->aq_flags & AQ_ACTIVE) &&
+ !(flags & ALQ_NOACTIVATE)) {
+ alq->aq_flags |= AQ_ACTIVE;
+ activate = 1;
+ }
- if ((alq->aq_flags & AQ_ACTIVE) == 0) {
- alq->aq_flags |= AQ_ACTIVE;
- activate = 1;
+ alq->aq_writehead += ale->ae_bytesused;
+ alq->aq_freebytes -= ale->ae_bytesused;
+
+ /* Wrap aq_writehead if we filled to the end of the buffer. */
+ if (alq->aq_writehead == alq->aq_buflen)
+ alq->aq_writehead = 0;
+
+ KASSERT((alq->aq_writehead >= 0 &&
+ alq->aq_writehead < alq->aq_buflen),
+ ("%s: aq_writehead < 0 || aq_writehead >= aq_buflen",
+ __func__));
+
+ KASSERT((HAS_PENDING_DATA(alq)), ("%s: queue empty!", __func__));
+ }
+
+ /*
+ * If there are waiters, we need to signal the waiting threads after we
+ * complete our work. The alq ptr is used as a wait channel for threads
+ * requiring resources to be freed up. In the AQ_ORDERED case, threads
+ * are not allowed to concurrently compete for resources in the
+ * alq_getn() while loop, so we use a different wait channel in this case.
+ */
+ if (alq->aq_waiters > 0) {
+ if (alq->aq_flags & AQ_ORDERED)
+ waitchan = &alq->aq_waiters;
+ else
+ waitchan = alq;
} else
- activate = 0;
+ waitchan = NULL;
ALQ_UNLOCK(alq);
+
if (activate) {
ALD_LOCK();
ald_activate(alq);
ALD_UNLOCK();
}
+
+ /* NB: We rely on wakeup_one waking threads in a FIFO manner. */
+ if (waitchan != NULL)
+ wakeup_one(waitchan);
}
void
@@ -475,16 +892,24 @@ alq_flush(struct alq *alq)
ALD_LOCK();
ALQ_LOCK(alq);
- if (alq->aq_flags & AQ_ACTIVE) {
- ald_deactivate(alq);
+
+ /*
+ * Pull the lever iff there is data to flush and we're
+ * not already in the middle of a flush operation.
+ */
+ if (HAS_PENDING_DATA(alq) && !(alq->aq_flags & AQ_FLUSHING)) {
+ if (alq->aq_flags & AQ_ACTIVE)
+ ald_deactivate(alq);
+
ALD_UNLOCK();
needwakeup = alq_doio(alq);
} else
ALD_UNLOCK();
+
ALQ_UNLOCK(alq);
if (needwakeup)
- wakeup(alq);
+ wakeup_one(alq);
}
/*
@@ -493,20 +918,57 @@ alq_flush(struct alq *alq)
void
alq_close(struct alq *alq)
{
- /*
- * If we're already shuting down someone else will flush and close
- * the vnode.
- */
- if (ald_rem(alq) != 0)
- return;
+ /* Only flush and destroy alq if not already shutting down. */
+ if (ald_rem(alq) == 0)
+ alq_destroy(alq);
+}
- /*
- * Drain all pending IO.
- */
- alq_shutdown(alq);
+static int
+alq_load_handler(module_t mod, int what, void *arg)
+{
+ int ret;
+
+ ret = 0;
- mtx_destroy(&alq->aq_mtx);
- free(alq->aq_first, M_ALD);
- free(alq->aq_entbuf, M_ALD);
- free(alq, M_ALD);
+ switch (what) {
+ case MOD_LOAD:
+ case MOD_SHUTDOWN:
+ break;
+
+ case MOD_QUIESCE:
+ ALD_LOCK();
+ /* Only allow unload if there are no open queues. */
+ if (LIST_FIRST(&ald_queues) == NULL) {
+ ald_shutingdown = 1;
+ ALD_UNLOCK();
+ ald_shutdown(NULL, 0);
+ mtx_destroy(&ald_mtx);
+ } else {
+ ALD_UNLOCK();
+ ret = EBUSY;
+ }
+ break;
+
+ case MOD_UNLOAD:
+ /* If MOD_QUIESCE failed we must fail here too. */
+ if (ald_shutingdown == 0)
+ ret = EBUSY;
+ break;
+
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return (ret);
}
+
+static moduledata_t alq_mod =
+{
+ "alq",
+ alq_load_handler,
+ NULL
+};
+
+DECLARE_MODULE(alq, alq_mod, SI_SUB_SMP, SI_ORDER_ANY);
+MODULE_VERSION(alq, 1);
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 2844103..da05cc1 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -162,6 +162,12 @@ SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,
0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics");
#ifdef DEADLKRES
+static const char *blessed[] = {
+ "getblk",
+ "so_snd_sx",
+ "so_rcv_sx",
+ NULL
+};
static int slptime_threshold = 1800;
static int blktime_threshold = 900;
static int sleepfreq = 3;
@@ -172,7 +178,7 @@ deadlkres(void)
struct proc *p;
struct thread *td;
void *wchan;
- int blkticks, slpticks, slptype, tryl, tticks;
+ int blkticks, i, slpticks, slptype, tryl, tticks;
tryl = 0;
for (;;) {
@@ -205,6 +211,10 @@ deadlkres(void)
* turnstile channel is in good state.
*/
MPASS(td->td_blocked != NULL);
+
+ /* Handle ticks wrap-up. */
+ if (ticks < td->td_blktick)
+ continue;
tticks = ticks - td->td_blktick;
thread_unlock(td);
if (tticks > blkticks) {
@@ -222,6 +232,10 @@ deadlkres(void)
}
} else if (TD_IS_SLEEPING(td)) {
+ /* Handle ticks wrap-up. */
+ if (ticks < td->td_blktick)
+ continue;
+
/*
* Check if the thread is sleeping on a
* lock, otherwise skip the check.
@@ -242,7 +256,24 @@ deadlkres(void)
* thresholds, this thread is
* stuck for too long on a
* sleepqueue.
+ * However, being on a
+ * sleepqueue, we might still
+ * check for the blessed
+ * list.
*/
+ tryl = 0;
+ for (i = 0; blessed[i] != NULL;
+ i++) {
+ if (!strcmp(blessed[i],
+ td->td_wmesg)) {
+ tryl = 1;
+ break;
+ }
+ }
+ if (tryl != 0) {
+ tryl = 0;
+ continue;
+ }
PROC_UNLOCK(p);
sx_sunlock(&allproc_lock);
panic("%s: possible deadlock detected for %p, blocked for %d ticks\n",
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 676de65..302ca5e 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2896,7 +2896,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
free(sa, M_SONAME);
}
if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa)
- == 00 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
+ == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
free(sa, M_SONAME);
}
@@ -3149,7 +3149,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS)
free(sa, M_SONAME);
}
if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa)
- == 00 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
+ == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
free(sa, M_SONAME);
}
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index cb418fb..5df669d 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1218,7 +1218,7 @@ static int
kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
int waitok)
{
- struct klist *list, *tmp_knhash;
+ struct klist *list, *tmp_knhash, *to_free;
u_long tmp_knhashmask;
int size;
int fd;
@@ -1226,6 +1226,7 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
KQ_NOTOWNED(kq);
+ to_free = NULL;
if (fops->f_isfd) {
fd = ident;
if (kq->kq_knlistsize <= fd) {
@@ -1237,13 +1238,13 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
return ENOMEM;
KQ_LOCK(kq);
if (kq->kq_knlistsize > fd) {
- free(list, M_KQUEUE);
+ to_free = list;
list = NULL;
} else {
if (kq->kq_knlist != NULL) {
bcopy(kq->kq_knlist, list,
kq->kq_knlistsize * sizeof(*list));
- free(kq->kq_knlist, M_KQUEUE);
+ to_free = kq->kq_knlist;
kq->kq_knlist = NULL;
}
bzero((caddr_t)list +
@@ -1265,11 +1266,12 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
kq->kq_knhash = tmp_knhash;
kq->kq_knhashmask = tmp_knhashmask;
} else {
- free(tmp_knhash, M_KQUEUE);
+ to_free = tmp_knhash;
}
KQ_UNLOCK(kq);
}
}
+ free(to_free, M_KQUEUE);
KQ_NOTOWNED(kq);
return 0;
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index dce624d..ed22519 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -372,6 +372,7 @@ do_execve(td, args, mac_p)
imgp->execlabel = NULL;
imgp->attr = &attr;
imgp->entry_addr = 0;
+ imgp->reloc_base = 0;
imgp->vmspace_destroyed = 0;
imgp->interpreted = 0;
imgp->opened = 0;
@@ -799,11 +800,10 @@ interpret:
/* Set values passed into the program in registers. */
if (p->p_sysent->sv_setregs)
- (*p->p_sysent->sv_setregs)(td, imgp->entry_addr,
- (u_long)(uintptr_t)stack_base, imgp->ps_strings);
+ (*p->p_sysent->sv_setregs)(td, imgp,
+ (u_long)(uintptr_t)stack_base);
else
- exec_setregs(td, imgp->entry_addr,
- (u_long)(uintptr_t)stack_base, imgp->ps_strings);
+ exec_setregs(td, imgp, (u_long)(uintptr_t)stack_base);
vfs_mark_atime(imgp->vp, td->td_ucred);
@@ -1260,7 +1260,7 @@ exec_copyout_strings(imgp)
* Fill in "ps_strings" struct for ps, w, etc.
*/
suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
- suword(&arginfo->ps_nargvstr, argc);
+ suword32(&arginfo->ps_nargvstr, argc);
/*
* Fill in argument portion of vector table.
@@ -1276,7 +1276,7 @@ exec_copyout_strings(imgp)
suword(vectp++, 0);
suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
- suword(&arginfo->ps_nenvstr, envc);
+ suword32(&arginfo->ps_nenvstr, envc);
/*
* Fill in environment portion of vector table.
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 93fdfa9..d419833 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -734,8 +734,8 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
}
}
-#ifdef COMPAT_IA32
- if (td->td_proc->p_sysent->sv_flags & SV_IA32) {
+#ifdef COMPAT_FREEBSD32
+ if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
uint32_t hid32;
error = vfs_copyopt(opts, "host.hostid", &hid32, sizeof(hid32));
@@ -1961,8 +1961,8 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
error = vfs_setopts(opts, "host.hostuuid", pr->pr_hostuuid);
if (error != 0 && error != ENOENT)
goto done_deref;
-#ifdef COMPAT_IA32
- if (td->td_proc->p_sysent->sv_flags & SV_IA32) {
+#ifdef COMPAT_FREEBSD32
+ if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
uint32_t hid32 = pr->pr_hostid;
error = vfs_setopt(opts, "host.hostid", &hid32, sizeof(hid32));
diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c
index 721cc52..9586ae6 100644
--- a/sys/kern/kern_ktr.c
+++ b/sys/kern/kern_ktr.c
@@ -84,20 +84,25 @@ SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options");
int ktr_cpumask = KTR_CPUMASK;
TUNABLE_INT("debug.ktr.cpumask", &ktr_cpumask);
-SYSCTL_INT(_debug_ktr, OID_AUTO, cpumask, CTLFLAG_RW, &ktr_cpumask, 0, "");
+SYSCTL_INT(_debug_ktr, OID_AUTO, cpumask, CTLFLAG_RW,
+ &ktr_cpumask, 0, "Bitmask of CPUs on which KTR logging is enabled");
int ktr_mask = KTR_MASK;
TUNABLE_INT("debug.ktr.mask", &ktr_mask);
-SYSCTL_INT(_debug_ktr, OID_AUTO, mask, CTLFLAG_RW, &ktr_mask, 0, "");
+SYSCTL_INT(_debug_ktr, OID_AUTO, mask, CTLFLAG_RW,
+ &ktr_mask, 0, "Bitmask of KTR event classes for which logging is enabled");
int ktr_compile = KTR_COMPILE;
-SYSCTL_INT(_debug_ktr, OID_AUTO, compile, CTLFLAG_RD, &ktr_compile, 0, "");
+SYSCTL_INT(_debug_ktr, OID_AUTO, compile, CTLFLAG_RD,
+ &ktr_compile, 0, "Bitmask of KTR event classes compiled into the kernel");
int ktr_entries = KTR_ENTRIES;
-SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD, &ktr_entries, 0, "");
+SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD,
+ &ktr_entries, 0, "Number of entries in the KTR buffer");
int ktr_version = KTR_VERSION;
-SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, &ktr_version, 0, "");
+SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD,
+ &ktr_version, 0, "Version of the KTR interface");
volatile int ktr_idx = 0;
struct ktr_entry ktr_buf[KTR_ENTRIES];
@@ -194,9 +199,8 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format,
struct ktr_entry *entry;
#ifdef KTR_ALQ
struct ale *ale = NULL;
-#else
- int newindex, saveindex;
#endif
+ int newindex, saveindex;
#if defined(KTR_VERBOSE) || defined(KTR_ALQ)
struct thread *td;
#endif
@@ -216,27 +220,30 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format,
td->td_pflags |= TDP_INKTR;
#endif
#ifdef KTR_ALQ
- if (ktr_alq_enabled &&
- td->td_critnest == 0 &&
- (td->td_flags & TDF_IDLETD) == 0 &&
- td != ald_thread) {
- if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max)
- goto done;
- if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) {
- ktr_alq_failed++;
+ if (ktr_alq_enabled) {
+ if (td->td_critnest == 0 &&
+ (td->td_flags & TDF_IDLETD) == 0 &&
+ td != ald_thread) {
+ if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max)
+ goto done;
+ if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) {
+ ktr_alq_failed++;
+ goto done;
+ }
+ ktr_alq_cnt++;
+ entry = (struct ktr_entry *)ale->ae_data;
+ } else {
goto done;
}
- ktr_alq_cnt++;
- entry = (struct ktr_entry *)ale->ae_data;
} else
- goto done;
-#else
- do {
- saveindex = ktr_idx;
- newindex = (saveindex + 1) & (KTR_ENTRIES - 1);
- } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0);
- entry = &ktr_buf[saveindex];
#endif
+ {
+ do {
+ saveindex = ktr_idx;
+ newindex = (saveindex + 1) & (KTR_ENTRIES - 1);
+ } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0);
+ entry = &ktr_buf[saveindex];
+ }
entry->ktr_timestamp = KTR_TIME;
entry->ktr_cpu = cpu;
entry->ktr_thread = curthread;
@@ -266,7 +273,7 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format,
entry->ktr_parms[4] = arg5;
entry->ktr_parms[5] = arg6;
#ifdef KTR_ALQ
- if (ale)
+ if (ktr_alq_enabled && ale)
alq_post(ktr_alq, ale);
done:
#endif
@@ -290,7 +297,9 @@ DB_SHOW_COMMAND(ktr, db_ktr_all)
tstate.cur = (ktr_idx - 1) & (KTR_ENTRIES - 1);
tstate.first = -1;
- db_ktr_verbose = index(modif, 'v') != NULL;
+ db_ktr_verbose = 0;
+ db_ktr_verbose |= (index(modif, 'v') != NULL) ? 2 : 0;
+ db_ktr_verbose |= (index(modif, 'V') != NULL) ? 1 : 0; /* just timestap please */
if (index(modif, 'a') != NULL) {
db_disable_pager();
while (cncheckc() != -1)
@@ -324,9 +333,11 @@ db_mach_vtrace(void)
db_printf(":cpu%d", kp->ktr_cpu);
#endif
db_printf(")");
- if (db_ktr_verbose) {
- db_printf(" %10.10lld %s.%d", (long long)kp->ktr_timestamp,
- kp->ktr_file, kp->ktr_line);
+ if (db_ktr_verbose >= 1) {
+ db_printf(" %10.10lld", (long long)kp->ktr_timestamp);
+ }
+ if (db_ktr_verbose >= 2) {
+ db_printf(" %s.%d", kp->ktr_file, kp->ktr_line);
}
db_printf(": ");
db_printf(kp->ktr_desc, kp->ktr_parms[0], kp->ktr_parms[1],
diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c
index 9c53bf6..0409344 100644
--- a/sys/kern/kern_module.c
+++ b/sys/kern/kern_module.c
@@ -446,7 +446,7 @@ modfind(struct thread *td, struct modfind_args *uap)
MODULE_VERSION(kernel, __FreeBSD_version);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/mount.h>
#include <sys/socket.h>
#include <compat/freebsd32/freebsd32_util.h>
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index c41909d..5601ecf 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
@@ -79,6 +80,11 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/uma.h>
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#endif
+
SDT_PROVIDER_DEFINE(proc);
SDT_PROBE_DEFINE(proc, kernel, ctor, entry);
SDT_PROBE_ARGTYPE(proc, kernel, ctor, entry, 0, "struct proc *");
@@ -145,6 +151,9 @@ int kstack_pages = KSTACK_PAGES;
SYSCTL_INT(_kern, OID_AUTO, kstack_pages, CTLFLAG_RD, &kstack_pages, 0, "");
CTASSERT(sizeof(struct kinfo_proc) == KINFO_PROC_SIZE);
+#ifdef COMPAT_FREEBSD32
+CTASSERT(sizeof(struct kinfo_proc32) == KINFO_PROC32_SIZE);
+#endif
/*
* Initialize global process hashing structures.
@@ -969,6 +978,128 @@ zpfind(pid_t pid)
#define KERN_PROC_ZOMBMASK 0x3
#define KERN_PROC_NOTHREADS 0x4
+#ifdef COMPAT_FREEBSD32
+
+/*
+ * This function is typically used to copy out the kernel address, so
+ * it can be replaced by assignment of zero.
+ */
+static inline uint32_t
+ptr32_trim(void *ptr)
+{
+ uintptr_t uptr;
+
+ uptr = (uintptr_t)ptr;
+ return ((uptr > UINT_MAX) ? 0 : uptr);
+}
+
+#define PTRTRIM_CP(src,dst,fld) \
+ do { (dst).fld = ptr32_trim((src).fld); } while (0)
+
+static void
+freebsd32_kinfo_proc_out(const struct kinfo_proc *ki, struct kinfo_proc32 *ki32)
+{
+ int i;
+
+ bzero(ki32, sizeof(struct kinfo_proc32));
+ ki32->ki_structsize = sizeof(struct kinfo_proc32);
+ CP(*ki, *ki32, ki_layout);
+ PTRTRIM_CP(*ki, *ki32, ki_args);
+ PTRTRIM_CP(*ki, *ki32, ki_paddr);
+ PTRTRIM_CP(*ki, *ki32, ki_addr);
+ PTRTRIM_CP(*ki, *ki32, ki_tracep);
+ PTRTRIM_CP(*ki, *ki32, ki_textvp);
+ PTRTRIM_CP(*ki, *ki32, ki_fd);
+ PTRTRIM_CP(*ki, *ki32, ki_vmspace);
+ PTRTRIM_CP(*ki, *ki32, ki_wchan);
+ CP(*ki, *ki32, ki_pid);
+ CP(*ki, *ki32, ki_ppid);
+ CP(*ki, *ki32, ki_pgid);
+ CP(*ki, *ki32, ki_tpgid);
+ CP(*ki, *ki32, ki_sid);
+ CP(*ki, *ki32, ki_tsid);
+ CP(*ki, *ki32, ki_jobc);
+ CP(*ki, *ki32, ki_tdev);
+ CP(*ki, *ki32, ki_siglist);
+ CP(*ki, *ki32, ki_sigmask);
+ CP(*ki, *ki32, ki_sigignore);
+ CP(*ki, *ki32, ki_sigcatch);
+ CP(*ki, *ki32, ki_uid);
+ CP(*ki, *ki32, ki_ruid);
+ CP(*ki, *ki32, ki_svuid);
+ CP(*ki, *ki32, ki_rgid);
+ CP(*ki, *ki32, ki_svgid);
+ CP(*ki, *ki32, ki_ngroups);
+ for (i = 0; i < KI_NGROUPS; i++)
+ CP(*ki, *ki32, ki_groups[i]);
+ CP(*ki, *ki32, ki_size);
+ CP(*ki, *ki32, ki_rssize);
+ CP(*ki, *ki32, ki_swrss);
+ CP(*ki, *ki32, ki_tsize);
+ CP(*ki, *ki32, ki_dsize);
+ CP(*ki, *ki32, ki_ssize);
+ CP(*ki, *ki32, ki_xstat);
+ CP(*ki, *ki32, ki_acflag);
+ CP(*ki, *ki32, ki_pctcpu);
+ CP(*ki, *ki32, ki_estcpu);
+ CP(*ki, *ki32, ki_slptime);
+ CP(*ki, *ki32, ki_swtime);
+ CP(*ki, *ki32, ki_runtime);
+ TV_CP(*ki, *ki32, ki_start);
+ TV_CP(*ki, *ki32, ki_childtime);
+ CP(*ki, *ki32, ki_flag);
+ CP(*ki, *ki32, ki_kiflag);
+ CP(*ki, *ki32, ki_traceflag);
+ CP(*ki, *ki32, ki_stat);
+ CP(*ki, *ki32, ki_nice);
+ CP(*ki, *ki32, ki_lock);
+ CP(*ki, *ki32, ki_rqindex);
+ CP(*ki, *ki32, ki_oncpu);
+ CP(*ki, *ki32, ki_lastcpu);
+ bcopy(ki->ki_ocomm, ki32->ki_ocomm, OCOMMLEN + 1);
+ bcopy(ki->ki_wmesg, ki32->ki_wmesg, WMESGLEN + 1);
+ bcopy(ki->ki_login, ki32->ki_login, LOGNAMELEN + 1);
+ bcopy(ki->ki_lockname, ki32->ki_lockname, LOCKNAMELEN + 1);
+ bcopy(ki->ki_comm, ki32->ki_comm, COMMLEN + 1);
+ bcopy(ki->ki_emul, ki32->ki_emul, KI_EMULNAMELEN + 1);
+ CP(*ki, *ki32, ki_cr_flags);
+ CP(*ki, *ki32, ki_jid);
+ CP(*ki, *ki32, ki_numthreads);
+ CP(*ki, *ki32, ki_tid);
+ CP(*ki, *ki32, ki_pri);
+ freebsd32_rusage_out(&ki->ki_rusage, &ki32->ki_rusage);
+ freebsd32_rusage_out(&ki->ki_rusage_ch, &ki32->ki_rusage_ch);
+ PTRTRIM_CP(*ki, *ki32, ki_pcb);
+ PTRTRIM_CP(*ki, *ki32, ki_kstack);
+ PTRTRIM_CP(*ki, *ki32, ki_udata);
+ CP(*ki, *ki32, ki_sflag);
+ CP(*ki, *ki32, ki_tdflags);
+}
+
+static int
+sysctl_out_proc_copyout(struct kinfo_proc *ki, struct sysctl_req *req)
+{
+ struct kinfo_proc32 ki32;
+ int error;
+
+ if (req->flags & SCTL_MASK32) {
+ freebsd32_kinfo_proc_out(ki, &ki32);
+ error = SYSCTL_OUT(req, (caddr_t)&ki32,
+ sizeof(struct kinfo_proc32));
+ } else
+ error = SYSCTL_OUT(req, (caddr_t)ki,
+ sizeof(struct kinfo_proc));
+ return (error);
+}
+#else
+static int
+sysctl_out_proc_copyout(struct kinfo_proc *ki, struct sysctl_req *req)
+{
+
+ return (SYSCTL_OUT(req, (caddr_t)ki, sizeof(struct kinfo_proc)));
+}
+#endif
+
/*
* Must be called with the process locked and will return with it unlocked.
*/
@@ -986,13 +1117,11 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int flags)
fill_kinfo_proc(p, &kinfo_proc);
if (flags & KERN_PROC_NOTHREADS)
- error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
- sizeof(kinfo_proc));
+ error = sysctl_out_proc_copyout(&kinfo_proc, req);
else {
FOREACH_THREAD_IN_PROC(p, td) {
fill_kinfo_thread(td, &kinfo_proc, 1);
- error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
- sizeof(kinfo_proc));
+ error = sysctl_out_proc_copyout(&kinfo_proc, req);
if (error)
break;
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 81a03ef..f867839 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -471,14 +471,20 @@ rtp_to_pri(struct rtprio *rtp, struct thread *td)
u_char newpri;
u_char oldpri;
- if (rtp->prio > RTP_PRIO_MAX)
- return (EINVAL);
thread_lock(td);
switch (RTP_PRIO_BASE(rtp->type)) {
case RTP_PRIO_REALTIME:
+ if (rtp->prio > RTP_PRIO_MAX) {
+ thread_unlock(td);
+ return (EINVAL);
+ }
newpri = PRI_MIN_REALTIME + rtp->prio;
break;
case RTP_PRIO_NORMAL:
+ if (rtp->prio > (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) {
+ thread_unlock(td);
+ return (EINVAL);
+ }
newpri = PRI_MIN_TIMESHARE + rtp->prio;
break;
case RTP_PRIO_IDLE:
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index c1f13e0..81b4c5f 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -199,8 +199,8 @@ void
rw_destroy(struct rwlock *rw)
{
- KASSERT(rw->rw_lock == RW_UNLOCKED, ("rw lock not unlocked"));
- KASSERT(rw->rw_recurse == 0, ("rw lock still recursed"));
+ KASSERT(rw->rw_lock == RW_UNLOCKED, ("rw lock %p not unlocked", rw));
+ KASSERT(rw->rw_recurse == 0, ("rw lock %p still recursed", rw));
rw->rw_lock = RW_DESTROYED;
lock_destroy(&rw->lock_object);
}
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 9b28af4..bd3c7aa 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -62,7 +62,7 @@ __FBSDID("$FreeBSD$");
#include <sys/reboot.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
-#include <sys/smp.h> /* smp_active */
+#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/sysproto.h>
@@ -485,15 +485,26 @@ static void
shutdown_reset(void *junk, int howto)
{
+ printf("Rebooting...\n");
+ DELAY(1000000); /* wait 1 sec for printf's to complete and be read */
+
/*
- * Disable interrupts on CPU0 in order to avoid fast handlers
- * to preempt the stopping process and to deadlock against other
- * CPUs.
+ * Acquiring smp_ipi_mtx here has a double effect:
+ * - it disables interrupts avoiding CPU0 preemption
+ * by fast handlers (thus deadlocking against other CPUs)
+ * - it avoids deadlocks against smp_rendezvous() or, more
+ * generally, threads busy-waiting, with this spinlock held,
+ * and waiting for responses by threads on other CPUs
+ * (ie. smp_tlb_shootdown()).
+ *
+ * For the !SMP case it just needs to handle the former problem.
*/
+#ifdef SMP
+ mtx_lock_spin(&smp_ipi_mtx);
+#else
spinlock_enter();
+#endif
- printf("Rebooting...\n");
- DELAY(1000000); /* wait 1 sec for printf's to complete and be read */
/* cpu_boot(howto); */ /* doesn't do anything at the moment */
cpu_reset();
/* NOTREACHED */ /* assuming reset worked */
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 98a121b..706433d 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2809,6 +2809,7 @@ killproc(p, why)
p, p->p_pid, p->p_comm);
log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm,
p->p_ucred ? p->p_ucred->cr_uid : -1, why);
+ p->p_flag |= P_WKILLED;
psignal(p, SIGKILL);
}
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
index 077aedc..9cb7b68 100644
--- a/sys/kern/kern_syscalls.c
+++ b/sys/kern/kern_syscalls.c
@@ -135,3 +135,33 @@ syscall_module_handler(struct module *mod, int what, void *arg)
else
return (0);
}
+
+int
+syscall_helper_register(struct syscall_helper_data *sd)
+{
+ struct syscall_helper_data *sd1;
+ int error;
+
+ for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
+ error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
+ &sd1->old_sysent);
+ if (error != 0) {
+ syscall_helper_unregister(sd);
+ return (error);
+ }
+ sd1->registered = 1;
+ }
+ return (0);
+}
+
+int
+syscall_helper_unregister(struct syscall_helper_data *sd)
+{
+ struct syscall_helper_data *sd1;
+
+ for (sd1 = sd; sd1->registered != 0; sd1++) {
+ syscall_deregister(&sd1->syscall_no, &sd1->old_sysent);
+ sd1->registered = 0;
+ }
+ return (0);
+}
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 116e79b..0b90dfc 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <security/audit/audit.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
static inline int
suword_lwpid(void *addr, lwpid_t lwpid)
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 14a79a3..137ffe5 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32_proto.h>
#endif
@@ -818,7 +818,7 @@ do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id)
return (0);
}
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
/*
* Lock a umtx object.
@@ -3269,7 +3269,7 @@ _umtx_op(struct thread *td, struct _umtx_op_args *uap)
return (EINVAL);
}
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
int
freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *uap)
/* struct umtx *umtx */
diff --git a/sys/kern/ksched.c b/sys/kern/ksched.c
index 192034f..2d11363 100644
--- a/sys/kern/ksched.c
+++ b/sys/kern/ksched.c
@@ -81,9 +81,8 @@ ksched_detach(struct ksched *ks)
* higher priority. It also permits sched_setparam to be
* implementation defined for SCHED_OTHER. I don't like
* the notion of inverted priorites for normal processes when
- * you can use "setpriority" for that.
+ * you can use "setpriority" for that.
*
- * I'm rejecting sched_setparam for SCHED_OTHER with EINVAL.
*/
/* Macros to convert between the unix (lower numerically is higher priority)
@@ -93,6 +92,9 @@ ksched_detach(struct ksched *ks)
#define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P))
#define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P))
+#define p4prio_to_tsprio(P) ((PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE) - (P))
+#define tsprio_to_p4prio(P) ((PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE) - (P))
+
/* These improve readability a bit for me:
*/
#define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX)
@@ -134,9 +136,6 @@ ksched_setparam(struct ksched *ksched,
if (e == 0)
{
- if (policy == SCHED_OTHER)
- e = EINVAL;
- else
e = ksched_setscheduler(ksched, td, policy, param);
}
@@ -152,7 +151,16 @@ ksched_getparam(struct ksched *ksched,
pri_to_rtp(td, &rtp);
if (RTP_PRIO_IS_REALTIME(rtp.type))
param->sched_priority = rtpprio_to_p4prio(rtp.prio);
-
+ else {
+ if (PRI_MIN_TIMESHARE < rtp.prio)
+ /*
+ * The interactive score has it to min realtime
+ * so we must show max (64 most likely
+ */
+ param->sched_priority = (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE);
+ else
+ param->sched_priority = tsprio_to_p4prio(rtp.prio);
+ }
return 0;
}
@@ -191,11 +199,14 @@ ksched_setscheduler(struct ksched *ksched,
break;
case SCHED_OTHER:
- {
+ if (param->sched_priority >= 0 &&
+ param->sched_priority <= (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) {
rtp.type = RTP_PRIO_NORMAL;
rtp.prio = p4prio_to_rtpprio(param->sched_priority);
rtp_to_pri(&rtp, td);
- }
+ } else
+ e = EINVAL;
+
break;
default:
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 6e939c0..9d3292a 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -545,15 +545,16 @@ devctl_queue_data(char *data)
struct proc *p;
if (strlen(data) == 0)
- return;
+ goto out;
if (devctl_queue_length == 0)
- return;
+ goto out;
n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
if (n1 == NULL)
- return;
+ goto out;
n1->dei_data = data;
mtx_lock(&devsoftc.mtx);
if (devctl_queue_length == 0) {
+ mtx_unlock(&devsoftc.mtx);
free(n1->dei_data, M_BUS);
free(n1, M_BUS);
return;
@@ -577,6 +578,14 @@ devctl_queue_data(char *data)
psignal(p, SIGIO);
PROC_UNLOCK(p);
}
+ return;
+out:
+ /*
+ * We have to free data on all error paths since the caller
+ * assumes it will be free'd when this item is dequeued.
+ */
+ free(data, M_BUS);
+ return;
}
/**
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c
index 37c482c..5894099 100644
--- a/sys/kern/subr_eventhandler.c
+++ b/sys/kern/subr_eventhandler.c
@@ -68,15 +68,15 @@ SYSINIT(eventhandlers, SI_SUB_EVENTHANDLER, SI_ORDER_FIRST, eventhandler_init,
* Insertion is O(n) due to the priority scan, but optimises to O(1)
* if all priorities are identical.
*/
-eventhandler_tag
-eventhandler_register(struct eventhandler_list *list, const char *name,
- void *func, void *arg, int priority)
+static eventhandler_tag
+eventhandler_register_internal(struct eventhandler_list *list,
+ const char *name, eventhandler_tag epn)
{
struct eventhandler_list *new_list;
- struct eventhandler_entry_generic *eg;
struct eventhandler_entry *ep;
KASSERT(eventhandler_lists_initted, ("eventhandler registered too early"));
+ KASSERT(epn != NULL, ("%s: cannot register NULL event", __func__));
/* lock the eventhandler lists */
mtx_lock(&eventhandler_mutex);
@@ -117,31 +117,68 @@ eventhandler_register(struct eventhandler_list *list, const char *name,
}
mtx_unlock(&eventhandler_mutex);
- /* allocate an entry for this handler, populate it */
- eg = malloc(sizeof(struct eventhandler_entry_generic), M_EVENTHANDLER,
- M_WAITOK | M_ZERO);
- eg->func = func;
- eg->ee.ee_arg = arg;
- eg->ee.ee_priority = priority;
- KASSERT(priority != EHE_DEAD_PRIORITY,
+ KASSERT(epn->ee_priority != EHE_DEAD_PRIORITY,
("%s: handler for %s registered with dead priority", __func__, name));
/* sort it into the list */
- CTR4(KTR_EVH, "%s: adding item %p (function %p) to \"%s\"", __func__, eg,
- func, name);
+ CTR4(KTR_EVH, "%s: adding item %p (function %p) to \"%s\"", __func__, epn,
+ ((struct eventhandler_entry_generic *)epn)->func, name);
EHL_LOCK(list);
TAILQ_FOREACH(ep, &list->el_entries, ee_link) {
if (ep->ee_priority != EHE_DEAD_PRIORITY &&
- eg->ee.ee_priority < ep->ee_priority) {
- TAILQ_INSERT_BEFORE(ep, &eg->ee, ee_link);
+ epn->ee_priority < ep->ee_priority) {
+ TAILQ_INSERT_BEFORE(ep, epn, ee_link);
break;
}
}
if (ep == NULL)
- TAILQ_INSERT_TAIL(&list->el_entries, &eg->ee, ee_link);
+ TAILQ_INSERT_TAIL(&list->el_entries, epn, ee_link);
EHL_UNLOCK(list);
- return(&eg->ee);
+ return(epn);
+}
+
+eventhandler_tag
+eventhandler_register(struct eventhandler_list *list, const char *name,
+ void *func, void *arg, int priority)
+{
+ struct eventhandler_entry_generic *eg;
+
+ /* allocate an entry for this handler, populate it */
+ eg = malloc(sizeof(struct eventhandler_entry_generic), M_EVENTHANDLER,
+ M_WAITOK | M_ZERO);
+ eg->func = func;
+ eg->ee.ee_arg = arg;
+ eg->ee.ee_priority = priority;
+
+ return (eventhandler_register_internal(list, name, &eg->ee));
+}
+
+#ifdef VIMAGE
+struct eventhandler_entry_generic_vimage
+{
+ struct eventhandler_entry ee;
+ vimage_iterator_func_t func; /* Vimage iterator function. */
+ struct eventhandler_entry_vimage v_ee; /* Original func, arg. */
+};
+
+eventhandler_tag
+vimage_eventhandler_register(struct eventhandler_list *list, const char *name,
+ void *func, void *arg, int priority, vimage_iterator_func_t iterfunc)
+{
+ struct eventhandler_entry_generic_vimage *eg;
+
+ /* allocate an entry for this handler, populate it */
+ eg = malloc(sizeof(struct eventhandler_entry_generic_vimage),
+ M_EVENTHANDLER, M_WAITOK | M_ZERO);
+ eg->func = iterfunc;
+ eg->v_ee.func = func;
+ eg->v_ee.ee_arg = arg;
+ eg->ee.ee_arg = &eg->v_ee;
+ eg->ee.ee_priority = priority;
+
+ return (eventhandler_register_internal(list, name, &eg->ee));
}
+#endif
void
eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
diff --git a/sys/kern/subr_firmware.c b/sys/kern/subr_firmware.c
index 3f5e52b..209f3a7 100644
--- a/sys/kern/subr_firmware.c
+++ b/sys/kern/subr_firmware.c
@@ -121,7 +121,7 @@ struct priv_fw {
* reallocate the array because pointers are held externally.
* A list may work, though.
*/
-#define FIRMWARE_MAX 30
+#define FIRMWARE_MAX 50
static struct priv_fw firmware_table[FIRMWARE_MAX];
/*
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
index a4d4ff8..f8d60dd 100644
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -124,7 +124,7 @@ SYSCTL_ULONG(_kern, OID_AUTO, sgrowsiz, CTLFLAG_RDTUN, &sgrowsiz, 0,
"Amount to grow stack on a stack fault");
SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
NULL, 0, sysctl_kern_vm_guest, "A",
- "Virtual machine detected? (none|generic|xen)");
+ "Virtual machine guest detected? (none|generic|xen)");
/*
* These have to be allocated somewhere; allocating
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index b34af61..eaefd9c 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -878,9 +878,10 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
sbp = selbits;
#define getbits(name, x) \
do { \
- if (name == NULL) \
+ if (name == NULL) { \
ibits[x] = NULL; \
- else { \
+ obits[x] = NULL; \
+ } else { \
ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \
obits[x] = sbp; \
sbp += ncpbytes / sizeof *sbp; \
@@ -895,6 +896,28 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
getbits(fd_ou, 1);
getbits(fd_ex, 2);
#undef getbits
+
+#if BYTE_ORDER == BIG_ENDIAN && defined(__LP64__)
+ /*
+ * XXX: swizzle_fdset assumes that if abi_nfdbits != NFDBITS,
+ * we are running under 32-bit emulation. This should be more
+ * generic.
+ */
+#define swizzle_fdset(bits) \
+ if (abi_nfdbits != NFDBITS && bits != NULL) { \
+ int i; \
+ for (i = 0; i < ncpbytes / sizeof *sbp; i++) \
+ bits[i] = (bits[i] >> 32) | (bits[i] << 32); \
+ }
+#else
+#define swizzle_fdset(bits)
+#endif
+
+ /* Make sure the bit order makes it through an ABI transition */
+ swizzle_fdset(ibits[0]);
+ swizzle_fdset(ibits[1]);
+ swizzle_fdset(ibits[2]);
+
if (nbufbytes != 0)
bzero(selbits, nbufbytes / 2);
@@ -941,6 +964,13 @@ done:
error = EINTR;
if (error == EWOULDBLOCK)
error = 0;
+
+ /* swizzle bit order back, if necessary */
+ swizzle_fdset(obits[0]);
+ swizzle_fdset(obits[1]);
+ swizzle_fdset(obits[2]);
+#undef swizzle_fdset
+
#define putbits(name, x) \
if (name && (error2 = copyout(obits[x], name, ncpubytes))) \
error = error2;
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index fcfb226..e098648 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -1428,9 +1428,9 @@ pipe_stat(fp, ub, active_cred, td)
else
ub->st_size = pipe->pipe_buffer.cnt;
ub->st_blocks = (ub->st_size + ub->st_blksize - 1) / ub->st_blksize;
- ub->st_atimespec = pipe->pipe_atime;
- ub->st_mtimespec = pipe->pipe_mtime;
- ub->st_ctimespec = pipe->pipe_ctime;
+ ub->st_atim = pipe->pipe_atime;
+ ub->st_mtim = pipe->pipe_mtime;
+ ub->st_ctim = pipe->pipe_ctime;
ub->st_uid = fp->f_cred->cr_uid;
ub->st_gid = fp->f_cred->cr_gid;
/*
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index d4b5d4d..f5671d9 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -62,10 +62,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_pager.h>
#include <vm/vm_param.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/procfs.h>
-#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
struct ptrace_io_desc32 {
int piod_op;
@@ -172,7 +170,7 @@ proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
PROC_ACTION(set_fpregs(td, fpregs));
}
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
/* For 32 bit binaries, we need to expose the 32 bit regs layouts. */
int
proc_read_regs32(struct thread *td, struct reg32 *regs32)
@@ -473,7 +471,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
return (error);
}
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
static int
ptrace_vm_entry32(struct thread *td, struct proc *p,
struct ptrace_vm_entry32 *pve32)
@@ -500,7 +498,7 @@ ptrace_vm_entry32(struct thread *td, struct proc *p,
pve32->pve_pathlen = pve.pve_pathlen;
return (error);
}
-#endif /* COMPAT_IA32 */
+#endif /* COMPAT_FREEBSD32 */
/*
* Process debugging system call.
@@ -514,7 +512,7 @@ struct ptrace_args {
};
#endif
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
/*
* This CPP subterfuge is to try and reduce the number of ifdefs in
* the body of the code.
@@ -549,7 +547,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
struct dbreg dbreg;
struct fpreg fpreg;
struct reg reg;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct dbreg32 dbreg32;
struct fpreg32 fpreg32;
struct reg32 reg32;
@@ -559,7 +557,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
} r;
void *addr;
int error = 0;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
int wrap32 = 0;
if (SV_CURPROC_FLAG(SV_ILP32))
@@ -627,7 +625,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
#undef COPYIN
#undef COPYOUT
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
/*
* PROC_READ(regs, td2, addr);
* becomes either:
@@ -661,7 +659,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
int error, write, tmp, num;
int proctree_locked = 0;
lwpid_t tid = 0, *buf;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
int wrap32 = 0, safe = 0;
struct ptrace_io_desc32 *piod32 = NULL;
#endif
@@ -749,7 +747,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
tid = td2->td_tid;
}
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
/*
* Test if we're a 32 bit client and what the target is.
* Set the wrap controls accordingly.
@@ -1017,7 +1015,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_IO:
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (wrap32) {
piod32 = addr;
iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;
@@ -1037,7 +1035,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_td = td;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
tmp = wrap32 ? piod32->piod_op : piod->piod_op;
#else
tmp = piod->piod_op;
@@ -1058,7 +1056,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
}
PROC_UNLOCK(p);
error = proc_rwmem(p, &uio);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (wrap32)
piod32->piod_len -= uio.uio_resid;
else
@@ -1147,7 +1145,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
case PT_VM_ENTRY:
PROC_UNLOCK(p);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (wrap32)
error = ptrace_vm_entry32(td, p, addr);
else
diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
index d33fdb0..e402cb5 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -178,3 +178,69 @@ ipcperm_new2old(struct ipc_perm *new, struct ipc_perm_old *old)
old->key = new->key;
}
#endif
+
+#ifdef COMPAT_FREEBSD32
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_ipc.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+void
+freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip)
+{
+
+ CP(*ip32, *ip, cuid);
+ CP(*ip32, *ip, cgid);
+ CP(*ip32, *ip, uid);
+ CP(*ip32, *ip, gid);
+ CP(*ip32, *ip, mode);
+ CP(*ip32, *ip, seq);
+ CP(*ip32, *ip, key);
+}
+
+void
+freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32)
+{
+
+ CP(*ip, *ip32, cuid);
+ CP(*ip, *ip32, cgid);
+ CP(*ip, *ip32, uid);
+ CP(*ip, *ip32, gid);
+ CP(*ip, *ip32, mode);
+ CP(*ip, *ip32, seq);
+ CP(*ip, *ip32, key);
+}
+#endif
+
+void
+freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
+{
+
+ CP(*ip32, *ip, cuid);
+ CP(*ip32, *ip, cgid);
+ CP(*ip32, *ip, uid);
+ CP(*ip32, *ip, gid);
+ CP(*ip32, *ip, mode);
+ CP(*ip32, *ip, seq);
+ CP(*ip32, *ip, key);
+}
+
+void
+freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
+{
+
+ CP(*ip, *ip32, cuid);
+ CP(*ip, *ip32, cgid);
+ CP(*ip, *ip32, uid);
+ CP(*ip, *ip32, gid);
+ CP(*ip, *ip32, mode);
+ CP(*ip, *ip32, seq);
+ CP(*ip, *ip32, key);
+}
+#endif
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index c7c67d4..01d7f79 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -74,7 +74,7 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
-static void msginit(void);
+static int msginit(void);
static int msgunload(void);
static int sysvmsg_modload(struct module *, int, void *);
@@ -152,10 +152,45 @@ static struct msg *msghdrs; /* MSGTQL msg headers */
static struct msqid_kernel *msqids; /* MSGMNI msqid_kernel struct's */
static struct mtx msq_mtx; /* global mutex for message queues. */
-static void
+static struct syscall_helper_data msg_syscalls[] = {
+ SYSCALL_INIT_HELPER(msgctl),
+ SYSCALL_INIT_HELPER(msgget),
+ SYSCALL_INIT_HELPER(msgsnd),
+ SYSCALL_INIT_HELPER(msgrcv),
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ SYSCALL_INIT_HELPER(msgsys),
+ SYSCALL_INIT_HELPER(freebsd7_msgctl),
+#endif
+ SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_ipc.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+static struct syscall_helper_data msg32_syscalls[] = {
+ SYSCALL32_INIT_HELPER(freebsd32_msgctl),
+ SYSCALL32_INIT_HELPER(freebsd32_msgsnd),
+ SYSCALL32_INIT_HELPER(freebsd32_msgrcv),
+ SYSCALL32_INIT_HELPER(msgget),
+ SYSCALL32_INIT_HELPER(freebsd32_msgsys),
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ SYSCALL32_INIT_HELPER(freebsd7_freebsd32_msgctl),
+#endif
+ SYSCALL_INIT_LAST
+};
+#endif
+
+static int
msginit()
{
- register int i;
+ int i, error;
TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);
TUNABLE_INT_FETCH("kern.ipc.msgssz", &msginfo.msgssz);
@@ -235,6 +270,16 @@ msginit()
#endif
}
mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
+
+ error = syscall_helper_register(msg_syscalls);
+ if (error != 0)
+ return (error);
+#ifdef COMPAT_FREEBSD32
+ error = syscall32_helper_register(msg32_syscalls);
+ if (error != 0)
+ return (error);
+#endif
+ return (0);
}
static int
@@ -246,6 +291,11 @@ msgunload()
int i;
#endif
+ syscall_helper_unregister(msg_syscalls);
+#ifdef COMPAT_FREEBSD32
+ syscall32_helper_unregister(msg32_syscalls);
+#endif
+
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
/*
* Look for an unallocated and unlocked msqid_ds.
@@ -283,7 +333,9 @@ sysvmsg_modload(struct module *module, int cmd, void *arg)
switch (cmd) {
case MOD_LOAD:
- msginit();
+ error = msginit();
+ if (error != 0)
+ msgunload();
break;
case MOD_UNLOAD:
error = msgunload();
@@ -303,11 +355,6 @@ static moduledata_t sysvmsg_mod = {
NULL
};
-SYSCALL_MODULE_HELPER(msgctl);
-SYSCALL_MODULE_HELPER(msgget);
-SYSCALL_MODULE_HELPER(msgsnd);
-SYSCALL_MODULE_HELPER(msgrcv);
-
DECLARE_MODULE(sysvmsg, sysvmsg_mod, SI_SUB_SYSV_MSG, SI_ORDER_FIRST);
MODULE_VERSION(sysvmsg, 1);
@@ -1257,10 +1304,159 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0,
SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
NULL, 0, sysctl_msqids, "", "Message queue IDs");
+#ifdef COMPAT_FREEBSD32
+int
+freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
+{
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ switch (uap->which) {
+ case 0:
+ return (freebsd7_freebsd32_msgctl(td,
+ (struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
+ case 2:
+ return (freebsd32_msgsnd(td,
+ (struct freebsd32_msgsnd_args *)&uap->a2));
+ case 3:
+ return (freebsd32_msgrcv(td,
+ (struct freebsd32_msgrcv_args *)&uap->a2));
+ default:
+ return (msgsys(td, (struct msgsys_args *)uap));
+ }
+#else
+ return (nosys(td, NULL));
+#endif
+}
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+int
+freebsd7_freebsd32_msgctl(struct thread *td,
+ struct freebsd7_freebsd32_msgctl_args *uap)
+{
+ struct msqid_ds msqbuf;
+ struct msqid_ds32_old msqbuf32;
+ int error;
+
+ if (uap->cmd == IPC_SET) {
+ error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
+ if (error)
+ return (error);
+ freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
+ PTRIN_CP(msqbuf32, msqbuf, msg_first);
+ PTRIN_CP(msqbuf32, msqbuf, msg_last);
+ CP(msqbuf32, msqbuf, msg_cbytes);
+ CP(msqbuf32, msqbuf, msg_qnum);
+ CP(msqbuf32, msqbuf, msg_qbytes);
+ CP(msqbuf32, msqbuf, msg_lspid);
+ CP(msqbuf32, msqbuf, msg_lrpid);
+ CP(msqbuf32, msqbuf, msg_stime);
+ CP(msqbuf32, msqbuf, msg_rtime);
+ CP(msqbuf32, msqbuf, msg_ctime);
+ }
+ error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
+ if (error)
+ return (error);
+ if (uap->cmd == IPC_STAT) {
+ bzero(&msqbuf32, sizeof(msqbuf32));
+ freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
+ PTROUT_CP(msqbuf, msqbuf32, msg_first);
+ PTROUT_CP(msqbuf, msqbuf32, msg_last);
+ CP(msqbuf, msqbuf32, msg_cbytes);
+ CP(msqbuf, msqbuf32, msg_qnum);
+ CP(msqbuf, msqbuf32, msg_qbytes);
+ CP(msqbuf, msqbuf32, msg_lspid);
+ CP(msqbuf, msqbuf32, msg_lrpid);
+ CP(msqbuf, msqbuf32, msg_stime);
+ CP(msqbuf, msqbuf32, msg_rtime);
+ CP(msqbuf, msqbuf32, msg_ctime);
+ error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
+ }
+ return (error);
+}
+#endif
+
+int
+freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
+{
+ struct msqid_ds msqbuf;
+ struct msqid_ds32 msqbuf32;
+ int error;
+
+ if (uap->cmd == IPC_SET) {
+ error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
+ if (error)
+ return (error);
+ freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
+ PTRIN_CP(msqbuf32, msqbuf, msg_first);
+ PTRIN_CP(msqbuf32, msqbuf, msg_last);
+ CP(msqbuf32, msqbuf, msg_cbytes);
+ CP(msqbuf32, msqbuf, msg_qnum);
+ CP(msqbuf32, msqbuf, msg_qbytes);
+ CP(msqbuf32, msqbuf, msg_lspid);
+ CP(msqbuf32, msqbuf, msg_lrpid);
+ CP(msqbuf32, msqbuf, msg_stime);
+ CP(msqbuf32, msqbuf, msg_rtime);
+ CP(msqbuf32, msqbuf, msg_ctime);
+ }
+ error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
+ if (error)
+ return (error);
+ if (uap->cmd == IPC_STAT) {
+ freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
+ PTROUT_CP(msqbuf, msqbuf32, msg_first);
+ PTROUT_CP(msqbuf, msqbuf32, msg_last);
+ CP(msqbuf, msqbuf32, msg_cbytes);
+ CP(msqbuf, msqbuf32, msg_qnum);
+ CP(msqbuf, msqbuf32, msg_qbytes);
+ CP(msqbuf, msqbuf32, msg_lspid);
+ CP(msqbuf, msqbuf32, msg_lrpid);
+ CP(msqbuf, msqbuf32, msg_stime);
+ CP(msqbuf, msqbuf32, msg_rtime);
+ CP(msqbuf, msqbuf32, msg_ctime);
+ error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
+ }
+ return (error);
+}
+
+int
+freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
+{
+ const void *msgp;
+ long mtype;
+ int32_t mtype32;
+ int error;
+
+ msgp = PTRIN(uap->msgp);
+ if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
+ return (error);
+ mtype = mtype32;
+ return (kern_msgsnd(td, uap->msqid,
+ (const char *)msgp + sizeof(mtype32),
+ uap->msgsz, uap->msgflg, mtype));
+}
+
+int
+freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
+{
+ void *msgp;
+ long mtype;
+ int32_t mtype32;
+ int error;
+
+ msgp = PTRIN(uap->msgp);
+ if ((error = kern_msgrcv(td, uap->msqid,
+ (char *)msgp + sizeof(mtype32), uap->msgsz,
+ uap->msgtyp, uap->msgflg, &mtype)) != 0)
+ return (error);
+ mtype32 = (int32_t)mtype;
+ return (copyout(&mtype32, msgp, sizeof(mtype32)));
+}
+#endif
+
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
-SYSCALL_MODULE_HELPER(msgsys);
-SYSCALL_MODULE_HELPER(freebsd7_msgctl);
/* XXX casting to (sy_call_t *) is bogus, as usual. */
static sy_call_t *msgcalls[] = {
@@ -1295,7 +1491,9 @@ msgsys(td, uap)
return (error);
}
+#ifndef CP
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
+#endif
#ifndef _SYS_SYSPROTO_H_
struct freebsd7_msgctl_args {
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index 2f2b528..f6d781c7 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -70,7 +70,7 @@ static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
#define DPRINTF(a)
#endif
-static void seminit(void);
+static int seminit(void);
static int sysvsem_modload(struct module *, int, void *);
static int semunload(void);
static void semexit_myhook(void *arg, struct proc *p);
@@ -214,10 +214,43 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0,
SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD,
NULL, 0, sysctl_sema, "", "");
-static void
+static struct syscall_helper_data sem_syscalls[] = {
+ SYSCALL_INIT_HELPER(__semctl),
+ SYSCALL_INIT_HELPER(semget),
+ SYSCALL_INIT_HELPER(semop),
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ SYSCALL_INIT_HELPER(semsys),
+ SYSCALL_INIT_HELPER(freebsd7___semctl),
+#endif
+ SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_ipc.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+static struct syscall_helper_data sem32_syscalls[] = {
+ SYSCALL32_INIT_HELPER(freebsd32_semctl),
+ SYSCALL32_INIT_HELPER(semget),
+ SYSCALL32_INIT_HELPER(semop),
+ SYSCALL32_INIT_HELPER(freebsd32_semsys),
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ SYSCALL32_INIT_HELPER(freebsd7_freebsd32_semctl),
+#endif
+ SYSCALL_INIT_LAST
+};
+#endif
+
+static int
seminit(void)
{
- int i;
+ int i, error;
TUNABLE_INT_FETCH("kern.ipc.semmap", &seminfo.semmap);
TUNABLE_INT_FETCH("kern.ipc.semmni", &seminfo.semmni);
@@ -258,6 +291,16 @@ seminit(void)
mtx_init(&sem_undo_mtx, "semu", NULL, MTX_DEF);
semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
EVENTHANDLER_PRI_ANY);
+
+ error = syscall_helper_register(sem_syscalls);
+ if (error != 0)
+ return (error);
+#ifdef COMPAT_FREEBSD32
+ error = syscall32_helper_register(sem32_syscalls);
+ if (error != 0)
+ return (error);
+#endif
+ return (0);
}
static int
@@ -269,6 +312,10 @@ semunload(void)
if (semtot != 0)
return (EBUSY);
+#ifdef COMPAT_FREEBSD32
+ syscall32_helper_unregister(sem32_syscalls);
+#endif
+ syscall_helper_unregister(sem_syscalls);
EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
#ifdef MAC
for (i = 0; i < seminfo.semmni; i++)
@@ -292,7 +339,9 @@ sysvsem_modload(struct module *module, int cmd, void *arg)
switch (cmd) {
case MOD_LOAD:
- seminit();
+ error = seminit();
+ if (error != 0)
+ semunload();
break;
case MOD_UNLOAD:
error = semunload();
@@ -312,10 +361,6 @@ static moduledata_t sysvsem_mod = {
NULL
};
-SYSCALL_MODULE_HELPER(__semctl);
-SYSCALL_MODULE_HELPER(semget);
-SYSCALL_MODULE_HELPER(semop);
-
DECLARE_MODULE(sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST);
MODULE_VERSION(sysvsem, 1);
@@ -1316,8 +1361,6 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
-SYSCALL_MODULE_HELPER(semsys);
-SYSCALL_MODULE_HELPER(freebsd7___semctl);
/* XXX casting to (sy_call_t *) is bogus, as usual. */
static sy_call_t *semcalls[] = {
@@ -1351,7 +1394,9 @@ semsys(td, uap)
return (error);
}
+#ifndef CP
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
+#endif
#ifndef _SYS_SYSPROTO_H_
struct freebsd7___semctl_args {
@@ -1432,7 +1477,172 @@ freebsd7___semctl(struct thread *td, struct freebsd7___semctl_args *uap)
return (error);
}
-#undef CP
+#endif /* COMPAT_FREEBSD{4,5,6,7} */
+
+#ifdef COMPAT_FREEBSD32
+
+int
+freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
+{
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ switch (uap->which) {
+ case 0:
+ return (freebsd7_freebsd32_semctl(td,
+ (struct freebsd7_freebsd32_semctl_args *)&uap->a2));
+ default:
+ return (semsys(td, (struct semsys_args *)uap));
+ }
+#else
+ return (nosys(td, NULL));
+#endif
+}
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+int
+freebsd7_freebsd32_semctl(struct thread *td,
+ struct freebsd7_freebsd32_semctl_args *uap)
+{
+ struct semid_ds32_old dsbuf32;
+ struct semid_ds dsbuf;
+ union semun semun;
+ union semun32 arg;
+ register_t rval;
+ int error;
+
+ switch (uap->cmd) {
+ case SEM_STAT:
+ case IPC_SET:
+ case IPC_STAT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
+ error = copyin(uap->arg, &arg, sizeof(arg));
+ if (error)
+ return (error);
+ break;
+ }
+
+ switch (uap->cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ semun.buf = &dsbuf;
+ break;
+ case IPC_SET:
+ error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
+ if (error)
+ return (error);
+ freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
+ PTRIN_CP(dsbuf32, dsbuf, sem_base);
+ CP(dsbuf32, dsbuf, sem_nsems);
+ CP(dsbuf32, dsbuf, sem_otime);
+ CP(dsbuf32, dsbuf, sem_ctime);
+ semun.buf = &dsbuf;
+ break;
+ case GETALL:
+ case SETALL:
+ semun.array = PTRIN(arg.array);
+ break;
+ case SETVAL:
+ semun.val = arg.val;
+ break;
+ }
+
+ error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
+ &rval);
+ if (error)
+ return (error);
+
+ switch (uap->cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ bzero(&dsbuf32, sizeof(dsbuf32));
+ freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
+ PTROUT_CP(dsbuf, dsbuf32, sem_base);
+ CP(dsbuf, dsbuf32, sem_nsems);
+ CP(dsbuf, dsbuf32, sem_otime);
+ CP(dsbuf, dsbuf32, sem_ctime);
+ error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
+ break;
+ }
+
+ if (error == 0)
+ td->td_retval[0] = rval;
+ return (error);
+}
+#endif
+
+int
+freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
+{
+ struct semid_ds32 dsbuf32;
+ struct semid_ds dsbuf;
+ union semun semun;
+ union semun32 arg;
+ register_t rval;
+ int error;
+
+ switch (uap->cmd) {
+ case SEM_STAT:
+ case IPC_SET:
+ case IPC_STAT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
+ error = copyin(uap->arg, &arg, sizeof(arg));
+ if (error)
+ return (error);
+ break;
+ }
+
+ switch (uap->cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ semun.buf = &dsbuf;
+ break;
+ case IPC_SET:
+ error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
+ if (error)
+ return (error);
+ freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
+ PTRIN_CP(dsbuf32, dsbuf, sem_base);
+ CP(dsbuf32, dsbuf, sem_nsems);
+ CP(dsbuf32, dsbuf, sem_otime);
+ CP(dsbuf32, dsbuf, sem_ctime);
+ semun.buf = &dsbuf;
+ break;
+ case GETALL:
+ case SETALL:
+ semun.array = PTRIN(arg.array);
+ break;
+ case SETVAL:
+ semun.val = arg.val;
+ break;
+ }
+
+ error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
+ &rval);
+ if (error)
+ return (error);
+
+ switch (uap->cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ bzero(&dsbuf32, sizeof(dsbuf32));
+ freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
+ PTROUT_CP(dsbuf, dsbuf32, sem_base);
+ CP(dsbuf, dsbuf32, sem_nsems);
+ CP(dsbuf, dsbuf32, sem_otime);
+ CP(dsbuf, dsbuf32, sem_ctime);
+ error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
+ break;
+ }
+
+ if (error == 0)
+ td->td_retval[0] = rval;
+ return (error);
+}
-#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
- COMPAT_FREEBSD7 */
+#endif /* COMPAT_FREEBSD32 */
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index a16c8af..ddf4ce1 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -122,7 +122,7 @@ static struct shmid_kernel *shm_find_segment_by_shmid(int);
static struct shmid_kernel *shm_find_segment_by_shmidx(int);
static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
static void shmrealloc(void);
-static void shminit(void);
+static int shminit(void);
static int sysvshm_modload(struct module *, int, void *);
static int shmunload(void);
static void shmexit_myhook(struct vmspace *vm);
@@ -816,10 +816,47 @@ shmrealloc(void)
shmalloced = shminfo.shmmni;
}
-static void
+static struct syscall_helper_data shm_syscalls[] = {
+ SYSCALL_INIT_HELPER(shmat),
+ SYSCALL_INIT_HELPER(shmctl),
+ SYSCALL_INIT_HELPER(shmdt),
+ SYSCALL_INIT_HELPER(shmget),
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ SYSCALL_INIT_HELPER(freebsd7_shmctl),
+#endif
+#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
+ SYSCALL_INIT_HELPER(shmsys),
+#endif
+ SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_ipc.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+static struct syscall_helper_data shm32_syscalls[] = {
+ SYSCALL32_INIT_HELPER(shmat),
+ SYSCALL32_INIT_HELPER(shmdt),
+ SYSCALL32_INIT_HELPER(shmget),
+ SYSCALL32_INIT_HELPER(freebsd32_shmsys),
+ SYSCALL32_INIT_HELPER(freebsd32_shmctl),
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ SYSCALL32_INIT_HELPER(freebsd7_freebsd32_shmctl),
+#endif
+ SYSCALL_INIT_LAST
+};
+#endif
+
+static int
shminit()
{
- int i;
+ int i, error;
#ifndef BURN_BRIDGES
if (TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall) != 0)
@@ -855,6 +892,16 @@ shminit()
shm_committed = 0;
shmexit_hook = &shmexit_myhook;
shmfork_hook = &shmfork_myhook;
+
+ error = syscall_helper_register(shm_syscalls);
+ if (error != 0)
+ return (error);
+#ifdef COMPAT_FREEBSD32
+ error = syscall32_helper_register(shm32_syscalls);
+ if (error != 0)
+ return (error);
+#endif
+ return (0);
}
static int
@@ -867,6 +914,11 @@ shmunload()
if (shm_nused > 0)
return (EBUSY);
+#ifdef COMPAT_FREEBSD32
+ syscall32_helper_unregister(shm32_syscalls);
+#endif
+ syscall_helper_unregister(shm_syscalls);
+
#ifdef MAC
for (i = 0; i < shmalloced; i++)
mac_sysvshm_destroy(&shmsegs[i]);
@@ -985,14 +1037,234 @@ shmsys(td, uap)
return (error);
}
-SYSCALL_MODULE_HELPER(shmsys);
#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
+#ifdef COMPAT_FREEBSD32
+
+int
+freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
+{
+
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+ switch (uap->which) {
+ case 0: { /* shmat */
+ struct shmat_args ap;
+
+ ap.shmid = uap->a2;
+ ap.shmaddr = PTRIN(uap->a3);
+ ap.shmflg = uap->a4;
+ return (sysent[SYS_shmat].sy_call(td, &ap));
+ }
+ case 2: { /* shmdt */
+ struct shmdt_args ap;
-#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
+ ap.shmaddr = PTRIN(uap->a2);
+ return (sysent[SYS_shmdt].sy_call(td, &ap));
+ }
+ case 3: { /* shmget */
+ struct shmget_args ap;
+ ap.key = uap->a2;
+ ap.size = uap->a3;
+ ap.shmflg = uap->a4;
+ return (sysent[SYS_shmget].sy_call(td, &ap));
+ }
+ case 4: { /* shmctl */
+ struct freebsd7_freebsd32_shmctl_args ap;
+
+ ap.shmid = uap->a2;
+ ap.cmd = uap->a3;
+ ap.buf = PTRIN(uap->a4);
+ return (freebsd7_freebsd32_shmctl(td, &ap));
+ }
+ case 1: /* oshmctl */
+ default:
+ return (EINVAL);
+ }
+#else
+ return (nosys(td, NULL));
+#endif
+}
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+int
+freebsd7_freebsd32_shmctl(struct thread *td,
+ struct freebsd7_freebsd32_shmctl_args *uap)
+{
+ int error = 0;
+ union {
+ struct shmid_ds shmid_ds;
+ struct shm_info shm_info;
+ struct shminfo shminfo;
+ } u;
+ union {
+ struct shmid_ds32_old shmid_ds32;
+ struct shm_info32 shm_info32;
+ struct shminfo32 shminfo32;
+ } u32;
+ size_t sz;
+
+ if (uap->cmd == IPC_SET) {
+ if ((error = copyin(uap->buf, &u32.shmid_ds32,
+ sizeof(u32.shmid_ds32))))
+ goto done;
+ freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
+ &u.shmid_ds.shm_perm);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
+ }
+
+ error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
+ if (error)
+ goto done;
+
+ /* Cases in which we need to copyout */
+ switch (uap->cmd) {
+ case IPC_INFO:
+ CP(u.shminfo, u32.shminfo32, shmmax);
+ CP(u.shminfo, u32.shminfo32, shmmin);
+ CP(u.shminfo, u32.shminfo32, shmmni);
+ CP(u.shminfo, u32.shminfo32, shmseg);
+ CP(u.shminfo, u32.shminfo32, shmall);
+ error = copyout(&u32.shminfo32, uap->buf,
+ sizeof(u32.shminfo32));
+ break;
+ case SHM_INFO:
+ CP(u.shm_info, u32.shm_info32, used_ids);
+ CP(u.shm_info, u32.shm_info32, shm_rss);
+ CP(u.shm_info, u32.shm_info32, shm_tot);
+ CP(u.shm_info, u32.shm_info32, shm_swp);
+ CP(u.shm_info, u32.shm_info32, swap_attempts);
+ CP(u.shm_info, u32.shm_info32, swap_successes);
+ error = copyout(&u32.shm_info32, uap->buf,
+ sizeof(u32.shm_info32));
+ break;
+ case SHM_STAT:
+ case IPC_STAT:
+ freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm,
+ &u32.shmid_ds32.shm_perm);
+ if (u.shmid_ds.shm_segsz > INT32_MAX)
+ u32.shmid_ds32.shm_segsz = INT32_MAX;
+ else
+ CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
+ u32.shmid_ds32.shm_internal = 0;
+ error = copyout(&u32.shmid_ds32, uap->buf,
+ sizeof(u32.shmid_ds32));
+ break;
+ }
+
+done:
+ if (error) {
+ /* Invalidate the return value */
+ td->td_retval[0] = -1;
+ }
+ return (error);
+}
+#endif
+
+int
+freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
+{
+ int error = 0;
+ union {
+ struct shmid_ds shmid_ds;
+ struct shm_info shm_info;
+ struct shminfo shminfo;
+ } u;
+ union {
+ struct shmid_ds32 shmid_ds32;
+ struct shm_info32 shm_info32;
+ struct shminfo32 shminfo32;
+ } u32;
+ size_t sz;
+
+ if (uap->cmd == IPC_SET) {
+ if ((error = copyin(uap->buf, &u32.shmid_ds32,
+ sizeof(u32.shmid_ds32))))
+ goto done;
+ freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
+ &u.shmid_ds.shm_perm);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
+ CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
+ }
+
+ error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
+ if (error)
+ goto done;
+
+ /* Cases in which we need to copyout */
+ switch (uap->cmd) {
+ case IPC_INFO:
+ CP(u.shminfo, u32.shminfo32, shmmax);
+ CP(u.shminfo, u32.shminfo32, shmmin);
+ CP(u.shminfo, u32.shminfo32, shmmni);
+ CP(u.shminfo, u32.shminfo32, shmseg);
+ CP(u.shminfo, u32.shminfo32, shmall);
+ error = copyout(&u32.shminfo32, uap->buf,
+ sizeof(u32.shminfo32));
+ break;
+ case SHM_INFO:
+ CP(u.shm_info, u32.shm_info32, used_ids);
+ CP(u.shm_info, u32.shm_info32, shm_rss);
+ CP(u.shm_info, u32.shm_info32, shm_tot);
+ CP(u.shm_info, u32.shm_info32, shm_swp);
+ CP(u.shm_info, u32.shm_info32, swap_attempts);
+ CP(u.shm_info, u32.shm_info32, swap_successes);
+ error = copyout(&u32.shm_info32, uap->buf,
+ sizeof(u32.shm_info32));
+ break;
+ case SHM_STAT:
+ case IPC_STAT:
+ freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
+ &u32.shmid_ds32.shm_perm);
+ if (u.shmid_ds.shm_segsz > INT32_MAX)
+ u32.shmid_ds32.shm_segsz = INT32_MAX;
+ else
+ CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
+ CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
+ error = copyout(&u32.shmid_ds32, uap->buf,
+ sizeof(u32.shmid_ds32));
+ break;
+ }
+
+done:
+ if (error) {
+ /* Invalidate the return value */
+ td->td_retval[0] = -1;
+ }
+ return (error);
+}
+#endif
+
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
+
+#ifndef CP
+#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
+#endif
#ifndef _SYS_SYSPROTO_H_
struct freebsd7_shmctl_args {
@@ -1068,10 +1340,6 @@ done:
return (error);
}
-SYSCALL_MODULE_HELPER(freebsd7_shmctl);
-
-#undef CP
-
#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
COMPAT_FREEBSD7 */
@@ -1082,7 +1350,9 @@ sysvshm_modload(struct module *module, int cmd, void *arg)
switch (cmd) {
case MOD_LOAD:
- shminit();
+ error = shminit();
+ if (error != 0)
+ shmunload();
break;
case MOD_UNLOAD:
error = shmunload();
@@ -1102,10 +1372,5 @@ static moduledata_t sysvshm_mod = {
NULL
};
-SYSCALL_MODULE_HELPER(shmat);
-SYSCALL_MODULE_HELPER(shmctl);
-SYSCALL_MODULE_HELPER(shmdt);
-SYSCALL_MODULE_HELPER(shmget);
-
DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST);
MODULE_VERSION(sysvshm, 1);
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index 290fdc2..51f2641 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -556,9 +556,9 @@ ptsdev_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
#endif /* PTS_EXTERNAL */
sb->st_ino = sb->st_rdev = tty_udev(tp);
- sb->st_atimespec = dev->si_atime;
- sb->st_ctimespec = dev->si_ctime;
- sb->st_mtimespec = dev->si_mtime;
+ sb->st_atim = dev->si_atime;
+ sb->st_ctim = dev->si_ctime;
+ sb->st_mtim = dev->si_mtime;
sb->st_uid = dev->si_uid;
sb->st_gid = dev->si_gid;
sb->st_mode = dev->si_mode | S_IFCHR;
@@ -575,6 +575,15 @@ ptsdev_close(struct file *fp, struct thread *td)
tty_lock(tp);
tty_rel_gone(tp);
+ /*
+ * Open of /dev/ptmx or /dev/ptyXX changes the type of file
+ * from DTYPE_VNODE to DTYPE_PTS. vn_open() increases vnode
+ * use count, we need to decrement it, and possibly do other
+ * required cleanup.
+ */
+ if (fp->f_vnode != NULL)
+ return (vnops.fo_close(fp, td));
+
return (0);
}
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index c44ab5a..1319666 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -45,6 +45,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_compat.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -1622,7 +1624,7 @@ mqueue_send(struct mqueue *mq, const char *msg_ptr,
const struct timespec *abs_timeout)
{
struct mqueue_msg *msg;
- struct timespec ets, ts, ts2;
+ struct timespec ts, ts2;
struct timeval tv;
int error;
@@ -1658,15 +1660,12 @@ mqueue_send(struct mqueue *mq, const char *msg_ptr,
if (error != EAGAIN)
goto bad;
- error = copyin(abs_timeout, &ets, sizeof(ets));
- if (error != 0)
- goto bad;
- if (ets.tv_nsec >= 1000000000 || ets.tv_nsec < 0) {
+ if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) {
error = EINVAL;
goto bad;
}
for (;;) {
- ts2 = ets;
+ ts2 = *abs_timeout;
getnanotime(&ts);
timespecsub(&ts2, &ts);
if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) {
@@ -1773,7 +1772,7 @@ mqueue_receive(struct mqueue *mq, char *msg_ptr,
const struct timespec *abs_timeout)
{
struct mqueue_msg *msg;
- struct timespec ets, ts, ts2;
+ struct timespec ts, ts2;
struct timeval tv;
int error;
@@ -1804,16 +1803,13 @@ mqueue_receive(struct mqueue *mq, char *msg_ptr,
if (error != EAGAIN)
return (error);
- error = copyin(abs_timeout, &ets, sizeof(ets));
- if (error != 0)
- return (error);
- if (ets.tv_nsec >= 1000000000 || ets.tv_nsec < 0) {
+ if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) {
error = EINVAL;
return (error);
}
for (;;) {
- ts2 = ets;
+ ts2 = *abs_timeout;
getnanotime(&ts);
timespecsub(&ts2, &ts);
if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) {
@@ -1934,40 +1930,28 @@ notifier_remove(struct proc *p, struct mqueue *mq, int fd)
PROC_UNLOCK(p);
}
-/*
- * Syscall to open a message queue.
- */
-int
-kmq_open(struct thread *td, struct kmq_open_args *uap)
+static int
+kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
+ const struct mq_attr *attr)
{
char path[MQFS_NAMELEN + 1];
- struct mq_attr attr, *pattr;
struct mqfs_node *pn;
struct filedesc *fdp;
struct file *fp;
struct mqueue *mq;
- int fd, error, len, flags, cmode;
-
- if ((uap->flags & O_ACCMODE) == O_ACCMODE)
- return (EINVAL);
+ int fd, error, len, cmode;
fdp = td->td_proc->p_fd;
- flags = FFLAGS(uap->flags);
- cmode = (((uap->mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT);
+ cmode = (((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT);
mq = NULL;
- if ((flags & O_CREAT) && (uap->attr != NULL)) {
- error = copyin(uap->attr, &attr, sizeof(attr));
- if (error)
- return (error);
- if (attr.mq_maxmsg <= 0 || attr.mq_maxmsg > maxmsg)
+ if ((flags & O_CREAT) != 0 && attr != NULL) {
+ if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
return (EINVAL);
- if (attr.mq_msgsize <= 0 || attr.mq_msgsize > maxmsgsize)
+ if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize)
return (EINVAL);
- pattr = &attr;
- } else
- pattr = NULL;
+ }
- error = copyinstr(uap->path, path, MQFS_NAMELEN + 1, NULL);
+ error = copyinstr(upath, path, MQFS_NAMELEN + 1, NULL);
if (error)
return (error);
@@ -1990,7 +1974,7 @@ kmq_open(struct thread *td, struct kmq_open_args *uap)
if (!(flags & O_CREAT)) {
error = ENOENT;
} else {
- mq = mqueue_alloc(pattr);
+ mq = mqueue_alloc(attr);
if (mq == NULL) {
error = ENFILE;
} else {
@@ -2045,6 +2029,27 @@ kmq_open(struct thread *td, struct kmq_open_args *uap)
}
/*
+ * Syscall to open a message queue.
+ */
+int
+kmq_open(struct thread *td, struct kmq_open_args *uap)
+{
+ struct mq_attr attr;
+ int flags, error;
+
+ if ((uap->flags & O_ACCMODE) == O_ACCMODE)
+ return (EINVAL);
+ flags = FFLAGS(uap->flags);
+ if ((flags & O_CREAT) != 0 && uap->attr != NULL) {
+ error = copyin(uap->attr, &attr, sizeof(attr));
+ if (error)
+ return (error);
+ }
+ return (kern_kmq_open(td, uap->path, flags, uap->mode,
+ uap->attr != NULL ? &attr : NULL));
+}
+
+/*
* Syscall to unlink a message queue.
*/
int
@@ -2120,39 +2125,52 @@ getmq_write(struct thread *td, int fd, struct file **fpp,
return _getmq(td, fd, fget_write, fpp, ppn, pmq);
}
-int
-kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
+static int
+kern_kmq_setattr(struct thread *td, int mqd, const struct mq_attr *attr,
+ struct mq_attr *oattr)
{
struct mqueue *mq;
struct file *fp;
- struct mq_attr attr, oattr;
u_int oflag, flag;
int error;
- if (uap->attr) {
- error = copyin(uap->attr, &attr, sizeof(attr));
- if (error)
- return (error);
- if (attr.mq_flags & ~O_NONBLOCK)
- return (EINVAL);
- }
- error = getmq(td, uap->mqd, &fp, NULL, &mq);
+ if (attr != NULL && (attr->mq_flags & ~O_NONBLOCK) != 0)
+ return (EINVAL);
+ error = getmq(td, mqd, &fp, NULL, &mq);
if (error)
return (error);
- oattr.mq_maxmsg = mq->mq_maxmsg;
- oattr.mq_msgsize = mq->mq_msgsize;
- oattr.mq_curmsgs = mq->mq_curmsgs;
- if (uap->attr) {
+ oattr->mq_maxmsg = mq->mq_maxmsg;
+ oattr->mq_msgsize = mq->mq_msgsize;
+ oattr->mq_curmsgs = mq->mq_curmsgs;
+ if (attr != NULL) {
do {
oflag = flag = fp->f_flag;
flag &= ~O_NONBLOCK;
- flag |= (attr.mq_flags & O_NONBLOCK);
+ flag |= (attr->mq_flags & O_NONBLOCK);
} while (atomic_cmpset_int(&fp->f_flag, oflag, flag) == 0);
} else
oflag = fp->f_flag;
- oattr.mq_flags = (O_NONBLOCK & oflag);
+ oattr->mq_flags = (O_NONBLOCK & oflag);
fdrop(fp, td);
- if (uap->oattr)
+ return (error);
+}
+
+int
+kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
+{
+ struct mq_attr attr, oattr;
+ int error;
+
+ if (uap->attr != NULL) {
+ error = copyin(uap->attr, &attr, sizeof(attr));
+ if (error != 0)
+ return (error);
+ }
+ error = kern_kmq_setattr(td, uap->mqd, uap->attr != NULL ? &attr : NULL,
+ &oattr);
+ if (error != 0)
+ return (error);
+ if (uap->oattr != NULL)
error = copyout(&oattr, uap->oattr, sizeof(oattr));
return (error);
}
@@ -2162,15 +2180,23 @@ kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
{
struct mqueue *mq;
struct file *fp;
+ struct timespec *abs_timeout, ets;
int error;
int waitok;
error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
+ if (uap->abs_timeout != NULL) {
+ error = copyin(uap->abs_timeout, &ets, sizeof(ets));
+ if (error != 0)
+ return (error);
+ abs_timeout = &ets;
+ } else
+ abs_timeout = NULL;
waitok = !(fp->f_flag & O_NONBLOCK);
error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
- uap->msg_prio, waitok, uap->abs_timeout);
+ uap->msg_prio, waitok, abs_timeout);
fdrop(fp, td);
return (error);
}
@@ -2180,14 +2206,22 @@ kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
{
struct mqueue *mq;
struct file *fp;
+ struct timespec *abs_timeout, ets;
int error, waitok;
error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
+ if (uap->abs_timeout != NULL) {
+ error = copyin(uap->abs_timeout, &ets, sizeof(ets));
+ if (error != 0)
+ return (error);
+ abs_timeout = &ets;
+ } else
+ abs_timeout = NULL;
waitok = !(fp->f_flag & O_NONBLOCK);
error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
- uap->msg_prio, waitok, uap->abs_timeout);
+ uap->msg_prio, waitok, abs_timeout);
fdrop(fp, td);
return (error);
}
@@ -2413,10 +2447,10 @@ mqf_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
struct mqfs_node *pn = fp->f_data;
bzero(st, sizeof *st);
- st->st_atimespec = pn->mn_atime;
- st->st_mtimespec = pn->mn_mtime;
- st->st_ctimespec = pn->mn_ctime;
- st->st_birthtimespec = pn->mn_birth;
+ st->st_atim = pn->mn_atime;
+ st->st_mtim = pn->mn_mtime;
+ st->st_ctim = pn->mn_ctime;
+ st->st_birthtim = pn->mn_birth;
st->st_uid = pn->mn_uid;
st->st_gid = pn->mn_gid;
st->st_mode = S_IFIFO | pn->mn_mode;
@@ -2511,12 +2545,219 @@ static struct vfsops mqfs_vfsops = {
.vfs_statfs = mqfs_statfs,
};
-SYSCALL_MODULE_HELPER(kmq_open);
-SYSCALL_MODULE_HELPER(kmq_setattr);
-SYSCALL_MODULE_HELPER(kmq_timedsend);
-SYSCALL_MODULE_HELPER(kmq_timedreceive);
-SYSCALL_MODULE_HELPER(kmq_notify);
-SYSCALL_MODULE_HELPER(kmq_unlink);
+static struct vfsconf mqueuefs_vfsconf = {
+ .vfc_version = VFS_VERSION,
+ .vfc_name = "mqueuefs",
+ .vfc_vfsops = &mqfs_vfsops,
+ .vfc_typenum = -1,
+ .vfc_flags = VFCF_SYNTHETIC
+};
+
+static struct syscall_helper_data mq_syscalls[] = {
+ SYSCALL_INIT_HELPER(kmq_open),
+ SYSCALL_INIT_HELPER(kmq_setattr),
+ SYSCALL_INIT_HELPER(kmq_timedsend),
+ SYSCALL_INIT_HELPER(kmq_timedreceive),
+ SYSCALL_INIT_HELPER(kmq_notify),
+ SYSCALL_INIT_HELPER(kmq_unlink),
+ SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+static void
+mq_attr_from32(const struct mq_attr32 *from, struct mq_attr *to)
+{
+
+ to->mq_flags = from->mq_flags;
+ to->mq_maxmsg = from->mq_maxmsg;
+ to->mq_msgsize = from->mq_msgsize;
+ to->mq_curmsgs = from->mq_curmsgs;
+}
+
+static void
+mq_attr_to32(const struct mq_attr *from, struct mq_attr32 *to)
+{
+
+ to->mq_flags = from->mq_flags;
+ to->mq_maxmsg = from->mq_maxmsg;
+ to->mq_msgsize = from->mq_msgsize;
+ to->mq_curmsgs = from->mq_curmsgs;
+}
+
+int
+freebsd32_kmq_open(struct thread *td, struct freebsd32_kmq_open_args *uap)
+{
+ struct mq_attr attr;
+ struct mq_attr32 attr32;
+ int flags, error;
+
+ if ((uap->flags & O_ACCMODE) == O_ACCMODE)
+ return (EINVAL);
+ flags = FFLAGS(uap->flags);
+ if ((flags & O_CREAT) != 0 && uap->attr != NULL) {
+ error = copyin(uap->attr, &attr32, sizeof(attr32));
+ if (error)
+ return (error);
+ mq_attr_from32(&attr32, &attr);
+ }
+ return (kern_kmq_open(td, uap->path, flags, uap->mode,
+ uap->attr != NULL ? &attr : NULL));
+}
+
+int
+freebsd32_kmq_setattr(struct thread *td, struct freebsd32_kmq_setattr_args *uap)
+{
+ struct mq_attr attr, oattr;
+ struct mq_attr32 attr32, oattr32;
+ int error;
+
+ if (uap->attr != NULL) {
+ error = copyin(uap->attr, &attr32, sizeof(attr32));
+ if (error != 0)
+ return (error);
+ mq_attr_from32(&attr32, &attr);
+ }
+ error = kern_kmq_setattr(td, uap->mqd, uap->attr != NULL ? &attr : NULL,
+ &oattr);
+ if (error != 0)
+ return (error);
+ if (uap->oattr != NULL) {
+ mq_attr_to32(&oattr, &oattr32);
+ error = copyout(&oattr32, uap->oattr, sizeof(oattr32));
+ }
+ return (error);
+}
+
+int
+freebsd32_kmq_timedsend(struct thread *td,
+ struct freebsd32_kmq_timedsend_args *uap)
+{
+ struct mqueue *mq;
+ struct file *fp;
+ struct timespec32 ets32;
+ struct timespec *abs_timeout, ets;
+ int error;
+ int waitok;
+
+ error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
+ if (error)
+ return (error);
+ if (uap->abs_timeout != NULL) {
+ error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
+ if (error != 0)
+ return (error);
+ CP(ets32, ets, tv_sec);
+ CP(ets32, ets, tv_nsec);
+ abs_timeout = &ets;
+ } else
+ abs_timeout = NULL;
+ waitok = !(fp->f_flag & O_NONBLOCK);
+ error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
+ uap->msg_prio, waitok, abs_timeout);
+ fdrop(fp, td);
+ return (error);
+}
+
+int
+freebsd32_kmq_timedreceive(struct thread *td,
+ struct freebsd32_kmq_timedreceive_args *uap)
+{
+ struct mqueue *mq;
+ struct file *fp;
+ struct timespec32 ets32;
+ struct timespec *abs_timeout, ets;
+ int error, waitok;
+
+ error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
+ if (error)
+ return (error);
+ if (uap->abs_timeout != NULL) {
+ error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
+ if (error != 0)
+ return (error);
+ CP(ets32, ets, tv_sec);
+ CP(ets32, ets, tv_nsec);
+ abs_timeout = &ets;
+ } else
+ abs_timeout = NULL;
+ waitok = !(fp->f_flag & O_NONBLOCK);
+ error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
+ uap->msg_prio, waitok, abs_timeout);
+ fdrop(fp, td);
+ return (error);
+}
+
+static struct syscall_helper_data mq32_syscalls[] = {
+ SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
+ SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
+ SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
+ SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
+ SYSCALL32_INIT_HELPER(kmq_notify),
+ SYSCALL32_INIT_HELPER(kmq_unlink),
+ SYSCALL_INIT_LAST
+};
+#endif
+
+static int
+mqinit(void)
+{
+ int error;
+
+ error = syscall_helper_register(mq_syscalls);
+ if (error != 0)
+ return (error);
+#ifdef COMPAT_FREEBSD32
+ error = syscall32_helper_register(mq32_syscalls);
+ if (error != 0)
+ return (error);
+#endif
+ return (0);
+}
+
+static int
+mqunload(void)
+{
+
+#ifdef COMPAT_FREEBSD32
+ syscall32_helper_unregister(mq32_syscalls);
+#endif
+ syscall_helper_unregister(mq_syscalls);
+ return (0);
+}
+
+static int
+mq_modload(struct module *module, int cmd, void *arg)
+{
+ int error = 0;
+
+ error = vfs_modevent(module, cmd, arg);
+ if (error != 0)
+ return (error);
-VFS_SET(mqfs_vfsops, mqueuefs, VFCF_SYNTHETIC);
+ switch (cmd) {
+ case MOD_LOAD:
+ error = mqinit();
+ if (error != 0)
+ mqunload();
+ break;
+ case MOD_UNLOAD:
+ error = mqunload();
+ break;
+ default:
+ break;
+ }
+ return (error);
+}
+
+static moduledata_t mqueuefs_mod = {
+ "mqueuefs",
+ mq_modload,
+ &mqueuefs_vfsconf
+};
+DECLARE_MODULE(mqueuefs, mqueuefs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE);
MODULE_VERSION(mqueuefs, 1);
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index f41b49c..d9229ea 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
@@ -34,6 +34,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_compat.h"
#include "opt_posix.h"
#include <sys/param.h>
@@ -112,7 +113,7 @@ static struct ksem *ksem_alloc(struct ucred *ucred, mode_t mode,
unsigned int value);
static int ksem_create(struct thread *td, const char *path,
semid_t *semidp, mode_t mode, unsigned int value,
- int flags);
+ int flags, int compat32);
static void ksem_drop(struct ksem *ks);
static int ksem_get(struct thread *td, semid_t id, struct file **fpp);
static struct ksem *ksem_hold(struct ksem *ks);
@@ -218,10 +219,10 @@ ksem_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
bzero(sb, sizeof(*sb));
sb->st_mode = S_IFREG | ks->ks_mode; /* XXX */
- sb->st_atimespec = ks->ks_atime;
- sb->st_ctimespec = ks->ks_ctime;
- sb->st_mtimespec = ks->ks_mtime;
- sb->st_birthtimespec = ks->ks_birthtime;
+ sb->st_atim = ks->ks_atime;
+ sb->st_ctim = ks->ks_ctime;
+ sb->st_mtim = ks->ks_mtime;
+ sb->st_birthtim = ks->ks_birthtime;
sb->st_uid = ks->ks_uid;
sb->st_gid = ks->ks_gid;
@@ -374,16 +375,44 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
return (ENOENT);
}
+static int
+ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd,
+ int compat32)
+{
+ semid_t semid;
+#ifdef COMPAT_FREEBSD32
+ int32_t semid32;
+#endif
+ void *ptr;
+ size_t ptrs;
+
+#ifdef COMPAT_FREEBSD32
+ if (compat32) {
+ semid32 = fd;
+ ptr = &semid32;
+ ptrs = sizeof(semid32);
+ } else {
+#endif
+ semid = fd;
+ ptr = &semid;
+ ptrs = sizeof(semid);
+ compat32 = 0; /* silence gcc */
+#ifdef COMPAT_FREEBSD32
+ }
+#endif
+
+ return (copyout(ptr, semidp, ptrs));
+}
+
/* Other helper routines. */
static int
ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
- unsigned int value, int flags)
+ unsigned int value, int flags, int compat32)
{
struct filedesc *fdp;
struct ksem *ks;
struct file *fp;
char *path;
- semid_t semid;
Fnv32_t fnv;
int error, fd;
@@ -404,8 +433,7 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
* premature, but it is a lot easier to handle errors as opposed
* to later when we've possibly created a new semaphore, etc.
*/
- semid = fd;
- error = copyout(&semid, semidp, sizeof(semid));
+ error = ksem_create_copyout_semid(td, semidp, fd, compat32);
if (error) {
fdclose(fdp, fp, fd, td);
fdrop(fp, td);
@@ -530,7 +558,7 @@ ksem_init(struct thread *td, struct ksem_init_args *uap)
{
return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value,
- 0));
+ 0, 0));
}
#ifndef _SYS_SYSPROTO_H_
@@ -551,7 +579,7 @@ ksem_open(struct thread *td, struct ksem_open_args *uap)
if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0)
return (EINVAL);
return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value,
- uap->oflag));
+ uap->oflag, 0));
}
#ifndef _SYS_SYSPROTO_H_
@@ -832,38 +860,85 @@ err:
return (error);
}
-#define SYSCALL_DATA(syscallname) \
-static int syscallname##_syscall = SYS_##syscallname; \
-static int syscallname##_registered; \
-static struct sysent syscallname##_old_sysent; \
-MAKE_SYSENT(syscallname);
-
-#define SYSCALL_REGISTER(syscallname) do { \
- error = syscall_register(& syscallname##_syscall, \
- & syscallname##_sysent, & syscallname##_old_sysent); \
- if (error) \
- return (error); \
- syscallname##_registered = 1; \
-} while(0)
-
-#define SYSCALL_DEREGISTER(syscallname) do { \
- if (syscallname##_registered) { \
- syscallname##_registered = 0; \
- syscall_deregister(& syscallname##_syscall, \
- & syscallname##_old_sysent); \
- } \
-} while(0)
-
-SYSCALL_DATA(ksem_init);
-SYSCALL_DATA(ksem_open);
-SYSCALL_DATA(ksem_unlink);
-SYSCALL_DATA(ksem_close);
-SYSCALL_DATA(ksem_post);
-SYSCALL_DATA(ksem_wait);
-SYSCALL_DATA(ksem_timedwait);
-SYSCALL_DATA(ksem_trywait);
-SYSCALL_DATA(ksem_getvalue);
-SYSCALL_DATA(ksem_destroy);
+static struct syscall_helper_data ksem_syscalls[] = {
+ SYSCALL_INIT_HELPER(ksem_init),
+ SYSCALL_INIT_HELPER(ksem_open),
+ SYSCALL_INIT_HELPER(ksem_unlink),
+ SYSCALL_INIT_HELPER(ksem_close),
+ SYSCALL_INIT_HELPER(ksem_post),
+ SYSCALL_INIT_HELPER(ksem_wait),
+ SYSCALL_INIT_HELPER(ksem_timedwait),
+ SYSCALL_INIT_HELPER(ksem_trywait),
+ SYSCALL_INIT_HELPER(ksem_getvalue),
+ SYSCALL_INIT_HELPER(ksem_destroy),
+ SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+int
+freebsd32_ksem_init(struct thread *td, struct freebsd32_ksem_init_args *uap)
+{
+
+ return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value,
+ 0, 1));
+}
+
+int
+freebsd32_ksem_open(struct thread *td, struct freebsd32_ksem_open_args *uap)
+{
+
+ if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0)
+ return (EINVAL);
+ return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value,
+ uap->oflag, 1));
+}
+
+int
+freebsd32_ksem_timedwait(struct thread *td,
+ struct freebsd32_ksem_timedwait_args *uap)
+{
+ struct timespec32 abstime32;
+ struct timespec *ts, abstime;
+ int error;
+
+ /*
+ * We allow a null timespec (wait forever).
+ */
+ if (uap->abstime == NULL)
+ ts = NULL;
+ else {
+ error = copyin(uap->abstime, &abstime32, sizeof(abstime32));
+ if (error != 0)
+ return (error);
+ CP(abstime32, abstime, tv_sec);
+ CP(abstime32, abstime, tv_nsec);
+ if (abstime.tv_nsec >= 1000000000 || abstime.tv_nsec < 0)
+ return (EINVAL);
+ ts = &abstime;
+ }
+ return (kern_sem_wait(td, uap->id, 0, ts));
+}
+
+static struct syscall_helper_data ksem32_syscalls[] = {
+ SYSCALL32_INIT_HELPER(freebsd32_ksem_init),
+ SYSCALL32_INIT_HELPER(freebsd32_ksem_open),
+ SYSCALL32_INIT_HELPER(ksem_unlink),
+ SYSCALL32_INIT_HELPER(ksem_close),
+ SYSCALL32_INIT_HELPER(ksem_post),
+ SYSCALL32_INIT_HELPER(ksem_wait),
+ SYSCALL32_INIT_HELPER(freebsd32_ksem_timedwait),
+ SYSCALL32_INIT_HELPER(ksem_trywait),
+ SYSCALL32_INIT_HELPER(ksem_getvalue),
+ SYSCALL32_INIT_HELPER(ksem_destroy),
+ SYSCALL_INIT_LAST
+};
+#endif
static int
ksem_module_init(void)
@@ -877,16 +952,14 @@ ksem_module_init(void)
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
- SYSCALL_REGISTER(ksem_init);
- SYSCALL_REGISTER(ksem_open);
- SYSCALL_REGISTER(ksem_unlink);
- SYSCALL_REGISTER(ksem_close);
- SYSCALL_REGISTER(ksem_post);
- SYSCALL_REGISTER(ksem_wait);
- SYSCALL_REGISTER(ksem_timedwait);
- SYSCALL_REGISTER(ksem_trywait);
- SYSCALL_REGISTER(ksem_getvalue);
- SYSCALL_REGISTER(ksem_destroy);
+ error = syscall_helper_register(ksem_syscalls);
+ if (error)
+ return (error);
+#ifdef COMPAT_FREEBSD32
+ error = syscall32_helper_register(ksem32_syscalls);
+ if (error)
+ return (error);
+#endif
return (0);
}
@@ -894,16 +967,10 @@ static void
ksem_module_destroy(void)
{
- SYSCALL_DEREGISTER(ksem_init);
- SYSCALL_DEREGISTER(ksem_open);
- SYSCALL_DEREGISTER(ksem_unlink);
- SYSCALL_DEREGISTER(ksem_close);
- SYSCALL_DEREGISTER(ksem_post);
- SYSCALL_DEREGISTER(ksem_wait);
- SYSCALL_DEREGISTER(ksem_timedwait);
- SYSCALL_DEREGISTER(ksem_trywait);
- SYSCALL_DEREGISTER(ksem_getvalue);
- SYSCALL_DEREGISTER(ksem_destroy);
+#ifdef COMPAT_FREEBSD32
+ syscall32_helper_unregister(ksem32_syscalls);
+#endif
+ syscall_helper_unregister(ksem_syscalls);
hashdestroy(ksem_dictionary, M_KSEM, ksem_hash);
sx_destroy(&ksem_dict_lock);
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 32bfd2d..fe1a224 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -219,10 +219,10 @@ shm_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
sb->st_blksize = PAGE_SIZE;
sb->st_size = shmfd->shm_size;
sb->st_blocks = (sb->st_size + sb->st_blksize - 1) / sb->st_blksize;
- sb->st_atimespec = shmfd->shm_atime;
- sb->st_ctimespec = shmfd->shm_ctime;
- sb->st_mtimespec = shmfd->shm_mtime;
- sb->st_birthtimespec = shmfd->shm_birthtime;
+ sb->st_atim = shmfd->shm_atime;
+ sb->st_ctim = shmfd->shm_ctime;
+ sb->st_mtim = shmfd->shm_mtime;
+ sb->st_birthtim = shmfd->shm_birthtime;
sb->st_uid = shmfd->shm_uid;
sb->st_gid = shmfd->shm_gid;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 5cbdc40..569aed0 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -136,7 +136,7 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
#include <sys/mount.h>
#include <sys/sysent.h>
#include <compat/freebsd32/freebsd32.h>
@@ -2507,7 +2507,7 @@ sosetopt(struct socket *so, struct sockopt *sopt)
case SO_SNDTIMEO:
case SO_RCVTIMEO:
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
struct timeval32 tv32;
@@ -2688,7 +2688,7 @@ integer:
tv.tv_sec = optval / hz;
tv.tv_usec = (optval % hz) * tick;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
struct timeval32 tv32;
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index c3e755b..a14be72 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/sf_buf.h>
+#include <sys/sysent.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/signalvar.h>
@@ -69,6 +70,9 @@ __FBSDID("$FreeBSD$");
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32_util.h>
+#endif
#include <net/vnet.h>
@@ -2513,7 +2517,13 @@ sctp_generic_sendmsg_iov(td, uap)
if (error)
goto sctp_bad1;
- error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32))
+ error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
+ uap->iovlen, &iov, EMSGSIZE);
+ else
+#endif
+ error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
if (error)
goto sctp_bad1;
#ifdef KTRACE
@@ -2528,7 +2538,7 @@ sctp_generic_sendmsg_iov(td, uap)
goto sctp_bad;
#endif /* MAC */
- auio.uio_iov = iov;
+ auio.uio_iov = iov;
auio.uio_iovcnt = uap->iovlen;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_WRITE;
@@ -2615,17 +2625,21 @@ sctp_generic_recvmsg(td, uap)
if (error) {
return (error);
}
- error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
- if (error) {
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32))
+ error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
+ uap->iovlen, &iov, EMSGSIZE);
+ else
+#endif
+ error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
+ if (error)
goto out1;
- }
so = fp->f_data;
#ifdef MAC
error = mac_socket_check_receive(td->td_ucred, so);
if (error) {
goto out;
- return (error);
}
#endif /* MAC */
@@ -2638,7 +2652,7 @@ sctp_generic_recvmsg(td, uap)
} else {
fromlen = 0;
}
- if(uap->msg_flags) {
+ if (uap->msg_flags) {
error = copyin(uap->msg_flags, &msg_flags, sizeof (int));
if (error) {
goto out;
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 088e4f6..e05106a 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -334,7 +334,7 @@ static TAILQ_HEAD(,aiocblist) aio_jobs; /* (c) Async job list */
static struct unrhdr *aiod_unr;
void aio_init_aioinfo(struct proc *p);
-static void aio_onceonly(void);
+static int aio_onceonly(void);
static int aio_free_entry(struct aiocblist *aiocbe);
static void aio_process(struct aiocblist *aiocbe);
static int aio_newproc(int *);
@@ -419,18 +419,47 @@ static moduledata_t aio_mod = {
NULL
};
-SYSCALL_MODULE_HELPER(aio_cancel);
-SYSCALL_MODULE_HELPER(aio_error);
-SYSCALL_MODULE_HELPER(aio_fsync);
-SYSCALL_MODULE_HELPER(aio_read);
-SYSCALL_MODULE_HELPER(aio_return);
-SYSCALL_MODULE_HELPER(aio_suspend);
-SYSCALL_MODULE_HELPER(aio_waitcomplete);
-SYSCALL_MODULE_HELPER(aio_write);
-SYSCALL_MODULE_HELPER(lio_listio);
-SYSCALL_MODULE_HELPER(oaio_read);
-SYSCALL_MODULE_HELPER(oaio_write);
-SYSCALL_MODULE_HELPER(olio_listio);
+static struct syscall_helper_data aio_syscalls[] = {
+ SYSCALL_INIT_HELPER(aio_cancel),
+ SYSCALL_INIT_HELPER(aio_error),
+ SYSCALL_INIT_HELPER(aio_fsync),
+ SYSCALL_INIT_HELPER(aio_read),
+ SYSCALL_INIT_HELPER(aio_return),
+ SYSCALL_INIT_HELPER(aio_suspend),
+ SYSCALL_INIT_HELPER(aio_waitcomplete),
+ SYSCALL_INIT_HELPER(aio_write),
+ SYSCALL_INIT_HELPER(lio_listio),
+ SYSCALL_INIT_HELPER(oaio_read),
+ SYSCALL_INIT_HELPER(oaio_write),
+ SYSCALL_INIT_HELPER(olio_listio),
+ SYSCALL_INIT_LAST
+};
+
+#ifdef COMPAT_FREEBSD32
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/freebsd32/freebsd32_util.h>
+
+static struct syscall_helper_data aio32_syscalls[] = {
+ SYSCALL32_INIT_HELPER(freebsd32_aio_return),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_suspend),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_cancel),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_error),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_fsync),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_read),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_write),
+ SYSCALL32_INIT_HELPER(freebsd32_aio_waitcomplete),
+ SYSCALL32_INIT_HELPER(freebsd32_lio_listio),
+ SYSCALL32_INIT_HELPER(freebsd32_oaio_read),
+ SYSCALL32_INIT_HELPER(freebsd32_oaio_write),
+ SYSCALL32_INIT_HELPER(freebsd32_olio_listio),
+ SYSCALL_INIT_LAST
+};
+#endif
DECLARE_MODULE(aio, aio_mod,
SI_SUB_VFS, SI_ORDER_ANY);
@@ -439,9 +468,10 @@ MODULE_VERSION(aio, 1);
/*
* Startup initialization
*/
-static void
+static int
aio_onceonly(void)
{
+ int error;
/* XXX: should probably just use so->callback */
aio_swake = &aio_swake_cb;
@@ -474,6 +504,16 @@ aio_onceonly(void)
p31b_setcfg(CTL_P1003_1B_AIO_LISTIO_MAX, AIO_LISTIO_MAX);
p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE);
p31b_setcfg(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, 0);
+
+ error = syscall_helper_register(aio_syscalls);
+ if (error)
+ return (error);
+#ifdef COMPAT_FREEBSD32
+ error = syscall32_helper_register(aio32_syscalls);
+ if (error)
+ return (error);
+#endif
+ return (0);
}
/*
@@ -495,6 +535,11 @@ aio_unload(void)
if (!unloadable)
return (EOPNOTSUPP);
+#ifdef COMPAT_FREEBSD32
+ syscall32_helper_unregister(aio32_syscalls);
+#endif
+ syscall_helper_unregister(aio_syscalls);
+
error = kqueue_del_filteropts(EVFILT_AIO);
if (error)
return error;
@@ -2532,14 +2577,7 @@ filt_lio(struct knote *kn, long hint)
return (lj->lioj_flags & LIOJ_KEVENT_POSTED);
}
-#ifdef COMPAT_IA32
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <compat/freebsd32/freebsd32.h>
-#include <compat/freebsd32/freebsd32_proto.h>
-#include <compat/freebsd32/freebsd32_signal.h>
-#include <compat/freebsd32/freebsd32_syscall.h>
-#include <compat/freebsd32/freebsd32_util.h>
+#ifdef COMPAT_FREEBSD32
struct __aiocb_private32 {
int32_t status;
@@ -2948,16 +2986,4 @@ freebsd32_lio_listio(struct thread *td, struct freebsd32_lio_listio_args *uap)
return (error);
}
-SYSCALL32_MODULE_HELPER(freebsd32_aio_return);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_suspend);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_cancel);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_error);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_fsync);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_read);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_write);
-SYSCALL32_MODULE_HELPER(freebsd32_aio_waitcomplete);
-SYSCALL32_MODULE_HELPER(freebsd32_lio_listio);
-SYSCALL32_MODULE_HELPER(freebsd32_oaio_read);
-SYSCALL32_MODULE_HELPER(freebsd32_oaio_write);
-SYSCALL32_MODULE_HELPER(freebsd32_olio_listio);
#endif
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index df9a257..156b676 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -216,6 +216,14 @@ SYSCTL_LONG(_vfs, OID_AUTO, notbufdflashes, CTLFLAG_RD, &notbufdflashes, 0,
static int bd_request;
/*
+ * Request for the buf daemon to write more buffers than is indicated by
+ * lodirtybuf. This may be necessary to push out excess dependencies or
+ * defragment the address space where a simple count of the number of dirty
+ * buffers is insufficient to characterize the demand for flushing them.
+ */
+static int bd_speedupreq;
+
+/*
* This lock synchronizes access to bd_request.
*/
static struct mtx bdlock;
@@ -467,12 +475,20 @@ bd_wakeup(int dirtybuflevel)
* bd_speedup - speedup the buffer cache flushing code
*/
-static __inline
void
bd_speedup(void)
{
+ int needwake;
- bd_wakeup(1);
+ mtx_lock(&bdlock);
+ needwake = 0;
+ if (bd_speedupreq == 0 || bd_request == 0)
+ needwake = 1;
+ bd_speedupreq = 1;
+ bd_request = 1;
+ if (needwake)
+ wakeup(&bd_request);
+ mtx_unlock(&bdlock);
}
/*
@@ -2120,6 +2136,7 @@ buf_do_flush(struct vnode *vp)
static void
buf_daemon()
{
+ int lodirtysave;
/*
* This process needs to be suspended prior to shutdown sync.
@@ -2137,7 +2154,11 @@ buf_daemon()
mtx_unlock(&bdlock);
kproc_suspend_check(bufdaemonproc);
-
+ lodirtysave = lodirtybuffers;
+ if (bd_speedupreq) {
+ lodirtybuffers = numdirtybuffers / 2;
+ bd_speedupreq = 0;
+ }
/*
* Do the flush. Limit the amount of in-transit I/O we
* allow to build up, otherwise we would completely saturate
@@ -2149,6 +2170,7 @@ buf_daemon()
break;
uio_yield();
}
+ lodirtybuffers = lodirtysave;
/*
* Only clear bd_request if we have reached our low water
@@ -2678,7 +2700,7 @@ loop:
*/
if (flags & GB_NOCREAT)
return NULL;
- bsize = bo->bo_bsize;
+ bsize = vn_isdisk(vp, NULL) ? DEV_BSIZE : bo->bo_bsize;
offset = blkno * bsize;
vmio = vp->v_object != NULL;
maxsize = vmio ? size + (offset & PAGE_MASK) : size;
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 7854803..a13a721 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -610,7 +610,9 @@ cache_enter(dvp, vp, cnp)
CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr);
VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp,
- ("cahe_enter: Adding a doomed vnode"));
+ ("cache_enter: Adding a doomed vnode"));
+ VNASSERT(dvp == NULL || (dvp->v_iflag & VI_DOOMED) == 0, dvp,
+ ("cache_enter: Doomed vnode used as src"));
if (!doingcache)
return;
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 50bf0d2..3788147 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vnode_pager.h>
static int vop_nolookup(struct vop_lookup_args *);
+static int vop_norename(struct vop_rename_args *);
static int vop_nostrategy(struct vop_strategy_args *);
static int get_next_dirent(struct vnode *vp, struct dirent **dpp,
char *dirbuf, int dirbuflen, off_t *off,
@@ -113,6 +114,7 @@ struct vop_vector default_vnodeops = {
.vop_poll = vop_nopoll,
.vop_putpages = vop_stdputpages,
.vop_readlink = VOP_EINVAL,
+ .vop_rename = vop_norename,
.vop_revoke = VOP_PANIC,
.vop_strategy = vop_nostrategy,
.vop_unlock = vop_stdunlock,
@@ -206,6 +208,20 @@ vop_nolookup(ap)
}
/*
+ * vop_norename:
+ *
+ * Handle unlock and reference counting for arguments of vop_rename
+ * for filesystems that do not implement rename operation.
+ */
+static int
+vop_norename(struct vop_rename_args *ap)
+{
+
+ vop_rename_fail(ap);
+ return (EOPNOTSUPP);
+}
+
+/*
* vop_nostrategy:
*
* Strategy routine for VFS devices that have none.
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 6f10b49..5b6ccf6 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -948,19 +948,17 @@ relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
#endif
/*
- * Check for degenerate name (e.g. / or "")
- * which is a way of talking about a directory,
- * e.g. like "/." or ".".
+ * Check for "" which represents the root directory after slash
+ * removal.
*/
if (cnp->cn_nameptr[0] == '\0') {
- if (cnp->cn_nameiop != LOOKUP || wantparent) {
- error = EISDIR;
- goto bad;
- }
- if (dp->v_type != VDIR) {
- error = ENOTDIR;
- goto bad;
- }
+ /*
+ * Support only LOOKUP for "/" because lookup()
+ * can't succeed for CREATE, DELETE and RENAME.
+ */
+ KASSERT(cnp->cn_nameiop == LOOKUP, ("nameiop must be LOOKUP"));
+ KASSERT(dp->v_type == VDIR, ("dp is not a directory"));
+
if (!(cnp->cn_flags & LOCKLEAF))
VOP_UNLOCK(dp, 0);
*vpp = dp;
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index daaa5b1..ae182e0 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1378,7 +1378,7 @@ restartsync:
/*
* buf_splay() - splay tree core for the clean/dirty list of buffers in
- * a vnode.
+ * a vnode.
*
* NOTE: We have to deal with the special case of a background bitmap
* buffer, a situation where two buffers will have the same logical
@@ -2100,13 +2100,13 @@ vget(struct vnode *vp, int flags, struct thread *td)
/* Upgrade our holdcnt to a usecount. */
v_upgrade_usecount(vp);
/*
- * We don't guarantee that any particular close will
+ * We don't guarantee that any particular close will
* trigger inactive processing so just make a best effort
* here at preventing a reference to a removed file. If
* we don't succeed no harm is done.
*/
if (vp->v_iflag & VI_OWEINACT) {
- if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE &&
+ if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE &&
(flags & LK_NOWAIT) == 0)
vinactive(vp, td);
vp->v_iflag &= ~VI_OWEINACT;
@@ -2362,7 +2362,7 @@ SYSCTL_INT(_debug, OID_AUTO, busyprt, CTLFLAG_RW, &busyprt, 0, "");
#endif
int
-vflush( struct mount *mp, int rootrefs, int flags, struct thread *td)
+vflush(struct mount *mp, int rootrefs, int flags, struct thread *td)
{
struct vnode *vp, *mvp, *rootvp = NULL;
struct vattr vattr;
@@ -2383,12 +2383,10 @@ vflush( struct mount *mp, int rootrefs, int flags, struct thread *td)
return (error);
}
vput(rootvp);
-
}
MNT_ILOCK(mp);
loop:
MNT_VNODE_FOREACH(vp, mp, mvp) {
-
VI_LOCK(vp);
vholdl(vp);
MNT_IUNLOCK(mp);
@@ -2799,6 +2797,7 @@ DB_SHOW_COMMAND(mount, db_show_mount)
MNT_FLAG(MNT_NOATIME);
MNT_FLAG(MNT_NOCLUSTERR);
MNT_FLAG(MNT_NOCLUSTERW);
+ MNT_FLAG(MNT_NFS4ACLS);
MNT_FLAG(MNT_EXRDONLY);
MNT_FLAG(MNT_EXPORTED);
MNT_FLAG(MNT_DEFEXPORTED);
@@ -2816,6 +2815,7 @@ DB_SHOW_COMMAND(mount, db_show_mount)
MNT_FLAG(MNT_FORCE);
MNT_FLAG(MNT_SNAPSHOT);
MNT_FLAG(MNT_BYFSID);
+ MNT_FLAG(MNT_SOFTDEP);
#undef MNT_FLAG
if (flags != 0) {
if (buf[0] != '\0')
@@ -2839,14 +2839,18 @@ DB_SHOW_COMMAND(mount, db_show_mount)
MNT_KERN_FLAG(MNTK_ASYNC);
MNT_KERN_FLAG(MNTK_SOFTDEP);
MNT_KERN_FLAG(MNTK_NOINSMNTQ);
+ MNT_KERN_FLAG(MNTK_DRAINING);
+ MNT_KERN_FLAG(MNTK_REFEXPIRE);
+ MNT_KERN_FLAG(MNTK_EXTENDED_SHARED);
+ MNT_KERN_FLAG(MNTK_SHARED_WRITES);
MNT_KERN_FLAG(MNTK_UNMOUNT);
MNT_KERN_FLAG(MNTK_MWAIT);
MNT_KERN_FLAG(MNTK_SUSPEND);
MNT_KERN_FLAG(MNTK_SUSPEND2);
MNT_KERN_FLAG(MNTK_SUSPENDED);
MNT_KERN_FLAG(MNTK_MPSAFE);
- MNT_KERN_FLAG(MNTK_NOKNOTE);
MNT_KERN_FLAG(MNTK_LOOKUP_SHARED);
+ MNT_KERN_FLAG(MNTK_NOKNOTE);
#undef MNT_KERN_FLAG
if (flags != 0) {
if (buf[0] != '\0')
@@ -3526,7 +3530,7 @@ vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid,
KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND)) == 0,
("invalid bit in accmode"));
KASSERT((accmode & VAPPEND) == 0 || (accmode & VWRITE),
- ("VAPPEND without VWRITE"));
+ ("VAPPEND without VWRITE"));
/*
* Look for a normal, non-privileged way to access the file/directory
@@ -3751,6 +3755,20 @@ assert_vop_slocked(struct vnode *vp, const char *str)
#endif /* DEBUG_VFS_LOCKS */
void
+vop_rename_fail(struct vop_rename_args *ap)
+{
+
+ if (ap->a_tvp != NULL)
+ vput(ap->a_tvp);
+ if (ap->a_tdvp == ap->a_tvp)
+ vrele(ap->a_tdvp);
+ else
+ vput(ap->a_tdvp);
+ vrele(ap->a_fdvp);
+ vrele(ap->a_fvp);
+}
+
+void
vop_rename_pre(void *ap)
{
struct vop_rename_args *a = ap;
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index f1e6ca8..ab0627d 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/disk.h>
#include <sys/sysent.h>
#include <sys/malloc.h>
#include <sys/mount.h>
@@ -1046,8 +1047,6 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
struct filedesc *fdp = p->p_fd;
struct file *fp;
struct vnode *vp;
- struct vattr vat;
- struct mount *mp;
int cmode;
struct file *nfp;
int type, indx, error;
@@ -1059,8 +1058,8 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
AUDIT_ARG_MODE(mode);
/* XXX: audit dirfd */
/*
- * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR may
- * be specified.
+ * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags
+ * may be specified.
*/
if (flags & O_EXEC) {
if (flags & O_ACCMODE)
@@ -1123,7 +1122,12 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
- fp->f_vnode = vp; /* XXX Does devfs need this? */
+ /*
+ * Store the vnode, for any f_type. Typically, the vnode use
+ * count is decremented by direct call to vn_closefile() for
+ * files that switched type in the cdevsw fdopen() method.
+ */
+ fp->f_vnode = vp;
/*
* If the file wasn't claimed by devfs bind it to the normal
* vnode operations here.
@@ -1135,7 +1139,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
}
VOP_UNLOCK(vp, 0);
- if (flags & (O_EXLOCK | O_SHLOCK)) {
+ if (fp->f_type == DTYPE_VNODE && (flags & (O_EXLOCK | O_SHLOCK)) != 0) {
lf.l_whence = SEEK_SET;
lf.l_start = 0;
lf.l_len = 0;
@@ -1152,18 +1156,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
atomic_set_int(&fp->f_flag, FHASLOCK);
}
if (flags & O_TRUNC) {
- if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
- goto bad;
- VATTR_NULL(&vat);
- vat.va_size = 0;
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-#ifdef MAC
- error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp);
- if (error == 0)
-#endif
- error = VOP_SETATTR(vp, &vat, td->td_ucred);
- VOP_UNLOCK(vp, 0);
- vn_finished_write(mp);
+ error = fo_truncate(fp, 0, td->td_ucred, td);
if (error)
goto bad;
}
@@ -1920,7 +1913,7 @@ lseek(td, uap)
struct file *fp;
struct vnode *vp;
struct vattr vattr;
- off_t offset;
+ off_t offset, size;
int error, noneg;
int vfslocked;
@@ -1951,6 +1944,15 @@ lseek(td, uap)
VOP_UNLOCK(vp, 0);
if (error)
break;
+
+ /*
+ * If the file references a disk device, then fetch
+ * the media size and use that to determine the ending
+ * offset.
+ */
+ if (vattr.va_size == 0 && vp->v_type == VCHR &&
+ fo_ioctl(fp, DIOCGMEDIASIZE, &size, cred, td) == 0)
+ vattr.va_size = size;
if (noneg &&
(vattr.va_size > OFF_MAX ||
(offset > 0 && vattr.va_size > OFF_MAX - offset))) {
@@ -2259,9 +2261,9 @@ cvtstat(st, ost)
ost->st_size = st->st_size;
else
ost->st_size = -2;
- ost->st_atime = st->st_atime;
- ost->st_mtime = st->st_mtime;
- ost->st_ctime = st->st_ctime;
+ ost->st_atim = st->st_atim;
+ ost->st_mtim = st->st_mtim;
+ ost->st_ctim = st->st_ctim;
ost->st_blksize = st->st_blksize;
ost->st_blocks = st->st_blocks;
ost->st_flags = st->st_flags;
@@ -2421,15 +2423,15 @@ cvtnstat(sb, nsb)
nsb->st_uid = sb->st_uid;
nsb->st_gid = sb->st_gid;
nsb->st_rdev = sb->st_rdev;
- nsb->st_atimespec = sb->st_atimespec;
- nsb->st_mtimespec = sb->st_mtimespec;
- nsb->st_ctimespec = sb->st_ctimespec;
+ nsb->st_atim = sb->st_atim;
+ nsb->st_mtim = sb->st_mtim;
+ nsb->st_ctim = sb->st_ctim;
nsb->st_size = sb->st_size;
nsb->st_blocks = sb->st_blocks;
nsb->st_blksize = sb->st_blksize;
nsb->st_flags = sb->st_flags;
nsb->st_gen = sb->st_gen;
- nsb->st_birthtimespec = sb->st_birthtimespec;
+ nsb->st_birthtim = sb->st_birthtim;
}
#ifndef _SYS_SYSPROTO_H_
@@ -4418,6 +4420,10 @@ fhopen(td, uap)
error = EOPNOTSUPP;
goto bad;
}
+ if (vp->v_type != VDIR && fmode & O_DIRECTORY) {
+ error = ENOTDIR;
+ goto bad;
+ }
accmode = 0;
if (fmode & (FWRITE | O_TRUNC)) {
if (vp->v_type == VDIR) {
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index d0b713c..838f8f7 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -200,6 +200,10 @@ restart:
error = EOPNOTSUPP;
goto bad;
}
+ if (vp->v_type != VDIR && fmode & O_DIRECTORY) {
+ error = ENOTDIR;
+ goto bad;
+ }
accmode = 0;
if (fmode & (FWRITE | O_TRUNC)) {
if (vp->v_type == VDIR) {
@@ -778,21 +782,20 @@ vn_stat(vp, sb, active_cred, file_cred, td)
if (vap->va_size > OFF_MAX)
return (EOVERFLOW);
sb->st_size = vap->va_size;
- sb->st_atimespec = vap->va_atime;
- sb->st_mtimespec = vap->va_mtime;
- sb->st_ctimespec = vap->va_ctime;
- sb->st_birthtimespec = vap->va_birthtime;
+ sb->st_atim = vap->va_atime;
+ sb->st_mtim = vap->va_mtime;
+ sb->st_ctim = vap->va_ctime;
+ sb->st_birthtim = vap->va_birthtime;
/*
* According to www.opengroup.org, the meaning of st_blksize is
* "a filesystem-specific preferred I/O block size for this
* object. In some filesystem types, this may vary from file
* to file"
- * Default to PAGE_SIZE after much discussion.
- * XXX: min(PAGE_SIZE, vp->v_bufobj.bo_bsize) may be more correct.
+ * Use miminum/default of PAGE_SIZE (e.g. for VCHR).
*/
- sb->st_blksize = PAGE_SIZE;
+ sb->st_blksize = max(PAGE_SIZE, vap->va_blocksize);
sb->st_flags = vap->va_flags;
if (priv_check(td, PRIV_VFS_GENERATION))
diff --git a/sys/libkern/iconv.c b/sys/libkern/iconv.c
index 7e0d2c0..7700937 100644
--- a/sys/libkern/iconv.c
+++ b/sys/libkern/iconv.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/libkern/iconv_converter_if.m b/sys/libkern/iconv_converter_if.m
index 63e1667..592fa13 100644
--- a/sys/libkern/iconv_converter_if.m
+++ b/sys/libkern/iconv_converter_if.m
@@ -1,5 +1,5 @@
#-
-# Copyright (c) 2000-2001, Boris Popov
+# Copyright (c) 2000-2001 Boris Popov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
# 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 Boris Popov.
-# 4. Neither the name of the author nor the names of any co-contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/libkern/iconv_xlat.c b/sys/libkern/iconv_xlat.c
index 8ab4d6c..c5c2dfd 100644
--- a/sys/libkern/iconv_xlat.c
+++ b/sys/libkern/iconv_xlat.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2000-2001, Boris Popov
+/*-
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/libkern/strcasecmp.c b/sys/libkern/strcasecmp.c
index a058654..a7bba22 100644
--- a/sys/libkern/strcasecmp.c
+++ b/sys/libkern/strcasecmp.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
*
diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c
index da8d181..4367bfb 100644
--- a/sys/mips/atheros/if_arge.c
+++ b/sys/mips/atheros/if_arge.c
@@ -171,7 +171,7 @@ extern uint32_t ar711_base_mac[ETHER_ADDR_LEN];
static struct mtx miibus_mtx;
-MTX_SYSINIT(miibus_mtx, &miibus_mtx, "arge mii lock", MTX_SPIN);
+MTX_SYSINIT(miibus_mtx, &miibus_mtx, "arge mii lock", MTX_DEF);
/*
diff --git a/sys/mips/cavium/asm_octeon.S b/sys/mips/cavium/asm_octeon.S
index d9f79f1..94ac875 100644
--- a/sys/mips/cavium/asm_octeon.S
+++ b/sys/mips/cavium/asm_octeon.S
@@ -1,182 +1,66 @@
-/***********************license start***************
- * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
- * reserved.
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett@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.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * 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.
- *
- * * Neither the name of Cavium Networks nor the names of
- * its contributors may be used to endorse or promote products
- * derived from this software without specific prior written
- * permission.
- *
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
- * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
- * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
- * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
- * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
- * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
- * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
- * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT
- * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- *
- *
- * For any questions regarding licensing please contact marketing@caviumnetworks.com
- *
- ***********************license end**************************************/
-
-/* $FreeBSD$ */
+ * $FreeBSD$
+ */
#include <machine/asm.h>
-#include <machine/cache_r4k.h>
-#include <machine/cpuregs.h>
-#include <machine/param.h>
-#include <machine/pte.h>
-
-#include "assym.s"
-
-
-
-#define CPU_DISABLE_INTERRUPTS(reg, reg2, reg3) \
- mfc0 reg, MIPS_COP_0_STATUS; \
- nop; \
- move reg3, reg; \
- li reg2, ~MIPS_SR_INT_IE; \
- and reg, reg2, reg; \
- mtc0 reg, MIPS_COP_0_STATUS; \
- COP0_SYNC
-
-
-
-#define CPU_ENABLE_INTERRUPTS(reg, reg3) \
- mfc0 reg, MIPS_COP_0_STATUS; \
- nop; \
- or reg, reg, reg3; \
- mtc0 reg, MIPS_COP_0_STATUS; \
- COP0_SYNC
+ .set noreorder
-#define PUSHR(reg) \
- addiu sp,sp,-16 ; \
- sd reg, 8(sp) ; \
- nop ;
-
-#define POPR(reg) \
- ld reg, 8(sp) ; \
- addiu sp,sp,16 ; \
- nop ;
-
-
-
-
+#ifdef SMP
/*
- * octeon_ciu_get_interrupt_reg_addr
- *
- * Given Int-X, En-X combination, return the CIU Interrupt Enable Register addr
- * a0 = ciu Int-X: 0/1
- * a1 = ciu EN-0: 0/1
+ * This function must be implemented in assembly because it is called early
+ * in AP boot without a valid stack.
*/
-LEAF(octeon_ciu_get_interrupt_reg_addr)
- .set noreorder
- .set mips3
-
- beqz a0, ciu_get_interrupt_reg_addr_Int_0
- nop
-
-ciu_get_interrupt_reg_addr_Int_1:
- beqz a1, ciu_get_interrupt_reg_addr_Int_1_En_0
- nop
+LEAF(platform_processor_id)
+ .set push
+ .set mips32r2
+ jr ra
+ rdhwr v0, $0
+ .set pop
+END(platform_processor_id)
-ciu_get_interrupt_reg_addr_Int_1_En1:
- li a0, OCTEON_CIU_ADDR_HI
- dsll32 a0, a0, 0
- nop
- ori a0, OCTEON_CIU_EN1_INT1_LO
- j ciu_get_interrupt_reg_addr_ret
- nop
-
-ciu_get_interrupt_reg_addr_Int_1_En_0:
- li a0, OCTEON_CIU_ADDR_HI
- dsll32 a0, a0, 0
- nop
- ori a0, OCTEON_CIU_EN0_INT1_LO
- j ciu_get_interrupt_reg_addr_ret
- nop
-
-ciu_get_interrupt_reg_addr_Int_0:
- beqz a1, ciu_get_interrupt_reg_addr_Int_0_En_0
- nop
-
-ciu_get_interrupt_reg_addr_Int_0_En_1:
- li a0, OCTEON_CIU_ADDR_HI
- dsll32 a0, a0, 0
- nop
- ori a0, OCTEON_CIU_EN1_INT0_LO
- j ciu_get_interrupt_reg_addr_ret
- nop
-
-ciu_get_interrupt_reg_addr_Int_0_En_0:
- li a0, OCTEON_CIU_ADDR_HI
- dsll32 a0, a0, 0
- nop
- ori a0, OCTEON_CIU_EN0_INT0_LO
-
-
-ciu_get_interrupt_reg_addr_ret:
- j ra
- nop
-
- .set mips0
- .set reorder
-END(octeon_ciu_get_interrupt_reg_addr)
-
-
-
/*
- * octeon_ciu_mask_all_interrupts
- *
- * a0 = ciu Interrupt-X: 0/1
- * a1 = ciu Enable-X: 0/1
+ * Called on APs to wait until they are told to launch.
*/
-LEAF(octeon_ciu_mask_all_interrupts)
- .set noreorder
- .set mips3
+LEAF(octeon_ap_wait)
+ jal platform_processor_id
+ nop
- PUSHR(ra)
- PUSHR(s0)
-
- move t0, a0
- move t1, a1
- li a0, MIPS_SR_INT_IE
- CPU_DISABLE_INTERRUPTS(a2, a1, s0)
- move a0, t0
- move t1, a1
- jal octeon_ciu_get_interrupt_reg_addr
- nop
- ld a2, 0(a0) # Dummy read
- nop
- move a2, zero # Clear all
- sd a2, 0(a0) # Write new Enable bits
- nop
- CPU_ENABLE_INTERRUPTS(a2, s0)
+1: ll t0, octeon_ap_boot
+ bne v0, t0, 1b
+ nop
- POPR(s0)
- POPR(ra)
- j ra # Return
- nop # (bd slot)
+ move t0, zero
+ sc t0, octeon_ap_boot
- .set mips0
- .set reorder
-END(octeon_ciu_mask_all_interrupts)
+ beqz t0, 1b
+ nop
+ j mpentry
+ nop
+END(octeon_ap_wait)
+#endif
diff --git a/sys/mips/cavium/dev/rgmii/octeon_fau.c b/sys/mips/cavium/dev/rgmii/octeon_fau.c
deleted file mode 100644
index fb4c0ad..0000000
--- a/sys/mips/cavium/dev/rgmii/octeon_fau.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/***********************license start***************
- * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
- * reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * 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.
- *
- * * Neither the name of Cavium Networks nor the names of
- * its contributors may be used to endorse or promote products
- * derived from this software without specific prior written
- * permission.
- *
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
- * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
- * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
- * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
- * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
- * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
- * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
- * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT
- * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- *
- *
- * For any questions regarding licensing please contact marketing@caviumnetworks.com
- *
- ***********************license end**************************************/
-
-/*------------------------------------------------------------------
- * octeon_fau.c Fetch & Add Block
- *
- *------------------------------------------------------------------
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <mips/cavium/octeon_pcmap_regs.h>
-#include "octeon_fau.h"
-
-/*
- * oct_fau_init
- *
- * How do we initialize FAU unit. I don't even think we can reset it.
- */
-void octeon_fau_init (void)
-{
-}
-
-
-/*
- * oct_fau_enable
- *
- * Let the Fetch/Add unit roll
- */
-void octeon_fau_enable (void)
-{
-}
-
-
-/*
- * oct_fau_disable
- *
- * disable fau
- *
- * Don't know if we can even do that.
- */
-void octeon_fau_disable (void)
-{
-}
diff --git a/sys/mips/cavium/dev/rgmii/octeon_fau.h b/sys/mips/cavium/dev/rgmii/octeon_fau.h
index 1683ff5..acf5132 100644
--- a/sys/mips/cavium/dev/rgmii/octeon_fau.h
+++ b/sys/mips/cavium/dev/rgmii/octeon_fau.h
@@ -217,9 +217,4 @@ static inline void octeon_fau_atomic_add64 (octeon_fau_reg_64_t reg, int64_t val
}
-extern void octeon_fau_init(void);
-extern void octeon_fau_enable(void);
-extern void octeon_fau_disable(void);
-
-
#endif /* ___OCTEON_FAU__H___ */
diff --git a/sys/mips/cavium/dev/rgmii/octeon_rgmx.c b/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
index 53365cc..5b84af5 100644
--- a/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
+++ b/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
@@ -136,7 +136,6 @@ struct rgmx_softc_dev {
u_int idx;
u_char ieee[6];
- char const * typestr; /* printable name of the interface. */
u_short txb_size; /* size of TX buffer, in bytes */
/* Transmission buffer management. */
@@ -182,7 +181,6 @@ static u_int get_rgmx_port_ordinal(u_int port);
static void octeon_rgmx_set_mac(u_int port);
static void octeon_rgmx_init_sc(struct rgmx_softc_dev *sc, device_t dev, u_int port, u_int num_devices);
static int octeon_rgmx_init_ifnet(struct rgmx_softc_dev *sc);
-static void octeon_rgmx_mark_ready(struct rgmx_softc_dev *sc);
static void octeon_rgmx_stop(struct rgmx_softc_dev *sc);
static void octeon_rgmx_config_speed(u_int port, u_int);
#ifdef DEBUG_RGMX_DUMP
@@ -211,6 +209,7 @@ static int octeon_rgmx_intr(void *arg);
/* Standard driver entry points. These can be static. */
static void octeon_rgmx_init (void *);
//static driver_intr_t rgmx_intr;
+static void octeon_rgmx_config_cam (struct ifnet *);
static int octeon_rgmx_ioctl (struct ifnet *, u_long, caddr_t);
static void octeon_rgmx_output_start (struct ifnet *);
static void octeon_rgmx_output_start_locked (struct ifnet *);
@@ -349,8 +348,6 @@ static int octeon_rgmx_init_ifnet (struct rgmx_softc_dev *sc)
ifmedia_set(&sc->media, bit2media[0]);
ether_ifattach(sc->ifp, sc->ieee);
- /* Print additional info when attached. */
- device_printf(sc->sc_dev, "type %s, full duplex\n", sc->typestr);
return (0);
}
@@ -447,12 +444,6 @@ static int rgmii_attach (device_t dev)
device_printf(dev, " ifinit failed for rgmx port %u\n", port);
return (ENOSPC);
}
-/*
- * Don't call octeon_rgmx_mark_ready()
- * ifnet will call it indirectly via octeon_rgmx_init()
- *
- * octeon_rgmx_mark_ready(sc);
- */
num_devices++;
}
}
@@ -1024,10 +1015,9 @@ static u_int octeon_rgmx_pko_xmit_packet (struct rgmx_softc_dev *sc, void *out_b
* 3 words or less are left. We write our 2nd word now and then put in a chain link
* to new PKO cmd buf.
*/
- void *pko_cmd_buf = octeon_fpa_alloc(OCTEON_FPA_TX_CMDBUF_POOL);
- uint64_t phys_cmd_buf;
+ uint64_t phys_cmd_buf = octeon_fpa_alloc_phys(OCTEON_FPA_TX_CMDBUF_POOL);
- if (!pko_cmd_buf) {
+ if (!phys_cmd_buf) {
/*
* FPA pool for xmit-buffer-commands is empty.
*/
@@ -1035,7 +1025,6 @@ static u_int octeon_rgmx_pko_xmit_packet (struct rgmx_softc_dev *sc, void *out_b
octeon_spinlock_unlock(&(sc->outq_ptr[queue].lock));
return (0);
}
- phys_cmd_buf = OCTEON_PTR2PHYS(pko_cmd_buf);
xmit_cmd_ptr[1] = pko_pkt_word.word64;
xmit_cmd_ptr[2] = phys_cmd_buf;
@@ -1235,6 +1224,8 @@ static void octeon_rgmx_output_start_locked (struct ifnet *ifp)
for (ii = 0; ii < len; ii++) printf(" %X", dc[ii]); printf("\n");
#endif
+ ETHER_BPF_MTAP(ifp, m);
+
IF_ENQUEUE(&sc->tx_pending_queue, m);
/*
@@ -1490,7 +1481,7 @@ static void octeon_config_hw_units_post_ports (void)
oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64);
#endif
- ciu_enable_interrupts(OCTEON_CORE_ID, OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX,
+ ciu_enable_interrupts(PCPU_GET(cpuid), OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX,
(OCTEON_POW_RX_GROUP_MASK |
CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)), CIU_MIPS_IP2);
@@ -1648,9 +1639,106 @@ static int octeon_rgmx_medchange (struct ifnet *ifp)
static void octeon_rgmx_medstat (struct ifnet *ifp, struct ifmediareq *ifm)
{
- /*
- * No support for Media Status callback
- */
+ struct rgmx_softc_dev *sc = ifp->if_softc;
+ octeon_rgmx_rxx_rx_inbnd_t link_status;
+
+ octeon_rgmx_config_speed(sc->port, 1);
+
+ RGMX_LOCK(sc);
+
+ ifm->ifm_status = IFM_AVALID;
+ ifm->ifm_active = IFM_ETHER;
+
+ /*
+ * Parse link status.
+ */
+ link_status.word64 = sc->link_status;
+
+ if (!link_status.bits.status) {
+ RGMX_UNLOCK(sc);
+ return;
+ }
+
+ ifm->ifm_status |= IFM_ACTIVE;
+
+ switch (link_status.bits.speed) {
+ case 0:
+ ifm->ifm_active |= IFM_10_T;
+ break;
+ case 1:
+ ifm->ifm_active |= IFM_100_TX;
+ break;
+ case 2:
+ ifm->ifm_active |= IFM_1000_T;;
+ break;
+ default:
+ /* Unknown! */
+ break;
+ }
+
+ /*
+ * Check duplex.
+ */
+ if (link_status.bits.duplex == 1)
+ ifm->ifm_active |= IFM_FDX;
+ else
+ ifm->ifm_active |= IFM_HDX;
+
+ RGMX_UNLOCK(sc);
+}
+
+static void octeon_rgmx_config_cam(struct ifnet *ifp)
+{
+ struct rgmx_softc_dev *sc = ifp->if_softc;
+ u_int port = sc->port;
+ int index = INDEX(port);
+ int iface = INTERFACE(port);
+ u_int last_enabled;
+ uint64_t adr_ctl;
+
+ last_enabled = octeon_rgmx_stop_port(port);
+
+ adr_ctl = oct_read64(OCTEON_RGMX_RXX_ADR_CTL(index, iface));
+
+ /*
+ * Always accept broadcast traffic.
+ */
+ if ((adr_ctl & OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST) == 0)
+ adr_ctl |= OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST;
+
+ /*
+ * Accept all multicast in all multicast mode and in
+ * promiscuous mode.
+ *
+ * XXX Since we don't handle programming the CAM for
+ * multicast filtering, always accept all multicast.
+ */
+ adr_ctl &= ~OCTEON_RGMX_ADRCTL_REJECT_ALL_MULTICAST;
+ adr_ctl |= OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST;
+
+ /*
+ * In promiscuous mode, the CAM is shut off, so reject everything.
+ * Otherwise, filter using the CAM.
+ */
+ if ((ifp->if_flags & IFF_PROMISC) != 0) {
+ adr_ctl &= ~OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC;
+ adr_ctl |= OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC;
+ } else {
+ adr_ctl &= ~OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC;
+ adr_ctl |= OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC;
+ }
+
+ oct_write64(OCTEON_RGMX_RXX_ADR_CTL(index, iface), adr_ctl);
+
+ /*
+ * If in promiscuous mode, disable the CAM.
+ */
+ if ((ifp->if_flags & IFF_PROMISC) != 0)
+ oct_write64(OCTEON_RGMX_RXX_ADR_CAM_EN(index, iface), 0);
+ else
+ oct_write64(OCTEON_RGMX_RXX_ADR_CAM_EN(index, iface), 1);
+
+ if (last_enabled) octeon_rgmx_start_port(port);
}
static int octeon_rgmx_ioctl (struct ifnet * ifp, u_long command, caddr_t data)
@@ -1671,28 +1759,21 @@ static int octeon_rgmx_ioctl (struct ifnet * ifp, u_long command, caddr_t data)
* "stopped", reflecting the UP flag.
*/
if (ifp->if_flags & IFF_UP) {
-
-
/*
* New state is IFF_UP
* Restart or Start now, if driver is not running currently.
*/
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- printf(" SIOCSTIFFLAGS UP/Not-running\n"); break;
octeon_rgmx_init(sc);
- } else {
- printf(" SIOCSTIFFLAGS UP/Running\n"); break;
}
+ octeon_rgmx_config_cam(ifp);
} else {
/*
* New state is IFF_DOWN.
* Stop & shut it down now, if driver is running currently.
*/
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
- printf(" SIOCSTIFFLAGS Down/Running\n"); break;
octeon_rgmx_stop(sc);
- } else {
- printf(" SIOCSTIFFLAGS Down/Not-Running\n"); break;
}
}
break;
@@ -1734,17 +1815,9 @@ static int octeon_rgmx_ioctl (struct ifnet * ifp, u_long command, caddr_t data)
return (error);
}
-
-
-
-/*
- * octeon_rgmx_mark_ready
- *
- * Initialize the rgmx driver for this instance
- * Initialize device.
- */
-static void octeon_rgmx_mark_ready (struct rgmx_softc_dev *sc)
+static void octeon_rgmx_init (void *xsc)
{
+ struct rgmx_softc_dev *sc = xsc;
/* Enable interrupts. */
/* For RGMX they are already enabled earlier */
@@ -1763,21 +1836,9 @@ static void octeon_rgmx_mark_ready (struct rgmx_softc_dev *sc)
/* Kick start the output */
/* Hopefully PKO is running and will pick up packets via the timer or receive loop */
-}
-
-static void octeon_rgmx_init (void *xsc)
-{
-
- /*
- * Called mostly from ifnet interface ifp->if_init();
- * I think we can anchor most of our iniialization here and
- * not do it in different places from driver_attach().
- */
- /*
- * For now, we only mark the interface ready
- */
- octeon_rgmx_mark_ready((struct rgmx_softc_dev *) xsc);
+ /* Set link status. */
+ octeon_rgmx_config_speed(sc->port, 1);
}
@@ -1792,7 +1853,6 @@ static void octeon_rgmx_config_speed (u_int port, u_int report_link)
uint64_t val64_tx_clk, val64_tx_slot, val64_tx_burst;
u_int last_enabled;
-
sc = get_rgmx_softc(port);
if (!sc) {
printf(" config_speed didn't find sc int:%u port:%u", iface, port);
@@ -1804,79 +1864,96 @@ static void octeon_rgmx_config_speed (u_int port, u_int report_link)
*/
link_status.word64 = oct_read64(OCTEON_RGMX_RXX_RX_INBND(index, iface));
+ RGMX_LOCK(sc);
+
/*
* Compre to prev known state. If same then nothing to do.
*/
if (link_status.word64 == sc->link_status) {
+ RGMX_UNLOCK(sc);
return;
}
-
- RGMX_LOCK(sc);
-
old_link_status.word64 = sc->link_status;
- sc->link_status = link_status.word64;
-
- last_enabled = octeon_rgmx_stop_port(port);
-
- gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface));
-
- /*
- * Duplex
- */
- gmx_cfg.bits.duplex = 1;
-
- switch (link_status.bits.speed) {
- case 0: /* 10Mbps */
- gmx_cfg.bits.speed = 0;
- gmx_cfg.bits.slottime = 0;
- val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0;
- break;
- case 1: /* 100Mbps */
- gmx_cfg.bits.speed = 0;
- gmx_cfg.bits.slottime = 0;
- val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0;
- break;
-
- case 2: /* 1Gbps */
- gmx_cfg.bits.speed = 1;
- gmx_cfg.bits.slottime = 1;
- val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
- break;
-
- case 3: /* ?? */
- default:
- gmx_cfg.bits.speed = 1;
- gmx_cfg.bits.slottime = 1;
- val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
- break;
- }
+ /*
+ * Compare to previous state modulo link status. If only link
+ * status is different, we don't need to change media.
+ */
+ if (old_link_status.bits.duplex != link_status.bits.duplex ||
+ old_link_status.bits.speed != link_status.bits.speed) {
+ last_enabled = octeon_rgmx_stop_port(port);
+
+ gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface));
- oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk);
- oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot);
- oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst);
+ /*
+ * Duplex
+ * XXX Set based on link_status.bits.duplex?
+ */
+ gmx_cfg.bits.duplex = 1;
+
+ switch (link_status.bits.speed) {
+ case 0: /* 10Mbps */
+ gmx_cfg.bits.speed = 0;
+ gmx_cfg.bits.slottime = 0;
+ val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0;
+ break;
+
+ case 1: /* 100Mbps */
+ gmx_cfg.bits.speed = 0;
+ gmx_cfg.bits.slottime = 0;
+ val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0;
+ break;
+
+ case 2: /* 1Gbps */
+ gmx_cfg.bits.speed = 1;
+ gmx_cfg.bits.slottime = 1;
+ val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
+ break;
+
+ case 3: /* ?? */
+ default:
+ gmx_cfg.bits.speed = 1;
+ gmx_cfg.bits.slottime = 1;
+ val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
+ break;
+ }
- oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64);
+ oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk);
+ oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot);
+ oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst);
+
+ oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64);
+
+ if (last_enabled) octeon_rgmx_start_port(port);
+ }
- if (last_enabled) octeon_rgmx_start_port(port);
+ /*
+ * Now check and possibly change link status.
+ */
+ if (link_status.bits.status != old_link_status.bits.status) {
+ if (report_link) {
+ if (link_status.bits.status) {
+ if_link_state_change(sc->ifp, LINK_STATE_UP);
+ } else {
+ if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+ }
+ }
+ }
- if (link_status.bits.status != old_link_status.bits.status) {
+ if (report_link) {
+ sc->link_status = link_status.word64;
+ } else {
+ /*
+ * We can't update link status proper since we can't
+ * change it in the interface, so keep the old link
+ * status intact but note the current speed and duplex
+ * settings.
+ */
+ link_status.bits.status = old_link_status.bits.status;
+ sc->link_status = link_status.word64;
+ }
-//#define DEBUG_LINESTATUS
- if (link_status.bits.status) {
-#ifdef DEBUG_LINESTATUS
- printf(" %u/%u: Interface is now alive\n", iface, port);
-#endif
- if (report_link) if_link_state_change(sc->ifp, LINK_STATE_UP);
- } else {
-#ifdef DEBUG_LINESTATUS
- printf(" %u/%u: Interface went down\n", iface, port);
-#endif
- if (report_link) if_link_state_change(sc->ifp, LINK_STATE_DOWN);
- }
- }
RGMX_UNLOCK(sc);
-
}
@@ -2096,7 +2173,6 @@ static void octeon_config_rgmii_port (u_int port)
gmx_cfg.bits.en = 1;
oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64);
-
octeon_rgmx_config_speed(port, 0);
oct_write64(OCTEON_RGMX_TXX_THRESH(index, iface), 32);
@@ -2181,7 +2257,7 @@ static int octeon_has_4ports (void)
u_int chipid;
int retcode = 1;
- chipid = octeon_get_chipid() & 0xffffff00;
+ chipid = octeon_get_chipid();
switch (chipid) {
case OCTEON_CN31XX_CHIP:
diff --git a/sys/mips/cavium/files.octeon1 b/sys/mips/cavium/files.octeon1
index c10988c..4cf31f8 100644
--- a/sys/mips/cavium/files.octeon1
+++ b/sys/mips/cavium/files.octeon1
@@ -1,8 +1,7 @@
# $FreeBSD$
# Octeon Support Files
#
-mips/mips/mp_machdep.c optional smp
-mips/cavium/dev/rgmii/octeon_fau.c optional rgmii
+mips/cavium/asm_octeon.S optional smp
mips/cavium/dev/rgmii/octeon_fpa.c optional rgmii
mips/cavium/dev/rgmii/octeon_ipd.c optional rgmii
mips/cavium/dev/rgmii/octeon_pko.c optional rgmii
@@ -10,6 +9,7 @@ mips/cavium/dev/rgmii/octeon_rgmx.c optional rgmii
mips/cavium/obio.c optional uart
mips/cavium/octeon_ebt3000_cf.c optional cf
mips/cavium/octeon_machdep.c standard
+mips/cavium/octeon_mp.c optional smp
mips/cavium/uart_bus_octeonusart.c optional uart
mips/cavium/uart_cpu_octeonusart.c optional uart
mips/cavium/uart_dev_oct16550.c optional uart
diff --git a/sys/mips/cavium/octeon_ebt3000_cf.c b/sys/mips/cavium/octeon_ebt3000_cf.c
index 10fb313..4298b75 100644
--- a/sys/mips/cavium/octeon_ebt3000_cf.c
+++ b/sys/mips/cavium/octeon_ebt3000_cf.c
@@ -89,6 +89,7 @@ __FBSDID("$FreeBSD$");
/* Status Register */
#define STATUS_BSY 0x80 /* Drive is busy */
#define STATUS_RDY 0x40 /* Drive is ready */
+#define STATUS_DF 0x20 /* Device fault */
#define STATUS_DRQ 0x08 /* Data can be transferred */
/* Miscelaneous */
@@ -153,11 +154,11 @@ static int cf_attach(device_t);
static int cf_attach_geom(void *, int);
/* ATA methods */
-static void cf_cmd_identify(void);
-static void cf_cmd_write(uint32_t, uint32_t, void *);
-static void cf_cmd_read(uint32_t, uint32_t, void *);
-static void cf_wait_busy(void);
-static void cf_send_cmd(uint32_t, uint8_t);
+static int cf_cmd_identify(void);
+static int cf_cmd_write(uint32_t, uint32_t, void *);
+static int cf_cmd_read(uint32_t, uint32_t, void *);
+static int cf_wait_busy(void);
+static int cf_send_cmd(uint32_t, uint8_t);
static void cf_attach_geom_proxy(void *arg, int flag);
/* Miscelenous */
@@ -183,6 +184,8 @@ static int cf_access (struct g_provider *pp, int r, int w, int e)
* ------------------------------------------------------------------- */
static void cf_start (struct bio *bp)
{
+ int error;
+
/*
* Handle actual I/O requests. The request is passed down through
* the bio struct.
@@ -200,12 +203,19 @@ static void cf_start (struct bio *bp)
if ((bp->bio_cmd & (BIO_READ | BIO_WRITE))) {
if (bp->bio_cmd & BIO_READ) {
- cf_cmd_read(bp->bio_length / drive_param.sector_size,
- bp->bio_offset / drive_param.sector_size, bp->bio_data);
-
+ error = cf_cmd_read(bp->bio_length / drive_param.sector_size,
+ bp->bio_offset / drive_param.sector_size, bp->bio_data);
} else if (bp->bio_cmd & BIO_WRITE) {
- cf_cmd_write(bp->bio_length / drive_param.sector_size,
- bp->bio_offset/drive_param.sector_size, bp->bio_data);
+ error = cf_cmd_write(bp->bio_length / drive_param.sector_size,
+ bp->bio_offset/drive_param.sector_size, bp->bio_data);
+ } else {
+ printf("%s: unrecognized bio_cmd %x.\n", __func__, bp->bio_cmd);
+ error = ENOTSUP;
+ }
+
+ if (error != 0) {
+ g_io_deliver(bp, error);
+ return;
}
bp->bio_resid = 0;
@@ -227,12 +237,13 @@ static int cf_ioctl (struct g_provider *pp, u_long cmd, void *data, int fflag, s
*
* Read nr_sectors from the device starting from start_sector.
*/
-static void cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf)
+static int cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf)
{
unsigned long lba;
uint32_t count;
uint16_t *ptr_16;
uint8_t *ptr_8;
+ int error;
//#define OCTEON_VISUAL_CF_0 1
#ifdef OCTEON_VISUAL_CF_0
@@ -244,8 +255,11 @@ static void cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf)
while (nr_sectors--) {
-
- cf_send_cmd(lba, CMD_READ_SECTOR);
+ error = cf_send_cmd(lba, CMD_READ_SECTOR);
+ if (error != 0) {
+ printf("%s: cf_send_cmd(CMD_READ_SECTOR) failed: %d\n", __func__, error);
+ return (error);
+ }
if (bus_width == 8) {
volatile uint8_t *task_file = (volatile uint8_t*)base_addr;
@@ -270,6 +284,7 @@ static void cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf)
#ifdef OCTEON_VISUAL_CF_0
octeon_led_write_char(0, ' ');
#endif
+ return (0);
}
@@ -279,12 +294,13 @@ static void cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf)
*
* Write nr_sectors to the device starting from start_sector.
*/
-static void cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf)
+static int cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf)
{
uint32_t lba;
uint32_t count;
uint16_t *ptr_16;
uint8_t *ptr_8;
+ int error;
//#define OCTEON_VISUAL_CF_1 1
#ifdef OCTEON_VISUAL_CF_1
@@ -295,8 +311,11 @@ static void cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf)
ptr_16 = (uint16_t*)buf;
while (nr_sectors--) {
-
- cf_send_cmd(lba, CMD_WRITE_SECTOR);
+ error = cf_send_cmd(lba, CMD_WRITE_SECTOR);
+ if (error != 0) {
+ printf("%s: cf_send_cmd(CMD_WRITE_SECTOR) failed: %d\n", __func__, error);
+ return (error);
+ }
if (bus_width == 8) {
volatile uint8_t *task_file;
@@ -324,6 +343,7 @@ static void cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf)
#ifdef OCTEON_VISUAL_CF_1
octeon_led_write_char(1, ' ');
#endif
+ return (0);
}
@@ -335,10 +355,11 @@ static void cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf)
* it in the drive_param structure
*
*/
-static void cf_cmd_identify (void)
+static int cf_cmd_identify (void)
{
int count;
uint8_t status;
+ int error;
if (bus_width == 8) {
volatile uint8_t *task_file;
@@ -356,11 +377,11 @@ static void cf_cmd_identify (void)
task_file[TF_DRV_HEAD] = 0;
task_file[TF_COMMAND] = CMD_IDENTIFY;
- cf_wait_busy();
-
- for (count = 0; count < SECTOR_SIZE; count++)
- drive_param.u.buf[count] = task_file[TF_DATA];
-
+ error = cf_wait_busy();
+ if (error == 0) {
+ for (count = 0; count < SECTOR_SIZE; count++)
+ drive_param.u.buf[count] = task_file[TF_DATA];
+ }
} else {
volatile uint16_t *task_file;
@@ -374,17 +395,22 @@ static void cf_cmd_identify (void)
task_file[TF_CYL_LSB/2] = 0; /* this includes TF_CYL_MSB */
task_file[TF_DRV_HEAD/2] = 0 | (CMD_IDENTIFY<<8); /* this includes TF_COMMAND */
- cf_wait_busy();
-
- for (count = 0; count < SECTOR_SIZE; count+=2) {
- uint16_t temp;
- temp = task_file[TF_DATA];
-
- /* endianess will be swapped below */
- drive_param.u.buf[count] = (temp & 0xff);
- drive_param.u.buf[count+1] = (temp & 0xff00)>>8;
+ error = cf_wait_busy();
+ if (error == 0) {
+ for (count = 0; count < SECTOR_SIZE; count+=2) {
+ uint16_t temp;
+ temp = task_file[TF_DATA];
+
+ /* endianess will be swapped below */
+ drive_param.u.buf[count] = (temp & 0xff);
+ drive_param.u.buf[count+1] = (temp & 0xff00)>>8;
+ }
}
}
+ if (error != 0) {
+ printf("%s: identify failed: %d\n", __func__, error);
+ return (error);
+ }
cf_swap_ascii(drive_param.u.driveid.model, drive_param.model);
@@ -394,6 +420,7 @@ static void cf_cmd_identify (void)
drive_param.sec_track = SWAP_SHORT (drive_param.u.driveid.cur_sectors);
drive_param.nr_sectors = SWAP_LONG (drive_param.u.driveid.lba_capacity);
+ return (0);
}
@@ -404,7 +431,7 @@ static void cf_cmd_identify (void)
* Send command to read/write one sector specified by lba.
*
*/
-static void cf_send_cmd (uint32_t lba, uint8_t cmd)
+static int cf_send_cmd (uint32_t lba, uint8_t cmd)
{
uint8_t status;
@@ -439,7 +466,7 @@ static void cf_send_cmd (uint32_t lba, uint8_t cmd)
}
- cf_wait_busy();
+ return (cf_wait_busy());
}
/* ------------------------------------------------------------------- *
@@ -448,12 +475,16 @@ static void cf_send_cmd (uint32_t lba, uint8_t cmd)
*
* Wait until the drive finishes a given command and data is
* ready to be transferred. This is done by repeatedly checking
- * the BSY and DRQ bits of the status register. When the controller
- * is ready for data transfer, it clears the BSY bit and sets the
- * DRQ bit.
+ * the BSY bit of the status register. When the controller is ready for
+ * data transfer, it clears the BSY bit and sets the DRQ bit.
+ *
+ * If the DF bit is ever set, we return error.
*
+ * This code originally spun on DRQ. If that behavior turns out to be
+ * necessary, a flag can be added or this function can be called
+ * repeatedly as long as it is returning ENXIO.
*/
-static void cf_wait_busy (void)
+static int cf_wait_busy (void)
{
uint8_t status;
@@ -469,7 +500,11 @@ static void cf_wait_busy (void)
task_file = (volatile uint8_t *)base_addr;
status = task_file[TF_STATUS];
- while ((status & STATUS_BSY) == STATUS_BSY || (status & STATUS_DRQ) != STATUS_DRQ ) {
+ while ((status & STATUS_BSY) == STATUS_BSY) {
+ if ((status & STATUS_DF) != 0) {
+ printf("%s: device fault (status=%x)\n", __func__, status);
+ return (EIO);
+ }
DELAY(WAIT_DELAY);
status = task_file[TF_STATUS];
}
@@ -478,15 +513,24 @@ static void cf_wait_busy (void)
task_file = (volatile uint16_t *)base_addr;
status = task_file[TF_STATUS/2]>>8;
- while ((status & STATUS_BSY) == STATUS_BSY || (status & STATUS_DRQ) != STATUS_DRQ ) {
+ while ((status & STATUS_BSY) == STATUS_BSY) {
+ if ((status & STATUS_DF) != 0) {
+ printf("%s: device fault (status=%x)\n", __func__, status);
+ return (EIO);
+ }
DELAY(WAIT_DELAY);
status = (uint8_t)(task_file[TF_STATUS/2]>>8);
}
}
+ if ((status & STATUS_DRQ) == 0) {
+ printf("%s: device not ready (status=%x)\n", __func__, status);
+ return (ENXIO);
+ }
#ifdef OCTEON_VISUAL_CF_2
octeon_led_write_char(2, ' ');
#endif
+ return (0);
}
/* ------------------------------------------------------------------- *
@@ -522,9 +566,7 @@ static int cf_probe (device_t dev)
device_set_desc(dev, "Octeon Compact Flash Driver");
- cf_cmd_identify();
-
- return (0);
+ return (cf_cmd_identify());
}
/* ------------------------------------------------------------------- *
@@ -543,7 +585,6 @@ static void cf_identify (driver_t *drv, device_t parent)
int count = 0;
octeon_mio_boot_reg_cfgx_t cfg;
-
if (!octeon_board_real())
return;
diff --git a/sys/mips/cavium/octeon_machdep.c b/sys/mips/cavium/octeon_machdep.c
index e3f2fbd..d5df4b4 100644
--- a/sys/mips/cavium/octeon_machdep.c
+++ b/sys/mips/cavium/octeon_machdep.c
@@ -86,16 +86,6 @@ static void octeon_boot_params_init(register_t ptr);
static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx);
static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx);
-static __inline void
-mips_wr_ebase(u_int32_t a0)
-{
- __asm __volatile("mtc0 %[a0], $15, 1 ;"
- :
- : [a0] "r"(a0));
-
- mips_barrier();
-}
-
void
platform_cpu_init()
{
@@ -111,25 +101,6 @@ platform_reset(void)
oct_write64(OCTEON_CIU_SOFT_RST, 1);
}
-
-static inline uint32_t
-octeon_disable_interrupts(void)
-{
- uint32_t status_bits;
-
- status_bits = mips_rd_status();
- mips_wr_status(status_bits & ~MIPS_SR_INT_IE);
- return (status_bits);
-}
-
-
-static inline void
-octeon_set_interrupts(uint32_t status_bits)
-{
- mips_wr_status(status_bits);
-}
-
-
void
octeon_led_write_char(int char_position, char val)
{
@@ -203,82 +174,6 @@ octeon_led_run_wheel(int *prog_count, int led_position)
*prog_count &= 0x7;
}
-#define LSR_DATAREADY 0x01 /* Data ready */
-#define LSR_THRE 0x20 /* Transmit holding register empty */
-#define LSR_TEMT 0x40 /* Transmitter Empty. THR, TSR & FIFO */
-#define USR_TXFIFO_NOTFULL 0x02 /* Uart TX FIFO Not full */
-
-/*
- * octeon_uart_write_byte
- *
- * Put out a single byte off of uart port.
- */
-
-void
-octeon_uart_write_byte(int uart_index, uint8_t ch)
-{
- uint64_t val, val2;
- if (uart_index < 0 || uart_index > 1)
- return;
-
- while (1) {
- val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
- val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400));
- if ((((uint8_t) val) & LSR_THRE) ||
- (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
- break;
- }
- }
-
- /* Write the byte */
- oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch);
-
- /* Force Flush the IOBus */
- oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-}
-
-
-void
-octeon_uart_write_byte0(uint8_t ch)
-{
- uint64_t val, val2;
-
- while (1) {
- val = oct_read64(OCTEON_MIO_UART0_LSR);
- val2 = oct_read64(OCTEON_MIO_UART0_USR);
- if ((((uint8_t) val) & LSR_THRE) ||
- (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
- break;
- }
- }
-
- /* Write the byte */
- oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch);
-
- /* Force Flush the IOBus */
- oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-}
-
-/*
- * octeon_uart_write_string
- *
- */
-void
-octeon_uart_write_string(int uart_index, const char *str)
-{
- /* Just loop writing one byte at a time */
-
- while (*str) {
- octeon_uart_write_byte(uart_index, *str);
- if (*str == '\n') {
- octeon_uart_write_byte(uart_index, '\r');
- }
- str++;
- }
-}
-
-static char wstr[30];
-
void
octeon_led_write_hex(uint32_t wl)
{
@@ -289,44 +184,6 @@ octeon_led_write_hex(uint32_t wl)
}
-void octeon_uart_write_hex2(uint32_t wl, uint32_t wh)
-{
- sprintf(wstr, "0x%X-0x%X ", wh, wl);
- octeon_uart_write_string(0, wstr);
-}
-
-void
-octeon_uart_write_hex(uint32_t wl)
-{
- sprintf(wstr, " 0x%X ", wl);
- octeon_uart_write_string(0, wstr);
-}
-
-/*
- * octeon_wait_uart_flush
- */
-void
-octeon_wait_uart_flush(int uart_index, uint8_t ch)
-{
- uint64_t val;
- int64_t val3;
- uint32_t cpu_status_bits;
-
- if (uart_index < 0 || uart_index > 1)
- return;
-
- cpu_status_bits = octeon_disable_interrupts();
- /* Force Flush the IOBus */
- oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
- for (val3 = 0xfffffffff; val3 > 0; val3--) {
- val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
- if (((uint8_t) val) & LSR_TEMT)
- break;
- }
- octeon_set_interrupts(cpu_status_bits);
-}
-
-
/*
* octeon_debug_symbol
*
@@ -450,17 +307,17 @@ ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip)
/* XXX kasserts? */
if (enx < CIU_EN_0 || enx > CIU_EN_1) {
printf("%s: invalid enx value %d, should be %d or %d\n",
- __FUNCTION__, enx, CIU_EN_0, CIU_EN_1);
+ __func__, enx, CIU_EN_0, CIU_EN_1);
return 0;
}
if (intx < CIU_INT_0 || intx > CIU_INT_1) {
printf("%s: invalid intx value %d, should be %d or %d\n",
- __FUNCTION__, enx, CIU_INT_0, CIU_INT_1);
+ __func__, enx, CIU_INT_0, CIU_INT_1);
return 0;
}
if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) {
printf("%s: invalid ciu_ip value %d, should be %d or %d\n",
- __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3);
+ __func__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3);
return 0;
}
@@ -517,7 +374,7 @@ ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits)
core_num, intx, enx, write_bits);
#endif
- cpu_status_bits = octeon_disable_interrupts();
+ cpu_status_bits = intr_disable();
ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx);
@@ -535,7 +392,7 @@ ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits)
printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr));
#endif
- octeon_set_interrupts(cpu_status_bits);
+ intr_restore(cpu_status_bits);
}
/*
@@ -550,7 +407,7 @@ ciu_disable_intr(int core_num, int intx, int enx)
if (core_num == CIU_THIS_CORE)
core_num = octeon_get_core_num();
- cpu_status_bits = octeon_disable_interrupts();
+ cpu_status_bits = intr_disable();
ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
@@ -559,7 +416,7 @@ ciu_disable_intr(int core_num, int intx, int enx)
oct_write64(ciu_intr_reg_addr, 0LL);
oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */
- octeon_set_interrupts(cpu_status_bits);
+ intr_restore(cpu_status_bits);
}
void
@@ -580,7 +437,7 @@ ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip)
#endif
if (!ciu_intr_reg_addr) {
- printf("Bad call to %s\n", __FUNCTION__);
+ printf("Bad call to %s\n", __func__);
while(1);
return;
}
@@ -612,7 +469,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx,
core_num, intx, enx, ciu_ip, set_these_interrupt_bits);
#endif
- cpu_status_bits = octeon_disable_interrupts();
+ cpu_status_bits = intr_disable();
#ifndef OCTEON_SMP_1
ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
@@ -621,7 +478,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx,
#endif
if (!ciu_intr_reg_addr) {
- printf("Bad call to %s\n", __FUNCTION__);
+ printf("Bad call to %s\n", __func__);
while(1);
return; /* XXX */
}
@@ -634,7 +491,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx,
#endif
ciu_intr_bits |= set_these_interrupt_bits;
oct_write64(ciu_intr_reg_addr, ciu_intr_bits);
-#ifdef OCTEON_SMP
+#ifdef SMP
mips_wbflush();
#endif
oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */
@@ -644,7 +501,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx,
(uint64_t)oct_read64(ciu_intr_reg_addr));
#endif
- octeon_set_interrupts(cpu_status_bits);
+ intr_restore(cpu_status_bits);
}
unsigned long
@@ -659,12 +516,8 @@ octeon_memory_init(void)
uint32_t realmem_bytes;
if (octeon_board_real()) {
- printf("octeon_dram == %jx\n", (intmax_t)octeon_dram);
- printf("reduced to ram: %u MB", (uint32_t)octeon_dram >> 20);
-
realmem_bytes = (octeon_dram - PAGE_SIZE);
realmem_bytes &= ~(PAGE_SIZE - 1);
- printf("Real memory bytes is %x\n", realmem_bytes);
} else {
/* Simulator we limit to 96 meg */
realmem_bytes = (96 << 20);
@@ -678,8 +531,6 @@ octeon_memory_init(void)
phys_avail[1] = realmem_bytes;
realmem_bytes -= OCTEON_DRAM_FIRST_256_END;
realmem_bytes &= ~(PAGE_SIZE - 1);
- printf("phys_avail[0] = %#lx phys_avail[1] = %#lx\n",
- (long)phys_avail[0], (long)phys_avail[1]);
} else {
/* Simulator gets 96Meg period. */
phys_avail[1] = (96 << 20);
@@ -705,23 +556,14 @@ octeon_memory_init(void)
realmem_bytes &= ~(PAGE_SIZE - 1);
/* Now map the rest of the memory */
phys_avail[2] = 0x20000000;
- printf("realmem_bytes is now at %x\n", realmem_bytes);
phys_avail[3] = ((uint32_t) 0x20000000 + realmem_bytes);
- printf("Next block of memory goes from %#lx to %#lx\n",
- (long)phys_avail[2], (long)phys_avail[3]);
physmem += btoc(phys_avail[3] - phys_avail[2]);
- } else {
- printf("realmem_bytes is %d\n", realmem_bytes);
}
realmem = physmem;
printf("Total DRAM Size %#X\n", (uint32_t) octeon_dram);
printf("Bank 0 = %#08lX -> %#08lX\n", (long)phys_avail[0], (long)phys_avail[1]);
printf("Bank 1 = %#08lX -> %#08lX\n", (long)phys_avail[2], (long)phys_avail[3]);
- printf("physmem: %#lx\n", physmem);
-
- Maxmem = physmem;
-
}
void
@@ -730,8 +572,6 @@ platform_start(__register_t a0, __register_t a1, __register_t a2 __unused,
{
uint64_t platform_counter_freq;
- boothowto |= RB_SINGLE;
-
/* Initialize pcpu stuff */
mips_pcpu0_init();
mips_timer_early_init(OCTEON_CLOCK_DEFAULT);
@@ -762,7 +602,15 @@ platform_start(__register_t a0, __register_t a1, __register_t a2 __unused,
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
platform_counter_freq = octeon_get_clock_rate();
- mips_timer_init_params(platform_counter_freq, 1);
+ mips_timer_init_params(platform_counter_freq, 0);
+
+#ifdef SMP
+ /*
+ * Clear any pending IPIs and enable the IPI interrupt.
+ */
+ oct_write64(OCTEON_CIU_MBOX_CLRX(0), 0xffffffff);
+ ciu_enable_interrupts(0, CIU_INT_1, CIU_EN_0, OCTEON_CIU_ENABLE_MBOX_INTR, CIU_MIPS_IP3);
+#endif
}
/* impSTART: This stuff should move back into the Cavium SDK */
@@ -873,8 +721,9 @@ int octeon_chip_rev_major = 0, octeon_chip_rev_minor = 0, octeon_chip_type = 0;
static octeon_boot_descriptor_t *app_desc_ptr;
static cvmx_bootinfo_t *cvmx_desc_ptr;
-#define OCTEON_BOARD_TYPE_NONE 0
-#define OCTEON_BOARD_TYPE_SIM 1
+#define OCTEON_BOARD_TYPE_NONE 0
+#define OCTEON_BOARD_TYPE_SIM 1
+#define OCTEON_BOARD_TYPE_CN3010_EVB_HS5 11
#define OCTEON_CLOCK_MIN (100 * 1000 * 1000)
#define OCTEON_CLOCK_MAX (800 * 1000 * 1000)
@@ -886,11 +735,23 @@ static cvmx_bootinfo_t *cvmx_desc_ptr;
int
octeon_board_real(void)
{
- if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) ||
- (octeon_board_type == OCTEON_BOARD_TYPE_SIM) ||
- !octeon_board_rev_major)
+ switch (octeon_board_type) {
+ case OCTEON_BOARD_TYPE_NONE:
+ case OCTEON_BOARD_TYPE_SIM:
return 0;
- return 1;
+ case OCTEON_BOARD_TYPE_CN3010_EVB_HS5:
+ /*
+ * XXX
+ * The CAM-0100 identifies itself as type 11, revision 0.0,
+ * despite its being rather real. Disable the revision check
+ * for type 11.
+ */
+ return 1;
+ default:
+ if (octeon_board_rev_major == 0)
+ return 0;
+ return 1;
+ }
}
static void
@@ -971,7 +832,7 @@ octeon_boot_params_init(register_t ptr)
printf("Boot Descriptor Ver: %u -> %u/%u",
octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100);
- printf(" CPU clock: %uMHz\n", octeon_cpu_clock/1000000);
+ printf(" CPU clock: %uMHz Core Mask: %#x\n", octeon_cpu_clock/1000000, octeon_core_mask);
printf(" Dram: %u MB", (uint32_t)(octeon_dram >> 20));
printf(" Board Type: %u Revision: %u/%u\n",
octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor);
diff --git a/sys/mips/cavium/octeon_mp.c b/sys/mips/cavium/octeon_mp.c
new file mode 100644
index 0000000..8ded87e
--- /dev/null
+++ b/sys/mips/cavium/octeon_mp.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett@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$
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <machine/hwfunc.h>
+#include <machine/smp.h>
+
+#include <mips/cavium/octeon_pcmap_regs.h>
+
+unsigned octeon_ap_boot = ~0;
+
+void
+platform_ipi_send(int cpuid)
+{
+ oct_write64(OCTEON_CIU_MBOX_SETX(cpuid), 1);
+ mips_wbflush();
+}
+
+void
+platform_ipi_clear(void)
+{
+ uint64_t action;
+
+ action = oct_read64(OCTEON_CIU_MBOX_CLRX(PCPU_GET(cpuid)));
+ KASSERT(action == 1, ("unexpected IPIs: %#jx", (uintmax_t)action));
+ oct_write64(OCTEON_CIU_MBOX_CLRX(PCPU_GET(cpuid)), action);
+}
+
+int
+platform_ipi_intrnum(void)
+{
+ return (1);
+}
+
+void
+platform_init_ap(int cpuid)
+{
+ /*
+ * Set the exception base.
+ */
+ mips_wr_ebase(0x80000000 | cpuid);
+
+ /*
+ * Set up interrupts, clear IPIs and unmask the IPI interrupt.
+ */
+ octeon_ciu_reset();
+
+ oct_write64(OCTEON_CIU_MBOX_CLRX(cpuid), 0xffffffff);
+ ciu_enable_interrupts(cpuid, CIU_INT_1, CIU_EN_0, OCTEON_CIU_ENABLE_MBOX_INTR, CIU_MIPS_IP3);
+
+ mips_wbflush();
+}
+
+int
+platform_num_processors(void)
+{
+ return (fls(octeon_core_mask));
+}
+
+int
+platform_start_ap(int cpuid)
+{
+ if (atomic_cmpset_32(&octeon_ap_boot, ~0, cpuid) == 0)
+ return (-1);
+ for (;;) {
+ DELAY(1000);
+ if (atomic_cmpset_32(&octeon_ap_boot, 0, ~0) != 0)
+ return (0);
+ printf("Waiting for cpu%d to start\n", cpuid);
+ }
+}
diff --git a/sys/mips/cavium/octeon_pcmap_regs.h b/sys/mips/cavium/octeon_pcmap_regs.h
index a80c3d4..0ee1a73e 100644
--- a/sys/mips/cavium/octeon_pcmap_regs.h
+++ b/sys/mips/cavium/octeon_pcmap_regs.h
@@ -54,14 +54,6 @@
#ifndef LOCORE
-/* XXXimp: From Cavium's include/pcpu.h, need to port that over */
-#ifndef OCTEON_SMP
-#define OCTEON_CORE_ID 0
-#else
-extern struct pcpu *cpuid_to_pcpu[];
-#define OCTEON_CORE_ID (mips_rd_coreid())
-#endif
-
/*
* Utility inlines & macros
*/
@@ -90,350 +82,228 @@ extern struct pcpu *cpuid_to_pcpu[];
#define OCTEON_SYNCW __asm __volatile (".word 0x10f" : : )
#define OCTEON_SYNCWS __asm __volatile (".word 0x14f" : : )
-#if defined(__mips_n32) || defined(__mips_n64)
+#if defined(__mips_n64)
+#define oct_write64(a, v) (*(volatile uint64_t *)(a) = (uint64_t)(v))
+#define oct_write8_x8(a, v) (*(volatile uint8_t *)(a) = (uint8_t)(v))
-static inline void oct_write64 (uint64_t csr_addr, uint64_t val64)
-{
- uint64_t *ptr = (uint64_t *) csr_addr;
- *ptr = val64;
+#define OCT_READ(n, t) \
+static inline t oct_read ## n(uintptr_t a) \
+{ \
+ volatile t *p = (volatile t *)a; \
+ return (*p); \
}
-static inline void oct_write64_int64 (uint64_t csr_addr, int64_t val64i)
-{
- int64_t *ptr = (int64_t *) csr_addr;
- *ptr = val64i;
-}
+OCT_READ(8, uint8_t);
+OCT_READ(16, uint16_t);
+OCT_READ(32, uint32_t);
+OCT_READ(64, uint64_t);
-static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8)
+#elif defined(__mips_n32) || defined(__mips_o32)
+#if defined(__mips_n32)
+static inline void oct_write64 (uint64_t csr_addr, uint64_t val64)
{
- uint64_t *ptr = (uint64_t *) csr_addr;
- *ptr = (uint64_t) val8;
+ __asm __volatile (
+ ".set push\n"
+ ".set mips64\n"
+ "sd %0, 0(%1)\n"
+ ".set pop\n"
+ :
+ : "r"(val64), "r"(csr_addr));
}
-static inline void oct_write8 (uint64_t csr_addr, uint8_t val8)
+static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8)
{
- oct_write64(csr_addr, (uint64_t) val8);
-}
+ __asm __volatile (
+ ".set push\n"
+ ".set mips64\n"
+ "sb %0, 0(%1)\n"
+ ".set pop\n"
+ :
+ : "r"(val8), "r"(csr_addr));
+}
+
+#define OCT_READ(n, t, insn) \
+static inline t oct_read ## n(uint64_t a) \
+{ \
+ uint64_t tmp; \
+ \
+ __asm __volatile ( \
+ ".set push\n" \
+ ".set mips64\n" \
+ insn "\t%0, 0(%1)\n" \
+ ".set pop\n" \
+ : "=r"(tmp) \
+ : "r"(a)); \
+ return ((t)tmp); \
+}
+
+OCT_READ(8, uint8_t, "lb");
+OCT_READ(16, uint16_t, "lh");
+OCT_READ(32, uint32_t, "lw");
+OCT_READ(64, uint64_t, "ld");
+#else
-static inline void oct_write16 (uint64_t csr_addr, uint16_t val16)
+/*
+ * XXX
+ * Add o32 variants that load the address into a register and the result out
+ * of a register properly, and simply disable interrupts before and after and
+ * hope that we don't need to refill or modify the TLB to access the address.
+ * I'd be a lot happier if csr_addr were a physical address and we mapped it
+ * into XKPHYS here so that we could guarantee that interrupts were the only
+ * kind of exception we needed to worry about.
+ *
+ * Also, some of this inline assembly is needlessly verbose. Oh, well.
+ */
+static inline void oct_write64 (uint64_t csr_addr, uint64_t val64)
{
- oct_write64(csr_addr, (uint64_t) val16);
-}
+ uint32_t csr_addrh = csr_addr >> 32;
+ uint32_t csr_addrl = csr_addr;
+ uint32_t valh = val64 >> 32;
+ uint32_t vall = val64;
+ uint32_t tmp1;
+ uint32_t tmp2;
+ uint32_t tmp3;
+ register_t sr;
-static inline void oct_write32 (uint64_t csr_addr, uint32_t val32)
-{
- oct_write64(csr_addr, (uint64_t) val32);
-}
+ sr = intr_disable();
-static inline uint8_t oct_read8 (uint64_t csr_addr)
-{
- uint8_t *ptr = (uint8_t *) csr_addr;
- return (*ptr);
+ __asm __volatile (
+ ".set push\n"
+ ".set mips64\n"
+ ".set noreorder\n"
+ ".set noat\n"
+ "dsll %0, %3, 32\n"
+ "dsll %1, %5, 32\n"
+ "dsll %2, %4, 32\n"
+ "dsrl %2, %2, 32\n"
+ "or %0, %0, %2\n"
+ "dsll %2, %6, 32\n"
+ "dsrl %2, %2, 32\n"
+ "or %1, %1, %2\n"
+ "sd %0, 0(%1)\n"
+ ".set pop\n"
+ : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
+ : "r" (valh), "r" (vall), "r" (csr_addrh), "r" (csr_addrl));
+
+ intr_restore(sr);
}
-static inline uint8_t oct_read16 (uint64_t csr_addr)
+static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8)
{
- uint16_t *ptr = (uint16_t *) csr_addr;
- return (*ptr);
-}
+ uint32_t csr_addrh = csr_addr >> 32;
+ uint32_t csr_addrl = csr_addr;
+ uint32_t tmp1;
+ uint32_t tmp2;
+ register_t sr;
+ sr = intr_disable();
-static inline uint32_t oct_read32 (uint64_t csr_addr)
-{
- uint32_t *ptr = (uint32_t *) csr_addr;
- return (*ptr);
-}
+ __asm __volatile (
+ ".set push\n"
+ ".set mips64\n"
+ ".set noreorder\n"
+ ".set noat\n"
+ "dsll %0, %3, 32\n"
+ "dsll %1, %4, 32\n"
+ "dsrl %1, %1, 32\n"
+ "or %0, %0, %1\n"
+ "sb %2, 0(%0)\n"
+ ".set pop\n"
+ : "=&r" (tmp1), "=&r" (tmp2)
+ : "r" (val8), "r" (csr_addrh), "r" (csr_addrl));
+
+ intr_restore(sr);
+}
+
+#define OCT_READ(n, t, insn) \
+static inline t oct_read ## n(uint64_t csr_addr) \
+{ \
+ uint32_t csr_addrh = csr_addr >> 32; \
+ uint32_t csr_addrl = csr_addr; \
+ uint32_t tmp1, tmp2; \
+ register_t sr; \
+ \
+ sr = intr_disable(); \
+ \
+ __asm __volatile ( \
+ ".set push\n" \
+ ".set mips64\n" \
+ ".set noreorder\n" \
+ ".set noat\n" \
+ "dsll %1, %2, 32\n" \
+ "dsll %0, %3, 32\n" \
+ "dsrl %0, %0, 32\n" \
+ "or %1, %1, %0\n" \
+ "lb %1, 0(%1)\n" \
+ ".set pop\n" \
+ : "=&r" (tmp1), "=&r" (tmp2) \
+ : "r" (csr_addrh), "r" (csr_addrl)); \
+ \
+ intr_restore(sr); \
+ \
+ return ((t)tmp2); \
+}
+
+OCT_READ(8, uint8_t, "lb");
+OCT_READ(16, uint16_t, "lh");
+OCT_READ(32, uint32_t, "lw");
static inline uint64_t oct_read64 (uint64_t csr_addr)
{
- uint64_t *ptr = (uint64_t *) csr_addr;
- return (*ptr);
-}
-
-static inline int32_t oct_readint32 (uint64_t csr_addr)
-{
- int32_t *ptr = (int32_t *) csr_addr;
- return (*ptr);
-}
-
-
-
-#else
-
-
-/* ABI o32 */
+ uint32_t csr_addrh = csr_addr >> 32;
+ uint32_t csr_addrl = csr_addr;
+ uint32_t valh;
+ uint32_t vall;
+ register_t sr;
+ sr = intr_disable();
-/*
- * Read/write functions
- */
-static inline void oct_write64 (uint64_t csr_addr, uint64_t val64)
-{
- uint32_t csr_addrh = csr_addr >> 32;
- uint32_t csr_addrl = csr_addr;
- uint32_t valh = (uint64_t)val64 >> 32;
- uint32_t vall = val64;
- uint32_t tmp1;
- uint32_t tmp2;
- uint32_t tmp3;
-
- __asm __volatile (
+ __asm __volatile (
+ ".set push\n"
".set mips64\n"
- "dsll %0, %3, 32\n"
- "dsll %1, %5, 32\n"
- "dsll %2, %4, 32\n"
- "dsrl %2, %2, 32\n"
- "or %0, %0, %2\n"
- "dsll %2, %6, 32\n"
- "dsrl %2, %2, 32\n"
- "or %1, %1, %2\n"
- "sd %0, 0(%1)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
- : "r" (valh), "r" (vall),
- "r" (csr_addrh), "r" (csr_addrl)
- );
-}
-
-static inline void oct_write64_int64 (uint64_t csr_addr, int64_t val64i)
-{
- uint32_t csr_addrh = csr_addr >> 32;
- uint32_t csr_addrl = csr_addr;
- int32_t valh = (uint64_t)val64i >> 32;
- int32_t vall = val64i;
- uint32_t tmp1;
- uint32_t tmp2;
- uint32_t tmp3;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %3, 32\n"
- "dsll %1, %5, 32\n"
- "dsll %2, %4, 32\n"
- "dsrl %2, %2, 32\n"
- "or %0, %0, %2\n"
- "dsll %2, %6, 32\n"
- "dsrl %2, %2, 32\n"
- "or %1, %1, %2\n"
- "sd %0, 0(%1)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
- : "r" (valh), "r" (vall),
- "r" (csr_addrh), "r" (csr_addrl)
- );
+ ".set noreorder\n"
+ ".set noat\n"
+ "dsll %0, %2, 32\n"
+ "dsll %1, %3, 32\n"
+ "dsrl %1, %1, 32\n"
+ "or %0, %0, %1\n"
+ "ld %1, 0(%0)\n"
+ "dsrl %0, %1, 32\n"
+ "dsll %1, %1, 32\n"
+ "dsrl %1, %1, 32\n"
+ ".set pop\n"
+ : "=&r" (valh), "=&r" (vall)
+ : "r" (csr_addrh), "r" (csr_addrl));
+
+ intr_restore(sr);
+
+ return ((uint64_t)valh << 32) | vall;
}
+#endif
+#endif
-/*
- * oct_write8_x8
- *
- * 8 bit data write into IO Space. Written using an 8 bit bus io transaction
- */
-static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8)
-{
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t tmp1;
- uint32_t tmp2;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %3, 32\n"
- "dsll %1, %4, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "sb %2, 0(%0)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "r" (val8), "r" (csr_addrh), "r" (csr_addrl) );
-}
+#define oct_write64_int64(a, v) (oct_write64(a, (int64_t)(v)))
/*
- * oct_write8
- *
- * 8 bit data write into IO Space. Written using a 64 bit bus io transaction
+ * Most write bus transactions are actually 64-bit on Octeon.
*/
static inline void oct_write8 (uint64_t csr_addr, uint8_t val8)
{
-#if 1
oct_write64(csr_addr, (uint64_t) val8);
-#else
-
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t tmp1;
- uint32_t tmp2;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %3, 32\n"
- "dsll %1, %4, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "sb %2, 0(%0)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "r" (val8), "r" (csr_addrh), "r" (csr_addrl) );
-#endif
}
static inline void oct_write16 (uint64_t csr_addr, uint16_t val16)
{
-#if 1
oct_write64(csr_addr, (uint64_t) val16);
-
-#else
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t tmp1;
- uint32_t tmp2;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %3, 32\n"
- "dsll %1, %4, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "sh %2, 0(%0)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "r" (val16), "r" (csr_addrh), "r" (csr_addrl) );
-#endif
}
static inline void oct_write32 (uint64_t csr_addr, uint32_t val32)
{
-#if 1
oct_write64(csr_addr, (uint64_t) val32);
-#else
-
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t tmp1;
- uint32_t tmp2;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %3, 32\n"
- "dsll %1, %4, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "sw %2, 0(%0)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "r" (val32), "r" (csr_addrh), "r" (csr_addrl) );
-#endif
-}
-
-
-
-static inline uint8_t oct_read8 (uint64_t csr_addr)
-{
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t tmp1, tmp2;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %1, %2, 32\n"
- "dsll %0, %3, 32\n"
- "dsrl %0, %0, 32\n"
- "or %1, %1, %0\n"
- "lb %1, 0(%1)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "r" (csr_addrh), "r" (csr_addrl) );
- return ((uint8_t) tmp2);
-}
-
-static inline uint8_t oct_read16 (uint64_t csr_addr)
-{
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t tmp1, tmp2;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %1, %2, 32\n"
- "dsll %0, %3, 32\n"
- "dsrl %0, %0, 32\n"
- "or %1, %1, %0\n"
- "lh %1, 0(%1)\n"
- ".set mips0\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "r" (csr_addrh), "r" (csr_addrl) );
- return ((uint16_t) tmp2);
-}
-
-
-static inline uint32_t oct_read32 (uint64_t csr_addr)
-{
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- uint32_t val32;
- uint32_t tmp;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %2, 32\n"
- "dsll %1, %3, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "lw %0, 0(%0)\n"
- ".set mips0\n"
- : "=&r" (val32), "=&r" (tmp)
- : "r" (csr_addrh), "r" (csr_addrl) );
- return (val32);
-}
-
-
-static inline uint64_t oct_read64 (uint64_t csr_addr)
-{
- uint32_t csr_addrh = csr_addr >> 32;
- uint32_t csr_addrl = csr_addr;
- uint32_t valh;
- uint32_t vall;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %2, 32\n"
- "dsll %1, %3, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "ld %1, 0(%0)\n"
- "dsrl %0, %1, 32\n"
- "dsll %1, %1, 32\n"
- "dsrl %1, %1, 32\n"
- ".set mips0\n"
- : "=&r" (valh), "=&r" (vall)
- : "r" (csr_addrh), "r" (csr_addrl)
- );
- return ((uint64_t)valh << 32) | vall;
-}
-
-
-static inline int32_t oct_readint32 (uint64_t csr_addr)
-{
- uint32_t csr_addrh = csr_addr>>32;
- uint32_t csr_addrl = csr_addr;
- int32_t val32;
- uint32_t tmp;
-
- __asm __volatile (
- ".set mips64\n"
- "dsll %0, %2, 32\n"
- "dsll %1, %3, 32\n"
- "dsrl %1, %1, 32\n"
- "or %0, %0, %1\n"
- "lw %0, 0(%0)\n"
- : "=&r" (val32), "=&r" (tmp)
- : "r" (csr_addrh), "r" (csr_addrl) );
- return (val32);
}
-
-#endif
-
+#define oct_readint32(a) ((int32_t)oct_read32((a)))
#define OCTEON_HW_BASE ((volatile uint64_t *) 0L)
#define OCTEON_REG_OFFSET (-4 * 1024ll) /* local scratchpad reg base */
@@ -446,62 +316,6 @@ static inline int32_t oct_readint32 (uint64_t csr_addr)
#define OCTEON_SCRATCH_2 32
-static inline uint64_t oct_mf_chord (void)
-{
- uint64_t dest;
-
- __asm __volatile ( ".set push\n"
- ".set noreorder\n"
- ".set noat\n"
- ".set mips64\n"
- "dmfc2 $1, 0x400\n"
- "move %0, $1\n"
- ".set pop\n"
- : "=r" (dest) : : "$1");
- return dest;
-}
-
-
-#define MIPS64_DMFCz(cop,regnum,cp0reg,select) \
- .word (0x40200000 | (cop << 25) | (regnum << 16) | (cp0reg << 11) | select)
-
-
-#define mips64_getcpz_xstr(s) mips64_getcpz_str(s)
-#define mips64_getcpz_str(s) #s
-
-#define mips64_dgetcpz(cop,cpzreg,sel,val_ptr) \
- ({ __asm __volatile( \
- ".set push\n" \
- ".set mips3\n" \
- ".set noreorder\n" \
- ".set noat\n" \
- mips64_getcpz_xstr(MIPS64_DMFCz(cop,1,cpzreg,sel)) "\n" \
- "nop\n" \
- "nop\n" \
- "nop\n" \
- "nop\n" \
- "sd $1,0(%0)\n" \
- ".set pop" \
- : /* no outputs */ : "r" (val_ptr) : "$1"); \
- })
-
-
-#define mips64_dgetcp2(cp2reg,sel,retval_ptr) \
- mips64_dgetcpz(2,cp2reg,sel,retval_ptr)
-
-
-#define OCTEON_MF_CHORD(dest) mips64_dgetcp2(0x400, 0, &dest)
-
-
-
-#define OCTEON_RDHWR(result, regstr) \
- __asm __volatile ( \
- ".set mips3\n" \
- "rdhwr %0,$" OCTEON_TMP_STR(regstr) "\n" \
- ".set mips\n" \
- : "=d" (result));
-
-#define CVMX_MF_CHORD(dest) OCTEON_RDHWR(dest, 30)
#define OCTEON_CHORD_HEX(dest_ptr) \
({ __asm __volatile( \
@@ -519,15 +333,6 @@ static inline uint64_t oct_mf_chord (void)
: /* no outputs */ : "r" (dest_ptr) : "$2"); \
})
-
-
-#define OCTEON_MF_CHORD_BAD(dest) \
- __asm __volatile ( \
- ".set mips3\n" \
- "dmfc2 %0, 0x400\n" \
- ".set mips0\n" \
- : "=&r" (dest) : )
-
static inline uint64_t oct_scratch_read64 (uint64_t address)
{
return(*((volatile uint64_t *)(OCTEON_SCRATCH_BASE + address)));
@@ -539,17 +344,6 @@ static inline void oct_scratch_write64 (uint64_t address, uint64_t value)
}
-#define OCTEON_READ_CSR32(addr, val) \
- addr_ptr = addr; \
- oct_read_32_ptr(&addr_ptr, &val);
-
-#define OCTEON_WRITE_CSR32(addr, val, val_dummy) \
- addr_ptr = addr; \
- oct_write_32_ptr(&addr_ptr, &val); \
- oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-
-
-
/*
* Octeon Address Space Definitions
*/
@@ -589,7 +383,7 @@ typedef enum {
/* PTR_SIZE == sizeof(uint32_t) */
-#ifdef ISA_MIPS32
+#if defined(__mips_n32) || defined(__mips_o32)
#define mipsx_addr_size uint32_t // u_int64
#define MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT 30 // 62
#define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffff // 0x1fffffff
@@ -913,12 +707,6 @@ extern void octeon_led_write_hexchar(int char_position, char hexval);
extern void octeon_led_write_hex(uint32_t wl);
extern void octeon_led_write_string(const char *str);
extern void octeon_reset(void);
-extern void octeon_uart_write_byte(int uart_index, uint8_t ch);
-extern void octeon_uart_write_string(int uart_index, const char *str);
-extern void octeon_uart_write_hex(uint32_t wl);
-extern void octeon_uart_write_hex2(uint32_t wl, uint32_t wh);
-extern void octeon_wait_uart_flush(int uart_index, uint8_t ch);
-extern void octeon_uart_write_byte0(uint8_t ch);
extern void octeon_led_write_char0(char val);
extern void octeon_led_run_wheel(int *pos, int led_position);
extern void octeon_debug_symbol(void);
diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX
index 30126bf..4ee6aab 100644
--- a/sys/mips/conf/AR71XX
+++ b/sys/mips/conf/AR71XX
@@ -15,7 +15,7 @@ files "../atheros/files.ar71xx"
hints "AR71XX.hints"
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
-makeoptions MODULES_OVERRIDE=""
+#makeoptions MODULES_OVERRIDE=""
options DDB
options KDB
@@ -67,10 +67,11 @@ device ath_rate_sample
device mii
device arge
-# device usb
-# options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order
+device usb
+options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order
# options USB_DEBUG
-# device ehci
+device ohci
+device ehci
device spibus
device ar71xx_spi
diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1
index b326823..c8597dc 100644
--- a/sys/mips/conf/OCTEON1
+++ b/sys/mips/conf/OCTEON1
@@ -81,6 +81,8 @@ nodevice uart_ns8250
device rgmii
#options VERBOSE_SYSINIT
+device bpf
+device random
#
# Use the following for Compact Flash file-system
diff --git a/sys/mips/conf/OCTEON1-32 b/sys/mips/conf/OCTEON1-32
index 7962a06..870a141 100644
--- a/sys/mips/conf/OCTEON1-32
+++ b/sys/mips/conf/OCTEON1-32
@@ -70,6 +70,8 @@ nodevice uart_ns8250
device rgmii
#options VERBOSE_SYSINIT
+device bpf
+device random
#
# Use the following for Compact Flash file-system
diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5
index a4e32c0..c38e45f 100644
--- a/sys/mips/conf/SENTRY5
+++ b/sys/mips/conf/SENTRY5
@@ -75,6 +75,7 @@ device pci # siba_pcib
#device ath_hal # pci chip support
#options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors
+options USB_DEBUG # enable debug msgs
device usb # USB Bus (required)
device uhci # UHCI PCI->USB interface
device ehci # EHCI PCI->USB interface (USB 2.0)
diff --git a/sys/mips/conf/SWARM b/sys/mips/conf/SWARM
index 3189bcb..041c94d 100644
--- a/sys/mips/conf/SWARM
+++ b/sys/mips/conf/SWARM
@@ -8,12 +8,6 @@ options CPU_SB1
files "../sibyte/files.sibyte"
hints "SWARM.hints"
-#
-# 32-bit kernel cannot deal with physical memory beyond 4GB
-# XXX pmap assumes that all the memory can be mapped using KSEG0
-#
-options MAXMEM=512*1024
-
options CFE
options CFE_CONSOLE
options CFE_ENV
diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR
index d743c1b..a0737b3 100644
--- a/sys/mips/conf/XLR
+++ b/sys/mips/conf/XLR
@@ -132,6 +132,7 @@ device scbus
#device ohci # OHCI PCI->USB interface
device ehci # EHCI PCI->USB interface (USB 2.0)
device usb # USB Bus (required)
+options USB_DEBUG # enable debug msgs
#device udbp # USB Double Bulk Pipe devices
#device ugen # Generic
#device uhid # "Human Interface Devices"
diff --git a/sys/mips/include/_inttypes.h b/sys/mips/include/_inttypes.h
index e09f9de..79664e4 100644
--- a/sys/mips/include/_inttypes.h
+++ b/sys/mips/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -45,177 +38,183 @@
* Macros for format specifiers.
*/
+#if defined(__mips_n64)
+#define PRI64 "l"
+#else
+#define PRI64 "ll"
+#endif
+
/* fprintf(3) macros for signed integers. */
#define PRId8 "d" /* int8_t */
#define PRId16 "d" /* int16_t */
#define PRId32 "d" /* int32_t */
-#define PRId64 "lld" /* int64_t */
+#define PRId64 PRI64"d" /* int64_t */
#define PRIdLEAST8 "d" /* int_least8_t */
#define PRIdLEAST16 "d" /* int_least16_t */
#define PRIdLEAST32 "d" /* int_least32_t */
-#define PRIdLEAST64 "lld" /* int_least64_t */
+#define PRIdLEAST64 PRI64"d" /* int_least64_t */
#define PRIdFAST8 "d" /* int_fast8_t */
#define PRIdFAST16 "d" /* int_fast16_t */
#define PRIdFAST32 "d" /* int_fast32_t */
-#define PRIdFAST64 "lld" /* int_fast64_t */
+#define PRIdFAST64 PRI64"d" /* int_fast64_t */
#define PRIdMAX "jd" /* intmax_t */
-#define PRIdPTR "d" /* intptr_t */
+#define PRIdPTR "ld" /* intptr_t */
#define PRIi8 "i" /* int8_t */
#define PRIi16 "i" /* int16_t */
#define PRIi32 "i" /* int32_t */
-#define PRIi64 "lli" /* int64_t */
+#define PRIi64 PRI64"i" /* int64_t */
#define PRIiLEAST8 "i" /* int_least8_t */
#define PRIiLEAST16 "i" /* int_least16_t */
#define PRIiLEAST32 "i" /* int_least32_t */
-#define PRIiLEAST64 "lli" /* int_least64_t */
+#define PRIiLEAST64 PRI64"i" /* int_least64_t */
#define PRIiFAST8 "i" /* int_fast8_t */
#define PRIiFAST16 "i" /* int_fast16_t */
#define PRIiFAST32 "i" /* int_fast32_t */
-#define PRIiFAST64 "lli" /* int_fast64_t */
+#define PRIiFAST64 PRI64"i" /* int_fast64_t */
#define PRIiMAX "ji" /* intmax_t */
-#define PRIiPTR "i" /* intptr_t */
+#define PRIiPTR "li" /* intptr_t */
/* fprintf(3) macros for unsigned integers. */
#define PRIo8 "o" /* uint8_t */
#define PRIo16 "o" /* uint16_t */
#define PRIo32 "o" /* uint32_t */
-#define PRIo64 "llo" /* uint64_t */
+#define PRIo64 PRI64"o" /* uint64_t */
#define PRIoLEAST8 "o" /* uint_least8_t */
#define PRIoLEAST16 "o" /* uint_least16_t */
#define PRIoLEAST32 "o" /* uint_least32_t */
-#define PRIoLEAST64 "llo" /* uint_least64_t */
+#define PRIoLEAST64 PRI64"o" /* uint_least64_t */
#define PRIoFAST8 "o" /* uint_fast8_t */
#define PRIoFAST16 "o" /* uint_fast16_t */
#define PRIoFAST32 "o" /* uint_fast32_t */
-#define PRIoFAST64 "llo" /* uint_fast64_t */
+#define PRIoFAST64 PRI64"o" /* uint_fast64_t */
#define PRIoMAX "jo" /* uintmax_t */
-#define PRIoPTR "o" /* uintptr_t */
+#define PRIoPTR "lo" /* uintptr_t */
#define PRIu8 "u" /* uint8_t */
#define PRIu16 "u" /* uint16_t */
#define PRIu32 "u" /* uint32_t */
-#define PRIu64 "llu" /* uint64_t */
+#define PRIu64 PRI64"u" /* uint64_t */
#define PRIuLEAST8 "u" /* uint_least8_t */
#define PRIuLEAST16 "u" /* uint_least16_t */
#define PRIuLEAST32 "u" /* uint_least32_t */
-#define PRIuLEAST64 "llu" /* uint_least64_t */
+#define PRIuLEAST64 PRI64"u" /* uint_least64_t */
#define PRIuFAST8 "u" /* uint_fast8_t */
#define PRIuFAST16 "u" /* uint_fast16_t */
#define PRIuFAST32 "u" /* uint_fast32_t */
-#define PRIuFAST64 "llu" /* uint_fast64_t */
+#define PRIuFAST64 PRI64"u" /* uint_fast64_t */
#define PRIuMAX "ju" /* uintmax_t */
-#define PRIuPTR "u" /* uintptr_t */
+#define PRIuPTR "lu" /* uintptr_t */
#define PRIx8 "x" /* uint8_t */
#define PRIx16 "x" /* uint16_t */
#define PRIx32 "x" /* uint32_t */
-#define PRIx64 "llx" /* uint64_t */
+#define PRIx64 PRI64"x" /* uint64_t */
#define PRIxLEAST8 "x" /* uint_least8_t */
#define PRIxLEAST16 "x" /* uint_least16_t */
#define PRIxLEAST32 "x" /* uint_least32_t */
-#define PRIxLEAST64 "llx" /* uint_least64_t */
+#define PRIxLEAST64 PRI64"x" /* uint_least64_t */
#define PRIxFAST8 "x" /* uint_fast8_t */
#define PRIxFAST16 "x" /* uint_fast16_t */
#define PRIxFAST32 "x" /* uint_fast32_t */
-#define PRIxFAST64 "llx" /* uint_fast64_t */
+#define PRIxFAST64 PRI64"x" /* uint_fast64_t */
#define PRIxMAX "jx" /* uintmax_t */
-#define PRIxPTR "x" /* uintptr_t */
+#define PRIxPTR "lx" /* uintptr_t */
#define PRIX8 "X" /* uint8_t */
#define PRIX16 "X" /* uint16_t */
#define PRIX32 "X" /* uint32_t */
-#define PRIX64 "llX" /* uint64_t */
+#define PRIX64 PRI64"X" /* uint64_t */
#define PRIXLEAST8 "X" /* uint_least8_t */
#define PRIXLEAST16 "X" /* uint_least16_t */
#define PRIXLEAST32 "X" /* uint_least32_t */
-#define PRIXLEAST64 "llX" /* uint_least64_t */
+#define PRIXLEAST64 PRI64"X" /* uint_least64_t */
#define PRIXFAST8 "X" /* uint_fast8_t */
#define PRIXFAST16 "X" /* uint_fast16_t */
#define PRIXFAST32 "X" /* uint_fast32_t */
-#define PRIXFAST64 "llX" /* uint_fast64_t */
+#define PRIXFAST64 PRI64"X" /* uint_fast64_t */
#define PRIXMAX "jX" /* uintmax_t */
-#define PRIXPTR "X" /* uintptr_t */
+#define PRIXPTR "lX" /* uintptr_t */
/* fscanf(3) macros for signed integers. */
#define SCNd8 "hhd" /* int8_t */
#define SCNd16 "hd" /* int16_t */
#define SCNd32 "d" /* int32_t */
-#define SCNd64 "lld" /* int64_t */
+#define SCNd64 PRI64"d" /* int64_t */
#define SCNdLEAST8 "hhd" /* int_least8_t */
#define SCNdLEAST16 "hd" /* int_least16_t */
#define SCNdLEAST32 "d" /* int_least32_t */
-#define SCNdLEAST64 "lld" /* int_least64_t */
+#define SCNdLEAST64 PRI64"d" /* int_least64_t */
#define SCNdFAST8 "d" /* int_fast8_t */
#define SCNdFAST16 "d" /* int_fast16_t */
#define SCNdFAST32 "d" /* int_fast32_t */
-#define SCNdFAST64 "lld" /* int_fast64_t */
+#define SCNdFAST64 PRI64"d" /* int_fast64_t */
#define SCNdMAX "jd" /* intmax_t */
-#define SCNdPTR "d" /* intptr_t */
+#define SCNdPTR "ld" /* intptr_t */
#define SCNi8 "hhi" /* int8_t */
#define SCNi16 "hi" /* int16_t */
#define SCNi32 "i" /* int32_t */
-#define SCNi64 "lli" /* int64_t */
+#define SCNi64 PRI64"i" /* int64_t */
#define SCNiLEAST8 "hhi" /* int_least8_t */
#define SCNiLEAST16 "hi" /* int_least16_t */
#define SCNiLEAST32 "i" /* int_least32_t */
-#define SCNiLEAST64 "lli" /* int_least64_t */
+#define SCNiLEAST64 PRI64"i" /* int_least64_t */
#define SCNiFAST8 "i" /* int_fast8_t */
#define SCNiFAST16 "i" /* int_fast16_t */
#define SCNiFAST32 "i" /* int_fast32_t */
-#define SCNiFAST64 "lli" /* int_fast64_t */
+#define SCNiFAST64 PRI64"i" /* int_fast64_t */
#define SCNiMAX "ji" /* intmax_t */
-#define SCNiPTR "i" /* intptr_t */
+#define SCNiPTR "li" /* intptr_t */
/* fscanf(3) macros for unsigned integers. */
#define SCNo8 "hho" /* uint8_t */
#define SCNo16 "ho" /* uint16_t */
#define SCNo32 "o" /* uint32_t */
-#define SCNo64 "llo" /* uint64_t */
+#define SCNo64 PRI64"o" /* uint64_t */
#define SCNoLEAST8 "hho" /* uint_least8_t */
#define SCNoLEAST16 "ho" /* uint_least16_t */
#define SCNoLEAST32 "o" /* uint_least32_t */
-#define SCNoLEAST64 "llo" /* uint_least64_t */
+#define SCNoLEAST64 PRI64"o" /* uint_least64_t */
#define SCNoFAST8 "o" /* uint_fast8_t */
#define SCNoFAST16 "o" /* uint_fast16_t */
#define SCNoFAST32 "o" /* uint_fast32_t */
-#define SCNoFAST64 "llo" /* uint_fast64_t */
+#define SCNoFAST64 PRI64"o" /* uint_fast64_t */
#define SCNoMAX "jo" /* uintmax_t */
-#define SCNoPTR "o" /* uintptr_t */
+#define SCNoPTR "lo" /* uintptr_t */
#define SCNu8 "hhu" /* uint8_t */
#define SCNu16 "hu" /* uint16_t */
#define SCNu32 "u" /* uint32_t */
-#define SCNu64 "llu" /* uint64_t */
+#define SCNu64 PRI64"u" /* uint64_t */
#define SCNuLEAST8 "hhu" /* uint_least8_t */
#define SCNuLEAST16 "hu" /* uint_least16_t */
#define SCNuLEAST32 "u" /* uint_least32_t */
-#define SCNuLEAST64 "llu" /* uint_least64_t */
+#define SCNuLEAST64 PRI64"u" /* uint_least64_t */
#define SCNuFAST8 "u" /* uint_fast8_t */
#define SCNuFAST16 "u" /* uint_fast16_t */
#define SCNuFAST32 "u" /* uint_fast32_t */
-#define SCNuFAST64 "llu" /* uint_fast64_t */
+#define SCNuFAST64 PRI64"u" /* uint_fast64_t */
#define SCNuMAX "ju" /* uintmax_t */
-#define SCNuPTR "u" /* uintptr_t */
+#define SCNuPTR "lu" /* uintptr_t */
#define SCNx8 "hhx" /* uint8_t */
#define SCNx16 "hx" /* uint16_t */
#define SCNx32 "x" /* uint32_t */
-#define SCNx64 "llx" /* uint64_t */
+#define SCNx64 PRI64"x" /* uint64_t */
#define SCNxLEAST8 "hhx" /* uint_least8_t */
#define SCNxLEAST16 "hx" /* uint_least16_t */
#define SCNxLEAST32 "x" /* uint_least32_t */
-#define SCNxLEAST64 "llx" /* uint_least64_t */
+#define SCNxLEAST64 PRI64"x" /* uint_least64_t */
#define SCNxFAST8 "x" /* uint_fast8_t */
#define SCNxFAST16 "x" /* uint_fast16_t */
#define SCNxFAST32 "x" /* uint_fast32_t */
-#define SCNxFAST64 "llx" /* uint_fast64_t */
+#define SCNxFAST64 PRI64"x" /* uint_fast64_t */
#define SCNxMAX "jx" /* uintmax_t */
-#define SCNxPTR "x" /* uintptr_t */
+#define SCNxPTR "lx" /* uintptr_t */
#endif /* !_MACHINE_INTTYPES_H_ */
diff --git a/sys/mips/include/_limits.h b/sys/mips/include/_limits.h
index d544305..e160a7f4 100644
--- a/sys/mips/include/_limits.h
+++ b/sys/mips/include/_limits.h
@@ -34,6 +34,10 @@
#ifndef _MACHINE__LIMITS_H_
#define _MACHINE__LIMITS_H_
+#if _MIPS_SZLONG == 64
+#define _LARGE_LONG
+#endif
+
/*
* According to ANSI (section 2.2.4.2), the values below must be usable by
* #if preprocessing directives. Additionally, the expression must have the
@@ -76,9 +80,9 @@
#define __LLONG_MAX 0x7fffffffffffffffLL /* max value for a long long */
#define __LLONG_MIN (-0x7fffffffffffffffLL - 1) /* min for a long long */
-#define __SSIZE_MAX __INT_MAX /* max value for a ssize_t */
+#define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */
-#define __SIZE_T_MAX __UINT_MAX /* max value for a size_t */
+#define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */
#define __OFF_MAX __LLONG_MAX /* max value for an off_t */
#define __OFF_MIN __LLONG_MIN /* min value for an off_t */
diff --git a/sys/mips/include/archtype.h b/sys/mips/include/archtype.h
deleted file mode 100644
index ed1b5ea..0000000
--- a/sys/mips/include/archtype.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $OpenBSD: archtype.h,v 1.6 1999/01/27 04:46:04 imp Exp $ */
-/*
- * Copyright (c) 1997 Per Fogelstrom
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed under OpenBSD by
- * Per Fogelstrom.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
- *
- * JNPR: archtype.h,v 1.6 2007/08/09 11:23:32 katta
- *
- * $FreeBSD$
- */
-
-#ifndef _MACHINE_ARCHTYPE_H_
-#define _MACHINE_ARCHTYPE_H_
-/*
- * Define architectural identitys for the different Mips machines.
- */
-
-/*
- * FREEBSD_DEVELOPERS_FIXME
- * Define constants for the supported MIPS CPU's
- */
-#define MIPS_CLASS_UNKNOWN 0x00
-
-#endif /* !_MACHINE_ARCHTYPE_H_ */
diff --git a/sys/mips/include/asm.h b/sys/mips/include/asm.h
index 0a9c518..23bfde1 100644
--- a/sys/mips/include/asm.h
+++ b/sys/mips/include/asm.h
@@ -98,23 +98,6 @@
#define _C_LABEL(x) x
-/*
- * Endian-independent assembly-code aliases for unaligned memory accesses.
- */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define LWLO lwl
-#define LWHI lwr
-#define SWLO swl
-#define SWHI swr
-#endif
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define LWLO lwr
-#define LWHI lwl
-#define SWLO swr
-#define SWHI swl
-#endif
-
#ifdef USE_AENT
#define AENT(x) \
.aent x, 0
@@ -306,28 +289,32 @@ _C_LABEL(x):
/*
* Call ast if required
+ *
+ * XXX Do we really need to disable interrupts?
*/
#define DO_AST \
44: \
- PTR_LA s0, _C_LABEL(disableintr) ;\
- jalr s0 ;\
- nop ;\
- move a0, v0 ;\
+ mfc0 t0, MIPS_COP_0_STATUS ;\
+ and a0, t0, MIPS_SR_INT_IE ;\
+ xor t0, a0, t0 ;\
+ mtc0 t0, MIPS_COP_0_STATUS ;\
+ COP0_SYNC ;\
GET_CPU_PCPU(s1) ;\
- lw s3, PC_CURPCB(s1) ;\
- lw s1, PC_CURTHREAD(s1) ;\
+ PTR_L s3, PC_CURPCB(s1) ;\
+ PTR_L s1, PC_CURTHREAD(s1) ;\
lw s2, TD_FLAGS(s1) ;\
li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\
and s2, s0 ;\
- PTR_LA s0, _C_LABEL(restoreintr) ;\
- jalr s0 ;\
- nop ;\
+ mfc0 t0, MIPS_COP_0_STATUS ;\
+ or t0, a0, t0 ;\
+ mtc0 t0, MIPS_COP_0_STATUS ;\
+ COP0_SYNC ;\
beq s2, zero, 4f ;\
nop ;\
PTR_LA s0, _C_LABEL(ast) ;\
jalr s0 ;\
PTR_ADDU a0, s3, U_PCB_REGS ;\
- j 44b ;\
+ j 44b ;\
nop ;\
4:
@@ -383,6 +370,45 @@ _C_LABEL(x):
#define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG)
/*
+ * Endian-independent assembly-code aliases for unaligned memory accesses.
+ */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+# define LWHI lwr
+# define LWLO lwl
+# define SWHI swr
+# define SWLO swl
+# if SZREG == 4
+# define REG_LHI lwr
+# define REG_LLO lwl
+# define REG_SHI swr
+# define REG_SLO swl
+# else
+# define REG_LHI ldr
+# define REG_LLO ldl
+# define REG_SHI sdr
+# define REG_SLO sdl
+# endif
+#endif
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+# define LWHI lwl
+# define LWLO lwr
+# define SWHI swl
+# define SWLO swr
+# if SZREG == 4
+# define REG_LHI lwl
+# define REG_LLO lwr
+# define REG_SHI swl
+# define REG_SLO swr
+# else
+# define REG_LHI ldl
+# define REG_LLO ldr
+# define REG_SHI sdl
+# define REG_SLO sdr
+# endif
+#endif
+
+/*
* While it would be nice to be compatible with the SGI
* REG_L and REG_S macros, because they do not take parameters, it
* is impossible to use them with the _MIPS_SIM_ABIX32 model.
@@ -402,6 +428,7 @@ _C_LABEL(x):
#define PTR_SUBIU subu
#define PTR_L lw
#define PTR_LA la
+#define PTR_LI li
#define PTR_S sw
#define PTR_SLL sll
#define PTR_SLLV sllv
@@ -424,6 +451,7 @@ _C_LABEL(x):
#define PTR_SUBIU dsubu
#define PTR_L ld
#define PTR_LA dla
+#define PTR_LI dli
#define PTR_S sd
#define PTR_SLL dsll
#define PTR_SLLV dsllv
@@ -765,7 +793,7 @@ _C_LABEL(x):
#endif
#define GET_CPU_PCPU(reg) \
- lw reg, _C_LABEL(pcpup);
+ PTR_L reg, _C_LABEL(pcpup);
/*
* Description of the setjmp buffer
diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h
index ccaeb34..2ab347b 100644
--- a/sys/mips/include/bus.h
+++ b/sys/mips/include/bus.h
@@ -713,6 +713,8 @@ void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \
#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
#define BUS_SPACE_MAXSIZE 0xFFFFFFFF
+#define BUS_SPACE_UNRESTRICTED (~0)
+
/*
* declare generic bus space, it suits all needs in
*/
diff --git a/sys/mips/include/clock.h b/sys/mips/include/clock.h
index 62b5112..7dbf4ab 100644
--- a/sys/mips/include/clock.h
+++ b/sys/mips/include/clock.h
@@ -34,6 +34,14 @@ void mips_timer_init_params(uint64_t, int);
extern uint64_t counter_freq;
extern int clocks_running;
+/*
+ * The 'platform_timecounter' pointer may be used to register a
+ * platform-specific timecounter.
+ *
+ * A default timecounter based on the CP0 COUNT register is always registered.
+ */
+extern struct timecounter *platform_timecounter;
+
#endif
#endif /* !_MACHINE_CLOCK_H_ */
diff --git a/sys/mips/include/cpu.h b/sys/mips/include/cpu.h
index 5a1cb9d..83b6a85 100644
--- a/sys/mips/include/cpu.h
+++ b/sys/mips/include/cpu.h
@@ -47,25 +47,10 @@
#ifndef _MACHINE_CPU_H_
#define _MACHINE_CPU_H_
-#include <machine/psl.h>
#include <machine/endian.h>
-#define MIPS_CACHED_MEMORY_ADDR 0x80000000
-#define MIPS_UNCACHED_MEMORY_ADDR 0xa0000000
-#define MIPS_MAX_MEM_ADDR 0xbe000000
-#define MIPS_RESERVED_ADDR 0xbfc80000
-
#define MIPS_KSEG0_LARGEST_PHYS 0x20000000
-#define MIPS_CACHED_TO_PHYS(x) ((uintptr_t)(x) & 0x1fffffff)
-#define MIPS_PHYS_TO_CACHED(x) ((uintptr_t)(x) | MIPS_CACHED_MEMORY_ADDR)
-#define MIPS_UNCACHED_TO_PHYS(x) ((uintptr_t)(x) & 0x1fffffff)
-#define MIPS_PHYS_TO_UNCACHED(x) ((uintptr_t)(x) | MIPS_UNCACHED_MEMORY_ADDR)
-
#define MIPS_PHYS_MASK (0x1fffffff)
-#define MIPS_PA_2_K1VA(x) (MIPS_KSEG1_START | ((x) & MIPS_PHYS_MASK))
-
-#define MIPS_VA_TO_CINDEX(x) ((uintptr_t)(x) & 0xffffff | MIPS_CACHED_MEMORY_ADDR)
-#define MIPS_CACHED_TO_UNCACHED(x) (MIPS_PHYS_TO_UNCACHED(MIPS_CACHED_TO_PHYS(x)))
#define MIPS_PHYS_TO_KSEG0(x) ((uintptr_t)(x) | MIPS_KSEG0_START)
#define MIPS_PHYS_TO_KSEG1(x) ((uintptr_t)(x) | MIPS_KSEG1_START)
@@ -348,6 +333,7 @@
#define cpu_swapout(p) panic("cpu_swapout: can't get here");
#ifndef _LOCORE
+#include <machine/cpufunc.h>
#include <machine/frame.h>
/*
* Arguments to hardclock and gatherstats encapsulate the previous
@@ -356,7 +342,6 @@
#define clockframe trapframe /* Use normal trap frame */
#define CLKF_USERMODE(framep) ((framep)->sr & SR_KSU_USER)
-#define CLKF_BASEPRI(framep) ((framep)->cpl == 0)
#define CLKF_PC(framep) ((framep)->pc)
#define CLKF_INTR(framep) (0)
#define MIPS_CLKF_INTR() (intr_nesting_level >= 1)
@@ -365,6 +350,11 @@
#define cpu_getstack(td) ((td)->td_frame->sp)
/*
+ * A machine-independent interface to the CPU's counter.
+ */
+#define get_cyclecount() mips_rd_count()
+
+/*
* CPU identification, from PRID register.
*/
union cpuprid {
@@ -468,13 +458,9 @@ extern union cpuprid fpu_id;
struct tlb;
struct user;
-u_int32_t mips_cp0_config1_read(void);
int Mips_ConfigCache(void);
void Mips_SetWIRED(int);
void Mips_SetPID(int);
-u_int Mips_GetCOUNT(void);
-void Mips_SetCOMPARE(u_int);
-u_int Mips_GetCOMPARE(void);
void Mips_SyncCache(void);
void Mips_SyncDCache(vm_offset_t, int);
@@ -556,18 +542,6 @@ extern int intr_nesting_level;
* Low level access routines to CPU registers
*/
-void setsoftintr0(void);
-void clearsoftintr0(void);
-void setsoftintr1(void);
-void clearsoftintr1(void);
-
-
-u_int32_t mips_cp0_status_read(void);
-void mips_cp0_status_write(u_int32_t);
-
-int disableintr(void);
-void restoreintr(int);
-int enableintr(void);
int Mips_TLBGetPID(void);
void swi_vm(void *);
@@ -576,7 +550,6 @@ void cpu_reset(void);
u_int32_t set_intr_mask(u_int32_t);
u_int32_t get_intr_mask(void);
-u_int32_t get_cyclecount(void);
#define cpu_spinwait() /* nothing */
diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h
index cd4d3e5..6520671 100644
--- a/sys/mips/include/cpufunc.h
+++ b/sys/mips/include/cpufunc.h
@@ -1,5 +1,29 @@
/* $OpenBSD: pio.h,v 1.2 1998/09/15 10:50:12 pefo Exp $ */
+/*-
+ * Copyright (c) 2002-2004 Juli Mallett. 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.
+ */
/*
* Copyright (c) 1995-1999 Per Fogelstrom. All rights reserved.
*
@@ -59,14 +83,16 @@ mips_barrier(void)
}
static __inline void
+mips_cp0_sync(void)
+{
+ __asm __volatile (__XSTRING(COP0_SYNC));
+}
+
+static __inline void
mips_wbflush(void)
{
__asm __volatile ("sync" : : : "memory");
mips_barrier();
-#if 0
- __asm __volatile("mtc0 %0, $12\n" /* MIPS_COP_0_STATUS */
- : : "r" (flag));
-#endif
}
static __inline void
@@ -82,54 +108,7 @@ mips_write_membar(void)
}
#ifdef _KERNEL
-
-static __inline void
-mips_tlbp(void)
-{
- __asm __volatile ("tlbp");
- mips_barrier();
-#if 0
- register_t ret;
- register_t tmp;
-
- __asm __volatile("mfc0 %0, $12\n" /* MIPS_COP_0_STATUS */
- "and %1, %0, $~1\n" /* MIPS_SR_INT_IE */
- "mtc0 %1, $12\n" /* MIPS_COP_0_STATUS */
- : "=r" (ret), "=r" (tmp));
- return (ret);
-#endif
-}
-
-static __inline void
-mips_tlbr(void)
-{
- __asm __volatile ("tlbr");
- mips_barrier();
-}
-
-static __inline void
-mips_tlbwi(void)
-{
- __asm __volatile ("tlbwi");
- mips_barrier();
-#if 0
- __asm __volatile("mfc %0, $12\n" /* MIPS_COP_0_STATUS */
- "or %0, %0, $1\n" /* MIPS_SR_INT_IE */
- "mtc0 %0, $12\n" /* MIPS_COP_0_STATUS */
- : "=r" (tmp));
-#endif
-}
-
-static __inline void
-mips_tlbwr(void)
-{
- __asm __volatile ("tlbwr");
- mips_barrier();
-}
-
-
-#if 0 /* XXX mips64 */
-
+#if defined(__mips_n32) || defined(__mips_n64)
#define MIPS_RDRW64_COP0(n,r) \
static __inline uint64_t \
mips_rd_ ## n (void) \
@@ -152,10 +131,12 @@ mips_wr_ ## n (uint64_t a0) \
mips_barrier(); \
} struct __hack
+#if defined(__mips_n64)
MIPS_RDRW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0);
MIPS_RDRW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
MIPS_RDRW64_COP0(entryhi, MIPS_COP_0_TLB_HI);
MIPS_RDRW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+#endif
MIPS_RDRW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT);
#undef MIPS_RDRW64_COP0
@@ -185,7 +166,7 @@ mips_wr_ ## n (uint32_t a0) \
#define MIPS_RDRW32_COP0_SEL(n,r,s) \
static __inline uint32_t \
-mips_rd_ ## n ## s(void) \
+mips_rd_ ## n(void) \
{ \
int v0; \
__asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \
@@ -194,7 +175,7 @@ mips_rd_ ## n ## s(void) \
return (v0); \
} \
static __inline void \
-mips_wr_ ## n ## s(uint32_t a0) \
+mips_wr_ ## n(uint32_t a0) \
{ \
__asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \
__XSTRING(COP0_SYNC)";" \
@@ -220,9 +201,9 @@ static __inline void mips_sync_icache (void)
MIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE);
MIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG);
-MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 1);
-MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 2);
-MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 3);
+MIPS_RDRW32_COP0_SEL(config1, MIPS_COP_0_CONFIG, 1);
+MIPS_RDRW32_COP0_SEL(config2, MIPS_COP_0_CONFIG, 2);
+MIPS_RDRW32_COP0_SEL(config3, MIPS_COP_0_CONFIG, 3);
MIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT);
MIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX);
MIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED);
@@ -230,20 +211,29 @@ MIPS_RDRW32_COP0(cause, MIPS_COP_0_CAUSE);
MIPS_RDRW32_COP0(status, MIPS_COP_0_STATUS);
/* XXX: Some of these registers are specific to MIPS32. */
+#if !defined(__mips_n64)
MIPS_RDRW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0);
MIPS_RDRW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
-MIPS_RDRW32_COP0(entrylow, MIPS_COP_0_TLB_LOW);
MIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI);
MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+#endif
MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID);
+/* XXX 64-bit? */
+MIPS_RDRW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1);
MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO);
-MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1);
-MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2);
-MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 3);
+MIPS_RDRW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1);
+MIPS_RDRW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2);
+MIPS_RDRW32_COP0_SEL(watchlo3, MIPS_COP_0_WATCH_LO, 3);
MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI);
-MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 1);
-MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 2);
-MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 3);
+MIPS_RDRW32_COP0_SEL(watchhi1, MIPS_COP_0_WATCH_HI, 1);
+MIPS_RDRW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2);
+MIPS_RDRW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3);
+
+MIPS_RDRW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0);
+MIPS_RDRW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1);
+MIPS_RDRW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2);
+MIPS_RDRW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3);
+
#undef MIPS_RDRW32_COP0
static __inline register_t
@@ -254,7 +244,7 @@ intr_disable(void)
s = mips_rd_status();
mips_wr_status(s & ~MIPS_SR_INT_IE);
- return (s);
+ return (s & MIPS_SR_INT_IE);
}
static __inline register_t
@@ -268,7 +258,13 @@ intr_enable(void)
return (s);
}
-#define intr_restore(s) mips_wr_status((s))
+static __inline void
+intr_restore(register_t ie)
+{
+ if (ie == MIPS_SR_INT_IE) {
+ intr_enable();
+ }
+}
static __inline void
breakpoint(void)
@@ -276,6 +272,35 @@ breakpoint(void)
__asm __volatile ("break");
}
+#if defined(__GNUC__) && !defined(__mips_o32)
+static inline uint64_t
+mips3_ld(const volatile uint64_t *va)
+{
+ uint64_t rv;
+
+#if defined(_LP64)
+ rv = *va;
+#else
+ __asm volatile("ld %0,0(%1)" : "=d"(rv) : "r"(va));
+#endif
+
+ return (rv);
+}
+
+static inline void
+mips3_sd(volatile uint64_t *va, uint64_t v)
+{
+#if defined(_LP64)
+ *va = v;
+#else
+ __asm volatile("sd %0,0(%1)" :: "r"(v), "r"(va));
+#endif
+}
+#else
+uint64_t mips3_ld(volatile uint64_t *va);
+void mips3_sd(volatile uint64_t *, uint64_t);
+#endif /* __GNUC__ */
+
#endif /* _KERNEL */
#define readb(va) (*(volatile uint8_t *) (va))
diff --git a/sys/mips/include/cpuinfo.h b/sys/mips/include/cpuinfo.h
index 4378c6a..53b966c 100644
--- a/sys/mips/include/cpuinfo.h
+++ b/sys/mips/include/cpuinfo.h
@@ -56,6 +56,7 @@ struct mips_cpuinfo {
u_int8_t tlb_type;
u_int16_t tlb_nentries;
u_int8_t icache_virtual;
+ boolean_t cache_coherent_dma;
struct {
u_int32_t ic_size;
u_int8_t ic_linesize;
@@ -68,52 +69,7 @@ struct mips_cpuinfo {
} l1;
};
-/* TODO: Merge above structure with NetBSD's below. */
-
-struct cpu_info {
-#ifdef notyet
- struct schedstate_percpu ci_schedstate; /* scheduler state */
-#endif
- u_long ci_cpu_freq; /* CPU frequency */
- u_long ci_cycles_per_hz; /* CPU freq / hz */
- u_long ci_divisor_delay; /* for delay/DELAY */
- u_long ci_divisor_recip; /* scaled reciprocal of previous;
- see below */
-#if defined(DIAGNOSTIC) || defined(LOCKDEBUG)
- u_long ci_spin_locks; /* # of spin locks held */
- u_long ci_simple_locks; /* # of simple locks held */
-#endif
-};
-
-/*
- * To implement a more accurate microtime using the CP0 COUNT register
- * we need to divide that register by the number of cycles per MHz.
- * But...
- *
- * DIV and DIVU are expensive on MIPS (eg 75 clocks on the R4000). MULT
- * and MULTU are only 12 clocks on the same CPU.
- *
- * The strategy we use is to calculate the reciprical of cycles per MHz,
- * scaled by 1<<32. Then we can simply issue a MULTU and pluck of the
- * HI register and have the results of the division.
- */
-#define MIPS_SET_CI_RECIPRICAL(cpu) \
-do { \
- KASSERT((cpu)->ci_divisor_delay != 0, ("divisor delay")); \
- (cpu)->ci_divisor_recip = 0x100000000ULL / (cpu)->ci_divisor_delay; \
-} while (0)
-
-#define MIPS_COUNT_TO_MHZ(cpu, count, res) \
- __asm __volatile ("multu %1,%2 ; mfhi %0" \
- : "=r"((res)) : "r"((count)), "r"((cpu)->ci_divisor_recip))
-
-
-extern struct cpu_info cpu_info_store;
-
-#if 0
-#define curcpu() (&cpu_info_store)
-#define cpu_number() (0)
-#endif
+extern struct mips_cpuinfo cpuinfo;
#endif /* !LOCORE */
#endif /* _KERNEL */
diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h
index f1f2485..3f4ffd2 100644
--- a/sys/mips/include/cpuregs.h
+++ b/sys/mips/include/cpuregs.h
@@ -78,27 +78,36 @@
* Caching of mapped addresses is controlled by bits in the TLB entry.
*/
-#define MIPS_KUSEG_START 0x0
-#define MIPS_KSEG0_START 0x80000000
-#define MIPS_KSEG0_END 0x9fffffff
-#define MIPS_KSEG1_START 0xa0000000
-#define MIPS_KSEG1_END 0xbfffffff
-#define MIPS_KSSEG_START 0xc0000000
-#define MIPS_KSSEG_END 0xdfffffff
+#if !defined(_LOCORE)
+#define MIPS_KUSEG_START 0x00000000
+#define MIPS_KSEG0_START ((intptr_t)(int32_t)0x80000000)
+#define MIPS_KSEG0_END ((intptr_t)(int32_t)0x9fffffff)
+#define MIPS_KSEG1_START ((intptr_t)(int32_t)0xa0000000)
+#define MIPS_KSEG1_END ((intptr_t)(int32_t)0xbfffffff)
+#define MIPS_KSSEG_START ((intptr_t)(int32_t)0xc0000000)
+#define MIPS_KSSEG_END ((intptr_t)(int32_t)0xdfffffff)
+#define MIPS_KSEG3_START ((intptr_t)(int32_t)0xe0000000)
+#define MIPS_KSEG3_END ((intptr_t)(int32_t)0xffffffff)
+
#define MIPS_KSEG2_START MIPS_KSSEG_START
#define MIPS_KSEG2_END MIPS_KSSEG_END
-#define MIPS_KSEG3_START 0xe0000000
-#define MIPS_KSEG3_END 0xffffffff
-#define MIPS_MAX_MEM_ADDR 0xbe000000
-#define MIPS_RESERVED_ADDR 0xbfc80000
+#endif
-/* Map virtual address to index in mips3 r4k virtually-indexed cache */
-#define MIPS3_VA_TO_CINDEX(x) \
- ((unsigned)(x) & 0xffffff | MIPS_KSEG0_START)
+#define MIPS_XKPHYS_START 0x8000000000000000
+#define MIPS_XKPHYS_END 0xbfffffffffffffff
+
+#define MIPS_XKPHYS_CCA_UC 0x02 /* Uncached. */
+#define MIPS_XKPHYS_CCA_CNC 0x03 /* Cacheable non-coherent. */
#define MIPS_PHYS_TO_XKPHYS(cca,x) \
((0x2ULL << 62) | ((unsigned long long)(cca) << 59) | (x))
-#define MIPS_XKPHYS_TO_PHYS(x) ((x) & 0x0effffffffffffffULL)
+#define MIPS_XKPHYS_TO_PHYS(x) ((x) & 0x07ffffffffffffffULL)
+
+#define MIPS_XUSEG_START 0x0000000000000000
+#define MIPS_XUSEG_END 0x0000010000000000
+
+#define MIPS_XKSEG_START 0xc000000000000000
+#define MIPS_XKSEG_END 0xc00000ff80000000
/* CPU dependent mtc0 hazard hook */
#ifdef TARGET_OCTEON
@@ -477,7 +486,6 @@
* (3=32bit, 6=64bit, i=impl dep)
* 0 MIPS_COP_0_TLB_INDEX 3333 TLB Index.
* 1 MIPS_COP_0_TLB_RANDOM 3333 TLB Random.
- * 2 MIPS_COP_0_TLB_LOW 3... r3k TLB entry low.
* 2 MIPS_COP_0_TLB_LO0 .636 r4k TLB entry low.
* 3 MIPS_COP_0_TLB_LO1 .636 r4k TLB entry low, extended.
* 4 MIPS_COP_0_TLB_CONTEXT 3636 TLB Context.
@@ -537,10 +545,6 @@
#define MIPS_COP_0_EXC_PC _(14)
#define MIPS_COP_0_PRID _(15)
-
-/* MIPS-I */
-#define MIPS_COP_0_TLB_LOW _(2)
-
/* MIPS-III */
#define MIPS_COP_0_TLB_LO0 _(2)
#define MIPS_COP_0_TLB_LO1 _(3)
@@ -583,6 +587,8 @@
#define MIPS_CONFIG1_TLBSZ_MASK 0x7E000000 /* bits 30..25 # tlb entries minus one */
#define MIPS_CONFIG1_TLBSZ_SHIFT 25
+#define MIPS_MAX_TLB_ENTRIES 64
+
#define MIPS_CONFIG1_IS_MASK 0x01C00000 /* bits 24..22 icache sets per way */
#define MIPS_CONFIG1_IS_SHIFT 22
#define MIPS_CONFIG1_IL_MASK 0x00380000 /* bits 21..19 icache line size */
diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h
index ea97120..f0a84d2 100644
--- a/sys/mips/include/db_machdep.h
+++ b/sys/mips/include/db_machdep.h
@@ -38,7 +38,6 @@
#define _MIPS_DB_MACHDEP_H_
#include <machine/frame.h>
-#include <machine/psl.h>
#include <machine/trap.h>
#include <machine/endian.h>
@@ -92,7 +91,6 @@ db_addr_t next_instr_address(db_addr_t, boolean_t);
#define DB_SMALL_VALUE_MIN (-0x400001)
int db_inst_type(int);
-void db_dump_tlb(int, int);
db_addr_t branch_taken(int inst, db_addr_t pc);
void stacktrace_subr(register_t pc, register_t sp, register_t ra, int (*)(const char *, ...));
int kdbpeek(int *);
diff --git a/sys/mips/include/defs.h b/sys/mips/include/defs.h
deleted file mode 100644
index 20d093e..0000000
--- a/sys/mips/include/defs.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (c) 1996, 2001-2003, 2005, Juniper Networks, Inc.
- * All rights reserved.
- *
- * defs.h -- Simple universal types and definitions for use by the microkernel
- * Jim Hayes, November 1996
- *
- * JNPR: defs.h,v 1.3.2.1 2007/09/10 08:16:32 girish
- * $FreeBSD$
- */
-
-#ifndef __DEFS_H__
-#define __DEFS_H__
-
-/*
- * Paranoid compilation. If defined, the PARANOID flag will enable asserts,
- * data structure magic stamping and a suite of other debug tools. To disable
- * it, comment out its definition.
- */
-#define PARANOID
-
-/*
- * This is the ONLY place you should see hardware specific information
- * encoded as #ifdefs. (Well, except for stdarg.h, perhaps.)
- * I apologize in advance!
- */
-#include <machine/defs_mips.h>
-#define CPU_GOT_ONE
-
-#if !defined(CPU_GOT_ONE)
-#error "YOU NEED TO SPECIFY ONE CPU TYPE TO USE THIS FILE"
-#endif
-
-#ifdef TRUE
-#undef TRUE
-#endif
-
-#ifdef FALSE
-#undef FALSE
-#endif
-
-typedef enum boolean_
-{
- FALSE = 0,
- TRUE = 1
-} boolean;
-
-/*
- * Make NULL a pointer within the microkernel environment to catch
- * pointer semantic miscreants.
- *
- * The reason it's conditional here is that some of the BSD includes
- * define it multiple times as a straight integer and GCC barfs on
- * the alternative prototypes.
- */
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-/*
- * Define some standard sized types. (Defined in cpu-specific type files
- * included above.)
- */
-
-#define MAX_U8 255
-#define MAX_S8 128
-#define MIN_S8 -127
-
-#define MAX_U16 0xffff
-#define MIN_S16 ((int16_t)(1 << 15))
-#define MAX_S16 ((int16_t)~MIN_S16)
-
-#define MAX_U32 0xffffffff
-#define MIN_S32 ((int32_t)(1 << 31))
-#define MAX_S32 ((int32_t)~MIN_S32)
-
-#define MAX_U64 ((u_int64_t)0 - 1)
-#define MAX_S64 ((int64_t)(MAX_U64 >> 1))
-#define MIN_S64 (-MAX_S64-1)
-
-/*
- * Solaris uses _SIZE_T to mark the fact that "size_t" has already
- * been defined. _SYS_TYPES_H_ is used by BSD.
- *
- */
-#if !defined(_SYS_TYPES_H_) && !defined(_SIZE_T)
-typedef UNSIGNED_32 size_t;
-#define _SIZE_T
-#endif
-
-#if !defined(_SYS_TYPES_H_)
-typedef char * caddr_t;
-
-typedef UNSIGNED_8 u_int8_t;
-typedef SIGNED_8 int8_t;
-
-typedef UNSIGNED_16 u_int16_t;
-typedef SIGNED_16 int16_t;
-
-typedef UNSIGNED_32 u_int32_t;
-typedef SIGNED_32 int32_t;
-
-typedef UNSIGNED_64 u_int64_t;
-typedef SIGNED_64 int64_t;
-
-typedef UNSIGNED_32 u_long;
-typedef UNSIGNED_16 u_short;
-typedef UNSIGNED_8 u_char;
-
-
-/*
- * Define the standard terminology used in the diag software
- * with regards to bytes, words, etc.
- * BYTE = 8 bits
- * HWORD (halfword) = 2 bytes or 16 bits
- * WORD = 4 bytes or 32 bits
- * QUAD = 8 bytes or 64 bits
- *
- * (The term QUAD seems less-than-intuitive here, but it is
- * derived from BSD sources where it is defined as int64_t.)
- *
- * For consistency use the following defines wherever appropriate.
- */
-
-typedef enum {
- NBI_BYTE = (sizeof(u_int8_t) * 8),
- NBI_HWORD = (sizeof(u_int16_t) * 8),
- NBI_WORD = (sizeof(u_int32_t) * 8),
- NBI_QUAD = (sizeof(u_int64_t) * 8)
-} num_bits_t;
-
-typedef enum {
- NBY_BYTE = sizeof(u_int8_t),
- NBY_HWORD = sizeof(u_int16_t),
- NBY_WORD = sizeof(u_int32_t),
- NBY_QUAD = sizeof(u_int64_t)
-} num_bytes_t;
-
-/*
- * We assume that pid values are 16 bit integers
- */
-
-typedef u_int16_t pid_t;
-
-#endif /* _SYS_TYPES_H_ */
-
-typedef UNSIGNED_32 magic_t;
-typedef int status_t;
-
-#define BITS_IN_BYTE 8
-
-/*
- * Packed definition. We use this for fields in network frames where we
- * don't want the compiler to pack out to even alignment
- */
-
-#ifdef PACKED
-#undef PACKED
-#endif
-#define PACKED(x) x __attribute__ ((packed))
-
-/*
- * __unused is a FreeBSDism that prevents the compiler from choking
- * on function parameters that remain unused through the life of a
- * function. This is not an issue for the Cygnus toolchain. In general
- * it SHOULD NOT BE USED in the martini embedded software repository.
- * It should only be used inside of shared code.
- */
-#ifndef __unused
-#define __unused __attribute__ ((__unused__))
-#endif
-
-/*
- * Basic memory multiples
- */
-
-#define SIZE_1K 0x00000400
-#define SIZE_2K 0x00000800
-#define SIZE_4K 0x00001000
-#define SIZE_8K 0x00002000
-#define SIZE_16K 0x00004000
-#define SIZE_32K 0x00008000
-#define SIZE_64K 0x00010000
-#define SIZE_128K 0x00020000
-#define SIZE_256K 0x00040000
-#define SIZE_512K 0x00080000
-#define SIZE_1M 0x00100000
-#define SIZE_2M 0x00200000
-#define SIZE_4M 0x00400000
-#define SIZE_8M 0x00800000
-#define SIZE_16M 0x01000000
-#define SIZE_32M 0x02000000
-#define SIZE_64M 0x04000000
-#define SIZE_128M 0x08000000
-#define SIZE_256M 0x10000000
-#define SIZE_512M 0x20000000
-#define SIZE_1G 0x40000000
-#define SIZE_2G 0x80000000
-
-/*
- * swap16_inline
- * swap32_inline
- *
- * Byteswap a 16 and 32 bit quantities
- */
-
-static inline u_int16_t
-swap16_inline(u_int16_t data)
-{
- return(((data & 0x00ff) << 8) |
- ((data & 0xff00) >> 8));
-}
-
-static inline u_int32_t
-swap32_inline(u_int32_t data)
-{
- return(((data & 0x000000ff) << 24) |
- ((data & 0x0000ff00) << 8) |
- ((data & 0x00ff0000) >> 8) |
- ((data & 0xff000000) >> 24));
-}
-
-/*
- * Define errno_t here as it is needed by the rom and ukernel
- */
-typedef u_int32_t errno_t;
-
-#define EOK 0
-
-/*
- * Define the main communication structure used for passing
- * information from the rom to the ukernel (done here as it is
- * used by them both)
- */
-typedef struct rom_info_ rom_info_t;
-
-/*
- * Typedef the return code from the ukernel to the ROM
- */
-typedef u_int32_t rom_return_t;
-
-/*
- * Pull in the relevant global environment header file
- *
- * This file is shared by the uKernel and the system simulation effort.
- */
-#if defined(ENV_UKERN) || defined (ENV_SYS_SIM)
-#include "ukern.h"
-#endif /* ENV_UKERN */
-
-#if defined(ENV_ROM)
-#include "rom.h"
-#endif
-
-#endif /* __DEFS_H__ */
diff --git a/sys/mips/include/kdb.h b/sys/mips/include/kdb.h
index cd8c618..6ca6654 100644
--- a/sys/mips/include/kdb.h
+++ b/sys/mips/include/kdb.h
@@ -32,6 +32,8 @@
#include <machine/frame.h>
+#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
+
static __inline void
kdb_cpu_clear_singlestep(void)
{
diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h
index 8edd48e..06cdeac 100644
--- a/sys/mips/include/param.h
+++ b/sys/mips/include/param.h
@@ -46,9 +46,7 @@
#include <sys/cdefs.h>
#ifdef _KERNEL
-#ifdef _LOCORE
-#include <machine/psl.h>
-#else
+#ifndef _LOCORE
#include <machine/cpu.h>
#endif
#endif
@@ -102,46 +100,28 @@
#define CACHE_LINE_SHIFT 6
#define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT)
-#define NBPG 4096 /* bytes/page */
-#define PGOFSET (NBPG-1) /* byte offset into page */
-#define PGSHIFT 12 /* LOG2(NBPG) */
-
#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */
#define PAGE_SIZE (1<<PAGE_SHIFT) /* bytes/page */
#define PAGE_MASK (PAGE_SIZE-1)
#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
-
-#define NBSEG 0x400000 /* bytes/segment */
-#define SEGOFSET (NBSEG-1) /* byte offset into segment */
-#define SEGSHIFT 22 /* LOG2(NBSEG) */
+#define NPDEPG (PAGE_SIZE/(sizeof (pd_entry_t)))
#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
-/* XXXimp: This has moved to vmparam.h */
-/* Also, this differs from the mips2 definition, but likely is better */
-/* since this means the kernel won't chew up TLBs when it is executing */
-/* code */
-#define KERNBASE 0x80000000 /* start of kernel virtual */
-#define BTOPKERNBASE ((u_long)KERNBASE >> PGSHIFT)
-
#define BLKDEV_IOSIZE 2048 /* xxx: Why is this 1/2 page? */
#define MAXDUMPPGS 1 /* xxx: why is this only one? */
/*
- * NOTE: In FreeBSD, Uarea's don't have a fixed address.
- * Therefore, any code imported from OpenBSD which depends on
- * UADDR, UVPN and KERNELSTACK requires porting.
- * XXX: 3 stack pages? Not 4 which would be more efficient from a tlb
- * XXX: point of view.
+ * The kernel stack needs to be aligned on a (PAGE_SIZE * 2) boundary.
*/
-#define KSTACK_PAGES 3 /* kernel stack*/
-#define KSTACK_GUARD_PAGES 0 /* pages of kstack guard; 0 disables */
+#define KSTACK_PAGES 2 /* kernel stack*/
+#define KSTACK_GUARD_PAGES 2 /* pages of kstack guard; 0 disables */
#define UPAGES 2
/* pages ("clicks") (4096 bytes) to disk blocks */
-#define ctod(x) ((x) << (PGSHIFT - DEV_BSHIFT))
-#define dtoc(x) ((x) >> (PGSHIFT - DEV_BSHIFT))
+#define ctod(x) ((x) << (PAGE_SHIFT - DEV_BSHIFT))
+#define dtoc(x) ((x) >> (PAGE_SHIFT - DEV_BSHIFT))
/*
* Map a ``block device block'' to a file system block.
@@ -152,18 +132,18 @@
#define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
/*
- * Conversion macros
+ * Mach derived conversion macros
*/
-#define mips_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1))
-#define mips_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1))
-#define mips_btop(x) ((unsigned long)(x) >> PGSHIFT)
-#define mips_ptob(x) ((unsigned long)(x) << PGSHIFT)
-#define round_page mips_round_page
-#define trunc_page mips_trunc_page
-#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT)
-#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT)
-
-#define pgtok(x) ((x) * (PAGE_SIZE / 1024))
+#define round_page(x) (((unsigned long)(x) + PAGE_MASK) & ~PAGE_MASK)
+#define trunc_page(x) ((unsigned long)(x) & ~PAGE_MASK)
+
+#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT)
+
+#define mips_btop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define mips_ptob(x) ((unsigned long)(x) << PAGE_SHIFT)
+
+#define pgtok(x) ((unsigned long)(x) * (PAGE_SIZE / 1024))
#ifndef _KERNEL
#define DELAY(n) { register int N = (n); while (--N > 0); }
diff --git a/sys/mips/include/pcb.h b/sys/mips/include/pcb.h
index f95ef4d..e0982e3 100644
--- a/sys/mips/include/pcb.h
+++ b/sys/mips/include/pcb.h
@@ -51,7 +51,7 @@ struct pcb
{
struct trapframe pcb_regs; /* saved CPU and registers */
__register_t pcb_context[14]; /* kernel context for resume */
- int pcb_onfault; /* for copyin/copyout faults */
+ void *pcb_onfault; /* for copyin/copyout faults */
register_t pcb_tpc;
};
diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h
index eedd4f3..80772d9 100644
--- a/sys/mips/include/pmap.h
+++ b/sys/mips/include/pmap.h
@@ -160,14 +160,8 @@ typedef struct pv_entry {
extern vm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2];
extern vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2];
-extern char *ptvmmap; /* poor name! */
extern vm_offset_t virtual_avail;
extern vm_offset_t virtual_end;
-extern pd_entry_t *segbase;
-
-extern vm_paddr_t mips_wired_tlb_physmem_start;
-extern vm_paddr_t mips_wired_tlb_physmem_end;
-extern u_int need_wired_tlb_page_pool;
#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
@@ -189,35 +183,9 @@ void pmap_update_page(pmap_t pmap, vm_offset_t va, pt_entry_t pte);
void pmap_flush_pvcache(vm_page_t m);
/*
- * floating virtual pages (FPAGES)
- *
- * These are the reserved virtual memory areas which can be
- * mapped to any physical memory.
+ * Function to save TLB contents so that they may be inspected in the debugger.
*/
-#define FPAGES 2
-#define FPAGES_SHARED 2
-#define FSPACE ((FPAGES * MAXCPU + FPAGES_SHARED) * PAGE_SIZE)
-#define PMAP_FPAGE1 0x00 /* Used by pmap_zero_page &
- * pmap_copy_page */
-#define PMAP_FPAGE2 0x01 /* Used by pmap_copy_page */
-
-#define PMAP_FPAGE3 0x00 /* Used by pmap_zero_page_idle */
-#define PMAP_FPAGE_KENTER_TEMP 0x01 /* Used by coredump */
-
-struct fpage {
- vm_offset_t kva;
- u_int state;
-};
-
-struct sysmaps {
- struct mtx lock;
- struct fpage fp[FPAGES];
-};
-
-vm_offset_t
-pmap_map_fpage(vm_paddr_t pa, struct fpage *fp,
- boolean_t check_unmaped);
-void pmap_unmap_fpage(vm_paddr_t pa, struct fpage *fp);
+extern void pmap_save_tlb(void);
#endif /* _KERNEL */
diff --git a/sys/mips/include/pmc_mdep.h b/sys/mips/include/pmc_mdep.h
index 46639544..658641a 100644
--- a/sys/mips/include/pmc_mdep.h
+++ b/sys/mips/include/pmc_mdep.h
@@ -8,17 +8,31 @@
#ifndef _MACHINE_PMC_MDEP_H_
#define _MACHINE_PMC_MDEP_H_
+#define PMC_MDEP_CLASS_INDEX_MIPS24K 0
+#include <dev/hwpmc/hwpmc_mips24k.h>
+
union pmc_md_op_pmcallocate {
uint64_t __pad[4];
};
/* Logging */
-#define PMCLOG_READADDR PMCLOG_READ64
-#define PMCLOG_EMITADDR PMCLOG_EMIT64
+#define PMCLOG_READADDR PMCLOG_READ32
+#define PMCLOG_EMITADDR PMCLOG_EMIT32
#if _KERNEL
union pmc_md_pmc {
+ struct pmc_md_mips24k_pmc pm_mips24k;
};
-#endif
+#define PMC_TRAPFRAME_TO_PC(TF) ((TF)->pc)
+#define PMC_TRAPFRAME_TO_FP(TF) ((TF)->tf_usr_lr)
+#define PMC_TRAPFRAME_TO_SP(TF) ((TF)->tf_usr_sp)
+
+/*
+ * Prototypes
+ */
+struct pmc_mdep *pmc_mips24k_initialize(void);
+void pmc_mips24k_finalize(struct pmc_mdep *_md);
+#endif /* _KERNEL */
+
#endif /* !_MACHINE_PMC_MDEP_H_ */
diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h
index 99dab78..1479eda 100644
--- a/sys/mips/include/proc.h
+++ b/sys/mips/include/proc.h
@@ -44,7 +44,7 @@
*/
struct mdthread {
int md_flags; /* machine-dependent flags */
- int md_upte[KSTACK_PAGES - 1]; /* ptes for mapping u pcb */
+ int md_upte[KSTACK_PAGES]; /* ptes for mapping u pcb */
int md_ss_addr; /* single step address for ptrace */
int md_ss_instr; /* single step instruction for ptrace */
register_t md_saved_intr;
@@ -53,7 +53,6 @@ struct mdthread {
int md_pc_ctrl; /* performance counter control */
int md_pc_count; /* performance counter */
int md_pc_spill; /* performance counter spill */
- vm_offset_t md_realstack;
void *md_tls;
};
@@ -69,4 +68,10 @@ struct thread;
void mips_cpu_switch(struct thread *, struct thread *, struct mtx *);
void mips_cpu_throw(struct thread *, struct thread *);
+#ifdef __mips_n64
+#define KINFO_PROC_SIZE 1088
+#else
+#define KINFO_PROC_SIZE 816
+#endif
+
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/mips/include/profile.h b/sys/mips/include/profile.h
index 728a468..6d976d9 100644
--- a/sys/mips/include/profile.h
+++ b/sys/mips/include/profile.h
@@ -84,17 +84,17 @@
#ifdef SMP
extern int mcount_lock;
#define MCOUNT_ENTER(s) { \
- s = disable_intr(); \
+ s = intr_disable(); \
while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1)) \
/* nothing */ ; \
}
#define MCOUNT_EXIT(s) { \
atomic_store_rel_int(&mcount_lock, 0); \
- enableintr(s); \
+ intr_restore(s); \
}
#else
-#define MCOUNT_ENTER(s) { s = disable_intr(); }
-#define MCOUNT_EXIT(s) (enableintr(s))
+#define MCOUNT_ENTER(s) { s = intr_disable(); }
+#define MCOUNT_EXIT(s) (intr_restore(s))
#endif
/* REVISIT for mips */
diff --git a/sys/mips/include/pte.h b/sys/mips/include/pte.h
index db26cbb..e3b46ca 100644
--- a/sys/mips/include/pte.h
+++ b/sys/mips/include/pte.h
@@ -83,7 +83,7 @@ struct tlb {
int tlb_lo1;
};
-typedef unsigned long pt_entry_t;
+typedef unsigned int pt_entry_t;
typedef pt_entry_t *pd_entry_t;
#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
@@ -126,7 +126,7 @@ typedef pt_entry_t *pd_entry_t;
#define pfn_to_vad(x) (((x) & PTE_FRAME) << PTE_SHIFT)
/* User virtual to pte offset in page table */
-#define vad_to_pte_offset(adr) (((adr) >> PGSHIFT) & (NPTEPG -1))
+#define vad_to_pte_offset(adr) (((adr) >> PAGE_SHIFT) & (NPTEPG -1))
#define mips_pg_v(entry) ((entry) & PTE_V)
#define mips_pg_wired(entry) ((entry) & PTE_WIRED)
diff --git a/sys/mips/include/queue.h b/sys/mips/include/queue.h
deleted file mode 100644
index d992332..0000000
--- a/sys/mips/include/queue.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*-
- * Copyright (c) 1996-1997, 2001, 2005, Juniper Networks, Inc.
- * All rights reserved.
- * Jim Hayes, November 1996
- *
- * queue.h - Description of uKernel queues, for the Juniper Kernel
- *
- * JNPR: queue.h,v 1.1 2006/08/07 05:38:57 katta
- * $FreeBSD$
- *
- */
-
-#ifndef __QUEUE_H__
-#define __QUEUE_H__
-
-/*---------------------------------------------------------------------------
- * QUEUE MANAGEMENT DOCUMENTATION
- */
-
-/*
- --------
- Q_INIT()
- --------
-
- void q_init(void)
-
- Initialize the queue management system for the microkernel.
- This initializes the debugging flags and sets up accounting.
-
- ---------
- Q_ALLOC()
- ---------
-
- queue_t *q_alloc()
-
- Allocates a queue from kernel memory, and initializes it for you.
-
- The default initialization provides a queue that is unbounded.
-
- If you want to be bounded with special features, use q_control
- after initialization.
-
- q_alloc() returns NULL in the face of peril or low memory.
-
- --------
- Q_FREE()
- --------
-
- void *q_free(queue_t *queue_pointer)
-
- Returns a queue to kernel memory, and frees the queue contents
- for you using free() and complains (with a traceback) that you
- tried to kill of a non-empty queue.
-
- If any threads are waiting on the queue, wake them up.
-
- -----------
- Q_CONTROL()
- -----------
- void q_control(queue_t *queue_pointer, queue_size_t max_queue_size);
-
- For now, allows you to limit queue growth.
-
- ----------------
- Q_DEQUEUE_WAIT() ** MAY CAUSE THREAD TO BLOCK/CANNOT BE CALLED FROM ISRs **
- ----------------
-
- void *q_dequeue_wait(queue_t *queue_pointer, wakeup_mask_t *mask)
-
- Removes and returns a pointer to the next message in the specified
- queue. If the queue is empty, the calling thread goes to sleep
- until something is queued to the queue. If this call returns NULL,
- then an extraordinary event requires this thread's attention--
- check errno in this case.
-
- ---------
- Q_DEQUEUE ** CAN BE CALLED FROM ISRs **
- ---------
-
- void *q_dequeue(queue_t *queue_pointer)
-
- Just like q_dequeue_wait(), but instead of blocking, return NULL.
-
- -----------
- Q_ENQUEUE() ** CAN BE CALLED FROM ISRs **
- -----------
-
- boolean q_enqueue(queue_t *queue_pointer, void *element_pointer)
-
- Add the element to the end of the named queue. If the add fails
- because a limit has been reached, return TRUE. Otherwise return
- FALSE if everything went OK.
-
- ----------
- Q_URGENT()
- ----------
-
- boolean q_urgent(queue_t *queue_pointer, void *element_pointer)
-
- Same as q_enqueue(), except this element will be placed at the top
- of the queue, and will be picked off at the next q_dequeue_wait()
- operation.
-
- --------
- Q_PEEK() ** CAN BE CALLED FROM ISRs **
- --------
-
- void *q_peek(queue_t *queue_pointer)
-
- Returns a pointer to the top element of the queue without actually
- dequeuing it. Returns NULL of the queue is empty.
-
- This routine will never block.
-
- ----------
- Q_DELETE()
- ----------
-
- void q_delete(queue_t *queue_pointer, void *element_pointer)
-
- Delete the element_pointer from the queue, if it exists. This
- isn't speedy, and isn't meant for tasks requiring performance.
- It's primary use is to pull something off the queue when you know
- in the common case that it's gonna be at or near the top of the
- list. (I.e. waking a thread from a wake list when extraordinary
- conditions exist, and you have to pluck it from the middle of the
- list.)
-
- This routine does not block or return anything.
-
- --------
- Q_SIZE()
- --------
-
- queue_size_t q_size(queue_t *queue_pointer)
-
- Returns the number of elements in the queue.
-
- ------------
- Q_MAX_SIZE()
- ------------
-
- queue_size_t q_max_size(queue_t *queue_pointer);
-
- Returns the maximum size of this queue, or 0 if this queue is
- unbounded.
-
-*/
-
-/*-------------------------------------------------------------------------
- * Basic queue management structures.
- */
-
-/*
- * Typedefs
- */
-
-typedef u_int32_t queue_size_t;
-
-/*
- * Prototypes
- */
-
-void q_init(void);
-queue_t *q_alloc(void);
-void *q_peek(queue_t *queue);
-void *q_dequeue(queue_t *queue);
-boolean q_enqueue(queue_t *queue, void *item);
-boolean q_urgent(queue_t *queue, void *item);
-
-#endif /* __QUEUE_H__ */
diff --git a/sys/mips/include/regnum.h b/sys/mips/include/regnum.h
index baa60bd..1c22bb9 100644
--- a/sys/mips/include/regnum.h
+++ b/sys/mips/include/regnum.h
@@ -42,10 +42,6 @@
#ifndef _MACHINE_REGNUM_H_
#define _MACHINE_REGNUM_H_
-#define STAND_ARG_SIZE 16
-#define STAND_FRAME_SIZE 24
-#define STAND_RA_OFFSET 20
-
/* This must match the numbers
* in pcb.h and is used by
* swtch.S
diff --git a/sys/mips/include/rm7000.h b/sys/mips/include/rm7000.h
deleted file mode 100644
index f1c0c44..0000000
--- a/sys/mips/include/rm7000.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $OpenBSD$ */
-
-/*
- * Copyright (c) 2000 Opsycon Open System Consulting AB (www.opsycon.se)
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Opsycon Open System
- * Consulting AB, Sweden under contract to QED, Inc.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
- *
- * JNPR: rm7000.h,v 1.2.4.1 2007/08/29 12:06:30 girish
- * $FreeBSD$
- */
-
-#ifndef _MACHINE_RM7000_H_
-#define _MACHINE_RM7000_H_
-
-/*
- * QED RM7000 specific defines.
- */
-
-/*
- * Performance counters.
- */
-
-#define PCNT_SRC_CLOCKS 0x00 /* Clock cycles */
-#define PCNT_SRC_INSTR 0x01 /* Total instructions issued */
-#define PCNT_SRC_FPINSTR 0x02 /* Float instructions issued */
-#define PCNT_SRC_IINSTR 0x03 /* Integer instructions issued */
-#define PCNT_SRC_LOAD 0x04 /* Load instructions issued */
-#define PCNT_SRC_STORE 0x05 /* Store instructions issued */
-#define PCNT_SRC_DUAL 0x06 /* Dual issued pairs */
-#define PCNT_SRC_BRPREF 0x07 /* Branch prefetches */
-#define PCNT_SRC_EXTMISS 0x08 /* External cache misses */
-#define PCNT_SRC_STALL 0x09 /* Stall cycles */
-#define PCNT_SRC_SECMISS 0x0a /* Secondary cache misses */
-#define PCNT_SRC_INSMISS 0x0b /* Instruction cache misses */
-#define PCNT_SRC_DTAMISS 0x0c /* Data cache misses */
-#define PCNT_SRC_DTLBMISS 0x0d /* Data TLB misses */
-#define PCNT_SRC_ITLBMISS 0x0e /* Instruction TLB misses */
-#define PCNT_SRC_JTLBIMISS 0x0f /* Joint TLB instruction misses */
-#define PCNT_SRC_JTLBDMISS 0x10 /* Joint TLB data misses */
-#define PCNT_SRC_BRTAKEN 0x11 /* Branches taken */
-#define PCNT_SRC_BRISSUED 0x12 /* Branches issued */
-#define PCNT_SRC_SECWBACK 0x13 /* Secondary cache writebacks */
-#define PCNT_SRC_PRIWBACK 0x14 /* Primary cache writebacks */
-#define PCNT_SRC_DCSTALL 0x15 /* Dcache miss stall cycles */
-#define PCNT_SRC_MISS 0x16 /* Cache misses */
-#define PCNT_SRC_FPEXC 0x17 /* FP possible execption cycles */
-#define PCNT_SRC_MULSLIP 0x18 /* Slip cycles due to mult. busy */
-#define PCNT_SRC_CP0SLIP 0x19 /* CP0 Slip cycles */
-#define PCNT_SRC_LDSLIP 0x1a /* Slip cycles due to pend. non-b ld */
-#define PCNT_SRC_WBFULL 0x1b /* Write buffer full stall cycles */
-#define PCNT_SRC_CISTALL 0x1c /* Cache instruction stall cycles */
-#define PCNT_SRC_MULSTALL 0x1d /* Multiplier stall cycles */
-#define PCNT_SRC_ELDSTALL 0x1d /* Excepion stall due to non-b ld */
-#define PCNT_SRC_MAX 0x1d /* Maximum PCNT select code */
-
-/*
- * Counter control bits.
- */
-
-#define PCNT_CE 0x0400 /* Count enable */
-#define PCNT_UM 0x0200 /* Count in User mode */
-#define PCNT_KM 0x0100 /* Count in kernel mode */
-
-/*
- * Performance counter system call function codes.
- */
-#define PCNT_FNC_SELECT 0x0001 /* Select counter source */
-#define PCNT_FNC_READ 0x0002 /* Read current value of counter */
-
-#endif /* _MACHINE_RM7000_H_ */
diff --git a/sys/mips/include/sf_buf.h b/sys/mips/include/sf_buf.h
index 0a9980c..b6ee1cc 100644
--- a/sys/mips/include/sf_buf.h
+++ b/sys/mips/include/sf_buf.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003, 2005 Alan L. Cox <alc@cs.rice.edu>
+ * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,29 +23,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: src/sys/i386/include/sf_buf.h,v 1.4 2005/02/13 06:23:13 alc
* $FreeBSD$
*/
#ifndef _MACHINE_SF_BUF_H_
-#define _MACHINE_SF_BUF_H_
+#define _MACHINE_SF_BUF_H_
#include <sys/queue.h>
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
struct vm_page;
struct sf_buf {
- LIST_ENTRY(sf_buf) list_entry; /* list of buffers */
- TAILQ_ENTRY(sf_buf) free_entry; /* list of buffers */
+ SLIST_ENTRY(sf_buf) free_list; /* list of free buffer slots */
struct vm_page *m; /* currently mapped page */
vm_offset_t kva; /* va of mapping */
- int ref_count; /* usage of this mapping */
-#ifdef SMP
- cpumask_t cpumask; /* cpus on which mapping is valid */
-#endif
};
static __inline vm_offset_t
diff --git a/sys/mips/include/smp.h b/sys/mips/include/smp.h
index 346c863..1cb0596 100644
--- a/sys/mips/include/smp.h
+++ b/sys/mips/include/smp.h
@@ -17,6 +17,8 @@
#ifdef _KERNEL
+#include <machine/pcb.h>
+
/*
* Interprocessor interrupts for SMP.
*/
@@ -31,6 +33,8 @@ void ipi_selected(cpumask_t cpus, int ipi);
void smp_init_secondary(u_int32_t cpuid);
void mpentry(void);
+extern struct pcb stoppcbs[];
+
#endif /* !LOCORE */
#endif /* _KERNEL */
diff --git a/sys/mips/include/trap.h b/sys/mips/include/trap.h
index 1c6be30..d8042382 100644
--- a/sys/mips/include/trap.h
+++ b/sys/mips/include/trap.h
@@ -74,17 +74,17 @@
#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
struct trapdebug { /* trap history buffer for debugging */
- u_int status;
- u_int cause;
- u_int vadr;
- u_int pc;
- u_int ra;
- u_int sp;
- u_int code;
+ register_t status;
+ register_t cause;
+ register_t vadr;
+ register_t pc;
+ register_t ra;
+ register_t sp;
+ register_t code;
};
#define trapdebug_enter(x, cd) { \
- intrmask_t s = disableintr(); \
+ register_t s = intr_disable(); \
trp->status = x->sr; \
trp->cause = x->cause; \
trp->vadr = x->badvaddr; \
@@ -94,7 +94,7 @@ struct trapdebug { /* trap history buffer for debugging */
trp->code = cd; \
if (++trp == &trapdebug[TRAPSIZE]) \
trp = trapdebug; \
- restoreintr(s); \
+ intr_restore(s); \
}
#define TRAPSIZE 10 /* Trap log buffer length */
@@ -111,13 +111,12 @@ void trapDump(char *msg);
void MipsFPTrap(u_int, u_int, u_int);
void MipsKernGenException(void);
void MipsKernIntr(void);
-void MipsKernTLBInvalidException(void);
+void MipsTLBInvalidException(void);
void MipsTLBMissException(void);
void MipsUserGenException(void);
void MipsUserIntr(void);
-void MipsUserTLBInvalidException(void);
-u_int trap(struct trapframe *);
+register_t trap(struct trapframe *);
#ifndef LOCORE /* XXX */
int check_address(void *);
diff --git a/sys/mips/include/vmparam.h b/sys/mips/include/vmparam.h
index a524293..3b9b12e 100644
--- a/sys/mips/include/vmparam.h
+++ b/sys/mips/include/vmparam.h
@@ -97,17 +97,19 @@
/* user/kernel map constants */
#define VM_MIN_ADDRESS ((vm_offset_t)0x00000000)
+#define VM_MAX_ADDRESS ((vm_offset_t)(intptr_t)(int32_t)0xffffffff)
+
+#define VM_MINUSER_ADDRESS ((vm_offset_t)0x00000000)
#define VM_MAXUSER_ADDRESS ((vm_offset_t)0x80000000)
#define VM_MAX_MMAP_ADDR VM_MAXUSER_ADDRESS
-#define VM_MAX_ADDRESS ((vm_offset_t)0x80000000)
-
-#ifndef VM_KERNEL_ALLOC_OFFSET
-#define VM_KERNEL_ALLOC_OFFSET ((vm_offset_t)0x00000000)
-#endif
#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0xC0000000)
-#define VM_KERNEL_WIRED_ADDR_END (VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET)
-#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xFFFFC000)
+#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xFFFFC000)
+#if 0
+#define KERNBASE (VM_MIN_KERNEL_ADDRESS)
+#else
+#define KERNBASE ((vm_offset_t)(intptr_t)(int32_t)0x80000000)
+#endif
/*
* Disable superpage reservations. (not sure if this is right
@@ -150,9 +152,9 @@
#define VM_PHYSSEG_MAX 32
/*
- * The physical address space is densely populated.
+ * The physical address space is sparsely populated.
*/
-#define VM_PHYSSEG_DENSE
+#define VM_PHYSSEG_SPARSE
/*
* Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
@@ -179,23 +181,8 @@
*/
#define VM_NFREEORDER 9
-/*
- * XXXMIPS: This values need to be changed!!!
- */
-#if 0
-#define VM_MIN_ADDRESS ((vm_offset_t)0x0000000000010000)
-#define VM_MAXUSER_ADDRESS ((vm_offset_t)MIPS_KSEG0_START-1)
-#define VM_MAX_ADDRESS ((vm_offset_t)0x0000000100000000)
-#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)MIPS_KSEG3_START)
-#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)MIPS_KSEG3_END)
-#define KERNBASE (VM_MIN_KERNEL_ADDRESS)
-
-/* virtual sizes (bytes) for various kernel submaps */
-#define VM_KMEM_SIZE (16*1024*1024) /* XXX ??? */
-#endif
-
-#define NBSEG 0x400000 /* bytes/segment */
-#define SEGOFSET (NBSEG-1) /* byte offset into segment */
#define SEGSHIFT 22 /* LOG2(NBSEG) */
+#define NBSEG (1 << SEGSHIFT) /* bytes/segment */
+#define SEGOFSET (NBSEG-1) /* byte offset into segment */
#endif /* !_MACHINE_VMPARAM_H_ */
diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c
index 2f0eada..237e742 100644
--- a/sys/mips/malta/gt_pci.c
+++ b/sys/mips/malta/gt_pci.c
@@ -109,8 +109,8 @@ struct gt_pci_softc {
struct rman sc_mem_rman;
struct rman sc_io_rman;
struct rman sc_irq_rman;
- uint32_t sc_mem;
- uint32_t sc_io;
+ unsigned long sc_mem;
+ bus_space_handle_t sc_io;
struct resource *sc_irq;
struct intr_event *sc_eventstab[ICU_LEN];
diff --git a/sys/mips/malta/gtreg.h b/sys/mips/malta/gtreg.h
index 8fa05a0..726f5fe 100644
--- a/sys/mips/malta/gtreg.h
+++ b/sys/mips/malta/gtreg.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/mips/mips/autoconf.c b/sys/mips/mips/autoconf.c
index 99fd541..e16c05c 100644
--- a/sys/mips/mips/autoconf.c
+++ b/sys/mips/mips/autoconf.c
@@ -102,6 +102,7 @@ static void
configure_final(dummy)
void *dummy;
{
+ intr_enable();
cninit_finish();
diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c
index 4e7b45f..a6a7419 100644
--- a/sys/mips/mips/busdma_machdep.c
+++ b/sys/mips/mips/busdma_machdep.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cache.h>
#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
#include <machine/md_var.h>
#define MAX_BPAGES 64
@@ -124,7 +125,7 @@ SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0,
#define DMAMAP_MBUF 0x2
#define DMAMAP_UIO 0x4
#define DMAMAP_TYPE_MASK (DMAMAP_LINEAR|DMAMAP_MBUF|DMAMAP_UIO)
-#define DMAMAP_COHERENT 0x8
+#define DMAMAP_UNCACHEABLE 0x8
#define DMAMAP_ALLOCATED 0x10
#define DMAMAP_MALLOCUSED 0x20
@@ -340,6 +341,8 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
newtag->nsegments = nsegments;
newtag->maxsegsz = maxsegsz;
newtag->flags = flags;
+ if (cpuinfo.cache_coherent_dma)
+ newtag->flags |= BUS_DMA_COHERENT;
newtag->ref_count = 1; /* Count ourself */
newtag->map_count = 0;
if (lockfunc != NULL) {
@@ -517,9 +520,6 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
bz->map_count++;
}
- if (flags & BUS_DMA_COHERENT)
- newmap->flags |= DMAMAP_COHERENT;
-
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, error);
@@ -577,13 +577,23 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
*mapp = newmap;
newmap->dmat = dmat;
+ /*
+ * If all the memory is coherent with DMA then we don't need to
+ * do anything special for a coherent mapping request.
+ */
+ if (dmat->flags & BUS_DMA_COHERENT)
+ flags &= ~BUS_DMA_COHERENT;
+
+ /*
+ * Allocate uncacheable memory if all else fails.
+ */
if (flags & BUS_DMA_COHERENT)
- newmap->flags |= DMAMAP_COHERENT;
-
+ newmap->flags |= DMAMAP_UNCACHEABLE;
+
if (dmat->maxsize <= PAGE_SIZE &&
(dmat->alignment < dmat->maxsize) &&
!_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr) &&
- !(flags & BUS_DMA_COHERENT)) {
+ !(newmap->flags & DMAMAP_UNCACHEABLE)) {
*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
newmap->flags |= DMAMAP_MALLOCUSED;
} else {
@@ -619,7 +629,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
return (ENOMEM);
}
- if (flags & BUS_DMA_COHERENT) {
+ if (newmap->flags & DMAMAP_UNCACHEABLE) {
void *tmpaddr = (void *)*vaddr;
if (tmpaddr) {
@@ -677,16 +687,21 @@ _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
* Count the number of bounce pages
* needed in order to complete this transfer
*/
- vaddr = trunc_page((vm_offset_t)buf);
+ vaddr = (vm_offset_t)buf;
vendaddr = (vm_offset_t)buf + buflen;
while (vaddr < vendaddr) {
+ bus_size_t sg_len;
+
KASSERT(kernel_pmap == pmap, ("pmap is not kernel pmap"));
+ sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
paddr = pmap_kextract(vaddr);
if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
- run_filter(dmat, paddr) != 0)
+ run_filter(dmat, paddr) != 0) {
+ sg_len = roundup2(sg_len, dmat->alignment);
map->pagesneeded++;
- vaddr += PAGE_SIZE;
+ }
+ vaddr += sg_len;
}
CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
}
@@ -1177,8 +1192,13 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
return;
if (STAILQ_FIRST(&map->bpages))
_bus_dmamap_sync_bp(dmat, map, op);
- if (map->flags & DMAMAP_COHERENT)
+
+ if (dmat->flags & BUS_DMA_COHERENT)
return;
+
+ if (map->flags & DMAMAP_UNCACHEABLE)
+ return;
+
CTR3(KTR_BUSDMA, "%s: op %x flags %x", __func__, op, map->flags);
switch(map->flags & DMAMAP_TYPE_MASK) {
case DMAMAP_LINEAR:
diff --git a/sys/mips/mips/copystr.S b/sys/mips/mips/copystr.S
deleted file mode 100644
index 35e7905..0000000
--- a/sys/mips/mips/copystr.S
+++ /dev/null
@@ -1,171 +0,0 @@
-/* $NetBSD: copy.S,v 1.5 2007/10/17 19:55:37 garbled Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Digital Equipment Corporation and Ralph Campbell.
- *
- * 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.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- *
- * Copyright (C) 1989 Digital Equipment Corporation.
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies.
- * Digital Equipment Corporation makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
- * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL)
- * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
- * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL)
- * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
- * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL)
- *
- * @(#)locore.s 8.5 (Berkeley) 1/4/94
- */
-
-#include "assym.s"
-#include <machine/asm.h>
-#include <machine/asmacros.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/errno.h>
-
-/*
- * copystr(9)
- * <v0>int copystr(<a0>const void *src, <a1>void *dst, <a2>size_t len,
- * <a3>size_t *done)
- */
-ENTRY(copystr)
- .set noreorder
- .set noat
- move v0, zero
- beqz a2, 2f
- move t1, zero
-1: subu a2, 1 /*XXX mips64 unsafe -- long */
- lbu t0, 0(a0)
- PTR_ADDU a0, 1
- sb t0, 0(a1)
- PTR_ADDU a1, 1
- beqz t0, 3f /* NULL - end of string*/
- addu t1, 1 /*XXX mips64 unsafe -- long */
- bnez a2, 1b
- nop
-2: /* ENAMETOOLONG */
- li v0, ENAMETOOLONG
-3: /* done != NULL -> how many bytes were copied */
- beqz a3, 4f
- nop
- sw t1, 0(a3) /*XXX mips64 unsafe -- long */
-4: jr ra
- nop
- .set reorder
- .set at
-END(copystr)
-
-/*
- * int copyinstr(void *uaddr, void *kaddr, size_t maxlen, size_t *lencopied)
- * Copy a NIL-terminated string, at most maxlen characters long, from the
- * user's address space. Return the number of characters copied (including
- * the NIL) in *lencopied. If the string is too long, return ENAMETOOLONG;
- * else return 0 or EFAULT.
- */
-LEAF(copyinstr)
- .set noreorder
- .set noat
- lw t2, pcpup
- lw v1, PC_CURPCB(t2)
- PTR_LA v0, _C_LABEL(copystrerr)
- blt a0, zero, _C_LABEL(copystrerr)
- sw v0, PCB_ONFAULT(v1)
- move t0, a2
- beq a2, zero, 4f
-1:
- lbu v0, 0(a0)
- subu a2, a2, 1 /*xxx mips64 unsafe -- long */
- beq v0, zero, 2f
- sb v0, 0(a1)
- PTR_ADDU a0, a0, 1
- bne a2, zero, 1b
- PTR_ADDU a1, a1, 1
-4:
- li v0, ENAMETOOLONG
-2:
- beq a3, zero, 3f
- subu a2, t0, a2 /*xxx mips64 unsafe -- long */
- sw a2, 0(a3) /*xxx mips64 unsafe -- long */
-3:
- j ra # v0 is 0 or ENAMETOOLONG
- sw zero, PCB_ONFAULT(v1)
- .set reorder
- .set at
-END(copyinstr)
-
-/*
- * int copyoutstr(void *uaddr, void *kaddr, size_t maxlen, size_t *lencopied);
- * Copy a NIL-terminated string, at most maxlen characters long, into the
- * user's address space. Return the number of characters copied (including
- * the NIL) in *lencopied. If the string is too long, return ENAMETOOLONG;
- * else return 0 or EFAULT.
- */
-LEAF(copyoutstr)
- .set noreorder
- .set noat
- lw t2, pcpup
- lw v1, PC_CURPCB(t2)
- PTR_LA v0, _C_LABEL(copystrerr)
- blt a1, zero, _C_LABEL(copystrerr)
- sw v0, PCB_ONFAULT(v1)
- move t0, a2
- beq a2, zero, 4f
-1:
- lbu v0, 0(a0)
- subu a2, a2, 1 /*xxx mips64 unsafe -- long */
- beq v0, zero, 2f
- sb v0, 0(a1)
- PTR_ADDU a0, a0, 1
- bne a2, zero, 1b
- PTR_ADDU a1, a1, 1
-4:
- li v0, ENAMETOOLONG
-2:
- beq a3, zero, 3f
- subu a2, t0, a2 /*xxx mips64 unsafe -- long */
- sw a2, 0(a3) /*xxx mips64 unsafe -- long */
-3:
- j ra # v0 is 0 or ENAMETOOLONG
- sw zero, PCB_ONFAULT(v1)
- .set reorder
- .set at
-END(copyoutstr)
-
-LEAF(copystrerr)
- sw zero, PCB_ONFAULT(v1)
- j ra
- li v0, EFAULT # return EFAULT
-END(copystrerr)
diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c
index 1b490e6..4539d1e 100644
--- a/sys/mips/mips/cpu.c
+++ b/sys/mips/mips/cpu.c
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/pte.h>
#include <machine/hwfunc.h>
-static struct mips_cpuinfo cpuinfo;
+struct mips_cpuinfo cpuinfo;
union cpuprid cpu_id;
union cpuprid fpu_id;
diff --git a/sys/mips/mips/db_trace.c b/sys/mips/mips/db_trace.c
index 4eadc25..9417bcc 100644
--- a/sys/mips/mips/db_trace.c
+++ b/sys/mips/mips/db_trace.c
@@ -162,13 +162,16 @@ loop:
subr = (uintptr_t)MipsUserGenException;
else if (pcBetween(MipsKernIntr, MipsUserIntr))
subr = (uintptr_t)MipsKernIntr;
- else if (pcBetween(MipsUserIntr, MipsKernTLBInvalidException))
+ else if (pcBetween(MipsUserIntr, MipsTLBInvalidException))
subr = (uintptr_t)MipsUserIntr;
- else if (pcBetween(MipsKernTLBInvalidException,
- MipsUserTLBInvalidException))
- subr = (uintptr_t)MipsKernTLBInvalidException;
- else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException))
- subr = (uintptr_t)MipsUserTLBInvalidException;
+ else if (pcBetween(MipsTLBInvalidException, MipsTLBMissException))
+ subr = (uintptr_t)MipsTLBInvalidException;
+ else if (pcBetween(fork_trampoline, savectx))
+ subr = (uintptr_t)fork_trampoline;
+ else if (pcBetween(savectx, mips_cpu_throw))
+ subr = (uintptr_t)savectx;
+ else if (pcBetween(mips_cpu_throw, cpu_switch))
+ subr = (uintptr_t)cpu_throw;
else if (pcBetween(cpu_switch, MipsSwitchFPState))
subr = (uintptr_t)cpu_switch;
else if (pcBetween(_locore, _locoreEnd)) {
@@ -412,10 +415,8 @@ db_trace_thread(struct thread *thr, int count)
: "=r" (pc)
: "r" (ra));
- }
-
- else {
- ctx = thr->td_pcb;
+ } else {
+ ctx = kdb_thr_ctx(thr);
sp = (register_t)ctx->pcb_context[PREG_SP];
pc = (register_t)ctx->pcb_context[PREG_PC];
ra = (register_t)ctx->pcb_context[PREG_RA];
diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S
index eff484a..d6fbc9c 100644
--- a/sys/mips/mips/exception.S
+++ b/sys/mips/mips/exception.S
@@ -66,37 +66,14 @@
#include "assym.s"
-#if defined(ISA_MIPS32)
-#undef WITH_64BIT_CP0
-#elif defined(ISA_MIPS64)
-#define WITH_64BIT_CP0
-#elif defined(ISA_MIPS3)
-#define WITH_64BIT_CP0
-#else
-#error "Please write the code for this ISA"
-#endif
+/*
+ * Clear the software-managed bits in a PTE in register pr.
+ */
+#define CLEAR_PTE_SWBITS(pr) \
+ sll pr, 2 ; \
+ srl pr, 2 # keep bottom 30 bits
-#ifdef WITH_64BIT_CP0
-#define _SLL dsll
-#define _SRL dsrl
-#define _MFC0 dmfc0
-#define _MTC0 dmtc0
-#define WIRED_SHIFT 34
-#else
-#define _SLL sll
-#define _SRL srl
-#define _MFC0 mfc0
-#define _MTC0 mtc0
-#define WIRED_SHIFT 2
-#endif
.set noreorder # Noreorder is default style!
-#if defined(ISA_MIPS32)
- .set mips32
-#elif defined(ISA_MIPS64)
- .set mips64
-#elif defined(ISA_MIPS3)
- .set mips3
-#endif
/*
* Reasonable limit
@@ -125,12 +102,12 @@
*
*
*/
-
- .set noat
VECTOR(MipsTLBMiss, unknown)
- j _C_LABEL(MipsDoTLBMiss)
- mfc0 k0, COP_0_BAD_VADDR # get the fault address
- nop
+ .set push
+ .set noat
+ j MipsDoTLBMiss
+ MFC0 k0, COP_0_BAD_VADDR # get the fault address
+ .set pop
VECTOR_END(MipsTLBMiss)
/*
@@ -145,42 +122,40 @@ VECTOR_END(MipsTLBMiss)
* let the processor trap to load the correct value after service.
*----------------------------------------------------------------------------
*/
+ .set push
+ .set noat
MipsDoTLBMiss:
- #k0 already has BadVA
- bltz k0, 1f #02: k0<0 -> 1f (kernel fault)
- srl k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost)
- GET_CPU_PCPU(k1)
- lw k1, PC_SEGBASE(k1)
- beqz k1, 2f #05: make sure segbase is not null
- andi k0, k0, 0x7fc #06: k0=seg offset (mask 0x3)
-#xxx mips64 unsafe?
- addu k1, k0, k1 #07: k1=seg entry address
- lw k1, 0(k1) #08: k1=seg entry
- mfc0 k0, COP_0_BAD_VADDR #09: k0=bad address (again)
- beq k1, zero, 2f #0a: ==0 -- no page table
- srl k0, PGSHIFT - 2 #0b: k0=VPN (aka va>>10)
+ bltz k0, 1f #02: k0<0 -> 1f (kernel fault)
+ PTR_SRL k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost)
- andi k0, k0, ((NPTEPG/2) - 1) << 3 #0c: k0=page tab offset
-#xxx mips64 unsafe?
- addu k1, k1, k0 #0d: k1=pte address
- lw k0, 0(k1) #0e: k0=lo0 pte
- lw k1, 4(k1) #0f: k1=lo1 pte
- _SLL k0, k0, WIRED_SHIFT #10: keep bottom 30 bits
- _SRL k0, k0, WIRED_SHIFT #11: keep bottom 30 bits
- _MTC0 k0, COP_0_TLB_LO0 #12: lo0 is loaded
- _SLL k1, k1, WIRED_SHIFT #13: keep bottom 30 bits
- _SRL k1, k1, WIRED_SHIFT #14: keep bottom 30 bits
- _MTC0 k1, COP_0_TLB_LO1 #15: lo1 is loaded
- HAZARD_DELAY
- tlbwr #1a: write to tlb
+ GET_CPU_PCPU(k1)
+ PTR_L k1, PC_SEGBASE(k1)
+ beqz k1, 2f #05: make sure segbase is not null
+ andi k0, k0, 0xffc #06: k0=seg offset (mask 0x3)
+ PTR_ADDU k1, k0, k1 #07: k1=seg entry address
+
+ PTR_L k1, 0(k1) #08: k1=seg entry
+ MFC0 k0, COP_0_BAD_VADDR #09: k0=bad address (again)
+ beq k1, zero, 2f #0a: ==0 -- no page table
+ srl k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10)
+ andi k0, k0, 0xff8 #0c: k0=page tab offset
+ PTR_ADDU k1, k1, k0 #0d: k1=pte address
+ lw k0, 0(k1) #0e: k0=lo0 pte
+ lw k1, 4(k1) #0f: k1=lo0 pte
+ CLEAR_PTE_SWBITS(k0)
+ MTC0 k0, COP_0_TLB_LO0 #12: lo0 is loaded
+ COP0_SYNC
+ CLEAR_PTE_SWBITS(k1)
+ MTC0 k1, COP_0_TLB_LO1 #15: lo1 is loaded
+ COP0_SYNC
+ tlbwr #1a: write to tlb
HAZARD_DELAY
- eret #1f: retUrn from exception
-1: j _C_LABEL(MipsTLBMissException) #20: kernel exception
- nop #21: branch delay slot
-2: j SlowFault #22: no page table present
- nop #23: branch delay slot
-
- .set at
+ eret #1f: retUrn from exception
+1: j MipsTLBMissException #20: kernel exception
+ nop #21: branch delay slot
+2: j SlowFault #22: no page table present
+ nop #23: branch delay slot
+ .set pop
/*
* This code is copied to the general exception vector address to
@@ -207,7 +182,7 @@ VECTOR(MipsException, unknown)
# the cause is already
# shifted left by 2 bits so
# we dont have to shift.
- lw k0, 0(k0) # Get the function address
+ PTR_L k0, 0(k0) # Get the function address
nop
j k0 # Jump to the function.
nop
@@ -244,37 +219,28 @@ SlowFault:
*
*----------------------------------------------------------------------------
*/
-#if defined(ISA_MIPS32)
-#define STORE sw /* 32 bit mode regsave instruction */
-#define LOAD lw /* 32 bit mode regload instruction */
-#define RSIZE 4 /* 32 bit mode register size */
-#elif defined(ISA_MIPS64)
-#define STORE sd /* 64 bit mode regsave instruction */
-#define LOAD ld /* 64 bit mode regload instruction */
-#define RSIZE 8 /* 64 bit mode register size */
-#else
-#error "Please write code for this isa."
-#endif
#define SAVE_REG(reg, offs, base) \
- STORE reg, STAND_ARG_SIZE + (RSIZE * offs) (base)
+ REG_S reg, CALLFRAME_SIZ + (SZREG * offs) (base)
#ifdef TARGET_OCTEON
#define CLEAR_STATUS \
mfc0 a0, COP_0_STATUS_REG ;\
li a2, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) ; \
or a0, a0, a2 ; \
- li a2, ~(MIPS_SR_INT_IE|MIPS_SR_EXL) ; \
+ li a2, ~(MIPS_SR_INT_IE | MIPS_SR_EXL | SR_KSU_USER) ; \
and a0, a0, a2 ; \
- mtc0 a0, COP_0_STATUS_REG
+ mtc0 a0, COP_0_STATUS_REG ; \
+ ITLBNOPFIX
#else
#define CLEAR_STATUS \
mfc0 a0, COP_0_STATUS_REG ;\
- li a2, ~(MIPS_SR_INT_IE|MIPS_SR_EXL) ; \
+ li a2, ~(MIPS_SR_INT_IE | MIPS_SR_EXL | SR_KSU_USER) ; \
and a0, a0, a2 ; \
- mtc0 a0, COP_0_STATUS_REG
+ mtc0 a0, COP_0_STATUS_REG ; \
+ ITLBNOPFIX
#endif
-
+
/*
* Save CPU and CP0 register state.
*
@@ -317,8 +283,8 @@ SlowFault:
mfhi v1 ;\
mfc0 a0, COP_0_STATUS_REG ;\
mfc0 a1, COP_0_CAUSE_REG ;\
- mfc0 a2, COP_0_BAD_VADDR ;\
- mfc0 a3, COP_0_EXC_PC ;\
+ MFC0 a2, COP_0_BAD_VADDR ;\
+ MFC0 a3, COP_0_EXC_PC ;\
SAVE_REG(v0, MULLO, sp) ;\
SAVE_REG(v1, MULHI, sp) ;\
SAVE_REG(a0, SR, sp) ;\
@@ -332,20 +298,20 @@ SlowFault:
PTR_ADDU v0, sp, KERN_EXC_FRAME_SIZE ;\
SAVE_REG(v0, SP, sp) ;\
CLEAR_STATUS ;\
- PTR_ADDU a0, sp, STAND_ARG_SIZE ;\
+ PTR_ADDU a0, sp, CALLFRAME_SIZ ;\
ITLBNOPFIX
#define RESTORE_REG(reg, offs, base) \
- LOAD reg, STAND_ARG_SIZE + (RSIZE * offs) (base)
+ REG_L reg, CALLFRAME_SIZ + (SZREG * offs) (base)
#define RESTORE_CPU \
- mtc0 zero,COP_0_STATUS_REG ;\
+ CLEAR_STATUS ;\
RESTORE_REG(k0, SR, sp) ;\
RESTORE_REG(t0, MULLO, sp) ;\
RESTORE_REG(t1, MULHI, sp) ;\
mtlo t0 ;\
mthi t1 ;\
- _MTC0 v0, COP_0_EXC_PC ;\
+ MTC0 v0, COP_0_EXC_PC ;\
.set noat ;\
RESTORE_REG(AT, AST, sp) ;\
RESTORE_REG(v0, V0, sp) ;\
@@ -384,13 +350,13 @@ SlowFault:
* the status register and the multiply lo and high registers.
* In addition, we set this up for linkage conventions.
*/
-#define KERN_REG_SIZE (NUMSAVEREGS * RSIZE)
-#define KERN_EXC_FRAME_SIZE (STAND_FRAME_SIZE + KERN_REG_SIZE + 16)
+#define KERN_REG_SIZE (NUMSAVEREGS * SZREG)
+#define KERN_EXC_FRAME_SIZE (CALLFRAME_SIZ + KERN_REG_SIZE + 16)
NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra)
.set noat
- subu sp, sp, KERN_EXC_FRAME_SIZE
- .mask 0x80000000, (STAND_RA_OFFSET - KERN_EXC_FRAME_SIZE)
+ PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE
+ .mask 0x80000000, (CALLFRAME_RA - KERN_EXC_FRAME_SIZE)
/*
* Save CPU state, building 'frame'.
*/
@@ -401,7 +367,7 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra)
PTR_LA gp, _C_LABEL(_gp)
PTR_LA k0, _C_LABEL(trap)
jalr k0
- sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) # for debugging
+ REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging
/*
* Update interrupt mask in saved status register
@@ -410,7 +376,6 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra)
* in trap handler
*/
mfc0 a0, COP_0_STATUS_REG
- mtc0 zero, COP_0_STATUS_REG
and a0, a0, SR_INT_MASK
RESTORE_REG(a1, SR, sp)
and a1, a1, ~SR_INT_MASK
@@ -424,10 +389,10 @@ END(MipsKernGenException)
#define SAVE_U_PCB_REG(reg, offs, base) \
- STORE reg, U_PCB_REGS + (RSIZE * offs) (base)
+ REG_S reg, U_PCB_REGS + (SZREG * offs) (base)
#define RESTORE_U_PCB_REG(reg, offs, base) \
- LOAD reg, U_PCB_REGS + (RSIZE * offs) (base)
+ REG_L reg, U_PCB_REGS + (SZREG * offs) (base)
/*----------------------------------------------------------------------------
*
@@ -443,14 +408,14 @@ END(MipsKernGenException)
*
*----------------------------------------------------------------------------
*/
-NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
+NNON_LEAF(MipsUserGenException, CALLFRAME_SIZ, ra)
.set noat
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
/*
* Save all of the registers except for the kernel temporaries in u.u_pcb.
*/
GET_CPU_PCPU(k1)
- lw k1, PC_CURPCB(k1)
+ PTR_L k1, PC_CURPCB(k1)
SAVE_U_PCB_REG(AT, AST, k1)
.set at
SAVE_U_PCB_REG(v0, V0, k1)
@@ -476,17 +441,17 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
SAVE_U_PCB_REG(s2, S2, k1)
SAVE_U_PCB_REG(s3, S3, k1)
SAVE_U_PCB_REG(s4, S4, k1)
- mfc0 a2, COP_0_BAD_VADDR # Third arg is the fault addr
+ MFC0 a2, COP_0_BAD_VADDR # Third arg is the fault addr
SAVE_U_PCB_REG(s5, S5, k1)
SAVE_U_PCB_REG(s6, S6, k1)
SAVE_U_PCB_REG(s7, S7, k1)
SAVE_U_PCB_REG(t8, T8, k1)
- mfc0 a3, COP_0_EXC_PC # Fourth arg is the pc.
+ MFC0 a3, COP_0_EXC_PC # Fourth arg is the pc.
SAVE_U_PCB_REG(t9, T9, k1)
SAVE_U_PCB_REG(gp, GP, k1)
SAVE_U_PCB_REG(sp, SP, k1)
SAVE_U_PCB_REG(s8, S8, k1)
- subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP
+ PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP
SAVE_U_PCB_REG(ra, RA, k1)
SAVE_U_PCB_REG(v0, MULLO, k1)
SAVE_U_PCB_REG(v1, MULHI, k1)
@@ -494,12 +459,12 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
SAVE_U_PCB_REG(a1, CAUSE, k1)
SAVE_U_PCB_REG(a2, BADVADDR, k1)
SAVE_U_PCB_REG(a3, PC, k1)
- sw a3, STAND_RA_OFFSET(sp) # for debugging
+ REG_S a3, CALLFRAME_RA(sp) # for debugging
PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP
# Turn off fpu and enter kernel mode
and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_KSU_MASK | SR_INT_ENAB)
#ifdef TARGET_OCTEON
- or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
+ or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS32_SR_PX)
#endif
mtc0 t0, COP_0_STATUS_REG
PTR_ADDU a0, k1, U_PCB_REGS
@@ -518,10 +483,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
*/
DO_AST
- mfc0 t0, COP_0_STATUS_REG # disable int
- and t0, t0, ~(MIPS_SR_INT_IE)
- mtc0 t0, COP_0_STATUS_REG
- ITLBNOPFIX
+ CLEAR_STATUS
/*
* The use of k1 for storing the PCB pointer must be done only
@@ -529,7 +491,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
* by the interrupt code.
*/
GET_CPU_PCPU(k1)
- lw k1, PC_CURPCB(k1)
+ PTR_L k1, PC_CURPCB(k1)
/*
* Update interrupt mask in saved status register
@@ -549,7 +511,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
mthi t1
RESTORE_U_PCB_REG(a0, PC, k1)
RESTORE_U_PCB_REG(v0, V0, k1)
- _MTC0 a0, COP_0_EXC_PC # set return address
+ MTC0 a0, COP_0_EXC_PC # set return address
RESTORE_U_PCB_REG(v1, V1, k1)
RESTORE_U_PCB_REG(a0, A0, k1)
RESTORE_U_PCB_REG(a1, A1, k1)
@@ -578,9 +540,6 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
RESTORE_U_PCB_REG(k0, SR, k1)
RESTORE_U_PCB_REG(s8, S8, k1)
RESTORE_U_PCB_REG(ra, RA, k1)
-#ifdef TARGET_OCTEON
- and k0, k0, ~(MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
-#endif
.set noat
RESTORE_U_PCB_REG(AT, AST, k1)
@@ -610,27 +569,25 @@ END(MipsUserGenException)
NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra)
.set noat
- subu sp, sp, KERN_EXC_FRAME_SIZE
- .mask 0x80000000, (STAND_RA_OFFSET - KERN_EXC_FRAME_SIZE)
+ PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE
+ .mask 0x80000000, (CALLFRAME_RA - KERN_EXC_FRAME_SIZE)
/*
- * Save the relevant kernel registers onto the stack.
+ * Save CPU state, building 'frame'.
*/
SAVE_CPU
-
/*
- * Call the interrupt handler.
+ * Call the interrupt handler. a0 points at the saved frame.
*/
PTR_LA gp, _C_LABEL(_gp)
- PTR_ADDU a0, sp, STAND_ARG_SIZE
PTR_LA k0, _C_LABEL(cpu_intr)
jalr k0
- sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp)
- /* Why no AST processing here? */
+ REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging
/*
* Update interrupt mask in saved status register
* Some of interrupts could be disabled by
- * intr filters
+ * intr filters if interrupts are enabled later
+ * in trap handler
*/
mfc0 a0, COP_0_STATUS_REG
and a0, a0, SR_INT_MASK
@@ -638,12 +595,8 @@ NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra)
and a1, a1, ~SR_INT_MASK
or a1, a1, a0
SAVE_REG(a1, SR, sp)
-
-/*
- * Restore registers and return from the interrupt.
- */
- lw v0, STAND_RA_OFFSET + KERN_REG_SIZE(sp)
- RESTORE_CPU
+ REG_L v0, CALLFRAME_RA + KERN_REG_SIZE(sp)
+ RESTORE_CPU # v0 contains the return address.
sync
eret
.set at
@@ -668,15 +621,15 @@ END(MipsKernIntr)
*
*----------------------------------------------------------------------------
*/
-NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
+NNON_LEAF(MipsUserIntr, CALLFRAME_SIZ, ra)
.set noat
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
/*
* Save the relevant user registers into the u.u_pcb struct.
* We don't need to save s0 - s8 because the compiler does it for us.
*/
GET_CPU_PCPU(k1)
- lw k1, PC_CURPCB(k1)
+ PTR_L k1, PC_CURPCB(k1)
SAVE_U_PCB_REG(AT, AST, k1)
.set at
SAVE_U_PCB_REG(v0, V0, k1)
@@ -715,19 +668,19 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
mfhi v1
mfc0 a0, COP_0_STATUS_REG
mfc0 a1, COP_0_CAUSE_REG
- mfc0 a3, COP_0_EXC_PC
+ MFC0 a3, COP_0_EXC_PC
SAVE_U_PCB_REG(v0, MULLO, k1)
SAVE_U_PCB_REG(v1, MULHI, k1)
SAVE_U_PCB_REG(a0, SR, k1)
SAVE_U_PCB_REG(a1, CAUSE, k1)
SAVE_U_PCB_REG(a3, PC, k1) # PC in a3, note used later!
- subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP
+ PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP
PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP
# Turn off fpu, disable interrupts, set kernel mode kernel mode, clear exception level.
and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK)
#ifdef TARGET_OCTEON
- or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
+ or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS32_SR_PX)
#endif
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
@@ -737,7 +690,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
*/
PTR_LA k0, _C_LABEL(cpu_intr)
jalr k0
- sw a3, STAND_RA_OFFSET(sp) # for debugging
+ REG_S a3, CALLFRAME_RA(sp) # for debugging
/*
* Enable interrupts before doing ast().
@@ -759,13 +712,10 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
/*
* Restore user registers and return.
*/
- mfc0 t0, COP_0_STATUS_REG # disable int
- and t0, t0, ~(MIPS_SR_INT_IE)
- mtc0 t0, COP_0_STATUS_REG
- ITLBNOPFIX
+ CLEAR_STATUS
GET_CPU_PCPU(k1)
- lw k1, PC_CURPCB(k1)
+ PTR_L k1, PC_CURPCB(k1)
/*
* Update interrupt mask in saved status register
@@ -793,7 +743,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
RESTORE_U_PCB_REG(t2, PC, k1)
mtlo t0
mthi t1
- _MTC0 t2, COP_0_EXC_PC # set return address
+ MTC0 t2, COP_0_EXC_PC # set return address
RESTORE_U_PCB_REG(v0, V0, k1)
RESTORE_U_PCB_REG(v1, V1, k1)
RESTORE_U_PCB_REG(a0, A0, k1)
@@ -814,9 +764,6 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
RESTORE_U_PCB_REG(k0, SR, k1)
RESTORE_U_PCB_REG(sp, SP, k1)
RESTORE_U_PCB_REG(ra, RA, k1)
-#ifdef TARGET_OCTEON
- and k0, k0, ~(MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
-#endif
.set noat
RESTORE_U_PCB_REG(AT, AST, k1)
@@ -827,177 +774,168 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
.set at
END(MipsUserIntr)
-NLEAF(MipsKernTLBInvalidException)
- .set noat
- mfc0 k0, COP_0_BAD_VADDR # get the fault address
-
+NLEAF(MipsTLBInvalidException)
+ .set push
+ .set noat
+ .set noreorder
- li k1, VM_MAXUSER_ADDRESS
- sltu k1, k0, k1
- beqz k1, 1f
+ MFC0 k0, COP_0_BAD_VADDR
+ PTR_LI k1, VM_MAXUSER_ADDRESS
+ sltu k1, k0, k1
+ bnez k1, 1f
nop
+
+ /* Kernel address. */
+ lui k1, %hi(kernel_segmap) # k1=hi of segbase
+ b 2f
+ PTR_L k1, %lo(kernel_segmap)(k1) # k1=segment tab base
+
+1: /* User address. */
GET_CPU_PCPU(k1)
- lw k1, PC_SEGBASE(k1) # works for single cpu????
- beqz k1, _C_LABEL(MipsKernGenException) # seg tab is null
+ PTR_L k1, PC_SEGBASE(k1)
+
+2: /* Validate page directory pointer. */
+ beqz k1, 3f
nop
- b 2f
+
+ PTR_SRL k0, SEGSHIFT - 2 # k0=seg offset (almost)
+ beq k1, zero, MipsKernGenException # ==0 -- no seg tab
+ andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
+ PTR_ADDU k1, k0, k1 # k1=seg entry address
+ PTR_L k1, 0(k1) # k1=seg entry
+
+ /* Validate page table pointer. */
+ beqz k1, 3f
nop
-1:
- li k1, (VM_MAX_KERNEL_ADDRESS)
- bgez k0, _C_LABEL(MipsKernGenException) # full trap processing
- sltu k1, k1, k0 # check fault address against
- bnez k1, _C_LABEL(MipsKernGenException) # kernel_segmap upper bound
- lui k1, %hi(_C_LABEL(kernel_segmap)) # k1=hi of segbase
- lw k1, %lo(_C_LABEL(kernel_segmap))(k1) # k1=segment tab base
- beqz k1, _C_LABEL(MipsKernGenException) # seg tab is null
-2:
- srl k0, 20 # k0=seg offset (almost)
- andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
-#xxx mips64 unsafe?
- addu k1, k0, k1 # k1=seg entry address
- lw k1, 0(k1) # k1=seg entry
- mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again)
- beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no page table
- srl k0, k0, PGSHIFT-2
- andi k0, k0, 0xffc # compute offset from index
- tlbp # Probe the invalid entry
-#xxx mips64 unsafe?
- addu k1, k1, k0
- and k0, k0, 4 # check even/odd page
- nop # required for QED 5230
- bne k0, zero, KernTLBIOdd
+
+ MFC0 k0, COP_0_BAD_VADDR # k0=bad address (again)
+ PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN
+ andi k0, k0, 0xffc # k0=page tab offset
+ PTR_ADDU k1, k1, k0 # k1=pte address
+ lw k0, 0(k1) # k0=this PTE
+
+ /* Validate page table entry. */
+ andi k0, PTE_V
+ beqz k0, 3f
nop
- mfc0 k0, COP_0_TLB_INDEX
+ /* Check whether this is an even or odd entry. */
+ andi k0, k1, 4
+ bnez k0, odd_page
nop
- bltz k0, sys_stk_chk
-
- sltiu k0, k0, VMWIRED_ENTRIES # index below wired entries?
- bne k0, zero, sys_stk_chk
- lw k0, 0(k1) # get PTE entry
-
- _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO0 # load PTE entry
- and k0, k0, PTE_V # check for valid entry
- nop # required for QED5230
- beq k0, zero, _C_LABEL(MipsKernGenException) # PTE invalid
- lw k0, 4(k1) # get odd PTE entry
- _SLL k0, k0, WIRED_SHIFT
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO1 # load PTE entry
- HAZARD_DELAY
- tlbwi # write TLB
- HAZARD_DELAY
- eret
-KernTLBIOdd:
- mfc0 k0, COP_0_TLB_INDEX
+ lw k0, 0(k1)
+ lw k1, 4(k1)
+ CLEAR_PTE_SWBITS(k0)
+ MTC0 k0, COP_0_TLB_LO0
+ COP0_SYNC
+ CLEAR_PTE_SWBITS(k1)
+ MTC0 k1, COP_0_TLB_LO1
+ COP0_SYNC
+
+ b tlb_insert_entry
nop
- bltz k0, sys_stk_chk
-
- sltiu k0, k0, VMWIRED_ENTRIES # index below wired entries?
- bne k0, zero, sys_stk_chk
- lw k0, 0(k1) # get PTE entry
-
- _SLL k0, k0, WIRED_SHIFT # get rid of wired bit
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO1 # save PTE entry
- and k0, k0, PTE_V # check for valid entry
- nop # required for QED5230
- beq k0, zero, _C_LABEL(MipsKernGenException) # PTE invalid
- lw k0, -4(k1) # get even PTE entry
- _SLL k0, k0, WIRED_SHIFT
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO0 # save PTE entry
- HAZARD_DELAY
- tlbwi # update TLB
+
+odd_page:
+ lw k0, -4(k1)
+ lw k1, 0(k1)
+ CLEAR_PTE_SWBITS(k0)
+ MTC0 k0, COP_0_TLB_LO0
+ COP0_SYNC
+ CLEAR_PTE_SWBITS(k1)
+ MTC0 k1, COP_0_TLB_LO1
+ COP0_SYNC
+
+tlb_insert_entry:
+ tlbp
HAZARD_DELAY
+ mfc0 k0, COP_0_TLB_INDEX
+ bltz k0, tlb_insert_random
+ nop
+ tlbwi
eret
+ ssnop
- .set at
-END(MipsKernTLBInvalidException)
-
-
-NLEAF(MipsUserTLBInvalidException)
- .set noat
- mfc0 k0, COP_0_BAD_VADDR # get the fault address
+tlb_insert_random:
+ tlbwr
+ eret
+ ssnop
- li k1, VM_MAXUSER_ADDRESS
- sltu k1, k0, k1
- beqz k1, _C_LABEL(MipsUserGenException)
+3:
+ /*
+ * Branch to the comprehensive exception processing.
+ */
+ mfc0 k1, COP_0_STATUS_REG
+ andi k1, k1, SR_KSU_USER
+ bnez k1, _C_LABEL(MipsUserGenException)
nop
+
+ /*
+ * Check for kernel stack overflow.
+ */
GET_CPU_PCPU(k1)
- lw k1, PC_SEGBASE(k1) # works for single cpu????
- beqz k1, _C_LABEL(MipsUserGenException) # seg tab is null
- nop
-2:
- srl k0, 20 # k0=seg offset (almost)
- andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
-#xxx mips64 unsafe?
- addu k1, k0, k1 # k1=seg entry address
- lw k1, 0(k1) # k1=seg entry
- mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again)
- beq k1, zero, _C_LABEL(MipsUserGenException) # ==0 -- no page table
- srl k0, k0, PGSHIFT-2
- andi k0, k0, 0xffc # compute offset from index
- tlbp # Probe the invalid entry
-#xxx mips64 unsafe?
- addu k1, k1, k0
- and k0, k0, 4 # check even/odd page
- nop # required for QED 5230
- bne k0, zero, UserTLBIOdd
+ PTR_L k0, PC_CURTHREAD(k1)
+ PTR_L k0, TD_KSTACK(k0)
+ sltu k0, k0, sp
+ bnez k0, _C_LABEL(MipsKernGenException)
nop
- mfc0 k0, COP_0_TLB_INDEX
- nop
- bltz k0, _C_LABEL(MipsUserGenException)
+ /*
+ * Kernel stack overflow.
+ *
+ * Move to a valid stack before we call panic. We use the boot stack
+ * for this purpose.
+ */
+ GET_CPU_PCPU(k1)
+ lw k1, PC_CPUID(k1)
+ sll k1, k1, PAGE_SHIFT + 1
- sltiu k0, k0, VMWIRED_ENTRIES # index below wired entries?
- bne k0, zero, _C_LABEL(MipsUserGenException)
- lw k0, 0(k1) # get PTE entry
-
- _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO0 # load PTE entry
- and k0, k0, PTE_V # check for valid entry
- nop # required for QED5230
- beq k0, zero, _C_LABEL(MipsUserGenException) # PTE invalid
- lw k0, 4(k1) # get odd PTE entry
- _SLL k0, k0, WIRED_SHIFT
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO1 # load PTE entry
- HAZARD_DELAY
- tlbwi # write TLB
- HAZARD_DELAY
- eret
+ PTR_LA k0, _C_LABEL(pcpu_space)
+ PTR_ADDU k0, PAGE_SIZE * 2
+ PTR_ADDU k0, k0, k1
-UserTLBIOdd:
- mfc0 k0, COP_0_TLB_INDEX
- nop
- bltz k0, _C_LABEL(MipsUserGenException)
- sltiu k0, k0, VMWIRED_ENTRIES # index below wired entries?
+ /*
+ * Stash the original value of 'sp' so we can update trapframe later.
+ * We assume that SAVE_CPU does not trash 'k1'.
+ */
+ move k1, sp
- bne k0, zero, _C_LABEL(MipsUserGenException)
- lw k0, 0(k1) # get PTE entry
-
- _SLL k0, k0, WIRED_SHIFT # get rid of wired bit
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO1 # save PTE entry
- and k0, k0, PTE_V # check for valid entry
- nop # required for QED5230
- beq k0, zero, _C_LABEL(MipsUserGenException) # PTE invalid
- lw k0, -4(k1) # get even PTE entry
- _SLL k0, k0, WIRED_SHIFT
- _SRL k0, k0, WIRED_SHIFT
- _MTC0 k0, COP_0_TLB_LO0 # save PTE entry
- HAZARD_DELAY
- tlbwi # update TLB
- HAZARD_DELAY
- eret
+ move sp, k0
+ PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE
- .set at
-END(MipsUserTLBInvalidException)
+ move k0, ra
+ move ra, zero
+ REG_S ra, CALLFRAME_RA(sp) /* stop the ddb backtrace right here */
+ REG_S zero, CALLFRAME_SP(sp)
+ move ra, k0
+
+ SAVE_CPU
+
+ /*
+ * Now restore the value of 'sp' at the time of the tlb exception in
+ * the trapframe.
+ */
+ SAVE_REG(k1, SP, sp)
+
+ /*
+ * Squelch any more overflow checks by setting the stack base to 0.
+ */
+ GET_CPU_PCPU(k1)
+ PTR_L k0, PC_CURTHREAD(k1)
+ PTR_S zero, TD_KSTACK(k0)
+
+ move a1, a0
+ PANIC("kernel stack overflow - trapframe at %p")
+
+ /*
+ * This nop is necessary so that the 'ra' remains within the bounds
+ * of this handler. Otherwise the ddb backtrace code will think that
+ * the panic() was called from MipsTLBMissException.
+ */
+ nop
+
+ .set pop
+END(MipsTLBInvalidException)
/*----------------------------------------------------------------------------
*
@@ -1017,99 +955,33 @@ END(MipsUserTLBInvalidException)
*/
NLEAF(MipsTLBMissException)
.set noat
- mfc0 k0, COP_0_BAD_VADDR # k0=bad address
- li k1, (VM_MAX_KERNEL_ADDRESS) # check fault address against
- sltu k1, k1, k0 # upper bound of kernel_segmap
- bnez k1, _C_LABEL(MipsKernGenException) # out of bound
- lui k1, %hi(_C_LABEL(kernel_segmap)) # k1=hi of segbase
- srl k0, 20 # k0=seg offset (almost)
- lw k1, %lo(_C_LABEL(kernel_segmap))(k1) # k1=segment tab base
- beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no seg tab
- andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
-#xxx mips64 unsafe
- addu k1, k0, k1 # k1=seg entry address
- lw k1, 0(k1) # k1=seg entry
- mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again)
- beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no page table
- srl k0, 10 # k0=VPN (aka va>>10)
- andi k0, k0, 0xff8 # k0=page tab offset
-#xxx mips64 unsafe
- addu k1, k1, k0 # k1=pte address
- lw k0, 0(k1) # k0=lo0 pte
- lw k1, 4(k1) # k1=lo1 pte
- _SLL k0, WIRED_SHIFT # chop bits [31..30]
- _SRL k0, WIRED_SHIFT # chop bits [31..30]
- _MTC0 k0, COP_0_TLB_LO0 # lo0 is loaded
- _SLL k1, WIRED_SHIFT # chop bits [31..30]
- _SRL k1, WIRED_SHIFT # chop bits [31..30]
- _MTC0 k1, COP_0_TLB_LO1 # lo1 is loaded
-
- HAZARD_DELAY
+ MFC0 k0, COP_0_BAD_VADDR # k0=bad address
+ PTR_LI k1, VM_MAX_KERNEL_ADDRESS # check fault address against
+ sltu k1, k1, k0 # upper bound of kernel_segmap
+ bnez k1, MipsKernGenException # out of bound
+ lui k1, %hi(kernel_segmap) # k1=hi of segbase
+ PTR_SRL k0, SEGSHIFT - 2 # k0=seg offset (almost)
+ PTR_L k1, %lo(kernel_segmap)(k1) # k1=segment tab base
+ beq k1, zero, MipsKernGenException # ==0 -- no seg tab
+ andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
+ PTR_ADDU k1, k0, k1 # k1=seg entry address
+ PTR_L k1, 0(k1) # k1=seg entry
+ MFC0 k0, COP_0_BAD_VADDR # k0=bad address (again)
+ beq k1, zero, MipsKernGenException # ==0 -- no page table
+ PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN
+ andi k0, k0, 0xff8 # k0=page tab offset
+ PTR_ADDU k1, k1, k0 # k1=pte address
+ lw k0, 0(k1) # k0=lo0 pte
+ lw k1, 4(k1) # k1=lo1 pte
+ CLEAR_PTE_SWBITS(k0)
+ MTC0 k0, COP_0_TLB_LO0 # lo0 is loaded
+ COP0_SYNC
+ CLEAR_PTE_SWBITS(k1)
+ MTC0 k1, COP_0_TLB_LO1 # lo1 is loaded
+ COP0_SYNC
tlbwr # write to tlb
HAZARD_DELAY
eret # return from exception
-
-sys_stk_chk:
- GET_CPU_PCPU(k0)
- lw k0, PC_CURTHREAD(k0)
- lw k0, TD_REALKSTACK(k0)
- sltu k0, sp, k0 # check for stack overflow
- beqz k0, _C_LABEL(MipsKernGenException) # not stack overflow
- nop
-
-# stack overflow
- PTR_LA a0, _C_LABEL(_start) - START_FRAME - 8 # set sp to a valid place
- sw sp, 24(a0)
- move sp, a0
- PTR_LA a0, 1f
- mfc0 a2, COP_0_STATUS_REG
- mfc0 a3, COP_0_CAUSE_REG
- _MFC0 a1, COP_0_EXC_PC
- sw a2, 16(sp)
- sw a3, 20(sp)
- move a2, ra
- PTR_LA k0, _C_LABEL(printf)
- jalr k0
- mfc0 a3, COP_0_BAD_VADDR
-
- PTR_LA sp, _C_LABEL(_start) - START_FRAME # set sp to a valid place
-
-#if !defined(SMP) && defined(DDB)
- PTR_LA a0, 2f
- PTR_LA k0, _C_LABEL(trapDump)
- jalr k0
- nop
-
- li a0, 0
- lw a1, _C_LABEL(num_tlbentries)
- PTR_LA k0, _C_LABEL(db_dump_tlb)
- jalr k0
- addu a1, -1
-
-3:
- b 3b
- nop
-#endif
-
- PANIC("kernel stack overflow")
-
- .data
- .globl lastktlbmiss
-lastktlbmiss:
- .word 0
-lastktlbmisspc:
- .word 0
-lastutlbmiss:
- .word 0
-lastutlbmisspc:
- .word 0
-
-1:
- .asciiz "ktlbmiss: PC %x RA %x ADR %x\nSR %x CR %x SP %x\n"
-2:
- .asciiz "stack ovf"
- .text
-
.set at
END(MipsTLBMissException)
@@ -1132,11 +1004,11 @@ END(MipsTLBMissException)
*
*----------------------------------------------------------------------------
*/
-NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
- subu sp, sp, STAND_FRAME_SIZE
+NON_LEAF(MipsFPTrap, CALLFRAME_SIZ, ra)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
mfc0 t0, COP_0_STATUS_REG
- sw ra, STAND_RA_OFFSET(sp)
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
+ REG_S ra, CALLFRAME_RA(sp)
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
or t1, t0, SR_COP_1_BIT
mtc0 t1, COP_0_STATUS_REG
@@ -1157,10 +1029,10 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
* The instruction is in the branch delay slot so the branch will have to
* be emulated to get the resulting PC.
*/
- sw a2, STAND_FRAME_SIZE + 8(sp)
+ PTR_S a2, CALLFRAME_SIZ + 8(sp)
GET_CPU_PCPU(a0)
#mips64 unsafe?
- lw a0, PC_CURPCB(a0)
+ PTR_L a0, PC_CURPCB(a0)
PTR_ADDU a0, a0, U_PCB_REGS # first arg is ptr to CPU registers
move a1, a2 # second arg is instruction PC
move a2, t1 # third arg is floating point CSR
@@ -1171,7 +1043,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
* Now load the floating-point instruction in the branch delay slot
* to be emulated.
*/
- lw a2, STAND_FRAME_SIZE + 8(sp) # restore EXC pc
+ PTR_L a2, CALLFRAME_SIZ + 8(sp) # restore EXC pc
b 2f
lw a0, 4(a2) # a0 = coproc instruction
/*
@@ -1181,10 +1053,10 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
1:
lw a0, 0(a2) # a0 = coproc instruction
#xxx mips64 unsafe?
- addu v0, a2, 4 # v0 = next pc
+ PTR_ADDU v0, a2, 4 # v0 = next pc
2:
GET_CPU_PCPU(t2)
- lw t2, PC_CURPCB(t2)
+ PTR_L t2, PC_CURPCB(t2)
SAVE_U_PCB_REG(v0, PC, t2) # save new pc
/*
* Check to see if the instruction to be emulated is a floating-point
@@ -1198,7 +1070,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
*/
3:
GET_CPU_PCPU(a0)
- lw a0, PC_CURTHREAD(a0) # get current thread
+ PTR_L a0, PC_CURTHREAD(a0) # get current thread
cfc1 a2, FPC_CSR # code = FP execptions
ctc1 zero, FPC_CSR # Clear exceptions
PTR_LA t3, _C_LABEL(trapsignal)
@@ -1220,12 +1092,12 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
*/
FPReturn:
mfc0 t0, COP_0_STATUS_REG
- lw ra, STAND_RA_OFFSET(sp)
+ PTR_L ra, CALLFRAME_RA(sp)
and t0, t0, ~SR_COP_1_BIT
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
j ra
- PTR_ADDU sp, sp, STAND_FRAME_SIZE
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
END(MipsFPTrap)
/*
@@ -1253,7 +1125,7 @@ VECTOR(MipsCache, unknown)
PTR_LA k0, _C_LABEL(MipsCacheException)
li k1, MIPS_PHYS_MASK
and k0, k1
- li k1, MIPS_UNCACHED_MEMORY_ADDR
+ PTR_LI k1, MIPS_KSEG1_START
or k0, k1
j k0
nop
@@ -1271,16 +1143,16 @@ NESTED_NOPROFILE(MipsCacheException, KERN_EXC_FRAME_SIZE, ra)
.mask 0x80000000, -4
PTR_LA k0, _C_LABEL(panic) # return to panic
PTR_LA a0, 9f # panicstr
- _MFC0 a1, COP_0_ERROR_PC
+ MFC0 a1, COP_0_ERROR_PC
mfc0 a2, COP_0_CACHE_ERR # 3rd arg cache error
- _MTC0 k0, COP_0_ERROR_PC # set return address
+ MTC0 k0, COP_0_ERROR_PC # set return address
mfc0 k0, COP_0_STATUS_REG # restore status
li k1, SR_DIAG_DE # ignore further errors
or k0, k1
mtc0 k0, COP_0_STATUS_REG # restore status
- HAZARD_DELAY
+ COP0_SYNC
eret
diff --git a/sys/mips/mips/fp.S b/sys/mips/mips/fp.S
index afe9f03..ce1702e 100644
--- a/sys/mips/mips/fp.S
+++ b/sys/mips/mips/fp.S
@@ -94,9 +94,9 @@
*
*----------------------------------------------------------------------------
*/
-NON_LEAF(MipsEmulateFP, STAND_FRAME_SIZE, ra)
- subu sp, sp, STAND_FRAME_SIZE
- sw ra, STAND_RA_OFFSET(sp)
+NON_LEAF(MipsEmulateFP, CALLFRAME_SIZ, ra)
+ subu sp, sp, CALLFRAME_SIZ
+ sw ra, CALLFRAME_RA(sp)
/*
* Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0).
*/
@@ -2247,8 +2247,8 @@ result_fs_d: # result is FS
jal set_fd_d # save result (in t0,t1,t2,t3)
done:
- lw ra, STAND_RA_OFFSET(sp)
- addu sp, sp, STAND_FRAME_SIZE
+ lw ra, CALLFRAME_RA(sp)
+ addu sp, sp, CALLFRAME_SIZ
j ra
END(MipsEmulateFP)
diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c
index 62da8f1..53f962b 100644
--- a/sys/mips/mips/genassym.c
+++ b/sys/mips/mips/genassym.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/proc.h>
+#include <machine/cpuregs.h>
#include <machine/pcb.h>
#include <machine/sigframe.h>
#include <machine/proc.h>
@@ -65,7 +66,7 @@ __FBSDID("$FreeBSD$");
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_UPTE, offsetof(struct thread, td_md.md_upte));
-ASSYM(TD_REALKSTACK, offsetof(struct thread, td_md.md_realstack));
+ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack));
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
@@ -87,15 +88,18 @@ ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
-ASSYM(VM_KERNEL_ALLOC_OFFSET, VM_KERNEL_ALLOC_OFFSET);
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
ASSYM(SIGFPE, SIGFPE);
ASSYM(PAGE_SHIFT, PAGE_SHIFT);
-ASSYM(PGSHIFT, PGSHIFT);
-ASSYM(NBPG, NBPG);
+ASSYM(PAGE_SIZE, PAGE_SIZE);
+ASSYM(PAGE_MASK, PAGE_MASK);
ASSYM(SEGSHIFT, SEGSHIFT);
ASSYM(NPTEPG, NPTEPG);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(PCPU_SIZE, sizeof(struct pcpu));
ASSYM(MAXCOMLEN, MAXCOMLEN);
+
+ASSYM(MIPS_KSEG0_START, MIPS_KSEG0_START);
+ASSYM(MIPS_KSEG1_START, MIPS_KSEG1_START);
+ASSYM(MIPS_KSEG2_START, MIPS_KSEG2_START);
diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S
index 1365e8e..d626add 100644
--- a/sys/mips/mips/locore.S
+++ b/sys/mips/mips/locore.S
@@ -162,14 +162,26 @@ VECTOR(_locore, unknown)
sw a2, _C_LABEL(fenvp)
#endif
+#if defined(TARGET_OCTEON) && defined(SMP)
+ .set push
+ .set mips32r2
+ rdhwr t2, $0
+ beqz t2, 1f
+ nop
+ j octeon_ap_wait
+ nop
+ .set pop
+1:
+#endif
+
/*
* Initialize stack and call machine startup.
*/
PTR_LA sp, _C_LABEL(pcpu_space)
- addiu sp, (NBPG * 2) - START_FRAME
+ addiu sp, (PAGE_SIZE * 2) - CALLFRAME_SIZ
- sw zero, START_FRAME - 4(sp) # Zero out old ra for debugger
- sw zero, START_FRAME - 8(sp) # Zero out old fp for debugger
+ sw zero, CALLFRAME_SIZ - 4(sp) # Zero out old ra for debugger
+ sw zero, CALLFRAME_SIZ - 8(sp) # Zero out old fp for debugger
PTR_LA gp, _C_LABEL(_gp)
@@ -178,13 +190,13 @@ VECTOR(_locore, unknown)
nop
PTR_LA sp, _C_LABEL(thread0)
- lw a0, TD_PCB(sp)
- li t0, ~7
+ PTR_L a0, TD_PCB(sp)
+ REG_LI t0, ~7
and a0, a0, t0
- subu sp, a0, START_FRAME
+ PTR_SUBU sp, a0, CALLFRAME_SIZ
jal _C_LABEL(mi_startup) # mi_startup(frame)
- sw zero, START_FRAME - 8(sp) # Zero out old fp for debugger
+ sw zero, CALLFRAME_SIZ - 8(sp) # Zero out old fp for debugger
PANIC("Startup failed!")
diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c
index ad1dab5..a9c484c 100644
--- a/sys/mips/mips/machdep.c
+++ b/sys/mips/mips/machdep.c
@@ -142,10 +142,6 @@ vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2];
struct platform platform;
#endif
-vm_paddr_t mips_wired_tlb_physmem_start;
-vm_paddr_t mips_wired_tlb_physmem_end;
-u_int need_wired_tlb_page_pool;
-
static void cpu_startup(void *);
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
@@ -302,14 +298,13 @@ mips_proc0_init(void)
(long)kstack0));
thread0.td_kstack = kstack0;
thread0.td_kstack_pages = KSTACK_PAGES;
- thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2);
/*
* Do not use cpu_thread_alloc to initialize these fields
* thread0 is the only thread that has kstack located in KSEG0
* while cpu_thread_alloc handles kstack allocated in KSEG2.
*/
- thread0.td_pcb = (struct pcb *)(thread0.td_md.md_realstack +
- (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1;
+ thread0.td_pcb = (struct pcb *)(thread0.td_kstack +
+ thread0.td_kstack_pages * PAGE_SIZE) - 1;
thread0.td_frame = &thread0.td_pcb->pcb_regs;
/* Steal memory for the dynamic per-cpu area. */
@@ -374,11 +369,9 @@ mips_vector_init(void)
* when handler is installed for it
*/
set_intr_mask(ALL_INT_MASK);
- enableintr();
/* Clear BEV in SR so we start handling our own exceptions */
- mips_cp0_status_write(mips_cp0_status_read() & ~SR_BOOT_EXC_VEC);
-
+ mips_wr_status(mips_rd_status() & ~SR_BOOT_EXC_VEC);
}
/*
@@ -475,7 +468,7 @@ spinlock_enter(void)
td = curthread;
if (td->td_md.md_spinlock_count == 0)
- td->td_md.md_saved_intr = disableintr();
+ td->td_md.md_saved_intr = intr_disable();
td->td_md.md_spinlock_count++;
critical_enter();
}
@@ -489,16 +482,7 @@ spinlock_exit(void)
critical_exit();
td->td_md.md_spinlock_count--;
if (td->td_md.md_spinlock_count == 0)
- restoreintr(td->td_md.md_saved_intr);
-}
-
-u_int32_t
-get_cyclecount(void)
-{
- u_int32_t count;
-
- mfc0_macro(count, 9);
- return (count);
+ intr_restore(td->td_md.md_saved_intr);
}
/*
@@ -507,7 +491,7 @@ get_cyclecount(void)
void
cpu_idle(int busy)
{
- if (mips_cp0_status_read() & SR_INT_ENAB)
+ if (mips_rd_status() & SR_INT_ENAB)
__asm __volatile ("wait");
else
panic("ints disabled in idleproc!");
diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c
index c0e88e0..9db282e 100644
--- a/sys/mips/mips/mem.c
+++ b/sys/mips/mips/mem.c
@@ -1,13 +1,12 @@
-/* $OpenBSD: mem.c,v 1.2 1998/08/31 17:42:34 millert Exp $ */
-/* $NetBSD: mem.c,v 1.6 1995/04/10 11:55:03 mycroft Exp $ */
-/*
+/*-
* Copyright (c) 1988 University of Utah.
- * Copyright (c) 1982, 1986, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
- * Science Department and Ralph Campbell.
+ * Science Department, and code derived from software contributed to
+ * Berkeley by William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,161 +32,138 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)mem.c 8.3 (Berkeley) 1/12/94
- * JNPR: mem.c,v 1.3 2007/08/09 11:23:32 katta Exp $
+ * from: Utah $Hdr: mem.c 1.13 89/10/08$
+ * from: @(#)mem.c 7.2 (Berkeley) 5/9/91
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
/*
* Memory special file
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/param.h>
-#include <sys/kernel.h>
#include <sys/conf.h>
+#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/memrange.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/pmap.h>
-#include <vm/vm_map.h>
-#include <sys/user.h>
#include <sys/msgbuf.h>
#include <sys/systm.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
+#include <sys/signalvar.h>
#include <sys/uio.h>
-#include <sys/sched.h>
-#include <sys/malloc.h>
-#include <machine/pte.h>
-#include <machine/cpu.h>
+
#include <machine/md_var.h>
-#include <machine/atomic.h>
+#include <machine/vmparam.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_page.h>
+
#include <machine/memdev.h>
+struct mem_range_softc mem_range_softc;
-extern struct sysmaps sysmaps_pcpu[];
-/*ARGSUSED*/
+/* ARGSUSED */
int
-memrw(dev, uio, flags)
- struct cdev *dev;
- struct uio *uio;
- int flags;
+memrw(struct cdev *dev, struct uio *uio, int flags)
{
- register vm_offset_t v;
- register int c;
- register struct iovec *iov;
+ struct iovec *iov;
int error = 0;
+ vm_offset_t va, eva, off, v;
+ vm_prot_t prot;
+ struct vm_page m;
+ vm_page_t marr;
+ vm_size_t cnt;
+
+ cnt = 0;
+ error = 0;
- while (uio->uio_resid > 0 && error == 0) {
+ GIANT_REQUIRED;
+
+ while (uio->uio_resid > 0 && !error) {
iov = uio->uio_iov;
if (iov->iov_len == 0) {
uio->uio_iov++;
uio->uio_iovcnt--;
if (uio->uio_iovcnt < 0)
- panic("mmrw");
+ panic("memrw");
continue;
}
-
- /* minor device 0 is physical memory */
if (dev2unit(dev) == CDEV_MINOR_MEM) {
v = uio->uio_offset;
- c = iov->iov_len;
-
- vm_offset_t va;
- vm_paddr_t pa;
- register int o;
-
- if (is_cacheable_mem(v) &&
- is_cacheable_mem(v + c - 1)) {
- struct fpage *fp;
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- sched_pin();
-
- fp = &sysmaps->fp[PMAP_FPAGE1];
- pa = uio->uio_offset & ~PAGE_MASK;
- va = pmap_map_fpage(pa, fp, FALSE);
- o = (int)uio->uio_offset & PAGE_MASK;
- c = (u_int)(PAGE_SIZE -
- ((uintptr_t)iov->iov_base & PAGE_MASK));
- c = min(c, (u_int)(PAGE_SIZE - o));
- c = min(c, (u_int)iov->iov_len);
- error = uiomove((caddr_t)(va + o), (int)c, uio);
- pmap_unmap_fpage(pa, fp);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
- } else
- return (EFAULT);
- continue;
- }
- /* minor device 1 is kernel memory */
+ off = uio->uio_offset & PAGE_MASK;
+ cnt = PAGE_SIZE - ((vm_offset_t)iov->iov_base &
+ PAGE_MASK);
+ cnt = min(cnt, PAGE_SIZE - off);
+ cnt = min(cnt, iov->iov_len);
+
+ m.phys_addr = trunc_page(v);
+ marr = &m;
+ error = uiomove_fromphys(&marr, off, cnt, uio);
+ }
else if (dev2unit(dev) == CDEV_MINOR_KMEM) {
- v = uio->uio_offset;
- c = min(iov->iov_len, MAXPHYS);
+ va = uio->uio_offset;
- vm_offset_t addr, eaddr;
- vm_offset_t wired_tlb_virtmem_end;
+ va = trunc_page(uio->uio_offset);
+ eva = round_page(uio->uio_offset
+ + iov->iov_len);
- /*
- * Make sure that all of the pages are currently
- * resident so that we don't create any zero-fill pages.
+ /*
+ * Make sure that all the pages are currently resident
+ * so that we don't create any zero-fill pages.
*/
- addr = trunc_page(uio->uio_offset);
- eaddr = round_page(uio->uio_offset + c);
-
- if (addr > (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
- wired_tlb_virtmem_end = VM_MIN_KERNEL_ADDRESS +
- VM_KERNEL_ALLOC_OFFSET;
- if ((addr < wired_tlb_virtmem_end) &&
- (eaddr >= wired_tlb_virtmem_end))
- addr = wired_tlb_virtmem_end;
-
- if (addr >= wired_tlb_virtmem_end) {
- for (; addr < eaddr; addr += PAGE_SIZE)
- if (pmap_extract(kernel_pmap,
- addr) == 0)
- return EFAULT;
-
- if (!kernacc(
- (caddr_t)(uintptr_t)uio->uio_offset, c,
- uio->uio_rw == UIO_READ ?
- VM_PROT_READ : VM_PROT_WRITE))
+ if (va >= VM_MIN_KERNEL_ADDRESS &&
+ eva <= VM_MAX_KERNEL_ADDRESS) {
+ for (; va < eva; va += PAGE_SIZE)
+ if (pmap_extract(kernel_pmap, va) == 0)
return (EFAULT);
- }
- }
- else if (MIPS_IS_KSEG0_ADDR(v)) {
- if (MIPS_KSEG0_TO_PHYS(v + c) >= ctob(physmem))
- return (EFAULT);
- }
- else if (MIPS_IS_KSEG1_ADDR(v)) {
- if (MIPS_KSEG1_TO_PHYS(v + c) >= ctob(physmem))
+
+ prot = (uio->uio_rw == UIO_READ)
+ ? VM_PROT_READ : VM_PROT_WRITE;
+
+ va = uio->uio_offset;
+ if (kernacc((void *) va, iov->iov_len, prot)
+ == FALSE)
return (EFAULT);
}
- else
- return (EFAULT);
-
- error = uiomove((caddr_t)v, c, uio);
+ va = uio->uio_offset;
+ error = uiomove((void *)va, iov->iov_len, uio);
continue;
}
-
}
+
return (error);
}
-/*ARGSUSED*/
+/*
+ * allow user processes to MMAP some memory sections
+ * instead of going through read/write
+ */
int
-memmmap(struct cdev *dev, vm_ooffset_t off, vm_paddr_t *paddr,
+memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
int prot, vm_memattr_t *memattr)
{
-
- return (EOPNOTSUPP);
+ /*
+ * /dev/mem is the only one that makes sense through this
+ * interface. For /dev/kmem any physaddr we return here
+ * could be transient and hence incorrect or invalid at
+ * a later time.
+ */
+ if (dev2unit(dev) != CDEV_MINOR_MEM)
+ return (-1);
+
+ *paddr = offset;
+
+ return (0);
}
void
diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c
index d8520cc..f0c142f 100644
--- a/sys/mips/mips/mp_machdep.c
+++ b/sys/mips/mips/mp_machdep.c
@@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <machine/cache.h>
+struct pcb stoppcbs[MAXCPU];
+
static void *dpcpu;
static struct mtx ap_boot_mtx;
@@ -88,10 +90,14 @@ ipi_selected(cpumask_t cpus, int ipi)
static int
mips_ipi_handler(void *arg)
{
+ int cpu;
cpumask_t cpumask;
u_int ipi, ipi_bitmap;
int bit;
+ cpu = PCPU_GET(cpuid);
+ cpumask = PCPU_GET(cpumask);
+
platform_ipi_clear(); /* quiesce the pending ipi interrupt */
ipi_bitmap = atomic_readandclear_int(PCPU_PTR(pending_ipis));
@@ -120,10 +126,17 @@ mips_ipi_handler(void *arg)
* necessary to add it in the switch.
*/
CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD");
- cpumask = PCPU_GET(cpumask);
+
+ savectx(&stoppcbs[cpu]);
+ pmap_save_tlb();
+
+ /* Indicate we are stopped */
atomic_set_int(&stopped_cpus, cpumask);
+
+ /* Wait for restart */
while ((started_cpus & cpumask) == 0)
cpu_spinwait();
+
atomic_clear_int(&started_cpus, cpumask);
atomic_clear_int(&stopped_cpus, cpumask);
CTR0(KTR_SMP, "IPI_STOP (restart)");
@@ -144,6 +157,8 @@ start_ap(int cpuid)
cpus = mp_naps;
dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
+ mips_sync();
+
if (platform_start_ap(cpuid) != 0)
return (-1); /* could not start AP */
@@ -233,6 +248,8 @@ smp_init_secondary(u_int32_t cpuid)
mips_dcache_wbinv_all();
mips_icache_sync_all();
+ mips_sync();
+
MachSetPID(0);
pcpu_init(PCPU_ADDR(cpuid), cpuid, sizeof(struct pcpu));
@@ -283,7 +300,7 @@ smp_init_secondary(u_int32_t cpuid)
*/
mips_wr_compare(mips_rd_count() + counter_freq / hz);
- enableintr();
+ intr_enable();
/* enter the scheduler */
sched_throw(NULL);
diff --git a/sys/mips/mips/mpboot.S b/sys/mips/mips/mpboot.S
index 6828847..631099c 100644
--- a/sys/mips/mips/mpboot.S
+++ b/sys/mips/mips/mpboot.S
@@ -36,8 +36,21 @@
.set noat
.set noreorder
+#ifdef TARGET_OCTEON
+#define CLEAR_STATUS \
+ mfc0 a0, COP_0_STATUS_REG ;\
+ li a2, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) ; \
+ or a0, a0, a2 ; \
+ li a2, ~(MIPS_SR_INT_IE | MIPS_SR_EXL | SR_KSU_USER | MIPS_SR_BEV) ; \
+ and a0, a0, a2 ; \
+ mtc0 a0, COP_0_STATUS_REG
+#else
+#define CLEAR_STATUS \
+ mtc0 zero, COP_0_STATUS_REG
+#endif
+
GLOBAL(mpentry)
- mtc0 zero, COP_0_STATUS_REG /* disable interrupts */
+ CLEAR_STATUS /* disable interrupts */
mtc0 zero, COP_0_CAUSE_REG /* clear soft interrupts */
@@ -53,13 +66,13 @@ GLOBAL(mpentry)
* Initialize stack and call machine startup
*/
PTR_LA sp, _C_LABEL(pcpu_space)
- addiu sp, (NBPG * 2) - START_FRAME
+ addiu sp, (PAGE_SIZE * 2) - CALLFRAME_SIZ
sll t0, s0, PAGE_SHIFT + 1
addu sp, sp, t0
/* Zero out old ra and old fp for debugger */
- sw zero, START_FRAME - 4(sp)
- sw zero, START_FRAME - 8(sp)
+ sw zero, CALLFRAME_SIZ - 4(sp)
+ sw zero, CALLFRAME_SIZ - 8(sp)
PTR_LA gp, _C_LABEL(_gp)
diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c
index 7d3f190..10b38b5 100644
--- a/sys/mips/mips/nexus.c
+++ b/sys/mips/mips/nexus.c
@@ -73,7 +73,6 @@ struct nexus_device {
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
#define NUM_MIPS_IRQS 6
-#define MIPS_MEM_RID 0x20
static struct rman irq_rman;
static struct rman mem_rman;
@@ -167,16 +166,19 @@ static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
+ register_t s;
int irq;
- intrmask_t s = disableintr();
+ s = intr_disable();
irq = rman_get_start(res);
- if (irq >= NUM_MIPS_IRQS)
+ if (irq >= NUM_MIPS_IRQS) {
+ intr_restore(s);
return (0);
+ }
cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg,
irq, flags, cookiep);
- restoreintr(s);
+ intr_restore(s);
return (0);
}
diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c
index 712763b..03867b0 100644
--- a/sys/mips/mips/pm_machdep.c
+++ b/sys/mips/mips/pm_machdep.c
@@ -472,7 +472,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs)
* code by the MIPS elf abi).
*/
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
bzero((caddr_t)td->td_frame, sizeof(struct trapframe));
@@ -481,8 +481,8 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
* Make sp 64-bit aligned.
*/
td->td_frame->sp = ((register_t) stack) & ~(sizeof(__int64_t) - 1);
- td->td_frame->pc = entry & ~3;
- td->td_frame->t9 = entry & ~3; /* abicall req */
+ td->td_frame->pc = imgp->entry_addr & ~3;
+ td->td_frame->t9 = imgp->entry_addr & ~3; /* abicall req */
#if 0
// td->td_frame->sr = SR_KSU_USER | SR_EXL | SR_INT_ENAB;
//? td->td_frame->sr |= idle_mask & ALL_INT_MASK;
@@ -511,7 +511,7 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
td->td_frame->a0 = (register_t) stack;
td->td_frame->a1 = 0;
td->td_frame->a2 = 0;
- td->td_frame->a3 = (register_t)ps_strings;
+ td->td_frame->a3 = (register_t)imgp->ps_strings;
td->td_md.md_flags &= ~MDTD_FPUSED;
if (PCPU_GET(fpcurthread) == td)
diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
index 4a267dc..3634a27 100644
--- a/sys/mips/mips/pmap.c
+++ b/sys/mips/mips/pmap.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <sys/msgbuf.h>
#include <sys/vmmeter.h>
#include <sys/mman.h>
+#include <sys/smp.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -149,6 +150,8 @@ unsigned pmap_max_asid; /* max ASID supported by the system */
vm_offset_t kernel_vm_end;
+static struct tlb tlbstash[MAXCPU][MIPS_MAX_TLB_ENTRIES];
+
static void pmap_asid_alloc(pmap_t pmap);
/*
@@ -158,10 +161,6 @@ static uma_zone_t pvzone;
static struct vm_object pvzone_obj;
static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0;
-struct fpage fpages_shared[FPAGES_SHARED];
-
-struct sysmaps sysmaps_pcpu[MAXCPU];
-
static PMAP_INLINE void free_pv_entry(pv_entry_t pv);
static pv_entry_t get_pv_entry(pmap_t locked_pmap);
static __inline void pmap_changebit(vm_page_t m, int bit, boolean_t setem);
@@ -185,7 +184,6 @@ static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t);
static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot);
static void pmap_TLB_invalidate_kernel(vm_offset_t);
static void pmap_TLB_update_kernel(vm_offset_t, pt_entry_t);
-static void pmap_init_fpage(void);
#ifdef SMP
static void pmap_invalidate_page_action(void *arg);
@@ -196,16 +194,13 @@ static void pmap_update_page_action(void *arg);
struct local_sysmaps {
struct mtx lock;
- pt_entry_t CMAP1;
- pt_entry_t CMAP2;
- caddr_t CADDR1;
- caddr_t CADDR2;
+ vm_offset_t base;
uint16_t valid1, valid2;
};
/* This structure is for large memory
* above 512Meg. We can't (in 32 bit mode)
- * just use the direct mapped MIPS_CACHED_TO_PHYS()
+ * just use the direct mapped MIPS_KSEG0_TO_PHYS()
* macros since we can't see the memory and must
* map it in when we need to access it. In 64
* bit mode this goes away.
@@ -213,6 +208,59 @@ struct local_sysmaps {
static struct local_sysmaps sysmap_lmem[MAXCPU];
caddr_t virtual_sys_start = (caddr_t)0;
+#define PMAP_LMEM_MAP1(va, phys) \
+ int cpu; \
+ struct local_sysmaps *sysm; \
+ pt_entry_t *pte, npte; \
+ \
+ cpu = PCPU_GET(cpuid); \
+ sysm = &sysmap_lmem[cpu]; \
+ PMAP_LGMEM_LOCK(sysm); \
+ intr = intr_disable(); \
+ sched_pin(); \
+ va = sysm->base; \
+ npte = mips_paddr_to_tlbpfn(phys) | \
+ PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; \
+ pte = pmap_pte(kernel_pmap, va); \
+ *pte = npte; \
+ sysm->valid1 = 1;
+
+#define PMAP_LMEM_MAP2(va1, phys1, va2, phys2) \
+ int cpu; \
+ struct local_sysmaps *sysm; \
+ pt_entry_t *pte, npte; \
+ \
+ cpu = PCPU_GET(cpuid); \
+ sysm = &sysmap_lmem[cpu]; \
+ PMAP_LGMEM_LOCK(sysm); \
+ intr = intr_disable(); \
+ sched_pin(); \
+ va1 = sysm->base; \
+ va2 = sysm->base + PAGE_SIZE; \
+ npte = mips_paddr_to_tlbpfn(phys2) | \
+ PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; \
+ pte = pmap_pte(kernel_pmap, va1); \
+ *pte = npte; \
+ npte = mips_paddr_to_tlbpfn(phys2) | \
+ PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; \
+ pte = pmap_pte(kernel_pmap, va2); \
+ *pte = npte; \
+ sysm->valid1 = 1; \
+ sysm->valid2 = 1;
+
+#define PMAP_LMEM_UNMAP() \
+ pte = pmap_pte(kernel_pmap, sysm->base); \
+ *pte = PTE_G; \
+ pmap_TLB_invalidate_kernel(sysm->base); \
+ sysm->valid1 = 0; \
+ pte = pmap_pte(kernel_pmap, sysm->base + PAGE_SIZE); \
+ *pte = PTE_G; \
+ pmap_TLB_invalidate_kernel(sysm->base + PAGE_SIZE); \
+ sysm->valid2 = 0; \
+ sched_unpin(); \
+ intr_restore(intr); \
+ PMAP_LGMEM_UNLOCK(sysm);
+
pd_entry_t
pmap_segmap(pmap_t pmap, vm_offset_t va)
{
@@ -271,7 +319,7 @@ pmap_steal_memory(vm_size_t size)
if (pa >= MIPS_KSEG0_LARGEST_PHYS) {
panic("Out of memory below 512Meg?");
}
- va = MIPS_PHYS_TO_CACHED(pa);
+ va = MIPS_PHYS_TO_KSEG0(pa);
bzero((caddr_t)va, size);
return va;
}
@@ -352,7 +400,7 @@ again:
kstack0 = pmap_steal_memory(KSTACK_PAGES << PAGE_SHIFT);
- virtual_avail = VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET;
+ virtual_avail = VM_MIN_KERNEL_ADDRESS;
virtual_end = VM_MAX_KERNEL_ADDRESS;
#ifdef SMP
@@ -384,12 +432,8 @@ again:
*/
if (memory_larger_than_512meg) {
for (i = 0; i < MAXCPU; i++) {
- sysmap_lmem[i].CMAP1 = PTE_G;
- sysmap_lmem[i].CMAP2 = PTE_G;
- sysmap_lmem[i].CADDR1 = (caddr_t)virtual_avail;
- virtual_avail += PAGE_SIZE;
- sysmap_lmem[i].CADDR2 = (caddr_t)virtual_avail;
- virtual_avail += PAGE_SIZE;
+ sysmap_lmem[i].base = virtual_avail;
+ virtual_avail += PAGE_SIZE * 2;
sysmap_lmem[i].valid1 = sysmap_lmem[i].valid2 = 0;
PMAP_LGMEM_LOCK_INIT(&sysmap_lmem[i]);
}
@@ -477,8 +521,6 @@ void
pmap_init(void)
{
- if (need_wired_tlb_page_pool)
- pmap_init_fpage();
/*
* Initialize the address space (zone) for the pv entries. Set a
* high water mark so that the system can recover from excessive
@@ -567,7 +609,7 @@ pmap_invalidate_page_action(void *arg)
pmap->pm_asid[PCPU_GET(cpuid)].gen = 0;
return;
}
- va = pmap_va_asid(pmap, (va & ~PGOFSET));
+ va = pmap_va_asid(pmap, (va & ~PAGE_MASK));
mips_TBIS(va);
}
@@ -618,7 +660,7 @@ pmap_update_page_action(void *arg)
pmap->pm_asid[PCPU_GET(cpuid)].gen = 0;
return;
}
- va = pmap_va_asid(pmap, va);
+ va = pmap_va_asid(pmap, (va & ~PAGE_MASK));
MachTLBUpdate(va, pte);
}
@@ -627,6 +669,8 @@ pmap_TLB_update_kernel(vm_offset_t va, pt_entry_t pte)
{
u_int32_t pid;
+ va &= ~PAGE_MASK;
+
MachTLBGetPID(pid);
va = va | (pid << VMTLB_PID_SHIFT);
@@ -723,7 +767,7 @@ pmap_kremove(vm_offset_t va)
/*
* Write back all caches from the page being destroyed
*/
- mips_dcache_wbinv_range_index(va, NBPG);
+ mips_dcache_wbinv_range_index(va, PAGE_SIZE);
pte = pmap_pte(kernel_pmap, va);
*pte = PTE_G;
@@ -802,136 +846,6 @@ pmap_qremove(vm_offset_t va, int count)
* Page table page management routines.....
***************************************************/
-/*
- * floating pages (FPAGES) management routines
- *
- * FPAGES are the reserved virtual memory areas which can be
- * mapped to any physical memory. This gets used typically
- * in the following functions:
- *
- * pmap_zero_page
- * pmap_copy_page
- */
-
-/*
- * Create the floating pages, aka FPAGES!
- */
-static void
-pmap_init_fpage()
-{
- vm_offset_t kva;
- int i, j;
- struct sysmaps *sysmaps;
-
- /*
- * We allocate a total of (FPAGES*MAXCPU + FPAGES_SHARED + 1) pages
- * at first. FPAGES & FPAGES_SHARED should be EVEN Then we'll adjust
- * 'kva' to be even-page aligned so that the fpage area can be wired
- * in the TLB with a single TLB entry.
- */
- kva = kmem_alloc_nofault(kernel_map,
- (FPAGES * MAXCPU + 1 + FPAGES_SHARED) * PAGE_SIZE);
- if ((void *)kva == NULL)
- panic("pmap_init_fpage: fpage allocation failed");
-
- /*
- * Make up start at an even page number so we can wire down the
- * fpage area in the tlb with a single tlb entry.
- */
- if ((((vm_offset_t)kva) >> PGSHIFT) & 1) {
- /*
- * 'kva' is not even-page aligned. Adjust it and free the
- * first page which is unused.
- */
- kmem_free(kernel_map, (vm_offset_t)kva, NBPG);
- kva = ((vm_offset_t)kva) + NBPG;
- } else {
- /*
- * 'kva' is even page aligned. We don't need the last page,
- * free it.
- */
- kmem_free(kernel_map, ((vm_offset_t)kva) + FSPACE, NBPG);
- }
-
- for (i = 0; i < MAXCPU; i++) {
- sysmaps = &sysmaps_pcpu[i];
- mtx_init(&sysmaps->lock, "SYSMAPS", NULL, MTX_DEF);
-
- /* Assign FPAGES pages to the CPU */
- for (j = 0; j < FPAGES; j++)
- sysmaps->fp[j].kva = kva + (j) * PAGE_SIZE;
- kva = ((vm_offset_t)kva) + (FPAGES * PAGE_SIZE);
- }
-
- /*
- * An additional 2 pages are needed, one for pmap_zero_page_idle()
- * and one for coredump. These pages are shared by all cpu's
- */
- fpages_shared[PMAP_FPAGE3].kva = kva;
- fpages_shared[PMAP_FPAGE_KENTER_TEMP].kva = kva + PAGE_SIZE;
-}
-
-/*
- * Map the page to the fpage virtual address as specified thru' fpage id
- */
-vm_offset_t
-pmap_map_fpage(vm_paddr_t pa, struct fpage *fp, boolean_t check_unmaped)
-{
- vm_offset_t kva;
- register pt_entry_t *pte;
- pt_entry_t npte;
-
- KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
- /*
- * Check if the fpage is free
- */
- if (fp->state) {
- if (check_unmaped == TRUE)
- pmap_unmap_fpage(pa, fp);
- else
- panic("pmap_map_fpage: fpage is busy");
- }
- fp->state = TRUE;
- kva = fp->kva;
-
- npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- pte = pmap_pte(kernel_pmap, kva);
- *pte = npte;
-
- pmap_TLB_update_kernel(kva, npte);
-
- return (kva);
-}
-
-/*
- * Unmap the page from the fpage virtual address as specified thru' fpage id
- */
-void
-pmap_unmap_fpage(vm_paddr_t pa, struct fpage *fp)
-{
- vm_offset_t kva;
- register pt_entry_t *pte;
-
- KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
- /*
- * Check if the fpage is busy
- */
- if (!(fp->state)) {
- panic("pmap_unmap_fpage: fpage is free");
- }
- kva = fp->kva;
-
- pte = pmap_pte(kernel_pmap, kva);
- *pte = PTE_G;
- pmap_TLB_invalidate_kernel(kva);
-
- fp->state = FALSE;
-
- /*
- * Should there be any flush operation at the end?
- */
-}
-
/* Revision 1.507
*
* Simplify the reference counting of page table pages. Specifically, use
@@ -946,10 +860,21 @@ pmap_unmap_fpage(vm_paddr_t pa, struct fpage *fp)
static int
_pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m)
{
+ vm_offset_t pteva;
/*
* unmap the page table page
*/
+ pteva = (vm_offset_t)pmap->pm_segtab[m->pindex];
+ if (pteva >= VM_MIN_KERNEL_ADDRESS) {
+ pmap_kremove(pteva);
+ kmem_free(kernel_map, pteva, PAGE_SIZE);
+ } else {
+ KASSERT(MIPS_IS_KSEG0_ADDR(pteva),
+ ("_pmap_unwire_pte_hold: 0x%0lx is not in kseg0",
+ (long)pteva));
+ }
+
pmap->pm_segtab[m->pindex] = 0;
--pmap->pm_stats.resident_count;
@@ -994,7 +919,7 @@ pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte)
mpte = pmap->pm_ptphint;
} else {
pteva = *pmap_pde(pmap, va);
- mpte = PHYS_TO_VM_PAGE(MIPS_CACHED_TO_PHYS(pteva));
+ mpte = PHYS_TO_VM_PAGE(vtophys(pteva));
pmap->pm_ptphint = mpte;
}
}
@@ -1026,6 +951,8 @@ pmap_pinit0(pmap_t pmap)
int
pmap_pinit(pmap_t pmap)
{
+ vm_offset_t ptdva;
+ vm_paddr_t ptdpa;
vm_page_t ptdpg;
int i;
int req;
@@ -1035,10 +962,6 @@ pmap_pinit(pmap_t pmap)
req = VM_ALLOC_NOOBJ | VM_ALLOC_NORMAL | VM_ALLOC_WIRED |
VM_ALLOC_ZERO;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool)
- req |= VM_ALLOC_WIRED_TLB_PG_POOL;
-#endif
/*
* allocate the page directory page
*/
@@ -1047,8 +970,17 @@ pmap_pinit(pmap_t pmap)
ptdpg->valid = VM_PAGE_BITS_ALL;
- pmap->pm_segtab = (pd_entry_t *)
- MIPS_PHYS_TO_CACHED(VM_PAGE_TO_PHYS(ptdpg));
+ ptdpa = VM_PAGE_TO_PHYS(ptdpg);
+ if (ptdpa < MIPS_KSEG0_LARGEST_PHYS) {
+ ptdva = MIPS_PHYS_TO_KSEG0(ptdpa);
+ } else {
+ ptdva = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
+ if (ptdva == 0)
+ panic("pmap_pinit: unable to allocate kva");
+ pmap_kenter(ptdva, ptdpa);
+ }
+
+ pmap->pm_segtab = (pd_entry_t *)ptdva;
if ((ptdpg->flags & PG_ZERO) == 0)
bzero(pmap->pm_segtab, PAGE_SIZE);
@@ -1080,10 +1012,6 @@ _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags)
("_pmap_allocpte: flags is neither M_NOWAIT nor M_WAITOK"));
req = VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_NOOBJ;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool)
- req |= VM_ALLOC_WIRED_TLB_PG_POOL;
-#endif
/*
* Find or fabricate a new pagetable page
*/
@@ -1115,7 +1043,15 @@ _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags)
pmap->pm_stats.resident_count++;
ptepa = VM_PAGE_TO_PHYS(m);
- pteva = MIPS_PHYS_TO_CACHED(ptepa);
+ if (ptepa < MIPS_KSEG0_LARGEST_PHYS) {
+ pteva = MIPS_PHYS_TO_KSEG0(ptepa);
+ } else {
+ pteva = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
+ if (pteva == 0)
+ panic("_pmap_allocpte: unable to allocate kva");
+ pmap_kenter(pteva, ptepa);
+ }
+
pmap->pm_segtab[ptepindex] = (pd_entry_t)pteva;
/*
@@ -1169,7 +1105,7 @@ retry:
(pmap->pm_ptphint->pindex == ptepindex)) {
m = pmap->pm_ptphint;
} else {
- m = PHYS_TO_VM_PAGE(MIPS_CACHED_TO_PHYS(pteva));
+ m = PHYS_TO_VM_PAGE(vtophys(pteva));
pmap->pm_ptphint = m;
}
m->wire_count++;
@@ -1209,16 +1145,28 @@ retry:
void
pmap_release(pmap_t pmap)
{
+ vm_offset_t ptdva;
vm_page_t ptdpg;
KASSERT(pmap->pm_stats.resident_count == 0,
("pmap_release: pmap resident count %ld != 0",
pmap->pm_stats.resident_count));
- ptdpg = PHYS_TO_VM_PAGE(MIPS_CACHED_TO_PHYS(pmap->pm_segtab));
+ ptdva = (vm_offset_t)pmap->pm_segtab;
+ ptdpg = PHYS_TO_VM_PAGE(vtophys(ptdva));
+
+ if (ptdva >= VM_MIN_KERNEL_ADDRESS) {
+ pmap_kremove(ptdva);
+ kmem_free(kernel_map, ptdva, PAGE_SIZE);
+ } else {
+ KASSERT(MIPS_IS_KSEG0_ADDR(ptdva),
+ ("pmap_release: 0x%0lx is not in kseg0", (long)ptdva));
+ }
+
ptdpg->wire_count--;
atomic_subtract_int(&cnt.v_wire_count, 1);
vm_page_free_zero(ptdpg);
+ PMAP_LOCK_DESTROY(pmap);
}
/*
@@ -1234,7 +1182,7 @@ pmap_growkernel(vm_offset_t addr)
mtx_assert(&kernel_map->system_mtx, MA_OWNED);
if (kernel_vm_end == 0) {
- kernel_vm_end = VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET;
+ kernel_vm_end = VM_MIN_KERNEL_ADDRESS;
nkpt = 0;
while (segtab_pde(kernel_segmap, kernel_vm_end)) {
kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) &
@@ -1263,10 +1211,6 @@ pmap_growkernel(vm_offset_t addr)
* This index is bogus, but out of the way
*/
req = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool)
- req |= VM_ALLOC_WIRED_TLB_PG_POOL;
-#endif
nkpg = vm_page_alloc(NULL, nkpt, req);
if (!nkpg)
panic("pmap_growkernel: no memory to grow kernel");
@@ -1285,7 +1229,7 @@ pmap_growkernel(vm_offset_t addr)
*/
panic("Gak, can't handle a k-page table outside of lower 512Meg");
}
- pte = (pt_entry_t *)MIPS_PHYS_TO_CACHED(ptppaddr);
+ pte = (pt_entry_t *)MIPS_PHYS_TO_KSEG0(ptppaddr);
segtab_pde(kernel_segmap, kernel_vm_end) = (pd_entry_t)pte;
/*
@@ -1574,7 +1518,7 @@ pmap_remove_page(struct pmap *pmap, vm_offset_t va)
/*
* Write back all caches from the page being destroyed
*/
- mips_dcache_wbinv_range_index(va, NBPG);
+ mips_dcache_wbinv_range_index(va, PAGE_SIZE);
/*
* get a local va for mappings for this pmap.
@@ -1661,7 +1605,7 @@ pmap_remove_all(vm_page_t m)
* the page being destroyed
*/
if (m->md.pv_list_count == 1)
- mips_dcache_wbinv_range_index(pv->pv_va, NBPG);
+ mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE);
pv->pv_pmap->pm_stats.resident_count--;
@@ -1943,7 +1887,7 @@ validate:
if (origpte & PTE_M) {
KASSERT((origpte & PTE_RW),
("pmap_enter: modified page not writable:"
- " va: %p, pte: 0x%lx", (void *)va, origpte));
+ " va: %p, pte: 0x%x", (void *)va, origpte));
if (page_is_managed(opa))
vm_page_dirty(om);
}
@@ -1960,8 +1904,8 @@ validate:
*/
if (!is_kernel_pmap(pmap) && (pmap == &curproc->p_vmspace->vm_pmap) &&
(prot & VM_PROT_EXECUTE)) {
- mips_icache_sync_range(va, NBPG);
- mips_dcache_wbinv_range(va, NBPG);
+ mips_icache_sync_range(va, PAGE_SIZE);
+ mips_dcache_wbinv_range(va, PAGE_SIZE);
}
vm_page_unlock_queues();
PMAP_UNLOCK(pmap);
@@ -2027,7 +1971,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
(pmap->pm_ptphint->pindex == ptepindex)) {
mpte = pmap->pm_ptphint;
} else {
- mpte = PHYS_TO_VM_PAGE(MIPS_CACHED_TO_PHYS(pteva));
+ mpte = PHYS_TO_VM_PAGE(vtophys(pteva));
pmap->pm_ptphint = mpte;
}
mpte->wire_count++;
@@ -2090,8 +2034,8 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
* unresolvable TLB miss may occur. */
if (pmap == &curproc->p_vmspace->vm_pmap) {
va &= ~PAGE_MASK;
- mips_icache_sync_range(va, NBPG);
- mips_dcache_wbinv_range(va, NBPG);
+ mips_icache_sync_range(va, PAGE_SIZE);
+ mips_dcache_wbinv_range(va, PAGE_SIZE);
}
}
return (mpte);
@@ -2105,36 +2049,34 @@ void *
pmap_kenter_temporary(vm_paddr_t pa, int i)
{
vm_offset_t va;
- int int_level;
+ register_t intr;
if (i != 0)
printf("%s: ERROR!!! More than one page of virtual address mapping not supported\n",
__func__);
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool) {
- va = pmap_map_fpage(pa, &fpages_shared[PMAP_FPAGE_KENTER_TEMP],
- TRUE);
- } else
-#endif
if (pa < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_CACHED(pa);
+ va = MIPS_PHYS_TO_KSEG0(pa);
} else {
int cpu;
struct local_sysmaps *sysm;
+ pt_entry_t *pte, npte;
+
/* If this is used other than for dumps, we may need to leave
* interrupts disasbled on return. If crash dumps don't work when
* we get to this point, we might want to consider this (leaving things
* disabled as a starting point ;-)
*/
- int_level = disableintr();
+ intr = intr_disable();
cpu = PCPU_GET(cpuid);
sysm = &sysmap_lmem[cpu];
/* Since this is for the debugger, no locks or any other fun */
- sysm->CMAP1 = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
+ npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
+ pte = pmap_pte(kernel_pmap, sysm->base);
+ *pte = npte;
sysm->valid1 = 1;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1);
- va = (vm_offset_t)sysm->CADDR1;
- restoreintr(int_level);
+ pmap_update_page(kernel_pmap, sysm->base, npte);
+ va = sysm->base;
+ intr_restore(intr);
}
return ((void *)va);
}
@@ -2143,7 +2085,7 @@ void
pmap_kenter_temporary_free(vm_paddr_t pa)
{
int cpu;
- int int_level;
+ register_t intr;
struct local_sysmaps *sysm;
if (pa < MIPS_KSEG0_LARGEST_PHYS) {
@@ -2153,10 +2095,13 @@ pmap_kenter_temporary_free(vm_paddr_t pa)
cpu = PCPU_GET(cpuid);
sysm = &sysmap_lmem[cpu];
if (sysm->valid1) {
- int_level = disableintr();
- pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1);
- restoreintr(int_level);
- sysm->CMAP1 = 0;
+ pt_entry_t *pte;
+
+ intr = intr_disable();
+ pte = pmap_pte(kernel_pmap, sysm->base);
+ *pte = PTE_G;
+ pmap_invalidate_page(kernel_pmap, sysm->base);
+ intr_restore(intr);
sysm->valid1 = 0;
}
}
@@ -2266,54 +2211,21 @@ pmap_zero_page(vm_page_t m)
{
vm_offset_t va;
vm_paddr_t phys = VM_PAGE_TO_PHYS(m);
- int int_level;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool) {
- struct fpage *fp1;
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- sched_pin();
-
- fp1 = &sysmaps->fp[PMAP_FPAGE1];
- va = pmap_map_fpage(phys, fp1, FALSE);
- bzero((caddr_t)va, PAGE_SIZE);
- pmap_unmap_fpage(phys, fp1);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
- /*
- * Should you do cache flush?
- */
- } else
-#endif
- if (phys < MIPS_KSEG0_LARGEST_PHYS) {
+ register_t intr;
- va = MIPS_PHYS_TO_CACHED(phys);
+ if (phys < MIPS_KSEG0_LARGEST_PHYS) {
+ va = MIPS_PHYS_TO_KSEG0(phys);
bzero((caddr_t)va, PAGE_SIZE);
mips_dcache_wbinv_range(va, PAGE_SIZE);
} else {
- int cpu;
- struct local_sysmaps *sysm;
+ PMAP_LMEM_MAP1(va, phys);
- cpu = PCPU_GET(cpuid);
- sysm = &sysmap_lmem[cpu];
- PMAP_LGMEM_LOCK(sysm);
- sched_pin();
- int_level = disableintr();
- sysm->CMAP1 = mips_paddr_to_tlbpfn(phys) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- sysm->valid1 = 1;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1);
- bzero(sysm->CADDR1, PAGE_SIZE);
- pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1);
- restoreintr(int_level);
- sysm->CMAP1 = 0;
- sysm->valid1 = 0;
- sched_unpin();
- PMAP_LGMEM_UNLOCK(sysm);
- }
+ bzero((caddr_t)va, PAGE_SIZE);
+ mips_dcache_wbinv_range(va, PAGE_SIZE);
+ PMAP_LMEM_UNMAP();
+ }
}
/*
@@ -2327,48 +2239,19 @@ pmap_zero_page_area(vm_page_t m, int off, int size)
{
vm_offset_t va;
vm_paddr_t phys = VM_PAGE_TO_PHYS(m);
- int int_level;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool) {
- struct fpage *fp1;
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- sched_pin();
-
- fp1 = &sysmaps->fp[PMAP_FPAGE1];
- va = pmap_map_fpage(phys, fp1, FALSE);
- bzero((caddr_t)va + off, size);
- pmap_unmap_fpage(phys, fp1);
-
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
- } else
-#endif
+ register_t intr;
+
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_CACHED(phys);
+ va = MIPS_PHYS_TO_KSEG0(phys);
bzero((char *)(caddr_t)va + off, size);
mips_dcache_wbinv_range(va + off, size);
} else {
- int cpu;
- struct local_sysmaps *sysm;
+ PMAP_LMEM_MAP1(va, phys);
- cpu = PCPU_GET(cpuid);
- sysm = &sysmap_lmem[cpu];
- PMAP_LGMEM_LOCK(sysm);
- int_level = disableintr();
- sched_pin();
- sysm->CMAP1 = mips_paddr_to_tlbpfn(phys) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- sysm->valid1 = 1;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1);
- bzero((char *)sysm->CADDR1 + off, size);
- pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1);
- restoreintr(int_level);
- sysm->CMAP1 = 0;
- sysm->valid1 = 0;
- sched_unpin();
- PMAP_LGMEM_UNLOCK(sysm);
+ bzero((char *)va + off, size);
+ mips_dcache_wbinv_range(va + off, size);
+
+ PMAP_LMEM_UNMAP();
}
}
@@ -2377,41 +2260,20 @@ pmap_zero_page_idle(vm_page_t m)
{
vm_offset_t va;
vm_paddr_t phys = VM_PAGE_TO_PHYS(m);
- int int_level;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool) {
- sched_pin();
- va = pmap_map_fpage(phys, &fpages_shared[PMAP_FPAGE3], FALSE);
- bzero((caddr_t)va, PAGE_SIZE);
- pmap_unmap_fpage(phys, &fpages_shared[PMAP_FPAGE3]);
- sched_unpin();
- } else
-#endif
+ register_t intr;
+
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_CACHED(phys);
+ va = MIPS_PHYS_TO_KSEG0(phys);
bzero((caddr_t)va, PAGE_SIZE);
mips_dcache_wbinv_range(va, PAGE_SIZE);
} else {
- int cpu;
- struct local_sysmaps *sysm;
+ PMAP_LMEM_MAP1(va, phys);
- cpu = PCPU_GET(cpuid);
- sysm = &sysmap_lmem[cpu];
- PMAP_LGMEM_LOCK(sysm);
- int_level = disableintr();
- sched_pin();
- sysm->CMAP1 = mips_paddr_to_tlbpfn(phys) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- sysm->valid1 = 1;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1);
- bzero(sysm->CADDR1, PAGE_SIZE);
- pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1);
- restoreintr(int_level);
- sysm->CMAP1 = 0;
- sysm->valid1 = 0;
- sched_unpin();
- PMAP_LGMEM_UNLOCK(sysm);
- }
+ bzero((caddr_t)va, PAGE_SIZE);
+ mips_dcache_wbinv_range(va, PAGE_SIZE);
+ PMAP_LMEM_UNMAP();
+ }
}
/*
@@ -2426,96 +2288,28 @@ pmap_copy_page(vm_page_t src, vm_page_t dst)
vm_offset_t va_src, va_dst;
vm_paddr_t phy_src = VM_PAGE_TO_PHYS(src);
vm_paddr_t phy_dst = VM_PAGE_TO_PHYS(dst);
- int int_level;
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- if (need_wired_tlb_page_pool) {
- struct fpage *fp1, *fp2;
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- sched_pin();
-
- fp1 = &sysmaps->fp[PMAP_FPAGE1];
- fp2 = &sysmaps->fp[PMAP_FPAGE2];
-
- va_src = pmap_map_fpage(phy_src, fp1, FALSE);
- va_dst = pmap_map_fpage(phy_dst, fp2, FALSE);
+ register_t intr;
+ if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) {
+ /* easy case, all can be accessed via KSEG0 */
+ /*
+ * Flush all caches for VA that are mapped to this page
+ * to make sure that data in SDRAM is up to date
+ */
+ pmap_flush_pvcache(src);
+ mips_dcache_wbinv_range_index(
+ MIPS_PHYS_TO_KSEG0(phy_dst), PAGE_SIZE);
+ va_src = MIPS_PHYS_TO_KSEG0(phy_src);
+ va_dst = MIPS_PHYS_TO_KSEG0(phy_dst);
bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE);
+ mips_dcache_wbinv_range(va_dst, PAGE_SIZE);
+ } else {
+ PMAP_LMEM_MAP2(va_src, phy_src, va_dst, phy_dst);
- pmap_unmap_fpage(phy_src, fp1);
- pmap_unmap_fpage(phy_dst, fp2);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
+ bcopy((void *)va_src, (void *)va_dst, PAGE_SIZE);
+ mips_dcache_wbinv_range(va_dst, PAGE_SIZE);
- /*
- * Should you flush the cache?
- */
- } else
-#endif
- {
- if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) {
- /* easy case, all can be accessed via KSEG0 */
- /*
- * Flush all caches for VA that are mapped to this page
- * to make sure that data in SDRAM is up to date
- */
- pmap_flush_pvcache(src);
- mips_dcache_wbinv_range_index(
- MIPS_PHYS_TO_CACHED(phy_dst), NBPG);
- va_src = MIPS_PHYS_TO_CACHED(phy_src);
- va_dst = MIPS_PHYS_TO_CACHED(phy_dst);
- bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE);
- mips_dcache_wbinv_range(va_dst, PAGE_SIZE);
- } else {
- int cpu;
- struct local_sysmaps *sysm;
-
- cpu = PCPU_GET(cpuid);
- sysm = &sysmap_lmem[cpu];
- PMAP_LGMEM_LOCK(sysm);
- sched_pin();
- int_level = disableintr();
- if (phy_src < MIPS_KSEG0_LARGEST_PHYS) {
- /* one side needs mapping - dest */
- va_src = MIPS_PHYS_TO_CACHED(phy_src);
- sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2);
- sysm->valid2 = 1;
- va_dst = (vm_offset_t)sysm->CADDR2;
- } else if (phy_dst < MIPS_KSEG0_LARGEST_PHYS) {
- /* one side needs mapping - src */
- va_dst = MIPS_PHYS_TO_CACHED(phy_dst);
- sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1);
- va_src = (vm_offset_t)sysm->CADDR1;
- sysm->valid1 = 1;
- } else {
- /* all need mapping */
- sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1);
- pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2);
- sysm->valid1 = sysm->valid2 = 1;
- va_src = (vm_offset_t)sysm->CADDR1;
- va_dst = (vm_offset_t)sysm->CADDR2;
- }
- bcopy((void *)va_src, (void *)va_dst, PAGE_SIZE);
- if (sysm->valid1) {
- pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1);
- sysm->CMAP1 = 0;
- sysm->valid1 = 0;
- }
- if (sysm->valid2) {
- pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR2);
- sysm->CMAP2 = 0;
- sysm->valid2 = 0;
- }
- restoreintr(int_level);
- sched_unpin();
- PMAP_LGMEM_UNLOCK(sysm);
- }
+ PMAP_LMEM_UNMAP();
}
}
@@ -2587,9 +2381,8 @@ pmap_remove_pages(pmap_t pmap)
*pte = is_kernel_pmap(pmap) ? PTE_G : 0;
m = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(tpte));
-
- KASSERT(m < &vm_page_array[vm_page_array_size],
- ("pmap_remove_pages: bad tpte %lx", tpte));
+ KASSERT(m != NULL,
+ ("pmap_remove_pages: bad tpte %x", tpte));
pv->pv_pmap->pm_stats.resident_count--;
@@ -2833,6 +2626,20 @@ pmap_clear_modify(vm_page_t m)
}
/*
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+ return ((m->flags & PG_FICTITIOUS) == 0 &&
+ (m->md.pv_flags & PV_TABLE_REF) != 0);
+}
+
+/*
* pmap_clear_reference:
*
* Clear the reference bit on the specified physical page.
@@ -2957,10 +2764,8 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
* Referenced by us or someone
*/
vm_page_lock_queues();
- if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
+ if ((m->flags & PG_REFERENCED) || pmap_is_referenced(m))
val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
- vm_page_flag_set(m, PG_REFERENCED);
- }
vm_page_unlock_queues();
}
return val;
@@ -3019,6 +2824,21 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
*addr = ((*addr + SEGOFSET) & ~SEGOFSET) + superpage_offset;
}
+/*
+ * Increase the starting virtual address of the given mapping so
+ * that it is aligned to not be the second page in a TLB entry.
+ * This routine assumes that the length is appropriately-sized so
+ * that the allocation does not share a TLB entry at all if required.
+ */
+void
+pmap_align_tlb(vm_offset_t *addr)
+{
+ if ((*addr & PAGE_SIZE) == 0)
+ return;
+ *addr += PAGE_SIZE;
+ return;
+}
+
int pmap_pid_dump(int pid);
int
@@ -3168,18 +2988,6 @@ pmap_asid_alloc(pmap)
pmap->pm_asid[PCPU_GET(cpuid)].gen = PCPU_GET(asid_generation);
PCPU_SET(next_asid, PCPU_GET(next_asid) + 1);
}
-
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW | PDB_TLBPID)) {
- if (curproc)
- printf("pmap_asid_alloc: curproc %d '%s' ",
- curproc->p_pid, curproc->p_comm);
- else
- printf("pmap_asid_alloc: curproc <none> ");
- printf("segtab %p asid %d\n", pmap->pm_segtab,
- pmap->pm_asid[PCPU_GET(cpuid)].asid);
- }
-#endif
}
int
@@ -3187,10 +2995,12 @@ page_is_managed(vm_offset_t pa)
{
vm_offset_t pgnum = mips_btop(pa);
- if (pgnum >= first_page && (pgnum < (first_page + vm_page_array_size))) {
+ if (pgnum >= first_page) {
vm_page_t m;
m = PHYS_TO_VM_PAGE(pa);
+ if (m == NULL)
+ return 0;
if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0)
return 1;
}
@@ -3248,53 +3058,6 @@ pmap_set_modified(vm_offset_t pa)
PHYS_TO_VM_PAGE(pa)->md.pv_flags |= (PV_TABLE_REF | PV_TABLE_MOD);
}
-#include <machine/db_machdep.h>
-
-/*
- * Dump the translation buffer (TLB) in readable form.
- */
-
-void
-db_dump_tlb(int first, int last)
-{
- struct tlb tlb;
- int tlbno;
-
- tlbno = first;
-
- while (tlbno <= last) {
- MachTLBRead(tlbno, &tlb);
- if (tlb.tlb_lo0 & PTE_V || tlb.tlb_lo1 & PTE_V) {
- printf("TLB %2d vad 0x%08x ", tlbno, (tlb.tlb_hi & 0xffffff00));
- } else {
- printf("TLB*%2d vad 0x%08x ", tlbno, (tlb.tlb_hi & 0xffffff00));
- }
- printf("0=0x%08x ", pfn_to_vad(tlb.tlb_lo0));
- printf("%c", tlb.tlb_lo0 & PTE_M ? 'M' : ' ');
- printf("%c", tlb.tlb_lo0 & PTE_G ? 'G' : ' ');
- printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
- printf("1=0x%08x ", pfn_to_vad(tlb.tlb_lo1));
- printf("%c", tlb.tlb_lo1 & PTE_M ? 'M' : ' ');
- printf("%c", tlb.tlb_lo1 & PTE_G ? 'G' : ' ');
- printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
- printf(" sz=%x pid=%x\n", tlb.tlb_mask,
- (tlb.tlb_hi & 0x000000ff)
- );
- tlbno++;
- }
-}
-
-#ifdef DDB
-#include <sys/kernel.h>
-#include <ddb/ddb.h>
-
-DB_SHOW_COMMAND(tlb, ddb_dump_tlb)
-{
- db_dump_tlb(0, num_tlbentries - 1);
-}
-
-#endif
-
/*
* Routine: pmap_kextract
* Function:
@@ -3306,7 +3069,7 @@ pmap_kextract(vm_offset_t va)
{
vm_offset_t pa = 0;
- if (va < MIPS_CACHED_MEMORY_ADDR) {
+ if (va < MIPS_KSEG0_START) {
/* user virtual address */
pt_entry_t *ptep;
@@ -3316,50 +3079,22 @@ pmap_kextract(vm_offset_t va)
pa = mips_tlbpfn_to_paddr(*ptep) |
(va & PAGE_MASK);
}
- } else if (va >= MIPS_CACHED_MEMORY_ADDR &&
- va < MIPS_UNCACHED_MEMORY_ADDR)
- pa = MIPS_CACHED_TO_PHYS(va);
- else if (va >= MIPS_UNCACHED_MEMORY_ADDR &&
+ } else if (va >= MIPS_KSEG0_START &&
+ va < MIPS_KSEG1_START)
+ pa = MIPS_KSEG0_TO_PHYS(va);
+ else if (va >= MIPS_KSEG1_START &&
va < MIPS_KSEG2_START)
- pa = MIPS_UNCACHED_TO_PHYS(va);
-#ifdef VM_ALLOC_WIRED_TLB_PG_POOL
- else if (need_wired_tlb_page_pool && ((va >= VM_MIN_KERNEL_ADDRESS) &&
- (va < (VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET))))
- pa = MIPS_CACHED_TO_PHYS(va);
-#endif
+ pa = MIPS_KSEG1_TO_PHYS(va);
else if (va >= MIPS_KSEG2_START && va < VM_MAX_KERNEL_ADDRESS) {
pt_entry_t *ptep;
/* Is the kernel pmap initialized? */
if (kernel_pmap->pm_active) {
- if (va >= (vm_offset_t)virtual_sys_start) {
- /* Its inside the virtual address range */
- ptep = pmap_pte(kernel_pmap, va);
- if (ptep)
- pa = mips_tlbpfn_to_paddr(*ptep) |
- (va & PAGE_MASK);
- } else {
- int i;
-
- /*
- * its inside the special mapping area, I
- * don't think this should happen, but if it
- * does I want it toa all work right :-)
- * Note if it does happen, we assume the
- * caller has the lock? FIXME, this needs to
- * be checked FIXEM - RRS.
- */
- for (i = 0; i < MAXCPU; i++) {
- if ((sysmap_lmem[i].valid1) && ((vm_offset_t)sysmap_lmem[i].CADDR1 == va)) {
- pa = mips_tlbpfn_to_paddr(sysmap_lmem[i].CMAP1);
- break;
- }
- if ((sysmap_lmem[i].valid2) && ((vm_offset_t)sysmap_lmem[i].CADDR2 == va)) {
- pa = mips_tlbpfn_to_paddr(sysmap_lmem[i].CMAP2);
- break;
- }
- }
- }
+ /* Its inside the virtual address range */
+ ptep = pmap_pte(kernel_pmap, va);
+ if (ptep)
+ pa = mips_tlbpfn_to_paddr(*ptep) |
+ (va & PAGE_MASK);
}
}
return pa;
@@ -3373,7 +3108,65 @@ pmap_flush_pvcache(vm_page_t m)
if (m != NULL) {
for (pv = TAILQ_FIRST(&m->md.pv_list); pv;
pv = TAILQ_NEXT(pv, pv_list)) {
- mips_dcache_wbinv_range_index(pv->pv_va, NBPG);
+ mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE);
}
}
}
+
+void
+pmap_save_tlb(void)
+{
+ int tlbno, cpu;
+
+ cpu = PCPU_GET(cpuid);
+
+ for (tlbno = 0; tlbno < num_tlbentries; ++tlbno)
+ MachTLBRead(tlbno, &tlbstash[cpu][tlbno]);
+}
+
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(tlb, ddb_dump_tlb)
+{
+ int cpu, tlbno;
+ struct tlb *tlb;
+
+ if (have_addr)
+ cpu = ((addr >> 4) % 16) * 10 + (addr % 16);
+ else
+ cpu = PCPU_GET(cpuid);
+
+ if (cpu < 0 || cpu >= mp_ncpus) {
+ db_printf("Invalid CPU %d\n", cpu);
+ return;
+ } else
+ db_printf("CPU %d:\n", cpu);
+
+ if (cpu == PCPU_GET(cpuid))
+ pmap_save_tlb();
+
+ for (tlbno = 0; tlbno < num_tlbentries; ++tlbno) {
+ tlb = &tlbstash[cpu][tlbno];
+ if (tlb->tlb_lo0 & PTE_V || tlb->tlb_lo1 & PTE_V) {
+ printf("TLB %2d vad 0x%0lx ",
+ tlbno, (long)(tlb->tlb_hi & 0xffffff00));
+ } else {
+ printf("TLB*%2d vad 0x%0lx ",
+ tlbno, (long)(tlb->tlb_hi & 0xffffff00));
+ }
+ printf("0=0x%0lx ", pfn_to_vad((long)tlb->tlb_lo0));
+ printf("%c", tlb->tlb_lo0 & PTE_V ? 'V' : '-');
+ printf("%c", tlb->tlb_lo0 & PTE_M ? 'M' : '-');
+ printf("%c", tlb->tlb_lo0 & PTE_G ? 'G' : '-');
+ printf(" atr %x ", (tlb->tlb_lo0 >> 3) & 7);
+ printf("1=0x%0lx ", pfn_to_vad((long)tlb->tlb_lo1));
+ printf("%c", tlb->tlb_lo1 & PTE_V ? 'V' : '-');
+ printf("%c", tlb->tlb_lo1 & PTE_M ? 'M' : '-');
+ printf("%c", tlb->tlb_lo1 & PTE_G ? 'G' : '-');
+ printf(" atr %x ", (tlb->tlb_lo1 >> 3) & 7);
+ printf(" sz=%x pid=%x\n", tlb->tlb_mask,
+ (tlb->tlb_hi & 0x000000ff));
+ }
+}
+#endif /* DDB */
diff --git a/sys/mips/mips/psraccess.S b/sys/mips/mips/psraccess.S
index 0bcb04d..9b40a23 100644
--- a/sys/mips/mips/psraccess.S
+++ b/sys/mips/mips/psraccess.S
@@ -53,109 +53,6 @@
.set noreorder # Noreorder is default style!
-/*
- * Set/clear software interrupt.
- */
-
-LEAF(setsoftintr0)
- mfc0 v0, COP_0_CAUSE_REG # read cause register
- nop
- or v0, v0, SOFT_INT_MASK_0 # set soft clock interrupt
- mtc0 v0, COP_0_CAUSE_REG # save it
- j ra
- nop
-END(setsoftintr0)
-
-LEAF(clearsoftintr0)
- mfc0 v0, COP_0_CAUSE_REG # read cause register
- nop
- and v0, v0, ~SOFT_INT_MASK_0 # clear soft clock interrupt
- mtc0 v0, COP_0_CAUSE_REG # save it
- j ra
- nop
-END(clearsoftintr0)
-
-LEAF(setsoftintr1)
- mfc0 v0, COP_0_CAUSE_REG # read cause register
- nop
- or v0, v0, SOFT_INT_MASK_1 # set soft net interrupt
- mtc0 v0, COP_0_CAUSE_REG # save it
- j ra
- nop
-END(setsoftintr1)
-
-LEAF(clearsoftintr1)
- mfc0 v0, COP_0_CAUSE_REG # read cause register
- nop
- and v0, v0, ~SOFT_INT_MASK_1 # clear soft net interrupt
- mtc0 v0, COP_0_CAUSE_REG # save it
- j ra
- nop
-END(clearsoftintr1)
-
-/*
- * Set/change interrupt priority routines.
- * These routines return the previous state.
- */
-LEAF(restoreintr)
- mfc0 t0,COP_0_STATUS_REG
- and t1,t0,SR_INT_ENAB
- beq a0,t1,1f
- xor t0,SR_INT_ENAB
-
- .set noreorder
-
- mtc0 t0,COP_0_STATUS_REG
- nop
- nop
- nop
- nop
-1:
- j ra
- nop
-END(restoreintr)
-
-/*
- * Set/change interrupt priority routines.
- * These routines return the previous state.
- */
-
-LEAF(enableintr)
-#ifdef TARGET_OCTEON
- .set mips64r2
- ei v0
- and v0, SR_INT_ENAB # return old interrupt enable bit
- .set mips0
-#else
- mfc0 v0, COP_0_STATUS_REG # read status register
- nop
- or v1, v0, SR_INT_ENAB
- mtc0 v1, COP_0_STATUS_REG # enable all interrupts
- and v0, SR_INT_ENAB # return old interrupt enable
-#endif
- j ra
- nop
-END(enableintr)
-
-
-LEAF(disableintr)
-#ifdef TARGET_OCTEON
- .set mips64r2
- di v0
- and v0, SR_INT_ENAB # return old interrupt enable bit
- .set mips0
-#else
- mfc0 v0, COP_0_STATUS_REG # read status register
- nop
- and v1, v0, ~SR_INT_ENAB
- mtc0 v1, COP_0_STATUS_REG # disable all interrupts
- MIPS_CPU_NOP_DELAY
- and v0, SR_INT_ENAB # return old interrupt enable
-#endif
- j ra
- nop
-END(disableintr)
-
LEAF(set_intr_mask)
li t0, SR_INT_MASK # 1 means masked so invert.
not a0, a0 # 1 means masked so invert.
@@ -182,17 +79,3 @@ LEAF(get_intr_mask)
nop
END(get_intr_mask)
-
-/*
- * u_int32_t mips_cp0_config1_read(void)
- *
- * Return the current value of the CP0 Config (Select 1) register.
- */
-LEAF(mips_cp0_config1_read)
- .set push
- .set mips32
- mfc0 v0, COP_0_CONFIG, 1
- j ra
- nop
- .set pop
-END(mips_cp0_config1_read)
diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S
index 526f957..9cbc998 100644
--- a/sys/mips/mips/support.S
+++ b/sys/mips/mips/support.S
@@ -51,6 +51,38 @@
*/
/*
+ * Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author)
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jonathan R. Stone for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+/*
* Contains code that is the first executed at boot time plus
* assembly language support routines.
*/
@@ -61,6 +93,7 @@
#include <machine/asm.h>
#include <machine/cpu.h>
#include <machine/regnum.h>
+#include <machine/cpuregs.h>
#include "assym.s"
@@ -70,47 +103,22 @@
* Primitives
*/
-/*
- * This table is indexed by u.u_pcb.pcb_onfault in trap().
- * The reason for using this table rather than storing an address in
- * u.u_pcb.pcb_onfault is simply to make the code faster.
- */
- .globl onfault_table
- .data
- .align 3
-onfault_table:
- .word 0 # invalid index number
-#define BADERR 1
- .word baderr
-#define COPYERR 2
- .word copyerr
-#define FSWBERR 3
- .word fswberr
-#define FSWINTRBERR 4
- .word fswintrberr
-#if defined(DDB) || defined(DEBUG)
-#define DDBERR 5
- .word ddberr
-#else
- .word 0
-#endif
-
.text
/*
* See if access to addr with a len type instruction causes a machine check.
- * len is length of access (1=byte, 2=short, 4=long)
+ * len is length of access (1=byte, 2=short, 4=int)
*
* badaddr(addr, len)
* char *addr;
* int len;
*/
LEAF(badaddr)
- li v0, BADERR
+ PTR_LA v0, baderr
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
+ PTR_L v1, PC_CURPCB(v1)
bne a1, 1, 2f
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
b 5f
lbu v0, (a0)
2:
@@ -121,7 +129,7 @@ LEAF(badaddr)
4:
lw v0, (a0)
5:
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
move v0, zero # made it w/o errors
baderr:
@@ -136,24 +144,24 @@ END(badaddr)
* string is too long, return ENAMETOOLONG; else return 0.
*/
LEAF(copystr)
- move t0, a2
- beq a2, zero, 4f
+ move t0, a2
+ beq a2, zero, 4f
1:
- lbu v0, 0(a0)
- subu a2, a2, 1
- beq v0, zero, 2f
- sb v0, 0(a1) # each byte until NIL
- addu a0, a0, 1
- bne a2, zero, 1b # less than maxlen
- addu a1, a1, 1
+ lbu v0, 0(a0)
+ PTR_SUBU a2, a2, 1
+ beq v0, zero, 2f
+ sb v0, 0(a1) # each byte until NIL
+ PTR_ADDU a0, a0, 1
+ bne a2, zero, 1b # less than maxlen
+ PTR_ADDU a1, a1, 1
4:
- li v0, ENAMETOOLONG # run out of space
+ li v0, ENAMETOOLONG # run out of space
2:
- beq a3, zero, 3f # return num. of copied bytes
- subu a2, t0, a2 # if the 4th arg was non-NULL
- sw a2, 0(a3)
+ beq a3, zero, 3f # return num. of copied bytes
+ PTR_SUBU a2, t0, a2 # if the 4th arg was non-NULL
+ PTR_S a2, 0(a3)
3:
- j ra # v0 is 0 or ENAMETOOLONG
+ j ra # v0 is 0 or ENAMETOOLONG
nop
END(copystr)
@@ -163,12 +171,12 @@ END(copystr)
*/
LEAF(fillw)
1:
- addiu a2, a2, -1
- sh a0, 0(a1)
- bne a2,zero, 1b
- addiu a1, a1, 2
+ PTR_ADDU a2, a2, -1
+ sh a0, 0(a1)
+ bne a2,zero, 1b
+ PTR_ADDU a1, a1, 2
- jr ra
+ jr ra
nop
END(fillw)
@@ -177,13 +185,13 @@ END(fillw)
* mem_zero_page(addr);
*/
LEAF(mem_zero_page)
- li v0, NBPG
+ li v0, PAGE_SIZE
1:
- subu v0, 8
- sd zero, 0(a0)
- bne zero, v0, 1b
- addu a0, 8
- jr ra
+ PTR_SUBU v0, 8
+ sd zero, 0(a0)
+ bne zero, v0, 1b
+ PTR_ADDU a0, 8
+ jr ra
nop
END(mem_zero_page)
@@ -195,56 +203,56 @@ END(mem_zero_page)
* a2 = count
*/
LEAF(insb)
- beq a2, zero, 2f
- addu a2, a1
+ beq a2, zero, 2f
+ PTR_ADDU a2, a1
1:
- lbu v0, 0(a0)
- addiu a1, 1
- bne a1, a2, 1b
- sb v0, -1(a1)
+ lbu v0, 0(a0)
+ PTR_ADDU a1, 1
+ bne a1, a2, 1b
+ sb v0, -1(a1)
2:
- jr ra
+ jr ra
nop
END(insb)
LEAF(insw)
- beq a2, zero, 2f
- addu a2, a2
- addu a2, a1
+ beq a2, zero, 2f
+ PTR_ADDU a2, a2
+ PTR_ADDU a2, a1
1:
- lhu v0, 0(a0)
- addiu a1, 2
- bne a1, a2, 1b
- sh v0, -2(a1)
+ lhu v0, 0(a0)
+ PTR_ADDU a1, 2
+ bne a1, a2, 1b
+ sh v0, -2(a1)
2:
- jr ra
+ jr ra
nop
END(insw)
LEAF(insl)
- beq a2, zero, 2f
- sll a2, 2
- addu a2, a1
+ beq a2, zero, 2f
+ sll a2, 2
+ PTR_ADDU a2, a1
1:
- lw v0, 0(a0)
- addiu a1, 4
- bne a1, a2, 1b
- sw v0, -4(a1)
+ lw v0, 0(a0)
+ PTR_ADDU a1, 4
+ bne a1, a2, 1b
+ sw v0, -4(a1)
2:
- jr ra
+ jr ra
nop
END(insl)
LEAF(outsb)
- beq a2, zero, 2f
- addu a2, a1
+ beq a2, zero, 2f
+ PTR_ADDU a2, a1
1:
- lbu v0, 0(a1)
- addiu a1, 1
- bne a1, a2, 1b
- sb v0, 0(a0)
+ lbu v0, 0(a1)
+ PTR_ADDU a1, 1
+ bne a1, a2, 1b
+ sb v0, 0(a0)
2:
- jr ra
+ jr ra
nop
END(outsb)
@@ -310,22 +318,22 @@ END(outsl)
* u_int maxlength;
* u_int *lencopied;
*/
-NON_LEAF(copyinstr, STAND_FRAME_SIZE, ra)
- subu sp, sp, STAND_FRAME_SIZE
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
- sw ra, STAND_RA_OFFSET(sp)
+NON_LEAF(copyinstr, CALLFRAME_SIZ, ra)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+ PTR_LA v0, copyerr
blt a0, zero, _C_LABEL(copyerr) # make sure address is in user space
- li v0, COPYERR
+ REG_S ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
+ PTR_L v1, PC_CURPCB(v1)
jal _C_LABEL(copystr)
- sw v0, U_PCB_ONFAULT(v1)
- lw ra, STAND_RA_OFFSET(sp)
+ PTR_S v0, U_PCB_ONFAULT(v1)
+ REG_L ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
- addu sp, sp, STAND_FRAME_SIZE
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
END(copyinstr)
/*
@@ -338,22 +346,22 @@ END(copyinstr)
* u_int maxlength;
* u_int *lencopied;
*/
-NON_LEAF(copyoutstr, STAND_FRAME_SIZE, ra)
- subu sp, sp, STAND_FRAME_SIZE
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
- sw ra, STAND_RA_OFFSET(sp)
+NON_LEAF(copyoutstr, CALLFRAME_SIZ, ra)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+ PTR_LA v0, copyerr
blt a1, zero, _C_LABEL(copyerr) # make sure address is in user space
- li v0, COPYERR
+ REG_S ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
+ PTR_L v1, PC_CURPCB(v1)
jal _C_LABEL(copystr)
- sw v0, U_PCB_ONFAULT(v1)
- lw ra, STAND_RA_OFFSET(sp)
+ PTR_S v0, U_PCB_ONFAULT(v1)
+ REG_L ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
- addu sp, sp, STAND_FRAME_SIZE
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
END(copyoutstr)
/*
@@ -363,21 +371,21 @@ END(copyoutstr)
* caddr_t *to; (kernel destination address)
* unsigned len;
*/
-NON_LEAF(copyin, STAND_FRAME_SIZE, ra)
- subu sp, sp, STAND_FRAME_SIZE
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
- sw ra, STAND_RA_OFFSET(sp)
+NON_LEAF(copyin, CALLFRAME_SIZ, ra)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+ PTR_LA v0, copyerr
blt a0, zero, _C_LABEL(copyerr) # make sure address is in user space
- li v0, COPYERR
+ REG_S ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
+ PTR_L v1, PC_CURPCB(v1)
jal _C_LABEL(bcopy)
- sw v0, U_PCB_ONFAULT(v1)
- lw ra, STAND_RA_OFFSET(sp)
+ PTR_S v0, U_PCB_ONFAULT(v1)
+ REG_L ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1) # bcopy modified v1, so reload
- sw zero, U_PCB_ONFAULT(v1)
- addu sp, sp, STAND_FRAME_SIZE
+ PTR_L v1, PC_CURPCB(v1) # bcopy modified v1, so reload
+ PTR_S zero, U_PCB_ONFAULT(v1)
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
j ra
move v0, zero
END(copyin)
@@ -389,31 +397,28 @@ END(copyin)
* caddr_t *to; (user destination address)
* unsigned len;
*/
-NON_LEAF(copyout, STAND_FRAME_SIZE, ra)
- subu sp, sp, STAND_FRAME_SIZE
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
- sw ra, STAND_RA_OFFSET(sp)
+NON_LEAF(copyout, CALLFRAME_SIZ, ra)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+ PTR_LA v0, copyerr
blt a1, zero, _C_LABEL(copyerr) # make sure address is in user space
- li v0, COPYERR
+ REG_S ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
+ PTR_L v1, PC_CURPCB(v1)
jal _C_LABEL(bcopy)
- sw v0, U_PCB_ONFAULT(v1)
- lw ra, STAND_RA_OFFSET(sp)
+ PTR_S v0, U_PCB_ONFAULT(v1)
+ REG_L ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1) # bcopy modified v1, so reload
- sw zero, U_PCB_ONFAULT(v1)
- addu sp, sp, STAND_FRAME_SIZE
+ PTR_L v1, PC_CURPCB(v1) # bcopy modified v1, so reload
+ PTR_S zero, U_PCB_ONFAULT(v1)
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
j ra
move v0, zero
END(copyout)
LEAF(copyerr)
- lw ra, STAND_RA_OFFSET(sp)
- GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw zero, U_PCB_ONFAULT(v1)
- addu sp, sp, STAND_FRAME_SIZE
+ REG_L ra, CALLFRAME_RA(sp)
+ PTR_ADDU sp, sp, CALLFRAME_SIZ
j ra
li v0, EFAULT # return error
END(copyerr)
@@ -427,51 +432,55 @@ END(copyerr)
LEAF(fuword)
ALEAF(fuword32)
ALEAF(fuiword)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
lw v0, 0(a0) # fetch word
j ra
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
END(fuword)
LEAF(fusword)
ALEAF(fuisword)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
lhu v0, 0(a0) # fetch short
j ra
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
END(fusword)
LEAF(fubyte)
ALEAF(fuibyte)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
lbu v0, 0(a0) # fetch byte
j ra
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
END(fubyte)
LEAF(suword32)
#ifndef __mips_n64
XLEAF(suword)
#endif
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
sw a1, 0(a0) # store word
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
move v0, zero
END(suword32)
@@ -479,13 +488,14 @@ END(suword32)
#ifdef __mips_n64
LEAF(suword64)
XLEAF(suword)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
sd a1, 0(a0) # store word
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
move v0, zero
END(suword64)
@@ -504,11 +514,12 @@ LEAF(casuword32)
#ifndef __mips_n64
XLEAF(casuword)
#endif
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
1:
move t0, a2
ll v0, 0(a0)
@@ -522,7 +533,7 @@ XLEAF(casuword)
2:
li v0, -1
3:
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
jr ra
nop
END(casuword32)
@@ -530,11 +541,12 @@ END(casuword32)
#ifdef __mips_n64
LEAF(casuword64)
XLEAF(casuword)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
1:
move t0, a2
lld v0, 0(a0)
@@ -548,7 +560,7 @@ XLEAF(casuword)
2:
li v0, -1
3:
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
jr ra
nop
END(casuword64)
@@ -560,13 +572,14 @@ END(casuword64)
* Have to flush instruction cache afterwards.
*/
LEAF(suiword)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
sw a1, 0(a0) # store word
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j _C_LABEL(Mips_SyncICache) # FlushICache sets v0 = 0. (Ugly)
li a1, 4 # size of word
END(suiword)
@@ -577,26 +590,28 @@ END(suiword)
*/
LEAF(susword)
ALEAF(suisword)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
sh a1, 0(a0) # store short
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
move v0, zero
END(susword)
LEAF(subyte)
ALEAF(suibyte)
+ PTR_LA v0, fswberr
blt a0, zero, fswberr # make sure address is in user space
- li v0, FSWBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
sb a1, 0(a0) # store byte
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
move v0, zero
END(subyte)
@@ -612,24 +627,26 @@ END(fswberr)
* The important thing is to prevent sleep() and switch().
*/
LEAF(fuswintr)
+ PTR_LA v0, fswintrberr
blt a0, zero, fswintrberr # make sure address is in user space
- li v0, FSWINTRBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
lhu v0, 0(a0) # fetch short
j ra
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
END(fuswintr)
LEAF(suswintr)
+ PTR_LA v0, fswintrberr
blt a0, zero, fswintrberr # make sure address is in user space
- li v0, FSWINTRBERR
+ nop
GET_CPU_PCPU(v1)
- lw v1, PC_CURPCB(v1)
- sw v0, U_PCB_ONFAULT(v1)
+ PTR_L v1, PC_CURPCB(v1)
+ PTR_S v0, U_PCB_ONFAULT(v1)
sh a1, 0(a0) # store short
- sw zero, U_PCB_ONFAULT(v1)
+ PTR_S zero, U_PCB_ONFAULT(v1)
j ra
move v0, zero
END(suswintr)
@@ -640,111 +657,6 @@ LEAF(fswintrberr)
END(fswintrberr)
/*
- * Insert 'p' after 'q'.
- * _insque(p, q)
- * caddr_t p, q;
- */
-LEAF(_insque)
- lw v0, 0(a1) # v0 = q->next
- sw a1, 4(a0) # p->prev = q
- sw v0, 0(a0) # p->next = q->next
- sw a0, 4(v0) # q->next->prev = p
- j ra
- sw a0, 0(a1) # q->next = p
-END(_insque)
-
-/*
- * Remove item 'p' from queue.
- * _remque(p)
- * caddr_t p;
- */
-LEAF(_remque)
- lw v0, 0(a0) # v0 = p->next
- lw v1, 4(a0) # v1 = p->prev
- nop
- sw v0, 0(v1) # p->prev->next = p->next
- j ra
- sw v1, 4(v0) # p->next->prev = p->prev
-END(_remque)
-
-/*--------------------------------------------------------------------------
- *
- * Mips_GetCOUNT --
- *
- * Mips_GetCOUNT()
- *
- * Results:
- * Returns the current COUNT reg.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------------------
- */
-LEAF(Mips_GetCOUNT)
- mfc0 v0, COP_0_COUNT
- nop #???
- nop #???
- j ra
- nop
-END(Mips_GetCOUNT)
-
-/*--------------------------------------------------------------------------
- *
- * Mips_SetCOMPARE --
- *
- * Mips_SetCOMPARE()
- *
- * Results:
- * Sets a new value to the COMPARE register.
- *
- * Side effects:
- * The COMPARE equal interrupt is acknowledged.
- *
- *--------------------------------------------------------------------------
- */
-LEAF(Mips_SetCOMPARE)
- mtc0 a0, COP_0_COMPARE
- j ra
- nop
-END(Mips_SetCOMPARE)
-
-LEAF(Mips_GetCOMPARE)
- mfc0 v0, COP_0_COMPARE
- j ra
- nop
-END(Mips_GetCOMPARE)
-
-/*
- * u_int32_t mips_cp0_status_read(void)
- *
- * Return the current value of the CP0 Status register.
- */
-LEAF(mips_cp0_status_read)
- mfc0 v0, COP_0_STATUS_REG
- j ra
- nop
-END(mips_cp0_status_read)
-
-/*
- * void mips_cp0_status_write(u_int32_t)
- *
- * Set the value of the CP0 Status register.
- *
- * Note: This is almost certainly not the way you want to write a
- * "permanent" value to to the CP0 Status register, since it gets
- * saved in trap frames and restores.
- */
-LEAF(mips_cp0_status_write)
- mtc0 a0, COP_0_STATUS_REG
- nop
- nop
- j ra
- nop
-END(mips_cp0_status_write)
-
-
-/*
* memcpy(to, from, len)
* {ov}bcopy(from, to, len)
*/
@@ -756,7 +668,7 @@ LEAF(memcpy)
ALEAF(bcopy)
ALEAF(ovbcopy)
.set noreorder
- addu t0, a0, a2 # t0 = end of s1 region
+ PTR_ADDU t0, a0, a2 # t0 = end of s1 region
sltu t1, a1, t0
sltu t2, a0, a1
and t1, t1, t2 # t1 = true if from < to < (from+len)
@@ -764,11 +676,11 @@ ALEAF(ovbcopy)
slt t2, a2, 12 # check for small copy
ble a2, zero, 2f
- addu t1, a1, a2 # t1 = end of to region
+ PTR_ADDU t1, a1, a2 # t1 = end of to region
1:
lb v1, -1(t0) # copy bytes backwards,
- subu t0, t0, 1 # doesnt happen often so do slow way
- subu t1, t1, 1
+ PTR_SUBU t0, t0, 1 # doesnt happen often so do slow way
+ PTR_SUBU t1, t1, 1
bne t0, a0, 1b
sb v1, 0(t1)
2:
@@ -778,59 +690,59 @@ forward:
bne t2, zero, smallcpy # do a small bcopy
xor v1, a0, a1 # compare low two bits of addresses
and v1, v1, 3
- subu a3, zero, a1 # compute # bytes to word align address
+ PTR_SUBU a3, zero, a1 # compute # bytes to word align address
beq v1, zero, aligned # addresses can be word aligned
and a3, a3, 3
beq a3, zero, 1f
- subu a2, a2, a3 # subtract from remaining count
+ PTR_SUBU a2, a2, a3 # subtract from remaining count
LWHI v1, 0(a0) # get next 4 bytes (unaligned)
LWLO v1, 3(a0)
- addu a0, a0, a3
+ PTR_ADDU a0, a0, a3
SWHI v1, 0(a1) # store 1, 2, or 3 bytes to align a1
- addu a1, a1, a3
+ PTR_ADDU a1, a1, a3
1:
and v1, a2, 3 # compute number of words left
- subu a3, a2, v1
+ PTR_SUBU a3, a2, v1
move a2, v1
- addu a3, a3, a0 # compute ending address
+ PTR_ADDU a3, a3, a0 # compute ending address
2:
LWHI v1, 0(a0) # copy words a0 unaligned, a1 aligned
LWLO v1, 3(a0)
- addu a0, a0, 4
+ PTR_ADDU a0, a0, 4
sw v1, 0(a1)
- addu a1, a1, 4
+ PTR_ADDU a1, a1, 4
bne a0, a3, 2b
nop # We have to do this mmu-bug.
b smallcpy
nop
aligned:
beq a3, zero, 1f
- subu a2, a2, a3 # subtract from remaining count
+ PTR_SUBU a2, a2, a3 # subtract from remaining count
LWHI v1, 0(a0) # copy 1, 2, or 3 bytes to align
- addu a0, a0, a3
+ PTR_ADDU a0, a0, a3
SWHI v1, 0(a1)
- addu a1, a1, a3
+ PTR_ADDU a1, a1, a3
1:
and v1, a2, 3 # compute number of whole words left
- subu a3, a2, v1
+ PTR_SUBU a3, a2, v1
move a2, v1
- addu a3, a3, a0 # compute ending address
+ PTR_ADDU a3, a3, a0 # compute ending address
2:
lw v1, 0(a0) # copy words
- addu a0, a0, 4
+ PTR_ADDU a0, a0, 4
sw v1, 0(a1)
bne a0, a3, 2b
- addu a1, a1, 4
+ PTR_ADDU a1, a1, 4
smallcpy:
ble a2, zero, 2f
- addu a3, a2, a0 # compute ending address
+ PTR_ADDU a3, a2, a0 # compute ending address
1:
lbu v1, 0(a0) # copy bytes
- addu a0, a0, 1
+ PTR_ADDU a0, a0, 1
sb v1, 0(a1)
bne a0, a3, 1b
- addu a1, a1, 1 # MMU BUG ? can not do -1(a1) at 0x80000000!!
+ PTR_ADDU a1, a1, 1 # MMU BUG ? can not do -1(a1) at 0x80000000!!
2:
j ra
nop
@@ -850,19 +762,19 @@ LEAF(memset)
sll t2, t1, 16 # shift that left 16
or t1, t2, t1 # or together
- subu t0, zero, a0 # compute # bytes to word align address
+ PTR_SUBU t0, zero, a0 # compute # bytes to word align address
and t0, t0, 3
beq t0, zero, 1f # skip if word aligned
- subu a2, a2, t0 # subtract from remaining count
+ PTR_SUBU a2, a2, t0 # subtract from remaining count
SWHI t1, 0(a0) # store 1, 2, or 3 bytes to align
- addu a0, a0, t0
+ PTR_ADDU a0, a0, t0
1:
and v1, a2, 3 # compute number of whole words left
- subu t0, a2, v1
- subu a2, a2, t0
- addu t0, t0, a0 # compute ending address
+ PTR_SUBU t0, a2, v1
+ PTR_SUBU a2, a2, t0
+ PTR_ADDU t0, t0, a0 # compute ending address
2:
- addu a0, a0, 4 # clear words
+ PTR_ADDU a0, a0, 4 # clear words
#ifdef MIPS3_5900
nop
nop
@@ -874,9 +786,9 @@ LEAF(memset)
memsetsmallclr:
ble a2, zero, 2f
- addu t0, a2, a0 # compute ending address
+ PTR_ADDU t0, a2, a0 # compute ending address
1:
- addu a0, a0, 1 # clear bytes
+ PTR_ADDU a0, a0, 1 # clear bytes
#ifdef MIPS3_5900
nop
nop
@@ -898,26 +810,26 @@ LEAF(bzero)
ALEAF(blkclr)
.set noreorder
blt a1, 12, smallclr # small amount to clear?
- subu a3, zero, a0 # compute # bytes to word align address
+ PTR_SUBU a3, zero, a0 # compute # bytes to word align address
and a3, a3, 3
beq a3, zero, 1f # skip if word aligned
- subu a1, a1, a3 # subtract from remaining count
+ PTR_SUBU a1, a1, a3 # subtract from remaining count
SWHI zero, 0(a0) # clear 1, 2, or 3 bytes to align
- addu a0, a0, a3
+ PTR_ADDU a0, a0, a3
1:
and v0, a1, 3 # compute number of words left
- subu a3, a1, v0
+ PTR_SUBU a3, a1, v0
move a1, v0
- addu a3, a3, a0 # compute ending address
+ PTR_ADDU a3, a3, a0 # compute ending address
2:
- addu a0, a0, 4 # clear words
+ PTR_ADDU a0, a0, 4 # clear words
bne a0, a3, 2b # unrolling loop does not help
sw zero, -4(a0) # since we are limited by memory speed
smallclr:
ble a1, zero, 2f
- addu a3, a1, a0 # compute ending address
+ PTR_ADDU a3, a1, a0 # compute ending address
1:
- addu a0, a0, 1 # clear bytes
+ PTR_ADDU a0, a0, 1 # clear bytes
bne a0, a3, 1b
sb zero, -1(a0)
2:
@@ -934,66 +846,66 @@ LEAF(bcmp)
blt a2, 16, smallcmp # is it worth any trouble?
xor v0, a0, a1 # compare low two bits of addresses
and v0, v0, 3
- subu a3, zero, a1 # compute # bytes to word align address
+ PTR_SUBU a3, zero, a1 # compute # bytes to word align address
bne v0, zero, unalignedcmp # not possible to align addresses
and a3, a3, 3
beq a3, zero, 1f
- subu a2, a2, a3 # subtract from remaining count
+ PTR_SUBU a2, a2, a3 # subtract from remaining count
move v0, v1 # init v0,v1 so unmodified bytes match
LWHI v0, 0(a0) # read 1, 2, or 3 bytes
LWHI v1, 0(a1)
- addu a1, a1, a3
+ PTR_ADDU a1, a1, a3
bne v0, v1, nomatch
- addu a0, a0, a3
+ PTR_ADDU a0, a0, a3
1:
and a3, a2, ~3 # compute number of whole words left
- subu a2, a2, a3 # which has to be >= (16-3) & ~3
- addu a3, a3, a0 # compute ending address
+ PTR_SUBU a2, a2, a3 # which has to be >= (16-3) & ~3
+ PTR_ADDU a3, a3, a0 # compute ending address
2:
lw v0, 0(a0) # compare words
lw v1, 0(a1)
- addu a0, a0, 4
+ PTR_ADDU a0, a0, 4
bne v0, v1, nomatch
- addu a1, a1, 4
+ PTR_ADDU a1, a1, 4
bne a0, a3, 2b
nop
b smallcmp # finish remainder
nop
unalignedcmp:
beq a3, zero, 2f
- subu a2, a2, a3 # subtract from remaining count
- addu a3, a3, a0 # compute ending address
+ PTR_SUBU a2, a2, a3 # subtract from remaining count
+ PTR_ADDU a3, a3, a0 # compute ending address
1:
lbu v0, 0(a0) # compare bytes until a1 word aligned
lbu v1, 0(a1)
- addu a0, a0, 1
+ PTR_ADDU a0, a0, 1
bne v0, v1, nomatch
- addu a1, a1, 1
+ PTR_ADDU a1, a1, 1
bne a0, a3, 1b
nop
2:
and a3, a2, ~3 # compute number of whole words left
- subu a2, a2, a3 # which has to be >= (16-3) & ~3
- addu a3, a3, a0 # compute ending address
+ PTR_SUBU a2, a2, a3 # which has to be >= (16-3) & ~3
+ PTR_ADDU a3, a3, a0 # compute ending address
3:
LWHI v0, 0(a0) # compare words a0 unaligned, a1 aligned
LWLO v0, 3(a0)
lw v1, 0(a1)
- addu a0, a0, 4
+ PTR_ADDU a0, a0, 4
bne v0, v1, nomatch
- addu a1, a1, 4
+ PTR_ADDU a1, a1, 4
bne a0, a3, 3b
nop
smallcmp:
ble a2, zero, match
- addu a3, a2, a0 # compute ending address
+ PTR_ADDU a3, a2, a0 # compute ending address
1:
lbu v0, 0(a0)
lbu v1, 0(a1)
- addu a0, a0, 1
+ PTR_ADDU a0, a0, 1
bne v0, v1, nomatch
- addu a1, a1, 1
+ PTR_ADDU a1, a1, 1
bne a0, a3, 1b
nop
match:
@@ -1334,9 +1246,6 @@ END(atomic_subtract_8)
*/
.set noreorder # Noreorder is default style!
-#ifndef _MIPS_ARCH_XLR
- .set mips3
-#endif
#if !defined(__mips_n64) && !defined(__mips_n32)
/*
@@ -1393,22 +1302,22 @@ END(atomic_load_64)
#if defined(DDB) || defined(DEBUG)
LEAF(kdbpeek)
- li v1, DDBERR
+ PTR_LA v1, ddberr
and v0, a0, 3 # unaligned ?
GET_CPU_PCPU(t1)
- lw t1, PC_CURPCB(t1)
+ PTR_L t1, PC_CURPCB(t1)
bne v0, zero, 1f
- sw v1, U_PCB_ONFAULT(t1)
+ PTR_S v1, U_PCB_ONFAULT(t1)
lw v0, (a0)
jr ra
- sw zero, U_PCB_ONFAULT(t1)
+ PTR_S zero, U_PCB_ONFAULT(t1)
1:
LWHI v0, 0(a0)
LWLO v0, 3(a0)
jr ra
- sw zero, U_PCB_ONFAULT(t1)
+ PTR_S zero, U_PCB_ONFAULT(t1)
END(kdbpeek)
ddberr:
@@ -1417,44 +1326,31 @@ ddberr:
#if defined(DDB)
LEAF(kdbpoke)
- li v1, DDBERR
+ PTR_LA v1, ddberr
and v0, a0, 3 # unaligned ?
GET_CPU_PCPU(t1)
- lw t1, PC_CURPCB(t1)
+ PTR_L t1, PC_CURPCB(t1)
bne v0, zero, 1f
- sw v1, U_PCB_ONFAULT(t1)
+ PTR_S v1, U_PCB_ONFAULT(t1)
sw a1, (a0)
jr ra
- sw zero, U_PCB_ONFAULT(t1)
+ PTR_S zero, U_PCB_ONFAULT(t1)
1:
SWHI a1, 0(a0)
SWLO a1, 3(a0)
jr ra
- sw zero, U_PCB_ONFAULT(t1)
+ PTR_S zero, U_PCB_ONFAULT(t1)
END(kdbpoke)
.data
.globl esym
esym: .word 0
-#ifndef _MIPS_ARCH_XLR
- .set mips2
-#endif
#endif /* DDB */
#endif /* DDB || DEBUG */
-#ifndef MIPS_ISAIII
-#define STORE sw /* 32 bit mode regsave instruction */
-#define LOAD lw /* 32 bit mode regload instruction */
-#define RSIZE 4 /* 32 bit mode register size */
-#else
-#define STORE sd /* 64 bit mode regsave instruction */
-#define LOAD ld /* 64 bit mode regload instruction */
-#define RSIZE 8 /* 64 bit mode register size */
-#endif
-
#define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
.text
@@ -1466,35 +1362,35 @@ LEAF(breakpoint)
LEAF(setjmp)
mfc0 v0, COP_0_STATUS_REG # Later the "real" spl value!
- STORE s0, (RSIZE * PREG_S0)(a0)
- STORE s1, (RSIZE * PREG_S1)(a0)
- STORE s2, (RSIZE * PREG_S2)(a0)
- STORE s3, (RSIZE * PREG_S3)(a0)
- STORE s4, (RSIZE * PREG_S4)(a0)
- STORE s5, (RSIZE * PREG_S5)(a0)
- STORE s6, (RSIZE * PREG_S6)(a0)
- STORE s7, (RSIZE * PREG_S7)(a0)
- STORE s8, (RSIZE * PREG_SP)(a0)
- STORE sp, (RSIZE * PREG_S8)(a0)
- STORE ra, (RSIZE * PREG_RA)(a0)
- STORE v0, (RSIZE * PREG_SR)(a0)
+ REG_S s0, (SZREG * PREG_S0)(a0)
+ REG_S s1, (SZREG * PREG_S1)(a0)
+ REG_S s2, (SZREG * PREG_S2)(a0)
+ REG_S s3, (SZREG * PREG_S3)(a0)
+ REG_S s4, (SZREG * PREG_S4)(a0)
+ REG_S s5, (SZREG * PREG_S5)(a0)
+ REG_S s6, (SZREG * PREG_S6)(a0)
+ REG_S s7, (SZREG * PREG_S7)(a0)
+ REG_S s8, (SZREG * PREG_S8)(a0)
+ REG_S sp, (SZREG * PREG_SP)(a0)
+ REG_S ra, (SZREG * PREG_RA)(a0)
+ REG_S v0, (SZREG * PREG_SR)(a0)
jr ra
li v0, 0 # setjmp return
END(setjmp)
LEAF(longjmp)
- LOAD v0, (RSIZE * PREG_SR)(a0)
- LOAD ra, (RSIZE * PREG_RA)(a0)
- LOAD s0, (RSIZE * PREG_S0)(a0)
- LOAD s1, (RSIZE * PREG_S1)(a0)
- LOAD s2, (RSIZE * PREG_S2)(a0)
- LOAD s3, (RSIZE * PREG_S3)(a0)
- LOAD s4, (RSIZE * PREG_S4)(a0)
- LOAD s5, (RSIZE * PREG_S5)(a0)
- LOAD s6, (RSIZE * PREG_S6)(a0)
- LOAD s7, (RSIZE * PREG_S7)(a0)
- LOAD s8, (RSIZE * PREG_S8)(a0)
- LOAD sp, (RSIZE * PREG_SP)(a0)
+ REG_L v0, (SZREG * PREG_SR)(a0)
+ REG_L ra, (SZREG * PREG_RA)(a0)
+ REG_L s0, (SZREG * PREG_S0)(a0)
+ REG_L s1, (SZREG * PREG_S1)(a0)
+ REG_L s2, (SZREG * PREG_S2)(a0)
+ REG_L s3, (SZREG * PREG_S3)(a0)
+ REG_L s4, (SZREG * PREG_S4)(a0)
+ REG_L s5, (SZREG * PREG_S5)(a0)
+ REG_L s6, (SZREG * PREG_S6)(a0)
+ REG_L s7, (SZREG * PREG_S7)(a0)
+ REG_L s8, (SZREG * PREG_S8)(a0)
+ REG_L sp, (SZREG * PREG_SP)(a0)
mtc0 v0, COP_0_STATUS_REG # Later the "real" spl value!
ITLBNOPFIX
jr ra
@@ -1505,7 +1401,6 @@ LEAF(fusufault)
GET_CPU_PCPU(t0)
lw t0, PC_CURTHREAD(t0)
lw t0, TD_PCB(t0)
- sw zero, U_PCB_ONFAULT(t0)
li v0, -1
j ra
END(fusufault)
@@ -1514,8 +1409,7 @@ END(fusufault)
a pointer that is in user space. It will be used as the basic primitive
for a kernel supported user space lock implementation. */
LEAF(casuptr)
-
- li t0, VM_MAXUSER_ADDRESS /* verify address validity */
+ PTR_LI t0, VM_MAXUSER_ADDRESS /* verify address validity */
blt a0, t0, fusufault /* trap faults */
nop
@@ -1523,8 +1417,8 @@ LEAF(casuptr)
lw t1, PC_CURTHREAD(t1)
lw t1, TD_PCB(t1)
- lw t2, fusufault
- sw t2, U_PCB_ONFAULT(t1)
+ PTR_LA t2, fusufault
+ PTR_S t2, U_PCB_ONFAULT(t1)
1:
ll v0, 0(a0) /* try to load the old value */
beq v0, a1, 2f /* compare */
@@ -1532,7 +1426,7 @@ LEAF(casuptr)
sc t0, 0(a0) /* write if address still locked */
beq t0, zero, 1b /* if it failed, spin */
2:
- sw zero, U_PCB_ONFAULT(t1) /* clean up */
+ PTR_S zero, U_PCB_ONFAULT(t1) /* clean up */
j ra
END(casuptr)
@@ -1560,7 +1454,7 @@ END(octeon_get_shadow)
* octeon_set_control(addr, uint32_t val)
*/
LEAF(octeon_set_control)
- .set mips64r2
+ .set push
or t1, a1, zero
/* dmfc0 a1, 9, 7*/
.word 0x40254807
@@ -1570,19 +1464,95 @@ LEAF(octeon_set_control)
.word 0x40a54807
jr ra
nop
- .set mips0
+ .set pop
END(octeon_set_control)
/*
* octeon_get_control(addr)
*/
LEAF(octeon_get_control)
+ .set push
.set mips64r2
/* dmfc0 a1, 9, 7 */
.word 0x40254807
sd a1, 0(a0)
jr ra
nop
- .set mips0
+ .set pop
END(octeon_get_control)
#endif
+
+LEAF(mips3_ld)
+ .set push
+ .set noreorder
+ .set mips64
+#if defined(__mips_o32)
+ mfc0 t0, MIPS_COP_0_STATUS # turn off interrupts
+ and t1, t0, ~(MIPS_SR_INT_IE)
+ mtc0 t1, MIPS_COP_0_STATUS
+ COP0_SYNC
+ nop
+ nop
+ nop
+
+ ld v0, 0(a0)
+#if _BYTE_ORDER == _BIG_ENDIAN
+ dsll v1, v0, 32
+ dsra v1, v1, 32 # low word in v1
+ dsra v0, v0, 32 # high word in v0
+#else
+ dsra v1, v0, 32 # high word in v1
+ dsll v0, v0, 32
+ dsra v0, v0, 32 # low word in v0
+#endif
+
+ mtc0 t0, MIPS_COP_0_STATUS # restore intr status.
+ COP0_SYNC
+ nop
+#else /* !__mips_o32 */
+ ld v0, 0(a0)
+#endif /* !__mips_o32 */
+
+ jr ra
+ nop
+ .set pop
+END(mips3_ld)
+
+LEAF(mips3_sd)
+ .set push
+ .set mips64
+ .set noreorder
+#if defined(__mips_o32)
+ mfc0 t0, MIPS_COP_0_STATUS # turn off interrupts
+ and t1, t0, ~(MIPS_SR_INT_IE)
+ mtc0 t1, MIPS_COP_0_STATUS
+ COP0_SYNC
+ nop
+ nop
+ nop
+
+ # NOTE: a1 is padding!
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+ dsll a2, a2, 32 # high word in a2
+ dsll a3, a3, 32 # low word in a3
+ dsrl a3, a3, 32
+#else
+ dsll a2, a2, 32 # low word in a2
+ dsrl a2, a2, 32
+ dsll a3, a3, 32 # high word in a3
+#endif
+ or a1, a2, a3
+ sd a1, 0(a0)
+
+ mtc0 t0, MIPS_COP_0_STATUS # restore intr status.
+ COP0_SYNC
+ nop
+#else /* !__mips_o32 */
+ sd a1, 0(a0)
+#endif /* !__mips_o32 */
+
+ jr ra
+ nop
+ .set pop
+END(mips3_sd)
diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S
index 1248276..f287476 100644
--- a/sys/mips/mips/swtch.S
+++ b/sys/mips/mips/swtch.S
@@ -65,53 +65,7 @@
#include "assym.s"
-#if defined(ISA_MIPS32)
-#undef WITH_64BIT_CP0
-#elif defined(ISA_MIPS64)
-#define WITH_64BIT_CP0
-#elif defined(ISA_MIPS3)
-#define WITH_64BIT_CP0
-#else
-#error "Please write the code for this ISA"
-#endif
-
-#ifdef WITH_64BIT_CP0
-#define _SLL dsll
-#define _SRL dsrl
-#define _MFC0 dmfc0
-#define _MTC0 dmtc0
-#define WIRED_SHIFT 34
-#else
-#define _SLL sll
-#define _SRL srl
-#define _MFC0 mfc0
-#define _MTC0 mtc0
-#define WIRED_SHIFT 2
-#endif
.set noreorder # Noreorder is default style!
-#if defined(ISA_MIPS32)
- .set mips32
-#elif defined(ISA_MIPS64)
- .set mips64
-#elif defined(ISA_MIPS3)
- .set mips3
-#endif
-
-#if defined(ISA_MIPS32)
-#define STORE sw /* 32 bit mode regsave instruction */
-#define LOAD lw /* 32 bit mode regload instruction */
-#define RSIZE 4 /* 32 bit mode register size */
-#define STORE_FP swc1 /* 32 bit mode fp regsave instruction */
-#define LOAD_FP lwc1 /* 32 bit mode fp regload instruction */
-#define FP_RSIZE 4 /* 32 bit mode fp register size */
-#else
-#define STORE sd /* 64 bit mode regsave instruction */
-#define LOAD ld /* 64 bit mode regload instruction */
-#define RSIZE 8 /* 64 bit mode register size */
-#define STORE_FP sdc1 /* 64 bit mode fp regsave instruction */
-#define LOAD_FP ldc1 /* 64 bit mode fp regload instruction */
-#define FP_RSIZE 8 /* 64 bit mode fp register size */
-#endif
/*
* FREEBSD_DEVELOPERS_FIXME
@@ -125,28 +79,28 @@
#endif
#define SAVE_U_PCB_REG(reg, offs, base) \
- STORE reg, U_PCB_REGS + (RSIZE * offs) (base)
+ REG_S reg, U_PCB_REGS + (SZREG * offs) (base)
#define RESTORE_U_PCB_REG(reg, offs, base) \
- LOAD reg, U_PCB_REGS + (RSIZE * offs) (base)
+ REG_L reg, U_PCB_REGS + (SZREG * offs) (base)
#define SAVE_U_PCB_FPREG(reg, offs, base) \
- STORE_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ FP_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define RESTORE_U_PCB_FPREG(reg, offs, base) \
- LOAD_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ FP_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define SAVE_U_PCB_FPSR(reg, offs, base) \
- STORE reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ REG_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define RESTORE_U_PCB_FPSR(reg, offs, base) \
- LOAD reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ REG_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define SAVE_U_PCB_CONTEXT(reg, offs, base) \
- STORE reg, U_PCB_CONTEXT + (RSIZE * offs) (base)
+ REG_S reg, U_PCB_CONTEXT + (SZREG * offs) (base)
#define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
- LOAD reg, U_PCB_CONTEXT + (RSIZE * offs) (base)
+ REG_L reg, U_PCB_CONTEXT + (SZREG * offs) (base)
#define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
@@ -172,7 +126,7 @@ LEAF(fork_trampoline)
*/
.set noat
GET_CPU_PCPU(k1)
- lw k1, PC_CURPCB(k1)
+ PTR_L k1, PC_CURPCB(k1)
RESTORE_U_PCB_REG(t0, MULLO, k1)
RESTORE_U_PCB_REG(t1, MULHI, k1)
@@ -181,7 +135,7 @@ LEAF(fork_trampoline)
RESTORE_U_PCB_REG(a0, PC, k1)
RESTORE_U_PCB_REG(AT, AST, k1)
RESTORE_U_PCB_REG(v0, V0, k1)
- _MTC0 a0, COP_0_EXC_PC # set return address
+ MTC0 a0, COP_0_EXC_PC # set return address
RESTORE_U_PCB_REG(v1, V1, k1)
RESTORE_U_PCB_REG(a0, A0, k1)
@@ -245,6 +199,14 @@ LEAF(savectx)
SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0)
SAVE_U_PCB_CONTEXT(v0, PREG_SR, a0)
SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0)
+
+ move v0, ra /* save 'ra' before we trash it */
+ jal 1f
+ nop
+1:
+ SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0)
+ move ra, v0 /* restore 'ra' before returning */
+
/*
* FREEBSD_DEVELOPERS_FIXME:
* In case there are CPU-specific registers that need
@@ -257,7 +219,7 @@ END(savectx)
KSEG0TEXT_START;
-NON_LEAF(mips_cpu_throw, STAND_FRAME_SIZE, ra)
+NON_LEAF(mips_cpu_throw, CALLFRAME_SIZ, ra)
mfc0 t0, COP_0_STATUS_REG # t0 = saved status register
nop
nop
@@ -277,7 +239,7 @@ END(mips_cpu_throw)
* a2 - mtx
* Find the highest priority process and resume it.
*/
-NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra)
+NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra)
mfc0 t0, COP_0_STATUS_REG # t0 = saved status register
nop
nop
@@ -286,11 +248,11 @@ NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra)
ITLBNOPFIX
beqz a0, mips_sw1
move a3, a0
- lw a0, TD_PCB(a0) # load PCB addr of curproc
+ PTR_L a0, TD_PCB(a0) # load PCB addr of curproc
SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0) # save old sp
- subu sp, sp, STAND_FRAME_SIZE
- sw ra, STAND_RA_OFFSET(sp)
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
+ REG_S ra, CALLFRAME_RA(sp)
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0) # do a 'savectx()'
SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0)
SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0)
@@ -313,13 +275,13 @@ getpc:
* to be saved with the other registers do so here.
*/
- sw a2, TD_LOCK(a3) # Switchout td_lock
+ PTR_S a2, TD_LOCK(a3) # Switchout td_lock
mips_sw1:
#if defined(SMP) && defined(SCHED_ULE)
PTR_LA t0, _C_LABEL(blocked_lock)
blocked_loop:
- lw t1, TD_LOCK(a1)
+ PTR_L t1, TD_LOCK(a1)
beq t0, t1, blocked_loop
nop
#endif
@@ -328,20 +290,16 @@ blocked_loop:
* Switch to new context.
*/
GET_CPU_PCPU(a3)
- sw a1, PC_CURTHREAD(a3)
- lw a2, TD_PCB(a1)
- sw a2, PC_CURPCB(a3)
- lw v0, TD_REALKSTACK(a1)
- li s0, (MIPS_KSEG2_START+VM_KERNEL_ALLOC_OFFSET) # If Uarea addr is below kseg2,
+ PTR_S a1, PC_CURTHREAD(a3)
+ PTR_L a2, TD_PCB(a1)
+ PTR_S a2, PC_CURPCB(a3)
+ PTR_L v0, TD_KSTACK(a1)
+#if !defined(__mips_n64)
+ PTR_LI s0, MIPS_KSEG2_START # If Uarea addr is below kseg2,
bltu v0, s0, sw2 # no need to insert in TLB.
- lw a1, TD_UPTE+0(s7) # t0 = first u. pte
- lw a2, TD_UPTE+4(s7) # t1 = 2nd u. pte
- and s0, v0, PTE_ODDPG
- beq s0, zero, entry0
- nop
-
- PANIC_KSEG0("USPACE sat on odd page boundary", t1)
-
+#endif
+ lw a1, TD_UPTE + 0(s7) # a1 = u. pte #0
+ lw a2, TD_UPTE + 4(s7) # a2 = u. pte #1
/*
* Wiredown the USPACE of newproc in TLB entry#0. Check whether target
* USPACE is already in another place of TLB before that, and if so
@@ -349,31 +307,32 @@ blocked_loop:
* NOTE: This is hard coded to UPAGES == 2.
* Also, there should be no TLB faults at this point.
*/
-entry0:
- mtc0 v0, COP_0_TLB_HI # VPN = va
+ MTC0 v0, COP_0_TLB_HI # VPN = va
HAZARD_DELAY
tlbp # probe VPN
HAZARD_DELAY
mfc0 s0, COP_0_TLB_INDEX
- nop
-pgm:
+ HAZARD_DELAY
+
+ PTR_LI t1, MIPS_KSEG0_START # invalidate tlb entry
bltz s0, entry0set
- li t1, MIPS_KSEG0_START # invalidate tlb entry
+ nop
sll s0, PAGE_SHIFT + 1
addu t1, s0
- mtc0 t1, COP_0_TLB_HI
+ MTC0 t1, COP_0_TLB_HI
mtc0 zero, COP_0_TLB_LO0
mtc0 zero, COP_0_TLB_LO1
HAZARD_DELAY
tlbwi
HAZARD_DELAY
- mtc0 v0, COP_0_TLB_HI # set VPN again
+ MTC0 v0, COP_0_TLB_HI # set VPN again
+
entry0set:
/* SMP!! - Works only for unshared TLB case - i.e. no v-cpus */
mtc0 zero, COP_0_TLB_INDEX # TLB entry #0
-# or a1, PG_G
+ HAZARD_DELAY
mtc0 a1, COP_0_TLB_LO0 # upte[0]
-# or a2, PG_G
+ HAZARD_DELAY
mtc0 a2, COP_0_TLB_LO1 # upte[1]
HAZARD_DELAY
tlbwi # set TLB entry #0
@@ -388,7 +347,7 @@ sw2:
/*
* Restore registers and return.
*/
- lw a0, TD_PCB(s7)
+ PTR_L a0, TD_PCB(s7)
RESTORE_U_PCB_CONTEXT(gp, PREG_GP, a0)
RESTORE_U_PCB_CONTEXT(v0, PREG_SR, a0) # restore kernel context
RESTORE_U_PCB_CONTEXT(ra, PREG_RA, a0)
@@ -449,7 +408,7 @@ LEAF(MipsSwitchFPState)
* First read out the status register to make sure that all FP operations
* have completed.
*/
- lw a0, TD_PCB(a0) # get pointer to pcb for proc
+ PTR_L a0, TD_PCB(a0) # get pointer to pcb for proc
cfc1 t0, FPC_CSR # stall til FP done
cfc1 t0, FPC_CSR # now get status
li t3, ~SR_COP_1_BIT
@@ -559,13 +518,13 @@ END(MipsSwitchFPState)
*----------------------------------------------------------------------------
*/
LEAF(MipsSaveCurFPState)
- lw a0, TD_PCB(a0) # get pointer to pcb for thread
+ PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread
mfc0 t1, COP_0_STATUS_REG # Disable interrupts and
li t0, SR_COP_1_BIT # enable the coprocessor
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
GET_CPU_PCPU(a1)
- sw zero, PC_FPCURTHREAD(a1) # indicate state has been saved
+ PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved
/*
* First read out the status register to make sure that all FP operations
* have completed.
diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c
index bf147c5..5931a5b 100644
--- a/sys/mips/mips/tick.c
+++ b/sys/mips/mips/tick.c
@@ -54,6 +54,8 @@ __FBSDID("$FreeBSD$");
uint64_t counter_freq;
+struct timecounter *platform_timecounter;
+
static uint64_t cycles_per_tick;
static uint64_t cycles_per_usec;
static uint64_t cycles_per_hz, cycles_per_stathz, cycles_per_profhz;
@@ -61,17 +63,14 @@ static uint64_t cycles_per_hz, cycles_per_stathz, cycles_per_profhz;
static u_int32_t counter_upper = 0;
static u_int32_t counter_lower_last = 0;
-struct clk_ticks
-{
+struct clk_ticks {
u_long hard_ticks;
u_long stat_ticks;
u_long prof_ticks;
- /*
- * pad for cache line alignment of pcpu info
- * cache-line-size - number of used bytes
- */
- char pad[32-(3*sizeof (u_long))];
-} static pcpu_ticks[MAXCPU];
+ uint32_t compare_ticks;
+} __aligned(CACHE_LINE_SIZE);
+
+static struct clk_ticks pcpu_ticks[MAXCPU];
/*
* Device methods
@@ -103,6 +102,9 @@ platform_initclocks(void)
{
tc_init(&counter_timecounter);
+
+ if (platform_timecounter != NULL)
+ tc_init(platform_timecounter);
}
static uint64_t
@@ -255,46 +257,77 @@ clock_intr(void *arg)
{
struct clk_ticks *cpu_ticks;
struct trapframe *tf;
- uint32_t ltick;
+ uint32_t count, compare, delta;
+
+ cpu_ticks = &pcpu_ticks[PCPU_GET(cpuid)];
+
/*
* Set next clock edge.
*/
- ltick = mips_rd_count();
- mips_wr_compare(ltick + cycles_per_tick);
- cpu_ticks = &pcpu_ticks[PCPU_GET(cpuid)];
+ count = mips_rd_count();
+ compare = cpu_ticks->compare_ticks;
+ cpu_ticks->compare_ticks = count + cycles_per_tick;
+ mips_wr_compare(cpu_ticks->compare_ticks);
critical_enter();
- if (ltick < counter_lower_last) {
+ if (count < counter_lower_last) {
counter_upper++;
- counter_lower_last = ltick;
+ counter_lower_last = count;
}
/*
* Magic. Setting up with an arg of NULL means we get passed tf.
*/
tf = (struct trapframe *)arg;
+ delta = cycles_per_tick;
+
+ /*
+ * Account for the "lost time" between when the timer interrupt fired
+ * and when 'clock_intr' actually started executing.
+ */
+ delta += count - compare;
+
+ /*
+ * If the COUNT and COMPARE registers are no longer in sync then make
+ * up some reasonable value for the 'delta'.
+ *
+ * This could happen, for e.g., after we resume normal operations after
+ * exiting the debugger.
+ */
+ if (delta > cycles_per_hz)
+ delta = cycles_per_hz;
+#ifdef KDTRACE_HOOKS
+ /*
+ * If the DTrace hooks are configured and a callback function
+ * has been registered, then call it to process the high speed
+ * timers.
+ */
+ int cpu = PCPU_GET(cpuid);
+ if (cyclic_clock_func[cpu] != NULL)
+ (*cyclic_clock_func[cpu])(tf);
+#endif
/* Fire hardclock at hz. */
- cpu_ticks->hard_ticks += cycles_per_tick;
+ cpu_ticks->hard_ticks += delta;
if (cpu_ticks->hard_ticks >= cycles_per_hz) {
cpu_ticks->hard_ticks -= cycles_per_hz;
if (PCPU_GET(cpuid) == 0)
- hardclock(USERMODE(tf->sr), tf->pc);
+ hardclock(TRAPF_USERMODE(tf), tf->pc);
else
- hardclock_cpu(USERMODE(tf->sr));
+ hardclock_cpu(TRAPF_USERMODE(tf));
}
/* Fire statclock at stathz. */
- cpu_ticks->stat_ticks += cycles_per_tick;
+ cpu_ticks->stat_ticks += delta;
if (cpu_ticks->stat_ticks >= cycles_per_stathz) {
cpu_ticks->stat_ticks -= cycles_per_stathz;
- statclock(USERMODE(tf->sr));
+ statclock(TRAPF_USERMODE(tf));
}
/* Fire profclock at profhz, but only when needed. */
- cpu_ticks->prof_ticks += cycles_per_tick;
+ cpu_ticks->prof_ticks += delta;
if (cpu_ticks->prof_ticks >= cycles_per_profhz) {
cpu_ticks->prof_ticks -= cycles_per_profhz;
if (profprocs != 0)
- profclock(USERMODE(tf->sr), tf->pc);
+ profclock(TRAPF_USERMODE(tf), tf->pc);
}
critical_exit();
#if 0 /* TARGET_OCTEON */
diff --git a/sys/mips/mips/tlb.S b/sys/mips/mips/tlb.S
index 46a15f8..f6e7934 100644
--- a/sys/mips/mips/tlb.S
+++ b/sys/mips/mips/tlb.S
@@ -240,7 +240,7 @@ LEAF(Mips_TLBFlush)
# MIPS_KSEG0_START + 2 * i * PAGE_SIZE;
# One bogus value for every TLB entry might cause MCHECK exception
#
- sll t3, t1, PGSHIFT + 1
+ sll t3, t1, PAGE_SHIFT + 1
li v0, MIPS_KSEG0_START # invalid address
addu v0, t3
/*
@@ -299,7 +299,7 @@ LEAF(Mips_TLBFlushAddr)
# address calculated by following expression:
# MIPS_KSEG0_START + 2 * i * PAGE_SIZE;
# One bogus value for every TLB entry might cause MCHECK exception
- sll v0, PGSHIFT + 1
+ sll v0, PAGE_SHIFT + 1
addu t1, v0
_MTC0 t1, COP_0_TLB_HI # Mark entry high as invalid
@@ -482,7 +482,7 @@ LEAF(mips_TBIAP)
# MIPS_KSEG0_START + 2 * i * PAGE_SIZE;
# One bogus value for every TLB entry might cause MCHECK exception
#
- sll t3, t1, PGSHIFT + 1
+ sll t3, t1, PAGE_SHIFT + 1
li v0, MIPS_KSEG0_START # invalid address
addu v0, t3
@@ -507,7 +507,7 @@ LEAF(mips_TBIAP)
tlbwi # invalidate the TLB entry
2:
addu t1, t1, 1
- addu v0, 1 << (PGSHIFT + 1)
+ addu v0, 1 << (PAGE_SHIFT + 1)
bne t1, t2, 1b
nop
diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c
index 5fdfabd..17a6be5 100644
--- a/sys/mips/mips/trap.c
+++ b/sys/mips/mips/trap.c
@@ -75,7 +75,6 @@ __FBSDID("$FreeBSD$");
#include <net/netisr.h>
#include <machine/trap.h>
-#include <machine/psl.h>
#include <machine/cpu.h>
#include <machine/pte.h>
#include <machine/pmap.h>
@@ -83,8 +82,6 @@ __FBSDID("$FreeBSD$");
#include <machine/mips_opcode.h>
#include <machine/frame.h>
#include <machine/regnum.h>
-#include <machine/rm7000.h>
-#include <machine/archtype.h>
#include <machine/asm.h>
#ifdef DDB
@@ -102,8 +99,7 @@ __FBSDID("$FreeBSD$");
int trap_debug = 1;
#endif
-extern unsigned onfault_table[];
-
+static void log_illegal_instruction(const char *, struct trapframe *);
static void log_bad_page_fault(char *, struct trapframe *, int);
static void log_frame_dump(struct trapframe *frame);
static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
@@ -118,8 +114,8 @@ void (*machExceptionTable[]) (void)= {
*/
MipsKernIntr, /* external interrupt */
MipsKernGenException, /* TLB modification */
- MipsKernTLBInvalidException, /* TLB miss (load or instr. fetch) */
- MipsKernTLBInvalidException, /* TLB miss (store) */
+ MipsTLBInvalidException,/* TLB miss (load or instr. fetch) */
+ MipsTLBInvalidException,/* TLB miss (store) */
MipsKernGenException, /* address error (load or I-fetch) */
MipsKernGenException, /* address error (store) */
MipsKernGenException, /* bus error (I-fetch) */
@@ -153,8 +149,8 @@ void (*machExceptionTable[]) (void)= {
*/
MipsUserIntr, /* 0 */
MipsUserGenException, /* 1 */
- MipsUserTLBInvalidException, /* 2 */
- MipsUserTLBInvalidException, /* 3 */
+ MipsTLBInvalidException,/* 2 */
+ MipsTLBInvalidException,/* 3 */
MipsUserGenException, /* 4 */
MipsUserGenException, /* 5 */
MipsUserGenException, /* 6 */
@@ -229,8 +225,8 @@ void stacktrace(struct trapframe *);
void logstacktrace(struct trapframe *);
#endif
-#define KERNLAND(x) ((int)(x) < 0)
-#define DELAYBRANCH(x) ((int)(x) < 0)
+#define KERNLAND(x) ((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS)
+#define DELAYBRANCH(x) ((int)(x) < 0)
/*
* MIPS load/store access type
@@ -266,6 +262,7 @@ SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
static int emulate_unaligned_access(struct trapframe *frame);
extern char *syscallnames[];
+extern void fswintrberr(void); /* XXX */
/*
* Handle an exception.
@@ -274,7 +271,7 @@ extern char *syscallnames[];
* In the case of a kernel trap, we return the pc where to resume if
* p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
*/
-u_int
+register_t
trap(struct trapframe *trapframe)
{
int type, usermode;
@@ -284,18 +281,17 @@ trap(struct trapframe *trapframe)
struct proc *p = curproc;
vm_prot_t ftype;
pt_entry_t *pte;
- unsigned int entry;
pmap_t pmap;
- int quad_syscall = 0;
int access_type;
ksiginfo_t ksi;
char *msg = NULL;
- register_t addr = 0;
+ intptr_t addr = 0;
+ register_t pc;
trapdebug_enter(trapframe, 0);
type = (trapframe->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT;
- if (USERMODE(trapframe->sr)) {
+ if (TRAPF_USERMODE(trapframe)) {
type |= T_USER;
usermode = 1;
} else {
@@ -309,9 +305,9 @@ trap(struct trapframe *trapframe)
*/
if (trapframe->sr & SR_INT_ENAB) {
set_intr_mask(~(trapframe->sr & ALL_INT_MASK));
- enableintr();
+ intr_enable();
} else {
- disableintr();
+ intr_disable();
}
#ifdef TRAP_DEBUG
@@ -333,9 +329,9 @@ trap(struct trapframe *trapframe)
printf("cpuid = %d\n", PCPU_GET(cpuid));
#endif
MachTLBGetPID(pid);
- printf("badaddr = 0x%0x, pc = 0x%0x, ra = 0x%0x, sp = 0x%0x, sr = 0x%x, pid = %d, ASID = 0x%x\n",
- trapframe->badvaddr, trapframe->pc, trapframe->ra,
- trapframe->sp, trapframe->sr,
+ printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
+ (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
+ (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
(curproc ? curproc->p_pid : -1), pid);
switch (type & ~T_USER) {
@@ -357,7 +353,7 @@ trap(struct trapframe *trapframe)
((type & ~T_USER) != T_SYSCALL)) {
if (++count == 3) {
trap_frame_dump(trapframe);
- panic("too many faults at %x\n", last_badvaddr);
+ panic("too many faults at %p\n", (void *)last_badvaddr);
}
} else {
last_badvaddr = this_badvaddr;
@@ -378,35 +374,30 @@ trap(struct trapframe *trapframe)
vm_offset_t pa;
PMAP_LOCK(kernel_pmap);
- if (!(pte = pmap_segmap(kernel_pmap,
- trapframe->badvaddr)))
- panic("trap: ktlbmod: invalid segmap");
- pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
- entry = *pte;
+ pte = pmap_pte(kernel_pmap, trapframe->badvaddr);
+ if (pte == NULL)
+ panic("trap: ktlbmod: can't find PTE");
#ifdef SMP
/* It is possible that some other CPU changed m-bit */
- if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
- trapframe->badvaddr &= ~PGOFSET;
+ if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) {
pmap_update_page(kernel_pmap,
- trapframe->badvaddr, entry);
+ trapframe->badvaddr, *pte);
PMAP_UNLOCK(kernel_pmap);
return (trapframe->pc);
}
#else
- if (!mips_pg_v(entry) || (entry & mips_pg_m_bit()))
+ if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit()))
panic("trap: ktlbmod: invalid pte");
#endif
- if (entry & mips_pg_ro_bit()) {
+ if (*pte & mips_pg_ro_bit()) {
/* write to read only page in the kernel */
ftype = VM_PROT_WRITE;
PMAP_UNLOCK(kernel_pmap);
goto kernel_fault;
}
- entry |= mips_pg_m_bit();
- *pte = entry;
- trapframe->badvaddr &= ~PGOFSET;
- pmap_update_page(kernel_pmap, trapframe->badvaddr, entry);
- pa = mips_tlbpfn_to_paddr(entry);
+ *pte |= mips_pg_m_bit();
+ pmap_update_page(kernel_pmap, trapframe->badvaddr, *pte);
+ pa = mips_tlbpfn_to_paddr(*pte);
if (!page_is_managed(pa))
panic("trap: ktlbmod: unmanaged page");
pmap_set_modified(pa);
@@ -422,36 +413,30 @@ trap(struct trapframe *trapframe)
pmap = &p->p_vmspace->vm_pmap;
PMAP_LOCK(pmap);
- if (!(pte = pmap_segmap(pmap, trapframe->badvaddr)))
- panic("trap: utlbmod: invalid segmap");
- pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
- entry = *pte;
+ pte = pmap_pte(pmap, trapframe->badvaddr);
+ if (pte == NULL)
+ panic("trap: utlbmod: can't find PTE");
#ifdef SMP
/* It is possible that some other CPU changed m-bit */
- if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
- trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
- pmap_update_page(pmap, trapframe->badvaddr, entry);
+ if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) {
+ pmap_update_page(pmap, trapframe->badvaddr, *pte);
PMAP_UNLOCK(pmap);
goto out;
}
#else
- if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
+ if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit()))
panic("trap: utlbmod: invalid pte");
- }
#endif
- if (entry & mips_pg_ro_bit()) {
+ if (*pte & mips_pg_ro_bit()) {
/* write to read only page */
ftype = VM_PROT_WRITE;
PMAP_UNLOCK(pmap);
goto dofault;
}
- entry |= mips_pg_m_bit();
- *pte = entry;
- trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
- pmap_update_page(pmap, trapframe->badvaddr, entry);
- trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT);
- pa = mips_tlbpfn_to_paddr(entry);
+ *pte |= mips_pg_m_bit();
+ pmap_update_page(pmap, trapframe->badvaddr, *pte);
+ pa = mips_tlbpfn_to_paddr(*pte);
if (!page_is_managed(pa))
panic("trap: utlbmod: unmanaged page");
pmap_set_modified(pa);
@@ -476,22 +461,29 @@ trap(struct trapframe *trapframe)
rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
if (rv == KERN_SUCCESS)
return (trapframe->pc);
- if ((i = td->td_pcb->pcb_onfault) != 0) {
- td->td_pcb->pcb_onfault = 0;
- return (onfault_table[i]);
+ if (td->td_pcb->pcb_onfault != NULL) {
+ pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
+ td->td_pcb->pcb_onfault = NULL;
+ return (pc);
}
goto err;
}
- /*
+
+ /*
* It is an error for the kernel to access user space except
* through the copyin/copyout routines.
*/
- if ((i = td->td_pcb->pcb_onfault) == 0)
+ if (td->td_pcb->pcb_onfault == NULL)
goto err;
+
/* check for fuswintr() or suswintr() getting a page fault */
- if (i == 4) {
- return (onfault_table[i]);
+ /* XXX There must be a nicer way to do this. */
+ if (td->td_pcb->pcb_onfault == fswintrberr) {
+ pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
+ td->td_pcb->pcb_onfault = NULL;
+ return (pc);
}
+
goto dofault;
case T_TLB_LD_MISS + T_USER:
@@ -510,7 +502,7 @@ dofault:
vm = p->p_vmspace;
map = &vm->vm_map;
va = trunc_page((vm_offset_t)trapframe->badvaddr);
- if ((vm_offset_t)trapframe->badvaddr >= VM_MIN_KERNEL_ADDRESS) {
+ if (KERNLAND(trapframe->badvaddr)) {
/*
* Don't allow user-mode faults in kernel
* address space.
@@ -532,9 +524,9 @@ dofault:
--p->p_lock;
PROC_UNLOCK(p);
#ifdef VMFAULT_TRACE
- printf("vm_fault(%p (pmap %p), %x (%x), %x, %d) -> %x at pc %x\n",
- map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, VM_FAULT_NORMAL,
- rv, trapframe->pc);
+ printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
+ map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
+ ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
#endif
if (rv == KERN_SUCCESS) {
@@ -545,9 +537,10 @@ dofault:
}
nogo:
if (!usermode) {
- if ((i = td->td_pcb->pcb_onfault) != 0) {
- td->td_pcb->pcb_onfault = 0;
- return (onfault_table[i]);
+ if (td->td_pcb->pcb_onfault != NULL) {
+ pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
+ td->td_pcb->pcb_onfault = NULL;
+ return (pc);
}
goto err;
}
@@ -609,6 +602,8 @@ dofault:
int nargs, nsaved;
register_t args[8];
+ bzero(args, sizeof args);
+
/*
* note: PCPU_LAZY_INC() can only be used if we can
* afford occassional inaccuracy in the count.
@@ -657,7 +652,6 @@ dofault:
args[0] = locr0->a2;
args[1] = locr0->a3;
nsaved = 2;
- quad_syscall = 1;
break;
default:
@@ -682,7 +676,7 @@ dofault:
nargs = callp->sy_narg;
if (nargs > nsaved) {
- i = copyin((caddr_t)(locr0->sp +
+ i = copyin((caddr_t)(intptr_t)(locr0->sp +
4 * sizeof(register_t)), (caddr_t)&args[nsaved],
(u_int)(nargs - nsaved) * sizeof(register_t));
if (i) {
@@ -773,7 +767,8 @@ dofault:
case T_BREAK + T_USER:
{
- uintptr_t va, instr;
+ intptr_t va;
+ uint32_t instr;
/* compute address of break instruction */
va = trapframe->pc;
@@ -806,7 +801,7 @@ dofault:
case T_IWATCH + T_USER:
case T_DWATCH + T_USER:
{
- uintptr_t va;
+ intptr_t va;
/* compute address of trapped instruction */
va = trapframe->pc;
@@ -820,7 +815,8 @@ dofault:
case T_TRAP + T_USER:
{
- uintptr_t va, instr;
+ intptr_t va;
+ uint32_t instr;
struct trapframe *locr0 = td->td_frame;
/* compute address of trap instruction */
@@ -842,6 +838,7 @@ dofault:
}
case T_RES_INST + T_USER:
+ log_illegal_instruction("RES_INST", trapframe);
i = SIGILL;
addr = trapframe->pc;
break;
@@ -856,11 +853,13 @@ dofault:
#if !defined(CPU_HAVEFPU)
/* FP (COP1) instruction */
if ((trapframe->cause & CR_COP_ERR) == 0x10000000) {
+ log_illegal_instruction("COP1_UNUSABLE", trapframe);
i = SIGILL;
break;
}
#endif
if ((trapframe->cause & CR_COP_ERR) != 0x10000000) {
+ log_illegal_instruction("COPn_UNUSABLE", trapframe);
i = SIGILL; /* only FPU instructions allowed */
break;
}
@@ -875,13 +874,13 @@ dofault:
#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
trapDump("fpintr");
#else
- printf("FPU Trap: PC %x CR %x SR %x\n",
- trapframe->pc, trapframe->cause, trapframe->sr);
+ printf("FPU Trap: PC %#jx CR %x SR %x\n",
+ (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
goto err;
#endif
case T_FPE + T_USER:
- MachFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
+ MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
goto out;
case T_OVFLOW + T_USER:
@@ -892,8 +891,8 @@ dofault:
case T_ADDR_ERR_LD: /* misaligned access */
case T_ADDR_ERR_ST: /* misaligned access */
#ifdef TRAP_DEBUG
- printf("+++ ADDR_ERR: type = %d, badvaddr = %x\n", type,
- trapframe->badvaddr);
+ printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
+ (intmax_t)trapframe->badvaddr);
#endif
/* Only allow emulation on a user address */
if (allow_unaligned_acc &&
@@ -925,10 +924,12 @@ dofault:
/* FALLTHROUGH */
case T_BUS_ERR_LD_ST: /* BERR asserted to cpu */
- if ((i = td->td_pcb->pcb_onfault) != 0) {
- td->td_pcb->pcb_onfault = 0;
- return (onfault_table[i]);
+ if (td->td_pcb->pcb_onfault != NULL) {
+ pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
+ td->td_pcb->pcb_onfault = NULL;
+ return (pc);
}
+
/* FALLTHROUGH */
default:
@@ -950,9 +951,9 @@ err:
printf("kernel mode)\n");
#ifdef TRAP_DEBUG
- printf("badvaddr = %x, pc = %x, ra = %x, sr = 0x%x\n",
- trapframe->badvaddr, trapframe->pc, trapframe->ra,
- trapframe->sr);
+ printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
+ (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
+ (intmax_t)trapframe->sr);
#endif
#ifdef KDB
@@ -985,9 +986,10 @@ out:
void
trapDump(char *msg)
{
- int i, s;
+ register_t s;
+ int i;
- s = disableintr();
+ s = intr_disable();
printf("trapDump(%s)\n", msg);
for (i = 0; i < TRAPSIZE; i++) {
if (trp == trapdebug) {
@@ -999,15 +1001,14 @@ trapDump(char *msg)
if (trp->cause == 0)
break;
- printf("%s: ADR %x PC %x CR %x SR %x\n",
+ printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
trap_type[(trp->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT],
- trp->vadr, trp->pc, trp->cause, trp->status);
+ (intmax_t)trp->vadr, (intmax_t)trp->pc, (intmax_t)trp->cause, (intmax_t)trp->status);
- printf(" RA %x SP %x code %d\n", trp->ra, trp->sp, trp->code);
+ printf(" RA %jx SP %jx code %d\n", (intmax_t)trp->ra, (intmax_t)trp->sp, (int)trp->code);
}
- restoreintr(s);
+ intr_restore(s);
}
-
#endif
@@ -1168,39 +1169,39 @@ static void
log_frame_dump(struct trapframe *frame)
{
log(LOG_ERR, "Trapframe Register Dump:\n");
- log(LOG_ERR, "\tzero: %p\tat: %p\tv0: %p\tv1: %p\n",
- (void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1);
+ log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
+ (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
- log(LOG_ERR, "\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n",
- (void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3);
+ log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
+ (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
- log(LOG_ERR, "\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n",
- (void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3);
+ log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
+ (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
- log(LOG_ERR, "\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n",
- (void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7);
+ log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
+ (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
- log(LOG_ERR, "\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n",
- (void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1);
+ log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
+ (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
- log(LOG_ERR, "\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n",
- (void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5);
+ log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
+ (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
- log(LOG_ERR, "\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n",
- (void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1);
+ log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
+ (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
- log(LOG_ERR, "\tgp: %p\tsp: %p\ts8: %p\tra: %p\n",
- (void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra);
+ log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
+ (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
- log(LOG_ERR, "\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n",
- (void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr);
+ log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
+ (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
#ifdef IC_REG
- log(LOG_ERR, "\tcause: %p\tpc: %p\tic: %p\n",
- (void *)frame->cause, (void *)frame->pc, (void *)frame->ic);
+ log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
+ (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
#else
- log(LOG_ERR, "\tcause: %p\tpc: %p\n",
- (void *)frame->cause, (void *)frame->pc);
+ log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
+ (intmax_t)frame->cause, (intmax_t)frame->pc);
#endif
}
@@ -1209,39 +1210,39 @@ static void
trap_frame_dump(struct trapframe *frame)
{
printf("Trapframe Register Dump:\n");
- printf("\tzero: %p\tat: %p\tv0: %p\tv1: %p\n",
- (void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1);
+ printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
+ (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
- printf("\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n",
- (void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3);
+ printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
+ (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
- printf("\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n",
- (void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3);
+ printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
+ (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
- printf("\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n",
- (void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7);
+ printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
+ (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
- printf("\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n",
- (void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1);
+ printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
+ (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
- printf("\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n",
- (void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5);
+ printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
+ (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
- printf("\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n",
- (void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1);
+ printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
+ (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
- printf("\tgp: %p\tsp: %p\ts8: %p\tra: %p\n",
- (void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra);
+ printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
+ (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
- printf("\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n",
- (void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr);
+ printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
+ (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
#ifdef IC_REG
- printf("\tcause: %p\tpc: %p\tic: %p\n",
- (void *)frame->cause, (void *)frame->pc, (void *)frame->ic);
+ printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
+ (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
#else
- printf("\tcause: %p\tpc: %p\n",
- (void *)frame->cause, (void *)frame->pc);
+ printf("\tcause: %#jx\tpc: %#jx\n",
+ (intmax_t)frame->cause, (intmax_t)frame->pc);
#endif
}
@@ -1255,7 +1256,7 @@ get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
pd_entry_t *pdep;
struct proc *p = curproc;
- pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[va >> SEGSHIFT]));
+ pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
if (*pdep)
ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
else
@@ -1265,6 +1266,50 @@ get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
*ptepp = ptep;
}
+static void
+log_illegal_instruction(const char *msg, struct trapframe *frame)
+{
+ pt_entry_t *ptep;
+ pd_entry_t *pdep;
+ unsigned int *addr;
+ struct proc *p = curproc;
+ register_t pc;
+
+#ifdef SMP
+ printf("cpuid = %d\n", PCPU_GET(cpuid));
+#endif
+ pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
+ log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx ra %#jx\n",
+ msg, p->p_pid, p->p_comm,
+ p->p_ucred ? p->p_ucred->cr_uid : -1,
+ (intmax_t)pc,
+ (intmax_t)frame->ra);
+
+ /* log registers in trap frame */
+ log_frame_dump(frame);
+
+ get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
+
+ /*
+ * Dump a few words around faulting instruction, if the addres is
+ * valid.
+ */
+ if (!(pc & 3) &&
+ useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
+ /* dump page table entry for faulting instruction */
+ log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
+ (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
+
+ addr = (unsigned int *)(intptr_t)pc;
+ log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
+ addr);
+ log(LOG_ERR, "%08x %08x %08x %08x\n",
+ addr[0], addr[1], addr[2], addr[3]);
+ } else {
+ log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
+ (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
+ }
+}
static void
log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
@@ -1296,12 +1341,12 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
}
pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
- log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %p got a %s fault at %p\n",
+ log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx got a %s fault at %#jx\n",
msg, p->p_pid, p->p_comm,
p->p_ucred ? p->p_ucred->cr_uid : -1,
- (void *)pc,
+ (intmax_t)pc,
read_or_write,
- (void *)frame->badvaddr);
+ (intmax_t)frame->badvaddr);
/* log registers in trap frame */
log_frame_dump(frame);
@@ -1314,21 +1359,24 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
*/
if (!(pc & 3) && (pc != frame->badvaddr) &&
(trap_type != T_BUS_ERR_IFETCH) &&
- useracc((caddr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
+ useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
/* dump page table entry for faulting instruction */
- log(LOG_ERR, "Page table info for pc address %p: pde = %p, pte = 0x%lx\n",
- (void *)pc, *pdep, ptep ? *ptep : 0);
+ log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
+ (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
- addr = (unsigned int *)pc;
+ addr = (unsigned int *)(intptr_t)pc;
log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
addr);
log(LOG_ERR, "%08x %08x %08x %08x\n",
addr[0], addr[1], addr[2], addr[3]);
} else {
- log(LOG_ERR, "pc address %p is inaccessible, pde = 0x%p, pte = 0x%lx\n",
- (void *)pc, *pdep, ptep ? *ptep : 0);
+ log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
+ (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
}
- /* panic("Bad trap");*/
+
+ get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
+ log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#x\n",
+ (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
}
@@ -1339,7 +1387,7 @@ static int
mips_unaligned_load_store(struct trapframe *frame, register_t addr, register_t pc)
{
register_t *reg = (register_t *) frame;
- u_int32_t inst = *((u_int32_t *) pc);
+ u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
u_int32_t value_msb, value;
int access_type = 0;
@@ -1435,9 +1483,9 @@ emulate_unaligned_access(struct trapframe *frame)
else
frame->pc += 4;
- log(LOG_INFO, "Unaligned %s: pc=%p, badvaddr=%p\n",
- access_name[access_type - 1], (void *)pc,
- (void *)frame->badvaddr);
+ log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
+ access_name[access_type - 1], (intmax_t)pc,
+ (intmax_t)frame->badvaddr);
}
}
return access_type;
diff --git a/sys/mips/mips/uio_machdep.c b/sys/mips/mips/uio_machdep.c
index 0872b4d..10deff6 100644
--- a/sys/mips/mips/uio_machdep.c
+++ b/sys/mips/mips/uio_machdep.c
@@ -32,8 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
- * from: src/sys/i386/i386/uio_machdep.c,v 1.8 2005/02/13 23:09:36 alc
+ * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
*/
#include <sys/cdefs.h>
@@ -44,17 +43,18 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
-#include <sys/sched.h>
#include <sys/sf_buf.h>
#include <sys/systm.h>
#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include <vm/vm_param.h>
/*
- * Implement uiomove(9) from physical memory using sf_bufs to reduce
- * the creation and destruction of ephemeral mappings.
+ * Implement uiomove(9) from physical memory using a combination
+ * of the direct mapping and sf_bufs to reduce the creation and
+ * destruction of ephemeral mappings.
*/
int
uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
@@ -64,6 +64,8 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
struct iovec *iov;
void *cp;
vm_offset_t page_offset;
+ vm_paddr_t pa;
+ vm_page_t m;
size_t cnt;
int error = 0;
int save = 0;
@@ -85,10 +87,16 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
if (cnt > n)
cnt = n;
page_offset = offset & PAGE_MASK;
- cnt = min(cnt, PAGE_SIZE - page_offset);
- sched_pin();
- sf = sf_buf_alloc(ma[offset >> PAGE_SHIFT], SFB_CPUPRIVATE);
- cp = (char *)sf_buf_kva(sf) + page_offset;
+ cnt = ulmin(cnt, PAGE_SIZE - page_offset);
+ m = ma[offset >> PAGE_SHIFT];
+ pa = VM_PAGE_TO_PHYS(m);
+ if (pa < MIPS_KSEG0_LARGEST_PHYS) {
+ cp = (char *)MIPS_PHYS_TO_KSEG0(pa);
+ sf = NULL;
+ } else {
+ sf = sf_buf_alloc(m, 0);
+ cp = (char *)sf_buf_kva(sf) + page_offset;
+ }
switch (uio->uio_segflg) {
case UIO_USERSPACE:
if (ticks - PCPU_GET(switchticks) >= hogticks)
@@ -98,8 +106,8 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
else
error = copyin(iov->iov_base, cp, cnt);
if (error) {
- sf_buf_free(sf);
- sched_unpin();
+ if (sf != NULL)
+ sf_buf_free(sf);
goto out;
}
break;
@@ -112,8 +120,8 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
case UIO_NOCOPY:
break;
}
- sf_buf_free(sf);
- sched_unpin();
+ if (sf != NULL)
+ sf_buf_free(sf);
iov->iov_base = (char *)iov->iov_base + cnt;
iov->iov_len -= cnt;
uio->uio_resid -= cnt;
diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c
index f76dc4d..2024303 100644
--- a/sys/mips/mips/vm_machdep.c
+++ b/sys/mips/mips/vm_machdep.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/unistd.h>
+#include <machine/asm.h>
#include <machine/cache.h>
#include <machine/clock.h>
#include <machine/cpu.h>
@@ -63,12 +64,15 @@ __FBSDID("$FreeBSD$");
#include <machine/pcb.h>
#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <sys/lock.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
#include <vm/vm_map.h>
-#include <vm/vm_extern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_param.h>
+#include <vm/uma.h>
+#include <vm/uma_int.h>
#include <sys/user.h>
#include <sys/mbuf.h>
@@ -81,26 +85,18 @@ __FBSDID("$FreeBSD$");
static void sf_buf_init(void *arg);
SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
-LIST_HEAD(sf_head, sf_buf);
-
-
/*
- * A hash table of active sendfile(2) buffers
+ * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the
+ * sf_freelist head with the sf_lock mutex.
*/
-static struct sf_head *sf_buf_active;
-static u_long sf_buf_hashmask;
-
-#define SF_BUF_HASH(m) (((m) - vm_page_array) & sf_buf_hashmask)
+static struct {
+ SLIST_HEAD(, sf_buf) sf_head;
+ struct mtx sf_lock;
+} sf_freelist;
-static TAILQ_HEAD(, sf_buf) sf_buf_freelist;
static u_int sf_buf_alloc_want;
/*
- * A lock used to synchronize access to the hash table and free list
- */
-static struct mtx sf_buf_lock;
-
-/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb, set up the stack so that the child
* ready to run and return to user mode.
@@ -148,7 +144,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2,
pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline;
/* Make sp 64-bit aligned */
pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td2->td_pcb &
- ~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE);
+ ~(sizeof(__int64_t) - 1)) - CALLFRAME_SIZ);
pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return;
pcb2->pcb_context[PCB_REG_S1] = (register_t)td2;
pcb2->pcb_context[PCB_REG_S2] = (register_t)td2->td_frame;
@@ -221,13 +217,9 @@ cpu_thread_swapin(struct thread *td)
* part of the thread struct so cpu_switch() can quickly map in
* the pcb struct and kernel stack.
*/
- if (!(pte = pmap_segmap(kernel_pmap, td->td_md.md_realstack)))
- panic("cpu_thread_swapin: invalid segmap");
- pte += ((vm_offset_t)td->td_md.md_realstack >> PGSHIFT) & (NPTEPG - 1);
-
- for (i = 0; i < KSTACK_PAGES - 1; i++) {
+ for (i = 0; i < KSTACK_PAGES; i++) {
+ pte = pmap_pte(kernel_pmap, td->td_kstack + i * PAGE_SIZE);
td->td_md.md_upte[i] = *pte & ~(PTE_RO|PTE_WIRED);
- pte++;
}
}
@@ -242,22 +234,14 @@ cpu_thread_alloc(struct thread *td)
pt_entry_t *pte;
int i;
- if(td->td_kstack & (1 << PAGE_SHIFT))
- td->td_md.md_realstack = td->td_kstack + PAGE_SIZE;
- else
- td->td_md.md_realstack = td->td_kstack;
-
- td->td_pcb = (struct pcb *)(td->td_md.md_realstack +
- (td->td_kstack_pages - 1) * PAGE_SIZE) - 1;
+ KASSERT((td->td_kstack & (1 << PAGE_SHIFT)) == 0, ("kernel stack must be aligned."));
+ td->td_pcb = (struct pcb *)(td->td_kstack +
+ td->td_kstack_pages * PAGE_SIZE) - 1;
td->td_frame = &td->td_pcb->pcb_regs;
- if (!(pte = pmap_segmap(kernel_pmap, td->td_md.md_realstack)))
- panic("cpu_thread_alloc: invalid segmap");
- pte += ((vm_offset_t)td->td_md.md_realstack >> PGSHIFT) & (NPTEPG - 1);
-
- for (i = 0; i < KSTACK_PAGES - 1; i++) {
+ for (i = 0; i < KSTACK_PAGES; i++) {
+ pte = pmap_pte(kernel_pmap, td->td_kstack + i * PAGE_SIZE);
td->td_md.md_upte[i] = *pte & ~(PTE_RO|PTE_WIRED);
- pte++;
}
}
@@ -355,7 +339,7 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline;
/* Make sp 64-bit aligned */
pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td->td_pcb &
- ~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE);
+ ~(sizeof(__int64_t) - 1)) - CALLFRAME_SIZ);
pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return;
pcb2->pcb_context[PCB_REG_S1] = (register_t)td;
pcb2->pcb_context[PCB_REG_S2] = (register_t)td->td_frame;
@@ -402,7 +386,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
* in ``See MIPS Run'' by D. Sweetman, p. 269
* align stack */
sp = ((register_t)(stack->ss_sp + stack->ss_size) & ~0x7) -
- STAND_FRAME_SIZE;
+ CALLFRAME_SIZ;
/*
* Set the trap frame to point at the beginning of the uts
@@ -471,56 +455,34 @@ sf_buf_init(void *arg)
nsfbufs = NSFBUFS;
TUNABLE_INT_FETCH("kern.ipc.nsfbufs", &nsfbufs);
- sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask);
- TAILQ_INIT(&sf_buf_freelist);
+ mtx_init(&sf_freelist.sf_lock, "sf_bufs list lock", NULL, MTX_DEF);
+ SLIST_INIT(&sf_freelist.sf_head);
sf_base = kmem_alloc_nofault(kernel_map, nsfbufs * PAGE_SIZE);
sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP,
M_NOWAIT | M_ZERO);
for (i = 0; i < nsfbufs; i++) {
sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
- TAILQ_INSERT_TAIL(&sf_buf_freelist, &sf_bufs[i], free_entry);
+ SLIST_INSERT_HEAD(&sf_freelist.sf_head, &sf_bufs[i], free_list);
}
sf_buf_alloc_want = 0;
- mtx_init(&sf_buf_lock, "sf_buf", NULL, MTX_DEF);
}
/*
- * Allocate an sf_buf for the given vm_page. On this machine, however, there
- * is no sf_buf object. Instead, an opaque pointer to the given vm_page is
- * returned.
+ * Get an sf_buf from the freelist. Will block if none are available.
*/
struct sf_buf *
sf_buf_alloc(struct vm_page *m, int flags)
{
- struct sf_head *hash_list;
struct sf_buf *sf;
int error;
- hash_list = &sf_buf_active[SF_BUF_HASH(m)];
- mtx_lock(&sf_buf_lock);
- LIST_FOREACH(sf, hash_list, list_entry) {
- if (sf->m == m) {
- sf->ref_count++;
- if (sf->ref_count == 1) {
- TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
- nsfbufsused++;
- nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
- }
- /*
- * Flush all mappings in order to have up to date
- * physycal memory
- */
- pmap_flush_pvcache(sf->m);
- mips_dcache_inv_range(sf->kva, PAGE_SIZE);
- goto done;
- }
- }
- while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
+ mtx_lock(&sf_freelist.sf_lock);
+ while ((sf = SLIST_FIRST(&sf_freelist.sf_head)) == NULL) {
if (flags & SFB_NOWAIT)
- goto done;
+ break;
sf_buf_alloc_want++;
mbstat.sf_allocwait++;
- error = msleep(&sf_buf_freelist, &sf_buf_lock,
+ error = msleep(&sf_freelist, &sf_freelist.sf_lock,
(flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
sf_buf_alloc_want--;
@@ -528,42 +490,33 @@ sf_buf_alloc(struct vm_page *m, int flags)
* If we got a signal, don't risk going back to sleep.
*/
if (error)
- goto done;
+ break;
+ }
+ if (sf != NULL) {
+ SLIST_REMOVE_HEAD(&sf_freelist.sf_head, free_list);
+ sf->m = m;
+ nsfbufsused++;
+ nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
+ pmap_qenter(sf->kva, &sf->m, 1);
}
- TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
- if (sf->m != NULL)
- LIST_REMOVE(sf, list_entry);
- LIST_INSERT_HEAD(hash_list, sf, list_entry);
- sf->ref_count = 1;
- sf->m = m;
- nsfbufsused++;
- nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
- pmap_qenter(sf->kva, &sf->m, 1);
-done:
- mtx_unlock(&sf_buf_lock);
+ mtx_unlock(&sf_freelist.sf_lock);
return (sf);
}
/*
- * Free the sf_buf. In fact, do nothing because there are no resources
- * associated with the sf_buf.
+ * Release resources back to the system.
*/
void
sf_buf_free(struct sf_buf *sf)
{
- mtx_lock(&sf_buf_lock);
- sf->ref_count--;
- /*
- * Make sure all changes in KVA end up in physical memory
- */
- mips_dcache_wbinv_range(sf->kva, PAGE_SIZE);
- if (sf->ref_count == 0) {
- TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
- nsfbufsused--;
- if (sf_buf_alloc_want > 0)
- wakeup_one(&sf_buf_freelist);
- }
- mtx_unlock(&sf_buf_lock);
+
+ pmap_qremove(sf->kva, 1);
+ mtx_lock(&sf_freelist.sf_lock);
+ SLIST_INSERT_HEAD(&sf_freelist.sf_head, sf, free_list);
+ nsfbufsused--;
+ if (sf_buf_alloc_want > 0)
+ wakeup_one(&sf_freelist);
+ mtx_unlock(&sf_freelist.sf_lock);
}
/*
@@ -682,7 +635,7 @@ DB_SHOW_COMMAND(pcb, ddb_dump_pcb)
DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_GP);
DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_PC);
- db_printf("PCB onfault = %d\n", pcb->pcb_onfault);
+ db_printf("PCB onfault = %p\n", pcb->pcb_onfault);
db_printf("md_saved_intr = 0x%0lx\n", (long)td->td_md.md_saved_intr);
db_printf("md_spinlock_count = %d\n", td->td_md.md_spinlock_count);
diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c
index 6964522..c123edf 100644
--- a/sys/mips/rmi/clock.c
+++ b/sys/mips/rmi/clock.c
@@ -116,11 +116,11 @@ count_compare_clockhandler(struct trapframe *tf)
cycles += XLR_CPU_HZ / hz;
mips_wr_compare(cycles);
- hardclock_cpu(USERMODE(tf->sr));
+ hardclock_cpu(TRAPF_USERMODE(tf));
if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) {
- statclock(USERMODE(tf->sr));
+ statclock(TRAPF_USERMODE(tf));
if (profprocs != 0) {
- profclock(USERMODE(tf->sr), tf->pc);
+ profclock(TRAPF_USERMODE(tf), tf->pc);
}
count_scale_factor[cpu] = 0;
}
@@ -148,11 +148,11 @@ pic_hardclockhandler(struct trapframe *tf)
printf("Clock tick foo at %ld\n", clock_tick_foo);
}
*/
- hardclock(USERMODE(tf->sr), tf->pc);
+ hardclock(TRAPF_USERMODE(tf), tf->pc);
if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) {
- statclock(USERMODE(tf->sr));
+ statclock(TRAPF_USERMODE(tf));
if (profprocs != 0) {
- profclock(USERMODE(tf->sr), tf->pc);
+ profclock(TRAPF_USERMODE(tf), tf->pc);
}
scale_factor = 0;
}
diff --git a/sys/mips/rmi/debug.h b/sys/mips/rmi/debug.h
index b5ec144..b5ec144 100755..100644
--- a/sys/mips/rmi/debug.h
+++ b/sys/mips/rmi/debug.h
diff --git a/sys/mips/rmi/dev/sec/desc.h b/sys/mips/rmi/dev/sec/desc.h
index 5757e13..5757e13 100755..100644
--- a/sys/mips/rmi/dev/sec/desc.h
+++ b/sys/mips/rmi/dev/sec/desc.h
diff --git a/sys/mips/rmi/ehcireg.h b/sys/mips/rmi/ehcireg.h
index 71af999..f54528b 100644
--- a/sys/mips/rmi/ehcireg.h
+++ b/sys/mips/rmi/ehcireg.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/mips/rmi/ehcivar.h b/sys/mips/rmi/ehcivar.h
index 09829d9..72a12f1 100644
--- a/sys/mips/rmi/ehcivar.h
+++ b/sys/mips/rmi/ehcivar.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h
index 43be638..43be638 100755..100644
--- a/sys/mips/rmi/msgring.h
+++ b/sys/mips/rmi/msgring.h
diff --git a/sys/mips/rmi/shared_structs.h b/sys/mips/rmi/shared_structs.h
index 6e5ecd4..6e5ecd4 100755..100644
--- a/sys/mips/rmi/shared_structs.h
+++ b/sys/mips/rmi/shared_structs.h
diff --git a/sys/mips/rmi/shared_structs_func.h b/sys/mips/rmi/shared_structs_func.h
index be96414..be96414 100755..100644
--- a/sys/mips/rmi/shared_structs_func.h
+++ b/sys/mips/rmi/shared_structs_func.h
diff --git a/sys/mips/rmi/shared_structs_offsets.h b/sys/mips/rmi/shared_structs_offsets.h
index 605c735..605c735 100755..100644
--- a/sys/mips/rmi/shared_structs_offsets.h
+++ b/sys/mips/rmi/shared_structs_offsets.h
diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c
index b90f317..73d88bb 100644
--- a/sys/mips/rmi/xls_ehci.c
+++ b/sys/mips/rmi/xls_ehci.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/mips/sibyte/sb_asm.S b/sys/mips/sibyte/sb_asm.S
index a822d79..312d3a5 100644
--- a/sys/mips/sibyte/sb_asm.S
+++ b/sys/mips/sibyte/sb_asm.S
@@ -28,61 +28,11 @@
#include <machine/asm.h>
#include <machine/cpuregs.h>
-#include <machine/endian.h>
-
-/*
- * We compile a 32-bit kernel to run on the SB-1 processor which is a 64-bit
- * processor. It has some registers that must be accessed using 64-bit load
- * and store instructions.
- *
- * So we have to resort to assembly because the compiler does not emit the
- * 'ld' and 'sd' instructions since it thinks that it is compiling for a
- * 32-bit mips processor.
- */
.set mips64
.set noat
.set noreorder
-/*
- * Parameters: uint32_t ptr
- * Return value: *(uint64_t *)ptr
- */
-LEAF(sb_load64)
- ld v1, 0(a0) /* result = *(uint64_t *)ptr */
- move v0, v1
-#if _BYTE_ORDER == _BIG_ENDIAN
- dsll32 v1, v1, 0
- dsrl32 v1, v1, 0 /* v1 = lower_uint32(result) */
- jr ra
- dsrl32 v0, v0, 0 /* v0 = upper_uint32(result) */
-#else
- dsll32 v0, v0, 0
- dsrl32 v0, v0, 0 /* v0 = lower_uint32(result) */
- jr ra
- dsrl32 v1, v1, 0 /* v1 = upper_uint32(result) */
-#endif
-END(sb_load64)
-
-/*
- * Parameters: uint32_t ptr, uint64_t val
- * Return value: void
- */
-LEAF(sb_store64)
-#if _BYTE_ORDER == _BIG_ENDIAN
- dsll32 a2, a2, 0 /* a2 = upper_uint32(val) */
- dsll32 a3, a3, 0 /* a3 = lower_uint32(val) */
- dsrl32 a3, a3, 0
-#else
- dsll32 a3, a3, 0 /* a3 = upper_uint32(val) */
- dsll32 a2, a2, 0 /* a2 = lower_uint32(val) */
- dsrl32 a2, a2, 0
-#endif
- or t0, a2, a3
- jr ra
- sd t0, 0(a0)
-END(sb_store64)
-
#ifdef SMP
/*
* This function must be implemented in assembly because it is called early
diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c
index c6043b8..559bf74 100644
--- a/sys/mips/sibyte/sb_machdep.c
+++ b/sys/mips/sibyte/sb_machdep.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/user.h>
+#include <sys/timetc.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -157,6 +158,17 @@ mips_init(void)
TUNABLE_INT_FETCH("hw.physmem", &tmp);
maxmem = (uint64_t)tmp * 1024;
+ /*
+ * XXX
+ * If we used vm_paddr_t consistently in pmap, etc., we could
+ * use 64-bit page numbers on !n64 systems, too, like i386
+ * does with PAE.
+ */
+#if !defined(__mips_n64)
+ if (maxmem == 0 || maxmem > 0xffffffff)
+ maxmem = 0xffffffff;
+#endif
+
#ifdef CFE
/*
* Query DRAM memory map from CFE.
@@ -220,6 +232,13 @@ mips_init(void)
mips_cpu_init();
/*
+ * Sibyte has a L1 data cache coherent with DMA. This includes
+ * on-chip network interfaces as well as PCI/HyperTransport bus
+ * masters.
+ */
+ cpuinfo.cache_coherent_dma = TRUE;
+
+ /*
* XXX
* The kernel is running in 32-bit mode but the CFE is running in
* 64-bit mode. So the SR_KX bit in the status register is turned
@@ -357,6 +376,32 @@ platform_start_ap(int cpuid)
}
#endif /* SMP */
+static u_int
+sb_get_timecount(struct timecounter *tc)
+{
+
+ return ((u_int)sb_zbbus_cycle_count());
+}
+
+static void
+sb_timecounter_init(void)
+{
+ static struct timecounter sb_timecounter = {
+ sb_get_timecount,
+ NULL,
+ ~0u,
+ 0,
+ "sibyte_zbbus_counter",
+ 2000
+ };
+
+ /*
+ * The ZBbus cycle counter runs at half the cpu frequency.
+ */
+ sb_timecounter.tc_frequency = sb_cpu_speed() / 2;
+ platform_timecounter = &sb_timecounter;
+}
+
void
platform_start(__register_t a0, __register_t a1, __register_t a2,
__register_t a3)
@@ -371,6 +416,7 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
mips_postboot_fixup();
sb_intr_init(0);
+ sb_timecounter_init();
/* Initialize pcpu stuff */
mips_pcpu0_init();
@@ -393,4 +439,6 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
mips_init();
mips_timer_init_params(sb_cpu_speed(), 0);
+
+ set_cputicker(sb_zbbus_cycle_count, sb_cpu_speed() / 2, 1);
}
diff --git a/sys/mips/sibyte/sb_scd.c b/sys/mips/sibyte/sb_scd.c
index 007e149..bfaa8d4 100644
--- a/sys/mips/sibyte/sb_scd.c
+++ b/sys/mips/sibyte/sb_scd.c
@@ -38,8 +38,15 @@ __FBSDID("$FreeBSD$");
#include "sb_scd.h"
-extern void sb_store64(uint32_t addr, uint64_t val);
-extern uint64_t sb_load64(uint32_t addr);
+/*
+ * We compile a 32-bit kernel to run on the SB-1 processor which is a 64-bit
+ * processor. It has some registers that must be accessed using 64-bit load
+ * and store instructions.
+ *
+ * We use the mips_ld() and mips_sd() functions to do this for us.
+ */
+#define sb_store64(addr, val) mips3_sd((uint64_t *)(addr), (val))
+#define sb_load64(addr) mips3_ld((uint64_t *)(addr))
/*
* System Control and Debug (SCD) unit on the Sibyte ZBbus.
@@ -56,6 +63,8 @@ extern uint64_t sb_load64(uint32_t addr);
#define SYSCFG_ADDR MIPS_PHYS_TO_KSEG1(0x10020008)
#define SYSCFG_PLLDIV(x) GET_VAL_64((x), 7, 5)
+#define ZBBUS_CYCLE_COUNT_ADDR MIPS_PHYS_TO_KSEG1(0x10030000)
+
#define INTSRC_MASK_ADDR(cpu) \
(MIPS_PHYS_TO_KSEG1(0x10020028) | ((cpu) << 13))
@@ -83,6 +92,13 @@ sb_write_syscfg(uint64_t val)
}
uint64_t
+sb_zbbus_cycle_count(void)
+{
+
+ return (sb_load64(ZBBUS_CYCLE_COUNT_ADDR));
+}
+
+uint64_t
sb_cpu_speed(void)
{
int plldiv;
diff --git a/sys/mips/sibyte/sb_scd.h b/sys/mips/sibyte/sb_scd.h
index 03d2681..f8bb6e4 100644
--- a/sys/mips/sibyte/sb_scd.h
+++ b/sys/mips/sibyte/sb_scd.h
@@ -31,6 +31,7 @@
#define NUM_INTSRC 64 /* total number of interrupt sources */
+uint64_t sb_zbbus_cycle_count(void);
uint64_t sb_cpu_speed(void);
void sb_system_reset(void);
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 0934772..83c7757 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -20,6 +20,7 @@ SUBDIR= ${_3dfx} \
aio \
alc \
ale \
+ alq \
${_amd} \
${_amdsbwd} \
${_amdtemp} \
@@ -66,7 +67,7 @@ SUBDIR= ${_3dfx} \
${_cryptodev} \
${_cs} \
${_ctau} \
- cxgb \
+ ${_cxgb} \
${_cyclic} \
dc \
dcons \
@@ -251,6 +252,7 @@ SUBDIR= ${_3dfx} \
sdhci \
sem \
sf \
+ sge \
siba_bwn \
siis \
sis \
@@ -268,12 +270,12 @@ SUBDIR= ${_3dfx} \
stge \
${_streams} \
${_svr4} \
- sym \
+ ${_sym} \
${_syscons} \
sysvipc \
ti \
tl \
- ${_tmpfs} \
+ tmpfs \
trm \
${_twa} \
twe \
@@ -312,11 +314,20 @@ SUBDIR= ${_3dfx} \
${_zfs} \
zlib \
-.if ${MACHINE_ARCH} != "powerpc"
+.if ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "arm" && \
+ ${MACHINE_ARCH} != "mips"
_syscons= syscons
_vpo= vpo
.endif
+.if ${MACHINE_ARCH} != "arm" && ${MACHINE_ARCH} != "mips"
+# no BUS_SPACE_UNSPECIFIED
+# No barrier instruction support (specific to this driver)
+_sym= sym
+# intr_disable() is a macro, causes problems
+_cxgb= cxgb
+.endif
+
.if ${MK_CRYPT} != "no" || defined(ALL_MODULES)
.if exists(${.CURDIR}/../opencrypto)
_crypto= crypto
@@ -416,7 +427,6 @@ _sppp= sppp
_stg= stg
_streams= streams
_svr4= svr4
-_tmpfs= tmpfs
_wi= wi
_xe= xe
.if ${MK_ZFS} != "no" || defined(ALL_MODULES)
@@ -554,7 +564,6 @@ _sound= sound
_speaker= speaker
_splash= splash
_sppp= sppp
-_tmpfs= tmpfs
_twa= twa
_vesa= vesa
_x86bios= x86bios
@@ -567,10 +576,7 @@ _zfs= zfs
.endif
.if ${MACHINE_ARCH} == "ia64"
-# Modules not enabled on ia64 (as compared to i386) include:
-# aac acpi aout apm atspeaker drm ibcs2 linprocfs linux ncv
-# nsp s3 sbni stg vesa
-# acpi is not enabled because it is broken as a module on ia64
+_aac= aac
_aic= aic
_an= an
_arcnet= arcnet
@@ -583,12 +589,17 @@ _cm= cm
_cmx= cmx
_coff= coff
_cpufreq= cpufreq
+_dpt= dpt
_em= em
_ep= ep
+_et= et
_exca= exca
_fe= fe
+_hptiop= hptiop
+_ida= ida
_igb= igb
_iir= iir
+_ips= ips
_mly= mly
_pccard= pccard
_scsi_low= scsi_low
@@ -597,6 +608,7 @@ _sound= sound
_splash= splash
_sppp= sppp
_streams= streams
+_twa= twa
_wi= wi
_xe= xe
.endif
diff --git a/sys/modules/acpi/acpi/Makefile b/sys/modules/acpi/acpi/Makefile
index 992c59c..6fa36ff 100644
--- a/sys/modules/acpi/acpi/Makefile
+++ b/sys/modules/acpi/acpi/Makefile
@@ -1,11 +1,11 @@
# $FreeBSD$
-.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64"
-.error "ACPI can only be compiled into the kernel on the amd64 and ia64 platforms"
+.if ${MACHINE_ARCH} == "ia64"
+.error "ACPI can only be compiled into the kernel on the ia64 platform"
.endif
-.if ${MACHINE} != "i386"
-.error "The ACPI module is only for i386"
+.if ${MACHINE} != "amd64" && ${MACHINE} != "i386"
+.error "The ACPI module is only for amd64 and i386"
.endif
.PATH: ${.CURDIR}/../../../contrib/dev/acpica/debugger \
@@ -35,10 +35,10 @@ SRCS+= dsfield.c dsinit.c dsmethod.c dsmthdat.c dsobject.c dsopcode.c
SRCS+= dsutils.c dswexec.c dswload.c dswscope.c dswstate.c
SRCS+= evevent.c evgpe.c evgpeblk.c evmisc.c evregion.c evrgnini.c evsci.c
SRCS+= evxface.c evxfevnt.c evxfregn.c
-SRCS+= exconfig.c exconvrt.c excreate.c exdump.c exfield.c exfldio.c exmisc.c
-SRCS+= exmutex.c exnames.c exoparg1.c exoparg2.c exoparg3.c exoparg6.c
-SRCS+= exprep.c exregion.c exresnte.c exresolv.c exresop.c exstore.c
-SRCS+= exstoren.c exstorob.c exsystem.c exutils.c
+SRCS+= exconfig.c exconvrt.c excreate.c exdebug.c exdump.c exfield.c
+SRCS+= exfldio.c exmisc.c exmutex.c exnames.c exoparg1.c exoparg2.c
+SRCS+= exoparg3.c exoparg6.c exprep.c exregion.c exresnte.c exresolv.c
+SRCS+= exresop.c exstore.c exstoren.c exstorob.c exsystem.c exutils.c
SRCS+= hwacpi.c hwgpe.c hwregs.c hwsleep.c hwtimer.c hwvalid.c hwxface.c
SRCS+= nsaccess.c nsalloc.c nsdump.c nseval.c nsinit.c nsload.c nsnames.c
SRCS+= nsobject.c nsparse.c nspredef.c nsrepair.c nsrepair2.c nssearch.c
@@ -97,9 +97,13 @@ opt_ddb.h: Makefile
SRCS+= acpi_machdep.c acpi_wakecode.h acpi_wakeup.c
SRCS+= assym.s madt.c
CLEANFILES+= acpi_wakecode.bin acpi_wakecode.h acpi_wakecode.o
+
.if ${MACHINE_ARCH} == "amd64"
-SRCS+= opt_global.h
+SRCS+= acpi_switch.S opt_global.h
CLEANFILES+= acpi_wakedata.h
+ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${CFLAGS}
+acpi_switch.o: acpi_switch.S
+ ${CC} -c ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}
.endif
acpi_wakecode.h: acpi_wakecode.S assym.s
diff --git a/sys/modules/alq/Makefile b/sys/modules/alq/Makefile
new file mode 100644
index 0000000..28b94d9
--- /dev/null
+++ b/sys/modules/alq/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+.PATH: ${.CURDIR}/../../kern
+KMOD= alq
+SRCS= opt_mac.h vnode_if.h kern_alq.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile
index a8bb5ea..3c01fd0 100644
--- a/sys/modules/ath/Makefile
+++ b/sys/modules/ath/Makefile
@@ -92,7 +92,7 @@ SRCS+= ar9160_attach.c
SRCS+= ar9280.c ar9280_attach.c
# RF backend for 5416 and 9160
SRCS+= ar2133.c
-SRCS+= ar9285.c ar9285_attach.c
+SRCS+= ar9285.c ar9285_reset.c ar9285_attach.c
# NB: rate control is bound to the driver by symbol names so only pick one
.if ${ATH_RATE} == "sample"
diff --git a/sys/modules/cyclic/Makefile b/sys/modules/cyclic/Makefile
index db99488..371dac6 100644
--- a/sys/modules/cyclic/Makefile
+++ b/sys/modules/cyclic/Makefile
@@ -10,7 +10,7 @@ SRCS+= vnode_if.h
CFLAGS+= -I${.CURDIR}/../../cddl/compat/opensolaris \
-I${.CURDIR}/../../cddl/contrib/opensolaris/uts/common \
-I${.CURDIR}/../.. \
- -I${.CURDIR}/../../cddl/dev/cyclic/${MACHINE_ARCH}
+ -I${.CURDIR}/../../cddl/dev/cyclic/${MACHINE_ARCH:S/amd64/i386/}
CFLAGS+= -DDEBUG=1
diff --git a/sys/modules/dummynet/Makefile b/sys/modules/dummynet/Makefile
index c25a7a7..dd96e0e 100644
--- a/sys/modules/dummynet/Makefile
+++ b/sys/modules/dummynet/Makefile
@@ -5,6 +5,9 @@
.PATH: ${.CURDIR}/../../netinet/ipfw
KMOD= dummynet
SRCS= ip_dummynet.c
+SRCS+= ip_dn_glue.c ip_dn_io.c
+SRCS+= dn_heap.c dn_sched_fifo.c dn_sched_qfq.c dn_sched_rr.c dn_sched_wf2q.c
+SRCS+= dn_sched_prio.c
SRCS+= opt_inet6.h
.if !defined(KERNBUILDDIR)
diff --git a/sys/modules/em/Makefile b/sys/modules/em/Makefile
index b5e2c3b..3e91c14 100644
--- a/sys/modules/em/Makefile
+++ b/sys/modules/em/Makefile
@@ -2,15 +2,19 @@
.PATH: ${.CURDIR}/../../dev/e1000
KMOD = if_em
SRCS = device_if.h bus_if.h pci_if.h opt_inet.h
-SRCS += if_em.c $(SHARED_SRCS)
-SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
-SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
-SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c
-SHARED_SRCS += e1000_82575.c
+SRCS += $(CORE_SRC) $(LEGACY_SRC)
+SRCS += $(COMMON_SHARED) $(LEGACY_SHARED) $(PCIE_SHARED)
+CORE_SRC = if_em.c e1000_osdep.c
+# This is the Legacy, pre-PCIE source, it can be
+# undefined when using modular driver if not needed
+LEGACY_SRC += if_lem.c
+COMMON_SHARED = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
+PCIE_SHARED = e1000_80003es2lan.c e1000_ich8lan.c e1000_82571.c e1000_82575.c
+LEGACY_SHARED = e1000_82540.c e1000_82542.c e1000_82541.c e1000_82543.c
-CFLAGS+= -I${.CURDIR}/../../dev/e1000
+CFLAGS += -I${.CURDIR}/../../dev/e1000
-# DEVICE_POLLING gives you Legacy interrupt handling
+# DEVICE_POLLING for a non-interrupt-driven method
#CFLAGS += -DDEVICE_POLLING
clean:
diff --git a/sys/modules/geom/Makefile b/sys/modules/geom/Makefile
index abce379..0b2e3e8 100644
--- a/sys/modules/geom/Makefile
+++ b/sys/modules/geom/Makefile
@@ -19,6 +19,7 @@ SUBDIR= geom_bde \
geom_part \
geom_pc98 \
geom_raid3 \
+ geom_sched \
geom_shsec \
geom_stripe \
geom_sunlabel \
diff --git a/sys/modules/geom/geom_sched/Makefile b/sys/modules/geom/geom_sched/Makefile
new file mode 100644
index 0000000..5937fa0
--- /dev/null
+++ b/sys/modules/geom/geom_sched/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= gs_sched gsched_rr
+
+.include <bsd.subdir.mk>
diff --git a/sys/modules/geom/geom_sched/Makefile.inc b/sys/modules/geom/geom_sched/Makefile.inc
new file mode 100644
index 0000000..808d6eb
--- /dev/null
+++ b/sys/modules/geom/geom_sched/Makefile.inc
@@ -0,0 +1,9 @@
+# $FreeBSD$
+# included by geom_sched children
+
+.PATH: ${.CURDIR}/../../../../geom/sched
+
+# 6.x needs this path
+#CFLAGS += -I${.CURDIR}/../../../../geom/sched
+
+# .include <bsd.kmod.mk>
diff --git a/sys/modules/geom/geom_sched/gs_sched/Makefile b/sys/modules/geom/geom_sched/gs_sched/Makefile
new file mode 100644
index 0000000..5739365
--- /dev/null
+++ b/sys/modules/geom/geom_sched/gs_sched/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+KMOD= geom_sched
+SRCS= g_sched.c subr_disk.c
+
+# ../Makefile.inc automatically included
+.include <bsd.kmod.mk>
diff --git a/sys/modules/geom/geom_sched/gsched_rr/Makefile b/sys/modules/geom/geom_sched/gsched_rr/Makefile
new file mode 100644
index 0000000..4209277
--- /dev/null
+++ b/sys/modules/geom/geom_sched/gsched_rr/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+KMOD= gsched_rr
+SRCS= gs_rr.c
+# hash.h on 6.x has a (char *) cast on a const pointer
+#CWARNFLAGS=
+
+# ../Makefile.inc automatically included
+.include <bsd.kmod.mk>
diff --git a/sys/modules/hwpmc/Makefile b/sys/modules/hwpmc/Makefile
index 0a696a1..1febf54 100644
--- a/sys/modules/hwpmc/Makefile
+++ b/sys/modules/hwpmc/Makefile
@@ -10,7 +10,7 @@ SRCS= hwpmc_mod.c hwpmc_logging.c vnode_if.h
.if ${MACHINE_ARCH} == "amd64"
SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_piv.c hwpmc_tsc.c
-SRCS+= hwpmc_x86.c
+SRCS+= hwpmc_x86.c hwpmc_uncore.c
SRCS+= device_if.h bus_if.h
.endif
@@ -20,7 +20,7 @@ SRCS+= hwpmc_arm.c
.if ${MACHINE_ARCH} == "i386"
SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_piv.c hwpmc_ppro.c
-SRCS+= hwpmc_pentium.c hwpmc_tsc.c hwpmc_x86.c
+SRCS+= hwpmc_pentium.c hwpmc_tsc.c hwpmc_x86.c hwpmc_uncore.c
SRCS+= device_if.h bus_if.h
.endif
diff --git a/sys/modules/iwnfw/iwn6000/Makefile b/sys/modules/iwnfw/iwn6000/Makefile
index c0295a9..2d2cc3f 100644
--- a/sys/modules/iwnfw/iwn6000/Makefile
+++ b/sys/modules/iwnfw/iwn6000/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
KMOD= iwn6000fw
-IMG= iwlwifi-6000-9.176.4.1
+IMG= iwlwifi-6000-9.193.4.1
.include <bsd.kmod.mk>
diff --git a/sys/modules/ixgbe/Makefile b/sys/modules/ixgbe/Makefile
index 844ac7c..2de7549 100644
--- a/sys/modules/ixgbe/Makefile
+++ b/sys/modules/ixgbe/Makefile
@@ -6,7 +6,7 @@ SRCS += ixgbe.c
# Shared source
SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c
SRCS += ixgbe_82599.c ixgbe_82598.c
-CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP
+CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP -DIXGBE_FDIR
clean:
rm -f device_if.h bus_if.h pci_if.h setdef* *_StripErr
diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile
index a24b6b2..a67fcc7 100644
--- a/sys/modules/linux/Makefile
+++ b/sys/modules/linux/Makefile
@@ -2,7 +2,7 @@
.if ${MACHINE_ARCH} == "amd64"
SFX= 32
-CFLAGS+=-DCOMPAT_IA32 -DCOMPAT_LINUX32
+CFLAGS+=-DCOMPAT_FREEBSD32 -DCOMPAT_LINUX32
.endif
.PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_ARCH}/linux${SFX}
diff --git a/sys/modules/procfs/Makefile b/sys/modules/procfs/Makefile
index c3b3633..9a94838 100644
--- a/sys/modules/procfs/Makefile
+++ b/sys/modules/procfs/Makefile
@@ -35,7 +35,7 @@ opt_compat.h:
echo "#define COMPAT_FREEBSD5 1" >> ${.TARGET}
echo "#define COMPAT_FREEBSD6 1" >> ${.TARGET}
.if ${MACHINE_ARCH} == "amd64"
- echo "#define COMPAT_IA32 1" >> ${.TARGET}
+ echo "#define COMPAT_FREEBSD32 1" >> ${.TARGET}
echo "#define COMPAT_LINUX32 1" >> ${.TARGET}
.endif
.endif
diff --git a/sys/modules/sge/Makefile b/sys/modules/sge/Makefile
new file mode 100644
index 0000000..5f8c587
--- /dev/null
+++ b/sys/modules/sge/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../dev/sge
+
+KMOD= if_sge
+SRCS= if_sge.c device_if.h bus_if.h pci_if.h miibus_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/syscons/Makefile b/sys/modules/syscons/Makefile
index 71e84d0..13cbc57 100644
--- a/sys/modules/syscons/Makefile
+++ b/sys/modules/syscons/Makefile
@@ -1,6 +1,7 @@
# $FreeBSD$
SUBDIR= ${_apm} \
+ ${_beastie} \
blank \
${_daemon} \
${_dragon} \
@@ -18,6 +19,7 @@ _apm= apm
.endif
.if ${MACHINE_ARCH} != "sparc64"
+_beastie= beastie
_daemon= daemon
_dragon= dragon
_fire= fire
diff --git a/sys/modules/syscons/beastie/Makefile b/sys/modules/syscons/beastie/Makefile
new file mode 100644
index 0000000..4f0865b
--- /dev/null
+++ b/sys/modules/syscons/beastie/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../dev/syscons/logo
+
+KMOD= beastie_saver
+SRCS= beastie.c logo_saver.c
+
+CFLAGS+=-DBEASTIE_LOGO
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/uart/Makefile b/sys/modules/uart/Makefile
index d47e2ab..06b3c9b 100644
--- a/sys/modules/uart/Makefile
+++ b/sys/modules/uart/Makefile
@@ -16,7 +16,7 @@ SRCS= uart_bus_acpi.c ${uart_bus_ebus} uart_bus_isa.c uart_bus_pccard.c \
uart_if.c uart_if.h uart_subr.c uart_tty.c
.if ${MACHINE} == "sun4v"
SRCS+= uart_cpu_sparc64.c
-.else
+.elif exists(${CURDIR}/uart_cpu_${MACHINE}.c)
SRCS+= uart_cpu_${MACHINE}.c
.endif
SRCS+= bus_if.h card_if.h device_if.h isa_if.h ${ofw_bus_if} pci_if.h \
diff --git a/sys/modules/wlan/Makefile b/sys/modules/wlan/Makefile
index 07233c6..79d5e75 100644
--- a/sys/modules/wlan/Makefile
+++ b/sys/modules/wlan/Makefile
@@ -3,12 +3,13 @@
.PATH: ${.CURDIR}/../../net80211
KMOD= wlan
-SRCS= ieee80211.c ieee80211_action.c ieee80211_ageq.c \
+SRCS= ieee80211.c ieee80211_action.c ieee80211_ageq.c ieee80211_amrr.c \
ieee80211_crypto.c ieee80211_crypto_none.c ieee80211_dfs.c \
ieee80211_freebsd.c ieee80211_input.c ieee80211_ioctl.c \
ieee80211_mesh.c ieee80211_node.c ieee80211_output.c ieee80211_phy.c \
ieee80211_power.c ieee80211_proto.c ieee80211_scan.c \
- ieee80211_scan_sta.c ieee80211_radiotap.c ieee80211_regdomain.c \
+ ieee80211_scan_sta.c ieee80211_radiotap.c ieee80211_ratectl.c \
+ ieee80211_regdomain.c ieee80211_rssadapt.c \
ieee80211_ht.c ieee80211_hwmp.c ieee80211_adhoc.c ieee80211_hostap.c \
ieee80211_monitor.c ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c
SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h opt_ipx.h opt_wlan.h \
diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile
index c95a840..4554088 100644
--- a/sys/modules/zfs/Makefile
+++ b/sys/modules/zfs/Makefile
@@ -63,8 +63,8 @@ ZFS_SRCS= ${ZFS_OBJS:C/.o$/.c/}
SRCS+= ${ZFS_SRCS}
SRCS+= vdev_geom.c
-# Use UMA for ZIO allocation. This is not stable.
-#CFLAGS+=-DZIO_USE_UMA
+# Use UMA for ZIO allocation.
+CFLAGS+=-DZIO_USE_UMA
# Use FreeBSD's namecache.
CFLAGS+=-DFREEBSD_NAMECACHE
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 65e3f2b..1755ec7 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -38,6 +38,7 @@
__FBSDID("$FreeBSD$");
#include "opt_bpf.h"
+#include "opt_compat.h"
#include "opt_netgraph.h"
#include <sys/types.h>
@@ -89,6 +90,43 @@ MALLOC_DEFINE(M_BPF, "BPF", "BPF data");
#define PRINET 26 /* interruptible */
+#ifdef COMPAT_FREEBSD32
+#include <sys/mount.h>
+#include <compat/freebsd32/freebsd32.h>
+#define BPF_ALIGNMENT32 sizeof(int32_t)
+#define BPF_WORDALIGN32(x) (((x)+(BPF_ALIGNMENT32-1))&~(BPF_ALIGNMENT32-1))
+
+/*
+ * 32-bit version of structure prepended to each packet. We use this header
+ * instead of the standard one for 32-bit streams. We mark the a stream as
+ * 32-bit the first time we see a 32-bit compat ioctl request.
+ */
+struct bpf_hdr32 {
+ struct timeval32 bh_tstamp; /* time stamp */
+ uint32_t bh_caplen; /* length of captured portion */
+ uint32_t bh_datalen; /* original length of packet */
+ uint16_t bh_hdrlen; /* length of bpf header (this struct
+ plus alignment padding) */
+};
+
+struct bpf_program32 {
+ u_int bf_len;
+ uint32_t bf_insns;
+};
+
+struct bpf_dltlist32 {
+ u_int bfl_len;
+ u_int bfl_list;
+};
+
+#define BIOCSETF32 _IOW('B', 103, struct bpf_program32)
+#define BIOCSRTIMEOUT32 _IOW('B',109, struct timeval32)
+#define BIOCGRTIMEOUT32 _IOR('B',110, struct timeval32)
+#define BIOCGDLTLIST32 _IOWR('B',121, struct bpf_dltlist32)
+#define BIOCSETWF32 _IOW('B',123, struct bpf_program32)
+#define BIOCSETFNR32 _IOW('B',130, struct bpf_program32)
+#endif
+
/*
* bpf_iflist is a list of BPF interface structures, each corresponding to a
* specific DLT. The same network interface might have several BPF interface
@@ -614,6 +652,7 @@ bpf_dtor(void *data)
mac_bpfdesc_destroy(d);
#endif /* MAC */
knlist_destroy(&d->bd_sel.si_note);
+ callout_drain(&d->bd_callout);
bpf_freed(d);
free(d, M_BPF);
}
@@ -651,7 +690,7 @@ bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td)
mac_bpfdesc_create(td->td_ucred, d);
#endif
mtx_init(&d->bd_mtx, devtoname(dev), "bpf cdev lock", MTX_DEF);
- callout_init(&d->bd_callout, CALLOUT_MPSAFE);
+ callout_init_mtx(&d->bd_callout, &d->bd_mtx, 0);
knlist_init_mtx(&d->bd_sel.si_note, &d->bd_mtx);
return (0);
@@ -807,13 +846,15 @@ bpf_timed_out(void *arg)
{
struct bpf_d *d = (struct bpf_d *)arg;
- BPFD_LOCK(d);
+ BPFD_LOCK_ASSERT(d);
+
+ if (callout_pending(&d->bd_callout) || !callout_active(&d->bd_callout))
+ return;
if (d->bd_state == BPF_WAITING) {
d->bd_state = BPF_TIMED_OUT;
if (d->bd_slen != 0)
bpf_wakeup(d);
}
- BPFD_UNLOCK(d);
}
static int
@@ -1002,8 +1043,14 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
case BIOCFLUSH:
case BIOCGDLT:
case BIOCGDLTLIST:
+#ifdef COMPAT_FREEBSD32
+ case BIOCGDLTLIST32:
+#endif
case BIOCGETIF:
case BIOCGRTIMEOUT:
+#ifdef COMPAT_FREEBSD32
+ case BIOCGRTIMEOUT32:
+#endif
case BIOCGSTATS:
case BIOCVERSION:
case BIOCGRSIG:
@@ -1012,6 +1059,9 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
case FIONREAD:
case BIOCLOCK:
case BIOCSRTIMEOUT:
+#ifdef COMPAT_FREEBSD32
+ case BIOCSRTIMEOUT32:
+#endif
case BIOCIMMEDIATE:
case TIOCGPGRP:
case BIOCROTZBUF:
@@ -1020,6 +1070,22 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
return (EPERM);
}
}
+#ifdef COMPAT_FREEBSD32
+ /*
+ * If we see a 32-bit compat ioctl, mark the stream as 32-bit so
+ * that it will get 32-bit packet headers.
+ */
+ switch (cmd) {
+ case BIOCSETF32:
+ case BIOCSETFNR32:
+ case BIOCSETWF32:
+ case BIOCGDLTLIST32:
+ case BIOCGRTIMEOUT32:
+ case BIOCSRTIMEOUT32:
+ d->bd_compat32 = 1;
+ }
+#endif
+
CURVNET_SET(TD_TO_VNET(td));
switch (cmd) {
@@ -1077,6 +1143,11 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
case BIOCSETF:
case BIOCSETFNR:
case BIOCSETWF:
+#ifdef COMPAT_FREEBSD32
+ case BIOCSETF32:
+ case BIOCSETFNR32:
+ case BIOCSETWF32:
+#endif
error = bpf_setf(d, (struct bpf_program *)addr, cmd);
break;
@@ -1120,6 +1191,26 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
/*
* Get a list of supported data link types.
*/
+#ifdef COMPAT_FREEBSD32
+ case BIOCGDLTLIST32:
+ {
+ struct bpf_dltlist32 *list32;
+ struct bpf_dltlist dltlist;
+
+ list32 = (struct bpf_dltlist32 *)addr;
+ dltlist.bfl_len = list32->bfl_len;
+ dltlist.bfl_list = PTRIN(list32->bfl_list);
+ if (d->bd_bif == NULL)
+ error = EINVAL;
+ else {
+ error = bpf_getdltlist(d, &dltlist);
+ if (error == 0)
+ list32->bfl_len = dltlist.bfl_len;
+ }
+ break;
+ }
+#endif
+
case BIOCGDLTLIST:
if (d->bd_bif == NULL)
error = EINVAL;
@@ -1163,8 +1254,23 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
* Set read timeout.
*/
case BIOCSRTIMEOUT:
+#ifdef COMPAT_FREEBSD32
+ case BIOCSRTIMEOUT32:
+#endif
{
struct timeval *tv = (struct timeval *)addr;
+#ifdef COMPAT_FREEBSD32
+ struct timeval32 *tv32;
+ struct timeval tv64;
+
+ if (cmd == BIOCSRTIMEOUT32) {
+ tv32 = (struct timeval32 *)addr;
+ tv = &tv64;
+ tv->tv_sec = tv32->tv_sec;
+ tv->tv_usec = tv32->tv_usec;
+ } else
+#endif
+ tv = (struct timeval *)addr;
/*
* Subtract 1 tick from tvtohz() since this isn't
@@ -1179,11 +1285,31 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
* Get read timeout.
*/
case BIOCGRTIMEOUT:
+#ifdef COMPAT_FREEBSD32
+ case BIOCGRTIMEOUT32:
+#endif
{
- struct timeval *tv = (struct timeval *)addr;
+ struct timeval *tv;
+#ifdef COMPAT_FREEBSD32
+ struct timeval32 *tv32;
+ struct timeval tv64;
+
+ if (cmd == BIOCGRTIMEOUT32)
+ tv = &tv64;
+ else
+#endif
+ tv = (struct timeval *)addr;
tv->tv_sec = d->bd_rtout / hz;
tv->tv_usec = (d->bd_rtout % hz) * tick;
+#ifdef COMPAT_FREEBSD32
+ if (cmd == BIOCGRTIMEOUT32) {
+ tv32 = (struct timeval32 *)addr;
+ tv32->tv_sec = tv->tv_sec;
+ tv32->tv_usec = tv->tv_usec;
+ }
+#endif
+
break;
}
@@ -1366,7 +1492,19 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd)
#ifdef BPF_JITTER
bpf_jit_filter *ofunc;
#endif
-
+#ifdef COMPAT_FREEBSD32
+ struct bpf_program32 *fp32;
+ struct bpf_program fp_swab;
+
+ if (cmd == BIOCSETWF32 || cmd == BIOCSETF32 || cmd == BIOCSETFNR32) {
+ fp32 = (struct bpf_program32 *)fp;
+ fp_swab.bf_len = fp32->bf_len;
+ fp_swab.bf_insns = (struct bpf_insn *)(uintptr_t)fp32->bf_insns;
+ fp = &fp_swab;
+ if (cmd == BIOCSETWF32)
+ cmd = BIOCSETWF;
+ }
+#endif
if (cmd == BIOCSETWF) {
old = d->bd_wfilter;
wfilter = 1;
@@ -1577,8 +1715,7 @@ filt_bpfread(struct knote *kn, long hint)
kn->kn_data = d->bd_slen;
if (d->bd_hbuf)
kn->kn_data += d->bd_hlen;
- }
- else if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
+ } else if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
callout_reset(&d->bd_callout, d->bd_rtout,
bpf_timed_out, d);
d->bd_state = BPF_WAITING;
@@ -1769,6 +1906,9 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
struct timeval *tv)
{
struct bpf_hdr hdr;
+#ifdef COMPAT_FREEBSD32
+ struct bpf_hdr32 hdr32;
+#endif
int totlen, curlen;
int hdrlen = d->bd_bif->bif_hdrlen;
int do_wakeup = 0;
@@ -1807,7 +1947,12 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
* buffer is considered immutable by the buffer model, try to rotate
* the buffer and wakeup pending processes.
*/
- curlen = BPF_WORDALIGN(d->bd_slen);
+#ifdef COMPAT_FREEBSD32
+ if (d->bd_compat32)
+ curlen = BPF_WORDALIGN32(d->bd_slen);
+ else
+#endif
+ curlen = BPF_WORDALIGN(d->bd_slen);
if (curlen + totlen > d->bd_bufsize || !bpf_canwritebuf(d)) {
if (d->bd_fbuf == NULL) {
/*
@@ -1829,6 +1974,22 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
* reader should be woken up.
*/
do_wakeup = 1;
+#ifdef COMPAT_FREEBSD32
+ /*
+ * If this is a 32-bit stream, then stick a 32-bit header at the
+ * front and copy the data into the buffer.
+ */
+ if (d->bd_compat32) {
+ bzero(&hdr32, sizeof(hdr32));
+ hdr32.bh_tstamp.tv_sec = tv->tv_sec;
+ hdr32.bh_tstamp.tv_usec = tv->tv_usec;
+ hdr32.bh_datalen = pktlen;
+ hdr32.bh_hdrlen = hdrlen;
+ hdr.bh_caplen = hdr32.bh_caplen = totlen - hdrlen;
+ bpf_append_bytes(d, d->bd_sbuf, curlen, &hdr32, sizeof(hdr32));
+ goto copy;
+ }
+#endif
/*
* Append the bpf header. Note we append the actual header size, but
@@ -1844,6 +2005,9 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
/*
* Copy the packet data into the store buffer and update its length.
*/
+#ifdef COMPAT_FREEBSD32
+ copy:
+#endif
(*cpfn)(d, d->bd_sbuf, curlen + hdrlen, pkt, hdr.bh_caplen);
d->bd_slen = curlen + totlen;
@@ -1865,13 +2029,14 @@ bpf_freed(struct bpf_d *d)
* free.
*/
bpf_free(d);
- if (d->bd_rfilter) {
+ if (d->bd_rfilter != NULL) {
free((caddr_t)d->bd_rfilter, M_BPF);
#ifdef BPF_JITTER
- bpf_destroy_jit_filter(d->bd_bfilter);
+ if (d->bd_bfilter != NULL)
+ bpf_destroy_jit_filter(d->bd_bfilter);
#endif
}
- if (d->bd_wfilter)
+ if (d->bd_wfilter != NULL)
free((caddr_t)d->bd_wfilter, M_BPF);
mtx_destroy(&d->bd_mtx);
}
diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h
index 5784763..03cb20d 100644
--- a/sys/net/bpfdesc.h
+++ b/sys/net/bpfdesc.h
@@ -97,6 +97,7 @@ struct bpf_d {
u_int64_t bd_wfcount; /* number of packets that matched write filter */
u_int64_t bd_wdcount; /* number of packets dropped during a write */
u_int64_t bd_zcopy; /* number of zero copy operations */
+ u_char bd_compat32; /* 32-bit stream on LP64 system */
};
/* Values for bd_state */
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index ab42e68..39b6b40 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -1,6 +1,6 @@
/**************************************************************************
-Copyright (c) 2008-2009, BitGravity Inc.
+Copyright (c) 2008-2010, BitGravity Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "opt_route.h"
#include "opt_mpath.h"
#include "opt_ddb.h"
+#include "opt_inet.h"
+#include "opt_inet6.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -45,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/proc.h>
+#include <sys/sbuf.h>
#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/socket.h>
@@ -63,6 +66,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
+#ifdef INET6
+#include <netinet/ip6.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/sctp.h>
@@ -140,31 +146,42 @@ union flentryp {
struct flentry **pcpu[MAXCPU];
};
+struct flowtable_stats {
+ uint64_t ft_collisions;
+ uint64_t ft_allocated;
+ uint64_t ft_misses;
+ uint64_t ft_max_depth;
+ uint64_t ft_free_checks;
+ uint64_t ft_frees;
+ uint64_t ft_hits;
+ uint64_t ft_lookups;
+} __aligned(CACHE_LINE_SIZE);
+
struct flowtable {
+ struct flowtable_stats ft_stats[MAXCPU];
int ft_size;
int ft_lock_count;
uint32_t ft_flags;
- uint32_t ft_collisions;
- uint32_t ft_allocated;
- uint32_t ft_misses;
- uint64_t ft_hits;
-
- uint32_t ft_udp_idle;
- uint32_t ft_fin_wait_idle;
- uint32_t ft_syn_idle;
- uint32_t ft_tcp_idle;
-
+ char *ft_name;
fl_lock_t *ft_lock;
fl_lock_t *ft_unlock;
fl_rtalloc_t *ft_rtalloc;
+ /*
+ * XXX need to pad out
+ */
struct mtx *ft_locks;
-
-
union flentryp ft_table;
bitstr_t *ft_masks[MAXCPU];
bitstr_t *ft_tmpmask;
struct flowtable *ft_next;
-};
+
+ uint32_t ft_count __aligned(CACHE_LINE_SIZE);
+ uint32_t ft_udp_idle __aligned(CACHE_LINE_SIZE);
+ uint32_t ft_fin_wait_idle;
+ uint32_t ft_syn_idle;
+ uint32_t ft_tcp_idle;
+ boolean_t ft_full;
+} __aligned(CACHE_LINE_SIZE);
static struct proc *flowcleanerproc;
static VNET_DEFINE(struct flowtable *, flow_list_head);
@@ -177,16 +194,30 @@ static VNET_DEFINE(uma_zone_t, flow_ipv6_zone);
#define V_flow_ipv4_zone VNET(flow_ipv4_zone)
#define V_flow_ipv6_zone VNET(flow_ipv6_zone)
+
static struct cv flowclean_cv;
static struct mtx flowclean_lock;
static uint32_t flowclean_cycles;
+static uint32_t flowclean_freq;
+
+#ifdef FLOWTABLE_DEBUG
+#define FLDPRINTF(ft, flags, fmt, ...) \
+do { \
+ if ((ft)->ft_flags & (flags)) \
+ printf((fmt), __VA_ARGS__); \
+} while (0); \
+
+#else
+#define FLDPRINTF(ft, flags, fmt, ...)
+
+#endif
+
/*
* TODO:
* - Make flowtable stats per-cpu, aggregated at sysctl call time,
* to avoid extra cache evictions caused by incrementing a shared
* counter
- * - add IPv6 support to flow lookup
* - add sysctls to resize && flush flow tables
* - Add per flowtable sysctls for statistics and configuring timeouts
* - add saturation counter to rtentry to support per-packet load-balancing
@@ -200,29 +231,15 @@ static uint32_t flowclean_cycles;
*/
VNET_DEFINE(int, flowtable_enable) = 1;
static VNET_DEFINE(int, flowtable_debug);
-static VNET_DEFINE(int, flowtable_hits);
-static VNET_DEFINE(int, flowtable_lookups);
-static VNET_DEFINE(int, flowtable_misses);
-static VNET_DEFINE(int, flowtable_frees);
-static VNET_DEFINE(int, flowtable_free_checks);
-static VNET_DEFINE(int, flowtable_max_depth);
-static VNET_DEFINE(int, flowtable_collisions);
static VNET_DEFINE(int, flowtable_syn_expire) = SYN_IDLE;
static VNET_DEFINE(int, flowtable_udp_expire) = UDP_IDLE;
static VNET_DEFINE(int, flowtable_fin_wait_expire) = FIN_WAIT_IDLE;
static VNET_DEFINE(int, flowtable_tcp_expire) = TCP_IDLE;
-static VNET_DEFINE(int, flowtable_nmbflows) = 4096;
+static VNET_DEFINE(int, flowtable_nmbflows);
static VNET_DEFINE(int, flowtable_ready) = 0;
#define V_flowtable_enable VNET(flowtable_enable)
#define V_flowtable_debug VNET(flowtable_debug)
-#define V_flowtable_hits VNET(flowtable_hits)
-#define V_flowtable_lookups VNET(flowtable_lookups)
-#define V_flowtable_misses VNET(flowtable_misses)
-#define V_flowtable_frees VNET(flowtable_frees)
-#define V_flowtable_free_checks VNET(flowtable_free_checks)
-#define V_flowtable_max_depth VNET(flowtable_max_depth)
-#define V_flowtable_collisions VNET(flowtable_collisions)
#define V_flowtable_syn_expire VNET(flowtable_syn_expire)
#define V_flowtable_udp_expire VNET(flowtable_udp_expire)
#define V_flowtable_fin_wait_expire VNET(flowtable_fin_wait_expire)
@@ -235,20 +252,6 @@ SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, debug, CTLFLAG_RW,
&VNET_NAME(flowtable_debug), 0, "print debug info.");
SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, enable, CTLFLAG_RW,
&VNET_NAME(flowtable_enable), 0, "enable flowtable caching.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, hits, CTLFLAG_RD,
- &VNET_NAME(flowtable_hits), 0, "# flowtable hits.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, lookups, CTLFLAG_RD,
- &VNET_NAME(flowtable_lookups), 0, "# flowtable lookups.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, misses, CTLFLAG_RD,
- &VNET_NAME(flowtable_misses), 0, "#flowtable misses.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, frees, CTLFLAG_RD,
- &VNET_NAME(flowtable_frees), 0, "#flows freed.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, free_checks, CTLFLAG_RD,
- &VNET_NAME(flowtable_free_checks), 0, "#flows free checks.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, max_depth, CTLFLAG_RD,
- &VNET_NAME(flowtable_max_depth), 0, "max collision list length.");
-SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, collisions, CTLFLAG_RD,
- &VNET_NAME(flowtable_collisions), 0, "#flowtable collisions.");
/*
* XXX This does not end up updating timeouts at runtime
@@ -298,6 +301,77 @@ SYSCTL_VNET_PROC(_net_inet_flowtable, OID_AUTO, nmbflows,
CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_nmbflows, "IU",
"Maximum number of flows allowed");
+
+
+#define FS_PRINT(sb, field) sbuf_printf((sb), "\t%s: %jd\n", #field, fs->ft_##field)
+
+static void
+fs_print(struct sbuf *sb, struct flowtable_stats *fs)
+{
+
+ FS_PRINT(sb, collisions);
+ FS_PRINT(sb, allocated);
+ FS_PRINT(sb, misses);
+ FS_PRINT(sb, max_depth);
+ FS_PRINT(sb, free_checks);
+ FS_PRINT(sb, frees);
+ FS_PRINT(sb, hits);
+ FS_PRINT(sb, lookups);
+}
+
+static void
+flowtable_show_stats(struct sbuf *sb, struct flowtable *ft)
+{
+ int i;
+ struct flowtable_stats fs, *pfs;
+
+ if (ft->ft_flags & FL_PCPU) {
+ bzero(&fs, sizeof(fs));
+ pfs = &fs;
+ for (i = 0; i <= mp_maxid; i++) {
+ if (CPU_ABSENT(i))
+ continue;
+ pfs->ft_collisions += ft->ft_stats[i].ft_collisions;
+ pfs->ft_allocated += ft->ft_stats[i].ft_allocated;
+ pfs->ft_misses += ft->ft_stats[i].ft_misses;
+ pfs->ft_free_checks += ft->ft_stats[i].ft_free_checks;
+ pfs->ft_frees += ft->ft_stats[i].ft_frees;
+ pfs->ft_hits += ft->ft_stats[i].ft_hits;
+ pfs->ft_lookups += ft->ft_stats[i].ft_lookups;
+ if (ft->ft_stats[i].ft_max_depth > pfs->ft_max_depth)
+ pfs->ft_max_depth = ft->ft_stats[i].ft_max_depth;
+ }
+ } else {
+ pfs = &ft->ft_stats[0];
+ }
+ fs_print(sb, pfs);
+}
+
+static int
+sysctl_flowtable_stats(SYSCTL_HANDLER_ARGS)
+{
+ struct flowtable *ft;
+ struct sbuf *sb;
+ int error;
+
+ sb = sbuf_new(NULL, NULL, 64*1024, SBUF_FIXEDLEN);
+
+ ft = V_flow_list_head;
+ while (ft != NULL) {
+ sbuf_printf(sb, "\ntable name: %s\n", ft->ft_name);
+ flowtable_show_stats(sb, ft);
+ ft = ft->ft_next;
+ }
+ sbuf_finish(sb);
+ error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
+ sbuf_delete(sb);
+
+ return (error);
+}
+SYSCTL_VNET_PROC(_net_inet_flowtable, OID_AUTO, stats, CTLTYPE_STRING|CTLFLAG_RD,
+ NULL, 0, sysctl_flowtable_stats, "A", "flowtable statistics");
+
+
#ifndef RADIX_MPATH
static void
in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum)
@@ -342,52 +416,122 @@ flowtable_pcpu_unlock(struct flowtable *table, uint32_t hash)
#define FL_ENTRY_LOCK(table, hash) (table)->ft_lock((table), (hash))
#define FL_ENTRY_UNLOCK(table, hash) (table)->ft_unlock((table), (hash))
-#define FL_STALE (1<<8)
-#define FL_IPV6 (1<<9)
+#define FL_STALE (1<<8)
+#define FL_IPV6 (1<<9)
+#define FL_OVERWRITE (1<<10)
-static uint32_t
-ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro,
- uint32_t *key, uint16_t *flags, uint8_t *protop)
+void
+flow_invalidate(struct flentry *fle)
{
- uint16_t sport = 0, dport = 0;
- struct ip *ip = NULL;
- uint8_t proto = 0;
+
+ fle->f_flags |= FL_STALE;
+}
+
+static __inline int
+proto_to_flags(uint8_t proto)
+{
+ int flag;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ flag = FL_TCP;
+ break;
+ case IPPROTO_SCTP:
+ flag = FL_SCTP;
+ break;
+ case IPPROTO_UDP:
+ flag = FL_UDP;
+ break;
+ default:
+ flag = 0;
+ break;
+ }
+
+ return (flag);
+}
+
+static __inline int
+flags_to_proto(int flags)
+{
+ int proto, protoflags;
+
+ protoflags = flags & (FL_TCP|FL_SCTP|FL_UDP);
+ switch (protoflags) {
+ case FL_TCP:
+ proto = IPPROTO_TCP;
+ break;
+ case FL_SCTP:
+ proto = IPPROTO_SCTP;
+ break;
+ case FL_UDP:
+ proto = IPPROTO_UDP;
+ break;
+ default:
+ proto = 0;
+ break;
+ }
+ return (proto);
+}
+
+#ifdef INET
+#ifdef FLOWTABLE_DEBUG
+static void
+ipv4_flow_print_tuple(int flags, int proto, struct sockaddr_in *ssin,
+ struct sockaddr_in *dsin)
+{
+ char saddr[4*sizeof "123"], daddr[4*sizeof "123"];
+
+ if (flags & FL_HASH_ALL) {
+ inet_ntoa_r(ssin->sin_addr, saddr);
+ inet_ntoa_r(dsin->sin_addr, daddr);
+ printf("proto=%d %s:%d->%s:%d\n",
+ proto, saddr, ntohs(ssin->sin_port), daddr,
+ ntohs(dsin->sin_port));
+ } else {
+ inet_ntoa_r(*(struct in_addr *) &dsin->sin_addr, daddr);
+ printf("proto=%d %s\n", proto, daddr);
+ }
+
+}
+#endif
+
+static int
+ipv4_mbuf_demarshal(struct flowtable *ft, struct mbuf *m,
+ struct sockaddr_in *ssin, struct sockaddr_in *dsin, uint16_t *flags)
+{
+ struct ip *ip;
+ uint8_t proto;
int iphlen;
- uint32_t hash;
- struct sockaddr_in *sin;
struct tcphdr *th;
struct udphdr *uh;
struct sctphdr *sh;
+ uint16_t sport, dport;
- if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0))
- return (0);
+ proto = sport = dport = 0;
+ ip = mtod(m, struct ip *);
+ dsin->sin_family = AF_INET;
+ dsin->sin_len = sizeof(*dsin);
+ dsin->sin_addr = ip->ip_dst;
+ ssin->sin_family = AF_INET;
+ ssin->sin_len = sizeof(*ssin);
+ ssin->sin_addr = ip->ip_src;
- key[1] = key[0] = 0;
- sin = (struct sockaddr_in *)&ro->ro_dst;
- if (m != NULL) {
- ip = mtod(m, struct ip *);
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_addr = ip->ip_dst;
- } else
- *flags &= ~FL_HASH_PORTS;
-
- key[2] = sin->sin_addr.s_addr;
-
- if ((*flags & FL_HASH_PORTS) == 0)
+ proto = ip->ip_p;
+ if ((*flags & FL_HASH_ALL) == 0) {
+ FLDPRINTF(ft, FL_DEBUG_ALL, "skip port check flags=0x%x ",
+ *flags);
goto skipports;
+ }
- proto = ip->ip_p;
iphlen = ip->ip_hl << 2; /* XXX options? */
- key[1] = ip->ip_src.s_addr;
-
+
switch (proto) {
case IPPROTO_TCP:
th = (struct tcphdr *)((caddr_t)ip + iphlen);
- sport = ntohs(th->th_sport);
- dport = ntohs(th->th_dport);
- *flags |= th->th_flags;
- if (*flags & TH_RST)
+ sport = th->th_sport;
+ dport = th->th_dport;
+ if ((*flags & FL_HASH_ALL) &&
+ (th->th_flags & (TH_RST|TH_FIN)))
*flags |= FL_STALE;
break;
case IPPROTO_UDP:
@@ -401,38 +545,292 @@ ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro,
dport = sh->dest_port;
break;
default:
- if (*flags & FL_HASH_PORTS)
- goto noop;
+ FLDPRINTF(ft, FL_DEBUG_ALL, "proto=0x%x not supported\n", proto);
+ return (ENOTSUP);
/* no port - hence not a protocol we care about */
break;
}
- *protop = proto;
- /*
- * If this is a transmit route cache then
- * hash all flows to a given destination to
- * the same bucket
- */
- if ((*flags & FL_HASH_PORTS) == 0)
- proto = sport = dport = 0;
+skipports:
+ *flags |= proto_to_flags(proto);
+ ssin->sin_port = sport;
+ dsin->sin_port = dport;
+ return (0);
+}
- ((uint16_t *)key)[0] = sport;
- ((uint16_t *)key)[1] = dport;
+static uint32_t
+ipv4_flow_lookup_hash_internal(
+ struct sockaddr_in *ssin, struct sockaddr_in *dsin,
+ uint32_t *key, uint16_t flags)
+{
+ uint16_t sport, dport;
+ uint8_t proto;
+ int offset = 0;
-skipports:
- hash = jenkins_hashword(key, 3, V_flow_hashjitter + proto);
- if (m != NULL && (m->m_flags & M_FLOWID) == 0) {
- m->m_flags |= M_FLOWID;
- m->m_pkthdr.flowid = hash;
+ if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0))
+ return (0);
+ proto = flags_to_proto(flags);
+ sport = dport = key[2] = key[1] = key[0] = 0;
+ if ((ssin != NULL) && (flags & FL_HASH_ALL)) {
+ key[1] = ssin->sin_addr.s_addr;
+ sport = ssin->sin_port;
}
+ if (dsin != NULL) {
+ key[2] = dsin->sin_addr.s_addr;
+ dport = dsin->sin_port;
+ }
+ if (flags & FL_HASH_ALL) {
+ ((uint16_t *)key)[0] = sport;
+ ((uint16_t *)key)[1] = dport;
+ } else
+ offset = V_flow_hashjitter + proto;
+
+ return (jenkins_hashword(key, 3, offset));
+}
+
+static struct flentry *
+flowtable_lookup_mbuf4(struct flowtable *ft, struct mbuf *m)
+{
+ struct sockaddr_storage ssa, dsa;
+ uint16_t flags;
+ struct sockaddr_in *dsin, *ssin;
+
+ dsin = (struct sockaddr_in *)&dsa;
+ ssin = (struct sockaddr_in *)&ssa;
+ bzero(dsin, sizeof(*dsin));
+ bzero(ssin, sizeof(*ssin));
+ flags = ft->ft_flags;
+ if (ipv4_mbuf_demarshal(ft, m, ssin, dsin, &flags) != 0)
+ return (NULL);
+
+ return (flowtable_lookup(ft, &ssa, &dsa, M_GETFIB(m), flags));
+}
+
+void
+flow_to_route(struct flentry *fle, struct route *ro)
+{
+ uint32_t *hashkey = NULL;
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&ro->ro_dst;
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ hashkey = ((struct flentry_v4 *)fle)->fl_flow.ipf_key;
+ sin->sin_addr.s_addr = hashkey[2];
+ ro->ro_rt = __DEVOLATILE(struct rtentry *, fle->f_rt);
+ ro->ro_lle = __DEVOLATILE(struct llentry *, fle->f_lle);
+}
+#endif /* INET */
+
+#ifdef INET6
+/*
+ * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous,
+ * then it sets p to point at the offset "len" in the mbuf. WARNING: the
+ * pointer might become stale after other pullups (but we never use it
+ * this way).
+ */
+#define PULLUP_TO(_len, p, T) \
+do { \
+ int x = (_len) + sizeof(T); \
+ if ((m)->m_len < x) { \
+ goto receive_failed; \
+ } \
+ p = (mtod(m, char *) + (_len)); \
+} while (0)
+
+#define TCP(p) ((struct tcphdr *)(p))
+#define SCTP(p) ((struct sctphdr *)(p))
+#define UDP(p) ((struct udphdr *)(p))
+
+static int
+ipv6_mbuf_demarshal(struct flowtable *ft, struct mbuf *m,
+ struct sockaddr_in6 *ssin6, struct sockaddr_in6 *dsin6, uint16_t *flags)
+{
+ struct ip6_hdr *ip6;
+ uint8_t proto;
+ int hlen;
+ uint16_t src_port, dst_port;
+ u_short offset;
+ void *ulp;
+
+ offset = hlen = src_port = dst_port = 0;
+ ulp = NULL;
+ ip6 = mtod(m, struct ip6_hdr *);
+ hlen = sizeof(struct ip6_hdr);
+ proto = ip6->ip6_nxt;
+
+ if ((*flags & FL_HASH_ALL) == 0)
+ goto skipports;
+
+ while (ulp == NULL) {
+ switch (proto) {
+ case IPPROTO_ICMPV6:
+ case IPPROTO_OSPFIGP:
+ case IPPROTO_PIM:
+ case IPPROTO_CARP:
+ case IPPROTO_ESP:
+ case IPPROTO_NONE:
+ ulp = ip6;
+ break;
+ case IPPROTO_TCP:
+ PULLUP_TO(hlen, ulp, struct tcphdr);
+ dst_port = TCP(ulp)->th_dport;
+ src_port = TCP(ulp)->th_sport;
+ if ((*flags & FL_HASH_ALL) &&
+ (TCP(ulp)->th_flags & (TH_RST|TH_FIN)))
+ *flags |= FL_STALE;
+ break;
+ case IPPROTO_SCTP:
+ PULLUP_TO(hlen, ulp, struct sctphdr);
+ src_port = SCTP(ulp)->src_port;
+ dst_port = SCTP(ulp)->dest_port;
+ break;
+ case IPPROTO_UDP:
+ PULLUP_TO(hlen, ulp, struct udphdr);
+ dst_port = UDP(ulp)->uh_dport;
+ src_port = UDP(ulp)->uh_sport;
+ break;
+ case IPPROTO_HOPOPTS: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_hbh);
+ hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
+ proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
+ ulp = NULL;
+ break;
+ case IPPROTO_ROUTING: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_rthdr);
+ hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
+ proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
+ ulp = NULL;
+ break;
+ case IPPROTO_FRAGMENT: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_frag);
+ hlen += sizeof (struct ip6_frag);
+ proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
+ offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
+ IP6F_OFF_MASK;
+ ulp = NULL;
+ break;
+ case IPPROTO_DSTOPTS: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_hbh);
+ hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
+ proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
+ ulp = NULL;
+ break;
+ case IPPROTO_AH: /* RFC 2402 */
+ PULLUP_TO(hlen, ulp, struct ip6_ext);
+ hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
+ proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
+ ulp = NULL;
+ break;
+ default:
+ PULLUP_TO(hlen, ulp, struct ip6_ext);
+ break;
+ }
+ }
+
+ if (src_port == 0) {
+ receive_failed:
+ return (ENOTSUP);
+ }
+
+skipports:
+ dsin6->sin6_family = AF_INET6;
+ dsin6->sin6_len = sizeof(*dsin6);
+ dsin6->sin6_port = dst_port;
+ memcpy(&dsin6->sin6_addr, &ip6->ip6_dst, sizeof(struct in6_addr));
+
+ ssin6->sin6_family = AF_INET6;
+ ssin6->sin6_len = sizeof(*ssin6);
+ ssin6->sin6_port = src_port;
+ memcpy(&ssin6->sin6_addr, &ip6->ip6_src, sizeof(struct in6_addr));
+ *flags |= proto_to_flags(proto);
- return (hash);
-noop:
- *protop = proto;
return (0);
}
+#define zero_key(key) \
+do { \
+ key[0] = 0; \
+ key[1] = 0; \
+ key[2] = 0; \
+ key[3] = 0; \
+ key[4] = 0; \
+ key[5] = 0; \
+ key[6] = 0; \
+ key[7] = 0; \
+ key[8] = 0; \
+} while (0)
+
+static uint32_t
+ipv6_flow_lookup_hash_internal(
+ struct sockaddr_in6 *ssin6, struct sockaddr_in6 *dsin6,
+ uint32_t *key, uint16_t flags)
+{
+ uint16_t sport, dport;
+ uint8_t proto;
+ int offset = 0;
+
+ if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0))
+ return (0);
+
+ proto = flags_to_proto(flags);
+ zero_key(key);
+ sport = dport = 0;
+ if (dsin6 != NULL) {
+ memcpy(&key[1], &dsin6->sin6_addr, sizeof(struct in6_addr));
+ dport = dsin6->sin6_port;
+ }
+ if ((ssin6 != NULL) && (flags & FL_HASH_ALL)) {
+ memcpy(&key[5], &ssin6->sin6_addr, sizeof(struct in6_addr));
+ sport = ssin6->sin6_port;
+ }
+ if (flags & FL_HASH_ALL) {
+ ((uint16_t *)key)[0] = sport;
+ ((uint16_t *)key)[1] = dport;
+ } else
+ offset = V_flow_hashjitter + proto;
+
+ return (jenkins_hashword(key, 9, offset));
+}
+
+static struct flentry *
+flowtable_lookup_mbuf6(struct flowtable *ft, struct mbuf *m)
+{
+ struct sockaddr_storage ssa, dsa;
+ struct sockaddr_in6 *dsin6, *ssin6;
+ uint16_t flags;
+
+ dsin6 = (struct sockaddr_in6 *)&dsa;
+ ssin6 = (struct sockaddr_in6 *)&ssa;
+ bzero(dsin6, sizeof(*dsin6));
+ bzero(ssin6, sizeof(*ssin6));
+ flags = ft->ft_flags;
+
+ if (ipv6_mbuf_demarshal(ft, m, ssin6, dsin6, &flags) != 0)
+ return (NULL);
+
+ return (flowtable_lookup(ft, &ssa, &dsa, M_GETFIB(m), flags));
+}
+
+void
+flow_to_route_in6(struct flentry *fle, struct route_in6 *ro)
+{
+ uint32_t *hashkey = NULL;
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&ro->ro_dst;
+
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
+ hashkey = ((struct flentry_v6 *)fle)->fl_flow.ipf_key;
+ memcpy(&sin6->sin6_addr, &hashkey[5], sizeof (struct in6_addr));
+ ro->ro_rt = __DEVOLATILE(struct rtentry *, fle->f_rt);
+ ro->ro_lle = __DEVOLATILE(struct llentry *, fle->f_lle);
+
+}
+#endif /* INET6 */
+
static bitstr_t *
flowtable_mask(struct flowtable *ft)
{
@@ -472,7 +870,8 @@ flow_stale(struct flowtable *ft, struct flentry *fle)
|| ((fle->f_rt->rt_flags & RTF_HOST) &&
((fle->f_rt->rt_flags & (RTF_UP))
!= (RTF_UP)))
- || (fle->f_rt->rt_ifp == NULL))
+ || (fle->f_rt->rt_ifp == NULL)
+ || !RT_LINK_IS_UP(fle->f_rt->rt_ifp))
return (1);
idle_time = time_uptime - fle->f_uptime;
@@ -511,22 +910,78 @@ flowtable_set_hashkey(struct flentry *fle, uint32_t *key)
hashkey[i] = key[i];
}
+static struct flentry *
+flow_alloc(struct flowtable *ft)
+{
+ struct flentry *newfle;
+ uma_zone_t zone;
+
+ newfle = NULL;
+ zone = (ft->ft_flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone;
+
+ newfle = uma_zalloc(zone, M_NOWAIT | M_ZERO);
+ if (newfle != NULL)
+ atomic_add_int(&ft->ft_count, 1);
+ return (newfle);
+}
+
+static void
+flow_free(struct flentry *fle, struct flowtable *ft)
+{
+ uma_zone_t zone;
+
+ zone = (ft->ft_flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone;
+ atomic_add_int(&ft->ft_count, -1);
+ uma_zfree(zone, fle);
+}
+
+static int
+flow_full(struct flowtable *ft)
+{
+ boolean_t full;
+ uint32_t count;
+
+ full = ft->ft_full;
+ count = ft->ft_count;
+
+ if (full && (count < (V_flowtable_nmbflows - (V_flowtable_nmbflows >> 3))))
+ ft->ft_full = FALSE;
+ else if (!full && (count > (V_flowtable_nmbflows - (V_flowtable_nmbflows >> 5))))
+ ft->ft_full = TRUE;
+
+ if (full && !ft->ft_full) {
+ flowclean_freq = 4*hz;
+ if ((ft->ft_flags & FL_HASH_ALL) == 0)
+ ft->ft_udp_idle = ft->ft_fin_wait_idle =
+ ft->ft_syn_idle = ft->ft_tcp_idle = 5;
+ cv_broadcast(&flowclean_cv);
+ } else if (!full && ft->ft_full) {
+ flowclean_freq = 20*hz;
+ if ((ft->ft_flags & FL_HASH_ALL) == 0)
+ ft->ft_udp_idle = ft->ft_fin_wait_idle =
+ ft->ft_syn_idle = ft->ft_tcp_idle = 30;
+ }
+
+ return (ft->ft_full);
+}
+
static int
flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
- uint8_t proto, uint32_t fibnum, struct route *ro, uint16_t flags)
+ uint32_t fibnum, struct route *ro, uint16_t flags)
{
struct flentry *fle, *fletail, *newfle, **flep;
+ struct flowtable_stats *fs = &ft->ft_stats[curcpu];
int depth;
- uma_zone_t flezone;
bitstr_t *mask;
+ uint8_t proto;
- flezone = (flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone;
- newfle = uma_zalloc(flezone, M_NOWAIT | M_ZERO);
+ newfle = flow_alloc(ft);
if (newfle == NULL)
return (ENOMEM);
newfle->f_flags |= (flags & FL_IPV6);
-
+ proto = flags_to_proto(flags);
+
FL_ENTRY_LOCK(ft, hash);
mask = flowtable_mask(ft);
flep = flowtable_entry(ft, hash);
@@ -539,7 +994,7 @@ flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
}
depth = 0;
- V_flowtable_collisions++;
+ fs->ft_collisions++;
/*
* find end of list and make sure that we were not
* preempted by another thread handling this flow
@@ -551,8 +1006,10 @@ flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
* or we lost a race to insert
*/
FL_ENTRY_UNLOCK(ft, hash);
- uma_zfree((newfle->f_flags & FL_IPV6) ?
- V_flow_ipv6_zone : V_flow_ipv4_zone, newfle);
+ flow_free(newfle, ft);
+
+ if (flags & FL_OVERWRITE)
+ goto skip;
return (EEXIST);
}
/*
@@ -565,8 +1022,8 @@ flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
fle = fle->f_next;
}
- if (depth > V_flowtable_max_depth)
- V_flowtable_max_depth = depth;
+ if (depth > fs->ft_max_depth)
+ fs->ft_max_depth = depth;
fletail->f_next = newfle;
fle = newfle;
skip:
@@ -582,6 +1039,35 @@ skip:
return (0);
}
+int
+kern_flowtable_insert(struct flowtable *ft,
+ struct sockaddr_storage *ssa, struct sockaddr_storage *dsa,
+ struct route *ro, uint32_t fibnum, int flags)
+{
+ uint32_t key[9], hash;
+
+ flags = (ft->ft_flags | flags | FL_OVERWRITE);
+ hash = 0;
+
+#ifdef INET
+ if (ssa->ss_family == AF_INET)
+ hash = ipv4_flow_lookup_hash_internal((struct sockaddr_in *)ssa,
+ (struct sockaddr_in *)dsa, key, flags);
+#endif
+#ifdef INET6
+ if (ssa->ss_family == AF_INET6)
+ hash = ipv6_flow_lookup_hash_internal((struct sockaddr_in6 *)ssa,
+ (struct sockaddr_in6 *)dsa, key, flags);
+#endif
+ if (ro->ro_rt == NULL || ro->ro_lle == NULL)
+ return (EINVAL);
+
+ FLDPRINTF(ft, FL_DEBUG,
+ "kern_flowtable_insert: key=%x:%x:%x hash=%x fibnum=%d flags=%x\n",
+ key[0], key[1], key[2], hash, fibnum, flags);
+ return (flowtable_insert(ft, hash, key, fibnum, ro, flags));
+}
+
static int
flowtable_key_equal(struct flentry *fle, uint32_t *key)
{
@@ -595,7 +1081,7 @@ flowtable_key_equal(struct flentry *fle, uint32_t *key)
nwords = 3;
hashkey = ((struct flentry_v6 *)fle)->fl_flow.ipf_key;
}
-
+
for (i = 0; i < nwords; i++)
if (hashkey[i] != key[i])
return (0);
@@ -603,44 +1089,95 @@ flowtable_key_equal(struct flentry *fle, uint32_t *key)
return (1);
}
-int
-flowtable_lookup(struct flowtable *ft, struct mbuf *m, struct route *ro, uint32_t fibnum)
+struct flentry *
+flowtable_lookup_mbuf(struct flowtable *ft, struct mbuf *m, int af)
+{
+ struct flentry *fle = NULL;
+
+#ifdef INET
+ if (af == AF_INET)
+ fle = flowtable_lookup_mbuf4(ft, m);
+#endif
+#ifdef INET6
+ if (af == AF_INET6)
+ fle = flowtable_lookup_mbuf6(ft, m);
+#endif
+ if (fle != NULL && m != NULL && (m->m_flags & M_FLOWID) == 0) {
+ m->m_flags |= M_FLOWID;
+ m->m_pkthdr.flowid = fle->f_fhash;
+ }
+ return (fle);
+}
+
+struct flentry *
+flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa,
+ struct sockaddr_storage *dsa, uint32_t fibnum, int flags)
{
uint32_t key[9], hash;
struct flentry *fle;
- uint16_t flags;
+ struct flowtable_stats *fs = &ft->ft_stats[curcpu];
uint8_t proto = 0;
int error = 0;
struct rtentry *rt;
struct llentry *lle;
-
- flags = ft->ft_flags;
- ro->ro_rt = NULL;
- ro->ro_lle = NULL;
-
- /*
- * The internal hash lookup is the only IPv4 specific bit
- * remaining
- *
- * XXX BZ: to add IPv6 support just add a check for the
- * address type in m and ro and an equivalent ipv6 lookup
- * function - the rest of the code should automatically
- * handle an ipv6 flow (note that m can be NULL in which
- * case ro will be set)
- */
- hash = ipv4_flow_lookup_hash_internal(m, ro, key,
- &flags, &proto);
-
+ struct route sro, *ro;
+ struct route_in6 sro6;
+
+ sro.ro_rt = sro6.ro_rt = NULL;
+ sro.ro_lle = sro6.ro_lle = NULL;
+ ro = NULL;
+ hash = 0;
+ flags |= ft->ft_flags;
+ proto = flags_to_proto(flags);
+#ifdef INET
+ if (ssa->ss_family == AF_INET) {
+ struct sockaddr_in *ssin, *dsin;
+
+ ro = &sro;
+ memcpy(&ro->ro_dst, dsa, sizeof(struct sockaddr_in));
+ /*
+ * The harvested source and destination addresses
+ * may contain port information if the packet is
+ * from a transport protocol (e.g. TCP/UDP). The
+ * port field must be cleared before performing
+ * a route lookup.
+ */
+ ((struct sockaddr_in *)&ro->ro_dst)->sin_port = 0;
+ dsin = (struct sockaddr_in *)dsa;
+ ssin = (struct sockaddr_in *)ssa;
+ if ((dsin->sin_addr.s_addr == ssin->sin_addr.s_addr) ||
+ (ntohl(dsin->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
+ (ntohl(ssin->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+ return (NULL);
+
+ hash = ipv4_flow_lookup_hash_internal(ssin, dsin, key, flags);
+ }
+#endif
+#ifdef INET6
+ if (ssa->ss_family == AF_INET6) {
+ struct sockaddr_in6 *ssin6, *dsin6;
+
+ ro = (struct route *)&sro6;
+ memcpy(&sro6.ro_dst, dsa,
+ sizeof(struct sockaddr_in6));
+ ((struct sockaddr_in6 *)&ro->ro_dst)->sin6_port = 0;
+ dsin6 = (struct sockaddr_in6 *)dsa;
+ ssin6 = (struct sockaddr_in6 *)ssa;
+
+ flags |= FL_IPV6;
+ hash = ipv6_flow_lookup_hash_internal(ssin6, dsin6, key, flags);
+ }
+#endif
/*
* Ports are zero and this isn't a transmit cache
* - thus not a protocol for which we need to keep
* state
- * FL_HASH_PORTS => key[0] != 0 for TCP || UDP || SCTP
+ * FL_HASH_ALL => key[0] != 0 for TCP || UDP || SCTP
*/
- if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_HASH_PORTS)))
- return (ENOENT);
+ if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_HASH_ALL)))
+ return (NULL);
- V_flowtable_lookups++;
+ fs->ft_lookups++;
FL_ENTRY_LOCK(ft, hash);
if ((fle = FL_ENTRY(ft, hash)) == NULL) {
FL_ENTRY_UNLOCK(ft, hash);
@@ -656,21 +1193,21 @@ keycheck:
&& (fibnum == fle->f_fibnum)
&& (rt->rt_flags & RTF_UP)
&& (rt->rt_ifp != NULL)) {
- V_flowtable_hits++;
+ fs->ft_hits++;
fle->f_uptime = time_uptime;
fle->f_flags |= flags;
- ro->ro_rt = rt;
- ro->ro_lle = lle;
FL_ENTRY_UNLOCK(ft, hash);
- return (0);
+ return (fle);
} else if (fle->f_next != NULL) {
fle = fle->f_next;
goto keycheck;
}
FL_ENTRY_UNLOCK(ft, hash);
-
uncached:
- V_flowtable_misses++;
+ if (flags & FL_NOAUTO || flow_full(ft))
+ return (NULL);
+
+ fs->ft_misses++;
/*
* This bit of code ends up locking the
* same route 3 times (just like ip_output + ether_output)
@@ -683,36 +1220,64 @@ uncached:
* receive the route locked
*/
+#ifdef INVARIANTS
+ if ((ro->ro_dst.sa_family != AF_INET) &&
+ (ro->ro_dst.sa_family != AF_INET6))
+ panic("sa_family == %d\n", ro->ro_dst.sa_family);
+#endif
+
ft->ft_rtalloc(ro, hash, fibnum);
if (ro->ro_rt == NULL)
error = ENETUNREACH;
else {
struct llentry *lle = NULL;
- struct sockaddr *l3addr;
+ struct sockaddr_storage *l3addr;
struct rtentry *rt = ro->ro_rt;
struct ifnet *ifp = rt->rt_ifp;
if (ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) {
RTFREE(rt);
ro->ro_rt = NULL;
- return (ENOENT);
+ return (NULL);
}
+#ifdef INET6
+ if (ssa->ss_family == AF_INET6) {
+ struct sockaddr_in6 *dsin6;
+
+ dsin6 = (struct sockaddr_in6 *)dsa;
+ if (in6_localaddr(&dsin6->sin6_addr)) {
+ RTFREE(rt);
+ ro->ro_rt = NULL;
+ return (NULL);
+ }
- if (rt->rt_flags & RTF_GATEWAY)
- l3addr = rt->rt_gateway;
- else
- l3addr = &ro->ro_dst;
- llentry_update(&lle, LLTABLE(ifp), l3addr, ifp);
+ if (rt->rt_flags & RTF_GATEWAY)
+ l3addr = (struct sockaddr_storage *)rt->rt_gateway;
+
+ else
+ l3addr = (struct sockaddr_storage *)&ro->ro_dst;
+ llentry_update(&lle, LLTABLE6(ifp), l3addr, ifp);
+ }
+#endif
+#ifdef INET
+ if (ssa->ss_family == AF_INET) {
+ if (rt->rt_flags & RTF_GATEWAY)
+ l3addr = (struct sockaddr_storage *)rt->rt_gateway;
+ else
+ l3addr = (struct sockaddr_storage *)&ro->ro_dst;
+ llentry_update(&lle, LLTABLE(ifp), l3addr, ifp);
+ }
+
+#endif
ro->ro_lle = lle;
if (lle == NULL) {
RTFREE(rt);
ro->ro_rt = NULL;
- return (ENOENT);
+ return (NULL);
}
- error = flowtable_insert(ft, hash, key, proto, fibnum,
- ro, flags);
-
+ error = flowtable_insert(ft, hash, key, fibnum, ro, flags);
+
if (error) {
RTFREE(rt);
LLE_FREE(lle);
@@ -721,7 +1286,7 @@ uncached:
}
}
- return (error);
+ return ((error) ? NULL : fle);
}
/*
@@ -730,7 +1295,7 @@ uncached:
#define calloc(count, size) malloc((count)*(size), M_DEVBUF, M_WAITOK|M_ZERO)
struct flowtable *
-flowtable_alloc(int nentry, int flags)
+flowtable_alloc(char *name, int nentry, int flags)
{
struct flowtable *ft, *fttail;
int i;
@@ -742,7 +1307,8 @@ flowtable_alloc(int nentry, int flags)
ft = malloc(sizeof(struct flowtable),
M_RTABLE, M_WAITOK | M_ZERO);
-
+
+ ft->ft_name = name;
ft->ft_flags = flags;
ft->ft_size = nentry;
#ifdef RADIX_MPATH
@@ -783,7 +1349,7 @@ flowtable_alloc(int nentry, int flags)
* just a cache - so everything is eligible for
* replacement after 5s of non-use
*/
- if (flags & FL_HASH_PORTS) {
+ if (flags & FL_HASH_ALL) {
ft->ft_udp_idle = V_flowtable_udp_expire;
ft->ft_syn_idle = V_flowtable_syn_expire;
ft->ft_fin_wait_idle = V_flowtable_fin_wait_expire;
@@ -816,7 +1382,7 @@ flowtable_alloc(int nentry, int flags)
*
*/
static void
-fle_free(struct flentry *fle)
+fle_free(struct flentry *fle, struct flowtable *ft)
{
struct rtentry *rt;
struct llentry *lle;
@@ -825,8 +1391,7 @@ fle_free(struct flentry *fle)
lle = __DEVOLATILE(struct llentry *, fle->f_lle);
RTFREE(rt);
LLE_FREE(lle);
- uma_zfree((fle->f_flags & FL_IPV6) ?
- V_flow_ipv6_zone : V_flow_ipv4_zone, fle);
+ flow_free(fle, ft);
}
static void
@@ -836,7 +1401,8 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt)
struct flentry *fle, **flehead, *fleprev;
struct flentry *flefreehead, *flefreetail, *fletmp;
bitstr_t *mask, *tmpmask;
-
+ struct flowtable_stats *fs = &ft->ft_stats[curcpu];
+
flefreehead = flefreetail = NULL;
mask = flowtable_mask(ft);
tmpmask = ft->ft_tmpmask;
@@ -853,12 +1419,12 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt)
curbit);
break;
}
-
+
FL_ENTRY_LOCK(ft, curbit);
flehead = flowtable_entry(ft, curbit);
fle = fleprev = *flehead;
- V_flowtable_free_checks++;
+ fs->ft_free_checks++;
#ifdef DIAGNOSTIC
if (fle == NULL && curbit > 0) {
log(LOG_ALERT,
@@ -896,7 +1462,7 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt)
fleprev->f_next = fle->f_next;
fle = fleprev->f_next;
}
-
+
if (flefreehead == NULL)
flefreehead = flefreetail = fletmp;
else {
@@ -915,8 +1481,8 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt)
while ((fle = flefreehead) != NULL) {
flefreehead = fle->f_next;
count++;
- V_flowtable_frees++;
- fle_free(fle);
+ fs->ft_frees++;
+ fle_free(fle, ft);
}
if (V_flowtable_debug && count)
log(LOG_DEBUG, "freed %d flow entries\n", count);
@@ -926,6 +1492,7 @@ void
flowtable_route_flush(struct flowtable *ft, struct rtentry *rt)
{
int i;
+
if (ft->ft_flags & FL_PCPU) {
for (i = 0; i <= mp_maxid; i++) {
if (CPU_ABSENT(i))
@@ -1007,7 +1574,7 @@ flowtable_cleaner(void)
*/
mtx_lock(&flowclean_lock);
cv_broadcast(&flowclean_cv);
- cv_timedwait(&flowclean_cv, &flowclean_lock, 10*hz);
+ cv_timedwait(&flowclean_cv, &flowclean_lock, flowclean_freq);
mtx_unlock(&flowclean_lock);
}
}
@@ -1016,7 +1583,7 @@ static void
flowtable_flush(void *unused __unused)
{
uint64_t start;
-
+
mtx_lock(&flowclean_lock);
start = flowclean_cycles;
while (start == flowclean_cycles) {
@@ -1037,6 +1604,7 @@ static void
flowtable_init_vnet(const void *unused __unused)
{
+ V_flowtable_nmbflows = 1024 + maxusers * 64 * mp_ncpus;
V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4),
NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);
V_flow_ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6),
@@ -1045,7 +1613,7 @@ flowtable_init_vnet(const void *unused __unused)
uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows);
V_flowtable_ready = 1;
}
-VNET_SYSINIT(flowtable_init_vnet, SI_SUB_KTHREAD_INIT, SI_ORDER_MIDDLE,
+VNET_SYSINIT(flowtable_init_vnet, SI_SUB_SMP, SI_ORDER_ANY,
flowtable_init_vnet, NULL);
static void
@@ -1056,8 +1624,9 @@ flowtable_init(const void *unused __unused)
mtx_init(&flowclean_lock, "flowclean lock", NULL, MTX_DEF);
EVENTHANDLER_REGISTER(ifnet_departure_event, flowtable_flush, NULL,
EVENTHANDLER_PRI_ANY);
+ flowclean_freq = 20*hz;
}
-SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
+SYSINIT(flowtable_init, SI_SUB_SMP, SI_ORDER_MIDDLE,
flowtable_init, NULL);
@@ -1076,6 +1645,19 @@ VNET_SYSUNINIT(flowtable_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
#endif
#ifdef DDB
+static uint32_t *
+flowtable_get_hashkey(struct flentry *fle)
+{
+ uint32_t *hashkey;
+
+ if (fle->f_flags & FL_IPV6)
+ hashkey = ((struct flentry_v4 *)fle)->fl_flow.ipf_key;
+ else
+ hashkey = ((struct flentry_v6 *)fle)->fl_flow.ipf_key;
+
+ return (hashkey);
+}
+
static bitstr_t *
flowtable_mask_pcpu(struct flowtable *ft, int cpuid)
{
@@ -1108,17 +1690,64 @@ static void
flow_show(struct flowtable *ft, struct flentry *fle)
{
int idle_time;
- int rt_valid;
+ int rt_valid, ifp_valid;
+ uint16_t sport, dport;
+ uint32_t *hashkey;
+ char saddr[4*sizeof "123"], daddr[4*sizeof "123"];
+ volatile struct rtentry *rt;
+ struct ifnet *ifp = NULL;
idle_time = (int)(time_uptime - fle->f_uptime);
- rt_valid = fle->f_rt != NULL;
- db_printf("hash=0x%08x idle_time=%03d rt=%p ifp=%p",
- fle->f_fhash, idle_time,
- fle->f_rt, rt_valid ? fle->f_rt->rt_ifp : NULL);
- if (rt_valid && (fle->f_rt->rt_flags & RTF_UP))
- db_printf(" RTF_UP ");
+ rt = fle->f_rt;
+ rt_valid = rt != NULL;
+ if (rt_valid)
+ ifp = rt->rt_ifp;
+ ifp_valid = ifp != NULL;
+ hashkey = flowtable_get_hashkey(fle);
+ if (fle->f_flags & FL_IPV6)
+ goto skipaddr;
+
+ inet_ntoa_r(*(struct in_addr *) &hashkey[2], daddr);
+ if (ft->ft_flags & FL_HASH_ALL) {
+ inet_ntoa_r(*(struct in_addr *) &hashkey[1], saddr);
+ sport = ntohs(((uint16_t *)hashkey)[0]);
+ dport = ntohs(((uint16_t *)hashkey)[1]);
+ db_printf("%s:%d->%s:%d",
+ saddr, sport, daddr,
+ dport);
+ } else
+ db_printf("%s ", daddr);
+
+skipaddr:
if (fle->f_flags & FL_STALE)
db_printf(" FL_STALE ");
+ if (fle->f_flags & FL_TCP)
+ db_printf(" FL_TCP ");
+ if (fle->f_flags & FL_UDP)
+ db_printf(" FL_UDP ");
+ if (rt_valid) {
+ if (rt->rt_flags & RTF_UP)
+ db_printf(" RTF_UP ");
+ }
+ if (ifp_valid) {
+ if (ifp->if_flags & IFF_LOOPBACK)
+ db_printf(" IFF_LOOPBACK ");
+ if (ifp->if_flags & IFF_UP)
+ db_printf(" IFF_UP ");
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ db_printf(" IFF_POINTOPOINT ");
+ }
+ if (fle->f_flags & FL_IPV6)
+ db_printf("\n\tkey=%08x:%08x:%08x%08x:%08x:%08x%08x:%08x:%08x",
+ hashkey[0], hashkey[1], hashkey[2],
+ hashkey[3], hashkey[4], hashkey[5],
+ hashkey[6], hashkey[7], hashkey[8]);
+ else
+ db_printf("\n\tkey=%08x:%08x:%08x ",
+ hashkey[0], hashkey[1], hashkey[2]);
+ db_printf("hash=%08x idle_time=%03d"
+ "\n\tfibnum=%02d rt=%p",
+ fle->f_fhash, idle_time, fle->f_fibnum, fle->f_rt);
db_printf("\n");
}
@@ -1129,7 +1758,8 @@ flowtable_show(struct flowtable *ft, int cpuid)
struct flentry *fle, **flehead;
bitstr_t *mask, *tmpmask;
- db_printf("cpu: %d\n", cpuid);
+ if (cpuid != -1)
+ db_printf("cpu: %d\n", cpuid);
mask = flowtable_mask_pcpu(ft, cpuid);
tmpmask = ft->ft_tmpmask;
memcpy(tmpmask, mask, ft->ft_size/8);
@@ -1166,6 +1796,7 @@ flowtable_show_vnet(void)
ft = V_flow_list_head;
while (ft != NULL) {
+ printf("name: %s\n", ft->ft_name);
if (ft->ft_flags & FL_PCPU) {
for (i = 0; i <= mp_maxid; i++) {
if (CPU_ABSENT(i))
@@ -1173,7 +1804,7 @@ flowtable_show_vnet(void)
flowtable_show(ft, i);
}
} else {
- flowtable_show(ft, 0);
+ flowtable_show(ft, -1);
}
ft = ft->ft_next;
}
diff --git a/sys/net/flowtable.h b/sys/net/flowtable.h
index 7d7abdf..6e79a3c 100644
--- a/sys/net/flowtable.h
+++ b/sys/net/flowtable.h
@@ -1,6 +1,6 @@
/**************************************************************************
-Copyright (c) 2008-2009, BitGravity Inc.
+Copyright (c) 2008-2010, BitGravity Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -34,24 +34,49 @@ $FreeBSD$
#ifdef _KERNEL
-#define FL_HASH_PORTS (1<<0) /* hash 4-tuple + protocol */
+#define FL_HASH_ALL (1<<0) /* hash 4-tuple + protocol */
#define FL_PCPU (1<<1) /* pcpu cache */
+#define FL_NOAUTO (1<<2) /* don't automatically add flentry on miss */
+
+#define FL_TCP (1<<11)
+#define FL_SCTP (1<<12)
+#define FL_UDP (1<<13)
+#define FL_DEBUG (1<<14)
+#define FL_DEBUG_ALL (1<<15)
struct flowtable;
+struct flentry;
+struct route;
+struct route_in6;
+
VNET_DECLARE(struct flowtable *, ip_ft);
#define V_ip_ft VNET(ip_ft)
-struct flowtable *flowtable_alloc(int nentry, int flags);
+VNET_DECLARE(struct flowtable *, ip6_ft);
+#define V_ip6_ft VNET(ip6_ft)
+
+struct flowtable *flowtable_alloc(char *name, int nentry, int flags);
/*
* Given a flow table, look up the L3 and L2 information and
* return it in the route.
*
*/
-int flowtable_lookup(struct flowtable *ft, struct mbuf *m,
- struct route *ro, uint32_t fibnum);
+struct flentry *flowtable_lookup_mbuf(struct flowtable *ft, struct mbuf *m, int af);
+
+struct flentry *flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa,
+ struct sockaddr_storage *dsa, uint32_t fibnum, int flags);
+int kern_flowtable_insert(struct flowtable *ft, struct sockaddr_storage *ssa,
+ struct sockaddr_storage *dsa, struct route *ro, uint32_t fibnum, int flags);
+
+void flow_invalidate(struct flentry *fl);
void flowtable_route_flush(struct flowtable *ft, struct rtentry *rt);
+void flow_to_route(struct flentry *fl, struct route *ro);
+
+void flow_to_route_in6(struct flentry *fl, struct route_in6 *ro);
+
+
#endif /* _KERNEL */
#endif
diff --git a/sys/net/if.c b/sys/net/if.c
index 38b1d50..98c8afa 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -897,14 +897,20 @@ if_detach_internal(struct ifnet *ifp, int vmove)
devctl_notify("IFNET", ifp->if_xname, "DETACH", NULL);
if_delgroups(ifp);
+ /*
+ * We cannot hold the lock over dom_ifdetach calls as they might
+ * sleep, for example trying to drain a callout, thus open up the
+ * theoretical race with re-attaching.
+ */
IF_AFDATA_LOCK(ifp);
- for (dp = domains; dp; dp = dp->dom_next) {
+ i = ifp->if_afdata_initialized;
+ ifp->if_afdata_initialized = 0;
+ IF_AFDATA_UNLOCK(ifp);
+ for (dp = domains; i > 0 && dp; dp = dp->dom_next) {
if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
(*dp->dom_ifdetach)(ifp,
ifp->if_afdata[dp->dom_family]);
}
- ifp->if_afdata_initialized = 0;
- IF_AFDATA_UNLOCK(ifp);
}
#ifdef VIMAGE
@@ -2043,14 +2049,13 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
case SIOCGIFDESCR:
error = 0;
sx_slock(&ifdescr_sx);
- if (ifp->if_description == NULL) {
- ifr->ifr_buffer.length = 0;
+ if (ifp->if_description == NULL)
error = ENOMSG;
- } else {
+ else {
/* space for terminating nul */
descrlen = strlen(ifp->if_description) + 1;
if (ifr->ifr_buffer.length < descrlen)
- error = ENAMETOOLONG;
+ ifr->ifr_buffer.buffer = NULL;
else
error = copyout(ifp->if_description,
ifr->ifr_buffer.buffer, descrlen);
diff --git a/sys/net/if.h b/sys/net/if.h
index e226654..ae0daf5 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -219,6 +219,7 @@ struct if_data {
#define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */
#define IFCAP_POLLING_NOCOUNT 0x20000 /* polling ticks cannot be fragmented */
#define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */
+#define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */
#define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM)
#define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6)
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index d985e98..5f33dd5 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -135,7 +135,6 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <netinet/ip_fw.h>
#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/ip_dummynet.h>
/*
* Size of the route hash table. Must be a power of two.
@@ -3073,15 +3072,15 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
if (mtag == NULL) {
args.rule.slot = 0;
} else {
- struct dn_pkt_tag *dn_tag;
+ struct ipfw_rule_ref *r;
/* XXX can we free the tag after use ? */
mtag->m_tag_id = PACKET_TAG_NONE;
- dn_tag = (struct dn_pkt_tag *)(mtag + 1);
+ r = (struct ipfw_rule_ref *)(mtag + 1);
/* packet already partially processed ? */
- if (dn_tag->rule.slot != 0 && V_fw_one_pass)
+ if (r->info & IPFW_ONEPASS)
goto ipfwpass;
- args.rule = dn_tag->rule;
+ args.rule = *r;
}
args.m = *mp;
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
index 0dd20fb..c02737b 100644
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -196,10 +196,11 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
int
if_clone_destroy(const char *name)
{
+ int err;
struct if_clone *ifc;
struct ifnet *ifp;
- ifp = ifunit(name);
+ ifp = ifunit_ref(name);
if (ifp == NULL)
return (ENXIO);
@@ -221,10 +222,14 @@ if_clone_destroy(const char *name)
}
#endif
IF_CLONERS_UNLOCK();
- if (ifc == NULL)
+ if (ifc == NULL) {
+ if_rele(ifp);
return (EINVAL);
+ }
- return (if_clone_destroyif(ifc, ifp));
+ err = if_clone_destroyif(ifc, ifp);
+ if_rele(ifp);
+ return err;
}
/*
@@ -234,6 +239,7 @@ int
if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
{
int err;
+ struct ifnet *ifcifp;
if (ifc->ifc_destroy == NULL)
return(EOPNOTSUPP);
@@ -246,8 +252,17 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
CURVNET_SET_QUIET(ifp->if_vnet);
IF_CLONE_LOCK(ifc);
- IFC_IFLIST_REMOVE(ifc, ifp);
+ LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
+ if (ifcifp == ifp) {
+ IFC_IFLIST_REMOVE(ifc, ifp);
+ break;
+ }
+ }
IF_CLONE_UNLOCK(ifc);
+ if (ifcifp == NULL) {
+ CURVNET_RESTORE();
+ return (ENXIO); /* ifp is not on the list. */
+ }
if_delgroup(ifp, ifc->ifc_name);
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index a6b7a7c..3164182 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2008 The FreeBSD Foundation
- * Copyright (c) 2009 Bjoern A. Zeeb <bz@FreeBSD.org>
+ * Copyright (c) 2009-2010 Bjoern A. Zeeb <bz@FreeBSD.org>
* All rights reserved.
*
* This software was developed by CK Software GmbH under sponsorship
@@ -256,6 +256,9 @@ epair_nh_sintr(struct mbuf *m)
(*ifp->if_input)(ifp, m);
sc = ifp->if_softc;
EPAIR_REFCOUNT_RELEASE(&sc->refcount);
+ EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
+ ("%s: ifp=%p sc->refcount not >= 1: %d",
+ __func__, ifp, sc->refcount));
DPRINTF("ifp=%p refcount=%u\n", ifp, sc->refcount);
}
@@ -292,8 +295,16 @@ epair_nh_drainedcpu(u_int cpuid)
IFQ_LOCK(&ifp->if_snd);
if (IFQ_IS_EMPTY(&ifp->if_snd)) {
+ struct epair_softc *sc;
+
STAILQ_REMOVE(&epair_dpcpu->epair_ifp_drain_list,
elm, epair_ifp_drain, ifp_next);
+ /* The cached ifp goes off the list. */
+ sc = ifp->if_softc;
+ EPAIR_REFCOUNT_RELEASE(&sc->refcount);
+ EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
+ ("%s: ifp=%p sc->refcount not >= 1: %d",
+ __func__, ifp, sc->refcount));
free(elm, M_EPAIR);
}
IFQ_UNLOCK(&ifp->if_snd);
@@ -312,14 +323,50 @@ epair_nh_drainedcpu(u_int cpuid)
/*
* Network interface (`if') related functions.
*/
+static void
+epair_remove_ifp_from_draining(struct ifnet *ifp)
+{
+ struct epair_dpcpu *epair_dpcpu;
+ struct epair_ifp_drain *elm, *tvar;
+ u_int cpuid;
+
+ for (cpuid = 0; cpuid <= mp_maxid; cpuid++) {
+ if (CPU_ABSENT(cpuid))
+ continue;
+
+ epair_dpcpu = DPCPU_ID_PTR(cpuid, epair_dpcpu);
+ EPAIR_LOCK(epair_dpcpu);
+ STAILQ_FOREACH_SAFE(elm, &epair_dpcpu->epair_ifp_drain_list,
+ ifp_next, tvar) {
+ if (ifp == elm->ifp) {
+ struct epair_softc *sc;
+
+ STAILQ_REMOVE(
+ &epair_dpcpu->epair_ifp_drain_list, elm,
+ epair_ifp_drain, ifp_next);
+ /* The cached ifp goes off the list. */
+ sc = ifp->if_softc;
+ EPAIR_REFCOUNT_RELEASE(&sc->refcount);
+ EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
+ ("%s: ifp=%p sc->refcount not >= 1: %d",
+ __func__, ifp, sc->refcount));
+ free(elm, M_EPAIR);
+ }
+ }
+ EPAIR_UNLOCK(epair_dpcpu);
+ }
+}
+
static int
epair_add_ifp_for_draining(struct ifnet *ifp)
{
struct epair_dpcpu *epair_dpcpu;
- struct epair_softc *sc = sc = ifp->if_softc;
+ struct epair_softc *sc;
struct epair_ifp_drain *elm = NULL;
+ sc = ifp->if_softc;
epair_dpcpu = DPCPU_ID_PTR(sc->cpuid, epair_dpcpu);
+ EPAIR_LOCK_ASSERT(epair_dpcpu);
STAILQ_FOREACH(elm, &epair_dpcpu->epair_ifp_drain_list, ifp_next)
if (elm->ifp == ifp)
break;
@@ -332,6 +379,8 @@ epair_add_ifp_for_draining(struct ifnet *ifp)
return (ENOMEM);
elm->ifp = ifp;
+ /* Add a reference for the ifp pointer on the list. */
+ EPAIR_REFCOUNT_AQUIRE(&sc->refcount);
STAILQ_INSERT_TAIL(&epair_dpcpu->epair_ifp_drain_list, elm, ifp_next);
return (0);
@@ -395,13 +444,15 @@ epair_start_locked(struct ifnet *ifp)
/* Someone else received the packet. */
oifp->if_ipackets++;
} else {
+ /* The packet was freed already. */
epair_dpcpu->epair_drv_flags |= IFF_DRV_OACTIVE;
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- if (epair_add_ifp_for_draining(ifp)) {
- ifp->if_oerrors++;
- m_freem(m);
- }
+ (void) epair_add_ifp_for_draining(ifp);
+ ifp->if_oerrors++;
EPAIR_REFCOUNT_RELEASE(&sc->refcount);
+ EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
+ ("%s: ifp=%p sc->refcount not >= 1: %d",
+ __func__, oifp, sc->refcount));
}
}
}
@@ -524,9 +575,13 @@ epair_transmit_locked(struct ifnet *ifp, struct mbuf *m)
oifp->if_ipackets++;
} else {
/* The packet was freed already. */
- EPAIR_REFCOUNT_RELEASE(&sc->refcount);
epair_dpcpu->epair_drv_flags |= IFF_DRV_OACTIVE;
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ ifp->if_oerrors++;
+ EPAIR_REFCOUNT_RELEASE(&sc->refcount);
+ EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
+ ("%s: ifp=%p sc->refcount not >= 1: %d",
+ __func__, oifp, sc->refcount));
}
return (error);
@@ -548,22 +603,18 @@ epair_transmit(struct ifnet *ifp, struct mbuf *m)
static void
epair_qflush(struct ifnet *ifp)
{
- struct epair_dpcpu *epair_dpcpu;
struct epair_softc *sc;
- struct ifaltq *ifq;
sc = ifp->if_softc;
- epair_dpcpu = DPCPU_ID_PTR(sc->cpuid, epair_dpcpu);
- EPAIR_LOCK(epair_dpcpu);
- ifq = &ifp->if_snd;
- DPRINTF("ifp=%p sc refcnt=%u ifq_len=%u\n",
- ifp, sc->refcount, ifq->ifq_len);
+ KASSERT(sc != NULL, ("%s: ifp=%p, epair_softc gone? sc=%p\n",
+ __func__, ifp, sc));
/*
- * Instead of calling EPAIR_REFCOUNT_RELEASE(&sc->refcount);
- * n times, just subtract for the cleanup.
+ * Remove this ifp from all backpointer lists. The interface will not
+ * usable for flushing anyway nor should it have anything to flush
+ * after if_qflush().
*/
- sc->refcount -= ifq->ifq_len;
- EPAIR_UNLOCK(epair_dpcpu);
+ epair_remove_ifp_from_draining(ifp);
+
if (sc->if_qflush)
sc->if_qflush(ifp);
}
@@ -828,8 +879,8 @@ epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
*/
DPRINTF("sca refcnt=%u scb refcnt=%u\n", sca->refcount, scb->refcount);
EPAIR_REFCOUNT_ASSERT(sca->refcount == 1 && scb->refcount == 1,
- ("%s: sca->refcount!=1: %d || scb->refcount!=1: %d",
- __func__, sca->refcount, scb->refcount));
+ ("%s: ifp=%p sca->refcount!=1: %d || ifp=%p scb->refcount!=1: %d",
+ __func__, ifp, sca->refcount, oifp, scb->refcount));
/*
* Get rid of our second half.
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index ac2ab05..bbf9753 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -73,7 +73,6 @@
#include <netinet/ip_var.h>
#include <netinet/ip_fw.h>
#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/ip_dummynet.h>
#endif
#ifdef INET6
#include <netinet6/nd6.h>
@@ -474,15 +473,15 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared)
if (mtag == NULL) {
args.rule.slot = 0;
} else {
- struct dn_pkt_tag *dn_tag;
+ /* dummynet packet, already partially processed */
+ struct ipfw_rule_ref *r;
/* XXX can we free it after use ? */
mtag->m_tag_id = PACKET_TAG_NONE;
- dn_tag = (struct dn_pkt_tag *)(mtag + 1);
- if (dn_tag->rule.slot != 0 && V_fw_one_pass)
- /* dummynet packet, already partially processed */
+ r = (struct ipfw_rule_ref *)(mtag + 1);
+ if (r->info & IPFW_ONEPASS)
return (1);
- args.rule = dn_tag->rule;
+ args.rule = *r;
}
/*
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 4728780..cb14601 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -484,10 +484,6 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
if (sc->sc_count >= LAGG_MAX_PORTS)
return (ENOSPC);
- /* New lagg port has to be in an idle state */
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
- return (EBUSY);
-
/* Check if port has already been associated to a lagg */
if (ifp->if_lagg != NULL)
return (EBUSY);
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index 5992f6d..c9b41f9 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -27,6 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -42,6 +43,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/rwlock.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
#include <vm/uma.h>
#include <netinet/in.h>
@@ -111,13 +116,13 @@ llentry_free(struct llentry *lle)
/*
* Update an llentry for address dst (equivalent to rtalloc for new-arp)
- * Caller must pass in a valid struct llentry *
+ * Caller must pass in a valid struct llentry * (or NULL)
*
* if found the llentry * is returned referenced and unlocked
*/
int
llentry_update(struct llentry **llep, struct lltable *lt,
- struct sockaddr *dst, struct ifnet *ifp)
+ struct sockaddr_storage *dst, struct ifnet *ifp)
{
struct llentry *la;
@@ -165,9 +170,12 @@ lltable_free(struct lltable *llt)
for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+ int canceled;
- callout_drain(&lle->la_timer);
+ canceled = callout_drain(&lle->la_timer);
LLE_WLOCK(lle);
+ if (canceled)
+ LLE_REMREF(lle);
llentry_free(lle);
}
}
@@ -382,3 +390,134 @@ vnet_lltable_init()
VNET_SYSINIT(vnet_lltable_init, SI_SUB_PSEUDO, SI_ORDER_FIRST,
vnet_lltable_init, NULL);
+#ifdef DDB
+struct llentry_sa {
+ struct llentry base;
+ struct sockaddr l3_addr;
+};
+
+static void
+llatbl_lle_show(struct llentry_sa *la)
+{
+ struct llentry *lle;
+ uint8_t octet[6];
+
+ lle = &la->base;
+ db_printf("lle=%p\n", lle);
+ db_printf(" lle_next=%p\n", lle->lle_next.le_next);
+ db_printf(" lle_lock=%p\n", &lle->lle_lock);
+ db_printf(" lle_tbl=%p\n", lle->lle_tbl);
+ db_printf(" lle_head=%p\n", lle->lle_head);
+ db_printf(" la_hold=%p\n", lle->la_hold);
+ db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire);
+ db_printf(" la_flags=0x%04x\n", lle->la_flags);
+ db_printf(" la_asked=%u\n", lle->la_asked);
+ db_printf(" la_preempt=%u\n", lle->la_preempt);
+ db_printf(" ln_byhint=%u\n", lle->ln_byhint);
+ db_printf(" ln_state=%d\n", lle->ln_state);
+ db_printf(" ln_router=%u\n", lle->ln_router);
+ db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
+ db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
+ bcopy(&lle->ll_addr.mac16, octet, sizeof(octet));
+ db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
+ db_printf(" la_timer=%p\n", &lle->la_timer);
+
+ switch (la->l3_addr.sa_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
+ char l3s[INET_ADDRSTRLEN];
+
+ sin = (struct sockaddr_in *)&la->l3_addr;
+ inet_ntoa_r(sin->sin_addr, l3s);
+ db_printf(" l3_addr=%s\n", l3s);
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
+ char l3s[INET6_ADDRSTRLEN];
+
+ sin6 = (struct sockaddr_in6 *)&la->l3_addr;
+ ip6_sprintf(l3s, &sin6->sin6_addr);
+ db_printf(" l3_addr=%s\n", l3s);
+ break;
+ }
+#endif
+ default:
+ db_printf(" l3_addr=N/A (af=%d)\n", la->l3_addr.sa_family);
+ break;
+ }
+}
+
+DB_SHOW_COMMAND(llentry, db_show_llentry)
+{
+
+ if (!have_addr) {
+ db_printf("usage: show llentry <struct llentry *>\n");
+ return;
+ }
+
+ llatbl_lle_show((struct llentry_sa *)addr);
+}
+
+static void
+llatbl_llt_show(struct lltable *llt)
+{
+ int i;
+ struct llentry *lle;
+
+ db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
+ llt, llt->llt_af, llt->llt_ifp);
+
+ for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+ LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
+
+ llatbl_lle_show((struct llentry_sa *)lle);
+ if (db_pager_quit)
+ return;
+ }
+ }
+}
+
+DB_SHOW_COMMAND(lltable, db_show_lltable)
+{
+
+ if (!have_addr) {
+ db_printf("usage: show lltable <struct lltable *>\n");
+ return;
+ }
+
+ llatbl_llt_show((struct lltable *)addr);
+}
+
+DB_SHOW_ALL_COMMAND(lltables, db_show_all_lltables)
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+ struct lltable *llt;
+
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET_QUIET(vnet_iter);
+#ifdef VIMAGE
+ db_printf("vnet=%p\n", curvnet);
+#endif
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
+ db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n",
+ llt, llt->llt_af, llt->llt_ifp,
+ (llt->llt_ifp != NULL) ?
+ llt->llt_ifp->if_xname : "?");
+ if (have_addr && addr != 0) /* verbose */
+ llatbl_llt_show(llt);
+ if (db_pager_quit) {
+ CURVNET_RESTORE();
+ return;
+ }
+ }
+ CURVNET_RESTORE();
+ }
+}
+#endif
diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index 21357eb..debb416 100644
--- a/sys/net/if_llatbl.h
+++ b/sys/net/if_llatbl.h
@@ -191,7 +191,7 @@ int lltable_sysctl_dumparp(int, struct sysctl_req *);
void llentry_free(struct llentry *);
int llentry_update(struct llentry **, struct lltable *,
- struct sockaddr *, struct ifnet *);
+ struct sockaddr_storage *, struct ifnet *);
/*
* Generic link layer address lookup function.
diff --git a/sys/net/if_media.h b/sys/net/if_media.h
index 1db2766..c937392 100644
--- a/sys/net/if_media.h
+++ b/sys/net/if_media.h
@@ -462,6 +462,7 @@ struct ifmedia_description {
{ IFM_IEEE80211_OFDM3, "OFDM/3Mbps" }, \
{ IFM_IEEE80211_OFDM4, "OFDM/4.5Mbps" }, \
{ IFM_IEEE80211_OFDM27, "OFDM/27Mbps" }, \
+ { IFM_IEEE80211_MCS, "MCS" }, \
{ 0, NULL }, \
}
@@ -500,6 +501,7 @@ struct ifmedia_description {
{ IFM_IEEE80211_OFDM3, "OFDM3" }, \
{ IFM_IEEE80211_OFDM4, "OFDM4.5" }, \
{ IFM_IEEE80211_OFDM27, "OFDM27" }, \
+ { IFM_IEEE80211_MCS, "MCS" }, \
{ 0, NULL }, \
}
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index 93801f1..eb81e81 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -443,6 +443,8 @@ tapcreate(struct cdev *dev)
ifp->if_mtu = ETHERMTU;
ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ ifp->if_capabilities |= IFCAP_LINKSTATE;
+ ifp->if_capenable |= IFCAP_LINKSTATE;
dev->si_drv1 = tp;
tp->tap_dev = dev;
@@ -502,6 +504,7 @@ tapopen(struct cdev *dev, int flag, int mode, struct thread *td)
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
if (tapuponopen)
ifp->if_flags |= IFF_UP;
+ if_link_state_change(ifp, LINK_STATE_UP);
splx(s);
TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, dev2unit(dev));
@@ -547,6 +550,7 @@ tapclose(struct cdev *dev, int foo, int bar, struct thread *td)
} else
mtx_unlock(&tp->tap_mtx);
+ if_link_state_change(ifp, LINK_STATE_DOWN);
funsetown(&tp->tap_sigio);
selwakeuppri(&tp->tap_rsel, PZERO+1);
KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0);
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index 1fa02ac..1da63ba 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -386,6 +386,8 @@ tuncreate(const char *name, struct cdev *dev)
ifp->if_snd.ifq_drv_maxlen = 0;
IFQ_SET_READY(&ifp->if_snd);
knlist_init_mtx(&sc->tun_rsel.si_note, NULL);
+ ifp->if_capabilities |= IFCAP_LINKSTATE;
+ ifp->if_capenable |= IFCAP_LINKSTATE;
if_attach(ifp);
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 4127069..fbca8ad 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -645,7 +645,7 @@ drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
IFQ_UNLOCK(&ifp->if_snd);
return (NULL);
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
IFQ_UNLOCK(&ifp->if_snd);
return (m);
}
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index f665047..01a8297 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1382,9 +1382,9 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCGIFMEDIA:
VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
- error = (*PARENT(ifv)->if_ioctl)(PARENT(ifv),
- SIOCGIFMEDIA, data);
+ p = PARENT(ifv);
VLAN_UNLOCK();
+ error = (*p->if_ioctl)(p, SIOCGIFMEDIA, data);
/* Limit the result to the parent's current config. */
if (error == 0) {
struct ifmediareq *ifmr;
diff --git a/sys/net/radix.c b/sys/net/radix.c
index f092aa1..33fcf82 100644
--- a/sys/net/radix.c
+++ b/sys/net/radix.c
@@ -761,8 +761,10 @@ on2:
if (m->rm_flags & RNF_NORMAL) {
mmask = m->rm_leaf->rn_mask;
if (tt->rn_flags & RNF_NORMAL) {
+#if !defined(RADIX_MPATH)
log(LOG_ERR,
"Non-unique normal route, mask not entered\n");
+#endif
return tt;
}
} else
@@ -936,7 +938,7 @@ on1:
if (m)
log(LOG_ERR,
"rn_delete: Orphaned Mask %p at %p\n",
- (void *)m, (void *)x);
+ m, x);
}
}
/*
@@ -1161,6 +1163,22 @@ rn_inithead(head, off)
return (1);
}
+int
+rn_detachhead(void **head)
+{
+ struct radix_node_head *rnh;
+
+ KASSERT((head != NULL && *head != NULL),
+ ("%s: head already freed", __func__));
+ rnh = *head;
+
+ /* Free <left,root,right> nodes. */
+ Free(rnh);
+
+ *head = NULL;
+ return (1);
+}
+
void
rn_init(int maxk)
{
diff --git a/sys/net/radix.h b/sys/net/radix.h
index aa341b6..29659b5 100644
--- a/sys/net/radix.h
+++ b/sys/net/radix.h
@@ -162,6 +162,7 @@ struct radix_node_head {
void rn_init(int);
int rn_inithead(void **, int);
+int rn_detachhead(void **);
int rn_refines(void *, void *);
struct radix_node
*rn_addmask(void *, int, int),
diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c
index 9be01d2..ea84e5c 100644
--- a/sys/net/radix_mpath.c
+++ b/sys/net/radix_mpath.c
@@ -270,7 +270,8 @@ rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
* XXX we don't attempt to lookup cached route again; what should
* be done for sendto(3) case?
*/
- if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
+ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP)
+ && RT_LINK_IS_UP(ro->ro_rt->rt_ifp))
return;
ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, 0, fibnum);
diff --git a/sys/net/route.c b/sys/net/route.c
index a938c9c..e500ed1 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -830,7 +830,13 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
int
rtexpunge(struct rtentry *rt)
{
+#if !defined(RADIX_MPATH)
struct radix_node *rn;
+#else
+ struct rt_addrinfo info;
+ int fib;
+ struct rtentry *rt0;
+#endif
struct radix_node_head *rnh;
struct ifaddr *ifa;
int error = 0;
@@ -843,14 +849,26 @@ rtexpunge(struct rtentry *rt)
if (rnh == NULL)
return (EAFNOSUPPORT);
RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
-#if 0
- /*
- * We cannot assume anything about the reference count
- * because protocols call us in many situations; often
- * before unwinding references to the table entry.
- */
- KASSERT(rt->rt_refcnt <= 1, ("bogus refcnt %ld", rt->rt_refcnt));
-#endif
+
+#ifdef RADIX_MPATH
+ fib = rt->rt_fibnum;
+ bzero(&info, sizeof(info));
+ info.rti_ifp = rt->rt_ifp;
+ info.rti_flags = RTF_RNH_LOCKED;
+ info.rti_info[RTAX_DST] = rt_key(rt);
+ info.rti_info[RTAX_GATEWAY] = rt->rt_ifa->ifa_addr;
+
+ RT_UNLOCK(rt);
+ error = rtrequest1_fib(RTM_DELETE, &info, &rt0, fib);
+
+ if (error == 0 && rt0 != NULL) {
+ rt = rt0;
+ RT_LOCK(rt);
+ } else if (error != 0) {
+ RT_LOCK(rt);
+ return (error);
+ }
+#else
/*
* Remove the item from the tree; it should be there,
* but when callers invoke us blindly it may not (sigh).
@@ -864,6 +882,7 @@ rtexpunge(struct rtentry *rt)
("unexpected flags 0x%x", rn->rn_flags));
KASSERT(rt == RNTORT(rn),
("lookup mismatch, rt %p rn %p", rt, rn));
+#endif /* RADIX_MPATH */
rt->rt_flags &= ~RTF_UP;
@@ -886,7 +905,9 @@ rtexpunge(struct rtentry *rt)
* linked to the routing table.
*/
V_rttrash++;
+#if !defined(RADIX_MPATH)
bad:
+#endif
return (error);
}
@@ -1044,6 +1065,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
*/
if (error != ENOENT)
goto bad;
+ error = 0;
}
#endif
/*
diff --git a/sys/net/route.h b/sys/net/route.h
index a8ae867..bb5def3 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -319,6 +319,9 @@ struct rt_addrinfo {
#ifdef _KERNEL
+#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \
+ || (ifp)->if_link_state == LINK_STATE_UP)
+
#define RT_LOCK_INIT(_rt) \
mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK)
#define RT_LOCK(_rt) mtx_lock(&(_rt)->rt_mtx)
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index df4f9ae..de65482 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -29,6 +29,7 @@
* @(#)rtsock.c 8.7 (Berkeley) 10/12/95
* $FreeBSD$
*/
+#include "opt_compat.h"
#include "opt_sctp.h"
#include "opt_mpath.h"
#include "opt_inet.h"
@@ -71,6 +72,49 @@ extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
#endif /* SCTP */
#endif
+#ifdef COMPAT_FREEBSD32
+#include <sys/mount.h>
+#include <compat/freebsd32/freebsd32.h>
+
+struct if_data32 {
+ uint8_t ifi_type;
+ uint8_t ifi_physical;
+ uint8_t ifi_addrlen;
+ uint8_t ifi_hdrlen;
+ uint8_t ifi_link_state;
+ uint8_t ifi_spare_char1;
+ uint8_t ifi_spare_char2;
+ uint8_t ifi_datalen;
+ uint32_t ifi_mtu;
+ uint32_t ifi_metric;
+ uint32_t ifi_baudrate;
+ uint32_t ifi_ipackets;
+ uint32_t ifi_ierrors;
+ uint32_t ifi_opackets;
+ uint32_t ifi_oerrors;
+ uint32_t ifi_collisions;
+ uint32_t ifi_ibytes;
+ uint32_t ifi_obytes;
+ uint32_t ifi_imcasts;
+ uint32_t ifi_omcasts;
+ uint32_t ifi_iqdrops;
+ uint32_t ifi_noproto;
+ uint32_t ifi_hwassist;
+ int32_t ifi_epoch;
+ struct timeval32 ifi_lastchange;
+};
+
+struct if_msghdr32 {
+ uint16_t ifm_msglen;
+ uint8_t ifm_version;
+ uint8_t ifm_type;
+ int32_t ifm_addrs;
+ int32_t ifm_flags;
+ uint16_t ifm_index;
+ struct if_data32 ifm_data;
+};
+#endif
+
MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
/* NB: these are not modified */
@@ -1001,6 +1045,12 @@ again:
break;
case RTM_IFINFO:
+#ifdef COMPAT_FREEBSD32
+ if (w != NULL && w->w_req->flags & SCTL_MASK32) {
+ len = sizeof(struct if_msghdr32);
+ break;
+ }
+#endif
len = sizeof(struct if_msghdr);
break;
@@ -1367,6 +1417,38 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
return (error);
}
+#ifdef COMPAT_FREEBSD32
+static void
+copy_ifdata32(struct if_data *src, struct if_data32 *dst)
+{
+
+ bzero(dst, sizeof(*dst));
+ CP(*src, *dst, ifi_type);
+ CP(*src, *dst, ifi_physical);
+ CP(*src, *dst, ifi_addrlen);
+ CP(*src, *dst, ifi_hdrlen);
+ CP(*src, *dst, ifi_link_state);
+ CP(*src, *dst, ifi_datalen);
+ CP(*src, *dst, ifi_mtu);
+ CP(*src, *dst, ifi_metric);
+ CP(*src, *dst, ifi_baudrate);
+ CP(*src, *dst, ifi_ipackets);
+ CP(*src, *dst, ifi_ierrors);
+ CP(*src, *dst, ifi_opackets);
+ CP(*src, *dst, ifi_oerrors);
+ CP(*src, *dst, ifi_collisions);
+ CP(*src, *dst, ifi_ibytes);
+ CP(*src, *dst, ifi_obytes);
+ CP(*src, *dst, ifi_imcasts);
+ CP(*src, *dst, ifi_omcasts);
+ CP(*src, *dst, ifi_iqdrops);
+ CP(*src, *dst, ifi_noproto);
+ CP(*src, *dst, ifi_hwassist);
+ CP(*src, *dst, ifi_epoch);
+ TV_CP(*src, *dst, ifi_lastchange);
+}
+#endif
+
static int
sysctl_iflist(int af, struct walkarg *w)
{
@@ -1387,12 +1469,30 @@ sysctl_iflist(int af, struct walkarg *w)
if (w->w_req && w->w_tmem) {
struct if_msghdr *ifm;
+#ifdef COMPAT_FREEBSD32
+ if (w->w_req->flags & SCTL_MASK32) {
+ struct if_msghdr32 *ifm32;
+
+ ifm32 = (struct if_msghdr32 *)w->w_tmem;
+ ifm32->ifm_index = ifp->if_index;
+ ifm32->ifm_flags = ifp->if_flags |
+ ifp->if_drv_flags;
+ copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
+ ifm32->ifm_addrs = info.rti_addrs;
+ error = SYSCTL_OUT(w->w_req, (caddr_t)ifm32,
+ len);
+ goto sysctl_out;
+ }
+#endif
ifm = (struct if_msghdr *)w->w_tmem;
ifm->ifm_index = ifp->if_index;
ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
ifm->ifm_data = ifp->if_data;
ifm->ifm_addrs = info.rti_addrs;
- error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len);
+ error = SYSCTL_OUT(w->w_req, (caddr_t)ifm, len);
+#ifdef COMPAT_FREEBSD32
+ sysctl_out:
+#endif
if (error)
goto done;
}
diff --git a/sys/net/vnet.c b/sys/net/vnet.c
index 323ed08..8013f5e 100644
--- a/sys/net/vnet.c
+++ b/sys/net/vnet.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sdt.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
+#include <sys/eventhandler.h>
#include <sys/linker_set.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -55,6 +56,8 @@ __FBSDID("$FreeBSD$");
#include <sys/sx.h>
#include <sys/sysctl.h>
+#include <machine/stdarg.h>
+
#ifdef DDB
#include <ddb/ddb.h>
#include <ddb/db_sym.h>
@@ -151,15 +154,6 @@ struct vnet *vnet0;
*/
/*
- * Location of the kernel's 'set_vnet' linker set.
- */
-extern uintptr_t *__start_set_vnet;
-extern uintptr_t *__stop_set_vnet;
-
-#define VNET_START (uintptr_t)&__start_set_vnet
-#define VNET_STOP (uintptr_t)&__stop_set_vnet
-
-/*
* Number of bytes of data in the 'set_vnet' linker set, and hence the total
* size of all kernel virtualized global variables, and the malloc(9) type
* that will be used to allocate it.
@@ -637,6 +631,39 @@ vnet_sysuninit(void)
VNET_SYSINIT_RUNLOCK();
}
+/*
+ * EVENTHANDLER(9) extensions.
+ */
+/*
+ * Invoke the eventhandler function originally registered with the possibly
+ * registered argument for all virtual network stack instances.
+ *
+ * This iterator can only be used for eventhandlers that do not take any
+ * additional arguments, as we do ignore the variadic arguments from the
+ * EVENTHANDLER_INVOKE() call.
+ */
+void
+vnet_global_eventhandler_iterator_func(void *arg, ...)
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+ struct eventhandler_entry_vimage *v_ee;
+
+ /*
+ * There is a bug here in that we should actually cast things to
+ * (struct eventhandler_entry_ ## name *) but that's not easily
+ * possible in here so just re-using the variadic version we
+ * defined for the generic vimage case.
+ */
+ v_ee = arg;
+ VNET_LIST_RLOCK();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ ((vimage_iterator_func_t)v_ee->func)(v_ee->ee_arg);
+ CURVNET_RESTORE();
+ }
+ VNET_LIST_RUNLOCK();
+}
+
#ifdef VNET_DEBUG
struct vnet_recursion {
SLIST_ENTRY(vnet_recursion) vnr_le;
@@ -696,6 +723,9 @@ vnet_log_recursion(struct vnet *old_vnet, const char *old_fn, int line)
}
#endif /* VNET_DEBUG */
+/*
+ * DDB(4).
+ */
#ifdef DDB
DB_SHOW_COMMAND(vnets, db_show_vnets)
{
diff --git a/sys/net/vnet.h b/sys/net/vnet.h
index d9a1ee0..4cdfdef 100644
--- a/sys/net/vnet.h
+++ b/sys/net/vnet.h
@@ -92,6 +92,15 @@ struct vnet {
#include <sys/sx.h>
/*
+ * Location of the kernel's 'set_vnet' linker set.
+ */
+extern uintptr_t *__start_set_vnet;
+extern uintptr_t *__stop_set_vnet;
+
+#define VNET_START (uintptr_t)&__start_set_vnet
+#define VNET_STOP (uintptr_t)&__stop_set_vnet
+
+/*
* Functions to allocate and destroy virtual network stacks.
*/
struct vnet *vnet_alloc(void);
@@ -313,6 +322,29 @@ void vnet_register_sysuninit(void *arg);
void vnet_deregister_sysinit(void *arg);
void vnet_deregister_sysuninit(void *arg);
+/*
+ * EVENTHANDLER(9) extensions.
+ */
+#include <sys/eventhandler.h>
+
+void vnet_global_eventhandler_iterator_func(void *, ...);
+#define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
+do { \
+ if (IS_DEFAULT_VNET(curvnet)) { \
+ (tag) = vimage_eventhandler_register(NULL, #name, func, \
+ arg, priority, \
+ vnet_global_eventhandler_iterator_func); \
+ } \
+} while(0)
+#define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority) \
+do { \
+ if (IS_DEFAULT_VNET(curvnet)) { \
+ vimage_eventhandler_register(NULL, #name, func, \
+ arg, priority, \
+ vnet_global_eventhandler_iterator_func); \
+ } \
+} while(0)
+
#else /* !VIMAGE */
/*
@@ -384,6 +416,13 @@ void vnet_deregister_sysuninit(void *arg);
#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \
SYSUNINIT(ident, subsystem, order, func, arg)
+/*
+ * Without VIMAGE revert to the default implementation.
+ */
+#define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
+ (tag) = eventhandler_register(NULL, #name, func, arg, priority)
+#define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority) \
+ eventhandler_register(NULL, #name, func, arg, priority)
#endif /* VIMAGE */
#endif /* _KERNEL */
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index f72e10b..3d5669c 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#ifdef IEEE80211_SUPPORT_SUPERG
#include <net80211/ieee80211_superg.h>
#endif
+#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@@ -404,6 +405,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
vap->iv_flags_ven = ic->ic_flags_ven;
vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
vap->iv_htcaps = ic->ic_htcaps;
+ vap->iv_htextcaps = ic->ic_htextcaps;
vap->iv_opmode = opmode;
vap->iv_caps |= ieee80211_opcap[opmode];
switch (opmode) {
@@ -485,6 +487,8 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ieee80211_regdomain_vattach(vap);
ieee80211_radiotap_vattach(vap);
+ ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR);
+
return 0;
}
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index d3b43bd..67bcf64 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -922,6 +922,12 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
}
static void
-adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m0, int subtype)
+adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_BAR:
+ ieee80211_recv_bar(ni, m);
+ break;
+ }
}
diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c
index a759e64..6111058 100644
--- a/sys/net80211/ieee80211_amrr.c
+++ b/sys/net80211/ieee80211_amrr.c
@@ -1,6 +1,7 @@
/* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */
/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* Copyright (c) 2006
* Damien Bergamini <damien.bergamini@free.fr>
*
@@ -46,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#define is_success(amn) \
((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
@@ -54,15 +56,45 @@ __FBSDID("$FreeBSD$");
#define is_enough(amn) \
((amn)->amn_txcnt > 10)
-static void amrr_sysctlattach(struct ieee80211_amrr *amrr,
- struct sysctl_ctx_list *ctx, struct sysctl_oid *tree);
+static void amrr_setinterval(const struct ieee80211vap *, int);
+static void amrr_init(struct ieee80211vap *);
+static void amrr_deinit(struct ieee80211vap *);
+static void amrr_node_init(struct ieee80211_node *);
+static void amrr_node_deinit(struct ieee80211_node *);
+static int amrr_update(struct ieee80211_amrr *,
+ struct ieee80211_amrr_node *, struct ieee80211_node *);
+static int amrr_rate(struct ieee80211_node *, void *, uint32_t);
+static void amrr_tx_complete(const struct ieee80211vap *,
+ const struct ieee80211_node *, int,
+ void *, void *);
+static void amrr_tx_update(const struct ieee80211vap *vap,
+ const struct ieee80211_node *, void *, void *, void *);
+static void amrr_sysctlattach(struct ieee80211vap *,
+ struct sysctl_ctx_list *, struct sysctl_oid *);
/* number of references from net80211 layer */
static int nrefs = 0;
-void
-ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs)
+static const struct ieee80211_ratectl amrr = {
+ .ir_name = "amrr",
+ .ir_attach = NULL,
+ .ir_detach = NULL,
+ .ir_init = amrr_init,
+ .ir_deinit = amrr_deinit,
+ .ir_node_init = amrr_node_init,
+ .ir_node_deinit = amrr_node_deinit,
+ .ir_rate = amrr_rate,
+ .ir_tx_complete = amrr_tx_complete,
+ .ir_tx_update = amrr_tx_update,
+ .ir_setinterval = amrr_setinterval,
+};
+IEEE80211_RATECTL_MODULE(amrr, 1);
+IEEE80211_RATECTL_ALG(amrr, IEEE80211_RATECTL_AMRR, amrr);
+
+static void
+amrr_setinterval(const struct ieee80211vap *vap, int msecs)
{
+ struct ieee80211_amrr *amrr = vap->iv_rs;
int t;
if (msecs < 100)
@@ -71,29 +103,49 @@ ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs)
amrr->amrr_interval = (t < 1) ? 1 : t;
}
-void
-ieee80211_amrr_init(struct ieee80211_amrr *amrr,
- struct ieee80211vap *vap, int amin, int amax, int interval)
+static void
+amrr_init(struct ieee80211vap *vap)
{
- /* XXX bounds check? */
- amrr->amrr_min_success_threshold = amin;
- amrr->amrr_max_success_threshold = amax;
- ieee80211_amrr_setinterval(amrr, interval);
+ struct ieee80211_amrr *amrr;
+
+ KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__));
- amrr_sysctlattach(amrr, vap->iv_sysctl, vap->iv_oid);
+ amrr = vap->iv_rs = malloc(sizeof(struct ieee80211_amrr),
+ M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ if (amrr == NULL) {
+ if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
+ return;
+ }
+ amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD;
+ amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD;
+ amrr_setinterval(vap, 500 /* ms */);
+ amrr_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid);
}
-void
-ieee80211_amrr_cleanup(struct ieee80211_amrr *amrr)
+static void
+amrr_deinit(struct ieee80211vap *vap)
{
+ free(vap->iv_rs, M_80211_RATECTL);
}
-void
-ieee80211_amrr_node_init(struct ieee80211_amrr *amrr,
- struct ieee80211_amrr_node *amn, struct ieee80211_node *ni)
+static void
+amrr_node_init(struct ieee80211_node *ni)
{
const struct ieee80211_rateset *rs = &ni->ni_rates;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_amrr *amrr = vap->iv_rs;
+ struct ieee80211_amrr_node *amn;
+
+ KASSERT(ni->ni_rctls == NULL, ("%s: ni_rctls already initialized",
+ __func__));
+ ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
+ M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ if (amn == NULL) {
+ if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
+ "structure\n");
+ return;
+ }
amn->amn_amrr = amrr;
amn->amn_success = 0;
amn->amn_recovery = 0;
@@ -112,6 +164,12 @@ ieee80211_amrr_node_init(struct ieee80211_amrr *amrr,
"AMRR initial rate %d", ni->ni_txrate);
}
+static void
+amrr_node_deinit(struct ieee80211_node *ni)
+{
+ free(ni->ni_rctls, M_80211_RATECTL);
+}
+
static int
amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
struct ieee80211_node *ni)
@@ -168,10 +226,10 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
* Update our internal state if it's been long enough.
* If the rate changes we also update ni_txrate to match.
*/
-int
-ieee80211_amrr_choose(struct ieee80211_node *ni,
- struct ieee80211_amrr_node *amn)
+static int
+amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused)
{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
struct ieee80211_amrr *amrr = amn->amn_amrr;
int rix;
@@ -189,27 +247,65 @@ ieee80211_amrr_choose(struct ieee80211_node *ni,
return rix;
}
+/*
+ * Update statistics with tx complete status. Ok is non-zero
+ * if the packet is known to be ACK'd. Retries has the number
+ * retransmissions (i.e. xmit attempts - 1).
+ */
+static void
+amrr_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int ok,
+ void *arg1, void *arg2 __unused)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ int retries = *(int *)arg1;
+
+ amn->amn_txcnt++;
+ if (ok)
+ amn->amn_success++;
+ amn->amn_retrycnt += retries;
+}
+
+/*
+ * Set tx count/retry statistics explicitly. Intended for
+ * drivers that poll the device for statistics maintained
+ * in the device.
+ */
+static void
+amrr_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni,
+ void *arg1, void *arg2, void *arg3)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ int txcnt = *(int *)arg1, success = *(int *)arg2, retrycnt = *(int *)arg3;
+
+ amn->amn_txcnt = txcnt;
+ amn->amn_success = success;
+ amn->amn_retrycnt = retrycnt;
+}
+
static int
amrr_sysctl_interval(SYSCTL_HANDLER_ARGS)
{
- struct ieee80211_amrr *amrr = arg1;
+ struct ieee80211vap *vap = arg1;
+ struct ieee80211_amrr *amrr = vap->iv_rs;
int msecs = ticks_to_msecs(amrr->amrr_interval);
int error;
error = sysctl_handle_int(oidp, &msecs, 0, req);
if (error || !req->newptr)
return error;
- ieee80211_amrr_setinterval(amrr, msecs);
+ amrr_setinterval(vap, msecs);
return 0;
}
static void
-amrr_sysctlattach(struct ieee80211_amrr *amrr,
+amrr_sysctlattach(struct ieee80211vap *vap,
struct sysctl_ctx_list *ctx, struct sysctl_oid *tree)
{
+ struct ieee80211_amrr *amrr = vap->iv_rs;
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, amrr,
+ "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap,
0, amrr_sysctl_interval, "I", "amrr operation interval (ms)");
/* XXX bounds check values */
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
@@ -219,8 +315,3 @@ amrr_sysctlattach(struct ieee80211_amrr *amrr,
"amrr_min_sucess_threshold", CTLFLAG_RW,
&amrr->amrr_min_success_threshold, 0, "");
}
-
-/*
- * Module glue.
- */
-IEEE80211_RATE_MODULE(amrr, 1);
diff --git a/sys/net80211/ieee80211_amrr.h b/sys/net80211/ieee80211_amrr.h
index c03f699..ec67bdf 100644
--- a/sys/net80211/ieee80211_amrr.h
+++ b/sys/net80211/ieee80211_amrr.h
@@ -58,44 +58,4 @@ struct ieee80211_amrr_node {
u_int amn_retrycnt;
};
-void ieee80211_amrr_init(struct ieee80211_amrr *, struct ieee80211vap *,
- int, int, int);
-void ieee80211_amrr_cleanup(struct ieee80211_amrr *);
-void ieee80211_amrr_setinterval(struct ieee80211_amrr *, int);
-void ieee80211_amrr_node_init(struct ieee80211_amrr *,
- struct ieee80211_amrr_node *, struct ieee80211_node *);
-int ieee80211_amrr_choose(struct ieee80211_node *,
- struct ieee80211_amrr_node *);
-
-#define IEEE80211_AMRR_SUCCESS 1
-#define IEEE80211_AMRR_FAILURE 0
-
-/*
- * Update statistics with tx complete status. Ok is non-zero
- * if the packet is known to be ACK'd. Retries has the number
- * retransmissions (i.e. xmit attempts - 1).
- */
-static __inline void
-ieee80211_amrr_tx_complete(struct ieee80211_amrr_node *amn,
- int ok, int retries)
-{
- amn->amn_txcnt++;
- if (ok)
- amn->amn_success++;
- amn->amn_retrycnt += retries;
-}
-
-/*
- * Set tx count/retry statistics explicitly. Intended for
- * drivers that poll the device for statistics maintained
- * in the device.
- */
-static __inline void
-ieee80211_amrr_tx_update(struct ieee80211_amrr_node *amn,
- int txcnt, int success, int retrycnt)
-{
- amn->amn_txcnt = txcnt;
- amn->amn_success = success;
- amn->amn_retrycnt = retrycnt;
-}
#endif /* _NET80211_IEEE80211_AMRR_H_ */
diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c
index 79df266..9ad2409 100644
--- a/sys/net80211/ieee80211_crypto_ccmp.c
+++ b/sys/net80211/ieee80211_crypto_ccmp.c
@@ -226,7 +226,14 @@ ccmp_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
}
tid = ieee80211_gettid(wh);
pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
- if (pn <= k->wk_keyrsc[tid]) {
+ /*
+ * NB: Multiple stations are using the same key in
+ * IBSS mode, there is currently no way to sync keyrsc
+ * counters without discarding too many frames.
+ */
+ if (vap->iv_opmode != IEEE80211_M_IBSS &&
+ vap->iv_opmode != IEEE80211_M_AHDEMO &&
+ pn <= k->wk_keyrsc[tid]) {
/*
* Replay violation.
*/
diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c
index 6e1fda1..0f17c17 100644
--- a/sys/net80211/ieee80211_crypto_tkip.c
+++ b/sys/net80211/ieee80211_crypto_tkip.c
@@ -281,7 +281,14 @@ tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
tid = ieee80211_gettid(wh);
ctx->rx_rsc = READ_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
- if (ctx->rx_rsc <= k->wk_keyrsc[tid]) {
+ /*
+ * NB: Multiple stations are using the same key in
+ * IBSS mode, there is currently no way to sync keyrsc
+ * counters without discarding too many frames.
+ */
+ if (vap->iv_opmode != IEEE80211_M_IBSS &&
+ vap->iv_opmode != IEEE80211_M_AHDEMO &&
+ ctx->rx_rsc <= k->wk_keyrsc[tid]) {
/*
* Replay violation; notify upper layer.
*/
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 6a8875a..abfc2c0 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -148,6 +148,16 @@ typedef struct mtx acl_lock_t;
mtx_assert((&(_as)->as_lock), MA_OWNED)
/*
+ * Scan table definitions.
+ */
+typedef struct mtx ieee80211_scan_table_lock_t;
+#define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
+ mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF)
+#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock)
+#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock)
+#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock)
+
+/*
* Node reference counting definitions.
*
* ieee80211_node_initref initialize the reference count to 1
@@ -386,14 +396,19 @@ TEXT_SET(auth_set, name##_modevent)
/*
* Rate control modules provide tx rate control support.
*/
-#define IEEE80211_RATE_MODULE(alg, version) \
-_IEEE80211_POLICY_MODULE(rate, alg, version); \
+#define IEEE80211_RATECTL_MODULE(alg, version) \
+ _IEEE80211_POLICY_MODULE(ratectl, alg, version); \
+
+#define IEEE80211_RATECTL_ALG(name, alg, v) \
static void \
alg##_modevent(int type) \
{ \
- /* XXX nothing to do until the rate control framework arrives */\
+ if (type == MOD_LOAD) \
+ ieee80211_ratectl_register(alg, &v); \
+ else \
+ ieee80211_ratectl_unregister(alg); \
} \
-TEXT_SET(rate##_set, alg##_modevent)
+TEXT_SET(ratectl##_set, alg##_modevent)
struct ieee80211req;
typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 8405b4f..63bcd3c 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -883,6 +883,14 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
}
+ /*
+ * Pass the packet to radiotap before calling iv_recv_mgmt().
+ * Otherwise iv_recv_mgmt() might pass another packet to
+ * radiotap, resulting in out of order packet captures.
+ */
+ if (ieee80211_radiotap_active_vap(vap))
+ ieee80211_radiotap_rx(vap, m);
+ need_tap = 0;
vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
goto out;
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index 2ce1b92..2d44816 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#define SM(_v, _f) (((_v) << _f##_S) & _f)
const struct ieee80211_mcs_rates ieee80211_htrates[16] = {
+ /* 20Mhz SGI 40Mhz SGI */
{ 13, 14, 27, 30 }, /* MCS 0 */
{ 26, 29, 54, 60 }, /* MCS 1 */
{ 39, 43, 81, 90 }, /* MCS 2 */
@@ -248,25 +249,60 @@ ieee80211_ht_vdetach(struct ieee80211vap *vap)
}
static void
-ht_announce(struct ieee80211com *ic, int mode,
- const struct ieee80211_htrateset *rs)
+ht_rateprint(struct ieee80211com *ic, int mode,
+ const struct ieee80211_htrateset *rs, int maxmcs, int ratetype)
{
- struct ifnet *ifp = ic->ic_ifp;
int i, rate, mword;
- if_printf(ifp, "%s MCS: ", ieee80211_phymode_name[mode]);
- for (i = 0; i < rs->rs_nrates; i++) {
+ for (i = 0; i < rs->rs_nrates && i < maxmcs; i++) {
mword = ieee80211_rate2media(ic,
rs->rs_rates[i] | IEEE80211_RATE_MCS, mode);
if (IFM_SUBTYPE(mword) != IFM_IEEE80211_MCS)
continue;
- rate = ieee80211_htrates[rs->rs_rates[i]].ht40_rate_400ns;
+ switch (ratetype) {
+ case 0:
+ rate = ieee80211_htrates[
+ rs->rs_rates[i]].ht20_rate_800ns;
+ break;
+ case 1:
+ rate = ieee80211_htrates[
+ rs->rs_rates[i]].ht20_rate_400ns;
+ break;
+ case 2:
+ rate = ieee80211_htrates[
+ rs->rs_rates[i]].ht40_rate_800ns;
+ break;
+ default:
+ rate = ieee80211_htrates[
+ rs->rs_rates[i]].ht40_rate_400ns;
+ break;
+ }
printf("%s%d%sMbps", (i != 0 ? " " : ""),
rate / 2, ((rate & 0x1) != 0 ? ".5" : ""));
}
printf("\n");
}
+static void
+ht_announce(struct ieee80211com *ic, int mode,
+ const struct ieee80211_htrateset *rs)
+{
+ struct ifnet *ifp = ic->ic_ifp;
+ int maxmcs = 2 * 8;
+ const char *modestr = ieee80211_phymode_name[mode];
+
+ KASSERT(maxmcs <= 16, ("maxmcs > 16"));
+ if_printf(ifp, "%d MCS rates\n", maxmcs);
+ if_printf(ifp, "%s MCS 20Mhz: ", modestr);
+ ht_rateprint(ic, mode, rs, maxmcs, 0);
+ if_printf(ifp, "%s MCS 20Mhz SGI: ", modestr);
+ ht_rateprint(ic, mode, rs, maxmcs, 1);
+ if_printf(ifp, "%s MCS 40Mhz: ", modestr);
+ ht_rateprint(ic, mode, rs, maxmcs, 2);
+ if_printf(ifp, "%s MCS 40Mhz SGI: ", modestr);
+ ht_rateprint(ic, mode, rs, maxmcs, 3);
+}
+
void
ieee80211_ht_announce(struct ieee80211com *ic)
{
@@ -396,6 +432,7 @@ ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
static void
ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
{
+
ampdu_rx_purge(rap);
rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND);
}
@@ -656,7 +693,7 @@ again:
if (off < rap->rxa_wnd) {
/*
* Common case (hopefully): in the BA window.
- * Sec 9.10.7.6 a) (D2.04 p.118 line 47)
+ * Sec 9.10.7.6.2 a) (p.137)
*/
#ifdef IEEE80211_AMPDU_AGE
/*
@@ -721,7 +758,7 @@ again:
/*
* Outside the BA window, but within range;
* flush the reorder q and move the window.
- * Sec 9.10.7.6 b) (D2.04 p.118 line 60)
+ * Sec 9.10.7.6.2 b) (p.138)
*/
IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
"move BA win <%u:%u> (%u frames) rxseq %u tid %u",
@@ -745,7 +782,7 @@ again:
} else {
/*
* Outside the BA window and out of range; toss.
- * Sec 9.10.7.6 c) (D2.04 p.119 line 16)
+ * Sec 9.10.7.6.2 c) (p.138)
*/
IEEE80211_DISCARD_MAC(vap,
IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr,
@@ -809,7 +846,7 @@ ieee80211_recv_bar(struct ieee80211_node *ni, struct mbuf *m0)
if (off < IEEE80211_SEQ_BA_RANGE) {
/*
* Flush the reorder q up to rxseq and move the window.
- * Sec 9.10.7.6 a) (D2.04 p.119 line 22)
+ * Sec 9.10.7.6.3 a) (p.138)
*/
IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
"BAR moves BA win <%u:%u> (%u frames) rxseq %u tid %u",
@@ -830,7 +867,7 @@ ieee80211_recv_bar(struct ieee80211_node *ni, struct mbuf *m0)
} else {
/*
* Out of range; toss.
- * Sec 9.10.7.6 b) (D2.04 p.119 line 41)
+ * Sec 9.10.7.6.3 b) (p.138)
*/
IEEE80211_DISCARD_MAC(vap,
IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr,
@@ -1621,7 +1658,7 @@ ht_recv_action_ba_addba_request(struct ieee80211_node *ni,
struct ieee80211_rx_ampdu *rap;
uint8_t dialogtoken;
uint16_t baparamset, batimeout, baseqctl;
- uint16_t args[4];
+ uint16_t args[5];
int tid;
dialogtoken = frm[2];
@@ -1671,6 +1708,7 @@ ht_recv_action_ba_addba_request(struct ieee80211_node *ni,
| SM(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ)
;
args[3] = 0;
+ args[4] = 0;
ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
IEEE80211_ACTION_BA_ADDBA_RESPONSE, args);
return 0;
@@ -1874,7 +1912,7 @@ ieee80211_ampdu_request(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap)
{
struct ieee80211com *ic = ni->ni_ic;
- uint16_t args[4];
+ uint16_t args[5];
int tid, dialogtoken;
static int tokens = 0; /* XXX */
@@ -1891,13 +1929,14 @@ ieee80211_ampdu_request(struct ieee80211_node *ni,
tap->txa_start = ni->ni_txseqs[tid];
args[0] = dialogtoken;
- args[1] = IEEE80211_BAPS_POLICY_IMMEDIATE
+ args[1] = 0; /* NB: status code not used */
+ args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE
| SM(tid, IEEE80211_BAPS_TID)
| SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ)
;
- args[2] = 0; /* batimeout */
+ args[3] = 0; /* batimeout */
/* NB: do first so there's no race against reply */
- if (!ic->ic_addba_request(ni, tap, dialogtoken, args[1], args[2])) {
+ if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) {
/* unable to setup state, don't make request */
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
ni, "%s: could not setup BA stream for AC %d",
@@ -1911,7 +1950,7 @@ ieee80211_ampdu_request(struct ieee80211_node *ni,
}
tokens = dialogtoken; /* allocate token */
/* NB: after calling ic_addba_request so driver can set txa_start */
- args[3] = SM(tap->txa_start, IEEE80211_BASEQ_START)
+ args[4] = SM(tap->txa_start, IEEE80211_BASEQ_START)
| SM(0, IEEE80211_BASEQ_FRAG)
;
return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
@@ -2157,12 +2196,12 @@ ht_send_action_ba_addba(struct ieee80211_node *ni,
uint8_t *frm;
IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
- "send ADDBA %s: dialogtoken %d "
+ "send ADDBA %s: dialogtoken %d status %d "
"baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x",
(action == IEEE80211_ACTION_BA_ADDBA_REQUEST) ?
"request" : "response",
- args[0], args[1], MS(args[1], IEEE80211_BAPS_TID),
- args[2], args[3]);
+ args[0], args[1], args[2], MS(args[2], IEEE80211_BAPS_TID),
+ args[3], args[4]);
IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
"ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
@@ -2179,10 +2218,12 @@ ht_send_action_ba_addba(struct ieee80211_node *ni,
*frm++ = category;
*frm++ = action;
*frm++ = args[0]; /* dialog token */
- ADDSHORT(frm, args[1]); /* baparamset */
- ADDSHORT(frm, args[2]); /* batimeout */
+ if (action == IEEE80211_ACTION_BA_ADDBA_RESPONSE)
+ ADDSHORT(frm, args[1]); /* status code */
+ ADDSHORT(frm, args[2]); /* baparamset */
+ ADDSHORT(frm, args[3]); /* batimeout */
if (action == IEEE80211_ACTION_BA_ADDBA_REQUEST)
- ADDSHORT(frm, args[3]); /* baseqctl */
+ ADDSHORT(frm, args[4]); /* baseqctl */
m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
return ht_action_output(ni, m);
} else {
@@ -2305,7 +2346,7 @@ ieee80211_add_htcap_body(uint8_t *frm, struct ieee80211_node *ni)
frm += 2; \
} while (0)
struct ieee80211vap *vap = ni->ni_vap;
- uint16_t caps;
+ uint16_t caps, extcaps;
int rxmax, density;
/* HT capabilities */
@@ -2363,8 +2404,17 @@ ieee80211_add_htcap_body(uint8_t *frm, struct ieee80211_node *ni)
*/
ieee80211_set_htrates(frm, &ieee80211_rateset_11n);
- frm += sizeof(struct ieee80211_ie_htcap) -
+ frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) -
__offsetof(struct ieee80211_ie_htcap, hc_mcsset);
+
+ /* HT extended capabilities */
+ extcaps = vap->iv_htextcaps & 0xffff;
+
+ ADDSHORT(frm, extcaps);
+
+ frm += sizeof(struct ieee80211_ie_htcap) -
+ __offsetof(struct ieee80211_ie_htcap, hc_txbf);
+
return frm;
#undef ADDSHORT
}
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index e701cb5..28a58fe 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -734,7 +734,8 @@ ieee80211_ssid_mismatch(struct ieee80211vap *vap, const char *tag,
* Return the bssid of a frame.
*/
static const uint8_t *
-ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
+ieee80211_getbssid(const struct ieee80211vap *vap,
+ const struct ieee80211_frame *wh)
{
if (vap->iv_opmode == IEEE80211_M_STA)
return wh->i_addr2;
@@ -748,7 +749,7 @@ ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
#include <machine/stdarg.h>
void
-ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...)
+ieee80211_note(const struct ieee80211vap *vap, const char *fmt, ...)
{
char buf[128]; /* XXX */
va_list ap;
@@ -761,7 +762,7 @@ ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...)
}
void
-ieee80211_note_frame(struct ieee80211vap *vap,
+ieee80211_note_frame(const struct ieee80211vap *vap,
const struct ieee80211_frame *wh,
const char *fmt, ...)
{
@@ -776,7 +777,7 @@ ieee80211_note_frame(struct ieee80211vap *vap,
}
void
-ieee80211_note_mac(struct ieee80211vap *vap,
+ieee80211_note_mac(const struct ieee80211vap *vap,
const uint8_t mac[IEEE80211_ADDR_LEN],
const char *fmt, ...)
{
@@ -790,7 +791,7 @@ ieee80211_note_mac(struct ieee80211vap *vap,
}
void
-ieee80211_discard_frame(struct ieee80211vap *vap,
+ieee80211_discard_frame(const struct ieee80211vap *vap,
const struct ieee80211_frame *wh,
const char *type, const char *fmt, ...)
{
@@ -811,7 +812,7 @@ ieee80211_discard_frame(struct ieee80211vap *vap,
}
void
-ieee80211_discard_ie(struct ieee80211vap *vap,
+ieee80211_discard_ie(const struct ieee80211vap *vap,
const struct ieee80211_frame *wh,
const char *type, const char *fmt, ...)
{
@@ -830,7 +831,7 @@ ieee80211_discard_ie(struct ieee80211vap *vap,
}
void
-ieee80211_discard_mac(struct ieee80211vap *vap,
+ieee80211_discard_mac(const struct ieee80211vap *vap,
const uint8_t mac[IEEE80211_ADDR_LEN],
const char *type, const char *fmt, ...)
{
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 237e556..3c913cc 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$");
static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
static struct ieee80211_channel *findchannel(struct ieee80211com *,
int ieee, int mode);
+static int ieee80211_scanreq(struct ieee80211vap *,
+ struct ieee80211_scan_req *);
static __noinline int
ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq)
@@ -1471,14 +1473,15 @@ mlmelookup(void *arg, const struct ieee80211_scan_entry *se)
}
static __noinline int
-setmlme_assoc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
- int ssid_len, const uint8_t ssid[IEEE80211_NWID_LEN])
+setmlme_assoc_sta(struct ieee80211vap *vap,
+ const uint8_t mac[IEEE80211_ADDR_LEN], int ssid_len,
+ const uint8_t ssid[IEEE80211_NWID_LEN])
{
struct scanlookup lookup;
- /* XXX ibss/ahdemo */
- if (vap->iv_opmode != IEEE80211_M_STA)
- return EINVAL;
+ KASSERT(vap->iv_opmode == IEEE80211_M_STA,
+ ("expected opmode STA not %s",
+ ieee80211_opmode_name[vap->iv_opmode]));
/* NB: this is racey if roaming is !manual */
lookup.se = NULL;
@@ -1495,6 +1498,36 @@ setmlme_assoc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
}
static __noinline int
+setmlme_assoc_adhoc(struct ieee80211vap *vap,
+ const uint8_t mac[IEEE80211_ADDR_LEN], int ssid_len,
+ const uint8_t ssid[IEEE80211_NWID_LEN])
+{
+ struct ieee80211_scan_req sr;
+
+ KASSERT(vap->iv_opmode == IEEE80211_M_IBSS ||
+ vap->iv_opmode == IEEE80211_M_AHDEMO,
+ ("expected opmode IBSS or AHDEMO not %s",
+ ieee80211_opmode_name[vap->iv_opmode]));
+
+ if (ssid_len == 0)
+ return EINVAL;
+
+ /* NB: IEEE80211_IOC_SSID call missing for ap_scan=2. */
+ memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN);
+ vap->iv_des_ssid[0].len = ssid_len;
+ memcpy(vap->iv_des_ssid[0].ssid, ssid, ssid_len);
+ vap->iv_des_nssid = 1;
+
+ sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE;
+ sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
+ memcpy(sr.sr_ssid[0].ssid, ssid, ssid_len);
+ sr.sr_ssid[0].len = ssid_len;
+ sr.sr_nssid = 1;
+
+ return ieee80211_scanreq(vap, &sr);
+}
+
+static __noinline int
ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
struct ieee80211req_mlme mlme;
@@ -1505,9 +1538,13 @@ ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq)
error = copyin(ireq->i_data, &mlme, sizeof(mlme));
if (error)
return error;
- if (mlme.im_op == IEEE80211_MLME_ASSOC)
- return setmlme_assoc(vap, mlme.im_macaddr,
+ if (vap->iv_opmode == IEEE80211_M_STA &&
+ mlme.im_op == IEEE80211_MLME_ASSOC)
+ return setmlme_assoc_sta(vap, mlme.im_macaddr,
vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid);
+ else if (mlme.im_op == IEEE80211_MLME_ASSOC)
+ return setmlme_assoc_adhoc(vap, mlme.im_macaddr,
+ mlme.im_ssid_len, mlme.im_ssid);
else
return setmlme_common(vap, mlme.im_op,
mlme.im_macaddr, mlme.im_reason);
@@ -2332,8 +2369,8 @@ ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq)
return error;
}
-static __noinline int
-ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
+static int
+ieee80211_scanreq(struct ieee80211vap *vap, struct ieee80211_scan_req *sr)
{
#define IEEE80211_IOC_SCAN_FLAGS \
(IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \
@@ -2342,48 +2379,38 @@ ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \
IEEE80211_IOC_SCAN_CHECK)
struct ieee80211com *ic = vap->iv_ic;
- struct ieee80211_scan_req sr; /* XXX off stack? */
- int error, i;
-
- /* NB: parent must be running */
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return ENXIO;
+ int i;
- if (ireq->i_len != sizeof(sr))
- return EINVAL;
- error = copyin(ireq->i_data, &sr, sizeof(sr));
- if (error != 0)
- return error;
/* convert duration */
- if (sr.sr_duration == IEEE80211_IOC_SCAN_FOREVER)
- sr.sr_duration = IEEE80211_SCAN_FOREVER;
+ if (sr->sr_duration == IEEE80211_IOC_SCAN_FOREVER)
+ sr->sr_duration = IEEE80211_SCAN_FOREVER;
else {
- if (sr.sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN ||
- sr.sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX)
+ if (sr->sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN ||
+ sr->sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX)
return EINVAL;
- sr.sr_duration = msecs_to_ticks(sr.sr_duration);
- if (sr.sr_duration < 1)
- sr.sr_duration = 1;
+ sr->sr_duration = msecs_to_ticks(sr->sr_duration);
+ if (sr->sr_duration < 1)
+ sr->sr_duration = 1;
}
/* convert min/max channel dwell */
- if (sr.sr_mindwell != 0) {
- sr.sr_mindwell = msecs_to_ticks(sr.sr_mindwell);
- if (sr.sr_mindwell < 1)
- sr.sr_mindwell = 1;
+ if (sr->sr_mindwell != 0) {
+ sr->sr_mindwell = msecs_to_ticks(sr->sr_mindwell);
+ if (sr->sr_mindwell < 1)
+ sr->sr_mindwell = 1;
}
- if (sr.sr_maxdwell != 0) {
- sr.sr_maxdwell = msecs_to_ticks(sr.sr_maxdwell);
- if (sr.sr_maxdwell < 1)
- sr.sr_maxdwell = 1;
+ if (sr->sr_maxdwell != 0) {
+ sr->sr_maxdwell = msecs_to_ticks(sr->sr_maxdwell);
+ if (sr->sr_maxdwell < 1)
+ sr->sr_maxdwell = 1;
}
/* NB: silently reduce ssid count to what is supported */
- if (sr.sr_nssid > IEEE80211_SCAN_MAX_SSID)
- sr.sr_nssid = IEEE80211_SCAN_MAX_SSID;
- for (i = 0; i < sr.sr_nssid; i++)
- if (sr.sr_ssid[i].len > IEEE80211_NWID_LEN)
+ if (sr->sr_nssid > IEEE80211_SCAN_MAX_SSID)
+ sr->sr_nssid = IEEE80211_SCAN_MAX_SSID;
+ for (i = 0; i < sr->sr_nssid; i++)
+ if (sr->sr_ssid[i].len > IEEE80211_NWID_LEN)
return EINVAL;
/* cleanse flags just in case, could reject if invalid flags */
- sr.sr_flags &= IEEE80211_IOC_SCAN_FLAGS;
+ sr->sr_flags &= IEEE80211_IOC_SCAN_FLAGS;
/*
* Add an implicit NOPICK if the vap is not marked UP. This
* allows applications to scan without joining a bss (or picking
@@ -2391,13 +2418,13 @@ ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
* roaming mode--you just need to mark the parent device UP.
*/
if ((vap->iv_ifp->if_flags & IFF_UP) == 0)
- sr.sr_flags |= IEEE80211_IOC_SCAN_NOPICK;
+ sr->sr_flags |= IEEE80211_IOC_SCAN_NOPICK;
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
"%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n",
- __func__, sr.sr_flags,
+ __func__, sr->sr_flags,
(vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "",
- sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, sr.sr_nssid);
+ sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell, sr->sr_nssid);
/*
* If we are in INIT state then the driver has never had a chance
* to setup hardware state to do a scan; we must use the state
@@ -2412,13 +2439,13 @@ ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
IEEE80211_LOCK(ic);
if (vap->iv_state == IEEE80211_S_INIT) {
/* NB: clobbers previous settings */
- vap->iv_scanreq_flags = sr.sr_flags;
- vap->iv_scanreq_duration = sr.sr_duration;
- vap->iv_scanreq_nssid = sr.sr_nssid;
- for (i = 0; i < sr.sr_nssid; i++) {
- vap->iv_scanreq_ssid[i].len = sr.sr_ssid[i].len;
- memcpy(vap->iv_scanreq_ssid[i].ssid, sr.sr_ssid[i].ssid,
- sr.sr_ssid[i].len);
+ vap->iv_scanreq_flags = sr->sr_flags;
+ vap->iv_scanreq_duration = sr->sr_duration;
+ vap->iv_scanreq_nssid = sr->sr_nssid;
+ for (i = 0; i < sr->sr_nssid; i++) {
+ vap->iv_scanreq_ssid[i].len = sr->sr_ssid[i].len;
+ memcpy(vap->iv_scanreq_ssid[i].ssid,
+ sr->sr_ssid[i].ssid, sr->sr_ssid[i].len);
}
vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ;
IEEE80211_UNLOCK(ic);
@@ -2427,25 +2454,44 @@ ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
IEEE80211_UNLOCK(ic);
/* XXX neeed error return codes */
- if (sr.sr_flags & IEEE80211_IOC_SCAN_CHECK) {
- (void) ieee80211_check_scan(vap, sr.sr_flags,
- sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell,
- sr.sr_nssid,
+ if (sr->sr_flags & IEEE80211_IOC_SCAN_CHECK) {
+ (void) ieee80211_check_scan(vap, sr->sr_flags,
+ sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell,
+ sr->sr_nssid,
/* NB: cheat, we assume structures are compatible */
- (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]);
+ (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]);
} else {
- (void) ieee80211_start_scan(vap, sr.sr_flags,
- sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell,
- sr.sr_nssid,
+ (void) ieee80211_start_scan(vap, sr->sr_flags,
+ sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell,
+ sr->sr_nssid,
/* NB: cheat, we assume structures are compatible */
- (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]);
+ (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]);
}
}
- return error;
+ return 0;
#undef IEEE80211_IOC_SCAN_FLAGS
}
static __noinline int
+ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ struct ieee80211_scan_req sr; /* XXX off stack? */
+ int error;
+
+ /* NB: parent must be running */
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ return ENXIO;
+
+ if (ireq->i_len != sizeof(sr))
+ return EINVAL;
+ error = copyin(ireq->i_data, &sr, sizeof(sr));
+ if (error != 0)
+ return error;
+ return ieee80211_scanreq(vap, &sr);
+}
+
+static __noinline int
ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
struct ieee80211_node *ni;
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 417337b..1086113 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -82,6 +82,7 @@ static void mesh_forward(struct ieee80211vap *, struct mbuf *,
static int mesh_input(struct ieee80211_node *, struct mbuf *, int, int);
static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
int, int);
+static void mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
static void mesh_peer_timeout_setup(struct ieee80211_node *);
static void mesh_peer_timeout_backoff(struct ieee80211_node *);
static void mesh_peer_timeout_cb(void *);
@@ -520,6 +521,7 @@ mesh_vattach(struct ieee80211vap *vap)
vap->iv_input = mesh_input;
vap->iv_opdetach = mesh_vdetach;
vap->iv_recv_mgmt = mesh_recv_mgmt;
+ vap->iv_recv_ctl = mesh_recv_ctl;
ms = malloc(sizeof(struct ieee80211_mesh_state), M_80211_VAP,
M_NOWAIT | M_ZERO);
if (ms == NULL) {
@@ -1535,6 +1537,17 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
}
}
+static void
+mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
+{
+
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_BAR:
+ ieee80211_recv_bar(ni, m);
+ break;
+ }
+}
+
/*
* Parse meshpeering action ie's for open+confirm frames; the
* important bits are returned in the supplied structure.
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index bccb6d5..b17f42f 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <net80211/ieee80211_wds.h>
#include <net80211/ieee80211_mesh.h>
+#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@@ -1035,6 +1036,7 @@ node_free(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
+ ieee80211_ratectl_node_deinit(ni);
ic->ic_node_cleanup(ni);
ieee80211_ies_cleanup(&ni->ni_ies);
ieee80211_psq_cleanup(&ni->ni_psq);
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 63b2355..01bb2cf 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -218,7 +218,8 @@ struct ieee80211_node {
struct ieee80211_nodestats ni_stats; /* per-node statistics */
struct ieee80211vap *ni_wdsvap; /* associated WDS vap */
- uint64_t ni_spare[4];
+ void *ni_rctls; /* private ratectl state */
+ uint64_t ni_spare[3];
};
MALLOC_DECLARE(M_80211_NODE);
MALLOC_DECLARE(M_80211_NODE_IE);
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 9aabfcf..edac519 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1432,8 +1432,6 @@ ieee80211_swbmiss(void *arg)
} else if (vap->iv_swbmiss_count == 0) {
if (vap->iv_bmiss != NULL)
ieee80211_runtask(ic, &vap->iv_swbmiss_task);
- if (vap->iv_bmiss_count == 0) /* don't re-arm timer */
- return;
} else
vap->iv_swbmiss_count = 0;
callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period,
diff --git a/sys/net80211/ieee80211_ratectl.c b/sys/net80211/ieee80211_ratectl.c
new file mode 100644
index 0000000..2e8eb7e
--- /dev/null
+++ b/sys/net80211/ieee80211_ratectl.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@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 ``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 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 <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_ratectl.h>
+
+static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX];
+
+MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control");
+
+void
+ieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl)
+{
+ if (type >= IEEE80211_RATECTL_MAX)
+ return;
+ ratectls[type] = ratectl;
+}
+
+void
+ieee80211_ratectl_unregister(int type)
+{
+ if (type >= IEEE80211_RATECTL_MAX)
+ return;
+ ratectls[type] = NULL;
+}
+
+void
+ieee80211_ratectl_set(struct ieee80211vap *vap, int type)
+{
+ if (type >= IEEE80211_RATECTL_MAX)
+ return;
+ vap->iv_rate = ratectls[type];
+}
diff --git a/sys/net80211/ieee80211_ratectl.h b/sys/net80211/ieee80211_ratectl.h
new file mode 100644
index 0000000..73b4f32
--- /dev/null
+++ b/sys/net80211/ieee80211_ratectl.h
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@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 ``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 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$
+ */
+
+enum ieee80211_ratealgs {
+ IEEE80211_RATECTL_AMRR = 0,
+ IEEE80211_RATECTL_RSSADAPT = 1,
+ IEEE80211_RATECTL_ONOE = 2,
+ IEEE80211_RATECTL_SAMPLE = 3,
+ IEEE80211_RATECTL_MAX
+};
+
+#define IEEE80211_RATECTL_TX_SUCCESS 1
+#define IEEE80211_RATECTL_TX_FAILURE 0
+
+struct ieee80211_ratectl {
+ const char *ir_name;
+ int (*ir_attach)(const struct ieee80211vap *);
+ void (*ir_detach)(const struct ieee80211vap *);
+ void (*ir_init)(struct ieee80211vap *);
+ void (*ir_deinit)(struct ieee80211vap *);
+ void (*ir_node_init)(struct ieee80211_node *);
+ void (*ir_node_deinit)(struct ieee80211_node *);
+ int (*ir_rate)(struct ieee80211_node *, void *, uint32_t);
+ void (*ir_tx_complete)(const struct ieee80211vap *,
+ const struct ieee80211_node *, int,
+ void *, void *);
+ void (*ir_tx_update)(const struct ieee80211vap *,
+ const struct ieee80211_node *,
+ void *, void *, void *);
+ void (*ir_setinterval)(const struct ieee80211vap *, int);
+};
+
+void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *);
+void ieee80211_ratectl_unregister(int);
+void ieee80211_ratectl_set(struct ieee80211vap *, int);
+
+MALLOC_DECLARE(M_80211_RATECTL);
+
+static void __inline
+ieee80211_ratectl_init(struct ieee80211vap *vap)
+{
+ vap->iv_rate->ir_init(vap);
+}
+
+static void __inline
+ieee80211_ratectl_deinit(struct ieee80211vap *vap)
+{
+ vap->iv_rate->ir_deinit(vap);
+}
+
+static void __inline
+ieee80211_ratectl_node_init(struct ieee80211_node *ni)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+
+ vap->iv_rate->ir_node_init(ni);
+}
+
+static void __inline
+ieee80211_ratectl_node_deinit(struct ieee80211_node *ni)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return;
+ vap->iv_rate->ir_node_deinit(ni);
+}
+
+static int __inline
+ieee80211_ratectl_rate(struct ieee80211_node *ni, void *arg, uint32_t iarg)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return 0;
+ return vap->iv_rate->ir_rate(ni, arg, iarg);
+}
+
+static void __inline
+ieee80211_ratectl_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int status, void *arg1, void *arg2)
+{
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return;
+ vap->iv_rate->ir_tx_complete(vap, ni, status, arg1, arg2);
+}
+
+static void __inline
+ieee80211_ratectl_tx_update(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, void *arg1, void *arg2, void *arg3)
+{
+ if (vap->iv_rate->ir_tx_update == NULL)
+ return;
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return;
+ vap->iv_rate->ir_tx_update(vap, ni, arg1, arg2, arg3);
+}
+
+static void __inline
+ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs)
+{
+ if (vap->iv_rate->ir_setinterval == NULL)
+ return;
+ vap->iv_rate->ir_setinterval(vap, msecs);
+}
diff --git a/sys/net80211/ieee80211_rssadapt.c b/sys/net80211/ieee80211_rssadapt.c
index f1fc409..ad329e0 100644
--- a/sys/net80211/ieee80211_rssadapt.c
+++ b/sys/net80211/ieee80211_rssadapt.c
@@ -1,6 +1,7 @@
/* $FreeBSD$ */
/* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */
/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
@@ -42,6 +43,7 @@
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_rssadapt.h>
+#include <net80211/ieee80211_ratectl.h>
struct rssadapt_expavgctl {
/* RSS threshold decay. */
@@ -71,15 +73,45 @@ static struct rssadapt_expavgctl master_expavgctl = {
(parm##_denom - parm##_old) * (new)) / \
parm##_denom)
-static void rssadapt_sysctlattach(struct ieee80211_rssadapt *rs,
- struct sysctl_ctx_list *ctx, struct sysctl_oid *tree);
+static void rssadapt_setinterval(const struct ieee80211vap *, int);
+static void rssadapt_init(struct ieee80211vap *);
+static void rssadapt_deinit(struct ieee80211vap *);
+static void rssadapt_updatestats(struct ieee80211_rssadapt_node *);
+static void rssadapt_node_init(struct ieee80211_node *);
+static void rssadapt_node_deinit(struct ieee80211_node *);
+static int rssadapt_rate(struct ieee80211_node *, void *, uint32_t);
+static void rssadapt_lower_rate(struct ieee80211_rssadapt_node *, int, int);
+static void rssadapt_raise_rate(struct ieee80211_rssadapt_node *,
+ int, int);
+static void rssadapt_tx_complete(const struct ieee80211vap *,
+ const struct ieee80211_node *, int,
+ void *, void *);
+static void rssadapt_sysctlattach(struct ieee80211vap *,
+ struct sysctl_ctx_list *, struct sysctl_oid *);
/* number of references from net80211 layer */
static int nrefs = 0;
-void
-ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs)
+static const struct ieee80211_ratectl rssadapt = {
+ .ir_name = "rssadapt",
+ .ir_attach = NULL,
+ .ir_detach = NULL,
+ .ir_init = rssadapt_init,
+ .ir_deinit = rssadapt_deinit,
+ .ir_node_init = rssadapt_node_init,
+ .ir_node_deinit = rssadapt_node_deinit,
+ .ir_rate = rssadapt_rate,
+ .ir_tx_complete = rssadapt_tx_complete,
+ .ir_tx_update = NULL,
+ .ir_setinterval = rssadapt_setinterval,
+};
+IEEE80211_RATECTL_MODULE(rssadapt, 1);
+IEEE80211_RATECTL_ALG(rssadapt, IEEE80211_RATECTL_RSSADAPT, rssadapt);
+
+static void
+rssadapt_setinterval(const struct ieee80211vap *vap, int msecs)
{
+ struct ieee80211_rssadapt *rs = vap->iv_rs;
int t;
if (msecs < 100)
@@ -88,18 +120,29 @@ ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs)
rs->interval = (t < 1) ? 1 : t;
}
-void
-ieee80211_rssadapt_init(struct ieee80211_rssadapt *rs, struct ieee80211vap *vap, int interval)
+static void
+rssadapt_init(struct ieee80211vap *vap)
{
+ struct ieee80211_rssadapt *rs;
+
+ KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized",
+ __func__));
+
+ vap->iv_rs = rs = malloc(sizeof(struct ieee80211_rssadapt),
+ M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ if (rs == NULL) {
+ if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
+ return;
+ }
rs->vap = vap;
- ieee80211_rssadapt_setinterval(rs, interval);
-
- rssadapt_sysctlattach(rs, vap->iv_sysctl, vap->iv_oid);
+ rssadapt_setinterval(vap, 500 /* msecs */);
+ rssadapt_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid);
}
-void
-ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *rs)
+static void
+rssadapt_deinit(struct ieee80211vap *vap)
{
+ free(vap->iv_rs, M_80211_RATECTL);
}
static void
@@ -118,12 +161,21 @@ rssadapt_updatestats(struct ieee80211_rssadapt_node *ra)
ra->ra_raise_interval = msecs_to_ticks(interval);
}
-void
-ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa,
- struct ieee80211_rssadapt_node *ra, struct ieee80211_node *ni)
+static void
+rssadapt_node_init(struct ieee80211_node *ni)
{
+ struct ieee80211_rssadapt_node *ra;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_rssadapt *rsa = vap->iv_rs;
const struct ieee80211_rateset *rs = &ni->ni_rates;
+ ni->ni_rctls = ra = malloc(sizeof(struct ieee80211_rssadapt_node),
+ M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ if (ra == NULL) {
+ if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
+ "structure\n");
+ return;
+ }
ra->ra_rs = rsa;
ra->ra_rates = *rs;
rssadapt_updatestats(ra);
@@ -140,6 +192,13 @@ ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa,
"RSSADAPT initial rate %d", ni->ni_txrate);
}
+static void
+rssadapt_node_deinit(struct ieee80211_node *ni)
+{
+
+ free(ni->ni_rctls, M_80211_RATECTL);
+}
+
static __inline int
bucket(int pktlen)
{
@@ -155,10 +214,11 @@ bucket(int pktlen)
return thridx;
}
-int
-ieee80211_rssadapt_choose(struct ieee80211_node *ni,
- struct ieee80211_rssadapt_node *ra, u_int pktlen)
+static int
+rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg)
{
+ struct ieee80211_rssadapt_node *ra = ni->ni_rctls;
+ u_int pktlen = iarg;
const struct ieee80211_rateset *rs = &ra->ra_rates;
uint16_t (*thrs)[IEEE80211_RATE_SIZE];
int rix, rssi;
@@ -193,9 +253,8 @@ ieee80211_rssadapt_choose(struct ieee80211_node *ni,
* raise the RSS threshold for transmitting packets of similar length at
* the same data rate.
*/
-void
-ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra,
- int pktlen, int rssi)
+static void
+rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi)
{
uint16_t last_thr;
uint16_t (*thrs)[IEEE80211_RATE_SIZE];
@@ -214,9 +273,8 @@ ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra,
last_thr, (*thrs)[rix], rssi);
}
-void
-ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra,
- int pktlen, int rssi)
+static void
+rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi)
{
uint16_t (*thrs)[IEEE80211_RATE_SIZE];
uint16_t newthr, oldthr;
@@ -243,31 +301,45 @@ ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra,
}
}
+static void
+rssadapt_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int success, void *arg1, void *arg2)
+{
+ struct ieee80211_rssadapt_node *ra = ni->ni_rctls;
+ int pktlen = *(int *)arg1, rssi = *(int *)arg2;
+
+ if (success) {
+ ra->ra_nok++;
+ if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates &&
+ (ticks - ra->ra_last_raise) >= ra->ra_raise_interval)
+ rssadapt_raise_rate(ra, pktlen, rssi);
+ } else {
+ ra->ra_nfail++;
+ rssadapt_lower_rate(ra, pktlen, rssi);
+ }
+}
+
static int
rssadapt_sysctl_interval(SYSCTL_HANDLER_ARGS)
{
- struct ieee80211_rssadapt *rs = arg1;
+ struct ieee80211vap *vap = arg1;
+ struct ieee80211_rssadapt *rs = vap->iv_rs;
int msecs = ticks_to_msecs(rs->interval);
int error;
error = sysctl_handle_int(oidp, &msecs, 0, req);
if (error || !req->newptr)
return error;
- ieee80211_rssadapt_setinterval(rs, msecs);
+ rssadapt_setinterval(vap, msecs);
return 0;
}
static void
-rssadapt_sysctlattach(struct ieee80211_rssadapt *rs,
+rssadapt_sysctlattach(struct ieee80211vap *vap,
struct sysctl_ctx_list *ctx, struct sysctl_oid *tree)
{
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, rs,
+ "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap,
0, rssadapt_sysctl_interval, "I", "rssadapt operation interval (ms)");
}
-
-/*
- * Module glue.
- */
-IEEE80211_RATE_MODULE(rssadapt, 1);
diff --git a/sys/net80211/ieee80211_rssadapt.h b/sys/net80211/ieee80211_rssadapt.h
index b454f43..ee1d2d9 100644
--- a/sys/net80211/ieee80211_rssadapt.h
+++ b/sys/net80211/ieee80211_rssadapt.h
@@ -43,7 +43,7 @@
#define IEEE80211_RSSADAPT_BKTPOWER 3 /* 2**_BKTPOWER */
struct ieee80211_rssadapt {
- struct ieee80211vap *vap;
+ const struct ieee80211vap *vap;
int interval; /* update interval (ticks) */
};
@@ -66,36 +66,6 @@ struct ieee80211_rssadapt_node {
[IEEE80211_RATE_SIZE];
};
-void ieee80211_rssadapt_init(struct ieee80211_rssadapt *,
- struct ieee80211vap *, int);
-void ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *);
-void ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *, int);
-void ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *,
- struct ieee80211_rssadapt_node *, struct ieee80211_node *);
-int ieee80211_rssadapt_choose(struct ieee80211_node *,
- struct ieee80211_rssadapt_node *, u_int);
-
-/* NB: these are public only for the inline below */
-void ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *,
- int pktlen, int rssi);
-void ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *,
- int pktlen, int rssi);
-
#define IEEE80211_RSSADAPT_SUCCESS 1
#define IEEE80211_RSSADAPT_FAILURE 0
-
-static __inline void
-ieee80211_rssadapt_tx_complete(struct ieee80211_rssadapt_node *ra,
- int success, int pktlen, int rssi)
-{
- if (success) {
- ra->ra_nok++;
- if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates &&
- (ticks - ra->ra_last_raise) >= ra->ra_raise_interval)
- ieee80211_rssadapt_raise_rate(ra, pktlen, rssi);
- } else {
- ra->ra_nfail++;
- ieee80211_rssadapt_lower_rate(ra, pktlen, rssi);
- }
-}
#endif /* _NET80211_IEEE80211_RSSADAPT_H_ */
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
index e697ad4..a4808e2 100644
--- a/sys/net80211/ieee80211_scan_sta.c
+++ b/sys/net80211/ieee80211_scan_sta.c
@@ -97,7 +97,7 @@ struct sta_entry {
CTASSERT(MAX_IEEE_CHAN >= 256);
struct sta_table {
- struct mtx st_lock; /* on scan table */
+ ieee80211_scan_table_lock_t st_lock; /* on scan table */
TAILQ_HEAD(, sta_entry) st_entry; /* all entries */
LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE];
struct mtx st_scanlock; /* on st_scaniter */
@@ -161,7 +161,7 @@ sta_attach(struct ieee80211_scan_state *ss)
M_80211_SCAN, M_NOWAIT | M_ZERO);
if (st == NULL)
return 0;
- mtx_init(&st->st_lock, "scantable", "802.11 scan table", MTX_DEF);
+ IEEE80211_SCAN_TABLE_LOCK_INIT(st, "scantable");
mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF);
TAILQ_INIT(&st->st_entry);
ss->ss_priv = st;
@@ -179,7 +179,7 @@ sta_detach(struct ieee80211_scan_state *ss)
if (st != NULL) {
sta_flush_table(st);
- mtx_destroy(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK_DESTROY(st);
mtx_destroy(&st->st_scanlock);
free(st, M_80211_SCAN);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
@@ -196,9 +196,9 @@ sta_flush(struct ieee80211_scan_state *ss)
{
struct sta_table *st = ss->ss_priv;
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
sta_flush_table(st);
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
ss->ss_last = 0;
return 0;
}
@@ -244,14 +244,14 @@ sta_add(struct ieee80211_scan_state *ss,
hash = STA_HASH(macaddr);
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
goto found;
se = (struct sta_entry *) malloc(sizeof(struct sta_entry),
M_80211_SCAN, M_NOWAIT | M_ZERO);
if (se == NULL) {
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
return 0;
}
se->se_scangen = st->st_scaniter-1;
@@ -370,7 +370,7 @@ found:
if (rssi > st->st_maxrssi[sp->bchan])
st->st_maxrssi[sp->bchan] = rssi;
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
/*
* If looking for a quick choice and nothing's
@@ -1132,7 +1132,7 @@ sta_update_notseen(struct sta_table *st)
{
struct sta_entry *se;
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
TAILQ_FOREACH(se, &st->st_entry, se_list) {
/*
* If seen the reset and don't bump the count;
@@ -1146,7 +1146,7 @@ sta_update_notseen(struct sta_table *st)
else
se->se_notseen++;
}
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
}
static void
@@ -1154,11 +1154,11 @@ sta_dec_fails(struct sta_table *st)
{
struct sta_entry *se;
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
TAILQ_FOREACH(se, &st->st_entry, se_list)
if (se->se_fails)
se->se_fails--;
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
}
static struct sta_entry *
@@ -1169,7 +1169,7 @@ select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug)
IEEE80211_DPRINTF(vap, debug, " %s\n",
"macaddr bssid chan rssi rate flag wep essid");
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
TAILQ_FOREACH(se, &st->st_entry, se_list) {
ieee80211_ies_expand(&se->base.se_ies);
if (match_bss(vap, ss, se, debug) == 0) {
@@ -1179,7 +1179,7 @@ select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug)
selbs = se;
}
}
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
return selbs;
}
@@ -1258,11 +1258,11 @@ sta_lookup(struct sta_table *st, const uint8_t macaddr[IEEE80211_ADDR_LEN])
struct sta_entry *se;
int hash = STA_HASH(macaddr);
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
break;
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
return se; /* NB: unlocked */
}
@@ -1382,18 +1382,18 @@ sta_iterate(struct ieee80211_scan_state *ss,
mtx_lock(&st->st_scanlock);
gen = st->st_scaniter++;
restart:
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
TAILQ_FOREACH(se, &st->st_entry, se_list) {
if (se->se_scangen != gen) {
se->se_scangen = gen;
/* update public state */
se->base.se_age = ticks - se->se_lastupdate;
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
(*f)(arg, &se->base);
goto restart;
}
}
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
mtx_unlock(&st->st_scanlock);
}
@@ -1510,7 +1510,7 @@ adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags)
bestchan = NULL;
bestrssi = -1;
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
for (i = 0; i < ss->ss_last; i++) {
c = ss->ss_chans[i];
/* never consider a channel with radar */
@@ -1532,7 +1532,7 @@ adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags)
if (bestchan == NULL || maxrssi < bestrssi)
bestchan = c;
}
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
return bestchan;
}
@@ -1638,7 +1638,7 @@ adhoc_age(struct ieee80211_scan_state *ss)
struct sta_table *st = ss->ss_priv;
struct sta_entry *se, *next;
- mtx_lock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_LOCK(st);
TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) {
if (se->se_notseen > STA_PURGE_SCANS) {
TAILQ_REMOVE(&st->st_entry, se, se_list);
@@ -1647,7 +1647,7 @@ adhoc_age(struct ieee80211_scan_state *ss)
free(se, M_80211_SCAN);
}
}
- mtx_unlock(&st->st_lock);
+ IEEE80211_SCAN_TABLE_UNLOCK(st);
}
static const struct ieee80211_scanner adhoc_default = {
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 743fe48..adf8fb5 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -141,6 +141,8 @@ sta_beacon_miss(struct ieee80211vap *vap)
vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen);
return;
}
+
+ callout_stop(&vap->iv_swbmiss);
vap->iv_bmiss_count = 0;
vap->iv_stats.is_beacon_miss++;
if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) {
@@ -1737,6 +1739,11 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
}
static void
-sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m0, int subtype)
+sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_BAR:
+ ieee80211_recv_bar(ni, m);
+ break;
+ }
}
diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c
index 43f32f7..8c191ab 100644
--- a/sys/net80211/ieee80211_tdma.c
+++ b/sys/net80211/ieee80211_tdma.c
@@ -295,6 +295,8 @@ tdma_beacon_miss(struct ieee80211vap *vap)
"beacon miss, mode %u state %s\n",
vap->iv_opmode, ieee80211_state_name[vap->iv_state]);
+ callout_stop(&vap->iv_swbmiss);
+
if (ts->tdma_peer != NULL) { /* XXX? can this be null? */
ieee80211_notify_node_leave(vap->iv_bss);
ts->tdma_peer = NULL;
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index d6f3e66..ff3694f 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -137,6 +137,7 @@ struct ieee80211com {
uint32_t ic_flags_ven; /* vendor state flags */
uint32_t ic_caps; /* capabilities */
uint32_t ic_htcaps; /* HT capabilities */
+ uint32_t ic_htextcaps; /* HT extended capabilities */
uint32_t ic_cryptocaps; /* crypto capabilities */
uint8_t ic_modecaps[2]; /* set of mode capabilities */
uint8_t ic_promisc; /* vap's needing promisc mode */
@@ -313,7 +314,8 @@ struct ieee80211com {
int batimeout, int baseqctl);
void (*ic_ampdu_rx_stop)(struct ieee80211_node *,
struct ieee80211_rx_ampdu *);
- uint64_t ic_spare[8];
+ uint64_t ic_spare[7];
+ uint32_t ic_spare2;
};
struct ieee80211_aclator;
@@ -340,6 +342,7 @@ struct ieee80211vap {
uint32_t iv_flags_ven; /* vendor state flags */
uint32_t iv_caps; /* capabilities */
uint32_t iv_htcaps; /* HT capabilities */
+ uint32_t iv_htextcaps; /* HT extended capabilities */
enum ieee80211_opmode iv_opmode; /* operation mode */
enum ieee80211_state iv_state; /* state machine state */
enum ieee80211_state iv_nstate; /* pending state */
@@ -433,6 +436,9 @@ struct ieee80211vap {
const struct ieee80211_aclator *iv_acl; /* acl glue */
void *iv_as; /* private aclator state */
+ const struct ieee80211_ratectl *iv_rate;
+ void *iv_rs; /* private ratectl state */
+
struct ieee80211_tdma_state *iv_tdma; /* tdma state */
struct ieee80211_mesh_state *iv_mesh; /* MBSS state */
struct ieee80211_hwmp_state *iv_hwmp; /* HWMP state */
@@ -468,7 +474,7 @@ struct ieee80211vap {
/* 802.3 output method for raw frame xmit */
int (*iv_output)(struct ifnet *, struct mbuf *,
struct sockaddr *, struct route *);
- uint64_t iv_spare[8];
+ uint64_t iv_spare[6];
};
MALLOC_DECLARE(M_80211_VAP);
@@ -849,10 +855,10 @@ ieee80211_htchanflags(const struct ieee80211_channel *c)
if (ieee80211_msg(_vap, _m)) \
ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__); \
} while (0)
-void ieee80211_note(struct ieee80211vap *, const char *, ...);
-void ieee80211_note_mac(struct ieee80211vap *,
+void ieee80211_note(const struct ieee80211vap *, const char *, ...);
+void ieee80211_note_mac(const struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...);
-void ieee80211_note_frame(struct ieee80211vap *,
+void ieee80211_note_frame(const struct ieee80211vap *,
const struct ieee80211_frame *, const char *, ...);
#define ieee80211_msg_debug(_vap) \
((_vap)->iv_debug & IEEE80211_MSG_DEBUG)
@@ -890,11 +896,11 @@ void ieee80211_note_frame(struct ieee80211vap *,
ieee80211_discard_mac(_vap, _mac, _type, _fmt, __VA_ARGS__);\
} while (0)
-void ieee80211_discard_frame(struct ieee80211vap *,
+void ieee80211_discard_frame(const struct ieee80211vap *,
const struct ieee80211_frame *, const char *type, const char *fmt, ...);
-void ieee80211_discard_ie(struct ieee80211vap *,
+void ieee80211_discard_ie(const struct ieee80211vap *,
const struct ieee80211_frame *, const char *type, const char *fmt, ...);
-void ieee80211_discard_mac(struct ieee80211vap *,
+void ieee80211_discard_mac(const struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN], const char *type,
const char *fmt, ...);
#else
diff --git a/sys/netgraph/netflow/ng_netflow.c b/sys/netgraph/netflow/ng_netflow.c
index cacbd72..8bf4845 100644
--- a/sys/netgraph/netflow/ng_netflow.c
+++ b/sys/netgraph/netflow/ng_netflow.c
@@ -286,15 +286,6 @@ ng_netflow_newhook(node_p node, hook_p hook, const char *name)
priv->export = hook;
-#if 0 /* TODO: profile & test first */
- /*
- * We send export dgrams in interrupt handlers and in
- * callout threads. We'd better queue data for later
- * netgraph ISR processing.
- */
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
-#endif
-
/* Exporter is ready. Let's schedule expiry. */
callout_reset(&priv->exp_callout, (1*hz), &ng_netflow_expire,
(void *)priv);
diff --git a/sys/netgraph/ng_deflate.c b/sys/netgraph/ng_deflate.c
index b248a83..f3ce1c0 100644
--- a/sys/netgraph/ng_deflate.c
+++ b/sys/netgraph/ng_deflate.c
@@ -36,6 +36,7 @@
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/syslog.h>
@@ -505,8 +506,8 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
priv->stats.OutOctets+=inlen;
} else {
/* Install header. */
- ((u_int16_t *)priv->outbuf)[0] = htons(PROT_COMPD);
- ((u_int16_t *)priv->outbuf)[1] = htons(priv->seqnum);
+ be16enc(priv->outbuf, PROT_COMPD);
+ be16enc(priv->outbuf + 2, priv->seqnum);
/* Return packet in an mbuf. */
m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
@@ -568,7 +569,7 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
proto = priv->inbuf[0];
offset = 1;
} else {
- proto = ntohs(((uint16_t *)priv->inbuf)[0]);
+ proto = be16dec(priv->inbuf);
offset = 2;
}
@@ -579,7 +580,7 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
priv->stats.FramesComp++;
/* Check sequence number. */
- rseqnum = ntohs(((uint16_t *)(priv->inbuf + offset))[0]);
+ rseqnum = be16dec(priv->inbuf + offset);
offset += 2;
if (rseqnum != priv->seqnum) {
priv->stats.Errors++;
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
index d1571b1..260eba9 100644
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -902,12 +902,24 @@ ng_ksocket_rcvdata(hook_p hook, item_p item)
struct sockaddr *sa = NULL;
int error;
struct mbuf *m;
+#ifdef ALIGNED_POINTER
+ struct mbuf *n;
+#endif /* ALIGNED_POINTER */
struct sa_tag *stag;
/* Extract data */
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
-
+#ifdef ALIGNED_POINTER
+ if (!ALIGNED_POINTER(mtod(m, caddr_t), uint32_t)) {
+ n = m_defrag(m, M_NOWAIT);
+ if (n == NULL) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+ m = n;
+ }
+#endif /* ALIGNED_POINTER */
/*
* Look if socket address is stored in packet tags.
* If sockaddr is ours, or provided by a third party (zero id),
diff --git a/sys/netgraph/ng_l2tp.c b/sys/netgraph/ng_l2tp.c
index a5bb628..ce15bc1 100644
--- a/sys/netgraph/ng_l2tp.c
+++ b/sys/netgraph/ng_l2tp.c
@@ -790,7 +790,7 @@ ng_l2tp_rcvdata_lower(hook_p h, item_p item)
NG_FREE_ITEM(item);
ERROUT(EINVAL);
}
- hdr = ntohs(*mtod(m, u_int16_t *));
+ hdr = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1];
m_adj(m, 2);
/* Check required header bits and minimum length */
@@ -819,7 +819,7 @@ ng_l2tp_rcvdata_lower(hook_p h, item_p item)
NG_FREE_ITEM(item);
ERROUT(EINVAL);
}
- len = (u_int16_t)ntohs(*mtod(m, u_int16_t *)) - 4;
+ len = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1] - 4;
m_adj(m, 2);
if (len < 0 || len > m->m_pkthdr.len) {
priv->stats.recvInvalid++;
@@ -1095,9 +1095,10 @@ ng_l2tp_rcvdata(hook_p hook, item_p item)
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook);
struct mbuf *m;
+ uint8_t *p;
u_int16_t hdr;
int error;
- int i = 1;
+ int i = 2;
/* Sanity check */
L2TP_SEQ_CHECK(&priv->seq);
@@ -1129,20 +1130,27 @@ ng_l2tp_rcvdata(hook_p hook, item_p item)
NG_FREE_ITEM(item);
ERROUT(ENOBUFS);
}
+ p = mtod(m, uint8_t *);
hdr = L2TP_DATA_HDR;
if (hpriv->conf.include_length) {
hdr |= L2TP_HDR_LEN;
- mtod(m, u_int16_t *)[i++] = htons(m->m_pkthdr.len);
+ p[i++] = m->m_pkthdr.len >> 8;
+ p[i++] = m->m_pkthdr.len & 0xff;
}
- mtod(m, u_int16_t *)[i++] = htons(priv->conf.peer_id);
- mtod(m, u_int16_t *)[i++] = htons(hpriv->conf.peer_id);
+ p[i++] = priv->conf.peer_id >> 8;
+ p[i++] = priv->conf.peer_id & 0xff;
+ p[i++] = hpriv->conf.peer_id >> 8;
+ p[i++] = hpriv->conf.peer_id & 0xff;
if (hpriv->conf.enable_dseq) {
hdr |= L2TP_HDR_SEQ;
- mtod(m, u_int16_t *)[i++] = htons(hpriv->ns);
- mtod(m, u_int16_t *)[i++] = htons(hpriv->nr);
+ p[i++] = hpriv->ns >> 8;
+ p[i++] = hpriv->ns & 0xff;
+ p[i++] = hpriv->nr >> 8;
+ p[i++] = hpriv->nr & 0xff;
hpriv->ns++;
}
- mtod(m, u_int16_t *)[0] = htons(hdr);
+ p[0] = hdr >> 8;
+ p[1] = hdr & 0xff;
/* Update per session stats. */
hpriv->stats.xmitPackets++;
@@ -1496,6 +1504,7 @@ static int
ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns)
{
struct l2tp_seq *const seq = &priv->seq;
+ uint8_t *p;
u_int16_t session_id = 0;
int error;
@@ -1540,12 +1549,19 @@ ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns)
}
/* Fill in L2TP header */
- mtod(m, u_int16_t *)[0] = htons(L2TP_CTRL_HDR);
- mtod(m, u_int16_t *)[1] = htons(m->m_pkthdr.len);
- mtod(m, u_int16_t *)[2] = htons(priv->conf.peer_id);
- mtod(m, u_int16_t *)[3] = htons(session_id);
- mtod(m, u_int16_t *)[4] = htons(ns);
- mtod(m, u_int16_t *)[5] = htons(seq->nr);
+ p = mtod(m, u_int8_t *);
+ p[0] = L2TP_CTRL_HDR >> 8;
+ p[1] = L2TP_CTRL_HDR & 0xff;
+ p[2] = m->m_pkthdr.len >> 8;
+ p[3] = m->m_pkthdr.len & 0xff;
+ p[4] = priv->conf.peer_id >> 8;
+ p[5] = priv->conf.peer_id & 0xff;
+ p[6] = session_id >> 8;
+ p[7] = session_id & 0xff;
+ p[8] = ns >> 8;
+ p[9] = ns & 0xff;
+ p[10] = seq->nr >> 8;
+ p[11] = seq->nr & 0xff;
/* Update sequence number info and stats */
priv->stats.xmitPackets++;
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
index e934481..074c018 100644
--- a/sys/netgraph/ng_mppc.c
+++ b/sys/netgraph/ng_mppc.c
@@ -53,6 +53,7 @@
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/syslog.h>
@@ -601,7 +602,7 @@ err1:
/* Install header */
M_PREPEND(m, MPPC_HDRLEN, M_DONTWAIT);
if (m != NULL)
- *(mtod(m, uint16_t *)) = htons(header);
+ be16enc(mtod(m, void *), header);
*datap = m;
return (*datap == NULL ? ENOBUFS : 0);
@@ -630,8 +631,7 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
m_freem(m);
return (EINVAL);
}
- m_copydata(m, 0, MPPC_HDRLEN, (caddr_t)&header);
- header = ntohs(header);
+ header = be16dec(mtod(m, void *));
cc = (header & MPPC_CCOUNT_MASK);
m_adj(m, MPPC_HDRLEN);
diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c
index 5f5e410..a094646 100644
--- a/sys/netgraph/ng_pipe.c
+++ b/sys/netgraph/ng_pipe.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2004-2008 University of Zagreb
* Copyright (c) 2007-2008 FreeBSD Foundation
*
diff --git a/sys/netgraph/ng_pipe.h b/sys/netgraph/ng_pipe.h
index e468605..6885ed5 100644
--- a/sys/netgraph/ng_pipe.h
+++ b/sys/netgraph/ng_pipe.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2004-2008 University of Zagreb
* Copyright (c) 2007-2008 FreeBSD Foundation
*
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
index b2b0cb0..e5897f3 100644
--- a/sys/netgraph/ng_ppp.c
+++ b/sys/netgraph/ng_ppp.c
@@ -97,6 +97,7 @@
#include <sys/time.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/ctype.h>
@@ -860,8 +861,8 @@ ng_ppp_rcvdata_bypass(hook_p hook, item_p item)
NG_FREE_ITEM(item);
return (ENOBUFS);
}
- linkNum = ntohs(mtod(m, uint16_t *)[0]);
- proto = ntohs(mtod(m, uint16_t *)[1]);
+ linkNum = be16dec(mtod(m, uint8_t *));
+ proto = be16dec(mtod(m, uint8_t *) + 2);
m_adj(m, 4);
NGI_M(item) = m;
@@ -907,7 +908,21 @@ ng_ppp_proto_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
const priv_p priv = NG_NODE_PRIVATE(node);
hook_p outHook = NULL;
int error;
+#ifdef ALIGNED_POINTER
+ struct mbuf *m, *n;
+ NGI_GET_M(item, m);
+ if (!ALIGNED_POINTER(mtod(m, caddr_t), uint32_t)) {
+ n = m_defrag(m, M_NOWAIT);
+ if (n == NULL) {
+ m_freem(m);
+ NG_FREE_ITEM(item);
+ return (ENOBUFS);
+ }
+ m = n;
+ }
+ NGI_M(item) = m;
+#endif /* ALIGNED_POINTER */
switch (proto) {
case PROT_IP:
if (priv->conf.enableIP)
@@ -1530,7 +1545,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL)
ERROUT(ENOBUFS);
- shdr = ntohs(*mtod(m, uint16_t *));
+ shdr = be16dec(mtod(m, void *));
frag->seq = MP_SHORT_EXTEND(shdr);
frag->first = (shdr & MP_SHORT_FIRST_FLAG) != 0;
frag->last = (shdr & MP_SHORT_LAST_FLAG) != 0;
@@ -1547,7 +1562,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL)
ERROUT(ENOBUFS);
- lhdr = ntohl(*mtod(m, uint32_t *));
+ lhdr = be32dec(mtod(m, void *));
frag->seq = MP_LONG_EXTEND(lhdr);
frag->first = (lhdr & MP_LONG_FIRST_FLAG) != 0;
frag->last = (lhdr & MP_LONG_LAST_FLAG) != 0;
diff --git a/sys/netgraph/ng_pptpgre.c b/sys/netgraph/ng_pptpgre.c
index 5c5d128..606d278 100644
--- a/sys/netgraph/ng_pptpgre.c
+++ b/sys/netgraph/ng_pptpgre.c
@@ -62,6 +62,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
+#include <sys/endian.h>
#include <sys/errno.h>
#include <netinet/in.h>
@@ -572,9 +573,9 @@ ng_pptpgre_xmit(hpriv_p hpriv, item_p item)
}
/* Build GRE header */
- ((u_int32_t *)gre)[0] = htonl(PPTP_INIT_VALUE);
- gre->length = (m != NULL) ? htons((u_short)m->m_pkthdr.len) : 0;
- gre->cid = htons(hpriv->conf.peerCid);
+ be32enc(gre, PPTP_INIT_VALUE);
+ be16enc(&gre->length, (m != NULL) ? m->m_pkthdr.len : 0);
+ be16enc(&gre->cid, hpriv->conf.peerCid);
/* Include sequence number if packet contains any data */
if (m != NULL) {
@@ -584,13 +585,13 @@ ng_pptpgre_xmit(hpriv_p hpriv, item_p item)
= ng_pptpgre_time();
}
hpriv->xmitSeq++;
- gre->data[0] = htonl(hpriv->xmitSeq);
+ be32enc(&gre->data[0], hpriv->xmitSeq);
}
/* Include acknowledgement (and stop send ack timer) if needed */
if (hpriv->conf.enableAlwaysAck || hpriv->xmitAck != hpriv->recvSeq) {
gre->hasAck = 1;
- gre->data[gre->hasSeq] = htonl(hpriv->recvSeq);
+ be32enc(&gre->data[gre->hasSeq], hpriv->recvSeq);
hpriv->xmitAck = hpriv->recvSeq;
if (hpriv->conf.enableDelayedAck)
ng_uncallout(&hpriv->sackTimer, hpriv->node);
@@ -705,18 +706,17 @@ ng_pptpgre_rcvdata_lower(hook_p hook, item_p item)
/* Sanity check packet length and GRE header bits */
extralen = m->m_pkthdr.len
- - (iphlen + grelen + gre->hasSeq * (u_int16_t)ntohs(gre->length));
+ - (iphlen + grelen + gre->hasSeq * be16dec(&gre->length));
if (extralen < 0) {
priv->stats.recvBadGRE++;
ERROUT(EINVAL);
}
- if ((ntohl(*((const u_int32_t *)gre)) & PPTP_INIT_MASK)
- != PPTP_INIT_VALUE) {
+ if ((be32dec(gre) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) {
priv->stats.recvBadGRE++;
ERROUT(EINVAL);
}
- hpriv = ng_pptpgre_find_session(priv, ntohs(gre->cid));
+ hpriv = ng_pptpgre_find_session(priv, be16dec(&gre->cid));
if (hpriv == NULL || hpriv->hook == NULL || !hpriv->conf.enabled) {
priv->stats.recvBadCID++;
ERROUT(EINVAL);
@@ -725,7 +725,7 @@ ng_pptpgre_rcvdata_lower(hook_p hook, item_p item)
/* Look for peer ack */
if (gre->hasAck) {
- const u_int32_t ack = ntohl(gre->data[gre->hasSeq]);
+ const u_int32_t ack = be32dec(&gre->data[gre->hasSeq]);
const int index = ack - hpriv->recvAck - 1;
long sample;
long diff;
@@ -776,7 +776,7 @@ badAck:
/* See if frame contains any data */
if (gre->hasSeq) {
- const u_int32_t seq = ntohl(gre->data[0]);
+ const u_int32_t seq = be32dec(&gre->data[0]);
/* Sanity check sequence number */
if (PPTP_SEQ_DIFF(seq, hpriv->recvSeq) <= 0) {
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c
index af68c63..28e4f0e 100644
--- a/sys/netgraph/ng_socket.c
+++ b/sys/netgraph/ng_socket.c
@@ -156,6 +156,11 @@ static u_long ngpdg_recvspace = 20 * 1024;
SYSCTL_INT(_net_graph, OID_AUTO, recvspace, CTLFLAG_RW,
&ngpdg_recvspace , 0, "Maximum space for incoming Netgraph datagrams");
+/* List of all sockets (for netstat -f netgraph) */
+static LIST_HEAD(, ngpcb) ngsocklist;
+
+static struct mtx ngsocketlist_mtx;
+
#define sotongpcb(so) ((struct ngpcb *)(so)->so_pcb)
/* If getting unexplained errors returned, set this to "kdb_enter("X"); */
@@ -547,6 +552,9 @@ ng_attach_cntl(struct socket *so)
return (error);
}
+ /* Store a hint for netstat(1). */
+ priv->node_id = priv->node->nd_ID;
+
/* Link the node and the private data. */
NG_NODE_SET_PRIVATE(priv->node, priv);
NG_NODE_REF(priv->node);
@@ -584,6 +592,10 @@ ng_attach_common(struct socket *so, int type)
so->so_pcb = (caddr_t)pcbp;
pcbp->ng_socket = so;
+ /* Add the socket to linked list */
+ mtx_lock(&ngsocketlist_mtx);
+ LIST_INSERT_HEAD(&ngsocklist, pcbp, socks);
+ mtx_unlock(&ngsocketlist_mtx);
return (0);
}
@@ -617,6 +629,9 @@ ng_detach_common(struct ngpcb *pcbp, int which)
}
pcbp->ng_socket->so_pcb = NULL;
+ mtx_lock(&ngsocketlist_mtx);
+ LIST_REMOVE(pcbp, socks);
+ mtx_unlock(&ngsocketlist_mtx);
free(pcbp, M_PCB);
}
@@ -1115,8 +1130,14 @@ ngs_mod_event(module_t mod, int event, void *data)
switch (event) {
case MOD_LOAD:
+ mtx_init(&ngsocketlist_mtx, "ng_socketlist", NULL, MTX_DEF);
break;
case MOD_UNLOAD:
+ /* Ensure there are no open netgraph sockets. */
+ if (!LIST_EMPTY(&ngsocklist)) {
+ error = EBUSY;
+ break;
+ }
#ifdef NOTYET
/* Unregister protocol domain XXX can't do this yet.. */
#endif
diff --git a/sys/netgraph/ng_socketvar.h b/sys/netgraph/ng_socketvar.h
index 3cf8103..c1e59dc 100644
--- a/sys/netgraph/ng_socketvar.h
+++ b/sys/netgraph/ng_socketvar.h
@@ -61,6 +61,7 @@ struct ngsock {
int refs;
struct mtx mtx; /* mtx to wait on */
int error; /* place to store error */
+ ng_ID_t node_id; /* a hint for netstat(1) to find the node */
};
#define NGS_FLAG_NOLINGER 1 /* close with last hook */
diff --git a/sys/netgraph/ng_tcpmss.c b/sys/netgraph/ng_tcpmss.c
index bcc421a..19f9edc 100644
--- a/sys/netgraph/ng_tcpmss.c
+++ b/sys/netgraph/ng_tcpmss.c
@@ -47,6 +47,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -410,9 +411,9 @@ correct_mss(struct tcphdr *tc, int hlen, uint16_t maxmss, int flags)
{
int olen, optlen;
u_char *opt;
- uint16_t *mss;
int accumulate;
int res = 0;
+ uint16_t sum;
for (olen = hlen - sizeof(struct tcphdr), opt = (u_char *)(tc + 1);
olen > 0; olen -= optlen, opt += optlen) {
@@ -427,13 +428,15 @@ correct_mss(struct tcphdr *tc, int hlen, uint16_t maxmss, int flags)
if (*opt == TCPOPT_MAXSEG) {
if (optlen != TCPOLEN_MAXSEG)
continue;
- mss = (uint16_t *)(opt + 2);
- if (ntohs(*mss) > maxmss) {
- accumulate = *mss;
- *mss = htons(maxmss);
- accumulate -= *mss;
- if ((flags & CSUM_TCP) == 0)
- TCPMSS_ADJUST_CHECKSUM(accumulate, tc->th_sum);
+ accumulate = be16dec(opt + 2);
+ if (accumulate > maxmss) {
+ if ((flags & CSUM_TCP) == 0) {
+ accumulate -= maxmss;
+ sum = be16dec(&tc->th_sum);
+ TCPMSS_ADJUST_CHECKSUM(accumulate, sum);
+ be16enc(&tc->th_sum, sum);
+ }
+ be16enc(opt + 2, maxmss);
res = 1;
}
}
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 97152a7..25fba9f 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -180,6 +180,8 @@ arptimer(void *arg)
else {
if (!callout_pending(&lle->la_timer) &&
callout_active(&lle->la_timer)) {
+ callout_stop(&lle->la_timer);
+ LLE_REMREF(lle);
(void) llentry_free(lle);
ARPSTAT_INC(timeouts);
}
@@ -382,9 +384,14 @@ retry:
EHOSTUNREACH : EHOSTDOWN;
if (renew) {
+ int canceled;
+
LLE_ADDREF(la);
la->la_expire = time_second + V_arpt_down;
- callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la);
+ canceled = callout_reset(&la->la_timer, hz * V_arpt_down,
+ arptimer, la);
+ if (canceled)
+ LLE_REMREF(la);
la->la_asked++;
LLE_WUNLOCK(la);
arprequest(ifp, NULL, &SIN(dst)->sin_addr,
@@ -696,9 +703,14 @@ match:
EVENTHANDLER_INVOKE(arp_update_event, la);
if (!(la->la_flags & LLE_STATIC)) {
+ int canceled;
+
+ LLE_ADDREF(la);
la->la_expire = time_second + V_arpt_keep;
- callout_reset(&la->la_timer, hz * V_arpt_keep,
- arptimer, la);
+ canceled = callout_reset(&la->la_timer,
+ hz * V_arpt_keep, arptimer, la);
+ if (canceled)
+ LLE_REMREF(la);
}
la->la_asked = 0;
la->la_preempt = V_arp_maxtries;
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index b1c51a2..0a0fe47 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -34,6 +34,7 @@
__FBSDID("$FreeBSD$");
#include "opt_carp.h"
+#include "opt_mpath.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -1040,6 +1041,13 @@ in_addprefix(struct in_ifaddr *target, int flags)
* interface address, we are done here.
*/
if (ia->ia_flags & IFA_ROUTE) {
+#ifdef RADIX_MPATH
+ if (ia->ia_addr.sin_addr.s_addr ==
+ target->ia_addr.sin_addr.s_addr)
+ return (EEXIST);
+ else
+ break;
+#endif
if (V_sameprefixcarponly &&
target->ia_ifp->if_type != IFT_CARP &&
ia->ia_ifp->if_type != IFT_CARP) {
@@ -1349,8 +1357,12 @@ in_lltable_prefix_free(struct lltable *llt,
if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle),
pfx, msk)) {
- callout_drain(&lle->la_timer);
+ int canceled;
+
+ canceled = callout_drain(&lle->la_timer);
LLE_WLOCK(lle);
+ if (canceled)
+ LLE_REMREF(lle);
llentry_free(lle);
}
}
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 4f47658..9eb3b17 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -236,6 +236,7 @@ __END_DECLS
#define IPPROTO_GMTP 100 /* GMTP*/
#define IPPROTO_IPCOMP 108 /* payload compression (IPComp) */
#define IPPROTO_SCTP 132 /* SCTP */
+#define IPPROTO_MH 135 /* IPv6 Mobility Header */
/* 101-254: Partly Unassigned */
#define IPPROTO_PIM 103 /* Protocol Independent Mcast */
#define IPPROTO_CARP 112 /* CARP */
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index 1f658da..4edf309 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -1999,9 +1999,12 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
}
} else {
/*
- * MCAST_JOIN_GROUP alone, on any existing membership,
- * is rejected, to stop the same inpcb tying up
- * multiple refs to the in_multi.
+ * MCAST_JOIN_GROUP on an existing exclusive
+ * membership is an error; return EADDRINUSE
+ * to preserve 4.4BSD API idempotence, and
+ * avoid tedious detour to code below.
+ * NOTE: This is bending RFC 3678 a bit.
+ *
* On an existing inclusive membership, this is also
* an error; if you want to change filter mode,
* you must use the userland API setsourcefilter().
@@ -2010,6 +2013,8 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
* is atomic with allocation of a membership.
*/
error = EINVAL;
+ if (imf->imf_st[1] == MCAST_EXCLUDE)
+ error = EADDRINUSE;
goto out_inp_locked;
}
}
@@ -2186,7 +2191,14 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
ssa->sin.sin_addr = mreqs.imr_sourceaddr;
}
- if (!in_nullhost(gsa->sin.sin_addr))
+ /*
+ * Attempt to look up hinted ifp from interface address.
+ * Fallthrough with null ifp iff lookup fails, to
+ * preserve 4.4BSD mcast API idempotence.
+ * XXX NOTE WELL: The RFC 3678 API is preferred because
+ * using an IPv4 address as a key is racy.
+ */
+ if (!in_nullhost(mreqs.imr_interface))
INADDR_TO_IFP(mreqs.imr_interface, ifp);
CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",
@@ -2222,6 +2234,9 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
return (EADDRNOTAVAIL);
ifp = ifnet_byindex(gsr.gsr_interface);
+
+ if (ifp == NULL)
+ return (EADDRNOTAVAIL);
break;
default:
@@ -2234,9 +2249,6 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
return (EINVAL);
- if (ifp == NULL)
- return (EADDRNOTAVAIL);
-
/*
* Find the membership in the membership array.
*/
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 204d904..8a291e4 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -184,6 +184,47 @@ SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, CTLFLAG_RW,
*/
/*
+ * Initialize an inpcbinfo -- we should be able to reduce the number of
+ * arguments in time.
+ */
+void
+in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name,
+ struct inpcbhead *listhead, int hash_nelements, int porthash_nelements,
+ char *inpcbzone_name, uma_init inpcbzone_init, uma_fini inpcbzone_fini,
+ uint32_t inpcbzone_flags)
+{
+
+ INP_INFO_LOCK_INIT(pcbinfo, name);
+#ifdef VIMAGE
+ pcbinfo->ipi_vnet = curvnet;
+#endif
+ pcbinfo->ipi_listhead = listhead;
+ LIST_INIT(pcbinfo->ipi_listhead);
+ pcbinfo->ipi_hashbase = hashinit(hash_nelements, M_PCB,
+ &pcbinfo->ipi_hashmask);
+ pcbinfo->ipi_porthashbase = hashinit(porthash_nelements, M_PCB,
+ &pcbinfo->ipi_porthashmask);
+ pcbinfo->ipi_zone = uma_zcreate(inpcbzone_name, sizeof(struct inpcb),
+ NULL, NULL, inpcbzone_init, inpcbzone_fini, UMA_ALIGN_PTR,
+ inpcbzone_flags);
+ uma_zone_set_max(pcbinfo->ipi_zone, maxsockets);
+}
+
+/*
+ * Destroy an inpcbinfo.
+ */
+void
+in_pcbinfo_destroy(struct inpcbinfo *pcbinfo)
+{
+
+ hashdestroy(pcbinfo->ipi_hashbase, M_PCB, pcbinfo->ipi_hashmask);
+ hashdestroy(pcbinfo->ipi_porthashbase, M_PCB,
+ pcbinfo->ipi_porthashmask);
+ uma_zdestroy(pcbinfo->ipi_zone);
+ INP_INFO_LOCK_DESTROY(pcbinfo);
+}
+
+/*
* Allocate a PCB and associate it with the socket.
* On success return with the PCB locked.
*/
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 811cf9f..4ba19e6 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -42,6 +42,7 @@
#ifdef _KERNEL
#include <sys/rwlock.h>
#include <net/vnet.h>
+#include <vm/uma.h>
#endif
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
@@ -376,6 +377,7 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
#define INP_INFO_WLOCK(ipi) rw_wlock(&(ipi)->ipi_lock)
#define INP_INFO_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_lock)
#define INP_INFO_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_lock)
+#define INP_INFO_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_lock)
#define INP_INFO_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_lock)
#define INP_INFO_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_lock)
#define INP_INFO_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_LOCKED)
@@ -482,6 +484,10 @@ VNET_DECLARE(int, ipport_tcpallocs);
extern struct callout ipport_tick_callout;
+void in_pcbinfo_destroy(struct inpcbinfo *);
+void in_pcbinfo_init(struct inpcbinfo *, const char *, struct inpcbhead *,
+ int, int, char *, uma_init, uma_fini, uint32_t);
+
void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
int in_pcballoc(struct socket *, struct inpcbinfo *);
int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 225dd46..acee341 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -147,35 +147,20 @@ static void
div_init(void)
{
- INP_INFO_LOCK_INIT(&V_divcbinfo, "div");
- LIST_INIT(&V_divcb);
- V_divcbinfo.ipi_listhead = &V_divcb;
-#ifdef VIMAGE
- V_divcbinfo.ipi_vnet = curvnet;
-#endif
/*
- * XXX We don't use the hash list for divert IP, but it's easier
- * to allocate a one entry hash list than it is to check all
- * over the place for hashbase == NULL.
+ * XXX We don't use the hash list for divert IP, but it's easier to
+ * allocate one-entry hash lists than it is to check all over the
+ * place for hashbase == NULL.
*/
- V_divcbinfo.ipi_hashbase = hashinit(1, M_PCB, &V_divcbinfo.ipi_hashmask);
- V_divcbinfo.ipi_porthashbase = hashinit(1, M_PCB,
- &V_divcbinfo.ipi_porthashmask);
- V_divcbinfo.ipi_zone = uma_zcreate("divcb", sizeof(struct inpcb),
- NULL, NULL, div_inpcb_init, div_inpcb_fini, UMA_ALIGN_PTR,
- UMA_ZONE_NOFREE);
- uma_zone_set_max(V_divcbinfo.ipi_zone, maxsockets);
+ in_pcbinfo_init(&V_divcbinfo, "div", &V_divcb, 1, 1, "divcb",
+ div_inpcb_init, div_inpcb_fini, UMA_ZONE_NOFREE);
}
static void
div_destroy(void)
{
- INP_INFO_LOCK_DESTROY(&V_divcbinfo);
- uma_zdestroy(V_divcbinfo.ipi_zone);
- hashdestroy(V_divcbinfo.ipi_hashbase, M_PCB, V_divcbinfo.ipi_hashmask);
- hashdestroy(V_divcbinfo.ipi_porthashbase, M_PCB,
- V_divcbinfo.ipi_porthashmask);
+ in_pcbinfo_destroy(&V_divcbinfo);
}
/*
@@ -227,7 +212,7 @@ divert_packet(struct mbuf *m, int incoming)
#ifdef SCTP
if (m->m_pkthdr.csum_flags & CSUM_SCTP) {
ip->ip_len = ntohs(ip->ip_len);
- sctp_delayed_cksum(m);
+ sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
ip->ip_len = htons(ip->ip_len);
}
@@ -385,7 +370,6 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
struct inpcb *inp;
dt->info |= IPFW_IS_DIVERT | IPFW_INFO_OUT;
- INP_INFO_WLOCK(&V_divcbinfo);
inp = sotoinpcb(so);
INP_RLOCK(inp);
/*
@@ -396,7 +380,6 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) {
error = EINVAL;
INP_RUNLOCK(inp);
- INP_INFO_WUNLOCK(&V_divcbinfo);
m_freem(m);
} else {
/* Convert fields to host order for ip_output() */
@@ -437,7 +420,6 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
error = ENOBUFS;
}
INP_RUNLOCK(inp);
- INP_INFO_WUNLOCK(&V_divcbinfo);
if (error == ENOBUFS) {
m_freem(m);
return (error);
@@ -646,11 +628,13 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RLOCK(&V_divcbinfo);
for (inp = LIST_FIRST(V_divcbinfo.ipi_listhead), i = 0; inp && i < n;
inp = LIST_NEXT(inp, inp_list)) {
- INP_RLOCK(inp);
+ INP_WLOCK(inp);
if (inp->inp_gencnt <= gencnt &&
- cr_canseeinpcb(req->td->td_ucred, inp) == 0)
+ cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
+ in_pcbref(inp);
inp_list[i++] = inp;
- INP_RUNLOCK(inp);
+ }
+ INP_WUNLOCK(inp);
}
INP_INFO_RUNLOCK(&V_divcbinfo);
n = i;
@@ -672,6 +656,15 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
} else
INP_RUNLOCK(inp);
}
+ INP_INFO_WLOCK(&V_divcbinfo);
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_WLOCK(inp);
+ if (!in_pcbrele(inp))
+ INP_WUNLOCK(inp);
+ }
+ INP_INFO_WUNLOCK(&V_divcbinfo);
+
if (!error) {
/*
* Give the user an updated idea of our state.
diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h
index 3a193e9..dc2c341 100644
--- a/sys/netinet/ip_dummynet.h
+++ b/sys/netinet/ip_dummynet.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa
+ * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
* Portions Copyright (c) 2000 Akamba Corp.
* All rights reserved
*
@@ -31,344 +31,233 @@
#define _IP_DUMMYNET_H
/*
- * Definition of dummynet data structures. In the structures, I decided
- * not to use the macros in <sys/queue.h> in the hope of making the code
- * easier to port to other architectures. The type of lists and queue we
- * use here is pretty simple anyways.
- */
-
-/*
- * We start with a heap, which is used in the scheduler to decide when
- * to transmit packets etc.
+ * Definition of the kernel-userland API for dummynet.
*
- * The key for the heap is used for two different values:
+ * Setsockopt() and getsockopt() pass a batch of objects, each
+ * of them starting with a "struct dn_id" which should fully identify
+ * the object and its relation with others in the sequence.
+ * The first object in each request should have
+ * type= DN_CMD_*, id = DN_API_VERSION.
+ * For other objects, type and subtype specify the object, len indicates
+ * the total length including the header, and 'id' identifies the specific
+ * object.
*
- * 1. timer ticks- max 10K/second, so 32 bits are enough;
- *
- * 2. virtual times. These increase in steps of len/x, where len is the
- * packet length, and x is either the weight of the flow, or the
- * sum of all weights.
- * If we limit to max 1000 flows and a max weight of 100, then
- * x needs 17 bits. The packet size is 16 bits, so we can easily
- * overflow if we do not allow errors.
- * So we use a key "dn_key" which is 64 bits. Some macros are used to
- * compare key values and handle wraparounds.
- * MAX64 returns the largest of two key values.
- * MY_M is used as a shift count when doing fixed point arithmetic
- * (a better name would be useful...).
- */
-typedef u_int64_t dn_key ; /* sorting key */
-#define DN_KEY_LT(a,b) ((int64_t)((a)-(b)) < 0)
-#define DN_KEY_LEQ(a,b) ((int64_t)((a)-(b)) <= 0)
-#define DN_KEY_GT(a,b) ((int64_t)((a)-(b)) > 0)
-#define DN_KEY_GEQ(a,b) ((int64_t)((a)-(b)) >= 0)
-#define MAX64(x,y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x)
-#define MY_M 16 /* number of left shift to obtain a larger precision */
-
-/*
- * XXX With this scaling, max 1000 flows, max weight 100, 1Gbit/s, the
- * virtual time wraps every 15 days.
+ * Most objects are numbered with an identifier in the range 1..65535.
+ * DN_MAX_ID indicates the first value outside the range.
*/
+#define DN_API_VERSION 12500000
+#define DN_MAX_ID 0x10000
-/*
- * The maximum hash table size for queues. This value must be a power
- * of 2.
- */
-#define DN_MAX_HASH_SIZE 65536
+struct dn_id {
+ uint16_t len; /* total obj len including this header */
+ uint8_t type;
+ uint8_t subtype;
+ uint32_t id; /* generic id */
+};
/*
- * A heap entry is made of a key and a pointer to the actual
- * object stored in the heap.
- * The heap is an array of dn_heap_entry entries, dynamically allocated.
- * Current size is "size", with "elements" actually in use.
- * The heap normally supports only ordered insert and extract from the top.
- * If we want to extract an object from the middle of the heap, we
- * have to know where the object itself is located in the heap (or we
- * need to scan the whole array). To this purpose, an object has a
- * field (int) which contains the index of the object itself into the
- * heap. When the object is moved, the field must also be updated.
- * The offset of the index in the object is stored in the 'offset'
- * field in the heap descriptor. The assumption is that this offset
- * is non-zero if we want to support extract from the middle.
- */
-struct dn_heap_entry {
- dn_key key ; /* sorting key. Topmost element is smallest one */
- void *object ; /* object pointer */
-} ;
-
-struct dn_heap {
- int size ;
- int elements ;
- int offset ; /* XXX if > 0 this is the offset of direct ptr to obj */
- struct dn_heap_entry *p ; /* really an array of "size" entries */
-} ;
-
-#ifdef _KERNEL
-/*
- * Packets processed by dummynet have an mbuf tag associated with
- * them that carries their dummynet state. This is used within
- * the dummynet code as well as outside when checking for special
- * processing requirements.
- * Note that the first part is the reinject info and is common to
- * other forms of packet reinjection.
+ * These values are in the type field of struct dn_id.
+ * To preserve the ABI, never rearrange the list or delete
+ * entries with the exception of DN_LAST
*/
-struct dn_pkt_tag {
- struct ipfw_rule_ref rule; /* matching rule */
+enum {
+ DN_NONE = 0,
+ DN_LINK = 1,
+ DN_FS,
+ DN_SCH,
+ DN_SCH_I,
+ DN_QUEUE,
+ DN_DELAY_LINE,
+ DN_PROFILE,
+ DN_FLOW, /* struct dn_flow */
+ DN_TEXT, /* opaque text is the object */
+
+ DN_CMD_CONFIG = 0x80, /* objects follow */
+ DN_CMD_DELETE, /* subtype + list of entries */
+ DN_CMD_GET, /* subtype + list of entries */
+ DN_CMD_FLUSH,
+ /* for compatibility with FreeBSD 7.2/8 */
+ DN_COMPAT_PIPE,
+ DN_COMPAT_QUEUE,
+ DN_GET_COMPAT,
+
+ /* special commands for emulation of sysctl variables */
+ DN_SYSCTL_GET,
+ DN_SYSCTL_SET,
+
+ DN_LAST,
+};
- /* second part, dummynet specific */
- int dn_dir; /* action when packet comes out. */
- /* see ip_fw_private.h */
+enum { /* subtype for schedulers, flowset and the like */
+ DN_SCHED_UNKNOWN = 0,
+ DN_SCHED_FIFO = 1,
+ DN_SCHED_WF2QP = 2,
+ /* others are in individual modules */
+};
- dn_key output_time; /* when the pkt is due for delivery */
- struct ifnet *ifp; /* interface, for ip_output */
- struct _ip6dn_args ip6opt; /* XXX ipv6 options */
+enum { /* user flags */
+ DN_HAVE_MASK = 0x0001, /* fs or sched has a mask */
+ DN_NOERROR = 0x0002, /* do not report errors */
+ DN_QHT_HASH = 0x0004, /* qht is a hash table */
+ DN_QSIZE_BYTES = 0x0008, /* queue size is in bytes */
+ DN_HAS_PROFILE = 0x0010, /* a link has a profile */
+ DN_IS_RED = 0x0020,
+ DN_IS_GENTLE_RED= 0x0040,
+ DN_PIPE_CMD = 0x1000, /* pipe config... */
};
-#endif /* _KERNEL */
/*
- * Overall structure of dummynet (with WF2Q+):
-
-In dummynet, packets are selected with the firewall rules, and passed
-to two different objects: PIPE or QUEUE.
-
-A QUEUE is just a queue with configurable size and queue management
-policy. It is also associated with a mask (to discriminate among
-different flows), a weight (used to give different shares of the
-bandwidth to different flows) and a "pipe", which essentially
-supplies the transmit clock for all queues associated with that
-pipe.
-
-A PIPE emulates a fixed-bandwidth link, whose bandwidth is
-configurable. The "clock" for a pipe can come from either an
-internal timer, or from the transmit interrupt of an interface.
-A pipe is also associated with one (or more, if masks are used)
-queue, where all packets for that pipe are stored.
-
-The bandwidth available on the pipe is shared by the queues
-associated with that pipe (only one in case the packet is sent
-to a PIPE) according to the WF2Q+ scheduling algorithm and the
-configured weights.
-
-In general, incoming packets are stored in the appropriate queue,
-which is then placed into one of a few heaps managed by a scheduler
-to decide when the packet should be extracted.
-The scheduler (a function called dummynet()) is run at every timer
-tick, and grabs queues from the head of the heaps when they are
-ready for processing.
-
-There are three data structures definining a pipe and associated queues:
-
- + dn_pipe, which contains the main configuration parameters related
- to delay and bandwidth;
- + dn_flow_set, which contains WF2Q+ configuration, flow
- masks, plr and RED configuration;
- + dn_flow_queue, which is the per-flow queue (containing the packets)
-
-Multiple dn_flow_set can be linked to the same pipe, and multiple
-dn_flow_queue can be linked to the same dn_flow_set.
-All data structures are linked in a linear list which is used for
-housekeeping purposes.
-
-During configuration, we create and initialize the dn_flow_set
-and dn_pipe structures (a dn_pipe also contains a dn_flow_set).
-
-At runtime: packets are sent to the appropriate dn_flow_set (either
-WFQ ones, or the one embedded in the dn_pipe for fixed-rate flows),
-which in turn dispatches them to the appropriate dn_flow_queue
-(created dynamically according to the masks).
-
-The transmit clock for fixed rate flows (ready_event()) selects the
-dn_flow_queue to be used to transmit the next packet. For WF2Q,
-wfq_ready_event() extract a pipe which in turn selects the right
-flow using a number of heaps defined into the pipe itself.
-
- *
+ * link template.
*/
+struct dn_link {
+ struct dn_id oid;
+
+ /*
+ * Userland sets bw and delay in bits/s and milliseconds.
+ * The kernel converts this back and forth to bits/tick and ticks.
+ * XXX what about burst ?
+ */
+ int32_t link_nr;
+ int bandwidth; /* bit/s or bits/tick. */
+ int delay; /* ms and ticks */
+ uint64_t burst; /* scaled. bits*Hz XXX */
+};
/*
- * per flow queue. This contains the flow identifier, the queue
- * of packets, counters, and parameters used to support both RED and
- * WF2Q+.
- *
- * A dn_flow_queue is created and initialized whenever a packet for
- * a new flow arrives.
+ * A flowset, which is a template for flows. Contains parameters
+ * from the command line: id, target scheduler, queue sizes, plr,
+ * flow masks, buckets for the flow hash, and possibly scheduler-
+ * specific parameters (weight, quantum and so on).
*/
-struct dn_flow_queue {
- struct dn_flow_queue *next ;
- struct ipfw_flow_id id ;
-
- struct mbuf *head, *tail ; /* queue of packets */
- u_int len ;
- u_int len_bytes ;
-
- /*
- * When we emulate MAC overheads, or channel unavailability due
- * to other traffic on a shared medium, we augment the packet at
- * the head of the queue with an 'extra_bits' field representsing
- * the additional delay the packet will be subject to:
- * extra_bits = bw*unavailable_time.
- * With large bandwidth and large delays, extra_bits (and also numbytes)
- * can become very large, so better play safe and use 64 bit
- */
- uint64_t numbytes ; /* credit for transmission (dynamic queues) */
- int64_t extra_bits; /* extra bits simulating unavailable channel */
-
- u_int64_t tot_pkts ; /* statistics counters */
- u_int64_t tot_bytes ;
- u_int32_t drops ;
-
- int hash_slot ; /* debugging/diagnostic */
-
- /* RED parameters */
- int avg ; /* average queue length est. (scaled) */
- int count ; /* arrivals since last RED drop */
- int random ; /* random value (scaled) */
- dn_key idle_time; /* start of queue idle time */
-
- /* WF2Q+ support */
- struct dn_flow_set *fs ; /* parent flow set */
- int heap_pos ; /* position (index) of struct in heap */
- dn_key sched_time ; /* current time when queue enters ready_heap */
-
- dn_key S,F ; /* start time, finish time */
- /*
- * Setting F < S means the timestamp is invalid. We only need
- * to test this when the queue is empty.
- */
-} ;
+struct dn_fs {
+ struct dn_id oid;
+ uint32_t fs_nr; /* the flowset number */
+ uint32_t flags; /* userland flags */
+ int qsize; /* queue size in slots or bytes */
+ int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */
+ uint32_t buckets; /* buckets used for the queue hash table */
+
+ struct ipfw_flow_id flow_mask;
+ uint32_t sched_nr; /* the scheduler we attach to */
+ /* generic scheduler parameters. Leave them at -1 if unset.
+ * Now we use 0: weight, 1: lmax, 2: priority
+ */
+ int par[4];
+
+ /* RED/GRED parameters.
+ * weight and probabilities are in the range 0..1 represented
+ * in fixed point arithmetic with SCALE_RED decimal bits.
+ */
+#define SCALE_RED 16
+#define SCALE(x) ( (x) << SCALE_RED )
+#define SCALE_VAL(x) ( (x) >> SCALE_RED )
+#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED )
+ int w_q ; /* queue weight (scaled) */
+ int max_th ; /* maximum threshold for queue (scaled) */
+ int min_th ; /* minimum threshold for queue (scaled) */
+ int max_p ; /* maximum value for p_b (scaled) */
-/*
- * flow_set descriptor. Contains the "template" parameters for the
- * queue configuration, and pointers to the hash table of dn_flow_queue's.
- *
- * The hash table is an array of lists -- we identify the slot by
- * hashing the flow-id, then scan the list looking for a match.
- * The size of the hash table (buckets) is configurable on a per-queue
- * basis.
- *
- * A dn_flow_set is created whenever a new queue or pipe is created (in the
- * latter case, the structure is located inside the struct dn_pipe).
- */
-struct dn_flow_set {
- SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */
-
- u_short fs_nr ; /* flow_set number */
- u_short flags_fs;
-#define DN_HAVE_FLOW_MASK 0x0001
-#define DN_IS_RED 0x0002
-#define DN_IS_GENTLE_RED 0x0004
-#define DN_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
-#define DN_NOERROR 0x0010 /* do not report ENOBUFS on drops */
-#define DN_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
-#define DN_IS_PIPE 0x4000
-#define DN_IS_QUEUE 0x8000
-
- struct dn_pipe *pipe ; /* pointer to parent pipe */
- u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */
-
- int weight ; /* WFQ queue weight */
- int qsize ; /* queue size in slots or bytes */
- int plr ; /* pkt loss rate (2^31-1 means 100%) */
-
- struct ipfw_flow_id flow_mask ;
-
- /* hash table of queues onto this flow_set */
- int rq_size ; /* number of slots */
- int rq_elements ; /* active elements */
- struct dn_flow_queue **rq; /* array of rq_size entries */
-
- u_int32_t last_expired ; /* do not expire too frequently */
- int backlogged ; /* #active queues for this flowset */
-
- /* RED parameters */
-#define SCALE_RED 16
-#define SCALE(x) ( (x) << SCALE_RED )
-#define SCALE_VAL(x) ( (x) >> SCALE_RED )
-#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED )
- int w_q ; /* queue weight (scaled) */
- int max_th ; /* maximum threshold for queue (scaled) */
- int min_th ; /* minimum threshold for queue (scaled) */
- int max_p ; /* maximum value for p_b (scaled) */
- u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
- u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
- u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
- u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
- u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
- u_int lookup_depth ; /* depth of lookup table */
- int lookup_step ; /* granularity inside the lookup table */
- int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
- int avg_pkt_size ; /* medium packet size */
- int max_pkt_size ; /* max packet size */
};
-SLIST_HEAD(dn_flow_set_head, dn_flow_set);
/*
- * Pipe descriptor. Contains global parameters, delay-line queue,
- * and the flow_set used for fixed-rate queues.
- *
- * For WF2Q+ support it also has 3 heaps holding dn_flow_queue:
- * not_eligible_heap, for queues whose start time is higher
- * than the virtual time. Sorted by start time.
- * scheduler_heap, for queues eligible for scheduling. Sorted by
- * finish time.
- * idle_heap, all flows that are idle and can be removed. We
- * do that on each tick so we do not slow down too much
- * operations during forwarding.
- *
+ * dn_flow collects flow_id and stats for queues and scheduler
+ * instances, and is used to pass these info to userland.
+ * oid.type/oid.subtype describe the object, oid.id is number
+ * of the parent object.
*/
-struct dn_pipe { /* a pipe */
- SLIST_ENTRY(dn_pipe) next; /* linked list in a hash slot */
-
- int pipe_nr ; /* number */
- int bandwidth; /* really, bytes/tick. */
- int delay ; /* really, ticks */
-
- struct mbuf *head, *tail ; /* packets in delay line */
+struct dn_flow {
+ struct dn_id oid;
+ struct ipfw_flow_id fid;
+ uint64_t tot_pkts; /* statistics counters */
+ uint64_t tot_bytes;
+ uint32_t length; /* Queue lenght, in packets */
+ uint32_t len_bytes; /* Queue lenght, in bytes */
+ uint32_t drops;
+};
- /* WF2Q+ */
- struct dn_heap scheduler_heap ; /* top extract - key Finish time*/
- struct dn_heap not_eligible_heap; /* top extract- key Start time */
- struct dn_heap idle_heap ; /* random extract - key Start=Finish time */
- dn_key V ; /* virtual time */
- int sum; /* sum of weights of all active sessions */
+/*
+ * Scheduler template, mostly indicating the name, number,
+ * sched_mask and buckets.
+ */
+struct dn_sch {
+ struct dn_id oid;
+ uint32_t sched_nr; /* N, scheduler number */
+ uint32_t buckets; /* number of buckets for the instances */
+ uint32_t flags; /* have_mask, ... */
+
+ char name[16]; /* null terminated */
+ /* mask to select the appropriate scheduler instance */
+ struct ipfw_flow_id sched_mask; /* M */
+};
- /* Same as in dn_flow_queue, numbytes can become large */
- int64_t numbytes; /* bits I can transmit (more or less). */
- uint64_t burst; /* burst size, scaled: bits * hz */
- dn_key sched_time ; /* time pipe was scheduled in ready_heap */
- dn_key idle_time; /* start of pipe idle time */
+/* A delay profile is attached to a link.
+ * Note that a profile, as any other object, cannot be longer than 2^16
+ */
+#define ED_MAX_SAMPLES_NO 1024
+struct dn_profile {
+ struct dn_id oid;
+ /* fields to simulate a delay profile */
+#define ED_MAX_NAME_LEN 32
+ char name[ED_MAX_NAME_LEN];
+ int link_nr;
+ int loss_level;
+ int bandwidth; // XXX use link bandwidth?
+ int samples_no; /* actual len of samples[] */
+ int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */
+};
- /*
- * When the tx clock come from an interface (if_name[0] != '\0'), its name
- * is stored below, whereas the ifp is filled when the rule is configured.
- */
- char if_name[IFNAMSIZ];
- struct ifnet *ifp ;
- int ready ; /* set if ifp != NULL and we got a signal from it */
- struct dn_flow_set fs ; /* used with fixed-rate flows */
- /* fields to simulate a delay profile */
+/*
+ * Overall structure of dummynet
-#define ED_MAX_NAME_LEN 32
- char name[ED_MAX_NAME_LEN];
- int loss_level;
- int samples_no;
- int *samples;
-};
+In dummynet, packets are selected with the firewall rules, and passed
+to two different objects: PIPE or QUEUE (bad name).
+
+A QUEUE defines a classifier, which groups packets into flows
+according to a 'mask', puts them into independent queues (one
+per flow) with configurable size and queue management policy,
+and passes flows to a scheduler:
+
+ (flow_mask|sched_mask) sched_mask
+ +---------+ weight Wx +-------------+
+ | |->-[flow]-->--| |-+
+ -->--| QUEUE x | ... | | |
+ | |->-[flow]-->--| SCHEDuler N | |
+ +---------+ | | |
+ ... | +--[LINK N]-->--
+ +---------+ weight Wy | | +--[LINK N]-->--
+ | |->-[flow]-->--| | |
+ -->--| QUEUE y | ... | | |
+ | |->-[flow]-->--| | |
+ +---------+ +-------------+ |
+ +-------------+
+
+Many QUEUE objects can connect to the same scheduler, each
+QUEUE object can have its own set of parameters.
+
+In turn, the SCHEDuler 'forks' multiple instances according
+to a 'sched_mask', each instance manages its own set of queues
+and transmits on a private instance of a configurable LINK.
+
+A PIPE is a simplified version of the above, where there
+is no flow_mask, and each scheduler instance handles a single queue.
+
+The following data structures (visible from userland) describe
+the objects used by dummynet:
+
+ + dn_link, contains the main configuration parameters related
+ to delay and bandwidth;
+ + dn_profile describes a delay profile;
+ + dn_flow describes the flow status (flow id, statistics)
+
+ + dn_sch describes a scheduler
+ + dn_fs describes a flowset (msk, weight, queue parameters)
-/* dn_pipe_max is used to pass pipe configuration from userland onto
- * kernel space and back
+ *
*/
-#define ED_MAX_SAMPLES_NO 1024
-struct dn_pipe_max {
- struct dn_pipe pipe;
- int samples[ED_MAX_SAMPLES_NO];
-};
-
-SLIST_HEAD(dn_pipe_head, dn_pipe);
#endif /* _IP_DUMMYNET_H */
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 21a79ec..cf5d8d0 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -487,24 +487,29 @@ struct ip_fw {
#define RULESIZE(rule) (sizeof(struct ip_fw) + \
((struct ip_fw *)(rule))->cmd_len * 4 - 4)
+#if 1 // should be moved to in.h
/*
* This structure is used as a flow mask and a flow id for various
* parts of the code.
+ * addr_type is used in userland and kernel to mark the address type.
+ * fib is used in the kernel to record the fib in use.
+ * _flags is used in the kernel to store tcp flags for dynamic rules.
*/
struct ipfw_flow_id {
- u_int32_t dst_ip;
- u_int32_t src_ip;
- u_int16_t dst_port;
- u_int16_t src_port;
- u_int8_t fib;
- u_int8_t proto;
- u_int8_t flags; /* protocol-specific flags */
- uint8_t addr_type; /* 4 = ipv4, 6 = ipv6, 1=ether ? */
- struct in6_addr dst_ip6; /* could also store MAC addr! */
+ uint32_t dst_ip;
+ uint32_t src_ip;
+ uint16_t dst_port;
+ uint16_t src_port;
+ uint8_t fib;
+ uint8_t proto;
+ uint8_t _flags; /* protocol-specific flags */
+ uint8_t addr_type; /* 4=ip4, 6=ip6, 1=ether ? */
+ struct in6_addr dst_ip6;
struct in6_addr src_ip6;
- u_int32_t flow_id6;
- u_int32_t frag_id6;
+ uint32_t flow_id6;
+ uint32_t extra; /* queue/pipe or frag_id */
};
+#endif
#define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6)
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 084bac0..fdef645 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -327,9 +327,21 @@ ip_init(void)
"error %d\n", __func__, i);
#ifdef FLOWTABLE
- TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size",
- &V_ip_output_flowtable_size);
- V_ip_ft = flowtable_alloc(V_ip_output_flowtable_size, FL_PCPU);
+ if (TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size",
+ &V_ip_output_flowtable_size)) {
+ if (V_ip_output_flowtable_size < 256)
+ V_ip_output_flowtable_size = 256;
+ if (!powerof2(V_ip_output_flowtable_size)) {
+ printf("flowtable must be power of 2 size\n");
+ V_ip_output_flowtable_size = 2048;
+ }
+ } else {
+ /*
+ * round up to the next power of 2
+ */
+ V_ip_output_flowtable_size = 1 << fls((1024 + maxusers * 64)-1);
+ }
+ V_ip_ft = flowtable_alloc("ipv4", V_ip_output_flowtable_size, FL_PCPU);
#endif
/* Skip initialization of globals for non-default instances. */
@@ -1578,7 +1590,7 @@ ip_forward(struct mbuf *m, int srcrt)
* If IPsec is configured for this path,
* override any possibly mtu value set by ip_output.
*/
- mtu = ip_ipsec_mtu(m, mtu);
+ mtu = ip_ipsec_mtu(mcopy, mtu);
#endif /* IPSEC */
/*
* If the MTU was set before make sure we are below the
diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c
index b49b620..3465d4b 100644
--- a/sys/netinet/ip_ipsec.c
+++ b/sys/netinet/ip_ipsec.c
@@ -342,7 +342,7 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error)
}
#ifdef SCTP
if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) {
- sctp_delayed_cksum(*m);
+ sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2));
(*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
}
#endif
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index d6f361d..dc26705 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -148,14 +148,20 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
bzero(ro, sizeof (*ro));
#ifdef FLOWTABLE
- /*
- * The flow table returns route entries valid for up to 30
- * seconds; we rely on the remainder of ip_output() taking no
- * longer than that long for the stability of ro_rt. The
- * flow ID assignment must have happened before this point.
- */
- if (flowtable_lookup(V_ip_ft, m, ro, M_GETFIB(m)) == 0)
- nortfree = 1;
+ {
+ struct flentry *fle;
+
+ /*
+ * The flow table returns route entries valid for up to 30
+ * seconds; we rely on the remainder of ip_output() taking no
+ * longer than that long for the stability of ro_rt. The
+ * flow ID assignment must have happened before this point.
+ */
+ if ((fle = flowtable_lookup_mbuf(V_ip_ft, m, AF_INET)) != NULL) {
+ flow_to_route(fle, ro);
+ nortfree = 1;
+ }
+ }
#endif
}
@@ -199,6 +205,8 @@ again:
*/
rte = ro->ro_rt;
if (rte && ((rte->rt_flags & RTF_UP) == 0 ||
+ rte->rt_ifp == NULL ||
+ !RT_LINK_IS_UP(rte->rt_ifp) ||
dst->sin_family != AF_INET ||
dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
if (!nortfree)
@@ -270,7 +278,9 @@ again:
#endif
rte = ro->ro_rt;
}
- if (rte == NULL) {
+ if (rte == NULL ||
+ rte->rt_ifp == NULL ||
+ !RT_LINK_IS_UP(rte->rt_ifp)) {
#ifdef IPSEC
/*
* There is no route for this packet, but it is
@@ -573,7 +583,7 @@ passout:
}
#ifdef SCTP
if (sw_csum & CSUM_SCTP) {
- sctp_delayed_cksum(m);
+ sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
sw_csum &= ~CSUM_SCTP;
}
#endif
@@ -715,7 +725,7 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
#ifdef SCTP
if (m0->m_pkthdr.csum_flags & CSUM_SCTP &&
(if_hwassist_flags & CSUM_IP_FRAGS) == 0) {
- sctp_delayed_cksum(m0);
+ sctp_delayed_cksum(m0, hlen);
m0->m_pkthdr.csum_flags &= ~CSUM_SCTP;
}
#endif
diff --git a/sys/netinet/ipfw/dn_heap.c b/sys/netinet/ipfw/dn_heap.c
new file mode 100644
index 0000000..6773851
--- /dev/null
+++ b/sys/netinet/ipfw/dn_heap.c
@@ -0,0 +1,550 @@
+/*-
+ * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * Binary heap and hash tables, used in dummynet
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#ifdef _KERNEL
+__FBSDID("$FreeBSD$");
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <netinet/ipfw/dn_heap.h>
+#ifndef log
+#define log(x, arg...)
+#endif
+
+#else /* !_KERNEL */
+
+#include <stdio.h>
+#include <dn_test.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include "dn_heap.h"
+#define log(x, arg...) fprintf(stderr, ## arg)
+#define panic(x...) fprintf(stderr, ## x), exit(1)
+#define MALLOC_DEFINE(a, b, c)
+static void *my_malloc(int s) { return malloc(s); }
+static void my_free(void *p) { free(p); }
+#define malloc(s, t, w) my_malloc(s)
+#define free(p, t) my_free(p)
+#endif /* !_KERNEL */
+
+MALLOC_DEFINE(M_DN_HEAP, "dummynet", "dummynet heap");
+
+/*
+ * Heap management functions.
+ *
+ * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
+ * Some macros help finding parent/children so we can optimize them.
+ *
+ * heap_init() is called to expand the heap when needed.
+ * Increment size in blocks of 16 entries.
+ * Returns 1 on error, 0 on success
+ */
+#define HEAP_FATHER(x) ( ( (x) - 1 ) / 2 )
+#define HEAP_LEFT(x) ( (x)+(x) + 1 )
+#define HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; }
+#define HEAP_INCREMENT 15
+
+static int
+heap_resize(struct dn_heap *h, unsigned int new_size)
+{
+ struct dn_heap_entry *p;
+
+ if (h->size >= new_size ) /* have enough room */
+ return 0;
+#if 1 /* round to the next power of 2 */
+ new_size |= new_size >> 1;
+ new_size |= new_size >> 2;
+ new_size |= new_size >> 4;
+ new_size |= new_size >> 8;
+ new_size |= new_size >> 16;
+#else
+ new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT;
+#endif
+ p = malloc(new_size * sizeof(*p), M_DN_HEAP, M_NOWAIT);
+ if (p == NULL) {
+ printf("--- %s, resize %d failed\n", __func__, new_size );
+ return 1; /* error */
+ }
+ if (h->size > 0) {
+ bcopy(h->p, p, h->size * sizeof(*p) );
+ free(h->p, M_DN_HEAP);
+ }
+ h->p = p;
+ h->size = new_size;
+ return 0;
+}
+
+int
+heap_init(struct dn_heap *h, int size, int ofs)
+{
+ if (heap_resize(h, size))
+ return 1;
+ h->elements = 0;
+ h->ofs = ofs;
+ return 0;
+}
+
+/*
+ * Insert element in heap. Normally, p != NULL, we insert p in
+ * a new position and bubble up. If p == NULL, then the element is
+ * already in place, and key is the position where to start the
+ * bubble-up.
+ * Returns 1 on failure (cannot allocate new heap entry)
+ *
+ * If ofs > 0 the position (index, int) of the element in the heap is
+ * also stored in the element itself at the given offset in bytes.
+ */
+#define SET_OFFSET(h, i) do { \
+ if (h->ofs > 0) \
+ *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = i; \
+ } while (0)
+/*
+ * RESET_OFFSET is used for sanity checks. It sets ofs
+ * to an invalid value.
+ */
+#define RESET_OFFSET(h, i) do { \
+ if (h->ofs > 0) \
+ *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = -16; \
+ } while (0)
+
+int
+heap_insert(struct dn_heap *h, uint64_t key1, void *p)
+{
+ int son = h->elements;
+
+ //log("%s key %llu p %p\n", __FUNCTION__, key1, p);
+ if (p == NULL) { /* data already there, set starting point */
+ son = key1;
+ } else { /* insert new element at the end, possibly resize */
+ son = h->elements;
+ if (son == h->size) /* need resize... */
+ // XXX expand by 16 or so
+ if (heap_resize(h, h->elements+16) )
+ return 1; /* failure... */
+ h->p[son].object = p;
+ h->p[son].key = key1;
+ h->elements++;
+ }
+ /* make sure that son >= father along the path */
+ while (son > 0) {
+ int father = HEAP_FATHER(son);
+ struct dn_heap_entry tmp;
+
+ if (DN_KEY_LT( h->p[father].key, h->p[son].key ) )
+ break; /* found right position */
+ /* son smaller than father, swap and repeat */
+ HEAP_SWAP(h->p[son], h->p[father], tmp);
+ SET_OFFSET(h, son);
+ son = father;
+ }
+ SET_OFFSET(h, son);
+ return 0;
+}
+
+/*
+ * remove top element from heap, or obj if obj != NULL
+ */
+void
+heap_extract(struct dn_heap *h, void *obj)
+{
+ int child, father, max = h->elements - 1;
+
+ if (max < 0) {
+ printf("--- %s: empty heap 0x%p\n", __FUNCTION__, h);
+ return;
+ }
+ if (obj == NULL)
+ father = 0; /* default: move up smallest child */
+ else { /* extract specific element, index is at offset */
+ if (h->ofs <= 0)
+ panic("%s: extract from middle not set on %p\n",
+ __FUNCTION__, h);
+ father = *((int *)((char *)obj + h->ofs));
+ if (father < 0 || father >= h->elements) {
+ panic("%s: father %d out of bound 0..%d\n",
+ __FUNCTION__, father, h->elements);
+ }
+ }
+ /*
+ * below, father is the index of the empty element, which
+ * we replace at each step with the smallest child until we
+ * reach the bottom level.
+ */
+ // XXX why removing RESET_OFFSET increases runtime by 10% ?
+ RESET_OFFSET(h, father);
+ while ( (child = HEAP_LEFT(father)) <= max ) {
+ if (child != max &&
+ DN_KEY_LT(h->p[child+1].key, h->p[child].key) )
+ child++; /* take right child, otherwise left */
+ h->p[father] = h->p[child];
+ SET_OFFSET(h, father);
+ father = child;
+ }
+ h->elements--;
+ if (father != max) {
+ /*
+ * Fill hole with last entry and bubble up,
+ * reusing the insert code
+ */
+ h->p[father] = h->p[max];
+ heap_insert(h, father, NULL);
+ }
+}
+
+#if 0
+/*
+ * change object position and update references
+ * XXX this one is never used!
+ */
+static void
+heap_move(struct dn_heap *h, uint64_t new_key, void *object)
+{
+ int temp, i, max = h->elements-1;
+ struct dn_heap_entry *p, buf;
+
+ if (h->ofs <= 0)
+ panic("cannot move items on this heap");
+ p = h->p; /* shortcut */
+
+ i = *((int *)((char *)object + h->ofs));
+ if (DN_KEY_LT(new_key, p[i].key) ) { /* must move up */
+ p[i].key = new_key;
+ for (; i>0 &&
+ DN_KEY_LT(new_key, p[(temp = HEAP_FATHER(i))].key);
+ i = temp ) { /* bubble up */
+ HEAP_SWAP(p[i], p[temp], buf);
+ SET_OFFSET(h, i);
+ }
+ } else { /* must move down */
+ p[i].key = new_key;
+ while ( (temp = HEAP_LEFT(i)) <= max ) {
+ /* found left child */
+ if (temp != max &&
+ DN_KEY_LT(p[temp+1].key, p[temp].key))
+ temp++; /* select child with min key */
+ if (DN_KEY_LT(>p[temp].key, new_key)) {
+ /* go down */
+ HEAP_SWAP(p[i], p[temp], buf);
+ SET_OFFSET(h, i);
+ } else
+ break;
+ i = temp;
+ }
+ }
+ SET_OFFSET(h, i);
+}
+#endif /* heap_move, unused */
+
+/*
+ * heapify() will reorganize data inside an array to maintain the
+ * heap property. It is needed when we delete a bunch of entries.
+ */
+static void
+heapify(struct dn_heap *h)
+{
+ int i;
+
+ for (i = 0; i < h->elements; i++ )
+ heap_insert(h, i , NULL);
+}
+
+int
+heap_scan(struct dn_heap *h, int (*fn)(void *, uintptr_t),
+ uintptr_t arg)
+{
+ int i, ret, found;
+
+ for (i = found = 0 ; i < h->elements ;) {
+ ret = fn(h->p[i].object, arg);
+ if (ret & HEAP_SCAN_DEL) {
+ h->elements-- ;
+ h->p[i] = h->p[h->elements] ;
+ found++ ;
+ } else
+ i++ ;
+ if (ret & HEAP_SCAN_END)
+ break;
+ }
+ if (found)
+ heapify(h);
+ return found;
+}
+
+/*
+ * cleanup the heap and free data structure
+ */
+void
+heap_free(struct dn_heap *h)
+{
+ if (h->size >0 )
+ free(h->p, M_DN_HEAP);
+ bzero(h, sizeof(*h) );
+}
+
+/*
+ * hash table support.
+ */
+
+struct dn_ht {
+ int buckets; /* how many buckets, really buckets - 1*/
+ int entries; /* how many entries */
+ int ofs; /* offset of link field */
+ uint32_t (*hash)(uintptr_t, int, void *arg);
+ int (*match)(void *_el, uintptr_t key, int, void *);
+ void *(*newh)(uintptr_t, int, void *);
+ void **ht; /* bucket heads */
+};
+/*
+ * Initialize, allocating bucket pointers inline.
+ * Recycle previous record if possible.
+ * If the 'newh' function is not supplied, we assume that the
+ * key passed to ht_find is the same object to be stored in.
+ */
+struct dn_ht *
+dn_ht_init(struct dn_ht *ht, int buckets, int ofs,
+ uint32_t (*h)(uintptr_t, int, void *),
+ int (*match)(void *, uintptr_t, int, void *),
+ void *(*newh)(uintptr_t, int, void *))
+{
+ int l;
+
+ /*
+ * Notes about rounding bucket size to a power of two.
+ * Given the original bucket size, we compute the nearest lower and
+ * higher power of two, minus 1 (respectively b_min and b_max) because
+ * this value will be used to do an AND with the index returned
+ * by hash function.
+ * To choice between these two values, the original bucket size is
+ * compared with b_min. If the original size is greater than 4/3 b_min,
+ * we round the bucket size to b_max, else to b_min.
+ * This ratio try to round to the nearest power of two, advantaging
+ * the greater size if the different between two power is relatively
+ * big.
+ * Rounding the bucket size to a power of two avoid the use of
+ * module when calculating the correct bucket.
+ * The ht->buckets variable store the bucket size - 1 to simply
+ * do an AND between the index returned by hash function and ht->bucket
+ * instead of a module.
+ */
+ int b_min; /* min buckets */
+ int b_max; /* max buckets */
+ int b_ori; /* original buckets */
+
+ if (h == NULL || match == NULL) {
+ printf("--- missing hash or match function");
+ return NULL;
+ }
+ if (buckets < 1 || buckets > 65536)
+ return NULL;
+
+ b_ori = buckets;
+ /* calculate next power of 2, - 1*/
+ buckets |= buckets >> 1;
+ buckets |= buckets >> 2;
+ buckets |= buckets >> 4;
+ buckets |= buckets >> 8;
+ buckets |= buckets >> 16;
+
+ b_max = buckets; /* Next power */
+ b_min = buckets >> 1; /* Previous power */
+
+ /* Calculate the 'nearest' bucket size */
+ if (b_min * 4000 / 3000 < b_ori)
+ buckets = b_max;
+ else
+ buckets = b_min;
+
+ if (ht) { /* see if we can reuse */
+ if (buckets <= ht->buckets) {
+ ht->buckets = buckets;
+ } else {
+ /* free pointers if not allocated inline */
+ if (ht->ht != (void *)(ht + 1))
+ free(ht->ht, M_DN_HEAP);
+ free(ht, M_DN_HEAP);
+ ht = NULL;
+ }
+ }
+ if (ht == NULL) {
+ /* Allocate buckets + 1 entries because buckets is use to
+ * do the AND with the index returned by hash function
+ */
+ l = sizeof(*ht) + (buckets + 1) * sizeof(void **);
+ ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO);
+ }
+ if (ht) {
+ ht->ht = (void **)(ht + 1);
+ ht->buckets = buckets;
+ ht->ofs = ofs;
+ ht->hash = h;
+ ht->match = match;
+ ht->newh = newh;
+ }
+ return ht;
+}
+
+/* dummy callback for dn_ht_free to unlink all */
+static int
+do_del(void *obj, void *arg)
+{
+ return DNHT_SCAN_DEL;
+}
+
+void
+dn_ht_free(struct dn_ht *ht, int flags)
+{
+ if (ht == NULL)
+ return;
+ if (flags & DNHT_REMOVE) {
+ (void)dn_ht_scan(ht, do_del, NULL);
+ } else {
+ if (ht->ht && ht->ht != (void *)(ht + 1))
+ free(ht->ht, M_DN_HEAP);
+ free(ht, M_DN_HEAP);
+ }
+}
+
+int
+dn_ht_entries(struct dn_ht *ht)
+{
+ return ht ? ht->entries : 0;
+}
+
+/* lookup and optionally create or delete element */
+void *
+dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags, void *arg)
+{
+ int i;
+ void **pp, *p;
+
+ if (ht == NULL) /* easy on an empty hash */
+ return NULL;
+ i = (ht->buckets == 1) ? 0 :
+ (ht->hash(key, flags, arg) & ht->buckets);
+
+ for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) {
+ if (flags & DNHT_MATCH_PTR) {
+ if (key == (uintptr_t)p)
+ break;
+ } else if (ht->match(p, key, flags, arg)) /* found match */
+ break;
+ }
+ if (p) {
+ if (flags & DNHT_REMOVE) {
+ /* link in the next element */
+ *pp = *(void **)((char *)p + ht->ofs);
+ *(void **)((char *)p + ht->ofs) = NULL;
+ ht->entries--;
+ }
+ } else if (flags & DNHT_INSERT) {
+ // printf("%s before calling new, bucket %d ofs %d\n",
+ // __FUNCTION__, i, ht->ofs);
+ p = ht->newh ? ht->newh(key, flags, arg) : (void *)key;
+ // printf("%s newh returns %p\n", __FUNCTION__, p);
+ if (p) {
+ ht->entries++;
+ *(void **)((char *)p + ht->ofs) = ht->ht[i];
+ ht->ht[i] = p;
+ }
+ }
+ return p;
+}
+
+/*
+ * do a scan with the option to delete the object. Extract next before
+ * running the callback because the element may be destroyed there.
+ */
+int
+dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, void *), void *arg)
+{
+ int i, ret, found = 0;
+ void **curp, *cur, *next;
+
+ if (ht == NULL || fn == NULL)
+ return 0;
+ for (i = 0; i <= ht->buckets; i++) {
+ curp = &ht->ht[i];
+ while ( (cur = *curp) != NULL) {
+ next = *(void **)((char *)cur + ht->ofs);
+ ret = fn(cur, arg);
+ if (ret & DNHT_SCAN_DEL) {
+ found++;
+ ht->entries--;
+ *curp = next;
+ } else {
+ curp = (void **)((char *)cur + ht->ofs);
+ }
+ if (ret & DNHT_SCAN_END)
+ return found;
+ }
+ }
+ return found;
+}
+
+/*
+ * Similar to dn_ht_scan(), except thah the scan is performed only
+ * in the bucket 'bucket'. The function returns a correct bucket number if
+ * the original is invalid
+ */
+int
+dn_ht_scan_bucket(struct dn_ht *ht, int *bucket, int (*fn)(void *, void *),
+ void *arg)
+{
+ int i, ret, found = 0;
+ void **curp, *cur, *next;
+
+ if (ht == NULL || fn == NULL)
+ return 0;
+ if (*bucket > ht->buckets)
+ *bucket = 0;
+ i = *bucket;
+
+ curp = &ht->ht[i];
+ while ( (cur = *curp) != NULL) {
+ next = *(void **)((char *)cur + ht->ofs);
+ ret = fn(cur, arg);
+ if (ret & DNHT_SCAN_DEL) {
+ found++;
+ ht->entries--;
+ *curp = next;
+ } else {
+ curp = (void **)((char *)cur + ht->ofs);
+ }
+ if (ret & DNHT_SCAN_END)
+ return found;
+ }
+ return found;
+}
+
diff --git a/sys/netinet/ipfw/dn_heap.h b/sys/netinet/ipfw/dn_heap.h
new file mode 100644
index 0000000..c95473a
--- /dev/null
+++ b/sys/netinet/ipfw/dn_heap.h
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * Binary heap and hash tables, header file
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IP_DN_HEAP_H
+#define _IP_DN_HEAP_H
+
+#define DN_KEY_LT(a,b) ((int64_t)((a)-(b)) < 0)
+#define DN_KEY_LEQ(a,b) ((int64_t)((a)-(b)) <= 0)
+
+/*
+ * This module implements a binary heap supporting random extraction.
+ *
+ * A heap entry contains an uint64_t key and a pointer to object.
+ * DN_KEY_LT(a,b) returns true if key 'a' is smaller than 'b'
+ *
+ * The heap is a struct dn_heap plus a dynamically allocated
+ * array of dn_heap_entry entries. 'size' represents the size of
+ * the array, 'elements' count entries in use. The topmost
+ * element has the smallest key.
+ * The heap supports ordered insert, and extract from the top.
+ * To extract an object from the middle of the heap, we the object
+ * must reserve an 'int32_t' to store the position of the object
+ * in the heap itself, and the location of this field must be
+ * passed as an argument to heap_init() -- use -1 if the feature
+ * is not used.
+ */
+struct dn_heap_entry {
+ uint64_t key; /* sorting key, smallest comes first */
+ void *object; /* object pointer */
+};
+
+struct dn_heap {
+ int size; /* the size of the array */
+ int elements; /* elements in use */
+ int ofs; /* offset in the object of heap index */
+ struct dn_heap_entry *p; /* array of "size" entries */
+};
+
+enum {
+ HEAP_SCAN_DEL = 1,
+ HEAP_SCAN_END = 2,
+};
+
+/*
+ * heap_init() reinitializes the heap setting the size and the offset
+ * of the index for random extraction (use -1 if not used).
+ * The 'elements' counter is set to 0.
+ *
+ * SET_HEAP_OFS() indicates where, in the object, is stored the index
+ * for random extractions from the heap.
+ *
+ * heap_free() frees the memory associated to a heap.
+ *
+ * heap_insert() adds a key-pointer pair to the heap
+ *
+ * HEAP_TOP() returns a pointer to the top element of the heap,
+ * but makes no checks on its existance (XXX should we change ?)
+ *
+ * heap_extract() removes the entry at the top, returing the pointer.
+ * (the key should have been read before).
+ *
+ * heap_scan() invokes a callback on each entry of the heap.
+ * The callback can return a combination of HEAP_SCAN_DEL and
+ * HEAP_SCAN_END. HEAP_SCAN_DEL means the current element must
+ * be removed, and HEAP_SCAN_END means to terminate the scan.
+ * heap_scan() returns the number of elements removed.
+ * Because the order is not guaranteed, we should use heap_scan()
+ * only as a last resort mechanism.
+ */
+#define HEAP_TOP(h) ((h)->p)
+#define SET_HEAP_OFS(h, n) do { (h)->ofs = n; } while (0)
+int heap_init(struct dn_heap *h, int size, int ofs);
+int heap_insert(struct dn_heap *h, uint64_t key1, void *p);
+void heap_extract(struct dn_heap *h, void *obj);
+void heap_free(struct dn_heap *h);
+int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t);
+
+/*------------------------------------------------------
+ * This module implements a generic hash table with support for
+ * running callbacks on the entire table. To avoid allocating
+ * memory during hash table operations, objects must reserve
+ * space for a link field. XXX if the heap is moderately full,
+ * an SLIST suffices, and we can tolerate the cost of a hash
+ * computation on each removal.
+ *
+ * dn_ht_init() initializes the table, setting the number of
+ * buckets, the offset of the link field, the main callbacks.
+ * Callbacks are:
+ *
+ * hash(key, flags, arg) called to return a bucket index.
+ * match(obj, key, flags, arg) called to determine if key
+ * matches the current 'obj' in the heap
+ * newh(key, flags, arg) optional, used to allocate a new
+ * object during insertions.
+ *
+ * dn_ht_free() frees the heap or unlink elements.
+ * DNHT_REMOVE unlink elements, 0 frees the heap.
+ * You need two calls to do both.
+ *
+ * dn_ht_find() is the main lookup function, which can also be
+ * used to insert or delete elements in the hash table.
+ * The final 'arg' is passed to all callbacks.
+ *
+ * dn_ht_scan() is used to invoke a callback on all entries of
+ * the heap, or possibly on just one bucket. The callback
+ * is invoked with a pointer to the object, and must return
+ * one of DNHT_SCAN_DEL or DNHT_SCAN_END to request the
+ * removal of the object from the heap and the end of the
+ * scan, respectively.
+ *
+ * dn_ht_scan_bucket() is similar to dn_ht_scan(), except that it scans
+ * only the specific bucket of the table. The bucket is a in-out
+ * parameter and return a valid bucket number if the original
+ * is invalid.
+ *
+ * A combination of flags can be used to modify the operation
+ * of the dn_ht_find(), and of the callbacks:
+ *
+ * DNHT_KEY_IS_OBJ means the key is the object pointer.
+ * It is usally of interest for the hash and match functions.
+ *
+ * DNHT_MATCH_PTR during a lookup, match pointers instead
+ * of calling match(). Normally used when removing specific
+ * entries. Does not imply KEY_IS_OBJ as the latter _is_ used
+ * by the match function.
+ *
+ * DNHT_INSERT insert the element if not found.
+ * Calls new() to allocates a new object unless
+ * DNHT_KEY_IS_OBJ is set.
+ *
+ * DNHT_UNIQUE only insert if object not found.
+ * XXX should it imply DNHT_INSERT ?
+ *
+ * DNHT_REMOVE remove objects if we find them.
+ */
+struct dn_ht; /* should be opaque */
+
+struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs,
+ uint32_t (*hash)(uintptr_t, int, void *),
+ int (*match)(void *, uintptr_t, int, void *),
+ void *(*newh)(uintptr_t, int, void *));
+void dn_ht_free(struct dn_ht *, int flags);
+
+void *dn_ht_find(struct dn_ht *, uintptr_t, int, void *);
+int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *);
+int dn_ht_scan_bucket(struct dn_ht *, int * , int (*)(void *, void *), void *);
+int dn_ht_entries(struct dn_ht *);
+
+enum { /* flags values.
+ * first two are returned by the scan callback to indicate
+ * to delete the matching element or to end the scan
+ */
+ DNHT_SCAN_DEL = 0x0001,
+ DNHT_SCAN_END = 0x0002,
+ DNHT_KEY_IS_OBJ = 0x0004, /* key is the obj pointer */
+ DNHT_MATCH_PTR = 0x0008, /* match by pointer, not match() */
+ DNHT_INSERT = 0x0010, /* insert if not found */
+ DNHT_UNIQUE = 0x0020, /* report error if already there */
+ DNHT_REMOVE = 0x0040, /* remove on find or dn_ht_free */
+};
+
+#endif /* _IP_DN_HEAP_H */
diff --git a/sys/netinet/ipfw/dn_sched.h b/sys/netinet/ipfw/dn_sched.h
new file mode 100644
index 0000000..b6bf24e
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * The API to write a packet scheduling algorithm for dummynet.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DN_SCHED_H
+#define _DN_SCHED_H
+
+#define DN_MULTIQUEUE 0x01
+/*
+ * Descriptor for a scheduling algorithm.
+ * Contains all function pointers for a given scheduler
+ * This is typically created when a module is loaded, and stored
+ * in a global list of schedulers.
+ */
+struct dn_alg {
+ uint32_t type; /* the scheduler type */
+ const char *name; /* scheduler name */
+ uint32_t flags; /* DN_MULTIQUEUE if supports multiple queues */
+
+ /*
+ * The following define the size of 3 optional data structures
+ * that may need to be allocated at runtime, and are appended
+ * to each of the base data structures: scheduler, sched.inst,
+ * and queue. We don't have a per-flowset structure.
+ */
+ /* + parameters attached to the template, e.g.
+ * default queue sizes, weights, quantum size, and so on;
+ */
+ size_t schk_datalen;
+
+ /* + per-instance parameters, such as timestamps,
+ * containers for queues, etc;
+ */
+ size_t si_datalen;
+
+ size_t q_datalen; /* per-queue parameters (e.g. S,F) */
+
+ /*
+ * Methods implemented by the scheduler:
+ * enqueue enqueue packet 'm' on scheduler 's', queue 'q'.
+ * q is NULL for !MULTIQUEUE.
+ * Return 0 on success, 1 on drop (packet consumed anyways).
+ * Note that q should be interpreted only as a hint
+ * on the flow that the mbuf belongs to: while a
+ * scheduler will normally enqueue m into q, it is ok
+ * to leave q alone and put the mbuf elsewhere.
+ * This function is called in two cases:
+ * - when a new packet arrives to the scheduler;
+ * - when a scheduler is reconfigured. In this case the
+ * call is issued by the new_queue callback, with a
+ * non empty queue (q) and m pointing to the first
+ * mbuf in the queue. For this reason, the function
+ * should internally check for (m != q->mq.head)
+ * before calling dn_enqueue().
+ *
+ * dequeue Called when scheduler instance 's' can
+ * dequeue a packet. Return NULL if none are available.
+ * XXX what about non work-conserving ?
+ *
+ * config called on 'sched X config ...', normally writes
+ * in the area of size sch_arg
+ *
+ * destroy called on 'sched delete', frees everything
+ * in sch_arg (other parts are handled by more specific
+ * functions)
+ *
+ * new_sched called when a new instance is created, e.g.
+ * to create the local queue for !MULTIQUEUE, set V or
+ * copy parameters for WFQ, and so on.
+ *
+ * free_sched called when deleting an instance, cleans
+ * extra data in the per-instance area.
+ *
+ * new_fsk called when a flowset is linked to a scheduler,
+ * e.g. to validate parameters such as weights etc.
+ * free_fsk when a flowset is unlinked from a scheduler.
+ * (probably unnecessary)
+ *
+ * new_queue called to set the per-queue parameters,
+ * e.g. S and F, adjust sum of weights in the parent, etc.
+ *
+ * The new_queue callback is normally called from when
+ * creating a new queue. In some cases (such as a
+ * scheduler change or reconfiguration) it can be called
+ * with a non empty queue. In this case, the queue
+ * In case of non empty queue, the new_queue callback could
+ * need to call the enqueue function. In this case,
+ * the callback should eventually call enqueue() passing
+ * as m the first element in the queue.
+ *
+ * free_queue actions related to a queue removal, e.g. undo
+ * all the above. If the queue has data in it, also remove
+ * from the scheduler. This can e.g. happen during a reconfigure.
+ */
+ int (*enqueue)(struct dn_sch_inst *, struct dn_queue *,
+ struct mbuf *);
+ struct mbuf * (*dequeue)(struct dn_sch_inst *);
+
+ int (*config)(struct dn_schk *);
+ int (*destroy)(struct dn_schk*);
+ int (*new_sched)(struct dn_sch_inst *);
+ int (*free_sched)(struct dn_sch_inst *);
+ int (*new_fsk)(struct dn_fsk *f);
+ int (*free_fsk)(struct dn_fsk *f);
+ int (*new_queue)(struct dn_queue *q);
+ int (*free_queue)(struct dn_queue *q);
+
+ /* run-time fields */
+ int ref_count; /* XXX number of instances in the system */
+ SLIST_ENTRY(dn_alg) next; /* Next scheduler in the list */
+};
+
+/* MSVC does not support initializers so we need this ugly macro */
+#ifdef _WIN32
+#define _SI(fld)
+#else
+#define _SI(fld) fld
+#endif
+
+/*
+ * Additionally, dummynet exports some functions and macros
+ * to be used by schedulers:
+ */
+
+void dn_free_pkts(struct mbuf *mnext);
+int dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop);
+/* bound a variable between min and max */
+int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg);
+
+/*
+ * Extract the head of a queue, update stats. Must be the very last
+ * thing done on a dequeue as the queue itself may go away.
+ */
+static __inline struct mbuf*
+dn_dequeue(struct dn_queue *q)
+{
+ struct mbuf *m = q->mq.head;
+ if (m == NULL)
+ return NULL;
+ q->mq.head = m->m_nextpkt;
+ q->ni.length--;
+ q->ni.len_bytes -= m->m_pkthdr.len;
+ if (q->_si) {
+ q->_si->ni.length--;
+ q->_si->ni.len_bytes -= m->m_pkthdr.len;
+ }
+ if (q->ni.length == 0) /* queue is now idle */
+ q->q_time = dn_cfg.curr_time;
+ return m;
+}
+
+int dn_sched_modevent(module_t mod, int cmd, void *arg);
+
+#define DECLARE_DNSCHED_MODULE(name, dnsched) \
+ static moduledata_t name##_mod = { \
+ #name, dn_sched_modevent, dnsched \
+ }; \
+ DECLARE_MODULE(name, name##_mod, \
+ SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \
+ MODULE_DEPEND(name, dummynet, 3, 3, 3);
+#endif /* _DN_SCHED_H */
diff --git a/sys/netinet/ipfw/dn_sched_fifo.c b/sys/netinet/ipfw/dn_sched_fifo.c
new file mode 100644
index 0000000..0bb3800
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_fifo.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * 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$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+/*
+ * This file implements a FIFO scheduler for a single queue.
+ * The queue is allocated as part of the scheduler instance,
+ * and there is a single flowset is in the template which stores
+ * queue size and policy.
+ * Enqueue and dequeue use the default library functions.
+ */
+static int
+fifo_enqueue(struct dn_sch_inst *si, struct dn_queue *q, struct mbuf *m)
+{
+ /* XXX if called with q != NULL and m=NULL, this is a
+ * re-enqueue from an existing scheduler, which we should
+ * handle.
+ */
+ return dn_enqueue((struct dn_queue *)(si+1), m, 0);
+}
+
+static struct mbuf *
+fifo_dequeue(struct dn_sch_inst *si)
+{
+ return dn_dequeue((struct dn_queue *)(si + 1));
+}
+
+static int
+fifo_new_sched(struct dn_sch_inst *si)
+{
+ /* This scheduler instance contains the queue */
+ struct dn_queue *q = (struct dn_queue *)(si + 1);
+
+ set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q));
+ q->_si = si;
+ q->fs = si->sched->fs;
+ return 0;
+}
+
+static int
+fifo_free_sched(struct dn_sch_inst *si)
+{
+ struct dn_queue *q = (struct dn_queue *)(si + 1);
+ dn_free_pkts(q->mq.head);
+ bzero(q, sizeof(*q));
+ return 0;
+}
+
+/*
+ * FIFO scheduler descriptor
+ * contains the type of the scheduler, the name, the size of extra
+ * data structures, and function pointers.
+ */
+static struct dn_alg fifo_desc = {
+ _SI( .type = ) DN_SCHED_FIFO,
+ _SI( .name = ) "FIFO",
+ _SI( .flags = ) 0,
+
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct dn_queue),
+ _SI( .q_datalen = ) 0,
+
+ _SI( .enqueue = ) fifo_enqueue,
+ _SI( .dequeue = ) fifo_dequeue,
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) fifo_new_sched,
+ _SI( .free_sched = ) fifo_free_sched,
+ _SI( .new_fsk = ) NULL,
+ _SI( .free_fsk = ) NULL,
+ _SI( .new_queue = ) NULL,
+ _SI( .free_queue = ) NULL,
+};
+
+DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc);
diff --git a/sys/netinet/ipfw/dn_sched_prio.c b/sys/netinet/ipfw/dn_sched_prio.c
new file mode 100644
index 0000000..28f6006
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_prio.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * 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$
+ */
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#define DN_SCHED_PRIO 5 //XXX
+
+#if !defined(_KERNEL) || !defined(__linux__)
+#define test_bit(ix, pData) ((*pData) & (1<<(ix)))
+#define __set_bit(ix, pData) (*pData) |= (1<<(ix))
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif
+
+#ifdef __MIPSEL__
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif
+
+/* Size of the array of queues pointers. */
+#define BITMAP_T unsigned long
+#define MAXPRIO (sizeof(BITMAP_T) * 8)
+
+/*
+ * The scheduler instance contains an array of pointers to queues,
+ * one for each priority, and a bitmap listing backlogged queues.
+ */
+struct prio_si {
+ BITMAP_T bitmap; /* array bitmap */
+ struct dn_queue *q_array[MAXPRIO]; /* Array of queues pointers */
+};
+
+/*
+ * If a queue with the same priority is already backlogged, use
+ * that one instead of the queue passed as argument.
+ */
+static int
+prio_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
+{
+ struct prio_si *si = (struct prio_si *)(_si + 1);
+ int prio = q->fs->fs.par[0];
+
+ if (test_bit(prio, &si->bitmap) == 0) {
+ /* No queue with this priority, insert */
+ __set_bit(prio, &si->bitmap);
+ si->q_array[prio] = q;
+ } else { /* use the existing queue */
+ q = si->q_array[prio];
+ }
+ if (dn_enqueue(q, m, 0))
+ return 1;
+ return 0;
+}
+
+/*
+ * Packets are dequeued only from the highest priority queue.
+ * The function ffs() return the lowest bit in the bitmap that rapresent
+ * the array index (-1) which contains the pointer to the highest priority
+ * queue.
+ * After the dequeue, if this queue become empty, it is index is removed
+ * from the bitmap.
+ * Scheduler is idle if the bitmap is empty
+ *
+ * NOTE: highest priority is 0, lowest is sched->max_prio_q
+ */
+static struct mbuf *
+prio_dequeue(struct dn_sch_inst *_si)
+{
+ struct prio_si *si = (struct prio_si *)(_si + 1);
+ struct mbuf *m;
+ struct dn_queue *q;
+ int prio;
+
+ if (si->bitmap == 0) /* scheduler idle */
+ return NULL;
+
+ prio = ffs(si->bitmap) - 1;
+
+ /* Take the highest priority queue in the scheduler */
+ q = si->q_array[prio];
+ // assert(q)
+
+ m = dn_dequeue(q);
+ if (q->mq.head == NULL) {
+ /* Queue is now empty, remove from scheduler
+ * and mark it
+ */
+ si->q_array[prio] = NULL;
+ __clear_bit(prio, &si->bitmap);
+ }
+ return m;
+}
+
+static int
+prio_new_sched(struct dn_sch_inst *_si)
+{
+ struct prio_si *si = (struct prio_si *)(_si + 1);
+
+ bzero(si->q_array, sizeof(si->q_array));
+ si->bitmap = 0;
+
+ return 0;
+}
+
+static int
+prio_new_fsk(struct dn_fsk *fs)
+{
+ /* Check if the prioritiy is between 0 and MAXPRIO-1 */
+ ipdn_bound_var(&fs->fs.par[0], 0, 0, MAXPRIO - 1, "PRIO priority");
+ return 0;
+}
+
+static int
+prio_new_queue(struct dn_queue *q)
+{
+ struct prio_si *si = (struct prio_si *)(q->_si + 1);
+ int prio = q->fs->fs.par[0];
+ struct dn_queue *oldq;
+
+ q->ni.oid.subtype = DN_SCHED_PRIO;
+
+ if (q->mq.head == NULL)
+ return 0;
+
+ /* Queue already full, must insert in the scheduler or append
+ * mbufs to existing queue. This partly duplicates prio_enqueue
+ */
+ if (test_bit(prio, &si->bitmap) == 0) {
+ /* No queue with this priority, insert */
+ __set_bit(prio, &si->bitmap);
+ si->q_array[prio] = q;
+ } else if ( (oldq = si->q_array[prio]) != q) {
+ /* must append to the existing queue.
+ * can simply append q->mq.head to q2->...
+ * and add the counters to those of q2
+ */
+ oldq->mq.tail->m_nextpkt = q->mq.head;
+ oldq->mq.tail = q->mq.tail;
+ oldq->ni.length += q->ni.length;
+ q->ni.length = 0;
+ oldq->ni.len_bytes += q->ni.len_bytes;
+ q->ni.len_bytes = 0;
+ q->mq.tail = q->mq.head = NULL;
+ }
+ return 0;
+}
+
+static int
+prio_free_queue(struct dn_queue *q)
+{
+ int prio = q->fs->fs.par[0];
+ struct prio_si *si = (struct prio_si *)(q->_si + 1);
+
+ if (si->q_array[prio] == q) {
+ si->q_array[prio] = NULL;
+ __clear_bit(prio, &si->bitmap);
+ }
+ return 0;
+}
+
+
+static struct dn_alg prio_desc = {
+ _SI( .type = ) DN_SCHED_PRIO,
+ _SI( .name = ) "PRIO",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ /* we need extra space in the si and the queue */
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct prio_si),
+ _SI( .q_datalen = ) 0,
+
+ _SI( .enqueue = ) prio_enqueue,
+ _SI( .dequeue = ) prio_dequeue,
+
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) prio_new_sched,
+ _SI( .free_sched = ) NULL,
+
+ _SI( .new_fsk = ) prio_new_fsk,
+ _SI( .free_fsk = ) NULL,
+
+ _SI( .new_queue = ) prio_new_queue,
+ _SI( .free_queue = ) prio_free_queue,
+};
+
+
+DECLARE_DNSCHED_MODULE(dn_prio, &prio_desc);
diff --git a/sys/netinet/ipfw/dn_sched_qfq.c b/sys/netinet/ipfw/dn_sched_qfq.c
new file mode 100644
index 0000000..44555ee
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_qfq.c
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) 2010 Fabio Checconi, Luigi Rizzo, Paolo Valente
+ * 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$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#ifdef QFQ_DEBUG
+struct qfq_sched;
+static void dump_sched(struct qfq_sched *q, const char *msg);
+#define NO(x) x
+#else
+#define NO(x)
+#endif
+#define DN_SCHED_QFQ 4 // XXX Where?
+typedef unsigned long bitmap;
+
+/*
+ * bitmaps ops are critical. Some linux versions have __fls
+ * and the bitmap ops. Some machines have ffs
+ */
+#if defined(_WIN32)
+int fls(unsigned int n)
+{
+ int i = 0;
+ for (i = 0; n > 0; n >>= 1, i++)
+ ;
+ return i;
+}
+#endif
+
+#if !defined(_KERNEL) || defined( __FreeBSD__ ) || defined(_WIN32)
+static inline unsigned long __fls(unsigned long word)
+{
+ return fls(word) - 1;
+}
+#endif
+
+#if !defined(_KERNEL) || !defined(__linux__)
+#ifdef QFQ_DEBUG
+int test_bit(int ix, bitmap *p)
+{
+ if (ix < 0 || ix > 31)
+ D("bad index %d", ix);
+ return *p & (1<<ix);
+}
+void __set_bit(int ix, bitmap *p)
+{
+ if (ix < 0 || ix > 31)
+ D("bad index %d", ix);
+ *p |= (1<<ix);
+}
+void __clear_bit(int ix, bitmap *p)
+{
+ if (ix < 0 || ix > 31)
+ D("bad index %d", ix);
+ *p &= ~(1<<ix);
+}
+#else /* !QFQ_DEBUG */
+/* XXX do we have fast version, or leave it to the compiler ? */
+#define test_bit(ix, pData) ((*pData) & (1<<(ix)))
+#define __set_bit(ix, pData) (*pData) |= (1<<(ix))
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif /* !QFQ_DEBUG */
+#endif /* !__linux__ */
+
+#ifdef __MIPSEL__
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif
+
+/*-------------------------------------------*/
+/*
+
+Virtual time computations.
+
+S, F and V are all computed in fixed point arithmetic with
+FRAC_BITS decimal bits.
+
+ QFQ_MAX_INDEX is the maximum index allowed for a group. We need
+ one bit per index.
+ QFQ_MAX_WSHIFT is the maximum power of two supported as a weight.
+ The layout of the bits is as below:
+
+ [ MTU_SHIFT ][ FRAC_BITS ]
+ [ MAX_INDEX ][ MIN_SLOT_SHIFT ]
+ ^.__grp->index = 0
+ *.__grp->slot_shift
+
+ where MIN_SLOT_SHIFT is derived by difference from the others.
+
+The max group index corresponds to Lmax/w_min, where
+Lmax=1<<MTU_SHIFT, w_min = 1 .
+From this, and knowing how many groups (MAX_INDEX) we want,
+we can derive the shift corresponding to each group.
+
+Because we often need to compute
+ F = S + len/w_i and V = V + len/wsum
+instead of storing w_i store the value
+ inv_w = (1<<FRAC_BITS)/w_i
+so we can do F = S + len * inv_w * wsum.
+We use W_TOT in the formulas so we can easily move between
+static and adaptive weight sum.
+
+The per-scheduler-instance data contain all the data structures
+for the scheduler: bitmaps and bucket lists.
+
+ */
+/*
+ * Maximum number of consecutive slots occupied by backlogged classes
+ * inside a group. This is approx lmax/lmin + 5.
+ * XXX check because it poses constraints on MAX_INDEX
+ */
+#define QFQ_MAX_SLOTS 32
+/*
+ * Shifts used for class<->group mapping. Class weights are
+ * in the range [1, QFQ_MAX_WEIGHT], we to map each class i to the
+ * group with the smallest index that can support the L_i / r_i
+ * configured for the class.
+ *
+ * grp->index is the index of the group; and grp->slot_shift
+ * is the shift for the corresponding (scaled) sigma_i.
+ *
+ * When computing the group index, we do (len<<FP_SHIFT)/weight,
+ * then compute an FLS (which is like a log2()), and if the result
+ * is below the MAX_INDEX region we use 0 (which is the same as
+ * using a larger len).
+ */
+#define QFQ_MAX_INDEX 19
+#define QFQ_MAX_WSHIFT 16 /* log2(max_weight) */
+
+#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
+#define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT)
+//#define IWSUM (q->i_wsum)
+#define IWSUM ((1<<FRAC_BITS)/QFQ_MAX_WSUM)
+
+#define FRAC_BITS 30 /* fixed point arithmetic */
+#define ONE_FP (1UL << FRAC_BITS)
+
+#define QFQ_MTU_SHIFT 11 /* log2(max_len) */
+#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
+
+/*
+ * Possible group states, also indexes for the bitmaps array in
+ * struct qfq_queue. We rely on ER, IR, EB, IB being numbered 0..3
+ */
+enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE };
+
+struct qfq_group;
+/*
+ * additional queue info. Some of this info should come from
+ * the flowset, we copy them here for faster processing.
+ * This is an overlay of the struct dn_queue
+ */
+struct qfq_class {
+ struct dn_queue _q;
+ uint64_t S, F; /* flow timestamps (exact) */
+ struct qfq_class *next; /* Link for the slot list. */
+
+ /* group we belong to. In principle we would need the index,
+ * which is log_2(lmax/weight), but we never reference it
+ * directly, only the group.
+ */
+ struct qfq_group *grp;
+
+ /* these are copied from the flowset. */
+ uint32_t inv_w; /* ONE_FP/weight */
+ uint32_t lmax; /* Max packet size for this flow. */
+};
+
+/* Group descriptor, see the paper for details.
+ * Basically this contains the bucket lists
+ */
+struct qfq_group {
+ uint64_t S, F; /* group timestamps (approx). */
+ unsigned int slot_shift; /* Slot shift. */
+ unsigned int index; /* Group index. */
+ unsigned int front; /* Index of the front slot. */
+ bitmap full_slots; /* non-empty slots */
+
+ /* Array of lists of active classes. */
+ struct qfq_class *slots[QFQ_MAX_SLOTS];
+};
+
+/* scheduler instance descriptor. */
+struct qfq_sched {
+ uint64_t V; /* Precise virtual time. */
+ uint32_t wsum; /* weight sum */
+ NO(uint32_t i_wsum; /* ONE_FP/w_sum */
+ uint32_t _queued; /* debugging */
+ uint32_t loops; /* debugging */)
+ bitmap bitmaps[QFQ_MAX_STATE]; /* Group bitmaps. */
+ struct qfq_group groups[QFQ_MAX_INDEX + 1]; /* The groups. */
+};
+
+/*---- support functions ----------------------------*/
+
+/* Generic comparison function, handling wraparound. */
+static inline int qfq_gt(uint64_t a, uint64_t b)
+{
+ return (int64_t)(a - b) > 0;
+}
+
+/* Round a precise timestamp to its slotted value. */
+static inline uint64_t qfq_round_down(uint64_t ts, unsigned int shift)
+{
+ return ts & ~((1ULL << shift) - 1);
+}
+
+/* return the pointer to the group with lowest index in the bitmap */
+static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
+ unsigned long bitmap)
+{
+ int index = ffs(bitmap) - 1; // zero-based
+ return &q->groups[index];
+}
+
+/*
+ * Calculate a flow index, given its weight and maximum packet length.
+ * index = log_2(maxlen/weight) but we need to apply the scaling.
+ * This is used only once at flow creation.
+ */
+static int qfq_calc_index(uint32_t inv_w, unsigned int maxlen)
+{
+ uint64_t slot_size = (uint64_t)maxlen *inv_w;
+ unsigned long size_map;
+ int index = 0;
+
+ size_map = (unsigned long)(slot_size >> QFQ_MIN_SLOT_SHIFT);
+ if (!size_map)
+ goto out;
+
+ index = __fls(size_map) + 1; // basically a log_2()
+ index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
+
+ if (index < 0)
+ index = 0;
+
+out:
+ ND("W = %d, L = %d, I = %d\n", ONE_FP/inv_w, maxlen, index);
+ return index;
+}
+/*---- end support functions ----*/
+
+/*-------- API calls --------------------------------*/
+/*
+ * Validate and copy parameters from flowset.
+ */
+static int
+qfq_new_queue(struct dn_queue *_q)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
+ struct qfq_class *cl = (struct qfq_class *)_q;
+ int i;
+ uint32_t w; /* approximated weight */
+
+ /* import parameters from the flowset. They should be correct
+ * already.
+ */
+ w = _q->fs->fs.par[0];
+ cl->lmax = _q->fs->fs.par[1];
+ if (!w || w > QFQ_MAX_WEIGHT) {
+ w = 1;
+ D("rounding weight to 1");
+ }
+ cl->inv_w = ONE_FP/w;
+ w = ONE_FP/cl->inv_w;
+ if (q->wsum + w > QFQ_MAX_WSUM)
+ return EINVAL;
+
+ i = qfq_calc_index(cl->inv_w, cl->lmax);
+ cl->grp = &q->groups[i];
+ q->wsum += w;
+ // XXX cl->S = q->V; ?
+ // XXX compute q->i_wsum
+ return 0;
+}
+
+/* remove an empty queue */
+static int
+qfq_free_queue(struct dn_queue *_q)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
+ struct qfq_class *cl = (struct qfq_class *)_q;
+ if (cl->inv_w) {
+ q->wsum -= ONE_FP/cl->inv_w;
+ cl->inv_w = 0; /* reset weight to avoid run twice */
+ }
+ return 0;
+}
+
+/* Calculate a mask to mimic what would be ffs_from(). */
+static inline unsigned long
+mask_from(unsigned long bitmap, int from)
+{
+ return bitmap & ~((1UL << from) - 1);
+}
+
+/*
+ * The state computation relies on ER=0, IR=1, EB=2, IB=3
+ * First compute eligibility comparing grp->S, q->V,
+ * then check if someone is blocking us and possibly add EB
+ */
+static inline unsigned int
+qfq_calc_state(struct qfq_sched *q, struct qfq_group *grp)
+{
+ /* if S > V we are not eligible */
+ unsigned int state = qfq_gt(grp->S, q->V);
+ unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (qfq_gt(grp->F, next->F))
+ state |= EB;
+ }
+
+ return state;
+}
+
+/*
+ * In principle
+ * q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ * q->bitmaps[src] &= ~mask;
+ * but we should make sure that src != dst
+ */
+static inline void
+qfq_move_groups(struct qfq_sched *q, unsigned long mask, int src, int dst)
+{
+ q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ q->bitmaps[src] &= ~mask;
+}
+
+static inline void
+qfq_unblock_groups(struct qfq_sched *q, int index, uint64_t old_finish)
+{
+ unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (!qfq_gt(next->F, old_finish))
+ return;
+ }
+
+ mask = (1UL << index) - 1;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+}
+
+/*
+ * perhaps
+ *
+ old_V ^= q->V;
+ old_V >>= QFQ_MIN_SLOT_SHIFT;
+ if (old_V) {
+ ...
+ }
+ *
+ */
+static inline void
+qfq_make_eligible(struct qfq_sched *q, uint64_t old_V)
+{
+ unsigned long mask, vslot, old_vslot;
+
+ vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
+ old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
+
+ if (vslot != old_vslot) {
+ mask = (2UL << (__fls(vslot ^ old_vslot))) - 1;
+ qfq_move_groups(q, mask, IR, ER);
+ qfq_move_groups(q, mask, IB, EB);
+ }
+}
+
+/*
+ * XXX we should make sure that slot becomes less than 32.
+ * This is guaranteed by the input values.
+ * roundedS is always cl->S rounded on grp->slot_shift bits.
+ */
+static inline void
+qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, uint64_t roundedS)
+{
+ uint64_t slot = (roundedS - grp->S) >> grp->slot_shift;
+ unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
+
+ cl->next = grp->slots[i];
+ grp->slots[i] = cl;
+ __set_bit(slot, &grp->full_slots);
+}
+
+/*
+ * remove the entry from the slot
+ */
+static inline void
+qfq_front_slot_remove(struct qfq_group *grp)
+{
+ struct qfq_class **h = &grp->slots[grp->front];
+
+ *h = (*h)->next;
+ if (!*h)
+ __clear_bit(0, &grp->full_slots);
+}
+
+/*
+ * Returns the first full queue in a group. As a side effect,
+ * adjust the bucket list so the first non-empty bucket is at
+ * position 0 in full_slots.
+ */
+static inline struct qfq_class *
+qfq_slot_scan(struct qfq_group *grp)
+{
+ int i;
+
+ ND("grp %d full %x", grp->index, grp->full_slots);
+ if (!grp->full_slots)
+ return NULL;
+
+ i = ffs(grp->full_slots) - 1; // zero-based
+ if (i > 0) {
+ grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
+ grp->full_slots >>= i;
+ }
+
+ return grp->slots[grp->front];
+}
+
+/*
+ * adjust the bucket list. When the start time of a group decreases,
+ * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to
+ * move the objects. The mask of occupied slots must be shifted
+ * because we use ffs() to find the first non-empty slot.
+ * This covers decreases in the group's start time, but what about
+ * increases of the start time ?
+ * Here too we should make sure that i is less than 32
+ */
+static inline void
+qfq_slot_rotate(struct qfq_sched *q, struct qfq_group *grp, uint64_t roundedS)
+{
+ unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
+
+ grp->full_slots <<= i;
+ grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
+}
+
+
+static inline void
+qfq_update_eligible(struct qfq_sched *q, uint64_t old_V)
+{
+ bitmap ineligible;
+
+ ineligible = q->bitmaps[IR] | q->bitmaps[IB];
+ if (ineligible) {
+ if (!q->bitmaps[ER]) {
+ struct qfq_group *grp;
+ grp = qfq_ffs(q, ineligible);
+ if (qfq_gt(grp->S, q->V))
+ q->V = grp->S;
+ }
+ qfq_make_eligible(q, old_V);
+ }
+}
+
+/*
+ * Updates the class, returns true if also the group needs to be updated.
+ */
+static inline int
+qfq_update_class(struct qfq_sched *q, struct qfq_group *grp,
+ struct qfq_class *cl)
+{
+
+ cl->S = cl->F;
+ if (cl->_q.mq.head == NULL) {
+ qfq_front_slot_remove(grp);
+ } else {
+ unsigned int len;
+ uint64_t roundedS;
+
+ len = cl->_q.mq.head->m_pkthdr.len;
+ cl->F = cl->S + (uint64_t)len * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (roundedS == grp->S)
+ return 0;
+
+ qfq_front_slot_remove(grp);
+ qfq_slot_insert(grp, cl, roundedS);
+ }
+ return 1;
+}
+
+static struct mbuf *
+qfq_dequeue(struct dn_sch_inst *si)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(si + 1);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ struct mbuf *m;
+ uint64_t old_V;
+
+ NO(q->loops++;)
+ if (!q->bitmaps[ER]) {
+ NO(if (q->queued)
+ dump_sched(q, "start dequeue");)
+ return NULL;
+ }
+
+ grp = qfq_ffs(q, q->bitmaps[ER]);
+
+ cl = grp->slots[grp->front];
+ /* extract from the first bucket in the bucket list */
+ m = dn_dequeue(&cl->_q);
+
+ if (!m) {
+ D("BUG/* non-workconserving leaf */");
+ return NULL;
+ }
+ NO(q->queued--;)
+ old_V = q->V;
+ q->V += (uint64_t)m->m_pkthdr.len * IWSUM;
+ ND("m is %p F 0x%llx V now 0x%llx", m, cl->F, q->V);
+
+ if (qfq_update_class(q, grp, cl)) {
+ uint64_t old_F = grp->F;
+ cl = qfq_slot_scan(grp);
+ if (!cl) { /* group gone, remove from ER */
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ // grp->S = grp->F + 1; // XXX debugging only
+ } else {
+ uint64_t roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ unsigned int s;
+
+ if (grp->S == roundedS)
+ goto skip_unblock;
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ /* remove from ER and put in the new set */
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+ /* we need to unblock even if the group has gone away */
+ qfq_unblock_groups(q, grp->index, old_F);
+ }
+
+skip_unblock:
+ qfq_update_eligible(q, old_V);
+ NO(if (!q->bitmaps[ER] && q->queued)
+ dump_sched(q, "end dequeue");)
+
+ return m;
+}
+
+/*
+ * Assign a reasonable start time for a new flow k in group i.
+ * Admissible values for \hat(F) are multiples of \sigma_i
+ * no greater than V+\sigma_i . Larger values mean that
+ * we had a wraparound so we consider the timestamp to be stale.
+ *
+ * If F is not stale and F >= V then we set S = F.
+ * Otherwise we should assign S = V, but this may violate
+ * the ordering in ER. So, if we have groups in ER, set S to
+ * the F_j of the first group j which would be blocking us.
+ * We are guaranteed not to move S backward because
+ * otherwise our group i would still be blocked.
+ */
+static inline void
+qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
+{
+ unsigned long mask;
+ uint32_t limit, roundedF;
+ int slot_shift = cl->grp->slot_shift;
+
+ roundedF = qfq_round_down(cl->F, slot_shift);
+ limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
+
+ if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
+ /* timestamp was stale */
+ mask = mask_from(q->bitmaps[ER], cl->grp->index);
+ if (mask) {
+ struct qfq_group *next = qfq_ffs(q, mask);
+ if (qfq_gt(roundedF, next->F)) {
+ cl->S = next->F;
+ return;
+ }
+ }
+ cl->S = q->V;
+ } else { /* timestamp is not stale */
+ cl->S = cl->F;
+ }
+}
+
+static int
+qfq_enqueue(struct dn_sch_inst *si, struct dn_queue *_q, struct mbuf *m)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(si + 1);
+ struct qfq_group *grp;
+ struct qfq_class *cl = (struct qfq_class *)_q;
+ uint64_t roundedS;
+ int s;
+
+ NO(q->loops++;)
+ DX(4, "len %d flow %p inv_w 0x%x grp %d", m->m_pkthdr.len,
+ _q, cl->inv_w, cl->grp->index);
+ /* XXX verify that the packet obeys the parameters */
+ if (m != _q->mq.head) {
+ if (dn_enqueue(_q, m, 0)) /* packet was dropped */
+ return 1;
+ NO(q->queued++;)
+ if (m != _q->mq.head)
+ return 0;
+ }
+ /* If reach this point, queue q was idle */
+ grp = cl->grp;
+ qfq_update_start(q, cl); /* adjust start time */
+ /* compute new finish time and rounded start. */
+ cl->F = cl->S + (uint64_t)(m->m_pkthdr.len) * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+
+ /*
+ * insert cl in the correct bucket.
+ * If cl->S >= grp->S we don't need to adjust the
+ * bucket list and simply go to the insertion phase.
+ * Otherwise grp->S is decreasing, we must make room
+ * in the bucket list, and also recompute the group state.
+ * Finally, if there were no flows in this group and nobody
+ * was in ER make sure to adjust V.
+ */
+ if (grp->full_slots) {
+ if (!qfq_gt(grp->S, cl->S))
+ goto skip_update;
+ /* create a slot for this cl->S */
+ qfq_slot_rotate(q, grp, roundedS);
+ /* group was surely ineligible, remove */
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+ q->V = roundedS;
+
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift); // i.e. 2\sigma_i
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ ND("new state %d 0x%x", s, q->bitmaps[s]);
+ ND("S %llx F %llx V %llx", cl->S, cl->F, q->V);
+skip_update:
+ qfq_slot_insert(grp, cl, roundedS);
+
+ return 0;
+}
+
+
+#if 0
+static inline void
+qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
+ struct qfq_class *cl, struct qfq_class **pprev)
+{
+ unsigned int i, offset;
+ uint64_t roundedS;
+
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ offset = (roundedS - grp->S) >> grp->slot_shift;
+ i = (grp->front + offset) % QFQ_MAX_SLOTS;
+
+#ifdef notyet
+ if (!pprev) {
+ pprev = &grp->slots[i];
+ while (*pprev && *pprev != cl)
+ pprev = &(*pprev)->next;
+ }
+#endif
+
+ *pprev = cl->next;
+ if (!grp->slots[i])
+ __clear_bit(offset, &grp->full_slots);
+}
+
+/*
+ * called to forcibly destroy a queue.
+ * If the queue is not in the front bucket, or if it has
+ * other queues in the front bucket, we can simply remove
+ * the queue with no other side effects.
+ * Otherwise we must propagate the event up.
+ * XXX description to be completed.
+ */
+static void
+qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl,
+ struct qfq_class **pprev)
+{
+ struct qfq_group *grp = &q->groups[cl->index];
+ unsigned long mask;
+ uint64_t roundedS;
+ int s;
+
+ cl->F = cl->S; // not needed if the class goes away.
+ qfq_slot_remove(q, grp, cl, pprev);
+
+ if (!grp->full_slots) {
+ /* nothing left in the group, remove from all sets.
+ * Do ER last because if we were blocking other groups
+ * we must unblock them.
+ */
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+
+ if (test_bit(grp->index, &q->bitmaps[ER]) &&
+ !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
+ mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
+ if (mask)
+ mask = ~((1UL << __fls(mask)) - 1);
+ else
+ mask = ~0UL;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+ }
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ } else if (!grp->slots[grp->front]) {
+ cl = qfq_slot_scan(grp);
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (grp->S != roundedS) {
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+ }
+ qfq_update_eligible(q, q->V);
+}
+#endif
+
+static int
+qfq_new_fsk(struct dn_fsk *f)
+{
+ ipdn_bound_var(&f->fs.par[0], 1, 1, QFQ_MAX_WEIGHT, "qfq weight");
+ ipdn_bound_var(&f->fs.par[1], 1500, 1, 2000, "qfq maxlen");
+ ND("weight %d len %d\n", f->fs.par[0], f->fs.par[1]);
+ return 0;
+}
+
+/*
+ * initialize a new scheduler instance
+ */
+static int
+qfq_new_sched(struct dn_sch_inst *si)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(si + 1);
+ struct qfq_group *grp;
+ int i;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ grp->index = i;
+ grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS -
+ (QFQ_MAX_INDEX - i);
+ }
+ return 0;
+}
+
+/*
+ * QFQ scheduler descriptor
+ */
+static struct dn_alg qfq_desc = {
+ _SI( .type = ) DN_SCHED_QFQ,
+ _SI( .name = ) "QFQ",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct qfq_sched),
+ _SI( .q_datalen = ) sizeof(struct qfq_class) - sizeof(struct dn_queue),
+
+ _SI( .enqueue = ) qfq_enqueue,
+ _SI( .dequeue = ) qfq_dequeue,
+
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) qfq_new_sched,
+ _SI( .free_sched = ) NULL,
+ _SI( .new_fsk = ) qfq_new_fsk,
+ _SI( .free_fsk = ) NULL,
+ _SI( .new_queue = ) qfq_new_queue,
+ _SI( .free_queue = ) qfq_free_queue,
+};
+
+DECLARE_DNSCHED_MODULE(dn_qfq, &qfq_desc);
+
+#ifdef QFQ_DEBUG
+static void
+dump_groups(struct qfq_sched *q, uint32_t mask)
+{
+ int i, j;
+
+ for (i = 0; i < QFQ_MAX_INDEX + 1; i++) {
+ struct qfq_group *g = &q->groups[i];
+
+ if (0 == (mask & (1<<i)))
+ continue;
+ for (j = 0; j < QFQ_MAX_SLOTS; j++) {
+ if (g->slots[j])
+ D(" bucket %d %p", j, g->slots[j]);
+ }
+ D("full_slots 0x%x", g->full_slots);
+ D(" %2d S 0x%20llx F 0x%llx %c", i,
+ g->S, g->F,
+ mask & (1<<i) ? '1' : '0');
+ }
+}
+
+static void
+dump_sched(struct qfq_sched *q, const char *msg)
+{
+ D("--- in %s: ---", msg);
+ ND("loops %d queued %d V 0x%llx", q->loops, q->queued, q->V);
+ D(" ER 0x%08x", q->bitmaps[ER]);
+ D(" EB 0x%08x", q->bitmaps[EB]);
+ D(" IR 0x%08x", q->bitmaps[IR]);
+ D(" IB 0x%08x", q->bitmaps[IB]);
+ dump_groups(q, 0xffffffff);
+};
+#endif /* QFQ_DEBUG */
diff --git a/sys/netinet/ipfw/dn_sched_rr.c b/sys/netinet/ipfw/dn_sched_rr.c
new file mode 100644
index 0000000..1bbd800
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_rr.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * 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$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#define DN_SCHED_RR 3 // XXX Where?
+
+struct rr_queue {
+ struct dn_queue q; /* Standard queue */
+ int status; /* 1: queue is in the list */
+ int credit; /* Number of bytes to transmit */
+ int quantum; /* quantum * C */
+ struct rr_queue *qnext; /* */
+};
+
+/* struct rr_schk contains global config parameters
+ * and is right after dn_schk
+ */
+struct rr_schk {
+ int min_q; /* Min quantum */
+ int max_q; /* Max quantum */
+ int q_bytes; /* Bytes per quantum */
+};
+
+/* per-instance round robin list, right after dn_sch_inst */
+struct rr_si {
+ struct rr_queue *head, *tail; /* Pointer to current queue */
+};
+
+/* Append a queue to the rr list */
+static inline void
+rr_append(struct rr_queue *q, struct rr_si *si)
+{
+ q->status = 1; /* mark as in-rr_list */
+ q->credit = q->quantum; /* initialize credit */
+
+ /* append to the tail */
+ if (si->head == NULL)
+ si->head = q;
+ else
+ si->tail->qnext = q;
+ si->tail = q; /* advance the tail pointer */
+ q->qnext = si->head; /* make it circular */
+}
+
+/* Remove the head queue from circular list. */
+static inline void
+rr_remove_head(struct rr_si *si)
+{
+ if (si->head == NULL)
+ return; /* empty queue */
+ si->head->status = 0;
+
+ if (si->head == si->tail) {
+ si->head = si->tail = NULL;
+ return;
+ }
+
+ si->head = si->head->qnext;
+ si->tail->qnext = si->head;
+}
+
+/* Remove a queue from circular list.
+ * XXX see if ti can be merge with remove_queue()
+ */
+static inline void
+remove_queue_q(struct rr_queue *q, struct rr_si *si)
+{
+ struct rr_queue *prev;
+
+ if (q->status != 1)
+ return;
+ if (q == si->head) {
+ rr_remove_head(si);
+ return;
+ }
+
+ for (prev = si->head; prev; prev = prev->qnext) {
+ if (prev->qnext != q)
+ continue;
+ prev->qnext = q->qnext;
+ if (q == si->tail)
+ si->tail = prev;
+ q->status = 0;
+ break;
+ }
+}
+
+
+static inline void
+next_pointer(struct rr_si *si)
+{
+ if (si->head == NULL)
+ return; /* empty queue */
+
+ si->head = si->head->qnext;
+ si->tail = si->tail->qnext;
+}
+
+static int
+rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
+{
+ struct rr_si *si;
+ struct rr_queue *rrq;
+
+ if (m != q->mq.head) {
+ if (dn_enqueue(q, m, 0)) /* packet was dropped */
+ return 1;
+ if (m != q->mq.head)
+ return 0;
+ }
+
+ /* If reach this point, queue q was idle */
+ si = (struct rr_si *)(_si + 1);
+ rrq = (struct rr_queue *)q;
+
+ if (rrq->status == 1) /* Queue is already in the queue list */
+ return 0;
+
+ /* Insert the queue in the queue list */
+ rr_append(rrq, si);
+
+ return 0;
+}
+
+static struct mbuf *
+rr_dequeue(struct dn_sch_inst *_si)
+{
+ /* Access scheduler instance private data */
+ struct rr_si *si = (struct rr_si *)(_si + 1);
+ struct rr_queue *rrq;
+ uint64_t len;
+
+ while ( (rrq = si->head) ) {
+ struct mbuf *m = rrq->q.mq.head;
+ if ( m == NULL) {
+ /* empty queue, remove from list */
+ rr_remove_head(si);
+ continue;
+ }
+ len = m->m_pkthdr.len;
+
+ if (len > rrq->credit) {
+ /* Packet too big */
+ rrq->credit += rrq->quantum;
+ /* Try next queue */
+ next_pointer(si);
+ } else {
+ rrq->credit -= len;
+ return dn_dequeue(&rrq->q);
+ }
+ }
+
+ /* no packet to dequeue*/
+ return NULL;
+}
+
+static int
+rr_config(struct dn_schk *_schk)
+{
+ struct rr_schk *schk = (struct rr_schk *)(_schk + 1);
+ ND("called");
+
+ /* use reasonable quantums (64..2k bytes, default 1500) */
+ schk->min_q = 64;
+ schk->max_q = 2048;
+ schk->q_bytes = 1500; /* quantum */
+
+ return 0;
+}
+
+static int
+rr_new_sched(struct dn_sch_inst *_si)
+{
+ struct rr_si *si = (struct rr_si *)(_si + 1);
+
+ ND("called");
+ si->head = si->tail = NULL;
+
+ return 0;
+}
+
+static int
+rr_free_sched(struct dn_sch_inst *_si)
+{
+ ND("called");
+ /* Nothing to do? */
+ return 0;
+}
+
+static int
+rr_new_fsk(struct dn_fsk *fs)
+{
+ struct rr_schk *schk = (struct rr_schk *)(fs->sched + 1);
+ /* par[0] is the weight, par[1] is the quantum step */
+ ipdn_bound_var(&fs->fs.par[0], 1,
+ 1, 65536, "RR weight");
+ ipdn_bound_var(&fs->fs.par[1], schk->q_bytes,
+ schk->min_q, schk->max_q, "RR quantum");
+ return 0;
+}
+
+static int
+rr_new_queue(struct dn_queue *_q)
+{
+ struct rr_queue *q = (struct rr_queue *)_q;
+
+ _q->ni.oid.subtype = DN_SCHED_RR;
+
+ q->quantum = _q->fs->fs.par[0] * _q->fs->fs.par[1];
+ ND("called, q->quantum %d", q->quantum);
+ q->credit = q->quantum;
+ q->status = 0;
+
+ if (_q->mq.head != NULL) {
+ /* Queue NOT empty, insert in the queue list */
+ rr_append(q, (struct rr_si *)(_q->_si + 1));
+ }
+ return 0;
+}
+
+static int
+rr_free_queue(struct dn_queue *_q)
+{
+ struct rr_queue *q = (struct rr_queue *)_q;
+
+ ND("called");
+ if (q->status == 1) {
+ struct rr_si *si = (struct rr_si *)(_q->_si + 1);
+ remove_queue_q(q, si);
+ }
+ return 0;
+}
+
+/*
+ * RR scheduler descriptor
+ * contains the type of the scheduler, the name, the size of the
+ * structures and function pointers.
+ */
+static struct dn_alg rr_desc = {
+ _SI( .type = ) DN_SCHED_RR,
+ _SI( .name = ) "RR",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct rr_si),
+ _SI( .q_datalen = ) sizeof(struct rr_queue) - sizeof(struct dn_queue),
+
+ _SI( .enqueue = ) rr_enqueue,
+ _SI( .dequeue = ) rr_dequeue,
+
+ _SI( .config = ) rr_config,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) rr_new_sched,
+ _SI( .free_sched = ) rr_free_sched,
+ _SI( .new_fsk = ) rr_new_fsk,
+ _SI( .free_fsk = ) NULL,
+ _SI( .new_queue = ) rr_new_queue,
+ _SI( .free_queue = ) rr_free_queue,
+};
+
+
+DECLARE_DNSCHED_MODULE(dn_rr, &rr_desc);
diff --git a/sys/netinet/ipfw/dn_sched_wf2q.c b/sys/netinet/ipfw/dn_sched_wf2q.c
new file mode 100644
index 0000000..55a4955
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_wf2q.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * Copyright (c) 2000-2002 Luigi Rizzo, Universita` di Pisa
+ * 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$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#ifndef MAX64
+#define MAX64(x,y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x)
+#endif
+
+/*
+ * timestamps are computed on 64 bit using fixed point arithmetic.
+ * LMAX_BITS, WMAX_BITS are the max number of bits for the packet len
+ * and sum of weights, respectively. FRAC_BITS is the number of
+ * fractional bits. We want FRAC_BITS >> WMAX_BITS to avoid too large
+ * errors when computing the inverse, FRAC_BITS < 32 so we can do 1/w
+ * using an unsigned 32-bit division, and to avoid wraparounds we need
+ * LMAX_BITS + WMAX_BITS + FRAC_BITS << 64
+ * As an example
+ * FRAC_BITS = 26, LMAX_BITS=14, WMAX_BITS = 19
+ */
+#ifndef FRAC_BITS
+#define FRAC_BITS 28 /* shift for fixed point arithmetic */
+#define ONE_FP (1UL << FRAC_BITS)
+#endif
+
+/*
+ * Private information for the scheduler instance:
+ * sch_heap (key is Finish time) returns the next queue to serve
+ * ne_heap (key is Start time) stores not-eligible queues
+ * idle_heap (key=start/finish time) stores idle flows. It must
+ * support extract-from-middle.
+ * A flow is only in 1 of the three heaps.
+ * XXX todo: use a more efficient data structure, e.g. a tree sorted
+ * by F with min_subtree(S) in each node
+ */
+struct wf2qp_si {
+ struct dn_heap sch_heap; /* top extract - key Finish time */
+ struct dn_heap ne_heap; /* top extract - key Start time */
+ struct dn_heap idle_heap; /* random extract - key Start=Finish time */
+ uint64_t V; /* virtual time */
+ uint32_t inv_wsum; /* inverse of sum of weights */
+ uint32_t wsum; /* sum of weights */
+};
+
+struct wf2qp_queue {
+ struct dn_queue _q;
+ uint64_t S, F; /* start time, finish time */
+ uint32_t inv_w; /* ONE_FP / weight */
+ int32_t heap_pos; /* position (index) of struct in heap */
+};
+
+/*
+ * This file implements a WF2Q+ scheduler as it has been in dummynet
+ * since 2000.
+ * The scheduler supports per-flow queues and has O(log N) complexity.
+ *
+ * WF2Q+ needs to drain entries from the idle heap so that we
+ * can keep the sum of weights up to date. We can do it whenever
+ * we get a chance, or periodically, or following some other
+ * strategy. The function idle_check() drains at most N elements
+ * from the idle heap.
+ */
+static void
+idle_check(struct wf2qp_si *si, int n, int force)
+{
+ struct dn_heap *h = &si->idle_heap;
+ while (n-- > 0 && h->elements > 0 &&
+ (force || DN_KEY_LT(HEAP_TOP(h)->key, si->V))) {
+ struct dn_queue *q = HEAP_TOP(h)->object;
+ struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
+
+ heap_extract(h, NULL);
+ /* XXX to let the flowset delete the queue we should
+ * mark it as 'unused' by the scheduler.
+ */
+ alg_fq->S = alg_fq->F + 1; /* Mark timestamp as invalid. */
+ si->wsum -= q->fs->fs.par[0]; /* adjust sum of weights */
+ if (si->wsum > 0)
+ si->inv_wsum = ONE_FP/si->wsum;
+ }
+}
+
+static int
+wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
+{
+ struct dn_fsk *fs = q->fs;
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+ struct wf2qp_queue *alg_fq;
+ uint64_t len = m->m_pkthdr.len;
+
+ if (m != q->mq.head) {
+ if (dn_enqueue(q, m, 0)) /* packet was dropped */
+ return 1;
+ if (m != q->mq.head) /* queue was already busy */
+ return 0;
+ }
+
+ /* If reach this point, queue q was idle */
+ alg_fq = (struct wf2qp_queue *)q;
+
+ if (DN_KEY_LT(alg_fq->F, alg_fq->S)) {
+ /* F<S means timestamps are invalid ->brand new queue. */
+ alg_fq->S = si->V; /* init start time */
+ si->wsum += fs->fs.par[0]; /* add weight of new queue. */
+ si->inv_wsum = ONE_FP/si->wsum;
+ } else { /* if it was idle then it was in the idle heap */
+ heap_extract(&si->idle_heap, q);
+ alg_fq->S = MAX64(alg_fq->F, si->V); /* compute new S */
+ }
+ alg_fq->F = alg_fq->S + len * alg_fq->inv_w;
+
+ /* if nothing is backlogged, make sure this flow is eligible */
+ if (si->ne_heap.elements == 0 && si->sch_heap.elements == 0)
+ si->V = MAX64(alg_fq->S, si->V);
+
+ /*
+ * Look at eligibility. A flow is not eligibile if S>V (when
+ * this happens, it means that there is some other flow already
+ * scheduled for the same pipe, so the sch_heap cannot be
+ * empty). If the flow is not eligible we just store it in the
+ * ne_heap. Otherwise, we store in the sch_heap.
+ * Note that for all flows in sch_heap (SCH), S_i <= V,
+ * and for all flows in ne_heap (NEH), S_i > V.
+ * So when we need to compute max(V, min(S_i)) forall i in
+ * SCH+NEH, we only need to look into NEH.
+ */
+ if (DN_KEY_LT(si->V, alg_fq->S)) {
+ /* S>V means flow Not eligible. */
+ if (si->sch_heap.elements == 0)
+ D("++ ouch! not eligible but empty scheduler!");
+ heap_insert(&si->ne_heap, alg_fq->S, q);
+ } else {
+ heap_insert(&si->sch_heap, alg_fq->F, q);
+ }
+ return 0;
+}
+
+/* XXX invariant: sch > 0 || V >= min(S in neh) */
+static struct mbuf *
+wf2qp_dequeue(struct dn_sch_inst *_si)
+{
+ /* Access scheduler instance private data */
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+ struct mbuf *m;
+ struct dn_queue *q;
+ struct dn_heap *sch = &si->sch_heap;
+ struct dn_heap *neh = &si->ne_heap;
+ struct wf2qp_queue *alg_fq;
+
+ if (sch->elements == 0 && neh->elements == 0) {
+ /* we have nothing to do. We could kill the idle heap
+ * altogether and reset V
+ */
+ idle_check(si, 0x7fffffff, 1);
+ si->V = 0;
+ si->wsum = 0; /* should be set already */
+ return NULL; /* quick return if nothing to do */
+ }
+ idle_check(si, 1, 0); /* drain something from the idle heap */
+
+ /* make sure at least one element is eligible, bumping V
+ * and moving entries that have become eligible.
+ * We need to repeat the first part twice, before and
+ * after extracting the candidate, or enqueue() will
+ * find the data structure in a wrong state.
+ */
+ m = NULL;
+ for(;;) {
+ /*
+ * Compute V = max(V, min(S_i)). Remember that all elements
+ * in sch have by definition S_i <= V so if sch is not empty,
+ * V is surely the max and we must not update it. Conversely,
+ * if sch is empty we only need to look at neh.
+ * We don't need to move the queues, as it will be done at the
+ * next enqueue
+ */
+ if (sch->elements == 0 && neh->elements > 0) {
+ si->V = MAX64(si->V, HEAP_TOP(neh)->key);
+ }
+ while (neh->elements > 0 &&
+ DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) {
+ q = HEAP_TOP(neh)->object;
+ alg_fq = (struct wf2qp_queue *)q;
+ heap_extract(neh, NULL);
+ heap_insert(sch, alg_fq->F, q);
+ }
+ if (m) /* pkt found in previous iteration */
+ break;
+ /* ok we have at least one eligible pkt */
+ q = HEAP_TOP(sch)->object;
+ alg_fq = (struct wf2qp_queue *)q;
+ m = dn_dequeue(q);
+ heap_extract(sch, NULL); /* Remove queue from heap. */
+ si->V += (uint64_t)(m->m_pkthdr.len) * si->inv_wsum;
+ alg_fq->S = alg_fq->F; /* Update start time. */
+ if (q->mq.head == 0) { /* not backlogged any more. */
+ heap_insert(&si->idle_heap, alg_fq->F, q);
+ } else { /* Still backlogged. */
+ /* Update F, store in neh or sch */
+ uint64_t len = q->mq.head->m_pkthdr.len;
+ alg_fq->F += len * alg_fq->inv_w;
+ if (DN_KEY_LEQ(alg_fq->S, si->V)) {
+ heap_insert(sch, alg_fq->F, q);
+ } else {
+ heap_insert(neh, alg_fq->S, q);
+ }
+ }
+ }
+ return m;
+}
+
+static int
+wf2qp_new_sched(struct dn_sch_inst *_si)
+{
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+ int ofs = offsetof(struct wf2qp_queue, heap_pos);
+
+ /* all heaps support extract from middle */
+ if (heap_init(&si->idle_heap, 16, ofs) ||
+ heap_init(&si->sch_heap, 16, ofs) ||
+ heap_init(&si->ne_heap, 16, ofs)) {
+ heap_free(&si->ne_heap);
+ heap_free(&si->sch_heap);
+ heap_free(&si->idle_heap);
+ return ENOMEM;
+ }
+ return 0;
+}
+
+static int
+wf2qp_free_sched(struct dn_sch_inst *_si)
+{
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+
+ heap_free(&si->sch_heap);
+ heap_free(&si->ne_heap);
+ heap_free(&si->idle_heap);
+
+ return 0;
+}
+
+static int
+wf2qp_new_fsk(struct dn_fsk *fs)
+{
+ ipdn_bound_var(&fs->fs.par[0], 1,
+ 1, 100, "WF2Q+ weight");
+ return 0;
+}
+
+static int
+wf2qp_new_queue(struct dn_queue *_q)
+{
+ struct wf2qp_queue *q = (struct wf2qp_queue *)_q;
+
+ _q->ni.oid.subtype = DN_SCHED_WF2QP;
+ q->F = 0; /* not strictly necessary */
+ q->S = q->F + 1; /* mark timestamp as invalid. */
+ q->inv_w = ONE_FP / _q->fs->fs.par[0];
+ if (_q->mq.head != NULL) {
+ wf2qp_enqueue(_q->_si, _q, _q->mq.head);
+ }
+ return 0;
+}
+
+/*
+ * Called when the infrastructure removes a queue (e.g. flowset
+ * is reconfigured). Nothing to do if we did not 'own' the queue,
+ * otherwise remove it from the right heap and adjust the sum
+ * of weights.
+ */
+static int
+wf2qp_free_queue(struct dn_queue *q)
+{
+ struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
+ struct wf2qp_si *si = (struct wf2qp_si *)(q->_si + 1);
+
+ if (alg_fq->S >= alg_fq->F + 1)
+ return 0; /* nothing to do, not in any heap */
+ si->wsum -= q->fs->fs.par[0];
+ if (si->wsum > 0)
+ si->inv_wsum = ONE_FP/si->wsum;
+
+ /* extract from the heap. XXX TODO we may need to adjust V
+ * to make sure the invariants hold.
+ */
+ if (q->mq.head == NULL) {
+ heap_extract(&si->idle_heap, q);
+ } else if (DN_KEY_LT(si->V, alg_fq->S)) {
+ heap_extract(&si->ne_heap, q);
+ } else {
+ heap_extract(&si->sch_heap, q);
+ }
+ return 0;
+}
+
+/*
+ * WF2Q+ scheduler descriptor
+ * contains the type of the scheduler, the name, the size of the
+ * structures and function pointers.
+ */
+static struct dn_alg wf2qp_desc = {
+ _SI( .type = ) DN_SCHED_WF2QP,
+ _SI( .name = ) "WF2Q+",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ /* we need extra space in the si and the queue */
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct wf2qp_si),
+ _SI( .q_datalen = ) sizeof(struct wf2qp_queue) -
+ sizeof(struct dn_queue),
+
+ _SI( .enqueue = ) wf2qp_enqueue,
+ _SI( .dequeue = ) wf2qp_dequeue,
+
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) wf2qp_new_sched,
+ _SI( .free_sched = ) wf2qp_free_sched,
+
+ _SI( .new_fsk = ) wf2qp_new_fsk,
+ _SI( .free_fsk = ) NULL,
+
+ _SI( .new_queue = ) wf2qp_new_queue,
+ _SI( .free_queue = ) wf2qp_free_queue,
+};
+
+
+DECLARE_DNSCHED_MODULE(dn_wf2qp, &wf2qp_desc);
diff --git a/sys/netinet/ipfw/dummynet.txt b/sys/netinet/ipfw/dummynet.txt
new file mode 100644
index 0000000..0ed6ad1
--- /dev/null
+++ b/sys/netinet/ipfw/dummynet.txt
@@ -0,0 +1,860 @@
+#
+# $FreeBSD$
+#
+
+Notes on the internal structure of dummynet (2010 version)
+by Riccardo Panicucci and Luigi Rizzo
+Work supported by the EC project ONELAB2
+
+
+*********
+* INDEX *
+*********
+Implementation of new dummynet
+ Internal structure
+ Files
+Packet arrival
+ The reconfiguration routine
+dummynet_task()
+Configuration
+ Add a pipe
+ Add a scheduler
+ Add a flowset
+Listing object
+Delete of object
+ Delete a pipe
+ Delete a flowset
+ Delete a scheduler
+Compatibility with FreeBSD7.2 and FreeBSD 8 ipfw binary
+ ip_dummynet_glue.c
+ ip_fw_glue.c
+How to configure dummynet
+How to implement a new scheduler
+
+
+
+OPEN ISSUES
+------------------------------
+20100131 deleting RR causes infinite loop
+ presumably in the rr_free_queue() call -- seems to hang
+ forever when deleting a live flow
+------------------------------
+
+Dummynet is a traffic shaper and network emulator. Packets are
+selected by an external filter such as ipfw, and passed to the emulator
+with a tag such as "pipe 10" or "queue 5" which tells what to
+do with the packet. As an example
+
+ ipfw add queue 5 icmp from 10.0.0.2 to all
+
+All packets with the same tag belong to a "flowset", or a set
+of flows which can be further partitioned according to a mask.
+Flowsets are then passed to a scheduler for processing. The
+association of flowsets and schedulers is configurable e.g.
+
+ ipfw queue 5 config sched 10 weight 3 flow_mask xxxx
+ ipfw queue 8 config sched 10 weight 1 ...
+ ipfw queue 3 config sched 20 weight 1 ...
+
+"sched 10" represents one or more scheduler instances,
+selected through a mask on the 5-tuple itself.
+
+ ipfw sched 20 config type FIFO sched_mask yyy ...
+
+There are in fact two masks applied to each packet:
++ the "sched_mask" sends packets arriving to a scheduler_id to
+ one of many instances.
++ the "flow_mask" together with the flowset_id is used to
+ collect packets into independent flows on each scheduler.
+
+As an example, we can have
+ ipfw queue 5 config sched 10 flow_mask src-ip 0x000000ff
+ ipfw sched 10 config type WF2Q+ sched_mask src-ip 0xffffff00
+
+means that sched 10 will have one instance per /24 source subnet,
+and within that, each individual source will be a flow.
+
+Internal structure
+-----------------
+Dummynet-related data is split into several data structures,
+part of them constituting the userland-kernel API, and others
+specific to the kernel.
+NOTE: for up-to-date details please look at the relevant source
+ headers (ip_dummynet.h, ip_dn_private.h, dn_sched.h)
+
+USERLAND-KERNEL API (ip_dummynet.h)
+
+ struct dn_link:
+ contains data about the physical link such as
+ bandwith, delay, burst size;
+
+ struct dn_fs:
+ describes a flowset, i.e. a template for queues.
+ Main parameters are the scheduler we attach to, a flow_mask,
+ buckets, queue size, plr, weight, and other scheduler-specific
+ parameters.
+
+ struct dn_flow
+ contains information on a flow, including masks and
+ statistics
+
+ struct dn_sch:
+ defines a scheduler (and a link attached to it).
+ Parameters include scheduler type, sched_mask, number of
+ buckets, and possibly other scheduler-specific parameters,
+
+ struct dn_profile:
+ fields to simulate a delay profile
+
+
+KERNEL REPRESENTATION (ip_dn_private.h)
+
+ struct mq
+ a queue of mbufs with head and tail.
+
+ struct dn_queue
+ individual queue of packets, created by a flowset using
+ flow_mask and attached to a scheduler instance selected
+ through sched_mask.
+ A dn_queue has a pointer to the dn_fsk (which in turn counts
+ how many queues point to it), a pointer to the
+ dn_sch_inst it attaches to, and is in a hash table in the
+ flowset. scheduler instances also should store queues in
+ their own containers used for scheduling (lists, trees, etc.)
+ CREATE: done on packet arrivals when a flow matches a flowset.
+ DELETE: done only when deleting the parent dn_sch_inst
+ or draining memory.
+
+ struct dn_fsk
+ includes a dn_fs; a pointer to the dn_schk; a link field
+ for the list of dn_fsk attached to the same scheduler,
+ or for the unlinked list;
+ a refcount for the number of queues pointing to it;
+ The dn_fsk is in a hash table, fshash.
+ CREATE: done on configuration commands.
+ DELETE: on configuration commands.
+
+ struct dn_sch_inst
+ a scheduler instance, created from a dn_schk applying sched_mask.
+ Contains a delay line, a reference to the parent, and scheduler-
+ specific info. Both dn_sch_inst and its delay line can be in the
+ evheap if they have events to be processed.
+ CREATE: created from a dn_schk applying sched_mask
+ DELETE: configuration command delete a scheduler which in turn
+ sweeps the hash table of instances deleting them
+
+ struct dn_schk
+ includes dn_sch, dn_link, a pointer to dn_profile,
+ a hash table of dn_sch_inst, a list of dn_fsk
+ attached to it.
+ CREATE: configuration command. If there are flowsets that
+ refer to this number, they are attached and moved
+ to the hash table
+ DELETE: manual, see dn_sch_inst
+
+
+ fshash schedhash
+ +---------------+ sched +--------------+
+ | sched-------------------->| NEW_SCHK|
+ -<----*sch_chain |<-----------------*fsk_list |
+ |NEW_FSK |<----. | [dn_link] |
+ +---------------+ | +--------------+
+ |qht (hash) | | | siht(hash) |
+ | [dn_queue] | | | [dn_si] |
+ | [dn_queue] | | | [dn_si] |
+ | ... | | | ... |
+ | +--------+ | | | +---------+ |
+ | |dn_queue| | | | |dn_si | |
+ | | fs *----------' | | | |
+ | | si *---------------------->| | |
+ | +---------+ | | +---------+ |
+ +---------------+ +--------------+
+
+The following global data structures contain all
+schedulers and flowsets.
+
+- schedhash[x]: contains all scheduler templates in the system.
+ Looked up only on manual configurations, where flowsets
+ are attached to matching schedulers.
+ We have one entry per 'sched X config' command
+ (plus one for each 'pipe X config').
+
+- fshash[x]: contains all flowsets.
+ We do a lookup on this for each packet.
+ We have one entry for each 'queue X config'
+ (plus one for each 'pipe X config').
+
+Additionally, a list that contains all unlinked flowset:
+- fsu: contains flowset that are not linked with any scheduler.
+ Flowset are put in this list when they refer to a non
+ existing scheduler.
+ We don't need an efficient data structure as we never search
+ here on a packet arrivals.
+
+Scheduler instances and the delay lines associated with each scheduler
+instance need to be woken up at certain times. Because we have many
+such objects, we keep them in a priority heap (system_heap).
+
+Almost all objects in this implementation are preceded by a structure
+(struct dn_id) which makes it easier to identify them.
+
+
+Files
+-----
+The dummynet code is split in several files.
+All kernel code is in sys/netinet/ipfw except ip_dummynet.h
+All userland code is in sbin/ipfw.
+Files are
+- sys/netinet/ip_dummynet.h defines the kernel-userland API
+- ip_dn_private.h contains the kernel-specific APIs
+ and data structures
+- dn_sched.h defines the scheduler API
+- ip_dummynet.c cointains module glue and sockopt handlers, with all
+ functions to configure and list objects.
+- ip_dn_io.c contains the functions directly related to packet processing,
+ and run in the critical path. It also contains some functions
+ exported to the schedulers.
+- dn_heap.[ch] implement a binary heap and a generic hash table
+- dn_sched_* implement the various scheduler modules
+
+- dummynet.c is the file used to implement the user side of dummynet.
+ It contains the function to parsing command line, and functions to
+ show the output of dummynet objects.
+Moreover, there are two new file (ip_dummynet_glue.c and ip_fw_glue.c) that
+are used to allow compatibility with the "ipfw" binary from FreeBSD 7.2 and
+FreeBSD 8.
+
+LOCKING
+=======
+At the moment the entire processing occurs under a single lock
+which is expected to be acquired in exclusive mode
+DN_BH_WLOCK() / DN_BH_WUNLOCK().
+
+In perspective we aim at the following:
+- the 'busy' flag, 'pending' list and all structures modified by packet
+ arrivals and departures are protected by the BH_WLOCK.
+ This is normally acquired in exclusive mode by the packet processing
+ functions for short sections of code (exception -- the timer).
+ If 'busy' is not set, we can do regular packet processing.
+ If 'busy' is set, no pieces can be accessed.
+ We must enqueue the packet on 'pending' and return immediately.
+
+- the 'busy' flag is set/cleared by long sections of code as follows:
+ UH_WLOCK(); KASSERT(busy == 0);
+ BH_WLOCK(); busy=1; BH_WUNLOCK();
+ ... do processing ...
+ BH_WLOCK(); busy=0; drain_queue(pending); BH_WUNLOCK();
+ UH_WUNLOCK();
+ this normally happens when the upper half has something heavy
+ to do. The prologue and epilogue are not in the critical path.
+
+- the main containers (fshash, schedhash, ...) are protected by
+ UH_WLOCK.
+
+Packet processing
+=================
+A packet enters dummynet through dummynet_io(). We first lookup
+the flowset number in fshash using dn_ht_find(), then find the scheduler
+instance using ipdn_si_find(), then possibly identify the correct
+queue with ipdn_q_find().
+If successful, we call the scheduler's enqueue function(), and
+if needed start I/O on the link calling serve_sched().
+If the packet can be returned immediately, this is done by
+leaving *m0 set. Otherwise, the packet is absorbed by dummynet
+and we simply return, possibly with some appropriate error code.
+
+Reconfiguration
+---------------
+Reconfiguration is the complex part of the system because we need to
+keep track of the various objects and containers.
+At the moment we do not use reference counts for objects so all
+processing must be done under a lock.
+
+The main entry points for configuration is the ip_dn_ctl() handler
+for the IP_DUMMYNET3 sockopt (others are provided only for backward
+compatibility). Modifications to the configuration call do_config().
+The argument is a sequence of blocks each starting with a struct dn_id
+which specifies its content.
+The first dn_id must contain as obj.id the DN_API_VERSION
+The obj.type is DN_CMD_CONFIG (followed by actual objects),
+DN_CMD_DELETE (with the correct subtype and list of objects), or
+DN_CMD_FLUSH.
+
+DN_CMD_CONFIG is followed by objects to add/reconfigure. In general,
+if an object already exists it is reconfigured, otherwise it is
+created in a way that keeps the structure consistent.
+We have the following objects in the system, normally numbered with
+an identifier N between 1 and 65535. For certain objects we have
+"shadow" copies numbered I+NMAX and I+ 2*NMAX which are used to
+implement certain backward compatibility features.
+
+In general we have the following linking
+
+ TRADITIONAL DUMMYNET QUEUES "queue N config ... pipe M ..."
+ corresponds to a dn_fs object numbered N
+
+ TRADITIONAL DUMMYNET PIPES "pipe N config ..."
+ dn_fs N+2*NMAX --> dn_sch N+NMAX type FIFO --> dn_link N+NMAX
+
+ GENERIC SCHEDULER "sched N config ... "
+ [dn_fs N+NMAX] --> dn_sch N --> dn_link N
+ The flowset N+NMAX is created only if the scheduler is not
+ of type MULTIQUEUE.
+
+ DELAY PROFILE "pipe N config profile ..."
+ it is always attached to an existing dn_link N
+
+Because traditional dummynet pipes actually configure both a
+'standalone' instance and one that can be used by queues,
+we do the following:
+
+ "pipe N config ..." configures:
+ dn_sched N type WF2Q+
+ dn_sched N+NMAX type FIFO
+ dn_fs N+2NMAX attached to dn_sched N+NMAX
+ dn_pipe N
+ dn_pipe N+NMAX
+
+ "queue N config" configures
+ dn_fs N
+
+ "sched N config" configures
+ dn_sched N type as desired
+ dn_fs N+NMAX attached to dn_sched N
+
+
+dummynet_task()
+===============
+The dummynet_task() is the the main dummynet processing function and is
+called every tick. This function first calculate the new current time, then
+it checks if it is the time to wake up object from the system_heap comparing
+the current time and the key of the heap. Two types of object (really the
+heap contains pointer to objects) are in the
+system_heap:
+
+- scheduler instance: if a scheduler instance is waked up, the dequeue()
+ function is called until it has credit. If the dequeue() returns packets,
+ the scheduler instance is inserted in the heap with a new key depending of
+ the data that will be send out. If the scheduler instance remains with
+ some credit, it means that is hasn't other packet to send and so the
+ instance is no longer inserted in the heap.
+
+ If the scheduler instance extracted from the heap has the DELETE flag set,
+ the dequeue() is not called and the instance is destroyed now.
+
+- delay line: when extracting a delay line, the function transmit_event() is
+ called to send out packet from delay line.
+
+ If the scheduler instance associated with this delay line doesn't exists,
+ the delay line will be delete now.
+
+Configuration
+=============
+To create a pipe, queue or scheduler, the user should type commands like:
+"ipfw pipe x config"
+"ipfw queue y config pipe x"
+"ipfw pipe x config sched <type>"
+
+The userland side of dummynet will prepare a buffer contains data to pass to
+kernel side.
+The buffer contains all struct needed to configure an object. In more detail,
+to configure a pipe all three structs (dn_link, dn_sch, dn_fs) are needed,
+plus the delay profile struct if the pipe has a delay profile.
+
+If configuring a scheduler only the struct dn_sch is wrote in the buffer,
+while if configuring a flowset only the dn_fs struct is wrote.
+
+The first struct in the buffer contains the type of command request, that is
+if it is configuring a pipe, a queue, or a scheduler. Then there are structs
+need to configure the object, and finally there is the struct that mark
+the end of the buffer.
+
+To support the insertion of pipe and queue using the old syntax, when adding
+a pipe it's necessary to create a FIFO flowset and a FIFO scheduler, which
+have a number x + DN_PIPEOFFSET.
+
+Add a pipe
+----------
+A pipe is only a template for a link.
+If the pipe already exists, parameters are updated. If a delay profile exists
+it is deleted and a new one is created.
+If the pipe doesn't exist a new one is created. After the creation, the
+flowset unlinked list is scanned to see if there are some flowset that would
+be linked with this pipe. If so, these flowset will be of wf2q+ type (for
+compatibility) and a new wf2q+ scheduler is created now.
+
+Add a scheduler
+---------------
+If the scheduler already exists, and the type and the mask are the same, the
+scheduler is simply reconfigured calling the config_scheduler() scheduler
+function with the RECONFIGURE flag active.
+If the type or the mask differ, it is necessary to delete the old scheduler
+and create a new one.
+If the scheduler doesn't exists, a new one is created. If the scheduler has
+a mask, the hash table is created to store pointers to scheduler instances.
+When a new scheduler is created, it is necessary to scan the unlinked
+flowset list to search eventually flowset that would be linked with this
+scheduler number. If some are found, flowsets became of the type of this
+scheduler and they are configured properly.
+
+Add a flowset
+-------------
+Flowset pointers are store in the system in two list. The unlinked flowset list
+contains all flowset that aren't linked with a scheduler, the flowset list
+contains flowset linked to a scheduler, and so they have a type.
+When adding a new flowset, first it is checked if the flowset exists (that is,
+it is in the flowset list) and if it doesn't exists a new flowset is created
+and added to unlinked flowset list if the scheduler which the flowset would be
+linked doesn't exists, or added in the flowset list and configured properly if
+the scheduler exists. If the flowset (before to be created) was in the
+unlinked flowset list, it is removed and deleted, and then recreated.
+If the flowset exists, to allow reconfiguration of this flowset, the
+scheduler number and types must match with the one in memory. If this isn't
+so, the flowset is deleted and a new one will be created. Really, the flowset
+it isn't deleted now, but it is removed from flowset list and it will be
+deleted later because there could be some queues that are using it.
+
+Listing of object
+=================
+The user can request a list of object present in dummynet through the command
+"ipfw [-v] pipe|queue [x] list|show"
+The kernel side of dummynet send a buffer to user side that contains all
+pipe, all scheduler, all flowset, plus all scheduler instances and all queues.
+The dummynet user land will format the output and show only the relevant
+information.
+The buffer sent start with all pipe from the system. The entire struct dn_link
+is passed, except the delay_profile struct that is useless in user space.
+After pipes, all flowset are wrote in the buffer. The struct contains
+scheduler flowset specific data is linked with the flowset writing the
+'obj' id of the extension into the 'alg_fs' pointer.
+Then schedulers are wrote. If a scheduler has one or more scheduler instance,
+these are linked to the parent scheduler writing the id of the parent in the
+'ptr_sched' pointer. If a scheduler instance has queues, there are wrote in
+the buffer and linked thorugh the 'obj' and 'sched_inst' pointer.
+Finally, flowsets in the unlinked flowset list are write in the buffer, and
+then a struct gen in saved in the buffer to mark the last struct in the buffer.
+
+
+Delete of object
+================
+An object is usually removed by user through a command like
+"ipfw pipe|queue x delete". XXX sched?
+ipfw pass to the kernel a struct gen that contains the type and the number
+of the object to remove
+
+Delete of pipe x
+----------------
+A pipe can be deleted by the user throught the command 'ipfw pipe x delete'.
+To delete a pipe, the pipe is removed from the pipe list, and then deleted.
+Also the scheduler associated with this pipe should be deleted.
+For compatibility with old dummynet syntax, the associated FIFO scheduler and
+FIFO flowset must be deleted.
+
+Delete of flowset x
+-------------------
+To remove a flowset, we must be sure that is no loger referenced by any object.
+If the flowset to remove is in the unlinked flowset list, there is not any
+issue, the flowset can be safely removed calling a free() (the flowset
+extension is not yet created if the flowset is in this list).
+If the flowset is in the flowset list, first we remove from it so new packet
+are discarded when arrive. Next, the flowset is marked as delete.
+Now we must check if some queue is using this flowset.
+To do this, a counter (active_f) is provided. This counter indicate how many
+queues exist using this flowset.
+The active_f counter is automatically incremented when a queue is created
+and decremented when a queue is deleted.
+If the counter is 0, the flowset can be safely deleted, and the delete_alg_fs()
+scheduler function is called before deallocate memory.
+If the counter is not 0, the flowset remain in memory until the counter become
+zero. When a queue is delete (by dn_delete_queue() function) it is checked if
+the linked flowset is deleting and if so the counter is decrementing. If the
+counter reaches 0, the flowset is deleted.
+The deletion of a queue can be done only by the scheduler, or when the scheduler
+is destroyed.
+
+Delete of scheduler x
+---------------------
+To delete a scheduler we must be sure that any scheduler instance of this type
+are in the system_heap. To do so, a counter (inst_counter) is provided.
+This counter is managed by the system: it is incremented every time it is
+inserted in the system_heap, and decremented every time it is extracted from it.
+To delete the scheduler, first we remove it from the scheduler list, so new
+packet are discarded when they arrive, and mark the scheduler as deleting.
+
+If the counter is 0, we can remove the scheduler safely calling the
+really_deletescheduler() function. This function will scan all scheduler
+instances and call the delete_scheduler_instance() function that will delete
+the instance. When all instance are deleted, the scheduler template is
+deleted calling the delete_scheduler_template(). If the delay line associate
+with the scheduler is empty, it is deleted now, else it will be deleted when
+it will became empy.
+If the counter was not 0, we wait for it. Every time the dummynet_task()
+function extract a scheduler from the system_heap, the counter is decremented.
+If the scheduler has the delete flag enabled the dequeue() is not called and
+delete_scheduler_instance() is called to delete the instance.
+Obviously this scheduler instance is no loger inserted in the system_heap.
+If the counter reaches 0, the delete_scheduler_template() function is called
+all memory is released.
+NOTE: Flowsets that belong to this scheduler are not deleted, so if a new
+ scheduler with the same number is inserted will use these flowsets.
+ To do so, the best approach would be insert these flowset in the
+ unlinked flowset list, but doing this now will be very expensive.
+ So flowsets will remain in memory and linked with a scheduler that no
+ longer exists until a packet belonging to this flowset arrives. When
+ this packet arrives, the reconfigure() function is called because the
+ generation number mismatch with one contains in the flowset and so
+ the flowset will be moved into the flowset unlinked list, or will be
+ linked with the new scheduler if a new one was created.
+
+
+COMPATIBILITY WITH FREEBSD 7.2 AND FREEBSD 8 'IPFW' BINARY
+==========================================================
+Dummynet is not compatible with old ipfw binary because internal structs are
+changed. Moreover, the old ipfw binary is not compatible with new kernels
+because the struct that represents a firewall rule has changed. So, if a user
+install a new kernel on a FreeBSD 7.2, the ipfw (and possibly many other
+commands) will not work.
+New dummynet uses a new socket option: IP_DUMMYNET3, used for both set and get.
+The old option can be used to allow compatibility with the 'ipfw' binary of
+older version (tested with 7.2 and 8.0) of FreeBSD.
+Two file are provided for this purpose:
+- ip_dummynet_glue.c translates old dummynet requests to the new ones,
+- ip_fw_glue.c converts the rule format between 7.2 and 8 versions.
+Let see in detail these two files.
+
+IP_DUMMYNET_GLUE.C
+------------------
+The internal structs of new dummynet are very different from the original.
+Because of there are some difference from between dummynet in FreeBSD 7.2 and
+dummynet in FreeBSD 8 (the FreeBSD 8 version includes support to pipe delay
+profile and burst option), I have to include both header files. I copied
+the revision 191715 (for version 7.2) and the revision 196045 (for version 8)
+and I appended a number to each struct to mark them.
+
+The main function of this file is ip_dummynet_compat() that is called by
+ip_dn_ctl() when it receive a request of old socket option.
+
+A global variabile ('is7') store the version of 'ipfw' that FreeBSD is using.
+This variable is set every time a request of configuration is done, because
+with this request we receive a buffer of which size depending of ipfw version.
+Because of in general the first action is a configuration, this variable is
+usually set accordly. If the first action is a request of listing of pipes
+or queues, the system cannot know the version of ipfw, and we suppose that
+version 7.2 is used. If version is wrong, the output can be senseless, but
+the application should not crash.
+
+There are four request for old dummynet:
+- IP_DUMMYNET_FLUSH: the flush options have no parameter, so simply the
+ dummynet_flush() function is called;
+- IP_DUMMYNET_DEL: the delete option need to be translate.
+ It is only necessary to extract the number and the type of the object
+ (pipe or queue) to delete from the buffer received and build a new struct
+ gen contains the right parameters, then call the delete_object() function;
+- IP_DUMMYNET_CONFIGURE: the configure command receive a buffer depending of
+ the ipfw version. After the properly extraction of all data, that depends
+ by the ipfw version used, new structures are filled and then the dummynet
+ config_link() function is properly called. Note that the 7.2 version does
+ not support some parameter as burst or delay profile.
+- IP_DUMMYNET_GET: The get command should send to the ipfw the correct buffer
+ depending of its version. There are two function that build the
+ corrected buffer, ip_dummynet_get7() and ip_dummynet_get8(). These
+ functions reproduce the buffer exactly as 'ipfw' expect. The only difference
+ is that the weight parameter for a queue is no loger sent by dummynet and so
+ it is set to 0.
+ Moreover, because of the internal structure has changed, the bucket size
+ of a queue could not be correct, because now all flowset share the hash
+ table.
+ If the version of ipfw is wrong, the output could be senseless or truncated,
+ but the application should not crash.
+
+IP_FW_GLUE.C
+------------
+The ipfw binary also is used to add rules to FreeBSD firewall. Because of the
+struct ip_fw is changed from FreeBsd 7.2 to FreeBSD 8, it is necessary
+to write some glue code to allow use ipfw from FreeBSD 7.2 with the kernel
+provided with FreeBSD 8.
+This file contains two functions to convert a rule from FreeBSD 7.2 format to
+FreeBSD 8 format, and viceversa.
+The conversion should be done when a rule passes from userspace to kernel space
+and viceversa.
+I have to modify the ip_fw2.c file to manage these two case, and added a
+variable (is7) to store the ipfw version used, using an approach like the
+previous file:
+- when a new rule is added (option IP_FW_ADD) the is7 variable is set if the
+ size of the rule received corrispond to FreeBSD 7.2 ipfw version. If so, the
+ rule is converted to version 8 calling the function convert_rule_to_8().
+ Moreover, after the insertion of the rule, the rule is now reconverted to
+ version 7 because the ipfw binary will print it.
+- when the user request a list of rules (option IP_FW_GET) the is7 variable
+ should be set correctly because we suppose that a configure command was done,
+ else we suppose that the FreeBSD version is 8. The function ipfw_getrules()
+ in ip_fw2.c file return all rules, eventually converted to version 7 (if
+ the is7 is set) to the ipfw binary.
+The conversion of a rule is quite simple. The only difference between the
+two structures (struct ip_fw) is that in the new there is a new field
+(uint32_t id). So, I copy the entire rule in a buffer and the copy the rule in
+the right position in the new (or old) struct. The size of commands are not
+changed, and the copy is done into a cicle.
+
+How to configure dummynet
+=========================
+It is possible to configure dummynet through two main commands:
+'ipfw pipe' and 'ipfw queue'.
+To allow compatibility with old version, it is possible configure dummynet
+using the old command syntax. Doing so, obviously, it is only possible to
+configure a FIFO scheduler or a wf2q+ scheduler.
+A new command, 'ipfw pipe x config sched <type>' is supported to add a new
+scheduler to the system.
+
+- ipfw pipe x config ...
+ create a new pipe with the link parameters
+ create a new scheduler fifo (x + offset)
+ create a new flowset fifo (x + offset)
+ the mask is eventually stored in the FIFO scheduler
+
+- ipfw queue y config pipe x ...
+ create a new flowset y linked to sched x.
+ The type of flowset depends by the specified scheduler.
+ If the scheduler does not exist, this flowset is inserted in a special
+ list and will be not active.
+ If pipe x exists and sched does not exist, a new wf2q+ scheduler is
+ created and the flowset will be linked to this new scheduler (this is
+ done for compatibility with old syntax).
+
+- ipfw pipe x config sched <type> ...
+ create a new scheduler x of type <type>.
+ Search into the flowset unlinked list if there are some flowset that
+ should be linked with this new scheduler.
+
+- ipfw pipe x delete
+ delete the pipe x
+ delete the scheduler fifo (x + offset)
+ delete the scheduler x
+ delete the flowset fifo (x + offset)
+
+- ipfw queue x delete
+ delete the flowset x
+
+- ipfw sched x delete ///XXX
+ delete the scheduler x
+
+Follow now some examples to how configure dummynet:
+- Ex1:
+ ipfw pipe 10 config bw 1M delay 15 // create a pipe with band and delay
+ A FIFO flowset and scheduler is
+ also created
+ ipfw queue 5 config pipe 10 weight 56 // create a flowset. This flowset
+ will be of wf2q+ because a pipe 10
+ exists. Moreover, the wf2q+
+ scheduler is created now.
+- Ex2:
+ ipfw queue 5 config pipe 10 weight 56 // Create a flowset. Scheduler 10
+ does not exist, so this flowset
+ is inserted in the unlinked
+ flowset list.
+ ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
+ Because of a flowset with 'pipe 10' exists,
+ a wf2q+ scheduler is created now and that
+ flowset is linked with this sceduler.
+
+- Ex3:
+ ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
+ ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
+ pipe 10
+ ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5. This flowset
+ will belong to scheduler 10 and
+ it is of type RR
+
+- Ex4:
+ ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
+ pipe 10 (not exist yet)
+ ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
+ ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5.This flowset
+ will belong to scheduler 10 and
+ it is of type RR
+ ipfw pipe 10 config sched wf2q+ // Modify the type of scheduler 10. It
+ becomes a wf2q+ scheduler.
+ When a new packet of flowset 5 arrives,
+ the flowset 5 becomes to wf2q+ type.
+
+How to implement a new scheduler
+================================
+In dummynet, a scheduler algorithm is represented by two main structs, some
+functions and other minor structs.
+- A struct dn_sch_xyz (where xyz is the 'type' of scheduler algorithm
+ implemented) contains data relative to scheduler, as global parameter that
+ are common to all instances of the scheduler
+- A struct dn_sch_inst_xyz contains data relative to a single scheduler
+ instance, as local status variable depending for example by flows that
+ are linked with the scheduler, and so on.
+To add a scheduler to dummynet, the user should type a command like:
+'ipfw pipe x config sched <type> [mask ... ...]'
+This command creates a new struct dn_sch_xyz of type <type>, and
+store the optional parameter in that struct.
+
+The parameter mask determines how many scheduler instance of this
+scheduler may exist. For example, it is possible to divide traffic
+depending on the source port (or destination, or ip address...),
+so that every scheduler instance act as an independent scheduler.
+If the mask is not set, all traffic goes to the same instance.
+
+When a packet arrives to a scheduler, the system search the corrected
+scheduler instance, and if it does not exist it is created now (the
+struct dn_sch_inst_xyz is allocated by the system, and the scheduler
+fills the field correctly). It is a task of the scheduler to create
+the struct that contains all queues for a scheduler instance.
+Dummynet provides some function to create an hash table to store
+queues, but the schedule algorithm can choice the own struct.
+
+To link a flow to a scheduler, the user should type a command like:
+'ipfw queue z config pipe x [mask... ...]'
+
+This command creates a new 'dn_fs' struct that will be inserted
+in the system. If the scheduler x exists, this flowset will be
+linked to that scheduler and the flowset type become the same as
+the scheduler type. At this point, the function create_alg_fs_xyz()
+is called to allow store eventually parameter for the flowset that
+depend by scheduler (for example the 'weight' parameter for a wf2q+
+scheduler, or some priority...). A parameter mask can be used for
+a flowset. If the mask parameter is set, the scheduler instance can
+separate packet according to its flow id (src and dst ip, ports...)
+and assign it to a separate queue. This is done by the scheduler,
+so it can ignore the mask if it wants.
+
+See now the two main structs:
+struct dn_sch_xyz {
+ struct gen g; /* important the name g */
+ /* global params */
+};
+struct dn_sch_inst_xyz {
+ struct gen g; /* important the name g */
+ /* params of the instance */
+};
+It is important to embed the struct gen as first parameter. The struct gen
+contains some values that the scheduler instance must fill (the 'type' of
+scheduler, the 'len' of the struct...)
+The function create_scheduler_xyz() should be implemented to initialize global
+parameters in the first struct, and if memory allocation is done it is
+mandatory to implement the delete_scheduler_template() function to free that
+memory.
+The function create_scheduler_instance_xyz() must be implemented even if the
+scheduler instance does not use extra parameters. In this function the struct
+gen fields must be filled with corrected infos. The
+delete_scheduler_instance_xyz() function must bu implemented if the instance
+has allocated some memory in the previous function.
+
+To store data belonging to a flowset the follow struct is used:
+struct alg_fs_xyz {
+ struct gen g;
+ /* fill correctly the gen struct
+ g.subtype = DN_XYZ;
+ g.len = sizeof(struct alg_fs_xyz)
+ ...
+ */
+ /* params for the flow */
+};
+The create_alg_fs_xyz() function is mandatory, because it must fill the struct
+gen, but the delete_alg_fs_xyz() is mandatory only if the previous function
+has allocated some memory.
+
+A struct dn_queue contains packets belonging to a queue and some statistical
+data. The scheduler could have to store data in this struct, so it must define
+a dn_queue_xyz struct:
+struct dn_queue_xyz {
+ struct dn_queue q;
+ /* parameter for a queue */
+}
+
+All structures are allocated by the system. To do so, the scheduler must
+set the size of its structs in the scheduler descriptor:
+scheduler_size: sizeof(dn_sch_xyz)
+scheduler_i_size: sizeof(dn_sch_inst_xyz)
+flowset_size: sizeof(alg_fs_xyz)
+queue_size: sizeof(dn_queue_xyz);
+The scheduler_size could be 0, but other struct must have at least a struct gen.
+
+
+After the definition of structs, it is necessary to implement the
+scheduler functions.
+
+- int (*config_scheduler)(char *command, void *sch, int reconfigure);
+ Configure a scheduler, or reconfigure if 'reconfigure' == 1.
+ This function performs additional allocation and initialization of global
+ parameter for this scheduler.
+ If memory is allocated here, the delete_scheduler_template() function
+ should be implemented to remove this memory.
+- int (*delete_scheduler_template)(void* sch);
+ Delete a scheduler template. This function is mandatory if the scheduler
+ uses extra data respect the struct dn_sch.
+- int (*create_scheduler_instance)(void *s);
+ Create a new scheduler instance. The system allocate the necessary memory
+ and the schedulet can access it using the 's' pointer.
+ The scheduler instance stores all queues, and to do this can use the
+ hash table provided by the system.
+- int (*delete_scheduler_instance)(void *s);
+ Delete a scheduler instance. It is important to free memory allocated
+ by create_scheduler_instance() function. The memory allocated by system
+ is freed by the system itself. The struct contains all queue also has
+ to be deleted.
+- int (*enqueue)(void *s, struct gen *f, struct mbuf *m,
+ struct ipfw_flow_id *id);
+ Called when a packet arrives. The packet 'm' belongs to the scheduler
+ instance 's', has a flowset 'f' and the flowid 'id' has already been
+ masked. The enqueue() must call dn_queue_packet(q, m) function to really
+ enqueue packet in the queue q. The queue 'q' is chosen by the scheduler
+ and if it does not exist should be created calling the dn_create_queue()
+ function. If the schedule want to drop the packet, it must call the
+ dn_drop_packet() function and then return 1.
+- struct mbuf * (*dequeue)(void *s);
+ Called when the timer expires (or when a packet arrives and the scheduler
+ instance is idle).
+ This function is called when at least a packet can be send out. The
+ scheduler choices the packet and returns it; if no packet are in the
+ schedulerinstance, the function must return NULL.
+ Before return a packet, it is important to call the function
+ dn_return_packet() to update some statistic of the queue and update the
+ queue counters.
+- int (*drain_queue)(void *s, int flag);
+ The system request to scheduler to delete all queues that is not using
+ to free memory. The flag parameter indicate if a queue must be deleted
+ even if it is active.
+
+- int (*create_alg_fs)(char *command, struct gen *g, int reconfigure);
+ It is called when a flowset is linked with a scheduler. This is done
+ when the scheduler is defined, so we can know the type of flowset.
+ The function initialize the flowset paramenter parsing the command
+ line. The parameter will be stored in the g struct that have the right
+ size allocated by the system. If the reconfigure flag is set, it means
+ that the flowset is reconfiguring
+- int (*delete_alg_fs)(struct gen *f);
+ It is called when a flowset is deleting. Must remove the memory allocate
+ by the create_alg_fs() function.
+
+- int (*create_queue_alg)(struct dn_queue *q, struct gen *f);
+ Called when a queue is created. The function should link the queue
+ to the struct used by the scheduler instance to store all queues.
+- int (*delete_queue_alg)(struct dn_queue *q);
+ Called when a queue is deleting. The function should remove extra data
+ and update the struct contains all queues in the scheduler instance.
+
+The struct scheduler represent the scheduler descriptor that is passed to
+dummynet when a scheduler module is loaded.
+This struct contains the type of scheduler, the lenght of all structs and
+all function pointers.
+If a function is not implemented should be initialize to NULL. Some functions
+are mandatory, other are mandatory if some memory should be freed.
+Mandatory functions:
+- create_scheduler_instance()
+- enqueue()
+- dequeue()
+- create_alg_fs()
+- drain_queue()
+Optional functions:
+- config_scheduler()
+- create_queue_alg()
+Mandatory functions if the corresponding create...() has allocated memory:
+- delete_scheduler_template()
+- delete_scheduler_instance()
+- delete_alg_fs()
+- delete_queue_alg()
+
diff --git a/sys/netinet/ipfw/ip_dn_glue.c b/sys/netinet/ipfw/ip_dn_glue.c
new file mode 100644
index 0000000..a31ec1f
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dn_glue.c
@@ -0,0 +1,845 @@
+/*-
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * 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$
+ *
+ * Binary compatibility support for /sbin/ipfw RELENG_7 and RELENG_8
+ */
+
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/time.h>
+#include <sys/taskqueue.h>
+#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+
+/* FREEBSD7.2 ip_dummynet.h r191715*/
+
+struct dn_heap_entry7 {
+ int64_t key; /* sorting key. Topmost element is smallest one */
+ void *object; /* object pointer */
+};
+
+struct dn_heap7 {
+ int size;
+ int elements;
+ int offset; /* XXX if > 0 this is the offset of direct ptr to obj */
+ struct dn_heap_entry7 *p; /* really an array of "size" entries */
+};
+
+/* Common to 7.2 and 8 */
+struct dn_flow_set {
+ SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */
+
+ u_short fs_nr ; /* flow_set number */
+ u_short flags_fs;
+#define DNOLD_HAVE_FLOW_MASK 0x0001
+#define DNOLD_IS_RED 0x0002
+#define DNOLD_IS_GENTLE_RED 0x0004
+#define DNOLD_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
+#define DNOLD_NOERROR 0x0010 /* do not report ENOBUFS on drops */
+#define DNOLD_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
+#define DNOLD_IS_PIPE 0x4000
+#define DNOLD_IS_QUEUE 0x8000
+
+ struct dn_pipe7 *pipe ; /* pointer to parent pipe */
+ u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */
+
+ int weight ; /* WFQ queue weight */
+ int qsize ; /* queue size in slots or bytes */
+ int plr ; /* pkt loss rate (2^31-1 means 100%) */
+
+ struct ipfw_flow_id flow_mask ;
+
+ /* hash table of queues onto this flow_set */
+ int rq_size ; /* number of slots */
+ int rq_elements ; /* active elements */
+ struct dn_flow_queue7 **rq; /* array of rq_size entries */
+
+ u_int32_t last_expired ; /* do not expire too frequently */
+ int backlogged ; /* #active queues for this flowset */
+
+ /* RED parameters */
+#define SCALE_RED 16
+#define SCALE(x) ( (x) << SCALE_RED )
+#define SCALE_VAL(x) ( (x) >> SCALE_RED )
+#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED )
+ int w_q ; /* queue weight (scaled) */
+ int max_th ; /* maximum threshold for queue (scaled) */
+ int min_th ; /* minimum threshold for queue (scaled) */
+ int max_p ; /* maximum value for p_b (scaled) */
+ u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
+ u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
+ u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
+ u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
+ u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
+ u_int lookup_depth ; /* depth of lookup table */
+ int lookup_step ; /* granularity inside the lookup table */
+ int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
+ int avg_pkt_size ; /* medium packet size */
+ int max_pkt_size ; /* max packet size */
+};
+SLIST_HEAD(dn_flow_set_head, dn_flow_set);
+
+#define DN_IS_PIPE 0x4000
+#define DN_IS_QUEUE 0x8000
+struct dn_flow_queue7 {
+ struct dn_flow_queue7 *next ;
+ struct ipfw_flow_id id ;
+
+ struct mbuf *head, *tail ; /* queue of packets */
+ u_int len ;
+ u_int len_bytes ;
+
+ u_long numbytes;
+
+ u_int64_t tot_pkts ; /* statistics counters */
+ u_int64_t tot_bytes ;
+ u_int32_t drops ;
+
+ int hash_slot ; /* debugging/diagnostic */
+
+ /* RED parameters */
+ int avg ; /* average queue length est. (scaled) */
+ int count ; /* arrivals since last RED drop */
+ int random ; /* random value (scaled) */
+ u_int32_t q_time; /* start of queue idle time */
+
+ /* WF2Q+ support */
+ struct dn_flow_set *fs ; /* parent flow set */
+ int heap_pos ; /* position (index) of struct in heap */
+ int64_t sched_time ; /* current time when queue enters ready_heap */
+
+ int64_t S,F ; /* start time, finish time */
+};
+
+struct dn_pipe7 { /* a pipe */
+ SLIST_ENTRY(dn_pipe7) next; /* linked list in a hash slot */
+
+ int pipe_nr ; /* number */
+ int bandwidth; /* really, bytes/tick. */
+ int delay ; /* really, ticks */
+
+ struct mbuf *head, *tail ; /* packets in delay line */
+
+ /* WF2Q+ */
+ struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
+ struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
+ struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
+
+ int64_t V ; /* virtual time */
+ int sum; /* sum of weights of all active sessions */
+
+ int numbytes;
+
+ int64_t sched_time ; /* time pipe was scheduled in ready_heap */
+
+ /*
+ * When the tx clock come from an interface (if_name[0] != '\0'), its name
+ * is stored below, whereas the ifp is filled when the rule is configured.
+ */
+ char if_name[IFNAMSIZ];
+ struct ifnet *ifp ;
+ int ready ; /* set if ifp != NULL and we got a signal from it */
+
+ struct dn_flow_set fs ; /* used with fixed-rate flows */
+};
+SLIST_HEAD(dn_pipe_head7, dn_pipe7);
+
+
+/* FREEBSD8 ip_dummynet.h r196045 */
+struct dn_flow_queue8 {
+ struct dn_flow_queue8 *next ;
+ struct ipfw_flow_id id ;
+
+ struct mbuf *head, *tail ; /* queue of packets */
+ u_int len ;
+ u_int len_bytes ;
+
+ uint64_t numbytes ; /* credit for transmission (dynamic queues) */
+ int64_t extra_bits; /* extra bits simulating unavailable channel */
+
+ u_int64_t tot_pkts ; /* statistics counters */
+ u_int64_t tot_bytes ;
+ u_int32_t drops ;
+
+ int hash_slot ; /* debugging/diagnostic */
+
+ /* RED parameters */
+ int avg ; /* average queue length est. (scaled) */
+ int count ; /* arrivals since last RED drop */
+ int random ; /* random value (scaled) */
+ int64_t idle_time; /* start of queue idle time */
+
+ /* WF2Q+ support */
+ struct dn_flow_set *fs ; /* parent flow set */
+ int heap_pos ; /* position (index) of struct in heap */
+ int64_t sched_time ; /* current time when queue enters ready_heap */
+
+ int64_t S,F ; /* start time, finish time */
+};
+
+struct dn_pipe8 { /* a pipe */
+ SLIST_ENTRY(dn_pipe8) next; /* linked list in a hash slot */
+
+ int pipe_nr ; /* number */
+ int bandwidth; /* really, bytes/tick. */
+ int delay ; /* really, ticks */
+
+ struct mbuf *head, *tail ; /* packets in delay line */
+
+ /* WF2Q+ */
+ struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
+ struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
+ struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
+
+ int64_t V ; /* virtual time */
+ int sum; /* sum of weights of all active sessions */
+
+ /* Same as in dn_flow_queue, numbytes can become large */
+ int64_t numbytes; /* bits I can transmit (more or less). */
+ uint64_t burst; /* burst size, scaled: bits * hz */
+
+ int64_t sched_time ; /* time pipe was scheduled in ready_heap */
+ int64_t idle_time; /* start of pipe idle time */
+
+ char if_name[IFNAMSIZ];
+ struct ifnet *ifp ;
+ int ready ; /* set if ifp != NULL and we got a signal from it */
+
+ struct dn_flow_set fs ; /* used with fixed-rate flows */
+
+ /* fields to simulate a delay profile */
+#define ED_MAX_NAME_LEN 32
+ char name[ED_MAX_NAME_LEN];
+ int loss_level;
+ int samples_no;
+ int *samples;
+};
+
+#define ED_MAX_SAMPLES_NO 1024
+struct dn_pipe_max8 {
+ struct dn_pipe8 pipe;
+ int samples[ED_MAX_SAMPLES_NO];
+};
+SLIST_HEAD(dn_pipe_head8, dn_pipe8);
+
+/*
+ * Changes from 7.2 to 8:
+ * dn_pipe:
+ * numbytes from int to int64_t
+ * add burst (int64_t)
+ * add idle_time (int64_t)
+ * add profile
+ * add struct dn_pipe_max
+ * add flag DN_HAS_PROFILE
+ *
+ * dn_flow_queue
+ * numbytes from u_long to int64_t
+ * add extra_bits (int64_t)
+ * q_time from u_int32_t to int64_t and name idle_time
+ *
+ * dn_flow_set unchanged
+ *
+ */
+
+/* NOTE:XXX copied from dummynet.c */
+#define O_NEXT(p, len) ((void *)((char *)p + len))
+static void
+oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
+{
+ oid->len = len;
+ oid->type = type;
+ oid->subtype = 0;
+ oid->id = id;
+}
+/* make room in the buffer and move the pointer forward */
+static void *
+o_next(struct dn_id **o, int len, int type)
+{
+ struct dn_id *ret = *o;
+ oid_fill(ret, len, type, 0);
+ *o = O_NEXT(*o, len);
+ return ret;
+}
+
+
+static size_t pipesize7 = sizeof(struct dn_pipe7);
+static size_t pipesize8 = sizeof(struct dn_pipe8);
+static size_t pipesizemax8 = sizeof(struct dn_pipe_max8);
+
+/* Indicate 'ipfw' version
+ * 1: from FreeBSD 7.2
+ * 0: from FreeBSD 8
+ * -1: unknow (for now is unused)
+ *
+ * It is update when a IP_DUMMYNET_DEL or IP_DUMMYNET_CONFIGURE request arrives
+ * NOTE: if a IP_DUMMYNET_GET arrives and the 'ipfw' version is unknow,
+ * it is suppose to be the FreeBSD 8 version.
+ */
+static int is7 = 0;
+
+static int
+convertflags2new(int src)
+{
+ int dst = 0;
+
+ if (src & DNOLD_HAVE_FLOW_MASK)
+ dst |= DN_HAVE_MASK;
+ if (src & DNOLD_QSIZE_IS_BYTES)
+ dst |= DN_QSIZE_BYTES;
+ if (src & DNOLD_NOERROR)
+ dst |= DN_NOERROR;
+ if (src & DNOLD_IS_RED)
+ dst |= DN_IS_RED;
+ if (src & DNOLD_IS_GENTLE_RED)
+ dst |= DN_IS_GENTLE_RED;
+ if (src & DNOLD_HAS_PROFILE)
+ dst |= DN_HAS_PROFILE;
+
+ return dst;
+}
+
+static int
+convertflags2old(int src)
+{
+ int dst = 0;
+
+ if (src & DN_HAVE_MASK)
+ dst |= DNOLD_HAVE_FLOW_MASK;
+ if (src & DN_IS_RED)
+ dst |= DNOLD_IS_RED;
+ if (src & DN_IS_GENTLE_RED)
+ dst |= DNOLD_IS_GENTLE_RED;
+ if (src & DN_NOERROR)
+ dst |= DNOLD_NOERROR;
+ if (src & DN_HAS_PROFILE)
+ dst |= DNOLD_HAS_PROFILE;
+ if (src & DN_QSIZE_BYTES)
+ dst |= DNOLD_QSIZE_IS_BYTES;
+
+ return dst;
+}
+
+static int
+dn_compat_del(void *v)
+{
+ struct dn_pipe7 *p = (struct dn_pipe7 *) v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *) v;
+ struct {
+ struct dn_id oid;
+ uintptr_t a[1]; /* add more if we want a list */
+ } cmd;
+
+ /* XXX DN_API_VERSION ??? */
+ oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
+
+ if (is7) {
+ if (p->pipe_nr == 0 && p->fs.fs_nr == 0)
+ return EINVAL;
+ if (p->pipe_nr != 0 && p->fs.fs_nr != 0)
+ return EINVAL;
+ } else {
+ if (p8->pipe_nr == 0 && p8->fs.fs_nr == 0)
+ return EINVAL;
+ if (p8->pipe_nr != 0 && p8->fs.fs_nr != 0)
+ return EINVAL;
+ }
+
+ if (p->pipe_nr != 0) { /* pipe x delete */
+ cmd.a[0] = p->pipe_nr;
+ cmd.oid.subtype = DN_LINK;
+ } else { /* queue x delete */
+ cmd.oid.subtype = DN_FS;
+ cmd.a[0] = (is7) ? p->fs.fs_nr : p8->fs.fs_nr;
+ }
+
+ return do_config(&cmd, cmd.oid.len);
+}
+
+static int
+dn_compat_config_queue(struct dn_fs *fs, void* v)
+{
+ struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+ struct dn_flow_set *f;
+
+ if (is7)
+ f = &p7->fs;
+ else
+ f = &p8->fs;
+
+ fs->fs_nr = f->fs_nr;
+ fs->sched_nr = f->parent_nr;
+ fs->flow_mask = f->flow_mask;
+ fs->buckets = f->rq_size;
+ fs->qsize = f->qsize;
+ fs->plr = f->plr;
+ fs->par[0] = f->weight;
+ fs->flags = convertflags2new(f->flags_fs);
+ if (fs->flags & DN_IS_GENTLE_RED || fs->flags & DN_IS_RED) {
+ fs->w_q = f->w_q;
+ fs->max_th = f->max_th;
+ fs->min_th = f->min_th;
+ fs->max_p = f->max_p;
+ }
+
+ return 0;
+}
+
+static int
+dn_compat_config_pipe(struct dn_sch *sch, struct dn_link *p,
+ struct dn_fs *fs, void* v)
+{
+ struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+ int i = p7->pipe_nr;
+
+ sch->sched_nr = i;
+ sch->oid.subtype = 0;
+ p->link_nr = i;
+ fs->fs_nr = i + 2*DN_MAX_ID;
+ fs->sched_nr = i + DN_MAX_ID;
+
+ /* Common to 7 and 8 */
+ p->bandwidth = p7->bandwidth;
+ p->delay = p7->delay;
+ if (!is7) {
+ /* FreeBSD 8 has burst */
+ p->burst = p8->burst;
+ }
+
+ /* fill the fifo flowset */
+ dn_compat_config_queue(fs, v);
+ fs->fs_nr = i + 2*DN_MAX_ID;
+ fs->sched_nr = i + DN_MAX_ID;
+
+ /* Move scheduler related parameter from fs to sch */
+ sch->buckets = fs->buckets; /*XXX*/
+ fs->buckets = 0;
+ if (fs->flags & DN_HAVE_MASK) {
+ sch->flags |= DN_HAVE_MASK;
+ fs->flags &= ~DN_HAVE_MASK;
+ sch->sched_mask = fs->flow_mask;
+ bzero(&fs->flow_mask, sizeof(struct ipfw_flow_id));
+ }
+
+ return 0;
+}
+
+static int
+dn_compat_config_profile(struct dn_profile *pf, struct dn_link *p,
+ void *v)
+{
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+
+ p8->samples = &(((struct dn_pipe_max8 *)p8)->samples[0]);
+
+ pf->link_nr = p->link_nr;
+ pf->loss_level = p8->loss_level;
+// pf->bandwidth = p->bandwidth; //XXX bandwidth redundant?
+ pf->samples_no = p8->samples_no;
+ strncpy(pf->name, p8->name,sizeof(pf->name));
+ bcopy(p8->samples, pf->samples, sizeof(pf->samples));
+
+ return 0;
+}
+
+/*
+ * If p->pipe_nr != 0 the command is 'pipe x config', so need to create
+ * the three main struct, else only a flowset is created
+ */
+static int
+dn_compat_configure(void *v)
+{
+ struct dn_id *buf = NULL, *base;
+ struct dn_sch *sch = NULL;
+ struct dn_link *p = NULL;
+ struct dn_fs *fs = NULL;
+ struct dn_profile *pf = NULL;
+ int lmax;
+ int error;
+
+ struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+
+ int i; /* number of object to configure */
+
+ lmax = sizeof(struct dn_id); /* command header */
+ lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
+ sizeof(struct dn_fs) + sizeof(struct dn_profile);
+
+ base = buf = malloc(lmax, M_DUMMYNET, M_WAIT|M_ZERO);
+ o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
+ base->id = DN_API_VERSION;
+
+ /* pipe_nr is the same in p7 and p8 */
+ i = p7->pipe_nr;
+ if (i != 0) { /* pipe config */
+ sch = o_next(&buf, sizeof(*sch), DN_SCH);
+ p = o_next(&buf, sizeof(*p), DN_LINK);
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+
+ error = dn_compat_config_pipe(sch, p, fs, v);
+ if (error) {
+ free(buf, M_DUMMYNET);
+ return error;
+ }
+ if (!is7 && p8->samples_no > 0) {
+ /* Add profiles*/
+ pf = o_next(&buf, sizeof(*pf), DN_PROFILE);
+ error = dn_compat_config_profile(pf, p, v);
+ if (error) {
+ free(buf, M_DUMMYNET);
+ return error;
+ }
+ }
+ } else { /* queue config */
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+ error = dn_compat_config_queue(fs, v);
+ if (error) {
+ free(buf, M_DUMMYNET);
+ return error;
+ }
+ }
+ error = do_config(base, (char *)buf - (char *)base);
+
+ if (buf)
+ free(buf, M_DUMMYNET);
+ return error;
+}
+
+int
+dn_compat_calc_size(void)
+{
+ int need = 0;
+ /* XXX use FreeBSD 8 struct size */
+ /* NOTE:
+ * - half scheduler: schk_count/2
+ * - all flowset: fsk_count
+ * - all flowset queues: queue_count
+ * - all pipe queue: si_count
+ */
+ need += dn_cfg.schk_count * sizeof(struct dn_pipe8) / 2;
+ need += dn_cfg.fsk_count * sizeof(struct dn_flow_set);
+ need += dn_cfg.si_count * sizeof(struct dn_flow_queue8);
+ need += dn_cfg.queue_count * sizeof(struct dn_flow_queue8);
+
+ return need;
+}
+
+int
+dn_c_copy_q (void *_ni, void *arg)
+{
+ struct copy_args *a = arg;
+ struct dn_flow_queue7 *fq7 = (struct dn_flow_queue7 *)*a->start;
+ struct dn_flow_queue8 *fq8 = (struct dn_flow_queue8 *)*a->start;
+ struct dn_flow *ni = (struct dn_flow *)_ni;
+ int size = 0;
+
+ /* XXX hash slot not set */
+ /* No difference between 7.2/8 */
+ fq7->len = ni->length;
+ fq7->len_bytes = ni->len_bytes;
+ fq7->id = ni->fid;
+
+ if (is7) {
+ size = sizeof(struct dn_flow_queue7);
+ fq7->tot_pkts = ni->tot_pkts;
+ fq7->tot_bytes = ni->tot_bytes;
+ fq7->drops = ni->drops;
+ } else {
+ size = sizeof(struct dn_flow_queue8);
+ fq8->tot_pkts = ni->tot_pkts;
+ fq8->tot_bytes = ni->tot_bytes;
+ fq8->drops = ni->drops;
+ }
+
+ *a->start += size;
+ return 0;
+}
+
+int
+dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq)
+{
+ struct dn_link *l = &s->link;
+ struct dn_fsk *f = s->fs;
+
+ struct dn_pipe7 *pipe7 = (struct dn_pipe7 *)*a->start;
+ struct dn_pipe8 *pipe8 = (struct dn_pipe8 *)*a->start;
+ struct dn_flow_set *fs;
+ int size = 0;
+
+ if (is7) {
+ fs = &pipe7->fs;
+ size = sizeof(struct dn_pipe7);
+ } else {
+ fs = &pipe8->fs;
+ size = sizeof(struct dn_pipe8);
+ }
+
+ /* These 4 field are the same in pipe7 and pipe8 */
+ pipe7->next.sle_next = (struct dn_pipe7 *)DN_IS_PIPE;
+ pipe7->bandwidth = l->bandwidth;
+ pipe7->delay = l->delay;
+ pipe7->pipe_nr = l->link_nr - DN_MAX_ID;
+
+ if (!is7) {
+ if (s->profile) {
+ struct dn_profile *pf = s->profile;
+ strncpy(pipe8->name, pf->name, sizeof(pf->name));
+ pipe8->loss_level = pf->loss_level;
+ pipe8->samples_no = pf->samples_no;
+ }
+ pipe8->burst = div64(l->burst , 8 * hz);
+ }
+
+ fs->flow_mask = s->sch.sched_mask;
+ fs->rq_size = s->sch.buckets ? s->sch.buckets : 1;
+
+ fs->parent_nr = l->link_nr - DN_MAX_ID;
+ fs->qsize = f->fs.qsize;
+ fs->plr = f->fs.plr;
+ fs->w_q = f->fs.w_q;
+ fs->max_th = f->max_th;
+ fs->min_th = f->min_th;
+ fs->max_p = f->fs.max_p;
+ fs->rq_elements = nq;
+
+ fs->flags_fs = convertflags2old(f->fs.flags);
+
+ *a->start += size;
+ return 0;
+}
+
+
+int
+dn_compat_copy_pipe(struct copy_args *a, void *_o)
+{
+ int have = a->end - *a->start;
+ int need = 0;
+ int pipe_size = sizeof(struct dn_pipe8);
+ int queue_size = sizeof(struct dn_flow_queue8);
+ int n_queue = 0; /* number of queues */
+
+ struct dn_schk *s = (struct dn_schk *)_o;
+ /* calculate needed space:
+ * - struct dn_pipe
+ * - if there are instances, dn_queue * n_instances
+ */
+ n_queue = (s->sch.flags & DN_HAVE_MASK ? dn_ht_entries(s->siht) :
+ (s->siht ? 1 : 0));
+ need = pipe_size + queue_size * n_queue;
+ if (have < need) {
+ D("have %d < need %d", have, need);
+ return 1;
+ }
+ /* copy pipe */
+ dn_c_copy_pipe(s, a, n_queue);
+
+ /* copy queues */
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, dn_c_copy_q, a);
+ else if (s->siht)
+ dn_c_copy_q(s->siht, a);
+ return 0;
+}
+
+int
+dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq)
+{
+ struct dn_flow_set *fs = (struct dn_flow_set *)*a->start;
+
+ fs->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
+ fs->fs_nr = f->fs.fs_nr;
+ fs->qsize = f->fs.qsize;
+ fs->plr = f->fs.plr;
+ fs->w_q = f->fs.w_q;
+ fs->max_th = f->max_th;
+ fs->min_th = f->min_th;
+ fs->max_p = f->fs.max_p;
+ fs->flow_mask = f->fs.flow_mask;
+ fs->rq_elements = nq;
+ fs->rq_size = (f->fs.buckets ? f->fs.buckets : 1);
+ fs->parent_nr = f->fs.sched_nr;
+ fs->weight = f->fs.par[0];
+
+ fs->flags_fs = convertflags2old(f->fs.flags);
+ *a->start += sizeof(struct dn_flow_set);
+ return 0;
+}
+
+int
+dn_compat_copy_queue(struct copy_args *a, void *_o)
+{
+ int have = a->end - *a->start;
+ int need = 0;
+ int fs_size = sizeof(struct dn_flow_set);
+ int queue_size = sizeof(struct dn_flow_queue8);
+
+ struct dn_fsk *fs = (struct dn_fsk *)_o;
+ int n_queue = 0; /* number of queues */
+
+ n_queue = (fs->fs.flags & DN_HAVE_MASK ? dn_ht_entries(fs->qht) :
+ (fs->qht ? 1 : 0));
+
+ need = fs_size + queue_size * n_queue;
+ if (have < need) {
+ D("have < need");
+ return 1;
+ }
+
+ /* copy flowset */
+ dn_c_copy_fs(fs, a, n_queue);
+
+ /* copy queues */
+ if (fs->fs.flags & DN_HAVE_MASK)
+ dn_ht_scan(fs->qht, dn_c_copy_q, a);
+ else if (fs->qht)
+ dn_c_copy_q(fs->qht, a);
+
+ return 0;
+}
+
+int
+copy_data_helper_compat(void *_o, void *_arg)
+{
+ struct copy_args *a = _arg;
+
+ if (a->type == DN_COMPAT_PIPE) {
+ struct dn_schk *s = _o;
+ if (s->sch.oid.subtype != 1 || s->sch.sched_nr <= DN_MAX_ID) {
+ return 0; /* not old type */
+ }
+ /* copy pipe parameters, and if instance exists, copy
+ * other parameters and eventually queues.
+ */
+ if(dn_compat_copy_pipe(a, _o))
+ return DNHT_SCAN_END;
+ } else if (a->type == DN_COMPAT_QUEUE) {
+ struct dn_fsk *fs = _o;
+ if (fs->fs.fs_nr >= DN_MAX_ID)
+ return 0;
+ if (dn_compat_copy_queue(a, _o))
+ return DNHT_SCAN_END;
+ }
+ return 0;
+}
+
+/* Main function to manage old requests */
+int
+ip_dummynet_compat(struct sockopt *sopt)
+{
+ int error=0;
+ void *v = NULL;
+ struct dn_id oid;
+
+ /* Lenght of data, used to found ipfw version... */
+ int len = sopt->sopt_valsize;
+
+ /* len can be 0 if command was dummynet_flush */
+ if (len == pipesize7) {
+ D("setting compatibility with FreeBSD 7.2");
+ is7 = 1;
+ }
+ else if (len == pipesize8 || len == pipesizemax8) {
+ D("setting compatibility with FreeBSD 8");
+ is7 = 0;
+ }
+
+ switch (sopt->sopt_name) {
+ default:
+ printf("dummynet: -- unknown option %d", sopt->sopt_name);
+ error = EINVAL;
+ break;
+
+ case IP_DUMMYNET_FLUSH:
+ oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
+ do_config(&oid, oid.len);
+ break;
+
+ case IP_DUMMYNET_DEL:
+ v = malloc(len, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, v, len, len);
+ if (error)
+ break;
+ error = dn_compat_del(v);
+ free(v, M_DUMMYNET);
+ break;
+
+ case IP_DUMMYNET_CONFIGURE:
+ v = malloc(len, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, v, len, len);
+ if (error)
+ break;
+ error = dn_compat_configure(v);
+ free(v, M_DUMMYNET);
+ break;
+
+ case IP_DUMMYNET_GET: {
+ void *buf;
+ int ret;
+ int original_size = sopt->sopt_valsize;
+ int size;
+
+ ret = dummynet_get(sopt, &buf);
+ if (ret)
+ return 0;//XXX ?
+ size = sopt->sopt_valsize;
+ sopt->sopt_valsize = original_size;
+ D("size=%d, buf=%p", size, buf);
+ ret = sooptcopyout(sopt, buf, size);
+ if (ret)
+ printf(" %s ERROR sooptcopyout\n", __FUNCTION__);
+ if (buf)
+ free(buf, M_DUMMYNET);
+ }
+ }
+
+ return error;
+}
+
+
diff --git a/sys/netinet/ipfw/ip_dn_io.c b/sys/netinet/ipfw/ip_dn_io.c
new file mode 100644
index 0000000..152010e
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dn_io.c
@@ -0,0 +1,801 @@
+/*-
+ * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * Dummynet portions related to packet handling.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
+#include <net/netisr.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h> /* ip_len, ip_off */
+#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+
+#include <netinet/if_ether.h> /* various ether_* routines */
+
+#include <netinet/ip6.h> /* for ip6_input, ip6_output prototypes */
+#include <netinet6/ip6_var.h>
+
+/*
+ * We keep a private variable for the simulation time, but we could
+ * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
+ * instead of dn_cfg.curr_time
+ */
+
+struct dn_parms dn_cfg;
+//VNET_DEFINE(struct dn_parms, _base_dn_cfg);
+
+static long tick_last; /* Last tick duration (usec). */
+static long tick_delta; /* Last vs standard tick diff (usec). */
+static long tick_delta_sum; /* Accumulated tick difference (usec).*/
+static long tick_adjustment; /* Tick adjustments done. */
+static long tick_lost; /* Lost(coalesced) ticks number. */
+/* Adjusted vs non-adjusted curr_time difference (ticks). */
+static long tick_diff;
+
+static unsigned long io_pkt;
+static unsigned long io_pkt_fast;
+static unsigned long io_pkt_drop;
+
+/*
+ * We use a heap to store entities for which we have pending timer events.
+ * The heap is checked at every tick and all entities with expired events
+ * are extracted.
+ */
+
+MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap");
+
+extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
+
+#ifdef SYSCTL_NODE
+
+SYSBEGIN(f4)
+
+SYSCTL_DECL(_net_inet);
+SYSCTL_DECL(_net_inet_ip);
+SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
+
+/* wrapper to pass dn_cfg fields to SYSCTL_* */
+//#define DC(x) (&(VNET_NAME(_base_dn_cfg).x))
+#define DC(x) (&(dn_cfg.x))
+/* parameters */
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size,
+ CTLFLAG_RW, DC(hash_size), 0, "Default hash table size");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit,
+ CTLFLAG_RW, DC(slot_limit), 0,
+ "Upper limit in slots for pipe queue.");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit,
+ CTLFLAG_RW, DC(byte_limit), 0,
+ "Upper limit in bytes for pipe queue.");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast,
+ CTLFLAG_RW, DC(io_fast), 0, "Enable fast dummynet io.");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug,
+ CTLFLAG_RW, DC(debug), 0, "Dummynet debug level");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire,
+ CTLFLAG_RW, DC(expire), 0, "Expire empty queues/pipes");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire_cycle,
+ CTLFLAG_RD, DC(expire_cycle), 0, "Expire cycle for queues/pipes");
+
+/* RED parameters */
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth,
+ CTLFLAG_RD, DC(red_lookup_depth), 0, "Depth of RED lookup table");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size,
+ CTLFLAG_RD, DC(red_avg_pkt_size), 0, "RED Medium packet size");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size,
+ CTLFLAG_RD, DC(red_max_pkt_size), 0, "RED Max packet size");
+
+/* time adjustment */
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta,
+ CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec).");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum,
+ CTLFLAG_RD, &tick_delta_sum, 0, "Accumulated tick difference (usec).");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_adjustment,
+ CTLFLAG_RD, &tick_adjustment, 0, "Tick adjustments done.");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff,
+ CTLFLAG_RD, &tick_diff, 0,
+ "Adjusted vs non-adjusted curr_time difference (ticks).");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost,
+ CTLFLAG_RD, &tick_lost, 0,
+ "Number of ticks coalesced by dummynet taskqueue.");
+
+/* statistics */
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, schk_count,
+ CTLFLAG_RD, DC(schk_count), 0, "Number of schedulers");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, si_count,
+ CTLFLAG_RD, DC(si_count), 0, "Number of scheduler instances");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, fsk_count,
+ CTLFLAG_RD, DC(fsk_count), 0, "Number of flowsets");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, queue_count,
+ CTLFLAG_RD, DC(queue_count), 0, "Number of queues");
+SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt,
+ CTLFLAG_RD, &io_pkt, 0,
+ "Number of packets passed to dummynet.");
+SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_fast,
+ CTLFLAG_RD, &io_pkt_fast, 0,
+ "Number of packets bypassed dummynet scheduler.");
+SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
+ CTLFLAG_RD, &io_pkt_drop, 0,
+ "Number of packets dropped by dummynet.");
+#undef DC
+SYSEND
+
+#endif
+
+static void dummynet_send(struct mbuf *);
+
+/*
+ * Packets processed by dummynet have an mbuf tag associated with
+ * them that carries their dummynet state.
+ * Outside dummynet, only the 'rule' field is relevant, and it must
+ * be at the beginning of the structure.
+ */
+struct dn_pkt_tag {
+ struct ipfw_rule_ref rule; /* matching rule */
+
+ /* second part, dummynet specific */
+ int dn_dir; /* action when packet comes out.*/
+ /* see ip_fw_private.h */
+ uint64_t output_time; /* when the pkt is due for delivery*/
+ struct ifnet *ifp; /* interface, for ip_output */
+ struct _ip6dn_args ip6opt; /* XXX ipv6 options */
+};
+
+/*
+ * Return the mbuf tag holding the dummynet state (it should
+ * be the first one on the list).
+ */
+static struct dn_pkt_tag *
+dn_tag_get(struct mbuf *m)
+{
+ struct m_tag *mtag = m_tag_first(m);
+ KASSERT(mtag != NULL &&
+ mtag->m_tag_cookie == MTAG_ABI_COMPAT &&
+ mtag->m_tag_id == PACKET_TAG_DUMMYNET,
+ ("packet on dummynet queue w/o dummynet tag!"));
+ return (struct dn_pkt_tag *)(mtag+1);
+}
+
+static inline void
+mq_append(struct mq *q, struct mbuf *m)
+{
+ if (q->head == NULL)
+ q->head = m;
+ else
+ q->tail->m_nextpkt = m;
+ q->tail = m;
+ m->m_nextpkt = NULL;
+}
+
+/*
+ * Dispose a list of packet. Use a functions so if we need to do
+ * more work, this is a central point to do it.
+ */
+void dn_free_pkts(struct mbuf *mnext)
+{
+ struct mbuf *m;
+
+ while ((m = mnext) != NULL) {
+ mnext = m->m_nextpkt;
+ FREE_PKT(m);
+ }
+}
+
+static int
+red_drops (struct dn_queue *q, int len)
+{
+ /*
+ * RED algorithm
+ *
+ * RED calculates the average queue size (avg) using a low-pass filter
+ * with an exponential weighted (w_q) moving average:
+ * avg <- (1-w_q) * avg + w_q * q_size
+ * where q_size is the queue length (measured in bytes or * packets).
+ *
+ * If q_size == 0, we compute the idle time for the link, and set
+ * avg = (1 - w_q)^(idle/s)
+ * where s is the time needed for transmitting a medium-sized packet.
+ *
+ * Now, if avg < min_th the packet is enqueued.
+ * If avg > max_th the packet is dropped. Otherwise, the packet is
+ * dropped with probability P function of avg.
+ */
+
+ struct dn_fsk *fs = q->fs;
+ int64_t p_b = 0;
+
+ /* Queue in bytes or packets? */
+ uint32_t q_size = (fs->fs.flags & DN_QSIZE_BYTES) ?
+ q->ni.len_bytes : q->ni.length;
+
+ /* Average queue size estimation. */
+ if (q_size != 0) {
+ /* Queue is not empty, avg <- avg + (q_size - avg) * w_q */
+ int diff = SCALE(q_size) - q->avg;
+ int64_t v = SCALE_MUL((int64_t)diff, (int64_t)fs->w_q);
+
+ q->avg += (int)v;
+ } else {
+ /*
+ * Queue is empty, find for how long the queue has been
+ * empty and use a lookup table for computing
+ * (1 - * w_q)^(idle_time/s) where s is the time to send a
+ * (small) packet.
+ * XXX check wraps...
+ */
+ if (q->avg) {
+ u_int t = div64((dn_cfg.curr_time - q->q_time), fs->lookup_step);
+
+ q->avg = (t < fs->lookup_depth) ?
+ SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
+ }
+ }
+
+ /* Should i drop? */
+ if (q->avg < fs->min_th) {
+ q->count = -1;
+ return (0); /* accept packet */
+ }
+ if (q->avg >= fs->max_th) { /* average queue >= max threshold */
+ if (fs->fs.flags & DN_IS_GENTLE_RED) {
+ /*
+ * According to Gentle-RED, if avg is greater than
+ * max_th the packet is dropped with a probability
+ * p_b = c_3 * avg - c_4
+ * where c_3 = (1 - max_p) / max_th
+ * c_4 = 1 - 2 * max_p
+ */
+ p_b = SCALE_MUL((int64_t)fs->c_3, (int64_t)q->avg) -
+ fs->c_4;
+ } else {
+ q->count = -1;
+ return (1);
+ }
+ } else if (q->avg > fs->min_th) {
+ /*
+ * We compute p_b using the linear dropping function
+ * p_b = c_1 * avg - c_2
+ * where c_1 = max_p / (max_th - min_th)
+ * c_2 = max_p * min_th / (max_th - min_th)
+ */
+ p_b = SCALE_MUL((int64_t)fs->c_1, (int64_t)q->avg) - fs->c_2;
+ }
+
+ if (fs->fs.flags & DN_QSIZE_BYTES)
+ p_b = div64((p_b * len) , fs->max_pkt_size);
+ if (++q->count == 0)
+ q->random = random() & 0xffff;
+ else {
+ /*
+ * q->count counts packets arrived since last drop, so a greater
+ * value of q->count means a greater packet drop probability.
+ */
+ if (SCALE_MUL(p_b, SCALE((int64_t)q->count)) > q->random) {
+ q->count = 0;
+ /* After a drop we calculate a new random value. */
+ q->random = random() & 0xffff;
+ return (1); /* drop */
+ }
+ }
+ /* End of RED algorithm. */
+
+ return (0); /* accept */
+
+}
+
+/*
+ * Enqueue a packet in q, subject to space and queue management policy
+ * (whose parameters are in q->fs).
+ * Update stats for the queue and the scheduler.
+ * Return 0 on success, 1 on drop. The packet is consumed anyways.
+ */
+int
+dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
+{
+ struct dn_fs *f;
+ struct dn_flow *ni; /* stats for scheduler instance */
+ uint64_t len;
+
+ if (q->fs == NULL || q->_si == NULL) {
+ printf("%s fs %p si %p, dropping\n",
+ __FUNCTION__, q->fs, q->_si);
+ FREE_PKT(m);
+ return 1;
+ }
+ f = &(q->fs->fs);
+ ni = &q->_si->ni;
+ len = m->m_pkthdr.len;
+ /* Update statistics, then check reasons to drop pkt. */
+ q->ni.tot_bytes += len;
+ q->ni.tot_pkts++;
+ ni->tot_bytes += len;
+ ni->tot_pkts++;
+ if (drop)
+ goto drop;
+ if (f->plr && random() < f->plr)
+ goto drop;
+ if (f->flags & DN_IS_RED && red_drops(q, m->m_pkthdr.len))
+ goto drop;
+ if (f->flags & DN_QSIZE_BYTES) {
+ if (q->ni.len_bytes > f->qsize)
+ goto drop;
+ } else if (q->ni.length >= f->qsize) {
+ goto drop;
+ }
+ mq_append(&q->mq, m);
+ q->ni.length++;
+ q->ni.len_bytes += len;
+ ni->length++;
+ ni->len_bytes += len;
+ return 0;
+
+drop:
+ io_pkt_drop++;
+ q->ni.drops++;
+ ni->drops++;
+ FREE_PKT(m);
+ return 1;
+}
+
+/*
+ * Fetch packets from the delay line which are due now. If there are
+ * leftover packets, reinsert the delay line in the heap.
+ * Runs under scheduler lock.
+ */
+static void
+transmit_event(struct mq *q, struct delay_line *dline, uint64_t now)
+{
+ struct mbuf *m;
+ struct dn_pkt_tag *pkt = NULL;
+
+ dline->oid.subtype = 0; /* not in heap */
+ while ((m = dline->mq.head) != NULL) {
+ pkt = dn_tag_get(m);
+ if (!DN_KEY_LEQ(pkt->output_time, now))
+ break;
+ dline->mq.head = m->m_nextpkt;
+ mq_append(q, m);
+ }
+ if (m != NULL) {
+ dline->oid.subtype = 1; /* in heap */
+ heap_insert(&dn_cfg.evheap, pkt->output_time, dline);
+ }
+}
+
+/*
+ * Convert the additional MAC overheads/delays into an equivalent
+ * number of bits for the given data rate. The samples are
+ * in milliseconds so we need to divide by 1000.
+ */
+static uint64_t
+extra_bits(struct mbuf *m, struct dn_schk *s)
+{
+ int index;
+ uint64_t bits;
+ struct dn_profile *pf = s->profile;
+
+ if (!pf || pf->samples_no == 0)
+ return 0;
+ index = random() % pf->samples_no;
+ bits = div64((uint64_t)pf->samples[index] * s->link.bandwidth, 1000);
+ if (index >= pf->loss_level) {
+ struct dn_pkt_tag *dt = dn_tag_get(m);
+ if (dt)
+ dt->dn_dir = DIR_DROP;
+ }
+ return bits;
+}
+
+/*
+ * Send traffic from a scheduler instance due by 'now'.
+ * Return a pointer to the head of the queue.
+ */
+static struct mbuf *
+serve_sched(struct mq *q, struct dn_sch_inst *si, uint64_t now)
+{
+ struct mq def_q;
+ struct dn_schk *s = si->sched;
+ struct mbuf *m = NULL;
+ int delay_line_idle = (si->dline.mq.head == NULL);
+ int done, bw;
+
+ if (q == NULL) {
+ q = &def_q;
+ q->head = NULL;
+ }
+
+ bw = s->link.bandwidth;
+ si->kflags &= ~DN_ACTIVE;
+
+ if (bw > 0)
+ si->credit += (now - si->sched_time) * bw;
+ else
+ si->credit = 0;
+ si->sched_time = now;
+ done = 0;
+ while (si->credit >= 0 && (m = s->fp->dequeue(si)) != NULL) {
+ uint64_t len_scaled;
+ done++;
+ len_scaled = (bw == 0) ? 0 : hz *
+ (m->m_pkthdr.len * 8 + extra_bits(m, s));
+ si->credit -= len_scaled;
+ /* Move packet in the delay line */
+ dn_tag_get(m)->output_time += s->link.delay ;
+ mq_append(&si->dline.mq, m);
+ }
+ /*
+ * If credit >= 0 the instance is idle, mark time.
+ * Otherwise put back in the heap, and adjust the output
+ * time of the last inserted packet, m, which was too early.
+ */
+ if (si->credit >= 0) {
+ si->idle_time = now;
+ } else {
+ uint64_t t;
+ KASSERT (bw > 0, ("bw=0 and credit<0 ?"));
+ t = div64(bw - 1 - si->credit, bw);
+ if (m)
+ dn_tag_get(m)->output_time += t;
+ si->kflags |= DN_ACTIVE;
+ heap_insert(&dn_cfg.evheap, now + t, si);
+ }
+ if (delay_line_idle && done)
+ transmit_event(q, &si->dline, now);
+ return q->head;
+}
+
+/*
+ * The timer handler for dummynet. Time is computed in ticks, but
+ * but the code is tolerant to the actual rate at which this is called.
+ * Once complete, the function reschedules itself for the next tick.
+ */
+void
+dummynet_task(void *context, int pending)
+{
+ struct timeval t;
+ struct mq q = { NULL, NULL }; /* queue to accumulate results */
+
+ CURVNET_SET((struct vnet *)context);
+
+ DN_BH_WLOCK();
+
+ /* Update number of lost(coalesced) ticks. */
+ tick_lost += pending - 1;
+
+ getmicrouptime(&t);
+ /* Last tick duration (usec). */
+ tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 +
+ (t.tv_usec - dn_cfg.prev_t.tv_usec);
+ /* Last tick vs standard tick difference (usec). */
+ tick_delta = (tick_last * hz - 1000000) / hz;
+ /* Accumulated tick difference (usec). */
+ tick_delta_sum += tick_delta;
+
+ dn_cfg.prev_t = t;
+
+ /*
+ * Adjust curr_time if the accumulated tick difference is
+ * greater than the 'standard' tick. Since curr_time should
+ * be monotonically increasing, we do positive adjustments
+ * as required, and throttle curr_time in case of negative
+ * adjustment.
+ */
+ dn_cfg.curr_time++;
+ if (tick_delta_sum - tick >= 0) {
+ int diff = tick_delta_sum / tick;
+
+ dn_cfg.curr_time += diff;
+ tick_diff += diff;
+ tick_delta_sum %= tick;
+ tick_adjustment++;
+ } else if (tick_delta_sum + tick <= 0) {
+ dn_cfg.curr_time--;
+ tick_diff--;
+ tick_delta_sum += tick;
+ tick_adjustment++;
+ }
+
+ /* serve pending events, accumulate in q */
+ for (;;) {
+ struct dn_id *p; /* generic parameter to handler */
+
+ if (dn_cfg.evheap.elements == 0 ||
+ DN_KEY_LT(dn_cfg.curr_time, HEAP_TOP(&dn_cfg.evheap)->key))
+ break;
+ p = HEAP_TOP(&dn_cfg.evheap)->object;
+ heap_extract(&dn_cfg.evheap, NULL);
+
+ if (p->type == DN_SCH_I) {
+ serve_sched(&q, (struct dn_sch_inst *)p, dn_cfg.curr_time);
+ } else { /* extracted a delay line */
+ transmit_event(&q, (struct delay_line *)p, dn_cfg.curr_time);
+ }
+ }
+ if (dn_cfg.expire && ++dn_cfg.expire_cycle >= dn_cfg.expire) {
+ dn_cfg.expire_cycle = 0;
+ dn_drain_scheduler();
+ dn_drain_queue();
+ }
+
+ DN_BH_WUNLOCK();
+ dn_reschedule();
+ if (q.head != NULL)
+ dummynet_send(q.head);
+ CURVNET_RESTORE();
+}
+
+/*
+ * forward a chain of packets to the proper destination.
+ * This runs outside the dummynet lock.
+ */
+static void
+dummynet_send(struct mbuf *m)
+{
+ struct mbuf *n;
+
+ for (; m != NULL; m = n) {
+ struct ifnet *ifp = NULL; /* gcc 3.4.6 complains */
+ struct m_tag *tag;
+ int dst;
+
+ n = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ tag = m_tag_first(m);
+ if (tag == NULL) { /* should not happen */
+ dst = DIR_DROP;
+ } else {
+ struct dn_pkt_tag *pkt = dn_tag_get(m);
+ /* extract the dummynet info, rename the tag
+ * to carry reinject info.
+ */
+ dst = pkt->dn_dir;
+ ifp = pkt->ifp;
+ tag->m_tag_cookie = MTAG_IPFW_RULE;
+ tag->m_tag_id = 0;
+ }
+
+ switch (dst) {
+ case DIR_OUT:
+ SET_HOST_IPLEN(mtod(m, struct ip *));
+ ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
+ break ;
+
+ case DIR_IN :
+ /* put header in network format for ip_input() */
+ //SET_NET_IPLEN(mtod(m, struct ip *));
+ netisr_dispatch(NETISR_IP, m);
+ break;
+
+#ifdef INET6
+ case DIR_IN | PROTO_IPV6:
+ netisr_dispatch(NETISR_IPV6, m);
+ break;
+
+ case DIR_OUT | PROTO_IPV6:
+ SET_HOST_IPLEN(mtod(m, struct ip *));
+ ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
+ break;
+#endif
+
+ case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
+ if (bridge_dn_p != NULL)
+ ((*bridge_dn_p)(m, ifp));
+ else
+ printf("dummynet: if_bridge not loaded\n");
+
+ break;
+
+ case DIR_IN | PROTO_LAYER2: /* DN_TO_ETH_DEMUX: */
+ /*
+ * The Ethernet code assumes the Ethernet header is
+ * contiguous in the first mbuf header.
+ * Insure this is true.
+ */
+ if (m->m_len < ETHER_HDR_LEN &&
+ (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
+ printf("dummynet/ether: pullup failed, "
+ "dropping packet\n");
+ break;
+ }
+ ether_demux(m->m_pkthdr.rcvif, m);
+ break;
+
+ case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
+ ether_output_frame(ifp, m);
+ break;
+
+ case DIR_DROP:
+ /* drop the packet after some time */
+ FREE_PKT(m);
+ break;
+
+ default:
+ printf("dummynet: bad switch %d!\n", dst);
+ FREE_PKT(m);
+ break;
+ }
+ }
+}
+
+static inline int
+tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa)
+{
+ struct dn_pkt_tag *dt;
+ struct m_tag *mtag;
+
+ mtag = m_tag_get(PACKET_TAG_DUMMYNET,
+ sizeof(*dt), M_NOWAIT | M_ZERO);
+ if (mtag == NULL)
+ return 1; /* Cannot allocate packet header. */
+ m_tag_prepend(m, mtag); /* Attach to mbuf chain. */
+ dt = (struct dn_pkt_tag *)(mtag + 1);
+ dt->rule = fwa->rule;
+ dt->rule.info &= IPFW_ONEPASS; /* only keep this info */
+ dt->dn_dir = dir;
+ dt->ifp = fwa->oif;
+ /* dt->output tame is updated as we move through */
+ dt->output_time = dn_cfg.curr_time;
+ return 0;
+}
+
+
+/*
+ * dummynet hook for packets.
+ * We use the argument to locate the flowset fs and the sched_set sch
+ * associated to it. The we apply flow_mask and sched_mask to
+ * determine the queue and scheduler instances.
+ *
+ * dir where shall we send the packet after dummynet.
+ * *m0 the mbuf with the packet
+ * ifp the 'ifp' parameter from the caller.
+ * NULL in ip_input, destination interface in ip_output,
+ */
+int
+dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
+{
+ struct mbuf *m = *m0;
+ struct dn_fsk *fs = NULL;
+ struct dn_sch_inst *si;
+ struct dn_queue *q = NULL; /* default */
+
+ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) +
+ ((fwa->rule.info & IPFW_IS_PIPE) ? 2*DN_MAX_ID : 0);
+ DN_BH_WLOCK();
+ io_pkt++;
+ /* we could actually tag outside the lock, but who cares... */
+ if (tag_mbuf(m, dir, fwa))
+ goto dropit;
+ if (dn_cfg.busy) {
+ /* if the upper half is busy doing something expensive,
+ * lets queue the packet and move forward
+ */
+ mq_append(&dn_cfg.pending, m);
+ m = *m0 = NULL; /* consumed */
+ goto done; /* already active, nothing to do */
+ }
+ /* XXX locate_flowset could be optimised with a direct ref. */
+ fs = dn_ht_find(dn_cfg.fshash, fs_id, 0, NULL);
+ if (fs == NULL)
+ goto dropit; /* This queue/pipe does not exist! */
+ if (fs->sched == NULL) /* should not happen */
+ goto dropit;
+ /* find scheduler instance, possibly applying sched_mask */
+ si = ipdn_si_find(fs->sched, &(fwa->f_id));
+ if (si == NULL)
+ goto dropit;
+ /*
+ * If the scheduler supports multiple queues, find the right one
+ * (otherwise it will be ignored by enqueue).
+ */
+ if (fs->sched->fp->flags & DN_MULTIQUEUE) {
+ q = ipdn_q_find(fs, si, &(fwa->f_id));
+ if (q == NULL)
+ goto dropit;
+ }
+ if (fs->sched->fp->enqueue(si, q, m)) {
+ /* packet was dropped by enqueue() */
+ m = *m0 = NULL;
+ goto dropit;
+ }
+
+ if (si->kflags & DN_ACTIVE) {
+ m = *m0 = NULL; /* consumed */
+ goto done; /* already active, nothing to do */
+ }
+
+ /* compute the initial allowance */
+ {
+ struct dn_link *p = &fs->sched->link;
+ si->credit = dn_cfg.io_fast ? p->bandwidth : 0;
+ if (p->burst) {
+ uint64_t burst = (dn_cfg.curr_time - si->idle_time) * p->bandwidth;
+ if (burst > p->burst)
+ burst = p->burst;
+ si->credit += burst;
+ }
+ }
+ /* pass through scheduler and delay line */
+ m = serve_sched(NULL, si, dn_cfg.curr_time);
+
+ /* optimization -- pass it back to ipfw for immediate send */
+ /* XXX Don't call dummynet_send() if scheduler return the packet
+ * just enqueued. This avoid a lock order reversal.
+ *
+ */
+ if (/*dn_cfg.io_fast &&*/ m == *m0 && (dir & PROTO_LAYER2) == 0 ) {
+ /* fast io, rename the tag * to carry reinject info. */
+ struct m_tag *tag = m_tag_first(m);
+
+ tag->m_tag_cookie = MTAG_IPFW_RULE;
+ tag->m_tag_id = 0;
+ io_pkt_fast++;
+ if (m->m_nextpkt != NULL) {
+ printf("dummynet: fast io: pkt chain detected!\n");
+ m->m_nextpkt = NULL;
+ }
+ m = NULL;
+ } else {
+ *m0 = NULL;
+ }
+done:
+ DN_BH_WUNLOCK();
+ if (m)
+ dummynet_send(m);
+ return 0;
+
+dropit:
+ io_pkt_drop++;
+ DN_BH_WUNLOCK();
+ if (m)
+ FREE_PKT(m);
+ *m0 = NULL;
+ return (fs && (fs->fs.flags & DN_NOERROR)) ? 0 : ENOBUFS;
+}
diff --git a/sys/netinet/ipfw/ip_dn_private.h b/sys/netinet/ipfw/ip_dn_private.h
new file mode 100644
index 0000000..03b43db
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dn_private.h
@@ -0,0 +1,406 @@
+/*-
+ * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * internal dummynet APIs.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IP_DN_PRIVATE_H
+#define _IP_DN_PRIVATE_H
+
+/* debugging support
+ * use ND() to remove debugging, D() to print a line,
+ * DX(level, ...) to print above a certain level
+ * If you redefine D() you are expected to redefine all.
+ */
+#ifndef D
+#define ND(fmt, ...) do {} while (0)
+#define D1(fmt, ...) do {} while (0)
+#define D(fmt, ...) printf("%-10s " fmt "\n", \
+ __FUNCTION__, ## __VA_ARGS__)
+#define DX(lev, fmt, ...) do { \
+ if (dn_cfg.debug > lev) D(fmt, ## __VA_ARGS__); } while (0)
+#endif
+
+MALLOC_DECLARE(M_DUMMYNET);
+
+#ifndef FREE_PKT
+#define FREE_PKT(m) m_freem(m)
+#endif
+
+#ifndef __linux__
+#define div64(a, b) ((int64_t)(a) / (int64_t)(b))
+#endif
+
+#define DN_LOCK_INIT() do { \
+ mtx_init(&dn_cfg.uh_mtx, "dn_uh", NULL, MTX_DEF); \
+ mtx_init(&dn_cfg.bh_mtx, "dn_bh", NULL, MTX_DEF); \
+ } while (0)
+#define DN_LOCK_DESTROY() do { \
+ mtx_destroy(&dn_cfg.uh_mtx); \
+ mtx_destroy(&dn_cfg.bh_mtx); \
+ } while (0)
+#if 0 /* not used yet */
+#define DN_UH_RLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_UH_RUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_UH_WLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_UH_WUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_UH_LOCK_ASSERT() mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
+#endif
+
+#define DN_BH_RLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_BH_RUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_BH_WLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_BH_WUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_BH_LOCK_ASSERT() mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
+
+SLIST_HEAD(dn_schk_head, dn_schk);
+SLIST_HEAD(dn_sch_inst_head, dn_sch_inst);
+SLIST_HEAD(dn_fsk_head, dn_fsk);
+SLIST_HEAD(dn_queue_head, dn_queue);
+SLIST_HEAD(dn_alg_head, dn_alg);
+
+struct mq { /* a basic queue of packets*/
+ struct mbuf *head, *tail;
+};
+
+static inline void
+set_oid(struct dn_id *o, int type, int len)
+{
+ o->type = type;
+ o->len = len;
+ o->subtype = 0;
+};
+
+/*
+ * configuration and global data for a dummynet instance
+ *
+ * When a configuration is modified from userland, 'id' is incremented
+ * so we can use the value to check for stale pointers.
+ */
+struct dn_parms {
+ uint32_t id; /* configuration version */
+
+ /* defaults (sysctl-accessible) */
+ int red_lookup_depth;
+ int red_avg_pkt_size;
+ int red_max_pkt_size;
+ int hash_size;
+ int max_hash_size;
+ long byte_limit; /* max queue sizes */
+ long slot_limit;
+
+ int io_fast;
+ int debug;
+
+ /* timekeeping */
+ struct timeval prev_t; /* last time dummynet_tick ran */
+ struct dn_heap evheap; /* scheduled events */
+
+ /* counters of objects -- used for reporting space */
+ int schk_count;
+ int si_count;
+ int fsk_count;
+ int queue_count;
+
+ /* ticks and other stuff */
+ uint64_t curr_time;
+ /* flowsets and schedulers are in hash tables, with 'hash_size'
+ * buckets. fshash is looked up at every packet arrival
+ * so better be generous if we expect many entries.
+ */
+ struct dn_ht *fshash;
+ struct dn_ht *schedhash;
+ /* list of flowsets without a scheduler -- use sch_chain */
+ struct dn_fsk_head fsu; /* list of unlinked flowsets */
+ struct dn_alg_head schedlist; /* list of algorithms */
+
+ /* Store the fs/sch to scan when draining. The value is the
+ * bucket number of the hash table. Expire can be disabled
+ * with net.inet.ip.dummynet.expire=0, or it happens every
+ * expire ticks.
+ **/
+ int drain_fs;
+ int drain_sch;
+ uint32_t expire;
+ uint32_t expire_cycle; /* tick count */
+
+ int init_done;
+
+ /* if the upper half is busy doing something long,
+ * can set the busy flag and we will enqueue packets in
+ * a queue for later processing.
+ */
+ int busy;
+ struct mq pending;
+
+#ifdef _KERNEL
+ /*
+ * This file is normally used in the kernel, unless we do
+ * some userland tests, in which case we do not need a mtx.
+ * uh_mtx arbitrates between system calls and also
+ * protects fshash, schedhash and fsunlinked.
+ * These structures are readonly for the lower half.
+ * bh_mtx protects all other structures which may be
+ * modified upon packet arrivals
+ */
+#if defined( __linux__ ) || defined( _WIN32 )
+ spinlock_t uh_mtx;
+ spinlock_t bh_mtx;
+#else
+ struct mtx uh_mtx;
+ struct mtx bh_mtx;
+#endif
+
+#endif /* _KERNEL */
+};
+
+/*
+ * Delay line, contains all packets on output from a link.
+ * Every scheduler instance has one.
+ */
+struct delay_line {
+ struct dn_id oid;
+ struct dn_sch_inst *si;
+ struct mq mq;
+};
+
+/*
+ * The kernel side of a flowset. It is linked in a hash table
+ * of flowsets, and in a list of children of their parent scheduler.
+ * qht is either the queue or (if HAVE_MASK) a hash table queues.
+ * Note that the mask to use is the (flow_mask|sched_mask), which
+ * changes as we attach/detach schedulers. So we store it here.
+ *
+ * XXX If we want to add scheduler-specific parameters, we need to
+ * put them in external storage because the scheduler may not be
+ * available when the fsk is created.
+ */
+struct dn_fsk { /* kernel side of a flowset */
+ struct dn_fs fs;
+ SLIST_ENTRY(dn_fsk) fsk_next; /* hash chain for fshash */
+
+ struct ipfw_flow_id fsk_mask;
+
+ /* qht is a hash table of queues, or just a single queue
+ * a bit in fs.flags tells us which one
+ */
+ struct dn_ht *qht;
+ struct dn_schk *sched; /* Sched we are linked to */
+ SLIST_ENTRY(dn_fsk) sch_chain; /* list of fsk attached to sched */
+
+ /* bucket index used by drain routine to drain queues for this
+ * flowset
+ */
+ int drain_bucket;
+ /* Parameter realted to RED / GRED */
+ /* original values are in dn_fs*/
+ int w_q ; /* queue weight (scaled) */
+ int max_th ; /* maximum threshold for queue (scaled) */
+ int min_th ; /* minimum threshold for queue (scaled) */
+ int max_p ; /* maximum value for p_b (scaled) */
+
+ u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
+ u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
+ u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
+ u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
+ u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
+ u_int lookup_depth ; /* depth of lookup table */
+ int lookup_step ; /* granularity inside the lookup table */
+ int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
+ int avg_pkt_size ; /* medium packet size */
+ int max_pkt_size ; /* max packet size */
+};
+
+/*
+ * A queue is created as a child of a flowset unless it belongs to
+ * a !MULTIQUEUE scheduler. It is normally in a hash table in the
+ * flowset. fs always points to the parent flowset.
+ * si normally points to the sch_inst, unless the flowset has been
+ * detached from the scheduler -- in this case si == NULL and we
+ * should not enqueue.
+ */
+struct dn_queue {
+ struct dn_flow ni; /* oid, flow_id, stats */
+ struct mq mq; /* packets queue */
+ struct dn_sch_inst *_si; /* owner scheduler instance */
+ SLIST_ENTRY(dn_queue) q_next; /* hash chain list for qht */
+ struct dn_fsk *fs; /* parent flowset. */
+
+ /* RED parameters */
+ int avg; /* average queue length est. (scaled) */
+ int count; /* arrivals since last RED drop */
+ int random; /* random value (scaled) */
+ uint64_t q_time; /* start of queue idle time */
+
+};
+
+/*
+ * The kernel side of a scheduler. Contains the userland config,
+ * a link, pointer to extra config arguments from command line,
+ * kernel flags, and a pointer to the scheduler methods.
+ * It is stored in a hash table, and holds a list of all
+ * flowsets and scheduler instances.
+ * XXX sch must be at the beginning, see schk_hash().
+ */
+struct dn_schk {
+ struct dn_sch sch;
+ struct dn_alg *fp; /* Pointer to scheduler functions */
+ struct dn_link link; /* The link, embedded */
+ struct dn_profile *profile; /* delay profile, if any */
+ struct dn_id *cfg; /* extra config arguments */
+
+ SLIST_ENTRY(dn_schk) schk_next; /* hash chain for schedhash */
+
+ struct dn_fsk_head fsk_list; /* all fsk linked to me */
+ struct dn_fsk *fs; /* Flowset for !MULTIQUEUE */
+
+ /* bucket index used by the drain routine to drain the scheduler
+ * instance for this flowset.
+ */
+ int drain_bucket;
+
+ /* Hash table of all instances (through sch.sched_mask)
+ * or single instance if no mask. Always valid.
+ */
+ struct dn_ht *siht;
+};
+
+
+/*
+ * Scheduler instance.
+ * Contains variables and all queues relative to a this instance.
+ * This struct is created a runtime.
+ */
+struct dn_sch_inst {
+ struct dn_flow ni; /* oid, flowid and stats */
+ SLIST_ENTRY(dn_sch_inst) si_next; /* hash chain for siht */
+ struct delay_line dline;
+ struct dn_schk *sched; /* the template */
+ int kflags; /* DN_ACTIVE */
+
+ int64_t credit; /* bits I can transmit (more or less). */
+ uint64_t sched_time; /* time link was scheduled in ready_heap */
+ uint64_t idle_time; /* start of scheduler instance idle time */
+
+ /* q_count is the number of queues that this instance is using.
+ * The counter is incremented or decremented when
+ * a reference from the queue is created or deleted.
+ * It is used to make sure that a scheduler instance can be safely
+ * deleted by the drain routine. See notes below.
+ */
+ int q_count;
+
+};
+
+/*
+ * NOTE about object drain.
+ * The system will automatically (XXX check when) drain queues and
+ * scheduler instances when they are idle.
+ * A queue is idle when it has no packets; an instance is idle when
+ * it is not in the evheap heap, and the corresponding delay line is empty.
+ * A queue can be safely deleted when it is idle because of the scheduler
+ * function xxx_free_queue() will remove any references to it.
+ * An instance can be only deleted when no queues reference it. To be sure
+ * of that, a counter (q_count) stores the number of queues that are pointing
+ * to the instance.
+ *
+ * XXX
+ * Order of scan:
+ * - take all flowset in a bucket for the flowset hash table
+ * - take all queues in a bucket for the flowset
+ * - increment the queue bucket
+ * - scan next flowset bucket
+ * Nothing is done if a bucket contains no entries.
+ *
+ * The same schema is used for sceduler instances
+ */
+
+
+/* kernel-side flags. Linux has DN_DELETE in fcntl.h
+ */
+enum {
+ /* 1 and 2 are reserved for the SCAN flags */
+ DN_DESTROY = 0x0004, /* destroy */
+ DN_DELETE_FS = 0x0008, /* destroy flowset */
+ DN_DETACH = 0x0010,
+ DN_ACTIVE = 0x0020, /* object is in evheap */
+ DN_F_DLINE = 0x0040, /* object is a delay line */
+ DN_F_SCHI = 0x00C0, /* object is a sched.instance */
+ DN_QHT_IS_Q = 0x0100, /* in flowset, qht is a single queue */
+};
+
+extern struct dn_parms dn_cfg;
+//VNET_DECLARE(struct dn_parms, _base_dn_cfg);
+//#define dn_cfg VNET(_base_dn_cfg)
+
+int dummynet_io(struct mbuf **, int , struct ip_fw_args *);
+void dummynet_task(void *context, int pending);
+void dn_reschedule(void);
+
+struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *,
+ struct ipfw_flow_id *);
+struct dn_sch_inst *ipdn_si_find(struct dn_schk *, struct ipfw_flow_id *);
+
+/*
+ * copy_range is a template for requests for ranges of pipes/queues/scheds.
+ * The number of ranges is variable and can be derived by o.len.
+ * As a default, we use a small number of entries so that the struct
+ * fits easily on the stack and is sufficient for most common requests.
+ */
+#define DEFAULT_RANGES 5
+struct copy_range {
+ struct dn_id o;
+ uint32_t r[ 2 * DEFAULT_RANGES ];
+};
+
+struct copy_args {
+ char **start;
+ char *end;
+ int flags;
+ int type;
+ struct copy_range *extra; /* extra filtering */
+};
+
+struct sockopt;
+int ip_dummynet_compat(struct sockopt *sopt);
+int dummynet_get(struct sockopt *sopt, void **compat);
+int dn_c_copy_q (void *_ni, void *arg);
+int dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq);
+int dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq);
+int dn_compat_copy_queue(struct copy_args *a, void *_o);
+int dn_compat_copy_pipe(struct copy_args *a, void *_o);
+int copy_data_helper_compat(void *_o, void *_arg);
+int dn_compat_calc_size(void);
+int do_config(void *p, int l);
+
+/* function to drain idle object */
+void dn_drain_scheduler(void);
+void dn_drain_queue(void);
+
+#endif /* _IP_DN_PRIVATE_H */
diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c
index 267776f..01714aa 100644
--- a/sys/netinet/ipfw/ip_dummynet.c
+++ b/sys/netinet/ipfw/ip_dummynet.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa
+ * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
* Portions Copyright (c) 2000 Akamba Corp.
* All rights reserved
*
@@ -28,32 +28,12 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#define DUMMYNET_DEBUG
-
-#include "opt_inet6.h"
-
/*
- * This module implements IP dummynet, a bandwidth limiter/delay emulator
- * used in conjunction with the ipfw package.
- * Description of the data structures used is in ip_dummynet.h
- * Here you mainly find the following blocks of code:
- * + variable declarations;
- * + heap management functions;
- * + scheduler and dummynet functions;
- * + configuration and initialization.
- *
- * NOTA BENE: critical sections are protected by the "dummynet lock".
- *
- * Most important Changes:
- *
- * 011004: KLDable
- * 010124: Fixed WF2Q behaviour
- * 010122: Fixed spl protection.
- * 000601: WF2Q support
- * 000106: large rewrite, use heaps to handle very many pipes.
- * 980513: initial release
+ * Configuration and internal object management for dummynet.
*/
+#include "opt_inet6.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -67,2201 +47,2115 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/time.h>
-#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
-#include <net/netisr.h>
#include <netinet/in.h>
-#include <netinet/ip.h> /* ip_len, ip_off */
#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
#include <netinet/ip_fw.h>
#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ipfw/dn_heap.h>
#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+
+/* which objects to copy */
+#define DN_C_LINK 0x01
+#define DN_C_SCH 0x02
+#define DN_C_FLOW 0x04
+#define DN_C_FS 0x08
+#define DN_C_QUEUE 0x10
+
+/* we use this argument in case of a schk_new */
+struct schk_new_arg {
+ struct dn_alg *fp;
+ struct dn_sch *sch;
+};
-#include <netinet/if_ether.h> /* various ether_* routines */
-
-#include <netinet/ip6.h> /* for ip6_input, ip6_output prototypes */
-#include <netinet6/ip6_var.h>
-
-/*
- * We keep a private variable for the simulation time, but we could
- * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
- */
-static dn_key curr_time = 0 ; /* current simulation time */
+/*---- callout hooks. ----*/
+static struct callout dn_timeout;
+static struct task dn_task;
+static struct taskqueue *dn_tq = NULL;
-static int dn_hash_size = 64 ; /* default hash size */
+static void
+dummynet(void * __unused unused)
+{
-/* statistics on number of queue searches and search steps */
-static long searches, search_steps ;
-static int pipe_expire = 1 ; /* expire queue if empty */
-static int dn_max_ratio = 16 ; /* max queues/buckets ratio */
+ taskqueue_enqueue(dn_tq, &dn_task);
+}
-static long pipe_slot_limit = 100; /* Foot shooting limit for pipe queues. */
-static long pipe_byte_limit = 1024 * 1024;
+void
+dn_reschedule(void)
+{
+ callout_reset(&dn_timeout, 1, dummynet, NULL);
+}
+/*----- end of callout hooks -----*/
-static int red_lookup_depth = 256; /* RED - default lookup table depth */
-static int red_avg_pkt_size = 512; /* RED - default medium packet size */
-static int red_max_pkt_size = 1500; /* RED - default max packet size */
+/* Return a scheduler descriptor given the type or name. */
+static struct dn_alg *
+find_sched_type(int type, char *name)
+{
+ struct dn_alg *d;
-static struct timeval prev_t;
-static long tick_last; /* Last tick duration (usec). */
-static long tick_delta; /* Last vs standard tick diff (usec). */
-static long tick_delta_sum; /* Accumulated tick difference (usec).*/
-static long tick_adjustment; /* Tick adjustments done. */
-static long tick_lost; /* Lost(coalesced) ticks number. */
-/* Adjusted vs non-adjusted curr_time difference (ticks). */
-static long tick_diff;
+ SLIST_FOREACH(d, &dn_cfg.schedlist, next) {
+ if (d->type == type || (name && !strcmp(d->name, name)))
+ return d;
+ }
+ return NULL; /* not found */
+}
-static int io_fast;
-static unsigned long io_pkt;
-static unsigned long io_pkt_fast;
-static unsigned long io_pkt_drop;
+int
+ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
+{
+ int oldv = *v;
+ const char *op = NULL;
+ if (oldv < lo) {
+ *v = dflt;
+ op = "Bump";
+ } else if (oldv > hi) {
+ *v = hi;
+ op = "Clamp";
+ } else
+ return *v;
+ if (op && msg)
+ printf("%s %s to %d (was %d)\n", op, msg, *v, oldv);
+ return *v;
+}
+/*---- flow_id mask, hash and compare functions ---*/
/*
- * Three heaps contain queues and pipes that the scheduler handles:
- *
- * ready_heap contains all dn_flow_queue related to fixed-rate pipes.
- *
- * wfq_ready_heap contains the pipes associated with WF2Q flows
- *
- * extract_heap contains pipes associated with delay lines.
- *
+ * The flow_id includes the 5-tuple, the queue/pipe number
+ * which we store in the extra area in host order,
+ * and for ipv6 also the flow_id6.
+ * XXX see if we want the tos byte (can store in 'flags')
*/
+static struct ipfw_flow_id *
+flow_id_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id)
+{
+ int is_v6 = IS_IP6_FLOW_ID(id);
-MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap");
-
-static struct dn_heap ready_heap, extract_heap, wfq_ready_heap ;
-
-static int heap_init(struct dn_heap *h, int size);
-static int heap_insert (struct dn_heap *h, dn_key key1, void *p);
-static void heap_extract(struct dn_heap *h, void *obj);
-static void transmit_event(struct dn_pipe *pipe, struct mbuf **head,
- struct mbuf **tail);
-static void ready_event(struct dn_flow_queue *q, struct mbuf **head,
- struct mbuf **tail);
-static void ready_event_wfq(struct dn_pipe *p, struct mbuf **head,
- struct mbuf **tail);
-
-#define HASHSIZE 16
-#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)
-static struct dn_pipe_head pipehash[HASHSIZE]; /* all pipes */
-static struct dn_flow_set_head flowsethash[HASHSIZE]; /* all flowsets */
-
-static struct callout dn_timeout;
-
-extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
-
-#ifdef SYSCTL_NODE
-SYSCTL_DECL(_net_inet);
-SYSCTL_DECL(_net_inet_ip);
-
-SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size,
- CTLFLAG_RW, &dn_hash_size, 0, "Default hash table size");
-#if 0 /* curr_time is 64 bit */
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, curr_time,
- CTLFLAG_RD, &curr_time, 0, "Current tick");
-#endif
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, ready_heap,
- CTLFLAG_RD, &ready_heap.size, 0, "Size of ready heap");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, extract_heap,
- CTLFLAG_RD, &extract_heap.size, 0, "Size of extract heap");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, searches,
- CTLFLAG_RD, &searches, 0, "Number of queue searches");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, search_steps,
- CTLFLAG_RD, &search_steps, 0, "Number of queue search steps");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire,
- CTLFLAG_RW, &pipe_expire, 0, "Expire queue if empty");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, max_chain_len,
- CTLFLAG_RW, &dn_max_ratio, 0,
- "Max ratio between dynamic queues and buckets");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth,
- CTLFLAG_RD, &red_lookup_depth, 0, "Depth of RED lookup table");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size,
- CTLFLAG_RD, &red_avg_pkt_size, 0, "RED Medium packet size");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size,
- CTLFLAG_RD, &red_max_pkt_size, 0, "RED Max packet size");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta,
- CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec).");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum,
- CTLFLAG_RD, &tick_delta_sum, 0, "Accumulated tick difference (usec).");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_adjustment,
- CTLFLAG_RD, &tick_adjustment, 0, "Tick adjustments done.");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff,
- CTLFLAG_RD, &tick_diff, 0,
- "Adjusted vs non-adjusted curr_time difference (ticks).");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost,
- CTLFLAG_RD, &tick_lost, 0,
- "Number of ticks coalesced by dummynet taskqueue.");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast,
- CTLFLAG_RW, &io_fast, 0, "Enable fast dummynet io.");
-SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt,
- CTLFLAG_RD, &io_pkt, 0,
- "Number of packets passed to dummynet.");
-SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_fast,
- CTLFLAG_RD, &io_pkt_fast, 0,
- "Number of packets bypassed dummynet scheduler.");
-SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
- CTLFLAG_RD, &io_pkt_drop, 0,
- "Number of packets dropped by dummynet.");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit,
- CTLFLAG_RW, &pipe_slot_limit, 0, "Upper limit in slots for pipe queue.");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit,
- CTLFLAG_RW, &pipe_byte_limit, 0, "Upper limit in bytes for pipe queue.");
-#endif
-
-#ifdef DUMMYNET_DEBUG
-int dummynet_debug = 0;
-#ifdef SYSCTL_NODE
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug, CTLFLAG_RW, &dummynet_debug,
- 0, "control debugging printfs");
-#endif
-#define DPRINTF(X) if (dummynet_debug) printf X
-#else
-#define DPRINTF(X)
-#endif
-
-static struct task dn_task;
-static struct taskqueue *dn_tq = NULL;
-static void dummynet_task(void *, int);
-
-static struct mtx dummynet_mtx;
-#define DUMMYNET_LOCK_INIT() \
- mtx_init(&dummynet_mtx, "dummynet", NULL, MTX_DEF)
-#define DUMMYNET_LOCK_DESTROY() mtx_destroy(&dummynet_mtx)
-#define DUMMYNET_LOCK() mtx_lock(&dummynet_mtx)
-#define DUMMYNET_UNLOCK() mtx_unlock(&dummynet_mtx)
-#define DUMMYNET_LOCK_ASSERT() mtx_assert(&dummynet_mtx, MA_OWNED)
-
-static int config_pipe(struct dn_pipe *p);
-static int ip_dn_ctl(struct sockopt *sopt);
-
-static void dummynet(void *);
-static void dummynet_flush(void);
-static void dummynet_send(struct mbuf *);
-static int dummynet_io(struct mbuf **, int , struct ip_fw_args *);
+ id->dst_port &= mask->dst_port;
+ id->src_port &= mask->src_port;
+ id->proto &= mask->proto;
+ id->extra &= mask->extra;
+ if (is_v6) {
+ APPLY_MASK(&id->dst_ip6, &mask->dst_ip6);
+ APPLY_MASK(&id->src_ip6, &mask->src_ip6);
+ id->flow_id6 &= mask->flow_id6;
+ } else {
+ id->dst_ip &= mask->dst_ip;
+ id->src_ip &= mask->src_ip;
+ }
+ return id;
+}
-/*
- * Flow queue is idle if:
- * 1) it's empty for at least 1 tick
- * 2) it has invalid timestamp (WF2Q case)
- * 3) parent pipe has no 'exhausted' burst.
- */
-#define QUEUE_IS_IDLE(q) ((q)->head == NULL && (q)->S == (q)->F + 1 && \
- curr_time > (q)->idle_time + 1 && \
- ((q)->numbytes + (curr_time - (q)->idle_time - 1) * \
- (q)->fs->pipe->bandwidth >= (q)->fs->pipe->burst))
+/* computes an OR of two masks, result in dst and also returned */
+static struct ipfw_flow_id *
+flow_id_or(struct ipfw_flow_id *src, struct ipfw_flow_id *dst)
+{
+ int is_v6 = IS_IP6_FLOW_ID(dst);
-/*
- * Heap management functions.
- *
- * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
- * Some macros help finding parent/children so we can optimize them.
- *
- * heap_init() is called to expand the heap when needed.
- * Increment size in blocks of 16 entries.
- * XXX failure to allocate a new element is a pretty bad failure
- * as we basically stall a whole queue forever!!
- * Returns 1 on error, 0 on success
- */
-#define HEAP_FATHER(x) ( ( (x) - 1 ) / 2 )
-#define HEAP_LEFT(x) ( 2*(x) + 1 )
-#define HEAP_IS_LEFT(x) ( (x) & 1 )
-#define HEAP_RIGHT(x) ( 2*(x) + 2 )
-#define HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; }
-#define HEAP_INCREMENT 15
+ dst->dst_port |= src->dst_port;
+ dst->src_port |= src->src_port;
+ dst->proto |= src->proto;
+ dst->extra |= src->extra;
+ if (is_v6) {
+#define OR_MASK(_d, _s) \
+ (_d)->__u6_addr.__u6_addr32[0] |= (_s)->__u6_addr.__u6_addr32[0]; \
+ (_d)->__u6_addr.__u6_addr32[1] |= (_s)->__u6_addr.__u6_addr32[1]; \
+ (_d)->__u6_addr.__u6_addr32[2] |= (_s)->__u6_addr.__u6_addr32[2]; \
+ (_d)->__u6_addr.__u6_addr32[3] |= (_s)->__u6_addr.__u6_addr32[3];
+ OR_MASK(&dst->dst_ip6, &src->dst_ip6);
+ OR_MASK(&dst->src_ip6, &src->src_ip6);
+#undef OR_MASK
+ dst->flow_id6 |= src->flow_id6;
+ } else {
+ dst->dst_ip |= src->dst_ip;
+ dst->src_ip |= src->src_ip;
+ }
+ return dst;
+}
static int
-heap_init(struct dn_heap *h, int new_size)
+nonzero_mask(struct ipfw_flow_id *m)
{
- struct dn_heap_entry *p;
+ if (m->dst_port || m->src_port || m->proto || m->extra)
+ return 1;
+ if (IS_IP6_FLOW_ID(m)) {
+ return
+ m->dst_ip6.__u6_addr.__u6_addr32[0] ||
+ m->dst_ip6.__u6_addr.__u6_addr32[1] ||
+ m->dst_ip6.__u6_addr.__u6_addr32[2] ||
+ m->dst_ip6.__u6_addr.__u6_addr32[3] ||
+ m->src_ip6.__u6_addr.__u6_addr32[0] ||
+ m->src_ip6.__u6_addr.__u6_addr32[1] ||
+ m->src_ip6.__u6_addr.__u6_addr32[2] ||
+ m->src_ip6.__u6_addr.__u6_addr32[3] ||
+ m->flow_id6;
+ } else {
+ return m->dst_ip || m->src_ip;
+ }
+}
- if (h->size >= new_size ) {
- printf("dummynet: %s, Bogus call, have %d want %d\n", __func__,
- h->size, new_size);
- return 0 ;
- }
- new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT ;
- p = malloc(new_size * sizeof(*p), M_DUMMYNET, M_NOWAIT);
- if (p == NULL) {
- printf("dummynet: %s, resize %d failed\n", __func__, new_size );
- return 1 ; /* error */
- }
- if (h->size > 0) {
- bcopy(h->p, p, h->size * sizeof(*p) );
- free(h->p, M_DUMMYNET);
+/* XXX we may want a better hash function */
+static uint32_t
+flow_id_hash(struct ipfw_flow_id *id)
+{
+ uint32_t i;
+
+ if (IS_IP6_FLOW_ID(id)) {
+ uint32_t *d = (uint32_t *)&id->dst_ip6;
+ uint32_t *s = (uint32_t *)&id->src_ip6;
+ i = (d[0] ) ^ (d[1]) ^
+ (d[2] ) ^ (d[3]) ^
+ (d[0] >> 15) ^ (d[1] >> 15) ^
+ (d[2] >> 15) ^ (d[3] >> 15) ^
+ (s[0] << 1) ^ (s[1] << 1) ^
+ (s[2] << 1) ^ (s[3] << 1) ^
+ (s[0] << 16) ^ (s[1] << 16) ^
+ (s[2] << 16) ^ (s[3] << 16) ^
+ (id->dst_port << 1) ^ (id->src_port) ^
+ (id->extra) ^
+ (id->proto ) ^ (id->flow_id6);
+ } else {
+ i = (id->dst_ip) ^ (id->dst_ip >> 15) ^
+ (id->src_ip << 1) ^ (id->src_ip >> 16) ^
+ (id->extra) ^
+ (id->dst_port << 1) ^ (id->src_port) ^ (id->proto);
}
- h->p = p ;
- h->size = new_size ;
- return 0 ;
+ return i;
}
-/*
- * Insert element in heap. Normally, p != NULL, we insert p in
- * a new position and bubble up. If p == NULL, then the element is
- * already in place, and key is the position where to start the
- * bubble-up.
- * Returns 1 on failure (cannot allocate new heap entry)
- *
- * If offset > 0 the position (index, int) of the element in the heap is
- * also stored in the element itself at the given offset in bytes.
- */
-#define SET_OFFSET(heap, node) \
- if (heap->offset > 0) \
- *((int *)((char *)(heap->p[node].object) + heap->offset)) = node ;
-/*
- * RESET_OFFSET is used for sanity checks. It sets offset to an invalid value.
- */
-#define RESET_OFFSET(heap, node) \
- if (heap->offset > 0) \
- *((int *)((char *)(heap->p[node].object) + heap->offset)) = -1 ;
+/* Like bcmp, returns 0 if ids match, 1 otherwise. */
static int
-heap_insert(struct dn_heap *h, dn_key key1, void *p)
-{
- int son = h->elements ;
-
- if (p == NULL) /* data already there, set starting point */
- son = key1 ;
- else { /* insert new element at the end, possibly resize */
- son = h->elements ;
- if (son == h->size) /* need resize... */
- if (heap_init(h, h->elements+1) )
- return 1 ; /* failure... */
- h->p[son].object = p ;
- h->p[son].key = key1 ;
- h->elements++ ;
- }
- while (son > 0) { /* bubble up */
- int father = HEAP_FATHER(son) ;
- struct dn_heap_entry tmp ;
-
- if (DN_KEY_LT( h->p[father].key, h->p[son].key ) )
- break ; /* found right position */
- /* son smaller than father, swap and repeat */
- HEAP_SWAP(h->p[son], h->p[father], tmp) ;
- SET_OFFSET(h, son);
- son = father ;
- }
- SET_OFFSET(h, son);
- return 0 ;
+flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2)
+{
+ int is_v6 = IS_IP6_FLOW_ID(id1);
+
+ if (!is_v6) {
+ if (IS_IP6_FLOW_ID(id2))
+ return 1; /* different address families */
+
+ return (id1->dst_ip == id2->dst_ip &&
+ id1->src_ip == id2->src_ip &&
+ id1->dst_port == id2->dst_port &&
+ id1->src_port == id2->src_port &&
+ id1->proto == id2->proto &&
+ id1->extra == id2->extra) ? 0 : 1;
+ }
+ /* the ipv6 case */
+ return (
+ !bcmp(&id1->dst_ip6,&id2->dst_ip6, sizeof(id1->dst_ip6)) &&
+ !bcmp(&id1->src_ip6,&id2->src_ip6, sizeof(id1->src_ip6)) &&
+ id1->dst_port == id2->dst_port &&
+ id1->src_port == id2->src_port &&
+ id1->proto == id2->proto &&
+ id1->extra == id2->extra &&
+ id1->flow_id6 == id2->flow_id6) ? 0 : 1;
}
+/*--------- end of flow-id mask, hash and compare ---------*/
-/*
- * remove top element from heap, or obj if obj != NULL
+/*--- support functions for the qht hashtable ----
+ * Entries are hashed by flow-id
*/
-static void
-heap_extract(struct dn_heap *h, void *obj)
+static uint32_t
+q_hash(uintptr_t key, int flags, void *arg)
{
- int child, father, max = h->elements - 1 ;
+ /* compute the hash slot from the flow id */
+ struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
+ &((struct dn_queue *)key)->ni.fid :
+ (struct ipfw_flow_id *)key;
- if (max < 0) {
- printf("dummynet: warning, extract from empty heap 0x%p\n", h);
- return ;
- }
- father = 0 ; /* default: move up smallest child */
- if (obj != NULL) { /* extract specific element, index is at offset */
- if (h->offset <= 0)
- panic("dummynet: heap_extract from middle not supported on this heap!!!\n");
- father = *((int *)((char *)obj + h->offset)) ;
- if (father < 0 || father >= h->elements) {
- printf("dummynet: heap_extract, father %d out of bound 0..%d\n",
- father, h->elements);
- panic("dummynet: heap_extract");
+ return flow_id_hash(id);
+}
+
+static int
+q_match(void *obj, uintptr_t key, int flags, void *arg)
+{
+ struct dn_queue *o = (struct dn_queue *)obj;
+ struct ipfw_flow_id *id2;
+
+ if (flags & DNHT_KEY_IS_OBJ) {
+ /* compare pointers */
+ id2 = &((struct dn_queue *)key)->ni.fid;
+ } else {
+ id2 = (struct ipfw_flow_id *)key;
}
- }
- RESET_OFFSET(h, father);
- child = HEAP_LEFT(father) ; /* left child */
- while (child <= max) { /* valid entry */
- if (child != max && DN_KEY_LT(h->p[child+1].key, h->p[child].key) )
- child = child+1 ; /* take right child, otherwise left */
- h->p[father] = h->p[child] ;
- SET_OFFSET(h, father);
- father = child ;
- child = HEAP_LEFT(child) ; /* left child for next loop */
- }
- h->elements-- ;
- if (father != max) {
- /*
- * Fill hole with last entry and bubble up, reusing the insert code
- */
- h->p[father] = h->p[max] ;
- heap_insert(h, father, NULL); /* this one cannot fail */
- }
+ return (0 == flow_id_cmp(&o->ni.fid, id2));
}
-#if 0
/*
- * change object position and update references
- * XXX this one is never used!
+ * create a new queue instance for the given 'key'.
*/
-static void
-heap_move(struct dn_heap *h, dn_key new_key, void *object)
-{
- int temp;
- int i ;
- int max = h->elements-1 ;
- struct dn_heap_entry buf ;
-
- if (h->offset <= 0)
- panic("cannot move items on this heap");
-
- i = *((int *)((char *)object + h->offset));
- if (DN_KEY_LT(new_key, h->p[i].key) ) { /* must move up */
- h->p[i].key = new_key ;
- for (; i>0 && DN_KEY_LT(new_key, h->p[(temp = HEAP_FATHER(i))].key) ;
- i = temp ) { /* bubble up */
- HEAP_SWAP(h->p[i], h->p[temp], buf) ;
- SET_OFFSET(h, i);
- }
- } else { /* must move down */
- h->p[i].key = new_key ;
- while ( (temp = HEAP_LEFT(i)) <= max ) { /* found left child */
- if ((temp != max) && DN_KEY_GT(h->p[temp].key, h->p[temp+1].key))
- temp++ ; /* select child with min key */
- if (DN_KEY_GT(new_key, h->p[temp].key)) { /* go down */
- HEAP_SWAP(h->p[i], h->p[temp], buf) ;
- SET_OFFSET(h, i);
- } else
- break ;
- i = temp ;
+static void *
+q_new(uintptr_t key, int flags, void *arg)
+{
+ struct dn_queue *q, *template = arg;
+ struct dn_fsk *fs = template->fs;
+ int size = sizeof(*q) + fs->sched->fp->q_datalen;
+
+ q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (q == NULL) {
+ D("no memory for new queue");
+ return NULL;
}
- }
- SET_OFFSET(h, i);
+
+ set_oid(&q->ni.oid, DN_QUEUE, size);
+ if (fs->fs.flags & DN_QHT_HASH)
+ q->ni.fid = *(struct ipfw_flow_id *)key;
+ q->fs = fs;
+ q->_si = template->_si;
+ q->_si->q_count++;
+
+ if (fs->sched->fp->new_queue)
+ fs->sched->fp->new_queue(q);
+ dn_cfg.queue_count++;
+ return q;
}
-#endif /* heap_move, unused */
/*
- * heapify() will reorganize data inside an array to maintain the
- * heap property. It is needed when we delete a bunch of entries.
+ * Notify schedulers that a queue is going away.
+ * If (flags & DN_DESTROY), also free the packets.
+ * The version for callbacks is called q_delete_cb().
*/
static void
-heapify(struct dn_heap *h)
+dn_delete_queue(struct dn_queue *q, int flags)
{
- int i ;
+ struct dn_fsk *fs = q->fs;
+
+ // D("fs %p si %p\n", fs, q->_si);
+ /* notify the parent scheduler that the queue is going away */
+ if (fs && fs->sched->fp->free_queue)
+ fs->sched->fp->free_queue(q);
+ q->_si->q_count--;
+ q->_si = NULL;
+ if (flags & DN_DESTROY) {
+ if (q->mq.head)
+ dn_free_pkts(q->mq.head);
+ bzero(q, sizeof(*q)); // safety
+ free(q, M_DUMMYNET);
+ dn_cfg.queue_count--;
+ }
+}
- for (i = 0 ; i < h->elements ; i++ )
- heap_insert(h, i , NULL) ;
+static int
+q_delete_cb(void *q, void *arg)
+{
+ int flags = (int)(uintptr_t)arg;
+ dn_delete_queue(q, flags);
+ return (flags & DN_DESTROY) ? DNHT_SCAN_DEL : 0;
}
/*
- * cleanup the heap and free data structure
+ * calls dn_delete_queue/q_delete_cb on all queues,
+ * which notifies the parent scheduler and possibly drains packets.
+ * flags & DN_DESTROY: drains queues and destroy qht;
*/
static void
-heap_free(struct dn_heap *h)
+qht_delete(struct dn_fsk *fs, int flags)
{
- if (h->size >0 )
- free(h->p, M_DUMMYNET);
- bzero(h, sizeof(*h) );
+ ND("fs %d start flags %d qht %p",
+ fs->fs.fs_nr, flags, fs->qht);
+ if (!fs->qht)
+ return;
+ if (fs->fs.flags & DN_QHT_HASH) {
+ dn_ht_scan(fs->qht, q_delete_cb, (void *)(uintptr_t)flags);
+ if (flags & DN_DESTROY) {
+ dn_ht_free(fs->qht, 0);
+ fs->qht = NULL;
+ }
+ } else {
+ dn_delete_queue((struct dn_queue *)(fs->qht), flags);
+ if (flags & DN_DESTROY)
+ fs->qht = NULL;
+ }
}
/*
- * --- end of heap management functions ---
+ * Find and possibly create the queue for a MULTIQUEUE scheduler.
+ * We never call it for !MULTIQUEUE (the queue is in the sch_inst).
*/
+struct dn_queue *
+ipdn_q_find(struct dn_fsk *fs, struct dn_sch_inst *si,
+ struct ipfw_flow_id *id)
+{
+ struct dn_queue template;
+
+ template._si = si;
+ template.fs = fs;
+
+ if (fs->fs.flags & DN_QHT_HASH) {
+ struct ipfw_flow_id masked_id;
+ if (fs->qht == NULL) {
+ fs->qht = dn_ht_init(NULL, fs->fs.buckets,
+ offsetof(struct dn_queue, q_next),
+ q_hash, q_match, q_new);
+ if (fs->qht == NULL)
+ return NULL;
+ }
+ masked_id = *id;
+ flow_id_mask(&fs->fsk_mask, &masked_id);
+ return dn_ht_find(fs->qht, (uintptr_t)&masked_id,
+ DNHT_INSERT, &template);
+ } else {
+ if (fs->qht == NULL)
+ fs->qht = q_new(0, 0, &template);
+ return (struct dn_queue *)fs->qht;
+ }
+}
+/*--- end of queue hash table ---*/
-/*
- * Dispose a list of packet. Use an inline functions so if we
- * need to free extra state associated to a packet, this is a
- * central point to do it.
+/*--- support functions for the sch_inst hashtable ----
+ *
+ * These are hashed by flow-id
*/
-
-static __inline void dn_free_pkts(struct mbuf *mnext)
+static uint32_t
+si_hash(uintptr_t key, int flags, void *arg)
{
- struct mbuf *m;
+ /* compute the hash slot from the flow id */
+ struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
+ &((struct dn_sch_inst *)key)->ni.fid :
+ (struct ipfw_flow_id *)key;
- while ((m = mnext) != NULL) {
- mnext = m->m_nextpkt;
- FREE_PKT(m);
- }
+ return flow_id_hash(id);
}
-/*
- * Return the mbuf tag holding the dummynet state. As an optimization
- * this is assumed to be the first tag on the list. If this turns out
- * wrong we'll need to search the list.
- */
-static struct dn_pkt_tag *
-dn_tag_get(struct mbuf *m)
+static int
+si_match(void *obj, uintptr_t key, int flags, void *arg)
{
- struct m_tag *mtag = m_tag_first(m);
- KASSERT(mtag != NULL &&
- mtag->m_tag_cookie == MTAG_ABI_COMPAT &&
- mtag->m_tag_id == PACKET_TAG_DUMMYNET,
- ("packet on dummynet queue w/o dummynet tag!"));
- return (struct dn_pkt_tag *)(mtag+1);
+ struct dn_sch_inst *o = obj;
+ struct ipfw_flow_id *id2;
+
+ id2 = (flags & DNHT_KEY_IS_OBJ) ?
+ &((struct dn_sch_inst *)key)->ni.fid :
+ (struct ipfw_flow_id *)key;
+ return flow_id_cmp(&o->ni.fid, id2) == 0;
}
/*
- * Scheduler functions:
- *
- * transmit_event() is called when the delay-line needs to enter
- * the scheduler, either because of existing pkts getting ready,
- * or new packets entering the queue. The event handled is the delivery
- * time of the packet.
- *
- * ready_event() does something similar with fixed-rate queues, and the
- * event handled is the finish time of the head pkt.
- *
- * wfq_ready_event() does something similar with WF2Q queues, and the
- * event handled is the start time of the head pkt.
- *
- * In all cases, we make sure that the data structures are consistent
- * before passing pkts out, because this might trigger recursive
- * invocations of the procedures.
+ * create a new instance for the given 'key'
+ * Allocate memory for instance, delay line and scheduler private data.
*/
-static void
-transmit_event(struct dn_pipe *pipe, struct mbuf **head, struct mbuf **tail)
+static void *
+si_new(uintptr_t key, int flags, void *arg)
{
- struct mbuf *m;
- struct dn_pkt_tag *pkt;
-
- DUMMYNET_LOCK_ASSERT();
-
- while ((m = pipe->head) != NULL) {
- pkt = dn_tag_get(m);
- if (!DN_KEY_LEQ(pkt->output_time, curr_time))
- break;
-
- pipe->head = m->m_nextpkt;
- if (*tail != NULL)
- (*tail)->m_nextpkt = m;
- else
- *head = m;
- *tail = m;
+ struct dn_schk *s = arg;
+ struct dn_sch_inst *si;
+ int l = sizeof(*si) + s->fp->si_datalen;
+
+ si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (si == NULL)
+ goto error;
+ /* Set length only for the part passed up to userland. */
+ set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct dn_flow));
+ set_oid(&(si->dline.oid), DN_DELAY_LINE,
+ sizeof(struct delay_line));
+ /* mark si and dline as outside the event queue */
+ si->ni.oid.id = si->dline.oid.id = -1;
+
+ si->sched = s;
+ si->dline.si = si;
+
+ if (s->fp->new_sched && s->fp->new_sched(si)) {
+ D("new_sched error");
+ goto error;
}
- if (*tail != NULL)
- (*tail)->m_nextpkt = NULL;
+ if (s->sch.flags & DN_HAVE_MASK)
+ si->ni.fid = *(struct ipfw_flow_id *)key;
- /* If there are leftover packets, put into the heap for next event. */
- if ((m = pipe->head) != NULL) {
- pkt = dn_tag_get(m);
- /*
- * XXX Should check errors on heap_insert, by draining the
- * whole pipe p and hoping in the future we are more successful.
- */
- heap_insert(&extract_heap, pkt->output_time, pipe);
+ dn_cfg.si_count++;
+ return si;
+
+error:
+ if (si) {
+ bzero(si, sizeof(*si)); // safety
+ free(si, M_DUMMYNET);
}
+ return NULL;
}
-#define div64(a, b) ((int64_t)(a) / (int64_t)(b))
/*
- * Compute how many ticks we have to wait before being able to send
- * a packet. This is computed as the "wire time" for the packet
- * (length + extra bits), minus the credit available, scaled to ticks.
- * Check that the result is not be negative (it could be if we have
- * too much leftover credit in q->numbytes).
+ * Callback from siht to delete all scheduler instances. Remove
+ * si and delay line from the system heap, destroy all queues.
+ * We assume that all flowset have been notified and do not
+ * point to us anymore.
*/
-static inline dn_key
-set_ticks(struct mbuf *m, struct dn_flow_queue *q, struct dn_pipe *p)
+static int
+si_destroy(void *_si, void *arg)
{
- int64_t ret;
-
- ret = div64( (m->m_pkthdr.len * 8 + q->extra_bits) * hz
- - q->numbytes + p->bandwidth - 1 , p->bandwidth);
- if (ret < 0)
- ret = 0;
- return ret;
+ struct dn_sch_inst *si = _si;
+ struct dn_schk *s = si->sched;
+ struct delay_line *dl = &si->dline;
+
+ if (dl->oid.subtype) /* remove delay line from event heap */
+ heap_extract(&dn_cfg.evheap, dl);
+ dn_free_pkts(dl->mq.head); /* drain delay line */
+ if (si->kflags & DN_ACTIVE) /* remove si from event heap */
+ heap_extract(&dn_cfg.evheap, si);
+ if (s->fp->free_sched)
+ s->fp->free_sched(si);
+ bzero(si, sizeof(*si)); /* safety */
+ free(si, M_DUMMYNET);
+ dn_cfg.si_count--;
+ return DNHT_SCAN_DEL;
}
/*
- * Convert the additional MAC overheads/delays into an equivalent
- * number of bits for the given data rate. The samples are in milliseconds
- * so we need to divide by 1000.
+ * Find the scheduler instance for this packet. If we need to apply
+ * a mask, do on a local copy of the flow_id to preserve the original.
+ * Assume siht is always initialized if we have a mask.
*/
-static dn_key
-compute_extra_bits(struct mbuf *pkt, struct dn_pipe *p)
+struct dn_sch_inst *
+ipdn_si_find(struct dn_schk *s, struct ipfw_flow_id *id)
{
- int index;
- dn_key extra_bits;
- if (!p->samples || p->samples_no == 0)
- return 0;
- index = random() % p->samples_no;
- extra_bits = div64((dn_key)p->samples[index] * p->bandwidth, 1000);
- if (index >= p->loss_level) {
- struct dn_pkt_tag *dt = dn_tag_get(pkt);
- if (dt)
- dt->dn_dir = DIR_DROP;
+ if (s->sch.flags & DN_HAVE_MASK) {
+ struct ipfw_flow_id id_t = *id;
+ flow_id_mask(&s->sch.sched_mask, &id_t);
+ return dn_ht_find(s->siht, (uintptr_t)&id_t,
+ DNHT_INSERT, s);
}
- return extra_bits;
+ if (!s->siht)
+ s->siht = si_new(0, 0, s);
+ return (struct dn_sch_inst *)s->siht;
}
-static void
-free_pipe(struct dn_pipe *p)
+/* callback to flush credit for the scheduler instance */
+static int
+si_reset_credit(void *_si, void *arg)
{
- if (p->samples)
- free(p->samples, M_DUMMYNET);
- free(p, M_DUMMYNET);
+ struct dn_sch_inst *si = _si;
+ struct dn_link *p = &si->sched->link;
+
+ si->credit = p->burst + (dn_cfg.io_fast ? p->bandwidth : 0);
+ return 0;
}
-/*
- * extract pkt from queue, compute output time (could be now)
- * and put into delay line (p_queue)
- */
static void
-move_pkt(struct mbuf *pkt, struct dn_flow_queue *q, struct dn_pipe *p,
- int len)
+schk_reset_credit(struct dn_schk *s)
{
- struct dn_pkt_tag *dt = dn_tag_get(pkt);
-
- q->head = pkt->m_nextpkt ;
- q->len-- ;
- q->len_bytes -= len ;
-
- dt->output_time = curr_time + p->delay ;
-
- if (p->head == NULL)
- p->head = pkt;
- else
- p->tail->m_nextpkt = pkt;
- p->tail = pkt;
- p->tail->m_nextpkt = NULL;
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, si_reset_credit, NULL);
+ else if (s->siht)
+ si_reset_credit(s->siht, NULL);
}
+/*---- end of sch_inst hashtable ---------------------*/
-/*
- * ready_event() is invoked every time the queue must enter the
- * scheduler, either because the first packet arrives, or because
- * a previously scheduled event fired.
- * On invokation, drain as many pkts as possible (could be 0) and then
- * if there are leftover packets reinsert the pkt in the scheduler.
+/*-------------------------------------------------------
+ * flowset hash (fshash) support. Entries are hashed by fs_nr.
+ * New allocations are put in the fsunlinked list, from which
+ * they are removed when they point to a specific scheduler.
*/
-static void
-ready_event(struct dn_flow_queue *q, struct mbuf **head, struct mbuf **tail)
+static uint32_t
+fsk_hash(uintptr_t key, int flags, void *arg)
{
- struct mbuf *pkt;
- struct dn_pipe *p = q->fs->pipe;
- int p_was_empty;
+ uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_fsk *)key)->fs.fs_nr;
- DUMMYNET_LOCK_ASSERT();
-
- if (p == NULL) {
- printf("dummynet: ready_event- pipe is gone\n");
- return;
- }
- p_was_empty = (p->head == NULL);
+ return ( (i>>8)^(i>>4)^i );
+}
- /*
- * Schedule fixed-rate queues linked to this pipe:
- * account for the bw accumulated since last scheduling, then
- * drain as many pkts as allowed by q->numbytes and move to
- * the delay line (in p) computing output time.
- * bandwidth==0 (no limit) means we can drain the whole queue,
- * setting len_scaled = 0 does the job.
- */
- q->numbytes += (curr_time - q->sched_time) * p->bandwidth;
- while ((pkt = q->head) != NULL) {
- int len = pkt->m_pkthdr.len;
- dn_key len_scaled = p->bandwidth ? len*8*hz
- + q->extra_bits*hz
- : 0;
-
- if (DN_KEY_GT(len_scaled, q->numbytes))
- break;
- q->numbytes -= len_scaled;
- move_pkt(pkt, q, p, len);
- if (q->head)
- q->extra_bits = compute_extra_bits(q->head, p);
- }
- /*
- * If we have more packets queued, schedule next ready event
- * (can only occur when bandwidth != 0, otherwise we would have
- * flushed the whole queue in the previous loop).
- * To this purpose we record the current time and compute how many
- * ticks to go for the finish time of the packet.
- */
- if ((pkt = q->head) != NULL) { /* this implies bandwidth != 0 */
- dn_key t = set_ticks(pkt, q, p); /* ticks i have to wait */
+static int
+fsk_match(void *obj, uintptr_t key, int flags, void *arg)
+{
+ struct dn_fsk *fs = obj;
+ int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_fsk *)key)->fs.fs_nr;
- q->sched_time = curr_time;
- heap_insert(&ready_heap, curr_time + t, (void *)q);
- /*
- * XXX Should check errors on heap_insert, and drain the whole
- * queue on error hoping next time we are luckier.
- */
- } else /* RED needs to know when the queue becomes empty. */
- q->idle_time = curr_time;
+ return (fs->fs.fs_nr == i);
+}
- /*
- * If the delay line was empty call transmit_event() now.
- * Otherwise, the scheduler will take care of it.
- */
- if (p_was_empty)
- transmit_event(p, head, tail);
+static void *
+fsk_new(uintptr_t key, int flags, void *arg)
+{
+ struct dn_fsk *fs;
+
+ fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (fs) {
+ set_oid(&fs->fs.oid, DN_FS, sizeof(fs->fs));
+ dn_cfg.fsk_count++;
+ fs->drain_bucket = 0;
+ SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
+ }
+ return fs;
}
/*
- * Called when we can transmit packets on WF2Q queues. Take pkts out of
- * the queues at their start time, and enqueue into the delay line.
- * Packets are drained until p->numbytes < 0. As long as
- * len_scaled >= p->numbytes, the packet goes into the delay line
- * with a deadline p->delay. For the last packet, if p->numbytes < 0,
- * there is an additional delay.
+ * detach flowset from its current scheduler. Flags as follows:
+ * DN_DETACH removes from the fsk_list
+ * DN_DESTROY deletes individual queues
+ * DN_DELETE_FS destroys the flowset (otherwise goes in unlinked).
*/
static void
-ready_event_wfq(struct dn_pipe *p, struct mbuf **head, struct mbuf **tail)
+fsk_detach(struct dn_fsk *fs, int flags)
{
- int p_was_empty = (p->head == NULL);
- struct dn_heap *sch = &(p->scheduler_heap);
- struct dn_heap *neh = &(p->not_eligible_heap);
- int64_t p_numbytes = p->numbytes;
-
- /*
- * p->numbytes is only 32bits in FBSD7, but we might need 64 bits.
- * Use a local variable for the computations, and write back the
- * results when done, saturating if needed.
- * The local variable has no impact on performance and helps
- * reducing diffs between the various branches.
- */
-
- DUMMYNET_LOCK_ASSERT();
-
- if (p->if_name[0] == 0) /* tx clock is simulated */
- p_numbytes += (curr_time - p->sched_time) * p->bandwidth;
- else { /*
- * tx clock is for real,
- * the ifq must be empty or this is a NOP.
- */
- if (p->ifp && p->ifp->if_snd.ifq_head != NULL)
- return;
- else {
- DPRINTF(("dummynet: pipe %d ready from %s --\n",
- p->pipe_nr, p->if_name));
- }
- }
-
- /*
- * While we have backlogged traffic AND credit, we need to do
- * something on the queue.
- */
- while (p_numbytes >= 0 && (sch->elements > 0 || neh->elements > 0)) {
- if (sch->elements > 0) {
- /* Have some eligible pkts to send out. */
- struct dn_flow_queue *q = sch->p[0].object;
- struct mbuf *pkt = q->head;
- struct dn_flow_set *fs = q->fs;
- uint64_t len = pkt->m_pkthdr.len;
- int len_scaled = p->bandwidth ? len * 8 * hz : 0;
-
- heap_extract(sch, NULL); /* Remove queue from heap. */
- p_numbytes -= len_scaled;
- move_pkt(pkt, q, p, len);
-
- p->V += div64((len << MY_M), p->sum); /* Update V. */
- q->S = q->F; /* Update start time. */
- if (q->len == 0) {
- /* Flow not backlogged any more. */
- fs->backlogged--;
- heap_insert(&(p->idle_heap), q->F, q);
- } else {
- /* Still backlogged. */
-
- /*
- * Update F and position in backlogged queue,
- * then put flow in not_eligible_heap
- * (we will fix this later).
- */
- len = (q->head)->m_pkthdr.len;
- q->F += div64((len << MY_M), fs->weight);
- if (DN_KEY_LEQ(q->S, p->V))
- heap_insert(neh, q->S, q);
- else
- heap_insert(sch, q->F, q);
- }
- }
- /*
- * Now compute V = max(V, min(S_i)). Remember that all elements
- * in sch have by definition S_i <= V so if sch is not empty,
- * V is surely the max and we must not update it. Conversely,
- * if sch is empty we only need to look at neh.
- */
- if (sch->elements == 0 && neh->elements > 0)
- p->V = MAX64(p->V, neh->p[0].key);
- /* Move from neh to sch any packets that have become eligible */
- while (neh->elements > 0 && DN_KEY_LEQ(neh->p[0].key, p->V)) {
- struct dn_flow_queue *q = neh->p[0].object;
- heap_extract(neh, NULL);
- heap_insert(sch, q->F, q);
- }
-
- if (p->if_name[0] != '\0') { /* Tx clock is from a real thing */
- p_numbytes = -1; /* Mark not ready for I/O. */
- break;
- }
+ if (flags & DN_DELETE_FS)
+ flags |= DN_DESTROY;
+ ND("fs %d from sched %d flags %s %s %s",
+ fs->fs.fs_nr, fs->fs.sched_nr,
+ (flags & DN_DELETE_FS) ? "DEL_FS":"",
+ (flags & DN_DESTROY) ? "DEL":"",
+ (flags & DN_DETACH) ? "DET":"");
+ if (flags & DN_DETACH) { /* detach from the list */
+ struct dn_fsk_head *h;
+ h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu;
+ SLIST_REMOVE(h, fs, dn_fsk, sch_chain);
}
- if (sch->elements == 0 && neh->elements == 0 && p_numbytes >= 0) {
- p->idle_time = curr_time;
- /*
- * No traffic and no events scheduled.
- * We can get rid of idle-heap.
- */
- if (p->idle_heap.elements > 0) {
- int i;
-
- for (i = 0; i < p->idle_heap.elements; i++) {
- struct dn_flow_queue *q;
-
- q = p->idle_heap.p[i].object;
- q->F = 0;
- q->S = q->F + 1;
- }
- p->sum = 0;
- p->V = 0;
- p->idle_heap.elements = 0;
- }
- }
- /*
- * If we are getting clocks from dummynet (not a real interface) and
- * If we are under credit, schedule the next ready event.
- * Also fix the delivery time of the last packet.
+ /* Free the RED parameters, they will be recomputed on
+ * subsequent attach if needed.
*/
- if (p->if_name[0]==0 && p_numbytes < 0) { /* This implies bw > 0. */
- dn_key t = 0; /* Number of ticks i have to wait. */
-
- if (p->bandwidth > 0)
- t = div64(p->bandwidth - 1 - p_numbytes, p->bandwidth);
- dn_tag_get(p->tail)->output_time += t;
- p->sched_time = curr_time;
- heap_insert(&wfq_ready_heap, curr_time + t, (void *)p);
- /*
- * XXX Should check errors on heap_insert, and drain the whole
- * queue on error hoping next time we are luckier.
- */
+ if (fs->w_q_lookup)
+ free(fs->w_q_lookup, M_DUMMYNET);
+ fs->w_q_lookup = NULL;
+ qht_delete(fs, flags);
+ if (fs->sched && fs->sched->fp->free_fsk)
+ fs->sched->fp->free_fsk(fs);
+ fs->sched = NULL;
+ if (flags & DN_DELETE_FS) {
+ bzero(fs, sizeof(fs)); /* safety */
+ free(fs, M_DUMMYNET);
+ dn_cfg.fsk_count--;
+ } else {
+ SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
}
-
- /* Write back p_numbytes (adjust 64->32bit if necessary). */
- p->numbytes = p_numbytes;
-
- /*
- * If the delay line was empty call transmit_event() now.
- * Otherwise, the scheduler will take care of it.
- */
- if (p_was_empty)
- transmit_event(p, head, tail);
}
/*
- * This is called one tick, after previous run. It is used to
- * schedule next run.
+ * Detach or destroy all flowsets in a list.
+ * flags specifies what to do:
+ * DN_DESTROY: flush all queues
+ * DN_DELETE_FS: DN_DESTROY + destroy flowset
+ * DN_DELETE_FS implies DN_DESTROY
*/
static void
-dummynet(void * __unused unused)
+fsk_detach_list(struct dn_fsk_head *h, int flags)
{
-
- taskqueue_enqueue(dn_tq, &dn_task);
+ struct dn_fsk *fs;
+ int n = 0; /* only for stats */
+
+ ND("head %p flags %x", h, flags);
+ while ((fs = SLIST_FIRST(h))) {
+ SLIST_REMOVE_HEAD(h, sch_chain);
+ n++;
+ fsk_detach(fs, flags);
+ }
+ ND("done %d flowsets", n);
}
/*
- * The timer handler for dummynet. Time is computed in ticks, but
- * but the code is tolerant to the actual rate at which this is called.
- * Once complete, the function reschedules itself for the next tick.
+ * called on 'queue X delete' -- removes the flowset from fshash,
+ * deletes all queues for the flowset, and removes the flowset.
*/
-static void
-dummynet_task(void *context, int pending)
+static int
+delete_fs(int i, int locked)
{
- struct mbuf *head = NULL, *tail = NULL;
- struct dn_pipe *pipe;
- struct dn_heap *heaps[3];
- struct dn_heap *h;
- void *p; /* generic parameter to handler */
- int i;
- struct timeval t;
-
- DUMMYNET_LOCK();
-
- heaps[0] = &ready_heap; /* fixed-rate queues */
- heaps[1] = &wfq_ready_heap; /* wfq queues */
- heaps[2] = &extract_heap; /* delay line */
-
- /* Update number of lost(coalesced) ticks. */
- tick_lost += pending - 1;
-
- getmicrouptime(&t);
- /* Last tick duration (usec). */
- tick_last = (t.tv_sec - prev_t.tv_sec) * 1000000 +
- (t.tv_usec - prev_t.tv_usec);
- /* Last tick vs standard tick difference (usec). */
- tick_delta = (tick_last * hz - 1000000) / hz;
- /* Accumulated tick difference (usec). */
- tick_delta_sum += tick_delta;
-
- prev_t = t;
-
- /*
- * Adjust curr_time if accumulated tick difference greater than
- * 'standard' tick. Since curr_time should be monotonically increasing,
- * we do positive adjustment as required and throttle curr_time in
- * case of negative adjustment.
- */
- curr_time++;
- if (tick_delta_sum - tick >= 0) {
- int diff = tick_delta_sum / tick;
-
- curr_time += diff;
- tick_diff += diff;
- tick_delta_sum %= tick;
- tick_adjustment++;
- } else if (tick_delta_sum + tick <= 0) {
- curr_time--;
- tick_diff--;
- tick_delta_sum += tick;
- tick_adjustment++;
- }
-
- for (i = 0; i < 3; i++) {
- h = heaps[i];
- while (h->elements > 0 && DN_KEY_LEQ(h->p[0].key, curr_time)) {
- if (h->p[0].key > curr_time)
- printf("dummynet: warning, "
- "heap %d is %d ticks late\n",
- i, (int)(curr_time - h->p[0].key));
- /* store a copy before heap_extract */
- p = h->p[0].object;
- /* need to extract before processing */
- heap_extract(h, NULL);
- if (i == 0)
- ready_event(p, &head, &tail);
- else if (i == 1) {
- struct dn_pipe *pipe = p;
- if (pipe->if_name[0] != '\0')
- printf("dummynet: bad ready_event_wfq "
- "for pipe %s\n", pipe->if_name);
- else
- ready_event_wfq(p, &head, &tail);
- } else
- transmit_event(p, &head, &tail);
- }
- }
-
- /* Sweep pipes trying to expire idle flow_queues. */
- for (i = 0; i < HASHSIZE; i++) {
- SLIST_FOREACH(pipe, &pipehash[i], next) {
- if (pipe->idle_heap.elements > 0 &&
- DN_KEY_LT(pipe->idle_heap.p[0].key, pipe->V)) {
- struct dn_flow_queue *q =
- pipe->idle_heap.p[0].object;
-
- heap_extract(&(pipe->idle_heap), NULL);
- /* Mark timestamp as invalid. */
- q->S = q->F + 1;
- pipe->sum -= q->fs->weight;
- }
- }
- }
-
- DUMMYNET_UNLOCK();
+ struct dn_fsk *fs;
+ int err = 0;
+
+ if (!locked)
+ DN_BH_WLOCK();
+ fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
+ ND("fs %d found %p", i, fs);
+ if (fs) {
+ fsk_detach(fs, DN_DETACH | DN_DELETE_FS);
+ err = 0;
+ } else
+ err = EINVAL;
+ if (!locked)
+ DN_BH_WUNLOCK();
+ return err;
+}
- if (head != NULL)
- dummynet_send(head);
+/*----- end of flowset hashtable support -------------*/
- callout_reset(&dn_timeout, 1, dummynet, NULL);
+/*------------------------------------------------------------
+ * Scheduler hash. When searching by index we pass sched_nr,
+ * otherwise we pass struct dn_sch * which is the first field in
+ * struct dn_schk so we can cast between the two. We use this trick
+ * because in the create phase (but it should be fixed).
+ */
+static uint32_t
+schk_hash(uintptr_t key, int flags, void *_arg)
+{
+ uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_schk *)key)->sch.sched_nr;
+ return ( (i>>8)^(i>>4)^i );
}
-static void
-dummynet_send(struct mbuf *m)
+static int
+schk_match(void *obj, uintptr_t key, int flags, void *_arg)
{
- struct mbuf *n;
-
- for (; m != NULL; m = n) {
- struct ifnet *ifp;
- int dst;
- struct m_tag *tag;
-
- n = m->m_nextpkt;
- m->m_nextpkt = NULL;
- tag = m_tag_first(m);
- if (tag == NULL) {
- dst = DIR_DROP;
- } else {
- struct dn_pkt_tag *pkt = dn_tag_get(m);
- /* extract the dummynet info, rename the tag */
- dst = pkt->dn_dir;
- ifp = pkt->ifp;
- /* rename the tag so it carries reinject info */
- tag->m_tag_cookie = MTAG_IPFW_RULE;
- tag->m_tag_id = 0;
- }
-
- switch (dst) {
- case DIR_OUT:
- SET_HOST_IPLEN(mtod(m, struct ip *));
- ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
- break ;
- case DIR_IN :
- /* put header in network format for ip_input() */
- //SET_NET_IPLEN(mtod(m, struct ip *));
- netisr_dispatch(NETISR_IP, m);
- break;
-#ifdef INET6
- case DIR_IN | PROTO_IPV6:
- netisr_dispatch(NETISR_IPV6, m);
- break;
-
- case DIR_OUT | PROTO_IPV6:
- SET_HOST_IPLEN(mtod(m, struct ip *));
- ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
- break;
-#endif
- case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
- if (bridge_dn_p != NULL)
- ((*bridge_dn_p)(m, ifp));
- else
- printf("dummynet: if_bridge not loaded\n");
-
- break;
- case DIR_IN | PROTO_LAYER2: /* DN_TO_ETH_DEMUX: */
- /*
- * The Ethernet code assumes the Ethernet header is
- * contiguous in the first mbuf header.
- * Insure this is true.
- */
- if (m->m_len < ETHER_HDR_LEN &&
- (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
- printf("dummynet/ether: pullup failed, "
- "dropping packet\n");
- break;
- }
- ether_demux(m->m_pkthdr.rcvif, m);
- break;
- case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
- ether_output_frame(ifp, m);
- break;
-
- case DIR_DROP:
- /* drop the packet after some time */
- FREE_PKT(m);
- break;
-
- default:
- printf("dummynet: bad switch %d!\n", dst);
- FREE_PKT(m);
- break;
- }
- }
+ struct dn_schk *s = (struct dn_schk *)obj;
+ int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_schk *)key)->sch.sched_nr;
+ return (s->sch.sched_nr == i);
}
/*
- * Unconditionally expire empty queues in case of shortage.
- * Returns the number of queues freed.
+ * Create the entry and intialize with the sched hash if needed.
+ * Leave s->fp unset so we can tell whether a dn_ht_find() returns
+ * a new object or a previously existing one.
*/
-static int
-expire_queues(struct dn_flow_set *fs)
-{
- struct dn_flow_queue *q, *prev ;
- int i, initial_elements = fs->rq_elements ;
-
- if (fs->last_expired == time_uptime)
- return 0 ;
- fs->last_expired = time_uptime ;
- for (i = 0 ; i <= fs->rq_size ; i++) { /* last one is overflow */
- for (prev=NULL, q = fs->rq[i] ; q != NULL ; ) {
- if (!QUEUE_IS_IDLE(q)) {
- prev = q ;
- q = q->next ;
- } else { /* entry is idle, expire it */
- struct dn_flow_queue *old_q = q ;
-
- if (prev != NULL)
- prev->next = q = q->next ;
- else
- fs->rq[i] = q = q->next ;
- fs->rq_elements-- ;
- free(old_q, M_DUMMYNET);
- }
+static void *
+schk_new(uintptr_t key, int flags, void *arg)
+{
+ struct schk_new_arg *a = arg;
+ struct dn_schk *s;
+ int l = sizeof(*s) +a->fp->schk_datalen;
+
+ s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s == NULL)
+ return NULL;
+ set_oid(&s->link.oid, DN_LINK, sizeof(s->link));
+ s->sch = *a->sch; // copy initial values
+ s->link.link_nr = s->sch.sched_nr;
+ SLIST_INIT(&s->fsk_list);
+ /* initialize the hash table or create the single instance */
+ s->fp = a->fp; /* si_new needs this */
+ s->drain_bucket = 0;
+ if (s->sch.flags & DN_HAVE_MASK) {
+ s->siht = dn_ht_init(NULL, s->sch.buckets,
+ offsetof(struct dn_sch_inst, si_next),
+ si_hash, si_match, si_new);
+ if (s->siht == NULL) {
+ free(s, M_DUMMYNET);
+ return NULL;
+ }
}
- }
- return initial_elements - fs->rq_elements ;
+ s->fp = NULL; /* mark as a new scheduler */
+ dn_cfg.schk_count++;
+ return s;
}
/*
- * If room, create a new queue and put at head of slot i;
- * otherwise, create or use the default queue.
+ * Callback for sched delete. Notify all attached flowsets to
+ * detach from the scheduler, destroy the internal flowset, and
+ * all instances. The scheduler goes away too.
+ * arg is 0 (only detach flowsets and destroy instances)
+ * DN_DESTROY (detach & delete queues, delete schk)
+ * or DN_DELETE_FS (delete queues and flowsets, delete schk)
*/
-static struct dn_flow_queue *
-create_queue(struct dn_flow_set *fs, int i)
+static int
+schk_delete_cb(void *obj, void *arg)
{
- struct dn_flow_queue *q;
-
- if (fs->rq_elements > fs->rq_size * dn_max_ratio &&
- expire_queues(fs) == 0) {
- /* No way to get room, use or create overflow queue. */
- i = fs->rq_size;
- if (fs->rq[i] != NULL)
- return fs->rq[i];
- }
- q = malloc(sizeof(*q), M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (q == NULL) {
- printf("dummynet: sorry, cannot allocate queue for new flow\n");
- return (NULL);
+ struct dn_schk *s = obj;
+#if 0
+ int a = (int)arg;
+ ND("sched %d arg %s%s",
+ s->sch.sched_nr,
+ a&DN_DESTROY ? "DEL ":"",
+ a&DN_DELETE_FS ? "DEL_FS":"");
+#endif
+ fsk_detach_list(&s->fsk_list, arg ? DN_DESTROY : 0);
+ /* no more flowset pointing to us now */
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, si_destroy, NULL);
+ else if (s->siht)
+ si_destroy(s->siht, NULL);
+ if (s->profile) {
+ free(s->profile, M_DUMMYNET);
+ s->profile = NULL;
}
- q->fs = fs;
- q->hash_slot = i;
- q->next = fs->rq[i];
- q->S = q->F + 1; /* hack - mark timestamp as invalid. */
- q->numbytes = fs->pipe->burst + (io_fast ? fs->pipe->bandwidth : 0);
- fs->rq[i] = q;
- fs->rq_elements++;
- return (q);
+ s->siht = NULL;
+ if (s->fp->destroy)
+ s->fp->destroy(s);
+ bzero(s, sizeof(*s)); // safety
+ free(obj, M_DUMMYNET);
+ dn_cfg.schk_count--;
+ return DNHT_SCAN_DEL;
}
/*
- * Given a flow_set and a pkt in last_pkt, find a matching queue
- * after appropriate masking. The queue is moved to front
- * so that further searches take less time.
+ * called on a 'sched X delete' command. Deletes a single scheduler.
+ * This is done by removing from the schedhash, unlinking all
+ * flowsets and deleting their traffic.
*/
-static struct dn_flow_queue *
-find_queue(struct dn_flow_set *fs, struct ipfw_flow_id *id)
-{
- int i = 0 ; /* we need i and q for new allocations */
- struct dn_flow_queue *q, *prev;
- int is_v6 = IS_IP6_FLOW_ID(id);
-
- if ( !(fs->flags_fs & DN_HAVE_FLOW_MASK) )
- q = fs->rq[0] ;
- else {
- /* first, do the masking, then hash */
- id->dst_port &= fs->flow_mask.dst_port ;
- id->src_port &= fs->flow_mask.src_port ;
- id->proto &= fs->flow_mask.proto ;
- id->flags = 0 ; /* we don't care about this one */
- if (is_v6) {
- APPLY_MASK(&id->dst_ip6, &fs->flow_mask.dst_ip6);
- APPLY_MASK(&id->src_ip6, &fs->flow_mask.src_ip6);
- id->flow_id6 &= fs->flow_mask.flow_id6;
-
- i = ((id->dst_ip6.__u6_addr.__u6_addr32[0]) & 0xffff)^
- ((id->dst_ip6.__u6_addr.__u6_addr32[1]) & 0xffff)^
- ((id->dst_ip6.__u6_addr.__u6_addr32[2]) & 0xffff)^
- ((id->dst_ip6.__u6_addr.__u6_addr32[3]) & 0xffff)^
-
- ((id->dst_ip6.__u6_addr.__u6_addr32[0] >> 15) & 0xffff)^
- ((id->dst_ip6.__u6_addr.__u6_addr32[1] >> 15) & 0xffff)^
- ((id->dst_ip6.__u6_addr.__u6_addr32[2] >> 15) & 0xffff)^
- ((id->dst_ip6.__u6_addr.__u6_addr32[3] >> 15) & 0xffff)^
-
- ((id->src_ip6.__u6_addr.__u6_addr32[0] << 1) & 0xfffff)^
- ((id->src_ip6.__u6_addr.__u6_addr32[1] << 1) & 0xfffff)^
- ((id->src_ip6.__u6_addr.__u6_addr32[2] << 1) & 0xfffff)^
- ((id->src_ip6.__u6_addr.__u6_addr32[3] << 1) & 0xfffff)^
-
- ((id->src_ip6.__u6_addr.__u6_addr32[0] << 16) & 0xffff)^
- ((id->src_ip6.__u6_addr.__u6_addr32[1] << 16) & 0xffff)^
- ((id->src_ip6.__u6_addr.__u6_addr32[2] << 16) & 0xffff)^
- ((id->src_ip6.__u6_addr.__u6_addr32[3] << 16) & 0xffff)^
-
- (id->dst_port << 1) ^ (id->src_port) ^
- (id->proto ) ^
- (id->flow_id6);
- } else {
- id->dst_ip &= fs->flow_mask.dst_ip ;
- id->src_ip &= fs->flow_mask.src_ip ;
-
- i = ( (id->dst_ip) & 0xffff ) ^
- ( (id->dst_ip >> 15) & 0xffff ) ^
- ( (id->src_ip << 1) & 0xffff ) ^
- ( (id->src_ip >> 16 ) & 0xffff ) ^
- (id->dst_port << 1) ^ (id->src_port) ^
- (id->proto );
- }
- i = i % fs->rq_size ;
- /* finally, scan the current list for a match */
- searches++ ;
- for (prev=NULL, q = fs->rq[i] ; q ; ) {
- search_steps++;
- if (is_v6 &&
- IN6_ARE_ADDR_EQUAL(&id->dst_ip6,&q->id.dst_ip6) &&
- IN6_ARE_ADDR_EQUAL(&id->src_ip6,&q->id.src_ip6) &&
- id->dst_port == q->id.dst_port &&
- id->src_port == q->id.src_port &&
- id->proto == q->id.proto &&
- id->flags == q->id.flags &&
- id->flow_id6 == q->id.flow_id6)
- break ; /* found */
-
- if (!is_v6 && id->dst_ip == q->id.dst_ip &&
- id->src_ip == q->id.src_ip &&
- id->dst_port == q->id.dst_port &&
- id->src_port == q->id.src_port &&
- id->proto == q->id.proto &&
- id->flags == q->id.flags)
- break ; /* found */
-
- /* No match. Check if we can expire the entry */
- if (pipe_expire && QUEUE_IS_IDLE(q)) {
- /* entry is idle and not in any heap, expire it */
- struct dn_flow_queue *old_q = q ;
-
- if (prev != NULL)
- prev->next = q = q->next ;
- else
- fs->rq[i] = q = q->next ;
- fs->rq_elements-- ;
- free(old_q, M_DUMMYNET);
- continue ;
- }
- prev = q ;
- q = q->next ;
- }
- if (q && prev != NULL) { /* found and not in front */
- prev->next = q->next ;
- q->next = fs->rq[i] ;
- fs->rq[i] = q ;
- }
- }
- if (q == NULL) { /* no match, need to allocate a new entry */
- q = create_queue(fs, i);
- if (q != NULL)
- q->id = *id ;
- }
- return q ;
+static int
+delete_schk(int i)
+{
+ struct dn_schk *s;
+
+ s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
+ ND("%d %p", i, s);
+ if (!s)
+ return EINVAL;
+ delete_fs(i + DN_MAX_ID, 1); /* first delete internal fs */
+ /* then detach flowsets, delete traffic */
+ schk_delete_cb(s, (void*)(uintptr_t)DN_DESTROY);
+ return 0;
}
+/*--- end of schk hashtable support ---*/
static int
-red_drops(struct dn_flow_set *fs, struct dn_flow_queue *q, int len)
+copy_obj(char **start, char *end, void *_o, const char *msg, int i)
{
- /*
- * RED algorithm
- *
- * RED calculates the average queue size (avg) using a low-pass filter
- * with an exponential weighted (w_q) moving average:
- * avg <- (1-w_q) * avg + w_q * q_size
- * where q_size is the queue length (measured in bytes or * packets).
- *
- * If q_size == 0, we compute the idle time for the link, and set
- * avg = (1 - w_q)^(idle/s)
- * where s is the time needed for transmitting a medium-sized packet.
- *
- * Now, if avg < min_th the packet is enqueued.
- * If avg > max_th the packet is dropped. Otherwise, the packet is
- * dropped with probability P function of avg.
- */
-
- int64_t p_b = 0;
+ struct dn_id *o = _o;
+ int have = end - *start;
- /* Queue in bytes or packets? */
- u_int q_size = (fs->flags_fs & DN_QSIZE_IS_BYTES) ?
- q->len_bytes : q->len;
-
- DPRINTF(("\ndummynet: %d q: %2u ", (int)curr_time, q_size));
-
- /* Average queue size estimation. */
- if (q_size != 0) {
- /* Queue is not empty, avg <- avg + (q_size - avg) * w_q */
- int diff = SCALE(q_size) - q->avg;
- int64_t v = SCALE_MUL((int64_t)diff, (int64_t)fs->w_q);
-
- q->avg += (int)v;
- } else {
- /*
- * Queue is empty, find for how long the queue has been
- * empty and use a lookup table for computing
- * (1 - * w_q)^(idle_time/s) where s is the time to send a
- * (small) packet.
- * XXX check wraps...
- */
- if (q->avg) {
- u_int t = div64(curr_time - q->idle_time,
- fs->lookup_step);
-
- q->avg = (t < fs->lookup_depth) ?
- SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
- }
- }
- DPRINTF(("dummynet: avg: %u ", SCALE_VAL(q->avg)));
-
- /* Should i drop? */
- if (q->avg < fs->min_th) {
- q->count = -1;
- return (0); /* accept packet */
- }
- if (q->avg >= fs->max_th) { /* average queue >= max threshold */
- if (fs->flags_fs & DN_IS_GENTLE_RED) {
- /*
- * According to Gentle-RED, if avg is greater than
- * max_th the packet is dropped with a probability
- * p_b = c_3 * avg - c_4
- * where c_3 = (1 - max_p) / max_th
- * c_4 = 1 - 2 * max_p
- */
- p_b = SCALE_MUL((int64_t)fs->c_3, (int64_t)q->avg) -
- fs->c_4;
- } else {
- q->count = -1;
- DPRINTF(("dummynet: - drop"));
- return (1);
- }
- } else if (q->avg > fs->min_th) {
- /*
- * We compute p_b using the linear dropping function
- * p_b = c_1 * avg - c_2
- * where c_1 = max_p / (max_th - min_th)
- * c_2 = max_p * min_th / (max_th - min_th)
- */
- p_b = SCALE_MUL((int64_t)fs->c_1, (int64_t)q->avg) - fs->c_2;
+ if (have < o->len || o->len == 0 || o->type == 0) {
+ D("(WARN) type %d %s %d have %d need %d",
+ o->type, msg, i, have, o->len);
+ return 1;
}
-
- if (fs->flags_fs & DN_QSIZE_IS_BYTES)
- p_b = div64(p_b * len, fs->max_pkt_size);
- if (++q->count == 0)
- q->random = random() & 0xffff;
- else {
- /*
- * q->count counts packets arrived since last drop, so a greater
- * value of q->count means a greater packet drop probability.
- */
- if (SCALE_MUL(p_b, SCALE((int64_t)q->count)) > q->random) {
- q->count = 0;
- DPRINTF(("dummynet: - red drop"));
- /* After a drop we calculate a new random value. */
- q->random = random() & 0xffff;
- return (1); /* drop */
- }
+ ND("type %d %s %d len %d", o->type, msg, i, o->len);
+ bcopy(_o, *start, o->len);
+ if (o->type == DN_LINK) {
+ /* Adjust burst parameter for link */
+ struct dn_link *l = (struct dn_link *)*start;
+ l->burst = div64(l->burst, 8 * hz);
+ } else if (o->type == DN_SCH) {
+ /* Set id->id to the number of instances */
+ struct dn_schk *s = _o;
+ struct dn_id *id = (struct dn_id *)(*start);
+ id->id = (s->sch.flags & DN_HAVE_MASK) ?
+ dn_ht_entries(s->siht) : (s->siht ? 1 : 0);
}
- /* End of RED algorithm. */
-
- return (0); /* accept */
+ *start += o->len;
+ return 0;
}
-static __inline struct dn_flow_set *
-locate_flowset(int fs_nr)
+/* Specific function to copy a queue.
+ * Copies only the user-visible part of a queue (which is in
+ * a struct dn_flow), and sets len accordingly.
+ */
+static int
+copy_obj_q(char **start, char *end, void *_o, const char *msg, int i)
{
- struct dn_flow_set *fs;
-
- SLIST_FOREACH(fs, &flowsethash[HASH(fs_nr)], next)
- if (fs->fs_nr == fs_nr)
- return (fs);
-
- return (NULL);
+ struct dn_id *o = _o;
+ int have = end - *start;
+ int len = sizeof(struct dn_flow); /* see above comment */
+
+ if (have < len || o->len == 0 || o->type != DN_QUEUE) {
+ D("ERROR type %d %s %d have %d need %d",
+ o->type, msg, i, have, len);
+ return 1;
+ }
+ ND("type %d %s %d len %d", o->type, msg, i, len);
+ bcopy(_o, *start, len);
+ ((struct dn_id*)(*start))->len = len;
+ *start += len;
+ return 0;
}
-static __inline struct dn_pipe *
-locate_pipe(int pipe_nr)
+static int
+copy_q_cb(void *obj, void *arg)
{
- struct dn_pipe *pipe;
-
- SLIST_FOREACH(pipe, &pipehash[HASH(pipe_nr)], next)
- if (pipe->pipe_nr == pipe_nr)
- return (pipe);
-
- return (NULL);
+ struct dn_queue *q = obj;
+ struct copy_args *a = arg;
+ struct dn_flow *ni = (struct dn_flow *)(*a->start);
+ if (copy_obj_q(a->start, a->end, &q->ni, "queue", -1))
+ return DNHT_SCAN_END;
+ ni->oid.type = DN_FLOW; /* override the DN_QUEUE */
+ ni->oid.id = si_hash((uintptr_t)&ni->fid, 0, NULL);
+ return 0;
}
-/*
- * dummynet hook for packets. Below 'pipe' is a pipe or a queue
- * depending on whether WF2Q or fixed bw is used.
- *
- * pipe_nr pipe or queue the packet is destined for.
- * dir where shall we send the packet after dummynet.
- * m the mbuf with the packet
- * ifp the 'ifp' parameter from the caller.
- * NULL in ip_input, destination interface in ip_output,
- * rule matching rule, in case of multiple passes
- */
static int
-dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
-{
- struct mbuf *m = *m0, *head = NULL, *tail = NULL;
- struct dn_pkt_tag *pkt;
- struct m_tag *mtag;
- struct dn_flow_set *fs = NULL;
- struct dn_pipe *pipe;
- uint64_t len = m->m_pkthdr.len;
- struct dn_flow_queue *q = NULL;
- int is_pipe = fwa->rule.info & IPFW_IS_PIPE;
-
- KASSERT(m->m_nextpkt == NULL,
- ("dummynet_io: mbuf queue passed to dummynet"));
-
- DUMMYNET_LOCK();
- io_pkt++;
- /*
- * This is a dummynet rule, so we expect an O_PIPE or O_QUEUE rule.
- */
- if (is_pipe) {
- pipe = locate_pipe(fwa->rule.info & IPFW_INFO_MASK);
- if (pipe != NULL)
- fs = &(pipe->fs);
- } else
- fs = locate_flowset(fwa->rule.info & IPFW_INFO_MASK);
-
- if (fs == NULL)
- goto dropit; /* This queue/pipe does not exist! */
- pipe = fs->pipe;
- if (pipe == NULL) { /* Must be a queue, try find a matching pipe. */
- pipe = locate_pipe(fs->parent_nr);
- if (pipe != NULL)
- fs->pipe = pipe;
- else {
- printf("dummynet: no pipe %d for queue %d, drop pkt\n",
- fs->parent_nr, fs->fs_nr);
- goto dropit;
- }
- }
- q = find_queue(fs, &(fwa->f_id));
- if (q == NULL)
- goto dropit; /* Cannot allocate queue. */
-
- /* Update statistics, then check reasons to drop pkt. */
- q->tot_bytes += len;
- q->tot_pkts++;
- if (fs->plr && random() < fs->plr)
- goto dropit; /* Random pkt drop. */
- if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
- if (q->len_bytes > fs->qsize)
- goto dropit; /* Queue size overflow. */
- } else {
- if (q->len >= fs->qsize)
- goto dropit; /* Queue count overflow. */
- }
- if (fs->flags_fs & DN_IS_RED && red_drops(fs, q, len))
- goto dropit;
-
- /* XXX expensive to zero, see if we can remove it. */
- mtag = m_tag_get(PACKET_TAG_DUMMYNET,
- sizeof(struct dn_pkt_tag), M_NOWAIT | M_ZERO);
- if (mtag == NULL)
- goto dropit; /* Cannot allocate packet header. */
- m_tag_prepend(m, mtag); /* Attach to mbuf chain. */
-
- pkt = (struct dn_pkt_tag *)(mtag + 1);
- /*
- * Ok, i can handle the pkt now...
- * Build and enqueue packet + parameters.
- */
- pkt->rule = fwa->rule;
- pkt->rule.info &= IPFW_ONEPASS; /* only keep this info */
- pkt->dn_dir = dir;
- pkt->ifp = fwa->oif;
-
- if (q->head == NULL)
- q->head = m;
+copy_q(struct copy_args *a, struct dn_fsk *fs, int flags)
+{
+ if (!fs->qht)
+ return 0;
+ if (fs->fs.flags & DN_QHT_HASH)
+ dn_ht_scan(fs->qht, copy_q_cb, a);
else
- q->tail->m_nextpkt = m;
- q->tail = m;
- q->len++;
- q->len_bytes += len;
-
- if (q->head != m) /* Flow was not idle, we are done. */
- goto done;
-
- if (is_pipe) { /* Fixed rate queues. */
- if (q->idle_time < curr_time) {
- /* Calculate available burst size. */
- q->numbytes +=
- (curr_time - q->idle_time - 1) * pipe->bandwidth;
- if (q->numbytes > pipe->burst)
- q->numbytes = pipe->burst;
- if (io_fast)
- q->numbytes += pipe->bandwidth;
- }
- } else { /* WF2Q. */
- if (pipe->idle_time < curr_time &&
- pipe->scheduler_heap.elements == 0 &&
- pipe->not_eligible_heap.elements == 0) {
- /* Calculate available burst size. */
- pipe->numbytes +=
- (curr_time - pipe->idle_time - 1) * pipe->bandwidth;
- if (pipe->numbytes > 0 && pipe->numbytes > pipe->burst)
- pipe->numbytes = pipe->burst;
- if (io_fast)
- pipe->numbytes += pipe->bandwidth;
- }
- pipe->idle_time = curr_time;
- }
- /* Necessary for both: fixed rate & WF2Q queues. */
- q->idle_time = curr_time;
-
- /*
- * If we reach this point the flow was previously idle, so we need
- * to schedule it. This involves different actions for fixed-rate or
- * WF2Q queues.
- */
- if (is_pipe) {
- /* Fixed-rate queue: just insert into the ready_heap. */
- dn_key t = 0;
-
- if (pipe->bandwidth) {
- q->extra_bits = compute_extra_bits(m, pipe);
- t = set_ticks(m, q, pipe);
- }
- q->sched_time = curr_time;
- if (t == 0) /* Must process it now. */
- ready_event(q, &head, &tail);
- else
- heap_insert(&ready_heap, curr_time + t , q);
- } else {
- /*
- * WF2Q. First, compute start time S: if the flow was
- * idle (S = F + 1) set S to the virtual time V for the
- * controlling pipe, and update the sum of weights for the pipe;
- * otherwise, remove flow from idle_heap and set S to max(F,V).
- * Second, compute finish time F = S + len / weight.
- * Third, if pipe was idle, update V = max(S, V).
- * Fourth, count one more backlogged flow.
- */
- if (DN_KEY_GT(q->S, q->F)) { /* Means timestamps are invalid. */
- q->S = pipe->V;
- pipe->sum += fs->weight; /* Add weight of new queue. */
- } else {
- heap_extract(&(pipe->idle_heap), q);
- q->S = MAX64(q->F, pipe->V);
- }
- q->F = q->S + div64(len << MY_M, fs->weight);
-
- if (pipe->not_eligible_heap.elements == 0 &&
- pipe->scheduler_heap.elements == 0)
- pipe->V = MAX64(q->S, pipe->V);
- fs->backlogged++;
- /*
- * Look at eligibility. A flow is not eligibile if S>V (when
- * this happens, it means that there is some other flow already
- * scheduled for the same pipe, so the scheduler_heap cannot be
- * empty). If the flow is not eligible we just store it in the
- * not_eligible_heap. Otherwise, we store in the scheduler_heap
- * and possibly invoke ready_event_wfq() right now if there is
- * leftover credit.
- * Note that for all flows in scheduler_heap (SCH), S_i <= V,
- * and for all flows in not_eligible_heap (NEH), S_i > V.
- * So when we need to compute max(V, min(S_i)) forall i in
- * SCH+NEH, we only need to look into NEH.
- */
- if (DN_KEY_GT(q->S, pipe->V)) { /* Not eligible. */
- if (pipe->scheduler_heap.elements == 0)
- printf("dummynet: ++ ouch! not eligible but empty scheduler!\n");
- heap_insert(&(pipe->not_eligible_heap), q->S, q);
- } else {
- heap_insert(&(pipe->scheduler_heap), q->F, q);
- if (pipe->numbytes >= 0) { /* Pipe is idle. */
- if (pipe->scheduler_heap.elements != 1)
- printf("dummynet: OUCH! pipe should have been idle!\n");
- DPRINTF(("dummynet: waking up pipe %d at %d\n",
- pipe->pipe_nr, (int)(q->F >> MY_M)));
- pipe->sched_time = curr_time;
- ready_event_wfq(pipe, &head, &tail);
- }
- }
- }
-done:
- if (head == m && (dir & PROTO_LAYER2) == 0 ) {
- /* Fast io. */
- io_pkt_fast++;
- if (m->m_nextpkt != NULL)
- printf("dummynet: fast io: pkt chain detected!\n");
- head = m->m_nextpkt = NULL;
- } else
- *m0 = NULL; /* Normal io. */
-
- DUMMYNET_UNLOCK();
- if (head != NULL)
- dummynet_send(head);
- return (0);
-
-dropit:
- io_pkt_drop++;
- if (q)
- q->drops++;
- DUMMYNET_UNLOCK();
- FREE_PKT(m);
- *m0 = NULL;
- return ((fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
+ copy_q_cb(fs->qht, a);
+ return 0;
}
/*
- * Dispose all packets and flow_queues on a flow_set.
- * If all=1, also remove red lookup table and other storage,
- * including the descriptor itself.
- * For the one in dn_pipe MUST also cleanup ready_heap...
+ * This routine only copies the initial part of a profile ? XXX
*/
-static void
-purge_flow_set(struct dn_flow_set *fs, int all)
+static int
+copy_profile(struct copy_args *a, struct dn_profile *p)
{
- struct dn_flow_queue *q, *qn;
- int i;
-
- DUMMYNET_LOCK_ASSERT();
+ int have = a->end - *a->start;
+ /* XXX here we check for max length */
+ int profile_len = sizeof(struct dn_profile) -
+ ED_MAX_SAMPLES_NO*sizeof(int);
- for (i = 0; i <= fs->rq_size; i++) {
- for (q = fs->rq[i]; q != NULL; q = qn) {
- dn_free_pkts(q->head);
- qn = q->next;
- free(q, M_DUMMYNET);
- }
- fs->rq[i] = NULL;
+ if (p == NULL)
+ return 0;
+ if (have < profile_len) {
+ D("error have %d need %d", have, profile_len);
+ return 1;
}
+ bcopy(p, *a->start, profile_len);
+ ((struct dn_id *)(*a->start))->len = profile_len;
+ *a->start += profile_len;
+ return 0;
+}
- fs->rq_elements = 0;
- if (all) {
- /* RED - free lookup table. */
- if (fs->w_q_lookup != NULL)
- free(fs->w_q_lookup, M_DUMMYNET);
- if (fs->rq != NULL)
- free(fs->rq, M_DUMMYNET);
- /* If this fs is not part of a pipe, free it. */
- if (fs->pipe == NULL || fs != &(fs->pipe->fs))
- free(fs, M_DUMMYNET);
+static int
+copy_flowset(struct copy_args *a, struct dn_fsk *fs, int flags)
+{
+ struct dn_fs *ufs = (struct dn_fs *)(*a->start);
+ if (!fs)
+ return 0;
+ ND("flowset %d", fs->fs.fs_nr);
+ if (copy_obj(a->start, a->end, &fs->fs, "flowset", fs->fs.fs_nr))
+ return DNHT_SCAN_END;
+ ufs->oid.id = (fs->fs.flags & DN_QHT_HASH) ?
+ dn_ht_entries(fs->qht) : (fs->qht ? 1 : 0);
+ if (flags) { /* copy queues */
+ copy_q(a, fs, 0);
}
+ return 0;
}
-/*
- * Dispose all packets queued on a pipe (not a flow_set).
- * Also free all resources associated to a pipe, which is about
- * to be deleted.
- */
-static void
-purge_pipe(struct dn_pipe *pipe)
+static int
+copy_si_cb(void *obj, void *arg)
{
+ struct dn_sch_inst *si = obj;
+ struct copy_args *a = arg;
+ struct dn_flow *ni = (struct dn_flow *)(*a->start);
+ if (copy_obj(a->start, a->end, &si->ni, "inst",
+ si->sched->sch.sched_nr))
+ return DNHT_SCAN_END;
+ ni->oid.type = DN_FLOW; /* override the DN_SCH_I */
+ ni->oid.id = si_hash((uintptr_t)si, DNHT_KEY_IS_OBJ, NULL);
+ return 0;
+}
- purge_flow_set( &(pipe->fs), 1 );
-
- dn_free_pkts(pipe->head);
-
- heap_free( &(pipe->scheduler_heap) );
- heap_free( &(pipe->not_eligible_heap) );
- heap_free( &(pipe->idle_heap) );
+static int
+copy_si(struct copy_args *a, struct dn_schk *s, int flags)
+{
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, copy_si_cb, a);
+ else if (s->siht)
+ copy_si_cb(s->siht, a);
+ return 0;
}
/*
- * Delete all pipes and heaps returning memory. Must also
- * remove references from all ipfw rules to all pipes.
+ * compute a list of children of a scheduler and copy up
*/
-static void
-dummynet_flush(void)
+static int
+copy_fsk_list(struct copy_args *a, struct dn_schk *s, int flags)
{
- struct dn_pipe *pipe, *pipe1;
- struct dn_flow_set *fs, *fs1;
- int i;
-
- DUMMYNET_LOCK();
- /* Free heaps so we don't have unwanted events. */
- heap_free(&ready_heap);
- heap_free(&wfq_ready_heap);
- heap_free(&extract_heap);
+ struct dn_fsk *fs;
+ struct dn_id *o;
+ uint32_t *p;
+
+ int n = 0, space = sizeof(*o);
+ SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
+ if (fs->fs.fs_nr < DN_MAX_ID)
+ n++;
+ }
+ space += n * sizeof(uint32_t);
+ DX(3, "sched %d has %d flowsets", s->sch.sched_nr, n);
+ if (a->end - *(a->start) < space)
+ return DNHT_SCAN_END;
+ o = (struct dn_id *)(*(a->start));
+ o->len = space;
+ *a->start += o->len;
+ o->type = DN_TEXT;
+ p = (uint32_t *)(o+1);
+ SLIST_FOREACH(fs, &s->fsk_list, sch_chain)
+ if (fs->fs.fs_nr < DN_MAX_ID)
+ *p++ = fs->fs.fs_nr;
+ return 0;
+}
- /*
- * Now purge all queued pkts and delete all pipes.
- *
- * XXXGL: can we merge the for(;;) cycles into one or not?
- */
- for (i = 0; i < HASHSIZE; i++)
- SLIST_FOREACH_SAFE(fs, &flowsethash[i], next, fs1) {
- SLIST_REMOVE(&flowsethash[i], fs, dn_flow_set, next);
- purge_flow_set(fs, 1);
+static int
+copy_data_helper(void *_o, void *_arg)
+{
+ struct copy_args *a = _arg;
+ uint32_t *r = a->extra->r; /* start of first range */
+ uint32_t *lim; /* first invalid pointer */
+ int n;
+
+ lim = (uint32_t *)((char *)(a->extra) + a->extra->o.len);
+
+ if (a->type == DN_LINK || a->type == DN_SCH) {
+ /* pipe|sched show, we receive a dn_schk */
+ struct dn_schk *s = _o;
+
+ n = s->sch.sched_nr;
+ if (a->type == DN_SCH && n >= DN_MAX_ID)
+ return 0; /* not a scheduler */
+ if (a->type == DN_LINK && n <= DN_MAX_ID)
+ return 0; /* not a pipe */
+
+ /* see if the object is within one of our ranges */
+ for (;r < lim; r += 2) {
+ if (n < r[0] || n > r[1])
+ continue;
+ /* Found a valid entry, copy and we are done */
+ if (a->flags & DN_C_LINK) {
+ if (copy_obj(a->start, a->end,
+ &s->link, "link", n))
+ return DNHT_SCAN_END;
+ if (copy_profile(a, s->profile))
+ return DNHT_SCAN_END;
+ if (copy_flowset(a, s->fs, 0))
+ return DNHT_SCAN_END;
+ }
+ if (a->flags & DN_C_SCH) {
+ if (copy_obj(a->start, a->end,
+ &s->sch, "sched", n))
+ return DNHT_SCAN_END;
+ /* list all attached flowsets */
+ if (copy_fsk_list(a, s, 0))
+ return DNHT_SCAN_END;
+ }
+ if (a->flags & DN_C_FLOW)
+ copy_si(a, s, 0);
+ break;
}
- for (i = 0; i < HASHSIZE; i++)
- SLIST_FOREACH_SAFE(pipe, &pipehash[i], next, pipe1) {
- SLIST_REMOVE(&pipehash[i], pipe, dn_pipe, next);
- purge_pipe(pipe);
- free_pipe(pipe);
+ } else if (a->type == DN_FS) {
+ /* queue show, skip internal flowsets */
+ struct dn_fsk *fs = _o;
+
+ n = fs->fs.fs_nr;
+ if (n >= DN_MAX_ID)
+ return 0;
+ /* see if the object is within one of our ranges */
+ for (;r < lim; r += 2) {
+ if (n < r[0] || n > r[1])
+ continue;
+ if (copy_flowset(a, fs, 0))
+ return DNHT_SCAN_END;
+ copy_q(a, fs, 0);
+ break; /* we are done */
}
- DUMMYNET_UNLOCK();
+ }
+ return 0;
+}
+
+static inline struct dn_schk *
+locate_scheduler(int i)
+{
+ return dn_ht_find(dn_cfg.schedhash, i, 0, NULL);
}
/*
- * setup RED parameters
+ * red parameters are in fixed point arithmetic.
*/
static int
-config_red(struct dn_flow_set *p, struct dn_flow_set *x)
+config_red(struct dn_fsk *fs)
{
- int i;
-
- x->w_q = p->w_q;
- x->min_th = SCALE(p->min_th);
- x->max_th = SCALE(p->max_th);
- x->max_p = p->max_p;
-
- x->c_1 = p->max_p / (p->max_th - p->min_th);
- x->c_2 = SCALE_MUL(x->c_1, SCALE(p->min_th));
-
- if (x->flags_fs & DN_IS_GENTLE_RED) {
- x->c_3 = (SCALE(1) - p->max_p) / p->max_th;
- x->c_4 = SCALE(1) - 2 * p->max_p;
+ int64_t s, idle, weight, w0;
+ int t, i;
+
+ fs->w_q = fs->fs.w_q;
+ fs->max_p = fs->fs.max_p;
+ D("called");
+ /* Doing stuff that was in userland */
+ i = fs->sched->link.bandwidth;
+ s = (i <= 0) ? 0 :
+ hz * dn_cfg.red_avg_pkt_size * 8 * SCALE(1) / i;
+
+ idle = div64((s * 3) , fs->w_q); /* s, fs->w_q scaled; idle not scaled */
+ fs->lookup_step = div64(idle , dn_cfg.red_lookup_depth);
+ /* fs->lookup_step not scaled, */
+ if (!fs->lookup_step)
+ fs->lookup_step = 1;
+ w0 = weight = SCALE(1) - fs->w_q; //fs->w_q scaled
+
+ for (t = fs->lookup_step; t > 1; --t)
+ weight = SCALE_MUL(weight, w0);
+ fs->lookup_weight = (int)(weight); // scaled
+
+ /* Now doing stuff that was in kerneland */
+ fs->min_th = SCALE(fs->fs.min_th);
+ fs->max_th = SCALE(fs->fs.max_th);
+
+ fs->c_1 = fs->max_p / (fs->fs.max_th - fs->fs.min_th);
+ fs->c_2 = SCALE_MUL(fs->c_1, SCALE(fs->fs.min_th));
+
+ if (fs->fs.flags & DN_IS_GENTLE_RED) {
+ fs->c_3 = (SCALE(1) - fs->max_p) / fs->fs.max_th;
+ fs->c_4 = SCALE(1) - 2 * fs->max_p;
}
/* If the lookup table already exist, free and create it again. */
- if (x->w_q_lookup) {
- free(x->w_q_lookup, M_DUMMYNET);
- x->w_q_lookup = NULL;
+ if (fs->w_q_lookup) {
+ free(fs->w_q_lookup, M_DUMMYNET);
+ fs->w_q_lookup = NULL;
}
- if (red_lookup_depth == 0) {
+ if (dn_cfg.red_lookup_depth == 0) {
printf("\ndummynet: net.inet.ip.dummynet.red_lookup_depth"
"must be > 0\n");
- free(x, M_DUMMYNET);
+ fs->fs.flags &= ~DN_IS_RED;
+ fs->fs.flags &= ~DN_IS_GENTLE_RED;
return (EINVAL);
}
- x->lookup_depth = red_lookup_depth;
- x->w_q_lookup = (u_int *)malloc(x->lookup_depth * sizeof(int),
+ fs->lookup_depth = dn_cfg.red_lookup_depth;
+ fs->w_q_lookup = (u_int *)malloc(fs->lookup_depth * sizeof(int),
M_DUMMYNET, M_NOWAIT);
- if (x->w_q_lookup == NULL) {
+ if (fs->w_q_lookup == NULL) {
printf("dummynet: sorry, cannot allocate red lookup table\n");
- free(x, M_DUMMYNET);
+ fs->fs.flags &= ~DN_IS_RED;
+ fs->fs.flags &= ~DN_IS_GENTLE_RED;
return(ENOSPC);
}
/* Fill the lookup table with (1 - w_q)^x */
- x->lookup_step = p->lookup_step;
- x->lookup_weight = p->lookup_weight;
- x->w_q_lookup[0] = SCALE(1) - x->w_q;
-
- for (i = 1; i < x->lookup_depth; i++)
- x->w_q_lookup[i] =
- SCALE_MUL(x->w_q_lookup[i - 1], x->lookup_weight);
+ fs->w_q_lookup[0] = SCALE(1) - fs->w_q;
+
+ for (i = 1; i < fs->lookup_depth; i++)
+ fs->w_q_lookup[i] =
+ SCALE_MUL(fs->w_q_lookup[i - 1], fs->lookup_weight);
+
+ if (dn_cfg.red_avg_pkt_size < 1)
+ dn_cfg.red_avg_pkt_size = 512;
+ fs->avg_pkt_size = dn_cfg.red_avg_pkt_size;
+ if (dn_cfg.red_max_pkt_size < 1)
+ dn_cfg.red_max_pkt_size = 1500;
+ fs->max_pkt_size = dn_cfg.red_max_pkt_size;
+ D("exit");
+ return 0;
+}
- if (red_avg_pkt_size < 1)
- red_avg_pkt_size = 512;
- x->avg_pkt_size = red_avg_pkt_size;
- if (red_max_pkt_size < 1)
- red_max_pkt_size = 1500;
- x->max_pkt_size = red_max_pkt_size;
- return (0);
+/* Scan all flowset attached to this scheduler and update red */
+static void
+update_red(struct dn_schk *s)
+{
+ struct dn_fsk *fs;
+ SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
+ if (fs && (fs->fs.flags & DN_IS_RED))
+ config_red(fs);
+ }
}
-static int
-alloc_hash(struct dn_flow_set *x, struct dn_flow_set *pfs)
-{
- if (x->flags_fs & DN_HAVE_FLOW_MASK) { /* allocate some slots */
- int l = pfs->rq_size;
-
- if (l == 0)
- l = dn_hash_size;
- if (l < 4)
- l = 4;
- else if (l > DN_MAX_HASH_SIZE)
- l = DN_MAX_HASH_SIZE;
- x->rq_size = l;
- } else /* one is enough for null mask */
- x->rq_size = 1;
- x->rq = malloc((1 + x->rq_size) * sizeof(struct dn_flow_queue *),
- M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (x->rq == NULL) {
- printf("dummynet: sorry, cannot allocate queue\n");
- return (ENOMEM);
- }
- x->rq_elements = 0;
- return 0 ;
+/* attach flowset to scheduler s, possibly requeue */
+static void
+fsk_attach(struct dn_fsk *fs, struct dn_schk *s)
+{
+ ND("remove fs %d from fsunlinked, link to sched %d",
+ fs->fs.fs_nr, s->sch.sched_nr);
+ SLIST_REMOVE(&dn_cfg.fsu, fs, dn_fsk, sch_chain);
+ fs->sched = s;
+ SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
+ if (s->fp->new_fsk)
+ s->fp->new_fsk(fs);
+ /* XXX compute fsk_mask */
+ fs->fsk_mask = fs->fs.flow_mask;
+ if (fs->sched->sch.flags & DN_HAVE_MASK)
+ flow_id_or(&fs->sched->sch.sched_mask, &fs->fsk_mask);
+ if (fs->qht) {
+ /*
+ * we must drain qht according to the old
+ * type, and reinsert according to the new one.
+ * The requeue is complex -- in general we need to
+ * reclassify every single packet.
+ * For the time being, let's hope qht is never set
+ * when we reach this point.
+ */
+ D("XXX TODO requeue from fs %d to sch %d",
+ fs->fs.fs_nr, s->sch.sched_nr);
+ fs->qht = NULL;
+ }
+ /* set the new type for qht */
+ if (nonzero_mask(&fs->fsk_mask))
+ fs->fs.flags |= DN_QHT_HASH;
+ else
+ fs->fs.flags &= ~DN_QHT_HASH;
+
+ /* XXX config_red() can fail... */
+ if (fs->fs.flags & DN_IS_RED)
+ config_red(fs);
}
+/* update all flowsets which may refer to this scheduler */
static void
-set_fs_parms(struct dn_flow_set *x, struct dn_flow_set *src)
-{
- x->flags_fs = src->flags_fs;
- x->qsize = src->qsize;
- x->plr = src->plr;
- x->flow_mask = src->flow_mask;
- if (x->flags_fs & DN_QSIZE_IS_BYTES) {
- if (x->qsize > pipe_byte_limit)
- x->qsize = 1024 * 1024;
- } else {
- if (x->qsize == 0)
- x->qsize = 50;
- if (x->qsize > pipe_slot_limit)
- x->qsize = 50;
+update_fs(struct dn_schk *s)
+{
+ struct dn_fsk *fs, *tmp;
+
+ SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) {
+ if (s->sch.sched_nr != fs->fs.sched_nr) {
+ D("fs %d for sch %d not %d still unlinked",
+ fs->fs.fs_nr, fs->fs.sched_nr,
+ s->sch.sched_nr);
+ continue;
+ }
+ fsk_attach(fs, s);
}
- /* Configuring RED. */
- if (x->flags_fs & DN_IS_RED)
- config_red(src, x); /* XXX should check errors */
}
/*
- * Setup pipe or queue parameters.
+ * Configuration -- to preserve backward compatibility we use
+ * the following scheme (N is 65536)
+ * NUMBER SCHED LINK FLOWSET
+ * 1 .. N-1 (1)WFQ (2)WFQ (3)queue
+ * N+1 .. 2N-1 (4)FIFO (5)FIFO (6)FIFO for sched 1..N-1
+ * 2N+1 .. 3N-1 -- -- (7)FIFO for sched N+1..2N-1
+ *
+ * "pipe i config" configures #1, #2 and #3
+ * "sched i config" configures #1 and possibly #6
+ * "queue i config" configures #3
+ * #1 is configured with 'pipe i config' or 'sched i config'
+ * #2 is configured with 'pipe i config', and created if not
+ * existing with 'sched i config'
+ * #3 is configured with 'queue i config'
+ * #4 is automatically configured after #1, can only be FIFO
+ * #5 is automatically configured after #2
+ * #6 is automatically created when #1 is !MULTIQUEUE,
+ * and can be updated.
+ * #7 is automatically configured after #2
+ */
+
+/*
+ * configure a link (and its FIFO instance)
*/
static int
-config_pipe(struct dn_pipe *p)
+config_link(struct dn_link *p, struct dn_id *arg)
{
- struct dn_flow_set *pfs = &(p->fs);
- struct dn_flow_queue *q;
- int i, error;
+ int i;
+ if (p->oid.len != sizeof(*p)) {
+ D("invalid pipe len %d", p->oid.len);
+ return EINVAL;
+ }
+ i = p->link_nr;
+ if (i <= 0 || i >= DN_MAX_ID)
+ return EINVAL;
/*
* The config program passes parameters as follows:
* bw = bits/second (0 means no limits),
* delay = ms, must be translated into ticks.
* qsize = slots/bytes
+ * burst ???
*/
p->delay = (p->delay * hz) / 1000;
/* Scale burst size: bytes -> bits * hz */
p->burst *= 8 * hz;
- /* We need either a pipe number or a flow_set number. */
- if (p->pipe_nr == 0 && pfs->fs_nr == 0)
- return (EINVAL);
- if (p->pipe_nr != 0 && pfs->fs_nr != 0)
- return (EINVAL);
- if (p->pipe_nr != 0) { /* this is a pipe */
- struct dn_pipe *pipe;
-
- DUMMYNET_LOCK();
- pipe = locate_pipe(p->pipe_nr); /* locate pipe */
-
- if (pipe == NULL) { /* new pipe */
- pipe = malloc(sizeof(struct dn_pipe), M_DUMMYNET,
- M_NOWAIT | M_ZERO);
- if (pipe == NULL) {
- DUMMYNET_UNLOCK();
- printf("dummynet: no memory for new pipe\n");
- return (ENOMEM);
- }
- pipe->pipe_nr = p->pipe_nr;
- pipe->fs.pipe = pipe;
- /*
- * idle_heap is the only one from which
- * we extract from the middle.
+
+ DN_BH_WLOCK();
+ /* do it twice, base link and FIFO link */
+ for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
+ struct dn_schk *s = locate_scheduler(i);
+ if (s == NULL) {
+ DN_BH_WUNLOCK();
+ D("sched %d not found", i);
+ return EINVAL;
+ }
+ /* remove profile if exists */
+ if (s->profile) {
+ free(s->profile, M_DUMMYNET);
+ s->profile = NULL;
+ }
+ /* copy all parameters */
+ s->link.oid = p->oid;
+ s->link.link_nr = i;
+ s->link.delay = p->delay;
+ if (s->link.bandwidth != p->bandwidth) {
+ /* XXX bandwidth changes, need to update red params */
+ s->link.bandwidth = p->bandwidth;
+ update_red(s);
+ }
+ s->link.burst = p->burst;
+ schk_reset_credit(s);
+ }
+ dn_cfg.id++;
+ DN_BH_WUNLOCK();
+ return 0;
+}
+
+/*
+ * configure a flowset. Can be called from inside with locked=1,
+ */
+static struct dn_fsk *
+config_fs(struct dn_fs *nfs, struct dn_id *arg, int locked)
+{
+ int i;
+ struct dn_fsk *fs;
+
+ if (nfs->oid.len != sizeof(*nfs)) {
+ D("invalid flowset len %d", nfs->oid.len);
+ return NULL;
+ }
+ i = nfs->fs_nr;
+ if (i <= 0 || i >= 3*DN_MAX_ID)
+ return NULL;
+ ND("flowset %d", i);
+ /* XXX other sanity checks */
+ if (nfs->flags & DN_QSIZE_BYTES) {
+ ipdn_bound_var(&nfs->qsize, 16384,
+ 1500, dn_cfg.byte_limit, NULL); // "queue byte size");
+ } else {
+ ipdn_bound_var(&nfs->qsize, 50,
+ 1, dn_cfg.slot_limit, NULL); // "queue slot size");
+ }
+ if (nfs->flags & DN_HAVE_MASK) {
+ /* make sure we have some buckets */
+ ipdn_bound_var(&nfs->buckets, dn_cfg.hash_size,
+ 1, dn_cfg.max_hash_size, "flowset buckets");
+ } else {
+ nfs->buckets = 1; /* we only need 1 */
+ }
+ if (!locked)
+ DN_BH_WLOCK();
+ do { /* exit with break when done */
+ struct dn_schk *s;
+ int flags = nfs->sched_nr ? DNHT_INSERT : 0;
+ int j;
+ int oldc = dn_cfg.fsk_count;
+ fs = dn_ht_find(dn_cfg.fshash, i, flags, NULL);
+ if (fs == NULL) {
+ D("missing sched for flowset %d", i);
+ break;
+ }
+ /* grab some defaults from the existing one */
+ if (nfs->sched_nr == 0) /* reuse */
+ nfs->sched_nr = fs->fs.sched_nr;
+ for (j = 0; j < sizeof(nfs->par)/sizeof(nfs->par[0]); j++) {
+ if (nfs->par[j] == -1) /* reuse */
+ nfs->par[j] = fs->fs.par[j];
+ }
+ if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) {
+ ND("flowset %d unchanged", i);
+ break; /* no change, nothing to do */
+ }
+ if (oldc != dn_cfg.fsk_count) /* new item */
+ dn_cfg.id++;
+ s = locate_scheduler(nfs->sched_nr);
+ /* detach from old scheduler if needed, preserving
+ * queues if we need to reattach. Then update the
+ * configuration, and possibly attach to the new sched.
+ */
+ DX(2, "fs %d changed sched %d@%p to %d@%p",
+ fs->fs.fs_nr,
+ fs->fs.sched_nr, fs->sched, nfs->sched_nr, s);
+ if (fs->sched) {
+ int flags = s ? DN_DETACH : (DN_DETACH | DN_DESTROY);
+ flags |= DN_DESTROY; /* XXX temporary */
+ fsk_detach(fs, flags);
+ }
+ fs->fs = *nfs; /* copy configuration */
+ if (s != NULL)
+ fsk_attach(fs, s);
+ } while (0);
+ if (!locked)
+ DN_BH_WUNLOCK();
+ return fs;
+}
+
+/*
+ * config/reconfig a scheduler and its FIFO variant.
+ * For !MULTIQUEUE schedulers, also set up the flowset.
+ *
+ * On reconfigurations (detected because s->fp is set),
+ * detach existing flowsets preserving traffic, preserve link,
+ * and delete the old scheduler creating a new one.
+ */
+static int
+config_sched(struct dn_sch *_nsch, struct dn_id *arg)
+{
+ struct dn_schk *s;
+ struct schk_new_arg a; /* argument for schk_new */
+ int i;
+ struct dn_link p; /* copy of oldlink */
+ struct dn_profile *pf = NULL; /* copy of old link profile */
+ /* Used to preserv mask parameter */
+ struct ipfw_flow_id new_mask;
+ int new_buckets = 0;
+ int new_flags = 0;
+ int pipe_cmd;
+ int err = ENOMEM;
+
+ a.sch = _nsch;
+ if (a.sch->oid.len != sizeof(*a.sch)) {
+ D("bad sched len %d", a.sch->oid.len);
+ return EINVAL;
+ }
+ i = a.sch->sched_nr;
+ if (i <= 0 || i >= DN_MAX_ID)
+ return EINVAL;
+ /* make sure we have some buckets */
+ if (a.sch->flags & DN_HAVE_MASK)
+ ipdn_bound_var(&a.sch->buckets, dn_cfg.hash_size,
+ 1, dn_cfg.max_hash_size, "sched buckets");
+ /* XXX other sanity checks */
+ bzero(&p, sizeof(p));
+
+ pipe_cmd = a.sch->flags & DN_PIPE_CMD;
+ a.sch->flags &= ~DN_PIPE_CMD; //XXX do it even if is not set?
+ if (pipe_cmd) {
+ /* Copy mask parameter */
+ new_mask = a.sch->sched_mask;
+ new_buckets = a.sch->buckets;
+ new_flags = a.sch->flags;
+ }
+ DN_BH_WLOCK();
+again: /* run twice, for wfq and fifo */
+ /*
+ * lookup the type. If not supplied, use the previous one
+ * or default to WF2Q+. Otherwise, return an error.
+ */
+ dn_cfg.id++;
+ a.fp = find_sched_type(a.sch->oid.subtype, a.sch->name);
+ if (a.fp != NULL) {
+ /* found. Lookup or create entry */
+ s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a);
+ } else if (a.sch->oid.subtype == 0 && !a.sch->name[0]) {
+ /* No type. search existing s* or retry with WF2Q+ */
+ s = dn_ht_find(dn_cfg.schedhash, i, 0, &a);
+ if (s != NULL) {
+ a.fp = s->fp;
+ /* Scheduler exists, skip to FIFO scheduler
+ * if command was pipe config...
*/
- pipe->idle_heap.size = pipe->idle_heap.elements = 0;
- pipe->idle_heap.offset =
- offsetof(struct dn_flow_queue, heap_pos);
+ if (pipe_cmd)
+ goto next;
} else {
- /* Flush accumulated credit for all queues. */
- for (i = 0; i <= pipe->fs.rq_size; i++) {
- for (q = pipe->fs.rq[i]; q; q = q->next) {
- q->numbytes = p->burst +
- (io_fast ? p->bandwidth : 0);
- }
+ /* New scheduler, create a wf2q+ with no mask
+ * if command was pipe config...
+ */
+ if (pipe_cmd) {
+ /* clear mask parameter */
+ bzero(&a.sch->sched_mask, sizeof(new_mask));
+ a.sch->buckets = 0;
+ a.sch->flags &= ~DN_HAVE_MASK;
}
+ a.sch->oid.subtype = DN_SCHED_WF2QP;
+ goto again;
}
-
- pipe->bandwidth = p->bandwidth;
- pipe->burst = p->burst;
- pipe->numbytes = pipe->burst + (io_fast ? pipe->bandwidth : 0);
- bcopy(p->if_name, pipe->if_name, sizeof(p->if_name));
- pipe->ifp = NULL; /* reset interface ptr */
- pipe->delay = p->delay;
- set_fs_parms(&(pipe->fs), pfs);
-
- /* Handle changes in the delay profile. */
- if (p->samples_no > 0) {
- if (pipe->samples_no != p->samples_no) {
- if (pipe->samples != NULL)
- free(pipe->samples, M_DUMMYNET);
- pipe->samples =
- malloc(p->samples_no*sizeof(dn_key),
- M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (pipe->samples == NULL) {
- DUMMYNET_UNLOCK();
- printf("dummynet: no memory "
- "for new samples\n");
- return (ENOMEM);
- }
- pipe->samples_no = p->samples_no;
+ } else {
+ D("invalid scheduler type %d %s",
+ a.sch->oid.subtype, a.sch->name);
+ err = EINVAL;
+ goto error;
+ }
+ /* normalize name and subtype */
+ a.sch->oid.subtype = a.fp->type;
+ bzero(a.sch->name, sizeof(a.sch->name));
+ strlcpy(a.sch->name, a.fp->name, sizeof(a.sch->name));
+ if (s == NULL) {
+ D("cannot allocate scheduler %d", i);
+ goto error;
+ }
+ /* restore existing link if any */
+ if (p.link_nr) {
+ s->link = p;
+ if (!pf || pf->link_nr != p.link_nr) { /* no saved value */
+ s->profile = NULL; /* XXX maybe not needed */
+ } else {
+ s->profile = malloc(sizeof(struct dn_profile),
+ M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s->profile == NULL) {
+ D("cannot allocate profile");
+ goto error; //XXX
}
-
- strncpy(pipe->name,p->name,sizeof(pipe->name));
- pipe->loss_level = p->loss_level;
- for (i = 0; i<pipe->samples_no; ++i)
- pipe->samples[i] = p->samples[i];
- } else if (pipe->samples != NULL) {
- free(pipe->samples, M_DUMMYNET);
- pipe->samples = NULL;
- pipe->samples_no = 0;
+ bcopy(pf, s->profile, sizeof(*pf));
}
-
- if (pipe->fs.rq == NULL) { /* a new pipe */
- error = alloc_hash(&(pipe->fs), pfs);
- if (error) {
- DUMMYNET_UNLOCK();
- free_pipe(pipe);
- return (error);
- }
- SLIST_INSERT_HEAD(&pipehash[HASH(pipe->pipe_nr)],
- pipe, next);
+ }
+ p.link_nr = 0;
+ if (s->fp == NULL) {
+ DX(2, "sched %d new type %s", i, a.fp->name);
+ } else if (s->fp != a.fp ||
+ bcmp(a.sch, &s->sch, sizeof(*a.sch)) ) {
+ /* already existing. */
+ DX(2, "sched %d type changed from %s to %s",
+ i, s->fp->name, a.fp->name);
+ DX(4, " type/sub %d/%d -> %d/%d",
+ s->sch.oid.type, s->sch.oid.subtype,
+ a.sch->oid.type, a.sch->oid.subtype);
+ if (s->link.link_nr == 0)
+ D("XXX WARNING link 0 for sched %d", i);
+ p = s->link; /* preserve link */
+ if (s->profile) {/* preserve profile */
+ if (!pf)
+ pf = malloc(sizeof(*pf),
+ M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (pf) /* XXX should issue a warning otherwise */
+ bcopy(s->profile, pf, sizeof(*pf));
}
- DUMMYNET_UNLOCK();
- } else { /* config queue */
- struct dn_flow_set *fs;
-
- DUMMYNET_LOCK();
- fs = locate_flowset(pfs->fs_nr); /* locate flow_set */
-
- if (fs == NULL) { /* new */
- if (pfs->parent_nr == 0) { /* need link to a pipe */
- DUMMYNET_UNLOCK();
- return (EINVAL);
- }
- fs = malloc(sizeof(struct dn_flow_set), M_DUMMYNET,
- M_NOWAIT | M_ZERO);
- if (fs == NULL) {
- DUMMYNET_UNLOCK();
- printf(
- "dummynet: no memory for new flow_set\n");
- return (ENOMEM);
- }
- fs->fs_nr = pfs->fs_nr;
- fs->parent_nr = pfs->parent_nr;
- fs->weight = pfs->weight;
- if (fs->weight == 0)
- fs->weight = 1;
- else if (fs->weight > 100)
- fs->weight = 100;
+ /* remove from the hash */
+ dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
+ /* Detach flowsets, preserve queues. */
+ // schk_delete_cb(s, NULL);
+ // XXX temporarily, kill queues
+ schk_delete_cb(s, (void *)DN_DESTROY);
+ goto again;
+ } else {
+ DX(4, "sched %d unchanged type %s", i, a.fp->name);
+ }
+ /* complete initialization */
+ s->sch = *a.sch;
+ s->fp = a.fp;
+ s->cfg = arg;
+ // XXX schk_reset_credit(s);
+ /* create the internal flowset if needed,
+ * trying to reuse existing ones if available
+ */
+ if (!(s->fp->flags & DN_MULTIQUEUE) && !s->fs) {
+ s->fs = dn_ht_find(dn_cfg.fshash, i, 0, NULL);
+ if (!s->fs) {
+ struct dn_fs fs;
+ bzero(&fs, sizeof(fs));
+ set_oid(&fs.oid, DN_FS, sizeof(fs));
+ fs.fs_nr = i + DN_MAX_ID;
+ fs.sched_nr = i;
+ s->fs = config_fs(&fs, NULL, 1 /* locked */);
+ }
+ if (!s->fs) {
+ schk_delete_cb(s, (void *)DN_DESTROY);
+ D("error creating internal fs for %d", i);
+ goto error;
+ }
+ }
+ /* call init function after the flowset is created */
+ if (s->fp->config)
+ s->fp->config(s);
+ update_fs(s);
+next:
+ if (i < DN_MAX_ID) { /* now configure the FIFO instance */
+ i += DN_MAX_ID;
+ if (pipe_cmd) {
+ /* Restore mask parameter for FIFO */
+ a.sch->sched_mask = new_mask;
+ a.sch->buckets = new_buckets;
+ a.sch->flags = new_flags;
} else {
- /*
- * Change parent pipe not allowed;
- * must delete and recreate.
- */
- if (pfs->parent_nr != 0 &&
- fs->parent_nr != pfs->parent_nr) {
- DUMMYNET_UNLOCK();
- return (EINVAL);
+ /* sched config shouldn't modify the FIFO scheduler */
+ if (dn_ht_find(dn_cfg.schedhash, i, 0, &a) != NULL) {
+ /* FIFO already exist, don't touch it */
+ err = 0; /* and this is not an error */
+ goto error;
}
}
+ a.sch->sched_nr = i;
+ a.sch->oid.subtype = DN_SCHED_FIFO;
+ bzero(a.sch->name, sizeof(a.sch->name));
+ goto again;
+ }
+ err = 0;
+error:
+ DN_BH_WUNLOCK();
+ if (pf)
+ free(pf, M_DUMMYNET);
+ return err;
+}
- set_fs_parms(fs, pfs);
+/*
+ * attach a profile to a link
+ */
+static int
+config_profile(struct dn_profile *pf, struct dn_id *arg)
+{
+ struct dn_schk *s;
+ int i, olen, err = 0;
- if (fs->rq == NULL) { /* a new flow_set */
- error = alloc_hash(fs, pfs);
- if (error) {
- DUMMYNET_UNLOCK();
- free(fs, M_DUMMYNET);
- return (error);
- }
- SLIST_INSERT_HEAD(&flowsethash[HASH(fs->fs_nr)],
- fs, next);
+ if (pf->oid.len < sizeof(*pf)) {
+ D("short profile len %d", pf->oid.len);
+ return EINVAL;
+ }
+ i = pf->link_nr;
+ if (i <= 0 || i >= DN_MAX_ID)
+ return EINVAL;
+ /* XXX other sanity checks */
+ DN_BH_WLOCK();
+ for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
+ s = locate_scheduler(i);
+
+ if (s == NULL) {
+ err = EINVAL;
+ break;
+ }
+ dn_cfg.id++;
+ /*
+ * If we had a profile and the new one does not fit,
+ * or it is deleted, then we need to free memory.
+ */
+ if (s->profile && (pf->samples_no == 0 ||
+ s->profile->oid.len < pf->oid.len)) {
+ free(s->profile, M_DUMMYNET);
+ s->profile = NULL;
}
- DUMMYNET_UNLOCK();
+ if (pf->samples_no == 0)
+ continue;
+ /*
+ * new profile, possibly allocate memory
+ * and copy data.
+ */
+ if (s->profile == NULL)
+ s->profile = malloc(pf->oid.len,
+ M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s->profile == NULL) {
+ D("no memory for profile %d", i);
+ err = ENOMEM;
+ break;
+ }
+ /* preserve larger length XXX double check */
+ olen = s->profile->oid.len;
+ if (olen < pf->oid.len)
+ olen = pf->oid.len;
+ bcopy(pf, s->profile, pf->oid.len);
+ s->profile->oid.len = olen;
}
- return (0);
+ DN_BH_WUNLOCK();
+ return err;
}
/*
- * Helper function to remove from a heap queues which are linked to
- * a flow_set about to be deleted.
+ * Delete all objects:
*/
static void
-fs_remove_from_heap(struct dn_heap *h, struct dn_flow_set *fs)
+dummynet_flush(void)
{
- int i, found;
- for (i = found = 0 ; i < h->elements ;) {
- if ( ((struct dn_flow_queue *)h->p[i].object)->fs == fs) {
- h->elements-- ;
- h->p[i] = h->p[h->elements] ;
- found++ ;
- } else
- i++ ;
- }
- if (found)
- heapify(h);
+ /* delete all schedulers and related links/queues/flowsets */
+ dn_ht_scan(dn_cfg.schedhash, schk_delete_cb,
+ (void *)(uintptr_t)DN_DELETE_FS);
+ /* delete all remaining (unlinked) flowsets */
+ DX(4, "still %d unlinked fs", dn_cfg.fsk_count);
+ dn_ht_free(dn_cfg.fshash, DNHT_REMOVE);
+ fsk_detach_list(&dn_cfg.fsu, DN_DELETE_FS);
+ /* Reinitialize system heap... */
+ heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
}
/*
- * helper function to remove a pipe from a heap (can be there at most once)
+ * Main handler for configuration. We are guaranteed to be called
+ * with an oid which is at least a dn_id.
+ * - the first object is the command (config, delete, flush, ...)
+ * - config_link must be issued after the corresponding config_sched
+ * - parameters (DN_TXT) for an object must preceed the object
+ * processed on a config_sched.
*/
-static void
-pipe_remove_from_heap(struct dn_heap *h, struct dn_pipe *p)
+int
+do_config(void *p, int l)
{
- int i;
+ struct dn_id *next, *o;
+ int err = 0, err2 = 0;
+ struct dn_id *arg = NULL;
+ uintptr_t *a;
+
+ o = p;
+ if (o->id != DN_API_VERSION) {
+ D("invalid api version got %d need %d",
+ o->id, DN_API_VERSION);
+ return EINVAL;
+ }
+ for (; l >= sizeof(*o); o = next) {
+ struct dn_id *prev = arg;
+ if (o->len < sizeof(*o) || l < o->len) {
+ D("bad len o->len %d len %d", o->len, l);
+ err = EINVAL;
+ break;
+ }
+ l -= o->len;
+ next = (struct dn_id *)((char *)o + o->len);
+ err = 0;
+ switch (o->type) {
+ default:
+ D("cmd %d not implemented", o->type);
+ break;
- for (i=0; i < h->elements ; i++ ) {
- if (h->p[i].object == p) { /* found it */
- h->elements-- ;
- h->p[i] = h->p[h->elements] ;
- heapify(h);
- break ;
+#ifdef EMULATE_SYSCTL
+ /* sysctl emulation.
+ * if we recognize the command, jump to the correct
+ * handler and return
+ */
+ case DN_SYSCTL_SET:
+ err = kesysctl_emu_set(p, l);
+ return err;
+#endif
+
+ case DN_CMD_CONFIG: /* simply a header */
+ break;
+
+ case DN_CMD_DELETE:
+ /* the argument is in the first uintptr_t after o */
+ a = (uintptr_t *)(o+1);
+ if (o->len < sizeof(*o) + sizeof(*a)) {
+ err = EINVAL;
+ break;
+ }
+ switch (o->subtype) {
+ case DN_LINK:
+ /* delete base and derived schedulers */
+ DN_BH_WLOCK();
+ err = delete_schk(*a);
+ err2 = delete_schk(*a + DN_MAX_ID);
+ DN_BH_WUNLOCK();
+ if (!err)
+ err = err2;
+ break;
+
+ default:
+ D("invalid delete type %d",
+ o->subtype);
+ err = EINVAL;
+ break;
+
+ case DN_FS:
+ err = (*a <1 || *a >= DN_MAX_ID) ?
+ EINVAL : delete_fs(*a, 0) ;
+ break;
+ }
+ break;
+
+ case DN_CMD_FLUSH:
+ DN_BH_WLOCK();
+ dummynet_flush();
+ DN_BH_WUNLOCK();
+ break;
+ case DN_TEXT: /* store argument the next block */
+ prev = NULL;
+ arg = o;
+ break;
+ case DN_LINK:
+ err = config_link((struct dn_link *)o, arg);
+ break;
+ case DN_PROFILE:
+ err = config_profile((struct dn_profile *)o, arg);
+ break;
+ case DN_SCH:
+ err = config_sched((struct dn_sch *)o, arg);
+ break;
+ case DN_FS:
+ err = (NULL==config_fs((struct dn_fs *)o, arg, 0));
+ break;
}
+ if (prev)
+ arg = NULL;
+ if (err != 0)
+ break;
}
+ return err;
}
-/*
- * Fully delete a pipe or a queue, cleaning up associated info.
- */
static int
-delete_pipe(struct dn_pipe *p)
+compute_space(struct dn_id *cmd, struct copy_args *a)
{
+ int x = 0, need = 0;
+ int profile_size = sizeof(struct dn_profile) -
+ ED_MAX_SAMPLES_NO*sizeof(int);
+
+ /* NOTE about compute space:
+ * NP = dn_cfg.schk_count
+ * NSI = dn_cfg.si_count
+ * NF = dn_cfg.fsk_count
+ * NQ = dn_cfg.queue_count
+ * - ipfw pipe show
+ * (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
+ * link, scheduler template, flowset
+ * integrated in scheduler and header
+ * for flowset list
+ * (NSI)*(dn_flow) all scheduler instance (includes
+ * the queue instance)
+ * - ipfw sched show
+ * (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
+ * link, scheduler template, flowset
+ * integrated in scheduler and header
+ * for flowset list
+ * (NSI * dn_flow) all scheduler instances
+ * (NF * sizeof(uint_32)) space for flowset list linked to scheduler
+ * (NQ * dn_queue) all queue [XXXfor now not listed]
+ * - ipfw queue show
+ * (NF * dn_fs) all flowset
+ * (NQ * dn_queue) all queues
+ */
+ switch (cmd->subtype) {
+ default:
+ return -1;
+ /* XXX where do LINK and SCH differ ? */
+ /* 'ipfw sched show' could list all queues associated to
+ * a scheduler. This feature for now is disabled
+ */
+ case DN_LINK: /* pipe show */
+ x = DN_C_LINK | DN_C_SCH | DN_C_FLOW;
+ need += dn_cfg.schk_count *
+ (sizeof(struct dn_fs) + profile_size) / 2;
+ need += dn_cfg.fsk_count * sizeof(uint32_t);
+ break;
+ case DN_SCH: /* sched show */
+ need += dn_cfg.schk_count *
+ (sizeof(struct dn_fs) + profile_size) / 2;
+ need += dn_cfg.fsk_count * sizeof(uint32_t);
+ x = DN_C_SCH | DN_C_LINK | DN_C_FLOW;
+ break;
+ case DN_FS: /* queue show */
+ x = DN_C_FS | DN_C_QUEUE;
+ break;
+ case DN_GET_COMPAT: /* compatibility mode */
+ need = dn_compat_calc_size();
+ break;
+ }
+ a->flags = x;
+ if (x & DN_C_SCH) {
+ need += dn_cfg.schk_count * sizeof(struct dn_sch) / 2;
+ /* NOT also, each fs might be attached to a sched */
+ need += dn_cfg.schk_count * sizeof(struct dn_id) / 2;
+ }
+ if (x & DN_C_FS)
+ need += dn_cfg.fsk_count * sizeof(struct dn_fs);
+ if (x & DN_C_LINK) {
+ need += dn_cfg.schk_count * sizeof(struct dn_link) / 2;
+ }
+ /*
+ * When exporting a queue to userland, only pass up the
+ * struct dn_flow, which is the only visible part.
+ */
- if (p->pipe_nr == 0 && p->fs.fs_nr == 0)
- return EINVAL ;
- if (p->pipe_nr != 0 && p->fs.fs_nr != 0)
- return EINVAL ;
- if (p->pipe_nr != 0) { /* this is an old-style pipe */
- struct dn_pipe *pipe;
- struct dn_flow_set *fs;
- int i;
-
- DUMMYNET_LOCK();
- pipe = locate_pipe(p->pipe_nr); /* locate pipe */
+ if (x & DN_C_QUEUE)
+ need += dn_cfg.queue_count * sizeof(struct dn_flow);
+ if (x & DN_C_FLOW)
+ need += dn_cfg.si_count * (sizeof(struct dn_flow));
+ return need;
+}
- if (pipe == NULL) {
- DUMMYNET_UNLOCK();
- return (ENOENT); /* not found */
+/*
+ * If compat != NULL dummynet_get is called in compatibility mode.
+ * *compat will be the pointer to the buffer to pass to ipfw
+ */
+int
+dummynet_get(struct sockopt *sopt, void **compat)
+{
+ int have, i, need, error;
+ char *start = NULL, *buf;
+ size_t sopt_valsize;
+ struct dn_id *cmd;
+ struct copy_args a;
+ struct copy_range r;
+ int l = sizeof(struct dn_id);
+
+ bzero(&a, sizeof(a));
+ bzero(&r, sizeof(r));
+
+ /* save and restore original sopt_valsize around copyin */
+ sopt_valsize = sopt->sopt_valsize;
+
+ cmd = &r.o;
+
+ if (!compat) {
+ /* copy at least an oid, and possibly a full object */
+ error = sooptcopyin(sopt, cmd, sizeof(r), sizeof(*cmd));
+ sopt->sopt_valsize = sopt_valsize;
+ if (error)
+ goto done;
+ l = cmd->len;
+#ifdef EMULATE_SYSCTL
+ /* sysctl emulation. */
+ if (cmd->type == DN_SYSCTL_GET)
+ return kesysctl_emu_get(sopt);
+#endif
+ if (l > sizeof(r)) {
+ /* request larger than default, allocate buffer */
+ cmd = malloc(l, M_DUMMYNET, M_WAIT);
+ if (cmd == NULL)
+ return ENOMEM; //XXX
+ error = sooptcopyin(sopt, cmd, l, l);
+ sopt->sopt_valsize = sopt_valsize;
+ if (error)
+ goto done;
+ }
+ } else { /* compatibility */
+ error = 0;
+ cmd->type = DN_CMD_GET;
+ cmd->len = sizeof(struct dn_id);
+ cmd->subtype = DN_GET_COMPAT;
+ // cmd->id = sopt_valsize;
+ D("compatibility mode");
}
+ a.extra = (struct copy_range *)cmd;
+ if (cmd->len == sizeof(*cmd)) { /* no range, create a default */
+ uint32_t *rp = (uint32_t *)(cmd + 1);
+ cmd->len += 2* sizeof(uint32_t);
+ rp[0] = 1;
+ rp[1] = DN_MAX_ID - 1;
+ if (cmd->subtype == DN_LINK) {
+ rp[0] += DN_MAX_ID;
+ rp[1] += DN_MAX_ID;
+ }
+ }
+ /* Count space (under lock) and allocate (outside lock).
+ * Exit with lock held if we manage to get enough buffer.
+ * Try a few times then give up.
+ */
+ for (have = 0, i = 0; i < 10; i++) {
+ DN_BH_WLOCK();
+ need = compute_space(cmd, &a);
+
+ /* if there is a range, ignore value from compute_space() */
+ if (l > sizeof(*cmd))
+ need = sopt_valsize - sizeof(*cmd);
+
+ if (need < 0) {
+ DN_BH_WUNLOCK();
+ error = EINVAL;
+ goto done;
+ }
+ need += sizeof(*cmd);
+ cmd->id = need;
+ if (have >= need)
+ break;
- /* Unlink from list of pipes. */
- SLIST_REMOVE(&pipehash[HASH(pipe->pipe_nr)], pipe, dn_pipe, next);
+ DN_BH_WUNLOCK();
+ if (start)
+ free(start, M_DUMMYNET);
+ start = NULL;
+ if (need > sopt_valsize)
+ break;
- /* Remove all references to this pipe from flow_sets. */
- for (i = 0; i < HASHSIZE; i++) {
- SLIST_FOREACH(fs, &flowsethash[i], next) {
- if (fs->pipe == pipe) {
- printf("dummynet: ++ ref to pipe %d from fs %d\n",
- p->pipe_nr, fs->fs_nr);
- fs->pipe = NULL ;
- purge_flow_set(fs, 0);
+ have = need;
+ start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO);
+ if (start == NULL) {
+ error = ENOMEM;
+ goto done;
}
- }
}
- fs_remove_from_heap(&ready_heap, &(pipe->fs));
- purge_pipe(pipe); /* remove all data associated to this pipe */
- /* remove reference to here from extract_heap and wfq_ready_heap */
- pipe_remove_from_heap(&extract_heap, pipe);
- pipe_remove_from_heap(&wfq_ready_heap, pipe);
- DUMMYNET_UNLOCK();
-
- free_pipe(pipe);
- } else { /* this is a WF2Q queue (dn_flow_set) */
- struct dn_flow_set *fs;
- DUMMYNET_LOCK();
- fs = locate_flowset(p->fs.fs_nr); /* locate set */
+ if (start == NULL) {
+ if (compat) {
+ *compat = NULL;
+ error = 1; // XXX
+ } else {
+ error = sooptcopyout(sopt, cmd, sizeof(*cmd));
+ }
+ goto done;
+ }
+ ND("have %d:%d sched %d, %d:%d links %d, %d:%d flowsets %d, "
+ "%d:%d si %d, %d:%d queues %d",
+ dn_cfg.schk_count, sizeof(struct dn_sch), DN_SCH,
+ dn_cfg.schk_count, sizeof(struct dn_link), DN_LINK,
+ dn_cfg.fsk_count, sizeof(struct dn_fs), DN_FS,
+ dn_cfg.si_count, sizeof(struct dn_flow), DN_SCH_I,
+ dn_cfg.queue_count, sizeof(struct dn_queue), DN_QUEUE);
+ sopt->sopt_valsize = sopt_valsize;
+ a.type = cmd->subtype;
+
+ if (compat == NULL) {
+ bcopy(cmd, start, sizeof(*cmd));
+ ((struct dn_id*)(start))->len = sizeof(struct dn_id);
+ buf = start + sizeof(*cmd);
+ } else
+ buf = start;
+ a.start = &buf;
+ a.end = start + have;
+ /* start copying other objects */
+ if (compat) {
+ a.type = DN_COMPAT_PIPE;
+ dn_ht_scan(dn_cfg.schedhash, copy_data_helper_compat, &a);
+ a.type = DN_COMPAT_QUEUE;
+ dn_ht_scan(dn_cfg.fshash, copy_data_helper_compat, &a);
+ } else if (a.type == DN_FS) {
+ dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
+ } else {
+ dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
+ }
+ DN_BH_WUNLOCK();
- if (fs == NULL) {
- DUMMYNET_UNLOCK();
- return (ENOENT); /* not found */
+ if (compat) {
+ *compat = start;
+ sopt->sopt_valsize = buf - start;
+ /* free() is done by ip_dummynet_compat() */
+ start = NULL; //XXX hack
+ } else {
+ error = sooptcopyout(sopt, start, buf - start);
}
+done:
+ if (cmd && cmd != &r.o)
+ free(cmd, M_DUMMYNET);
+ if (start)
+ free(start, M_DUMMYNET);
+ return error;
+}
- /* Unlink from list of flowsets. */
- SLIST_REMOVE( &flowsethash[HASH(fs->fs_nr)], fs, dn_flow_set, next);
+/* Callback called on scheduler instance to delete it if idle */
+static int
+drain_scheduler_cb(void *_si, void *arg)
+{
+ struct dn_sch_inst *si = _si;
- if (fs->pipe != NULL) {
- /* Update total weight on parent pipe and cleanup parent heaps. */
- fs->pipe->sum -= fs->weight * fs->backlogged ;
- fs_remove_from_heap(&(fs->pipe->not_eligible_heap), fs);
- fs_remove_from_heap(&(fs->pipe->scheduler_heap), fs);
-#if 1 /* XXX should i remove from idle_heap as well ? */
- fs_remove_from_heap(&(fs->pipe->idle_heap), fs);
-#endif
+ if ((si->kflags & DN_ACTIVE) || si->dline.mq.head != NULL)
+ return 0;
+
+ if (si->sched->fp->flags & DN_MULTIQUEUE) {
+ if (si->q_count == 0)
+ return si_destroy(si, NULL);
+ else
+ return 0;
+ } else { /* !DN_MULTIQUEUE */
+ if ((si+1)->ni.length == 0)
+ return si_destroy(si, NULL);
+ else
+ return 0;
}
- purge_flow_set(fs, 1);
- DUMMYNET_UNLOCK();
- }
- return 0 ;
+ return 0; /* unreachable */
}
-/*
- * helper function used to copy data from kernel in DUMMYNET_GET
- */
-static char *
-dn_copy_set(struct dn_flow_set *set, char *bp)
-{
- int i, copied = 0 ;
- struct dn_flow_queue *q, *qp = (struct dn_flow_queue *)bp;
-
- DUMMYNET_LOCK_ASSERT();
-
- for (i = 0 ; i <= set->rq_size ; i++) {
- for (q = set->rq[i] ; q ; q = q->next, qp++ ) {
- if (q->hash_slot != i)
- printf("dummynet: ++ at %d: wrong slot (have %d, "
- "should be %d)\n", copied, q->hash_slot, i);
- if (q->fs != set)
- printf("dummynet: ++ at %d: wrong fs ptr (have %p, should be %p)\n",
- i, q->fs, set);
- copied++ ;
- bcopy(q, qp, sizeof( *q ) );
- /* cleanup pointers */
- qp->next = NULL ;
- qp->head = qp->tail = NULL ;
- qp->fs = NULL ;
+/* Callback called on scheduler to check if it has instances */
+static int
+drain_scheduler_sch_cb(void *_s, void *arg)
+{
+ struct dn_schk *s = _s;
+
+ if (s->sch.flags & DN_HAVE_MASK) {
+ dn_ht_scan_bucket(s->siht, &s->drain_bucket,
+ drain_scheduler_cb, NULL);
+ s->drain_bucket++;
+ } else {
+ if (s->siht) {
+ if (drain_scheduler_cb(s->siht, NULL) == DNHT_SCAN_DEL)
+ s->siht = NULL;
+ }
}
- }
- if (copied != set->rq_elements)
- printf("dummynet: ++ wrong count, have %d should be %d\n",
- copied, set->rq_elements);
- return (char *)qp ;
-}
-
-static size_t
-dn_calc_size(void)
-{
- struct dn_flow_set *fs;
- struct dn_pipe *pipe;
- size_t size = 0;
- int i;
-
- DUMMYNET_LOCK_ASSERT();
- /*
- * Compute size of data structures: list of pipes and flow_sets.
- */
- for (i = 0; i < HASHSIZE; i++) {
- SLIST_FOREACH(pipe, &pipehash[i], next)
- size += sizeof(*pipe) +
- pipe->fs.rq_elements * sizeof(struct dn_flow_queue);
- SLIST_FOREACH(fs, &flowsethash[i], next)
- size += sizeof (*fs) +
- fs->rq_elements * sizeof(struct dn_flow_queue);
- }
- return size;
+ return 0;
}
-static int
-dummynet_get(struct sockopt *sopt)
-{
- char *buf, *bp ; /* bp is the "copy-pointer" */
- size_t size ;
- struct dn_flow_set *fs;
- struct dn_pipe *pipe;
- int error=0, i ;
-
- /* XXX lock held too long */
- DUMMYNET_LOCK();
- /*
- * XXX: Ugly, but we need to allocate memory with M_WAITOK flag and we
- * cannot use this flag while holding a mutex.
- */
- for (i = 0; i < 10; i++) {
- size = dn_calc_size();
- DUMMYNET_UNLOCK();
- buf = malloc(size, M_TEMP, M_WAITOK);
- DUMMYNET_LOCK();
- if (size >= dn_calc_size())
- break;
- free(buf, M_TEMP);
- buf = NULL;
- }
- if (buf == NULL) {
- DUMMYNET_UNLOCK();
- return ENOBUFS ;
- }
- bp = buf;
- for (i = 0; i < HASHSIZE; i++) {
- SLIST_FOREACH(pipe, &pipehash[i], next) {
- struct dn_pipe *pipe_bp = (struct dn_pipe *)bp;
+/* Called every tick, try to delete a 'bucket' of scheduler */
+void
+dn_drain_scheduler(void)
+{
+ dn_ht_scan_bucket(dn_cfg.schedhash, &dn_cfg.drain_sch,
+ drain_scheduler_sch_cb, NULL);
+ dn_cfg.drain_sch++;
+}
- /*
- * Copy pipe descriptor into *bp, convert delay back to ms,
- * then copy the flow_set descriptor(s) one at a time.
- * After each flow_set, copy the queue descriptor it owns.
- */
- bcopy(pipe, bp, sizeof(*pipe));
- pipe_bp->delay = (pipe_bp->delay * 1000) / hz;
- pipe_bp->burst = div64(pipe_bp->burst, 8 * hz);
- /*
- * XXX the following is a hack based on ->next being the
- * first field in dn_pipe and dn_flow_set. The correct
- * solution would be to move the dn_flow_set to the beginning
- * of struct dn_pipe.
- */
- pipe_bp->next.sle_next = (struct dn_pipe *)DN_IS_PIPE;
- /* Clean pointers. */
- pipe_bp->head = pipe_bp->tail = NULL;
- pipe_bp->fs.next.sle_next = NULL;
- pipe_bp->fs.pipe = NULL;
- pipe_bp->fs.rq = NULL;
- pipe_bp->samples = NULL;
+/* Callback called on queue to delete if it is idle */
+static int
+drain_queue_cb(void *_q, void *arg)
+{
+ struct dn_queue *q = _q;
- bp += sizeof(*pipe) ;
- bp = dn_copy_set(&(pipe->fs), bp);
+ if (q->ni.length == 0) {
+ dn_delete_queue(q, DN_DESTROY);
+ return DNHT_SCAN_DEL; /* queue is deleted */
}
- }
- for (i = 0; i < HASHSIZE; i++) {
- SLIST_FOREACH(fs, &flowsethash[i], next) {
- struct dn_flow_set *fs_bp = (struct dn_flow_set *)bp;
+ return 0; /* queue isn't deleted */
+}
- bcopy(fs, bp, sizeof(*fs));
- /* XXX same hack as above */
- fs_bp->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
- fs_bp->pipe = NULL;
- fs_bp->rq = NULL;
- bp += sizeof(*fs);
- bp = dn_copy_set(fs, bp);
- }
- }
+/* Callback called on flowset used to check if it has queues */
+static int
+drain_queue_fs_cb(void *_fs, void *arg)
+{
+ struct dn_fsk *fs = _fs;
- DUMMYNET_UNLOCK();
+ if (fs->fs.flags & DN_QHT_HASH) {
+ /* Flowset has a hash table for queues */
+ dn_ht_scan_bucket(fs->qht, &fs->drain_bucket,
+ drain_queue_cb, NULL);
+ fs->drain_bucket++;
+ } else {
+ /* No hash table for this flowset, null the pointer
+ * if the queue is deleted
+ */
+ if (fs->qht) {
+ if (drain_queue_cb(fs->qht, NULL) == DNHT_SCAN_DEL)
+ fs->qht = NULL;
+ }
+ }
+ return 0;
+}
- error = sooptcopyout(sopt, buf, size);
- free(buf, M_TEMP);
- return error ;
+/* Called every tick, try to delete a 'bucket' of queue */
+void
+dn_drain_queue(void)
+{
+ /* scan a bucket of flowset */
+ dn_ht_scan_bucket(dn_cfg.fshash, &dn_cfg.drain_fs,
+ drain_queue_fs_cb, NULL);
+ dn_cfg.drain_fs++;
}
/*
- * Handler for the various dummynet socket options (get, flush, config, del)
+ * Handler for the various dummynet socket options
*/
static int
ip_dn_ctl(struct sockopt *sopt)
{
- int error;
- struct dn_pipe *p = NULL;
-
- error = priv_check(sopt->sopt_td, PRIV_NETINET_DUMMYNET);
- if (error)
- return (error);
+ void *p = NULL;
+ int error, l;
- /* Disallow sets in really-really secure mode. */
- if (sopt->sopt_dir == SOPT_SET) {
-#if __FreeBSD_version >= 500034
- error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
+ error = priv_check(sopt->sopt_td, PRIV_NETINET_DUMMYNET);
if (error)
- return (error);
-#else
- if (securelevel >= 3)
- return (EPERM);
-#endif
- }
+ return (error);
- switch (sopt->sopt_name) {
- default :
- printf("dummynet: -- unknown option %d", sopt->sopt_name);
- error = EINVAL ;
- break;
-
- case IP_DUMMYNET_GET :
- error = dummynet_get(sopt);
- break ;
-
- case IP_DUMMYNET_FLUSH :
- dummynet_flush() ;
- break ;
-
- case IP_DUMMYNET_CONFIGURE :
- p = malloc(sizeof(struct dn_pipe_max), M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, p, sizeof(struct dn_pipe_max), sizeof *p);
- if (error)
- break ;
- if (p->samples_no > 0)
- p->samples = &(((struct dn_pipe_max *)p)->samples[0]);
+ /* Disallow sets in really-really secure mode. */
+ if (sopt->sopt_dir == SOPT_SET) {
+ error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
+ if (error)
+ return (error);
+ }
- error = config_pipe(p);
- break ;
+ switch (sopt->sopt_name) {
+ default :
+ D("dummynet: unknown option %d", sopt->sopt_name);
+ error = EINVAL;
+ break;
- case IP_DUMMYNET_DEL : /* remove a pipe or queue */
- p = malloc(sizeof(struct dn_pipe), M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, p, sizeof(struct dn_pipe), sizeof *p);
- if (error)
- break ;
+ case IP_DUMMYNET_FLUSH:
+ case IP_DUMMYNET_CONFIGURE:
+ case IP_DUMMYNET_DEL: /* remove a pipe or queue */
+ case IP_DUMMYNET_GET:
+ D("dummynet: compat option %d", sopt->sopt_name);
+ error = ip_dummynet_compat(sopt);
+ break;
- error = delete_pipe(p);
- break ;
- }
+ case IP_DUMMYNET3 :
+ if (sopt->sopt_dir == SOPT_GET) {
+ error = dummynet_get(sopt, NULL);
+ break;
+ }
+ l = sopt->sopt_valsize;
+ if (l < sizeof(struct dn_id) || l > 12000) {
+ D("argument len %d invalid", l);
+ break;
+ }
+ p = malloc(l, M_TEMP, M_WAITOK); // XXX can it fail ?
+ error = sooptcopyin(sopt, p, l, l);
+ if (error)
+ break ;
+ error = do_config(p, l);
+ break;
+ }
- if (p != NULL)
- free(p, M_TEMP);
+ if (p != NULL)
+ free(p, M_TEMP);
- return error ;
+ return error ;
}
+
static void
ip_dn_init(void)
{
- int i;
-
- if (bootverbose)
- printf("DUMMYNET with IPv6 initialized (040826)\n");
-
- DUMMYNET_LOCK_INIT();
-
- for (i = 0; i < HASHSIZE; i++) {
- SLIST_INIT(&pipehash[i]);
- SLIST_INIT(&flowsethash[i]);
- }
- ready_heap.size = ready_heap.elements = 0;
- ready_heap.offset = 0;
+ if (dn_cfg.init_done)
+ return;
+ printf("DUMMYNET %p with IPv6 initialized (100409)\n", curvnet);
+ dn_cfg.init_done = 1;
+ /* Set defaults here. MSVC does not accept initializers,
+ * and this is also useful for vimages
+ */
+ /* queue limits */
+ dn_cfg.slot_limit = 100; /* Foot shooting limit for queues. */
+ dn_cfg.byte_limit = 1024 * 1024;
+ dn_cfg.expire = 1;
+
+ /* RED parameters */
+ dn_cfg.red_lookup_depth = 256; /* default lookup table depth */
+ dn_cfg.red_avg_pkt_size = 512; /* default medium packet size */
+ dn_cfg.red_max_pkt_size = 1500; /* default max packet size */
+
+ /* hash tables */
+ dn_cfg.max_hash_size = 1024; /* max in the hash tables */
+ dn_cfg.hash_size = 64; /* default hash size */
+
+ /* create hash tables for schedulers and flowsets.
+ * In both we search by key and by pointer.
+ */
+ dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.hash_size,
+ offsetof(struct dn_schk, schk_next),
+ schk_hash, schk_match, schk_new);
+ dn_cfg.fshash = dn_ht_init(NULL, dn_cfg.hash_size,
+ offsetof(struct dn_fsk, fsk_next),
+ fsk_hash, fsk_match, fsk_new);
- wfq_ready_heap.size = wfq_ready_heap.elements = 0;
- wfq_ready_heap.offset = 0;
+ /* bucket index to drain object */
+ dn_cfg.drain_fs = 0;
+ dn_cfg.drain_sch = 0;
- extract_heap.size = extract_heap.elements = 0;
- extract_heap.offset = 0;
+ heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
+ SLIST_INIT(&dn_cfg.fsu);
+ SLIST_INIT(&dn_cfg.schedlist);
- ip_dn_ctl_ptr = ip_dn_ctl;
- ip_dn_io_ptr = dummynet_io;
+ DN_LOCK_INIT();
- TASK_INIT(&dn_task, 0, dummynet_task, NULL);
+ TASK_INIT(&dn_task, 0, dummynet_task, curvnet);
dn_tq = taskqueue_create_fast("dummynet", M_NOWAIT,
taskqueue_thread_enqueue, &dn_tq);
taskqueue_start_threads(&dn_tq, 1, PI_NET, "dummynet");
@@ -2270,25 +2164,32 @@ ip_dn_init(void)
callout_reset(&dn_timeout, 1, dummynet, NULL);
/* Initialize curr_time adjustment mechanics. */
- getmicrouptime(&prev_t);
+ getmicrouptime(&dn_cfg.prev_t);
}
#ifdef KLD_MODULE
static void
-ip_dn_destroy(void)
+ip_dn_destroy(int last)
{
- ip_dn_ctl_ptr = NULL;
- ip_dn_io_ptr = NULL;
+ callout_drain(&dn_timeout);
+
+ DN_BH_WLOCK();
+ if (last) {
+ printf("%s removing last instance\n", __FUNCTION__);
+ ip_dn_ctl_ptr = NULL;
+ ip_dn_io_ptr = NULL;
+ }
- DUMMYNET_LOCK();
- callout_stop(&dn_timeout);
- DUMMYNET_UNLOCK();
+ dummynet_flush();
+ DN_BH_WUNLOCK();
taskqueue_drain(dn_tq, &dn_task);
taskqueue_free(dn_tq);
- dummynet_flush();
+ dn_ht_free(dn_cfg.schedhash, 0);
+ dn_ht_free(dn_cfg.fshash, 0);
+ heap_free(&dn_cfg.evheap);
- DUMMYNET_LOCK_DESTROY();
+ DN_LOCK_DESTROY();
}
#endif /* KLD_MODULE */
@@ -2296,36 +2197,116 @@ static int
dummynet_modevent(module_t mod, int type, void *data)
{
- switch (type) {
- case MOD_LOAD:
+ if (type == MOD_LOAD) {
if (ip_dn_io_ptr) {
- printf("DUMMYNET already loaded\n");
- return EEXIST ;
+ printf("DUMMYNET already loaded\n");
+ return EEXIST ;
}
ip_dn_init();
- break;
-
- case MOD_UNLOAD:
+ ip_dn_ctl_ptr = ip_dn_ctl;
+ ip_dn_io_ptr = dummynet_io;
+ return 0;
+ } else if (type == MOD_UNLOAD) {
#if !defined(KLD_MODULE)
printf("dummynet statically compiled, cannot unload\n");
return EINVAL ;
#else
- ip_dn_destroy();
+ ip_dn_destroy(1 /* last */);
+ return 0;
#endif
- break ;
- default:
+ } else
return EOPNOTSUPP;
- break ;
+}
+
+/* modevent helpers for the modules */
+static int
+load_dn_sched(struct dn_alg *d)
+{
+ struct dn_alg *s;
+
+ if (d == NULL)
+ return 1; /* error */
+ ip_dn_init(); /* just in case, we need the lock */
+
+ /* Check that mandatory funcs exists */
+ if (d->enqueue == NULL || d->dequeue == NULL) {
+ D("missing enqueue or dequeue for %s", d->name);
+ return 1;
+ }
+
+ /* Search if scheduler already exists */
+ DN_BH_WLOCK();
+ SLIST_FOREACH(s, &dn_cfg.schedlist, next) {
+ if (strcmp(s->name, d->name) == 0) {
+ D("%s already loaded", d->name);
+ break; /* scheduler already exists */
+ }
}
- return 0 ;
+ if (s == NULL)
+ SLIST_INSERT_HEAD(&dn_cfg.schedlist, d, next);
+ DN_BH_WUNLOCK();
+ D("dn_sched %s %sloaded", d->name, s ? "not ":"");
+ return s ? 1 : 0;
+}
+
+static int
+unload_dn_sched(struct dn_alg *s)
+{
+ struct dn_alg *tmp, *r;
+ int err = EINVAL;
+
+ D("called for %s", s->name);
+
+ DN_BH_WLOCK();
+ SLIST_FOREACH_SAFE(r, &dn_cfg.schedlist, next, tmp) {
+ if (strcmp(s->name, r->name) != 0)
+ continue;
+ D("ref_count = %d", r->ref_count);
+ err = (r->ref_count != 0) ? EBUSY : 0;
+ if (err == 0)
+ SLIST_REMOVE(&dn_cfg.schedlist, r, dn_alg, next);
+ break;
+ }
+ DN_BH_WUNLOCK();
+ D("dn_sched %s %sunloaded", s->name, err ? "not ":"");
+ return err;
+}
+
+int
+dn_sched_modevent(module_t mod, int cmd, void *arg)
+{
+ struct dn_alg *sch = arg;
+
+ if (cmd == MOD_LOAD)
+ return load_dn_sched(sch);
+ else if (cmd == MOD_UNLOAD)
+ return unload_dn_sched(sch);
+ else
+ return EINVAL;
}
static moduledata_t dummynet_mod = {
- "dummynet",
- dummynet_modevent,
- NULL
+ "dummynet", dummynet_modevent, NULL
};
-DECLARE_MODULE(dummynet, dummynet_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
+
+#define DN_SI_SUB SI_SUB_PROTO_IFATTACHDOMAIN
+#define DN_MODEV_ORD (SI_ORDER_ANY - 128) /* after ipfw */
+DECLARE_MODULE(dummynet, dummynet_mod, DN_SI_SUB, DN_MODEV_ORD);
MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
MODULE_VERSION(dummynet, 1);
+
+/*
+ * Starting up. Done in order after dummynet_modevent() has been called.
+ * VNET_SYSINIT is also called for each existing vnet and each new vnet.
+ */
+//VNET_SYSINIT(vnet_dn_init, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_init, NULL);
+
+/*
+ * Shutdown handlers up shop. These are done in REVERSE ORDER, but still
+ * after dummynet_modevent() has been called. Not called on reboot.
+ * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
+ * or when the module is unloaded.
+ */
+//VNET_SYSUNINIT(vnet_dn_uninit, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_destroy, NULL);
+
/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
index 724536c..959ad8e 100644
--- a/sys/netinet/ipfw/ip_fw2.c
+++ b/sys/netinet/ipfw/ip_fw2.c
@@ -142,6 +142,11 @@ ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
#ifdef SYSCTL_NODE
+uint32_t dummy_def = IPFW_DEFAULT_RULE;
+uint32_t dummy_tables_max = IPFW_TABLES_MAX;
+
+SYSBEGIN(f3)
+
SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
@@ -156,10 +161,10 @@ SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
"Set upper limit of matches of ipfw rules logged");
SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
- NULL, IPFW_DEFAULT_RULE,
+ &dummy_def, 0,
"The default/max possible rule number.");
SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
- NULL, IPFW_TABLES_MAX,
+ &dummy_tables_max, 0,
"The maximum number of tables.");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
&default_to_accept, 0,
@@ -177,6 +182,8 @@ SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
"Deny packets with unknown IPv6 Extension Headers");
#endif /* INET6 */
+SYSEND
+
#endif /* SYSCTL_NODE */
@@ -344,6 +351,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
return(1);
}
} else {
+#ifdef __FreeBSD__ /* and OSX too ? */
struct ifaddr *ia;
if_addr_rlock(ifp);
@@ -357,6 +365,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
}
}
if_addr_runlock(ifp);
+#endif /* __FreeBSD__ */
}
return(0); /* no match, fail ... */
}
@@ -385,6 +394,9 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
static int
verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
{
+#ifndef __FreeBSD__
+ return 0;
+#else
struct route ro;
struct sockaddr_in *dst;
@@ -427,6 +439,7 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
/* found valid route */
RTFREE(ro.ro_rt);
return 1;
+#endif /* __FreeBSD__ */
}
#ifdef INET6
@@ -634,9 +647,14 @@ send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
static int
check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
- u_int16_t src_port, struct ucred **uc, int *ugid_lookupp,
- struct inpcb *inp)
+ u_int16_t src_port, int *ugid_lookupp,
+ struct ucred **uc, struct inpcb *inp)
{
+#ifndef __FreeBSD__
+ return cred_check(insn, proto, oif,
+ dst_ip, dst_port, src_ip, src_port,
+ (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
+#else /* FreeBSD */
struct inpcbinfo *pi;
int wildcard;
struct inpcb *pcb;
@@ -703,6 +721,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
else if (insn->o.opcode == O_JAIL)
match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
return match;
+#endif /* __FreeBSD__ */
}
/*
@@ -794,7 +813,11 @@ ipfw_chk(struct ip_fw_args *args)
* these types of constraints, as well as decrease contention
* on pcb related locks.
*/
+#ifndef __FreeBSD__
+ struct bsd_ucred ucred_cache;
+#else
struct ucred *ucred_cache = NULL;
+#endif
int ucred_lookup = 0;
/*
@@ -863,10 +886,13 @@ ipfw_chk(struct ip_fw_args *args)
* ulp is NULL if not found.
*/
void *ulp = NULL; /* upper layer protocol pointer. */
+
/* XXX ipv6 variables */
int is_ipv6 = 0;
- u_int16_t ext_hd = 0; /* bits vector for extension header filtering */
+ uint8_t icmp6_type = 0;
+ uint16_t ext_hd = 0; /* bits vector for extension header filtering */
/* end of ipv6 variables */
+
int is_ipv4 = 0;
int done = 0; /* flag to exit the outer loop */
@@ -918,14 +944,15 @@ do { \
switch (proto) {
case IPPROTO_ICMPV6:
PULLUP_TO(hlen, ulp, struct icmp6_hdr);
- args->f_id.flags = ICMP6(ulp)->icmp6_type;
+ icmp6_type = ICMP6(ulp)->icmp6_type;
break;
case IPPROTO_TCP:
PULLUP_TO(hlen, ulp, struct tcphdr);
dst_port = TCP(ulp)->th_dport;
src_port = TCP(ulp)->th_sport;
- args->f_id.flags = TCP(ulp)->th_flags;
+ /* save flags for dynamic rules */
+ args->f_id._flags = TCP(ulp)->th_flags;
break;
case IPPROTO_SCTP:
@@ -989,7 +1016,7 @@ do { \
return (IP_FW_DENY);
break;
}
- args->f_id.frag_id6 =
+ args->f_id.extra =
ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
ulp = NULL;
break;
@@ -1092,7 +1119,8 @@ do { \
PULLUP_TO(hlen, ulp, struct tcphdr);
dst_port = TCP(ulp)->th_dport;
src_port = TCP(ulp)->th_sport;
- args->f_id.flags = TCP(ulp)->th_flags;
+ /* save flags for dynamic rules */
+ args->f_id._flags = TCP(ulp)->th_flags;
break;
case IPPROTO_UDP:
@@ -1103,7 +1131,7 @@ do { \
case IPPROTO_ICMP:
PULLUP_TO(hlen, ulp, struct icmphdr);
- args->f_id.flags = ICMP(ulp)->icmp_type;
+ //args->f_id.flags = ICMP(ulp)->icmp_type;
break;
default:
@@ -1233,8 +1261,13 @@ do { \
(ipfw_insn_u32 *)cmd,
proto, oif,
dst_ip, dst_port,
- src_ip, src_port, &ucred_cache,
- &ucred_lookup, args->inp);
+ src_ip, src_port, &ucred_lookup,
+#ifdef __FreeBSD__
+ &ucred_cache, args->inp);
+#else
+ (void *)&ucred_cache,
+ (struct inpcb *)args->m);
+#endif
break;
case O_RECV:
@@ -1334,6 +1367,8 @@ do { \
key = dst_ip.s_addr;
else if (v == 1)
key = src_ip.s_addr;
+ else if (v == 6) /* dscp */
+ key = (ip->ip_tos >> 2) & 0x3f;
else if (offset != 0)
break;
else if (proto != IPPROTO_TCP &&
@@ -1348,12 +1383,21 @@ do { \
(ipfw_insn_u32 *)cmd,
proto, oif,
dst_ip, dst_port,
- src_ip, src_port, &ucred_cache,
- &ucred_lookup, args->inp);
+ src_ip, src_port, &ucred_lookup,
+#ifdef __FreeBSD__
+ &ucred_cache, args->inp);
if (v == 4 /* O_UID */)
key = ucred_cache->cr_uid;
else if (v == 5 /* O_JAIL */)
key = ucred_cache->cr_prison->pr_id;
+#else /* !__FreeBSD__ */
+ (void *)&ucred_cache,
+ (struct inpcb *)args->m);
+ if (v ==4 /* O_UID */)
+ key = ucred_cache.uid;
+ else if (v == 5 /* O_JAIL */)
+ key = ucred_cache.xid;
+#endif /* !__FreeBSD__ */
key = htonl(key);
} else
break;
@@ -1392,11 +1436,10 @@ do { \
match = (tif != NULL);
break;
}
- /* FALLTHROUGH */
#ifdef INET6
+ /* FALLTHROUGH */
case O_IP6_SRC_ME:
- match = is_ipv6 &&
- search_ip6_addr_net(&args->f_id.src_ip6);
+ match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
#endif
break;
@@ -1432,14 +1475,14 @@ do { \
match = (tif != NULL);
break;
}
- /* FALLTHROUGH */
#ifdef INET6
+ /* FALLTHROUGH */
case O_IP6_DST_ME:
- match = is_ipv6 &&
- search_ip6_addr_net(&args->f_id.dst_ip6);
+ match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
#endif
break;
+
case O_IP_SRCPORT:
case O_IP_DSTPORT:
/*
@@ -1998,7 +2041,7 @@ do { \
if (hlen > 0 && is_ipv6 &&
((offset & IP6F_OFF_MASK) == 0) &&
(proto != IPPROTO_ICMPV6 ||
- (is_icmp6_query(args->f_id.flags) == 1)) &&
+ (is_icmp6_query(icmp6_type) == 1)) &&
!(m->m_flags & (M_BCAST|M_MCAST)) &&
!IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
send_reject6(
@@ -2164,8 +2207,10 @@ do { \
printf("ipfw: ouch!, skip past end of rules, denying packet\n");
}
IPFW_RUNLOCK(chain);
+#ifdef __FreeBSD__
if (ucred_cache != NULL)
crfree(ucred_cache);
+#endif
return (retval);
pullup_failed:
@@ -2354,7 +2399,7 @@ vnet_ipfw_uninit(const void *unused)
IPFW_WLOCK(chain);
ipfw_dyn_uninit(0); /* run the callout_drain */
- ipfw_flush_tables(chain);
+ ipfw_destroy_tables(chain);
reap = NULL;
for (i = 0; i < chain->n_rules; i++) {
rule = chain->map[i];
diff --git a/sys/netinet/ipfw/ip_fw_dynamic.c b/sys/netinet/ipfw/ip_fw_dynamic.c
index ad5599a..6947582 100644
--- a/sys/netinet/ipfw/ip_fw_dynamic.c
+++ b/sys/netinet/ipfw/ip_fw_dynamic.c
@@ -128,7 +128,11 @@ static VNET_DEFINE(struct callout, ipfw_timeout);
#define V_ipfw_timeout VNET(ipfw_timeout)
static uma_zone_t ipfw_dyn_rule_zone;
+#ifndef __FreeBSD__
+DEFINE_SPINLOCK(ipfw_dyn_mtx);
+#else
static struct mtx ipfw_dyn_mtx; /* mutex guarding dynamic rules */
+#endif
#define IPFW_DYN_LOCK_INIT() \
mtx_init(&ipfw_dyn_mtx, "IPFW dynamic rules", NULL, MTX_DEF)
@@ -183,6 +187,9 @@ static VNET_DEFINE(u_int32_t, dyn_max); /* max # of dynamic rules */
#define V_dyn_max VNET(dyn_max)
#ifdef SYSCTL_NODE
+
+SYSBEGIN(f2)
+
SYSCTL_DECL(_net_inet_ip_fw);
SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
@@ -217,6 +224,9 @@ SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
"Enable keepalives for dyn. rules");
+
+SYSEND
+
#endif /* SYSCTL_NODE */
@@ -466,7 +476,7 @@ next:
V_ipfw_dyn_v[i] = q;
}
if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
- u_char flags = pkt->flags & (TH_FIN|TH_SYN|TH_RST);
+ u_char flags = pkt->_flags & (TH_FIN|TH_SYN|TH_RST);
#define BOTH_SYN (TH_SYN | (TH_SYN << 8))
#define BOTH_FIN (TH_FIN | (TH_FIN << 8))
@@ -884,6 +894,9 @@ struct mbuf *
ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
u_int32_t ack, int flags)
{
+#ifndef __FreeBSD__
+ return NULL;
+#else
struct mbuf *m;
int len, dir;
struct ip *h = NULL; /* stupid compiler */
@@ -1020,6 +1033,7 @@ ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
}
return (m);
+#endif /* __FreeBSD__ */
}
/*
diff --git a/sys/netinet/ipfw/ip_fw_log.c b/sys/netinet/ipfw/ip_fw_log.c
index a5178db..93bd19b 100644
--- a/sys/netinet/ipfw/ip_fw_log.c
+++ b/sys/netinet/ipfw/ip_fw_log.c
@@ -395,7 +395,7 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
snprintf(SNPARGS(fragment, 0),
" (frag %08x:%d@%d%s)",
- args->f_id.frag_id6,
+ args->f_id.extra,
ntohs(ip6->ip6_plen) - hlen,
ntohs(offset & IP6F_OFF_MASK) << 3,
(offset & IP6F_MORE_FRAG) ? "+" : "");
@@ -413,6 +413,7 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
(ipoff & IP_MF) ? "+" : "");
}
}
+#ifdef __FreeBSD__
if (oif || m->m_pkthdr.rcvif)
log(LOG_SECURITY | LOG_INFO,
"ipfw: %d %s %s %s via %s%s\n",
@@ -421,6 +422,7 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
fragment);
else
+#endif
log(LOG_SECURITY | LOG_INFO,
"ipfw: %d %s %s [no if info]%s\n",
f ? f->rulenum : -1,
diff --git a/sys/netinet/ipfw/ip_fw_pfil.c b/sys/netinet/ipfw/ip_fw_pfil.c
index a7aa5aa..e87a4c9 100644
--- a/sys/netinet/ipfw/ip_fw_pfil.c
+++ b/sys/netinet/ipfw/ip_fw_pfil.c
@@ -77,6 +77,9 @@ int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int);
#ifdef SYSCTL_NODE
+
+SYSBEGIN(f1)
+
SYSCTL_DECL(_net_inet_ip_fw);
SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
@@ -87,6 +90,9 @@ SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
ipfw_chg_hook, "I", "Enable ipfw+6");
#endif /* INET6 */
+
+SYSEND
+
#endif /* SYSCTL_NODE */
/*
@@ -94,7 +100,7 @@ SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
* dummynet, divert, netgraph or other modules.
* The packet may be consumed.
*/
-static int
+int
ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
@@ -141,8 +147,8 @@ again:
switch (ipfw) {
case IP_FW_PASS:
/* next_hop may be set by ipfw_chk */
- if (args.next_hop == NULL)
- break; /* pass */
+ if (args.next_hop == NULL)
+ break; /* pass */
#ifndef IPFIREWALL_FORWARD
ret = EACCES;
#else
@@ -341,14 +347,14 @@ ipfw_attach_hooks(int arg)
if (arg == 0) /* detach */
ipfw_hook(0, AF_INET);
- else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) {
+ else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) {
error = ENOENT; /* see ip_fw_pfil.c::ipfw_hook() */
printf("ipfw_hook() error\n");
}
#ifdef INET6
if (arg == 0) /* detach */
ipfw_hook(0, AF_INET6);
- else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) {
+ else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) {
error = ENOENT;
printf("ipfw6_hook() error\n");
}
diff --git a/sys/netinet/ipfw/ip_fw_private.h b/sys/netinet/ipfw/ip_fw_private.h
index 92508f1..ac55433 100644
--- a/sys/netinet/ipfw/ip_fw_private.h
+++ b/sys/netinet/ipfw/ip_fw_private.h
@@ -35,6 +35,18 @@
#ifdef _KERNEL
+/*
+ * For platforms that do not have SYSCTL support, we wrap the
+ * SYSCTL_* into a function (one per file) to collect the values
+ * into an array at module initialization. The wrapping macros,
+ * SYSBEGIN() and SYSEND, are empty in the default case.
+ */
+#ifndef SYSBEGIN
+#define SYSBEGIN(x)
+#endif
+#ifndef SYSEND
+#define SYSEND
+#endif
/* Return values from ipfw_chk() */
enum {
@@ -119,7 +131,13 @@ enum {
};
/* wrapper for freeing a packet, in case we need to do more work */
+#ifndef FREE_PKT
+#if defined(__linux__) || defined(_WIN32)
+#define FREE_PKT(m) netisr_dispatch(-1, m)
+#else
#define FREE_PKT(m) m_freem(m)
+#endif
+#endif /* !FREE_PKT */
/*
* Function definitions.
@@ -196,11 +214,16 @@ struct ip_fw_chain {
struct ip_fw *default_rule;
int n_rules; /* number of static rules */
int static_len; /* total len of static rules */
- struct ip_fw **map; /* array of rule ptrs to ease lookup */
+ struct ip_fw **map; /* array of rule ptrs to ease lookup */
LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */
struct radix_node_head *tables[IPFW_TABLES_MAX];
+#if defined( __linux__ ) || defined( _WIN32 )
+ spinlock_t rwmtx;
+ spinlock_t uh_lock;
+#else
struct rwlock rwmtx;
struct rwlock uh_lock; /* lock for upper half */
+#endif
uint32_t id; /* ruleset id */
};
@@ -240,13 +263,17 @@ int ipfw_ctl(struct sockopt *sopt);
int ipfw_chk(struct ip_fw_args *args);
void ipfw_reap_rules(struct ip_fw *head);
+/* In ip_fw_pfil */
+int ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
+ struct inpcb *inp);
+
/* In ip_fw_table.c */
struct radix_node;
int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
uint32_t *val);
int ipfw_init_tables(struct ip_fw_chain *ch);
+void ipfw_destroy_tables(struct ip_fw_chain *ch);
int ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl);
-void ipfw_flush_tables(struct ip_fw_chain *ch);
int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
uint8_t mlen, uint32_t value);
int ipfw_dump_table_entry(struct radix_node *rn, void *arg);
diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
index 3d0fc55..c505728 100644
--- a/sys/netinet/ipfw/ip_fw_sockopt.c
+++ b/sys/netinet/ipfw/ip_fw_sockopt.c
@@ -115,7 +115,8 @@ get_map(struct ip_fw_chain *chain, int extra, int locked)
int i;
i = chain->n_rules + extra;
- map = malloc(i * sizeof(struct ip_fw *), M_IPFW, M_WAITOK);
+ map = malloc(i * sizeof(struct ip_fw *), M_IPFW,
+ locked ? M_NOWAIT : M_WAITOK);
if (map == NULL) {
printf("%s: cannot allocate map\n", __FUNCTION__);
return NULL;
@@ -231,61 +232,103 @@ ipfw_reap_rules(struct ip_fw *head)
}
}
+/*
+ * Used by del_entry() to check if a rule should be kept.
+ * Returns 1 if the rule must be kept, 0 otherwise.
+ *
+ * Called with cmd = {0,1,5}.
+ * cmd == 0 matches on rule numbers, excludes rules in RESVD_SET if n == 0 ;
+ * cmd == 1 matches on set numbers only, rule numbers are ignored;
+ * cmd == 5 matches on rule and set numbers.
+ *
+ * n == 0 is a wildcard for rule numbers, there is no wildcard for sets.
+ *
+ * Rules to keep are
+ * (default || reserved || !match_set || !match_number)
+ * where
+ * default ::= (rule->rulenum == IPFW_DEFAULT_RULE)
+ * // the default rule is always protected
+ *
+ * reserved ::= (cmd == 0 && n == 0 && rule->set == RESVD_SET)
+ * // RESVD_SET is protected only if cmd == 0 and n == 0 ("ipfw flush")
+ *
+ * match_set ::= (cmd == 0 || rule->set == set)
+ * // set number is ignored for cmd == 0
+ *
+ * match_number ::= (cmd == 1 || n == 0 || n == rule->rulenum)
+ * // number is ignored for cmd == 1 or n == 0
+ *
+ */
+static int
+keep_rule(struct ip_fw *rule, uint8_t cmd, uint8_t set, uint32_t n)
+{
+ return
+ (rule->rulenum == IPFW_DEFAULT_RULE) ||
+ (cmd == 0 && n == 0 && rule->set == RESVD_SET) ||
+ !(cmd == 0 || rule->set == set) ||
+ !(cmd == 1 || n == 0 || n == rule->rulenum);
+}
+
/**
- * Remove all rules with given number, and also do set manipulation.
+ * Remove all rules with given number, or do set manipulation.
* Assumes chain != NULL && *chain != NULL.
*
- * The argument is an u_int32_t. The low 16 bit are the rule or set number,
- * the next 8 bits are the new set, the top 8 bits are the command:
+ * The argument is an uint32_t. The low 16 bit are the rule or set number;
+ * the next 8 bits are the new set; the top 8 bits indicate the command:
*
- * 0 delete rules with given number
- * 1 delete rules with given set number
- * 2 move rules with given number to new set
- * 3 move rules with given set number to new set
- * 4 swap sets with given numbers
- * 5 delete rules with given number and with given set number
+ * 0 delete rules numbered "rulenum"
+ * 1 delete rules in set "rulenum"
+ * 2 move rules "rulenum" to set "new_set"
+ * 3 move rules from set "rulenum" to set "new_set"
+ * 4 swap sets "rulenum" and "new_set"
+ * 5 delete rules "rulenum" and set "new_set"
*/
static int
-del_entry(struct ip_fw_chain *chain, u_int32_t arg)
+del_entry(struct ip_fw_chain *chain, uint32_t arg)
{
struct ip_fw *rule;
- uint32_t rulenum; /* rule or old_set */
+ uint32_t num; /* rule number or old_set */
uint8_t cmd, new_set;
- int start, end = 0, i, ofs, n;
+ int start, end, i, ofs, n;
struct ip_fw **map = NULL;
int error = 0;
- rulenum = arg & 0xffff;
+ num = arg & 0xffff;
cmd = (arg >> 24) & 0xff;
new_set = (arg >> 16) & 0xff;
if (cmd > 5 || new_set > RESVD_SET)
return EINVAL;
if (cmd == 0 || cmd == 2 || cmd == 5) {
- if (rulenum >= IPFW_DEFAULT_RULE)
+ if (num >= IPFW_DEFAULT_RULE)
return EINVAL;
} else {
- if (rulenum > RESVD_SET) /* old_set */
+ if (num > RESVD_SET) /* old_set */
return EINVAL;
}
- IPFW_UH_WLOCK(chain); /* prevent conflicts among the writers */
+ IPFW_UH_WLOCK(chain); /* arbitrate writers */
chain->reap = NULL; /* prepare for deletions */
switch (cmd) {
- case 0: /* delete rules with given number (0 is special means all) */
- case 1: /* delete all rules with given set number, rule->set == rulenum */
- case 5: /* delete rules with given number and with given set number.
- * rulenum - given rule number;
- * new_set - given set number.
- */
- /* locate first rule to delete (start), the one after the
- * last one (end), and count how many rules to delete (n)
+ case 0: /* delete rules "num" (num == 0 matches all) */
+ case 1: /* delete all rules in set N */
+ case 5: /* delete rules with number N and set "new_set". */
+
+ /*
+ * Locate first rule to delete (start), the rule after
+ * the last one to delete (end), and count how many
+ * rules to delete (n). Always use keep_rule() to
+ * determine which rules to keep.
*/
n = 0;
- if (cmd == 1) { /* look for a specific set, must scan all */
- for (start = -1, i = 0; i < chain->n_rules; i++) {
- if (chain->map[start]->set != rulenum)
+ if (cmd == 1) {
+ /* look for a specific set including RESVD_SET.
+ * Must scan the entire range, ignore num.
+ */
+ new_set = num;
+ for (start = -1, end = i = 0; i < chain->n_rules; i++) {
+ if (keep_rule(chain->map[i], cmd, new_set, 0))
continue;
if (start < 0)
start = i;
@@ -294,80 +337,94 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg)
}
end++; /* first non-matching */
} else {
- start = ipfw_find_rule(chain, rulenum, 0);
+ /* Optimized search on rule numbers */
+ start = ipfw_find_rule(chain, num, 0);
for (end = start; end < chain->n_rules; end++) {
rule = chain->map[end];
- if (rulenum > 0 && rule->rulenum != rulenum)
+ if (num > 0 && rule->rulenum != num)
break;
- if (rule->set != RESVD_SET &&
- (cmd == 0 || rule->set == new_set) )
+ if (!keep_rule(rule, cmd, new_set, num))
n++;
}
}
- if (n == 0 && arg == 0)
- break; /* special case, flush on empty ruleset */
- /* allocate the map, if needed */
- if (n > 0)
- map = get_map(chain, -n, 1 /* locked */);
- if (n == 0 || map == NULL) {
+
+ if (n == 0) {
+ /* A flush request (arg == 0) on empty ruleset
+ * returns with no error. On the contrary,
+ * if there is no match on a specific request,
+ * we return EINVAL.
+ */
+ error = (arg == 0) ? 0 : EINVAL;
+ break;
+ }
+
+ /* We have something to delete. Allocate the new map */
+ map = get_map(chain, -n, 1 /* locked */);
+ if (map == NULL) {
error = EINVAL;
break;
}
- /* copy the initial part of the map */
+
+ /* 1. bcopy the initial part of the map */
if (start > 0)
bcopy(chain->map, map, start * sizeof(struct ip_fw *));
- /* copy active rules between start and end */
+ /* 2. copy active rules between start and end */
for (i = ofs = start; i < end; i++) {
rule = chain->map[i];
- if (!(rule->set != RESVD_SET &&
- (cmd == 0 || rule->set == new_set) ))
- map[ofs++] = chain->map[i];
+ if (keep_rule(rule, cmd, new_set, num))
+ map[ofs++] = rule;
}
- /* finally the tail */
+ /* 3. copy the final part of the map */
bcopy(chain->map + end, map + ofs,
(chain->n_rules - end) * sizeof(struct ip_fw *));
+ /* 4. swap the maps (under BH_LOCK) */
map = swap_map(chain, map, chain->n_rules - n);
- /* now remove the rules deleted */
+ /* 5. now remove the rules deleted from the old map */
for (i = start; i < end; i++) {
+ int l;
rule = map[i];
- if (rule->set != RESVD_SET &&
- (cmd == 0 || rule->set == new_set) ) {
- int l = RULESIZE(rule);
-
- chain->static_len -= l;
- ipfw_remove_dyn_children(rule);
- rule->x_next = chain->reap;
- chain->reap = rule;
- }
+ if (keep_rule(rule, cmd, new_set, num))
+ continue;
+ l = RULESIZE(rule);
+ chain->static_len -= l;
+ ipfw_remove_dyn_children(rule);
+ rule->x_next = chain->reap;
+ chain->reap = rule;
}
break;
- case 2: /* move rules with given number to new set */
- for (i = 0; i < chain->n_rules; i++) {
+ /*
+ * In the next 3 cases the loop stops at (n_rules - 1)
+ * because the default rule is never eligible..
+ */
+
+ case 2: /* move rules with given RULE number to new set */
+ for (i = 0; i < chain->n_rules - 1; i++) {
rule = chain->map[i];
- if (rule->rulenum == rulenum)
+ if (rule->rulenum == num)
rule->set = new_set;
}
break;
- case 3: /* move rules with given set number to new set */
- for (i = 0; i < chain->n_rules; i++) {
+ case 3: /* move rules with given SET number to new set */
+ for (i = 0; i < chain->n_rules - 1; i++) {
rule = chain->map[i];
- if (rule->set == rulenum)
+ if (rule->set == num)
rule->set = new_set;
}
break;
case 4: /* swap two sets */
- for (i = 0; i < chain->n_rules; i++) {
+ for (i = 0; i < chain->n_rules - 1; i++) {
rule = chain->map[i];
- if (rule->set == rulenum)
+ if (rule->set == num)
rule->set = new_set;
else if (rule->set == new_set)
- rule->set = rulenum;
+ rule->set = num;
}
break;
}
+
rule = chain->reap;
chain->reap = NULL;
IPFW_UH_WUNLOCK(chain);
@@ -445,7 +502,7 @@ zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
break;
}
if (!cleared) { /* we did not find any matching rules */
- IPFW_WUNLOCK(chain);
+ IPFW_UH_RUNLOCK(chain);
return (EINVAL);
}
msg = log_only ? "logging count reset" : "cleared";
@@ -771,6 +828,44 @@ bad_size:
return EINVAL;
}
+
+/*
+ * Translation of requests for compatibility with FreeBSD 7.2/8.
+ * a static variable tells us if we have an old client from userland,
+ * and if necessary we translate requests and responses between the
+ * two formats.
+ */
+static int is7 = 0;
+
+struct ip_fw7 {
+ struct ip_fw7 *next; /* linked list of rules */
+ struct ip_fw7 *next_rule; /* ptr to next [skipto] rule */
+ /* 'next_rule' is used to pass up 'set_disable' status */
+
+ uint16_t act_ofs; /* offset of action in 32-bit units */
+ uint16_t cmd_len; /* # of 32-bit words in cmd */
+ uint16_t rulenum; /* rule number */
+ uint8_t set; /* rule set (0..31) */
+ // #define RESVD_SET 31 /* set for default and persistent rules */
+ uint8_t _pad; /* padding */
+ // uint32_t id; /* rule id, only in v.8 */
+ /* These fields are present in all rules. */
+ uint64_t pcnt; /* Packet counter */
+ uint64_t bcnt; /* Byte counter */
+ uint32_t timestamp; /* tv_sec of last match */
+
+ ipfw_insn cmd[1]; /* storage for commands */
+};
+
+ int convert_rule_to_7(struct ip_fw *rule);
+int convert_rule_to_8(struct ip_fw *rule);
+
+#ifndef RULESIZE7
+#define RULESIZE7(rule) (sizeof(struct ip_fw7) + \
+ ((struct ip_fw7 *)(rule))->cmd_len * 4 - 4)
+#endif
+
+
/*
* Copy the static and dynamic rules to the supplied buffer
* and return the amount of space actually used.
@@ -788,6 +883,32 @@ ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
boot_seconds = boottime.tv_sec;
for (i = 0; i < chain->n_rules; i++) {
rule = chain->map[i];
+
+ if (is7) {
+ /* Convert rule to FreeBSd 7.2 format */
+ l = RULESIZE7(rule);
+ if (bp + l + sizeof(uint32_t) <= ep) {
+ int error;
+ bcopy(rule, bp, l + sizeof(uint32_t));
+ error = convert_rule_to_7((struct ip_fw *) bp);
+ if (error)
+ return 0; /*XXX correct? */
+ /*
+ * XXX HACK. Store the disable mask in the "next"
+ * pointer in a wild attempt to keep the ABI the same.
+ * Why do we do this on EVERY rule?
+ */
+ bcopy(&V_set_disable,
+ &(((struct ip_fw7 *)bp)->next_rule),
+ sizeof(V_set_disable));
+ if (((struct ip_fw7 *)bp)->timestamp)
+ ((struct ip_fw7 *)bp)->timestamp += boot_seconds;
+ bp += l;
+ }
+ continue; /* go to next rule */
+ }
+
+ /* normal mode, don't touch rules */
l = RULESIZE(rule);
if (bp + l > ep) { /* should not happen */
printf("overflow dumping static rules\n");
@@ -886,16 +1007,43 @@ ipfw_ctl(struct sockopt *sopt)
case IP_FW_ADD:
rule = malloc(RULE_MAXSIZE, M_TEMP, M_WAITOK);
error = sooptcopyin(sopt, rule, RULE_MAXSIZE,
- sizeof(struct ip_fw) );
+ sizeof(struct ip_fw7) );
+
+ /*
+ * If the size of commands equals RULESIZE7 then we assume
+ * a FreeBSD7.2 binary is talking to us (set is7=1).
+ * is7 is persistent so the next 'ipfw list' command
+ * will use this format.
+ * NOTE: If wrong version is guessed (this can happen if
+ * the first ipfw command is 'ipfw [pipe] list')
+ * the ipfw binary may crash or loop infinitly...
+ */
+ if (sopt->sopt_valsize == RULESIZE7(rule)) {
+ is7 = 1;
+ error = convert_rule_to_8(rule);
+ if (error)
+ return error;
+ if (error == 0)
+ error = check_ipfw_struct(rule, RULESIZE(rule));
+ } else {
+ is7 = 0;
if (error == 0)
error = check_ipfw_struct(rule, sopt->sopt_valsize);
+ }
if (error == 0) {
/* locking is done within ipfw_add_rule() */
error = ipfw_add_rule(chain, rule);
size = RULESIZE(rule);
- if (!error && sopt->sopt_dir == SOPT_GET)
+ if (!error && sopt->sopt_dir == SOPT_GET) {
+ if (is7) {
+ error = convert_rule_to_7(rule);
+ size = RULESIZE7(rule);
+ if (error)
+ return error;
+ }
error = sooptcopyout(sopt, rule, size);
}
+ }
free(rule, M_TEMP);
break;
@@ -1078,4 +1226,118 @@ ipfw_ctl(struct sockopt *sopt)
return (error);
#undef RULE_MAXSIZE
}
+
+
+#define RULE_MAXSIZE (256*sizeof(u_int32_t))
+
+/* Functions to convert rules 7.2 <==> 8.0 */
+int
+convert_rule_to_7(struct ip_fw *rule)
+{
+ /* Used to modify original rule */
+ struct ip_fw7 *rule7 = (struct ip_fw7 *)rule;
+ /* copy of original rule, version 8 */
+ struct ip_fw *tmp;
+
+ /* Used to copy commands */
+ ipfw_insn *ccmd, *dst;
+ int ll = 0, ccmdlen = 0;
+
+ tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
+ if (tmp == NULL) {
+ return 1; //XXX error
+ }
+ bcopy(rule, tmp, RULE_MAXSIZE);
+
+ /* Copy fields */
+ rule7->_pad = tmp->_pad;
+ rule7->set = tmp->set;
+ rule7->rulenum = tmp->rulenum;
+ rule7->cmd_len = tmp->cmd_len;
+ rule7->act_ofs = tmp->act_ofs;
+ rule7->next_rule = (struct ip_fw7 *)tmp->next_rule;
+ rule7->next = (struct ip_fw7 *)tmp->x_next;
+ rule7->cmd_len = tmp->cmd_len;
+ rule7->pcnt = tmp->pcnt;
+ rule7->bcnt = tmp->bcnt;
+ rule7->timestamp = tmp->timestamp;
+
+ /* Copy commands */
+ for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule7->cmd ;
+ ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
+ ccmdlen = F_LEN(ccmd);
+
+ bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
+
+ if (dst->opcode > O_NAT)
+ /* O_REASS doesn't exists in 7.2 version, so
+ * decrement opcode if it is after O_REASS
+ */
+ dst->opcode--;
+
+ if (ccmdlen > ll) {
+ printf("ipfw: opcode %d size truncated\n",
+ ccmd->opcode);
+ return EINVAL;
+ }
+ }
+ free(tmp, M_TEMP);
+
+ return 0;
+}
+
+int
+convert_rule_to_8(struct ip_fw *rule)
+{
+ /* Used to modify original rule */
+ struct ip_fw7 *rule7 = (struct ip_fw7 *) rule;
+
+ /* Used to copy commands */
+ ipfw_insn *ccmd, *dst;
+ int ll = 0, ccmdlen = 0;
+
+ /* Copy of original rule */
+ struct ip_fw7 *tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
+ if (tmp == NULL) {
+ return 1; //XXX error
+ }
+
+ bcopy(rule7, tmp, RULE_MAXSIZE);
+
+ for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule->cmd ;
+ ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
+ ccmdlen = F_LEN(ccmd);
+
+ bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
+
+ if (dst->opcode > O_NAT)
+ /* O_REASS doesn't exists in 7.2 version, so
+ * increment opcode if it is after O_REASS
+ */
+ dst->opcode++;
+
+ if (ccmdlen > ll) {
+ printf("ipfw: opcode %d size truncated\n",
+ ccmd->opcode);
+ return EINVAL;
+ }
+ }
+
+ rule->_pad = tmp->_pad;
+ rule->set = tmp->set;
+ rule->rulenum = tmp->rulenum;
+ rule->cmd_len = tmp->cmd_len;
+ rule->act_ofs = tmp->act_ofs;
+ rule->next_rule = (struct ip_fw *)tmp->next_rule;
+ rule->x_next = (struct ip_fw *)tmp->next;
+ rule->cmd_len = tmp->cmd_len;
+ rule->id = 0; /* XXX see if is ok = 0 */
+ rule->pcnt = tmp->pcnt;
+ rule->bcnt = tmp->bcnt;
+ rule->timestamp = tmp->timestamp;
+
+ free (tmp, M_TEMP);
+ return 0;
+}
+
/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_table.c b/sys/netinet/ipfw/ip_fw_table.c
index 0d8625a..517622f 100644
--- a/sys/netinet/ipfw/ip_fw_table.c
+++ b/sys/netinet/ipfw/ip_fw_table.c
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/ip_var.h> /* struct ipfw_rule_ref */
#include <netinet/ip_fw.h>
+#include <sys/queue.h> /* LIST_HEAD */
#include <netinet/ipfw/ip_fw_private.h>
#ifdef MAC
@@ -175,14 +176,18 @@ ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl)
}
void
-ipfw_flush_tables(struct ip_fw_chain *ch)
+ipfw_destroy_tables(struct ip_fw_chain *ch)
{
uint16_t tbl;
+ struct radix_node_head *rnh;
IPFW_WLOCK_ASSERT(ch);
- for (tbl = 0; tbl < IPFW_TABLES_MAX; tbl++)
+ for (tbl = 0; tbl < IPFW_TABLES_MAX; tbl++) {
ipfw_flush_table(ch, tbl);
+ rnh = ch->tables[tbl];
+ rn_detachhead((void **)&rnh);
+ }
}
int
diff --git a/sys/netinet/ipfw/test/Makefile b/sys/netinet/ipfw/test/Makefile
new file mode 100644
index 0000000..c556a4b
--- /dev/null
+++ b/sys/netinet/ipfw/test/Makefile
@@ -0,0 +1,51 @@
+#
+# $FreeBSD$
+#
+# Makefile for building userland tests
+# this is written in a form compatible with gmake
+
+SCHED_SRCS = test_dn_sched.c
+SCHED_SRCS += dn_sched_fifo.c
+SCHED_SRCS += dn_sched_prio.c
+SCHED_SRCS += dn_sched_qfq.c
+SCHED_SRCS += dn_sched_rr.c
+SCHED_SRCS += dn_sched_wf2q.c
+SCHED_SRCS += dn_heap.c
+SCHED_SRCS += main.c
+
+SCHED_OBJS=$(SCHED_SRCS:.c=.o)
+
+HEAP_SRCS = dn_heap.c test_dn_heap.c
+HEAP_OBJS=$(HEAP_SRCS:.c=.o)
+
+VPATH= .:..
+
+CFLAGS = -I.. -I. -Wall -Werror -O3 -DIPFW
+TARGETS= test_sched # no test_heap by default
+
+all: $(TARGETS)
+
+test_heap : $(HEAP_OBJS)
+ $(CC) -o $@ $(HEAP_OBJS)
+
+test_sched : $(SCHED_OBJS)
+ $(CC) -o $@ $(SCHED_OBJS)
+
+$(SCHED_OBJS): dn_test.h
+main.o: mylist.h
+
+clean:
+ - rm *.o $(TARGETS) *.core
+
+ALLSRCS = $(SCHED_SRCS) dn_test.h mylist.h \
+ dn_sched.h dn_heap.h ip_dn_private.h Makefile
+TMPBASE = /tmp/testXYZ
+TMPDIR = $(TMPBASE)/test
+
+tgz:
+ -rm -rf $(TMPDIR)
+ mkdir -p $(TMPDIR)
+ -cp -p $(ALLSRCS) $(TMPDIR)
+ -(cd ..; cp -p $(ALLSRCS) $(TMPDIR))
+ ls -la $(TMPDIR)
+ (cd $(TMPBASE); tar cvzf /tmp/test.tgz test)
diff --git a/sys/netinet/ipfw/test/dn_test.h b/sys/netinet/ipfw/test/dn_test.h
new file mode 100644
index 0000000..4e079bc
--- /dev/null
+++ b/sys/netinet/ipfw/test/dn_test.h
@@ -0,0 +1,175 @@
+/*
+ * $FreeBSD$
+ *
+ * userspace compatibility code for dummynet schedulers
+ */
+
+#ifndef _DN_TEST_H
+#define _DN_TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h> /* bzero, ffs, ... */
+#include <string.h> /* strcmp */
+#include <errno.h>
+#include <sys/queue.h>
+#include <sys/time.h>
+
+extern int debug;
+#define ND(fmt, args...) do {} while (0)
+#define D1(fmt, args...) do {} while (0)
+#define D(fmt, args...) fprintf(stderr, "%-8s " fmt "\n", \
+ __FUNCTION__, ## args)
+#define DX(lev, fmt, args...) do { \
+ if (debug > lev) D(fmt, ## args); } while (0)
+
+
+#ifndef offsetof
+#define offsetof(t,m) (int)((&((t *)0L)->m))
+#endif
+
+#include <mylist.h>
+
+/* prevent include of other system headers */
+#define _NETINET_IP_VAR_H_ /* ip_fw_args */
+#define _IPFW2_H
+#define _SYS_MBUF_H_
+
+enum {
+ DN_QUEUE,
+};
+
+enum {
+ DN_SCHED_FIFO,
+ DN_SCHED_WF2QP,
+};
+
+struct dn_id {
+ int type, subtype, len, id;
+};
+
+struct dn_fs {
+ int par[4]; /* flowset parameters */
+
+ /* simulation entries.
+ * 'index' is not strictly necessary
+ * y is used for the inverse mapping ,
+ */
+ int index;
+ int y; /* inverse mapping */
+ int base_y; /* inverse mapping */
+ int next_y; /* inverse mapping */
+ int n_flows;
+ int first_flow;
+ int next_flow; /* first_flow + n_flows */
+ /*
+ * when generating, let 'cur' go from 0 to n_flows-1,
+ * then point to flow first_flow + cur
+ */
+ int cur;
+};
+
+struct dn_sch {
+};
+
+struct dn_flow {
+ struct dn_id oid;
+ int length;
+ int len_bytes;
+ int drops;
+ uint64_t tot_bytes;
+ uint32_t flow_id;
+ struct list_head h; /* used by the generator */
+};
+
+struct dn_link {
+};
+
+struct ip_fw_args {
+};
+
+struct mbuf {
+ struct {
+ int len;
+ } m_pkthdr;
+ struct mbuf *m_nextpkt;
+ int flow_id; /* for testing, index of a flow */
+ //int flowset_id; /* for testing, index of a flowset */
+ void *cfg; /* config args */
+};
+
+#define MALLOC_DECLARE(x)
+#define KASSERT(x, y) do { if (!(x)) printf y ; exit(0); } while (0)
+struct ipfw_flow_id {
+};
+
+typedef void * module_t;
+
+struct _md_t {
+ const char *name;
+ int (*f)(module_t, int, void *);
+ void *p;
+};
+
+typedef struct _md_t moduledata_t;
+
+#define DECLARE_MODULE(name, b, c, d) \
+ moduledata_t *_g_##name = & b
+#define MODULE_DEPEND(a, b, c, d, e)
+
+#ifdef IPFW
+#include <dn_heap.h>
+#include <ip_dn_private.h>
+#include <dn_sched.h>
+#else
+struct dn_queue {
+ struct dn_fsk *fs; /* parent flowset. */
+ struct dn_sch_inst *_si; /* parent sched instance. */
+};
+struct dn_schk {
+};
+struct dn_fsk {
+ struct dn_fs fs;
+ struct dn_schk *sched;
+};
+struct dn_sch_inst {
+ struct dn_schk *sched;
+};
+struct dn_alg {
+ int type;
+ const char *name;
+ void *enqueue, *dequeue;
+ int q_datalen, si_datalen, schk_datalen;
+ int (*config)(struct dn_schk *);
+ int (*new_sched)(struct dn_sch_inst *);
+ int (*new_fsk)(struct dn_fsk *);
+ int (*new_queue)(struct dn_queue *q);
+};
+
+#endif
+
+#ifndef __FreeBSD__
+int fls(int);
+#endif
+
+static inline void
+mq_append(struct mq *q, struct mbuf *m)
+{
+ if (q->head == NULL)
+ q->head = m;
+ else
+ q->tail->m_nextpkt = m;
+ q->tail = m;
+ m->m_nextpkt = NULL;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DN_TEST_H */
diff --git a/sys/netinet/ipfw/test/main.c b/sys/netinet/ipfw/test/main.c
new file mode 100644
index 0000000..be9fdf5
--- /dev/null
+++ b/sys/netinet/ipfw/test/main.c
@@ -0,0 +1,636 @@
+/*
+ * $FreeBSD$
+ *
+ * Testing program for schedulers
+ *
+ * The framework include a simple controller which, at each
+ * iteration, decides whether we can enqueue and/or dequeue.
+ * Then the mainloop runs the required number of tests,
+ * keeping track of statistics.
+ */
+
+#include "dn_test.h"
+
+struct q_list {
+ struct list_head h;
+};
+
+struct cfg_s {
+ int ac;
+ char * const *av;
+
+ const char *name;
+ int loops;
+ struct timeval time;
+
+ /* running counters */
+ uint32_t _enqueue;
+ uint32_t drop;
+ uint32_t pending;
+ uint32_t dequeue;
+
+ /* generator parameters */
+ int th_min, th_max;
+ int maxburst;
+ int lmin, lmax; /* packet len */
+ int flows; /* number of flows */
+ int flowsets; /* number of flowsets */
+ int wsum; /* sum of weights of all flows */
+ int max_y; /* max random number in the generation */
+ int cur_y, cur_fs; /* used in generation, between 0 and max_y - 1 */
+ const char *fs_config; /* flowset config */
+ int can_dequeue;
+ int burst; /* count of packets sent in a burst */
+ struct mbuf *tosend; /* packet to send -- also flag to enqueue */
+
+ struct mbuf *freelist;
+
+ struct mbuf *head, *tail; /* a simple tailq */
+
+ /* scheduler hooks */
+ int (*enq)(struct dn_sch_inst *, struct dn_queue *,
+ struct mbuf *);
+ struct mbuf * (*deq)(struct dn_sch_inst *);
+ /* size of the three fields including sched-specific areas */
+ int schk_len;
+ int q_len; /* size of a queue including sched-fields */
+ int si_len; /* size of a sch_inst including sched-fields */
+ char *q; /* array of flow queues */
+ /* use a char* because size is variable */
+ struct dn_fsk *fs; /* array of flowsets */
+ struct dn_sch_inst *si;
+ struct dn_schk *sched;
+
+ /* generator state */
+ int state; /* 0 = going up, 1: going down */
+
+ /*
+ * We keep lists for each backlog level, and always serve
+ * the one with shortest backlog. llmask contains a bitmap
+ * of lists, and ll are the heads of the lists. The last
+ * entry (BACKLOG) contains all entries considered 'full'
+ * XXX to optimize things, entry i could contain queues with
+ * 2^{i-1}+1 .. 2^i entries.
+ */
+#define BACKLOG 30
+ uint32_t llmask;
+ struct list_head ll[BACKLOG + 10];
+};
+
+/* FI2Q and Q2FI converts from flow_id to dn_queue and back.
+ * We cannot easily use pointer arithmetic because it is variable size.
+ */
+#define FI2Q(c, i) ((struct dn_queue *)((c)->q + (c)->q_len * (i)))
+#define Q2FI(c, q) (((char *)(q) - (c)->q)/(c)->q_len)
+
+int debug = 0;
+
+struct dn_parms dn_cfg;
+
+static void controller(struct cfg_s *c);
+
+/* release a packet: put the mbuf in the freelist, and the queue in
+ * the bucket.
+ */
+int
+drop(struct cfg_s *c, struct mbuf *m)
+{
+ struct dn_queue *q;
+ int i;
+
+ c->drop++;
+ q = FI2Q(c, m->flow_id);
+ i = q->ni.length; // XXX or ffs...
+
+ ND("q %p id %d current length %d", q, m->flow_id, i);
+ if (i < BACKLOG) {
+ struct list_head *h = &q->ni.h;
+ c->llmask &= ~(1<<(i+1));
+ c->llmask |= (1<<(i));
+ list_del(h);
+ list_add_tail(h, &c->ll[i]);
+ }
+ m->m_nextpkt = c->freelist;
+ c->freelist = m;
+ return 0;
+}
+
+/* dequeue returns NON-NULL when a packet is dropped */
+static int
+enqueue(struct cfg_s *c, void *_m)
+{
+ struct mbuf *m = _m;
+ if (c->enq)
+ return c->enq(c->si, FI2Q(c, m->flow_id), m);
+ if (c->head == NULL)
+ c->head = m;
+ else
+ c->tail->m_nextpkt = m;
+ c->tail = m;
+ return 0; /* default - success */
+}
+
+/* dequeue returns NON-NULL when a packet is available */
+static void *
+dequeue(struct cfg_s *c)
+{
+ struct mbuf *m;
+ if (c->deq)
+ return c->deq(c->si);
+ if ((m = c->head)) {
+ m = c->head;
+ c->head = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ }
+ return m;
+}
+
+static int
+mainloop(struct cfg_s *c)
+{
+ int i;
+ struct mbuf *m;
+
+ for (i=0; i < c->loops; i++) {
+ /* implement histeresis */
+ controller(c);
+ DX(3, "loop %d enq %d send %p rx %d",
+ i, c->_enqueue, c->tosend, c->can_dequeue);
+ if ( (m = c->tosend) ) {
+ c->_enqueue++;
+ if (enqueue(c, m)) {
+ drop(c, m);
+ ND("loop %d enqueue fail", i );
+ } else {
+ ND("enqueue ok");
+ c->pending++;
+ }
+ }
+ if (c->can_dequeue) {
+ c->dequeue++;
+ if ((m = dequeue(c))) {
+ c->pending--;
+ drop(c, m);
+ c->drop--; /* compensate */
+ }
+ }
+ }
+ DX(1, "mainloop ends %d", i);
+ return 0;
+}
+
+int
+dump(struct cfg_s *c)
+{
+ int i;
+ struct dn_queue *q;
+
+ for (i=0; i < c->flows; i++) {
+ q = FI2Q(c, i);
+ DX(1, "queue %4d tot %10lld", i, q->ni.tot_bytes);
+ }
+ DX(1, "done %d loops\n", c->loops);
+ return 0;
+}
+
+/* interpret a number in human form */
+static long
+getnum(const char *s, char **next, const char *key)
+{
+ char *end = NULL;
+ long l;
+
+ if (next) /* default */
+ *next = NULL;
+ if (s && *s) {
+ DX(3, "token is <%s> %s", s, key ? key : "-");
+ l = strtol(s, &end, 0);
+ } else {
+ DX(3, "empty string");
+ l = -1;
+ }
+ if (l < 0) {
+ DX(2, "invalid %s for %s", s ? s : "NULL", (key ? key : "") );
+ return 0; // invalid
+ }
+ if (!end || !*end)
+ return l;
+ if (*end == 'n')
+ l = -l; /* multiply by n */
+ else if (*end == 'K')
+ l = l*1000;
+ else if (*end == 'M')
+ l = l*1000000;
+ else if (*end == 'k')
+ l = l*1024;
+ else if (*end == 'm')
+ l = l*1024*1024;
+ else if (*end == 'w')
+ ;
+ else {/* not recognized */
+ D("suffix %s for %s, next %p", end, key, next);
+ end--;
+ }
+ end++;
+ DX(3, "suffix now %s for %s, next %p", end, key, next);
+ if (next && *end) {
+ DX(3, "setting next to %s for %s", end, key);
+ *next = end;
+ }
+ return l;
+}
+
+/*
+ * flowsets are a comma-separated list of
+ * weight:maxlen:flows
+ * indicating how many flows are hooked to that fs.
+ * Both weight and range can be min-max-steps.
+ * In a first pass we just count the number of flowsets and flows,
+ * in a second pass we complete the setup.
+ */
+static void
+parse_flowsets(struct cfg_s *c, const char *fs, int pass)
+{
+ char *s, *cur, *next;
+ int n_flows = 0, n_fs = 0, wsum = 0;
+ int i, j;
+ struct dn_fs *prev = NULL;
+
+ DX(3, "--- pass %d flows %d flowsets %d", pass, c->flows, c->flowsets);
+ if (pass == 0)
+ c->fs_config = fs;
+ s = c->fs_config ? strdup(c->fs_config) : NULL;
+ if (s == NULL) {
+ if (pass == 0)
+ D("no fsconfig");
+ return;
+ }
+ for (next = s; (cur = strsep(&next, ","));) {
+ char *p = NULL;
+ int w, w_h, w_steps, wi;
+ int len, len_h, l_steps, li;
+ int flows;
+
+ w = getnum(strsep(&cur, ":"), &p, "weight");
+ if (w <= 0)
+ w = 1;
+ w_h = p ? getnum(p+1, &p, "weight_max") : w;
+ w_steps = p ? getnum(p+1, &p, "w_steps") : (w_h == w ?1:2);
+ len = getnum(strsep(&cur, ":"), &p, "len");
+ if (len <= 0)
+ len = 1000;
+ len_h = p ? getnum(p+1, &p, "len_max") : len;
+ l_steps = p ? getnum(p+1, &p, "l_steps") : (len_h == len ? 1 : 2);
+ flows = getnum(strsep(&cur, ":"), NULL, "flows");
+ if (flows == 0)
+ flows = 1;
+ DX(4, "weight %d..%d (%d) len %d..%d (%d) flows %d",
+ w, w_h, w_steps, len, len_h, l_steps, flows);
+ if (w == 0 || w_h < w || len == 0 || len_h < len ||
+ flows == 0) {
+ DX(4,"wrong parameters %s", fs);
+ return;
+ }
+ n_flows += flows * w_steps * l_steps;
+ for (i = 0; i < w_steps; i++) {
+ wi = w + ((w_h - w)* i)/(w_steps == 1 ? 1 : (w_steps-1));
+ for (j = 0; j < l_steps; j++, n_fs++) {
+ struct dn_fs *fs = &c->fs[n_fs].fs; // tentative
+ int x;
+
+ li = len + ((len_h - len)* j)/(l_steps == 1 ? 1 : (l_steps-1));
+ x = (wi*2048)/li;
+ DX(3, "----- fs %4d weight %4d lmax %4d X %4d flows %d",
+ n_fs, wi, li, x, flows);
+ if (pass == 0)
+ continue;
+ if (c->fs == NULL || c->flowsets <= n_fs) {
+ D("error in number of flowsets");
+ return;
+ }
+ wsum += wi * flows;
+ fs->par[0] = wi;
+ fs->par[1] = li;
+ fs->index = n_fs;
+ fs->n_flows = flows;
+ fs->cur = fs->first_flow = prev==NULL ? 0 : prev->next_flow;
+ fs->next_flow = fs->first_flow + fs->n_flows;
+ fs->y = x * flows;
+ fs->base_y = (prev == NULL) ? 0 : prev->next_y;
+ fs->next_y = fs->base_y + fs->y;
+ prev = fs;
+ }
+ }
+ }
+ c->max_y = prev ? prev->base_y + prev->y : 0;
+ c->flows = n_flows;
+ c->flowsets = n_fs;
+ c->wsum = wsum;
+ if (pass == 0)
+ return;
+
+ /* now link all flows to their parent flowsets */
+ DX(1,"%d flows on %d flowsets max_y %d", c->flows, c->flowsets, c->max_y);
+ for (i=0; i < c->flowsets; i++) {
+ struct dn_fs *fs = &c->fs[i].fs;
+ DX(1, "fs %3d w %5d l %4d flow %5d .. %5d y %6d .. %6d",
+ i, fs->par[0], fs->par[1],
+ fs->first_flow, fs->next_flow,
+ fs->base_y, fs->next_y);
+ for (j = fs->first_flow; j < fs->next_flow; j++) {
+ struct dn_queue *q = FI2Q(c, j);
+ q->fs = &c->fs[i];
+ }
+ }
+}
+
+static int
+init(struct cfg_s *c)
+{
+ int i;
+ int ac = c->ac;
+ char * const *av = c->av;
+
+ c->si_len = sizeof(struct dn_sch_inst);
+ c->q_len = sizeof(struct dn_queue);
+ moduledata_t *mod = NULL;
+ struct dn_alg *p = NULL;
+
+ c->th_min = 0;
+ c->th_max = -20;/* 20 packets per flow */
+ c->lmin = c->lmax = 1280; /* packet len */
+ c->flows = 1;
+ c->flowsets = 1;
+ c->name = "null";
+ ac--; av++;
+ while (ac > 1) {
+ if (!strcmp(*av, "-n")) {
+ c->loops = getnum(av[1], NULL, av[0]);
+ } else if (!strcmp(*av, "-d")) {
+ debug = atoi(av[1]);
+ } else if (!strcmp(*av, "-alg")) {
+ extern moduledata_t *_g_dn_fifo;
+ extern moduledata_t *_g_dn_wf2qp;
+ extern moduledata_t *_g_dn_rr;
+ extern moduledata_t *_g_dn_qfq;
+#ifdef WITH_KPS
+ extern moduledata_t *_g_dn_kps;
+#endif
+ if (!strcmp(av[1], "rr"))
+ mod = _g_dn_rr;
+ else if (!strcmp(av[1], "wf2qp"))
+ mod = _g_dn_wf2qp;
+ else if (!strcmp(av[1], "fifo"))
+ mod = _g_dn_fifo;
+ else if (!strcmp(av[1], "qfq"))
+ mod = _g_dn_qfq;
+#ifdef WITH_KPS
+ else if (!strcmp(av[1], "kps"))
+ mod = _g_dn_kps;
+#endif
+ else
+ mod = NULL;
+ c->name = mod ? mod->name : "NULL";
+ DX(3, "using scheduler %s", c->name);
+ } else if (!strcmp(*av, "-len")) {
+ c->lmin = getnum(av[1], NULL, av[0]);
+ c->lmax = c->lmin;
+ DX(3, "setting max to %d", c->th_max);
+ } else if (!strcmp(*av, "-burst")) {
+ c->maxburst = getnum(av[1], NULL, av[0]);
+ DX(3, "setting max to %d", c->th_max);
+ } else if (!strcmp(*av, "-qmax")) {
+ c->th_max = getnum(av[1], NULL, av[0]);
+ DX(3, "setting max to %d", c->th_max);
+ } else if (!strcmp(*av, "-qmin")) {
+ c->th_min = getnum(av[1], NULL, av[0]);
+ DX(3, "setting min to %d", c->th_min);
+ } else if (!strcmp(*av, "-flows")) {
+ c->flows = getnum(av[1], NULL, av[0]);
+ DX(3, "setting flows to %d", c->flows);
+ } else if (!strcmp(*av, "-flowsets")) {
+ parse_flowsets(c, av[1], 0);
+ DX(3, "setting flowsets to %d", c->flowsets);
+ } else {
+ D("option %s not recognised, ignore", *av);
+ }
+ ac -= 2; av += 2;
+ }
+ if (c->maxburst <= 0)
+ c->maxburst = 1;
+ if (c->loops <= 0)
+ c->loops = 1;
+ if (c->flows <= 0)
+ c->flows = 1;
+ if (c->flowsets <= 0)
+ c->flowsets = 1;
+ if (c->lmin <= 0)
+ c->lmin = 1;
+ if (c->lmax <= 0)
+ c->lmax = 1;
+ /* multiply by N */
+ if (c->th_min < 0)
+ c->th_min = c->flows * -c->th_min;
+ if (c->th_max < 0)
+ c->th_max = c->flows * -c->th_max;
+ if (c->th_max <= c->th_min)
+ c->th_max = c->th_min + 1;
+ if (mod) {
+ p = mod->p;
+ DX(3, "using module %s f %p p %p", mod->name, mod->f, mod->p);
+ DX(3, "modname %s ty %d", p->name, p->type);
+ c->enq = p->enqueue;
+ c->deq = p->dequeue;
+ c->si_len += p->si_datalen;
+ c->q_len += p->q_datalen;
+ c->schk_len += p->schk_datalen;
+ }
+ /* allocate queues, flowsets and one scheduler */
+ c->q = calloc(c->flows, c->q_len);
+ c->fs = calloc(c->flowsets, sizeof(struct dn_fsk));
+ c->si = calloc(1, c->si_len);
+ c->sched = calloc(c->flows, c->schk_len);
+ if (c->q == NULL || c->fs == NULL) {
+ D("error allocating memory for flows");
+ exit(1);
+ }
+ c->si->sched = c->sched;
+ if (p) {
+ if (p->config)
+ p->config(c->sched);
+ if (p->new_sched)
+ p->new_sched(c->si);
+ }
+ /* parse_flowsets links queues to their flowsets */
+ parse_flowsets(c, av[1], 1);
+ /* complete the work calling new_fsk */
+ for (i = 0; i < c->flowsets; i++) {
+ if (c->fs[i].fs.par[1] == 0)
+ c->fs[i].fs.par[1] = 1000; /* default pkt len */
+ c->fs[i].sched = c->sched;
+ if (p && p->new_fsk)
+ p->new_fsk(&c->fs[i]);
+ }
+
+ /* initialize the lists for the generator, and put
+ * all flows in the list for backlog = 0
+ */
+ for (i=0; i <= BACKLOG+5; i++)
+ INIT_LIST_HEAD(&c->ll[i]);
+
+ for (i = 0; i < c->flows; i++) {
+ struct dn_queue *q = FI2Q(c, i);
+ if (q->fs == NULL)
+ q->fs = &c->fs[0]; /* XXX */
+ q->_si = c->si;
+ if (p && p->new_queue)
+ p->new_queue(q);
+ INIT_LIST_HEAD(&q->ni.h);
+ list_add_tail(&q->ni.h, &c->ll[0]);
+ }
+ c->llmask = 1;
+ return 0;
+}
+
+
+int
+main(int ac, char *av[])
+{
+ struct cfg_s c;
+ struct timeval end;
+ double ll;
+ int i;
+ char msg[40];
+
+ bzero(&c, sizeof(c));
+ c.ac = ac;
+ c.av = av;
+ init(&c);
+ gettimeofday(&c.time, NULL);
+ mainloop(&c);
+ gettimeofday(&end, NULL);
+ end.tv_sec -= c.time.tv_sec;
+ end.tv_usec -= c.time.tv_usec;
+ if (end.tv_usec < 0) {
+ end.tv_usec += 1000000;
+ end.tv_sec--;
+ }
+ c.time = end;
+ ll = end.tv_sec*1000000 + end.tv_usec;
+ ll *= 1000; /* convert to nanoseconds */
+ ll /= c._enqueue;
+ sprintf(msg, "1::%d", c.flows);
+ D("%-8s n %d %d time %d.%06d %8.3f qlen %d %d flows %s drops %d",
+ c.name, c._enqueue, c.loops,
+ (int)c.time.tv_sec, (int)c.time.tv_usec, ll,
+ c.th_min, c.th_max,
+ c.fs_config ? c.fs_config : msg, c.drop);
+ dump(&c);
+ DX(1, "done ac %d av %p", ac, av);
+ for (i=0; i < ac; i++)
+ DX(1, "arg %d %s", i, av[i]);
+ return 0;
+}
+
+/*
+ * The controller decides whether in this iteration we should send
+ * (the packet is in c->tosend) and/or receive (flag c->can_dequeue)
+ */
+static void
+controller(struct cfg_s *c)
+{
+ struct mbuf *m;
+ struct dn_fs *fs;
+ int flow_id;
+
+ /* histeresis between max and min */
+ if (c->state == 0 && c->pending >= c->th_max)
+ c->state = 1;
+ else if (c->state == 1 && c->pending <= c->th_min)
+ c->state = 0;
+ ND(1, "state %d pending %2d", c->state, c->pending);
+ c->can_dequeue = c->state;
+ c->tosend = NULL;
+ if (c->state)
+ return;
+
+ if (1) {
+ int i;
+ struct dn_queue *q;
+ struct list_head *h;
+
+ i = ffs(c->llmask) - 1;
+ if (i < 0) {
+ DX(2, "no candidate");
+ c->can_dequeue = 1;
+ return;
+ }
+ h = &c->ll[i];
+ ND(1, "backlog %d p %p prev %p next %p", i, h, h->prev, h->next);
+ q = list_first_entry(h, struct dn_queue, ni.h);
+ list_del(&q->ni.h);
+ flow_id = Q2FI(c, q);
+ DX(2, "extracted flow %p %d backlog %d", q, flow_id, i);
+ if (list_empty(h)) {
+ ND(2, "backlog %d empty", i);
+ c->llmask &= ~(1<<i);
+ }
+ ND(1, "before %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
+ list_add_tail(&q->ni.h, h+1);
+ ND(1, " after %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
+ if (i < BACKLOG) {
+ ND(2, "backlog %d full", i+1);
+ c->llmask |= 1<<(1+i);
+ }
+ fs = &q->fs->fs;
+ c->cur_fs = q->fs - c->fs;
+ fs->cur = flow_id;
+ } else {
+ /* XXX this does not work ? */
+ /* now decide whom to send the packet, and the length */
+ /* lookup in the flow table */
+ if (c->cur_y >= c->max_y) { /* handle wraparound */
+ c->cur_y = 0;
+ c->cur_fs = 0;
+ }
+ fs = &c->fs[c->cur_fs].fs;
+ flow_id = fs->cur++;
+ if (fs->cur >= fs->next_flow)
+ fs->cur = fs->first_flow;
+ c->cur_y++;
+ if (c->cur_y >= fs->next_y)
+ c->cur_fs++;
+ }
+
+ /* construct a packet */
+ if (c->freelist) {
+ m = c->tosend = c->freelist;
+ c->freelist = c->freelist->m_nextpkt;
+ } else {
+ m = c->tosend = calloc(1, sizeof(struct mbuf));
+ }
+ if (m == NULL)
+ return;
+
+ m->cfg = c;
+ m->m_nextpkt = NULL;
+ m->m_pkthdr.len = fs->par[1]; // XXX maxlen
+ m->flow_id = flow_id;
+
+ ND(2,"y %6d flow %5d fs %3d weight %4d len %4d",
+ c->cur_y, m->flow_id, c->cur_fs,
+ fs->par[0], m->m_pkthdr.len);
+
+}
+
+/*
+Packet allocation:
+to achieve a distribution that matches weights, for each X=w/lmax class
+we should generate a number of packets proportional to Y = X times the number
+of flows in the class.
+So we construct an array with the cumulative distribution of Y's,
+and use it to identify the flow via inverse mapping (if the Y's are
+not too many we can use an array for the lookup). In practice,
+each flow will have X entries [virtually] pointing to it.
+
+*/
diff --git a/sys/netinet/ipfw/test/mylist.h b/sys/netinet/ipfw/test/mylist.h
new file mode 100644
index 0000000..6247f32
--- /dev/null
+++ b/sys/netinet/ipfw/test/mylist.h
@@ -0,0 +1,49 @@
+/*
+ * $FreeBSD$
+ *
+ * linux-like bidirectional lists
+ */
+
+#ifndef _MYLIST_H
+#define _MYLIST_H
+struct list_head {
+ struct list_head *prev, *next;
+};
+
+#define INIT_LIST_HEAD(l) do { (l)->prev = (l)->next = (l); } while (0)
+#define list_empty(l) ( (l)->next == l )
+static inline void
+__list_add(struct list_head *o, struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = o;
+ o->next = next;
+ o->prev = prev;
+ prev->next = o;
+}
+
+static inline void
+list_add_tail(struct list_head *o, struct list_head *head)
+{
+ __list_add(o, head->prev, head);
+}
+
+#define list_first_entry(pL, ty, member) \
+ (ty *)((char *)((pL)->next) - offsetof(ty, member))
+
+static inline void
+__list_del(struct list_head *prev, struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void
+list_del(struct list_head *entry)
+{
+ ND("called on %p", entry);
+ __list_del(entry->prev, entry->next);
+ entry->next = entry->prev = NULL;
+}
+
+#endif /* _MYLIST_H */
diff --git a/sys/netinet/ipfw/test/test_dn_heap.c b/sys/netinet/ipfw/test/test_dn_heap.c
new file mode 100644
index 0000000..d460cf2
--- /dev/null
+++ b/sys/netinet/ipfw/test/test_dn_heap.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
+ * 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.
+ */
+
+/*
+ * Userland code for testing binary heaps and hash tables
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include "dn_heap.h"
+#define log(x, arg...) fprintf(stderr, ## arg)
+#define panic(x...) fprintf(stderr, ## x), exit(1)
+
+#include <string.h>
+
+struct x {
+ struct x *ht_link;
+ char buf[0];
+};
+
+uint32_t hf(uintptr_t key, int flags, void *arg)
+{
+ return (flags & DNHT_KEY_IS_OBJ) ?
+ ((struct x *)key)->buf[0] : *(char *)key;
+}
+
+int matchf(void *obj, uintptr_t key, int flags, void *arg)
+{
+ char *s = (flags & DNHT_KEY_IS_OBJ) ?
+ ((struct x *)key)->buf : (char *)key;
+ return (strcmp(((struct x *)obj)->buf, s) == 0);
+}
+
+void *newfn(uintptr_t key, int flags, void *arg)
+{
+ char *s = (char *)key;
+ struct x *p = malloc(sizeof(*p) + 1 + strlen(s));
+ if (p)
+ strcpy(p->buf, s);
+ return p;
+}
+
+char *strings[] = {
+ "undici", "unico", "doppio", "devoto",
+ "uno", "due", "tre", "quattro", "cinque", "sei",
+ "uno", "due", "tre", "quattro", "cinque", "sei",
+ NULL,
+};
+
+int doprint(void *_x, void *arg)
+{
+ struct x *x = _x;
+ printf("found element <%s>\n", x->buf);
+ return (int)arg;
+}
+
+static void
+test_hash()
+{
+ char **p;
+ struct dn_ht *h;
+ uintptr_t x = 0;
+ uintptr_t x1 = 0;
+
+ /* first, find and allocate */
+ h = dn_ht_init(NULL, 10, 0, hf, matchf, newfn);
+
+ for (p = strings; *p; p++) {
+ dn_ht_find(h, (uintptr_t)*p, DNHT_INSERT, NULL);
+ }
+ dn_ht_scan(h, doprint, 0);
+ printf("/* second -- find without allocate */\n");
+ h = dn_ht_init(NULL, 10, 0, hf, matchf, NULL);
+ for (p = strings; *p; p++) {
+ void **y = newfn((uintptr_t)*p, 0, NULL);
+ if (x == 0)
+ x = (uintptr_t)y;
+ else {
+ if (x1 == 0)
+ x1 = (uintptr_t)*p;
+ }
+ dn_ht_find(h, (uintptr_t)y, DNHT_INSERT | DNHT_KEY_IS_OBJ, NULL);
+ }
+ dn_ht_scan(h, doprint, 0);
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x1, DNHT_REMOVE, NULL));
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x1, DNHT_REMOVE, NULL));
+ dn_ht_scan(h, doprint, 0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct dn_heap h;
+ int i, n, n2, n3;
+
+ test_hash();
+ return 0;
+
+ /* n = elements, n2 = cycles */
+ n = (argc > 1) ? atoi(argv[1]) : 0;
+ if (n <= 0 || n > 1000000)
+ n = 100;
+ n2 = (argc > 2) ? atoi(argv[2]) : 0;
+ if (n2 <= 0)
+ n = 1000000;
+ n3 = (argc > 3) ? atoi(argv[3]) : 0;
+ bzero(&h, sizeof(h));
+ heap_init(&h, n, -1);
+ while (n2-- > 0) {
+ uint64_t prevk = 0;
+ for (i=0; i < n; i++)
+ heap_insert(&h, n3 ? n-i: random(), (void *)(100+i));
+
+ for (i=0; h.elements > 0; i++) {
+ uint64_t k = h.p[0].key;
+ if (k < prevk)
+ panic("wrong sequence\n");
+ prevk = k;
+ if (0)
+ printf("%d key %llu, val %p\n",
+ i, h.p[0].key, h.p[0].object);
+ heap_extract(&h, NULL);
+ }
+ }
+ return 0;
+}
diff --git a/sys/netinet/ipfw/test/test_dn_sched.c b/sys/netinet/ipfw/test/test_dn_sched.c
new file mode 100644
index 0000000..ee46c95
--- /dev/null
+++ b/sys/netinet/ipfw/test/test_dn_sched.c
@@ -0,0 +1,89 @@
+/*
+ * $FreeBSD$
+ *
+ * library functions for userland testing of dummynet schedulers
+ */
+
+#include "dn_test.h"
+
+void
+m_freem(struct mbuf *m)
+{
+ printf("free %p\n", m);
+}
+
+int
+dn_sched_modevent(module_t mod, int cmd, void *arg)
+{
+ return 0;
+}
+
+void
+dn_free_pkts(struct mbuf *m)
+{
+ struct mbuf *x;
+ while ( (x = m) ) {
+ m = m->m_nextpkt;
+ m_freem(x);
+ }
+}
+
+int
+dn_delete_queue(void *_q, void *do_free)
+{
+ struct dn_queue *q = _q;
+ if (q->mq.head)
+ dn_free_pkts(q->mq.head);
+ free(q);
+ return 0;
+}
+
+/*
+ * This is a simplified function for testing purposes, which does
+ * not implement statistics or random loss.
+ * Enqueue a packet in q, subject to space and queue management policy
+ * (whose parameters are in q->fs).
+ * Update stats for the queue and the scheduler.
+ * Return 0 on success, 1 on drop. The packet is consumed anyways.
+ */
+int
+dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
+{
+ if (drop)
+ goto drop;
+ if (q->ni.length >= 200)
+ goto drop;
+ mq_append(&q->mq, m);
+ q->ni.length++;
+ q->ni.tot_bytes += m->m_pkthdr.len;
+ return 0;
+
+drop:
+ q->ni.drops++;
+ return 1;
+}
+
+int
+ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
+{
+ if (*v < lo) {
+ *v = dflt;
+ } else if (*v > hi) {
+ *v = hi;
+ }
+ return *v;
+}
+
+#ifndef __FreeBSD__
+int
+fls(int mask)
+{
+ int bit;
+
+ if (mask == 0)
+ return (0);
+ for (bit = 1; mask != 1; bit++)
+ mask = (unsigned int)mask >> 1;
+ return (bit);
+}
+#endif
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 9341cf2..1db3774 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -185,19 +185,8 @@ void
rip_init(void)
{
- INP_INFO_LOCK_INIT(&V_ripcbinfo, "rip");
- LIST_INIT(&V_ripcb);
-#ifdef VIMAGE
- V_ripcbinfo.ipi_vnet = curvnet;
-#endif
- V_ripcbinfo.ipi_listhead = &V_ripcb;
- V_ripcbinfo.ipi_hashbase =
- hashinit(INP_PCBHASH_RAW_SIZE, M_PCB, &V_ripcbinfo.ipi_hashmask);
- V_ripcbinfo.ipi_porthashbase =
- hashinit(1, M_PCB, &V_ripcbinfo.ipi_porthashmask);
- V_ripcbinfo.ipi_zone = uma_zcreate("ripcb", sizeof(struct inpcb),
- NULL, NULL, rip_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
- uma_zone_set_max(V_ripcbinfo.ipi_zone, maxsockets);
+ in_pcbinfo_init(&V_ripcbinfo, "rip", &V_ripcb, INP_PCBHASH_RAW_SIZE,
+ 1, "ripcb", rip_inpcb_init, NULL, UMA_ZONE_NOFREE);
EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
EVENTHANDLER_PRI_ANY);
}
@@ -207,10 +196,7 @@ void
rip_destroy(void)
{
- hashdestroy(V_ripcbinfo.ipi_hashbase, M_PCB,
- V_ripcbinfo.ipi_hashmask);
- hashdestroy(V_ripcbinfo.ipi_porthashbase, M_PCB,
- V_ripcbinfo.ipi_porthashmask);
+ in_pcbinfo_destroy(&V_ripcbinfo);
}
#endif
@@ -1025,13 +1011,13 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RLOCK(&V_ripcbinfo);
for (inp = LIST_FIRST(V_ripcbinfo.ipi_listhead), i = 0; inp && i < n;
inp = LIST_NEXT(inp, inp_list)) {
- INP_RLOCK(inp);
+ INP_WLOCK(inp);
if (inp->inp_gencnt <= gencnt &&
cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
- /* XXX held references? */
+ in_pcbref(inp);
inp_list[i++] = inp;
}
- INP_RUNLOCK(inp);
+ INP_WUNLOCK(inp);
}
INP_INFO_RUNLOCK(&V_ripcbinfo);
n = i;
@@ -1054,6 +1040,15 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
} else
INP_RUNLOCK(inp);
}
+ INP_INFO_WLOCK(&V_ripcbinfo);
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_WLOCK(inp);
+ if (!in_pcbrele(inp))
+ INP_WUNLOCK(inp);
+ }
+ INP_INFO_WUNLOCK(&V_ripcbinfo);
+
if (!error) {
/*
* Give the user an updated idea of our state. If the
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 9513ded..2d16ef0 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -556,9 +556,9 @@ sctp_process_asconf_set_primary(struct mbuf *m,
* PRIMARY with DELETE IP ADDRESS of the previous primary
* destination, unacknowledged DATA are retransmitted
* immediately to the new primary destination for seamless
- * handover. If the destination is UNCONFIRMED and marked
- * to REQ_PRIM, The retransmission occur when reception of
- * the HEARTBEAT-ACK. (See sctp_handle_heartbeat_ack in
+ * handover. If the destination is UNCONFIRMED and marked to
+ * REQ_PRIM, The retransmission occur when reception of the
+ * HEARTBEAT-ACK. (See sctp_handle_heartbeat_ack in
* sctp_input.c) Also, when change of the primary
* destination, it is better that all subsequent new DATA
* containing already queued DATA are transmitted to the new
@@ -1113,7 +1113,7 @@ sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
}
SCTP_TCB_LOCK_ASSERT(stcb);
#ifdef SCTP_AUDITING_ENABLED
- sctp_auditing(4, stcb->sctp_ep, stcb->asoc.deleted_primary);
+ sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
#endif
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
if ((stcb->asoc.num_send_timers_up == 0) &&
@@ -1166,7 +1166,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
/*
* If number of local valid addresses is 1, the valid address is
- * probably newly added address. Several valid addresses in this
+ * probably newly added address. Several valid addresses in this
* association. A source address may not be changed. Additionally,
* they can be configured on a same interface as "alias" addresses.
* (by micchie)
@@ -1210,7 +1210,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
/*
* Check if the nexthop is corresponding to the new address.
* If the new address is corresponding to the current
- * nexthop, the path will be changed. If the new address is
+ * nexthop, the path will be changed. If the new address is
* NOT corresponding to the current nexthop, the path will
* not be changed.
*/
diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
index 4a013d3..3d88631 100644
--- a/sys/netinet/sctp_constants.h
+++ b/sys/netinet/sctp_constants.h
@@ -544,13 +544,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_INITIAL_MAPPING_ARRAY 16
/* how much we grow the mapping array each call */
#define SCTP_MAPPING_ARRAY_INCR 32
-/* EY 05/13/08 - nr_sack version of the previous 3 constants */
-/* Maximum the nr mapping array will grow to (TSN mapping array) */
-#define SCTP_NR_MAPPING_ARRAY 512
-/* size of the inital malloc on the nr mapping array */
-#define SCTP_INITIAL_NR_MAPPING_ARRAY 16
-/* how much we grow the nr mapping array each call */
-#define SCTP_NR_MAPPING_ARRAY_INCR 32
+
/*
* Here we define the timer types used by the implementation as arguments in
* the set/get timer type calls.
@@ -933,6 +927,13 @@ __FBSDID("$FreeBSD$");
#define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01)
#define SCTP_SET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] |= (0x01 << ((gap & 0x07))))
#define SCTP_UNSET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] &= ((~(0x01 << ((gap & 0x07)))) & 0xff))
+#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
+ if (tsn >= mapping_tsn) { \
+ gap = tsn - mapping_tsn; \
+ } else { \
+ gap = (MAX_TSN - mapping_tsn) + tsn + 1; \
+ } \
+ } while(0)
#define SCTP_RETRAN_DONE -1
diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c
index aeb9715..d9ae238 100644
--- a/sys/netinet/sctp_crc32.c
+++ b/sys/netinet/sctp_crc32.c
@@ -127,14 +127,12 @@ sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
void
-sctp_delayed_cksum(struct mbuf *m)
+sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
{
struct ip *ip;
uint32_t checksum;
- uint32_t offset;
ip = mtod(m, struct ip *);
- offset = ip->ip_hl << 2;
checksum = sctp_calculate_cksum(m, offset);
SCTP_STAT_DECR(sctps_sendhwcrc);
SCTP_STAT_INCR(sctps_sendswcrc);
diff --git a/sys/netinet/sctp_crc32.h b/sys/netinet/sctp_crc32.h
index 44196b1..e66815e 100644
--- a/sys/netinet/sctp_crc32.h
+++ b/sys/netinet/sctp_crc32.h
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#if defined(_KERNEL) || defined(__Userspace__)
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
-void sctp_delayed_cksum(struct mbuf *);
+void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
#endif /* _KERNEL */
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index cdb78af..2ed6c16 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -45,24 +45,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_uio.h>
#include <netinet/sctp_timer.h>
-#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
- if ((compare_with_wrap(tsn, mapping_tsn, MAX_TSN)) || \
- (tsn == mapping_tsn)) { \
- gap = tsn - mapping_tsn; \
- } else { \
- gap = (MAX_TSN - mapping_tsn) + tsn + 1; \
- } \
- } while(0)
-
-#define SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc) do { \
- if (asoc->mapping_array_base_tsn == asoc->nr_mapping_array_base_tsn) { \
- SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, nr_gap); \
- } else {\
- int lgap; \
- SCTP_CALC_TSN_TO_GAP(lgap, tsn, asoc->mapping_array_base_tsn); \
- SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, lgap); \
- } \
- } while(0)
/*
* NOTES: On the outbound side of things I need to check the sack timer to
@@ -304,6 +286,45 @@ sctp_build_ctl_cchunk(struct sctp_inpcb *inp,
return (buf);
}
+static void
+sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
+{
+ uint32_t gap, i;
+ int fnd = 0;
+
+ if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
+ return;
+ }
+ SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
+ if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
+ printf("gap:%x tsn:%x\n", gap, tsn);
+ sctp_print_mapping_array(asoc);
+#ifdef INVARIANTS
+ panic("Things are really messed up now!!");
+#endif
+ }
+ SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
+ SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_nr_map = tsn;
+ }
+ if (tsn == asoc->highest_tsn_inside_map) {
+ /* We must back down to see what the new highest is */
+ for (i = tsn - 1; (compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN) ||
+ (i == asoc->mapping_array_base_tsn)); i--) {
+ SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
+ if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
+ asoc->highest_tsn_inside_map = i;
+ fnd = 1;
+ break;
+ }
+ }
+ if (!fnd) {
+ asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
+ }
+ }
+}
+
/*
* We are delivering currently from the reassembly queue. We must continue to
@@ -319,9 +340,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
int end = 0;
int cntDel;
- /* EY if any out-of-order delivered, then tag it nr on nr_map */
- uint32_t nr_tsn, nr_gap;
-
struct sctp_queued_to_read *control, *ctl, *ctlat;
if (stcb == NULL)
@@ -387,6 +405,7 @@ abandon:
end = 1;
else
end = 0;
+ sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
sctp_add_to_readq(stcb->sctp_ep,
stcb, control, &stcb->sctp_socket->so_rcv, end,
SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
@@ -396,6 +415,7 @@ abandon:
end = 1;
else
end = 0;
+ sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
if (sctp_append_to_readq(stcb->sctp_ep, stcb,
stcb->asoc.control_pdapi,
chk->data, end, chk->rec.data.TSN_seq,
@@ -430,39 +450,6 @@ abandon:
}
/* pull it we did it */
TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
- /*
- * EY this is the chunk that should be tagged nr gapped
- * calculate the gap and such then tag this TSN nr
- * chk->rec.data.TSN_seq
- */
- /*
- * EY!-TODO- this tsn should be tagged nr only if it is
- * out-of-order, the if statement should be modified
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- nr_tsn = chk->rec.data.TSN_seq;
- SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
- if ((nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
- /*
- * EY The 1st should never happen, as in
- * process_a_data_chunk method this check
- * should be done
- */
- /*
- * EY The 2nd should never happen, because
- * nr_mapping_array is always expanded when
- * mapping_array is expanded
- */
- printf("Impossible nr_gap ack range failed\n");
- } else {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
- if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
- asoc->highest_tsn_inside_nr_map = nr_tsn;
- }
- }
if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
asoc->fragmented_delivery_inprogress = 0;
if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0) {
@@ -509,67 +496,11 @@ abandon:
asoc->size_on_all_streams -= ctl->length;
sctp_ucount_decr(asoc->cnt_on_all_streams);
strm->last_sequence_delivered++;
- /*
- * EY will be used to
- * calculate nr-gap
- */
- nr_tsn = ctl->sinfo_tsn;
+ sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
ctl,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
- /*
- * EY -now something is
- * delivered, calculate
- * nr_gap and tag this tsn
- * NR
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
- if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
- (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
- /*
- * EY The
- * 1st
- * should
- * never
- * happen,
- * as in
- * process_a_
- * data_chunk
- * method
- * this
- * check
- * should be
- * done
- */
- /*
- * EY The
- * 2nd
- * should
- * never
- * happen,
- * because
- * nr_mapping
- * _array is
- * always
- * expanded
- * when
- * mapping_ar
- * ray is
- * expanded
- */
- } else {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
- if (compare_with_wrap(nr_tsn,
- asoc->highest_tsn_inside_nr_map,
- MAX_TSN))
- asoc->highest_tsn_inside_nr_map = nr_tsn;
- }
- }
ctl = ctlat;
} else {
break;
@@ -618,9 +549,6 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
uint16_t nxt_todel;
struct mbuf *oper;
- /* EY- will be used to calculate nr-gap for a tsn */
- uint32_t nr_tsn, nr_gap;
-
queue_needed = 1;
asoc->size_on_all_streams += control->length;
sctp_ucount_incr(asoc->cnt_on_all_streams);
@@ -682,41 +610,12 @@ protocol_error:
asoc->size_on_all_streams -= control->length;
sctp_ucount_decr(asoc->cnt_on_all_streams);
strm->last_sequence_delivered++;
- /* EY will be used to calculate nr-gap */
- nr_tsn = control->sinfo_tsn;
+
+ sctp_mark_non_revokable(asoc, control->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
- /*
- * EY this is the chunk that should be tagged nr gapped
- * calculate the gap and such then tag this TSN nr
- * chk->rec.data.TSN_seq
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
- if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
- (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
- printf("Impossible nr_tsn set 2?\n");
- /*
- * EY The 1st should never happen, as in
- * process_a_data_chunk method this check
- * should be done
- */
- /*
- * EY The 2nd should never happen, because
- * nr_mapping_array is always expanded when
- * mapping_array is expanded
- */
- } else {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
- if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
- asoc->highest_tsn_inside_nr_map = nr_tsn;
- }
- }
control = TAILQ_FIRST(&strm->inqueue);
while (control != NULL) {
/* all delivered */
@@ -737,48 +636,12 @@ protocol_error:
sctp_log_strm_del(control, NULL,
SCTP_STR_LOG_FROM_IMMED_DEL);
}
- /* EY will be used to calculate nr-gap */
- nr_tsn = control->sinfo_tsn;
+ sctp_mark_non_revokable(asoc, control->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD,
SCTP_SO_NOT_LOCKED);
- /*
- * EY this is the chunk that should be
- * tagged nr gapped calculate the gap and
- * such then tag this TSN nr
- * chk->rec.data.TSN_seq
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
- if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
- (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
- /*
- * EY The 1st should never
- * happen, as in
- * process_a_data_chunk
- * method this check should
- * be done
- */
- /*
- * EY The 2nd should never
- * happen, because
- * nr_mapping_array is
- * always expanded when
- * mapping_array is expanded
- */
- } else {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- if (compare_with_wrap(nr_tsn,
- asoc->highest_tsn_inside_nr_map,
- MAX_TSN))
- asoc->highest_tsn_inside_nr_map = nr_tsn;
- }
- }
control = at;
continue;
}
@@ -1096,8 +959,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
*abort_flag = 1;
} else if ((asoc->fragment_flags & SCTP_DATA_UNORDERED) !=
SCTP_DATA_UNORDERED &&
- chk->rec.data.stream_seq !=
- asoc->ssn_of_pdapi) {
+ chk->rec.data.stream_seq != asoc->ssn_of_pdapi) {
/* Got to be the right STR Seq */
SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream seq %d vs %d\n",
chk->rec.data.stream_seq,
@@ -1586,9 +1448,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* struct sctp_tmit_chunk *chk; */
struct sctp_tmit_chunk *chk;
uint32_t tsn, gap;
-
- /* EY - for nr_sack */
- uint32_t nr_gap;
struct mbuf *dmbuf;
int indx, the_len;
int need_reasm_check = 0;
@@ -1607,7 +1466,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->send_sack = 1;
}
protocol_id = ch->dp.protocol_id;
- ordered = ((ch->ch.chunk_flags & SCTP_DATA_UNORDERED) == 0);
+ ordered = ((chunk_flags & SCTP_DATA_UNORDERED) == 0);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
sctp_log_map(tsn, asoc->cumulative_tsn, asoc->highest_tsn_inside_map, SCTP_MAP_TSN_ENTERS);
}
@@ -1640,14 +1499,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
return (0);
}
}
- /* EY - for nr_sack */
- nr_gap = gap;
-
if (compare_with_wrap(tsn, *high_tsn, MAX_TSN)) {
*high_tsn = tsn;
}
/* See if we have received this one already */
- if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
+ if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap) ||
+ SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap)) {
SCTP_STAT_INCR(sctps_recvdupdata);
if (asoc->numduptsns < SCTP_MAX_DUP_TSNS) {
/* Record a dup for the next outbound sack */
@@ -1714,7 +1571,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
#endif
}
/* now is it in the mapping array of what we have accepted? */
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN) &&
+ compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
/* Nope not in the valid range dump it */
sctp_set_rwnd(stcb, asoc);
if ((asoc->cnt_on_all_streams +
@@ -1758,23 +1616,9 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
SCTP_STAT_INCR(sctps_badsid);
SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
- /* EY set this tsn present in nr_sack's nr_mapping_array */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
- SCTP_REVERSE_OUT_TSN_PRES(gap, tsn, asoc);
- }
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
- /* we have a new high score */
- asoc->highest_tsn_inside_map = tsn;
- /* EY nr_sack version of the above */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack)
- asoc->highest_tsn_inside_nr_map = tsn;
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(0, 2, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
- }
+ SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_nr_map = tsn;
}
if (tsn == (asoc->cumulative_tsn + 1)) {
/* Update cum-ack */
@@ -1925,48 +1769,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
control, &stcb->sctp_socket->so_rcv,
1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
- /*
- * EY here I should check if this delivered tsn is
- * out_of_order, if yes then update the nr_map
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
- /*
- * EY check if the mapping_array and nr_mapping
- * array are consistent
- */
- if (asoc->mapping_array_base_tsn != asoc->nr_mapping_array_base_tsn)
- /*
- * printf("EY-IN
- * sctp_process_a_data_chunk(5): Something
- * is wrong the map base tsn" "\nEY-and
- * nr_map base tsn should be equal.");
- */
- /* EY debugging block */
- {
- /*
- * printf("\nEY-Calculating an
- * nr_gap!!\nmapping_array_size = %d
- * nr_mapping_array_size = %d"
- * "\nEY-mapping_array_base = %d
- * nr_mapping_array_base =
- * %d\nEY-highest_tsn_inside_map = %d"
- * "highest_tsn_inside_nr_map = %d\nEY-TSN =
- * %d nr_gap = %d",asoc->mapping_array_size,
- * asoc->nr_mapping_array_size,
- * asoc->mapping_array_base_tsn,
- * asoc->nr_mapping_array_base_tsn,
- * asoc->highest_tsn_inside_map,
- * asoc->highest_tsn_inside_nr_map,tsn,nr_gap
- * );
- */
- }
- /* EY - not %100 sure about the lock thing */
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
- asoc->highest_tsn_inside_nr_map = tsn;
- }
if ((chunk_flags & SCTP_DATA_UNORDERED) == 0) {
/* for ordered, bump what we delivered */
asoc->strmin[strmno].last_sequence_delivered++;
@@ -1977,6 +1779,11 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
SCTP_STR_LOG_FROM_EXPRS_DEL);
}
control = NULL;
+
+ SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_nr_map = tsn;
+ }
goto finish_express_del;
}
failed_express_del:
@@ -2012,39 +1819,9 @@ failed_express_del:
SCTP_PRINTF("Append fails end:%d\n", end);
goto failed_pdapi_express_del;
}
- /*
- * EY It is appended to the read queue in prev if
- * block here I should check if this delivered tsn
- * is out_of_order, if yes then update the nr_map
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- /* EY debugging block */
- {
- /*
- * printf("\nEY-Calculating an
- * nr_gap!!\nEY-mapping_array_size =
- * %d nr_mapping_array_size = %d"
- * "\nEY-mapping_array_base = %d
- * nr_mapping_array_base =
- * %d\nEY-highest_tsn_inside_map =
- * %d" "highest_tsn_inside_nr_map =
- * %d\nEY-TSN = %d nr_gap =
- * %d",asoc->mapping_array_size,
- * asoc->nr_mapping_array_size,
- * asoc->mapping_array_base_tsn,
- * asoc->nr_mapping_array_base_tsn,
- * asoc->highest_tsn_inside_map,
- * asoc->highest_tsn_inside_nr_map,ts
- * n,nr_gap);
- */
- }
- /* EY - not %100 sure about the lock thing */
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
- asoc->highest_tsn_inside_nr_map = tsn;
+ SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_nr_map = tsn;
}
SCTP_STAT_INCR(sctps_recvexpressm);
control->sinfo_tsn = tsn;
@@ -2075,6 +1852,17 @@ failed_express_del:
}
failed_pdapi_express_del:
control = NULL;
+ if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
+ SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_nr_map = tsn;
+ }
+ } else {
+ SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
+ if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_map = tsn;
+ }
+ }
if ((chunk_flags & SCTP_DATA_NOT_FRAG) != SCTP_DATA_NOT_FRAG) {
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
@@ -2260,59 +2048,10 @@ failed_pdapi_express_del:
/* ok, if we reach here we have passed the sanity checks */
if (chunk_flags & SCTP_DATA_UNORDERED) {
/* queue directly into socket buffer */
+ sctp_mark_non_revokable(asoc, control->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
- /*
- * EY It is added to the read queue in prev if block
- * here I should check if this delivered tsn is
- * out_of_order, if yes then update the nr_map
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- /*
- * EY check if the mapping_array and
- * nr_mapping array are consistent
- */
- if (asoc->mapping_array_base_tsn != asoc->nr_mapping_array_base_tsn)
- /*
- * printf("EY-IN
- * sctp_process_a_data_chunk(6):
- * Something is wrong the map base
- * tsn" "\nEY-and nr_map base tsn
- * should be equal.");
- */
- /*
- * EY - not %100 sure about the lock
- * thing, i think we don't need the
- * below,
- */
- /* SCTP_TCB_LOCK_ASSERT(stcb); */
- {
- /*
- * printf("\nEY-Calculating an
- * nr_gap!!\nEY-mapping_array_size =
- * %d nr_mapping_array_size = %d"
- * "\nEY-mapping_array_base = %d
- * nr_mapping_array_base =
- * %d\nEY-highest_tsn_inside_map =
- * %d" "highest_tsn_inside_nr_map =
- * %d\nEY-TSN = %d nr_gap =
- * %d",asoc->mapping_array_size,
- * asoc->nr_mapping_array_size,
- * asoc->mapping_array_base_tsn,
- * asoc->nr_mapping_array_base_tsn,
- * asoc->highest_tsn_inside_map,
- * asoc->highest_tsn_inside_nr_map,ts
- * n,nr_gap);
- */
- }
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
- asoc->highest_tsn_inside_nr_map = tsn;
- }
} else {
/*
* Special check for when streams are resetting. We
@@ -2384,13 +2123,6 @@ failed_pdapi_express_del:
}
}
finish_express_del:
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
- /* we have a new high score */
- asoc->highest_tsn_inside_map = tsn;
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(0, 2, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
- }
- }
if (tsn == (asoc->cumulative_tsn + 1)) {
/* Update cum-ack */
asoc->cumulative_tsn = tsn;
@@ -2412,22 +2144,6 @@ finish_express_del:
sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
}
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
-
- /*
- * EY - set tsn present in nr-map if doing nr-sacks and the tsn is
- * non-renegable
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack &&
- (SCTP_BASE_SYSCTL(sctp_do_drain) == 0)) {
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
- if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
- asoc->highest_tsn_inside_nr_map = tsn;
- }
- }
/* check the special flag for stream resets */
if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
((compare_with_wrap(asoc->cumulative_tsn, liste->tsn, MAX_TSN)) ||
@@ -2488,43 +2204,43 @@ finish_express_del:
}
int8_t sctp_map_lookup_tab[256] = {
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 4,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 5,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 4,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 6,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 4,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 5,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 4,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 3,
- -1, 0, -1, 1, -1, 0, -1, 2,
- -1, 0, -1, 1, -1, 0, -1, 7,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 5,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 6,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 5,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 7,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 5,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 6,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 5,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 4,
+ 0, 1, 0, 2, 0, 1, 0, 3,
+ 0, 1, 0, 2, 0, 1, 0, 8
};
void
-sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort_flag)
+sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
{
/*
* Now we also need to check the mapping array in a couple of ways.
@@ -2532,23 +2248,13 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
*/
struct sctp_association *asoc;
int at;
- uint8_t comb_byte;
- int last_all_ones = 0;
int slide_from, slide_end, lgap, distance;
/* EY nr_mapping array variables */
/* int nr_at; */
/* int nr_last_all_ones = 0; */
/* int nr_slide_from, nr_slide_end, nr_lgap, nr_distance; */
-
- uint32_t old_cumack, old_base, old_highest;
- unsigned char aux_array[64];
-
- /*
- * EY! Don't think this is required but I am immitating the code for
- * map just to make sure
- */
- unsigned char nr_aux_array[64];
+ uint32_t old_cumack, old_base, old_highest, highest_tsn;
asoc = &stcb->asoc;
at = 0;
@@ -2556,68 +2262,31 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
old_cumack = asoc->cumulative_tsn;
old_base = asoc->mapping_array_base_tsn;
old_highest = asoc->highest_tsn_inside_map;
- if (asoc->mapping_array_size < 64)
- memcpy(aux_array, asoc->mapping_array,
- asoc->mapping_array_size);
- else
- memcpy(aux_array, asoc->mapping_array, 64);
- /* EY do the same for nr_mapping_array */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
- if (asoc->nr_mapping_array_size != asoc->mapping_array_size) {
- /*
- * printf("\nEY-IN sack_check method: \nEY-" "The
- * size of map and nr_map are inconsitent")
- */ ;
- }
- if (asoc->nr_mapping_array_base_tsn != asoc->mapping_array_base_tsn) {
- /*
- * printf("\nEY-IN sack_check method VERY CRUCIAL
- * error: \nEY-" "The base tsns of map and nr_map
- * are inconsitent")
- */ ;
- }
- /* EY! just immitating the above code */
- if (asoc->nr_mapping_array_size < 64)
- memcpy(nr_aux_array, asoc->nr_mapping_array,
- asoc->nr_mapping_array_size);
- else
- memcpy(aux_array, asoc->nr_mapping_array, 64);
- }
/*
* We could probably improve this a small bit by calculating the
* offset of the current cum-ack as the starting point.
*/
at = 0;
for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) {
- /*
- * We must combine the renegable and non-renegable arrays
- * here to form a unified view of what is acked right now
- * (since they are kept separate
- */
- comb_byte = asoc->mapping_array[slide_from] | asoc->nr_mapping_array[slide_from];
- if (comb_byte == 0xff) {
+ if (asoc->nr_mapping_array[slide_from] == 0xff) {
at += 8;
- last_all_ones = 1;
} else {
/* there is a 0 bit */
- at += sctp_map_lookup_tab[comb_byte];
- last_all_ones = 0;
+ at += sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]];
break;
}
}
- asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - last_all_ones);
- /* at is one off, since in the table a embedded -1 is present */
- at++;
+ asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - 1);
- if (compare_with_wrap(asoc->cumulative_tsn,
- asoc->highest_tsn_inside_map,
- MAX_TSN)) {
+ if (compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_map, MAX_TSN) &&
+ compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
#ifdef INVARIANTS
panic("huh, cumack 0x%x greater than high-tsn 0x%x in map",
asoc->cumulative_tsn, asoc->highest_tsn_inside_map);
#else
SCTP_PRINTF("huh, cumack 0x%x greater than high-tsn 0x%x in map - should panic?\n",
asoc->cumulative_tsn, asoc->highest_tsn_inside_map);
+ sctp_print_mapping_array(asoc);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
sctp_log_map(0, 6, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
}
@@ -2625,37 +2294,40 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn;
#endif
}
- if ((asoc->cumulative_tsn == asoc->highest_tsn_inside_map) && (at >= 8)) {
+ if (compare_with_wrap(asoc->highest_tsn_inside_nr_map,
+ asoc->highest_tsn_inside_map,
+ MAX_TSN)) {
+ highest_tsn = asoc->highest_tsn_inside_nr_map;
+ } else {
+ highest_tsn = asoc->highest_tsn_inside_map;
+ }
+ if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) {
/* The complete array was completed by a single FR */
- /* higest becomes the cum-ack */
+ /* highest becomes the cum-ack */
int clr;
- asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
+#ifdef INVARIANTS
+ unsigned int i;
+
+#endif
+
/* clear the array */
- clr = (at >> 3) + 1;
+ clr = ((at + 7) >> 3);
if (clr > asoc->mapping_array_size) {
clr = asoc->mapping_array_size;
}
memset(asoc->mapping_array, 0, clr);
- /* base becomes one ahead of the cum-ack */
- asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
-
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
-
- if (clr > asoc->nr_mapping_array_size)
- clr = asoc->nr_mapping_array_size;
-
- memset(asoc->nr_mapping_array, 0, clr);
- /* base becomes one ahead of the cum-ack */
- asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1;
- asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn;
- }
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(old_base, old_cumack, old_highest,
- SCTP_MAP_PREPARE_SLIDE);
- sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
- asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_CLEARED);
+ memset(asoc->nr_mapping_array, 0, clr);
+#ifdef INVARIANTS
+ for (i = 0; i < asoc->mapping_array_size; i++) {
+ if ((asoc->mapping_array[i]) || (asoc->nr_mapping_array[i])) {
+ printf("Error Mapping array's not clean at clear\n");
+ sctp_print_mapping_array(asoc);
+ }
}
+#endif
+ asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
+ asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
} else if (at >= 8) {
/* we can slide the mapping array down */
/* slide_from holds where we hit the first NON 0xff byte */
@@ -2664,19 +2336,15 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
* now calculate the ceiling of the move using our highest
* TSN value
*/
- if (asoc->highest_tsn_inside_map >= asoc->mapping_array_base_tsn) {
- lgap = asoc->highest_tsn_inside_map -
- asoc->mapping_array_base_tsn;
- } else {
- lgap = (MAX_TSN - asoc->mapping_array_base_tsn) +
- asoc->highest_tsn_inside_map + 1;
- }
- slide_end = lgap >> 3;
+ SCTP_CALC_TSN_TO_GAP(lgap, highest_tsn, asoc->mapping_array_base_tsn);
+ slide_end = (lgap >> 3);
if (slide_end < slide_from) {
+ sctp_print_mapping_array(asoc);
#ifdef INVARIANTS
panic("impossible slide");
#else
- printf("impossible slide?\n");
+ printf("impossible slide lgap:%x slide_end:%x slide_from:%x? at:%d\n",
+ lgap, slide_end, slide_from, at);
return;
#endif
}
@@ -2714,11 +2382,19 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
int ii;
for (ii = 0; ii < distance; ii++) {
- asoc->mapping_array[ii] =
- asoc->mapping_array[slide_from + ii];
+ asoc->mapping_array[ii] = asoc->mapping_array[slide_from + ii];
+ asoc->nr_mapping_array[ii] = asoc->nr_mapping_array[slide_from + ii];
+
}
- for (ii = distance; ii <= slide_end; ii++) {
+ for (ii = distance; ii < asoc->mapping_array_size; ii++) {
asoc->mapping_array[ii] = 0;
+ asoc->nr_mapping_array[ii] = 0;
+ }
+ if (asoc->highest_tsn_inside_map + 1 == asoc->mapping_array_base_tsn) {
+ asoc->highest_tsn_inside_map += (slide_from << 3);
+ }
+ if (asoc->highest_tsn_inside_nr_map + 1 == asoc->mapping_array_base_tsn) {
+ asoc->highest_tsn_inside_nr_map += (slide_from << 3);
}
asoc->mapping_array_base_tsn += (slide_from << 3);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
@@ -2726,112 +2402,97 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
asoc->cumulative_tsn, asoc->highest_tsn_inside_map,
SCTP_MAP_SLIDE_RESULT);
}
- /*
- * EY if doing nr_sacks then slide the
- * nr_mapping_array accordingly please
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
- for (ii = 0; ii < distance; ii++) {
- asoc->nr_mapping_array[ii] =
- asoc->nr_mapping_array[slide_from + ii];
- }
- for (ii = distance; ii <= slide_end; ii++) {
- asoc->nr_mapping_array[ii] = 0;
- }
- asoc->nr_mapping_array_base_tsn += (slide_from << 3);
- }
}
}
+}
+
+
+void
+sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag)
+{
+ struct sctp_association *asoc;
+ uint32_t highest_tsn;
+
+ asoc = &stcb->asoc;
+ if (compare_with_wrap(asoc->highest_tsn_inside_nr_map,
+ asoc->highest_tsn_inside_map,
+ MAX_TSN)) {
+ highest_tsn = asoc->highest_tsn_inside_nr_map;
+ } else {
+ highest_tsn = asoc->highest_tsn_inside_map;
+ }
+
/*
* Now we need to see if we need to queue a sack or just start the
* timer (if allowed).
*/
- if (ok_to_sack) {
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
- /*
- * Ok special case, in SHUTDOWN-SENT case. here we
- * maker sure SACK timer is off and instead send a
- * SHUTDOWN and a SACK
- */
- if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
- sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
- }
- sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
- /*
- * EY if nr_sacks used then send an nr-sack , a sack
- * otherwise
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
- sctp_send_nr_sack(stcb);
- else
- sctp_send_sack(stcb);
- } else {
- int is_a_gap;
+ if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
+ /*
+ * Ok special case, in SHUTDOWN-SENT case. here we maker
+ * sure SACK timer is off and instead send a SHUTDOWN and a
+ * SACK
+ */
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
+ sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
+ stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
+ }
+ sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
+ sctp_send_sack(stcb);
+ } else {
+ int is_a_gap;
- /* is there a gap now ? */
- is_a_gap = compare_with_wrap(stcb->asoc.highest_tsn_inside_map,
- stcb->asoc.cumulative_tsn, MAX_TSN);
+ /* is there a gap now ? */
+ is_a_gap = compare_with_wrap(highest_tsn, stcb->asoc.cumulative_tsn, MAX_TSN);
- /*
- * CMT DAC algorithm: increase number of packets
- * received since last ack
- */
- stcb->asoc.cmt_dac_pkts_rcvd++;
-
- if ((stcb->asoc.send_sack == 1) || /* We need to send a
- * SACK */
- ((was_a_gap) && (is_a_gap == 0)) || /* was a gap, but no
- * longer is one */
- (stcb->asoc.numduptsns) || /* we have dup's */
- (is_a_gap) || /* is still a gap */
- (stcb->asoc.delayed_ack == 0) || /* Delayed sack disabled */
- (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit limit of pkts */
- ) {
+ /*
+ * CMT DAC algorithm: increase number of packets received
+ * since last ack
+ */
+ stcb->asoc.cmt_dac_pkts_rcvd++;
+
+ if ((stcb->asoc.send_sack == 1) || /* We need to send a
+ * SACK */
+ ((was_a_gap) && (is_a_gap == 0)) || /* was a gap, but no
+ * longer is one */
+ (stcb->asoc.numduptsns) || /* we have dup's */
+ (is_a_gap) || /* is still a gap */
+ (stcb->asoc.delayed_ack == 0) || /* Delayed sack disabled */
+ (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit limit of pkts */
+ ) {
- if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
- (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
- (stcb->asoc.send_sack == 0) &&
- (stcb->asoc.numduptsns == 0) &&
- (stcb->asoc.delayed_ack) &&
- (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
+ if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
+ (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
+ (stcb->asoc.send_sack == 0) &&
+ (stcb->asoc.numduptsns == 0) &&
+ (stcb->asoc.delayed_ack) &&
+ (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
- /*
- * CMT DAC algorithm: With CMT,
- * delay acks even in the face of
- *
- * reordering. Therefore, if acks that
- * do not have to be sent because of
- * the above reasons, will be
- * delayed. That is, acks that would
- * have been sent due to gap reports
- * will be delayed with DAC. Start
- * the delayed ack timer.
- */
- sctp_timer_start(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL);
- } else {
- /*
- * Ok we must build a SACK since the
- * timer is pending, we got our
- * first packet OR there are gaps or
- * duplicates.
- */
- (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
- /*
- * EY if nr_sacks used then send an
- * nr-sack , a sack otherwise
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
- sctp_send_nr_sack(stcb);
- else
- sctp_send_sack(stcb);
- }
+ /*
+ * CMT DAC algorithm: With CMT, delay acks
+ * even in the face of
+ *
+ * reordering. Therefore, if acks that do not
+ * have to be sent because of the above
+ * reasons, will be delayed. That is, acks
+ * that would have been sent due to gap
+ * reports will be delayed with DAC. Start
+ * the delayed ack timer.
+ */
+ sctp_timer_start(SCTP_TIMER_TYPE_RECV,
+ stcb->sctp_ep, stcb, NULL);
} else {
- if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
- sctp_timer_start(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL);
- }
+ /*
+ * Ok we must build a SACK since the timer
+ * is pending, we got our first packet OR
+ * there are gaps or duplicates.
+ */
+ (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
+ sctp_send_sack(stcb);
+ }
+ } else {
+ if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
+ sctp_timer_start(SCTP_TIMER_TYPE_RECV,
+ stcb->sctp_ep, stcb, NULL);
}
}
}
@@ -3162,32 +2823,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
stcb->asoc.send_sack = 1;
}
/* Start a sack timer or QUEUE a SACK for sending */
- if ((stcb->asoc.cumulative_tsn == stcb->asoc.highest_tsn_inside_map) &&
- (stcb->asoc.mapping_array[0] != 0xff)) {
- if ((stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) ||
- (stcb->asoc.delayed_ack == 0) ||
- (stcb->asoc.numduptsns) ||
- (stcb->asoc.send_sack == 1)) {
- if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
- (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
- }
- /*
- * EY if nr_sacks used then send an nr-sack , a sack
- * otherwise
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
- sctp_send_nr_sack(stcb);
- else
- sctp_send_sack(stcb);
- } else {
- if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
- sctp_timer_start(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL);
- }
- }
- } else {
- sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
- }
+ sctp_sack_check(stcb, was_a_gap, &abort_flag);
if (abort_flag)
return (2);
@@ -3204,7 +2840,7 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
{
struct sctp_tmit_chunk *tp1;
unsigned int theTSN;
- int j, wake_him = 0;
+ int j, wake_him = 0, circled = 0;
/* Recover the tp1 we last saw */
tp1 = *p_tp1;
@@ -3382,12 +3018,6 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
}
/* NR Sack code here */
if (nr_sacking) {
- if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
- tp1->sent = SCTP_DATAGRAM_NR_MARKED;
- /*
- * TAILQ_REMOVE(&asoc->sent_q
- * ueue, tp1, sctp_next);
- */
if (tp1->data) {
/*
* sa_ignore
@@ -3395,13 +3025,8 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
*/
sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
sctp_m_freem(tp1->data);
+ tp1->data = NULL;
}
- tp1->data = NULL;
- /* asoc->sent_queue_cnt--; */
- /*
- * sctp_free_a_chunk(stcb,
- * tp1);
- */
wake_him++;
}
}
@@ -3412,11 +3037,16 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
break;
tp1 = TAILQ_NEXT(tp1, sctp_next);
+ if ((tp1 == NULL) && (circled == 0)) {
+ circled++;
+ tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
+ }
} /* end while (tp1) */
- /* In case the fragments were not in order we must reset */
if (tp1 == NULL) {
+ circled = 0;
tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
}
+ /* In case the fragments were not in order we must reset */
} /* end for (j = fragStart */
*p_tp1 = tp1;
return (wake_him); /* Return value only used for nr-sack */
@@ -3495,6 +3125,9 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
} else {
non_revocable = 1;
}
+ if (i == num_seg) {
+ tp1 = NULL;
+ }
if (sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
non_revocable, &num_frs, biggest_newly_acked_tsn,
this_sack_lowest_newack, ecn_seg_sums)) {
@@ -4298,6 +3931,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
#ifdef INVARIANTS
panic("Impossible sack 1");
#else
+
*abort_now = 1;
/* XXX */
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
@@ -4776,50 +4410,6 @@ again:
}
}
-/* EY- nr_sack */
-/* Identifies the non-renegable tsns that are revoked*/
-static void
-sctp_check_for_nr_revoked(struct sctp_tcb *stcb,
- struct sctp_association *asoc, uint32_t cumack,
- uint32_t biggest_tsn_acked)
-{
- struct sctp_tmit_chunk *tp1;
-
- for (tp1 = TAILQ_FIRST(&asoc->sent_queue); tp1; tp1 = TAILQ_NEXT(tp1, sctp_next)) {
- if (compare_with_wrap(tp1->rec.data.TSN_seq, cumack,
- MAX_TSN)) {
- /*
- * ok this guy is either ACK or MARKED. If it is
- * ACKED it has been previously acked but not this
- * time i.e. revoked. If it is MARKED it was ACK'ed
- * again.
- */
- if (compare_with_wrap(tp1->rec.data.TSN_seq, biggest_tsn_acked,
- MAX_TSN))
- break;
-
-
- if (tp1->sent == SCTP_DATAGRAM_NR_ACKED) {
- /*
- * EY! a non-renegable TSN is revoked, need
- * to abort the association
- */
- /*
- * EY TODO: put in the code to abort the
- * assoc.
- */
- return;
- } else if (tp1->sent == SCTP_DATAGRAM_NR_MARKED) {
- /* it has been re-acked in this SACK */
- tp1->sent = SCTP_DATAGRAM_NR_ACKED;
- }
- }
- if (tp1->sent == SCTP_DATAGRAM_UNSENT)
- break;
- }
- return;
-}
-
void
sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
struct sctp_tcb *stcb, struct sctp_nets *net_from,
@@ -4925,22 +4515,23 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
sctpchunk_listhead);
send_s = tp1->rec.data.TSN_seq + 1;
} else {
+ tp1 = NULL;
send_s = asoc->sending_seq;
}
if (cum_ack == send_s ||
compare_with_wrap(cum_ack, send_s, MAX_TSN)) {
-#ifndef INVARIANTS
struct mbuf *oper;
-#endif
-#ifdef INVARIANTS
- hopeless_peer:
- panic("Impossible sack 1");
-#else
/*
* no way, we have not even sent this TSN out yet.
* Peer is hopelessly messed up with us.
*/
+ printf("NEW cum_ack:%x send_s:%x is smaller or equal\n",
+ cum_ack, send_s);
+ if (tp1) {
+ printf("Got send_s from tsn:%x + 1 of tp1:%p\n",
+ tp1->rec.data.TSN_seq, tp1);
+ }
hopeless_peer:
*abort_now = 1;
/* XXX */
@@ -4961,7 +4552,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper, SCTP_SO_NOT_LOCKED);
return;
-#endif
}
}
/**********************/
@@ -5181,6 +4771,10 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
* peer is either confused or we are under
* attack. We must abort.
*/
+ printf("Hopeless peer! biggest_tsn_acked:%x largest seq:%x\n",
+ biggest_tsn_acked,
+ send_s);
+
goto hopeless_peer;
}
}
@@ -5328,15 +4922,9 @@ done_with_it:
*/
if ((tp1->sent == SCTP_DATAGRAM_NR_ACKED) ||
(tp1->sent == SCTP_DATAGRAM_NR_MARKED)) {
- /*
- * EY! - TODO: Something previously
- * nr_gapped is reneged, abort the
- * association
- */
- return;
+ continue;
}
- if ((tp1->sent > SCTP_DATAGRAM_RESEND) &&
- (tp1->sent < SCTP_FORWARD_TSN_SKIP)) {
+ if (tp1->sent == SCTP_DATAGRAM_ACKED) {
tp1->sent = SCTP_DATAGRAM_SENT;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
sctp_misc_ints(SCTP_FLIGHT_LOG_UP_REVOKE,
@@ -5365,15 +4953,11 @@ done_with_it:
}
asoc->saw_sack_with_frags = 0;
}
- if (num_seg)
+ if (num_seg || num_nr_seg)
asoc->saw_sack_with_frags = 1;
else
asoc->saw_sack_with_frags = 0;
- /* EY! - not sure about if there should be an IF */
- if (num_nr_seg > 0)
- sctp_check_for_nr_revoked(stcb, asoc, cum_ack, biggest_tsn_acked);
-
/* JRS - Use the congestion control given in the CC module */
asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
@@ -5776,9 +5360,6 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
struct sctp_association *asoc;
int tt;
- /* EY -used to calculate nr_gap information */
- uint32_t nr_tsn, nr_gap;
-
asoc = &stcb->asoc;
tt = strmin->last_sequence_delivered;
/*
@@ -5797,83 +5378,10 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
sctp_ucount_decr(asoc->cnt_on_all_streams);
/* deliver it to at least the delivery-q */
if (stcb->sctp_socket) {
- /* EY need the tsn info for calculating nr */
- nr_tsn = ctl->sinfo_tsn;
+ sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
ctl,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
- /*
- * EY this is the chunk that should be
- * tagged nr gapped calculate the gap and
- * such then tag this TSN nr
- * chk->rec.data.TSN_seq
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
- if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
- (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
- /*
- * EY These should never
- * happen- explained before
- */
- } else {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
- if (compare_with_wrap(nr_tsn,
- asoc->highest_tsn_inside_nr_map,
- MAX_TSN))
- asoc->highest_tsn_inside_nr_map = nr_tsn;
- }
- if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap))
- /*
- * printf("In
- * sctp_kick_prsctp_reorder_q
- * ueue(7): Something wrong,
- * the TSN to be tagged"
- * "\nas NR is not even in
- * the mapping_array, or map
- * and nr_map are
- * inconsistent");
- */
- /*
- * EY - not %100 sure about
- * the lock thing, don't
- * think its required
- */
- /*
- * SCTP_TCB_LOCK_ASSERT(stcb)
- * ;
- */
- {
- /*
- * printf("\nCalculating an
- * nr_gap!!\nmapping_array_si
- * ze = %d
- * nr_mapping_array_size =
- * %d" "\nmapping_array_base
- * = %d
- * nr_mapping_array_base =
- * %d\nhighest_tsn_inside_map
- * = %d"
- * "highest_tsn_inside_nr_map
- * = %d\nTSN = %d nr_gap =
- * %d",asoc->mapping_array_si
- * ze,
- * asoc->nr_mapping_array_siz
- * e,
- * asoc->mapping_array_base_t
- * sn,
- * asoc->nr_mapping_array_bas
- * e_tsn,
- * asoc->highest_tsn_inside_m
- * ap,
- * asoc->highest_tsn_inside_n
- * r_map,tsn,nr_gap);
- */
- }
- }
}
} else {
/* no more delivery now. */
@@ -5898,82 +5406,11 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
/* deliver it to at least the delivery-q */
strmin->last_sequence_delivered = ctl->sinfo_ssn;
if (stcb->sctp_socket) {
- /* EY */
- nr_tsn = ctl->sinfo_tsn;
+ sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
ctl,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
- /*
- * EY this is the chunk that should be
- * tagged nr gapped calculate the gap and
- * such then tag this TSN nr
- * chk->rec.data.TSN_seq
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- asoc->peer_supports_nr_sack) {
- SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
- if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
- (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
- /*
- * EY These should never
- * happen, explained before
- */
- } else {
- SCTP_TCB_LOCK_ASSERT(stcb);
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
- SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
- if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map,
- MAX_TSN))
- asoc->highest_tsn_inside_nr_map = nr_tsn;
- }
- if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap))
- /*
- * printf("In
- * sctp_kick_prsctp_reorder_q
- * ueue(8): Something wrong,
- * the TSN to be tagged"
- * "\nas NR is not even in
- * the mapping_array, or map
- * and nr_map are
- * inconsistent");
- */
- /*
- * EY - not %100 sure about
- * the lock thing, don't
- * think its required
- */
- /*
- * SCTP_TCB_LOCK_ASSERT(stcb)
- * ;
- */
- {
- /*
- * printf("\nCalculating an
- * nr_gap!!\nmapping_array_si
- * ze = %d
- * nr_mapping_array_size =
- * %d" "\nmapping_array_base
- * = %d
- * nr_mapping_array_base =
- * %d\nhighest_tsn_inside_map
- * = %d"
- * "highest_tsn_inside_nr_map
- * = %d\nTSN = %d nr_gap =
- * %d",asoc->mapping_array_si
- * ze,
- * asoc->nr_mapping_array_siz
- * e,
- * asoc->mapping_array_base_t
- * sn,
- * asoc->nr_mapping_array_bas
- * e_tsn,
- * asoc->highest_tsn_inside_m
- * ap,
- * asoc->highest_tsn_inside_n
- * r_map,tsn,nr_gap);
- */
- }
- }
+
}
tt = strmin->last_sequence_delivered + 1;
} else {
@@ -6076,7 +5513,8 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
void
sctp_handle_forward_tsn(struct sctp_tcb *stcb,
- struct sctp_forward_tsn_chunk *fwd, int *abort_flag, struct mbuf *m, int offset)
+ struct sctp_forward_tsn_chunk *fwd,
+ int *abort_flag, struct mbuf *m, int offset)
{
/*
* ISSUES that MUST be fixed for ECN! When we are the sender of the
@@ -6102,8 +5540,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
* report where we are.
*/
struct sctp_association *asoc;
- uint32_t new_cum_tsn, gap;
- unsigned int i, fwd_sz, cumack_set_flag, m_size;
+ uint32_t new_cum_tsn, tsn, gap;
+ unsigned int i, fwd_sz, cumack_set_flag, m_size, fnd = 0;
uint32_t str_seq;
struct sctp_stream_in *strm;
struct sctp_tmit_chunk *chk, *at;
@@ -6130,25 +5568,19 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map,
MAX_TSN)) {
asoc->highest_tsn_inside_map = new_cum_tsn;
- /* EY nr_mapping_array version of the above */
- /*
- * if(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
- * asoc->peer_supports_nr_sack)
- */
+
+ }
+ if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map,
+ MAX_TSN)) {
asoc->highest_tsn_inside_nr_map = new_cum_tsn;
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
- }
}
/*
* now we know the new TSN is more advanced, let's find the actual
* gap
*/
SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn);
+ asoc->cumulative_tsn = new_cum_tsn;
if (gap >= m_size) {
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
- }
if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) {
struct mbuf *oper;
@@ -6181,23 +5613,14 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
return;
}
SCTP_STAT_INCR(sctps_fwdtsn_map_over);
+
memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
- cumack_set_flag = 1;
asoc->mapping_array_base_tsn = new_cum_tsn + 1;
- asoc->cumulative_tsn = asoc->highest_tsn_inside_map = new_cum_tsn;
- /* EY - nr_sack: nr_mapping_array version of the above */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
- memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
- asoc->nr_mapping_array_base_tsn = new_cum_tsn + 1;
- asoc->highest_tsn_inside_nr_map = new_cum_tsn;
- if (asoc->nr_mapping_array_size != asoc->mapping_array_size) {
- /*
- * printf("IN sctp_handle_forward_tsn:
- * Something is wrong the size of" "map and
- * nr_map should be equal!")
- */ ;
- }
- }
+ asoc->highest_tsn_inside_map = new_cum_tsn;
+
+ memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
+ asoc->highest_tsn_inside_nr_map = new_cum_tsn;
+
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
sctp_log_map(0, 3, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
}
@@ -6205,20 +5628,34 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
} else {
SCTP_TCB_LOCK_ASSERT(stcb);
for (i = 0; i <= gap; i++) {
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack
- && SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
- SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
- } else {
- SCTP_SET_TSN_PRESENT(asoc->mapping_array, i);
+ SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, i);
+ SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
+ /* FIX ME add something to set up highest TSN in map */
+ }
+ if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ asoc->highest_tsn_inside_nr_map = new_cum_tsn;
+ }
+ if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map, MAX_TSN) ||
+ new_cum_tsn == asoc->highest_tsn_inside_map) {
+ /* We must back down to see what the new highest is */
+ for (tsn = new_cum_tsn; (compare_with_wrap(tsn, asoc->mapping_array_base_tsn, MAX_TSN) ||
+ (tsn == asoc->mapping_array_base_tsn)); tsn--) {
+ SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
+ if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
+ asoc->highest_tsn_inside_map = tsn;
+ fnd = 1;
+ break;
+ }
+ }
+ if (!fnd) {
+ asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
}
}
/*
* Now after marking all, slide thing forward but no sack
* please.
*/
- sctp_sack_check(stcb, 0, 0, abort_flag);
- if (*abort_flag)
- return;
+ sctp_slide_mapping_arrays(stcb);
}
/*************************************************************/
/* 2. Clear up re-assembly queue */
diff --git a/sys/netinet/sctp_indata.h b/sys/netinet/sctp_indata.h
index b6a8323..79978a5 100644
--- a/sys/netinet/sctp_indata.h
+++ b/sys/netinet/sctp_indata.h
@@ -121,7 +121,9 @@ sctp_process_data(struct mbuf **, int, int *, int, struct sctphdr *,
struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint32_t *);
-void sctp_sack_check(struct sctp_tcb *, int, int, int *);
+void sctp_slide_mapping_arrays(struct sctp_tcb *stcb);
+
+void sctp_sack_check(struct sctp_tcb *, int, int *);
#endif
#endif
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index ef18737..a2bb063 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -343,11 +343,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb,
asoc->str_reset_seq_in = asoc->asconf_seq_in + 1;
asoc->mapping_array_base_tsn = ntohl(init->initial_tsn);
- /*
- * EY 05/13/08 - nr_sack: initialize nr_mapping array's base tsn
- * like above
- */
- asoc->nr_mapping_array_base_tsn = ntohl(init->initial_tsn);
asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in;
asoc->last_echo_tsn = asoc->asconf_seq_in;
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
@@ -1860,11 +1855,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
memset(asoc->mapping_array, 0,
asoc->mapping_array_size);
}
- /* EY 05/13/08 - nr_sack version of the above if statement */
- if (asoc->nr_mapping_array && SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)
- && asoc->peer_supports_nr_sack) {
+ if (asoc->nr_mapping_array) {
memset(asoc->nr_mapping_array, 0,
- asoc->nr_mapping_array_size);
+ asoc->mapping_array_size);
}
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
@@ -2029,7 +2022,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
* socket is unbound and we must do an implicit bind. Since we are
* getting a cookie, we cannot be unbound.
*/
- stcb = sctp_aloc_assoc(inp, init_src, 0, &error,
+ stcb = sctp_aloc_assoc(inp, init_src, &error,
ntohl(initack_cp->init.initiate_tag), vrf_id,
(struct thread *)NULL
);
@@ -3238,13 +3231,10 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
}
break;
case SCTP_SELECTIVE_ACK:
+ case SCTP_NR_SELECTIVE_ACK:
/* resend the sack */
sctp_send_sack(stcb);
break;
- /* EY for nr_sacks */
- case SCTP_NR_SELECTIVE_ACK:
- sctp_send_nr_sack(stcb); /* EY resend the nr-sack */
- break;
case SCTP_HEARTBEAT_REQUEST:
/* resend a demand HB */
if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) {
@@ -3515,16 +3505,9 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn);
memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
- /*
- * EY 05/13/08 - nr_sack: to keep
- * nr_mapping array be consistent
- * with mapping_array
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack) {
- stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
- stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.mapping_array_base_tsn;
- memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
- }
+ stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
+ memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
+
stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
@@ -3631,15 +3614,8 @@ sctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map;
stcb->asoc.mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
- /*
- * EY 05/13/08 -nr_sack: to keep nr_mapping array consistent
- * with mapping array
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack) {
- stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
- stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
- memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
- }
+ stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
+ memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
atomic_add_int(&stcb->asoc.sending_seq, 1);
/* save off historical data for retrans */
stcb->asoc.last_sending_seq[1] = stcb->asoc.last_sending_seq[0];
@@ -5650,7 +5626,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
was_a_gap = 1;
}
stcb->asoc.send_sack = 1;
- sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
+ sctp_sack_check(stcb, was_a_gap, &abort_flag);
if (abort_flag) {
/* Again, we aborted so NO UNLOCK needed */
goto out_now;
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index be4c3a8..47590c7 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3709,7 +3709,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
(stcb) &&
(stcb->asoc.loopback_scope))) {
m->m_pkthdr.csum_flags = CSUM_SCTP;
- m->m_pkthdr.csum_data = 0; /* FIXME MT */
+ m->m_pkthdr.csum_data = 0;
SCTP_STAT_INCR(sctps_sendhwcrc);
} else {
SCTP_STAT_INCR(sctps_sendnocrc);
@@ -4021,7 +4021,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
(stcb) &&
(stcb->asoc.loopback_scope))) {
m->m_pkthdr.csum_flags = CSUM_SCTP;
- m->m_pkthdr.csum_data = 0; /* FIXME MT */
+ m->m_pkthdr.csum_data = 0;
SCTP_STAT_INCR(sctps_sendhwcrc);
} else {
SCTP_STAT_INCR(sctps_sendnocrc);
@@ -7871,19 +7871,8 @@ again_one_more_time:
pf_hbflag = 1;
}
/* remove these chunks at the end */
- if (chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) {
- /* turn off the timer */
- if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
- sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- inp, stcb, net, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_1);
- }
- }
- /*
- * EY -Nr-sack version of the above
- * if statement
- */
- if ((SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) &&
- (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) { /* EY !?! */
+ if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
+ (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) {
/* turn off the timer */
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
@@ -8984,7 +8973,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
/* (void)SCTP_GETTIME_TIMEVAL(&chk->whoTo->last_sent_time); */
*cnt_out += 1;
chk->sent = SCTP_DATAGRAM_SENT;
- sctp_ucount_decr(asoc->sent_queue_retran_cnt);
+ /* sctp_ucount_decr(asoc->sent_queue_retran_cnt); */
if (fwd_tsn == 0) {
return (0);
} else {
@@ -9014,6 +9003,11 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
/* No, not sent to this net or not ready for rtx */
continue;
}
+ if (chk->data == NULL) {
+ printf("TSN:%x chk->snd_count:%d chk->sent:%d can't retran - no data\n",
+ chk->rec.data.TSN_seq, chk->snd_count, chk->sent);
+ continue;
+ }
if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) &&
(chk->snd_count >= SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) {
/* Gak, we have exceeded max unlucky retran, abort! */
@@ -9437,14 +9431,7 @@ sctp_chunk_output(struct sctp_inpcb *inp,
* running, if so piggy-back the sack.
*/
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
- /*
- * EY if nr_sacks used then send an nr-sack , a sack
- * otherwise
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack)
- sctp_send_nr_sack(stcb);
- else
- sctp_send_sack(stcb);
+ sctp_send_sack(stcb);
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
}
while (asoc->sent_queue_retran_cnt) {
@@ -9867,13 +9854,15 @@ void
sctp_send_sack(struct sctp_tcb *stcb)
{
/*-
- * Queue up a SACK in the control queue. We must first check to see
- * if a SACK is somehow on the control queue. If so, we will take
- * and and remove the old one.
+ * Queue up a SACK or NR-SACK in the control queue.
+ * We must first check to see if a SACK or NR-SACK is
+ * somehow on the control queue.
+ * If so, we will take and and remove the old one.
*/
struct sctp_association *asoc;
struct sctp_tmit_chunk *chk, *a_chk;
struct sctp_sack_chunk *sack;
+ struct sctp_nr_sack_chunk *nr_sack;
struct sctp_gap_ack_block *gap_descriptor;
struct sack_track *selector;
int mergeable = 0;
@@ -9881,11 +9870,20 @@ sctp_send_sack(struct sctp_tcb *stcb)
caddr_t limit;
uint32_t *dup;
int limit_reached = 0;
- unsigned int i, jstart, siz, j;
- unsigned int num_gap_blocks = 0, space;
+ unsigned int i, sel_start, siz, j, starting_index;
+ unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
int num_dups = 0;
int space_req;
+ uint32_t highest_tsn;
+ uint8_t flags;
+ uint8_t type;
+ if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
+ stcb->asoc.peer_supports_nr_sack) {
+ type = SCTP_NR_SELECTIVE_ACK;
+ } else {
+ type = SCTP_SELECTIVE_ACK;
+ }
a_chk = NULL;
asoc = &stcb->asoc;
SCTP_TCB_LOCK_ASSERT(stcb);
@@ -9893,9 +9891,10 @@ sctp_send_sack(struct sctp_tcb *stcb)
/* Hmm we never received anything */
return;
}
+ sctp_slide_mapping_arrays(stcb);
sctp_set_rwnd(stcb, asoc);
TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
- if (chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) {
+ if (chk->rec.chunk_id.id == type) {
/* Hmm, found a sack already on queue, remove it */
TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
asoc->ctrl_queue_cnt++;
@@ -9924,8 +9923,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
return;
}
a_chk->copy_by_ref = 0;
- /* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */
- a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK;
+ a_chk->rec.chunk_id.id = type;
a_chk->rec.chunk_id.can_take_data = 1;
}
/* Clear our pkt counts */
@@ -9970,9 +9968,18 @@ sctp_send_sack(struct sctp_tcb *stcb)
if (a_chk->whoTo) {
atomic_add_int(&a_chk->whoTo->ref_count, 1);
}
- if (asoc->highest_tsn_inside_map == asoc->cumulative_tsn) {
+ if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
+ highest_tsn = asoc->highest_tsn_inside_map;
+ } else {
+ highest_tsn = asoc->highest_tsn_inside_nr_map;
+ }
+ if (highest_tsn == asoc->cumulative_tsn) {
/* no gaps */
- space_req = sizeof(struct sctp_sack_chunk);
+ if (type == SCTP_SELECTIVE_ACK) {
+ space_req = sizeof(struct sctp_sack_chunk);
+ } else {
+ space_req = sizeof(struct sctp_nr_sack_chunk);
+ }
} else {
/* gaps get a cluster */
space_req = MCLBYTES;
@@ -10008,15 +10015,13 @@ sctp_send_sack(struct sctp_tcb *stcb)
limit = mtod(a_chk->data, caddr_t);
limit += space;
- sack = mtod(a_chk->data, struct sctp_sack_chunk *);
- sack->ch.chunk_type = SCTP_SELECTIVE_ACK;
/* 0x01 is used by nonce for ecn */
if ((SCTP_BASE_SYSCTL(sctp_ecn_enable)) &&
(SCTP_BASE_SYSCTL(sctp_ecn_nonce)) &&
(asoc->peer_supports_ecn_nonce))
- sack->ch.chunk_flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM);
+ flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM);
else
- sack->ch.chunk_flags = 0;
+ flags = 0;
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
/*-
@@ -10024,7 +10029,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
* received, then set high bit to 1, else 0. Reset
* pkts_rcvd.
*/
- sack->ch.chunk_flags |= (asoc->cmt_dac_pkts_rcvd << 6);
+ flags |= (asoc->cmt_dac_pkts_rcvd << 6);
asoc->cmt_dac_pkts_rcvd = 0;
}
#ifdef SCTP_ASOCLOG_OF_TSNS
@@ -10034,344 +10039,81 @@ sctp_send_sack(struct sctp_tcb *stcb)
stcb->asoc.cumack_log_atsnt = 0;
}
#endif
- sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
- sack->sack.a_rwnd = htonl(asoc->my_rwnd);
- asoc->my_last_reported_rwnd = asoc->my_rwnd;
-
/* reset the readers interpretation */
stcb->freed_by_sorcv_sincelast = 0;
- gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)sack + sizeof(struct sctp_sack_chunk));
-
- if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn)
- siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
- else
- siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
-
- if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
- offset = 1;
- /*-
- * cum-ack behind the mapping array, so we start and use all
- * entries.
- */
- jstart = 0;
- } else {
- offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
- /*-
- * we skip the first one when the cum-ack is at or above the
- * mapping array base. Note this only works if
- */
- jstart = 1;
- }
- if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN)) {
- /* we have a gap .. maybe */
- for (i = 0; i < siz; i++) {
- selector = &sack_array[asoc->mapping_array[i]];
- if (mergeable && selector->right_edge) {
- /*
- * Backup, left and right edges were ok to
- * merge.
- */
- num_gap_blocks--;
- gap_descriptor--;
- }
- if (selector->num_entries == 0)
- mergeable = 0;
- else {
- for (j = jstart; j < selector->num_entries; j++) {
- if (mergeable && selector->right_edge) {
- /*
- * do a merge by NOT setting
- * the left side
- */
- mergeable = 0;
- } else {
- /*
- * no merge, set the left
- * side
- */
- mergeable = 0;
- gap_descriptor->start = htons((selector->gaps[j].start + offset));
- }
- gap_descriptor->end = htons((selector->gaps[j].end + offset));
- num_gap_blocks++;
- gap_descriptor++;
- if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
- /* no more room */
- limit_reached = 1;
- break;
- }
- }
- if (selector->left_edge) {
- mergeable = 1;
- }
- }
- if (limit_reached) {
- /* Reached the limit stop */
- break;
- }
- jstart = 0;
- offset += 8;
- }
- if (num_gap_blocks == 0) {
- /*
- * slide not yet happened, and somehow we got called
- * to send a sack. Cumack needs to move up.
- */
- int abort_flag = 0;
-
- asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
- sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
- sctp_sack_check(stcb, 0, 0, &abort_flag);
- }
- }
- /* now we must add any dups we are going to report. */
- if ((limit_reached == 0) && (asoc->numduptsns)) {
- dup = (uint32_t *) gap_descriptor;
- for (i = 0; i < asoc->numduptsns; i++) {
- *dup = htonl(asoc->dup_tsns[i]);
- dup++;
- num_dups++;
- if (((caddr_t)dup + sizeof(uint32_t)) > limit) {
- /* no more room */
- break;
- }
- }
- asoc->numduptsns = 0;
- }
- /*
- * now that the chunk is prepared queue it to the control chunk
- * queue.
- */
- a_chk->send_size = (sizeof(struct sctp_sack_chunk) +
- (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) +
- (num_dups * sizeof(int32_t)));
- SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
- sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
- sack->sack.num_dup_tsns = htons(num_dups);
- sack->ch.chunk_length = htons(a_chk->send_size);
- TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
- asoc->ctrl_queue_cnt++;
- asoc->send_sack = 0;
- SCTP_STAT_INCR(sctps_sendsacks);
- return;
-}
-
-/* EY - This method will replace sctp_send_sack method if nr_sacks negotiated*/
-void
-sctp_send_nr_sack(struct sctp_tcb *stcb)
-{
- /*-
- * Queue up an NR-SACK in the control queue. We must first check to see
- * if an NR-SACK is somehow on the control queue. If so, we will take
- * and and remove the old one.
- */
- struct sctp_association *asoc;
- struct sctp_tmit_chunk *chk, *a_chk;
-
- struct sctp_nr_sack_chunk *nr_sack;
-
- struct sctp_gap_ack_block *gap_descriptor;
-
- struct sack_track *selector;
- struct sack_track *nr_selector;
-
- /* EY do we need nr_mergeable, NO */
- int mergeable = 0;
- int offset;
- caddr_t limit;
- uint32_t *dup;
- int limit_reached = 0;
- unsigned int i, jstart, siz, j;
- unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
- int num_dups = 0;
- int space_req;
- unsigned int reserved = 0;
-
- a_chk = NULL;
- asoc = &stcb->asoc;
- SCTP_TCB_LOCK_ASSERT(stcb);
- if (asoc->last_data_chunk_from == NULL) {
- /* Hmm we never received anything */
- return;
- }
- sctp_set_rwnd(stcb, asoc);
- TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
- if (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) {
- /* Hmm, found a sack already on queue, remove it */
- TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
- asoc->ctrl_queue_cnt++;
- a_chk = chk;
- if (a_chk->data) {
- sctp_m_freem(a_chk->data);
- a_chk->data = NULL;
- }
- sctp_free_remote_addr(a_chk->whoTo);
- a_chk->whoTo = NULL;
- break;
- }
- }
- if (a_chk == NULL) {
- sctp_alloc_a_chunk(stcb, a_chk);
- if (a_chk == NULL) {
- /* No memory so we drop the idea, and set a timer */
- if (stcb->asoc.delayed_ack) {
- sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
- sctp_timer_start(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL);
- } else {
- stcb->asoc.send_sack = 1;
- }
- return;
- }
- a_chk->copy_by_ref = 0;
- /* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */
- a_chk->rec.chunk_id.id = SCTP_NR_SELECTIVE_ACK;
- a_chk->rec.chunk_id.can_take_data = 1;
- }
- /* Clear our pkt counts */
- asoc->data_pkts_seen = 0;
-
- a_chk->asoc = asoc;
- a_chk->snd_count = 0;
- a_chk->send_size = 0; /* fill in later */
- a_chk->sent = SCTP_DATAGRAM_UNSENT;
- a_chk->whoTo = NULL;
-
- if ((asoc->numduptsns) ||
- (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)
- ) {
- /*-
- * Ok, we have some duplicates or the destination for the
- * sack is unreachable, lets see if we can select an
- * alternate than asoc->last_data_chunk_from
- */
- if ((!(asoc->last_data_chunk_from->dest_state &
- SCTP_ADDR_NOT_REACHABLE)) &&
- (asoc->used_alt_onsack > asoc->numnets)) {
- /* We used an alt last time, don't this time */
- a_chk->whoTo = NULL;
+ if (type == SCTP_SELECTIVE_ACK) {
+ sack = mtod(a_chk->data, struct sctp_sack_chunk *);
+ nr_sack = NULL;
+ gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)sack + sizeof(struct sctp_sack_chunk));
+ if (highest_tsn > asoc->mapping_array_base_tsn) {
+ siz = (((highest_tsn - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
} else {
- asoc->used_alt_onsack++;
- a_chk->whoTo = sctp_find_alternate_net(stcb, asoc->last_data_chunk_from, 0);
- }
- if (a_chk->whoTo == NULL) {
- /* Nope, no alternate */
- a_chk->whoTo = asoc->last_data_chunk_from;
- asoc->used_alt_onsack = 0;
+ siz = (((MAX_TSN - highest_tsn) + 1) + highest_tsn + 7) / 8;
}
} else {
- /*
- * No duplicates so we use the last place we received data
- * from.
- */
- asoc->used_alt_onsack = 0;
- a_chk->whoTo = asoc->last_data_chunk_from;
- }
- if (a_chk->whoTo) {
- atomic_add_int(&a_chk->whoTo->ref_count, 1);
- }
- if (asoc->highest_tsn_inside_map == asoc->cumulative_tsn) {
- /* no gaps */
- space_req = sizeof(struct sctp_nr_sack_chunk);
- } else {
- /* EY - what is this about? */
- /* gaps get a cluster */
- space_req = MCLBYTES;
- }
- /* Ok now lets formulate a MBUF with our sack */
- a_chk->data = sctp_get_mbuf_for_msg(space_req, 0, M_DONTWAIT, 1, MT_DATA);
- if ((a_chk->data == NULL) ||
- (a_chk->whoTo == NULL)) {
- /* rats, no mbuf memory */
- if (a_chk->data) {
- /* was a problem with the destination */
- sctp_m_freem(a_chk->data);
- a_chk->data = NULL;
- }
- sctp_free_a_chunk(stcb, a_chk);
- /* sa_ignore NO_NULL_CHK */
- if (stcb->asoc.delayed_ack) {
- sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
- sctp_timer_start(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL);
+ sack = NULL;
+ nr_sack = mtod(a_chk->data, struct sctp_nr_sack_chunk *);
+ gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)nr_sack + sizeof(struct sctp_nr_sack_chunk));
+ if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn) {
+ siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
} else {
- stcb->asoc.send_sack = 1;
+ siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
}
- return;
- }
- /* ok, lets go through and fill it in */
- SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD);
- space = M_TRAILINGSPACE(a_chk->data);
- if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) {
- space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD);
}
- limit = mtod(a_chk->data, caddr_t);
- limit += space;
-
- nr_sack = mtod(a_chk->data, struct sctp_nr_sack_chunk *);
- nr_sack->ch.chunk_type = SCTP_NR_SELECTIVE_ACK;
- /* EYJ */
- /* 0x01 is used by nonce for ecn */
- if ((SCTP_BASE_SYSCTL(sctp_ecn_enable)) &&
- (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) &&
- (asoc->peer_supports_ecn_nonce))
- nr_sack->ch.chunk_flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM);
- else
- nr_sack->ch.chunk_flags = 0;
-
- if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
- /*-
- * CMT DAC algorithm: If 2 (i.e., 0x10) packets have been
- * received, then set high bit to 1, else 0. Reset
- * pkts_rcvd.
- */
- /* EY - TODO: which chunk flag is used in here? -The LSB */
- nr_sack->ch.chunk_flags |= (asoc->cmt_dac_pkts_rcvd << 6);
- asoc->cmt_dac_pkts_rcvd = 0;
- }
-#ifdef SCTP_ASOCLOG_OF_TSNS
- stcb->asoc.cumack_logsnt[stcb->asoc.cumack_log_atsnt] = asoc->cumulative_tsn;
- stcb->asoc.cumack_log_atsnt++;
- if (stcb->asoc.cumack_log_atsnt >= SCTP_TSN_LOG_SIZE) {
- stcb->asoc.cumack_log_atsnt = 0;
- }
-#endif
- nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
- nr_sack->nr_sack.a_rwnd = htonl(asoc->my_rwnd);
- asoc->my_last_reported_rwnd = asoc->my_rwnd;
-
- /* reset the readers interpretation */
- stcb->freed_by_sorcv_sincelast = 0;
-
- gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)nr_sack + sizeof(struct sctp_nr_sack_chunk));
-
- if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn)
- siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
- else
- siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
offset = 1;
/*-
- * cum-ack behind the mapping array, so we start and use all
- * entries.
+ * The base TSN is intialized to be the first TSN the peer
+ * will send us. If the cum-ack is behind this then when they
+ * send us the next in sequence it will mark the base_tsn bit.
+ * Thus we need to use the very first selector and the offset
+ * is 1. Our table is built for this case.
*/
- jstart = 0;
+ starting_index = 0;
+ sel_start = 0;
} else {
- offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
/*-
- * we skip the first one when the cum-ack is at or above the
- * mapping array base. Note this only works if
+ * we skip the first selector when the cum-ack is at or above the
+ * mapping array base. This is because the bits at the base or above
+ * are turned on and our first selector in the table assumes they are
+ * off. We thus will use the second selector (first is 0). We use
+ * the reverse of our macro to fix the offset, in bits, that our
+ * table is at. Note that this method assumes that the cum-tsn is
+ * within the first bit, i.e. its value is 0-7 which means the
+ * result to our offset will be either a 0 - -7. If the cumack
+ * is NOT in the first byte (0) (which it should be since we did
+ * a mapping array slide above) then we need to calculate the starting
+ * index i.e. which byte of the mapping array we should start at. We
+ * do this by dividing by 8 and pushing the remainder (mod) into offset.
+ * then we multiply the offset to be negative, since we need a negative
+ * offset into the selector table.
*/
- jstart = 1;
+ SCTP_CALC_TSN_TO_GAP(offset, asoc->cumulative_tsn, asoc->mapping_array_base_tsn);
+ if (offset > 7) {
+ starting_index = offset / 8;
+ offset = offset % 8;
+ printf("Strange starting index is %d offset:%d (not 0/x)\n",
+ starting_index, offset);
+ } else {
+ starting_index = 0;
+ }
+ /* We need a negative offset in our table */
+ offset *= -1;
+ sel_start = 1;
}
- if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN)) {
+ if (((type == SCTP_SELECTIVE_ACK) &&
+ compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) ||
+ ((type == SCTP_NR_SELECTIVE_ACK) &&
+ compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN))) {
/* we have a gap .. maybe */
- for (i = 0; i < siz; i++) {
- selector = &sack_array[asoc->mapping_array[i]];
+ for (i = starting_index; i < siz; i++) {
+ if (type == SCTP_SELECTIVE_ACK) {
+ selector = &sack_array[asoc->mapping_array[i] | asoc->nr_mapping_array[i]];
+ } else {
+ selector = &sack_array[asoc->mapping_array[i]];
+ }
if (mergeable && selector->right_edge) {
/*
* Backup, left and right edges were ok to
@@ -10383,7 +10125,7 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
if (selector->num_entries == 0)
mergeable = 0;
else {
- for (j = jstart; j < selector->num_entries; j++) {
+ for (j = sel_start; j < selector->num_entries; j++) {
if (mergeable && selector->right_edge) {
/*
* do a merge by NOT setting
@@ -10415,53 +10157,40 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
/* Reached the limit stop */
break;
}
- jstart = 0;
+ sel_start = 0;
offset += 8;
}
- if (num_gap_blocks == 0) {
- /*
- * slide not yet happened, and somehow we got called
- * to send a sack. Cumack needs to move up.
- */
- int abort_flag = 0;
-
- asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
- nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
- sctp_sack_check(stcb, 0, 0, &abort_flag);
- }
}
- /*---------------------------------------------------------filling the nr_gap_ack blocks----------------------------------------------------*/
-
- /* EY - there will be gaps + nr_gaps if draining is possible */
- if ((SCTP_BASE_SYSCTL(sctp_do_drain)) && (limit_reached == 0)) {
+ if ((type == SCTP_NR_SELECTIVE_ACK) &&
+ (limit_reached == 0)) {
mergeable = 0;
- if (asoc->highest_tsn_inside_nr_map > asoc->nr_mapping_array_base_tsn)
- siz = (((asoc->highest_tsn_inside_nr_map - asoc->nr_mapping_array_base_tsn) + 1) + 7) / 8;
+ if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn)
+ siz = (((asoc->highest_tsn_inside_nr_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
else
- siz = (((MAX_TSN - asoc->nr_mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
+ siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
- if (compare_with_wrap(asoc->nr_mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
+ if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
offset = 1;
/*-
* cum-ack behind the mapping array, so we start and use all
* entries.
*/
- jstart = 0;
+ sel_start = 0;
} else {
- offset = asoc->nr_mapping_array_base_tsn - asoc->cumulative_tsn;
+ offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
/*-
* we skip the first one when the cum-ack is at or above the
* mapping array base. Note this only works if
*/
- jstart = 1;
+ sel_start = 1;
}
if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) {
/* we have a gap .. maybe */
for (i = 0; i < siz; i++) {
- nr_selector = &sack_array[asoc->nr_mapping_array[i]];
- if (mergeable && nr_selector->right_edge) {
+ selector = &sack_array[asoc->nr_mapping_array[i]];
+ if (mergeable && selector->right_edge) {
/*
* Backup, left and right edges were
* ok to merge.
@@ -10469,11 +10198,11 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
num_nr_gap_blocks--;
gap_descriptor--;
}
- if (nr_selector->num_entries == 0)
+ if (selector->num_entries == 0)
mergeable = 0;
else {
- for (j = jstart; j < nr_selector->num_entries; j++) {
- if (mergeable && nr_selector->right_edge) {
+ for (j = sel_start; j < selector->num_entries; j++) {
+ if (mergeable && selector->right_edge) {
/*
* do a merge by NOT
* setting the left
@@ -10486,9 +10215,9 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
* left side
*/
mergeable = 0;
- gap_descriptor->start = htons((nr_selector->gaps[j].start + offset));
+ gap_descriptor->start = htons((selector->gaps[j].start + offset));
}
- gap_descriptor->end = htons((nr_selector->gaps[j].end + offset));
+ gap_descriptor->end = htons((selector->gaps[j].end + offset));
num_nr_gap_blocks++;
gap_descriptor++;
if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
@@ -10497,7 +10226,7 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
break;
}
}
- if (nr_selector->left_edge) {
+ if (selector->left_edge) {
mergeable = 1;
}
}
@@ -10505,13 +10234,11 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
/* Reached the limit stop */
break;
}
- jstart = 0;
+ sel_start = 0;
offset += 8;
}
}
}
- /*---------------------------------------------End of---filling the nr_gap_ack blocks----------------------------------------------------*/
-
/* now we must add any dups we are going to report. */
if ((limit_reached == 0) && (asoc->numduptsns)) {
dup = (uint32_t *) gap_descriptor;
@@ -10530,21 +10257,35 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
* now that the chunk is prepared queue it to the control chunk
* queue.
*/
- if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
- num_nr_gap_blocks = num_gap_blocks;
- num_gap_blocks = 0;
- }
- a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
- (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
- num_dups * sizeof(int32_t);
-
- SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
- nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
- nr_sack->nr_sack.num_nr_gap_ack_blks = htons(num_nr_gap_blocks);
- nr_sack->nr_sack.num_dup_tsns = htons(num_dups);
- nr_sack->nr_sack.reserved = htons(reserved);
- nr_sack->ch.chunk_length = htons(a_chk->send_size);
+ if (type == SCTP_SELECTIVE_ACK) {
+ a_chk->send_size = sizeof(struct sctp_sack_chunk) +
+ (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
+ num_dups * sizeof(int32_t);
+ SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
+ sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
+ sack->sack.a_rwnd = htonl(asoc->my_rwnd);
+ sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
+ sack->sack.num_dup_tsns = htons(num_dups);
+ sack->ch.chunk_type = type;
+ sack->ch.chunk_flags = flags;
+ sack->ch.chunk_length = htons(a_chk->send_size);
+ } else {
+ a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
+ (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
+ num_dups * sizeof(int32_t);
+ SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
+ nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
+ nr_sack->nr_sack.a_rwnd = htonl(asoc->my_rwnd);
+ nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
+ nr_sack->nr_sack.num_nr_gap_ack_blks = htons(num_nr_gap_blocks);
+ nr_sack->nr_sack.num_dup_tsns = htons(num_dups);
+ nr_sack->nr_sack.reserved = 0;
+ nr_sack->ch.chunk_type = type;
+ nr_sack->ch.chunk_flags = flags;
+ nr_sack->ch.chunk_length = htons(a_chk->send_size);
+ }
TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
+ asoc->my_last_reported_rwnd = asoc->my_rwnd;
asoc->ctrl_queue_cnt++;
asoc->send_sack = 0;
SCTP_STAT_INCR(sctps_sendsacks);
@@ -10801,7 +10542,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
SCTP_ENABLE_UDP_CSUM(mout);
} else {
mout->m_pkthdr.csum_flags = CSUM_SCTP;
- mout->m_pkthdr.csum_data = 0; /* FIXME MT */
+ mout->m_pkthdr.csum_data = 0;
SCTP_STAT_INCR(sctps_sendhwcrc);
}
SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
@@ -10825,14 +10566,29 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
sctp_packet_log(mout, mlen);
#endif
- comp_cp->sh.checksum = sctp_calculate_cksum(mout, offset_out);
- SCTP_STAT_INCR(sctps_sendswcrc);
SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
if (port) {
- if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr),
- sizeof(struct sctp_shutdown_complete_msg) + sizeof(struct udphdr))) == 0) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ comp_cp->sh.checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
+ if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), mlen - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ mout->m_pkthdr.csum_flags = CSUM_SCTP;
+ mout->m_pkthdr.csum_data = 0;
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
@@ -11852,7 +11608,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
SCTP_ENABLE_UDP_CSUM(o_pak);
} else {
mout->m_pkthdr.csum_flags = CSUM_SCTP;
- mout->m_pkthdr.csum_data = 0; /* FIXME MT */
+ mout->m_pkthdr.csum_data = 0;
SCTP_STAT_INCR(sctps_sendhwcrc);
}
SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
@@ -11880,13 +11636,29 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
sctp_packet_log(mout, len);
#endif
- abm->sh.checksum = sctp_calculate_cksum(mout, iphlen_out);
- SCTP_STAT_INCR(sctps_sendswcrc);
SCTP_ATTACH_CHAIN(o_pak, mout, len);
if (port) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ abm->sh.checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ mout->m_pkthdr.csum_flags = CSUM_SCTP;
+ mout->m_pkthdr.csum_data = 0;
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
@@ -12074,7 +11846,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
SCTP_ENABLE_UDP_CSUM(o_pak);
} else {
mout->m_pkthdr.csum_flags = CSUM_SCTP;
- mout->m_pkthdr.csum_data = 0; /* FIXME MT */
+ mout->m_pkthdr.csum_data = 0;
SCTP_STAT_INCR(sctps_sendhwcrc);
}
SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
@@ -12100,13 +11872,29 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
sctp_packet_log(mout, len);
#endif
- sh_out->checksum = sctp_calculate_cksum(mout, iphlen_out);
- SCTP_STAT_INCR(sctps_sendswcrc);
SCTP_ATTACH_CHAIN(o_pak, mout, len);
if (port) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sh_out->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ mout->m_pkthdr.csum_flags = CSUM_SCTP;
+ mout->m_pkthdr.csum_data = 0;
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
@@ -12598,7 +12386,7 @@ sctp_lower_sosend(struct socket *so,
panic("Error, should hold create lock and I don't?");
}
#endif
- stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id,
+ stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
p
);
if (stcb == NULL) {
diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
index bd40a0b..6488b1c 100644
--- a/sys/netinet/sctp_output.h
+++ b/sys/netinet/sctp_output.h
@@ -155,9 +155,6 @@ void send_forward_tsn(struct sctp_tcb *, struct sctp_association *);
void sctp_send_sack(struct sctp_tcb *);
-/* EY 05/07/08 if nr_sacks used, the following function will be called instead of sctp_send_sack */
-void sctp_send_nr_sack(struct sctp_tcb *);
-
int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *);
void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t);
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 73e7991..273a4a7 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -3960,7 +3960,7 @@ try_again:
*/
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
- int for_a_init, int *error, uint32_t override_tag, uint32_t vrf_id,
+ int *error, uint32_t override_tag, uint32_t vrf_id,
struct thread *p
)
{
@@ -4080,7 +4080,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
/* setup back pointer's */
stcb->sctp_ep = inp;
stcb->sctp_socket = inp->sctp_socket;
- if ((err = sctp_init_asoc(inp, stcb, for_a_init, override_tag, vrf_id))) {
+ if ((err = sctp_init_asoc(inp, stcb, override_tag, vrf_id))) {
/* failed */
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
@@ -4681,7 +4681,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
inp->sctp_lport, stcb->rport);
/*
- * Now restop the timers to be sure - this is paranoia at is finest!
+ * Now restop the timers to be sure this is paranoia at is finest!
*/
(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
(void)SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
@@ -5425,8 +5425,13 @@ sctp_pcb_init()
bzero(&SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
#endif
(void)SCTP_GETTIME_TIMEVAL(&tv);
+#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+ SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_sec = (uint32_t) tv.tv_sec;
+ SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_usec = (uint32_t) tv.tv_usec;
+#else
SCTP_BASE_STAT(sctps_discontinuitytime).tv_sec = (uint32_t) tv.tv_sec;
SCTP_BASE_STAT(sctps_discontinuitytime).tv_usec = (uint32_t) tv.tv_usec;
+#endif
/* init the empty list of (All) Endpoints */
LIST_INIT(&SCTP_BASE_INFO(listhead));
@@ -6417,9 +6422,11 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
*/
struct sctp_association *asoc;
struct sctp_tmit_chunk *chk, *nchk;
- uint32_t cumulative_tsn_p1, tsn;
+ uint32_t cumulative_tsn_p1;
struct sctp_queued_to_read *ctl, *nctl;
- int cnt, strmat, gap;
+ int cnt, strmat;
+ uint32_t gap, i;
+ int fnd = 0;
/* We look for anything larger than the cum-ack + 1 */
@@ -6440,13 +6447,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
cumulative_tsn_p1, MAX_TSN)) {
/* Yep it is above cum-ack */
cnt++;
- tsn = chk->rec.data.TSN_seq;
- if (tsn >= asoc->mapping_array_base_tsn) {
- gap = tsn - asoc->mapping_array_base_tsn;
- } else {
- gap = (MAX_TSN - asoc->mapping_array_base_tsn) +
- tsn + 1;
- }
+ SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
sctp_ucount_decr(asoc->cnt_on_reasm_queue);
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
@@ -6468,22 +6469,11 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
cumulative_tsn_p1, MAX_TSN)) {
/* Yep it is above cum-ack */
cnt++;
- tsn = ctl->sinfo_tsn;
- if (tsn >= asoc->mapping_array_base_tsn) {
- gap = tsn -
- asoc->mapping_array_base_tsn;
- } else {
- gap = (MAX_TSN -
- asoc->mapping_array_base_tsn) +
- tsn + 1;
- }
+ SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
sctp_ucount_decr(asoc->cnt_on_all_streams);
-
- SCTP_UNSET_TSN_PRESENT(asoc->mapping_array,
- gap);
- TAILQ_REMOVE(&asoc->strmin[strmat].inqueue,
- ctl, next);
+ SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
+ TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, ctl, next);
if (ctl->data) {
sctp_m_freem(ctl->data);
ctl->data = NULL;
@@ -6495,69 +6485,44 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
ctl = nctl;
}
}
- /*
- * Question, should we go through the delivery queue? The only
- * reason things are on here is the app not reading OR a p-d-api up.
- * An attacker COULD send enough in to initiate the PD-API and then
- * send a bunch of stuff to other streams... these would wind up on
- * the delivery queue.. and then we would not get to them. But in
- * order to do this I then have to back-track and un-deliver
- * sequence numbers in streams.. el-yucko. I think for now we will
- * NOT look at the delivery queue and leave it to be something to
- * consider later. An alternative would be to abort the P-D-API with
- * a notification and then deliver the data.... Or another method
- * might be to keep track of how many times the situation occurs and
- * if we see a possible attack underway just abort the association.
- */
-#ifdef SCTP_DEBUG
if (cnt) {
+ /* We must back down to see what the new highest is */
+ for (i = asoc->highest_tsn_inside_map;
+ (compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN) || (i == asoc->mapping_array_base_tsn));
+ i--) {
+ SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
+ if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
+ asoc->highest_tsn_inside_map = i;
+ fnd = 1;
+ break;
+ }
+ }
+ if (!fnd) {
+ asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
+ }
+ /*
+ * Question, should we go through the delivery queue? The
+ * only reason things are on here is the app not reading OR
+ * a p-d-api up. An attacker COULD send enough in to
+ * initiate the PD-API and then send a bunch of stuff to
+ * other streams... these would wind up on the delivery
+ * queue.. and then we would not get to them. But in order
+ * to do this I then have to back-track and un-deliver
+ * sequence numbers in streams.. el-yucko. I think for now
+ * we will NOT look at the delivery queue and leave it to be
+ * something to consider later. An alternative would be to
+ * abort the P-D-API with a notification and then deliver
+ * the data.... Or another method might be to keep track of
+ * how many times the situation occurs and if we see a
+ * possible attack underway just abort the association.
+ */
+#ifdef SCTP_DEBUG
SCTPDBG(SCTP_DEBUG_PCB1, "Freed %d chunks from reneg harvest\n", cnt);
- }
#endif
- if (cnt) {
/*
* Now do we need to find a new
* asoc->highest_tsn_inside_map?
*/
- if (asoc->highest_tsn_inside_map >= asoc->mapping_array_base_tsn) {
- gap = asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn;
- } else {
- gap = (MAX_TSN - asoc->mapping_array_base_tsn) +
- asoc->highest_tsn_inside_map + 1;
- }
- if (gap >= (asoc->mapping_array_size << 3)) {
- /*
- * Something bad happened or cum-ack and high were
- * behind the base, but if so earlier checks should
- * have found NO data... wierd... we will start at
- * end of mapping array.
- */
- SCTP_PRINTF("Gap was larger than array?? %d set to max:%d maparraymax:%x\n",
- (int)gap,
- (int)(asoc->mapping_array_size << 3),
- (int)asoc->highest_tsn_inside_map);
- gap = asoc->mapping_array_size << 3;
- }
- while (gap > 0) {
- if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
- /* found the new highest */
- asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn + gap;
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(0, 8, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
- }
- break;
- }
- gap--;
- }
- if (gap == 0) {
- /* Nothing left in map */
- memset(asoc->mapping_array, 0, asoc->mapping_array_size);
- asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
- asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
- sctp_log_map(0, 9, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
- }
- }
asoc->last_revoke_count = cnt;
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
/* sa_ignore NO_NULL_CHK */
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index d9e1db6..1a468f8 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -246,7 +246,11 @@ struct sctp_base_info {
* All static structures that anchor the system must be here.
*/
struct sctp_epinfo sctppcbinfo;
+#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+ struct sctpstat sctpstat[MAXCPU];
+#else
struct sctpstat sctpstat;
+#endif
struct sctp_sysctl sctpsysctl;
uint8_t first_time;
char sctp_pcb_initialized;
@@ -560,7 +564,7 @@ void sctp_inpcb_free(struct sctp_inpcb *, int, int);
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
- int, int *, uint32_t, uint32_t, struct thread *);
+ int *, uint32_t, uint32_t, struct thread *);
int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index 9b952fd..cd798b5 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -477,7 +477,6 @@ struct sctp_asconf_addr {
struct sctp_ifa *ifa; /* save the ifa for add/del ip */
uint8_t sent; /* has this been sent yet? */
uint8_t special_del; /* not to be used in lookup */
-
};
struct sctp_scoping {
@@ -771,9 +770,7 @@ struct sctp_association {
/* EY - new NR variables used for nr_sack based on mapping_array */
uint8_t *nr_mapping_array;
- uint32_t nr_mapping_array_base_tsn;
uint32_t highest_tsn_inside_nr_map;
- uint16_t nr_mapping_array_size;
uint32_t last_echo_tsn;
uint32_t last_cwr_tsn;
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index b4023c6..c9967ea 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_pcb.h>
#include <netinet/sctputil.h>
#include <netinet/sctp_output.h>
+#include <sys/smp.h>
/*
* sysctl tunable variables
@@ -627,7 +628,158 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
return (error);
}
+#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+static int
+sysctl_stat_get(SYSCTL_HANDLER_ARGS)
+{
+ int cpu, error;
+ struct sctpstat sb, *sarry;
+
+ memset(&sb, 0, sizeof(sb));
+ for (cpu = 0; cpu < mp_ncpus; cpu++) {
+ sarry = &SCTP_BASE_STATS[cpu];
+ if (sarry->sctps_discontinuitytime.tv_sec > sb.sctps_discontinuitytime.tv_sec) {
+ sb.sctps_discontinuitytime.tv_sec = sarry->sctps_discontinuitytime.tv_sec;
+ sb.sctps_discontinuitytime.tv_usec = sarry->sctps_discontinuitytime.tv_usec;
+ }
+ sb.sctps_currestab += sarry->sctps_currestab;
+ sb.sctps_activeestab += sarry->sctps_activeestab;
+ sb.sctps_restartestab += sarry->sctps_restartestab;
+ sb.sctps_collisionestab += sarry->sctps_collisionestab;
+ sb.sctps_passiveestab += sarry->sctps_passiveestab;
+ sb.sctps_aborted += sarry->sctps_aborted;
+ sb.sctps_shutdown += sarry->sctps_shutdown;
+ sb.sctps_outoftheblue += sarry->sctps_outoftheblue;
+ sb.sctps_checksumerrors += sarry->sctps_checksumerrors;
+ sb.sctps_outcontrolchunks += sarry->sctps_outcontrolchunks;
+ sb.sctps_outorderchunks += sarry->sctps_outorderchunks;
+ sb.sctps_outunorderchunks += sarry->sctps_outunorderchunks;
+ sb.sctps_incontrolchunks += sarry->sctps_incontrolchunks;
+ sb.sctps_inorderchunks += sarry->sctps_inorderchunks;
+ sb.sctps_inunorderchunks += sarry->sctps_inunorderchunks;
+ sb.sctps_fragusrmsgs += sarry->sctps_fragusrmsgs;
+ sb.sctps_reasmusrmsgs += sarry->sctps_reasmusrmsgs;
+ sb.sctps_outpackets += sarry->sctps_outpackets;
+ sb.sctps_inpackets += sarry->sctps_inpackets;
+ sb.sctps_recvpackets += sarry->sctps_recvpackets;
+ sb.sctps_recvdatagrams += sarry->sctps_recvdatagrams;
+ sb.sctps_recvpktwithdata += sarry->sctps_recvpktwithdata;
+ sb.sctps_recvsacks += sarry->sctps_recvsacks;
+ sb.sctps_recvdata += sarry->sctps_recvdata;
+ sb.sctps_recvdupdata += sarry->sctps_recvdupdata;
+ sb.sctps_recvheartbeat += sarry->sctps_recvheartbeat;
+ sb.sctps_recvheartbeatack += sarry->sctps_recvheartbeatack;
+ sb.sctps_recvecne += sarry->sctps_recvecne;
+ sb.sctps_recvauth += sarry->sctps_recvauth;
+ sb.sctps_recvauthmissing += sarry->sctps_recvauthmissing;
+ sb.sctps_recvivalhmacid += sarry->sctps_recvivalhmacid;
+ sb.sctps_recvivalkeyid += sarry->sctps_recvivalkeyid;
+ sb.sctps_recvauthfailed += sarry->sctps_recvauthfailed;
+ sb.sctps_recvexpress += sarry->sctps_recvexpress;
+ sb.sctps_recvexpressm += sarry->sctps_recvexpressm;
+ sb.sctps_recvnocrc += sarry->sctps_recvnocrc;
+ sb.sctps_recvswcrc += sarry->sctps_recvswcrc;
+ sb.sctps_recvhwcrc += sarry->sctps_recvhwcrc;
+ sb.sctps_sendpackets += sarry->sctps_sendpackets;
+ sb.sctps_sendsacks += sarry->sctps_sendsacks;
+ sb.sctps_senddata += sarry->sctps_senddata;
+ sb.sctps_sendretransdata += sarry->sctps_sendretransdata;
+ sb.sctps_sendfastretrans += sarry->sctps_sendfastretrans;
+ sb.sctps_sendmultfastretrans += sarry->sctps_sendmultfastretrans;
+ sb.sctps_sendheartbeat += sarry->sctps_sendheartbeat;
+ sb.sctps_sendecne += sarry->sctps_sendecne;
+ sb.sctps_sendauth += sarry->sctps_sendauth;
+ sb.sctps_senderrors += sarry->sctps_senderrors;
+ sb.sctps_sendnocrc += sarry->sctps_sendnocrc;
+ sb.sctps_sendswcrc += sarry->sctps_sendswcrc;
+ sb.sctps_sendhwcrc += sarry->sctps_sendhwcrc;
+ sb.sctps_pdrpfmbox += sarry->sctps_pdrpfmbox;
+ sb.sctps_pdrpfehos += sarry->sctps_pdrpfehos;
+ sb.sctps_pdrpmbda += sarry->sctps_pdrpmbda;
+ sb.sctps_pdrpmbct += sarry->sctps_pdrpmbct;
+ sb.sctps_pdrpbwrpt += sarry->sctps_pdrpbwrpt;
+ sb.sctps_pdrpcrupt += sarry->sctps_pdrpcrupt;
+ sb.sctps_pdrpnedat += sarry->sctps_pdrpnedat;
+ sb.sctps_pdrppdbrk += sarry->sctps_pdrppdbrk;
+ sb.sctps_pdrptsnnf += sarry->sctps_pdrptsnnf;
+ sb.sctps_pdrpdnfnd += sarry->sctps_pdrpdnfnd;
+ sb.sctps_pdrpdiwnp += sarry->sctps_pdrpdiwnp;
+ sb.sctps_pdrpdizrw += sarry->sctps_pdrpdizrw;
+ sb.sctps_pdrpbadd += sarry->sctps_pdrpbadd;
+ sb.sctps_pdrpmark += sarry->sctps_pdrpmark;
+ sb.sctps_timoiterator += sarry->sctps_timoiterator;
+ sb.sctps_timodata += sarry->sctps_timodata;
+ sb.sctps_timowindowprobe += sarry->sctps_timowindowprobe;
+ sb.sctps_timoinit += sarry->sctps_timoinit;
+ sb.sctps_timosack += sarry->sctps_timosack;
+ sb.sctps_timoshutdown += sarry->sctps_timoshutdown;
+ sb.sctps_timoheartbeat += sarry->sctps_timoheartbeat;
+ sb.sctps_timocookie += sarry->sctps_timocookie;
+ sb.sctps_timosecret += sarry->sctps_timosecret;
+ sb.sctps_timopathmtu += sarry->sctps_timopathmtu;
+ sb.sctps_timoshutdownack += sarry->sctps_timoshutdownack;
+ sb.sctps_timoshutdownguard += sarry->sctps_timoshutdownguard;
+ sb.sctps_timostrmrst += sarry->sctps_timostrmrst;
+ sb.sctps_timoearlyfr += sarry->sctps_timoearlyfr;
+ sb.sctps_timoasconf += sarry->sctps_timoasconf;
+ sb.sctps_timodelprim += sarry->sctps_timodelprim;
+ sb.sctps_timoautoclose += sarry->sctps_timoautoclose;
+ sb.sctps_timoassockill += sarry->sctps_timoassockill;
+ sb.sctps_timoinpkill += sarry->sctps_timoinpkill;
+ sb.sctps_earlyfrstart += sarry->sctps_earlyfrstart;
+ sb.sctps_earlyfrstop += sarry->sctps_earlyfrstop;
+ sb.sctps_earlyfrmrkretrans += sarry->sctps_earlyfrmrkretrans;
+ sb.sctps_earlyfrstpout += sarry->sctps_earlyfrstpout;
+ sb.sctps_earlyfrstpidsck1 += sarry->sctps_earlyfrstpidsck1;
+ sb.sctps_earlyfrstpidsck2 += sarry->sctps_earlyfrstpidsck2;
+ sb.sctps_earlyfrstpidsck3 += sarry->sctps_earlyfrstpidsck3;
+ sb.sctps_earlyfrstpidsck4 += sarry->sctps_earlyfrstpidsck4;
+ sb.sctps_earlyfrstrid += sarry->sctps_earlyfrstrid;
+ sb.sctps_earlyfrstrout += sarry->sctps_earlyfrstrout;
+ sb.sctps_earlyfrstrtmr += sarry->sctps_earlyfrstrtmr;
+ sb.sctps_hdrops += sarry->sctps_hdrops;
+ sb.sctps_badsum += sarry->sctps_badsum;
+ sb.sctps_noport += sarry->sctps_noport;
+ sb.sctps_badvtag += sarry->sctps_badvtag;
+ sb.sctps_badsid += sarry->sctps_badsid;
+ sb.sctps_nomem += sarry->sctps_nomem;
+ sb.sctps_fastretransinrtt += sarry->sctps_fastretransinrtt;
+ sb.sctps_markedretrans += sarry->sctps_markedretrans;
+ sb.sctps_naglesent += sarry->sctps_naglesent;
+ sb.sctps_naglequeued += sarry->sctps_naglequeued;
+ sb.sctps_maxburstqueued += sarry->sctps_maxburstqueued;
+ sb.sctps_ifnomemqueued += sarry->sctps_ifnomemqueued;
+ sb.sctps_windowprobed += sarry->sctps_windowprobed;
+ sb.sctps_lowlevelerr += sarry->sctps_lowlevelerr;
+ sb.sctps_lowlevelerrusr += sarry->sctps_lowlevelerrusr;
+ sb.sctps_datadropchklmt += sarry->sctps_datadropchklmt;
+ sb.sctps_datadroprwnd += sarry->sctps_datadroprwnd;
+ sb.sctps_ecnereducedcwnd += sarry->sctps_ecnereducedcwnd;
+ sb.sctps_vtagexpress += sarry->sctps_vtagexpress;
+ sb.sctps_vtagbogus += sarry->sctps_vtagbogus;
+ sb.sctps_primary_randry += sarry->sctps_primary_randry;
+ sb.sctps_cmt_randry += sarry->sctps_cmt_randry;
+ sb.sctps_slowpath_sack += sarry->sctps_slowpath_sack;
+ sb.sctps_wu_sacks_sent += sarry->sctps_wu_sacks_sent;
+ sb.sctps_sends_with_flags += sarry->sctps_sends_with_flags;
+ sb.sctps_sends_with_unord += sarry->sctps_sends_with_unord;
+ sb.sctps_sends_with_eof += sarry->sctps_sends_with_eof;
+ sb.sctps_sends_with_abort += sarry->sctps_sends_with_abort;
+ sb.sctps_protocol_drain_calls += sarry->sctps_protocol_drain_calls;
+ sb.sctps_protocol_drains_done += sarry->sctps_protocol_drains_done;
+ sb.sctps_read_peeks += sarry->sctps_read_peeks;
+ sb.sctps_cached_chk += sarry->sctps_cached_chk;
+ sb.sctps_cached_strmoq += sarry->sctps_cached_strmoq;
+ sb.sctps_left_abandon += sarry->sctps_left_abandon;
+ sb.sctps_send_burst_avoid += sarry->sctps_send_burst_avoid;
+ sb.sctps_send_cwnd_avoid += sarry->sctps_send_cwnd_avoid;
+ sb.sctps_fwdtsn_map_over += sarry->sctps_fwdtsn_map_over;
+ }
+ error = SYSCTL_OUT(req, &sb, sizeof(sb));
+ return (error);
+}
+#endif
#if defined(SCTP_LOCAL_TRACE_BUF)
static int
@@ -916,10 +1068,16 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_INT | CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_output_unlocked), 0, sysctl_sctp_check, "IU",
SCTPCTL_OUTPUT_UNLOCKED_DESC);
#endif
-
+#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats,
+ CTLTYPE_STRUCT | CTLFLAG_RD,
+ 0, 0, sysctl_stat_get, "S,sctpstat",
+ "SCTP statistics (struct sctp_stat)");
+#else
SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
&SCTP_BASE_STATS_SYSCTL, sctpstat,
"SCTP statistics (struct sctp_stat)");
+#endif
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
0, 0, sctp_assoclist,
diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
index 1908930..e3fbc3e 100644
--- a/sys/netinet/sctp_uio.h
+++ b/sys/netinet/sctp_uio.h
@@ -957,9 +957,13 @@ struct sctpstat {
#define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1)
#define SCTP_STAT_DECR(_x) SCTP_STAT_DECR_BY(_x,1)
+#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+#define SCTP_STAT_INCR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x += _d)
+#define SCTP_STAT_DECR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x -= _d)
+#else
#define SCTP_STAT_INCR_BY(_x,_d) atomic_add_int(&SCTP_BASE_STAT(_x), _d)
#define SCTP_STAT_DECR_BY(_x,_d) atomic_subtract_int(&SCTP_BASE_STAT(_x), _d)
-
+#endif
/* The following macros are for handling MIB values, */
#define SCTP_STAT_INCR_COUNTER32(_x) SCTP_STAT_INCR(_x)
#define SCTP_STAT_INCR_COUNTER64(_x) SCTP_STAT_INCR(_x)
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 2851272..fc6a4ac 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -1492,7 +1492,7 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
/* We are GOOD to go */
- stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id,
+ stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id,
(struct thread *)p
);
if (stcb == NULL) {
@@ -4459,7 +4459,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
}
vrf_id = inp->def_vrf_id;
/* We are GOOD to go */
- stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id, p);
+ stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p);
if (stcb == NULL) {
/* Gak! no memory */
goto out_now;
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index 1ccccf3..bff7f5d 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -108,7 +108,7 @@ extern struct pr_usrreqs sctp_usrreqs;
sctp_auth_key_release((_stcb), (_chk)->auth_keyid); \
(_chk)->holds_key_ref = 0; \
} \
- if(_stcb) { \
+ if (_stcb) { \
SCTP_TCB_LOCK_ASSERT((_stcb)); \
if ((_chk)->whoTo) { \
sctp_free_remote_addr((_chk)->whoTo); \
@@ -231,7 +231,7 @@ extern struct pr_usrreqs sctp_usrreqs;
#ifdef SCTP_FS_SPEC_LOG
#define sctp_total_flight_decrease(stcb, tp1) do { \
- if(stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
+ if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
stcb->asoc.fs_index = 0;\
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
@@ -252,7 +252,7 @@ extern struct pr_usrreqs sctp_usrreqs;
} while (0)
#define sctp_total_flight_increase(stcb, tp1) do { \
- if(stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
+ if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
stcb->asoc.fs_index = 0;\
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 658dc55..04f7673 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -52,9 +52,15 @@ __FBSDID("$FreeBSD$");
#define NUMBER_OF_MTU_SIZES 18
+#if defined(__Windows__) && !defined(SCTP_LOCAL_TRACE_BUF)
+#include "eventrace_netinet.h"
+#include "sctputil.tmh" /* this is the file that will be auto
+ * generated */
+#else
#ifndef KTR_SCTP
#define KTR_SCTP KTR_SUBSYS
#endif
+#endif
void
sctp_sblog(struct sockbuf *sb,
@@ -668,7 +674,7 @@ sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_audit_indx = 0;
}
rep = 1;
- SCTP_PRINTF("tot_flt_book:%d\n", tot_book);
+ SCTP_PRINTF("tot_flt_book:%d\n", tot_book_cnt);
stcb->asoc.total_flight_count = tot_book_cnt;
}
@@ -697,8 +703,8 @@ sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
if (lnet->flight_size != tot_out) {
- SCTP_PRINTF("net:%x flight was %d corrected to %d\n",
- (uint32_t) lnet, lnet->flight_size,
+ SCTP_PRINTF("net:%p flight was %d corrected to %d\n",
+ lnet, lnet->flight_size,
tot_out);
lnet->flight_size = tot_out;
}
@@ -869,7 +875,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int sa
int
sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
- int for_a_init, uint32_t override_tag, uint32_t vrf_id)
+ uint32_t override_tag, uint32_t vrf_id)
{
struct sctp_association *asoc;
@@ -1132,9 +1138,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
return (ENOMEM);
}
memset(asoc->mapping_array, 0, asoc->mapping_array_size);
- /* EY - initialize the nr_mapping_array just like mapping array */
- asoc->nr_mapping_array_size = SCTP_INITIAL_NR_MAPPING_ARRAY;
- SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->nr_mapping_array_size,
+ SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size,
SCTP_M_MAP);
if (asoc->nr_mapping_array == NULL) {
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
@@ -1142,7 +1146,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
return (ENOMEM);
}
- memset(asoc->nr_mapping_array, 0, asoc->nr_mapping_array_size);
+ memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
/* Now the init of the other outqueues */
TAILQ_INIT(&asoc->free_chunks);
@@ -1175,46 +1179,78 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
asoc->discontinuity_time = asoc->start_time;
/*
* sa_ignore MEMLEAK {memory is put in the assoc mapping array and
- * freed later whe the association is freed.
+ * freed later when the association is freed.
*/
return (0);
}
+void
+sctp_print_mapping_array(struct sctp_association *asoc)
+{
+ unsigned int i, limit;
+
+ printf("Mapping array size: %d, baseTSN: %8.8x, cumAck: %8.8x, highestTSN: (%8.8x, %8.8x).\n",
+ asoc->mapping_array_size,
+ asoc->mapping_array_base_tsn,
+ asoc->cumulative_tsn,
+ asoc->highest_tsn_inside_map,
+ asoc->highest_tsn_inside_nr_map);
+ for (limit = asoc->mapping_array_size; limit > 1; limit--) {
+ if (asoc->mapping_array[limit - 1]) {
+ break;
+ }
+ }
+ printf("Renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
+ for (i = 0; i < limit; i++) {
+ printf("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
+ if (((i + 1) % 16) == 0)
+ printf("\n");
+ }
+ if (limit % 16)
+ printf("\n");
+ for (limit = asoc->mapping_array_size; limit > 1; limit--) {
+ if (asoc->nr_mapping_array[limit - 1]) {
+ break;
+ }
+ }
+ printf("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
+ for (i = 0; i < limit; i++) {
+ printf("%2.2x%c", asoc->nr_mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
+ }
+ if (limit % 16)
+ printf("\n");
+}
+
int
sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
{
/* mapping array needs to grow */
- uint8_t *new_array;
+ uint8_t *new_array1, *new_array2;
uint32_t new_size;
new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
- SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
- if (new_array == NULL) {
+ SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
+ SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
+ if ((new_array1 == NULL) || (new_array2 == NULL)) {
/* can't get more, forget it */
- SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
- new_size);
+ SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size);
+ if (new_array1) {
+ SCTP_FREE(new_array1, SCTP_M_MAP);
+ }
+ if (new_array2) {
+ SCTP_FREE(new_array2, SCTP_M_MAP);
+ }
return (-1);
}
- memset(new_array, 0, new_size);
- memcpy(new_array, asoc->mapping_array, asoc->mapping_array_size);
+ memset(new_array1, 0, new_size);
+ memset(new_array2, 0, new_size);
+ memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size);
+ memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size);
SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
- asoc->mapping_array = new_array;
+ SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
+ asoc->mapping_array = new_array1;
+ asoc->nr_mapping_array = new_array2;
asoc->mapping_array_size = new_size;
- if (asoc->peer_supports_nr_sack) {
- new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
- SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
- if (new_array == NULL) {
- /* can't get more, forget it */
- SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
- new_size);
- return (-1);
- }
- memset(new_array, 0, new_size);
- memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
- SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
- asoc->nr_mapping_array = new_array;
- asoc->nr_mapping_array_size = new_size;
- }
return (0);
}
@@ -1635,21 +1671,9 @@ sctp_timeout_handler(void *t)
if ((stcb == NULL) || (inp == NULL)) {
break;
} {
- int abort_flag;
-
SCTP_STAT_INCR(sctps_timosack);
stcb->asoc.timosack++;
- if (stcb->asoc.cumulative_tsn != stcb->asoc.highest_tsn_inside_map)
- sctp_sack_check(stcb, 0, 0, &abort_flag);
-
- /*
- * EY if nr_sacks used then send an nr-sack , a sack
- * otherwise
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
- sctp_send_nr_sack(stcb);
- else
- sctp_send_sack(stcb);
+ sctp_send_sack(stcb);
}
#ifdef SCTP_AUDITING_ENABLED
sctp_auditing(4, inp, stcb, net);
@@ -4709,8 +4733,7 @@ next_on_sent:
*/
if ((tp1) &&
(tp1->rec.data.stream_number == stream) &&
- (tp1->rec.data.stream_seq == seq)
- ) {
+ (tp1->rec.data.stream_seq == seq)) {
/*
* save to chk in case we have some on stream out
* queue. If so and we have an un-transmitted one we
@@ -5053,14 +5076,7 @@ sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t * freed_so_far, int hold_rlock,
goto out;
}
SCTP_STAT_INCR(sctps_wu_sacks_sent);
- /*
- * EY if nr_sacks used then send an nr-sack , a sack
- * otherwise
- */
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
- sctp_send_nr_sack(stcb);
- else
- sctp_send_sack(stcb);
+ sctp_send_sack(stcb);
sctp_chunk_output(stcb->sctp_ep, stcb,
SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
@@ -5430,8 +5446,7 @@ restart_nosblocks:
((ctl->some_taken) ||
((ctl->do_not_ref_stcb == 0) &&
((ctl->spec_flags & M_NOTIFICATION) == 0) &&
- (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
- ) {
+ (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) {
/*-
* If we have the same tcb, and there is data present, and we
* have the strm interleave feature present. Then if we have
@@ -5890,8 +5905,7 @@ wait_some_more:
hold_sblock = 1;
}
if ((copied_so_far) && (control->length == 0) &&
- (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))
- ) {
+ (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
goto release;
}
if (so->so_rcv.sb_cc <= control->held_length) {
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index f3a731e..dfd552a 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -81,7 +81,7 @@ uint32_t sctp_select_initial_TSN(struct sctp_pcb *);
uint32_t sctp_select_a_tag(struct sctp_inpcb *, uint16_t lport, uint16_t rport, int);
-int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, int, uint32_t, uint32_t);
+int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t);
void sctp_fill_random_store(struct sctp_pcb *);
@@ -169,8 +169,6 @@ sctp_report_all_outbound(struct sctp_tcb *, int, int
int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
-/* EY nr_sack version of the above method, expands nr_mapping_array */
-int sctp_expand_nr_mapping_array(struct sctp_association *, uint32_t);
void
sctp_abort_notification(struct sctp_tcb *, int, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
@@ -376,7 +374,7 @@ int sctp_fill_stat_log(void *, size_t *);
void sctp_log_fr(uint32_t, uint32_t, uint32_t, int);
void sctp_log_sack(uint32_t, uint32_t, uint32_t, uint16_t, uint16_t, int);
void sctp_log_map(uint32_t, uint32_t, uint32_t, int);
-
+void sctp_print_mapping_array(struct sctp_association *asoc);
void sctp_clr_stat_log(void);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 09f834b..0254cff 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -632,7 +632,7 @@ relocked:
("%s: INP_TIMEWAIT ti_locked %d", __func__, ti_locked));
if (ti_locked == TI_RLOCKED) {
- if (rw_try_upgrade(&V_tcbinfo.ipi_lock) == 0) {
+ if (INP_INFO_TRY_UPGRADE(&V_tcbinfo) == 0) {
in_pcbref(inp);
INP_WUNLOCK(inp);
INP_INFO_RUNLOCK(&V_tcbinfo);
@@ -683,7 +683,7 @@ relocked:
("%s: upgrade check ti_locked %d", __func__, ti_locked));
if (ti_locked == TI_RLOCKED) {
- if (rw_try_upgrade(&V_tcbinfo.ipi_lock) == 0) {
+ if (INP_INFO_TRY_UPGRADE(&V_tcbinfo) == 0) {
in_pcbref(inp);
INP_WUNLOCK(inp);
INP_INFO_RUNLOCK(&V_tcbinfo);
@@ -1134,6 +1134,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* TCP ECN processing.
*/
if (tp->t_flags & TF_ECN_PERMIT) {
+ if (thflags & TH_CWR)
+ tp->t_flags &= ~TF_ECN_SND_ECE;
switch (iptos & IPTOS_ECN_MASK) {
case IPTOS_ECN_CE:
tp->t_flags |= TF_ECN_SND_ECE;
@@ -1146,10 +1148,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
TCPSTAT_INC(tcps_ecn_ect1);
break;
}
-
- if (thflags & TH_CWR)
- tp->t_flags &= ~TF_ECN_SND_ECE;
-
/*
* Congestion experienced.
* Ignore if we are already trying to recover.
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index ebe5e36..f9d1b63 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1048,7 +1048,7 @@ send:
* XXX: Fixme: This is currently not the case for IPv6.
*/
if (tso) {
- m->m_pkthdr.csum_flags = CSUM_TSO;
+ m->m_pkthdr.csum_flags |= CSUM_TSO;
m->m_pkthdr.tso_segsz = tp->t_maxopd - optlen;
}
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 8115b2b..cd7eb1c 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -132,6 +132,15 @@ tcp_reass_init(void)
tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY);
}
+#ifdef VIMAGE
+void
+tcp_reass_destroy(void)
+{
+
+ uma_zdestroy(V_tcp_reass_zone);
+}
+#endif
+
int
tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
{
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index d0b2e0e..9ec434c 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -376,25 +376,15 @@ tcp_init(void)
TUNABLE_INT_FETCH("net.inet.tcp.sack.enable", &V_tcp_do_sack);
- INP_INFO_LOCK_INIT(&V_tcbinfo, "tcp");
- LIST_INIT(&V_tcb);
-#ifdef VIMAGE
- V_tcbinfo.ipi_vnet = curvnet;
-#endif
- V_tcbinfo.ipi_listhead = &V_tcb;
hashsize = TCBHASHSIZE;
TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize);
if (!powerof2(hashsize)) {
printf("WARNING: TCB hash size not a power of 2\n");
hashsize = 512; /* safe default */
}
- V_tcbinfo.ipi_hashbase = hashinit(hashsize, M_PCB,
- &V_tcbinfo.ipi_hashmask);
- V_tcbinfo.ipi_porthashbase = hashinit(hashsize, M_PCB,
- &V_tcbinfo.ipi_porthashmask);
- V_tcbinfo.ipi_zone = uma_zcreate("tcp_inpcb", sizeof(struct inpcb),
- NULL, NULL, tcp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
- uma_zone_set_max(V_tcbinfo.ipi_zone, maxsockets);
+ in_pcbinfo_init(&V_tcbinfo, "tcp", &V_tcb, hashsize, hashsize,
+ "tcp_inpcb", tcp_inpcb_init, NULL, UMA_ZONE_NOFREE);
+
/*
* These have to be type stable for the benefit of the timers.
*/
@@ -459,16 +449,13 @@ void
tcp_destroy(void)
{
- tcp_tw_destroy();
+ tcp_reass_destroy();
tcp_hc_destroy();
syncache_destroy();
-
- /* XXX check that hashes are empty! */
- hashdestroy(V_tcbinfo.ipi_hashbase, M_PCB,
- V_tcbinfo.ipi_hashmask);
- hashdestroy(V_tcbinfo.ipi_porthashbase, M_PCB,
- V_tcbinfo.ipi_porthashmask);
- INP_INFO_LOCK_DESTROY(&V_tcbinfo);
+ tcp_tw_destroy();
+ in_pcbinfo_destroy(&V_tcbinfo);
+ uma_zdestroy(V_sack_hole_zone);
+ uma_zdestroy(V_tcpcb_zone);
}
#endif
@@ -835,8 +822,19 @@ tcp_discardcb(struct tcpcb *tp)
INP_WLOCK_ASSERT(inp);
/*
- * Make sure that all of our timers are stopped before we
- * delete the PCB.
+ * Make sure that all of our timers are stopped before we delete the
+ * PCB.
+ *
+ * XXXRW: Really, we would like to use callout_drain() here in order
+ * to avoid races experienced in tcp_timer.c where a timer is already
+ * executing at this point. However, we can't, both because we're
+ * running in a context where we can't sleep, and also because we
+ * hold locks required by the timers. What we instead need to do is
+ * test to see if callout_drain() is required, and if so, defer some
+ * portion of the remainder of tcp_discardcb() to an asynchronous
+ * context that can callout_drain() and then continue. Some care
+ * will be required to ensure that no further processing takes place
+ * on the tcpcb, even though it hasn't been freed (a flag?).
*/
callout_stop(&tp->t_timers->tt_rexmt);
callout_stop(&tp->t_timers->tt_persist);
@@ -1110,7 +1108,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RLOCK(&V_tcbinfo);
for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0;
inp != NULL && i < n; inp = LIST_NEXT(inp, inp_list)) {
- INP_RLOCK(inp);
+ INP_WLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
/*
* XXX: This use of cr_cansee(), introduced with
@@ -1125,10 +1123,12 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
error = EINVAL; /* Skip this inp. */
} else
error = cr_canseeinpcb(req->td->td_ucred, inp);
- if (error == 0)
+ if (error == 0) {
+ in_pcbref(inp);
inp_list[i++] = inp;
+ }
}
- INP_RUNLOCK(inp);
+ INP_WUNLOCK(inp);
}
INP_INFO_RUNLOCK(&V_tcbinfo);
n = i;
@@ -1167,8 +1167,16 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
error = SYSCTL_OUT(req, &xt, sizeof xt);
} else
INP_RUNLOCK(inp);
-
}
+ INP_INFO_WLOCK(&V_tcbinfo);
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_WLOCK(inp);
+ if (!in_pcbrele(inp))
+ INP_WUNLOCK(inp);
+ }
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+
if (!error) {
/*
* Give the user an updated idea of our state.
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 8ead3dc..65c6a3e 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/protosw.h>
+#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
@@ -117,6 +118,13 @@ int tcp_maxpersistidle;
/* max idle time in persist */
int tcp_maxidle;
+static int per_cpu_timers = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, per_cpu_timers, CTLFLAG_RW,
+ &per_cpu_timers , 0, "run tcp timers on all cpus");
+
+#define INP_CPU(inp) (per_cpu_timers ? (!CPU_ABSENT(((inp)->inp_flowid % (mp_maxid+1))) ? \
+ ((inp)->inp_flowid % (mp_maxid+1)) : curcpu) : 0)
+
/*
* Tcp protocol timeout routine called every 500 ms.
* Updates timestamps used for TCP
@@ -162,7 +170,6 @@ tcp_timer_delack(void *xtp)
struct inpcb *inp;
CURVNET_SET(tp->t_vnet);
- INP_INFO_RLOCK(&V_tcbinfo);
inp = tp->t_inpcb;
/*
* XXXRW: While this assert is in fact correct, bugs in the tcpcb
@@ -173,12 +180,10 @@ tcp_timer_delack(void *xtp)
*/
if (inp == NULL) {
tcp_timer_race++;
- INP_INFO_RUNLOCK(&V_tcbinfo);
CURVNET_RESTORE();
return;
}
INP_WLOCK(inp);
- INP_INFO_RUNLOCK(&V_tcbinfo);
if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_delack)
|| !callout_active(&tp->t_timers->tt_delack)) {
INP_WUNLOCK(inp);
@@ -251,8 +256,8 @@ tcp_timer_2msl(void *xtp)
} else {
if (tp->t_state != TCPS_TIME_WAIT &&
ticks - tp->t_rcvtime <= tcp_maxidle)
- callout_reset(&tp->t_timers->tt_2msl, tcp_keepintvl,
- tcp_timer_2msl, tp);
+ callout_reset_on(&tp->t_timers->tt_2msl, tcp_keepintvl,
+ tcp_timer_2msl, tp, INP_CPU(inp));
else
tp = tcp_close(tp);
}
@@ -335,9 +340,9 @@ tcp_timer_keep(void *xtp)
tp->rcv_nxt, tp->snd_una - 1, 0);
free(t_template, M_TEMP);
}
- callout_reset(&tp->t_timers->tt_keep, tcp_keepintvl, tcp_timer_keep, tp);
+ callout_reset_on(&tp->t_timers->tt_keep, tcp_keepintvl, tcp_timer_keep, tp, INP_CPU(inp));
} else
- callout_reset(&tp->t_timers->tt_keep, tcp_keepidle, tcp_timer_keep, tp);
+ callout_reset_on(&tp->t_timers->tt_keep, tcp_keepidle, tcp_timer_keep, tp, INP_CPU(inp));
#ifdef TCPDEBUG
if (inp->inp_socket->so_options & SO_DEBUG)
@@ -447,8 +452,7 @@ tcp_timer_rexmt(void * xtp)
ostate = tp->t_state;
#endif
- INP_INFO_WLOCK(&V_tcbinfo);
- headlocked = 1;
+ INP_INFO_RLOCK(&V_tcbinfo);
inp = tp->t_inpcb;
/*
* XXXRW: While this assert is in fact correct, bugs in the tcpcb
@@ -459,7 +463,7 @@ tcp_timer_rexmt(void * xtp)
*/
if (inp == NULL) {
tcp_timer_race++;
- INP_INFO_WUNLOCK(&V_tcbinfo);
+ INP_INFO_RUNLOCK(&V_tcbinfo);
CURVNET_RESTORE();
return;
}
@@ -467,7 +471,7 @@ tcp_timer_rexmt(void * xtp)
if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_rexmt)
|| !callout_active(&tp->t_timers->tt_rexmt)) {
INP_WUNLOCK(inp);
- INP_INFO_WUNLOCK(&V_tcbinfo);
+ INP_INFO_RUNLOCK(&V_tcbinfo);
CURVNET_RESTORE();
return;
}
@@ -481,11 +485,22 @@ tcp_timer_rexmt(void * xtp)
if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
tp->t_rxtshift = TCP_MAXRXTSHIFT;
TCPSTAT_INC(tcps_timeoutdrop);
+ in_pcbref(inp);
+ INP_INFO_RUNLOCK(&V_tcbinfo);
+ INP_WUNLOCK(inp);
+ INP_INFO_WLOCK(&V_tcbinfo);
+ INP_WLOCK(inp);
+ if (in_pcbrele(inp)) {
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ CURVNET_RESTORE();
+ return;
+ }
tp = tcp_drop(tp, tp->t_softerror ?
tp->t_softerror : ETIMEDOUT);
+ headlocked = 1;
goto out;
}
- INP_INFO_WUNLOCK(&V_tcbinfo);
+ INP_INFO_RUNLOCK(&V_tcbinfo);
headlocked = 0;
if (tp->t_rxtshift == 1) {
/*
@@ -601,6 +616,8 @@ tcp_timer_activate(struct tcpcb *tp, int timer_type, u_int delta)
{
struct callout *t_callout;
void *f_callout;
+ struct inpcb *inp = tp->t_inpcb;
+ int cpu = INP_CPU(inp);
switch (timer_type) {
case TT_DELACK:
@@ -629,7 +646,7 @@ tcp_timer_activate(struct tcpcb *tp, int timer_type, u_int delta)
if (delta == 0) {
callout_stop(t_callout);
} else {
- callout_reset(t_callout, delta, f_callout, tp);
+ callout_reset_on(t_callout, delta, f_callout, tp, cpu);
}
}
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index f755fa1..6e5b013 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -185,6 +185,8 @@ tcp_tw_destroy(void)
while((tw = TAILQ_FIRST(&V_twq_2msl)) != NULL)
tcp_twclose(tw, 0);
INP_INFO_WUNLOCK(&V_tcbinfo);
+
+ uma_zdestroy(V_tcptw_zone);
}
#endif
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index dc9f11b..2e61c31 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -560,9 +560,15 @@ out:
}
/*
- * Accept a connection. Essentially all the work is
- * done at higher levels; just return the address
- * of the peer, storing through addr.
+ * Accept a connection. Essentially all the work is done at higher levels;
+ * just return the address of the peer, storing through addr.
+ *
+ * The rationale for acquiring the tcbinfo lock here is somewhat complicated,
+ * and is described in detail in the commit log entry for r175612. Acquiring
+ * it delays an accept(2) racing with sonewconn(), which inserts the socket
+ * before the inpcb address/port fields are initialized. A better fix would
+ * prevent the socket from being placed in the listen queue until all fields
+ * are fully initialized.
*/
static int
tcp_usr_accept(struct socket *so, struct sockaddr **nam)
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 769c219..3a59eee 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -657,6 +657,9 @@ char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *,
const void *);
int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *);
void tcp_reass_init(void);
+#ifdef VIMAGE
+void tcp_reass_destroy(void);
+#endif
void tcp_input(struct mbuf *, int);
u_long tcp_maxmtu(struct in_conninfo *, int *);
u_long tcp_maxmtu6(struct in_conninfo *, int *);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 019ceb3..0d8e04d 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -180,25 +180,11 @@ udp_init(void)
{
V_udp_blackhole = 0;
-
- INP_INFO_LOCK_INIT(&V_udbinfo, "udp");
- LIST_INIT(&V_udb);
-#ifdef VIMAGE
- V_udbinfo.ipi_vnet = curvnet;
-#endif
- V_udbinfo.ipi_listhead = &V_udb;
- V_udbinfo.ipi_hashbase = hashinit(UDBHASHSIZE, M_PCB,
- &V_udbinfo.ipi_hashmask);
- V_udbinfo.ipi_porthashbase = hashinit(UDBHASHSIZE, M_PCB,
- &V_udbinfo.ipi_porthashmask);
- V_udbinfo.ipi_zone = uma_zcreate("udp_inpcb", sizeof(struct inpcb),
- NULL, NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
- uma_zone_set_max(V_udbinfo.ipi_zone, maxsockets);
-
+ in_pcbinfo_init(&V_udbinfo, "udp", &V_udb, UDBHASHSIZE, UDBHASHSIZE,
+ "udp_inpcb", udp_inpcb_init, NULL, UMA_ZONE_NOFREE);
V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_udpcb_zone, maxsockets);
-
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
EVENTHANDLER_PRI_ANY);
}
@@ -241,11 +227,8 @@ void
udp_destroy(void)
{
- hashdestroy(V_udbinfo.ipi_hashbase, M_PCB,
- V_udbinfo.ipi_hashmask);
- hashdestroy(V_udbinfo.ipi_porthashbase, M_PCB,
- V_udbinfo.ipi_porthashmask);
- INP_INFO_LOCK_DESTROY(&V_udbinfo);
+ in_pcbinfo_destroy(&V_udbinfo);
+ uma_zdestroy(V_udpcb_zone);
}
#endif
@@ -763,11 +746,13 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RLOCK(&V_udbinfo);
for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n;
inp = LIST_NEXT(inp, inp_list)) {
- INP_RLOCK(inp);
+ INP_WLOCK(inp);
if (inp->inp_gencnt <= gencnt &&
- cr_canseeinpcb(req->td->td_ucred, inp) == 0)
+ cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
+ in_pcbref(inp);
inp_list[i++] = inp;
- INP_RUNLOCK(inp);
+ }
+ INP_WUNLOCK(inp);
}
INP_INFO_RUNLOCK(&V_udbinfo);
n = i;
@@ -778,6 +763,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
+
bzero(&xi, sizeof(xi));
xi.xi_len = sizeof xi;
/* XXX should avoid extra copy */
@@ -790,6 +776,15 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
} else
INP_RUNLOCK(inp);
}
+ INP_INFO_WLOCK(&V_udbinfo);
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_WLOCK(inp);
+ if (!in_pcbrele(inp))
+ INP_WUNLOCK(inp);
+ }
+ INP_INFO_WUNLOCK(&V_udbinfo);
+
if (!error) {
/*
* Give the user an updated idea of our state. If the
@@ -1427,7 +1422,7 @@ udp_attach(struct socket *so, int proto, struct thread *td)
return (error);
}
- inp = (struct inpcb *)so->so_pcb;
+ inp = sotoinpcb(so);
inp->inp_vflag |= INP_IPV4;
inp->inp_ip_ttl = V_ip_defttl;
@@ -1450,17 +1445,10 @@ udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f)
struct inpcb *inp;
struct udpcb *up;
- KASSERT(so->so_type == SOCK_DGRAM, ("udp_set_kernel_tunneling: !dgram"));
- KASSERT(so->so_pcb != NULL, ("udp_set_kernel_tunneling: NULL inp"));
- if (so->so_type != SOCK_DGRAM) {
- /* Not UDP socket... sorry! */
- return (ENOTSUP);
- }
- inp = (struct inpcb *)so->so_pcb;
- if (inp == NULL) {
- /* NULL INP? */
- return (EINVAL);
- }
+ KASSERT(so->so_type == SOCK_DGRAM,
+ ("udp_set_kernel_tunneling: !dgram"));
+ inp = sotoinpcb(so);
+ KASSERT(inp != NULL, ("udp_set_kernel_tunneling: inp == NULL"));
INP_WLOCK(inp);
up = intoudpcb(inp);
if (up->u_tun_func != NULL) {
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index c839efd..74c15d5 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2344,8 +2344,12 @@ in6_lltable_prefix_free(struct lltable *llt,
&((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr,
&pfx->sin6_addr,
&msk->sin6_addr)) {
- callout_drain(&lle->la_timer);
+ int canceled;
+
+ canceled = callout_drain(&lle->la_timer);
LLE_WLOCK(lle);
+ if (canceled)
+ LLE_REMREF(lle);
llentry_free(lle);
}
}
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index c2ec49a..a878aac 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
+#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/kernel.h>
@@ -102,6 +103,10 @@ __FBSDID("$FreeBSD$");
#include <netipsec/key.h>
#include <netinet6/ip6_ipsec.h>
#endif /* IPSEC */
+#ifdef SCTP
+#include <netinet/sctp.h>
+#include <netinet/sctp_crc32.h>
+#endif
#include <netinet6/ip6protosw.h>
#include <netinet6/scope6_var.h>
@@ -208,6 +213,9 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
struct route_in6 *ro_pmtu = NULL;
int hdrsplit = 0;
int needipsec = 0;
+#ifdef SCTP
+ int sw_csum;
+#endif
#ifdef IPSEC
struct ipsec_output_state state;
struct ip6_rthdr *rh = NULL;
@@ -829,6 +837,10 @@ again:
}
m->m_pkthdr.csum_flags |=
CSUM_IP_CHECKED | CSUM_IP_VALID;
+#ifdef SCTP
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+ m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID;
+#endif
error = netisr_queue(NETISR_IPV6, m);
goto done;
} else
@@ -857,6 +869,13 @@ passout:
* 4: if dontfrag == 1 && alwaysfrag == 1
* error, as we cannot handle this conflicting request
*/
+#ifdef SCTP
+ sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
+ if (sw_csum & CSUM_SCTP) {
+ sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
+ sw_csum &= ~CSUM_SCTP;
+ }
+#endif
tlen = m->m_pkthdr.len;
if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG))
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index cade0d2..21d9eab 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -195,8 +195,10 @@ static int sysctl_mld_ifinfo(SYSCTL_HANDLER_ARGS);
static struct mtx mld_mtx;
MALLOC_DEFINE(M_MLD, "mld", "mld state");
-#define MLD_EMBEDSCOPE(pin6, zoneid) \
- (pin6)->s6_addr16[1] = htons((zoneid) & 0xFFFF)
+#define MLD_EMBEDSCOPE(pin6, zoneid) \
+ if (IN6_IS_SCOPE_LINKLOCAL(pin6) || \
+ IN6_IS_ADDR_MC_INTFACELOCAL(pin6)) \
+ (pin6)->s6_addr16[1] = htons((zoneid) & 0xFFFF) \
/*
* VIMAGE-wide globals.
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index a32539b..a0ef204 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1125,6 +1125,7 @@ nd6_free(struct llentry *ln, int gc)
ifp = ln->lle_tbl->llt_ifp;
IF_AFDATA_LOCK(ifp);
LLE_WLOCK(ln);
+ LLE_REMREF(ln);
llentry_free(ln);
IF_AFDATA_UNLOCK(ifp);
@@ -1168,7 +1169,7 @@ nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force)
ln->ln_state = ND6_LLINFO_REACHABLE;
if (!ND6_LLINFO_PERMANENT(ln)) {
- nd6_llinfo_settimer(ln,
+ nd6_llinfo_settimer_locked(ln,
(long)ND_IFINFO(rt->rt_ifp)->reachable * hz);
}
done:
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 50f5ef8..02e2880 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -1033,7 +1033,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
return (EALREADY);
}
/* We are GOOD to go */
- stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id, p);
+ stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p);
SCTP_ASOC_CREATE_UNLOCK(inp);
if (stcb == NULL) {
/* Gak! no memory */
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index 4b552c8..5ee4bbb 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -592,7 +592,7 @@ ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),("packet too short"));
/* NB: ip_input() flips it into host endian. XXX Need more checking. */
- if (m->m_len < sizeof (struct ip)) {
+ if (m->m_len >= sizeof (struct ip)) {
struct ip *ip = mtod(m, struct ip *);
if (ip->ip_off & (IP_MF | IP_OFFMASK))
goto done;
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index c5aa4b7..2b17fb0 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -1882,7 +1882,9 @@ key_spdadd(so, m, mhp)
newsp = key_getsp(&spidx);
if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
if (newsp) {
+ SPTREE_LOCK();
newsp->state = IPSEC_SPSTATE_DEAD;
+ SPTREE_UNLOCK();
KEY_FREESP(&newsp);
}
} else {
@@ -2117,7 +2119,9 @@ key_spddelete(so, m, mhp)
/* save policy id to buffer to be returned. */
xpl0->sadb_x_policy_id = sp->id;
+ SPTREE_LOCK();
sp->state = IPSEC_SPSTATE_DEAD;
+ SPTREE_UNLOCK();
KEY_FREESP(&sp);
{
@@ -2184,7 +2188,9 @@ key_spddelete2(so, m, mhp)
return key_senderror(so, m, EINVAL);
}
+ SPTREE_LOCK();
sp->state = IPSEC_SPSTATE_DEAD;
+ SPTREE_UNLOCK();
KEY_FREESP(&sp);
{
@@ -7779,7 +7785,8 @@ void
key_destroy(void)
{
struct secpolicy *sp, *nextsp;
- struct secspacq *acq, *nextacq;
+ struct secacq *acq, *nextacq;
+ struct secspacq *spacq, *nextspacq;
struct secashead *sah, *nextsah;
struct secreg *reg;
int i;
@@ -7820,7 +7827,7 @@ key_destroy(void)
REGTREE_UNLOCK();
ACQ_LOCK();
- for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) {
+ for (acq = LIST_FIRST(&V_acqtree); acq != NULL; acq = nextacq) {
nextacq = LIST_NEXT(acq, chain);
if (__LIST_CHAINED(acq)) {
LIST_REMOVE(acq, chain);
@@ -7830,11 +7837,12 @@ key_destroy(void)
ACQ_UNLOCK();
SPACQ_LOCK();
- for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) {
- nextacq = LIST_NEXT(acq, chain);
- if (__LIST_CHAINED(acq)) {
- LIST_REMOVE(acq, chain);
- free(acq, M_IPSEC_SAQ);
+ for (spacq = LIST_FIRST(&V_spacqtree); spacq != NULL;
+ spacq = nextspacq) {
+ nextspacq = LIST_NEXT(spacq, chain);
+ if (__LIST_CHAINED(spacq)) {
+ LIST_REMOVE(spacq, chain);
+ free(spacq, M_IPSEC_SAQ);
}
}
SPACQ_UNLOCK();
diff --git a/sys/netncp/ncp_conn.c b/sys/netncp/ncp_conn.c
index 5b61dfe..03ef5e3 100644
--- a/sys/netncp/ncp_conn.c
+++ b/sys/netncp/ncp_conn.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_conn.h b/sys/netncp/ncp_conn.h
index 1524d40..0a87051 100644
--- a/sys/netncp/ncp_conn.h
+++ b/sys/netncp/ncp_conn.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_file.h b/sys/netncp/ncp_file.h
index cebf4b9..207a158 100644
--- a/sys/netncp/ncp_file.h
+++ b/sys/netncp/ncp_file.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_lib.h b/sys/netncp/ncp_lib.h
index f3ce680..2e8eebe 100644
--- a/sys/netncp/ncp_lib.h
+++ b/sys/netncp/ncp_lib.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_login.c b/sys/netncp/ncp_login.c
index a61eb76..bce8e68 100644
--- a/sys/netncp/ncp_login.c
+++ b/sys/netncp/ncp_login.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_ncp.c b/sys/netncp/ncp_ncp.c
index 92b7e59..943639e 100644
--- a/sys/netncp/ncp_ncp.c
+++ b/sys/netncp/ncp_ncp.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_ncp.h b/sys/netncp/ncp_ncp.h
index ab1c742..e62eda2 100644
--- a/sys/netncp/ncp_ncp.h
+++ b/sys/netncp/ncp_ncp.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_nls.c b/sys/netncp/ncp_nls.c
index bb746fc..b582626 100644
--- a/sys/netncp/ncp_nls.c
+++ b/sys/netncp/ncp_nls.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_nls.h b/sys/netncp/ncp_nls.h
index 0a39152..0180a92 100644
--- a/sys/netncp/ncp_nls.h
+++ b/sys/netncp/ncp_nls.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_rcfile.h b/sys/netncp/ncp_rcfile.h
index 034402d..926af4e 100644
--- a/sys/netncp/ncp_rcfile.h
+++ b/sys/netncp/ncp_rcfile.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_rq.c b/sys/netncp/ncp_rq.c
index f8f7ce2..e011c10 100644
--- a/sys/netncp/ncp_rq.c
+++ b/sys/netncp/ncp_rq.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_rq.h b/sys/netncp/ncp_rq.h
index d0ad9ad..8d20d3f 100644
--- a/sys/netncp/ncp_rq.h
+++ b/sys/netncp/ncp_rq.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_sock.c b/sys/netncp/ncp_sock.c
index 0095f3f..4be432e 100644
--- a/sys/netncp/ncp_sock.c
+++ b/sys/netncp/ncp_sock.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_sock.h b/sys/netncp/ncp_sock.h
index a3998a4..f8feac5 100644
--- a/sys/netncp/ncp_sock.h
+++ b/sys/netncp/ncp_sock.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_subr.c b/sys/netncp/ncp_subr.c
index da0a6d9..6664dbd 100644
--- a/sys/netncp/ncp_subr.c
+++ b/sys/netncp/ncp_subr.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_subr.h b/sys/netncp/ncp_subr.h
index 5c57755..a0d3ce9 100644
--- a/sys/netncp/ncp_subr.h
+++ b/sys/netncp/ncp_subr.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netncp/ncp_user.h b/sys/netncp/ncp_user.h
index dc6d3cd..832715e 100644
--- a/sys/netncp/ncp_user.h
+++ b/sys/netncp/ncp_user.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, Boris Popov
+ * Copyright (c) 1999 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/netbios.h b/sys/netsmb/netbios.h
index 9ee78d8..dff79b9 100644
--- a/sys/netsmb/netbios.h
+++ b/sys/netsmb/netbios.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb.h b/sys/netsmb/smb.h
index a127465..c6945d3 100644
--- a/sys/netsmb/smb.h
+++ b/sys/netsmb/smb.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_conn.c b/sys/netsmb/smb_conn.c
index 2307f97..c14cb8b 100644
--- a/sys/netsmb/smb_conn.c
+++ b/sys/netsmb/smb_conn.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_conn.h b/sys/netsmb/smb_conn.h
index 153c83a..370f6cf 100644
--- a/sys/netsmb/smb_conn.h
+++ b/sys/netsmb/smb_conn.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_dev.c b/sys/netsmb/smb_dev.c
index 8c47498..6867804 100644
--- a/sys/netsmb/smb_dev.c
+++ b/sys/netsmb/smb_dev.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_dev.h b/sys/netsmb/smb_dev.h
index 1454ab3..8eb41f3 100644
--- a/sys/netsmb/smb_dev.h
+++ b/sys/netsmb/smb_dev.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_iod.c b/sys/netsmb/smb_iod.c
index 29b48e7..78def47 100644
--- a/sys/netsmb/smb_iod.c
+++ b/sys/netsmb/smb_iod.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_rq.c b/sys/netsmb/smb_rq.c
index 3d068b6..4f5c5e6 100644
--- a/sys/netsmb/smb_rq.c
+++ b/sys/netsmb/smb_rq.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_rq.h b/sys/netsmb/smb_rq.h
index d989e4f..af17c9c 100644
--- a/sys/netsmb/smb_rq.h
+++ b/sys/netsmb/smb_rq.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_smb.c b/sys/netsmb/smb_smb.c
index d6633e7..d3fb94a 100644
--- a/sys/netsmb/smb_smb.c
+++ b/sys/netsmb/smb_smb.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_subr.c b/sys/netsmb/smb_subr.c
index 23598a7..39d3b49 100644
--- a/sys/netsmb/smb_subr.c
+++ b/sys/netsmb/smb_subr.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_subr.h b/sys/netsmb/smb_subr.h
index 15e4a7a..12730cc 100644
--- a/sys/netsmb/smb_subr.h
+++ b/sys/netsmb/smb_subr.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_tran.h b/sys/netsmb/smb_tran.h
index 4d8955d..0169807 100644
--- a/sys/netsmb/smb_tran.h
+++ b/sys/netsmb/smb_tran.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c
index 1a74e728..c898451 100644
--- a/sys/netsmb/smb_trantcp.c
+++ b/sys/netsmb/smb_trantcp.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_trantcp.h b/sys/netsmb/smb_trantcp.h
index 6251b0e..b420103 100644
--- a/sys/netsmb/smb_trantcp.h
+++ b/sys/netsmb/smb_trantcp.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/netsmb/smb_usr.c b/sys/netsmb/smb_usr.c
index 2916ee84..b538807 100644
--- a/sys/netsmb/smb_usr.c
+++ b/sys/netsmb/smb_usr.c
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index d84261e..f2e9d51 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -1128,6 +1128,9 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
}
}
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
+ if (error != 0)
+ /* Make sure the server replies ESTALE to the client. */
+ error = ESTALE;
vfs_unbusy(mp);
if (error)
goto out;
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
index 10b2598..8c5a7d2 100644
--- a/sys/pc98/cbus/clock.c
+++ b/sys/pc98/cbus/clock.c
@@ -93,6 +93,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq);
int i8254_max_count;
static int i8254_real_max_count;
+static int lapic_allclocks = 1;
+TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
+
static struct mtx clock_lock;
static struct intsrc *i8254_intsrc;
static u_int32_t i8254_lastcount;
@@ -172,8 +175,8 @@ clkintr(struct trapframe *frame)
* timers.
*/
int cpu = PCPU_GET(cpuid);
- if (lapic_cyclic_clock_func[cpu] != NULL)
- (*lapic_cyclic_clock_func[cpu])(frame);
+ if (cyclic_clock_func[cpu] != NULL)
+ (*cyclic_clock_func[cpu])(frame);
#endif
#ifdef SMP
@@ -432,9 +435,11 @@ startrtclock()
void
cpu_initclocks()
{
+#if defined(DEV_APIC)
+ enum lapic_clock tlsca;
-#ifdef DEV_APIC
- using_lapic_timer = lapic_setup_clock();
+ tlsca = lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL;
+ using_lapic_timer = lapic_setup_clock(tlsca);
#endif
/*
* If we aren't using the local APIC timer to drive the kernel
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 9f08bf5..699091e 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -46,7 +46,6 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
options COMPAT_FREEBSD4 # Compatible with FreeBSD4
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options COMPAT_FREEBSD6 # Compatible with FreeBSD6
@@ -248,6 +247,7 @@ device firmware # firmware assist module
device bpf # Berkeley packet filter
# USB support
+#options USB_DEBUG # enable debug msgs
#device uhci # UHCI PCI->USB interface
#device ohci # OHCI PCI->USB interface
#device ehci # EHCI PCI->USB interface (USB 2.0)
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index f178748..f470b5e 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -1172,11 +1172,7 @@ void (*cpu_idle_hook)(void) = cpu_idle_default;
* Reset registers to default values on exec.
*/
void
-exec_setregs(td, entry, stack, ps_strings)
- struct thread *td;
- u_long entry;
- u_long stack;
- u_long ps_strings;
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *regs = td->td_frame;
struct pcb *pcb = td->td_pcb;
@@ -1192,7 +1188,7 @@ exec_setregs(td, entry, stack, ps_strings)
mtx_unlock_spin(&dt_lock);
bzero((char *)regs, sizeof(struct trapframe));
- regs->tf_eip = entry;
+ regs->tf_eip = imgp->entry_addr;
regs->tf_esp = stack;
regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T);
regs->tf_ss = _udatasel;
@@ -1202,7 +1198,7 @@ exec_setregs(td, entry, stack, ps_strings)
regs->tf_cs = _ucodesel;
/* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
- regs->tf_ebx = ps_strings;
+ regs->tf_ebx = imgp->ps_strings;
/*
* Reset the hardware debug registers if they were in use.
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index b575289..7d2c7e4 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -133,6 +133,7 @@
#define RL_GMEDIASTAT 0x006C /* 8 bits */
#define RL_MACDBG 0x006D /* 8 bits, 8168C SPIN2 only */
#define RL_GPIO 0x006E /* 8 bits, 8168C SPIN2 only */
+#define RL_PMCH 0x006F /* 8 bits */
#define RL_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */
#define RL_GTXSTART 0x0038 /* 8 bits */
@@ -159,9 +160,10 @@
#define RL_HWREV_8169_8110SB 0x10000000
#define RL_HWREV_8169_8110SC 0x18000000
#define RL_HWREV_8102EL 0x24800000
-#define RL_HWREV_8102EL_SPIN1 0x24c00000
+#define RL_HWREV_8102EL_SPIN1 0x24C00000
#define RL_HWREV_8168D 0x28000000
#define RL_HWREV_8168DP 0x28800000
+#define RL_HWREV_8168E 0x2C000000
#define RL_HWREV_8168_SPIN1 0x30000000
#define RL_HWREV_8100E 0x30800000
#define RL_HWREV_8101E 0x34000000
@@ -180,7 +182,7 @@
#define RL_HWREV_8139C 0x74000000
#define RL_HWREV_8139D 0x74400000
#define RL_HWREV_8139CPLUS 0x74800000
-#define RL_HWREV_8101 0x74c00000
+#define RL_HWREV_8101 0x74C00000
#define RL_HWREV_8100 0x78800000
#define RL_HWREV_8169_8110SBL 0x7CC00000
#define RL_HWREV_8169_8110SCE 0x98000000
@@ -884,6 +886,7 @@ struct rl_softc {
uint32_t rl_flags;
#define RL_FLAG_MSI 0x0001
#define RL_FLAG_AUTOPAD 0x0002
+#define RL_FLAG_PHYWAKE_PM 0x0004
#define RL_FLAG_PHYWAKE 0x0008
#define RL_FLAG_NOJUMBO 0x0010
#define RL_FLAG_PAR 0x0020
diff --git a/sys/powerpc/aim/interrupt.c b/sys/powerpc/aim/interrupt.c
index d7f489a..b436038 100644
--- a/sys/powerpc/aim/interrupt.c
+++ b/sys/powerpc/aim/interrupt.c
@@ -80,15 +80,17 @@ powerpc_interrupt(struct trapframe *framep)
switch (framep->exc) {
case EXC_EXI:
- atomic_add_int(&td->td_intr_nesting_level, 1);
+ critical_enter();
PIC_DISPATCH(pic, framep);
- atomic_subtract_int(&td->td_intr_nesting_level, 1);
+ critical_exit();
break;
case EXC_DECR:
+ critical_enter();
atomic_add_int(&td->td_intr_nesting_level, 1);
decr_intr(framep);
atomic_subtract_int(&td->td_intr_nesting_level, 1);
+ critical_exit();
break;
default:
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index a9cf051..49aae27 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -951,7 +951,7 @@ cpu_idle_wakeup(int cpu)
* Set set up registers on exec.
*/
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf;
struct ps_strings arginfo;
@@ -995,7 +995,7 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
tf->fixreg[7] = 0; /* termination vector */
tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */
- tf->srr0 = entry;
+ tf->srr0 = imgp->entry_addr;
tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
td->td_pcb->pcb_flags = 0;
}
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 8357929..24e7b4e 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -305,6 +305,7 @@ vm_paddr_t moea_extract(mmu_t, pmap_t, vm_offset_t);
vm_page_t moea_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
void moea_init(mmu_t);
boolean_t moea_is_modified(mmu_t, vm_page_t);
+boolean_t moea_is_referenced(mmu_t, vm_page_t);
boolean_t moea_ts_referenced(mmu_t, vm_page_t);
vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t, int);
boolean_t moea_page_exists_quick(mmu_t, pmap_t, vm_page_t);
@@ -344,6 +345,7 @@ static mmu_method_t moea_methods[] = {
MMUMETHOD(mmu_extract_and_hold, moea_extract_and_hold),
MMUMETHOD(mmu_init, moea_init),
MMUMETHOD(mmu_is_modified, moea_is_modified),
+ MMUMETHOD(mmu_is_referenced, moea_is_referenced),
MMUMETHOD(mmu_ts_referenced, moea_ts_referenced),
MMUMETHOD(mmu_map, moea_map),
MMUMETHOD(mmu_page_exists_quick,moea_page_exists_quick),
@@ -1269,6 +1271,15 @@ moea_init(mmu_t mmu)
}
boolean_t
+moea_is_referenced(mmu_t mmu, vm_page_t m)
+{
+
+ if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
+ return (FALSE);
+ return (moea_query_bit(m, PTE_REF));
+}
+
+boolean_t
moea_is_modified(mmu_t mmu, vm_page_t m)
{
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 6760fee..2571587 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -327,7 +327,6 @@ SYSCTL_INT(_machdep, OID_AUTO, moea64_pvo_remove_calls, CTLFLAG_RD,
&moea64_pvo_remove_calls, 0, "");
vm_offset_t moea64_scratchpage_va[2];
-struct pvo_entry *moea64_scratchpage_pvo[2];
struct lpte *moea64_scratchpage_pte[2];
struct mtx moea64_scratchpage_mtx;
@@ -380,6 +379,7 @@ vm_paddr_t moea64_extract(mmu_t, pmap_t, vm_offset_t);
vm_page_t moea64_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
void moea64_init(mmu_t);
boolean_t moea64_is_modified(mmu_t, vm_page_t);
+boolean_t moea64_is_referenced(mmu_t, vm_page_t);
boolean_t moea64_ts_referenced(mmu_t, vm_page_t);
vm_offset_t moea64_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t, int);
boolean_t moea64_page_exists_quick(mmu_t, pmap_t, vm_page_t);
@@ -417,6 +417,7 @@ static mmu_method_t moea64_bridge_methods[] = {
MMUMETHOD(mmu_extract_and_hold, moea64_extract_and_hold),
MMUMETHOD(mmu_init, moea64_init),
MMUMETHOD(mmu_is_modified, moea64_is_modified),
+ MMUMETHOD(mmu_is_referenced, moea64_is_referenced),
MMUMETHOD(mmu_ts_referenced, moea64_ts_referenced),
MMUMETHOD(mmu_map, moea64_map),
MMUMETHOD(mmu_page_exists_quick,moea64_page_exists_quick),
@@ -965,22 +966,36 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
PMAP_UNLOCK(kernel_pmap);
/*
- * Allocate some things for page zeroing
+ * Allocate some things for page zeroing. We put this directly
+ * in the page table, marked with LPTE_LOCKED, to avoid any
+ * of the PVO book-keeping or other parts of the VM system
+ * from even knowing that this hack exists.
*/
mtx_init(&moea64_scratchpage_mtx, "pvo zero page", NULL, MTX_DEF);
for (i = 0; i < 2; i++) {
+ struct lpte pt;
+ uint64_t vsid;
+ int pteidx, ptegidx;
+
moea64_scratchpage_va[i] = (virtual_end+1) - PAGE_SIZE;
virtual_end -= PAGE_SIZE;
- moea64_kenter(mmup,moea64_scratchpage_va[i],0);
-
LOCK_TABLE();
- moea64_scratchpage_pvo[i] = moea64_pvo_find_va(kernel_pmap,
- moea64_scratchpage_va[i],&j);
- moea64_scratchpage_pte[i] = moea64_pvo_to_pte(
- moea64_scratchpage_pvo[i],j);
- moea64_scratchpage_pte[i]->pte_hi |= LPTE_LOCKED;
+
+ vsid = va_to_vsid(kernel_pmap, moea64_scratchpage_va[i]);
+ moea64_pte_create(&pt, vsid, moea64_scratchpage_va[i],
+ LPTE_NOEXEC);
+ pt.pte_hi |= LPTE_LOCKED;
+
+ ptegidx = va_to_pteg(vsid, moea64_scratchpage_va[i]);
+ pteidx = moea64_pte_insert(ptegidx, &pt);
+ if (pt.pte_hi & LPTE_HID)
+ ptegidx ^= moea64_pteg_mask;
+
+ moea64_scratchpage_pte[i] =
+ &moea64_pteg_table[ptegidx].pt[pteidx];
+
UNLOCK_TABLE();
}
@@ -1088,18 +1103,16 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
static __inline
void moea64_set_scratchpage_pa(int which, vm_offset_t pa) {
- mtx_assert(&moea64_scratchpage_mtx, MA_OWNED);
- moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo &=
- ~(LPTE_WIMG | LPTE_RPGN);
- moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo |=
- moea64_calc_wimg(pa) | (uint64_t)pa;
+ mtx_assert(&moea64_scratchpage_mtx, MA_OWNED);
moea64_scratchpage_pte[which]->pte_hi &= ~LPTE_VALID;
TLBIE(kernel_pmap, moea64_scratchpage_va[which]);
- moea64_scratchpage_pte[which]->pte_lo =
- moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo;
+ moea64_scratchpage_pte[which]->pte_lo &=
+ ~(LPTE_WIMG | LPTE_RPGN);
+ moea64_scratchpage_pte[which]->pte_lo |=
+ moea64_calc_wimg(pa) | (uint64_t)pa;
EIEIO();
moea64_scratchpage_pte[which]->pte_hi |= LPTE_VALID;
@@ -1452,6 +1465,15 @@ moea64_init(mmu_t mmu)
}
boolean_t
+moea64_is_referenced(mmu_t mmu, vm_page_t m)
+{
+
+ if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
+ return (FALSE);
+ return (moea64_query_bit(m, PTE_REF));
+}
+
+boolean_t
moea64_is_modified(mmu_t mmu, vm_page_t m)
{
@@ -1499,8 +1521,8 @@ moea64_remove_write(mmu_t mmu, vm_page_t m)
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
pmap = pvo->pvo_pmap;
PMAP_LOCK(pmap);
+ LOCK_TABLE();
if ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) {
- LOCK_TABLE();
pt = moea64_pvo_to_pte(pvo, -1);
pvo->pvo_pte.lpte.pte_lo &= ~LPTE_PP;
pvo->pvo_pte.lpte.pte_lo |= LPTE_BR;
@@ -1511,8 +1533,8 @@ moea64_remove_write(mmu_t mmu, vm_page_t m)
moea64_pte_change(pt, &pvo->pvo_pte.lpte,
pvo->pvo_pmap, PVO_VADDR(pvo));
}
- UNLOCK_TABLE();
}
+ UNLOCK_TABLE();
PMAP_UNLOCK(pmap);
}
if ((lo & LPTE_CHG) != 0) {
@@ -1593,6 +1615,13 @@ moea64_kextract(mmu_t mmu, vm_offset_t va)
struct pvo_entry *pvo;
vm_paddr_t pa;
+ /*
+ * Shortcut the direct-mapped case when applicable. We never put
+ * anything but 1:1 mappings below VM_MIN_KERNEL_ADDRESS.
+ */
+ if (va < VM_MIN_KERNEL_ADDRESS)
+ return (va);
+
PMAP_LOCK(kernel_pmap);
pvo = moea64_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
KASSERT(pvo != NULL, ("moea64_kextract: no addr found"));
@@ -1650,9 +1679,11 @@ moea64_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m)
if (!moea64_initialized || (m->flags & PG_FICTITIOUS))
return FALSE;
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+
loops = 0;
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
- if (pvo->pvo_pmap == pmap)
+ if (pvo->pvo_pmap == pmap)
return (TRUE);
if (++loops >= 16)
break;
@@ -2046,7 +2077,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
bootstrap = 1;
} else {
/*
- * Note: drop the table around the UMA allocation in
+ * Note: drop the table lock around the UMA allocation in
* case the UMA allocator needs to manipulate the page
* table. The mapping we are working with is already
* protected by the PMAP lock.
@@ -2130,7 +2161,6 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx)
} else {
moea64_pte_overflow--;
}
- UNLOCK_TABLE();
/*
* Update our statistics.
@@ -2162,9 +2192,12 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx)
* if we aren't going to reuse it.
*/
LIST_REMOVE(pvo, pvo_olink);
+ UNLOCK_TABLE();
+
if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
uma_zfree((pvo->pvo_vaddr & PVO_MANAGED) ? moea64_mpvo_zone :
moea64_upvo_zone, pvo);
+
moea64_pvo_entries--;
moea64_pvo_remove_calls++;
}
@@ -2247,7 +2280,7 @@ moea64_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
}
if (((pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo) &
- ~(LPTE_CHG|LPTE_REF)) != 0) {
+ ~(LPTE_M|LPTE_CHG|LPTE_REF)) != 0) {
panic("moea64_pvo_to_pte: pvo %p pte does not match "
"pte %p in moea64_pteg_table difference is %#x",
pvo, pt,
@@ -2313,6 +2346,8 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
if (moea64_attr_fetch(m) & ptebit)
return (TRUE);
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
MOEA_PVO_CHECK(pvo); /* sanity check */
@@ -2367,6 +2402,8 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit, u_int64_t *origbit)
struct lpte *pt;
uint64_t rv;
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+
/*
* Clear the cached value.
*/
@@ -2399,10 +2436,10 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit, u_int64_t *origbit)
moea64_pte_clear(pt, pvo->pvo_pmap, PVO_VADDR(pvo), ptebit);
}
}
- UNLOCK_TABLE();
rv |= pvo->pvo_pte.lpte.pte_lo;
pvo->pvo_pte.lpte.pte_lo &= ~ptebit;
MOEA_PVO_CHECK(pvo); /* sanity check */
+ UNLOCK_TABLE();
}
if (origbit != NULL) {
@@ -2489,7 +2526,7 @@ moea64_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
len = MIN(lim - va, sz);
pvo = moea64_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
if (pvo != NULL) {
- pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) |
+ pa = (pvo->pvo_pte.pte.pte_lo & LPTE_RPGN) |
(va & ADDR_POFF);
moea64_syncicache(pm, va, pa, len);
}
diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c
index d92090b..54567b1 100644
--- a/sys/powerpc/aim/nexus.c
+++ b/sys/powerpc/aim/nexus.c
@@ -60,7 +60,6 @@
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/bus.h>
-#include <sys/clock.h>
#include <sys/cons.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -74,7 +73,6 @@
#include <sys/rman.h>
-#include "clock_if.h"
#include "ofw_bus_if.h"
#include "pic_if.h"
@@ -143,12 +141,6 @@ static const char *nexus_ofw_get_type(device_t, device_t);
static const char *nexus_ofw_get_compat(device_t, device_t);
/*
- * Clock interface.
- */
-static int nexus_gettime(device_t, struct timespec *);
-static int nexus_settime(device_t, struct timespec *);
-
-/*
* Local routines
*/
static device_t nexus_device_from_node(device_t, phandle_t);
@@ -181,10 +173,6 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(ofw_bus_get_type, nexus_ofw_get_type),
DEVMETHOD(ofw_bus_get_compat, nexus_ofw_get_compat),
- /* Clock interface */
- DEVMETHOD(clock_gettime, nexus_gettime),
- DEVMETHOD(clock_settime, nexus_settime),
-
{ 0, 0 }
};
@@ -240,7 +228,6 @@ nexus_attach(device_t dev)
}
- clock_register(dev, 1000);
return (bus_generic_attach(dev));
}
@@ -512,50 +499,3 @@ nexus_ofw_get_compat(device_t bus, device_t dev)
return (dinfo->ndi_compatible);
}
-#define DIFF19041970 2082844800
-
-static int
-nexus_gettime(device_t dev, struct timespec *ts)
-{
- char path[128];
- ihandle_t ih;
- phandle_t ph;
- u_int rtc;
-
- ph = OF_finddevice("rtc");
- if (ph == -1)
- return (ENOENT);
-
- OF_package_to_path(ph, path, sizeof(path));
- ih = OF_open(path);
- if (ih == -1)
- return (ENXIO);
-
- if (OF_call_method("read-rtc", ih, 0, 1, &rtc))
- return (EIO);
-
- ts->tv_sec = rtc - DIFF19041970;
- ts->tv_nsec = 0;
- return (0);
-}
-
-static int
-nexus_settime(device_t dev, struct timespec *ts)
-{
- char path[128];
- ihandle_t ih;
- phandle_t ph;
- u_int rtc;
-
- ph = OF_finddevice("rtc");
- if (ph == -1)
- return (ENOENT);
-
- OF_package_to_path(ph, path, sizeof(path));
- ih = OF_open(path);
- if (ih == -1)
- return (ENXIO);
-
- rtc = ts->tv_sec + DIFF19041970;
- return ((OF_call_method("write-rtc", ih, 1, 0, rtc) != 0) ? EIO : 0);
-}
diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c
index 6e27697..6e98f3e 100644
--- a/sys/powerpc/aim/ofw_machdep.c
+++ b/sys/powerpc/aim/ofw_machdep.c
@@ -63,6 +63,8 @@ __FBSDID("$FreeBSD$");
static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
static struct mem_region OFfree[OFMEM_REGIONS + 3];
+static struct mtx ofw_mutex;
+
struct mem_region64 {
vm_offset_t mr_start_hi;
vm_offset_t mr_start_lo;
@@ -281,6 +283,8 @@ OF_bootstrap()
{
boolean_t status = FALSE;
+ mtx_init(&ofw_mutex, "open firmware", NULL, MTX_DEF);
+
if (ofwcall != NULL) {
if (ofw_real_mode)
status = OF_install(OFW_STD_REAL, 0);
@@ -314,6 +318,8 @@ openfirmware(void *args)
if (pmap_bootstrapped && ofw_real_mode)
args = (void *)pmap_kextract((vm_offset_t)args);
+ mtx_lock(&ofw_mutex);
+
__asm __volatile( "\t"
"sync\n\t"
"mfmsr %0\n\t"
@@ -366,6 +372,8 @@ openfirmware(void *args)
: : "r" (oldmsr)
);
+ mtx_unlock(&ofw_mutex);
+
return (result);
}
diff --git a/sys/powerpc/aim/ofwmagic.S b/sys/powerpc/aim/ofwmagic.S
index 55af6d2..f44f1e5 100644
--- a/sys/powerpc/aim/ofwmagic.S
+++ b/sys/powerpc/aim/ofwmagic.S
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/powerpc/booke/interrupt.c b/sys/powerpc/booke/interrupt.c
index 01ee3d9..91ceeb7 100644
--- a/sys/powerpc/booke/interrupt.c
+++ b/sys/powerpc/booke/interrupt.c
@@ -118,9 +118,12 @@ powerpc_decr_interrupt(struct trapframe *framep)
struct thread *td;
td = PCPU_GET(curthread);
+ critical_enter();
atomic_add_int(&td->td_intr_nesting_level, 1);
decr_intr(framep);
atomic_subtract_int(&td->td_intr_nesting_level, 1);
+ critical_exit();
+ framep->srr1 &= ~PSL_WE;
}
/*
@@ -129,10 +132,9 @@ powerpc_decr_interrupt(struct trapframe *framep)
void
powerpc_extr_interrupt(struct trapframe *framep)
{
- struct thread *td;
- td = PCPU_GET(curthread);
- atomic_add_int(&td->td_intr_nesting_level, 1);
+ critical_enter();
PIC_DISPATCH(pic, framep);
- atomic_subtract_int(&td->td_intr_nesting_level, 1);
+ critical_exit();
+ framep->srr1 &= ~PSL_WE;
}
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index d2e25e7..8a53b73 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -509,7 +509,7 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
/* Set set up registers on exec. */
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf;
struct ps_strings arginfo;
@@ -553,7 +553,7 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
tf->fixreg[7] = 0; /* termination vector */
tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */
- tf->srr0 = entry;
+ tf->srr0 = imgp->entry_addr;
tf->srr1 = PSL_USERSET;
td->td_pcb->pcb_flags = 0;
}
@@ -706,6 +706,7 @@ cpu_idle (int busy)
register_t msr;
msr = mfmsr();
+
#ifdef INVARIANTS
if ((msr & PSL_EE) != PSL_EE) {
struct thread *td = curthread;
@@ -713,19 +714,10 @@ cpu_idle (int busy)
panic("ints disabled in idleproc!");
}
#endif
-#if 0
- /*
- * Freescale E500 core RM section 6.4.1
- */
- msr = msr | PSL_WE;
- __asm__(" msync;"
- " mtmsr %0;"
- " isync;"
- "loop: b loop" :
- /* no output */ :
- "r" (msr));
-#endif
+ /* Freescale E500 core RM section 6.4.1. */
+ msr = msr | PSL_WE;
+ __asm __volatile("msync; mtmsr %0; isync" :: "r" (msr));
}
int
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 13e637c..549eaaa 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -288,6 +288,7 @@ static vm_page_t mmu_booke_extract_and_hold(mmu_t, pmap_t, vm_offset_t,
static void mmu_booke_init(mmu_t);
static boolean_t mmu_booke_is_modified(mmu_t, vm_page_t);
static boolean_t mmu_booke_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
+static boolean_t mmu_booke_is_referenced(mmu_t, vm_page_t);
static boolean_t mmu_booke_ts_referenced(mmu_t, vm_page_t);
static vm_offset_t mmu_booke_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t,
int);
@@ -342,6 +343,7 @@ static mmu_method_t mmu_booke_methods[] = {
MMUMETHOD(mmu_init, mmu_booke_init),
MMUMETHOD(mmu_is_modified, mmu_booke_is_modified),
MMUMETHOD(mmu_is_prefaultable, mmu_booke_is_prefaultable),
+ MMUMETHOD(mmu_is_referenced, mmu_booke_is_referenced),
MMUMETHOD(mmu_ts_referenced, mmu_booke_ts_referenced),
MMUMETHOD(mmu_map, mmu_booke_map),
MMUMETHOD(mmu_mincore, mmu_booke_mincore),
@@ -2181,6 +2183,33 @@ mmu_booke_is_prefaultable(mmu_t mmu, pmap_t pmap, vm_offset_t addr)
}
/*
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+static boolean_t
+mmu_booke_is_referenced(mmu_t mmu, vm_page_t m)
+{
+ pte_t *pte;
+ pv_entry_t pv;
+ boolean_t rv;
+
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ rv = FALSE;
+ if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
+ return (rv);
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_link) {
+ PMAP_LOCK(pv->pv_pmap);
+ if ((pte = pte_find(mmu, pv->pv_pmap, pv->pv_va)) != NULL &&
+ PTE_ISVALID(pte))
+ rv = PTE_ISREFERENCED(pte) ? TRUE : FALSE;
+ PMAP_UNLOCK(pv->pv_pmap);
+ if (rv)
+ break;
+ }
+ return (rv);
+}
+
+/*
* Clear the modify bits on the specified physical page.
*/
static void
diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S
index 2e67725..b71f4bd 100644
--- a/sys/powerpc/booke/trap_subr.S
+++ b/sys/powerpc/booke/trap_subr.S
@@ -441,6 +441,7 @@ INTERRUPT(int_instr_storage)
INTERRUPT(int_external_input)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_EXI)
+ addi %r3, %r1, 8
bl CNAME(powerpc_extr_interrupt)
b trapexit
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 6e1aa09..86f56cc 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -47,7 +47,6 @@ options PROCFS #Process filesystem (requires PSEUDOFS)
options PSEUDOFS #Pseudo-filesystem framework
options GEOM_PART_GPT #GUID Partition Tables.
options GEOM_LABEL #Provides labelization
-options COMPAT_43TTY #BSD 4.3 TTY compat (sgtty)
options COMPAT_FREEBSD4 #Keep this for a while
options COMPAT_FREEBSD5 #Compatible with FreeBSD5
options COMPAT_FREEBSD6 #Compatible with FreeBSD6
@@ -145,6 +144,7 @@ device firmware # firmware assist module
device bpf #Berkeley packet filter
# USB support
+options USB_DEBUG # enable debug msgs
device uhci # UHCI PCI->USB interface
device ohci # OHCI PCI->USB interface
device ehci # EHCI PCI->USB interface
diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX
index 51d4e8d..a2a8de4 100644
--- a/sys/powerpc/conf/MPC85XX
+++ b/sys/powerpc/conf/MPC85XX
@@ -79,6 +79,7 @@ device sec
device tsec
device tun
device uart
+options USB_DEBUG # enable debug msgs
#device uhci
device umass
device usb
diff --git a/sys/powerpc/fpu/fpu_extern.h b/sys/powerpc/fpu/fpu_extern.h
index d8528d7..9c24f1d 100644
--- a/sys/powerpc/fpu/fpu_extern.h
+++ b/sys/powerpc/fpu/fpu_extern.h
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/powerpc/include/_inttypes.h b/sys/powerpc/include/_inttypes.h
index 7da589d..ca70a7a 100644
--- a/sys/powerpc/include/_inttypes.h
+++ b/sys/powerpc/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/powerpc/include/intr.h b/sys/powerpc/include/intr.h
index 72c8542..f2aef46 100644
--- a/sys/powerpc/include/intr.h
+++ b/sys/powerpc/include/intr.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/powerpc/include/proc.h b/sys/powerpc/include/proc.h
index c958fb7..cbe6da9 100644
--- a/sys/powerpc/include/proc.h
+++ b/sys/powerpc/include/proc.h
@@ -46,4 +46,6 @@ struct mdthread {
struct mdproc {
};
+#define KINFO_PROC_SIZE 768
+
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h
index 586a57b..48ee536 100644
--- a/sys/powerpc/include/spr.h
+++ b/sys/powerpc/include/spr.h
@@ -10,13 +10,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/powerpc/mpc85xx/ocpbus.c b/sys/powerpc/mpc85xx/ocpbus.c
index 2adec47..6c6515e 100644
--- a/sys/powerpc/mpc85xx/ocpbus.c
+++ b/sys/powerpc/mpc85xx/ocpbus.c
@@ -152,6 +152,10 @@ ocpbus_write_law(int trgt, int type, u_long *startp, u_long *countp)
addr = 0xA0000000;
size = 0x10000000;
break;
+ case OCP85XX_TGTIF_PCI3:
+ addr = 0xB0000000;
+ size = 0x10000000;
+ break;
default:
return (EINVAL);
}
@@ -170,6 +174,10 @@ ocpbus_write_law(int trgt, int type, u_long *startp, u_long *countp)
addr = 0xfee20000;
size = 0x00010000;
break;
+ case OCP85XX_TGTIF_PCI3:
+ addr = 0xfee30000;
+ size = 0x00010000;
+ break;
default:
return (EINVAL);
}
@@ -188,7 +196,7 @@ static int
ocpbus_probe(device_t dev)
{
- device_set_desc(dev, "On-Chip Peripherals bus");
+ device_set_desc(dev, "Freescale on-chip peripherals bus");
return (BUS_PROBE_DEFAULT);
}
@@ -210,6 +218,7 @@ ocpbus_attach(device_t dev)
ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 0);
ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 1);
ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 2);
+ ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 3);
ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 0);
ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 1);
ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 2);
@@ -338,6 +347,10 @@ const struct ocp_resource mpc8555_resources[] = {
OCP85XX_PCI_SIZE},
{OCPBUS_DEVTYPE_PCIB, 2, SYS_RES_MEMORY, 1, 0, OCP85XX_TGTIF_PCI2},
{OCPBUS_DEVTYPE_PCIB, 2, SYS_RES_IOPORT, 1, 0, OCP85XX_TGTIF_PCI2},
+ {OCPBUS_DEVTYPE_PCIB, 3, SYS_RES_MEMORY, 0, OCP85XX_PCI3_OFF,
+ OCP85XX_PCI_SIZE},
+ {OCPBUS_DEVTYPE_PCIB, 3, SYS_RES_MEMORY, 1, 0, OCP85XX_TGTIF_PCI3},
+ {OCPBUS_DEVTYPE_PCIB, 3, SYS_RES_IOPORT, 1, 0, OCP85XX_TGTIF_PCI3},
{OCPBUS_DEVTYPE_LBC, 0, SYS_RES_MEMORY, 0, OCP85XX_LBC_OFF,
OCP85XX_LBC_SIZE},
diff --git a/sys/powerpc/mpc85xx/ocpbus.h b/sys/powerpc/mpc85xx/ocpbus.h
index 6aa6de3..fb715da 100644
--- a/sys/powerpc/mpc85xx/ocpbus.h
+++ b/sys/powerpc/mpc85xx/ocpbus.h
@@ -50,6 +50,7 @@
#define OCP85XX_TGTIF_PCI0 0
#define OCP85XX_TGTIF_PCI1 1
#define OCP85XX_TGTIF_PCI2 2
+#define OCP85XX_TGTIF_PCI3 3
#define OCP85XX_TGTIF_LBC 4
#define OCP85XX_TGTIF_RAM_INTL 11
#define OCP85XX_TGTIF_RIO 12
@@ -86,6 +87,7 @@
#define OCP85XX_PCI0_OFF 0x08000
#define OCP85XX_PCI1_OFF 0x09000
#define OCP85XX_PCI2_OFF 0x0A000
+#define OCP85XX_PCI3_OFF 0x0B000
#define OCP85XX_PCI_SIZE 0x1000
#define OCP85XX_TSEC0_OFF 0x24000
#define OCP85XX_TSEC1_OFF 0x25000
diff --git a/sys/powerpc/mpc85xx/pci_ocp.c b/sys/powerpc/mpc85xx/pci_ocp.c
index eba3f50..cdcf986 100644
--- a/sys/powerpc/mpc85xx/pci_ocp.c
+++ b/sys/powerpc/mpc85xx/pci_ocp.c
@@ -264,7 +264,7 @@ pci_ocp_maxslots(device_t dev)
{
struct pci_ocp_softc *sc = device_get_softc(dev);
- return ((sc->sc_pcie_cap) ? 0 : 30);
+ return ((sc->sc_pcie_cap) ? 0 : 31);
}
static uint32_t
@@ -328,6 +328,7 @@ pci_ocp_probe(device_t dev)
return (ENXIO);
sc = device_get_softc(dev);
+ sc->sc_dev = dev;
sc->sc_rid = 0;
sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
@@ -492,7 +493,7 @@ pci_ocp_route_int(struct pci_ocp_softc *sc, u_int bus, u_int slot, u_int func,
}
static int
-pci_ocp_init(struct pci_ocp_softc *sc, int bus, int maxslot)
+pci_ocp_init(struct pci_ocp_softc *sc, int bus, int nslots)
{
int secbus, slot;
int func, maxfunc;
@@ -502,7 +503,7 @@ pci_ocp_init(struct pci_ocp_softc *sc, int bus, int maxslot)
uint8_t intline, intpin;
secbus = bus;
- for (slot = 0; slot < maxslot; slot++) {
+ for (slot = 0; slot < nslots; slot++) {
maxfunc = 0;
for (func = 0; func <= maxfunc; func++) {
hdrtype = pci_ocp_read_config(sc->sc_dev, bus, slot,
@@ -599,7 +600,7 @@ pci_ocp_init(struct pci_ocp_softc *sc, int bus, int maxslot)
PCIR_SUBBUS_1, 0xff, 1);
secbus = pci_ocp_init(sc, secbus,
- (subclass == PCIS_BRIDGE_PCI) ? 31 : 1);
+ (subclass == PCIS_BRIDGE_PCI) ? 32 : 1);
pci_ocp_write_config(sc->sc_dev, bus, slot, func,
PCIR_SUBBUS_1, secbus, 1);
@@ -721,7 +722,7 @@ pci_ocp_attach(device_t dev)
{
struct pci_ocp_softc *sc;
uint32_t cfgreg;
- int error, maxslot;
+ int error, nslots;
sc = device_get_softc(dev);
sc->sc_dev = dev;
@@ -765,8 +766,8 @@ pci_ocp_attach(device_t dev)
return (0);
}
- maxslot = (sc->sc_pcie_cap) ? 1 : 31;
- pci_ocp_init(sc, sc->sc_busnr, maxslot);
+ nslots = (sc->sc_pcie_cap) ? 1 : 32;
+ pci_ocp_init(sc, sc->sc_busnr, nslots);
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
diff --git a/sys/powerpc/ofw/ofw_real.c b/sys/powerpc/ofw/ofw_real.c
index a65ee91..4425ad1 100644
--- a/sys/powerpc/ofw/ofw_real.c
+++ b/sys/powerpc/ofw/ofw_real.c
@@ -273,7 +273,7 @@ ofw_real_init(ofw_t ofw, void *openfirm)
static int
ofw_real_test(ofw_t ofw, const char *name)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -304,7 +304,7 @@ ofw_real_test(ofw_t ofw, const char *name)
static phandle_t
ofw_real_peer(ofw_t ofw, phandle_t node)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -326,7 +326,7 @@ ofw_real_peer(ofw_t ofw, phandle_t node)
static phandle_t
ofw_real_child(ofw_t ofw, phandle_t node)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -348,7 +348,7 @@ ofw_real_child(ofw_t ofw, phandle_t node)
static phandle_t
ofw_real_parent(ofw_t ofw, phandle_t node)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -370,7 +370,7 @@ ofw_real_parent(ofw_t ofw, phandle_t node)
static phandle_t
ofw_real_instance_to_package(ofw_t ofw, ihandle_t instance)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -392,7 +392,7 @@ ofw_real_instance_to_package(ofw_t ofw, ihandle_t instance)
static ssize_t
ofw_real_getproplen(ofw_t ofw, phandle_t package, const char *propname)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -422,7 +422,7 @@ static ssize_t
ofw_real_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf,
size_t buflen)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -458,7 +458,7 @@ static int
ofw_real_nextprop(ofw_t ofw, phandle_t package, const char *previous,
char *buf, size_t size)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -493,7 +493,7 @@ static int
ofw_real_setprop(ofw_t ofw, phandle_t package, const char *propname,
const void *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -526,7 +526,7 @@ ofw_real_setprop(ofw_t ofw, phandle_t package, const char *propname,
static ssize_t
ofw_real_canon(ofw_t ofw, const char *device, char *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -559,7 +559,7 @@ ofw_real_canon(ofw_t ofw, const char *device, char *buf, size_t len)
static phandle_t
ofw_real_finddevice(ofw_t ofw, const char *device)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -586,7 +586,7 @@ ofw_real_finddevice(ofw_t ofw, const char *device)
static ssize_t
ofw_real_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -619,7 +619,7 @@ ofw_real_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
static ssize_t
ofw_real_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -653,7 +653,7 @@ static int
ofw_real_call_method(ofw_t ofw, ihandle_t instance, const char *method,
int nargs, int nreturns, unsigned long *args_and_returns)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -701,7 +701,7 @@ ofw_real_call_method(ofw_t ofw, ihandle_t instance, const char *method,
static ihandle_t
ofw_real_open(ofw_t ofw, const char *device)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -729,7 +729,7 @@ ofw_real_open(ofw_t ofw, const char *device)
static void
ofw_real_close(ofw_t ofw, ihandle_t instance)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -737,6 +737,7 @@ ofw_real_close(ofw_t ofw, ihandle_t instance)
} args = {
(cell_t)"close",
1,
+ 0,
};
args.instance = instance;
@@ -747,7 +748,7 @@ ofw_real_close(ofw_t ofw, ihandle_t instance)
static ssize_t
ofw_real_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -780,7 +781,7 @@ ofw_real_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
static ssize_t
ofw_real_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -811,7 +812,7 @@ ofw_real_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
static int
ofw_real_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -841,7 +842,7 @@ ofw_real_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos)
static caddr_t
ofw_real_claim(ofw_t ofw, void *virt, size_t size, u_int align)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -867,7 +868,7 @@ ofw_real_claim(ofw_t ofw, void *virt, size_t size, u_int align)
static void
ofw_real_release(ofw_t ofw, void *virt, size_t size)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
@@ -876,6 +877,7 @@ ofw_real_release(ofw_t ofw, void *virt, size_t size)
} args = {
(cell_t)"release",
2,
+ 0,
};
args.virt = (cell_t)virt;
@@ -891,12 +893,14 @@ ofw_real_release(ofw_t ofw, void *virt, size_t size)
static void
ofw_real_enter(ofw_t ofw)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
} args = {
(cell_t)"enter",
+ 0,
+ 0,
};
openfirmware(&args);
@@ -907,12 +911,14 @@ ofw_real_enter(ofw_t ofw)
static void
ofw_real_exit(ofw_t ofw)
{
- static struct {
+ struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
} args = {
(cell_t)"exit",
+ 0,
+ 0,
};
openfirmware(&args);
diff --git a/sys/powerpc/ofw/ofw_syscons.c b/sys/powerpc/ofw/ofw_syscons.c
index 56d0ca8..d85cee5 100644
--- a/sys/powerpc/ofw/ofw_syscons.c
+++ b/sys/powerpc/ofw/ofw_syscons.c
@@ -55,10 +55,10 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_pci.h>
#include <powerpc/ofw/ofw_syscons.h>
-static int ofwfb_ignore_mmap_checks;
+static int ofwfb_ignore_mmap_checks = 1;
SYSCTL_NODE(_hw, OID_AUTO, ofwfb, CTLFLAG_RD, 0, "ofwfb");
SYSCTL_INT(_hw_ofwfb, OID_AUTO, relax_mmap, CTLFLAG_RW,
- &ofwfb_ignore_mmap_checks, 0, "relax mmap bounds checking");
+ &ofwfb_ignore_mmap_checks, 0, "relaxed mmap bounds checking");
extern u_char dflt_font_16[];
extern u_char dflt_font_14[];
diff --git a/sys/powerpc/powermac/cuda.c b/sys/powerpc/powermac/cuda.c
index 203889c..230298e 100644
--- a/sys/powerpc/powermac/cuda.c
+++ b/sys/powerpc/powermac/cuda.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/clock.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
@@ -55,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <dev/adb/adb.h>
+#include "clock_if.h"
#include "cudavar.h"
#include "viareg.h"
@@ -72,6 +74,12 @@ static u_int cuda_poll(device_t dev);
static void cuda_send_inbound(struct cuda_softc *sc);
static void cuda_send_outbound(struct cuda_softc *sc);
+/*
+ * Clock interface
+ */
+static int cuda_gettime(device_t dev, struct timespec *ts);
+static int cuda_settime(device_t dev, struct timespec *ts);
+
static device_method_t cuda_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, cuda_probe),
@@ -90,6 +98,10 @@ static device_method_t cuda_methods[] = {
DEVMETHOD(adb_hb_controller_poll, cuda_poll),
DEVMETHOD(adb_hb_set_autopoll_mask, cuda_adb_autopoll),
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, cuda_gettime),
+ DEVMETHOD(clock_settime, cuda_settime),
+
{ 0, 0 },
};
@@ -173,6 +185,7 @@ cuda_attach(device_t dev)
sc->sc_polling = 0;
sc->sc_state = CUDA_NOTREADY;
sc->sc_autopoll = 0;
+ sc->sc_rtc = -1;
STAILQ_INIT(&sc->sc_inq);
STAILQ_INIT(&sc->sc_outq);
@@ -236,6 +249,8 @@ cuda_attach(device_t dev)
}
}
+ clock_register(dev, 1000);
+
return (bus_generic_attach(dev));
}
@@ -444,8 +459,18 @@ cuda_send_inbound(struct cuda_softc *sc)
break;
case CUDA_PSEUDO:
mtx_lock(&sc->sc_mutex);
- if (pkt->data[0] == CMD_AUTOPOLL)
+ switch (pkt->data[1]) {
+ case CMD_AUTOPOLL:
sc->sc_autopoll = 1;
+ break;
+ case CMD_READ_RTC:
+ memcpy(&sc->sc_rtc, &pkt->data[2],
+ sizeof(sc->sc_rtc));
+ wakeup(&sc->sc_rtc);
+ break;
+ case CMD_WRITE_RTC:
+ break;
+ }
mtx_unlock(&sc->sc_mutex);
break;
case CUDA_ERROR:
@@ -715,3 +740,41 @@ cuda_adb_autopoll(device_t dev, uint16_t mask) {
return (0);
}
+#define DIFF19041970 2082844800
+
+static int
+cuda_gettime(device_t dev, struct timespec *ts)
+{
+ struct cuda_softc *sc = device_get_softc(dev);
+ uint8_t cmd[] = {CUDA_PSEUDO, CMD_READ_RTC};
+
+ mtx_lock(&sc->sc_mutex);
+ sc->sc_rtc = -1;
+ cuda_send(sc, 1, 2, cmd);
+ if (sc->sc_rtc == -1)
+ mtx_sleep(&sc->sc_rtc, &sc->sc_mutex, 0, "rtc", 100);
+
+ ts->tv_sec = sc->sc_rtc - DIFF19041970;
+ ts->tv_nsec = 0;
+ mtx_unlock(&sc->sc_mutex);
+
+ return (0);
+}
+
+static int
+cuda_settime(device_t dev, struct timespec *ts)
+{
+ struct cuda_softc *sc = device_get_softc(dev);
+ uint8_t cmd[] = {CUDA_PSEUDO, CMD_WRITE_RTC, 0, 0, 0, 0};
+ uint32_t sec;
+
+ sec = ts->tv_sec + DIFF19041970;
+ memcpy(&cmd[2], &sec, sizeof(sec));
+
+ mtx_lock(&sc->sc_mutex);
+ cuda_send(sc, 0, 6, cmd);
+ mtx_unlock(&sc->sc_mutex);
+
+ return (0);
+}
+
diff --git a/sys/powerpc/powermac/cudavar.h b/sys/powerpc/powermac/cudavar.h
index 02791cb..2254464 100644
--- a/sys/powerpc/powermac/cudavar.h
+++ b/sys/powerpc/powermac/cudavar.h
@@ -90,6 +90,7 @@ struct cuda_softc {
int sc_polling;
int sc_iic_done;
volatile int sc_autopoll;
+ uint32_t sc_rtc;
int sc_i2c_read_len;
diff --git a/sys/powerpc/powermac/pmu.c b/sys/powerpc/powermac/pmu.c
index 9ddba9e..a980622 100644
--- a/sys/powerpc/powermac/pmu.c
+++ b/sys/powerpc/powermac/pmu.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/clock.h>
#include <sys/sysctl.h>
#include <dev/ofw/ofw_bus.h>
@@ -55,16 +56,27 @@ __FBSDID("$FreeBSD$");
#include <dev/adb/adb.h>
+#include "clock_if.h"
#include "pmuvar.h"
#include "viareg.h"
/*
- * MacIO interface
+ * Bus interface
*/
static int pmu_probe(device_t);
static int pmu_attach(device_t);
static int pmu_detach(device_t);
+/*
+ * Clock interface
+ */
+static int pmu_gettime(device_t dev, struct timespec *ts);
+static int pmu_settime(device_t dev, struct timespec *ts);
+
+/*
+ * ADB Interface
+ */
+
static u_int pmu_adb_send(device_t dev, u_char command_byte, int len,
u_char *data, u_char poll);
static u_int pmu_adb_autopoll(device_t dev, uint16_t mask);
@@ -110,6 +122,10 @@ static device_method_t pmu_methods[] = {
DEVMETHOD(adb_hb_controller_poll, pmu_poll),
DEVMETHOD(adb_hb_set_autopoll_mask, pmu_adb_autopoll),
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, pmu_gettime),
+ DEVMETHOD(clock_settime, pmu_settime),
+
{ 0, 0 },
};
@@ -453,6 +469,12 @@ pmu_attach(device_t dev)
sc->sc_leddev = led_create(pmu_set_sleepled, sc, "sleepled");
+ /*
+ * Register RTC
+ */
+
+ clock_register(dev, 1000);
+
return (bus_generic_attach(dev));
}
@@ -926,3 +948,38 @@ pmu_battquery_sysctl(SYSCTL_HANDLER_ARGS)
return (error);
}
+#define DIFF19041970 2082844800
+
+static int
+pmu_gettime(device_t dev, struct timespec *ts)
+{
+ struct pmu_softc *sc = device_get_softc(dev);
+ uint8_t resp[16];
+ uint32_t sec;
+
+ mtx_lock(&sc->sc_mutex);
+ pmu_send(sc, PMU_READ_RTC, 0, NULL, 16, resp);
+ mtx_unlock(&sc->sc_mutex);
+
+ memcpy(&sec, &resp[1], 4);
+ ts->tv_sec = sec - DIFF19041970;
+ ts->tv_nsec = 0;
+
+ return (0);
+}
+
+static int
+pmu_settime(device_t dev, struct timespec *ts)
+{
+ struct pmu_softc *sc = device_get_softc(dev);
+ uint32_t sec;
+
+ sec = ts->tv_sec + DIFF19041970;
+
+ mtx_lock(&sc->sc_mutex);
+ pmu_send(sc, PMU_SET_RTC, sizeof(sec), (uint8_t *)&sec, 0, NULL);
+ mtx_unlock(&sc->sc_mutex);
+
+ return (0);
+}
+
diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c
index 061ac1c..1001876 100644
--- a/sys/powerpc/powermac/smu.c
+++ b/sys/powerpc/powermac/smu.c
@@ -32,16 +32,19 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/module.h>
-#include <sys/callout.h>
#include <sys/conf.h>
#include <sys/cpu.h>
+#include <sys/clock.h>
#include <sys/ctype.h>
#include <sys/kernel.h>
+#include <sys/kthread.h>
#include <sys/reboot.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
+#include <sys/unistd.h>
#include <machine/bus.h>
+#include <machine/intr_machdep.h>
#include <machine/md_var.h>
#include <dev/led/led.h>
@@ -49,12 +52,18 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <powerpc/powermac/macgpiovar.h>
+#include "clock_if.h"
+
struct smu_cmd {
volatile uint8_t cmd;
uint8_t len;
uint8_t data[254];
+
+ STAILQ_ENTRY(smu_cmd) cmd_q;
};
+STAILQ_HEAD(smu_cmdq, smu_cmd);
+
struct smu_fan {
cell_t reg;
cell_t min_rpm;
@@ -88,16 +97,21 @@ struct smu_softc {
bus_space_tag_t sc_bt;
bus_space_handle_t sc_mailbox;
- struct smu_cmd *sc_cmd;
+ struct smu_cmd *sc_cmd, *sc_cur_cmd;
bus_addr_t sc_cmd_phys;
bus_dmamap_t sc_cmd_dmamap;
+ struct smu_cmdq sc_cmdq;
struct smu_fan *sc_fans;
int sc_nfans;
struct smu_sensor *sc_sensors;
int sc_nsensors;
- struct callout sc_fanmgt_callout;
+ int sc_doorbellirqid;
+ struct resource *sc_doorbellirq;
+ void *sc_doorbellirqcookie;
+
+ struct proc *sc_fanmgt_proc;
time_t sc_lastuserchange;
/* Calibration data */
@@ -129,15 +143,21 @@ static int smu_attach(device_t);
static void smu_cpufreq_pre_change(device_t, const struct cf_level *level);
static void smu_cpufreq_post_change(device_t, const struct cf_level *level);
+/* clock interface */
+static int smu_gettime(device_t dev, struct timespec *ts);
+static int smu_settime(device_t dev, struct timespec *ts);
+
/* utility functions */
-static int smu_run_cmd(device_t dev, struct smu_cmd *cmd);
+static int smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait);
static int smu_get_datablock(device_t dev, int8_t id, uint8_t *buf,
size_t len);
static void smu_attach_fans(device_t dev, phandle_t fanroot);
static void smu_attach_sensors(device_t dev, phandle_t sensroot);
-static void smu_fanmgt_callout(void *xdev);
+static void smu_fan_management_proc(void *xdev);
+static void smu_manage_fans(device_t smu);
static void smu_set_sleepled(void *xdev, int onoff);
static int smu_server_mode(SYSCTL_HANDLER_ARGS);
+static void smu_doorbell_intr(void *xdev);
/* where to find the doorbell GPIO */
@@ -147,6 +167,10 @@ static device_method_t smu_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, smu_probe),
DEVMETHOD(device_attach, smu_attach),
+
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, smu_gettime),
+ DEVMETHOD(clock_settime, smu_settime),
{ 0, 0 },
};
@@ -162,7 +186,7 @@ DRIVER_MODULE(smu, nexus, smu_driver, smu_devclass, 0, 0);
MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor Information");
#define SMU_MAILBOX 0x8000860c
-#define SMU_FANMGT_INTERVAL 500 /* ms */
+#define SMU_FANMGT_INTERVAL 1000 /* ms */
/* Command types */
#define SMU_ADC 0xd8
@@ -179,6 +203,9 @@ MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor Information");
#define SMU_PWR_GET_POWERUP 0x00
#define SMU_PWR_SET_POWERUP 0x01
#define SMU_PWR_CLR_POWERUP 0x02
+#define SMU_RTC 0x8e
+#define SMU_RTC_GET 0x81
+#define SMU_RTC_SET 0x80
/* Power event types */
#define SMU_WAKEUP_KEYPRESS 0x01
@@ -227,6 +254,8 @@ smu_attach(device_t dev)
sc = device_get_softc(dev);
mtx_init(&sc->sc_mtx, "smu", NULL, MTX_DEF);
+ sc->sc_cur_cmd = NULL;
+ sc->sc_doorbellirqid = -1;
/*
* Map the mailbox area. This should be determined from firmware,
@@ -246,6 +275,7 @@ smu_attach(device_t dev)
BUS_DMA_ZERO, &sc->sc_cmd_dmamap);
bus_dmamap_load(sc->sc_dmatag, sc->sc_cmd_dmamap,
sc->sc_cmd, PAGE_SIZE, smu_phys_callback, sc, 0);
+ STAILQ_INIT(&sc->sc_cmdq);
/*
* Set up handlers to change CPU voltage when CPU frequency is changed.
@@ -304,8 +334,8 @@ smu_attach(device_t dev)
"critical_temp", CTLTYPE_INT | CTLFLAG_RW,
&sc->sc_critical_temp, sizeof(int), "Critical temperature (C)");
- callout_init(&sc->sc_fanmgt_callout, 1);
- smu_fanmgt_callout(dev);
+ kproc_create(smu_fan_management_proc, dev, &sc->sc_fanmgt_proc,
+ RFHIGHPID, 0, "smu_thermal");
/*
* Set up LED interface
@@ -321,24 +351,42 @@ smu_attach(device_t dev)
"server_mode", CTLTYPE_INT | CTLFLAG_RW, dev, 0,
smu_server_mode, "I", "Enable reboot after power failure");
+ /*
+ * Set up doorbell interrupt.
+ */
+ sc->sc_doorbellirqid = 0;
+ sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ,
+ &sc->sc_doorbellirqid, RF_ACTIVE);
+ bus_setup_intr(smu_doorbell, sc->sc_doorbellirq,
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev,
+ &sc->sc_doorbellirqcookie);
+ powerpc_config_intr(rman_get_start(sc->sc_doorbellirq),
+ INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
+
+ /*
+ * Connect RTC interface.
+ */
+ clock_register(dev, 1000);
+
return (0);
}
-static int
-smu_run_cmd(device_t dev, struct smu_cmd *cmd)
+static void
+smu_send_cmd(device_t dev, struct smu_cmd *cmd)
{
struct smu_softc *sc;
- int doorbell_ack, result, oldpow;
sc = device_get_softc(dev);
- mtx_lock(&sc->sc_mtx);
+ mtx_assert(&sc->sc_mtx, MA_OWNED);
- oldpow = powerpc_pow_enabled;
- powerpc_pow_enabled = 0;
+ powerpc_pow_enabled = 0; /* SMU cannot work if we go to NAP */
+ sc->sc_cur_cmd = cmd;
/* Copy the command to the mailbox */
- memcpy(sc->sc_cmd, cmd, sizeof(*cmd));
+ sc->sc_cmd->cmd = cmd->cmd;
+ sc->sc_cmd->len = cmd->len;
+ memcpy(sc->sc_cmd->data, cmd->data, sizeof(cmd->data));
bus_dmamap_sync(sc->sc_dmatag, sc->sc_cmd_dmamap, BUS_DMASYNC_PREWRITE);
bus_space_write_4(sc->sc_bt, sc->sc_mailbox, 0, sc->sc_cmd_phys);
@@ -347,33 +395,107 @@ smu_run_cmd(device_t dev, struct smu_cmd *cmd)
/* Ring SMU doorbell */
macgpio_write(smu_doorbell, GPIO_DDR_OUTPUT);
+}
- /* Wait for the doorbell GPIO to go high, signaling completion */
- do {
- /* XXX: timeout */
- DELAY(50);
- doorbell_ack = macgpio_read(smu_doorbell);
- } while (doorbell_ack != (GPIO_DDR_OUTPUT | GPIO_LEVEL_RO | GPIO_DATA));
+static void
+smu_doorbell_intr(void *xdev)
+{
+ device_t smu;
+ struct smu_softc *sc;
+ int doorbell_ack;
+
+ smu = xdev;
+ doorbell_ack = macgpio_read(smu_doorbell);
+ sc = device_get_softc(smu);
+
+ if (doorbell_ack != (GPIO_DDR_OUTPUT | GPIO_LEVEL_RO | GPIO_DATA))
+ return;
+
+ mtx_lock(&sc->sc_mtx);
+
+ if (sc->sc_cur_cmd == NULL) /* spurious */
+ goto done;
/* Check result. First invalidate the cache again... */
__asm __volatile("dcbf 0,%0; sync" :: "r"(sc->sc_cmd) : "memory");
bus_dmamap_sync(sc->sc_dmatag, sc->sc_cmd_dmamap, BUS_DMASYNC_POSTREAD);
- /* SMU acks the command by inverting the command bits */
- if (sc->sc_cmd->cmd == ((~cmd->cmd) & 0xff))
- result = 0;
- else
- result = EIO;
+ sc->sc_cur_cmd->cmd = sc->sc_cmd->cmd;
+ sc->sc_cur_cmd->len = sc->sc_cmd->len;
+ memcpy(sc->sc_cur_cmd->data, sc->sc_cmd->data,
+ sizeof(sc->sc_cmd->data));
+ wakeup(sc->sc_cur_cmd);
+ sc->sc_cur_cmd = NULL;
+ powerpc_pow_enabled = 1;
+
+ done:
+ /* Queue next command if one is pending */
+ if (STAILQ_FIRST(&sc->sc_cmdq) != NULL) {
+ sc->sc_cur_cmd = STAILQ_FIRST(&sc->sc_cmdq);
+ STAILQ_REMOVE_HEAD(&sc->sc_cmdq, cmd_q);
+ smu_send_cmd(smu, sc->sc_cur_cmd);
+ }
- powerpc_pow_enabled = oldpow;
+ mtx_unlock(&sc->sc_mtx);
+}
- memcpy(cmd->data, sc->sc_cmd->data, sizeof(cmd->data));
- cmd->len = sc->sc_cmd->len;
+static int
+smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait)
+{
+ struct smu_softc *sc;
+ uint8_t cmd_code;
+ int error;
+ sc = device_get_softc(dev);
+ cmd_code = cmd->cmd;
+
+ mtx_lock(&sc->sc_mtx);
+ if (sc->sc_cur_cmd != NULL) {
+ STAILQ_INSERT_TAIL(&sc->sc_cmdq, cmd, cmd_q);
+ } else
+ smu_send_cmd(dev, cmd);
mtx_unlock(&sc->sc_mtx);
- return (result);
+ if (!wait)
+ return (0);
+
+ if (sc->sc_doorbellirqid < 0) {
+ /* Poll if the IRQ has not been set up yet */
+ do {
+ DELAY(50);
+ smu_doorbell_intr(dev);
+ } while (sc->sc_cur_cmd != NULL);
+ } else {
+ /* smu_doorbell_intr will wake us when the command is ACK'ed */
+ error = tsleep(cmd, 0, "smu", 800 * hz / 1000);
+ if (error != 0)
+ smu_doorbell_intr(dev); /* One last chance */
+
+ if (error != 0) {
+ mtx_lock(&sc->sc_mtx);
+ if (cmd->cmd == cmd_code) { /* Never processed */
+ /* Abort this command if we timed out */
+ if (sc->sc_cur_cmd == cmd)
+ sc->sc_cur_cmd = NULL;
+ else
+ STAILQ_REMOVE(&sc->sc_cmdq, cmd, smu_cmd,
+ cmd_q);
+ mtx_unlock(&sc->sc_mtx);
+ return (error);
+ }
+ error = 0;
+ mtx_unlock(&sc->sc_mtx);
+ }
+ }
+
+ /* SMU acks the command by inverting the command bits */
+ if (cmd->cmd == ((~cmd_code) & 0xff))
+ error = 0;
+ else
+ error = EIO;
+
+ return (error);
}
static int
@@ -387,7 +509,7 @@ smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, size_t len)
cmd.data[0] = SMU_PARTITION_LATEST;
cmd.data[1] = id;
- smu_run_cmd(dev, &cmd);
+ smu_run_cmd(dev, &cmd, 1);
addr[0] = addr[1] = 0;
addr[2] = cmd.data[0];
@@ -400,7 +522,7 @@ smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, size_t len)
memcpy(&cmd.data[2], addr, sizeof(addr));
cmd.data[6] = len;
- smu_run_cmd(dev, &cmd);
+ smu_run_cmd(dev, &cmd, 1);
memcpy(buf, cmd.data, len);
return (0);
}
@@ -421,7 +543,7 @@ smu_slew_cpu_voltage(device_t dev, int to)
cmd.data[6] = 1;
cmd.data[7] = to;
- smu_run_cmd(dev, &cmd);
+ smu_run_cmd(dev, &cmd, 1);
}
static void
@@ -516,7 +638,7 @@ smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
cmd.data[2] = (rpm >> 8) & 0xff;
cmd.data[3] = rpm & 0xff;
- error = smu_run_cmd(smu, &cmd);
+ error = smu_run_cmd(smu, &cmd, 1);
if (error)
fan->old_style = 1;
}
@@ -527,7 +649,7 @@ smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
cmd.data[1] = 1 << fan->reg;
cmd.data[2 + 2*fan->reg] = (rpm >> 8) & 0xff;
cmd.data[3 + 2*fan->reg] = rpm & 0xff;
- error = smu_run_cmd(smu, &cmd);
+ error = smu_run_cmd(smu, &cmd, 1);
}
if (error == 0)
@@ -545,7 +667,7 @@ smu_fan_read_rpm(device_t smu, struct smu_fan *fan)
cmd.len = 1;
cmd.data[0] = 1;
- smu_run_cmd(smu, &cmd);
+ smu_run_cmd(smu, &cmd, 1);
return ((cmd.data[fan->reg*2+1] << 8) | cmd.data[fan->reg*2+2]);
}
@@ -651,17 +773,21 @@ smu_attach_fans(device_t dev, phandle_t fanroot)
}
static int
-smu_sensor_read(device_t smu, struct smu_sensor *sens)
+smu_sensor_read(device_t smu, struct smu_sensor *sens, int *val)
{
struct smu_cmd cmd;
struct smu_softc *sc;
int64_t value;
+ int error;
cmd.cmd = SMU_ADC;
cmd.len = 1;
cmd.data[0] = sens->reg;
+ error = 0;
- smu_run_cmd(smu, &cmd);
+ error = smu_run_cmd(smu, &cmd, 1);
+ if (error != 0)
+ return (error);
sc = device_get_softc(smu);
value = (cmd.data[0] << 8) | cmd.data[1];
@@ -674,9 +800,7 @@ smu_sensor_read(device_t smu, struct smu_sensor *sens)
value <<= 1;
/* Convert from 16.16 fixed point degC into integer C. */
- value *= 15625;
- value /= 1024;
- value /= 1000000;
+ value >>= 16;
break;
case SMU_VOLTAGE_SENSOR:
value *= sc->sc_cpu_volt_scale;
@@ -710,7 +834,8 @@ smu_sensor_read(device_t smu, struct smu_sensor *sens)
break;
}
- return (value);
+ *val = value;
+ return (0);
}
static int
@@ -725,7 +850,10 @@ smu_sensor_sysctl(SYSCTL_HANDLER_ARGS)
sc = device_get_softc(smu);
sens = &sc->sc_sensors[arg2];
- value = smu_sensor_read(smu, sens);
+ error = smu_sensor_read(smu, sens, &value);
+ if (error != 0)
+ return (error);
+
error = sysctl_handle_int(oidp, &value, 0, req);
return (error);
@@ -808,41 +936,32 @@ smu_attach_sensors(device_t dev, phandle_t sensroot)
}
}
-static int
-ms_to_ticks(int ms)
+static void
+smu_fan_management_proc(void *xdev)
{
- if (hz > 1000)
- return ms*(hz/1000);
+ device_t smu = xdev;
- return ms/(1000/hz);
-}
+ while(1) {
+ smu_manage_fans(smu);
+ pause("smu", SMU_FANMGT_INTERVAL * hz / 1000);
+ }
+}
static void
-smu_fanmgt_callout(void *xdev) {
- device_t smu = xdev;
+smu_manage_fans(device_t smu)
+{
struct smu_softc *sc;
- int i, maxtemp, temp, factor;
+ int i, maxtemp, temp, factor, error;
sc = device_get_softc(smu);
- if (time_uptime - sc->sc_lastuserchange < 3) {
- /*
- * If we have heard from a user process in the last 3 seconds,
- * go away.
- */
-
- callout_reset(&sc->sc_fanmgt_callout,
- ms_to_ticks(SMU_FANMGT_INTERVAL), smu_fanmgt_callout, smu);
- return;
- }
-
maxtemp = 0;
for (i = 0; i < sc->sc_nsensors; i++) {
if (sc->sc_sensors[i].type != SMU_TEMP_SENSOR)
continue;
- temp = smu_sensor_read(smu, &sc->sc_sensors[i]);
- if (temp > maxtemp)
+ error = smu_sensor_read(smu, &sc->sc_sensors[i], &temp);
+ if (error == 0 && temp > maxtemp)
maxtemp = temp;
}
@@ -865,8 +984,19 @@ smu_fanmgt_callout(void *xdev) {
"more than 20 degrees over target temperature (%d C)!\n",
maxtemp, sc->sc_target_temp);
- if (maxtemp > sc->sc_target_temp)
+ if (time_uptime - sc->sc_lastuserchange < 3) {
+ /*
+ * If we have heard from a user process in the last 3 seconds,
+ * go away.
+ */
+
+ return;
+ }
+
+ if (maxtemp - sc->sc_target_temp > 4)
factor = 110;
+ else if (maxtemp - sc->sc_target_temp > 1)
+ factor = 105;
else if (sc->sc_target_temp - maxtemp > 4)
factor = 90;
else if (sc->sc_target_temp - maxtemp > 1)
@@ -877,15 +1007,12 @@ smu_fanmgt_callout(void *xdev) {
for (i = 0; i < sc->sc_nfans; i++)
smu_fan_set_rpm(smu, &sc->sc_fans[i],
(sc->sc_fans[i].setpoint * factor) / 100);
-
- callout_reset(&sc->sc_fanmgt_callout,
- ms_to_ticks(SMU_FANMGT_INTERVAL), smu_fanmgt_callout, smu);
}
static void
smu_set_sleepled(void *xdev, int onoff)
{
- struct smu_cmd cmd;
+ static struct smu_cmd cmd;
device_t smu = xdev;
cmd.cmd = SMU_MISC;
@@ -894,7 +1021,7 @@ smu_set_sleepled(void *xdev, int onoff)
cmd.data[1] = 0;
cmd.data[2] = onoff;
- smu_run_cmd(smu, &cmd);
+ smu_run_cmd(smu, &cmd, 0);
}
static int
@@ -909,7 +1036,7 @@ smu_server_mode(SYSCTL_HANDLER_ARGS)
cmd.len = 1;
cmd.data[0] = SMU_PWR_GET_POWERUP;
- error = smu_run_cmd(smu, &cmd);
+ error = smu_run_cmd(smu, &cmd, 1);
if (error)
return (error);
@@ -932,6 +1059,54 @@ smu_server_mode(SYSCTL_HANDLER_ARGS)
cmd.data[1] = 0;
cmd.data[2] = SMU_WAKEUP_AC_INSERT;
- return (smu_run_cmd(smu, &cmd));
+ return (smu_run_cmd(smu, &cmd, 1));
+}
+
+static int
+smu_gettime(device_t dev, struct timespec *ts)
+{
+ struct smu_cmd cmd;
+ struct clocktime ct;
+
+ cmd.cmd = SMU_RTC;
+ cmd.len = 1;
+ cmd.data[0] = SMU_RTC_GET;
+
+ if (smu_run_cmd(dev, &cmd, 1) != 0)
+ return (ENXIO);
+
+ ct.nsec = 0;
+ ct.sec = bcd2bin(cmd.data[0]);
+ ct.min = bcd2bin(cmd.data[1]);
+ ct.hour = bcd2bin(cmd.data[2]);
+ ct.dow = bcd2bin(cmd.data[3]);
+ ct.day = bcd2bin(cmd.data[4]);
+ ct.mon = bcd2bin(cmd.data[5]);
+ ct.year = bcd2bin(cmd.data[6]) + 2000;
+
+ return (clock_ct_to_ts(&ct, ts));
+}
+
+static int
+smu_settime(device_t dev, struct timespec *ts)
+{
+ struct smu_cmd cmd;
+ struct clocktime ct;
+
+ cmd.cmd = SMU_RTC;
+ cmd.len = 8;
+ cmd.data[0] = SMU_RTC_SET;
+
+ clock_ts_to_ct(ts, &ct);
+
+ cmd.data[1] = bin2bcd(ct.sec);
+ cmd.data[2] = bin2bcd(ct.min);
+ cmd.data[3] = bin2bcd(ct.hour);
+ cmd.data[4] = bin2bcd(ct.dow);
+ cmd.data[5] = bin2bcd(ct.day);
+ cmd.data[6] = bin2bcd(ct.mon);
+ cmd.data[7] = bin2bcd(ct.year - 2000);
+
+ return (smu_run_cmd(dev, &cmd, 1));
}
diff --git a/sys/powerpc/powermac/uninorth.c b/sys/powerpc/powermac/uninorth.c
index d9de1af..fb3c990 100644
--- a/sys/powerpc/powermac/uninorth.c
+++ b/sys/powerpc/powermac/uninorth.c
@@ -611,7 +611,7 @@ unin_chip_probe(device_t dev)
if (name == NULL)
return (ENXIO);
- if (strcmp(name, "uni-n") != 0)
+ if (strcmp(name, "uni-n") != 0 && strcmp(name, "u3") != 0)
return (ENXIO);
device_set_desc(dev, "Apple UniNorth System Controller");
@@ -622,7 +622,8 @@ static int
unin_chip_attach(device_t dev)
{
phandle_t node;
- u_int reg[2];
+ u_int reg[3];
+ int i = 0;
uncsc = device_get_softc(dev);
node = ofw_bus_get_node(dev);
@@ -630,14 +631,18 @@ unin_chip_attach(device_t dev)
if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8)
return (ENXIO);
- uncsc->sc_physaddr = reg[0];
- uncsc->sc_size = reg[1];
+ if (strcmp(ofw_bus_get_name(dev), "u3") == 0)
+ i = 1; /* #address-cells lies */
+
+ uncsc->sc_physaddr = reg[i];
+ uncsc->sc_size = reg[i+1];
/*
* Only map the first page, since that is where the registers
* of interest lie.
*/
- uncsc->sc_addr = (vm_offset_t) pmap_mapdev(reg[0], PAGE_SIZE);
+ uncsc->sc_addr = (vm_offset_t) pmap_mapdev(uncsc->sc_physaddr,
+ PAGE_SIZE);
uncsc->sc_version = *(u_int *)uncsc->sc_addr;
device_printf(dev, "Version %d\n", uncsc->sc_version);
diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c
index d02c156..555172a 100644
--- a/sys/powerpc/powerpc/cpu.c
+++ b/sys/powerpc/powerpc/cpu.c
@@ -433,6 +433,13 @@ cpu_e500_setup(int cpuid, uint16_t vers)
register_t hid0;
hid0 = mfspr(SPR_HID0);
+
+ /* Programe power-management mode. */
+ hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
+ hid0 |= HID0_DOZE;
+
+ mtspr(SPR_HID0, hid0);
+
printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK);
}
diff --git a/sys/powerpc/powerpc/mmu_if.m b/sys/powerpc/powerpc/mmu_if.m
index 5b8ba14..a87e5d8 100644
--- a/sys/powerpc/powerpc/mmu_if.m
+++ b/sys/powerpc/powerpc/mmu_if.m
@@ -346,6 +346,20 @@ METHOD boolean_t is_prefaultable {
/**
+ * @brief Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ *
+ * @params _pg physical page
+ *
+ * @retval boolean TRUE if page has been referenced
+ */
+METHOD boolean_t is_referenced {
+ mmu_t _mmu;
+ vm_page_t _pg;
+};
+
+
+/**
* @brief Return a count of referenced bits for a page, clearing those bits.
* Not all referenced bits need to be cleared, but it is necessary that 0
* only be returned when there are none set.
diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c
index 2b45e17..c16360f 100644
--- a/sys/powerpc/powerpc/pmap_dispatch.c
+++ b/sys/powerpc/powerpc/pmap_dispatch.c
@@ -195,6 +195,14 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t va)
}
boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+ CTR2(KTR_PMAP, "%s(%p)", __func__, m);
+ return (MMU_IS_REFERENCED(mmu_obj, m));
+}
+
+boolean_t
pmap_ts_referenced(vm_page_t m)
{
diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c
index a594894..8678a18 100644
--- a/sys/rpc/svc.c
+++ b/sys/rpc/svc.c
@@ -819,9 +819,11 @@ svc_getreq(SVCXPRT *xprt, struct svc_req **rqstp_ret)
free(r->rq_addr, M_SONAME);
r->rq_addr = NULL;
}
+ m_freem(args);
goto call_done;
default:
+ m_freem(args);
goto call_done;
}
}
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 1c4d45b..9ce2d6c 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -47,7 +47,6 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options COMPAT_FREEBSD6 # Compatible with FreeBSD6
options COMPAT_FREEBSD7 # Compatible with FreeBSD7
@@ -144,6 +143,9 @@ device mk48txx # Mostek MK48Txx clocks
device rtc # rtc (really a front-end for the MC146818)
device mc146818 # Motorola MC146818 and compatible clocks
device epic # Sun Fire V215/V245 LEDs
+device sbbc # Sun BootBus controller (time-of-day clock for
+ # Serengeti and StarCat, console for Serengeti,
+ # requires device uart)
# Serial (COM) ports
device puc # Multi-channel uarts
@@ -224,6 +226,7 @@ device firmware # firmware assist module
device bpf # Berkeley packet filter
# USB support
+options USB_DEBUG # enable debug msgs
device uhci # UHCI PCI->USB interface
device ohci # OHCI PCI->USB interface
device ehci # EHCI PCI->USB interface (USB 2.0)
diff --git a/sys/sparc64/conf/NOTES b/sys/sparc64/conf/NOTES
index d9c5be5..5e02289 100644
--- a/sys/sparc64/conf/NOTES
+++ b/sys/sparc64/conf/NOTES
@@ -37,6 +37,7 @@ device eeprom # eeprom (really a front-end for the MK48Txx)
device mk48txx # Mostek MK48Txx clocks
device rtc # rtc (really a front-end for the MC146818)
device mc146818 # Motorola MC146818 and compatible clocks
+device sbbc # Sun BootBus controller
#
# Optional devices:
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index 6aefffa..2b15e5e 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -208,7 +208,7 @@ fhc_attach(device_t dev)
printf("model unknown\n");
for (i = FHC_FANFAIL; i <= FHC_TOD; i++) {
- bus_write_4(sc->sc_memres[i], FHC_ICLR, 0x0);
+ bus_write_4(sc->sc_memres[i], FHC_ICLR, INTCLR_IDLE);
(void)bus_read_4(sc->sc_memres[i], FHC_ICLR);
}
@@ -391,7 +391,7 @@ fhc_intr_clear(void *arg)
struct intr_vector *iv = arg;
struct fhc_icarg *fica = iv->iv_icarg;
- bus_write_4(fica->fica_memres, FHC_ICLR, 0x0);
+ bus_write_4(fica->fica_memres, FHC_ICLR, INTCLR_IDLE);
(void)bus_read_4(fica->fica_memres, FHC_ICLR);
}
diff --git a/sys/sparc64/include/_inttypes.h b/sys/sparc64/include/_inttypes.h
index e6b2536..a7cbea5 100644
--- a/sys/sparc64/include/_inttypes.h
+++ b/sys/sparc64/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/sparc64/include/dcr.h b/sys/sparc64/include/dcr.h
index a885d05..42159ad 100644
--- a/sys/sparc64/include/dcr.h
+++ b/sys/sparc64/include/dcr.h
@@ -43,8 +43,8 @@
#define DCR_OBSDATA_CT_MASK \
(((1UL << DCR_OBSDATA_CT_BITS) - 1) << DCR_OBSDATA_SHIFT)
-/* The following bits are valid for the UltraSPARC-III+/IV+ only. */
-#define DCR_IPE (1UL << 5)
+/* The following bits are valid for the UltraSPARC-III++/IV+ only. */
+#define DCR_IPE (1UL << 2)
#define DCR_OBSDATA_CTP_BITS 6
#define DCR_OBSDATA_CTP_MASK \
@@ -57,6 +57,10 @@
#define DCR_BPM_BITS 2
#define DCR_BPM_MASK \
(((1UL << DCR_BPM_BITS) - 1) << DCR_BPM_SHIFT)
+#define DCR_BPM_1HIST_GSHARE (0UL << DCR_BPM_SHIFT)
+#define DCR_BPM_2HIST_GSHARE (1UL << DCR_BPM_SHIFT)
+#define DCR_BPM_PC (2UL << DCR_BPM_SHIFT)
+#define DCR_BPM_2HIST_MIXED (3UL << DCR_BPM_SHIFT)
#define DCR_JPE (1UL << 15)
#define DCR_ITPE (1UL << 16)
diff --git a/sys/sparc64/include/lsu.h b/sys/sparc64/include/lsu.h
index a8787dc..5eeaa55 100644
--- a/sys/sparc64/include/lsu.h
+++ b/sys/sparc64/include/lsu.h
@@ -29,7 +29,7 @@
/*
* Definitions for the Load-Store-Unit Control Register. This is called
- * Data Cache Unit Control Register (DCUCR) for UltraSPARC-III.
+ * Data Cache Unit Control Register (DCUCR) for UltraSPARC-III and greater.
*/
#define LSU_IC (1UL << 0)
#define LSU_DC (1UL << 1)
@@ -41,7 +41,7 @@
#define LSU_FM_BITS 16
#define LSU_FM_MASK (((1UL << LSU_FM_BITS) - 1) << LSU_FM_SHIFT)
-#define LSU_VM_SHIFT 25
+#define LSU_VM_SHIFT 25
#define LSU_VM_BITS 8
#define LSU_VM_MASK (((1UL << LSU_VM_BITS) - 1) << LSU_VM_SHIFT)
@@ -65,4 +65,22 @@
#define LSU_CV (1UL << 48)
#define LSU_CP (1UL << 49)
+/* The following bit is valid for the UltraSPARC-IV only. */
+#define LSU_WIH (1UL << 4)
+
+/* The following bits are valid for the UltraSPARC-IV+ only. */
+#define LSU_PPS_SHIFT 50
+#define LSU_PPS_BITS 2
+#define LSU_PPS_MASK (((1UL << LSU_PPS_BITS) - 1) << LSU_PPS_SHIFT)
+
+#define LSU_IPS_SHIFT 52
+#define LSU_IPS_BITS 2
+#define LSU_IPS_MASK (((1UL << LSU_IPS_BITS) - 1) << LSU_IPS_SHIFT)
+
+#define LSU_PCM (1UL << 54)
+#define LSU_WCE (1UL << 55)
+
+/* The following bit is valid for the SPARC64 V, VI, VII and VIIIfx only. */
+#define LSU_WEAK_SPCA (1UL << 41)
+
#endif /* _MACHINE_LSU_H_ */
diff --git a/sys/sparc64/include/ofw_machdep.h b/sys/sparc64/include/ofw_machdep.h
index 625b131..658d9c7 100644
--- a/sys/sparc64/include/ofw_machdep.h
+++ b/sys/sparc64/include/ofw_machdep.h
@@ -36,6 +36,7 @@ typedef uint64_t cell_t;
int OF_decode_addr(phandle_t, int, int *, bus_addr_t *);
void OF_getetheraddr(device_t, u_char *);
+u_int OF_getscsinitid(device_t);
void cpu_shutdown(void *);
int ofw_entry(void *);
void ofw_exit(void *);
diff --git a/sys/sparc64/include/proc.h b/sys/sparc64/include/proc.h
index bfd1268..84eaed5 100644
--- a/sys/sparc64/include/proc.h
+++ b/sys/sparc64/include/proc.h
@@ -51,4 +51,6 @@ struct mdproc {
void *md_sigtramp;
};
+#define KINFO_PROC_SIZE 1088
+
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/sparc64/include/tlb.h b/sys/sparc64/include/tlb.h
index f0a4a7b..b813b0f 100644
--- a/sys/sparc64/include/tlb.h
+++ b/sys/sparc64/include/tlb.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2001 Jake Burkholder.
+ * Copyright (c) 2008, 2010 Marius Strobl <marius@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,11 +36,11 @@
#define TLB_DIRECT_ADDRESS_MASK ((1UL << TLB_DIRECT_ADDRESS_BITS) - 1)
#define TLB_DIRECT_PAGE_MASK ((1UL << TLB_DIRECT_PAGE_BITS) - 1)
-#define TLB_PHYS_TO_DIRECT(pa) \
+#define TLB_PHYS_TO_DIRECT(pa) \
((pa) | VM_MIN_DIRECT_ADDRESS)
-#define TLB_DIRECT_TO_PHYS(va) \
+#define TLB_DIRECT_TO_PHYS(va) \
((va) & TLB_DIRECT_ADDRESS_MASK)
-#define TLB_DIRECT_TO_TTE_MASK \
+#define TLB_DIRECT_TO_TTE_MASK \
(TD_V | TD_4M | (TLB_DIRECT_ADDRESS_MASK - TLB_DIRECT_PAGE_MASK))
#define TLB_DAR_SLOT_SHIFT (3)
@@ -56,18 +57,21 @@
(((1UL << TLB_CXR_CTX_BITS) - 1) << TLB_CXR_CTX_SHIFT)
#define TLB_CXR_CTX_SHIFT (0)
#define TLB_CXR_PGSZ_BITS (3)
-#define TLB_PCXR_PGSZ_MASK \
- ((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ0_SHIFT) | \
- (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ1_SHIFT) | \
- (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ0_SHIFT) | \
- (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ1_SHIFT))
+#define TLB_CXR_PGSZ_MASK (~TLB_CXR_CTX_MASK)
+#define TLB_PCXR_N_IPGSZ0_SHIFT (53) /* SPARC64 VI, VII, VIIIfx */
+#define TLB_PCXR_N_IPGSZ1_SHIFT (50) /* SPARC64 VI, VII, VIIIfx */
#define TLB_PCXR_N_PGSZ0_SHIFT (61)
#define TLB_PCXR_N_PGSZ1_SHIFT (58)
+#define TLB_PCXR_N_PGSZ_I_SHIFT (55) /* US-IV+ */
+#define TLB_PCXR_P_IPGSZ0_SHIFT (24) /* SPARC64 VI, VII, VIIIfx */
+#define TLB_PCXR_P_IPGSZ1_SHIFT (27) /* SPARC64 VI, VII, VIIIfx */
#define TLB_PCXR_P_PGSZ0_SHIFT (16)
#define TLB_PCXR_P_PGSZ1_SHIFT (19)
-#define TLB_SCXR_PGSZ_MASK \
- ((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ0_SHIFT) | \
- (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ1_SHIFT))
+/*
+ * Note that the US-IV+ documentation appears to have TLB_PCXR_P_PGSZ_I_SHIFT
+ * and TLB_PCXR_P_PGSZ0_SHIFT erroneously inverted.
+ */
+#define TLB_PCXR_P_PGSZ_I_SHIFT (22) /* US-IV+ */
#define TLB_SCXR_S_PGSZ1_SHIFT (19)
#define TLB_SCXR_S_PGSZ0_SHIFT (16)
@@ -87,7 +91,7 @@
#define TLB_DEMAP_TYPE_SHIFT (6)
#define TLB_DEMAP_TYPE_PAGE (0)
#define TLB_DEMAP_TYPE_CONTEXT (1)
-#define TLB_DEMAP_TYPE_ALL (2) /* USIII and beyond only */
+#define TLB_DEMAP_TYPE_ALL (2) /* US-III and beyond only */
#define TLB_DEMAP_VA(va) ((va) & ~PAGE_MASK)
#define TLB_DEMAP_ID(id) ((id) << TLB_DEMAP_ID_SHIFT)
@@ -118,9 +122,17 @@
#define MMU_SFSR_FT_SIZE (6)
#define MMU_SFSR_CT_SIZE (2)
-#define MMU_SFSR_GET_ASI(sfsr) \
+#define MMU_SFSR_GET_ASI(sfsr) \
(((sfsr) >> MMU_SFSR_ASI_SHIFT) & ((1UL << MMU_SFSR_ASI_SIZE) - 1))
+#define MMU_SFSR_GET_FT(sfsr) \
+ (((sfsr) >> MMU_SFSR_FT_SHIFT) & ((1UL << MMU_SFSR_FT_SIZE) - 1))
+#define MMU_SFSR_GET_CT(sfsr) \
+ (((sfsr) >> MMU_SFSR_CT_SHIFT) & ((1UL << MMU_SFSR_CT_SIZE) - 1))
+
+#define MMU_SFSR_E (1UL << MMU_SFSR_E_SHIFT)
+#define MMU_SFSR_PR (1UL << MMU_SFSR_PR_SHIFT)
#define MMU_SFSR_W (1UL << MMU_SFSR_W_SHIFT)
+#define MMU_SFSR_OW (1UL << MMU_SFSR_OW_SHIFT)
#define MMU_SFSR_FV (1UL << MMU_SFSR_FV_SHIFT)
typedef void tlb_flush_nonlocked_t(void);
diff --git a/sys/sparc64/include/tte.h b/sys/sparc64/include/tte.h
index 421bc16..ff60342 100644
--- a/sys/sparc64/include/tte.h
+++ b/sys/sparc64/include/tte.h
@@ -36,25 +36,42 @@
#define TD_SIZE_SHIFT (61)
#define TD_SOFT2_SHIFT (50)
+#define TD_RSVD2_SHIFT (49)
+#define TD_SIZE2_SHIFT (48)
#define TD_DIAG_SF_SHIFT (41)
#define TD_RSVD_CH_SHIFT (43)
+#define TD_RSVD_OC_SHIFT (47)
+#define TD_RSVD_PT_SHIFT TD_RSVD_CH_SHIFT
+#define TD_RSVD_VE_SHIFT (41)
#define TD_PA_SHIFT (13)
#define TD_SOFT_SHIFT (7)
#define TD_SIZE_BITS (2)
#define TD_SOFT2_BITS (9)
-#define TD_DIAG_SF_BITS (9)
-#define TD_RSVD_CH_BITS (7)
-#define TD_PA_CH_BITS (30)
-#define TD_PA_SF_BITS (28)
+#define TD_RSVD2_BITS (1) /* US-IV+, SPARC64 VI, VII, VIIIfx */
+#define TD_SIZE2_BITS (1) /* US-IV+, SPARC64 VI, VII, VIIIfx */
+#define TD_DIAG_SF_BITS (9) /* US-I, II{,e,i} */
+#define TD_RSVD_CH_BITS (7) /* US-III{,i,+}, US-IV, SPARC64 V */
+#define TD_RSVD_OC_BITS (1) /* SPARC64 VI, VII */
+#define TD_RSVD_PT_BITS (5) /* US-IV+, SPARC64 VI, VII */
+#define TD_RSVD_VE_BITS (7) /* SPARC64 VIIIfx */
+#define TD_PA_CH_BITS (30) /* US-III{,i,+}, US-IV{,+}, SPARC64 V */
+#define TD_PA_OC_BITS (34) /* SPARC64 VI, VII */
+#define TD_PA_SF_BITS (28) /* US-I, II{,e,i}, SPARC64 VIIIfx */
#define TD_PA_BITS TD_PA_CH_BITS
#define TD_SOFT_BITS (6)
#define TD_SIZE_MASK ((1UL << TD_SIZE_BITS) - 1)
#define TD_SOFT2_MASK ((1UL << TD_SOFT2_BITS) - 1)
+#define TD_RSVD2_MASK ((1UL << TD_RSVD2_BITS) - 1)
+#define TD_SIZE2_MASK ((1UL << TD_SIZE2_BITS) - 1)
#define TD_DIAG_SF_MASK ((1UL << TD_DIAG_SF_BITS) - 1)
#define TD_RSVD_CH_MASK ((1UL << TD_RSVD_CH_BITS) - 1)
+#define TD_RSVD_OC_MASK ((1UL << TD_RSVD_OC_BITS) - 1)
+#define TD_RSVD_PT_MASK ((1UL << TD_RSVD_PT_BITS) - 1)
+#define TD_RSVD_VE_MASK ((1UL << TD_RSVD_VE_BITS) - 1)
#define TD_PA_CH_MASK ((1UL << TD_PA_CH_BITS) - 1)
+#define TD_PA_OC_MASK ((1UL << TD_PA_OC_BITS) - 1)
#define TD_PA_SF_MASK ((1UL << TD_PA_SF_BITS) - 1)
#define TD_PA_MASK ((1UL << TD_PA_BITS) - 1)
#define TD_SOFT_MASK ((1UL << TD_SOFT_BITS) - 1)
@@ -63,6 +80,9 @@
#define TS_64K (1UL)
#define TS_512K (2UL)
#define TS_4M (3UL)
+#define TS_32M (4UL) /* US-IV+, SPARC64 VI, VII only */
+#define TS_256M (5UL) /* US-IV+, SPARC64 VI, VII only */
+#define TS_2G (6UL) /* SPARC64 VIIIfx only */
#define TS_MIN TS_8K
#define TS_MAX TS_4M
@@ -72,6 +92,15 @@
#define TD_64K (TS_64K << TD_SIZE_SHIFT)
#define TD_512K (TS_512K << TD_SIZE_SHIFT)
#define TD_4M (TS_4M << TD_SIZE_SHIFT)
+#define TD_32M \
+ (((TS_32M & TD_SIZE_MASK) << TD_SIZE_SHIFT) | \
+ (TD_SIZE2_MASK << TD_SIZE2_SHIFT))
+#define TD_256M \
+ (((TS_256M & TD_SIZE_MASK) << TD_SIZE_SHIFT) | \
+ (TD_SIZE2_MASK << TD_SIZE2_SHIFT))
+#define TD_2G \
+ (((TS_2G & TD_SIZE_MASK) << TD_SIZE_SHIFT) | \
+ (TD_SIZE2_MASK << TD_SIZE2_SHIFT))
#define TD_NFO (1UL << 60)
#define TD_IE (1UL << 59)
#define TD_PA(pa) ((pa) & (TD_PA_MASK << TD_PA_SHIFT))
@@ -94,29 +123,28 @@
#define TV_VPN(va, sz) ((((va) >> TTE_PAGE_SHIFT(sz)) << TV_SIZE_BITS) | sz)
#define TTE_SIZE_SPREAD (3)
-#define TTE_PAGE_SHIFT(sz) \
+#define TTE_PAGE_SHIFT(sz) \
(PAGE_SHIFT + ((sz) * TTE_SIZE_SPREAD))
-#define TTE_GET_SIZE(tp) \
+#define TTE_GET_SIZE(tp) \
(((tp)->tte_data >> TD_SIZE_SHIFT) & TD_SIZE_MASK)
-#define TTE_GET_PAGE_SHIFT(tp) \
+#define TTE_GET_PAGE_SHIFT(tp) \
TTE_PAGE_SHIFT(TTE_GET_SIZE(tp))
-#define TTE_GET_PAGE_SIZE(tp) \
+#define TTE_GET_PAGE_SIZE(tp) \
(1 << TTE_GET_PAGE_SHIFT(tp))
-#define TTE_GET_PAGE_MASK(tp) \
+#define TTE_GET_PAGE_MASK(tp) \
(TTE_GET_PAGE_SIZE(tp) - 1)
-#define TTE_GET_PA(tp) \
+#define TTE_GET_PA(tp) \
((tp)->tte_data & (TD_PA_MASK << TD_PA_SHIFT))
-#define TTE_GET_VPN(tp) \
+#define TTE_GET_VPN(tp) \
((tp)->tte_vpn >> TV_SIZE_BITS)
-#define TTE_GET_VA(tp) \
+#define TTE_GET_VA(tp) \
(TTE_GET_VPN(tp) << TTE_GET_PAGE_SHIFT(tp))
-#define TTE_GET_PMAP(tp) \
- (((tp)->tte_data & TD_P) != 0 ? \
- (kernel_pmap) : \
- (PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)(tp)))->md.pmap))
-#define TTE_ZERO(tp) \
+#define TTE_GET_PMAP(tp) \
+ (((tp)->tte_data & TD_P) != 0 ? (kernel_pmap) : \
+ (PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)(tp)))->md.pmap))
+#define TTE_ZERO(tp) \
memset(tp, 0, sizeof(*tp))
struct pmap;
@@ -130,6 +158,7 @@ struct tte {
static __inline int
tte_match(struct tte *tp, vm_offset_t va)
{
+
return (((tp->tte_data & TD_V) != 0) &&
(tp->tte_vpn == TV_VPN(va, TTE_GET_SIZE(tp))));
}
diff --git a/sys/sparc64/include/ver.h b/sys/sparc64/include/ver.h
index ad6841b..19547ba 100644
--- a/sys/sparc64/include/ver.h
+++ b/sys/sparc64/include/ver.h
@@ -69,8 +69,15 @@ extern char sparc64_model[];
#endif /* !LOCORE */
-/* Known implementations. */
+/* Known implementations */
#define CPU_IMPL_SPARC64 0x01
+#define CPU_IMPL_SPARC64II 0x02
+#define CPU_IMPL_SPARC64III 0x03
+#define CPU_IMPL_SPARC64IV 0x04
+#define CPU_IMPL_SPARC64V 0x05
+#define CPU_IMPL_SPARC64VI 0x06
+#define CPU_IMPL_SPARC64VII 0x07
+#define CPU_IMPL_SPARC64VIIIfx 0x08
#define CPU_IMPL_ULTRASPARCI 0x10
#define CPU_IMPL_ULTRASPARCII 0x11
#define CPU_IMPL_ULTRASPARCIIi 0x12
diff --git a/sys/sparc64/include/wstate.h b/sys/sparc64/include/wstate.h
index 7ce0a49..aae2fda 100644
--- a/sys/sparc64/include/wstate.h
+++ b/sys/sparc64/include/wstate.h
@@ -33,7 +33,7 @@
#define _MACHINE_WSTATE_H_
/*
- * Window state register bits.
+ * Window state register bits
*
* There really are no bits per se, just the two fields WSTATE.NORMAL
* and WSTATE.OTHER. The rest is up to software.
@@ -42,37 +42,8 @@
* (whichever is currently in effect) and WSTATE_OTHER to represent
* user mode saves (only).
*
- * We use the low bit to suggest 32-bit mode, with the next bit set
- * once we succeed in saving in some mode. That is, if the WSTATE_ASSUME
- * bit is set, the spill or fill handler we use will be one that makes
- * an assumption about the proper window-save mode. If the spill or
- * fill fails with an alignment fault, the spill or fill op should
- * take the `assume' bit away retry the instruction that caused the
- * spill or fill. This will use the new %wstate, which will test for
- * which mode to use. The alignment fault code helps us out here by
- * resuming the spill vector at offset +70, where we are allowed to
- * execute two instructions (i.e., write to %wstate and RETRY).
- *
- * If the ASSUME bit is not set when the alignment fault occurs, the
- * given stack pointer is hopelessly wrong (and the spill, if it is a
- * spill, should be done as a sort of "panic spill") -- so those two
- * instructions will be a branch sequence.
- *
* Note that locore.s assumes this same bit layout (since the translation
* from "bits" to "{spill,fill}_N_{normal,other}" is done in hardware).
- *
- * The value 0 is preferred for unknown to make it easy to start in
- * unknown state and continue in whichever state unknown succeeds in --
- * a successful "other" save, for instance, can just set %wstate to
- * ASSUMExx << USERSHIFT and thus leave the kernel state "unknown".
- *
- * We also need values for managing the somewhat tricky transition from
- * user to kernel and back, so we use the one remaining free bit to mean
- * "although this looks like kernel mode, the window(s) involved are
- * user windows and should be saved ASI_AIUP". Everything else is
- * otherwise the same, but we need not bother with assumptions in this
- * mode (we expect it to apply to at most one window spill or fill),
- * i.e., WSTATE_TRANSITION can ignore WSTATE_ASSUME if it likes.
*/
#define WSTATE_NORMAL_MASK 1 /* wstate normal minus transition */
@@ -88,4 +59,8 @@
#define WSTATE_NESTED /* if set, spill must not fault */ \
(WSTATE_TRANSITION << WSTATE_OTHER_SHIFT)
+/* Values used by the PROM and (Open)Solaris */
+#define WSTATE_PROM_KMIX 7
+#define WSTATE_PROM_MASK 7
+
#endif /* !_MACHINE_WSTATE_H_ */
diff --git a/sys/sparc64/isa/isa.c b/sys/sparc64/isa/isa.c
index 724b4a8..9159cda 100644
--- a/sys/sparc64/isa/isa.c
+++ b/sys/sparc64/isa/isa.c
@@ -116,7 +116,7 @@ isa_init(device_t dev)
}
static const struct {
- const char *name;
+ const char *const name;
uint32_t id;
} const ofw_isa_pnp_map[] = {
{ "SUNW,lomh", 0x0000ae4e }, /* SUN0000 */
@@ -126,6 +126,7 @@ static const struct {
{ "flashprom", 0x0100ae4e }, /* SUN0001 */
{ "parallel", 0x0104d041 }, /* PNP0401 */
{ "serial", 0x0105d041 }, /* PNP0501 */
+ { "su", 0x0105d041 }, /* PNP0501 */
{ "i2c", 0x0200ae4e }, /* SUN0002 */
{ "rmc-comm", 0x0300ae4e }, /* SUN0003 */
{ "kb_ps2", 0x0303d041 }, /* PNP0303 */
diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c
index 2f4932e..098e191 100644
--- a/sys/sparc64/pci/apb.c
+++ b/sys/sparc64/pci/apb.c
@@ -223,8 +223,7 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid,
*/
if (start == 0 && end == ~0) {
device_printf(dev, "can't decode default resource id %d for "
- "%s%d, bypassing\n", *rid, device_get_name(child),
- device_get_unit(child));
+ "%s, bypassing\n", *rid, device_get_nameunit(child));
goto passup;
}
@@ -236,31 +235,28 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid,
switch (type) {
case SYS_RES_IOPORT:
if (!apb_checkrange(sc->sc_iomap, APB_IO_SCALE, start, end)) {
- device_printf(dev, "device %s%d requested unsupported "
- "I/O range 0x%lx-0x%lx\n", device_get_name(child),
- device_get_unit(child), start, end);
+ device_printf(dev, "device %s requested unsupported "
+ "I/O range 0x%lx-0x%lx\n",
+ device_get_nameunit(child), start, end);
return (NULL);
}
if (bootverbose)
device_printf(sc->sc_bsc.ops_pcib_sc.dev, "device "
- "%s%d requested decoded I/O range 0x%lx-0x%lx\n",
- device_get_name(child), device_get_unit(child),
- start, end);
+ "%s requested decoded I/O range 0x%lx-0x%lx\n",
+ device_get_nameunit(child), start, end);
break;
case SYS_RES_MEMORY:
if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end)) {
- device_printf(dev, "device %s%d requested unsupported "
+ device_printf(dev, "device %s requested unsupported "
"memory range 0x%lx-0x%lx\n",
- device_get_name(child), device_get_unit(child),
- start, end);
+ device_get_nameunit(child), start, end);
return (NULL);
}
if (bootverbose)
device_printf(sc->sc_bsc.ops_pcib_sc.dev, "device "
- "%s%d requested decoded memory range 0x%lx-0x%lx\n",
- device_get_name(child), device_get_unit(child),
- start, end);
+ "%s requested decoded memory range 0x%lx-0x%lx\n",
+ device_get_nameunit(child), start, end);
break;
default:
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 486136a..28933f5 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -188,13 +188,13 @@ struct psycho_dma_sync {
uint8_t pds_func; /* func. of farest PCI dev. */
};
-#define PSYCHO_READ8(sc, off) \
+#define PSYCHO_READ8(sc, off) \
bus_read_8((sc)->sc_mem_res, (off))
-#define PSYCHO_WRITE8(sc, off, v) \
+#define PSYCHO_WRITE8(sc, off, v) \
bus_write_8((sc)->sc_mem_res, (off), (v))
-#define PCICTL_READ8(sc, off) \
+#define PCICTL_READ8(sc, off) \
PSYCHO_READ8((sc), (sc)->sc_pcictl + (off))
-#define PCICTL_WRITE8(sc, off, v) \
+#define PCICTL_WRITE8(sc, off, v) \
PSYCHO_WRITE8((sc), (sc)->sc_pcictl + (off), (v))
/*
@@ -523,7 +523,7 @@ psycho_attach(device_t dev)
(u_long)intrmap, (u_long)PSYCHO_READ8(sc,
intrmap), (u_long)intrclr);
PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, i));
- PSYCHO_WRITE8(sc, intrclr, 0);
+ PSYCHO_WRITE8(sc, intrclr, INTCLR_IDLE);
PSYCHO_WRITE8(sc, intrmap,
INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, i),
PCPU_GET(mid)));
@@ -808,7 +808,7 @@ psycho_ue(void *arg)
if ((afsr & UEAFSR_P_DTE) != 0)
iommu_decode_fault(sc->sc_is, afar);
panic("%s: uncorrectable DMA error AFAR %#lx AFSR %#lx",
- device_get_name(sc->sc_dev), (u_long)afar, (u_long)afsr);
+ device_get_nameunit(sc->sc_dev), (u_long)afar, (u_long)afsr);
return (FILTER_HANDLED);
}
@@ -838,7 +838,7 @@ psycho_pci_bus(void *arg)
afar = PCICTL_READ8(sc, PCR_AFA);
afsr = PCICTL_READ8(sc, PCR_AFS);
panic("%s: PCI bus %c error AFAR %#lx AFSR %#lx",
- device_get_name(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar,
+ device_get_nameunit(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar,
(u_long)afsr);
return (FILTER_HANDLED);
}
@@ -1137,7 +1137,7 @@ psycho_intr_clear(void *arg)
struct intr_vector *iv = arg;
struct psycho_icarg *pica = iv->iv_icarg;
- PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, 0);
+ PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, INTCLR_IDLE);
}
static int
diff --git a/sys/sparc64/pci/sbbc.c b/sys/sparc64/pci/sbbc.c
new file mode 100644
index 0000000..0aa1df3
--- /dev/null
+++ b/sys/sparc64/pci/sbbc.c
@@ -0,0 +1,1074 @@
+/* $OpenBSD: sbbc.c,v 1.7 2009/11/09 17:53:39 nicm Exp $ */
+/*-
+ * Copyright (c) 2008 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*-
+ * Copyright (c) 2010 Marius Strobl <marius@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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_bus.h>
+
+#include "clock_if.h"
+#include "uart_if.h"
+
+#define SBBC_PCI_BAR PCIR_BAR(0)
+#define SBBC_PCI_VENDOR 0x108e
+#define SBBC_PCI_PRODUCT 0xc416
+
+#define SBBC_REGS_OFFSET 0x800000
+#define SBBC_REGS_SIZE 0x6230
+#define SBBC_EPLD_OFFSET 0x8e0000
+#define SBBC_EPLD_SIZE 0x20
+#define SBBC_SRAM_OFFSET 0x900000
+#define SBBC_SRAM_SIZE 0x20000 /* 128KB SRAM */
+
+#define SBBC_PCI_INT_STATUS 0x2320
+#define SBBC_PCI_INT_ENABLE 0x2330
+#define SBBC_PCI_ENABLE_INT_A 0x11
+
+#define SBBC_EPLD_INTERRUPT 0x13
+#define SBBC_EPLD_INTERRUPT_ON 0x01
+
+#define SBBC_SRAM_CONS_IN 0x00000001
+#define SBBC_SRAM_CONS_OUT 0x00000002
+#define SBBC_SRAM_CONS_BRK 0x00000004
+#define SBBC_SRAM_CONS_SPACE_IN 0x00000008
+#define SBBC_SRAM_CONS_SPACE_OUT 0x00000010
+
+#define SBBC_TAG_KEY_SIZE 8
+#define SBBC_TAG_KEY_SCSOLIE "SCSOLIE" /* SC -> OS int. enable */
+#define SBBC_TAG_KEY_SCSOLIR "SCSOLIR" /* SC -> OS int. reason */
+#define SBBC_TAG_KEY_SOLCONS "SOLCONS" /* OS console buffer */
+#define SBBC_TAG_KEY_SOLSCIE "SOLSCIE" /* OS -> SC int. enable */
+#define SBBC_TAG_KEY_SOLSCIR "SOLSCIR" /* OS -> SC int. reason */
+#define SBBC_TAG_KEY_TODDATA "TODDATA" /* OS TOD struct */
+#define SBBC_TAG_OFF(x) offsetof(struct sbbc_sram_tag, x)
+
+struct sbbc_sram_tag {
+ char tag_key[SBBC_TAG_KEY_SIZE];
+ uint32_t tag_size;
+ uint32_t tag_offset;
+} __packed;
+
+#define SBBC_TOC_MAGIC "TOCSRAM"
+#define SBBC_TOC_MAGIC_SIZE 8
+#define SBBC_TOC_TAGS_MAX 32
+#define SBBC_TOC_OFF(x) offsetof(struct sbbc_sram_toc, x)
+
+struct sbbc_sram_toc {
+ char toc_magic[SBBC_TOC_MAGIC_SIZE];
+ uint8_t toc_reserved;
+ uint8_t toc_type;
+ uint16_t toc_version;
+ uint32_t toc_ntags;
+ struct sbbc_sram_tag toc_tag[SBBC_TOC_TAGS_MAX];
+} __packed;
+
+#define SBBC_TOD_MAGIC 0x54443100 /* "TD1" */
+#define SBBC_TOD_VERSION 1
+#define SBBC_TOD_OFF(x) offsetof(struct sbbc_sram_tod, x)
+
+struct sbbc_sram_tod {
+ uint32_t tod_magic;
+ uint32_t tod_version;
+ uint64_t tod_time;
+ uint64_t tod_skew;
+ uint32_t tod_reserved;
+ uint32_t tod_heartbeat;
+ uint32_t tod_timeout;
+} __packed;
+
+#define SBBC_CONS_MAGIC 0x434f4e00 /* "CON" */
+#define SBBC_CONS_VERSION 1
+#define SBBC_CONS_OFF(x) offsetof(struct sbbc_sram_cons, x)
+
+struct sbbc_sram_cons {
+ uint32_t cons_magic;
+ uint32_t cons_version;
+ uint32_t cons_size;
+
+ uint32_t cons_in_begin;
+ uint32_t cons_in_end;
+ uint32_t cons_in_rdptr;
+ uint32_t cons_in_wrptr;
+
+ uint32_t cons_out_begin;
+ uint32_t cons_out_end;
+ uint32_t cons_out_rdptr;
+ uint32_t cons_out_wrptr;
+} __packed;
+
+struct sbbc_softc {
+ struct resource *sc_res;
+};
+
+#define SBBC_READ_N(wdth, offs) \
+ bus_space_read_ ## wdth((bst), (bsh), (offs))
+#define SBBC_WRITE_N(wdth, offs, val) \
+ bus_space_write_ ## wdth((bst), (bsh), (offs), (val))
+
+#define SBBC_READ_1(offs) \
+ SBBC_READ_N(1, (offs))
+#define SBBC_READ_2(offs) \
+ bswap16(SBBC_READ_N(2, (offs)))
+#define SBBC_READ_4(offs) \
+ bswap32(SBBC_READ_N(4, (offs)))
+#define SBBC_READ_8(offs) \
+ bswap64(SBBC_READ_N(8, (offs)))
+#define SBBC_WRITE_1(offs, val) \
+ SBBC_WRITE_N(1, (offs), (val))
+#define SBBC_WRITE_2(offs, val) \
+ SBBC_WRITE_N(2, (offs), bswap16(val))
+#define SBBC_WRITE_4(offs, val) \
+ SBBC_WRITE_N(4, (offs), bswap32(val))
+#define SBBC_WRITE_8(offs, val) \
+ SBBC_WRITE_N(8, (offs), bswap64(val))
+
+#define SBBC_REGS_READ_1(offs) \
+ SBBC_READ_1((offs) + SBBC_REGS_OFFSET)
+#define SBBC_REGS_READ_2(offs) \
+ SBBC_READ_2((offs) + SBBC_REGS_OFFSET)
+#define SBBC_REGS_READ_4(offs) \
+ SBBC_READ_4((offs) + SBBC_REGS_OFFSET)
+#define SBBC_REGS_READ_8(offs) \
+ SBBC_READ_8((offs) + SBBC_REGS_OFFSET)
+#define SBBC_REGS_WRITE_1(offs, val) \
+ SBBC_WRITE_1((offs) + SBBC_REGS_OFFSET, (val))
+#define SBBC_REGS_WRITE_2(offs, val) \
+ SBBC_WRITE_2((offs) + SBBC_REGS_OFFSET, (val))
+#define SBBC_REGS_WRITE_4(offs, val) \
+ SBBC_WRITE_4((offs) + SBBC_REGS_OFFSET, (val))
+#define SBBC_REGS_WRITE_8(offs, val) \
+ SBBC_WRITE_8((offs) + SBBC_REGS_OFFSET, (val))
+
+#define SBBC_EPLD_READ_1(offs) \
+ SBBC_READ_1((offs) + SBBC_EPLD_OFFSET)
+#define SBBC_EPLD_READ_2(offs) \
+ SBBC_READ_2((offs) + SBBC_EPLD_OFFSET)
+#define SBBC_EPLD_READ_4(offs) \
+ SBBC_READ_4((offs) + SBBC_EPLD_OFFSET)
+#define SBBC_EPLD_READ_8(offs) \
+ SBBC_READ_8((offs) + SBBC_EPLD_OFFSET)
+#define SBBC_EPLD_WRITE_1(offs, val) \
+ SBBC_WRITE_1((offs) + SBBC_EPLD_OFFSET, (val))
+#define SBBC_EPLD_WRITE_2(offs, val) \
+ SBBC_WRITE_2((offs) + SBBC_EPLD_OFFSET, (val))
+#define SBBC_EPLD_WRITE_4(offs, val) \
+ SBBC_WRITE_4((offs) + SBBC_EPLD_OFFSET, (val))
+#define SBBC_EPLD_WRITE_8(offs, val) \
+ SBBC_WRITE_8((offs) + SBBC_EPLD_OFFSET, (val))
+
+#define SBBC_SRAM_READ_1(offs) \
+ SBBC_READ_1((offs) + SBBC_SRAM_OFFSET)
+#define SBBC_SRAM_READ_2(offs) \
+ SBBC_READ_2((offs) + SBBC_SRAM_OFFSET)
+#define SBBC_SRAM_READ_4(offs) \
+ SBBC_READ_4((offs) + SBBC_SRAM_OFFSET)
+#define SBBC_SRAM_READ_8(offs) \
+ SBBC_READ_8((offs) + SBBC_SRAM_OFFSET)
+#define SBBC_SRAM_WRITE_1(offs, val) \
+ SBBC_WRITE_1((offs) + SBBC_SRAM_OFFSET, (val))
+#define SBBC_SRAM_WRITE_2(offs, val) \
+ SBBC_WRITE_2((offs) + SBBC_SRAM_OFFSET, (val))
+#define SBBC_SRAM_WRITE_4(offs, val) \
+ SBBC_WRITE_4((offs) + SBBC_SRAM_OFFSET, (val))
+#define SBBC_SRAM_WRITE_8(offs, val) \
+ SBBC_WRITE_8((offs) + SBBC_SRAM_OFFSET, (val))
+
+#define SUNW_SETCONSINPUT "SUNW,set-console-input"
+#define SUNW_SETCONSINPUT_CLNT "CON_CLNT"
+#define SUNW_SETCONSINPUT_OBP "CON_OBP"
+
+static u_int sbbc_console;
+
+static uint32_t sbbc_scsolie;
+static uint32_t sbbc_scsolir;
+static uint32_t sbbc_solcons;
+static uint32_t sbbc_solscie;
+static uint32_t sbbc_solscir;
+static uint32_t sbbc_toddata;
+
+/*
+ * internal helpers
+ */
+static int sbbc_parse_toc(bus_space_tag_t bst, bus_space_handle_t bsh);
+static inline void sbbc_send_intr(bus_space_tag_t bst,
+ bus_space_handle_t bsh);
+static const char *sbbc_serengeti_set_console_input(char *new);
+
+/*
+ * SBBC PCI interface
+ */
+static bus_alloc_resource_t sbbc_bus_alloc_resource;
+static bus_release_resource_t sbbc_bus_release_resource;
+static bus_get_resource_list_t sbbc_bus_get_resource_list;
+static bus_setup_intr_t sbbc_bus_setup_intr;
+static bus_teardown_intr_t sbbc_bus_teardown_intr;
+
+static device_attach_t sbbc_pci_attach;
+static device_probe_t sbbc_pci_probe;
+
+static clock_gettime_t sbbc_tod_gettime;
+static clock_settime_t sbbc_tod_settime;
+
+static device_method_t sbbc_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sbbc_pci_probe),
+ DEVMETHOD(device_attach, sbbc_pci_attach),
+
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, sbbc_bus_alloc_resource),
+ DEVMETHOD(bus_release_resource, sbbc_bus_release_resource),
+ DEVMETHOD(bus_setup_intr, sbbc_bus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, sbbc_bus_teardown_intr),
+ DEVMETHOD(bus_get_resource_list, sbbc_bus_get_resource_list),
+
+ /* clock interface */
+ DEVMETHOD(clock_gettime, sbbc_tod_gettime),
+ DEVMETHOD(clock_settime, sbbc_tod_settime),
+
+ KOBJMETHOD_END
+};
+
+static devclass_t sbbc_devclass;
+
+DEFINE_CLASS_0(sbbc, sbbc_driver, sbbc_pci_methods, sizeof(struct sbbc_softc));
+DRIVER_MODULE(sbbc, pci, sbbc_driver, sbbc_devclass, 0, 0);
+
+static int
+sbbc_pci_probe(device_t dev)
+{
+
+ if (pci_get_vendor(dev) == SBBC_PCI_VENDOR &&
+ pci_get_device(dev) == SBBC_PCI_PRODUCT) {
+ device_set_desc(dev, "Sun BootBus controller");
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+static int
+sbbc_pci_attach(device_t dev)
+{
+ struct sbbc_softc *sc;
+ struct timespec ts;
+ device_t child;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ phandle_t node;
+ int error, rid;
+ uint32_t val;
+
+ /* Nothing to to if we're not the chosen one. */
+ if ((node = OF_finddevice("/chosen")) == -1) {
+ device_printf(dev, "failed to find /chosen\n");
+ return (ENXIO);
+ }
+ if (OF_getprop(node, "iosram", &node, sizeof(node)) == -1) {
+ device_printf(dev, "failed to get iosram\n");
+ return (ENXIO);
+ }
+ if (node != ofw_bus_get_node(dev))
+ return (0);
+
+ sc = device_get_softc(dev);
+ rid = SBBC_PCI_BAR;
+ /*
+ * Note that we don't activate the resource so it's not mapped twice
+ * but only once by the the firmware.
+ */
+ sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
+ if (sc->sc_res == NULL) {
+ device_printf(dev, "failed to allocate resources\n");
+ return (ENXIO);
+ }
+ bst = rman_get_bustag(sc->sc_res);
+ bsh = rman_get_bushandle(sc->sc_res);
+ if (sbbc_console != 0) {
+ /* Once again the interrupt pin isn't set. */
+ if (pci_get_intpin(dev) == 0)
+ pci_set_intpin(dev, 1);
+ child = device_add_child(dev, NULL, -1);
+ if (child == NULL)
+ device_printf(dev, "failed to add UART device\n");
+ error = bus_generic_attach(dev);
+ if (error != 0)
+ device_printf(dev, "failed to attach UART device\n");
+ } else {
+ error = sbbc_parse_toc(rman_get_bustag(sc->sc_res),
+ rman_get_bushandle(sc->sc_res));
+ if (error != 0) {
+ device_printf(dev, "failed to parse TOC\n");
+ if (sbbc_console != 0) {
+ bus_release_resource(dev, SYS_RES_MEMORY, rid,
+ sc->sc_res);
+ return (error);
+ }
+ }
+ }
+ if (sbbc_toddata != 0) {
+ if ((val = SBBC_SRAM_READ_4(sbbc_toddata +
+ SBBC_TOD_OFF(tod_magic))) != SBBC_TOD_MAGIC)
+ device_printf(dev, "invalid TOD magic %#x\n", val);
+ else if ((val = SBBC_SRAM_READ_4(sbbc_toddata +
+ SBBC_TOD_OFF(tod_version))) < SBBC_TOD_VERSION)
+ device_printf(dev, "invalid TOD version %#x\n", val);
+ else {
+ clock_register(dev, 1000000); /* 1 sec. resolution */
+ if (bootverbose) {
+ sbbc_tod_gettime(dev, &ts);
+ device_printf(dev,
+ "current time: %ld.%09ld\n",
+ (long)ts.tv_sec, ts.tv_nsec);
+ }
+ }
+ }
+ return (0);
+}
+
+/*
+ * Note that the bus methods don't pass-through the uart(4) requests but act
+ * as if they would come from sbbc(4) in order to avoid complications with
+ * pci(4) (actually, uart(4) isn't a real child but rather a function of
+ * sbbc(4) anyway).
+ */
+
+static struct resource *
+sbbc_bus_alloc_resource(device_t dev, device_t child __unused, int type,
+ int *rid, u_long start, u_long end, u_long count, u_int flags)
+{
+ struct sbbc_softc *sc;
+
+ sc = device_get_softc(dev);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type,
+ rid, start, end, count, flags));
+ case SYS_RES_MEMORY:
+ return (sc->sc_res);
+ default:
+ return (NULL);
+ /* NOTREACHED */
+ }
+}
+
+static int
+sbbc_bus_release_resource(device_t dev, device_t child __unused, int type,
+ int rid, struct resource *res)
+{
+
+ if (type == SYS_RES_IRQ)
+ return (BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
+ type, rid, res));
+ return (0);
+}
+
+static struct resource_list *
+sbbc_bus_get_resource_list(device_t dev, device_t child __unused)
+{
+
+ return (BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev));
+}
+
+static int
+sbbc_bus_setup_intr(device_t dev, device_t child __unused,
+ struct resource *res, int flags, driver_filter_t *filt,
+ driver_intr_t *intr, void *arg, void **cookiep)
+{
+
+ return (BUS_SETUP_INTR(device_get_parent(dev), dev, res, flags, filt,
+ intr, arg, cookiep));
+}
+
+static int
+sbbc_bus_teardown_intr(device_t dev, device_t child __unused,
+ struct resource *res, void *cookie)
+{
+
+ return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, res, cookie));
+}
+
+/*
+ * internal helpers
+ */
+static int
+sbbc_parse_toc(bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+ char buf[MAX(SBBC_TAG_KEY_SIZE, SBBC_TOC_MAGIC_SIZE)];
+ bus_size_t tag;
+ phandle_t node;
+ uint32_t off, sram_toc;
+ u_int i, tags;
+
+ if ((node = OF_finddevice("/chosen")) == -1)
+ return (ENXIO);
+ /* SRAM TOC offset defaults to 0. */
+ if (OF_getprop(node, "iosram-toc", &sram_toc, sizeof(sram_toc)) <= 0)
+ sram_toc = 0;
+
+ bus_space_read_region_1(bst, bsh, SBBC_SRAM_OFFSET + sram_toc +
+ SBBC_TOC_OFF(toc_magic), buf, SBBC_TOC_MAGIC_SIZE);
+ buf[SBBC_TOC_MAGIC_SIZE - 1] = '\0';
+ if (strcmp(buf, SBBC_TOC_MAGIC) != 0)
+ return (ENXIO);
+
+ tags = SBBC_SRAM_READ_4(sram_toc + SBBC_TOC_OFF(toc_ntags));
+ for (i = 0; i < tags; i++) {
+ tag = sram_toc + SBBC_TOC_OFF(toc_tag) +
+ i * sizeof(struct sbbc_sram_tag);
+ bus_space_read_region_1(bst, bsh, SBBC_SRAM_OFFSET + tag +
+ SBBC_TAG_OFF(tag_key), buf, SBBC_TAG_KEY_SIZE);
+ buf[SBBC_TAG_KEY_SIZE - 1] = '\0';
+ off = SBBC_SRAM_READ_4(tag + SBBC_TAG_OFF(tag_offset));
+ if (strcmp(buf, SBBC_TAG_KEY_SCSOLIE) == 0)
+ sbbc_scsolie = off;
+ else if (strcmp(buf, SBBC_TAG_KEY_SCSOLIR) == 0)
+ sbbc_scsolir = off;
+ else if (strcmp(buf, SBBC_TAG_KEY_SOLCONS) == 0)
+ sbbc_solcons = off;
+ else if (strcmp(buf, SBBC_TAG_KEY_SOLSCIE) == 0)
+ sbbc_solscie = off;
+ else if (strcmp(buf, SBBC_TAG_KEY_SOLSCIR) == 0)
+ sbbc_solscir = off;
+ else if (strcmp(buf, SBBC_TAG_KEY_TODDATA) == 0)
+ sbbc_toddata = off;
+ }
+ return (0);
+}
+
+static const char *
+sbbc_serengeti_set_console_input(char *new)
+{
+ struct {
+ cell_t name;
+ cell_t nargs;
+ cell_t nreturns;
+ cell_t new;
+ cell_t old;
+ } args = {
+ (cell_t)SUNW_SETCONSINPUT,
+ 1,
+ 1,
+ };
+
+ args.new = (cell_t)new;
+ if (ofw_entry(&args) == -1)
+ return (NULL);
+ return ((const char *)args.old);
+}
+
+static inline void
+sbbc_send_intr(bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+
+ SBBC_EPLD_WRITE_1(SBBC_EPLD_INTERRUPT, SBBC_EPLD_INTERRUPT_ON);
+ bus_space_barrier(bst, bsh, SBBC_EPLD_OFFSET + SBBC_EPLD_INTERRUPT, 1,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+}
+
+/*
+ * TOD interface
+ */
+static int
+sbbc_tod_gettime(device_t dev, struct timespec *ts)
+{
+ struct sbbc_softc *sc;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ sc = device_get_softc(dev);
+ bst = rman_get_bustag(sc->sc_res);
+ bsh = rman_get_bushandle(sc->sc_res);
+
+ ts->tv_sec = SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_time)) +
+ SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_skew));
+ ts->tv_nsec = 0;
+ return (0);
+}
+
+static int
+sbbc_tod_settime(device_t dev, struct timespec *ts)
+{
+ struct sbbc_softc *sc;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ sc = device_get_softc(dev);
+ bst = rman_get_bustag(sc->sc_res);
+ bsh = rman_get_bushandle(sc->sc_res);
+
+ SBBC_SRAM_WRITE_8(sbbc_toddata + SBBC_TOD_OFF(tod_skew), ts->tv_sec -
+ SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_time)));
+ return (0);
+}
+
+/*
+ * UART bus front-end
+ */
+static device_probe_t sbbc_uart_sbbc_probe;
+
+static device_method_t sbbc_uart_sbbc_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sbbc_uart_sbbc_probe),
+ DEVMETHOD(device_attach, uart_bus_attach),
+ DEVMETHOD(device_detach, uart_bus_detach),
+
+ KOBJMETHOD_END
+};
+
+DEFINE_CLASS_0(uart, sbbc_uart_driver, sbbc_uart_sbbc_methods,
+ sizeof(struct uart_softc));
+DRIVER_MODULE(uart, sbbc, sbbc_uart_driver, uart_devclass, 0, 0);
+
+static int
+sbbc_uart_sbbc_probe(device_t dev)
+{
+ struct uart_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_class = &uart_sbbc_class;
+ device_set_desc(dev, "Serengeti console");
+ return (uart_bus_probe(dev, 0, 0, SBBC_PCI_BAR, 0));
+}
+
+/*
+ * Low-level UART interface
+ */
+static int sbbc_uart_probe(struct uart_bas *bas);
+static void sbbc_uart_init(struct uart_bas *bas, int baudrate, int databits,
+ int stopbits, int parity);
+static void sbbc_uart_term(struct uart_bas *bas);
+static void sbbc_uart_putc(struct uart_bas *bas, int c);
+static int sbbc_uart_rxready(struct uart_bas *bas);
+static int sbbc_uart_getc(struct uart_bas *bas, struct mtx *hwmtx);
+
+static struct uart_ops sbbc_uart_ops = {
+ .probe = sbbc_uart_probe,
+ .init = sbbc_uart_init,
+ .term = sbbc_uart_term,
+ .putc = sbbc_uart_putc,
+ .rxready = sbbc_uart_rxready,
+ .getc = sbbc_uart_getc,
+};
+
+static int
+sbbc_uart_probe(struct uart_bas *bas)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ int error;
+
+ sbbc_console = 1;
+ bst = bas->bst;
+ bsh = bas->bsh;
+ error = sbbc_parse_toc(bst, bsh);
+ if (error != 0)
+ return (error);
+
+ if (sbbc_scsolie == 0 || sbbc_scsolir == 0 || sbbc_solcons == 0 ||
+ sbbc_solscie == 0 || sbbc_solscir == 0)
+ return (ENXIO);
+
+ if (SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_magic)) !=
+ SBBC_CONS_MAGIC || SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_version)) < SBBC_CONS_VERSION)
+ return (ENXIO);
+ return (0);
+}
+
+static void
+sbbc_uart_init(struct uart_bas *bas, int baudrate __unused,
+ int databits __unused, int stopbits __unused, int parity __unused)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ /* Enable output to and space in from the SC interrupts. */
+ SBBC_SRAM_WRITE_4(sbbc_solscie, SBBC_SRAM_READ_4(sbbc_solscie) |
+ SBBC_SRAM_CONS_OUT | SBBC_SRAM_CONS_SPACE_IN);
+ uart_barrier(bas);
+
+ /* Take over the console input. */
+ sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_CLNT);
+}
+
+static void
+sbbc_uart_term(struct uart_bas *bas __unused)
+{
+
+ /* Give back the console input. */
+ sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_OBP);
+}
+
+static void
+sbbc_uart_putc(struct uart_bas *bas, int c)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ uint32_t wrptr;
+
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_wrptr));
+ SBBC_SRAM_WRITE_1(sbbc_solcons + wrptr, c);
+ uart_barrier(bas);
+ if (++wrptr == SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_end)))
+ wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_begin));
+ SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr),
+ wrptr);
+ uart_barrier(bas);
+
+ SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+ SBBC_SRAM_CONS_OUT);
+ uart_barrier(bas);
+ sbbc_send_intr(bst, bsh);
+}
+
+static int
+sbbc_uart_rxready(struct uart_bas *bas)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ if (SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr)) ==
+ SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_wrptr)))
+ return (0);
+ return (1);
+}
+
+static int
+sbbc_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ int c;
+ uint32_t rdptr;
+
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ uart_lock(hwmtx);
+
+ while (sbbc_uart_rxready(bas) == 0) {
+ uart_unlock(hwmtx);
+ DELAY(4);
+ uart_lock(hwmtx);
+ }
+
+ rdptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr));
+ c = SBBC_SRAM_READ_1(sbbc_solcons + rdptr);
+ uart_barrier(bas);
+ if (++rdptr == SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_end)))
+ rdptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_begin));
+ SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr),
+ rdptr);
+ uart_barrier(bas);
+ SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+ SBBC_SRAM_CONS_SPACE_IN);
+ uart_barrier(bas);
+ sbbc_send_intr(bst, bsh);
+
+ uart_unlock(hwmtx);
+ return (c);
+}
+
+/*
+ * High-level UART interface
+ */
+static int sbbc_uart_bus_attach(struct uart_softc *sc);
+static int sbbc_uart_bus_detach(struct uart_softc *sc);
+static int sbbc_uart_bus_flush(struct uart_softc *sc, int what);
+static int sbbc_uart_bus_getsig(struct uart_softc *sc);
+static int sbbc_uart_bus_ioctl(struct uart_softc *sc, int request,
+ intptr_t data);
+static int sbbc_uart_bus_ipend(struct uart_softc *sc);
+static int sbbc_uart_bus_param(struct uart_softc *sc, int baudrate,
+ int databits, int stopbits, int parity);
+static int sbbc_uart_bus_probe(struct uart_softc *sc);
+static int sbbc_uart_bus_receive(struct uart_softc *sc);
+static int sbbc_uart_bus_setsig(struct uart_softc *sc, int sig);
+static int sbbc_uart_bus_transmit(struct uart_softc *sc);
+
+static kobj_method_t sbbc_uart_methods[] = {
+ KOBJMETHOD(uart_attach, sbbc_uart_bus_attach),
+ KOBJMETHOD(uart_detach, sbbc_uart_bus_detach),
+ KOBJMETHOD(uart_flush, sbbc_uart_bus_flush),
+ KOBJMETHOD(uart_getsig, sbbc_uart_bus_getsig),
+ KOBJMETHOD(uart_ioctl, sbbc_uart_bus_ioctl),
+ KOBJMETHOD(uart_ipend, sbbc_uart_bus_ipend),
+ KOBJMETHOD(uart_param, sbbc_uart_bus_param),
+ KOBJMETHOD(uart_probe, sbbc_uart_bus_probe),
+ KOBJMETHOD(uart_receive, sbbc_uart_bus_receive),
+ KOBJMETHOD(uart_setsig, sbbc_uart_bus_setsig),
+ KOBJMETHOD(uart_transmit, sbbc_uart_bus_transmit),
+
+ KOBJMETHOD_END
+};
+
+struct uart_class uart_sbbc_class = {
+ "sbbc",
+ sbbc_uart_methods,
+ sizeof(struct uart_softc),
+ .uc_ops = &sbbc_uart_ops,
+ .uc_range = 1,
+ .uc_rclk = 0x5bbc /* arbitrary */
+};
+
+#define SIGCHG(c, i, s, d) \
+ if ((c) != 0) { \
+ i |= (((i) & (s)) != 0) ? (s) : (s) | (d); \
+ } else { \
+ i = (((i) & (s)) != 0) ? ((i) & ~(s)) | (d) : (i); \
+ }
+
+static int
+sbbc_uart_bus_attach(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ uint32_t wrptr;
+
+ bas = &sc->sc_bas;
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ sc->sc_rxfifosz = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_end)) - SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_begin)) - 1;
+ sc->sc_txfifosz = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_end)) - SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_begin)) - 1;
+
+ uart_lock(sc->sc_hwmtx);
+
+ /*
+ * Let the current output drain before enabling interrupts. Not
+ * doing so tends to cause lost output when turning them on.
+ */
+ wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_wrptr));
+ while (SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_rdptr)) != wrptr);
+ cpu_spinwait();
+
+ /* Clear and acknowledge possibly outstanding interrupts. */
+ SBBC_SRAM_WRITE_4(sbbc_scsolir, 0);
+ uart_barrier(bas);
+ SBBC_REGS_WRITE_4(SBBC_PCI_INT_STATUS,
+ SBBC_SRAM_READ_4(sbbc_scsolir));
+ uart_barrier(bas);
+ /* Enable PCI interrupts. */
+ SBBC_REGS_WRITE_4(SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A);
+ uart_barrier(bas);
+ /* Enable input from and output to SC as well as break interrupts. */
+ SBBC_SRAM_WRITE_4(sbbc_scsolie, SBBC_SRAM_READ_4(sbbc_scsolie) |
+ SBBC_SRAM_CONS_IN | SBBC_SRAM_CONS_BRK |
+ SBBC_SRAM_CONS_SPACE_OUT);
+ uart_barrier(bas);
+
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+}
+
+static int
+sbbc_uart_bus_detach(struct uart_softc *sc)
+{
+
+ /* Give back the console input. */
+ sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_OBP);
+ return (0);
+}
+
+static int
+sbbc_uart_bus_flush(struct uart_softc *sc, int what)
+{
+ struct uart_bas *bas;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ bas = &sc->sc_bas;
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ if ((what & UART_FLUSH_TRANSMITTER) != 0)
+ return (ENODEV);
+ if ((what & UART_FLUSH_RECEIVER) != 0) {
+ SBBC_SRAM_WRITE_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_rdptr),
+ SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_wrptr)));
+ uart_barrier(bas);
+ }
+ return (0);
+}
+
+static int
+sbbc_uart_bus_getsig(struct uart_softc *sc)
+{
+ uint32_t dummy, new, old, sig;
+
+ do {
+ old = sc->sc_hwsig;
+ sig = old;
+ dummy = 0;
+ SIGCHG(dummy, sig, SER_CTS, SER_DCTS);
+ SIGCHG(dummy, sig, SER_DCD, SER_DDCD);
+ SIGCHG(dummy, sig, SER_DSR, SER_DDSR);
+ new = sig & ~SER_MASK_DELTA;
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+ return (sig);
+}
+
+static int
+sbbc_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+ int error;
+
+ error = 0;
+ uart_lock(sc->sc_hwmtx);
+ switch (request) {
+ case UART_IOCTL_BAUD:
+ *(int*)data = 9600; /* arbitrary */
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ uart_unlock(sc->sc_hwmtx);
+ return (error);
+}
+
+static int
+sbbc_uart_bus_ipend(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ int ipend;
+ uint32_t reason, status;
+
+ bas = &sc->sc_bas;
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ uart_lock(sc->sc_hwmtx);
+ status = SBBC_REGS_READ_4(SBBC_PCI_INT_STATUS);
+ if (status == 0) {
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+ }
+
+ /*
+ * Unfortunately, we can't use compare and swap for non-cachable
+ * memory.
+ */
+ reason = SBBC_SRAM_READ_4(sbbc_scsolir);
+ SBBC_SRAM_WRITE_4(sbbc_scsolir, 0);
+ uart_barrier(bas);
+ /* Acknowledge the interrupt. */
+ SBBC_REGS_WRITE_4(SBBC_PCI_INT_STATUS, status);
+ uart_barrier(bas);
+
+ uart_unlock(sc->sc_hwmtx);
+
+ ipend = 0;
+ if ((reason & SBBC_SRAM_CONS_IN) != 0)
+ ipend |= SER_INT_RXREADY;
+ if ((reason & SBBC_SRAM_CONS_BRK) != 0)
+ ipend |= SER_INT_BREAK;
+ if ((reason & SBBC_SRAM_CONS_SPACE_OUT) != 0 &&
+ SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_rdptr)) ==
+ SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr)))
+ ipend |= SER_INT_TXIDLE;
+ return (ipend);
+}
+
+static int
+sbbc_uart_bus_param(struct uart_softc *sc __unused, int baudrate __unused,
+ int databits __unused, int stopbits __unused, int parity __unused)
+{
+
+ return (0);
+}
+
+static int
+sbbc_uart_bus_probe(struct uart_softc *sc __unused)
+{
+
+ if (sbbc_console != 0)
+ return (0);
+ return (ENXIO);
+}
+
+static int
+sbbc_uart_bus_receive(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ int c;
+ uint32_t end, rdptr, wrptr;
+
+ bas = &sc->sc_bas;
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ uart_lock(sc->sc_hwmtx);
+
+ end = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_end));
+ rdptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr));
+ wrptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_wrptr));
+ while (rdptr != wrptr) {
+ if (uart_rx_full(sc) != 0) {
+ sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+ break;
+ }
+ c = SBBC_SRAM_READ_1(sbbc_solcons + rdptr);
+ uart_rx_put(sc, c);
+ if (++rdptr == end)
+ rdptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_in_begin));
+ }
+ uart_barrier(bas);
+ SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr),
+ rdptr);
+ uart_barrier(bas);
+ SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+ SBBC_SRAM_CONS_SPACE_IN);
+ uart_barrier(bas);
+ sbbc_send_intr(bst, bsh);
+
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+}
+
+static int
+sbbc_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+ struct uart_bas *bas;
+ uint32_t new, old;
+
+ bas = &sc->sc_bas;
+ do {
+ old = sc->sc_hwsig;
+ new = old;
+ if ((sig & SER_DDTR) != 0) {
+ SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR);
+ }
+ if ((sig & SER_DRTS) != 0) {
+ SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS);
+ }
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+ return (0);
+}
+
+static int
+sbbc_uart_bus_transmit(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ int i;
+ uint32_t end, wrptr;
+
+ bas = &sc->sc_bas;
+ bst = bas->bst;
+ bsh = bas->bsh;
+
+ uart_lock(sc->sc_hwmtx);
+
+ end = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_end));
+ wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_wrptr));
+ for (i = 0; i < sc->sc_txdatasz; i++) {
+ SBBC_SRAM_WRITE_1(sbbc_solcons + wrptr, sc->sc_txbuf[i]);
+ if (++wrptr == end)
+ wrptr = SBBC_SRAM_READ_4(sbbc_solcons +
+ SBBC_CONS_OFF(cons_out_begin));
+ }
+ uart_barrier(bas);
+ SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr),
+ wrptr);
+ uart_barrier(bas);
+ SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) |
+ SBBC_SRAM_CONS_OUT);
+ uart_barrier(bas);
+ sbbc_send_intr(bst, bsh);
+ sc->sc_txbusy = 1;
+
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+}
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index f783b23..8442e7d 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -189,26 +189,26 @@ struct schizo_dma_sync {
#define SCHIZO_PERF_CNT_QLTY 100
-#define SCHIZO_SPC_READ_8(spc, sc, offs) \
+#define SCHIZO_SPC_READ_8(spc, sc, offs) \
bus_read_8((sc)->sc_mem_res[(spc)], (offs))
-#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \
+#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \
bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v))
-#define SCHIZO_PCI_READ_8(sc, offs) \
+#define SCHIZO_PCI_READ_8(sc, offs) \
SCHIZO_SPC_READ_8(STX_PCI, (sc), (offs))
-#define SCHIZO_PCI_WRITE_8(sc, offs, v) \
+#define SCHIZO_PCI_WRITE_8(sc, offs, v) \
SCHIZO_SPC_WRITE_8(STX_PCI, (sc), (offs), (v))
-#define SCHIZO_CTRL_READ_8(sc, offs) \
+#define SCHIZO_CTRL_READ_8(sc, offs) \
SCHIZO_SPC_READ_8(STX_CTRL, (sc), (offs))
-#define SCHIZO_CTRL_WRITE_8(sc, offs, v) \
+#define SCHIZO_CTRL_WRITE_8(sc, offs, v) \
SCHIZO_SPC_WRITE_8(STX_CTRL, (sc), (offs), (v))
-#define SCHIZO_PCICFG_READ_8(sc, offs) \
+#define SCHIZO_PCICFG_READ_8(sc, offs) \
SCHIZO_SPC_READ_8(STX_PCICFG, (sc), (offs))
-#define SCHIZO_PCICFG_WRITE_8(sc, offs, v) \
+#define SCHIZO_PCICFG_WRITE_8(sc, offs, v) \
SCHIZO_SPC_WRITE_8(STX_PCICFG, (sc), (offs), (v))
-#define SCHIZO_ICON_READ_8(sc, offs) \
+#define SCHIZO_ICON_READ_8(sc, offs) \
SCHIZO_SPC_READ_8(STX_ICON, (sc), (offs))
-#define SCHIZO_ICON_WRITE_8(sc, offs, v) \
+#define SCHIZO_ICON_WRITE_8(sc, offs, v) \
SCHIZO_SPC_WRITE_8(STX_ICON, (sc), (offs), (v))
struct schizo_desc {
@@ -402,9 +402,22 @@ schizo_attach(device_t dev)
*/
i = OF_getprop(node, "ino-bitmap", (void *)prop_array,
sizeof(prop_array));
- if (i == -1)
- panic("%s: could not get ino-bitmap", __func__);
- ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
+ if (i != -1)
+ ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
+ else {
+ /*
+ * If the ino-bitmap property is missing, just provide the
+ * default set of interrupts for this controller and let
+ * schizo_setup_intr() take care of child interrupts.
+ */
+ if (sc->sc_half == 0)
+ ino_bitmap = (1ULL << STX_UE_INO) |
+ (1ULL << STX_CE_INO) |
+ (1ULL << STX_PCIERR_A_INO) |
+ (1ULL << STX_BUS_INO);
+ else
+ ino_bitmap = 1ULL << STX_PCIERR_B_INO;
+ }
for (i = 0; i <= STX_MAX_INO; i++) {
if ((ino_bitmap & (1ULL << i)) == 0)
continue;
@@ -684,6 +697,14 @@ schizo_attach(device_t dev)
ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
+ /*
+ * At least when booting Fire V890 from disk a Schizo comes up with
+ * a PCI bus error residing which triggers as soon as we register
+ * schizo_pci_bus() even when clearing it from all involved registers
+ * beforehand (but is quiet once it has fired). Thus we make PCI bus
+ * errors non-fatal until we actually touch the bus.
+ */
+ sc->sc_flags |= SCHIZO_FLAGS_ARMED;
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
}
@@ -787,6 +808,8 @@ schizo_pci_bus(void *arg)
iommu = SCHIZO_PCI_READ_8(sc, STX_PCI_IOMMU);
status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_pci_secbus,
STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2);
+ if ((sc->sc_flags & SCHIZO_FLAGS_ARMED) == 0)
+ goto clear_error;
if ((csr & STX_PCI_CTRL_MMU_ERR) != 0) {
if ((iommu & TOM_PCI_IOMMU_ERR) == 0)
goto clear_error;
@@ -803,7 +826,7 @@ schizo_pci_bus(void *arg)
}
panic("%s: PCI bus %c error AFAR %#llx AFSR %#llx PCI CSR %#llx "
- "IOMMU %#llx STATUS %#llx", device_get_name(sc->sc_dev),
+ "IOMMU %#llx STATUS %#llx", device_get_nameunit(sc->sc_dev),
'A' + sc->sc_half, (unsigned long long)afar,
(unsigned long long)afsr, (unsigned long long)csr,
(unsigned long long)iommu, (unsigned long long)status);
@@ -838,7 +861,7 @@ schizo_ue(void *arg)
break;
mtx_unlock_spin(sc->sc_mtx);
panic("%s: uncorrectable DMA error AFAR %#llx AFSR %#llx",
- device_get_name(sc->sc_dev), (unsigned long long)afar,
+ device_get_nameunit(sc->sc_dev), (unsigned long long)afar,
(unsigned long long)afsr);
return (FILTER_HANDLED);
}
@@ -872,7 +895,7 @@ schizo_host_bus(void *arg)
uint64_t errlog;
errlog = SCHIZO_CTRL_READ_8(sc, STX_CTRL_BUS_ERRLOG);
- panic("%s: %s error %#llx", device_get_name(sc->sc_dev),
+ panic("%s: %s error %#llx", device_get_nameunit(sc->sc_dev),
sc->sc_mode == SCHIZO_MODE_TOM ? "JBus" : "Safari",
(unsigned long long)errlog);
return (FILTER_HANDLED);
@@ -1054,7 +1077,7 @@ schizo_dma_sync_stub(void *arg)
for (; atomic_cmpset_acq_32(&sc->sc_cdma_state,
SCHIZO_CDMA_STATE_DONE, SCHIZO_CDMA_STATE_PENDING) == 0;)
;
- SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, 1);
+ SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, INTCLR_RECEIVED);
microuptime(&cur);
end.tv_sec = 1;
end.tv_usec = 0;
@@ -1139,7 +1162,7 @@ schizo_intr_clear(void *arg)
struct intr_vector *iv = arg;
struct schizo_icarg *sica = iv->iv_icarg;
- SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_clr, 0);
+ SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE);
}
static int
diff --git a/sys/sparc64/pci/schizovar.h b/sys/sparc64/pci/schizovar.h
index 144ace7..964ab37 100644
--- a/sys/sparc64/pci/schizovar.h
+++ b/sys/sparc64/pci/schizovar.h
@@ -44,8 +44,9 @@ struct schizo_softc {
#define SCHIZO_MODE_XMS 2
u_int sc_flags;
-#define SCHIZO_FLAGS_BSWAR (1 << 0)
-#define SCHIZO_FLAGS_CDMA (1 << 1)
+#define SCHIZO_FLAGS_ARMED (1 << 0)
+#define SCHIZO_FLAGS_BSWAR (1 << 1)
+#define SCHIZO_FLAGS_CDMA (1 << 2)
bus_addr_t sc_cdma_clr;
uint32_t sc_cdma_state;
diff --git a/sys/sparc64/sbus/lsi64854reg.h b/sys/sparc64/sbus/lsi64854reg.h
index 802e9d6..5230d3b 100644
--- a/sys/sparc64/sbus/lsi64854reg.h
+++ b/sys/sparc64/sbus/lsi64854reg.h
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/sparc64/sbus/lsi64854var.h b/sys/sparc64/sbus/lsi64854var.h
index f0147e0..8cc00b8 100644
--- a/sys/sparc64/sbus/lsi64854var.h
+++ b/sys/sparc64/sbus/lsi64854var.h
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/sparc64/sbus/ofw_sbus.h b/sys/sparc64/sbus/ofw_sbus.h
index 8db6a32..dec4221 100644
--- a/sys/sparc64/sbus/ofw_sbus.h
+++ b/sys/sparc64/sbus/ofw_sbus.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index 0c4b509..597d382 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -171,9 +171,9 @@ struct sbus_softc {
void *sc_pf_ihand;
};
-#define SYSIO_READ8(sc, off) \
+#define SYSIO_READ8(sc, off) \
bus_read_8((sc)->sc_sysio_res, (off))
-#define SYSIO_WRITE8(sc, off, v) \
+#define SYSIO_WRITE8(sc, off, v) \
bus_write_8((sc)->sc_sysio_res, (off), (v))
static device_probe_t sbus_probe;
@@ -697,7 +697,7 @@ sbus_intr_clear(void *arg)
struct intr_vector *iv = arg;
struct sbus_icarg *sica = iv->iv_icarg;
- SYSIO_WRITE8(sica->sica_sc, sica->sica_clr, 0);
+ SYSIO_WRITE8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE);
}
static int
diff --git a/sys/sparc64/sparc64/cheetah.c b/sys/sparc64/sparc64/cheetah.c
index ae24744..8366187 100644
--- a/sys/sparc64/sparc64/cheetah.c
+++ b/sys/sparc64/sparc64/cheetah.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2003 Jake Burkholder.
- * Copyright (c) 2005, 2008 Marius Strobl <marius@FreeBSD.org>
+ * Copyright (c) 2005, 2008, 2010 Marius Strobl <marius@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,9 +49,6 @@ __FBSDID("$FreeBSD$");
#include <machine/ver.h>
#include <machine/vmparam.h>
-/* A FLUSH is required after changing LSU_IC (the address is ignored). */
-#define CHEETAH_FLUSH_LSU_IC() __asm __volatile("flush %%g0" : :)
-
#define CHEETAH_ICACHE_TAG_LOWER 0x30
/*
@@ -60,21 +57,7 @@ __FBSDID("$FreeBSD$");
void
cheetah_init(u_int cpu_impl)
{
- register_t s;
-
- /*
- * Disable interrupts for safety, this shouldn't be actually
- * necessary though.
- */
- s = intr_disable();
-
- /*
- * Ensure DCR_IFPOE is disabled as long as we haven't implemented
- * support for it (if ever) as most if not all firmware versions
- * apparently turn it on. Not making use of DCR_IFPOE should also
- * avoid Cheetah erratum #109.
- */
- wr(asr18, rd(asr18) & ~DCR_IFPOE, 0);
+ u_long val;
/* Ensure the TSB Extension Registers hold 0 as TSB_Base. */
@@ -93,26 +76,57 @@ cheetah_init(u_int cpu_impl)
membar(Sync);
/*
- * Ensure that the dt512_0 is set to hold 8k pages for all three
- * contexts and configure the dt512_1 to hold 4MB pages for them
- * (e.g. for direct mappings).
- * NB: according to documentation, this requires a contex demap
- * _before_ changing the corresponding page size, but we hardly
- * can flush our locked pages here, so we use a demap all instead.
+ * Configure the first large dTLB to hold 4MB pages (e.g. for direct
+ * mappings) for all three contexts and ensure the second one is set
+ * up to hold 8k pages for them. Note that this is constraint by
+ * US-IV+, whose large dTLBs can only hold entries of certain page
+ * sizes each.
+ * For US-IV+, additionally ensure that the large iTLB is set up to
+ * hold 8k pages for nucleus and primary context (still no secondary
+ * iMMU context.
+ * NB: according to documentation, changing the page size of the same
+ * context requires a context demap before changing the corresponding
+ * page size, but we hardly can flush our locked pages here, so we use
+ * a demap all instead.
*/
stxa(TLB_DEMAP_ALL, ASI_DMMU_DEMAP, 0);
membar(Sync);
- stxa(AA_DMMU_PCXR, ASI_DMMU,
- (TS_8K << TLB_PCXR_N_PGSZ0_SHIFT) |
- (TS_4M << TLB_PCXR_N_PGSZ1_SHIFT) |
- (TS_8K << TLB_PCXR_P_PGSZ0_SHIFT) |
- (TS_4M << TLB_PCXR_P_PGSZ1_SHIFT));
- stxa(AA_DMMU_SCXR, ASI_DMMU,
- (TS_8K << TLB_SCXR_S_PGSZ0_SHIFT) |
- (TS_4M << TLB_SCXR_S_PGSZ1_SHIFT));
+ val = (TS_4M << TLB_PCXR_N_PGSZ0_SHIFT) |
+ (TS_8K << TLB_PCXR_N_PGSZ1_SHIFT) |
+ (TS_4M << TLB_PCXR_P_PGSZ0_SHIFT) |
+ (TS_8K << TLB_PCXR_P_PGSZ1_SHIFT);
+ if (cpu_impl == CPU_IMPL_ULTRASPARCIVp)
+ val |= (TS_8K << TLB_PCXR_N_PGSZ_I_SHIFT) |
+ (TS_8K << TLB_PCXR_P_PGSZ_I_SHIFT);
+ stxa(AA_DMMU_PCXR, ASI_DMMU, val);
+ val = (TS_4M << TLB_SCXR_S_PGSZ0_SHIFT) |
+ (TS_8K << TLB_SCXR_S_PGSZ1_SHIFT);
+ stxa(AA_DMMU_SCXR, ASI_DMMU, val);
flush(KERNBASE);
- intr_restore(s);
+ /*
+ * Ensure DCR_IFPOE is disabled as long as we haven't implemented
+ * support for it (if ever) as most if not all firmware versions
+ * apparently turn it on. Not making use of DCR_IFPOE should also
+ * avoid Cheetah erratum #109.
+ */
+ val = rd(asr18) & ~DCR_IFPOE;
+ if (cpu_impl == CPU_IMPL_ULTRASPARCIVp) {
+ /*
+ * Ensure the branch prediction mode is set to PC indexing
+ * in order to work around US-IV+ erratum #2.
+ */
+ val = (val & ~DCR_BPM_MASK) | DCR_BPM_PC;
+ /*
+ * XXX disable dTLB parity error reporting as otherwise we
+ * get seemingly false positives when copying in the user
+ * window by simulating a fill trap on return to usermode in
+ * case single issue is disabled, which thus appears to be
+ * a CPU bug.
+ */
+ val &= ~DCR_DTPE;
+ }
+ wr(asr18, val, 0);
}
/*
@@ -125,11 +139,11 @@ cheetah_cache_enable(u_int cpu_impl)
lsu = ldxa(0, ASI_LSU_CTL_REG);
if (cpu_impl == CPU_IMPL_ULTRASPARCIII) {
- /* Disable P$ due to Cheetah erratum #18. */
+ /* Disable P$ due to US-III erratum #18. */
lsu &= ~LSU_PE;
}
stxa(0, ASI_LSU_CTL_REG, lsu | LSU_IC | LSU_DC);
- CHEETAH_FLUSH_LSU_IC();
+ flush(KERNBASE);
}
/*
@@ -139,21 +153,35 @@ void
cheetah_cache_flush(void)
{
u_long addr, lsu;
+ register_t s;
+ s = intr_disable();
for (addr = 0; addr < PCPU_GET(cache.dc_size);
addr += PCPU_GET(cache.dc_linesize))
- stxa_sync(addr, ASI_DCACHE_TAG, 0);
+ /*
+ * Note that US-IV+ additionally require a membar #Sync before
+ * a load or store to ASI_DCACHE_TAG.
+ */
+ __asm __volatile(
+ "membar #Sync;"
+ "stxa %%g0, [%0] %1;"
+ "membar #Sync"
+ : : "r" (addr), "n" (ASI_DCACHE_TAG));
/* The I$ must be disabled when flushing it so ensure it's off. */
lsu = ldxa(0, ASI_LSU_CTL_REG);
stxa(0, ASI_LSU_CTL_REG, lsu & ~(LSU_IC));
- CHEETAH_FLUSH_LSU_IC();
+ flush(KERNBASE);
for (addr = CHEETAH_ICACHE_TAG_LOWER;
addr < PCPU_GET(cache.ic_size) * 2;
addr += PCPU_GET(cache.ic_linesize) * 2)
- stxa_sync(addr, ASI_ICACHE_TAG, 0);
+ __asm __volatile(
+ "stxa %%g0, [%0] %1;"
+ "membar #Sync"
+ : : "r" (addr), "n" (ASI_ICACHE_TAG));
stxa(0, ASI_LSU_CTL_REG, lsu);
- CHEETAH_FLUSH_LSU_IC();
+ flush(KERNBASE);
+ intr_restore(s);
}
/*
@@ -165,9 +193,11 @@ cheetah_dcache_page_inval(vm_paddr_t spa)
vm_paddr_t pa;
void *cookie;
- KASSERT((spa & PAGE_MASK) == 0, ("%s: pa not page aligned", __func__));
+ KASSERT((spa & PAGE_MASK) == 0,
+ ("%s: pa not page aligned", __func__));
cookie = ipi_dcache_page_inval(tl_ipi_cheetah_dcache_page_inval, spa);
- for (pa = spa; pa < spa + PAGE_SIZE; pa += PCPU_GET(cache.dc_linesize))
+ for (pa = spa; pa < spa + PAGE_SIZE;
+ pa += PCPU_GET(cache.dc_linesize))
stxa_sync(pa, ASI_DCACHE_INVALIDATE, 0);
ipi_wait(cookie);
}
diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S
index 5f81c04..a0f6f6e 100644
--- a/sys/sparc64/sparc64/exception.S
+++ b/sys/sparc64/sparc64/exception.S
@@ -316,15 +316,6 @@ END(tl1_kstack_fault)
#define RSF_FILL_INC tl0_ret_fill_end - tl0_ret_fill
/*
- * Retry a spill or fill with a different wstate due to an alignment fault.
- * We may just be using the wrong stack offset.
- */
-#define RSF_ALIGN_RETRY(ws) \
- wrpr %g0, (ws), %wstate ; \
- retry ; \
- .align 16
-
-/*
* Generate a T_SPILL or T_FILL trap if the window operation fails.
*/
#define RSF_TRAP(type) \
@@ -1716,6 +1707,19 @@ END(tl1_dmmu_prot_trap)
RSF_SPILL_TOPCB
.endm
+ .macro tl1_spill_7_n
+ btst 1, %sp
+ bnz,a,pn %xcc, tl1_spill_0_n
+ nop
+ srl %sp, 0, %sp
+ SPILL(stw, %sp, 4, EMPTY)
+ saved
+ retry
+ .align 32
+ RSF_FATAL(T_SPILL)
+ RSF_FATAL(T_SPILL)
+ .endm
+
.macro tl1_spill_0_o
wr %g0, ASI_AIUP, %asi
SPILL(stxa, %sp + SPOFF, 8, %asi)
@@ -1770,6 +1774,19 @@ END(tl1_dmmu_prot_trap)
RSF_FILL_MAGIC
.endm
+ .macro tl1_fill_7_n
+ btst 1, %sp
+ bnz,a,pt %xcc, tl1_fill_0_n
+ nop
+ srl %sp, 0, %sp
+ FILL(lduw, %sp, 4, EMPTY)
+ restored
+ retry
+ .align 32
+ RSF_FATAL(T_FILL)
+ RSF_FATAL(T_FILL)
+ .endm
+
/*
* This is used to spill windows that are still occupied with user
* data on kernel entry to the pcb.
@@ -2016,8 +2033,10 @@ tl1_spill_0_n:
tl1_spill_2_n:
tl1_spill_2_n ! 0x288
tl1_spill_3_n:
- tl1_spill_3_n ! 0x29c
- tl1_spill_bad 4 ! 0x290-0x29f
+ tl1_spill_3_n ! 0x28c
+ tl1_spill_bad 3 ! 0x290-0x29b
+tl1_spill_7_n:
+ tl1_spill_7_n ! 0x29c
tl1_spill_0_o:
tl1_spill_0_o ! 0x2a0
tl1_spill_1_o:
@@ -2029,10 +2048,13 @@ tl1_fill_0_n:
tl1_fill_0_n ! 0x2c0
tl1_fill_bad 1 ! 0x2c4
tl1_fill_2_n:
- tl1_fill_2_n ! 0x2d0
+ tl1_fill_2_n ! 0x2c8
tl1_fill_3_n:
- tl1_fill_3_n ! 0x2d4
- tl1_fill_bad 12 ! 0x2d8-0x2ff
+ tl1_fill_3_n ! 0x2cc
+ tl1_fill_bad 3 ! 0x2d0-0x2db
+tl1_fill_7_n:
+ tl1_fill_7_n ! 0x2dc
+ tl1_fill_bad 8 ! 0x2e0-0x2ff
tl1_reserved 1 ! 0x300
tl1_breakpoint:
tl1_gen T_BREAKPOINT ! 0x301
@@ -2649,7 +2671,7 @@ END(tl0_ret)
* Kernel trap entry point
*
* void tl1_trap(u_int type, u_long o1, u_long o2, u_long tar, u_long sfar,
- * u_int sfsr)
+ * u_int sfsr)
*
* This is easy because the stack is already setup and the windows don't need
* to be split. We build a trapframe and call trap(), the same as above, but
diff --git a/sys/sparc64/sparc64/genassym.c b/sys/sparc64/sparc64/genassym.c
index 9efaa74..f8cd6a2 100644
--- a/sys/sparc64/sparc64/genassym.c
+++ b/sys/sparc64/sparc64/genassym.c
@@ -139,7 +139,7 @@ ASSYM(TD_W, TD_W);
ASSYM(TS_MIN, TS_MIN);
ASSYM(TS_MAX, TS_MAX);
ASSYM(TLB_DAR_SLOT_SHIFT, TLB_DAR_SLOT_SHIFT);
-ASSYM(TLB_PCXR_PGSZ_MASK, TLB_PCXR_PGSZ_MASK);
+ASSYM(TLB_CXR_PGSZ_MASK, TLB_CXR_PGSZ_MASK);
ASSYM(TLB_DIRECT_TO_TTE_MASK, TLB_DIRECT_TO_TTE_MASK);
ASSYM(TV_SIZE_BITS, TV_SIZE_BITS);
#endif
diff --git a/sys/sparc64/sparc64/locore.S b/sys/sparc64/sparc64/locore.S
index ac6659b..41f55a5 100644
--- a/sys/sparc64/sparc64/locore.S
+++ b/sys/sparc64/sparc64/locore.S
@@ -29,7 +29,9 @@ __FBSDID("$FreeBSD$");
#include <machine/asi.h>
#include <machine/asmacros.h>
+#include <machine/intr_machdep.h>
#include <machine/pstate.h>
+#include <machine/wstate.h>
#include "assym.s"
@@ -46,7 +48,7 @@ ENTRY(btext)
ENTRY(_start)
/*
* Initialize misc. state to known values: interrupts disabled, normal
- * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL 0 and
+ * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL_TICK and
* floating point disabled.
* Note that some firmware versions don't implement a clean window
* trap handler so we unfortunately can't clear the windows by setting
@@ -54,7 +56,7 @@ ENTRY(_start)
*/
wrpr %g0, PSTATE_NORMAL, %pstate
flushw
- wrpr %g0, 0, %pil
+ wrpr %g0, PIL_TICK, %pil
wr %g0, 0, %fprs
/*
@@ -65,11 +67,6 @@ ENTRY(_start)
sub %l0, SPOFF + CCFSZ, %sp
/*
- * Enable interrupts.
- */
- wrpr %g0, PSTATE_KERNEL, %pstate
-
- /*
* Do initial bootstrap to setup pmap and thread0.
*/
call sparc64_init
@@ -96,7 +93,7 @@ ENTRY(cpu_setregs)
ldx [%o0 + PC_CURPCB], %o1
/*
- * Disable interrupts, normal globals.
+ * Ensure we are on normal globals.
*/
wrpr %g0, PSTATE_NORMAL, %pstate
@@ -139,13 +136,12 @@ ENTRY(cpu_setregs)
* Force trap level 1 and take over the trap table.
*/
SET(tl0_base, %o2, %o1)
+ SET(tba_taken_over, %o3, %o2)
+ mov 1, %o3
+ wrpr %g0, WSTATE_KERNEL, %wstate
wrpr %g0, 1, %tl
wrpr %o1, 0, %tba
-
- /*
- * Re-enable interrupts.
- */
- wrpr %g0, PSTATE_KERNEL, %pstate
+ stw %o3, [%o2]
retl
nop
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index c5b08ee..c904060 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -138,6 +138,7 @@ struct kva_md_info kmi;
u_long ofw_vec;
u_long ofw_tba;
+u_int tba_taken_over;
char sparc64_model[32];
@@ -340,7 +341,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
cpu_impl = VER_IMPL(rdpr(ver));
/*
- * Do CPU-specific Initialization.
+ * Do CPU-specific initialization.
*/
if (cpu_impl >= CPU_IMPL_ULTRASPARCIII)
cheetah_init(cpu_impl);
@@ -466,7 +467,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
/*
* Determine the TLB slot maxima, which are expected to be
* equal across all CPUs.
- * NB: for Cheetah-class CPUs, these properties only refer
+ * NB: for cheetah-class CPUs, these properties only refer
* to the t16s.
*/
if (OF_getprop(pc->pc_node, "#dtlb-entries", &dtlb_slots,
@@ -476,6 +477,10 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
sizeof(itlb_slots)) == -1)
panic("sparc64_init: cannot determine number of iTLB slots");
+ /*
+ * Initialize and enable the caches. Note that his may include
+ * applying workarounds.
+ */
cache_init(pc);
cache_enable(cpu_impl);
uma_set_align(pc->pc_cache.dc_linesize - 1);
@@ -567,8 +572,18 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
dpcpu_init(dpcpu0, 0);
msgbufinit(msgbufp, MSGBUF_SIZE);
+ /*
+ * Initialize mutexes.
+ */
mutex_init();
+
+ /*
+ * Finish the interrupt initialization now that mutexes work and
+ * enable them.
+ */
intr_init2();
+ wrpr(pil, 0, PIL_TICK);
+ wrpr(pstate, 0, PSTATE_KERNEL);
/*
* Finish pmap initialization now that we're ready for mutexes.
@@ -968,7 +983,7 @@ ptrace_clear_single_step(struct thread *td)
}
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf;
struct pcb *pcb;
@@ -991,8 +1006,8 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
tf->tf_out[0] = stack;
tf->tf_out[3] = p->p_sysent->sv_psstrings;
tf->tf_out[6] = sp - SPOFF - sizeof(struct frame);
- tf->tf_tnpc = entry + 4;
- tf->tf_tpc = entry;
+ tf->tf_tnpc = imgp->entry_addr + 4;
+ tf->tf_tpc = imgp->entry_addr;
tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO;
td->td_retval[0] = tf->tf_out[0];
diff --git a/sys/sparc64/sparc64/mp_locore.S b/sys/sparc64/sparc64/mp_locore.S
index 17dc444..bd4fd13 100644
--- a/sys/sparc64/sparc64/mp_locore.S
+++ b/sys/sparc64/sparc64/mp_locore.S
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include <machine/asi.h>
#include <machine/asmacros.h>
+#include <machine/intr_machdep.h>
#include <machine/ktr.h>
#include <machine/pstate.h>
#include <machine/smp.h>
@@ -44,14 +45,14 @@ __FBSDID("$FreeBSD$");
_ALIGN_TEXT
/*
* Initialize misc. state to known values: interrupts disabled, normal
- * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL 0 and
+ * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL_TICK and
* floating point disabled.
* Note that some firmware versions don't implement a clean window
* trap handler so we unfortunately can't clear the windows by setting
* %cleanwin to zero here.
*/
1: wrpr %g0, PSTATE_NORMAL, %pstate
- wrpr %g0, 0, %pil
+ wrpr %g0, PIL_TICK, %pil
wr %g0, 0, %fprs
rdpr %ver, %l7
@@ -262,11 +263,6 @@ ENTRY(mp_startup)
add %l1, %l2, %l1
sub %l1, SPOFF + CCFSZ, %sp
- /*
- * Enable interrupts.
- */
- wrpr %g0, PSTATE_KERNEL, %pstate
-
#if KTR_COMPILE & KTR_SMP
CATR(KTR_SMP,
"mp_startup: bootstrap cpuid=%d mid=%d pcpu=%#lx data=%#lx sp=%#lx"
diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c
index 8ea72f3..ce66a4b 100644
--- a/sys/sparc64/sparc64/mp_machdep.c
+++ b/sys/sparc64/sparc64/mp_machdep.c
@@ -409,16 +409,32 @@ cpu_mp_bootstrap(struct pcpu *pc)
volatile struct cpu_start_args *csa;
csa = &cpu_start_args;
+
+ /* Do CPU-specific initialization. */
if (pc->pc_impl >= CPU_IMPL_ULTRASPARCIII)
cheetah_init(pc->pc_impl);
+ /*
+ * Enable the caches. Note that his may include applying workarounds.
+ */
cache_enable(pc->pc_impl);
+
+ /* Lock the kernel TSB in the TLB. */
pmap_map_tsb();
+
/*
* Flush all non-locked TLB entries possibly left over by the
* firmware.
*/
tlb_flush_nonlocked();
+
+ /* Initialize global registers. */
cpu_setregs(pc);
+
+ /* Enable interrupts. */
+ wrpr(pil, 0, PIL_TICK);
+ wrpr(pstate, 0, PSTATE_KERNEL);
+
+ /* Start the (S)TICK interrupts. */
tick_start();
smp_cpus++;
diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c
index ee01aa8..192251d 100644
--- a/sys/sparc64/sparc64/nexus.c
+++ b/sys/sparc64/sparc64/nexus.c
@@ -153,6 +153,7 @@ EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0,
MODULE_VERSION(nexus, 1);
static const char *const nexus_excl_name[] = {
+ "FJSV,system",
"aliases",
"associations",
"chosen",
@@ -163,6 +164,7 @@ static const char *const nexus_excl_name[] = {
"openprom",
"options",
"packages",
+ "physical-memory",
"rsc",
"sgcn",
"todsg",
diff --git a/sys/sparc64/sparc64/ofw_machdep.c b/sys/sparc64/sparc64/ofw_machdep.c
index 9d52262..88ee072 100644
--- a/sys/sparc64/sparc64/ofw_machdep.c
+++ b/sys/sparc64/sparc64/ofw_machdep.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>.
- * Copyright (c) 2005 - 2009 by Marius Strobl <marius@FreeBSD.org>.
+ * Copyright (c) 2005 - 2010 by Marius Strobl <marius@FreeBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -68,6 +68,19 @@ OF_getetheraddr(device_t dev, u_char *addr)
bcopy(&idp.id_ether, addr, ETHER_ADDR_LEN);
}
+u_int
+OF_getscsinitid(device_t dev)
+{
+ phandle_t node;
+ uint32_t id;
+
+ for (node = ofw_bus_get_node(dev); node != 0; node = OF_parent(node))
+ if (OF_getprop(node, "scsi-initiator-id", &id,
+ sizeof(id)) > 0)
+ return (id);
+ return (7);
+}
+
static __inline uint32_t
phys_hi_mask_space(const char *bus, uint32_t phys_hi)
{
@@ -186,13 +199,10 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
name[sizeof(name) - 1] = '\0';
goto skip;
}
- if (lbus != bus) {
- if (OF_getprop(bus, "#size-cells", &szc,
- sizeof(szc)) == -1)
- szc = 1;
- if (szc < 1 || szc > 2)
- return (ENXIO);
- }
+ if (OF_getprop(bus, "#size-cells", &szc, sizeof(szc)) == -1)
+ szc = 1;
+ if (szc < 1 || szc > 2)
+ return (ENXIO);
nbank /= sizeof(banks[0]) * (addrc + paddrc + szc);
bank = 0;
for (i = 0; i < nbank; i++) {
@@ -232,9 +242,9 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
}
if (i == nbank)
return (ENXIO);
+ lbus = bus;
skip:
addrc = paddrc;
- lbus = bus;
bus = pbus;
}
diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c
index 5ebc6ff..d97900c 100644
--- a/sys/sparc64/sparc64/pmap.c
+++ b/sys/sparc64/sparc64/pmap.c
@@ -236,6 +236,8 @@ PMAP_STATS_VAR(pmap_ncopy_page_soc);
PMAP_STATS_VAR(pmap_nnew_thread);
PMAP_STATS_VAR(pmap_nnew_thread_oc);
+static inline u_long dtlb_get_data(u_int slot);
+
/*
* Quick sort callout for comparing memory regions
*/
@@ -274,6 +276,18 @@ om_cmp(const void *a, const void *b)
return (0);
}
+static inline u_long
+dtlb_get_data(u_int slot)
+{
+
+ /*
+ * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work
+ * around errata of USIII and beyond.
+ */
+ (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG);
+ return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG));
+}
+
/*
* Bootstrap the system enough to run with virtual memory.
*/
@@ -287,11 +301,13 @@ pmap_bootstrap(u_int cpu_impl)
vm_paddr_t pa;
vm_size_t physsz;
vm_size_t virtsz;
+ u_long data;
phandle_t pmem;
phandle_t vmem;
- int sz;
+ u_int dtlb_slots_avail;
int i;
int j;
+ int sz;
/*
* Find out what physical memory is available from the PROM and
@@ -336,22 +352,30 @@ pmap_bootstrap(u_int cpu_impl)
/*
* Calculate the size of kernel virtual memory, and the size and mask
* for the kernel TSB based on the phsyical memory size but limited
- * by letting the kernel TSB take up no more than half of the dTLB
- * slots available for locked entries.
+ * by the amount of dTLB slots available for locked entries (given
+ * that for spitfire-class CPUs all of the dt64 slots can hold locked
+ * entries but there is no large dTLB for unlocked ones, we don't use
+ * more than half of it for locked entries).
*/
+ dtlb_slots_avail = 0;
+ for (i = 0; i < dtlb_slots; i++) {
+ data = dtlb_get_data(i);
+ if ((data & (TD_V | TD_L)) != (TD_V | TD_L))
+ dtlb_slots_avail++;
+ }
+#ifdef SMP
+ dtlb_slots_avail -= PCPU_PAGES;
+#endif
+ if (cpu_impl >= CPU_IMPL_ULTRASPARCI &&
+ cpu_impl < CPU_IMPL_ULTRASPARCIII)
+ dtlb_slots_avail /= 2;
virtsz = roundup(physsz, PAGE_SIZE_4M << (PAGE_SHIFT - TTE_SHIFT));
virtsz = MIN(virtsz,
- (dtlb_slots / 2 * PAGE_SIZE_4M) << (PAGE_SHIFT - TTE_SHIFT));
+ (dtlb_slots_avail * PAGE_SIZE_4M) << (PAGE_SHIFT - TTE_SHIFT));
vm_max_kernel_address = VM_MIN_KERNEL_ADDRESS + virtsz;
tsb_kernel_size = virtsz >> (PAGE_SHIFT - TTE_SHIFT);
tsb_kernel_mask = (tsb_kernel_size >> TTE_SHIFT) - 1;
- if (kernel_tlb_slots + PCPU_PAGES + tsb_kernel_size / PAGE_SIZE_4M +
- 1 /* PROM page */ + 1 /* spare */ > dtlb_slots)
- panic("pmap_bootstrap: insufficient dTLB entries");
- if (kernel_tlb_slots + 1 /* PROM page */ + 1 /* spare */ > itlb_slots)
- panic("pmap_bootstrap: insufficient iTLB entries");
-
/*
* Allocate the kernel TSB and lock it in the TLB.
*/
@@ -572,7 +596,7 @@ pmap_map_tsb(void)
* FP block operations in the kernel).
*/
stxa(AA_DMMU_SCXR, ASI_DMMU, (ldxa(AA_DMMU_SCXR, ASI_DMMU) &
- TLB_SCXR_PGSZ_MASK) | TLB_CTX_KERNEL);
+ TLB_CXR_PGSZ_MASK) | TLB_CTX_KERNEL);
flush(KERNBASE);
intr_restore(s);
@@ -1893,6 +1917,27 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
return (FALSE);
}
+/*
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+ struct tte *tp;
+
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
+ return (FALSE);
+ TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
+ if ((tp->tte_data & TD_PV) == 0)
+ continue;
+ if ((tp->tte_data & TD_REF) != 0)
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
void
pmap_clear_modify(vm_page_t m)
{
@@ -1989,7 +2034,7 @@ pmap_activate(struct thread *td)
stxa(AA_DMMU_TSB, ASI_DMMU, pm->pm_tsb);
stxa(AA_IMMU_TSB, ASI_IMMU, pm->pm_tsb);
stxa(AA_DMMU_PCXR, ASI_DMMU, (ldxa(AA_DMMU_PCXR, ASI_DMMU) &
- TLB_PCXR_PGSZ_MASK) | context);
+ TLB_CXR_PGSZ_MASK) | context);
flush(KERNBASE);
mtx_unlock_spin(&sched_lock);
diff --git a/sys/sparc64/sparc64/support.S b/sys/sparc64/sparc64/support.S
index 821e694..d4ca5d3 100644
--- a/sys/sparc64/sparc64/support.S
+++ b/sys/sparc64/sparc64/support.S
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <machine/ktr.h>
#include <machine/pcb.h>
#include <machine/pstate.h>
+#include <machine/wstate.h>
#include "assym.s"
@@ -751,11 +752,20 @@ ENTRY(ofw_entry)
save %sp, -CCFSZ, %sp
SET(ofw_vec, %l7, %l6)
ldx [%l6], %l6
- rdpr %pil, %l7
- wrpr %g0, PIL_TICK, %pil
- call %l6
+ rdpr %pstate, %l7
+ andn %l7, PSTATE_AM | PSTATE_IE, %l5
+ wrpr %l5, 0, %pstate
+ SET(tba_taken_over, %l5, %l4)
+ brz,pn %l4, 1f
+ rdpr %wstate, %l5
+ andn %l5, WSTATE_PROM_MASK, %l3
+ wrpr %l3, WSTATE_PROM_KMIX, %wstate
+1: call %l6
mov %i0, %o0
- wrpr %l7, 0, %pil
+ brz,pn %l4, 1f
+ nop
+ wrpr %g0, %l5, %wstate
+1: wrpr %l7, 0, %pstate
ret
restore %o0, %g0, %o0
END(ofw_entry)
@@ -766,9 +776,14 @@ END(ofw_entry)
ENTRY(ofw_exit)
save %sp, -CCFSZ, %sp
flushw
- wrpr %g0, PIL_TICK, %pil
SET(ofw_tba, %l7, %l5)
ldx [%l5], %l5
+ rdpr %pstate, %l7
+ andn %l7, PSTATE_AM | PSTATE_IE, %l7
+ wrpr %l7, 0, %pstate
+ rdpr %wstate, %l7
+ andn %l7, WSTATE_PROM_MASK, %l7
+ wrpr %l7, WSTATE_PROM_KMIX, %wstate
wrpr %l5, 0, %tba ! restore the OFW trap table
SET(ofw_vec, %l7, %l6)
ldx [%l6], %l6
diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S
index af05316..ea13779 100644
--- a/sys/sparc64/sparc64/swtch.S
+++ b/sys/sparc64/sparc64/swtch.S
@@ -237,7 +237,7 @@ ENTRY(cpu_switch)
stxa %i4, [%i5] ASI_DMMU
mov AA_IMMU_TSB, %i5
stxa %i4, [%i5] ASI_IMMU
- setx TLB_PCXR_PGSZ_MASK, %i5, %i4
+ setx TLB_CXR_PGSZ_MASK, %i5, %i4
mov AA_DMMU_PCXR, %i5
ldxa [%i5] ASI_DMMU, %l1
and %l1, %i4, %l1
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index 3df335b..c0772a1 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -106,6 +106,7 @@ void trap(struct trapframe *tf);
void syscall(struct trapframe *tf);
static int fetch_syscall_args(struct thread *td, struct syscall_args *sa);
+static int trap_cecc(void);
static int trap_pfault(struct thread *td, struct trapframe *tf);
extern char copy_fault[];
@@ -240,6 +241,10 @@ int debugger_on_signal = 0;
SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
&debugger_on_signal, 0, "");
+u_int corrected_ecc = 0;
+SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
+ "corrected ECC errors");
+
/*
* SUNW,set-trap-table allows to take over %tba from the PROM, which
* will turn off interrupts and handle outstanding ones while doing so,
@@ -255,7 +260,8 @@ sun4u_set_traptable(void *tba_addr)
cell_t tba_addr;
} args = {
(cell_t)"SUNW,set-trap-table",
- 2,
+ 1,
+ 0,
};
args.tba_addr = (cell_t)tba_addr;
@@ -308,10 +314,16 @@ trap(struct trapframe *tf)
case T_SPILL:
sig = rwindow_save(td);
break;
+ case T_CORRECTED_ECC_ERROR:
+ sig = trap_cecc();
+ break;
default:
- if (tf->tf_type < 0 || tf->tf_type >= T_MAX ||
- trap_sig[tf->tf_type] == -1)
- panic("trap: bad trap type");
+ if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
+ panic("trap: bad trap type %#lx (user)",
+ tf->tf_type);
+ else if (trap_sig[tf->tf_type] == -1)
+ panic("trap: %s (user)",
+ trap_msg[tf->tf_type]);
sig = trap_sig[tf->tf_type];
break;
}
@@ -400,18 +412,53 @@ trap(struct trapframe *tf)
}
error = 1;
break;
+ case T_CORRECTED_ECC_ERROR:
+ error = trap_cecc();
+ break;
default:
error = 1;
break;
}
- if (error != 0)
- panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]);
+ if (error != 0) {
+ tf->tf_type &= ~T_KERNEL;
+ if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
+ panic("trap: bad trap type %#lx (kernel)",
+ tf->tf_type);
+ else if (trap_sig[tf->tf_type] == -1)
+ panic("trap: %s (kernel)",
+ trap_msg[tf->tf_type]);
+ }
}
CTR1(KTR_TRAP, "trap: td=%p return", td);
}
static int
+trap_cecc(void)
+{
+ u_long eee;
+
+ /*
+ * Turn off (non-)correctable error reporting while we're dealing
+ * with the error.
+ */
+ eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
+ stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
+ AA_ESTATE_CEEN));
+ /* Flush the caches in order ensure no corrupt data got installed. */
+ cache_flush();
+ /* Ensure the caches are still turned on (should be). */
+ cache_enable(PCPU_GET(impl));
+ /* Clear the the error from the AFSR. */
+ stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
+ corrected_ecc++;
+ printf("corrected ECC error\n");
+ /* Turn (non-)correctable error reporting back on. */
+ stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
+ return (0);
+}
+
+static int
trap_pfault(struct thread *td, struct trapframe *tf)
{
struct vmspace *vm;
@@ -664,7 +711,7 @@ syscall(struct trapframe *tf)
*/
WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
(sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
- syscallnames[sa.code] : "???");
+ syscallnames[sa.code] : "???");
KASSERT(td->td_critnest == 0,
("System call %s returning in a critical section",
(sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
diff --git a/sys/sun4v/conf/GENERIC b/sys/sun4v/conf/GENERIC
index 13db23d..26ec3af 100644
--- a/sys/sun4v/conf/GENERIC
+++ b/sys/sun4v/conf/GENERIC
@@ -51,7 +51,6 @@ options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
-options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty)
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options STACK # stack(9) support
@@ -184,6 +183,7 @@ device faith # IPv6-to-IPv4 relaying (translation)
device bpf # Berkeley packet filter
# USB support
+options USB_DEBUG # enable debug msgs
#device uhci # UHCI PCI->USB interface
#device ohci # OHCI PCI->USB interface
device usb # USB Bus (required)
diff --git a/sys/sun4v/include/_inttypes.h b/sys/sun4v/include/_inttypes.h
index e6b2536..a7cbea5 100644
--- a/sys/sun4v/include/_inttypes.h
+++ b/sys/sun4v/include/_inttypes.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/sun4v/include/ofw_machdep.h b/sys/sun4v/include/ofw_machdep.h
index 625b131..658d9c7 100644
--- a/sys/sun4v/include/ofw_machdep.h
+++ b/sys/sun4v/include/ofw_machdep.h
@@ -36,6 +36,7 @@ typedef uint64_t cell_t;
int OF_decode_addr(phandle_t, int, int *, bus_addr_t *);
void OF_getetheraddr(device_t, u_char *);
+u_int OF_getscsinitid(device_t);
void cpu_shutdown(void *);
int ofw_entry(void *);
void ofw_exit(void *);
diff --git a/sys/sun4v/include/proc.h b/sys/sun4v/include/proc.h
index bfd1268..84eaed5 100644
--- a/sys/sun4v/include/proc.h
+++ b/sys/sun4v/include/proc.h
@@ -51,4 +51,6 @@ struct mdproc {
void *md_sigtramp;
};
+#define KINFO_PROC_SIZE 1088
+
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/sun4v/sun4v/machdep.c b/sys/sun4v/sun4v/machdep.c
index 3913d35..e14eebd 100644
--- a/sys/sun4v/sun4v/machdep.c
+++ b/sys/sun4v/sun4v/machdep.c
@@ -869,7 +869,7 @@ ptrace_clear_single_step(struct thread *td)
}
void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf;
struct pcb *pcb;
@@ -897,8 +897,8 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
tf->tf_out[3] = p->p_sysent->sv_psstrings;
tf->tf_out[6] = sp - SPOFF - sizeof(struct frame);
- tf->tf_tnpc = entry + 4;
- tf->tf_tpc = entry;
+ tf->tf_tnpc = imgp->entry_addr + 4;
+ tf->tf_tpc = imgp->entry_addr;
tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO;
td->td_retval[0] = tf->tf_out[0];
diff --git a/sys/sun4v/sun4v/pmap.c b/sys/sun4v/sun4v/pmap.c
index d3b8c79..2633b8e 100644
--- a/sys/sun4v/sun4v/pmap.c
+++ b/sys/sun4v/sun4v/pmap.c
@@ -1592,6 +1592,17 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t va)
}
/*
+ * Return whether or not the specified physical page was referenced
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+ return (tte_get_phys_bit(m, VTD_REF));
+}
+
+/*
* Extract the physical page address associated with the given kernel virtual
* address.
*/
diff --git a/sys/sys/_timespec.h b/sys/sys/_timespec.h
index 9dcd5f8..d51559c 100644
--- a/sys/sys/_timespec.h
+++ b/sys/sys/_timespec.h
@@ -31,26 +31,18 @@
* $FreeBSD$
*/
-/*
- * Prerequisite: <sys/_types.h>
- *
- * This file must be kept synchronized with <sys/timespec.h>.
- * It defines a structure which must be a type pun for
- * `struct timespec'; this structure is used in header files where
- * the ABI uses a `struct timespec' but standards prohibit its
- * definition. (Currently only <sys/stat.h>.)
- *
- * XXX should just declare struct __timespec as necessary. It's simple,
- * so is easy to keep synchronized, and hopefully not needed in as many
- * places as struct timespec, so we don't need this extra header.
- * Perhaps we don't need timespec.h either.
- */
-
#ifndef _SYS__TIMESPEC_H_
#define _SYS__TIMESPEC_H_
-struct __timespec {
- __time_t tv_sec; /* seconds */
+#include <sys/_types.h>
+
+#ifndef _TIME_T_DECLARED
+typedef __time_t time_t;
+#define _TIME_T_DECLARED
+#endif
+
+struct timespec {
+ time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
diff --git a/sys/sys/alq.h b/sys/sys/alq.h
index bc4961e..4a502d2 100644
--- a/sys/sys/alq.h
+++ b/sys/sys/alq.h
@@ -1,7 +1,13 @@
/*-
* Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org>
+ * Copyright (c) 2008-2009, Lawrence Stewart <lstewart@freebsd.org>
+ * Copyright (c) 2010, The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed at the Centre for Advanced
+ * Internet Architectures, Swinburne University of Technology, Melbourne,
+ * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -41,46 +47,47 @@ extern struct thread *ald_thread;
* Async. Logging Entry
*/
struct ale {
- struct ale *ae_next; /* Next Entry */
- char *ae_data; /* Entry buffer */
- int ae_flags; /* Entry flags */
+ intptr_t ae_bytesused; /* # bytes written to ALE. */
+ char *ae_data; /* Write ptr. */
+ int ae_pad; /* Unused, compat. */
};
-#define AE_VALID 0x0001 /* Entry has valid data */
-
-
-/* waitok options */
-#define ALQ_NOWAIT 0x0001
-#define ALQ_WAITOK 0x0002
+/* Flag options. */
+#define ALQ_NOWAIT 0x0001 /* ALQ may not sleep. */
+#define ALQ_WAITOK 0x0002 /* ALQ may sleep. */
+#define ALQ_NOACTIVATE 0x0004 /* Don't activate ALQ after write. */
+#define ALQ_ORDERED 0x0010 /* Maintain write ordering between threads. */
/* Suggested mode for file creation. */
#define ALQ_DEFAULT_CMODE 0600
/*
- * alq_open: Creates a new queue
+ * alq_open_flags: Creates a new queue
*
* Arguments:
* alq Storage for a pointer to the newly created queue.
* file The filename to open for logging.
* cred Credential to authorize open and I/O with.
* cmode Creation mode for file, if new.
- * size The size of each entry in the queue.
- * count The number of items in the buffer, this should be large enough
- * to store items over the period of a disk write.
+ * size The size of the queue in bytes.
+ * flags ALQ_ORDERED
* Returns:
* error from open or 0 on success
*/
struct ucred;
-int alq_open(struct alq **, const char *file, struct ucred *cred, int cmode,
+int alq_open_flags(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
+ int size, int flags);
+int alq_open(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
int size, int count);
/*
- * alq_write: Write data into the queue
+ * alq_writen: Write data into the queue
*
* Arguments:
* alq The queue we're writing to
* data The entry to be recorded
- * waitok Are we permitted to wait?
+ * len The number of bytes to write from *data
+ * flags (ALQ_NOWAIT || ALQ_WAITOK), ALQ_NOACTIVATE
*
* Returns:
* EWOULDBLOCK if:
@@ -88,7 +95,8 @@ int alq_open(struct alq **, const char *file, struct ucred *cred, int cmode,
* The system is shutting down.
* 0 on success.
*/
-int alq_write(struct alq *alq, void *data, int waitok);
+int alq_writen(struct alq *alq, void *data, int len, int flags);
+int alq_write(struct alq *alq, void *data, int flags);
/*
* alq_flush: Flush the queue out to disk
@@ -101,27 +109,36 @@ void alq_flush(struct alq *alq);
void alq_close(struct alq *alq);
/*
- * alq_get: Return an entry for direct access
+ * alq_getn: Return an entry for direct access
*
* Arguments:
* alq The queue to retrieve an entry from
- * waitok Are we permitted to wait?
+ * len Max number of bytes required
+ * flags (ALQ_NOWAIT || ALQ_WAITOK)
*
* Returns:
* The next available ale on success.
* NULL if:
- * Waitok is ALQ_NOWAIT and the queue is full.
+ * flags is ALQ_NOWAIT and the queue is full.
* The system is shutting down.
*
* This leaves the queue locked until a subsequent alq_post.
*/
-struct ale *alq_get(struct alq *alq, int waitok);
+struct ale *alq_getn(struct alq *alq, int len, int flags);
+struct ale *alq_get(struct alq *alq, int flags);
/*
- * alq_post: Schedule the ale retrieved by alq_get for writing.
+ * alq_post_flags: Schedule the ale retrieved by alq_get/alq_getn for writing.
* alq The queue to post the entry to.
* ale An asynch logging entry returned by alq_get.
+ * flags ALQ_NOACTIVATE
*/
-void alq_post(struct alq *, struct ale *);
+void alq_post_flags(struct alq *alq, struct ale *ale, int flags);
+
+static __inline void
+alq_post(struct alq *alq, struct ale *ale)
+{
+ alq_post_flags(alq, ale, 0);
+}
#endif /* _SYS_ALQ_H_ */
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 8f3b1b2..137f90f 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -215,7 +215,7 @@ struct buf {
#define B_DIRTY 0x00200000 /* Needs writing later (in EXT2FS). */
#define B_RELBUF 0x00400000 /* Release VMIO buffer. */
#define B_00800000 0x00800000 /* Available flag. */
-#define B_01000000 0x01000000 /* Available flag. */
+#define B_NOCOPY 0x01000000 /* Don't copy-on-write this buf. */
#define B_NEEDSGIANT 0x02000000 /* Buffer's vnode needs giant. */
#define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */
#define B_MANAGED 0x08000000 /* Managed by FS. */
@@ -493,6 +493,7 @@ int bufwait(struct buf *);
int bufwrite(struct buf *);
void bufdone(struct buf *);
void bufdone_finish(struct buf *);
+void bd_speedup(void);
int cluster_read(struct vnode *, u_quad_t, daddr_t, long,
struct ucred *, long, int, struct buf **);
diff --git a/sys/sys/clock.h b/sys/sys/clock.h
index c08683e..b484bc8 100644
--- a/sys/sys/clock.h
+++ b/sys/sys/clock.h
@@ -13,13 +13,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h
index f323284..a14a1a1 100644
--- a/sys/sys/dtrace_bsd.h
+++ b/sys/sys/dtrace_bsd.h
@@ -50,7 +50,7 @@ typedef void (*cyclic_clock_func_t)(struct trapframe *);
*
* Defining them here avoids a proliferation of header files.
*/
-extern cyclic_clock_func_t lapic_cyclic_clock_func[];
+extern cyclic_clock_func_t cyclic_clock_func[];
/*
* The dtrace module handles traps that occur during a DTrace probe.
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h
index 6715efc..47a0efc 100644
--- a/sys/sys/eventhandler.h
+++ b/sys/sys/eventhandler.h
@@ -41,6 +41,14 @@ struct eventhandler_entry {
void *ee_arg;
};
+#ifdef VIMAGE
+struct eventhandler_entry_vimage {
+ void (* func)(void); /* Original function registered. */
+ void *ee_arg; /* Original argument registered. */
+ void *sparep[2];
+};
+#endif
+
struct eventhandler_list {
char *el_name;
int el_flags;
@@ -142,6 +150,14 @@ void eventhandler_deregister(struct eventhandler_list *list,
struct eventhandler_list *eventhandler_find_list(const char *name);
void eventhandler_prune_list(struct eventhandler_list *list);
+#ifdef VIMAGE
+typedef void (*vimage_iterator_func_t)(void *, ...);
+
+eventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list,
+ const char *name, void *func, void *arg, int priority,
+ vimage_iterator_func_t);
+#endif
+
/*
* Standard system event queues.
*/
diff --git a/sys/sys/iconv.h b/sys/sys/iconv.h
index 8620863..7ca84b5 100644
--- a/sys/sys/iconv.h
+++ b/sys/sys/iconv.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2001, Boris Popov
+ * Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h
index 79b389e..1d1e361 100644
--- a/sys/sys/imgact.h
+++ b/sys/sys/imgact.h
@@ -56,6 +56,7 @@ struct image_params {
struct vattr *attr; /* attributes of file */
const char *image_header; /* head of file to exec */
unsigned long entry_addr; /* entry address of target executable */
+ unsigned long reloc_base; /* load address of image */
char vmspace_destroyed; /* flag - we've blown away original vm space */
char interpreted; /* flag - this executable is interpreted */
char opened; /* flag - we have opened executable vnode */
@@ -80,7 +81,7 @@ struct thread;
int exec_check_permissions(struct image_params *);
register_t *exec_copyout_strings(struct image_params *);
int exec_new_vmspace(struct image_params *, struct sysentvec *);
-void exec_setregs(struct thread *, u_long, u_long, u_long);
+void exec_setregs(struct thread *, struct image_params *, u_long);
int exec_shell_imgact(struct image_params *);
int exec_copyin_args(struct image_args *, char *, enum uio_seg,
char **, char **);
diff --git a/sys/sys/ioccom.h b/sys/sys/ioccom.h
index be2ce66..5669088 100644
--- a/sys/sys/ioccom.h
+++ b/sys/sys/ioccom.h
@@ -38,12 +38,13 @@
* any in or out parameters in the upper word. The high 3 bits of the
* upper word are used to encode the in/out status of the parameter.
*/
-#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
+#define IOCPARM_SHIFT 13 /* number of bits for ioctl size */
+#define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */
#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
#define IOCGROUP(x) (((x) >> 8) & 0xff)
-#define IOCPARM_MAX PAGE_SIZE /* max size of ioctl, mult. of PAGE_SIZE */
+#define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* copy in parameters */
diff --git a/sys/sys/mchain.h b/sys/sys/mchain.h
index 69775ff..4ee32e4 100644
--- a/sys/sys/mchain.h
+++ b/sys/sys/mchain.h
@@ -10,12 +10,6 @@
* 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index b826413..20dcf64 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -275,7 +275,8 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
MNT_ROOTFS | MNT_NOATIME | MNT_NOCLUSTERR| \
MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP | \
MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \
- MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | MNT_NFS4ACLS)
+ MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | \
+ MNT_NFS4ACLS)
/* Mask of flags that can be updated. */
#define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \
@@ -324,6 +325,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
#define MNTK_REFEXPIRE 0x00000020 /* refcount expiring is happening */
#define MNTK_EXTENDED_SHARED 0x00000040 /* Allow shared locking for more ops */
#define MNTK_SHARED_WRITES 0x00000080 /* Allow shared locking for writes */
+#define MNTK_SUJ 0x00000100 /* Softdep journaling enabled */
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
#define MNTK_SUSPEND 0x08000000 /* request write suspension */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 11e3fa6..9f87ee2 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 900009 /* Master, propagated to newvers */
+#define __FreeBSD_version 900010 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index ae6cc09..30fbb14 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -42,22 +42,19 @@
#include <sys/resource.h>
#include <machine/pcpu.h>
-struct pcb;
-struct thread;
-
/*
* Define a set for pcpu data.
*
* We don't use SET_DECLARE because it defines the set as 'a' when we
- * want 'aw'. GCC considers uninitialized data in a seperate section
- * writable and there is no generic zero initializer that works for
+ * want 'aw'. gcc considers uninitialized data in a separate section
+ * writable, and there is no generic zero initializer that works for
* structs and scalars.
*/
extern uintptr_t *__start_set_pcpu;
extern uintptr_t *__stop_set_pcpu;
__asm__(
-#if defined(__arm__)
+#ifdef __arm__
".section set_pcpu, \"aw\", %progbits\n"
#else
".section set_pcpu, \"aw\", @progbits\n"
@@ -73,8 +70,8 @@ extern uintptr_t dpcpu_off[];
/*
* Convenience defines.
*/
-#define DPCPU_START (uintptr_t)&__start_set_pcpu
-#define DPCPU_STOP (uintptr_t)&__stop_set_pcpu
+#define DPCPU_START ((uintptr_t)&__start_set_pcpu)
+#define DPCPU_STOP ((uintptr_t)&__stop_set_pcpu)
#define DPCPU_BYTES (DPCPU_STOP - DPCPU_START)
#define DPCPU_MODMIN 2048
#define DPCPU_SIZE roundup2(DPCPU_BYTES, PAGE_SIZE)
@@ -111,8 +108,8 @@ extern uintptr_t dpcpu_off[];
/*
* XXXUPS remove as soon as we have per cpu variable
- * linker sets and can define rm_queue in _rm_lock.h
-*/
+ * linker sets and can define rm_queue in _rm_lock.h
+ */
struct rm_queue {
struct rm_queue* volatile rmq_next;
struct rm_queue* volatile rmq_prev;
@@ -120,7 +117,6 @@ struct rm_queue {
#define PCPU_NAME_LEN (sizeof("CPU ") + sizeof(__XSTRING(MAXCPU) + 1))
-
/*
* This structure maps out the global data that needs to be kept on a
* per-cpu basis. The members are accessed via the PCPU_GET/SET/PTR
@@ -133,52 +129,50 @@ struct pcpu {
struct thread *pc_fpcurthread; /* Fp state owner */
struct thread *pc_deadthread; /* Zombie thread or NULL */
struct pcb *pc_curpcb; /* Current pcb */
- uint64_t pc_switchtime;
- int pc_switchticks;
+ uint64_t pc_switchtime; /* cpu_ticks() at last csw */
+ int pc_switchticks; /* `ticks' at last csw */
u_int pc_cpuid; /* This cpu number */
cpumask_t pc_cpumask; /* This cpu mask */
cpumask_t pc_other_cpus; /* Mask of all other cpus */
SLIST_ENTRY(pcpu) pc_allcpu;
struct lock_list_entry *pc_spinlocks;
#ifdef KTR
- char pc_name[PCPU_NAME_LEN]; /* String name for KTR. */
+ char pc_name[PCPU_NAME_LEN]; /* String name for KTR */
#endif
struct vmmeter pc_cnt; /* VM stats counters */
long pc_cp_time[CPUSTATES]; /* statclock ticks */
struct device *pc_device;
- void *pc_netisr; /* netisr SWI cookie. */
+ void *pc_netisr; /* netisr SWI cookie */
- /*
+ /*
* Stuff for read mostly lock
- *
+ *
* XXXUPS remove as soon as we have per cpu variable
* linker sets.
*/
- struct rm_queue pc_rm_queue;
+ struct rm_queue pc_rm_queue;
- /*
- * Dynamic per-cpu data area.
- */
- uintptr_t pc_dynamic;
+ uintptr_t pc_dynamic; /* Dynamic per-cpu data area */
/*
* Keep MD fields last, so that CPU-specific variations on a
* single architecture don't result in offset variations of
- * the machine-independent fields of the pcpu. Even though
+ * the machine-independent fields of the pcpu. Even though
* the pcpu structure is private to the kernel, some ports
- * (e.g. lsof, part of gtop) define _KERNEL and include this
- * header. While strictly speaking this is wrong, there's no
- * reason not to keep the offsets of the MI fields contants.
- * If only to make kernel debugging easier...
+ * (e.g., lsof, part of gtop) define _KERNEL and include this
+ * header. While strictly speaking this is wrong, there's no
+ * reason not to keep the offsets of the MI fields constant
+ * if only to make kernel debugging easier.
*/
PCPU_MD_FIELDS;
-} __aligned(128);
+} __aligned(CACHE_LINE_SIZE);
#ifdef _KERNEL
SLIST_HEAD(cpuhead, pcpu);
extern struct cpuhead cpuhead;
+extern struct pcpu *cpuid_to_pcpu[MAXCPU];
#define curcpu PCPU_GET(cpuid)
#define curproc (curthread->td_proc)
@@ -193,21 +187,17 @@ extern struct cpuhead cpuhead;
* db_show_mdpcpu() is responsible for handling machine dependent
* fields for the DDB 'show pcpu' command.
*/
-
-extern struct pcpu *cpuid_to_pcpu[MAXCPU];
-
-
void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
void db_show_mdpcpu(struct pcpu *pcpu);
-void pcpu_destroy(struct pcpu *pcpu);
-struct pcpu *pcpu_find(u_int cpuid);
-void pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
void *dpcpu_alloc(int size);
void dpcpu_copy(void *s, int size);
void dpcpu_free(void *s, int size);
void dpcpu_init(void *dpcpu, int cpuid);
+void pcpu_destroy(struct pcpu *pcpu);
+struct pcpu *pcpu_find(u_int cpuid);
+void pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
-#endif /* _KERNEL */
+#endif /* _KERNEL */
#endif /* !_SYS_PCPU_H_ */
diff --git a/sys/sys/pioctl.h b/sys/sys/pioctl.h
index 91a3229..3213d59 100644
--- a/sys/sys/pioctl.h
+++ b/sys/sys/pioctl.h
@@ -1,5 +1,5 @@
/*-
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index f4a29ce..9da2cc8 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -40,7 +40,7 @@
#define PMC_MODULE_NAME "hwpmc"
#define PMC_NAME_MAX 16 /* HW counter name size */
-#define PMC_CLASS_MAX 4 /* max #classes of PMCs per-system */
+#define PMC_CLASS_MAX 6 /* max #classes of PMCs per-system */
/*
* Kernel<->userland API version number [MMmmpppp]
@@ -84,8 +84,10 @@
__PMC_CPU(INTEL_CORE2, 0x88, "Intel Core2") \
__PMC_CPU(INTEL_CORE2EXTREME, 0x89, "Intel Core2 Extreme") \
__PMC_CPU(INTEL_ATOM, 0x8A, "Intel Atom") \
- __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7") \
- __PMC_CPU(INTEL_XSCALE, 0x100, "Intel XScale")
+ __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7") \
+ __PMC_CPU(INTEL_WESTMERE, 0x8C, "Intel Westmere") \
+ __PMC_CPU(INTEL_XSCALE, 0x100, "Intel XScale") \
+ __PMC_CPU(MIPS_24K, 0x200, "MIPS 24K")
enum pmc_cputype {
#undef __PMC_CPU
@@ -94,7 +96,7 @@ enum pmc_cputype {
};
#define PMC_CPU_FIRST PMC_CPU_AMD_K7
-#define PMC_CPU_LAST PMC_CPU_INTEL_XSCALE
+#define PMC_CPU_LAST PMC_CPU_MIPS_24K
/*
* Classes of PMCs
@@ -108,8 +110,11 @@ enum pmc_cputype {
__PMC_CLASS(P6) /* Intel Pentium Pro counters */ \
__PMC_CLASS(P4) /* Intel Pentium-IV counters */ \
__PMC_CLASS(IAF) /* Intel Core2/Atom, fixed function */ \
- __PMC_CLASS(IAP) /* Intel Core...Atom, programmable */ \
- __PMC_CLASS(XSCALE) /* Intel XScale counters */
+ __PMC_CLASS(IAP) /* Intel Core...Atom, programmable */ \
+ __PMC_CLASS(UCF) /* Intel Uncore programmable */ \
+ __PMC_CLASS(UCP) /* Intel Uncore fixed function */ \
+ __PMC_CLASS(XSCALE) /* Intel XScale counters */ \
+ __PMC_CLASS(MIPS24K) /* MIPS 24K */
enum pmc_class {
#undef __PMC_CLASS
@@ -118,7 +123,7 @@ enum pmc_class {
};
#define PMC_CLASS_FIRST PMC_CLASS_TSC
-#define PMC_CLASS_LAST PMC_CLASS_XSCALE
+#define PMC_CLASS_LAST PMC_CLASS_MIPS24K
/*
* A PMC can be in the following states:
@@ -296,7 +301,7 @@ enum pmc_event {
__PMC_OP(PMCRW, "Read/Set a PMC") \
__PMC_OP(PMCSETCOUNT, "Set initial count/sampling rate") \
__PMC_OP(PMCSTART, "Start a PMC") \
- __PMC_OP(PMCSTOP, "Start a PMC") \
+ __PMC_OP(PMCSTOP, "Stop a PMC") \
__PMC_OP(WRITELOG, "Write a cookie to the log file")
@@ -757,7 +762,7 @@ struct pmc_owner {
};
#define PMC_PO_OWNS_LOGFILE 0x00000001 /* has a log file */
-#define PMC_PO_IN_FLUSH 0x00000010 /* in the middle of a flush */
+#define PMC_PO_SHUTDOWN 0x00000010 /* in the process of shutdown */
#define PMC_PO_INITIAL_MAPPINGS_DONE 0x00000020
/*
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index dd9efae..fb31cfc 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -573,7 +573,7 @@ struct proc {
#define P_WAITED 0x01000 /* Someone is waiting for us. */
#define P_WEXIT 0x02000 /* Working on exiting. */
#define P_EXEC 0x04000 /* Process called exec. */
-#define P_UNUSED8000 0x08000 /* available. */
+#define P_WKILLED 0x08000 /* Killed, go to kernel/user boundary ASAP. */
#define P_CONTINUED 0x10000 /* Proc has continued from a stopped state. */
#define P_STOPPED_SIG 0x20000 /* Stopped due to SIGSTOP/SIGTSTP. */
#define P_STOPPED_TRACE 0x40000 /* Stopped because of tracing. */
@@ -592,6 +592,7 @@ struct proc {
#define P_STOPPED (P_STOPPED_SIG|P_STOPPED_SINGLE|P_STOPPED_TRACE)
#define P_SHOULDSTOP(p) ((p)->p_flag & P_STOPPED)
+#define P_KILLED(p) ((p)->p_flag & P_WKILLED)
/*
* These were process status values (p_stat), now they are only used in
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
index e3653b6..b30447c 100644
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -34,6 +34,7 @@
#define _SYS_PTRACE_H_
#include <sys/_sigset.h>
+#include <machine/reg.h>
#define PT_TRACE_ME 0 /* child declares it's being traced */
#define PT_READ_I 1 /* read word in child's I space */
@@ -157,7 +158,7 @@ int proc_read_dbregs(struct thread *_td, struct dbreg *_dbreg);
int proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg);
int proc_sstep(struct thread *_td);
int proc_rwmem(struct proc *_p, struct uio *_uio);
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
struct reg32;
struct fpreg32;
struct dbreg32;
diff --git a/sys/sys/stat.h b/sys/sys/stat.h
index 856d674..1b03bd2 100644
--- a/sys/sys/stat.h
+++ b/sys/sys/stat.h
@@ -39,6 +39,7 @@
#define _SYS_STAT_H_
#include <sys/cdefs.h>
+#include <sys/_timespec.h>
#include <sys/_types.h>
#ifndef _BLKSIZE_T_DECLARED
@@ -86,11 +87,6 @@ typedef __off_t off_t;
#define _OFF_T_DECLARED
#endif
-#ifndef _TIME_T_DECLARED
-typedef __time_t time_t;
-#define _TIME_T_DECLARED
-#endif
-
#ifndef _UID_T_DECLARED
typedef __uid_t uid_t;
#define _UID_T_DECLARED
@@ -98,16 +94,11 @@ typedef __uid_t uid_t;
#if !defined(_KERNEL) && __BSD_VISIBLE
/*
- * XXX we need this for struct timespec. We get miscellaneous namespace
- * pollution with it.
+ * XXX We get miscellaneous namespace pollution with this.
*/
#include <sys/time.h>
#endif
-#if !__BSD_VISIBLE
-#include <sys/_timespec.h>
-#endif
-
#if __BSD_VISIBLE
struct ostat {
__uint16_t st_dev; /* inode's device */
@@ -118,9 +109,9 @@ struct ostat {
__uint16_t st_gid; /* group ID of the file's group */
__uint16_t st_rdev; /* device type */
__int32_t st_size; /* file size, in bytes */
- struct timespec st_atimespec; /* time of last access */
- struct timespec st_mtimespec; /* time of last data modification */
- struct timespec st_ctimespec; /* time of last file status change */
+ struct timespec st_atim; /* time of last access */
+ struct timespec st_mtim; /* time of last data modification */
+ struct timespec st_ctim; /* time of last file status change */
__int32_t st_blksize; /* optimal blocksize for I/O */
__int32_t st_blocks; /* blocks allocated for file */
fflags_t st_flags; /* user defined flags for file */
@@ -136,28 +127,18 @@ struct stat {
uid_t st_uid; /* user ID of the file's owner */
gid_t st_gid; /* group ID of the file's group */
__dev_t st_rdev; /* device type */
-#if __BSD_VISIBLE
- struct timespec st_atimespec; /* time of last access */
- struct timespec st_mtimespec; /* time of last data modification */
- struct timespec st_ctimespec; /* time of last file status change */
-#else
- time_t st_atime; /* time of last access */
- long __st_atimensec; /* nsec of last access */
- time_t st_mtime; /* time of last data modification */
- long __st_mtimensec; /* nsec of last data modification */
- time_t st_ctime; /* time of last file status change */
- long __st_ctimensec; /* nsec of last file status change */
-#endif
+ struct timespec st_atim; /* time of last access */
+ struct timespec st_mtim; /* time of last data modification */
+ struct timespec st_ctim; /* time of last file status change */
off_t st_size; /* file size, in bytes */
blkcnt_t st_blocks; /* blocks allocated for file */
blksize_t st_blksize; /* optimal blocksize for I/O */
fflags_t st_flags; /* user defined flags for file */
__uint32_t st_gen; /* file generation number */
__int32_t st_lspare;
-#if __BSD_VISIBLE
- struct timespec st_birthtimespec; /* time of file creation */
+ struct timespec st_birthtim; /* time of file creation */
/*
- * Explicitly pad st_birthtimespec to 16 bytes so that the size of
+ * Explicitly pad st_birthtim to 16 bytes so that the size of
* struct stat is backwards compatible. We use bitfields instead
* of an array of chars so that this doesn't require a C99 compiler
* to compile if the size of the padding is 0. We use 2 bitfields
@@ -166,12 +147,6 @@ struct stat {
*/
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
-#else
- time_t st_birthtime; /* time of file creation */
- long st_birthtimensec; /* nsec of file creation */
- unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec));
- unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec));
-#endif
};
#if __BSD_VISIBLE
@@ -183,15 +158,15 @@ struct nstat {
uid_t st_uid; /* user ID of the file's owner */
gid_t st_gid; /* group ID of the file's group */
__dev_t st_rdev; /* device type */
- struct timespec st_atimespec; /* time of last access */
- struct timespec st_mtimespec; /* time of last data modification */
- struct timespec st_ctimespec; /* time of last file status change */
+ struct timespec st_atim; /* time of last access */
+ struct timespec st_mtim; /* time of last data modification */
+ struct timespec st_ctim; /* time of last file status change */
off_t st_size; /* file size, in bytes */
blkcnt_t st_blocks; /* blocks allocated for file */
blksize_t st_blksize; /* optimal blocksize for I/O */
fflags_t st_flags; /* user defined flags for file */
__uint32_t st_gen; /* file generation number */
- struct timespec st_birthtimespec; /* time of file creation */
+ struct timespec st_birthtim; /* time of file creation */
/*
* See above about the following padding.
*/
@@ -200,13 +175,23 @@ struct nstat {
};
#endif
+#ifndef _KERNEL
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
#if __BSD_VISIBLE
-#define st_atime st_atimespec.tv_sec
-#define st_mtime st_mtimespec.tv_sec
-#define st_ctime st_ctimespec.tv_sec
-#define st_birthtime st_birthtimespec.tv_sec
+#define st_birthtime st_birthtim.tv_sec
#endif
+/* For compatibility. */
+#if __BSD_VISIBLE
+#define st_atimespec st_atim
+#define st_mtimespec st_mtim
+#define st_ctimespec st_ctim
+#define st_birthtimespec st_birthtim
+#endif
+#endif /* !_KERNEL */
+
#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#if __BSD_VISIBLE
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index a7a2907..c3a19d8 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -98,7 +98,8 @@ struct sysentvec {
vm_offset_t sv_psstrings; /* PS_STRINGS */
int sv_stackprot; /* vm protection for stack */
register_t *(*sv_copyout_strings)(struct image_params *);
- void (*sv_setregs)(struct thread *, u_long, u_long, u_long);
+ void (*sv_setregs)(struct thread *, struct image_params *,
+ u_long);
void (*sv_fixlimit)(struct rlimit *, int);
u_long *sv_maxssiz;
u_int sv_flags;
@@ -149,7 +150,7 @@ static struct syscall_module_data name##_syscall_mod = { \
}; \
\
static moduledata_t name##_mod = { \
- #name, \
+ "sys/" #name, \
syscall_module_handler, \
&name##_syscall_mod \
}; \
@@ -166,10 +167,34 @@ SYSCALL_MODULE(syscallname, \
(sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmnosys && \
sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmressys)
+/*
+ * Syscall registration helpers with resource allocation handling.
+ */
+struct syscall_helper_data {
+ struct sysent new_sysent;
+ struct sysent old_sysent;
+ int syscall_no;
+ int registered;
+};
+#define SYSCALL_INIT_HELPER(syscallname) { \
+ .new_sysent = { \
+ .sy_narg = (sizeof(struct syscallname ## _args ) \
+ / sizeof(register_t)), \
+ .sy_call = (sy_call_t *)& syscallname, \
+ .sy_auevent = SYS_AUE_##syscallname \
+ }, \
+ .syscall_no = SYS_##syscallname \
+}
+#define SYSCALL_INIT_LAST { \
+ .syscall_no = NO_SYSCALL \
+}
+
int syscall_register(int *offset, struct sysent *new_sysent,
struct sysent *old_sysent);
int syscall_deregister(int *offset, struct sysent *old_sysent);
int syscall_module_handler(struct module *mod, int what, void *arg);
+int syscall_helper_register(struct syscall_helper_data *sd);
+int syscall_helper_unregister(struct syscall_helper_data *sd);
/* Special purpose system call functions. */
struct nosys_args;
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 3868c9a..1d861f0 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -65,6 +65,11 @@ extern int maxusers; /* system tune hint */
extern int ngroups_max; /* max # of supplemental groups */
extern int vm_guest; /* Running as virtual machine guest? */
+/*
+ * Detected virtual machine guest types. The intention is to expand
+ * and/or add to the VM_GUEST_VM type if specific VM functionality is
+ * ever implemented (e.g. vendor-specific paravirtualization features).
+ */
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
#ifdef INVARIANTS /* The option is always available */
diff --git a/sys/sys/thr.h b/sys/sys/thr.h
index ae4a65d..7ccc872 100644
--- a/sys/sys/thr.h
+++ b/sys/sys/thr.h
@@ -30,6 +30,7 @@
#ifndef _SYS_THR_H_
#define _SYS_THR_H_
+#include <sys/cdefs.h>
#include <sys/_types.h>
#include <sys/sched.h>
@@ -68,6 +69,7 @@ typedef __pid_t pid_t;
#define _PID_T_DECLARED
#endif
+__BEGIN_DECLS
int thr_create(ucontext_t *ctx, long *id, int flags);
int thr_new(struct thr_param *param, int param_size);
int thr_self(long *id);
@@ -77,7 +79,7 @@ int thr_kill2(pid_t pid, long id, int sig);
int thr_suspend(const struct timespec *timeout);
int thr_wake(long id);
int thr_set_name(long id, const char *name);
-
+__END_DECLS
#endif /* !_KERNEL */
#endif /* ! _SYS_THR_H_ */
diff --git a/sys/sys/timeb.h b/sys/sys/timeb.h
index 59aa466..810c523 100644
--- a/sys/sys/timeb.h
+++ b/sys/sys/timeb.h
@@ -38,6 +38,10 @@
#ifndef _SYS_TIMEB_H_
#define _SYS_TIMEB_H_
+#ifdef __GNUC__
+#warning "this file includes <sys/timeb.h> which is deprecated"
+#endif
+
#include <sys/_types.h>
#ifndef _TIME_T_DECLARED
diff --git a/sys/sys/timespec.h b/sys/sys/timespec.h
index 8986c09..2505cef 100644
--- a/sys/sys/timespec.h
+++ b/sys/sys/timespec.h
@@ -31,22 +31,11 @@
* $FreeBSD$
*/
-/*
- * Prerequisites: <sys/cdefs.h>, <sys/_types.h>
- */
-
#ifndef _SYS_TIMESPEC_H_
#define _SYS_TIMESPEC_H_
-#ifndef _TIME_T_DECLARED
-typedef __time_t time_t;
-#define _TIME_T_DECLARED
-#endif
-
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
+#include <sys/cdefs.h>
+#include <sys/_timespec.h>
#if __BSD_VISIBLE
#define TIMEVAL_TO_TIMESPEC(tv, ts) \
diff --git a/sys/sys/user.h b/sys/sys/user.h
index d5e46fe..34635e3 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -87,34 +87,11 @@
#define KI_NSPARE_LONG 12
#define KI_NSPARE_PTR 7
-#ifdef __amd64__
-#define KINFO_PROC_SIZE 1088
-#endif
-#ifdef __arm__
-#define KINFO_PROC_SIZE 792
-#endif
-#ifdef __ia64__
-#define KINFO_PROC_SIZE 1088
-#endif
-#ifdef __i386__
-#define KINFO_PROC_SIZE 768
-#endif
-#ifdef __mips__
-#ifdef __mips_n64
-#define KINFO_PROC_SIZE 1088
-#else
-#define KINFO_PROC_SIZE 816
-#endif
-#endif
-#ifdef __powerpc__
-#define KINFO_PROC_SIZE 768
-#endif
-#ifdef __sparc64__
-#define KINFO_PROC_SIZE 1088
-#endif
+#ifndef _KERNEL
#ifndef KINFO_PROC_SIZE
#error "Unknown architecture"
#endif
+#endif /* !_KERNEL */
#define WMESGLEN 8 /* size of returned wchan message */
#define LOCKNAMELEN 8 /* size of returned lock name */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 4c84ea3..b5784e4 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -720,6 +720,8 @@ void vop_symlink_post(void *a, int rc);
void vop_unlock_post(void *a, int rc);
void vop_unlock_pre(void *a);
+void vop_rename_fail(struct vop_rename_args *ap);
+
#define VOP_WRITE_PRE(ap) \
struct vattr va; \
int error, osize, ooffset, noffset; \
diff --git a/sys/sys/vtoc.h b/sys/sys/vtoc.h
index 231da00..7745bca 100644
--- a/sys/sys/vtoc.h
+++ b/sys/sys/vtoc.h
@@ -97,7 +97,7 @@ struct vtoc8 {
} map[VTOC8_NPARTS];
uint16_t magic;
uint16_t cksum;
-};
+} __packed;
#ifdef CTASSERT
CTASSERT(sizeof(struct vtoc8) == 512);
diff --git a/sys/teken/teken.c b/sys/teken/teken.c
index 1435d2f..91d706f 100644
--- a/sys/teken/teken.c
+++ b/sys/teken/teken.c
@@ -36,7 +36,7 @@
#else /* !(__FreeBSD__ && _KERNEL) */
#include <sys/types.h>
#include <assert.h>
-#include <inttypes.h>
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define teken_assert(x) assert(x)
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 7bf1177..b1f7ba0 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -94,24 +94,24 @@ __FBSDID("$FreeBSD$");
#include <ufs/ffs/ffs_extern.h>
typedef ufs2_daddr_t allocfcn_t(struct inode *ip, u_int cg, ufs2_daddr_t bpref,
- int size);
+ int size, int rsize);
-static ufs2_daddr_t ffs_alloccg(struct inode *, u_int, ufs2_daddr_t, int);
+static ufs2_daddr_t ffs_alloccg(struct inode *, u_int, ufs2_daddr_t, int, int);
static ufs2_daddr_t
- ffs_alloccgblk(struct inode *, struct buf *, ufs2_daddr_t);
+ ffs_alloccgblk(struct inode *, struct buf *, ufs2_daddr_t, int);
#ifdef INVARIANTS
static int ffs_checkblk(struct inode *, ufs2_daddr_t, long);
#endif
-static ufs2_daddr_t ffs_clusteralloc(struct inode *, u_int, ufs2_daddr_t, int);
-static void ffs_clusteracct(struct ufsmount *, struct fs *, struct cg *,
- ufs1_daddr_t, int);
+static ufs2_daddr_t ffs_clusteralloc(struct inode *, u_int, ufs2_daddr_t, int,
+ int);
static ino_t ffs_dirpref(struct inode *);
static ufs2_daddr_t ffs_fragextend(struct inode *, u_int, ufs2_daddr_t,
int, int);
static void ffs_fserr(struct fs *, ino_t, char *);
static ufs2_daddr_t ffs_hashalloc
- (struct inode *, u_int, ufs2_daddr_t, int, allocfcn_t *);
-static ufs2_daddr_t ffs_nodealloccg(struct inode *, u_int, ufs2_daddr_t, int);
+ (struct inode *, u_int, ufs2_daddr_t, int, int, allocfcn_t *);
+static ufs2_daddr_t ffs_nodealloccg(struct inode *, u_int, ufs2_daddr_t, int,
+ int);
static ufs1_daddr_t ffs_mapsearch(struct fs *, struct cg *, ufs2_daddr_t, int);
static int ffs_reallocblks_ufs1(struct vop_reallocblks_args *);
static int ffs_reallocblks_ufs2(struct vop_reallocblks_args *);
@@ -188,7 +188,7 @@ retry:
cg = ino_to_cg(fs, ip->i_number);
else
cg = dtog(fs, bpref);
- bno = ffs_hashalloc(ip, cg, bpref, size, ffs_alloccg);
+ bno = ffs_hashalloc(ip, cg, bpref, size, size, ffs_alloccg);
if (bno > 0) {
delta = btodb(size);
if (ip->i_flag & IN_SPACECOUNTED) {
@@ -387,16 +387,12 @@ retry:
panic("ffs_realloccg: bad optim");
/* NOTREACHED */
}
- bno = ffs_hashalloc(ip, cg, bpref, request, ffs_alloccg);
+ bno = ffs_hashalloc(ip, cg, bpref, request, nsize, ffs_alloccg);
if (bno > 0) {
bp->b_blkno = fsbtodb(fs, bno);
if (!DOINGSOFTDEP(vp))
ffs_blkfree(ump, fs, ip->i_devvp, bprev, (long)osize,
- ip->i_number);
- if (nsize < request)
- ffs_blkfree(ump, fs, ip->i_devvp,
- bno + numfrags(fs, nsize),
- (long)(request - nsize), ip->i_number);
+ ip->i_number, NULL);
delta = btodb(nsize - osize);
if (ip->i_flag & IN_SPACECOUNTED) {
UFS_LOCK(ump);
@@ -487,6 +483,14 @@ ffs_reallocblks(ap)
if (doreallocblks == 0)
return (ENOSPC);
+ /*
+ * We can't wait in softdep prealloc as it may fsync and recurse
+ * here. Instead we simply fail to reallocate blocks if this
+ * rare condition arises.
+ */
+ if (DOINGSOFTDEP(ap->a_vp))
+ if (softdep_prealloc(ap->a_vp, MNT_NOWAIT) != 0)
+ return (ENOSPC);
if (VTOI(ap->a_vp)->i_ump->um_fstype == UFS1)
return (ffs_reallocblks_ufs1(ap));
return (ffs_reallocblks_ufs2(ap));
@@ -587,7 +591,7 @@ ffs_reallocblks_ufs1(ap)
* Search the block map looking for an allocation of the desired size.
*/
if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref,
- len, ffs_clusteralloc)) == 0) {
+ len, len, ffs_clusteralloc)) == 0) {
UFS_UNLOCK(ump);
goto fail;
}
@@ -673,7 +677,7 @@ ffs_reallocblks_ufs1(ap)
if (!DOINGSOFTDEP(vp))
ffs_blkfree(ump, fs, ip->i_devvp,
dbtofsb(fs, buflist->bs_children[i]->b_blkno),
- fs->fs_bsize, ip->i_number);
+ fs->fs_bsize, ip->i_number, NULL);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
#ifdef INVARIANTS
if (!ffs_checkblk(ip,
@@ -795,7 +799,7 @@ ffs_reallocblks_ufs2(ap)
* Search the block map looking for an allocation of the desired size.
*/
if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref,
- len, ffs_clusteralloc)) == 0) {
+ len, len, ffs_clusteralloc)) == 0) {
UFS_UNLOCK(ump);
goto fail;
}
@@ -881,7 +885,7 @@ ffs_reallocblks_ufs2(ap)
if (!DOINGSOFTDEP(vp))
ffs_blkfree(ump, fs, ip->i_devvp,
dbtofsb(fs, buflist->bs_children[i]->b_blkno),
- fs->fs_bsize, ip->i_number);
+ fs->fs_bsize, ip->i_number, NULL);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
#ifdef INVARIANTS
if (!ffs_checkblk(ip,
@@ -969,7 +973,7 @@ ffs_valloc(pvp, mode, cred, vpp)
if (fs->fs_contigdirs[cg] > 0)
fs->fs_contigdirs[cg]--;
}
- ino = (ino_t)ffs_hashalloc(pip, cg, ipref, mode,
+ ino = (ino_t)ffs_hashalloc(pip, cg, ipref, mode, 0,
(allocfcn_t *)ffs_nodealloccg);
if (ino == 0)
goto noinodes;
@@ -1278,11 +1282,12 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap)
*/
/*VARARGS5*/
static ufs2_daddr_t
-ffs_hashalloc(ip, cg, pref, size, allocator)
+ffs_hashalloc(ip, cg, pref, size, rsize, allocator)
struct inode *ip;
u_int cg;
ufs2_daddr_t pref;
- int size; /* size for data blocks, mode for inodes */
+ int size; /* Search size for data blocks, mode for inodes */
+ int rsize; /* Real allocated size. */
allocfcn_t *allocator;
{
struct fs *fs;
@@ -1298,7 +1303,7 @@ ffs_hashalloc(ip, cg, pref, size, allocator)
/*
* 1: preferred cylinder group
*/
- result = (*allocator)(ip, cg, pref, size);
+ result = (*allocator)(ip, cg, pref, size, rsize);
if (result)
return (result);
/*
@@ -1308,7 +1313,7 @@ ffs_hashalloc(ip, cg, pref, size, allocator)
cg += i;
if (cg >= fs->fs_ncg)
cg -= fs->fs_ncg;
- result = (*allocator)(ip, cg, 0, size);
+ result = (*allocator)(ip, cg, 0, size, rsize);
if (result)
return (result);
}
@@ -1319,7 +1324,7 @@ ffs_hashalloc(ip, cg, pref, size, allocator)
*/
cg = (icg + 2) % fs->fs_ncg;
for (i = 2; i < fs->fs_ncg; i++) {
- result = (*allocator)(ip, cg, 0, size);
+ result = (*allocator)(ip, cg, 0, size, rsize);
if (result)
return (result);
cg++;
@@ -1401,7 +1406,8 @@ ffs_fragextend(ip, cg, bprev, osize, nsize)
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_blkmapdep(bp, UFSTOVFS(ump), bprev);
+ softdep_setup_blkmapdep(bp, UFSTOVFS(ump), bprev,
+ frags, numfrags(fs, osize));
bdwrite(bp);
return (bprev);
@@ -1419,11 +1425,12 @@ fail:
* and if it is, allocate it.
*/
static ufs2_daddr_t
-ffs_alloccg(ip, cg, bpref, size)
+ffs_alloccg(ip, cg, bpref, size, rsize)
struct inode *ip;
u_int cg;
ufs2_daddr_t bpref;
int size;
+ int rsize;
{
struct fs *fs;
struct cg *cgp;
@@ -1451,7 +1458,7 @@ ffs_alloccg(ip, cg, bpref, size)
cgp->cg_old_time = cgp->cg_time = time_second;
if (size == fs->fs_bsize) {
UFS_LOCK(ump);
- blkno = ffs_alloccgblk(ip, bp, bpref);
+ blkno = ffs_alloccgblk(ip, bp, bpref, rsize);
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
bdwrite(bp);
@@ -1475,21 +1482,14 @@ ffs_alloccg(ip, cg, bpref, size)
if (cgp->cg_cs.cs_nbfree == 0)
goto fail;
UFS_LOCK(ump);
- blkno = ffs_alloccgblk(ip, bp, bpref);
- bno = dtogd(fs, blkno);
- for (i = frags; i < fs->fs_frag; i++)
- setbit(blksfree, bno + i);
- i = fs->fs_frag - frags;
- cgp->cg_cs.cs_nffree += i;
- fs->fs_cstotal.cs_nffree += i;
- fs->fs_cs(fs, cg).cs_nffree += i;
- fs->fs_fmod = 1;
- cgp->cg_frsum[i]++;
+ blkno = ffs_alloccgblk(ip, bp, bpref, rsize);
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
bdwrite(bp);
return (blkno);
}
+ KASSERT(size == rsize,
+ ("ffs_alloccg: size(%d) != rsize(%d)", size, rsize));
bno = ffs_mapsearch(fs, cgp, bpref, allocsiz);
if (bno < 0)
goto fail;
@@ -1507,7 +1507,7 @@ ffs_alloccg(ip, cg, bpref, size)
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno);
+ softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno, frags, 0);
bdwrite(bp);
return (blkno);
@@ -1529,10 +1529,11 @@ fail:
* blocks may be fragmented by the routine that allocates them.
*/
static ufs2_daddr_t
-ffs_alloccgblk(ip, bp, bpref)
+ffs_alloccgblk(ip, bp, bpref, size)
struct inode *ip;
struct buf *bp;
ufs2_daddr_t bpref;
+ int size;
{
struct fs *fs;
struct cg *cgp;
@@ -1540,6 +1541,7 @@ ffs_alloccgblk(ip, bp, bpref)
ufs1_daddr_t bno;
ufs2_daddr_t blkno;
u_int8_t *blksfree;
+ int i;
fs = ip->i_fs;
ump = ip->i_ump;
@@ -1567,16 +1569,32 @@ ffs_alloccgblk(ip, bp, bpref)
gotit:
blkno = fragstoblks(fs, bno);
ffs_clrblock(fs, blksfree, (long)blkno);
- ffs_clusteracct(ump, fs, cgp, blkno, -1);
+ ffs_clusteracct(fs, cgp, blkno, -1);
cgp->cg_cs.cs_nbfree--;
fs->fs_cstotal.cs_nbfree--;
fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--;
fs->fs_fmod = 1;
blkno = cgbase(fs, cgp->cg_cgx) + bno;
+ /*
+ * If the caller didn't want the whole block free the frags here.
+ */
+ size = numfrags(fs, size);
+ if (size != fs->fs_frag) {
+ bno = dtogd(fs, blkno);
+ for (i = size; i < fs->fs_frag; i++)
+ setbit(blksfree, bno + i);
+ i = fs->fs_frag - size;
+ cgp->cg_cs.cs_nffree += i;
+ fs->fs_cstotal.cs_nffree += i;
+ fs->fs_cs(fs, cgp->cg_cgx).cs_nffree += i;
+ fs->fs_fmod = 1;
+ cgp->cg_frsum[i]++;
+ }
/* XXX Fixme. */
UFS_UNLOCK(ump);
if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno);
+ softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno,
+ size, 0);
UFS_LOCK(ump);
return (blkno);
}
@@ -1589,11 +1607,12 @@ gotit:
* take the first one that we find following bpref.
*/
static ufs2_daddr_t
-ffs_clusteralloc(ip, cg, bpref, len)
+ffs_clusteralloc(ip, cg, bpref, len, unused)
struct inode *ip;
u_int cg;
ufs2_daddr_t bpref;
int len;
+ int unused;
{
struct fs *fs;
struct cg *cgp;
@@ -1689,7 +1708,7 @@ ffs_clusteralloc(ip, cg, bpref, len)
len = blkstofrags(fs, len);
UFS_LOCK(ump);
for (i = 0; i < len; i += fs->fs_frag)
- if (ffs_alloccgblk(ip, bp, bno + i) != bno + i)
+ if (ffs_alloccgblk(ip, bp, bno + i, fs->fs_bsize) != bno + i)
panic("ffs_clusteralloc: lost block");
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
@@ -1713,11 +1732,12 @@ fail:
* inode in the specified cylinder group.
*/
static ufs2_daddr_t
-ffs_nodealloccg(ip, cg, ipref, mode)
+ffs_nodealloccg(ip, cg, ipref, mode, unused)
struct inode *ip;
u_int cg;
ufs2_daddr_t ipref;
int mode;
+ int unused;
{
struct fs *fs;
struct cg *cgp;
@@ -1820,28 +1840,6 @@ gotit:
}
/*
- * check if a block is free
- */
-static int
-ffs_isfreeblock(struct fs *fs, u_char *cp, ufs1_daddr_t h)
-{
-
- switch ((int)fs->fs_frag) {
- case 8:
- return (cp[h] == 0);
- case 4:
- return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
- case 2:
- return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
- case 1:
- return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
- default:
- panic("ffs_isfreeblock");
- }
- return (0);
-}
-
-/*
* Free a block or fragment.
*
* The specified block or fragment is placed back in the
@@ -1849,14 +1847,16 @@ ffs_isfreeblock(struct fs *fs, u_char *cp, ufs1_daddr_t h)
* block reassembly is checked.
*/
void
-ffs_blkfree(ump, fs, devvp, bno, size, inum)
+ffs_blkfree(ump, fs, devvp, bno, size, inum, dephd)
struct ufsmount *ump;
struct fs *fs;
struct vnode *devvp;
ufs2_daddr_t bno;
long size;
ino_t inum;
+ struct workhead *dephd;
{
+ struct mount *mp;
struct cg *cgp;
struct buf *bp;
ufs1_daddr_t fragno, cgbno;
@@ -1923,7 +1923,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
panic("ffs_blkfree: freeing free block");
}
ffs_setblock(fs, blksfree, fragno);
- ffs_clusteracct(ump, fs, cgp, fragno, 1);
+ ffs_clusteracct(fs, cgp, fragno, 1);
cgp->cg_cs.cs_nbfree++;
fs->fs_cstotal.cs_nbfree++;
fs->fs_cs(fs, cg).cs_nbfree++;
@@ -1963,7 +1963,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
cgp->cg_cs.cs_nffree -= fs->fs_frag;
fs->fs_cstotal.cs_nffree -= fs->fs_frag;
fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag;
- ffs_clusteracct(ump, fs, cgp, fragno, 1);
+ ffs_clusteracct(fs, cgp, fragno, 1);
cgp->cg_cs.cs_nbfree++;
fs->fs_cstotal.cs_nbfree++;
fs->fs_cs(fs, cg).cs_nbfree++;
@@ -1972,6 +1972,10 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
fs->fs_fmod = 1;
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
+ mp = UFSTOVFS(ump);
+ if (mp->mnt_flag & MNT_SOFTDEP && devvp->v_type != VREG)
+ softdep_setup_blkfree(UFSTOVFS(ump), bp, bno,
+ numfrags(fs, size), dephd);
bdwrite(bp);
}
@@ -2042,7 +2046,8 @@ ffs_vfree(pvp, ino, mode)
return (0);
}
ip = VTOI(pvp);
- return (ffs_freefile(ip->i_ump, ip->i_fs, ip->i_devvp, ino, mode));
+ return (ffs_freefile(ip->i_ump, ip->i_fs, ip->i_devvp, ino, mode,
+ NULL));
}
/*
@@ -2050,12 +2055,13 @@ ffs_vfree(pvp, ino, mode)
* The specified inode is placed back in the free map.
*/
int
-ffs_freefile(ump, fs, devvp, ino, mode)
+ffs_freefile(ump, fs, devvp, ino, mode, wkhd)
struct ufsmount *ump;
struct fs *fs;
struct vnode *devvp;
ino_t ino;
int mode;
+ struct workhead *wkhd;
{
struct cg *cgp;
struct buf *bp;
@@ -2112,6 +2118,9 @@ ffs_freefile(ump, fs, devvp, ino, mode)
fs->fs_fmod = 1;
ACTIVECLEAR(fs, cg);
UFS_UNLOCK(ump);
+ if (UFSTOVFS(ump)->mnt_flag & MNT_SOFTDEP && devvp->v_type != VREG)
+ softdep_setup_inofree(UFSTOVFS(ump), bp,
+ ino + cg * fs->fs_ipg, wkhd);
bdwrite(bp);
return (0);
}
@@ -2226,101 +2235,6 @@ ffs_mapsearch(fs, cgp, bpref, allocsiz)
}
/*
- * Update the cluster map because of an allocation or free.
- *
- * Cnt == 1 means free; cnt == -1 means allocating.
- */
-void
-ffs_clusteracct(ump, fs, cgp, blkno, cnt)
- struct ufsmount *ump;
- struct fs *fs;
- struct cg *cgp;
- ufs1_daddr_t blkno;
- int cnt;
-{
- int32_t *sump;
- int32_t *lp;
- u_char *freemapp, *mapp;
- int i, start, end, forw, back, map, bit;
-
- mtx_assert(UFS_MTX(ump), MA_OWNED);
-
- if (fs->fs_contigsumsize <= 0)
- return;
- freemapp = cg_clustersfree(cgp);
- sump = cg_clustersum(cgp);
- /*
- * Allocate or clear the actual block.
- */
- if (cnt > 0)
- setbit(freemapp, blkno);
- else
- clrbit(freemapp, blkno);
- /*
- * Find the size of the cluster going forward.
- */
- start = blkno + 1;
- end = start + fs->fs_contigsumsize;
- if (end >= cgp->cg_nclusterblks)
- end = cgp->cg_nclusterblks;
- mapp = &freemapp[start / NBBY];
- map = *mapp++;
- bit = 1 << (start % NBBY);
- for (i = start; i < end; i++) {
- if ((map & bit) == 0)
- break;
- if ((i & (NBBY - 1)) != (NBBY - 1)) {
- bit <<= 1;
- } else {
- map = *mapp++;
- bit = 1;
- }
- }
- forw = i - start;
- /*
- * Find the size of the cluster going backward.
- */
- start = blkno - 1;
- end = start - fs->fs_contigsumsize;
- if (end < 0)
- end = -1;
- mapp = &freemapp[start / NBBY];
- map = *mapp--;
- bit = 1 << (start % NBBY);
- for (i = start; i > end; i--) {
- if ((map & bit) == 0)
- break;
- if ((i & (NBBY - 1)) != 0) {
- bit >>= 1;
- } else {
- map = *mapp--;
- bit = 1 << (NBBY - 1);
- }
- }
- back = start - i;
- /*
- * Account for old cluster and the possibly new forward and
- * back clusters.
- */
- i = back + forw + 1;
- if (i > fs->fs_contigsumsize)
- i = fs->fs_contigsumsize;
- sump[i] += cnt;
- if (back > 0)
- sump[back] -= cnt;
- if (forw > 0)
- sump[forw] -= cnt;
- /*
- * Update cluster summary information.
- */
- lp = &sump[fs->fs_contigsumsize];
- for (i = fs->fs_contigsumsize; i > 0; i--)
- if (*lp-- > 0)
- break;
- fs->fs_maxcluster[cgp->cg_cgx] = i;
-}
-
-/*
* Fserr prints the name of a filesystem with an error diagnostic.
*
* The form of the error message is:
@@ -2540,7 +2454,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
#endif /* DEBUG */
while (cmd.size > 0) {
if ((error = ffs_freefile(ump, fs, ump->um_devvp,
- cmd.value, filetype)))
+ cmd.value, filetype, NULL)))
break;
cmd.size -= 1;
cmd.value += 1;
@@ -2568,7 +2482,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
if (blksize > blkcnt)
blksize = blkcnt;
ffs_blkfree(ump, fs, ump->um_devvp, blkno,
- blksize * fs->fs_fsize, ROOTINO);
+ blksize * fs->fs_fsize, ROOTINO, NULL);
blkno += blksize;
blkcnt -= blksize;
blksize = fs->fs_frag;
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index a12f96e..6d5f27c 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -120,6 +120,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
if (lbn < 0)
return (EFBIG);
+ if (DOINGSOFTDEP(vp))
+ softdep_prealloc(vp, MNT_WAIT);
/*
* If the next write will extend the file into a new block,
* and the file is currently composed of a fragment
@@ -418,6 +420,8 @@ fail:
* slow, running out of disk space is not expected to be a common
* occurence. The error return from fsync is ignored as we already
* have an error to return to the user.
+ *
+ * XXX Still have to journal the free below
*/
(void) ffs_syncvnode(vp, MNT_WAIT);
for (deallocated = 0, blkp = allociblk, lbns_remfree = lbns;
@@ -473,7 +477,7 @@ fail:
*/
for (blkp = allociblk; blkp < allocblk; blkp++) {
ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize,
- ip->i_number);
+ ip->i_number, NULL);
}
return (error);
}
@@ -515,6 +519,9 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
if (lbn < 0)
return (EFBIG);
+ if (DOINGSOFTDEP(vp))
+ softdep_prealloc(vp, MNT_WAIT);
+
/*
* Check for allocating external data.
*/
@@ -930,6 +937,8 @@ fail:
* slow, running out of disk space is not expected to be a common
* occurence. The error return from fsync is ignored as we already
* have an error to return to the user.
+ *
+ * XXX Still have to journal the free below
*/
(void) ffs_syncvnode(vp, MNT_WAIT);
for (deallocated = 0, blkp = allociblk, lbns_remfree = lbns;
@@ -985,7 +994,7 @@ fail:
*/
for (blkp = allociblk; blkp < allocblk; blkp++) {
ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize,
- ip->i_number);
+ ip->i_number, NULL);
}
return (error);
}
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 7e32ced..7011623 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -47,6 +47,7 @@ struct ucred;
struct vnode;
struct vop_fsync_args;
struct vop_reallocblks_args;
+struct workhead;
int ffs_alloc(struct inode *, ufs2_daddr_t, ufs2_daddr_t, int, int,
struct ucred *, ufs2_daddr_t *);
@@ -56,20 +57,23 @@ int ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size,
struct ucred *a_cred, int a_flags, struct buf **a_bpp);
int ffs_blkatoff(struct vnode *, off_t, char **, struct buf **);
void ffs_blkfree(struct ufsmount *, struct fs *, struct vnode *,
- ufs2_daddr_t, long, ino_t);
+ ufs2_daddr_t, long, ino_t, struct workhead *);
ufs2_daddr_t ffs_blkpref_ufs1(struct inode *, ufs_lbn_t, int, ufs1_daddr_t *);
ufs2_daddr_t ffs_blkpref_ufs2(struct inode *, ufs_lbn_t, int, ufs2_daddr_t *);
int ffs_checkfreefile(struct fs *, struct vnode *, ino_t);
void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
+void ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int);
void ffs_bdflush(struct bufobj *, struct buf *);
int ffs_copyonwrite(struct vnode *, struct buf *);
int ffs_flushfiles(struct mount *, int, struct thread *);
void ffs_fragacct(struct fs *, int, int32_t [], int);
int ffs_freefile(struct ufsmount *, struct fs *, struct vnode *, ino_t,
- int);
+ int, struct workhead *);
int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
+int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
int ffs_mountroot(void);
+void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
int ffs_reallocblks(struct vop_reallocblks_args *);
int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t,
ufs2_daddr_t, int, int, int, struct ucred *, struct buf **);
@@ -103,12 +107,14 @@ extern struct vop_vector ffs_fifoops2;
int softdep_check_suspend(struct mount *, struct vnode *,
int, int, int, int);
+int softdep_complete_trunc(struct vnode *, void *);
void softdep_get_depcounts(struct mount *, int *, int *);
void softdep_initialize(void);
void softdep_uninitialize(void);
int softdep_mount(struct vnode *, struct mount *, struct fs *,
struct ucred *);
-void softdep_move_dependencies(struct buf *, struct buf *);
+void softdep_unmount(struct mount *);
+int softdep_move_dependencies(struct buf *, struct buf *);
int softdep_flushworklist(struct mount *, int *, struct thread *);
int softdep_flushfiles(struct mount *, int, struct thread *);
void softdep_update_inodeblock(struct inode *, struct buf *, int);
@@ -117,7 +123,8 @@ void softdep_freefile(struct vnode *, ino_t, int);
int softdep_request_cleanup(struct fs *, struct vnode *);
void softdep_setup_freeblocks(struct inode *, off_t, int);
void softdep_setup_inomapdep(struct buf *, struct inode *, ino_t);
-void softdep_setup_blkmapdep(struct buf *, struct mount *, ufs2_daddr_t);
+void softdep_setup_blkmapdep(struct buf *, struct mount *, ufs2_daddr_t,
+ int, int);
void softdep_setup_allocdirect(struct inode *, ufs_lbn_t, ufs2_daddr_t,
ufs2_daddr_t, long, long, struct buf *);
void softdep_setup_allocext(struct inode *, ufs_lbn_t, ufs2_daddr_t,
@@ -126,11 +133,20 @@ void softdep_setup_allocindir_meta(struct buf *, struct inode *,
struct buf *, int, ufs2_daddr_t);
void softdep_setup_allocindir_page(struct inode *, ufs_lbn_t,
struct buf *, int, ufs2_daddr_t, ufs2_daddr_t, struct buf *);
+void softdep_setup_blkfree(struct mount *, struct buf *, ufs2_daddr_t, int,
+ struct workhead *);
+void softdep_setup_inofree(struct mount *, struct buf *, ino_t,
+ struct workhead *);
+void softdep_setup_sbupdate(struct ufsmount *, struct fs *, struct buf *);
+void *softdep_setup_trunc(struct vnode *vp, off_t length, int flags);
void softdep_fsync_mountdev(struct vnode *);
int softdep_sync_metadata(struct vnode *);
int softdep_process_worklist(struct mount *, int);
int softdep_fsync(struct vnode *);
int softdep_waitidle(struct mount *);
+int softdep_prealloc(struct vnode *, int);
+int softdep_journal_lookup(struct mount *, struct vnode **);
+
int ffs_rdonly(struct inode *);
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index b2f9067..3b69832 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -92,15 +92,6 @@ ffs_update(vp, waitfor)
fs = ip->i_fs;
if (fs->fs_ronly)
return (0);
- /*
- * Ensure that uid and gid are correct. This is a temporary
- * fix until fsck has been changed to do the update.
- */
- if (fs->fs_magic == FS_UFS1_MAGIC && /* XXX */
- fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */
- ip->i_din1->di_ouid = ip->i_uid; /* XXX */
- ip->i_din1->di_ogid = ip->i_gid; /* XXX */
- } /* XXX */
error = bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
(int)fs->fs_bsize, NOCRED, &bp);
if (error) {
@@ -160,6 +151,7 @@ ffs_truncate(vp, length, flags, cred, td)
ufs2_daddr_t bn, lbn, lastblock, lastiblock[NIADDR], indir_lbn[NIADDR];
ufs2_daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR];
ufs2_daddr_t count, blocksreleased = 0, datablocks;
+ void *cookie;
struct bufobj *bo;
struct fs *fs;
struct buf *bp;
@@ -173,11 +165,14 @@ ffs_truncate(vp, length, flags, cred, td)
fs = ip->i_fs;
ump = ip->i_ump;
bo = &vp->v_bufobj;
+ cookie = NULL;
ASSERT_VOP_LOCKED(vp, "ffs_truncate");
if (length < 0)
return (EINVAL);
+ if (length > fs->fs_maxfilesize)
+ return (EFBIG);
/*
* Historically clients did not have to specify which data
* they were truncating. So, if not specified, we assume
@@ -192,6 +187,7 @@ ffs_truncate(vp, length, flags, cred, td)
* (e.g., the file is being unlinked), then pick it off with
* soft updates below.
*/
+ allerror = 0;
needextclean = 0;
softdepslowdown = DOINGSOFTDEP(vp) && softdep_slowdown(vp);
extblocks = 0;
@@ -212,6 +208,8 @@ ffs_truncate(vp, length, flags, cred, td)
panic("ffs_truncate: partial trunc of extdata");
if ((error = ffs_syncvnode(vp, MNT_WAIT)) != 0)
return (error);
+ if (DOINGSUJ(vp))
+ cookie = softdep_setup_trunc(vp, length, flags);
osize = ip->i_din2->di_extsize;
ip->i_din2->di_blocks -= extblocks;
#ifdef QUOTA
@@ -227,19 +225,19 @@ ffs_truncate(vp, length, flags, cred, td)
}
ip->i_flag |= IN_CHANGE;
if ((error = ffs_update(vp, 1)))
- return (error);
+ goto out;
for (i = 0; i < NXADDR; i++) {
if (oldblks[i] == 0)
continue;
ffs_blkfree(ump, fs, ip->i_devvp, oldblks[i],
- sblksize(fs, osize, i), ip->i_number);
+ sblksize(fs, osize, i), ip->i_number, NULL);
}
}
}
- if ((flags & IO_NORMAL) == 0)
- return (0);
- if (length > fs->fs_maxfilesize)
- return (EFBIG);
+ if ((flags & IO_NORMAL) == 0) {
+ error = 0;
+ goto out;
+ }
if (vp->v_type == VLNK &&
(ip->i_size < vp->v_mount->mnt_maxsymlinklen ||
datablocks == 0)) {
@@ -253,24 +251,52 @@ ffs_truncate(vp, length, flags, cred, td)
ip->i_flag |= IN_CHANGE | IN_UPDATE;
if (needextclean)
softdep_setup_freeblocks(ip, length, IO_EXT);
- return (ffs_update(vp, 1));
+ error = ffs_update(vp, 1);
+ goto out;
}
if (ip->i_size == length) {
ip->i_flag |= IN_CHANGE | IN_UPDATE;
if (needextclean)
softdep_setup_freeblocks(ip, length, IO_EXT);
- return (ffs_update(vp, 0));
+ error = ffs_update(vp, 0);
+ goto out;
}
if (fs->fs_ronly)
panic("ffs_truncate: read-only filesystem");
#ifdef QUOTA
error = getinoquota(ip);
if (error)
- return (error);
+ goto out;
#endif
if ((ip->i_flags & SF_SNAPSHOT) != 0)
ffs_snapremove(vp);
vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0;
+ osize = ip->i_size;
+ /*
+ * Lengthen the size of the file. We must ensure that the
+ * last byte of the file is allocated. Since the smallest
+ * value of osize is 0, length will be at least 1.
+ */
+ if (osize < length) {
+ vnode_pager_setsize(vp, length);
+ flags |= BA_CLRBUF;
+ error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp);
+ if (error) {
+ vnode_pager_setsize(vp, osize);
+ goto out;
+ }
+ ip->i_size = length;
+ DIP_SET(ip, i_size, length);
+ if (bp->b_bufsize == fs->fs_bsize)
+ bp->b_flags |= B_CLUSTEROK;
+ if (flags & IO_SYNC)
+ bwrite(bp);
+ else
+ bawrite(bp);
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ error = ffs_update(vp, 1);
+ goto out;
+ }
if (DOINGSOFTDEP(vp)) {
if (length > 0 || softdepslowdown) {
/*
@@ -283,11 +309,18 @@ ffs_truncate(vp, length, flags, cred, td)
* so that it will have no data structures left.
*/
if ((error = ffs_syncvnode(vp, MNT_WAIT)) != 0)
- return (error);
+ goto out;
UFS_LOCK(ump);
if (ip->i_flag & IN_SPACECOUNTED)
fs->fs_pendingblocks -= datablocks;
UFS_UNLOCK(ump);
+ /*
+ * We have to journal the truncation before we change
+ * any blocks so we don't leave the file partially
+ * truncated.
+ */
+ if (DOINGSUJ(vp) && cookie == NULL)
+ cookie = softdep_setup_trunc(vp, length, flags);
} else {
#ifdef QUOTA
(void) chkdq(ip, -datablocks, NOCRED, 0);
@@ -301,33 +334,9 @@ ffs_truncate(vp, length, flags, cred, td)
OFF_TO_IDX(lblktosize(fs, -extblocks)));
vnode_pager_setsize(vp, 0);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (ffs_update(vp, 0));
- }
- }
- osize = ip->i_size;
- /*
- * Lengthen the size of the file. We must ensure that the
- * last byte of the file is allocated. Since the smallest
- * value of osize is 0, length will be at least 1.
- */
- if (osize < length) {
- vnode_pager_setsize(vp, length);
- flags |= BA_CLRBUF;
- error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp);
- if (error) {
- vnode_pager_setsize(vp, osize);
- return (error);
+ error = ffs_update(vp, 0);
+ goto out;
}
- ip->i_size = length;
- DIP_SET(ip, i_size, length);
- if (bp->b_bufsize == fs->fs_bsize)
- bp->b_flags |= B_CLUSTEROK;
- if (flags & IO_SYNC)
- bwrite(bp);
- else
- bawrite(bp);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (ffs_update(vp, 1));
}
/*
* Shorten the size of the file. If the file is not being
@@ -345,9 +354,8 @@ ffs_truncate(vp, length, flags, cred, td)
lbn = lblkno(fs, length);
flags |= BA_CLRBUF;
error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp);
- if (error) {
- return (error);
- }
+ if (error)
+ goto out;
/*
* When we are doing soft updates and the UFS_BALLOC
* above fills in a direct block hole with a full sized
@@ -359,7 +367,7 @@ ffs_truncate(vp, length, flags, cred, td)
if (DOINGSOFTDEP(vp) && lbn < NDADDR &&
fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize &&
(error = ffs_syncvnode(vp, MNT_WAIT)) != 0)
- return (error);
+ goto out;
ip->i_size = length;
DIP_SET(ip, i_size, length);
size = blksize(fs, ip, lbn);
@@ -405,7 +413,13 @@ ffs_truncate(vp, length, flags, cred, td)
DIP_SET(ip, i_db[i], 0);
}
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- allerror = ffs_update(vp, 1);
+ /*
+ * When doing softupdate journaling we must preserve the size along
+ * with the old pointers until they are freed or we might not
+ * know how many fragments remain.
+ */
+ if (!DOINGSUJ(vp))
+ allerror = ffs_update(vp, 1);
/*
* Having written the new inode to disk, save its new configuration
@@ -445,7 +459,7 @@ ffs_truncate(vp, length, flags, cred, td)
if (lastiblock[level] < 0) {
DIP_SET(ip, i_ib[level], 0);
ffs_blkfree(ump, fs, ip->i_devvp, bn,
- fs->fs_bsize, ip->i_number);
+ fs->fs_bsize, ip->i_number, NULL);
blocksreleased += nblocks;
}
}
@@ -464,7 +478,8 @@ ffs_truncate(vp, length, flags, cred, td)
continue;
DIP_SET(ip, i_db[i], 0);
bsize = blksize(fs, ip, i);
- ffs_blkfree(ump, fs, ip->i_devvp, bn, bsize, ip->i_number);
+ ffs_blkfree(ump, fs, ip->i_devvp, bn, bsize, ip->i_number,
+ NULL);
blocksreleased += btodb(bsize);
}
if (lastblock < 0)
@@ -496,7 +511,7 @@ ffs_truncate(vp, length, flags, cred, td)
*/
bn += numfrags(fs, newspace);
ffs_blkfree(ump, fs, ip->i_devvp, bn,
- oldspace - newspace, ip->i_number);
+ oldspace - newspace, ip->i_number, NULL);
blocksreleased += btodb(oldspace - newspace);
}
}
@@ -528,7 +543,14 @@ done:
#ifdef QUOTA
(void) chkdq(ip, -blocksreleased, NOCRED, 0);
#endif
- return (allerror);
+ error = allerror;
+out:
+ if (cookie) {
+ allerror = softdep_complete_trunc(vp, cookie);
+ if (allerror != 0 && error == 0)
+ error = allerror;
+ }
+ return (error);
}
/*
@@ -638,7 +660,7 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp)
blocksreleased += blkcount;
}
ffs_blkfree(ip->i_ump, fs, ip->i_devvp, nb, fs->fs_bsize,
- ip->i_number);
+ ip->i_number, NULL);
blocksreleased += nblocks;
}
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index b36cb58..11362cf 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -142,7 +142,7 @@ MTX_SYSINIT(ffs_snapfree, &snapfree_lock, "snapdata free list", MTX_DEF);
static int cgaccount(int, struct vnode *, struct buf *, int);
static int expunge_ufs1(struct vnode *, struct inode *, struct fs *,
int (*)(struct vnode *, ufs1_daddr_t *, ufs1_daddr_t *, struct fs *,
- ufs_lbn_t, int), int);
+ ufs_lbn_t, int), int, int);
static int indiracct_ufs1(struct vnode *, struct vnode *, int,
ufs1_daddr_t, ufs_lbn_t, ufs_lbn_t, ufs_lbn_t, ufs_lbn_t, struct fs *,
int (*)(struct vnode *, ufs1_daddr_t *, ufs1_daddr_t *, struct fs *,
@@ -155,7 +155,7 @@ static int mapacct_ufs1(struct vnode *, ufs1_daddr_t *, ufs1_daddr_t *,
struct fs *, ufs_lbn_t, int);
static int expunge_ufs2(struct vnode *, struct inode *, struct fs *,
int (*)(struct vnode *, ufs2_daddr_t *, ufs2_daddr_t *, struct fs *,
- ufs_lbn_t, int), int);
+ ufs_lbn_t, int), int, int);
static int indiracct_ufs2(struct vnode *, struct vnode *, int,
ufs2_daddr_t, ufs_lbn_t, ufs_lbn_t, ufs_lbn_t, ufs_lbn_t, struct fs *,
int (*)(struct vnode *, ufs2_daddr_t *, ufs2_daddr_t *, struct fs *,
@@ -582,7 +582,8 @@ loop:
len = fragroundup(fs, blkoff(fs, xp->i_size));
if (len != 0 && len < fs->fs_bsize) {
ffs_blkfree(ump, copy_fs, vp,
- DIP(xp, i_db[loc]), len, xp->i_number);
+ DIP(xp, i_db[loc]), len, xp->i_number,
+ NULL);
blkno = DIP(xp, i_db[loc]);
DIP_SET(xp, i_db[loc], 0);
}
@@ -590,15 +591,15 @@ loop:
snaplistsize += 1;
if (xp->i_ump->um_fstype == UFS1)
error = expunge_ufs1(vp, xp, copy_fs, fullacct_ufs1,
- BLK_NOCOPY);
+ BLK_NOCOPY, 1);
else
error = expunge_ufs2(vp, xp, copy_fs, fullacct_ufs2,
- BLK_NOCOPY);
+ BLK_NOCOPY, 1);
if (blkno)
DIP_SET(xp, i_db[loc], blkno);
if (!error)
error = ffs_freefile(ump, copy_fs, vp, xp->i_number,
- xp->i_mode);
+ xp->i_mode, NULL);
VOP_UNLOCK(xvp, 0);
vdrop(xvp);
if (error) {
@@ -612,6 +613,26 @@ loop:
}
MNT_IUNLOCK(mp);
/*
+ * Erase the journal file from the snapshot.
+ */
+ if (fs->fs_flags & FS_SUJ) {
+ error = softdep_journal_lookup(mp, &xvp);
+ if (error) {
+ free(copy_fs->fs_csp, M_UFSMNT);
+ bawrite(sbp);
+ sbp = NULL;
+ goto out1;
+ }
+ xp = VTOI(xvp);
+ if (xp->i_ump->um_fstype == UFS1)
+ error = expunge_ufs1(vp, xp, copy_fs, fullacct_ufs1,
+ BLK_NOCOPY, 0);
+ else
+ error = expunge_ufs2(vp, xp, copy_fs, fullacct_ufs2,
+ BLK_NOCOPY, 0);
+ vput(xvp);
+ }
+ /*
* Acquire a lock on the snapdata structure, creating it if necessary.
*/
sn = ffs_snapdata_acquire(devvp);
@@ -691,16 +712,16 @@ out1:
break;
if (xp->i_ump->um_fstype == UFS1)
error = expunge_ufs1(vp, xp, fs, snapacct_ufs1,
- BLK_SNAP);
+ BLK_SNAP, 0);
else
error = expunge_ufs2(vp, xp, fs, snapacct_ufs2,
- BLK_SNAP);
+ BLK_SNAP, 0);
if (error == 0 && xp->i_effnlink == 0) {
error = ffs_freefile(ump,
copy_fs,
vp,
xp->i_number,
- xp->i_mode);
+ xp->i_mode, NULL);
}
if (error) {
fs->fs_snapinum[snaploc] = 0;
@@ -719,9 +740,11 @@ out1:
* the list of allocated blocks in i_snapblklist.
*/
if (ip->i_ump->um_fstype == UFS1)
- error = expunge_ufs1(vp, ip, copy_fs, mapacct_ufs1, BLK_SNAP);
+ error = expunge_ufs1(vp, ip, copy_fs, mapacct_ufs1,
+ BLK_SNAP, 0);
else
- error = expunge_ufs2(vp, ip, copy_fs, mapacct_ufs2, BLK_SNAP);
+ error = expunge_ufs2(vp, ip, copy_fs, mapacct_ufs2,
+ BLK_SNAP, 0);
if (error) {
fs->fs_snapinum[snaploc] = 0;
free(snapblklist, M_UFSMNT);
@@ -954,13 +977,14 @@ cgaccount(cg, vp, nbp, passno)
* is reproduced once each for UFS1 and UFS2.
*/
static int
-expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype)
+expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode)
struct vnode *snapvp;
struct inode *cancelip;
struct fs *fs;
int (*acctfunc)(struct vnode *, ufs1_daddr_t *, ufs1_daddr_t *,
struct fs *, ufs_lbn_t, int);
int expungetype;
+ int clearmode;
{
int i, error, indiroff;
ufs_lbn_t lbn, rlbn;
@@ -1005,7 +1029,7 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype)
*/
dip = (struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, cancelip->i_number);
- if (expungetype == BLK_NOCOPY || cancelip->i_effnlink == 0)
+ if (clearmode || cancelip->i_effnlink == 0)
dip->di_mode = 0;
dip->di_size = 0;
dip->di_blocks = 0;
@@ -1220,7 +1244,7 @@ mapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype)
*ip->i_snapblklist++ = lblkno;
if (blkno == BLK_SNAP)
blkno = blkstofrags(fs, lblkno);
- ffs_blkfree(ip->i_ump, fs, vp, blkno, fs->fs_bsize, inum);
+ ffs_blkfree(ip->i_ump, fs, vp, blkno, fs->fs_bsize, inum, NULL);
}
return (0);
}
@@ -1234,13 +1258,14 @@ mapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype)
* is reproduced once each for UFS1 and UFS2.
*/
static int
-expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype)
+expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode)
struct vnode *snapvp;
struct inode *cancelip;
struct fs *fs;
int (*acctfunc)(struct vnode *, ufs2_daddr_t *, ufs2_daddr_t *,
struct fs *, ufs_lbn_t, int);
int expungetype;
+ int clearmode;
{
int i, error, indiroff;
ufs_lbn_t lbn, rlbn;
@@ -1285,7 +1310,7 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype)
*/
dip = (struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, cancelip->i_number);
- if (expungetype == BLK_NOCOPY)
+ if (clearmode || cancelip->i_effnlink == 0)
dip->di_mode = 0;
dip->di_size = 0;
dip->di_blocks = 0;
@@ -1500,7 +1525,7 @@ mapacct_ufs2(vp, oldblkp, lastblkp, fs, lblkno, expungetype)
*ip->i_snapblklist++ = lblkno;
if (blkno == BLK_SNAP)
blkno = blkstofrags(fs, lblkno);
- ffs_blkfree(ip->i_ump, fs, vp, blkno, fs->fs_bsize, inum);
+ ffs_blkfree(ip->i_ump, fs, vp, blkno, fs->fs_bsize, inum, NULL);
}
return (0);
}
@@ -1657,6 +1682,13 @@ ffs_snapremove(vp)
ip->i_flags &= ~SF_SNAPSHOT;
DIP_SET(ip, i_flags, ip->i_flags);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ /*
+ * The dirtied indirects must be written out before
+ * softdep_setup_freeblocks() is called. Otherwise indir_trunc()
+ * may find indirect pointers using the magic BLK_* values.
+ */
+ if (DOINGSOFTDEP(vp))
+ ffs_syncvnode(vp, MNT_WAIT);
#ifdef QUOTA
/*
* Reenable disk quotas for ex-snapshot file.
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 4d652c1..4a659f9 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1,5 +1,7 @@
/*-
- * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
+ * Copyright 1998, 2000 Marshall Kirk McKusick.
+ * Copyright 2009, 2010 Jeffrey W. Roberson <jeff@FreeBSD.org>
+ * All rights reserved.
*
* The soft updates code is derived from the appendix of a University
* of Michigan technical report (Gregory R. Ganger and Yale N. Patt,
@@ -23,17 +25,16 @@
* 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 MARSHALL KIRK MCKUSICK ``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 MARSHALL KIRK MCKUSICK 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 AUTHORS ``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 AUTHORS 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.
*
* from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00
*/
@@ -50,6 +51,7 @@ __FBSDID("$FreeBSD$");
#ifndef DEBUG
#define DEBUG
#endif
+#define SUJ_DEBUG
#include <sys/param.h>
#include <sys/kernel.h>
@@ -62,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
+#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
@@ -130,10 +133,12 @@ softdep_setup_inomapdep(bp, ip, newinum)
}
void
-softdep_setup_blkmapdep(bp, mp, newblkno)
+softdep_setup_blkmapdep(bp, mp, newblkno, frags, oldfrags)
struct buf *bp;
struct mount *mp;
ufs2_daddr_t newblkno;
+ int frags;
+ int oldfrags;
{
panic("softdep_setup_blkmapdep called");
@@ -227,7 +232,8 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk)
}
void
-softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize)
+softdep_change_directoryentry_offset(bp, dp, base, oldloc, newloc, entrysize)
+ struct buf *bp;
struct inode *dp;
caddr_t base;
caddr_t oldloc;
@@ -403,31 +409,13 @@ softdep_get_depcounts(struct mount *mp,
* These definitions need to be adapted to the system to which
* this file is being ported.
*/
-/*
- * malloc types defined for the softdep system.
- */
-static MALLOC_DEFINE(M_PAGEDEP, "pagedep","File page dependencies");
-static MALLOC_DEFINE(M_INODEDEP, "inodedep","Inode dependencies");
-static MALLOC_DEFINE(M_NEWBLK, "newblk","New block allocation");
-static MALLOC_DEFINE(M_BMSAFEMAP, "bmsafemap","Block or frag allocated from cyl group map");
-static MALLOC_DEFINE(M_ALLOCDIRECT, "allocdirect","Block or frag dependency for an inode");
-static MALLOC_DEFINE(M_INDIRDEP, "indirdep","Indirect block dependencies");
-static MALLOC_DEFINE(M_ALLOCINDIR, "allocindir","Block dependency for an indirect block");
-static MALLOC_DEFINE(M_FREEFRAG, "freefrag","Previously used frag for an inode");
-static MALLOC_DEFINE(M_FREEBLKS, "freeblks","Blocks freed from an inode");
-static MALLOC_DEFINE(M_FREEFILE, "freefile","Inode deallocated");
-static MALLOC_DEFINE(M_DIRADD, "diradd","New directory entry");
-static MALLOC_DEFINE(M_MKDIR, "mkdir","New directory");
-static MALLOC_DEFINE(M_DIRREM, "dirrem","Directory entry deleted");
-static MALLOC_DEFINE(M_NEWDIRBLK, "newdirblk","Unclaimed new directory block");
-static MALLOC_DEFINE(M_SAVEDINO, "savedino","Saved inodes");
#define M_SOFTDEP_FLAGS (M_WAITOK | M_USE_RESERVE)
#define D_PAGEDEP 0
#define D_INODEDEP 1
-#define D_NEWBLK 2
-#define D_BMSAFEMAP 3
+#define D_BMSAFEMAP 2
+#define D_NEWBLK 3
#define D_ALLOCDIRECT 4
#define D_INDIRDEP 5
#define D_ALLOCINDIR 6
@@ -438,7 +426,67 @@ static MALLOC_DEFINE(M_SAVEDINO, "savedino","Saved inodes");
#define D_MKDIR 11
#define D_DIRREM 12
#define D_NEWDIRBLK 13
-#define D_LAST D_NEWDIRBLK
+#define D_FREEWORK 14
+#define D_FREEDEP 15
+#define D_JADDREF 16
+#define D_JREMREF 17
+#define D_JMVREF 18
+#define D_JNEWBLK 19
+#define D_JFREEBLK 20
+#define D_JFREEFRAG 21
+#define D_JSEG 22
+#define D_JSEGDEP 23
+#define D_SBDEP 24
+#define D_JTRUNC 25
+#define D_LAST D_JTRUNC
+
+unsigned long dep_current[D_LAST + 1];
+unsigned long dep_total[D_LAST + 1];
+
+
+SYSCTL_NODE(_debug, OID_AUTO, softdep, CTLFLAG_RW, 0, "soft updates stats");
+SYSCTL_NODE(_debug_softdep, OID_AUTO, total, CTLFLAG_RW, 0,
+ "total dependencies allocated");
+SYSCTL_NODE(_debug_softdep, OID_AUTO, current, CTLFLAG_RW, 0,
+ "current dependencies allocated");
+
+#define SOFTDEP_TYPE(type, str, long) \
+ static MALLOC_DEFINE(M_ ## type, #str, long); \
+ SYSCTL_LONG(_debug_softdep_total, OID_AUTO, str, CTLFLAG_RD, \
+ &dep_total[D_ ## type], 0, ""); \
+ SYSCTL_LONG(_debug_softdep_current, OID_AUTO, str, CTLFLAG_RD, \
+ &dep_current[D_ ## type], 0, "");
+
+SOFTDEP_TYPE(PAGEDEP, pagedep, "File page dependencies");
+SOFTDEP_TYPE(INODEDEP, inodedep, "Inode dependencies");
+SOFTDEP_TYPE(BMSAFEMAP, bmsafemap,
+ "Block or frag allocated from cyl group map");
+SOFTDEP_TYPE(NEWBLK, newblk, "New block or frag allocation dependency");
+SOFTDEP_TYPE(ALLOCDIRECT, allocdirect, "Block or frag dependency for an inode");
+SOFTDEP_TYPE(INDIRDEP, indirdep, "Indirect block dependencies");
+SOFTDEP_TYPE(ALLOCINDIR, allocindir, "Block dependency for an indirect block");
+SOFTDEP_TYPE(FREEFRAG, freefrag, "Previously used frag for an inode");
+SOFTDEP_TYPE(FREEBLKS, freeblks, "Blocks freed from an inode");
+SOFTDEP_TYPE(FREEFILE, freefile, "Inode deallocated");
+SOFTDEP_TYPE(DIRADD, diradd, "New directory entry");
+SOFTDEP_TYPE(MKDIR, mkdir, "New directory");
+SOFTDEP_TYPE(DIRREM, dirrem, "Directory entry deleted");
+SOFTDEP_TYPE(NEWDIRBLK, newdirblk, "Unclaimed new directory block");
+SOFTDEP_TYPE(FREEWORK, freework, "free an inode block");
+SOFTDEP_TYPE(FREEDEP, freedep, "track a block free");
+SOFTDEP_TYPE(JADDREF, jaddref, "Journal inode ref add");
+SOFTDEP_TYPE(JREMREF, jremref, "Journal inode ref remove");
+SOFTDEP_TYPE(JMVREF, jmvref, "Journal inode ref move");
+SOFTDEP_TYPE(JNEWBLK, jnewblk, "Journal new block");
+SOFTDEP_TYPE(JFREEBLK, jfreeblk, "Journal free block");
+SOFTDEP_TYPE(JFREEFRAG, jfreefrag, "Journal free frag");
+SOFTDEP_TYPE(JSEG, jseg, "Journal segment");
+SOFTDEP_TYPE(JSEGDEP, jsegdep, "Journal segment complete");
+SOFTDEP_TYPE(SBDEP, sbdep, "Superblock write dependency");
+SOFTDEP_TYPE(JTRUNC, jtrunc, "Journal inode truncation");
+
+static MALLOC_DEFINE(M_SAVEDINO, "savedino", "Saved inodes");
+static MALLOC_DEFINE(M_JBLOCKS, "jblocks", "Journal block locations");
/*
* translate from workitem type to memory type
@@ -447,8 +495,8 @@ static MALLOC_DEFINE(M_SAVEDINO, "savedino","Saved inodes");
static struct malloc_type *memtype[] = {
M_PAGEDEP,
M_INODEDEP,
- M_NEWBLK,
M_BMSAFEMAP,
+ M_NEWBLK,
M_ALLOCDIRECT,
M_INDIRDEP,
M_ALLOCINDIR,
@@ -458,7 +506,19 @@ static struct malloc_type *memtype[] = {
M_DIRADD,
M_MKDIR,
M_DIRREM,
- M_NEWDIRBLK
+ M_NEWDIRBLK,
+ M_FREEWORK,
+ M_FREEDEP,
+ M_JADDREF,
+ M_JREMREF,
+ M_JMVREF,
+ M_JNEWBLK,
+ M_JFREEBLK,
+ M_JFREEFRAG,
+ M_JSEG,
+ M_JSEGDEP,
+ M_SBDEP,
+ M_JTRUNC
};
#define DtoM(type) (memtype[type])
@@ -467,17 +527,21 @@ static struct malloc_type *memtype[] = {
* Names of malloc types.
*/
#define TYPENAME(type) \
- ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???")
+ ((unsigned)(type) <= D_LAST ? memtype[type]->ks_shortdesc : "???")
/*
* End system adaptation definitions.
*/
+#define DOTDOT_OFFSET offsetof(struct dirtemplate, dotdot_ino)
+#define DOT_OFFSET offsetof(struct dirtemplate, dot_ino)
+
/*
* Forward declarations.
*/
struct inodedep_hashhead;
struct newblk_hashhead;
struct pagedep_hashhead;
+struct bmsafemap_hashhead;
/*
* Internal function prototypes.
@@ -487,59 +551,172 @@ static void drain_output(struct vnode *);
static struct buf *getdirtybuf(struct buf *, struct mtx *, int);
static void clear_remove(struct thread *);
static void clear_inodedeps(struct thread *);
+static void unlinked_inodedep(struct mount *, struct inodedep *);
+static void clear_unlinked_inodedep(struct inodedep *);
+static struct inodedep *first_unlinked_inodedep(struct ufsmount *);
static int flush_pagedep_deps(struct vnode *, struct mount *,
struct diraddhd *);
+static void free_pagedep(struct pagedep *);
+static int flush_newblk_dep(struct vnode *, struct mount *, ufs_lbn_t);
static int flush_inodedep_deps(struct mount *, ino_t);
static int flush_deplist(struct allocdirectlst *, int, int *);
static int handle_written_filepage(struct pagedep *, struct buf *);
+static int handle_written_sbdep(struct sbdep *, struct buf *);
+static void initiate_write_sbdep(struct sbdep *);
static void diradd_inode_written(struct diradd *, struct inodedep *);
+static int handle_written_indirdep(struct indirdep *, struct buf *,
+ struct buf**);
static int handle_written_inodeblock(struct inodedep *, struct buf *);
-static void handle_allocdirect_partdone(struct allocdirect *);
+static int handle_written_bmsafemap(struct bmsafemap *, struct buf *);
+static void handle_written_jaddref(struct jaddref *);
+static void handle_written_jremref(struct jremref *);
+static void handle_written_jseg(struct jseg *, struct buf *);
+static void handle_written_jnewblk(struct jnewblk *);
+static void handle_written_jfreeblk(struct jfreeblk *);
+static void handle_written_jfreefrag(struct jfreefrag *);
+static void complete_jseg(struct jseg *);
+static void jseg_write(struct fs *, struct jblocks *, struct jseg *,
+ uint8_t *);
+static void jaddref_write(struct jaddref *, struct jseg *, uint8_t *);
+static void jremref_write(struct jremref *, struct jseg *, uint8_t *);
+static void jmvref_write(struct jmvref *, struct jseg *, uint8_t *);
+static void jtrunc_write(struct jtrunc *, struct jseg *, uint8_t *);
+static void jnewblk_write(struct jnewblk *, struct jseg *, uint8_t *);
+static void jfreeblk_write(struct jfreeblk *, struct jseg *, uint8_t *);
+static void jfreefrag_write(struct jfreefrag *, struct jseg *, uint8_t *);
+static inline void inoref_write(struct inoref *, struct jseg *,
+ struct jrefrec *);
+static void handle_allocdirect_partdone(struct allocdirect *,
+ struct workhead *);
+static void cancel_newblk(struct newblk *, struct workhead *);
+static void indirdep_complete(struct indirdep *);
static void handle_allocindir_partdone(struct allocindir *);
static void initiate_write_filepage(struct pagedep *, struct buf *);
+static void initiate_write_indirdep(struct indirdep*, struct buf *);
static void handle_written_mkdir(struct mkdir *, int);
+static void initiate_write_bmsafemap(struct bmsafemap *, struct buf *);
static void initiate_write_inodeblock_ufs1(struct inodedep *, struct buf *);
static void initiate_write_inodeblock_ufs2(struct inodedep *, struct buf *);
static void handle_workitem_freefile(struct freefile *);
static void handle_workitem_remove(struct dirrem *, struct vnode *);
static struct dirrem *newdirrem(struct buf *, struct inode *,
struct inode *, int, struct dirrem **);
-static void free_diradd(struct diradd *);
-static void free_allocindir(struct allocindir *, struct inodedep *);
+static void cancel_indirdep(struct indirdep *, struct buf *, struct inodedep *,
+ struct freeblks *);
+static void free_indirdep(struct indirdep *);
+static void free_diradd(struct diradd *, struct workhead *);
+static void merge_diradd(struct inodedep *, struct diradd *);
+static void complete_diradd(struct diradd *);
+static struct diradd *diradd_lookup(struct pagedep *, int);
+static struct jremref *cancel_diradd_dotdot(struct inode *, struct dirrem *,
+ struct jremref *);
+static struct jremref *cancel_mkdir_dotdot(struct inode *, struct dirrem *,
+ struct jremref *);
+static void cancel_diradd(struct diradd *, struct dirrem *, struct jremref *,
+ struct jremref *, struct jremref *);
+static void dirrem_journal(struct dirrem *, struct jremref *, struct jremref *,
+ struct jremref *);
+static void cancel_allocindir(struct allocindir *, struct inodedep *,
+ struct freeblks *);
+static void complete_mkdir(struct mkdir *);
static void free_newdirblk(struct newdirblk *);
-static int indir_trunc(struct freeblks *, ufs2_daddr_t, int, ufs_lbn_t,
- ufs2_daddr_t *);
-static void deallocate_dependencies(struct buf *, struct inodedep *);
-static void free_allocdirect(struct allocdirectlst *,
- struct allocdirect *, int);
+static void free_jremref(struct jremref *);
+static void free_jaddref(struct jaddref *);
+static void free_jsegdep(struct jsegdep *);
+static void free_jseg(struct jseg *);
+static void free_jnewblk(struct jnewblk *);
+static void free_jfreeblk(struct jfreeblk *);
+static void free_jfreefrag(struct jfreefrag *);
+static void free_freedep(struct freedep *);
+static void journal_jremref(struct dirrem *, struct jremref *,
+ struct inodedep *);
+static void cancel_jnewblk(struct jnewblk *, struct workhead *);
+static int cancel_jaddref(struct jaddref *, struct inodedep *,
+ struct workhead *);
+static void cancel_jfreefrag(struct jfreefrag *);
+static void indir_trunc(struct freework *, ufs2_daddr_t, ufs_lbn_t);
+static int deallocate_dependencies(struct buf *, struct inodedep *,
+ struct freeblks *);
+static void free_newblk(struct newblk *);
+static void cancel_allocdirect(struct allocdirectlst *,
+ struct allocdirect *, struct freeblks *, int);
static int check_inode_unwritten(struct inodedep *);
static int free_inodedep(struct inodedep *);
+static void freework_freeblock(struct freework *);
static void handle_workitem_freeblocks(struct freeblks *, int);
+static void handle_complete_freeblocks(struct freeblks *);
+static void handle_workitem_indirblk(struct freework *);
+static void handle_written_freework(struct freework *);
static void merge_inode_lists(struct allocdirectlst *,struct allocdirectlst *);
static void setup_allocindir_phase2(struct buf *, struct inode *,
- struct allocindir *);
+ struct inodedep *, struct allocindir *, ufs_lbn_t);
static struct allocindir *newallocindir(struct inode *, int, ufs2_daddr_t,
- ufs2_daddr_t);
+ ufs2_daddr_t, ufs_lbn_t);
static void handle_workitem_freefrag(struct freefrag *);
-static struct freefrag *newfreefrag(struct inode *, ufs2_daddr_t, long);
+static struct freefrag *newfreefrag(struct inode *, ufs2_daddr_t, long,
+ ufs_lbn_t);
static void allocdirect_merge(struct allocdirectlst *,
struct allocdirect *, struct allocdirect *);
-static struct bmsafemap *bmsafemap_lookup(struct mount *, struct buf *);
-static int newblk_find(struct newblk_hashhead *, struct fs *, ufs2_daddr_t,
- struct newblk **);
-static int newblk_lookup(struct fs *, ufs2_daddr_t, int, struct newblk **);
+static struct freefrag *allocindir_merge(struct allocindir *,
+ struct allocindir *);
+static int bmsafemap_find(struct bmsafemap_hashhead *, struct mount *, int,
+ struct bmsafemap **);
+static struct bmsafemap *bmsafemap_lookup(struct mount *, struct buf *,
+ int cg);
+static int newblk_find(struct newblk_hashhead *, struct mount *, ufs2_daddr_t,
+ int, struct newblk **);
+static int newblk_lookup(struct mount *, ufs2_daddr_t, int, struct newblk **);
static int inodedep_find(struct inodedep_hashhead *, struct fs *, ino_t,
struct inodedep **);
static int inodedep_lookup(struct mount *, ino_t, int, struct inodedep **);
-static int pagedep_lookup(struct inode *, ufs_lbn_t, int, struct pagedep **);
+static int pagedep_lookup(struct mount *, ino_t, ufs_lbn_t, int,
+ struct pagedep **);
static int pagedep_find(struct pagedep_hashhead *, ino_t, ufs_lbn_t,
struct mount *mp, int, struct pagedep **);
static void pause_timer(void *);
static int request_cleanup(struct mount *, int);
static int process_worklist_item(struct mount *, int);
-static void add_to_worklist(struct worklist *);
+static void process_removes(struct vnode *);
+static void jwork_move(struct workhead *, struct workhead *);
+static void add_to_worklist(struct worklist *, int);
+static void remove_from_worklist(struct worklist *);
static void softdep_flush(void);
static int softdep_speedup(void);
+static void worklist_speedup(void);
+static int journal_mount(struct mount *, struct fs *, struct ucred *);
+static void journal_unmount(struct mount *);
+static int journal_space(struct ufsmount *, int);
+static void journal_suspend(struct ufsmount *);
+static void softdep_prelink(struct vnode *, struct vnode *);
+static void add_to_journal(struct worklist *);
+static void remove_from_journal(struct worklist *);
+static void softdep_process_journal(struct mount *, int);
+static struct jremref *newjremref(struct dirrem *, struct inode *,
+ struct inode *ip, off_t, nlink_t);
+static struct jaddref *newjaddref(struct inode *, ino_t, off_t, int16_t,
+ uint16_t);
+static inline void newinoref(struct inoref *, ino_t, ino_t, off_t, nlink_t,
+ uint16_t);
+static inline struct jsegdep *inoref_jseg(struct inoref *);
+static struct jmvref *newjmvref(struct inode *, ino_t, off_t, off_t);
+static struct jfreeblk *newjfreeblk(struct freeblks *, ufs_lbn_t,
+ ufs2_daddr_t, int);
+static struct jfreefrag *newjfreefrag(struct freefrag *, struct inode *,
+ ufs2_daddr_t, long, ufs_lbn_t);
+static struct freework *newfreework(struct freeblks *, struct freework *,
+ ufs_lbn_t, ufs2_daddr_t, int, int);
+static void jwait(struct worklist *wk);
+static struct inodedep *inodedep_lookup_ip(struct inode *);
+static int bmsafemap_rollbacks(struct bmsafemap *);
+static struct freefile *handle_bufwait(struct inodedep *, struct workhead *);
+static void handle_jwork(struct workhead *);
+static struct mkdir *setup_newdir(struct diradd *, ino_t, ino_t, struct buf *,
+ struct mkdir **);
+static struct jblocks *jblocks_create(void);
+static ufs2_daddr_t jblocks_alloc(struct jblocks *, int, int *);
+static void jblocks_free(struct jblocks *, struct mount *, int);
+static void jblocks_destroy(struct jblocks *);
+static void jblocks_add(struct jblocks *, ufs2_daddr_t, int);
/*
* Exported softdep operations.
@@ -572,40 +749,128 @@ MTX_SYSINIT(softdep_lock, &lk, "Softdep Lock", MTX_DEF);
(item)->wk_state &= ~ONWORKLIST; \
LIST_REMOVE(item, wk_list); \
} while (0)
+#define WORKLIST_INSERT_UNLOCKED WORKLIST_INSERT
+#define WORKLIST_REMOVE_UNLOCKED WORKLIST_REMOVE
+
#else /* DEBUG */
-static void worklist_insert(struct workhead *, struct worklist *);
-static void worklist_remove(struct worklist *);
+static void worklist_insert(struct workhead *, struct worklist *, int);
+static void worklist_remove(struct worklist *, int);
-#define WORKLIST_INSERT(head, item) worklist_insert(head, item)
-#define WORKLIST_REMOVE(item) worklist_remove(item)
+#define WORKLIST_INSERT(head, item) worklist_insert(head, item, 1)
+#define WORKLIST_INSERT_UNLOCKED(head, item) worklist_insert(head, item, 0)
+#define WORKLIST_REMOVE(item) worklist_remove(item, 1)
+#define WORKLIST_REMOVE_UNLOCKED(item) worklist_remove(item, 0)
static void
-worklist_insert(head, item)
+worklist_insert(head, item, locked)
struct workhead *head;
struct worklist *item;
+ int locked;
{
- mtx_assert(&lk, MA_OWNED);
+ if (locked)
+ mtx_assert(&lk, MA_OWNED);
if (item->wk_state & ONWORKLIST)
- panic("worklist_insert: already on list");
+ panic("worklist_insert: %p %s(0x%X) already on list",
+ item, TYPENAME(item->wk_type), item->wk_state);
item->wk_state |= ONWORKLIST;
LIST_INSERT_HEAD(head, item, wk_list);
}
static void
-worklist_remove(item)
+worklist_remove(item, locked)
struct worklist *item;
+ int locked;
{
- mtx_assert(&lk, MA_OWNED);
+ if (locked)
+ mtx_assert(&lk, MA_OWNED);
if ((item->wk_state & ONWORKLIST) == 0)
- panic("worklist_remove: not on list");
+ panic("worklist_remove: %p %s(0x%X) not on list",
+ item, TYPENAME(item->wk_type), item->wk_state);
item->wk_state &= ~ONWORKLIST;
LIST_REMOVE(item, wk_list);
}
#endif /* DEBUG */
/*
+ * Merge two jsegdeps keeping only the oldest one as newer references
+ * can't be discarded until after older references.
+ */
+static inline struct jsegdep *
+jsegdep_merge(struct jsegdep *one, struct jsegdep *two)
+{
+ struct jsegdep *swp;
+
+ if (two == NULL)
+ return (one);
+
+ if (one->jd_seg->js_seq > two->jd_seg->js_seq) {
+ swp = one;
+ one = two;
+ two = swp;
+ }
+ WORKLIST_REMOVE(&two->jd_list);
+ free_jsegdep(two);
+
+ return (one);
+}
+
+/*
+ * If two freedeps are compatible free one to reduce list size.
+ */
+static inline struct freedep *
+freedep_merge(struct freedep *one, struct freedep *two)
+{
+ if (two == NULL)
+ return (one);
+
+ if (one->fd_freework == two->fd_freework) {
+ WORKLIST_REMOVE(&two->fd_list);
+ free_freedep(two);
+ }
+ return (one);
+}
+
+/*
+ * Move journal work from one list to another. Duplicate freedeps and
+ * jsegdeps are coalesced to keep the lists as small as possible.
+ */
+static void
+jwork_move(dst, src)
+ struct workhead *dst;
+ struct workhead *src;
+{
+ struct freedep *freedep;
+ struct jsegdep *jsegdep;
+ struct worklist *wkn;
+ struct worklist *wk;
+
+ KASSERT(dst != src,
+ ("jwork_move: dst == src"));
+ freedep = NULL;
+ jsegdep = NULL;
+ LIST_FOREACH_SAFE(wk, dst, wk_list, wkn) {
+ if (wk->wk_type == D_JSEGDEP)
+ jsegdep = jsegdep_merge(WK_JSEGDEP(wk), jsegdep);
+ if (wk->wk_type == D_FREEDEP)
+ freedep = freedep_merge(WK_FREEDEP(wk), freedep);
+ }
+
+ mtx_assert(&lk, MA_OWNED);
+ while ((wk = LIST_FIRST(src)) != NULL) {
+ WORKLIST_REMOVE(wk);
+ WORKLIST_INSERT(dst, wk);
+ if (wk->wk_type == D_JSEGDEP) {
+ jsegdep = jsegdep_merge(WK_JSEGDEP(wk), jsegdep);
+ continue;
+ }
+ if (wk->wk_type == D_FREEDEP)
+ freedep = freedep_merge(WK_FREEDEP(wk), freedep);
+ }
+}
+
+/*
* Routines for tracking and managing workitems.
*/
static void workitem_free(struct worklist *, int);
@@ -623,13 +888,16 @@ workitem_free(item, type)
#ifdef DEBUG
if (item->wk_state & ONWORKLIST)
- panic("workitem_free: still on list");
+ panic("workitem_free: %s(0x%X) still on list",
+ TYPENAME(item->wk_type), item->wk_state);
if (item->wk_type != type)
- panic("workitem_free: type mismatch");
+ panic("workitem_free: type mismatch %s != %s",
+ TYPENAME(item->wk_type), TYPENAME(type));
#endif
ump = VFSTOUFS(item->wk_mp);
if (--ump->softdep_deps == 0 && ump->softdep_req)
wakeup(&ump->softdep_deps);
+ dep_current[type]--;
free(item, DtoM(type));
}
@@ -643,6 +911,8 @@ workitem_alloc(item, type, mp)
item->wk_mp = mp;
item->wk_state = 0;
ACQUIRE_LOCK(&lk);
+ dep_current[type]++;
+ dep_total[type]++;
VFSTOUFS(mp)->softdep_deps++;
VFSTOUFS(mp)->softdep_accdeps++;
FREE_LOCK(&lk);
@@ -678,24 +948,66 @@ static int stat_indir_blk_ptrs; /* bufs redirtied as indir ptrs not written */
static int stat_inode_bitmap; /* bufs redirtied as inode bitmap not written */
static int stat_direct_blk_ptrs;/* bufs redirtied as direct ptrs not written */
static int stat_dir_entry; /* bufs redirtied as dir entry cannot write */
-
-SYSCTL_INT(_debug, OID_AUTO, max_softdeps, CTLFLAG_RW, &max_softdeps, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, tickdelay, CTLFLAG_RW, &tickdelay, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, maxindirdeps, CTLFLAG_RW, &maxindirdeps, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, worklist_push, CTLFLAG_RW, &stat_worklist_push, 0,"");
-SYSCTL_INT(_debug, OID_AUTO, blk_limit_push, CTLFLAG_RW, &stat_blk_limit_push, 0,"");
-SYSCTL_INT(_debug, OID_AUTO, ino_limit_push, CTLFLAG_RW, &stat_ino_limit_push, 0,"");
-SYSCTL_INT(_debug, OID_AUTO, blk_limit_hit, CTLFLAG_RW, &stat_blk_limit_hit, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, ino_limit_hit, CTLFLAG_RW, &stat_ino_limit_hit, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, sync_limit_hit, CTLFLAG_RW, &stat_sync_limit_hit, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, indir_blk_ptrs, CTLFLAG_RW, &stat_indir_blk_ptrs, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, inode_bitmap, CTLFLAG_RW, &stat_inode_bitmap, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, direct_blk_ptrs, CTLFLAG_RW, &stat_direct_blk_ptrs, 0, "");
-SYSCTL_INT(_debug, OID_AUTO, dir_entry, CTLFLAG_RW, &stat_dir_entry, 0, "");
-/* SYSCTL_INT(_debug, OID_AUTO, worklist_num, CTLFLAG_RD, &softdep_on_worklist, 0, ""); */
+static int stat_jaddref; /* bufs redirtied as ino bitmap can not write */
+static int stat_jnewblk; /* bufs redirtied as blk bitmap can not write */
+static int stat_journal_min; /* Times hit journal min threshold */
+static int stat_journal_low; /* Times hit journal low threshold */
+static int stat_journal_wait; /* Times blocked in jwait(). */
+static int stat_jwait_filepage; /* Times blocked in jwait() for filepage. */
+static int stat_jwait_freeblks; /* Times blocked in jwait() for freeblks. */
+static int stat_jwait_inode; /* Times blocked in jwait() for inodes. */
+static int stat_jwait_newblk; /* Times blocked in jwait() for newblks. */
+
+SYSCTL_INT(_debug_softdep, OID_AUTO, max_softdeps, CTLFLAG_RW,
+ &max_softdeps, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, tickdelay, CTLFLAG_RW,
+ &tickdelay, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, maxindirdeps, CTLFLAG_RW,
+ &maxindirdeps, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, worklist_push, CTLFLAG_RW,
+ &stat_worklist_push, 0,"");
+SYSCTL_INT(_debug_softdep, OID_AUTO, blk_limit_push, CTLFLAG_RW,
+ &stat_blk_limit_push, 0,"");
+SYSCTL_INT(_debug_softdep, OID_AUTO, ino_limit_push, CTLFLAG_RW,
+ &stat_ino_limit_push, 0,"");
+SYSCTL_INT(_debug_softdep, OID_AUTO, blk_limit_hit, CTLFLAG_RW,
+ &stat_blk_limit_hit, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, ino_limit_hit, CTLFLAG_RW,
+ &stat_ino_limit_hit, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, sync_limit_hit, CTLFLAG_RW,
+ &stat_sync_limit_hit, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, indir_blk_ptrs, CTLFLAG_RW,
+ &stat_indir_blk_ptrs, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, inode_bitmap, CTLFLAG_RW,
+ &stat_inode_bitmap, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, direct_blk_ptrs, CTLFLAG_RW,
+ &stat_direct_blk_ptrs, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, dir_entry, CTLFLAG_RW,
+ &stat_dir_entry, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, jaddref_rollback, CTLFLAG_RW,
+ &stat_jaddref, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, jnewblk_rollback, CTLFLAG_RW,
+ &stat_jnewblk, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, journal_low, CTLFLAG_RW,
+ &stat_journal_low, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, journal_min, CTLFLAG_RW,
+ &stat_journal_min, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, journal_wait, CTLFLAG_RW,
+ &stat_journal_wait, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_filepage, CTLFLAG_RW,
+ &stat_jwait_filepage, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_freeblks, CTLFLAG_RW,
+ &stat_jwait_freeblks, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_inode, CTLFLAG_RW,
+ &stat_jwait_inode, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, jwait_newblk, CTLFLAG_RW,
+ &stat_jwait_newblk, 0, "");
SYSCTL_DECL(_vfs_ffs);
+LIST_HEAD(bmsafemap_hashhead, bmsafemap) *bmsafemap_hashtbl;
+static u_long bmsafemap_hash; /* size of hash table - 1 */
+
static int compute_summary_at_mount = 0; /* Whether to recompute the summary at mount time */
SYSCTL_INT(_vfs_ffs, OID_AUTO, compute_summary_at_mount, CTLFLAG_RW,
&compute_summary_at_mount, 0, "Recompute summary at mount");
@@ -770,16 +1082,22 @@ softdep_flush(void)
}
}
-static int
-softdep_speedup(void)
+static void
+worklist_speedup(void)
{
-
mtx_assert(&lk, MA_OWNED);
if (req_pending == 0) {
req_pending = 1;
wakeup(&req_pending);
}
+}
+static int
+softdep_speedup(void)
+{
+
+ worklist_speedup();
+ bd_speedup();
return speedup_syncer();
}
@@ -791,15 +1109,17 @@ softdep_speedup(void)
* and does so in order from first to last.
*/
static void
-add_to_worklist(wk)
+add_to_worklist(wk, nodelay)
struct worklist *wk;
+ int nodelay;
{
struct ufsmount *ump;
mtx_assert(&lk, MA_OWNED);
ump = VFSTOUFS(wk->wk_mp);
if (wk->wk_state & ONWORKLIST)
- panic("add_to_worklist: already on list");
+ panic("add_to_worklist: %s(0x%X) already on list",
+ TYPENAME(wk->wk_type), wk->wk_state);
wk->wk_state |= ONWORKLIST;
if (LIST_EMPTY(&ump->softdep_workitem_pending))
LIST_INSERT_HEAD(&ump->softdep_workitem_pending, wk, wk_list);
@@ -807,6 +1127,30 @@ add_to_worklist(wk)
LIST_INSERT_AFTER(ump->softdep_worklist_tail, wk, wk_list);
ump->softdep_worklist_tail = wk;
ump->softdep_on_worklist += 1;
+ if (nodelay)
+ worklist_speedup();
+}
+
+/*
+ * Remove the item to be processed. If we are removing the last
+ * item on the list, we need to recalculate the tail pointer.
+ */
+static void
+remove_from_worklist(wk)
+ struct worklist *wk;
+{
+ struct ufsmount *ump;
+ struct worklist *wkend;
+
+ ump = VFSTOUFS(wk->wk_mp);
+ WORKLIST_REMOVE(wk);
+ if (wk == ump->softdep_worklist_tail) {
+ LIST_FOREACH(wkend, &ump->softdep_workitem_pending, wk_list)
+ if (LIST_NEXT(wkend, wk_list) == NULL)
+ break;
+ ump->softdep_worklist_tail = wkend;
+ }
+ ump->softdep_on_worklist -= 1;
}
/*
@@ -838,8 +1182,9 @@ softdep_process_worklist(mp, full)
ACQUIRE_LOCK(&lk);
loopcount = 1;
starttime = time_second;
+ softdep_process_journal(mp, full?MNT_WAIT:0);
while (ump->softdep_on_worklist > 0) {
- if ((cnt = process_worklist_item(mp, 0)) == -1)
+ if ((cnt = process_worklist_item(mp, LK_NOWAIT)) == -1)
break;
else
matchcnt += cnt;
@@ -871,16 +1216,61 @@ softdep_process_worklist(mp, full)
* second. Otherwise the other mountpoints may get
* excessively backlogged.
*/
- if (!full && starttime != time_second) {
- matchcnt = -1;
+ if (!full && starttime != time_second)
break;
- }
}
FREE_LOCK(&lk);
return (matchcnt);
}
/*
+ * Process all removes associated with a vnode if we are running out of
+ * journal space. Any other process which attempts to flush these will
+ * be unable as we have the vnodes locked.
+ */
+static void
+process_removes(vp)
+ struct vnode *vp;
+{
+ struct inodedep *inodedep;
+ struct dirrem *dirrem;
+ struct mount *mp;
+ ino_t inum;
+
+ mtx_assert(&lk, MA_OWNED);
+
+ mp = vp->v_mount;
+ inum = VTOI(vp)->i_number;
+ for (;;) {
+ if (inodedep_lookup(mp, inum, 0, &inodedep) == 0)
+ return;
+ LIST_FOREACH(dirrem, &inodedep->id_dirremhd, dm_inonext)
+ if ((dirrem->dm_state & (COMPLETE | ONWORKLIST)) ==
+ (COMPLETE | ONWORKLIST))
+ break;
+ if (dirrem == NULL)
+ return;
+ /*
+ * If another thread is trying to lock this vnode it will
+ * fail but we must wait for it to do so before we can
+ * proceed.
+ */
+ if (dirrem->dm_state & INPROGRESS) {
+ dirrem->dm_state |= IOWAITING;
+ msleep(&dirrem->dm_list, &lk, PVM, "pwrwait", 0);
+ continue;
+ }
+ remove_from_worklist(&dirrem->dm_list);
+ FREE_LOCK(&lk);
+ if (vn_start_secondary_write(NULL, &mp, V_NOWAIT))
+ panic("process_removes: suspended filesystem");
+ handle_workitem_remove(dirrem, vp);
+ vn_finished_secondary_write(mp);
+ ACQUIRE_LOCK(&lk);
+ }
+}
+
+/*
* Process one item on the worklist.
*/
static int
@@ -888,7 +1278,7 @@ process_worklist_item(mp, flags)
struct mount *mp;
int flags;
{
- struct worklist *wk, *wkend;
+ struct worklist *wk, *wkXXX;
struct ufsmount *ump;
struct vnode *vp;
int matchcnt = 0;
@@ -908,11 +1298,14 @@ process_worklist_item(mp, flags)
* inodes, we have to skip over any dirrem requests whose
* vnodes are resident and locked.
*/
- ump = VFSTOUFS(mp);
vp = NULL;
+ ump = VFSTOUFS(mp);
LIST_FOREACH(wk, &ump->softdep_workitem_pending, wk_list) {
- if (wk->wk_state & INPROGRESS)
+ if (wk->wk_state & INPROGRESS) {
+ wkXXX = wk;
continue;
+ }
+ wkXXX = wk; /* Record the last valid wk pointer. */
if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM)
break;
wk->wk_state |= INPROGRESS;
@@ -921,6 +1314,10 @@ process_worklist_item(mp, flags)
ffs_vgetf(mp, WK_DIRREM(wk)->dm_oldinum,
LK_NOWAIT | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ);
ACQUIRE_LOCK(&lk);
+ if (wk->wk_state & IOWAITING) {
+ wk->wk_state &= ~IOWAITING;
+ wakeup(wk);
+ }
wk->wk_state &= ~INPROGRESS;
ump->softdep_on_worklist_inprogress--;
if (vp != NULL)
@@ -928,21 +1325,7 @@ process_worklist_item(mp, flags)
}
if (wk == 0)
return (-1);
- /*
- * Remove the item to be processed. If we are removing the last
- * item on the list, we need to recalculate the tail pointer.
- * As this happens rarely and usually when the list is short,
- * we just run down the list to find it rather than tracking it
- * in the above loop.
- */
- WORKLIST_REMOVE(wk);
- if (wk == ump->softdep_worklist_tail) {
- LIST_FOREACH(wkend, &ump->softdep_workitem_pending, wk_list)
- if (LIST_NEXT(wkend, wk_list) == NULL)
- break;
- ump->softdep_worklist_tail = wkend;
- }
- ump->softdep_on_worklist -= 1;
+ remove_from_worklist(wk);
FREE_LOCK(&lk);
if (vn_start_secondary_write(NULL, &mp, V_NOWAIT))
panic("process_worklist_item: suspended filesystem");
@@ -952,6 +1335,8 @@ process_worklist_item(mp, flags)
case D_DIRREM:
/* removal of a directory entry */
handle_workitem_remove(WK_DIRREM(wk), vp);
+ if (vp)
+ vput(vp);
break;
case D_FREEBLKS:
@@ -969,6 +1354,11 @@ process_worklist_item(mp, flags)
handle_workitem_freefile(WK_FREEFILE(wk));
break;
+ case D_FREEWORK:
+ /* Final block in an indirect was freed. */
+ handle_workitem_indirblk(WK_FREEWORK(wk));
+ break;
+
default:
panic("%s_process_worklist: Unknown type %s",
"softdep", TYPENAME(wk->wk_type));
@@ -982,19 +1372,22 @@ process_worklist_item(mp, flags)
/*
* Move dependencies from one buffer to another.
*/
-void
+int
softdep_move_dependencies(oldbp, newbp)
struct buf *oldbp;
struct buf *newbp;
{
struct worklist *wk, *wktail;
+ int dirty;
- if (!LIST_EMPTY(&newbp->b_dep))
- panic("softdep_move_dependencies: need merge code");
- wktail = 0;
+ dirty = 0;
+ wktail = NULL;
ACQUIRE_LOCK(&lk);
while ((wk = LIST_FIRST(&oldbp->b_dep)) != NULL) {
LIST_REMOVE(wk, wk_list);
+ if (wk->wk_type == D_BMSAFEMAP &&
+ bmsafemap_rollbacks(WK_BMSAFEMAP(wk)))
+ dirty = 1;
if (wktail == 0)
LIST_INSERT_HEAD(&newbp->b_dep, wk, wk_list);
else
@@ -1002,6 +1395,8 @@ softdep_move_dependencies(oldbp, newbp)
wktail = wk;
}
FREE_LOCK(&lk);
+
+ return (dirty);
}
/*
@@ -1198,23 +1593,22 @@ pagedep_find(pagedephd, ino, lbn, mp, flags, pagedeppp)
* This routine must be called with splbio interrupts blocked.
*/
static int
-pagedep_lookup(ip, lbn, flags, pagedeppp)
- struct inode *ip;
+pagedep_lookup(mp, ino, lbn, flags, pagedeppp)
+ struct mount *mp;
+ ino_t ino;
ufs_lbn_t lbn;
int flags;
struct pagedep **pagedeppp;
{
struct pagedep *pagedep;
struct pagedep_hashhead *pagedephd;
- struct mount *mp;
int ret;
int i;
mtx_assert(&lk, MA_OWNED);
- mp = ITOV(ip)->v_mount;
- pagedephd = PAGEDEP_HASH(mp, ip->i_number, lbn);
+ pagedephd = PAGEDEP_HASH(mp, ino, lbn);
- ret = pagedep_find(pagedephd, ip->i_number, lbn, mp, flags, pagedeppp);
+ ret = pagedep_find(pagedephd, ino, lbn, mp, flags, pagedeppp);
if (*pagedeppp || (flags & DEPALLOC) == 0)
return (ret);
FREE_LOCK(&lk);
@@ -1222,12 +1616,12 @@ pagedep_lookup(ip, lbn, flags, pagedeppp)
M_PAGEDEP, M_SOFTDEP_FLAGS|M_ZERO);
workitem_alloc(&pagedep->pd_list, D_PAGEDEP, mp);
ACQUIRE_LOCK(&lk);
- ret = pagedep_find(pagedephd, ip->i_number, lbn, mp, flags, pagedeppp);
+ ret = pagedep_find(pagedephd, ino, lbn, mp, flags, pagedeppp);
if (*pagedeppp) {
WORKITEM_FREE(pagedep, D_PAGEDEP);
return (ret);
}
- pagedep->pd_ino = ip->i_number;
+ pagedep->pd_ino = ino;
pagedep->pd_lbn = lbn;
LIST_INIT(&pagedep->pd_dirremhd);
LIST_INIT(&pagedep->pd_pendinghd);
@@ -1314,10 +1708,14 @@ inodedep_lookup(mp, inum, flags, inodedeppp)
inodedep->id_savedino1 = NULL;
inodedep->id_savedsize = -1;
inodedep->id_savedextsize = -1;
- inodedep->id_buf = NULL;
+ inodedep->id_savednlink = -1;
+ inodedep->id_bmsafemap = NULL;
+ inodedep->id_mkdiradd = NULL;
+ LIST_INIT(&inodedep->id_dirremhd);
LIST_INIT(&inodedep->id_pendinghd);
LIST_INIT(&inodedep->id_inowait);
LIST_INIT(&inodedep->id_bufwait);
+ TAILQ_INIT(&inodedep->id_inoreflst);
TAILQ_INIT(&inodedep->id_inoupdt);
TAILQ_INIT(&inodedep->id_newinoupdt);
TAILQ_INIT(&inodedep->id_extupdt);
@@ -1336,17 +1734,29 @@ u_long newblk_hash; /* size of hash table - 1 */
(&newblk_hashtbl[((((register_t)(fs)) >> 13) + (inum)) & newblk_hash])
static int
-newblk_find(newblkhd, fs, newblkno, newblkpp)
+newblk_find(newblkhd, mp, newblkno, flags, newblkpp)
struct newblk_hashhead *newblkhd;
- struct fs *fs;
+ struct mount *mp;
ufs2_daddr_t newblkno;
+ int flags;
struct newblk **newblkpp;
{
struct newblk *newblk;
- LIST_FOREACH(newblk, newblkhd, nb_hash)
- if (newblkno == newblk->nb_newblkno && fs == newblk->nb_fs)
- break;
+ LIST_FOREACH(newblk, newblkhd, nb_hash) {
+ if (newblkno != newblk->nb_newblkno)
+ continue;
+ if (mp != newblk->nb_list.wk_mp)
+ continue;
+ /*
+ * If we're creating a new dependency don't match those that
+ * have already been converted to allocdirects. This is for
+ * a frag extend.
+ */
+ if ((flags & DEPALLOC) && newblk->nb_list.wk_type != D_NEWBLK)
+ continue;
+ break;
+ }
if (newblk) {
*newblkpp = newblk;
return (1);
@@ -1361,8 +1771,8 @@ newblk_find(newblkhd, fs, newblkno, newblkpp)
* Found or allocated entry is returned in newblkpp.
*/
static int
-newblk_lookup(fs, newblkno, flags, newblkpp)
- struct fs *fs;
+newblk_lookup(mp, newblkno, flags, newblkpp)
+ struct mount *mp;
ufs2_daddr_t newblkno;
int flags;
struct newblk **newblkpp;
@@ -1370,21 +1780,25 @@ newblk_lookup(fs, newblkno, flags, newblkpp)
struct newblk *newblk;
struct newblk_hashhead *newblkhd;
- newblkhd = NEWBLK_HASH(fs, newblkno);
- if (newblk_find(newblkhd, fs, newblkno, newblkpp))
+ newblkhd = NEWBLK_HASH(VFSTOUFS(mp)->um_fs, newblkno);
+ if (newblk_find(newblkhd, mp, newblkno, flags, newblkpp))
return (1);
if ((flags & DEPALLOC) == 0)
return (0);
FREE_LOCK(&lk);
- newblk = malloc(sizeof(struct newblk),
- M_NEWBLK, M_SOFTDEP_FLAGS);
+ newblk = malloc(sizeof(union allblk), M_NEWBLK,
+ M_SOFTDEP_FLAGS | M_ZERO);
+ workitem_alloc(&newblk->nb_list, D_NEWBLK, mp);
ACQUIRE_LOCK(&lk);
- if (newblk_find(newblkhd, fs, newblkno, newblkpp)) {
- free(newblk, M_NEWBLK);
+ if (newblk_find(newblkhd, mp, newblkno, flags, newblkpp)) {
+ WORKITEM_FREE(newblk, D_NEWBLK);
return (1);
}
- newblk->nb_state = 0;
- newblk->nb_fs = fs;
+ newblk->nb_freefrag = NULL;
+ LIST_INIT(&newblk->nb_indirdeps);
+ LIST_INIT(&newblk->nb_newdirblk);
+ LIST_INIT(&newblk->nb_jwork);
+ newblk->nb_state = ATTACHED;
newblk->nb_newblkno = newblkno;
LIST_INSERT_HEAD(newblkhd, newblk, nb_hash);
*newblkpp = newblk;
@@ -1401,10 +1815,10 @@ softdep_initialize()
LIST_INIT(&mkdirlisthd);
max_softdeps = desiredvnodes * 4;
- pagedep_hashtbl = hashinit(desiredvnodes / 5, M_PAGEDEP,
- &pagedep_hash);
+ pagedep_hashtbl = hashinit(desiredvnodes / 5, M_PAGEDEP, &pagedep_hash);
inodedep_hashtbl = hashinit(desiredvnodes, M_INODEDEP, &inodedep_hash);
- newblk_hashtbl = hashinit(64, M_NEWBLK, &newblk_hash);
+ newblk_hashtbl = hashinit(desiredvnodes / 5, M_NEWBLK, &newblk_hash);
+ bmsafemap_hashtbl = hashinit(1024, M_BMSAFEMAP, &bmsafemap_hash);
/* initialise bioops hack */
bioops.io_start = softdep_disk_io_initiation;
@@ -1428,6 +1842,7 @@ softdep_uninitialize()
hashdestroy(pagedep_hashtbl, M_PAGEDEP, pagedep_hash);
hashdestroy(inodedep_hashtbl, M_INODEDEP, inodedep_hash);
hashdestroy(newblk_hashtbl, M_NEWBLK, newblk_hash);
+ hashdestroy(bmsafemap_hashtbl, M_BMSAFEMAP, bmsafemap_hash);
}
/*
@@ -1457,9 +1872,16 @@ softdep_mount(devvp, mp, fs, cred)
MNT_IUNLOCK(mp);
ump = VFSTOUFS(mp);
LIST_INIT(&ump->softdep_workitem_pending);
+ LIST_INIT(&ump->softdep_journal_pending);
+ TAILQ_INIT(&ump->softdep_unlinked);
ump->softdep_worklist_tail = NULL;
ump->softdep_on_worklist = 0;
ump->softdep_deps = 0;
+ if ((fs->fs_flags & FS_SUJ) &&
+ (error = journal_mount(mp, fs, cred)) != 0) {
+ printf("Failed to start journal: %d\n", error);
+ return (error);
+ }
/*
* When doing soft updates, the counters in the
* superblock may have gotten out of sync. Recomputation
@@ -1493,6 +1915,2019 @@ softdep_mount(devvp, mp, fs, cred)
return (0);
}
+void
+softdep_unmount(mp)
+ struct mount *mp;
+{
+
+ if (mp->mnt_kern_flag & MNTK_SUJ)
+ journal_unmount(mp);
+}
+
+struct jblocks {
+ struct jseglst jb_segs; /* TAILQ of current segments. */
+ struct jseg *jb_writeseg; /* Next write to complete. */
+ struct jextent *jb_extent; /* Extent array. */
+ uint64_t jb_nextseq; /* Next sequence number. */
+ uint64_t jb_oldestseq; /* Oldest active sequence number. */
+ int jb_avail; /* Available extents. */
+ int jb_used; /* Last used extent. */
+ int jb_head; /* Allocator head. */
+ int jb_off; /* Allocator extent offset. */
+ int jb_blocks; /* Total disk blocks covered. */
+ int jb_free; /* Total disk blocks free. */
+ int jb_min; /* Minimum free space. */
+ int jb_low; /* Low on space. */
+ int jb_age; /* Insertion time of oldest rec. */
+ int jb_suspended; /* Did journal suspend writes? */
+};
+
+struct jextent {
+ ufs2_daddr_t je_daddr; /* Disk block address. */
+ int je_blocks; /* Disk block count. */
+};
+
+static struct jblocks *
+jblocks_create(void)
+{
+ struct jblocks *jblocks;
+
+ jblocks = malloc(sizeof(*jblocks), M_JBLOCKS, M_WAITOK | M_ZERO);
+ TAILQ_INIT(&jblocks->jb_segs);
+ jblocks->jb_avail = 10;
+ jblocks->jb_extent = malloc(sizeof(struct jextent) * jblocks->jb_avail,
+ M_JBLOCKS, M_WAITOK | M_ZERO);
+
+ return (jblocks);
+}
+
+static ufs2_daddr_t
+jblocks_alloc(jblocks, bytes, actual)
+ struct jblocks *jblocks;
+ int bytes;
+ int *actual;
+{
+ ufs2_daddr_t daddr;
+ struct jextent *jext;
+ int freecnt;
+ int blocks;
+
+ blocks = bytes / DEV_BSIZE;
+ jext = &jblocks->jb_extent[jblocks->jb_head];
+ freecnt = jext->je_blocks - jblocks->jb_off;
+ if (freecnt == 0) {
+ jblocks->jb_off = 0;
+ if (++jblocks->jb_head > jblocks->jb_used)
+ jblocks->jb_head = 0;
+ jext = &jblocks->jb_extent[jblocks->jb_head];
+ freecnt = jext->je_blocks;
+ }
+ if (freecnt > blocks)
+ freecnt = blocks;
+ *actual = freecnt * DEV_BSIZE;
+ daddr = jext->je_daddr + jblocks->jb_off;
+ jblocks->jb_off += freecnt;
+ jblocks->jb_free -= freecnt;
+
+ return (daddr);
+}
+
+static void
+jblocks_free(jblocks, mp, bytes)
+ struct jblocks *jblocks;
+ struct mount *mp;
+ int bytes;
+{
+
+ jblocks->jb_free += bytes / DEV_BSIZE;
+ if (jblocks->jb_suspended)
+ worklist_speedup();
+ wakeup(jblocks);
+}
+
+static void
+jblocks_destroy(jblocks)
+ struct jblocks *jblocks;
+{
+
+ if (jblocks->jb_extent)
+ free(jblocks->jb_extent, M_JBLOCKS);
+ free(jblocks, M_JBLOCKS);
+}
+
+static void
+jblocks_add(jblocks, daddr, blocks)
+ struct jblocks *jblocks;
+ ufs2_daddr_t daddr;
+ int blocks;
+{
+ struct jextent *jext;
+
+ jblocks->jb_blocks += blocks;
+ jblocks->jb_free += blocks;
+ jext = &jblocks->jb_extent[jblocks->jb_used];
+ /* Adding the first block. */
+ if (jext->je_daddr == 0) {
+ jext->je_daddr = daddr;
+ jext->je_blocks = blocks;
+ return;
+ }
+ /* Extending the last extent. */
+ if (jext->je_daddr + jext->je_blocks == daddr) {
+ jext->je_blocks += blocks;
+ return;
+ }
+ /* Adding a new extent. */
+ if (++jblocks->jb_used == jblocks->jb_avail) {
+ jblocks->jb_avail *= 2;
+ jext = malloc(sizeof(struct jextent) * jblocks->jb_avail,
+ M_JBLOCKS, M_WAITOK | M_ZERO);
+ memcpy(jext, jblocks->jb_extent,
+ sizeof(struct jextent) * jblocks->jb_used);
+ free(jblocks->jb_extent, M_JBLOCKS);
+ jblocks->jb_extent = jext;
+ }
+ jext = &jblocks->jb_extent[jblocks->jb_used];
+ jext->je_daddr = daddr;
+ jext->je_blocks = blocks;
+ return;
+}
+
+int
+softdep_journal_lookup(mp, vpp)
+ struct mount *mp;
+ struct vnode **vpp;
+{
+ struct componentname cnp;
+ struct vnode *dvp;
+ ino_t sujournal;
+ int error;
+
+ error = VFS_VGET(mp, ROOTINO, LK_EXCLUSIVE, &dvp);
+ if (error)
+ return (error);
+ bzero(&cnp, sizeof(cnp));
+ cnp.cn_nameiop = LOOKUP;
+ cnp.cn_flags = ISLASTCN;
+ cnp.cn_thread = curthread;
+ cnp.cn_cred = curthread->td_ucred;
+ cnp.cn_pnbuf = SUJ_FILE;
+ cnp.cn_nameptr = SUJ_FILE;
+ cnp.cn_namelen = strlen(SUJ_FILE);
+ error = ufs_lookup_ino(dvp, NULL, &cnp, &sujournal);
+ vput(dvp);
+ if (error != 0)
+ return (error);
+ error = VFS_VGET(mp, sujournal, LK_EXCLUSIVE, vpp);
+ return (error);
+}
+
+/*
+ * Open and verify the journal file.
+ */
+static int
+journal_mount(mp, fs, cred)
+ struct mount *mp;
+ struct fs *fs;
+ struct ucred *cred;
+{
+ struct jblocks *jblocks;
+ struct vnode *vp;
+ struct inode *ip;
+ ufs2_daddr_t blkno;
+ int bcount;
+ int error;
+ int i;
+
+ mp->mnt_kern_flag |= MNTK_SUJ;
+ error = softdep_journal_lookup(mp, &vp);
+ if (error != 0) {
+ printf("Failed to find journal. Use tunefs to create one\n");
+ return (error);
+ }
+ ip = VTOI(vp);
+ if (ip->i_size < SUJ_MIN) {
+ error = ENOSPC;
+ goto out;
+ }
+ bcount = lblkno(fs, ip->i_size); /* Only use whole blocks. */
+ jblocks = jblocks_create();
+ for (i = 0; i < bcount; i++) {
+ error = ufs_bmaparray(vp, i, &blkno, NULL, NULL, NULL);
+ if (error)
+ break;
+ jblocks_add(jblocks, blkno, fsbtodb(fs, fs->fs_frag));
+ }
+ if (error) {
+ jblocks_destroy(jblocks);
+ goto out;
+ }
+ jblocks->jb_low = jblocks->jb_free / 3; /* Reserve 33%. */
+ jblocks->jb_min = jblocks->jb_free / 10; /* Suspend at 10%. */
+ /*
+ * Only validate the journal contents if the filesystem is clean,
+ * otherwise we write the logs but they'll never be used. If the
+ * filesystem was still dirty when we mounted it the journal is
+ * invalid and a new journal can only be valid if it starts from a
+ * clean mount.
+ */
+ if (fs->fs_clean) {
+ DIP_SET(ip, i_modrev, fs->fs_mtime);
+ ip->i_flags |= IN_MODIFIED;
+ ffs_update(vp, 1);
+ }
+ VFSTOUFS(mp)->softdep_jblocks = jblocks;
+out:
+ vput(vp);
+ return (error);
+}
+
+static void
+journal_unmount(mp)
+ struct mount *mp;
+{
+ struct ufsmount *ump;
+
+ ump = VFSTOUFS(mp);
+ if (ump->softdep_jblocks)
+ jblocks_destroy(ump->softdep_jblocks);
+ ump->softdep_jblocks = NULL;
+}
+
+/*
+ * Called when a journal record is ready to be written. Space is allocated
+ * and the journal entry is created when the journal is flushed to stable
+ * store.
+ */
+static void
+add_to_journal(wk)
+ struct worklist *wk;
+{
+ struct ufsmount *ump;
+
+ mtx_assert(&lk, MA_OWNED);
+ ump = VFSTOUFS(wk->wk_mp);
+ if (wk->wk_state & ONWORKLIST)
+ panic("add_to_journal: %s(0x%X) already on list",
+ TYPENAME(wk->wk_type), wk->wk_state);
+ wk->wk_state |= ONWORKLIST | DEPCOMPLETE;
+ if (LIST_EMPTY(&ump->softdep_journal_pending)) {
+ ump->softdep_jblocks->jb_age = ticks;
+ LIST_INSERT_HEAD(&ump->softdep_journal_pending, wk, wk_list);
+ } else
+ LIST_INSERT_AFTER(ump->softdep_journal_tail, wk, wk_list);
+ ump->softdep_journal_tail = wk;
+ ump->softdep_on_journal += 1;
+}
+
+/*
+ * Remove an arbitrary item for the journal worklist maintain the tail
+ * pointer. This happens when a new operation obviates the need to
+ * journal an old operation.
+ */
+static void
+remove_from_journal(wk)
+ struct worklist *wk;
+{
+ struct ufsmount *ump;
+
+ mtx_assert(&lk, MA_OWNED);
+ ump = VFSTOUFS(wk->wk_mp);
+#ifdef DEBUG /* XXX Expensive, temporary. */
+ {
+ struct worklist *wkn;
+
+ LIST_FOREACH(wkn, &ump->softdep_journal_pending, wk_list)
+ if (wkn == wk)
+ break;
+ if (wkn == NULL)
+ panic("remove_from_journal: %p is not in journal", wk);
+ }
+#endif
+ /*
+ * We emulate a TAILQ to save space in most structures which do not
+ * require TAILQ semantics. Here we must update the tail position
+ * when removing the tail which is not the final entry.
+ */
+ if (ump->softdep_journal_tail == wk)
+ ump->softdep_journal_tail =
+ (struct worklist *)wk->wk_list.le_prev;
+
+ WORKLIST_REMOVE(wk);
+ ump->softdep_on_journal -= 1;
+}
+
+/*
+ * Check for journal space as well as dependency limits so the prelink
+ * code can throttle both journaled and non-journaled filesystems.
+ * Threshold is 0 for low and 1 for min.
+ */
+static int
+journal_space(ump, thresh)
+ struct ufsmount *ump;
+ int thresh;
+{
+ struct jblocks *jblocks;
+ int avail;
+
+ /*
+ * We use a tighter restriction here to prevent request_cleanup()
+ * running in threads from running into locks we currently hold.
+ */
+ if (num_inodedep > (max_softdeps / 10) * 9)
+ return (0);
+
+ jblocks = ump->softdep_jblocks;
+ if (jblocks == NULL)
+ return (1);
+ if (thresh)
+ thresh = jblocks->jb_min;
+ else
+ thresh = jblocks->jb_low;
+ avail = (ump->softdep_on_journal * JREC_SIZE) / DEV_BSIZE;
+ avail = jblocks->jb_free - avail;
+
+ return (avail > thresh);
+}
+
+static void
+journal_suspend(ump)
+ struct ufsmount *ump;
+{
+ struct jblocks *jblocks;
+ struct mount *mp;
+
+ mp = UFSTOVFS(ump);
+ jblocks = ump->softdep_jblocks;
+ MNT_ILOCK(mp);
+ if ((mp->mnt_kern_flag & MNTK_SUSPEND) == 0) {
+ stat_journal_min++;
+ mp->mnt_kern_flag |= MNTK_SUSPEND;
+ mp->mnt_susp_owner = FIRST_THREAD_IN_PROC(softdepproc);
+ }
+ jblocks->jb_suspended = 1;
+ MNT_IUNLOCK(mp);
+}
+
+/*
+ * Called before any allocation function to be certain that there is
+ * sufficient space in the journal prior to creating any new records.
+ * Since in the case of block allocation we may have multiple locked
+ * buffers at the time of the actual allocation we can not block
+ * when the journal records are created. Doing so would create a deadlock
+ * if any of these buffers needed to be flushed to reclaim space. Instead
+ * we require a sufficiently large amount of available space such that
+ * each thread in the system could have passed this allocation check and
+ * still have sufficient free space. With 20% of a minimum journal size
+ * of 1MB we have 6553 records available.
+ */
+int
+softdep_prealloc(vp, waitok)
+ struct vnode *vp;
+ int waitok;
+{
+ struct ufsmount *ump;
+
+ if (DOINGSUJ(vp) == 0)
+ return (0);
+ ump = VFSTOUFS(vp->v_mount);
+ ACQUIRE_LOCK(&lk);
+ if (journal_space(ump, 0)) {
+ FREE_LOCK(&lk);
+ return (0);
+ }
+ stat_journal_low++;
+ FREE_LOCK(&lk);
+ if (waitok == MNT_NOWAIT)
+ return (ENOSPC);
+ /*
+ * Attempt to sync this vnode once to flush any journal
+ * work attached to it.
+ */
+ ffs_syncvnode(vp, waitok);
+ ACQUIRE_LOCK(&lk);
+ process_removes(vp);
+ if (journal_space(ump, 0) == 0) {
+ softdep_speedup();
+ if (journal_space(ump, 1) == 0)
+ journal_suspend(ump);
+ }
+ FREE_LOCK(&lk);
+
+ return (0);
+}
+
+/*
+ * Before adjusting a link count on a vnode verify that we have sufficient
+ * journal space. If not, process operations that depend on the currently
+ * locked pair of vnodes to try to flush space as the syncer, buf daemon,
+ * and softdep flush threads can not acquire these locks to reclaim space.
+ */
+static void
+softdep_prelink(dvp, vp)
+ struct vnode *dvp;
+ struct vnode *vp;
+{
+ struct ufsmount *ump;
+
+ ump = VFSTOUFS(dvp->v_mount);
+ mtx_assert(&lk, MA_OWNED);
+ if (journal_space(ump, 0))
+ return;
+ stat_journal_low++;
+ FREE_LOCK(&lk);
+ if (vp)
+ ffs_syncvnode(vp, MNT_NOWAIT);
+ ffs_syncvnode(dvp, MNT_WAIT);
+ ACQUIRE_LOCK(&lk);
+ /* Process vp before dvp as it may create .. removes. */
+ if (vp)
+ process_removes(vp);
+ process_removes(dvp);
+ softdep_speedup();
+ process_worklist_item(UFSTOVFS(ump), LK_NOWAIT);
+ process_worklist_item(UFSTOVFS(ump), LK_NOWAIT);
+ if (journal_space(ump, 0) == 0) {
+ softdep_speedup();
+ if (journal_space(ump, 1) == 0)
+ journal_suspend(ump);
+ }
+}
+
+static void
+jseg_write(fs, jblocks, jseg, data)
+ struct fs *fs;
+ struct jblocks *jblocks;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jsegrec *rec;
+
+ rec = (struct jsegrec *)data;
+ rec->jsr_seq = jseg->js_seq;
+ rec->jsr_oldest = jblocks->jb_oldestseq;
+ rec->jsr_cnt = jseg->js_cnt;
+ rec->jsr_blocks = jseg->js_size / DEV_BSIZE;
+ rec->jsr_crc = 0;
+ rec->jsr_time = fs->fs_mtime;
+}
+
+static inline void
+inoref_write(inoref, jseg, rec)
+ struct inoref *inoref;
+ struct jseg *jseg;
+ struct jrefrec *rec;
+{
+
+ inoref->if_jsegdep->jd_seg = jseg;
+ rec->jr_ino = inoref->if_ino;
+ rec->jr_parent = inoref->if_parent;
+ rec->jr_nlink = inoref->if_nlink;
+ rec->jr_mode = inoref->if_mode;
+ rec->jr_diroff = inoref->if_diroff;
+}
+
+static void
+jaddref_write(jaddref, jseg, data)
+ struct jaddref *jaddref;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jrefrec *rec;
+
+ rec = (struct jrefrec *)data;
+ rec->jr_op = JOP_ADDREF;
+ inoref_write(&jaddref->ja_ref, jseg, rec);
+}
+
+static void
+jremref_write(jremref, jseg, data)
+ struct jremref *jremref;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jrefrec *rec;
+
+ rec = (struct jrefrec *)data;
+ rec->jr_op = JOP_REMREF;
+ inoref_write(&jremref->jr_ref, jseg, rec);
+}
+
+static void
+jmvref_write(jmvref, jseg, data)
+ struct jmvref *jmvref;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jmvrec *rec;
+
+ rec = (struct jmvrec *)data;
+ rec->jm_op = JOP_MVREF;
+ rec->jm_ino = jmvref->jm_ino;
+ rec->jm_parent = jmvref->jm_parent;
+ rec->jm_oldoff = jmvref->jm_oldoff;
+ rec->jm_newoff = jmvref->jm_newoff;
+}
+
+static void
+jnewblk_write(jnewblk, jseg, data)
+ struct jnewblk *jnewblk;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jblkrec *rec;
+
+ jnewblk->jn_jsegdep->jd_seg = jseg;
+ rec = (struct jblkrec *)data;
+ rec->jb_op = JOP_NEWBLK;
+ rec->jb_ino = jnewblk->jn_ino;
+ rec->jb_blkno = jnewblk->jn_blkno;
+ rec->jb_lbn = jnewblk->jn_lbn;
+ rec->jb_frags = jnewblk->jn_frags;
+ rec->jb_oldfrags = jnewblk->jn_oldfrags;
+}
+
+static void
+jfreeblk_write(jfreeblk, jseg, data)
+ struct jfreeblk *jfreeblk;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jblkrec *rec;
+
+ jfreeblk->jf_jsegdep->jd_seg = jseg;
+ rec = (struct jblkrec *)data;
+ rec->jb_op = JOP_FREEBLK;
+ rec->jb_ino = jfreeblk->jf_ino;
+ rec->jb_blkno = jfreeblk->jf_blkno;
+ rec->jb_lbn = jfreeblk->jf_lbn;
+ rec->jb_frags = jfreeblk->jf_frags;
+ rec->jb_oldfrags = 0;
+}
+
+static void
+jfreefrag_write(jfreefrag, jseg, data)
+ struct jfreefrag *jfreefrag;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jblkrec *rec;
+
+ jfreefrag->fr_jsegdep->jd_seg = jseg;
+ rec = (struct jblkrec *)data;
+ rec->jb_op = JOP_FREEBLK;
+ rec->jb_ino = jfreefrag->fr_ino;
+ rec->jb_blkno = jfreefrag->fr_blkno;
+ rec->jb_lbn = jfreefrag->fr_lbn;
+ rec->jb_frags = jfreefrag->fr_frags;
+ rec->jb_oldfrags = 0;
+}
+
+static void
+jtrunc_write(jtrunc, jseg, data)
+ struct jtrunc *jtrunc;
+ struct jseg *jseg;
+ uint8_t *data;
+{
+ struct jtrncrec *rec;
+
+ rec = (struct jtrncrec *)data;
+ rec->jt_op = JOP_TRUNC;
+ rec->jt_ino = jtrunc->jt_ino;
+ rec->jt_size = jtrunc->jt_size;
+ rec->jt_extsize = jtrunc->jt_extsize;
+}
+
+/*
+ * Flush some journal records to disk.
+ */
+static void
+softdep_process_journal(mp, flags)
+ struct mount *mp;
+ int flags;
+{
+ struct jblocks *jblocks;
+ struct ufsmount *ump;
+ struct worklist *wk;
+ struct jseg *jseg;
+ struct buf *bp;
+ uint8_t *data;
+ struct fs *fs;
+ int segwritten;
+ int jrecmin; /* Minimum records per block. */
+ int jrecmax; /* Maximum records per block. */
+ int size;
+ int cnt;
+ int off;
+
+ if ((mp->mnt_kern_flag & MNTK_SUJ) == 0)
+ return;
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ jblocks = ump->softdep_jblocks;
+ /*
+ * We write anywhere between a disk block and fs block. The upper
+ * bound is picked to prevent buffer cache fragmentation and limit
+ * processing time per I/O.
+ */
+ jrecmin = (DEV_BSIZE / JREC_SIZE) - 1; /* -1 for seg header */
+ jrecmax = (fs->fs_bsize / DEV_BSIZE) * jrecmin;
+ segwritten = 0;
+ while ((cnt = ump->softdep_on_journal) != 0) {
+ /*
+ * Create a new segment to hold as many as 'cnt' journal
+ * entries and add them to the segment. Notice cnt is
+ * off by one to account for the space required by the
+ * jsegrec. If we don't have a full block to log skip it
+ * unless we haven't written anything.
+ */
+ cnt++;
+ if (cnt < jrecmax && segwritten)
+ break;
+ /*
+ * Verify some free journal space. softdep_prealloc() should
+ * guarantee that we don't run out so this is indicative of
+ * a problem with the flow control. Try to recover
+ * gracefully in any event.
+ */
+ while (jblocks->jb_free == 0) {
+ if (flags != MNT_WAIT)
+ break;
+ printf("softdep: Out of journal space!\n");
+ softdep_speedup();
+ msleep(jblocks, &lk, PRIBIO, "jblocks", 1);
+ }
+ FREE_LOCK(&lk);
+ jseg = malloc(sizeof(*jseg), M_JSEG, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jseg->js_list, D_JSEG, mp);
+ LIST_INIT(&jseg->js_entries);
+ jseg->js_state = ATTACHED;
+ jseg->js_jblocks = jblocks;
+ bp = geteblk(fs->fs_bsize, 0);
+ ACQUIRE_LOCK(&lk);
+ /*
+ * If there was a race while we were allocating the block
+ * and jseg the entry we care about was likely written.
+ * We bail out in both the WAIT and NOWAIT case and assume
+ * the caller will loop if the entry it cares about is
+ * not written.
+ */
+ if (ump->softdep_on_journal == 0 || jblocks->jb_free == 0) {
+ bp->b_flags |= B_INVAL | B_NOCACHE;
+ WORKITEM_FREE(jseg, D_JSEG);
+ FREE_LOCK(&lk);
+ brelse(bp);
+ ACQUIRE_LOCK(&lk);
+ break;
+ }
+ /*
+ * Calculate the disk block size required for the available
+ * records rounded to the min size.
+ */
+ cnt = ump->softdep_on_journal;
+ if (cnt < jrecmax)
+ size = howmany(cnt, jrecmin) * DEV_BSIZE;
+ else
+ size = fs->fs_bsize;
+ /*
+ * Allocate a disk block for this journal data and account
+ * for truncation of the requested size if enough contiguous
+ * space was not available.
+ */
+ bp->b_blkno = jblocks_alloc(jblocks, size, &size);
+ bp->b_lblkno = bp->b_blkno;
+ bp->b_offset = bp->b_blkno * DEV_BSIZE;
+ bp->b_bcount = size;
+ bp->b_bufobj = &ump->um_devvp->v_bufobj;
+ bp->b_flags &= ~B_INVAL;
+ bp->b_flags |= B_VALIDSUSPWRT | B_NOCOPY;
+ /*
+ * Initialize our jseg with cnt records. Assign the next
+ * sequence number to it and link it in-order.
+ */
+ cnt = MIN(ump->softdep_on_journal,
+ (size / DEV_BSIZE) * jrecmin);
+ jseg->js_buf = bp;
+ jseg->js_cnt = cnt;
+ jseg->js_refs = cnt + 1; /* Self ref. */
+ jseg->js_size = size;
+ jseg->js_seq = jblocks->jb_nextseq++;
+ if (TAILQ_EMPTY(&jblocks->jb_segs))
+ jblocks->jb_oldestseq = jseg->js_seq;
+ TAILQ_INSERT_TAIL(&jblocks->jb_segs, jseg, js_next);
+ if (jblocks->jb_writeseg == NULL)
+ jblocks->jb_writeseg = jseg;
+ /*
+ * Start filling in records from the pending list.
+ */
+ data = bp->b_data;
+ off = 0;
+ while ((wk = LIST_FIRST(&ump->softdep_journal_pending))
+ != NULL) {
+ /* Place a segment header on every device block. */
+ if ((off % DEV_BSIZE) == 0) {
+ jseg_write(fs, jblocks, jseg, data);
+ off += JREC_SIZE;
+ data = bp->b_data + off;
+ }
+ remove_from_journal(wk);
+ wk->wk_state |= IOSTARTED;
+ WORKLIST_INSERT(&jseg->js_entries, wk);
+ switch (wk->wk_type) {
+ case D_JADDREF:
+ jaddref_write(WK_JADDREF(wk), jseg, data);
+ break;
+ case D_JREMREF:
+ jremref_write(WK_JREMREF(wk), jseg, data);
+ break;
+ case D_JMVREF:
+ jmvref_write(WK_JMVREF(wk), jseg, data);
+ break;
+ case D_JNEWBLK:
+ jnewblk_write(WK_JNEWBLK(wk), jseg, data);
+ break;
+ case D_JFREEBLK:
+ jfreeblk_write(WK_JFREEBLK(wk), jseg, data);
+ break;
+ case D_JFREEFRAG:
+ jfreefrag_write(WK_JFREEFRAG(wk), jseg, data);
+ break;
+ case D_JTRUNC:
+ jtrunc_write(WK_JTRUNC(wk), jseg, data);
+ break;
+ default:
+ panic("process_journal: Unknown type %s",
+ TYPENAME(wk->wk_type));
+ /* NOTREACHED */
+ }
+ if (--cnt == 0)
+ break;
+ off += JREC_SIZE;
+ data = bp->b_data + off;
+ }
+ /*
+ * Write this one buffer and continue.
+ */
+ WORKLIST_INSERT(&bp->b_dep, &jseg->js_list);
+ FREE_LOCK(&lk);
+ BO_LOCK(bp->b_bufobj);
+ bgetvp(ump->um_devvp, bp);
+ BO_UNLOCK(bp->b_bufobj);
+ if (flags == MNT_NOWAIT)
+ bawrite(bp);
+ else
+ bwrite(bp);
+ ACQUIRE_LOCK(&lk);
+ }
+ /*
+ * If we've suspended the filesystem because we ran out of journal
+ * space either try to sync it here to make some progress or
+ * unsuspend it if we already have.
+ */
+ if (flags == 0 && jblocks && jblocks->jb_suspended) {
+ if (journal_space(ump, jblocks->jb_min)) {
+ FREE_LOCK(&lk);
+ jblocks->jb_suspended = 0;
+ mp->mnt_susp_owner = curthread;
+ vfs_write_resume(mp);
+ ACQUIRE_LOCK(&lk);
+ return;
+ }
+ FREE_LOCK(&lk);
+ VFS_SYNC(mp, MNT_NOWAIT);
+ ffs_sbupdate(ump, MNT_WAIT, 0);
+ ACQUIRE_LOCK(&lk);
+ }
+}
+
+/*
+ * Complete a jseg, allowing all dependencies awaiting journal writes
+ * to proceed. Each journal dependency also attaches a jsegdep to dependent
+ * structures so that the journal segment can be freed to reclaim space.
+ */
+static void
+complete_jseg(jseg)
+ struct jseg *jseg;
+{
+ struct worklist *wk;
+ struct jmvref *jmvref;
+ int waiting;
+ int i;
+
+ i = 0;
+ while ((wk = LIST_FIRST(&jseg->js_entries)) != NULL) {
+ WORKLIST_REMOVE(wk);
+ waiting = wk->wk_state & IOWAITING;
+ wk->wk_state &= ~(IOSTARTED | IOWAITING);
+ wk->wk_state |= COMPLETE;
+ KASSERT(i < jseg->js_cnt,
+ ("handle_written_jseg: overflow %d >= %d",
+ i, jseg->js_cnt));
+ switch (wk->wk_type) {
+ case D_JADDREF:
+ handle_written_jaddref(WK_JADDREF(wk));
+ break;
+ case D_JREMREF:
+ handle_written_jremref(WK_JREMREF(wk));
+ break;
+ case D_JMVREF:
+ /* No jsegdep here. */
+ free_jseg(jseg);
+ jmvref = WK_JMVREF(wk);
+ LIST_REMOVE(jmvref, jm_deps);
+ free_pagedep(jmvref->jm_pagedep);
+ WORKITEM_FREE(jmvref, D_JMVREF);
+ break;
+ case D_JNEWBLK:
+ handle_written_jnewblk(WK_JNEWBLK(wk));
+ break;
+ case D_JFREEBLK:
+ handle_written_jfreeblk(WK_JFREEBLK(wk));
+ break;
+ case D_JFREEFRAG:
+ handle_written_jfreefrag(WK_JFREEFRAG(wk));
+ break;
+ case D_JTRUNC:
+ WK_JTRUNC(wk)->jt_jsegdep->jd_seg = jseg;
+ WORKITEM_FREE(wk, D_JTRUNC);
+ break;
+ default:
+ panic("handle_written_jseg: Unknown type %s",
+ TYPENAME(wk->wk_type));
+ /* NOTREACHED */
+ }
+ if (waiting)
+ wakeup(wk);
+ }
+ /* Release the self reference so the structure may be freed. */
+ free_jseg(jseg);
+}
+
+/*
+ * Mark a jseg as DEPCOMPLETE and throw away the buffer. Handle jseg
+ * completions in order only.
+ */
+static void
+handle_written_jseg(jseg, bp)
+ struct jseg *jseg;
+ struct buf *bp;
+{
+ struct jblocks *jblocks;
+ struct jseg *jsegn;
+
+ if (jseg->js_refs == 0)
+ panic("handle_written_jseg: No self-reference on %p", jseg);
+ jseg->js_state |= DEPCOMPLETE;
+ /*
+ * We'll never need this buffer again, set flags so it will be
+ * discarded.
+ */
+ bp->b_flags |= B_INVAL | B_NOCACHE;
+ jblocks = jseg->js_jblocks;
+ /*
+ * Don't allow out of order completions. If this isn't the first
+ * block wait for it to write before we're done.
+ */
+ if (jseg != jblocks->jb_writeseg)
+ return;
+ /* Iterate through available jsegs processing their entries. */
+ do {
+ jsegn = TAILQ_NEXT(jseg, js_next);
+ complete_jseg(jseg);
+ jseg = jsegn;
+ } while (jseg && jseg->js_state & DEPCOMPLETE);
+ jblocks->jb_writeseg = jseg;
+}
+
+static inline struct jsegdep *
+inoref_jseg(inoref)
+ struct inoref *inoref;
+{
+ struct jsegdep *jsegdep;
+
+ jsegdep = inoref->if_jsegdep;
+ inoref->if_jsegdep = NULL;
+
+ return (jsegdep);
+}
+
+/*
+ * Called once a jremref has made it to stable store. The jremref is marked
+ * complete and we attempt to free it. Any pagedeps writes sleeping waiting
+ * for the jremref to complete will be awoken by free_jremref.
+ */
+static void
+handle_written_jremref(jremref)
+ struct jremref *jremref;
+{
+ struct inodedep *inodedep;
+ struct jsegdep *jsegdep;
+ struct dirrem *dirrem;
+
+ /* Grab the jsegdep. */
+ jsegdep = inoref_jseg(&jremref->jr_ref);
+ /*
+ * Remove us from the inoref list.
+ */
+ if (inodedep_lookup(jremref->jr_list.wk_mp, jremref->jr_ref.if_ino,
+ 0, &inodedep) == 0)
+ panic("handle_written_jremref: Lost inodedep");
+ TAILQ_REMOVE(&inodedep->id_inoreflst, &jremref->jr_ref, if_deps);
+ /*
+ * Complete the dirrem.
+ */
+ dirrem = jremref->jr_dirrem;
+ jremref->jr_dirrem = NULL;
+ LIST_REMOVE(jremref, jr_deps);
+ jsegdep->jd_state |= jremref->jr_state & MKDIR_PARENT;
+ WORKLIST_INSERT(&dirrem->dm_jwork, &jsegdep->jd_list);
+ if (LIST_EMPTY(&dirrem->dm_jremrefhd) &&
+ (dirrem->dm_state & COMPLETE) != 0)
+ add_to_worklist(&dirrem->dm_list, 0);
+ free_jremref(jremref);
+}
+
+/*
+ * Called once a jaddref has made it to stable store. The dependency is
+ * marked complete and any dependent structures are added to the inode
+ * bufwait list to be completed as soon as it is written. If a bitmap write
+ * depends on this entry we move the inode into the inodedephd of the
+ * bmsafemap dependency and attempt to remove the jaddref from the bmsafemap.
+ */
+static void
+handle_written_jaddref(jaddref)
+ struct jaddref *jaddref;
+{
+ struct jsegdep *jsegdep;
+ struct inodedep *inodedep;
+ struct diradd *diradd;
+ struct mkdir *mkdir;
+
+ /* Grab the jsegdep. */
+ jsegdep = inoref_jseg(&jaddref->ja_ref);
+ mkdir = NULL;
+ diradd = NULL;
+ if (inodedep_lookup(jaddref->ja_list.wk_mp, jaddref->ja_ino,
+ 0, &inodedep) == 0)
+ panic("handle_written_jaddref: Lost inodedep.");
+ if (jaddref->ja_diradd == NULL)
+ panic("handle_written_jaddref: No dependency");
+ if (jaddref->ja_diradd->da_list.wk_type == D_DIRADD) {
+ diradd = jaddref->ja_diradd;
+ WORKLIST_INSERT(&inodedep->id_bufwait, &diradd->da_list);
+ } else if (jaddref->ja_state & MKDIR_PARENT) {
+ mkdir = jaddref->ja_mkdir;
+ WORKLIST_INSERT(&inodedep->id_bufwait, &mkdir->md_list);
+ } else if (jaddref->ja_state & MKDIR_BODY)
+ mkdir = jaddref->ja_mkdir;
+ else
+ panic("handle_written_jaddref: Unknown dependency %p",
+ jaddref->ja_diradd);
+ jaddref->ja_diradd = NULL; /* also clears ja_mkdir */
+ /*
+ * Remove us from the inode list.
+ */
+ TAILQ_REMOVE(&inodedep->id_inoreflst, &jaddref->ja_ref, if_deps);
+ /*
+ * The mkdir may be waiting on the jaddref to clear before freeing.
+ */
+ if (mkdir) {
+ KASSERT(mkdir->md_list.wk_type == D_MKDIR,
+ ("handle_written_jaddref: Incorrect type for mkdir %s",
+ TYPENAME(mkdir->md_list.wk_type)));
+ mkdir->md_jaddref = NULL;
+ diradd = mkdir->md_diradd;
+ mkdir->md_state |= DEPCOMPLETE;
+ complete_mkdir(mkdir);
+ }
+ WORKLIST_INSERT(&diradd->da_jwork, &jsegdep->jd_list);
+ if (jaddref->ja_state & NEWBLOCK) {
+ inodedep->id_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&inodedep->id_bmsafemap->sm_inodedephd,
+ inodedep, id_deps);
+ }
+ free_jaddref(jaddref);
+}
+
+/*
+ * Called once a jnewblk journal is written. The allocdirect or allocindir
+ * is placed in the bmsafemap to await notification of a written bitmap.
+ */
+static void
+handle_written_jnewblk(jnewblk)
+ struct jnewblk *jnewblk;
+{
+ struct bmsafemap *bmsafemap;
+ struct jsegdep *jsegdep;
+ struct newblk *newblk;
+
+ /* Grab the jsegdep. */
+ jsegdep = jnewblk->jn_jsegdep;
+ jnewblk->jn_jsegdep = NULL;
+ /*
+ * Add the written block to the bmsafemap so it can be notified when
+ * the bitmap is on disk.
+ */
+ newblk = jnewblk->jn_newblk;
+ jnewblk->jn_newblk = NULL;
+ if (newblk == NULL)
+ panic("handle_written_jnewblk: No dependency for the segdep.");
+
+ newblk->nb_jnewblk = NULL;
+ bmsafemap = newblk->nb_bmsafemap;
+ WORKLIST_INSERT(&newblk->nb_jwork, &jsegdep->jd_list);
+ newblk->nb_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&bmsafemap->sm_newblkhd, newblk, nb_deps);
+ free_jnewblk(jnewblk);
+}
+
+/*
+ * Cancel a jfreefrag that won't be needed, probably due to colliding with
+ * an in-flight allocation that has not yet been committed. Divorce us
+ * from the freefrag and mark it DEPCOMPLETE so that it may be added
+ * to the worklist.
+ */
+static void
+cancel_jfreefrag(jfreefrag)
+ struct jfreefrag *jfreefrag;
+{
+ struct freefrag *freefrag;
+
+ if (jfreefrag->fr_jsegdep) {
+ free_jsegdep(jfreefrag->fr_jsegdep);
+ jfreefrag->fr_jsegdep = NULL;
+ }
+ freefrag = jfreefrag->fr_freefrag;
+ jfreefrag->fr_freefrag = NULL;
+ freefrag->ff_jfreefrag = NULL;
+ free_jfreefrag(jfreefrag);
+ freefrag->ff_state |= DEPCOMPLETE;
+}
+
+/*
+ * Free a jfreefrag when the parent freefrag is rendered obsolete.
+ */
+static void
+free_jfreefrag(jfreefrag)
+ struct jfreefrag *jfreefrag;
+{
+
+ if (jfreefrag->fr_state & IOSTARTED)
+ WORKLIST_REMOVE(&jfreefrag->fr_list);
+ else if (jfreefrag->fr_state & ONWORKLIST)
+ remove_from_journal(&jfreefrag->fr_list);
+ if (jfreefrag->fr_freefrag != NULL)
+ panic("free_jfreefrag: Still attached to a freefrag.");
+ WORKITEM_FREE(jfreefrag, D_JFREEFRAG);
+}
+
+/*
+ * Called when the journal write for a jfreefrag completes. The parent
+ * freefrag is added to the worklist if this completes its dependencies.
+ */
+static void
+handle_written_jfreefrag(jfreefrag)
+ struct jfreefrag *jfreefrag;
+{
+ struct jsegdep *jsegdep;
+ struct freefrag *freefrag;
+
+ /* Grab the jsegdep. */
+ jsegdep = jfreefrag->fr_jsegdep;
+ jfreefrag->fr_jsegdep = NULL;
+ freefrag = jfreefrag->fr_freefrag;
+ if (freefrag == NULL)
+ panic("handle_written_jfreefrag: No freefrag.");
+ freefrag->ff_state |= DEPCOMPLETE;
+ freefrag->ff_jfreefrag = NULL;
+ WORKLIST_INSERT(&freefrag->ff_jwork, &jsegdep->jd_list);
+ if ((freefrag->ff_state & ALLCOMPLETE) == ALLCOMPLETE)
+ add_to_worklist(&freefrag->ff_list, 0);
+ jfreefrag->fr_freefrag = NULL;
+ free_jfreefrag(jfreefrag);
+}
+
+/*
+ * Called when the journal write for a jfreeblk completes. The jfreeblk
+ * is removed from the freeblks list of pending journal writes and the
+ * jsegdep is moved to the freeblks jwork to be completed when all blocks
+ * have been reclaimed.
+ */
+static void
+handle_written_jfreeblk(jfreeblk)
+ struct jfreeblk *jfreeblk;
+{
+ struct freeblks *freeblks;
+ struct jsegdep *jsegdep;
+
+ /* Grab the jsegdep. */
+ jsegdep = jfreeblk->jf_jsegdep;
+ jfreeblk->jf_jsegdep = NULL;
+ freeblks = jfreeblk->jf_freeblks;
+ LIST_REMOVE(jfreeblk, jf_deps);
+ WORKLIST_INSERT(&freeblks->fb_jwork, &jsegdep->jd_list);
+ /*
+ * If the freeblks is all journaled, we can add it to the worklist.
+ */
+ if (LIST_EMPTY(&freeblks->fb_jfreeblkhd) &&
+ (freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE) {
+ /* Remove from the b_dep that is waiting on this write. */
+ if (freeblks->fb_state & ONWORKLIST)
+ WORKLIST_REMOVE(&freeblks->fb_list);
+ add_to_worklist(&freeblks->fb_list, 1);
+ }
+
+ free_jfreeblk(jfreeblk);
+}
+
+static struct jsegdep *
+newjsegdep(struct worklist *wk)
+{
+ struct jsegdep *jsegdep;
+
+ jsegdep = malloc(sizeof(*jsegdep), M_JSEGDEP, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jsegdep->jd_list, D_JSEGDEP, wk->wk_mp);
+ jsegdep->jd_seg = NULL;
+
+ return (jsegdep);
+}
+
+static struct jmvref *
+newjmvref(dp, ino, oldoff, newoff)
+ struct inode *dp;
+ ino_t ino;
+ off_t oldoff;
+ off_t newoff;
+{
+ struct jmvref *jmvref;
+
+ jmvref = malloc(sizeof(*jmvref), M_JMVREF, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jmvref->jm_list, D_JMVREF, UFSTOVFS(dp->i_ump));
+ jmvref->jm_list.wk_state = ATTACHED | DEPCOMPLETE;
+ jmvref->jm_parent = dp->i_number;
+ jmvref->jm_ino = ino;
+ jmvref->jm_oldoff = oldoff;
+ jmvref->jm_newoff = newoff;
+
+ return (jmvref);
+}
+
+/*
+ * Allocate a new jremref that tracks the removal of ip from dp with the
+ * directory entry offset of diroff. Mark the entry as ATTACHED and
+ * DEPCOMPLETE as we have all the information required for the journal write
+ * and the directory has already been removed from the buffer. The caller
+ * is responsible for linking the jremref into the pagedep and adding it
+ * to the journal to write. The MKDIR_PARENT flag is set if we're doing
+ * a DOTDOT addition so handle_workitem_remove() can properly assign
+ * the jsegdep when we're done.
+ */
+static struct jremref *
+newjremref(dirrem, dp, ip, diroff, nlink)
+ struct dirrem *dirrem;
+ struct inode *dp;
+ struct inode *ip;
+ off_t diroff;
+ nlink_t nlink;
+{
+ struct jremref *jremref;
+
+ jremref = malloc(sizeof(*jremref), M_JREMREF, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jremref->jr_list, D_JREMREF, UFSTOVFS(dp->i_ump));
+ jremref->jr_state = ATTACHED;
+ newinoref(&jremref->jr_ref, ip->i_number, dp->i_number, diroff,
+ nlink, ip->i_mode);
+ jremref->jr_dirrem = dirrem;
+
+ return (jremref);
+}
+
+static inline void
+newinoref(inoref, ino, parent, diroff, nlink, mode)
+ struct inoref *inoref;
+ ino_t ino;
+ ino_t parent;
+ off_t diroff;
+ nlink_t nlink;
+ uint16_t mode;
+{
+
+ inoref->if_jsegdep = newjsegdep(&inoref->if_list);
+ inoref->if_diroff = diroff;
+ inoref->if_ino = ino;
+ inoref->if_parent = parent;
+ inoref->if_nlink = nlink;
+ inoref->if_mode = mode;
+}
+
+/*
+ * Allocate a new jaddref to track the addition of ino to dp at diroff. The
+ * directory offset may not be known until later. The caller is responsible
+ * adding the entry to the journal when this information is available. nlink
+ * should be the link count prior to the addition and mode is only required
+ * to have the correct FMT.
+ */
+static struct jaddref *
+newjaddref(dp, ino, diroff, nlink, mode)
+ struct inode *dp;
+ ino_t ino;
+ off_t diroff;
+ int16_t nlink;
+ uint16_t mode;
+{
+ struct jaddref *jaddref;
+
+ jaddref = malloc(sizeof(*jaddref), M_JADDREF, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jaddref->ja_list, D_JADDREF, UFSTOVFS(dp->i_ump));
+ jaddref->ja_state = ATTACHED;
+ jaddref->ja_mkdir = NULL;
+ newinoref(&jaddref->ja_ref, ino, dp->i_number, diroff, nlink, mode);
+
+ return (jaddref);
+}
+
+/*
+ * Create a new free dependency for a freework. The caller is responsible
+ * for adjusting the reference count when it has the lock held. The freedep
+ * will track an outstanding bitmap write that will ultimately clear the
+ * freework to continue.
+ */
+static struct freedep *
+newfreedep(struct freework *freework)
+{
+ struct freedep *freedep;
+
+ freedep = malloc(sizeof(*freedep), M_FREEDEP, M_SOFTDEP_FLAGS);
+ workitem_alloc(&freedep->fd_list, D_FREEDEP, freework->fw_list.wk_mp);
+ freedep->fd_freework = freework;
+
+ return (freedep);
+}
+
+/*
+ * Free a freedep structure once the buffer it is linked to is written. If
+ * this is the last reference to the freework schedule it for completion.
+ */
+static void
+free_freedep(freedep)
+ struct freedep *freedep;
+{
+
+ if (--freedep->fd_freework->fw_ref == 0)
+ add_to_worklist(&freedep->fd_freework->fw_list, 1);
+ WORKITEM_FREE(freedep, D_FREEDEP);
+}
+
+/*
+ * Allocate a new freework structure that may be a level in an indirect
+ * when parent is not NULL or a top level block when it is. The top level
+ * freework structures are allocated without lk held and before the freeblks
+ * is visible outside of softdep_setup_freeblocks().
+ */
+static struct freework *
+newfreework(freeblks, parent, lbn, nb, frags, journal)
+ struct freeblks *freeblks;
+ struct freework *parent;
+ ufs_lbn_t lbn;
+ ufs2_daddr_t nb;
+ int frags;
+ int journal;
+{
+ struct freework *freework;
+
+ freework = malloc(sizeof(*freework), M_FREEWORK, M_SOFTDEP_FLAGS);
+ workitem_alloc(&freework->fw_list, D_FREEWORK, freeblks->fb_list.wk_mp);
+ freework->fw_freeblks = freeblks;
+ freework->fw_parent = parent;
+ freework->fw_lbn = lbn;
+ freework->fw_blkno = nb;
+ freework->fw_frags = frags;
+ freework->fw_ref = 0;
+ freework->fw_off = 0;
+ LIST_INIT(&freework->fw_jwork);
+
+ if (parent == NULL) {
+ WORKLIST_INSERT_UNLOCKED(&freeblks->fb_freeworkhd,
+ &freework->fw_list);
+ freeblks->fb_ref++;
+ }
+ if (journal)
+ newjfreeblk(freeblks, lbn, nb, frags);
+
+ return (freework);
+}
+
+/*
+ * Allocate a new jfreeblk to journal top level block pointer when truncating
+ * a file. The caller must add this to the worklist when lk is held.
+ */
+static struct jfreeblk *
+newjfreeblk(freeblks, lbn, blkno, frags)
+ struct freeblks *freeblks;
+ ufs_lbn_t lbn;
+ ufs2_daddr_t blkno;
+ int frags;
+{
+ struct jfreeblk *jfreeblk;
+
+ jfreeblk = malloc(sizeof(*jfreeblk), M_JFREEBLK, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jfreeblk->jf_list, D_JFREEBLK, freeblks->fb_list.wk_mp);
+ jfreeblk->jf_jsegdep = newjsegdep(&jfreeblk->jf_list);
+ jfreeblk->jf_state = ATTACHED | DEPCOMPLETE;
+ jfreeblk->jf_ino = freeblks->fb_previousinum;
+ jfreeblk->jf_lbn = lbn;
+ jfreeblk->jf_blkno = blkno;
+ jfreeblk->jf_frags = frags;
+ jfreeblk->jf_freeblks = freeblks;
+ LIST_INSERT_HEAD(&freeblks->fb_jfreeblkhd, jfreeblk, jf_deps);
+
+ return (jfreeblk);
+}
+
+static void move_newblock_dep(struct jaddref *, struct inodedep *);
+/*
+ * If we're canceling a new bitmap we have to search for another ref
+ * to move into the bmsafemap dep. This might be better expressed
+ * with another structure.
+ */
+static void
+move_newblock_dep(jaddref, inodedep)
+ struct jaddref *jaddref;
+ struct inodedep *inodedep;
+{
+ struct inoref *inoref;
+ struct jaddref *jaddrefn;
+
+ jaddrefn = NULL;
+ for (inoref = TAILQ_NEXT(&jaddref->ja_ref, if_deps); inoref;
+ inoref = TAILQ_NEXT(inoref, if_deps)) {
+ if ((jaddref->ja_state & NEWBLOCK) &&
+ inoref->if_list.wk_type == D_JADDREF) {
+ jaddrefn = (struct jaddref *)inoref;
+ break;
+ }
+ }
+ if (jaddrefn == NULL)
+ return;
+ jaddrefn->ja_state &= ~(ATTACHED | UNDONE);
+ jaddrefn->ja_state |= jaddref->ja_state &
+ (ATTACHED | UNDONE | NEWBLOCK);
+ jaddref->ja_state &= ~(ATTACHED | UNDONE | NEWBLOCK);
+ jaddref->ja_state |= ATTACHED;
+ LIST_REMOVE(jaddref, ja_bmdeps);
+ LIST_INSERT_HEAD(&inodedep->id_bmsafemap->sm_jaddrefhd, jaddrefn,
+ ja_bmdeps);
+}
+
+/*
+ * Cancel a jaddref either before it has been written or while it is being
+ * written. This happens when a link is removed before the add reaches
+ * the disk. The jaddref dependency is kept linked into the bmsafemap
+ * and inode to prevent the link count or bitmap from reaching the disk
+ * until handle_workitem_remove() re-adjusts the counts and bitmaps as
+ * required.
+ *
+ * Returns 1 if the canceled addref requires journaling of the remove and
+ * 0 otherwise.
+ */
+static int
+cancel_jaddref(jaddref, inodedep, wkhd)
+ struct jaddref *jaddref;
+ struct inodedep *inodedep;
+ struct workhead *wkhd;
+{
+ struct inoref *inoref;
+ struct jsegdep *jsegdep;
+ int needsj;
+
+ KASSERT((jaddref->ja_state & COMPLETE) == 0,
+ ("cancel_jaddref: Canceling complete jaddref"));
+ if (jaddref->ja_state & (IOSTARTED | COMPLETE))
+ needsj = 1;
+ else
+ needsj = 0;
+ if (inodedep == NULL)
+ if (inodedep_lookup(jaddref->ja_list.wk_mp, jaddref->ja_ino,
+ 0, &inodedep) == 0)
+ panic("cancel_jaddref: Lost inodedep");
+ /*
+ * We must adjust the nlink of any reference operation that follows
+ * us so that it is consistent with the in-memory reference. This
+ * ensures that inode nlink rollbacks always have the correct link.
+ */
+ if (needsj == 0)
+ for (inoref = TAILQ_NEXT(&jaddref->ja_ref, if_deps); inoref;
+ inoref = TAILQ_NEXT(inoref, if_deps))
+ inoref->if_nlink--;
+ jsegdep = inoref_jseg(&jaddref->ja_ref);
+ if (jaddref->ja_state & NEWBLOCK)
+ move_newblock_dep(jaddref, inodedep);
+ if (jaddref->ja_state & IOWAITING) {
+ jaddref->ja_state &= ~IOWAITING;
+ wakeup(&jaddref->ja_list);
+ }
+ jaddref->ja_mkdir = NULL;
+ if (jaddref->ja_state & IOSTARTED) {
+ jaddref->ja_state &= ~IOSTARTED;
+ WORKLIST_REMOVE(&jaddref->ja_list);
+ WORKLIST_INSERT(wkhd, &jsegdep->jd_list);
+ } else {
+ free_jsegdep(jsegdep);
+ remove_from_journal(&jaddref->ja_list);
+ }
+ /*
+ * Leave NEWBLOCK jaddrefs on the inodedep so handle_workitem_remove
+ * can arrange for them to be freed with the bitmap. Otherwise we
+ * no longer need this addref attached to the inoreflst and it
+ * will incorrectly adjust nlink if we leave it.
+ */
+ if ((jaddref->ja_state & NEWBLOCK) == 0) {
+ TAILQ_REMOVE(&inodedep->id_inoreflst, &jaddref->ja_ref,
+ if_deps);
+ jaddref->ja_state |= COMPLETE;
+ free_jaddref(jaddref);
+ return (needsj);
+ }
+ jaddref->ja_state |= GOINGAWAY;
+ /*
+ * Leave the head of the list for jsegdeps for fast merging.
+ */
+ if (LIST_FIRST(wkhd) != NULL) {
+ jaddref->ja_state |= ONWORKLIST;
+ LIST_INSERT_AFTER(LIST_FIRST(wkhd), &jaddref->ja_list, wk_list);
+ } else
+ WORKLIST_INSERT(wkhd, &jaddref->ja_list);
+
+ return (needsj);
+}
+
+/*
+ * Attempt to free a jaddref structure when some work completes. This
+ * should only succeed once the entry is written and all dependencies have
+ * been notified.
+ */
+static void
+free_jaddref(jaddref)
+ struct jaddref *jaddref;
+{
+
+ if ((jaddref->ja_state & ALLCOMPLETE) != ALLCOMPLETE)
+ return;
+ if (jaddref->ja_ref.if_jsegdep)
+ panic("free_jaddref: segdep attached to jaddref %p(0x%X)\n",
+ jaddref, jaddref->ja_state);
+ if (jaddref->ja_state & NEWBLOCK)
+ LIST_REMOVE(jaddref, ja_bmdeps);
+ if (jaddref->ja_state & (IOSTARTED | ONWORKLIST))
+ panic("free_jaddref: Bad state %p(0x%X)",
+ jaddref, jaddref->ja_state);
+ if (jaddref->ja_mkdir != NULL)
+ panic("free_jaddref: Work pending, 0x%X\n", jaddref->ja_state);
+ WORKITEM_FREE(jaddref, D_JADDREF);
+}
+
+/*
+ * Free a jremref structure once it has been written or discarded.
+ */
+static void
+free_jremref(jremref)
+ struct jremref *jremref;
+{
+
+ if (jremref->jr_ref.if_jsegdep)
+ free_jsegdep(jremref->jr_ref.if_jsegdep);
+ if (jremref->jr_state & IOSTARTED)
+ panic("free_jremref: IO still pending");
+ WORKITEM_FREE(jremref, D_JREMREF);
+}
+
+/*
+ * Free a jnewblk structure.
+ */
+static void
+free_jnewblk(jnewblk)
+ struct jnewblk *jnewblk;
+{
+
+ if ((jnewblk->jn_state & ALLCOMPLETE) != ALLCOMPLETE)
+ return;
+ LIST_REMOVE(jnewblk, jn_deps);
+ if (jnewblk->jn_newblk != NULL)
+ panic("free_jnewblk: Dependency still attached.");
+ WORKITEM_FREE(jnewblk, D_JNEWBLK);
+}
+
+/*
+ * Cancel a jnewblk which has been superseded by a freeblk. The jnewblk
+ * is kept linked into the bmsafemap until the free completes, thus
+ * preventing the modified state from ever reaching disk. The free
+ * routine must pass this structure via ffs_blkfree() to
+ * softdep_setup_freeblks() so there is no race in releasing the space.
+ */
+static void
+cancel_jnewblk(jnewblk, wkhd)
+ struct jnewblk *jnewblk;
+ struct workhead *wkhd;
+{
+ struct jsegdep *jsegdep;
+
+ jsegdep = jnewblk->jn_jsegdep;
+ jnewblk->jn_jsegdep = NULL;
+ free_jsegdep(jsegdep);
+ jnewblk->jn_newblk = NULL;
+ jnewblk->jn_state |= GOINGAWAY;
+ if (jnewblk->jn_state & IOSTARTED) {
+ jnewblk->jn_state &= ~IOSTARTED;
+ WORKLIST_REMOVE(&jnewblk->jn_list);
+ } else
+ remove_from_journal(&jnewblk->jn_list);
+ /*
+ * Leave the head of the list for jsegdeps for fast merging.
+ */
+ if (LIST_FIRST(wkhd) != NULL) {
+ jnewblk->jn_state |= ONWORKLIST;
+ LIST_INSERT_AFTER(LIST_FIRST(wkhd), &jnewblk->jn_list, wk_list);
+ } else
+ WORKLIST_INSERT(wkhd, &jnewblk->jn_list);
+ if (jnewblk->jn_state & IOWAITING) {
+ jnewblk->jn_state &= ~IOWAITING;
+ wakeup(&jnewblk->jn_list);
+ }
+}
+
+static void
+free_jfreeblk(jfreeblk)
+ struct jfreeblk *jfreeblk;
+{
+
+ WORKITEM_FREE(jfreeblk, D_JFREEBLK);
+}
+
+/*
+ * Release one reference to a jseg and free it if the count reaches 0. This
+ * should eventually reclaim journal space as well.
+ */
+static void
+free_jseg(jseg)
+ struct jseg *jseg;
+{
+ struct jblocks *jblocks;
+
+ KASSERT(jseg->js_refs > 0,
+ ("free_jseg: Invalid refcnt %d", jseg->js_refs));
+ if (--jseg->js_refs != 0)
+ return;
+ /*
+ * Free only those jsegs which have none allocated before them to
+ * preserve the journal space ordering.
+ */
+ jblocks = jseg->js_jblocks;
+ while ((jseg = TAILQ_FIRST(&jblocks->jb_segs)) != NULL) {
+ jblocks->jb_oldestseq = jseg->js_seq;
+ if (jseg->js_refs != 0)
+ break;
+ TAILQ_REMOVE(&jblocks->jb_segs, jseg, js_next);
+ jblocks_free(jblocks, jseg->js_list.wk_mp, jseg->js_size);
+ KASSERT(LIST_EMPTY(&jseg->js_entries),
+ ("free_jseg: Freed jseg has valid entries."));
+ WORKITEM_FREE(jseg, D_JSEG);
+ }
+}
+
+/*
+ * Release a jsegdep and decrement the jseg count.
+ */
+static void
+free_jsegdep(jsegdep)
+ struct jsegdep *jsegdep;
+{
+
+ if (jsegdep->jd_seg)
+ free_jseg(jsegdep->jd_seg);
+ WORKITEM_FREE(jsegdep, D_JSEGDEP);
+}
+
+/*
+ * Wait for a journal item to make it to disk. Initiate journal processing
+ * if required.
+ */
+static void
+jwait(wk)
+ struct worklist *wk;
+{
+
+ stat_journal_wait++;
+ /*
+ * If IO has not started we process the journal. We can't mark the
+ * worklist item as IOWAITING because we drop the lock while
+ * processing the journal and the worklist entry may be freed after
+ * this point. The caller may call back in and re-issue the request.
+ */
+ if ((wk->wk_state & IOSTARTED) == 0) {
+ softdep_process_journal(wk->wk_mp, MNT_WAIT);
+ return;
+ }
+ wk->wk_state |= IOWAITING;
+ msleep(wk, &lk, PRIBIO, "jwait", 0);
+}
+
+/*
+ * Lookup an inodedep based on an inode pointer and set the nlinkdelta as
+ * appropriate. This is a convenience function to reduce duplicate code
+ * for the setup and revert functions below.
+ */
+static struct inodedep *
+inodedep_lookup_ip(ip)
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+
+ KASSERT(ip->i_nlink >= ip->i_effnlink,
+ ("inodedep_lookup_ip: bad delta"));
+ (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number,
+ DEPALLOC, &inodedep);
+ inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
+
+ return (inodedep);
+}
+
+/*
+ * Create a journal entry that describes a truncate that we're about to
+ * perform. The inode allocations and frees between here and the completion
+ * of the operation are done asynchronously and without journaling. At
+ * the end of the operation the vnode is sync'd and the journal space
+ * is released. Recovery will discover the partially completed truncate
+ * and complete it.
+ */
+void *
+softdep_setup_trunc(vp, length, flags)
+ struct vnode *vp;
+ off_t length;
+ int flags;
+{
+ struct jsegdep *jsegdep;
+ struct jtrunc *jtrunc;
+ struct ufsmount *ump;
+ struct inode *ip;
+
+ softdep_prealloc(vp, MNT_WAIT);
+ ip = VTOI(vp);
+ ump = VFSTOUFS(vp->v_mount);
+ jtrunc = malloc(sizeof(*jtrunc), M_JTRUNC, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jtrunc->jt_list, D_JTRUNC, vp->v_mount);
+ jsegdep = jtrunc->jt_jsegdep = newjsegdep(&jtrunc->jt_list);
+ jtrunc->jt_ino = ip->i_number;
+ jtrunc->jt_extsize = 0;
+ jtrunc->jt_size = length;
+ if ((flags & IO_EXT) == 0 && ump->um_fstype == UFS2)
+ jtrunc->jt_extsize = ip->i_din2->di_extsize;
+ if ((flags & IO_NORMAL) == 0)
+ jtrunc->jt_size = DIP(ip, i_size);
+ ACQUIRE_LOCK(&lk);
+ add_to_journal(&jtrunc->jt_list);
+ while (jsegdep->jd_seg == NULL) {
+ stat_jwait_freeblks++;
+ jwait(&jtrunc->jt_list);
+ }
+ FREE_LOCK(&lk);
+
+ return (jsegdep);
+}
+
+/*
+ * After synchronous truncation is complete we free sync the vnode and
+ * release the jsegdep so the journal space can be freed.
+ */
+int
+softdep_complete_trunc(vp, cookie)
+ struct vnode *vp;
+ void *cookie;
+{
+ int error;
+
+ error = ffs_syncvnode(vp, MNT_WAIT);
+ ACQUIRE_LOCK(&lk);
+ free_jsegdep((struct jsegdep *)cookie);
+ FREE_LOCK(&lk);
+
+ return (error);
+}
+
+/*
+ * Called prior to creating a new inode and linking it to a directory. The
+ * jaddref structure must already be allocated by softdep_setup_inomapdep
+ * and it is discovered here so we can initialize the mode and update
+ * nlinkdelta.
+ */
+void
+softdep_setup_create(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ KASSERT(ip->i_nlink == 1,
+ ("softdep_setup_create: Invalid link count."));
+ dvp = ITOV(dp);
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(ip);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref != NULL && jaddref->ja_parent == dp->i_number,
+ ("softdep_setup_create: No addref structure present."));
+ jaddref->ja_mode = ip->i_mode;
+ }
+ softdep_prelink(dvp, NULL);
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Create a jaddref structure to track the addition of a DOTDOT link when
+ * we are reparenting an inode as part of a rename. This jaddref will be
+ * found by softdep_setup_directory_change. Adjusts nlinkdelta for
+ * non-journaling softdep.
+ */
+void
+softdep_setup_dotdot_link(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+ struct vnode *vp;
+
+ dvp = ITOV(dp);
+ vp = ITOV(ip);
+ jaddref = NULL;
+ /*
+ * We don't set MKDIR_PARENT as this is not tied to a mkdir and
+ * is used as a normal link would be.
+ */
+ if (DOINGSUJ(dvp))
+ jaddref = newjaddref(ip, dp->i_number, DOTDOT_OFFSET,
+ dp->i_effnlink - 1, dp->i_mode);
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(dp);
+ if (jaddref)
+ TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
+ if_deps);
+ softdep_prelink(dvp, ITOV(ip));
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Create a jaddref structure to track a new link to an inode. The directory
+ * offset is not known until softdep_setup_directory_add or
+ * softdep_setup_directory_change. Adjusts nlinkdelta for non-journaling
+ * softdep.
+ */
+void
+softdep_setup_link(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ jaddref = NULL;
+ if (DOINGSUJ(dvp))
+ jaddref = newjaddref(dp, ip->i_number, 0, ip->i_effnlink - 1,
+ ip->i_mode);
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(ip);
+ if (jaddref)
+ TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
+ if_deps);
+ softdep_prelink(dvp, ITOV(ip));
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to create the jaddref structures to track . and .. references as
+ * well as lookup and further initialize the incomplete jaddref created
+ * by softdep_setup_inomapdep when the inode was allocated. Adjusts
+ * nlinkdelta for non-journaling softdep.
+ */
+void
+softdep_setup_mkdir(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *dotdotaddref;
+ struct jaddref *dotaddref;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ dotaddref = dotdotaddref = NULL;
+ if (DOINGSUJ(dvp)) {
+ dotaddref = newjaddref(ip, ip->i_number, DOT_OFFSET, 1,
+ ip->i_mode);
+ dotaddref->ja_state |= MKDIR_BODY;
+ dotdotaddref = newjaddref(ip, dp->i_number, DOTDOT_OFFSET,
+ dp->i_effnlink - 1, dp->i_mode);
+ dotdotaddref->ja_state |= MKDIR_PARENT;
+ }
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(ip);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref != NULL,
+ ("softdep_setup_mkdir: No addref structure present."));
+ KASSERT(jaddref->ja_parent == dp->i_number,
+ ("softdep_setup_mkdir: bad parent %d",
+ jaddref->ja_parent));
+ jaddref->ja_mode = ip->i_mode;
+ TAILQ_INSERT_BEFORE(&jaddref->ja_ref, &dotaddref->ja_ref,
+ if_deps);
+ }
+ inodedep = inodedep_lookup_ip(dp);
+ if (DOINGSUJ(dvp))
+ TAILQ_INSERT_TAIL(&inodedep->id_inoreflst,
+ &dotdotaddref->ja_ref, if_deps);
+ softdep_prelink(ITOV(dp), NULL);
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to track nlinkdelta of the inode and parent directories prior to
+ * unlinking a directory.
+ */
+void
+softdep_setup_rmdir(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ ACQUIRE_LOCK(&lk);
+ (void) inodedep_lookup_ip(ip);
+ (void) inodedep_lookup_ip(dp);
+ softdep_prelink(dvp, ITOV(ip));
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to track nlinkdelta of the inode and parent directories prior to
+ * unlink.
+ */
+void
+softdep_setup_unlink(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ ACQUIRE_LOCK(&lk);
+ (void) inodedep_lookup_ip(ip);
+ (void) inodedep_lookup_ip(dp);
+ softdep_prelink(dvp, ITOV(ip));
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to release the journal structures created by a failed non-directory
+ * creation. Adjusts nlinkdelta for non-journaling softdep.
+ */
+void
+softdep_revert_create(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(ip);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref->ja_parent == dp->i_number,
+ ("softdep_revert_create: addref parent mismatch"));
+ cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
+ }
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to release the journal structures created by a failed dotdot link
+ * creation. Adjusts nlinkdelta for non-journaling softdep.
+ */
+void
+softdep_revert_dotdot_link(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(dp);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref->ja_parent == ip->i_number,
+ ("softdep_revert_dotdot_link: addref parent mismatch"));
+ cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
+ }
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to release the journal structures created by a failed link
+ * addition. Adjusts nlinkdelta for non-journaling softdep.
+ */
+void
+softdep_revert_link(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(ip);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref->ja_parent == dp->i_number,
+ ("softdep_revert_link: addref parent mismatch"));
+ cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
+ }
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to release the journal structures created by a failed mkdir
+ * attempt. Adjusts nlinkdelta for non-journaling softdep.
+ */
+void
+softdep_revert_mkdir(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct vnode *dvp;
+
+ dvp = ITOV(dp);
+
+ ACQUIRE_LOCK(&lk);
+ inodedep = inodedep_lookup_ip(dp);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref->ja_parent == ip->i_number,
+ ("softdep_revert_mkdir: dotdot addref parent mismatch"));
+ cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
+ }
+ inodedep = inodedep_lookup_ip(ip);
+ if (DOINGSUJ(dvp)) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref->ja_parent == dp->i_number,
+ ("softdep_revert_mkdir: addref parent mismatch"));
+ cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref->ja_parent == ip->i_number,
+ ("softdep_revert_mkdir: dot addref parent mismatch"));
+ cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
+ }
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Called to correct nlinkdelta after a failed rmdir.
+ */
+void
+softdep_revert_rmdir(dp, ip)
+ struct inode *dp;
+ struct inode *ip;
+{
+
+ ACQUIRE_LOCK(&lk);
+ (void) inodedep_lookup_ip(ip);
+ (void) inodedep_lookup_ip(dp);
+ FREE_LOCK(&lk);
+}
+
/*
* Protecting the freemaps (or bitmaps).
*
@@ -1536,6 +3971,22 @@ softdep_setup_inomapdep(bp, ip, newinum)
{
struct inodedep *inodedep;
struct bmsafemap *bmsafemap;
+ struct jaddref *jaddref;
+ struct mount *mp;
+ struct fs *fs;
+
+ mp = UFSTOVFS(ip->i_ump);
+ fs = ip->i_ump->um_fs;
+ jaddref = NULL;
+
+ /*
+ * Allocate the journal reference add structure so that the bitmap
+ * can be dependent on it.
+ */
+ if (mp->mnt_kern_flag & MNTK_SUJ) {
+ jaddref = newjaddref(ip, newinum, 0, 0, 0);
+ jaddref->ja_state |= NEWBLOCK;
+ }
/*
* Create a dependency for the newly allocated inode.
@@ -1544,14 +3995,20 @@ softdep_setup_inomapdep(bp, ip, newinum)
* the cylinder group map from which it was allocated.
*/
ACQUIRE_LOCK(&lk);
- if ((inodedep_lookup(UFSTOVFS(ip->i_ump), newinum, DEPALLOC|NODELAY,
- &inodedep)))
- panic("softdep_setup_inomapdep: dependency for new inode "
- "already exists");
- inodedep->id_buf = bp;
+ if ((inodedep_lookup(mp, newinum, DEPALLOC|NODELAY, &inodedep)))
+ panic("softdep_setup_inomapdep: dependency %p for new"
+ "inode already exists", inodedep);
+ bmsafemap = bmsafemap_lookup(mp, bp, ino_to_cg(fs, newinum));
+ if (jaddref) {
+ LIST_INSERT_HEAD(&bmsafemap->sm_jaddrefhd, jaddref, ja_bmdeps);
+ TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
+ if_deps);
+ } else {
+ inodedep->id_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps);
+ }
+ inodedep->id_bmsafemap = bmsafemap;
inodedep->id_state &= ~DEPCOMPLETE;
- bmsafemap = bmsafemap_lookup(inodedep->id_list.wk_mp, bp);
- LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps);
FREE_LOCK(&lk);
}
@@ -1560,29 +4017,98 @@ softdep_setup_inomapdep(bp, ip, newinum)
* allocate block or fragment.
*/
void
-softdep_setup_blkmapdep(bp, mp, newblkno)
+softdep_setup_blkmapdep(bp, mp, newblkno, frags, oldfrags)
struct buf *bp; /* buffer for cylgroup block with block map */
struct mount *mp; /* filesystem doing allocation */
ufs2_daddr_t newblkno; /* number of newly allocated block */
+ int frags; /* Number of fragments. */
+ int oldfrags; /* Previous number of fragments for extend. */
{
struct newblk *newblk;
struct bmsafemap *bmsafemap;
+ struct jnewblk *jnewblk;
struct fs *fs;
fs = VFSTOUFS(mp)->um_fs;
+ jnewblk = NULL;
/*
* Create a dependency for the newly allocated block.
* Add it to the dependency list for the buffer holding
* the cylinder group map from which it was allocated.
*/
+ if (mp->mnt_kern_flag & MNTK_SUJ) {
+ jnewblk = malloc(sizeof(*jnewblk), M_JNEWBLK, M_SOFTDEP_FLAGS);
+ workitem_alloc(&jnewblk->jn_list, D_JNEWBLK, mp);
+ jnewblk->jn_jsegdep = newjsegdep(&jnewblk->jn_list);
+ jnewblk->jn_state = ATTACHED;
+ jnewblk->jn_blkno = newblkno;
+ jnewblk->jn_frags = frags;
+ jnewblk->jn_oldfrags = oldfrags;
+#ifdef SUJ_DEBUG
+ {
+ struct cg *cgp;
+ uint8_t *blksfree;
+ long bno;
+ int i;
+
+ cgp = (struct cg *)bp->b_data;
+ blksfree = cg_blksfree(cgp);
+ bno = dtogd(fs, jnewblk->jn_blkno);
+ for (i = jnewblk->jn_oldfrags; i < jnewblk->jn_frags;
+ i++) {
+ if (isset(blksfree, bno + i))
+ panic("softdep_setup_blkmapdep: "
+ "free fragment %d from %d-%d "
+ "state 0x%X dep %p", i,
+ jnewblk->jn_oldfrags,
+ jnewblk->jn_frags,
+ jnewblk->jn_state,
+ jnewblk->jn_newblk);
+ }
+ }
+#endif
+ }
ACQUIRE_LOCK(&lk);
- if (newblk_lookup(fs, newblkno, DEPALLOC, &newblk) != 0)
+ if (newblk_lookup(mp, newblkno, DEPALLOC, &newblk) != 0)
panic("softdep_setup_blkmapdep: found block");
- newblk->nb_bmsafemap = bmsafemap = bmsafemap_lookup(mp, bp);
- LIST_INSERT_HEAD(&bmsafemap->sm_newblkhd, newblk, nb_deps);
+ newblk->nb_bmsafemap = bmsafemap = bmsafemap_lookup(mp, bp,
+ dtog(fs, newblkno));
+ if (jnewblk) {
+ jnewblk->jn_newblk = newblk;
+ LIST_INSERT_HEAD(&bmsafemap->sm_jnewblkhd, jnewblk, jn_deps);
+ } else {
+ newblk->nb_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&bmsafemap->sm_newblkhd, newblk, nb_deps);
+ }
+ newblk->nb_bmsafemap = bmsafemap;
+ newblk->nb_jnewblk = jnewblk;
FREE_LOCK(&lk);
}
+#define BMSAFEMAP_HASH(fs, cg) \
+ (&bmsafemap_hashtbl[((((register_t)(fs)) >> 13) + (cg)) & bmsafemap_hash])
+
+static int
+bmsafemap_find(bmsafemaphd, mp, cg, bmsafemapp)
+ struct bmsafemap_hashhead *bmsafemaphd;
+ struct mount *mp;
+ int cg;
+ struct bmsafemap **bmsafemapp;
+{
+ struct bmsafemap *bmsafemap;
+
+ LIST_FOREACH(bmsafemap, bmsafemaphd, sm_hash)
+ if (bmsafemap->sm_list.wk_mp == mp && bmsafemap->sm_cg == cg)
+ break;
+ if (bmsafemap) {
+ *bmsafemapp = bmsafemap;
+ return (1);
+ }
+ *bmsafemapp = NULL;
+
+ return (0);
+}
+
/*
* Find the bmsafemap associated with a cylinder group buffer.
* If none exists, create one. The buffer must be locked when
@@ -1590,27 +4116,43 @@ softdep_setup_blkmapdep(bp, mp, newblkno)
* splbio interrupts blocked.
*/
static struct bmsafemap *
-bmsafemap_lookup(mp, bp)
+bmsafemap_lookup(mp, bp, cg)
struct mount *mp;
struct buf *bp;
+ int cg;
{
- struct bmsafemap *bmsafemap;
+ struct bmsafemap_hashhead *bmsafemaphd;
+ struct bmsafemap *bmsafemap, *collision;
struct worklist *wk;
+ struct fs *fs;
mtx_assert(&lk, MA_OWNED);
- LIST_FOREACH(wk, &bp->b_dep, wk_list)
- if (wk->wk_type == D_BMSAFEMAP)
- return (WK_BMSAFEMAP(wk));
+ if (bp)
+ LIST_FOREACH(wk, &bp->b_dep, wk_list)
+ if (wk->wk_type == D_BMSAFEMAP)
+ return (WK_BMSAFEMAP(wk));
+ fs = VFSTOUFS(mp)->um_fs;
+ bmsafemaphd = BMSAFEMAP_HASH(fs, cg);
+ if (bmsafemap_find(bmsafemaphd, mp, cg, &bmsafemap) == 1)
+ return (bmsafemap);
FREE_LOCK(&lk);
bmsafemap = malloc(sizeof(struct bmsafemap),
M_BMSAFEMAP, M_SOFTDEP_FLAGS);
workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
bmsafemap->sm_buf = bp;
- LIST_INIT(&bmsafemap->sm_allocdirecthd);
- LIST_INIT(&bmsafemap->sm_allocindirhd);
LIST_INIT(&bmsafemap->sm_inodedephd);
+ LIST_INIT(&bmsafemap->sm_inodedepwr);
LIST_INIT(&bmsafemap->sm_newblkhd);
+ LIST_INIT(&bmsafemap->sm_newblkwr);
+ LIST_INIT(&bmsafemap->sm_jaddrefhd);
+ LIST_INIT(&bmsafemap->sm_jnewblkhd);
ACQUIRE_LOCK(&lk);
+ if (bmsafemap_find(bmsafemaphd, mp, cg, &collision) == 1) {
+ WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
+ return (collision);
+ }
+ bmsafemap->sm_cg = cg;
+ LIST_INSERT_HEAD(bmsafemaphd, bmsafemap, sm_hash);
WORKLIST_INSERT(&bp->b_dep, &bmsafemap->sm_list);
return (bmsafemap);
}
@@ -1645,9 +4187,9 @@ bmsafemap_lookup(mp, bp)
* unreferenced fragments.
*/
void
-softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
+softdep_setup_allocdirect(ip, off, newblkno, oldblkno, newsize, oldsize, bp)
struct inode *ip; /* inode to which block is being added */
- ufs_lbn_t lbn; /* block pointer within inode */
+ ufs_lbn_t off; /* block pointer within inode */
ufs2_daddr_t newblkno; /* disk block number being added */
ufs2_daddr_t oldblkno; /* previous block number, 0 unless frag */
long newsize; /* size of new block */
@@ -1656,34 +4198,33 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
{
struct allocdirect *adp, *oldadp;
struct allocdirectlst *adphead;
- struct bmsafemap *bmsafemap;
+ struct freefrag *freefrag;
struct inodedep *inodedep;
struct pagedep *pagedep;
+ struct jnewblk *jnewblk;
struct newblk *newblk;
struct mount *mp;
+ ufs_lbn_t lbn;
+ lbn = bp->b_lblkno;
mp = UFSTOVFS(ip->i_ump);
- adp = malloc(sizeof(struct allocdirect),
- M_ALLOCDIRECT, M_SOFTDEP_FLAGS|M_ZERO);
- workitem_alloc(&adp->ad_list, D_ALLOCDIRECT, mp);
- adp->ad_lbn = lbn;
- adp->ad_newblkno = newblkno;
- adp->ad_oldblkno = oldblkno;
- adp->ad_newsize = newsize;
- adp->ad_oldsize = oldsize;
- adp->ad_state = ATTACHED;
- LIST_INIT(&adp->ad_newdirblk);
- if (newblkno == oldblkno)
- adp->ad_freefrag = NULL;
+ if (oldblkno && oldblkno != newblkno)
+ freefrag = newfreefrag(ip, oldblkno, oldsize, lbn);
else
- adp->ad_freefrag = newfreefrag(ip, oldblkno, oldsize);
+ freefrag = NULL;
ACQUIRE_LOCK(&lk);
- if (lbn >= NDADDR) {
+ if (off >= NDADDR) {
+ if (lbn > 0)
+ panic("softdep_setup_allocdirect: bad lbn %jd, off %jd",
+ lbn, off);
/* allocating an indirect block */
if (oldblkno != 0)
panic("softdep_setup_allocdirect: non-zero indir");
} else {
+ if (off != lbn)
+ panic("softdep_setup_allocdirect: lbn %jd != off %jd",
+ lbn, off);
/*
* Allocating a direct block.
*
@@ -1692,26 +4233,39 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
* deletions.
*/
if ((ip->i_mode & IFMT) == IFDIR &&
- pagedep_lookup(ip, lbn, DEPALLOC, &pagedep) == 0)
+ pagedep_lookup(mp, ip->i_number, off, DEPALLOC,
+ &pagedep) == 0)
WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
}
- if (newblk_lookup(ip->i_fs, newblkno, 0, &newblk) == 0)
+ if (newblk_lookup(mp, newblkno, 0, &newblk) == 0)
panic("softdep_setup_allocdirect: lost block");
- if (newblk->nb_state == DEPCOMPLETE) {
- adp->ad_state |= DEPCOMPLETE;
- adp->ad_buf = NULL;
- } else {
- bmsafemap = newblk->nb_bmsafemap;
- adp->ad_buf = bmsafemap->sm_buf;
- LIST_REMOVE(newblk, nb_deps);
- LIST_INSERT_HEAD(&bmsafemap->sm_allocdirecthd, adp, ad_deps);
- }
- LIST_REMOVE(newblk, nb_hash);
- free(newblk, M_NEWBLK);
+ KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
+ ("softdep_setup_allocdirect: newblk already initialized"));
+ /*
+ * Convert the newblk to an allocdirect.
+ */
+ newblk->nb_list.wk_type = D_ALLOCDIRECT;
+ adp = (struct allocdirect *)newblk;
+ newblk->nb_freefrag = freefrag;
+ adp->ad_offset = off;
+ adp->ad_oldblkno = oldblkno;
+ adp->ad_newsize = newsize;
+ adp->ad_oldsize = oldsize;
+ /*
+ * Finish initializing the journal.
+ */
+ if ((jnewblk = newblk->nb_jnewblk) != NULL) {
+ jnewblk->jn_ino = ip->i_number;
+ jnewblk->jn_lbn = lbn;
+ add_to_journal(&jnewblk->jn_list);
+ }
+ if (freefrag && freefrag->ff_jfreefrag != NULL)
+ add_to_journal(&freefrag->ff_jfreefrag->fr_list);
inodedep_lookup(mp, ip->i_number, DEPALLOC | NODELAY, &inodedep);
adp->ad_inodedep = inodedep;
- WORKLIST_INSERT(&bp->b_dep, &adp->ad_list);
+
+ WORKLIST_INSERT(&bp->b_dep, &newblk->nb_list);
/*
* The list of allocdirects must be kept in sorted and ascending
* order so that the rollback routines can quickly determine the
@@ -1726,24 +4280,25 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
*/
adphead = &inodedep->id_newinoupdt;
oldadp = TAILQ_LAST(adphead, allocdirectlst);
- if (oldadp == NULL || oldadp->ad_lbn <= lbn) {
+ if (oldadp == NULL || oldadp->ad_offset <= off) {
/* insert at end of list */
TAILQ_INSERT_TAIL(adphead, adp, ad_next);
- if (oldadp != NULL && oldadp->ad_lbn == lbn)
+ if (oldadp != NULL && oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
FREE_LOCK(&lk);
return;
}
TAILQ_FOREACH(oldadp, adphead, ad_next) {
- if (oldadp->ad_lbn >= lbn)
+ if (oldadp->ad_offset >= off)
break;
}
if (oldadp == NULL)
panic("softdep_setup_allocdirect: lost entry");
/* insert in middle of list */
TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);
- if (oldadp->ad_lbn == lbn)
+ if (oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
+
FREE_LOCK(&lk);
}
@@ -1761,10 +4316,11 @@ allocdirect_merge(adphead, newadp, oldadp)
struct freefrag *freefrag;
struct newdirblk *newdirblk;
+ freefrag = NULL;
mtx_assert(&lk, MA_OWNED);
if (newadp->ad_oldblkno != oldadp->ad_newblkno ||
newadp->ad_oldsize != oldadp->ad_newsize ||
- newadp->ad_lbn >= NDADDR)
+ newadp->ad_offset >= NDADDR)
panic("%s %jd != new %jd || old size %ld != new %ld",
"allocdirect_merge: old blkno",
(intmax_t)newadp->ad_oldblkno,
@@ -1779,7 +4335,7 @@ allocdirect_merge(adphead, newadp, oldadp)
* This action is done by swapping the freefrag dependencies.
* The new dependency gains the old one's freefrag, and the
* old one gets the new one and then immediately puts it on
- * the worklist when it is freed by free_allocdirect. It is
+ * the worklist when it is freed by free_newblk. It is
* not possible to do this swap when the old dependency had a
* non-zero size but no previous fragment to free. This condition
* arises when the new block is an extension of the old block.
@@ -1788,8 +4344,8 @@ allocdirect_merge(adphead, newadp, oldadp)
* the old dependency, so cannot legitimately be freed until the
* conditions for the new dependency are fulfilled.
*/
+ freefrag = newadp->ad_freefrag;
if (oldadp->ad_freefrag != NULL || oldadp->ad_oldblkno == 0) {
- freefrag = newadp->ad_freefrag;
newadp->ad_freefrag = oldadp->ad_freefrag;
oldadp->ad_freefrag = freefrag;
}
@@ -1804,32 +4360,118 @@ allocdirect_merge(adphead, newadp, oldadp)
panic("allocdirect_merge: extra newdirblk");
WORKLIST_INSERT(&newadp->ad_newdirblk, &newdirblk->db_list);
}
- free_allocdirect(adphead, oldadp, 0);
+ TAILQ_REMOVE(adphead, oldadp, ad_next);
+ /*
+ * We need to move any journal dependencies over to the freefrag
+ * that releases this block if it exists. Otherwise we are
+ * extending an existing block and we'll wait until that is
+ * complete to release the journal space and extend the
+ * new journal to cover this old space as well.
+ */
+ if (freefrag == NULL) {
+ struct jnewblk *jnewblk;
+ struct jnewblk *njnewblk;
+
+ if (oldadp->ad_newblkno != newadp->ad_newblkno)
+ panic("allocdirect_merge: %jd != %jd",
+ oldadp->ad_newblkno, newadp->ad_newblkno);
+ jnewblk = oldadp->ad_block.nb_jnewblk;
+ cancel_newblk(&oldadp->ad_block, &newadp->ad_block.nb_jwork);
+ /*
+ * We have an unwritten jnewblk, we need to merge the
+ * frag bits with our own. The newer adp's journal can not
+ * be written prior to the old one so no need to check for
+ * it here.
+ */
+ if (jnewblk) {
+ njnewblk = newadp->ad_block.nb_jnewblk;
+ if (njnewblk == NULL)
+ panic("allocdirect_merge: No jnewblk");
+ if (jnewblk->jn_state & UNDONE) {
+ njnewblk->jn_state |= UNDONE | NEWBLOCK;
+ njnewblk->jn_state &= ~ATTACHED;
+ jnewblk->jn_state &= ~UNDONE;
+ }
+ njnewblk->jn_oldfrags = jnewblk->jn_oldfrags;
+ WORKLIST_REMOVE(&jnewblk->jn_list);
+ jnewblk->jn_state |= ATTACHED | COMPLETE;
+ free_jnewblk(jnewblk);
+ }
+ } else {
+ /*
+ * We can skip journaling for this freefrag and just complete
+ * any pending journal work for the allocdirect that is being
+ * removed after the freefrag completes.
+ */
+ if (freefrag->ff_jfreefrag)
+ cancel_jfreefrag(freefrag->ff_jfreefrag);
+ cancel_newblk(&oldadp->ad_block, &freefrag->ff_jwork);
+ }
+ free_newblk(&oldadp->ad_block);
}
-
+
/*
- * Allocate a new freefrag structure if needed.
+ * Allocate a jfreefrag structure to journal a single block free.
+ */
+static struct jfreefrag *
+newjfreefrag(freefrag, ip, blkno, size, lbn)
+ struct freefrag *freefrag;
+ struct inode *ip;
+ ufs2_daddr_t blkno;
+ long size;
+ ufs_lbn_t lbn;
+{
+ struct jfreefrag *jfreefrag;
+ struct fs *fs;
+
+ fs = ip->i_fs;
+ jfreefrag = malloc(sizeof(struct jfreefrag), M_JFREEFRAG,
+ M_SOFTDEP_FLAGS);
+ workitem_alloc(&jfreefrag->fr_list, D_JFREEFRAG, UFSTOVFS(ip->i_ump));
+ jfreefrag->fr_jsegdep = newjsegdep(&jfreefrag->fr_list);
+ jfreefrag->fr_state = ATTACHED | DEPCOMPLETE;
+ jfreefrag->fr_ino = ip->i_number;
+ jfreefrag->fr_lbn = lbn;
+ jfreefrag->fr_blkno = blkno;
+ jfreefrag->fr_frags = numfrags(fs, size);
+ jfreefrag->fr_freefrag = freefrag;
+
+ return (jfreefrag);
+}
+
+/*
+ * Allocate a new freefrag structure.
*/
static struct freefrag *
-newfreefrag(ip, blkno, size)
+newfreefrag(ip, blkno, size, lbn)
struct inode *ip;
ufs2_daddr_t blkno;
long size;
+ ufs_lbn_t lbn;
{
struct freefrag *freefrag;
struct fs *fs;
- if (blkno == 0)
- return (NULL);
fs = ip->i_fs;
if (fragnum(fs, blkno) + numfrags(fs, size) > fs->fs_frag)
panic("newfreefrag: frag size");
freefrag = malloc(sizeof(struct freefrag),
- M_FREEFRAG, M_SOFTDEP_FLAGS);
+ M_FREEFRAG, M_SOFTDEP_FLAGS);
workitem_alloc(&freefrag->ff_list, D_FREEFRAG, UFSTOVFS(ip->i_ump));
+ freefrag->ff_state = ATTACHED;
+ LIST_INIT(&freefrag->ff_jwork);
freefrag->ff_inum = ip->i_number;
freefrag->ff_blkno = blkno;
freefrag->ff_fragsize = size;
+
+ if (fs->fs_flags & FS_SUJ) {
+ freefrag->ff_jfreefrag =
+ newjfreefrag(freefrag, ip, blkno, size, lbn);
+ } else {
+ freefrag->ff_state |= DEPCOMPLETE;
+ freefrag->ff_jfreefrag = NULL;
+ }
+
return (freefrag);
}
@@ -1842,9 +4484,17 @@ handle_workitem_freefrag(freefrag)
struct freefrag *freefrag;
{
struct ufsmount *ump = VFSTOUFS(freefrag->ff_list.wk_mp);
+ struct workhead wkhd;
+ /*
+ * It would be illegal to add new completion items to the
+ * freefrag after it was schedule to be done so it must be
+ * safe to modify the list head here.
+ */
+ LIST_INIT(&wkhd);
+ LIST_SWAP(&freefrag->ff_jwork, &wkhd, worklist, wk_list);
ffs_blkfree(ump, ump->um_fs, ump->um_devvp, freefrag->ff_blkno,
- freefrag->ff_fragsize, freefrag->ff_inum);
+ freefrag->ff_fragsize, freefrag->ff_inum, &wkhd);
ACQUIRE_LOCK(&lk);
WORKITEM_FREE(freefrag, D_FREEFRAG);
FREE_LOCK(&lk);
@@ -1856,9 +4506,9 @@ handle_workitem_freefrag(freefrag)
* See the description of softdep_setup_allocdirect above for details.
*/
void
-softdep_setup_allocext(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
+softdep_setup_allocext(ip, off, newblkno, oldblkno, newsize, oldsize, bp)
struct inode *ip;
- ufs_lbn_t lbn;
+ ufs_lbn_t off;
ufs2_daddr_t newblkno;
ufs2_daddr_t oldblkno;
long newsize;
@@ -1867,50 +4517,55 @@ softdep_setup_allocext(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
{
struct allocdirect *adp, *oldadp;
struct allocdirectlst *adphead;
- struct bmsafemap *bmsafemap;
+ struct freefrag *freefrag;
struct inodedep *inodedep;
+ struct jnewblk *jnewblk;
struct newblk *newblk;
struct mount *mp;
+ ufs_lbn_t lbn;
+
+ if (off >= NXADDR)
+ panic("softdep_setup_allocext: lbn %lld > NXADDR",
+ (long long)off);
+ lbn = bp->b_lblkno;
mp = UFSTOVFS(ip->i_ump);
- adp = malloc(sizeof(struct allocdirect),
- M_ALLOCDIRECT, M_SOFTDEP_FLAGS|M_ZERO);
- workitem_alloc(&adp->ad_list, D_ALLOCDIRECT, mp);
- adp->ad_lbn = lbn;
- adp->ad_newblkno = newblkno;
- adp->ad_oldblkno = oldblkno;
- adp->ad_newsize = newsize;
- adp->ad_oldsize = oldsize;
- adp->ad_state = ATTACHED | EXTDATA;
- LIST_INIT(&adp->ad_newdirblk);
- if (newblkno == oldblkno)
- adp->ad_freefrag = NULL;
+ if (oldblkno && oldblkno != newblkno)
+ freefrag = newfreefrag(ip, oldblkno, oldsize, lbn);
else
- adp->ad_freefrag = newfreefrag(ip, oldblkno, oldsize);
+ freefrag = NULL;
ACQUIRE_LOCK(&lk);
- if (newblk_lookup(ip->i_fs, newblkno, 0, &newblk) == 0)
+ if (newblk_lookup(mp, newblkno, 0, &newblk) == 0)
panic("softdep_setup_allocext: lost block");
+ KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
+ ("softdep_setup_allocext: newblk already initialized"));
+ /*
+ * Convert the newblk to an allocdirect.
+ */
+ newblk->nb_list.wk_type = D_ALLOCDIRECT;
+ adp = (struct allocdirect *)newblk;
+ newblk->nb_freefrag = freefrag;
+ adp->ad_offset = off;
+ adp->ad_oldblkno = oldblkno;
+ adp->ad_newsize = newsize;
+ adp->ad_oldsize = oldsize;
+ adp->ad_state |= EXTDATA;
+ /*
+ * Finish initializing the journal.
+ */
+ if ((jnewblk = newblk->nb_jnewblk) != NULL) {
+ jnewblk->jn_ino = ip->i_number;
+ jnewblk->jn_lbn = lbn;
+ add_to_journal(&jnewblk->jn_list);
+ }
+ if (freefrag && freefrag->ff_jfreefrag != NULL)
+ add_to_journal(&freefrag->ff_jfreefrag->fr_list);
inodedep_lookup(mp, ip->i_number, DEPALLOC | NODELAY, &inodedep);
adp->ad_inodedep = inodedep;
- if (newblk->nb_state == DEPCOMPLETE) {
- adp->ad_state |= DEPCOMPLETE;
- adp->ad_buf = NULL;
- } else {
- bmsafemap = newblk->nb_bmsafemap;
- adp->ad_buf = bmsafemap->sm_buf;
- LIST_REMOVE(newblk, nb_deps);
- LIST_INSERT_HEAD(&bmsafemap->sm_allocdirecthd, adp, ad_deps);
- }
- LIST_REMOVE(newblk, nb_hash);
- free(newblk, M_NEWBLK);
-
- WORKLIST_INSERT(&bp->b_dep, &adp->ad_list);
- if (lbn >= NXADDR)
- panic("softdep_setup_allocext: lbn %lld > NXADDR",
- (long long)lbn);
+ WORKLIST_INSERT(&bp->b_dep, &newblk->nb_list);
/*
* The list of allocdirects must be kept in sorted and ascending
* order so that the rollback routines can quickly determine the
@@ -1925,23 +4580,23 @@ softdep_setup_allocext(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
*/
adphead = &inodedep->id_newextupdt;
oldadp = TAILQ_LAST(adphead, allocdirectlst);
- if (oldadp == NULL || oldadp->ad_lbn <= lbn) {
+ if (oldadp == NULL || oldadp->ad_offset <= off) {
/* insert at end of list */
TAILQ_INSERT_TAIL(adphead, adp, ad_next);
- if (oldadp != NULL && oldadp->ad_lbn == lbn)
+ if (oldadp != NULL && oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
FREE_LOCK(&lk);
return;
}
TAILQ_FOREACH(oldadp, adphead, ad_next) {
- if (oldadp->ad_lbn >= lbn)
+ if (oldadp->ad_offset >= off)
break;
}
if (oldadp == NULL)
panic("softdep_setup_allocext: lost entry");
/* insert in middle of list */
TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);
- if (oldadp->ad_lbn == lbn)
+ if (oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
FREE_LOCK(&lk);
}
@@ -1975,22 +4630,39 @@ softdep_setup_allocext(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
* Allocate a new allocindir structure.
*/
static struct allocindir *
-newallocindir(ip, ptrno, newblkno, oldblkno)
+newallocindir(ip, ptrno, newblkno, oldblkno, lbn)
struct inode *ip; /* inode for file being extended */
int ptrno; /* offset of pointer in indirect block */
ufs2_daddr_t newblkno; /* disk block number being added */
ufs2_daddr_t oldblkno; /* previous block number, 0 if none */
+ ufs_lbn_t lbn;
{
+ struct newblk *newblk;
struct allocindir *aip;
+ struct freefrag *freefrag;
+ struct jnewblk *jnewblk;
- aip = malloc(sizeof(struct allocindir),
- M_ALLOCINDIR, M_SOFTDEP_FLAGS|M_ZERO);
- workitem_alloc(&aip->ai_list, D_ALLOCINDIR, UFSTOVFS(ip->i_ump));
- aip->ai_state = ATTACHED;
+ if (oldblkno)
+ freefrag = newfreefrag(ip, oldblkno, ip->i_fs->fs_bsize, lbn);
+ else
+ freefrag = NULL;
+ ACQUIRE_LOCK(&lk);
+ if (newblk_lookup(UFSTOVFS(ip->i_ump), newblkno, 0, &newblk) == 0)
+ panic("new_allocindir: lost block");
+ KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
+ ("newallocindir: newblk already initialized"));
+ newblk->nb_list.wk_type = D_ALLOCINDIR;
+ newblk->nb_freefrag = freefrag;
+ aip = (struct allocindir *)newblk;
aip->ai_offset = ptrno;
- aip->ai_newblkno = newblkno;
aip->ai_oldblkno = oldblkno;
- aip->ai_freefrag = newfreefrag(ip, oldblkno, ip->i_fs->fs_bsize);
+ if ((jnewblk = newblk->nb_jnewblk) != NULL) {
+ jnewblk->jn_ino = ip->i_number;
+ jnewblk->jn_lbn = lbn;
+ add_to_journal(&jnewblk->jn_list);
+ }
+ if (freefrag && freefrag->ff_jfreefrag != NULL)
+ add_to_journal(&freefrag->ff_jfreefrag->fr_list);
return (aip);
}
@@ -2008,22 +4680,28 @@ softdep_setup_allocindir_page(ip, lbn, bp, ptrno, newblkno, oldblkno, nbp)
ufs2_daddr_t oldblkno; /* previous block number, 0 if none */
struct buf *nbp; /* buffer holding allocated page */
{
+ struct inodedep *inodedep;
struct allocindir *aip;
struct pagedep *pagedep;
+ struct mount *mp;
+ if (lbn != nbp->b_lblkno)
+ panic("softdep_setup_allocindir_page: lbn %jd != lblkno %jd",
+ lbn, bp->b_lblkno);
ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_page");
- aip = newallocindir(ip, ptrno, newblkno, oldblkno);
- ACQUIRE_LOCK(&lk);
+ mp = UFSTOVFS(ip->i_ump);
+ aip = newallocindir(ip, ptrno, newblkno, oldblkno, lbn);
+ (void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
/*
* If we are allocating a directory page, then we must
* allocate an associated pagedep to track additions and
* deletions.
*/
if ((ip->i_mode & IFMT) == IFDIR &&
- pagedep_lookup(ip, lbn, DEPALLOC, &pagedep) == 0)
+ pagedep_lookup(mp, ip->i_number, lbn, DEPALLOC, &pagedep) == 0)
WORKLIST_INSERT(&nbp->b_dep, &pagedep->pd_list);
- WORKLIST_INSERT(&nbp->b_dep, &aip->ai_list);
- setup_allocindir_phase2(bp, ip, aip);
+ WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
+ setup_allocindir_phase2(bp, ip, inodedep, aip, lbn);
FREE_LOCK(&lk);
}
@@ -2039,38 +4717,68 @@ softdep_setup_allocindir_meta(nbp, ip, bp, ptrno, newblkno)
int ptrno; /* offset of pointer in indirect block */
ufs2_daddr_t newblkno; /* disk block number being added */
{
+ struct inodedep *inodedep;
struct allocindir *aip;
+ ufs_lbn_t lbn;
+ lbn = nbp->b_lblkno;
ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_meta");
- aip = newallocindir(ip, ptrno, newblkno, 0);
- ACQUIRE_LOCK(&lk);
- WORKLIST_INSERT(&nbp->b_dep, &aip->ai_list);
- setup_allocindir_phase2(bp, ip, aip);
+ aip = newallocindir(ip, ptrno, newblkno, 0, lbn);
+ inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC, &inodedep);
+ WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
+ setup_allocindir_phase2(bp, ip, inodedep, aip, lbn);
FREE_LOCK(&lk);
}
+static void
+indirdep_complete(indirdep)
+ struct indirdep *indirdep;
+{
+ struct allocindir *aip;
+
+ LIST_REMOVE(indirdep, ir_next);
+ indirdep->ir_state &= ~ONDEPLIST;
+
+ while ((aip = LIST_FIRST(&indirdep->ir_completehd)) != NULL) {
+ LIST_REMOVE(aip, ai_next);
+ free_newblk(&aip->ai_block);
+ }
+ /*
+ * If this indirdep is not attached to a buf it was simply waiting
+ * on completion to clear completehd. free_indirdep() asserts
+ * that nothing is dangling.
+ */
+ if ((indirdep->ir_state & ONWORKLIST) == 0)
+ free_indirdep(indirdep);
+}
+
/*
* Called to finish the allocation of the "aip" allocated
* by one of the two routines above.
*/
static void
-setup_allocindir_phase2(bp, ip, aip)
+setup_allocindir_phase2(bp, ip, inodedep, aip, lbn)
struct buf *bp; /* in-memory copy of the indirect block */
struct inode *ip; /* inode for file being extended */
+ struct inodedep *inodedep; /* Inodedep for ip */
struct allocindir *aip; /* allocindir allocated by the above routines */
+ ufs_lbn_t lbn; /* Logical block number for this block. */
{
struct worklist *wk;
+ struct fs *fs;
+ struct newblk *newblk;
struct indirdep *indirdep, *newindirdep;
- struct bmsafemap *bmsafemap;
struct allocindir *oldaip;
struct freefrag *freefrag;
- struct newblk *newblk;
+ struct mount *mp;
ufs2_daddr_t blkno;
+ mp = UFSTOVFS(ip->i_ump);
+ fs = ip->i_fs;
mtx_assert(&lk, MA_OWNED);
if (bp->b_lblkno >= 0)
panic("setup_allocindir_phase2: not indir blk");
- for (indirdep = NULL, newindirdep = NULL; ; ) {
+ for (freefrag = NULL, indirdep = NULL, newindirdep = NULL; ; ) {
LIST_FOREACH(wk, &bp->b_dep, wk_list) {
if (wk->wk_type != D_INDIRDEP)
continue;
@@ -2079,49 +4787,41 @@ setup_allocindir_phase2(bp, ip, aip)
}
if (indirdep == NULL && newindirdep) {
indirdep = newindirdep;
- WORKLIST_INSERT(&bp->b_dep, &indirdep->ir_list);
newindirdep = NULL;
+ WORKLIST_INSERT(&bp->b_dep, &indirdep->ir_list);
+ if (newblk_lookup(mp, dbtofsb(fs, bp->b_blkno), 0,
+ &newblk)) {
+ indirdep->ir_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&newblk->nb_indirdeps,
+ indirdep, ir_next);
+ } else
+ indirdep->ir_state |= DEPCOMPLETE;
}
if (indirdep) {
- if (newblk_lookup(ip->i_fs, aip->ai_newblkno, 0,
- &newblk) == 0)
- panic("setup_allocindir: lost block");
- if (newblk->nb_state == DEPCOMPLETE) {
- aip->ai_state |= DEPCOMPLETE;
- aip->ai_buf = NULL;
- } else {
- bmsafemap = newblk->nb_bmsafemap;
- aip->ai_buf = bmsafemap->sm_buf;
- LIST_REMOVE(newblk, nb_deps);
- LIST_INSERT_HEAD(&bmsafemap->sm_allocindirhd,
- aip, ai_deps);
- }
- LIST_REMOVE(newblk, nb_hash);
- free(newblk, M_NEWBLK);
aip->ai_indirdep = indirdep;
/*
* Check to see if there is an existing dependency
* for this block. If there is, merge the old
- * dependency into the new one.
+ * dependency into the new one. This happens
+ * as a result of reallocblk only.
*/
if (aip->ai_oldblkno == 0)
oldaip = NULL;
else
- LIST_FOREACH(oldaip, &indirdep->ir_deplisthd, ai_next)
+ LIST_FOREACH(oldaip, &indirdep->ir_deplisthd,
+ ai_next)
if (oldaip->ai_offset == aip->ai_offset)
break;
- freefrag = NULL;
- if (oldaip != NULL) {
- if (oldaip->ai_newblkno != aip->ai_oldblkno)
- panic("setup_allocindir_phase2: blkno");
- aip->ai_oldblkno = oldaip->ai_oldblkno;
- freefrag = aip->ai_freefrag;
- aip->ai_freefrag = oldaip->ai_freefrag;
- oldaip->ai_freefrag = NULL;
- free_allocindir(oldaip, NULL);
- }
+ if (oldaip != NULL)
+ freefrag = allocindir_merge(aip, oldaip);
LIST_INSERT_HEAD(&indirdep->ir_deplisthd, aip, ai_next);
+ KASSERT(aip->ai_offset >= 0 &&
+ aip->ai_offset < NINDIR(ip->i_ump->um_fs),
+ ("setup_allocindir_phase2: Bad offset %d",
+ aip->ai_offset));
+ KASSERT(indirdep->ir_savebp != NULL,
+ ("setup_allocindir_phase2 NULL ir_savebp"));
if (ip->i_ump->um_fstype == UFS1)
((ufs1_daddr_t *)indirdep->ir_savebp->b_data)
[aip->ai_offset] = aip->ai_oldblkno;
@@ -2148,13 +4848,16 @@ setup_allocindir_phase2(bp, ip, aip)
}
newindirdep = malloc(sizeof(struct indirdep),
M_INDIRDEP, M_SOFTDEP_FLAGS);
- workitem_alloc(&newindirdep->ir_list, D_INDIRDEP,
- UFSTOVFS(ip->i_ump));
+ workitem_alloc(&newindirdep->ir_list, D_INDIRDEP, mp);
newindirdep->ir_state = ATTACHED;
if (ip->i_ump->um_fstype == UFS1)
newindirdep->ir_state |= UFS1FMT;
+ newindirdep->ir_saveddata = NULL;
LIST_INIT(&newindirdep->ir_deplisthd);
LIST_INIT(&newindirdep->ir_donehd);
+ LIST_INIT(&newindirdep->ir_writehd);
+ LIST_INIT(&newindirdep->ir_completehd);
+ LIST_INIT(&newindirdep->ir_jwork);
if (bp->b_blkno == bp->b_lblkno) {
ufs_bmaparray(bp->b_vp, bp->b_lblkno, &blkno, bp,
NULL, NULL);
@@ -2169,6 +4872,51 @@ setup_allocindir_phase2(bp, ip, aip)
}
/*
+ * Merge two allocindirs which refer to the same block. Move newblock
+ * dependencies and setup the freefrags appropriately.
+ */
+static struct freefrag *
+allocindir_merge(aip, oldaip)
+ struct allocindir *aip;
+ struct allocindir *oldaip;
+{
+ struct newdirblk *newdirblk;
+ struct freefrag *freefrag;
+ struct worklist *wk;
+
+ if (oldaip->ai_newblkno != aip->ai_oldblkno)
+ panic("allocindir_merge: blkno");
+ aip->ai_oldblkno = oldaip->ai_oldblkno;
+ freefrag = aip->ai_freefrag;
+ aip->ai_freefrag = oldaip->ai_freefrag;
+ oldaip->ai_freefrag = NULL;
+ KASSERT(freefrag != NULL, ("setup_allocindir_phase2: No freefrag"));
+ /*
+ * If we are tracking a new directory-block allocation,
+ * move it from the old allocindir to the new allocindir.
+ */
+ if ((wk = LIST_FIRST(&oldaip->ai_newdirblk)) != NULL) {
+ newdirblk = WK_NEWDIRBLK(wk);
+ WORKLIST_REMOVE(&newdirblk->db_list);
+ if (!LIST_EMPTY(&oldaip->ai_newdirblk))
+ panic("allocindir_merge: extra newdirblk");
+ WORKLIST_INSERT(&aip->ai_newdirblk, &newdirblk->db_list);
+ }
+ /*
+ * We can skip journaling for this freefrag and just complete
+ * any pending journal work for the allocindir that is being
+ * removed after the freefrag completes.
+ */
+ if (freefrag->ff_jfreefrag)
+ cancel_jfreefrag(freefrag->ff_jfreefrag);
+ LIST_REMOVE(oldaip, ai_next);
+ cancel_newblk(&oldaip->ai_block, &freefrag->ff_jwork);
+ free_newblk(&oldaip->ai_block);
+
+ return (freefrag);
+}
+
+/*
* Block de-allocation dependencies.
*
* When blocks are de-allocated, the on-disk pointers must be nullified before
@@ -2203,9 +4951,12 @@ softdep_setup_freeblocks(ip, length, flags)
off_t length; /* The new length for the file */
int flags; /* IO_EXT and/or IO_NORMAL */
{
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
struct freeblks *freeblks;
struct inodedep *inodedep;
struct allocdirect *adp;
+ struct jfreeblk *jfreeblk;
struct bufobj *bo;
struct vnode *vp;
struct buf *bp;
@@ -2213,6 +4964,13 @@ softdep_setup_freeblocks(ip, length, flags)
ufs2_daddr_t extblocks, datablocks;
struct mount *mp;
int i, delay, error;
+ ufs2_daddr_t blkno;
+ ufs_lbn_t tmpval;
+ ufs_lbn_t lbn;
+ long oldextsize;
+ long oldsize;
+ int frags;
+ int needj;
fs = ip->i_fs;
mp = UFSTOVFS(ip->i_ump);
@@ -2221,32 +4979,53 @@ softdep_setup_freeblocks(ip, length, flags)
freeblks = malloc(sizeof(struct freeblks),
M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO);
workitem_alloc(&freeblks->fb_list, D_FREEBLKS, mp);
+ LIST_INIT(&freeblks->fb_jfreeblkhd);
+ LIST_INIT(&freeblks->fb_jwork);
freeblks->fb_state = ATTACHED;
freeblks->fb_uid = ip->i_uid;
freeblks->fb_previousinum = ip->i_number;
freeblks->fb_devvp = ip->i_devvp;
+ freeblks->fb_chkcnt = 0;
ACQUIRE_LOCK(&lk);
+ /*
+ * If we're truncating a removed file that will never be written
+ * we don't need to journal the block frees. The canceled journals
+ * for the allocations will suffice.
+ */
+ inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
+ if ((inodedep->id_state & (UNLINKED | DEPCOMPLETE)) == UNLINKED ||
+ (fs->fs_flags & FS_SUJ) == 0)
+ needj = 0;
+ else
+ needj = 1;
num_freeblkdep++;
FREE_LOCK(&lk);
extblocks = 0;
if (fs->fs_magic == FS_UFS2_MAGIC)
extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize));
datablocks = DIP(ip, i_blocks) - extblocks;
- if ((flags & IO_NORMAL) == 0) {
- freeblks->fb_oldsize = 0;
- freeblks->fb_chkcnt = 0;
- } else {
- freeblks->fb_oldsize = ip->i_size;
+ if ((flags & IO_NORMAL) != 0) {
+ oldsize = ip->i_size;
ip->i_size = 0;
DIP_SET(ip, i_size, 0);
freeblks->fb_chkcnt = datablocks;
for (i = 0; i < NDADDR; i++) {
- freeblks->fb_dblks[i] = DIP(ip, i_db[i]);
+ blkno = DIP(ip, i_db[i]);
DIP_SET(ip, i_db[i], 0);
+ if (blkno == 0)
+ continue;
+ frags = sblksize(fs, oldsize, i);
+ frags = numfrags(fs, frags);
+ newfreework(freeblks, NULL, i, blkno, frags, needj);
}
- for (i = 0; i < NIADDR; i++) {
- freeblks->fb_iblks[i] = DIP(ip, i_ib[i]);
+ for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR;
+ i++, tmpval *= NINDIR(fs)) {
+ blkno = DIP(ip, i_ib[i]);
DIP_SET(ip, i_ib[i], 0);
+ if (blkno)
+ newfreework(freeblks, NULL, -lbn - i, blkno,
+ fs->fs_frag, needj);
+ lbn += tmpval;
}
/*
* If the file was removed, then the space being freed was
@@ -2259,17 +5038,23 @@ softdep_setup_freeblocks(ip, length, flags)
UFS_UNLOCK(ip->i_ump);
}
}
- if ((flags & IO_EXT) == 0) {
- freeblks->fb_oldextsize = 0;
- } else {
- freeblks->fb_oldextsize = ip->i_din2->di_extsize;
+ if ((flags & IO_EXT) != 0) {
+ oldextsize = ip->i_din2->di_extsize;
ip->i_din2->di_extsize = 0;
freeblks->fb_chkcnt += extblocks;
for (i = 0; i < NXADDR; i++) {
- freeblks->fb_eblks[i] = ip->i_din2->di_extb[i];
+ blkno = ip->i_din2->di_extb[i];
ip->i_din2->di_extb[i] = 0;
+ if (blkno == 0)
+ continue;
+ frags = sblksize(fs, oldextsize, i);
+ frags = numfrags(fs, frags);
+ newfreework(freeblks, NULL, -1 - i, blkno, frags,
+ needj);
}
}
+ if (LIST_EMPTY(&freeblks->fb_jfreeblkhd))
+ needj = 0;
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - freeblks->fb_chkcnt);
/*
* Push the zero'ed inode to to its disk buffer so that we are free
@@ -2282,12 +5067,17 @@ softdep_setup_freeblocks(ip, length, flags)
brelse(bp);
softdep_error("softdep_setup_freeblocks", error);
}
- if (ip->i_ump->um_fstype == UFS1)
- *((struct ufs1_dinode *)bp->b_data +
- ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1;
- else
- *((struct ufs2_dinode *)bp->b_data +
- ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
+ if (ip->i_ump->um_fstype == UFS1) {
+ dp1 = ((struct ufs1_dinode *)bp->b_data +
+ ino_to_fsbo(fs, ip->i_number));
+ ip->i_din1->di_freelink = dp1->di_freelink;
+ *dp1 = *ip->i_din1;
+ } else {
+ dp2 = ((struct ufs2_dinode *)bp->b_data +
+ ino_to_fsbo(fs, ip->i_number));
+ ip->i_din2->di_freelink = dp2->di_freelink;
+ *dp2 = *ip->i_din2;
+ }
/*
* Find and eliminate any inode dependencies.
*/
@@ -2304,7 +5094,9 @@ softdep_setup_freeblocks(ip, length, flags)
*/
delay = (inodedep->id_state & DEPCOMPLETE);
if (delay)
- WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
+ WORKLIST_INSERT(&bp->b_dep, &freeblks->fb_list);
+ else if (needj)
+ freeblks->fb_state |= DEPCOMPLETE | COMPLETE;
/*
* Because the file length has been truncated to zero, any
* pending block allocation dependency structures associated
@@ -2318,14 +5110,19 @@ softdep_setup_freeblocks(ip, length, flags)
merge_inode_lists(&inodedep->id_newinoupdt,
&inodedep->id_inoupdt);
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
- free_allocdirect(&inodedep->id_inoupdt, adp, delay);
+ cancel_allocdirect(&inodedep->id_inoupdt, adp,
+ freeblks, delay);
}
if (flags & IO_EXT) {
merge_inode_lists(&inodedep->id_newextupdt,
&inodedep->id_extupdt);
while ((adp = TAILQ_FIRST(&inodedep->id_extupdt)) != 0)
- free_allocdirect(&inodedep->id_extupdt, adp, delay);
+ cancel_allocdirect(&inodedep->id_extupdt, adp,
+ freeblks, delay);
}
+ LIST_FOREACH(jfreeblk, &freeblks->fb_jfreeblkhd, jf_deps)
+ add_to_journal(&jfreeblk->jf_list);
+
FREE_LOCK(&lk);
bdwrite(bp);
/*
@@ -2349,9 +5146,9 @@ restart:
BO_UNLOCK(bo);
ACQUIRE_LOCK(&lk);
(void) inodedep_lookup(mp, ip->i_number, 0, &inodedep);
- deallocate_dependencies(bp, inodedep);
+ if (deallocate_dependencies(bp, inodedep, freeblks))
+ bp->b_flags |= B_INVAL | B_NOCACHE;
FREE_LOCK(&lk);
- bp->b_flags |= B_INVAL | B_NOCACHE;
brelse(bp);
BO_LOCK(bo);
goto restart;
@@ -2361,7 +5158,7 @@ restart:
if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) != 0)
(void) free_inodedep(inodedep);
- if(delay) {
+ if (delay) {
freeblks->fb_state |= DEPCOMPLETE;
/*
* If the inode with zeroed block pointers is now on disk
@@ -2371,16 +5168,16 @@ restart:
* the request here than in the !delay case.
*/
if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE)
- add_to_worklist(&freeblks->fb_list);
+ add_to_worklist(&freeblks->fb_list, 1);
}
FREE_LOCK(&lk);
/*
- * If the inode has never been written to disk (delay == 0),
- * then we can process the freeblks now that we have deleted
- * the dependencies.
+ * If the inode has never been written to disk (delay == 0) and
+ * we're not waiting on any journal writes, then we can process the
+ * freeblks now that we have deleted the dependencies.
*/
- if (!delay)
+ if (!delay && !needj)
handle_workitem_freeblocks(freeblks, 0);
}
@@ -2389,19 +5186,23 @@ restart:
* be reallocated to a new vnode. The buffer must be locked, thus,
* no I/O completion operations can occur while we are manipulating
* its associated dependencies. The mutex is held so that other I/O's
- * associated with related dependencies do not occur.
+ * associated with related dependencies do not occur. Returns 1 if
+ * all dependencies were cleared, 0 otherwise.
*/
-static void
-deallocate_dependencies(bp, inodedep)
+static int
+deallocate_dependencies(bp, inodedep, freeblks)
struct buf *bp;
struct inodedep *inodedep;
+ struct freeblks *freeblks;
{
struct worklist *wk;
struct indirdep *indirdep;
+ struct newdirblk *newdirblk;
struct allocindir *aip;
struct pagedep *pagedep;
+ struct jremref *jremref;
+ struct jmvref *jmvref;
struct dirrem *dirrem;
- struct diradd *dap;
int i;
mtx_assert(&lk, MA_OWNED);
@@ -2410,47 +5211,24 @@ deallocate_dependencies(bp, inodedep)
case D_INDIRDEP:
indirdep = WK_INDIRDEP(wk);
- /*
- * None of the indirect pointers will ever be visible,
- * so they can simply be tossed. GOINGAWAY ensures
- * that allocated pointers will be saved in the buffer
- * cache until they are freed. Note that they will
- * only be able to be found by their physical address
- * since the inode mapping the logical address will
- * be gone. The save buffer used for the safe copy
- * was allocated in setup_allocindir_phase2 using
- * the physical address so it could be used for this
- * purpose. Hence we swap the safe copy with the real
- * copy, allowing the safe copy to be freed and holding
- * on to the real copy for later use in indir_trunc.
- */
- if (indirdep->ir_state & GOINGAWAY)
- panic("deallocate_dependencies: already gone");
- indirdep->ir_state |= GOINGAWAY;
- VFSTOUFS(bp->b_vp->v_mount)->um_numindirdeps += 1;
- while ((aip = LIST_FIRST(&indirdep->ir_deplisthd)) != 0)
- free_allocindir(aip, inodedep);
if (bp->b_lblkno >= 0 ||
bp->b_blkno != indirdep->ir_savebp->b_lblkno)
panic("deallocate_dependencies: not indir");
- bcopy(bp->b_data, indirdep->ir_savebp->b_data,
- bp->b_bcount);
- WORKLIST_REMOVE(wk);
- WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk);
+ cancel_indirdep(indirdep, bp, inodedep, freeblks);
continue;
case D_PAGEDEP:
pagedep = WK_PAGEDEP(wk);
/*
- * None of the directory additions will ever be
- * visible, so they can simply be tossed.
+ * There should be no directory add dependencies present
+ * as the directory could not be truncated until all
+ * children were removed.
*/
+ KASSERT(LIST_FIRST(&pagedep->pd_pendinghd) == NULL,
+ ("deallocate_dependencies: pendinghd != NULL"));
for (i = 0; i < DAHASHSZ; i++)
- while ((dap =
- LIST_FIRST(&pagedep->pd_diraddhd[i])))
- free_diradd(dap);
- while ((dap = LIST_FIRST(&pagedep->pd_pendinghd)) != 0)
- free_diradd(dap);
+ KASSERT(LIST_FIRST(&pagedep->pd_diraddhd[i]) == NULL,
+ ("deallocate_dependencies: diraddhd != NULL"));
/*
* Copy any directory remove dependencies to the list
* to be processed after the zero'ed inode is written.
@@ -2458,28 +5236,40 @@ deallocate_dependencies(bp, inodedep)
* can be dumped directly onto the work list.
*/
LIST_FOREACH(dirrem, &pagedep->pd_dirremhd, dm_next) {
+ /*
+ * If there are any dirrems we wait for
+ * the journal write to complete and
+ * then restart the buf scan as the lock
+ * has been dropped.
+ */
+ while ((jremref =
+ LIST_FIRST(&dirrem->dm_jremrefhd))
+ != NULL) {
+ stat_jwait_filepage++;
+ jwait(&jremref->jr_list);
+ return (0);
+ }
LIST_REMOVE(dirrem, dm_next);
dirrem->dm_dirinum = pagedep->pd_ino;
if (inodedep == NULL ||
(inodedep->id_state & ALLCOMPLETE) ==
- ALLCOMPLETE)
- add_to_worklist(&dirrem->dm_list);
- else
+ ALLCOMPLETE) {
+ dirrem->dm_state |= COMPLETE;
+ add_to_worklist(&dirrem->dm_list, 0);
+ } else
WORKLIST_INSERT(&inodedep->id_bufwait,
&dirrem->dm_list);
}
if ((pagedep->pd_state & NEWBLOCK) != 0) {
- LIST_FOREACH(wk, &inodedep->id_bufwait, wk_list)
- if (wk->wk_type == D_NEWDIRBLK &&
- WK_NEWDIRBLK(wk)->db_pagedep ==
- pagedep)
- break;
- if (wk != NULL) {
- WORKLIST_REMOVE(wk);
- free_newdirblk(WK_NEWDIRBLK(wk));
- } else
- panic("deallocate_dependencies: "
- "lost pagedep");
+ newdirblk = pagedep->pd_newdirblk;
+ WORKLIST_REMOVE(&newdirblk->db_list);
+ free_newdirblk(newdirblk);
+ }
+ while ((jmvref = LIST_FIRST(&pagedep->pd_jmvrefhd))
+ != NULL) {
+ stat_jwait_filepage++;
+ jwait(&jmvref->jm_list);
+ return (0);
}
WORKLIST_REMOVE(&pagedep->pd_list);
LIST_REMOVE(pagedep, pd_hash);
@@ -2487,7 +5277,8 @@ deallocate_dependencies(bp, inodedep)
continue;
case D_ALLOCINDIR:
- free_allocindir(WK_ALLOCINDIR(wk), inodedep);
+ aip = WK_ALLOCINDIR(wk);
+ cancel_allocindir(aip, inodedep, freeblks);
continue;
case D_ALLOCDIRECT:
@@ -2502,46 +5293,155 @@ deallocate_dependencies(bp, inodedep)
/* NOTREACHED */
}
}
+
+ return (1);
}
/*
- * Free an allocdirect. Generate a new freefrag work request if appropriate.
- * This routine must be called with splbio interrupts blocked.
+ * An allocdirect is being canceled due to a truncate. We must make sure
+ * the journal entry is released in concert with the blkfree that releases
+ * the storage. Completed journal entries must not be released until the
+ * space is no longer pointed to by the inode or in the bitmap.
*/
static void
-free_allocdirect(adphead, adp, delay)
+cancel_allocdirect(adphead, adp, freeblks, delay)
struct allocdirectlst *adphead;
struct allocdirect *adp;
+ struct freeblks *freeblks;
int delay;
{
+ struct freework *freework;
+ struct newblk *newblk;
+ struct worklist *wk;
+ ufs_lbn_t lbn;
+
+ TAILQ_REMOVE(adphead, adp, ad_next);
+ newblk = (struct newblk *)adp;
+ /*
+ * If the journal hasn't been written the jnewblk must be passed
+ * to the call to ffs_freeblk that reclaims the space. We accomplish
+ * this by linking the journal dependency into the freework to be
+ * freed when freework_freeblock() is called. If the journal has
+ * been written we can simply reclaim the journal space when the
+ * freeblks work is complete.
+ */
+ if (newblk->nb_jnewblk == NULL) {
+ cancel_newblk(newblk, &freeblks->fb_jwork);
+ goto found;
+ }
+ lbn = newblk->nb_jnewblk->jn_lbn;
+ /*
+ * Find the correct freework structure so it releases the canceled
+ * journal when the bitmap is cleared. This preserves rollback
+ * until the allocation is reverted.
+ */
+ LIST_FOREACH(wk, &freeblks->fb_freeworkhd, wk_list) {
+ freework = WK_FREEWORK(wk);
+ if (freework->fw_lbn != lbn)
+ continue;
+ cancel_newblk(newblk, &freework->fw_jwork);
+ goto found;
+ }
+ panic("cancel_allocdirect: Freework not found for lbn %jd\n", lbn);
+found:
+ if (delay)
+ WORKLIST_INSERT(&adp->ad_inodedep->id_bufwait,
+ &newblk->nb_list);
+ else
+ free_newblk(newblk);
+ return;
+}
+
+
+static void
+cancel_newblk(newblk, wkhd)
+ struct newblk *newblk;
+ struct workhead *wkhd;
+{
+ struct indirdep *indirdep;
+ struct allocindir *aip;
+
+ while ((indirdep = LIST_FIRST(&newblk->nb_indirdeps)) != NULL) {
+ indirdep->ir_state &= ~ONDEPLIST;
+ LIST_REMOVE(indirdep, ir_next);
+ /*
+ * If an indirdep is not on the buf worklist we need to
+ * free it here as deallocate_dependencies() will never
+ * find it. These pointers were never visible on disk and
+ * can be discarded immediately.
+ */
+ while ((aip = LIST_FIRST(&indirdep->ir_completehd)) != NULL) {
+ LIST_REMOVE(aip, ai_next);
+ cancel_newblk(&aip->ai_block, wkhd);
+ free_newblk(&aip->ai_block);
+ }
+ /*
+ * If this indirdep is not attached to a buf it was simply
+ * waiting on completion to clear completehd. free_indirdep()
+ * asserts that nothing is dangling.
+ */
+ if ((indirdep->ir_state & ONWORKLIST) == 0)
+ free_indirdep(indirdep);
+ }
+ if (newblk->nb_state & ONDEPLIST) {
+ newblk->nb_state &= ~ONDEPLIST;
+ LIST_REMOVE(newblk, nb_deps);
+ }
+ if (newblk->nb_state & ONWORKLIST)
+ WORKLIST_REMOVE(&newblk->nb_list);
+ /*
+ * If the journal entry hasn't been written we hold onto the dep
+ * until it is safe to free along with the other journal work.
+ */
+ if (newblk->nb_jnewblk != NULL) {
+ cancel_jnewblk(newblk->nb_jnewblk, wkhd);
+ newblk->nb_jnewblk = NULL;
+ }
+ if (!LIST_EMPTY(&newblk->nb_jwork))
+ jwork_move(wkhd, &newblk->nb_jwork);
+}
+
+/*
+ * Free a newblk. Generate a new freefrag work request if appropriate.
+ * This must be called after the inode pointer and any direct block pointers
+ * are valid or fully removed via truncate or frag extension.
+ */
+static void
+free_newblk(newblk)
+ struct newblk *newblk;
+{
+ struct indirdep *indirdep;
struct newdirblk *newdirblk;
+ struct freefrag *freefrag;
struct worklist *wk;
mtx_assert(&lk, MA_OWNED);
- if ((adp->ad_state & DEPCOMPLETE) == 0)
- LIST_REMOVE(adp, ad_deps);
- TAILQ_REMOVE(adphead, adp, ad_next);
- if ((adp->ad_state & COMPLETE) == 0)
- WORKLIST_REMOVE(&adp->ad_list);
- if (adp->ad_freefrag != NULL) {
- if (delay)
- WORKLIST_INSERT(&adp->ad_inodedep->id_bufwait,
- &adp->ad_freefrag->ff_list);
- else
- add_to_worklist(&adp->ad_freefrag->ff_list);
+ if (newblk->nb_state & ONDEPLIST)
+ LIST_REMOVE(newblk, nb_deps);
+ if (newblk->nb_state & ONWORKLIST)
+ WORKLIST_REMOVE(&newblk->nb_list);
+ LIST_REMOVE(newblk, nb_hash);
+ if ((freefrag = newblk->nb_freefrag) != NULL) {
+ freefrag->ff_state |= COMPLETE;
+ if ((freefrag->ff_state & ALLCOMPLETE) == ALLCOMPLETE)
+ add_to_worklist(&freefrag->ff_list, 0);
}
- if ((wk = LIST_FIRST(&adp->ad_newdirblk)) != NULL) {
+ if ((wk = LIST_FIRST(&newblk->nb_newdirblk)) != NULL) {
newdirblk = WK_NEWDIRBLK(wk);
WORKLIST_REMOVE(&newdirblk->db_list);
- if (!LIST_EMPTY(&adp->ad_newdirblk))
- panic("free_allocdirect: extra newdirblk");
- if (delay)
- WORKLIST_INSERT(&adp->ad_inodedep->id_bufwait,
- &newdirblk->db_list);
- else
- free_newdirblk(newdirblk);
- }
- WORKITEM_FREE(adp, D_ALLOCDIRECT);
+ if (!LIST_EMPTY(&newblk->nb_newdirblk))
+ panic("free_newblk: extra newdirblk");
+ free_newdirblk(newdirblk);
+ }
+ while ((indirdep = LIST_FIRST(&newblk->nb_indirdeps)) != NULL) {
+ indirdep->ir_state |= DEPCOMPLETE;
+ indirdep_complete(indirdep);
+ }
+ KASSERT(newblk->nb_jnewblk == NULL,
+ ("free_newblk; jnewblk %p still attached", newblk->nb_jnewblk));
+ handle_jwork(&newblk->nb_jwork);
+ newblk->nb_list.wk_type = D_NEWBLK;
+ WORKITEM_FREE(newblk, D_NEWBLK);
}
/*
@@ -2554,6 +5454,7 @@ free_newdirblk(newdirblk)
{
struct pagedep *pagedep;
struct diradd *dap;
+ struct worklist *wk;
int i;
mtx_assert(&lk, MA_OWNED);
@@ -2571,17 +5472,25 @@ free_newdirblk(newdirblk)
pagedep->pd_state &= ~NEWBLOCK;
if ((pagedep->pd_state & ONWORKLIST) == 0)
while ((dap = LIST_FIRST(&pagedep->pd_pendinghd)) != NULL)
- free_diradd(dap);
+ free_diradd(dap, NULL);
/*
* If no dependencies remain, the pagedep will be freed.
*/
for (i = 0; i < DAHASHSZ; i++)
if (!LIST_EMPTY(&pagedep->pd_diraddhd[i]))
break;
- if (i == DAHASHSZ && (pagedep->pd_state & ONWORKLIST) == 0) {
+ if (i == DAHASHSZ && (pagedep->pd_state & ONWORKLIST) == 0 &&
+ LIST_EMPTY(&pagedep->pd_jmvrefhd)) {
+ KASSERT(LIST_FIRST(&pagedep->pd_dirremhd) == NULL,
+ ("free_newdirblk: Freeing non-free pagedep %p", pagedep));
LIST_REMOVE(pagedep, pd_hash);
WORKITEM_FREE(pagedep, D_PAGEDEP);
}
+ /* Should only ever be one item in the list. */
+ while ((wk = LIST_FIRST(&newdirblk->db_mkdir)) != NULL) {
+ WORKLIST_REMOVE(wk);
+ handle_written_mkdir(WK_MKDIR(wk), MKDIR_BODY);
+ }
WORKITEM_FREE(newdirblk, D_NEWDIRBLK);
}
@@ -2608,6 +5517,7 @@ softdep_freefile(pvp, ino, mode)
freefile->fx_mode = mode;
freefile->fx_oldinum = ino;
freefile->fx_devvp = ip->i_devvp;
+ LIST_INIT(&freefile->fx_jwork);
if ((ip->i_flag & IN_SPACECOUNTED) == 0) {
UFS_LOCK(ip->i_ump);
ip->i_fs->fs_pendinginodes += 1;
@@ -2618,11 +5528,34 @@ softdep_freefile(pvp, ino, mode)
* If the inodedep does not exist, then the zero'ed inode has
* been written to disk. If the allocated inode has never been
* written to disk, then the on-disk inode is zero'ed. In either
- * case we can free the file immediately.
+ * case we can free the file immediately. If the journal was
+ * canceled before being written the inode will never make it to
+ * disk and we must send the canceled journal entrys to
+ * ffs_freefile() to be cleared in conjunction with the bitmap.
+ * Any blocks waiting on the inode to write can be safely freed
+ * here as it will never been written.
*/
ACQUIRE_LOCK(&lk);
- if (inodedep_lookup(pvp->v_mount, ino, 0, &inodedep) == 0 ||
- check_inode_unwritten(inodedep)) {
+ inodedep_lookup(pvp->v_mount, ino, 0, &inodedep);
+ /*
+ * Remove this inode from the unlinked list and set
+ * GOINGAWAY as appropriate to indicate that this inode
+ * will never be written.
+ */
+ if (inodedep && inodedep->id_state & UNLINKED) {
+ /*
+ * Save the journal work to be freed with the bitmap
+ * before we clear UNLINKED. Otherwise it can be lost
+ * if the inode block is written.
+ */
+ handle_bufwait(inodedep, &freefile->fx_jwork);
+ clear_unlinked_inodedep(inodedep);
+ /* Re-acquire inodedep as we've dropped lk. */
+ inodedep_lookup(pvp->v_mount, ino, 0, &inodedep);
+ if (inodedep && (inodedep->id_state & DEPCOMPLETE) == 0)
+ inodedep->id_state |= GOINGAWAY;
+ }
+ if (inodedep == NULL || check_inode_unwritten(inodedep)) {
FREE_LOCK(&lk);
handle_workitem_freefile(freefile);
return;
@@ -2654,7 +5587,8 @@ check_inode_unwritten(inodedep)
{
mtx_assert(&lk, MA_OWNED);
- if ((inodedep->id_state & DEPCOMPLETE) != 0 ||
+
+ if ((inodedep->id_state & (DEPCOMPLETE | UNLINKED)) != 0 ||
!LIST_EMPTY(&inodedep->id_pendinghd) ||
!LIST_EMPTY(&inodedep->id_bufwait) ||
!LIST_EMPTY(&inodedep->id_inowait) ||
@@ -2662,9 +5596,9 @@ check_inode_unwritten(inodedep)
!TAILQ_EMPTY(&inodedep->id_newinoupdt) ||
!TAILQ_EMPTY(&inodedep->id_extupdt) ||
!TAILQ_EMPTY(&inodedep->id_newextupdt) ||
+ inodedep->id_mkdiradd != NULL ||
inodedep->id_nlinkdelta != 0)
return (0);
-
/*
* Another process might be in initiate_write_inodeblock_ufs[12]
* trying to allocate memory without holding "Softdep Lock".
@@ -2673,9 +5607,11 @@ check_inode_unwritten(inodedep)
inodedep->id_savedino1 == NULL)
return (0);
+ if (inodedep->id_state & ONDEPLIST)
+ LIST_REMOVE(inodedep, id_deps);
+ inodedep->id_state &= ~ONDEPLIST;
inodedep->id_state |= ALLCOMPLETE;
- LIST_REMOVE(inodedep, id_deps);
- inodedep->id_buf = NULL;
+ inodedep->id_bmsafemap = NULL;
if (inodedep->id_state & ONWORKLIST)
WORKLIST_REMOVE(&inodedep->id_list);
if (inodedep->id_savedino1 != NULL) {
@@ -2696,17 +5632,23 @@ free_inodedep(inodedep)
{
mtx_assert(&lk, MA_OWNED);
- if ((inodedep->id_state & ONWORKLIST) != 0 ||
+ if ((inodedep->id_state & (ONWORKLIST | UNLINKED)) != 0 ||
(inodedep->id_state & ALLCOMPLETE) != ALLCOMPLETE ||
+ !LIST_EMPTY(&inodedep->id_dirremhd) ||
!LIST_EMPTY(&inodedep->id_pendinghd) ||
!LIST_EMPTY(&inodedep->id_bufwait) ||
!LIST_EMPTY(&inodedep->id_inowait) ||
+ !TAILQ_EMPTY(&inodedep->id_inoreflst) ||
!TAILQ_EMPTY(&inodedep->id_inoupdt) ||
!TAILQ_EMPTY(&inodedep->id_newinoupdt) ||
!TAILQ_EMPTY(&inodedep->id_extupdt) ||
!TAILQ_EMPTY(&inodedep->id_newextupdt) ||
- inodedep->id_nlinkdelta != 0 || inodedep->id_savedino1 != NULL)
+ inodedep->id_mkdiradd != NULL ||
+ inodedep->id_nlinkdelta != 0 ||
+ inodedep->id_savedino1 != NULL)
return (0);
+ if (inodedep->id_state & ONDEPLIST)
+ LIST_REMOVE(inodedep, id_deps);
LIST_REMOVE(inodedep, id_hash);
WORKITEM_FREE(inodedep, D_INODEDEP);
num_inodedep -= 1;
@@ -2714,6 +5656,126 @@ free_inodedep(inodedep)
}
/*
+ * Free the block referenced by a freework structure. The parent freeblks
+ * structure is released and completed when the final cg bitmap reaches
+ * the disk. This routine may be freeing a jnewblk which never made it to
+ * disk in which case we do not have to wait as the operation is undone
+ * in memory immediately.
+ */
+static void
+freework_freeblock(freework)
+ struct freework *freework;
+{
+ struct freeblks *freeblks;
+ struct ufsmount *ump;
+ struct workhead wkhd;
+ struct fs *fs;
+ int complete;
+ int pending;
+ int bsize;
+ int needj;
+
+ freeblks = freework->fw_freeblks;
+ ump = VFSTOUFS(freeblks->fb_list.wk_mp);
+ fs = ump->um_fs;
+ needj = freeblks->fb_list.wk_mp->mnt_kern_flag & MNTK_SUJ;
+ complete = 0;
+ LIST_INIT(&wkhd);
+ /*
+ * If we are canceling an existing jnewblk pass it to the free
+ * routine, otherwise pass the freeblk which will ultimately
+ * release the freeblks. If we're not journaling, we can just
+ * free the freeblks immediately.
+ */
+ if (!LIST_EMPTY(&freework->fw_jwork)) {
+ LIST_SWAP(&wkhd, &freework->fw_jwork, worklist, wk_list);
+ complete = 1;
+ } else if (needj)
+ WORKLIST_INSERT_UNLOCKED(&wkhd, &freework->fw_list);
+ bsize = lfragtosize(fs, freework->fw_frags);
+ pending = btodb(bsize);
+ ACQUIRE_LOCK(&lk);
+ freeblks->fb_chkcnt -= pending;
+ FREE_LOCK(&lk);
+ /*
+ * extattr blocks don't show up in pending blocks. XXX why?
+ */
+ if (freework->fw_lbn >= 0 || freework->fw_lbn <= -NDADDR) {
+ UFS_LOCK(ump);
+ fs->fs_pendingblocks -= pending;
+ UFS_UNLOCK(ump);
+ }
+ ffs_blkfree(ump, fs, freeblks->fb_devvp, freework->fw_blkno,
+ bsize, freeblks->fb_previousinum, &wkhd);
+ if (complete == 0 && needj)
+ return;
+ /*
+ * The jnewblk will be discarded and the bits in the map never
+ * made it to disk. We can immediately free the freeblk.
+ */
+ ACQUIRE_LOCK(&lk);
+ handle_written_freework(freework);
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Start, continue, or finish the process of freeing an indirect block tree.
+ * The free operation may be paused at any point with fw_off containing the
+ * offset to restart from. This enables us to implement some flow control
+ * for large truncates which may fan out and generate a huge number of
+ * dependencies.
+ */
+static void
+handle_workitem_indirblk(freework)
+ struct freework *freework;
+{
+ struct freeblks *freeblks;
+ struct ufsmount *ump;
+ struct fs *fs;
+
+
+ freeblks = freework->fw_freeblks;
+ ump = VFSTOUFS(freeblks->fb_list.wk_mp);
+ fs = ump->um_fs;
+ if (freework->fw_off == NINDIR(fs))
+ freework_freeblock(freework);
+ else
+ indir_trunc(freework, fsbtodb(fs, freework->fw_blkno),
+ freework->fw_lbn);
+}
+
+/*
+ * Called when a freework structure attached to a cg buf is written. The
+ * ref on either the parent or the freeblks structure is released and
+ * either may be added to the worklist if it is the final ref.
+ */
+static void
+handle_written_freework(freework)
+ struct freework *freework;
+{
+ struct freeblks *freeblks;
+ struct freework *parent;
+
+ freeblks = freework->fw_freeblks;
+ parent = freework->fw_parent;
+ if (parent) {
+ if (--parent->fw_ref != 0)
+ parent = NULL;
+ freeblks = NULL;
+ } else if (--freeblks->fb_ref != 0)
+ freeblks = NULL;
+ WORKITEM_FREE(freework, D_FREEWORK);
+ /*
+ * Don't delay these block frees or it takes an intolerable amount
+ * of time to process truncates and free their journal entries.
+ */
+ if (freeblks)
+ add_to_worklist(&freeblks->fb_list, 1);
+ if (parent)
+ add_to_worklist(&parent->fw_list, 1);
+}
+
+/*
* This workitem routine performs the block de-allocation.
* The workitem is added to the pending list after the updated
* inode block has been written to disk. As mentioned above,
@@ -2726,99 +5788,79 @@ handle_workitem_freeblocks(freeblks, flags)
struct freeblks *freeblks;
int flags;
{
+ struct freework *freework;
+ struct worklist *wk;
+
+ KASSERT(LIST_EMPTY(&freeblks->fb_jfreeblkhd),
+ ("handle_workitem_freeblocks: Journal entries not written."));
+ if (LIST_EMPTY(&freeblks->fb_freeworkhd)) {
+ handle_complete_freeblocks(freeblks);
+ return;
+ }
+ freeblks->fb_ref++;
+ while ((wk = LIST_FIRST(&freeblks->fb_freeworkhd)) != NULL) {
+ KASSERT(wk->wk_type == D_FREEWORK,
+ ("handle_workitem_freeblocks: Unknown type %s",
+ TYPENAME(wk->wk_type)));
+ WORKLIST_REMOVE_UNLOCKED(wk);
+ freework = WK_FREEWORK(wk);
+ if (freework->fw_lbn <= -NDADDR)
+ handle_workitem_indirblk(freework);
+ else
+ freework_freeblock(freework);
+ }
+ ACQUIRE_LOCK(&lk);
+ if (--freeblks->fb_ref != 0)
+ freeblks = NULL;
+ FREE_LOCK(&lk);
+ if (freeblks)
+ handle_complete_freeblocks(freeblks);
+}
+
+/*
+ * Once all of the freework workitems are complete we can retire the
+ * freeblocks dependency and any journal work awaiting completion. This
+ * can not be called until all other dependencies are stable on disk.
+ */
+static void
+handle_complete_freeblocks(freeblks)
+ struct freeblks *freeblks;
+{
struct inode *ip;
struct vnode *vp;
struct fs *fs;
struct ufsmount *ump;
- int i, nblocks, level, bsize;
- ufs2_daddr_t bn, blocksreleased = 0;
- int error, allerror = 0;
- ufs_lbn_t baselbns[NIADDR], tmpval;
- int fs_pendingblocks;
+ int flags;
ump = VFSTOUFS(freeblks->fb_list.wk_mp);
fs = ump->um_fs;
- fs_pendingblocks = 0;
- tmpval = 1;
- baselbns[0] = NDADDR;
- for (i = 1; i < NIADDR; i++) {
- tmpval *= NINDIR(fs);
- baselbns[i] = baselbns[i - 1] + tmpval;
- }
- nblocks = btodb(fs->fs_bsize);
- blocksreleased = 0;
- /*
- * Release all extended attribute blocks or frags.
- */
- if (freeblks->fb_oldextsize > 0) {
- for (i = (NXADDR - 1); i >= 0; i--) {
- if ((bn = freeblks->fb_eblks[i]) == 0)
- continue;
- bsize = sblksize(fs, freeblks->fb_oldextsize, i);
- ffs_blkfree(ump, fs, freeblks->fb_devvp, bn, bsize,
- freeblks->fb_previousinum);
- blocksreleased += btodb(bsize);
- }
- }
- /*
- * Release all data blocks or frags.
- */
- if (freeblks->fb_oldsize > 0) {
- /*
- * Indirect blocks first.
- */
- for (level = (NIADDR - 1); level >= 0; level--) {
- if ((bn = freeblks->fb_iblks[level]) == 0)
- continue;
- if ((error = indir_trunc(freeblks, fsbtodb(fs, bn),
- level, baselbns[level], &blocksreleased)) != 0)
- allerror = error;
- ffs_blkfree(ump, fs, freeblks->fb_devvp, bn,
- fs->fs_bsize, freeblks->fb_previousinum);
- fs_pendingblocks += nblocks;
- blocksreleased += nblocks;
- }
- /*
- * All direct blocks or frags.
- */
- for (i = (NDADDR - 1); i >= 0; i--) {
- if ((bn = freeblks->fb_dblks[i]) == 0)
- continue;
- bsize = sblksize(fs, freeblks->fb_oldsize, i);
- ffs_blkfree(ump, fs, freeblks->fb_devvp, bn, bsize,
- freeblks->fb_previousinum);
- fs_pendingblocks += btodb(bsize);
- blocksreleased += btodb(bsize);
- }
- }
- UFS_LOCK(ump);
- fs->fs_pendingblocks -= fs_pendingblocks;
- UFS_UNLOCK(ump);
+ flags = LK_NOWAIT;
+
/*
* If we still have not finished background cleanup, then check
* to see if the block count needs to be adjusted.
*/
- if (freeblks->fb_chkcnt != blocksreleased &&
- (fs->fs_flags & FS_UNCLEAN) != 0 &&
+ if (freeblks->fb_chkcnt != 0 && (fs->fs_flags & FS_UNCLEAN) != 0 &&
ffs_vgetf(freeblks->fb_list.wk_mp, freeblks->fb_previousinum,
- (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ)
- == 0) {
+ (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ) == 0) {
ip = VTOI(vp);
- DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + \
- freeblks->fb_chkcnt - blocksreleased);
+ DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + freeblks->fb_chkcnt);
ip->i_flag |= IN_CHANGE;
vput(vp);
}
#ifdef INVARIANTS
- if (freeblks->fb_chkcnt != blocksreleased &&
+ if (freeblks->fb_chkcnt != 0 &&
((fs->fs_flags & FS_UNCLEAN) == 0 || (flags & LK_NOWAIT) != 0))
printf("handle_workitem_freeblocks: block count\n");
- if (allerror)
- softdep_error("handle_workitem_freeblks", allerror);
#endif /* INVARIANTS */
ACQUIRE_LOCK(&lk);
+ /*
+ * All of the freeblock deps must be complete prior to this call
+ * so it's now safe to complete earlier outstanding journal entries.
+ */
+ handle_jwork(&freeblks->fb_jwork);
WORKITEM_FREE(freeblks, D_FREEBLKS);
num_freeblkdep--;
FREE_LOCK(&lk);
@@ -2830,29 +5872,42 @@ handle_workitem_freeblocks(freeblks, flags)
* and recursive calls to indirtrunc must be used to cleanse other indirect
* blocks.
*/
-static int
-indir_trunc(freeblks, dbn, level, lbn, countp)
- struct freeblks *freeblks;
+static void
+indir_trunc(freework, dbn, lbn)
+ struct freework *freework;
ufs2_daddr_t dbn;
- int level;
ufs_lbn_t lbn;
- ufs2_daddr_t *countp;
{
+ struct freework *nfreework;
+ struct workhead wkhd;
+ struct jnewblk *jnewblk;
+ struct freeblks *freeblks;
struct buf *bp;
struct fs *fs;
+ struct worklist *wkn;
struct worklist *wk;
struct indirdep *indirdep;
struct ufsmount *ump;
ufs1_daddr_t *bap1 = 0;
- ufs2_daddr_t nb, *bap2 = 0;
+ ufs2_daddr_t nb, nnb, *bap2 = 0;
ufs_lbn_t lbnadd;
int i, nblocks, ufs1fmt;
- int error, allerror = 0;
int fs_pendingblocks;
+ int freedeps;
+ int needj;
+ int level;
+ int cnt;
+ LIST_INIT(&wkhd);
+ level = lbn_level(lbn);
+ if (level == -1)
+ panic("indir_trunc: Invalid lbn %jd\n", lbn);
+ freeblks = freework->fw_freeblks;
ump = VFSTOUFS(freeblks->fb_list.wk_mp);
fs = ump->um_fs;
fs_pendingblocks = 0;
+ freedeps = 0;
+ needj = UFSTOVFS(ump)->mnt_kern_flag & MNTK_SUJ;
lbnadd = 1;
for (i = level; i > 0; i--)
lbnadd *= NINDIR(fs);
@@ -2877,13 +5932,14 @@ indir_trunc(freeblks, dbn, level, lbn, countp)
ACQUIRE_LOCK(&lk);
if (bp != NULL && (wk = LIST_FIRST(&bp->b_dep)) != NULL) {
if (wk->wk_type != D_INDIRDEP ||
- (indirdep = WK_INDIRDEP(wk))->ir_savebp != bp ||
- (indirdep->ir_state & GOINGAWAY) == 0)
- panic("indir_trunc: lost indirdep");
- WORKLIST_REMOVE(wk);
- WORKITEM_FREE(indirdep, D_INDIRDEP);
+ (wk->wk_state & GOINGAWAY) == 0)
+ panic("indir_trunc: lost indirdep %p", wk);
+ indirdep = WK_INDIRDEP(wk);
+ LIST_SWAP(&wkhd, &indirdep->ir_jwork, worklist, wk_list);
+ free_indirdep(indirdep);
if (!LIST_EMPTY(&bp->b_dep))
- panic("indir_trunc: dangling dep");
+ panic("indir_trunc: dangling dep %p",
+ LIST_FIRST(&bp->b_dep));
ump->um_numindirdeps -= 1;
FREE_LOCK(&lk);
} else {
@@ -2892,11 +5948,10 @@ indir_trunc(freeblks, dbn, level, lbn, countp)
brelse(bp);
#endif
FREE_LOCK(&lk);
- error = bread(freeblks->fb_devvp, dbn, (int)fs->fs_bsize,
- NOCRED, &bp);
- if (error) {
+ if (bread(freeblks->fb_devvp, dbn, (int)fs->fs_bsize,
+ NOCRED, &bp) != 0) {
brelse(bp);
- return (error);
+ return;
}
}
/*
@@ -2909,57 +5964,264 @@ indir_trunc(freeblks, dbn, level, lbn, countp)
ufs1fmt = 0;
bap2 = (ufs2_daddr_t *)bp->b_data;
}
- nblocks = btodb(fs->fs_bsize);
- for (i = NINDIR(fs) - 1; i >= 0; i--) {
- if (ufs1fmt)
- nb = bap1[i];
+ /*
+ * Reclaim indirect blocks which never made it to disk.
+ */
+ cnt = 0;
+ LIST_FOREACH_SAFE(wk, &wkhd, wk_list, wkn) {
+ struct workhead freewk;
+ if (wk->wk_type != D_JNEWBLK)
+ continue;
+ WORKLIST_REMOVE_UNLOCKED(wk);
+ LIST_INIT(&freewk);
+ WORKLIST_INSERT_UNLOCKED(&freewk, wk);
+ jnewblk = WK_JNEWBLK(wk);
+ if (jnewblk->jn_lbn > 0)
+ i = (jnewblk->jn_lbn - -lbn) / lbnadd;
else
+ i = (jnewblk->jn_lbn - (lbn + 1)) / lbnadd;
+ KASSERT(i >= 0 && i < NINDIR(fs),
+ ("indir_trunc: Index out of range %d parent %jd lbn %jd",
+ i, lbn, jnewblk->jn_lbn));
+ /* Clear the pointer so it isn't found below. */
+ if (ufs1fmt) {
+ nb = bap1[i];
+ bap1[i] = 0;
+ } else {
nb = bap2[i];
+ bap2[i] = 0;
+ }
+ KASSERT(nb == jnewblk->jn_blkno,
+ ("indir_trunc: Block mismatch %jd != %jd",
+ nb, jnewblk->jn_blkno));
+ ffs_blkfree(ump, fs, freeblks->fb_devvp, jnewblk->jn_blkno,
+ fs->fs_bsize, freeblks->fb_previousinum, &freewk);
+ cnt++;
+ }
+ ACQUIRE_LOCK(&lk);
+ if (needj)
+ freework->fw_ref += NINDIR(fs) + 1;
+ /* Any remaining journal work can be completed with freeblks. */
+ jwork_move(&freeblks->fb_jwork, &wkhd);
+ FREE_LOCK(&lk);
+ nblocks = btodb(fs->fs_bsize);
+ if (ufs1fmt)
+ nb = bap1[0];
+ else
+ nb = bap2[0];
+ nfreework = freework;
+ /*
+ * Reclaim on disk blocks.
+ */
+ for (i = freework->fw_off; i < NINDIR(fs); i++, nb = nnb) {
+ if (i != NINDIR(fs) - 1) {
+ if (ufs1fmt)
+ nnb = bap1[i+1];
+ else
+ nnb = bap2[i+1];
+ } else
+ nnb = 0;
if (nb == 0)
continue;
+ cnt++;
if (level != 0) {
- if ((error = indir_trunc(freeblks, fsbtodb(fs, nb),
- level - 1, lbn + (i * lbnadd), countp)) != 0)
- allerror = error;
+ ufs_lbn_t nlbn;
+
+ nlbn = (lbn + 1) - (i * lbnadd);
+ if (needj != 0) {
+ nfreework = newfreework(freeblks, freework,
+ nlbn, nb, fs->fs_frag, 0);
+ freedeps++;
+ }
+ indir_trunc(nfreework, fsbtodb(fs, nb), nlbn);
+ } else {
+ struct freedep *freedep;
+
+ /*
+ * Attempt to aggregate freedep dependencies for
+ * all blocks being released to the same CG.
+ */
+ LIST_INIT(&wkhd);
+ if (needj != 0 &&
+ (nnb == 0 || (dtog(fs, nb) != dtog(fs, nnb)))) {
+ freedep = newfreedep(freework);
+ WORKLIST_INSERT_UNLOCKED(&wkhd,
+ &freedep->fd_list);
+ freedeps++;
+ }
+ ffs_blkfree(ump, fs, freeblks->fb_devvp, nb,
+ fs->fs_bsize, freeblks->fb_previousinum, &wkhd);
}
- ffs_blkfree(ump, fs, freeblks->fb_devvp, nb, fs->fs_bsize,
- freeblks->fb_previousinum);
+ }
+ if (level == 0)
+ fs_pendingblocks = (nblocks * cnt);
+ /*
+ * If we're not journaling we can free the indirect now. Otherwise
+ * setup the ref counts and offset so this indirect can be completed
+ * when its children are free.
+ */
+ if (needj == 0) {
fs_pendingblocks += nblocks;
- *countp += nblocks;
+ dbn = dbtofsb(fs, dbn);
+ ffs_blkfree(ump, fs, freeblks->fb_devvp, dbn, fs->fs_bsize,
+ freeblks->fb_previousinum, NULL);
+ ACQUIRE_LOCK(&lk);
+ freeblks->fb_chkcnt -= fs_pendingblocks;
+ if (freework->fw_blkno == dbn)
+ handle_written_freework(freework);
+ FREE_LOCK(&lk);
+ freework = NULL;
+ } else {
+ ACQUIRE_LOCK(&lk);
+ freework->fw_off = i;
+ freework->fw_ref += freedeps;
+ freework->fw_ref -= NINDIR(fs) + 1;
+ if (freework->fw_ref != 0)
+ freework = NULL;
+ freeblks->fb_chkcnt -= fs_pendingblocks;
+ FREE_LOCK(&lk);
+ }
+ if (fs_pendingblocks) {
+ UFS_LOCK(ump);
+ fs->fs_pendingblocks -= fs_pendingblocks;
+ UFS_UNLOCK(ump);
}
- UFS_LOCK(ump);
- fs->fs_pendingblocks -= fs_pendingblocks;
- UFS_UNLOCK(ump);
bp->b_flags |= B_INVAL | B_NOCACHE;
brelse(bp);
- return (allerror);
+ if (freework)
+ handle_workitem_indirblk(freework);
+ return;
}
/*
- * Free an allocindir.
- * This routine must be called with splbio interrupts blocked.
+ * Cancel an allocindir when it is removed via truncation.
*/
static void
-free_allocindir(aip, inodedep)
+cancel_allocindir(aip, inodedep, freeblks)
struct allocindir *aip;
struct inodedep *inodedep;
+ struct freeblks *freeblks;
{
- struct freefrag *freefrag;
+ struct newblk *newblk;
- mtx_assert(&lk, MA_OWNED);
- if ((aip->ai_state & DEPCOMPLETE) == 0)
- LIST_REMOVE(aip, ai_deps);
- if (aip->ai_state & ONWORKLIST)
- WORKLIST_REMOVE(&aip->ai_list);
+ /*
+ * If the journal hasn't been written the jnewblk must be passed
+ * to the call to ffs_freeblk that reclaims the space. We accomplish
+ * this by linking the journal dependency into the indirdep to be
+ * freed when indir_trunc() is called. If the journal has already
+ * been written we can simply reclaim the journal space when the
+ * freeblks work is complete.
+ */
LIST_REMOVE(aip, ai_next);
- if ((freefrag = aip->ai_freefrag) != NULL) {
+ newblk = (struct newblk *)aip;
+ if (newblk->nb_jnewblk == NULL)
+ cancel_newblk(newblk, &freeblks->fb_jwork);
+ else
+ cancel_newblk(newblk, &aip->ai_indirdep->ir_jwork);
+ if (inodedep && inodedep->id_state & DEPCOMPLETE)
+ WORKLIST_INSERT(&inodedep->id_bufwait, &newblk->nb_list);
+ else
+ free_newblk(newblk);
+}
+
+/*
+ * Create the mkdir dependencies for . and .. in a new directory. Link them
+ * in to a newdirblk so any subsequent additions are tracked properly. The
+ * caller is responsible for adding the mkdir1 dependency to the journal
+ * and updating id_mkdiradd. This function returns with lk held.
+ */
+static struct mkdir *
+setup_newdir(dap, newinum, dinum, newdirbp, mkdirp)
+ struct diradd *dap;
+ ino_t newinum;
+ ino_t dinum;
+ struct buf *newdirbp;
+ struct mkdir **mkdirp;
+{
+ struct newblk *newblk;
+ struct pagedep *pagedep;
+ struct inodedep *inodedep;
+ struct newdirblk *newdirblk = 0;
+ struct mkdir *mkdir1, *mkdir2;
+ struct worklist *wk;
+ struct jaddref *jaddref;
+ struct mount *mp;
+
+ mp = dap->da_list.wk_mp;
+ newdirblk = malloc(sizeof(struct newdirblk), M_NEWDIRBLK,
+ M_SOFTDEP_FLAGS);
+ workitem_alloc(&newdirblk->db_list, D_NEWDIRBLK, mp);
+ LIST_INIT(&newdirblk->db_mkdir);
+ mkdir1 = malloc(sizeof(struct mkdir), M_MKDIR, M_SOFTDEP_FLAGS);
+ workitem_alloc(&mkdir1->md_list, D_MKDIR, mp);
+ mkdir1->md_state = ATTACHED | MKDIR_BODY;
+ mkdir1->md_diradd = dap;
+ mkdir1->md_jaddref = NULL;
+ mkdir2 = malloc(sizeof(struct mkdir), M_MKDIR, M_SOFTDEP_FLAGS);
+ workitem_alloc(&mkdir2->md_list, D_MKDIR, mp);
+ mkdir2->md_state = ATTACHED | MKDIR_PARENT;
+ mkdir2->md_diradd = dap;
+ mkdir2->md_jaddref = NULL;
+ if ((mp->mnt_kern_flag & MNTK_SUJ) == 0) {
+ mkdir1->md_state |= DEPCOMPLETE;
+ mkdir2->md_state |= DEPCOMPLETE;
+ }
+ /*
+ * Dependency on "." and ".." being written to disk.
+ */
+ mkdir1->md_buf = newdirbp;
+ ACQUIRE_LOCK(&lk);
+ LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
+ /*
+ * We must link the pagedep, allocdirect, and newdirblk for
+ * the initial file page so the pointer to the new directory
+ * is not written until the directory contents are live and
+ * any subsequent additions are not marked live until the
+ * block is reachable via the inode.
+ */
+ if (pagedep_lookup(mp, newinum, 0, 0, &pagedep) == 0)
+ panic("setup_newdir: lost pagedep");
+ LIST_FOREACH(wk, &newdirbp->b_dep, wk_list)
+ if (wk->wk_type == D_ALLOCDIRECT)
+ break;
+ if (wk == NULL)
+ panic("setup_newdir: lost allocdirect");
+ newblk = WK_NEWBLK(wk);
+ pagedep->pd_state |= NEWBLOCK;
+ pagedep->pd_newdirblk = newdirblk;
+ newdirblk->db_pagedep = pagedep;
+ WORKLIST_INSERT(&newblk->nb_newdirblk, &newdirblk->db_list);
+ WORKLIST_INSERT(&newdirblk->db_mkdir, &mkdir1->md_list);
+ /*
+ * Look up the inodedep for the parent directory so that we
+ * can link mkdir2 into the pending dotdot jaddref or
+ * the inode write if there is none. If the inode is
+ * ALLCOMPLETE and no jaddref is present all dependencies have
+ * been satisfied and mkdir2 can be freed.
+ */
+ inodedep_lookup(mp, dinum, 0, &inodedep);
+ if (mp->mnt_kern_flag & MNTK_SUJ) {
if (inodedep == NULL)
- add_to_worklist(&freefrag->ff_list);
- else
- WORKLIST_INSERT(&inodedep->id_bufwait,
- &freefrag->ff_list);
+ panic("setup_newdir: Lost parent.");
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref != NULL && jaddref->ja_parent == newinum &&
+ (jaddref->ja_state & MKDIR_PARENT),
+ ("setup_newdir: bad dotdot jaddref %p", jaddref));
+ LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
+ mkdir2->md_jaddref = jaddref;
+ jaddref->ja_mkdir = mkdir2;
+ } else if (inodedep == NULL ||
+ (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
+ dap->da_state &= ~MKDIR_PARENT;
+ WORKITEM_FREE(mkdir2, D_MKDIR);
+ } else {
+ LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
+ WORKLIST_INSERT(&inodedep->id_bufwait,&mkdir2->md_list);
}
- WORKITEM_FREE(aip, D_ALLOCINDIR);
+ *mkdirp = mkdir2;
+
+ return (mkdir1);
}
/*
@@ -2998,12 +6260,14 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk)
ufs_lbn_t lbn; /* block in directory containing new entry */
struct fs *fs;
struct diradd *dap;
- struct allocdirect *adp;
+ struct newblk *newblk;
struct pagedep *pagedep;
struct inodedep *inodedep;
struct newdirblk *newdirblk = 0;
struct mkdir *mkdir1, *mkdir2;
+ struct jaddref *jaddref;
struct mount *mp;
+ int isindir;
/*
* Whiteouts have no dependencies.
@@ -3013,6 +6277,8 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk)
bdwrite(newdirbp);
return (0);
}
+ jaddref = NULL;
+ mkdir1 = mkdir2 = NULL;
mp = UFSTOVFS(dp->i_ump);
fs = dp->i_fs;
lbn = lblkno(fs, diroffset);
@@ -3023,111 +6289,123 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk)
dap->da_offset = offset;
dap->da_newinum = newinum;
dap->da_state = ATTACHED;
- if (isnewblk && lbn < NDADDR && fragoff(fs, diroffset) == 0) {
+ LIST_INIT(&dap->da_jwork);
+ isindir = bp->b_lblkno >= NDADDR;
+ if (isnewblk &&
+ (isindir ? blkoff(fs, diroffset) : fragoff(fs, diroffset)) == 0) {
newdirblk = malloc(sizeof(struct newdirblk),
M_NEWDIRBLK, M_SOFTDEP_FLAGS);
workitem_alloc(&newdirblk->db_list, D_NEWDIRBLK, mp);
+ LIST_INIT(&newdirblk->db_mkdir);
}
+ /*
+ * If we're creating a new directory setup the dependencies and set
+ * the dap state to wait for them. Otherwise it's COMPLETE and
+ * we can move on.
+ */
if (newdirbp == NULL) {
dap->da_state |= DEPCOMPLETE;
ACQUIRE_LOCK(&lk);
} else {
dap->da_state |= MKDIR_BODY | MKDIR_PARENT;
- mkdir1 = malloc(sizeof(struct mkdir), M_MKDIR,
- M_SOFTDEP_FLAGS);
- workitem_alloc(&mkdir1->md_list, D_MKDIR, mp);
- mkdir1->md_state = MKDIR_BODY;
- mkdir1->md_diradd = dap;
- mkdir2 = malloc(sizeof(struct mkdir), M_MKDIR,
- M_SOFTDEP_FLAGS);
- workitem_alloc(&mkdir2->md_list, D_MKDIR, mp);
- mkdir2->md_state = MKDIR_PARENT;
- mkdir2->md_diradd = dap;
- /*
- * Dependency on "." and ".." being written to disk.
- */
- mkdir1->md_buf = newdirbp;
- ACQUIRE_LOCK(&lk);
- LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
- WORKLIST_INSERT(&newdirbp->b_dep, &mkdir1->md_list);
- FREE_LOCK(&lk);
- bdwrite(newdirbp);
- /*
- * Dependency on link count increase for parent directory
- */
- ACQUIRE_LOCK(&lk);
- if (inodedep_lookup(mp, dp->i_number, 0, &inodedep) == 0
- || (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
- dap->da_state &= ~MKDIR_PARENT;
- WORKITEM_FREE(mkdir2, D_MKDIR);
- } else {
- LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
- WORKLIST_INSERT(&inodedep->id_bufwait,&mkdir2->md_list);
- }
+ mkdir1 = setup_newdir(dap, newinum, dp->i_number, newdirbp,
+ &mkdir2);
}
/*
* Link into parent directory pagedep to await its being written.
*/
- if (pagedep_lookup(dp, lbn, DEPALLOC, &pagedep) == 0)
+ if (pagedep_lookup(mp, dp->i_number, lbn, DEPALLOC, &pagedep) == 0)
WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
+#ifdef DEBUG
+ if (diradd_lookup(pagedep, offset) != NULL)
+ panic("softdep_setup_directory_add: %p already at off %d\n",
+ diradd_lookup(pagedep, offset), offset);
+#endif
dap->da_pagedep = pagedep;
LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(offset)], dap,
da_pdlist);
+ inodedep_lookup(mp, newinum, DEPALLOC, &inodedep);
/*
- * Link into its inodedep. Put it on the id_bufwait list if the inode
- * is not yet written. If it is written, do the post-inode write
- * processing to put it on the id_pendinghd list.
+ * If we're journaling, link the diradd into the jaddref so it
+ * may be completed after the journal entry is written. Otherwise,
+ * link the diradd into its inodedep. If the inode is not yet
+ * written place it on the bufwait list, otherwise do the post-inode
+ * write processing to put it on the id_pendinghd list.
*/
- (void) inodedep_lookup(mp, newinum, DEPALLOC, &inodedep);
- if ((inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE)
+ if (mp->mnt_kern_flag & MNTK_SUJ) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref != NULL && jaddref->ja_parent == dp->i_number,
+ ("softdep_setup_directory_add: bad jaddref %p", jaddref));
+ jaddref->ja_diroff = diroffset;
+ jaddref->ja_diradd = dap;
+ add_to_journal(&jaddref->ja_list);
+ } else if ((inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE)
diradd_inode_written(dap, inodedep);
else
WORKLIST_INSERT(&inodedep->id_bufwait, &dap->da_list);
- if (isnewblk) {
+ /*
+ * Add the journal entries for . and .. links now that the primary
+ * link is written.
+ */
+ if (mkdir1 != NULL && mp->mnt_kern_flag & MNTK_SUJ) {
+ jaddref = (struct jaddref *)TAILQ_PREV(&jaddref->ja_ref,
+ inoreflst, if_deps);
+ KASSERT(jaddref != NULL &&
+ jaddref->ja_ino == jaddref->ja_parent &&
+ (jaddref->ja_state & MKDIR_BODY),
+ ("softdep_setup_directory_add: bad dot jaddref %p",
+ jaddref));
+ mkdir1->md_jaddref = jaddref;
+ jaddref->ja_mkdir = mkdir1;
/*
- * Directories growing into indirect blocks are rare
- * enough and the frequency of new block allocation
- * in those cases even more rare, that we choose not
- * to bother tracking them. Rather we simply force the
- * new directory entry to disk.
+ * It is important that the dotdot journal entry
+ * is added prior to the dot entry since dot writes
+ * both the dot and dotdot links. These both must
+ * be added after the primary link for the journal
+ * to remain consistent.
*/
- if (lbn >= NDADDR) {
- FREE_LOCK(&lk);
- /*
- * We only have a new allocation when at the
- * beginning of a new block, not when we are
- * expanding into an existing block.
- */
- if (blkoff(fs, diroffset) == 0)
- return (1);
- return (0);
- }
+ add_to_journal(&mkdir2->md_jaddref->ja_list);
+ add_to_journal(&jaddref->ja_list);
+ }
+ /*
+ * If we are adding a new directory remember this diradd so that if
+ * we rename it we can keep the dot and dotdot dependencies. If
+ * we are adding a new name for an inode that has a mkdiradd we
+ * must be in rename and we have to move the dot and dotdot
+ * dependencies to this new name. The old name is being orphaned
+ * soon.
+ */
+ if (mkdir1 != NULL) {
+ if (inodedep->id_mkdiradd != NULL)
+ panic("softdep_setup_directory_add: Existing mkdir");
+ inodedep->id_mkdiradd = dap;
+ } else if (inodedep->id_mkdiradd)
+ merge_diradd(inodedep, dap);
+ if (newdirblk) {
/*
- * We only have a new allocation when at the beginning
- * of a new fragment, not when we are expanding into an
- * existing fragment. Also, there is nothing to do if we
- * are already tracking this block.
+ * There is nothing to do if we are already tracking
+ * this block.
*/
- if (fragoff(fs, diroffset) != 0) {
- FREE_LOCK(&lk);
- return (0);
- }
if ((pagedep->pd_state & NEWBLOCK) != 0) {
WORKITEM_FREE(newdirblk, D_NEWDIRBLK);
FREE_LOCK(&lk);
return (0);
}
- /*
- * Find our associated allocdirect and have it track us.
- */
- if (inodedep_lookup(mp, dp->i_number, 0, &inodedep) == 0)
- panic("softdep_setup_directory_add: lost inodedep");
- adp = TAILQ_LAST(&inodedep->id_newinoupdt, allocdirectlst);
- if (adp == NULL || adp->ad_lbn != lbn)
+ if (newblk_lookup(mp, dbtofsb(fs, bp->b_blkno), 0, &newblk)
+ == 0)
panic("softdep_setup_directory_add: lost entry");
+ WORKLIST_INSERT(&newblk->nb_newdirblk, &newdirblk->db_list);
pagedep->pd_state |= NEWBLOCK;
+ pagedep->pd_newdirblk = newdirblk;
newdirblk->db_pagedep = pagedep;
- WORKLIST_INSERT(&adp->ad_newdirblk, &newdirblk->db_list);
+ FREE_LOCK(&lk);
+ /*
+ * If we extended into an indirect signal direnter to sync.
+ */
+ if (isindir)
+ return (1);
+ return (0);
}
FREE_LOCK(&lk);
return (0);
@@ -3141,7 +6419,8 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk)
* occur while the move is in progress.
*/
void
-softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize)
+softdep_change_directoryentry_offset(bp, dp, base, oldloc, newloc, entrysize)
+ struct buf *bp; /* Buffer holding directory block. */
struct inode *dp; /* inode for directory */
caddr_t base; /* address of dp->i_offset */
caddr_t oldloc; /* address of old directory location */
@@ -3150,40 +6429,204 @@ softdep_change_directoryentry_offset(dp, base, oldloc, newloc, entrysize)
{
int offset, oldoffset, newoffset;
struct pagedep *pagedep;
+ struct jmvref *jmvref;
struct diradd *dap;
+ struct direct *de;
+ struct mount *mp;
ufs_lbn_t lbn;
+ int flags;
- ACQUIRE_LOCK(&lk);
+ mp = UFSTOVFS(dp->i_ump);
+ de = (struct direct *)oldloc;
+ jmvref = NULL;
+ flags = 0;
+ /*
+ * Moves are always journaled as it would be too complex to
+ * determine if any affected adds or removes are present in the
+ * journal.
+ */
+ if (mp->mnt_kern_flag & MNTK_SUJ) {
+ flags = DEPALLOC;
+ jmvref = newjmvref(dp, de->d_ino,
+ dp->i_offset + (oldloc - base),
+ dp->i_offset + (newloc - base));
+ }
lbn = lblkno(dp->i_fs, dp->i_offset);
offset = blkoff(dp->i_fs, dp->i_offset);
- if (pagedep_lookup(dp, lbn, 0, &pagedep) == 0)
- goto done;
oldoffset = offset + (oldloc - base);
newoffset = offset + (newloc - base);
-
- LIST_FOREACH(dap, &pagedep->pd_diraddhd[DIRADDHASH(oldoffset)], da_pdlist) {
- if (dap->da_offset != oldoffset)
- continue;
+ ACQUIRE_LOCK(&lk);
+ if (pagedep_lookup(mp, dp->i_number, lbn, flags, &pagedep) == 0) {
+ if (pagedep)
+ WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
+ goto done;
+ }
+ dap = diradd_lookup(pagedep, oldoffset);
+ if (dap) {
dap->da_offset = newoffset;
- if (DIRADDHASH(newoffset) == DIRADDHASH(oldoffset))
- break;
- LIST_REMOVE(dap, da_pdlist);
- LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(newoffset)],
- dap, da_pdlist);
- break;
+ newoffset = DIRADDHASH(newoffset);
+ oldoffset = DIRADDHASH(oldoffset);
+ if ((dap->da_state & ALLCOMPLETE) != ALLCOMPLETE &&
+ newoffset != oldoffset) {
+ LIST_REMOVE(dap, da_pdlist);
+ LIST_INSERT_HEAD(&pagedep->pd_diraddhd[newoffset],
+ dap, da_pdlist);
+ }
}
- if (dap == NULL) {
+done:
+ if (jmvref) {
+ jmvref->jm_pagedep = pagedep;
+ LIST_INSERT_HEAD(&pagedep->pd_jmvrefhd, jmvref, jm_deps);
+ add_to_journal(&jmvref->jm_list);
+ }
+ bcopy(oldloc, newloc, entrysize);
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Move the mkdir dependencies and journal work from one diradd to another
+ * when renaming a directory. The new name must depend on the mkdir deps
+ * completing as the old name did. Directories can only have one valid link
+ * at a time so one must be canonical.
+ */
+static void
+merge_diradd(inodedep, newdap)
+ struct inodedep *inodedep;
+ struct diradd *newdap;
+{
+ struct diradd *olddap;
+ struct mkdir *mkdir, *nextmd;
+ short state;
- LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist) {
- if (dap->da_offset == oldoffset) {
- dap->da_offset = newoffset;
+ olddap = inodedep->id_mkdiradd;
+ inodedep->id_mkdiradd = newdap;
+ if ((olddap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
+ newdap->da_state &= ~DEPCOMPLETE;
+ for (mkdir = LIST_FIRST(&mkdirlisthd); mkdir; mkdir = nextmd) {
+ nextmd = LIST_NEXT(mkdir, md_mkdirs);
+ if (mkdir->md_diradd != olddap)
+ continue;
+ mkdir->md_diradd = newdap;
+ state = mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY);
+ newdap->da_state |= state;
+ olddap->da_state &= ~state;
+ if ((olddap->da_state &
+ (MKDIR_PARENT | MKDIR_BODY)) == 0)
break;
+ }
+ if ((olddap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
+ panic("merge_diradd: unfound ref");
+ }
+ /*
+ * Any mkdir related journal items are not safe to be freed until
+ * the new name is stable.
+ */
+ jwork_move(&newdap->da_jwork, &olddap->da_jwork);
+ olddap->da_state |= DEPCOMPLETE;
+ complete_diradd(olddap);
+}
+
+/*
+ * Move the diradd to the pending list when all diradd dependencies are
+ * complete.
+ */
+static void
+complete_diradd(dap)
+ struct diradd *dap;
+{
+ struct pagedep *pagedep;
+
+ if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
+ if (dap->da_state & DIRCHG)
+ pagedep = dap->da_previous->dm_pagedep;
+ else
+ pagedep = dap->da_pagedep;
+ LIST_REMOVE(dap, da_pdlist);
+ LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
+ }
+}
+
+/*
+ * Cancel a diradd when a dirrem overlaps with it. We must cancel the journal
+ * add entries and conditonally journal the remove.
+ */
+static void
+cancel_diradd(dap, dirrem, jremref, dotremref, dotdotremref)
+ struct diradd *dap;
+ struct dirrem *dirrem;
+ struct jremref *jremref;
+ struct jremref *dotremref;
+ struct jremref *dotdotremref;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct inoref *inoref;
+ struct mkdir *mkdir;
+
+ /*
+ * If no remove references were allocated we're on a non-journaled
+ * filesystem and can skip the cancel step.
+ */
+ if (jremref == NULL) {
+ free_diradd(dap, NULL);
+ return;
+ }
+ /*
+ * Cancel the primary name an free it if it does not require
+ * journaling.
+ */
+ if (inodedep_lookup(dap->da_list.wk_mp, dap->da_newinum,
+ 0, &inodedep) != 0) {
+ /* Abort the addref that reference this diradd. */
+ TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
+ if (inoref->if_list.wk_type != D_JADDREF)
+ continue;
+ jaddref = (struct jaddref *)inoref;
+ if (jaddref->ja_diradd != dap)
+ continue;
+ if (cancel_jaddref(jaddref, inodedep,
+ &dirrem->dm_jwork) == 0) {
+ free_jremref(jremref);
+ jremref = NULL;
}
+ break;
}
}
-done:
- bcopy(oldloc, newloc, entrysize);
- FREE_LOCK(&lk);
+ /*
+ * Cancel subordinate names and free them if they do not require
+ * journaling.
+ */
+ if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
+ LIST_FOREACH(mkdir, &mkdirlisthd, md_mkdirs) {
+ if (mkdir->md_diradd != dap)
+ continue;
+ if ((jaddref = mkdir->md_jaddref) == NULL)
+ continue;
+ mkdir->md_jaddref = NULL;
+ if (mkdir->md_state & MKDIR_PARENT) {
+ if (cancel_jaddref(jaddref, NULL,
+ &dirrem->dm_jwork) == 0) {
+ free_jremref(dotdotremref);
+ dotdotremref = NULL;
+ }
+ } else {
+ if (cancel_jaddref(jaddref, inodedep,
+ &dirrem->dm_jwork) == 0) {
+ free_jremref(dotremref);
+ dotremref = NULL;
+ }
+ }
+ }
+ }
+
+ if (jremref)
+ journal_jremref(dirrem, jremref, inodedep);
+ if (dotremref)
+ journal_jremref(dirrem, dotremref, inodedep);
+ if (dotdotremref)
+ journal_jremref(dirrem, dotdotremref, NULL);
+ jwork_move(&dirrem->dm_jwork, &dap->da_jwork);
+ free_diradd(dap, &dirrem->dm_jwork);
}
/*
@@ -3191,8 +6634,9 @@ done:
* with splbio interrupts blocked.
*/
static void
-free_diradd(dap)
+free_diradd(dap, wkhd)
struct diradd *dap;
+ struct workhead *wkhd;
{
struct dirrem *dirrem;
struct pagedep *pagedep;
@@ -3200,32 +6644,48 @@ free_diradd(dap)
struct mkdir *mkdir, *nextmd;
mtx_assert(&lk, MA_OWNED);
- WORKLIST_REMOVE(&dap->da_list);
LIST_REMOVE(dap, da_pdlist);
+ if (dap->da_state & ONWORKLIST)
+ WORKLIST_REMOVE(&dap->da_list);
if ((dap->da_state & DIRCHG) == 0) {
pagedep = dap->da_pagedep;
} else {
dirrem = dap->da_previous;
pagedep = dirrem->dm_pagedep;
dirrem->dm_dirinum = pagedep->pd_ino;
- add_to_worklist(&dirrem->dm_list);
+ dirrem->dm_state |= COMPLETE;
+ if (LIST_EMPTY(&dirrem->dm_jremrefhd))
+ add_to_worklist(&dirrem->dm_list, 0);
}
if (inodedep_lookup(pagedep->pd_list.wk_mp, dap->da_newinum,
0, &inodedep) != 0)
- (void) free_inodedep(inodedep);
+ if (inodedep->id_mkdiradd == dap)
+ inodedep->id_mkdiradd = NULL;
if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
for (mkdir = LIST_FIRST(&mkdirlisthd); mkdir; mkdir = nextmd) {
nextmd = LIST_NEXT(mkdir, md_mkdirs);
if (mkdir->md_diradd != dap)
continue;
- dap->da_state &= ~mkdir->md_state;
- WORKLIST_REMOVE(&mkdir->md_list);
+ dap->da_state &=
+ ~(mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY));
LIST_REMOVE(mkdir, md_mkdirs);
+ if (mkdir->md_state & ONWORKLIST)
+ WORKLIST_REMOVE(&mkdir->md_list);
+ if (mkdir->md_jaddref != NULL)
+ panic("free_diradd: Unexpected jaddref");
WORKITEM_FREE(mkdir, D_MKDIR);
+ if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0)
+ break;
}
if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
panic("free_diradd: unfound ref");
}
+ if (inodedep)
+ free_inodedep(inodedep);
+ /*
+ * Free any journal segments waiting for the directory write.
+ */
+ handle_jwork(&dap->da_jwork);
WORKITEM_FREE(dap, D_DIRADD);
}
@@ -3254,11 +6714,24 @@ softdep_setup_remove(bp, dp, ip, isrmdir)
int isrmdir; /* indicates if doing RMDIR */
{
struct dirrem *dirrem, *prevdirrem;
+ struct inodedep *inodedep;
+ int direct;
/*
- * Allocate a new dirrem if appropriate and ACQUIRE_LOCK.
+ * Allocate a new dirrem if appropriate and ACQUIRE_LOCK. We want
+ * newdirrem() to setup the full directory remove which requires
+ * isrmdir > 1.
*/
- dirrem = newdirrem(bp, dp, ip, isrmdir, &prevdirrem);
+ dirrem = newdirrem(bp, dp, ip, isrmdir?2:0, &prevdirrem);
+ /*
+ * Add the dirrem to the inodedep's pending remove list for quick
+ * discovery later.
+ */
+ if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
+ &inodedep) == 0)
+ panic("softdep_setup_remove: Lost inodedep.");
+ dirrem->dm_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&inodedep->id_dirremhd, dirrem, dm_inonext);
/*
* If the COMPLETE flag is clear, then there were no active
@@ -3280,9 +6753,146 @@ softdep_setup_remove(bp, dp, ip, isrmdir)
LIST_INSERT_HEAD(&dirrem->dm_pagedep->pd_dirremhd,
prevdirrem, dm_next);
dirrem->dm_dirinum = dirrem->dm_pagedep->pd_ino;
+ direct = LIST_EMPTY(&dirrem->dm_jremrefhd);
FREE_LOCK(&lk);
- handle_workitem_remove(dirrem, NULL);
+ if (direct)
+ handle_workitem_remove(dirrem, NULL);
+ }
+}
+
+/*
+ * Check for an entry matching 'offset' on both the pd_dirraddhd list and the
+ * pd_pendinghd list of a pagedep.
+ */
+static struct diradd *
+diradd_lookup(pagedep, offset)
+ struct pagedep *pagedep;
+ int offset;
+{
+ struct diradd *dap;
+
+ LIST_FOREACH(dap, &pagedep->pd_diraddhd[DIRADDHASH(offset)], da_pdlist)
+ if (dap->da_offset == offset)
+ return (dap);
+ LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist)
+ if (dap->da_offset == offset)
+ return (dap);
+ return (NULL);
+}
+
+/*
+ * Search for a .. diradd dependency in a directory that is being removed.
+ * If the directory was renamed to a new parent we have a diradd rather
+ * than a mkdir for the .. entry. We need to cancel it now before
+ * it is found in truncate().
+ */
+static struct jremref *
+cancel_diradd_dotdot(ip, dirrem, jremref)
+ struct inode *ip;
+ struct dirrem *dirrem;
+ struct jremref *jremref;
+{
+ struct pagedep *pagedep;
+ struct diradd *dap;
+ struct worklist *wk;
+
+ if (pagedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0, 0,
+ &pagedep) == 0)
+ return (jremref);
+ dap = diradd_lookup(pagedep, DOTDOT_OFFSET);
+ if (dap == NULL)
+ return (jremref);
+ cancel_diradd(dap, dirrem, jremref, NULL, NULL);
+ /*
+ * Mark any journal work as belonging to the parent so it is freed
+ * with the .. reference.
+ */
+ LIST_FOREACH(wk, &dirrem->dm_jwork, wk_list)
+ wk->wk_state |= MKDIR_PARENT;
+ return (NULL);
+}
+
+/*
+ * Cancel the MKDIR_PARENT mkdir component of a diradd when we're going to
+ * replace it with a dirrem/diradd pair as a result of re-parenting a
+ * directory. This ensures that we don't simultaneously have a mkdir and
+ * a diradd for the same .. entry.
+ */
+static struct jremref *
+cancel_mkdir_dotdot(ip, dirrem, jremref)
+ struct inode *ip;
+ struct dirrem *dirrem;
+ struct jremref *jremref;
+{
+ struct inodedep *inodedep;
+ struct jaddref *jaddref;
+ struct mkdir *mkdir;
+ struct diradd *dap;
+
+ if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
+ &inodedep) == 0)
+ panic("cancel_mkdir_dotdot: Lost inodedep");
+ dap = inodedep->id_mkdiradd;
+ if (dap == NULL || (dap->da_state & MKDIR_PARENT) == 0)
+ return (jremref);
+ for (mkdir = LIST_FIRST(&mkdirlisthd); mkdir;
+ mkdir = LIST_NEXT(mkdir, md_mkdirs))
+ if (mkdir->md_diradd == dap && mkdir->md_state & MKDIR_PARENT)
+ break;
+ if (mkdir == NULL)
+ panic("cancel_mkdir_dotdot: Unable to find mkdir\n");
+ if ((jaddref = mkdir->md_jaddref) != NULL) {
+ mkdir->md_jaddref = NULL;
+ jaddref->ja_state &= ~MKDIR_PARENT;
+ if (inodedep_lookup(UFSTOVFS(ip->i_ump), jaddref->ja_ino, 0,
+ &inodedep) == 0)
+ panic("cancel_mkdir_dotdot: Lost parent inodedep");
+ if (cancel_jaddref(jaddref, inodedep, &dirrem->dm_jwork)) {
+ journal_jremref(dirrem, jremref, inodedep);
+ jremref = NULL;
+ }
}
+ if (mkdir->md_state & ONWORKLIST)
+ WORKLIST_REMOVE(&mkdir->md_list);
+ mkdir->md_state |= ALLCOMPLETE;
+ complete_mkdir(mkdir);
+ return (jremref);
+}
+
+static void
+journal_jremref(dirrem, jremref, inodedep)
+ struct dirrem *dirrem;
+ struct jremref *jremref;
+ struct inodedep *inodedep;
+{
+
+ if (inodedep == NULL)
+ if (inodedep_lookup(jremref->jr_list.wk_mp,
+ jremref->jr_ref.if_ino, 0, &inodedep) == 0)
+ panic("journal_jremref: Lost inodedep");
+ LIST_INSERT_HEAD(&dirrem->dm_jremrefhd, jremref, jr_deps);
+ TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jremref->jr_ref, if_deps);
+ add_to_journal(&jremref->jr_list);
+}
+
+static void
+dirrem_journal(dirrem, jremref, dotremref, dotdotremref)
+ struct dirrem *dirrem;
+ struct jremref *jremref;
+ struct jremref *dotremref;
+ struct jremref *dotdotremref;
+{
+ struct inodedep *inodedep;
+
+
+ if (inodedep_lookup(jremref->jr_list.wk_mp, jremref->jr_ref.if_ino, 0,
+ &inodedep) == 0)
+ panic("dirrem_journal: Lost inodedep");
+ journal_jremref(dirrem, jremref, inodedep);
+ if (dotremref)
+ journal_jremref(dirrem, dotremref, inodedep);
+ if (dotdotremref)
+ journal_jremref(dirrem, dotdotremref, NULL);
}
/*
@@ -3303,12 +6913,17 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
struct diradd *dap;
struct dirrem *dirrem;
struct pagedep *pagedep;
+ struct jremref *jremref;
+ struct jremref *dotremref;
+ struct jremref *dotdotremref;
+ struct vnode *dvp;
/*
* Whiteouts have no deletion dependencies.
*/
if (ip == NULL)
panic("newdirrem: whiteout");
+ dvp = ITOV(dp);
/*
* If we are over our limit, try to improve the situation.
* Limiting the number of dirrem structures will also limit
@@ -3321,34 +6936,75 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
FREE_LOCK(&lk);
dirrem = malloc(sizeof(struct dirrem),
M_DIRREM, M_SOFTDEP_FLAGS|M_ZERO);
- workitem_alloc(&dirrem->dm_list, D_DIRREM, ITOV(dp)->v_mount);
+ workitem_alloc(&dirrem->dm_list, D_DIRREM, dvp->v_mount);
+ LIST_INIT(&dirrem->dm_jremrefhd);
+ LIST_INIT(&dirrem->dm_jwork);
dirrem->dm_state = isrmdir ? RMDIR : 0;
dirrem->dm_oldinum = ip->i_number;
*prevdirremp = NULL;
-
+ /*
+ * Allocate remove reference structures to track journal write
+ * dependencies. We will always have one for the link and
+ * when doing directories we will always have one more for dot.
+ * When renaming a directory we skip the dotdot link change so
+ * this is not needed.
+ */
+ jremref = dotremref = dotdotremref = NULL;
+ if (DOINGSUJ(dvp)) {
+ if (isrmdir) {
+ jremref = newjremref(dirrem, dp, ip, dp->i_offset,
+ ip->i_effnlink + 2);
+ dotremref = newjremref(dirrem, ip, ip, DOT_OFFSET,
+ ip->i_effnlink + 1);
+ } else
+ jremref = newjremref(dirrem, dp, ip, dp->i_offset,
+ ip->i_effnlink + 1);
+ if (isrmdir > 1) {
+ dotdotremref = newjremref(dirrem, ip, dp, DOTDOT_OFFSET,
+ dp->i_effnlink + 1);
+ dotdotremref->jr_state |= MKDIR_PARENT;
+ }
+ }
ACQUIRE_LOCK(&lk);
lbn = lblkno(dp->i_fs, dp->i_offset);
offset = blkoff(dp->i_fs, dp->i_offset);
- if (pagedep_lookup(dp, lbn, DEPALLOC, &pagedep) == 0)
+ if (pagedep_lookup(UFSTOVFS(dp->i_ump), dp->i_number, lbn, DEPALLOC,
+ &pagedep) == 0)
WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);
dirrem->dm_pagedep = pagedep;
/*
+ * If we're renaming a .. link to a new directory, cancel any
+ * existing MKDIR_PARENT mkdir. If it has already been canceled
+ * the jremref is preserved for any potential diradd in this
+ * location. This can not coincide with a rmdir.
+ */
+ if (dp->i_offset == DOTDOT_OFFSET) {
+ if (isrmdir)
+ panic("newdirrem: .. directory change during remove?");
+ jremref = cancel_mkdir_dotdot(dp, dirrem, jremref);
+ }
+ /*
+ * If we're removing a directory search for the .. dependency now and
+ * cancel it. Any pending journal work will be added to the dirrem
+ * to be completed when the workitem remove completes.
+ */
+ if (isrmdir > 1)
+ dotdotremref = cancel_diradd_dotdot(ip, dirrem, dotdotremref);
+ /*
* Check for a diradd dependency for the same directory entry.
* If present, then both dependencies become obsolete and can
- * be de-allocated. Check for an entry on both the pd_dirraddhd
- * list and the pd_pendinghd list.
+ * be de-allocated.
*/
-
- LIST_FOREACH(dap, &pagedep->pd_diraddhd[DIRADDHASH(offset)], da_pdlist)
- if (dap->da_offset == offset)
- break;
+ dap = diradd_lookup(pagedep, offset);
if (dap == NULL) {
-
- LIST_FOREACH(dap, &pagedep->pd_pendinghd, da_pdlist)
- if (dap->da_offset == offset)
- break;
- if (dap == NULL)
- return (dirrem);
+ /*
+ * Link the jremref structures into the dirrem so they are
+ * written prior to the pagedep.
+ */
+ if (jremref)
+ dirrem_journal(dirrem, jremref, dotremref,
+ dotdotremref);
+ return (dirrem);
}
/*
* Must be ATTACHED at this point.
@@ -3373,7 +7029,17 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
* Mark it COMPLETE so we can delete its inode immediately.
*/
dirrem->dm_state |= COMPLETE;
- free_diradd(dap);
+ cancel_diradd(dap, dirrem, jremref, dotremref, dotdotremref);
+#ifdef SUJ_DEBUG
+ if (isrmdir == 0) {
+ struct worklist *wk;
+
+ LIST_FOREACH(wk, &dirrem->dm_jwork, wk_list)
+ if (wk->wk_state & (MKDIR_BODY | MKDIR_PARENT))
+ panic("bad wk %p (0x%X)\n", wk, wk->wk_state);
+ }
+#endif
+
return (dirrem);
}
@@ -3407,6 +7073,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
struct dirrem *dirrem, *prevdirrem;
struct pagedep *pagedep;
struct inodedep *inodedep;
+ struct jaddref *jaddref;
struct mount *mp;
offset = blkoff(dp->i_fs, dp->i_offset);
@@ -3422,6 +7089,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
dap->da_state = DIRCHG | ATTACHED | DEPCOMPLETE;
dap->da_offset = offset;
dap->da_newinum = newinum;
+ LIST_INIT(&dap->da_jwork);
}
/*
@@ -3454,11 +7122,21 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
dm_next);
} else {
dirrem->dm_dirinum = pagedep->pd_ino;
- add_to_worklist(&dirrem->dm_list);
+ if (LIST_EMPTY(&dirrem->dm_jremrefhd))
+ add_to_worklist(&dirrem->dm_list, 0);
}
FREE_LOCK(&lk);
return;
}
+ /*
+ * Add the dirrem to the inodedep's pending remove list for quick
+ * discovery later. A valid nlinkdelta ensures that this lookup
+ * will not fail.
+ */
+ if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0)
+ panic("softdep_setup_directory_change: Lost inodedep.");
+ dirrem->dm_state |= ONDEPLIST;
+ LIST_INSERT_HEAD(&inodedep->id_dirremhd, dirrem, dm_inonext);
/*
* If the COMPLETE flag is clear, then there were no active
@@ -3483,15 +7161,29 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
dap->da_pagedep = pagedep;
}
dirrem->dm_dirinum = pagedep->pd_ino;
- add_to_worklist(&dirrem->dm_list);
+ if (LIST_EMPTY(&dirrem->dm_jremrefhd))
+ add_to_worklist(&dirrem->dm_list, 0);
}
/*
- * Link into its inodedep. Put it on the id_bufwait list if the inode
+ * Lookup the jaddref for this journal entry. We must finish
+ * initializing it and make the diradd write dependent on it.
+ * If we're not journaling Put it on the id_bufwait list if the inode
* is not yet written. If it is written, do the post-inode write
* processing to put it on the id_pendinghd list.
*/
- if (inodedep_lookup(mp, newinum, DEPALLOC, &inodedep) == 0 ||
- (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
+ inodedep_lookup(mp, newinum, DEPALLOC, &inodedep);
+ if (mp->mnt_kern_flag & MNTK_SUJ) {
+ jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
+ inoreflst);
+ KASSERT(jaddref != NULL && jaddref->ja_parent == dp->i_number,
+ ("softdep_setup_directory_change: bad jaddref %p",
+ jaddref));
+ jaddref->ja_diroff = dp->i_offset;
+ jaddref->ja_diradd = dap;
+ LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(offset)],
+ dap, da_pdlist);
+ add_to_journal(&jaddref->ja_list);
+ } else if ((inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
dap->da_state |= COMPLETE;
LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
WORKLIST_INSERT(&inodedep->id_pendinghd, &dap->da_list);
@@ -3500,6 +7192,13 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
dap, da_pdlist);
WORKLIST_INSERT(&inodedep->id_bufwait, &dap->da_list);
}
+ /*
+ * If we're making a new name for a directory that has not been
+ * committed when need to move the dot and dotdot references to
+ * this new name.
+ */
+ if (inodedep->id_mkdiradd && dp->i_offset != DOTDOT_OFFSET)
+ merge_diradd(inodedep, dap);
FREE_LOCK(&lk);
}
@@ -3516,8 +7215,7 @@ softdep_change_linkcnt(ip)
struct inodedep *inodedep;
ACQUIRE_LOCK(&lk);
- (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number,
- DEPALLOC, &inodedep);
+ inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC, &inodedep);
if (ip->i_nlink < ip->i_effnlink)
panic("softdep_change_linkcnt: bad delta");
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
@@ -3574,6 +7272,305 @@ softdep_releasefile(ip)
}
/*
+ * Attach a sbdep dependency to the superblock buf so that we can keep
+ * track of the head of the linked list of referenced but unlinked inodes.
+ */
+void
+softdep_setup_sbupdate(ump, fs, bp)
+ struct ufsmount *ump;
+ struct fs *fs;
+ struct buf *bp;
+{
+ struct sbdep *sbdep;
+ struct worklist *wk;
+
+ if ((fs->fs_flags & FS_SUJ) == 0)
+ return;
+ LIST_FOREACH(wk, &bp->b_dep, wk_list)
+ if (wk->wk_type == D_SBDEP)
+ break;
+ if (wk != NULL)
+ return;
+ sbdep = malloc(sizeof(struct sbdep), M_SBDEP, M_SOFTDEP_FLAGS);
+ workitem_alloc(&sbdep->sb_list, D_SBDEP, UFSTOVFS(ump));
+ sbdep->sb_fs = fs;
+ sbdep->sb_ump = ump;
+ ACQUIRE_LOCK(&lk);
+ WORKLIST_INSERT(&bp->b_dep, &sbdep->sb_list);
+ FREE_LOCK(&lk);
+}
+
+/*
+ * Return the first unlinked inodedep which is ready to be the head of the
+ * list. The inodedep and all those after it must have valid next pointers.
+ */
+static struct inodedep *
+first_unlinked_inodedep(ump)
+ struct ufsmount *ump;
+{
+ struct inodedep *inodedep;
+ struct inodedep *idp;
+
+ for (inodedep = TAILQ_LAST(&ump->softdep_unlinked, inodedeplst);
+ inodedep; inodedep = idp) {
+ if ((inodedep->id_state & UNLINKNEXT) == 0)
+ return (NULL);
+ idp = TAILQ_PREV(inodedep, inodedeplst, id_unlinked);
+ if (idp == NULL || (idp->id_state & UNLINKNEXT) == 0)
+ break;
+ if ((inodedep->id_state & UNLINKPREV) == 0)
+ panic("first_unlinked_inodedep: prev != next");
+ }
+ if (inodedep == NULL)
+ return (NULL);
+
+ return (inodedep);
+}
+
+/*
+ * Set the sujfree unlinked head pointer prior to writing a superblock.
+ */
+static void
+initiate_write_sbdep(sbdep)
+ struct sbdep *sbdep;
+{
+ struct inodedep *inodedep;
+ struct fs *bpfs;
+ struct fs *fs;
+
+ bpfs = sbdep->sb_fs;
+ fs = sbdep->sb_ump->um_fs;
+ inodedep = first_unlinked_inodedep(sbdep->sb_ump);
+ if (inodedep) {
+ fs->fs_sujfree = inodedep->id_ino;
+ inodedep->id_state |= UNLINKPREV;
+ } else
+ fs->fs_sujfree = 0;
+ bpfs->fs_sujfree = fs->fs_sujfree;
+}
+
+/*
+ * After a superblock is written determine whether it must be written again
+ * due to a changing unlinked list head.
+ */
+static int
+handle_written_sbdep(sbdep, bp)
+ struct sbdep *sbdep;
+ struct buf *bp;
+{
+ struct inodedep *inodedep;
+ struct mount *mp;
+ struct fs *fs;
+
+ fs = sbdep->sb_fs;
+ mp = UFSTOVFS(sbdep->sb_ump);
+ inodedep = first_unlinked_inodedep(sbdep->sb_ump);
+ if ((inodedep && fs->fs_sujfree != inodedep->id_ino) ||
+ (inodedep == NULL && fs->fs_sujfree != 0)) {
+ bdirty(bp);
+ return (1);
+ }
+ WORKITEM_FREE(sbdep, D_SBDEP);
+ if (fs->fs_sujfree == 0)
+ return (0);
+ if (inodedep_lookup(mp, fs->fs_sujfree, 0, &inodedep) == 0)
+ panic("handle_written_sbdep: lost inodedep");
+ /*
+ * Now that we have a record of this indode in stable store allow it
+ * to be written to free up pending work. Inodes may see a lot of
+ * write activity after they are unlinked which we must not hold up.
+ */
+ for (; inodedep != NULL; inodedep = TAILQ_NEXT(inodedep, id_unlinked)) {
+ if ((inodedep->id_state & UNLINKLINKS) != UNLINKLINKS)
+ panic("handle_written_sbdep: Bad inodedep %p (0x%X)",
+ inodedep, inodedep->id_state);
+ if (inodedep->id_state & UNLINKONLIST)
+ break;
+ inodedep->id_state |= DEPCOMPLETE | UNLINKONLIST;
+ }
+
+ return (0);
+}
+
+/*
+ * Mark an inodedep has unlinked and insert it into the in-memory unlinked
+ * list.
+ */
+static void
+unlinked_inodedep(mp, inodedep)
+ struct mount *mp;
+ struct inodedep *inodedep;
+{
+ struct ufsmount *ump;
+
+ if ((mp->mnt_kern_flag & MNTK_SUJ) == 0)
+ return;
+ ump = VFSTOUFS(mp);
+ ump->um_fs->fs_fmod = 1;
+ inodedep->id_state |= UNLINKED;
+ TAILQ_INSERT_HEAD(&ump->softdep_unlinked, inodedep, id_unlinked);
+}
+
+/*
+ * Remove an inodedep from the unlinked inodedep list. This may require
+ * disk writes if the inode has made it that far.
+ */
+static void
+clear_unlinked_inodedep(inodedep)
+ struct inodedep *inodedep;
+{
+ struct ufsmount *ump;
+ struct inodedep *idp;
+ struct inodedep *idn;
+ struct fs *fs;
+ struct buf *bp;
+ ino_t ino;
+ ino_t nino;
+ ino_t pino;
+ int error;
+
+ ump = VFSTOUFS(inodedep->id_list.wk_mp);
+ fs = ump->um_fs;
+ ino = inodedep->id_ino;
+ error = 0;
+ for (;;) {
+ /*
+ * If nothing has yet been written simply remove us from
+ * the in memory list and return. This is the most common
+ * case where handle_workitem_remove() loses the final
+ * reference.
+ */
+ if ((inodedep->id_state & UNLINKLINKS) == 0)
+ break;
+ /*
+ * If we have a NEXT pointer and no PREV pointer we can simply
+ * clear NEXT's PREV and remove ourselves from the list. Be
+ * careful not to clear PREV if the superblock points at
+ * next as well.
+ */
+ idn = TAILQ_NEXT(inodedep, id_unlinked);
+ if ((inodedep->id_state & UNLINKLINKS) == UNLINKNEXT) {
+ if (idn && fs->fs_sujfree != idn->id_ino)
+ idn->id_state &= ~UNLINKPREV;
+ break;
+ }
+ /*
+ * Here we have an inodedep which is actually linked into
+ * the list. We must remove it by forcing a write to the
+ * link before us, whether it be the superblock or an inode.
+ * Unfortunately the list may change while we're waiting
+ * on the buf lock for either resource so we must loop until
+ * we lock. the right one. If both the superblock and an
+ * inode point to this inode we must clear the inode first
+ * followed by the superblock.
+ */
+ idp = TAILQ_PREV(inodedep, inodedeplst, id_unlinked);
+ pino = 0;
+ if (idp && (idp->id_state & UNLINKNEXT))
+ pino = idp->id_ino;
+ FREE_LOCK(&lk);
+ if (pino == 0)
+ bp = getblk(ump->um_devvp, btodb(fs->fs_sblockloc),
+ (int)fs->fs_sbsize, 0, 0, 0);
+ else
+ error = bread(ump->um_devvp,
+ fsbtodb(fs, ino_to_fsba(fs, pino)),
+ (int)fs->fs_bsize, NOCRED, &bp);
+ ACQUIRE_LOCK(&lk);
+ if (error)
+ break;
+ /* If the list has changed restart the loop. */
+ idp = TAILQ_PREV(inodedep, inodedeplst, id_unlinked);
+ nino = 0;
+ if (idp && (idp->id_state & UNLINKNEXT))
+ nino = idp->id_ino;
+ if (nino != pino ||
+ (inodedep->id_state & UNLINKPREV) != UNLINKPREV) {
+ FREE_LOCK(&lk);
+ brelse(bp);
+ ACQUIRE_LOCK(&lk);
+ continue;
+ }
+ /*
+ * Remove us from the in memory list. After this we cannot
+ * access the inodedep.
+ */
+ idn = TAILQ_NEXT(inodedep, id_unlinked);
+ inodedep->id_state &= ~(UNLINKED | UNLINKLINKS);
+ TAILQ_REMOVE(&ump->softdep_unlinked, inodedep, id_unlinked);
+ /*
+ * Determine the next inode number.
+ */
+ nino = 0;
+ if (idn) {
+ /*
+ * If next isn't on the list we can just clear prev's
+ * state and schedule it to be fixed later. No need
+ * to synchronously write if we're not in the real
+ * list.
+ */
+ if ((idn->id_state & UNLINKPREV) == 0 && pino != 0) {
+ idp->id_state &= ~UNLINKNEXT;
+ if ((idp->id_state & ONWORKLIST) == 0)
+ WORKLIST_INSERT(&bp->b_dep,
+ &idp->id_list);
+ FREE_LOCK(&lk);
+ bawrite(bp);
+ ACQUIRE_LOCK(&lk);
+ return;
+ }
+ nino = idn->id_ino;
+ }
+ FREE_LOCK(&lk);
+ /*
+ * The predecessor's next pointer is manually updated here
+ * so that the NEXT flag is never cleared for an element
+ * that is in the list.
+ */
+ if (pino == 0) {
+ bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
+ ffs_oldfscompat_write((struct fs *)bp->b_data, ump);
+ softdep_setup_sbupdate(ump, (struct fs *)bp->b_data,
+ bp);
+ } else if (fs->fs_magic == FS_UFS1_MAGIC)
+ ((struct ufs1_dinode *)bp->b_data +
+ ino_to_fsbo(fs, pino))->di_freelink = nino;
+ else
+ ((struct ufs2_dinode *)bp->b_data +
+ ino_to_fsbo(fs, pino))->di_freelink = nino;
+ /*
+ * If the bwrite fails we have no recourse to recover. The
+ * filesystem is corrupted already.
+ */
+ bwrite(bp);
+ ACQUIRE_LOCK(&lk);
+ /*
+ * If the superblock pointer still needs to be cleared force
+ * a write here.
+ */
+ if (fs->fs_sujfree == ino) {
+ FREE_LOCK(&lk);
+ bp = getblk(ump->um_devvp, btodb(fs->fs_sblockloc),
+ (int)fs->fs_sbsize, 0, 0, 0);
+ bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
+ ffs_oldfscompat_write((struct fs *)bp->b_data, ump);
+ softdep_setup_sbupdate(ump, (struct fs *)bp->b_data,
+ bp);
+ bwrite(bp);
+ ACQUIRE_LOCK(&lk);
+ }
+ if (fs->fs_sujfree != ino)
+ return;
+ panic("clear_unlinked_inodedep: Failed to clear free head");
+ }
+ if (inodedep->id_ino == fs->fs_sujfree)
+ panic("clear_unlinked_inodedep: Freeing head of free list");
+ inodedep->id_state &= ~(UNLINKED | UNLINKLINKS);
+ TAILQ_REMOVE(&ump->softdep_unlinked, inodedep, id_unlinked);
+ return;
+}
+
+/*
* This workitem decrements the inode's link count.
* If the link count reaches zero, the file is removed.
*/
@@ -3584,22 +7581,54 @@ handle_workitem_remove(dirrem, xp)
{
struct thread *td = curthread;
struct inodedep *inodedep;
+ struct workhead dotdotwk;
+ struct worklist *wk;
+ struct ufsmount *ump;
+ struct mount *mp;
struct vnode *vp;
struct inode *ip;
ino_t oldinum;
int error;
+ if (dirrem->dm_state & ONWORKLIST)
+ panic("handle_workitem_remove: dirrem %p still on worklist",
+ dirrem);
+ oldinum = dirrem->dm_oldinum;
+ mp = dirrem->dm_list.wk_mp;
+ ump = VFSTOUFS(mp);
if ((vp = xp) == NULL &&
- (error = ffs_vgetf(dirrem->dm_list.wk_mp,
- dirrem->dm_oldinum, LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ)) != 0) {
+ (error = ffs_vgetf(mp, oldinum, LK_EXCLUSIVE, &vp,
+ FFSV_FORCEINSMQ)) != 0) {
softdep_error("handle_workitem_remove: vget", error);
return;
}
ip = VTOI(vp);
ACQUIRE_LOCK(&lk);
- if ((inodedep_lookup(dirrem->dm_list.wk_mp,
- dirrem->dm_oldinum, 0, &inodedep)) == 0)
+ if ((inodedep_lookup(mp, oldinum, 0, &inodedep)) == 0)
panic("handle_workitem_remove: lost inodedep");
+ if (dirrem->dm_state & ONDEPLIST)
+ LIST_REMOVE(dirrem, dm_inonext);
+ KASSERT(LIST_EMPTY(&dirrem->dm_jremrefhd),
+ ("handle_workitem_remove: Journal entries not written."));
+
+ /*
+ * Move all dependencies waiting on the remove to complete
+ * from the dirrem to the inode inowait list to be completed
+ * after the inode has been updated and written to disk. Any
+ * marked MKDIR_PARENT are saved to be completed when the .. ref
+ * is removed.
+ */
+ LIST_INIT(&dotdotwk);
+ while ((wk = LIST_FIRST(&dirrem->dm_jwork)) != NULL) {
+ WORKLIST_REMOVE(wk);
+ if (wk->wk_state & MKDIR_PARENT) {
+ wk->wk_state &= ~MKDIR_PARENT;
+ WORKLIST_INSERT(&dotdotwk, wk);
+ continue;
+ }
+ WORKLIST_INSERT(&inodedep->id_inowait, wk);
+ }
+ LIST_SWAP(&dirrem->dm_jwork, &dotdotwk, worklist, wk_list);
/*
* Normal file deletion.
*/
@@ -3609,12 +7638,16 @@ handle_workitem_remove(dirrem, xp)
ip->i_flag |= IN_CHANGE;
if (ip->i_nlink < ip->i_effnlink)
panic("handle_workitem_remove: bad file delta");
+ if (ip->i_nlink == 0)
+ unlinked_inodedep(mp, inodedep);
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
num_dirrem -= 1;
+ KASSERT(LIST_EMPTY(&dirrem->dm_jwork),
+ ("handle_workitem_remove: worklist not empty. %s",
+ TYPENAME(LIST_FIRST(&dirrem->dm_jwork)->wk_type)));
WORKITEM_FREE(dirrem, D_DIRREM);
FREE_LOCK(&lk);
- vput(vp);
- return;
+ goto out;
}
/*
* Directory deletion. Decrement reference count for both the
@@ -3628,6 +7661,8 @@ handle_workitem_remove(dirrem, xp)
ip->i_flag |= IN_CHANGE;
if (ip->i_nlink < ip->i_effnlink)
panic("handle_workitem_remove: bad dir delta");
+ if (ip->i_nlink == 0)
+ unlinked_inodedep(mp, inodedep);
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
FREE_LOCK(&lk);
if ((error = ffs_truncate(vp, (off_t)0, 0, td->td_ucred, td)) != 0)
@@ -3639,36 +7674,47 @@ handle_workitem_remove(dirrem, xp)
* directory should not change. Thus we skip the followup dirrem.
*/
if (dirrem->dm_state & DIRCHG) {
+ KASSERT(LIST_EMPTY(&dirrem->dm_jwork),
+ ("handle_workitem_remove: DIRCHG and worklist not empty."));
num_dirrem -= 1;
WORKITEM_FREE(dirrem, D_DIRREM);
FREE_LOCK(&lk);
- vput(vp);
- return;
+ goto out;
}
+ dirrem->dm_state = ONDEPLIST;
+ dirrem->dm_oldinum = dirrem->dm_dirinum;
/*
- * If the inodedep does not exist, then the zero'ed inode has
- * been written to disk. If the allocated inode has never been
- * written to disk, then the on-disk inode is zero'ed. In either
- * case we can remove the file immediately.
+ * Place the dirrem on the parent's diremhd list.
*/
- dirrem->dm_state = 0;
- oldinum = dirrem->dm_oldinum;
- dirrem->dm_oldinum = dirrem->dm_dirinum;
- if (inodedep_lookup(dirrem->dm_list.wk_mp, oldinum,
- 0, &inodedep) == 0 || check_inode_unwritten(inodedep)) {
+ if (inodedep_lookup(mp, dirrem->dm_oldinum, 0, &inodedep) == 0)
+ panic("handle_workitem_remove: lost dir inodedep");
+ LIST_INSERT_HEAD(&inodedep->id_dirremhd, dirrem, dm_inonext);
+ /*
+ * If the allocated inode has never been written to disk, then
+ * the on-disk inode is zero'ed and we can remove the file
+ * immediately. When journaling if the inode has been marked
+ * unlinked and not DEPCOMPLETE we know it can never be written.
+ */
+ inodedep_lookup(mp, oldinum, 0, &inodedep);
+ if (inodedep == NULL ||
+ (inodedep->id_state & (DEPCOMPLETE | UNLINKED)) == UNLINKED ||
+ check_inode_unwritten(inodedep)) {
if (xp != NULL)
- add_to_worklist(&dirrem->dm_list);
+ add_to_worklist(&dirrem->dm_list, 0);
FREE_LOCK(&lk);
- vput(vp);
- if (xp == NULL)
+ if (xp == NULL) {
+ vput(vp);
handle_workitem_remove(dirrem, NULL);
+ }
return;
}
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
FREE_LOCK(&lk);
ip->i_flag |= IN_CHANGE;
+out:
ffs_update(vp, 0);
- vput(vp);
+ if (xp == NULL)
+ vput(vp);
}
/*
@@ -3689,6 +7735,7 @@ static void
handle_workitem_freefile(freefile)
struct freefile *freefile;
{
+ struct workhead wkhd;
struct fs *fs;
struct inodedep *idp;
struct ufsmount *ump;
@@ -3701,13 +7748,15 @@ handle_workitem_freefile(freefile)
error = inodedep_lookup(UFSTOVFS(ump), freefile->fx_oldinum, 0, &idp);
FREE_LOCK(&lk);
if (error)
- panic("handle_workitem_freefile: inodedep survived");
+ panic("handle_workitem_freefile: inodedep %p survived", idp);
#endif
UFS_LOCK(ump);
fs->fs_pendinginodes -= 1;
UFS_UNLOCK(ump);
+ LIST_INIT(&wkhd);
+ LIST_SWAP(&freefile->fx_jwork, &wkhd, worklist, wk_list);
if ((error = ffs_freefile(ump, fs, freefile->fx_devvp,
- freefile->fx_oldinum, freefile->fx_mode)) != 0)
+ freefile->fx_oldinum, freefile->fx_mode, &wkhd)) != 0)
softdep_error("handle_workitem_freefile", error);
ACQUIRE_LOCK(&lk);
WORKITEM_FREE(freefile, D_FREEFILE);
@@ -3757,8 +7806,10 @@ softdep_disk_io_initiation(bp)
{
struct worklist *wk;
struct worklist marker;
- struct indirdep *indirdep;
struct inodedep *inodedep;
+ struct freeblks *freeblks;
+ struct jfreeblk *jfreeblk;
+ struct newblk *newblk;
/*
* We only care about write operations. There should never
@@ -3767,6 +7818,10 @@ softdep_disk_io_initiation(bp)
if (bp->b_iocmd != BIO_WRITE)
panic("softdep_disk_io_initiation: not write");
+ if (bp->b_vflags & BV_BKGRDINPROG)
+ panic("softdep_disk_io_initiation: Writing buffer with "
+ "background write in progress: %p", bp);
+
marker.wk_type = D_LAST + 1; /* Not a normal workitem */
PHOLD(curproc); /* Don't swap out kernel stack */
@@ -3792,46 +7847,58 @@ softdep_disk_io_initiation(bp)
continue;
case D_INDIRDEP:
- indirdep = WK_INDIRDEP(wk);
- if (indirdep->ir_state & GOINGAWAY)
- panic("disk_io_initiation: indirdep gone");
+ initiate_write_indirdep(WK_INDIRDEP(wk), bp);
+ continue;
+
+ case D_BMSAFEMAP:
+ initiate_write_bmsafemap(WK_BMSAFEMAP(wk), bp);
+ continue;
+
+ case D_JSEG:
+ WK_JSEG(wk)->js_buf = NULL;
+ continue;
+
+ case D_FREEBLKS:
+ freeblks = WK_FREEBLKS(wk);
+ jfreeblk = LIST_FIRST(&freeblks->fb_jfreeblkhd);
/*
- * If there are no remaining dependencies, this
- * will be writing the real pointers, so the
- * dependency can be freed.
+ * We have to wait for the jfreeblks to be journaled
+ * before we can write an inodeblock with updated
+ * pointers. Be careful to arrange the marker so
+ * we revisit the jfreeblk if it's not removed by
+ * the first jwait().
*/
- if (LIST_EMPTY(&indirdep->ir_deplisthd)) {
- struct buf *bp;
-
- bp = indirdep->ir_savebp;
- bp->b_flags |= B_INVAL | B_NOCACHE;
- /* inline expand WORKLIST_REMOVE(wk); */
- wk->wk_state &= ~ONWORKLIST;
- LIST_REMOVE(wk, wk_list);
- WORKITEM_FREE(indirdep, D_INDIRDEP);
- FREE_LOCK(&lk);
- brelse(bp);
- ACQUIRE_LOCK(&lk);
- continue;
+ if (jfreeblk != NULL) {
+ LIST_REMOVE(&marker, wk_list);
+ LIST_INSERT_BEFORE(wk, &marker, wk_list);
+ jwait(&jfreeblk->jf_list);
}
+ continue;
+ case D_ALLOCDIRECT:
+ case D_ALLOCINDIR:
/*
- * Replace up-to-date version with safe version.
+ * We have to wait for the jnewblk to be journaled
+ * before we can write to a block otherwise the
+ * contents may be confused with an earlier file
+ * at recovery time. Handle the marker as described
+ * above.
*/
- FREE_LOCK(&lk);
- indirdep->ir_saveddata = malloc(bp->b_bcount,
- M_INDIRDEP, M_SOFTDEP_FLAGS);
- ACQUIRE_LOCK(&lk);
- indirdep->ir_state &= ~ATTACHED;
- indirdep->ir_state |= UNDONE;
- bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount);
- bcopy(indirdep->ir_savebp->b_data, bp->b_data,
- bp->b_bcount);
+ newblk = WK_NEWBLK(wk);
+ if (newblk->nb_jnewblk != NULL) {
+ LIST_REMOVE(&marker, wk_list);
+ LIST_INSERT_BEFORE(wk, &marker, wk_list);
+ jwait(&newblk->nb_jnewblk->jn_list);
+ }
+ continue;
+
+ case D_SBDEP:
+ initiate_write_sbdep(WK_SBDEP(wk));
continue;
case D_MKDIR:
- case D_BMSAFEMAP:
- case D_ALLOCDIRECT:
- case D_ALLOCINDIR:
+ case D_FREEWORK:
+ case D_FREEDEP:
+ case D_JSEGDEP:
continue;
default:
@@ -3855,6 +7922,9 @@ initiate_write_filepage(pagedep, bp)
struct pagedep *pagedep;
struct buf *bp;
{
+ struct jremref *jremref;
+ struct jmvref *jmvref;
+ struct dirrem *dirrem;
struct diradd *dap;
struct direct *ep;
int i;
@@ -3869,6 +7939,22 @@ initiate_write_filepage(pagedep, bp)
return;
}
pagedep->pd_state |= IOSTARTED;
+ /*
+ * Wait for all journal remove dependencies to hit the disk.
+ * We can not allow any potentially conflicting directory adds
+ * to be visible before removes and rollback is too difficult.
+ * lk may be dropped and re-acquired, however we hold the buf
+ * locked so the dependency can not go away.
+ */
+ LIST_FOREACH(dirrem, &pagedep->pd_dirremhd, dm_next)
+ while ((jremref = LIST_FIRST(&dirrem->dm_jremrefhd)) != NULL) {
+ stat_jwait_filepage++;
+ jwait(&jremref->jr_list);
+ }
+ while ((jmvref = LIST_FIRST(&pagedep->pd_jmvrefhd)) != NULL) {
+ stat_jwait_filepage++;
+ jwait(&jmvref->jm_list);
+ }
for (i = 0; i < DAHASHSZ; i++) {
LIST_FOREACH(dap, &pagedep->pd_diraddhd[i], da_pdlist) {
ep = (struct direct *)
@@ -3905,6 +7991,7 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
struct allocdirect *adp, *lastadp;
struct ufs1_dinode *dp;
struct ufs1_dinode *sip;
+ struct inoref *inoref;
struct fs *fs;
ufs_lbn_t i;
#ifdef INVARIANTS
@@ -3918,6 +8005,17 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
fs = inodedep->id_fs;
dp = (struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, inodedep->id_ino);
+
+ /*
+ * If we're on the unlinked list but have not yet written our
+ * next pointer initialize it here.
+ */
+ if ((inodedep->id_state & (UNLINKED | UNLINKNEXT)) == UNLINKED) {
+ struct inodedep *inon;
+
+ inon = TAILQ_NEXT(inodedep, id_unlinked);
+ dp->di_freelink = inon ? inon->id_ino : 0;
+ }
/*
* If the bitmap is not yet written, then the allocated
* inode cannot be written to disk.
@@ -3933,6 +8031,7 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
*inodedep->id_savedino1 = *dp;
bzero((caddr_t)dp, sizeof(struct ufs1_dinode));
dp->di_gen = inodedep->id_savedino1->di_gen;
+ dp->di_freelink = inodedep->id_savedino1->di_freelink;
return;
}
/*
@@ -3940,32 +8039,40 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
*/
inodedep->id_savedsize = dp->di_size;
inodedep->id_savedextsize = 0;
- if (TAILQ_EMPTY(&inodedep->id_inoupdt))
+ inodedep->id_savednlink = dp->di_nlink;
+ if (TAILQ_EMPTY(&inodedep->id_inoupdt) &&
+ TAILQ_EMPTY(&inodedep->id_inoreflst))
return;
/*
+ * Revert the link count to that of the first unwritten journal entry.
+ */
+ inoref = TAILQ_FIRST(&inodedep->id_inoreflst);
+ if (inoref)
+ dp->di_nlink = inoref->if_nlink;
+ /*
* Set the dependencies to busy.
*/
for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
adp = TAILQ_NEXT(adp, ad_next)) {
#ifdef INVARIANTS
- if (deplist != 0 && prevlbn >= adp->ad_lbn)
+ if (deplist != 0 && prevlbn >= adp->ad_offset)
panic("softdep_write_inodeblock: lbn order");
- prevlbn = adp->ad_lbn;
- if (adp->ad_lbn < NDADDR &&
- dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
+ prevlbn = adp->ad_offset;
+ if (adp->ad_offset < NDADDR &&
+ dp->di_db[adp->ad_offset] != adp->ad_newblkno)
panic("%s: direct pointer #%jd mismatch %d != %jd",
"softdep_write_inodeblock",
- (intmax_t)adp->ad_lbn,
- dp->di_db[adp->ad_lbn],
+ (intmax_t)adp->ad_offset,
+ dp->di_db[adp->ad_offset],
(intmax_t)adp->ad_newblkno);
- if (adp->ad_lbn >= NDADDR &&
- dp->di_ib[adp->ad_lbn - NDADDR] != adp->ad_newblkno)
+ if (adp->ad_offset >= NDADDR &&
+ dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno)
panic("%s: indirect pointer #%jd mismatch %d != %jd",
"softdep_write_inodeblock",
- (intmax_t)adp->ad_lbn - NDADDR,
- dp->di_ib[adp->ad_lbn - NDADDR],
+ (intmax_t)adp->ad_offset - NDADDR,
+ dp->di_ib[adp->ad_offset - NDADDR],
(intmax_t)adp->ad_newblkno);
- deplist |= 1 << adp->ad_lbn;
+ deplist |= 1 << adp->ad_offset;
if ((adp->ad_state & ATTACHED) == 0)
panic("softdep_write_inodeblock: Unknown state 0x%x",
adp->ad_state);
@@ -3981,14 +8088,14 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
*/
for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
- if (adp->ad_lbn >= NDADDR)
+ if (adp->ad_offset >= NDADDR)
break;
- dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
+ dp->di_db[adp->ad_offset] = adp->ad_oldblkno;
/* keep going until hitting a rollback to a frag */
if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
continue;
- dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
- for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
+ dp->di_size = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize;
+ for (i = adp->ad_offset + 1; i < NDADDR; i++) {
#ifdef INVARIANTS
if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
panic("softdep_write_inodeblock: lost dep1");
@@ -4012,8 +8119,8 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
* we already checked for fragments in the loop above.
*/
if (lastadp != NULL &&
- dp->di_size <= (lastadp->ad_lbn + 1) * fs->fs_bsize) {
- for (i = lastadp->ad_lbn; i >= 0; i--)
+ dp->di_size <= (lastadp->ad_offset + 1) * fs->fs_bsize) {
+ for (i = lastadp->ad_offset; i >= 0; i--)
if (dp->di_db[i] != 0)
break;
dp->di_size = (i + 1) * fs->fs_bsize;
@@ -4030,7 +8137,7 @@ initiate_write_inodeblock_ufs1(inodedep, bp)
* postpone fsck, we are stuck with this argument.
*/
for (; adp; adp = TAILQ_NEXT(adp, ad_next))
- dp->di_ib[adp->ad_lbn - NDADDR] = 0;
+ dp->di_ib[adp->ad_offset - NDADDR] = 0;
}
/*
@@ -4051,6 +8158,7 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
struct allocdirect *adp, *lastadp;
struct ufs2_dinode *dp;
struct ufs2_dinode *sip;
+ struct inoref *inoref;
struct fs *fs;
ufs_lbn_t i;
#ifdef INVARIANTS
@@ -4064,6 +8172,29 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
fs = inodedep->id_fs;
dp = (struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, inodedep->id_ino);
+
+ /*
+ * If we're on the unlinked list but have not yet written our
+ * next pointer initialize it here.
+ */
+ if ((inodedep->id_state & (UNLINKED | UNLINKNEXT)) == UNLINKED) {
+ struct inodedep *inon;
+
+ inon = TAILQ_NEXT(inodedep, id_unlinked);
+ dp->di_freelink = inon ? inon->id_ino : 0;
+ }
+ if ((inodedep->id_state & (UNLINKED | UNLINKNEXT)) ==
+ (UNLINKED | UNLINKNEXT)) {
+ struct inodedep *inon;
+ ino_t freelink;
+
+ inon = TAILQ_NEXT(inodedep, id_unlinked);
+ freelink = inon ? inon->id_ino : 0;
+ if (freelink != dp->di_freelink)
+ panic("ino %p(0x%X) %d, %d != %d",
+ inodedep, inodedep->id_state, inodedep->id_ino,
+ freelink, dp->di_freelink);
+ }
/*
* If the bitmap is not yet written, then the allocated
* inode cannot be written to disk.
@@ -4079,6 +8210,7 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
*inodedep->id_savedino2 = *dp;
bzero((caddr_t)dp, sizeof(struct ufs2_dinode));
dp->di_gen = inodedep->id_savedino2->di_gen;
+ dp->di_freelink = inodedep->id_savedino2->di_freelink;
return;
}
/*
@@ -4086,25 +8218,34 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
*/
inodedep->id_savedsize = dp->di_size;
inodedep->id_savedextsize = dp->di_extsize;
+ inodedep->id_savednlink = dp->di_nlink;
if (TAILQ_EMPTY(&inodedep->id_inoupdt) &&
- TAILQ_EMPTY(&inodedep->id_extupdt))
+ TAILQ_EMPTY(&inodedep->id_extupdt) &&
+ TAILQ_EMPTY(&inodedep->id_inoreflst))
return;
/*
+ * Revert the link count to that of the first unwritten journal entry.
+ */
+ inoref = TAILQ_FIRST(&inodedep->id_inoreflst);
+ if (inoref)
+ dp->di_nlink = inoref->if_nlink;
+
+ /*
* Set the ext data dependencies to busy.
*/
for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
adp = TAILQ_NEXT(adp, ad_next)) {
#ifdef INVARIANTS
- if (deplist != 0 && prevlbn >= adp->ad_lbn)
+ if (deplist != 0 && prevlbn >= adp->ad_offset)
panic("softdep_write_inodeblock: lbn order");
- prevlbn = adp->ad_lbn;
- if (dp->di_extb[adp->ad_lbn] != adp->ad_newblkno)
+ prevlbn = adp->ad_offset;
+ if (dp->di_extb[adp->ad_offset] != adp->ad_newblkno)
panic("%s: direct pointer #%jd mismatch %jd != %jd",
"softdep_write_inodeblock",
- (intmax_t)adp->ad_lbn,
- (intmax_t)dp->di_extb[adp->ad_lbn],
+ (intmax_t)adp->ad_offset,
+ (intmax_t)dp->di_extb[adp->ad_offset],
(intmax_t)adp->ad_newblkno);
- deplist |= 1 << adp->ad_lbn;
+ deplist |= 1 << adp->ad_offset;
if ((adp->ad_state & ATTACHED) == 0)
panic("softdep_write_inodeblock: Unknown state 0x%x",
adp->ad_state);
@@ -4120,12 +8261,12 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
*/
for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
- dp->di_extb[adp->ad_lbn] = adp->ad_oldblkno;
+ dp->di_extb[adp->ad_offset] = adp->ad_oldblkno;
/* keep going until hitting a rollback to a frag */
if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
continue;
- dp->di_extsize = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
- for (i = adp->ad_lbn + 1; i < NXADDR; i++) {
+ dp->di_extsize = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize;
+ for (i = adp->ad_offset + 1; i < NXADDR; i++) {
#ifdef INVARIANTS
if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0)
panic("softdep_write_inodeblock: lost dep1");
@@ -4142,8 +8283,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
* we already checked for fragments in the loop above.
*/
if (lastadp != NULL &&
- dp->di_extsize <= (lastadp->ad_lbn + 1) * fs->fs_bsize) {
- for (i = lastadp->ad_lbn; i >= 0; i--)
+ dp->di_extsize <= (lastadp->ad_offset + 1) * fs->fs_bsize) {
+ for (i = lastadp->ad_offset; i >= 0; i--)
if (dp->di_extb[i] != 0)
break;
dp->di_extsize = (i + 1) * fs->fs_bsize;
@@ -4154,24 +8295,24 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
adp = TAILQ_NEXT(adp, ad_next)) {
#ifdef INVARIANTS
- if (deplist != 0 && prevlbn >= adp->ad_lbn)
+ if (deplist != 0 && prevlbn >= adp->ad_offset)
panic("softdep_write_inodeblock: lbn order");
- prevlbn = adp->ad_lbn;
- if (adp->ad_lbn < NDADDR &&
- dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
+ prevlbn = adp->ad_offset;
+ if (adp->ad_offset < NDADDR &&
+ dp->di_db[adp->ad_offset] != adp->ad_newblkno)
panic("%s: direct pointer #%jd mismatch %jd != %jd",
"softdep_write_inodeblock",
- (intmax_t)adp->ad_lbn,
- (intmax_t)dp->di_db[adp->ad_lbn],
+ (intmax_t)adp->ad_offset,
+ (intmax_t)dp->di_db[adp->ad_offset],
(intmax_t)adp->ad_newblkno);
- if (adp->ad_lbn >= NDADDR &&
- dp->di_ib[adp->ad_lbn - NDADDR] != adp->ad_newblkno)
+ if (adp->ad_offset >= NDADDR &&
+ dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno)
panic("%s indirect pointer #%jd mismatch %jd != %jd",
"softdep_write_inodeblock:",
- (intmax_t)adp->ad_lbn - NDADDR,
- (intmax_t)dp->di_ib[adp->ad_lbn - NDADDR],
+ (intmax_t)adp->ad_offset - NDADDR,
+ (intmax_t)dp->di_ib[adp->ad_offset - NDADDR],
(intmax_t)adp->ad_newblkno);
- deplist |= 1 << adp->ad_lbn;
+ deplist |= 1 << adp->ad_offset;
if ((adp->ad_state & ATTACHED) == 0)
panic("softdep_write_inodeblock: Unknown state 0x%x",
adp->ad_state);
@@ -4187,14 +8328,14 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
*/
for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
- if (adp->ad_lbn >= NDADDR)
+ if (adp->ad_offset >= NDADDR)
break;
- dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
+ dp->di_db[adp->ad_offset] = adp->ad_oldblkno;
/* keep going until hitting a rollback to a frag */
if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
continue;
- dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
- for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
+ dp->di_size = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize;
+ for (i = adp->ad_offset + 1; i < NDADDR; i++) {
#ifdef INVARIANTS
if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
panic("softdep_write_inodeblock: lost dep2");
@@ -4218,8 +8359,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
* we already checked for fragments in the loop above.
*/
if (lastadp != NULL &&
- dp->di_size <= (lastadp->ad_lbn + 1) * fs->fs_bsize) {
- for (i = lastadp->ad_lbn; i >= 0; i--)
+ dp->di_size <= (lastadp->ad_offset + 1) * fs->fs_bsize) {
+ for (i = lastadp->ad_offset; i >= 0; i--)
if (dp->di_db[i] != 0)
break;
dp->di_size = (i + 1) * fs->fs_bsize;
@@ -4236,7 +8377,355 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
* postpone fsck, we are stuck with this argument.
*/
for (; adp; adp = TAILQ_NEXT(adp, ad_next))
- dp->di_ib[adp->ad_lbn - NDADDR] = 0;
+ dp->di_ib[adp->ad_offset - NDADDR] = 0;
+}
+
+/*
+ * Cancel an indirdep as a result of truncation. Release all of the
+ * children allocindirs and place their journal work on the appropriate
+ * list.
+ */
+static void
+cancel_indirdep(indirdep, bp, inodedep, freeblks)
+ struct indirdep *indirdep;
+ struct buf *bp;
+ struct inodedep *inodedep;
+ struct freeblks *freeblks;
+{
+ struct allocindir *aip;
+
+ /*
+ * None of the indirect pointers will ever be visible,
+ * so they can simply be tossed. GOINGAWAY ensures
+ * that allocated pointers will be saved in the buffer
+ * cache until they are freed. Note that they will
+ * only be able to be found by their physical address
+ * since the inode mapping the logical address will
+ * be gone. The save buffer used for the safe copy
+ * was allocated in setup_allocindir_phase2 using
+ * the physical address so it could be used for this
+ * purpose. Hence we swap the safe copy with the real
+ * copy, allowing the safe copy to be freed and holding
+ * on to the real copy for later use in indir_trunc.
+ */
+ if (indirdep->ir_state & GOINGAWAY)
+ panic("cancel_indirdep: already gone");
+ if (indirdep->ir_state & ONDEPLIST) {
+ indirdep->ir_state &= ~ONDEPLIST;
+ LIST_REMOVE(indirdep, ir_next);
+ }
+ indirdep->ir_state |= GOINGAWAY;
+ VFSTOUFS(indirdep->ir_list.wk_mp)->um_numindirdeps += 1;
+ while ((aip = LIST_FIRST(&indirdep->ir_deplisthd)) != 0)
+ cancel_allocindir(aip, inodedep, freeblks);
+ while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0)
+ cancel_allocindir(aip, inodedep, freeblks);
+ while ((aip = LIST_FIRST(&indirdep->ir_writehd)) != 0)
+ cancel_allocindir(aip, inodedep, freeblks);
+ while ((aip = LIST_FIRST(&indirdep->ir_completehd)) != 0)
+ cancel_allocindir(aip, inodedep, freeblks);
+ bcopy(bp->b_data, indirdep->ir_savebp->b_data, bp->b_bcount);
+ WORKLIST_REMOVE(&indirdep->ir_list);
+ WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, &indirdep->ir_list);
+ indirdep->ir_savebp = NULL;
+}
+
+/*
+ * Free an indirdep once it no longer has new pointers to track.
+ */
+static void
+free_indirdep(indirdep)
+ struct indirdep *indirdep;
+{
+
+ KASSERT(LIST_EMPTY(&indirdep->ir_jwork),
+ ("free_indirdep: Journal work not empty."));
+ KASSERT(LIST_EMPTY(&indirdep->ir_completehd),
+ ("free_indirdep: Complete head not empty."));
+ KASSERT(LIST_EMPTY(&indirdep->ir_writehd),
+ ("free_indirdep: write head not empty."));
+ KASSERT(LIST_EMPTY(&indirdep->ir_donehd),
+ ("free_indirdep: done head not empty."));
+ KASSERT(LIST_EMPTY(&indirdep->ir_deplisthd),
+ ("free_indirdep: deplist head not empty."));
+ KASSERT(indirdep->ir_savebp == NULL,
+ ("free_indirdep: %p ir_savebp != NULL", indirdep));
+ KASSERT((indirdep->ir_state & ONDEPLIST) == 0,
+ ("free_indirdep: %p still on deplist.", indirdep));
+ if (indirdep->ir_state & ONWORKLIST)
+ WORKLIST_REMOVE(&indirdep->ir_list);
+ WORKITEM_FREE(indirdep, D_INDIRDEP);
+}
+
+/*
+ * Called before a write to an indirdep. This routine is responsible for
+ * rolling back pointers to a safe state which includes only those
+ * allocindirs which have been completed.
+ */
+static void
+initiate_write_indirdep(indirdep, bp)
+ struct indirdep *indirdep;
+ struct buf *bp;
+{
+
+ if (indirdep->ir_state & GOINGAWAY)
+ panic("disk_io_initiation: indirdep gone");
+
+ /*
+ * If there are no remaining dependencies, this will be writing
+ * the real pointers.
+ */
+ if (LIST_EMPTY(&indirdep->ir_deplisthd))
+ return;
+ /*
+ * Replace up-to-date version with safe version.
+ */
+ FREE_LOCK(&lk);
+ indirdep->ir_saveddata = malloc(bp->b_bcount, M_INDIRDEP,
+ M_SOFTDEP_FLAGS);
+ ACQUIRE_LOCK(&lk);
+ indirdep->ir_state &= ~ATTACHED;
+ indirdep->ir_state |= UNDONE;
+ bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount);
+ bcopy(indirdep->ir_savebp->b_data, bp->b_data,
+ bp->b_bcount);
+}
+
+/*
+ * Called when an inode has been cleared in a cg bitmap. This finally
+ * eliminates any canceled jaddrefs
+ */
+void
+softdep_setup_inofree(mp, bp, ino, wkhd)
+ struct mount *mp;
+ struct buf *bp;
+ ino_t ino;
+ struct workhead *wkhd;
+{
+ struct worklist *wk, *wkn;
+ struct inodedep *inodedep;
+ uint8_t *inosused;
+ struct cg *cgp;
+ struct fs *fs;
+
+ ACQUIRE_LOCK(&lk);
+ fs = VFSTOUFS(mp)->um_fs;
+ cgp = (struct cg *)bp->b_data;
+ inosused = cg_inosused(cgp);
+ if (isset(inosused, ino % fs->fs_ipg))
+ panic("softdep_setup_inofree: inode %d not freed.", ino);
+ if (inodedep_lookup(mp, ino, 0, &inodedep))
+ panic("softdep_setup_inofree: ino %d has existing inodedep %p",
+ ino, inodedep);
+ if (wkhd) {
+ LIST_FOREACH_SAFE(wk, wkhd, wk_list, wkn) {
+ if (wk->wk_type != D_JADDREF)
+ continue;
+ WORKLIST_REMOVE(wk);
+ /*
+ * We can free immediately even if the jaddref
+ * isn't attached in a background write as now
+ * the bitmaps are reconciled.
+ */
+ wk->wk_state |= COMPLETE | ATTACHED;
+ free_jaddref(WK_JADDREF(wk));
+ }
+ jwork_move(&bp->b_dep, wkhd);
+ }
+ FREE_LOCK(&lk);
+}
+
+
+/*
+ * Called via ffs_blkfree() after a set of frags has been cleared from a cg
+ * map. Any dependencies waiting for the write to clear are added to the
+ * buf's list and any jnewblks that are being canceled are discarded
+ * immediately.
+ */
+void
+softdep_setup_blkfree(mp, bp, blkno, frags, wkhd)
+ struct mount *mp;
+ struct buf *bp;
+ ufs2_daddr_t blkno;
+ int frags;
+ struct workhead *wkhd;
+{
+ struct jnewblk *jnewblk;
+ struct worklist *wk, *wkn;
+#ifdef SUJ_DEBUG
+ struct bmsafemap *bmsafemap;
+ struct fs *fs;
+ uint8_t *blksfree;
+ struct cg *cgp;
+ ufs2_daddr_t jstart;
+ ufs2_daddr_t jend;
+ ufs2_daddr_t end;
+ long bno;
+ int i;
+#endif
+
+ ACQUIRE_LOCK(&lk);
+ /*
+ * Detach any jnewblks which have been canceled. They must linger
+ * until the bitmap is cleared again by ffs_blkfree() to prevent
+ * an unjournaled allocation from hitting the disk.
+ */
+ if (wkhd) {
+ LIST_FOREACH_SAFE(wk, wkhd, wk_list, wkn) {
+ if (wk->wk_type != D_JNEWBLK)
+ continue;
+ jnewblk = WK_JNEWBLK(wk);
+ KASSERT(jnewblk->jn_state & GOINGAWAY,
+ ("softdep_setup_blkfree: jnewblk not canceled."));
+ WORKLIST_REMOVE(wk);
+#ifdef SUJ_DEBUG
+ /*
+ * Assert that this block is free in the bitmap
+ * before we discard the jnewblk.
+ */
+ fs = VFSTOUFS(mp)->um_fs;
+ cgp = (struct cg *)bp->b_data;
+ blksfree = cg_blksfree(cgp);
+ bno = dtogd(fs, jnewblk->jn_blkno);
+ for (i = jnewblk->jn_oldfrags;
+ i < jnewblk->jn_frags; i++) {
+ if (isset(blksfree, bno + i))
+ continue;
+ panic("softdep_setup_blkfree: not free");
+ }
+#endif
+ /*
+ * Even if it's not attached we can free immediately
+ * as the new bitmap is correct.
+ */
+ wk->wk_state |= COMPLETE | ATTACHED;
+ free_jnewblk(jnewblk);
+ }
+ /*
+ * The buf must be locked by the caller otherwise these could
+ * be added while it's being written and the write would
+ * complete them before they made it to disk.
+ */
+ jwork_move(&bp->b_dep, wkhd);
+ }
+
+#ifdef SUJ_DEBUG
+ /*
+ * Assert that we are not freeing a block which has an outstanding
+ * allocation dependency.
+ */
+ fs = VFSTOUFS(mp)->um_fs;
+ bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno));
+ end = blkno + frags;
+ LIST_FOREACH(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps) {
+ /*
+ * Don't match against blocks that will be freed when the
+ * background write is done.
+ */
+ if ((jnewblk->jn_state & (ATTACHED | COMPLETE | DEPCOMPLETE)) ==
+ (COMPLETE | DEPCOMPLETE))
+ continue;
+ jstart = jnewblk->jn_blkno + jnewblk->jn_oldfrags;
+ jend = jnewblk->jn_blkno + jnewblk->jn_frags;
+ if ((blkno >= jstart && blkno < jend) ||
+ (end > jstart && end <= jend)) {
+ printf("state 0x%X %jd - %d %d dep %p\n",
+ jnewblk->jn_state, jnewblk->jn_blkno,
+ jnewblk->jn_oldfrags, jnewblk->jn_frags,
+ jnewblk->jn_newblk);
+ panic("softdep_setup_blkfree: "
+ "%jd-%jd(%d) overlaps with %jd-%jd",
+ blkno, end, frags, jstart, jend);
+ }
+ }
+#endif
+ FREE_LOCK(&lk);
+}
+
+static void
+initiate_write_bmsafemap(bmsafemap, bp)
+ struct bmsafemap *bmsafemap;
+ struct buf *bp; /* The cg block. */
+{
+ struct jaddref *jaddref;
+ struct jnewblk *jnewblk;
+ uint8_t *inosused;
+ uint8_t *blksfree;
+ struct cg *cgp;
+ struct fs *fs;
+ int cleared;
+ ino_t ino;
+ long bno;
+ int i;
+
+ if (bmsafemap->sm_state & IOSTARTED)
+ panic("initiate_write_bmsafemap: Already started\n");
+ bmsafemap->sm_state |= IOSTARTED;
+ /*
+ * Clear any inode allocations which are pending journal writes.
+ */
+ if (LIST_FIRST(&bmsafemap->sm_jaddrefhd) != NULL) {
+ cgp = (struct cg *)bp->b_data;
+ fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
+ inosused = cg_inosused(cgp);
+ LIST_FOREACH(jaddref, &bmsafemap->sm_jaddrefhd, ja_bmdeps) {
+ ino = jaddref->ja_ino % fs->fs_ipg;
+ /*
+ * If this is a background copy the inode may not
+ * be marked used yet.
+ */
+ if (isset(inosused, ino)) {
+ if ((jaddref->ja_mode & IFMT) == IFDIR)
+ cgp->cg_cs.cs_ndir--;
+ cgp->cg_cs.cs_nifree++;
+ clrbit(inosused, ino);
+ jaddref->ja_state &= ~ATTACHED;
+ jaddref->ja_state |= UNDONE;
+ stat_jaddref++;
+ } else if ((bp->b_xflags & BX_BKGRDMARKER) == 0)
+ panic("initiate_write_bmsafemap: inode %d "
+ "marked free", jaddref->ja_ino);
+ }
+ }
+ /*
+ * Clear any block allocations which are pending journal writes.
+ */
+ if (LIST_FIRST(&bmsafemap->sm_jnewblkhd) != NULL) {
+ cgp = (struct cg *)bp->b_data;
+ fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
+ blksfree = cg_blksfree(cgp);
+ LIST_FOREACH(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps) {
+ bno = dtogd(fs, jnewblk->jn_blkno);
+ cleared = 0;
+ for (i = jnewblk->jn_oldfrags; i < jnewblk->jn_frags;
+ i++) {
+ if (isclr(blksfree, bno + i)) {
+ cleared = 1;
+ setbit(blksfree, bno + i);
+ }
+ }
+ /*
+ * We may not clear the block if it's a background
+ * copy. In that case there is no reason to detach
+ * it.
+ */
+ if (cleared) {
+ stat_jnewblk++;
+ jnewblk->jn_state &= ~ATTACHED;
+ jnewblk->jn_state |= UNDONE;
+ } else if ((bp->b_xflags & BX_BKGRDMARKER) == 0)
+ panic("initiate_write_bmsafemap: block %jd "
+ "marked free", jnewblk->jn_blkno);
+ }
+ }
+ /*
+ * Move allocation lists to the written lists so they can be
+ * cleared once the block write is complete.
+ */
+ LIST_SWAP(&bmsafemap->sm_inodedephd, &bmsafemap->sm_inodedepwr,
+ inodedep, id_deps);
+ LIST_SWAP(&bmsafemap->sm_newblkhd, &bmsafemap->sm_newblkwr,
+ newblk, nb_deps);
}
/*
@@ -4246,6 +8735,7 @@ initiate_write_inodeblock_ufs2(inodedep, bp)
* a request completion). It should be called early in this
* procedure, before the block is made available to other
* processes or other routines are called.
+ *
*/
static void
softdep_disk_write_complete(bp)
@@ -4254,12 +8744,7 @@ softdep_disk_write_complete(bp)
struct worklist *wk;
struct worklist *owk;
struct workhead reattach;
- struct newblk *newblk;
- struct allocindir *aip;
- struct allocdirect *adp;
- struct indirdep *indirdep;
- struct inodedep *inodedep;
- struct bmsafemap *bmsafemap;
+ struct buf *sbp;
/*
* If an error occurred while doing the write, then the data
@@ -4271,8 +8756,9 @@ softdep_disk_write_complete(bp)
/*
* This lock must not be released anywhere in this code segment.
*/
- ACQUIRE_LOCK(&lk);
+ sbp = NULL;
owk = NULL;
+ ACQUIRE_LOCK(&lk);
while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
WORKLIST_REMOVE(wk);
if (wk == owk)
@@ -4291,33 +8777,8 @@ softdep_disk_write_complete(bp)
continue;
case D_BMSAFEMAP:
- bmsafemap = WK_BMSAFEMAP(wk);
- while ((newblk = LIST_FIRST(&bmsafemap->sm_newblkhd))) {
- newblk->nb_state |= DEPCOMPLETE;
- newblk->nb_bmsafemap = NULL;
- LIST_REMOVE(newblk, nb_deps);
- }
- while ((adp =
- LIST_FIRST(&bmsafemap->sm_allocdirecthd))) {
- adp->ad_state |= DEPCOMPLETE;
- adp->ad_buf = NULL;
- LIST_REMOVE(adp, ad_deps);
- handle_allocdirect_partdone(adp);
- }
- while ((aip =
- LIST_FIRST(&bmsafemap->sm_allocindirhd))) {
- aip->ai_state |= DEPCOMPLETE;
- aip->ai_buf = NULL;
- LIST_REMOVE(aip, ai_deps);
- handle_allocindir_partdone(aip);
- }
- while ((inodedep =
- LIST_FIRST(&bmsafemap->sm_inodedephd)) != NULL) {
- inodedep->id_state |= DEPCOMPLETE;
- LIST_REMOVE(inodedep, id_deps);
- inodedep->id_buf = NULL;
- }
- WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
+ if (handle_written_bmsafemap(WK_BMSAFEMAP(wk), bp))
+ WORKLIST_INSERT(&reattach, wk);
continue;
case D_MKDIR:
@@ -4325,35 +8786,45 @@ softdep_disk_write_complete(bp)
continue;
case D_ALLOCDIRECT:
- adp = WK_ALLOCDIRECT(wk);
- adp->ad_state |= COMPLETE;
- handle_allocdirect_partdone(adp);
+ wk->wk_state |= COMPLETE;
+ handle_allocdirect_partdone(WK_ALLOCDIRECT(wk), NULL);
continue;
case D_ALLOCINDIR:
- aip = WK_ALLOCINDIR(wk);
- aip->ai_state |= COMPLETE;
- handle_allocindir_partdone(aip);
+ wk->wk_state |= COMPLETE;
+ handle_allocindir_partdone(WK_ALLOCINDIR(wk));
continue;
case D_INDIRDEP:
- indirdep = WK_INDIRDEP(wk);
- if (indirdep->ir_state & GOINGAWAY)
- panic("disk_write_complete: indirdep gone");
- bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount);
- free(indirdep->ir_saveddata, M_INDIRDEP);
- indirdep->ir_saveddata = 0;
- indirdep->ir_state &= ~UNDONE;
- indirdep->ir_state |= ATTACHED;
- while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) {
- handle_allocindir_partdone(aip);
- if (aip == LIST_FIRST(&indirdep->ir_donehd))
- panic("disk_write_complete: not gone");
- }
- WORKLIST_INSERT(&reattach, wk);
- if ((bp->b_flags & B_DELWRI) == 0)
- stat_indir_blk_ptrs++;
- bdirty(bp);
+ if (handle_written_indirdep(WK_INDIRDEP(wk), bp, &sbp))
+ WORKLIST_INSERT(&reattach, wk);
+ continue;
+
+ case D_FREEBLKS:
+ wk->wk_state |= COMPLETE;
+ if ((wk->wk_state & ALLCOMPLETE) == ALLCOMPLETE)
+ add_to_worklist(wk, 1);
+ continue;
+
+ case D_FREEWORK:
+ handle_written_freework(WK_FREEWORK(wk));
+ break;
+
+ case D_FREEDEP:
+ free_freedep(WK_FREEDEP(wk));
+ continue;
+
+ case D_JSEGDEP:
+ free_jsegdep(WK_JSEGDEP(wk));
+ continue;
+
+ case D_JSEG:
+ handle_written_jseg(WK_JSEG(wk), bp);
+ continue;
+
+ case D_SBDEP:
+ if (handle_written_sbdep(WK_SBDEP(wk), bp))
+ WORKLIST_INSERT(&reattach, wk);
continue;
default:
@@ -4370,6 +8841,8 @@ softdep_disk_write_complete(bp)
WORKLIST_INSERT(&bp->b_dep, wk);
}
FREE_LOCK(&lk);
+ if (sbp)
+ brelse(sbp);
}
/*
@@ -4378,18 +8851,17 @@ softdep_disk_write_complete(bp)
* splbio interrupts blocked.
*/
static void
-handle_allocdirect_partdone(adp)
+handle_allocdirect_partdone(adp, wkhd)
struct allocdirect *adp; /* the completed allocdirect */
+ struct workhead *wkhd; /* Work to do when inode is writtne. */
{
struct allocdirectlst *listhead;
struct allocdirect *listadp;
struct inodedep *inodedep;
- long bsize, delay;
+ long bsize;
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
return;
- if (adp->ad_buf != NULL)
- panic("handle_allocdirect_partdone: dangling dep");
/*
* The on-disk inode cannot claim to be any larger than the last
* fragment that has been written. Otherwise, the on-disk inode
@@ -4439,25 +8911,27 @@ handle_allocdirect_partdone(adp)
return;
}
/*
- * If we have found the just finished dependency, then free
+ * If we have found the just finished dependency, then queue
* it along with anything that follows it that is complete.
- * If the inode still has a bitmap dependency, then it has
- * never been written to disk, hence the on-disk inode cannot
- * reference the old fragment so we can free it without delay.
+ * Since the pointer has not yet been written in the inode
+ * as the dependency prevents it, place the allocdirect on the
+ * bufwait list where it will be freed once the pointer is
+ * valid.
*/
- delay = (inodedep->id_state & DEPCOMPLETE);
+ if (wkhd == NULL)
+ wkhd = &inodedep->id_bufwait;
for (; adp; adp = listadp) {
listadp = TAILQ_NEXT(adp, ad_next);
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
return;
- free_allocdirect(listhead, adp, delay);
+ TAILQ_REMOVE(listhead, adp, ad_next);
+ WORKLIST_INSERT(wkhd, &adp->ad_block.nb_list);
}
}
/*
- * Called from within softdep_disk_write_complete above. Note that
- * this routine is always called from interrupt level with further
- * splbio interrupts blocked.
+ * Called from within softdep_disk_write_complete above. This routine
+ * completes successfully written allocindirs.
*/
static void
handle_allocindir_partdone(aip)
@@ -4467,11 +8941,9 @@ handle_allocindir_partdone(aip)
if ((aip->ai_state & ALLCOMPLETE) != ALLCOMPLETE)
return;
- if (aip->ai_buf != NULL)
- panic("handle_allocindir_partdone: dangling dependency");
indirdep = aip->ai_indirdep;
+ LIST_REMOVE(aip, ai_next);
if (indirdep->ir_state & UNDONE) {
- LIST_REMOVE(aip, ai_next);
LIST_INSERT_HEAD(&indirdep->ir_donehd, aip, ai_next);
return;
}
@@ -4481,13 +8953,130 @@ handle_allocindir_partdone(aip)
else
((ufs2_daddr_t *)indirdep->ir_savebp->b_data)[aip->ai_offset] =
aip->ai_newblkno;
- LIST_REMOVE(aip, ai_next);
- if (aip->ai_freefrag != NULL)
- add_to_worklist(&aip->ai_freefrag->ff_list);
- WORKITEM_FREE(aip, D_ALLOCINDIR);
+ /*
+ * Await the pointer write before freeing the allocindir.
+ */
+ LIST_INSERT_HEAD(&indirdep->ir_writehd, aip, ai_next);
}
/*
+ * Release segments held on a jwork list.
+ */
+static void
+handle_jwork(wkhd)
+ struct workhead *wkhd;
+{
+ struct worklist *wk;
+
+ while ((wk = LIST_FIRST(wkhd)) != NULL) {
+ WORKLIST_REMOVE(wk);
+ switch (wk->wk_type) {
+ case D_JSEGDEP:
+ free_jsegdep(WK_JSEGDEP(wk));
+ continue;
+ default:
+ panic("handle_jwork: Unknown type %s\n",
+ TYPENAME(wk->wk_type));
+ }
+ }
+}
+
+/*
+ * Handle the bufwait list on an inode when it is safe to release items
+ * held there. This normally happens after an inode block is written but
+ * may be delayed and handle later if there are pending journal items that
+ * are not yet safe to be released.
+ */
+static struct freefile *
+handle_bufwait(inodedep, refhd)
+ struct inodedep *inodedep;
+ struct workhead *refhd;
+{
+ struct jaddref *jaddref;
+ struct freefile *freefile;
+ struct worklist *wk;
+
+ freefile = NULL;
+ while ((wk = LIST_FIRST(&inodedep->id_bufwait)) != NULL) {
+ WORKLIST_REMOVE(wk);
+ switch (wk->wk_type) {
+ case D_FREEFILE:
+ /*
+ * We defer adding freefile to the worklist
+ * until all other additions have been made to
+ * ensure that it will be done after all the
+ * old blocks have been freed.
+ */
+ if (freefile != NULL)
+ panic("handle_bufwait: freefile");
+ freefile = WK_FREEFILE(wk);
+ continue;
+
+ case D_MKDIR:
+ handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
+ continue;
+
+ case D_DIRADD:
+ diradd_inode_written(WK_DIRADD(wk), inodedep);
+ continue;
+
+ case D_FREEFRAG:
+ wk->wk_state |= COMPLETE;
+ if ((wk->wk_state & ALLCOMPLETE) == ALLCOMPLETE)
+ add_to_worklist(wk, 0);
+ continue;
+
+ case D_DIRREM:
+ wk->wk_state |= COMPLETE;
+ add_to_worklist(wk, 0);
+ continue;
+
+ case D_ALLOCDIRECT:
+ case D_ALLOCINDIR:
+ free_newblk(WK_NEWBLK(wk));
+ continue;
+
+ case D_JNEWBLK:
+ wk->wk_state |= COMPLETE;
+ free_jnewblk(WK_JNEWBLK(wk));
+ continue;
+
+ /*
+ * Save freed journal segments and add references on
+ * the supplied list which will delay their release
+ * until the cg bitmap is cleared on disk.
+ */
+ case D_JSEGDEP:
+ if (refhd == NULL)
+ free_jsegdep(WK_JSEGDEP(wk));
+ else
+ WORKLIST_INSERT(refhd, wk);
+ continue;
+
+ case D_JADDREF:
+ jaddref = WK_JADDREF(wk);
+ TAILQ_REMOVE(&inodedep->id_inoreflst, &jaddref->ja_ref,
+ if_deps);
+ /*
+ * Transfer any jaddrefs to the list to be freed with
+ * the bitmap if we're handling a removed file.
+ */
+ if (refhd == NULL) {
+ wk->wk_state |= COMPLETE;
+ free_jaddref(jaddref);
+ } else
+ WORKLIST_INSERT(refhd, wk);
+ continue;
+
+ default:
+ panic("handle_bufwait: Unknown type %p(%s)",
+ wk, TYPENAME(wk->wk_type));
+ /* NOTREACHED */
+ }
+ }
+ return (freefile);
+}
+/*
* Called from within softdep_disk_write_complete above to restore
* in-memory inode block contents to their most up-to-date state. Note
* that this routine is always called from interrupt level with further
@@ -4498,12 +9087,17 @@ handle_written_inodeblock(inodedep, bp)
struct inodedep *inodedep;
struct buf *bp; /* buffer containing the inode block */
{
- struct worklist *wk, *filefree;
+ struct freefile *freefile;
struct allocdirect *adp, *nextadp;
struct ufs1_dinode *dp1 = NULL;
struct ufs2_dinode *dp2 = NULL;
+ struct workhead wkhd;
int hadchanges, fstype;
+ ino_t freelink;
+ LIST_INIT(&wkhd);
+ hadchanges = 0;
+ freefile = NULL;
if ((inodedep->id_state & IOSTARTED) == 0)
panic("handle_written_inodeblock: not started");
inodedep->id_state &= ~IOSTARTED;
@@ -4511,11 +9105,32 @@ handle_written_inodeblock(inodedep, bp)
fstype = UFS1;
dp1 = (struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(inodedep->id_fs, inodedep->id_ino);
+ freelink = dp1->di_freelink;
} else {
fstype = UFS2;
dp2 = (struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(inodedep->id_fs, inodedep->id_ino);
+ freelink = dp2->di_freelink;
+ }
+ /*
+ * If we wrote a valid freelink pointer during the last write
+ * record it here.
+ */
+ if ((inodedep->id_state & (UNLINKED | UNLINKNEXT)) == UNLINKED) {
+ struct inodedep *inon;
+
+ inon = TAILQ_NEXT(inodedep, id_unlinked);
+ if ((inon == NULL && freelink == 0) ||
+ (inon && inon->id_ino == freelink)) {
+ if (inon)
+ inon->id_state |= UNLINKPREV;
+ inodedep->id_state |= UNLINKNEXT;
+ } else
+ hadchanges = 1;
}
+ /* Leave this inodeblock dirty until it's in the list. */
+ if ((inodedep->id_state & (UNLINKED | DEPCOMPLETE)) == UNLINKED)
+ hadchanges = 1;
/*
* If we had to rollback the inode allocation because of
* bitmaps being incomplete, then simply restore it.
@@ -4524,6 +9139,7 @@ handle_written_inodeblock(inodedep, bp)
* corresponding updates written to disk.
*/
if (inodedep->id_savedino1 != NULL) {
+ hadchanges = 1;
if (fstype == UFS1)
*dp1 = *inodedep->id_savedino1;
else
@@ -4533,6 +9149,13 @@ handle_written_inodeblock(inodedep, bp)
if ((bp->b_flags & B_DELWRI) == 0)
stat_inode_bitmap++;
bdirty(bp);
+ /*
+ * If the inode is clear here and GOINGAWAY it will never
+ * be written. Process the bufwait and clear any pending
+ * work which may include the freefile.
+ */
+ if (inodedep->id_state & GOINGAWAY)
+ goto bufwait;
return (1);
}
inodedep->id_state |= COMPLETE;
@@ -4540,50 +9163,49 @@ handle_written_inodeblock(inodedep, bp)
* Roll forward anything that had to be rolled back before
* the inode could be updated.
*/
- hadchanges = 0;
for (adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp; adp = nextadp) {
nextadp = TAILQ_NEXT(adp, ad_next);
if (adp->ad_state & ATTACHED)
panic("handle_written_inodeblock: new entry");
if (fstype == UFS1) {
- if (adp->ad_lbn < NDADDR) {
- if (dp1->di_db[adp->ad_lbn]!=adp->ad_oldblkno)
+ if (adp->ad_offset < NDADDR) {
+ if (dp1->di_db[adp->ad_offset]!=adp->ad_oldblkno)
panic("%s %s #%jd mismatch %d != %jd",
"handle_written_inodeblock:",
"direct pointer",
- (intmax_t)adp->ad_lbn,
- dp1->di_db[adp->ad_lbn],
+ (intmax_t)adp->ad_offset,
+ dp1->di_db[adp->ad_offset],
(intmax_t)adp->ad_oldblkno);
- dp1->di_db[adp->ad_lbn] = adp->ad_newblkno;
+ dp1->di_db[adp->ad_offset] = adp->ad_newblkno;
} else {
- if (dp1->di_ib[adp->ad_lbn - NDADDR] != 0)
+ if (dp1->di_ib[adp->ad_offset - NDADDR] != 0)
panic("%s: %s #%jd allocated as %d",
"handle_written_inodeblock",
"indirect pointer",
- (intmax_t)adp->ad_lbn - NDADDR,
- dp1->di_ib[adp->ad_lbn - NDADDR]);
- dp1->di_ib[adp->ad_lbn - NDADDR] =
+ (intmax_t)adp->ad_offset - NDADDR,
+ dp1->di_ib[adp->ad_offset - NDADDR]);
+ dp1->di_ib[adp->ad_offset - NDADDR] =
adp->ad_newblkno;
}
} else {
- if (adp->ad_lbn < NDADDR) {
- if (dp2->di_db[adp->ad_lbn]!=adp->ad_oldblkno)
+ if (adp->ad_offset < NDADDR) {
+ if (dp2->di_db[adp->ad_offset]!=adp->ad_oldblkno)
panic("%s: %s #%jd %s %jd != %jd",
"handle_written_inodeblock",
"direct pointer",
- (intmax_t)adp->ad_lbn, "mismatch",
- (intmax_t)dp2->di_db[adp->ad_lbn],
+ (intmax_t)adp->ad_offset, "mismatch",
+ (intmax_t)dp2->di_db[adp->ad_offset],
(intmax_t)adp->ad_oldblkno);
- dp2->di_db[adp->ad_lbn] = adp->ad_newblkno;
+ dp2->di_db[adp->ad_offset] = adp->ad_newblkno;
} else {
- if (dp2->di_ib[adp->ad_lbn - NDADDR] != 0)
+ if (dp2->di_ib[adp->ad_offset - NDADDR] != 0)
panic("%s: %s #%jd allocated as %jd",
"handle_written_inodeblock",
"indirect pointer",
- (intmax_t)adp->ad_lbn - NDADDR,
+ (intmax_t)adp->ad_offset - NDADDR,
(intmax_t)
- dp2->di_ib[adp->ad_lbn - NDADDR]);
- dp2->di_ib[adp->ad_lbn - NDADDR] =
+ dp2->di_ib[adp->ad_offset - NDADDR]);
+ dp2->di_ib[adp->ad_offset - NDADDR] =
adp->ad_newblkno;
}
}
@@ -4595,13 +9217,13 @@ handle_written_inodeblock(inodedep, bp)
nextadp = TAILQ_NEXT(adp, ad_next);
if (adp->ad_state & ATTACHED)
panic("handle_written_inodeblock: new entry");
- if (dp2->di_extb[adp->ad_lbn] != adp->ad_oldblkno)
+ if (dp2->di_extb[adp->ad_offset] != adp->ad_oldblkno)
panic("%s: direct pointers #%jd %s %jd != %jd",
"handle_written_inodeblock",
- (intmax_t)adp->ad_lbn, "mismatch",
- (intmax_t)dp2->di_extb[adp->ad_lbn],
+ (intmax_t)adp->ad_offset, "mismatch",
+ (intmax_t)dp2->di_extb[adp->ad_offset],
(intmax_t)adp->ad_oldblkno);
- dp2->di_extb[adp->ad_lbn] = adp->ad_newblkno;
+ dp2->di_extb[adp->ad_offset] = adp->ad_newblkno;
adp->ad_state &= ~UNDONE;
adp->ad_state |= ATTACHED;
hadchanges = 1;
@@ -4613,12 +9235,23 @@ handle_written_inodeblock(inodedep, bp)
*/
if (inodedep->id_savedsize == -1 || inodedep->id_savedextsize == -1)
panic("handle_written_inodeblock: bad size");
+ if (inodedep->id_savednlink > LINK_MAX)
+ panic("handle_written_inodeblock: Invalid link count "
+ "%d for inodedep %p", inodedep->id_savednlink, inodedep);
if (fstype == UFS1) {
+ if (dp1->di_nlink != inodedep->id_savednlink) {
+ dp1->di_nlink = inodedep->id_savednlink;
+ hadchanges = 1;
+ }
if (dp1->di_size != inodedep->id_savedsize) {
dp1->di_size = inodedep->id_savedsize;
hadchanges = 1;
}
} else {
+ if (dp2->di_nlink != inodedep->id_savednlink) {
+ dp2->di_nlink = inodedep->id_savednlink;
+ hadchanges = 1;
+ }
if (dp2->di_size != inodedep->id_savedsize) {
dp2->di_size = inodedep->id_savedsize;
hadchanges = 1;
@@ -4630,6 +9263,7 @@ handle_written_inodeblock(inodedep, bp)
}
inodedep->id_savedsize = -1;
inodedep->id_savedextsize = -1;
+ inodedep->id_savednlink = -1;
/*
* If there were any rollbacks in the inode block, then it must be
* marked dirty so that its will eventually get written back in
@@ -4637,69 +9271,49 @@ handle_written_inodeblock(inodedep, bp)
*/
if (hadchanges)
bdirty(bp);
+bufwait:
/*
* Process any allocdirects that completed during the update.
*/
if ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != NULL)
- handle_allocdirect_partdone(adp);
+ handle_allocdirect_partdone(adp, &wkhd);
if ((adp = TAILQ_FIRST(&inodedep->id_extupdt)) != NULL)
- handle_allocdirect_partdone(adp);
+ handle_allocdirect_partdone(adp, &wkhd);
/*
* Process deallocations that were held pending until the
* inode had been written to disk. Freeing of the inode
* is delayed until after all blocks have been freed to
* avoid creation of new <vfsid, inum, lbn> triples
- * before the old ones have been deleted.
+ * before the old ones have been deleted. Completely
+ * unlinked inodes are not processed until the unlinked
+ * inode list is written or the last reference is removed.
*/
- filefree = NULL;
- while ((wk = LIST_FIRST(&inodedep->id_bufwait)) != NULL) {
- WORKLIST_REMOVE(wk);
- switch (wk->wk_type) {
-
- case D_FREEFILE:
- /*
- * We defer adding filefree to the worklist until
- * all other additions have been made to ensure
- * that it will be done after all the old blocks
- * have been freed.
- */
- if (filefree != NULL)
- panic("handle_written_inodeblock: filefree");
- filefree = wk;
- continue;
-
- case D_MKDIR:
- handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
- continue;
-
- case D_DIRADD:
- diradd_inode_written(WK_DIRADD(wk), inodedep);
- continue;
-
- case D_FREEBLKS:
- wk->wk_state |= COMPLETE;
- if ((wk->wk_state & ALLCOMPLETE) != ALLCOMPLETE)
- continue;
- /* -- fall through -- */
- case D_FREEFRAG:
- case D_DIRREM:
- add_to_worklist(wk);
- continue;
-
- case D_NEWDIRBLK:
- free_newdirblk(WK_NEWDIRBLK(wk));
- continue;
-
- default:
- panic("handle_written_inodeblock: Unknown type %s",
- TYPENAME(wk->wk_type));
- /* NOTREACHED */
+ if ((inodedep->id_state & (UNLINKED | UNLINKONLIST)) != UNLINKED) {
+ freefile = handle_bufwait(inodedep, NULL);
+ if (freefile && !LIST_EMPTY(&wkhd)) {
+ WORKLIST_INSERT(&wkhd, &freefile->fx_list);
+ freefile = NULL;
}
}
- if (filefree != NULL) {
+ /*
+ * Move rolled forward dependency completions to the bufwait list
+ * now that those that were already written have been processed.
+ */
+ if (!LIST_EMPTY(&wkhd) && hadchanges == 0)
+ panic("handle_written_inodeblock: bufwait but no changes");
+ jwork_move(&inodedep->id_bufwait, &wkhd);
+
+ if (freefile != NULL) {
+ /*
+ * If the inode is goingaway it was never written. Fake up
+ * the state here so free_inodedep() can succeed.
+ */
+ if (inodedep->id_state & GOINGAWAY)
+ inodedep->id_state |= COMPLETE | DEPCOMPLETE;
if (free_inodedep(inodedep) == 0)
- panic("handle_written_inodeblock: live inodedep");
- add_to_worklist(filefree);
+ panic("handle_written_inodeblock: live inodedep %p",
+ inodedep);
+ add_to_worklist(&freefile->fx_list, 0);
return (0);
}
@@ -4707,12 +9321,101 @@ handle_written_inodeblock(inodedep, bp)
* If no outstanding dependencies, free it.
*/
if (free_inodedep(inodedep) ||
- (TAILQ_FIRST(&inodedep->id_inoupdt) == 0 &&
- TAILQ_FIRST(&inodedep->id_extupdt) == 0))
+ (TAILQ_FIRST(&inodedep->id_inoreflst) == 0 &&
+ TAILQ_FIRST(&inodedep->id_inoupdt) == 0 &&
+ TAILQ_FIRST(&inodedep->id_extupdt) == 0 &&
+ LIST_FIRST(&inodedep->id_bufwait) == 0))
return (0);
return (hadchanges);
}
+static int
+handle_written_indirdep(indirdep, bp, bpp)
+ struct indirdep *indirdep;
+ struct buf *bp;
+ struct buf **bpp;
+{
+ struct allocindir *aip;
+ int chgs;
+
+ if (indirdep->ir_state & GOINGAWAY)
+ panic("disk_write_complete: indirdep gone");
+ chgs = 0;
+ /*
+ * If there were rollbacks revert them here.
+ */
+ if (indirdep->ir_saveddata) {
+ bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount);
+ free(indirdep->ir_saveddata, M_INDIRDEP);
+ indirdep->ir_saveddata = 0;
+ chgs = 1;
+ }
+ indirdep->ir_state &= ~UNDONE;
+ indirdep->ir_state |= ATTACHED;
+ /*
+ * Move allocindirs with written pointers to the completehd if
+ * the the indirdep's pointer is not yet written. Otherwise
+ * free them here.
+ */
+ while ((aip = LIST_FIRST(&indirdep->ir_writehd)) != 0) {
+ LIST_REMOVE(aip, ai_next);
+ if ((indirdep->ir_state & DEPCOMPLETE) == 0) {
+ LIST_INSERT_HEAD(&indirdep->ir_completehd, aip,
+ ai_next);
+ continue;
+ }
+ free_newblk(&aip->ai_block);
+ }
+ /*
+ * Move allocindirs that have finished dependency processing from
+ * the done list to the write list after updating the pointers.
+ */
+ while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) {
+ handle_allocindir_partdone(aip);
+ if (aip == LIST_FIRST(&indirdep->ir_donehd))
+ panic("disk_write_complete: not gone");
+ chgs = 1;
+ }
+ /*
+ * If this indirdep has been detached from its newblk during
+ * I/O we need to keep this dep attached to the buffer so
+ * deallocate_dependencies can find it and properly resolve
+ * any outstanding dependencies.
+ */
+ if ((indirdep->ir_state & (ONDEPLIST | DEPCOMPLETE)) == 0)
+ chgs = 1;
+ if ((bp->b_flags & B_DELWRI) == 0)
+ stat_indir_blk_ptrs++;
+ /*
+ * If there were no changes we can discard the savedbp and detach
+ * ourselves from the buf. We are only carrying completed pointers
+ * in this case.
+ */
+ if (chgs == 0) {
+ struct buf *sbp;
+
+ sbp = indirdep->ir_savebp;
+ sbp->b_flags |= B_INVAL | B_NOCACHE;
+ indirdep->ir_savebp = NULL;
+ if (*bpp != NULL)
+ panic("handle_written_indirdep: bp already exists.");
+ *bpp = sbp;
+ } else
+ bdirty(bp);
+ /*
+ * If there are no fresh dependencies and none waiting on writes
+ * we can free the indirdep.
+ */
+ if ((indirdep->ir_state & DEPCOMPLETE) && chgs == 0) {
+ if (indirdep->ir_state & ONDEPLIST)
+ LIST_REMOVE(indirdep, ir_next);
+ free_indirdep(indirdep);
+ return (0);
+ }
+
+ return (chgs);
+}
+
/*
* Process a diradd entry after its dependent inode has been written.
* This routine must be called with splbio interrupts blocked.
@@ -4722,50 +9425,200 @@ diradd_inode_written(dap, inodedep)
struct diradd *dap;
struct inodedep *inodedep;
{
- struct pagedep *pagedep;
dap->da_state |= COMPLETE;
- if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
- if (dap->da_state & DIRCHG)
- pagedep = dap->da_previous->dm_pagedep;
- else
- pagedep = dap->da_pagedep;
- LIST_REMOVE(dap, da_pdlist);
- LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
- }
+ complete_diradd(dap);
WORKLIST_INSERT(&inodedep->id_pendinghd, &dap->da_list);
}
/*
- * Handle the completion of a mkdir dependency.
+ * Returns true if the bmsafemap will have rollbacks when written. Must
+ * only be called with lk and the buf lock on the cg held.
+ */
+static int
+bmsafemap_rollbacks(bmsafemap)
+ struct bmsafemap *bmsafemap;
+{
+
+ return (!LIST_EMPTY(&bmsafemap->sm_jaddrefhd) |
+ !LIST_EMPTY(&bmsafemap->sm_jnewblkhd));
+}
+
+/*
+ * Complete a write to a bmsafemap structure. Roll forward any bitmap
+ * changes if it's not a background write. Set all written dependencies
+ * to DEPCOMPLETE and free the structure if possible.
+ */
+static int
+handle_written_bmsafemap(bmsafemap, bp)
+ struct bmsafemap *bmsafemap;
+ struct buf *bp;
+{
+ struct newblk *newblk;
+ struct inodedep *inodedep;
+ struct jaddref *jaddref, *jatmp;
+ struct jnewblk *jnewblk, *jntmp;
+ uint8_t *inosused;
+ uint8_t *blksfree;
+ struct cg *cgp;
+ struct fs *fs;
+ ino_t ino;
+ long bno;
+ int chgs;
+ int i;
+
+ if ((bmsafemap->sm_state & IOSTARTED) == 0)
+ panic("initiate_write_bmsafemap: Not started\n");
+ chgs = 0;
+ bmsafemap->sm_state &= ~IOSTARTED;
+ /*
+ * Restore unwritten inode allocation pending jaddref writes.
+ */
+ if (!LIST_EMPTY(&bmsafemap->sm_jaddrefhd)) {
+ cgp = (struct cg *)bp->b_data;
+ fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
+ inosused = cg_inosused(cgp);
+ LIST_FOREACH_SAFE(jaddref, &bmsafemap->sm_jaddrefhd,
+ ja_bmdeps, jatmp) {
+ if ((jaddref->ja_state & UNDONE) == 0)
+ continue;
+ ino = jaddref->ja_ino % fs->fs_ipg;
+ if (isset(inosused, ino))
+ panic("handle_written_bmsafemap: "
+ "re-allocated inode");
+ if ((bp->b_xflags & BX_BKGRDMARKER) == 0) {
+ if ((jaddref->ja_mode & IFMT) == IFDIR)
+ cgp->cg_cs.cs_ndir++;
+ cgp->cg_cs.cs_nifree--;
+ setbit(inosused, ino);
+ chgs = 1;
+ }
+ jaddref->ja_state &= ~UNDONE;
+ jaddref->ja_state |= ATTACHED;
+ free_jaddref(jaddref);
+ }
+ }
+ /*
+ * Restore any block allocations which are pending journal writes.
+ */
+ if (LIST_FIRST(&bmsafemap->sm_jnewblkhd) != NULL) {
+ cgp = (struct cg *)bp->b_data;
+ fs = VFSTOUFS(bmsafemap->sm_list.wk_mp)->um_fs;
+ blksfree = cg_blksfree(cgp);
+ LIST_FOREACH_SAFE(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps,
+ jntmp) {
+ if ((jnewblk->jn_state & UNDONE) == 0)
+ continue;
+ bno = dtogd(fs, jnewblk->jn_blkno);
+ for (i = jnewblk->jn_oldfrags; i < jnewblk->jn_frags;
+ i++) {
+ if (bp->b_xflags & BX_BKGRDMARKER)
+ break;
+ if ((jnewblk->jn_state & NEWBLOCK) == 0 &&
+ isclr(blksfree, bno + i))
+ panic("handle_written_bmsafemap: "
+ "re-allocated fragment");
+ clrbit(blksfree, bno + i);
+ chgs = 1;
+ }
+ jnewblk->jn_state &= ~(UNDONE | NEWBLOCK);
+ jnewblk->jn_state |= ATTACHED;
+ free_jnewblk(jnewblk);
+ }
+ }
+ while ((newblk = LIST_FIRST(&bmsafemap->sm_newblkwr))) {
+ newblk->nb_state |= DEPCOMPLETE;
+ newblk->nb_state &= ~ONDEPLIST;
+ newblk->nb_bmsafemap = NULL;
+ LIST_REMOVE(newblk, nb_deps);
+ if (newblk->nb_list.wk_type == D_ALLOCDIRECT)
+ handle_allocdirect_partdone(
+ WK_ALLOCDIRECT(&newblk->nb_list), NULL);
+ else if (newblk->nb_list.wk_type == D_ALLOCINDIR)
+ handle_allocindir_partdone(
+ WK_ALLOCINDIR(&newblk->nb_list));
+ else if (newblk->nb_list.wk_type != D_NEWBLK)
+ panic("handle_written_bmsafemap: Unexpected type: %s",
+ TYPENAME(newblk->nb_list.wk_type));
+ }
+ while ((inodedep = LIST_FIRST(&bmsafemap->sm_inodedepwr)) != NULL) {
+ inodedep->id_state |= DEPCOMPLETE;
+ inodedep->id_state &= ~ONDEPLIST;
+ LIST_REMOVE(inodedep, id_deps);
+ inodedep->id_bmsafemap = NULL;
+ }
+ if (LIST_EMPTY(&bmsafemap->sm_jaddrefhd) &&
+ LIST_EMPTY(&bmsafemap->sm_jnewblkhd) &&
+ LIST_EMPTY(&bmsafemap->sm_newblkhd) &&
+ LIST_EMPTY(&bmsafemap->sm_inodedephd)) {
+ if (chgs)
+ bdirty(bp);
+ LIST_REMOVE(bmsafemap, sm_hash);
+ WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
+ return (0);
+ }
+ bdirty(bp);
+ return (1);
+}
+
+/*
+ * Try to free a mkdir dependency.
*/
static void
-handle_written_mkdir(mkdir, type)
+complete_mkdir(mkdir)
struct mkdir *mkdir;
- int type;
{
struct diradd *dap;
- struct pagedep *pagedep;
- if (mkdir->md_state != type)
- panic("handle_written_mkdir: bad type");
+ if ((mkdir->md_state & ALLCOMPLETE) != ALLCOMPLETE)
+ return;
+ LIST_REMOVE(mkdir, md_mkdirs);
dap = mkdir->md_diradd;
- dap->da_state &= ~type;
- if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0)
+ dap->da_state &= ~(mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY));
+ if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0) {
dap->da_state |= DEPCOMPLETE;
- if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
- if (dap->da_state & DIRCHG)
- pagedep = dap->da_previous->dm_pagedep;
- else
- pagedep = dap->da_pagedep;
- LIST_REMOVE(dap, da_pdlist);
- LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
+ complete_diradd(dap);
}
- LIST_REMOVE(mkdir, md_mkdirs);
WORKITEM_FREE(mkdir, D_MKDIR);
}
/*
+ * Handle the completion of a mkdir dependency.
+ */
+static void
+handle_written_mkdir(mkdir, type)
+ struct mkdir *mkdir;
+ int type;
+{
+
+ if ((mkdir->md_state & (MKDIR_PARENT | MKDIR_BODY)) != type)
+ panic("handle_written_mkdir: bad type");
+ mkdir->md_state |= COMPLETE;
+ complete_mkdir(mkdir);
+}
+
+static void
+free_pagedep(pagedep)
+ struct pagedep *pagedep;
+{
+ int i;
+
+ if (pagedep->pd_state & (NEWBLOCK | ONWORKLIST))
+ return;
+ for (i = 0; i < DAHASHSZ; i++)
+ if (!LIST_EMPTY(&pagedep->pd_diraddhd[i]))
+ return;
+ if (!LIST_EMPTY(&pagedep->pd_jmvrefhd))
+ return;
+ if (!LIST_EMPTY(&pagedep->pd_dirremhd))
+ return;
+ if (!LIST_EMPTY(&pagedep->pd_pendinghd))
+ return;
+ LIST_REMOVE(pagedep, pd_hash);
+ WORKITEM_FREE(pagedep, D_PAGEDEP);
+}
+
+/*
* Called from within softdep_disk_write_complete above.
* A write operation was just completed. Removed inodes can
* now be freed and associated block pointers may be committed.
@@ -4790,8 +9643,11 @@ handle_written_filepage(pagedep, bp)
*/
while ((dirrem = LIST_FIRST(&pagedep->pd_dirremhd)) != NULL) {
LIST_REMOVE(dirrem, dm_next);
+ dirrem->dm_state |= COMPLETE;
dirrem->dm_dirinum = pagedep->pd_ino;
- add_to_worklist(&dirrem->dm_list);
+ KASSERT(LIST_EMPTY(&dirrem->dm_jremrefhd),
+ ("handle_written_filepage: Journal entries not written."));
+ add_to_worklist(&dirrem->dm_list, 0);
}
/*
* Free any directory additions that have been committed.
@@ -4800,7 +9656,7 @@ handle_written_filepage(pagedep, bp)
*/
if ((pagedep->pd_state & NEWBLOCK) == 0)
while ((dap = LIST_FIRST(&pagedep->pd_pendinghd)) != NULL)
- free_diradd(dap);
+ free_diradd(dap, NULL);
/*
* Uncommitted directory entries must be restored.
*/
@@ -4845,7 +9701,8 @@ handle_written_filepage(pagedep, bp)
* Otherwise it will remain to track any new entries on
* the page in case they are fsync'ed.
*/
- if ((pagedep->pd_state & NEWBLOCK) == 0) {
+ if ((pagedep->pd_state & NEWBLOCK) == 0 &&
+ LIST_EMPTY(&pagedep->pd_jmvrefhd)) {
LIST_REMOVE(pagedep, pd_hash);
WORKITEM_FREE(pagedep, D_PAGEDEP);
}
@@ -4880,8 +9737,8 @@ softdep_load_inodeblock(ip)
*/
ip->i_effnlink = ip->i_nlink;
ACQUIRE_LOCK(&lk);
- if (inodedep_lookup(UFSTOVFS(ip->i_ump),
- ip->i_number, 0, &inodedep) == 0) {
+ if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
+ &inodedep) == 0) {
FREE_LOCK(&lk);
return;
}
@@ -4908,11 +9765,26 @@ softdep_update_inodeblock(ip, bp, waitfor)
int waitfor; /* nonzero => update must be allowed */
{
struct inodedep *inodedep;
+ struct inoref *inoref;
struct worklist *wk;
struct mount *mp;
struct buf *ibp;
+ struct fs *fs;
int error;
+ mp = UFSTOVFS(ip->i_ump);
+ fs = ip->i_fs;
+ /*
+ * Preserve the freelink that is on disk. clear_unlinked_inodedep()
+ * does not have access to the in-core ip so must write directly into
+ * the inode block buffer when setting freelink.
+ */
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ DIP_SET(ip, i_freelink, ((struct ufs1_dinode *)bp->b_data +
+ ino_to_fsbo(fs, ip->i_number))->di_freelink);
+ else
+ DIP_SET(ip, i_freelink, ((struct ufs2_dinode *)bp->b_data +
+ ino_to_fsbo(fs, ip->i_number))->di_freelink);
/*
* If the effective link count is not equal to the actual link
* count, then we must track the difference in an inodedep while
@@ -4920,8 +9792,8 @@ softdep_update_inodeblock(ip, bp, waitfor)
* if there is no existing inodedep, then there are no dependencies
* to track.
*/
- mp = UFSTOVFS(ip->i_ump);
ACQUIRE_LOCK(&lk);
+again:
if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0) {
FREE_LOCK(&lk);
if (ip->i_effnlink != ip->i_nlink)
@@ -4931,6 +9803,20 @@ softdep_update_inodeblock(ip, bp, waitfor)
if (inodedep->id_nlinkdelta != ip->i_nlink - ip->i_effnlink)
panic("softdep_update_inodeblock: bad delta");
/*
+ * If we're flushing all dependencies we must also move any waiting
+ * for journal writes onto the bufwait list prior to I/O.
+ */
+ if (waitfor) {
+ TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
+ if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
+ == DEPCOMPLETE) {
+ stat_jwait_inode++;
+ jwait(&inoref->if_list);
+ goto again;
+ }
+ }
+ }
+ /*
* Changes have been initiated. Anything depending on these
* changes cannot occur until this inode has been written.
*/
@@ -4945,10 +9831,12 @@ softdep_update_inodeblock(ip, bp, waitfor)
*/
merge_inode_lists(&inodedep->id_newinoupdt, &inodedep->id_inoupdt);
if (!TAILQ_EMPTY(&inodedep->id_inoupdt))
- handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_inoupdt));
+ handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_inoupdt),
+ NULL);
merge_inode_lists(&inodedep->id_newextupdt, &inodedep->id_extupdt);
if (!TAILQ_EMPTY(&inodedep->id_extupdt))
- handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_extupdt));
+ handle_allocdirect_partdone(TAILQ_FIRST(&inodedep->id_extupdt),
+ NULL);
/*
* Now that the inode has been pushed into the buffer, the
* operations dependent on the inode being written to disk
@@ -4971,11 +9859,11 @@ softdep_update_inodeblock(ip, bp, waitfor)
return;
}
retry:
- if ((inodedep->id_state & DEPCOMPLETE) != 0) {
+ if ((inodedep->id_state & (DEPCOMPLETE | GOINGAWAY)) != 0) {
FREE_LOCK(&lk);
return;
}
- ibp = inodedep->id_buf;
+ ibp = inodedep->id_bmsafemap->sm_buf;
ibp = getdirtybuf(ibp, &lk, MNT_WAIT);
if (ibp == NULL) {
/*
@@ -5007,13 +9895,13 @@ merge_inode_lists(newlisthead, oldlisthead)
newadp = TAILQ_FIRST(newlisthead);
for (listadp = TAILQ_FIRST(oldlisthead); listadp && newadp;) {
- if (listadp->ad_lbn < newadp->ad_lbn) {
+ if (listadp->ad_offset < newadp->ad_offset) {
listadp = TAILQ_NEXT(listadp, ad_next);
continue;
}
TAILQ_REMOVE(newlisthead, newadp, ad_next);
TAILQ_INSERT_BEFORE(listadp, newadp, ad_next);
- if (listadp->ad_lbn == newadp->ad_lbn) {
+ if (listadp->ad_offset == newadp->ad_offset) {
allocdirect_merge(oldlisthead, newadp,
listadp);
listadp = newadp;
@@ -5036,6 +9924,7 @@ softdep_fsync(vp)
{
struct inodedep *inodedep;
struct pagedep *pagedep;
+ struct inoref *inoref;
struct worklist *wk;
struct diradd *dap;
struct mount *mp;
@@ -5052,17 +9941,25 @@ softdep_fsync(vp)
fs = ip->i_fs;
mp = vp->v_mount;
ACQUIRE_LOCK(&lk);
+restart:
if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0) {
FREE_LOCK(&lk);
return (0);
}
+ TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
+ if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
+ == DEPCOMPLETE) {
+ stat_jwait_inode++;
+ jwait(&inoref->if_list);
+ goto restart;
+ }
+ }
if (!LIST_EMPTY(&inodedep->id_inowait) ||
- !LIST_EMPTY(&inodedep->id_bufwait) ||
!TAILQ_EMPTY(&inodedep->id_extupdt) ||
!TAILQ_EMPTY(&inodedep->id_newextupdt) ||
!TAILQ_EMPTY(&inodedep->id_inoupdt) ||
!TAILQ_EMPTY(&inodedep->id_newinoupdt))
- panic("softdep_fsync: pending ops");
+ panic("softdep_fsync: pending ops %p", inodedep);
for (error = 0, flushparent = 0; ; ) {
if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) == NULL)
break;
@@ -5254,8 +10151,8 @@ int
softdep_sync_metadata(struct vnode *vp)
{
struct pagedep *pagedep;
- struct allocdirect *adp;
struct allocindir *aip;
+ struct newblk *newblk;
struct buf *bp, *nbp;
struct worklist *wk;
struct bufobj *bo;
@@ -5319,27 +10216,16 @@ loop:
switch (wk->wk_type) {
case D_ALLOCDIRECT:
- adp = WK_ALLOCDIRECT(wk);
- if (adp->ad_state & DEPCOMPLETE)
- continue;
- nbp = adp->ad_buf;
- nbp = getdirtybuf(nbp, &lk, waitfor);
- if (nbp == NULL)
- continue;
- FREE_LOCK(&lk);
- if (waitfor == MNT_NOWAIT) {
- bawrite(nbp);
- } else if ((error = bwrite(nbp)) != 0) {
- break;
- }
- ACQUIRE_LOCK(&lk);
- continue;
-
case D_ALLOCINDIR:
- aip = WK_ALLOCINDIR(wk);
- if (aip->ai_state & DEPCOMPLETE)
+ newblk = WK_NEWBLK(wk);
+ if (newblk->nb_jnewblk != NULL) {
+ stat_jwait_newblk++;
+ jwait(&newblk->nb_jnewblk->jn_list);
+ goto restart;
+ }
+ if (newblk->nb_state & DEPCOMPLETE)
continue;
- nbp = aip->ai_buf;
+ nbp = newblk->nb_bmsafemap->sm_buf;
nbp = getdirtybuf(nbp, &lk, waitfor);
if (nbp == NULL)
continue;
@@ -5355,10 +10241,17 @@ loop:
case D_INDIRDEP:
restart:
- LIST_FOREACH(aip, &WK_INDIRDEP(wk)->ir_deplisthd, ai_next) {
- if (aip->ai_state & DEPCOMPLETE)
+ LIST_FOREACH(aip,
+ &WK_INDIRDEP(wk)->ir_deplisthd, ai_next) {
+ newblk = (struct newblk *)aip;
+ if (newblk->nb_jnewblk != NULL) {
+ stat_jwait_newblk++;
+ jwait(&newblk->nb_jnewblk->jn_list);
+ goto restart;
+ }
+ if (newblk->nb_state & DEPCOMPLETE)
continue;
- nbp = aip->ai_buf;
+ nbp = newblk->nb_bmsafemap->sm_buf;
nbp = getdirtybuf(nbp, &lk, MNT_WAIT);
if (nbp == NULL)
goto restart;
@@ -5371,14 +10264,6 @@ loop:
}
continue;
- case D_INODEDEP:
- if ((error = flush_inodedep_deps(wk->wk_mp,
- WK_INODEDEP(wk)->id_ino)) != 0) {
- FREE_LOCK(&lk);
- break;
- }
- continue;
-
case D_PAGEDEP:
/*
* We are trying to sync a directory that may
@@ -5400,48 +10285,6 @@ loop:
}
continue;
- case D_MKDIR:
- /*
- * This case should never happen if the vnode has
- * been properly sync'ed. However, if this function
- * is used at a place where the vnode has not yet
- * been sync'ed, this dependency can show up. So,
- * rather than panic, just flush it.
- */
- nbp = WK_MKDIR(wk)->md_buf;
- nbp = getdirtybuf(nbp, &lk, waitfor);
- if (nbp == NULL)
- continue;
- FREE_LOCK(&lk);
- if (waitfor == MNT_NOWAIT) {
- bawrite(nbp);
- } else if ((error = bwrite(nbp)) != 0) {
- break;
- }
- ACQUIRE_LOCK(&lk);
- continue;
-
- case D_BMSAFEMAP:
- /*
- * This case should never happen if the vnode has
- * been properly sync'ed. However, if this function
- * is used at a place where the vnode has not yet
- * been sync'ed, this dependency can show up. So,
- * rather than panic, just flush it.
- */
- nbp = WK_BMSAFEMAP(wk)->sm_buf;
- nbp = getdirtybuf(nbp, &lk, waitfor);
- if (nbp == NULL)
- continue;
- FREE_LOCK(&lk);
- if (waitfor == MNT_NOWAIT) {
- bawrite(nbp);
- } else if ((error = bwrite(nbp)) != 0) {
- break;
- }
- ACQUIRE_LOCK(&lk);
- continue;
-
default:
panic("softdep_sync_metadata: Unknown type %s",
TYPENAME(wk->wk_type));
@@ -5489,7 +10332,8 @@ loop:
BO_LOCK(bo);
drain_output(vp);
BO_UNLOCK(bo);
- return (0);
+ return ffs_update(vp, 1);
+ /* return (0); */
}
/*
@@ -5502,6 +10346,7 @@ flush_inodedep_deps(mp, ino)
ino_t ino;
{
struct inodedep *inodedep;
+ struct inoref *inoref;
int error, waitfor;
/*
@@ -5522,8 +10367,17 @@ flush_inodedep_deps(mp, ino)
return (error);
FREE_LOCK(&lk);
ACQUIRE_LOCK(&lk);
+restart:
if (inodedep_lookup(mp, ino, 0, &inodedep) == 0)
return (0);
+ TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
+ if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
+ == DEPCOMPLETE) {
+ stat_jwait_inode++;
+ jwait(&inoref->if_list);
+ goto restart;
+ }
+ }
if (flush_deplist(&inodedep->id_inoupdt, waitfor, &error) ||
flush_deplist(&inodedep->id_newinoupdt, waitfor, &error) ||
flush_deplist(&inodedep->id_extupdt, waitfor, &error) ||
@@ -5555,13 +10409,20 @@ flush_deplist(listhead, waitfor, errorp)
int *errorp;
{
struct allocdirect *adp;
+ struct newblk *newblk;
struct buf *bp;
mtx_assert(&lk, MA_OWNED);
TAILQ_FOREACH(adp, listhead, ad_next) {
- if (adp->ad_state & DEPCOMPLETE)
+ newblk = (struct newblk *)adp;
+ if (newblk->nb_jnewblk != NULL) {
+ stat_jwait_newblk++;
+ jwait(&newblk->nb_jnewblk->jn_list);
+ return (1);
+ }
+ if (newblk->nb_state & DEPCOMPLETE)
continue;
- bp = adp->ad_buf;
+ bp = newblk->nb_bmsafemap->sm_buf;
bp = getdirtybuf(bp, &lk, waitfor);
if (bp == NULL) {
if (waitfor == MNT_NOWAIT)
@@ -5582,6 +10443,101 @@ flush_deplist(listhead, waitfor, errorp)
}
/*
+ * Flush dependencies associated with an allocdirect block.
+ */
+static int
+flush_newblk_dep(vp, mp, lbn)
+ struct vnode *vp;
+ struct mount *mp;
+ ufs_lbn_t lbn;
+{
+ struct newblk *newblk;
+ struct bufobj *bo;
+ struct inode *ip;
+ struct buf *bp;
+ ufs2_daddr_t blkno;
+ int error;
+
+ error = 0;
+ bo = &vp->v_bufobj;
+ ip = VTOI(vp);
+ blkno = DIP(ip, i_db[lbn]);
+ if (blkno == 0)
+ panic("flush_newblk_dep: Missing block");
+ ACQUIRE_LOCK(&lk);
+ /*
+ * Loop until all dependencies related to this block are satisfied.
+ * We must be careful to restart after each sleep in case a write
+ * completes some part of this process for us.
+ */
+ for (;;) {
+ if (newblk_lookup(mp, blkno, 0, &newblk) == 0) {
+ FREE_LOCK(&lk);
+ break;
+ }
+ if (newblk->nb_list.wk_type != D_ALLOCDIRECT)
+ panic("flush_newblk_deps: Bad newblk %p", newblk);
+ /*
+ * Flush the journal.
+ */
+ if (newblk->nb_jnewblk != NULL) {
+ stat_jwait_newblk++;
+ jwait(&newblk->nb_jnewblk->jn_list);
+ continue;
+ }
+ /*
+ * Write the bitmap dependency.
+ */
+ if ((newblk->nb_state & DEPCOMPLETE) == 0) {
+ bp = newblk->nb_bmsafemap->sm_buf;
+ bp = getdirtybuf(bp, &lk, MNT_WAIT);
+ if (bp == NULL)
+ continue;
+ FREE_LOCK(&lk);
+ error = bwrite(bp);
+ if (error)
+ break;
+ ACQUIRE_LOCK(&lk);
+ continue;
+ }
+ /*
+ * Write the buffer.
+ */
+ FREE_LOCK(&lk);
+ BO_LOCK(bo);
+ bp = gbincore(bo, lbn);
+ if (bp != NULL) {
+ error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL |
+ LK_INTERLOCK, BO_MTX(bo));
+ if (error == ENOLCK) {
+ ACQUIRE_LOCK(&lk);
+ continue; /* Slept, retry */
+ }
+ if (error != 0)
+ break; /* Failed */
+ if (bp->b_flags & B_DELWRI) {
+ bremfree(bp);
+ error = bwrite(bp);
+ if (error)
+ break;
+ } else
+ BUF_UNLOCK(bp);
+ } else
+ BO_UNLOCK(bo);
+ /*
+ * We have to wait for the direct pointers to
+ * point at the newdirblk before the dependency
+ * will go away.
+ */
+ error = ffs_update(vp, MNT_WAIT);
+ if (error)
+ break;
+ ACQUIRE_LOCK(&lk);
+ }
+ return (error);
+}
+
+/*
* Eliminate a pagedep dependency by flushing out all its diradd dependencies.
* Called with splbio blocked.
*/
@@ -5592,16 +10548,16 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
struct diraddhd *diraddhdp;
{
struct inodedep *inodedep;
+ struct inoref *inoref;
struct ufsmount *ump;
struct diradd *dap;
struct vnode *vp;
- struct bufobj *bo;
int error = 0;
struct buf *bp;
ino_t inum;
- struct worklist *wk;
ump = VFSTOUFS(mp);
+restart:
while ((dap = LIST_FIRST(diraddhdp)) != NULL) {
/*
* Flush ourselves if this directory entry
@@ -5609,7 +10565,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
*/
if (dap->da_state & MKDIR_PARENT) {
FREE_LOCK(&lk);
- if ((error = ffs_update(pvp, 1)) != 0)
+ if ((error = ffs_update(pvp, MNT_WAIT)) != 0)
break;
ACQUIRE_LOCK(&lk);
/*
@@ -5623,84 +10579,52 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
/*
* A newly allocated directory must have its "." and
* ".." entries written out before its name can be
- * committed in its parent. We do not want or need
- * the full semantics of a synchronous ffs_syncvnode as
- * that may end up here again, once for each directory
- * level in the filesystem. Instead, we push the blocks
- * and wait for them to clear. We have to fsync twice
- * because the first call may choose to defer blocks
- * that still have dependencies, but deferral will
- * happen at most once.
+ * committed in its parent.
*/
inum = dap->da_newinum;
+ if (inodedep_lookup(UFSTOVFS(ump), inum, 0, &inodedep) == 0)
+ panic("flush_pagedep_deps: lost inode1");
+ /*
+ * Wait for any pending journal adds to complete so we don't
+ * cause rollbacks while syncing.
+ */
+ TAILQ_FOREACH(inoref, &inodedep->id_inoreflst, if_deps) {
+ if ((inoref->if_state & (DEPCOMPLETE | GOINGAWAY))
+ == DEPCOMPLETE) {
+ stat_jwait_inode++;
+ jwait(&inoref->if_list);
+ goto restart;
+ }
+ }
if (dap->da_state & MKDIR_BODY) {
FREE_LOCK(&lk);
if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp,
FFSV_FORCEINSMQ)))
break;
- if ((error=ffs_syncvnode(vp, MNT_NOWAIT)) ||
- (error=ffs_syncvnode(vp, MNT_NOWAIT))) {
- vput(vp);
- break;
- }
- bo = &vp->v_bufobj;
- BO_LOCK(bo);
- drain_output(vp);
+ error = flush_newblk_dep(vp, mp, 0);
/*
- * If first block is still dirty with a D_MKDIR
- * dependency then it needs to be written now.
+ * If we still have the dependency we might need to
+ * update the vnode to sync the new link count to
+ * disk.
*/
- for (;;) {
- error = 0;
- bp = gbincore(bo, 0);
- if (bp == NULL)
- break; /* First block not present */
- error = BUF_LOCK(bp,
- LK_EXCLUSIVE |
- LK_SLEEPFAIL |
- LK_INTERLOCK,
- BO_MTX(bo));
- BO_LOCK(bo);
- if (error == ENOLCK)
- continue; /* Slept, retry */
- if (error != 0)
- break; /* Failed */
- if ((bp->b_flags & B_DELWRI) == 0) {
- BUF_UNLOCK(bp);
- break; /* Buffer not dirty */
- }
- for (wk = LIST_FIRST(&bp->b_dep);
- wk != NULL;
- wk = LIST_NEXT(wk, wk_list))
- if (wk->wk_type == D_MKDIR)
- break;
- if (wk == NULL)
- BUF_UNLOCK(bp); /* Dependency gone */
- else {
- /*
- * D_MKDIR dependency remains,
- * must write buffer to stable
- * storage.
- */
- BO_UNLOCK(bo);
- bremfree(bp);
- error = bwrite(bp);
- BO_LOCK(bo);
- }
- break;
- }
- BO_UNLOCK(bo);
+ if (error == 0 && dap == LIST_FIRST(diraddhdp))
+ error = ffs_update(vp, MNT_WAIT);
vput(vp);
if (error != 0)
- break; /* Flushing of first block failed */
+ break;
ACQUIRE_LOCK(&lk);
/*
* If that cleared dependencies, go on to next.
*/
if (dap != LIST_FIRST(diraddhdp))
continue;
- if (dap->da_state & MKDIR_BODY)
- panic("flush_pagedep_deps: MKDIR_BODY");
+ if (dap->da_state & MKDIR_BODY) {
+ inodedep_lookup(UFSTOVFS(ump), inum, 0,
+ &inodedep);
+ panic("flush_pagedep_deps: MKDIR_BODY "
+ "inodedep %p dap %p vp %p",
+ inodedep, dap, vp);
+ }
}
/*
* Flush the inode on which the directory entry depends.
@@ -5719,8 +10643,8 @@ retry:
* If the inode still has bitmap dependencies,
* push them to disk.
*/
- if ((inodedep->id_state & DEPCOMPLETE) == 0) {
- bp = inodedep->id_buf;
+ if ((inodedep->id_state & (DEPCOMPLETE | GOINGAWAY)) == 0) {
+ bp = inodedep->id_bmsafemap->sm_buf;
bp = getdirtybuf(bp, &lk, MNT_WAIT);
if (bp == NULL)
goto retry;
@@ -5733,24 +10657,29 @@ retry:
}
/*
* If the inode is still sitting in a buffer waiting
- * to be written, push it to disk.
+ * to be written or waiting for the link count to be
+ * adjusted update it here to flush it to disk.
*/
- FREE_LOCK(&lk);
- if ((error = bread(ump->um_devvp,
- fsbtodb(ump->um_fs, ino_to_fsba(ump->um_fs, inum)),
- (int)ump->um_fs->fs_bsize, NOCRED, &bp)) != 0) {
- brelse(bp);
- break;
+ if (dap == LIST_FIRST(diraddhdp)) {
+ FREE_LOCK(&lk);
+ if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp,
+ FFSV_FORCEINSMQ)))
+ break;
+ error = ffs_update(vp, MNT_WAIT);
+ vput(vp);
+ if (error)
+ break;
+ ACQUIRE_LOCK(&lk);
}
- if ((error = bwrite(bp)) != 0)
- break;
- ACQUIRE_LOCK(&lk);
/*
* If we have failed to get rid of all the dependencies
* then something is seriously wrong.
*/
- if (dap == LIST_FIRST(diraddhdp))
- panic("flush_pagedep_deps: flush failed");
+ if (dap == LIST_FIRST(diraddhdp)) {
+ inodedep_lookup(UFSTOVFS(ump), inum, 0, &inodedep);
+ panic("flush_pagedep_deps: failed to flush "
+ "inodedep %p ino %d dap %p", inodedep, inum, dap);
+ }
}
if (error)
ACQUIRE_LOCK(&lk);
@@ -5828,6 +10757,7 @@ softdep_request_cleanup(fs, vp)
return (0);
UFS_UNLOCK(ump);
ACQUIRE_LOCK(&lk);
+ process_removes(vp);
if (ump->softdep_on_worklist > 0 &&
process_worklist_item(UFSTOVFS(ump), LK_NOWAIT) != -1) {
stat_worklist_push += 1;
@@ -6100,10 +11030,15 @@ softdep_count_dependencies(bp, wantcount)
int wantcount;
{
struct worklist *wk;
+ struct bmsafemap *bmsafemap;
struct inodedep *inodedep;
struct indirdep *indirdep;
+ struct freeblks *freeblks;
struct allocindir *aip;
struct pagedep *pagedep;
+ struct dirrem *dirrem;
+ struct newblk *newblk;
+ struct mkdir *mkdir;
struct diradd *dap;
int i, retval;
@@ -6132,6 +11067,12 @@ softdep_count_dependencies(bp, wantcount)
if (!wantcount)
goto out;
}
+ if (TAILQ_FIRST(&inodedep->id_inoreflst)) {
+ /* Add reference dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
continue;
case D_INDIRDEP:
@@ -6147,6 +11088,14 @@ softdep_count_dependencies(bp, wantcount)
case D_PAGEDEP:
pagedep = WK_PAGEDEP(wk);
+ LIST_FOREACH(dirrem, &pagedep->pd_dirremhd, dm_next) {
+ if (LIST_FIRST(&dirrem->dm_jremrefhd)) {
+ /* Journal remove ref dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
+ }
for (i = 0; i < DAHASHSZ; i++) {
LIST_FOREACH(dap, &pagedep->pd_diraddhd[i], da_pdlist) {
@@ -6159,14 +11108,62 @@ softdep_count_dependencies(bp, wantcount)
continue;
case D_BMSAFEMAP:
+ bmsafemap = WK_BMSAFEMAP(wk);
+ if (LIST_FIRST(&bmsafemap->sm_jaddrefhd)) {
+ /* Add reference dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
+ if (LIST_FIRST(&bmsafemap->sm_jnewblkhd)) {
+ /* Allocate block dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
+ continue;
+
+ case D_FREEBLKS:
+ freeblks = WK_FREEBLKS(wk);
+ if (LIST_FIRST(&freeblks->fb_jfreeblkhd)) {
+ /* Freeblk journal dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
+ continue;
+
case D_ALLOCDIRECT:
case D_ALLOCINDIR:
+ newblk = WK_NEWBLK(wk);
+ if (newblk->nb_jnewblk) {
+ /* Journal allocate dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
+ continue;
+
case D_MKDIR:
+ mkdir = WK_MKDIR(wk);
+ if (mkdir->md_jaddref) {
+ /* Journal reference dependency. */
+ retval += 1;
+ if (!wantcount)
+ goto out;
+ }
+ continue;
+
+ case D_FREEWORK:
+ case D_FREEDEP:
+ case D_JSEGDEP:
+ case D_JSEG:
+ case D_SBDEP:
/* never a dependency on these blocks */
continue;
default:
- panic("softdep_check_for_rollback: Unexpected type %s",
+ panic("softdep_count_dependencies: Unexpected type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
}
@@ -6382,6 +11379,45 @@ softdep_error(func, error)
#ifdef DDB
+static void
+inodedep_print(struct inodedep *inodedep, int verbose)
+{
+ db_printf("%p fs %p st %x ino %jd inoblk %jd delta %d nlink %d"
+ " saveino %p\n",
+ inodedep, inodedep->id_fs, inodedep->id_state,
+ (intmax_t)inodedep->id_ino,
+ (intmax_t)fsbtodb(inodedep->id_fs,
+ ino_to_fsba(inodedep->id_fs, inodedep->id_ino)),
+ inodedep->id_nlinkdelta, inodedep->id_savednlink,
+ inodedep->id_savedino1);
+
+ if (verbose == 0)
+ return;
+
+ db_printf("\tpendinghd %p, bufwait %p, inowait %p, inoreflst %p, "
+ "mkdiradd %p\n",
+ LIST_FIRST(&inodedep->id_pendinghd),
+ LIST_FIRST(&inodedep->id_bufwait),
+ LIST_FIRST(&inodedep->id_inowait),
+ TAILQ_FIRST(&inodedep->id_inoreflst),
+ inodedep->id_mkdiradd);
+ db_printf("\tinoupdt %p, newinoupdt %p, extupdt %p, newextupdt %p\n",
+ TAILQ_FIRST(&inodedep->id_inoupdt),
+ TAILQ_FIRST(&inodedep->id_newinoupdt),
+ TAILQ_FIRST(&inodedep->id_extupdt),
+ TAILQ_FIRST(&inodedep->id_newextupdt));
+}
+
+DB_SHOW_COMMAND(inodedep, db_show_inodedep)
+{
+
+ if (have_addr == 0) {
+ db_printf("Address required\n");
+ return;
+ }
+ inodedep_print((struct inodedep*)addr, 1);
+}
+
DB_SHOW_COMMAND(inodedeps, db_show_inodedeps)
{
struct inodedep_hashhead *inodedephd;
@@ -6395,15 +11431,62 @@ DB_SHOW_COMMAND(inodedeps, db_show_inodedeps)
LIST_FOREACH(inodedep, inodedephd, id_hash) {
if (fs != NULL && fs != inodedep->id_fs)
continue;
- db_printf("%p fs %p st %x ino %jd inoblk %jd\n",
- inodedep, inodedep->id_fs, inodedep->id_state,
- (intmax_t)inodedep->id_ino,
- (intmax_t)fsbtodb(inodedep->id_fs,
- ino_to_fsba(inodedep->id_fs, inodedep->id_ino)));
+ inodedep_print(inodedep, 0);
}
}
}
+DB_SHOW_COMMAND(worklist, db_show_worklist)
+{
+ struct worklist *wk;
+
+ if (have_addr == 0) {
+ db_printf("Address required\n");
+ return;
+ }
+ wk = (struct worklist *)addr;
+ printf("worklist: %p type %s state 0x%X\n",
+ wk, TYPENAME(wk->wk_type), wk->wk_state);
+}
+
+DB_SHOW_COMMAND(workhead, db_show_workhead)
+{
+ struct workhead *wkhd;
+ struct worklist *wk;
+ int i;
+
+ if (have_addr == 0) {
+ db_printf("Address required\n");
+ return;
+ }
+ wkhd = (struct workhead *)addr;
+ wk = LIST_FIRST(wkhd);
+ for (i = 0; i < 100 && wk != NULL; i++, wk = LIST_NEXT(wk, wk_list))
+ db_printf("worklist: %p type %s state 0x%X",
+ wk, TYPENAME(wk->wk_type), wk->wk_state);
+ if (i == 100)
+ db_printf("workhead overflow");
+ printf("\n");
+}
+
+
+DB_SHOW_COMMAND(mkdirs, db_show_mkdirs)
+{
+ struct jaddref *jaddref;
+ struct diradd *diradd;
+ struct mkdir *mkdir;
+
+ LIST_FOREACH(mkdir, &mkdirlisthd, md_mkdirs) {
+ diradd = mkdir->md_diradd;
+ db_printf("mkdir: %p state 0x%X dap %p state 0x%X",
+ mkdir, mkdir->md_state, diradd, diradd->da_state);
+ if ((jaddref = mkdir->md_jaddref) != NULL)
+ db_printf(" jaddref %p jaddref state 0x%X",
+ jaddref, jaddref->ja_state);
+ db_printf("\n");
+ }
+}
+
#endif /* DDB */
#endif /* SOFTUPDATES */
diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index e34bc13..e2460a3 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
#ifndef _KERNEL
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
-#include "fsck.h"
#else
#include <sys/systm.h>
#include <sys/lock.h>
@@ -223,7 +222,38 @@ ffs_isblock(fs, cp, h)
mask = 0x01 << (h & 0x7);
return ((cp[h >> 3] & mask) == mask);
default:
+#ifdef _KERNEL
panic("ffs_isblock");
+#endif
+ break;
+ }
+ return (0);
+}
+
+/*
+ * check if a block is free
+ */
+int
+ffs_isfreeblock(fs, cp, h)
+ struct fs *fs;
+ u_char *cp;
+ ufs1_daddr_t h;
+{
+
+ switch ((int)fs->fs_frag) {
+ case 8:
+ return (cp[h] == 0);
+ case 4:
+ return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
+ case 2:
+ return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
+ case 1:
+ return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
+ default:
+#ifdef _KERNEL
+ panic("ffs_isfreeblock");
+#endif
+ break;
}
return (0);
}
@@ -252,7 +282,10 @@ ffs_clrblock(fs, cp, h)
cp[h >> 3] &= ~(0x01 << (h & 0x7));
return;
default:
+#ifdef _KERNEL
panic("ffs_clrblock");
+#endif
+ break;
}
}
@@ -281,6 +314,101 @@ ffs_setblock(fs, cp, h)
cp[h >> 3] |= (0x01 << (h & 0x7));
return;
default:
+#ifdef _KERNEL
panic("ffs_setblock");
+#endif
+ break;
+ }
+}
+
+/*
+ * Update the cluster map because of an allocation or free.
+ *
+ * Cnt == 1 means free; cnt == -1 means allocating.
+ */
+void
+ffs_clusteracct(fs, cgp, blkno, cnt)
+ struct fs *fs;
+ struct cg *cgp;
+ ufs1_daddr_t blkno;
+ int cnt;
+{
+ int32_t *sump;
+ int32_t *lp;
+ u_char *freemapp, *mapp;
+ int i, start, end, forw, back, map, bit;
+
+ if (fs->fs_contigsumsize <= 0)
+ return;
+ freemapp = cg_clustersfree(cgp);
+ sump = cg_clustersum(cgp);
+ /*
+ * Allocate or clear the actual block.
+ */
+ if (cnt > 0)
+ setbit(freemapp, blkno);
+ else
+ clrbit(freemapp, blkno);
+ /*
+ * Find the size of the cluster going forward.
+ */
+ start = blkno + 1;
+ end = start + fs->fs_contigsumsize;
+ if (end >= cgp->cg_nclusterblks)
+ end = cgp->cg_nclusterblks;
+ mapp = &freemapp[start / NBBY];
+ map = *mapp++;
+ bit = 1 << (start % NBBY);
+ for (i = start; i < end; i++) {
+ if ((map & bit) == 0)
+ break;
+ if ((i & (NBBY - 1)) != (NBBY - 1)) {
+ bit <<= 1;
+ } else {
+ map = *mapp++;
+ bit = 1;
+ }
+ }
+ forw = i - start;
+ /*
+ * Find the size of the cluster going backward.
+ */
+ start = blkno - 1;
+ end = start - fs->fs_contigsumsize;
+ if (end < 0)
+ end = -1;
+ mapp = &freemapp[start / NBBY];
+ map = *mapp--;
+ bit = 1 << (start % NBBY);
+ for (i = start; i > end; i--) {
+ if ((map & bit) == 0)
+ break;
+ if ((i & (NBBY - 1)) != 0) {
+ bit >>= 1;
+ } else {
+ map = *mapp--;
+ bit = 1 << (NBBY - 1);
+ }
}
+ back = start - i;
+ /*
+ * Account for old cluster and the possibly new forward and
+ * back clusters.
+ */
+ i = back + forw + 1;
+ if (i > fs->fs_contigsumsize)
+ i = fs->fs_contigsumsize;
+ sump[i] += cnt;
+ if (back > 0)
+ sump[back] -= cnt;
+ if (forw > 0)
+ sump[forw] -= cnt;
+ /*
+ * Update cluster summary information.
+ */
+ lp = &sump[fs->fs_contigsumsize];
+ for (i = fs->fs_contigsumsize; i > 0; i--)
+ if (*lp-- > 0)
+ break;
+ fs->fs_maxcluster[cgp->cg_cgx] = i;
}
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 8aa9f9c..e403368 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -79,7 +79,6 @@ static int ffs_reload(struct mount *, struct thread *);
static int ffs_mountfs(struct vnode *, struct mount *, struct thread *);
static void ffs_oldfscompat_read(struct fs *, struct ufsmount *,
ufs2_daddr_t);
-static void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
static void ffs_ifree(struct ufsmount *ump, struct inode *ip);
static vfs_init_t ffs_init;
static vfs_uninit_t ffs_uninit;
@@ -299,7 +298,8 @@ ffs_mount(struct mount *mp)
if (fs->fs_clean == 0) {
fs->fs_flags |= FS_UNCLEAN;
if ((mp->mnt_flag & MNT_FORCE) ||
- ((fs->fs_flags & FS_NEEDSFSCK) == 0 &&
+ ((fs->fs_flags &
+ (FS_SUJ | FS_NEEDSFSCK)) == 0 &&
(fs->fs_flags & FS_DOSOFTDEP))) {
printf("WARNING: %s was not %s\n",
fs->fs_fsmnt, "properly dismounted");
@@ -307,6 +307,9 @@ ffs_mount(struct mount *mp)
printf(
"WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
fs->fs_fsmnt);
+ if (fs->fs_flags & FS_SUJ)
+ printf(
+"WARNING: Forced mount will invalidated journal contents\n");
return (EPERM);
}
}
@@ -330,17 +333,18 @@ ffs_mount(struct mount *mp)
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_RDONLY;
MNT_IUNLOCK(mp);
- fs->fs_clean = 0;
- if ((error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0) {
- vn_finished_write(mp);
- return (error);
- }
+ fs->fs_mtime = time_second;
/* check to see if we need to start softdep */
if ((fs->fs_flags & FS_DOSOFTDEP) &&
(error = softdep_mount(devvp, mp, fs, td->td_ucred))){
vn_finished_write(mp);
return (error);
}
+ fs->fs_clean = 0;
+ if ((error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0) {
+ vn_finished_write(mp);
+ return (error);
+ }
if (fs->fs_snapinum[0] != 0)
ffs_snapshot_mount(mp);
vn_finished_write(mp);
@@ -665,7 +669,6 @@ ffs_mountfs(devvp, mp, td)
if (mp->mnt_iosize_max > MAXPHYS)
mp->mnt_iosize_max = MAXPHYS;
- devvp->v_bufobj.bo_private = cp;
devvp->v_bufobj.bo_ops = &ffs_ops;
fs = NULL;
@@ -706,7 +709,7 @@ ffs_mountfs(devvp, mp, td)
if (fs->fs_clean == 0) {
fs->fs_flags |= FS_UNCLEAN;
if (ronly || (mp->mnt_flag & MNT_FORCE) ||
- ((fs->fs_flags & FS_NEEDSFSCK) == 0 &&
+ ((fs->fs_flags & (FS_SUJ | FS_NEEDSFSCK)) == 0 &&
(fs->fs_flags & FS_DOSOFTDEP))) {
printf(
"WARNING: %s was not properly dismounted\n",
@@ -715,6 +718,9 @@ ffs_mountfs(devvp, mp, td)
printf(
"WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
fs->fs_fsmnt);
+ if (fs->fs_flags & FS_SUJ)
+ printf(
+"WARNING: Forced mount will invalidated journal contents\n");
error = EPERM;
goto out;
}
@@ -897,6 +903,7 @@ ffs_mountfs(devvp, mp, td)
*/
bzero(fs->fs_fsmnt, MAXMNTLEN);
strlcpy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MAXMNTLEN);
+ mp->mnt_stat.f_iosize = fs->fs_bsize;
if( mp->mnt_flag & MNT_ROOTFS) {
/*
@@ -908,6 +915,7 @@ ffs_mountfs(devvp, mp, td)
}
if (ronly == 0) {
+ fs->fs_mtime = time_second;
if ((fs->fs_flags & FS_DOSOFTDEP) &&
(error = softdep_mount(devvp, mp, fs, cred)) != 0) {
free(fs->fs_csp, M_UFSMNT);
@@ -938,7 +946,6 @@ ffs_mountfs(devvp, mp, td)
* This would all happen while the filesystem was busy/not
* available, so would effectively be "atomic".
*/
- mp->mnt_stat.f_iosize = fs->fs_bsize;
(void) ufs_extattr_autostart(mp, td);
#endif /* !UFS_EXTATTR_AUTOSTART */
#endif /* !UFS_EXTATTR */
@@ -1038,7 +1045,7 @@ ffs_oldfscompat_read(fs, ump, sblockloc)
* XXX - Parts get retired eventually.
* Unfortunately new bits get added.
*/
-static void
+void
ffs_oldfscompat_write(fs, ump)
struct fs *fs;
struct ufsmount *ump;
@@ -1133,6 +1140,7 @@ ffs_unmount(mp, mntflags)
fs->fs_pendinginodes = 0;
}
UFS_UNLOCK(ump);
+ softdep_unmount(mp);
if (fs->fs_ronly == 0) {
fs->fs_clean = fs->fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK) ? 0 : 1;
error = ffs_sbupdate(ump, MNT_WAIT, 0);
@@ -1574,16 +1582,6 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
DIP_SET(ip, i_gen, ip->i_gen);
}
}
- /*
- * Ensure that uid and gid are correct. This is a temporary
- * fix until fsck has been changed to do the update.
- */
- if (fs->fs_magic == FS_UFS1_MAGIC && /* XXX */
- fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */
- ip->i_uid = ip->i_din1->di_ouid; /* XXX */
- ip->i_gid = ip->i_din1->di_ogid; /* XXX */
- } /* XXX */
-
#ifdef MAC
if ((mp->mnt_flag & MNT_MULTILABEL) && ip->i_mode) {
/*
@@ -1727,6 +1725,8 @@ ffs_sbupdate(mp, waitfor, suspended)
}
fs->fs_fmod = 0;
fs->fs_time = time_second;
+ if (fs->fs_flags & FS_DOSOFTDEP)
+ softdep_setup_sbupdate(mp, (struct fs *)bp->b_data, bp);
bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
ffs_oldfscompat_write((struct fs *)bp->b_data, mp);
if (suspended)
@@ -1868,9 +1868,6 @@ ffs_bufwrite(struct buf *bp)
}
BO_UNLOCK(bp->b_bufobj);
- /* Mark the buffer clean */
- bundirty(bp);
-
/*
* If this buffer is marked for background writing and we
* do not have to wait for it, make a copy and write the
@@ -1911,9 +1908,16 @@ ffs_bufwrite(struct buf *bp)
newbp->b_flags &= ~B_INVAL;
#ifdef SOFTUPDATES
- /* move over the dependencies */
- if (!LIST_EMPTY(&bp->b_dep))
- softdep_move_dependencies(bp, newbp);
+ /*
+ * Move over the dependencies. If there are rollbacks,
+ * leave the parent buffer dirtied as it will need to
+ * be written again.
+ */
+ if (LIST_EMPTY(&bp->b_dep) ||
+ softdep_move_dependencies(bp, newbp) == 0)
+ bundirty(bp);
+#else
+ bundirty(bp);
#endif
/*
@@ -1926,7 +1930,10 @@ ffs_bufwrite(struct buf *bp)
*/
bqrelse(bp);
bp = newbp;
- }
+ } else
+ /* Mark the buffer clean */
+ bundirty(bp);
+
/* Let the normal bufwrite do the rest for us */
normal_write:
@@ -1940,6 +1947,7 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp)
struct vnode *vp;
int error;
struct buf *tbp;
+ int nocopy;
vp = bo->__bo_vnode;
if (bp->b_iocmd == BIO_WRITE) {
@@ -1947,8 +1955,9 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp)
bp->b_vp != NULL && bp->b_vp->v_mount != NULL &&
(bp->b_vp->v_mount->mnt_kern_flag & MNTK_SUSPENDED) != 0)
panic("ffs_geom_strategy: bad I/O");
- bp->b_flags &= ~B_VALIDSUSPWRT;
- if ((vp->v_vflag & VV_COPYONWRITE) &&
+ nocopy = bp->b_flags & B_NOCOPY;
+ bp->b_flags &= ~(B_VALIDSUSPWRT | B_NOCOPY);
+ if ((vp->v_vflag & VV_COPYONWRITE) && nocopy == 0 &&
vp->v_rdev->si_snapdata != NULL) {
if ((bp->b_flags & B_CLUSTER) != 0) {
runningbufwakeup(bp);
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 464a761..e6617cb 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -225,6 +225,7 @@ ffs_syncvnode(struct vnode *vp, int waitfor)
wait = (waitfor == MNT_WAIT);
lbn = lblkno(ip->i_fs, (ip->i_size + ip->i_fs->fs_bsize - 1));
bo = &vp->v_bufobj;
+ ip->i_flag &= ~IN_NEEDSYNC;
/*
* Flush all dirty buffers associated with a vnode.
diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h
index 5452e2b..e863b96 100644
--- a/sys/ufs/ffs/fs.h
+++ b/sys/ufs/ffs/fs.h
@@ -340,7 +340,9 @@ struct fs {
u_int32_t fs_avgfilesize; /* expected average file size */
u_int32_t fs_avgfpdir; /* expected # of files per directory */
int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */
- int32_t fs_sparecon32[26]; /* reserved for future constants */
+ ufs_time_t fs_mtime; /* Last mount or fsck time. */
+ int32_t fs_sujfree; /* SUJ free list */
+ int32_t fs_sparecon32[23]; /* reserved for future constants */
int32_t fs_flags; /* see FS_ flags below */
int32_t fs_contigsumsize; /* size of cluster summary array */
int32_t fs_maxsymlinklen; /* max length of an internal symlink */
@@ -408,12 +410,13 @@ CTASSERT(sizeof(struct fs) == 1376);
#define FS_UNCLEAN 0x0001 /* filesystem not clean at mount */
#define FS_DOSOFTDEP 0x0002 /* filesystem using soft dependencies */
#define FS_NEEDSFSCK 0x0004 /* filesystem needs sync fsck before mount */
-#define FS_INDEXDIRS 0x0008 /* kernel supports indexed directories */
+#define FS_SUJ 0x0008 /* Filesystem using softupdate journal */
#define FS_ACLS 0x0010 /* file system has POSIX.1e ACLs enabled */
#define FS_MULTILABEL 0x0020 /* file system is MAC multi-label */
#define FS_GJOURNAL 0x0040 /* gjournaled file system */
#define FS_FLAGS_UPDATED 0x0080 /* flags have been moved to new location */
#define FS_NFS4ACLS 0x0100 /* file system has NFSv4 ACLs enabled */
+#define FS_INDEXDIRS 0x0200 /* kernel supports indexed directories */
/*
* Macros to access bits in the fs_active array.
@@ -603,7 +606,31 @@ struct cg {
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (size)))))
-
+/*
+ * Indirect lbns are aligned on NDADDR addresses where single indirects
+ * are the negated address of the lowest lbn reachable, double indirects
+ * are this lbn - 1 and triple indirects are this lbn - 2. This yields
+ * an unusual bit order to determine level.
+ */
+static inline int
+lbn_level(ufs_lbn_t lbn)
+{
+ if (lbn >= 0)
+ return 0;
+ switch (lbn & 0x3) {
+ case 0:
+ return (0);
+ case 1:
+ break;
+ case 2:
+ return (2);
+ case 3:
+ return (1);
+ default:
+ break;
+ }
+ return (-1);
+}
/*
* Number of inodes in a secondary storage block/fragment.
*/
@@ -615,6 +642,108 @@ struct cg {
*/
#define NINDIR(fs) ((fs)->fs_nindir)
+/*
+ * Softdep journal record format.
+ */
+
+#define JOP_ADDREF 1 /* Add a reference to an inode. */
+#define JOP_REMREF 2 /* Remove a reference from an inode. */
+#define JOP_NEWBLK 3 /* Allocate a block. */
+#define JOP_FREEBLK 4 /* Free a block or a tree of blocks. */
+#define JOP_MVREF 5 /* Move a reference from one off to another. */
+#define JOP_TRUNC 6 /* Partial truncation record. */
+
+#define JREC_SIZE 32 /* Record and segment header size. */
+
+#define SUJ_MIN (4 * 1024 * 1024) /* Minimum journal size */
+#define SUJ_MAX (32 * 1024 * 1024) /* Maximum journal size */
+#define SUJ_FILE ".sujournal" /* Journal file name */
+
+/*
+ * Size of the segment record header. There is at most one for each disk
+ * block n the journal. The segment header is followed by an array of
+ * records. fsck depends on the first element in each record being 'op'
+ * and the second being 'ino'. Segments may span multiple disk blocks but
+ * the header is present on each.
+ */
+struct jsegrec {
+ uint64_t jsr_seq; /* Our sequence number */
+ uint64_t jsr_oldest; /* Oldest valid sequence number */
+ uint16_t jsr_cnt; /* Count of valid records */
+ uint16_t jsr_blocks; /* Count of DEV_BSIZE blocks. */
+ uint32_t jsr_crc; /* 32bit crc of the valid space */
+ ufs_time_t jsr_time; /* timestamp for mount instance */
+};
+
+/*
+ * Reference record. Records a single link count modification.
+ */
+struct jrefrec {
+ uint32_t jr_op;
+ ino_t jr_ino;
+ ino_t jr_parent;
+ uint16_t jr_nlink;
+ uint16_t jr_mode;
+ off_t jr_diroff;
+ uint64_t jr_unused;
+};
+
+/*
+ * Move record. Records a reference moving within a directory block. The
+ * nlink is unchanged but we must search both locations.
+ */
+struct jmvrec {
+ uint32_t jm_op;
+ ino_t jm_ino;
+ ino_t jm_parent;
+ uint16_t jm_unused;
+ off_t jm_oldoff;
+ off_t jm_newoff;
+};
+
+/*
+ * Block record. A set of frags or tree of blocks starting at an indirect are
+ * freed or a set of frags are allocated.
+ */
+struct jblkrec {
+ uint32_t jb_op;
+ uint32_t jb_ino;
+ ufs2_daddr_t jb_blkno;
+ ufs_lbn_t jb_lbn;
+ uint16_t jb_frags;
+ uint16_t jb_oldfrags;
+ uint32_t jb_unused;
+};
+
+/*
+ * Truncation record. Records a partial truncation so that it may be
+ * completed later.
+ */
+struct jtrncrec {
+ uint32_t jt_op;
+ uint32_t jt_ino;
+ off_t jt_size;
+ uint32_t jt_extsize;
+ uint32_t jt_pad[3];
+};
+
+union jrec {
+ struct jsegrec rec_jsegrec;
+ struct jrefrec rec_jrefrec;
+ struct jmvrec rec_jmvrec;
+ struct jblkrec rec_jblkrec;
+ struct jtrncrec rec_jtrncrec;
+};
+
+#ifdef CTASSERT
+CTASSERT(sizeof(struct jsegrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jrefrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jmvrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jblkrec) == JREC_SIZE);
+CTASSERT(sizeof(struct jtrncrec) == JREC_SIZE);
+CTASSERT(sizeof(union jrec) == JREC_SIZE);
+#endif
+
extern int inside[], around[];
extern u_char *fragtbl[];
diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h
index b00183b..5d8a869 100644
--- a/sys/ufs/ffs/softdep.h
+++ b/sys/ufs/ffs/softdep.h
@@ -94,22 +94,29 @@
* The ONWORKLIST flag shows whether the structure is currently linked
* onto a worklist.
*/
-#define ATTACHED 0x0001
-#define UNDONE 0x0002
-#define COMPLETE 0x0004
-#define DEPCOMPLETE 0x0008
-#define MKDIR_PARENT 0x0010 /* diradd & mkdir only */
-#define MKDIR_BODY 0x0020 /* diradd & mkdir only */
-#define RMDIR 0x0040 /* dirrem only */
-#define DIRCHG 0x0080 /* diradd & dirrem only */
-#define GOINGAWAY 0x0100 /* indirdep only */
-#define IOSTARTED 0x0200 /* inodedep & pagedep only */
-#define SPACECOUNTED 0x0400 /* inodedep only */
-#define NEWBLOCK 0x0800 /* pagedep only */
-#define INPROGRESS 0x1000 /* dirrem, freeblks, freefrag, freefile only */
-#define UFS1FMT 0x2000 /* indirdep only */
-#define EXTDATA 0x4000 /* allocdirect only */
-#define ONWORKLIST 0x8000
+#define ATTACHED 0x000001
+#define UNDONE 0x000002
+#define COMPLETE 0x000004
+#define DEPCOMPLETE 0x000008
+#define MKDIR_PARENT 0x000010 /* diradd, mkdir, jaddref, jsegdep only */
+#define MKDIR_BODY 0x000020 /* diradd, mkdir, jaddref only */
+#define RMDIR 0x000040 /* dirrem only */
+#define DIRCHG 0x000080 /* diradd, dirrem only */
+#define GOINGAWAY 0x000100 /* indirdep, jremref only */
+#define IOSTARTED 0x000200 /* inodedep, pagedep, bmsafemap only */
+#define SPACECOUNTED 0x000400 /* inodedep only */
+#define NEWBLOCK 0x000800 /* pagedep, jaddref only */
+#define INPROGRESS 0x001000 /* dirrem, freeblks, freefrag, freefile only */
+#define UFS1FMT 0x002000 /* indirdep only */
+#define EXTDATA 0x004000 /* allocdirect only */
+#define ONWORKLIST 0x008000
+#define IOWAITING 0x010000 /* Thread is waiting for IO to complete. */
+#define ONDEPLIST 0x020000 /* Structure is on a dependency list. */
+#define UNLINKED 0x040000 /* inodedep has been unlinked. */
+#define UNLINKNEXT 0x080000 /* inodedep has valid di_freelink */
+#define UNLINKPREV 0x100000 /* inodedep is pointed at in the unlink list */
+#define UNLINKONLIST 0x200000 /* inodedep is in the unlinked list on disk */
+#define UNLINKLINKS (UNLINKNEXT | UNLINKPREV)
#define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE)
@@ -135,25 +142,38 @@
* and the macros below changed to use it.
*/
struct worklist {
- struct mount *wk_mp; /* Mount we live in */
LIST_ENTRY(worklist) wk_list; /* list of work requests */
- unsigned short wk_type; /* type of request */
- unsigned short wk_state; /* state flags */
+ struct mount *wk_mp; /* Mount we live in */
+ unsigned int wk_type:8, /* type of request */
+ wk_state:24; /* state flags */
};
#define WK_DATA(wk) ((void *)(wk))
#define WK_PAGEDEP(wk) ((struct pagedep *)(wk))
#define WK_INODEDEP(wk) ((struct inodedep *)(wk))
#define WK_BMSAFEMAP(wk) ((struct bmsafemap *)(wk))
+#define WK_NEWBLK(wk) ((struct newblk *)(wk))
#define WK_ALLOCDIRECT(wk) ((struct allocdirect *)(wk))
#define WK_INDIRDEP(wk) ((struct indirdep *)(wk))
#define WK_ALLOCINDIR(wk) ((struct allocindir *)(wk))
#define WK_FREEFRAG(wk) ((struct freefrag *)(wk))
#define WK_FREEBLKS(wk) ((struct freeblks *)(wk))
+#define WK_FREEWORK(wk) ((struct freework *)(wk))
#define WK_FREEFILE(wk) ((struct freefile *)(wk))
#define WK_DIRADD(wk) ((struct diradd *)(wk))
#define WK_MKDIR(wk) ((struct mkdir *)(wk))
#define WK_DIRREM(wk) ((struct dirrem *)(wk))
#define WK_NEWDIRBLK(wk) ((struct newdirblk *)(wk))
+#define WK_JADDREF(wk) ((struct jaddref *)(wk))
+#define WK_JREMREF(wk) ((struct jremref *)(wk))
+#define WK_JMVREF(wk) ((struct jmvref *)(wk))
+#define WK_JSEGDEP(wk) ((struct jsegdep *)(wk))
+#define WK_JSEG(wk) ((struct jseg *)(wk))
+#define WK_JNEWBLK(wk) ((struct jnewblk *)(wk))
+#define WK_JFREEBLK(wk) ((struct jfreeblk *)(wk))
+#define WK_FREEDEP(wk) ((struct freedep *)(wk))
+#define WK_JFREEFRAG(wk) ((struct jfreefrag *)(wk))
+#define WK_SBDEP(wk) ((struct sbdep *)wk)
+#define WK_JTRUNC(wk) ((struct jtrunc *)(wk))
/*
* Various types of lists
@@ -165,6 +185,15 @@ LIST_HEAD(inodedephd, inodedep);
LIST_HEAD(allocindirhd, allocindir);
LIST_HEAD(allocdirecthd, allocdirect);
TAILQ_HEAD(allocdirectlst, allocdirect);
+LIST_HEAD(indirdephd, indirdep);
+LIST_HEAD(jaddrefhd, jaddref);
+LIST_HEAD(jremrefhd, jremref);
+LIST_HEAD(jmvrefhd, jmvref);
+LIST_HEAD(jnewblkhd, jnewblk);
+LIST_HEAD(jfreeblkhd, jfreeblk);
+LIST_HEAD(freeworkhd, freework);
+TAILQ_HEAD(jseglst, jseg);
+TAILQ_HEAD(inoreflst, inoref);
/*
* The "pagedep" structure tracks the various dependencies related to
@@ -192,9 +221,11 @@ struct pagedep {
LIST_ENTRY(pagedep) pd_hash; /* hashed lookup */
ino_t pd_ino; /* associated file */
ufs_lbn_t pd_lbn; /* block within file */
+ struct newdirblk *pd_newdirblk; /* associated newdirblk if NEWBLOCK */
struct dirremhd pd_dirremhd; /* dirrem's waiting for page */
struct diraddhd pd_diraddhd[DAHASHSZ]; /* diradd dir entry updates */
struct diraddhd pd_pendinghd; /* directory entries awaiting write */
+ struct jmvrefhd pd_jmvrefhd; /* Dependent journal writes. */
};
/*
@@ -248,13 +279,18 @@ struct inodedep {
struct worklist id_list; /* buffer holding inode block */
# define id_state id_list.wk_state /* inode dependency state */
LIST_ENTRY(inodedep) id_hash; /* hashed lookup */
+ TAILQ_ENTRY(inodedep) id_unlinked; /* Unlinked but ref'd inodes */
struct fs *id_fs; /* associated filesystem */
ino_t id_ino; /* dependent inode */
nlink_t id_nlinkdelta; /* saved effective link count */
+ nlink_t id_savednlink; /* Link saved during rollback */
LIST_ENTRY(inodedep) id_deps; /* bmsafemap's list of inodedep's */
- struct buf *id_buf; /* related bmsafemap (if pending) */
+ struct bmsafemap *id_bmsafemap; /* related bmsafemap (if pending) */
+ struct diradd *id_mkdiradd; /* diradd for a mkdir. */
+ struct inoreflst id_inoreflst; /* Inode reference adjustments. */
long id_savedextsize; /* ext size saved during rollback */
off_t id_savedsize; /* file size saved during rollback */
+ struct dirremhd id_dirremhd; /* Removals pending. */
struct workhead id_pendinghd; /* entries awaiting directory write */
struct workhead id_bufwait; /* operations after inode written */
struct workhead id_inowait; /* operations waiting inode update */
@@ -271,23 +307,6 @@ struct inodedep {
#define id_savedino2 id_un.idu_savedino2
/*
- * A "newblk" structure is attached to a bmsafemap structure when a block
- * or fragment is allocated from a cylinder group. Its state is set to
- * DEPCOMPLETE when its cylinder group map is written. It is consumed by
- * an associated allocdirect or allocindir allocation which will attach
- * themselves to the bmsafemap structure if the newblk's DEPCOMPLETE flag
- * is not set (i.e., its cylinder group map has not been written).
- */
-struct newblk {
- LIST_ENTRY(newblk) nb_hash; /* hashed lookup */
- struct fs *nb_fs; /* associated filesystem */
- int nb_state; /* state of bitmap dependency */
- ufs2_daddr_t nb_newblkno; /* allocated block number */
- LIST_ENTRY(newblk) nb_deps; /* bmsafemap's list of newblk's */
- struct bmsafemap *nb_bmsafemap; /* associated bmsafemap */
-};
-
-/*
* A "bmsafemap" structure maintains a list of dependency structures
* that depend on the update of a particular cylinder group map.
* It has lists for newblks, allocdirects, allocindirs, and inodedeps.
@@ -299,11 +318,41 @@ struct newblk {
*/
struct bmsafemap {
struct worklist sm_list; /* cylgrp buffer */
+# define sm_state sm_list.wk_state
+ int sm_cg;
+ LIST_ENTRY(bmsafemap) sm_hash; /* Hash links. */
struct buf *sm_buf; /* associated buffer */
struct allocdirecthd sm_allocdirecthd; /* allocdirect deps */
+ struct allocdirecthd sm_allocdirectwr; /* writing allocdirect deps */
struct allocindirhd sm_allocindirhd; /* allocindir deps */
+ struct allocindirhd sm_allocindirwr; /* writing allocindir deps */
struct inodedephd sm_inodedephd; /* inodedep deps */
+ struct inodedephd sm_inodedepwr; /* writing inodedep deps */
struct newblkhd sm_newblkhd; /* newblk deps */
+ struct newblkhd sm_newblkwr; /* writing newblk deps */
+ struct jaddrefhd sm_jaddrefhd; /* Pending inode allocations. */
+ struct jnewblkhd sm_jnewblkhd; /* Pending block allocations. */
+};
+
+/*
+ * A "newblk" structure is attached to a bmsafemap structure when a block
+ * or fragment is allocated from a cylinder group. Its state is set to
+ * DEPCOMPLETE when its cylinder group map is written. It is converted to
+ * an allocdirect or allocindir allocation once the allocator calls the
+ * appropriate setup function.
+ */
+struct newblk {
+ struct worklist nb_list;
+# define nb_state nb_list.wk_state
+ LIST_ENTRY(newblk) nb_hash; /* hashed lookup */
+ LIST_ENTRY(newblk) nb_deps; /* bmsafemap's list of newblks */
+ struct jnewblk *nb_jnewblk; /* New block journal entry. */
+ struct bmsafemap *nb_bmsafemap;/* cylgrp dep (if pending) */
+ struct freefrag *nb_freefrag; /* fragment to be freed (if any) */
+ struct indirdephd nb_indirdeps; /* Children indirect blocks. */
+ struct workhead nb_newdirblk; /* dir block to notify when written */
+ struct workhead nb_jwork; /* Journal work pending. */
+ ufs2_daddr_t nb_newblkno; /* new value of block pointer */
};
/*
@@ -334,20 +383,18 @@ struct bmsafemap {
* and inodedep->id_pendinghd lists.
*/
struct allocdirect {
- struct worklist ad_list; /* buffer holding block */
-# define ad_state ad_list.wk_state /* block pointer state */
+ struct newblk ad_block; /* Common block logic */
+# define ad_state ad_block.nb_list.wk_state /* block pointer state */
TAILQ_ENTRY(allocdirect) ad_next; /* inodedep's list of allocdirect's */
- ufs_lbn_t ad_lbn; /* block within file */
- ufs2_daddr_t ad_newblkno; /* new value of block pointer */
- ufs2_daddr_t ad_oldblkno; /* old value of block pointer */
- long ad_newsize; /* size of new block */
- long ad_oldsize; /* size of old block */
- LIST_ENTRY(allocdirect) ad_deps; /* bmsafemap's list of allocdirect's */
- struct buf *ad_buf; /* cylgrp buffer (if pending) */
struct inodedep *ad_inodedep; /* associated inodedep */
- struct freefrag *ad_freefrag; /* fragment to be freed (if any) */
- struct workhead ad_newdirblk; /* dir block to notify when written */
+ ufs2_daddr_t ad_oldblkno; /* old value of block pointer */
+ int ad_offset; /* Pointer offset in parent. */
+ long ad_newsize; /* size of new block */
+ long ad_oldsize; /* size of old block */
};
+#define ad_newblkno ad_block.nb_newblkno
+#define ad_freefrag ad_block.nb_freefrag
+#define ad_newdirblk ad_block.nb_newdirblk
/*
* A single "indirdep" structure manages all allocation dependencies for
@@ -369,10 +416,14 @@ struct allocdirect {
struct indirdep {
struct worklist ir_list; /* buffer holding indirect block */
# define ir_state ir_list.wk_state /* indirect block pointer state */
- caddr_t ir_saveddata; /* buffer cache contents */
+ LIST_ENTRY(indirdep) ir_next; /* alloc{direct,indir} list */
+ caddr_t ir_saveddata; /* buffer cache contents */
struct buf *ir_savebp; /* buffer holding safe copy */
+ struct allocindirhd ir_completehd; /* waiting for indirdep complete */
+ struct allocindirhd ir_writehd; /* Waiting for the pointer write. */
struct allocindirhd ir_donehd; /* done waiting to update safecopy */
struct allocindirhd ir_deplisthd; /* allocindir deps for this block */
+ struct workhead ir_jwork; /* Journal work pending. */
};
/*
@@ -389,16 +440,25 @@ struct indirdep {
* can then be freed as it is no longer applicable.
*/
struct allocindir {
- struct worklist ai_list; /* buffer holding indirect block */
-# define ai_state ai_list.wk_state /* indirect block pointer state */
+ struct newblk ai_block; /* Common block area */
+# define ai_state ai_block.nb_list.wk_state /* indirect pointer state */
LIST_ENTRY(allocindir) ai_next; /* indirdep's list of allocindir's */
- int ai_offset; /* pointer offset in indirect block */
- ufs2_daddr_t ai_newblkno; /* new block pointer value */
- ufs2_daddr_t ai_oldblkno; /* old block pointer value */
- struct freefrag *ai_freefrag; /* block to be freed when complete */
struct indirdep *ai_indirdep; /* address of associated indirdep */
- LIST_ENTRY(allocindir) ai_deps; /* bmsafemap's list of allocindir's */
- struct buf *ai_buf; /* cylgrp buffer (if pending) */
+ ufs2_daddr_t ai_oldblkno; /* old value of block pointer */
+ int ai_offset; /* Pointer offset in parent. */
+};
+#define ai_newblkno ai_block.nb_newblkno
+#define ai_freefrag ai_block.nb_freefrag
+#define ai_newdirblk ai_block.nb_newdirblk
+
+/*
+ * The allblk union is used to size the newblk structure on allocation so
+ * that it may be any one of three types.
+ */
+union allblk {
+ struct allocindir ab_allocindir;
+ struct allocdirect ab_allocdirect;
+ struct newblk ab_newblk;
};
/*
@@ -406,14 +466,13 @@ struct allocindir {
* allocated fragment is replaced with a larger fragment, rather than extended.
* The "freefrag" structure is constructed and attached when the replacement
* block is first allocated. It is processed after the inode claiming the
- * bigger block that replaces it has been written to disk. Note that the
- * ff_state field is is used to store the uid, so may lose data. However,
- * the uid is used only in printing an error message, so is not critical.
- * Keeping it in a short keeps the data structure down to 32 bytes.
+ * bigger block that replaces it has been written to disk.
*/
struct freefrag {
struct worklist ff_list; /* id_inowait or delayed worklist */
-# define ff_state ff_list.wk_state /* owning user; should be uid_t */
+# define ff_state ff_list.wk_state
+ struct jfreefrag *ff_jfreefrag; /* Associated journal entry. */
+ struct workhead ff_jwork; /* Journal work pending. */
ufs2_daddr_t ff_blkno; /* fragment physical block number */
long ff_fragsize; /* size of fragment being deleted */
ino_t ff_inum; /* owning inode number */
@@ -423,20 +482,57 @@ struct freefrag {
* A "freeblks" structure is attached to an "inodedep" when the
* corresponding file's length is reduced to zero. It records all
* the information needed to free the blocks of a file after its
- * zero'ed inode has been written to disk.
+ * zero'ed inode has been written to disk. The actual work is done
+ * by child freework structures which are responsible for individual
+ * inode pointers while freeblks is responsible for retiring the
+ * entire operation when it is complete and holding common members.
*/
struct freeblks {
struct worklist fb_list; /* id_inowait or delayed worklist */
# define fb_state fb_list.wk_state /* inode and dirty block state */
+ struct jfreeblkhd fb_jfreeblkhd; /* Journal entries pending */
+ struct workhead fb_freeworkhd; /* Work items pending */
+ struct workhead fb_jwork; /* Journal work pending */
ino_t fb_previousinum; /* inode of previous owner of blocks */
uid_t fb_uid; /* uid of previous owner of blocks */
struct vnode *fb_devvp; /* filesystem device vnode */
- long fb_oldextsize; /* previous ext data size */
- off_t fb_oldsize; /* previous file size */
ufs2_daddr_t fb_chkcnt; /* used to check cnt of blks released */
- ufs2_daddr_t fb_dblks[NDADDR]; /* direct blk ptrs to deallocate */
- ufs2_daddr_t fb_iblks[NIADDR]; /* indirect blk ptrs to deallocate */
- ufs2_daddr_t fb_eblks[NXADDR]; /* indirect blk ptrs to deallocate */
+ int fb_ref; /* Children outstanding. */
+};
+
+/*
+ * A "freework" structure handles the release of a tree of blocks or a single
+ * block. Each indirect block in a tree is allocated its own freework
+ * structure so that the indrect block may be freed only when all of its
+ * children are freed. In this way we enforce the rule that an allocated
+ * block must have a valid path to a root that is journaled. Each child
+ * block acquires a reference and when the ref hits zero the parent ref
+ * is decremented. If there is no parent the freeblks ref is decremented.
+ */
+struct freework {
+ struct worklist fw_list;
+# define fw_state fw_list.wk_state
+ LIST_ENTRY(freework) fw_next; /* Queue for freeblksk. */
+ struct freeblks *fw_freeblks; /* Root of operation. */
+ struct freework *fw_parent; /* Parent indirect. */
+ ufs2_daddr_t fw_blkno; /* Our block #. */
+ ufs_lbn_t fw_lbn; /* Original lbn before free. */
+ int fw_frags; /* Number of frags. */
+ int fw_ref; /* Number of children out. */
+ int fw_off; /* Current working position. */
+ struct workhead fw_jwork; /* Journal work pending. */
+};
+
+/*
+ * A "freedep" structure is allocated to track the completion of a bitmap
+ * write for a freework. One freedep may cover many freed blocks so long
+ * as they reside in the same cylinder group. When the cg is written
+ * the freedep decrements the ref on the freework which may permit it
+ * to be freed as well.
+ */
+struct freedep {
+ struct worklist fd_list;
+ struct freework *fd_freework; /* Parent freework. */
};
/*
@@ -450,6 +546,7 @@ struct freefile {
mode_t fx_mode; /* mode of inode */
ino_t fx_oldinum; /* inum of the unlinked file */
struct vnode *fx_devvp; /* filesystem device vnode */
+ struct workhead fx_jwork; /* journal work pending. */
};
/*
@@ -482,12 +579,11 @@ struct freefile {
* than zero.
*
* The overlaying of da_pagedep and da_previous is done to keep the
- * structure down to 32 bytes in size on a 32-bit machine. If a
- * da_previous entry is present, the pointer to its pagedep is available
- * in the associated dirrem entry. If the DIRCHG flag is set, the
- * da_previous entry is valid; if not set the da_pagedep entry is valid.
- * The DIRCHG flag never changes; it is set when the structure is created
- * if appropriate and is never cleared.
+ * structure down. If a da_previous entry is present, the pointer to its
+ * pagedep is available in the associated dirrem entry. If the DIRCHG flag
+ * is set, the da_previous entry is valid; if not set the da_pagedep entry
+ * is valid. The DIRCHG flag never changes; it is set when the structure
+ * is created if appropriate and is never cleared.
*/
struct diradd {
struct worklist da_list; /* id_inowait or id_pendinghd list */
@@ -499,6 +595,7 @@ struct diradd {
struct dirrem *dau_previous; /* entry being replaced in dir change */
struct pagedep *dau_pagedep; /* pagedep dependency for addition */
} da_un;
+ struct workhead da_jwork; /* Journal work awaiting completion. */
};
#define da_previous da_un.dau_previous
#define da_pagedep da_un.dau_pagedep
@@ -525,12 +622,13 @@ struct diradd {
* mkdir structures that reference it. The deletion would be faster if the
* diradd structure were simply augmented to have two pointers that referenced
* the associated mkdir's. However, this would increase the size of the diradd
- * structure from 32 to 64-bits to speed a very infrequent operation.
+ * structure to speed a very infrequent operation.
*/
struct mkdir {
struct worklist md_list; /* id_inowait or buffer holding dir */
# define md_state md_list.wk_state /* type: MKDIR_PARENT or MKDIR_BODY */
struct diradd *md_diradd; /* associated diradd */
+ struct jaddref *md_jaddref; /* dependent jaddref. */
struct buf *md_buf; /* MKDIR_BODY: buffer holding dir */
LIST_ENTRY(mkdir) md_mkdirs; /* list of all mkdirs */
};
@@ -542,20 +640,19 @@ LIST_HEAD(mkdirlist, mkdir) mkdirlisthd;
* list of the pagedep for the directory page that contains the entry.
* It is processed after the directory page with the deleted entry has
* been written to disk.
- *
- * The overlaying of dm_pagedep and dm_dirinum is done to keep the
- * structure down to 32 bytes in size on a 32-bit machine. It works
- * because they are never used concurrently.
*/
struct dirrem {
struct worklist dm_list; /* delayed worklist */
# define dm_state dm_list.wk_state /* state of the old directory entry */
LIST_ENTRY(dirrem) dm_next; /* pagedep's list of dirrem's */
+ LIST_ENTRY(dirrem) dm_inonext; /* inodedep's list of dirrem's */
+ struct jremrefhd dm_jremrefhd; /* Pending remove reference deps. */
ino_t dm_oldinum; /* inum of the removed dir entry */
union {
struct pagedep *dmu_pagedep; /* pagedep dependency for remove */
ino_t dmu_dirinum; /* parent inode number (for rmdir) */
} dm_un;
+ struct workhead dm_jwork; /* Journal work awaiting completion. */
};
#define dm_pagedep dm_un.dmu_pagedep
#define dm_dirinum dm_un.dmu_dirinum
@@ -577,9 +674,200 @@ struct dirrem {
* blocks using a similar scheme with the allocindir structures. Rather
* than adding this level of complexity, we simply write those newly
* allocated indirect blocks synchronously as such allocations are rare.
+ * In the case of a new directory the . and .. links are tracked with
+ * a mkdir rather than a pagedep. In this case we track the mkdir
+ * so it can be released when it is written. A workhead is used
+ * to simplify canceling a mkdir that is removed by a subsequent dirrem.
*/
struct newdirblk {
struct worklist db_list; /* id_inowait or pg_newdirblk */
# define db_state db_list.wk_state /* unused */
struct pagedep *db_pagedep; /* associated pagedep */
+ struct workhead db_mkdir;
+};
+
+/*
+ * The inoref structure holds the elements common to jaddref and jremref
+ * so they may easily be queued in-order on the inodedep.
+ */
+struct inoref {
+ struct worklist if_list;
+# define if_state if_list.wk_state
+ TAILQ_ENTRY(inoref) if_deps; /* Links for inodedep. */
+ struct jsegdep *if_jsegdep;
+ off_t if_diroff; /* Directory offset. */
+ ino_t if_ino; /* Inode number. */
+ ino_t if_parent; /* Parent inode number. */
+ nlink_t if_nlink; /* nlink before addition. */
+ uint16_t if_mode; /* File mode, needed for IFMT. */
+};
+
+/*
+ * A "jaddref" structure tracks a new reference (link count) on an inode
+ * and prevents the link count increase and bitmap allocation until a
+ * journal entry can be written. Once the journal entry is written,
+ * the inode is put on the pendinghd of the bmsafemap and a diradd or
+ * mkdir entry is placed on the bufwait list of the inode. The DEPCOMPLETE
+ * flag is used to indicate that all of the required information for writing
+ * the journal entry is present. MKDIR_BODY and MKDIR_PARENT are used to
+ * differentiate . and .. links from regular file names. NEWBLOCK indicates
+ * a bitmap is still pending. If a new reference is canceled by a delete
+ * prior to writing the journal the jaddref write is canceled and the
+ * structure persists to prevent any disk-visible changes until it is
+ * ultimately released when the file is freed or the link is dropped again.
+ */
+struct jaddref {
+ struct inoref ja_ref;
+# define ja_list ja_ref.if_list /* Journal pending or jseg entries. */
+# define ja_state ja_ref.if_list.wk_state
+ LIST_ENTRY(jaddref) ja_bmdeps; /* Links for bmsafemap. */
+ union {
+ struct diradd *jau_diradd; /* Pending diradd. */
+ struct mkdir *jau_mkdir; /* MKDIR_{PARENT,BODY} */
+ } ja_un;
+};
+#define ja_diradd ja_un.jau_diradd
+#define ja_mkdir ja_un.jau_mkdir
+#define ja_diroff ja_ref.if_diroff
+#define ja_ino ja_ref.if_ino
+#define ja_parent ja_ref.if_parent
+#define ja_mode ja_ref.if_mode
+
+/*
+ * A "jremref" structure tracks a removed reference (unlink) on an
+ * inode and prevents the directory remove from proceeding until the
+ * journal entry is written. Once the journal has been written the remove
+ * may proceed as normal.
+ */
+struct jremref {
+ struct inoref jr_ref;
+# define jr_list jr_ref.if_list /* Journal pending or jseg entries. */
+# define jr_state jr_ref.if_list.wk_state
+ LIST_ENTRY(jremref) jr_deps; /* Links for pagdep. */
+ struct dirrem *jr_dirrem; /* Back pointer to dirrem. */
+};
+
+struct jmvref {
+ struct worklist jm_list;
+ LIST_ENTRY(jmvref) jm_deps;
+ struct pagedep *jm_pagedep;
+ ino_t jm_parent;
+ ino_t jm_ino;
+ off_t jm_oldoff;
+ off_t jm_newoff;
+};
+
+/*
+ * A "jnewblk" structure tracks a newly allocated block or fragment and
+ * prevents the direct or indirect block pointer as well as the cg bitmap
+ * from being written until it is logged. After it is logged the jsegdep
+ * is attached to the allocdirect or allocindir until the operation is
+ * completed or reverted. If the operation is reverted prior to the journal
+ * write the jnewblk structure is maintained to prevent the bitmaps from
+ * reaching the disk. Ultimately the jnewblk structure will be passed
+ * to the free routine as the in memory cg is modified back to the free
+ * state at which time it can be released.
+ */
+struct jnewblk {
+ struct worklist jn_list;
+# define jn_state jn_list.wk_state
+ struct jsegdep *jn_jsegdep;
+ LIST_ENTRY(jnewblk) jn_deps; /* All jnewblks on bmsafemap */
+ struct newblk *jn_newblk;
+ ino_t jn_ino;
+ ufs_lbn_t jn_lbn;
+ ufs2_daddr_t jn_blkno;
+ int jn_oldfrags;
+ int jn_frags;
+};
+
+/*
+ * A "jfreeblk" structure tracks the journal write for freeing a block
+ * or tree of blocks. The block pointer must not be cleared in the inode
+ * or indirect prior to the jfreeblk being written.
+ */
+struct jfreeblk {
+ struct worklist jf_list;
+# define jf_state jf_list.wk_state
+ struct jsegdep *jf_jsegdep;
+ struct freeblks *jf_freeblks;
+ LIST_ENTRY(jfreeblk) jf_deps;
+ ino_t jf_ino;
+ ufs_lbn_t jf_lbn;
+ ufs2_daddr_t jf_blkno;
+ int jf_frags;
+};
+
+/*
+ * A "jfreefrag" tracks the freeing of a single block when a fragment is
+ * extended or an indirect page is replaced. It is not part of a larger
+ * freeblks operation.
+ */
+struct jfreefrag {
+ struct worklist fr_list;
+# define fr_state fr_list.wk_state
+ struct jsegdep *fr_jsegdep;
+ struct freefrag *fr_freefrag;
+ ino_t fr_ino;
+ ufs_lbn_t fr_lbn;
+ ufs2_daddr_t fr_blkno;
+ int fr_frags;
+};
+
+/*
+ * A "jtrunc" journals the intent to truncate an inode to a non-zero
+ * value. This is done synchronously prior to the synchronous partial
+ * truncation process. The jsegdep is not released until the truncation
+ * is complete and the truncated inode is fsync'd.
+ */
+struct jtrunc {
+ struct worklist jt_list;
+ struct jsegdep *jt_jsegdep;
+ ino_t jt_ino;
+ off_t jt_size;
+ int jt_extsize;
+};
+
+/*
+ * A "jsegdep" structure tracks a single reference to a written journal
+ * segment so the journal space can be reclaimed when all dependencies
+ * have been written.
+ */
+struct jsegdep {
+ struct worklist jd_list;
+# define jd_state jd_list.wk_state
+ struct jseg *jd_seg;
+};
+
+/*
+ * A "jseg" structure contains all of the journal records written in a
+ * single disk write. jaddref and jremref structures are linked into
+ * js_entries so thay may be completed when the write completes. The
+ * js_deps array contains as many entries as there are ref counts to
+ * reduce the number of allocations required per journal write to one.
+ */
+struct jseg {
+ struct worklist js_list; /* b_deps link for journal */
+# define js_state js_list.wk_state
+ struct workhead js_entries; /* Entries awaiting write */
+ TAILQ_ENTRY(jseg) js_next;
+ struct jblocks *js_jblocks; /* Back pointer to block/seg list */
+ struct buf *js_buf; /* Buffer while unwritten */
+ uint64_t js_seq;
+ int js_size; /* Allocated size in bytes */
+ int js_cnt; /* Total items allocated */
+ int js_refs; /* Count of items pending completion */
+};
+
+/*
+ * A 'sbdep' structure tracks the head of the free inode list and
+ * superblock writes. This makes sure the superblock is always pointing at
+ * the first possible unlinked inode for the suj recovery process. If a
+ * block write completes and we discover a new head is available the buf
+ * is dirtied and the dep is kept.
+ */
+struct sbdep {
+ struct worklist sb_list; /* b_dep linkage */
+ struct fs *sb_fs; /* Filesystem pointer within buf. */
+ struct ufsmount *sb_ump;
};
diff --git a/sys/ufs/ufs/dinode.h b/sys/ufs/ufs/dinode.h
index 7f9e7c5..c75257c 100644
--- a/sys/ufs/ufs/dinode.h
+++ b/sys/ufs/ufs/dinode.h
@@ -146,7 +146,8 @@ struct ufs2_dinode {
ufs2_daddr_t di_db[NDADDR]; /* 112: Direct disk blocks. */
ufs2_daddr_t di_ib[NIADDR]; /* 208: Indirect disk blocks. */
u_int64_t di_modrev; /* 232: i_modrev for NFSv4 */
- int64_t di_spare[2]; /* 240: Reserved; currently unused */
+ ino_t di_freelink; /* 240: SUJ: Next unlinked inode. */
+ uint32_t di_spare[3]; /* 244: Reserved; currently unused */
};
/*
@@ -167,9 +168,7 @@ struct ufs2_dinode {
struct ufs1_dinode {
u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
int16_t di_nlink; /* 2: File link count. */
- union {
- u_int16_t oldids[2]; /* 4: Ffs: old user and group ids. */
- } di_u;
+ ino_t di_freelink; /* 4: SUJ: Next unlinked inode. */
u_int64_t di_size; /* 8: File byte count. */
int32_t di_atime; /* 16: Last access time. */
int32_t di_atimensec; /* 20: Last access time. */
@@ -186,7 +185,5 @@ struct ufs1_dinode {
u_int32_t di_gid; /* 116: File group. */
u_int64_t di_modrev; /* 120: i_modrev for NFSv4 */
};
-#define di_ogid di_u.oldids[1]
-#define di_ouid di_u.oldids[0]
#endif /* _UFS_UFS_DINODE_H_ */
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 565580e..295b129 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -120,7 +120,7 @@ struct inode {
#define IN_CHANGE 0x0002 /* Inode change time update request. */
#define IN_UPDATE 0x0004 /* Modification time update request. */
#define IN_MODIFIED 0x0008 /* Inode has been modified. */
-#define IN_RENAME 0x0010 /* Inode is being renamed. */
+#define IN_NEEDSYNC 0x0010 /* Inode requires fsync. */
#define IN_LAZYMOD 0x0040 /* Modified, but don't write yet. */
#define IN_SPACECOUNTED 0x0080 /* Blocks to be freed in free count. */
#define IN_LAZYACCESS 0x0100 /* Process IN_ACCESS after the
@@ -175,6 +175,7 @@ struct indir {
/* Determine if soft dependencies are being done */
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
+#define DOINGSUJ(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_SUJ)
/* This overlays the fid structure (see mount.h). */
struct ufid {
diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c
index c85fdc8..d7c1d0d 100644
--- a/sys/ufs/ufs/ufs_dirhash.c
+++ b/sys/ufs/ufs/ufs_dirhash.c
@@ -68,8 +68,6 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_DIRHASH, "ufs_dirhash", "UFS directory hash tables");
-static SYSCTL_NODE(_vfs, OID_AUTO, ufs, CTLFLAG_RD, 0, "UFS filesystem");
-
static int ufs_mindirhashsize = DIRBLKSIZ * 5;
SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_minsize, CTLFLAG_RW,
&ufs_mindirhashsize,
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index b2e4a97..6658b66 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -57,7 +57,7 @@ int ufs_bmap(struct vop_bmap_args *);
int ufs_bmaparray(struct vnode *, ufs2_daddr_t, ufs2_daddr_t *,
struct buf *, int *, int *);
int ufs_fhtovp(struct mount *, struct ufid *, struct vnode **);
-int ufs_checkpath(ino_t, struct inode *, struct ucred *);
+int ufs_checkpath(ino_t, ino_t, struct inode *, struct ucred *, ino_t *);
void ufs_dirbad(struct inode *, doff_t, char *);
int ufs_dirbadentry(struct vnode *, struct direct *, int);
int ufs_dirempty(struct inode *, ino_t, struct ucred *);
@@ -66,9 +66,11 @@ int ufs_extwrite(struct vop_write_args *);
void ufs_makedirentry(struct inode *, struct componentname *,
struct direct *);
int ufs_direnter(struct vnode *, struct vnode *, struct direct *,
- struct componentname *, struct buf *);
+ struct componentname *, struct buf *, int);
int ufs_dirremove(struct vnode *, struct inode *, int, int);
int ufs_dirrewrite(struct inode *, struct inode *, ino_t, int, int);
+int ufs_lookup_ino(struct vnode *, struct vnode **, struct componentname *,
+ ino_t *);
int ufs_getlbns(struct vnode *, ufs2_daddr_t, struct indir *, int *);
int ufs_inactive(struct vop_inactive_args *);
int ufs_init(struct vfsconf *);
@@ -81,19 +83,33 @@ vfs_root_t ufs_root;
int ufs_uninit(struct vfsconf *);
int ufs_vinit(struct mount *, struct vop_vector *, struct vnode **);
+#include <sys/sysctl.h>
+SYSCTL_DECL(_vfs_ufs);
+
/*
* Soft update function prototypes.
*/
int softdep_setup_directory_add(struct buf *, struct inode *, off_t,
ino_t, struct buf *, int);
-void softdep_change_directoryentry_offset(struct inode *, caddr_t,
- caddr_t, caddr_t, int);
+void softdep_change_directoryentry_offset(struct buf *, struct inode *,
+ caddr_t, caddr_t, caddr_t, int);
void softdep_setup_remove(struct buf *,struct inode *, struct inode *, int);
void softdep_setup_directory_change(struct buf *, struct inode *,
struct inode *, ino_t, int);
void softdep_change_linkcnt(struct inode *);
void softdep_releasefile(struct inode *);
int softdep_slowdown(struct vnode *);
+void softdep_setup_create(struct inode *, struct inode *);
+void softdep_setup_dotdot_link(struct inode *, struct inode *);
+void softdep_setup_link(struct inode *, struct inode *);
+void softdep_setup_mkdir(struct inode *, struct inode *);
+void softdep_setup_rmdir(struct inode *, struct inode *);
+void softdep_setup_unlink(struct inode *, struct inode *);
+void softdep_revert_create(struct inode *, struct inode *);
+void softdep_revert_dotdot_link(struct inode *, struct inode *);
+void softdep_revert_link(struct inode *, struct inode *);
+void softdep_revert_mkdir(struct inode *, struct inode *);
+void softdep_revert_rmdir(struct inode *, struct inode *);
/*
* Flags to low-level allocation routines. The low 16-bits are reserved
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index b0247e7..0030c52 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -77,9 +77,6 @@ SYSCTL_INT(_debug, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, "");
/* true if old FS format...*/
#define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0)
-static int ufs_lookup_(struct vnode *, struct vnode **, struct componentname *,
- ino_t *);
-
static int
ufs_delete_denied(struct vnode *vdp, struct vnode *tdp, struct ucred *cred,
struct thread *td)
@@ -189,11 +186,11 @@ ufs_lookup(ap)
} */ *ap;
{
- return (ufs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL));
+ return (ufs_lookup_ino(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL));
}
-static int
-ufs_lookup_(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp,
+int
+ufs_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp,
ino_t *dd_ino)
{
struct inode *dp; /* inode for directory being searched */
@@ -524,6 +521,8 @@ notfound:
return (ENOENT);
found:
+ if (dd_ino != NULL)
+ *dd_ino = ino;
if (numdirpasses == 2)
nchstats.ncs_pass2++;
/*
@@ -546,11 +545,6 @@ found:
if ((flags & ISLASTCN) && nameiop == LOOKUP)
dp->i_diroff = i_offset &~ (DIRBLKSIZ - 1);
- if (dd_ino != NULL) {
- *dd_ino = ino;
- return (0);
- }
-
/*
* If deleting, and at end of pathname, return
* parameters which can be used to remove file.
@@ -558,17 +552,6 @@ found:
if (nameiop == DELETE && (flags & ISLASTCN)) {
if (flags & LOCKPARENT)
ASSERT_VOP_ELOCKED(vdp, __FUNCTION__);
- if ((error = VFS_VGET(vdp->v_mount, ino,
- LK_EXCLUSIVE, &tdp)) != 0)
- return (error);
-
- error = ufs_delete_denied(vdp, tdp, cred, cnp->cn_thread);
- if (error) {
- vput(tdp);
- return (error);
- }
-
-
/*
* Return pointer to current entry in dp->i_offset,
* and distance past previous entry (if there
@@ -585,6 +568,16 @@ found:
dp->i_count = 0;
else
dp->i_count = dp->i_offset - prevoff;
+ if (dd_ino != NULL)
+ return (0);
+ if ((error = VFS_VGET(vdp->v_mount, ino,
+ LK_EXCLUSIVE, &tdp)) != 0)
+ return (error);
+ error = ufs_delete_denied(vdp, tdp, cred, cnp->cn_thread);
+ if (error) {
+ vput(tdp);
+ return (error);
+ }
if (dp->i_number == ino) {
VREF(vdp);
*vpp = vdp;
@@ -616,6 +609,8 @@ found:
dp->i_offset = i_offset;
if (dp->i_number == ino)
return (EISDIR);
+ if (dd_ino != NULL)
+ return (0);
if ((error = VFS_VGET(vdp->v_mount, ino,
LK_EXCLUSIVE, &tdp)) != 0)
return (error);
@@ -650,6 +645,8 @@ found:
cnp->cn_flags |= SAVENAME;
return (0);
}
+ if (dd_ino != NULL)
+ return (0);
/*
* Step through the translation in the name. We do not `vput' the
@@ -681,7 +678,7 @@ found:
* to the inode we looked up before vdp lock was
* dropped.
*/
- error = ufs_lookup_(pdp, NULL, cnp, &ino1);
+ error = ufs_lookup_ino(pdp, NULL, cnp, &ino1);
if (error) {
vput(tdp);
return (error);
@@ -704,6 +701,14 @@ found:
vn_lock(vdp, LK_UPGRADE | LK_RETRY);
else /* if (ltype == LK_SHARED) */
vn_lock(vdp, LK_DOWNGRADE | LK_RETRY);
+ /*
+ * Relock for the "." case may left us with
+ * reclaimed vnode.
+ */
+ if (vdp->v_iflag & VI_DOOMED) {
+ vrele(vdp);
+ return (ENOENT);
+ }
}
*vpp = vdp;
} else {
@@ -825,12 +830,13 @@ ufs_makedirentry(ip, cnp, newdirp)
* soft dependency code).
*/
int
-ufs_direnter(dvp, tvp, dirp, cnp, newdirbp)
+ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename)
struct vnode *dvp;
struct vnode *tvp;
struct direct *dirp;
struct componentname *cnp;
struct buf *newdirbp;
+ int isrename;
{
struct ucred *cr;
struct thread *td;
@@ -903,22 +909,28 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp)
blkoff += DIRBLKSIZ;
}
if (softdep_setup_directory_add(bp, dp, dp->i_offset,
- dirp->d_ino, newdirbp, 1) == 0) {
- bdwrite(bp);
+ dirp->d_ino, newdirbp, 1))
+ dp->i_flag |= IN_NEEDSYNC;
+ if (newdirbp)
+ bdwrite(newdirbp);
+ bdwrite(bp);
+ if ((dp->i_flag & IN_NEEDSYNC) == 0)
return (UFS_UPDATE(dvp, 0));
- }
- /* We have just allocated a directory block in an
- * indirect block. Rather than tracking when it gets
- * claimed by the inode, we simply do a VOP_FSYNC
- * now to ensure that it is there (in case the user
- * does a future fsync). Note that we have to unlock
- * the inode for the entry that we just entered, as
- * the VOP_FSYNC may need to lock other inodes which
- * can lead to deadlock if we also hold a lock on
- * the newly entered node.
+ /*
+ * We have just allocated a directory block in an
+ * indirect block. We must prevent holes in the
+ * directory created if directory entries are
+ * written out of order. To accomplish this we
+ * fsync when we extend a directory into indirects.
+ * During rename it's not safe to drop the tvp lock
+ * so sync must be delayed until it is.
+ *
+ * This synchronous step could be removed if fsck and
+ * the kernel were taught to fill in sparse
+ * directories rather than panic.
*/
- if ((error = bwrite(bp)))
- return (error);
+ if (isrename)
+ return (0);
if (tvp != NULL)
VOP_UNLOCK(tvp, 0);
error = VOP_FSYNC(dvp, MNT_WAIT, td);
@@ -1007,7 +1019,7 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp)
dp->i_offset + ((char *)ep - dirbuf));
#endif
if (DOINGSOFTDEP(dvp))
- softdep_change_directoryentry_offset(dp, dirbuf,
+ softdep_change_directoryentry_offset(bp, dp, dirbuf,
(caddr_t)nep, (caddr_t)ep, dsize);
else
bcopy((caddr_t)nep, (caddr_t)ep, dsize);
@@ -1059,6 +1071,8 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp)
(void) softdep_setup_directory_add(bp, dp,
dp->i_offset + (caddr_t)ep - dirbuf,
dirp->d_ino, newdirbp, 0);
+ if (newdirbp != NULL)
+ bdwrite(newdirbp);
bdwrite(bp);
} else {
if (DOINGASYNC(dvp)) {
@@ -1076,7 +1090,8 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp)
* lock other inodes which can lead to deadlock if we also hold a
* lock on the newly entered node.
*/
- if (error == 0 && dp->i_endoff && dp->i_endoff < dp->i_size) {
+ if (isrename == 0 && error == 0 &&
+ dp->i_endoff && dp->i_endoff < dp->i_size) {
if (tvp != NULL)
VOP_UNLOCK(tvp, 0);
#ifdef UFS_DIRHASH
@@ -1117,6 +1132,19 @@ ufs_dirremove(dvp, ip, flags, isrmdir)
dp = VTOI(dvp);
+ /*
+ * Adjust the link count early so softdep can block if necessary.
+ */
+ if (ip) {
+ ip->i_effnlink--;
+ if (DOINGSOFTDEP(dvp)) {
+ softdep_setup_unlink(dp, ip);
+ } else {
+ ip->i_nlink--;
+ DIP_SET(ip, i_nlink, ip->i_nlink);
+ ip->i_flag |= IN_CHANGE;
+ }
+ }
if (flags & DOWHITEOUT) {
/*
* Whiteout entry: set d_ino to WINO.
@@ -1146,6 +1174,9 @@ ufs_dirremove(dvp, ip, flags, isrmdir)
if (dp->i_dirhash != NULL)
ufsdirhash_remove(dp, rep, dp->i_offset);
#endif
+ if (ip && rep->d_ino != ip->i_number)
+ panic("ufs_dirremove: ip %d does not match dirent ino %d\n",
+ ip->i_number, rep->d_ino);
if (dp->i_count == 0) {
/*
* First entry in block: set d_ino to zero.
@@ -1164,31 +1195,20 @@ ufs_dirremove(dvp, ip, flags, isrmdir)
dp->i_offset & ~(DIRBLKSIZ - 1));
#endif
out:
+ error = 0;
if (DOINGSOFTDEP(dvp)) {
- if (ip) {
- ip->i_effnlink--;
- softdep_change_linkcnt(ip);
+ if (ip)
softdep_setup_remove(bp, dp, ip, isrmdir);
- }
- if (softdep_slowdown(dvp)) {
+ if (softdep_slowdown(dvp))
error = bwrite(bp);
- } else {
+ else
bdwrite(bp);
- error = 0;
- }
} else {
- if (ip) {
- ip->i_effnlink--;
- ip->i_nlink--;
- DIP_SET(ip, i_nlink, ip->i_nlink);
- ip->i_flag |= IN_CHANGE;
- }
if (flags & DOWHITEOUT)
error = bwrite(bp);
- else if (DOINGASYNC(dvp) && dp->i_count != 0) {
+ else if (DOINGASYNC(dvp) && dp->i_count != 0)
bdwrite(bp);
- error = 0;
- } else
+ else
error = bwrite(bp);
}
dp->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -1221,6 +1241,19 @@ ufs_dirrewrite(dp, oip, newinum, newtype, isrmdir)
struct vnode *vdp = ITOV(dp);
int error;
+ /*
+ * Drop the link before we lock the buf so softdep can block if
+ * necessary.
+ */
+ oip->i_effnlink--;
+ if (DOINGSOFTDEP(vdp)) {
+ softdep_setup_unlink(dp, oip);
+ } else {
+ oip->i_nlink--;
+ DIP_SET(oip, i_nlink, oip->i_nlink);
+ oip->i_flag |= IN_CHANGE;
+ }
+
error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp);
if (error)
return (error);
@@ -1232,15 +1265,10 @@ ufs_dirrewrite(dp, oip, newinum, newtype, isrmdir)
ep->d_ino = newinum;
if (!OFSFMT(vdp))
ep->d_type = newtype;
- oip->i_effnlink--;
if (DOINGSOFTDEP(vdp)) {
- softdep_change_linkcnt(oip);
softdep_setup_directory_change(bp, dp, oip, newinum, isrmdir);
bdwrite(bp);
} else {
- oip->i_nlink--;
- DIP_SET(oip, i_nlink, oip->i_nlink);
- oip->i_flag |= IN_CHANGE;
if (DOINGASYNC(vdp)) {
bdwrite(bp);
error = 0;
@@ -1355,25 +1383,25 @@ ufs_dir_dd_ino(struct vnode *vp, struct ucred *cred, ino_t *dd_ino)
/*
* Check if source directory is in the path of the target directory.
- * Target is supplied locked, source is unlocked.
- * The target is always vput before returning.
*/
int
-ufs_checkpath(ino_t source_ino, struct inode *target, struct ucred *cred)
+ufs_checkpath(ino_t source_ino, ino_t parent_ino, struct inode *target, struct ucred *cred, ino_t *wait_ino)
{
- struct vnode *vp, *vp1;
+ struct mount *mp;
+ struct vnode *tvp, *vp, *vp1;
int error;
ino_t dd_ino;
- vp = ITOV(target);
- if (target->i_number == source_ino) {
- error = EEXIST;
- goto out;
- }
- error = 0;
+ vp = tvp = ITOV(target);
+ mp = vp->v_mount;
+ *wait_ino = 0;
+ if (target->i_number == source_ino)
+ return (EEXIST);
+ if (target->i_number == parent_ino)
+ return (0);
if (target->i_number == ROOTINO)
- goto out;
-
+ return (0);
+ error = 0;
for (;;) {
error = ufs_dir_dd_ino(vp, cred, &dd_ino);
if (error != 0)
@@ -1384,9 +1412,13 @@ ufs_checkpath(ino_t source_ino, struct inode *target, struct ucred *cred)
}
if (dd_ino == ROOTINO)
break;
- error = vn_vget_ino(vp, dd_ino, LK_EXCLUSIVE, &vp1);
- if (error != 0)
+ if (dd_ino == parent_ino)
break;
+ error = VFS_VGET(mp, dd_ino, LK_SHARED | LK_NOWAIT, &vp1);
+ if (error != 0) {
+ *wait_ino = dd_ino;
+ break;
+ }
/* Recheck that ".." still points to vp1 after relock of vp */
error = ufs_dir_dd_ino(vp, cred, &dd_ino);
if (error != 0) {
@@ -1398,14 +1430,14 @@ ufs_checkpath(ino_t source_ino, struct inode *target, struct ucred *cred)
vput(vp1);
continue;
}
- vput(vp);
+ if (vp != tvp)
+ vput(vp);
vp = vp1;
}
-out:
if (error == ENOTDIR)
- printf("checkpath: .. not a directory\n");
- if (vp != NULL)
+ panic("checkpath: .. not a directory\n");
+ if (vp != tvp)
vput(vp);
return (error);
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 9d4d93d..f8d45cf 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -114,6 +114,8 @@ static vop_close_t ufsfifo_close;
static vop_kqfilter_t ufsfifo_kqfilter;
static vop_pathconf_t ufsfifo_pathconf;
+SYSCTL_NODE(_vfs, OID_AUTO, ufs, CTLFLAG_RD, 0, "UFS filesystem");
+
/*
* A virgin directory (no blushing please).
*/
@@ -974,6 +976,9 @@ ufs_link(ap)
error = EXDEV;
goto out;
}
+ if (VTOI(tdvp)->i_effnlink < 2)
+ panic("ufs_link: Bad link count %d on parent",
+ VTOI(tdvp)->i_effnlink);
ip = VTOI(vp);
if ((nlink_t)ip->i_nlink >= LINK_MAX) {
error = EMLINK;
@@ -988,11 +993,11 @@ ufs_link(ap)
DIP_SET(ip, i_nlink, ip->i_nlink);
ip->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(vp))
- softdep_change_linkcnt(ip);
+ softdep_setup_link(VTOI(tdvp), ip);
error = UFS_UPDATE(vp, !(DOINGSOFTDEP(vp) | DOINGASYNC(vp)));
if (!error) {
ufs_makedirentry(ip, cnp, &newdir);
- error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL);
+ error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL, 0);
}
if (error) {
@@ -1001,7 +1006,7 @@ ufs_link(ap)
DIP_SET(ip, i_nlink, ip->i_nlink);
ip->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(vp))
- softdep_change_linkcnt(ip);
+ softdep_revert_link(VTOI(tdvp), ip);
}
out:
return (error);
@@ -1043,7 +1048,7 @@ ufs_whiteout(ap)
newdir.d_namlen = cnp->cn_namelen;
bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
newdir.d_type = DT_WHT;
- error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL);
+ error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL, 0);
break;
case DELETE:
@@ -1062,6 +1067,11 @@ ufs_whiteout(ap)
return (error);
}
+static volatile int rename_restarts;
+SYSCTL_INT(_vfs_ufs, OID_AUTO, rename_restarts, CTLFLAG_RD,
+ __DEVOLATILE(int *, &rename_restarts), 0,
+ "Times rename had to restart due to lock contention");
+
/*
* Rename system call.
* rename("foo", "bar");
@@ -1101,111 +1111,183 @@ ufs_rename(ap)
struct vnode *tdvp = ap->a_tdvp;
struct vnode *fvp = ap->a_fvp;
struct vnode *fdvp = ap->a_fdvp;
+ struct vnode *nvp;
struct componentname *tcnp = ap->a_tcnp;
struct componentname *fcnp = ap->a_fcnp;
struct thread *td = fcnp->cn_thread;
- struct inode *ip, *xp, *dp;
+ struct inode *fip, *tip, *tdp, *fdp;
struct direct newdir;
- int doingdirectory = 0, oldparent = 0, newparent = 0;
+ off_t endoff;
+ int doingdirectory, newparent;
int error = 0, ioflag;
- ino_t fvp_ino;
+ struct mount *mp;
+ ino_t ino;
#ifdef INVARIANTS
if ((tcnp->cn_flags & HASBUF) == 0 ||
(fcnp->cn_flags & HASBUF) == 0)
panic("ufs_rename: no name");
#endif
+ endoff = 0;
+ mp = tdvp->v_mount;
+ VOP_UNLOCK(tdvp, 0);
+ if (tvp && tvp != tdvp)
+ VOP_UNLOCK(tvp, 0);
/*
* Check for cross-device rename.
*/
if ((fvp->v_mount != tdvp->v_mount) ||
(tvp && (fvp->v_mount != tvp->v_mount))) {
error = EXDEV;
-abortit:
- if (tdvp == tvp)
- vrele(tdvp);
- else
- vput(tdvp);
- if (tvp)
- vput(tvp);
- vrele(fdvp);
+ mp = NULL;
+ goto releout;
+ }
+ error = vfs_busy(mp, 0);
+ if (error) {
+ mp = NULL;
+ goto releout;
+ }
+relock:
+ /*
+ * We need to acquire 2 to 4 locks depending on whether tvp is NULL
+ * and fdvp and tdvp are the same directory. Subsequently we need
+ * to double-check all paths and in the directory rename case we
+ * need to verify that we are not creating a directory loop. To
+ * handle this we acquire all but fdvp using non-blocking
+ * acquisitions. If we fail to acquire any lock in the path we will
+ * drop all held locks, acquire the new lock in a blocking fashion,
+ * and then release it and restart the rename. This acquire/release
+ * step ensures that we do not spin on a lock waiting for release.
+ */
+ error = vn_lock(fdvp, LK_EXCLUSIVE);
+ if (error)
+ goto releout;
+ if (vn_lock(tdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
+ VOP_UNLOCK(fdvp, 0);
+ error = vn_lock(tdvp, LK_EXCLUSIVE);
+ if (error)
+ goto releout;
+ VOP_UNLOCK(tdvp, 0);
+ atomic_add_int(&rename_restarts, 1);
+ goto relock;
+ }
+ /*
+ * Re-resolve fvp to be certain it still exists and fetch the
+ * correct vnode.
+ */
+ error = ufs_lookup_ino(fdvp, NULL, fcnp, &ino);
+ if (error) {
+ VOP_UNLOCK(fdvp, 0);
+ VOP_UNLOCK(tdvp, 0);
+ goto releout;
+ }
+ error = VFS_VGET(mp, ino, LK_EXCLUSIVE | LK_NOWAIT, &nvp);
+ if (error) {
+ VOP_UNLOCK(fdvp, 0);
+ VOP_UNLOCK(tdvp, 0);
+ if (error != EBUSY)
+ goto releout;
+ error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &nvp);
+ if (error != 0)
+ goto releout;
+ VOP_UNLOCK(nvp, 0);
vrele(fvp);
- return (error);
+ fvp = nvp;
+ atomic_add_int(&rename_restarts, 1);
+ goto relock;
}
-
+ vrele(fvp);
+ fvp = nvp;
+ /*
+ * Re-resolve tvp and acquire the vnode lock if present.
+ */
+ error = ufs_lookup_ino(tdvp, NULL, tcnp, &ino);
+ if (error != 0 && error != EJUSTRETURN) {
+ VOP_UNLOCK(fdvp, 0);
+ VOP_UNLOCK(tdvp, 0);
+ VOP_UNLOCK(fvp, 0);
+ goto releout;
+ }
+ /*
+ * If tvp disappeared we just carry on.
+ */
+ if (error == EJUSTRETURN && tvp != NULL) {
+ vrele(tvp);
+ tvp = NULL;
+ }
+ /*
+ * Get the tvp ino if the lookup succeeded. We may have to restart
+ * if the non-blocking acquire fails.
+ */
+ if (error == 0) {
+ nvp = NULL;
+ error = VFS_VGET(mp, ino, LK_EXCLUSIVE | LK_NOWAIT, &nvp);
+ if (tvp)
+ vrele(tvp);
+ tvp = nvp;
+ if (error) {
+ VOP_UNLOCK(fdvp, 0);
+ VOP_UNLOCK(tdvp, 0);
+ VOP_UNLOCK(fvp, 0);
+ if (error != EBUSY)
+ goto releout;
+ error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &nvp);
+ if (error != 0)
+ goto releout;
+ VOP_UNLOCK(nvp, 0);
+ atomic_add_int(&rename_restarts, 1);
+ goto relock;
+ }
+ }
+ fdp = VTOI(fdvp);
+ fip = VTOI(fvp);
+ tdp = VTOI(tdvp);
+ tip = NULL;
+ if (tvp)
+ tip = VTOI(tvp);
if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
(VTOI(tdvp)->i_flags & APPEND))) {
error = EPERM;
- goto abortit;
+ goto unlockout;
}
-
/*
* Renaming a file to itself has no effect. The upper layers should
- * not call us in that case. Temporarily just warn if they do.
+ * not call us in that case. However, things could change after
+ * we drop the locks above.
*/
if (fvp == tvp) {
- printf("ufs_rename: fvp == tvp (can't happen)\n");
error = 0;
- goto abortit;
+ goto unlockout;
}
-
- if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
- goto abortit;
- dp = VTOI(fdvp);
- ip = VTOI(fvp);
- if (ip->i_nlink >= LINK_MAX) {
- VOP_UNLOCK(fvp, 0);
+ doingdirectory = 0;
+ newparent = 0;
+ ino = fip->i_number;
+ if (fip->i_nlink >= LINK_MAX) {
error = EMLINK;
- goto abortit;
+ goto unlockout;
}
- if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
- || (dp->i_flags & APPEND)) {
- VOP_UNLOCK(fvp, 0);
+ if ((fip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
+ || (fdp->i_flags & APPEND)) {
error = EPERM;
- goto abortit;
+ goto unlockout;
}
- if ((ip->i_mode & IFMT) == IFDIR) {
+ if ((fip->i_mode & IFMT) == IFDIR) {
/*
* Avoid ".", "..", and aliases of "." for obvious reasons.
*/
if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
- dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT ||
- (ip->i_flag & IN_RENAME)) {
- VOP_UNLOCK(fvp, 0);
+ fdp == fip ||
+ (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT) {
error = EINVAL;
- goto abortit;
+ goto unlockout;
}
- ip->i_flag |= IN_RENAME;
- oldparent = dp->i_number;
+ if (fdp->i_number != tdp->i_number)
+ newparent = tdp->i_number;
doingdirectory = 1;
}
- vrele(fdvp);
-
- /*
- * When the target exists, both the directory
- * and target vnodes are returned locked.
- */
- dp = VTOI(tdvp);
- xp = NULL;
- if (tvp)
- xp = VTOI(tvp);
-
- /*
- * 1) Bump link count while we're moving stuff
- * around. If we crash somewhere before
- * completing our work, the link count
- * may be wrong, but correctable.
- */
- ip->i_effnlink++;
- ip->i_nlink++;
- DIP_SET(ip, i_nlink, ip->i_nlink);
- ip->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(fvp))
- softdep_change_linkcnt(ip);
- if ((error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) |
- DOINGASYNC(fvp)))) != 0) {
- VOP_UNLOCK(fvp, 0);
- goto bad;
+ if (fvp->v_mountedhere != NULL || (tvp && tvp->v_mountedhere != NULL)) {
+ error = EXDEV;
+ goto unlockout;
}
/*
@@ -1214,35 +1296,55 @@ abortit:
* directory hierarchy above the target, as this would
* orphan everything below the source directory. Also
* the user must have write permission in the source so
- * as to be able to change "..". We must repeat the call
- * to namei, as the parent directory is unlocked by the
- * call to checkpath().
+ * as to be able to change "..".
*/
- error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread);
- fvp_ino = ip->i_number;
- VOP_UNLOCK(fvp, 0);
- if (oldparent != dp->i_number)
- newparent = dp->i_number;
if (doingdirectory && newparent) {
- if (error) /* write access check above */
- goto bad;
- if (xp != NULL)
- vput(tvp);
- error = ufs_checkpath(fvp_ino, dp, tcnp->cn_cred);
+ error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread);
if (error)
- goto out;
+ goto unlockout;
+ error = ufs_checkpath(ino, fdp->i_number, tdp, tcnp->cn_cred,
+ &ino);
+ /*
+ * We encountered a lock that we have to wait for. Unlock
+ * everything else and VGET before restarting.
+ */
+ if (ino) {
+ VOP_UNLOCK(fdvp, 0);
+ VOP_UNLOCK(fvp, 0);
+ VOP_UNLOCK(tdvp, 0);
+ if (tvp)
+ VOP_UNLOCK(tvp, 0);
+ error = VFS_VGET(mp, ino, LK_SHARED, &nvp);
+ if (error == 0)
+ vput(nvp);
+ atomic_add_int(&rename_restarts, 1);
+ goto relock;
+ }
+ if (error)
+ goto unlockout;
if ((tcnp->cn_flags & SAVESTART) == 0)
panic("ufs_rename: lost to startdir");
- VREF(tdvp);
- error = relookup(tdvp, &tvp, tcnp);
- if (error)
- goto out;
- vrele(tdvp);
- dp = VTOI(tdvp);
- xp = NULL;
- if (tvp)
- xp = VTOI(tvp);
}
+ if (fip->i_effnlink == 0 || fdp->i_effnlink == 0 ||
+ tdp->i_effnlink == 0)
+ panic("Bad effnlink fip %p, fdp %p, tdp %p", fip, fdp, tdp);
+
+ /*
+ * 1) Bump link count while we're moving stuff
+ * around. If we crash somewhere before
+ * completing our work, the link count
+ * may be wrong, but correctable.
+ */
+ fip->i_effnlink++;
+ fip->i_nlink++;
+ DIP_SET(fip, i_nlink, fip->i_nlink);
+ fip->i_flag |= IN_CHANGE;
+ if (DOINGSOFTDEP(fvp))
+ softdep_setup_link(tdp, fip);
+ error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) | DOINGASYNC(fvp)));
+ if (error)
+ goto bad;
+
/*
* 2) If target doesn't exist, link the target
* to the source and unlink the source.
@@ -1250,52 +1352,37 @@ abortit:
* entry to reference the source inode and
* expunge the original entry's existence.
*/
- if (xp == NULL) {
- if (dp->i_dev != ip->i_dev)
+ if (tip == NULL) {
+ if (tdp->i_dev != fip->i_dev)
panic("ufs_rename: EXDEV");
- /*
- * Account for ".." in new directory.
- * When source and destination have the same
- * parent we don't fool with the link count.
- */
if (doingdirectory && newparent) {
- if ((nlink_t)dp->i_nlink >= LINK_MAX) {
+ /*
+ * Account for ".." in new directory.
+ * When source and destination have the same
+ * parent we don't adjust the link count. The
+ * actual link modification is completed when
+ * .. is rewritten below.
+ */
+ if ((nlink_t)tdp->i_nlink >= LINK_MAX) {
error = EMLINK;
goto bad;
}
- dp->i_effnlink++;
- dp->i_nlink++;
- DIP_SET(dp, i_nlink, dp->i_nlink);
- dp->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(tdvp))
- softdep_change_linkcnt(dp);
- error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) |
- DOINGASYNC(tdvp)));
- if (error)
- goto bad;
}
- ufs_makedirentry(ip, tcnp, &newdir);
- error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL);
- if (error) {
- if (doingdirectory && newparent) {
- dp->i_effnlink--;
- dp->i_nlink--;
- DIP_SET(dp, i_nlink, dp->i_nlink);
- dp->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(tdvp))
- softdep_change_linkcnt(dp);
- (void)UFS_UPDATE(tdvp, 1);
- }
+ ufs_makedirentry(fip, tcnp, &newdir);
+ error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL, 1);
+ if (error)
goto bad;
- }
- vput(tdvp);
+ /* Setup tdvp for directory compaction if needed. */
+ if (tdp->i_count && tdp->i_endoff &&
+ tdp->i_endoff < tdp->i_size)
+ endoff = tdp->i_endoff;
} else {
- if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
+ if (tip->i_dev != tdp->i_dev || tip->i_dev != fip->i_dev)
panic("ufs_rename: EXDEV");
/*
* Short circuit rename(foo, foo).
*/
- if (xp->i_number == ip->i_number)
+ if (tip->i_number == fip->i_number)
panic("ufs_rename: same file");
/*
* If the parent directory is "sticky", then the caller
@@ -1303,7 +1390,7 @@ abortit:
* destination of the rename. This implements append-only
* directories.
*/
- if ((dp->i_mode & S_ISTXT) &&
+ if ((tdp->i_mode & S_ISTXT) &&
VOP_ACCESS(tdvp, VADMIN, tcnp->cn_cred, td) &&
VOP_ACCESS(tvp, VADMIN, tcnp->cn_cred, td)) {
error = EPERM;
@@ -1314,9 +1401,9 @@ abortit:
* to it. Also, ensure source and target are compatible
* (both directories, or both not directories).
*/
- if ((xp->i_mode&IFMT) == IFDIR) {
- if ((xp->i_effnlink > 2) ||
- !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
+ if ((tip->i_mode & IFMT) == IFDIR) {
+ if ((tip->i_effnlink > 2) ||
+ !ufs_dirempty(tip, tdp->i_number, tcnp->cn_cred)) {
error = ENOTEMPTY;
goto bad;
}
@@ -1329,20 +1416,30 @@ abortit:
error = EISDIR;
goto bad;
}
- error = ufs_dirrewrite(dp, xp, ip->i_number,
- IFTODT(ip->i_mode),
- (doingdirectory && newparent) ? newparent : doingdirectory);
- if (error)
- goto bad;
if (doingdirectory) {
if (!newparent) {
- dp->i_effnlink--;
+ tdp->i_effnlink--;
if (DOINGSOFTDEP(tdvp))
- softdep_change_linkcnt(dp);
+ softdep_change_linkcnt(tdp);
}
- xp->i_effnlink--;
+ tip->i_effnlink--;
if (DOINGSOFTDEP(tvp))
- softdep_change_linkcnt(xp);
+ softdep_change_linkcnt(tip);
+ }
+ error = ufs_dirrewrite(tdp, tip, fip->i_number,
+ IFTODT(fip->i_mode),
+ (doingdirectory && newparent) ? newparent : doingdirectory);
+ if (error) {
+ if (doingdirectory) {
+ if (!newparent) {
+ tdp->i_effnlink++;
+ if (DOINGSOFTDEP(tdvp))
+ softdep_change_linkcnt(tdp);
+ }
+ tip->i_effnlink++;
+ if (DOINGSOFTDEP(tvp))
+ softdep_change_linkcnt(tip);
+ }
}
if (doingdirectory && !DOINGSOFTDEP(tvp)) {
/*
@@ -1357,115 +1454,107 @@ abortit:
* them now.
*/
if (!newparent) {
- dp->i_nlink--;
- DIP_SET(dp, i_nlink, dp->i_nlink);
- dp->i_flag |= IN_CHANGE;
+ tdp->i_nlink--;
+ DIP_SET(tdp, i_nlink, tdp->i_nlink);
+ tdp->i_flag |= IN_CHANGE;
}
- xp->i_nlink--;
- DIP_SET(xp, i_nlink, xp->i_nlink);
- xp->i_flag |= IN_CHANGE;
+ tip->i_nlink--;
+ DIP_SET(tip, i_nlink, tip->i_nlink);
+ tip->i_flag |= IN_CHANGE;
ioflag = IO_NORMAL;
if (!DOINGASYNC(tvp))
ioflag |= IO_SYNC;
+ /* Don't go to bad here as the new link exists. */
if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag,
tcnp->cn_cred, tcnp->cn_thread)) != 0)
- goto bad;
+ goto unlockout;
}
- vput(tdvp);
- vput(tvp);
- xp = NULL;
}
/*
- * 3) Unlink the source.
+ * 3) Unlink the source. We have to resolve the path again to
+ * fixup the directory offset and count for ufs_dirremove.
*/
- fcnp->cn_flags &= ~MODMASK;
- fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
- if ((fcnp->cn_flags & SAVESTART) == 0)
- panic("ufs_rename: lost from startdir");
- VREF(fdvp);
- error = relookup(fdvp, &fvp, fcnp);
- if (error == 0)
- vrele(fdvp);
- if (fvp != NULL) {
- xp = VTOI(fvp);
- dp = VTOI(fdvp);
- } else {
- /*
- * From name has disappeared. IN_RENAME is not sufficient
- * to protect against directory races due to timing windows,
- * so we have to remove the panic. XXX the only real way
- * to solve this issue is at a much higher level. By the
- * time we hit ufs_rename() it's too late.
- */
-#if 0
- if (doingdirectory)
- panic("ufs_rename: lost dir entry");
-#endif
- vrele(ap->a_fvp);
- return (0);
+ if (fdvp == tdvp) {
+ error = ufs_lookup_ino(fdvp, NULL, fcnp, &ino);
+ if (error)
+ panic("ufs_rename: from entry went away!");
+ if (ino != fip->i_number)
+ panic("ufs_rename: ino mismatch %d != %d\n", ino,
+ fip->i_number);
}
/*
- * Ensure that the directory entry still exists and has not
- * changed while the new name has been entered. If the source is
- * a file then the entry may have been unlinked or renamed. In
- * either case there is no further work to be done. If the source
- * is a directory then it cannot have been rmdir'ed; the IN_RENAME
- * flag ensures that it cannot be moved by another rename or removed
- * by a rmdir.
+ * If the source is a directory with a
+ * new parent, the link count of the old
+ * parent directory must be decremented
+ * and ".." set to point to the new parent.
*/
- if (xp != ip) {
- /*
- * From name resolves to a different inode. IN_RENAME is
- * not sufficient protection against timing window races
- * so we can't panic here. XXX the only real way
- * to solve this issue is at a much higher level. By the
- * time we hit ufs_rename() it's too late.
- */
-#if 0
- if (doingdirectory)
- panic("ufs_rename: lost dir entry");
-#endif
- } else {
+ if (doingdirectory && newparent) {
/*
- * If the source is a directory with a
- * new parent, the link count of the old
- * parent directory must be decremented
- * and ".." set to point to the new parent.
+ * If tip exists we simply use its link, otherwise we must
+ * add a new one.
*/
- if (doingdirectory && newparent) {
- xp->i_offset = mastertemplate.dot_reclen;
- ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0);
- cache_purge(fdvp);
+ if (tip == NULL) {
+ tdp->i_effnlink++;
+ tdp->i_nlink++;
+ DIP_SET(tdp, i_nlink, tdp->i_nlink);
+ tdp->i_flag |= IN_CHANGE;
+ if (DOINGSOFTDEP(tdvp))
+ softdep_setup_dotdot_link(tdp, fip);
+ error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) |
+ DOINGASYNC(tdvp)));
+ /* Don't go to bad here as the new link exists. */
+ if (error)
+ goto unlockout;
}
- error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
- xp->i_flag &= ~IN_RENAME;
- }
- if (dp)
- vput(fdvp);
- if (xp)
- vput(fvp);
- vrele(ap->a_fvp);
+ fip->i_offset = mastertemplate.dot_reclen;
+ ufs_dirrewrite(fip, fdp, newparent, DT_DIR, 0);
+ cache_purge(fdvp);
+ }
+ error = ufs_dirremove(fdvp, fip, fcnp->cn_flags, 0);
+
+unlockout:
+ vput(fdvp);
+ vput(fvp);
+ if (tvp)
+ vput(tvp);
+ /*
+ * If compaction or fsync was requested do it now that other locks
+ * are no longer needed.
+ */
+ if (error == 0 && endoff != 0) {
+#ifdef UFS_DIRHASH
+ if (tdp->i_dirhash != NULL)
+ ufsdirhash_dirtrunc(tdp, endoff);
+#endif
+ UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC, tcnp->cn_cred,
+ td);
+ }
+ if (error == 0 && tdp->i_flag & IN_NEEDSYNC)
+ error = VOP_FSYNC(tdvp, MNT_WAIT, td);
+ vput(tdvp);
+ if (mp)
+ vfs_unbusy(mp);
return (error);
bad:
- if (xp)
- vput(ITOV(xp));
- vput(ITOV(dp));
-out:
- if (doingdirectory)
- ip->i_flag &= ~IN_RENAME;
- if (vn_lock(fvp, LK_EXCLUSIVE) == 0) {
- ip->i_effnlink--;
- ip->i_nlink--;
- DIP_SET(ip, i_nlink, ip->i_nlink);
- ip->i_flag |= IN_CHANGE;
- ip->i_flag &= ~IN_RENAME;
- if (DOINGSOFTDEP(fvp))
- softdep_change_linkcnt(ip);
- vput(fvp);
- } else
- vrele(fvp);
+ fip->i_effnlink--;
+ fip->i_nlink--;
+ DIP_SET(fip, i_nlink, fip->i_nlink);
+ fip->i_flag |= IN_CHANGE;
+ if (DOINGSOFTDEP(fvp))
+ softdep_revert_link(tdp, fip);
+ goto unlockout;
+
+releout:
+ vrele(fdvp);
+ vrele(fvp);
+ vrele(tdvp);
+ if (tvp)
+ vrele(tvp);
+ if (mp)
+ vfs_unbusy(mp);
+
return (error);
}
@@ -1767,8 +1856,7 @@ ufs_mkdir(ap)
ip->i_effnlink = 2;
ip->i_nlink = 2;
DIP_SET(ip, i_nlink, 2);
- if (DOINGSOFTDEP(tvp))
- softdep_change_linkcnt(ip);
+
if (cnp->cn_flags & ISWHITEOUT) {
ip->i_flags |= UF_OPAQUE;
DIP_SET(ip, i_flags, ip->i_flags);
@@ -1784,8 +1872,8 @@ ufs_mkdir(ap)
DIP_SET(dp, i_nlink, dp->i_nlink);
dp->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(dvp))
- softdep_change_linkcnt(dp);
- error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp)));
+ softdep_setup_mkdir(dp, ip);
+ error = UFS_UPDATE(dvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp)));
if (error)
goto bad;
#ifdef MAC
@@ -1863,7 +1951,7 @@ ufs_mkdir(ap)
else if (!DOINGSOFTDEP(dvp) && ((error = bwrite(bp))))
goto bad;
ufs_makedirentry(ip, cnp, &newdir);
- error = ufs_direnter(dvp, tvp, &newdir, cnp, bp);
+ error = ufs_direnter(dvp, tvp, &newdir, cnp, bp, 0);
bad:
if (error == 0) {
@@ -1873,8 +1961,6 @@ bad:
dp->i_nlink--;
DIP_SET(dp, i_nlink, dp->i_nlink);
dp->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(dvp))
- softdep_change_linkcnt(dp);
/*
* No need to do an explicit VOP_TRUNCATE here, vrele will
* do this for us because we set the link count to 0.
@@ -1884,7 +1970,8 @@ bad:
DIP_SET(ip, i_nlink, 0);
ip->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(tvp))
- softdep_change_linkcnt(ip);
+ softdep_revert_mkdir(dp, ip);
+
vput(tvp);
}
out:
@@ -1920,10 +2007,13 @@ ufs_rmdir(ap)
* tries to remove a locally mounted on directory).
*/
error = 0;
- if ((ip->i_flag & IN_RENAME) || ip->i_effnlink < 2) {
+ if (ip->i_effnlink < 2) {
error = EINVAL;
goto out;
}
+ if (dp->i_effnlink < 3)
+ panic("ufs_dirrem: Bad link count %d on parent",
+ dp->i_effnlink);
if (!ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
error = ENOTEMPTY;
goto out;
@@ -1947,18 +2037,14 @@ ufs_rmdir(ap)
*/
dp->i_effnlink--;
ip->i_effnlink--;
- if (DOINGSOFTDEP(vp)) {
- softdep_change_linkcnt(dp);
- softdep_change_linkcnt(ip);
- }
+ if (DOINGSOFTDEP(vp))
+ softdep_setup_rmdir(dp, ip);
error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1);
if (error) {
dp->i_effnlink++;
ip->i_effnlink++;
- if (DOINGSOFTDEP(vp)) {
- softdep_change_linkcnt(dp);
- softdep_change_linkcnt(ip);
- }
+ if (DOINGSOFTDEP(vp))
+ softdep_revert_rmdir(dp, ip);
goto out;
}
cache_purge(dvp);
@@ -2464,6 +2550,9 @@ ufs_makeinode(mode, dvp, vpp, cnp)
if ((mode & IFMT) == 0)
mode |= IFREG;
+ if (VTOI(dvp)->i_effnlink < 2)
+ panic("ufs_makeinode: Bad link count %d on parent",
+ VTOI(dvp)->i_effnlink);
error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
if (error)
return (error);
@@ -2539,7 +2628,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
ip->i_nlink = 1;
DIP_SET(ip, i_nlink, 1);
if (DOINGSOFTDEP(tvp))
- softdep_change_linkcnt(ip);
+ softdep_setup_create(VTOI(dvp), ip);
if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID, 0)) {
ip->i_mode &= ~ISGID;
@@ -2579,7 +2668,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
}
#endif /* !UFS_ACL */
ufs_makedirentry(ip, cnp, &newdir);
- error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL);
+ error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL, 0);
if (error)
goto bad;
*vpp = tvp;
@@ -2595,7 +2684,7 @@ bad:
DIP_SET(ip, i_nlink, 0);
ip->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(tvp))
- softdep_change_linkcnt(ip);
+ softdep_revert_create(VTOI(dvp), ip);
vput(tvp);
return (error);
}
diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h
index 83f9af0..d566917 100644
--- a/sys/ufs/ufs/ufsmount.h
+++ b/sys/ufs/ufs/ufsmount.h
@@ -57,6 +57,10 @@ struct ucred;
struct uio;
struct vnode;
struct ufs_extattr_per_mount;
+struct jblocks;
+struct inodedep;
+
+TAILQ_HEAD(inodedeplst, inodedep);
/* This structure describes the UFS specific mount structure data. */
struct ufsmount {
@@ -75,6 +79,11 @@ struct ufsmount {
long um_numindirdeps; /* outstanding indirdeps */
struct workhead softdep_workitem_pending; /* softdep work queue */
struct worklist *softdep_worklist_tail; /* Tail pointer for above */
+ struct workhead softdep_journal_pending; /* journal work queue */
+ struct worklist *softdep_journal_tail; /* Tail pointer for above */
+ struct jblocks *softdep_jblocks; /* Journal block information */
+ struct inodedeplst softdep_unlinked; /* Unlinked inodes */
+ int softdep_on_journal; /* Items on the journal list */
int softdep_on_worklist; /* Items on the worklist */
int softdep_on_worklist_inprogress; /* Busy items on worklist */
int softdep_deps; /* Total dependency count */
diff --git a/sys/vm/memguard.c b/sys/vm/memguard.c
index 861ba3d..a3792d9 100644
--- a/sys/vm/memguard.c
+++ b/sys/vm/memguard.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2005,
* Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved.
*
diff --git a/sys/vm/memguard.h b/sys/vm/memguard.h
index 34d79cf..cabcc0a 100644
--- a/sys/vm/memguard.h
+++ b/sys/vm/memguard.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2005,
* Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved.
*
diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h
index 02fda07..e4d8e81 100644
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -98,6 +98,9 @@ extern vm_offset_t kernel_vm_end;
void pmap_align_superpage(vm_object_t, vm_ooffset_t, vm_offset_t *,
vm_size_t);
+#if defined(__mips__)
+void pmap_align_tlb(vm_offset_t *);
+#endif
void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t);
void pmap_clear_modify(vm_page_t m);
void pmap_clear_reference(vm_page_t m);
@@ -116,6 +119,7 @@ void pmap_growkernel(vm_offset_t);
void pmap_init(void);
boolean_t pmap_is_modified(vm_page_t m);
boolean_t pmap_is_prefaultable(pmap_t pmap, vm_offset_t va);
+boolean_t pmap_is_referenced(vm_page_t m);
boolean_t pmap_ts_referenced(vm_page_t m);
vm_offset_t pmap_map(vm_offset_t *, vm_paddr_t, vm_paddr_t, int);
void pmap_object_init_pt(pmap_t pmap, vm_offset_t addr,
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index ef64b31..f1d89d5 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -1101,8 +1101,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage)
* happen. Note that blk, iblk & jblk can be SWAPBLK_NONE, but the
* loops are set up such that the case(s) are handled implicitly.
*
- * The swp_*() calls must be made at splvm(). vm_page_free() does
- * not need to be, but it will go a little faster if it is.
+ * The swp_*() calls must be made with the object locked.
*/
blk = swp_pager_meta_ctl(mreq->object, mreq->pindex, 0);
@@ -1212,9 +1211,6 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage)
VM_OBJECT_LOCK(object);
while ((mreq->oflags & VPO_SWAPINPROG) != 0) {
mreq->oflags |= VPO_WANTED;
- vm_page_lock_queues();
- vm_page_flag_set(mreq, PG_REFERENCED);
- vm_page_unlock_queues();
PCPU_INC(cnt.v_intrans);
if (msleep(mreq, VM_OBJECT_MTX(object), PSWP, "swread", hz*20)) {
printf(
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index 1aaf84f..27396ea 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -160,6 +160,15 @@ struct uma_hash {
};
/*
+ * align field or structure to cache line
+ */
+#if defined(__amd64__)
+#define UMA_ALIGN __aligned(CACHE_LINE_SIZE)
+#else
+#define UMA_ALIGN
+#endif
+
+/*
* Structures for per cpu queues.
*/
@@ -177,7 +186,7 @@ struct uma_cache {
uma_bucket_t uc_allocbucket; /* Bucket to allocate from */
u_int64_t uc_allocs; /* Count of allocations */
u_int64_t uc_frees; /* Count of frees */
-};
+} UMA_ALIGN;
typedef struct uma_cache * uma_cache_t;
@@ -312,11 +321,12 @@ struct uma_zone {
uma_init uz_init; /* Initializer for each item */
uma_fini uz_fini; /* Discards memory */
- u_int64_t uz_allocs; /* Total number of allocations */
- u_int64_t uz_frees; /* Total number of frees */
- u_int64_t uz_fails; /* Total number of alloc failures */
u_int32_t uz_flags; /* Flags inherited from kegs */
u_int32_t uz_size; /* Size inherited from kegs */
+
+ u_int64_t uz_allocs UMA_ALIGN; /* Total number of allocations */
+ u_int64_t uz_frees; /* Total number of frees */
+ u_int64_t uz_fails; /* Total number of alloc failures */
uint16_t uz_fills; /* Outstanding bucket fills */
uint16_t uz_count; /* Highest value ub_ptr can have */
@@ -324,7 +334,7 @@ struct uma_zone {
* This HAS to be the last item because we adjust the zone size
* based on NCPU and then allocate the space for the zones.
*/
- struct uma_cache uz_cpu[1]; /* Per cpu caches */
+ struct uma_cache uz_cpu[1]; /* Per cpu caches */
};
/*
@@ -341,6 +351,8 @@ struct uma_zone {
#define UMA_ZFLAG_INHERIT (UMA_ZFLAG_INTERNAL | UMA_ZFLAG_CACHEONLY | \
UMA_ZFLAG_BUCKET)
+#undef UMA_ALIGN
+
#ifdef _KERNEL
/* Internal prototypes */
static __inline uma_slab_t hash_sfind(struct uma_hash *hash, u_int8_t *data);
diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c
index 7358cb0..78d7e28 100644
--- a/sys/vm/vm_contig.c
+++ b/sys/vm/vm_contig.c
@@ -87,6 +87,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_phys.h>
#include <vm/vm_extern.h>
+static void vm_contig_grow_cache(int tries);
+
static int
vm_contig_launder_page(vm_page_t m, vm_page_t *next)
{
@@ -186,6 +188,99 @@ vm_page_release_contig(vm_page_t m, vm_pindex_t count)
}
/*
+ * Increase the number of cached pages.
+ */
+static void
+vm_contig_grow_cache(int tries)
+{
+ int actl, actmax, inactl, inactmax;
+
+ vm_page_lock_queues();
+ inactl = 0;
+ inactmax = tries < 1 ? 0 : cnt.v_inactive_count;
+ actl = 0;
+ actmax = tries < 2 ? 0 : cnt.v_active_count;
+again:
+ if (inactl < inactmax && vm_contig_launder(PQ_INACTIVE)) {
+ inactl++;
+ goto again;
+ }
+ if (actl < actmax && vm_contig_launder(PQ_ACTIVE)) {
+ actl++;
+ goto again;
+ }
+ vm_page_unlock_queues();
+}
+
+/*
+ * Allocates a region from the kernel address map and pages within the
+ * specified physical address range to the kernel object, creates a wired
+ * mapping from the region to these pages, and returns the region's starting
+ * virtual address. The allocated pages are not necessarily physically
+ * contiguous. If M_ZERO is specified through the given flags, then the pages
+ * are zeroed before they are mapped.
+ */
+vm_offset_t
+kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
+ vm_paddr_t high, vm_memattr_t memattr)
+{
+ vm_object_t object = kernel_object;
+ vm_offset_t addr, i, offset;
+ vm_page_t m;
+ int tries;
+
+ size = round_page(size);
+ vm_map_lock(map);
+ if (vm_map_findspace(map, vm_map_min(map), size, &addr)) {
+ vm_map_unlock(map);
+ return (0);
+ }
+ offset = addr - VM_MIN_KERNEL_ADDRESS;
+ vm_object_reference(object);
+ vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL,
+ VM_PROT_ALL, 0);
+ VM_OBJECT_LOCK(object);
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ tries = 0;
+retry:
+ m = vm_phys_alloc_contig(1, low, high, PAGE_SIZE, 0);
+ if (m == NULL) {
+ if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
+ VM_OBJECT_UNLOCK(object);
+ vm_map_unlock(map);
+ vm_contig_grow_cache(tries);
+ vm_map_lock(map);
+ VM_OBJECT_LOCK(object);
+ goto retry;
+ }
+ while (i != 0) {
+ i -= PAGE_SIZE;
+ m = vm_page_lookup(object, OFF_TO_IDX(offset +
+ i));
+ vm_page_lock_queues();
+ vm_page_free(m);
+ vm_page_unlock_queues();
+ }
+ VM_OBJECT_UNLOCK(object);
+ vm_map_delete(map, addr, addr + size);
+ vm_map_unlock(map);
+ return (0);
+ }
+ if (memattr != VM_MEMATTR_DEFAULT)
+ pmap_page_set_memattr(m, memattr);
+ vm_page_insert(m, object, OFF_TO_IDX(offset + i));
+ if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
+ pmap_zero_page(m);
+ m->valid = VM_PAGE_BITS_ALL;
+ }
+ VM_OBJECT_UNLOCK(object);
+ vm_map_unlock(map);
+ vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM |
+ VM_MAP_WIRE_NOHOLES);
+ return (addr);
+}
+
+/*
* Allocates a region from the kernel address map, inserts the
* given physically contiguous pages into the kernel object,
* creates a wired mapping from the region to the pages, and
@@ -253,7 +348,7 @@ kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
vm_offset_t ret;
vm_page_t pages;
unsigned long npgs;
- int actl, actmax, inactl, inactmax, tries;
+ int tries;
size = round_page(size);
npgs = size >> PAGE_SHIFT;
@@ -262,23 +357,7 @@ retry:
pages = vm_phys_alloc_contig(npgs, low, high, alignment, boundary);
if (pages == NULL) {
if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
- vm_page_lock_queues();
- inactl = 0;
- inactmax = tries < 1 ? 0 : cnt.v_inactive_count;
- actl = 0;
- actmax = tries < 2 ? 0 : cnt.v_active_count;
-again:
- if (inactl < inactmax &&
- vm_contig_launder(PQ_INACTIVE)) {
- inactl++;
- goto again;
- }
- if (actl < actmax &&
- vm_contig_launder(PQ_ACTIVE)) {
- actl++;
- goto again;
- }
- vm_page_unlock_queues();
+ vm_contig_grow_cache(tries);
tries++;
goto retry;
}
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index ad6087e..ca6d49c 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -41,15 +41,18 @@ struct vnode;
int kernacc(void *, int, int);
vm_offset_t kmem_alloc(vm_map_t, vm_size_t);
+vm_offset_t kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags,
+ vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr);
vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
unsigned long boundary, vm_memattr_t memattr);
vm_offset_t kmem_alloc_nofault(vm_map_t, vm_size_t);
+vm_offset_t kmem_alloc_nofault_space(vm_map_t, vm_size_t, int);
vm_offset_t kmem_alloc_wait(vm_map_t, vm_size_t);
void kmem_free(vm_map_t, vm_offset_t, vm_size_t);
void kmem_free_wakeup(vm_map_t, vm_offset_t, vm_size_t);
void kmem_init(vm_offset_t, vm_offset_t);
-vm_offset_t kmem_malloc(vm_map_t, vm_size_t, boolean_t);
+vm_offset_t kmem_malloc(vm_map_t map, vm_size_t size, int flags);
vm_map_t kmem_suballoc(vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t,
boolean_t);
void swapout_procs(int);
@@ -82,7 +85,5 @@ struct sf_buf *vm_imgact_map_page(vm_object_t object, vm_ooffset_t offset);
void vm_imgact_unmap_page(struct sf_buf *sf);
void vm_thread_dispose(struct thread *td);
int vm_thread_new(struct thread *td, int pages);
-void vm_thread_swapin(struct thread *td);
-void vm_thread_swapout(struct thread *td);
#endif /* _KERNEL */
#endif /* !_VM_EXTERN_H_ */
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 0a5a412..f409856 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -216,7 +216,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
vm_object_t next_object;
vm_page_t marray[VM_FAULT_READ];
int hardfault;
- int faultcount, ahead, behind;
+ int faultcount, ahead, behind, alloc_req;
struct faultstate fs;
struct vnode *vp;
int locked, error;
@@ -386,9 +386,14 @@ RetryFault:;
/*
* Allocate a new page for this object/offset pair.
+ *
+ * Unlocked read of the p_flag is harmless. At
+ * worst, the P_KILLED might be not observed
+ * there, and allocation can fail, causing
+ * restart and new reading of the p_flag.
*/
fs.m = NULL;
- if (!vm_page_count_severe()) {
+ if (!vm_page_count_severe() || P_KILLED(curproc)) {
#if VM_NRESERVLEVEL > 0
if ((fs.object->flags & OBJ_COLORED) == 0) {
fs.object->flags |= OBJ_COLORED;
@@ -396,10 +401,13 @@ RetryFault:;
fs.pindex;
}
#endif
+ alloc_req = P_KILLED(curproc) ?
+ VM_ALLOC_SYSTEM : VM_ALLOC_NORMAL;
+ if (fs.object->type != OBJT_VNODE &&
+ fs.object->backing_object == NULL)
+ alloc_req |= VM_ALLOC_ZERO;
fs.m = vm_page_alloc(fs.object, fs.pindex,
- (fs.object->type == OBJT_VNODE ||
- fs.object->backing_object != NULL) ?
- VM_ALLOC_NORMAL : VM_ALLOC_ZERO);
+ alloc_req);
}
if (fs.m == NULL) {
unlock_and_deallocate(&fs);
@@ -424,7 +432,8 @@ readrest:
int reqpage = 0;
u_char behavior = vm_map_entry_behavior(fs.entry);
- if (behavior == MAP_ENTRY_BEHAV_RANDOM) {
+ if (behavior == MAP_ENTRY_BEHAV_RANDOM ||
+ P_KILLED(curproc)) {
ahead = 0;
behind = 0;
} else {
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 8882565..dbd5065d8 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -99,12 +99,6 @@ extern int maxslp;
/*
* System initialization
*
- * Note: proc0 from proc.h
- */
-static void vm_init_limits(void *);
-SYSINIT(vm_limits, SI_SUB_VM_CONF, SI_ORDER_FIRST, vm_init_limits, &proc0);
-
-/*
* THIS MUST BE THE LAST INITIALIZATION ITEM!!!
*
* Note: run scheduling should be divorced from the vm system.
@@ -115,6 +109,8 @@ SYSINIT(scheduler, SI_SUB_RUN_SCHEDULER, SI_ORDER_ANY, scheduler, NULL);
#ifndef NO_SWAPPING
static int swapout(struct proc *);
static void swapclear(struct proc *);
+static void vm_thread_swapin(struct thread *td);
+static void vm_thread_swapout(struct thread *td);
#endif
/*
@@ -377,8 +373,17 @@ vm_thread_new(struct thread *td, int pages)
/*
* Get a kernel virtual address for this thread's kstack.
*/
+#if defined(__mips__)
+ /*
+ * We need to align the kstack's mapped address to fit within
+ * a single TLB entry.
+ */
+ ks = kmem_alloc_nofault_space(kernel_map,
+ (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE, VMFS_TLB_ALIGNED_SPACE);
+#else
ks = kmem_alloc_nofault(kernel_map,
(pages + KSTACK_GUARD_PAGES) * PAGE_SIZE);
+#endif
if (ks == 0) {
printf("vm_thread_new: kstack allocation failed\n");
vm_object_deallocate(ksobj);
@@ -498,10 +503,11 @@ kstack_cache_init(void *nulll)
MTX_SYSINIT(kstack_cache, &kstack_cache_mtx, "kstkch", MTX_DEF);
SYSINIT(vm_kstacks, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, kstack_cache_init, NULL);
+#ifndef NO_SWAPPING
/*
* Allow a thread's kernel stack to be paged out.
*/
-void
+static void
vm_thread_swapout(struct thread *td)
{
vm_object_t ksobj;
@@ -517,8 +523,8 @@ vm_thread_swapout(struct thread *td)
m = vm_page_lookup(ksobj, i);
if (m == NULL)
panic("vm_thread_swapout: kstack already missing?");
- vm_page_lock_queues();
vm_page_dirty(m);
+ vm_page_lock_queues();
vm_page_unwire(m, 0);
vm_page_unlock_queues();
}
@@ -528,7 +534,7 @@ vm_thread_swapout(struct thread *td)
/*
* Bring the kernel stack for a specified thread back in.
*/
-void
+static void
vm_thread_swapin(struct thread *td)
{
vm_object_t ksobj;
@@ -539,7 +545,8 @@ vm_thread_swapin(struct thread *td)
ksobj = td->td_kstack_obj;
VM_OBJECT_LOCK(ksobj);
for (i = 0; i < pages; i++) {
- m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+ m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY |
+ VM_ALLOC_WIRED);
if (m->valid != VM_PAGE_BITS_ALL) {
rv = vm_pager_get_pages(ksobj, &m, 1, 0);
if (rv != VM_PAGER_OK)
@@ -547,15 +554,13 @@ vm_thread_swapin(struct thread *td)
m = vm_page_lookup(ksobj, i);
}
ma[i] = m;
- vm_page_lock_queues();
- vm_page_wire(m);
- vm_page_unlock_queues();
vm_page_wakeup(m);
}
VM_OBJECT_UNLOCK(ksobj);
pmap_qenter(td->td_kstack, ma, pages);
cpu_thread_swapin(td);
}
+#endif /* !NO_SWAPPING */
/*
* Implement fork's actions on an address space.
@@ -629,38 +634,6 @@ vm_waitproc(p)
vmspace_exitfree(p); /* and clean-out the vmspace */
}
-/*
- * Set default limits for VM system.
- * Called for proc 0, and then inherited by all others.
- *
- * XXX should probably act directly on proc0.
- */
-static void
-vm_init_limits(udata)
- void *udata;
-{
- struct proc *p = udata;
- struct plimit *limp;
- int rss_limit;
-
- /*
- * Set up the initial limits on process VM. Set the maximum resident
- * set size to be half of (reasonably) available memory. Since this
- * is a soft limit, it comes into effect only when the system is out
- * of memory - half of main memory helps to favor smaller processes,
- * and reduces thrashing of the object cache.
- */
- limp = p->p_limit;
- limp->pl_rlimit[RLIMIT_STACK].rlim_cur = dflssiz;
- limp->pl_rlimit[RLIMIT_STACK].rlim_max = maxssiz;
- limp->pl_rlimit[RLIMIT_DATA].rlim_cur = dfldsiz;
- limp->pl_rlimit[RLIMIT_DATA].rlim_max = maxdsiz;
- /* limit the limit to no less than 2MB */
- rss_limit = max(cnt.v_free_count, 512);
- limp->pl_rlimit[RLIMIT_RSS].rlim_cur = ptoa(rss_limit);
- limp->pl_rlimit[RLIMIT_RSS].rlim_max = RLIM_INFINITY;
-}
-
void
faultin(p)
struct proc *p;
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 9006572..739d289 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -119,6 +119,35 @@ kmem_alloc_nofault(map, size)
}
/*
+ * kmem_alloc_nofault_space:
+ *
+ * Allocate a virtual address range with no underlying object and
+ * no initial mapping to physical memory within the specified
+ * address space. Any mapping from this range to physical memory
+ * must be explicitly created prior to its use, typically with
+ * pmap_qenter(). Any attempt to create a mapping on demand
+ * through vm_fault() will result in a panic.
+ */
+vm_offset_t
+kmem_alloc_nofault_space(map, size, find_space)
+ vm_map_t map;
+ vm_size_t size;
+ int find_space;
+{
+ vm_offset_t addr;
+ int result;
+
+ size = round_page(size);
+ addr = vm_map_min(map);
+ result = vm_map_find(map, NULL, 0, &addr, size, find_space,
+ VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT);
+ if (result != KERN_SUCCESS) {
+ return (0);
+ }
+ return (addr);
+}
+
+/*
* Allocate wired-down memory in the kernel's address map
* or a submap.
*/
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 3b17a30..1d22fa6 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -126,7 +126,8 @@ static int vmspace_zinit(void *mem, int size, int flags);
static void vmspace_zfini(void *mem, int size);
static int vm_map_zinit(void *mem, int ize, int flags);
static void vm_map_zfini(void *mem, int size);
-static void _vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max);
+static void _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min,
+ vm_offset_t max);
static void vm_map_entry_dispose(vm_map_t map, vm_map_entry_t entry);
#ifdef INVARIANTS
static void vm_map_zdtor(void *mem, int size, void *arg);
@@ -281,8 +282,7 @@ vmspace_alloc(min, max)
return (NULL);
}
CTR1(KTR_VM, "vmspace_alloc: %p", vm);
- _vm_map_init(&vm->vm_map, min, max);
- vm->vm_map.pmap = vmspace_pmap(vm); /* XXX */
+ _vm_map_init(&vm->vm_map, vmspace_pmap(vm), min, max);
vm->vm_refcnt = 1;
vm->vm_shm = NULL;
vm->vm_swrss = 0;
@@ -313,6 +313,7 @@ vm_init2(void)
static inline void
vmspace_dofree(struct vmspace *vm)
{
+
CTR1(KTR_VM, "vmspace_free: %p", vm);
/*
@@ -329,12 +330,8 @@ vmspace_dofree(struct vmspace *vm)
(void)vm_map_remove(&vm->vm_map, vm->vm_map.min_offset,
vm->vm_map.max_offset);
- /*
- * XXX Comment out the pmap_release call for now. The
- * vmspace_zone is marked as UMA_ZONE_NOFREE, and bugs cause
- * pmap.resident_count to be != 0 on exit sometimes.
- */
-/* pmap_release(vmspace_pmap(vm)); */
+ pmap_release(vmspace_pmap(vm));
+ vm->vm_map.pmap = NULL;
uma_zfree(vmspace_zone, vm);
}
@@ -681,23 +678,22 @@ vm_map_create(pmap_t pmap, vm_offset_t min, vm_offset_t max)
result = uma_zalloc(mapzone, M_WAITOK);
CTR1(KTR_VM, "vm_map_create: %p", result);
- _vm_map_init(result, min, max);
- result->pmap = pmap;
+ _vm_map_init(result, pmap, min, max);
return (result);
}
/*
* Initialize an existing vm_map structure
* such as that in the vmspace structure.
- * The pmap is set elsewhere.
*/
static void
-_vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max)
+_vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max)
{
map->header.next = map->header.prev = &map->header;
map->needs_wakeup = FALSE;
map->system_map = 0;
+ map->pmap = pmap;
map->min_offset = min;
map->max_offset = max;
map->flags = 0;
@@ -707,9 +703,10 @@ _vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max)
}
void
-vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max)
+vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max)
{
- _vm_map_init(map, min, max);
+
+ _vm_map_init(map, pmap, min, max);
mtx_init(&map->system_mtx, "system map", NULL, MTX_DEF | MTX_DUPOK);
sx_init(&map->lock, "user map");
}
@@ -1397,9 +1394,20 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
vm_map_unlock(map);
return (KERN_NO_SPACE);
}
- if (find_space == VMFS_ALIGNED_SPACE)
+ switch (find_space) {
+ case VMFS_ALIGNED_SPACE:
pmap_align_superpage(object, offset, addr,
length);
+ break;
+#ifdef VMFS_TLB_ALIGNED_SPACE
+ case VMFS_TLB_ALIGNED_SPACE:
+ pmap_align_tlb(addr);
+ break;
+#endif
+ default:
+ break;
+ }
+
start = *addr;
}
result = vm_map_insert(map, object, offset, start, start +
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 9630845..d5c5b51 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -326,6 +326,9 @@ long vmspace_wired_count(struct vmspace *vmspace);
#define VMFS_NO_SPACE 0 /* don't find; use the given range */
#define VMFS_ANY_SPACE 1 /* find a range with any alignment */
#define VMFS_ALIGNED_SPACE 2 /* find a superpage-aligned range */
+#if defined(__mips__)
+#define VMFS_TLB_ALIGNED_SPACE 3 /* find a TLB entry aligned range */
+#endif
/*
* vm_map_wire and vm_map_unwire option flags
@@ -346,7 +349,7 @@ int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t,
vm_prot_t, vm_prot_t, int);
int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t *);
int vm_map_inherit (vm_map_t, vm_offset_t, vm_offset_t, vm_inherit_t);
-void vm_map_init (struct vm_map *, vm_offset_t, vm_offset_t);
+void vm_map_init(vm_map_t, pmap_t, vm_offset_t, vm_offset_t);
int vm_map_insert (vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_offset_t, vm_prot_t, vm_prot_t, int);
int vm_map_lookup (vm_map_t *, vm_offset_t, vm_prot_t, vm_map_entry_t *, vm_object_t *,
vm_pindex_t *, vm_prot_t *, boolean_t *);
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 4963a60..88ed3d5 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -233,7 +233,7 @@ mmap(td, uap)
/* Make sure mapping fits into numeric range, etc. */
if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) &&
curproc->p_osrel >= 800104) ||
- ((flags & MAP_ANON) && uap->fd != -1))
+ ((flags & MAP_ANON) && (uap->fd != -1 || pos != 0)))
return (EINVAL);
if (flags & MAP_STACK) {
@@ -300,7 +300,6 @@ mmap(td, uap)
handle = NULL;
handle_type = OBJT_DEFAULT;
maxprot = VM_PROT_ALL;
- pos = 0;
} else {
/*
* Mapping file, get fp for validation and
@@ -872,10 +871,8 @@ RestartScan:
pmap_is_modified(m))
mincoreinfo |= MINCORE_MODIFIED_OTHER;
if ((m->flags & PG_REFERENCED) ||
- pmap_ts_referenced(m)) {
- vm_page_flag_set(m, PG_REFERENCED);
+ pmap_is_referenced(m))
mincoreinfo |= MINCORE_REFERENCED_OTHER;
- }
vm_page_unlock_queues();
}
VM_OBJECT_UNLOCK(current->object.vm_object);
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 399cb10..7e4dbc8 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1205,12 +1205,19 @@ shadowlookup:
goto unlock_tobject;
}
if ((m->oflags & VPO_BUSY) || m->busy) {
- vm_page_flag_set(m, PG_REFERENCED);
+ if (advise == MADV_WILLNEED)
+ /*
+ * Reference the page before unlocking and
+ * sleeping so that the page daemon is less
+ * likely to reclaim it.
+ */
+ vm_page_flag_set(m, PG_REFERENCED);
vm_page_unlock_queues();
if (object != tobject)
VM_OBJECT_UNLOCK(object);
m->oflags |= VPO_WANTED;
- msleep(m, VM_OBJECT_MTX(tobject), PDROP | PVM, "madvpo", 0);
+ msleep(m, VM_OBJECT_MTX(tobject), PDROP | PVM, "madvpo",
+ 0);
VM_OBJECT_LOCK(object);
goto relookup;
}
@@ -1415,7 +1422,6 @@ retry:
* not be changed by this operation.
*/
if ((m->oflags & VPO_BUSY) || m->busy) {
- vm_page_flag_set(m, PG_REFERENCED);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(new_object);
m->oflags |= VPO_WANTED;
@@ -1553,9 +1559,6 @@ vm_object_backing_scan(vm_object_t object, int op)
}
} else if (op & OBSC_COLLAPSE_WAIT) {
if ((p->oflags & VPO_BUSY) || p->busy) {
- vm_page_lock_queues();
- vm_page_flag_set(p, PG_REFERENCED);
- vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
p->oflags |= VPO_WANTED;
msleep(p, VM_OBJECT_MTX(backing_object),
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 665baa9..7c149c9 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1084,6 +1084,7 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
return (NULL);
#if VM_NRESERVLEVEL > 0
} else if (object == NULL || object->type == OBJT_DEVICE ||
+ object->type == OBJT_SG ||
(object->flags & OBJ_COLORED) == 0 ||
(m = vm_reserv_alloc_page(object, pindex)) == NULL) {
#else
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 723b14d..735beee 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -350,7 +350,6 @@ more:
vm_page_test_dirty(p);
if (p->dirty == 0 ||
p->queue != PQ_INACTIVE ||
- p->wire_count != 0 || /* may be held by buf cache */
p->hold_count != 0) { /* may be undergoing I/O */
ib = 0;
break;
@@ -378,7 +377,6 @@ more:
vm_page_test_dirty(p);
if (p->dirty == 0 ||
p->queue != PQ_INACTIVE ||
- p->wire_count != 0 || /* may be held by buf cache */
p->hold_count != 0) { /* may be undergoing I/O */
break;
}
@@ -1124,7 +1122,8 @@ unlock_and_continue:
m->act_count == 0) {
page_shortage--;
if (object->ref_count == 0) {
- pmap_remove_all(m);
+ KASSERT(!pmap_page_is_mapped(m),
+ ("vm_pageout_scan: page %p is mapped", m));
if (m->dirty == 0)
vm_page_cache(m);
else
@@ -1206,10 +1205,10 @@ vm_pageout_oom(int shortage)
if (PROC_TRYLOCK(p) == 0)
continue;
/*
- * If this is a system or protected process, skip it.
+ * If this is a system, protected or killed process, skip it.
*/
if ((p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) ||
- (p->p_pid == 1) ||
+ (p->p_pid == 1) || P_KILLED(p) ||
((p->p_pid < 48) && (swap_pager_avail != 0))) {
PROC_UNLOCK(p);
continue;
diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c
index 6ced537..36dc36e 100644
--- a/sys/x86/isa/clock.c
+++ b/sys/x86/isa/clock.c
@@ -97,6 +97,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq);
int i8254_max_count;
static int i8254_real_max_count;
+static int lapic_allclocks = 1;
+TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
+
struct mtx clock_lock;
static struct intsrc *i8254_intsrc;
static u_int32_t i8254_lastcount;
@@ -183,8 +186,8 @@ clkintr(struct trapframe *frame)
* timers.
*/
int cpu = PCPU_GET(cpuid);
- if (lapic_cyclic_clock_func[cpu] != NULL)
- (*lapic_cyclic_clock_func[cpu])(frame);
+ if (cyclic_clock_func[cpu] != NULL)
+ (*cyclic_clock_func[cpu])(frame);
#endif
if (using_atrtc_timer) {
@@ -526,9 +529,24 @@ startrtclock()
void
cpu_initclocks()
{
+#if defined(__amd64__) || defined(DEV_APIC)
+ enum lapic_clock tlsca;
+#endif
+ int tasc;
+
+ /* Initialize RTC. */
+ atrtc_start();
+ tasc = atrtc_setup_clock();
+ /*
+ * If the atrtc successfully initialized and the users didn't force
+ * otherwise use the LAPIC in order to cater hardclock only, otherwise
+ * take in charge all the clock sources.
+ */
#if defined(__amd64__) || defined(DEV_APIC)
- using_lapic_timer = lapic_setup_clock();
+ tlsca = (lapic_allclocks == 0 && tasc != 0) ? LAPIC_CLOCK_HARDCLOCK :
+ LAPIC_CLOCK_ALL;
+ using_lapic_timer = lapic_setup_clock(tlsca);
#endif
/*
* If we aren't using the local APIC timer to drive the kernel
@@ -550,9 +568,6 @@ cpu_initclocks()
set_i8254_freq(i8254_freq, hz);
}
- /* Initialize RTC. */
- atrtc_start();
-
/*
* If the separate statistics clock hasn't been explicility disabled
* and we aren't already using the local APIC timer to drive the
@@ -560,7 +575,7 @@ cpu_initclocks()
* drive statclock() and profclock().
*/
if (using_lapic_timer != LAPIC_CLOCK_ALL) {
- using_atrtc_timer = atrtc_setup_clock();
+ using_atrtc_timer = tasc;
if (using_atrtc_timer) {
/* Enable periodic interrupts from the RTC. */
intr_add_handler("rtc", 8,
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index dd5497e..78d32d7 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -776,12 +776,6 @@ OLD_FILES+=usr/share/man/man1/gdbserver.1.gz
OLD_FILES+=usr/share/man/man1/kgdb.1.gz
.endif
-.if ${MK_GNU_CPIO} == no
-OLD_FILES+=usr/bin/gcpio
-OLD_FILES+=usr/share/info/cpio.info.gz
-OLD_FILES+=usr/share/man/man1/gcpio.1.gz
-.endif
-
.if ${MK_GPIB} == no
OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h
OLD_FILES+=usr/include/dev/ieee488/ugpib.h
diff --git a/tools/build/options/WITH_GNU_CPIO b/tools/build/options/WITH_GNU_CPIO
deleted file mode 100644
index b4e756a..0000000
--- a/tools/build/options/WITH_GNU_CPIO
+++ /dev/null
@@ -1,6 +0,0 @@
-.\" $FreeBSD$
-Set to build GNU cpio as a part of the base system,
-and symlink
-.Pa /usr/bin/cpio
-to this version.
-(This will override the symlink to the BSD version.)
diff --git a/tools/regression/aio/aiotest/aiotest.c b/tools/regression/aio/aiotest/aiotest.c
index 8769dc1..60de273 100644
--- a/tools/regression/aio/aiotest/aiotest.c
+++ b/tools/regression/aio/aiotest/aiotest.c
@@ -40,14 +40,17 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/mdioctl.h>
#include <aio.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <libutil.h>
#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
diff --git a/tools/regression/bin/sh/builtins/command10.0 b/tools/regression/bin/sh/builtins/command10.0
new file mode 100644
index 0000000..2c1adf1
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/command10.0
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if ! eval "[ $* ]"; then
+ echo "Failed: $*"
+ : $((failures += 1))
+ fi
+}
+
+check '"$(f() { shift x; }; { command eval f 2>/dev/null; } >/dev/null; echo hi)" = hi'
+
+exit $((failures > 0))
diff --git a/tools/regression/bin/sh/builtins/command11.0 b/tools/regression/bin/sh/builtins/command11.0
new file mode 100644
index 0000000..10c8647
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/command11.0
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if ! eval "[ $* ]"; then
+ echo "Failed: $*"
+ : $((failures += 1))
+ fi
+}
+
+check '"$({ command eval \{ shift x\; \} 2\>/dev/null; } >/dev/null; echo hi)" = hi'
+
+exit $((failures > 0))
diff --git a/tools/regression/bin/sh/builtins/command8.0 b/tools/regression/bin/sh/builtins/command8.0
new file mode 100644
index 0000000..949ffed
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/command8.0
@@ -0,0 +1,45 @@
+# $FreeBSD$
+IFS=,
+
+SPECIAL="break,\
+ :,\
+ continue,\
+ . /dev/null,\
+ eval,\
+ exec,\
+ export -p,\
+ readonly -p,\
+ set,\
+ shift 0,\
+ times,\
+ trap,\
+ unset foo"
+
+set -e
+
+# Check that special builtins can be executed via "command".
+
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+ sh -c "v=:; while \$v; do v=false; command ${cmd}; done" >/dev/null
+done
+
+while :; do
+ command break
+ echo Error on line $LINENO
+done
+
+set p q r
+command shift 2
+if [ $# -ne 1 ]; then
+ echo Error on line $LINENO
+fi
+
+(
+ command exec >/dev/null
+ echo Error on line $LINENO
+)
+
+set +e
+! command shift 2 2>/dev/null
diff --git a/tools/regression/bin/sh/builtins/command9.0 b/tools/regression/bin/sh/builtins/command9.0
new file mode 100644
index 0000000..212e52a
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/command9.0
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if ! eval "[ $* ]"; then
+ echo "Failed: $*"
+ : $((failures += 1))
+ fi
+}
+
+check '"$({ command eval shift x 2>/dev/null; } >/dev/null; echo hi)" = hi'
+
+exit $((failures > 0))
diff --git a/tools/regression/bin/sh/builtins/var-assign2.0 b/tools/regression/bin/sh/builtins/var-assign2.0
new file mode 100644
index 0000000..8485df8
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/var-assign2.0
@@ -0,0 +1,55 @@
+# $FreeBSD$
+IFS=,
+
+SPECIAL="break,\
+ :,\
+ continue,\
+ . /dev/null,\
+ eval,\
+ exec,\
+ export -p,\
+ readonly -p,\
+ set,\
+ shift 0,\
+ times,\
+ trap,\
+ unset foo"
+
+UTILS="alias,\
+ bg,\
+ bind,\
+ cd,\
+ command echo,\
+ echo,\
+ false,\
+ fc -l,\
+ fg,\
+ getopts a var,\
+ hash,\
+ jobs,\
+ printf a,\
+ pwd,\
+ read var < /dev/null,\
+ test,\
+ true,\
+ type ls,\
+ ulimit,\
+ umask,\
+ unalias -a,\
+ wait"
+
+set -e
+
+# With 'command', variable assignments affect the shell environment.
+
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+ sh -c "VAR=0; VAR=1 command ${cmd}; exit \${VAR}" >/dev/null 2>&1
+done
+
+set -- ${UTILS}
+for cmd in "$@"
+do
+ sh -c "VAR=0; VAR=1 command ${cmd}; exit \${VAR}" >/dev/null 2>&1
+done
diff --git a/tools/regression/bin/sh/errors/assignment-error1.0 b/tools/regression/bin/sh/errors/assignment-error1.0
new file mode 100644
index 0000000..9e42f2b
--- /dev/null
+++ b/tools/regression/bin/sh/errors/assignment-error1.0
@@ -0,0 +1,30 @@
+# $FreeBSD$
+IFS=,
+
+SPECIAL="break,\
+ :,\
+ continue,\
+ . /dev/null,\
+ eval,\
+ exec,\
+ export -p,\
+ readonly -p,\
+ set,\
+ shift,\
+ times,\
+ trap,\
+ unset foo"
+
+# If there is no command word, the shell must abort on an assignment error.
+sh -c "readonly a=0; a=2; exit 0" 2>/dev/null && exit 1
+
+# Special built-in utilities must abort on an assignment error.
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+ sh -c "readonly a=0; a=2 ${cmd}; exit 0" 2>/dev/null && exit 1
+done
+
+# Other utilities must not abort; we currently still execute them.
+sh -c "readonly a=0; a=1 true; exit $a" 2>/dev/null || exit 1
+sh -c "readonly a=0; a=1 command :; exit $a" 2>/dev/null || exit 1
diff --git a/tools/regression/bin/sh/errors/redirection-error3.0 b/tools/regression/bin/sh/errors/redirection-error3.0
new file mode 100644
index 0000000..93f526c
--- /dev/null
+++ b/tools/regression/bin/sh/errors/redirection-error3.0
@@ -0,0 +1,54 @@
+# $FreeBSD$
+IFS=,
+
+SPECIAL="break,\
+ :,\
+ continue,\
+ . /dev/null,\
+ eval,\
+ exec,\
+ export -p,\
+ readonly -p,\
+ set,\
+ shift,\
+ times,\
+ trap,\
+ unset foo"
+
+UTILS="alias,\
+ bg,\
+ bind,\
+ cd,\
+ command echo,\
+ echo,\
+ false,\
+ fc -l,\
+ fg,\
+ getopts a -a,\
+ hash,\
+ jobs,\
+ printf a,\
+ pwd,\
+ read var < /dev/null,\
+ test,\
+ true,\
+ type ls,\
+ ulimit,\
+ umask,\
+ unalias -a,\
+ wait"
+
+# When used with 'command', neither special built-in utilities nor other
+# utilities must abort on a redirection error.
+
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+ sh -c "command ${cmd} > /; exit 0" 2>/dev/null || exit 1
+done
+
+set -- ${UTILS}
+for cmd in "$@"
+do
+ sh -c "command ${cmd} > /; exit 0" 2>/dev/null || exit 1
+done
diff --git a/tools/regression/bin/sh/errors/redirection-error4.0 b/tools/regression/bin/sh/errors/redirection-error4.0
new file mode 100644
index 0000000..2060974
--- /dev/null
+++ b/tools/regression/bin/sh/errors/redirection-error4.0
@@ -0,0 +1,7 @@
+# $FreeBSD$
+# A redirection error should not abort the shell if there is no command word.
+exec 2>/dev/null
+</var/empty/x
+</var/empty/x y=2
+y=2 </var/empty/x
+exit 0
diff --git a/tools/regression/bin/sh/errors/redirection-error5.0 b/tools/regression/bin/sh/errors/redirection-error5.0
new file mode 100644
index 0000000..1fcd47e
--- /dev/null
+++ b/tools/regression/bin/sh/errors/redirection-error5.0
@@ -0,0 +1,5 @@
+# $FreeBSD$
+# A redirection error on a subshell should not abort the shell.
+exec 2>/dev/null
+( echo bad ) </var/empty/x
+exit 0
diff --git a/tools/regression/bin/sh/errors/redirection-error6.0 b/tools/regression/bin/sh/errors/redirection-error6.0
new file mode 100644
index 0000000..17d1109
--- /dev/null
+++ b/tools/regression/bin/sh/errors/redirection-error6.0
@@ -0,0 +1,12 @@
+# $FreeBSD$
+# A redirection error on a compound command should not abort the shell.
+exec 2>/dev/null
+{ echo bad; } </var/empty/x
+if :; then echo bad; fi </var/empty/x
+for i in 1; do echo bad; done </var/empty/x
+i=0
+while [ $i = 0 ]; do echo bad; i=1; done </var/empty/x
+i=0
+until [ $i != 0 ]; do echo bad; i=1; done </var/empty/x
+case i in *) echo bad ;; esac </var/empty/x
+exit 0
diff --git a/tools/regression/bin/sh/expansion/arith4.0 b/tools/regression/bin/sh/expansion/arith4.0
new file mode 100644
index 0000000..610dad8
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/arith4.0
@@ -0,0 +1,20 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if [ $(($1)) != $2 ]; then
+ failures=$((failures+1))
+ echo "For $1, expected $2 actual $(($1))"
+ fi
+}
+
+check '20 / 2 / 2' 5
+check '20 - 2 - 2' 16
+unset a b c d
+check "a = b = c = d = 1" 1
+check "a == 1 && b == 1 && c == 1 && d == 1" 1
+check "a += b += c += d" 4
+check "a == 4 && b == 3 && c == 2 && d == 1" 1
+
+exit $((failures != 0))
diff --git a/tools/regression/bin/sh/expansion/arith5.0 b/tools/regression/bin/sh/expansion/arith5.0
new file mode 100644
index 0000000..d0f2331
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/arith5.0
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if [ "$2" != "$3" ]; then
+ failures=$((failures+1))
+ echo "For $1, expected $3 actual $2"
+ fi
+}
+
+unset a
+check '$((1+${a:-$((7+2))}))' "$((1+${a:-$((7+2))}))" 10
+check '$((1+${a:=$((2+2))}))' "$((1+${a:=$((2+2))}))" 5
+check '$a' "$a" 4
+
+exit $((failures != 0))
diff --git a/tools/regression/bin/sh/expansion/assign1.0 b/tools/regression/bin/sh/expansion/assign1.0
new file mode 100644
index 0000000..d4fa772
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/assign1.0
@@ -0,0 +1,37 @@
+# $FreeBSD$
+
+e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
+h='##'
+failures=''
+ok=''
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+testcase 'v=; set -- ${v=a b} $v' '0|'
+testcase 'unset v; set -- ${v=a b} $v' '4|a|b|a|b'
+testcase 'v=; set -- ${v:=a b} $v' '4|a|b|a|b'
+testcase 'v=; set -- "${v:=a b}" "$v"' '2|a b|a b'
+# expect sensible behaviour, although it disagrees with POSIX
+testcase 'v=; set -- ${v:=a\ b} $v' '4|a|b|a|b'
+testcase 'v=; set -- ${v:=$p} $v' '2|/etc/|/etc/'
+testcase 'v=; set -- "${v:=$p}" "$v"' '2|/et[c]/|/et[c]/'
+testcase 'v=; set -- "${v:=a\ b}" "$v"' '2|a\ b|a\ b'
+testcase 'v=; set -- ${v:="$p"} $v' '2|/etc/|/etc/'
+# whether $p is quoted or not shouldn't really matter
+testcase 'v=; set -- "${v:="$p"}" "$v"' '2|/et[c]/|/et[c]/'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/cmdsubst2.0 b/tools/regression/bin/sh/expansion/cmdsubst2.0
new file mode 100644
index 0000000..b86776e
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/cmdsubst2.0
@@ -0,0 +1,43 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if ! eval "[ $* ]"; then
+ echo "Failed: $*"
+ : $((failures += 1))
+ fi
+}
+
+check '`echo /et[c]/` = "/etc/"'
+check '`printf /var/empty%s /et[c]/` = "/var/empty/etc/"'
+check '"`echo /et[c]/`" = "/etc/"'
+check '`echo "/et[c]/"` = "/etc/"'
+check '`printf /var/empty%s "/et[c]/"` = "/var/empty/et[c]/"'
+check '`printf /var/empty/%s \"/et[c]/\"` = "/var/empty/\"/et[c]/\""'
+check '"`echo \"/et[c]/\"`" = "/et[c]/"'
+check '"`echo "/et[c]/"`" = "/et[c]/"'
+check '`echo $$` = $$'
+check '"`echo $$`" = $$'
+check '`echo \$\$` = $$'
+check '"`echo \$\$`" = $$'
+
+# Command substitutions consisting of a single builtin may be treated
+# differently.
+check '`:; echo /et[c]/` = "/etc/"'
+check '`:; printf /var/empty%s /et[c]/` = "/var/empty/etc/"'
+check '"`:; echo /et[c]/`" = "/etc/"'
+check '`:; echo "/et[c]/"` = "/etc/"'
+check '`:; printf /var/empty%s "/et[c]/"` = "/var/empty/et[c]/"'
+check '`:; printf /var/empty/%s \"/et[c]/\"` = "/var/empty/\"/et[c]/\""'
+check '"`:; echo \"/et[c]/\"`" = "/et[c]/"'
+check '"`:; echo "/et[c]/"`" = "/et[c]/"'
+check '`:; echo $$` = $$'
+check '"`:; echo $$`" = $$'
+check '`:; echo \$\$` = $$'
+check '"`:; echo \$\$`" = $$'
+
+check '`set -f; echo /et[c]/` = "/etc/"'
+check '"`set -f; echo /et[c]/`" = "/et[c]/"'
+
+exit $((failures > 0))
diff --git a/tools/regression/bin/sh/expansion/plus-minus1.0 b/tools/regression/bin/sh/expansion/plus-minus1.0
new file mode 100644
index 0000000..e98c989
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/plus-minus1.0
@@ -0,0 +1,81 @@
+# $FreeBSD$
+
+e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
+h='##'
+failures=''
+ok=''
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+testcase 'set -- a b' '2|a|b'
+testcase 'set --' '0|'
+testcase 'set -- ${e}' '0|'
+testcase 'set -- "${e}"' '1|'
+
+testcase 'set -- $p' '1|/etc/'
+testcase 'set -- "$p"' '1|/et[c]/'
+testcase 'set -- ${s+$p}' '1|/etc/'
+testcase 'set -- "${s+$p}"' '1|/et[c]/'
+testcase 'set -- ${s+"$p"}' '1|/et[c]/'
+# Dquotes in dquotes is undefined for Bourne shell operators
+#testcase 'set -- "${s+"$p"}"' '1|/et[c]/'
+testcase 'set -- ${e:-$p}' '1|/etc/'
+testcase 'set -- "${e:-$p}"' '1|/et[c]/'
+testcase 'set -- ${e:-"$p"}' '1|/et[c]/'
+# Dquotes in dquotes is undefined for Bourne shell operators
+#testcase 'set -- "${e:-"$p"}"' '1|/et[c]/'
+testcase 'set -- ${e:+"$e"}' '0|'
+testcase 'set -- ${e:+$w"$e"}' '0|'
+testcase 'set -- ${w:+"$w"}' '1|a b c'
+testcase 'set -- ${w:+$w"$w"}' '3|a|b|ca b c'
+
+# These two are known broken in FreeBSD /bin/sh
+#testcase 'set -- ${s+a b}' '2|a|b'
+#testcase 'set -- ${e:-a b}' '2|a|b'
+testcase 'set -- "${s+a b}"' '1|a b'
+testcase 'set -- "${e:-a b}"' '1|a b'
+testcase 'set -- ${e:-\}}' '1|}'
+# Currently broken in FreeBSD /bin/sh
+#testcase 'set -- "${e:-\}}"' '1|}'
+testcase 'set -- ${e:+{}}' '1|}'
+testcase 'set -- "${e:+{}}"' '1|}'
+
+testcase 'set -- ${e+x}${e+x}' '1|xx'
+testcase 'set -- "${e+x}"${e+x}' '1|xx'
+testcase 'set -- ${e+x}"${e+x}"' '1|xx'
+testcase 'set -- "${e+x}${e+x}"' '1|xx'
+testcase 'set -- "${e+x}""${e+x}"' '1|xx'
+
+testcase 'set -- ${e:-${e:-$p}}' '1|/etc/'
+testcase 'set -- "${e:-${e:-$p}}"' '1|/et[c]/'
+testcase 'set -- ${e:-"${e:-$p}"}' '1|/et[c]/'
+testcase 'set -- ${e:-${e:-"$p"}}' '1|/et[c]/'
+testcase 'set -- ${e:-${e:-${e:-$w}}}' '3|a|b|c'
+testcase 'set -- ${e:-${e:-${e:-"$w"}}}' '1|a b c'
+testcase 'set -- ${e:-${e:-"${e:-$w}"}}' '1|a b c'
+testcase 'set -- ${e:-"${e:-${e:-$w}}"}' '1|a b c'
+testcase 'set -- "${e:-${e:-${e:-$w}}}"' '1|a b c'
+
+testcase 'shift $#; set -- ${1+"$@"}' '0|'
+testcase 'set -- ""; set -- ${1+"$@"}' '1|'
+testcase 'set -- "" a; set -- ${1+"$@"}' '2||a'
+testcase 'set -- a ""; set -- ${1+"$@"}' '2|a|'
+testcase 'set -- a b; set -- ${1+"$@"}' '2|a|b'
+testcase 'set -- a\ b; set -- ${1+"$@"}' '1|a b'
+testcase 'set -- " " ""; set -- ${1+"$@"}' '2| |'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/plus-minus2.0 b/tools/regression/bin/sh/expansion/plus-minus2.0
new file mode 100644
index 0000000..f5a8752
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/plus-minus2.0
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+e=
+test "${e:-\}}" = '}'
diff --git a/tools/regression/bin/sh/expansion/plus-minus3.0 b/tools/regression/bin/sh/expansion/plus-minus3.0
new file mode 100644
index 0000000..49fcdc2
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/plus-minus3.0
@@ -0,0 +1,44 @@
+# $FreeBSD$
+
+e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
+h='##'
+failures=''
+ok=''
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+# We follow original ash behaviour for quoted ${var+-=?} expansions:
+# a double-quote in one switches back to unquoted state.
+# This allows expanding a variable as a single word if it is set
+# and substituting multiple words otherwise.
+# It is also close to the Bourne and Korn shells.
+# POSIX leaves this undefined, and various other shells treat
+# such double-quotes as introducing a second level of quoting
+# which does not do much except quoting close braces.
+
+testcase 'set -- "${p+"/et[c]/"}"' '1|/etc/'
+testcase 'set -- "${p-"/et[c]/"}"' '1|/et[c]/'
+testcase 'set -- "${p+"$p"}"' '1|/etc/'
+testcase 'set -- "${p-"$p"}"' '1|/et[c]/'
+testcase 'set -- "${p+"""/et[c]/"}"' '1|/etc/'
+testcase 'set -- "${p-"""/et[c]/"}"' '1|/et[c]/'
+testcase 'set -- "${p+"""$p"}"' '1|/etc/'
+testcase 'set -- "${p-"""$p"}"' '1|/et[c]/'
+testcase 'set -- "${p+"\@"}"' '1|@'
+testcase 'set -- "${p+"'\''/et[c]/'\''"}"' '1|/et[c]/'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/tilde1.0 b/tools/regression/bin/sh/expansion/tilde1.0
new file mode 100644
index 0000000..7d8581b
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/tilde1.0
@@ -0,0 +1,56 @@
+# $FreeBSD$
+
+HOME=/tmp
+roothome=~root
+if [ "$roothome" = "~root" ]; then
+ echo "~root is not expanded!"
+ exit 2
+fi
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+testcase 'set -- ~' '1|/tmp'
+testcase 'set -- ~/foo' '1|/tmp/foo'
+testcase 'set -- x~' '1|x~'
+testcase 'set -- ~root' "1|$roothome"
+h=~
+testcase 'set -- "$h"' '1|/tmp'
+ooIFS=$IFS
+IFS=m
+testcase 'set -- ~' '1|/tmp'
+testcase 'set -- ~/foo' '1|/tmp/foo'
+testcase 'set -- $h' '2|/t|p'
+IFS=$ooIFS
+t=\~
+testcase 'set -- $t' '1|~'
+r=$(cat <<EOF
+~
+EOF
+)
+testcase 'set -- $r' '1|~'
+r=$(cat <<EOF
+${t+~}
+EOF
+)
+testcase 'set -- $r' '1|~'
+r=$(cat <<EOF
+${t+~/.}
+EOF
+)
+testcase 'set -- $r' '1|~/.'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/tilde2.0 b/tools/regression/bin/sh/expansion/tilde2.0
new file mode 100644
index 0000000..4f8ed9b
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/tilde2.0
@@ -0,0 +1,90 @@
+# $FreeBSD$
+
+HOME=/tmp
+roothome=~root
+if [ "$roothome" = "~root" ]; then
+ echo "~root is not expanded!"
+ exit 2
+fi
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+testcase 'set -- ${$+~}' '1|/tmp'
+testcase 'set -- ${$+~/}' '1|/tmp/'
+testcase 'set -- ${$+~/foo}' '1|/tmp/foo'
+testcase 'set -- ${$+x~}' '1|x~'
+testcase 'set -- ${$+~root}' "1|$roothome"
+testcase 'set -- ${$+"~"}' '1|~'
+testcase 'set -- ${$+"~/"}' '1|~/'
+testcase 'set -- ${$+"~/foo"}' '1|~/foo'
+testcase 'set -- ${$+"x~"}' '1|x~'
+testcase 'set -- ${$+"~root"}' "1|~root"
+testcase 'set -- "${$+~}"' '1|~'
+testcase 'set -- "${$+~/}"' '1|~/'
+testcase 'set -- "${$+~/foo}"' '1|~/foo'
+testcase 'set -- "${$+x~}"' '1|x~'
+testcase 'set -- "${$+~root}"' "1|~root"
+testcase 'set -- ${HOME#~}' '0|'
+h=~
+testcase 'set -- "$h"' '1|/tmp'
+f=~/foo
+testcase 'set -- "$f"' '1|/tmp/foo'
+testcase 'set -- ${f#~}' '1|/foo'
+testcase 'set -- ${f#~/}' '1|foo'
+
+ooIFS=$IFS
+IFS=m
+testcase 'set -- ${$+~}' '1|/tmp'
+testcase 'set -- ${$+~/foo}' '1|/tmp/foo'
+testcase 'set -- ${$+$h}' '2|/t|p'
+testcase 'set -- ${HOME#~}' '0|'
+IFS=$ooIFS
+
+t=\~
+testcase 'set -- ${$+$t}' '1|~'
+r=$(cat <<EOF
+${HOME#~}
+EOF
+)
+testcase 'set -- $r' '0|'
+r=$(cat <<EOF
+${HOME#'~'}
+EOF
+)
+testcase 'set -- $r' '1|/tmp'
+r=$(cat <<EOF
+${t#'~'}
+EOF
+)
+testcase 'set -- $r' '0|'
+r=$(cat <<EOF
+${roothome#~root}
+EOF
+)
+testcase 'set -- $r' '0|'
+r=$(cat <<EOF
+${f#~}
+EOF
+)
+testcase 'set -- $r' '1|/foo'
+r=$(cat <<EOF
+${f#~/}
+EOF
+)
+testcase 'set -- $r' '1|foo'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/trim1.0 b/tools/regression/bin/sh/expansion/trim1.0
new file mode 100644
index 0000000..b548e52
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/trim1.0
@@ -0,0 +1,85 @@
+# $FreeBSD$
+
+e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
+h='##'
+failures=''
+ok=''
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+testcase 'set -- ${t%t}' '1|texttex'
+testcase 'set -- "${t%t}"' '1|texttex'
+testcase 'set -- ${t%e*}' '1|textt'
+testcase 'set -- "${t%e*}"' '1|textt'
+testcase 'set -- ${t%%e*}' '1|t'
+testcase 'set -- "${t%%e*}"' '1|t'
+testcase 'set -- ${t%%*}' '0|'
+testcase 'set -- "${t%%*}"' '1|'
+testcase 'set -- ${t#t}' '1|exttext'
+testcase 'set -- "${t#t}"' '1|exttext'
+testcase 'set -- ${t#*x}' '1|ttext'
+testcase 'set -- "${t#*x}"' '1|ttext'
+testcase 'set -- ${t##*x}' '1|t'
+testcase 'set -- "${t##*x}"' '1|t'
+testcase 'set -- ${t##*}' '0|'
+testcase 'set -- "${t##*}"' '1|'
+testcase 'set -- ${t%e$a}' '1|textt'
+
+set -f
+testcase 'set -- ${s%[?]*}' '1|ast*que'
+testcase 'set -- "${s%[?]*}"' '1|ast*que'
+testcase 'set -- ${s%[*]*}' '1|ast'
+testcase 'set -- "${s%[*]*}"' '1|ast'
+set +f
+
+testcase 'set -- $b' '1|{{(#)}}'
+testcase 'set -- ${b%\}}' '1|{{(#)}'
+testcase 'set -- ${b#{}' '1|{(#)}}'
+testcase 'set -- "${b#{}"' '1|{(#)}}'
+# Parentheses are special in ksh, check that they can be escaped
+testcase 'set -- ${b%\)*}' '1|{{(#'
+testcase 'set -- ${b#{}' '1|{(#)}}'
+testcase 'set -- $h' '1|##'
+testcase 'set -- ${h#\#}' '1|#'
+testcase 'set -- ${h###}' '1|#'
+testcase 'set -- "${h###}"' '1|#'
+testcase 'set -- ${h%#}' '1|#'
+testcase 'set -- "${h%#}"' '1|#'
+
+set -f
+testcase 'set -- ${s%"${s#?}"}' '1|a'
+testcase 'set -- ${s%"${s#????}"}' '1|ast*'
+testcase 'set -- ${s%"${s#????????}"}' '1|ast*que?'
+testcase 'set -- ${s#"${s%?}"}' '1|n'
+testcase 'set -- ${s#"${s%????}"}' '1|?non'
+testcase 'set -- ${s#"${s%????????}"}' '1|*que?non'
+set +f
+testcase 'set -- "${s%"${s#?}"}"' '1|a'
+testcase 'set -- "${s%"${s#????}"}"' '1|ast*'
+testcase 'set -- "${s%"${s#????????}"}"' '1|ast*que?'
+testcase 'set -- "${s#"${s%?}"}"' '1|n'
+testcase 'set -- "${s#"${s%????}"}"' '1|?non'
+testcase 'set -- "${s#"${s%????????}"}"' '1|*que?non'
+testcase 'set -- ${p#${p}}' '1|/etc/'
+testcase 'set -- "${p#${p}}"' '1|/et[c]/'
+testcase 'set -- ${p#*[[]}' '1|c]/'
+testcase 'set -- "${p#*[[]}"' '1|c]/'
+testcase 'set -- ${p#*\[}' '1|c]/'
+testcase 'set -- ${p#*"["}' '1|c]/'
+testcase 'set -- "${p#*"["}"' '1|c]/'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/trim2.0 b/tools/regression/bin/sh/expansion/trim2.0
new file mode 100644
index 0000000..619ef65
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/trim2.0
@@ -0,0 +1,55 @@
+# $FreeBSD$
+
+e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
+h='##'
+failures=''
+ok=''
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+set -f
+testcase 'set -- $s' '1|ast*que?non'
+testcase 'set -- ${s%\?*}' '1|ast*que'
+testcase 'set -- "${s%\?*}"' '1|ast*que'
+testcase 'set -- ${s%\**}' '1|ast'
+testcase 'set -- "${s%\**}"' '1|ast'
+testcase 'set -- ${s%"$q"*}' '1|ast*que'
+testcase 'set -- "${s%"$q"*}"' '1|ast*que'
+testcase 'set -- ${s%"$a"*}' '1|ast'
+testcase 'set -- "${s%"$a"*}"' '1|ast'
+testcase 'set -- ${s%"$q"$a}' '1|ast*que'
+testcase 'set -- "${s%"$q"$a}"' '1|ast*que'
+testcase 'set -- ${s%"$a"$a}' '1|ast'
+testcase 'set -- "${s%"$a"$a}"' '1|ast'
+set +f
+
+testcase 'set -- "${b%\}}"' '1|{{(#)}'
+# Parentheses are special in ksh, check that they can be escaped
+testcase 'set -- "${b%\)*}"' '1|{{(#'
+testcase 'set -- "${h#\#}"' '1|#'
+
+testcase 'set -- ${p%"${p#?}"}' '1|/'
+testcase 'set -- ${p%"${p#??????}"}' '1|/etc'
+testcase 'set -- ${p%"${p#???????}"}' '1|/etc/'
+testcase 'set -- "${p%"${p#?}"}"' '1|/'
+testcase 'set -- "${p%"${p#??????}"}"' '1|/et[c]'
+testcase 'set -- "${p%"${p#???????}"}"' '1|/et[c]/'
+testcase 'set -- ${p#"${p}"}' '0|'
+testcase 'set -- "${p#"${p}"}"' '1|'
+testcase 'set -- "${p#*\[}"' '1|c]/'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/expansion/trim3.0 b/tools/regression/bin/sh/expansion/trim3.0
new file mode 100644
index 0000000..b89a041
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/trim3.0
@@ -0,0 +1,46 @@
+# $FreeBSD$
+
+e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
+h='##' c='\\\\'
+failures=''
+ok=''
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+# This doesn't make much sense, but it fails in dash so I'm adding it here:
+testcase 'set -- "${w%${w#???}}"' '1|a b'
+
+testcase 'set -- ${p#/et[}' '1|c]/'
+testcase 'set -- "${p#/et[}"' '1|c]/'
+testcase 'set -- "${p%${p#????}}"' '1|/et['
+
+testcase 'set -- ${b%'\'}\''}' '1|{{(#)}'
+
+testcase 'set -- ${c#\\}' '1|\\\'
+testcase 'set -- ${c#\\\\}' '1|\\'
+testcase 'set -- ${c#\\\\\\}' '1|\'
+testcase 'set -- ${c#\\\\\\\\}' '0|'
+testcase 'set -- "${c#\\}"' '1|\\\'
+testcase 'set -- "${c#\\\\}"' '1|\\'
+testcase 'set -- "${c#\\\\\\}"' '1|\'
+testcase 'set -- "${c#\\\\\\\\}"' '1|'
+testcase 'set -- "${c#"$c"}"' '1|'
+testcase 'set -- ${c#"$c"}' '0|'
+testcase 'set -- "${c%"$c"}"' '1|'
+testcase 'set -- ${c%"$c"}' '0|'
+
+test "x$failures" = x
diff --git a/tools/regression/bin/sh/parameters/pwd1.0 b/tools/regression/bin/sh/parameters/pwd1.0
new file mode 100644
index 0000000..d543030
--- /dev/null
+++ b/tools/regression/bin/sh/parameters/pwd1.0
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Check that bogus PWD values are not accepted from the environment.
+
+cd / || exit 3
+failures=0
+[ "$(PWD=foo sh -c 'pwd')" = / ] || : $((failures += 1))
+[ "$(PWD=/var/empty sh -c 'pwd')" = / ] || : $((failures += 1))
+[ "$(PWD=/var/empty/foo sh -c 'pwd')" = / ] || : $((failures += 1))
+[ "$(PWD=/bin/ls sh -c 'pwd')" = / ] || : $((failures += 1))
+
+exit $((failures != 0))
diff --git a/tools/regression/bin/sh/parameters/pwd2.0 b/tools/regression/bin/sh/parameters/pwd2.0
new file mode 100644
index 0000000..29b5531
--- /dev/null
+++ b/tools/regression/bin/sh/parameters/pwd2.0
@@ -0,0 +1,24 @@
+# $FreeBSD$
+# Check that PWD is exported and accepted from the environment.
+set -e
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX)
+trap 'rm -rf $T' 0
+cd -P $T
+TP=$(pwd)
+mkdir test1
+ln -s test1 link
+cd link
+[ "$PWD" = "$TP/link" ]
+[ "$(pwd)" = "$TP/link" ]
+[ "$(pwd -P)" = "$TP/test1" ]
+[ "$(sh -c pwd)" = "$TP/link" ]
+[ "$(sh -c pwd\ -P)" = "$TP/test1" ]
+cd ..
+[ "$(pwd)" = "$TP" ]
+cd -P link
+[ "$PWD" = "$TP/test1" ]
+[ "$(pwd)" = "$TP/test1" ]
+[ "$(pwd -P)" = "$TP/test1" ]
+[ "$(sh -c pwd)" = "$TP/test1" ]
+[ "$(sh -c pwd\ -P)" = "$TP/test1" ]
diff --git a/tools/regression/bin/sh/parser/heredoc1.0 b/tools/regression/bin/sh/parser/heredoc1.0
new file mode 100644
index 0000000..5ce3897
--- /dev/null
+++ b/tools/regression/bin/sh/parser/heredoc1.0
@@ -0,0 +1,85 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if ! eval "[ $* ]"; then
+ echo "Failed: $*"
+ : $((failures += 1))
+ fi
+}
+
+check '"$(cat <<EOF
+hi
+EOF
+)" = hi'
+
+check '"$(cat <<EOF
+${$+hi}
+EOF
+)" = hi'
+
+unset yy
+check '"$(cat <<EOF
+${yy-hi}
+EOF
+)" = hi'
+
+check '"$(cat <<EOF
+${$+hi
+there}
+EOF
+)" = "hi
+there"'
+
+check '"$(cat <<EOF
+$((1+1))
+EOF
+)" = 2'
+
+check '"$(cat <<EOF
+$(echo hi)
+EOF
+)" = hi'
+
+check '"$(cat <<EOF
+`echo hi`
+EOF
+)" = hi'
+
+check '"$(cat <<\EOF
+${$+hi}
+EOF
+)" = "\${\$+hi}"'
+
+check '"$(cat <<\EOF
+$(
+EOF
+)" = \$\('
+
+check '"$(cat <<\EOF
+`
+EOF
+)" = \`'
+
+check '"$(cat <<EOF
+"
+EOF
+)" = \"'
+
+check '"$(cat <<\EOF
+"
+EOF
+)" = \"'
+
+check '"$(cat <<esac
+'"'"'
+esac
+)" = "'"'"'"'
+
+check '"$(cat <<\)
+'"'"'
+)
+)" = "'"'"'"'
+
+exit $((failures != 0))
diff --git a/tools/regression/bin/sh/parser/heredoc2.0 b/tools/regression/bin/sh/parser/heredoc2.0
new file mode 100644
index 0000000..b239520
--- /dev/null
+++ b/tools/regression/bin/sh/parser/heredoc2.0
@@ -0,0 +1,44 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if ! eval "[ $* ]"; then
+ echo "Failed: $*"
+ : $((failures += 1))
+ fi
+}
+
+s='ast*que?non' sq=\' dq=\"
+
+check '"$(cat <<EOF
+${s}
+EOF
+)" = "ast*que?non"'
+
+check '"$(cat <<EOF
+${s+"x"}
+EOF
+)" = ${dq}x${dq}'
+
+check '"$(cat <<EOF
+${s+'$sq'x'$sq'}
+EOF
+)" = ${sq}x${sq}'
+
+check '"$(cat <<EOF
+${s#ast}
+EOF
+)" = "*que?non"'
+
+check '"$(cat <<EOF
+${s##"ast"}
+EOF
+)" = "*que?non"'
+
+check '"$(cat <<EOF
+${s##'$sq'ast'$sq'}
+EOF
+)" = "*que?non"'
+
+exit $((failures != 0))
diff --git a/tools/regression/bpf/bpf_filter/tests/test0083.h b/tools/regression/bpf/bpf_filter/tests/test0083.h
index debe719..a55780f 100644
--- a/tools/regression/bpf/bpf_filter/tests/test0083.h
+++ b/tools/regression/bpf/bpf_filter/tests/test0083.h
@@ -6,7 +6,7 @@
/* BPF program */
struct bpf_insn pc[] = {
- BPF_JUMP(BPF_JMP+BPF_JA, 0, 0, 0),
+ BPF_STMT(BPF_LD|BPF_IMM, 0),
};
/* Packet */
diff --git a/tools/regression/kqueue/Makefile b/tools/regression/kqueue/Makefile
index b25a17b..4537249 100644
--- a/tools/regression/kqueue/Makefile
+++ b/tools/regression/kqueue/Makefile
@@ -16,6 +16,6 @@ SRCS= \
signal.c \
user.c
NO_MAN=
-WARNS=2
+WARNS?= 2
.include "bsd.prog.mk"
diff --git a/tools/regression/lib/libc/gen/Makefile b/tools/regression/lib/libc/gen/Makefile
index 3dbe803..3e911e4 100644
--- a/tools/regression/lib/libc/gen/Makefile
+++ b/tools/regression/lib/libc/gen/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-TESTS= test-fmtcheck test-fpclassify test-wordexp
+TESTS= test-fmtcheck test-fnmatch test-fpclassify 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
new file mode 100644
index 0000000..6cbf8ee
--- /dev/null
+++ b/tools/regression/lib/libc/gen/test-fnmatch.c
@@ -0,0 +1,336 @@
+/*-
+ * Copyright (c) 2010 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fnmatch.h>
+
+struct testcase {
+ const char *pattern;
+ const char *string;
+ int flags;
+ int result;
+} testcases[] = {
+ "", "", 0, 0,
+ "a", "a", 0, 0,
+ "a", "b", 0, FNM_NOMATCH,
+ "a", "A", 0, FNM_NOMATCH,
+ "*", "a", 0, 0,
+ "*", "aa", 0, 0,
+ "*a", "a", 0, 0,
+ "*a", "b", 0, FNM_NOMATCH,
+ "*a*", "b", 0, FNM_NOMATCH,
+ "*a*b*", "ab", 0, 0,
+ "*a*b*", "qaqbq", 0, 0,
+ "*a*bb*", "qaqbqbbq", 0, 0,
+ "*a*bc*", "qaqbqbcq", 0, 0,
+ "*a*bb*", "qaqbqbb", 0, 0,
+ "*a*bc*", "qaqbqbc", 0, 0,
+ "*a*bb", "qaqbqbb", 0, 0,
+ "*a*bc", "qaqbqbc", 0, 0,
+ "*a*bb", "qaqbqbbq", 0, FNM_NOMATCH,
+ "*a*bc", "qaqbqbcq", 0, FNM_NOMATCH,
+ "*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaa", 0, FNM_NOMATCH,
+ "*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaaa", 0, 0,
+ "*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaaaa", 0, 0,
+ ".*.*.*.*.*.*.*.*.*.*", ".........", 0, FNM_NOMATCH,
+ ".*.*.*.*.*.*.*.*.*.*", "..........", 0, 0,
+ ".*.*.*.*.*.*.*.*.*.*", "...........", 0, 0,
+ "*?*?*?*?*?*?*?*?*?*?*", "123456789", 0, FNM_NOMATCH,
+ "??????????*", "123456789", 0, FNM_NOMATCH,
+ "*??????????", "123456789", 0, FNM_NOMATCH,
+ "*?*?*?*?*?*?*?*?*?*?*", "1234567890", 0, 0,
+ "??????????*", "1234567890", 0, 0,
+ "*??????????", "1234567890", 0, 0,
+ "*?*?*?*?*?*?*?*?*?*?*", "12345678901", 0, 0,
+ "??????????*", "12345678901", 0, 0,
+ "*??????????", "12345678901", 0, 0,
+ "[x]", "x", 0, 0,
+ "[*]", "*", 0, 0,
+ "[?]", "?", 0, 0,
+ "[", "[", 0, 0,
+ "[[]", "[", 0, 0,
+ "[[]", "x", 0, FNM_NOMATCH,
+ "[*]", "", 0, FNM_NOMATCH,
+ "[*]", "x", 0, FNM_NOMATCH,
+ "[?]", "x", 0, FNM_NOMATCH,
+ "*[*]*", "foo*foo", 0, 0,
+ "*[*]*", "foo", 0, FNM_NOMATCH,
+ "[0-9]", "0", 0, 0,
+ "[0-9]", "5", 0, 0,
+ "[0-9]", "9", 0, 0,
+ "[0-9]", "/", 0, FNM_NOMATCH,
+ "[0-9]", ":", 0, FNM_NOMATCH,
+ "[0-9]", "*", 0, FNM_NOMATCH,
+ "[!0-9]", "0", 0, FNM_NOMATCH,
+ "[!0-9]", "5", 0, FNM_NOMATCH,
+ "[!0-9]", "9", 0, FNM_NOMATCH,
+ "[!0-9]", "/", 0, 0,
+ "[!0-9]", ":", 0, 0,
+ "[!0-9]", "*", 0, 0,
+ "*[0-9]", "a0", 0, 0,
+ "*[0-9]", "a5", 0, 0,
+ "*[0-9]", "a9", 0, 0,
+ "*[0-9]", "a/", 0, FNM_NOMATCH,
+ "*[0-9]", "a:", 0, FNM_NOMATCH,
+ "*[0-9]", "a*", 0, FNM_NOMATCH,
+ "*[!0-9]", "a0", 0, FNM_NOMATCH,
+ "*[!0-9]", "a5", 0, FNM_NOMATCH,
+ "*[!0-9]", "a9", 0, FNM_NOMATCH,
+ "*[!0-9]", "a/", 0, 0,
+ "*[!0-9]", "a:", 0, 0,
+ "*[!0-9]", "a*", 0, 0,
+ "*[0-9]", "a00", 0, 0,
+ "*[0-9]", "a55", 0, 0,
+ "*[0-9]", "a99", 0, 0,
+ "*[0-9]", "a0a0", 0, 0,
+ "*[0-9]", "a5a5", 0, 0,
+ "*[0-9]", "a9a9", 0, 0,
+ "\\*", "*", 0, 0,
+ "\\?", "?", 0, 0,
+ "\\[x]", "[x]", 0, 0,
+ "\\[", "[", 0, 0,
+ "\\\\", "\\", 0, 0,
+ "*\\**", "foo*foo", 0, 0,
+ "*\\**", "foo", 0, FNM_NOMATCH,
+ "*\\\\*", "foo\\foo", 0, 0,
+ "*\\\\*", "foo", 0, FNM_NOMATCH,
+ "\\(", "(", 0, 0,
+ "\\a", "a", 0, 0,
+ "\\*", "a", 0, FNM_NOMATCH,
+ "\\?", "a", 0, FNM_NOMATCH,
+ "\\*", "\\*", 0, FNM_NOMATCH,
+ "\\?", "\\?", 0, FNM_NOMATCH,
+ "\\[x]", "\\[x]", 0, FNM_NOMATCH,
+ "\\[x]", "\\x", 0, FNM_NOMATCH,
+ "\\[", "\\[", 0, FNM_NOMATCH,
+ "\\(", "\\(", 0, FNM_NOMATCH,
+ "\\a", "\\a", 0, FNM_NOMATCH,
+ "\\*", "\\*", FNM_NOESCAPE, 0,
+ "\\?", "\\?", FNM_NOESCAPE, 0,
+ "\\", "\\", FNM_NOESCAPE, 0,
+ "\\\\", "\\", FNM_NOESCAPE, FNM_NOMATCH,
+ "\\\\", "\\\\", FNM_NOESCAPE, 0,
+ "*\\*", "foo\\foo", FNM_NOESCAPE, 0,
+ "*\\*", "foo", FNM_NOESCAPE, FNM_NOMATCH,
+ "*", ".", FNM_PERIOD, FNM_NOMATCH,
+ "?", ".", FNM_PERIOD, FNM_NOMATCH,
+ ".*", ".", 0, 0,
+ ".*", "..", 0, 0,
+ ".*", ".a", 0, 0,
+ "[0-9]", ".", FNM_PERIOD, FNM_NOMATCH,
+ "a*", "a.", 0, 0,
+ "a/a", "a/a", FNM_PATHNAME, 0,
+ "a/*", "a/a", FNM_PATHNAME, 0,
+ "*/a", "a/a", FNM_PATHNAME, 0,
+ "*/*", "a/a", FNM_PATHNAME, 0,
+ "a*b/*", "abbb/x", FNM_PATHNAME, 0,
+ "a*b/*", "abbb/.x", FNM_PATHNAME, 0,
+ "*", "a/a", FNM_PATHNAME, FNM_NOMATCH,
+ "*/*", "a/a/a", FNM_PATHNAME, FNM_NOMATCH,
+ "b/*", "b/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH,
+ "b*/*", "a/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH,
+ "b/.*", "b/.x", FNM_PATHNAME | FNM_PERIOD, 0,
+ "b*/.*", "b/.x", FNM_PATHNAME | FNM_PERIOD, 0,
+ "a", "A", FNM_CASEFOLD, 0,
+ "A", "a", FNM_CASEFOLD, 0,
+ "[a]", "A", FNM_CASEFOLD, 0,
+ "[A]", "a", FNM_CASEFOLD, 0,
+ "a", "b", FNM_CASEFOLD, FNM_NOMATCH,
+ "a", "a/b", FNM_PATHNAME, FNM_NOMATCH,
+ "*", "a/b", FNM_PATHNAME, FNM_NOMATCH,
+ "*b", "a/b", FNM_PATHNAME, FNM_NOMATCH,
+ "a", "a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
+ "*", "a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
+ "*", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
+ "*a", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
+ "*", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH,
+ "*a", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH,
+ "a*b/*", "abbb/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH,
+};
+
+static const char *
+flags_to_string(int flags)
+{
+ static const int flagvalues[] = { FNM_NOESCAPE, FNM_PATHNAME,
+ FNM_PERIOD, FNM_LEADING_DIR, FNM_CASEFOLD, 0 };
+ static const char flagnames[] = "FNM_NOESCAPE\0FNM_PATHNAME\0FNM_PERIOD\0FNM_LEADING_DIR\0FNM_CASEFOLD\0";
+ static char result[sizeof(flagnames) + 3 * sizeof(int) + 2];
+ char *p;
+ size_t i, len;
+ const char *fp;
+
+ p = result;
+ fp = flagnames;
+ for (i = 0; flagvalues[i] != 0; i++) {
+ len = strlen(fp);
+ if (flags & flagvalues[i]) {
+ if (p != result)
+ *p++ = '|';
+ memcpy(p, fp, len);
+ p += len;
+ flags &= ~flagvalues[i];
+ }
+ fp += len + 1;
+ }
+ if (p == result)
+ memcpy(p, "0", 2);
+ else if (flags != 0)
+ sprintf(p, "%d", flags);
+ else
+ *p = '\0';
+ return result;
+}
+
+int
+main(int argc, char *argv[])
+{
+ size_t i, n;
+ int flags, result, extra, errors;
+ struct testcase *t;
+
+ n = sizeof(testcases) / sizeof(testcases[0]);
+ errors = 0;
+ printf("1..%zu\n", n);
+ for (i = 0; i < n; i++) {
+ t = &testcases[i];
+ flags = t->flags;
+ extra = 0;
+ do {
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ if (strchr(t->pattern, '\\') == NULL &&
+ !(flags & FNM_NOESCAPE)) {
+ flags |= FNM_NOESCAPE;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if (strchr(t->pattern, '\\') != NULL &&
+ strchr(t->string, '\\') == NULL &&
+ t->result == FNM_NOMATCH &&
+ !(flags & (FNM_NOESCAPE | FNM_LEADING_DIR))) {
+ flags |= FNM_NOESCAPE;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if ((t->string[0] != '.' || t->pattern[0] == '.' ||
+ t->result == FNM_NOMATCH) &&
+ !(flags & (FNM_PATHNAME | FNM_PERIOD))) {
+ flags |= FNM_PERIOD;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if ((strchr(t->string, '/') == NULL ||
+ t->result == FNM_NOMATCH) &&
+ !(flags & FNM_PATHNAME)) {
+ flags |= FNM_PATHNAME;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if ((((t->string[0] != '.' || t->pattern[0] == '.') &&
+ strstr(t->string, "/.") == NULL) ||
+ t->result == FNM_NOMATCH) &&
+ flags & FNM_PATHNAME && !(flags & FNM_PERIOD)) {
+ flags |= FNM_PERIOD;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if ((((t->string[0] != '.' || t->pattern[0] == '.') &&
+ strchr(t->string, '/') == NULL) ||
+ t->result == FNM_NOMATCH) &&
+ !(flags & (FNM_PATHNAME | FNM_PERIOD))) {
+ flags |= FNM_PATHNAME | FNM_PERIOD;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if ((strchr(t->string, '/') == NULL || t->result == 0)
+ && !(flags & FNM_LEADING_DIR)) {
+ flags |= FNM_LEADING_DIR;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if (t->result == 0 && !(flags & FNM_CASEFOLD)) {
+ flags |= FNM_CASEFOLD;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ if (strchr(t->pattern, '\\') == NULL &&
+ t->result == 0 &&
+ !(flags & (FNM_NOESCAPE | FNM_CASEFOLD))) {
+ flags |= FNM_NOESCAPE | FNM_CASEFOLD;
+ result = fnmatch(t->pattern, t->string, flags);
+ if (result != t->result)
+ break;
+ flags = t->flags;
+ extra++;
+ }
+ } while (0);
+ if (result == t->result)
+ printf("ok %zu - fnmatch(\"%s\", \"%s\", %s) = %d (+%d)\n",
+ i + 1, t->pattern, t->string,
+ flags_to_string(flags),
+ result, extra);
+ else {
+ printf("not ok %zu - fnmatch(\"%s\", \"%s\", %s) = %d != %d\n",
+ i + 1, t->pattern, t->string,
+ flags_to_string(flags),
+ result, t->result);
+ errors = 1;
+ }
+ }
+
+ return (errors);
+}
diff --git a/tools/regression/lib/libc/resolv/resolv.c b/tools/regression/lib/libc/resolv/resolv.c
index dc925d3..c61d02e 100644
--- a/tools/regression/lib/libc/resolv/resolv.c
+++ b/tools/regression/lib/libc/resolv/resolv.c
@@ -15,13 +15,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/mqueue/mqtest1/mqtest1.c b/tools/regression/mqueue/mqtest1/mqtest1.c
index 8551b9f..25fc1ba 100644
--- a/tools/regression/mqueue/mqtest1/mqtest1.c
+++ b/tools/regression/mqueue/mqtest1/mqtest1.c
@@ -1,10 +1,11 @@
/* $FreeBSD$ */
-#include <stdio.h>
-#include <mqueue.h>
+#include <err.h>
+#include <errno.h>
#include <fcntl.h>
+#include <mqueue.h>
#include <signal.h>
-#include <errno.h>
+#include <stdio.h>
#define MQNAME "/mytstqueue1"
diff --git a/tools/regression/mqueue/mqtest2/mqtest2.c b/tools/regression/mqueue/mqtest2/mqtest2.c
index f37af20..bfe6d97 100644
--- a/tools/regression/mqueue/mqtest2/mqtest2.c
+++ b/tools/regression/mqueue/mqtest2/mqtest2.c
@@ -1,8 +1,13 @@
/* $FreeBSD$ */
-#include <stdio.h>
-#include <mqueue.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <err.h>
#include <fcntl.h>
+#include <mqueue.h>
#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#define MQNAME "/mytstqueue2"
diff --git a/tools/regression/mqueue/mqtest3/mqtest3.c b/tools/regression/mqueue/mqtest3/mqtest3.c
index e2d8a9e..aa47ffa 100644
--- a/tools/regression/mqueue/mqtest3/mqtest3.c
+++ b/tools/regression/mqueue/mqtest3/mqtest3.c
@@ -1,10 +1,15 @@
/* $FreeBSD$ */
-#include <stdio.h>
-#include <mqueue.h>
+
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <err.h>
#include <fcntl.h>
+#include <mqueue.h>
#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
-#include <sys/select.h>
#define MQNAME "/mytstqueue3"
#define LOOPS 1000
diff --git a/tools/regression/mqueue/mqtest4/mqtest4.c b/tools/regression/mqueue/mqtest4/mqtest4.c
index a49c210..80a7f88 100644
--- a/tools/regression/mqueue/mqtest4/mqtest4.c
+++ b/tools/regression/mqueue/mqtest4/mqtest4.c
@@ -1,11 +1,16 @@
/* $FreeBSD$ */
-#include <stdio.h>
-#include <mqueue.h>
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <err.h>
#include <fcntl.h>
+#include <mqueue.h>
#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
-#include <sys/select.h>
-#include <sys/event.h>
#define MQNAME "/mytstqueue4"
#define LOOPS 1000
diff --git a/tools/regression/mqueue/mqtest5/mqtest5.c b/tools/regression/mqueue/mqtest5/mqtest5.c
index adf54dc..354a7bb 100644
--- a/tools/regression/mqueue/mqtest5/mqtest5.c
+++ b/tools/regression/mqueue/mqtest5/mqtest5.c
@@ -1,12 +1,16 @@
/* $FreeBSD$ */
-#include <stdio.h>
-#include <mqueue.h>
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <err.h>
#include <fcntl.h>
+#include <mqueue.h>
#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
-#include <sys/select.h>
-#include <sys/event.h>
-#include <signal.h>
#define MQNAME "/mytstqueue5"
#define LOOPS 1000
diff --git a/tools/regression/posixsem/posixsem.c b/tools/regression/posixsem/posixsem.c
index 465d6e7..6401b5c 100644
--- a/tools/regression/posixsem/posixsem.c
+++ b/tools/regression/posixsem/posixsem.c
@@ -1239,7 +1239,8 @@ exhaust_unnamed_sems(void)
return;
}
- if (child_worker(exhaust_unnamed_child, (void *)nsems_max, &stat))
+ if (child_worker(exhaust_unnamed_child, (void *)(uintptr_t)nsems_max,
+ &stat))
return;
errno = CSTAT_ERROR(stat);
switch (CSTAT_CLASS(stat)) {
@@ -1293,7 +1294,8 @@ exhaust_named_sems(void)
return;
}
- if (child_worker(exhaust_named_child, (void *)nsems_max, &stat) < 0)
+ if (child_worker(exhaust_named_child, (void *)(uintptr_t)nsems_max,
+ &stat) < 0)
return;
errno = CSTAT_ERROR(stat);
switch (CSTAT_CLASS(stat)) {
@@ -1351,7 +1353,8 @@ fdlimit_unnamed_sems(void)
int nsems_max, stat;
nsems_max = 10;
- if (child_worker(fdlimit_unnamed_child, (void *)nsems_max, &stat))
+ if (child_worker(fdlimit_unnamed_child, (void *)(uintptr_t)nsems_max,
+ &stat))
return;
errno = CSTAT_ERROR(stat);
switch (CSTAT_CLASS(stat)) {
@@ -1395,7 +1398,8 @@ fdlimit_named_sems(void)
int i, nsems_max, stat;
nsems_max = 10;
- if (child_worker(fdlimit_named_child, (void *)nsems_max, &stat) < 0)
+ if (child_worker(fdlimit_named_child, (void *)(uintptr_t)nsems_max,
+ &stat) < 0)
return;
errno = CSTAT_ERROR(stat);
switch (CSTAT_CLASS(stat)) {
diff --git a/tools/regression/posixsem2/semtest.c b/tools/regression/posixsem2/semtest.c
index befc7c5..b1255db 100644
--- a/tools/regression/posixsem2/semtest.c
+++ b/tools/regression/posixsem2/semtest.c
@@ -65,7 +65,8 @@ test_named(void)
if (s2 == SEM_FAILED)
err(2, "second sem_open call failed");
if (s != s2)
- err(3, "two sem_open calls for same semaphore do not returm same address.");
+ errx(3,
+"two sem_open calls for same semaphore do not return same address");
if (sem_close(s2))
err(4, "sem_close failed");
if ((pid = fork()) == 0) {
diff --git a/tools/regression/priv/Makefile b/tools/regression/priv/Makefile
index 814f5c3..663d68d 100644
--- a/tools/regression/priv/Makefile
+++ b/tools/regression/priv/Makefile
@@ -46,7 +46,7 @@ SRCS= main.c \
priv_vm_munlock.c
NO_MAN=
-WARNS= 3
+WARNS?= 3
DPADD+= ${LIBIPSEC}
LDADD+= -lipsec
diff --git a/tools/regression/sockets/unix_gc/Makefile b/tools/regression/sockets/unix_gc/Makefile
index 1e2fd56..d791494 100644
--- a/tools/regression/sockets/unix_gc/Makefile
+++ b/tools/regression/sockets/unix_gc/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG= unix_gc
-WARNS= 3
NO_MAN=
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/tools/regression/sockets/unix_sorflush/Makefile b/tools/regression/sockets/unix_sorflush/Makefile
index 7f0b9f1..96e48cf 100644
--- a/tools/regression/sockets/unix_sorflush/Makefile
+++ b/tools/regression/sockets/unix_sorflush/Makefile
@@ -2,6 +2,6 @@
PROG= unix_sorflush
NO_MAN=
-WARNS= 3
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/tools/regression/sysvmsg/msgtest.c b/tools/regression/sysvmsg/msgtest.c
index 9aff817..462dc38 100644
--- a/tools/regression/sysvmsg/msgtest.c
+++ b/tools/regression/sysvmsg/msgtest.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/sysvsem/semtest.c b/tools/regression/sysvsem/semtest.c
index 83f73e9..b6859bf 100644
--- a/tools/regression/sysvsem/semtest.c
+++ b/tools/regression/sysvsem/semtest.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/sysvshm/shmtest.c b/tools/regression/sysvshm/shmtest.c
index 22f626e..9e5ab1c 100644
--- a/tools/regression/sysvshm/shmtest.c
+++ b/tools/regression/sysvshm/shmtest.c
@@ -14,13 +14,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/Makefile b/tools/regression/tmpfs/Makefile
index 91e1392..f96ba18 100644
--- a/tools/regression/tmpfs/Makefile
+++ b/tools/regression/tmpfs/Makefile
@@ -31,7 +31,7 @@ regress: ${tests}
PROG= h_tools
NO_MAN= # defined
-WARNS= 4
+WARNS?= 4
t_sizes t_sockets t_statvfs: h_tools
diff --git a/tools/regression/tmpfs/h_funcs.subr b/tools/regression/tmpfs/h_funcs.subr
index 22c9de3..3d6eb4fe 100644
--- a/tools/regression/tmpfs/h_funcs.subr
+++ b/tools/regression/tmpfs/h_funcs.subr
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/h_tools.c b/tools/regression/tmpfs/h_tools.c
index 6e8a236..6f3b87f 100644
--- a/tools/regression/tmpfs/h_tools.c
+++ b/tools/regression/tmpfs/h_tools.c
@@ -16,13 +16,6 @@
* 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 the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_create b/tools/regression/tmpfs/t_create
index 39ea4f4..1a63582 100644
--- a/tools/regression/tmpfs/t_create
+++ b/tools/regression/tmpfs/t_create
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_dots b/tools/regression/tmpfs/t_dots
index 80d721a..6282ad6 100644
--- a/tools/regression/tmpfs/t_dots
+++ b/tools/regression/tmpfs/t_dots
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_exec b/tools/regression/tmpfs/t_exec
index cb1e239..95939cd 100644
--- a/tools/regression/tmpfs/t_exec
+++ b/tools/regression/tmpfs/t_exec
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_link b/tools/regression/tmpfs/t_link
index bf57ec5..640391c 100644
--- a/tools/regression/tmpfs/t_link
+++ b/tools/regression/tmpfs/t_link
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_mkdir b/tools/regression/tmpfs/t_mkdir
index 7a91961..5c4b6d4 100644
--- a/tools/regression/tmpfs/t_mkdir
+++ b/tools/regression/tmpfs/t_mkdir
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_mount b/tools/regression/tmpfs/t_mount
index c5deaf7..318d892 100644
--- a/tools/regression/tmpfs/t_mount
+++ b/tools/regression/tmpfs/t_mount
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_pipes b/tools/regression/tmpfs/t_pipes
index 00da567..c1a6201 100644
--- a/tools/regression/tmpfs/t_pipes
+++ b/tools/regression/tmpfs/t_pipes
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_read_write b/tools/regression/tmpfs/t_read_write
index 42759e0..d2e997d 100644
--- a/tools/regression/tmpfs/t_read_write
+++ b/tools/regression/tmpfs/t_read_write
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_readdir b/tools/regression/tmpfs/t_readdir
index 73cb578..c6e8d26 100644
--- a/tools/regression/tmpfs/t_readdir
+++ b/tools/regression/tmpfs/t_readdir
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_remove b/tools/regression/tmpfs/t_remove
index 80b8986..e54e105 100644
--- a/tools/regression/tmpfs/t_remove
+++ b/tools/regression/tmpfs/t_remove
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_rename b/tools/regression/tmpfs/t_rename
index 0dbc0b0..af81a5c 100644
--- a/tools/regression/tmpfs/t_rename
+++ b/tools/regression/tmpfs/t_rename
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_rmdir b/tools/regression/tmpfs/t_rmdir
index 0cb92d8..860fdb2 100644
--- a/tools/regression/tmpfs/t_rmdir
+++ b/tools/regression/tmpfs/t_rmdir
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_setattr b/tools/regression/tmpfs/t_setattr
index b38ad88e..a25015a 100644
--- a/tools/regression/tmpfs/t_setattr
+++ b/tools/regression/tmpfs/t_setattr
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_sizes b/tools/regression/tmpfs/t_sizes
index 890ac15..6623ee5 100644
--- a/tools/regression/tmpfs/t_sizes
+++ b/tools/regression/tmpfs/t_sizes
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_sockets b/tools/regression/tmpfs/t_sockets
index 6d8e58d..24f9844 100644
--- a/tools/regression/tmpfs/t_sockets
+++ b/tools/regression/tmpfs/t_sockets
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_statvfs b/tools/regression/tmpfs/t_statvfs
index 937e72d..98eb80c 100644
--- a/tools/regression/tmpfs/t_statvfs
+++ b/tools/regression/tmpfs/t_statvfs
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_symlink b/tools/regression/tmpfs/t_symlink
index 6a5638a..218429d 100644
--- a/tools/regression/tmpfs/t_symlink
+++ b/tools/regression/tmpfs/t_symlink
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_times b/tools/regression/tmpfs/t_times
index 06055b9..11e2014 100644
--- a/tools/regression/tmpfs/t_times
+++ b/tools/regression/tmpfs/t_times
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_trail_slash b/tools/regression/tmpfs/t_trail_slash
index 028dd21..131beb7 100644
--- a/tools/regression/tmpfs/t_trail_slash
+++ b/tools/regression/tmpfs/t_trail_slash
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_truncate b/tools/regression/tmpfs/t_truncate
index c5ff811..74d7e53 100644
--- a/tools/regression/tmpfs/t_truncate
+++ b/tools/regression/tmpfs/t_truncate
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_vnd b/tools/regression/tmpfs/t_vnd
index 54e51ba..7065a3d 100644
--- a/tools/regression/tmpfs/t_vnd
+++ b/tools/regression/tmpfs/t_vnd
@@ -16,13 +16,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/tmpfs/t_vnode_leak b/tools/regression/tmpfs/t_vnode_leak
index 7f6b2f9..e71a57c 100644
--- a/tools/regression/tmpfs/t_vnode_leak
+++ b/tools/regression/tmpfs/t_vnode_leak
@@ -17,13 +17,6 @@
# 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 the NetBSD
-# Foundation, Inc. and its contributors.
-# 4. Neither the name of The NetBSD Foundation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/tools/regression/usr.bin/Makefile b/tools/regression/usr.bin/Makefile
index 364741b..7538f23 100644
--- a/tools/regression/usr.bin/Makefile
+++ b/tools/regression/usr.bin/Makefile
@@ -1,6 +1,7 @@
# $FreeBSD$
-SUBDIR= calendar comm file2c join jot m4 printf sed tr uudecode uuencode xargs
+SUBDIR= apply calendar comm file2c join jot m4 ncal printf sed tr \
+ uudecode uuencode xargs
.if !defined(AUTOMATED)
SUBDIR+= lastcomm
.endif
diff --git a/tools/regression/usr.bin/apply/Makefile b/tools/regression/usr.bin/apply/Makefile
new file mode 100644
index 0000000..b937d41
--- /dev/null
+++ b/tools/regression/usr.bin/apply/Makefile
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+all:
+ @m4 ${.CURDIR}/../regress.m4 ${.CURDIR}/regress.sh | sh /dev/stdin ${.CURDIR}
diff --git a/tools/regression/usr.bin/apply/regress.00.in b/tools/regression/usr.bin/apply/regress.00.in
new file mode 100644
index 0000000..8282be7
--- /dev/null
+++ b/tools/regression/usr.bin/apply/regress.00.in
@@ -0,0 +1 @@
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
diff --git a/tools/regression/usr.bin/apply/regress.00.out b/tools/regression/usr.bin/apply/regress.00.out
new file mode 100644
index 0000000..c725cb2
--- /dev/null
+++ b/tools/regression/usr.bin/apply/regress.00.out
@@ -0,0 +1 @@
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
diff --git a/tools/regression/usr.bin/apply/regress.01.out b/tools/regression/usr.bin/apply/regress.01.out
new file mode 100644
index 0000000..bcf5ab2
--- /dev/null
+++ b/tools/regression/usr.bin/apply/regress.01.out
@@ -0,0 +1 @@
+apply: Argument list too long
diff --git a/tools/regression/usr.bin/apply/regress.01.sh b/tools/regression/usr.bin/apply/regress.01.sh
new file mode 100644
index 0000000..db5f1d4
--- /dev/null
+++ b/tools/regression/usr.bin/apply/regress.01.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+SHELL=/bin/sh; export SHELL
+
+ARG_MAX=$(getconf ARG_MAX)
+ARG_MAX_HALF=$((ARG_MAX / 2))
+
+apply 'echo %1 %1 %1' $(jot $ARG_MAX_HALF 1 1 | tr -d '\n') 2>&1
+
+if [ $? -eq 0 ]; then
+ return 1
+else
+ return 0
+fi
diff --git a/tools/regression/usr.bin/apply/regress.sh b/tools/regression/usr.bin/apply/regress.sh
new file mode 100644
index 0000000..7cbaae3
--- /dev/null
+++ b/tools/regression/usr.bin/apply/regress.sh
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+echo 1..2
+
+REGRESSION_START($1)
+
+REGRESSION_TEST(`00', `apply "echo %1 %1 %1 %1" $(cat regress.00.in)')
+REGRESSION_TEST(`01', `sh regress.01.sh')
+
+REGRESSION_END()
diff --git a/tools/regression/usr.bin/apply/regress.t b/tools/regression/usr.bin/apply/regress.t
new file mode 100644
index 0000000..a82aacd
--- /dev/null
+++ b/tools/regression/usr.bin/apply/regress.t
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+m4 ../regress.m4 regress.sh | sh
diff --git a/tools/regression/usr.bin/ncal/Makefile b/tools/regression/usr.bin/ncal/Makefile
new file mode 100644
index 0000000..b937d41
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/Makefile
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+all:
+ @m4 ${.CURDIR}/../regress.m4 ${.CURDIR}/regress.sh | sh /dev/stdin ${.CURDIR}
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200901-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200901-jd-nhl.out
new file mode 100644
index 0000000..65d3619
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200901-jd-nhl.out
@@ -0,0 +1,17 @@
+ December 2008 January 2009
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 336 337 338 339 340 341 1 2 3
+342 343 344 345 346 347 348 4 5 6 7 8 9 10
+349 350 351 352 353 354 355 11 12 13 14 15 16 17
+356 357 358 359 360 361 362 18 19 20 21 22 23 24
+363 364 365 366 25 26 27 28 29 30 31
+
+
+ February 2009
+ Su Mo Tu We Th Fr Sa
+ 32 33 34 35 36 37 38
+ 39 40 41 42 43 44 45
+ 46 47 48 49 50 51 52
+ 53 54 55 56 57 58 59
+
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200901-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200901-md-nhl.out
new file mode 100644
index 0000000..afbdde1
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200901-md-nhl.out
@@ -0,0 +1,8 @@
+ December 2008 January 2009 February 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7
+ 7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14
+14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21
+21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28
+28 29 30 31 25 26 27 28 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200902-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200902-jd-nhl.out
new file mode 100644
index 0000000..33f614d
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200902-jd-nhl.out
@@ -0,0 +1,18 @@
+ 2009
+ January February
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 32 33 34 35 36 37 38
+ 4 5 6 7 8 9 10 39 40 41 42 43 44 45
+ 11 12 13 14 15 16 17 46 47 48 49 50 51 52
+ 18 19 20 21 22 23 24 53 54 55 56 57 58 59
+ 25 26 27 28 29 30 31
+
+
+ March
+ Su Mo Tu We Th Fr Sa
+ 60 61 62 63 64 65 66
+ 67 68 69 70 71 72 73
+ 74 75 76 77 78 79 80
+ 81 82 83 84 85 86 87
+ 88 89 90
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200902-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200902-md-nhl.out
new file mode 100644
index 0000000..e81b78e
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200902-md-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ January February March
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7
+ 4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14
+11 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21
+18 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28
+25 26 27 28 29 30 31 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200903-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200903-jd-nhl.out
new file mode 100644
index 0000000..5974cbf
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200903-jd-nhl.out
@@ -0,0 +1,17 @@
+ February 2009 March 2009
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 32 33 34 35 36 37 38 60 61 62 63 64 65 66
+ 39 40 41 42 43 44 45 67 68 69 70 71 72 73
+ 46 47 48 49 50 51 52 74 75 76 77 78 79 80
+ 53 54 55 56 57 58 59 81 82 83 84 85 86 87
+ 88 89 90
+
+
+ April 2009
+ Su Mo Tu We Th Fr Sa
+ 91 92 93 94
+ 95 96 97 98 99 100 101
+102 103 104 105 106 107 108
+109 110 111 112 113 114 115
+116 117 118 119 120
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200903-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200903-md-nhl.out
new file mode 100644
index 0000000..4e9f0eb
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200903-md-nhl.out
@@ -0,0 +1,8 @@
+ February 2009 March 2009 April 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4
+ 8 9 10 11 12 13 14 8 9 10 11 12 13 14 5 6 7 8 9 10 11
+15 16 17 18 19 20 21 15 16 17 18 19 20 21 12 13 14 15 16 17 18
+22 23 24 25 26 27 28 22 23 24 25 26 27 28 19 20 21 22 23 24 25
+ 29 30 31 26 27 28 29 30
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200904-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200904-jd-nhl.out
new file mode 100644
index 0000000..d559f32
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200904-jd-nhl.out
@@ -0,0 +1,18 @@
+ 2009
+ March April
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 60 61 62 63 64 65 66 91 92 93 94
+ 67 68 69 70 71 72 73 95 96 97 98 99 100 101
+ 74 75 76 77 78 79 80 102 103 104 105 106 107 108
+ 81 82 83 84 85 86 87 109 110 111 112 113 114 115
+ 88 89 90 116 117 118 119 120
+
+
+ May
+ Su Mo Tu We Th Fr Sa
+ 121 122
+123 124 125 126 127 128 129
+130 131 132 133 134 135 136
+137 138 139 140 141 142 143
+144 145 146 147 148 149 150
+151
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200904-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200904-md-nhl.out
new file mode 100644
index 0000000..0df9a75
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200904-md-nhl.out
@@ -0,0 +1,8 @@
+ March 2009 April 2009 May 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6 7 1 2 3 4 1 2
+ 8 9 10 11 12 13 14 5 6 7 8 9 10 11 3 4 5 6 7 8 9
+15 16 17 18 19 20 21 12 13 14 15 16 17 18 10 11 12 13 14 15 16
+22 23 24 25 26 27 28 19 20 21 22 23 24 25 17 18 19 20 21 22 23
+29 30 31 26 27 28 29 30 24 25 26 27 28 29 30
+ 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200905-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200905-jd-nhl.out
new file mode 100644
index 0000000..35d9c2b
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200905-jd-nhl.out
@@ -0,0 +1,17 @@
+ April 2009 May 2009
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 91 92 93 94 121 122
+ 95 96 97 98 99 100 101 123 124 125 126 127 128 129
+102 103 104 105 106 107 108 130 131 132 133 134 135 136
+109 110 111 112 113 114 115 137 138 139 140 141 142 143
+116 117 118 119 120 144 145 146 147 148 149 150
+ 151
+
+ June 2009
+ Su Mo Tu We Th Fr Sa
+ 152 153 154 155 156 157
+158 159 160 161 162 163 164
+165 166 167 168 169 170 171
+172 173 174 175 176 177 178
+179 180 181
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200905-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200905-md-nhl.out
new file mode 100644
index 0000000..3ee495d
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200905-md-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ April May June
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 1 2 1 2 3 4 5 6
+ 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
+12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
+19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
+26 27 28 29 30 24 25 26 27 28 29 30 28 29 30
+ 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200906-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200906-jd-nhl.out
new file mode 100644
index 0000000..47f95b0
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200906-jd-nhl.out
@@ -0,0 +1,18 @@
+ 2009
+ May June
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 121 122 152 153 154 155 156 157
+123 124 125 126 127 128 129 158 159 160 161 162 163 164
+130 131 132 133 134 135 136 165 166 167 168 169 170 171
+137 138 139 140 141 142 143 172 173 174 175 176 177 178
+144 145 146 147 148 149 150 179 180 181
+151
+
+ July
+ Su Mo Tu We Th Fr Sa
+ 182 183 184 185
+186 187 188 189 190 191 192
+193 194 195 196 197 198 199
+200 201 202 203 204 205 206
+207 208 209 210 211 212
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200906-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200906-md-nhl.out
new file mode 100644
index 0000000..a6c1dcd
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200906-md-nhl.out
@@ -0,0 +1,8 @@
+ May 2009 June 2009 July 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 2 3 4 5 6 1 2 3 4
+ 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11
+10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18
+17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25
+24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31
+31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200907-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200907-jd-nhl.out
new file mode 100644
index 0000000..9d96208
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200907-jd-nhl.out
@@ -0,0 +1,17 @@
+ June 2009 July 2009
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 152 153 154 155 156 157 182 183 184 185
+158 159 160 161 162 163 164 186 187 188 189 190 191 192
+165 166 167 168 169 170 171 193 194 195 196 197 198 199
+172 173 174 175 176 177 178 200 201 202 203 204 205 206
+179 180 181 207 208 209 210 211 212
+
+
+ August 2009
+ Su Mo Tu We Th Fr Sa
+ 213
+214 215 216 217 218 219 220
+221 222 223 224 225 226 227
+228 229 230 231 232 233 234
+235 236 237 238 239 240 241
+242 243
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200907-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200907-md-nhl.out
new file mode 100644
index 0000000..9b762e2
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200907-md-nhl.out
@@ -0,0 +1,8 @@
+ June 2009 July 2009 August 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6 1 2 3 4 1
+ 7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
+14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
+21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
+28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
+ 30 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200908-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200908-jd-nhl.out
new file mode 100644
index 0000000..768de3f
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200908-jd-nhl.out
@@ -0,0 +1,18 @@
+ 2009
+ July August
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 182 183 184 185 213
+186 187 188 189 190 191 192 214 215 216 217 218 219 220
+193 194 195 196 197 198 199 221 222 223 224 225 226 227
+200 201 202 203 204 205 206 228 229 230 231 232 233 234
+207 208 209 210 211 212 235 236 237 238 239 240 241
+ 242 243
+
+ September
+ Su Mo Tu We Th Fr Sa
+ 244 245 246 247 248
+249 250 251 252 253 254 255
+256 257 258 259 260 261 262
+263 264 265 266 267 268 269
+270 271 272 273
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200908-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200908-md-nhl.out
new file mode 100644
index 0000000..339870e
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200908-md-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ July August September
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 1 1 2 3 4 5
+ 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
+12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
+19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
+26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
+ 30 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200909-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200909-jd-nhl.out
new file mode 100644
index 0000000..befa00d
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200909-jd-nhl.out
@@ -0,0 +1,17 @@
+ August 2009 September 2009
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 213 244 245 246 247 248
+214 215 216 217 218 219 220 249 250 251 252 253 254 255
+221 222 223 224 225 226 227 256 257 258 259 260 261 262
+228 229 230 231 232 233 234 263 264 265 266 267 268 269
+235 236 237 238 239 240 241 270 271 272 273
+242 243
+
+ October 2009
+ Su Mo Tu We Th Fr Sa
+ 274 275 276
+277 278 279 280 281 282 283
+284 285 286 287 288 289 290
+291 292 293 294 295 296 297
+298 299 300 301 302 303 304
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200909-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200909-md-nhl.out
new file mode 100644
index 0000000..4fb2714
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200909-md-nhl.out
@@ -0,0 +1,8 @@
+ August 2009 September 2009 October 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 1 2 3 4 5 1 2 3
+ 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
+ 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
+16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
+23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
+30 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200910-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200910-jd-nhl.out
new file mode 100644
index 0000000..0a29593
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200910-jd-nhl.out
@@ -0,0 +1,18 @@
+ 2009
+ September October
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 244 245 246 247 248 274 275 276
+249 250 251 252 253 254 255 277 278 279 280 281 282 283
+256 257 258 259 260 261 262 284 285 286 287 288 289 290
+263 264 265 266 267 268 269 291 292 293 294 295 296 297
+270 271 272 273 298 299 300 301 302 303 304
+
+
+ November
+ Su Mo Tu We Th Fr Sa
+305 306 307 308 309 310 311
+312 313 314 315 316 317 318
+319 320 321 322 323 324 325
+326 327 328 329 330 331 332
+333 334
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200910-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200910-md-nhl.out
new file mode 100644
index 0000000..29cd67e
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200910-md-nhl.out
@@ -0,0 +1,8 @@
+ September 2009 October 2009 November 2009
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
+ 6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
+13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
+20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
+27 28 29 30 25 26 27 28 29 30 31 29 30
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200911-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200911-jd-nhl.out
new file mode 100644
index 0000000..4969cbc
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200911-jd-nhl.out
@@ -0,0 +1,17 @@
+ October 2009 November 2009
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 274 275 276 305 306 307 308 309 310 311
+277 278 279 280 281 282 283 312 313 314 315 316 317 318
+284 285 286 287 288 289 290 319 320 321 322 323 324 325
+291 292 293 294 295 296 297 326 327 328 329 330 331 332
+298 299 300 301 302 303 304 333 334
+
+
+ December 2009
+ Su Mo Tu We Th Fr Sa
+ 335 336 337 338 339
+340 341 342 343 344 345 346
+347 348 349 350 351 352 353
+354 355 356 357 358 359 360
+361 362 363 364 365
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200911-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200911-md-nhl.out
new file mode 100644
index 0000000..b1f57ff
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200911-md-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ October November December
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
+ 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
+11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
+18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
+25 26 27 28 29 30 31 29 30 27 28 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200912-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200912-jd-nhl.out
new file mode 100644
index 0000000..61480a5
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200912-jd-nhl.out
@@ -0,0 +1,19 @@
+ 2009
+ November December
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+305 306 307 308 309 310 311 335 336 337 338 339
+312 313 314 315 316 317 318 340 341 342 343 344 345 346
+319 320 321 322 323 324 325 347 348 349 350 351 352 353
+326 327 328 329 330 331 332 354 355 356 357 358 359 360
+333 334 361 362 363 364 365
+
+
+ 2010
+ January
+ Su Mo Tu We Th Fr Sa
+ 1 2
+ 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23
+ 24 25 26 27 28 29 30
+ 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-3m200912-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-3m200912-md-nhl.out
new file mode 100644
index 0000000..fd4d220
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-3m200912-md-nhl.out
@@ -0,0 +1,8 @@
+ November 2009 December 2009 January 2010
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6 7 1 2 3 4 5 1 2
+ 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9
+15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16
+22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23
+29 30 27 28 29 30 31 24 25 26 27 28 29 30
+ 31
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2008-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2008-jd-nhl.out
new file mode 100644
index 0000000..cd423db
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2008-jd-nhl.out
@@ -0,0 +1,54 @@
+ 2008
+ January February
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 32 33
+ 6 7 8 9 10 11 12 34 35 36 37 38 39 40
+ 13 14 15 16 17 18 19 41 42 43 44 45 46 47
+ 20 21 22 23 24 25 26 48 49 50 51 52 53 54
+ 27 28 29 30 31 55 56 57 58 59 60
+
+
+ March April
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 61 92 93 94 95 96
+ 62 63 64 65 66 67 68 97 98 99 100 101 102 103
+ 69 70 71 72 73 74 75 104 105 106 107 108 109 110
+ 76 77 78 79 80 81 82 111 112 113 114 115 116 117
+ 83 84 85 86 87 88 89 118 119 120 121
+ 90 91
+
+ May June
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 122 123 124 153 154 155 156 157 158 159
+125 126 127 128 129 130 131 160 161 162 163 164 165 166
+132 133 134 135 136 137 138 167 168 169 170 171 172 173
+139 140 141 142 143 144 145 174 175 176 177 178 179 180
+146 147 148 149 150 151 152 181 182
+
+
+ July August
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 183 184 185 186 187 214 215
+188 189 190 191 192 193 194 216 217 218 219 220 221 222
+195 196 197 198 199 200 201 223 224 225 226 227 228 229
+202 203 204 205 206 207 208 230 231 232 233 234 235 236
+209 210 211 212 213 237 238 239 240 241 242 243
+ 244
+
+ September October
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 245 246 247 248 249 250 275 276 277 278
+251 252 253 254 255 256 257 279 280 281 282 283 284 285
+258 259 260 261 262 263 264 286 287 288 289 290 291 292
+265 266 267 268 269 270 271 293 294 295 296 297 298 299
+272 273 274 300 301 302 303 304 305
+
+
+ November December
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 306 336 337 338 339 340 341
+307 308 309 310 311 312 313 342 343 344 345 346 347 348
+314 315 316 317 318 319 320 349 350 351 352 353 354 355
+321 322 323 324 325 326 327 356 357 358 359 360 361 362
+328 329 330 331 332 333 334 363 364 365 366
+335
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2008-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2008-md-nhl.out
new file mode 100644
index 0000000..dcd96fc
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2008-md-nhl.out
@@ -0,0 +1,36 @@
+ 2008
+ January February March
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 1 2 1
+ 6 7 8 9 10 11 12 3 4 5 6 7 8 9 2 3 4 5 6 7 8
+13 14 15 16 17 18 19 10 11 12 13 14 15 16 9 10 11 12 13 14 15
+20 21 22 23 24 25 26 17 18 19 20 21 22 23 16 17 18 19 20 21 22
+27 28 29 30 31 24 25 26 27 28 29 23 24 25 26 27 28 29
+ 30 31
+
+ April May June
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
+ 6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
+13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
+20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
+27 28 29 30 25 26 27 28 29 30 31 29 30
+
+
+ July August September
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 1 2 1 2 3 4 5 6
+ 6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13
+13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20
+20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
+27 28 29 30 31 24 25 26 27 28 29 30 28 29 30
+ 31
+
+ October November December
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 1 1 2 3 4 5 6
+ 5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
+12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
+19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
+26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
+ 30
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2009-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2009-jd-nhl.out
new file mode 100644
index 0000000..db22d05
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2009-jd-nhl.out
@@ -0,0 +1,54 @@
+ 2009
+ January February
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 32 33 34 35 36 37 38
+ 4 5 6 7 8 9 10 39 40 41 42 43 44 45
+ 11 12 13 14 15 16 17 46 47 48 49 50 51 52
+ 18 19 20 21 22 23 24 53 54 55 56 57 58 59
+ 25 26 27 28 29 30 31
+
+
+ March April
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 60 61 62 63 64 65 66 91 92 93 94
+ 67 68 69 70 71 72 73 95 96 97 98 99 100 101
+ 74 75 76 77 78 79 80 102 103 104 105 106 107 108
+ 81 82 83 84 85 86 87 109 110 111 112 113 114 115
+ 88 89 90 116 117 118 119 120
+
+
+ May June
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 121 122 152 153 154 155 156 157
+123 124 125 126 127 128 129 158 159 160 161 162 163 164
+130 131 132 133 134 135 136 165 166 167 168 169 170 171
+137 138 139 140 141 142 143 172 173 174 175 176 177 178
+144 145 146 147 148 149 150 179 180 181
+151
+
+ July August
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 182 183 184 185 213
+186 187 188 189 190 191 192 214 215 216 217 218 219 220
+193 194 195 196 197 198 199 221 222 223 224 225 226 227
+200 201 202 203 204 205 206 228 229 230 231 232 233 234
+207 208 209 210 211 212 235 236 237 238 239 240 241
+ 242 243
+
+ September October
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 244 245 246 247 248 274 275 276
+249 250 251 252 253 254 255 277 278 279 280 281 282 283
+256 257 258 259 260 261 262 284 285 286 287 288 289 290
+263 264 265 266 267 268 269 291 292 293 294 295 296 297
+270 271 272 273 298 299 300 301 302 303 304
+
+
+ November December
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+305 306 307 308 309 310 311 335 336 337 338 339
+312 313 314 315 316 317 318 340 341 342 343 344 345 346
+319 320 321 322 323 324 325 347 348 349 350 351 352 353
+326 327 328 329 330 331 332 354 355 356 357 358 359 360
+333 334 361 362 363 364 365
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2009-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2009-md-nhl.out
new file mode 100644
index 0000000..c9f084e
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2009-md-nhl.out
@@ -0,0 +1,36 @@
+ 2009
+ January February March
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7
+ 4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14
+11 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21
+18 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28
+25 26 27 28 29 30 31 29 30 31
+
+
+ April May June
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 1 2 1 2 3 4 5 6
+ 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
+12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
+19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
+26 27 28 29 30 24 25 26 27 28 29 30 28 29 30
+ 31
+
+ July August September
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 4 1 1 2 3 4 5
+ 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
+12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
+19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
+26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
+ 30 31
+
+ October November December
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
+ 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
+11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
+18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
+25 26 27 28 29 30 31 29 30 27 28 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2010-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2010-jd-nhl.out
new file mode 100644
index 0000000..d7ad9fc
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2010-jd-nhl.out
@@ -0,0 +1,54 @@
+ 2010
+ January February
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 32 33 34 35 36 37
+ 3 4 5 6 7 8 9 38 39 40 41 42 43 44
+ 10 11 12 13 14 15 16 45 46 47 48 49 50 51
+ 17 18 19 20 21 22 23 52 53 54 55 56 57 58
+ 24 25 26 27 28 29 30 59
+ 31
+
+ March April
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 60 61 62 63 64 65 91 92 93
+ 66 67 68 69 70 71 72 94 95 96 97 98 99 100
+ 73 74 75 76 77 78 79 101 102 103 104 105 106 107
+ 80 81 82 83 84 85 86 108 109 110 111 112 113 114
+ 87 88 89 90 115 116 117 118 119 120
+
+
+ May June
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 121 152 153 154 155 156
+122 123 124 125 126 127 128 157 158 159 160 161 162 163
+129 130 131 132 133 134 135 164 165 166 167 168 169 170
+136 137 138 139 140 141 142 171 172 173 174 175 176 177
+143 144 145 146 147 148 149 178 179 180 181
+150 151
+
+ July August
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 182 183 184 213 214 215 216 217 218 219
+185 186 187 188 189 190 191 220 221 222 223 224 225 226
+192 193 194 195 196 197 198 227 228 229 230 231 232 233
+199 200 201 202 203 204 205 234 235 236 237 238 239 240
+206 207 208 209 210 211 212 241 242 243
+
+
+ September October
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 244 245 246 247 274 275
+248 249 250 251 252 253 254 276 277 278 279 280 281 282
+255 256 257 258 259 260 261 283 284 285 286 287 288 289
+262 263 264 265 266 267 268 290 291 292 293 294 295 296
+269 270 271 272 273 297 298 299 300 301 302 303
+ 304
+
+ November December
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 305 306 307 308 309 310 335 336 337 338
+311 312 313 314 315 316 317 339 340 341 342 343 344 345
+318 319 320 321 322 323 324 346 347 348 349 350 351 352
+325 326 327 328 329 330 331 353 354 355 356 357 358 359
+332 333 334 360 361 362 363 364 365
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2010-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2010-md-nhl.out
new file mode 100644
index 0000000..1d8a410
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2010-md-nhl.out
@@ -0,0 +1,36 @@
+ 2010
+ January February March
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 2 3 4 5 6 1 2 3 4 5 6
+ 3 4 5 6 7 8 9 7 8 9 10 11 12 13 7 8 9 10 11 12 13
+10 11 12 13 14 15 16 14 15 16 17 18 19 20 14 15 16 17 18 19 20
+17 18 19 20 21 22 23 21 22 23 24 25 26 27 21 22 23 24 25 26 27
+24 25 26 27 28 29 30 28 28 29 30 31
+31
+
+ April May June
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 1 1 2 3 4 5
+ 4 5 6 7 8 9 10 2 3 4 5 6 7 8 6 7 8 9 10 11 12
+11 12 13 14 15 16 17 9 10 11 12 13 14 15 13 14 15 16 17 18 19
+18 19 20 21 22 23 24 16 17 18 19 20 21 22 20 21 22 23 24 25 26
+25 26 27 28 29 30 23 24 25 26 27 28 29 27 28 29 30
+ 30 31
+
+ July August September
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 3 1 2 3 4 5 6 7 1 2 3 4
+ 4 5 6 7 8 9 10 8 9 10 11 12 13 14 5 6 7 8 9 10 11
+11 12 13 14 15 16 17 15 16 17 18 19 20 21 12 13 14 15 16 17 18
+18 19 20 21 22 23 24 22 23 24 25 26 27 28 19 20 21 22 23 24 25
+25 26 27 28 29 30 31 29 30 31 26 27 28 29 30
+
+
+ October November December
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 2 3 4 5 6 1 2 3 4
+ 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11
+10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18
+17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25
+24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31
+31
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2011-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2011-jd-nhl.out
new file mode 100644
index 0000000..31abb4e
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2011-jd-nhl.out
@@ -0,0 +1,54 @@
+ 2011
+ January February
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 32 33 34 35 36
+ 2 3 4 5 6 7 8 37 38 39 40 41 42 43
+ 9 10 11 12 13 14 15 44 45 46 47 48 49 50
+ 16 17 18 19 20 21 22 51 52 53 54 55 56 57
+ 23 24 25 26 27 28 29 58 59
+ 30 31
+
+ March April
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 60 61 62 63 64 91 92
+ 65 66 67 68 69 70 71 93 94 95 96 97 98 99
+ 72 73 74 75 76 77 78 100 101 102 103 104 105 106
+ 79 80 81 82 83 84 85 107 108 109 110 111 112 113
+ 86 87 88 89 90 114 115 116 117 118 119 120
+
+
+ May June
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+121 122 123 124 125 126 127 152 153 154 155
+128 129 130 131 132 133 134 156 157 158 159 160 161 162
+135 136 137 138 139 140 141 163 164 165 166 167 168 169
+142 143 144 145 146 147 148 170 171 172 173 174 175 176
+149 150 151 177 178 179 180 181
+
+
+ July August
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 182 183 213 214 215 216 217 218
+184 185 186 187 188 189 190 219 220 221 222 223 224 225
+191 192 193 194 195 196 197 226 227 228 229 230 231 232
+198 199 200 201 202 203 204 233 234 235 236 237 238 239
+205 206 207 208 209 210 211 240 241 242 243
+212
+
+ September October
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 244 245 246 274
+247 248 249 250 251 252 253 275 276 277 278 279 280 281
+254 255 256 257 258 259 260 282 283 284 285 286 287 288
+261 262 263 264 265 266 267 289 290 291 292 293 294 295
+268 269 270 271 272 273 296 297 298 299 300 301 302
+ 303 304
+
+ November December
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 305 306 307 308 309 335 336 337
+310 311 312 313 314 315 316 338 339 340 341 342 343 344
+317 318 319 320 321 322 323 345 346 347 348 349 350 351
+324 325 326 327 328 329 330 352 353 354 355 356 357 358
+331 332 333 334 359 360 361 362 363 364 365
+
diff --git a/tools/regression/usr.bin/ncal/regress.b-y2011-md-nhl.out b/tools/regression/usr.bin/ncal/regress.b-y2011-md-nhl.out
new file mode 100644
index 0000000..d76a44f
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.b-y2011-md-nhl.out
@@ -0,0 +1,36 @@
+ 2011
+ January February March
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 1 2 3 4 5 1 2 3 4 5
+ 2 3 4 5 6 7 8 6 7 8 9 10 11 12 6 7 8 9 10 11 12
+ 9 10 11 12 13 14 15 13 14 15 16 17 18 19 13 14 15 16 17 18 19
+16 17 18 19 20 21 22 20 21 22 23 24 25 26 20 21 22 23 24 25 26
+23 24 25 26 27 28 29 27 28 27 28 29 30 31
+30 31
+
+ April May June
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 2 3 4 5 6 7 1 2 3 4
+ 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
+10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
+17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
+24 25 26 27 28 29 30 29 30 31 26 27 28 29 30
+
+
+ July August September
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 2 3 4 5 6 1 2 3
+ 3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10
+10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17
+17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24
+24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30
+31
+
+ October November December
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 1 2 3 4 5 1 2 3
+ 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
+ 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
+16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
+23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
+30 31
diff --git a/tools/regression/usr.bin/ncal/regress.f-3A-nhl.out b/tools/regression/usr.bin/ncal/regress.f-3A-nhl.out
new file mode 100644
index 0000000..e7f5e91
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-3A-nhl.out
@@ -0,0 +1 @@
+ncal: -3 together with -A and -B is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-3AB-nhl.out b/tools/regression/usr.bin/ncal/regress.f-3AB-nhl.out
new file mode 100644
index 0000000..e7f5e91
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-3AB-nhl.out
@@ -0,0 +1 @@
+ncal: -3 together with -A and -B is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-3B-nhl.out b/tools/regression/usr.bin/ncal/regress.f-3B-nhl.out
new file mode 100644
index 0000000..e7f5e91
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-3B-nhl.out
@@ -0,0 +1 @@
+ncal: -3 together with -A and -B is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-3gy-nhl.out b/tools/regression/usr.bin/ncal/regress.f-3gy-nhl.out
new file mode 100644
index 0000000..018646f
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-3gy-nhl.out
@@ -0,0 +1 @@
+ncal: -3 together with a given year but no given month is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-3y-nhl.out b/tools/regression/usr.bin/ncal/regress.f-3y-nhl.out
new file mode 100644
index 0000000..5b2e000
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-3y-nhl.out
@@ -0,0 +1 @@
+ncal: -3 together with -y is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-mgm-nhl.out b/tools/regression/usr.bin/ncal/regress.f-mgm-nhl.out
new file mode 100644
index 0000000..5f6c2eb
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-mgm-nhl.out
@@ -0,0 +1 @@
+ncal: -m together with a given month is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-yA-nhl.out b/tools/regression/usr.bin/ncal/regress.f-yA-nhl.out
new file mode 100644
index 0000000..ce39ae7
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-yA-nhl.out
@@ -0,0 +1 @@
+ncal: -y together a -A or -B is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-yAB-nhl.out b/tools/regression/usr.bin/ncal/regress.f-yAB-nhl.out
new file mode 100644
index 0000000..ce39ae7
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-yAB-nhl.out
@@ -0,0 +1 @@
+ncal: -y together a -A or -B is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-yB-nhl.out b/tools/regression/usr.bin/ncal/regress.f-yB-nhl.out
new file mode 100644
index 0000000..ce39ae7
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-yB-nhl.out
@@ -0,0 +1 @@
+ncal: -y together a -A or -B is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-ygm-nhl.out b/tools/regression/usr.bin/ncal/regress.f-ygm-nhl.out
new file mode 100644
index 0000000..6f898eb
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-ygm-nhl.out
@@ -0,0 +1 @@
+ncal: -y together a given month is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.f-ym-nhl.out b/tools/regression/usr.bin/ncal/regress.f-ym-nhl.out
new file mode 100644
index 0000000..1921d92
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.f-ym-nhl.out
@@ -0,0 +1 @@
+ncal: -y together with -m is not supported.
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200901-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200901-jd-nhl.out
new file mode 100644
index 0000000..26ef49b
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200901-jd-nhl.out
@@ -0,0 +1,8 @@
+ December 2008 January 2009 February 2009
+Mo 336 343 350 357 364 5 12 19 26 33 40 47 54
+Tu 337 344 351 358 365 6 13 20 27 34 41 48 55
+We 338 345 352 359 366 7 14 21 28 35 42 49 56
+Th 339 346 353 360 1 8 15 22 29 36 43 50 57
+Fr 340 347 354 361 2 9 16 23 30 37 44 51 58
+Sa 341 348 355 362 3 10 17 24 31 38 45 52 59
+Su 342 349 356 363 4 11 18 25 32 39 46 53
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200901-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200901-md-nhl.out
new file mode 100644
index 0000000..d197fd3
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200901-md-nhl.out
@@ -0,0 +1,8 @@
+ December 2008 January 2009 February 2009
+Mo 1 8 15 22 29 5 12 19 26 2 9 16 23
+Tu 2 9 16 23 30 6 13 20 27 3 10 17 24
+We 3 10 17 24 31 7 14 21 28 4 11 18 25
+Th 4 11 18 25 1 8 15 22 29 5 12 19 26
+Fr 5 12 19 26 2 9 16 23 30 6 13 20 27
+Sa 6 13 20 27 3 10 17 24 31 7 14 21 28
+Su 7 14 21 28 4 11 18 25 1 8 15 22
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200902-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200902-jd-nhl.out
new file mode 100644
index 0000000..cd84869
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200902-jd-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ January February March
+Mo 5 12 19 26 33 40 47 54 61 68 75 82 89
+Tu 6 13 20 27 34 41 48 55 62 69 76 83 90
+We 7 14 21 28 35 42 49 56 63 70 77 84
+Th 1 8 15 22 29 36 43 50 57 64 71 78 85
+Fr 2 9 16 23 30 37 44 51 58 65 72 79 86
+Sa 3 10 17 24 31 38 45 52 59 66 73 80 87
+Su 4 11 18 25 32 39 46 53 60 67 74 81 88
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200902-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200902-md-nhl.out
new file mode 100644
index 0000000..20c35f1
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200902-md-nhl.out
@@ -0,0 +1,8 @@
+ January 2009 February 2009 March 2009
+Mo 5 12 19 26 2 9 16 23 2 9 16 23 30
+Tu 6 13 20 27 3 10 17 24 3 10 17 24 31
+We 7 14 21 28 4 11 18 25 4 11 18 25
+Th 1 8 15 22 29 5 12 19 26 5 12 19 26
+Fr 2 9 16 23 30 6 13 20 27 6 13 20 27
+Sa 3 10 17 24 31 7 14 21 28 7 14 21 28
+Su 4 11 18 25 1 8 15 22 1 8 15 22 29
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200903-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200903-jd-nhl.out
new file mode 100644
index 0000000..1ca28e0
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200903-jd-nhl.out
@@ -0,0 +1,8 @@
+ February 2009 March 2009 April 2009
+Mo 33 40 47 54 61 68 75 82 89 96 103 110 117
+Tu 34 41 48 55 62 69 76 83 90 97 104 111 118
+We 35 42 49 56 63 70 77 84 91 98 105 112 119
+Th 36 43 50 57 64 71 78 85 92 99 106 113 120
+Fr 37 44 51 58 65 72 79 86 93 100 107 114
+Sa 38 45 52 59 66 73 80 87 94 101 108 115
+Su 32 39 46 53 60 67 74 81 88 95 102 109 116
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200903-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200903-md-nhl.out
new file mode 100644
index 0000000..19fc969
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200903-md-nhl.out
@@ -0,0 +1,8 @@
+ February 2009 March 2009 April 2009
+Mo 2 9 16 23 2 9 16 23 30 6 13 20 27
+Tu 3 10 17 24 3 10 17 24 31 7 14 21 28
+We 4 11 18 25 4 11 18 25 1 8 15 22 29
+Th 5 12 19 26 5 12 19 26 2 9 16 23 30
+Fr 6 13 20 27 6 13 20 27 3 10 17 24
+Sa 7 14 21 28 7 14 21 28 4 11 18 25
+Su 1 8 15 22 1 8 15 22 29 5 12 19 26
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200904-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200904-jd-nhl.out
new file mode 100644
index 0000000..8b8e77a
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200904-jd-nhl.out
@@ -0,0 +1,8 @@
+ March 2009 April 2009 May 2009
+Mo 61 68 75 82 89 96 103 110 117 124 131 138 145
+Tu 62 69 76 83 90 97 104 111 118 125 132 139 146
+We 63 70 77 84 91 98 105 112 119 126 133 140 147
+Th 64 71 78 85 92 99 106 113 120 127 134 141 148
+Fr 65 72 79 86 93 100 107 114 121 128 135 142 149
+Sa 66 73 80 87 94 101 108 115 122 129 136 143 150
+Su 60 67 74 81 88 95 102 109 116 123 130 137 144 151
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200904-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200904-md-nhl.out
new file mode 100644
index 0000000..449127c
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200904-md-nhl.out
@@ -0,0 +1,8 @@
+ March 2009 April 2009 May 2009
+Mo 2 9 16 23 30 6 13 20 27 4 11 18 25
+Tu 3 10 17 24 31 7 14 21 28 5 12 19 26
+We 4 11 18 25 1 8 15 22 29 6 13 20 27
+Th 5 12 19 26 2 9 16 23 30 7 14 21 28
+Fr 6 13 20 27 3 10 17 24 1 8 15 22 29
+Sa 7 14 21 28 4 11 18 25 2 9 16 23 30
+Su 1 8 15 22 29 5 12 19 26 3 10 17 24 31
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200905-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200905-jd-nhl.out
new file mode 100644
index 0000000..9054a1f
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200905-jd-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ April May June
+Mo 96 103 110 117 124 131 138 145 152 159 166 173 180
+Tu 97 104 111 118 125 132 139 146 153 160 167 174 181
+We 91 98 105 112 119 126 133 140 147 154 161 168 175
+Th 92 99 106 113 120 127 134 141 148 155 162 169 176
+Fr 93 100 107 114 121 128 135 142 149 156 163 170 177
+Sa 94 101 108 115 122 129 136 143 150 157 164 171 178
+Su 95 102 109 116 123 130 137 144 151 158 165 172 179
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200905-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200905-md-nhl.out
new file mode 100644
index 0000000..4a6a635
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200905-md-nhl.out
@@ -0,0 +1,8 @@
+ April 2009 May 2009 June 2009
+Mo 6 13 20 27 4 11 18 25 1 8 15 22 29
+Tu 7 14 21 28 5 12 19 26 2 9 16 23 30
+We 1 8 15 22 29 6 13 20 27 3 10 17 24
+Th 2 9 16 23 30 7 14 21 28 4 11 18 25
+Fr 3 10 17 24 1 8 15 22 29 5 12 19 26
+Sa 4 11 18 25 2 9 16 23 30 6 13 20 27
+Su 5 12 19 26 3 10 17 24 31 7 14 21 28
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200906-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200906-jd-nhl.out
new file mode 100644
index 0000000..6eb35eb
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200906-jd-nhl.out
@@ -0,0 +1,8 @@
+ May 2009 June 2009 July 2009
+Mo 124 131 138 145 152 159 166 173 180 187 194 201 208
+Tu 125 132 139 146 153 160 167 174 181 188 195 202 209
+We 126 133 140 147 154 161 168 175 182 189 196 203 210
+Th 127 134 141 148 155 162 169 176 183 190 197 204 211
+Fr 121 128 135 142 149 156 163 170 177 184 191 198 205 212
+Sa 122 129 136 143 150 157 164 171 178 185 192 199 206
+Su 123 130 137 144 151 158 165 172 179 186 193 200 207
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200906-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200906-md-nhl.out
new file mode 100644
index 0000000..53f1274
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200906-md-nhl.out
@@ -0,0 +1,8 @@
+ May 2009 June 2009 July 2009
+Mo 4 11 18 25 1 8 15 22 29 6 13 20 27
+Tu 5 12 19 26 2 9 16 23 30 7 14 21 28
+We 6 13 20 27 3 10 17 24 1 8 15 22 29
+Th 7 14 21 28 4 11 18 25 2 9 16 23 30
+Fr 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Sa 2 9 16 23 30 6 13 20 27 4 11 18 25
+Su 3 10 17 24 31 7 14 21 28 5 12 19 26
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200907-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200907-jd-nhl.out
new file mode 100644
index 0000000..8c5701a
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200907-jd-nhl.out
@@ -0,0 +1,8 @@
+ June 2009 July 2009 August 2009
+Mo 152 159 166 173 180 187 194 201 208 215 222 229 236 243
+Tu 153 160 167 174 181 188 195 202 209 216 223 230 237
+We 154 161 168 175 182 189 196 203 210 217 224 231 238
+Th 155 162 169 176 183 190 197 204 211 218 225 232 239
+Fr 156 163 170 177 184 191 198 205 212 219 226 233 240
+Sa 157 164 171 178 185 192 199 206 213 220 227 234 241
+Su 158 165 172 179 186 193 200 207 214 221 228 235 242
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200907-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200907-md-nhl.out
new file mode 100644
index 0000000..f07ea0a
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200907-md-nhl.out
@@ -0,0 +1,8 @@
+ June 2009 July 2009 August 2009
+Mo 1 8 15 22 29 6 13 20 27 3 10 17 24 31
+Tu 2 9 16 23 30 7 14 21 28 4 11 18 25
+We 3 10 17 24 1 8 15 22 29 5 12 19 26
+Th 4 11 18 25 2 9 16 23 30 6 13 20 27
+Fr 5 12 19 26 3 10 17 24 31 7 14 21 28
+Sa 6 13 20 27 4 11 18 25 1 8 15 22 29
+Su 7 14 21 28 5 12 19 26 2 9 16 23 30
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200908-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200908-jd-nhl.out
new file mode 100644
index 0000000..9d50894
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200908-jd-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ July August September
+Mo 187 194 201 208 215 222 229 236 243 250 257 264 271
+Tu 188 195 202 209 216 223 230 237 244 251 258 265 272
+We 182 189 196 203 210 217 224 231 238 245 252 259 266 273
+Th 183 190 197 204 211 218 225 232 239 246 253 260 267
+Fr 184 191 198 205 212 219 226 233 240 247 254 261 268
+Sa 185 192 199 206 213 220 227 234 241 248 255 262 269
+Su 186 193 200 207 214 221 228 235 242 249 256 263 270
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200908-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200908-md-nhl.out
new file mode 100644
index 0000000..e4822eb
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200908-md-nhl.out
@@ -0,0 +1,8 @@
+ July 2009 August 2009 September 2009
+Mo 6 13 20 27 3 10 17 24 31 7 14 21 28
+Tu 7 14 21 28 4 11 18 25 1 8 15 22 29
+We 1 8 15 22 29 5 12 19 26 2 9 16 23 30
+Th 2 9 16 23 30 6 13 20 27 3 10 17 24
+Fr 3 10 17 24 31 7 14 21 28 4 11 18 25
+Sa 4 11 18 25 1 8 15 22 29 5 12 19 26
+Su 5 12 19 26 2 9 16 23 30 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200909-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200909-jd-nhl.out
new file mode 100644
index 0000000..3bccbf5
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200909-jd-nhl.out
@@ -0,0 +1,8 @@
+ August 2009 September 2009 October 2009
+Mo 215 222 229 236 243 250 257 264 271 278 285 292 299
+Tu 216 223 230 237 244 251 258 265 272 279 286 293 300
+We 217 224 231 238 245 252 259 266 273 280 287 294 301
+Th 218 225 232 239 246 253 260 267 274 281 288 295 302
+Fr 219 226 233 240 247 254 261 268 275 282 289 296 303
+Sa 213 220 227 234 241 248 255 262 269 276 283 290 297 304
+Su 214 221 228 235 242 249 256 263 270 277 284 291 298
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200909-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200909-md-nhl.out
new file mode 100644
index 0000000..0c77c2d
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200909-md-nhl.out
@@ -0,0 +1,8 @@
+ August 2009 September 2009 October 2009
+Mo 3 10 17 24 31 7 14 21 28 5 12 19 26
+Tu 4 11 18 25 1 8 15 22 29 6 13 20 27
+We 5 12 19 26 2 9 16 23 30 7 14 21 28
+Th 6 13 20 27 3 10 17 24 1 8 15 22 29
+Fr 7 14 21 28 4 11 18 25 2 9 16 23 30
+Sa 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Su 2 9 16 23 30 6 13 20 27 4 11 18 25
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200910-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200910-jd-nhl.out
new file mode 100644
index 0000000..f5598e1
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200910-jd-nhl.out
@@ -0,0 +1,8 @@
+ September 2009 October 2009 November 2009
+Mo 250 257 264 271 278 285 292 299 306 313 320 327 334
+Tu 244 251 258 265 272 279 286 293 300 307 314 321 328
+We 245 252 259 266 273 280 287 294 301 308 315 322 329
+Th 246 253 260 267 274 281 288 295 302 309 316 323 330
+Fr 247 254 261 268 275 282 289 296 303 310 317 324 331
+Sa 248 255 262 269 276 283 290 297 304 311 318 325 332
+Su 249 256 263 270 277 284 291 298 305 312 319 326 333
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200910-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200910-md-nhl.out
new file mode 100644
index 0000000..18561d2
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200910-md-nhl.out
@@ -0,0 +1,8 @@
+ September 2009 October 2009 November 2009
+Mo 7 14 21 28 5 12 19 26 2 9 16 23 30
+Tu 1 8 15 22 29 6 13 20 27 3 10 17 24
+We 2 9 16 23 30 7 14 21 28 4 11 18 25
+Th 3 10 17 24 1 8 15 22 29 5 12 19 26
+Fr 4 11 18 25 2 9 16 23 30 6 13 20 27
+Sa 5 12 19 26 3 10 17 24 31 7 14 21 28
+Su 6 13 20 27 4 11 18 25 1 8 15 22 29
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200911-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200911-jd-nhl.out
new file mode 100644
index 0000000..4b8d1db
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200911-jd-nhl.out
@@ -0,0 +1,9 @@
+ 2009
+ October November December
+Mo 278 285 292 299 306 313 320 327 334 341 348 355 362
+Tu 279 286 293 300 307 314 321 328 335 342 349 356 363
+We 280 287 294 301 308 315 322 329 336 343 350 357 364
+Th 274 281 288 295 302 309 316 323 330 337 344 351 358 365
+Fr 275 282 289 296 303 310 317 324 331 338 345 352 359
+Sa 276 283 290 297 304 311 318 325 332 339 346 353 360
+Su 277 284 291 298 305 312 319 326 333 340 347 354 361
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200911-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200911-md-nhl.out
new file mode 100644
index 0000000..35f1371
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200911-md-nhl.out
@@ -0,0 +1,8 @@
+ October 2009 November 2009 December 2009
+Mo 5 12 19 26 2 9 16 23 30 7 14 21 28
+Tu 6 13 20 27 3 10 17 24 1 8 15 22 29
+We 7 14 21 28 4 11 18 25 2 9 16 23 30
+Th 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Fr 2 9 16 23 30 6 13 20 27 4 11 18 25
+Sa 3 10 17 24 31 7 14 21 28 5 12 19 26
+Su 4 11 18 25 1 8 15 22 29 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200912-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200912-jd-nhl.out
new file mode 100644
index 0000000..66efa29
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200912-jd-nhl.out
@@ -0,0 +1,8 @@
+ November 2009 December 2009 January 2010
+Mo 306 313 320 327 334 341 348 355 362 4 11 18 25
+Tu 307 314 321 328 335 342 349 356 363 5 12 19 26
+We 308 315 322 329 336 343 350 357 364 6 13 20 27
+Th 309 316 323 330 337 344 351 358 365 7 14 21 28
+Fr 310 317 324 331 338 345 352 359 1 8 15 22 29
+Sa 311 318 325 332 339 346 353 360 2 9 16 23 30
+Su 305 312 319 326 333 340 347 354 361 3 10 17 24 31
diff --git a/tools/regression/usr.bin/ncal/regress.r-3m200912-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-3m200912-md-nhl.out
new file mode 100644
index 0000000..c62332a
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-3m200912-md-nhl.out
@@ -0,0 +1,8 @@
+ November 2009 December 2009 January 2010
+Mo 2 9 16 23 30 7 14 21 28 4 11 18 25
+Tu 3 10 17 24 1 8 15 22 29 5 12 19 26
+We 4 11 18 25 2 9 16 23 30 6 13 20 27
+Th 5 12 19 26 3 10 17 24 31 7 14 21 28
+Fr 6 13 20 27 4 11 18 25 1 8 15 22 29
+Sa 7 14 21 28 5 12 19 26 2 9 16 23 30
+Su 1 8 15 22 29 6 13 20 27 3 10 17 24 31
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2008-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2008-jd-nhl.out
new file mode 100644
index 0000000..0ea30ae
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2008-jd-nhl.out
@@ -0,0 +1,36 @@
+ 2008
+ January February March
+Mo 7 14 21 28 35 42 49 56 63 70 77 84 91
+Tu 1 8 15 22 29 36 43 50 57 64 71 78 85
+We 2 9 16 23 30 37 44 51 58 65 72 79 86
+Th 3 10 17 24 31 38 45 52 59 66 73 80 87
+Fr 4 11 18 25 32 39 46 53 60 67 74 81 88
+Sa 5 12 19 26 33 40 47 54 61 68 75 82 89
+Su 6 13 20 27 34 41 48 55 62 69 76 83 90
+
+ April May June
+Mo 98 105 112 119 126 133 140 147 154 161 168 175 182
+Tu 92 99 106 113 120 127 134 141 148 155 162 169 176
+We 93 100 107 114 121 128 135 142 149 156 163 170 177
+Th 94 101 108 115 122 129 136 143 150 157 164 171 178
+Fr 95 102 109 116 123 130 137 144 151 158 165 172 179
+Sa 96 103 110 117 124 131 138 145 152 159 166 173 180
+Su 97 104 111 118 125 132 139 146 153 160 167 174 181
+
+ July August September
+Mo 189 196 203 210 217 224 231 238 245 252 259 266 273
+Tu 183 190 197 204 211 218 225 232 239 246 253 260 267 274
+We 184 191 198 205 212 219 226 233 240 247 254 261 268
+Th 185 192 199 206 213 220 227 234 241 248 255 262 269
+Fr 186 193 200 207 214 221 228 235 242 249 256 263 270
+Sa 187 194 201 208 215 222 229 236 243 250 257 264 271
+Su 188 195 202 209 216 223 230 237 244 251 258 265 272
+
+ October November December
+Mo 280 287 294 301 308 315 322 329 336 343 350 357 364
+Tu 281 288 295 302 309 316 323 330 337 344 351 358 365
+We 275 282 289 296 303 310 317 324 331 338 345 352 359 366
+Th 276 283 290 297 304 311 318 325 332 339 346 353 360
+Fr 277 284 291 298 305 312 319 326 333 340 347 354 361
+Sa 278 285 292 299 306 313 320 327 334 341 348 355 362
+Su 279 286 293 300 307 314 321 328 335 342 349 356 363
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2008-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2008-md-nhl.out
new file mode 100644
index 0000000..18191f6
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2008-md-nhl.out
@@ -0,0 +1,27 @@
+ 2008
+ January February March April
+Mo 7 14 21 28 4 11 18 25 3 10 17 24 31 7 14 21 28
+Tu 1 8 15 22 29 5 12 19 26 4 11 18 25 1 8 15 22 29
+We 2 9 16 23 30 6 13 20 27 5 12 19 26 2 9 16 23 30
+Th 3 10 17 24 31 7 14 21 28 6 13 20 27 3 10 17 24
+Fr 4 11 18 25 1 8 15 22 29 7 14 21 28 4 11 18 25
+Sa 5 12 19 26 2 9 16 23 1 8 15 22 29 5 12 19 26
+Su 6 13 20 27 3 10 17 24 2 9 16 23 30 6 13 20 27
+
+ May June July August
+Mo 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25
+Tu 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26
+We 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27
+Th 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28
+Fr 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29
+Sa 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30
+Su 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31
+
+ September October November December
+Mo 1 8 15 22 29 6 13 20 27 3 10 17 24 1 8 15 22 29
+Tu 2 9 16 23 30 7 14 21 28 4 11 18 25 2 9 16 23 30
+We 3 10 17 24 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Th 4 11 18 25 2 9 16 23 30 6 13 20 27 4 11 18 25
+Fr 5 12 19 26 3 10 17 24 31 7 14 21 28 5 12 19 26
+Sa 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27
+Su 7 14 21 28 5 12 19 26 2 9 16 23 30 7 14 21 28
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2009-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2009-jd-nhl.out
new file mode 100644
index 0000000..3869ace
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2009-jd-nhl.out
@@ -0,0 +1,36 @@
+ 2009
+ January February March
+Mo 5 12 19 26 33 40 47 54 61 68 75 82 89
+Tu 6 13 20 27 34 41 48 55 62 69 76 83 90
+We 7 14 21 28 35 42 49 56 63 70 77 84
+Th 1 8 15 22 29 36 43 50 57 64 71 78 85
+Fr 2 9 16 23 30 37 44 51 58 65 72 79 86
+Sa 3 10 17 24 31 38 45 52 59 66 73 80 87
+Su 4 11 18 25 32 39 46 53 60 67 74 81 88
+
+ April May June
+Mo 96 103 110 117 124 131 138 145 152 159 166 173 180
+Tu 97 104 111 118 125 132 139 146 153 160 167 174 181
+We 91 98 105 112 119 126 133 140 147 154 161 168 175
+Th 92 99 106 113 120 127 134 141 148 155 162 169 176
+Fr 93 100 107 114 121 128 135 142 149 156 163 170 177
+Sa 94 101 108 115 122 129 136 143 150 157 164 171 178
+Su 95 102 109 116 123 130 137 144 151 158 165 172 179
+
+ July August September
+Mo 187 194 201 208 215 222 229 236 243 250 257 264 271
+Tu 188 195 202 209 216 223 230 237 244 251 258 265 272
+We 182 189 196 203 210 217 224 231 238 245 252 259 266 273
+Th 183 190 197 204 211 218 225 232 239 246 253 260 267
+Fr 184 191 198 205 212 219 226 233 240 247 254 261 268
+Sa 185 192 199 206 213 220 227 234 241 248 255 262 269
+Su 186 193 200 207 214 221 228 235 242 249 256 263 270
+
+ October November December
+Mo 278 285 292 299 306 313 320 327 334 341 348 355 362
+Tu 279 286 293 300 307 314 321 328 335 342 349 356 363
+We 280 287 294 301 308 315 322 329 336 343 350 357 364
+Th 274 281 288 295 302 309 316 323 330 337 344 351 358 365
+Fr 275 282 289 296 303 310 317 324 331 338 345 352 359
+Sa 276 283 290 297 304 311 318 325 332 339 346 353 360
+Su 277 284 291 298 305 312 319 326 333 340 347 354 361
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2009-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2009-md-nhl.out
new file mode 100644
index 0000000..43496e9
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2009-md-nhl.out
@@ -0,0 +1,27 @@
+ 2009
+ January February March April
+Mo 5 12 19 26 2 9 16 23 2 9 16 23 30 6 13 20 27
+Tu 6 13 20 27 3 10 17 24 3 10 17 24 31 7 14 21 28
+We 7 14 21 28 4 11 18 25 4 11 18 25 1 8 15 22 29
+Th 1 8 15 22 29 5 12 19 26 5 12 19 26 2 9 16 23 30
+Fr 2 9 16 23 30 6 13 20 27 6 13 20 27 3 10 17 24
+Sa 3 10 17 24 31 7 14 21 28 7 14 21 28 4 11 18 25
+Su 4 11 18 25 1 8 15 22 1 8 15 22 29 5 12 19 26
+
+ May June July August
+Mo 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31
+Tu 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25
+We 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26
+Th 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27
+Fr 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28
+Sa 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29
+Su 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30
+
+ September October November December
+Mo 7 14 21 28 5 12 19 26 2 9 16 23 30 7 14 21 28
+Tu 1 8 15 22 29 6 13 20 27 3 10 17 24 1 8 15 22 29
+We 2 9 16 23 30 7 14 21 28 4 11 18 25 2 9 16 23 30
+Th 3 10 17 24 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Fr 4 11 18 25 2 9 16 23 30 6 13 20 27 4 11 18 25
+Sa 5 12 19 26 3 10 17 24 31 7 14 21 28 5 12 19 26
+Su 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2010-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2010-jd-nhl.out
new file mode 100644
index 0000000..affd536
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2010-jd-nhl.out
@@ -0,0 +1,36 @@
+ 2010
+ January February March
+Mo 4 11 18 25 32 39 46 53 60 67 74 81 88
+Tu 5 12 19 26 33 40 47 54 61 68 75 82 89
+We 6 13 20 27 34 41 48 55 62 69 76 83 90
+Th 7 14 21 28 35 42 49 56 63 70 77 84
+Fr 1 8 15 22 29 36 43 50 57 64 71 78 85
+Sa 2 9 16 23 30 37 44 51 58 65 72 79 86
+Su 3 10 17 24 31 38 45 52 59 66 73 80 87
+
+ April May June
+Mo 95 102 109 116 123 130 137 144 151 158 165 172 179
+Tu 96 103 110 117 124 131 138 145 152 159 166 173 180
+We 97 104 111 118 125 132 139 146 153 160 167 174 181
+Th 91 98 105 112 119 126 133 140 147 154 161 168 175
+Fr 92 99 106 113 120 127 134 141 148 155 162 169 176
+Sa 93 100 107 114 121 128 135 142 149 156 163 170 177
+Su 94 101 108 115 122 129 136 143 150 157 164 171 178
+
+ July August September
+Mo 186 193 200 207 214 221 228 235 242 249 256 263 270
+Tu 187 194 201 208 215 222 229 236 243 250 257 264 271
+We 188 195 202 209 216 223 230 237 244 251 258 265 272
+Th 182 189 196 203 210 217 224 231 238 245 252 259 266 273
+Fr 183 190 197 204 211 218 225 232 239 246 253 260 267
+Sa 184 191 198 205 212 219 226 233 240 247 254 261 268
+Su 185 192 199 206 213 220 227 234 241 248 255 262 269
+
+ October November December
+Mo 277 284 291 298 305 312 319 326 333 340 347 354 361
+Tu 278 285 292 299 306 313 320 327 334 341 348 355 362
+We 279 286 293 300 307 314 321 328 335 342 349 356 363
+Th 280 287 294 301 308 315 322 329 336 343 350 357 364
+Fr 274 281 288 295 302 309 316 323 330 337 344 351 358 365
+Sa 275 282 289 296 303 310 317 324 331 338 345 352 359
+Su 276 283 290 297 304 311 318 325 332 339 346 353 360
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2010-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2010-md-nhl.out
new file mode 100644
index 0000000..8649c16
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2010-md-nhl.out
@@ -0,0 +1,27 @@
+ 2010
+ January February March April
+Mo 4 11 18 25 1 8 15 22 1 8 15 22 29 5 12 19 26
+Tu 5 12 19 26 2 9 16 23 2 9 16 23 30 6 13 20 27
+We 6 13 20 27 3 10 17 24 3 10 17 24 31 7 14 21 28
+Th 7 14 21 28 4 11 18 25 4 11 18 25 1 8 15 22 29
+Fr 1 8 15 22 29 5 12 19 26 5 12 19 26 2 9 16 23 30
+Sa 2 9 16 23 30 6 13 20 27 6 13 20 27 3 10 17 24
+Su 3 10 17 24 31 7 14 21 28 7 14 21 28 4 11 18 25
+
+ May June July August
+Mo 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30
+Tu 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31
+We 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25
+Th 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26
+Fr 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27
+Sa 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28
+Su 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29
+
+ September October November December
+Mo 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27
+Tu 7 14 21 28 5 12 19 26 2 9 16 23 30 7 14 21 28
+We 1 8 15 22 29 6 13 20 27 3 10 17 24 1 8 15 22 29
+Th 2 9 16 23 30 7 14 21 28 4 11 18 25 2 9 16 23 30
+Fr 3 10 17 24 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Sa 4 11 18 25 2 9 16 23 30 6 13 20 27 4 11 18 25
+Su 5 12 19 26 3 10 17 24 31 7 14 21 28 5 12 19 26
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2011-jd-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2011-jd-nhl.out
new file mode 100644
index 0000000..a4a71c2
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2011-jd-nhl.out
@@ -0,0 +1,36 @@
+ 2011
+ January February March
+Mo 3 10 17 24 31 38 45 52 59 66 73 80 87
+Tu 4 11 18 25 32 39 46 53 60 67 74 81 88
+We 5 12 19 26 33 40 47 54 61 68 75 82 89
+Th 6 13 20 27 34 41 48 55 62 69 76 83 90
+Fr 7 14 21 28 35 42 49 56 63 70 77 84
+Sa 1 8 15 22 29 36 43 50 57 64 71 78 85
+Su 2 9 16 23 30 37 44 51 58 65 72 79 86
+
+ April May June
+Mo 94 101 108 115 122 129 136 143 150 157 164 171 178
+Tu 95 102 109 116 123 130 137 144 151 158 165 172 179
+We 96 103 110 117 124 131 138 145 152 159 166 173 180
+Th 97 104 111 118 125 132 139 146 153 160 167 174 181
+Fr 91 98 105 112 119 126 133 140 147 154 161 168 175
+Sa 92 99 106 113 120 127 134 141 148 155 162 169 176
+Su 93 100 107 114 121 128 135 142 149 156 163 170 177
+
+ July August September
+Mo 185 192 199 206 213 220 227 234 241 248 255 262 269
+Tu 186 193 200 207 214 221 228 235 242 249 256 263 270
+We 187 194 201 208 215 222 229 236 243 250 257 264 271
+Th 188 195 202 209 216 223 230 237 244 251 258 265 272
+Fr 182 189 196 203 210 217 224 231 238 245 252 259 266 273
+Sa 183 190 197 204 211 218 225 232 239 246 253 260 267
+Su 184 191 198 205 212 219 226 233 240 247 254 261 268
+
+ October November December
+Mo 276 283 290 297 304 311 318 325 332 339 346 353 360
+Tu 277 284 291 298 305 312 319 326 333 340 347 354 361
+We 278 285 292 299 306 313 320 327 334 341 348 355 362
+Th 279 286 293 300 307 314 321 328 335 342 349 356 363
+Fr 280 287 294 301 308 315 322 329 336 343 350 357 364
+Sa 274 281 288 295 302 309 316 323 330 337 344 351 358 365
+Su 275 282 289 296 303 310 317 324 331 338 345 352 359
diff --git a/tools/regression/usr.bin/ncal/regress.r-y2011-md-nhl.out b/tools/regression/usr.bin/ncal/regress.r-y2011-md-nhl.out
new file mode 100644
index 0000000..8852932
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.r-y2011-md-nhl.out
@@ -0,0 +1,27 @@
+ 2011
+ January February March April
+Mo 3 10 17 24 31 7 14 21 28 7 14 21 28 4 11 18 25
+Tu 4 11 18 25 1 8 15 22 1 8 15 22 29 5 12 19 26
+We 5 12 19 26 2 9 16 23 2 9 16 23 30 6 13 20 27
+Th 6 13 20 27 3 10 17 24 3 10 17 24 31 7 14 21 28
+Fr 7 14 21 28 4 11 18 25 4 11 18 25 1 8 15 22 29
+Sa 1 8 15 22 29 5 12 19 26 5 12 19 26 2 9 16 23 30
+Su 2 9 16 23 30 6 13 20 27 6 13 20 27 3 10 17 24
+
+ May June July August
+Mo 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29
+Tu 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30
+We 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31
+Th 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25
+Fr 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26
+Sa 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27
+Su 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28
+
+ September October November December
+Mo 5 12 19 26 3 10 17 24 31 7 14 21 28 5 12 19 26
+Tu 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27
+We 7 14 21 28 5 12 19 26 2 9 16 23 30 7 14 21 28
+Th 1 8 15 22 29 6 13 20 27 3 10 17 24 1 8 15 22 29
+Fr 2 9 16 23 30 7 14 21 28 4 11 18 25 2 9 16 23 30
+Sa 3 10 17 24 1 8 15 22 29 5 12 19 26 3 10 17 24 31
+Su 4 11 18 25 2 9 16 23 30 6 13 20 27 4 11 18 25
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-3-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-3-nhl.out
new file mode 100644
index 0000000..ccb6b36
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-3-nhl.out
@@ -0,0 +1,8 @@
+ February 2008 March 2008 April 2008
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 1 2 3 4 5
+ 3 4 5 6 7 8 9 2 3 4 5 6 7 8 6 7 8 9 10 11 12
+10 11 12 13 14 15 16 9 10 11 12 13 14 15 13 14 15 16 17 18 19
+17 18 19 20 21 22 23 16 17 18 19 20 21 22 20 21 22 23 24 25 26
+24 25 26 27 28 29 23 24 25 26 27 28 29 27 28 29 30
+ 30 31
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-A-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-A-nhl.out
new file mode 100644
index 0000000..19149ca6
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-A-nhl.out
@@ -0,0 +1,8 @@
+ March 2008 April 2008
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 1 2 3 4 5
+ 2 3 4 5 6 7 8 6 7 8 9 10 11 12
+ 9 10 11 12 13 14 15 13 14 15 16 17 18 19
+16 17 18 19 20 21 22 20 21 22 23 24 25 26
+23 24 25 26 27 28 29 27 28 29 30
+30 31
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-AB-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-AB-nhl.out
new file mode 100644
index 0000000..ccb6b36
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-AB-nhl.out
@@ -0,0 +1,8 @@
+ February 2008 March 2008 April 2008
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1 1 2 3 4 5
+ 3 4 5 6 7 8 9 2 3 4 5 6 7 8 6 7 8 9 10 11 12
+10 11 12 13 14 15 16 9 10 11 12 13 14 15 13 14 15 16 17 18 19
+17 18 19 20 21 22 23 16 17 18 19 20 21 22 20 21 22 23 24 25 26
+24 25 26 27 28 29 23 24 25 26 27 28 29 27 28 29 30
+ 30 31
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-B-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-B-nhl.out
new file mode 100644
index 0000000..5d61423
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-B-nhl.out
@@ -0,0 +1,8 @@
+ February 2008 March 2008
+Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
+ 1 2 1
+ 3 4 5 6 7 8 9 2 3 4 5 6 7 8
+10 11 12 13 14 15 16 9 10 11 12 13 14 15
+17 18 19 20 21 22 23 16 17 18 19 20 21 22
+24 25 26 27 28 29 23 24 25 26 27 28 29
+ 30 31
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-gmgy-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-gmgy-nhl.out
new file mode 100644
index 0000000..5620051
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-gmgy-nhl.out
@@ -0,0 +1,8 @@
+ January 2007
+Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6
+ 7 8 9 10 11 12 13
+14 15 16 17 18 19 20
+21 22 23 24 25 26 27
+28 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-m-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-m-nhl.out
new file mode 100644
index 0000000..37b9ffa
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-m-nhl.out
@@ -0,0 +1,8 @@
+ January 2008
+Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5
+ 6 7 8 9 10 11 12
+13 14 15 16 17 18 19
+20 21 22 23 24 25 26
+27 28 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.s-b-mgy-nhl.out b/tools/regression/usr.bin/ncal/regress.s-b-mgy-nhl.out
new file mode 100644
index 0000000..5620051
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-b-mgy-nhl.out
@@ -0,0 +1,8 @@
+ January 2007
+Su Mo Tu We Th Fr Sa
+ 1 2 3 4 5 6
+ 7 8 9 10 11 12 13
+14 15 16 17 18 19 20
+21 22 23 24 25 26 27
+28 29 30 31
+
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-3-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-3-nhl.out
new file mode 100644
index 0000000..9a816b7
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-3-nhl.out
@@ -0,0 +1,8 @@
+ February 2008 March 2008 April 2008
+Mo 4 11 18 25 3 10 17 24 31 7 14 21 28
+Tu 5 12 19 26 4 11 18 25 1 8 15 22 29
+We 6 13 20 27 5 12 19 26 2 9 16 23 30
+Th 7 14 21 28 6 13 20 27 3 10 17 24
+Fr 1 8 15 22 29 7 14 21 28 4 11 18 25
+Sa 2 9 16 23 1 8 15 22 29 5 12 19 26
+Su 3 10 17 24 2 9 16 23 30 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-A-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-A-nhl.out
new file mode 100644
index 0000000..603c2cf
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-A-nhl.out
@@ -0,0 +1,8 @@
+ March 2008 April 2008
+Mo 3 10 17 24 31 7 14 21 28
+Tu 4 11 18 25 1 8 15 22 29
+We 5 12 19 26 2 9 16 23 30
+Th 6 13 20 27 3 10 17 24
+Fr 7 14 21 28 4 11 18 25
+Sa 1 8 15 22 29 5 12 19 26
+Su 2 9 16 23 30 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-AB-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-AB-nhl.out
new file mode 100644
index 0000000..9a816b7
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-AB-nhl.out
@@ -0,0 +1,8 @@
+ February 2008 March 2008 April 2008
+Mo 4 11 18 25 3 10 17 24 31 7 14 21 28
+Tu 5 12 19 26 4 11 18 25 1 8 15 22 29
+We 6 13 20 27 5 12 19 26 2 9 16 23 30
+Th 7 14 21 28 6 13 20 27 3 10 17 24
+Fr 1 8 15 22 29 7 14 21 28 4 11 18 25
+Sa 2 9 16 23 1 8 15 22 29 5 12 19 26
+Su 3 10 17 24 2 9 16 23 30 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-B-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-B-nhl.out
new file mode 100644
index 0000000..94614da
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-B-nhl.out
@@ -0,0 +1,8 @@
+ February 2008 March 2008
+Mo 4 11 18 25 3 10 17 24 31
+Tu 5 12 19 26 4 11 18 25
+We 6 13 20 27 5 12 19 26
+Th 7 14 21 28 6 13 20 27
+Fr 1 8 15 22 29 7 14 21 28
+Sa 2 9 16 23 1 8 15 22 29
+Su 3 10 17 24 2 9 16 23 30
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-gmgy-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-gmgy-nhl.out
new file mode 100644
index 0000000..0b42e41
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-gmgy-nhl.out
@@ -0,0 +1,8 @@
+ January 2007
+Mo 1 8 15 22 29
+Tu 2 9 16 23 30
+We 3 10 17 24 31
+Th 4 11 18 25
+Fr 5 12 19 26
+Sa 6 13 20 27
+Su 7 14 21 28
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-m-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-m-nhl.out
new file mode 100644
index 0000000..34b939d
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-m-nhl.out
@@ -0,0 +1,8 @@
+ January 2008
+Mo 7 14 21 28
+Tu 1 8 15 22 29
+We 2 9 16 23 30
+Th 3 10 17 24 31
+Fr 4 11 18 25
+Sa 5 12 19 26
+Su 6 13 20 27
diff --git a/tools/regression/usr.bin/ncal/regress.s-r-mgy-nhl.out b/tools/regression/usr.bin/ncal/regress.s-r-mgy-nhl.out
new file mode 100644
index 0000000..0b42e41
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.s-r-mgy-nhl.out
@@ -0,0 +1,8 @@
+ January 2007
+Mo 1 8 15 22 29
+Tu 2 9 16 23 30
+We 3 10 17 24 31
+Th 4 11 18 25
+Fr 5 12 19 26
+Sa 6 13 20 27
+Su 7 14 21 28
diff --git a/tools/regression/usr.bin/ncal/regress.sh b/tools/regression/usr.bin/ncal/regress.sh
new file mode 100644
index 0000000..3dc188d
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.sh
@@ -0,0 +1,82 @@
+# $FreeBSD$
+
+CAL_BIN="ncal"
+CAL="${CAL_BIN} -C"
+NCAL="${CAL_BIN} -N"
+YEARS="2008 2009 2010 2011"
+ONEYEAR="2009"
+
+REGRESSION_START($1)
+
+#
+# The first tests are layout tests, to make sure that the output is still the
+# same despite varying months.
+#
+
+# Full year calendars
+
+echo 1..16
+
+for y in ${YEARS}; do
+ # Regular calendar, Month days, No-highlight
+ REGRESSION_TEST(`r-y${y}-md-nhl', `$NCAL -h ${y}')
+ # Backwards calendar, Month days, No-highlight
+ REGRESSION_TEST(`b-y${y}-md-nhl', `$CAL -h ${y}')
+ # Regular calendar, Julian days, No-highlight
+ REGRESSION_TEST(`r-y${y}-jd-nhl', `$NCAL -jh ${y}')
+ # Backwards calendar, Julian days, No-highlight
+ REGRESSION_TEST(`b-y${y}-jd-nhl', `$CAL -jh ${y}')
+done
+
+# 3 month calendars
+
+echo 17 .. 29
+
+for m in $(jot -w %02d 12); do
+ # Regular calendar, Month days, No-highlight
+ REGRESSION_TEST(`r-3m${ONEYEAR}${m}-md-nhl',
+ `$NCAL -h3 ${m} ${ONEYEAR}')
+ # Backwards calendar, Month days, No-highlight
+ REGRESSION_TEST(`b-3m${ONEYEAR}${m}-md-nhl', `$CAL -h3 ${m} ${ONEYEAR}')
+ # Regular calendar, Julian days, No-highlight
+ REGRESSION_TEST(`r-3m${ONEYEAR}${m}-jd-nhl',
+ `$NCAL -jh3 ${m} ${ONEYEAR}')
+ # Backwards calendar, Julian days, No-highlight
+ REGRESSION_TEST(`b-3m${ONEYEAR}${m}-jd-nhl', `$CAL -jh3 ${m} ${ONEYEAR}')
+done
+
+#
+# The next tests are combinations of the various arguments.
+#
+
+# These should fail
+REGRESSION_TEST(`f-3y-nhl', `$NCAL -3 -y 2>&1')
+REGRESSION_TEST(`f-3A-nhl', `$NCAL -3 -A 3 2>&1')
+REGRESSION_TEST(`f-3B-nhl', `$NCAL -3 -B 3 2>&1')
+REGRESSION_TEST(`f-3gy-nhl', `$NCAL -3 2008 2>&1')
+REGRESSION_TEST(`f-3AB-nhl', `$NCAL -3 -A 3 -B 3 2>&1')
+REGRESSION_TEST(`f-mgm-nhl', `$NCAL -m 3 2 2008 2>&1')
+REGRESSION_TEST(`f-ym-nhl', `$NCAL -y -m 2 2>&1')
+REGRESSION_TEST(`f-ygm-nhl', `$NCAL -y 2 2008 2>&1')
+REGRESSION_TEST(`f-yA-nhl', `$NCAL -y -A 3 2>&1')
+REGRESSION_TEST(`f-yB-nhl', `$NCAL -y -B 3 2>&1')
+REGRESSION_TEST(`f-yAB-nhl', `$NCAL -y -A 3 -B 3 2>&1')
+
+# These should be successful
+
+REGRESSION_TEST(`s-b-3-nhl', `$CAL -d 2008.03 -3')
+REGRESSION_TEST(`s-b-A-nhl', `$CAL -d 2008.03 -A 1')
+REGRESSION_TEST(`s-b-B-nhl', `$CAL -d 2008.03 -B 1')
+REGRESSION_TEST(`s-b-AB-nhl', `$CAL -d 2008.03 -A 1 -B 1')
+REGRESSION_TEST(`s-b-m-nhl', `$CAL -d 2008.03 -m 1')
+REGRESSION_TEST(`s-b-mgy-nhl', `$CAL -d 2008.03 -m 1 2007')
+REGRESSION_TEST(`s-b-gmgy-nhl', `$CAL -d 2008.03 1 2007')
+REGRESSION_TEST(`s-r-3-nhl', `$NCAL -d 2008.03 -3')
+REGRESSION_TEST(`s-r-A-nhl', `$NCAL -d 2008.03 -A 1')
+REGRESSION_TEST(`s-r-B-nhl', `$NCAL -d 2008.03 -B 1')
+REGRESSION_TEST(`s-r-AB-nhl', `$NCAL -d 2008.03 -A 1 -B 1')
+REGRESSION_TEST(`s-r-m-nhl', `$NCAL -d 2008.03 -m 1')
+REGRESSION_TEST(`s-r-mgy-nhl', `$NCAL -d 2008.03 -m 1 2007')
+REGRESSION_TEST(`s-r-gmgy-nhl', `$NCAL -d 2008.03 1 2007')
+
+REGRESSION_END()
diff --git a/tools/regression/usr.bin/ncal/regress.t b/tools/regression/usr.bin/ncal/regress.t
new file mode 100644
index 0000000..a82aacd
--- /dev/null
+++ b/tools/regression/usr.bin/ncal/regress.t
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+m4 ../regress.m4 regress.sh | sh
diff --git a/tools/test/README b/tools/test/README
index f16e215..438c1f5 100644
--- a/tools/test/README
+++ b/tools/test/README
@@ -11,3 +11,4 @@ devrandom Programs to test /dev/*random.
dtrace DTrace test suite
malloc A program to test and benchmark malloc().
posixshm A program to test POSIX shared memory.
+testfloat Programs to test floating-point implementations
diff --git a/tools/test/testfloat/README.txt b/tools/test/testfloat/README.txt
new file mode 100644
index 0000000..fe99fd9
--- /dev/null
+++ b/tools/test/testfloat/README.txt
@@ -0,0 +1,50 @@
+
+Package Overview for TestFloat Release 2a
+
+John R. Hauser
+1998 December 16
+
+
+TestFloat is a program for testing that a floating-point implementation
+conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+TestFloat is distributed in the form of C source code. The TestFloat
+package actually provides two related programs:
+
+-- The `testfloat' program tests a system's floating-point for conformance
+ to the IEC/IEEE Standard. This program uses the SoftFloat software
+ floating-point implementation as a basis for comparison.
+
+-- The `testsoftfloat' program tests SoftFloat itself for conformance to
+ the IEC/IEEE Standard. These tests are performed by comparing against a
+ separate, slower software floating-point that is included in the TestFloat
+ package.
+
+TestFloat depends on SoftFloat, but SoftFloat is not included in the
+TestFloat package. SoftFloat can be obtained through the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
+
+TestFloat is documented in three text files:
+
+ testfloat.txt Documentation for using the TestFloat programs
+ (both `testfloat' and `testsoftfloat').
+ testfloat-source.txt Documentation for porting and compiling TestFloat.
+ testfloat-history.txt History of major changes to TestFloat.
+
+The following file is also provided:
+
+ systemBugs.txt Information about processor bugs found using
+ TestFloat.
+
+Other files in the package comprise the source code for TestFloat.
+
+Please be aware that some work is involved in porting this software to other
+targets. It is not just a matter of getting `make' to complete without
+error messages. I would have written the code that way if I could, but
+there are fundamental differences between systems that I can't make go away.
+You should not attempt to compile the TestFloat sources without first
+reading `testfloat-source.txt'.
+
+At the time of this writing, the most up-to-date information about
+TestFloat and the latest release can be found at the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
diff --git a/tools/test/testfloat/fail.c b/tools/test/testfloat/fail.c
new file mode 100644
index 0000000..30bbea6
--- /dev/null
+++ b/tools/test/testfloat/fail.c
@@ -0,0 +1,46 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "milieu.h"
+#include "fail.h"
+
+char *fail_programName = "";
+
+void fail( const char *message, ... )
+{
+ va_list varArgs;
+
+ fprintf( stderr, "%s: ", fail_programName );
+ va_start( varArgs, message );
+ vfprintf( stderr, message, varArgs );
+ va_end( varArgs );
+ fputs( ".\n", stderr );
+ exit( EXIT_FAILURE );
+
+}
+
diff --git a/tools/test/testfloat/fail.h b/tools/test/testfloat/fail.h
new file mode 100644
index 0000000..9c338da
--- /dev/null
+++ b/tools/test/testfloat/fail.h
@@ -0,0 +1,29 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+extern char *fail_programName;
+
+void fail( const char *, ... );
+
diff --git a/tools/test/testfloat/random.c b/tools/test/testfloat/random.c
new file mode 100644
index 0000000..21326c1
--- /dev/null
+++ b/tools/test/testfloat/random.c
@@ -0,0 +1,63 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include "milieu.h"
+#include "random.h"
+
+uint8 randomUint8( void )
+{
+
+ return (bits8) ( random()>>4 );
+
+}
+
+uint16 randomUint16( void )
+{
+
+ return ( random() & 0x0000ffff );
+
+}
+
+uint32 randomUint32( void )
+{
+
+ return ( ( (uint32) random()<<16) | ( (uint32) random() & 0x0000ffff) );
+}
+
+#ifdef BITS64
+
+uint64 randomUint64( void )
+{
+
+ return ( ( (uint64) randomUint32() )<<32 ) | randomUint32();
+
+}
+
+#endif
+
diff --git a/tools/test/testfloat/random.h b/tools/test/testfloat/random.h
new file mode 100644
index 0000000..7375499
--- /dev/null
+++ b/tools/test/testfloat/random.h
@@ -0,0 +1,32 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+uint8 randomUint8( void );
+uint16 randomUint16( void );
+uint32 randomUint32( void );
+#ifdef BITS64
+uint64 randomUint64( void );
+#endif
+
diff --git a/tools/test/testfloat/slowfloat-32.c b/tools/test/testfloat/slowfloat-32.c
new file mode 100644
index 0000000..549654b
--- /dev/null
+++ b/tools/test/testfloat/slowfloat-32.c
@@ -0,0 +1,1183 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+int8 slow_float_rounding_mode;
+int8 slow_float_exception_flags;
+int8 slow_float_detect_tininess;
+
+typedef struct {
+ bits32 a0, a1;
+} bits64X;
+
+typedef struct {
+ flag isNaN;
+ flag isInf;
+ flag isZero;
+ flag sign;
+ int16 exp;
+ bits64X sig;
+} floatX;
+
+static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
+static const floatX floatXPositiveZero =
+ { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
+static const floatX floatXNegativeZero =
+ { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
+
+static bits64X shortShift64Left( bits64X a, int8 shiftCount )
+{
+ int8 negShiftCount;
+
+ negShiftCount = ( - shiftCount & 31 );
+ a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
+ a.a1 <<= shiftCount;
+ return a;
+
+}
+
+static bits64X shortShift64RightJamming( bits64X a, int8 shiftCount )
+{
+ int8 negShiftCount;
+ bits32 extra;
+
+ negShiftCount = ( - shiftCount & 31 );
+ extra = a.a1<<negShiftCount;
+ a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
+ a.a0 >>= shiftCount;
+ return a;
+
+}
+
+static bits64X neg64( bits64X a )
+{
+
+ if ( a.a1 == 0 ) {
+ a.a0 = - a.a0;
+ }
+ else {
+ a.a1 = - a.a1;
+ a.a0 = ~ a.a0;
+ }
+ return a;
+
+}
+
+static bits64X add64( bits64X a, bits64X b )
+{
+
+ a.a1 += b.a1;
+ a.a0 += b.a0 + ( a.a1 < b.a1 );
+ return a;
+
+}
+
+static flag eq64( bits64X a, bits64X b )
+{
+
+ return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
+
+}
+
+static flag le64( bits64X a, bits64X b )
+{
+
+ return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
+
+}
+
+static flag lt64( bits64X a, bits64X b )
+{
+
+ return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
+
+}
+
+static floatX roundFloatXTo24( flag isTiny, floatX zx )
+{
+
+ if ( zx.sig.a1 ) {
+ slow_float_exception_flags |= float_flag_inexact;
+ if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( zx.sig.a1 < 0x80000000 ) goto noIncrement;
+ if ( ( zx.sig.a1 == 0x80000000 ) && ! ( zx.sig.a0 & 1 ) ) {
+ goto noIncrement;
+ }
+ break;
+ case float_round_to_zero:
+ goto noIncrement;
+ case float_round_down:
+ if ( ! zx.sign ) goto noIncrement;
+ break;
+ case float_round_up:
+ if ( zx.sign ) goto noIncrement;
+ break;
+ }
+ ++zx.sig.a0;
+ if ( zx.sig.a0 == 0x01000000 ) {
+ zx.sig.a0 = 0x00800000;
+ ++zx.exp;
+ }
+ }
+ noIncrement:
+ zx.sig.a1 = 0;
+ return zx;
+
+}
+
+static floatX roundFloatXTo53( flag isTiny, floatX zx )
+{
+ int8 roundBits;
+
+ roundBits = zx.sig.a1 & 7;
+ zx.sig.a1 -= roundBits;
+ if ( roundBits ) {
+ slow_float_exception_flags |= float_flag_inexact;
+ if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( roundBits < 4 ) goto noIncrement;
+ if ( ( roundBits == 4 ) && ! ( zx.sig.a1 & 8 ) ) goto noIncrement;
+ break;
+ case float_round_to_zero:
+ goto noIncrement;
+ case float_round_down:
+ if ( ! zx.sign ) goto noIncrement;
+ break;
+ case float_round_up:
+ if ( zx.sign ) goto noIncrement;
+ break;
+ }
+ zx.sig.a1 += 8;
+ zx.sig.a0 += ( zx.sig.a1 == 0 );
+ if ( zx.sig.a0 == 0x01000000 ) {
+ zx.sig.a0 = 0x00800000;
+ ++zx.exp;
+ }
+ }
+ noIncrement:
+ return zx;
+
+}
+
+static floatX int32ToFloatX( int32 a )
+{
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.sign = ( a < 0 );
+ ax.sig.a1 = ax.sign ? - a : a;
+ ax.sig.a0 = 0;
+ if ( a == 0 ) {
+ ax.isZero = TRUE;
+ return ax;
+ }
+ ax.isZero = FALSE;
+ ax.sig = shortShift64Left( ax.sig, 23 );
+ ax.exp = 32;
+ while ( ax.sig.a0 < 0x00800000 ) {
+ ax.sig = shortShift64Left( ax.sig, 1 );
+ --ax.exp;
+ }
+ return ax;
+
+}
+
+static int32 floatXToInt32( floatX ax )
+{
+ int8 savedExceptionFlags;
+ int16 shiftCount;
+ int32 z;
+
+ if ( ax.isInf || ax.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ return ( ax.isInf & ax.sign ) ? 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( ax.isZero ) return 0;
+ savedExceptionFlags = slow_float_exception_flags;
+ shiftCount = 52 - ax.exp;
+ if ( 56 < shiftCount ) {
+ ax.sig.a1 = 1;
+ ax.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < shiftCount ) {
+ ax.sig = shortShift64RightJamming( ax.sig, 1 );
+ --shiftCount;
+ }
+ }
+ ax = roundFloatXTo53( FALSE, ax );
+ ax.sig = shortShift64RightJamming( ax.sig, 3 );
+ z = ax.sig.a1;
+ if ( ax.sign ) z = - z;
+ if ( ( shiftCount < 0 )
+ || ax.sig.a0
+ || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
+ ) {
+ slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
+ return ax.sign ? 0x80000000 : 0x7FFFFFFF;
+ }
+ return z;
+
+}
+
+static floatX float32ToFloatX( float32 a )
+{
+ int16 expField;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.isZero = FALSE;
+ ax.sign = ( ( a & 0x80000000 ) != 0 );
+ expField = ( a>>23 ) & 0xFF;
+ ax.sig.a1 = 0;
+ ax.sig.a0 = a & 0x007FFFFF;
+ if ( expField == 0 ) {
+ if ( ax.sig.a0 == 0 ) {
+ ax.isZero = TRUE;
+ }
+ else {
+ expField = 1 - 0x7F;
+ do {
+ ax.sig.a0 <<= 1;
+ --expField;
+ } while ( ax.sig.a0 < 0x00800000 );
+ ax.exp = expField;
+ }
+ }
+ else if ( expField == 0xFF ) {
+ if ( ax.sig.a0 == 0 ) {
+ ax.isInf = TRUE;
+ }
+ else {
+ ax.isNaN = TRUE;
+ }
+ }
+ else {
+ ax.sig.a0 |= 0x00800000;
+ ax.exp = expField - 0x7F;
+ }
+ return ax;
+
+}
+
+static float32 floatXToFloat32( floatX zx )
+{
+ floatX savedZ;
+ flag isTiny;
+ int16 expField;
+ float32 z;
+
+ if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
+ if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
+ if ( zx.isNaN ) return 0xFFFFFFFF;
+ while ( 0x01000000 <= zx.sig.a0 ) {
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ ++zx.exp;
+ }
+ while ( zx.sig.a0 < 0x00800000 ) {
+ zx.sig = shortShift64Left( zx.sig, 1 );
+ --zx.exp;
+ }
+ savedZ = zx;
+ isTiny =
+ ( slow_float_detect_tininess == float_tininess_before_rounding )
+ && ( zx.exp + 0x7F <= 0 );
+ zx = roundFloatXTo24( isTiny, zx );
+ expField = zx.exp + 0x7F;
+ if ( 0xFF <= expField ) {
+ slow_float_exception_flags |=
+ float_flag_overflow | float_flag_inexact;
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z = 0xFF800000;
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ z = 0xFF7FFFFF;
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z = 0x7F800000;
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ z = 0x7F7FFFFF;
+ break;
+ }
+ }
+ return z;
+ }
+ if ( expField <= 0 ) {
+ isTiny = TRUE;
+ zx = savedZ;
+ expField = zx.exp + 0x7F;
+ if ( expField < -27 ) {
+ zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expField <= 0 ) {
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ ++expField;
+ }
+ }
+ zx = roundFloatXTo24( isTiny, zx );
+ expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
+ }
+ z = expField;
+ z <<= 23;
+ if ( zx.sign ) z |= 0x80000000;
+ z |= zx.sig.a0 & 0x007FFFFF;
+ return z;
+
+}
+
+static floatX float64ToFloatX( float64 a )
+{
+ int16 expField;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.isZero = FALSE;
+#ifdef BITS64
+ ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
+ expField = ( a>>52 ) & 0x7FF;
+ ax.sig.a1 = a;
+ ax.sig.a0 = ( a>>32 ) & 0x000FFFFF;
+#else
+ ax.sign = ( ( a.high & 0x80000000 ) != 0 );
+ expField = ( a.high>>( 52 - 32 ) ) & 0x7FF;
+ ax.sig.a1 = a.low;
+ ax.sig.a0 = a.high & 0x000FFFFF;
+#endif
+ if ( expField == 0 ) {
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+ ax.isZero = TRUE;
+ }
+ else {
+ expField = 1 - 0x3FF;
+ do {
+ ax.sig = shortShift64Left( ax.sig, 1 );
+ --expField;
+ } while ( ax.sig.a0 < 0x00100000 );
+ ax.exp = expField;
+ }
+ }
+ else if ( expField == 0x7FF ) {
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+ ax.isInf = TRUE;
+ }
+ else {
+ ax.isNaN = TRUE;
+ }
+ }
+ else {
+ ax.exp = expField - 0x3FF;
+ ax.sig.a0 |= 0x00100000;
+ }
+ ax.sig = shortShift64Left( ax.sig, 3 );
+ return ax;
+
+}
+
+static float64 floatXToFloat64( floatX zx )
+{
+ floatX savedZ;
+ flag isTiny;
+ int16 expField;
+ float64 z;
+
+#ifdef BITS64
+ if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
+ if ( zx.isInf ) {
+ return
+ zx.sign ? LIT64( 0xFFF0000000000000 )
+ : LIT64( 0x7FF0000000000000 );
+ }
+ if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+#else
+ if ( zx.isZero ) {
+ z.low = 0;
+ z.high = zx.sign ? 0x80000000 : 0;
+ return z;
+ }
+ if ( zx.isInf ) {
+ z.low = 0;
+ z.high = zx.sign ? 0xFFF00000 : 0x7FF00000;
+ return z;
+ }
+ if ( zx.isNaN ) {
+ z.high = z.low = 0xFFFFFFFF;
+ return z;
+ }
+#endif
+ while ( 0x01000000 <= zx.sig.a0 ) {
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ ++zx.exp;
+ }
+ while ( zx.sig.a0 < 0x00800000 ) {
+ zx.sig = shortShift64Left( zx.sig, 1 );
+ --zx.exp;
+ }
+ savedZ = zx;
+ isTiny =
+ ( slow_float_detect_tininess == float_tininess_before_rounding )
+ && ( zx.exp + 0x3FF <= 0 );
+ zx = roundFloatXTo53( isTiny, zx );
+ expField = zx.exp + 0x3FF;
+ if ( 0x7FF <= expField ) {
+ slow_float_exception_flags |=
+ float_flag_overflow | float_flag_inexact;
+#ifdef BITS64
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z = LIT64( 0xFFF0000000000000 );
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ z = LIT64( 0xFFEFFFFFFFFFFFFF );
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z = LIT64( 0x7FF0000000000000 );
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ z = LIT64( 0x7FEFFFFFFFFFFFFF );
+ break;
+ }
+ }
+#else
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z.low = 0;
+ z.high = 0xFFF00000;
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ z.low = 0xFFFFFFFF;
+ z.high = 0xFFEFFFFF;
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z.low = 0;
+ z.high = 0x7FF00000;
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ z.low = 0xFFFFFFFF;
+ z.high = 0x7FEFFFFF;
+ break;
+ }
+ }
+#endif
+ return z;
+ }
+ if ( expField <= 0 ) {
+ isTiny = TRUE;
+ zx = savedZ;
+ expField = zx.exp + 0x3FF;
+ if ( expField < -56 ) {
+ zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expField <= 0 ) {
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ ++expField;
+ }
+ }
+ zx = roundFloatXTo53( isTiny, zx );
+ expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
+ }
+ zx.sig = shortShift64RightJamming( zx.sig, 3 );
+#ifdef BITS64
+ z = expField;
+ z <<= 52;
+ if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
+ z |= ( ( (bits64) ( zx.sig.a0 & 0x000FFFFF ) )<<32 ) | zx.sig.a1;
+#else
+ z.low = zx.sig.a1;
+ z.high = expField;
+ z.high <<= 52 - 32;
+ if ( zx.sign ) z.high |= 0x80000000;
+ z.high |= zx.sig.a0 & 0x000FFFFF;
+#endif
+ return z;
+
+}
+
+static floatX floatXInvalid( void )
+{
+
+ slow_float_exception_flags |= float_flag_invalid;
+ return floatXNaN;
+
+}
+
+static floatX floatXRoundToInt( floatX ax )
+{
+ int16 shiftCount, i;
+
+ if ( ax.isNaN || ax.isInf ) return ax;
+ shiftCount = 52 - ax.exp;
+ if ( shiftCount <= 0 ) return ax;
+ if ( 55 < shiftCount ) {
+ ax.exp = 52;
+ ax.sig.a1 = ! ax.isZero;
+ ax.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < shiftCount ) {
+ ax.sig = shortShift64RightJamming( ax.sig, 1 );
+ ++ax.exp;
+ --shiftCount;
+ }
+ }
+ ax = roundFloatXTo53( FALSE, ax );
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+ return ax;
+
+}
+
+static floatX floatXAdd( floatX ax, floatX bx )
+{
+ int16 expDiff;
+ floatX zx;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf && bx.isInf ) {
+ if ( ax.sign == bx.sign ) return ax;
+ return floatXInvalid();
+ }
+ if ( ax.isInf ) return ax;
+ if ( bx.isInf ) return bx;
+ if ( ax.isZero && bx.isZero ) {
+ if ( ax.sign == bx.sign ) return ax;
+ goto completeCancellation;
+ }
+ if ( ( ax.sign != bx.sign )
+ && ( ax.exp == bx.exp )
+ && eq64( ax.sig, bx.sig )
+ ) {
+ completeCancellation:
+ return
+ ( slow_float_rounding_mode == float_round_down ) ?
+ floatXNegativeZero
+ : floatXPositiveZero;
+ }
+ if ( ax.isZero ) return bx;
+ if ( bx.isZero ) return ax;
+ expDiff = ax.exp - bx.exp;
+ if ( expDiff < 0 ) {
+ zx = ax;
+ zx.exp = bx.exp;
+ if ( expDiff < -56 ) {
+ zx.sig.a1 = 1;
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expDiff < 0 ) {
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ ++expDiff;
+ }
+ }
+ if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
+ zx.sign = bx.sign;
+ zx.sig = add64( zx.sig, bx.sig );
+ }
+ else {
+ zx = bx;
+ zx.exp = ax.exp;
+ if ( 56 < expDiff ) {
+ zx.sig.a1 = 1;
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < expDiff ) {
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ --expDiff;
+ }
+ }
+ if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
+ zx.sign = ax.sign;
+ zx.sig = add64( zx.sig, ax.sig );
+ }
+ if ( zx.sig.a0 & 0x80000000 ) {
+ zx.sig = neg64( zx.sig );
+ zx.sign = ! zx.sign;
+ }
+ return zx;
+
+}
+
+static floatX floatXMul( floatX ax, floatX bx )
+{
+ int8 bitNum;
+ floatX zx;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf ) {
+ if ( bx.isZero ) return floatXInvalid();
+ if ( bx.sign ) ax.sign = ! ax.sign;
+ return ax;
+ }
+ if ( bx.isInf ) {
+ if ( ax.isZero ) return floatXInvalid();
+ if ( ax.sign ) bx.sign = ! bx.sign;
+ return bx;
+ }
+ zx = ax;
+ zx.sign ^= bx.sign;
+ if ( ax.isZero || bx.isZero ) {
+ return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+ }
+ zx.exp += bx.exp + 1;
+ zx.sig.a1 = 0;
+ zx.sig.a0 = 0;
+ for ( bitNum = 0; bitNum < 55; ++bitNum ) {
+ if ( bx.sig.a1 & 2 ) zx.sig = add64( zx.sig, ax.sig );
+ bx.sig = shortShift64RightJamming( bx.sig, 1 );
+ zx.sig = shortShift64RightJamming( zx.sig, 1 );
+ }
+ return zx;
+
+}
+
+static floatX floatXDiv( floatX ax, floatX bx )
+{
+ bits64X negBSig;
+ int8 bitNum;
+ floatX zx;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf ) {
+ if ( bx.isInf ) return floatXInvalid();
+ if ( bx.sign ) ax.sign = ! ax.sign;
+ return ax;
+ }
+ if ( bx.isZero ) {
+ if ( ax.isZero ) return floatXInvalid();
+ slow_float_exception_flags |= float_flag_divbyzero;
+ if ( ax.sign ) bx.sign = ! bx.sign;
+ bx.isZero = FALSE;
+ bx.isInf = TRUE;
+ return bx;
+ }
+ zx = ax;
+ zx.sign ^= bx.sign;
+ if ( ax.isZero || bx.isInf ) {
+ return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+ }
+ zx.exp -= bx.exp + 1;
+ zx.sig.a1 = 0;
+ zx.sig.a0 = 0;
+ negBSig = neg64( bx.sig );
+ for ( bitNum = 0; bitNum < 56; ++bitNum ) {
+ if ( le64( bx.sig, ax.sig ) ) {
+ zx.sig.a1 |= 1;
+ ax.sig = add64( ax.sig, negBSig );
+ }
+ ax.sig = shortShift64Left( ax.sig, 1 );
+ zx.sig = shortShift64Left( zx.sig, 1 );
+ }
+ if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+ return zx;
+
+}
+
+static floatX floatXRem( floatX ax, floatX bx )
+{
+ bits64X negBSig;
+ flag lastQuotientBit;
+ bits64X savedASig;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf || bx.isZero ) return floatXInvalid();
+ if ( ax.isZero || bx.isInf ) return ax;
+ --bx.exp;
+ if ( ax.exp < bx.exp ) return ax;
+ bx.sig = shortShift64Left( bx.sig, 1 );
+ negBSig = neg64( bx.sig );
+ while ( bx.exp < ax.exp ) {
+ if ( le64( bx.sig, ax.sig ) ) ax.sig = add64( ax.sig, negBSig );
+ ax.sig = shortShift64Left( ax.sig, 1 );
+ --ax.exp;
+ }
+ lastQuotientBit = le64( bx.sig, ax.sig );
+ if ( lastQuotientBit ) ax.sig = add64( ax.sig, negBSig );
+ savedASig = ax.sig;
+ ax.sig = neg64( add64( ax.sig, negBSig ) );
+ if ( lt64( ax.sig, savedASig ) ) {
+ ax.sign = ! ax.sign;
+ }
+ else if ( lt64( savedASig, ax.sig ) ) {
+ ax.sig = savedASig;
+ }
+ else {
+ if ( lastQuotientBit ) {
+ ax.sign = ! ax.sign;
+ }
+ else {
+ ax.sig = savedASig;
+ }
+ }
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+ return ax;
+
+}
+
+static floatX floatXSqrt( floatX ax )
+{
+ int8 bitNum;
+ bits64X bitSig, savedASig;
+ floatX zx;
+
+ if ( ax.isNaN || ax.isZero ) return ax;
+ if ( ax.sign ) return floatXInvalid();
+ if ( ax.isInf ) return ax;
+ zx = ax;
+ zx.exp >>= 1;
+ if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift64RightJamming( ax.sig, 1 );
+ zx.sig.a1 = 0;
+ zx.sig.a0 = 0;
+ bitSig.a1 = 0;
+ bitSig.a0 = 0x00800000;
+ for ( bitNum = 0; bitNum < 56; ++bitNum ) {
+ savedASig = ax.sig;
+ ax.sig = add64( ax.sig, neg64( zx.sig ) );
+ ax.sig = shortShift64Left( ax.sig, 1 );
+ ax.sig = add64( ax.sig, neg64( bitSig ) );
+ if ( ax.sig.a0 & 0x80000000 ) {
+ ax.sig = shortShift64Left( savedASig, 1 );
+ }
+ else {
+ zx.sig.a1 |= bitSig.a1;
+ zx.sig.a0 |= bitSig.a0;
+ }
+ bitSig = shortShift64RightJamming( bitSig, 1 );
+ }
+ if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+ return zx;
+
+}
+
+static flag floatXEq( floatX ax, floatX bx )
+{
+
+ if ( ax.isNaN || bx.isNaN ) return FALSE;
+ if ( ax.isZero && bx.isZero ) return TRUE;
+ if ( ax.sign != bx.sign ) return FALSE;
+ if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
+ return ( ax.exp == bx.exp ) && eq64( ax.sig, bx.sig );
+
+}
+
+static flag floatXLe( floatX ax, floatX bx )
+{
+
+ if ( ax.isNaN || bx.isNaN ) return FALSE;
+ if ( ax.isZero && bx.isZero ) return TRUE;
+ if ( ax.sign != bx.sign ) return ax.sign;
+ if ( ax.sign ) {
+ if ( ax.isInf || bx.isZero ) return TRUE;
+ if ( bx.isInf || ax.isZero ) return FALSE;
+ if ( bx.exp < ax.exp ) return TRUE;
+ if ( ax.exp < bx.exp ) return FALSE;
+ return le64( bx.sig, ax.sig );
+ }
+ else {
+ if ( bx.isInf || ax.isZero ) return TRUE;
+ if ( ax.isInf || bx.isZero ) return FALSE;
+ if ( ax.exp < bx.exp ) return TRUE;
+ if ( bx.exp < ax.exp ) return FALSE;
+ return le64( ax.sig, bx.sig );
+ }
+
+}
+
+static flag floatXLt( floatX ax, floatX bx )
+{
+
+ if ( ax.isNaN || bx.isNaN ) return FALSE;
+ if ( ax.isZero && bx.isZero ) return FALSE;
+ if ( ax.sign != bx.sign ) return ax.sign;
+ if ( ax.isInf && bx.isInf ) return FALSE;
+ if ( ax.sign ) {
+ if ( ax.isInf || bx.isZero ) return TRUE;
+ if ( bx.isInf || ax.isZero ) return FALSE;
+ if ( bx.exp < ax.exp ) return TRUE;
+ if ( ax.exp < bx.exp ) return FALSE;
+ return lt64( bx.sig, ax.sig );
+ }
+ else {
+ if ( bx.isInf || ax.isZero ) return TRUE;
+ if ( ax.isInf || bx.isZero ) return FALSE;
+ if ( ax.exp < bx.exp ) return TRUE;
+ if ( bx.exp < ax.exp ) return FALSE;
+ return lt64( ax.sig, bx.sig );
+ }
+
+}
+
+float32 slow_int32_to_float32( int32 a )
+{
+
+ return floatXToFloat32( int32ToFloatX( a ) );
+
+}
+
+float64 slow_int32_to_float64( int32 a )
+{
+
+ return floatXToFloat64( int32ToFloatX( a ) );
+
+}
+
+int32 slow_float32_to_int32( float32 a )
+{
+
+ return floatXToInt32( float32ToFloatX( a ) );
+
+}
+
+int32 slow_float32_to_int32_round_to_zero( float32 a )
+{
+ int8 savedRoundingMode;
+ int32 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt32( float32ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+float64 slow_float32_to_float64( float32 a )
+{
+
+ return floatXToFloat64( float32ToFloatX( a ) );
+
+}
+
+float32 slow_float32_round_to_int( float32 a )
+{
+
+ return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
+
+}
+
+float32 slow_float32_add( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sub( float32 a, float32 b )
+{
+
+ b ^= 0x80000000;
+ return
+ floatXToFloat32(
+ floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_mul( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_div( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_rem( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sqrt( float32 a )
+{
+
+ return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
+
+}
+
+flag slow_float32_eq( float32 a, float32 b )
+{
+
+ return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_le( float32 a, float32 b )
+{
+ floatX ax, bx;
+
+ ax = float32ToFloatX( a );
+ bx = float32ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLe( ax, bx );
+
+}
+
+flag slow_float32_lt( float32 a, float32 b )
+{
+ floatX ax, bx;
+
+ ax = float32ToFloatX( a );
+ bx = float32ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLt( ax, bx );
+
+}
+
+flag slow_float32_eq_signaling( float32 a, float32 b )
+{
+ floatX ax, bx;
+
+ ax = float32ToFloatX( a );
+ bx = float32ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXEq( ax, bx );
+
+}
+
+flag slow_float32_le_quiet( float32 a, float32 b )
+{
+
+ return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_lt_quiet( float32 a, float32 b )
+{
+
+ return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+int32 slow_float64_to_int32( float64 a )
+{
+
+ return floatXToInt32( float64ToFloatX( a ) );
+
+}
+
+int32 slow_float64_to_int32_round_to_zero( float64 a )
+{
+ int8 savedRoundingMode;
+ int32 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt32( float64ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+float32 slow_float64_to_float32( float64 a )
+{
+
+ return floatXToFloat32( float64ToFloatX( a ) );
+
+}
+
+float64 slow_float64_round_to_int( float64 a )
+{
+
+ return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
+
+}
+
+float64 slow_float64_add( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sub( float64 a, float64 b )
+{
+
+#ifdef BITS64
+ b ^= LIT64( 0x8000000000000000 );
+#else
+ b.high ^= 0x80000000;
+#endif
+ return
+ floatXToFloat64(
+ floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_mul( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_div( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_rem( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sqrt( float64 a )
+{
+
+ return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
+
+}
+
+flag slow_float64_eq( float64 a, float64 b )
+{
+
+ return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_le( float64 a, float64 b )
+{
+ floatX ax, bx;
+
+ ax = float64ToFloatX( a );
+ bx = float64ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLe( ax, bx );
+
+}
+
+flag slow_float64_lt( float64 a, float64 b )
+{
+ floatX ax, bx;
+
+ ax = float64ToFloatX( a );
+ bx = float64ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLt( ax, bx );
+
+}
+
+flag slow_float64_eq_signaling( float64 a, float64 b )
+{
+ floatX ax, bx;
+
+ ax = float64ToFloatX( a );
+ bx = float64ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXEq( ax, bx );
+
+}
+
+flag slow_float64_le_quiet( float64 a, float64 b )
+{
+
+ return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_lt_quiet( float64 a, float64 b )
+{
+
+ return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
diff --git a/tools/test/testfloat/slowfloat-64.c b/tools/test/testfloat/slowfloat-64.c
new file mode 100644
index 0000000..27e56e1
--- /dev/null
+++ b/tools/test/testfloat/slowfloat-64.c
@@ -0,0 +1,2109 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+int8 slow_float_rounding_mode;
+int8 slow_float_exception_flags;
+int8 slow_float_detect_tininess;
+#ifdef FLOATX80
+int8 slow_floatx80_rounding_precision;
+#endif
+
+typedef struct {
+ bits64 a0, a1;
+} bits128X;
+
+typedef struct {
+ flag isNaN;
+ flag isInf;
+ flag isZero;
+ flag sign;
+ int32 exp;
+ bits128X sig;
+} floatX;
+
+static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
+static const floatX floatXPositiveZero =
+ { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
+static const floatX floatXNegativeZero =
+ { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
+
+static bits128X shortShift128Left( bits128X a, int8 shiftCount )
+{
+ int8 negShiftCount;
+
+ negShiftCount = ( - shiftCount & 63 );
+ a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
+ a.a1 <<= shiftCount;
+ return a;
+
+}
+
+static bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
+{
+ int8 negShiftCount;
+ bits64 extra;
+
+ negShiftCount = ( - shiftCount & 63 );
+ extra = a.a1<<negShiftCount;
+ a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
+ a.a0 >>= shiftCount;
+ return a;
+
+}
+
+static bits128X neg128( bits128X a )
+{
+
+ if ( a.a1 == 0 ) {
+ a.a0 = - a.a0;
+ }
+ else {
+ a.a1 = - a.a1;
+ a.a0 = ~ a.a0;
+ }
+ return a;
+
+}
+
+static bits128X add128( bits128X a, bits128X b )
+{
+
+ a.a1 += b.a1;
+ a.a0 += b.a0 + ( a.a1 < b.a1 );
+ return a;
+
+}
+
+static flag eq128( bits128X a, bits128X b )
+{
+
+ return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
+
+}
+
+static flag le128( bits128X a, bits128X b )
+{
+
+ return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
+
+}
+
+static flag lt128( bits128X a, bits128X b )
+{
+
+ return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
+
+}
+
+static floatX roundFloatXTo24( flag isTiny, floatX zx )
+{
+ bits32 roundBits;
+
+ zx.sig.a0 |= ( zx.sig.a1 != 0 );
+ zx.sig.a1 = 0;
+ roundBits = zx.sig.a0 & 0xFFFFFFFF;
+ zx.sig.a0 -= roundBits;
+ if ( roundBits ) {
+ slow_float_exception_flags |= float_flag_inexact;
+ if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( roundBits < 0x80000000 ) goto noIncrement;
+ if ( ( roundBits == 0x80000000 )
+ && ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
+ goto noIncrement;
+ }
+ break;
+ case float_round_to_zero:
+ goto noIncrement;
+ case float_round_down:
+ if ( ! zx.sign ) goto noIncrement;
+ break;
+ case float_round_up:
+ if ( zx.sign ) goto noIncrement;
+ break;
+ }
+ zx.sig.a0 += LIT64( 0x100000000 );
+ if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+ zx.sig.a0 = LIT64( 0x0080000000000000 );
+ ++zx.exp;
+ }
+ }
+ noIncrement:
+ return zx;
+
+}
+
+static floatX roundFloatXTo53( flag isTiny, floatX zx )
+{
+ int8 roundBits;
+
+ zx.sig.a0 |= ( zx.sig.a1 != 0 );
+ zx.sig.a1 = 0;
+ roundBits = zx.sig.a0 & 7;
+ zx.sig.a0 -= roundBits;
+ if ( roundBits ) {
+ slow_float_exception_flags |= float_flag_inexact;
+ if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( roundBits < 4 ) goto noIncrement;
+ if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
+ break;
+ case float_round_to_zero:
+ goto noIncrement;
+ case float_round_down:
+ if ( ! zx.sign ) goto noIncrement;
+ break;
+ case float_round_up:
+ if ( zx.sign ) goto noIncrement;
+ break;
+ }
+ zx.sig.a0 += 8;
+ if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+ zx.sig.a0 = LIT64( 0x0080000000000000 );
+ ++zx.exp;
+ }
+ }
+ noIncrement:
+ return zx;
+
+}
+
+static floatX roundFloatXTo64( flag isTiny, floatX zx )
+{
+ int64 roundBits;
+
+ roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
+ zx.sig.a1 -= roundBits;
+ if ( roundBits ) {
+ slow_float_exception_flags |= float_flag_inexact;
+ if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
+ if ( ( roundBits == LIT64( 0x0080000000000000 ) )
+ && ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
+ goto noIncrement;
+ }
+ break;
+ case float_round_to_zero:
+ goto noIncrement;
+ case float_round_down:
+ if ( ! zx.sign ) goto noIncrement;
+ break;
+ case float_round_up:
+ if ( zx.sign ) goto noIncrement;
+ break;
+ }
+ zx.sig.a1 += LIT64( 0x0100000000000000 );
+ zx.sig.a0 += ( zx.sig.a1 == 0 );
+ if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+ zx.sig.a0 = LIT64( 0x0080000000000000 );
+ ++zx.exp;
+ }
+ }
+ noIncrement:
+ return zx;
+
+}
+
+static floatX roundFloatXTo113( flag isTiny, floatX zx )
+{
+ int8 roundBits;
+
+ roundBits = zx.sig.a1 & 0x7F;
+ zx.sig.a1 -= roundBits;
+ if ( roundBits ) {
+ slow_float_exception_flags |= float_flag_inexact;
+ if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( roundBits < 0x40 ) goto noIncrement;
+ if ( ( roundBits == 0x40 )
+ && ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
+ break;
+ case float_round_to_zero:
+ goto noIncrement;
+ case float_round_down:
+ if ( ! zx.sign ) goto noIncrement;
+ break;
+ case float_round_up:
+ if ( zx.sign ) goto noIncrement;
+ break;
+ }
+ zx.sig.a1 += 0x80;
+ zx.sig.a0 += ( zx.sig.a1 == 0 );
+ if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+ zx.sig.a0 = LIT64( 0x0080000000000000 );
+ ++zx.exp;
+ }
+ }
+ noIncrement:
+ return zx;
+
+}
+
+static floatX int32ToFloatX( int32 a )
+{
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.sign = ( a < 0 );
+ ax.sig.a1 = 0;
+ ax.sig.a0 = ax.sign ? - (bits64) a : a;
+ if ( a == 0 ) {
+ ax.isZero = TRUE;
+ return ax;
+ }
+ ax.isZero = FALSE;
+ ax.sig.a0 <<= 24;
+ ax.exp = 31;
+ while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+ ax.sig.a0 <<= 1;
+ --ax.exp;
+ }
+ return ax;
+
+}
+
+static int32 floatXToInt32( floatX ax )
+{
+ int8 savedExceptionFlags;
+ int32 shiftCount;
+ int32 z;
+
+ if ( ax.isInf || ax.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( ax.isZero ) return 0;
+ savedExceptionFlags = slow_float_exception_flags;
+ shiftCount = 52 - ax.exp;
+ if ( 56 < shiftCount ) {
+ ax.sig.a1 = 1;
+ ax.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < shiftCount ) {
+ ax.sig = shortShift128RightJamming( ax.sig, 1 );
+ --shiftCount;
+ }
+ }
+ ax = roundFloatXTo53( FALSE, ax );
+ ax.sig = shortShift128RightJamming( ax.sig, 3 );
+ z = ax.sig.a0;
+ if ( ax.sign ) z = - z;
+ if ( ( shiftCount < 0 )
+ || ( ax.sig.a0>>32 )
+ || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
+ ) {
+ slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
+ return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
+ }
+ return z;
+
+}
+
+static floatX int64ToFloatX( int64 a )
+{
+ uint64 absA;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.sign = ( a < 0 );
+ ax.sig.a1 = ax.sign ? - a : a;
+ ax.sig.a0 = 0;
+ if ( a == 0 ) {
+ ax.isZero = TRUE;
+ return ax;
+ }
+ ax.isZero = FALSE;
+ ax.sig = shortShift128Left( ax.sig, 56 );
+ ax.exp = 63;
+ while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+ ax.sig = shortShift128Left( ax.sig, 1 );
+ --ax.exp;
+ }
+ return ax;
+
+}
+
+static int64 floatXToInt64( floatX ax )
+{
+ int8 savedExceptionFlags;
+ int32 shiftCount;
+ int64 z;
+
+ if ( ax.isInf || ax.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ return
+ ( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
+ : LIT64( 0x7FFFFFFFFFFFFFFF );
+ }
+ if ( ax.isZero ) return 0;
+ savedExceptionFlags = slow_float_exception_flags;
+ shiftCount = 112 - ax.exp;
+ if ( 116 < shiftCount ) {
+ ax.sig.a1 = 1;
+ ax.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < shiftCount ) {
+ ax.sig = shortShift128RightJamming( ax.sig, 1 );
+ --shiftCount;
+ }
+ }
+ ax = roundFloatXTo113( FALSE, ax );
+ ax.sig = shortShift128RightJamming( ax.sig, 7 );
+ z = ax.sig.a1;
+ if ( ax.sign ) z = - z;
+ if ( ( shiftCount < 0 )
+ || ax.sig.a0
+ || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
+ ) {
+ slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
+ return
+ ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
+ : LIT64( 0x7FFFFFFFFFFFFFFF );
+ }
+ return z;
+
+}
+
+static floatX float32ToFloatX( float32 a )
+{
+ int16 expField;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.isZero = FALSE;
+ ax.sign = ( ( a & 0x80000000 ) != 0 );
+ expField = ( a>>23 ) & 0xFF;
+ ax.sig.a1 = 0;
+ ax.sig.a0 = a & 0x007FFFFF;
+ ax.sig.a0 <<= 32;
+ if ( expField == 0 ) {
+ if ( ax.sig.a0 == 0 ) {
+ ax.isZero = TRUE;
+ }
+ else {
+ expField = 1 - 0x7F;
+ do {
+ ax.sig.a0 <<= 1;
+ --expField;
+ } while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
+ ax.exp = expField;
+ }
+ }
+ else if ( expField == 0xFF ) {
+ if ( ax.sig.a0 == 0 ) {
+ ax.isInf = TRUE;
+ }
+ else {
+ ax.isNaN = TRUE;
+ }
+ }
+ else {
+ ax.sig.a0 |= LIT64( 0x0080000000000000 );
+ ax.exp = expField - 0x7F;
+ }
+ return ax;
+
+}
+
+static float32 floatXToFloat32( floatX zx )
+{
+ floatX savedZ;
+ flag isTiny;
+ int32 expField;
+ float32 z;
+
+ if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
+ if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
+ if ( zx.isNaN ) return 0xFFFFFFFF;
+ while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++zx.exp;
+ }
+ while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+ zx.sig = shortShift128Left( zx.sig, 1 );
+ --zx.exp;
+ }
+ savedZ = zx;
+ isTiny =
+ ( slow_float_detect_tininess == float_tininess_before_rounding )
+ && ( zx.exp + 0x7F <= 0 );
+ zx = roundFloatXTo24( isTiny, zx );
+ expField = zx.exp + 0x7F;
+ if ( 0xFF <= expField ) {
+ slow_float_exception_flags |=
+ float_flag_overflow | float_flag_inexact;
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z = 0xFF800000;
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ z = 0xFF7FFFFF;
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z = 0x7F800000;
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ z = 0x7F7FFFFF;
+ break;
+ }
+ }
+ return z;
+ }
+ if ( expField <= 0 ) {
+ isTiny = TRUE;
+ zx = savedZ;
+ expField = zx.exp + 0x7F;
+ if ( expField < -27 ) {
+ zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expField <= 0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++expField;
+ }
+ }
+ zx = roundFloatXTo24( isTiny, zx );
+ expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+ }
+ z = expField;
+ z <<= 23;
+ if ( zx.sign ) z |= 0x80000000;
+ z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
+ return z;
+
+}
+
+static floatX float64ToFloatX( float64 a )
+{
+ int16 expField;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.isZero = FALSE;
+ ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
+ expField = ( a>>52 ) & 0x7FF;
+ ax.sig.a1 = 0;
+ ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
+ if ( expField == 0 ) {
+ if ( ax.sig.a0 == 0 ) {
+ ax.isZero = TRUE;
+ }
+ else {
+ expField = 1 - 0x3FF;
+ do {
+ ax.sig.a0 <<= 1;
+ --expField;
+ } while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
+ ax.exp = expField;
+ }
+ }
+ else if ( expField == 0x7FF ) {
+ if ( ax.sig.a0 == 0 ) {
+ ax.isInf = TRUE;
+ }
+ else {
+ ax.isNaN = TRUE;
+ }
+ }
+ else {
+ ax.exp = expField - 0x3FF;
+ ax.sig.a0 |= LIT64( 0x0010000000000000 );
+ }
+ ax.sig.a0 <<= 3;
+ return ax;
+
+}
+
+static float64 floatXToFloat64( floatX zx )
+{
+ floatX savedZ;
+ flag isTiny;
+ int32 expField;
+ float64 z;
+
+ if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
+ if ( zx.isInf ) {
+ return
+ zx.sign ? LIT64( 0xFFF0000000000000 )
+ : LIT64( 0x7FF0000000000000 );
+ }
+ if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+ while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++zx.exp;
+ }
+ while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+ zx.sig = shortShift128Left( zx.sig, 1 );
+ --zx.exp;
+ }
+ savedZ = zx;
+ isTiny =
+ ( slow_float_detect_tininess == float_tininess_before_rounding )
+ && ( zx.exp + 0x3FF <= 0 );
+ zx = roundFloatXTo53( isTiny, zx );
+ expField = zx.exp + 0x3FF;
+ if ( 0x7FF <= expField ) {
+ slow_float_exception_flags |=
+ float_flag_overflow | float_flag_inexact;
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z = LIT64( 0xFFF0000000000000 );
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ z = LIT64( 0xFFEFFFFFFFFFFFFF );
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z = LIT64( 0x7FF0000000000000 );
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ z = LIT64( 0x7FEFFFFFFFFFFFFF );
+ break;
+ }
+ }
+ return z;
+ }
+ if ( expField <= 0 ) {
+ isTiny = TRUE;
+ zx = savedZ;
+ expField = zx.exp + 0x3FF;
+ if ( expField < -56 ) {
+ zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expField <= 0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++expField;
+ }
+ }
+ zx = roundFloatXTo53( isTiny, zx );
+ expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+ }
+ zx.sig.a0 >>= 3;
+ z = expField;
+ z <<= 52;
+ if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
+ z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
+ return z;
+
+}
+
+#ifdef FLOATX80
+
+static floatX floatx80ToFloatX( floatx80 a )
+{
+ int32 expField;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.isZero = FALSE;
+ ax.sign = ( ( a.high & 0x8000 ) != 0 );
+ expField = a.high & 0x7FFF;
+ ax.sig.a1 = a.low;
+ ax.sig.a0 = 0;
+ if ( expField == 0 ) {
+ if ( ax.sig.a1 == 0 ) {
+ ax.isZero = TRUE;
+ }
+ else {
+ expField = 1 - 0x3FFF;
+ while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
+ ax.sig.a1 <<= 1;
+ --expField;
+ }
+ ax.exp = expField;
+ }
+ }
+ else if ( expField == 0x7FFF ) {
+ if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
+ ax.isInf = TRUE;
+ }
+ else {
+ ax.isNaN = TRUE;
+ }
+ }
+ else {
+ ax.exp = expField - 0x3FFF;
+ }
+ ax.sig = shortShift128Left( ax.sig, 56 );
+ return ax;
+
+}
+
+static floatx80 floatXToFloatx80( floatX zx )
+{
+ floatX savedZ;
+ flag isTiny;
+ int32 expField;
+ floatx80 z;
+
+ if ( zx.isZero ) {
+ z.low = 0;
+ z.high = zx.sign ? 0x8000 : 0;
+ return z;
+ }
+ if ( zx.isInf ) {
+ z.low = LIT64( 0x8000000000000000 );
+ z.high = zx.sign ? 0xFFFF : 0x7FFF;
+ return z;
+ }
+ if ( zx.isNaN ) {
+ z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+ z.high = 0xFFFF;
+ return z;
+ }
+ while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++zx.exp;
+ }
+ while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+ zx.sig = shortShift128Left( zx.sig, 1 );
+ --zx.exp;
+ }
+ savedZ = zx;
+ isTiny =
+ ( slow_float_detect_tininess == float_tininess_before_rounding )
+ && ( zx.exp + 0x3FFF <= 0 );
+ switch ( slow_floatx80_rounding_precision ) {
+ case 32:
+ zx = roundFloatXTo24( isTiny, zx );
+ break;
+ case 64:
+ zx = roundFloatXTo53( isTiny, zx );
+ break;
+ default:
+ zx = roundFloatXTo64( isTiny, zx );
+ break;
+ }
+ expField = zx.exp + 0x3FFF;
+ if ( 0x7FFF <= expField ) {
+ slow_float_exception_flags |=
+ float_flag_overflow | float_flag_inexact;
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z.low = LIT64( 0x8000000000000000 );
+ z.high = 0xFFFF;
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ switch ( slow_floatx80_rounding_precision ) {
+ case 32:
+ z.low = LIT64( 0xFFFFFF0000000000 );
+ break;
+ case 64:
+ z.low = LIT64( 0xFFFFFFFFFFFFF800 );
+ break;
+ default:
+ z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+ break;
+ }
+ z.high = 0xFFFE;
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z.low = LIT64( 0x8000000000000000 );
+ z.high = 0x7FFF;
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ switch ( slow_floatx80_rounding_precision ) {
+ case 32:
+ z.low = LIT64( 0xFFFFFF0000000000 );
+ break;
+ case 64:
+ z.low = LIT64( 0xFFFFFFFFFFFFF800 );
+ break;
+ default:
+ z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+ break;
+ }
+ z.high = 0x7FFE;
+ break;
+ }
+ }
+ return z;
+ }
+ if ( expField <= 0 ) {
+ isTiny = TRUE;
+ zx = savedZ;
+ expField = zx.exp + 0x3FFF;
+ if ( expField < -70 ) {
+ zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expField <= 0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++expField;
+ }
+ }
+ switch ( slow_floatx80_rounding_precision ) {
+ case 32:
+ zx = roundFloatXTo24( isTiny, zx );
+ break;
+ case 64:
+ zx = roundFloatXTo53( isTiny, zx );
+ break;
+ default:
+ zx = roundFloatXTo64( isTiny, zx );
+ break;
+ }
+ expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+ }
+ zx.sig = shortShift128RightJamming( zx.sig, 56 );
+ z.low = zx.sig.a1;
+ z.high = expField;
+ if ( zx.sign ) z.high |= 0x8000;
+ return z;
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+static floatX float128ToFloatX( float128 a )
+{
+ int32 expField;
+ floatX ax;
+
+ ax.isNaN = FALSE;
+ ax.isInf = FALSE;
+ ax.isZero = FALSE;
+ ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
+ expField = ( a.high>>48 ) & 0x7FFF;
+ ax.sig.a1 = a.low;
+ ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
+ if ( expField == 0 ) {
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+ ax.isZero = TRUE;
+ }
+ else {
+ expField = 1 - 0x3FFF;
+ do {
+ ax.sig = shortShift128Left( ax.sig, 1 );
+ --expField;
+ } while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
+ ax.exp = expField;
+ }
+ }
+ else if ( expField == 0x7FFF ) {
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+ ax.isInf = TRUE;
+ }
+ else {
+ ax.isNaN = TRUE;
+ }
+ }
+ else {
+ ax.exp = expField - 0x3FFF;
+ ax.sig.a0 |= LIT64( 0x0001000000000000 );
+ }
+ ax.sig = shortShift128Left( ax.sig, 7 );
+ return ax;
+
+}
+
+static float128 floatXToFloat128( floatX zx )
+{
+ floatX savedZ;
+ flag isTiny;
+ int32 expField;
+ float128 z;
+
+ if ( zx.isZero ) {
+ z.low = 0;
+ z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
+ return z;
+ }
+ if ( zx.isInf ) {
+ z.low = 0;
+ z.high =
+ zx.sign ? LIT64( 0xFFFF000000000000 )
+ : LIT64( 0x7FFF000000000000 );
+ return z;
+ }
+ if ( zx.isNaN ) {
+ z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+ return z;
+ }
+ while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++zx.exp;
+ }
+ while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+ zx.sig = shortShift128Left( zx.sig, 1 );
+ --zx.exp;
+ }
+ savedZ = zx;
+ isTiny =
+ ( slow_float_detect_tininess == float_tininess_before_rounding )
+ && ( zx.exp + 0x3FFF <= 0 );
+ zx = roundFloatXTo113( isTiny, zx );
+ expField = zx.exp + 0x3FFF;
+ if ( 0x7FFF <= expField ) {
+ slow_float_exception_flags |=
+ float_flag_overflow | float_flag_inexact;
+ if ( zx.sign ) {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_down:
+ z.low = 0;
+ z.high = LIT64( 0xFFFF000000000000 );
+ break;
+ case float_round_to_zero:
+ case float_round_up:
+ z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+ z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
+ break;
+ }
+ }
+ else {
+ switch ( slow_float_rounding_mode ) {
+ case float_round_nearest_even:
+ case float_round_up:
+ z.low = 0;
+ z.high = LIT64( 0x7FFF000000000000 );
+ break;
+ case float_round_to_zero:
+ case float_round_down:
+ z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+ z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
+ break;
+ }
+ }
+ return z;
+ }
+ if ( expField <= 0 ) {
+ isTiny = TRUE;
+ zx = savedZ;
+ expField = zx.exp + 0x3FFF;
+ if ( expField < -120 ) {
+ zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expField <= 0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++expField;
+ }
+ }
+ zx = roundFloatXTo113( isTiny, zx );
+ expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+ }
+ zx.sig = shortShift128RightJamming( zx.sig, 7 );
+ z.low = zx.sig.a1;
+ z.high = expField;
+ z.high <<= 48;
+ if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
+ z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
+ return z;
+
+}
+
+#endif
+
+static floatX floatXInvalid( void )
+{
+
+ slow_float_exception_flags |= float_flag_invalid;
+ return floatXNaN;
+
+}
+
+static floatX floatXRoundToInt( floatX ax )
+{
+ int32 shiftCount, i;
+
+ if ( ax.isNaN || ax.isInf ) return ax;
+ shiftCount = 112 - ax.exp;
+ if ( shiftCount <= 0 ) return ax;
+ if ( 119 < shiftCount ) {
+ ax.exp = 112;
+ ax.sig.a1 = ! ax.isZero;
+ ax.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < shiftCount ) {
+ ax.sig = shortShift128RightJamming( ax.sig, 1 );
+ ++ax.exp;
+ --shiftCount;
+ }
+ }
+ ax = roundFloatXTo113( FALSE, ax );
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+ return ax;
+
+}
+
+static floatX floatXAdd( floatX ax, floatX bx )
+{
+ int32 expDiff;
+ floatX zx;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf && bx.isInf ) {
+ if ( ax.sign == bx.sign ) return ax;
+ return floatXInvalid();
+ }
+ if ( ax.isInf ) return ax;
+ if ( bx.isInf ) return bx;
+ if ( ax.isZero && bx.isZero ) {
+ if ( ax.sign == bx.sign ) return ax;
+ goto completeCancellation;
+ }
+ if ( ( ax.sign != bx.sign )
+ && ( ax.exp == bx.exp )
+ && eq128( ax.sig, bx.sig )
+ ) {
+ completeCancellation:
+ return
+ ( slow_float_rounding_mode == float_round_down ) ?
+ floatXNegativeZero
+ : floatXPositiveZero;
+ }
+ if ( ax.isZero ) return bx;
+ if ( bx.isZero ) return ax;
+ expDiff = ax.exp - bx.exp;
+ if ( expDiff < 0 ) {
+ zx = ax;
+ zx.exp = bx.exp;
+ if ( expDiff < -120 ) {
+ zx.sig.a1 = 1;
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( expDiff < 0 ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ ++expDiff;
+ }
+ }
+ if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
+ zx.sign = bx.sign;
+ zx.sig = add128( zx.sig, bx.sig );
+ }
+ else {
+ zx = bx;
+ zx.exp = ax.exp;
+ if ( 120 < expDiff ) {
+ zx.sig.a1 = 1;
+ zx.sig.a0 = 0;
+ }
+ else {
+ while ( 0 < expDiff ) {
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ --expDiff;
+ }
+ }
+ if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
+ zx.sign = ax.sign;
+ zx.sig = add128( zx.sig, ax.sig );
+ }
+ if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
+ zx.sig = neg128( zx.sig );
+ zx.sign = ! zx.sign;
+ }
+ return zx;
+
+}
+
+static floatX floatXMul( floatX ax, floatX bx )
+{
+ int8 bitNum;
+ floatX zx;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf ) {
+ if ( bx.isZero ) return floatXInvalid();
+ if ( bx.sign ) ax.sign = ! ax.sign;
+ return ax;
+ }
+ if ( bx.isInf ) {
+ if ( ax.isZero ) return floatXInvalid();
+ if ( ax.sign ) bx.sign = ! bx.sign;
+ return bx;
+ }
+ zx = ax;
+ zx.sign ^= bx.sign;
+ if ( ax.isZero || bx.isZero ) {
+ return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+ }
+ zx.exp += bx.exp + 1;
+ zx.sig.a1 = 0;
+ zx.sig.a0 = 0;
+ for ( bitNum = 0; bitNum < 119; ++bitNum ) {
+ if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
+ bx.sig = shortShift128RightJamming( bx.sig, 1 );
+ zx.sig = shortShift128RightJamming( zx.sig, 1 );
+ }
+ return zx;
+
+}
+
+static floatX floatXDiv( floatX ax, floatX bx )
+{
+ bits128X negBSig;
+ int8 bitNum;
+ floatX zx;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf ) {
+ if ( bx.isInf ) return floatXInvalid();
+ if ( bx.sign ) ax.sign = ! ax.sign;
+ return ax;
+ }
+ if ( bx.isZero ) {
+ if ( ax.isZero ) return floatXInvalid();
+ slow_float_exception_flags |= float_flag_divbyzero;
+ if ( ax.sign ) bx.sign = ! bx.sign;
+ bx.isZero = FALSE;
+ bx.isInf = TRUE;
+ return bx;
+ }
+ zx = ax;
+ zx.sign ^= bx.sign;
+ if ( ax.isZero || bx.isInf ) {
+ return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+ }
+ zx.exp -= bx.exp + 1;
+ zx.sig.a1 = 0;
+ zx.sig.a0 = 0;
+ negBSig = neg128( bx.sig );
+ for ( bitNum = 0; bitNum < 120; ++bitNum ) {
+ if ( le128( bx.sig, ax.sig ) ) {
+ zx.sig.a1 |= 1;
+ ax.sig = add128( ax.sig, negBSig );
+ }
+ ax.sig = shortShift128Left( ax.sig, 1 );
+ zx.sig = shortShift128Left( zx.sig, 1 );
+ }
+ if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+ return zx;
+
+}
+
+static floatX floatXRem( floatX ax, floatX bx )
+{
+ bits128X negBSig;
+ flag lastQuotientBit;
+ bits128X savedASig;
+
+ if ( ax.isNaN ) return ax;
+ if ( bx.isNaN ) return bx;
+ if ( ax.isInf || bx.isZero ) return floatXInvalid();
+ if ( ax.isZero || bx.isInf ) return ax;
+ --bx.exp;
+ if ( ax.exp < bx.exp ) return ax;
+ bx.sig = shortShift128Left( bx.sig, 1 );
+ negBSig = neg128( bx.sig );
+ while ( bx.exp < ax.exp ) {
+ if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
+ ax.sig = shortShift128Left( ax.sig, 1 );
+ --ax.exp;
+ }
+ lastQuotientBit = le128( bx.sig, ax.sig );
+ if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
+ savedASig = ax.sig;
+ ax.sig = neg128( add128( ax.sig, negBSig ) );
+ if ( lt128( ax.sig, savedASig ) ) {
+ ax.sign = ! ax.sign;
+ }
+ else if ( lt128( savedASig, ax.sig ) ) {
+ ax.sig = savedASig;
+ }
+ else {
+ if ( lastQuotientBit ) {
+ ax.sign = ! ax.sign;
+ }
+ else {
+ ax.sig = savedASig;
+ }
+ }
+ if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+ return ax;
+
+}
+
+static floatX floatXSqrt( floatX ax )
+{
+ int8 bitNum;
+ bits128X bitSig, savedASig;
+ floatX zx;
+
+ if ( ax.isNaN || ax.isZero ) return ax;
+ if ( ax.sign ) return floatXInvalid();
+ if ( ax.isInf ) return ax;
+ zx = ax;
+ zx.exp >>= 1;
+ if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
+ zx.sig.a1 = 0;
+ zx.sig.a0 = 0;
+ bitSig.a1 = 0;
+ bitSig.a0 = LIT64( 0x0080000000000000 );
+ for ( bitNum = 0; bitNum < 120; ++bitNum ) {
+ savedASig = ax.sig;
+ ax.sig = add128( ax.sig, neg128( zx.sig ) );
+ ax.sig = shortShift128Left( ax.sig, 1 );
+ ax.sig = add128( ax.sig, neg128( bitSig ) );
+ if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
+ ax.sig = shortShift128Left( savedASig, 1 );
+ }
+ else {
+ zx.sig.a1 |= bitSig.a1;
+ zx.sig.a0 |= bitSig.a0;
+ }
+ bitSig = shortShift128RightJamming( bitSig, 1 );
+ }
+ if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+ return zx;
+
+}
+
+static flag floatXEq( floatX ax, floatX bx )
+{
+
+ if ( ax.isNaN || bx.isNaN ) return FALSE;
+ if ( ax.isZero && bx.isZero ) return TRUE;
+ if ( ax.sign != bx.sign ) return FALSE;
+ if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
+ return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
+
+}
+
+static flag floatXLe( floatX ax, floatX bx )
+{
+
+ if ( ax.isNaN || bx.isNaN ) return FALSE;
+ if ( ax.isZero && bx.isZero ) return TRUE;
+ if ( ax.sign != bx.sign ) return ax.sign;
+ if ( ax.sign ) {
+ if ( ax.isInf || bx.isZero ) return TRUE;
+ if ( bx.isInf || ax.isZero ) return FALSE;
+ if ( bx.exp < ax.exp ) return TRUE;
+ if ( ax.exp < bx.exp ) return FALSE;
+ return le128( bx.sig, ax.sig );
+ }
+ else {
+ if ( bx.isInf || ax.isZero ) return TRUE;
+ if ( ax.isInf || bx.isZero ) return FALSE;
+ if ( ax.exp < bx.exp ) return TRUE;
+ if ( bx.exp < ax.exp ) return FALSE;
+ return le128( ax.sig, bx.sig );
+ }
+
+}
+
+static flag floatXLt( floatX ax, floatX bx )
+{
+
+ if ( ax.isNaN || bx.isNaN ) return FALSE;
+ if ( ax.isZero && bx.isZero ) return FALSE;
+ if ( ax.sign != bx.sign ) return ax.sign;
+ if ( ax.isInf && bx.isInf ) return FALSE;
+ if ( ax.sign ) {
+ if ( ax.isInf || bx.isZero ) return TRUE;
+ if ( bx.isInf || ax.isZero ) return FALSE;
+ if ( bx.exp < ax.exp ) return TRUE;
+ if ( ax.exp < bx.exp ) return FALSE;
+ return lt128( bx.sig, ax.sig );
+ }
+ else {
+ if ( bx.isInf || ax.isZero ) return TRUE;
+ if ( ax.isInf || bx.isZero ) return FALSE;
+ if ( ax.exp < bx.exp ) return TRUE;
+ if ( bx.exp < ax.exp ) return FALSE;
+ return lt128( ax.sig, bx.sig );
+ }
+
+}
+
+float32 slow_int32_to_float32( int32 a )
+{
+
+ return floatXToFloat32( int32ToFloatX( a ) );
+
+}
+
+float64 slow_int32_to_float64( int32 a )
+{
+
+ return floatXToFloat64( int32ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_int32_to_floatx80( int32 a )
+{
+
+ return floatXToFloatx80( int32ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_int32_to_float128( int32 a )
+{
+
+ return floatXToFloat128( int32ToFloatX( a ) );
+
+}
+
+#endif
+
+float32 slow_int64_to_float32( int64 a )
+{
+
+ return floatXToFloat32( int64ToFloatX( a ) );
+
+}
+
+float64 slow_int64_to_float64( int64 a )
+{
+
+ return floatXToFloat64( int64ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_int64_to_floatx80( int64 a )
+{
+
+ return floatXToFloatx80( int64ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_int64_to_float128( int64 a )
+{
+
+ return floatXToFloat128( int64ToFloatX( a ) );
+
+}
+
+#endif
+
+int32 slow_float32_to_int32( float32 a )
+{
+
+ return floatXToInt32( float32ToFloatX( a ) );
+
+}
+
+int32 slow_float32_to_int32_round_to_zero( float32 a )
+{
+ int8 savedRoundingMode;
+ int32 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt32( float32ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+int64 slow_float32_to_int64( float32 a )
+{
+
+ return floatXToInt64( float32ToFloatX( a ) );
+
+}
+
+int64 slow_float32_to_int64_round_to_zero( float32 a )
+{
+ int8 savedRoundingMode;
+ int64 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt64( float32ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+float64 slow_float32_to_float64( float32 a )
+{
+
+ return floatXToFloat64( float32ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_float32_to_floatx80( float32 a )
+{
+
+ return floatXToFloatx80( float32ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_float32_to_float128( float32 a )
+{
+
+ return floatXToFloat128( float32ToFloatX( a ) );
+
+}
+
+#endif
+
+float32 slow_float32_round_to_int( float32 a )
+{
+
+ return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
+
+}
+
+float32 slow_float32_add( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sub( float32 a, float32 b )
+{
+
+ b ^= 0x80000000;
+ return
+ floatXToFloat32(
+ floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_mul( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_div( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_rem( float32 a, float32 b )
+{
+
+ return
+ floatXToFloat32(
+ floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sqrt( float32 a )
+{
+
+ return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
+
+}
+
+flag slow_float32_eq( float32 a, float32 b )
+{
+
+ return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_le( float32 a, float32 b )
+{
+ floatX ax, bx;
+
+ ax = float32ToFloatX( a );
+ bx = float32ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLe( ax, bx );
+
+}
+
+flag slow_float32_lt( float32 a, float32 b )
+{
+ floatX ax, bx;
+
+ ax = float32ToFloatX( a );
+ bx = float32ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLt( ax, bx );
+
+}
+
+flag slow_float32_eq_signaling( float32 a, float32 b )
+{
+ floatX ax, bx;
+
+ ax = float32ToFloatX( a );
+ bx = float32ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXEq( ax, bx );
+
+}
+
+flag slow_float32_le_quiet( float32 a, float32 b )
+{
+
+ return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_lt_quiet( float32 a, float32 b )
+{
+
+ return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+int32 slow_float64_to_int32( float64 a )
+{
+
+ return floatXToInt32( float64ToFloatX( a ) );
+
+}
+
+int32 slow_float64_to_int32_round_to_zero( float64 a )
+{
+ int8 savedRoundingMode;
+ int32 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt32( float64ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+int64 slow_float64_to_int64( float64 a )
+{
+
+ return floatXToInt64( float64ToFloatX( a ) );
+
+}
+
+int64 slow_float64_to_int64_round_to_zero( float64 a )
+{
+ int8 savedRoundingMode;
+ int64 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt64( float64ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+float32 slow_float64_to_float32( float64 a )
+{
+
+ return floatXToFloat32( float64ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_float64_to_floatx80( float64 a )
+{
+
+ return floatXToFloatx80( float64ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_float64_to_float128( float64 a )
+{
+
+ return floatXToFloat128( float64ToFloatX( a ) );
+
+}
+
+#endif
+
+float64 slow_float64_round_to_int( float64 a )
+{
+
+ return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
+
+}
+
+float64 slow_float64_add( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sub( float64 a, float64 b )
+{
+
+ b ^= LIT64( 0x8000000000000000 );
+ return
+ floatXToFloat64(
+ floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_mul( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_div( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_rem( float64 a, float64 b )
+{
+
+ return
+ floatXToFloat64(
+ floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sqrt( float64 a )
+{
+
+ return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
+
+}
+
+flag slow_float64_eq( float64 a, float64 b )
+{
+
+ return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_le( float64 a, float64 b )
+{
+ floatX ax, bx;
+
+ ax = float64ToFloatX( a );
+ bx = float64ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLe( ax, bx );
+
+}
+
+flag slow_float64_lt( float64 a, float64 b )
+{
+ floatX ax, bx;
+
+ ax = float64ToFloatX( a );
+ bx = float64ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLt( ax, bx );
+
+}
+
+flag slow_float64_eq_signaling( float64 a, float64 b )
+{
+ floatX ax, bx;
+
+ ax = float64ToFloatX( a );
+ bx = float64ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXEq( ax, bx );
+
+}
+
+flag slow_float64_le_quiet( float64 a, float64 b )
+{
+
+ return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_lt_quiet( float64 a, float64 b )
+{
+
+ return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+#ifdef FLOATX80
+
+int32 slow_floatx80_to_int32( floatx80 a )
+{
+
+ return floatXToInt32( floatx80ToFloatX( a ) );
+
+}
+
+int32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
+{
+ int8 savedRoundingMode;
+ int32 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt32( floatx80ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+int64 slow_floatx80_to_int64( floatx80 a )
+{
+
+ return floatXToInt64( floatx80ToFloatX( a ) );
+
+}
+
+int64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
+{
+ int8 savedRoundingMode;
+ int64 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt64( floatx80ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+float32 slow_floatx80_to_float32( floatx80 a )
+{
+
+ return floatXToFloat32( floatx80ToFloatX( a ) );
+
+}
+
+float64 slow_floatx80_to_float64( floatx80 a )
+{
+
+ return floatXToFloat64( floatx80ToFloatX( a ) );
+
+}
+
+#ifdef FLOAT128
+
+float128 slow_floatx80_to_float128( floatx80 a )
+{
+
+ return floatXToFloat128( floatx80ToFloatX( a ) );
+
+}
+
+#endif
+
+floatx80 slow_floatx80_round_to_int( floatx80 a )
+{
+
+ return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
+
+}
+
+floatx80 slow_floatx80_add( floatx80 a, floatx80 b )
+{
+
+ return
+ floatXToFloatx80(
+ floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
+{
+
+ b.high ^= 0x8000;
+ return
+ floatXToFloatx80(
+ floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
+{
+
+ return
+ floatXToFloatx80(
+ floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_div( floatx80 a, floatx80 b )
+{
+
+ return
+ floatXToFloatx80(
+ floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
+{
+
+ return
+ floatXToFloatx80(
+ floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_sqrt( floatx80 a )
+{
+
+ return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
+
+}
+
+flag slow_floatx80_eq( floatx80 a, floatx80 b )
+{
+
+ return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
+
+}
+
+flag slow_floatx80_le( floatx80 a, floatx80 b )
+{
+ floatX ax, bx;
+
+ ax = floatx80ToFloatX( a );
+ bx = floatx80ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLe( ax, bx );
+
+}
+
+flag slow_floatx80_lt( floatx80 a, floatx80 b )
+{
+ floatX ax, bx;
+
+ ax = floatx80ToFloatX( a );
+ bx = floatx80ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLt( ax, bx );
+
+}
+
+flag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
+{
+ floatX ax, bx;
+
+ ax = floatx80ToFloatX( a );
+ bx = floatx80ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXEq( ax, bx );
+
+}
+
+flag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
+{
+
+ return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
+
+}
+
+flag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
+{
+
+ return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+int32 slow_float128_to_int32( float128 a )
+{
+
+ return floatXToInt32( float128ToFloatX( a ) );
+
+}
+
+int32 slow_float128_to_int32_round_to_zero( float128 a )
+{
+ int8 savedRoundingMode;
+ int32 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt32( float128ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+int64 slow_float128_to_int64( float128 a )
+{
+
+ return floatXToInt64( float128ToFloatX( a ) );
+
+}
+
+int64 slow_float128_to_int64_round_to_zero( float128 a )
+{
+ int8 savedRoundingMode;
+ int64 z;
+
+ savedRoundingMode = slow_float_rounding_mode;
+ slow_float_rounding_mode = float_round_to_zero;
+ z = floatXToInt64( float128ToFloatX( a ) );
+ slow_float_rounding_mode = savedRoundingMode;
+ return z;
+
+}
+
+float32 slow_float128_to_float32( float128 a )
+{
+
+ return floatXToFloat32( float128ToFloatX( a ) );
+
+}
+
+float64 slow_float128_to_float64( float128 a )
+{
+
+ return floatXToFloat64( float128ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_float128_to_floatx80( float128 a )
+{
+
+ return floatXToFloatx80( float128ToFloatX( a ) );
+
+}
+
+#endif
+
+float128 slow_float128_round_to_int( float128 a )
+{
+
+ return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
+
+}
+
+float128 slow_float128_add( float128 a, float128 b )
+{
+
+ return
+ floatXToFloat128(
+ floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_sub( float128 a, float128 b )
+{
+
+ b.high ^= LIT64( 0x8000000000000000 );
+ return
+ floatXToFloat128(
+ floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_mul( float128 a, float128 b )
+{
+
+ return
+ floatXToFloat128(
+ floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_div( float128 a, float128 b )
+{
+
+ return
+ floatXToFloat128(
+ floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_rem( float128 a, float128 b )
+{
+
+ return
+ floatXToFloat128(
+ floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_sqrt( float128 a )
+{
+
+ return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
+
+}
+
+flag slow_float128_eq( float128 a, float128 b )
+{
+
+ return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
+
+}
+
+flag slow_float128_le( float128 a, float128 b )
+{
+ floatX ax, bx;
+
+ ax = float128ToFloatX( a );
+ bx = float128ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLe( ax, bx );
+
+}
+
+flag slow_float128_lt( float128 a, float128 b )
+{
+ floatX ax, bx;
+
+ ax = float128ToFloatX( a );
+ bx = float128ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXLt( ax, bx );
+
+}
+
+flag slow_float128_eq_signaling( float128 a, float128 b )
+{
+ floatX ax, bx;
+
+ ax = float128ToFloatX( a );
+ bx = float128ToFloatX( b );
+ if ( ax.isNaN || bx.isNaN ) {
+ slow_float_exception_flags |= float_flag_invalid;
+ }
+ return floatXEq( ax, bx );
+
+}
+
+flag slow_float128_le_quiet( float128 a, float128 b )
+{
+
+ return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
+
+}
+
+flag slow_float128_lt_quiet( float128 a, float128 b )
+{
+
+ return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
+
+}
+
+#endif
+
diff --git a/tools/test/testfloat/slowfloat.c b/tools/test/testfloat/slowfloat.c
new file mode 100644
index 0000000..ea69f82
--- /dev/null
+++ b/tools/test/testfloat/slowfloat.c
@@ -0,0 +1,35 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+#include "slowfloat.h"
+
+#ifdef BITS64
+#include "slowfloat-64.c"
+#else
+#include "slowfloat-32.c"
+#endif
+
diff --git a/tools/test/testfloat/slowfloat.h b/tools/test/testfloat/slowfloat.h
new file mode 100644
index 0000000..45c6c6b
--- /dev/null
+++ b/tools/test/testfloat/slowfloat.h
@@ -0,0 +1,167 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+extern int8 slow_float_rounding_mode;
+extern int8 slow_float_exception_flags;
+extern int8 slow_float_detect_tininess;
+#ifdef FLOATX80
+extern int8 slow_floatx80_rounding_precision;
+#endif
+
+float32 slow_int32_to_float32( int32 );
+float64 slow_int32_to_float64( int32 );
+#ifdef FLOATX80
+floatx80 slow_int32_to_floatx80( int32 );
+#endif
+#ifdef FLOAT128
+float128 slow_int32_to_float128( int32 );
+#endif
+#ifdef BITS64
+float32 slow_int64_to_float32( int64 );
+float64 slow_int64_to_float64( int64 );
+#ifdef FLOATX80
+floatx80 slow_int64_to_floatx80( int64 );
+#endif
+#ifdef FLOAT128
+float128 slow_int64_to_float128( int64 );
+#endif
+#endif
+
+int32 slow_float32_to_int32( float32 );
+int32 slow_float32_to_int32_round_to_zero( float32 );
+#ifdef BITS64
+int64 slow_float32_to_int64( float32 );
+int64 slow_float32_to_int64_round_to_zero( float32 );
+#endif
+float64 slow_float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 slow_float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 slow_float32_to_float128( float32 );
+#endif
+
+float32 slow_float32_round_to_int( float32 );
+float32 slow_float32_add( float32, float32 );
+float32 slow_float32_sub( float32, float32 );
+float32 slow_float32_mul( float32, float32 );
+float32 slow_float32_div( float32, float32 );
+float32 slow_float32_rem( float32, float32 );
+float32 slow_float32_sqrt( float32 );
+flag slow_float32_eq( float32, float32 );
+flag slow_float32_le( float32, float32 );
+flag slow_float32_lt( float32, float32 );
+flag slow_float32_eq_signaling( float32, float32 );
+flag slow_float32_le_quiet( float32, float32 );
+flag slow_float32_lt_quiet( float32, float32 );
+
+int32 slow_float64_to_int32( float64 );
+int32 slow_float64_to_int32_round_to_zero( float64 );
+#ifdef BITS64
+int64 slow_float64_to_int64( float64 );
+int64 slow_float64_to_int64_round_to_zero( float64 );
+#endif
+float32 slow_float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 slow_float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 slow_float64_to_float128( float64 );
+#endif
+
+float64 slow_float64_round_to_int( float64 );
+float64 slow_float64_add( float64, float64 );
+float64 slow_float64_sub( float64, float64 );
+float64 slow_float64_mul( float64, float64 );
+float64 slow_float64_div( float64, float64 );
+float64 slow_float64_rem( float64, float64 );
+float64 slow_float64_sqrt( float64 );
+flag slow_float64_eq( float64, float64 );
+flag slow_float64_le( float64, float64 );
+flag slow_float64_lt( float64, float64 );
+flag slow_float64_eq_signaling( float64, float64 );
+flag slow_float64_le_quiet( float64, float64 );
+flag slow_float64_lt_quiet( float64, float64 );
+
+#ifdef FLOATX80
+
+int32 slow_floatx80_to_int32( floatx80 );
+int32 slow_floatx80_to_int32_round_to_zero( floatx80 );
+#ifdef BITS64
+int64 slow_floatx80_to_int64( floatx80 );
+int64 slow_floatx80_to_int64_round_to_zero( floatx80 );
+#endif
+float32 slow_floatx80_to_float32( floatx80 );
+float64 slow_floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 slow_floatx80_to_float128( floatx80 );
+#endif
+
+floatx80 slow_floatx80_round_to_int( floatx80 );
+floatx80 slow_floatx80_add( floatx80, floatx80 );
+floatx80 slow_floatx80_sub( floatx80, floatx80 );
+floatx80 slow_floatx80_mul( floatx80, floatx80 );
+floatx80 slow_floatx80_div( floatx80, floatx80 );
+floatx80 slow_floatx80_rem( floatx80, floatx80 );
+floatx80 slow_floatx80_sqrt( floatx80 );
+flag slow_floatx80_eq( floatx80, floatx80 );
+flag slow_floatx80_le( floatx80, floatx80 );
+flag slow_floatx80_lt( floatx80, floatx80 );
+flag slow_floatx80_eq_signaling( floatx80, floatx80 );
+flag slow_floatx80_le_quiet( floatx80, floatx80 );
+flag slow_floatx80_lt_quiet( floatx80, floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+int32 slow_float128_to_int32( float128 );
+int32 slow_float128_to_int32_round_to_zero( float128 );
+#ifdef BITS64
+int64 slow_float128_to_int64( float128 );
+int64 slow_float128_to_int64_round_to_zero( float128 );
+#endif
+float32 slow_float128_to_float32( float128 );
+float64 slow_float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 slow_float128_to_floatx80( float128 );
+#endif
+
+float128 slow_float128_round_to_int( float128 );
+float128 slow_float128_add( float128, float128 );
+float128 slow_float128_sub( float128, float128 );
+float128 slow_float128_mul( float128, float128 );
+float128 slow_float128_div( float128, float128 );
+float128 slow_float128_rem( float128, float128 );
+float128 slow_float128_sqrt( float128 );
+flag slow_float128_eq( float128, float128 );
+flag slow_float128_le( float128, float128 );
+flag slow_float128_lt( float128, float128 );
+flag slow_float128_eq_signaling( float128, float128 );
+flag slow_float128_le_quiet( float128, float128 );
+flag slow_float128_lt_quiet( float128, float128 );
+
+#endif
+
diff --git a/tools/test/testfloat/sparc64/Makefile b/tools/test/testfloat/sparc64/Makefile
new file mode 100644
index 0000000..a24834b
--- /dev/null
+++ b/tools/test/testfloat/sparc64/Makefile
@@ -0,0 +1,105 @@
+# Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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$
+
+.PATH: ${.CURDIR}/../../../../lib/libc/softfloat/bits64 ${.CURDIR}/..
+
+LIBC_DIR= ${.CURDIR}/../../../../lib/libc
+EMUFLOAT_DIR= ${LIBC_DIR}/sparc64/fpu
+
+LN= ln -sf
+
+# Common source files
+SRCS1= fail.c random.c softfloat.c testCases.c testLoops.c writeHex.c
+
+# Additional common sources to build testfloat/testemufloat
+SRCS2= testFunction.c testfloat.c
+
+# Additional sources to build testemufloat
+SRCS3= fpu.c fpu_add.c fpu_compare.c fpu_div.c fpu_emul.S fpu_explode.c \
+ fpu_implode.c fpu_mul.c fpu_qp.c fpu_sqrt.c fpu_subr.c fpu_util.c
+
+# Additional sources to build testfloat
+SRCS4= systflags.c systfloat.S systmodes.c
+
+# Additional sources to build testsoftfloat
+SRCS5= slowfloat.c testsoftfloat.c
+
+SRCS= ${SRCS1} ${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5}
+
+OBJ_TF= ${SRCS1:R:S/$/.o/g} ${SRCS2:R:S/$/.o/g} ${SRCS4:R:S/$/.o/g}
+OBJ_TEF= ${SRCS1:R:S/$/.o/g} ${SRCS2:R:S/$/.o/g} ${SRCS3:R:S/$/.o/g}
+OBJ_TSF= ${SRCS1:R:S/$/.o/g} ${SRCS5:R:S/$/.o/g}
+
+all: testfloat testemufloat testsoftfloat
+
+CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/.. -I${LIBC_DIR}/sparc64/fpu \
+ -I${LIBC_DIR}/sparc64/sys -I${LIBC_DIR}/softfloat/bits64 \
+ -I${LIBC_DIR}/softfloat
+
+CLEANFILES+= fpu.c fpu_add.c fpu_compare.c fpu_div.c fpu_emu.h \
+ fpu_explode.c fpu_implode.c fpu_mul.c fpu_qp.c fpu_sqrt.c fpu_subr.c \
+ ${SRCS:R:S/$/.o/g} testfloat testemufloat testsoftfloat
+
+testsoftfloat: ${OBJ_TSF}
+ ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJ_TSF}
+
+testfloat: ${OBJ_TF}
+ ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJ_TF}
+
+testemufloat: ${OBJ_TEF}
+ ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJ_TEF}
+
+beforedepend: fpu_emu.h
+
+# The emulator code needs to be built with a local fpu_reg.h instead of
+# the one in ${EMUFLOAT_DIR}. Unfortunately, C preprocessor semantics
+# means that a header file in the same directory as the source file
+# overrides any alternative header file location. In order to include
+# the wanted header file, create symlinks pointing to the real files
+# and compile through the symlink.
+fpu.c: ${EMUFLOAT_DIR}/fpu.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_add.c: ${EMUFLOAT_DIR}/fpu_add.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_compare.c: ${EMUFLOAT_DIR}/fpu_compare.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_div.c: ${EMUFLOAT_DIR}/fpu_div.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_emu.h: ${EMUFLOAT_DIR}/fpu_emu.h
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_explode.c: ${EMUFLOAT_DIR}/fpu_explode.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_implode.c: ${EMUFLOAT_DIR}/fpu_implode.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_mul.c: ${EMUFLOAT_DIR}/fpu_mul.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_qp.c: ${EMUFLOAT_DIR}/fpu_qp.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_sqrt.c: ${EMUFLOAT_DIR}/fpu_sqrt.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+fpu_subr.c: ${EMUFLOAT_DIR}/fpu_subr.c
+ ${LN} ${.ALLSRC} ${.TARGET}
+
+.include <bsd.prog.mk>
diff --git a/tools/test/testfloat/sparc64/fpu_emul.S b/tools/test/testfloat/sparc64/fpu_emul.S
new file mode 100644
index 0000000..0872e89
--- /dev/null
+++ b/tools/test/testfloat/sparc64/fpu_emul.S
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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 <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+ .section "rodata1",#alloc
+ .align 8
+
+ .global insn_int32_to_float32
+insn_int32_to_float32:
+ fitos %f0,%f0
+
+ .global insn_int32_to_float64
+insn_int32_to_float64:
+ fitod %f0,%f0
+
+ .global insn_int32_to_float128
+insn_int32_to_float128:
+ fitoq %f0,%f0
+
+ .global insn_int64_to_float32
+insn_int64_to_float32:
+ fxtos %f0,%f0
+
+ .global insn_int64_to_float64
+insn_int64_to_float64:
+ fxtod %f0,%f0
+
+ .global insn_int64_to_float128
+insn_int64_to_float128:
+ fxtoq %f0,%f0
+
+ .global insn_float32_to_int32_round_to_zero
+insn_float32_to_int32_round_to_zero:
+ fstoi %f0,%f0
+
+ .global insn_float32_to_int64_round_to_zero
+insn_float32_to_int64_round_to_zero:
+ fstox %f0,%f0
+
+ .global insn_float32_to_float64
+insn_float32_to_float64:
+ fstod %f0,%f0
+
+ .global insn_float32_to_float128
+insn_float32_to_float128:
+ fstoq %f0,%f0
+
+ .global insn_float32_add
+insn_float32_add:
+ fadds %f0,%f1,%f0
+
+ .global insn_float32_sub
+insn_float32_sub:
+ fsubs %f0,%f1,%f0
+
+ .global insn_float32_mul
+insn_float32_mul:
+ fmuls %f0,%f1,%f0
+
+ .global insn_float32_div
+insn_float32_div:
+ fdivs %f0,%f1,%f0
+
+ .global insn_float32_sqrt
+insn_float32_sqrt:
+ fsqrts %f0,%f0
+
+ .global insn_float32_cmp
+insn_float32_cmp:
+ fcmps %fcc0,%f0,%f1
+
+ .global insn_float32_cmpe
+insn_float32_cmpe:
+ fcmpes %fcc0,%f0,%f1
+
+ .global insn_float64_to_int32_round_to_zero
+insn_float64_to_int32_round_to_zero:
+ fdtoi %f0,%f0
+
+ .global insn_float64_to_int64_round_to_zero
+insn_float64_to_int64_round_to_zero:
+ fdtox %f0,%f0
+
+ .global insn_float64_to_float32
+insn_float64_to_float32:
+ fdtos %f0,%f0
+
+ .global insn_float64_to_float128
+insn_float64_to_float128:
+ fdtoq %f0,%f0
+
+ .global insn_float64_add
+insn_float64_add:
+ faddd %f0,%f2,%f0
+
+ .global insn_float64_sub
+insn_float64_sub:
+ fsubd %f0,%f2,%f0
+
+ .global insn_float64_mul
+insn_float64_mul:
+ fmuld %f0,%f2,%f0
+
+ .global insn_float64_div
+insn_float64_div:
+ fdivd %f0,%f2,%f0
+
+ .global insn_float64_sqrt
+insn_float64_sqrt:
+ fsqrtd %f0,%f0
+
+ .global insn_float64_cmp
+insn_float64_cmp:
+ fcmpd %fcc0,%f0,%f2
+
+ .global insn_float64_cmpe
+insn_float64_cmpe:
+ fcmped %fcc0,%f0,%f2
+
+ .global insn_float128_to_int32_round_to_zero
+insn_float128_to_int32_round_to_zero:
+ fqtoi %f0,%f0
+
+ .global insn_float128_to_int64_round_to_zero
+insn_float128_to_int64_round_to_zero:
+ fqtox %f0,%f0
+
+ .global insn_float128_to_float32
+insn_float128_to_float32:
+ fqtos %f0,%f0
+
+ .global insn_float128_to_float64
+insn_float128_to_float64:
+ fqtod %f0,%f0
+
+ .global insn_float128_add
+insn_float128_add:
+ faddq %f0,%f4,%f0
+
+ .global insn_float128_sub
+insn_float128_sub:
+ fsubq %f0,%f4,%f0
+
+ .global insn_float128_mul
+insn_float128_mul:
+ fmulq %f0,%f4,%f0
+
+ .global insn_float128_div
+insn_float128_div:
+ fdivq %f0,%f4,%f0
+
+ .global insn_float128_sqrt
+insn_float128_sqrt:
+ fsqrtq %f0,%f0
+
+ .global insn_float128_cmp
+insn_float128_cmp:
+ fcmpq %fcc0,%f0,%f4
+
+ .global insn_float128_cmpe
+insn_float128_cmpe:
+ fcmpeq %fcc0,%f0,%f4
diff --git a/tools/test/testfloat/sparc64/fpu_reg.h b/tools/test/testfloat/sparc64/fpu_reg.h
new file mode 100644
index 0000000..76f7244
--- /dev/null
+++ b/tools/test/testfloat/sparc64/fpu_reg.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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 _TESTFLOAT_SPARC64_FPU_REG_H_
+#define _TESTFLOAT_SPARC64_FPU_REG_H_
+
+#include <sys/types.h>
+extern u_int32_t __fpreg[64];
+
+static __inline u_int32_t
+__fpu_getreg(int r)
+{
+
+ return (__fpreg[r]);
+}
+
+static __inline u_int64_t
+__fpu_getreg64(int r)
+{
+
+ return ((u_int64_t)__fpreg[r] << 32 | (u_int64_t)__fpreg[r + 1]);
+}
+
+static __inline void
+__fpu_setreg(int r, u_int32_t v)
+{
+
+ __fpreg[r] = v;
+}
+
+static __inline void
+__fpu_setreg64(int r, u_int64_t v)
+{
+
+ __fpreg[r] = (u_int32_t)(v >> 32);
+ __fpreg[r + 1] = (u_int32_t)v;
+}
+
+#endif /* _TESTFLOAT_SPARC64_FPU_REG_H_ */
diff --git a/tools/test/testfloat/sparc64/fpu_util.c b/tools/test/testfloat/sparc64/fpu_util.c
new file mode 100644
index 0000000..1b766e0
--- /dev/null
+++ b/tools/test/testfloat/sparc64/fpu_util.c
@@ -0,0 +1,706 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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 <sys/param.h>
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "__sparc_utrap_private.h"
+#include "fpu_extern.h"
+#include "fpu_reg.h"
+
+static u_long ireg[32];
+
+void
+__utrap_panic(const char *msg)
+{
+
+ fprintf(stderr, "panic: %s\n", msg);
+ exit(1);
+}
+
+void __utrap_write(const char *msg)
+{
+
+ fprintf(stderr, "%s", msg);
+}
+
+u_long
+__emul_fetch_reg(struct utrapframe *uf, int reg)
+{
+
+ return (ireg[reg]);
+}
+
+typedef unsigned char int8;
+typedef unsigned int int32;
+typedef unsigned long int64;
+typedef unsigned int float32;
+typedef unsigned long float64;
+typedef struct {
+ unsigned long high, low;
+} float128;
+typedef unsigned long flag;
+
+struct utrapframe utf;
+
+u_int32_t __fpreg[64];
+
+static __inline float128
+__fpu_getreg128(int r)
+{
+ float128 v;
+
+ v.high = ((u_int64_t)__fpreg[r] << 32 | (u_int64_t)__fpreg[r + 1]);
+ v.low = ((u_int64_t)__fpreg[r + 2] << 32 | (u_int64_t)__fpreg[r + 3]);
+ return (v);
+}
+
+static __inline void
+__fpu_setreg128(int r, float128 v)
+{
+
+ __fpreg[r] = (u_int32_t)(v.high >> 32);
+ __fpreg[r + 1] = (u_int32_t)v.high;
+ __fpreg[r + 2] = (u_int32_t)(v.low >> 32);
+ __fpreg[r + 3] = (u_int32_t)v.low;
+}
+
+/*
+-------------------------------------------------------------------------------
+Clears the system's IEC/IEEE floating-point exception flags. Returns the
+previous value of the flags.
+-------------------------------------------------------------------------------
+*/
+#include <fenv.h>
+#include <ieeefp.h>
+
+int8 syst_float_flags_clear(void)
+{
+ int32 flags;
+
+ flags = (utf.uf_fsr & FE_ALL_EXCEPT) >> 5;
+ utf.uf_fsr &= ~(u_long)FE_ALL_EXCEPT;
+ return (flags);
+}
+
+static void
+emul_trap(const u_int *insn, u_long mask)
+{
+ u_int32_t savreg[64];
+ int i;
+
+ for (i = 0; i < 64; i++)
+ savreg[i] = __fpreg[i];
+
+ utf.uf_fsr = (utf.uf_fsr & ~FSR_FTT_MASK) |
+ (FSR_FTT_UNFIN << FSR_FTT_SHIFT);
+ utf.uf_pc = (u_long)insn;
+ if (__fpu_exception(&utf) == 0)
+ __asm("stx %%fsr,%0" : "=m" (utf.uf_fsr));
+
+ for (i = 0; i < 64; i++) {
+ if (!(mask & (1UL << i)) && savreg[i] != __fpreg[i]) {
+ fprintf(stderr, "### %2d %08x != %08x\n",
+ i, savreg[i], __fpreg[i]);
+ }
+ }
+}
+
+extern u_int insn_int32_to_float32;
+extern u_int insn_int32_to_float64;
+extern u_int insn_int32_to_float128;
+extern u_int insn_int64_to_float32;
+extern u_int insn_int64_to_float64;
+extern u_int insn_int64_to_float128;
+extern u_int insn_float32_to_int32_round_to_zero;
+extern u_int insn_float32_to_int64_round_to_zero;
+extern u_int insn_float32_to_float64;
+extern u_int insn_float32_to_float128;
+extern u_int insn_float32_add;
+extern u_int insn_float32_sub;
+extern u_int insn_float32_mul;
+extern u_int insn_float32_div;
+extern u_int insn_float32_sqrt;
+extern u_int insn_float32_cmp;
+extern u_int insn_float32_cmpe;
+extern u_int insn_float64_to_int32_round_to_zero;
+extern u_int insn_float64_to_int64_round_to_zero;
+extern u_int insn_float64_to_float32;
+extern u_int insn_float64_to_float128;
+extern u_int insn_float64_add;
+extern u_int insn_float64_sub;
+extern u_int insn_float64_mul;
+extern u_int insn_float64_div;
+extern u_int insn_float64_sqrt;
+extern u_int insn_float64_cmp;
+extern u_int insn_float64_cmpe;
+extern u_int insn_float128_to_int32_round_to_zero;
+extern u_int insn_float128_to_int64_round_to_zero;
+extern u_int insn_float128_to_float32;
+extern u_int insn_float128_to_float64;
+extern u_int insn_float128_add;
+extern u_int insn_float128_sub;
+extern u_int insn_float128_mul;
+extern u_int insn_float128_div;
+extern u_int insn_float128_sqrt;
+extern u_int insn_float128_cmp;
+extern u_int insn_float128_cmpe;
+
+float32
+syst_int32_to_float32(int32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_int32_to_float32, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float64
+syst_int32_to_float64(int32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_int32_to_float64, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float128
+syst_int32_to_float128(int32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_int32_to_float128, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float32
+syst_int64_to_float32(int64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_int64_to_float32, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float64
+syst_int64_to_float64(int64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_int64_to_float64, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+
+float128
+syst_int64_to_float128(int64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_int64_to_float128, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+int32
+syst_float32_to_int32_round_to_zero(float32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_float32_to_int32_round_to_zero, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+int64
+syst_float32_to_int64_round_to_zero(float32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_float32_to_int64_round_to_zero, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float64
+syst_float32_to_float64(float32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_float32_to_float64, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float128
+syst_float32_to_float128(float32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_float32_to_float128, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float32
+syst_float32_add(float32 a, float32 b)
+{
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_add, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float32
+syst_float32_sub(float32 a, float32 b)
+{
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_sub, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float32
+syst_float32_mul(float32 a, float32 b)
+{
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_mul, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float32
+syst_float32_div(float32 a, float32 b)
+{
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_div, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float32
+syst_float32_sqrt(float32 a)
+{
+
+ __fpu_setreg(0, a);
+ emul_trap(&insn_float32_sqrt, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+flag syst_float32_eq(float32 a, float32 b)
+{
+ u_long r;
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float32_le(float32 a, float32 b)
+{
+ u_long r;
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float32_lt(float32 a, float32 b)
+{
+ u_long r;
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float32_eq_signaling(float32 a, float32 b)
+{
+ u_long r;
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float32_le_quiet(float32 a, float32 b)
+{
+ u_long r;
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float32_lt_quiet(float32 a, float32 b)
+{
+ u_long r;
+
+ __fpu_setreg(0, a);
+ __fpu_setreg(1, b);
+ emul_trap(&insn_float32_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+int32
+syst_float64_to_int32_round_to_zero(float64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_float64_to_int32_round_to_zero, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+int64
+syst_float64_to_int64_round_to_zero(float64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_float64_to_int64_round_to_zero, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float32
+syst_float64_to_float32(float64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_float64_to_float32, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float128
+syst_float64_to_float128(float64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_float64_to_float128, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float64
+syst_float64_add(float64 a, float64 b)
+{
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_add, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float64
+syst_float64_sub(float64 a, float64 b)
+{
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_sub, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float64
+syst_float64_mul(float64 a, float64 b)
+{
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_mul, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float64
+syst_float64_div(float64 a, float64 b)
+{
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_div, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float64
+syst_float64_sqrt(float64 a)
+{
+
+ __fpu_setreg64(0, a);
+ emul_trap(&insn_float64_sqrt, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+flag syst_float64_eq(float64 a, float64 b)
+{
+ u_long r;
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float64_le(float64 a, float64 b)
+{
+ u_long r;
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float64_lt(float64 a, float64 b)
+{
+ u_long r;
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float64_eq_signaling(float64 a, float64 b)
+{
+ u_long r;
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float64_le_quiet(float64 a, float64 b)
+{
+ u_long r;
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float64_lt_quiet(float64 a, float64 b)
+{
+ u_long r;
+
+ __fpu_setreg64(0, a);
+ __fpu_setreg64(2, b);
+ emul_trap(&insn_float64_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+int32
+syst_float128_to_int32_round_to_zero(float128 a)
+{
+
+ __fpu_setreg128(0, a);
+ emul_trap(&insn_float128_to_int32_round_to_zero, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+int64
+syst_float128_to_int64_round_to_zero(float128 a)
+{
+
+ __fpu_setreg128(0, a);
+ emul_trap(&insn_float128_to_int64_round_to_zero, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float32
+syst_float128_to_float32(float128 a)
+{
+
+ __fpu_setreg128(0, a);
+ emul_trap(&insn_float128_to_float32, 0x1UL);
+ return (__fpu_getreg(0));
+}
+
+float64
+syst_float128_to_float64(float128 a)
+{
+
+ __fpu_setreg128(0, a);
+ emul_trap(&insn_float128_to_float64, 0x3UL);
+ return (__fpu_getreg64(0));
+}
+
+float128
+syst_float128_add(float128 a, float128 b)
+{
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_add, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float128
+syst_float128_sub(float128 a, float128 b)
+{
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_sub, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float128
+syst_float128_mul(float128 a, float128 b)
+{
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_mul, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float128
+syst_float128_div(float128 a, float128 b)
+{
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_div, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+float128
+syst_float128_sqrt(float128 a)
+{
+
+ __fpu_setreg128(0, a);
+ emul_trap(&insn_float128_sqrt, 0xfUL);
+ return (__fpu_getreg128(0));
+}
+
+flag syst_float128_eq(float128 a, float128 b)
+{
+ u_long r;
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float128_le(float128 a, float128 b)
+{
+ u_long r;
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float128_lt(float128 a, float128 b)
+{
+ u_long r;
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float128_eq_signaling(float128 a, float128 b)
+{
+ u_long r;
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_cmpe, 0x0UL);
+ __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float128_le_quiet(float128 a, float128 b)
+{
+ u_long r;
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+flag syst_float128_lt_quiet(float128 a, float128 b)
+{
+ u_long r;
+
+ __fpu_setreg128(0, a);
+ __fpu_setreg128(4, b);
+ emul_trap(&insn_float128_cmp, 0x0UL);
+ __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
+ return (r);
+}
+
+
+/*
+-------------------------------------------------------------------------------
+Sets the system's IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_mode(int8 roundingMode)
+{
+
+ utf.uf_fsr &= ~FSR_RD_MASK;
+ utf.uf_fsr |= FSR_RD((unsigned int)roundingMode & 0x03);
+}
+
+/*
+-------------------------------------------------------------------------------
+Does nothing.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_precision(int8 precision)
+{
+
+}
diff --git a/tools/test/testfloat/sparc64/libc_private.h b/tools/test/testfloat/sparc64/libc_private.h
new file mode 100644
index 0000000..5e7d1bc
--- /dev/null
+++ b/tools/test/testfloat/sparc64/libc_private.h
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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$
+ */
+/*
+ * This file has no content and is solely to satisfy a #include in
+ * the FP emulator code.
+ */
diff --git a/tools/test/testfloat/sparc64/milieu.h b/tools/test/testfloat/sparc64/milieu.h
new file mode 100644
index 0000000..26491d1
--- /dev/null
+++ b/tools/test/testfloat/sparc64/milieu.h
@@ -0,0 +1,56 @@
+#ifndef TESTFLOAT_SPARC64_MILIEU_H_
+#define TESTFLOAT_SPARC64_MILIEU_H_
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/* $FreeBSD$ */
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "sparc64.h"
+
+/*
+-------------------------------------------------------------------------------
+If the `BITS64' macro is defined by the processor header file but the
+version of SoftFloat being used/tested is the 32-bit one (`bits32'), the
+`BITS64' macro must be undefined here.
+-------------------------------------------------------------------------------
+#undef BITS64
+*/
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+ FALSE = 0,
+ TRUE = 1
+};
+
+#endif
diff --git a/tools/test/testfloat/sparc64/namespace.h b/tools/test/testfloat/sparc64/namespace.h
new file mode 100644
index 0000000..5e7d1bc
--- /dev/null
+++ b/tools/test/testfloat/sparc64/namespace.h
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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$
+ */
+/*
+ * This file has no content and is solely to satisfy a #include in
+ * the FP emulator code.
+ */
diff --git a/tools/test/testfloat/sparc64/softfloat.h b/tools/test/testfloat/sparc64/softfloat.h
new file mode 100644
index 0000000..f804b9c
--- /dev/null
+++ b/tools/test/testfloat/sparc64/softfloat.h
@@ -0,0 +1,267 @@
+#ifndef TESTFLOAT_SPARC64_SOFTFLOAT_H
+#define TESTFLOAT_SPARC64_SOFTFLOAT_H
+
+/*============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
+Package, Release 2b.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
+been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
+RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
+AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
+COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
+EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
+INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
+OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) the source code for the derivative work includes prominent notice that
+the work is derivative, and (2) the source code includes prominent notice with
+these four paragraphs for those parts of this code that are retained.
+
+=============================================================================*/
+
+/* $FreeBSD$ */
+
+#include <machine/ieeefp.h>
+
+/*----------------------------------------------------------------------------
+| The macro `FLOATX80' must be defined to enable the extended double-precision
+| floating-point format `floatx80'. If this macro is not defined, the
+| `floatx80' type will not be defined, and none of the functions that either
+| input or output the `floatx80' type will be defined. The same applies to
+| the `FLOAT128' macro and the quadruple-precision format `float128'.
+*----------------------------------------------------------------------------*/
+#define FLOATX80
+#define FLOAT128
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point types.
+*----------------------------------------------------------------------------*/
+typedef unsigned int float32;
+typedef unsigned long float64;
+#ifdef FLOATX80
+typedef struct {
+ unsigned short high;
+ unsigned long low;
+} floatx80;
+#endif
+#ifdef FLOAT128
+typedef struct {
+ unsigned long high, low;
+} float128;
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point underflow tininess-detection mode.
+*----------------------------------------------------------------------------*/
+extern int float_detect_tininess;
+enum {
+ float_tininess_after_rounding = 0,
+ float_tininess_before_rounding = 1
+};
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point rounding mode.
+*----------------------------------------------------------------------------*/
+extern fp_rnd_t float_rounding_mode;
+enum {
+ float_round_nearest_even = 0,
+ float_round_to_zero = 1,
+ float_round_up = 2,
+ float_round_down = 3
+};
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point exception flags.
+*----------------------------------------------------------------------------*/
+typedef int fp_except;
+extern fp_except float_exception_flags;
+enum {
+ float_flag_inexact = 1,
+ float_flag_divbyzero = 2,
+ float_flag_underflow = 4,
+ float_flag_overflow = 8,
+ float_flag_invalid = 16
+};
+
+/*----------------------------------------------------------------------------
+| Routine to raise any or all of the software IEC/IEEE floating-point
+| exception flags.
+*----------------------------------------------------------------------------*/
+void float_raise( int );
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE integer-to-floating-point conversion routines.
+*----------------------------------------------------------------------------*/
+float32 int32_to_float32( int );
+float64 int32_to_float64( int );
+#ifdef FLOATX80
+floatx80 int32_to_floatx80( int );
+#endif
+#ifdef FLOAT128
+float128 int32_to_float128( int );
+#endif
+float32 int64_to_float32( long );
+float64 int64_to_float64( long );
+#ifdef FLOATX80
+floatx80 int64_to_floatx80( long );
+#endif
+#ifdef FLOAT128
+float128 int64_to_float128( long );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE single-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int float32_to_int32( float32 );
+int float32_to_int32_round_to_zero( float32 );
+long float32_to_int64( float32 );
+long float32_to_int64_round_to_zero( float32 );
+float64 float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 float32_to_float128( float32 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE single-precision operations.
+*----------------------------------------------------------------------------*/
+float32 float32_round_to_int( float32 );
+float32 float32_add( float32, float32 );
+float32 float32_sub( float32, float32 );
+float32 float32_mul( float32, float32 );
+float32 float32_div( float32, float32 );
+float32 float32_rem( float32, float32 );
+float32 float32_sqrt( float32 );
+int float32_eq( float32, float32 );
+int float32_le( float32, float32 );
+int float32_lt( float32, float32 );
+int float32_eq_signaling( float32, float32 );
+int float32_le_quiet( float32, float32 );
+int float32_lt_quiet( float32, float32 );
+int float32_is_signaling_nan( float32 );
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int float64_to_int32( float64 );
+int float64_to_int32_round_to_zero( float64 );
+long float64_to_int64( float64 );
+long float64_to_int64_round_to_zero( float64 );
+float32 float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 float64_to_float128( float64 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision operations.
+*----------------------------------------------------------------------------*/
+float64 float64_round_to_int( float64 );
+float64 float64_add( float64, float64 );
+float64 float64_sub( float64, float64 );
+float64 float64_mul( float64, float64 );
+float64 float64_div( float64, float64 );
+float64 float64_rem( float64, float64 );
+float64 float64_sqrt( float64 );
+int float64_eq( float64, float64 );
+int float64_le( float64, float64 );
+int float64_lt( float64, float64 );
+int float64_eq_signaling( float64, float64 );
+int float64_le_quiet( float64, float64 );
+int float64_lt_quiet( float64, float64 );
+int float64_is_signaling_nan( float64 );
+
+#ifdef FLOATX80
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int floatx80_to_int32( floatx80 );
+int floatx80_to_int32_round_to_zero( floatx80 );
+long floatx80_to_int64( floatx80 );
+long floatx80_to_int64_round_to_zero( floatx80 );
+float32 floatx80_to_float32( floatx80 );
+float64 floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 floatx80_to_float128( floatx80 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision rounding precision. Valid
+| values are 32, 64, and 80.
+*----------------------------------------------------------------------------*/
+extern int floatx80_rounding_precision;
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision operations.
+*----------------------------------------------------------------------------*/
+floatx80 floatx80_round_to_int( floatx80 );
+floatx80 floatx80_add( floatx80, floatx80 );
+floatx80 floatx80_sub( floatx80, floatx80 );
+floatx80 floatx80_mul( floatx80, floatx80 );
+floatx80 floatx80_div( floatx80, floatx80 );
+floatx80 floatx80_rem( floatx80, floatx80 );
+floatx80 floatx80_sqrt( floatx80 );
+int floatx80_eq( floatx80, floatx80 );
+int floatx80_le( floatx80, floatx80 );
+int floatx80_lt( floatx80, floatx80 );
+int floatx80_eq_signaling( floatx80, floatx80 );
+int floatx80_le_quiet( floatx80, floatx80 );
+int floatx80_lt_quiet( floatx80, floatx80 );
+int floatx80_is_signaling_nan( floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE quadruple-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int float128_to_int32( float128 );
+int float128_to_int32_round_to_zero( float128 );
+long float128_to_int64( float128 );
+long float128_to_int64_round_to_zero( float128 );
+float32 float128_to_float32( float128 );
+float64 float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 float128_to_floatx80( float128 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE quadruple-precision operations.
+*----------------------------------------------------------------------------*/
+float128 float128_round_to_int( float128 );
+float128 float128_add( float128, float128 );
+float128 float128_sub( float128, float128 );
+float128 float128_mul( float128, float128 );
+float128 float128_div( float128, float128 );
+float128 float128_rem( float128, float128 );
+float128 float128_sqrt( float128 );
+int float128_eq( float128, float128 );
+int float128_le( float128, float128 );
+int float128_lt( float128, float128 );
+int float128_eq_signaling( float128, float128 );
+int float128_le_quiet( float128, float128 );
+int float128_lt_quiet( float128, float128 );
+int float128_is_signaling_nan( float128 );
+
+#endif
+
+#endif
diff --git a/tools/test/testfloat/sparc64/sparc64.h b/tools/test/testfloat/sparc64/sparc64.h
new file mode 100644
index 0000000..959a78c
--- /dev/null
+++ b/tools/test/testfloat/sparc64/sparc64.h
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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$
+ */
+
+/*----------------------------------------------------------------------------
+| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+*----------------------------------------------------------------------------*/
+#define BIGENDIAN
+
+/*----------------------------------------------------------------------------
+| The macro `BITS64' can be defined to indicate that 64-bit integer types are
+| supported by the compiler.
+*----------------------------------------------------------------------------*/
+#define BITS64
+
+/*----------------------------------------------------------------------------
+| Each of the following `typedef's defines the most convenient type that holds
+| integers of at least as many bits as specified. For example, `uint8' should
+| be the most convenient type that can hold unsigned integers of as many as
+| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
+| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+| to the same as `int'.
+*----------------------------------------------------------------------------*/
+typedef int flag;
+typedef int uint8;
+typedef int int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long int uint64;
+typedef signed long int int64;
+#endif
+
+/*----------------------------------------------------------------------------
+| Each of the following `typedef's defines a type that holds integers
+| of _exactly_ the number of bits specified. For instance, for most
+| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+| `unsigned short int' and `signed short int' (or `short int'), respectively.
+*----------------------------------------------------------------------------*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long int bits64;
+typedef signed long int sbits64;
+#endif
+
+#ifdef BITS64
+/*----------------------------------------------------------------------------
+| The `LIT64' macro takes as its argument a textual integer literal and
+| if necessary ``marks'' the literal as having a 64-bit integer type.
+| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+| appended with the letters `LL' standing for `long long', which is `gcc's
+| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
+| defined as the identity macro: `#define LIT64( a ) a'.
+*----------------------------------------------------------------------------*/
+#define LIT64( a ) a##L
+#endif
+
+/*----------------------------------------------------------------------------
+| The macro `INLINE' can be used before functions that should be inlined. If
+| a compiler does not support explicit inlining, this macro should be defined
+| to be `static'.
+*----------------------------------------------------------------------------*/
+#define INLINE extern inline
diff --git a/tools/test/testfloat/sparc64/systflags.c b/tools/test/testfloat/sparc64/systflags.c
new file mode 100644
index 0000000..9187fac
--- /dev/null
+++ b/tools/test/testfloat/sparc64/systflags.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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.
+ */
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#pragma STDC FENV_ACCESS ON
+#include <fenv.h>
+#include <ieeefp.h>
+#include "milieu.h"
+#include "systflags.h"
+
+/*
+-------------------------------------------------------------------------------
+Clears the system's IEC/IEEE floating-point exception flags. Returns the
+previous value of the flags.
+-------------------------------------------------------------------------------
+*/
+int8 syst_float_flags_clear( void )
+{
+ fexcept_t flags;
+
+ fegetexceptflag(&flags, FE_ALL_EXCEPT);
+ feclearexcept(FE_ALL_EXCEPT);
+ return (flags >> 5);
+}
+
diff --git a/tools/test/testfloat/sparc64/systfloat.S b/tools/test/testfloat/sparc64/systfloat.S
new file mode 100644
index 0000000..09e97d1
--- /dev/null
+++ b/tools/test/testfloat/sparc64/systfloat.S
@@ -0,0 +1,1120 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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.
+ */
+
+/*
+===============================================================================
+
+This GNU assembler source file is part of TestFloat, Release 2a, a package
+of programs for testing the correctness of floating-point arithmetic
+complying to the IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+ .text
+
+/*
+ .macro i2f32 src=%i0,dst=%f0
+ st \src,[%sp+2231]
+ ld [%sp+2231],\dst
+ .endm
+
+ .macro i2f64 src=%i0,dst=%f0
+ stx \src,[%sp+2231]
+ ldd [%sp+2231],\dst
+ .endm
+
+ .macro f2i32 src=%f0,dst=%i0
+ st \src,[%sp+2231]
+ ld [%sp+2231],\dst
+ .endm
+
+ .macro f2i64 src=%f0,dst=%i0
+ std \src,[%sp+2231]
+ ldx [%sp+2231],\dst
+ .endm
+*/
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_int32_to_float32
+syst_int32_to_float32:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fitos %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_int32_to_float64
+syst_int32_to_float64:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fitod %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_int32_to_float128
+syst_int32_to_float128:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fitoq %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_int64_to_float32
+syst_int64_to_float32:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fxtos %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_int64_to_float64
+syst_int64_to_float64:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fxtod %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_int64_to_float128
+syst_int64_to_float128:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fxtoq %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_to_int32_round_to_zero
+syst_float32_to_int32_round_to_zero:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fstoi %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_to_int64_round_to_zero
+syst_float32_to_int64_round_to_zero:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fstox %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_to_float64
+syst_float32_to_float64:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fstod %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_to_float128
+syst_float32_to_float128:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fstoq %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_add
+syst_float32_add:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fadds %f0,%f1,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_sub
+syst_float32_sub:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fsubs %f0,%f1,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_mul
+syst_float32_mul:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fmuls %f0,%f1,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_div
+syst_float32_div:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fdivs %f0,%f1,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_sqrt
+syst_float32_sqrt:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ fsqrts %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_eq
+syst_float32_eq:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fcmps %fcc0,%f0,%f1
+ mov 0,%i0
+ move %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_le
+syst_float32_le:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fcmpes %fcc0,%f0,%f1
+ mov 0,%i0
+ movle %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_lt
+syst_float32_lt:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fcmpes %fcc0,%f0,%f1
+ mov 0,%i0
+ movl %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_eq_signaling
+syst_float32_eq_signaling:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fcmpes %fcc0,%f0,%f1
+ mov 0,%i0
+ move %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_le_quiet
+syst_float32_le_quiet:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fcmps %fcc0,%f0,%f1
+ mov 0,%i0
+ movle %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float32_lt_quiet
+syst_float32_lt_quiet:
+ save %sp,-192,%sp
+
+ st %i0,[%sp+2231]
+ ld [%sp+2231],%f0
+ st %i1,[%sp+2231]
+ ld [%sp+2231],%f1
+ fcmps %fcc0,%f0,%f1
+ mov 0,%i0
+ movl %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_to_int32_round_to_zero
+syst_float64_to_int32_round_to_zero:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fdtoi %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_to_int64_round_to_zero
+syst_float64_to_int64_round_to_zero:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fdtox %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_to_float32
+syst_float64_to_float32:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fdtos %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_to_float128
+syst_float64_to_float128:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fdtoq %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_add
+syst_float64_add:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ faddd %f0,%f2,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_sub
+syst_float64_sub:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fsubd %f0,%f2,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_mul
+syst_float64_mul:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fmuld %f0,%f2,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_div
+syst_float64_div:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fdivd %f0,%f2,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_sqrt
+syst_float64_sqrt:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ fsqrtd %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_eq
+syst_float64_eq:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fcmpd %fcc0,%f0,%f2
+ mov 0,%i0
+ move %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_le
+syst_float64_le:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fcmped %fcc0,%f0,%f2
+ mov 0,%i0
+ movle %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_lt
+syst_float64_lt:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fcmped %fcc0,%f0,%f2
+ mov 0,%i0
+ movl %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_eq_signaling
+syst_float64_eq_signaling:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fcmped %fcc0,%f0,%f2
+ mov 0,%i0
+ move %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_le_quiet
+syst_float64_le_quiet:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fcmpd %fcc0,%f0,%f2
+ mov 0,%i0
+ movle %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float64_lt_quiet
+syst_float64_lt_quiet:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fcmpd %fcc0,%f0,%f2
+ mov 0,%i0
+ movl %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_to_int32_round_to_zero
+syst_float128_to_int32_round_to_zero:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fqtoi %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_to_int64_round_to_zero
+syst_float128_to_int64_round_to_zero:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fqtox %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_to_float32
+syst_float128_to_float32:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fqtos %f0,%f0
+ st %f0,[%sp+2231]
+ ld [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_to_float64
+syst_float128_to_float64:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fqtod %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_add
+syst_float128_add:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ faddq %f0,%f4,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_sub
+syst_float128_sub:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fsubq %f0,%f4,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_mul
+syst_float128_mul:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fmulq %f0,%f4,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_div
+syst_float128_div:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fdivq %f0,%f4,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_sqrt
+syst_float128_sqrt:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ fsqrtq %f0,%f0
+ std %f0,[%sp+2231]
+ ldx [%sp+2231],%i0
+ std %f2,[%sp+2231]
+ ldx [%sp+2231],%i1
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_eq
+syst_float128_eq:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fcmpq %fcc0,%f0,%f4
+ mov 0,%i0
+ move %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_le
+syst_float128_le:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fcmpeq %fcc0,%f0,%f4
+ mov 0,%i0
+ movle %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_lt
+syst_float128_lt:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fcmpeq %fcc0,%f0,%f4
+ mov 0,%i0
+ movl %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_eq_signaling
+syst_float128_eq_signaling:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fcmpeq %fcc0,%f0,%f4
+ mov 0,%i0
+ move %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_le_quiet
+syst_float128_le_quiet:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fcmpq %fcc0,%f0,%f4
+ mov 0,%i0
+ movle %fcc0,1,%i0
+
+ ret
+ restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+ .align 4
+ .global syst_float128_lt_quiet
+syst_float128_lt_quiet:
+ save %sp,-192,%sp
+
+ stx %i0,[%sp+2231]
+ ldd [%sp+2231],%f0
+ stx %i1,[%sp+2231]
+ ldd [%sp+2231],%f2
+ stx %i2,[%sp+2231]
+ ldd [%sp+2231],%f4
+ stx %i3,[%sp+2231]
+ ldd [%sp+2231],%f6
+ fcmpq %fcc0,%f0,%f4
+ mov 0,%i0
+ movl %fcc0,1,%i0
+
+ ret
+ restore
diff --git a/tools/test/testfloat/sparc64/systfloat.h b/tools/test/testfloat/sparc64/systfloat.h
new file mode 100644
index 0000000..c1db1eb
--- /dev/null
+++ b/tools/test/testfloat/sparc64/systfloat.h
@@ -0,0 +1,216 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/* $FreeBSD$ */
+
+#include "softfloat.h"
+#include "milieu.h"
+
+/*
+-------------------------------------------------------------------------------
+The following macros are defined to indicate that the corresponding
+functions exist.
+-------------------------------------------------------------------------------
+*/
+#define SYST_INT32_TO_FLOAT32
+#define SYST_INT32_TO_FLOAT64
+#define SYST_INT32_TO_FLOAT128
+#define SYST_INT64_TO_FLOAT32
+#define SYST_INT64_TO_FLOAT64
+#define SYST_INT64_TO_FLOAT128
+#define SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+#define SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
+#define SYST_FLOAT32_TO_FLOAT64
+#define SYST_FLOAT32_TO_FLOAT128
+#define SYST_FLOAT32_ADD
+#define SYST_FLOAT32_SUB
+#define SYST_FLOAT32_MUL
+#define SYST_FLOAT32_DIV
+#define SYST_FLOAT32_SQRT
+#define SYST_FLOAT32_EQ
+#define SYST_FLOAT32_LE
+#define SYST_FLOAT32_LT
+#define SYST_FLOAT32_EQ_SIGNALING
+#define SYST_FLOAT32_LE_QUIET
+#define SYST_FLOAT32_LT_QUIET
+#define SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+#define SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
+#define SYST_FLOAT64_TO_FLOAT32
+#define SYST_FLOAT64_TO_FLOAT128
+#define SYST_FLOAT64_ADD
+#define SYST_FLOAT64_SUB
+#define SYST_FLOAT64_MUL
+#define SYST_FLOAT64_DIV
+#define SYST_FLOAT64_SQRT
+#define SYST_FLOAT64_EQ
+#define SYST_FLOAT64_LE
+#define SYST_FLOAT64_LT
+#define SYST_FLOAT64_EQ_SIGNALING
+#define SYST_FLOAT64_LE_QUIET
+#define SYST_FLOAT64_LT_QUIET
+#define SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+#define SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
+#define SYST_FLOAT128_TO_FLOAT32
+#define SYST_FLOAT128_TO_FLOAT64
+#define SYST_FLOAT128_ADD
+#define SYST_FLOAT128_SUB
+#define SYST_FLOAT128_MUL
+#define SYST_FLOAT128_DIV
+#define SYST_FLOAT128_SQRT
+#define SYST_FLOAT128_EQ
+#define SYST_FLOAT128_LE
+#define SYST_FLOAT128_LT
+#define SYST_FLOAT128_EQ_SIGNALING
+#define SYST_FLOAT128_LE_QUIET
+#define SYST_FLOAT128_LT_QUIET
+
+/*
+-------------------------------------------------------------------------------
+System function declarations. (Some of these functions may not exist.)
+-------------------------------------------------------------------------------
+*/
+float32 syst_int32_to_float32( int32 );
+float64 syst_int32_to_float64( int32 );
+#ifdef FLOATX80
+floatx80 syst_int32_to_floatx80( int32 );
+#endif
+#ifdef FLOAT128
+float128 syst_int32_to_float128( int32 );
+#endif
+#ifdef BITS64
+float32 syst_int64_to_float32( int64 );
+float64 syst_int64_to_float64( int64 );
+#ifdef FLOATX80
+floatx80 syst_int64_to_floatx80( int64 );
+#endif
+#ifdef FLOAT128
+float128 syst_int64_to_float128( int64 );
+#endif
+#endif
+int32 syst_float32_to_int32( float32 );
+int32 syst_float32_to_int32_round_to_zero( float32 );
+#ifdef BITS64
+int64 syst_float32_to_int64( float32 );
+int64 syst_float32_to_int64_round_to_zero( float32 );
+#endif
+float64 syst_float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 syst_float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 syst_float32_to_float128( float32 );
+#endif
+float32 syst_float32_round_to_int( float32 );
+float32 syst_float32_add( float32, float32 );
+float32 syst_float32_sub( float32, float32 );
+float32 syst_float32_mul( float32, float32 );
+float32 syst_float32_div( float32, float32 );
+float32 syst_float32_rem( float32, float32 );
+float32 syst_float32_sqrt( float32 );
+flag syst_float32_eq( float32, float32 );
+flag syst_float32_le( float32, float32 );
+flag syst_float32_lt( float32, float32 );
+flag syst_float32_eq_signaling( float32, float32 );
+flag syst_float32_le_quiet( float32, float32 );
+flag syst_float32_lt_quiet( float32, float32 );
+int32 syst_float64_to_int32( float64 );
+int32 syst_float64_to_int32_round_to_zero( float64 );
+#ifdef BITS64
+int64 syst_float64_to_int64( float64 );
+int64 syst_float64_to_int64_round_to_zero( float64 );
+#endif
+float32 syst_float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 syst_float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 syst_float64_to_float128( float64 );
+#endif
+float64 syst_float64_round_to_int( float64 );
+float64 syst_float64_add( float64, float64 );
+float64 syst_float64_sub( float64, float64 );
+float64 syst_float64_mul( float64, float64 );
+float64 syst_float64_div( float64, float64 );
+float64 syst_float64_rem( float64, float64 );
+float64 syst_float64_sqrt( float64 );
+flag syst_float64_eq( float64, float64 );
+flag syst_float64_le( float64, float64 );
+flag syst_float64_lt( float64, float64 );
+flag syst_float64_eq_signaling( float64, float64 );
+flag syst_float64_le_quiet( float64, float64 );
+flag syst_float64_lt_quiet( float64, float64 );
+#ifdef FLOATX80
+int32 syst_floatx80_to_int32( floatx80 );
+int32 syst_floatx80_to_int32_round_to_zero( floatx80 );
+#ifdef BITS64
+int64 syst_floatx80_to_int64( floatx80 );
+int64 syst_floatx80_to_int64_round_to_zero( floatx80 );
+#endif
+float32 syst_floatx80_to_float32( floatx80 );
+float64 syst_floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 syst_floatx80_to_float128( floatx80 );
+#endif
+floatx80 syst_floatx80_round_to_int( floatx80 );
+floatx80 syst_floatx80_add( floatx80, floatx80 );
+floatx80 syst_floatx80_sub( floatx80, floatx80 );
+floatx80 syst_floatx80_mul( floatx80, floatx80 );
+floatx80 syst_floatx80_div( floatx80, floatx80 );
+floatx80 syst_floatx80_rem( floatx80, floatx80 );
+floatx80 syst_floatx80_sqrt( floatx80 );
+flag syst_floatx80_eq( floatx80, floatx80 );
+flag syst_floatx80_le( floatx80, floatx80 );
+flag syst_floatx80_lt( floatx80, floatx80 );
+flag syst_floatx80_eq_signaling( floatx80, floatx80 );
+flag syst_floatx80_le_quiet( floatx80, floatx80 );
+flag syst_floatx80_lt_quiet( floatx80, floatx80 );
+#endif
+#ifdef FLOAT128
+int32 syst_float128_to_int32( float128 );
+int32 syst_float128_to_int32_round_to_zero( float128 );
+#ifdef BITS64
+int64 syst_float128_to_int64( float128 );
+int64 syst_float128_to_int64_round_to_zero( float128 );
+#endif
+float32 syst_float128_to_float32( float128 );
+float64 syst_float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 syst_float128_to_floatx80( float128 );
+#endif
+float128 syst_float128_round_to_int( float128 );
+float128 syst_float128_add( float128, float128 );
+float128 syst_float128_sub( float128, float128 );
+float128 syst_float128_mul( float128, float128 );
+float128 syst_float128_div( float128, float128 );
+float128 syst_float128_rem( float128, float128 );
+float128 syst_float128_sqrt( float128 );
+flag syst_float128_eq( float128, float128 );
+flag syst_float128_le( float128, float128 );
+flag syst_float128_lt( float128, float128 );
+flag syst_float128_eq_signaling( float128, float128 );
+flag syst_float128_le_quiet( float128, float128 );
+flag syst_float128_lt_quiet( float128, float128 );
+#endif
+
diff --git a/tools/test/testfloat/sparc64/systmodes.c b/tools/test/testfloat/sparc64/systmodes.c
new file mode 100644
index 0000000..2677059
--- /dev/null
+++ b/tools/test/testfloat/sparc64/systmodes.c
@@ -0,0 +1,54 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ieeefp.h>
+#include "milieu.h"
+#include "systmodes.h"
+
+/*
+-------------------------------------------------------------------------------
+Sets the system's IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_mode( int8 roundingMode )
+{
+
+ (void) fpsetround( roundingMode );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Does nothing.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_precision( int8 precision )
+{
+
+}
+
diff --git a/tools/test/testfloat/sparc64/un-namespace.h b/tools/test/testfloat/sparc64/un-namespace.h
new file mode 100644
index 0000000..5e7d1bc
--- /dev/null
+++ b/tools/test/testfloat/sparc64/un-namespace.h
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.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 ``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$
+ */
+/*
+ * This file has no content and is solely to satisfy a #include in
+ * the FP emulator code.
+ */
diff --git a/tools/test/testfloat/systemBugs.txt b/tools/test/testfloat/systemBugs.txt
new file mode 100644
index 0000000..a0d171a
--- /dev/null
+++ b/tools/test/testfloat/systemBugs.txt
@@ -0,0 +1,323 @@
+
+Known Floating-point Bugs Detected by TestFloat
+
+John R. Hauser
+1997 December 15
+
+
+-------------------------------------------------------------------------------
+Introduction
+
+Several popular systems have bugs that TestFloat is very likely to run
+across. The ones I know of are documented here. First off, TestFloat finds
+no errors in the following processors/machines:
+
+ AMD 486 DX4's
+ Sun UltraSPARC 1's and 2's
+
+On the other hand, bugs are found in these processors/machines:
+
+ Older Intel Pentiums (with the divide bug)
+ Intel Pentium Pros
+ Sun SPARCstation 1's and IPX's
+ Sun SPARCstation 10's
+ HP Precision Architecture processors, with HP-UX prior to version 10.10
+
+For some reason, most of the bugs found involve conversions from floating-
+point to integer formats.
+
+The bugs are shown as actual TestFloat error lines, along with a brief
+explanation. The error lines given are not necesarily exhaustive and were
+not necessarily output in the order shown.
+
+This document does not pretend to be an authoritative bug listing for all
+commercial processors. The vast majority of processors are absent from this
+list because I have never run TestFloat on such machines and I thus have no
+knowledge of what bugs TestFloat might find in them.
+
+The latest version of this file can be found at the Web page `http://
+http.cs.berkeley.edu/~jhauser/arithmetic/testfloat.html'.
+
+
+-------------------------------------------------------------------------------
+Older Intel Pentiums (with the divide bug)
+
+The following conversion problems are found on Pentiums that also suffer
+from the infamous floating-point divide bug. These bugs have been fixed on
+newer Pentiums. (TestFloat does not find the divide bug.)
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+floatx80_to_int32
+
+-- A few small fractions are treated as though they were zero.
+
+ Errors found in floatx80_to_int32, rounding nearest_even:
+ 3FFB.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ 3FFC.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ 3FFC.C000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFB.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFC.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ Errors found in floatx80_to_int32, rounding to_zero:
+ 3FFB.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ 3FFC.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ 3FFC.C000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFB.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFC.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFC.C000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ Errors found in floatx80_to_int32, rounding down:
+ 3FFB.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ 3FFC.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ 3FFC.C000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFB.8000000000000000 soft: FFFFFFFF ....x syst: 00000000 .....
+ BFFC.8000000000000000 soft: FFFFFFFF ....x syst: 00000000 .....
+ BFFC.C000000000000000 soft: FFFFFFFF ....x syst: 00000000 .....
+ Errors found in floatx80_to_int32, rounding up:
+ 3FFB.8000000000000000 soft: 00000001 ....x syst: 00000000 .....
+ 3FFC.8000000000000000 soft: 00000001 ....x syst: 00000000 .....
+ 3FFC.C000000000000000 soft: 00000001 ....x syst: 00000000 .....
+ BFFB.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+ BFFC.8000000000000000 soft: 00000000 ....x syst: 00000000 .....
+
+ 3FFB.8000000000000000 is the fraction 1/16; 3FFC.8000000000000000 is 1/8;
+ and 3FFC.C000000000000000 is 3/16. Both positive and negative inputs are
+ affected.
+
+-- Some (all?) positive floating-point values between 2^32 - 1/2
+ (401E.FFFFFFFF00000000) and 2^32 (401F.0000000000000000) are rounded to
+ zero when the rounding mode is nearest/even or up.
+
+ Errors found in floatx80_to_int32, rounding nearest_even:
+ 401E.FFFFFFFF80000000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFC00001FE soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFF8000000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFEC00000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFF002000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFC00000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFE00000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFD7FFE soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFFFFFE soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFFFFFF soft: 7FFFFFFF v.... syst: 00000000 ....x
+ Errors found in floatx80_to_int32, rounding up:
+ 401E.FFFFFFFF00800000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFF80000000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFEFFFC000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFC000000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFE7FFFFF soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFF00000 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFE0800 soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFF7FFB soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFFFFFE soft: 7FFFFFFF v.... syst: 00000000 ....x
+ 401E.FFFFFFFFFFFFFFFF soft: 7FFFFFFF v.... syst: 00000000 ....x
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Intel Pentium Pros
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+floatx80_to_int32
+
+-- The inexact flag is sometimes raised instead of the invalid flag for
+ floating-point inputs under -(2^32) (C01F.0000000000000000). This bug is
+ sporadic. It appears to be deterministic but dependent on the sequence
+ of operations executed.
+
+ Errors found in floatx80_to_int32, rounding nearest_even:
+ C01F.C000000000000002 soft: 80000000 v.... syst: 80000000 ....x
+ C021.F00000000000003F soft: 80000000 v.... syst: 80000000 ....x
+ Errors found in floatx80_to_int32, rounding to_zero:
+ C021.F00000000000003F soft: 80000000 v.... syst: 80000000 ....x
+ Errors found in floatx80_to_int32, rounding up:
+ C01F.C000000000000007 soft: 80000000 v.... syst: 80000000 ....x
+ C01F.C000000000001000 soft: 80000000 v.... syst: 80000000 ....x
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Sun SPARCstation 1's and IPX's
+
+Some older SPARCstations appear confused about whether underflow tininess is
+detected before or after rounding. For conversions from double precision
+to single precision, tininess is detected after rounding, while for all
+quadruple-precision operations it is detected before rounding. Single- and
+double-precision multipies go both ways:
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float32_mul, float64_mul
+
+-- For multiplies, underflow tininess is detected _before_ rounding if one
+ of the inputs is subnormal, and _after_ rounding otherwise. If tininess
+ is assumed to be detected before rounding, the following errors are
+ generated:
+
+ Errors found in float32_mul, rounding nearest_even:
+ 001.000001 07E.7FFFFE soft: 001.000000 ...ux syst: 001.000000 ....x
+ 001.000001 87E.7FFFFE soft: 801.000000 ...ux syst: 801.000000 ....x
+ 001.000002 07E.7FFFFC soft: 001.000000 ...ux syst: 001.000000 ....x
+ 001.000002 87E.7FFFFC soft: 801.000000 ...ux syst: 801.000000 ....x
+ 001.000004 07E.7FFFF8 soft: 001.000000 ...ux syst: 001.000000 ....x
+ Errors found in float32_mul, rounding down:
+ 001.000001 87E.7FFFFE soft: 801.000000 ...ux syst: 801.000000 ....x
+ 001.000002 87E.7FFFFC soft: 801.000000 ...ux syst: 801.000000 ....x
+ 001.000004 87E.7FFFF8 soft: 801.000000 ...ux syst: 801.000000 ....x
+ 001.000008 87E.7FFFF0 soft: 801.000000 ...ux syst: 801.000000 ....x
+ 001.000010 87E.7FFFE0 soft: 801.000000 ...ux syst: 801.000000 ....x
+ Errors found in float32_mul, rounding up:
+ 001.000001 07E.7FFFFE soft: 001.000000 ...ux syst: 001.000000 ....x
+ 001.000002 07E.7FFFFC soft: 001.000000 ...ux syst: 001.000000 ....x
+ 001.000004 07E.7FFFF8 soft: 001.000000 ...ux syst: 001.000000 ....x
+ 001.000008 07E.7FFFF0 soft: 001.000000 ...ux syst: 001.000000 ....x
+ 001.000010 07E.7FFFE0 soft: 001.000000 ...ux syst: 001.000000 ....x
+ Errors found in float64_mul, rounding nearest_even:
+ 001.0000000000001 3FE.FFFFFFFFFFFFE
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ 001.0000000000001 BFE.FFFFFFFFFFFFE
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ 001.0000000000002 3FE.FFFFFFFFFFFFC
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ 001.0000000000002 BFE.FFFFFFFFFFFFC
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ 001.0000000000004 3FE.FFFFFFFFFFFF8
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ Errors found in float64_mul, rounding down:
+ 001.0000000000001 BFE.FFFFFFFFFFFFE
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ 001.0000000000002 BFE.FFFFFFFFFFFFC
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ 001.0000000000004 BFE.FFFFFFFFFFFF8
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ 001.0000000000008 BFE.FFFFFFFFFFFF0
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ 001.0000000000010 BFE.FFFFFFFFFFFE0
+ soft: 801.0000000000000 ...ux syst: 801.0000000000000 ....x
+ Errors found in float64_mul, rounding up:
+ 001.0000000000001 3FE.FFFFFFFFFFFFE
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ 001.0000000000002 3FE.FFFFFFFFFFFFC
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ 001.0000000000004 3FE.FFFFFFFFFFFF8
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ 001.0000000000008 3FE.FFFFFFFFFFFF0
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+ 001.0000000000010 3FE.FFFFFFFFFFFE0
+ soft: 001.0000000000000 ...ux syst: 001.0000000000000 ....x
+
+ If we assume tininess should be detected after rounding, we get the
+ following errors:
+
+ Errors found in float32_mul, rounding nearest_even:
+ 000.7FFC00 07F.000400 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 000.7FFC00 87F.000400 soft: 801.000000 ....x syst: 801.000000 ...ux
+ 000.7FFE00 07F.000200 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 000.7FFE00 87F.000200 soft: 801.000000 ....x syst: 801.000000 ...ux
+ 000.7FFF00 07F.000100 soft: 001.000000 ....x syst: 001.000000 ...ux
+ Errors found in float32_mul, rounding down:
+ 000.7FFC00 87F.000400 soft: 801.000000 ....x syst: 801.000000 ...ux
+ 000.7FFE00 87F.000200 soft: 801.000000 ....x syst: 801.000000 ...ux
+ 000.7FFF00 87F.000100 soft: 801.000000 ....x syst: 801.000000 ...ux
+ 000.7FFF80 87F.000080 soft: 801.000000 ....x syst: 801.000000 ...ux
+ 000.7FFFC0 87F.000040 soft: 801.000000 ....x syst: 801.000000 ...ux
+ Errors found in float32_mul, rounding up:
+ 000.7FFC00 07F.000400 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 000.7FFE00 07F.000200 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 000.7FFF00 07F.000100 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 000.7FFF80 07F.000080 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 000.7FFFC0 07F.000040 soft: 001.000000 ....x syst: 001.000000 ...ux
+ Errors found in float64_mul, rounding nearest_even:
+ 000.FFFFFFE000000 3FF.0000002000000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ 000.FFFFFFE000000 BFF.0000002000000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ 000.FFFFFFF000000 3FF.0000001000000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ 000.FFFFFFF000000 BFF.0000001000000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ 000.FFFFFFF800000 3FF.0000000800000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ Errors found in float64_mul, rounding down:
+ 000.FFFFFFE000000 BFF.0000002000000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ 000.FFFFFFF000000 BFF.0000001000000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ 000.FFFFFFF800000 BFF.0000000800000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ 000.FFFFFFFC00000 BFF.0000000400000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ 000.FFFFFFFE00000 BFF.0000000200000
+ soft: 801.0000000000000 ....x syst: 801.0000000000000 ...ux
+ Errors found in float64_mul, rounding up:
+ 000.FFFFFFE000000 3FF.0000002000000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ 000.FFFFFFF000000 3FF.0000001000000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ 000.FFFFFFF800000 3FF.0000000800000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ 000.FFFFFFFC00000 3FF.0000000400000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+ 000.FFFFFFFE00000 3FF.0000000200000
+ soft: 001.0000000000000 ....x syst: 001.0000000000000 ...ux
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Sun SPARCstation 10's
+
+Like other SPARCstations, some SPARCstation 10's are inconsistent regarding
+underflow tininess, detecting it after rounding for single- and double-
+precision operations and before rounding for quadruple-precision operations.
+The following bug has also been observed.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float32_to_int32_round_to_zero, float64_to_int32_round_to_zero
+
+-- Single- and double-precision NaNs are converted to the integer zero.
+ (The invalid exception flag is raised correctly.)
+
+ Errors found in float32_to_int32_round_to_zero:
+ 8FF.5D36AC soft: 7FFFFFFF v.... syst: 00000000 v....
+ 0FF.7FFFC0 soft: 7FFFFFFF v.... syst: 00000000 v....
+ 8FF.7C0000 soft: 7FFFFFFF v.... syst: 00000000 v....
+ 0FF.2AB7ED soft: 7FFFFFFF v.... syst: 00000000 v....
+ 0FF.03FFFF soft: 7FFFFFFF v.... syst: 00000000 v....
+ Errors found in float64_to_int32_round_to_zero:
+ 7FF.45AD84DB2524A soft: 7FFFFFFF v.... syst: 00000000 v....
+ 7FF.CFEE063EE0512 soft: 7FFFFFFF v.... syst: 00000000 v....
+ 7FF.89FF03AB7DBA2 soft: 7FFFFFFF v.... syst: 00000000 v....
+ 7FF.FFFFFFFFFF800 soft: 7FFFFFFF v.... syst: 00000000 v....
+ FFF.68A6410E91BF6 soft: 7FFFFFFF v.... syst: 00000000 v....
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+HP Precision Architecture processors, with HP-UX prior to version 10.10
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float32_to_int32_round_to_zero, float64_to_int32_round_to_zero
+
+-- When the floating-point value is too large, the overflow and inexact
+ exception flags are raised instead of the invalid flag.
+
+ Errors found in float32_to_int32_round_to_zero:
+ 89E.000007 soft: 80000000 v.... syst: 80000000 ..o.x
+ 0A2.000020 soft: 7FFFFFFF v.... syst: 7FFFFFFF ..o.x
+ 8FA.7C0000 soft: 80000000 v.... syst: 80000000 ..o.x
+ Errors found in float64_to_int32_round_to_zero:
+ 7FD.0448700002F1C soft: 7FFFFFFF v.... syst: 7FFFFFFF ..o.x
+ DAA.F000000000000 soft: 80000000 v.... syst: 80000000 ..o.x
+ 41E.063DA00005E65 soft: 7FFFFFFF v.... syst: 7FFFFFFF ..o.x
+ 47E.FFFF800000000 soft: 7FFFFFFF v.... syst: 7FFFFFFF ..o.x
+ 51F.0000000000004 soft: 7FFFFFFF v.... syst: 7FFFFFFF ..o.x
+ DDA.0000001FFFFFF soft: 80000000 v.... syst: 80000000 ..o.x
+ D70.00000000003FF soft: 80000000 v.... syst: 80000000 ..o.x
+ C7E.0000100000000 soft: 80000000 v.... syst: 80000000 ..o.x
+ 47E.000000000007F soft: 7FFFFFFF v.... syst: 7FFFFFFF ..o.x
+ D57.000000000FFFF soft: 80000000 v.... syst: 80000000 ..o.x
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
diff --git a/tools/test/testfloat/systflags.h b/tools/test/testfloat/systflags.h
new file mode 100644
index 0000000..23e6b23
--- /dev/null
+++ b/tools/test/testfloat/systflags.h
@@ -0,0 +1,33 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Target-specific function for clearing the system's IEC/IEEE floating-point
+exception flags. The previous value of the flags is returned.
+-------------------------------------------------------------------------------
+*/
+int8 syst_float_flags_clear( void );
+
diff --git a/tools/test/testfloat/systfloat.c b/tools/test/testfloat/systfloat.c
new file mode 100644
index 0000000..08548c4
--- /dev/null
+++ b/tools/test/testfloat/systfloat.c
@@ -0,0 +1,553 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <math.h>
+#include "milieu.h"
+#include "softfloat.h"
+#include "systfloat.h"
+
+float32 syst_int32_to_float32( int32 a )
+{
+ float32 z;
+
+ *( (float *) &z ) = a;
+ return z;
+
+}
+
+float64 syst_int32_to_float64( int32 a )
+{
+ float64 z;
+
+ *( (double *) &z ) = a;
+ return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_int32_to_floatx80( int32 a )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) = a;
+ return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_int32_to_float128( int32 a )
+{
+ float128 z;
+
+ *( (long double *) &z ) = a;
+ return z;
+
+}
+
+#endif
+
+#ifdef BITS64
+
+float32 syst_int64_to_float32( int64 a )
+{
+ float32 z;
+
+ *( (float *) &z ) = a;
+ return z;
+
+}
+
+float64 syst_int64_to_float64( int64 a )
+{
+ float64 z;
+
+ *( (double *) &z ) = a;
+ return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_int64_to_floatx80( int64 a )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) = a;
+ return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_int64_to_float128( int64 a )
+{
+ float128 z;
+
+ *( (long double *) &z ) = a;
+ return z;
+
+}
+
+#endif
+
+#endif
+
+int32 syst_float32_to_int32_round_to_zero( float32 a )
+{
+
+ return *( (float *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_float32_to_int64_round_to_zero( float32 a )
+{
+
+ return *( (float *) &a );
+
+}
+
+#endif
+
+float64 syst_float32_to_float64( float32 a )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (float *) &a );
+ return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_float32_to_floatx80( float32 a )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) = *( (float *) &a );
+ return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_float32_to_float128( float32 a )
+{
+ float128 z;
+
+ *( (long double *) &z ) = *( (float *) &a );
+ return z;
+
+}
+
+#endif
+
+float32 syst_float32_add( float32 a, float32 b )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (float *) &a ) + *( (float *) &b );
+ return z;
+
+}
+
+float32 syst_float32_sub( float32 a, float32 b )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (float *) &a ) - *( (float *) &b );
+ return z;
+
+}
+
+float32 syst_float32_mul( float32 a, float32 b )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (float *) &a ) * *( (float *) &b );
+ return z;
+
+}
+
+float32 syst_float32_div( float32 a, float32 b )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (float *) &a ) / *( (float *) &b );
+ return z;
+
+}
+
+flag syst_float32_eq( float32 a, float32 b )
+{
+
+ return ( *( (float *) &a ) == *( (float *) &b ) );
+
+}
+
+flag syst_float32_le( float32 a, float32 b )
+{
+
+ return ( *( (float *) &a ) <= *( (float *) &b ) );
+
+}
+
+flag syst_float32_lt( float32 a, float32 b )
+{
+
+ return ( *( (float *) &a ) < *( (float *) &b ) );
+
+}
+
+int32 syst_float64_to_int32_round_to_zero( float64 a )
+{
+
+ return *( (double *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_float64_to_int64_round_to_zero( float64 a )
+{
+
+ return *( (double *) &a );
+
+}
+
+#endif
+
+float32 syst_float64_to_float32( float64 a )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (double *) &a );
+ return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_float64_to_floatx80( float64 a )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) = *( (double *) &a );
+ return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_float64_to_float128( float64 a )
+{
+ float128 z;
+
+ *( (long double *) &z ) = *( (double *) &a );
+ return z;
+
+}
+
+#endif
+
+float64 syst_float64_add( float64 a, float64 b )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (double *) &a ) + *( (double *) &b );
+ return z;
+
+}
+
+float64 syst_float64_sub( float64 a, float64 b )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (double *) &a ) - *( (double *) &b );
+ return z;
+
+}
+
+float64 syst_float64_mul( float64 a, float64 b )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (double *) &a ) * *( (double *) &b );
+ return z;
+
+}
+
+float64 syst_float64_div( float64 a, float64 b )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (double *) &a ) / *( (double *) &b );
+ return z;
+
+}
+
+float64 syst_float64_sqrt( float64 a )
+{
+ float64 z;
+
+ *( (double *) &z ) = sqrt( *( (double *) &a ) );
+ return z;
+
+}
+
+flag syst_float64_eq( float64 a, float64 b )
+{
+
+ return ( *( (double *) &a ) == *( (double *) &b ) );
+
+}
+
+flag syst_float64_le( float64 a, float64 b )
+{
+
+ return ( *( (double *) &a ) <= *( (double *) &b ) );
+
+}
+
+flag syst_float64_lt( float64 a, float64 b )
+{
+
+ return ( *( (double *) &a ) < *( (double *) &b ) );
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+int32 syst_floatx80_to_int32_round_to_zero( floatx80 a )
+{
+
+ return *( (long double *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_floatx80_to_int64_round_to_zero( floatx80 a )
+{
+
+ return *( (long double *) &a );
+
+}
+
+#endif
+
+float32 syst_floatx80_to_float32( floatx80 a )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (long double *) &a );
+ return z;
+
+}
+
+float64 syst_floatx80_to_float64( floatx80 a )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (long double *) &a );
+ return z;
+
+}
+
+floatx80 syst_floatx80_add( floatx80 a, floatx80 b )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) + *( (long double *) &b );
+ return z;
+
+}
+
+floatx80 syst_floatx80_sub( floatx80 a, floatx80 b )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) - *( (long double *) &b );
+ return z;
+
+}
+
+floatx80 syst_floatx80_mul( floatx80 a, floatx80 b )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) * *( (long double *) &b );
+ return z;
+
+}
+
+floatx80 syst_floatx80_div( floatx80 a, floatx80 b )
+{
+ floatx80 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) / *( (long double *) &b );
+ return z;
+
+}
+
+flag syst_floatx80_eq( floatx80 a, floatx80 b )
+{
+
+ return ( *( (long double *) &a ) == *( (long double *) &b ) );
+
+}
+
+flag syst_floatx80_le( floatx80 a, floatx80 b )
+{
+
+ return ( *( (long double *) &a ) <= *( (long double *) &b ) );
+
+}
+
+flag syst_floatx80_lt( floatx80 a, floatx80 b )
+{
+
+ return ( *( (long double *) &a ) < *( (long double *) &b ) );
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+int32 syst_float128_to_int32_round_to_zero( float128 a )
+{
+
+ return *( (long double *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_float128_to_int64_round_to_zero( float128 a )
+{
+
+ return *( (long double *) &a );
+
+}
+
+#endif
+
+float32 syst_float128_to_float32( float128 a )
+{
+ float32 z;
+
+ *( (float *) &z ) = *( (long double *) &a );
+ return z;
+
+}
+
+float64 syst_float128_to_float64( float128 a )
+{
+ float64 z;
+
+ *( (double *) &z ) = *( (long double *) &a );
+ return z;
+
+}
+
+float128 syst_float128_add( float128 a, float128 b )
+{
+ float128 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) + *( (long double *) &b );
+ return z;
+
+}
+
+float128 syst_float128_sub( float128 a, float128 b )
+{
+ float128 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) - *( (long double *) &b );
+ return z;
+
+}
+
+float128 syst_float128_mul( float128 a, float128 b )
+{
+ float128 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) * *( (long double *) &b );
+ return z;
+
+}
+
+float128 syst_float128_div( float128 a, float128 b )
+{
+ float128 z;
+
+ *( (long double *) &z ) =
+ *( (long double *) &a ) / *( (long double *) &b );
+ return z;
+
+}
+
+flag syst_float128_eq( float128 a, float128 b )
+{
+
+ return ( *( (long double *) &a ) == *( (long double *) &b ) );
+
+}
+
+flag syst_float128_le( float128 a, float128 b )
+{
+
+ return ( *( (long double *) &a ) <= *( (long double *) &b ) );
+
+}
+
+flag syst_float128_lt( float128 a, float128 b )
+{
+
+ return ( *( (long double *) &a ) < *( (long double *) &b ) );
+
+}
+
+#endif
+
diff --git a/tools/test/testfloat/systmodes.h b/tools/test/testfloat/systmodes.h
new file mode 100644
index 0000000..b2befa4
--- /dev/null
+++ b/tools/test/testfloat/systmodes.h
@@ -0,0 +1,42 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Target-specific function for setting the system's IEC/IEEE floating-point
+rounding mode. Other system modes are also initialized as necessary (for
+example, exception trapping may be disabled).
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_mode( int8 );
+
+/*
+-------------------------------------------------------------------------------
+Target-specific function for setting the IEC/IEEE rounding precision of
+subsequent extended double-precision operations performed by the system.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_precision( int8 );
+
diff --git a/tools/test/testfloat/testCases.c b/tools/test/testfloat/testCases.c
new file mode 100644
index 0000000..e2d8f42
--- /dev/null
+++ b/tools/test/testfloat/testCases.c
@@ -0,0 +1,3682 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "milieu.h"
+#include "fail.h"
+#include "random.h"
+#include "softfloat.h"
+#include "testCases.h"
+
+typedef struct {
+ int16 expNum, term1Num, term2Num;
+ flag done;
+} sequenceT;
+
+enum {
+ int32NumP1 = 124
+};
+
+static const uint32 int32P1[ int32NumP1 ] = {
+ 0x00000000,
+ 0x00000001,
+ 0x00000002,
+ 0x00000004,
+ 0x00000008,
+ 0x00000010,
+ 0x00000020,
+ 0x00000040,
+ 0x00000080,
+ 0x00000100,
+ 0x00000200,
+ 0x00000400,
+ 0x00000800,
+ 0x00001000,
+ 0x00002000,
+ 0x00004000,
+ 0x00008000,
+ 0x00010000,
+ 0x00020000,
+ 0x00040000,
+ 0x00080000,
+ 0x00100000,
+ 0x00200000,
+ 0x00400000,
+ 0x00800000,
+ 0x01000000,
+ 0x02000000,
+ 0x04000000,
+ 0x08000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000,
+ 0xC0000000,
+ 0xE0000000,
+ 0xF0000000,
+ 0xF8000000,
+ 0xFC000000,
+ 0xFE000000,
+ 0xFF000000,
+ 0xFF800000,
+ 0xFFC00000,
+ 0xFFE00000,
+ 0xFFF00000,
+ 0xFFF80000,
+ 0xFFFC0000,
+ 0xFFFE0000,
+ 0xFFFF0000,
+ 0xFFFF8000,
+ 0xFFFFC000,
+ 0xFFFFE000,
+ 0xFFFFF000,
+ 0xFFFFF800,
+ 0xFFFFFC00,
+ 0xFFFFFE00,
+ 0xFFFFFF00,
+ 0xFFFFFF80,
+ 0xFFFFFFC0,
+ 0xFFFFFFE0,
+ 0xFFFFFFF0,
+ 0xFFFFFFF8,
+ 0xFFFFFFFC,
+ 0xFFFFFFFE,
+ 0xFFFFFFFF,
+ 0xFFFFFFFD,
+ 0xFFFFFFFB,
+ 0xFFFFFFF7,
+ 0xFFFFFFEF,
+ 0xFFFFFFDF,
+ 0xFFFFFFBF,
+ 0xFFFFFF7F,
+ 0xFFFFFEFF,
+ 0xFFFFFDFF,
+ 0xFFFFFBFF,
+ 0xFFFFF7FF,
+ 0xFFFFEFFF,
+ 0xFFFFDFFF,
+ 0xFFFFBFFF,
+ 0xFFFF7FFF,
+ 0xFFFEFFFF,
+ 0xFFFDFFFF,
+ 0xFFFBFFFF,
+ 0xFFF7FFFF,
+ 0xFFEFFFFF,
+ 0xFFDFFFFF,
+ 0xFFBFFFFF,
+ 0xFF7FFFFF,
+ 0xFEFFFFFF,
+ 0xFDFFFFFF,
+ 0xFBFFFFFF,
+ 0xF7FFFFFF,
+ 0xEFFFFFFF,
+ 0xDFFFFFFF,
+ 0xBFFFFFFF,
+ 0x7FFFFFFF,
+ 0x3FFFFFFF,
+ 0x1FFFFFFF,
+ 0x0FFFFFFF,
+ 0x07FFFFFF,
+ 0x03FFFFFF,
+ 0x01FFFFFF,
+ 0x00FFFFFF,
+ 0x007FFFFF,
+ 0x003FFFFF,
+ 0x001FFFFF,
+ 0x000FFFFF,
+ 0x0007FFFF,
+ 0x0003FFFF,
+ 0x0001FFFF,
+ 0x0000FFFF,
+ 0x00007FFF,
+ 0x00003FFF,
+ 0x00001FFF,
+ 0x00000FFF,
+ 0x000007FF,
+ 0x000003FF,
+ 0x000001FF,
+ 0x000000FF,
+ 0x0000007F,
+ 0x0000003F,
+ 0x0000001F,
+ 0x0000000F,
+ 0x00000007,
+ 0x00000003
+};
+
+static int32 int32NextP1( sequenceT *sequencePtr )
+{
+ uint8 termNum;
+ int32 z;
+
+ termNum = sequencePtr->term1Num;
+ z = int32P1[ termNum ];
+ ++termNum;
+ if ( int32NumP1 <= termNum ) {
+ termNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->term1Num = termNum;
+ return (sbits32) z;
+
+}
+
+static const int32 int32NumP2 = ( int32NumP1 * int32NumP1 + int32NumP1 ) / 2;
+
+static int32 int32NextP2( sequenceT *sequencePtr )
+{
+ uint8 term1Num, term2Num;
+ int32 z;
+
+ term2Num = sequencePtr->term2Num;
+ term1Num = sequencePtr->term1Num;
+ z = int32P1[ term1Num ] + int32P1[ term2Num ];
+ ++term2Num;
+ if ( int32NumP1 <= term2Num ) {
+ ++term1Num;
+ if ( int32NumP1 <= term1Num ) {
+ term1Num = 0;
+ sequencePtr->done = TRUE;
+ }
+ term2Num = term1Num;
+ sequencePtr->term1Num = term1Num;
+ }
+ sequencePtr->term2Num = term2Num;
+ return (sbits32) z;
+
+}
+
+static int32 int32RandomP3( void )
+{
+
+ return
+ (sbits32) (
+ int32P1[ randomUint8() % int32NumP1 ]
+ + int32P1[ randomUint8() % int32NumP1 ]
+ + int32P1[ randomUint8() % int32NumP1 ]
+ );
+
+}
+
+enum {
+ int32NumPInfWeightMasks = 29
+};
+
+static const uint32 int32PInfWeightMasks[ int32NumPInfWeightMasks ] = {
+ 0xFFFFFFFF,
+ 0x7FFFFFFF,
+ 0x3FFFFFFF,
+ 0x1FFFFFFF,
+ 0x0FFFFFFF,
+ 0x07FFFFFF,
+ 0x03FFFFFF,
+ 0x01FFFFFF,
+ 0x00FFFFFF,
+ 0x007FFFFF,
+ 0x003FFFFF,
+ 0x001FFFFF,
+ 0x000FFFFF,
+ 0x0007FFFF,
+ 0x0003FFFF,
+ 0x0001FFFF,
+ 0x0000FFFF,
+ 0x00007FFF,
+ 0x00003FFF,
+ 0x00001FFF,
+ 0x00000FFF,
+ 0x000007FF,
+ 0x000003FF,
+ 0x000001FF,
+ 0x000000FF,
+ 0x0000007F,
+ 0x0000003F,
+ 0x0000001F,
+ 0x0000000F
+};
+
+static const uint32 int32PInfWeightOffsets[ int32NumPInfWeightMasks ] = {
+ 0x00000000,
+ 0xC0000000,
+ 0xE0000000,
+ 0xF0000000,
+ 0xF8000000,
+ 0xFC000000,
+ 0xFE000000,
+ 0xFF000000,
+ 0xFF800000,
+ 0xFFC00000,
+ 0xFFE00000,
+ 0xFFF00000,
+ 0xFFF80000,
+ 0xFFFC0000,
+ 0xFFFE0000,
+ 0xFFFF0000,
+ 0xFFFF8000,
+ 0xFFFFC000,
+ 0xFFFFE000,
+ 0xFFFFF000,
+ 0xFFFFF800,
+ 0xFFFFFC00,
+ 0xFFFFFE00,
+ 0xFFFFFF00,
+ 0xFFFFFF80,
+ 0xFFFFFFC0,
+ 0xFFFFFFE0,
+ 0xFFFFFFF0,
+ 0xFFFFFFF8
+};
+
+static int32 int32RandomPInf( void )
+{
+ int8 weightMaskNum;
+
+ weightMaskNum = randomUint8() % int32NumPInfWeightMasks;
+ return
+ (sbits32) (
+ ( randomUint32() & int32PInfWeightMasks[ weightMaskNum ] )
+ + int32PInfWeightOffsets[ weightMaskNum ]
+ );
+
+}
+
+#ifdef BITS64
+
+enum {
+ int64NumP1 = 252
+};
+
+static const uint64 int64P1[ int64NumP1 ] = {
+ LIT64( 0x0000000000000000 ),
+ LIT64( 0x0000000000000001 ),
+ LIT64( 0x0000000000000002 ),
+ LIT64( 0x0000000000000004 ),
+ LIT64( 0x0000000000000008 ),
+ LIT64( 0x0000000000000010 ),
+ LIT64( 0x0000000000000020 ),
+ LIT64( 0x0000000000000040 ),
+ LIT64( 0x0000000000000080 ),
+ LIT64( 0x0000000000000100 ),
+ LIT64( 0x0000000000000200 ),
+ LIT64( 0x0000000000000400 ),
+ LIT64( 0x0000000000000800 ),
+ LIT64( 0x0000000000001000 ),
+ LIT64( 0x0000000000002000 ),
+ LIT64( 0x0000000000004000 ),
+ LIT64( 0x0000000000008000 ),
+ LIT64( 0x0000000000010000 ),
+ LIT64( 0x0000000000020000 ),
+ LIT64( 0x0000000000040000 ),
+ LIT64( 0x0000000000080000 ),
+ LIT64( 0x0000000000100000 ),
+ LIT64( 0x0000000000200000 ),
+ LIT64( 0x0000000000400000 ),
+ LIT64( 0x0000000000800000 ),
+ LIT64( 0x0000000001000000 ),
+ LIT64( 0x0000000002000000 ),
+ LIT64( 0x0000000004000000 ),
+ LIT64( 0x0000000008000000 ),
+ LIT64( 0x0000000010000000 ),
+ LIT64( 0x0000000020000000 ),
+ LIT64( 0x0000000040000000 ),
+ LIT64( 0x0000000080000000 ),
+ LIT64( 0x0000000100000000 ),
+ LIT64( 0x0000000200000000 ),
+ LIT64( 0x0000000400000000 ),
+ LIT64( 0x0000000800000000 ),
+ LIT64( 0x0000001000000000 ),
+ LIT64( 0x0000002000000000 ),
+ LIT64( 0x0000004000000000 ),
+ LIT64( 0x0000008000000000 ),
+ LIT64( 0x0000010000000000 ),
+ LIT64( 0x0000020000000000 ),
+ LIT64( 0x0000040000000000 ),
+ LIT64( 0x0000080000000000 ),
+ LIT64( 0x0000100000000000 ),
+ LIT64( 0x0000200000000000 ),
+ LIT64( 0x0000400000000000 ),
+ LIT64( 0x0000800000000000 ),
+ LIT64( 0x0001000000000000 ),
+ LIT64( 0x0002000000000000 ),
+ LIT64( 0x0004000000000000 ),
+ LIT64( 0x0008000000000000 ),
+ LIT64( 0x0010000000000000 ),
+ LIT64( 0x0020000000000000 ),
+ LIT64( 0x0040000000000000 ),
+ LIT64( 0x0080000000000000 ),
+ LIT64( 0x0100000000000000 ),
+ LIT64( 0x0200000000000000 ),
+ LIT64( 0x0400000000000000 ),
+ LIT64( 0x0800000000000000 ),
+ LIT64( 0x1000000000000000 ),
+ LIT64( 0x2000000000000000 ),
+ LIT64( 0x4000000000000000 ),
+ LIT64( 0x8000000000000000 ),
+ LIT64( 0xC000000000000000 ),
+ LIT64( 0xE000000000000000 ),
+ LIT64( 0xF000000000000000 ),
+ LIT64( 0xF800000000000000 ),
+ LIT64( 0xFC00000000000000 ),
+ LIT64( 0xFE00000000000000 ),
+ LIT64( 0xFF00000000000000 ),
+ LIT64( 0xFF80000000000000 ),
+ LIT64( 0xFFC0000000000000 ),
+ LIT64( 0xFFE0000000000000 ),
+ LIT64( 0xFFF0000000000000 ),
+ LIT64( 0xFFF8000000000000 ),
+ LIT64( 0xFFFC000000000000 ),
+ LIT64( 0xFFFE000000000000 ),
+ LIT64( 0xFFFF000000000000 ),
+ LIT64( 0xFFFF800000000000 ),
+ LIT64( 0xFFFFC00000000000 ),
+ LIT64( 0xFFFFE00000000000 ),
+ LIT64( 0xFFFFF00000000000 ),
+ LIT64( 0xFFFFF80000000000 ),
+ LIT64( 0xFFFFFC0000000000 ),
+ LIT64( 0xFFFFFE0000000000 ),
+ LIT64( 0xFFFFFF0000000000 ),
+ LIT64( 0xFFFFFF8000000000 ),
+ LIT64( 0xFFFFFFC000000000 ),
+ LIT64( 0xFFFFFFE000000000 ),
+ LIT64( 0xFFFFFFF000000000 ),
+ LIT64( 0xFFFFFFF800000000 ),
+ LIT64( 0xFFFFFFFC00000000 ),
+ LIT64( 0xFFFFFFFE00000000 ),
+ LIT64( 0xFFFFFFFF00000000 ),
+ LIT64( 0xFFFFFFFF80000000 ),
+ LIT64( 0xFFFFFFFFC0000000 ),
+ LIT64( 0xFFFFFFFFE0000000 ),
+ LIT64( 0xFFFFFFFFF0000000 ),
+ LIT64( 0xFFFFFFFFF8000000 ),
+ LIT64( 0xFFFFFFFFFC000000 ),
+ LIT64( 0xFFFFFFFFFE000000 ),
+ LIT64( 0xFFFFFFFFFF000000 ),
+ LIT64( 0xFFFFFFFFFF800000 ),
+ LIT64( 0xFFFFFFFFFFC00000 ),
+ LIT64( 0xFFFFFFFFFFE00000 ),
+ LIT64( 0xFFFFFFFFFFF00000 ),
+ LIT64( 0xFFFFFFFFFFF80000 ),
+ LIT64( 0xFFFFFFFFFFFC0000 ),
+ LIT64( 0xFFFFFFFFFFFE0000 ),
+ LIT64( 0xFFFFFFFFFFFF0000 ),
+ LIT64( 0xFFFFFFFFFFFF8000 ),
+ LIT64( 0xFFFFFFFFFFFFC000 ),
+ LIT64( 0xFFFFFFFFFFFFE000 ),
+ LIT64( 0xFFFFFFFFFFFFF000 ),
+ LIT64( 0xFFFFFFFFFFFFF800 ),
+ LIT64( 0xFFFFFFFFFFFFFC00 ),
+ LIT64( 0xFFFFFFFFFFFFFE00 ),
+ LIT64( 0xFFFFFFFFFFFFFF00 ),
+ LIT64( 0xFFFFFFFFFFFFFF80 ),
+ LIT64( 0xFFFFFFFFFFFFFFC0 ),
+ LIT64( 0xFFFFFFFFFFFFFFE0 ),
+ LIT64( 0xFFFFFFFFFFFFFFF0 ),
+ LIT64( 0xFFFFFFFFFFFFFFF8 ),
+ LIT64( 0xFFFFFFFFFFFFFFFC ),
+ LIT64( 0xFFFFFFFFFFFFFFFE ),
+ LIT64( 0xFFFFFFFFFFFFFFFF ),
+ LIT64( 0xFFFFFFFFFFFFFFFD ),
+ LIT64( 0xFFFFFFFFFFFFFFFB ),
+ LIT64( 0xFFFFFFFFFFFFFFF7 ),
+ LIT64( 0xFFFFFFFFFFFFFFEF ),
+ LIT64( 0xFFFFFFFFFFFFFFDF ),
+ LIT64( 0xFFFFFFFFFFFFFFBF ),
+ LIT64( 0xFFFFFFFFFFFFFF7F ),
+ LIT64( 0xFFFFFFFFFFFFFEFF ),
+ LIT64( 0xFFFFFFFFFFFFFDFF ),
+ LIT64( 0xFFFFFFFFFFFFFBFF ),
+ LIT64( 0xFFFFFFFFFFFFF7FF ),
+ LIT64( 0xFFFFFFFFFFFFEFFF ),
+ LIT64( 0xFFFFFFFFFFFFDFFF ),
+ LIT64( 0xFFFFFFFFFFFFBFFF ),
+ LIT64( 0xFFFFFFFFFFFF7FFF ),
+ LIT64( 0xFFFFFFFFFFFEFFFF ),
+ LIT64( 0xFFFFFFFFFFFDFFFF ),
+ LIT64( 0xFFFFFFFFFFFBFFFF ),
+ LIT64( 0xFFFFFFFFFFF7FFFF ),
+ LIT64( 0xFFFFFFFFFFEFFFFF ),
+ LIT64( 0xFFFFFFFFFFDFFFFF ),
+ LIT64( 0xFFFFFFFFFFBFFFFF ),
+ LIT64( 0xFFFFFFFFFF7FFFFF ),
+ LIT64( 0xFFFFFFFFFEFFFFFF ),
+ LIT64( 0xFFFFFFFFFDFFFFFF ),
+ LIT64( 0xFFFFFFFFFBFFFFFF ),
+ LIT64( 0xFFFFFFFFF7FFFFFF ),
+ LIT64( 0xFFFFFFFFEFFFFFFF ),
+ LIT64( 0xFFFFFFFFDFFFFFFF ),
+ LIT64( 0xFFFFFFFFBFFFFFFF ),
+ LIT64( 0xFFFFFFFF7FFFFFFF ),
+ LIT64( 0xFFFFFFFEFFFFFFFF ),
+ LIT64( 0xFFFFFFFDFFFFFFFF ),
+ LIT64( 0xFFFFFFFBFFFFFFFF ),
+ LIT64( 0xFFFFFFF7FFFFFFFF ),
+ LIT64( 0xFFFFFFEFFFFFFFFF ),
+ LIT64( 0xFFFFFFDFFFFFFFFF ),
+ LIT64( 0xFFFFFFBFFFFFFFFF ),
+ LIT64( 0xFFFFFF7FFFFFFFFF ),
+ LIT64( 0xFFFFFEFFFFFFFFFF ),
+ LIT64( 0xFFFFFDFFFFFFFFFF ),
+ LIT64( 0xFFFFFBFFFFFFFFFF ),
+ LIT64( 0xFFFFF7FFFFFFFFFF ),
+ LIT64( 0xFFFFEFFFFFFFFFFF ),
+ LIT64( 0xFFFFDFFFFFFFFFFF ),
+ LIT64( 0xFFFFBFFFFFFFFFFF ),
+ LIT64( 0xFFFF7FFFFFFFFFFF ),
+ LIT64( 0xFFFEFFFFFFFFFFFF ),
+ LIT64( 0xFFFDFFFFFFFFFFFF ),
+ LIT64( 0xFFFBFFFFFFFFFFFF ),
+ LIT64( 0xFFF7FFFFFFFFFFFF ),
+ LIT64( 0xFFEFFFFFFFFFFFFF ),
+ LIT64( 0xFFDFFFFFFFFFFFFF ),
+ LIT64( 0xFFBFFFFFFFFFFFFF ),
+ LIT64( 0xFF7FFFFFFFFFFFFF ),
+ LIT64( 0xFEFFFFFFFFFFFFFF ),
+ LIT64( 0xFDFFFFFFFFFFFFFF ),
+ LIT64( 0xFBFFFFFFFFFFFFFF ),
+ LIT64( 0xF7FFFFFFFFFFFFFF ),
+ LIT64( 0xEFFFFFFFFFFFFFFF ),
+ LIT64( 0xDFFFFFFFFFFFFFFF ),
+ LIT64( 0xBFFFFFFFFFFFFFFF ),
+ LIT64( 0x7FFFFFFFFFFFFFFF ),
+ LIT64( 0x3FFFFFFFFFFFFFFF ),
+ LIT64( 0x1FFFFFFFFFFFFFFF ),
+ LIT64( 0x0FFFFFFFFFFFFFFF ),
+ LIT64( 0x07FFFFFFFFFFFFFF ),
+ LIT64( 0x03FFFFFFFFFFFFFF ),
+ LIT64( 0x01FFFFFFFFFFFFFF ),
+ LIT64( 0x00FFFFFFFFFFFFFF ),
+ LIT64( 0x007FFFFFFFFFFFFF ),
+ LIT64( 0x003FFFFFFFFFFFFF ),
+ LIT64( 0x001FFFFFFFFFFFFF ),
+ LIT64( 0x000FFFFFFFFFFFFF ),
+ LIT64( 0x0007FFFFFFFFFFFF ),
+ LIT64( 0x0003FFFFFFFFFFFF ),
+ LIT64( 0x0001FFFFFFFFFFFF ),
+ LIT64( 0x0000FFFFFFFFFFFF ),
+ LIT64( 0x00007FFFFFFFFFFF ),
+ LIT64( 0x00003FFFFFFFFFFF ),
+ LIT64( 0x00001FFFFFFFFFFF ),
+ LIT64( 0x00000FFFFFFFFFFF ),
+ LIT64( 0x000007FFFFFFFFFF ),
+ LIT64( 0x000003FFFFFFFFFF ),
+ LIT64( 0x000001FFFFFFFFFF ),
+ LIT64( 0x000000FFFFFFFFFF ),
+ LIT64( 0x0000007FFFFFFFFF ),
+ LIT64( 0x0000003FFFFFFFFF ),
+ LIT64( 0x0000001FFFFFFFFF ),
+ LIT64( 0x0000000FFFFFFFFF ),
+ LIT64( 0x00000007FFFFFFFF ),
+ LIT64( 0x00000003FFFFFFFF ),
+ LIT64( 0x00000001FFFFFFFF ),
+ LIT64( 0x00000000FFFFFFFF ),
+ LIT64( 0x000000007FFFFFFF ),
+ LIT64( 0x000000003FFFFFFF ),
+ LIT64( 0x000000001FFFFFFF ),
+ LIT64( 0x000000000FFFFFFF ),
+ LIT64( 0x0000000007FFFFFF ),
+ LIT64( 0x0000000003FFFFFF ),
+ LIT64( 0x0000000001FFFFFF ),
+ LIT64( 0x0000000000FFFFFF ),
+ LIT64( 0x00000000007FFFFF ),
+ LIT64( 0x00000000003FFFFF ),
+ LIT64( 0x00000000001FFFFF ),
+ LIT64( 0x00000000000FFFFF ),
+ LIT64( 0x000000000007FFFF ),
+ LIT64( 0x000000000003FFFF ),
+ LIT64( 0x000000000001FFFF ),
+ LIT64( 0x000000000000FFFF ),
+ LIT64( 0x0000000000007FFF ),
+ LIT64( 0x0000000000003FFF ),
+ LIT64( 0x0000000000001FFF ),
+ LIT64( 0x0000000000000FFF ),
+ LIT64( 0x00000000000007FF ),
+ LIT64( 0x00000000000003FF ),
+ LIT64( 0x00000000000001FF ),
+ LIT64( 0x00000000000000FF ),
+ LIT64( 0x000000000000007F ),
+ LIT64( 0x000000000000003F ),
+ LIT64( 0x000000000000001F ),
+ LIT64( 0x000000000000000F ),
+ LIT64( 0x0000000000000007 ),
+ LIT64( 0x0000000000000003 )
+};
+
+static int64 int64NextP1( sequenceT *sequencePtr )
+{
+ uint8 termNum;
+ int64 z;
+
+ termNum = sequencePtr->term1Num;
+ z = int64P1[ termNum ];
+ ++termNum;
+ if ( int64NumP1 <= termNum ) {
+ termNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->term1Num = termNum;
+ return (sbits64) z;
+
+}
+
+static const int64 int64NumP2 = ( int64NumP1 * int64NumP1 + int64NumP1 ) / 2;
+
+static int64 int64NextP2( sequenceT *sequencePtr )
+{
+ uint8 term1Num, term2Num;
+ int64 z;
+
+ term2Num = sequencePtr->term2Num;
+ term1Num = sequencePtr->term1Num;
+ z = int64P1[ term1Num ] + int64P1[ term2Num ];
+ ++term2Num;
+ if ( int64NumP1 <= term2Num ) {
+ ++term1Num;
+ if ( int64NumP1 <= term1Num ) {
+ term1Num = 0;
+ sequencePtr->done = TRUE;
+ }
+ term2Num = term1Num;
+ sequencePtr->term1Num = term1Num;
+ }
+ sequencePtr->term2Num = term2Num;
+ return (sbits64) z;
+
+}
+
+static int64 int64RandomP3( void )
+{
+
+ return
+ (sbits64) (
+ int64P1[ randomUint8() % int64NumP1 ]
+ + int64P1[ randomUint8() % int64NumP1 ]
+ + int64P1[ randomUint8() % int64NumP1 ]
+ );
+
+}
+
+enum {
+ int64NumPInfWeightMasks = 61
+};
+
+static const uint64 int64PInfWeightMasks[ int64NumPInfWeightMasks ] = {
+ LIT64( 0xFFFFFFFFFFFFFFFF ),
+ LIT64( 0x7FFFFFFFFFFFFFFF ),
+ LIT64( 0x3FFFFFFFFFFFFFFF ),
+ LIT64( 0x1FFFFFFFFFFFFFFF ),
+ LIT64( 0x0FFFFFFFFFFFFFFF ),
+ LIT64( 0x07FFFFFFFFFFFFFF ),
+ LIT64( 0x03FFFFFFFFFFFFFF ),
+ LIT64( 0x01FFFFFFFFFFFFFF ),
+ LIT64( 0x00FFFFFFFFFFFFFF ),
+ LIT64( 0x007FFFFFFFFFFFFF ),
+ LIT64( 0x003FFFFFFFFFFFFF ),
+ LIT64( 0x001FFFFFFFFFFFFF ),
+ LIT64( 0x000FFFFFFFFFFFFF ),
+ LIT64( 0x0007FFFFFFFFFFFF ),
+ LIT64( 0x0003FFFFFFFFFFFF ),
+ LIT64( 0x0001FFFFFFFFFFFF ),
+ LIT64( 0x0000FFFFFFFFFFFF ),
+ LIT64( 0x00007FFFFFFFFFFF ),
+ LIT64( 0x00003FFFFFFFFFFF ),
+ LIT64( 0x00001FFFFFFFFFFF ),
+ LIT64( 0x00000FFFFFFFFFFF ),
+ LIT64( 0x000007FFFFFFFFFF ),
+ LIT64( 0x000003FFFFFFFFFF ),
+ LIT64( 0x000001FFFFFFFFFF ),
+ LIT64( 0x000000FFFFFFFFFF ),
+ LIT64( 0x0000007FFFFFFFFF ),
+ LIT64( 0x0000003FFFFFFFFF ),
+ LIT64( 0x0000001FFFFFFFFF ),
+ LIT64( 0x0000000FFFFFFFFF ),
+ LIT64( 0x00000007FFFFFFFF ),
+ LIT64( 0x00000003FFFFFFFF ),
+ LIT64( 0x00000001FFFFFFFF ),
+ LIT64( 0x00000000FFFFFFFF ),
+ LIT64( 0x000000007FFFFFFF ),
+ LIT64( 0x000000003FFFFFFF ),
+ LIT64( 0x000000001FFFFFFF ),
+ LIT64( 0x000000000FFFFFFF ),
+ LIT64( 0x0000000007FFFFFF ),
+ LIT64( 0x0000000003FFFFFF ),
+ LIT64( 0x0000000001FFFFFF ),
+ LIT64( 0x0000000000FFFFFF ),
+ LIT64( 0x00000000007FFFFF ),
+ LIT64( 0x00000000003FFFFF ),
+ LIT64( 0x00000000001FFFFF ),
+ LIT64( 0x00000000000FFFFF ),
+ LIT64( 0x000000000007FFFF ),
+ LIT64( 0x000000000003FFFF ),
+ LIT64( 0x000000000001FFFF ),
+ LIT64( 0x000000000000FFFF ),
+ LIT64( 0x0000000000007FFF ),
+ LIT64( 0x0000000000003FFF ),
+ LIT64( 0x0000000000001FFF ),
+ LIT64( 0x0000000000000FFF ),
+ LIT64( 0x00000000000007FF ),
+ LIT64( 0x00000000000003FF ),
+ LIT64( 0x00000000000001FF ),
+ LIT64( 0x00000000000000FF ),
+ LIT64( 0x000000000000007F ),
+ LIT64( 0x000000000000003F ),
+ LIT64( 0x000000000000001F ),
+ LIT64( 0x000000000000000F )
+};
+
+static const uint64 int64PInfWeightOffsets[ int64NumPInfWeightMasks ] = {
+ LIT64( 0x0000000000000000 ),
+ LIT64( 0xC000000000000000 ),
+ LIT64( 0xE000000000000000 ),
+ LIT64( 0xF000000000000000 ),
+ LIT64( 0xF800000000000000 ),
+ LIT64( 0xFC00000000000000 ),
+ LIT64( 0xFE00000000000000 ),
+ LIT64( 0xFF00000000000000 ),
+ LIT64( 0xFF80000000000000 ),
+ LIT64( 0xFFC0000000000000 ),
+ LIT64( 0xFFE0000000000000 ),
+ LIT64( 0xFFF0000000000000 ),
+ LIT64( 0xFFF8000000000000 ),
+ LIT64( 0xFFFC000000000000 ),
+ LIT64( 0xFFFE000000000000 ),
+ LIT64( 0xFFFF000000000000 ),
+ LIT64( 0xFFFF800000000000 ),
+ LIT64( 0xFFFFC00000000000 ),
+ LIT64( 0xFFFFE00000000000 ),
+ LIT64( 0xFFFFF00000000000 ),
+ LIT64( 0xFFFFF80000000000 ),
+ LIT64( 0xFFFFFC0000000000 ),
+ LIT64( 0xFFFFFE0000000000 ),
+ LIT64( 0xFFFFFF0000000000 ),
+ LIT64( 0xFFFFFF8000000000 ),
+ LIT64( 0xFFFFFFC000000000 ),
+ LIT64( 0xFFFFFFE000000000 ),
+ LIT64( 0xFFFFFFF000000000 ),
+ LIT64( 0xFFFFFFF800000000 ),
+ LIT64( 0xFFFFFFFC00000000 ),
+ LIT64( 0xFFFFFFFE00000000 ),
+ LIT64( 0xFFFFFFFF00000000 ),
+ LIT64( 0xFFFFFFFF80000000 ),
+ LIT64( 0xFFFFFFFFC0000000 ),
+ LIT64( 0xFFFFFFFFE0000000 ),
+ LIT64( 0xFFFFFFFFF0000000 ),
+ LIT64( 0xFFFFFFFFF8000000 ),
+ LIT64( 0xFFFFFFFFFC000000 ),
+ LIT64( 0xFFFFFFFFFE000000 ),
+ LIT64( 0xFFFFFFFFFF000000 ),
+ LIT64( 0xFFFFFFFFFF800000 ),
+ LIT64( 0xFFFFFFFFFFC00000 ),
+ LIT64( 0xFFFFFFFFFFE00000 ),
+ LIT64( 0xFFFFFFFFFFF00000 ),
+ LIT64( 0xFFFFFFFFFFF80000 ),
+ LIT64( 0xFFFFFFFFFFFC0000 ),
+ LIT64( 0xFFFFFFFFFFFE0000 ),
+ LIT64( 0xFFFFFFFFFFFF0000 ),
+ LIT64( 0xFFFFFFFFFFFF8000 ),
+ LIT64( 0xFFFFFFFFFFFFC000 ),
+ LIT64( 0xFFFFFFFFFFFFE000 ),
+ LIT64( 0xFFFFFFFFFFFFF000 ),
+ LIT64( 0xFFFFFFFFFFFFF800 ),
+ LIT64( 0xFFFFFFFFFFFFFC00 ),
+ LIT64( 0xFFFFFFFFFFFFFE00 ),
+ LIT64( 0xFFFFFFFFFFFFFF00 ),
+ LIT64( 0xFFFFFFFFFFFFFF80 ),
+ LIT64( 0xFFFFFFFFFFFFFFC0 ),
+ LIT64( 0xFFFFFFFFFFFFFFE0 ),
+ LIT64( 0xFFFFFFFFFFFFFFF0 ),
+ LIT64( 0xFFFFFFFFFFFFFFF8 )
+};
+
+static int64 int64RandomPInf( void )
+{
+ int8 weightMaskNum;
+
+ weightMaskNum = randomUint8() % int64NumPInfWeightMasks;
+ return
+ (sbits64) (
+ ( randomUint64() & int64PInfWeightMasks[ weightMaskNum ] )
+ + int64PInfWeightOffsets[ weightMaskNum ]
+ );
+
+}
+
+#endif
+
+enum {
+ float32NumQIn = 22,
+ float32NumQOut = 50,
+ float32NumP1 = 4,
+ float32NumP2 = 88
+};
+
+static const uint32 float32QIn[ float32NumQIn ] = {
+ 0x00000000, /* positive, subnormal */
+ 0x00800000, /* positive, -126 */
+ 0x33800000, /* positive, -24 */
+ 0x3E800000, /* positive, -2 */
+ 0x3F000000, /* positive, -1 */
+ 0x3F800000, /* positive, 0 */
+ 0x40000000, /* positive, 1 */
+ 0x40800000, /* positive, 2 */
+ 0x4B800000, /* positive, 24 */
+ 0x7F000000, /* positive, 127 */
+ 0x7F800000, /* positive, infinity or NaN */
+ 0x80000000, /* negative, subnormal */
+ 0x80800000, /* negative, -126 */
+ 0xB3800000, /* negative, -24 */
+ 0xBE800000, /* negative, -2 */
+ 0xBF000000, /* negative, -1 */
+ 0xBF800000, /* negative, 0 */
+ 0xC0000000, /* negative, 1 */
+ 0xC0800000, /* negative, 2 */
+ 0xCB800000, /* negative, 24 */
+ 0xFE800000, /* negative, 126 */
+ 0xFF800000 /* negative, infinity or NaN */
+};
+
+static const uint32 float32QOut[ float32NumQOut ] = {
+ 0x00000000, /* positive, subnormal */
+ 0x00800000, /* positive, -126 */
+ 0x01000000, /* positive, -125 */
+ 0x33800000, /* positive, -24 */
+ 0x3D800000, /* positive, -4 */
+ 0x3E000000, /* positive, -3 */
+ 0x3E800000, /* positive, -2 */
+ 0x3F000000, /* positive, -1 */
+ 0x3F800000, /* positive, 0 */
+ 0x40000000, /* positive, 1 */
+ 0x40800000, /* positive, 2 */
+ 0x41000000, /* positive, 3 */
+ 0x41800000, /* positive, 4 */
+ 0x4B800000, /* positive, 24 */
+ 0x4E000000, /* positive, 29 */
+ 0x4E800000, /* positive, 30 */
+ 0x4F000000, /* positive, 31 */
+ 0x4F800000, /* positive, 32 */
+ 0x5E000000, /* positive, 61 */
+ 0x5E800000, /* positive, 62 */
+ 0x5F000000, /* positive, 63 */
+ 0x5F800000, /* positive, 64 */
+ 0x7E800000, /* positive, 126 */
+ 0x7F000000, /* positive, 127 */
+ 0x7F800000, /* positive, infinity or NaN */
+ 0x80000000, /* negative, subnormal */
+ 0x80800000, /* negative, -126 */
+ 0x81000000, /* negative, -125 */
+ 0xB3800000, /* negative, -24 */
+ 0xBD800000, /* negative, -4 */
+ 0xBE000000, /* negative, -3 */
+ 0xBE800000, /* negative, -2 */
+ 0xBF000000, /* negative, -1 */
+ 0xBF800000, /* negative, 0 */
+ 0xC0000000, /* negative, 1 */
+ 0xC0800000, /* negative, 2 */
+ 0xC1000000, /* negative, 3 */
+ 0xC1800000, /* negative, 4 */
+ 0xCB800000, /* negative, 24 */
+ 0xCE000000, /* negative, 29 */
+ 0xCE800000, /* negative, 30 */
+ 0xCF000000, /* negative, 31 */
+ 0xCF800000, /* negative, 32 */
+ 0xDE000000, /* negative, 61 */
+ 0xDE800000, /* negative, 62 */
+ 0xDF000000, /* negative, 63 */
+ 0xDF800000, /* negative, 64 */
+ 0xFE800000, /* negative, 126 */
+ 0xFF000000, /* negative, 127 */
+ 0xFF800000 /* negative, infinity or NaN */
+};
+
+static const uint32 float32P1[ float32NumP1 ] = {
+ 0x00000000,
+ 0x00000001,
+ 0x007FFFFF,
+ 0x007FFFFE
+};
+
+static const uint32 float32P2[ float32NumP2 ] = {
+ 0x00000000,
+ 0x00000001,
+ 0x00000002,
+ 0x00000004,
+ 0x00000008,
+ 0x00000010,
+ 0x00000020,
+ 0x00000040,
+ 0x00000080,
+ 0x00000100,
+ 0x00000200,
+ 0x00000400,
+ 0x00000800,
+ 0x00001000,
+ 0x00002000,
+ 0x00004000,
+ 0x00008000,
+ 0x00010000,
+ 0x00020000,
+ 0x00040000,
+ 0x00080000,
+ 0x00100000,
+ 0x00200000,
+ 0x00400000,
+ 0x00600000,
+ 0x00700000,
+ 0x00780000,
+ 0x007C0000,
+ 0x007E0000,
+ 0x007F0000,
+ 0x007F8000,
+ 0x007FC000,
+ 0x007FE000,
+ 0x007FF000,
+ 0x007FF800,
+ 0x007FFC00,
+ 0x007FFE00,
+ 0x007FFF00,
+ 0x007FFF80,
+ 0x007FFFC0,
+ 0x007FFFE0,
+ 0x007FFFF0,
+ 0x007FFFF8,
+ 0x007FFFFC,
+ 0x007FFFFE,
+ 0x007FFFFF,
+ 0x007FFFFD,
+ 0x007FFFFB,
+ 0x007FFFF7,
+ 0x007FFFEF,
+ 0x007FFFDF,
+ 0x007FFFBF,
+ 0x007FFF7F,
+ 0x007FFEFF,
+ 0x007FFDFF,
+ 0x007FFBFF,
+ 0x007FF7FF,
+ 0x007FEFFF,
+ 0x007FDFFF,
+ 0x007FBFFF,
+ 0x007F7FFF,
+ 0x007EFFFF,
+ 0x007DFFFF,
+ 0x007BFFFF,
+ 0x0077FFFF,
+ 0x006FFFFF,
+ 0x005FFFFF,
+ 0x003FFFFF,
+ 0x001FFFFF,
+ 0x000FFFFF,
+ 0x0007FFFF,
+ 0x0003FFFF,
+ 0x0001FFFF,
+ 0x0000FFFF,
+ 0x00007FFF,
+ 0x00003FFF,
+ 0x00001FFF,
+ 0x00000FFF,
+ 0x000007FF,
+ 0x000003FF,
+ 0x000001FF,
+ 0x000000FF,
+ 0x0000007F,
+ 0x0000003F,
+ 0x0000001F,
+ 0x0000000F,
+ 0x00000007,
+ 0x00000003
+};
+
+static const uint32 float32NumQInP1 = float32NumQIn * float32NumP1;
+static const uint32 float32NumQOutP1 = float32NumQOut * float32NumP1;
+
+static float32 float32NextQInP1( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float32 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z = float32QIn[ expNum ] | float32P1[ sigNum ];
+ ++sigNum;
+ if ( float32NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float32NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float32 float32NextQOutP1( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float32 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z = float32QOut[ expNum ] | float32P1[ sigNum ];
+ ++sigNum;
+ if ( float32NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float32NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static const uint32 float32NumQInP2 = float32NumQIn * float32NumP2;
+static const uint32 float32NumQOutP2 = float32NumQOut * float32NumP2;
+
+static float32 float32NextQInP2( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float32 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z = float32QIn[ expNum ] | float32P2[ sigNum ];
+ ++sigNum;
+ if ( float32NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float32NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float32 float32NextQOutP2( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float32 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z = float32QOut[ expNum ] | float32P2[ sigNum ];
+ ++sigNum;
+ if ( float32NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float32NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float32 float32RandomQOutP3( void )
+{
+
+ return
+ float32QOut[ randomUint8() % float32NumQOut ]
+ | ( ( float32P2[ randomUint8() % float32NumP2 ]
+ + float32P2[ randomUint8() % float32NumP2 ] )
+ & 0x007FFFFF );
+
+}
+
+static float32 float32RandomQOutPInf( void )
+{
+
+ return
+ float32QOut[ randomUint8() % float32NumQOut ]
+ | ( randomUint32() & 0x007FFFFF );
+
+}
+
+enum {
+ float32NumQInfWeightMasks = 7
+};
+
+static const uint32 float32QInfWeightMasks[ float32NumQInfWeightMasks ] = {
+ 0x7F800000,
+ 0x7F800000,
+ 0x3F800000,
+ 0x1F800000,
+ 0x0F800000,
+ 0x07800000,
+ 0x03800000
+};
+
+static const uint32 float32QInfWeightOffsets[ float32NumQInfWeightMasks ] = {
+ 0x00000000,
+ 0x00000000,
+ 0x20000000,
+ 0x30000000,
+ 0x38000000,
+ 0x3C000000,
+ 0x3E000000
+};
+
+static float32 float32RandomQInfP3( void )
+{
+ int8 weightMaskNum;
+
+ weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
+ return
+ ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+ | ( ( ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
+ & float32QInfWeightMasks[ weightMaskNum ] )
+ + float32QInfWeightOffsets[ weightMaskNum ]
+ )
+ | ( ( float32P2[ randomUint8() % float32NumP2 ]
+ + float32P2[ randomUint8() % float32NumP2 ] )
+ & 0x007FFFFF );
+
+}
+
+static float32 float32RandomQInfPInf( void )
+{
+ int8 weightMaskNum;
+
+ weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
+ return
+ ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+ | ( ( ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
+ & float32QInfWeightMasks[ weightMaskNum ] )
+ + float32QInfWeightOffsets[ weightMaskNum ]
+ )
+ | ( randomUint32() & 0x007FFFFF );
+
+}
+
+static float32 float32Random( void )
+{
+
+ switch ( randomUint8() & 7 ) {
+ case 0:
+ case 1:
+ case 2:
+ return float32RandomQOutP3();
+ case 3:
+ return float32RandomQOutPInf();
+ case 4:
+ case 5:
+ case 6:
+ return float32RandomQInfP3();
+ default:
+ return float32RandomQInfPInf();
+ }
+
+}
+
+#ifdef BITS64
+#define SETFLOAT64( z, zHigh, zLow ) z = ( ( (float64) zHigh )<<32 ) | zLow
+#else
+#define SETFLOAT64( z, zHigh, zLow ) z.low = zLow; z.high = zHigh
+#endif
+
+enum {
+ float64NumQIn = 22,
+ float64NumQOut = 64,
+ float64NumP1 = 4,
+ float64NumP2 = 204
+};
+
+static const uint32 float64QIn[ float64NumQIn ] = {
+ 0x00000000, /* positive, subnormal */
+ 0x00100000, /* positive, -1022 */
+ 0x3CA00000, /* positive, -53 */
+ 0x3FD00000, /* positive, -2 */
+ 0x3FE00000, /* positive, -1 */
+ 0x3FF00000, /* positive, 0 */
+ 0x40000000, /* positive, 1 */
+ 0x40100000, /* positive, 2 */
+ 0x43400000, /* positive, 53 */
+ 0x7FE00000, /* positive, 1023 */
+ 0x7FF00000, /* positive, infinity or NaN */
+ 0x80000000, /* negative, subnormal */
+ 0x80100000, /* negative, -1022 */
+ 0xBCA00000, /* negative, -53 */
+ 0xBFD00000, /* negative, -2 */
+ 0xBFE00000, /* negative, -1 */
+ 0xBFF00000, /* negative, 0 */
+ 0xC0000000, /* negative, 1 */
+ 0xC0100000, /* negative, 2 */
+ 0xC3400000, /* negative, 53 */
+ 0xFFE00000, /* negative, 1023 */
+ 0xFFF00000 /* negative, infinity or NaN */
+};
+
+static const uint32 float64QOut[ float64NumQOut ] = {
+ 0x00000000, /* positive, subnormal */
+ 0x00100000, /* positive, -1022 */
+ 0x00200000, /* positive, -1021 */
+ 0x37E00000, /* positive, -129 */
+ 0x37F00000, /* positive, -128 */
+ 0x38000000, /* positive, -127 */
+ 0x38100000, /* positive, -126 */
+ 0x3CA00000, /* positive, -53 */
+ 0x3FB00000, /* positive, -4 */
+ 0x3FC00000, /* positive, -3 */
+ 0x3FD00000, /* positive, -2 */
+ 0x3FE00000, /* positive, -1 */
+ 0x3FF00000, /* positive, 0 */
+ 0x40000000, /* positive, 1 */
+ 0x40100000, /* positive, 2 */
+ 0x40200000, /* positive, 3 */
+ 0x40300000, /* positive, 4 */
+ 0x41C00000, /* positive, 29 */
+ 0x41D00000, /* positive, 30 */
+ 0x41E00000, /* positive, 31 */
+ 0x41F00000, /* positive, 32 */
+ 0x43400000, /* positive, 53 */
+ 0x43C00000, /* positive, 61 */
+ 0x43D00000, /* positive, 62 */
+ 0x43E00000, /* positive, 63 */
+ 0x43F00000, /* positive, 64 */
+ 0x47E00000, /* positive, 127 */
+ 0x47F00000, /* positive, 128 */
+ 0x48000000, /* positive, 129 */
+ 0x7FD00000, /* positive, 1022 */
+ 0x7FE00000, /* positive, 1023 */
+ 0x7FF00000, /* positive, infinity or NaN */
+ 0x80000000, /* negative, subnormal */
+ 0x80100000, /* negative, -1022 */
+ 0x80200000, /* negative, -1021 */
+ 0xB7E00000, /* negative, -129 */
+ 0xB7F00000, /* negative, -128 */
+ 0xB8000000, /* negative, -127 */
+ 0xB8100000, /* negative, -126 */
+ 0xBCA00000, /* negative, -53 */
+ 0xBFB00000, /* negative, -4 */
+ 0xBFC00000, /* negative, -3 */
+ 0xBFD00000, /* negative, -2 */
+ 0xBFE00000, /* negative, -1 */
+ 0xBFF00000, /* negative, 0 */
+ 0xC0000000, /* negative, 1 */
+ 0xC0100000, /* negative, 2 */
+ 0xC0200000, /* negative, 3 */
+ 0xC0300000, /* negative, 4 */
+ 0xC1C00000, /* negative, 29 */
+ 0xC1D00000, /* negative, 30 */
+ 0xC1E00000, /* negative, 31 */
+ 0xC1F00000, /* negative, 32 */
+ 0xC3400000, /* negative, 53 */
+ 0xC3C00000, /* negative, 61 */
+ 0xC3D00000, /* negative, 62 */
+ 0xC3E00000, /* negative, 63 */
+ 0xC3F00000, /* negative, 64 */
+ 0xC7E00000, /* negative, 127 */
+ 0xC7F00000, /* negative, 128 */
+ 0xC8000000, /* negative, 129 */
+ 0xFFD00000, /* negative, 1022 */
+ 0xFFE00000, /* negative, 1023 */
+ 0xFFF00000 /* negative, infinity or NaN */
+};
+
+static const struct { bits32 high, low; } float64P1[ float64NumP1 ] = {
+ { 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000001 },
+ { 0x000FFFFF, 0xFFFFFFFF },
+ { 0x000FFFFF, 0xFFFFFFFE }
+};
+
+static const struct { bits32 high, low; } float64P2[ float64NumP2 ] = {
+ { 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000001 },
+ { 0x00000000, 0x00000002 },
+ { 0x00000000, 0x00000004 },
+ { 0x00000000, 0x00000008 },
+ { 0x00000000, 0x00000010 },
+ { 0x00000000, 0x00000020 },
+ { 0x00000000, 0x00000040 },
+ { 0x00000000, 0x00000080 },
+ { 0x00000000, 0x00000100 },
+ { 0x00000000, 0x00000200 },
+ { 0x00000000, 0x00000400 },
+ { 0x00000000, 0x00000800 },
+ { 0x00000000, 0x00001000 },
+ { 0x00000000, 0x00002000 },
+ { 0x00000000, 0x00004000 },
+ { 0x00000000, 0x00008000 },
+ { 0x00000000, 0x00010000 },
+ { 0x00000000, 0x00020000 },
+ { 0x00000000, 0x00040000 },
+ { 0x00000000, 0x00080000 },
+ { 0x00000000, 0x00100000 },
+ { 0x00000000, 0x00200000 },
+ { 0x00000000, 0x00400000 },
+ { 0x00000000, 0x00800000 },
+ { 0x00000000, 0x01000000 },
+ { 0x00000000, 0x02000000 },
+ { 0x00000000, 0x04000000 },
+ { 0x00000000, 0x08000000 },
+ { 0x00000000, 0x10000000 },
+ { 0x00000000, 0x20000000 },
+ { 0x00000000, 0x40000000 },
+ { 0x00000000, 0x80000000 },
+ { 0x00000001, 0x00000000 },
+ { 0x00000002, 0x00000000 },
+ { 0x00000004, 0x00000000 },
+ { 0x00000008, 0x00000000 },
+ { 0x00000010, 0x00000000 },
+ { 0x00000020, 0x00000000 },
+ { 0x00000040, 0x00000000 },
+ { 0x00000080, 0x00000000 },
+ { 0x00000100, 0x00000000 },
+ { 0x00000200, 0x00000000 },
+ { 0x00000400, 0x00000000 },
+ { 0x00000800, 0x00000000 },
+ { 0x00001000, 0x00000000 },
+ { 0x00002000, 0x00000000 },
+ { 0x00004000, 0x00000000 },
+ { 0x00008000, 0x00000000 },
+ { 0x00010000, 0x00000000 },
+ { 0x00020000, 0x00000000 },
+ { 0x00040000, 0x00000000 },
+ { 0x00080000, 0x00000000 },
+ { 0x000C0000, 0x00000000 },
+ { 0x000E0000, 0x00000000 },
+ { 0x000F0000, 0x00000000 },
+ { 0x000F8000, 0x00000000 },
+ { 0x000FC000, 0x00000000 },
+ { 0x000FE000, 0x00000000 },
+ { 0x000FF000, 0x00000000 },
+ { 0x000FF800, 0x00000000 },
+ { 0x000FFC00, 0x00000000 },
+ { 0x000FFE00, 0x00000000 },
+ { 0x000FFF00, 0x00000000 },
+ { 0x000FFF80, 0x00000000 },
+ { 0x000FFFC0, 0x00000000 },
+ { 0x000FFFE0, 0x00000000 },
+ { 0x000FFFF0, 0x00000000 },
+ { 0x000FFFF8, 0x00000000 },
+ { 0x000FFFFC, 0x00000000 },
+ { 0x000FFFFE, 0x00000000 },
+ { 0x000FFFFF, 0x00000000 },
+ { 0x000FFFFF, 0x80000000 },
+ { 0x000FFFFF, 0xC0000000 },
+ { 0x000FFFFF, 0xE0000000 },
+ { 0x000FFFFF, 0xF0000000 },
+ { 0x000FFFFF, 0xF8000000 },
+ { 0x000FFFFF, 0xFC000000 },
+ { 0x000FFFFF, 0xFE000000 },
+ { 0x000FFFFF, 0xFF000000 },
+ { 0x000FFFFF, 0xFF800000 },
+ { 0x000FFFFF, 0xFFC00000 },
+ { 0x000FFFFF, 0xFFE00000 },
+ { 0x000FFFFF, 0xFFF00000 },
+ { 0x000FFFFF, 0xFFF80000 },
+ { 0x000FFFFF, 0xFFFC0000 },
+ { 0x000FFFFF, 0xFFFE0000 },
+ { 0x000FFFFF, 0xFFFF0000 },
+ { 0x000FFFFF, 0xFFFF8000 },
+ { 0x000FFFFF, 0xFFFFC000 },
+ { 0x000FFFFF, 0xFFFFE000 },
+ { 0x000FFFFF, 0xFFFFF000 },
+ { 0x000FFFFF, 0xFFFFF800 },
+ { 0x000FFFFF, 0xFFFFFC00 },
+ { 0x000FFFFF, 0xFFFFFE00 },
+ { 0x000FFFFF, 0xFFFFFF00 },
+ { 0x000FFFFF, 0xFFFFFF80 },
+ { 0x000FFFFF, 0xFFFFFFC0 },
+ { 0x000FFFFF, 0xFFFFFFE0 },
+ { 0x000FFFFF, 0xFFFFFFF0 },
+ { 0x000FFFFF, 0xFFFFFFF8 },
+ { 0x000FFFFF, 0xFFFFFFFC },
+ { 0x000FFFFF, 0xFFFFFFFE },
+ { 0x000FFFFF, 0xFFFFFFFF },
+ { 0x000FFFFF, 0xFFFFFFFD },
+ { 0x000FFFFF, 0xFFFFFFFB },
+ { 0x000FFFFF, 0xFFFFFFF7 },
+ { 0x000FFFFF, 0xFFFFFFEF },
+ { 0x000FFFFF, 0xFFFFFFDF },
+ { 0x000FFFFF, 0xFFFFFFBF },
+ { 0x000FFFFF, 0xFFFFFF7F },
+ { 0x000FFFFF, 0xFFFFFEFF },
+ { 0x000FFFFF, 0xFFFFFDFF },
+ { 0x000FFFFF, 0xFFFFFBFF },
+ { 0x000FFFFF, 0xFFFFF7FF },
+ { 0x000FFFFF, 0xFFFFEFFF },
+ { 0x000FFFFF, 0xFFFFDFFF },
+ { 0x000FFFFF, 0xFFFFBFFF },
+ { 0x000FFFFF, 0xFFFF7FFF },
+ { 0x000FFFFF, 0xFFFEFFFF },
+ { 0x000FFFFF, 0xFFFDFFFF },
+ { 0x000FFFFF, 0xFFFBFFFF },
+ { 0x000FFFFF, 0xFFF7FFFF },
+ { 0x000FFFFF, 0xFFEFFFFF },
+ { 0x000FFFFF, 0xFFDFFFFF },
+ { 0x000FFFFF, 0xFFBFFFFF },
+ { 0x000FFFFF, 0xFF7FFFFF },
+ { 0x000FFFFF, 0xFEFFFFFF },
+ { 0x000FFFFF, 0xFDFFFFFF },
+ { 0x000FFFFF, 0xFBFFFFFF },
+ { 0x000FFFFF, 0xF7FFFFFF },
+ { 0x000FFFFF, 0xEFFFFFFF },
+ { 0x000FFFFF, 0xDFFFFFFF },
+ { 0x000FFFFF, 0xBFFFFFFF },
+ { 0x000FFFFF, 0x7FFFFFFF },
+ { 0x000FFFFE, 0xFFFFFFFF },
+ { 0x000FFFFD, 0xFFFFFFFF },
+ { 0x000FFFFB, 0xFFFFFFFF },
+ { 0x000FFFF7, 0xFFFFFFFF },
+ { 0x000FFFEF, 0xFFFFFFFF },
+ { 0x000FFFDF, 0xFFFFFFFF },
+ { 0x000FFFBF, 0xFFFFFFFF },
+ { 0x000FFF7F, 0xFFFFFFFF },
+ { 0x000FFEFF, 0xFFFFFFFF },
+ { 0x000FFDFF, 0xFFFFFFFF },
+ { 0x000FFBFF, 0xFFFFFFFF },
+ { 0x000FF7FF, 0xFFFFFFFF },
+ { 0x000FEFFF, 0xFFFFFFFF },
+ { 0x000FDFFF, 0xFFFFFFFF },
+ { 0x000FBFFF, 0xFFFFFFFF },
+ { 0x000F7FFF, 0xFFFFFFFF },
+ { 0x000EFFFF, 0xFFFFFFFF },
+ { 0x000DFFFF, 0xFFFFFFFF },
+ { 0x000BFFFF, 0xFFFFFFFF },
+ { 0x0007FFFF, 0xFFFFFFFF },
+ { 0x0003FFFF, 0xFFFFFFFF },
+ { 0x0001FFFF, 0xFFFFFFFF },
+ { 0x0000FFFF, 0xFFFFFFFF },
+ { 0x00007FFF, 0xFFFFFFFF },
+ { 0x00003FFF, 0xFFFFFFFF },
+ { 0x00001FFF, 0xFFFFFFFF },
+ { 0x00000FFF, 0xFFFFFFFF },
+ { 0x000007FF, 0xFFFFFFFF },
+ { 0x000003FF, 0xFFFFFFFF },
+ { 0x000001FF, 0xFFFFFFFF },
+ { 0x000000FF, 0xFFFFFFFF },
+ { 0x0000007F, 0xFFFFFFFF },
+ { 0x0000003F, 0xFFFFFFFF },
+ { 0x0000001F, 0xFFFFFFFF },
+ { 0x0000000F, 0xFFFFFFFF },
+ { 0x00000007, 0xFFFFFFFF },
+ { 0x00000003, 0xFFFFFFFF },
+ { 0x00000001, 0xFFFFFFFF },
+ { 0x00000000, 0xFFFFFFFF },
+ { 0x00000000, 0x7FFFFFFF },
+ { 0x00000000, 0x3FFFFFFF },
+ { 0x00000000, 0x1FFFFFFF },
+ { 0x00000000, 0x0FFFFFFF },
+ { 0x00000000, 0x07FFFFFF },
+ { 0x00000000, 0x03FFFFFF },
+ { 0x00000000, 0x01FFFFFF },
+ { 0x00000000, 0x00FFFFFF },
+ { 0x00000000, 0x007FFFFF },
+ { 0x00000000, 0x003FFFFF },
+ { 0x00000000, 0x001FFFFF },
+ { 0x00000000, 0x000FFFFF },
+ { 0x00000000, 0x0007FFFF },
+ { 0x00000000, 0x0003FFFF },
+ { 0x00000000, 0x0001FFFF },
+ { 0x00000000, 0x0000FFFF },
+ { 0x00000000, 0x00007FFF },
+ { 0x00000000, 0x00003FFF },
+ { 0x00000000, 0x00001FFF },
+ { 0x00000000, 0x00000FFF },
+ { 0x00000000, 0x000007FF },
+ { 0x00000000, 0x000003FF },
+ { 0x00000000, 0x000001FF },
+ { 0x00000000, 0x000000FF },
+ { 0x00000000, 0x0000007F },
+ { 0x00000000, 0x0000003F },
+ { 0x00000000, 0x0000001F },
+ { 0x00000000, 0x0000000F },
+ { 0x00000000, 0x00000007 },
+ { 0x00000000, 0x00000003 }
+};
+
+static const uint32 float64NumQInP1 = float64NumQIn * float64NumP1;
+static const uint32 float64NumQOutP1 = float64NumQOut * float64NumP1;
+
+static float64 float64NextQInP1( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float64 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ SETFLOAT64(
+ z,
+ float64QIn[ expNum ] | float64P1[ sigNum ].high,
+ float64P1[ sigNum ].low
+ );
+ ++sigNum;
+ if ( float64NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float64NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float64 float64NextQOutP1( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float64 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ SETFLOAT64(
+ z,
+ float64QOut[ expNum ] | float64P1[ sigNum ].high,
+ float64P1[ sigNum ].low
+ );
+ ++sigNum;
+ if ( float64NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float64NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static const uint32 float64NumQInP2 = float64NumQIn * float64NumP2;
+static const uint32 float64NumQOutP2 = float64NumQOut * float64NumP2;
+
+static float64 float64NextQInP2( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float64 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ SETFLOAT64(
+ z,
+ float64QIn[ expNum ] | float64P2[ sigNum ].high,
+ float64P2[ sigNum ].low
+ );
+ ++sigNum;
+ if ( float64NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float64NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float64 float64NextQOutP2( sequenceT *sequencePtr )
+{
+ uint8 expNum, sigNum;
+ float64 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ SETFLOAT64(
+ z,
+ float64QOut[ expNum ] | float64P2[ sigNum ].high,
+ float64P2[ sigNum ].low
+ );
+ ++sigNum;
+ if ( float64NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float64NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float64 float64RandomQOutP3( void )
+{
+ int8 sigNum1, sigNum2;
+ uint32 sig1Low, sig2Low, zLow;
+ float64 z;
+
+ sigNum1 = randomUint8() % float64NumP2;
+ sigNum2 = randomUint8() % float64NumP2;
+ sig1Low = float64P2[ sigNum1 ].low;
+ sig2Low = float64P2[ sigNum2 ].low;
+ zLow = sig1Low + sig2Low;
+ SETFLOAT64(
+ z,
+ float64QOut[ randomUint8() % float64NumQOut ]
+ | ( ( float64P2[ sigNum1 ].high
+ + float64P2[ sigNum2 ].high
+ + ( zLow < sig1Low )
+ )
+ & 0x000FFFFF
+ ),
+ zLow
+ );
+ return z;
+
+}
+
+static float64 float64RandomQOutPInf( void )
+{
+ float64 z;
+
+ SETFLOAT64(
+ z,
+ float64QOut[ randomUint8() % float64NumQOut ]
+ | ( randomUint32() & 0x000FFFFF ),
+ randomUint32()
+ );
+ return z;
+
+}
+
+enum {
+ float64NumQInfWeightMasks = 10
+};
+
+static const uint32 float64QInfWeightMasks[ float64NumQInfWeightMasks ] = {
+ 0x7FF00000,
+ 0x7FF00000,
+ 0x3FF00000,
+ 0x1FF00000,
+ 0x0FF00000,
+ 0x07F00000,
+ 0x03F00000,
+ 0x01F00000,
+ 0x00F00000,
+ 0x00700000
+};
+
+static const uint32 float64QInfWeightOffsets[ float64NumQInfWeightMasks ] = {
+ 0x00000000,
+ 0x00000000,
+ 0x20000000,
+ 0x30000000,
+ 0x38000000,
+ 0x3C000000,
+ 0x3E000000,
+ 0x3F000000,
+ 0x3F800000,
+ 0x3FC00000
+};
+
+static float64 float64RandomQInfP3( void )
+{
+ int8 sigNum1, sigNum2;
+ uint32 sig1Low, sig2Low, zLow;
+ int8 weightMaskNum;
+ float64 z;
+
+ sigNum1 = randomUint8() % float64NumP2;
+ sigNum2 = randomUint8() % float64NumP2;
+ sig1Low = float64P2[ sigNum1 ].low;
+ sig2Low = float64P2[ sigNum2 ].low;
+ zLow = sig1Low + sig2Low;
+ weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
+ SETFLOAT64(
+ z,
+ ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+ | ( ( ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
+ & float64QInfWeightMasks[ weightMaskNum ] )
+ + float64QInfWeightOffsets[ weightMaskNum ]
+ )
+ | ( ( float64P2[ sigNum1 ].high
+ + float64P2[ sigNum2 ].high
+ + ( zLow < sig1Low )
+ )
+ & 0x000FFFFF
+ ),
+ zLow
+ );
+ return z;
+
+}
+
+static float64 float64RandomQInfPInf( void )
+{
+ int8 weightMaskNum;
+ float64 z;
+
+ weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
+ SETFLOAT64(
+ z,
+ ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+ | ( ( ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
+ & float64QInfWeightMasks[ weightMaskNum ] )
+ + float64QInfWeightOffsets[ weightMaskNum ]
+ )
+ | ( randomUint32() & 0x000FFFFF ),
+ randomUint32()
+ );
+ return z;
+
+}
+
+static float64 float64Random( void )
+{
+
+ switch ( randomUint8() & 7 ) {
+ case 0:
+ case 1:
+ case 2:
+ return float64RandomQOutP3();
+ case 3:
+ return float64RandomQOutPInf();
+ case 4:
+ case 5:
+ case 6:
+ return float64RandomQInfP3();
+ default:
+ return float64RandomQInfPInf();
+ }
+
+}
+
+#ifdef FLOATX80
+
+enum {
+ floatx80NumQIn = 22,
+ floatx80NumQOut = 76,
+ floatx80NumP1 = 4,
+ floatx80NumP2 = 248
+};
+
+static const uint16 floatx80QIn[ floatx80NumQIn ] = {
+ 0x0000, /* positive, subnormal */
+ 0x0001, /* positive, -16382 */
+ 0x3FBF, /* positive, -64 */
+ 0x3FFD, /* positive, -2 */
+ 0x3FFE, /* positive, -1 */
+ 0x3FFF, /* positive, 0 */
+ 0x4000, /* positive, 1 */
+ 0x4001, /* positive, 2 */
+ 0x403F, /* positive, 64 */
+ 0x7FFE, /* positive, 16383 */
+ 0x7FFF, /* positive, infinity or NaN */
+ 0x8000, /* negative, subnormal */
+ 0x8001, /* negative, -16382 */
+ 0xBFBF, /* negative, -64 */
+ 0xBFFD, /* negative, -2 */
+ 0xBFFE, /* negative, -1 */
+ 0xBFFF, /* negative, 0 */
+ 0xC000, /* negative, 1 */
+ 0xC001, /* negative, 2 */
+ 0xC03F, /* negative, 64 */
+ 0xFFFE, /* negative, 16383 */
+ 0xFFFF /* negative, infinity or NaN */
+};
+
+static const uint16 floatx80QOut[ floatx80NumQOut ] = {
+ 0x0000, /* positive, subnormal */
+ 0x0001, /* positive, -16382 */
+ 0x0002, /* positive, -16381 */
+ 0x3BFE, /* positive, -1025 */
+ 0x3BFF, /* positive, -1024 */
+ 0x3C00, /* positive, -1023 */
+ 0x3C01, /* positive, -1022 */
+ 0x3F7E, /* positive, -129 */
+ 0x3F7F, /* positive, -128 */
+ 0x3F80, /* positive, -127 */
+ 0x3F81, /* positive, -126 */
+ 0x3FBF, /* positive, -64 */
+ 0x3FFB, /* positive, -4 */
+ 0x3FFC, /* positive, -3 */
+ 0x3FFD, /* positive, -2 */
+ 0x3FFE, /* positive, -1 */
+ 0x3FFF, /* positive, 0 */
+ 0x4000, /* positive, 1 */
+ 0x4001, /* positive, 2 */
+ 0x4002, /* positive, 3 */
+ 0x4003, /* positive, 4 */
+ 0x401C, /* positive, 29 */
+ 0x401D, /* positive, 30 */
+ 0x401E, /* positive, 31 */
+ 0x401F, /* positive, 32 */
+ 0x403C, /* positive, 61 */
+ 0x403D, /* positive, 62 */
+ 0x403E, /* positive, 63 */
+ 0x403F, /* positive, 64 */
+ 0x407E, /* positive, 127 */
+ 0x407F, /* positive, 128 */
+ 0x4080, /* positive, 129 */
+ 0x43FE, /* positive, 1023 */
+ 0x43FF, /* positive, 1024 */
+ 0x4400, /* positive, 1025 */
+ 0x7FFD, /* positive, 16382 */
+ 0x7FFE, /* positive, 16383 */
+ 0x7FFF, /* positive, infinity or NaN */
+ 0x8000, /* negative, subnormal */
+ 0x8001, /* negative, -16382 */
+ 0x8002, /* negative, -16381 */
+ 0xBBFE, /* negative, -1025 */
+ 0xBBFF, /* negative, -1024 */
+ 0xBC00, /* negative, -1023 */
+ 0xBC01, /* negative, -1022 */
+ 0xBF7E, /* negative, -129 */
+ 0xBF7F, /* negative, -128 */
+ 0xBF80, /* negative, -127 */
+ 0xBF81, /* negative, -126 */
+ 0xBFBF, /* negative, -64 */
+ 0xBFFB, /* negative, -4 */
+ 0xBFFC, /* negative, -3 */
+ 0xBFFD, /* negative, -2 */
+ 0xBFFE, /* negative, -1 */
+ 0xBFFF, /* negative, 0 */
+ 0xC000, /* negative, 1 */
+ 0xC001, /* negative, 2 */
+ 0xC002, /* negative, 3 */
+ 0xC003, /* negative, 4 */
+ 0xC01C, /* negative, 29 */
+ 0xC01D, /* negative, 30 */
+ 0xC01E, /* negative, 31 */
+ 0xC01F, /* negative, 32 */
+ 0xC03C, /* negative, 61 */
+ 0xC03D, /* negative, 62 */
+ 0xC03E, /* negative, 63 */
+ 0xC03F, /* negative, 64 */
+ 0xC07E, /* negative, 127 */
+ 0xC07F, /* negative, 128 */
+ 0xC080, /* negative, 129 */
+ 0xC3FE, /* negative, 1023 */
+ 0xC3FF, /* negative, 1024 */
+ 0xC400, /* negative, 1025 */
+ 0xFFFD, /* negative, 16382 */
+ 0xFFFE, /* negative, 16383 */
+ 0xFFFF /* negative, infinity or NaN */
+};
+
+static const bits64 floatx80P1[ floatx80NumP1 ] = {
+ LIT64( 0x0000000000000000 ),
+ LIT64( 0x0000000000000001 ),
+ LIT64( 0x7FFFFFFFFFFFFFFF ),
+ LIT64( 0x7FFFFFFFFFFFFFFE )
+};
+
+static const bits64 floatx80P2[ floatx80NumP2 ] = {
+ LIT64( 0x0000000000000000 ),
+ LIT64( 0x0000000000000001 ),
+ LIT64( 0x0000000000000002 ),
+ LIT64( 0x0000000000000004 ),
+ LIT64( 0x0000000000000008 ),
+ LIT64( 0x0000000000000010 ),
+ LIT64( 0x0000000000000020 ),
+ LIT64( 0x0000000000000040 ),
+ LIT64( 0x0000000000000080 ),
+ LIT64( 0x0000000000000100 ),
+ LIT64( 0x0000000000000200 ),
+ LIT64( 0x0000000000000400 ),
+ LIT64( 0x0000000000000800 ),
+ LIT64( 0x0000000000001000 ),
+ LIT64( 0x0000000000002000 ),
+ LIT64( 0x0000000000004000 ),
+ LIT64( 0x0000000000008000 ),
+ LIT64( 0x0000000000010000 ),
+ LIT64( 0x0000000000020000 ),
+ LIT64( 0x0000000000040000 ),
+ LIT64( 0x0000000000080000 ),
+ LIT64( 0x0000000000100000 ),
+ LIT64( 0x0000000000200000 ),
+ LIT64( 0x0000000000400000 ),
+ LIT64( 0x0000000000800000 ),
+ LIT64( 0x0000000001000000 ),
+ LIT64( 0x0000000002000000 ),
+ LIT64( 0x0000000004000000 ),
+ LIT64( 0x0000000008000000 ),
+ LIT64( 0x0000000010000000 ),
+ LIT64( 0x0000000020000000 ),
+ LIT64( 0x0000000040000000 ),
+ LIT64( 0x0000000080000000 ),
+ LIT64( 0x0000000100000000 ),
+ LIT64( 0x0000000200000000 ),
+ LIT64( 0x0000000400000000 ),
+ LIT64( 0x0000000800000000 ),
+ LIT64( 0x0000001000000000 ),
+ LIT64( 0x0000002000000000 ),
+ LIT64( 0x0000004000000000 ),
+ LIT64( 0x0000008000000000 ),
+ LIT64( 0x0000010000000000 ),
+ LIT64( 0x0000020000000000 ),
+ LIT64( 0x0000040000000000 ),
+ LIT64( 0x0000080000000000 ),
+ LIT64( 0x0000100000000000 ),
+ LIT64( 0x0000200000000000 ),
+ LIT64( 0x0000400000000000 ),
+ LIT64( 0x0000800000000000 ),
+ LIT64( 0x0001000000000000 ),
+ LIT64( 0x0002000000000000 ),
+ LIT64( 0x0004000000000000 ),
+ LIT64( 0x0008000000000000 ),
+ LIT64( 0x0010000000000000 ),
+ LIT64( 0x0020000000000000 ),
+ LIT64( 0x0040000000000000 ),
+ LIT64( 0x0080000000000000 ),
+ LIT64( 0x0100000000000000 ),
+ LIT64( 0x0200000000000000 ),
+ LIT64( 0x0400000000000000 ),
+ LIT64( 0x0800000000000000 ),
+ LIT64( 0x1000000000000000 ),
+ LIT64( 0x2000000000000000 ),
+ LIT64( 0x4000000000000000 ),
+ LIT64( 0x6000000000000000 ),
+ LIT64( 0x7000000000000000 ),
+ LIT64( 0x7800000000000000 ),
+ LIT64( 0x7C00000000000000 ),
+ LIT64( 0x7E00000000000000 ),
+ LIT64( 0x7F00000000000000 ),
+ LIT64( 0x7F80000000000000 ),
+ LIT64( 0x7FC0000000000000 ),
+ LIT64( 0x7FE0000000000000 ),
+ LIT64( 0x7FF0000000000000 ),
+ LIT64( 0x7FF8000000000000 ),
+ LIT64( 0x7FFC000000000000 ),
+ LIT64( 0x7FFE000000000000 ),
+ LIT64( 0x7FFF000000000000 ),
+ LIT64( 0x7FFF800000000000 ),
+ LIT64( 0x7FFFC00000000000 ),
+ LIT64( 0x7FFFE00000000000 ),
+ LIT64( 0x7FFFF00000000000 ),
+ LIT64( 0x7FFFF80000000000 ),
+ LIT64( 0x7FFFFC0000000000 ),
+ LIT64( 0x7FFFFE0000000000 ),
+ LIT64( 0x7FFFFF0000000000 ),
+ LIT64( 0x7FFFFF8000000000 ),
+ LIT64( 0x7FFFFFC000000000 ),
+ LIT64( 0x7FFFFFE000000000 ),
+ LIT64( 0x7FFFFFF000000000 ),
+ LIT64( 0x7FFFFFF800000000 ),
+ LIT64( 0x7FFFFFFC00000000 ),
+ LIT64( 0x7FFFFFFE00000000 ),
+ LIT64( 0x7FFFFFFF00000000 ),
+ LIT64( 0x7FFFFFFF80000000 ),
+ LIT64( 0x7FFFFFFFC0000000 ),
+ LIT64( 0x7FFFFFFFE0000000 ),
+ LIT64( 0x7FFFFFFFF0000000 ),
+ LIT64( 0x7FFFFFFFF8000000 ),
+ LIT64( 0x7FFFFFFFFC000000 ),
+ LIT64( 0x7FFFFFFFFE000000 ),
+ LIT64( 0x7FFFFFFFFF000000 ),
+ LIT64( 0x7FFFFFFFFF800000 ),
+ LIT64( 0x7FFFFFFFFFC00000 ),
+ LIT64( 0x7FFFFFFFFFE00000 ),
+ LIT64( 0x7FFFFFFFFFF00000 ),
+ LIT64( 0x7FFFFFFFFFF80000 ),
+ LIT64( 0x7FFFFFFFFFFC0000 ),
+ LIT64( 0x7FFFFFFFFFFE0000 ),
+ LIT64( 0x7FFFFFFFFFFF0000 ),
+ LIT64( 0x7FFFFFFFFFFF8000 ),
+ LIT64( 0x7FFFFFFFFFFFC000 ),
+ LIT64( 0x7FFFFFFFFFFFE000 ),
+ LIT64( 0x7FFFFFFFFFFFF000 ),
+ LIT64( 0x7FFFFFFFFFFFF800 ),
+ LIT64( 0x7FFFFFFFFFFFFC00 ),
+ LIT64( 0x7FFFFFFFFFFFFE00 ),
+ LIT64( 0x7FFFFFFFFFFFFF00 ),
+ LIT64( 0x7FFFFFFFFFFFFF80 ),
+ LIT64( 0x7FFFFFFFFFFFFFC0 ),
+ LIT64( 0x7FFFFFFFFFFFFFE0 ),
+ LIT64( 0x7FFFFFFFFFFFFFF0 ),
+ LIT64( 0x7FFFFFFFFFFFFFF8 ),
+ LIT64( 0x7FFFFFFFFFFFFFFC ),
+ LIT64( 0x7FFFFFFFFFFFFFFE ),
+ LIT64( 0x7FFFFFFFFFFFFFFF ),
+ LIT64( 0x7FFFFFFFFFFFFFFD ),
+ LIT64( 0x7FFFFFFFFFFFFFFB ),
+ LIT64( 0x7FFFFFFFFFFFFFF7 ),
+ LIT64( 0x7FFFFFFFFFFFFFEF ),
+ LIT64( 0x7FFFFFFFFFFFFFDF ),
+ LIT64( 0x7FFFFFFFFFFFFFBF ),
+ LIT64( 0x7FFFFFFFFFFFFF7F ),
+ LIT64( 0x7FFFFFFFFFFFFEFF ),
+ LIT64( 0x7FFFFFFFFFFFFDFF ),
+ LIT64( 0x7FFFFFFFFFFFFBFF ),
+ LIT64( 0x7FFFFFFFFFFFF7FF ),
+ LIT64( 0x7FFFFFFFFFFFEFFF ),
+ LIT64( 0x7FFFFFFFFFFFDFFF ),
+ LIT64( 0x7FFFFFFFFFFFBFFF ),
+ LIT64( 0x7FFFFFFFFFFF7FFF ),
+ LIT64( 0x7FFFFFFFFFFEFFFF ),
+ LIT64( 0x7FFFFFFFFFFDFFFF ),
+ LIT64( 0x7FFFFFFFFFFBFFFF ),
+ LIT64( 0x7FFFFFFFFFF7FFFF ),
+ LIT64( 0x7FFFFFFFFFEFFFFF ),
+ LIT64( 0x7FFFFFFFFFDFFFFF ),
+ LIT64( 0x7FFFFFFFFFBFFFFF ),
+ LIT64( 0x7FFFFFFFFF7FFFFF ),
+ LIT64( 0x7FFFFFFFFEFFFFFF ),
+ LIT64( 0x7FFFFFFFFDFFFFFF ),
+ LIT64( 0x7FFFFFFFFBFFFFFF ),
+ LIT64( 0x7FFFFFFFF7FFFFFF ),
+ LIT64( 0x7FFFFFFFEFFFFFFF ),
+ LIT64( 0x7FFFFFFFDFFFFFFF ),
+ LIT64( 0x7FFFFFFFBFFFFFFF ),
+ LIT64( 0x7FFFFFFF7FFFFFFF ),
+ LIT64( 0x7FFFFFFEFFFFFFFF ),
+ LIT64( 0x7FFFFFFDFFFFFFFF ),
+ LIT64( 0x7FFFFFFBFFFFFFFF ),
+ LIT64( 0x7FFFFFF7FFFFFFFF ),
+ LIT64( 0x7FFFFFEFFFFFFFFF ),
+ LIT64( 0x7FFFFFDFFFFFFFFF ),
+ LIT64( 0x7FFFFFBFFFFFFFFF ),
+ LIT64( 0x7FFFFF7FFFFFFFFF ),
+ LIT64( 0x7FFFFEFFFFFFFFFF ),
+ LIT64( 0x7FFFFDFFFFFFFFFF ),
+ LIT64( 0x7FFFFBFFFFFFFFFF ),
+ LIT64( 0x7FFFF7FFFFFFFFFF ),
+ LIT64( 0x7FFFEFFFFFFFFFFF ),
+ LIT64( 0x7FFFDFFFFFFFFFFF ),
+ LIT64( 0x7FFFBFFFFFFFFFFF ),
+ LIT64( 0x7FFF7FFFFFFFFFFF ),
+ LIT64( 0x7FFEFFFFFFFFFFFF ),
+ LIT64( 0x7FFDFFFFFFFFFFFF ),
+ LIT64( 0x7FFBFFFFFFFFFFFF ),
+ LIT64( 0x7FF7FFFFFFFFFFFF ),
+ LIT64( 0x7FEFFFFFFFFFFFFF ),
+ LIT64( 0x7FDFFFFFFFFFFFFF ),
+ LIT64( 0x7FBFFFFFFFFFFFFF ),
+ LIT64( 0x7F7FFFFFFFFFFFFF ),
+ LIT64( 0x7EFFFFFFFFFFFFFF ),
+ LIT64( 0x7DFFFFFFFFFFFFFF ),
+ LIT64( 0x7BFFFFFFFFFFFFFF ),
+ LIT64( 0x77FFFFFFFFFFFFFF ),
+ LIT64( 0x6FFFFFFFFFFFFFFF ),
+ LIT64( 0x5FFFFFFFFFFFFFFF ),
+ LIT64( 0x3FFFFFFFFFFFFFFF ),
+ LIT64( 0x1FFFFFFFFFFFFFFF ),
+ LIT64( 0x0FFFFFFFFFFFFFFF ),
+ LIT64( 0x07FFFFFFFFFFFFFF ),
+ LIT64( 0x03FFFFFFFFFFFFFF ),
+ LIT64( 0x01FFFFFFFFFFFFFF ),
+ LIT64( 0x00FFFFFFFFFFFFFF ),
+ LIT64( 0x007FFFFFFFFFFFFF ),
+ LIT64( 0x003FFFFFFFFFFFFF ),
+ LIT64( 0x001FFFFFFFFFFFFF ),
+ LIT64( 0x000FFFFFFFFFFFFF ),
+ LIT64( 0x0007FFFFFFFFFFFF ),
+ LIT64( 0x0003FFFFFFFFFFFF ),
+ LIT64( 0x0001FFFFFFFFFFFF ),
+ LIT64( 0x0000FFFFFFFFFFFF ),
+ LIT64( 0x00007FFFFFFFFFFF ),
+ LIT64( 0x00003FFFFFFFFFFF ),
+ LIT64( 0x00001FFFFFFFFFFF ),
+ LIT64( 0x00000FFFFFFFFFFF ),
+ LIT64( 0x000007FFFFFFFFFF ),
+ LIT64( 0x000003FFFFFFFFFF ),
+ LIT64( 0x000001FFFFFFFFFF ),
+ LIT64( 0x000000FFFFFFFFFF ),
+ LIT64( 0x0000007FFFFFFFFF ),
+ LIT64( 0x0000003FFFFFFFFF ),
+ LIT64( 0x0000001FFFFFFFFF ),
+ LIT64( 0x0000000FFFFFFFFF ),
+ LIT64( 0x00000007FFFFFFFF ),
+ LIT64( 0x00000003FFFFFFFF ),
+ LIT64( 0x00000001FFFFFFFF ),
+ LIT64( 0x00000000FFFFFFFF ),
+ LIT64( 0x000000007FFFFFFF ),
+ LIT64( 0x000000003FFFFFFF ),
+ LIT64( 0x000000001FFFFFFF ),
+ LIT64( 0x000000000FFFFFFF ),
+ LIT64( 0x0000000007FFFFFF ),
+ LIT64( 0x0000000003FFFFFF ),
+ LIT64( 0x0000000001FFFFFF ),
+ LIT64( 0x0000000000FFFFFF ),
+ LIT64( 0x00000000007FFFFF ),
+ LIT64( 0x00000000003FFFFF ),
+ LIT64( 0x00000000001FFFFF ),
+ LIT64( 0x00000000000FFFFF ),
+ LIT64( 0x000000000007FFFF ),
+ LIT64( 0x000000000003FFFF ),
+ LIT64( 0x000000000001FFFF ),
+ LIT64( 0x000000000000FFFF ),
+ LIT64( 0x0000000000007FFF ),
+ LIT64( 0x0000000000003FFF ),
+ LIT64( 0x0000000000001FFF ),
+ LIT64( 0x0000000000000FFF ),
+ LIT64( 0x00000000000007FF ),
+ LIT64( 0x00000000000003FF ),
+ LIT64( 0x00000000000001FF ),
+ LIT64( 0x00000000000000FF ),
+ LIT64( 0x000000000000007F ),
+ LIT64( 0x000000000000003F ),
+ LIT64( 0x000000000000001F ),
+ LIT64( 0x000000000000000F ),
+ LIT64( 0x0000000000000007 ),
+ LIT64( 0x0000000000000003 )
+};
+
+static const uint32 floatx80NumQInP1 = floatx80NumQIn * floatx80NumP1;
+static const uint32 floatx80NumQOutP1 = floatx80NumQOut * floatx80NumP1;
+
+static floatx80 floatx80NextQInP1( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ floatx80 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = floatx80P1[ sigNum ];
+ z.high = floatx80QIn[ expNum ];
+ if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+ ++sigNum;
+ if ( floatx80NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( floatx80NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static floatx80 floatx80NextQOutP1( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ floatx80 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = floatx80P1[ sigNum ];
+ z.high = floatx80QOut[ expNum ];
+ if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+ ++sigNum;
+ if ( floatx80NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( floatx80NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static const uint32 floatx80NumQInP2 = floatx80NumQIn * floatx80NumP2;
+static const uint32 floatx80NumQOutP2 = floatx80NumQOut * floatx80NumP2;
+
+static floatx80 floatx80NextQInP2( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ floatx80 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = floatx80P2[ sigNum ];
+ z.high = floatx80QIn[ expNum ];
+ if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+ ++sigNum;
+ if ( floatx80NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( floatx80NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static floatx80 floatx80NextQOutP2( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ floatx80 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = floatx80P2[ sigNum ];
+ z.high = floatx80QOut[ expNum ];
+ if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+ ++sigNum;
+ if ( floatx80NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( floatx80NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static floatx80 floatx80RandomQOutP3( void )
+{
+ floatx80 z;
+
+ z.low =
+ ( floatx80P2[ randomUint8() % floatx80NumP2 ]
+ + floatx80P2[ randomUint8() % floatx80NumP2 ] )
+ & LIT64( 0x7FFFFFFFFFFFFFFF );
+ z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
+ if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+ return z;
+
+}
+
+static floatx80 floatx80RandomQOutPInf( void )
+{
+ floatx80 z;
+
+ z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
+ z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
+ if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+ return z;
+
+}
+
+enum {
+ floatx80NumQInfWeightMasks = 14
+};
+
+static const uint16 floatx80QInfWeightMasks[ floatx80NumQInfWeightMasks ] = {
+ 0x7FFF,
+ 0x7FFF,
+ 0x3FFF,
+ 0x1FFF,
+ 0x07FF,
+ 0x07FF,
+ 0x03FF,
+ 0x01FF,
+ 0x00FF,
+ 0x007F,
+ 0x003F,
+ 0x001F,
+ 0x000F,
+ 0x0007
+};
+
+static const uint16 floatx80QInfWeightOffsets[ floatx80NumQInfWeightMasks ] = {
+ 0x0000,
+ 0x0000,
+ 0x2000,
+ 0x3000,
+ 0x3800,
+ 0x3C00,
+ 0x3E00,
+ 0x3F00,
+ 0x3F80,
+ 0x3FC0,
+ 0x3FE0,
+ 0x3FF0,
+ 0x3FF8,
+ 0x3FFC
+};
+
+static floatx80 floatx80RandomQInfP3( void )
+{
+ int8 weightMaskNum;
+ floatx80 z;
+
+ z.low =
+ ( floatx80P2[ randomUint8() % floatx80NumP2 ]
+ + floatx80P2[ randomUint8() % floatx80NumP2 ] )
+ & LIT64( 0x7FFFFFFFFFFFFFFF );
+ weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
+ z.high =
+ ( randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ] )
+ + floatx80QInfWeightOffsets[ weightMaskNum ];
+ if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
+ z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
+ return z;
+
+}
+
+static floatx80 floatx80RandomQInfPInf( void )
+{
+ int8 weightMaskNum;
+ floatx80 z;
+
+ z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
+ weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
+ z.high =
+ ( randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ] )
+ + floatx80QInfWeightOffsets[ weightMaskNum ];
+ if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
+ z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
+ return z;
+
+}
+
+static floatx80 floatx80Random( void )
+{
+
+ switch ( randomUint8() & 7 ) {
+ case 0:
+ case 1:
+ case 2:
+ return floatx80RandomQOutP3();
+ case 3:
+ return floatx80RandomQOutPInf();
+ case 4:
+ case 5:
+ case 6:
+ return floatx80RandomQInfP3();
+ default:
+ return floatx80RandomQInfPInf();
+ }
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+enum {
+ float128NumQIn = 22,
+ float128NumQOut = 78,
+ float128NumP1 = 4,
+ float128NumP2 = 443
+};
+
+static const uint64 float128QIn[ float128NumQIn ] = {
+ LIT64( 0x0000000000000000 ), /* positive, subnormal */
+ LIT64( 0x0001000000000000 ), /* positive, -16382 */
+ LIT64( 0x3F8E000000000000 ), /* positive, -113 */
+ LIT64( 0x3FFD000000000000 ), /* positive, -2 */
+ LIT64( 0x3FFE000000000000 ), /* positive, -1 */
+ LIT64( 0x3FFF000000000000 ), /* positive, 0 */
+ LIT64( 0x4000000000000000 ), /* positive, 1 */
+ LIT64( 0x4001000000000000 ), /* positive, 2 */
+ LIT64( 0x4070000000000000 ), /* positive, 113 */
+ LIT64( 0x7FFE000000000000 ), /* positive, 16383 */
+ LIT64( 0x7FFF000000000000 ), /* positive, infinity or NaN */
+ LIT64( 0x8000000000000000 ), /* negative, subnormal */
+ LIT64( 0x8001000000000000 ), /* negative, -16382 */
+ LIT64( 0xBF8E000000000000 ), /* negative, -113 */
+ LIT64( 0xBFFD000000000000 ), /* negative, -2 */
+ LIT64( 0xBFFE000000000000 ), /* negative, -1 */
+ LIT64( 0xBFFF000000000000 ), /* negative, 0 */
+ LIT64( 0xC000000000000000 ), /* negative, 1 */
+ LIT64( 0xC001000000000000 ), /* negative, 2 */
+ LIT64( 0xC070000000000000 ), /* negative, 113 */
+ LIT64( 0xFFFE000000000000 ), /* negative, 16383 */
+ LIT64( 0xFFFF000000000000 ) /* negative, infinity or NaN */
+};
+
+static const uint64 float128QOut[ float128NumQOut ] = {
+ LIT64( 0x0000000000000000 ), /* positive, subnormal */
+ LIT64( 0x0001000000000000 ), /* positive, -16382 */
+ LIT64( 0x0002000000000000 ), /* positive, -16381 */
+ LIT64( 0x3BFE000000000000 ), /* positive, -1025 */
+ LIT64( 0x3BFF000000000000 ), /* positive, -1024 */
+ LIT64( 0x3C00000000000000 ), /* positive, -1023 */
+ LIT64( 0x3C01000000000000 ), /* positive, -1022 */
+ LIT64( 0x3F7E000000000000 ), /* positive, -129 */
+ LIT64( 0x3F7F000000000000 ), /* positive, -128 */
+ LIT64( 0x3F80000000000000 ), /* positive, -127 */
+ LIT64( 0x3F81000000000000 ), /* positive, -126 */
+ LIT64( 0x3F8E000000000000 ), /* positive, -113 */
+ LIT64( 0x3FFB000000000000 ), /* positive, -4 */
+ LIT64( 0x3FFC000000000000 ), /* positive, -3 */
+ LIT64( 0x3FFD000000000000 ), /* positive, -2 */
+ LIT64( 0x3FFE000000000000 ), /* positive, -1 */
+ LIT64( 0x3FFF000000000000 ), /* positive, 0 */
+ LIT64( 0x4000000000000000 ), /* positive, 1 */
+ LIT64( 0x4001000000000000 ), /* positive, 2 */
+ LIT64( 0x4002000000000000 ), /* positive, 3 */
+ LIT64( 0x4003000000000000 ), /* positive, 4 */
+ LIT64( 0x401C000000000000 ), /* positive, 29 */
+ LIT64( 0x401D000000000000 ), /* positive, 30 */
+ LIT64( 0x401E000000000000 ), /* positive, 31 */
+ LIT64( 0x401F000000000000 ), /* positive, 32 */
+ LIT64( 0x403C000000000000 ), /* positive, 61 */
+ LIT64( 0x403D000000000000 ), /* positive, 62 */
+ LIT64( 0x403E000000000000 ), /* positive, 63 */
+ LIT64( 0x403F000000000000 ), /* positive, 64 */
+ LIT64( 0x4070000000000000 ), /* positive, 113 */
+ LIT64( 0x407E000000000000 ), /* positive, 127 */
+ LIT64( 0x407F000000000000 ), /* positive, 128 */
+ LIT64( 0x4080000000000000 ), /* positive, 129 */
+ LIT64( 0x43FE000000000000 ), /* positive, 1023 */
+ LIT64( 0x43FF000000000000 ), /* positive, 1024 */
+ LIT64( 0x4400000000000000 ), /* positive, 1025 */
+ LIT64( 0x7FFD000000000000 ), /* positive, 16382 */
+ LIT64( 0x7FFE000000000000 ), /* positive, 16383 */
+ LIT64( 0x7FFF000000000000 ), /* positive, infinity or NaN */
+ LIT64( 0x8000000000000000 ), /* negative, subnormal */
+ LIT64( 0x8001000000000000 ), /* negative, -16382 */
+ LIT64( 0x8002000000000000 ), /* negative, -16381 */
+ LIT64( 0xBBFE000000000000 ), /* negative, -1025 */
+ LIT64( 0xBBFF000000000000 ), /* negative, -1024 */
+ LIT64( 0xBC00000000000000 ), /* negative, -1023 */
+ LIT64( 0xBC01000000000000 ), /* negative, -1022 */
+ LIT64( 0xBF7E000000000000 ), /* negative, -129 */
+ LIT64( 0xBF7F000000000000 ), /* negative, -128 */
+ LIT64( 0xBF80000000000000 ), /* negative, -127 */
+ LIT64( 0xBF81000000000000 ), /* negative, -126 */
+ LIT64( 0xBF8E000000000000 ), /* negative, -113 */
+ LIT64( 0xBFFB000000000000 ), /* negative, -4 */
+ LIT64( 0xBFFC000000000000 ), /* negative, -3 */
+ LIT64( 0xBFFD000000000000 ), /* negative, -2 */
+ LIT64( 0xBFFE000000000000 ), /* negative, -1 */
+ LIT64( 0xBFFF000000000000 ), /* negative, 0 */
+ LIT64( 0xC000000000000000 ), /* negative, 1 */
+ LIT64( 0xC001000000000000 ), /* negative, 2 */
+ LIT64( 0xC002000000000000 ), /* negative, 3 */
+ LIT64( 0xC003000000000000 ), /* negative, 4 */
+ LIT64( 0xC01C000000000000 ), /* negative, 29 */
+ LIT64( 0xC01D000000000000 ), /* negative, 30 */
+ LIT64( 0xC01E000000000000 ), /* negative, 31 */
+ LIT64( 0xC01F000000000000 ), /* negative, 32 */
+ LIT64( 0xC03C000000000000 ), /* negative, 61 */
+ LIT64( 0xC03D000000000000 ), /* negative, 62 */
+ LIT64( 0xC03E000000000000 ), /* negative, 63 */
+ LIT64( 0xC03F000000000000 ), /* negative, 64 */
+ LIT64( 0xC070000000000000 ), /* negative, 113 */
+ LIT64( 0xC07E000000000000 ), /* negative, 127 */
+ LIT64( 0xC07F000000000000 ), /* negative, 128 */
+ LIT64( 0xC080000000000000 ), /* negative, 129 */
+ LIT64( 0xC3FE000000000000 ), /* negative, 1023 */
+ LIT64( 0xC3FF000000000000 ), /* negative, 1024 */
+ LIT64( 0xC400000000000000 ), /* negative, 1025 */
+ LIT64( 0xFFFD000000000000 ), /* negative, 16382 */
+ LIT64( 0xFFFE000000000000 ), /* negative, 16383 */
+ LIT64( 0xFFFF000000000000 ) /* negative, infinity or NaN */
+};
+
+static const struct { bits64 high, low; } float128P1[ float128NumP1 ] = {
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) }
+};
+
+static const struct { bits64 high, low; } float128P2[ float128NumP2 ] = {
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000002 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000004 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000008 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000010 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000020 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000040 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000080 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000100 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000200 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000400 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000800 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000002000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000004000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000008000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000010000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000020000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000040000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000080000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000100000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000200000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000400000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000800000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000001000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000002000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000004000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000008000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000010000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000020000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000040000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000080000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000100000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000200000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000400000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000800000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000001000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000002000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000004000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000008000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000010000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000020000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000040000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000080000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000100000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000200000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000400000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000800000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0001000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0002000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0004000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0008000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0010000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0020000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0040000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0080000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0100000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0200000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0400000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0800000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x1000000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x2000000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x4000000000000000 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x8000000000000000 ) },
+ { LIT64( 0x0000000000000001 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000002 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000004 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000008 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000010 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000020 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000040 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000080 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000100 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000200 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000400 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000000800 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000001000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000002000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000004000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000008000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000010000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000020000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000040000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000080000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000100000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000200000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000400000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000000800000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000001000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000002000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000004000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000008000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000010000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000020000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000040000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000080000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000100000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000200000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000400000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000000800000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000001000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000002000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000004000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000008000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000010000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000020000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000040000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000080000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000100000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000200000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000400000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000800000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000C00000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000E00000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000F00000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000F80000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FC0000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FE0000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FF0000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FF8000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFC000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFE000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFF000000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFF800000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFC00000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFE00000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFF00000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFF80000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFC0000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFE0000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFF0000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFF8000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFC000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFE000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFF000000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFF800000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFC00000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFE00000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFF00000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFF80000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFC0000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFE0000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFF0000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFF8000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFC000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFE000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFF000 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFF800 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFC00 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFE00 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFF00 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFF80 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFC0 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFE0 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFF0 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFF8 ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFC ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFE ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x0000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x8000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xC000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xE000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF000000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF800000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFC00000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFE00000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF00000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF80000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFC0000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFE0000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF0000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF8000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFC000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFE000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF000000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF800000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFC00000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFE00000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF00000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF80000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFC0000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFE0000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF0000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF8000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFC000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFE000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF000000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF800000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFC00000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFE00000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF00000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF80000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFC0000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFE0000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF0000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF8000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFC000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFE000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF000000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF800000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFC00000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFE00000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF00000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF80000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFC0000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFE0000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF0000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF8000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFC000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFE000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF000 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF800 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFC00 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFE00 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF00 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF80 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFC0 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFE0 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF0 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF8 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFC ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFD ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFB ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF7 ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFEF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFDF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFBF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF7F ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFEFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFDFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFBFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF7FF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFEFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFDFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFBFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF7FFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFEFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFDFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFBFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF7FFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFEFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFDFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFBFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF7FFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFEFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFDFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFBFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF7FFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFEFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFDFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFBFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF7FFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFEFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFDFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFBFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF7FFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFEFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFDFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFBFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF7FFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFEFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFDFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFBFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF7FFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFEFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFDFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFBFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF7FFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFEFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFDFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFBFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF7FFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFEFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFDFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFBFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF7FFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFEFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFDFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFBFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF7FFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xEFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xDFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xBFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFD ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFFB ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFF7 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFEF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFDF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFFBF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFF7F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFEFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFDFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFFBFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFF7FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFEFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFDFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFFBFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFF7FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFEFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFDFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFFBFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFF7FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFEFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFDFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFFBFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFF7FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFEFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFDFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFFBFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFF7FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFEFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFDFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFFBFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFF7FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFEFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFDFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFFBFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFF7FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFEFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFDFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FFBFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FF7FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FEFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FDFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000FBFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000F7FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000EFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000DFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000BFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00007FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00003FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00001FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000007FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000003FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000001FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000007FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000003FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000001FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000007FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000003FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000001FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000007FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000003FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000001FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000007FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000003FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000001FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000007FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000003FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000001FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000000FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000007FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000003FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000001FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000000FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000007FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000003FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000001FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000000007FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000000003FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000000001FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x00000000000000FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000000007F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000000003F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000000001F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x000000000000000F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000007 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000003 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000001 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x3FFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x1FFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0FFFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x07FFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x03FFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x01FFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00FFFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x007FFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x003FFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x001FFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000FFFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0007FFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0003FFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0001FFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000FFFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00007FFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00003FFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00001FFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000FFFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000007FFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000003FFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000001FFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000FFFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000007FFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000003FFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000001FFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000FFFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000007FFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000003FFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000001FFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000FFFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000007FFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000003FFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000001FFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000FFFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000007FFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000003FFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000001FFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000FFFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000007FFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000003FFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000001FFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000FFFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000007FFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000003FFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000001FFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000FFFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000007FFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000003FFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001FFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000FFF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000007FF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000003FF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000001FF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000000FF ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000007F ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000003F ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000001F ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000000F ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000007 ) },
+ { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000003 ) }
+};
+
+static const uint32 float128NumQInP1 = float128NumQIn * float128NumP1;
+static const uint32 float128NumQOutP1 = float128NumQOut * float128NumP1;
+
+static float128 float128NextQInP1( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ float128 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = float128P1[ sigNum ].low;
+ z.high = float128QIn[ expNum ] | float128P1[ sigNum ].high;
+ ++sigNum;
+ if ( float128NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float128NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float128 float128NextQOutP1( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ float128 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = float128P1[ sigNum ].low;
+ z.high = float128QOut[ expNum ] | float128P1[ sigNum ].high;
+ ++sigNum;
+ if ( float128NumP1 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float128NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static const uint32 float128NumQInP2 = float128NumQIn * float128NumP2;
+static const uint32 float128NumQOutP2 = float128NumQOut * float128NumP2;
+
+static float128 float128NextQInP2( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ float128 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = float128P2[ sigNum ].low;
+ z.high = float128QIn[ expNum ] | float128P2[ sigNum ].high;
+ ++sigNum;
+ if ( float128NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float128NumQIn <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float128 float128NextQOutP2( sequenceT *sequencePtr )
+{
+ int16 expNum, sigNum;
+ float128 z;
+
+ sigNum = sequencePtr->term1Num;
+ expNum = sequencePtr->expNum;
+ z.low = float128P2[ sigNum ].low;
+ z.high = float128QOut[ expNum ] | float128P2[ sigNum ].high;
+ ++sigNum;
+ if ( float128NumP2 <= sigNum ) {
+ sigNum = 0;
+ ++expNum;
+ if ( float128NumQOut <= expNum ) {
+ expNum = 0;
+ sequencePtr->done = TRUE;
+ }
+ sequencePtr->expNum = expNum;
+ }
+ sequencePtr->term1Num = sigNum;
+ return z;
+
+}
+
+static float128 float128RandomQOutP3( void )
+{
+ int16 sigNum1, sigNum2;
+ uint64 sig1Low, sig2Low;
+ float128 z;
+
+ sigNum1 = randomUint8() % float128NumP2;
+ sigNum2 = randomUint8() % float128NumP2;
+ sig1Low = float128P2[ sigNum1 ].low;
+ sig2Low = float128P2[ sigNum2 ].low;
+ z.low = sig1Low + sig2Low;
+ z.high =
+ float128QOut[ randomUint8() % float128NumQOut ]
+ | ( ( float128P2[ sigNum1 ].high
+ + float128P2[ sigNum2 ].high
+ + ( z.low < sig1Low )
+ )
+ & LIT64( 0x0000FFFFFFFFFFFF )
+ );
+ return z;
+
+}
+
+static float128 float128RandomQOutPInf( void )
+{
+ float128 z;
+
+ z.low = randomUint64();
+ z.high =
+ float128QOut[ randomUint8() % float128NumQOut ]
+ | ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
+ return z;
+
+}
+
+enum {
+ float128NumQInfWeightMasks = 14
+};
+
+static const uint64 float128QInfWeightMasks[ float128NumQInfWeightMasks ] = {
+ LIT64( 0x7FFF000000000000 ),
+ LIT64( 0x7FFF000000000000 ),
+ LIT64( 0x3FFF000000000000 ),
+ LIT64( 0x1FFF000000000000 ),
+ LIT64( 0x07FF000000000000 ),
+ LIT64( 0x07FF000000000000 ),
+ LIT64( 0x03FF000000000000 ),
+ LIT64( 0x01FF000000000000 ),
+ LIT64( 0x00FF000000000000 ),
+ LIT64( 0x007F000000000000 ),
+ LIT64( 0x003F000000000000 ),
+ LIT64( 0x001F000000000000 ),
+ LIT64( 0x000F000000000000 ),
+ LIT64( 0x0007000000000000 )
+};
+
+static const uint64 float128QInfWeightOffsets[ float128NumQInfWeightMasks ] = {
+ LIT64( 0x0000000000000000 ),
+ LIT64( 0x0000000000000000 ),
+ LIT64( 0x2000000000000000 ),
+ LIT64( 0x3000000000000000 ),
+ LIT64( 0x3800000000000000 ),
+ LIT64( 0x3C00000000000000 ),
+ LIT64( 0x3E00000000000000 ),
+ LIT64( 0x3F00000000000000 ),
+ LIT64( 0x3F80000000000000 ),
+ LIT64( 0x3FC0000000000000 ),
+ LIT64( 0x3FE0000000000000 ),
+ LIT64( 0x3FF0000000000000 ),
+ LIT64( 0x3FF8000000000000 ),
+ LIT64( 0x3FFC000000000000 )
+};
+
+static float128 float128RandomQInfP3( void )
+{
+ int16 sigNum1, sigNum2;
+ uint64 sig1Low, sig2Low;
+ int8 weightMaskNum;
+ float128 z;
+
+ sigNum1 = randomUint8() % float128NumP2;
+ sigNum2 = randomUint8() % float128NumP2;
+ sig1Low = float128P2[ sigNum1 ].low;
+ sig2Low = float128P2[ sigNum2 ].low;
+ z.low = sig1Low + sig2Low;
+ weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
+ z.high =
+ ( ( (uint64) ( randomUint8() & 1 ) )<<63 )
+ | ( ( ( ( (uint64) randomUint16() )<<48 )
+ & float128QInfWeightMasks[ weightMaskNum ] )
+ + float128QInfWeightOffsets[ weightMaskNum ]
+ )
+ | ( ( float128P2[ sigNum1 ].high
+ + float128P2[ sigNum2 ].high
+ + ( z.low < sig1Low )
+ )
+ & LIT64( 0x0000FFFFFFFFFFFF )
+ );
+ return z;
+
+}
+
+static float128 float128RandomQInfPInf( void )
+{
+ int8 weightMaskNum;
+ float128 z;
+
+ weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
+ z.low = randomUint64();
+ z.high =
+ ( ( (uint64) ( randomUint8() & 1 ) )<<63 )
+ | ( ( ( ( (uint64) randomUint16() )<<48 )
+ & float128QInfWeightMasks[ weightMaskNum ] )
+ + float128QInfWeightOffsets[ weightMaskNum ]
+ )
+ | ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
+ return z;
+
+}
+
+static float128 float128Random( void )
+{
+
+ switch ( randomUint8() & 7 ) {
+ case 0:
+ case 1:
+ case 2:
+ return float128RandomQOutP3();
+ case 3:
+ return float128RandomQOutPInf();
+ case 4:
+ case 5:
+ case 6:
+ return float128RandomQInfP3();
+ default:
+ return float128RandomQInfPInf();
+ }
+
+}
+
+#endif
+
+static int8 level = 0;
+
+void testCases_setLevel( int8 levelIn )
+{
+
+ if ( ( levelIn < 1 ) || ( 2 < levelIn ) ) {
+ fail( "Invalid testing level: %d", levelIn );
+ }
+ level = levelIn;
+
+}
+
+static int8 sequenceType;
+static sequenceT sequenceA, sequenceB;
+static int8 subcase;
+
+uint32 testCases_total;
+flag testCases_done;
+
+static float32 current_a_float32;
+static float32 current_b_float32;
+static float64 current_a_float64;
+static float64 current_b_float64;
+#ifdef FLOATX80
+static floatx80 current_a_floatx80;
+static floatx80 current_b_floatx80;
+#endif
+#ifdef FLOAT128
+static float128 current_a_float128;
+static float128 current_b_float128;
+#endif
+
+void testCases_initSequence( int8 sequenceTypeIn )
+{
+
+ sequenceType = sequenceTypeIn;
+ sequenceA.term2Num = 0;
+ sequenceA.term1Num = 0;
+ sequenceA.expNum = 0;
+ sequenceA.done = FALSE;
+ sequenceB.term2Num = 0;
+ sequenceB.term1Num = 0;
+ sequenceB.expNum = 0;
+ sequenceB.done = FALSE;
+ subcase = 0;
+ switch ( level ) {
+ case 1:
+ switch ( sequenceTypeIn ) {
+ case testCases_sequence_a_int32:
+ testCases_total = 3 * int32NumP1;
+ break;
+#ifdef BITS64
+ case testCases_sequence_a_int64:
+ testCases_total = 3 * int64NumP1;
+ break;
+#endif
+ case testCases_sequence_a_float32:
+ testCases_total = 3 * float32NumQOutP1;
+ break;
+ case testCases_sequence_ab_float32:
+ testCases_total = 6 * float32NumQInP1 * float32NumQInP1;
+ current_a_float32 = float32NextQInP1( &sequenceA );
+ break;
+ case testCases_sequence_a_float64:
+ testCases_total = 3 * float64NumQOutP1;
+ break;
+ case testCases_sequence_ab_float64:
+ testCases_total = 6 * float64NumQInP1 * float64NumQInP1;
+ current_a_float64 = float64NextQInP1( &sequenceA );
+ break;
+#ifdef FLOATX80
+ case testCases_sequence_a_floatx80:
+ testCases_total = 3 * floatx80NumQOutP1;
+ break;
+ case testCases_sequence_ab_floatx80:
+ testCases_total = 6 * floatx80NumQInP1 * floatx80NumQInP1;
+ current_a_floatx80 = floatx80NextQInP1( &sequenceA );
+ break;
+#endif
+#ifdef FLOAT128
+ case testCases_sequence_a_float128:
+ testCases_total = 3 * float128NumQOutP1;
+ break;
+ case testCases_sequence_ab_float128:
+ testCases_total = 6 * float128NumQInP1 * float128NumQInP1;
+ current_a_float128 = float128NextQInP1( &sequenceA );
+ break;
+#endif
+ }
+ break;
+ case 2:
+ switch ( sequenceTypeIn ) {
+ case testCases_sequence_a_int32:
+ testCases_total = 2 * int32NumP2;
+ break;
+#ifdef BITS64
+ case testCases_sequence_a_int64:
+ testCases_total = 2 * int64NumP2;
+ break;
+#endif
+ case testCases_sequence_a_float32:
+ testCases_total = 2 * float32NumQOutP2;
+ break;
+ case testCases_sequence_ab_float32:
+ testCases_total = 2 * float32NumQInP2 * float32NumQInP2;
+ current_a_float32 = float32NextQInP2( &sequenceA );
+ break;
+ case testCases_sequence_a_float64:
+ testCases_total = 2 * float64NumQOutP2;
+ break;
+ case testCases_sequence_ab_float64:
+ testCases_total = 2 * float64NumQInP2 * float64NumQInP2;
+ current_a_float64 = float64NextQInP2( &sequenceA );
+ break;
+#ifdef FLOATX80
+ case testCases_sequence_a_floatx80:
+ testCases_total = 2 * floatx80NumQOutP2;
+ break;
+ case testCases_sequence_ab_floatx80:
+ testCases_total = 2 * floatx80NumQInP2 * floatx80NumQInP2;
+ current_a_floatx80 = floatx80NextQInP2( &sequenceA );
+ break;
+#endif
+#ifdef FLOAT128
+ case testCases_sequence_a_float128:
+ testCases_total = 2 * float128NumQOutP2;
+ break;
+ case testCases_sequence_ab_float128:
+ testCases_total = 2 * float128NumQInP2 * float128NumQInP2;
+ current_a_float128 = float128NextQInP2( &sequenceA );
+ break;
+#endif
+ }
+ break;
+ }
+ testCases_done = FALSE;
+
+}
+
+int32 testCases_a_int32;
+#ifdef BITS64
+int64 testCases_a_int64;
+#endif
+float32 testCases_a_float32;
+float32 testCases_b_float32;
+float64 testCases_a_float64;
+float64 testCases_b_float64;
+#ifdef FLOATX80
+floatx80 testCases_a_floatx80;
+floatx80 testCases_b_floatx80;
+#endif
+#ifdef FLOAT128
+float128 testCases_a_float128;
+float128 testCases_b_float128;
+#endif
+
+void testCases_next( void )
+{
+
+ switch ( level ) {
+ case 1:
+ switch ( sequenceType ) {
+ case testCases_sequence_a_int32:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_int32 = int32RandomP3();
+ break;
+ case 1:
+ testCases_a_int32 = int32RandomPInf();
+ break;
+ case 2:
+ testCases_a_int32 = int32NextP1( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#ifdef BITS64
+ case testCases_sequence_a_int64:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_int64 = int64RandomP3();
+ break;
+ case 1:
+ testCases_a_int64 = int64RandomPInf();
+ break;
+ case 2:
+ testCases_a_int64 = int64NextP1( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#endif
+ case testCases_sequence_a_float32:
+ switch ( subcase ) {
+ case 0:
+ case 1:
+ testCases_a_float32 = float32Random();
+ break;
+ case 2:
+ testCases_a_float32 = float32NextQOutP1( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_float32:
+ switch ( subcase ) {
+ case 0:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_float32 = float32NextQInP1( &sequenceA );
+ }
+ current_b_float32 = float32NextQInP1( &sequenceB );
+ case 2:
+ case 4:
+ testCases_a_float32 = float32Random();
+ testCases_b_float32 = float32Random();
+ break;
+ case 1:
+ testCases_a_float32 = current_a_float32;
+ testCases_b_float32 = float32Random();
+ break;
+ case 3:
+ testCases_a_float32 = float32Random();
+ testCases_b_float32 = current_b_float32;
+ break;
+ case 5:
+ testCases_a_float32 = current_a_float32;
+ testCases_b_float32 = current_b_float32;
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_a_float64:
+ switch ( subcase ) {
+ case 0:
+ case 1:
+ testCases_a_float64 = float64Random();
+ break;
+ case 2:
+ testCases_a_float64 = float64NextQOutP1( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_float64:
+ switch ( subcase ) {
+ case 0:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_float64 = float64NextQInP1( &sequenceA );
+ }
+ current_b_float64 = float64NextQInP1( &sequenceB );
+ case 2:
+ case 4:
+ testCases_a_float64 = float64Random();
+ testCases_b_float64 = float64Random();
+ break;
+ case 1:
+ testCases_a_float64 = current_a_float64;
+ testCases_b_float64 = float64Random();
+ break;
+ case 3:
+ testCases_a_float64 = float64Random();
+ testCases_b_float64 = current_b_float64;
+ break;
+ case 5:
+ testCases_a_float64 = current_a_float64;
+ testCases_b_float64 = current_b_float64;
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#ifdef FLOATX80
+ case testCases_sequence_a_floatx80:
+ switch ( subcase ) {
+ case 0:
+ case 1:
+ testCases_a_floatx80 = floatx80Random();
+ break;
+ case 2:
+ testCases_a_floatx80 = floatx80NextQOutP1( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_floatx80:
+ switch ( subcase ) {
+ case 0:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_floatx80 = floatx80NextQInP1( &sequenceA );
+ }
+ current_b_floatx80 = floatx80NextQInP1( &sequenceB );
+ case 2:
+ case 4:
+ testCases_a_floatx80 = floatx80Random();
+ testCases_b_floatx80 = floatx80Random();
+ break;
+ case 1:
+ testCases_a_floatx80 = current_a_floatx80;
+ testCases_b_floatx80 = floatx80Random();
+ break;
+ case 3:
+ testCases_a_floatx80 = floatx80Random();
+ testCases_b_floatx80 = current_b_floatx80;
+ break;
+ case 5:
+ testCases_a_floatx80 = current_a_floatx80;
+ testCases_b_floatx80 = current_b_floatx80;
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#endif
+#ifdef FLOAT128
+ case testCases_sequence_a_float128:
+ switch ( subcase ) {
+ case 0:
+ case 1:
+ testCases_a_float128 = float128Random();
+ break;
+ case 2:
+ testCases_a_float128 = float128NextQOutP1( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_float128:
+ switch ( subcase ) {
+ case 0:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_float128 = float128NextQInP1( &sequenceA );
+ }
+ current_b_float128 = float128NextQInP1( &sequenceB );
+ case 2:
+ case 4:
+ testCases_a_float128 = float128Random();
+ testCases_b_float128 = float128Random();
+ break;
+ case 1:
+ testCases_a_float128 = current_a_float128;
+ testCases_b_float128 = float128Random();
+ break;
+ case 3:
+ testCases_a_float128 = float128Random();
+ testCases_b_float128 = current_b_float128;
+ break;
+ case 5:
+ testCases_a_float128 = current_a_float128;
+ testCases_b_float128 = current_b_float128;
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#endif
+ }
+ break;
+ case 2:
+ switch ( sequenceType ) {
+ case testCases_sequence_a_int32:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_int32 = int32RandomP3();
+ break;
+ case 2:
+ testCases_a_int32 = int32RandomPInf();
+ break;
+ case 3:
+ subcase = -1;
+ case 1:
+ testCases_a_int32 = int32NextP2( &sequenceA );
+ testCases_done = sequenceA.done;
+ break;
+ }
+ ++subcase;
+ break;
+#ifdef BITS64
+ case testCases_sequence_a_int64:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_int64 = int64RandomP3();
+ break;
+ case 2:
+ testCases_a_int64 = int64RandomPInf();
+ break;
+ case 3:
+ subcase = -1;
+ case 1:
+ testCases_a_int64 = int64NextP2( &sequenceA );
+ testCases_done = sequenceA.done;
+ break;
+ }
+ ++subcase;
+ break;
+#endif
+ case testCases_sequence_a_float32:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_float32 = float32Random();
+ break;
+ case 1:
+ testCases_a_float32 = float32NextQOutP2( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_float32:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_float32 = float32Random();
+ testCases_b_float32 = float32Random();
+ break;
+ case 1:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_float32 = float32NextQInP2( &sequenceA );
+ }
+ testCases_a_float32 = current_a_float32;
+ testCases_b_float32 = float32NextQInP2( &sequenceB );
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_a_float64:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_float64 = float64Random();
+ break;
+ case 1:
+ testCases_a_float64 = float64NextQOutP2( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_float64:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_float64 = float64Random();
+ testCases_b_float64 = float64Random();
+ break;
+ case 1:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_float64 = float64NextQInP2( &sequenceA );
+ }
+ testCases_a_float64 = current_a_float64;
+ testCases_b_float64 = float64NextQInP2( &sequenceB );
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#ifdef FLOATX80
+ case testCases_sequence_a_floatx80:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_floatx80 = floatx80Random();
+ break;
+ case 1:
+ testCases_a_floatx80 = floatx80NextQOutP2( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_floatx80:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_floatx80 = floatx80Random();
+ testCases_b_floatx80 = floatx80Random();
+ break;
+ case 1:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_floatx80 = floatx80NextQInP2( &sequenceA );
+ }
+ testCases_a_floatx80 = current_a_floatx80;
+ testCases_b_floatx80 = floatx80NextQInP2( &sequenceB );
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#endif
+#ifdef FLOAT128
+ case testCases_sequence_a_float128:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_float128 = float128Random();
+ break;
+ case 1:
+ testCases_a_float128 = float128NextQOutP2( &sequenceA );
+ testCases_done = sequenceA.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+ case testCases_sequence_ab_float128:
+ switch ( subcase ) {
+ case 0:
+ testCases_a_float128 = float128Random();
+ testCases_b_float128 = float128Random();
+ break;
+ case 1:
+ if ( sequenceB.done ) {
+ sequenceB.done = FALSE;
+ current_a_float128 = float128NextQInP2( &sequenceA );
+ }
+ testCases_a_float128 = current_a_float128;
+ testCases_b_float128 = float128NextQInP2( &sequenceB );
+ testCases_done = sequenceA.done & sequenceB.done;
+ subcase = -1;
+ break;
+ }
+ ++subcase;
+ break;
+#endif
+ }
+ break;
+ }
+
+}
+
diff --git a/tools/test/testfloat/testCases.h b/tools/test/testfloat/testCases.h
new file mode 100644
index 0000000..ed6ea2b
--- /dev/null
+++ b/tools/test/testfloat/testCases.h
@@ -0,0 +1,69 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+void testCases_setLevel( int8 );
+
+void testCases_initSequence( int8 );
+enum {
+ testCases_sequence_a_int32,
+#ifdef BITS64
+ testCases_sequence_a_int64,
+#endif
+ testCases_sequence_a_float32,
+ testCases_sequence_ab_float32,
+ testCases_sequence_a_float64,
+ testCases_sequence_ab_float64,
+#ifdef FLOATX80
+ testCases_sequence_a_floatx80,
+ testCases_sequence_ab_floatx80,
+#endif
+#ifdef FLOAT128
+ testCases_sequence_a_float128,
+ testCases_sequence_ab_float128,
+#endif
+};
+
+extern uint32 testCases_total;
+extern flag testCases_done;
+
+void testCases_next( void );
+
+extern int32 testCases_a_int32;
+#ifdef BITS64
+extern int64 testCases_a_int64;
+#endif
+extern float32 testCases_a_float32;
+extern float32 testCases_b_float32;
+extern float64 testCases_a_float64;
+extern float64 testCases_b_float64;
+#ifdef FLOATX80
+extern floatx80 testCases_a_floatx80;
+extern floatx80 testCases_b_floatx80;
+#endif
+#ifdef FLOAT128
+extern float128 testCases_a_float128;
+extern float128 testCases_b_float128;
+#endif
+
diff --git a/tools/test/testfloat/testFunction.c b/tools/test/testfloat/testFunction.c
new file mode 100644
index 0000000..687563b
--- /dev/null
+++ b/tools/test/testfloat/testFunction.c
@@ -0,0 +1,1149 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+#include "testCases.h"
+#include "testLoops.h"
+#include "systmodes.h"
+#include "systflags.h"
+#include "systfloat.h"
+#include "testFunction.h"
+
+const functionT functions[ NUM_FUNCTIONS ] = {
+ { 0, 0, 0, 0 },
+ { "int32_to_float32", 1, FALSE, TRUE },
+ { "int32_to_float64", 1, FALSE, FALSE },
+ { "int32_to_floatx80", 1, FALSE, FALSE },
+ { "int32_to_float128", 1, FALSE, FALSE },
+ { "int64_to_float32", 1, FALSE, TRUE },
+ { "int64_to_float64", 1, FALSE, TRUE },
+ { "int64_to_floatx80", 1, FALSE, FALSE },
+ { "int64_to_float128", 1, FALSE, FALSE },
+ { "float32_to_int32", 1, FALSE, TRUE },
+ { "float32_to_int32_round_to_zero", 1, FALSE, FALSE },
+ { "float32_to_int64", 1, FALSE, TRUE },
+ { "float32_to_int64_round_to_zero", 1, FALSE, FALSE },
+ { "float32_to_float64", 1, FALSE, FALSE },
+ { "float32_to_floatx80", 1, FALSE, FALSE },
+ { "float32_to_float128", 1, FALSE, FALSE },
+ { "float32_round_to_int", 1, FALSE, TRUE },
+ { "float32_add", 2, FALSE, TRUE },
+ { "float32_sub", 2, FALSE, TRUE },
+ { "float32_mul", 2, FALSE, TRUE },
+ { "float32_div", 2, FALSE, TRUE },
+ { "float32_rem", 2, FALSE, FALSE },
+ { "float32_sqrt", 1, FALSE, TRUE },
+ { "float32_eq", 2, FALSE, FALSE },
+ { "float32_le", 2, FALSE, FALSE },
+ { "float32_lt", 2, FALSE, FALSE },
+ { "float32_eq_signaling", 2, FALSE, FALSE },
+ { "float32_le_quiet", 2, FALSE, FALSE },
+ { "float32_lt_quiet", 2, FALSE, FALSE },
+ { "float64_to_int32", 1, FALSE, TRUE },
+ { "float64_to_int32_round_to_zero", 1, FALSE, FALSE },
+ { "float64_to_int64", 1, FALSE, TRUE },
+ { "float64_to_int64_round_to_zero", 1, FALSE, FALSE },
+ { "float64_to_float32", 1, FALSE, TRUE },
+ { "float64_to_floatx80", 1, FALSE, FALSE },
+ { "float64_to_float128", 1, FALSE, FALSE },
+ { "float64_round_to_int", 1, FALSE, TRUE },
+ { "float64_add", 2, FALSE, TRUE },
+ { "float64_sub", 2, FALSE, TRUE },
+ { "float64_mul", 2, FALSE, TRUE },
+ { "float64_div", 2, FALSE, TRUE },
+ { "float64_rem", 2, FALSE, FALSE },
+ { "float64_sqrt", 1, FALSE, TRUE },
+ { "float64_eq", 2, FALSE, FALSE },
+ { "float64_le", 2, FALSE, FALSE },
+ { "float64_lt", 2, FALSE, FALSE },
+ { "float64_eq_signaling", 2, FALSE, FALSE },
+ { "float64_le_quiet", 2, FALSE, FALSE },
+ { "float64_lt_quiet", 2, FALSE, FALSE },
+ { "floatx80_to_int32", 1, FALSE, TRUE },
+ { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE },
+ { "floatx80_to_int64", 1, FALSE, TRUE },
+ { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE },
+ { "floatx80_to_float32", 1, FALSE, TRUE },
+ { "floatx80_to_float64", 1, FALSE, TRUE },
+ { "floatx80_to_float128", 1, FALSE, FALSE },
+ { "floatx80_round_to_int", 1, FALSE, TRUE },
+ { "floatx80_add", 2, TRUE, TRUE },
+ { "floatx80_sub", 2, TRUE, TRUE },
+ { "floatx80_mul", 2, TRUE, TRUE },
+ { "floatx80_div", 2, TRUE, TRUE },
+ { "floatx80_rem", 2, FALSE, FALSE },
+ { "floatx80_sqrt", 1, TRUE, TRUE },
+ { "floatx80_eq", 2, FALSE, FALSE },
+ { "floatx80_le", 2, FALSE, FALSE },
+ { "floatx80_lt", 2, FALSE, FALSE },
+ { "floatx80_eq_signaling", 2, FALSE, FALSE },
+ { "floatx80_le_quiet", 2, FALSE, FALSE },
+ { "floatx80_lt_quiet", 2, FALSE, FALSE },
+ { "float128_to_int32", 1, FALSE, TRUE },
+ { "float128_to_int32_round_to_zero", 1, FALSE, FALSE },
+ { "float128_to_int64", 1, FALSE, TRUE },
+ { "float128_to_int64_round_to_zero", 1, FALSE, FALSE },
+ { "float128_to_float32", 1, FALSE, TRUE },
+ { "float128_to_float64", 1, FALSE, TRUE },
+ { "float128_to_floatx80", 1, FALSE, TRUE },
+ { "float128_round_to_int", 1, FALSE, TRUE },
+ { "float128_add", 2, FALSE, TRUE },
+ { "float128_sub", 2, FALSE, TRUE },
+ { "float128_mul", 2, FALSE, TRUE },
+ { "float128_div", 2, FALSE, TRUE },
+ { "float128_rem", 2, FALSE, FALSE },
+ { "float128_sqrt", 1, FALSE, TRUE },
+ { "float128_eq", 2, FALSE, FALSE },
+ { "float128_le", 2, FALSE, FALSE },
+ { "float128_lt", 2, FALSE, FALSE },
+ { "float128_eq_signaling", 2, FALSE, FALSE },
+ { "float128_le_quiet", 2, FALSE, FALSE },
+ { "float128_lt_quiet", 2, FALSE, FALSE },
+};
+
+const flag functionExists[ NUM_FUNCTIONS ] = {
+ 0,
+#ifdef SYST_INT32_TO_FLOAT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT32_TO_FLOAT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT32_TO_FLOATX80
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT32_TO_FLOAT128
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT64_TO_FLOAT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT64_TO_FLOAT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT64_TO_FLOATX80
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_INT64_TO_FLOAT128
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_FLOATX80
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT128
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_ROUND_TO_INT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_ADD
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_SUB
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_MUL
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_DIV
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_REM
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_SQRT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_EQ
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_LE
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_LT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_EQ_SIGNALING
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_LE_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT32_LT_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_FLOATX80
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT128
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_ROUND_TO_INT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_ADD
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_SUB
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_MUL
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_DIV
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_REM
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_SQRT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_EQ
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_LE
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_LT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_EQ_SIGNALING
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_LE_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT64_LT_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT128
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_ROUND_TO_INT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_ADD
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_SUB
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_MUL
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_DIV
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_REM
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_SQRT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_EQ
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_LE
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_LT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_EQ_SIGNALING
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_LE_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOATX80_LT_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT32
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT64
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_TO_FLOATX80
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_ROUND_TO_INT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_ADD
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_SUB
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_MUL
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_DIV
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_REM
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_SQRT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_EQ
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_LE
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_LT
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_EQ_SIGNALING
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_LE_QUIET
+ 1,
+#else
+ 0,
+#endif
+#ifdef SYST_FLOAT128_LT_QUIET
+ 1,
+#else
+ 0,
+#endif
+};
+
+static void
+ testFunctionVariety(
+ uint8 functionCode, int8 roundingPrecision, int8 roundingMode )
+{
+ uint8 roundingCode;
+
+ functionName = functions[ functionCode ].name;
+#ifdef FLOATX80
+ if ( roundingPrecision == 32 ) {
+ roundingPrecisionName = "32";
+ }
+ else if ( roundingPrecision == 64 ) {
+ roundingPrecisionName = "64";
+ }
+ else if ( roundingPrecision == 80 ) {
+ roundingPrecisionName = "80";
+ }
+ else {
+ roundingPrecision = 80;
+ roundingPrecisionName = 0;
+ }
+ floatx80_rounding_precision = roundingPrecision;
+ syst_float_set_rounding_precision( roundingPrecision );
+#endif
+ switch ( roundingMode ) {
+ case 0:
+ roundingModeName = 0;
+ roundingCode = float_round_nearest_even;
+ break;
+ case ROUND_NEAREST_EVEN:
+ roundingModeName = "nearest_even";
+ roundingCode = float_round_nearest_even;
+ break;
+ case ROUND_TO_ZERO:
+ roundingModeName = "to_zero";
+ roundingCode = float_round_to_zero;
+ break;
+ case ROUND_DOWN:
+ roundingModeName = "down";
+ roundingCode = float_round_down;
+ break;
+ case ROUND_UP:
+ roundingModeName = "up";
+ roundingCode = float_round_up;
+ break;
+ }
+ float_rounding_mode = roundingCode;
+ syst_float_set_rounding_mode( roundingCode );
+ fputs( "Testing ", stderr );
+ writeFunctionName( stderr );
+ fputs( ".\n", stderr );
+ switch ( functionCode ) {
+#ifdef SYST_INT32_TO_FLOAT32
+ case INT32_TO_FLOAT32:
+ test_a_int32_z_float32( int32_to_float32, syst_int32_to_float32 );
+ break;
+#endif
+#ifdef SYST_INT32_TO_FLOAT64
+ case INT32_TO_FLOAT64:
+ test_a_int32_z_float64( int32_to_float64, syst_int32_to_float64 );
+ break;
+#endif
+#ifdef SYST_INT32_TO_FLOATX80
+ case INT32_TO_FLOATX80:
+ test_a_int32_z_floatx80( int32_to_floatx80, syst_int32_to_floatx80 );
+ break;
+#endif
+#ifdef SYST_INT32_TO_FLOAT128
+ case INT32_TO_FLOAT128:
+ test_a_int32_z_float128( int32_to_float128, syst_int32_to_float128 );
+ break;
+#endif
+#ifdef SYST_INT64_TO_FLOAT32
+ case INT64_TO_FLOAT32:
+ test_a_int64_z_float32( int64_to_float32, syst_int64_to_float32 );
+ break;
+#endif
+#ifdef SYST_INT64_TO_FLOAT64
+ case INT64_TO_FLOAT64:
+ test_a_int64_z_float64( int64_to_float64, syst_int64_to_float64 );
+ break;
+#endif
+#ifdef SYST_INT64_TO_FLOATX80
+ case INT64_TO_FLOATX80:
+ test_a_int64_z_floatx80( int64_to_floatx80, syst_int64_to_floatx80 );
+ break;
+#endif
+#ifdef SYST_INT64_TO_FLOAT128
+ case INT64_TO_FLOAT128:
+ test_a_int64_z_float128( int64_to_float128, syst_int64_to_float128 );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT32
+ case FLOAT32_TO_INT32:
+ test_a_float32_z_int32( float32_to_int32, syst_float32_to_int32 );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+ case FLOAT32_TO_INT32_ROUND_TO_ZERO:
+ test_a_float32_z_int32(
+ float32_to_int32_round_to_zero,
+ syst_float32_to_int32_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT64
+ case FLOAT32_TO_INT64:
+ test_a_float32_z_int64( float32_to_int64, syst_float32_to_int64 );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
+ case FLOAT32_TO_INT64_ROUND_TO_ZERO:
+ test_a_float32_z_int64(
+ float32_to_int64_round_to_zero,
+ syst_float32_to_int64_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT64
+ case FLOAT32_TO_FLOAT64:
+ test_a_float32_z_float64(
+ float32_to_float64, syst_float32_to_float64 );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_FLOATX80
+ case FLOAT32_TO_FLOATX80:
+ test_a_float32_z_floatx80(
+ float32_to_floatx80, syst_float32_to_floatx80 );
+ break;
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT128
+ case FLOAT32_TO_FLOAT128:
+ test_a_float32_z_float128(
+ float32_to_float128, syst_float32_to_float128 );
+ break;
+#endif
+#ifdef SYST_FLOAT32_ROUND_TO_INT
+ case FLOAT32_ROUND_TO_INT:
+ test_az_float32( float32_round_to_int, syst_float32_round_to_int );
+ break;
+#endif
+#ifdef SYST_FLOAT32_ADD
+ case FLOAT32_ADD:
+ test_abz_float32( float32_add, syst_float32_add );
+ break;
+#endif
+#ifdef SYST_FLOAT32_SUB
+ case FLOAT32_SUB:
+ test_abz_float32( float32_sub, syst_float32_sub );
+ break;
+#endif
+#ifdef SYST_FLOAT32_MUL
+ case FLOAT32_MUL:
+ test_abz_float32( float32_mul, syst_float32_mul );
+ break;
+#endif
+#ifdef SYST_FLOAT32_DIV
+ case FLOAT32_DIV:
+ test_abz_float32( float32_div, syst_float32_div );
+ break;
+#endif
+#ifdef SYST_FLOAT32_REM
+ case FLOAT32_REM:
+ test_abz_float32( float32_rem, syst_float32_rem );
+ break;
+#endif
+#ifdef SYST_FLOAT32_SQRT
+ case FLOAT32_SQRT:
+ test_az_float32( float32_sqrt, syst_float32_sqrt );
+ break;
+#endif
+#ifdef SYST_FLOAT32_EQ
+ case FLOAT32_EQ:
+ test_ab_float32_z_flag( float32_eq, syst_float32_eq );
+ break;
+#endif
+#ifdef SYST_FLOAT32_LE
+ case FLOAT32_LE:
+ test_ab_float32_z_flag( float32_le, syst_float32_le );
+ break;
+#endif
+#ifdef SYST_FLOAT32_LT
+ case FLOAT32_LT:
+ test_ab_float32_z_flag( float32_lt, syst_float32_lt );
+ break;
+#endif
+#ifdef SYST_FLOAT32_EQ_SIGNALING
+ case FLOAT32_EQ_SIGNALING:
+ test_ab_float32_z_flag(
+ float32_eq_signaling, syst_float32_eq_signaling );
+ break;
+#endif
+#ifdef SYST_FLOAT32_LE_QUIET
+ case FLOAT32_LE_QUIET:
+ test_ab_float32_z_flag( float32_le_quiet, syst_float32_le_quiet );
+ break;
+#endif
+#ifdef SYST_FLOAT32_LT_QUIET
+ case FLOAT32_LT_QUIET:
+ test_ab_float32_z_flag( float32_lt_quiet, syst_float32_lt_quiet );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT32
+ case FLOAT64_TO_INT32:
+ test_a_float64_z_int32( float64_to_int32, syst_float64_to_int32 );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+ case FLOAT64_TO_INT32_ROUND_TO_ZERO:
+ test_a_float64_z_int32(
+ float64_to_int32_round_to_zero,
+ syst_float64_to_int32_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT64
+ case FLOAT64_TO_INT64:
+ test_a_float64_z_int64( float64_to_int64, syst_float64_to_int64 );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
+ case FLOAT64_TO_INT64_ROUND_TO_ZERO:
+ test_a_float64_z_int64(
+ float64_to_int64_round_to_zero,
+ syst_float64_to_int64_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT32
+ case FLOAT64_TO_FLOAT32:
+ test_a_float64_z_float32(
+ float64_to_float32, syst_float64_to_float32 );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_FLOATX80
+ case FLOAT64_TO_FLOATX80:
+ test_a_float64_z_floatx80(
+ float64_to_floatx80, syst_float64_to_floatx80 );
+ break;
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT128
+ case FLOAT64_TO_FLOAT128:
+ test_a_float64_z_float128(
+ float64_to_float128, syst_float64_to_float128 );
+ break;
+#endif
+#ifdef SYST_FLOAT64_ROUND_TO_INT
+ case FLOAT64_ROUND_TO_INT:
+ test_az_float64( float64_round_to_int, syst_float64_round_to_int );
+ break;
+#endif
+#ifdef SYST_FLOAT64_ADD
+ case FLOAT64_ADD:
+ test_abz_float64( float64_add, syst_float64_add );
+ break;
+#endif
+#ifdef SYST_FLOAT64_SUB
+ case FLOAT64_SUB:
+ test_abz_float64( float64_sub, syst_float64_sub );
+ break;
+#endif
+#ifdef SYST_FLOAT64_MUL
+ case FLOAT64_MUL:
+ test_abz_float64( float64_mul, syst_float64_mul );
+ break;
+#endif
+#ifdef SYST_FLOAT64_DIV
+ case FLOAT64_DIV:
+ test_abz_float64( float64_div, syst_float64_div );
+ break;
+#endif
+#ifdef SYST_FLOAT64_REM
+ case FLOAT64_REM:
+ test_abz_float64( float64_rem, syst_float64_rem );
+ break;
+#endif
+#ifdef SYST_FLOAT64_SQRT
+ case FLOAT64_SQRT:
+ test_az_float64( float64_sqrt, syst_float64_sqrt );
+ break;
+#endif
+#ifdef SYST_FLOAT64_EQ
+ case FLOAT64_EQ:
+ test_ab_float64_z_flag( float64_eq, syst_float64_eq );
+ break;
+#endif
+#ifdef SYST_FLOAT64_LE
+ case FLOAT64_LE:
+ test_ab_float64_z_flag( float64_le, syst_float64_le );
+ break;
+#endif
+#ifdef SYST_FLOAT64_LT
+ case FLOAT64_LT:
+ test_ab_float64_z_flag( float64_lt, syst_float64_lt );
+ break;
+#endif
+#ifdef SYST_FLOAT64_EQ_SIGNALING
+ case FLOAT64_EQ_SIGNALING:
+ test_ab_float64_z_flag(
+ float64_eq_signaling, syst_float64_eq_signaling );
+ break;
+#endif
+#ifdef SYST_FLOAT64_LE_QUIET
+ case FLOAT64_LE_QUIET:
+ test_ab_float64_z_flag( float64_le_quiet, syst_float64_le_quiet );
+ break;
+#endif
+#ifdef SYST_FLOAT64_LT_QUIET
+ case FLOAT64_LT_QUIET:
+ test_ab_float64_z_flag( float64_lt_quiet, syst_float64_lt_quiet );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT32
+ case FLOATX80_TO_INT32:
+ test_a_floatx80_z_int32( floatx80_to_int32, syst_floatx80_to_int32 );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
+ case FLOATX80_TO_INT32_ROUND_TO_ZERO:
+ test_a_floatx80_z_int32(
+ floatx80_to_int32_round_to_zero,
+ syst_floatx80_to_int32_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT64
+ case FLOATX80_TO_INT64:
+ test_a_floatx80_z_int64( floatx80_to_int64, syst_floatx80_to_int64 );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
+ case FLOATX80_TO_INT64_ROUND_TO_ZERO:
+ test_a_floatx80_z_int64(
+ floatx80_to_int64_round_to_zero,
+ syst_floatx80_to_int64_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT32
+ case FLOATX80_TO_FLOAT32:
+ test_a_floatx80_z_float32(
+ floatx80_to_float32, syst_floatx80_to_float32 );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT64
+ case FLOATX80_TO_FLOAT64:
+ test_a_floatx80_z_float64(
+ floatx80_to_float64, syst_floatx80_to_float64 );
+ break;
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT128
+ case FLOATX80_TO_FLOAT128:
+ test_a_floatx80_z_float128(
+ floatx80_to_float128, syst_floatx80_to_float128 );
+ break;
+#endif
+#ifdef SYST_FLOATX80_ROUND_TO_INT
+ case FLOATX80_ROUND_TO_INT:
+ test_az_floatx80( floatx80_round_to_int, syst_floatx80_round_to_int );
+ break;
+#endif
+#ifdef SYST_FLOATX80_ADD
+ case FLOATX80_ADD:
+ test_abz_floatx80( floatx80_add, syst_floatx80_add );
+ break;
+#endif
+#ifdef SYST_FLOATX80_SUB
+ case FLOATX80_SUB:
+ test_abz_floatx80( floatx80_sub, syst_floatx80_sub );
+ break;
+#endif
+#ifdef SYST_FLOATX80_MUL
+ case FLOATX80_MUL:
+ test_abz_floatx80( floatx80_mul, syst_floatx80_mul );
+ break;
+#endif
+#ifdef SYST_FLOATX80_DIV
+ case FLOATX80_DIV:
+ test_abz_floatx80( floatx80_div, syst_floatx80_div );
+ break;
+#endif
+#ifdef SYST_FLOATX80_REM
+ case FLOATX80_REM:
+ test_abz_floatx80( floatx80_rem, syst_floatx80_rem );
+ break;
+#endif
+#ifdef SYST_FLOATX80_SQRT
+ case FLOATX80_SQRT:
+ test_az_floatx80( floatx80_sqrt, syst_floatx80_sqrt );
+ break;
+#endif
+#ifdef SYST_FLOATX80_EQ
+ case FLOATX80_EQ:
+ test_ab_floatx80_z_flag( floatx80_eq, syst_floatx80_eq );
+ break;
+#endif
+#ifdef SYST_FLOATX80_LE
+ case FLOATX80_LE:
+ test_ab_floatx80_z_flag( floatx80_le, syst_floatx80_le );
+ break;
+#endif
+#ifdef SYST_FLOATX80_LT
+ case FLOATX80_LT:
+ test_ab_floatx80_z_flag( floatx80_lt, syst_floatx80_lt );
+ break;
+#endif
+#ifdef SYST_FLOATX80_EQ_SIGNALING
+ case FLOATX80_EQ_SIGNALING:
+ test_ab_floatx80_z_flag(
+ floatx80_eq_signaling, syst_floatx80_eq_signaling );
+ break;
+#endif
+#ifdef SYST_FLOATX80_LE_QUIET
+ case FLOATX80_LE_QUIET:
+ test_ab_floatx80_z_flag( floatx80_le_quiet, syst_floatx80_le_quiet );
+ break;
+#endif
+#ifdef SYST_FLOATX80_LT_QUIET
+ case FLOATX80_LT_QUIET:
+ test_ab_floatx80_z_flag( floatx80_lt_quiet, syst_floatx80_lt_quiet );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT32
+ case FLOAT128_TO_INT32:
+ test_a_float128_z_int32( float128_to_int32, syst_float128_to_int32 );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+ case FLOAT128_TO_INT32_ROUND_TO_ZERO:
+ test_a_float128_z_int32(
+ float128_to_int32_round_to_zero,
+ syst_float128_to_int32_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT64
+ case FLOAT128_TO_INT64:
+ test_a_float128_z_int64( float128_to_int64, syst_float128_to_int64 );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
+ case FLOAT128_TO_INT64_ROUND_TO_ZERO:
+ test_a_float128_z_int64(
+ float128_to_int64_round_to_zero,
+ syst_float128_to_int64_round_to_zero
+ );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT32
+ case FLOAT128_TO_FLOAT32:
+ test_a_float128_z_float32(
+ float128_to_float32, syst_float128_to_float32 );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT64
+ case FLOAT128_TO_FLOAT64:
+ test_a_float128_z_float64(
+ float128_to_float64, syst_float128_to_float64 );
+ break;
+#endif
+#ifdef SYST_FLOAT128_TO_FLOATX80
+ case FLOAT128_TO_FLOATX80:
+ test_a_float128_z_floatx80(
+ float128_to_floatx80, syst_float128_to_floatx80 );
+ break;
+#endif
+#ifdef SYST_FLOAT128_ROUND_TO_INT
+ case FLOAT128_ROUND_TO_INT:
+ test_az_float128( float128_round_to_int, syst_float128_round_to_int );
+ break;
+#endif
+#ifdef SYST_FLOAT128_ADD
+ case FLOAT128_ADD:
+ test_abz_float128( float128_add, syst_float128_add );
+ break;
+#endif
+#ifdef SYST_FLOAT128_SUB
+ case FLOAT128_SUB:
+ test_abz_float128( float128_sub, syst_float128_sub );
+ break;
+#endif
+#ifdef SYST_FLOAT128_MUL
+ case FLOAT128_MUL:
+ test_abz_float128( float128_mul, syst_float128_mul );
+ break;
+#endif
+#ifdef SYST_FLOAT128_DIV
+ case FLOAT128_DIV:
+ test_abz_float128( float128_div, syst_float128_div );
+ break;
+#endif
+#ifdef SYST_FLOAT128_REM
+ case FLOAT128_REM:
+ test_abz_float128( float128_rem, syst_float128_rem );
+ break;
+#endif
+#ifdef SYST_FLOAT128_SQRT
+ case FLOAT128_SQRT:
+ test_az_float128( float128_sqrt, syst_float128_sqrt );
+ break;
+#endif
+#ifdef SYST_FLOAT128_EQ
+ case FLOAT128_EQ:
+ test_ab_float128_z_flag( float128_eq, syst_float128_eq );
+ break;
+#endif
+#ifdef SYST_FLOAT128_LE
+ case FLOAT128_LE:
+ test_ab_float128_z_flag( float128_le, syst_float128_le );
+ break;
+#endif
+#ifdef SYST_FLOAT128_LT
+ case FLOAT128_LT:
+ test_ab_float128_z_flag( float128_lt, syst_float128_lt );
+ break;
+#endif
+#ifdef SYST_FLOAT128_EQ_SIGNALING
+ case FLOAT128_EQ_SIGNALING:
+ test_ab_float128_z_flag(
+ float128_eq_signaling, syst_float128_eq_signaling );
+ break;
+#endif
+#ifdef SYST_FLOAT128_LE_QUIET
+ case FLOAT128_LE_QUIET:
+ test_ab_float128_z_flag( float128_le_quiet, syst_float128_le_quiet );
+ break;
+#endif
+#ifdef SYST_FLOAT128_LT_QUIET
+ case FLOAT128_LT_QUIET:
+ test_ab_float128_z_flag( float128_lt_quiet, syst_float128_lt_quiet );
+ break;
+#endif
+ }
+ if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
+
+}
+
+void
+ testFunction(
+ uint8 functionCode, int8 roundingPrecisionIn, int8 roundingModeIn )
+{
+ int8 roundingPrecision, roundingMode;
+
+ roundingPrecision = 32;
+ for (;;) {
+ if ( ! functions[ functionCode ].roundingPrecision ) {
+ roundingPrecision = 0;
+ }
+ else if ( roundingPrecisionIn ) {
+ roundingPrecision = roundingPrecisionIn;
+ }
+ for ( roundingMode = 1;
+ roundingMode < NUM_ROUNDINGMODES;
+ ++roundingMode
+ ) {
+ if ( ! functions[ functionCode ].roundingMode ) {
+ roundingMode = 0;
+ }
+ else if ( roundingModeIn ) {
+ roundingMode = roundingModeIn;
+ }
+ testFunctionVariety(
+ functionCode, roundingPrecision, roundingMode );
+ if ( roundingModeIn || ! roundingMode ) break;
+ }
+ if ( roundingPrecisionIn || ! roundingPrecision ) break;
+ if ( roundingPrecision == 80 ) {
+ break;
+ }
+ else if ( roundingPrecision == 64 ) {
+ roundingPrecision = 80;
+ }
+ else if ( roundingPrecision == 32 ) {
+ roundingPrecision = 64;
+ }
+ }
+
+}
+
diff --git a/tools/test/testfloat/testFunction.h b/tools/test/testfloat/testFunction.h
new file mode 100644
index 0000000..04bf856
--- /dev/null
+++ b/tools/test/testfloat/testFunction.h
@@ -0,0 +1,135 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+enum {
+ INT32_TO_FLOAT32 = 1,
+ INT32_TO_FLOAT64,
+ INT32_TO_FLOATX80,
+ INT32_TO_FLOAT128,
+ INT64_TO_FLOAT32,
+ INT64_TO_FLOAT64,
+ INT64_TO_FLOATX80,
+ INT64_TO_FLOAT128,
+ FLOAT32_TO_INT32,
+ FLOAT32_TO_INT32_ROUND_TO_ZERO,
+ FLOAT32_TO_INT64,
+ FLOAT32_TO_INT64_ROUND_TO_ZERO,
+ FLOAT32_TO_FLOAT64,
+ FLOAT32_TO_FLOATX80,
+ FLOAT32_TO_FLOAT128,
+ FLOAT32_ROUND_TO_INT,
+ FLOAT32_ADD,
+ FLOAT32_SUB,
+ FLOAT32_MUL,
+ FLOAT32_DIV,
+ FLOAT32_REM,
+ FLOAT32_SQRT,
+ FLOAT32_EQ,
+ FLOAT32_LE,
+ FLOAT32_LT,
+ FLOAT32_EQ_SIGNALING,
+ FLOAT32_LE_QUIET,
+ FLOAT32_LT_QUIET,
+ FLOAT64_TO_INT32,
+ FLOAT64_TO_INT32_ROUND_TO_ZERO,
+ FLOAT64_TO_INT64,
+ FLOAT64_TO_INT64_ROUND_TO_ZERO,
+ FLOAT64_TO_FLOAT32,
+ FLOAT64_TO_FLOATX80,
+ FLOAT64_TO_FLOAT128,
+ FLOAT64_ROUND_TO_INT,
+ FLOAT64_ADD,
+ FLOAT64_SUB,
+ FLOAT64_MUL,
+ FLOAT64_DIV,
+ FLOAT64_REM,
+ FLOAT64_SQRT,
+ FLOAT64_EQ,
+ FLOAT64_LE,
+ FLOAT64_LT,
+ FLOAT64_EQ_SIGNALING,
+ FLOAT64_LE_QUIET,
+ FLOAT64_LT_QUIET,
+ FLOATX80_TO_INT32,
+ FLOATX80_TO_INT32_ROUND_TO_ZERO,
+ FLOATX80_TO_INT64,
+ FLOATX80_TO_INT64_ROUND_TO_ZERO,
+ FLOATX80_TO_FLOAT32,
+ FLOATX80_TO_FLOAT64,
+ FLOATX80_TO_FLOAT128,
+ FLOATX80_ROUND_TO_INT,
+ FLOATX80_ADD,
+ FLOATX80_SUB,
+ FLOATX80_MUL,
+ FLOATX80_DIV,
+ FLOATX80_REM,
+ FLOATX80_SQRT,
+ FLOATX80_EQ,
+ FLOATX80_LE,
+ FLOATX80_LT,
+ FLOATX80_EQ_SIGNALING,
+ FLOATX80_LE_QUIET,
+ FLOATX80_LT_QUIET,
+ FLOAT128_TO_INT32,
+ FLOAT128_TO_INT32_ROUND_TO_ZERO,
+ FLOAT128_TO_INT64,
+ FLOAT128_TO_INT64_ROUND_TO_ZERO,
+ FLOAT128_TO_FLOAT32,
+ FLOAT128_TO_FLOAT64,
+ FLOAT128_TO_FLOATX80,
+ FLOAT128_ROUND_TO_INT,
+ FLOAT128_ADD,
+ FLOAT128_SUB,
+ FLOAT128_MUL,
+ FLOAT128_DIV,
+ FLOAT128_REM,
+ FLOAT128_SQRT,
+ FLOAT128_EQ,
+ FLOAT128_LE,
+ FLOAT128_LT,
+ FLOAT128_EQ_SIGNALING,
+ FLOAT128_LE_QUIET,
+ FLOAT128_LT_QUIET,
+ NUM_FUNCTIONS
+};
+
+typedef struct {
+ char *name;
+ int8 numInputs;
+ flag roundingPrecision, roundingMode;
+} functionT;
+extern const functionT functions[ NUM_FUNCTIONS ];
+extern const flag functionExists[ NUM_FUNCTIONS ];
+
+enum {
+ ROUND_NEAREST_EVEN = 1,
+ ROUND_TO_ZERO,
+ ROUND_DOWN,
+ ROUND_UP,
+ NUM_ROUNDINGMODES
+};
+
+void testFunction( uint8, int8, int8 );
+
diff --git a/tools/test/testfloat/testLoops.c b/tools/test/testfloat/testLoops.c
new file mode 100644
index 0000000..8ba92f3
--- /dev/null
+++ b/tools/test/testfloat/testLoops.c
@@ -0,0 +1,2713 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "milieu.h"
+#include "softfloat.h"
+#include "testCases.h"
+#include "writeHex.h"
+#include "testLoops.h"
+
+volatile flag stop = FALSE;
+
+char *trueName, *testName;
+flag forever, errorStop;
+uint32 maxErrorCount = 0;
+flag checkNaNs = FALSE;
+int8 *trueFlagsPtr;
+int8 ( *testFlagsFunctionPtr )( void );
+char *functionName;
+char *roundingPrecisionName, *roundingModeName, *tininessModeName;
+flag anyErrors = FALSE;
+
+void writeFunctionName( FILE *stream )
+{
+
+ fputs( functionName, stream );
+ if ( roundingModeName ) {
+ if ( roundingPrecisionName ) {
+ fputs( ", precision ", stream );
+ fputs( roundingPrecisionName, stream );
+ }
+ fputs( ", rounding ", stream );
+ fputs( roundingModeName, stream );
+ if ( tininessModeName ) {
+ fputs( ", tininess ", stream );
+ fputs( tininessModeName, stream );
+ fputs( " rounding", stream );
+ }
+ }
+
+}
+
+void exitWithStatus( void )
+{
+
+ exit( anyErrors ? EXIT_FAILURE : EXIT_SUCCESS );
+
+}
+
+static uint32 tenthousandsCount, errorCount = 0;
+
+static void writeTestsTotal( void )
+{
+
+ if ( forever ) {
+ fputs( "Unbounded tests.\n", stderr );
+ }
+ else {
+ fprintf( stderr, "\r%d tests total.\n", testCases_total );
+ }
+
+}
+
+static void writeTestsPerformed( int16 count )
+{
+
+ if ( tenthousandsCount ) {
+ fprintf(
+ stderr, "\r%d%04d tests performed", tenthousandsCount, count );
+ }
+ else {
+ fprintf( stderr, "\r%d tests performed", count );
+ }
+ if ( errorCount ) {
+ fprintf(
+ stderr,
+ "; %d error%s found.\n",
+ errorCount,
+ ( errorCount == 1 ) ? "" : "s"
+ );
+ }
+ else {
+ fputs( ".\n", stderr );
+ fputs( "No errors found in ", stdout );
+ writeFunctionName( stdout );
+ fputs( ".\n", stdout );
+ fflush( stdout );
+ }
+
+}
+
+static void checkEarlyExit( void )
+{
+
+ ++tenthousandsCount;
+ if ( stop ) {
+ writeTestsPerformed( 0 );
+ exitWithStatus();
+ }
+ fprintf( stderr, "\r%3d0000", tenthousandsCount );
+
+}
+
+static void writeErrorFound( int16 count )
+{
+
+ fputc( '\r', stderr );
+ if ( errorCount == 1 ) {
+ fputs( "Errors found in ", stdout );
+ writeFunctionName( stdout );
+ fputs( ":\n", stdout );
+ }
+ if ( stop ) {
+ writeTestsPerformed( count );
+ exitWithStatus();
+ }
+ anyErrors = TRUE;
+
+}
+
+INLINE void writeInput_a_int32( void )
+{
+
+ writeHex_bits32( testCases_a_int32, stdout );
+
+}
+
+#ifdef BITS64
+
+INLINE void writeInput_a_int64( void )
+{
+
+ writeHex_bits64( testCases_a_int64, stdout );
+
+}
+
+#endif
+
+INLINE void writeInput_a_float32( void )
+{
+
+ writeHex_float32( testCases_a_float32, stdout );
+
+}
+
+static void writeInputs_ab_float32( void )
+{
+
+ writeHex_float32( testCases_a_float32, stdout );
+ fputs( " ", stdout );
+ writeHex_float32( testCases_b_float32, stdout );
+
+}
+
+INLINE void writeInput_a_float64( void )
+{
+
+ writeHex_float64( testCases_a_float64, stdout );
+
+}
+
+static void writeInputs_ab_float64( void )
+{
+
+ writeHex_float64( testCases_a_float64, stdout );
+ fputs( " ", stdout );
+ writeHex_float64( testCases_b_float64, stdout );
+
+}
+
+#ifdef FLOATX80
+
+INLINE void writeInput_a_floatx80( void )
+{
+
+ writeHex_floatx80( testCases_a_floatx80, stdout );
+
+}
+
+static void writeInputs_ab_floatx80( void )
+{
+
+ writeHex_floatx80( testCases_a_floatx80, stdout );
+ fputs( " ", stdout );
+ writeHex_floatx80( testCases_b_floatx80, stdout );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+INLINE void writeInput_a_float128( void )
+{
+
+ writeHex_float128( testCases_a_float128, stdout );
+
+}
+
+static void writeInputs_ab_float128( void )
+{
+
+ writeHex_float128( testCases_a_float128, stdout );
+ fputs( " ", stdout );
+ writeHex_float128( testCases_b_float128, stdout );
+
+}
+
+#endif
+
+static void
+ writeOutputs_z_flag(
+ flag trueZ, uint8 trueFlags, flag testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_flag( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( " ", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_flag( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+static void
+ writeOutputs_z_int32(
+ int32 trueZ, uint8 trueFlags, int32 testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_bits32( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( " ", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_bits32( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+#ifdef BITS64
+
+static void
+ writeOutputs_z_int64(
+ int64 trueZ, uint8 trueFlags, int64 testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_bits64( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( " ", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_bits64( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+#endif
+
+static void
+ writeOutputs_z_float32(
+ float32 trueZ, uint8 trueFlags, float32 testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_float32( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( " ", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_float32( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+static void
+ writeOutputs_z_float64(
+ float64 trueZ, uint8 trueFlags, float64 testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_float64( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( " ", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_float64( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+#ifdef FLOATX80
+
+static void
+ writeOutputs_z_floatx80(
+ floatx80 trueZ, uint8 trueFlags, floatx80 testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_floatx80( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( " ", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_floatx80( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+static void
+ writeOutputs_z_float128(
+ float128 trueZ, uint8 trueFlags, float128 testZ, uint8 testFlags )
+{
+
+ fputs( trueName, stdout );
+ fputs( ": ", stdout );
+ writeHex_float128( trueZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( trueFlags, stdout );
+ fputs( "\n\t", stdout );
+ fputs( testName, stdout );
+ fputs( ": ", stdout );
+ writeHex_float128( testZ, stdout );
+ fputc( ' ', stdout );
+ writeHex_float_flags( testFlags, stdout );
+ fputc( '\n', stdout );
+
+}
+
+#endif
+
+INLINE flag float32_isNaN( float32 a )
+{
+
+ return 0x7F800000 < ( a & 0x7FFFFFFF );
+
+}
+
+#ifdef BITS64
+
+INLINE flag float64_same( float64 a, float64 b )
+{
+
+ return a == b;
+
+}
+
+INLINE flag float64_isNaN( float64 a )
+{
+
+ return LIT64( 0x7FF0000000000000 ) < ( a & LIT64( 0x7FFFFFFFFFFFFFFF ) );
+
+}
+
+#else
+
+INLINE flag float64_same( float64 a, float64 b )
+{
+
+ return ( a.high == b.high ) && ( a.low == b.low );
+
+}
+
+INLINE flag float64_isNaN( float64 a )
+{
+ bits32 absAHigh;
+
+ absAHigh = a.high & 0x7FFFFFFF;
+ return
+ ( 0x7FF00000 < absAHigh ) || ( ( absAHigh == 0x7FF00000 ) && a.low );
+
+}
+
+#endif
+
+#ifdef FLOATX80
+
+INLINE flag floatx80_same( floatx80 a, floatx80 b )
+{
+
+ return ( a.high == b.high ) && ( a.low == b.low );
+
+}
+
+INLINE flag floatx80_isNaN( floatx80 a )
+{
+
+ return ( ( a.high & 0x7FFF ) == 0x7FFF ) && a.low;
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+INLINE flag float128_same( float128 a, float128 b )
+{
+
+ return ( a.high == b.high ) && ( a.low == b.low );
+
+}
+
+INLINE flag float128_isNaN( float128 a )
+{
+ bits64 absAHigh;
+
+ absAHigh = a.high & LIT64( 0x7FFFFFFFFFFFFFFF );
+ return
+ ( LIT64( 0x7FFF000000000000 ) < absAHigh )
+ || ( ( absAHigh == LIT64( 0x7FFF000000000000 ) ) && a.low );
+
+}
+
+#endif
+
+void
+ test_a_int32_z_float32(
+ float32 trueFunction( int32 ), float32 testFunction( int32 ) )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int32();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_int32_z_float64(
+ float64 trueFunction( int32 ), float64 testFunction( int32 ) )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int32();
+ fputs( " ", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_int32_z_floatx80(
+ floatx80 trueFunction( int32 ), floatx80 testFunction( int32 ) )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int32();
+ fputs( " ", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_int32_z_float128(
+ float128 trueFunction( int32 ), float128 testFunction( int32 ) )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int32();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef BITS64
+
+void
+ test_a_int64_z_float32(
+ float32 trueFunction( int64 ), float32 testFunction( int64 ) )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int64();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_int64_z_float64(
+ float64 trueFunction( int64 ), float64 testFunction( int64 ) )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int64();
+ fputs( " ", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_int64_z_floatx80(
+ floatx80 trueFunction( int64 ), floatx80 testFunction( int64 ) )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int64();
+ fputs( " ", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_int64_z_float128(
+ float128 trueFunction( int64 ), float128 testFunction( int64 ) )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_int64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_int64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_int64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_int64();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#endif
+
+void
+ test_a_float32_z_int32(
+ int32 trueFunction( float32 ), int32 testFunction( float32 ) )
+{
+ int16 count;
+ int32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_is_signaling_nan( testCases_a_float32 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == 0x7FFFFFFF )
+ && ( ( testZ == 0x7FFFFFFF )
+ || ( testZ == (sbits32) 0x80000000 ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float32();
+ fputs( " ", stdout );
+ writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_float32_z_int64(
+ int64 trueFunction( float32 ), int64 testFunction( float32 ) )
+{
+ int16 count;
+ int64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_is_signaling_nan( testCases_a_float32 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ && ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float32();
+ fputs( " ", stdout );
+ writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_float32_z_float64(
+ float64 trueFunction( float32 ), float64 testFunction( float32 ) )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_is_signaling_nan( testCases_a_float32 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float32();
+ fputs( " ", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_float32_z_floatx80(
+ floatx80 trueFunction( float32 ), floatx80 testFunction( float32 ) )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_is_signaling_nan( testCases_a_float32 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float32();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_float32_z_float128(
+ float128 trueFunction( float32 ), float128 testFunction( float32 ) )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_is_signaling_nan( testCases_a_float32 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float32();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_float32(
+ float32 trueFunction( float32 ), float32 testFunction( float32 ) )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float32_is_signaling_nan( testCases_a_float32 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float32();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_float32_z_flag(
+ flag trueFunction( float32, float32 ),
+ flag testFunction( float32, float32 )
+ )
+{
+ int16 count;
+ flag trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32, testCases_b_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( float32_is_signaling_nan( testCases_a_float32 )
+ || float32_is_signaling_nan( testCases_b_float32 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_float32();
+ fputs( " ", stdout );
+ writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+void
+ test_abz_float32(
+ float32 trueFunction( float32, float32 ),
+ float32 testFunction( float32, float32 )
+ )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_float32 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float32, testCases_b_float32 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( float32_is_signaling_nan( testCases_a_float32 )
+ || float32_is_signaling_nan( testCases_b_float32 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_float32();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+void
+ test_a_float64_z_int32(
+ int32 trueFunction( float64 ), int32 testFunction( float64 ) )
+{
+ int16 count;
+ int32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_is_signaling_nan( testCases_a_float64 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == 0x7FFFFFFF )
+ && ( ( testZ == 0x7FFFFFFF )
+ || ( testZ == (sbits32) 0x80000000 ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float64();
+ fputs( " ", stdout );
+ writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_float64_z_int64(
+ int64 trueFunction( float64 ), int64 testFunction( float64 ) )
+{
+ int16 count;
+ int64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_is_signaling_nan( testCases_a_float64 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ && ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float64();
+ fputs( " ", stdout );
+ writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_float64_z_float32(
+ float32 trueFunction( float64 ), float32 testFunction( float64 ) )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_is_signaling_nan( testCases_a_float64 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float64();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_float64_z_floatx80(
+ floatx80 trueFunction( float64 ), floatx80 testFunction( float64 ) )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_is_signaling_nan( testCases_a_float64 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float64();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_float64_z_float128(
+ float128 trueFunction( float64 ), float128 testFunction( float64 ) )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_is_signaling_nan( testCases_a_float64 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float64();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_float64(
+ float64 trueFunction( float64 ), float64 testFunction( float64 ) )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float64_is_signaling_nan( testCases_a_float64 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float64();
+ fputs( " ", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_float64_z_flag(
+ flag trueFunction( float64, float64 ),
+ flag testFunction( float64, float64 )
+ )
+{
+ int16 count;
+ flag trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64, testCases_b_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( float64_is_signaling_nan( testCases_a_float64 )
+ || float64_is_signaling_nan( testCases_b_float64 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_float64();
+ fputs( " ", stdout );
+ writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+void
+ test_abz_float64(
+ float64 trueFunction( float64, float64 ),
+ float64 testFunction( float64, float64 )
+ )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_float64 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float64, testCases_b_float64 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( float64_is_signaling_nan( testCases_a_float64 )
+ || float64_is_signaling_nan( testCases_b_float64 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_float64();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_floatx80_z_int32(
+ int32 trueFunction( floatx80 ), int32 testFunction( floatx80 ) )
+{
+ int16 count;
+ int32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == 0x7FFFFFFF )
+ && ( ( testZ == 0x7FFFFFFF )
+ || ( testZ == (sbits32) 0x80000000 ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_floatx80();
+ fputs( " ", stdout );
+ writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_floatx80_z_int64(
+ int64 trueFunction( floatx80 ), int64 testFunction( floatx80 ) )
+{
+ int16 count;
+ int64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ && ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_floatx80();
+ fputs( " ", stdout );
+ writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_floatx80_z_float32(
+ float32 trueFunction( floatx80 ), float32 testFunction( floatx80 ) )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_floatx80();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_floatx80_z_float64(
+ float64 trueFunction( floatx80 ), float64 testFunction( floatx80 ) )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_floatx80();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOAT128
+
+void
+ test_a_floatx80_z_float128(
+ float128 trueFunction( floatx80 ), float128 testFunction( floatx80 ) )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_floatx80();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_floatx80(
+ floatx80 trueFunction( floatx80 ), floatx80 testFunction( floatx80 ) )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_floatx80();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_floatx80_z_flag(
+ flag trueFunction( floatx80, floatx80 ),
+ flag testFunction( floatx80, floatx80 )
+ )
+{
+ int16 count;
+ flag trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( floatx80_is_signaling_nan( testCases_a_floatx80 )
+ || floatx80_is_signaling_nan( testCases_b_floatx80 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_floatx80();
+ fputs( " ", stdout );
+ writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+void
+ test_abz_floatx80(
+ floatx80 trueFunction( floatx80, floatx80 ),
+ floatx80 testFunction( floatx80, floatx80 )
+ )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_floatx80 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( floatx80_is_signaling_nan( testCases_a_floatx80 )
+ || floatx80_is_signaling_nan( testCases_b_floatx80 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_floatx80();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_float128_z_int32(
+ int32 trueFunction( float128 ), int32 testFunction( float128 ) )
+{
+ int16 count;
+ int32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_is_signaling_nan( testCases_a_float128 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == 0x7FFFFFFF )
+ && ( ( testZ == 0x7FFFFFFF )
+ || ( testZ == (sbits32) 0x80000000 ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float128();
+ fputs( " ", stdout );
+ writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_float128_z_int64(
+ int64 trueFunction( float128 ), int64 testFunction( float128 ) )
+{
+ int16 count;
+ int64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_is_signaling_nan( testCases_a_float128 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ && ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+ || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+ && ( trueFlags == float_flag_invalid )
+ && ( testFlags == float_flag_invalid )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float128();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_float128_z_float32(
+ float32 trueFunction( float128 ), float32 testFunction( float128 ) )
+{
+ int16 count;
+ float32 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_is_signaling_nan( testCases_a_float128 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float32_isNaN( trueZ )
+ && float32_isNaN( testZ )
+ && ! float32_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float128();
+ fputs( " ", stdout );
+ writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_float128_z_float64(
+ float64 trueFunction( float128 ), float64 testFunction( float128 ) )
+{
+ int16 count;
+ float64 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_is_signaling_nan( testCases_a_float128 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float64_isNaN( trueZ )
+ && float64_isNaN( testZ )
+ && ! float64_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float128();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_float128_z_floatx80(
+ floatx80 trueFunction( float128 ), floatx80 testFunction( float128 ) )
+{
+ int16 count;
+ floatx80 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_is_signaling_nan( testCases_a_float128 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && floatx80_isNaN( trueZ )
+ && floatx80_isNaN( testZ )
+ && ! floatx80_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float128();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_float128(
+ float128 trueFunction( float128 ), float128 testFunction( float128 ) )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_a_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && float128_is_signaling_nan( testCases_a_float128 ) ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInput_a_float128();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_float128_z_flag(
+ flag trueFunction( float128, float128 ),
+ flag testFunction( float128, float128 )
+ )
+{
+ int16 count;
+ flag trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128, testCases_b_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( float128_is_signaling_nan( testCases_a_float128 )
+ || float128_is_signaling_nan( testCases_b_float128 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_float128();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+void
+ test_abz_float128(
+ float128 trueFunction( float128, float128 ),
+ float128 testFunction( float128, float128 )
+ )
+{
+ int16 count;
+ float128 trueZ, testZ;
+ uint8 trueFlags, testFlags;
+
+ errorCount = 0;
+ tenthousandsCount = 0;
+ count = 10000;
+ testCases_initSequence( testCases_sequence_ab_float128 );
+ writeTestsTotal();
+ while ( ! testCases_done || forever ) {
+ testCases_next();
+ *trueFlagsPtr = 0;
+ trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
+ trueFlags = *trueFlagsPtr;
+ (void) testFlagsFunctionPtr();
+ testZ = testFunction( testCases_a_float128, testCases_b_float128 );
+ testFlags = testFlagsFunctionPtr();
+ --count;
+ if ( count == 0 ) {
+ checkEarlyExit();
+ count = 10000;
+ }
+ if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+ if ( ! checkNaNs
+ && ( float128_is_signaling_nan( testCases_a_float128 )
+ || float128_is_signaling_nan( testCases_b_float128 ) )
+ ) {
+ trueFlags |= float_flag_invalid;
+ }
+ if ( ! checkNaNs
+ && float128_isNaN( trueZ )
+ && float128_isNaN( testZ )
+ && ! float128_is_signaling_nan( testZ )
+ && ( trueFlags == testFlags )
+ ) {
+ /* no problem */
+ }
+ else {
+ ++errorCount;
+ writeErrorFound( 10000 - count );
+ writeInputs_ab_float128();
+ fputs( "\n\t", stdout );
+ writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+ fflush( stdout );
+ if ( errorCount == maxErrorCount ) goto exit;
+ }
+ }
+ }
+ exit:
+ writeTestsPerformed( 10000 - count );
+ return;
+
+}
+
+#endif
+
diff --git a/tools/test/testfloat/testLoops.h b/tools/test/testfloat/testLoops.h
new file mode 100644
index 0000000..c3b0847
--- /dev/null
+++ b/tools/test/testfloat/testLoops.h
@@ -0,0 +1,143 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <stdio.h>
+
+extern volatile flag stop;
+
+extern char *trueName, *testName;
+extern flag forever, errorStop;
+extern uint32 maxErrorCount;
+extern flag checkNaNs;
+extern int8 *trueFlagsPtr;
+extern int8 ( *testFlagsFunctionPtr )( void );
+extern char *functionName;
+extern char *roundingPrecisionName, *roundingModeName, *tininessModeName;
+extern flag anyErrors;
+
+void writeFunctionName( FILE * );
+void exitWithStatus( void );
+
+void test_a_int32_z_float32( float32 ( int32 ), float32 ( int32 ) );
+void test_a_int32_z_float64( float64 ( int32 ), float64 ( int32 ) );
+#ifdef FLOATX80
+void test_a_int32_z_floatx80( floatx80 ( int32 ), floatx80 ( int32 ) );
+#endif
+#ifdef FLOAT128
+void test_a_int32_z_float128( float128 ( int32 ), float128 ( int32 ) );
+#endif
+#ifdef BITS64
+void test_a_int64_z_float32( float32 ( int64 ), float32 ( int64 ) );
+void test_a_int64_z_float64( float64 ( int64 ), float64 ( int64 ) );
+#ifdef FLOATX80
+void test_a_int64_z_floatx80( floatx80 ( int64 ), floatx80 ( int64 ) );
+#endif
+#ifdef FLOAT128
+void test_a_int64_z_float128( float128 ( int64 ), float128 ( int64 ) );
+#endif
+#endif
+
+void test_a_float32_z_int32( int32 ( float32 ), int32 ( float32 ) );
+#ifdef BITS64
+void test_a_float32_z_int64( int64 ( float32 ), int64 ( float32 ) );
+#endif
+void test_a_float32_z_float64( float64 ( float32 ), float64 ( float32 ) );
+#ifdef FLOATX80
+void test_a_float32_z_floatx80( floatx80 ( float32 ), floatx80 ( float32 ) );
+#endif
+#ifdef FLOAT128
+void test_a_float32_z_float128( float128 ( float32 ), float128 ( float32 ) );
+#endif
+void test_az_float32( float32 ( float32 ), float32 ( float32 ) );
+void
+ test_ab_float32_z_flag(
+ flag ( float32, float32 ), flag ( float32, float32 ) );
+void
+ test_abz_float32(
+ float32 ( float32, float32 ), float32 ( float32, float32 ) );
+
+void test_a_float64_z_int32( int32 ( float64 ), int32 ( float64 ) );
+#ifdef BITS64
+void test_a_float64_z_int64( int64 ( float64 ), int64 ( float64 ) );
+#endif
+void test_a_float64_z_float32( float32 ( float64 ), float32 ( float64 ) );
+#ifdef FLOATX80
+void test_a_float64_z_floatx80( floatx80 ( float64 ), floatx80 ( float64 ) );
+#endif
+#ifdef FLOAT128
+void test_a_float64_z_float128( float128 ( float64 ), float128 ( float64 ) );
+#endif
+void test_az_float64( float64 ( float64 ), float64 ( float64 ) );
+void
+ test_ab_float64_z_flag(
+ flag ( float64, float64 ), flag ( float64, float64 ) );
+void
+ test_abz_float64(
+ float64 ( float64, float64 ), float64 ( float64, float64 ) );
+
+#ifdef FLOATX80
+
+void test_a_floatx80_z_int32( int32 ( floatx80 ), int32 ( floatx80 ) );
+#ifdef BITS64
+void test_a_floatx80_z_int64( int64 ( floatx80 ), int64 ( floatx80 ) );
+#endif
+void test_a_floatx80_z_float32( float32 ( floatx80 ), float32 ( floatx80 ) );
+void test_a_floatx80_z_float64( float64 ( floatx80 ), float64 ( floatx80 ) );
+#ifdef FLOAT128
+void
+ test_a_floatx80_z_float128( float128 ( floatx80 ), float128 ( floatx80 ) );
+#endif
+void test_az_floatx80( floatx80 ( floatx80 ), floatx80 ( floatx80 ) );
+void
+ test_ab_floatx80_z_flag(
+ flag ( floatx80, floatx80 ), flag ( floatx80, floatx80 ) );
+void
+ test_abz_floatx80(
+ floatx80 ( floatx80, floatx80 ), floatx80 ( floatx80, floatx80 ) );
+
+#endif
+
+#ifdef FLOAT128
+
+void test_a_float128_z_int32( int32 ( float128 ), int32 ( float128 ) );
+#ifdef BITS64
+void test_a_float128_z_int64( int64 ( float128 ), int64 ( float128 ) );
+#endif
+void test_a_float128_z_float32( float32 ( float128 ), float32 ( float128 ) );
+void test_a_float128_z_float64( float64 ( float128 ), float64 ( float128 ) );
+#ifdef FLOATX80
+void
+ test_a_float128_z_floatx80( floatx80 ( float128 ), floatx80 ( float128 ) );
+#endif
+void test_az_float128( float128 ( float128 ), float128 ( float128 ) );
+void
+ test_ab_float128_z_flag(
+ flag ( float128, float128 ), flag ( float128, float128 ) );
+void
+ test_abz_float128(
+ float128 ( float128, float128 ), float128 ( float128, float128 ) );
+
+#endif
+
diff --git a/tools/test/testfloat/testfloat-history.txt b/tools/test/testfloat/testfloat-history.txt
new file mode 100644
index 0000000..61520b3
--- /dev/null
+++ b/tools/test/testfloat/testfloat-history.txt
@@ -0,0 +1,57 @@
+
+History of Major Changes to TestFloat, up to Release 2a
+
+John R. Hauser
+1998 December 17
+
+
+The TestFloat releases parallel those of SoftFloat, on which TestFloat is
+based. Each TestFloat release also incorporates all bug fixes from the
+corresponding release of SoftFloat.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 2a (1998 December)
+
+-- Added support for testing conversions between floating-point and 64-bit
+ integers.
+
+-- Improved the makefiles.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 2 (1997 June)
+
+-- Integrated the generation of test cases and the checking of system
+ results into a single program. (Before they were separate programs,
+ normally joined by explicit command-line pipes.)
+
+-- Improved the sequence of test cases.
+
+-- Added support for testing extended double precision and quadruple
+ precision.
+
+-- Made program output more readable, and added new command arguments.
+
+-- Reduced dependence on the quality of the standard `random' function for
+ generating test cases. (Previously naively expected `random' to be able
+ to generate good random bits for the entire machine word width.)
+
+-- Created `testsoftfloat', with its own simpler complete software floating-
+ point (``slowfloat'') for comparison purposes.
+
+-- Made some changes to the source file structure, including renaming
+ `environment.h' to `milieu.h' (to avoid confusion with environment
+ variables).
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 1a (1996 July)
+
+-- Added the `-tininessbefore' and `-tininessafter' options to control
+ whether tininess should be detected before or after rounding.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 1 (1996 July)
+
+-- Original release.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
diff --git a/tools/test/testfloat/testfloat-source.txt b/tools/test/testfloat/testfloat-source.txt
new file mode 100644
index 0000000..b8f7e9b
--- /dev/null
+++ b/tools/test/testfloat/testfloat-source.txt
@@ -0,0 +1,444 @@
+
+TestFloat Release 2a Source Documentation
+
+John R. Hauser
+1998 December 16
+
+
+-------------------------------------------------------------------------------
+Introduction
+
+TestFloat is a program for testing that a floating-point implementation
+conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+All standard operations supported by the system can be tested, except for
+conversions to and from decimal. Any of the following machine formats can
+be tested: single precision, double precision, extended double precision,
+and/or quadruple precision. Testing extended double-precision or quadruple-
+precision formats requires a C compiler that supports 64-bit integer
+arithmetic.
+
+This document gives information needed for compiling and/or porting
+TestFloat.
+
+The source code for TestFloat is intended to be relatively machine-
+independent. TestFloat is written in C, and should be compilable using
+any ISO/ANSI C compiler. At the time of this writing, the program has
+been successfully compiled using the GNU C Compiler (`gcc') for several
+platforms. Because ISO/ANSI C does not provide access to some features
+of IEC/IEEE floating-point such as the exception flags, porting TestFloat
+unfortunately involves some machine-dependent coding.
+
+TestFloat depends on SoftFloat, which is a software implementation of
+floating-point that conforms to the IEC/IEEE Standard. SoftFloat is not
+included with the TestFloat sources. It can be obtained from the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
+
+In addition to a program for testing a machine's floating-point, the
+TestFloat package includes a variant for testing SoftFloat called
+`testsoftfloat'. The sources for both programs are intermixed, and both are
+described here.
+
+The first release of TestFloat (Release 1) was called _FloatTest_. The old
+name has been obsolete for some time.
+
+
+-------------------------------------------------------------------------------
+Limitations
+
+TestFloat as written requires an ISO/ANSI-style C compiler. No attempt has
+been made to accomodate compilers that are not ISO-conformant. Older ``K&R-
+style'' compilers are not adequate for compiling TestFloat. All testing I
+have done so far has been with the GNU C Compiler. Compilation with other
+compilers should be possible but has not been tested.
+
+The TestFloat sources assume that source code file names can be longer than
+8 characters. In order to compile under an MS-DOS-style system, many of the
+source files will need to be renamed, and the source and makefiles edited
+appropriately. Once compiled, the TestFloat program does not depend on the
+existence of long file names.
+
+The underlying machine is assumed to be binary with a word size that is a
+power of 2. Bytes are 8 bits. Testing of extended double-precision and
+quadruple-precision formats depends on the C compiler implementing a 64-bit
+integer type. If the largest integer type supported by the C compiler is
+32 bits, only single- and double-precision operations can be tested.
+
+
+-------------------------------------------------------------------------------
+Contents
+
+ Introduction
+ Limitations
+ Contents
+ Legal Notice
+ TestFloat Source Directory Structure
+ Target-Independent Modules
+ Target-Specific Modules
+ Target-Specific Header Files
+ processors/*.h
+ testfloat/*/milieu.h
+ Target-Specific Floating-Point Subroutines
+ Steps to Creating the TestFloat Executables
+ Improving the Random Number Generator
+ Contact Information
+
+
+
+-------------------------------------------------------------------------------
+Legal Notice
+
+TestFloat was written by John R. Hauser.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+
+-------------------------------------------------------------------------------
+TestFloat Source Directory Structure
+
+Because TestFloat is targeted to multiple platforms, its source code
+is slightly scattered between target-specific and target-independent
+directories and files. The directory structure is as follows:
+
+ processors
+ testfloat
+ templates
+ 386-Win32-gcc
+ SPARC-Solaris-gcc
+
+The two topmost directories and their contents are:
+
+ testfloat - Most of the source code needed for TestFloat.
+ processors - Target-specific header files that are not specific to
+ TestFloat.
+
+Within the `testfloat' directory are subdirectories for each of the
+targeted platforms. The TestFloat source code is distributed with targets
+`386-Win32-gcc' and `SPARC-Solaris-gcc' (and perhaps others) already
+prepared. These can be used as examples for porting to new targets. Source
+files that are not within these target-specific subdirectories are intended
+to be target-independent.
+
+The naming convention used for the target-specific directories is
+`<processor>-<executable-type>-<compiler>'. The names of the supplied
+target directories should be interpreted as follows:
+
+ <processor>:
+ 386 - Intel 386-compatible processor.
+ SPARC - SPARC processor (as used by Sun machines).
+ <executable-type>:
+ Win32 - Microsoft Win32 executable.
+ Solaris - Sun Solaris executable.
+ <compiler>:
+ gcc - GNU C Compiler.
+
+You do not need to maintain this convention if you do not want to.
+
+Alongside the supplied target-specific directories there is a `templates'
+directory containing a set of ``generic'' target-specific source files.
+A new target directory can be created by copying the `templates' directory
+and editing the files inside. (Complete instructions for porting TestFloat
+to a new target are in the section _Steps_to_Creating_the_TestFloat_
+_Executables_.) Note that the `templates' directory will not work as a
+target directory without some editing. To avoid confusion, it would be wise
+to refrain from editing the files inside `templates' directly.
+
+In addition to the distributed sources, TestFloat depends on the existence
+of an appropriately-compiled SoftFloat binary and the corresponding header
+file `softfloat.h'. SoftFloat is not included with the TestFloat sources.
+It can be obtained from the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/SoftFloat.html'.
+
+As distributed, the makefiles for TestFloat assume the existence of three
+sibling directories:
+
+ processors
+ softfloat
+ testfloat
+
+Only the `processors' and `testfloat' directories are included in the
+TestFloat package. The `softfloat' directory is assumed to contain a
+target-specific subdirectory within which the SoftFloat header file and
+compiled binary can be found. (See the source documentation accompanying
+SoftFloat.) The `processors' directory distributed with TestFloat is
+intended to be identical to that included with the SoftFloat source.
+
+These are the defaults, but other organizations of the sources are possible.
+The TestFloat makefiles and `milieu.h' files (see below) are easily edited
+to accomodate other arrangements.
+
+
+-------------------------------------------------------------------------------
+Target-Independent Modules
+
+The TestFloat program is composed of a number of modules, some target-
+specific and some target-independent. The target-independent modules are as
+follows:
+
+-- The `fail' module provides a common routine for writing an error message
+ and aborting.
+
+-- The `random' module generates random integer values.
+
+-- The `writeHex' module defines routines for writing the various types in
+ the hexadecimal form used by TestFloat.
+
+-- The `testCases' module generates test cases for the various types.
+
+-- The `testLoops' module contains various routines for exercising two
+ implementations of a function and reporting any differences observed.
+
+-- The `slowfloat' module provides the simple floating-point implementation
+ used by `testsoftfloat' for comparing against SoftFloat. The heart
+ of `slowfloat' is found in either `slowfloat-32' or `slowfloat-64',
+ depending on whether the `BITS64' macro is defined.
+
+-- The `systfloat' module gives a SoftFloat-like interface to the machine's
+ floating-point.
+
+-- The `testFunction' module implements `testfloat's main loop for testing a
+ function for all of the relevant rounding modes and rounding precisions.
+ (The `testsoftfloat' program contains its own version of this code.)
+
+-- The `testfloat' and `testsoftfloat' modules are the main modules for the
+ `testfloat' and `testsoftfloat' programs.
+
+Except possibly for `systfloat', these modules should not need to be
+modified.
+
+The `systfloat' module uses the floating-point operations of the C language
+to access a machine's floating-point. Unfortunately, some IEC/IEEE
+floating-point operations are not accessible within ISO/ANSI C. The
+following machine functions cannot be tested unless an alternate `systfloat'
+module is provided:
+
+ <float>_to_int32 (rounded according to rounding mode)
+ <float>_to_int64 (rounded according to rounding mode)
+ <float>_round_to_int
+ <float>_rem
+ <float>_sqrt, except float64_sqrt
+ <float>_eq_signaling
+ <float>_le_quiet
+ <float>_lt_quiet
+
+The `-list' option to `testfloat' will show the operations the program is
+prepared to test. The section _Target-Specific_Floating-Point_Subroutines_
+later in this document explains how to create a target-specific `systfloat'
+module to change the set of testable functions.
+
+
+-------------------------------------------------------------------------------
+Target-Specific Modules
+
+No target-specific modules are needed for `testsoftfloat'.
+
+The `testfloat' program uses two target-specific modules:
+
+-- The `systmodes' module defines functions for setting the modes
+ controlling the system's floating-point, including the rounding mode and
+ the rounding precision for extended double precision.
+
+-- The `systflags' module provides a function for clearing and examining the
+ system's floating-point exception flags.
+
+These modules must be supplied for each target. They can be implemented in
+any way desired, so long as all is reflected in the target's makefile. For
+the targets that come with the distributed source, each of these modules is
+implemented as a single assembly language or C language source file.
+
+
+-------------------------------------------------------------------------------
+Target-Specific Header Files
+
+The purpose of the two target-specific header files is detailed below.
+In the following, the `*' symbol is used in place of the name of a specific
+target, such as `386-Win32-gcc' or `SPARC-Solaris-gcc', or in place of some
+other text as explained below.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+processors/*.h
+
+The target-specific `processors' header file defines integer types
+of various sizes, and also defines certain C preprocessor macros that
+characterize the target. The two examples supplied are `386-gcc.h' and
+`SPARC-gcc.h'. The naming convention used for processor header files is
+`<processor>-<compiler>.h'. The `processors' header file used to compile
+TestFloat should be the same as that used to compile SoftFloat.
+
+If 64-bit integers are supported by the compiler, the macro name `BITS64'
+should be defined here along with the corresponding 64-bit integer
+types. In addition, the function-like macro `LIT64' must be defined for
+constructing 64-bit integer literals (constants). The `LIT64' macro is used
+consistently in the TestFloat code to annotate 64-bit literals.
+
+If an inlining attribute (such as an `inline' keyword) is provided by the
+compiler, the macro `INLINE' should be defined to the appropriate keyword.
+If not, `INLINE' can be set to the keyword `static'. The `INLINE' macro
+appears in the TestFloat source code before every function that should be
+inlined by the compiler.
+
+For maximum flexibility, the TestFloat source files do not include the
+`processors' header file directly; rather, this file is included by the
+target-specific `milieu.h' header, and `milieu.h' is included by the source
+files.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+testfloat/*/milieu.h
+
+The `milieu.h' header file provides declarations that are needed to
+compile TestFloat. In particular, it is through this header file that
+the appropriate `processors' header is included to characterize the target
+processor. In addition, deviations from ISO/ANSI C by the compiler (such as
+names not properly declared in system header files) are corrected in this
+header if possible.
+
+If the preprocessor macro `BITS64' is defined in the `processors' header
+file but only the 32-bit version of SoftFloat is actually used, the `BITS64'
+macro should be undefined here after the `processors' header has defined it.
+
+If the C compiler implements the `long double' floating-point type of C
+as extended double precision, then `LONG_DOUBLE_IS_FLOATX80' should be
+defined here. Alternatively, if the C `long double' type is implemented as
+quadruple precision, `LONG_DOUBLE_IS_FLOAT128' should be defined. At most
+one of these macros should be defined. A C compiler is allowed to implement
+`long double' the same as `double', in which case neither of these macros
+should be defined.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Target-Specific Floating-Point Subroutines
+
+This section applies only to `testfloat' and not to `testsoftfloat'.
+
+By default, TestFloat tests a machine's floating-point by testing the
+floating-point operations of the C language. Unfortunately, some IEC/IEEE
+floating-point operations are not defined within ISO/ANSI C. If a machine
+implements such ``non-C'' operations, target-specific subroutines for
+the operations can be supplied to allow TestFloat to test these machine
+features. Typically, such subroutines will need to be written in assembly
+language, although equivalent functions can sometimes be found among the
+system's software libraries.
+
+The following machine functions cannot be tested by TestFloat unless target-
+specific subroutines are supplied for them:
+
+ <float>_to_int32 (rounded according to rounding mode)
+ <float>_to_int64 (rounded according to rounding mode)
+ <float>_round_to_int
+ <float>_rem
+ <float>_sqrt, except float64_sqrt
+ <float>_eq_signaling
+ <float>_le_quiet
+ <float>_lt_quiet
+
+In addition to these, none of the `floatx80' functions can be tested by
+default if the C `long double' type is something other than extended double
+precision; and likewise, none of the `float128' functions can be tested by
+default if `long double' is not quadruple precision. Since `long double'
+cannot be both extended double precision and quadruple precision at the
+same time, at least one of these types cannot be tested by TestFloat without
+appropriate subroutines being supplied for that type. (On the other hand,
+few systems implement _both_ extended double-precision and quadruple-
+precision floating-point; and unless a system does implement both, it does
+not need both tested.)
+
+Note that the `-list' option to `testfloat' will show the operations
+TestFloat is prepared to test.
+
+TestFloat's `systfloat' module supplies the system version of the functions
+to be tested. The names of the `systfloat' subroutines are the same as the
+function names used as arguments to the `testfloat' command but with `syst_'
+prefixed--thus, for example, `syst_float32_add' and `syst_int32_to_float32'.
+The default `systfloat' module maps these system functions to the standard
+C operations; so `syst_float32_add', for example, is implemented using the
+C `+' operation for the single-precision `float' type. For each system
+function supplied by `systfloat', a corresponding `SYST_<function>'
+preprocessor macro is defined in `systfloat.h' to indicate that the function
+exists to be tested (e.g., `SYST_FLOAT32_ADD'). The `systfloat.h' header
+file also declares function prototypes for the `systfloat' functions.
+
+(The `systfloat.h' file that comes with the TestFloat package declares
+prototypes for all of the possible `systfloat' functions, whether defined in
+`systfloat' or not. There is no penalty for declaring a function prototype
+that is never used.)
+
+A target-specific version of the `systfloat' module can easily be created to
+replace the generic one. This in fact has been done for the example targets
+`386-Win32-gcc' and `SPARC-Solaris-gcc'. For each target, an assembly
+language `systfloat.S' has been created in the target directory along with
+a corresponding `systfloat.h' header file defining the `SYST_<function>'
+macros for the functions implemented. The makefiles of the targets have
+been edited to use these target-specific versions of `systfloat' rather than
+the generic one.
+
+The `systfloat' modules of the example targets have been written entirely
+in assembly language in order to bypass any peculiarities of the C compiler.
+Although this is probably a good idea, it is certainly not required.
+
+
+-------------------------------------------------------------------------------
+Steps to Creating the TestFloat Executables
+
+Porting and/or compiling TestFloat involves the following steps:
+
+1. Port SoftFloat and create a SoftFloat binary. (Refer to the
+ documentation accompanying SoftFloat.)
+
+2. If one does not already exist, create an appropriate target-specific
+ subdirectory under `testfloat' by copying the given `templates'
+ directory. The remaining steps occur within the target-specific
+ subdirectory.
+
+3. Edit the files `milieu.h' and `Makefile' to reflect the current
+ environment.
+
+4. Make `testsoftfloat' by executing `make testsoftfloat' (or `make
+ testsoftfloat.exe', or whatever the `testsoftfloat' executable is
+ called). Verify that SoftFloat is working correctly by testing it with
+ `testsoftfloat'.
+
+If you only wanted `testsoftfloat', you are done. The steps for `testfloat'
+continue:
+
+5. In the target-specific subdirectory, implement the `systmodes' and
+ `systflags' modules. (The `syst_float_set_rounding_precision' function
+ need not do anything if the system does not support extended double
+ precision.)
+
+6. If the target machine supports standard floating-point functions that are
+ not accessible within ISO/ANSI C, or if the C compiler cannot be trusted
+ to use the machine's floating-point directly, create a target-specific
+ `systfloat' module.
+
+7. In the target-specific subdirectory, execute `make'.
+
+
+-------------------------------------------------------------------------------
+Improving the Random Number Generator
+
+If you are serious about using TestFloat for testing floating-point, you
+should consider replacing the supplied `random.c' with a better target-
+specific one. The standard C `rand' function is rather poor on some
+systems, and consequently `random.c' has been written to assume very little
+about the quality of `rand'. As a result, the `rand' function is called
+more frequently than it might need to be, shortening the time before
+the random number generator repeats, and possibly wasting time as well.
+If `rand' is better on your system, or if another better random number
+generator is available (such as `rand48' on most Unix systems), TestFloat
+can be improved by overriding the given `random.c' with a target-specific
+one.
+
+
+-------------------------------------------------------------------------------
+Contact Information
+
+At the time of this writing, the most up-to-date information about
+TestFloat and the latest release can be found at the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+
diff --git a/tools/test/testfloat/testfloat.c b/tools/test/testfloat/testfloat.c
new file mode 100644
index 0000000..5a19d88
--- /dev/null
+++ b/tools/test/testfloat/testfloat.c
@@ -0,0 +1,299 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include "milieu.h"
+#include "fail.h"
+#include "softfloat.h"
+#include "testCases.h"
+#include "testLoops.h"
+#include "systflags.h"
+#include "testFunction.h"
+
+static void catchSIGINT( int signalCode )
+{
+
+ if ( stop ) exit( EXIT_FAILURE );
+ stop = TRUE;
+
+}
+
+int
+main( int argc, char **argv )
+{
+ char *argPtr;
+ flag functionArgument;
+ uint8 functionCode;
+ int8 operands, roundingPrecision, roundingMode;
+
+ fail_programName = "testfloat";
+ if ( argc <= 1 ) goto writeHelpMessage;
+ testCases_setLevel( 1 );
+ trueName = "soft";
+ testName = "syst";
+ errorStop = FALSE;
+ forever = FALSE;
+ maxErrorCount = 20;
+ trueFlagsPtr = &float_exception_flags;
+ testFlagsFunctionPtr = syst_float_flags_clear;
+ tininessModeName = 0;
+ functionArgument = FALSE;
+ functionCode = 0;
+ operands = 0;
+ roundingPrecision = 0;
+ roundingMode = 0;
+ --argc;
+ ++argv;
+ while ( argc && ( argPtr = argv[ 0 ] ) ) {
+ if ( argPtr[ 0 ] == '-' ) ++argPtr;
+ if ( strcmp( argPtr, "help" ) == 0 ) {
+ writeHelpMessage:
+ fputs(
+"testfloat [<option>...] <function>\n"
+" <option>: (* is default)\n"
+" -help --Write this message and exit.\n"
+" -list --List all testable functions and exit.\n"
+" -level <num> --Testing level <num> (1 or 2).\n"
+" * -level 1\n"
+" -errors <num> --Stop each function test after <num> errors.\n"
+" * -errors 20\n"
+" -errorstop --Exit after first function with any error.\n"
+" -forever --Test one function repeatedly (implies `-level 2').\n"
+" -checkNaNs --Check for bitwise correctness of NaN results.\n"
+#ifdef FLOATX80
+" -precision32 --Only test rounding precision equivalent to float32.\n"
+" -precision64 --Only test rounding precision equivalent to float64.\n"
+" -precision80 --Only test maximum rounding precision.\n"
+#endif
+" -nearesteven --Only test rounding to nearest/even.\n"
+" -tozero --Only test rounding to zero.\n"
+" -down --Only test rounding down.\n"
+" -up --Only test rounding up.\n"
+" -tininessbefore --Underflow tininess detected before rounding.\n"
+" -tininessafter --Underflow tininess detected after rounding.\n"
+" <function>:\n"
+" int32_to_<float> <float>_add <float>_eq\n"
+" <float>_to_int32 <float>_sub <float>_le\n"
+" <float>_to_int32_round_to_zero <float>_mul <float>_lt\n"
+#ifdef BITS64
+" int64_to_<float> <float>_div <float>_eq_signaling\n"
+" <float>_to_int64 <float>_rem <float>_le_quiet\n"
+" <float>_to_int64_round_to_zero <float>_lt_quiet\n"
+" <float>_to_<float>\n"
+" <float>_round_to_int\n"
+" <float>_sqrt\n"
+#else
+" <float>_to_<float> <float>_div <float>_eq_signaling\n"
+" <float>_round_to_int <float>_rem <float>_le_quiet\n"
+" <float>_sqrt <float>_lt_quiet\n"
+#endif
+" -all1 --All 1-operand functions.\n"
+" -all2 --All 2-operand functions.\n"
+" -all --All functions.\n"
+" <float>:\n"
+" float32 --Single precision.\n"
+" float64 --Double precision.\n"
+#ifdef FLOATX80
+" floatx80 --Extended double precision.\n"
+#endif
+#ifdef FLOAT128
+" float128 --Quadruple precision.\n"
+#endif
+ ,
+ stdout
+ );
+ return EXIT_SUCCESS;
+ }
+ else if ( strcmp( argPtr, "list" ) == 0 ) {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( functionExists[ functionCode ] ) {
+ puts( functions[ functionCode ].name );
+ }
+ }
+ return EXIT_SUCCESS;
+ }
+ else if ( strcmp( argPtr, "level" ) == 0 ) {
+ if ( argc < 2 ) goto optionError;
+ testCases_setLevel( atoi( argv[ 1 ] ) );
+ --argc;
+ ++argv;
+ }
+ else if ( strcmp( argPtr, "level1" ) == 0 ) {
+ testCases_setLevel( 1 );
+ }
+ else if ( strcmp( argPtr, "level2" ) == 0 ) {
+ testCases_setLevel( 2 );
+ }
+ else if ( strcmp( argPtr, "errors" ) == 0 ) {
+ if ( argc < 2 ) {
+ optionError:
+ fail( "`%s' option requires numeric argument", argv[ 0 ] );
+ }
+ maxErrorCount = atoi( argv[ 1 ] );
+ --argc;
+ ++argv;
+ }
+ else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
+ errorStop = TRUE;
+ }
+ else if ( strcmp( argPtr, "forever" ) == 0 ) {
+ testCases_setLevel( 2 );
+ forever = TRUE;
+ }
+ else if ( ( strcmp( argPtr, "checkNaNs" ) == 0 )
+ || ( strcmp( argPtr, "checknans" ) == 0 ) ) {
+ checkNaNs = TRUE;
+ }
+#ifdef FLOATX80
+ else if ( strcmp( argPtr, "precision32" ) == 0 ) {
+ roundingPrecision = 32;
+ }
+ else if ( strcmp( argPtr, "precision64" ) == 0 ) {
+ roundingPrecision = 64;
+ }
+ else if ( strcmp( argPtr, "precision80" ) == 0 ) {
+ roundingPrecision = 80;
+ }
+#endif
+ else if ( ( strcmp( argPtr, "nearesteven" ) == 0 )
+ || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
+ roundingMode = ROUND_NEAREST_EVEN;
+ }
+ else if ( ( strcmp( argPtr, "tozero" ) == 0 )
+ || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
+ roundingMode = ROUND_TO_ZERO;
+ }
+ else if ( strcmp( argPtr, "down" ) == 0 ) {
+ roundingMode = ROUND_DOWN;
+ }
+ else if ( strcmp( argPtr, "up" ) == 0 ) {
+ roundingMode = ROUND_UP;
+ }
+ else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
+ float_detect_tininess = float_tininess_before_rounding;
+ }
+ else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
+ float_detect_tininess = float_tininess_after_rounding;
+ }
+ else if ( strcmp( argPtr, "all1" ) == 0 ) {
+ functionArgument = TRUE;
+ functionCode = 0;
+ operands = 1;
+ }
+ else if ( strcmp( argPtr, "all2" ) == 0 ) {
+ functionArgument = TRUE;
+ functionCode = 0;
+ operands = 2;
+ }
+ else if ( strcmp( argPtr, "all" ) == 0 ) {
+ functionArgument = TRUE;
+ functionCode = 0;
+ operands = 0;
+ }
+ else {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
+ break;
+ }
+ }
+ if ( functionCode == NUM_FUNCTIONS ) {
+ fail( "Invalid option or function `%s'", argv[ 0 ] );
+ }
+ if ( ! functionExists[ functionCode ] ) {
+ fail(
+ "Function `%s' is not supported or cannot be tested",
+ argPtr
+ );
+ }
+ functionArgument = TRUE;
+ }
+ --argc;
+ ++argv;
+ }
+ if ( ! functionArgument ) fail( "Function argument required" );
+ (void) signal( SIGINT, catchSIGINT );
+ (void) signal( SIGTERM, catchSIGINT );
+ if ( functionCode ) {
+ if ( forever ) {
+ if ( ! roundingPrecision ) roundingPrecision = 80;
+ if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
+ }
+ testFunction( functionCode, roundingPrecision, roundingMode );
+ }
+ else {
+ if ( forever ) {
+ fail( "Can only test one function with `-forever' option" );
+ }
+ if ( operands == 1 ) {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( functionExists[ functionCode ]
+ && ( functions[ functionCode ].numInputs == 1 ) ) {
+ testFunction(
+ functionCode, roundingPrecision, roundingMode );
+ }
+ }
+ }
+ else if ( operands == 2 ) {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( functionExists[ functionCode ]
+ && ( functions[ functionCode ].numInputs == 2 ) ) {
+ testFunction(
+ functionCode, roundingPrecision, roundingMode );
+ }
+ }
+ }
+ else {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( functionExists[ functionCode ] ) {
+ testFunction(
+ functionCode, roundingPrecision, roundingMode );
+ }
+ }
+ }
+ }
+ exitWithStatus();
+
+}
+
diff --git a/tools/test/testfloat/testfloat.txt b/tools/test/testfloat/testfloat.txt
new file mode 100644
index 0000000..6e72c1d
--- /dev/null
+++ b/tools/test/testfloat/testfloat.txt
@@ -0,0 +1,771 @@
+
+TestFloat Release 2a General Documentation
+
+John R. Hauser
+1998 December 16
+
+
+-------------------------------------------------------------------------------
+Introduction
+
+TestFloat is a program for testing that a floating-point implementation
+conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+All standard operations supported by the system can be tested, except for
+conversions to and from decimal. Any of the following machine formats can
+be tested: single precision, double precision, extended double precision,
+and/or quadruple precision.
+
+TestFloat actually comes in two variants: one is a program for testing
+a machine's floating-point, and the other is a program for testing
+the SoftFloat software implementation of floating-point. (Information
+about SoftFloat can be found at the SoftFloat Web page, `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.) The version that
+tests SoftFloat is expected to be of interest only to people compiling the
+SoftFloat sources. However, because the two versions share much in common,
+they are discussed together in all the TestFloat documentation.
+
+This document explains how to use the TestFloat programs. It does not
+attempt to define or explain the IEC/IEEE Standard for floating-point.
+Details about the standard are available elsewhere.
+
+The first release of TestFloat (Release 1) was called _FloatTest_. The old
+name has been obsolete for some time.
+
+
+-------------------------------------------------------------------------------
+Limitations
+
+TestFloat's output is not always easily interpreted. Detailed knowledge
+of the IEC/IEEE Standard and its vagaries is needed to use TestFloat
+responsibly.
+
+TestFloat performs relatively simple tests designed to check the fundamental
+soundness of the floating-point under test. TestFloat may also at times
+manage to find rarer and more subtle bugs, but it will probably only find
+such bugs by accident. Software that purposefully seeks out various kinds
+of subtle floating-point bugs can be found through links posted on the
+TestFloat Web page (`http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/
+TestFloat.html').
+
+
+-------------------------------------------------------------------------------
+Contents
+
+ Introduction
+ Limitations
+ Contents
+ Legal Notice
+ What TestFloat Does
+ Executing TestFloat
+ Functions Tested by TestFloat
+ Conversion Functions
+ Standard Arithmetic Functions
+ Remainder and Round-to-Integer Functions
+ Comparison Functions
+ Interpreting TestFloat Output
+ Variations Allowed by the IEC/IEEE Standard
+ Underflow
+ NaNs
+ Conversions to Integer
+ TestFloat Options
+ -help
+ -list
+ -level <num>
+ -errors <num>
+ -errorstop
+ -forever
+ -checkNaNs
+ -precision32, -precision64, -precision80
+ -nearesteven, -tozero, -down, -up
+ -tininessbefore, -tininessafter
+ Function Sets
+ Contact Information
+
+
+
+-------------------------------------------------------------------------------
+Legal Notice
+
+TestFloat was written by John R. Hauser.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+
+-------------------------------------------------------------------------------
+What TestFloat Does
+
+TestFloat tests a system's floating-point by comparing its behavior with
+that of TestFloat's own internal floating-point implemented in software.
+For each operation tested, TestFloat generates a large number of test cases,
+made up of simple pattern tests intermixed with weighted random inputs.
+The cases generated should be adequate for testing carry chain propagations,
+plus the rounding of adds, subtracts, multiplies, and simple operations like
+conversions. TestFloat makes a point of checking all boundary cases of the
+arithmetic, including underflows, overflows, invalid operations, subnormal
+inputs, zeros (positive and negative), infinities, and NaNs. For the
+interesting operations like adds and multiplies, literally millions of test
+cases can be checked.
+
+TestFloat is not remarkably good at testing difficult rounding cases for
+divisions and square roots. It also makes no attempt to find bugs specific
+to SRT divisions and the like (such as the infamous Pentium divide bug).
+Software that tests for such failures can be found through links on the
+TestFloat Web page, `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/
+TestFloat.html'.
+
+NOTE!
+It is the responsibility of the user to verify that the discrepancies
+TestFloat finds actually represent faults in the system being tested.
+Advice to help with this task is provided later in this document.
+Furthermore, even if TestFloat finds no fault with a floating-point
+implementation, that in no way guarantees that the implementation is bug-
+free.
+
+For each operation, TestFloat can test all four rounding modes required
+by the IEC/IEEE Standard. TestFloat verifies not only that the numeric
+results of an operation are correct, but also that the proper floating-point
+exception flags are raised. All five exception flags are tested, including
+the inexact flag. TestFloat does not attempt to verify that the floating-
+point exception flags are actually implemented as sticky flags.
+
+For machines that implement extended double precision with rounding
+precision control (such as Intel's 80x86), TestFloat can test the add,
+subtract, multiply, divide, and square root functions at all the standard
+rounding precisions. The rounding precision can be set equivalent to single
+precision, to double precision, or to the full extended double precision.
+Rounding precision control can only be applied to the extended double-
+precision format and only for the five standard arithmetic operations: add,
+subtract, multiply, divide, and square root. Other functions can be tested
+only at full precision.
+
+As a rule, TestFloat is not particular about the bit patterns of NaNs that
+appear as function results. Any NaN is considered as good a result as
+another. This laxness can be overridden so that TestFloat checks for
+particular bit patterns within NaN results. See the sections _Variations_
+_Allowed_by_the_IEC/IEEE_Standard_ and _TestFloat_Options_ for details.
+
+Not all IEC/IEEE Standard functions are supported by all machines.
+TestFloat can only test functions that exist on the machine. But even if
+a function is supported by the machine, TestFloat may still not be able
+to test the function if it is not accessible through standard ISO C (the
+programming language in which TestFloat is written) and if the person who
+compiled TestFloat did not provide an alternate means for TestFloat to
+invoke the machine function.
+
+TestFloat compares a machine's floating-point against the SoftFloat software
+implementation of floating-point, also written by me. SoftFloat is built
+into the TestFloat executable and does not need to be supplied by the user.
+If SoftFloat is wanted for some other reason (to compile a new version
+of TestFloat, for instance), it can be found separately at the Web page
+`http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
+
+For testing SoftFloat itself, the TestFloat package includes a program that
+compares SoftFloat's floating-point against _another_ software floating-
+point implementation. The second software floating-point is simpler and
+slower than SoftFloat, and is completely independent of SoftFloat. Although
+the second software floating-point cannot be guaranteed to be bug-free, the
+chance that it would mimic any of SoftFloat's bugs is remote. Consequently,
+an error in one or the other floating-point version should appear as an
+unexpected discrepancy between the two implementations. Note that testing
+SoftFloat should only be necessary when compiling a new TestFloat executable
+or when compiling SoftFloat for some other reason.
+
+
+-------------------------------------------------------------------------------
+Executing TestFloat
+
+TestFloat is intended to be executed from a command line interpreter. The
+`testfloat' program is invoked as follows:
+
+ testfloat [<option>...] <function>
+
+Here square brackets ([]) indicate optional items, while angled brackets
+(<>) denote parameters to be filled in.
+
+The `<function>' argument is a name like `float32_add' or `float64_to_int32'.
+The complete list of function names is given in the next section,
+_Functions_Tested_by_TestFloat_. It is also possible to test all machine
+functions in a single invocation. The various options to TestFloat are
+detailed in the section _TestFloat_Options_ later in this document. If
+`testfloat' is executed without any arguments, a summary of TestFloat usage
+is written.
+
+TestFloat will ordinarily test a function for all four rounding modes, one
+after the other. If the rounding mode is not supposed to have any affect
+on the results--for instance, some operations do not require rounding--only
+the nearest/even rounding mode is checked. For extended double-precision
+operations affected by rounding precision control, TestFloat also tests all
+three rounding precision modes, one after the other. Testing can be limited
+to a single rounding mode and/or rounding precision with appropriate options
+(see _TestFloat_Options_).
+
+As it executes, TestFloat writes status information to the standard error
+output, which should be the screen by default. In order for this status to
+be displayed properly, the standard error stream should not be redirected
+to a file. The discrepancies TestFloat finds are written to the standard
+output stream, which is easily redirected to a file if desired. Ordinarily,
+the errors TestFloat reports and the ongoing status information appear
+intermixed on the same screen.
+
+The version of TestFloat for testing SoftFloat is called `testsoftfloat'.
+It is invoked the same as `testfloat',
+
+ testsoftfloat [<option>...] <function>
+
+and operates similarly.
+
+
+-------------------------------------------------------------------------------
+Functions Tested by TestFloat
+
+TestFloat tests all operations required by the IEC/IEEE Standard except for
+conversions to and from decimal. The operations are
+
+-- Conversions among the supported floating-point formats, and also between
+ integers (32-bit and 64-bit) and any of the floating-point formats.
+
+-- The usual add, subtract, multiply, divide, and square root operations
+ for all supported floating-point formats.
+
+-- For each format, the floating-point remainder operation defined by the
+ IEC/IEEE Standard.
+
+-- For each floating-point format, a ``round to integer'' operation that
+ rounds to the nearest integer value in the same format. (The floating-
+ point formats can hold integer values, of course.)
+
+-- Comparisons between two values in the same floating-point format.
+
+Detailed information about these functions is given below. In the function
+names used by TestFloat, single precision is called `float32', double
+precision is `float64', extended double precision is `floatx80', and
+quadruple precision is `float128'. TestFloat uses the same names for
+functions as SoftFloat.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Conversion Functions
+
+All conversions among the floating-point formats and all conversion between
+a floating-point format and 32-bit and 64-bit signed integers can be tested.
+The conversion functions are:
+
+ int32_to_float32 int64_to_float32
+ int32_to_float64 int64_to_float32
+ int32_to_floatx80 int64_to_floatx80
+ int32_to_float128 int64_to_float128
+
+ float32_to_int32 float32_to_int64
+ float32_to_int32 float64_to_int64
+ floatx80_to_int32 floatx80_to_int64
+ float128_to_int32 float128_to_int64
+
+ float32_to_float64 float32_to_floatx80 float32_to_float128
+ float64_to_float32 float64_to_floatx80 float64_to_float128
+ floatx80_to_float32 floatx80_to_float64 floatx80_to_float128
+ float128_to_float32 float128_to_float64 float128_to_floatx80
+
+These conversions all round according to the current rounding mode as
+necessary. Conversions from a smaller to a larger floating-point format are
+always exact and so require no rounding. Conversions from 32-bit integers
+to double precision or to any larger floating-point format are also exact,
+and likewise for conversions from 64-bit integers to extended double and
+quadruple precisions.
+
+ISO/ANSI C requires that conversions to integers be rounded toward zero.
+Such conversions can be tested with the following functions that ignore any
+rounding mode:
+
+ float32_to_int32_round_to_zero float32_to_int64_round_to_zero
+ float64_to_int32_round_to_zero float64_to_int64_round_to_zero
+ floatx80_to_int32_round_to_zero floatx80_to_int64_round_to_zero
+ float128_to_int32_round_to_zero float128_to_int64_round_to_zero
+
+TestFloat assumes that conversions from floating-point to integer should
+raise the invalid exception if the source value cannot be rounded to a
+representable integer of the desired size (32 or 64 bits). If such a
+conversion overflows, TestFloat expects the largest integer with the same
+sign as the operand to be returned. If the floating-point operand is a NaN,
+TestFloat allows either the largest postive or largest negative integer to
+be returned.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Standard Arithmetic Functions
+
+The following standard arithmetic functions can be tested:
+
+ float32_add float32_sub float32_mul float32_div float32_sqrt
+ float64_add float64_sub float64_mul float64_div float64_sqrt
+ floatx80_add floatx80_sub floatx80_mul floatx80_div floatx80_sqrt
+ float128_add float128_sub float128_mul float128_div float128_sqrt
+
+The extended double-precision (`floatx80') functions can be rounded to
+reduced precision under rounding precision control.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Remainder and Round-to-Integer Functions
+
+For each format, TestFloat can test the IEC/IEEE Standard remainder and
+round-to-integer functions. The remainder functions are:
+
+ float32_rem
+ float64_rem
+ floatx80_rem
+ float128_rem
+
+The round-to-integer functions are:
+
+ float32_round_to_int
+ float64_round_to_int
+ floatx80_round_to_int
+ float128_round_to_int
+
+The remainder functions are always exact and so do not require rounding.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Comparison Functions
+
+The following floating-point comparison functions can be tested:
+
+ float32_eq float32_le float32_lt
+ float64_eq float64_le float64_lt
+ floatx80_eq floatx80_le floatx80_lt
+ float128_eq float128_le float128_lt
+
+The abbreviation `eq' stands for ``equal'' (=); `le' stands for ``less than
+or equal'' (<=); and `lt' stands for ``less than'' (<).
+
+The IEC/IEEE Standard specifies that the less-than-or-equal and less-than
+functions raise the invalid exception if either input is any kind of NaN.
+The equal functions, for their part, are defined not to raise the invalid
+exception on quiet NaNs. For completeness, the following additional
+functions can be tested if supported:
+
+ float32_eq_signaling float32_le_quiet float32_lt_quiet
+ float64_eq_signaling float64_le_quiet float64_lt_quiet
+ floatx80_eq_signaling floatx80_le_quiet floatx80_lt_quiet
+ float128_eq_signaling float128_le_quiet float128_lt_quiet
+
+The `signaling' equal functions are identical to the standard functions
+except that the invalid exception should be raised for any NaN input.
+Likewise, the `quiet' comparison functions should be identical to their
+counterparts except that the invalid exception is not raised for quiet NaNs.
+
+Obviously, no comparison functions ever require rounding. Any rounding mode
+is ignored.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Interpreting TestFloat Output
+
+The ``errors'' reported by TestFloat may or may not really represent errors
+in the system being tested. For each test case tried, TestFloat performs
+the same floating-point operation for the two implementations being compared
+and reports any unexpected difference in the results. The two results could
+differ for several reasons:
+
+-- The IEC/IEEE Standard allows for some variation in how conforming
+ floating-point behaves. Two implementations can occasionally give
+ different results without either being incorrect.
+
+-- The trusted floating-point emulation could be faulty. This could be
+ because there is a bug in the way the enulation is coded, or because a
+ mistake was made when the code was compiled for the current system.
+
+-- TestFloat may not work properly, reporting discrepancies that do not
+ exist.
+
+-- Lastly, the floating-point being tested could actually be faulty.
+
+It is the responsibility of the user to determine the causes for the
+discrepancies TestFloat reports. Making this determination can require
+detailed knowledge about the IEC/IEEE Standard. Assuming TestFloat is
+working properly, any differences found will be due to either the first or
+last of these reasons. Variations in the IEC/IEEE Standard that could lead
+to false error reports are discussed in the section _Variations_Allowed_by_
+_the_IEC/IEEE_Standard_.
+
+For each error (or apparent error) TestFloat reports, a line of text
+is written to the default output. If a line would be longer than 79
+characters, it is divided. The first part of each error line begins in the
+leftmost column, and any subsequent ``continuation'' lines are indented with
+a tab.
+
+Each error reported by `testfloat' is of the form:
+
+ <inputs> soft: <output-from-emulation> syst: <output-from-system>
+
+The `<inputs>' are the inputs to the operation. Each output is shown as a
+pair: the result value first, followed by the exception flags. The `soft'
+label stands for ``software'' (or ``SoftFloat''), while `syst' stands for
+``system,'' the machine's floating-point.
+
+For example, two typical error lines could be
+
+ 800.7FFF00 87F.000100 soft: 001.000000 ....x syst: 001.000000 ...ux
+ 081.000004 000.1FFFFF soft: 001.000000 ....x syst: 001.000000 ...ux
+
+In the first line, the inputs are `800.7FFF00' and `87F.000100'. The
+internal emulation result is `001.000000' with flags `....x', and the
+system result is the same but with flags `...ux'. All the items composed of
+hexadecimal digits and a single period represent floating-point values (here
+single precision). These cases were reported as errors because the flag
+results differ.
+
+In addition to the exception flags, there are seven data types that may
+be represented. Four are floating-point types: single precision, double
+precision, extended double precision, and quadruple precision. The
+remaining three types are 32-bit and 64-bit two's-complement integers and
+Boolean values (the results of comparison operations). Boolean values are
+represented as a single character, either a `0' or a `1'. 32-bit integers
+are written as 8 hexadecimal digits in two's-complement form. Thus,
+`FFFFFFFF' is -1, and `7FFFFFFF' is the largest positive 32-bit integer.
+64-bit integers are the same except with 16 hexadecimal digits.
+
+Floating-point values are written in a correspondingly primitive form.
+Double-precision values are represented by 16 hexadecimal digits that give
+the raw bits of the floating-point encoding. A period separates the 3rd and
+4th hexadecimal digits to mark the division between the exponent bits and
+fraction bits. Some notable double-precision values include:
+
+ 000.0000000000000 +0
+ 3FF.0000000000000 1
+ 400.0000000000000 2
+ 7FF.0000000000000 +infinity
+
+ 800.0000000000000 -0
+ BFF.0000000000000 -1
+ C00.0000000000000 -2
+ FFF.0000000000000 -infinity
+
+ 3FE.FFFFFFFFFFFFF largest representable number preceding +1
+
+The following categories are easily distinguished (assuming the `x's are not
+all 0):
+
+ 000.xxxxxxxxxxxxx positive subnormal (denormalized) numbers
+ 7FF.xxxxxxxxxxxxx positive NaNs
+ 800.xxxxxxxxxxxxx negative subnormal numbers
+ FFF.xxxxxxxxxxxxx negative NaNs
+
+Quadruple-precision values are written the same except with 4 hexadecimal
+digits for the sign and exponent and 28 for the fraction. Notable values
+include:
+
+ 0000.0000000000000000000000000000 +0
+ 3FFF.0000000000000000000000000000 1
+ 4000.0000000000000000000000000000 2
+ 7FFF.0000000000000000000000000000 +infinity
+
+ 8000.0000000000000000000000000000 -0
+ BFFF.0000000000000000000000000000 -1
+ C000.0000000000000000000000000000 -2
+ FFFF.0000000000000000000000000000 -infinity
+
+ 3FFE.FFFFFFFFFFFFFFFFFFFFFFFFFFFF largest representable number
+ preceding +1
+
+Extended double-precision values are a little unusual in that the leading
+significand bit is not hidden as with other formats. When correctly
+encoded, the leading significand bit of an extended double-precision value
+will be 0 if the value is zero or subnormal, and will be 1 otherwise.
+Hence, the same values listed above appear in extended double-precision as
+follows (note the leading `8' digit in the significands):
+
+ 0000.0000000000000000 +0
+ 3FFF.8000000000000000 1
+ 4000.8000000000000000 2
+ 7FFF.8000000000000000 +infinity
+
+ 8000.0000000000000000 -0
+ BFFF.8000000000000000 -1
+ C000.8000000000000000 -2
+ FFFF.8000000000000000 -infinity
+
+ 3FFE.FFFFFFFFFFFFFFFF largest representable number preceding +1
+
+The representation of single-precision values is unusual for a different
+reason. Because the subfields of standard single-precision do not fall
+on neat 4-bit boundaries, single-precision outputs are slightly perturbed.
+These are written as 9 hexadecimal digits, with a period separating the 3rd
+and 4th hexadecimal digits. Broken out into bits, the 9 hexademical digits
+cover the single-precision subfields as follows:
+
+ x000 .... .... . .... .... .... .... .... .... sign (1 bit)
+ .... xxxx xxxx . .... .... .... .... .... .... exponent (8 bits)
+ .... .... .... . 0xxx xxxx xxxx xxxx xxxx xxxx fraction (23 bits)
+
+As shown in this schematic, the first hexadecimal digit contains only
+the sign, and will be either `0' or `8'. The next two digits give the
+biased exponent as an 8-bit integer. This is followed by a period and
+6 hexadecimal digits of fraction. The most significant hexadecimal digit
+of the fraction can be at most a `7'.
+
+Notable single-precision values include:
+
+ 000.000000 +0
+ 07F.000000 1
+ 080.000000 2
+ 0FF.000000 +infinity
+
+ 800.000000 -0
+ 87F.000000 -1
+ 880.000000 -2
+ 8FF.000000 -infinity
+
+ 07E.7FFFFF largest representable number preceding +1
+
+Again, certain categories are easily distinguished (assuming the `x's are
+not all 0):
+
+ 000.xxxxxx positive subnormal (denormalized) numbers
+ 0FF.xxxxxx positive NaNs
+ 800.xxxxxx negative subnormal numbers
+ 8FF.xxxxxx negative NaNs
+
+Lastly, exception flag values are represented by five characters, one
+character per flag. Each flag is written as either a letter or a period
+(`.') according to whether the flag was set or not by the operation. A
+period indicates the flag was not set. The letter used to indicate a set
+flag depends on the flag:
+
+ v invalid flag
+ z division-by-zero flag
+ o overflow flag
+ u underflow flag
+ x inexact flag
+
+For example, the notation `...ux' indicates that the underflow and inexact
+exception flags were set and that the other three flags (invalid, division-
+by-zero, and overflow) were not set. The exception flags are always shown
+following the value returned as the result of the operation.
+
+The output from `testsoftfloat' is of the same form, except that the results
+are labeled `true' and `soft':
+
+ <inputs> true: <simple-software-result> soft: <SoftFloat-result>
+
+The ``true'' result is from the simpler, slower software floating-point,
+which, although not necessarily correct, is more likely to be right than
+the SoftFloat (`soft') result.
+
+
+-------------------------------------------------------------------------------
+Variations Allowed by the IEC/IEEE Standard
+
+The IEC/IEEE Standard admits some variation among conforming
+implementations. Because TestFloat expects the two implementations being
+compared to deliver bit-for-bit identical results under most circumstances,
+this leeway in the standard can result in false errors being reported if
+the two implementations do not make the same choices everywhere the standard
+provides an option.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Underflow
+
+The standard specifies that the underflow exception flag is to be raised
+when two conditions are met simultaneously: (1) _tininess_ and (2) _loss_
+_of_accuracy_. A result is tiny when its magnitude is nonzero yet smaller
+than any normalized floating-point number. The standard allows tininess to
+be determined either before or after a result is rounded to the destination
+precision. If tininess is detected before rounding, some borderline cases
+will be flagged as underflows even though the result after rounding actually
+lies within the normal floating-point range. By detecting tininess after
+rounding, a system can avoid some unnecessary signaling of underflow.
+
+Loss of accuracy occurs when the subnormal format is not sufficient
+to represent an underflowed result accurately. The standard allows
+loss of accuracy to be detected either as an _inexact_result_ or as a
+_denormalization_loss_. If loss of accuracy is detected as an inexact
+result, the underflow flag is raised whenever an underflowed quantity
+cannot be exactly represented in the subnormal format (that is, whenever the
+inexact flag is also raised). A denormalization loss, on the other hand,
+occurs only when the subnormal format is not able to represent the result
+that would have been returned if the destination format had infinite range.
+Some underflowed results are inexact but do not suffer a denormalization
+loss. By detecting loss of accuracy as a denormalization loss, a system can
+once again avoid some unnecessary signaling of underflow.
+
+The `-tininessbefore' and `-tininessafter' options can be used to control
+whether TestFloat expects tininess on underflow to be detected before or
+after rounding. (See _TestFloat_Options_ below.) One or the other is
+selected as the default when TestFloat is compiled, but these command
+options allow the default to be overridden.
+
+Most (possibly all) systems detect loss of accuracy as an inexact result.
+The current version of TestFloat can only test for this case.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+NaNs
+
+The IEC/IEEE Standard gives the floating-point formats a large number of
+NaN encodings and specifies that NaNs are to be returned as results under
+certain conditions. However, the standard allows an implementation almost
+complete freedom over _which_ NaN to return in each situation.
+
+By default, TestFloat does not check the bit patterns of NaN results. When
+the result of an operation should be a NaN, any NaN is considered as good
+as another. This laxness can be overridden with the `-checkNaNs' option.
+(See _TestFloat_Options_ below.) In order for this option to be sensible,
+TestFloat must have been compiled so that its internal floating-point
+implementation (SoftFloat) generates the proper NaN results for the system
+being tested.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Conversions to Integer
+
+Conversion of a floating-point value to an integer format will fail if the
+source value is a NaN or if it is too large. The IEC/IEEE Standard does not
+specify what value should be returned as the integer result in these cases.
+Moreover, according to the standard, the invalid exception can be raised or
+an unspecified alternative mechanism may be used to signal such cases.
+
+TestFloat assumes that conversions to integer will raise the invalid
+exception if the source value cannot be rounded to a representable integer.
+When the conversion overflows, TestFloat expects the largest integer with
+the same sign as the operand to be returned. If the floating-point operand
+is a NaN, TestFloat allows either the largest postive or largest negative
+integer to be returned. The current version of TestFloat provides no means
+to alter these conventions.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+TestFloat Options
+
+The `testfloat' (and `testsoftfloat') program accepts several command
+options. If mutually contradictory options are given, the last one has
+priority.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-help
+
+The `-help' option causes a summary of program usage to be written, after
+which the program exits.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-list
+
+The `-list' option causes a list of testable functions to be written,
+after which the program exits. Some machines do not implement all of the
+functions TestFloat can test, plus it may not be possible to test functions
+that are inaccessible from the C language.
+
+The `testsoftfloat' program does not have this option. All SoftFloat
+functions can be tested by `testsoftfloat'.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-level <num>
+
+The `-level' option sets the level of testing. The argument to `-level' can
+be either 1 or 2. The default is level 1. Level 2 performs many more tests
+than level 1. Testing at level 2 can take as much as a day (even longer for
+`testsoftfloat'), but can reveal bugs not found by level 1.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-errors <num>
+
+The `-errors' option instructs TestFloat to report no more than the
+specified number of errors for any combination of function, rounding mode,
+etc. The argument to `-errors' must be a nonnegative decimal number. Once
+the specified number of error reports has been generated, TestFloat ends the
+current test and begins the next one, if any. The default is `-errors 20'.
+
+Against intuition, `-errors 0' causes TestFloat to report every error it
+finds.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-errorstop
+
+The `-errorstop' option causes the program to exit after the first function
+for which any errors are reported.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-forever
+
+The `-forever' option causes a single operation to be repeatedly tested.
+Only one rounding mode and/or rounding precision can be tested in a single
+invocation. If not specified, the rounding mode defaults to nearest/even.
+For extended double-precision operations, the rounding precision defaults
+to full extended double precision. The testing level is set to 2 by this
+option.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-checkNaNs
+
+The `-checkNaNs' option causes TestFloat to verify the bitwise correctness
+of NaN results. In order for this option to be sensible, TestFloat must
+have been compiled so that its internal floating-point implementation
+(SoftFloat) generates the proper NaN results for the system being tested.
+
+This option is not available to `testsoftfloat'.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-precision32, -precision64, -precision80
+
+For extended double-precision functions affected by rounding precision
+control, the `-precision32' option restricts testing to only the cases
+in which rounding precision is equivalent to single precision. The other
+rounding precision options are not tested. Likewise, the `-precision64'
+and `-precision80' options fix the rounding precision equivalent to double
+precision or extended double precision, respectively. These options are
+ignored for functions not affected by rounding precision control.
+
+These options are not available if extended double precision is not
+supported by the machine or if extended double precision functions cannot be
+tested.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-nearesteven, -tozero, -down, -up
+
+The `-nearesteven' option restricts testing to only the cases in which the
+rounding mode is nearest/even. The other rounding mode options are not
+tested. Likewise, `-tozero' forces rounding to zero; `-down' forces
+rounding down; and `-up' forces rounding up. These options are ignored for
+functions that are exact and thus do not round.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-tininessbefore, -tininessafter
+
+The `-tininessbefore' option indicates that the system detects tininess
+on underflow before rounding. The `-tininessafter' option indicates that
+tininess is detected after rounding. TestFloat alters its expectations
+accordingly. These options override the default selected when TestFloat was
+compiled. Choosing the wrong one of these two options should cause error
+reports for some (not all) functions.
+
+For `testsoftfloat', these options operate more like the rounding precision
+and rounding mode options, in that they restrict the tests performed by
+`testsoftfloat'. By default, `testsoftfloat' tests both cases for any
+function for which there is a difference.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Function Sets
+
+Just as TestFloat can test an operation for all four rounding modes in
+sequence, multiple operations can be tested with a single invocation of
+TestFloat. Three sets are recognized: `-all1', `-all2', and `-all'. The
+set `-all1' comprises all one-operand functions; `-all2' is all two-operand
+functions; and `-all' is all functions. A function set can be used in place
+of a function name in the TestFloat command line, such as
+
+ testfloat [<option>...] -all
+
+
+-------------------------------------------------------------------------------
+Contact Information
+
+At the time of this writing, the most up-to-date information about
+TestFloat and the latest release can be found at the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+
diff --git a/tools/test/testfloat/testsoftfloat.c b/tools/test/testfloat/testsoftfloat.c
new file mode 100644
index 0000000..2689ee3
--- /dev/null
+++ b/tools/test/testfloat/testsoftfloat.c
@@ -0,0 +1,1044 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include "milieu.h"
+#include "fail.h"
+#include "softfloat.h"
+#include "slowfloat.h"
+#include "testCases.h"
+#include "testLoops.h"
+
+static void catchSIGINT( int signalCode )
+{
+
+ if ( stop ) exit( EXIT_FAILURE );
+ stop = TRUE;
+
+}
+
+int8 clearFlags( void )
+{
+ int8 flags;
+
+ flags = float_exception_flags;
+ float_exception_flags = 0;
+ return flags;
+
+}
+
+enum {
+ INT32_TO_FLOAT32 = 1,
+ INT32_TO_FLOAT64,
+#ifdef FLOATX80
+ INT32_TO_FLOATX80,
+#endif
+#ifdef FLOAT128
+ INT32_TO_FLOAT128,
+#endif
+#ifdef BITS64
+ INT64_TO_FLOAT32,
+ INT64_TO_FLOAT64,
+#ifdef FLOATX80
+ INT64_TO_FLOATX80,
+#endif
+#ifdef FLOAT128
+ INT64_TO_FLOAT128,
+#endif
+#endif
+ FLOAT32_TO_INT32,
+ FLOAT32_TO_INT32_ROUND_TO_ZERO,
+#ifdef BITS64
+ FLOAT32_TO_INT64,
+ FLOAT32_TO_INT64_ROUND_TO_ZERO,
+#endif
+ FLOAT32_TO_FLOAT64,
+#ifdef FLOATX80
+ FLOAT32_TO_FLOATX80,
+#endif
+#ifdef FLOAT128
+ FLOAT32_TO_FLOAT128,
+#endif
+ FLOAT32_ROUND_TO_INT,
+ FLOAT32_ADD,
+ FLOAT32_SUB,
+ FLOAT32_MUL,
+ FLOAT32_DIV,
+ FLOAT32_REM,
+ FLOAT32_SQRT,
+ FLOAT32_EQ,
+ FLOAT32_LE,
+ FLOAT32_LT,
+ FLOAT32_EQ_SIGNALING,
+ FLOAT32_LE_QUIET,
+ FLOAT32_LT_QUIET,
+ FLOAT64_TO_INT32,
+ FLOAT64_TO_INT32_ROUND_TO_ZERO,
+#ifdef BITS64
+ FLOAT64_TO_INT64,
+ FLOAT64_TO_INT64_ROUND_TO_ZERO,
+#endif
+ FLOAT64_TO_FLOAT32,
+#ifdef FLOATX80
+ FLOAT64_TO_FLOATX80,
+#endif
+#ifdef FLOAT128
+ FLOAT64_TO_FLOAT128,
+#endif
+ FLOAT64_ROUND_TO_INT,
+ FLOAT64_ADD,
+ FLOAT64_SUB,
+ FLOAT64_MUL,
+ FLOAT64_DIV,
+ FLOAT64_REM,
+ FLOAT64_SQRT,
+ FLOAT64_EQ,
+ FLOAT64_LE,
+ FLOAT64_LT,
+ FLOAT64_EQ_SIGNALING,
+ FLOAT64_LE_QUIET,
+ FLOAT64_LT_QUIET,
+#ifdef FLOATX80
+ FLOATX80_TO_INT32,
+ FLOATX80_TO_INT32_ROUND_TO_ZERO,
+#ifdef BITS64
+ FLOATX80_TO_INT64,
+ FLOATX80_TO_INT64_ROUND_TO_ZERO,
+#endif
+ FLOATX80_TO_FLOAT32,
+ FLOATX80_TO_FLOAT64,
+#ifdef FLOAT128
+ FLOATX80_TO_FLOAT128,
+#endif
+ FLOATX80_ROUND_TO_INT,
+ FLOATX80_ADD,
+ FLOATX80_SUB,
+ FLOATX80_MUL,
+ FLOATX80_DIV,
+ FLOATX80_REM,
+ FLOATX80_SQRT,
+ FLOATX80_EQ,
+ FLOATX80_LE,
+ FLOATX80_LT,
+ FLOATX80_EQ_SIGNALING,
+ FLOATX80_LE_QUIET,
+ FLOATX80_LT_QUIET,
+#endif
+#ifdef FLOAT128
+ FLOAT128_TO_INT32,
+ FLOAT128_TO_INT32_ROUND_TO_ZERO,
+#ifdef BITS64
+ FLOAT128_TO_INT64,
+ FLOAT128_TO_INT64_ROUND_TO_ZERO,
+#endif
+ FLOAT128_TO_FLOAT32,
+ FLOAT128_TO_FLOAT64,
+#ifdef FLOATX80
+ FLOAT128_TO_FLOATX80,
+#endif
+ FLOAT128_ROUND_TO_INT,
+ FLOAT128_ADD,
+ FLOAT128_SUB,
+ FLOAT128_MUL,
+ FLOAT128_DIV,
+ FLOAT128_REM,
+ FLOAT128_SQRT,
+ FLOAT128_EQ,
+ FLOAT128_LE,
+ FLOAT128_LT,
+ FLOAT128_EQ_SIGNALING,
+ FLOAT128_LE_QUIET,
+ FLOAT128_LT_QUIET,
+#endif
+ NUM_FUNCTIONS
+};
+static struct {
+ char *name;
+ int8 numInputs;
+ flag roundingPrecision, roundingMode;
+ flag tininessMode, tininessModeAtReducedPrecision;
+} functions[ NUM_FUNCTIONS ] = {
+ { 0, 0, 0, 0, 0, 0 },
+ { "int32_to_float32", 1, FALSE, TRUE, FALSE, FALSE },
+ { "int32_to_float64", 1, FALSE, FALSE, FALSE, FALSE },
+#ifdef FLOATX80
+ { "int32_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+#ifdef FLOAT128
+ { "int32_to_float128", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+#ifdef BITS64
+ { "int64_to_float32", 1, FALSE, TRUE, FALSE, FALSE },
+ { "int64_to_float64", 1, FALSE, TRUE, FALSE, FALSE },
+#ifdef FLOATX80
+ { "int64_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+#ifdef FLOAT128
+ { "int64_to_float128", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+#endif
+ { "float32_to_int32", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float32_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#ifdef BITS64
+ { "float32_to_int64", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float32_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "float32_to_float64", 1, FALSE, FALSE, FALSE, FALSE },
+#ifdef FLOATX80
+ { "float32_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+#ifdef FLOAT128
+ { "float32_to_float128", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "float32_round_to_int", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float32_add", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float32_sub", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float32_mul", 2, FALSE, TRUE, TRUE, FALSE },
+ { "float32_div", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float32_rem", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float32_sqrt", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float32_eq", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float32_le", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float32_lt", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float32_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float32_le_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float32_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_to_int32", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float64_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#ifdef BITS64
+ { "float64_to_int64", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float64_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "float64_to_float32", 1, FALSE, TRUE, TRUE, FALSE },
+#ifdef FLOATX80
+ { "float64_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+#ifdef FLOAT128
+ { "float64_to_float128", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "float64_round_to_int", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float64_add", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float64_sub", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float64_mul", 2, FALSE, TRUE, TRUE, FALSE },
+ { "float64_div", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float64_rem", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_sqrt", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float64_eq", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_le", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_lt", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_le_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float64_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+#ifdef FLOATX80
+ { "floatx80_to_int32", 1, FALSE, TRUE, FALSE, FALSE },
+ { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#ifdef BITS64
+ { "floatx80_to_int64", 1, FALSE, TRUE, FALSE, FALSE },
+ { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "floatx80_to_float32", 1, FALSE, TRUE, TRUE, FALSE },
+ { "floatx80_to_float64", 1, FALSE, TRUE, TRUE, FALSE },
+#ifdef FLOAT128
+ { "floatx80_to_float128", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "floatx80_round_to_int", 1, FALSE, TRUE, FALSE, FALSE },
+ { "floatx80_add", 2, TRUE, TRUE, FALSE, TRUE },
+ { "floatx80_sub", 2, TRUE, TRUE, FALSE, TRUE },
+ { "floatx80_mul", 2, TRUE, TRUE, TRUE, TRUE },
+ { "floatx80_div", 2, TRUE, TRUE, FALSE, TRUE },
+ { "floatx80_rem", 2, FALSE, FALSE, FALSE, FALSE },
+ { "floatx80_sqrt", 1, TRUE, TRUE, FALSE, FALSE },
+ { "floatx80_eq", 2, FALSE, FALSE, FALSE, FALSE },
+ { "floatx80_le", 2, FALSE, FALSE, FALSE, FALSE },
+ { "floatx80_lt", 2, FALSE, FALSE, FALSE, FALSE },
+ { "floatx80_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE },
+ { "floatx80_le_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+ { "floatx80_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+#endif
+#ifdef FLOAT128
+ { "float128_to_int32", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float128_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#ifdef BITS64
+ { "float128_to_int64", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float128_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
+#endif
+ { "float128_to_float32", 1, FALSE, TRUE, TRUE, FALSE },
+ { "float128_to_float64", 1, FALSE, TRUE, TRUE, FALSE },
+#ifdef FLOATX80
+ { "float128_to_floatx80", 1, FALSE, TRUE, TRUE, FALSE },
+#endif
+ { "float128_round_to_int", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float128_add", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float128_sub", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float128_mul", 2, FALSE, TRUE, TRUE, FALSE },
+ { "float128_div", 2, FALSE, TRUE, FALSE, FALSE },
+ { "float128_rem", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float128_sqrt", 1, FALSE, TRUE, FALSE, FALSE },
+ { "float128_eq", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float128_le", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float128_lt", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float128_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float128_le_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+ { "float128_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE },
+#endif
+};
+
+enum {
+ ROUND_NEAREST_EVEN = 1,
+ ROUND_TO_ZERO,
+ ROUND_DOWN,
+ ROUND_UP,
+ NUM_ROUNDINGMODES
+};
+enum {
+ TININESS_BEFORE_ROUNDING = 1,
+ TININESS_AFTER_ROUNDING,
+ NUM_TININESSMODES
+};
+
+static void
+ testFunctionVariety(
+ uint8 functionCode,
+ int8 roundingPrecision,
+ int8 roundingMode,
+ int8 tininessMode
+ )
+{
+ uint8 roundingCode;
+ int8 tininessCode;
+
+ functionName = functions[ functionCode ].name;
+ if ( roundingPrecision == 32 ) {
+ roundingPrecisionName = "32";
+ }
+ else if ( roundingPrecision == 64 ) {
+ roundingPrecisionName = "64";
+ }
+ else if ( roundingPrecision == 80 ) {
+ roundingPrecisionName = "80";
+ }
+ else {
+ roundingPrecisionName = 0;
+ }
+#ifdef FLOATX80
+ floatx80_rounding_precision = roundingPrecision;
+ slow_floatx80_rounding_precision = roundingPrecision;
+#endif
+ switch ( roundingMode ) {
+ default:
+ roundingModeName = 0;
+ roundingCode = float_round_nearest_even;
+ break;
+ case ROUND_NEAREST_EVEN:
+ roundingModeName = "nearest_even";
+ roundingCode = float_round_nearest_even;
+ break;
+ case ROUND_TO_ZERO:
+ roundingModeName = "to_zero";
+ roundingCode = float_round_to_zero;
+ break;
+ case ROUND_DOWN:
+ roundingModeName = "down";
+ roundingCode = float_round_down;
+ break;
+ case ROUND_UP:
+ roundingModeName = "up";
+ roundingCode = float_round_up;
+ break;
+ }
+ float_rounding_mode = roundingCode;
+ slow_float_rounding_mode = roundingCode;
+ switch ( tininessMode ) {
+ default:
+ tininessModeName = 0;
+ tininessCode = float_tininess_after_rounding;
+ break;
+ case TININESS_BEFORE_ROUNDING:
+ tininessModeName = "before";
+ tininessCode = float_tininess_before_rounding;
+ break;
+ case TININESS_AFTER_ROUNDING:
+ tininessModeName = "after";
+ tininessCode = float_tininess_after_rounding;
+ break;
+ }
+ float_detect_tininess = tininessCode;
+ slow_float_detect_tininess = tininessCode;
+ fputs( "Testing ", stderr );
+ writeFunctionName( stderr );
+ fputs( ".\n", stderr );
+ switch ( functionCode ) {
+ case INT32_TO_FLOAT32:
+ test_a_int32_z_float32( slow_int32_to_float32, int32_to_float32 );
+ break;
+ case INT32_TO_FLOAT64:
+ test_a_int32_z_float64( slow_int32_to_float64, int32_to_float64 );
+ break;
+#ifdef FLOATX80
+ case INT32_TO_FLOATX80:
+ test_a_int32_z_floatx80( slow_int32_to_floatx80, int32_to_floatx80 );
+ break;
+#endif
+#ifdef FLOAT128
+ case INT32_TO_FLOAT128:
+ test_a_int32_z_float128( slow_int32_to_float128, int32_to_float128 );
+ break;
+#endif
+#ifdef BITS64
+ case INT64_TO_FLOAT32:
+ test_a_int64_z_float32( slow_int64_to_float32, int64_to_float32 );
+ break;
+ case INT64_TO_FLOAT64:
+ test_a_int64_z_float64( slow_int64_to_float64, int64_to_float64 );
+ break;
+#ifdef FLOATX80
+ case INT64_TO_FLOATX80:
+ test_a_int64_z_floatx80( slow_int64_to_floatx80, int64_to_floatx80 );
+ break;
+#endif
+#ifdef FLOAT128
+ case INT64_TO_FLOAT128:
+ test_a_int64_z_float128( slow_int64_to_float128, int64_to_float128 );
+ break;
+#endif
+#endif
+ case FLOAT32_TO_INT32:
+ test_a_float32_z_int32( slow_float32_to_int32, float32_to_int32 );
+ break;
+ case FLOAT32_TO_INT32_ROUND_TO_ZERO:
+ test_a_float32_z_int32(
+ slow_float32_to_int32_round_to_zero,
+ float32_to_int32_round_to_zero
+ );
+ break;
+#ifdef BITS64
+ case FLOAT32_TO_INT64:
+ test_a_float32_z_int64( slow_float32_to_int64, float32_to_int64 );
+ break;
+ case FLOAT32_TO_INT64_ROUND_TO_ZERO:
+ test_a_float32_z_int64(
+ slow_float32_to_int64_round_to_zero,
+ float32_to_int64_round_to_zero
+ );
+ break;
+#endif
+ case FLOAT32_TO_FLOAT64:
+ test_a_float32_z_float64(
+ slow_float32_to_float64, float32_to_float64 );
+ break;
+#ifdef FLOATX80
+ case FLOAT32_TO_FLOATX80:
+ test_a_float32_z_floatx80(
+ slow_float32_to_floatx80, float32_to_floatx80 );
+ break;
+#endif
+#ifdef FLOAT128
+ case FLOAT32_TO_FLOAT128:
+ test_a_float32_z_float128(
+ slow_float32_to_float128, float32_to_float128 );
+ break;
+#endif
+ case FLOAT32_ROUND_TO_INT:
+ test_az_float32( slow_float32_round_to_int, float32_round_to_int );
+ break;
+ case FLOAT32_ADD:
+ test_abz_float32( slow_float32_add, float32_add );
+ break;
+ case FLOAT32_SUB:
+ test_abz_float32( slow_float32_sub, float32_sub );
+ break;
+ case FLOAT32_MUL:
+ test_abz_float32( slow_float32_mul, float32_mul );
+ break;
+ case FLOAT32_DIV:
+ test_abz_float32( slow_float32_div, float32_div );
+ break;
+ case FLOAT32_REM:
+ test_abz_float32( slow_float32_rem, float32_rem );
+ break;
+ case FLOAT32_SQRT:
+ test_az_float32( slow_float32_sqrt, float32_sqrt );
+ break;
+ case FLOAT32_EQ:
+ test_ab_float32_z_flag( slow_float32_eq, float32_eq );
+ break;
+ case FLOAT32_LE:
+ test_ab_float32_z_flag( slow_float32_le, float32_le );
+ break;
+ case FLOAT32_LT:
+ test_ab_float32_z_flag( slow_float32_lt, float32_lt );
+ break;
+ case FLOAT32_EQ_SIGNALING:
+ test_ab_float32_z_flag(
+ slow_float32_eq_signaling, float32_eq_signaling );
+ break;
+ case FLOAT32_LE_QUIET:
+ test_ab_float32_z_flag( slow_float32_le_quiet, float32_le_quiet );
+ break;
+ case FLOAT32_LT_QUIET:
+ test_ab_float32_z_flag( slow_float32_lt_quiet, float32_lt_quiet );
+ break;
+ case FLOAT64_TO_INT32:
+ test_a_float64_z_int32( slow_float64_to_int32, float64_to_int32 );
+ break;
+ case FLOAT64_TO_INT32_ROUND_TO_ZERO:
+ test_a_float64_z_int32(
+ slow_float64_to_int32_round_to_zero,
+ float64_to_int32_round_to_zero
+ );
+ break;
+#ifdef BITS64
+ case FLOAT64_TO_INT64:
+ test_a_float64_z_int64( slow_float64_to_int64, float64_to_int64 );
+ break;
+ case FLOAT64_TO_INT64_ROUND_TO_ZERO:
+ test_a_float64_z_int64(
+ slow_float64_to_int64_round_to_zero,
+ float64_to_int64_round_to_zero
+ );
+ break;
+#endif
+ case FLOAT64_TO_FLOAT32:
+ test_a_float64_z_float32(
+ slow_float64_to_float32, float64_to_float32 );
+ break;
+#ifdef FLOATX80
+ case FLOAT64_TO_FLOATX80:
+ test_a_float64_z_floatx80(
+ slow_float64_to_floatx80, float64_to_floatx80 );
+ break;
+#endif
+#ifdef FLOAT128
+ case FLOAT64_TO_FLOAT128:
+ test_a_float64_z_float128(
+ slow_float64_to_float128, float64_to_float128 );
+ break;
+#endif
+ case FLOAT64_ROUND_TO_INT:
+ test_az_float64( slow_float64_round_to_int, float64_round_to_int );
+ break;
+ case FLOAT64_ADD:
+ test_abz_float64( slow_float64_add, float64_add );
+ break;
+ case FLOAT64_SUB:
+ test_abz_float64( slow_float64_sub, float64_sub );
+ break;
+ case FLOAT64_MUL:
+ test_abz_float64( slow_float64_mul, float64_mul );
+ break;
+ case FLOAT64_DIV:
+ test_abz_float64( slow_float64_div, float64_div );
+ break;
+ case FLOAT64_REM:
+ test_abz_float64( slow_float64_rem, float64_rem );
+ break;
+ case FLOAT64_SQRT:
+ test_az_float64( slow_float64_sqrt, float64_sqrt );
+ break;
+ case FLOAT64_EQ:
+ test_ab_float64_z_flag( slow_float64_eq, float64_eq );
+ break;
+ case FLOAT64_LE:
+ test_ab_float64_z_flag( slow_float64_le, float64_le );
+ break;
+ case FLOAT64_LT:
+ test_ab_float64_z_flag( slow_float64_lt, float64_lt );
+ break;
+ case FLOAT64_EQ_SIGNALING:
+ test_ab_float64_z_flag(
+ slow_float64_eq_signaling, float64_eq_signaling );
+ break;
+ case FLOAT64_LE_QUIET:
+ test_ab_float64_z_flag( slow_float64_le_quiet, float64_le_quiet );
+ break;
+ case FLOAT64_LT_QUIET:
+ test_ab_float64_z_flag( slow_float64_lt_quiet, float64_lt_quiet );
+ break;
+#ifdef FLOATX80
+ case FLOATX80_TO_INT32:
+ test_a_floatx80_z_int32( slow_floatx80_to_int32, floatx80_to_int32 );
+ break;
+ case FLOATX80_TO_INT32_ROUND_TO_ZERO:
+ test_a_floatx80_z_int32(
+ slow_floatx80_to_int32_round_to_zero,
+ floatx80_to_int32_round_to_zero
+ );
+ break;
+#ifdef BITS64
+ case FLOATX80_TO_INT64:
+ test_a_floatx80_z_int64( slow_floatx80_to_int64, floatx80_to_int64 );
+ break;
+ case FLOATX80_TO_INT64_ROUND_TO_ZERO:
+ test_a_floatx80_z_int64(
+ slow_floatx80_to_int64_round_to_zero,
+ floatx80_to_int64_round_to_zero
+ );
+ break;
+#endif
+ case FLOATX80_TO_FLOAT32:
+ test_a_floatx80_z_float32(
+ slow_floatx80_to_float32, floatx80_to_float32 );
+ break;
+ case FLOATX80_TO_FLOAT64:
+ test_a_floatx80_z_float64(
+ slow_floatx80_to_float64, floatx80_to_float64 );
+ break;
+#ifdef FLOAT128
+ case FLOATX80_TO_FLOAT128:
+ test_a_floatx80_z_float128(
+ slow_floatx80_to_float128, floatx80_to_float128 );
+ break;
+#endif
+ case FLOATX80_ROUND_TO_INT:
+ test_az_floatx80( slow_floatx80_round_to_int, floatx80_round_to_int );
+ break;
+ case FLOATX80_ADD:
+ test_abz_floatx80( slow_floatx80_add, floatx80_add );
+ break;
+ case FLOATX80_SUB:
+ test_abz_floatx80( slow_floatx80_sub, floatx80_sub );
+ break;
+ case FLOATX80_MUL:
+ test_abz_floatx80( slow_floatx80_mul, floatx80_mul );
+ break;
+ case FLOATX80_DIV:
+ test_abz_floatx80( slow_floatx80_div, floatx80_div );
+ break;
+ case FLOATX80_REM:
+ test_abz_floatx80( slow_floatx80_rem, floatx80_rem );
+ break;
+ case FLOATX80_SQRT:
+ test_az_floatx80( slow_floatx80_sqrt, floatx80_sqrt );
+ break;
+ case FLOATX80_EQ:
+ test_ab_floatx80_z_flag( slow_floatx80_eq, floatx80_eq );
+ break;
+ case FLOATX80_LE:
+ test_ab_floatx80_z_flag( slow_floatx80_le, floatx80_le );
+ break;
+ case FLOATX80_LT:
+ test_ab_floatx80_z_flag( slow_floatx80_lt, floatx80_lt );
+ break;
+ case FLOATX80_EQ_SIGNALING:
+ test_ab_floatx80_z_flag(
+ slow_floatx80_eq_signaling, floatx80_eq_signaling );
+ break;
+ case FLOATX80_LE_QUIET:
+ test_ab_floatx80_z_flag( slow_floatx80_le_quiet, floatx80_le_quiet );
+ break;
+ case FLOATX80_LT_QUIET:
+ test_ab_floatx80_z_flag( slow_floatx80_lt_quiet, floatx80_lt_quiet );
+ break;
+#endif
+#ifdef FLOAT128
+ case FLOAT128_TO_INT32:
+ test_a_float128_z_int32( slow_float128_to_int32, float128_to_int32 );
+ break;
+ case FLOAT128_TO_INT32_ROUND_TO_ZERO:
+ test_a_float128_z_int32(
+ slow_float128_to_int32_round_to_zero,
+ float128_to_int32_round_to_zero
+ );
+ break;
+#ifdef BITS64
+ case FLOAT128_TO_INT64:
+ test_a_float128_z_int64( slow_float128_to_int64, float128_to_int64 );
+ break;
+ case FLOAT128_TO_INT64_ROUND_TO_ZERO:
+ test_a_float128_z_int64(
+ slow_float128_to_int64_round_to_zero,
+ float128_to_int64_round_to_zero
+ );
+ break;
+#endif
+ case FLOAT128_TO_FLOAT32:
+ test_a_float128_z_float32(
+ slow_float128_to_float32, float128_to_float32 );
+ break;
+ case FLOAT128_TO_FLOAT64:
+ test_a_float128_z_float64(
+ slow_float128_to_float64, float128_to_float64 );
+ break;
+#ifdef FLOATX80
+ case FLOAT128_TO_FLOATX80:
+ test_a_float128_z_floatx80(
+ slow_float128_to_floatx80, float128_to_floatx80 );
+ break;
+#endif
+ case FLOAT128_ROUND_TO_INT:
+ test_az_float128( slow_float128_round_to_int, float128_round_to_int );
+ break;
+ case FLOAT128_ADD:
+ test_abz_float128( slow_float128_add, float128_add );
+ break;
+ case FLOAT128_SUB:
+ test_abz_float128( slow_float128_sub, float128_sub );
+ break;
+ case FLOAT128_MUL:
+ test_abz_float128( slow_float128_mul, float128_mul );
+ break;
+ case FLOAT128_DIV:
+ test_abz_float128( slow_float128_div, float128_div );
+ break;
+ case FLOAT128_REM:
+ test_abz_float128( slow_float128_rem, float128_rem );
+ break;
+ case FLOAT128_SQRT:
+ test_az_float128( slow_float128_sqrt, float128_sqrt );
+ break;
+ case FLOAT128_EQ:
+ test_ab_float128_z_flag( slow_float128_eq, float128_eq );
+ break;
+ case FLOAT128_LE:
+ test_ab_float128_z_flag( slow_float128_le, float128_le );
+ break;
+ case FLOAT128_LT:
+ test_ab_float128_z_flag( slow_float128_lt, float128_lt );
+ break;
+ case FLOAT128_EQ_SIGNALING:
+ test_ab_float128_z_flag(
+ slow_float128_eq_signaling, float128_eq_signaling );
+ break;
+ case FLOAT128_LE_QUIET:
+ test_ab_float128_z_flag( slow_float128_le_quiet, float128_le_quiet );
+ break;
+ case FLOAT128_LT_QUIET:
+ test_ab_float128_z_flag( slow_float128_lt_quiet, float128_lt_quiet );
+ break;
+#endif
+ }
+ if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
+
+}
+
+static void
+ testFunction(
+ uint8 functionCode,
+ int8 roundingPrecisionIn,
+ int8 roundingModeIn,
+ int8 tininessModeIn
+ )
+{
+ int8 roundingPrecision, roundingMode, tininessMode;
+
+ roundingPrecision = 32;
+ for (;;) {
+ if ( ! functions[ functionCode ].roundingPrecision ) {
+ roundingPrecision = 0;
+ }
+ else if ( roundingPrecisionIn ) {
+ roundingPrecision = roundingPrecisionIn;
+ }
+ for ( roundingMode = 1;
+ roundingMode < NUM_ROUNDINGMODES;
+ ++roundingMode
+ ) {
+ if ( ! functions[ functionCode ].roundingMode ) {
+ roundingMode = 0;
+ }
+ else if ( roundingModeIn ) {
+ roundingMode = roundingModeIn;
+ }
+ for ( tininessMode = 1;
+ tininessMode < NUM_TININESSMODES;
+ ++tininessMode
+ ) {
+ if ( ( roundingPrecision == 32 )
+ || ( roundingPrecision == 64 ) ) {
+ if ( ! functions[ functionCode ]
+ .tininessModeAtReducedPrecision
+ ) {
+ tininessMode = 0;
+ }
+ else if ( tininessModeIn ) {
+ tininessMode = tininessModeIn;
+ }
+ }
+ else {
+ if ( ! functions[ functionCode ].tininessMode ) {
+ tininessMode = 0;
+ }
+ else if ( tininessModeIn ) {
+ tininessMode = tininessModeIn;
+ }
+ }
+ testFunctionVariety(
+ functionCode, roundingPrecision, roundingMode, tininessMode
+ );
+ if ( tininessModeIn || ! tininessMode ) break;
+ }
+ if ( roundingModeIn || ! roundingMode ) break;
+ }
+ if ( roundingPrecisionIn || ! roundingPrecision ) break;
+ if ( roundingPrecision == 80 ) {
+ break;
+ }
+ else if ( roundingPrecision == 64 ) {
+ roundingPrecision = 80;
+ }
+ else if ( roundingPrecision == 32 ) {
+ roundingPrecision = 64;
+ }
+ }
+
+}
+
+int
+main( int argc, char **argv )
+{
+ char *argPtr;
+ flag functionArgument;
+ uint8 functionCode;
+ int8 operands, roundingPrecision, roundingMode, tininessMode;
+
+ fail_programName = "testsoftfloat";
+ if ( argc <= 1 ) goto writeHelpMessage;
+ testCases_setLevel( 1 );
+ trueName = "true";
+ testName = "soft";
+ errorStop = FALSE;
+ forever = FALSE;
+ maxErrorCount = 20;
+ trueFlagsPtr = &slow_float_exception_flags;
+ testFlagsFunctionPtr = clearFlags;
+ functionArgument = FALSE;
+ functionCode = 0;
+ operands = 0;
+ roundingPrecision = 0;
+ roundingMode = 0;
+ tininessMode = 0;
+ --argc;
+ ++argv;
+ while ( argc && ( argPtr = argv[ 0 ] ) ) {
+ if ( argPtr[ 0 ] == '-' ) ++argPtr;
+ if ( strcmp( argPtr, "help" ) == 0 ) {
+ writeHelpMessage:
+ fputs(
+"testsoftfloat [<option>...] <function>\n"
+" <option>: (* is default)\n"
+" -help --Write this message and exit.\n"
+" -level <num> --Testing level <num> (1 or 2).\n"
+" * -level 1\n"
+" -errors <num> --Stop each function test after <num> errors.\n"
+" * -errors 20\n"
+" -errorstop --Exit after first function with any error.\n"
+" -forever --Test one function repeatedly (implies `-level 2').\n"
+#ifdef FLOATX80
+" -precision32 --Only test rounding precision equivalent to float32.\n"
+" -precision64 --Only test rounding precision equivalent to float64.\n"
+" -precision80 --Only test maximum rounding precision.\n"
+#endif
+" -nearesteven --Only test rounding to nearest/even.\n"
+" -tozero --Only test rounding to zero.\n"
+" -down --Only test rounding down.\n"
+" -up --Only test rounding up.\n"
+" -tininessbefore --Only test underflow tininess before rounding.\n"
+" -tininessafter --Only test underflow tininess after rounding.\n"
+" <function>:\n"
+" int32_to_<float> <float>_add <float>_eq\n"
+" <float>_to_int32 <float>_sub <float>_le\n"
+" <float>_to_int32_round_to_zero <float>_mul <float>_lt\n"
+#ifdef BITS64
+" int64_to_<float> <float>_div <float>_eq_signaling\n"
+" <float>_to_int64 <float>_rem <float>_le_quiet\n"
+" <float>_to_int64_round_to_zero <float>_lt_quiet\n"
+" <float>_to_<float>\n"
+" <float>_round_to_int\n"
+" <float>_sqrt\n"
+#else
+" <float>_to_<float> <float>_div <float>_eq_signaling\n"
+" <float>_round_to_int <float>_rem <float>_le_quiet\n"
+" <float>_sqrt <float>_lt_quiet\n"
+#endif
+" -all1 --All 1-operand functions.\n"
+" -all2 --All 2-operand functions.\n"
+" -all --All functions.\n"
+" <float>:\n"
+" float32 --Single precision.\n"
+" float64 --Double precision.\n"
+#ifdef FLOATX80
+" floatx80 --Extended double precision.\n"
+#endif
+#ifdef FLOAT128
+" float128 --Quadruple precision.\n"
+#endif
+ ,
+ stdout
+ );
+ return EXIT_SUCCESS;
+ }
+ else if ( strcmp( argPtr, "level" ) == 0 ) {
+ if ( argc < 2 ) goto optionError;
+ testCases_setLevel( atoi( argv[ 1 ] ) );
+ --argc;
+ ++argv;
+ }
+ else if ( strcmp( argPtr, "level1" ) == 0 ) {
+ testCases_setLevel( 1 );
+ }
+ else if ( strcmp( argPtr, "level2" ) == 0 ) {
+ testCases_setLevel( 2 );
+ }
+ else if ( strcmp( argPtr, "errors" ) == 0 ) {
+ if ( argc < 2 ) {
+ optionError:
+ fail( "`%s' option requires numeric argument", argv[ 0 ] );
+ }
+ maxErrorCount = atoi( argv[ 1 ] );
+ --argc;
+ ++argv;
+ }
+ else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
+ errorStop = TRUE;
+ }
+ else if ( strcmp( argPtr, "forever" ) == 0 ) {
+ testCases_setLevel( 2 );
+ forever = TRUE;
+ }
+#ifdef FLOATX80
+ else if ( strcmp( argPtr, "precision32" ) == 0 ) {
+ roundingPrecision = 32;
+ }
+ else if ( strcmp( argPtr, "precision64" ) == 0 ) {
+ roundingPrecision = 64;
+ }
+ else if ( strcmp( argPtr, "precision80" ) == 0 ) {
+ roundingPrecision = 80;
+ }
+#endif
+ else if ( ( strcmp( argPtr, "nearesteven" ) == 0 )
+ || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
+ roundingMode = ROUND_NEAREST_EVEN;
+ }
+ else if ( ( strcmp( argPtr, "tozero" ) == 0 )
+ || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
+ roundingMode = ROUND_TO_ZERO;
+ }
+ else if ( strcmp( argPtr, "down" ) == 0 ) {
+ roundingMode = ROUND_DOWN;
+ }
+ else if ( strcmp( argPtr, "up" ) == 0 ) {
+ roundingMode = ROUND_UP;
+ }
+ else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
+ tininessMode = TININESS_BEFORE_ROUNDING;
+ }
+ else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
+ tininessMode = TININESS_AFTER_ROUNDING;
+ }
+ else if ( strcmp( argPtr, "all1" ) == 0 ) {
+ functionArgument = TRUE;
+ functionCode = 0;
+ operands = 1;
+ }
+ else if ( strcmp( argPtr, "all2" ) == 0 ) {
+ functionArgument = TRUE;
+ functionCode = 0;
+ operands = 2;
+ }
+ else if ( strcmp( argPtr, "all" ) == 0 ) {
+ functionArgument = TRUE;
+ functionCode = 0;
+ operands = 0;
+ }
+ else {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
+ break;
+ }
+ }
+ if ( functionCode == NUM_FUNCTIONS ) {
+ fail( "Invalid option or function `%s'", argv[ 0 ] );
+ }
+ functionArgument = TRUE;
+ }
+ --argc;
+ ++argv;
+ }
+ if ( ! functionArgument ) fail( "Function argument required" );
+ (void) signal( SIGINT, catchSIGINT );
+ (void) signal( SIGTERM, catchSIGINT );
+ if ( functionCode ) {
+ if ( forever ) {
+ if ( ! roundingPrecision ) roundingPrecision = 80;
+ if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
+ }
+ testFunction(
+ functionCode, roundingPrecision, roundingMode, tininessMode );
+ }
+ else {
+ if ( operands == 1 ) {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( functions[ functionCode ].numInputs == 1 ) {
+ testFunction(
+ functionCode,
+ roundingPrecision,
+ roundingMode,
+ tininessMode
+ );
+ }
+ }
+ }
+ else if ( operands == 2 ) {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ if ( functions[ functionCode ].numInputs == 2 ) {
+ testFunction(
+ functionCode,
+ roundingPrecision,
+ roundingMode,
+ tininessMode
+ );
+ }
+ }
+ }
+ else {
+ for ( functionCode = 1;
+ functionCode < NUM_FUNCTIONS;
+ ++functionCode
+ ) {
+ testFunction(
+ functionCode, roundingPrecision, roundingMode, tininessMode
+ );
+ }
+ }
+ }
+ exitWithStatus();
+
+}
+
diff --git a/tools/test/testfloat/writeHex.c b/tools/test/testfloat/writeHex.c
new file mode 100644
index 0000000..f304aed
--- /dev/null
+++ b/tools/test/testfloat/writeHex.c
@@ -0,0 +1,183 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <stdio.h>
+#include "milieu.h"
+#include "softfloat.h"
+#include "writeHex.h"
+
+void writeHex_flag( flag a, FILE *stream )
+{
+
+ fputc( a ? '1' : '0', stream );
+
+}
+
+static void writeHex_bits8( bits8 a, FILE *stream )
+{
+ int digit;
+
+ digit = ( a>>4 ) & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+ digit = a & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+
+}
+
+static void writeHex_bits12( int16 a, FILE *stream )
+{
+ int digit;
+
+ digit = ( a>>8 ) & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+ digit = ( a>>4 ) & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+ digit = a & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+
+}
+
+static void writeHex_bits16( bits16 a, FILE *stream )
+{
+ int digit;
+
+ digit = ( a>>12 ) & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+ digit = ( a>>8 ) & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+ digit = ( a>>4 ) & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+ digit = a & 0xF;
+ if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
+ fputc( '0' + digit, stream );
+
+}
+
+void writeHex_bits32( bits32 a, FILE *stream )
+{
+
+ writeHex_bits16( a>>16, stream );
+ writeHex_bits16( a, stream );
+
+}
+
+#ifdef BITS64
+
+void writeHex_bits64( bits64 a, FILE *stream )
+{
+
+ writeHex_bits32( a>>32, stream );
+ writeHex_bits32( a, stream );
+
+}
+
+#endif
+
+void writeHex_float32( float32 a, FILE *stream )
+{
+
+ fputc( ( ( (sbits32) a ) < 0 ) ? '8' : '0', stream );
+ writeHex_bits8( a>>23, stream );
+ fputc( '.', stream );
+ writeHex_bits8( ( a>>16 ) & 0x7F, stream );
+ writeHex_bits16( a, stream );
+
+}
+
+#ifdef BITS64
+
+void writeHex_float64( float64 a, FILE *stream )
+{
+
+ writeHex_bits12( a>>52, stream );
+ fputc( '.', stream );
+ writeHex_bits12( a>>40, stream );
+ writeHex_bits8( a>>32, stream );
+ writeHex_bits32( a, stream );
+
+}
+
+#else
+
+void writeHex_float64( float64 a, FILE *stream )
+{
+
+ writeHex_bits12( a.high>>20, stream );
+ fputc( '.', stream );
+ writeHex_bits12( a.high>>8, stream );
+ writeHex_bits8( a.high, stream );
+ writeHex_bits32( a.low, stream );
+
+}
+
+#endif
+
+#ifdef FLOATX80
+
+void writeHex_floatx80( floatx80 a, FILE *stream )
+{
+
+ writeHex_bits16( a.high, stream );
+ fputc( '.', stream );
+ writeHex_bits64( a.low, stream );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void writeHex_float128( float128 a, FILE *stream )
+{
+
+ writeHex_bits16( a.high>>48, stream );
+ fputc( '.', stream );
+ writeHex_bits16( a.high>>32, stream );
+ writeHex_bits32( a.high, stream );
+ writeHex_bits64( a.low, stream );
+
+}
+
+#endif
+
+void writeHex_float_flags( uint8 flags, FILE *stream )
+{
+
+ fputc( flags & float_flag_invalid ? 'v' : '.', stream );
+ fputc( flags & float_flag_divbyzero ? 'z' : '.', stream );
+ fputc( flags & float_flag_overflow ? 'o' : '.', stream );
+ fputc( flags & float_flag_underflow ? 'u' : '.', stream );
+ fputc( flags & float_flag_inexact ? 'x' : '.', stream );
+
+}
+
diff --git a/tools/test/testfloat/writeHex.h b/tools/test/testfloat/writeHex.h
new file mode 100644
index 0000000..0dde44c
--- /dev/null
+++ b/tools/test/testfloat/writeHex.h
@@ -0,0 +1,42 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser. More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <stdio.h>
+
+void writeHex_flag( flag, FILE * );
+void writeHex_bits32( bits32, FILE * );
+#ifdef BITS64
+void writeHex_bits64( bits64, FILE * );
+#endif
+void writeHex_float32( float32, FILE * );
+void writeHex_float64( float64, FILE * );
+#ifdef FLOATX80
+void writeHex_floatx80( floatx80, FILE * );
+#endif
+#ifdef FLOAT128
+void writeHex_float128( float128, FILE * );
+#endif
+void writeHex_float_flags( uint8, FILE * );
+
diff --git a/tools/tools/ath/common/dumpregs_5416.c b/tools/tools/ath/common/dumpregs_5416.c
index a074ff7..0bc66f3 100644
--- a/tools/tools/ath/common/dumpregs_5416.c
+++ b/tools/tools/ath/common/dumpregs_5416.c
@@ -394,6 +394,7 @@ static struct dumpreg ar5416regs[] = {
DEFBASIC(AR_SLP_CNT, "SLPCNT"),
DEFBASIC(AR_SLP_MIB_CTRL, "SLPMIB"),
DEFBASIC(AR_EXTRCCNT, "EXTRCCNT"),
+ DEFBASIC(AR_PHY_TURBO, "PHYTURBO"),
DEFVOID(AR_PHY_ADC_SERIAL_CTL, "PHY_ADC_SERIAL_CTL"),
diff --git a/tools/tools/nanobsd/Files/root/updatep1 b/tools/tools/nanobsd/Files/root/updatep1
index 6e094fa..6b83de5 100644
--- a/tools/tools/nanobsd/Files/root/updatep1
+++ b/tools/tools/nanobsd/Files/root/updatep1
@@ -51,4 +51,4 @@ dd of=/dev/${NANO_DRIVE}s1 obs=64k
# Check that it worked
fsck_ffs -n /dev/${NANO_DRIVE}s1a
-boot0cfg -s 1 -v ${NANO_DRIVE}
+gpart set -a active -i 1 ${NANO_DRIVE}
diff --git a/tools/tools/nanobsd/Files/root/updatep2 b/tools/tools/nanobsd/Files/root/updatep2
index b9067eb..fc5312b 100644
--- a/tools/tools/nanobsd/Files/root/updatep2
+++ b/tools/tools/nanobsd/Files/root/updatep2
@@ -58,4 +58,4 @@ sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/" /mnt/conf/base/etc/fstab
sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/" /mnt/etc/fstab
umount /mnt
trap 1 2 15 EXIT
-boot0cfg -s 2 -v ${NANO_DRIVE}
+gpart set -a active -i 2 ${NANO_DRIVE}
diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common
index 750cd39..2e2d46c 100644
--- a/tools/tools/nanobsd/gateworks/common
+++ b/tools/tools/nanobsd/gateworks/common
@@ -37,7 +37,7 @@ NANO_CUSTOMIZE="$NANO_CUSTOMIZE cust_install_files cust_install_machine_files"
buildenv()
{
cd ${NANO_SRC}
- env TARGET_ARCH=${NANO_ARCH} __MAKE_CONF=${NANO_MAKE_CONF} \
+ env TARGET_ARCH=${NANO_ARCH} __MAKE_CONF=${NANO_MAKE_CONF_BUILD} \
DESTDIR=${NANO_WORLDDIR} make buildenv
}
@@ -146,22 +146,9 @@ WITHOUT_TCSH=true
CONF_INSTALL="$CONF_BUILD
WITHOUT_TOOLCHAIN=true
WITHOUT_INSTALLLIB=true
+INSTALL_NODEBUG=true
"
-# NB: override to suppress install of kernel.symbols
-install_kernel()
-{
- pprint 2 "install kernel"
- pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.ik"
-
- cd ${NANO_SRC}
- env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} installkernel \
- INSTALL_NODEBUG=true \
- DESTDIR=${NANO_WORLDDIR} \
- __MAKE_CONF=${NANO_MAKE_CONF} KERNCONF=`basename ${NANO_KERNEL}` \
- > ${MAKEOBJDIRPREFIX}/_.ik 2>&1
-}
-
# NB: override to force / on s1 instead of s1a
setup_nanobsd_etc()
{
diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
index 10d8f78..ce518a5 100644
--- a/tools/tools/nanobsd/nanobsd.sh
+++ b/tools/tools/nanobsd/nanobsd.sh
@@ -132,9 +132,12 @@ NANO_MD_BACKING="file"
PPLEVEL=3
#######################################################################
-# Not a variable at this time
+# Architecture to build. Corresponds to TARGET_ARCH in a buildworld.
+# Unfortunately, there's no way to set TARGET at this time, and it
+# conflates the two, so architectures where TARGET != TARGET_ARCH do
+# not work. This defaults to the arch of the current machine.
-NANO_ARCH=i386
+NANO_ARCH=`uname -p`
#######################################################################
#
@@ -497,6 +500,11 @@ create_i386_diskimage ( ) (
) > ${NANO_OBJ}/_.di 2>&1
)
+# i386 and amd64 are identical for disk images
+create_amd64_diskimage ( ) (
+ create_i386_diskimage
+)
+
last_orders () (
# Redefine this function with any last orders you may have
# after the build completed, for instance to copy the finished
diff --git a/tools/tools/netrate/http/Makefile b/tools/tools/netrate/http/Makefile
index 789e7d0..fb8960b 100644
--- a/tools/tools/netrate/http/Makefile
+++ b/tools/tools/netrate/http/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
PROG= http
-WARNS= 3
NO_MAN=
+WARNS?= 3
DPADD= ${LIBPTHREAD}
LDADD= -lpthread
diff --git a/tools/tools/netrate/httpd/Makefile b/tools/tools/netrate/httpd/Makefile
index 74067f2..b66ad19 100644
--- a/tools/tools/netrate/httpd/Makefile
+++ b/tools/tools/netrate/httpd/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
PROG= httpd
-WARNS= 3
NO_MAN=
+WARNS?= 3
DPADD= ${LIBPTHREAD}
LDADD= -lpthread
diff --git a/tools/tools/netrate/juggle/Makefile b/tools/tools/netrate/juggle/Makefile
index 67d6263..cd64a07 100644
--- a/tools/tools/netrate/juggle/Makefile
+++ b/tools/tools/netrate/juggle/Makefile
@@ -2,9 +2,8 @@
PROG= juggle
NO_MAN=
-WARNS= 3
-
-LDADD= -lpthread
+WARNS?= 3
DPADD= ${LIBPTHREAD}
+LDADD= -lpthread
.include <bsd.prog.mk>
diff --git a/tools/tools/netrate/tcpconnect/Makefile b/tools/tools/netrate/tcpconnect/Makefile
index 4a3f5ad..624c94a 100644
--- a/tools/tools/netrate/tcpconnect/Makefile
+++ b/tools/tools/netrate/tcpconnect/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG= tcpconnect
-WARNS= 3
NO_MAN=
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/tools/tools/netrate/tcpp/Makefile b/tools/tools/netrate/tcpp/Makefile
index 31f8fc2..a0b2715 100644
--- a/tools/tools/netrate/tcpp/Makefile
+++ b/tools/tools/netrate/tcpp/Makefile
@@ -4,6 +4,6 @@ PROG= tcpp
INCS= tcpp.h
NO_MAN=
SRCS= tcpp.c tcpp_client.c tcpp_server.c tcpp_util.c
-WARNS= 3
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/tools/tools/netrate/tcpp/tcpp_client.c b/tools/tools/netrate/tcpp/tcpp_client.c
index 15df06e..6c3e800 100644
--- a/tools/tools/netrate/tcpp/tcpp_client.c
+++ b/tools/tools/netrate/tcpp/tcpp_client.c
@@ -33,9 +33,11 @@
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/time.h>
+#include <sys/uio.h>
#include <sys/wait.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <err.h>
#include <errno.h>
@@ -82,6 +84,7 @@ static int kq;
static int started; /* Number started so far. */
static int finished; /* Number finished so far. */
static int counter; /* IP number offset. */
+static uint64_t payload_len;
static struct connection *
tcpp_client_newconn(void)
@@ -109,6 +112,9 @@ tcpp_client_newconn(void)
i = 1;
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0)
err(-1, "setsockopt");
+ i = 1;
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i)) < 0)
+ err(-1, "setsockopt");
#if 0
i = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
@@ -131,7 +137,7 @@ tcpp_client_newconn(void)
conn->conn_magic = CONNECTION_MAGIC;
conn->conn_fd = fd;
conn->conn_header.th_magic = TCPP_MAGIC;
- conn->conn_header.th_len = bflag;
+ conn->conn_header.th_len = payload_len;
tcpp_header_encode(&conn->conn_header);
EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, conn);
@@ -156,16 +162,22 @@ static void
tcpp_client_handleconn(struct kevent *kev)
{
struct connection *conn;
- ssize_t len;
+ struct iovec iov[2];
+ ssize_t len, header_left;
conn = kev->udata;
if (conn->conn_magic != CONNECTION_MAGIC)
errx(-1, "tcpp_client_handleconn: magic");
if (conn->conn_header_sent < sizeof(conn->conn_header)) {
- len = write(conn->conn_fd, ((u_char *)&conn->conn_header) +
- conn->conn_header_sent, sizeof(conn->conn_header) -
- conn->conn_header_sent);
+ header_left = sizeof(conn->conn_header) -
+ conn->conn_header_sent;
+ iov[0].iov_base = ((u_char *)&conn->conn_header) +
+ conn->conn_header_sent;
+ iov[0].iov_len = header_left;
+ iov[1].iov_base = buffer;
+ iov[1].iov_len = min(sizeof(buffer), payload_len);
+ len = writev(conn->conn_fd, iov, 2);
if (len < 0) {
tcpp_client_closeconn(conn);
err(-1, "tcpp_client_handleconn: header write");
@@ -175,10 +187,14 @@ tcpp_client_handleconn(struct kevent *kev)
errx(-1, "tcpp_client_handleconn: header write "
"premature EOF");
}
- conn->conn_header_sent += len;
+ if (len > header_left) {
+ conn->conn_data_sent += (len - header_left);
+ conn->conn_header_sent += header_left;
+ } else
+ conn->conn_header_sent += len;
} else {
len = write(conn->conn_fd, buffer, min(sizeof(buffer),
- bflag - conn->conn_data_sent));
+ payload_len - conn->conn_data_sent));
if (len < 0) {
tcpp_client_closeconn(conn);
err(-1, "tcpp_client_handleconn: data write");
@@ -189,12 +205,12 @@ tcpp_client_handleconn(struct kevent *kev)
"premature EOF");
}
conn->conn_data_sent += len;
- if (conn->conn_data_sent >= bflag) {
- /*
- * All is well.
- */
- tcpp_client_closeconn(conn);
- }
+ }
+ if (conn->conn_data_sent >= payload_len) {
+ /*
+ * All is well.
+ */
+ tcpp_client_closeconn(conn);
}
}
@@ -261,6 +277,11 @@ tcpp_client(void)
pid_t pid;
int i, failed, status;
+ if (bflag < sizeof(struct tcpp_header))
+ errx(-1, "Can't use -b less than %zu\n",
+ sizeof(struct tcpp_header));
+ payload_len = bflag - sizeof(struct tcpp_header);
+
pid_list = malloc(sizeof(*pid_list) * pflag);
if (pid_list == NULL)
err(-1, "malloc pid_list");
diff --git a/tools/tools/netrate/tcpp/tcpp_server.c b/tools/tools/netrate/tcpp/tcpp_server.c
index 8101005..76f5e8d 100644
--- a/tools/tools/netrate/tcpp/tcpp_server.c
+++ b/tools/tools/netrate/tcpp/tcpp_server.c
@@ -37,6 +37,7 @@
#include <sys/wait.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <err.h>
#include <fcntl.h>
@@ -239,6 +240,10 @@ tcpp_server_worker(int workernum)
if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEPORT, &i, sizeof(i))
< 0)
err(-1, "setsockopt");
+ i = 1;
+ if (setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i))
+ < 0)
+ err(-1, "setsockopt");
if (bind(listen_sock, (struct sockaddr *)&localipbase,
sizeof(localipbase)) < 0)
err(-1, "bind");
diff --git a/tools/tools/netrate/tcpreceive/Makefile b/tools/tools/netrate/tcpreceive/Makefile
index 06d58ce..f04ea5f 100644
--- a/tools/tools/netrate/tcpreceive/Makefile
+++ b/tools/tools/netrate/tcpreceive/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG= tcpreceive
-WARNS= 3
NO_MAN=
+WARNS?= 3
.include <bsd.prog.mk>
diff --git a/tools/tools/umastat/Makefile b/tools/tools/umastat/Makefile
index 9461173..2335673 100644
--- a/tools/tools/umastat/Makefile
+++ b/tools/tools/umastat/Makefile
@@ -2,10 +2,9 @@
PROG= umastat
NO_MAN=
+WARNS?= 3
DPADD= ${LIBKVM}
LDADD= -lkvm
-WARNS= 3
-
.include <bsd.prog.mk>
diff --git a/usr.bin/alias/Makefile b/usr.bin/alias/Makefile
index 53df717..474499f 100644
--- a/usr.bin/alias/Makefile
+++ b/usr.bin/alias/Makefile
@@ -10,8 +10,11 @@ LINKS= ${BINDIR}/alias ${BINDIR}/bg \
${BINDIR}/alias ${BINDIR}/fc \
${BINDIR}/alias ${BINDIR}/fg \
${BINDIR}/alias ${BINDIR}/getopts \
+ ${BINDIR}/alias ${BINDIR}/hash \
${BINDIR}/alias ${BINDIR}/jobs \
${BINDIR}/alias ${BINDIR}/read \
+ ${BINDIR}/alias ${BINDIR}/type \
+ ${BINDIR}/alias ${BINDIR}/ulimit \
${BINDIR}/alias ${BINDIR}/umask \
${BINDIR}/alias ${BINDIR}/unalias \
${BINDIR}/alias ${BINDIR}/wait
diff --git a/usr.bin/apply/Makefile b/usr.bin/apply/Makefile
index ca0f10a..c23d928 100644
--- a/usr.bin/apply/Makefile
+++ b/usr.bin/apply/Makefile
@@ -2,5 +2,7 @@
# $FreeBSD$
PROG= apply
+DPADD= ${LIBSBUF}
+LDADD= -lsbuf
.include <bsd.prog.mk>
diff --git a/usr.bin/apply/apply.c b/usr.bin/apply/apply.c
index 25ba374..9c83126 100644
--- a/usr.bin/apply/apply.c
+++ b/usr.bin/apply/apply.c
@@ -44,10 +44,12 @@ static char sccsid[] = "@(#)apply.c 8.4 (Berkeley) 4/4/94";
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/sbuf.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
@@ -61,10 +63,13 @@ static int exec_shell(const char *, char *, char *);
static void usage(void);
int
-main(int argc, char *argv[]) {
+main(int argc, char *argv[])
+{
+ struct sbuf *cmdbuf;
+ long arg_max;
int ch, debug, i, magic, n, nargs, offset, rval;
- size_t clen, cmdsize, l;
- char *c, *cmd, *name, *p, *q, *shell, *slashp, *tmpshell;
+ size_t cmdsize;
+ char *cmd, *name, *p, *shell, *slashp, *tmpshell;
debug = 0;
magic = '%'; /* Default magic char is `%'. */
@@ -144,13 +149,13 @@ main(int argc, char *argv[]) {
p = cmd;
offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
if ((size_t)offset >= cmdsize)
- err(1, "snprintf() failed");
+ errx(1, "snprintf() failed");
p += offset;
cmdsize -= offset;
for (i = 1; i <= nargs; i++) {
offset = snprintf(p, cmdsize, " %c%d", magic, i);
if ((size_t)offset >= cmdsize)
- err(1, "snprintf() failed");
+ errx(1, "snprintf() failed");
p += offset;
cmdsize -= offset;
}
@@ -164,61 +169,53 @@ main(int argc, char *argv[]) {
} else {
offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
if ((size_t)offset >= cmdsize)
- err(1, "snprintf() failed");
+ errx(1, "snprintf() failed");
nargs = n;
}
- /*
- * Grab some space in which to build the command. Allocate
- * as necessary later, but no reason to build it up slowly
- * for the normal case.
- */
- if ((c = malloc(clen = 1024)) == NULL)
+ cmdbuf = sbuf_new(NULL, NULL, 1024, SBUF_AUTOEXTEND);
+ if (cmdbuf == NULL)
err(1, NULL);
+ arg_max = sysconf(_SC_ARG_MAX);
+
/*
* (argc) and (argv) are still offset by one to make it simpler to
* expand %digit references. At the end of the loop check for (argc)
* equals 1 means that all the (argv) has been consumed.
*/
for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
- /*
- * Find a max value for the command length, and ensure
- * there's enough space to build it.
- */
- for (l = strlen(cmd), i = 0; i < nargs; i++)
- l += strlen(argv[i+1]);
- if (l > clen && (c = realloc(c, clen = l)) == NULL)
- err(1, NULL);
-
+ sbuf_clear(cmdbuf);
/* Expand command argv references. */
- for (p = cmd, q = c; *p != '\0'; ++p)
+ for (p = cmd; *p != '\0'; ++p) {
if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
- offset = snprintf(q, l, "%s",
- argv[(++p)[0] - '0']);
- if ((size_t)offset >= l)
- err(1, "snprintf() failed");
- q += offset;
- l -= offset;
- } else
- *q++ = *p;
+ if (sbuf_cat(cmdbuf, argv[(++p)[0] - '0'])
+ == -1)
+ errc(1, ENOMEM, "sbuf");
+ } else {
+ if (sbuf_putc(cmdbuf, *p) == -1)
+ errc(1, ENOMEM, "sbuf");
+ }
+ if (sbuf_len(cmdbuf) > arg_max)
+ errc(1, E2BIG, NULL);
+ }
/* Terminate the command string. */
- *q = '\0';
+ sbuf_finish(cmdbuf);
/* Run the command. */
if (debug)
- (void)printf("%s\n", c);
+ (void)printf("%s\n", sbuf_data(cmdbuf));
else
- if (exec_shell(c, shell, name))
+ if (exec_shell(sbuf_data(cmdbuf), shell, name))
rval = 1;
}
if (argc != 1)
errx(1, "expecting additional argument%s after \"%s\"",
- (nargs - argc) ? "s" : "", argv[argc - 1]);
+ (nargs - argc) ? "s" : "", argv[argc - 1]);
free(cmd);
- free(c);
+ sbuf_delete(cmdbuf);
free(shell);
exit(rval);
}
diff --git a/usr.bin/ar/ar.1 b/usr.bin/ar/ar.1
index cb9414e..250cd20 100644
--- a/usr.bin/ar/ar.1
+++ b/usr.bin/ar/ar.1
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 31, 2007
-.Os
.Dt AR 1
+.Os
.Sh NAME
.Nm ar ,
.Nm ranlib
diff --git a/usr.bin/biff/biff.1 b/usr.bin/biff/biff.1
index 8484faa..45d0fad 100644
--- a/usr.bin/biff/biff.1
+++ b/usr.bin/biff/biff.1
@@ -32,7 +32,7 @@
.\" @(#)biff.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd July 9, 2002
+.Dd March 20, 2010
.Dt BIFF 1
.Os
.Sh NAME
@@ -67,7 +67,7 @@ Enable bell notification.
When header notification is enabled, the header and first few lines of
the message will be printed on your terminal whenever mail arrives.
A
-.Dq "Li biff y"
+.Dq "biff y"
command is often included in the file
.Pa .login
or
diff --git a/usr.bin/c89/c89.1 b/usr.bin/c89/c89.1
index 302aa32..82acf37 100644
--- a/usr.bin/c89/c89.1
+++ b/usr.bin/c89/c89.1
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd September 17, 1997
-.Os
.Dt C89 1
+.Os
.Sh NAME
.Nm c89
.Nd POSIX.2 C language compiler
diff --git a/usr.bin/c99/c99.1 b/usr.bin/c99/c99.1
index c56e585..e5207e5 100644
--- a/usr.bin/c99/c99.1
+++ b/usr.bin/c99/c99.1
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd October 7, 2002
-.Os
.Dt C99 1
+.Os
.Sh NAME
.Nm c99
.Nd standard C language compiler
diff --git a/usr.bin/calendar/Makefile b/usr.bin/calendar/Makefile
index 27df8b6..e5d1c6a 100644
--- a/usr.bin/calendar/Makefile
+++ b/usr.bin/calendar/Makefile
@@ -2,14 +2,16 @@
# $FreeBSD$
PROG= calendar
-SRCS= calendar.c io.c day.c ostern.c paskha.c
+SRCS= calendar.c locale.c events.c dates.c parsedata.c io.c day.c \
+ ostern.c paskha.c pom.c sunpos.c
+LDADD= -lm
INTER= de_AT.ISO_8859-15 de_DE.ISO8859-1 fr_FR.ISO8859-1 \
hr_HR.ISO8859-2 hu_HU.ISO8859-2 ru_RU.KOI8-R uk_UA.KOI8-U
DE_LINKS= de_DE.ISO8859-15
FR_LINKS= fr_FR.ISO8859-15
TEXTMODE?= 444
-WARNS?= 3
+WARNS?= 7
beforeinstall:
${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
diff --git a/usr.bin/calendar/calendar.1 b/usr.bin/calendar/calendar.1
index 404f44c..8f8fb5c 100644
--- a/usr.bin/calendar/calendar.1
+++ b/usr.bin/calendar/calendar.1
@@ -9,10 +9,6 @@
.\" 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 the University of
-.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
@@ -54,6 +50,8 @@
.Ek
.Oc
.Op Fl W Ar num
+.Op Fl U Ar UTC-offset
+.Op Fl l Ar longitude
.Sh DESCRIPTION
The
.Nm
@@ -93,6 +91,12 @@ as the default calendar file.
.Sm on
.Xc
For test purposes only: set date directly to argument values.
+.It Fl l Ar longitude , Fl U Ar UTC-offset
+Only one is needed:
+Perform lunar and solar calculations from this longitude or from
+this UTC offset.
+If neither is specified, the calculations will be based on the
+difference between UTC time and localtime.
.It Fl W Ar num
Print lines from today and the next
.Ar num
@@ -103,12 +107,36 @@ Ignore weekends when calculating the number of days.
To handle calendars in your national code table you can specify
.Dq LANG=<locale_name>
in the calendar file as early as possible.
-To handle national Easter
-names in the calendars
-.Dq Easter=<national_name>
-(for Catholic Easter) or
-.Dq Paskha=<national_name>
-(for Orthodox Easter) can be used.
+.Pp
+To handle the local name of sequences, you can specify them as:
+.Dq SEQUENCE=<first> <second> <third> <fourth> <fifth> <last>
+in the calendar file as early as possible.
+.Pp
+The names of the following special days are recognized:
+.Bl -tag -width 123456789012345 -compact
+.It Easter
+Catholic Easter.
+.It Paskha
+Orthodox Easter.
+.It NewMoon
+The lunar New Moon.
+.It FullMoon
+The lunar Full Moon.
+.It MarEquinox
+The solar equinox in March.
+.It JunSolstice
+The solar solstice in June.
+.It SepEquinox
+The solar equinox in March.
+.It DecSolstice
+The solar solstice in December.
+.It ChineseNewYear
+The first day of the Chinese year.
+.El
+These names may be reassigned to their local names via an assignment
+like
+.Dq Easter=Pasen
+in the calendar file.
.Pp
Other lines should begin with a month and day.
They may be entered in almost any format, either numeric or as character
@@ -122,11 +150,11 @@ Two numbers default to the month followed by the day.
Lines with leading tabs default to the last entered date, allowing
multiple line specifications for a single date.
.Pp
-``Easter'', is Easter for this year, and may be followed by a positive
-or negative integer.
-.Pp
-``Paskha'', is Orthodox Easter for this year, and may be followed by a
-positive or negative integer.
+The names of the recognized special days may be followed by a
+positive or negative integer, like:
+.Dq Easter+3
+or
+.Dq Pashka-4 .
.Pp
Weekdays may be followed by ``-4'' ...\& ``+5'' (aliases for
last, first, second, third, fourth) for moving events like
@@ -191,7 +219,8 @@ calendar file to use if no calendar file exists in the current directory.
do not send mail if this file exists.
.El
.Pp
-The following default calendar files are provided:
+The following default calendar files are provided in
+.Pa /usr/share/calendars:
.Pp
.Bl -tag -width calendar.southafrica -compact
.It Pa calendar.all
@@ -208,6 +237,8 @@ so that roving holidays are set correctly for the current year.
Days of special significance to computer people.
.It Pa calendar.croatian
Calendar of events in Croatia.
+.It Pa calendar.dutch
+Calendar of events in the Netherlands.
.It Pa calendar.freebsd
Birthdays of
.Fx
@@ -259,7 +290,28 @@ A
.Nm
command appeared in
.At v7 .
+.Sh NOTES
+Chinese New Year is calculated at 120 degrees east of Greenwich,
+which roughly corresponds with the east coast of China.
+For people west of China, this might result that the start of Chinese
+New Year and the day of the related new moon might differ.
+.Pp
+The phases of the moon and the longitude of the sun are calculated
+against the local position which corresponds with 30 degrees times
+the time-difference towards Greenwich.
+.Pp
+The new and full moons are happening on the day indicated: They
+might happen in the time period in the early night or in the late
+evening.
+It doesn't indicate that they are starting in the night on that date.
+.Pp
+Because of minor differences between the output of the formulas
+used and other sources on the Internet, Druids and Werewolves should
+double-check the start and end time of solar and lunar events.
.Sh BUGS
The
.Nm
-utility does not handle Jewish holidays and moon phases.
+utility does not handle Jewish holidays.
+.Pp
+There is no possibility to properly specify the local position
+needed for solar and lunar calculations.
diff --git a/usr.bin/calendar/calendar.c b/usr.bin/calendar/calendar.c
index 39f2c9c..29ac174 100644
--- a/usr.bin/calendar/calendar.c
+++ b/usr.bin/calendar/calendar.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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 the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -52,29 +48,38 @@ __FBSDID("$FreeBSD$");
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <unistd.h>
#include "calendar.h"
+#define UTCOFFSET_NOTSET 100 /* Expected between -24 and +24 */
+#define LONGITUDE_NOTSET 1000 /* Expected between -360 and +360 */
+
struct passwd *pw;
int doall = 0;
+int debug = 0;
+char *DEBUG = NULL;
time_t f_time = 0;
-
-int f_dayAfter = 0; /* days after current date */
-int f_dayBefore = 0; /* days before current date */
-int Friday = 5; /* day before weekend */
+double UTCOffset = UTCOFFSET_NOTSET;
+int EastLongitude = LONGITUDE_NOTSET;
static void usage(void) __dead2;
int
main(int argc, char *argv[])
{
+ int f_dayAfter = 0; /* days after current date */
+ int f_dayBefore = 0; /* days before current date */
+ int Friday = 5; /* day before weekend */
+
int ch;
+ struct tm tp1, tp2;
(void)setlocale(LC_ALL, "");
- while ((ch = getopt(argc, argv, "-A:aB:F:f:t:W:")) != -1)
+ while ((ch = getopt(argc, argv, "-A:aB:dD:F:f:l:t:U:W:")) != -1)
switch (ch) {
case '-': /* backward contemptible */
case 'a':
@@ -89,14 +94,10 @@ main(int argc, char *argv[])
calendarFile = optarg;
break;
- case 't': /* other date, undocumented, for tests */
- f_time = Mktime(optarg);
- break;
-
case 'W': /* we don't need no steenking Fridays */
Friday = -1;
-
/* FALLTHROUGH */
+
case 'A': /* days after current date */
f_dayAfter = atoi(optarg);
break;
@@ -105,9 +106,25 @@ main(int argc, char *argv[])
f_dayBefore = atoi(optarg);
break;
- case 'F':
+ case 'F': /* Change the time: When does weekend start? */
Friday = atoi(optarg);
break;
+ case 'l': /* Change longitudal position */
+ EastLongitude = strtol(optarg, NULL, 10);
+ break;
+ case 'U': /* Change UTC offset */
+ UTCOffset = strtod(optarg, NULL);
+ break;
+
+ case 'd':
+ debug = 1;
+ break;
+ case 'D':
+ DEBUG = optarg;
+ break;
+ case 't': /* other date, undocumented, for tests */
+ f_time = Mktime(optarg);
+ break;
case '?':
default:
@@ -124,7 +141,60 @@ main(int argc, char *argv[])
if (f_time <= 0)
(void)time(&f_time);
- settime(f_time);
+ /* if not set, determine where I could be */
+ {
+ if (UTCOffset == UTCOFFSET_NOTSET &&
+ EastLongitude == LONGITUDE_NOTSET) {
+ /* Calculate on difference between here and UTC */
+ time_t t;
+ struct tm tm;
+ long utcoffset, hh, mm, ss;
+ double uo;
+
+ time(&t);
+ localtime_r(&t, &tm);
+ utcoffset = tm.tm_gmtoff;
+ /* seconds -> hh:mm:ss */
+ hh = utcoffset / SECSPERHOUR;
+ utcoffset %= SECSPERHOUR;
+ mm = utcoffset / SECSPERMINUTE;
+ utcoffset %= SECSPERMINUTE;
+ ss = utcoffset;
+
+ /* hh:mm:ss -> hh.mmss */
+ uo = mm + (100.0 * (ss / 60.0));
+ uo /= 60.0 / 100.0;
+ uo = hh + uo / 100;
+
+ UTCOffset = uo;
+ EastLongitude = UTCOffset * 15;
+ } else if (UTCOffset == UTCOFFSET_NOTSET) {
+ /* Base on information given */
+ UTCOffset = EastLongitude / 15;
+ } else if (EastLongitude == LONGITUDE_NOTSET) {
+ /* Base on information given */
+ EastLongitude = UTCOffset * 15;
+ }
+ }
+
+ settimes(f_time, f_dayBefore, f_dayAfter, Friday, &tp1, &tp2);
+ generatedates(&tp1, &tp2);
+
+ /*
+ * FROM now on, we are working in UTC.
+ * This will only affect moon and sun related events anyway.
+ */
+ if (setenv("TZ", "UTC", 1) != 0)
+ errx(1, "setenv: %s", strerror(errno));
+ tzset();
+
+ if (debug)
+ dumpdates();
+
+ if (DEBUG != NULL) {
+ dodebug(DEBUG);
+ exit(0);
+ }
if (doall)
while ((pw = getpwent()) != NULL) {
@@ -145,9 +215,11 @@ static void __dead2
usage(void)
{
- fprintf(stderr, "%s\n%s\n",
+ fprintf(stderr, "%s\n%s\n%s\n",
"usage: calendar [-a] [-A days] [-B days] [-F friday] "
"[-f calendarfile]",
- " [-t dd[.mm[.year]]] [-W days]");
+ " [-d] [-t dd[.mm[.year]]] [-W days]",
+ " [-U utcoffset] [-l longitude]"
+ );
exit(1);
}
diff --git a/usr.bin/calendar/calendar.h b/usr.bin/calendar/calendar.h
index ff67ca6..634c278 100644
--- a/usr.bin/calendar/calendar.h
+++ b/usr.bin/calendar/calendar.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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 the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -36,43 +32,163 @@
#include <sys/types.h>
#include <sys/uio.h>
+#define SECSPERDAY (24 * 60 * 60)
+#define SECSPERHOUR (60 * 60)
+#define SECSPERMINUTE (60)
+#define MINSPERHOUR (60)
+#define HOURSPERDAY (24)
+#define FSECSPERDAY (24.0 * 60.0 * 60.0)
+#define FSECSPERHOUR (60.0 * 60.0)
+#define FSECSPERMINUTE (60.0)
+#define FMINSPERHOUR (60.0)
+#define FHOURSPERDAY (24.0)
+
+#define DAYSPERYEAR 365
+#define DAYSPERLEAPYEAR 366
+
+/* Not yet categorized */
+
extern struct passwd *pw;
extern int doall;
-extern struct iovec header[];
-extern struct tm *tp;
+extern time_t t1, t2;
extern const char *calendarFile;
-extern int *cumdays;
extern int yrdays;
-extern struct fixs neaster, npaskha;
-
-void cal(void);
-void closecal(FILE *);
-int getday(char *);
-int getdayvar(char *);
-int getfield(char *, char **, int *);
-int getmonth(char *);
-int geteaster(char *, int);
-int getpaskha(char *, int);
-int easter(int);
-int isnow(char *, int *, int *, int *);
-FILE *opencal(void);
-void settime(time_t);
-time_t Mktime(char *);
-void setnnames(void);
+extern struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon;
+extern struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice;
+extern double UTCOffset;
+extern int EastLongitude;
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-/* some flags */
-#define F_ISMONTH 0x01 /* month (January ...) */
-#define F_ISDAY 0x02 /* day of week (Sun, Mon, ...) */
-#define F_ISDAYVAR 0x04 /* variables day of week, like SundayLast */
-#define F_EASTER 0x08 /* Easter or easter depending days */
+/* Flags to determine the returned values by determinestyle() in parsedata.c */
+#define F_NONE 0x00000
+#define F_MONTH 0x00001
+#define F_DAYOFWEEK 0x00002
+#define F_DAYOFMONTH 0x00004
+#define F_MODIFIERINDEX 0x00008
+#define F_MODIFIEROFFSET 0x00010
+#define F_SPECIALDAY 0x00020
+#define F_ALLMONTH 0x00040
+#define F_ALLDAY 0x00080
+#define F_VARIABLE 0x00100
+#define F_EASTER 0x00200
+#define F_CNY 0x00400
+#define F_PASKHA 0x00800
+#define F_NEWMOON 0x01000
+#define F_FULLMOON 0x02000
+#define F_MAREQUINOX 0x04000
+#define F_SEPEQUINOX 0x08000
+#define F_JUNSOLSTICE 0x10000
+#define F_DECSOLSTICE 0x20000
+
+#define STRING_EASTER "Easter"
+#define STRING_PASKHA "Paskha"
+#define STRING_CNY "ChineseNewYear"
+#define STRING_NEWMOON "NewMoon"
+#define STRING_FULLMOON "FullMoon"
+#define STRING_MAREQUINOX "MarEquinox"
+#define STRING_SEPEQUINOX "SepEquinox"
+#define STRING_JUNSOLSTICE "JunSolstice"
+#define STRING_DECSOLSTICE "DecSolstice"
-extern int f_dayAfter; /* days after current date */
-extern int f_dayBefore; /* days before current date */
-extern int Friday; /* day before weekend */
+#define MAXCOUNT 125 /* Random number of maximum number of
+ * repeats of an event. Should be 52
+ * (number of weeks per year), if you
+ * want to show two years then it
+ * should be 104. If you are seeing
+ * more than this you are using this
+ * program wrong.
+ */
+
+/*
+ * All the astronomical calculations are carried out for the meridian 120
+ * degrees east of Greenwich.
+ */
+#define UTCOFFSET_CNY 8.0
+
+extern int debug; /* show parsing of the input */
+extern int year1, year2;
+
+/* events.c */
+/*
+ * Event sorting related functions:
+ * - Use event_add() to create a new event
+ * - Use event_continue() to add more text to the last added event
+ * - Use event_print_all() to display them in time chronological order
+ */
+struct event *event_add(int, int, int, char *, int, char *, char *);
+void event_continue(struct event *events, char *txt);
+void event_print_all(FILE *fp);
+struct event {
+ int year;
+ int month;
+ int day;
+ int var;
+ char *date;
+ char *text;
+ char *extra;
+ struct event *next;
+};
+
+/* locale.c */
struct fixs {
char *name;
- int len;
+ size_t len;
};
+
+extern const char *days[];
+extern const char *fdays[];
+extern const char *fmonths[];
+extern const char *months[];
+extern const char *sequences[];
+extern struct fixs fndays[8]; /* full national days names */
+extern struct fixs fnmonths[13]; /* full national months names */
+extern struct fixs ndays[8]; /* short national days names */
+extern struct fixs nmonths[13]; /* short national month names */
+extern struct fixs nsequences[10];
+
+void setnnames(void);
+void setnsequences(char *);
+
+/* day.c */
+extern const struct tm tm0;
+extern char dayname[];
+void settimes(time_t,int before, int after, int friday, struct tm *tp1, struct tm *tp2);
+time_t Mktime(char *);
+
+/* parsedata.c */
+int parsedaymonth(char *, int *, int *, int *, int *, char **);
+void dodebug(char *type);
+
+/* io.c */
+void cal(void);
+void closecal(FILE *);
+FILE *opencal(void);
+
+/* ostern.c / pashka.c */
+int paskha(int);
+int easter(int);
+
+/* dates.c */
+extern int cumdaytab[][14];
+extern int mondaytab[][14];
+extern int debug_remember;
+void generatedates(struct tm *tp1, struct tm *tp2);
+void dumpdates(void);
+int remember_ymd(int y, int m, int d);
+int remember_yd(int y, int d, int *rm, int *rd);
+int first_dayofweek_of_year(int y);
+int first_dayofweek_of_month(int y, int m);
+int walkthrough_dates(struct event **e);
+void addtodate(struct event *e, int year, int month, int day);
+
+/* pom.c */
+#define MAXMOONS 18
+void pom(int year, double UTCoffset, int *fms, int *nms);
+void fpom(int year, double utcoffset, double *ffms, double *fnms);
+
+/* sunpos.c */
+void equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays);
+void fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays);
+int calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths);
diff --git a/usr.bin/calendar/calendars/calendar.australia b/usr.bin/calendar/calendars/calendar.australia
index 323e7ee..daa07ff 100644
--- a/usr.bin/calendar/calendars/calendar.australia
+++ b/usr.bin/calendar/calendars/calendar.australia
@@ -10,49 +10,63 @@
LANG=en_AU.ISO8859-1
/* Australia */
-Jan 26 Australia Day
-Mar/SunLast Daylight Savings Time ends in ACT, NSW, SA, TAS and VIC.
-Apr 25 Anzac Day
+Jan 26 Australia Day
+Apr/SunFirst Daylight Savings Time ends in ACT, NSW, SA, TAS and VIC.
+Apr 25 Anzac Day
Jun/MonSecond Queen's Birthday Holiday (Australia, except WA)
-Oct/SunLast Daylight Savings Time starts in ACT, NSW, SA and VIC.
+Oct/SunFirst Daylight Savings Time starts in ACT, NSW, SA and VIC.
/* ACT, NSW, common */
-Mar 18 Canberra Day (ACT)
-8/MonFirst Bank Holiday (ACT, NSW)
-10/MonFirst Labour Day (ACT, NSW, SA)
+Mar 18 Canberra Day (ACT)
+Sep/MonLast Family & Community Day (ACT)
+Aug/MonFirst Bank Holiday (ACT, NSW)
+Oct/MonFirst Labour Day (ACT, NSW, SA)
/* Victoria */
-3/MonSecond Labour Day (Vic)
-Nov/TueFirst Melbourne Cup (Vic)
-
-/* Tasmania */
-Feb 11 Regatta Day (Tas)
-Feb 27 Launceston Cup (Tas)
-Mar 11 Eight Hours Day (Tas)
-Oct/SunFirst Daylight Savings Time starts in TAS.
-Oct 10 Launceston Show Day (Tas)
-Oct 24 Hobart Show Day (Tas)
-Nov 04 Recreation Day (N Tas)
+Mar/MonSecond Labour Day (VIC)
+Nov/TueFirst Melbourne Cup (VIC)
+
+/* Tasmania
+ * http://www.wst.tas.gov.au/employment_info/public_holidays/html/2010
+ */
+Feb/MonSecond Regatta Day (TAS)
+Feb/WedLast Launceston Cup (TAS)
+Mar/TueFirst King Island show (TAS)
+Mar/MonSecond Eight Hours Day (TAS)
+Oct 10 Launceston Show Day (TAS) /* Thursday preceding second Saturday in October */
+Oct 24 Hobart Show Day (TAS) /* Thursday preceding fourth Saturday in October */
+Nov/MonFirst Recreation Day (N TAS)
+
+/*
+Oct/SatSecond-2 Launceston Show Day (TAS) // Thursday preceding second Sat in October
+Oct/SatFourth-2 Hobart Show Day (TAS) // Thursday preceding fourth Sat in October
+May/ThuFirst+1 Agfest (Circular Head only) // Friday following the first Thursday in May
+Oct/SatFirst-1 Burnie Show // Friday preceding first Saturday in October
+Oct/SatThird-1 Flinders Island Show // Friday preceding third Saturday in October
+
+DEVONPORT CUP Wednesday not earlier than fifth and not later than eleventh day of January
+DEVONPORT SHOW Friday nearest last day in November, but not later than first day of December
+*/
/* South Australia */
May/MonThird Adelaide Cup (SA)
-Dec 26 Proclamation Day holiday (SA)
+Dec 26 Proclamation Day holiday (SA)
/* Western Australia */
-3/MonFirst Labour Day (WA)
-6/MonFirst Foundation Day (WA)
-Sep 30 Queen's Birthday (WA)
+Mar/MonFirst Labour Day (WA)
+Jun/MonFirst Foundation Day (WA)
+Sep 30 Queen's Birthday (WA)
/* Northern Territory */
-5/MonFirst May Day (NT)
-7/FriFirst Alice Springs Show Day (NT)
-7/FriSecond Tennant Creek Show Day (NT)
-7/FriThird Katherine Show Day (NT)
-7/FriLast Darwin Show Day (NT)
-8/MonFirst Picnic Day (NT)
+May/MonFirst May Day (NT)
+Jul/FriFirst Alice Springs Show Day (NT)
+Jul/FriSecond Tennant Creek Show Day (NT)
+Jul/FriThird Katherine Show Day (NT)
+Jul/FriLast Darwin Show Day (NT)
+Aug/MonFirst Picnic Day (NT)
/* Queensland */
-5/MonFirst Labour Day (Qld)
-Aug 14 RNA Show Day (Brisbane metro)
+May/MonFirst Labour Day (QLD)
+Aug/WedSecond RNA Show Day (Brisbane metro) /* Second Last Wednesday */
#endif
diff --git a/usr.bin/calendar/calendars/calendar.dutch b/usr.bin/calendar/calendars/calendar.dutch
index 47b1bf5..fab1793 100644
--- a/usr.bin/calendar/calendars/calendar.dutch
+++ b/usr.bin/calendar/calendars/calendar.dutch
@@ -10,25 +10,25 @@ Easter=Pasen
/*
* Feestdagen
*/
-01/01 Nieuwjaar
-01/06 Driekoningen
-04/01 Een April
-04/30 Koninginendag
-05/01 Dag van de Arbeid
-05/04 Dodenherdenking
-05/05 Bevrijdingsdag
-10/04 Dierendag
-11/01 Allerheilingen
-11/02 Allerzielen
-11/11 Sint Maarten
-11/11 Elfde-van-de-elfde
-12/05 Sinterklaas avond
-12/15 Koninkrijksdag
-12/24 Kerstavond
-12/25 Eerste kerstdag
-12/26 Tweede kerstdag
-12/28 Feest der Onnozele Kinderen
-12/31 Oudjaar
+jan/01 Nieuwjaar
+jan/06 Driekoningen
+apr/01 1 april
+apr/30 Koninginnedag
+mei/01 Dag van de Arbeid
+mei/04 Dodenherdenking
+mei/05 Bevrijdingsdag
+okt/04 Dierendag
+nov/01 Allerheiligen
+nov/02 Allerzielen
+nov/11 Sint Maarten
+nov/11 Elfde-van-de-elfde
+dec/05 Sinterklaas avond
+dec/15 Koninkrijksdag
+dec/24 Kerstavond
+dec/25 Eerste kerstdag
+dec/26 Tweede kerstdag
+dec/28 Feest der Onnozele Kinderen
+dec/31 Oudjaar
/*
* Pasen gerelateerd
@@ -38,12 +38,12 @@ Pasen-49 Carnaval
Pasen-48 Carnaval
Pasen-47 Carnaval (Vastenavond)
Pasen-46 Aswoensdag
-Pasen-7 Palmzondag
-Pasen-3 Witte Donderdag
-Pasen-2 Goede vrijdag
-Pasen-1 Stille zaterdag
+Pasen-7 Palmzondag
+Pasen-3 Witte Donderdag
+Pasen-2 Goede vrijdag
+Pasen-1 Stille zaterdag
Pasen Eerste paasdag
-Pasen+1 Tweede paasdag
+Pasen+1 Tweede paasdag
Pasen+39 Hemelvaartsdag
Pasen+49 Eerste Pinksterdag
Pasen+50 Tweede Pinksterdag
@@ -52,28 +52,28 @@ Pasen+56 Trinitatis
/*
* Misc
*/
-05/SunSecond Moederdag
-06/SunThird Vaderdag
-09/TueThird Prinsjesdag
+mei/SunSecond Moederdag
+jun/SunThird Vaderdag
+sep/TueThird Prinsjesdag
/*
* Het koningshuis
*/
-01/19 Prinses Margriet (1943)
-01/31 Koningin Beatrix (1938)
-02/17 Prins Willem III (1817 - 1890)
-02/18 Prinses Christina (1947)
-04/10 Prinses Ariane (2007)
-04/19 Prins Hendrik (1876 - 1934)
-04/27 Kroonprins Willem Alexander (1967)
-04/30 Koningin Juliana (1909 - 2004)
-04/30 Mr. Pieter van Vollenhoven (1939)
-05/17 Prinses Maxima (1971)
-06/26 Prinses Alexia (2005)
-06/29 Prins Bernhard (1911 - 2004)
-08/05 Prinses Irene (1939)
-08/31 Prinses Wilhelmina (1880 - 1962)
-09/06 Prins Claus (1925 - 2002)
-09/25 Prins Johan Friso (1968)
-10/11 Prins Constantijn (1969)
-12/07 Prinses Catharina-Amalia (2003)
+jan/19 Prinses Margriet (1943)
+jan/31 Koningin Beatrix (1938)
+feb/17 Prins Willem III (1817 - 1890)
+feb/18 Prinses Christina (1947)
+apr/10 Prinses Ariane (2007)
+apr/19 Prins Hendrik (1876 - 1934)
+apr/27 Kroonprins Willem Alexander (1967)
+apr/30 Koningin Juliana (1909 - 2004)
+apr/30 Mr. Pieter van Vollenhoven (1939)
+mei/17 Prinses Maxima (1971)
+jun/26 Prinses Alexia (2005)
+jun/29 Prins Bernhard (1911 - 2004)
+aug/05 Prinses Irene (1939)
+aug/31 Prinses Wilhelmina (1880 - 1962)
+sep/06 Prins Claus (1925 - 2002)
+sep/25 Prins Johan Friso (1968)
+okt/11 Prins Constantijn (1969)
+dec/07 Prinses Catharina-Amalia (2003)
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index 3c7d71d..cfebc36 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -82,6 +82,7 @@
03/12 Greg Lewis <glewis@FreeBSD.org> born in Adelaide, South Australia, Australia, 1969
03/13 Alexander Leidinger <netchild@FreeBSD.org> born in Neunkirchen, Saarland, Germany, 1976
03/13 Will Andrews <will@FreeBSD.org> born in Pontiac, Michigan, United States, 1982
+03/14 Bernhard Froehlich <decke@FreeBSD.org> born in Graz, Styria, Austria, 1985
03/15 Paolo Pisati <piso@FreeBSD.org> born in Lodi, Italy, 1977
03/15 Brian Fundakowski Feldman <green@FreeBSD.org> born in Alexandria, Virginia, United States, 1983
03/17 Michael Smith <msmith@FreeBSD.org> born in Bankstown, New South Wales, Australia, 1971
@@ -107,6 +108,7 @@
04/03 Tong Liu <nemoliu@FreeBSD.org> born in Beijing, People's Republic of China, 1981
04/03 Gabor Pali <pgj@FreeBSD.org> born in Kunhegyes, Hungary, 1982
04/05 Stacey Son <sson@FreeBSD.org> born in Burley, Idaho, United States. 1967
+04/07 Edward Tomasz Napierala <trasz@FreeBSD.org> born in Wolsztyn, Poland, 1981
04/08 Jordan K. Hubbard <jkh@FreeBSD.org> born in Honolulu, Hawaii, United States, 1963
04/09 Ceri Davies <ceri@FreeBSD.org> born in Haverfordwest, Pembrokeshire, United Kingdom, 1976
04/11 Bruce A. Mah <bmah@FreeBSD.org> born in Fresno, California, United States, 1969
@@ -206,6 +208,7 @@
07/23 Sergey A. Osokin <osa@FreeBSD.org> born in Krasnogorsky, Stepnogorsk, Akmolinskaya region, Kazakhstan, 1972
07/24 Alexander Nedotsukov <bland@FreeBSD.org> born in Ulyanovsk, Russian Federation, 1974
07/24 Alberto Villa <avilla@FreeBSD.org> born in Vercelli, Italy, 1987
+07/27 Andriy Gapon <avg@FreeBSD.org> born in Kyrykivka, Sumy region, Ukraine, 1976
07/28 Jim Mock <jim@FreeBSD.org> born in Bethlehem, Pennsylvania, United States, 1974
07/28 Tom Hukins <tom@FreeBSD.org> born in Manchester, United Kingdom, 1976
07/29 Dirk Meyer <dinoex@FreeBSD.org> born in Kassel, Hessen, Germany, 1965
diff --git a/usr.bin/calendar/dates.c b/usr.bin/calendar/dates.c
new file mode 100644
index 0000000..3f8b89f
--- /dev/null
+++ b/usr.bin/calendar/dates.c
@@ -0,0 +1,452 @@
+/*-
+ * Copyright (c) 1992-2009 Edwin Groothuis <edwin@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 <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <time.h>
+
+#include "calendar.h"
+
+struct cal_year {
+ int year; /* 19xx, 20xx, 21xx */
+ int easter; /* Julian day */
+ int paskha; /* Julian day */
+ int cny; /* Julian day */
+ int firstdayofweek; /* 0 .. 6 */
+ struct cal_month *months;
+ struct cal_year *nextyear;
+} cal_year;
+
+struct cal_month {
+ int month; /* 01 .. 12 */
+ int firstdayjulian; /* 000 .. 366 */
+ int firstdayofweek; /* 0 .. 6 */
+ struct cal_year *year; /* points back */
+ struct cal_day *days;
+ struct cal_month *nextmonth;
+} cal_month;
+
+struct cal_day {
+ int dayofmonth; /* 01 .. 31 */
+ int julianday; /* 000 .. 366 */
+ int dayofweek; /* 0 .. 6 */
+ struct cal_day *nextday;
+ struct cal_month *month; /* points back */
+ struct cal_year *year; /* points back */
+ struct event *events;
+} cal_day;
+
+int debug_remember = 0;
+struct cal_year *hyear = NULL;
+
+/* 1-based month, 0-based days, cumulative */
+int *cumdays;
+int cumdaytab[][14] = {
+ {0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},
+ {0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
+};
+/* 1-based month, individual */
+int *mondays;
+int mondaytab[][14] = {
+ {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 30},
+ {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 30},
+};
+
+static struct cal_day * find_day(int yy, int mm, int dd);
+
+static void
+createdate(int y, int m, int d)
+{
+ struct cal_year *py, *pyp;
+ struct cal_month *pm, *pmp;
+ struct cal_day *pd, *pdp;
+ int *cumday;
+
+ pyp = NULL;
+ py = hyear;
+ while (py != NULL) {
+ if (py->year == y + 1900)
+ break;
+ pyp = py;
+ py = py->nextyear;
+ }
+
+ if (py == NULL) {
+ struct tm td;
+ time_t t;
+ py = (struct cal_year *)calloc(1, sizeof(struct cal_year));
+ py->year = y + 1900;
+ py->easter = easter(y);
+ py->paskha = paskha(y);
+
+ td = tm0;
+ td.tm_year = y;
+ td.tm_mday = 1;
+ t = mktime(&td);
+ localtime_r(&t, &td);
+ py->firstdayofweek = td.tm_wday;
+
+ if (pyp != NULL)
+ pyp->nextyear = py;
+ }
+ if (pyp == NULL) {
+ /* The very very very first one */
+ hyear = py;
+ }
+
+ pmp = NULL;
+ pm = py->months;
+ while (pm != NULL) {
+ if (pm->month == m)
+ break;
+ pmp = pm;
+ pm = pm->nextmonth;
+ }
+
+ if (pm == NULL) {
+ pm = (struct cal_month *)calloc(1, sizeof(struct cal_month));
+ pm->year = py;
+ pm->month = m;
+ cumday = cumdaytab[isleap(y)];
+ pm->firstdayjulian = cumday[m] + 2;
+ pm->firstdayofweek =
+ (py->firstdayofweek + pm->firstdayjulian -1) % 7;
+ if (pmp != NULL)
+ pmp->nextmonth = pm;
+ }
+ if (pmp == NULL)
+ py->months = pm;
+
+ pdp = NULL;
+ pd = pm->days;
+ while (pd != NULL) {
+ pdp = pd;
+ pd = pd->nextday;
+ }
+
+ if (pd == NULL) { /* Always true */
+ pd = (struct cal_day *)calloc(1, sizeof(struct cal_day));
+ pd->month = pm;
+ pd->year = py;
+ pd->dayofmonth = d;
+ pd->julianday = pm->firstdayjulian + d - 1;
+ pd->dayofweek = (pm->firstdayofweek + d - 1) % 7;
+ if (pdp != NULL)
+ pdp->nextday = pd;
+ }
+ if (pdp == NULL)
+ pm->days = pd;
+}
+
+void
+generatedates(struct tm *tp1, struct tm *tp2)
+{
+ int y1, m1, d1;
+ int y2, m2, d2;
+ int y, m, d;
+
+ y1 = tp1->tm_year;
+ m1 = tp1->tm_mon + 1;
+ d1 = tp1->tm_mday;
+ y2 = tp2->tm_year;
+ m2 = tp2->tm_mon + 1;
+ d2 = tp2->tm_mday;
+
+ if (y1 == y2) {
+ if (m1 == m2) {
+ /* Same year, same month. Easy! */
+ for (d = d1; d <= d2; d++)
+ createdate(y1, m1, d);
+ return;
+ }
+ /*
+ * Same year, different month.
+ * - Take the leftover days from m1
+ * - Take all days from <m1 .. m2>
+ * - Take the first days from m2
+ */
+ mondays = mondaytab[isleap(y1)];
+ for (d = d1; d <= mondays[m1]; d++)
+ createdate(y1, m1, d);
+ for (m = m1 + 1; m < m2; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y1, m, d);
+ for (d = 1; d <= d2; d++)
+ createdate(y1, m2, d);
+ return;
+ }
+ /*
+ * Different year, different month.
+ * - Take the leftover days from y1-m1
+ * - Take all days from y1-<m1 .. 12]
+ * - Take all days from <y1 .. y2>
+ * - Take all days from y2-[1 .. m2>
+ * - Take the first days of y2-m2
+ */
+ mondays = mondaytab[isleap(y1)];
+ for (d = d1; d <= mondays[m1]; d++)
+ createdate(y1, m1, d);
+ for (m = m1 + 1; m <= 12; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y1, m, d);
+ for (y = y1 + 1; y < y2; y++) {
+ mondays = mondaytab[isleap(y)];
+ for (m = 1; m <= 12; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y, m, d);
+ }
+ mondays = mondaytab[isleap(y2)];
+ for (m = 1; m < m2; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y2, m, d);
+ for (d = 1; d <= d2; d++)
+ createdate(y2, m2, d);
+}
+
+void
+dumpdates(void)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ y = hyear;
+ while (y != NULL) {
+ printf("%-5d (wday:%d)\n", y->year, y->firstdayofweek);
+ m = y->months;
+ while (m != NULL) {
+ printf("-- %-5d (julian:%d, dow:%d)\n", m->month,
+ m->firstdayjulian, m->firstdayofweek);
+ d = m->days;
+ while (d != NULL) {
+ printf(" -- %-5d (julian:%d, dow:%d)\n",
+ d->dayofmonth, d->julianday, d->dayofweek);
+ d = d->nextday;
+ }
+ m = m->nextmonth;
+ }
+ y = y->nextyear;
+ }
+}
+
+int
+remember_ymd(int yy, int mm, int dd)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ if (debug_remember)
+ printf("remember_ymd: %d - %d - %d\n", yy, mm, dd);
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ if (m->month != mm) {
+ m = m->nextmonth;
+ continue;
+ }
+ d = m->days;
+ while (d != NULL) {
+ if (d->dayofmonth == dd)
+ return (1);
+ d = d->nextday;
+ continue;
+ }
+ return (0);
+ }
+ return (0);
+ }
+ return (0);
+}
+
+int
+remember_yd(int yy, int dd, int *rm, int *rd)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ if (debug_remember)
+ printf("remember_yd: %d - %d\n", yy, dd);
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ d = m->days;
+ while (d != NULL) {
+ if (d->julianday == dd) {
+ *rm = m->month;
+ *rd = d->dayofmonth;
+ return (1);
+ }
+ d = d->nextday;
+ }
+ m = m->nextmonth;
+ }
+ return (0);
+ }
+ return (0);
+}
+
+int
+first_dayofweek_of_year(int yy)
+{
+ struct cal_year *y;
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year == yy)
+ return (y->firstdayofweek);
+ y = y->nextyear;
+ }
+
+ /* Should not happen */
+ return (-1);
+}
+
+int
+first_dayofweek_of_month(int yy, int mm)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ if (m->month == mm)
+ return (m->firstdayofweek);
+ m = m->nextmonth;
+ }
+ /* Should not happen */
+ return (-1);
+ }
+
+ /* Should not happen */
+ return (-1);
+}
+
+int
+walkthrough_dates(struct event **e)
+{
+ static struct cal_year *y = NULL;
+ static struct cal_month *m = NULL;
+ static struct cal_day *d = NULL;
+
+ if (y == NULL) {
+ y = hyear;
+ m = y->months;
+ d = m->days;
+ *e = d->events;
+ return (1);
+ };
+ if (d->nextday != NULL) {
+ d = d->nextday;
+ *e = d->events;
+ return (1);
+ }
+ if (m->nextmonth != NULL) {
+ m = m->nextmonth;
+ d = m->days;
+ *e = d->events;
+ return (1);
+ }
+ if (y->nextyear != NULL) {
+ y = y->nextyear;
+ m = y->months;
+ d = m->days;
+ *e = d->events;
+ return (1);
+ }
+
+ return (0);
+}
+
+static struct cal_day *
+find_day(int yy, int mm, int dd)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ if (debug_remember)
+ printf("remember_ymd: %d - %d - %d\n", yy, mm, dd);
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ if (m->month != mm) {
+ m = m->nextmonth;
+ continue;
+ }
+ d = m->days;
+ while (d != NULL) {
+ if (d->dayofmonth == dd)
+ return (d);
+ d = d->nextday;
+ continue;
+ }
+ return (NULL);
+ }
+ return (NULL);
+ }
+ return (NULL);
+}
+
+void
+addtodate(struct event *e, int year, int month, int day)
+{
+ struct cal_day *d;
+
+ d = find_day(year, month, day);
+ e->next = d->events;
+ d->events = e;
+}
diff --git a/usr.bin/calendar/day.c b/usr.bin/calendar/day.c
index e40481e..237b6b5 100644
--- a/usr.bin/calendar/day.c
+++ b/usr.bin/calendar/day.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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 the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -34,9 +30,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <ctype.h>
#include <err.h>
#include <locale.h>
#include <stdio.h>
@@ -46,120 +39,38 @@ __FBSDID("$FreeBSD$");
#include "calendar.h"
-struct tm *tp;
-static const struct tm tm0;
-int *cumdays, yrdays;
-char dayname[10];
-
-
-/* 1-based month, 0-based days, cumulative */
-int daytab[][14] = {
- {0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},
- {0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
-};
-
-static char const *days[] = {
- "sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL,
-};
-
-static const char *months[] = {
- "jan", "feb", "mar", "apr", "may", "jun",
- "jul", "aug", "sep", "oct", "nov", "dec", NULL,
-};
-
-static struct fixs fndays[8]; /* full national days names */
-static struct fixs ndays[8]; /* short national days names */
-
-static struct fixs fnmonths[13]; /* full national months names */
-static struct fixs nmonths[13]; /* short national month names */
+time_t time1, time2;
+const struct tm tm0;
+char dayname[100];
+int year1, year2;
void
-setnnames(void)
+settimes(time_t now, int before, int after, int friday, struct tm *tp1, struct tm *tp2)
{
- char buf[80];
- int i, l;
- struct tm tm;
-
- for (i = 0; i < 7; i++) {
- tm.tm_wday = i;
- strftime(buf, sizeof(buf), "%a", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (ndays[i].name != NULL)
- free(ndays[i].name);
- if ((ndays[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- ndays[i].len = strlen(buf);
-
- strftime(buf, sizeof(buf), "%A", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (fndays[i].name != NULL)
- free(fndays[i].name);
- if ((fndays[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- fndays[i].len = strlen(buf);
- }
+ char *oldl, *lbufp;
+ struct tm tp;
- for (i = 0; i < 12; i++) {
- tm.tm_mon = i;
- strftime(buf, sizeof(buf), "%b", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (nmonths[i].name != NULL)
- free(nmonths[i].name);
- if ((nmonths[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- nmonths[i].len = strlen(buf);
+ localtime_r(&now, &tp);
- strftime(buf, sizeof(buf), "%B", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (fnmonths[i].name != NULL)
- free(fnmonths[i].name);
- if ((fnmonths[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- fnmonths[i].len = strlen(buf);
- }
-}
+ /* Friday displays Monday's events */
+ if (after == 0 && before == 0 && friday != -1)
+ after = tp.tm_wday == friday ? 3 : 1;
-void
-settime(time_t now)
-{
- char *oldl, *lbufp;
+ time1 = now - SECSPERDAY * before;
+ localtime_r(&time1, tp1);
+ year1 = 1900 + tp1->tm_year;
+ time2 = now + SECSPERDAY * after;
+ localtime_r(&time2, tp2);
+ year2 = 1900 + tp2->tm_year;
- tp = localtime(&now);
- if (isleap(tp->tm_year + 1900)) {
- yrdays = 366;
- cumdays = daytab[1];
- } else {
- yrdays = 365;
- cumdays = daytab[0];
- }
- /* Friday displays Monday's events */
- if (f_dayAfter == 0 && f_dayBefore == 0 && Friday != -1)
- f_dayAfter = tp->tm_wday == Friday ? 3 : 1;
- header[5].iov_base = dayname;
+ strftime(dayname, sizeof(dayname) - 1, "%A, %d %B %Y", tp1);
oldl = NULL;
lbufp = setlocale(LC_TIME, NULL);
if (lbufp != NULL && (oldl = strdup(lbufp)) == NULL)
errx(1, "cannot allocate memory");
(void)setlocale(LC_TIME, "C");
- header[5].iov_len = strftime(dayname, sizeof(dayname), "%A", tp);
(void)setlocale(LC_TIME, (oldl != NULL ? oldl : ""));
if (oldl != NULL)
free(oldl);
@@ -175,15 +86,15 @@ Mktime(char *dp)
{
time_t t;
int d, m, y;
- struct tm tm;
+ struct tm tm, tp;
(void)time(&t);
- tp = localtime(&t);
+ localtime_r(&t, &tp);
tm = tm0;
- tm.tm_mday = tp->tm_mday;
- tm.tm_mon = tp->tm_mon;
- tm.tm_year = tp->tm_year;
+ tm.tm_mday = tp.tm_mday;
+ tm.tm_mon = tp.tm_mon;
+ tm.tm_year = tp.tm_year;
switch (sscanf(dp, "%d.%d.%d", &d, &m, &y)) {
case 3:
@@ -204,282 +115,3 @@ Mktime(char *dp)
#endif
return (mktime(&tm));
}
-
-/*
- * Possible date formats include any combination of:
- * 3-charmonth (January, Jan, Jan)
- * 3-charweekday (Friday, Monday, mon.)
- * numeric month or day (1, 2, 04)
- *
- * Any character may separate them, or they may not be separated. Any line,
- * following a line that is matched, that starts with "whitespace", is shown
- * along with the matched line.
- */
-int
-isnow(char *endp, int *monthp, int *dayp, int *varp)
-{
- int day, flags, month = 0, v1, v2;
-
- /*
- * CONVENTION
- *
- * Month: 1-12
- * Monthname: Jan .. Dec
- * Day: 1-31
- * Weekday: Mon-Sun
- *
- */
-
- flags = 0;
-
- /* read first field */
- /* didn't recognize anything, skip it */
- if (!(v1 = getfield(endp, &endp, &flags)))
- return (0);
-
- /* Easter or Easter depending days */
- if (flags & F_EASTER)
- day = v1 - 1; /* days since January 1 [0-365] */
-
- /*
- * 1. {Weekday,Day} XYZ ...
- *
- * where Day is > 12
- */
- else if (flags & F_ISDAY || v1 > 12) {
-
- /* found a day; day: 1-31 or weekday: 1-7 */
- day = v1;
-
- /* {Day,Weekday} {Month,Monthname} ... */
- /* if no recognizable month, assume just a day alone
- * in other words, find month or use current month */
- if (!(month = getfield(endp, &endp, &flags)))
- month = tp->tm_mon + 1;
- }
-
- /* 2. {Monthname} XYZ ... */
- else if (flags & F_ISMONTH) {
- month = v1;
-
- /* Monthname {day,weekday} */
- /* if no recognizable day, assume the first day in month */
- if (!(day = getfield(endp, &endp, &flags)))
- day = 1;
- }
-
- /* Hm ... */
- else {
- v2 = getfield(endp, &endp, &flags);
-
- /*
- * {Day} {Monthname} ...
- * where Day <= 12
- */
- if (flags & F_ISMONTH) {
- day = v1;
- month = v2;
- *varp = 0;
- }
-
- /* {Month} {Weekday,Day} ... */
- else {
- /* F_ISDAY set, v2 > 12, or no way to tell */
- month = v1;
- /* if no recognizable day, assume the first */
- day = v2 ? v2 : 1;
- *varp = 0;
- }
- }
-
- /* convert Weekday into *next* Day,
- * e.g.: 'Sunday' -> 22
- * 'SundayLast' -> ??
- */
- if (flags & F_ISDAY) {
-#ifdef DEBUG
- fprintf(stderr, "\nday: %d %s month %d\n", day, endp, month);
-#endif
-
- *varp = 1;
- /* variable weekday, SundayLast, MondayFirst ... */
- if (day < 0 || day >= 10) {
-
- /* negative offset; last, -4 .. -1 */
- if (day < 0) {
- v1 = day / 10 - 1; /* offset -4 ... -1 */
- day = 10 + (day % 10); /* day 1 ... 7 */
-
- /* day, eg '22nd' */
- v2 = tp->tm_mday +
- (((day - 1) - tp->tm_wday + 7) % 7);
-
- /* (month length - day) / 7 + 1 */
- if (cumdays[month + 1] - cumdays[month] >= v2
- && ((int)((cumdays[month + 1] -
- cumdays[month] - v2) / 7) + 1) == -v1)
- day = v2; /* bingo ! */
-
- /* set to yesterday */
- else {
- day = tp->tm_mday - 1;
- if (day == 0)
- return (0);
- }
- }
-
- /* first, second ... +1 ... +5 */
- else {
- /* offset: +1 (first Sunday) ... */
- v1 = day / 10;
- day = day % 10;
-
- /* day, eg '22th' */
- v2 = tp->tm_mday +
- (((day - 1) - tp->tm_wday + 7) % 7);
-
- /* Hurrah! matched */
- if (((v2 - 1 + 7) / 7) == v1 )
- day = v2;
-
- else {
- /* set to yesterday */
- day = tp->tm_mday - 1;
- if (day == 0)
- return (0);
- }
- }
- } else {
- /* wired */
- day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7);
- *varp = 1;
- }
- }
-
- if (!(flags & F_EASTER)) {
- if (day + cumdays[month] > cumdays[month + 1]) {
- /* off end of month, adjust */
- day -= (cumdays[month + 1] - cumdays[month]);
- /* next year */
- if (++month > 12)
- month = 1;
- }
- *monthp = month;
- *dayp = day;
- day = cumdays[month] + day;
- } else {
- for (v1 = 0; day > cumdays[v1]; v1++)
- ;
- *monthp = v1 - 1;
- *dayp = day - cumdays[v1 - 1];
- *varp = 1;
- }
-
-#ifdef DEBUG
- fprintf(stderr, "day2: day %d(%d-%d) yday %d\n",
- *dayp, day, cumdays[month], tp->tm_yday);
-#endif
-
- /* When days before or days after is specified */
- /* no year rollover */
- if (day >= tp->tm_yday - f_dayBefore &&
- day <= tp->tm_yday + f_dayAfter)
- return (1);
-
- /* next year */
- if (tp->tm_yday + f_dayAfter >= yrdays) {
- int end = tp->tm_yday + f_dayAfter - yrdays;
- if (day <= end)
- return (1);
- }
-
- /* previous year */
- if (tp->tm_yday - f_dayBefore < 0) {
- int before = yrdays + (tp->tm_yday - f_dayBefore);
- if (day >= before)
- return (1);
- }
-
- return (0);
-}
-
-
-int
-getmonth(char *s)
-{
- const char **p;
- struct fixs *n;
-
- for (n = fnmonths; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - fnmonths) + 1);
- for (n = nmonths; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - nmonths) + 1);
- for (p = months; *p; ++p)
- if (!strncasecmp(s, *p, 3))
- return ((p - months) + 1);
- return (0);
-}
-
-
-int
-getday(char *s)
-{
- const char **p;
- struct fixs *n;
-
- for (n = fndays; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - fndays) + 1);
- for (n = ndays; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - ndays) + 1);
- for (p = days; *p; ++p)
- if (!strncasecmp(s, *p, 3))
- return ((p - days) + 1);
- return (0);
-}
-
-/* return offset for variable weekdays
- * -1 -> last weekday in month
- * +1 -> first weekday in month
- * ... etc ...
- */
-int
-getdayvar(char *s)
-{
- int offs;
-
- offs = strlen(s);
-
- /* Sun+1 or Wednesday-2
- * ^ ^ */
-
- /* fprintf(stderr, "x: %s %s %d\n", s, s + offs - 2, offs); */
- switch (*(s + offs - 2)) {
- case '-':
- return (-(atoi(s + offs - 1)));
- case '+':
- return (atoi(s + offs - 1));
- }
-
- /*
- * some aliases: last, first, second, third, fourth
- */
-
- /* last */
- if (offs > 4 && !strcasecmp(s + offs - 4, "last"))
- return (-1);
- else if (offs > 5 && !strcasecmp(s + offs - 5, "first"))
- return (+1);
- else if (offs > 6 && !strcasecmp(s + offs - 6, "second"))
- return (+2);
- else if (offs > 5 && !strcasecmp(s + offs - 5, "third"))
- return (+3);
- else if (offs > 6 && !strcasecmp(s + offs - 6, "fourth"))
- return (+4);
-
- /* no offset detected */
- return (0);
-}
diff --git a/usr.bin/calendar/events.c b/usr.bin/calendar/events.c
new file mode 100644
index 0000000..d6f358a
--- /dev/null
+++ b/usr.bin/calendar/events.c
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 1992-2009 Edwin Groothuis <edwin@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 <sys/time.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pathnames.h"
+#include "calendar.h"
+
+struct event *
+event_add(int year, int month, int day, char *date, int var, char *txt,
+ char *extra)
+{
+ struct event *e;
+
+ /*
+ * Creating a new event:
+ * - Create a new event
+ * - Copy the machine readable day and month
+ * - Copy the human readable and language specific date
+ * - Copy the text of the event
+ */
+ e = (struct event *)calloc(1, sizeof(struct event));
+ if (e == NULL)
+ errx(1, "event_add: cannot allocate memory");
+ e->month = month;
+ e->day = day;
+ e->var = var;
+ e->date = strdup(date);
+ if (e->date == NULL)
+ errx(1, "event_add: cannot allocate memory");
+ e->text = strdup(txt);
+ if (e->text == NULL)
+ errx(1, "event_add: cannot allocate memory");
+ e->extra = NULL;
+ if (extra != NULL && extra[0] != '\0')
+ e->extra = strdup(extra);
+ addtodate(e, year, month, day);
+ return (e);
+}
+
+void
+event_continue(struct event *e, char *txt)
+{
+ char *text;
+
+ /*
+ * Adding text to the event:
+ * - Save a copy of the old text (unknown length, so strdup())
+ * - Allocate enough space for old text + \n + new text + 0
+ * - Store the old text + \n + new text
+ * - Destroy the saved copy.
+ */
+ text = strdup(e->text);
+ if (text == NULL)
+ errx(1, "event_continue: cannot allocate memory");
+
+ free(e->text);
+ e->text = (char *)malloc(strlen(text) + strlen(txt) + 3);
+ if (e->text == NULL)
+ errx(1, "event_continue: cannot allocate memory");
+ strcpy(e->text, text);
+ strcat(e->text, "\n");
+ strcat(e->text, txt);
+ free(text);
+
+ return;
+}
+
+void
+event_print_all(FILE *fp)
+{
+ struct event *e;
+
+ while (walkthrough_dates(&e) != 0) {
+#ifdef DEBUG
+ fprintf(stderr, "event_print_allmonth: %d, day: %d\n",
+ month, day);
+#endif
+
+ /*
+ * Go through all events and print the text of the matching
+ * dates
+ */
+ while (e != NULL) {
+ (void)fprintf(fp, "%s%c%s%s%s%s\n", e->date,
+ e->var ? '*' : ' ', e->text,
+ e->extra != NULL ? " (" : "",
+ e->extra != NULL ? e->extra : "",
+ e->extra != NULL ? ")" : ""
+ );
+
+ e = e->next;
+ }
+ }
+}
diff --git a/usr.bin/calendar/io.c b/usr.bin/calendar/io.c
index 03f28fe..42abca6 100644
--- a/usr.bin/calendar/io.c
+++ b/usr.bin/calendar/io.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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 the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -46,11 +42,8 @@ static char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
@@ -66,62 +59,61 @@ __FBSDID("$FreeBSD$");
#include "pathnames.h"
#include "calendar.h"
-/*
- * Event sorting related functions:
- * - Use event_add() to create a new event
- * - Use event_continue() to add more text to the last added event
- * - Use event_print_all() to display them in time chronological order
- */
-static struct event *event_add(struct event *, int, int, char *, int, char *);
-static void event_continue(struct event *events, char *txt);
-static void event_print_all(FILE *fp, struct event *events);
-struct event {
- int month;
- int day;
- int var;
- char *date;
- char *text;
- struct event *next;
-};
-
const char *calendarFile = "calendar"; /* default calendar file */
const char *calendarHomes[] = {".calendar", _PATH_INCLUDE}; /* HOME */
const char *calendarNoMail = "nomail"; /* don't sent mail if this file exist */
char path[MAXPATHLEN];
-struct fixs neaster, npaskha;
-
-struct iovec header[] = {
- {"From: ", 6},
- {NULL, 0},
- {" (Reminder Service)\nTo: ", 24},
- {NULL, 0},
- {"\nSubject: ", 10},
- {NULL, 0},
- {"'s Calendar\nPrecedence: bulk\n\n", 30},
-};
-
+struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon;
+struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice;
+
+#define REPLACE(string, slen, struct_) \
+ if (strncasecmp(buf, (string), (slen)) == 0 && buf[(slen)]) { \
+ if (struct_.name != NULL) \
+ free(struct_.name); \
+ if ((struct_.name = strdup(buf + (slen))) == NULL) \
+ errx(1, "cannot allocate memory"); \
+ struct_.len = strlen(buf + (slen)); \
+ continue; \
+ }
void
cal(void)
{
- int printing;
- char *p;
+ char *pp, p;
FILE *fp;
int ch, l;
- int month;
- int day;
- int var;
+ int count, i;
+ int month[MAXCOUNT];
+ int day[MAXCOUNT];
+ int year[MAXCOUNT];
+ char **extradata; /* strings of 20 length */
+ int flags;
static int d_first = -1;
char buf[2048 + 1];
- struct event *events = NULL;
+ struct event *events[MAXCOUNT];
+ struct tm tm;
+ char dbuf[80];
+
+ extradata = (char **)calloc(MAXCOUNT, sizeof(char *));
+ for (i = 0; i < MAXCOUNT; i++) {
+ extradata[i] = (char *)calloc(1, 20);
+ }
+
+ /* Unused */
+ tm.tm_sec = 0;
+ tm.tm_min = 0;
+ tm.tm_hour = 0;
+ tm.tm_wday = 0;
+ count = 0;
if ((fp = opencal()) == NULL)
return;
- for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) {
- if ((p = strchr(buf, '\n')) != NULL)
- *p = '\0';
+ while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ if ((pp = strchr(buf, '\n')) != NULL)
+ *pp = '\0';
else
+ /* Flush this line */
while ((ch = getchar()) != '\n' && ch != EOF);
for (l = strlen(buf);
l > 0 && isspace((unsigned char)buf[l - 1]);
@@ -130,246 +122,87 @@ cal(void)
buf[l] = '\0';
if (buf[0] == '\0')
continue;
+
+ /* Parse special definitions: LANG, Easter, Paskha etc */
if (strncmp(buf, "LANG=", 5) == 0) {
(void)setlocale(LC_ALL, buf + 5);
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
setnnames();
continue;
}
- if (strncasecmp(buf, "Easter=", 7) == 0 && buf[7]) {
- if (neaster.name != NULL)
- free(neaster.name);
- if ((neaster.name = strdup(buf + 7)) == NULL)
- errx(1, "cannot allocate memory");
- neaster.len = strlen(buf + 7);
- continue;
- }
- if (strncasecmp(buf, "Paskha=", 7) == 0 && buf[7]) {
- if (npaskha.name != NULL)
- free(npaskha.name);
- if ((npaskha.name = strdup(buf + 7)) == NULL)
- errx(1, "cannot allocate memory");
- npaskha.len = strlen(buf + 7);
+ REPLACE("Easter=", 7, neaster);
+ REPLACE("Paskha=", 7, npaskha);
+ REPLACE("ChineseNewYear=", 15, ncny);
+ REPLACE("NewMoon=", 8, nnewmoon);
+ REPLACE("FullMoon=", 9, nfullmoon);
+ REPLACE("MarEquinox=", 11, nmarequinox);
+ REPLACE("SepEquinox=", 11, nsepequinox);
+ REPLACE("JunSolstice=", 12, njunsolstice);
+ REPLACE("DecSolstice=", 12, ndecsolstice);
+ if (strncmp(buf, "SEQUENCE=", 9) == 0) {
+ setnsequences(buf + 9);
continue;
}
- if (buf[0] != '\t') {
- printing = isnow(buf, &month, &day, &var) ? 1 : 0;
- if ((p = strchr(buf, '\t')) == NULL)
- continue;
- if (p > buf && p[-1] == '*')
- var = 1;
- if (printing) {
- struct tm tm;
- char dbuf[80];
-
- if (d_first < 0)
- d_first =
- (*nl_langinfo(D_MD_ORDER) == 'd');
- tm.tm_sec = 0; /* unused */
- tm.tm_min = 0; /* unused */
- tm.tm_hour = 0; /* unused */
- tm.tm_wday = 0; /* unused */
- tm.tm_mon = month - 1;
- tm.tm_mday = day;
- tm.tm_year = tp->tm_year; /* unused */
- (void)strftime(dbuf, sizeof(dbuf),
- d_first ? "%e %b" : "%b %e", &tm);
- events = event_add(events, month, day, dbuf,
- var, p);
- }
- } else {
- if (printing)
- event_continue(events, buf);
- }
- }
-
- event_print_all(fp, events);
- closecal(fp);
-}
-
-static struct event *
-event_add(struct event *events, int month, int day,
- char *date, int var, char *txt)
-{
- struct event *e;
-
- /*
- * Creating a new event:
- * - Create a new event
- * - Copy the machine readable day and month
- * - Copy the human readable and language specific date
- * - Copy the text of the event
- */
- e = (struct event *)calloc(1, sizeof(struct event));
- if (e == NULL)
- errx(1, "event_add: cannot allocate memory");
- e->month = month;
- e->day = day;
- e->var = var;
- e->date = strdup(date);
- if (e->date == NULL)
- errx(1, "event_add: cannot allocate memory");
- e->text = strdup(txt);
- if (e->text == NULL)
- errx(1, "event_add: cannot allocate memory");
- e->next = events;
-
- return e;
-}
-
-static void
-event_continue(struct event *e, char *txt)
-{
- char *text;
-
- /*
- * Adding text to the event:
- * - Save a copy of the old text (unknown length, so strdup())
- * - Allocate enough space for old text + \n + new text + 0
- * - Store the old text + \n + new text
- * - Destroy the saved copy.
- */
- text = strdup(e->text);
- if (text == NULL)
- errx(1, "event_continue: cannot allocate memory");
-
- free(e->text);
- e->text = (char *)malloc(strlen(text) + strlen(txt) + 3);
- if (e->text == NULL)
- errx(1, "event_continue: cannot allocate memory");
- strcpy(e->text, text);
- strcat(e->text, "\n");
- strcat(e->text, txt);
- free(text);
-
- return;
-}
-
-static void
-event_print_all(FILE *fp, struct event *events)
-{
- struct event *e, *e_next;
- int daycounter;
- int day, month;
-
- /*
- * Print all events:
- * - We know the number of days to be counted (f_dayAfter + f_dayBefore)
- * - We know the current day of the year ("now" - f_dayBefore + counter)
- * - We know the number of days in the year (yrdays, set in settime())
- * - So we know the date on which the current daycounter is on the
- * calendar in days and months.
- * - Go through the list of events, and print all matching dates
- */
- for (daycounter = 0; daycounter <= f_dayAfter + f_dayBefore;
- daycounter++) {
- day = tp->tm_yday - f_dayBefore + daycounter;
- if (day < 0)
- day += yrdays;
- if (day >= yrdays)
- day -= yrdays;
/*
- * When we know the day of the year, we can determine the day
- * of the month and the month.
+ * If the line starts with a tab, the data has to be
+ * added to the previous line
*/
- month = 1;
- while (month <= 12) {
- if (day <= cumdays[month])
- break;
- month++;
+ if (buf[0] == '\t') {
+ for (i = 0; i < count; i++)
+ event_continue(events[i], buf);
+ continue;
}
- month--;
- day -= cumdays[month];
-#ifdef DEBUG
- fprintf(stderr, "event_print_allmonth: %d, day: %d\n",
- month, day);
-#endif
+ /* Get rid of leading spaces (non-standard) */
+ while (isspace(buf[0]))
+ memcpy(buf, buf + 1, strlen(buf) - 1);
- /*
- * Go through all events and print the text of the matching
- * dates
- */
- for (e = events; e != NULL; e = e_next) {
- e_next = e->next;
+ /* No tab in the line, then not a valid line */
+ if ((pp = strchr(buf, '\t')) == NULL)
+ continue;
- if (month != e->month || day != e->day)
- continue;
+ /* Trim spaces in front of the tab */
+ while (isspace(pp[-1]))
+ pp--;
- (void)fprintf(fp, "%s%c%s\n", e->date,
- e->var ? '*' : ' ', e->text);
+ p = *pp;
+ *pp = '\0';
+ if ((count = parsedaymonth(buf, year, month, day, &flags,
+ extradata)) == 0)
+ continue;
+ *pp = p;
+ if (count < 0) {
+ /* Show error status based on return value */
+ fprintf(stderr, "Ignored: %s\n", buf);
+ if (count == -1)
+ continue;
+ count = -count + 1;
}
- }
-}
-int
-getfield(char *p, char **endp, int *flags)
-{
- int val, var;
- char *start, savech;
+ /* Find the last tab */
+ while (pp[1] == '\t')
+ pp++;
- for (; !isdigit((unsigned char)*p) && !isalpha((unsigned char)*p)
- && *p != '*'; ++p)
- ;
- if (*p == '*') { /* `*' is current month */
- *flags |= F_ISMONTH;
- *endp = p + 1;
- return (tp->tm_mon + 1);
- }
- if (isdigit((unsigned char)*p)) {
- val = strtol(p, &p, 10); /* if 0, it's failure */
- for (; !isdigit((unsigned char)*p)
- && !isalpha((unsigned char)*p) && *p != '*'; ++p);
- *endp = p;
- return (val);
- }
- for (start = p; isalpha((unsigned char)*++p););
-
- /* Sunday-1 */
- if (*p == '+' || *p == '-')
- for(; isdigit((unsigned char)*++p);)
- ;
-
- savech = *p;
- *p = '\0';
-
- /* Month */
- if ((val = getmonth(start)) != 0)
- *flags |= F_ISMONTH;
-
- /* Day */
- else if ((val = getday(start)) != 0) {
- *flags |= F_ISDAY;
+ if (d_first < 0)
+ d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
- /* variable weekday */
- if ((var = getdayvar(start)) != 0) {
- if (var <= 5 && var >= -4)
- val += var * 10;
-#ifdef DEBUG
- printf("var: %d\n", var);
-#endif
+ for (i = 0; i < count; i++) {
+ tm.tm_mon = month[i] - 1;
+ tm.tm_mday = day[i];
+ tm.tm_year = year[i] - 1900;
+ (void)strftime(dbuf, sizeof(dbuf),
+ d_first ? "%e %b" : "%b %e", &tm);
+ if (debug)
+ fprintf(stderr, "got %s\n", pp);
+ events[i] = event_add(year[i], month[i], day[i], dbuf,
+ ((flags &= F_VARIABLE) != 0) ? 1 : 0, pp,
+ extradata[i]);
}
}
- /* Easter */
- else if ((val = geteaster(start, tp->tm_year + 1900)) != 0)
- *flags |= F_EASTER;
-
- /* Paskha */
- else if ((val = getpaskha(start, tp->tm_year + 1900)) != 0)
- *flags |= F_EASTER;
-
- /* undefined rest */
- else {
- *p = savech;
- return (0);
- }
- for (*p = savech; !isdigit((unsigned char)*p)
- && !isalpha((unsigned char)*p) && *p != '*'; ++p)
- ;
- *endp = p;
- return (val);
+ event_print_all(fp);
+ closecal(fp);
}
FILE *
@@ -505,9 +338,14 @@ closecal(FILE *fp)
/* parent -- write to pipe input */
(void)close(pdes[0]);
- header[1].iov_base = header[3].iov_base = pw->pw_name;
- header[1].iov_len = header[3].iov_len = strlen(pw->pw_name);
- writev(pdes[1], header, 7);
+ write(pdes[1], "From: \"Reminder Service\" <", 26);
+ write(pdes[1], pw->pw_name, strlen(pw->pw_name));
+ write(pdes[1], ">\nTo: <", 7);
+ write(pdes[1], pw->pw_name, strlen(pw->pw_name));
+ write(pdes[1], ">\nSubject: ", 12);
+ write(pdes[1], dayname, strlen(dayname));
+ write(pdes[1], "'s Calendar\nPrecedence: bulk\n\n", 30);
+
while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0)
(void)write(pdes[1], buf, nread);
(void)close(pdes[1]);
diff --git a/usr.bin/calendar/locale.c b/usr.bin/calendar/locale.c
new file mode 100644
index 0000000..57839ac
--- /dev/null
+++ b/usr.bin/calendar/locale.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <ctype.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "calendar.h"
+
+const char *fdays[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
+ "Saturday", NULL,
+};
+
+const char *days[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL,
+};
+
+const char *fmonths[] = {
+ "January", "February", "March", "April", "May", "June", "Juli",
+ "August", "September", "October", "November", "December", NULL,
+};
+
+const char *months[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL,
+};
+
+const char *sequences[] = {
+ "First", "Second", "Third", "Fourth", "Fifth", "Last"
+};
+
+struct fixs fndays[8]; /* full national days names */
+struct fixs ndays[8]; /* short national days names */
+struct fixs fnmonths[13]; /* full national months names */
+struct fixs nmonths[13]; /* short national month names */
+struct fixs nsequences[10]; /* national sequence names */
+
+
+void
+setnnames(void)
+{
+ char buf[80];
+ int i, l;
+ struct tm tm;
+
+ for (i = 0; i < 7; i++) {
+ tm.tm_wday = i;
+ strftime(buf, sizeof(buf), "%a", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (ndays[i].name != NULL)
+ free(ndays[i].name);
+ if ((ndays[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ ndays[i].len = strlen(buf);
+
+ strftime(buf, sizeof(buf), "%A", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (fndays[i].name != NULL)
+ free(fndays[i].name);
+ if ((fndays[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ fndays[i].len = strlen(buf);
+ }
+
+ for (i = 0; i < 12; i++) {
+ tm.tm_mon = i;
+ strftime(buf, sizeof(buf), "%b", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (nmonths[i].name != NULL)
+ free(nmonths[i].name);
+ if ((nmonths[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ nmonths[i].len = strlen(buf);
+
+ strftime(buf, sizeof(buf), "%B", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (fnmonths[i].name != NULL)
+ free(fnmonths[i].name);
+ if ((fnmonths[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ fnmonths[i].len = strlen(buf);
+ }
+}
+
+void
+setnsequences(char *seq)
+{
+ int i;
+ char *p;
+
+ p = seq;
+ for (i = 0; i < 5; i++) {
+ nsequences[i].name = p;
+ if ((p = strchr(p, ' ')) == NULL) {
+ for (i = 0; i < 5; i++) {
+ nsequences[i].name = NULL;
+ nsequences[i].len = 0;
+ return;
+ }
+
+ }
+ *p = '\0';
+ p++;
+ }
+ nsequences[i].name = p;
+
+ for (i = 0; i < 5; i++) {
+ nsequences[i].name = strdup(nsequences[i].name);
+ nsequences[i].len = nsequences[i + 1].name - nsequences[i].name;
+ }
+ nsequences[i].name = strdup(nsequences[i].name);
+ nsequences[i].len = strlen(nsequences[i].name);
+
+ return;
+}
diff --git a/usr.bin/calendar/ostern.c b/usr.bin/calendar/ostern.c
index 89e7b1c..3cce299 100644
--- a/usr.bin/calendar/ostern.c
+++ b/usr.bin/calendar/ostern.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
* All rights reserved.
*
@@ -60,50 +60,8 @@ easter(int year) /* 0 ... abcd, NOT since 1900 */
L = I - J;
- if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
+ if (isleap(year))
return 31 + 29 + 21 + L + 7;
else
return 31 + 28 + 21 + L + 7;
}
-
-/* return year day for Easter or easter depending days
- * Match: Easter([+-][0-9]+)?
- * e.g: Easter-2 is Good Friday (2 days before Easter)
- */
-
-int
-geteaster(char *s, int year)
-{
- int offset = 0;
-
-#define EASTER "easter"
-#define EASTERNAMELEN (sizeof(EASTER) - 1)
-
- if (strncasecmp(s, EASTER, EASTERNAMELEN) == 0)
- s += EASTERNAMELEN;
- else if (neaster.name != NULL
- && strncasecmp(s, neaster.name, neaster.len) == 0)
- s += neaster.len;
- else
- return (0);
-
-#ifdef DEBUG
- printf("%s %d %d\n", s, year, EASTERNAMELEN);
-#endif
-
- /* Easter+1 or Easter-2
- * ^ ^ */
-
- switch (*s) {
-
- case '-':
- case '+':
- offset = atoi(s);
- break;
-
- default:
- offset = 0;
- }
-
- return (easter(year) + offset);
-}
diff --git a/usr.bin/calendar/parsedata.c b/usr.bin/calendar/parsedata.c
new file mode 100644
index 0000000..4fab640
--- /dev/null
+++ b/usr.bin/calendar/parsedata.c
@@ -0,0 +1,1009 @@
+/*-
+ * Copyright (c) 1992-2009 Edwin Groothuis <edwin@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 <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+
+#include "calendar.h"
+
+static char *showflags(int flags);
+static int isonlydigits(char *s, int nostar);
+static const char *getmonthname(int i);
+static int checkmonth(char *s, size_t *len, size_t *offset, const char **month);
+static const char *getdayofweekname(int i);
+static int checkdayofweek(char *s, size_t *len, size_t *offset, const char **dow);
+static int indextooffset(char *s);
+static int parseoffset(char *s);
+static char *floattoday(int year, double f);
+static char *floattotime(double f);
+
+/*
+ * Expected styles:
+ *
+ * Date ::= Month . ' ' . DayOfMonth |
+ * Month . ' ' . DayOfWeek . ModifierIndex |
+ * Month . '/' . DayOfMonth |
+ * Month . '/' . DayOfWeek . ModifierIndex |
+ * DayOfMonth . ' ' . Month |
+ * DayOfMonth . '/' . Month |
+ * DayOfWeek . ModifierIndex . ' ' .Month |
+ * DayOfWeek . ModifierIndex . '/' .Month |
+ * DayOfWeek . ModifierIndex |
+ * SpecialDay . ModifierOffset
+ *
+ * Month ::= MonthName | MonthNumber | '*'
+ * MonthNumber ::= '0' ... '9' | '00' ... '09' | '10' ... '12'
+ * MonthName ::= MonthNameShort | MonthNameLong
+ * MonthNameLong ::= 'January' ... 'December'
+ * MonthNameShort ::= 'Jan' ... 'Dec' | 'Jan.' ... 'Dec.'
+ *
+ * DayOfWeek ::= DayOfWeekShort | DayOfWeekLong
+ * DayOfWeekShort ::= 'Mon' .. 'Sun'
+ * DayOfWeekLong ::= 'Monday' .. 'Sunday'
+ * DayOfMonth ::= '0' ... '9' | '00' ... '09' | '10' ... '29' |
+ * '30' ... '31' | '*'
+ *
+ * ModifierOffset ::= '' | '+' . ModifierNumber | '-' . ModifierNumber
+ * ModifierNumber ::= '0' ... '9' | '00' ... '99' | '000' ... '299' |
+ * '300' ... '359' | '360' ... '365'
+ * ModifierIndex ::= 'Second' | 'Third' | 'Fourth' | 'Fifth' |
+ * 'First' | 'Last'
+ *
+ * SpecialDay ::= 'Easter' | 'Pashka' | 'ChineseNewYear'
+ *
+ */
+static int
+determinestyle(char *date, int *flags,
+ char *month, int *imonth, char *dayofmonth, int *idayofmonth,
+ char *dayofweek, int *idayofweek, char *modifieroffset,
+ char *modifierindex, char *specialday)
+{
+ char *p, *p1, *p2;
+ const char *dow, *pmonth;
+ char pold;
+ size_t len, offset;
+
+ *flags = F_NONE;
+ *month = '\0';
+ *imonth = 0;
+ *dayofmonth = '\0';
+ *idayofmonth = 0;
+ *dayofweek = '\0';
+ *idayofweek = 0;
+ *modifieroffset = '\0';
+ *modifierindex = '\0';
+ *specialday = '\0';
+
+#define CHECKSPECIAL(s1, s2, lens2, type) \
+ if (s2 != NULL && strncmp(s1, s2, lens2) == 0) { \
+ *flags |= F_SPECIALDAY; \
+ *flags |= type; \
+ *flags |= F_VARIABLE; \
+ if (strlen(s1) == lens2) { \
+ strcpy(specialday, s1); \
+ return (1); \
+ } \
+ strncpy(specialday, s1, lens2); \
+ specialday[lens2] = '\0'; \
+ strcpy(modifieroffset, s1 + lens2); \
+ *flags |= F_MODIFIEROFFSET; \
+ return (1); \
+ }
+
+ if ((p = strchr(date, ' ')) == NULL) {
+ if ((p = strchr(date, '/')) == NULL) {
+ CHECKSPECIAL(date, STRING_CNY, strlen(STRING_CNY),
+ F_CNY);
+ CHECKSPECIAL(date, ncny.name, ncny.len, F_CNY);
+ CHECKSPECIAL(date, STRING_NEWMOON,
+ strlen(STRING_NEWMOON), F_NEWMOON);
+ CHECKSPECIAL(date, nnewmoon.name, nnewmoon.len,
+ F_NEWMOON);
+ CHECKSPECIAL(date, STRING_FULLMOON,
+ strlen(STRING_FULLMOON), F_FULLMOON);
+ CHECKSPECIAL(date, nfullmoon.name, nfullmoon.len,
+ F_FULLMOON);
+ CHECKSPECIAL(date, STRING_PASKHA,
+ strlen(STRING_PASKHA), F_PASKHA);
+ CHECKSPECIAL(date, npaskha.name, npaskha.len, F_PASKHA);
+ CHECKSPECIAL(date, STRING_EASTER,
+ strlen(STRING_EASTER), F_EASTER);
+ CHECKSPECIAL(date, neaster.name, neaster.len, F_EASTER);
+ CHECKSPECIAL(date, STRING_MAREQUINOX,
+ strlen(STRING_MAREQUINOX), F_MAREQUINOX);
+ CHECKSPECIAL(date, nmarequinox.name, nmarequinox.len,
+ F_SEPEQUINOX);
+ CHECKSPECIAL(date, STRING_SEPEQUINOX,
+ strlen(STRING_SEPEQUINOX), F_SEPEQUINOX);
+ CHECKSPECIAL(date, nsepequinox.name, nsepequinox.len,
+ F_SEPEQUINOX);
+ CHECKSPECIAL(date, STRING_JUNSOLSTICE,
+ strlen(STRING_JUNSOLSTICE), F_JUNSOLSTICE);
+ CHECKSPECIAL(date, njunsolstice.name, njunsolstice.len,
+ F_JUNSOLSTICE);
+ CHECKSPECIAL(date, STRING_DECSOLSTICE,
+ strlen(STRING_DECSOLSTICE), F_DECSOLSTICE);
+ CHECKSPECIAL(date, ndecsolstice.name, ndecsolstice.len,
+ F_DECSOLSTICE);
+ if (checkdayofweek(date, &len, &offset, &dow) != 0) {
+ *flags |= F_DAYOFWEEK;
+ *flags |= F_VARIABLE;
+ *idayofweek = offset;
+ if (strlen(date) == len) {
+ strcpy(dayofweek, date);
+ return (1);
+ }
+ strncpy(dayofweek, date, len);
+ dayofweek[len] = '\0';
+ strcpy(modifierindex, date + len);
+ *flags |= F_MODIFIERINDEX;
+ return (1);
+ }
+ if (isonlydigits(date, 1)) {
+ /* Assume month number only */
+ *flags |= F_MONTH;
+ *imonth = (int)strtol(date, (char **)NULL, 10);
+ strcpy(month, getmonthname(*imonth));
+ return(1);
+ }
+ return (0);
+ }
+ }
+
+ /*
+ * AFTER this, leave by goto-ing to "allfine" or "fail" to restore the
+ * original data in `date'.
+ */
+ pold = *p;
+ *p = 0;
+ p1 = date;
+ p2 = p + 1;
+ /* Now p2 points to the next field and p1 to the first field */
+
+ /* Check if there is a month-string in the date */
+ if ((checkmonth(p1, &len, &offset, &pmonth) != 0)
+ || (checkmonth(p2, &len, &offset, &pmonth) != 0 && (p2 = p1))) {
+ /* p2 is the non-month part */
+ *flags |= F_MONTH;
+ *imonth = offset;
+
+ strcpy(month, getmonthname(offset));
+ if (isonlydigits(p2, 1)) {
+ strcpy(dayofmonth, p2);
+ *idayofmonth = (int)strtol(p2, (char **)NULL, 10);
+ *flags |= F_DAYOFMONTH;
+ goto allfine;
+ }
+ if (strcmp(p2, "*") == 0) {
+ *flags |= F_ALLDAY;
+ goto allfine;
+ }
+
+ if (checkdayofweek(p2, &len, &offset, &dow) != 0) {
+ *flags |= F_DAYOFWEEK;
+ *flags |= F_VARIABLE;
+ *idayofweek = offset;
+ strcpy(dayofweek, getdayofweekname(offset));
+ if (strlen(p2) == len)
+ goto allfine;
+ strcpy(modifierindex, p2 + len);
+ *flags |= F_MODIFIERINDEX;
+ goto allfine;
+ }
+
+ goto fail;
+ }
+
+ /* Check if there is an every-day or every-month in the string */
+ if ((strcmp(p1, "*") == 0 && isonlydigits(p2, 1))
+ || (strcmp(p2, "*") == 0 && isonlydigits(p1, 1) && (p2 = p1))) {
+ int d;
+
+ *flags |= F_ALLMONTH;
+ *flags |= F_DAYOFMONTH;
+ d = (int)strtol(p2, (char **)NULL, 10);
+ *idayofmonth = d;
+ sprintf(dayofmonth, "%d", d);
+ goto allfine;
+ }
+
+ /* Month as a number, then a weekday */
+ if (isonlydigits(p1, 1)
+ && checkdayofweek(p2, &len, &offset, &dow) != 0) {
+ int d;
+
+ *flags |= F_MONTH;
+ *flags |= F_DAYOFWEEK;
+ *flags |= F_VARIABLE;
+
+ *idayofweek = offset;
+ d = (int)strtol(p1, (char **)NULL, 10);
+ *imonth = d;
+ strcpy(month, getmonthname(d));
+
+ strcpy(dayofweek, getdayofweekname(offset));
+ if (strlen(p2) == len)
+ goto allfine;
+ strcpy(modifierindex, p2 + len);
+ *flags |= F_MODIFIERINDEX;
+ goto allfine;
+ }
+
+ /* If both the month and date are specified as numbers */
+ if (isonlydigits(p1, 1) && isonlydigits(p2, 0)) {
+ /* Now who wants to be this ambigious? :-( */
+ int m, d;
+
+ if (strchr(p2, '*') != NULL)
+ *flags |= F_VARIABLE;
+
+ m = (int)strtol(p1, (char **)NULL, 10);
+ d = (int)strtol(p2, (char **)NULL, 10);
+
+ *flags |= F_MONTH;
+ *flags |= F_DAYOFMONTH;
+
+ if (m > 12) {
+ *imonth = d;
+ *idayofmonth = m;
+ strcpy(month, getmonthname(d));
+ sprintf(dayofmonth, "%d", m);
+ } else {
+ *imonth = m;
+ *idayofmonth = d;
+ strcpy(month, getmonthname(m));
+ sprintf(dayofmonth, "%d", d);
+ }
+ goto allfine;
+ }
+
+ /* FALLTHROUGH */
+fail:
+ *p = pold;
+ return (0);
+allfine:
+ *p = pold;
+ return (1);
+
+}
+
+static void
+remember(int *rememberindex, int *y, int *m, int *d, char **ed, int yy, int mm,
+ int dd, char *extra)
+{
+ static int warned = 0;
+
+ if (*rememberindex >= MAXCOUNT - 1) {
+ if (warned == 0)
+ warnx("Index > %d, ignored", MAXCOUNT);
+ warned++;
+ return;
+ }
+ y[*rememberindex] = yy;
+ m[*rememberindex] = mm;
+ d[*rememberindex] = dd;
+ if (extra != NULL)
+ strcpy(ed[*rememberindex], extra);
+ else
+ ed[*rememberindex][0] = '\0';
+ *rememberindex += 1;
+}
+
+static void
+debug_determinestyle(int dateonly, char *date, int flags, char *month,
+ int imonth, char *dayofmonth, int idayofmonth, char *dayofweek,
+ int idayofweek, char *modifieroffset, char *modifierindex, char *specialday)
+{
+
+ if (dateonly != 0) {
+ printf("-------\ndate: |%s|\n", date);
+ if (dateonly == 1)
+ return;
+ }
+ printf("flags: %x - %s\n", flags, showflags(flags));
+ if (modifieroffset[0] != '\0')
+ printf("modifieroffset: |%s|\n", modifieroffset);
+ if (modifierindex[0] != '\0')
+ printf("modifierindex: |%s|\n", modifierindex);
+ if (month[0] != '\0')
+ printf("month: |%s| (%d)\n", month, imonth);
+ if (dayofmonth[0] != '\0')
+ printf("dayofmonth: |%s| (%d)\n", dayofmonth, idayofmonth);
+ if (dayofweek[0] != '\0')
+ printf("dayofweek: |%s| (%d)\n", dayofweek, idayofweek);
+ if (specialday[0] != '\0')
+ printf("specialday: |%s|\n", specialday);
+}
+
+struct yearinfo {
+ int year;
+ int ieaster, ipaskha, firstcnyday;
+ double ffullmoon[MAXMOONS], fnewmoon[MAXMOONS];
+ double ffullmooncny[MAXMOONS], fnewmooncny[MAXMOONS];
+ int ichinesemonths[MAXMOONS];
+ double equinoxdays[2], solsticedays[2];
+ int *mondays;
+ struct yearinfo *next;
+};
+/*
+ * Possible date formats include any combination of:
+ * 3-charmonth (January, Jan, Jan)
+ * 3-charweekday (Friday, Monday, mon.)
+ * numeric month or day (1, 2, 04)
+ *
+ * Any character may separate them, or they may not be separated. Any line,
+ * following a line that is matched, that starts with "whitespace", is shown
+ * along with the matched line.
+ */
+int
+parsedaymonth(char *date, int *yearp, int *monthp, int *dayp, int *flags,
+ char **edp)
+{
+ char month[100], dayofmonth[100], dayofweek[100], modifieroffset[100];
+ char modifierindex[100], specialday[100];
+ int idayofweek = -1, imonth = -1, idayofmonth = -1, year, remindex;
+ int d, m, dow, rm, rd, offset;
+ char *ed;
+ int retvalsign = 1;
+
+ static struct yearinfo *years, *yearinfo;
+
+ /*
+ * CONVENTION
+ *
+ * Month: 1-12
+ * Monthname: Jan .. Dec
+ * Day: 1-31
+ * Weekday: Mon .. Sun
+ *
+ */
+
+ *flags = 0;
+
+ if (debug)
+ debug_determinestyle(1, date, *flags, month, imonth,
+ dayofmonth, idayofmonth, dayofweek, idayofweek,
+ modifieroffset, modifierindex, specialday);
+ if (determinestyle(date, flags, month, &imonth, dayofmonth,
+ &idayofmonth, dayofweek, &idayofweek, modifieroffset,
+ modifierindex, specialday) == 0) {
+ if (debug)
+ printf("Failed!\n");
+ return (0);
+ }
+
+ if (debug)
+ debug_determinestyle(0, date, *flags, month, imonth,
+ dayofmonth, idayofmonth, dayofweek, idayofweek,
+ modifieroffset, modifierindex, specialday);
+
+ remindex = 0;
+ for (year = year1; year <= year2; year++) {
+ /* Get important dates for this year */
+ yearinfo = years;
+ while (yearinfo != NULL) {
+ if (yearinfo->year == year)
+ break;
+ yearinfo = yearinfo -> next;
+ }
+ if (yearinfo == NULL) {
+ yearinfo = (struct yearinfo *)calloc(1,
+ sizeof(struct yearinfo));
+ if (yearinfo == NULL)
+ errx(1, "Unable to allocate more years");
+ yearinfo->year = year;
+ yearinfo->next = years;
+ years = yearinfo;
+
+ yearinfo->mondays = mondaytab[isleap(year)];
+ yearinfo->ieaster = easter(year);
+ fpom(year, UTCOffset, yearinfo->ffullmoon,
+ yearinfo->fnewmoon);
+ fpom(year, UTCOFFSET_CNY, yearinfo->ffullmooncny,
+ yearinfo->fnewmooncny);
+ fequinoxsolstice(year, UTCOffset,
+ yearinfo->equinoxdays, yearinfo->solsticedays);
+
+ /*
+ * CNY: Match day with sun longitude at 330` with new
+ * moon
+ */
+ yearinfo->firstcnyday = calculatesunlongitude30(year,
+ UTCOFFSET_CNY, yearinfo->ichinesemonths);
+ for (m = 0; yearinfo->fnewmooncny[m] >= 0; m++) {
+ if (yearinfo->fnewmooncny[m] >
+ yearinfo->firstcnyday) {
+ yearinfo->firstcnyday =
+ floor(yearinfo->fnewmooncny[m - 1]);
+ break;
+ }
+ }
+ }
+
+ /* Same day every year */
+ if (*flags == (F_MONTH | F_DAYOFMONTH)) {
+ if (!remember_ymd(year, imonth, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, imonth, idayofmonth, NULL);
+ continue;
+ }
+
+ /* XXX Same day every year, but variable */
+ if (*flags == (F_MONTH | F_DAYOFMONTH | F_VARIABLE)) {
+ if (!remember_ymd(year, imonth, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, imonth, idayofmonth, NULL);
+ continue;
+ }
+
+ /* Same day every month */
+ if (*flags == (F_ALLMONTH | F_DAYOFMONTH)) {
+ for (m = 1; m <= 12; m++) {
+ if (!remember_ymd(year, m, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, m, idayofmonth, NULL);
+ }
+ continue;
+ }
+
+ /* Every day of a month */
+ if (*flags == (F_ALLDAY | F_MONTH)) {
+ for (d = 1; d <= yearinfo->mondays[imonth]; d++) {
+ if (!remember_ymd(year, imonth, d))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ }
+ continue;
+ }
+
+ /* One day of every month */
+ if (*flags == (F_ALLMONTH | F_DAYOFWEEK)) {
+ for (m = 1; m <= 12; m++) {
+ if (!remember_ymd(year, m, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, m, idayofmonth, NULL);
+ }
+ continue;
+ }
+
+ /* Every dayofweek of the year */
+ if (*flags == (F_DAYOFWEEK | F_VARIABLE)) {
+ dow = first_dayofweek_of_year(year);
+ d = (idayofweek - dow + 8) % 7;
+ while (d <= 366) {
+ if (remember_yd(year, d, &rm, &rd))
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ d += 7;
+ }
+ continue;
+ }
+
+ /* A certain dayofweek of a month */
+ if (*flags ==
+ (F_MONTH | F_DAYOFWEEK | F_MODIFIERINDEX | F_VARIABLE)) {
+ offset = indextooffset(modifierindex);
+ dow = first_dayofweek_of_month(year, imonth);
+ d = (idayofweek - dow + 8) % 7;
+
+ if (offset > 0) {
+ while (d <= yearinfo->mondays[imonth]) {
+ if (--offset == 0
+ && remember_ymd(year, imonth, d)) {
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ continue;
+ }
+ d += 7;
+ }
+ continue;
+ }
+ if (offset < 0) {
+ while (d <= yearinfo->mondays[imonth])
+ d += 7;
+ while (offset != 0) {
+ offset++;
+ d -= 7;
+ }
+ if (remember_ymd(year, imonth, d))
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ continue;
+ }
+ continue;
+ }
+
+ /* Every dayofweek of the month */
+ if (*flags == (F_DAYOFWEEK | F_MONTH | F_VARIABLE)) {
+ dow = first_dayofweek_of_month(year, imonth);
+ d = (idayofweek - dow + 8) % 7;
+ while (d <= yearinfo->mondays[imonth]) {
+ if (remember_ymd(year, imonth, d))
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ d += 7;
+ }
+ continue;
+ }
+
+ /* Easter */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_EASTER)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->ieaster + offset,
+ &rm, &rd))
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ continue;
+ }
+
+ /* Paskha */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_PASKHA)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->ipaskha + offset,
+ &rm, &rd))
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ continue;
+ }
+
+ /* Chinese New Year */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_CNY)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->firstcnyday + offset,
+ &rm, &rd))
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ continue;
+ }
+
+ /* FullMoon */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_FULLMOON)) {
+ int i;
+
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ for (i = 0; yearinfo->ffullmoon[i] > 0; i++) {
+ if (remember_yd(year,
+ floor(yearinfo->ffullmoon[i]) + offset,
+ &rm, &rd)) {
+ ed = floattotime(
+ yearinfo->ffullmoon[i]);
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ }
+ continue;
+ }
+
+ /* NewMoon */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_NEWMOON)) {
+ int i;
+
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ for (i = 0; yearinfo->ffullmoon[i] > 0; i++) {
+ if (remember_yd(year,
+ floor(yearinfo->fnewmoon[i]) + offset,
+ &rm, &rd)) {
+ ed = floattotime(yearinfo->fnewmoon[i]);
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ }
+ continue;
+ }
+
+ /* (Mar|Sep)Equinox */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_MAREQUINOX)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->equinoxdays[0] + offset,
+ &rm, &rd)) {
+ ed = floattotime(yearinfo->equinoxdays[0]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_SEPEQUINOX)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->equinoxdays[1] + offset,
+ &rm, &rd)) {
+ ed = floattotime(yearinfo->equinoxdays[1]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+
+ /* (Jun|Dec)Solstice */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_JUNSOLSTICE)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year,
+ yearinfo->solsticedays[0] + offset, &rm, &rd)) {
+ ed = floattotime(yearinfo->solsticedays[0]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_DECSOLSTICE)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year,
+ yearinfo->solsticedays[1] + offset, &rm, &rd)) {
+ ed = floattotime(yearinfo->solsticedays[1]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+
+ printf("Unprocessed:\n");
+ debug_determinestyle(2, date, *flags, month, imonth,
+ dayofmonth, idayofmonth, dayofweek, idayofweek,
+ modifieroffset, modifierindex, specialday);
+ retvalsign = -1;
+ }
+
+ if (retvalsign == -1)
+ return (-remindex - 1);
+ else
+ return (remindex);
+}
+
+static char *
+showflags(int flags)
+{
+ static char s[1000];
+ s[0] = '\0';
+
+ if ((flags & F_MONTH) != 0)
+ strcat(s, "month ");
+ if ((flags & F_DAYOFWEEK) != 0)
+ strcat(s, "dayofweek ");
+ if ((flags & F_DAYOFMONTH) != 0)
+ strcat(s, "dayofmonth ");
+ if ((flags & F_MODIFIERINDEX) != 0)
+ strcat(s, "modifierindex ");
+ if ((flags & F_MODIFIEROFFSET) != 0)
+ strcat(s, "modifieroffset ");
+ if ((flags & F_SPECIALDAY) != 0)
+ strcat(s, "specialday ");
+ if ((flags & F_ALLMONTH) != 0)
+ strcat(s, "allmonth ");
+ if ((flags & F_ALLDAY) != 0)
+ strcat(s, "allday ");
+ if ((flags & F_VARIABLE) != 0)
+ strcat(s, "variable ");
+ if ((flags & F_CNY) != 0)
+ strcat(s, "chinesenewyear ");
+ if ((flags & F_PASKHA) != 0)
+ strcat(s, "paskha ");
+ if ((flags & F_EASTER) != 0)
+ strcat(s, "easter ");
+ if ((flags & F_FULLMOON) != 0)
+ strcat(s, "fullmoon ");
+ if ((flags & F_NEWMOON) != 0)
+ strcat(s, "newmoon ");
+ if ((flags & F_MAREQUINOX) != 0)
+ strcat(s, "marequinox ");
+ if ((flags & F_SEPEQUINOX) != 0)
+ strcat(s, "sepequinox ");
+ if ((flags & F_JUNSOLSTICE) != 0)
+ strcat(s, "junsolstice ");
+ if ((flags & F_DECSOLSTICE) != 0)
+ strcat(s, "decsolstice ");
+
+ return s;
+}
+
+static const char *
+getmonthname(int i)
+{
+ if (nmonths[i - 1].len != 0 && nmonths[i - 1].name != NULL)
+ return (nmonths[i - 1].name);
+ return (months[i - 1]);
+}
+
+static int
+checkmonth(char *s, size_t *len, size_t *offset, const char **month)
+{
+ struct fixs *n;
+ int i;
+
+ for (i = 0; fnmonths[i].name != NULL; i++) {
+ n = fnmonths + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *month = n->name;
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ for (i = 0; nmonths[i].name != NULL; i++) {
+ n = nmonths + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *month = n->name;
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ for (i = 0; fmonths[i] != NULL; i++) {
+ *len = strlen(fmonths[i]);
+ if (strncasecmp(s, fmonths[i], *len) == 0) {
+ *month = fmonths[i];
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ for (i = 0; months[i] != NULL; i++) {
+ if (strncasecmp(s, months[i], 3) == 0) {
+ *len = 3;
+ *month = months[i];
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static const char *
+getdayofweekname(int i)
+{
+ if (ndays[i].len != 0 && ndays[i].name != NULL)
+ return (ndays[i].name);
+ return (days[i]);
+}
+
+static int
+checkdayofweek(char *s, size_t *len, size_t *offset, const char **dow)
+{
+ struct fixs *n;
+ int i;
+
+ for (i = 0; fndays[i].name != NULL; i++) {
+ n = fndays + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *dow = n->name;
+ *offset = i;
+ return (1);
+ }
+ }
+ for (i = 0; ndays[i].name != NULL; i++) {
+ n = ndays + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *dow = n->name;
+ *offset = i;
+ return (1);
+ }
+ }
+ for (i = 0; fdays[i] != NULL; i++) {
+ *len = strlen(fdays[i]);
+ if (strncasecmp(s, fdays[i], *len) == 0) {
+ *dow = fdays[i];
+ *offset = i;
+ return (1);
+ }
+ }
+ for (i = 0; days[i] != NULL; i++) {
+ if (strncasecmp(s, days[i], 3) == 0) {
+ *len = 3;
+ *dow = days[i];
+ *offset = i;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static int
+isonlydigits(char *s, int nostar)
+{
+ int i;
+ for (i = 0; s[i] != '\0'; i++) {
+ if (nostar == 0 && s[i] == '*' && s[i + 1] == '\0')
+ return 1;
+ if (!isdigit(s[i]))
+ return (0);
+ }
+ return (1);
+}
+
+static int
+indextooffset(char *s)
+{
+ int i;
+ struct fixs *n;
+
+ for (i = 0; i < 6; i++) {
+ if (strcasecmp(s, sequences[i]) == 0) {
+ if (i == 5)
+ return (-1);
+ return (i + 1);
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ n = nsequences + i;
+ if (n->len == 0)
+ continue;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ if (i == 5)
+ return (-1);
+ return (i + 1);
+ }
+ }
+ return (0);
+}
+
+static int
+parseoffset(char *s)
+{
+
+ return strtol(s, NULL, 10);
+}
+
+static char *
+floattotime(double f)
+{
+ static char buf[100];
+ int hh, mm, ss, i;
+
+ f -= floor(f);
+ i = f * SECSPERDAY;
+
+ hh = i / SECSPERHOUR;
+ i %= SECSPERHOUR;
+ mm = i / SECSPERMINUTE;
+ i %= SECSPERMINUTE;
+ ss = i;
+
+ sprintf(buf, "%02d:%02d:%02d", hh, mm, ss);
+ return (buf);
+}
+
+static char *
+floattoday(int year, double f)
+{
+ static char buf[100];
+ int i, m, d, hh, mm, ss;
+ int *cumdays = cumdaytab[isleap(year)];
+
+ for (i = 0; 1 + cumdays[i] < f; i++)
+ ;;
+ m = --i;
+ d = floor(f - 1 - cumdays[i]);
+ f -= floor(f);
+ i = f * SECSPERDAY;
+
+ hh = i / SECSPERHOUR;
+ i %= SECSPERHOUR;
+ mm = i / SECSPERMINUTE;
+ i %= SECSPERMINUTE;
+ ss = i;
+
+ sprintf(buf, "%02d-%02d %02d:%02d:%02d", m, d, hh, mm, ss);
+ return (buf);
+}
+
+void
+dodebug(char *what)
+{
+ int year;
+
+ printf("UTCOffset: %g\n", UTCOffset);
+ printf("eastlongitude: %d\n", EastLongitude);
+
+ if (strcmp(what, "moon") == 0) {
+ double ffullmoon[MAXMOONS], fnewmoon[MAXMOONS];
+ int i;
+
+ for (year = year1; year <= year2; year++) {
+ fpom(year, UTCOffset, ffullmoon, fnewmoon);
+ printf("Full moon %d:\t", year);
+ for (i = 0; ffullmoon[i] >= 0; i++) {
+ printf("%g (%s) ", ffullmoon[i],
+ floattoday(year, ffullmoon[i]));
+ }
+ printf("\nNew moon %d:\t", year);
+ for (i = 0; fnewmoon[i] >= 0; i++) {
+ printf("%g (%s) ", fnewmoon[i],
+ floattoday(year, fnewmoon[i]));
+ }
+ printf("\n");
+
+ }
+
+ return;
+ }
+
+ if (strcmp(what, "sun") == 0) {
+ double equinoxdays[2], solsticedays[2];
+ for (year = year1; year <= year2; year++) {
+ printf("Sun in %d:\n", year);
+ fequinoxsolstice(year, UTCOffset, equinoxdays,
+ solsticedays);
+ printf("e[0] - %g (%s)\n",
+ equinoxdays[0],
+ floattoday(year, equinoxdays[0]));
+ printf("e[1] - %g (%s)\n",
+ equinoxdays[1],
+ floattoday(year, equinoxdays[1]));
+ printf("s[0] - %g (%s)\n",
+ solsticedays[0],
+ floattoday(year, solsticedays[0]));
+ printf("s[1] - %g (%s)\n",
+ solsticedays[1],
+ floattoday(year, solsticedays[1]));
+ }
+ return;
+ }
+}
diff --git a/usr.bin/calendar/paskha.c b/usr.bin/calendar/paskha.c
index e713f5f..373ee5d 100644
--- a/usr.bin/calendar/paskha.c
+++ b/usr.bin/calendar/paskha.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (C) 1993-1996 by Andrey A. Chernov, Moscow, Russia.
* All rights reserved.
*
@@ -36,55 +36,22 @@ __FBSDID("$FreeBSD$");
#define PASKHA "paskha"
#define PASKHALEN (sizeof(PASKHA) - 1)
-static int paskha(int);
-
/* return year day for Orthodox Easter using Gauss formula */
/* (old style result) */
-static int
+int
paskha(int R) /*year*/
{
int a, b, c, d, e;
static int x = 15;
static int y = 6;
+ int *cumday;
a = R % 19;
b = R % 4;
c = R % 7;
d = (19 * a + x) % 30;
e = (2 * b + 4 * c + 6 * d + y) % 7;
- return (((cumdays[3] + 1) + 22) + (d + e));
-}
-
-/* return year day for Orthodox Easter depending days */
-
-int
-getpaskha(char *s, int year)
-{
- int offset;
-
- if (strncasecmp(s, PASKHA, PASKHALEN) == 0)
- s += PASKHALEN;
- else if (npaskha.name != NULL
- && strncasecmp(s, npaskha.name, npaskha.len) == 0)
- s += npaskha.len;
- else
- return 0;
-
- /* Paskha+1 or Paskha-2
- * ^ ^ */
-
- switch (*s) {
-
- case '-':
- case '+':
- offset = atoi(s);
- break;
-
- default:
- offset = 0;
- break;
- }
-
- return (paskha(year) + offset + 13 /* new style */);
+ cumday = cumdaytab[isleap(R)];
+ return (((cumday[3] + 1) + 22) + (d + e));
}
diff --git a/usr.bin/calendar/pathnames.h b/usr.bin/calendar/pathnames.h
index cacbd25..ea76948 100644
--- a/usr.bin/calendar/pathnames.h
+++ b/usr.bin/calendar/pathnames.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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 the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
diff --git a/usr.bin/calendar/pom.c b/usr.bin/calendar/pom.c
new file mode 100644
index 0000000..89d06a2
--- /dev/null
+++ b/usr.bin/calendar/pom.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software posted to USENET.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#if 0
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static const char sccsid[] = "@(#)pom.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Phase of the Moon. Calculates the current phase of the moon.
+ * Based on routines from `Practical Astronomy with Your Calculator',
+ * by Duffett-Smith. Comments give the section from the book that
+ * particular piece of code was adapted from.
+ *
+ * -- Keith E. Brandt VIII 1984
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "calendar.h"
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+#define EPOCH 85
+#define EPSILONg 279.611371 /* solar ecliptic long at EPOCH */
+#define RHOg 282.680403 /* solar ecliptic long of perigee at EPOCH */
+#define ECCEN 0.01671542 /* solar orbit eccentricity */
+#define lzero 18.251907 /* lunar mean long at EPOCH */
+#define Pzero 192.917585 /* lunar mean long of perigee at EPOCH */
+#define Nzero 55.204723 /* lunar mean long of node at EPOCH */
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+static void adj360(double *);
+static double dtor(double);
+static double potm(double onday);
+static double potm_minute(double onday, int olddir);
+
+void
+pom(int year, double utcoffset, int *fms, int *nms)
+{
+ double ffms[MAXMOONS];
+ double fnms[MAXMOONS];
+ int i, j;
+
+ fpom(year, utcoffset, ffms, fnms);
+
+ j = 0;
+ for (i = 0; ffms[i] != 0; i++)
+ fms[j++] = round(ffms[i]);
+ fms[i] = -1;
+ for (i = 0; fnms[i] != 0; i++)
+ nms[i] = round(fnms[i]);
+ nms[i] = -1;
+}
+
+void
+fpom(int year, double utcoffset, double *ffms, double *fnms)
+{
+ time_t tt;
+ struct tm GMT, tmd_today, tmd_tomorrow;
+ double days_today, days_tomorrow, today, tomorrow;
+ int cnt, d;
+ int yeardays;
+ int olddir, newdir;
+ double *pfnms, *pffms, t;
+
+ pfnms = fnms;
+ pffms = ffms;
+
+ /*
+ * We take the phase of the moon one second before and one second
+ * after midnight.
+ */
+ memset(&tmd_today, 0, sizeof(tmd_today));
+ tmd_today.tm_year = year - 1900;
+ tmd_today.tm_mon = 0;
+ tmd_today.tm_mday = -1; /* 31 December */
+ tmd_today.tm_hour = 23;
+ tmd_today.tm_min = 59;
+ tmd_today.tm_sec = 59;
+ memset(&tmd_tomorrow, 0, sizeof(tmd_tomorrow));
+ tmd_tomorrow.tm_year = year - 1900;
+ tmd_tomorrow.tm_mon = 0;
+ tmd_tomorrow.tm_mday = 0; /* 01 January */
+ tmd_tomorrow.tm_hour = 0;
+ tmd_tomorrow.tm_min = 0;
+ tmd_tomorrow.tm_sec = 1;
+
+ tt = mktime(&tmd_today);
+ gmtime_r(&tt, &GMT);
+ yeardays = 0;
+ for (cnt = EPOCH; cnt < GMT.tm_year; ++cnt)
+ yeardays += isleap(1900 + cnt) ? DAYSPERLEAPYEAR : DAYSPERYEAR;
+ days_today = (GMT.tm_yday + 1) + ((GMT.tm_hour +
+ (GMT.tm_min / FSECSPERMINUTE) + (GMT.tm_sec / FSECSPERHOUR)) /
+ FHOURSPERDAY);
+ days_today += yeardays;
+
+ tt = mktime(&tmd_tomorrow);
+ gmtime_r(&tt, &GMT);
+ yeardays = 0;
+ for (cnt = EPOCH; cnt < GMT.tm_year; ++cnt)
+ yeardays += isleap(1900 + cnt) ? DAYSPERLEAPYEAR : DAYSPERYEAR;
+ days_tomorrow = (GMT.tm_yday + 1) + ((GMT.tm_hour +
+ (GMT.tm_min / FSECSPERMINUTE) + (GMT.tm_sec / FSECSPERHOUR)) /
+ FHOURSPERDAY);
+ days_tomorrow += yeardays;
+
+ today = potm(days_today); /* 30 December 23:59:59 */
+ tomorrow = potm(days_tomorrow); /* 31 December 00:00:01 */
+ olddir = today > tomorrow ? -1 : +1;
+
+ yeardays = 1 + isleap(year) ? DAYSPERLEAPYEAR : DAYSPERYEAR; /* reuse */
+ for (d = 0; d <= yeardays; d++) {
+ today = potm(days_today);
+ tomorrow = potm(days_tomorrow);
+ newdir = today > tomorrow ? -1 : +1;
+ if (olddir != newdir) {
+ t = potm_minute(days_today - 1, olddir) +
+ utcoffset / FHOURSPERDAY;
+ if (olddir == -1 && newdir == +1) {
+ *pfnms = d - 1 + t;
+ pfnms++;
+ } else if (olddir == +1 && newdir == -1) {
+ *pffms = d - 1 + t;
+ pffms++;
+ }
+ }
+ olddir = newdir;
+ days_today++;
+ days_tomorrow++;
+ }
+ *pffms = -1;
+ *pfnms = -1;
+}
+
+static double
+potm_minute(double onday, int olddir) {
+ double period = FSECSPERDAY / 2.0;
+ double p1, p2;
+ double before, after;
+ int newdir;
+
+// printf("---> days:%g olddir:%d\n", days, olddir);
+
+ p1 = onday + (period / SECSPERDAY);
+ period /= 2;
+
+ while (period > 30) { /* half a minute */
+// printf("period:%g - p1:%g - ", period, p1);
+ p2 = p1 + (2.0 / SECSPERDAY);
+ before = potm(p1);
+ after = potm(p2);
+// printf("before:%10.10g - after:%10.10g\n", before, after);
+ newdir = before < after ? -1 : +1;
+ if (olddir != newdir)
+ p1 += (period / SECSPERDAY);
+ else
+ p1 -= (period / SECSPERDAY);
+ period /= 2;
+// printf("newdir:%d - p1:%10.10f - period:%g\n",
+// newdir, p1, period);
+ }
+ p1 -= floor(p1);
+ //exit(0);
+ return (p1);
+}
+
+/*
+ * potm --
+ * return phase of the moon, as a percentage [0 ... 100]
+ */
+static double
+potm(double onday)
+{
+ double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
+ double A4, lprime, V, ldprime, D, Nm;
+
+ N = 360 * onday / 365.2422; /* sec 42 #3 */
+ adj360(&N);
+ Msol = N + EPSILONg - RHOg; /* sec 42 #4 */
+ adj360(&Msol);
+ Ec = 360 / PI * ECCEN * sin(dtor(Msol)); /* sec 42 #5 */
+ LambdaSol = N + Ec + EPSILONg; /* sec 42 #6 */
+ adj360(&LambdaSol);
+ l = 13.1763966 * onday + lzero; /* sec 61 #4 */
+ adj360(&l);
+ Mm = l - (0.1114041 * onday) - Pzero; /* sec 61 #5 */
+ adj360(&Mm);
+ Nm = Nzero - (0.0529539 * onday); /* sec 61 #6 */
+ adj360(&Nm);
+ Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 61 #7 */
+ Ac = 0.1858 * sin(dtor(Msol)); /* sec 61 #8 */
+ A3 = 0.37 * sin(dtor(Msol));
+ Mmprime = Mm + Ev - Ac - A3; /* sec 61 #9 */
+ Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 61 #10 */
+ A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 61 #11 */
+ lprime = l + Ev + Ec - Ac + A4; /* sec 61 #12 */
+ V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 61 #13 */
+ ldprime = lprime + V; /* sec 61 #14 */
+ D = ldprime - LambdaSol; /* sec 63 #2 */
+ return(50 * (1 - cos(dtor(D)))); /* sec 63 #3 */
+}
+
+/*
+ * dtor --
+ * convert degrees to radians
+ */
+static double
+dtor(double deg)
+{
+
+ return(deg * PI / 180);
+}
+
+/*
+ * adj360 --
+ * adjust value so 0 <= deg <= 360
+ */
+static void
+adj360(double *deg)
+{
+
+ for (;;)
+ if (*deg < 0)
+ *deg += 360;
+ else if (*deg > 360)
+ *deg -= 360;
+ else
+ break;
+}
diff --git a/usr.bin/calendar/sunpos.c b/usr.bin/calendar/sunpos.c
new file mode 100644
index 0000000..a0546e5
--- /dev/null
+++ b/usr.bin/calendar/sunpos.c
@@ -0,0 +1,448 @@
+/*-
+ * Copyright (c) 2009-2010 Edwin Groothuis <edwin@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$");
+
+/*
+ * This code is created to match the formulas available at:
+ * Formula and examples obtained from "How to Calculate alt/az: SAAO" at
+ * http://www.saao.ac.za/public-info/sun-moon-stars/sun-index/how-to-calculate-altaz/
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+#include <time.h>
+#include "calendar.h"
+
+#define D2R(m) ((m) / 180 * M_PI)
+#define R2D(m) ((m) * 180 / M_PI)
+
+#define SIN(x) (sin(D2R(x)))
+#define COS(x) (cos(D2R(x)))
+#define TAN(x) (tan(D2R(x)))
+#define ASIN(x) (R2D(asin(x)))
+#define ATAN(x) (R2D(atan(x)))
+
+#ifdef NOTDEF
+static void
+comp(char *s, double v, double c)
+{
+
+ printf("%-*s %*g %*g %*g\n", 15, s, 15, v, 15, c, 15, v - c);
+}
+
+int expY;
+double expZJ = 30.5;
+double expUTHM = 8.5;
+double expD = 34743.854;
+double expT = 0.9512349;
+double expL = 324.885;
+double expM = 42.029;
+double expepsilon = 23.4396;
+double explambda = 326.186;
+double expalpha = 328.428;
+double expDEC = -12.789;
+double expeastlongitude = 17.10;
+double explatitude = -22.57;
+double expHA = -37.673;
+double expALT = 49.822;
+double expAZ = 67.49;
+#endif
+
+static double
+fixup(double *d)
+{
+
+ if (*d < 0) {
+ while (*d < 0)
+ *d += 360;
+ } else {
+ while (*d > 360)
+ *d -= 360;
+ }
+
+ return (*d);
+}
+
+static double ZJtable[] = {
+ 0, -0.5, 30.5, 58.5, 89.5, 119.5, 150.5, 180.5, 211.5, 242.5, 272.5, 303.5, 333.5 };
+
+static void
+sunpos(int inYY, int inMM, int inDD, double UTCOFFSET, int inHOUR, int inMIN,
+ int inSEC, double eastlongitude, double latitude, double *L, double *DEC)
+{
+ int Y;
+ double ZJ, D, T, M, epsilon, lambda, alpha, HA, UTHM;
+
+ ZJ = ZJtable[inMM];
+ if (inMM <= 2 && isleap(inYY))
+ ZJ -= 1.0;
+
+ UTHM = inHOUR + inMIN / FMINSPERHOUR + inSEC / FSECSPERHOUR - UTCOFFSET;
+ Y = inYY - 1900; /* 1 */
+ D = floor(365.25 * Y) + ZJ + inDD + UTHM / FHOURSPERDAY; /* 3 */
+ T = D / 36525.0; /* 4 */
+ *L = 279.697 + 36000.769 * T; /* 5 */
+ fixup(L);
+ M = 358.476 + 35999.050 * T; /* 6 */
+ fixup(&M);
+ epsilon = 23.452 - 0.013 * T; /* 7 */
+ fixup(&epsilon);
+
+ lambda = *L + (1.919 - 0.005 * T) * SIN(M) + 0.020 * SIN(2 * M);/* 8 */
+ fixup(&lambda);
+ alpha = ATAN(TAN(lambda) * COS(epsilon)); /* 9 */
+
+ /* Alpha should be in the same quadrant as lamba */
+ {
+ int lssign = sin(D2R(lambda)) < 0 ? -1 : 1;
+ int lcsign = cos(D2R(lambda)) < 0 ? -1 : 1;
+ while (((sin(D2R(alpha)) < 0) ? -1 : 1) != lssign
+ || ((cos(D2R(alpha)) < 0) ? -1 : 1) != lcsign)
+ alpha += 90.0;
+ }
+ fixup(&alpha);
+
+ *DEC = ASIN(SIN(lambda) * SIN(epsilon)); /* 10 */
+ fixup(DEC);
+ fixup(&eastlongitude);
+ HA = *L - alpha + 180 + 15 * UTHM + eastlongitude; /* 12 */
+ fixup(&HA);
+ fixup(&latitude);
+#ifdef NOTDEF
+ printf("%02d/%02d %02d:%02d:%02d l:%g d:%g h:%g\n",
+ inMM, inDD, inHOUR, inMIN, inSEC, latitude, *DEC, HA);
+#endif
+ return;
+
+ /*
+ * The following calculations are not used, so to save time
+ * they are not calculated.
+ */
+#ifdef NOTDEF
+ *ALT = ASIN(SIN(latitude) * SIN(*DEC) +
+ COS(latitude) * COS(*DEC) * COS(HA)); /* 13 */
+ fixup(ALT);
+ *AZ = ATAN(SIN(HA) /
+ (COS(HA) * SIN(latitude) - TAN(*DEC) * COS(latitude))); /* 14 */
+
+ if (*ALT > 180)
+ *ALT -= 360;
+ if (*ALT < -180)
+ *ALT += 360;
+ printf("a:%g a:%g\n", *ALT, *AZ);
+#endif
+
+#ifdef NOTDEF
+ printf("Y:\t\t\t %d\t\t %d\t\t %d\n", Y, expY, Y - expY);
+ comp("ZJ", ZJ, expZJ);
+ comp("UTHM", UTHM, expUTHM);
+ comp("D", D, expD);
+ comp("T", T, expT);
+ comp("L", L, fixup(&expL));
+ comp("M", M, fixup(&expM));
+ comp("epsilon", epsilon, fixup(&expepsilon));
+ comp("lambda", lambda, fixup(&explambda));
+ comp("alpha", alpha, fixup(&expalpha));
+ comp("DEC", DEC, fixup(&expDEC));
+ comp("eastlongitude", eastlongitude, fixup(&expeastlongitude));
+ comp("latitude", latitude, fixup(&explatitude));
+ comp("HA", HA, fixup(&expHA));
+ comp("ALT", ALT, fixup(&expALT));
+ comp("AZ", AZ, fixup(&expAZ));
+#endif
+}
+
+
+#define SIGN(a) (((a) > 180) ? -1 : 1)
+#define ANGLE(a, b) (((a) < (b)) ? 1 : -1)
+#define SHOUR(s) ((s) / 3600)
+#define SMIN(s) (((s) % 3600) / 60)
+#define SSEC(s) ((s) % 60)
+#define HOUR(h) ((h) / 4)
+#define MIN(h) (15 * ((h) % 4))
+#define SEC(h) 0
+#define DEBUG1(y, m, d, hh, mm, pdec, dec) \
+ printf("%4d-%02d-%02d %02d:%02d:00 - %7.7g -> %7.7g\n", \
+ y, m, d, hh, mm, pdec, dec)
+#define DEBUG2(y, m, d, hh, mm, pdec, dec, pang, ang) \
+ printf("%4d-%02d-%02d %02d:%02d:00 - %7.7g -> %7.7g - %d -> %d\n", \
+ y, m, d, hh, mm, pdec, dec, pang, ang)
+void
+equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays)
+{
+ double fe[2], fs[2];
+
+ fequinoxsolstice(year, UTCoffset, fe, fs);
+ equinoxdays[0] = round(fe[0]);
+ equinoxdays[1] = round(fe[1]);
+ solsticedays[0] = round(fs[0]);
+ solsticedays[1] = round(fs[1]);
+}
+
+void
+fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays)
+{
+ double dec, prevdec, L;
+ int h, d, prevangle, angle;
+ int found = 0;
+
+ double decleft, decright, decmiddle;
+ int dial, s;
+
+ int *cumdays;
+ cumdays = cumdaytab[isleap(year)];
+
+ /*
+ * Find the first equinox, somewhere in March:
+ * It happens when the returned value "dec" goes from
+ * [350 ... 360> -> [0 ... 10]
+ */
+ found = 0;
+ prevdec = 350;
+ for (d = 18; d < 31; d++) {
+// printf("Comparing day %d to %d.\n", d, d+1);
+ sunpos(year, 3, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
+ sunpos(year, 3, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
+ &L, &decright);
+// printf("Found %g and %g.\n", decleft, decright);
+ if (SIGN(decleft) == SIGN(decright))
+ continue;
+
+ dial = SECSPERDAY;
+ s = SECSPERDAY / 2;
+ while (s > 0) {
+// printf("Obtaining %d (%02d:%02d)\n",
+// dial, SHOUR(dial), SMIN(dial));
+ sunpos(year, 3, d, UTCoffset,
+ SHOUR(dial), SMIN(dial), SSEC(dial),
+ 0.0, 0.0, &L, &decmiddle);
+// printf("Found %g\n", decmiddle);
+ if (SIGN(decleft) == SIGN(decmiddle)) {
+ decleft = decmiddle;
+ dial += s;
+ } else {
+ decright = decmiddle;
+ dial -= s;
+ }
+// printf("New boundaries: %g - %g\n", decleft, decright);
+
+ s /= 2;
+ }
+ equinoxdays[0] = 1 + cumdays[3] + d + (dial / FSECSPERDAY);
+ break;
+ }
+
+ /* Find the second equinox, somewhere in September:
+ * It happens when the returned value "dec" goes from
+ * [10 ... 0] -> <360 ... 350]
+ */
+ found = 0;
+ prevdec = 10;
+ for (d = 18; d < 31; d++) {
+// printf("Comparing day %d to %d.\n", d, d+1);
+ sunpos(year, 9, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
+ sunpos(year, 9, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
+ &L, &decright);
+// printf("Found %g and %g.\n", decleft, decright);
+ if (SIGN(decleft) == SIGN(decright))
+ continue;
+
+ dial = SECSPERDAY;
+ s = SECSPERDAY / 2;
+ while (s > 0) {
+// printf("Obtaining %d (%02d:%02d)\n",
+// dial, SHOUR(dial), SMIN(dial));
+ sunpos(year, 9, d, UTCoffset,
+ SHOUR(dial), SMIN(dial), SSEC(dial),
+ 0.0, 0.0, &L, &decmiddle);
+// printf("Found %g\n", decmiddle);
+ if (SIGN(decleft) == SIGN(decmiddle)) {
+ decleft = decmiddle;
+ dial += s;
+ } else {
+ decright = decmiddle;
+ dial -= s;
+ }
+// printf("New boundaries: %g - %g\n", decleft, decright);
+
+ s /= 2;
+ }
+ equinoxdays[1] = 1 + cumdays[9] + d + (dial / FSECSPERDAY);
+ break;
+ }
+
+ /*
+ * Find the first solstice, somewhere in June:
+ * It happens when the returned value "dec" peaks
+ * [40 ... 45] -> [45 ... 40]
+ */
+ found = 0;
+ prevdec = 0;
+ prevangle = 1;
+ for (d = 18; d < 31; d++) {
+ for (h = 0; h < 4 * HOURSPERDAY; h++) {
+ sunpos(year, 6, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
+ 0.0, 0.0, &L, &dec);
+ angle = ANGLE(prevdec, dec);
+ if (prevangle != angle) {
+#ifdef NOTDEF
+ DEBUG2(year, 6, d, HOUR(h), MIN(h),
+ prevdec, dec, prevangle, angle);
+#endif
+ solsticedays[0] = 1 + cumdays[6] + d +
+ ((h / 4.0) / 24.0);
+ found = 1;
+ break;
+ }
+ prevdec = dec;
+ prevangle = angle;
+ }
+ if (found)
+ break;
+ }
+
+ /*
+ * Find the second solstice, somewhere in December:
+ * It happens when the returned value "dec" peaks
+ * [315 ... 310] -> [310 ... 315]
+ */
+ found = 0;
+ prevdec = 360;
+ prevangle = -1;
+ for (d = 18; d < 31; d++) {
+ for (h = 0; h < 4 * HOURSPERDAY; h++) {
+ sunpos(year, 12, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
+ 0.0, 0.0, &L, &dec);
+ angle = ANGLE(prevdec, dec);
+ if (prevangle != angle) {
+#ifdef NOTDEF
+ DEBUG2(year, 12, d, HOUR(h), MIN(h),
+ prevdec, dec, prevangle, angle);
+#endif
+ solsticedays[1] = 1 + cumdays[12] + d +
+ ((h / 4.0) / 24.0);
+ found = 1;
+ break;
+ }
+ prevdec = dec;
+ prevangle = angle;
+ }
+ if (found)
+ break;
+ }
+
+ return;
+}
+
+int
+calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths)
+{
+ int m, d, h;
+ double dec;
+ double curL, prevL;
+ int *pichinesemonths, *monthdays, *cumdays, i;
+ int firstmonth330 = -1;
+
+ cumdays = cumdaytab[isleap(year)];
+ monthdays = mondaytab[isleap(year)];
+ pichinesemonths = ichinesemonths;
+
+ h = 0;
+ sunpos(year - 1, 12, 31,
+ -24 * (degreeGMToffset / 360.0),
+ HOUR(h), MIN(h), SEC(h), 0.0, 0.0, &prevL, &dec);
+
+ for (m = 1; m <= 12; m++) {
+ for (d = 1; d <= monthdays[m]; d++) {
+ for (h = 0; h < 4 * HOURSPERDAY; h++) {
+ sunpos(year, m, d,
+ -24 * (degreeGMToffset / 360.0),
+ HOUR(h), MIN(h), SEC(h),
+ 0.0, 0.0, &curL, &dec);
+ if (curL < 180 && prevL > 180) {
+ *pichinesemonths = cumdays[m] + d;
+#ifdef DEBUG
+printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
+ year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
+#endif
+ pichinesemonths++;
+ } else {
+ for (i = 0; i <= 360; i += 30)
+ if (curL > i && prevL < i) {
+ *pichinesemonths =
+ cumdays[m] + d;
+#ifdef DEBUG
+printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
+ year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
+#endif
+ if (i == 330)
+ firstmonth330 = *pichinesemonths;
+ pichinesemonths++;
+ }
+ }
+ prevL = curL;
+ }
+ }
+ }
+ *pichinesemonths = -1;
+ return (firstmonth330);
+}
+
+#ifdef NOTDEF
+int
+main(int argc, char **argv)
+{
+/*
+ year Mar June Sept Dec
+ day time day time day time day time
+ 2004 20 06:49 21 00:57 22 16:30 21 12:42
+ 2005 20 12:33 21 06:46 22 22:23 21 18:35
+ 2006 20 18:26 21 12:26 23 04:03 22 00:22
+ 2007 21 00:07 21 18:06 23 09:51 22 06:08
+ 2008 20 05:48 20 23:59 22 15:44 21 12:04
+ 2009 20 11:44 21 05:45 22 21:18 21 17:47
+ 2010 20 17:32 21 11:28 23 03:09 21 23:38
+ 2011 20 23:21 21 17:16 23 09:04 22 05:30
+ 2012 20 05:14 20 23:09 22 14:49 21 11:11
+ 2013 20 11:02 21 05:04 22 20:44 21 17:11
+ 2014 20 16:57 21 10:51 23 02:29 21 23:03
+ 2015 20 22:45 21 16:38 23 08:20 22 04:48
+ 2016 20 04:30 20 22:34 22 14:21 21 10:44
+ 2017 20 10:28 21 04:24 22 20:02 21 16:28
+*/
+
+ int eq[2], sol[2];
+ equinoxsolstice(strtol(argv[1], NULL, 10), 0.0, eq, sol);
+ printf("%d - %d - %d - %d\n", eq[0], sol[0], eq[1], sol[1]);
+ return(0);
+}
+#endif
diff --git a/usr.bin/chpass/Makefile b/usr.bin/chpass/Makefile
index 7f7ac51..a5571d7 100644
--- a/usr.bin/chpass/Makefile
+++ b/usr.bin/chpass/Makefile
@@ -43,7 +43,7 @@ beforeinstall:
.if !defined(NO_FSCHG)
afterinstall:
- chflags schg ${DESTDIR}${BINDIR}/chpass
+ -chflags schg ${DESTDIR}${BINDIR}/chpass
.endif
.include <bsd.prog.mk>
diff --git a/usr.bin/column/column.1 b/usr.bin/column/column.1
index 5c5a100..d4418c5 100644
--- a/usr.bin/column/column.1
+++ b/usr.bin/column/column.1
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd July 29, 2004
-.Os
.Dt COLUMN 1
+.Os
.Sh NAME
.Nm column
.Nd columnate lists
diff --git a/usr.bin/comm/comm.1 b/usr.bin/comm/comm.1
index 02b508c..67b5eec 100644
--- a/usr.bin/comm/comm.1
+++ b/usr.bin/comm/comm.1
@@ -36,8 +36,8 @@
.\" $FreeBSD$
.\"
.Dd December 12, 2009
-.Os
.Dt COMM 1
+.Os
.Sh NAME
.Nm comm
.Nd select or reject lines common to two files
diff --git a/usr.bin/comm/comm.c b/usr.bin/comm/comm.c
index afda0e7..ddad5dc 100644
--- a/usr.bin/comm/comm.c
+++ b/usr.bin/comm/comm.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <locale.h>
#include <stdint.h>
+#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -60,40 +61,31 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
#include <wctype.h>
-#define INITLINELEN (LINE_MAX + 1)
-#define MAXLINELEN ((SIZE_MAX / sizeof(wchar_t)) / 2)
-
-const wchar_t *tabs[] = { L"", L"\t", L"\t\t" };
+int iflag;
+const char *tabs[] = { "", "\t", "\t\t" };
FILE *file(const char *);
-wchar_t *getline(wchar_t *, size_t *, FILE *);
-void show(FILE *, const char *, const wchar_t *, wchar_t *, size_t *);
-int wcsicoll(const wchar_t *, const wchar_t *);
+wchar_t *convert(const char *);
+void show(FILE *, const char *, const char *, char **, size_t *);
static void usage(void);
int
main(int argc, char *argv[])
{
int comp, read1, read2;
- int ch, flag1, flag2, flag3, iflag;
+ int ch, flag1, flag2, flag3;
FILE *fp1, *fp2;
- const wchar_t *col1, *col2, *col3;
+ const char *col1, *col2, *col3;
size_t line1len, line2len;
- wchar_t *line1, *line2;
- const wchar_t **p;
-
- flag1 = flag2 = flag3 = 1;
- iflag = 0;
-
- line1len = INITLINELEN;
- line2len = INITLINELEN;
- line1 = malloc(line1len * sizeof(*line1));
- line2 = malloc(line2len * sizeof(*line2));
- if (line1 == NULL || line2 == NULL)
- err(1, "malloc");
+ char *line1, *line2;
+ ssize_t n1, n2;
+ wchar_t *tline1, *tline2;
+ const char **p;
(void) setlocale(LC_ALL, "");
+ flag1 = flag2 = flag3 = 1;
+
while ((ch = getopt(argc, argv, "123i")) != -1)
switch(ch) {
case '1':
@@ -131,41 +123,57 @@ main(int argc, char *argv[])
if (flag3)
col3 = *p;
+ line1len = line2len = 0;
+ line1 = line2 = NULL;
+ n1 = n2 = -1;
+
for (read1 = read2 = 1;;) {
/* read next line, check for EOF */
if (read1) {
- line1 = getline(line1, &line1len, fp1);
- if (line1 == NULL && ferror(fp1))
+ n1 = getline(&line1, &line1len, fp1);
+ if (n1 < 0 && ferror(fp1))
err(1, "%s", argv[0]);
+ if (n1 > 0 && line1[n1 - 1] == '\n')
+ line1[n1 - 1] = '\0';
+
}
if (read2) {
- line2 = getline(line2, &line2len, fp2);
- if (line2 == NULL && ferror(fp2))
+ n2 = getline(&line2, &line2len, fp2);
+ if (n2 < 0 && ferror(fp2))
err(1, "%s", argv[1]);
+ if (n2 > 0 && line2[n2 - 1] == '\n')
+ line2[n2 - 1] = '\0';
}
/* if one file done, display the rest of the other file */
- if (line1 == NULL) {
- if (line2 != NULL && col2 != NULL)
- show(fp2, argv[1], col2, line2, &line2len);
+ if (n1 < 0) {
+ if (n2 >= 0 && col2 != NULL)
+ show(fp2, argv[1], col2, &line2, &line2len);
break;
}
- if (line2 == NULL) {
- if (line1 != NULL && col1 != NULL)
- show(fp1, argv[0], col1, line1, &line1len);
+ if (n2 < 0) {
+ if (n1 >= 0 && col1 != NULL)
+ show(fp1, argv[0], col1, &line1, &line1len);
break;
}
- /* lines are the same */
- if(iflag)
- comp = wcsicoll(line1, line2);
+ tline2 = NULL;
+ if ((tline1 = convert(line1)) != NULL)
+ tline2 = convert(line2);
+ if (tline1 == NULL || tline2 == NULL)
+ comp = strcmp(line1, line2);
else
- comp = wcscoll(line1, line2);
+ comp = wcscoll(tline1, tline2);
+ if (tline1 != NULL)
+ free(tline1);
+ if (tline2 != NULL)
+ free(tline2);
+ /* lines are the same */
if (!comp) {
read1 = read2 = 1;
if (col3 != NULL)
- (void)printf("%ls%ls\n", col3, line1);
+ (void)printf("%s%s\n", col3, line1);
continue;
}
@@ -174,49 +182,52 @@ main(int argc, char *argv[])
read1 = 1;
read2 = 0;
if (col1 != NULL)
- (void)printf("%ls%ls\n", col1, line1);
+ (void)printf("%s%s\n", col1, line1);
} else {
read1 = 0;
read2 = 1;
if (col2 != NULL)
- (void)printf("%ls%ls\n", col2, line2);
+ (void)printf("%s%s\n", col2, line2);
}
}
exit(0);
}
wchar_t *
-getline(wchar_t *buf, size_t *buflen, FILE *fp)
+convert(const char *str)
{
- size_t bufpos;
- wint_t ch;
+ size_t n;
+ wchar_t *buf, *p;
+
+ if ((n = mbstowcs(NULL, str, 0)) == (size_t)-1)
+ return (NULL);
+ if (SIZE_MAX / sizeof(*buf) < n + 1)
+ errx(1, "conversion buffer length overflow");
+ if ((buf = malloc((n + 1) * sizeof(*buf))) == NULL)
+ err(1, "malloc");
+ if (mbstowcs(buf, str, n + 1) != n)
+ errx(1, "internal mbstowcs() error");
- bufpos = 0;
- while ((ch = getwc(fp)) != WEOF && ch != '\n') {
- if (bufpos + 1 >= *buflen) {
- *buflen = *buflen * 2;
- if (*buflen > MAXLINELEN)
- errx(1,
- "Maximum line buffer length (%zu) exceeded",
- MAXLINELEN);
- buf = reallocf(buf, *buflen * sizeof(*buf));
- if (buf == NULL)
- err(1, "reallocf");
- }
- buf[bufpos++] = ch;
+ if (iflag) {
+ for (p = buf; *p != L'\0'; p++)
+ *p = towlower(*p);
}
- buf[bufpos] = '\0';
- return (bufpos != 0 || ch == '\n' ? buf : NULL);
+ return (buf);
}
void
-show(FILE *fp, const char *fn, const wchar_t *offset, wchar_t *buf, size_t *buflen)
+show(FILE *fp, const char *fn, const char *offset, char **bufp, size_t *buflenp)
{
+ ssize_t n;
do {
- (void)printf("%ls%ls\n", offset, buf);
- } while ((buf = getline(buf, buflen, fp)) != NULL);
+ (void)printf("%s%s\n", offset, *bufp);
+ if ((n = getline(bufp, buflenp, fp)) < 0)
+ break;
+ if (n > 0 && (*bufp)[n - 1] == '\n')
+ (*bufp)[n - 1] = '\0';
+ } while (1);
if (ferror(fp))
err(1, "%s", fn);
}
@@ -240,52 +251,3 @@ usage(void)
(void)fprintf(stderr, "usage: comm [-123i] file1 file2\n");
exit(1);
}
-
-static size_t wcsicoll_l1_buflen = 0, wcsicoll_l2_buflen = 0;
-static wchar_t *wcsicoll_l1_buf = NULL, *wcsicoll_l2_buf = NULL;
-
-int
-wcsicoll(const wchar_t *s1, const wchar_t *s2)
-{
- wchar_t *p;
- size_t l1, l2;
- size_t new_l1_buflen, new_l2_buflen;
-
- l1 = wcslen(s1) + 1;
- l2 = wcslen(s2) + 1;
- new_l1_buflen = wcsicoll_l1_buflen;
- new_l2_buflen = wcsicoll_l2_buflen;
- while (new_l1_buflen < l1) {
- if (new_l1_buflen == 0)
- new_l1_buflen = INITLINELEN;
- else
- new_l1_buflen *= 2;
- }
- while (new_l2_buflen < l2) {
- if (new_l2_buflen == 0)
- new_l2_buflen = INITLINELEN;
- else
- new_l2_buflen *= 2;
- }
- if (new_l1_buflen > wcsicoll_l1_buflen) {
- wcsicoll_l1_buf = reallocf(wcsicoll_l1_buf, new_l1_buflen * sizeof(*wcsicoll_l1_buf));
- if (wcsicoll_l1_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l1_buflen = new_l1_buflen;
- }
- if (new_l2_buflen > wcsicoll_l2_buflen) {
- wcsicoll_l2_buf = reallocf(wcsicoll_l2_buf, new_l2_buflen * sizeof(*wcsicoll_l2_buf));
- if (wcsicoll_l2_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l2_buflen = new_l2_buflen;
- }
-
- for (p = wcsicoll_l1_buf; *s1; s1++)
- *p++ = towlower(*s1);
- *p = '\0';
- for (p = wcsicoll_l2_buf; *s2; s2++)
- *p++ = towlower(*s2);
- *p = '\0';
-
- return (wcscoll(wcsicoll_l1_buf, wcsicoll_l2_buf));
-}
diff --git a/usr.bin/compress/compress.c b/usr.bin/compress/compress.c
index 584f283..6f674c2 100644
--- a/usr.bin/compress/compress.c
+++ b/usr.bin/compress/compress.c
@@ -368,8 +368,8 @@ setfile(const char *name, struct stat *fs)
fs->st_mode &= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
- TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atim);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtim);
if (utimes(name, tv))
cwarn("utimes: %s", name);
diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile
index bfcbe97..499b173 100644
--- a/usr.bin/cpio/Makefile
+++ b/usr.bin/cpio/Makefile
@@ -19,10 +19,8 @@ DPADD+= ${LIBCRYPTO}
LDADD+= -lcrypto
.endif
-.if ${MK_GNU_CPIO} != "yes"
SYMLINKS=bsdcpio ${BINDIR}/cpio
MLINKS= bsdcpio.1 cpio.1
-.endif
.PHONY: check test
diff --git a/usr.bin/csup/Makefile b/usr.bin/csup/Makefile
index af1815c..7fda5b0 100644
--- a/usr.bin/csup/Makefile
+++ b/usr.bin/csup/Makefile
@@ -1,22 +1,40 @@
# $FreeBSD$
-PREFIX?= /usr/local
-BINDIR?= ${PREFIX}/bin
-MANDIR?= ${PREFIX}/man/man
-
-UNAME!= /usr/bin/uname -s
-
PROG= csup
-SRCS= attrstack.c auth.c config.c detailer.c diff.c fattr.c fixups.c fnmatch.c \
- globtree.c idcache.c keyword.c lister.c main.c misc.c mux.c parse.y \
- pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
- rcsfile.c rcsparse.c lex.rcs.c rsyncfile.c
+SRCS= attrstack.c \
+ auth.c \
+ config.c \
+ detailer.c \
+ diff.c \
+ fattr.c \
+ fixups.c \
+ fnmatch.c \
+ globtree.c \
+ idcache.c \
+ keyword.c \
+ lex.rcs.c \
+ lister.c \
+ main.c \
+ misc.c \
+ mux.c \
+ parse.y \
+ pathcomp.c \
+ proto.c \
+ rcsfile.c \
+ rcsparse.c \
+ rsyncfile.c \
+ status.c \
+ stream.c \
+ threads.c \
+ token.l \
+ updater.c
-CFLAGS+= -I. -I${.CURDIR} -g -pthread -DHAVE_FFLAGS -DNDEBUG
-WARNS?= 1
+CFLAGS+= -I. -I${.CURDIR}
+CFLAGS+= -DHAVE_FFLAGS -DNDEBUG
+WARNS?= 1
-DPADD= ${LIBCRYPTO} ${LIBZ}
-LDADD= -lcrypto -lz
+DPADD= ${LIBCRYPTO} ${LIBZ} ${LIBPTHREAD}
+LDADD= -lcrypto -lz -lpthread
SCRIPTS= cpasswd.sh
MAN= csup.1 cpasswd.1
diff --git a/usr.bin/csup/auth.c b/usr.bin/csup/auth.c
index 4e79bc5..7a84aca 100644
--- a/usr.bin/csup/auth.c
+++ b/usr.bin/csup/auth.c
@@ -147,7 +147,7 @@ auth_domd5auth(struct config *config)
lprintf(-1, "Server failed to authenticate itself to client\n");
return (STATUS_FAILURE);
}
- lprintf(2, "MD5 authentication successfull\n");
+ lprintf(2, "MD5 authentication successful\n");
return (STATUS_SUCCESS);
}
if (strcmp(cmd, "!") == 0) {
diff --git a/usr.bin/csup/cpasswd.1 b/usr.bin/csup/cpasswd.1
index 946783f..1f486d1 100644
--- a/usr.bin/csup/cpasswd.1
+++ b/usr.bin/csup/cpasswd.1
@@ -27,11 +27,11 @@
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $Id: cvpasswd.1,v 1.4 2003/03/04 18:24:42 jdp Exp $
-.\" $FreeBSD $
+.\" $FreeBSD$
.\"
.Dd June 27, 2007
-.Os FreeBSD
.Dt CPASSWD 1
+.Os FreeBSD
.Sh NAME
.Nm cpasswd
.Nd scramble passwords for csup authentication
diff --git a/usr.bin/csup/csup.1 b/usr.bin/csup/csup.1
index 2690863..02e2edb 100644
--- a/usr.bin/csup/csup.1
+++ b/usr.bin/csup/csup.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd February 1, 2006
-.Os FreeBSD
.Dt CSUP 1
+.Os FreeBSD
.Sh NAME
.Nm csup
.Nd network distribution package for CVS repositories
diff --git a/usr.bin/enigma/enigma.1 b/usr.bin/enigma/enigma.1
index 4fc0b20..e5f65ac 100644
--- a/usr.bin/enigma/enigma.1
+++ b/usr.bin/enigma/enigma.1
@@ -7,8 +7,8 @@
.\" $FreeBSD$
.\" "
.Dd May 14, 2004
-.Os
.Dt ENIGMA 1
+.Os
.Sh NAME
.Nm enigma ,
.Nm crypt
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index dee5e04..4890d37 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -35,7 +35,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
-.Dd February 24, 2008
+.Dd March 17, 2010
.Dt FIND 1
.Os
.Sh NAME
@@ -429,12 +429,9 @@ bits match those of
True if the file is contained in a file system of type
.Ar type .
The
-.Xr sysctl 8
+.Xr lsvfs 1
command can be used to find out the types of file systems
-that are available on the system:
-.Pp
-.Dl "sysctl vfs"
-.Pp
+that are available on the system.
In addition, there are two pseudo-types,
.Dq Li local
and
@@ -947,6 +944,7 @@ section below for details.
.Xr chmod 1 ,
.Xr cvs 1 ,
.Xr locate 1 ,
+.Xr lsvfs 1 ,
.Xr whereis 1 ,
.Xr which 1 ,
.Xr xargs 1 ,
diff --git a/usr.bin/getent/getent.c b/usr.bin/getent/getent.c
index e958665..0459cca 100644
--- a/usr.bin/getent/getent.c
+++ b/usr.bin/getent/getent.c
@@ -615,14 +615,13 @@ static int
utmpx(int argc, char *argv[])
{
const struct utmpx *ut;
- int rv = RV_OK, db;
+ const char *file = NULL;
+ int rv = RV_OK, db = 0;
assert(argc > 1);
assert(argv != NULL);
- if (argc == 2) {
- db = UTXDB_ACTIVE;
- } else if (argc == 3) {
+ if (argc == 3 || argc == 4) {
if (strcmp(argv[2], "active") == 0)
db = UTXDB_ACTIVE;
else if (strcmp(argv[2], "lastlogin") == 0)
@@ -631,15 +630,18 @@ utmpx(int argc, char *argv[])
db = UTXDB_LOG;
else
rv = RV_USAGE;
+ if (argc == 4)
+ file = argv[3];
} else {
rv = RV_USAGE;
}
if (rv == RV_USAGE) {
- fprintf(stderr, "Usage: %s utmpx [active | lastlogin | log]\n",
+ fprintf(stderr,
+ "Usage: %s utmpx active | lastlogin | log [filename]\n",
getprogname());
} else if (rv == RV_OK) {
- if (setutxdb(db, NULL) != 0)
+ if (setutxdb(db, file) != 0)
return (RV_NOTFOUND);
while ((ut = getutxent()) != NULL)
utmpxprint(ut);
diff --git a/usr.bin/gzip/gzip.1 b/usr.bin/gzip/gzip.1
index 20d0250..bb1fadd 100644
--- a/usr.bin/gzip/gzip.1
+++ b/usr.bin/gzip/gzip.1
@@ -25,7 +25,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
-.Dd June 24, 2009
+.Dd April 7, 2010
.Dt GZIP 1
.Os
.Sh NAME
@@ -205,14 +205,17 @@ This implementation of
.Nm
was ported based on the
.Nx
-.Nm
-20090412, and first appeared in
+.Nm ,
+and first appeared in
.Fx 7.0 .
.Sh AUTHORS
+.An -nosplit
This implementation of
.Nm
was written by
-.An Matthew R. Green Aq mrg@eterna.com.au .
+.An Matthew R. Green Aq mrg@eterna.com.au
+with unpack support written by
+.An Xin LI Aq delphij@FreeBSD.org .
.Sh BUGS
According to RFC 1952, the recorded file size is stored in a 32-bit
integer and therefore it can not represent files that is bigger than
diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c
index e9371d2..9503762 100644
--- a/usr.bin/gzip/gzip.c
+++ b/usr.bin/gzip/gzip.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gzip.c,v 1.94 2009/04/12 10:31:14 lukem Exp $ */
+/* $NetBSD: gzip.c,v 1.97 2009/10/11 09:17:21 mrg Exp $ */
/*-
* Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
@@ -43,7 +43,6 @@ __RCSID("$FreeBSD$");
*
* TODO:
* - use mmap where possible
- * - handle some signals better (remove outfile?)
* - make bzip2/compress -v/-t/-l support work as well as possible
*/
@@ -149,10 +148,9 @@ static suffixes_t suffixes[] = {
#undef SUFFIX
};
#define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0])
-
#define SUFFIX_MAXLEN 30
-static const char gzip_version[] = "FreeBSD gzip 20090621";
+static const char gzip_version[] = "FreeBSD gzip 20100407";
#ifndef SMALL
static const char gzip_copyright[] = \
@@ -195,6 +193,7 @@ static int qflag; /* quiet mode */
static int rflag; /* recursive mode */
static int tflag; /* test */
static int vflag; /* verbose mode */
+static const char *remove_file = NULL; /* file to be removed upon SIGINT */
#else
#define qflag 0
#define tflag 0
@@ -206,7 +205,7 @@ static char *infile; /* name of file coming in */
static void maybe_err(const char *fmt, ...) __dead2
__attribute__((__format__(__printf__, 1, 2)));
-#ifndef NO_BZIP2_SUPPORT
+#if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT)
static void maybe_errx(const char *fmt, ...) __dead2
__attribute__((__format__(__printf__, 1, 2)));
#endif
@@ -232,6 +231,7 @@ static void usage(void);
static void display_version(void);
#ifndef SMALL
static void display_license(void);
+static void sigint_handler(int);
#endif
static const suffixes_t *check_suffix(char *, int);
static ssize_t read_retry(int, void *, size_t);
@@ -301,11 +301,10 @@ main(int argc, char **argv)
#endif
int ch;
- /* XXX set up signals */
-
#ifndef SMALL
if ((gzip = getenv("GZIP")) != NULL)
prepend_gzip(gzip, &argc, &argv);
+ signal(SIGINT, sigint_handler);
#endif
/*
@@ -461,7 +460,7 @@ maybe_err(const char *fmt, ...)
exit(2);
}
-#ifndef NO_BZIP2_SUPPORT
+#if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT)
/* ... without an errno. */
void
maybe_errx(const char *fmt, ...)
@@ -1088,8 +1087,8 @@ copymodes(int fd, const struct stat *sbp, const char *file)
if (fchmod(fd, sb.st_mode) < 0)
maybe_warn("couldn't fchmod: %s", file);
- TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atimespec);
- TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atim);
+ TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtim);
if (futimes(fd, times) < 0)
maybe_warn("couldn't utimes: %s", file);
@@ -1172,6 +1171,15 @@ unlink_input(const char *file, const struct stat *sb)
return;
unlink(file);
}
+
+static void
+sigint_handler(int signo __unused)
+{
+
+ if (remove_file != NULL)
+ unlink(remove_file);
+ exit(2);
+}
#endif
static const suffixes_t *
@@ -1258,6 +1266,9 @@ file_compress(char *file, char *outfile, size_t outsize)
fclose(stdin);
return -1;
}
+#ifndef SMALL
+ remove_file = outfile;
+#endif
} else
out = STDOUT_FILENO;
@@ -1289,6 +1300,7 @@ file_compress(char *file, char *outfile, size_t outsize)
}
copymodes(out, &isb, outfile);
+ remove_file = NULL;
#endif
if (close(out) == -1)
maybe_warn("couldn't close output");
@@ -1319,6 +1331,7 @@ file_uncompress(char *file, char *outfile, size_t outsize)
enum filetype method;
int fd, ofd, zfd = -1;
#ifndef SMALL
+ ssize_t rv;
time_t timestamp = 0;
unsigned char name[PATH_MAX + 1];
#endif
@@ -1364,7 +1377,6 @@ file_uncompress(char *file, char *outfile, size_t outsize)
#ifndef SMALL
if (method == FT_GZIP && Nflag) {
unsigned char ts[4]; /* timestamp */
- ssize_t rv;
rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP);
if (rv >= 0 && rv < (ssize_t)(sizeof ts))
@@ -1425,6 +1437,9 @@ file_uncompress(char *file, char *outfile, size_t outsize)
maybe_warn("can't open %s", outfile);
goto lose;
}
+#ifndef SMALL
+ remove_file = outfile;
+#endif
} else
zfd = STDOUT_FILENO;
@@ -1556,11 +1571,12 @@ file_uncompress(char *file, char *outfile, size_t outsize)
unlink(outfile);
return -1;
}
- unlink_input(file, &isb);
#ifndef SMALL
copymodes(ofd, &isb, outfile);
+ remove_file = NULL;
#endif
close(ofd);
+ unlink_input(file, &isb);
return size;
unexpected_EOF:
@@ -2054,7 +2070,7 @@ static void
display_license(void)
{
- fprintf(stderr, "%s (based on NetBSD gzip 20060927)\n", gzip_version);
+ fprintf(stderr, "%s (based on NetBSD gzip 20091011)\n", gzip_version);
fprintf(stderr, "%s\n", gzip_copyright);
exit(0);
}
@@ -2100,4 +2116,3 @@ read_retry(int fd, void *buf, size_t sz)
return sz - left;
}
-
diff --git a/usr.bin/gzip/unbzip2.c b/usr.bin/gzip/unbzip2.c
index c744e56..a5cd1be 100644
--- a/usr.bin/gzip/unbzip2.c
+++ b/usr.bin/gzip/unbzip2.c
@@ -1,4 +1,4 @@
-/* $NetBSD: unbzip2.c,v 1.12 2009/10/11 05:17:20 mrg Exp $ */
+/* $NetBSD: unbzip2.c,v 1.13 2009/12/05 03:23:37 mrg Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
diff --git a/usr.bin/hexdump/od.1 b/usr.bin/hexdump/od.1
index dd67ff5..b5b5494 100644
--- a/usr.bin/hexdump/od.1
+++ b/usr.bin/hexdump/od.1
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd February 18, 2010
-.Os
.Dt OD 1
+.Os
.Sh NAME
.Nm od
.Nd octal, decimal, hex, ASCII dump
diff --git a/usr.bin/indent/args.c b/usr.bin/indent/args.c
index f139de5..cab0f7d 100644
--- a/usr.bin/indent/args.c
+++ b/usr.bin/indent/args.c
@@ -157,6 +157,7 @@ struct pro {
{"sc", PRO_BOOL, true, ON, &star_comment_cont},
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines},
{"st", PRO_SPECIAL, 0, STDIN, 0},
+ {"ta", PRO_BOOL, false, ON, &auto_typedefs},
{"troff", PRO_BOOL, false, ON, &troff},
{"ut", PRO_BOOL, true, ON, &use_tabs},
{"v", PRO_BOOL, false, ON, &verbose},
diff --git a/usr.bin/indent/indent.1 b/usr.bin/indent/indent.1
index f04e13d..1a7c789 100644
--- a/usr.bin/indent/indent.1
+++ b/usr.bin/indent/indent.1
@@ -80,6 +80,7 @@
.Op Fl sob | Fl nsob
.Ek
.Op Fl \&st
+.Op Fl \&ta
.Op Fl troff
.Op Fl ut | Fl nut
.Op Fl v | Fl \&nv
@@ -377,6 +378,9 @@ Default:
Causes
.Nm
to take its input from stdin and put its output to stdout.
+.It Fl ta
+Automatically add all identifiers ending in "_t" to the list
+of type keywords.
.It Fl T Ns Ar typename
Adds
.Ar typename
diff --git a/usr.bin/indent/indent.c b/usr.bin/indent/indent.c
index 9917960..7820ebe 100644
--- a/usr.bin/indent/indent.c
+++ b/usr.bin/indent/indent.c
@@ -675,7 +675,7 @@ check_type:
ps.want_blank = true;
break;
}
- if (ps.in_decl) {
+ if (ps.in_or_st) {
*e_code++ = ':';
ps.want_blank = false;
break;
diff --git a/usr.bin/indent/indent_globs.h b/usr.bin/indent/indent_globs.h
index 11ea239..087f41c 100644
--- a/usr.bin/indent/indent_globs.h
+++ b/usr.bin/indent/indent_globs.h
@@ -204,6 +204,8 @@ int function_brace_split; /* split function declaration and
* brace onto separate lines */
int use_tabs; /* set true to use tabs for spacing,
* false uses all spaces */
+int auto_typedefs; /* set true to recognize identifiers
+ * ending in "_t" like typedefs */
/* -troff font state information */
diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c
index 60fc1ae..b3604c6 100644
--- a/usr.bin/indent/lexi.c
+++ b/usr.bin/indent/lexi.c
@@ -249,6 +249,18 @@ lexi(void)
last_code = ident; /* Remember that this is the code we will
* return */
+ if (auto_typedefs) {
+ const char *q = s_token;
+ size_t q_len = strlen(q);
+ /* Check if we have an "_t" in the end */
+ if (q_len > 2 &&
+ (strcmp(q + q_len - 2, "_t") == 0)) {
+ ps.its_a_keyword = true;
+ ps.last_u_d = true;
+ goto found_auto_typedef;
+ }
+ }
+
/*
* This loop will check if the token is a keyword.
*/
@@ -285,6 +297,7 @@ lexi(void)
/* FALLTHROUGH */
case 4: /* one of the declaration keywords */
+ found_auto_typedef:
if (ps.p_l_follow) {
ps.cast_mask |= (1 << ps.p_l_follow) & ~ps.sizeof_mask;
break; /* inside parens: cast, param list or sizeof */
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 9c86fff..ec32ee7 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -1270,50 +1270,50 @@ ktrstat(struct stat *statp)
printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
printf("atime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_atimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_atim.tv_sec);
else {
- tm = localtime(&statp->st_atimespec.tv_sec);
+ tm = localtime(&statp->st_atim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_atimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_atimespec.tv_nsec);
+ if (statp->st_atim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_atim.tv_nsec);
else
printf(", ");
printf("stime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_mtimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
else {
- tm = localtime(&statp->st_mtimespec.tv_sec);
+ tm = localtime(&statp->st_mtim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_mtimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_mtimespec.tv_nsec);
+ if (statp->st_mtim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_mtim.tv_nsec);
else
printf(", ");
printf("ctime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_ctimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
else {
- tm = localtime(&statp->st_ctimespec.tv_sec);
+ tm = localtime(&statp->st_ctim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_ctimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_ctimespec.tv_nsec);
+ if (statp->st_ctim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_ctim.tv_nsec);
else
printf(", ");
printf("birthtime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_birthtimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
else {
- tm = localtime(&statp->st_birthtimespec.tv_sec);
+ tm = localtime(&statp->st_birthtim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_birthtimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_birthtimespec.tv_nsec);
+ if (statp->st_birthtim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_birthtim.tv_nsec);
else
printf(", ");
printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
diff --git a/usr.bin/killall/killall.1 b/usr.bin/killall/killall.1
index 19362bc..58ffa06 100644
--- a/usr.bin/killall/killall.1
+++ b/usr.bin/killall/killall.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 25, 2009
-.Os
.Dt KILLALL 1
+.Os
.Sh NAME
.Nm killall
.Nd kill processes by name
diff --git a/usr.bin/locale/Makefile b/usr.bin/locale/Makefile
index 5b8932c..96c18bc 100644
--- a/usr.bin/locale/Makefile
+++ b/usr.bin/locale/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
-PROG = locale
-CFLAGS += -I${.CURDIR}/../../lib/libc/locale
-WARNS ?= 3
+PROG= locale
+WARNS?= 3
+CFLAGS+= -I${.CURDIR}/../../lib/libc/locale
.include <bsd.prog.mk>
diff --git a/usr.bin/lockf/lockf.1 b/usr.bin/lockf/lockf.1
index 6e2e06e..255a828 100644
--- a/usr.bin/lockf/lockf.1
+++ b/usr.bin/lockf/lockf.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd July 7, 1998
-.Os
.Dt LOCKF 1
+.Os
.Sh NAME
.Nm lockf
.Nd execute a command while holding a file lock
diff --git a/usr.bin/mail/util.c b/usr.bin/mail/util.c
index e764aac..df2d840 100644
--- a/usr.bin/mail/util.c
+++ b/usr.bin/mail/util.c
@@ -349,7 +349,7 @@ alter(name)
return;
(void)gettimeofday(&tv[0], (struct timezone *)NULL);
tv[0].tv_sec++;
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
(void)utimes(name, tv);
}
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 91638d4..3b091fd 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -983,8 +983,6 @@ main(int argc, char **argv)
if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
if (!strcmp(machine_arch, "i386"))
machine_cpu = "i386";
- else if (!strcmp(machine_arch, "alpha"))
- machine_cpu = "ev4";
else
machine_cpu = "unknown";
}
diff --git a/usr.bin/minigzip/Makefile b/usr.bin/minigzip/Makefile
index 9a0ab95..21b0924 100644
--- a/usr.bin/minigzip/Makefile
+++ b/usr.bin/minigzip/Makefile
@@ -1,10 +1,13 @@
# $FreeBSD$
+SRCDIR= ${.CURDIR}/../../lib/libz
+.PATH: ${SRCDIR}
+
PROG= minigzip
-LDADD= -lz
-DPADD= ${LIBZ}
-.PATH: ${.CURDIR}/../../lib/libz
WARNS?= 5
+CFLAGS+=-DUSE_MMAP
+DPADD= ${LIBZ}
+LDADD= -lz
.include <bsd.prog.mk>
diff --git a/usr.bin/ncal/Makefile b/usr.bin/ncal/Makefile
index 343e8cd..7d42921 100644
--- a/usr.bin/ncal/Makefile
+++ b/usr.bin/ncal/Makefile
@@ -4,7 +4,6 @@ PROG= ncal
DPADD= ${LIBCALENDAR} ${LIBTERMCAP}
LDADD= -lcalendar -ltermcap
-WARNS?= 1
LINKS= ${BINDIR}/ncal ${BINDIR}/cal
MLINKS= ncal.1 cal.1
diff --git a/usr.bin/ncal/ncal.1 b/usr.bin/ncal/ncal.1
index 1c93a84..8429906 100644
--- a/usr.bin/ncal/ncal.1
+++ b/usr.bin/ncal/ncal.1
@@ -33,25 +33,37 @@
.Nd displays a calendar and the date of Easter
.Sh SYNOPSIS
.Nm
-.Op Fl hjy
+.Op Fl 3hjy
+.Op Fl A Ar number
+.Op Fl B Ar number
.Oo
.Op Ar month
.Ar year
.Oc
.Nm
-.Op Fl hj
+.Op Fl 3hj
+.Op Fl A Ar number
+.Op Fl B Ar number
.Fl m Ar month
.Op Ar year
.Nm ncal
-.Op Fl hjJpwy
+.Op Fl 3hjJpwy
+.Op Fl A Ar number
+.Op Fl B Ar number
.Op Fl s Ar country_code
.Oo
.Op Ar month
.Ar year
.Oc
.Nm ncal
-.Op Fl hJeo
+.Op Fl 3hJeo
+.Op Fl A Ar number
+.Op Fl B Ar number
.Op Ar year
+.Nm ncal
+.Op Fl CN
+.Op Fl H Ar yyyy-mm-dd
+.Op Fl d Ar yyyy-mm
.Sh DESCRIPTION
The
.Nm
@@ -109,6 +121,32 @@ Britain and her colonies switched to the Gregorian Calendar.
Print the number of the week below each week column.
.It Fl y
Display a calendar for the specified year.
+.It Fl 3
+Display the previous, current and next month surrounding today.
+.It Fl A Ar number
+Display the
+.Ar number
+of months after the current month.
+.It Fl B Ar number
+Display the
+.Ar number
+of months before the current month.
+.It Fl C
+Switch to
+.Nm cal
+mode.
+.It Fl N
+Switch to
+.Nm ncal
+mode.
+.It Fl d Ar yyyy-mm
+Use
+.Ar yyyy-mm
+as the current date (for debugging of date selection).
+.It Fl H Ar yyyy-mm-dd
+Use
+.Ar yyyy-mm-dd
+as the current date (for debugging of highlighting).
.El
.Pp
A single parameter specifies the year (1\(en9999) to be displayed;
@@ -116,12 +154,21 @@ note the year must be fully specified:
.Dq Li cal 89
will
.Em not
-display a calendar for 1989.
-Two parameters denote the month and year; the month is either a number between
-1 and 12, or a full or abbreviated name as specified by the current locale.
-Month and year default to those of the current system clock and time zone (so
+display a calendar for 1989. Two parameters denote the month and
+year; the month is either a number between 1 and 12, or a full or
+abbreviated name as specified by the current locale. Month and
+year default to those of the current system clock and time zone (so
.Dq Li cal -m 8
-will display a calendar for the month of August in the current year).
+will display a calendar for the month of August in the current
+year).
+.Pp
+Not all options can be used together. For example
+.Dq Li -3 -A 2 -B 3 -y -m 7
+would mean:
+show me the three months around the seventh month, three before
+that, two after that and the whole year.
+.Nm ncal
+will warn about these combinations.
.Pp
A year starts on January 1.
.Sh SEE ALSO
@@ -142,5 +189,8 @@ The
command and manual were written by
.An Wolfgang Helbig Aq helbig@FreeBSD.org .
.Sh BUGS
-The assignment of Julian\(enGregorian switching dates to
-country codes is historically naive for many countries.
+The assignment of Julian\(enGregorian switching dates to country
+codes is historically naive for many countries.
+.Pp
+Not all options are compatible and using them in different orders
+will give varying results.
diff --git a/usr.bin/ncal/ncal.c b/usr.bin/ncal/ncal.c
index a65a2fc..5ab9a21 100644
--- a/usr.bin/ncal/ncal.c
+++ b/usr.bin/ncal/ncal.c
@@ -45,12 +45,12 @@ static const char rcsid[] =
#include <term.h>
#undef lines /* term.h defines this */
-/* Width of one month with backward compatibility */
+/* Width of one month with backward compatibility and in regular mode*/
#define MONTH_WIDTH_B_J 27
#define MONTH_WIDTH_B 20
-#define MONTH_WIDTH_J 24
-#define MONTH_WIDTH 18
+#define MONTH_WIDTH_R_J 24
+#define MONTH_WIDTH_R 18
#define MAX_WIDTH 64
@@ -60,6 +60,7 @@ struct monthlines {
wchar_t name[MAX_WIDTH + 1];
char lines[7][MAX_WIDTH + 1];
char weeks[MAX_WIDTH + 1];
+ unsigned int extralen[7];
};
struct weekdays {
@@ -158,31 +159,29 @@ char jdaystr[] = " 1 2 3 4 5 6 7 8 9"
" 350 351 352 353 354 355 356 357 358 359"
" 360 361 362 363 364 365 366";
+int flag_nohighlight; /* user doesn't want a highlighted today */
int flag_weeks; /* user wants number of week */
int nswitch; /* user defined switch date */
int nswitchb; /* switch date for backward compatibility */
-const char *term_so, *term_se;
-int today;
+int highlightdate;
-char *center(char *s, char *t, int w);
+char *center(char *s, char *t, int w);
wchar_t *wcenter(wchar_t *s, wchar_t *t, int w);
-void mkmonth(int year, int month, int jd_flag, struct monthlines * monthl);
-void mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
-void mkweekdays(struct weekdays * wds);
-int parsemonth(const char *s, int *m, int *y);
-void printcc(void);
-void printeaster(int year, int julian, int orthodox);
-void printmonth(int year, int month, int jd_flag);
-void printmonthb(int year, int month, int jd_flag);
-void printyear(int year, int jd_flag);
-void printyearb(int year, int jd_flag);
int firstday(int y, int m);
-date *sdate(int ndays, struct date * d);
-date *sdateb(int ndays, struct date * d);
-int sndays(struct date * d);
-int sndaysb(struct date * d);
-static void usage(void);
-int weekdayb(int nd);
+void highlight(char *dst, char *src, int len, int *extraletters);
+void mkmonthr(int year, int month, int jd_flag, struct monthlines * monthl);
+void mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
+void mkweekdays(struct weekdays * wds);
+void monthranger(int year, int m, int jd_flag, int before, int after);
+void monthrangeb(int year, int m, int jd_flag, int before, int after);
+int parsemonth(const char *s, int *m, int *y);
+void printcc(void);
+void printeaster(int year, int julian, int orthodox);
+date *sdater(int ndays, struct date * d);
+date *sdateb(int ndays, struct date * d);
+int sndaysr(struct date * d);
+int sndaysb(struct date * d);
+static void usage(void);
int
main(int argc, char *argv[])
@@ -190,39 +189,31 @@ main(int argc, char *argv[])
struct djswitch *p, *q; /* to search user defined switch date */
date never = {10000, 1, 1}; /* outside valid range of dates */
date ukswitch = {1752, 9, 2};/* switch date for Great Britain */
+ date dt;
int ch; /* holds the option character */
int m = 0; /* month */
int y = 0; /* year */
int flag_backward = 0; /* user called cal--backward compat. */
- int flag_hole_year = 0; /* user wants the whole year */
+ int flag_wholeyear = 0; /* user wants the whole year */
int flag_julian_cal = 0; /* user wants Julian Calendar */
- int flag_julian_day = 0; /* user wants the Julian day
- * numbers */
- int flag_orthodox = 0; /* use wants Orthodox easter */
- int flag_easter = 0; /* use wants easter date */
+ int flag_julian_day = 0; /* user wants the Julian day numbers */
+ int flag_orthodox = 0; /* user wants Orthodox easter */
+ int flag_easter = 0; /* user wants easter date */
+ int flag_3months = 0; /* user wants 3 month display (-3) */
+ int flag_after = 0; /* user wants to see months after */
+ int flag_before = 0; /* user wants to see months before */
+ int flag_specifiedmonth = 0;/* user wants to see this month (-m) */
+ int flag_givenmonth = 0; /* user has specified month [n] */
+ int flag_givenyear = 0; /* user has specified year [n] */
char *cp; /* character pointer */
+ char *flag_today = NULL; /* debug: use date as being today */
char *flag_month = NULL; /* requested month as string */
+ char *flag_highlightdate = NULL; /* debug: date to highlight */
+ int before, after;
const char *locale; /* locale to get country code */
- char tbuf[1024], cbuf[512], *b;
- time_t t;
- struct tm *tm1;
-
- term_se = term_so = NULL;
- today = 0;
- if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
- date dt; /* handy date */
-
- b = cbuf;
- term_so = tgetstr("so", &b);
- term_se = tgetstr("se", &b);
- t = time(NULL);
- tm1 = localtime(&t);
- dt.y = tm1->tm_year + 1900;
- dt.m = tm1->tm_mon + 1;
- dt.d = tm1->tm_mday;
- today = sndaysb(&dt);
- }
+ flag_nohighlight = 0;
+ flag_weeks = 0;
/*
* Use locale to determine the country code,
@@ -263,16 +254,49 @@ main(int argc, char *argv[])
if (flag_backward)
nswitchb = ndaysj(&ukswitch);
- while ((ch = getopt(argc, argv, "Jehjm:ops:wy")) != -1)
+ before = after = -1;
+
+ while ((ch = getopt(argc, argv, "3A:B:Cd:eH:hjJm:Nops:wy")) != -1)
switch (ch) {
+ case '3':
+ flag_3months = 1;
+ break;
+ case 'A':
+ if (flag_after > 0)
+ errx(EX_USAGE, "Double -A specified");
+ flag_after = strtol(optarg, NULL, 10);
+ if (flag_after <= 0)
+ errx(EX_USAGE,
+ "Argument to -A must be positive");
+ break;
+ case 'B':
+ if (flag_before > 0)
+ errx(EX_USAGE, "Double -A specified");
+ flag_before = strtol(optarg, NULL, 10);
+ if (flag_before <= 0)
+ errx(EX_USAGE,
+ "Argument to -B must be positive");
+ break;
case 'J':
if (flag_backward)
usage();
nswitch = ndaysj(&never);
flag_julian_cal = 1;
break;
+ case 'C':
+ flag_backward = 1;
+ break;
+ case 'N':
+ flag_backward = 0;
+ break;
+ case 'd':
+ flag_today = optarg;
+ break;
+ case 'H':
+ flag_highlightdate = optarg;
+ break;
case 'h':
- term_so = term_se = NULL;
+ flag_nohighlight = 1;
break;
case 'e':
if (flag_backward)
@@ -283,7 +307,10 @@ main(int argc, char *argv[])
flag_julian_day = 1;
break;
case 'm':
+ if (flag_specifiedmonth)
+ errx(EX_USAGE, "Double -m specified");
flag_month = optarg;
+ flag_specifiedmonth = 1;
break;
case 'o':
if (flag_backward)
@@ -316,7 +343,7 @@ main(int argc, char *argv[])
flag_weeks = 1;
break;
case 'y':
- flag_hole_year = 1;
+ flag_wholeyear = 1;
break;
default:
usage();
@@ -330,14 +357,21 @@ main(int argc, char *argv[])
if (flag_easter)
usage();
flag_month = *argv++;
+ flag_givenmonth = 1;
+ m = strtol(flag_month, NULL, 10);
/* FALLTHROUGH */
case 1:
- y = atoi(*argv++);
+ y = atoi(*argv);
if (y < 1 || y > 9999)
- errx(EX_USAGE, "year %d not in range 1..9999", y);
+ errx(EX_USAGE, "year `%s' not in range 1..9999", *argv);
+ argv++;
+ flag_givenyear = 1;
break;
case 0:
- {
+ if (flag_today != NULL) {
+ y = strtol(flag_today, NULL, 10);
+ m = strtol(flag_today + 5, NULL, 10);
+ } else {
time_t t;
struct tm *tm;
@@ -359,21 +393,108 @@ main(int argc, char *argv[])
}
}
+ /*
+ * What is not supported:
+ * -3 with -A or -B
+ * -3 displays 3 months, -A and -B change that behaviour.
+ * -3 with -y
+ * -3 displays 3 months, -y says display a whole year.
+ * -3 with a given year but no given month or without -m
+ * -3 displays 3 months, no month specified doesn't make clear
+ * which three months.
+ * -m with a given month
+ * conflicting arguments, both specify the same field.
+ * -y with -m
+ * -y displays the whole year, -m displays a single month.
+ * -y with a given month
+ * -y displays the whole year, the given month displays a single
+ * month.
+ * -y with -A or -B
+ * -y displays the whole year, -A and -B display extra months.
+ */
+
+ /* -3 together with -A or -B. */
+ if (flag_3months && (flag_after || flag_before))
+ errx(EX_USAGE, "-3 together with -A and -B is not supported.");
+ /* -3 together with -y. */
+ if (flag_3months && flag_wholeyear)
+ errx(EX_USAGE, "-3 together with -y is not supported.");
+ /* -3 together with givenyear but no givenmonth. */
+ if (flag_3months && flag_givenyear &&
+ !(flag_givenmonth || flag_specifiedmonth))
+ errx(EX_USAGE,
+ "-3 together with a given year but no given month is "
+ "not supported.");
+ /* -m together with xx xxxx. */
+ if (flag_specifiedmonth && flag_givenmonth)
+ errx(EX_USAGE,
+ "-m together with a given month is not supported.");
+ /* -y together with -m. */
+ if (flag_wholeyear && flag_specifiedmonth)
+ errx(EX_USAGE, "-y together with -m is not supported.");
+ /* -y together with xx xxxx. */
+ if (flag_wholeyear && flag_givenmonth)
+ errx(EX_USAGE, "-y together a given month is not supported.");
+ /* -y together with -A or -B. */
+ if (flag_wholeyear && (flag_before > 0 || flag_after > 0))
+ errx(EX_USAGE, "-y together a -A or -B is not supported.");
+ /* The rest should be fine. */
+
+ /* Select the period to display, in order of increasing priority .*/
+ if (flag_wholeyear ||
+ (flag_givenyear && !(flag_givenmonth || flag_specifiedmonth))) {
+ m = 1;
+ before = 0;
+ after = 11;
+ }
+ if (flag_givenyear && flag_givenmonth) {
+ before = 0;
+ after = 0;
+ }
+ if (flag_specifiedmonth) {
+ before = 0;
+ after = 0;
+ }
+ if (flag_before) {
+ before = flag_before;
+ }
+ if (flag_after) {
+ after = flag_after;
+ }
+ if (flag_3months) {
+ before = 1;
+ after = 1;
+ }
+ if (after == -1)
+ after = 0;
+ if (before == -1)
+ before = 0;
+
+ /* Highlight a specified day or today .*/
+ if (flag_highlightdate != NULL) {
+ dt.y = strtol(flag_highlightdate, NULL, 10);
+ dt.m = strtol(flag_highlightdate + 5, NULL, 10);
+ dt.d = strtol(flag_highlightdate + 8, NULL, 10);
+ } else {
+ time_t t;
+ struct tm *tm1;
+
+ t = time(NULL);
+ tm1 = localtime(&t);
+ dt.y = tm1->tm_year + 1900;
+ dt.m = tm1->tm_mon + 1;
+ dt.d = tm1->tm_mday;
+ }
+ highlightdate = sndaysb(&dt);
+
+ /* And now we finally start to calculate and output calendars. */
if (flag_easter)
printeaster(y, flag_julian_cal, flag_orthodox);
- else if (argc == 1 || flag_hole_year) {
- /* disable the highlight for now */
- today = 0;
- if (flag_backward)
- printyearb(y, flag_julian_day);
- else
- printyear(y, flag_julian_day);
- } else
+ else
if (flag_backward)
- printmonthb(y, m, flag_julian_day);
+ monthrangeb(y, m, flag_julian_day, before, after);
else
- printmonth(y, m, flag_julian_day);
-
+ monthranger(y, m, flag_julian_day, before, after);
return (0);
}
@@ -382,14 +503,17 @@ usage(void)
{
fputs(
- "usage: cal [-hjy] [[month] year]\n"
- " cal [-hj] [-m month] [year]\n"
- " ncal [-hJjpwy] [-s country_code] [[month] year]\n"
- " ncal [-hJeo] [year]\n", stderr);
+"Usage: cal [general options] [-hjy] [[month] year]\n"
+" cal [general options] [-hj] [-m month] [year]\n"
+" ncal [general options] [-hJjpwy] [-s country_code] [[month] year]\n"
+" ncal [general options] [-hJeo] [year]\n"
+"General options: [-NC3] [-A months] [-B months]\n"
+"For debug the highlighting: [-H yyyy-mm-dd] [-d yyyy-mm]\n",
+ stderr);
exit(EX_USAGE);
}
-/* print the assumed switches for all countries */
+/* Print the assumed switches for all countries. */
void
printcc(void)
{
@@ -410,13 +534,13 @@ printcc(void)
printf(FSTR"\n", FSTRARG(p));
}
-/* print the date of easter sunday */
+/* Print the date of easter sunday. */
void
printeaster(int y, int julian, int orthodox)
{
date dt;
struct tm tm;
- char buf[80];
+ char buf[MAX_WIDTH];
static int d_first = -1;
if (d_first < 0)
@@ -441,183 +565,201 @@ printeaster(int y, int julian, int orthodox)
printf("%s\n", buf);
}
-void
-printmonth(int y, int m, int jd_flag)
-{
- struct monthlines month;
- struct weekdays wds;
- int i, len;
-
- mkmonth(y, m - 1, jd_flag, &month);
- mkweekdays(&wds);
- printf(" %ls %d\n", month.name, y);
- for (i = 0; i != 7; i++) {
- len = wcslen(wds.names[i]);
- if (wcswidth(wds.names[i], len) == len)
- wprintf(L"%.2ls%s\n", wds.names[i], month.lines[i]);
- else
- wprintf(L"%.1ls%s\n", wds.names[i], month.lines[i]);
- }
- if (flag_weeks)
- printf(" %s\n", month.weeks);
-}
-
-void
-printmonthb(int y, int m, int jd_flag)
-{
- struct monthlines month;
- struct weekdays wds;
- wchar_t s[MAX_WIDTH], t[MAX_WIDTH];
- int i;
- int mw;
-
- mkmonthb(y, m - 1, jd_flag, &month);
- mkweekdays(&wds);
-
- mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
-
- swprintf(s, MAX_WIDTH, L"%ls %d", month.name, y);
- wprintf(L"%ls\n", wcenter(t, s, mw));
-
- if (jd_flag)
- wprintf(L" %ls %ls %ls %ls %ls %ls %.2ls\n",
- wds.names[6], wds.names[0],
- wds.names[1], wds.names[2], wds.names[3],
- wds.names[4], wds.names[5]);
- else
- wprintf(L"%ls%ls%ls%ls%ls%ls%.2ls\n", wds.names[6],
- wds.names[0], wds.names[1], wds.names[2], wds.names[3],
- wds.names[4], wds.names[5]);
-
- for (i = 0; i != 6; i++)
- printf("%s\n", month.lines[i]+1);
-}
+#define MW(mw, me) ((mw) + me)
+#define DECREASEMONTH(m, y) \
+ if (--m == 0) { \
+ m = 12; \
+ y--; \
+ }
+#define INCREASEMONTH(m, y) \
+ if (++(m) == 13) { \
+ (m) = 1; \
+ (y)++; \
+ }
+#define M2Y(m) ((m) / 12)
+#define M2M(m) (1 + (m) % 12)
+/* Print all months for the period in the range [ before .. y-m .. after ]. */
void
-printyear(int y, int jd_flag)
+monthrangeb(int y, int m, int jd_flag, int before, int after)
{
struct monthlines year[12];
struct weekdays wds;
- char s[80], t[80];
+ char s[MAX_WIDTH], t[MAX_WIDTH];
+ wchar_t ws[MAX_WIDTH], ws1[MAX_WIDTH];
+ const char *wdss;
int i, j;
int mpl;
int mw;
+ int m1, m2;
+ int printyearheader;
+ int prevyear = -1;
+
+ mpl = jd_flag ? 2 : 3;
+ mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
+ wdss = (mpl == 2) ? " " : "";
+
+ while (before != 0) {
+ DECREASEMONTH(m, y);
+ before--;
+ after++;
+ }
+ m1 = y * 12 + m - 1;
+ m2 = m1 + after;
- for (i = 0; i != 12; i++)
- mkmonth(y, i, jd_flag, year + i);
mkweekdays(&wds);
- mpl = jd_flag ? 3 : 4;
- mw = jd_flag ? MONTH_WIDTH_J : MONTH_WIDTH;
- sprintf(s, "%d", y);
- printf("%s\n", center(t, s, mpl * mw));
+ /*
+ * The year header is printed when there are more than 'mpl' months
+ * and if the first month is a multitude of 'mpl'.
+ * If not, it will print the year behind every month.
+ */
+ printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0;
+
+ m = m1;
+ while (m <= m2) {
+ int count = 0;
+ for (i = 0; i != mpl && m + i <= m2; i++) {
+ mkmonthb(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i);
+ count++;
+ }
- for (j = 0; j != 12; j += mpl) {
- wprintf(L" %-*ls%-*ls",
- mw, year[j].name,
- mw, year[j + 1].name);
- if (mpl == 3)
- printf("%ls\n", year[j + 2].name);
- else
- wprintf(L"%-*ls%ls\n",
- mw, year[j + 2].name,
- year[j + 3].name);
- for (i = 0; i != 7; i++) {
- wprintf(L"%.2ls%-*s%-*s",
- wds.names[i],
- mw, year[j].lines[i],
- mw, year[j + 1].lines[i]);
- if (mpl == 3)
- printf("%s\n", year[j + 2].lines[i]);
- else
- printf("%-*s%s\n",
- mw, year[j + 2].lines[i],
- year[j + 3].lines[i]);
+ /* Empty line between two rows of months */
+ if (m != m1)
+ printf("\n");
+
+ /* Year at the top. */
+ if (printyearheader && M2Y(m) != prevyear) {
+ sprintf(s, "%d", M2Y(m));
+ printf("%s\n", center(t, s, mpl * mw));
+ prevyear = M2Y(m);
}
- if (flag_weeks) {
- if (mpl == 3)
- printf(" %-*s%-*s%-s\n",
- mw, year[j].weeks,
- mw, year[j + 1].weeks,
- year[j + 2].weeks);
- else
- printf(" %-*s%-*s%-*s%-s\n",
- mw, year[j].weeks,
- mw, year[j + 1].weeks,
- mw, year[j + 2].weeks,
- year[j + 3].weeks);
+
+ /* Month names. */
+ for (i = 0; i < count; i++)
+ if (printyearheader)
+ wprintf(L"%-*ls ",
+ mw, wcenter(ws, year[i].name, mw));
+ else {
+ swprintf(ws, sizeof(ws), L"%-ls %d",
+ year[i].name, M2Y(m + i));
+ wprintf(L"%-*ls ", mw, wcenter(ws1, ws, mw));
+ }
+ printf("\n");
+
+ /* Day of the week names. */
+ for (i = 0; i < count; i++) {
+ wprintf(L"%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls ",
+ wdss, wds.names[6], wdss, wds.names[0],
+ wdss, wds.names[1], wdss, wds.names[2],
+ wdss, wds.names[3], wdss, wds.names[4],
+ wdss, wds.names[5]);
}
+ printf("\n");
+
+ /* And the days of the month. */
+ for (i = 0; i != 6; i++) {
+ for (j = 0; j < count; j++)
+ printf("%-*s ",
+ MW(mw, year[j].extralen[i]),
+ year[j].lines[i]+1);
+ printf("\n");
+ }
+
+ m += mpl;
}
}
void
-printyearb(int y, int jd_flag)
+monthranger(int y, int m, int jd_flag, int before, int after)
{
struct monthlines year[12];
struct weekdays wds;
- char s[80], t[80];
- wchar_t ws[80], wt[80];
+ char s[MAX_WIDTH], t[MAX_WIDTH];
int i, j;
int mpl;
int mw;
+ int m1, m2;
+ int prevyear = -1;
+ int printyearheader;
+
+ mpl = jd_flag ? 3 : 4;
+ mw = jd_flag ? MONTH_WIDTH_R_J : MONTH_WIDTH_R;
+
+ while (before != 0) {
+ DECREASEMONTH(m, y);
+ before--;
+ after++;
+ }
+ m1 = y * 12 + m - 1;
+ m2 = m1 + after;
- for (i = 0; i != 12; i++)
- mkmonthb(y, i, jd_flag, year + i);
mkweekdays(&wds);
- mpl = jd_flag ? 2 : 3;
- mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
- sprintf(s, "%d", y);
- printf("%s\n\n", center(t, s, mw * mpl + mpl));
+ /*
+ * The year header is printed when there are more than 'mpl' months
+ * and if the first month is a multitude of 'mpl'.
+ * If not, it will print the year behind every month.
+ */
+ printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0;
+
+ m = m1;
+ while (m <= m2) {
+ int count = 0;
+ for (i = 0; i != mpl && m + i <= m2; i++) {
+ mkmonthr(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i);
+ count++;
+ }
- for (j = 0; j != 12; j += mpl) {
- wprintf(L"%-*ls ", mw, wcenter(ws, year[j].name, mw));
- if (mpl == 2)
- printf("%ls\n", wcenter(ws, year[j + 1].name, mw));
- else
- wprintf(L"%-*ls %ls\n", mw,
- wcenter(ws, year[j + 1].name, mw),
- wcenter(wt, year[j + 2].name, mw));
-
- if (mpl == 2)
- wprintf(L" %ls %ls %ls %ls %ls %ls %ls "
- " %ls %ls %ls %ls %ls %ls %.2ls\n",
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5],
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5]);
- else
- wprintf(L"%ls%ls%ls%ls%ls%ls%ls "
- "%ls%ls%ls%ls%ls%ls%ls "
- "%ls%ls%ls%ls%ls%ls%.2ls\n",
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5],
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5],
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5]);
- for (i = 0; i != 6; i++) {
- if (mpl == 2)
- printf("%-*s %s\n",
- mw, year[j].lines[i]+1,
- year[j + 1].lines[i]+1);
+ /* Empty line between two rows of months. */
+ if (m != m1)
+ printf("\n");
+
+ /* Year at the top. */
+ if (printyearheader && M2Y(m) != prevyear) {
+ sprintf(s, "%d", M2Y(m));
+ printf("%s\n", center(t, s, mpl * mw));
+ prevyear = M2Y(m);
+ }
+
+ /* Month names. */
+ wprintf(L" ");
+ for (i = 0; i < count; i++)
+ if (printyearheader)
+ wprintf(L"%-*ls", mw, year[i].name);
else
- printf("%-*s %-*s %s\n",
- mw, year[j].lines[i]+1,
- mw, year[j + 1].lines[i]+1,
- year[j + 2].lines[i]+1);
+ wprintf(L"%-ls %-*d", year[i].name,
+ mw - wcslen(year[i].name) - 1, M2Y(m + i));
+ printf("\n");
+
+ /* And the days of the month. */
+ for (i = 0; i != 7; i++) {
+ /* Week day */
+ wprintf(L"%.2ls", wds.names[i]);
+
+ /* Full months */
+ for (j = 0; j < count; j++)
+ printf("%-*s",
+ MW(mw, year[j].extralen[i]),
+ year[j].lines[i]);
+ printf("\n");
+ }
+ /* Week numbers. */
+ if (flag_weeks) {
+ printf(" ");
+ for (i = 0; i < count; i++)
+ printf("%-*s", mw, year[i].weeks);
+ printf("\n");
}
+
+ m += mpl;
}
+ return;
}
void
-mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
+mkmonthr(int y, int m, int jd_flag, struct monthlines *mlines)
{
struct tm tm; /* for strftime printing local names of
@@ -659,7 +801,7 @@ mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
*/
firstm = first - weekday(first);
- /* Set ds (daystring) and dw (daywidth) according to the jd_flag */
+ /* Set ds (daystring) and dw (daywidth) according to the jd_flag. */
if (jd_flag) {
ds = jdaystr;
dw = 4;
@@ -676,40 +818,25 @@ mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
for (i = 0; i != 7; i++) {
l = 0;
for (j = firstm + i, k = 0; j < last; j += 7, k += dw) {
- if (j == today && (term_so != NULL && term_se != NULL)) {
- l = strlen(term_so);
- if (jd_flag)
- dt.d = j - jan1 + 1;
- else
- sdateb(j, &dt);
- /* separator */
- mlines->lines[i][k] = ' ';
- /* the actual text */
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
- /* highlight on */
- memcpy(mlines->lines[i] + k + 1, term_so, l);
- /* highlight off */
- memcpy(mlines->lines[i] + k + l + dw, term_se,
- strlen(term_se));
- l = strlen(term_se) + strlen(term_so);
- continue;
- }
if (j >= first) {
if (jd_flag)
dt.d = j - jan1 + 1;
else
- sdate(j, &dt);
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
+ sdater(j, &dt);
+ if (j == highlightdate && !flag_nohighlight)
+ highlight(mlines->lines[i] + k,
+ ds + dt.d * dw, dw, &l);
+ else
+ memcpy(mlines->lines[i] + k + l,
+ ds + dt.d * dw, dw);
} else
memcpy(mlines->lines[i] + k + l, " ", dw);
}
mlines->lines[i][k + l] = '\0';
-
+ mlines->extralen[i] = l;
}
- /* fill the weeknumbers */
+ /* fill the weeknumbers. */
if (flag_weeks) {
for (j = firstm, k = 0; j < last; k += dw, j += 7)
if (j <= nswitch)
@@ -746,7 +873,7 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
dw = 3;
}
- /* Set name of month centered */
+ /* Set name of month centered. */
memset(&tm, 0, sizeof(tm));
tm.tm_mon = m;
wcsftime(mlines->name, sizeof(mlines->name) / sizeof(mlines->name[0]),
@@ -795,32 +922,17 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
l = 0;
for (j = firsts + 7 * i, k = 0; j < last && k != dw * 7;
j++, k += dw) {
- if (j == today && (term_so != NULL && term_se != NULL)) {
- l = strlen(term_so);
- if (jd_flag)
- dt.d = j - jan1 + 1;
- else
- sdateb(j, &dt);
- /* separator */
- mlines->lines[i][k] = ' ';
- /* the actual text */
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
- /* highlight on */
- memcpy(mlines->lines[i] + k + 1, term_so, l);
- /* highlight off */
- memcpy(mlines->lines[i] + k + l + dw, term_se,
- strlen(term_se));
- l = strlen(term_se) + strlen(term_so);
- continue;
- }
if (j >= first) {
if (jd_flag)
dt.d = j - jan1 + 1;
else
sdateb(j, &dt);
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
+ if (j == highlightdate && !flag_nohighlight)
+ highlight(mlines->lines[i] + k,
+ ds + dt.d * dw, dw, &l);
+ else
+ memcpy(mlines->lines[i] + k + l,
+ ds + dt.d * dw, dw);
} else
memcpy(mlines->lines[i] + k + l, " ", dw);
}
@@ -828,10 +940,11 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
mlines->lines[i][1] = '\0';
else
mlines->lines[i][k + l] = '\0';
+ mlines->extralen[i] = l;
}
}
-/* Put the local names of weekdays into the wds */
+/* Put the local names of weekdays into the wds. */
void
mkweekdays(struct weekdays *wds)
{
@@ -857,9 +970,8 @@ mkweekdays(struct weekdays *wds)
}
/*
- * Compute the day number of the first
- * existing date after the first day in month.
- * (the first day in month and even the month might not exist!)
+ * Compute the day number of the first existing date after the first day in
+ * month. (the first day in month and even the month might not exist!)
*/
int
firstday(int y, int m)
@@ -870,9 +982,9 @@ firstday(int y, int m)
dt.y = y;
dt.m = m;
dt.d = 1;
- nd = sndays(&dt);
+ nd = sndaysr(&dt);
for (;;) {
- sdate(nd, &dt);
+ sdater(nd, &dt);
if ((dt.m >= m && dt.y == y) || dt.y > y)
return (nd);
else
@@ -886,7 +998,7 @@ firstday(int y, int m)
* Julian to Gregorian if specified by the user.
*/
int
-sndays(struct date *d)
+sndaysr(struct date *d)
{
if (nswitch != 0)
@@ -912,9 +1024,9 @@ sndaysb(struct date *d)
return (ndaysj(d));
}
-/* Inverse of sndays */
+/* Inverse of sndays. */
struct date *
-sdate(int nd, struct date *d)
+sdater(int nd, struct date *d)
{
if (nswitch < nd)
@@ -923,7 +1035,7 @@ sdate(int nd, struct date *d)
return (jdate(nd, d));
}
-/* Inverse of sndaysb */
+/* Inverse of sndaysb. */
struct date *
sdateb(int nd, struct date *d)
{
@@ -934,22 +1046,22 @@ sdateb(int nd, struct date *d)
return (jdate(nd, d));
}
-/* Center string t in string s of length w by putting enough leading blanks */
+/* Center string t in string s of length w by putting enough leading blanks. */
char *
center(char *s, char *t, int w)
{
- char blanks[80];
+ char blanks[MAX_WIDTH];
memset(blanks, ' ', sizeof(blanks));
sprintf(s, "%.*s%s", (int)(w - strlen(t)) / 2, blanks, t);
return (s);
}
-/* Center string t in string s of length w by putting enough leading blanks */
+/* Center string t in string s of length w by putting enough leading blanks. */
wchar_t *
wcenter(wchar_t *s, wchar_t *t, int w)
{
- char blanks[80];
+ char blanks[MAX_WIDTH];
memset(blanks, ' ', sizeof(blanks));
swprintf(s, MAX_WIDTH, L"%.*s%ls", (int)(w - wcslen(t)) / 2, blanks, t);
@@ -988,3 +1100,76 @@ parsemonth(const char *s, int *m, int *y)
}
return (1);
}
+
+void
+highlight(char *dst, char *src, int len, int *extralen)
+{
+ static int first = 1;
+ static const char *term_so, *term_se;
+
+ if (first) {
+ char tbuf[1024], cbuf[512], *b;
+
+ term_se = term_so = NULL;
+
+ /* On how to highlight on this type of terminal (if any). */
+ if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
+ b = cbuf;
+ term_so = tgetstr("so", &b);
+ term_se = tgetstr("se", &b);
+ }
+
+ first = 0;
+ }
+
+ /*
+ * This check is not necessary, should have been handled before calling
+ * this function.
+ */
+ if (flag_nohighlight) {
+ memcpy(dst, src, len);
+ return;
+ }
+
+ /*
+ * If it is a real terminal, use the data from the termcap database.
+ */
+ if (term_so != NULL && term_se != NULL) {
+ /* separator. */
+ dst[0] = ' ';
+ dst++;
+ /* highlight on. */
+ memcpy(dst, term_so, strlen(term_so));
+ dst += strlen(term_so);
+ /* the actual text. (minus leading space) */
+ len--;
+ src++;
+ memcpy(dst, src, len);
+ dst += len;
+ /* highlight off. */
+ memcpy(dst, term_se, strlen(term_se));
+ *extralen = strlen(term_so) + strlen(term_se);
+ return;
+ }
+
+ /*
+ * Otherwise, print a _, backspace and the letter.
+ */
+ *extralen = 0;
+ /* skip leading space. */
+ src++;
+ len--;
+ /* separator. */
+ dst[0] = ' ';
+ dst++;
+ while (len > 0) {
+ /* _ and backspace. */
+ memcpy(dst, "_\010", 2);
+ dst += 2;
+ *extralen += 2;
+ /* the character. */
+ *dst++ = *src++;
+ len--;
+ }
+ return;
+}
diff --git a/usr.bin/netstat/netgraph.c b/usr.bin/netstat/netgraph.c
index c4dd647..d510414 100644
--- a/usr.bin/netstat/netgraph.c
+++ b/usr.bin/netstat/netgraph.c
@@ -166,14 +166,14 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused,
name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
/* Get ngsock structure */
- if (ngpcb.sockdata == 0) /* unconnected data socket */
+ if (ngpcb.sockdata == NULL) /* unconnected data socket */
goto finish;
kread((u_long)ngpcb.sockdata, (char *)&info, sizeof(info));
/* Get info on associated node */
- if (info.node == 0 || csock == -1)
+ if (info.node_id == 0 || csock == -1)
goto finish;
- snprintf(path, sizeof(path), "[%lx]:", (u_long) info.node);
+ snprintf(path, sizeof(path), "[%x]:", info.node_id);
if (NgSendMsg(csock, path,
NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0)
goto finish;
diff --git a/usr.bin/perror/perror.1 b/usr.bin/perror/perror.1
index 7faf77f..0b724b1 100644
--- a/usr.bin/perror/perror.1
+++ b/usr.bin/perror/perror.1
@@ -34,7 +34,7 @@
.Nd "print an error number as a string"
.Sh SYNOPSIS
.Nm
-.Op Ar number
+.Ar number
.Sh DESCRIPTION
The
.Nm
diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile
index 1c187b0..fa1c3b4 100644
--- a/usr.bin/procstat/Makefile
+++ b/usr.bin/procstat/Makefile
@@ -9,6 +9,7 @@ SRCS= procstat.c \
procstat_cred.c \
procstat_files.c \
procstat_kstack.c \
+ procstat_sigs.c \
procstat_threads.c \
procstat_vm.c
diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1
index f4dc731..0113e37 100644
--- a/usr.bin/procstat/procstat.1
+++ b/usr.bin/procstat/procstat.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 20, 2008
+.Dd March 7, 2010
.Dt PROCSTAT 1
.Os
.Sh NAME
@@ -34,8 +34,9 @@
.Sh SYNOPSIS
.Nm
.Op Fl h
+.Op Fl n
.Op Fl w Ar interval
-.Op Fl b | c | f | k | s | t | v
+.Op Fl b | c | f | i | j | k | s | t | v
.Op Fl a | Ar pid ...
.Sh DESCRIPTION
The
@@ -56,6 +57,10 @@ Display binary information for the process.
Display command line arguments for the process.
.It Fl f
Display file descriptor information for the process.
+.It Fl i
+Display signal pending and disposition information for the process.
+.It Fl j
+Display signal pending and blocked information for the process threads.
.It Fl k
Display the stacks of kernel threads in the process, excluding stacks of
threads currently running on a CPU and threads with stacks swapped to disk.
@@ -204,6 +209,58 @@ direct I/O
.It l
lock held
.El
+.Ss Signal Disposition Information
+Display signal pending and disposition for a process:
+.Pp
+.Bl -tag -width ident -compact
+.It PID
+process ID
+.It COMM
+command
+.It SIG
+signal name
+.It FLAGS
+process signal disposition details, three symbols
+.Bl -tag -width X -compact
+.It P
+if signal is pending in the global process queue, - otherwise
+.It I
+if signal delivery disposition is SIGIGN, - otherwise
+.It C
+if signal delivery is to catch it, - otherwise
+.El
+.El
+.Pp
+If
+.Fl n
+switch is given, the signal numbers are shown instead of signal names.
+.Ss Thread Signal Information
+Display signal pending and blocked for a process threads:
+.Pp
+.Bl -tag -width ident -compact
+.It PID
+process ID
+.It COMM
+command
+.It TID
+thread ID
+.It SIG
+signal name
+.It FLAGS
+thread signal delivery status, two symbols
+.Bl -tag -width X -compact
+.It P
+if signal is pending for the thread, - otherwise
+.It B
+if signal is blocked in the thread signal mask, - if not blocked
+.El
+.El
+.Pp
+The
+.Fl n
+switch has the same effect as for the
+.Fl i
+switch, the signals numbers are shown instead of signal names.
.Ss Kernel Thread Stacks
Display kernel thread stacks for a process, allowing further interpretation
of thread wait channels.
diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c
index bc02682..ee95ae2 100644
--- a/usr.bin/procstat/procstat.c
+++ b/usr.bin/procstat/procstat.c
@@ -38,15 +38,15 @@
#include "procstat.h"
-static int aflag, bflag, cflag, fflag, kflag, sflag, tflag, vflag;
-int hflag;
+static int aflag, bflag, cflag, fflag, iflag, jflag, kflag, sflag, tflag, vflag;
+int hflag, nflag;
static void
usage(void)
{
- fprintf(stderr, "usage: procstat [-h] [-w interval] [-b | -c | -f | "
- "-k | -s | -t | -v]\n");
+ fprintf(stderr, "usage: procstat [-h] [-n] [-w interval] [-b | -c | -f | "
+ "-i | -j | -k | -s | -t | -v]\n");
fprintf(stderr, " [-a | pid ...]\n");
exit(EX_USAGE);
}
@@ -61,6 +61,10 @@ procstat(pid_t pid, struct kinfo_proc *kipp)
procstat_args(pid, kipp);
else if (fflag)
procstat_files(pid, kipp);
+ else if (iflag)
+ procstat_sigs(pid, kipp);
+ else if (jflag)
+ procstat_threads_sigs(pid, kipp);
else if (kflag)
procstat_kstack(pid, kipp, kflag);
else if (sflag)
@@ -109,7 +113,7 @@ main(int argc, char *argv[])
char *dummy;
interval = 0;
- while ((ch = getopt(argc, argv, "abcfkhstvw:")) != -1) {
+ while ((ch = getopt(argc, argv, "abcfijknhstvw:")) != -1) {
switch (ch) {
case 'a':
aflag++;
@@ -127,10 +131,22 @@ main(int argc, char *argv[])
fflag++;
break;
+ case 'i':
+ iflag++;
+ break;
+
+ case 'j':
+ jflag++;
+ break;
+
case 'k':
kflag++;
break;
+ case 'n':
+ nflag++;
+ break;
+
case 'h':
hflag++;
break;
diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h
index 8bacab7..d73a203 100644
--- a/usr.bin/procstat/procstat.h
+++ b/usr.bin/procstat/procstat.h
@@ -29,7 +29,7 @@
#ifndef PROCSTAT_H
#define PROCSTAT_H
-extern int hflag;
+extern int hflag, nflag;
struct kinfo_proc;
void kinfo_proc_sort(struct kinfo_proc *kipp, int count);
@@ -40,7 +40,9 @@ void procstat_bin(pid_t pid, struct kinfo_proc *kipp);
void procstat_cred(pid_t pid, struct kinfo_proc *kipp);
void procstat_files(pid_t pid, struct kinfo_proc *kipp);
void procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag);
+void procstat_sigs(pid_t pid, struct kinfo_proc *kipp);
void procstat_threads(pid_t pid, struct kinfo_proc *kipp);
+void procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp);
void procstat_vm(pid_t pid, struct kinfo_proc *kipp);
#endif /* !PROCSTAT_H */
diff --git a/usr.bin/procstat/procstat_sigs.c b/usr.bin/procstat/procstat_sigs.c
new file mode 100644
index 0000000..b1f5e35
--- /dev/null
+++ b/usr.bin/procstat/procstat_sigs.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2010 Konstantin Belousov
+ * 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/param.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "procstat.h"
+
+static void
+procstat_print_signame(int sig)
+{
+ char name[12];
+ int i;
+
+ if (!nflag && sig < sys_nsig) {
+ strlcpy(name, sys_signame[sig], sizeof(name));
+ for (i = 0; name[i] != 0; i++)
+ name[i] = toupper(name[i]);
+ printf("%-7s ", name);
+ } else
+ printf("%-7d ", sig);
+}
+
+static void
+procstat_print_sig(const sigset_t *set, int sig, char flag)
+{
+
+ printf("%c", sigismember(set, sig) ? flag : '-');
+}
+
+void
+procstat_sigs(pid_t pid, struct kinfo_proc *kipp)
+{
+ int j;
+
+ if (!hflag)
+ printf("%5s %-16s %-7s %4s\n", "PID", "COMM", "SIG", "FLAGS");
+
+ for (j = 1; j <= _SIG_MAXSIG; j++) {
+ printf("%5d ", pid);
+ printf("%-16s ", kipp->ki_comm);
+ procstat_print_signame(j);
+ printf(" ");
+ procstat_print_sig(&kipp->ki_siglist, j, 'P');
+ procstat_print_sig(&kipp->ki_sigignore, j, 'I');
+ procstat_print_sig(&kipp->ki_sigcatch, j, 'C');
+ printf("\n");
+ }
+}
+
+void
+procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp)
+{
+ struct kinfo_proc *kip;
+ int error, name[4], j;
+ unsigned int i;
+ size_t len;
+
+ if (!hflag)
+ printf("%5s %6s %-16s %-7s %4s\n", "PID", "TID", "COMM",
+ "SIG", "FLAGS");
+
+ /*
+ * We need to re-query for thread information, so don't use *kipp.
+ */
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
+ name[3] = pid;
+
+ len = 0;
+ error = sysctl(name, 4, NULL, &len, NULL, 0);
+ if (error < 0 && errno != ESRCH) {
+ warn("sysctl: kern.proc.pid: %d", pid);
+ return;
+ }
+ if (error < 0)
+ return;
+
+ kip = malloc(len);
+ if (kip == NULL)
+ err(-1, "malloc");
+
+ if (sysctl(name, 4, kip, &len, NULL, 0) < 0) {
+ warn("sysctl: kern.proc.pid: %d", pid);
+ free(kip);
+ return;
+ }
+
+ kinfo_proc_sort(kip, len / sizeof(*kipp));
+ for (i = 0; i < len / sizeof(*kipp); i++) {
+ kipp = &kip[i];
+ for (j = 1; j <= _SIG_MAXSIG; j++) {
+ printf("%5d ", pid);
+ printf("%6d ", kipp->ki_tid);
+ printf("%-16s ", kipp->ki_comm);
+ procstat_print_signame(j);
+ printf(" ");
+ procstat_print_sig(&kipp->ki_siglist, j, 'P');
+ procstat_print_sig(&kipp->ki_sigmask, j, 'B');
+ printf("\n");
+ }
+ }
+ free(kip);
+}
diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c
index bd2de28..6c4e0ee 100644
--- a/usr.bin/script/script.c
+++ b/usr.bin/script/script.c
@@ -158,6 +158,7 @@ main(int argc, char *argv[])
}
if (child == 0)
doshell(argv);
+ close(slave);
if (flushtime > 0)
tvp = &tv;
diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index 1a140b1..8d4fe95 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -130,8 +130,9 @@ main(int argc, char *argv[])
fflag = 0;
inplace = NULL;
- while ((c = getopt(argc, argv, "EI:ae:f:i:ln")) != -1)
+ while ((c = getopt(argc, argv, "EI:ae:f:i:lnr")) != -1)
switch (c) {
+ case 'r': /* Gnu sed compat */
case 'E':
rflags = REG_EXTENDED;
break;
diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1
index d5858ff..0744630 100644
--- a/usr.bin/sed/sed.1
+++ b/usr.bin/sed/sed.1
@@ -39,11 +39,11 @@
.Nd stream editor
.Sh SYNOPSIS
.Nm
-.Op Fl Ealn
+.Op Fl Ealnr
.Ar command
.Op Ar
.Nm
-.Op Fl Ealn
+.Op Fl Ealnr
.Op Fl e Ar command
.Op Fl f Ar command_file
.Op Fl I Ar extension
@@ -144,6 +144,10 @@ all of the commands have been applied to it.
The
.Fl n
option suppresses this behavior.
+.It Fl r
+Same as
+.Fl E
+for compatibility with GNU sed.
.El
.Pp
The form of a
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 1a5af42..2242c4e 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -621,6 +621,8 @@ display(void)
case AF_INET:
case AF_INET6:
pos += printaddr(s->family, &s->laddr);
+ if (s->family == AF_INET6 && pos >= 58)
+ pos += xprintf(" ");
while (pos < 58)
pos += xprintf(" ");
pos += printaddr(s->family, &s->faddr);
diff --git a/usr.bin/stat/stat.1 b/usr.bin/stat/stat.1
index 6856efa..8bbdda4 100644
--- a/usr.bin/stat/stat.1
+++ b/usr.bin/stat/stat.1
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 27, 2007
+.Dd April 24, 2010
.Dt STAT 1
.Os
.Sh NAME
@@ -232,6 +232,11 @@ Display date in
format.
.It Cm dr
Display actual device name.
+.It Cm f
+Display the flags of
+.Ar file
+as in
+.Nm ls Fl lTdo .
.It Cm gu
Display group or user name.
.It Cm p
diff --git a/usr.bin/stat/stat.c b/usr.bin/stat/stat.c
index 83d389b..1ab10ea 100644
--- a/usr.bin/stat/stat.c
+++ b/usr.bin/stat/stat.c
@@ -182,6 +182,9 @@ int format1(const struct stat *, /* stat info */
char *, size_t, /* a place to put the output */
int, int, int, int, /* the parsed format */
int, int);
+#if HAVE_STRUCT_STAT_ST_FLAGS
+char *xfflagstostr(unsigned long);
+#endif
char *timefmt;
int linkfail;
@@ -333,6 +336,25 @@ main(int argc, char *argv[])
return (am_readlink ? linkfail : errs);
}
+#if HAVE_STRUCT_STAT_ST_FLAGS
+/*
+ * fflagstostr() wrapper that leaks only once
+ */
+char *
+xfflagstostr(unsigned long fflags)
+{
+ static char *str = NULL;
+
+ if (str != NULL)
+ free(str);
+
+ str = fflagstostr(fflags);
+ if (str == NULL)
+ err(1, "fflagstostr");
+ return (str);
+}
+#endif /* HAVE_STRUCT_STAT_ST_FLAGS */
+
void
usage(const char *synopsis)
{
@@ -725,8 +747,11 @@ format1(const struct stat *st,
case SHOW_st_flags:
small = (sizeof(st->st_flags) == 4);
data = st->st_flags;
- sdata = NULL;
- formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX;
+ sdata = xfflagstostr(st->st_flags);
+ if (*sdata == '\0')
+ sdata = "-";
+ formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
+ FMTF_STRING;
if (ofmt == 0)
ofmt = FMTF_UNSIGNED;
break;
diff --git a/usr.bin/tar/bsdtar.1 b/usr.bin/tar/bsdtar.1
index 8baab7a..ac9afbb 100644
--- a/usr.bin/tar/bsdtar.1
+++ b/usr.bin/tar/bsdtar.1
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 25, 2009
+.Dd Oct 12, 2009
.Dt BSDTAR 1
.Os
.Sh NAME
@@ -336,6 +336,13 @@ This is enabled by default, use
or
.Cm iso9660:!joliet
to disable.
+.It Cm iso9660:rockridge
+Support Rock Ridge extensions.
+This is enabled by default, use
+.Cm !rockridge
+or
+.Cm iso9660:!rockridge
+to disable.
.It Cm gzip:compression-level
A decimal integer from 0 to 9 specifying the gzip compression level.
.It Cm xz:compression-level
@@ -359,7 +366,13 @@ Enable generation of
.Cm /set
lines in the output.
.It Cm mtree:indent
-XXX need explanation XXX
+Produce human-readable output by indenting options and splitting lines
+to fit into 80 columns.
+.It Cm zip:compression Ns = Ns Ar type
+Use
+.Ar type
+as compression method.
+Supported values are store (uncompressed) and deflate (gzip algorithm).
.El
If a provided option is not supported by any module, that
is a fatal error.
@@ -412,10 +425,20 @@ but before security checks.
.It Fl s Ar pattern
Modify file or archive member names according to
.Pa pattern .
-The pattern has the format /old/new/[gps].
-old is a basic regular expression.
-If it doesn't apply, the pattern is skipped.
-new is the replacement string of the matched part.
+The pattern has the format
+.Ar /old/new/ Ns Op gps
+where
+.Ar old
+is a basic regular expression,
+.Ar new
+is the replacement string of the matched part,
+and the optional trailing letters modify
+how the replacement is handled.
+If
+.Ar old
+is not matched, the pattern is skipped.
+Within
+.Ar new ,
~ is substituted with the match, \1 to \9 with the content of
the corresponding captured group.
The optional trailing g specifies that matching should continue
diff --git a/usr.bin/tar/bsdtar.c b/usr.bin/tar/bsdtar.c
index c858ba3..00c6f45 100644
--- a/usr.bin/tar/bsdtar.c
+++ b/usr.bin/tar/bsdtar.c
@@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
#include "bsdtar.h"
#include "err.h"
-#include "matching.h"
/*
* Per POSIX.1-1988, tar defaults to reading/writing archives to/from
@@ -180,8 +179,10 @@ main(int argc, char **argv)
time(&now);
+#if HAVE_SETLOCALE
if (setlocale(LC_ALL, "") == NULL)
bsdtar_warnc(0, "Failed to set default locale");
+#endif
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_D_MD_ORDER)
bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd');
#endif
diff --git a/usr.bin/tar/bsdtar_platform.h b/usr.bin/tar/bsdtar_platform.h
index 5ad8d30..c9b9dd6 100644
--- a/usr.bin/tar/bsdtar_platform.h
+++ b/usr.bin/tar/bsdtar_platform.h
@@ -62,6 +62,10 @@
#include "archive_entry.h"
#endif
+#ifdef HAVE_LIBACL
+#include <acl/libacl.h>
+#endif
+
/*
* Include "dirent.h" (or it's equivalent on several different platforms).
*
diff --git a/usr.bin/tar/matching.c b/usr.bin/tar/matching.c
index 184d29a..dc316b1 100644
--- a/usr.bin/tar/matching.c
+++ b/usr.bin/tar/matching.c
@@ -89,7 +89,7 @@ lafe_exclude_from_file(struct lafe_matching **matching, const char *pathname)
const char *p;
int ret = 0;
- lr = lafe_line_reader(pathname, '\n');
+ lr = lafe_line_reader(pathname, 0);
while ((p = lafe_line_reader_next(lr)) != NULL) {
if (lafe_exclude(matching, p) != 0)
ret = -1;
@@ -156,40 +156,41 @@ lafe_excluded(struct lafe_matching *matching, const char *pathname)
if (matching == NULL)
return (0);
+ /* Mark off any unmatched inclusions. */
+ /* In particular, if a filename does appear in the archive and
+ * is explicitly included and excluded, then we don't report
+ * it as missing even though we don't extract it.
+ */
+ matched = NULL;
+ for (match = matching->inclusions; match != NULL; match = match->next){
+ if (match->matches == 0
+ && match_inclusion(match, pathname)) {
+ matching->inclusions_unmatched_count--;
+ match->matches++;
+ matched = match;
+ }
+ }
+
/* Exclusions take priority */
for (match = matching->exclusions; match != NULL; match = match->next){
if (match_exclusion(match, pathname))
return (1);
}
- /* Then check for inclusions */
- matched = NULL;
+ /* It's not excluded and we found an inclusion above, so it's included. */
+ if (matched != NULL)
+ return (0);
+
+
+ /* We didn't find an unmatched inclusion, check the remaining ones. */
for (match = matching->inclusions; match != NULL; match = match->next){
- if (match_inclusion(match, pathname)) {
- /*
- * If this pattern has never been matched,
- * then we're done.
- */
- if (match->matches == 0) {
- match->matches++;
- matching->inclusions_unmatched_count--;
- return (0);
- }
- /*
- * Otherwise, remember the match but keep checking
- * in case we can tick off an unmatched pattern.
- */
- matched = match;
+ /* We looked at previously-unmatched inclusions already. */
+ if (match->matches > 0
+ && match_inclusion(match, pathname)) {
+ match->matches++;
+ return (0);
}
}
- /*
- * We didn't find a pattern that had never been matched, but
- * we did find a match, so count it and exit.
- */
- if (matched != NULL) {
- matched->matches++;
- return (0);
- }
/* If there were inclusions, default is to exclude. */
if (matching->inclusions != NULL)
diff --git a/usr.bin/tar/subst.c b/usr.bin/tar/subst.c
index 44fd87b..a217293 100644
--- a/usr.bin/tar/subst.c
+++ b/usr.bin/tar/subst.c
@@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
#if HAVE_REGEX_H
#include "bsdtar.h"
-#include "err.h"
#include <errno.h>
#include <regex.h>
@@ -39,6 +38,8 @@ __FBSDID("$FreeBSD$");
#define REG_BASIC 0
#endif
+#include "err.h"
+
struct subst_rule {
struct subst_rule *next;
regex_t re;
diff --git a/usr.bin/tar/tree.h b/usr.bin/tar/tree.h
index 09e36e4..3ae74fd 100644
--- a/usr.bin/tar/tree.h
+++ b/usr.bin/tar/tree.h
@@ -53,16 +53,17 @@ void tree_close(struct tree *);
/*
* tree_next() returns Zero if there is no next entry, non-zero if
- * there is. Note that directories are potentially visited three
- * times. Directories are always visited first as part of enumerating
- * their parent. If tree_descend() is invoked at that time, the
- * directory is added to a work list and will subsequently be visited
- * two more times: once just after descending into the directory and
- * again just after ascending back to the parent.
+ * there is. Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
*
* TREE_ERROR_DIR is returned if the descent failed (because the
* directory couldn't be opened, for instance). This is returned
- * instead of TREE_PREVISIT/TREE_POSTVISIT. TREE_ERROR_DIR is not a
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
* fatal error, but it does imply that the relevant subtree won't be
* visited. TREE_ERROR_FATAL is returned for an error that left the
* traversal completely hosed. Right now, this is only returned for
@@ -96,10 +97,23 @@ void tree_descend(struct tree *);
int tree_current_depth(struct tree *);
/*
- * The current full pathname, length of the full pathname,
- * and a name that can be used to access the file.
- * Because tree does use chdir extensively, the access path is
- * almost never the same as the full current path.
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file. Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ * TODO: Flesh out this interface to provide other information. In
+ * particular, Windows can provide file size, mode, and some permission
+ * information without invoking stat() at all.
+ *
+ * TODO: On platforms that support it, use openat()-style operations
+ * to eliminate the chdir() operations entirely while still supporting
+ * arbitrarily deep traversals. This makes access_path troublesome to
+ * support, of course, which means we'll need a rich enough interface
+ * that clients can function without it. (In particular, we'll need
+ * tree_current_open() that returns an open file descriptor.)
+ *
+ * TODO: Provide tree_current_archive_entry().
*/
const char *tree_current_path(struct tree *);
size_t tree_current_pathlen(struct tree *);
diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c
index 31005eb..207122e 100644
--- a/usr.bin/tar/write.c
+++ b/usr.bin/tar/write.c
@@ -95,6 +95,10 @@ __FBSDID("$FreeBSD$");
/* Fixed size of uname/gname caches. */
#define name_cache_size 101
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
static const char * const NO_NAME = "(noname)";
struct archive_dir_entry {
@@ -256,9 +260,9 @@ tar_mode_r(struct bsdtar *bsdtar)
format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
#if defined(__BORLANDC__)
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT);
+ bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY);
#else
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666);
+ bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666);
#endif
if (bsdtar->fd < 0)
bsdtar_errc(1, errno,
@@ -353,7 +357,7 @@ tar_mode_u(struct bsdtar *bsdtar)
/* Sanity-test some arguments and the file. */
test_for_append(bsdtar);
- bsdtar->fd = open(bsdtar->filename, O_RDWR);
+ bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY);
if (bsdtar->fd < 0)
bsdtar_errc(1, errno,
"Cannot open %s", bsdtar->filename);
@@ -843,7 +847,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
#if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL)
/* Linux uses ioctl to read flags. */
if (bsdtar->option_honor_nodump) {
- int fd = open(name, O_RDONLY | O_NONBLOCK);
+ int fd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY);
if (fd >= 0) {
unsigned long fflags;
int r = ioctl(fd, EXT2_IOC_GETFLAGS, &fflags);
@@ -913,7 +917,7 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
if (archive_entry_size(entry) > 0) {
const char *pathname = archive_entry_sourcepath(entry);
- fd = open(pathname, O_RDONLY);
+ fd = open(pathname, O_RDONLY | O_BINARY);
if (fd == -1) {
if (!bsdtar->verbose)
bsdtar_warnc(errno,
diff --git a/usr.bin/touch/touch.c b/usr.bin/touch/touch.c
index 5ceb175..2148939 100644
--- a/usr.bin/touch/touch.c
+++ b/usr.bin/touch/touch.c
@@ -187,9 +187,9 @@ main(int argc, char *argv[])
}
if (!aflag)
- TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atim);
if (!mflag)
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
/*
* We're adjusting the times based on the file times, not a
@@ -197,11 +197,11 @@ main(int argc, char *argv[])
*/
if (Aflag) {
if (aflag) {
- TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atim);
tv[0].tv_sec += Aflag;
}
if (mflag) {
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
tv[1].tv_sec += Aflag;
}
}
@@ -368,8 +368,8 @@ stime_file(char *fname, struct timeval *tvp)
if (stat(fname, &sb))
err(1, "%s", fname);
- TIMESPEC_TO_TIMEVAL(tvp, &sb.st_atimespec);
- TIMESPEC_TO_TIMEVAL(tvp + 1, &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(tvp, &sb.st_atim);
+ TIMESPEC_TO_TIMEVAL(tvp + 1, &sb.st_mtim);
}
int
diff --git a/usr.bin/truncate/Makefile b/usr.bin/truncate/Makefile
index 4752c5c..1b24d35 100644
--- a/usr.bin/truncate/Makefile
+++ b/usr.bin/truncate/Makefile
@@ -1,5 +1,7 @@
# $FreeBSD$
PROG= truncate
+DPADD= ${LIBUTIL}
+LDADD= -lutil
.include <bsd.prog.mk>
diff --git a/usr.bin/truncate/truncate.c b/usr.bin/truncate/truncate.c
index 3ab068b..12b81af 100644
--- a/usr.bin/truncate/truncate.c
+++ b/usr.bin/truncate/truncate.c
@@ -40,7 +40,8 @@ static const char rcsid[] =
#include <stdlib.h>
#include <unistd.h>
-static int parselength(char *, off_t *);
+#include <libutil.h>
+
static void usage(void);
static int no_create;
@@ -53,7 +54,8 @@ main(int argc, char **argv)
{
struct stat sb;
mode_t omode;
- off_t oflow, rsize, sz, tsize;
+ off_t oflow, rsize, tsize;
+ int64_t sz;
int ch, error, fd, oflags;
char *fname, *rname;
@@ -71,7 +73,7 @@ main(int argc, char **argv)
rname = optarg;
break;
case 's':
- if (parselength(optarg, &sz) == -1)
+ if (expand_number(optarg, &sz) == -1)
errx(EXIT_FAILURE,
"invalid size argument `%s'", optarg);
if (*optarg == '+' || *optarg == '-')
@@ -148,65 +150,6 @@ main(int argc, char **argv)
return error ? EXIT_FAILURE : EXIT_SUCCESS;
}
-/*
- * Return the numeric value of a string given in the form [+-][0-9]+[GMKT]
- * or -1 on format error or overflow.
- */
-static int
-parselength(char *ls, off_t *sz)
-{
- off_t length, oflow;
- int lsign;
-
- length = 0;
- lsign = 1;
-
- switch (*ls) {
- case '-':
- lsign = -1;
- case '+':
- ls++;
- }
-
-#define ASSIGN_CHK_OFLOW(x, y) if (x < y) return -1; y = x
- /*
- * Calculate the value of the decimal digit string, failing
- * on overflow.
- */
- while (isdigit(*ls)) {
- oflow = length * 10 + *ls++ - '0';
- ASSIGN_CHK_OFLOW(oflow, length);
- }
-
- switch (*ls) {
- case 'T':
- case 't':
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case 'G':
- case 'g':
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case 'M':
- case 'm':
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case 'K':
- case 'k':
- if (ls[1] != '\0')
- return -1;
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case '\0':
- break;
- default:
- return -1;
- }
-
- *sz = length * lsign;
- return 0;
-}
-
static void
usage(void)
{
diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c
index bfd39c2..b6a5195 100644
--- a/usr.bin/truss/amd64-fbsd.c
+++ b/usr.bin/truss/amd64-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c
index 3b1b882..ec8b406 100644
--- a/usr.bin/truss/amd64-fbsd32.c
+++ b/usr.bin/truss/amd64-fbsd32.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c
index 5e9d012..f392a4b 100644
--- a/usr.bin/truss/amd64-linux32.c
+++ b/usr.bin/truss/amd64-linux32.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/extern.h b/usr.bin/truss/extern.h
index fc3b038..322e291 100644
--- a/usr.bin/truss/extern.h
+++ b/usr.bin/truss/extern.h
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c
index 3a81392..9c20eb5 100644
--- a/usr.bin/truss/i386-fbsd.c
+++ b/usr.bin/truss/i386-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c
index cf4c1c0..8e0aa04 100644
--- a/usr.bin/truss/i386-linux.c
+++ b/usr.bin/truss/i386-linux.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/ia64-fbsd.c b/usr.bin/truss/ia64-fbsd.c
index dae1116..e631707 100644
--- a/usr.bin/truss/ia64-fbsd.c
+++ b/usr.bin/truss/ia64-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c
index 586fcd6..5c7da1d 100644
--- a/usr.bin/truss/main.c
+++ b/usr.bin/truss/main.c
@@ -1,5 +1,5 @@
/*-
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c
index cf5e2e1..55cbdb1 100644
--- a/usr.bin/truss/mips-fbsd.c
+++ b/usr.bin/truss/mips-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1998 Sean Eric Fagan
+ * Copyright 1998 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c
index 8de66ee..ab5b9a4 100644
--- a/usr.bin/truss/powerpc-fbsd.c
+++ b/usr.bin/truss/powerpc-fbsd.c
@@ -1,7 +1,7 @@
/*
* Copyright 2006 Peter Grehan <grehan@freebsd.org>
- * Copryight 2005 Orlando Bassotto <orlando@break.net>
- * Copryight 1998 Sean Eric Fagan
+ * Copyright 2005 Orlando Bassotto <orlando@break.net>
+ * Copyright 1998 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
index 53a6fe1..ce18f98 100644
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -1,5 +1,5 @@
/*-
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c
index d06e6b0..2eb21bd 100644
--- a/usr.bin/truss/sparc64-fbsd.c
+++ b/usr.bin/truss/sparc64-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1998 Sean Eric Fagan
+ * Copyright 1998 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index f927e1e..7ef8e19 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h
index 89198c9..4bf5a55 100644
--- a/usr.bin/truss/truss.h
+++ b/usr.bin/truss/truss.h
@@ -1,5 +1,5 @@
/*
- * Copryight 2001 Jamey Wood
+ * Copyright 2001 Jamey Wood
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/unifdef/unifdef.1 b/usr.bin/unifdef/unifdef.1
index da7cde8..0803d72 100644
--- a/usr.bin/unifdef/unifdef.1
+++ b/usr.bin/unifdef/unifdef.1
@@ -29,11 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94
-.\" $dotat: unifdef/unifdef.1,v 1.63 2010/02/19 16:41:15 fanf2 Exp $
.\" $FreeBSD$
.\"
-.Dd January 19, 2010
+.Dd March 11, 2010
.Dt UNIFDEF 1
.Os
.Sh NAME
@@ -41,7 +39,7 @@
.Nd remove preprocessor conditionals from code
.Sh SYNOPSIS
.Nm
-.Op Fl BbcdeKknst
+.Op Fl bBcdeKknsStV
.Op Fl I Ns Ar path
.Op Fl D Ns Ar sym Ns Op = Ns Ar val
.Op Fl U Ns Ar sym
@@ -184,12 +182,6 @@ Specify that a symbol is undefined.
If the same symbol appears in more than one argument,
the last occurrence dominates.
.Pp
-.It Fl B
-Compress blank lines around a deleted section.
-Mutually exclusive with the
-.Fl b
-option.
-.Pp
.It Fl b
Replace removed lines with blank lines
instead of deleting them.
@@ -197,6 +189,12 @@ Mutually exclusive with the
.Fl B
option.
.Pp
+.It Fl B
+Compress blank lines around a deleted section.
+Mutually exclusive with the
+.Fl b
+option.
+.Pp
.It Fl c
If the
.Fl c
@@ -285,6 +283,13 @@ for creating
.Nm
command lines.
.Pp
+.It Fl S
+Like the
+.Fl s
+option, but the nesting depth of each symbol is also printed.
+This is useful for working out the number of possible combinations
+of interdependent defined/undefined symbols.
+.Pp
.It Fl t
Disables parsing for C comments
and line continuations,
@@ -329,6 +334,9 @@ for compatibility with
.Xr cpp 1
and to simplify the implementation of
.Nm unifdefall .
+.Pp
+.It Fl V
+Print version details.
.El
.Pp
The
diff --git a/usr.bin/unifdef/unifdef.c b/usr.bin/unifdef/unifdef.c
index cdcc403..b8f99f8 100644
--- a/usr.bin/unifdef/unifdef.c
+++ b/usr.bin/unifdef/unifdef.c
@@ -56,12 +56,12 @@
#include <string.h>
#include <unistd.h>
-#ifdef __IDSTRING
-__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.198 2010/02/19 16:37:05 fanf2 Exp $");
-#endif
-#ifdef __FBSDID
-__FBSDID("$FreeBSD$");
-#endif
+const char copyright[] =
+ "@(#) $Version: unifdef-2.3 $\n"
+ "@(#) $FreeBSD$\n"
+ "@(#) $Author: Tony Finch (dot@dotat.at) $\n"
+ "@(#) $URL: http://dotat.at/prog/unifdef $\n"
+;
/* types of input lines: */
typedef enum {
@@ -172,6 +172,7 @@ static bool strictlogic; /* -K: keep ambiguous #ifs */
static bool killconsts; /* -k: eval constant #ifs */
static bool lnnum; /* -n: add #line directives */
static bool symlist; /* -s: output symbol list */
+static bool symdepth; /* -S: output symbol depth */
static bool text; /* -t: this is a text file */
static const char *symname[MAXSYMS]; /* symbol name */
@@ -204,6 +205,8 @@ static int delcount; /* count of deleted lines */
static unsigned blankcount; /* count of blank lines */
static unsigned blankmax; /* maximum recent blankcount */
static bool constexpr; /* constant #if expression */
+static bool zerosyms = true; /* to format symdepth output */
+static bool firstsym; /* ditto */
static int exitstat; /* program exit status */
@@ -228,6 +231,7 @@ static void state(Ifstate);
static int strlcmp(const char *, const char *, size_t);
static void unnest(void);
static void usage(void);
+static void version(void);
#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
@@ -239,7 +243,7 @@ main(int argc, char *argv[])
{
int opt;
- while ((opt = getopt(argc, argv, "i:D:U:I:o:BbcdeKklnst")) != -1)
+ while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1)
switch (opt) {
case 'i': /* treat stuff controlled by these symbols as text */
/*
@@ -261,16 +265,15 @@ main(int argc, char *argv[])
case 'U': /* undef a symbol */
addsym(false, false, optarg);
break;
- case 'I':
- /* no-op for compatibility with cpp */
- break;
- case 'B': /* compress blank lines around removed section */
- compblank = true;
+ case 'I': /* no-op for compatibility with cpp */
break;
case 'b': /* blank deleted lines instead of omitting them */
case 'l': /* backwards compatibility */
lnblank = true;
break;
+ case 'B': /* compress blank lines around removed section */
+ compblank = true;
+ break;
case 'c': /* treat -D as -U and vice versa */
complement = true;
break;
@@ -295,9 +298,14 @@ main(int argc, char *argv[])
case 's': /* only output list of symbols that control #ifs */
symlist = true;
break;
+ case 'S': /* list symbols with their nesting depth */
+ symlist = symdepth = true;
+ break;
case 't': /* don't parse C comments */
text = true;
break;
+ case 'V': /* print version */
+ version();
default:
usage();
}
@@ -309,7 +317,7 @@ main(int argc, char *argv[])
errx(2, "can only do one file");
} else if (argc == 1 && strcmp(*argv, "-") != 0) {
filename = *argv;
- input = fopen(filename, "r");
+ input = fopen(filename, "rb");
if (input == NULL)
err(2, "can't open %s", filename);
} else {
@@ -345,12 +353,12 @@ main(int argc, char *argv[])
TEMPLATE);
ofd = mkstemp(tempname);
if (ofd != -1)
- output = fdopen(ofd, "w+");
+ output = fdopen(ofd, "wb+");
if (output == NULL)
err(2, "can't create temporary file");
- fchmod(ofd, ist.st_mode & ACCESSPERMS);
+ fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
} else {
- output = fopen(ofilename, "w");
+ output = fopen(ofilename, "wb");
if (output == NULL)
err(2, "can't open %s", ofilename);
}
@@ -360,9 +368,23 @@ main(int argc, char *argv[])
}
static void
+version(void)
+{
+ const char *c = copyright;
+ for (;;) {
+ while (*++c != '$')
+ if (*c == '\0')
+ exit(0);
+ while (*++c != '$')
+ putc(*c, stderr);
+ putc('\n', stderr);
+ }
+}
+
+static void
usage(void)
{
- fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]"
+ fprintf(stderr, "usage: unifdef [-bBcdeKknsStV] [-Ipath]"
" [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
exit(2);
}
@@ -557,6 +579,8 @@ flushline(bool keep)
delcount += 1;
blankcount = 0;
}
+ if (debugging)
+ fflush(output);
}
/*
@@ -565,17 +589,14 @@ flushline(bool keep)
static void
process(void)
{
- Linetype lineval;
-
/* When compressing blank lines, act as if the file
is preceded by a large number of blank lines. */
blankmax = blankcount = 1000;
for (;;) {
- linenum++;
- lineval = parseline();
+ Linetype lineval = parseline();
trans_table[ifstate[depth]][lineval]();
- debug("process %s -> %s depth %d",
- linetype_name[lineval],
+ debug("process line %d %s -> %s depth %d",
+ linenum, linetype_name[lineval],
ifstate_name[ifstate[depth]], depth);
}
}
@@ -586,6 +607,8 @@ process(void)
static void
closeout(void)
{
+ if (symdepth && !zerosyms)
+ printf("\n");
if (fclose(output) == EOF) {
warn("couldn't write to %s", ofilename);
if (overwriting) {
@@ -628,6 +651,7 @@ parseline(void)
Linetype retval;
Comment_state wascomment;
+ linenum++;
if (fgets(tline, MAXLINE, input) == NULL)
return (LT_EOF);
if (newline == NULL) {
@@ -642,6 +666,7 @@ parseline(void)
if (linestate == LS_START) {
if (*cp == '#') {
linestate = LS_HASH;
+ firstsym = true;
cp = skipcomment(cp + 1);
} else if (*cp != '\0')
linestate = LS_DIRTY;
@@ -715,7 +740,7 @@ parseline(void)
while (*cp != '\0')
cp = skipcomment(cp + 1);
}
- debug("parser %s comment %s line",
+ debug("parser line %d state %s comment %s line", linenum,
comment_name[incomment], linestate_name[linestate]);
return (retval);
}
@@ -1108,7 +1133,13 @@ findsym(const char *str)
if (cp == str)
return (-1);
if (symlist) {
- printf("%.*s\n", (int)(cp-str), str);
+ if (symdepth && firstsym)
+ printf("%s%3d", zerosyms ? "" : "\n", depth);
+ firstsym = zerosyms = false;
+ printf("%s%.*s%s",
+ symdepth ? " " : "",
+ (int)(cp-str), str,
+ symdepth ? "" : "\n");
/* we don't care about the value of the symbol */
return (0);
}
@@ -1153,6 +1184,8 @@ addsym(bool ignorethis, bool definethis, char *sym)
usage();
value[symind] = NULL;
}
+ debug("addsym %s=%s", symname[symind],
+ value[symind] ? value[symind] : "undef");
}
/*
diff --git a/usr.bin/unifdef/unifdefall.sh b/usr.bin/unifdef/unifdefall.sh
index 179fc93..c9a04cc 100644
--- a/usr.bin/unifdef/unifdefall.sh
+++ b/usr.bin/unifdef/unifdefall.sh
@@ -26,7 +26,6 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $dotat: unifdef/unifdefall.sh,v 1.27 2010/01/19 16:09:50 fanf2 Exp $
# $FreeBSD$
set -e
@@ -36,17 +35,21 @@ if [ ! -e "$unifdef" ]
then
unifdef=unifdef
fi
-# export to the final shell command
-export unifdef
+
+case "$@" in
+"-d "*) echo DEBUGGING 1>&2
+ debug=-d
+ shift
+esac
basename=$(basename "$0")
tmp=$(mktemp -d "${TMPDIR:-/tmp}/$basename.XXXXXXXXXX") || exit 2
-trap 'rm -r "$tmp" || exit 1' EXIT
+trap 'rm -r "$tmp" || exit 2' EXIT
export LC_ALL=C
# list of all controlling macros
-"$unifdef" -s "$@" | sort | uniq >"$tmp/ctrl"
+"$unifdef" $debug -s "$@" | sort | uniq >"$tmp/ctrl"
# list of all macro definitions
cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs"
# list of defined macro names
@@ -58,7 +61,7 @@ comm -12 "$tmp/ctrl" "$tmp/alldef" >"$tmp/def"
# and converts them to unifdef command-line arguments
sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
# create the final unifdef command
-{ echo '"$unifdef" -k \'
+{ echo "$unifdef" $debug -k '\'
# convert the controlling undefined macros to -U arguments
sed 's/.*/-U& \\/' <"$tmp/undef"
# convert the controlling defined macros to quoted -D arguments
@@ -66,5 +69,11 @@ sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
sed "s/'/'\\\\''/g;s/.*/'&' \\\\/"
echo '"$@"'
} >"$tmp/cmd"
+case $debug in
+-d) for i in ctrl hashdefs alldef undef def script cmd
+ do echo ==== $i
+ cat "$tmp/$i"
+ done 1>&2
+esac
# run the command we just created
sh "$tmp/cmd" "$@"
diff --git a/usr.bin/uniq/uniq.c b/usr.bin/uniq/uniq.c
index 2b11fe4..605bd00 100644
--- a/usr.bin/uniq/uniq.c
+++ b/usr.bin/uniq/uniq.c
@@ -53,6 +53,7 @@ static const char rcsid[] =
#include <limits.h>
#include <locale.h>
#include <stdint.h>
+#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -60,31 +61,26 @@ static const char rcsid[] =
#include <wchar.h>
#include <wctype.h>
-#define INITLINELEN (LINE_MAX + 1)
-#define MAXLINELEN ((SIZE_MAX / sizeof(wchar_t)) / 2)
-
-int cflag, dflag, uflag;
+int cflag, dflag, uflag, iflag;
int numchars, numfields, repeats;
FILE *file(const char *, const char *);
-wchar_t *getline(wchar_t *, size_t *, FILE *);
-void show(FILE *, wchar_t *);
+wchar_t *convert(const char *);
+int inlcmp(const char *, const char *);
+void show(FILE *, const char *);
wchar_t *skip(wchar_t *);
void obsolete(char *[]);
static void usage(void);
-int wcsicoll(wchar_t *, wchar_t *);
int
main (int argc, char *argv[])
{
- wchar_t *t1, *t2;
+ wchar_t *tprev, *tthis;
FILE *ifp, *ofp;
- int ch, b1;
- size_t prevbuflen, thisbuflen;
- wchar_t *prevline, *thisline;
- char *p;
+ int ch, comp;
+ size_t prevbuflen, thisbuflen, b1;
+ char *prevline, *thisline, *p;
const char *ifn;
- int iflag = 0, comp;
(void) setlocale(LC_ALL, "");
@@ -139,48 +135,48 @@ main (int argc, char *argv[])
if (argc > 1)
ofp = file(argv[1], "w");
- prevbuflen = INITLINELEN;
- thisbuflen = INITLINELEN;
- prevline = malloc(prevbuflen * sizeof(*prevline));
- thisline = malloc(thisbuflen * sizeof(*thisline));
- if (prevline == NULL || thisline == NULL)
- err(1, "malloc");
+ prevbuflen = thisbuflen = 0;
+ prevline = thisline = NULL;
- if ((prevline = getline(prevline, &prevbuflen, ifp)) == NULL) {
+ if (getline(&prevline, &prevbuflen, ifp) < 0) {
if (ferror(ifp))
err(1, "%s", ifn);
exit(0);
}
+ tprev = convert(prevline);
+
if (!cflag && uflag && dflag)
show(ofp, prevline);
- while ((thisline = getline(thisline, &thisbuflen, ifp)) != NULL) {
- /* If requested get the chosen fields + character offsets. */
- if (numfields || numchars) {
- t1 = skip(thisline);
- t2 = skip(prevline);
- } else {
- t1 = thisline;
- t2 = prevline;
- }
+ tthis = NULL;
+ while (getline(&thisline, &thisbuflen, ifp) >= 0) {
+ if (tthis != NULL)
+ free(tthis);
+ tthis = convert(thisline);
- /* If different, print; set previous to new value. */
- if (iflag)
- comp = wcsicoll(t1, t2);
+ if (tthis == NULL && tprev == NULL)
+ comp = inlcmp(thisline, prevline);
+ else if (tthis == NULL || tprev == NULL)
+ comp = 1;
else
- comp = wcscoll(t1, t2);
+ comp = wcscoll(tthis, tprev);
if (comp) {
+ /* If different, print; set previous to new value. */
if (cflag || !dflag || !uflag)
show(ofp, prevline);
- t1 = prevline;
+ p = prevline;
b1 = prevbuflen;
prevline = thisline;
prevbuflen = thisbuflen;
+ if (tprev != NULL)
+ free(tprev);
+ tprev = tthis;
if (!cflag && uflag && dflag)
show(ofp, prevline);
- thisline = t1;
+ thisline = p;
thisbuflen = b1;
+ tthis = NULL;
repeats = 0;
} else
++repeats;
@@ -193,28 +189,55 @@ main (int argc, char *argv[])
}
wchar_t *
-getline(wchar_t *buf, size_t *buflen, FILE *fp)
+convert(const char *str)
{
- size_t bufpos;
- wint_t ch;
-
- bufpos = 0;
- while ((ch = getwc(fp)) != WEOF && ch != '\n') {
- if (bufpos + 1 >= *buflen) {
- *buflen = *buflen * 2;
- if (*buflen > MAXLINELEN)
- errx(1,
- "Maximum line buffer length (%zu) exceeded",
- MAXLINELEN);
- buf = reallocf(buf, *buflen * sizeof(*buf));
- if (buf == NULL)
- err(1, "reallocf");
- }
- buf[bufpos++] = ch;
+ size_t n;
+ wchar_t *buf, *ret, *p;
+
+ if ((n = mbstowcs(NULL, str, 0)) == (size_t)-1)
+ return (NULL);
+ if (SIZE_MAX / sizeof(*buf) < n + 1)
+ errx(1, "conversion buffer length overflow");
+ if ((buf = malloc((n + 1) * sizeof(*buf))) == NULL)
+ err(1, "malloc");
+ if (mbstowcs(buf, str, n + 1) != n)
+ errx(1, "internal mbstowcs() error");
+ /* The last line may not end with \n. */
+ if (n > 0 && buf[n - 1] == L'\n')
+ buf[n - 1] = L'\0';
+
+ /* If requested get the chosen fields + character offsets. */
+ if (numfields || numchars) {
+ if ((ret = wcsdup(skip(buf))) == NULL)
+ err(1, "wcsdup");
+ free(buf);
+ } else
+ ret = buf;
+
+ if (iflag) {
+ for (p = ret; *p != L'\0'; p++)
+ *p = towlower(*p);
}
- buf[bufpos] = '\0';
- return (bufpos != 0 || ch == '\n' ? buf : NULL);
+ return (ret);
+}
+
+int
+inlcmp(const char *s1, const char *s2)
+{
+ int c1, c2;
+
+ while (*s1 == *s2++)
+ if (*s1++ == '\0')
+ return (0);
+ c1 = (unsigned char)*s1;
+ c2 = (unsigned char)*(s2 - 1);
+ /* The last line may not end with \n. */
+ if (c1 == '\n')
+ c1 = '\0';
+ if (c2 == '\n')
+ c2 = '\0';
+ return (c1 - c2);
}
/*
@@ -223,13 +246,13 @@ getline(wchar_t *buf, size_t *buflen, FILE *fp)
* of the line.
*/
void
-show(FILE *ofp, wchar_t *str)
+show(FILE *ofp, const char *str)
{
if (cflag)
- (void)fprintf(ofp, "%4d %ls\n", repeats + 1, str);
+ (void)fprintf(ofp, "%4d %s", repeats + 1, str);
if ((dflag && repeats) || (uflag && !repeats))
- (void)fprintf(ofp, "%ls\n", str);
+ (void)fprintf(ofp, "%s", str);
}
wchar_t *
@@ -237,13 +260,14 @@ skip(wchar_t *str)
{
int nchars, nfields;
- for (nfields = 0; *str != '\0' && nfields++ != numfields; ) {
+ for (nfields = 0; *str != L'\0' && nfields++ != numfields; ) {
while (iswblank(*str))
str++;
- while (*str != '\0' && !iswblank(*str))
+ while (*str != L'\0' && !iswblank(*str))
str++;
}
- for (nchars = numchars; nchars-- && *str; ++str);
+ for (nchars = numchars; nchars-- && *str != L'\0'; ++str)
+ ;
return(str);
}
@@ -293,52 +317,3 @@ usage(void)
"usage: uniq [-c | -d | -u] [-i] [-f fields] [-s chars] [input [output]]\n");
exit(1);
}
-
-static size_t wcsicoll_l1_buflen = 0, wcsicoll_l2_buflen = 0;
-static wchar_t *wcsicoll_l1_buf = NULL, *wcsicoll_l2_buf = NULL;
-
-int
-wcsicoll(wchar_t *s1, wchar_t *s2)
-{
- wchar_t *p;
- size_t l1, l2;
- size_t new_l1_buflen, new_l2_buflen;
-
- l1 = wcslen(s1) + 1;
- l2 = wcslen(s2) + 1;
- new_l1_buflen = wcsicoll_l1_buflen;
- new_l2_buflen = wcsicoll_l2_buflen;
- while (new_l1_buflen < l1) {
- if (new_l1_buflen == 0)
- new_l1_buflen = INITLINELEN;
- else
- new_l1_buflen *= 2;
- }
- while (new_l2_buflen < l2) {
- if (new_l2_buflen == 0)
- new_l2_buflen = INITLINELEN;
- else
- new_l2_buflen *= 2;
- }
- if (new_l1_buflen > wcsicoll_l1_buflen) {
- wcsicoll_l1_buf = reallocf(wcsicoll_l1_buf, new_l1_buflen * sizeof(*wcsicoll_l1_buf));
- if (wcsicoll_l1_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l1_buflen = new_l1_buflen;
- }
- if (new_l2_buflen > wcsicoll_l2_buflen) {
- wcsicoll_l2_buf = reallocf(wcsicoll_l2_buf, new_l2_buflen * sizeof(*wcsicoll_l2_buf));
- if (wcsicoll_l2_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l2_buflen = new_l2_buflen;
- }
-
- for (p = wcsicoll_l1_buf; *s1; s1++)
- *p++ = towlower(*s1);
- *p = '\0';
- for (p = wcsicoll_l2_buf; *s2; s2++)
- *p++ = towlower(*s2);
- *p = '\0';
-
- return (wcscoll(wcsicoll_l1_buf, wcsicoll_l2_buf));
-}
diff --git a/usr.bin/wtmpcvt/wtmpcvt.1 b/usr.bin/wtmpcvt/wtmpcvt.1
index fdc995b..50f89ee 100644
--- a/usr.bin/wtmpcvt/wtmpcvt.1
+++ b/usr.bin/wtmpcvt/wtmpcvt.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 14, 2010
-.Os
.Dt WTMPCVT 1
+.Os
.Sh NAME
.Nm wtmpcvt
.Nd convert wtmp files to the utmpx format
diff --git a/usr.bin/xlint/lint1/decl.c b/usr.bin/xlint/lint1/decl.c
index 69c7cda..41492cf 100644
--- a/usr.bin/xlint/lint1/decl.c
+++ b/usr.bin/xlint/lint1/decl.c
@@ -825,15 +825,15 @@ getbound(type_t *tp)
} else if (t == FUNC) {
/* compiler takes alignment of function */
error(14);
- a = ALIGN(1) * CHAR_BIT;
+ a = LINT_ALIGN(1) * CHAR_BIT;
} else {
if ((a = size(t)) == 0) {
a = CHAR_BIT;
- } else if (a > ALIGN(1) * CHAR_BIT) {
- a = ALIGN(1) * CHAR_BIT;
+ } else if (a > LINT_ALIGN(1) * CHAR_BIT) {
+ a = LINT_ALIGN(1) * CHAR_BIT;
}
}
- if (a < CHAR_BIT || a > ALIGN(1) * CHAR_BIT)
+ if (a < CHAR_BIT || a > LINT_ALIGN(1) * CHAR_BIT)
lerror("getbound() 1");
return (a);
}
diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h
index fe1a524..6cfcbb7 100644
--- a/usr.bin/xlint/lint1/lint1.h
+++ b/usr.bin/xlint/lint1/lint1.h
@@ -38,8 +38,8 @@ __FBSDID("$FreeBSD$");
#include "op.h"
/* XXX - works for most systems, but the whole ALIGN thing needs to go away */
-#ifndef ALIGN
-#define ALIGN(x) (((x) + 7) & ~7)
+#ifndef LINT_ALIGN
+#define LINT_ALIGN(x) (((x) + 15) & ~15)
#endif
/*
diff --git a/usr.bin/xlint/lint1/mem1.c b/usr.bin/xlint/lint1/mem1.c
index 24e911e..280a63c 100644
--- a/usr.bin/xlint/lint1/mem1.c
+++ b/usr.bin/xlint/lint1/mem1.c
@@ -203,7 +203,7 @@ xgetblk(mbl_t **mbp, size_t s)
void *p;
size_t t = 0;
- s = ALIGN(s);
+ s = LINT_ALIGN(s);
if ((mb = *mbp) == NULL || mb->nfree < s) {
if ((mb = frmblks) == NULL) {
if (s > mblklen) {
diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l
index ea5a2c5..05f4ed7 100644
--- a/usr.bin/xlint/lint1/scan.l
+++ b/usr.bin/xlint/lint1/scan.l
@@ -319,7 +319,7 @@ allocsb(void)
if ((sb = malloc(sizeof (sbuf_t))) == NULL)
nomem();
}
- (void)memset(sb, 0, sizeof (sb));
+ (void)memset(sb, 0, sizeof (*sb));
return (sb);
}
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index cdcaaf3..c47ef76 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -3,7 +3,6 @@
.include <bsd.own.mk>
-# XXX MISSING: mkproto
SUBDIR= ${_ac} \
${_accton} \
${_acpi} \
@@ -168,6 +167,7 @@ SUBDIR= ${_ac} \
${_sade} \
${_sendmail} \
service \
+ services_mkdb \
setfib \
setfmac \
setpmac \
@@ -302,7 +302,6 @@ _jls= jls
.endif
# XXX MK_SYSCONS
-# XXX is moused w/ usb useful?
.if ${MK_LEGACY_CONSOLE} != "no"
_kbdcontrol= kbdcontrol
_kbdmap= kbdmap
diff --git a/usr.sbin/ac/ac.c b/usr.sbin/ac/ac.c
index d6db2d8..c584cd4 100644
--- a/usr.sbin/ac/ac.c
+++ b/usr.sbin/ac/ac.c
@@ -583,10 +583,11 @@ ac(const char *file)
endutxent();
if (!(Flags & AC_W))
usht.ut_tv.tv_sec = time(NULL);
+ else
+ usht.ut_tv.tv_sec = ut_timecopy;;
usht.ut_type = SHUTDOWN_TIME;
if (Flags & AC_D) {
- ut_timecopy = usht.ut_tv.tv_sec;
ltm = localtime(&ut_timecopy);
if (day >= 0 && day != ltm->tm_yday) {
/*
diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile
index 5981f38..c2fe844 100644
--- a/usr.sbin/acpi/acpidb/Makefile
+++ b/usr.sbin/acpi/acpidb/Makefile
@@ -25,11 +25,11 @@ SRCS+= dsfield.c dsinit.c dsmethod.c dsmthdat.c dsobject.c \
dswstate.c
# interpreter/executer
-SRCS+= exconfig.c exconvrt.c excreate.c exdump.c exfield.c \
- exfldio.c exmisc.c exmutex.c exnames.c exoparg1.c \
- exoparg2.c exoparg3.c exoparg6.c exprep.c exregion.c \
- exresnte.c exresolv.c exresop.c exstore.c exstoren.c \
- exstorob.c exsystem.c exutils.c
+SRCS+= exconfig.c exconvrt.c excreate.c exdebug.c exdump.c \
+ exfield.c exfldio.c exmisc.c exmutex.c exnames.c \
+ exoparg1.c exoparg2.c exoparg3.c exoparg6.c exprep.c \
+ exregion.c exresnte.c exresolv.c exresop.c exstore.c \
+ exstoren.c exstorob.c exsystem.c exutils.c
# interpreter/parser
SRCS+= psargs.c psloop.c psopcode.c psparse.c psscope.c \
diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile
index 130c39e..ea7a325 100644
--- a/usr.sbin/acpi/iasl/Makefile
+++ b/usr.sbin/acpi/iasl/Makefile
@@ -13,9 +13,9 @@ SRCS+= aslanalyze.c aslcodegen.c aslcompile.c aslcompiler.y.h \
aslcompilerlex.l aslcompilerparse.y aslerror.c \
aslfiles.c aslfold.c asllength.c asllisting.c \
aslload.c asllookup.c aslmain.c aslmap.c aslopcodes.c \
- asloperands.c aslopt.c aslresource.c aslrestype1.c \
- aslrestype2.c aslstartup.c aslstubs.c asltransform.c \
- asltree.c aslutils.c
+ asloperands.c aslopt.c aslpredef.c aslresource.c \
+ aslrestype1.c aslrestype2.c aslstartup.c aslstubs.c \
+ asltransform.c asltree.c aslutils.c
# debugger
SRCS+= dbfileio.c
diff --git a/usr.sbin/asf/asf.8 b/usr.sbin/asf/asf.8
index 25b0308..92edb4b 100644
--- a/usr.sbin/asf/asf.8
+++ b/usr.sbin/asf/asf.8
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd December 20, 2006
-.Os
.Dt ASF 8
+.Os
.Sh NAME
.Nm asf
.Nd add symbol files
diff --git a/usr.sbin/bluetooth/bthidd/Makefile b/usr.sbin/bluetooth/bthidd/Makefile
index 128bd20..dd0754d 100644
--- a/usr.sbin/bluetooth/bthidd/Makefile
+++ b/usr.sbin/bluetooth/bthidd/Makefile
@@ -8,7 +8,6 @@ SRCS= bthidd.c client.c hid.c kbd.c lexer.l parser.y server.c \
session.c
CFLAGS+= -I${.CURDIR}
-WARNS?= 6
DEBUG_FLAGS= -g
DPADD= ${LIBBLUETOOTH} ${LIBUSBHID}
diff --git a/usr.sbin/bsnmpd/modules/Makefile.inc b/usr.sbin/bsnmpd/modules/Makefile.inc
index adf6d72..b5dad56 100644
--- a/usr.sbin/bsnmpd/modules/Makefile.inc
+++ b/usr.sbin/bsnmpd/modules/Makefile.inc
@@ -1,8 +1,9 @@
# $FreeBSD$
SHLIB_MAJOR= 6
-WARNS?= 6
MANFILTER= sed -e 's%@MODPATH@%${LIBDIR}/%g' \
-e 's%@DEFPATH@%${DEFSDIR}/%g' \
-e 's%@MIBSPATH@%${BMIBSDIR}/%g'
+
+.include "../Makefile.inc"
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt b/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt
index 72ebdb7..0b90bb2 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt
@@ -17,11 +17,13 @@ IMPORTS
FROM SNMPv2-SMI
TruthValue
FROM SNMPv2-TC
+ InetAddress, InetAddressType, InetAddressPrefixLength
+ FROM INET-ADDRESS-MIB
begemot
FROM BEGEMOT-MIB;
begemotPf MODULE-IDENTITY
- LAST-UPDATED "200501240000Z"
+ LAST-UPDATED "201003180000Z"
ORGANIZATION "NixSys BVBA"
CONTACT-INFO
" Philip Paeps
@@ -34,6 +36,19 @@ begemotPf MODULE-IDENTITY
E-Mail: philip@FreeBSD.org"
DESCRIPTION
"The Begemot MIB for the pf packet filter."
+ REVISION "201003180000Z"
+ DESCRIPTION
+ "Modified pfTablesAddrEntry to support IPv6
+ addresses - added pfTablesAddrNetType column
+ and modified type of pfTablesAddrNet to
+ InetAddress."
+ REVISION "200912050000Z"
+ DESCRIPTION
+ "Added support for retrieving counters of labeled
+ pf filter rules via pfLabelspfLabels subtree."
+ REVISION "200501240000Z"
+ DESCRIPTION
+ "Initial revision."
::= { begemot 200 }
@@ -51,6 +66,7 @@ pfLogInterface OBJECT IDENTIFIER ::= { begemotPfObjects 7 }
pfInterfaces OBJECT IDENTIFIER ::= { begemotPfObjects 8 }
pfTables OBJECT IDENTIFIER ::= { begemotPfObjects 9 }
pfAltq OBJECT IDENTIFIER ::= { begemotPfObjects 10 }
+pfLabels OBJECT IDENTIFIER ::= { begemotPfObjects 11 }
-- --------------------------------------------------------------------------
@@ -1017,8 +1033,9 @@ pfTablesAddrEntry OBJECT-TYPE
PfTablesAddrEntry ::= SEQUENCE {
pfTablesAddrIndex Integer32,
- pfTablesAddrNet IpAddress,
- pfTablesAddrMask Integer32,
+ pfTablesAddrNetType InetAddressType,
+ pfTablesAddrNet InetAddress,
+ pfTablesAddrPrefix InetAddressPrefixLength,
pfTablesAddrTZero TimeTicks,
pfTablesAddrBytesInPass Counter64,
pfTablesAddrBytesInBlock Counter64,
@@ -1038,21 +1055,29 @@ pfTablesAddrIndex OBJECT-TYPE
"A unique value, greater than zero, for each address."
::= { pfTablesAddrEntry 1 }
+pfTablesAddrNetType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The type of address in the corresponding pfTablesAddrNet object."
+ ::= { pfTablesAddrEntry 2 }
+
pfTablesAddrNet OBJECT-TYPE
- SYNTAX IpAddress
+ SYNTAX InetAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The IP address of this particular table entry."
- ::= { pfTablesAddrEntry 2 }
+ ::= { pfTablesAddrEntry 3 }
-pfTablesAddrMask OBJECT-TYPE
- SYNTAX Integer32 (0..32)
+pfTablesAddrPrefix OBJECT-TYPE
+ SYNTAX InetAddressPrefixLength
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The CIDR netmask of this particular table entry."
- ::= { pfTablesAddrEntry 3 }
+ ::= { pfTablesAddrEntry 4 }
pfTablesAddrTZero OBJECT-TYPE
SYNTAX TimeTicks
@@ -1063,7 +1088,7 @@ pfTablesAddrTZero OBJECT-TYPE
"The time passed since this entry's statistics were last
cleared, or the time passed since this entry was loaded
into the table, whichever is sooner."
- ::= { pfTablesAddrEntry 4 }
+ ::= { pfTablesAddrEntry 5 }
pfTablesAddrBytesInPass OBJECT-TYPE
SYNTAX Counter64
@@ -1071,7 +1096,7 @@ pfTablesAddrBytesInPass OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of inbound bytes passed as a result of this entry."
- ::= { pfTablesAddrEntry 5 }
+ ::= { pfTablesAddrEntry 6 }
pfTablesAddrBytesInBlock OBJECT-TYPE
SYNTAX Counter64
@@ -1079,7 +1104,7 @@ pfTablesAddrBytesInBlock OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of inbound bytes blocked as a result of this entry."
- ::= { pfTablesAddrEntry 6 }
+ ::= { pfTablesAddrEntry 7 }
pfTablesAddrBytesOutPass OBJECT-TYPE
SYNTAX Counter64
@@ -1087,7 +1112,7 @@ pfTablesAddrBytesOutPass OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of outbound bytes passed as a result of this entry."
- ::= { pfTablesAddrEntry 7 }
+ ::= { pfTablesAddrEntry 8 }
pfTablesAddrBytesOutBlock OBJECT-TYPE
SYNTAX Counter64
@@ -1095,7 +1120,7 @@ pfTablesAddrBytesOutBlock OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of outbound bytes blocked as a result of this entry."
- ::= { pfTablesAddrEntry 8 }
+ ::= { pfTablesAddrEntry 9 }
pfTablesAddrPktsInPass OBJECT-TYPE
SYNTAX Counter64
@@ -1103,7 +1128,7 @@ pfTablesAddrPktsInPass OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of inbound packets passed as a result of this entry."
- ::= { pfTablesAddrEntry 9 }
+ ::= { pfTablesAddrEntry 10 }
pfTablesAddrPktsInBlock OBJECT-TYPE
SYNTAX Counter64
@@ -1111,7 +1136,7 @@ pfTablesAddrPktsInBlock OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of inbound packets blocked as a result of this entry."
- ::= { pfTablesAddrEntry 10 }
+ ::= { pfTablesAddrEntry 11 }
pfTablesAddrPktsOutPass OBJECT-TYPE
SYNTAX Counter64
@@ -1119,7 +1144,7 @@ pfTablesAddrPktsOutPass OBJECT-TYPE
STATUS current
DESCRIPTION
"The number of outbound packets passed as a result of this entry."
- ::= { pfTablesAddrEntry 11 }
+ ::= { pfTablesAddrEntry 12 }
pfTablesAddrPktsOutBlock OBJECT-TYPE
SYNTAX Counter64
@@ -1128,7 +1153,7 @@ pfTablesAddrPktsOutBlock OBJECT-TYPE
DESCRIPTION
"The number of outbound packets blocked as a result of this
entry."
- ::= { pfTablesAddrEntry 12 }
+ ::= { pfTablesAddrEntry 13 }
-- --------------------------------------------------------------------------
@@ -1227,4 +1252,96 @@ pfAltqQueueLimit OBJECT-TYPE
"Maximum number of packets in the queue."
::= { pfAltqQueueEntry 7 }
+pfLabelsLblNumber OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of labeled filter rules on this system."
+ ::= { pfLabels 1 }
+
+pfLabelsLblTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF PfLabelsLblEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Table of filter rules, index on pfLabelsLblIndex."
+ ::= { pfLabels 2 }
+
+pfLabelsLblEntry OBJECT-TYPE
+ SYNTAX PfLabelsLblEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Any entry in the pfLabelsLblTable containing information
+ about a particular filter rule on the system."
+ INDEX { pfLabelsLblIndex }
+ ::= { pfLabelsLblTable 1 }
+
+PfLabelsLblEntry ::= SEQUENCE {
+ pfLabelsLblIndex Integer32,
+ pfLabelsLblName OCTET STRING,
+ pfLabelsLblEvals Counter64,
+ pfLabelsLblBytesIn Counter64,
+ pfLabelsLblBytesOut Counter64,
+ pfLabelsLblPktsIn Counter64,
+ pfLabelsLblPktsOut Counter64
+}
+
+pfLabelsLblIndex OBJECT-TYPE
+ SYNTAX Integer32 (1..2147483647)
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A unique value, greater than zero, for each label."
+ ::= { pfLabelsLblEntry 1 }
+
+pfLabelsLblName OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The name of the rule label."
+ ::= { pfLabelsLblEntry 2 }
+
+pfLabelsLblEvals OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of rule evaluations."
+ ::= { pfLabelsLblEntry 3 }
+
+pfLabelsLblBytesIn OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of incoming bytes matched by the rule."
+ ::= { pfLabelsLblEntry 4 }
+
+pfLabelsLblBytesOut OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of outgoing bytes matched by the rule."
+ ::= { pfLabelsLblEntry 5 }
+
+pfLabelsLblPktsIn OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of incoming packets matched by the rule."
+ ::= { pfLabelsLblEntry 6 }
+
+pfLabelsLblPktsOut OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of outgoing packets matched by the rule."
+ ::= { pfLabelsLblEntry 7 }
+
END
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile
index 92b0a4ba..6218932 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile
@@ -4,6 +4,7 @@
MOD= pf
SRCS= pf_snmp.c
+CFLAGS+= -DSNMPTREE_TYPES
XSYM= begemotPf
DEFS= ${MOD}_tree.def
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
index 4e554c0..c7178f3 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -85,6 +85,19 @@ static int pft_table_count;
#define PFT_TABLE_MAXAGE 5
+struct pfa_entry {
+ struct pfr_astats pfas;
+ u_int index;
+ TAILQ_ENTRY(pfa_entry) link;
+};
+TAILQ_HEAD(pfa_table, pfa_entry);
+
+static struct pfa_table pfa_table;
+static time_t pfa_table_age;
+static int pfa_table_count;
+
+#define PFA_TABLE_MAXAGE 5
+
struct pfq_entry {
struct pf_altq altq;
u_int index;
@@ -100,14 +113,34 @@ static int altq_enabled = 0;
#define PFQ_TABLE_MAXAGE 5
+struct pfl_entry {
+ char name[MAXPATHLEN + PF_RULE_LABEL_SIZE];
+ u_int64_t evals;
+ u_int64_t bytes[2];
+ u_int64_t pkts[2];
+ u_int index;
+ TAILQ_ENTRY(pfl_entry) link;
+};
+TAILQ_HEAD(pfl_table, pfl_entry);
+
+static struct pfl_table pfl_table;
+static time_t pfl_table_age;
+static int pfl_table_count;
+
+#define PFL_TABLE_MAXAGE 5
+
/* Forward declarations */
static int pfi_refresh(void);
static int pfq_refresh(void);
static int pfs_refresh(void);
static int pft_refresh(void);
+static int pfa_refresh(void);
+static int pfl_refresh(void);
static struct pfi_entry * pfi_table_find(u_int idx);
static struct pfq_entry * pfq_table_find(u_int idx);
static struct pft_entry * pft_table_find(u_int idx);
+static struct pfa_entry * pfa_table_find(u_int idx);
+static struct pfl_entry * pfl_table_find(u_int idx);
static int altq_is_enabled(int pfdevice);
@@ -516,6 +549,9 @@ pf_iftable(struct snmp_context __unused *ctx, struct snmp_value *val,
asn_subid_t which = val->var.subs[sub - 1];
struct pfi_entry *e = NULL;
+ if ((time(NULL) - pfi_table_age) > PFI_TABLE_MAXAGE)
+ pfi_refresh();
+
switch (op) {
case SNMP_OP_SET:
return (SNMP_ERR_NOT_WRITEABLE);
@@ -539,9 +575,6 @@ pf_iftable(struct snmp_context __unused *ctx, struct snmp_value *val,
abort();
}
- if ((time(NULL) - pfi_table_age) > PFI_TABLE_MAXAGE)
- pfi_refresh();
-
switch (which) {
case LEAF_pfInterfacesIfDescr:
return (string_get(val, e->pfi.pfik_name, -1));
@@ -666,6 +699,9 @@ pf_tbltable(struct snmp_context __unused *ctx, struct snmp_value *val,
asn_subid_t which = val->var.subs[sub - 1];
struct pft_entry *e = NULL;
+ if ((time(NULL) - pft_table_age) > PFT_TABLE_MAXAGE)
+ pft_refresh();
+
switch (op) {
case SNMP_OP_SET:
return (SNMP_ERR_NOT_WRITEABLE);
@@ -689,9 +725,6 @@ pf_tbltable(struct snmp_context __unused *ctx, struct snmp_value *val,
abort();
}
- if ((time(NULL) - pft_table_age) > PFT_TABLE_MAXAGE)
- pft_refresh();
-
switch (which) {
case LEAF_pfTablesTblDescr:
return (string_get(val, e->pft.pfrts_name, -1));
@@ -776,7 +809,98 @@ int
pf_tbladdr(struct snmp_context __unused *ctx, struct snmp_value __unused *val,
u_int __unused sub, u_int __unused vindex, enum snmp_op __unused op)
{
- return (SNMP_ERR_GENERR);
+ asn_subid_t which = val->var.subs[sub - 1];
+ struct pfa_entry *e = NULL;
+
+ if ((time(NULL) - pfa_table_age) > PFA_TABLE_MAXAGE)
+ pfa_refresh();
+
+ switch (op) {
+ case SNMP_OP_SET:
+ return (SNMP_ERR_NOT_WRITEABLE);
+ case SNMP_OP_GETNEXT:
+ if ((e = NEXT_OBJECT_INT(&pfa_table,
+ &val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ val->var.len = sub + 1;
+ val->var.subs[sub] = e->index;
+ break;
+ case SNMP_OP_GET:
+ if (val->var.len - sub != 1)
+ return (SNMP_ERR_NOSUCHNAME);
+ if ((e = pfa_table_find(val->var.subs[sub])) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_COMMIT:
+ case SNMP_OP_ROLLBACK:
+ default:
+ abort();
+ }
+
+ switch (which) {
+ case LEAF_pfTablesAddrNetType:
+ if (e->pfas.pfras_a.pfra_af == AF_INET)
+ val->v.integer = pfTablesAddrNetType_ipv4;
+ else if (e->pfas.pfras_a.pfra_af == AF_INET6)
+ val->v.integer = pfTablesAddrNetType_ipv6;
+ else
+ return (SNMP_ERR_GENERR);
+ break;
+ case LEAF_pfTablesAddrNet:
+ if (e->pfas.pfras_a.pfra_af == AF_INET) {
+ return (string_get(val,
+ (u_char *)&e->pfas.pfras_a.pfra_ip4addr, 4));
+ } else if (e->pfas.pfras_a.pfra_af == AF_INET6)
+ return (string_get(val,
+ (u_char *)&e->pfas.pfras_a.pfra_ip6addr, 16));
+ else
+ return (SNMP_ERR_GENERR);
+ break;
+ case LEAF_pfTablesAddrPrefix:
+ val->v.integer = (int32_t) e->pfas.pfras_a.pfra_net;
+ break;
+ case LEAF_pfTablesAddrTZero:
+ val->v.uint32 =
+ (time(NULL) - e->pfas.pfras_tzero) * 100;
+ break;
+ case LEAF_pfTablesAddrBytesInPass:
+ val->v.counter64 =
+ e->pfas.pfras_bytes[PFR_DIR_IN][PFR_OP_PASS];
+ break;
+ case LEAF_pfTablesAddrBytesInBlock:
+ val->v.counter64 =
+ e->pfas.pfras_bytes[PFR_DIR_IN][PFR_OP_BLOCK];
+ break;
+ case LEAF_pfTablesAddrBytesOutPass:
+ val->v.counter64 =
+ e->pfas.pfras_bytes[PFR_DIR_OUT][PFR_OP_PASS];
+ break;
+ case LEAF_pfTablesAddrBytesOutBlock:
+ val->v.counter64 =
+ e->pfas.pfras_bytes[PFR_DIR_OUT][PFR_OP_BLOCK];
+ break;
+ case LEAF_pfTablesAddrPktsInPass:
+ val->v.counter64 =
+ e->pfas.pfras_packets[PFR_DIR_IN][PFR_OP_PASS];
+ break;
+ case LEAF_pfTablesAddrPktsInBlock:
+ val->v.counter64 =
+ e->pfas.pfras_packets[PFR_DIR_IN][PFR_OP_BLOCK];
+ break;
+ case LEAF_pfTablesAddrPktsOutPass:
+ val->v.counter64 =
+ e->pfas.pfras_packets[PFR_DIR_OUT][PFR_OP_PASS];
+ break;
+ case LEAF_pfTablesAddrPktsOutBlock:
+ val->v.counter64 =
+ e->pfas.pfras_packets[PFR_DIR_OUT][PFR_OP_BLOCK];
+ break;
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+
+ return (SNMP_ERR_NOERROR);
}
int
@@ -785,9 +909,8 @@ pf_altq(struct snmp_context __unused *ctx, struct snmp_value *val,
{
asn_subid_t which = val->var.subs[sub - 1];
- if (!altq_enabled) {
- return (SNMP_ERR_NOERROR);
- }
+ if (!altq_enabled)
+ return (SNMP_ERR_NOSUCHNAME);
if (op == SNMP_OP_SET)
return (SNMP_ERR_NOT_WRITEABLE);
@@ -820,9 +943,11 @@ pf_altqq(struct snmp_context __unused *ctx, struct snmp_value *val,
asn_subid_t which = val->var.subs[sub - 1];
struct pfq_entry *e = NULL;
- if (!altq_enabled) {
- return (SNMP_ERR_NOERROR);
- }
+ if (!altq_enabled)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if ((time(NULL) - pfq_table_age) > PFQ_TABLE_MAXAGE)
+ pfq_refresh();
switch (op) {
case SNMP_OP_SET:
@@ -847,9 +972,6 @@ pf_altqq(struct snmp_context __unused *ctx, struct snmp_value *val,
abort();
}
- if ((time(NULL) - pfq_table_age) > PFQ_TABLE_MAXAGE)
- pfq_refresh();
-
switch (which) {
case LEAF_pfAltqQueueDescr:
return (string_get(val, e->altq.qname, -1));
@@ -873,7 +995,95 @@ pf_altqq(struct snmp_context __unused *ctx, struct snmp_value *val,
}
return (SNMP_ERR_NOERROR);
-}
+}
+
+int
+pf_labels(struct snmp_context __unused *ctx, struct snmp_value *val,
+ u_int sub, u_int __unused vindex, enum snmp_op op)
+{
+ asn_subid_t which = val->var.subs[sub - 1];
+
+ if (op == SNMP_OP_SET)
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ if (op == SNMP_OP_GET) {
+ if ((time(NULL) - pfl_table_age) > PFL_TABLE_MAXAGE)
+ if (pfl_refresh() == -1)
+ return (SNMP_ERR_GENERR);
+
+ switch (which) {
+ case LEAF_pfLabelsLblNumber:
+ val->v.uint32 = pfl_table_count;
+ break;
+
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+
+ return (SNMP_ERR_NOERROR);
+ }
+
+ abort();
+ return (SNMP_ERR_GENERR);
+}
+
+int
+pf_lbltable(struct snmp_context __unused *ctx, struct snmp_value *val,
+ u_int sub, u_int __unused vindex, enum snmp_op op)
+{
+ asn_subid_t which = val->var.subs[sub - 1];
+ struct pfl_entry *e = NULL;
+
+ if ((time(NULL) - pfl_table_age) > PFL_TABLE_MAXAGE)
+ pfl_refresh();
+
+ switch (op) {
+ case SNMP_OP_SET:
+ return (SNMP_ERR_NOT_WRITEABLE);
+ case SNMP_OP_GETNEXT:
+ if ((e = NEXT_OBJECT_INT(&pfl_table,
+ &val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ val->var.len = sub + 1;
+ val->var.subs[sub] = e->index;
+ break;
+ case SNMP_OP_GET:
+ if (val->var.len - sub != 1)
+ return (SNMP_ERR_NOSUCHNAME);
+ if ((e = pfl_table_find(val->var.subs[sub])) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_COMMIT:
+ case SNMP_OP_ROLLBACK:
+ default:
+ abort();
+ }
+
+ switch (which) {
+ case LEAF_pfLabelsLblName:
+ return (string_get(val, e->name, -1));
+ case LEAF_pfLabelsLblEvals:
+ val->v.counter64 = e->evals;
+ break;
+ case LEAF_pfLabelsLblBytesIn:
+ val->v.counter64 = e->bytes[IN];
+ break;
+ case LEAF_pfLabelsLblBytesOut:
+ val->v.counter64 = e->bytes[OUT];
+ break;
+ case LEAF_pfLabelsLblPktsIn:
+ val->v.counter64 = e->pkts[IN];
+ break;
+ case LEAF_pfLabelsLblPktsOut:
+ val->v.counter64 = e->pkts[OUT];
+ break;
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
static struct pfi_entry *
pfi_table_find(u_int idx)
@@ -890,6 +1100,7 @@ static struct pfq_entry *
pfq_table_find(u_int idx)
{
struct pfq_entry *e;
+
TAILQ_FOREACH(e, &pfq_table, link)
if (e->index == idx)
return (e);
@@ -907,6 +1118,29 @@ pft_table_find(u_int idx)
return (NULL);
}
+static struct pfa_entry *
+pfa_table_find(u_int idx)
+{
+ struct pfa_entry *e;
+
+ TAILQ_FOREACH(e, &pfa_table, link)
+ if (e->index == idx)
+ return (e);
+ return (NULL);
+}
+
+static struct pfl_entry *
+pfl_table_find(u_int idx)
+{
+ struct pfl_entry *e;
+
+ TAILQ_FOREACH(e, &pfl_table, link)
+ if (e->index == idx)
+ return (e);
+
+ return (NULL);
+}
+
static int
pfi_refresh(void)
{
@@ -1129,6 +1363,278 @@ err2:
return(-1);
}
+static int
+pfa_table_addrs(u_int sidx, struct pfr_table *pt)
+{
+ struct pfioc_table io;
+ struct pfr_astats *t = NULL;
+ struct pfa_entry *e;
+ int i, numaddrs = 1;
+
+ if (pt == NULL)
+ return (-1);
+
+ memset(&io, 0, sizeof(io));
+ strlcpy(io.pfrio_table.pfrt_name, pt->pfrt_name,
+ sizeof(io.pfrio_table.pfrt_name));
+
+ for (;;) {
+ t = reallocf(t, numaddrs * sizeof(struct pfr_astats));
+ if (t == NULL) {
+ syslog(LOG_ERR, "pfa_table_addrs(): reallocf(): %s",
+ strerror(errno));
+ numaddrs = -1;
+ goto error;
+ }
+
+ memset(t, 0, sizeof(*t));
+ io.pfrio_size = numaddrs;
+ io.pfrio_buffer = t;
+ io.pfrio_esize = sizeof(struct pfr_astats);
+
+ if (ioctl(dev, DIOCRGETASTATS, &io)) {
+ syslog(LOG_ERR, "pfa_table_addrs(): ioctl() on %s: %s",
+ pt->pfrt_name, strerror(errno));
+ numaddrs = -1;
+ break;
+ }
+
+ if (numaddrs >= io.pfrio_size)
+ break;
+
+ numaddrs = io.pfrio_size;
+ }
+
+ for (i = 0; i < numaddrs; i++) {
+ if ((t + i)->pfras_a.pfra_af != AF_INET &&
+ (t + i)->pfras_a.pfra_af != AF_INET6) {
+ numaddrs = i;
+ break;
+ }
+
+ e = (struct pfa_entry *)malloc(sizeof(struct pfa_entry));
+ if (e == NULL) {
+ syslog(LOG_ERR, "pfa_table_addrs(): malloc(): %s",
+ strerror(errno));
+ numaddrs = -1;
+ break;
+ }
+ e->index = sidx + i;
+ memcpy(&e->pfas, t + i, sizeof(struct pfr_astats));
+ TAILQ_INSERT_TAIL(&pfa_table, e, link);
+ }
+
+ free(t);
+error:
+ return (numaddrs);
+}
+
+static int
+pfa_refresh(void)
+{
+ struct pfioc_table io;
+ struct pfr_table *pt = NULL, *it = NULL;
+ struct pfa_entry *e;
+ int i, numtbls = 1, cidx, naddrs;
+
+ if (started && this_tick <= pf_tick)
+ return (0);
+
+ while (!TAILQ_EMPTY(&pfa_table)) {
+ e = TAILQ_FIRST(&pfa_table);
+ TAILQ_REMOVE(&pfa_table, e, link);
+ free(e);
+ }
+
+ memset(&io, 0, sizeof(io));
+ io.pfrio_esize = sizeof(struct pfr_table);
+
+ for (;;) {
+ pt = reallocf(pt, numtbls * sizeof(struct pfr_table));
+ if (pt == NULL) {
+ syslog(LOG_ERR, "pfa_refresh(): reallocf() %s",
+ strerror(errno));
+ return (-1);
+ }
+ memset(pt, 0, sizeof(*pt));
+ io.pfrio_size = numtbls;
+ io.pfrio_buffer = pt;
+
+ if (ioctl(dev, DIOCRGETTABLES, &io)) {
+ syslog(LOG_ERR, "pfa_refresh(): ioctl(): %s",
+ strerror(errno));
+ goto err2;
+ }
+
+ if (numtbls >= io.pfrio_size)
+ break;
+
+ numtbls = io.pfrio_size;
+ }
+
+ cidx = 1;
+
+ for (it = pt, i = 0; i < numtbls; it++, i++) {
+ /*
+ * Skip the table if not active - ioctl(DIOCRGETASTATS) will
+ * return ESRCH for this entry anyway.
+ */
+ if (!(it->pfrt_flags & PFR_TFLAG_ACTIVE))
+ continue;
+
+ if ((naddrs = pfa_table_addrs(cidx, it)) < 0)
+ goto err1;
+
+ cidx += naddrs;
+ }
+
+ pfa_table_age = time(NULL);
+ pfa_table_count = cidx;
+ pf_tick = this_tick;
+
+ free(pt);
+ return (0);
+err1:
+ while (!TAILQ_EMPTY(&pfa_table)) {
+ e = TAILQ_FIRST(&pfa_table);
+ TAILQ_REMOVE(&pfa_table, e, link);
+ free(e);
+ }
+
+err2:
+ free(pt);
+ return (-1);
+}
+
+static int
+pfl_scan_ruleset(const char *path)
+{
+ struct pfioc_rule pr;
+ struct pfl_entry *e;
+ u_int32_t nr, i;
+
+ bzero(&pr, sizeof(pr));
+ strlcpy(pr.anchor, path, sizeof(pr.anchor));
+ pr.rule.action = PF_PASS;
+ if (ioctl(dev, DIOCGETRULES, &pr)) {
+ syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULES): %s",
+ strerror(errno));
+ goto err;
+ }
+
+ for (nr = pr.nr, i = 0; i < nr; i++) {
+ pr.nr = i;
+ if (ioctl(dev, DIOCGETRULE, &pr)) {
+ syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULE):"
+ " %s", strerror(errno));
+ goto err;
+ }
+
+ if (pr.rule.label[0]) {
+ e = (struct pfl_entry *)malloc(sizeof(*e));
+ if (e == NULL)
+ goto err;
+
+ strlcpy(e->name, path, sizeof(e->name));
+ if (path[0])
+ strlcat(e->name, "/", sizeof(e->name));
+ strlcat(e->name, pr.rule.label, sizeof(e->name));
+
+ e->evals = pr.rule.evaluations;
+ e->bytes[IN] = pr.rule.bytes[IN];
+ e->bytes[OUT] = pr.rule.bytes[OUT];
+ e->pkts[IN] = pr.rule.packets[IN];
+ e->pkts[OUT] = pr.rule.packets[OUT];
+ e->index = ++pfl_table_count;
+
+ TAILQ_INSERT_TAIL(&pfl_table, e, link);
+ }
+ }
+
+ return (0);
+
+err:
+ return (-1);
+}
+
+static int
+pfl_walk_rulesets(const char *path)
+{
+ struct pfioc_ruleset prs;
+ char newpath[MAXPATHLEN];
+ u_int32_t nr, i;
+
+ if (pfl_scan_ruleset(path))
+ goto err;
+
+ bzero(&prs, sizeof(prs));
+ strlcpy(prs.path, path, sizeof(prs.path));
+ if (ioctl(dev, DIOCGETRULESETS, &prs)) {
+ syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESETS): %s",
+ strerror(errno));
+ goto err;
+ }
+
+ for (nr = prs.nr, i = 0; i < nr; i++) {
+ prs.nr = i;
+ if (ioctl(dev, DIOCGETRULESET, &prs)) {
+ syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESET):"
+ " %s", strerror(errno));
+ goto err;
+ }
+
+ if (strcmp(prs.name, PF_RESERVED_ANCHOR) == 0)
+ continue;
+
+ strlcpy(newpath, path, sizeof(newpath));
+ if (path[0])
+ strlcat(newpath, "/", sizeof(newpath));
+
+ strlcat(newpath, prs.name, sizeof(newpath));
+ if (pfl_walk_rulesets(newpath))
+ goto err;
+ }
+
+ return (0);
+
+err:
+ return (-1);
+}
+
+static int
+pfl_refresh(void)
+{
+ struct pfl_entry *e;
+
+ if (started && this_tick <= pf_tick)
+ return (0);
+
+ while (!TAILQ_EMPTY(&pfl_table)) {
+ e = TAILQ_FIRST(&pfl_table);
+ TAILQ_REMOVE(&pfl_table, e, link);
+ free(e);
+ }
+ pfl_table_count = 0;
+
+ if (pfl_walk_rulesets(""))
+ goto err;
+
+ pfl_table_age = time(NULL);
+ pf_tick = this_tick;
+
+ return (0);
+
+err:
+ while (!TAILQ_EMPTY(&pfl_table)) {
+ e = TAILQ_FIRST(&pfl_table);
+ TAILQ_REMOVE(&pfl_table, e, link);
+ free(e);
+ }
+ pfl_table_count = 0;
+
+ return (-1);
+}
+
/*
* check whether altq support is enabled in kernel
*/
@@ -1175,6 +1681,8 @@ pf_init(struct lmodule *mod, int __unused argc, char __unused *argv[])
TAILQ_INIT(&pfi_table);
TAILQ_INIT(&pfq_table);
TAILQ_INIT(&pft_table);
+ TAILQ_INIT(&pfa_table);
+ TAILQ_INIT(&pfl_table);
pfi_refresh();
if (altq_enabled) {
@@ -1183,6 +1691,8 @@ pf_init(struct lmodule *mod, int __unused argc, char __unused *argv[])
pfs_refresh();
pft_refresh();
+ pfa_refresh();
+ pfl_refresh();
started = 1;
@@ -1195,6 +1705,8 @@ pf_fini(void)
struct pfi_entry *i1, *i2;
struct pfq_entry *q1, *q2;
struct pft_entry *t1, *t2;
+ struct pfa_entry *a1, *a2;
+ struct pfl_entry *l1, *l2;
/* Empty the list of interfaces */
i1 = TAILQ_FIRST(&pfi_table);
@@ -1212,7 +1724,7 @@ pf_fini(void)
q1 = q2;
}
- /* And the list of tables */
+ /* List of tables */
t1 = TAILQ_FIRST(&pft_table);
while (t1 != NULL) {
t2 = TAILQ_NEXT(t1, link);
@@ -1220,6 +1732,22 @@ pf_fini(void)
t1 = t2;
}
+ /* List of table addresses */
+ a1 = TAILQ_FIRST(&pfa_table);
+ while (a1 != NULL) {
+ a2 = TAILQ_NEXT(a1, link);
+ free(a1);
+ a1 = a2;
+ }
+
+ /* And the list of labeled filter rules */
+ l1 = TAILQ_FIRST(&pfl_table);
+ while (l1 != NULL) {
+ l2 = TAILQ_NEXT(l1, link);
+ free(l1);
+ l1 = l2;
+ }
+
close(dev);
return (0);
}
@@ -1232,6 +1760,8 @@ pf_dump(void)
pfq_refresh();
}
pft_refresh();
+ pfa_refresh();
+ pfl_refresh();
syslog(LOG_ERR, "Dump: pfi_table_age = %jd",
(intmax_t)pfi_table_age);
@@ -1245,9 +1775,18 @@ pf_dump(void)
syslog(LOG_ERR, "Dump: pft_table_age = %jd",
(intmax_t)pft_table_age);
-
syslog(LOG_ERR, "Dump: pft_table_count = %d",
pft_table_count);
+
+ syslog(LOG_ERR, "Dump: pfa_table_age = %jd",
+ (intmax_t)pfa_table_age);
+ syslog(LOG_ERR, "Dump: pfa_table_count = %d",
+ pfa_table_count);
+
+ syslog(LOG_ERR, "Dump: pfl_table_age = %jd",
+ (intmax_t)pfl_table_age);
+ syslog(LOG_ERR, "Dump: pfl_table_count = %d",
+ pfl_table_count);
}
const struct snmp_module config = {
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def b/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def
index 003a3ec..7b791b3 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005 Philip Paeps <philip@FreeBSD.org>
+# Copyright (c) 2010 Philip Paeps <philip@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -34,9 +34,9 @@
(200 begemotPf
(1 begemotPfObjects
(1 pfStatus
- (1 pfStatusRunning INTEGER pf_status GET)
+ (1 pfStatusRunning ENUM ( 1 true 2 false ) pf_status GET)
(2 pfStatusRuntime TIMETICKS pf_status GET)
- (3 pfStatusDebug INTEGER pf_status GET)
+ (3 pfStatusDebug ENUM ( 0 none 1 urgent 2 misc 3 loud ) pf_status GET)
(4 pfStatusHostId OCTETSTRING pf_status GET)
)
(2 pfCounter
@@ -106,7 +106,7 @@
(1 pfInterfacesIfEntry : INTEGER32 pf_iftable
(1 pfInterfacesIfIndex INTEGER32)
(2 pfInterfacesIfDescr OCTETSTRING GET)
- (3 pfInterfacesIfType INTEGER GET)
+ (3 pfInterfacesIfType ENUM ( 0 group 1 instance 2 detached ) GET)
(4 pfInterfacesIfTZero TIMETICKS GET)
(5 pfInterfacesIfRefsState UNSIGNED32 GET)
(6 pfInterfacesIfRefsRule UNSIGNED32 GET)
@@ -158,17 +158,18 @@
(3 pfTablesAddrTable
(1 pfTablesAddrEntry : INTEGER32 pf_tbladdr
(1 pfTablesAddrIndex INTEGER32)
- (2 pfTablesAddrNet IPADDRESS GET)
- (3 pfTablesAddrMask INTEGER32 GET)
- (4 pfTablesAddrTZero TIMETICKS GET)
- (5 pfTablesAddrBytesInPass COUNTER64 GET)
- (6 pfTablesAddrBytesInBlock COUNTER64 GET)
- (7 pfTablesAddrBytesOutPass COUNTER64 GET)
- (8 pfTablesAddrBytesOutBlock COUNTER64 GET)
- (9 pfTablesAddrPktsInPass COUNTER64 GET)
- (10 pfTablesAddrPktsInBlock COUNTER64 GET)
- (11 pfTablesAddrPktsOutPass COUNTER64 GET)
- (12 pfTablesAddrPktsOutBlock COUNTER64 GET)
+ (2 pfTablesAddrNetType ENUM ( 0 unknown 1 ipv4 2 ipv6) GET)
+ (3 pfTablesAddrNet OCTETSTRING | InetAddress GET)
+ (4 pfTablesAddrPrefix UNSIGNED32 GET)
+ (5 pfTablesAddrTZero TIMETICKS GET)
+ (6 pfTablesAddrBytesInPass COUNTER64 GET)
+ (7 pfTablesAddrBytesInBlock COUNTER64 GET)
+ (8 pfTablesAddrBytesOutPass COUNTER64 GET)
+ (9 pfTablesAddrBytesOutBlock COUNTER64 GET)
+ (10 pfTablesAddrPktsInPass COUNTER64 GET)
+ (11 pfTablesAddrPktsInBlock COUNTER64 GET)
+ (12 pfTablesAddrPktsOutPass COUNTER64 GET)
+ (13 pfTablesAddrPktsOutBlock COUNTER64 GET)
)
)
)
@@ -179,13 +180,27 @@
(1 pfAltqQueueIndex INTEGER32)
(2 pfAltqQueueDescr OCTETSTRING GET)
(3 pfAltqQueueParent OCTETSTRING GET)
- (4 pfAltqQueueScheduler INTEGER GET)
+ (4 pfAltqQueueScheduler ENUM ( 1 cbq 8 hfsc 11 priq ) GET)
(5 pfAltqQueueBandwidth UNSIGNED32 GET)
(6 pfAltqQueuePriority INTEGER32 GET)
(7 pfAltqQueueLimit INTEGER32 GET)
)
)
)
+ (11 pfLabels
+ (1 pfLabelsLblNumber INTEGER32 pf_labels GET)
+ (2 pfLabelsLblTable
+ (1 pfLabelsLblEntry : INTEGER pf_lbltable
+ (1 pfLabelsLblIndex INTEGER)
+ (2 pfLabelsLblName OCTETSTRING GET)
+ (3 pfLabelsLblEvals COUNTER64 GET)
+ (4 pfLabelsLblBytesIn COUNTER64 GET)
+ (5 pfLabelsLblBytesOut COUNTER64 GET)
+ (6 pfLabelsLblPktsIn COUNTER64 GET)
+ (7 pfLabelsLblPktsOut COUNTER64 GET)
+ )
+ )
+ )
)
)
)
diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8
index 2501e72..a9c53e6 100644
--- a/usr.sbin/burncd/burncd.8
+++ b/usr.sbin/burncd/burncd.8
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd December 21, 2009
-.Os
.Dt BURNCD 8
+.Os
.Sh NAME
.Nm burncd
.Nd control the ATAPI CD-R/RW driver
diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h
index d55c96b..ec19986 100644
--- a/usr.sbin/config/config.h
+++ b/usr.sbin/config/config.h
@@ -129,6 +129,8 @@ SLIST_HEAD(opt_head, opt) opt, mkopt, rmopts;
struct opt_list {
char *o_name;
char *o_file;
+ int o_flags;
+#define OL_ALIAS 1
SLIST_ENTRY(opt_list) o_next;
};
diff --git a/usr.sbin/config/config.y b/usr.sbin/config/config.y
index 9425daf..19f2779 100644
--- a/usr.sbin/config/config.y
+++ b/usr.sbin/config/config.y
@@ -166,6 +166,8 @@ Config_spec:
CPU Save_id {
struct cputype *cp =
(struct cputype *)calloc(1, sizeof (struct cputype));
+ if (cp == NULL)
+ err(EXIT_FAILURE, "calloc");
cp->cpu_name = $2;
SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
} |
@@ -197,6 +199,8 @@ Config_spec:
struct hint *hint;
hint = (struct hint *)calloc(1, sizeof (struct hint));
+ if (hint == NULL)
+ err(EXIT_FAILURE, "calloc");
hint->hint_name = $2;
STAILQ_INSERT_TAIL(&hints, hint, hint_next);
hintmode = 1;
@@ -331,6 +335,8 @@ newfile(char *name)
struct files_name *nl;
nl = (struct files_name *) calloc(1, sizeof *nl);
+ if (nl == NULL)
+ err(EXIT_FAILURE, "calloc");
nl->f_name = name;
STAILQ_INSERT_TAIL(&fntab, nl, f_next);
}
@@ -364,6 +370,8 @@ newdev(char *name)
}
np = (struct device *) calloc(1, sizeof *np);
+ if (np == NULL)
+ err(EXIT_FAILURE, "calloc");
np->d_name = name;
STAILQ_INSERT_TAIL(&dtab, np, d_next);
}
@@ -422,6 +430,8 @@ newopt(struct opt_head *list, char *name, char *value, int append)
}
op = (struct opt *)calloc(1, sizeof (struct opt));
+ if (op == NULL)
+ err(EXIT_FAILURE, "calloc");
op->op_name = name;
op->op_ownfile = 0;
op->op_value = value;
diff --git a/usr.sbin/config/configvers.h b/usr.sbin/config/configvers.h
index 28451585..73310bd 100644
--- a/usr.sbin/config/configvers.h
+++ b/usr.sbin/config/configvers.h
@@ -49,5 +49,5 @@
*
* $FreeBSD$
*/
-#define CONFIGVERS 600007
+#define CONFIGVERS 600008
#define MAJOR_VERS(x) ((x) / 100000)
diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l
index c7845cb..4eb94da 100644
--- a/usr.sbin/config/lang.l
+++ b/usr.sbin/config/lang.l
@@ -33,6 +33,7 @@
#include <assert.h>
#include <ctype.h>
+#include <err.h>
#include <string.h>
#include "y.tab.h"
#include "config.h"
@@ -220,6 +221,8 @@ cfgfile_add(const char *fname)
struct cfgfile *cf;
cf = calloc(1, sizeof(*cf));
+ if (cf == NULL)
+ err(EXIT_FAILURE, "calloc");
assert(cf != NULL);
asprintf(&cf->cfg_path, "%s", fname);
STAILQ_INSERT_TAIL(&cfgfiles, cf, cfg_next);
diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
index 34806ab..2b5e055 100644
--- a/usr.sbin/config/main.c
+++ b/usr.sbin/config/main.c
@@ -120,7 +120,7 @@ main(int argc, char **argv)
if (*destdir == '\0')
strlcpy(destdir, optarg, sizeof(destdir));
else
- errx(2, "directory already set");
+ errx(EXIT_FAILURE, "directory already set");
break;
case 'g':
debugging++;
@@ -175,7 +175,7 @@ main(int argc, char **argv)
if (mkdir(p, 0777))
err(2, "%s", p);
} else if (!S_ISDIR(buf.st_mode))
- errx(2, "%s isn't a directory", p);
+ errx(EXIT_FAILURE, "%s isn't a directory", p);
SLIST_INIT(&cputype);
SLIST_INIT(&mkopt);
@@ -256,7 +256,7 @@ get_srcdir(void)
int i;
if (realpath("../..", srcdir) == NULL)
- errx(2, "Unable to find root of source tree");
+ err(EXIT_FAILURE, "Unable to find root of source tree");
if ((pwd = getenv("PWD")) != NULL && *pwd == '/' &&
(pwd = strdup(pwd)) != NULL) {
/* Remove the last two path components. */
@@ -513,7 +513,7 @@ configfile(void)
}
sbuf_finish(sb);
/*
- * We print first part of the tamplate, replace our tag with
+ * We print first part of the template, replace our tag with
* configuration files content and later continue writing our
* template.
*/
@@ -650,6 +650,8 @@ remember(const char *file)
}
}
hl = calloc(1, sizeof(*hl));
+ if (hl == NULL)
+ err(EXIT_FAILURE, "calloc");
hl->h_name = s;
hl->h_next = htab;
htab = hl;
@@ -671,19 +673,19 @@ kernconfdump(const char *file)
r = open(file, O_RDONLY);
if (r == -1)
- errx(EXIT_FAILURE, "Couldn't open file '%s'", file);
+ err(EXIT_FAILURE, "Couldn't open file '%s'", file);
error = fstat(r, &st);
if (error == -1)
- errx(EXIT_FAILURE, "fstat() failed");
+ err(EXIT_FAILURE, "fstat() failed");
if (S_ISDIR(st.st_mode))
errx(EXIT_FAILURE, "'%s' is a directory", file);
fp = fdopen(r, "r");
if (fp == NULL)
- errx(EXIT_FAILURE, "fdopen() failed");
+ err(EXIT_FAILURE, "fdopen() failed");
osz = 1024;
o = calloc(1, osz);
if (o == NULL)
- errx(EXIT_FAILURE, "Couldn't allocate memory");
+ err(EXIT_FAILURE, "Couldn't allocate memory");
/* ELF note section header. */
asprintf(&cmd, "/usr/bin/elfdump -c %s | grep -A 5 kern_conf"
"| tail -2 | cut -d ' ' -f 2 | paste - - -", file);
@@ -703,7 +705,7 @@ kernconfdump(const char *file)
"INCLUDE_CONFIG_FILE", file);
r = fseek(fp, off, SEEK_CUR);
if (r != 0)
- errx(EXIT_FAILURE, "fseek() failed");
+ err(EXIT_FAILURE, "fseek() failed");
for (i = 0; i < size - 1; i++) {
r = fgetc(fp);
if (r == EOF)
diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c
index a89db8e..7845089 100644
--- a/usr.sbin/config/mkmakefile.c
+++ b/usr.sbin/config/mkmakefile.c
@@ -98,6 +98,8 @@ new_fent(void)
struct file_list *fp;
fp = (struct file_list *) calloc(1, sizeof *fp);
+ if (fp == NULL)
+ err(EXIT_FAILURE, "calloc");
STAILQ_INSERT_TAIL(&ftab, fp, f_next);
return (fp);
}
@@ -739,7 +741,7 @@ do_rules(FILE *f)
printf("config: don't know rules for %s\n", np);
break;
}
- snprintf(cmd, sizeof(cmd), "${%s_%c%s}\n.if defined(NORMAL_CTFCONVERT) && !empty(NORMAL_CTFCONVERT)\n\t${NORMAL_CTFCONVERT}\n.endif", ftype,
+ snprintf(cmd, sizeof(cmd), "${%s_%c%s}\n\t@${NORMAL_CTFCONVERT}", ftype,
toupper(och),
ftp->f_flags & NOWERROR ? "_NOWERROR" : "");
compilewith = cmd;
diff --git a/usr.sbin/config/mkoptions.c b/usr.sbin/config/mkoptions.c
index c4bd624..1a6ccc8 100644
--- a/usr.sbin/config/mkoptions.c
+++ b/usr.sbin/config/mkoptions.c
@@ -70,6 +70,8 @@ options(void)
/* Fake the cpu types as options. */
SLIST_FOREACH(cp, &cputype, cpu_next) {
op = (struct opt *)calloc(1, sizeof(*op));
+ if (op == NULL)
+ err(EXIT_FAILURE, "calloc");
op->op_name = ns(cp->cpu_name);
SLIST_INSERT_HEAD(&opt, op, op_next);
}
@@ -84,12 +86,25 @@ options(void)
/* Fake MAXUSERS as an option. */
op = (struct opt *)calloc(1, sizeof(*op));
+ if (op == NULL)
+ err(EXIT_FAILURE, "calloc");
op->op_name = ns("MAXUSERS");
snprintf(buf, sizeof(buf), "%d", maxusers);
op->op_value = ns(buf);
SLIST_INSERT_HEAD(&opt, op, op_next);
read_options();
+ SLIST_FOREACH(op, &opt, op_next) {
+ SLIST_FOREACH(ol, &otab, o_next) {
+ if (eq(op->op_name, ol->o_name) &&
+ (ol->o_flags & OL_ALIAS)) {
+ printf("Mapping option %s to %s.\n",
+ op->op_name, ol->o_file);
+ op->op_name = ol->o_file;
+ break;
+ }
+ }
+ }
SLIST_FOREACH(ol, &otab, o_next)
do_option(ol->o_name);
SLIST_FOREACH(op, &opt, op_next) {
@@ -120,7 +135,6 @@ do_option(char *name)
int tidy;
file = tooption(name);
-
/*
* Check to see if the option was specified..
*/
@@ -199,6 +213,8 @@ do_option(char *name)
tidy++;
} else {
op = (struct opt *) calloc(1, sizeof *op);
+ if (op == NULL)
+ err(EXIT_FAILURE, "calloc");
op->op_name = inw;
op->op_value = invalue;
SLIST_INSERT_HEAD(&op_head, op, op_next);
@@ -225,6 +241,8 @@ do_option(char *name)
if (value && !seen) {
/* New option appears */
op = (struct opt *) calloc(1, sizeof *op);
+ if (op == NULL)
+ err(EXIT_FAILURE, "calloc");
op->op_name = ns(name);
op->op_value = value ? ns(value) : NULL;
SLIST_INSERT_HEAD(&op_head, op, op_next);
@@ -284,6 +302,7 @@ read_options(void)
struct opt_list *po;
int first = 1;
char genopt[MAXPATHLEN];
+ int flags = 0;
SLIST_INIT(&otab);
(void) snprintf(fname, sizeof(fname), "../../conf/options");
@@ -293,6 +312,7 @@ openit:
return;
}
next:
+ flags = 0;
wd = get_word(fp);
if (wd == (char *)EOF) {
(void) fclose(fp);
@@ -324,6 +344,18 @@ next:
(void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s));
val = genopt;
free(s);
+ } else if (eq(val, "=")) {
+ val = get_word(fp);
+ if (val == (char *)EOF) {
+ printf("%s: unexpected end of file\n", fname);
+ exit(1);
+ }
+ if (val == 0) {
+ printf("%s: Expected a right hand side at %s\n", fname,
+ this);
+ exit(1);
+ }
+ flags |= OL_ALIAS;
}
val = ns(val);
@@ -336,8 +368,11 @@ next:
}
po = (struct opt_list *) calloc(1, sizeof *po);
+ if (po == NULL)
+ err(EXIT_FAILURE, "calloc");
po->o_name = this;
po->o_file = val;
+ po->o_flags = flags;
SLIST_INSERT_HEAD(&otab, po, o_next);
goto next;
diff --git a/usr.sbin/ctm/ctm/ctm.1 b/usr.sbin/ctm/ctm/ctm.1
index 732b0b9..d5cc614 100644
--- a/usr.sbin/ctm/ctm/ctm.1
+++ b/usr.sbin/ctm/ctm/ctm.1
@@ -13,8 +13,8 @@
.\" $FreeBSD$
.\"
.Dd March 25, 1995
-.Os
.Dt CTM 1
+.Os
.Sh NAME
.Nm ctm
.Nd source code mirror program
diff --git a/usr.sbin/ctm/ctm/ctm.5 b/usr.sbin/ctm/ctm/ctm.5
index 678837e..a51c93b 100644
--- a/usr.sbin/ctm/ctm/ctm.5
+++ b/usr.sbin/ctm/ctm/ctm.5
@@ -13,8 +13,8 @@
.\" $FreeBSD$
.\"
.Dd March 25, 1995
-.Os
.Dt CTM 5
+.Os
.Sh NAME
.Nm ctm
.Nd source code mirror system
diff --git a/usr.sbin/devinfo/devinfo.8 b/usr.sbin/devinfo/devinfo.8
index 6c893dc..ecb3b01 100644
--- a/usr.sbin/devinfo/devinfo.8
+++ b/usr.sbin/devinfo/devinfo.8
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd November 28, 2005
-.Os
.Dt DEVINFO 8
+.Os
.Sh NAME
.Nm devinfo
.Nd print information about system device configuration
diff --git a/usr.sbin/fdformat/fdformat.1 b/usr.sbin/fdformat/fdformat.1
index 25891c0..596b09b 100644
--- a/usr.sbin/fdformat/fdformat.1
+++ b/usr.sbin/fdformat/fdformat.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 25, 2001
-.Os
.Dt FDFORMAT 1
+.Os
.Sh NAME
.Nm fdformat
.Nd format floppy disks
diff --git a/usr.sbin/fdread/fdread.1 b/usr.sbin/fdread/fdread.1
index 20a79fc..d29a4a4 100644
--- a/usr.sbin/fdread/fdread.1
+++ b/usr.sbin/fdread/fdread.1
@@ -27,8 +27,8 @@
.\"
.\"
.Dd May 14, 2001
-.Os
.Dt FDREAD 1
+.Os
.Sh NAME
.Nm fdread
.Nd read floppy disks
diff --git a/usr.sbin/fdwrite/fdwrite.1 b/usr.sbin/fdwrite/fdwrite.1
index 28df514..e847398 100644
--- a/usr.sbin/fdwrite/fdwrite.1
+++ b/usr.sbin/fdwrite/fdwrite.1
@@ -10,8 +10,8 @@
.\"
.\"
.Dd September 16, 1993
-.Os
.Dt FDWRITE 1
+.Os
.Sh NAME
.Nm fdwrite
.Nd format and write floppy disks
diff --git a/usr.sbin/fifolog/fifolog_create/fifolog.1 b/usr.sbin/fifolog/fifolog_create/fifolog.1
index 7db58e7..d0be0ce 100644
--- a/usr.sbin/fifolog/fifolog_create/fifolog.1
+++ b/usr.sbin/fifolog/fifolog_create/fifolog.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd February 9, 2008
-.Os
.Dt FIFOLOG 1
+.Os
.Sh NAME
.Nm fifolog_create , fifolog_writer , fifolog_reader
.Nd "initialize, write, seek and extract data from a fifolog"
diff --git a/usr.sbin/flowctl/flowctl.8 b/usr.sbin/flowctl/flowctl.8
index e72486b..75304c4 100644
--- a/usr.sbin/flowctl/flowctl.8
+++ b/usr.sbin/flowctl/flowctl.8
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2005
-.Os
.Dt FLOWCTL 8
+.Os
.Sh NAME
.Nm flowctl
.Nd
diff --git a/usr.sbin/freebsd-update/freebsd-update.8 b/usr.sbin/freebsd-update/freebsd-update.8
index 9c8120f..1d684b0 100644
--- a/usr.sbin/freebsd-update/freebsd-update.8
+++ b/usr.sbin/freebsd-update/freebsd-update.8
@@ -149,7 +149,7 @@ other than 3AM, to avoid overly imposing an uneven load
on the server(s) hosting the updates.
.It
In spite of its name,
-.Cm
+.Nm
IDS should not be relied upon as an "Intrusion Detection
System", since if the system has been tampered with
it cannot be trusted to operate correctly.
diff --git a/usr.sbin/fwcontrol/Makefile b/usr.sbin/fwcontrol/Makefile
index 9694d5e..10320d2 100644
--- a/usr.sbin/fwcontrol/Makefile
+++ b/usr.sbin/fwcontrol/Makefile
@@ -3,7 +3,7 @@
PROG= fwcontrol
SRCS= fwcontrol.c fwcrom.c fwdv.c fwmpegts.c
MAN= fwcontrol.8
-WARNS= 3
+WARNS?= 3
.PATH: ${.CURDIR}/../../sys/dev/firewire
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 77f1b95..85fe988 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -47,7 +47,6 @@
.Op Fl l u Ar username | Fl U Ar username
.Op Fl c | m
.Op Ar parameter=value ...
-.Br
.Nm
.Op Fl hi
.Op Fl n Ar jailname
@@ -55,7 +54,6 @@
.Op Fl s Ar securelevel
.Op Fl l u Ar username | Fl U Ar username
.Op Ar path hostname [ip[,..]] command ...
-.Br
.Nm
.Op Fl r Ar jail
.Sh DESCRIPTION
@@ -67,9 +65,7 @@ imprisoning the current process (and future descendants) inside it.
The options are as follows:
.Bl -tag -width indent
.It Fl d
-Allow making changes to a
-.Va
-dying jail.
+Allow making changes to a dying jail.
.It Fl h
Resolve the
.Va host.hostname
diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c
index 3f4800c..a3a23b7 100644
--- a/usr.sbin/jls/jls.c
+++ b/usr.sbin/jls/jls.c
@@ -355,7 +355,7 @@ print_jail(int pflags, int jflags)
count = params[7].jp_valuelen / sizeof(struct in6_addr);
for (ai = 0; ai < count; ai++)
if (inet_ntop(AF_INET6,
- &((struct in_addr *)params[7].jp_value)[ai],
+ &((struct in6_addr *)params[7].jp_value)[ai],
ipbuf, sizeof(ipbuf)) == NULL)
err(1, "inet_ntop");
else
diff --git a/usr.sbin/lastlogin/lastlogin.8 b/usr.sbin/lastlogin/lastlogin.8
index 4d07a2b..0630163 100644
--- a/usr.sbin/lastlogin/lastlogin.8
+++ b/usr.sbin/lastlogin/lastlogin.8
@@ -55,7 +55,7 @@ If more than one
is given, the session information for each user is printed in
the order given on the command line.
Otherwise, information
-for all users is printed, sorted by uid.
+for all users is printed, sorted by name.
.Pp
The
.Nm
diff --git a/usr.sbin/lastlogin/lastlogin.c b/usr.sbin/lastlogin/lastlogin.c
index a1b5b6e..4c08547 100644
--- a/usr.sbin/lastlogin/lastlogin.c
+++ b/usr.sbin/lastlogin/lastlogin.c
@@ -39,6 +39,7 @@ __RCSID("$NetBSD: lastlogin.c,v 1.4 1998/02/03 04:45:35 perry Exp $");
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utmpx.h>
@@ -47,11 +48,19 @@ __RCSID("$NetBSD: lastlogin.c,v 1.4 1998/02/03 04:45:35 perry Exp $");
static void output(struct utmpx *);
static void usage(void);
+static int
+utcmp(const void *u1, const void *u2)
+{
+
+ return (strcmp(((const struct utmpx *)u1)->ut_user,
+ ((const struct utmpx *)u2)->ut_user));
+}
+
int
main(int argc, char *argv[])
{
- int ch, i;
- struct utmpx *u;
+ int ch, i, ulistsize;
+ struct utmpx *u, *ulist;
while ((ch = getopt(argc, argv, "")) != -1) {
usage();
@@ -74,12 +83,24 @@ main(int argc, char *argv[])
else {
if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0)
errx(1, "failed to open lastlog database");
+ ulist = NULL;
+ ulistsize = 0;
while ((u = getutxent()) != NULL) {
if (u->ut_type != USER_PROCESS)
continue;
- output(u);
+ if ((ulistsize % 16) == 0) {
+ ulist = realloc(ulist,
+ (ulistsize + 16) * sizeof(struct utmpx));
+ if (ulist == NULL)
+ err(1, "malloc");
+ }
+ ulist[ulistsize++] = *u;
}
endutxent();
+
+ qsort(ulist, ulistsize, sizeof(struct utmpx), utcmp);
+ for (i = 0; i < ulistsize; i++)
+ output(&ulist[i]);
}
exit(0);
@@ -91,7 +112,7 @@ output(struct utmpx *u)
{
time_t t = u->ut_tv.tv_sec;
- printf("%-10s %-8s %-22s %s",
+ printf("%-10s %-8s %-22.22s %s",
u->ut_user, u->ut_line, u->ut_host, ctime(&t));
}
diff --git a/usr.sbin/mailwrapper/mailwrapper.8 b/usr.sbin/mailwrapper/mailwrapper.8
index 587826b..6e498f6 100644
--- a/usr.sbin/mailwrapper/mailwrapper.8
+++ b/usr.sbin/mailwrapper/mailwrapper.8
@@ -1,5 +1,5 @@
+.\" $OpenBSD: mailwrapper.8,v 1.10 2009/02/07 16:58:23 martynas Exp $
.\" $NetBSD: mailwrapper.8,v 1.11 2002/02/08 01:38:50 ross Exp $
-.\" $OpenBSD: mailwrapper.8,v 1.8 2003/06/12 12:59:51 jmc Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 1998
@@ -31,7 +31,6 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" The following requests are required for all man pages.
.Dd August 7, 2006
.Dt MAILWRAPPER 8
.Os
diff --git a/usr.sbin/mailwrapper/mailwrapper.c b/usr.sbin/mailwrapper/mailwrapper.c
index d696d25..1b52a64 100644
--- a/usr.sbin/mailwrapper/mailwrapper.c
+++ b/usr.sbin/mailwrapper/mailwrapper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mailwrapper.c,v 1.16 2004/07/06 03:38:14 millert Exp $ */
+/* $OpenBSD: mailwrapper.c,v 1.18 2007/11/06 14:39:19 otto Exp $ */
/* $NetBSD: mailwrapper.c,v 1.9 2003/03/09 08:10:43 mjl Exp $ */
/*
@@ -61,8 +61,8 @@ initarg(struct arglist *al)
{
al->argc = 0;
al->maxc = 10;
- if ((al->argv = malloc(al->maxc * sizeof(char *))) == NULL)
- err(EX_TEMPFAIL, "malloc");
+ if ((al->argv = calloc(al->maxc, sizeof(char *))) == NULL)
+ err(EX_TEMPFAIL, "calloc");
}
static void
@@ -126,7 +126,7 @@ main(int argc, char *argv[], char *envp[])
continue;
}
- if ((from = strsep(&cp, WS)) == NULL)
+ if ((from = strsep(&cp, WS)) == NULL || cp == NULL)
goto parse_error;
cp += strspn(cp, WS);
diff --git a/usr.sbin/makefs/ffs/ffs_bswap.c b/usr.sbin/makefs/ffs/ffs_bswap.c
index d560884..18ace03 100644
--- a/usr.sbin/makefs/ffs/ffs_bswap.c
+++ b/usr.sbin/makefs/ffs/ffs_bswap.c
@@ -136,8 +136,6 @@ ffs_dinode1_swap(struct ufs1_dinode *o, struct ufs1_dinode *n)
n->di_mode = bswap16(o->di_mode);
n->di_nlink = bswap16(o->di_nlink);
- n->di_u.oldids[0] = bswap16(o->di_u.oldids[0]);
- n->di_u.oldids[1] = bswap16(o->di_u.oldids[1]);
n->di_size = bswap64(o->di_size);
n->di_atime = bswap32(o->di_atime);
n->di_atimensec = bswap32(o->di_atimensec);
diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8
index a56897c..2715791 100644
--- a/usr.sbin/mergemaster/mergemaster.8
+++ b/usr.sbin/mergemaster/mergemaster.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 7, 2010
+.Dd March 13, 2010
.Dt MERGEMASTER 8
.Os
.Sh NAME
@@ -32,7 +32,8 @@
.Nd merge configuration files, et al during an upgrade
.Sh SYNOPSIS
.Nm
-.Op Fl scrvahipFCPU
+.Op Fl scrvhpCP
+.Op Fl a|iFU
.Op Fl m Ar /path/to/sources
.Op Fl t Ar /path/to/temp/root
.Op Fl d
@@ -168,7 +169,7 @@ and therefore can override both files.
When the comparison is done if there are any files remaining
in the temproot directory they will be listed, and if the
.Fl a
-option is not in use the user will be given the option of
+option is not in use the user will be given the option of
deleting the temproot directory.
If there are no files remaining in the temproot directory
it will be deleted.
@@ -206,9 +207,11 @@ If the
directory exists, it creates a new one in a previously
non-existent directory.
This option unsets the verbose flag,
-but other than
-.Fl U
-it is compatible with all other options.
+and is not compatible with
+.Fl i ,
+.Fl F ,
+or
+.Fl U .
Setting
.Fl a
makes
diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh
index 2fa9906..7f06968 100755
--- a/usr.sbin/mergemaster/mergemaster.sh
+++ b/usr.sbin/mergemaster/mergemaster.sh
@@ -15,7 +15,7 @@ PATH=/bin:/usr/bin:/usr/sbin
display_usage () {
VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
echo "mergemaster version ${VERSION_NUMBER}"
- echo 'Usage: mergemaster [-scrvahipFCPU]'
+ echo 'Usage: mergemaster [-scrvhpCP] [-a|[-iFU]]'
echo ' [-m /path] [-t /path] [-d] [-u N] [-w N] [-A arch] [-D /path]'
echo "Options:"
echo " -s Strict comparison (diff every pair of files)"
@@ -337,6 +337,18 @@ while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
esac
done
+if [ -n "$AUTO_RUN" ]; then
+ if [ -n "$FREEBSD_ID" -o -n "$AUTO_UPGRADE" -o -n "$AUTO_INSTALL" ]; then
+ echo ''
+ echo "*** You have included the -a option along with one or more options"
+ echo ' that indicate that you wish mergemaster to actually make updates'
+ echo ' (-F, -U, or -i), however these options are not compatible.'
+ echo ' Please read mergemaster(8) for more information.'
+ echo ''
+ exit 1
+ fi
+fi
+
# Assign the location of the mtree database
#
MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
diff --git a/usr.sbin/mount_nwfs/Makefile b/usr.sbin/mount_nwfs/Makefile
index 8fbb9a8..8f46581 100644
--- a/usr.sbin/mount_nwfs/Makefile
+++ b/usr.sbin/mount_nwfs/Makefile
@@ -6,7 +6,6 @@ MAN= mount_nwfs.8
MOUNT= ${.CURDIR}/../../sbin/mount
CFLAGS+= -DNWFS -I${MOUNT}
-WARNS?= 0
.PATH: ${MOUNT}
diff --git a/usr.sbin/mount_nwfs/mount_nwfs.c b/usr.sbin/mount_nwfs/mount_nwfs.c
index 98a5f8e..5f5f19a 100644
--- a/usr.sbin/mount_nwfs/mount_nwfs.c
+++ b/usr.sbin/mount_nwfs/mount_nwfs.c
@@ -62,16 +62,19 @@ static int parsercfile(struct ncp_conn_loginfo *li, struct nwfs_args *mdata);
static struct mntopt mopts[] = {
MOPT_STDOPTS,
- { NULL }
+ MOPT_END
};
-static int
-parsercfile(struct ncp_conn_loginfo *li, struct nwfs_args *mdata) {
+static int
+parsercfile(struct ncp_conn_loginfo *li __unused,
+ struct nwfs_args *mdata __unused)
+{
return 0;
}
int
-main(int argc, char *argv[]) {
+main(int argc, char *argv[])
+{
NWCONN_HANDLE connHandle;
struct nwfs_args mdata;
struct ncp_conn_loginfo li;
@@ -80,6 +83,7 @@ main(int argc, char *argv[]) {
struct tm *tm;
time_t ltime;
int opt, error, mntflags, nlsopt, wall_clock;
+ int uid_set, gid_set;
size_t len;
char *p, *p1, tmp[1024];
u_char *pv;
@@ -100,7 +104,7 @@ main(int argc, char *argv[]) {
mntflags = error = 0;
bzero(&mdata,sizeof(mdata));
- mdata.uid = mdata.gid = -1;
+ gid_set = uid_set = 0;
nlsopt = 0;
if (ncp_li_init(&li, argc, argv)) return 1;
@@ -182,6 +186,7 @@ main(int argc, char *argv[]) {
if (pwd == NULL)
errx(EX_NOUSER, "unknown user '%s'", optarg);
mdata.uid = pwd->pw_uid;
+ uid_set = 1;
break;
}
case 'g': {
@@ -192,6 +197,7 @@ main(int argc, char *argv[]) {
if (grp == NULL)
errx(EX_NOUSER, "unknown group '%s'", optarg);
mdata.gid = grp->gr_gid;
+ gid_set = 1;
break;
}
case 'd':
@@ -282,10 +288,10 @@ main(int argc, char *argv[]) {
if (ncp_geteinfo(mount_point, &einfo) == 0)
errx(EX_OSERR, "can't mount on %s twice", mount_point);
- if (mdata.uid == -1) {
+ if (uid_set == 0) {
mdata.uid = st.st_uid;
}
- if (mdata.gid == -1) {
+ if (gid_set == 0) {
mdata.gid = st.st_gid;
}
if (mdata.file_mode == 0 ) {
diff --git a/usr.sbin/mtest/mtest.8 b/usr.sbin/mtest/mtest.8
index b4d3514..9a961e0 100644
--- a/usr.sbin/mtest/mtest.8
+++ b/usr.sbin/mtest/mtest.8
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd April 29, 2009
-.Os
.Dt MTEST 8
+.Os
.Sh NAME
.Nm mtest
.Nd test multicast socket operations
diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c
index 44556d6..fdd3767 100644
--- a/usr.sbin/mtree/compare.c
+++ b/usr.sbin/mtree/compare.c
@@ -181,13 +181,13 @@ typeerr: LABEL;
* Catches nano-second differences, but doesn't display them.
*/
if ((s->flags & F_TIME) &&
- ((s->st_mtimespec.tv_sec != p->fts_statp->st_mtimespec.tv_sec) ||
- (s->st_mtimespec.tv_nsec != p->fts_statp->st_mtimespec.tv_nsec))) {
+ ((s->st_mtimespec.tv_sec != p->fts_statp->st_mtim.tv_sec) ||
+ (s->st_mtimespec.tv_nsec != p->fts_statp->st_mtim.tv_nsec))) {
LABEL;
(void)printf("%smodification time expected %.24s ",
tab, ctime(&s->st_mtimespec.tv_sec));
(void)printf("found %.24s",
- ctime(&p->fts_statp->st_mtimespec.tv_sec));
+ ctime(&p->fts_statp->st_mtim.tv_sec));
if (uflag) {
tv[0].tv_sec = s->st_mtimespec.tv_sec;
tv[0].tv_usec = s->st_mtimespec.tv_nsec / 1000;
diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c
index eee5037..da72fc6 100644
--- a/usr.sbin/mtree/create.c
+++ b/usr.sbin/mtree/create.c
@@ -213,8 +213,8 @@ statf(int indent, FTSENT *p)
(intmax_t)p->fts_statp->st_size);
if (keys & F_TIME)
output(indent, &offset, "time=%ld.%09ld",
- (long)p->fts_statp->st_mtimespec.tv_sec,
- p->fts_statp->st_mtimespec.tv_nsec);
+ (long)p->fts_statp->st_mtim.tv_sec,
+ p->fts_statp->st_mtim.tv_nsec);
if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
crc(fd, &val, &len))
diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8
index f0a93ed..e57b798 100644
--- a/usr.sbin/mtree/mtree.8
+++ b/usr.sbin/mtree/mtree.8
@@ -41,9 +41,6 @@
.Op Fl f Ar spec
.Ek
.Bk -words
-.Op Fl f Ar spec
-.Ek
-.Bk -words
.Op Fl K Ar keywords
.Ek
.Bk -words
@@ -119,7 +116,7 @@ Same as
except a status of 2 is returned if the file hierarchy did not match
the specification.
.It Fl w
-Make some errorconditions non-fatal warnings.
+Make some errors non-fatal warnings.
.It Fl x
Do not descend below mount points in the file hierarchy.
.It Fl f Ar file
@@ -260,10 +257,10 @@ socket
The default set of keywords are
.Cm flags ,
.Cm gid ,
+.Cm link ,
.Cm mode ,
.Cm nlink ,
.Cm size ,
-.Cm link ,
.Cm time ,
and
.Cm uid .
diff --git a/usr.sbin/periodic/periodic.8 b/usr.sbin/periodic/periodic.8
index 6335930..22a96a2 100644
--- a/usr.sbin/periodic/periodic.8
+++ b/usr.sbin/periodic/periodic.8
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd August 30, 2007
-.Os
.Dt PERIODIC 8
+.Os
.Sh NAME
.Nm periodic
.Nd run periodic system functions
diff --git a/usr.sbin/pkg_install/Makefile b/usr.sbin/pkg_install/Makefile
index bf1a213..0aa1941 100644
--- a/usr.sbin/pkg_install/Makefile
+++ b/usr.sbin/pkg_install/Makefile
@@ -2,11 +2,11 @@
.include <bsd.own.mk>
-SUBDIR= lib add create delete info updating version
+SUBDIR= add create delete info updating version
.include <bsd.subdir.mk>
-DATE!= grep PKG_INSTALL_VERSION ${.CURDIR}/lib/lib.h | sed 's|.*[ ]||'
+DATE!= grep PKG_INSTALL_VERSION ${.CURDIR}/Makefile.inc | sed 's|.*=||'
distfile: clean
@(cd ${.CURDIR}/..; \
diff --git a/usr.sbin/pkg_install/Makefile.inc b/usr.sbin/pkg_install/Makefile.inc
index 2fa20aa..5c9e266 100644
--- a/usr.sbin/pkg_install/Makefile.inc
+++ b/usr.sbin/pkg_install/Makefile.inc
@@ -2,16 +2,11 @@
.include <bsd.own.mk>
-LIBINSTALL= ${.OBJDIR}/../lib/libinstall.a
+CFLAGS+= -DPKG_INSTALL_VERSION=20100423
+CFLAGS+= -DYES_I_KNOW_THE_API_IS_RUBBISH_AND_IS_DOOMED_TO_CHANGE
-DPADD+= ${LIBUTIL}
-LDADD+= -lutil
-
-.if ${MK_OPENSSL} != "no" && \
- defined(LDADD) && ${LDADD:M-lfetch} != ""
-DPADD+= ${LIBSSL} ${LIBCRYPTO}
-LDADD+= -lssl -lcrypto
-.endif
+DPADD+= ${LIBPKG}
+LDADD+= -lpkg
# Inherit BINDIR from one level up.
.include "../Makefile.inc"
diff --git a/usr.sbin/pkg_install/add/Makefile b/usr.sbin/pkg_install/add/Makefile
index 89988e7..03a43f0 100644
--- a/usr.sbin/pkg_install/add/Makefile
+++ b/usr.sbin/pkg_install/add/Makefile
@@ -1,14 +1,11 @@
# $FreeBSD$
+.include <bsd.own.mk>
+
PROG= pkg_add
SRCS= main.c perform.c futil.c extract.c
-CFLAGS+= -I${.CURDIR}/../lib
-
WARNS?= 3
WFORMAT?= 1
-DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
-LDADD= ${LIBINSTALL} -lfetch -lmd
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/add/extract.c b/usr.sbin/pkg_install/add/extract.c
index 732a13f..6c2c4fc 100644
--- a/usr.sbin/pkg_install/add/extract.c
+++ b/usr.sbin/pkg_install/add/extract.c
@@ -23,7 +23,7 @@ __FBSDID("$FreeBSD$");
#include <ctype.h>
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "add.h"
diff --git a/usr.sbin/pkg_install/add/futil.c b/usr.sbin/pkg_install/add/futil.c
index e097140..c525320 100644
--- a/usr.sbin/pkg_install/add/futil.c
+++ b/usr.sbin/pkg_install/add/futil.c
@@ -22,7 +22,7 @@
__FBSDID("$FreeBSD$");
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "add.h"
/*
@@ -50,7 +50,7 @@ make_hierarchy(char *dir)
}
}
else {
- if (vsystem("/bin/mkdir %s", dir)) {
+ if (mkdir(dir, 0777) < 0) {
if (cp2)
*cp2 = '/';
return FAIL;
diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c
index d9b381b..762b61a 100644
--- a/usr.sbin/pkg_install/add/main.c
+++ b/usr.sbin/pkg_install/add/main.c
@@ -26,7 +26,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <getopt.h>
-#include "lib.h"
+#include <pkg.h>
#include "add.h"
char *Prefix = NULL;
@@ -128,6 +128,8 @@ main(int argc, char **argv)
static char temppackageroot[MAXPATHLEN];
static char pkgaddpath[MAXPATHLEN];
+ pkg_wrap(PKG_INSTALL_VERSION, argv);
+
if (*argv[0] != '/' && strchr(argv[0], '/') != NULL)
PkgAddCmd = realpath(argv[0], pkgaddpath);
else
diff --git a/usr.sbin/pkg_install/add/perform.c b/usr.sbin/pkg_install/add/perform.c
index 499d6c6..653a1d6 100644
--- a/usr.sbin/pkg_install/add/perform.c
+++ b/usr.sbin/pkg_install/add/perform.c
@@ -23,7 +23,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <paths.h>
-#include "lib.h"
+#include <pkg.h>
#include "add.h"
#include <libgen.h>
@@ -78,6 +78,7 @@ pkg_do(char *pkg)
char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX];
char *conflict[2];
char **matched;
+ int fd;
conflictsfound = 0;
code = 0;
@@ -408,8 +409,10 @@ pkg_do(char *pkg)
goto bomb;
/* Look for the requirements file */
- if (fexists(REQUIRE_FNAME)) {
- vsystem("/bin/chmod +x %s", REQUIRE_FNAME); /* be sure */
+ if ((fd = open(REQUIRE_FNAME, O_RDWR)) != -1) {
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
+ close(fd);
if (Verbose)
printf("Running requirements file first for %s..\n", Plist.name);
if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, Plist.name)) {
@@ -441,8 +444,10 @@ pkg_do(char *pkg)
}
/* If we're really installing, and have an installation file, run it */
- if (!NoInstall && fexists(pre_script)) {
- vsystem("/bin/chmod +x %s", pre_script); /* make sure */
+ if (!NoInstall && (fd = open(pre_script, O_RDWR)) != -1) {
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
+ close(fd);
if (Verbose)
printf("Running pre-install for %s..\n", Plist.name);
if (!Fake && vsystem("./%s %s %s", pre_script, Plist.name, pre_arg)) {
@@ -470,8 +475,10 @@ pkg_do(char *pkg)
}
/* Run the installation script one last time? */
- if (!NoInstall && fexists(post_script)) {
- vsystem("/bin/chmod +x %s", post_script); /* make sure */
+ if (!NoInstall && (fd = open(post_script, O_RDWR)) != -1) {
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
+ close(fd);
if (Verbose)
printf("Running post-install for %s..\n", Plist.name);
if (!Fake && vsystem("./%s %s %s", post_script, Plist.name, post_arg)) {
@@ -503,7 +510,10 @@ pkg_do(char *pkg)
goto success; /* close enough for government work */
}
/* Make sure pkg_info can read the entry */
- vsystem("/bin/chmod a+rx %s", LogDir);
+ fd = open(LogDir, O_RDWR);
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IRALL | S_IXALL); /* be sure, chmod a+rx */
+ close(fd);
move_file(".", DESC_FNAME, LogDir);
move_file(".", COMMENT_FNAME, LogDir);
if (fexists(INSTALL_FNAME))
diff --git a/usr.sbin/pkg_install/create/Makefile b/usr.sbin/pkg_install/create/Makefile
index 42718c6..3334037 100644
--- a/usr.sbin/pkg_install/create/Makefile
+++ b/usr.sbin/pkg_install/create/Makefile
@@ -3,12 +3,10 @@
PROG= pkg_create
SRCS= main.c perform.c pl.c
-CFLAGS+= -I${.CURDIR}/../lib
-
WARNS?= 3
WFORMAT?= 1
-DPADD= ${LIBINSTALL} ${LIBMD}
-LDADD= ${LIBINSTALL} -lmd
+DPADD= ${LIBMD}
+LDADD= -lmd
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c
index d85392d..e463d1f 100644
--- a/usr.sbin/pkg_install/create/main.c
+++ b/usr.sbin/pkg_install/create/main.c
@@ -15,7 +15,7 @@ __FBSDID("$FreeBSD$");
#include <getopt.h>
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "create.h"
match_t MatchType = MATCH_GLOB;
@@ -72,6 +72,8 @@ main(int argc, char **argv)
int ch;
char **pkgs, **start, *tmp;
+ pkg_wrap(PKG_INSTALL_VERSION, argv);
+
pkgs = start = argv;
while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1)
switch(ch) {
diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c
index e4f0d2e..0e14095 100644
--- a/usr.sbin/pkg_install/create/perform.c
+++ b/usr.sbin/pkg_install/create/perform.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include <pkg.h>
#include "create.h"
#include <err.h>
diff --git a/usr.sbin/pkg_install/create/pl.c b/usr.sbin/pkg_install/create/pl.c
index 18bbaf2..fe62d42 100644
--- a/usr.sbin/pkg_install/create/pl.c
+++ b/usr.sbin/pkg_install/create/pl.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include <pkg.h>
#include "create.h"
#include <errno.h>
#include <err.h>
diff --git a/usr.sbin/pkg_install/delete/Makefile b/usr.sbin/pkg_install/delete/Makefile
index c9a0fde..4f3b390 100644
--- a/usr.sbin/pkg_install/delete/Makefile
+++ b/usr.sbin/pkg_install/delete/Makefile
@@ -3,11 +3,6 @@
PROG= pkg_delete
SRCS= main.c perform.c
-CFLAGS+= -I${.CURDIR}/../lib
-
WFORMAT?= 1
-DPADD= ${LIBINSTALL} ${LIBMD}
-LDADD= ${LIBINSTALL} -lmd
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/delete/main.c b/usr.sbin/pkg_install/delete/main.c
index f09a432..7677fe9 100644
--- a/usr.sbin/pkg_install/delete/main.c
+++ b/usr.sbin/pkg_install/delete/main.c
@@ -27,7 +27,7 @@ __FBSDID("$FreeBSD$");
#include <getopt.h>
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "delete.h"
char *Prefix = NULL;
@@ -67,6 +67,8 @@ main(int argc, char **argv)
const char *tmp;
struct stat stat_s;
+ pkg_wrap(PKG_INSTALL_VERSION, argv);
+
pkgs = start = argv;
while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1)
switch(ch) {
diff --git a/usr.sbin/pkg_install/delete/perform.c b/usr.sbin/pkg_install/delete/perform.c
index 1519fd7..02f9717 100644
--- a/usr.sbin/pkg_install/delete/perform.c
+++ b/usr.sbin/pkg_install/delete/perform.c
@@ -22,7 +22,7 @@
__FBSDID("$FreeBSD$");
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "delete.h"
static int pkg_do(char *);
@@ -132,6 +132,8 @@ pkg_do(char *pkg)
const char *post_script, *pre_arg, *post_arg;
struct reqr_by_entry *rb_entry;
struct reqr_by_head *rb_list;
+ int fd;
+ struct stat sb;
if (!pkg || !(len = strlen(pkg)))
return 1;
@@ -221,10 +223,12 @@ pkg_do(char *pkg)
setenv(PKG_PREFIX_VNAME, p->name, 1);
- if (fexists(REQUIRE_FNAME)) {
+ if ((fd = open(REQUIRE_FNAME, O_RDWR)) != -1) {
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
+ close(fd);
if (Verbose)
printf("Executing 'require' script.\n");
- vsystem("/bin/chmod +x %s", REQUIRE_FNAME); /* be sure */
if (vsystem("./%s %s DEINSTALL", REQUIRE_FNAME, pkg)) {
warnx("package %s fails requirements %s", pkg,
Force ? "" : "- not deleted");
@@ -250,11 +254,13 @@ pkg_do(char *pkg)
post_script = pre_arg = post_arg = NULL;
}
- if (!NoDeInstall && pre_script != NULL && fexists(pre_script)) {
+ if (!NoDeInstall && pre_script != NULL && (fd = open(pre_script, O_RDWR)) != -1) {
if (Fake)
printf("Would execute de-install script at this point.\n");
else {
- vsystem("/bin/chmod +x %s", pre_script); /* make sure */
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
+ close(fd);
if (vsystem("./%s %s %s", pre_script, pkg, pre_arg)) {
warnx("deinstall script returned error status");
if (!Force)
@@ -326,11 +332,13 @@ pkg_do(char *pkg)
return 1;
}
- if (!NoDeInstall && post_script != NULL && fexists(post_script)) {
+ if (!NoDeInstall && post_script != NULL && (fd = open(post_script, O_RDWR)) != -1) {
if (Fake)
printf("Would execute post-deinstall script at this point.\n");
else {
- vsystem("/bin/chmod +x %s", post_script); /* make sure */
+ fstat(fd, &sb);
+ fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
+ close(fd);
if (vsystem("./%s %s %s", post_script, pkg, post_arg)) {
warnx("post-deinstall script returned error status");
if (!Force)
diff --git a/usr.sbin/pkg_install/info/Makefile b/usr.sbin/pkg_install/info/Makefile
index 485cb22..ba3909d 100644
--- a/usr.sbin/pkg_install/info/Makefile
+++ b/usr.sbin/pkg_install/info/Makefile
@@ -3,11 +3,9 @@
PROG= pkg_info
SRCS= main.c perform.c show.c
-CFLAGS+= -I${.CURDIR}/../lib
-
WFORMAT?= 1
-DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
-LDADD= ${LIBINSTALL} -lfetch -lmd
+DPADD= ${LIBMD}
+LDADD= -lmd
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h
index 46e29b1..68ec710 100644
--- a/usr.sbin/pkg_install/info/info.h
+++ b/usr.sbin/pkg_install/info/info.h
@@ -33,25 +33,26 @@
#define MAXNAMESIZE 20
#endif
-#define SHOW_COMMENT 0x00001
-#define SHOW_DESC 0x00002
-#define SHOW_PLIST 0x00004
-#define SHOW_INSTALL 0x00008
-#define SHOW_DEINSTALL 0x00010
-#define SHOW_REQUIRE 0x00020
-#define SHOW_PREFIX 0x00040
-#define SHOW_INDEX 0x00080
-#define SHOW_FILES 0x00100
-#define SHOW_DISPLAY 0x00200
-#define SHOW_REQBY 0x00400
-#define SHOW_MTREE 0x00800
-#define SHOW_SIZE 0x01000
-#define SHOW_ORIGIN 0x02000
-#define SHOW_CKSUM 0x04000
-#define SHOW_FMTREV 0x08000
-#define SHOW_PTREV 0x10000
-#define SHOW_DEPEND 0x20000
-#define SHOW_PKGNAME 0x40000
+#define SHOW_COMMENT 0x000001
+#define SHOW_DESC 0x000002
+#define SHOW_PLIST 0x000004
+#define SHOW_INSTALL 0x000008
+#define SHOW_DEINSTALL 0x000010
+#define SHOW_REQUIRE 0x000020
+#define SHOW_PREFIX 0x000040
+#define SHOW_INDEX 0x000080
+#define SHOW_FILES 0x000100
+#define SHOW_DISPLAY 0x000200
+#define SHOW_REQBY 0x000400
+#define SHOW_MTREE 0x000800
+#define SHOW_SIZE 0x001000
+#define SHOW_ORIGIN 0x002000
+#define SHOW_CKSUM 0x004000
+#define SHOW_FMTREV 0x008000
+#define SHOW_PTREV 0x010000
+#define SHOW_DEPEND 0x020000
+#define SHOW_PKGNAME 0x040000
+#define SHOW_LPREV 0x100000
struct which_entry {
TAILQ_ENTRY(which_entry) next;
diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c
index 2de638e..ca4e477 100644
--- a/usr.sbin/pkg_install/info/main.c
+++ b/usr.sbin/pkg_install/info/main.c
@@ -25,7 +25,7 @@ __FBSDID("$FreeBSD$");
#include <getopt.h>
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "info.h"
int Flags = 0;
@@ -68,6 +68,8 @@ main(int argc, char **argv)
char **pkgs, **start;
char *pkgs_split;
+ pkg_wrap(PKG_INSTALL_VERSION, argv);
+
whead = malloc(sizeof(struct which_head));
if (whead == NULL)
err(2, NULL);
@@ -225,7 +227,10 @@ main(int argc, char **argv)
}
case 'P':
- Flags = SHOW_PTREV;
+ if (Flags & SHOW_PTREV)
+ Flags |= SHOW_LPREV;
+ else
+ Flags = SHOW_PTREV;
break;
case 'h':
@@ -242,6 +247,11 @@ main(int argc, char **argv)
if (!Quiet)
printf("Package tools revision: ");
printf("%d\n", PKG_INSTALL_VERSION);
+ if (Flags & SHOW_LPREV) {
+ if (!Quiet)
+ printf("Libpkg revision: ");
+ printf("%d\n", libpkg_version());
+ }
exit(0);
}
diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c
index 09cad78..d295612 100644
--- a/usr.sbin/pkg_install/info/perform.c
+++ b/usr.sbin/pkg_install/info/perform.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include <pkg.h>
#include "info.h"
#include <err.h>
#include <signal.h>
diff --git a/usr.sbin/pkg_install/info/show.c b/usr.sbin/pkg_install/info/show.c
index c65c312..0d3b4ad 100644
--- a/usr.sbin/pkg_install/info/show.c
+++ b/usr.sbin/pkg_install/info/show.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include <pkg.h>
#include "info.h"
#include <err.h>
#include <stdlib.h>
diff --git a/usr.sbin/pkg_install/lib/Makefile b/usr.sbin/pkg_install/lib/Makefile
deleted file mode 100644
index 84a41b8..0000000
--- a/usr.sbin/pkg_install/lib/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# $FreeBSD$
-
-LIB= install
-INTERNALLIB=
-SRCS= file.c msg.c plist.c str.c exec.c global.c pen.c match.c \
- deps.c version.c pkgwrap.c url.c
-
-WARNS?= 3
-WFORMAT?= 1
-
-.include <bsd.lib.mk>
diff --git a/usr.sbin/pkg_install/lib/pkgwrap.c b/usr.sbin/pkg_install/lib/pkgwrap.c
deleted file mode 100644
index cbd15cd..0000000
--- a/usr.sbin/pkg_install/lib/pkgwrap.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * FreeBSD install - a package for the installation and maintenance
- * of non-core utilities.
- *
- * 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.
- *
- * Maxim Sobolev
- * 8 September 2002
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "lib.h"
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#undef main
-
-#define SEPARATORS " \t"
-
-extern char **environ;
-
-int
-main(int argc, char **argv)
-{
- FILE *f;
- char buffer[FILENAME_MAX], *cp, *verstr;
- int len;
-
- if (getenv("PKG_NOWRAP") != NULL)
- goto nowrap;
- f = fopen(PKG_WRAPCONF_FNAME, "r");
- if (f == NULL)
- goto nowrap;
- cp = fgets(buffer, 256, f);
- fclose(f);
- if (cp == NULL)
- goto nowrap;
- len = strlen(cp);
- if (cp[len - 1] == '\n')
- cp[len - 1] = '\0';
- while (strchr(SEPARATORS, *cp) != NULL)
- cp++;
- verstr = cp;
- cp = strpbrk(cp, SEPARATORS);
- if (cp == NULL)
- goto nowrap;
- *cp = '\0';
- for (cp = verstr; *cp != '\0'; cp++)
- if (isdigit(*cp) == 0)
- goto nowrap;
- if (atoi(verstr) < PKG_INSTALL_VERSION)
- goto nowrap;
- cp++;
- while (*cp != '\0' && strchr(SEPARATORS, *cp) != NULL)
- cp++;
- if (*cp == '\0')
- goto nowrap;
- bcopy(cp, buffer, strlen(cp) + 1);
- cp = strpbrk(buffer, SEPARATORS);
- if (cp != NULL)
- *cp = '\0';
- if (!isdir(buffer))
- goto nowrap;
- cp = strrchr(argv[0], '/');
- if (cp == NULL)
- cp = argv[0];
- else
- cp++;
- strlcat(buffer, "/", sizeof(buffer));
- strlcat(buffer, cp, sizeof(buffer));
- setenv("PKG_NOWRAP", "1", 1);
- execve(buffer, argv, environ);
-
-nowrap:
- unsetenv("PKG_NOWRAP");
- return(real_main(argc, argv));
-}
diff --git a/usr.sbin/pkg_install/updating/Makefile b/usr.sbin/pkg_install/updating/Makefile
index b0d3689..f5b7525 100644
--- a/usr.sbin/pkg_install/updating/Makefile
+++ b/usr.sbin/pkg_install/updating/Makefile
@@ -3,11 +3,6 @@
PROG= pkg_updating
SRCS= main.c
-CFLAGS+= -I${.CURDIR}/../lib
-
WFORMAT?= 1
-DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
-LDADD= ${LIBINSTALL} -lfetch -lmd
-
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/updating/main.c b/usr.sbin/pkg_install/updating/main.c
index 0ab2ec0..993ccd5 100644
--- a/usr.sbin/pkg_install/updating/main.c
+++ b/usr.sbin/pkg_install/updating/main.c
@@ -19,7 +19,7 @@ __FBSDID("$FreeBSD$");
#include <sysexits.h>
#include <getopt.h>
-#include "lib.h"
+#include <pkg.h>
#include "pathnames.h"
typedef struct installedport {
@@ -87,6 +87,8 @@ main(int argc, char *argv[])
DIR *dir;
FILE *fd;
+ pkg_wrap(PKG_INSTALL_VERSION, argv);
+
while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) {
switch (ch) {
case 'd':
diff --git a/usr.sbin/pkg_install/updating/pkg_updating.1 b/usr.sbin/pkg_install/updating/pkg_updating.1
index 0c35f9a..998b4c4 100644
--- a/usr.sbin/pkg_install/updating/pkg_updating.1
+++ b/usr.sbin/pkg_install/updating/pkg_updating.1
@@ -44,34 +44,25 @@ Defines a alternative location of the UPDATING
Print help message.
.El
.Sh EXAMPLES
-.Bl -tag -width indent
Shows all entries of all installed ports:
-.Pp
.Dl % pkg_updating
.Pp
Shows all entries of all installed ports since 2007-01-01:
-.Pp
.Dl % pkg_updating -d 20070101
.Pp
Shows all entries for all apache and mysql ports:
-.Pp
.Dl % pkg_updating apache mysql
.Pp
Shows all apache entries since 2006-01-01:
-.Pp
.Dl % pkg_updating -d 20060101 apache
.Pp
Defines that the UPDATING file is in /tmp and shows all entries of all
installed ports:
-.Pp
.Dl % pkg_updating -f /tmp/UPDATING
.Pp
Fetch UPDATING file from ftp mirror and show all entries of all
installed ports:
-.Pp
.Dl % pkg_updating -f ftp://ftp.freebsd.org/pub/FreeBSD/ports/packages/UPDATING
-.Pp
-.El
.Sh ENVIRONMENT
.Bl -tag -width PKG_DBDIR
.It Ev PKG_DBDIR
diff --git a/usr.sbin/pkg_install/version/Makefile b/usr.sbin/pkg_install/version/Makefile
index 3e1d7a5..fb079e3 100644
--- a/usr.sbin/pkg_install/version/Makefile
+++ b/usr.sbin/pkg_install/version/Makefile
@@ -3,13 +3,8 @@
PROG= pkg_version
SRCS= main.c perform.c
-CFLAGS+= -I${.CURDIR}/../lib
-
WFORMAT?= 1
-DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
-LDADD= ${LIBINSTALL} -lfetch -lmd
-
test:
sh ${.CURDIR}/test-pkg_version.sh
diff --git a/usr.sbin/pkg_install/version/main.c b/usr.sbin/pkg_install/version/main.c
index cad8583..4238497 100644
--- a/usr.sbin/pkg_install/version/main.c
+++ b/usr.sbin/pkg_install/version/main.c
@@ -25,7 +25,7 @@ __FBSDID("$FreeBSD$");
#include <getopt.h>
#include <err.h>
-#include "lib.h"
+#include <pkg.h>
#include "version.h"
char *LimitChars = NULL;
@@ -58,6 +58,8 @@ main(int argc, char **argv)
{
int ch, cmp = 0;
+ pkg_wrap(PKG_INSTALL_VERSION, argv);
+
if (argc == 4 && !strcmp(argv[1], "-t")) {
cmp = version_cmp(argv[2], argv[3]);
printf(cmp > 0 ? ">\n" : (cmp < 0 ? "<\n" : "=\n"));
diff --git a/usr.sbin/pkg_install/version/perform.c b/usr.sbin/pkg_install/version/perform.c
index e39adaf..79575a3 100644
--- a/usr.sbin/pkg_install/version/perform.c
+++ b/usr.sbin/pkg_install/version/perform.c
@@ -21,7 +21,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "lib.h"
+#include <pkg.h>
#include "version.h"
#include <err.h>
#include <fetch.h>
@@ -35,28 +35,41 @@ static int pkg_do(char *);
static void show_version(Package, const char *, const char *);
/*
- * This is the traditional pkg_perform, except that the argument is _not_
- * a list of packages. It is the index file from the command line.
+ * This is the traditional pkg_perform, except that the argument is _not_ a
+ * list of packages. It is the index file from the command line.
*
- * We loop over the installed packages, matching them with the -s flag
- * if needed and calling pkg_do(). Before hand we set up a few things,
- * and after we tear them down...
+ * We loop over the installed packages, matching them with the -s flag if
+ * needed and calling pkg_do(). Beforehand we set up a few things, and after
+ * we tear them down...
+ *
+ * Returns 0 on success, non-zero on failure, corresponding to the number of
+ * failed attempts to access the INDEX.
*/
int
pkg_perform(char **indexarg)
{
char **pkgs, *pat[2], **patterns;
struct index_entry *ie;
- int i, err_cnt = 0;
+ int i, err_cnt = 0, rel_major_ver;
int MatchType;
+ struct utsname u;
+
+ if (uname(&u) == -1) {
+ warn("%s(): failed to determine uname information", __func__);
+ return 1;
+ } else if ((rel_major_ver = (int) strtol(u.release, NULL, 10)) <= 0) {
+
+ }
+
/*
* Try to find and open the INDEX. We only check IndexFile != NULL
* later, if we actually need the INDEX.
*/
- if (*indexarg == NULL)
- snprintf(IndexPath, sizeof(IndexPath), "%s/%s", PORTS_DIR, INDEX_FNAME);
- else
+ if (*indexarg == NULL) {
+ snprintf(IndexPath, sizeof(IndexPath), "%s/INDEX-%d", PORTS_DIR,
+ rel_major_ver);
+ } else
strlcpy(IndexPath, *indexarg, sizeof(IndexPath));
if (isURL(IndexPath))
IndexFile = fetchGetURL(IndexPath, "");
diff --git a/usr.sbin/pmcannotate/pmcannotate.8 b/usr.sbin/pmcannotate/pmcannotate.8
index 38a413a..17c7c0e 100644
--- a/usr.sbin/pmcannotate/pmcannotate.8
+++ b/usr.sbin/pmcannotate/pmcannotate.8
@@ -28,8 +28,8 @@
.\" $FreeBSD$
.\"
.Dd November 20, 2008
-.Os
.Dt PMCANNOTATE 8
+.Os
.Sh NAME
.Nm pmcannotate
.Nd "sources printout with inlined profiling"
@@ -86,6 +86,7 @@ This directory specifies where
should look for the kernel and its modules.
The default is
.Pa /boot/kernel .
+.El
.Sh LIMITATIONS
As long as
.Nm
diff --git a/usr.sbin/pmccontrol/pmccontrol.8 b/usr.sbin/pmccontrol/pmccontrol.8
index e521a1f..f436753 100644
--- a/usr.sbin/pmccontrol/pmccontrol.8
+++ b/usr.sbin/pmccontrol/pmccontrol.8
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd November 9, 2008
-.Os
.Dt PMCCONTROL 8
+.Os
.Sh NAME
.Nm pmccontrol
.Nd "control hardware performance monitoring counters"
diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c
index d6f1a9d..d948b77 100644
--- a/usr.sbin/pmcstat/pmcpl_callgraph.c
+++ b/usr.sbin/pmcstat/pmcpl_callgraph.c
@@ -341,6 +341,7 @@ pmcpl_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
if (parent == NULL) {
pmcstat_stats.ps_callchain_dubious_frames++;
+ pmcr->pr_dubious_frames++;
return;
}
@@ -550,7 +551,7 @@ pmcstat_cgnode_topprint(struct pmcstat_cgnode *cg,
len = ns_len + vs_len + 1;
if (width - len < 0) {
- PMCSTAT_PRINTW("...");
+ PMCSTAT_PRINTW(" ...");
break;
}
width -= len;
@@ -580,6 +581,8 @@ pmcpl_cg_topdisplay(void)
struct pmcstat_pmcrecord *pmcr;
pmcr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
+ if (!pmcr)
+ err(EX_SOFTWARE, "ERROR: invalid pmcindex");
/*
* We pull out all callgraph nodes in the top-level hash table
diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c
index 498092d..f8ceece 100644
--- a/usr.sbin/pmcstat/pmcpl_calltree.c
+++ b/usr.sbin/pmcstat/pmcpl_calltree.c
@@ -366,7 +366,7 @@ pmcpl_ct_node_cleartag(void)
static int
pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
- struct pmcpl_ct_sample *rsamples, int x, int *y)
+ struct pmcpl_ct_sample *rsamples, int x, int *y, int maxy)
{
int i;
@@ -387,7 +387,7 @@ pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
if (ct->pct_narc == 0) {
pmcpl_ct_topscreen[x+1][*y] = NULL;
if (*y >= PMCPL_CT_MAXLINE ||
- *y >= pmcstat_displaywidth)
+ *y >= maxy)
return 1;
*y = *y + 1;
for (i=0; i < x; i++)
@@ -403,11 +403,15 @@ pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
&pmcin, pmcpl_ct_arc_compare);
for (i = 0; i < ct->pct_narc; i++) {
+ /* Skip this arc if there is no sample at all. */
+ if (PMCPL_CT_SAMPLE(pmcin,
+ &ct->pct_arc[i].pcta_samples) == 0)
+ continue;
if (PMCPL_CT_SAMPLEP(pmcin,
&ct->pct_arc[i].pcta_samples) > pmcstat_threshold) {
if (pmcpl_ct_node_dumptop(pmcin,
ct->pct_arc[i].pcta_child,
- rsamples, x+1, y))
+ rsamples, x+1, y, maxy))
return 1;
}
}
@@ -472,6 +476,9 @@ pmcpl_ct_node_printtop(struct pmcpl_ct_sample *rsamples, int pmcin, int maxy)
/* Check for line wrap. */
width += ns_len + is_len + vs_len + 1;
if (width >= pmcstat_displaywidth) {
+ maxy--;
+ if (y >= maxy)
+ break;
PMCSTAT_PRINTW("\n%*s", indentwidth, space);
width = indentwidth + ns_len + is_len + vs_len;
}
@@ -492,9 +499,10 @@ void
pmcpl_ct_topdisplay(void)
{
int i, x, y, pmcin;
- struct pmcpl_ct_sample rsamples;
+ struct pmcpl_ct_sample r, *rsamples;
- pmcpl_ct_samples_root(&rsamples);
+ rsamples = &r;
+ pmcpl_ct_samples_root(rsamples);
PMCSTAT_PRINTW("%-10.10s %s\n", "IMAGE", "CALLTREE");
@@ -513,16 +521,24 @@ pmcpl_ct_topdisplay(void)
x = y = 0;
for (i = 0; i < pmcpl_ct_root->pct_narc; i++) {
+ /* Skip this arc if there is no sample at all. */
+ if (PMCPL_CT_SAMPLE(pmcin,
+ &pmcpl_ct_root->pct_arc[i].pcta_samples) == 0)
+ continue;
+ if (PMCPL_CT_SAMPLEP(pmcin,
+ &pmcpl_ct_root->pct_arc[i].pcta_samples) <=
+ pmcstat_threshold)
+ continue;
if (pmcpl_ct_node_dumptop(pmcin,
pmcpl_ct_root->pct_arc[i].pcta_child,
- &rsamples, x, &y)) {
+ rsamples, x, &y, pmcstat_displayheight - 2)) {
break;
}
}
- pmcpl_ct_node_printtop(&rsamples, pmcin, y);
+ pmcpl_ct_node_printtop(rsamples, pmcin, y);
}
- pmcpl_ct_samples_free(&rsamples);
+ pmcpl_ct_samples_free(rsamples);
}
/*
@@ -690,6 +706,7 @@ pmcpl_ct_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
}
if (n-- == 0) {
pmcstat_stats.ps_callchain_dubious_frames++;
+ pmcr->pr_dubious_frames++;
return;
}
diff --git a/usr.sbin/pmcstat/pmcpl_gprof.c b/usr.sbin/pmcstat/pmcpl_gprof.c
index 9327eb9..2027ecf 100644
--- a/usr.sbin/pmcstat/pmcpl_gprof.c
+++ b/usr.sbin/pmcstat/pmcpl_gprof.c
@@ -171,6 +171,8 @@ pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image,
char fullpath[PATH_MAX];
pmcname = pmcstat_pmcid_to_name(pmcid);
+ if (!pmcname)
+ err(EX_SOFTWARE, "ERROR: cannot find pmcid");
(void) snprintf(fullpath, sizeof(fullpath),
"%s/%s/%s", samplesdir, pmcname,
diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8
index 309eb3e..b033357 100644
--- a/usr.sbin/pmcstat/pmcstat.8
+++ b/usr.sbin/pmcstat/pmcstat.8
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd September 19, 2008
-.Os
.Dt PMCSTAT 8
+.Os
.Sh NAME
.Nm pmcstat
.Nd "performance measurement with performance monitoring hardware"
diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
index a73d293..89ec8f0 100644
--- a/usr.sbin/pmcstat/pmcstat.c
+++ b/usr.sbin/pmcstat/pmcstat.c
@@ -1311,6 +1311,9 @@ main(int argc, char **argv)
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
clear();
+ /* Get terminal width / height with ncurses. */
+ getmaxyx(stdscr, pmcstat_displayheight, pmcstat_displaywidth);
+ pmcstat_displayheight--; pmcstat_displaywidth--;
atexit(pmcstat_topexit);
}
}
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
index 5811af3..6d8c57a 100644
--- a/usr.sbin/pmcstat/pmcstat_log.c
+++ b/usr.sbin/pmcstat/pmcstat_log.c
@@ -247,6 +247,7 @@ static int pmcstat_string_compute_hash(const char *_string);
static void pmcstat_string_initialize(void);
static int pmcstat_string_lookup_hash(pmcstat_interned_string _is);
static void pmcstat_string_shutdown(void);
+static void pmcstat_stats_reset(void);
/*
* A simple implementation of interned strings. Each interned string
@@ -274,6 +275,21 @@ int pmcstat_npmcs;
*/
int pmcstat_pause;
+static void
+pmcstat_stats_reset(void)
+{
+ struct pmcstat_pmcrecord *pr;
+
+ /* Flush PMCs stats. */
+ LIST_FOREACH(pr, &pmcstat_pmcs, pr_next) {
+ pr->pr_samples = 0;
+ pr->pr_dubious_frames = 0;
+ }
+
+ /* Flush global stats. */
+ bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+}
+
/*
* Compute a 'hash' value for a string.
*/
@@ -1009,6 +1025,8 @@ pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps)
pr->pr_pmcid = pmcid;
pr->pr_pmcname = ps;
pr->pr_pmcin = pmcstat_npmcs++;
+ pr->pr_samples = 0;
+ pr->pr_dubious_frames = 0;
pr->pr_merge = prm == NULL ? pr : prm;
LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
@@ -1032,7 +1050,6 @@ pmcstat_pmcid_to_name(pmc_id_t pmcid)
if (pr->pr_pmcid == pmcid)
return (pmcstat_string_unintern(pr->pr_pmcname));
- err(EX_SOFTWARE, "ERROR: cannot find pmcid");
return NULL;
}
@@ -1049,7 +1066,6 @@ pmcstat_pmcindex_to_name(int pmcin)
if (pr->pr_pmcin == pmcin)
return pmcstat_string_unintern(pr->pr_pmcname);
- err(EX_SOFTWARE, "ERROR: cannot find pmcid name");
return NULL;
}
@@ -1066,7 +1082,6 @@ pmcstat_pmcindex_to_pmcr(int pmcin)
if (pr->pr_pmcin == pmcin)
return pr;
- err(EX_SOFTWARE, "ERROR: invalid pmcindex");
return NULL;
}
@@ -1388,6 +1403,7 @@ pmcstat_analyze_log(void)
/* Get PMC record. */
pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_s.pl_pmcid);
assert(pmcr != NULL);
+ pmcr->pr_samples++;
/*
* Call the plugins processing
@@ -1421,6 +1437,7 @@ pmcstat_analyze_log(void)
/* Get PMC record. */
pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_cc.pl_pmcid);
assert(pmcr != NULL);
+ pmcr->pr_samples++;
/*
* Call the plugins processing
@@ -1670,10 +1687,8 @@ pmcstat_print_log(void)
int
pmcstat_close_log(void)
{
- if (pmc_flush_logfile() < 0 ||
- pmc_configure_logfile(-1) < 0)
+ if (pmc_flush_logfile() < 0)
err(EX_OSERR, "ERROR: logging failed");
- args.pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
return (args.pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
PMCSTAT_FINISHED);
}
@@ -1790,28 +1805,46 @@ pmcstat_process_log(void)
static void
pmcstat_refresh_top(void)
{
+ int v_attrs;
+ float v;
char pmcname[40];
+ struct pmcstat_pmcrecord *pmcpr;
/* If in pause mode do not refresh display. */
if (pmcstat_pause)
return;
+ /* Wait until PMC pop in the log. */
+ pmcpr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
+ if (pmcpr == NULL)
+ return;
+
/* Format PMC name. */
if (pmcstat_mergepmc)
snprintf(pmcname, sizeof(pmcname), "[%s]",
- pmcstat_pmcindex_to_name(pmcstat_pmcinfilter));
+ pmcstat_string_unintern(pmcpr->pr_pmcname));
else
snprintf(pmcname, sizeof(pmcname), "%s.%d",
- pmcstat_pmcindex_to_name(pmcstat_pmcinfilter),
+ pmcstat_string_unintern(pmcpr->pr_pmcname),
pmcstat_pmcinfilter);
+ /* Format samples count. */
+ if (pmcstat_stats.ps_samples_total > 0)
+ v = (pmcpr->pr_samples * 100.0) /
+ pmcstat_stats.ps_samples_total;
+ else
+ v = 0.;
+ v_attrs = PMCSTAT_ATTRPERCENT(v);
+
PMCSTAT_PRINTBEGIN();
- PMCSTAT_PRINTW("PMC: %s Samples: %u processed, %u invalid\n\n",
+ PMCSTAT_PRINTW("PMC: %s Samples: %u ",
pmcname,
- pmcstat_stats.ps_samples_total,
- pmcstat_stats.ps_samples_unknown_offset +
- pmcstat_stats.ps_samples_indeterminable +
- pmcstat_stats.ps_callchain_dubious_frames);
+ pmcpr->pr_samples);
+ PMCSTAT_ATTRON(v_attrs);
+ PMCSTAT_PRINTW("(%.1f%%) ", v);
+ PMCSTAT_ATTROFF(v_attrs);
+ PMCSTAT_PRINTW(", %u unresolved\n\n",
+ pmcpr->pr_dubious_frames);
if (plugins[args.pa_plugin].pl_topdisplay != NULL)
plugins[args.pa_plugin].pl_topdisplay();
PMCSTAT_PRINTEND();
@@ -1878,7 +1911,7 @@ pmcstat_keypress_log(void)
*/
if (plugins[args.pa_plugin].pl_shutdown != NULL)
plugins[args.pa_plugin].pl_shutdown(NULL);
- bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+ pmcstat_stats_reset();
if (plugins[args.pa_plugin].pl_init != NULL)
plugins[args.pa_plugin].pl_init();
@@ -1899,7 +1932,7 @@ pmcstat_keypress_log(void)
} while (plugins[args.pa_plugin].pl_topdisplay == NULL);
/* Open new plugin. */
- bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+ pmcstat_stats_reset();
if (plugins[args.pa_plugin].pl_init != NULL)
plugins[args.pa_plugin].pl_init();
wprintw(w, "switching to plugin %s",
@@ -1948,7 +1981,7 @@ pmcstat_display_log(void)
if (args.pa_topmode == PMCSTAT_TOP_DELTA) {
if (plugins[args.pa_plugin].pl_shutdown != NULL)
plugins[args.pa_plugin].pl_shutdown(NULL);
- bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
+ pmcstat_stats_reset();
if (plugins[args.pa_plugin].pl_init != NULL)
plugins[args.pa_plugin].pl_init();
}
diff --git a/usr.sbin/pmcstat/pmcstat_log.h b/usr.sbin/pmcstat/pmcstat_log.h
index de92649..8936fad 100644
--- a/usr.sbin/pmcstat/pmcstat_log.h
+++ b/usr.sbin/pmcstat/pmcstat_log.h
@@ -146,6 +146,8 @@ struct pmcstat_pmcrecord {
pmc_id_t pr_pmcid;
int pr_pmcin;
pmcstat_interned_string pr_pmcname;
+ int pr_samples;
+ int pr_dubious_frames;
struct pmcstat_pmcrecord *pr_merge;
};
extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
diff --git a/usr.sbin/powerd/powerd.8 b/usr.sbin/powerd/powerd.8
index 5808862..2d6acff 100644
--- a/usr.sbin/powerd/powerd.8
+++ b/usr.sbin/powerd/powerd.8
@@ -58,7 +58,7 @@ the system appears idle and increasing it when the system is busy.
It offers a good balance between a small performance loss for greatly
increased power savings.
Hiadaptive mode is like adaptive mode, but tuned for systems where
-performance and interactivity are more important then power consumption.
+performance and interactivity are more important than power consumption.
It increases frequency faster, reduces the frequency less aggressively and
will maintain full frequency for longer.
The default mode is adaptive for battery power and hiadaptive for the rest.
diff --git a/usr.sbin/ppp/arp.c b/usr.sbin/ppp/arp.c
index 02dce51..e67f89b 100644
--- a/usr.sbin/ppp/arp.c
+++ b/usr.sbin/ppp/arp.c
@@ -119,7 +119,7 @@ arp_ProxySub(struct bundle *bundle, struct in_addr addr, int add)
return 0;
}
arpmsg.hdr.rtm_type = add ? RTM_ADD : RTM_DELETE;
- arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;
+ arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC | RTF_LLDATA;
arpmsg.hdr.rtm_version = RTM_VERSION;
arpmsg.hdr.rtm_seq = ++bundle->routing_seq;
arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
diff --git a/usr.sbin/pppctl/pppctl.8 b/usr.sbin/pppctl/pppctl.8
index 245690f..431b7d7 100644
--- a/usr.sbin/pppctl/pppctl.8
+++ b/usr.sbin/pppctl/pppctl.8
@@ -1,7 +1,7 @@
.\" $FreeBSD$
.Dd June 26, 1997
-.Os
.Dt PPPCTL 8
+.Os
.Sh NAME
.Nm pppctl
.Nd PPP control program
diff --git a/usr.sbin/sade/disks.c b/usr.sbin/sade/disks.c
index b802e12..3158ff3 100644
--- a/usr.sbin/sade/disks.c
+++ b/usr.sbin/sade/disks.c
@@ -202,10 +202,9 @@ static void
print_command_summary(void)
{
mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
- mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice F = `DD' mode");
- mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
- mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
- mvprintw(18, 47, "W = Write Changes");
+ mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice");
+ mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Expert m.");
+ mvprintw(18, 0, "T = Change Type U = Undo All Changes W = Write Changes Q = Finish");
mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
move(0, 0);
}
diff --git a/usr.sbin/sade/menus.c b/usr.sbin/sade/menus.c
index f48c772..df51804 100644
--- a/usr.sbin/sade/menus.c
+++ b/usr.sbin/sade/menus.c
@@ -92,24 +92,23 @@ DMenu MenuIPLType = {
DMenu MenuMBRType = {
DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
"overwrite me", /* will be disk specific label */
- "FreeBSD comes with a boot selector that allows you to easily\n"
+ "FreeBSD comes with a boot manager that allows you to easily\n"
"select between FreeBSD and any other operating systems on your machine\n"
"at boot time. If you have more than one drive and want to boot\n"
- "from the second one, the boot selector will also make it possible\n"
+ "from the second one, the boot manager will also make it possible\n"
"to do so (limitations in the PC BIOS usually prevent this otherwise).\n"
- "If you do not want a boot selector, or wish to replace an existing\n"
- "one, select \"standard\". If you would prefer your Master Boot\n"
- "Record to remain untouched then select \"None\".\n\n"
- " NOTE: PC-DOS users will almost certainly require \"None\"!",
- "Press F1 to read about drive setup",
+ "If you have other operating systems installed and would like a choice when\n"
+ "booting, choose \"BootMgr\". If you would prefer to keep your existing\n"
+ "boot manager, select \"None\".\n\n",
+ "",
"drives",
- { { "BootMgr", "Install the FreeBSD Boot Manager",
- dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, 0, 0, 0, 0 },
- { "Standard", "Install a standard MBR (no boot manager)",
+ { { "Standard", "Install a standard MBR (non-interactive boot manager)",
dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 1 },
- { "None", "Leave the Master Boot Record untouched",
+ { "BootMgr", "Install the FreeBSD boot manager",
+ dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 0 },
+ { "None", "Do not install a boot manager",
dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 2 },
- { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0 } },
+ { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0 } }
};
#endif /* PC98 */
#endif /* __i386__ */
diff --git a/usr.sbin/services_mkdb/Makefile b/usr.sbin/services_mkdb/Makefile
new file mode 100644
index 0000000..659cdb8
--- /dev/null
+++ b/usr.sbin/services_mkdb/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG= services_mkdb
+MAN= services_mkdb.8
+SRCS= services_mkdb.c uniq.c
+
+DPADD+= ${LIBUTIL}
+LDADD+= -lutil
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/services_mkdb/services_mkdb.8 b/usr.sbin/services_mkdb/services_mkdb.8
new file mode 100644
index 0000000..6468fd2
--- /dev/null
+++ b/usr.sbin/services_mkdb/services_mkdb.8
@@ -0,0 +1,97 @@
+.\" $NetBSD: services_mkdb.8,v 1.9 2009/05/13 22:36:39 wiz Exp $
+.\"
+.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Luke Mewburn.
+.\"
+.\" 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 NETBSD FOUNDATION, INC. 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 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 2010
+.Dt SERVICES_MKDB 8
+.Os
+.Sh NAME
+.Nm services_mkdb
+.Nd generate the services databases
+.Sh SYNOPSIS
+.Nm
+.Op Fl q
+.Op Fl o Ar database
+.Op file
+.Nm
+.Fl u
+.Op file
+.Sh DESCRIPTION
+.Nm
+creates a
+.Xr db 3
+database for the specified file.
+If no file is specified, then
+.Pa /etc/services
+is used.
+The database is installed into
+.Pa /var/db/services.db .
+The file must be in the correct format (see
+.Xr services 5 ) .
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl o Ar database
+Put the output databases in the named file.
+.It Fl q
+Don't warn about duplicate services.
+.It Fl u
+Print the services file to stdout, omitting duplicate entries and comments.
+.El
+.Pp
+The databases are used by the C library services routines (see
+.Xr getservent 3 ) .
+.Pp
+.Nm
+exits zero on success, non-zero on failure.
+.Sh FILES
+.Bl -tag -width 24n -compact
+.It Pa /var/db/services.db
+The current services database.
+.It Pa /var/db/services.db.tmp
+A temporary file.
+.It Pa /etc/services
+The current services file.
+.El
+.Sh SEE ALSO
+.Xr db 3 ,
+.Xr getservent 3 ,
+.Xr services 5
+.Sh BUGS
+Because
+.Nm
+guarantees not to install a partial destination file it must
+build a temporary file in the same file system and if successful use
+.Xr rename 2
+to install over the destination file.
+.Pp
+If
+.Nm
+fails it will leave the previous version of the destination file intact.
diff --git a/usr.sbin/services_mkdb/services_mkdb.c b/usr.sbin/services_mkdb/services_mkdb.c
new file mode 100644
index 0000000..f4cf62a
--- /dev/null
+++ b/usr.sbin/services_mkdb/services_mkdb.c
@@ -0,0 +1,429 @@
+/* $NetBSD: services_mkdb.c,v 1.14 2008/04/28 20:24:17 martin Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn and Christos Zoulas.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <db.h>
+#include <err.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libutil.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stringlist.h>
+
+static char tname[MAXPATHLEN];
+
+#define PMASK 0xffff
+#define PROTOMAX 5
+
+extern void uniq(const char *);
+
+static void add(DB *, StringList *, size_t, const char *, size_t *, int);
+static StringList ***parseservices(const char *, StringList *);
+static void cleanup(void);
+static void store(DB *, DBT *, DBT *, int);
+static void killproto(DBT *);
+static char *getstring(const char *, size_t, char **, const char *);
+static size_t getprotoindex(StringList *, const char *);
+static const char *getprotostr(StringList *, size_t);
+static const char *mkaliases(StringList *, char *, size_t);
+static void usage(void);
+
+const HASHINFO hinfo = {
+ .bsize = 256,
+ .ffactor = 4,
+ .nelem = 32768,
+ .cachesize = 1024,
+ .hash = NULL,
+ .lorder = 0
+};
+
+
+int
+main(int argc, char *argv[])
+{
+ DB *db;
+ int ch;
+ const char *fname = _PATH_SERVICES;
+ const char *dbname = _PATH_SERVICES_DB;
+ int warndup = 1;
+ int unique = 0;
+ int otherflag = 0;
+ size_t cnt = 0;
+ StringList *sl, ***svc;
+ size_t port, proto;
+
+ setprogname(argv[0]);
+
+ while ((ch = getopt(argc, argv, "qo:u")) != -1)
+ switch (ch) {
+ case 'q':
+ otherflag = 1;
+ warndup = 0;
+ break;
+ case 'o':
+ otherflag = 1;
+ dbname = optarg;
+ break;
+ case 'u':
+ unique++;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1 || (unique && otherflag))
+ usage();
+ if (argc == 1)
+ fname = argv[0];
+
+ if (unique)
+ uniq(fname);
+
+ svc = parseservices(fname, sl = sl_init());
+
+ if (atexit(cleanup))
+ err(1, "Cannot install exit handler");
+
+ (void)snprintf(tname, sizeof(tname), "%s.tmp", dbname);
+ db = dbopen(tname, O_RDWR | O_CREAT | O_EXCL,
+ (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, &hinfo);
+ if (!db)
+ err(1, "Error opening temporary database `%s'", tname);
+
+
+ for (port = 0; port < PMASK + 1; port++) {
+ if (svc[port] == NULL)
+ continue;
+
+ for (proto = 0; proto < PROTOMAX; proto++) {
+ StringList *s;
+ if ((s = svc[port][proto]) == NULL)
+ continue;
+ add(db, s, port, getprotostr(sl, proto), &cnt, warndup);
+ }
+
+ free(svc[port]);
+ }
+
+ free(svc);
+ sl_free(sl, 1);
+
+ if ((db->close)(db))
+ err(1, "Error closing temporary database `%s'", tname);
+
+ if (rename(tname, dbname) == -1)
+ err(1, "Cannot rename `%s' to `%s'", tname, dbname);
+
+ return 0;
+}
+
+static void
+add(DB *db, StringList *sl, size_t port, const char *proto, size_t *cnt,
+ int warndup)
+{
+ size_t i;
+ char keyb[BUFSIZ], datab[BUFSIZ], abuf[BUFSIZ];
+ DBT data, key;
+ key.data = keyb;
+ data.data = datab;
+
+#ifdef DEBUG
+ (void)printf("add %s %zu %s [ ", sl->sl_str[0], port, proto);
+ for (i = 1; i < sl->sl_cur; i++)
+ (void)printf("%s ", sl->sl_str[i]);
+ (void)printf("]\n");
+#endif
+
+ /* key `indirect key', data `full line' */
+ data.size = snprintf(datab, sizeof(datab), "%zu", (*cnt)++) + 1;
+ key.size = snprintf(keyb, sizeof(keyb), "%s %zu/%s %s",
+ sl->sl_str[0], port, proto, mkaliases(sl, abuf, sizeof(abuf))) + 1;
+ store(db, &data, &key, warndup);
+
+ /* key `\377port/proto', data = `indirect key' */
+ key.size = snprintf(keyb, sizeof(keyb), "\377%zu/%s",
+ port, proto) + 1;
+ store(db, &key, &data, warndup);
+
+ /* key `\377port', data = `indirect key' */
+ killproto(&key);
+ store(db, &key, &data, warndup);
+
+ /* add references for service and all aliases */
+ for (i = 0; i < sl->sl_cur; i++) {
+ /* key `\376service/proto', data = `indirect key' */
+ key.size = snprintf(keyb, sizeof(keyb), "\376%s/%s",
+ sl->sl_str[i], proto) + 1;
+ store(db, &key, &data, warndup);
+
+ /* key `\376service', data = `indirect key' */
+ killproto(&key);
+ store(db, &key, &data, warndup);
+ }
+ sl_free(sl, 1);
+}
+
+static StringList ***
+parseservices(const char *fname, StringList *sl)
+{
+ size_t len, line, pindex;
+ FILE *fp;
+ StringList ***svc, *s;
+ char *p, *ep;
+
+ if ((fp = fopen(fname, "r")) == NULL)
+ err(1, "Cannot open `%s'", fname);
+
+ line = 0;
+ if ((svc = calloc(PMASK + 1, sizeof(StringList **))) == NULL)
+ err(1, "Cannot allocate %zu bytes", (size_t)(PMASK + 1));
+
+ /* XXX: change NULL to "\0\0#" when fparseln fixed */
+ for (; (p = fparseln(fp, &len, &line, NULL, 0)) != NULL; free(p)) {
+ char *name, *port, *proto, *aliases, *cp, *alias;
+ unsigned long pnum;
+
+ if (len == 0)
+ continue;
+
+ for (cp = p; *cp && isspace((unsigned char)*cp); cp++)
+ continue;
+
+ if (*cp == '\0' || *cp == '#')
+ continue;
+
+ if ((name = getstring(fname, line, &cp, "name")) == NULL)
+ continue;
+
+ if ((port = getstring(fname, line, &cp, "port")) == NULL)
+ continue;
+
+ if (cp) {
+ for (aliases = cp; *cp && *cp != '#'; cp++)
+ continue;
+
+ if (*cp)
+ *cp = '\0';
+ } else
+ aliases = NULL;
+
+ proto = strchr(port, '/');
+ if (proto == NULL || proto[1] == '\0') {
+ warnx("%s, %zu: no protocol found", fname, line);
+ continue;
+ }
+ *proto++ = '\0';
+
+ errno = 0;
+ pnum = strtoul(port, &ep, 0);
+ if (*port == '\0' || *ep != '\0') {
+ warnx("%s, %zu: invalid port `%s'", fname, line, port);
+ continue;
+ }
+ if ((errno == ERANGE && pnum == ULONG_MAX) || pnum > PMASK) {
+ warnx("%s, %zu: port too big `%s'", fname, line, port);
+ continue;
+ }
+
+ if (svc[pnum] == NULL) {
+ svc[pnum] = calloc(PROTOMAX, sizeof(StringList *));
+ if (svc[pnum] == NULL)
+ err(1, "Cannot allocate %zu bytes",
+ (size_t)PROTOMAX);
+ }
+
+ pindex = getprotoindex(sl, proto);
+ if (svc[pnum][pindex] == NULL)
+ s = svc[pnum][pindex] = sl_init();
+ else
+ s = svc[pnum][pindex];
+
+ /* build list of aliases */
+ if (sl_find(s, name) == NULL) {
+ char *p2;
+
+ if ((p2 = strdup(name)) == NULL)
+ err(1, "Cannot copy string");
+ (void)sl_add(s, p2);
+ }
+
+ if (aliases) {
+ while ((alias = strsep(&aliases, " \t")) != NULL) {
+ if (alias[0] == '\0')
+ continue;
+ if (sl_find(s, alias) == NULL) {
+ char *p2;
+
+ if ((p2 = strdup(alias)) == NULL)
+ err(1, "Cannot copy string");
+ (void)sl_add(s, p2);
+ }
+ }
+ }
+ }
+ (void)fclose(fp);
+ return svc;
+}
+
+/*
+ * cleanup(): Remove temporary files upon exit
+ */
+static void
+cleanup(void)
+{
+ if (tname[0])
+ (void)unlink(tname);
+}
+
+static char *
+getstring(const char *fname, size_t line, char **cp, const char *tag)
+{
+ char *str;
+
+ while ((str = strsep(cp, " \t")) != NULL && *str == '\0')
+ continue;
+
+ if (str == NULL)
+ warnx("%s, %zu: no %s found", fname, line, tag);
+
+ return str;
+}
+
+static void
+killproto(DBT *key)
+{
+ char *p, *d = key->data;
+
+ if ((p = strchr(d, '/')) == NULL)
+ abort();
+ *p++ = '\0';
+ key->size = p - d;
+}
+
+static void
+store(DB *db, DBT *key, DBT *data, int warndup)
+{
+#ifdef DEBUG
+ int k = key->size - 1;
+ int d = data->size - 1;
+ (void)printf("store [%*.*s] [%*.*s]\n",
+ k, k, (char *)key->data + 1,
+ d, d, (char *)data->data + 1);
+#endif
+ switch ((db->put)(db, key, data, R_NOOVERWRITE)) {
+ case 0:
+ break;
+ case 1:
+ if (warndup)
+ warnx("duplicate service `%s'",
+ &((char *)key->data)[1]);
+ break;
+ case -1:
+ err(1, "put");
+ break;
+ default:
+ abort();
+ break;
+ }
+}
+
+static size_t
+getprotoindex(StringList *sl, const char *str)
+{
+ size_t i;
+ char *p;
+
+ for (i= 0; i < sl->sl_cur; i++)
+ if (strcmp(sl->sl_str[i], str) == 0)
+ return i;
+
+ if (i == PROTOMAX)
+ errx(1, "Ran out of protocols adding `%s';"
+ " recompile with larger PROTOMAX", str);
+ if ((p = strdup(str)) == NULL)
+ err(1, "Cannot copy string");
+ (void)sl_add(sl, p);
+ return i;
+}
+
+static const char *
+getprotostr(StringList *sl, size_t i)
+{
+ assert(i < sl->sl_cur);
+ return sl->sl_str[i];
+}
+
+static const char *
+mkaliases(StringList *sl, char *buf, size_t len)
+{
+ size_t nc, i, pos;
+
+ buf[0] = 0;
+ for (i = 1, pos = 0; i < sl->sl_cur; i++) {
+ nc = strlcpy(buf + pos, sl->sl_str[i], len);
+ if (nc >= len)
+ goto out;
+ pos += nc;
+ len -= nc;
+ nc = strlcpy(buf + pos, " ", len);
+ if (nc >= len)
+ goto out;
+ pos += nc;
+ len -= nc;
+ }
+ return buf;
+out:
+ warn("aliases for `%s' truncated", sl->sl_str[0]);
+ return buf;
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr, "Usage:\t%s [-q] [-o <db>] [<servicefile>]\n"
+ "\t%s -u [<servicefile>]\n", getprogname(), getprogname());
+ exit(1);
+}
diff --git a/usr.sbin/services_mkdb/uniq.c b/usr.sbin/services_mkdb/uniq.c
new file mode 100644
index 0000000..0674b4b
--- /dev/null
+++ b/usr.sbin/services_mkdb/uniq.c
@@ -0,0 +1,159 @@
+/* $NetBSD: uniq.c,v 1.4 2008/04/28 20:24:17 martin Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 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.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <db.h>
+#include <err.h>
+#include <libutil.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+extern const HASHINFO hinfo;
+
+void uniq(const char *);
+static int comp(const char *, char **, size_t *);
+
+/*
+ * Preserve only unique content lines in a file. Input lines that have
+ * content [alphanumeric characters before a comment] are white-space
+ * normalized and have their comments removed. Then they are placed
+ * in a hash table, and only the first instance of them is printed.
+ * Comment lines without any alphanumeric content are always printed
+ * since they are there to make the file "pretty". Comment lines with
+ * alphanumeric content are also placed into the hash table and only
+ * printed once.
+ */
+void
+uniq(const char *fname)
+{
+ DB *db;
+ DBT key;
+ static const DBT data = { NULL, 0 };
+ FILE *fp;
+ char *line;
+ size_t len;
+
+ if ((db = dbopen(NULL, O_RDWR, 0, DB_HASH, &hinfo)) == NULL)
+ err(1, "Cannot create in memory database");
+
+ if ((fp = fopen(fname, "r")) == NULL)
+ err(1, "Cannot open `%s'", fname);
+ while ((line = fgetln(fp, &len)) != NULL) {
+ size_t complen = len;
+ char *compline;
+ if (!comp(line, &compline, &complen)) {
+ (void)fprintf(stdout, "%*.*s", (int)len, (int)len,
+ line);
+ continue;
+ }
+ key.data = compline;
+ key.size = complen;
+ switch ((db->put)(db, &key, &data, R_NOOVERWRITE)) {
+ case 0:
+ (void)fprintf(stdout, "%*.*s", (int)len, (int)len,
+ line);
+ break;
+ case 1:
+ break;
+ case -1:
+ err(1, "put");
+ default:
+ abort();
+ break;
+ }
+ }
+ (void)fflush(stdout);
+ exit(0);
+}
+
+/*
+ * normalize whitespace in the original line and place a new string
+ * with whitespace converted to a single space in compline. If the line
+ * contains just comments, we preserve them. If it contains data and
+ * comments, we kill the comments. Return 1 if the line had actual
+ * contents, or 0 if it was just a comment without alphanumeric characters.
+ */
+static int
+comp(const char *origline, char **compline, size_t *len)
+{
+ const unsigned char *p;
+ unsigned char *q;
+ char *cline;
+ size_t l = *len, complen;
+ int hasalnum, iscomment;
+
+ /* Eat leading space */
+ for (p = (const unsigned char *)origline; l && *p && isspace(*p);
+ p++, l--)
+ continue;
+ if ((cline = malloc(l + 1)) == NULL)
+ err(1, "Cannot allocate %zu bytes", l + 1);
+ (void)memcpy(cline, p, l);
+ cline[l] = '\0';
+ if (*cline == '\0')
+ return 0;
+
+ complen = 0;
+ hasalnum = 0;
+ iscomment = 0;
+
+ for (q = (unsigned char *)cline; l && *p; p++, l--) {
+ if (isspace(*p)) {
+ if (complen && isspace(q[-1]))
+ continue;
+ *q++ = ' ';
+ complen++;
+ } else {
+ if (!iscomment && *p == '#') {
+ if (hasalnum)
+ break;
+ iscomment = 1;
+ } else
+ hasalnum |= isalnum(*p);
+ *q++ = *p;
+ complen++;
+ }
+ }
+
+ /* Eat trailing space */
+ while (complen && isspace(q[-1])) {
+ --q;
+ --complen;
+ }
+ *q = '\0';
+ *compline = cline;
+ *len = complen;
+ return hasalnum;
+}
diff --git a/usr.sbin/setfmac/setfsmac.8 b/usr.sbin/setfmac/setfsmac.8
index 7d4150f..9bdb0e8 100644
--- a/usr.sbin/setfmac/setfsmac.8
+++ b/usr.sbin/setfmac/setfsmac.8
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd February 17, 2004
-.Os
.Dt SETFSMAC 8
+.Os
.Sh NAME
.Nm setfsmac
.Nd set MAC label for a file hierarchy
diff --git a/usr.sbin/setpmac/setpmac.8 b/usr.sbin/setpmac/setpmac.8
index e84a8bc6..c5c2963 100644
--- a/usr.sbin/setpmac/setpmac.8
+++ b/usr.sbin/setpmac/setpmac.8
@@ -31,8 +31,8 @@
.\" $FreeBSD$
.\"
.Dd January 14, 2003
-.Os
.Dt SETPMAC 8
+.Os
.Sh NAME
.Nm setpmac
.Nd "run a command with a different MAC process label"
diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c
index a2b7939..8cf1fb3 100644
--- a/usr.sbin/sysinstall/devices.c
+++ b/usr.sbin/sysinstall/devices.c
@@ -150,6 +150,7 @@ static struct _devname {
NETWORK("rue", "RealTek USB Ethernet card"),
NETWORK("rum", "Ralink Technology USB IEEE 802.11 wireless adapter"),
NETWORK("sf", "Adaptec AIC-6915 PCI Ethernet card"),
+ NETWORK("sge", "Silicon Integrated Systems SiS190/191 Ethernet"),
NETWORK("sis", "SiS 900/SiS 7016 PCI Ethernet card"),
#ifdef PC98
NETWORK("snc", "SONIC Ethernet card"),
diff --git a/usr.sbin/sysinstall/disks.c b/usr.sbin/sysinstall/disks.c
index a1c09b6..c0fd12a 100644
--- a/usr.sbin/sysinstall/disks.c
+++ b/usr.sbin/sysinstall/disks.c
@@ -207,9 +207,12 @@ print_command_summary(void)
mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice");
mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Expert m.");
- mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
+ mvprintw(18, 0, "T = Change Type U = Undo All Changes");
+
if (!RunningAsInit)
- mvprintw(18, 47, "W = Write Changes");
+ mvprintw(18, 47, "W = Write Changes Q = Finish");
+ else
+ mvprintw(18, 47, "Q = Finish");
mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
move(0, 0);
}
diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
index decb4fd..65cab4c 100644
--- a/usr.sbin/sysinstall/menus.c
+++ b/usr.sbin/sysinstall/menus.c
@@ -1175,20 +1175,16 @@ DMenu MenuMBRType = {
"at boot time. If you have more than one drive and want to boot\n"
"from the second one, the boot manager will also make it possible\n"
"to do so (limitations in the PC BIOS usually prevent this otherwise).\n"
- "If you will only have FreeBSD on the machine the boot manager is\n"
- "not needed and it slows down the boot while offering you the choice\n"
- "of which operating system to boot. If you do not want a boot\n"
- "manager, or wish to replace an existing one, select \"standard\".\n"
- "If you would prefer your Master Boot Record remain untouched then\n"
- "select \"None\".\n\n"
- " NOTE: PC-DOS users will almost certainly require \"None\"!",
- "Press F1 to read about drive setup",
+ "If you have other operating systems installed and would like a choice when\n"
+ "booting, choose \"BootMgr\". If you would prefer to keep your existing\n"
+ "boot manager, select \"None\".\n\n",
+ "",
"drives",
- { { "Standard", "Install a standard MBR (no boot manager)",
+ { { "Standard", "Install a standard MBR (non-interactive boot manager)",
dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 1 },
{ "BootMgr", "Install the FreeBSD Boot Manager",
dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 0 },
- { "None", "Leave the Master Boot Record untouched",
+ { "None", "Do not install a boot manager",
dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 2 },
{ NULL } },
};
@@ -1980,26 +1976,28 @@ DMenu MenuSysconsSaver = {
NULL,
{ { "1 Blank", "Simply blank the screen",
dmenuVarCheck, configSaver, NULL, "saver=blank" },
- { "2 Daemon", "\"BSD Daemon\" animated screen saver (text)",
+ { "2 Beastie", "\"BSD Daemon\" animated screen saver (graphics)",
+ dmenuVarCheck, configSaver, NULL, "saver=beastie" },
+ { "3 Daemon", "\"BSD Daemon\" animated screen saver (text)",
dmenuVarCheck, configSaver, NULL, "saver=daemon" },
- { "3 Fade", "Fade out effect screen saver",
+ { "4 Dragon", "Dragon screensaver (graphics)",
+ dmenuVarCheck, configSaver, NULL, "saver=dragon" },
+ { "5 Fade", "Fade out effect screen saver",
dmenuVarCheck, configSaver, NULL, "saver=fade" },
- { "4 Fire", "Flames effect screen saver",
+ { "6 Fire", "Flames effect screen saver",
dmenuVarCheck, configSaver, NULL, "saver=fire" },
- { "5 Green", "\"Green\" power saving mode (if supported by monitor)",
+ { "7 Green", "\"Green\" power saving mode (if supported by monitor)",
dmenuVarCheck, configSaver, NULL, "saver=green" },
- { "6 Logo", "\"BSD Daemon\" animated screen saver (graphics)",
+ { "8 Logo", "FreeBSD \"logo\" animated screen saver (graphics)",
dmenuVarCheck, configSaver, NULL, "saver=logo" },
- { "7 Rain", "Rain drops screen saver",
+ { "9 Rain", "Rain drops screen saver",
dmenuVarCheck, configSaver, NULL, "saver=rain" },
- { "8 Snake", "Draw a FreeBSD \"snake\" on your screen",
+ { "a Snake", "Draw a FreeBSD \"snake\" on your screen",
dmenuVarCheck, configSaver, NULL, "saver=snake" },
- { "9 Star", "A \"twinkling stars\" effect",
+ { "b Star", "A \"twinkling stars\" effect",
dmenuVarCheck, configSaver, NULL, "saver=star" },
- { "Warp", "A \"stars warping\" effect",
+ { "c Warp", "A \"stars warping\" effect",
dmenuVarCheck, configSaver, NULL, "saver=warp" },
- { "Dragon", "Dragon screensaver (graphics)",
- dmenuVarCheck, configSaver, NULL, "saver=dragon" },
{ "Timeout", "Set the screen saver timeout interval",
NULL, configSaverTimeout, NULL, NULL, ' ', ' ', ' ' },
{ NULL } },
diff --git a/usr.sbin/sysinstall/sysinstall.8 b/usr.sbin/sysinstall/sysinstall.8
index cdaec6d..010b9eb 100644
--- a/usr.sbin/sysinstall/sysinstall.8
+++ b/usr.sbin/sysinstall/sysinstall.8
@@ -541,7 +541,7 @@ Commit any rc.conf changes to disk.
Preserve existing rc.conf parameters.
This is useful if you have a post-install script which modifies rc.conf.
.El
- .It installExpress
+.It installExpress
Start an "express" installation, asking few questions of
the user.
.Pp
diff --git a/usr.sbin/sysinstall/tcpip.c b/usr.sbin/sysinstall/tcpip.c
index 75a40e8..1c1d676 100644
--- a/usr.sbin/sysinstall/tcpip.c
+++ b/usr.sbin/sysinstall/tcpip.c
@@ -683,6 +683,8 @@ tcpDeviceScan(void)
}
}
+ close(s);
+
freeifaddrs(ifap);
return (NULL);
diff --git a/usr.sbin/uhsoctl/Makefile b/usr.sbin/uhsoctl/Makefile
index 9704923..565b2e6 100644
--- a/usr.sbin/uhsoctl/Makefile
+++ b/usr.sbin/uhsoctl/Makefile
@@ -2,7 +2,7 @@
PROG= uhsoctl
MAN= uhsoctl.1
-WARNS= 1
+WARNS?= 1
DPADD= ${LIBUTIL}
LDADD= -lutil
diff --git a/usr.sbin/uhsoctl/uhsoctl.1 b/usr.sbin/uhsoctl/uhsoctl.1
index 932cefa..cd0c5ca 100644
--- a/usr.sbin/uhsoctl/uhsoctl.1
+++ b/usr.sbin/uhsoctl/uhsoctl.1
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd Aug 12, 2009
-.Os
.Dt UHSOCTL 1
+.Os
.Sh NAME
.Nm uhsoctl
.Nd connection utility for Option based devices
@@ -94,11 +94,9 @@ on interface
and use PIN
.Dq 1234
to enable the SIM card.
-
.Dl "uhsoctl -a apn.example.com -p 1234 uhso0"
-
-Disconnect from a previously established connection
-
+.Pp
+Disconnect from a previously established connection.
.Dl "uhsoctl -d uhso0"
.Sh SEE ALSO
.Xr uhso 4
diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c
index 06afe53..48580f1 100644
--- a/usr.sbin/vidcontrol/vidcontrol.c
+++ b/usr.sbin/vidcontrol/vidcontrol.c
@@ -950,10 +950,11 @@ show_adapter_info(void)
static void
show_mode_info(void)
{
- struct video_info _info;
char buf[80];
- int mode;
+ struct video_info _info;
int c;
+ int mm;
+ int mode;
printf(" mode# flags type size "
"font window linear buffer\n");
@@ -972,9 +973,35 @@ show_mode_info(void)
if (_info.vi_flags & V_INFO_GRAPHICS) {
c = 'G';
- snprintf(buf, sizeof(buf), "%dx%dx%d %d",
- _info.vi_width, _info.vi_height,
- _info.vi_depth, _info.vi_planes);
+ if (_info.vi_mem_model == V_INFO_MM_PLANAR)
+ snprintf(buf, sizeof(buf), "%dx%dx%d %d",
+ _info.vi_width, _info.vi_height,
+ _info.vi_depth, _info.vi_planes);
+ else {
+ switch (_info.vi_mem_model) {
+ case V_INFO_MM_PACKED:
+ mm = 'P';
+ break;
+ case V_INFO_MM_DIRECT:
+ mm = 'D';
+ break;
+ case V_INFO_MM_CGA:
+ mm = 'C';
+ break;
+ case V_INFO_MM_HGC:
+ mm = 'H';
+ break;
+ case V_INFO_MM_VGAX:
+ mm = 'V';
+ break;
+ default:
+ mm = ' ';
+ break;
+ }
+ snprintf(buf, sizeof(buf), "%dx%dx%d %c",
+ _info.vi_width, _info.vi_height,
+ _info.vi_depth, mm);
+ }
} else {
c = 'T';
diff --git a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
index ec8ae98..65989c2 100644
--- a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
+++ b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
@@ -396,7 +396,7 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
{
struct wpa_driver_bsd_data *drv = priv;
struct ieee80211req_mlme mlme;
- int privacy;
+ int flags, privacy;
wpa_printf(MSG_DEBUG,
"%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
@@ -408,6 +408,17 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
, params->key_mgmt_suite
);
+ /* NB: interface must be marked UP to associate */
+ if (getifflags(drv, &flags) != 0) {
+ wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__);
+ return -1;
+ }
+ if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) {
+ wpa_printf(MSG_DEBUG, "%s unable to mark interface UP",
+ __func__);
+ return -1;
+ }
+
/* XXX error handling is wrong but unclear what to do... */
if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
return -1;
diff --git a/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5 b/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5
index a7a1698..7e25391 100644
--- a/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5
+++ b/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 8, 2007
+.Dd April 10, 2010
.Dt WPA_SUPPLICANT.CONF 5
.Os
.Sh NAME
@@ -153,7 +153,27 @@ Note that IBSS (adhoc) mode can only be used with
.Va key_mgmt
set to
.Li NONE
-(plaintext and static WEP).
+(plaintext and static WEP), or
+.Va key_mgmt
+set to
+.Li WPA-NONE
+(fixed group key TKIP/CCMP).
+In addition,
+.Va ap_scan
+has to be set to 2 for IBSS.
+.Li WPA-NONE
+requires
+.Va proto
+set to WPA,
+.Va key_mgmt
+set to WPA-NONE,
+.Va pairwise
+set to NONE,
+.Va group
+set to either
+CCMP or TKIP (but not both), and
+.Va psk
+must also be set.
.It Va proto
List of acceptable protocols; one or more of:
.Li WPA
diff --git a/usr.sbin/zic/Makefile b/usr.sbin/zic/Makefile
index 2496e82..9d699a8 100644
--- a/usr.sbin/zic/Makefile
+++ b/usr.sbin/zic/Makefile
@@ -1,7 +1,6 @@
# $FreeBSD$
# Vendor contact: tz@elsie.nci.nih.gov
-MAINTAINER= wollman@FreeBSD.org
SUBDIR= zic zdump
OpenPOWER on IntegriCloud